fwbuilder-5.1.0.3599/0000755000175000017500000000000011733011756014776 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/acsite.m40000644000175000017500000001435711733011756016522 0ustar sylvestresylvestrednl dnl $Id: acsite.m4 808 2004-09-08 05:34:53Z vkurland $ dnl dnl Test files define( [AC_TEST_FILES], [ ac_file_found=yes for f in $1; do if test ! -f $2/$f; then ac_file_found=no break; fi done if test "$ac_file_found" = "yes" ; then ifelse([$3], , :,[$3]) else ifelse([$4], , :,[$4]) fi ]) dnl Search for headers, add path to CPPFLAGS if found define( [AC_SEARCH_HEADERS], [ AC_MSG_CHECKING("for $1") ac_hdr_found=no for p in $2; do AC_TEST_FILES($1, $p, [ ac_hdr_found=yes break ] ) done if test "$ac_hdr_found" = "yes" ; then CPPFLAGS="$CPPFLAGS -I$p" AC_MSG_RESULT( [($p) yes] ) ifelse([$3], , :,[$3]) else AC_MSG_RESULT("no") ifelse([$4], , :,[$4]) fi ]) dnl checks for ucd-snmp or netsnmp library and sets dnl vars LIBSNMP_LIBS and HAVE_LIBSNMP dnl dnl call like this: dnl AC_CHECK_LIBSNMP ( snmp ) dnl AC_CHECK_LIBSNMP ( netsnmp ) dnl define( [AC_CHECK_LIBSNMP], [ ac_snmplib_name="$1" ac_snmplib_name=`echo ${ac_snmplib_name} | tr -d " "` AC_CHECK_LIB($ac_snmplib_name, init_snmp, [ LIBSNMP_LIBS="-l$ac_snmplib_name" HAVE_LIBSNMP="1" AC_DEFINE(HAVE_LIBSNMP) ],[ if test "${ac_cv_lib_snmp_init_snmp+set}" = "set"; then unset ac_cv_lib_snmp_init_snmp fi save_LIBS="$LIBS" LIBS="$LIBS -lcrypto" AC_CHECK_LIB($ac_snmplib_name, init_snmp, [ LIBS="$save_LIBS" LIBSNMP_LIBS="-lcrypto -l$ac_snmplib_name" HAVE_LIBSNMP="1" AC_DEFINE(HAVE_LIBSNMP) ],[ echo dnl if test "${ac_cv_lib_snmp_init_snmp+set}" = "set"; then dnl unset ac_cv_lib_snmp_init_snmp dnl fi dnl dnl save_LIBS="$LIBS" dnl LIBS="$LIBS -ldes" dnl AC_CHECK_LIB($ac_snmplib_name, init_snmp, dnl [ dnl LIBS="$save_LIBS" dnl LIBSNMP_LIBS="-ldes -l$ac_snmplib_name" dnl HAVE_LIBSNMP="1" dnl AC_DEFINE(HAVE_LIBSNMP) dnl ]) ]) ]) dnl if test "Z$HAVE_LIBSNMP" != "Z"; then dnl AC_CHECK_LIB($ac_snmplib_name, snprint_objid, [ dnl AC_DEFINE(HAVE_SNPRINT_OBJID) dnl ]) dnl fi ]) define( [AC_CHECK_GETHOSTBYNAME_R], [ ac_define_this="$1" if test -z "$ac_define_this"; then ac_define_this="__FWB_DUMMY__"; fi AC_MSG_CHECKING(if gethostbyname_r takes 3 arguments) AC_TRY_COMPILE([ #define $ac_define_this #include ],[ char *name; struct hostent *he; struct hostent_data data; (void) gethostbyname_r(name, he, &data); ], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_FUNC_GETHOSTBYNAME_R_3) ac_cv_func_which_gethostname_r="3", [ dnl ac_cv_func_which_gethostname_r=no AC_MSG_RESULT(no) AC_MSG_CHECKING(if gethostbyname_r takes 6 arguments) AC_TRY_COMPILE([ #define $ac_define_this #include ],[ char *name; struct hostent *he, *res; char buffer[2048]; int buflen = 2048; int h_errnop; (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop) ], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_FUNC_GETHOSTBYNAME_R_6) ac_cv_func_which_gethostname_r="6", [ dnl ac_cv_func_which_gethostname_r=no AC_MSG_RESULT(no) AC_MSG_CHECKING(if gethostbyname_r takes 5 arguments) AC_TRY_COMPILE([ #define $ac_define_this #include ],[ char *name; struct hostent *he; char buffer[2048]; int buflen = 2048; int h_errnop; (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop) ], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_FUNC_GETHOSTBYNAME_R_5) ac_cv_func_which_gethostname_r="5", [ AC_MSG_RESULT(no) ac_cv_func_which_gethostname_r=no]) ]) ] ,ac_cv_func_which_gethostname_r=no) ]) dnl check for number of arguments to gethostbyaddr_r. it might take dnl 5, 7, or 8 arguments. define( [AC_CHECK_GETHOSTBYADDR_R], [ ac_define_this="$1" if test -z "$ac_define_this"; then ac_define_this="__FWB_DUMMY__"; fi AC_MSG_CHECKING(if gethostbyaddr_r takes 5 arguments) AC_TRY_COMPILE([ #define $ac_define_this #include #include ],[ char * address; int length; int type; struct hostent h; struct hostent_data hdata; int rc; rc = gethostbyaddr_r(address, length, type, &h, &hdata); ],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETHOSTBYADDR_R_5) ac_cv_gethostbyaddr_args=5 ],[ AC_MSG_RESULT(no) AC_MSG_CHECKING(if gethostbyaddr_r takes 7 arguments) AC_TRY_COMPILE([ #define $ac_define_this #include #include ],[ char * address; int length; int type; struct hostent h; char buffer[8192]; int h_errnop; struct hostent * hp; hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop); ],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETHOSTBYADDR_R_7) ac_cv_gethostbyaddr_args=7 ],[ AC_MSG_RESULT(no) AC_MSG_CHECKING(if gethostbyaddr_r takes 8 arguments and first arg is (in_addr*)) AC_TRY_COMPILE([ #define $ac_define_this #include #include ],[ struct in_addr *address; int length; int type; struct hostent h; char buffer[8192]; int h_errnop; struct hostent * hp; int rc; rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop); ],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETHOSTBYADDR_R_8) AC_DEFINE(GETHOSTBYADDR_FIRST_ARG_VOIDPTR) ac_cv_gethostbyaddr_first_arg="voidptr" ac_cv_gethostbyaddr_args=8 ],[ AC_MSG_RESULT(no) AC_MSG_CHECKING(if gethostbyaddr_r takes 8 arguments and first arg is (char*)) AC_TRY_COMPILE([ #define $ac_define_this #include #include ],[ char * address; int length; int type; struct hostent h; char buffer[8192]; int h_errnop; struct hostent * hp; int rc; rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop); ],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETHOSTBYADDR_R_8) AC_DEFINE(GETHOSTBYADDR_FIRST_ARG_CHARPTR) ac_cv_gethostbyaddr_first_arg="charptr" ac_cv_gethostbyaddr_args=8 ],[ AC_MSG_RESULT(no) have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r" ac_cv_gethostbyaddr_args=no ]) ]) ]) ]) ]) ]) fwbuilder-5.1.0.3599/packaging/0000755000175000017500000000000011733011756016722 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/packaging/fwbuilder-static-qt.spec0000644000175000017500000000571711733011756023502 0ustar sylvestresylvestre # .spec file for statically linked fwbuilder rpm for CentOS 5.2 %define name fwbuilder %define version 5.1.0.3599 %define release 1 %if "%_vendor" == "MandrakeSoft" %define guigroup System/Configuration/Networking %define compgroup System/Configuration/Networking %else %define guigroup Applications/System %define compgroup Applications/System %endif Summary: Firewall Builder Name: %{name} Version: %{version} Release: %{release}%{?dist} License: GPL2 Vendor: NetCitadel LLC., http://sourceforge.net/project/showfiles.php?group_id=5314 Group: %{guigroup} Url: http://www.fwbuilder.org/ Source: http://prdownloads.sourceforge.net/fwbuilder/%{name}-%{version}.tar.gz Packager: Vadim Kurland Buildroot: %{_tmppath}/%{name}-%{version}-root BuildRequires: libxml2-devel, libxslt-devel, openssl-devel Obsoletes: fwbuilder-ipt, fwbuilder-pf, fwbuilder-ipf, fwbuilder-ipfw, fwbuilder-pix, fwbuilder-iosacl, fwbuilder-cisco, libfwbuilder, libfwbuilder-devel Docdir: /usr/share/doc %description Firewall Builder consists of a GUI and set of policy compilers for various firewall platforms. It helps users maintain a database of objects and allows policy editing using simple drag-and-drop operations. GUI generates firewall description in the form of XML file, which compilers then interpret and generate platform-specific code. Several algorithms are provided for automated network objects discovery and bulk import of data. The GUI and policy compilers are completely independent, this provides for a consistent abstract model and the same GUI for different firewall platforms. %prep %setup ./autogen.sh %build %configure --with-qtdir=/opt/qt44 make -j5 all %install [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT make INSTALL_ROOT="${RPM_BUILD_ROOT}/" install rm -fr $RPM_BUILD_ROOT/usr/share/doc/%{name}-%{version} %clean [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %dir /usr/share/fwbuilder-%version /usr/share/fwbuilder-%version /usr/bin/fwbuilder /usr/bin/fwbedit /usr/bin/fwb_iosacl /usr/bin/fwb_ipf /usr/bin/fwb_ipfw /usr/bin/fwb_ipt /usr/bin/fwb_pf /usr/bin/fwb_pix /usr/bin/fwb_procurve_acl %doc doc/AUTHORS %doc doc/COPYING %doc doc/Credits %doc doc/ChangeLog %doc doc/PatchAcceptancePolicy.txt %doc doc/README.floppyfw %doc doc/README.iosacl %doc doc/README.ipf %doc doc/README.ipfw %doc doc/README.ipt %doc doc/README.pf %doc doc/README.pix %doc doc/README.pix_routing %doc doc/README.routing %doc doc/README.policy_import %doc doc/README.iosacl %doc doc/FWBuilder-Routing-LICENSE.txt %{_mandir}/man1/fwbuilder.1* %{_mandir}/man1/fwbedit.1* %{_mandir}/man1/fwb_iosacl.1* %{_mandir}/man1/fwb_ipf.1* %{_mandir}/man1/fwb_ipfw.1* %{_mandir}/man1/fwb_ipt.1* %{_mandir}/man1/fwb_pf.1* %{_mandir}/man1/fwb_pix.1* %{_datadir}/applications/*.desktop %{_datadir}/icons/hicolor/*/apps/%name.png fwbuilder-5.1.0.3599/packaging/fwbuilder.nsi.in0000755000175000017500000003107211733011756022033 0ustar sylvestresylvestre; fwbuilder.nsi ; ; !verbose 1 ;-------------------------------- ;Variables Var MUI_TEMP Var STARTMENU_FOLDER ; GENERATION is used to build the path in the registry, it should be coordinated ; with the path defined in FWBSettings class ; !define GENERATION "@GENERATION@" !define GENERATION_SHORT "@GENERATION_SHORT@" !define VERSION "@VERSION@" !define APPNAME "FirewallBuilder${GENERATION}" ;------------------------------------------------------------------------------ ; GetWindowsVersion ; ; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/ ; Returns on top of stack ; ; Windows Version (95, 98, ME, NT x.x, 2000) ; or ; '' (Unknown Windows Version) ; ; Usage: ; Call GetWindowsVersion ; Pop $0 ; ; at this point $0 is "NT 4.0" or whatnot Function GetWindowsVersion Push $0 Push $9 ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion StrCmp $0 "" 0 lbl_winnt ; we are not NT. ReadRegStr $0 HKLM SOFTWARE\Microsoft\Windows\CurrentVersion VersionNumber StrCpy $9 $0 1 StrCmp $9 '4' 0 lbl_error StrCpy $9 $0 3 StrCmp $9 '4.0' lbl_win32_95 StrCmp $9 '4.9' lbl_win32_ME lbl_win32_98 lbl_win32_95: StrCpy $0 '95' Goto lbl_done lbl_win32_98: StrCpy $0 '98' Goto lbl_done lbl_win32_ME: StrCpy $0 'ME' Goto lbl_done lbl_winnt: StrCpy $9 $0 1 StrCmp $9 '3' lbl_winnt_x StrCmp $9 '4' lbl_winnt_x StrCmp $9 '5' lbl_winnt_5 StrCmp $9 '6' lbl_winnt_6 lbl_error lbl_winnt_x: StrCpy $0 "NT $0" 6 Goto lbl_done lbl_winnt_5: Strcpy $0 '2000' Goto lbl_done lbl_winnt_6: Strcpy $0 'Vista' Goto lbl_done lbl_error: Strcpy $0 '' lbl_done: Pop $9 Exch $0 FunctionEnd Function .onInit Call GetWindowsVersion Pop $0 StrCmp $0 "NT 4.0" lbl_done check_2000 check_2000: StrCmp $0 "2000" lbl_done check_vista check_vista: StrCmp $0 "Vista" lbl_done lbl_error lbl_error: MessageBox MB_OK "Firewall Builder supports only Windows 2000, Windows XP and Vista platform." Abort lbl_done: FunctionEnd Function un.UninstallSurveyPageText IfFileExists $PROFILE\fwb4*license* +4 0 IfFileExists $PROFILE\Documents\fwb4*license* +3 0 MessageBox MB_YESNO "Help us improve Firewall Builder! If you are \ uninstalling because you don't plan to use the software please fill out \ a short survey to tell us why you are leaving and what we can do better.\ $\n\ $\n\ Click Yes to open the survey in your web browser, click No to exit the \ uninstaller." IDNO +2 ExecShell open "http://www.fwbuilder.org/uninstall_survey.html" ; MessageBox MB_ICONSTOP "Continuing uninstaller" FunctionEnd ;**************************************************************************** ;Include Modern UI !include "MUI2.nsh" ;**************************************************************************** setCompressor lzma Name "Firewall Builder ${GENERATION}" Caption "Firewall Builder installation" OutFile "fwbuilder-${VERSION}.exe" ; Default installation folder InstallDir "C:\FWBuilder${GENERATION_SHORT}" ;**************************************************************************** ; We need to keep installation data and program settings in ; registry folders with different names. QSettings always looks into ; Current User registry first, so if the folders have the same names, ; then we store evaluation key in Current User, while it is better ; to put it in the Local Machine branch. ; ; So, installation data goes to HKLM Software\NetCitadel\FirewallBuilder\2.1 ; and settings to HKCU Software\NetCitadel\FirewallBuilder2_1 ; ; fwbuilder-lm determines folder path for the license file by ; reading key Install_Dir under HKLM Software\NetCitadel\FirewallBuilder\2.1 ; ;**************************************************************************** ; ; Get installation folder from registry if available InstallDirRegKey HKLM Software\NetCitadel\${APPNAME} "Install_Dir" ;**************************************************************************** ;Interface Settings !define MUI_ABORTWARNING ;Start Menu Folder Page Configuration !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\NetCitadel\${APPNAME}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" LicenseText "GNU GENERAL PUBLIC LICENSE" LicenseData "doc\COPYING" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP packaging\fwbuilder-160x60.bmp !define MUI_WELCOMEFINISHPAGE_BITMAP packaging\fwbuilder-164x314.bmp ;**************************************************************************** ; The following macros add PageEx statements !insertmacro MUI_PAGE_LICENSE "doc\COPYING" ; !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER !insertmacro MUI_PAGE_INSTFILES ; Uninstaller starts with a custom page that asks the user to fill survey !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES UninstPage custom un.UninstallSurveyPageText ; Set language !insertmacro MUI_LANGUAGE "English" ;**************************************************************************** ; Request elevated priviliges RequestExecutionLevel admin ;**************************************************************************** ; The stuff to install Section "FWBuilder (required)" ; Set output path to the installation directory. ; SetOutPath $INSTDIR SetOutPath $INSTDIR\resources File src\res\resources.xml File src\res\templates.xml File src\res\objects_init.xml File src\libfwbuilder\etc\fwbuilder.dtd File /r src\res\configlets File /r src\res\help File /r src\res\os File /r src\res\platform File /r src\libfwbuilder\migration SetOutPath $INSTDIR\resources\locale ; we have no working translations for v4 and v5 ; File src\libgui\*.qm SetOutPath $INSTDIR File /oname=COPYING.doc doc\COPYING File "doc\FWBuilder-Routing-LICENSE.txt" File "doc\README.iosacl" File "doc\README.ipt" File "doc\README.ipf" File "doc\README.ipfw" File "doc\README.pf" File "doc\README.pix" File "doc\README.pix_routing" File "doc\README.routing" File /oname=fwbuilder.ico "src\gui\fwbuilder-windows.ico" File /a "src\gui\release\fwbuilder.exe" File /a "src\fwbedit\release\fwbedit.exe" File /a "src\iosacl\release\fwb_iosacl.exe" File /a "src\ipt\release\fwb_ipt.exe" File /a "src\ipf\release\fwb_ipf.exe" File /a "src\ipfw\release\fwb_ipfw.exe" File /a "src\pf\release\fwb_pf.exe" File /a "src\pix\release\fwb_pix.exe" File /a "src\procurve_acl\release\fwb_procurve_acl.exe" File "c:\MinGW\bin\libiconv-2.dll" File "c:\MinGW\bin\libpthread-2.dll" File "c:\MinGW\bin\libgcc_s_dw2-1.dll" File "c:\MinGW\bin\libstdc++-6.dll" File "c:\local\bin\libxml2-2.dll" File "c:\local\bin\libxslt-1.dll" ; Install RCS for these files ; File "c:\local\bin\ci.exe" File "c:\local\bin\co.exe" File "c:\local\bin\rcs.exe" File "c:\local\bin\rcsdiff.exe" File "c:\local\bin\rlog.exe" File "c:\local\bin\diff.exe" File "c:\local\bin\rcslib.dll" ; File "c:\local\bin\netsnmp.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtCore4.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtGui4.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtNetwork4.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtTest4.dll" File /nonfatal /oname=resources\locale\qt_de.qm "c:\local\qt-everywhere-commercial-src-4.7.3\translations\qt_de.qm" File /nonfatal /oname=resources\locale\qt_fr.qm "c:\local\qt-everywhere-commercial-src-4.7.3\translations\qt_fr.qm" File /nonfatal /oname=resources\locale\qt_ru.qm "c:\local\qt-everywhere-commercial-src-4.7.3\translations\qt_ru.qm" ;; Starting with 4.0.2, we now package putty tools with fwbuilder File "c:\PuTTY\plink.exe" File "c:\PuTTY\pscp.exe" ; Write the installation path into the registry WriteRegStr HKLM Software\NetCitadel\${APPNAME} "Install_Dir" "$INSTDIR" ; Write the uninstall keys for Windows WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "DisplayName" "Firewall Builder ${GENERATION}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "Publisher" "NetCitadel LLC" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "DisplayVersion" "${VERSION}" ; Write file associations and icons WriteRegStr HKLM "Software\Classes\.fwb" "" "fwbfile" WriteRegStr HKLM "Software\Classes\fwbfile\shell\open\command" "" "$INSTDIR\fwbuilder.exe -noexec %1" WriteRegStr HKLM "Software\Classes\fwbfile\DefaultIcon" "" "$INSTDIR\fwbuilder.exe,0" WriteRegStr HKLM "Software\Classes\.fwl" "" "fwlfile" WriteRegStr HKLM "Software\Classes\fwlfile\shell\open\command" "" "$INSTDIR\fwbuilder.exe -noexec %1" WriteRegStr HKLM "Software\Classes\fwlfile\DefaultIcon" "" "$INSTDIR\fwbuilder.exe,0" ; Create registry entry for putty session with ssh keepalive WriteRegDWORD HKCU "Software\SimonTatham\PuTTY\Sessions\fwb_session_with_keepalive" "PingInterval" "0" WriteRegDWORD HKCU "Software\SimonTatham\PuTTY\Sessions\fwb_session_with_keepalive" "PingIntervalSecs" "10" ; ======================================================================== ; Configure installer to use our prepackaged plink.exe and pscp.exe but only if it was not configured before ; ; ******** THESE KEYS MUST MATCH THOSE USED BY the class FWBSettings ; ReadRegStr $0 HKCU "Software\netcitadel.com\${APPNAME}\${GENERATION}\SSH" "SSHPath" StrCmp $0 "" 0 +3 WriteRegStr HKCU "Software\netcitadel.com\${APPNAME}\${GENERATION}\SSH" "SSHPath" "$INSTDIR\plink.exe" WriteRegStr HKCU "Software\netcitadel.com\${APPNAME}\${GENERATION}\SSH" "SCPPath" "$INSTDIR\pscp.exe" ; ======================================================================== !insertmacro MUI_STARTMENU_WRITE_BEGIN Application ; Setting var context to "all" makes Start menu shortcuts appear for all ; users ; SetShellVarContext all CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder on the Web.lnk" "http://www.fwbuilder.org/" "" "$INSTDIR\fwbuilder.ico" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder.lnk" "$INSTDIR\fwbuilder.exe" "" "$INSTDIR\fwbuilder.ico" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 !insertmacro MUI_STARTMENU_WRITE_END WriteUninstaller "uninstall.exe" SectionEnd ;============================================================================= ; uninstall stuff UninstallText "This will uninstall FWBuilder. Hit next to continue." ;============================================================================= Section "Uninstall" ; remove registry keys DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" DeleteRegKey HKLM "Software\NetCitadel\${APPNAME}" ; delete obsolete registry folder, not used in v3.x but could be left over from older versions DeleteRegKey HKCU "Software\NetCitadel LLC\Firewall Builder" DeleteRegKey HKCU "Software\netcitadel.com\${APPNAME}" DeleteRegKey /ifempty HKCU "Software\netcitadel.com\${APPNAME}" DeleteRegKey /ifempty HKCU "Software\netcitadel.com" DeleteRegKey HKCR ".fwb" DeleteRegKey HKCR ".fwl" DeleteRegKey HKCR "fwbfile" DeleteRegKey HKCR "fwlfile" DeleteRegKey HKCR "FirewallBuilder.AssocFile.FWB" DeleteRegKey HKCR "FirewallBuilder.AssocFile.FWL" ; remove files ; MUST REMOVE UNINSTALLER, too Delete $INSTDIR\uninstall.exe Delete "$INSTDIR\*.*" Delete "$INSTDIR\migration\*.*" Delete "$INSTDIR\resources\os\*.*" Delete "$INSTDIR\resources\platform\*.*" Delete "$INSTDIR\resources\help\*.*" Delete "$INSTDIR\resources\configlets\*.*" Delete $INSTDIR\COPYING.doc RMDir /r "$INSTDIR" ; !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP ; Delete "$SMPROGRAMS\$MUI_TEMP\*.*" ; StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" ; Remove Start menu shortcuts !insertmacro MUI_STARTMENU_GETFOLDER Application $STARTMENU_FOLDER ; SetShellVarContext all Delete "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder on the Web.lnk" Delete "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder.lnk" Delete "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" RMDir "$SMPROGRAMS\$STARTMENU_FOLDER" ; delete only if empty because there could be registry folders ; for our other products DeleteRegKey /ifempty HKLM "Software\NetCitadel" SectionEnd ; eof fwbuilder-5.1.0.3599/packaging/fwbuilder.control.in0000644000175000017500000000075011733011756022716 0ustar sylvestresylvestrePackage: fwbuilder Conflicts: fwbuilder (<=4.1.1-1), fwbuilder-common, fwbuilder-bsd, fwbuilder-linux, fwbuilder-doc, libfwbuilder Replaces: fwbuilder (<=4.1.1-1), fwbuilder-common, fwbuilder-bsd, fwbuilder-linux, fwbuilder-doc, libfwbuilder Priority: extra Section: checkinstall Maintainer: vadim@fwbuilder.org Version: @VERSION@-1 Depends: libqt4-gui (>= 4.4.0), libqt4-network (>= 4.4.0), libxml2, libxslt1.1, libsnmp | libsnmp15 Description: Firewall Builder GUI and policy compilers fwbuilder-5.1.0.3599/packaging/fwbuilder-static-qt.spec.in0000644000175000017500000000571611733011756024106 0ustar sylvestresylvestre # .spec file for statically linked fwbuilder rpm for CentOS 5.2 %define name fwbuilder %define version @VERSION@ %define release 1 %if "%_vendor" == "MandrakeSoft" %define guigroup System/Configuration/Networking %define compgroup System/Configuration/Networking %else %define guigroup Applications/System %define compgroup Applications/System %endif Summary: Firewall Builder Name: %{name} Version: %{version} Release: %{release}%{?dist} License: GPL2 Vendor: NetCitadel LLC., http://sourceforge.net/project/showfiles.php?group_id=5314 Group: %{guigroup} Url: http://www.fwbuilder.org/ Source: http://prdownloads.sourceforge.net/fwbuilder/%{name}-%{version}.tar.gz Packager: Vadim Kurland Buildroot: %{_tmppath}/%{name}-%{version}-root BuildRequires: libxml2-devel, libxslt-devel, openssl-devel Obsoletes: fwbuilder-ipt, fwbuilder-pf, fwbuilder-ipf, fwbuilder-ipfw, fwbuilder-pix, fwbuilder-iosacl, fwbuilder-cisco, libfwbuilder, libfwbuilder-devel Docdir: /usr/share/doc %description Firewall Builder consists of a GUI and set of policy compilers for various firewall platforms. It helps users maintain a database of objects and allows policy editing using simple drag-and-drop operations. GUI generates firewall description in the form of XML file, which compilers then interpret and generate platform-specific code. Several algorithms are provided for automated network objects discovery and bulk import of data. The GUI and policy compilers are completely independent, this provides for a consistent abstract model and the same GUI for different firewall platforms. %prep %setup ./autogen.sh %build %configure --with-qtdir=/opt/qt44 make -j5 all %install [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT make INSTALL_ROOT="${RPM_BUILD_ROOT}/" install rm -fr $RPM_BUILD_ROOT/usr/share/doc/%{name}-%{version} %clean [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %dir /usr/share/fwbuilder-%version /usr/share/fwbuilder-%version /usr/bin/fwbuilder /usr/bin/fwbedit /usr/bin/fwb_iosacl /usr/bin/fwb_ipf /usr/bin/fwb_ipfw /usr/bin/fwb_ipt /usr/bin/fwb_pf /usr/bin/fwb_pix /usr/bin/fwb_procurve_acl %doc doc/AUTHORS %doc doc/COPYING %doc doc/Credits %doc doc/ChangeLog %doc doc/PatchAcceptancePolicy.txt %doc doc/README.floppyfw %doc doc/README.iosacl %doc doc/README.ipf %doc doc/README.ipfw %doc doc/README.ipt %doc doc/README.pf %doc doc/README.pix %doc doc/README.pix_routing %doc doc/README.routing %doc doc/README.policy_import %doc doc/README.iosacl %doc doc/FWBuilder-Routing-LICENSE.txt %{_mandir}/man1/fwbuilder.1* %{_mandir}/man1/fwbedit.1* %{_mandir}/man1/fwb_iosacl.1* %{_mandir}/man1/fwb_ipf.1* %{_mandir}/man1/fwb_ipfw.1* %{_mandir}/man1/fwb_ipt.1* %{_mandir}/man1/fwb_pf.1* %{_mandir}/man1/fwb_pix.1* %{_datadir}/applications/*.desktop %{_datadir}/icons/hicolor/*/apps/%name.png fwbuilder-5.1.0.3599/packaging/fwbuilder-160x60.bmp0000644000175000017500000007026611733011756022262 0ustar sylvestresylvestreBMЖp6( <€p#.#.џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџћџџћџџћџїїїяѓяяяяяыяяяяяѓяїїїїћїџћџїћїяѓяцчццчцїѓїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїяѓяопоЮЮЮНОНЕВЕ­Ў­­Њ­ЅЂЅœžœœžœœžœœžœЅЂЅ­Њ­­Ў­­Ў­ЅЂЅŒŠŒ{Ž{œІœжвжџџџџћџЕЦНЅВЅЮвЮяяяопоЮзжжлжїѓяџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїцуцХЦХЅІЅœšœ”š”ŒŽŒ„†„{y{sqskmkkmkceccecZYZRQRJIJBEB:=::11)1)Q)a)i):uJkŽsJ‚cQ)Q!1iBJqR)i:)a1)a1k†sжзжїћїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџопоЅЊЅ{}{kekkik„‚„”–”œžœœžœ”–”ŒŠŒ„†„„‚„suskmkcecZ]ZRURJMJB=B!()U)e1m1}:]!a1q:!uB!m:U)Y!i)i)a!Q{Š{опоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїЮЪЮsus:=:JEJcac{}{”–”ЅІЅ­Њ­­Њ­œЂœ”–”ŒŽŒ„†„{}{suskikcacZYZRQRJEB)9)!‚:)’J‚:‚:e1)†R)ŽR1ŠJ!u:a)u1!}:e!m)q)])ЅЊ­яяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџопоcac)()BABRURkmk„†„œšœЅІЅ­Њ­­Њ­œЂœ”–”ŒŽŒ„†„{}{suskikcacZYZRQRJIJ111])!’:!’B)šBy:1’Z:žZBІZ1’J!}:!†B!†:i)i!!‚:i!{Š{цуцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЦХ! !151BEBZUZkmk„‚„”–”ЅІЅ­Њ­­Њ­ЅЂЅ”–”ŒŽŒ„†„{}{suskikcacZYZRQRJIJ:1:9!)ІJ1ЖZ)ІJ†:!ŠB:ЂR:ЊZ!’J!ŠB!’B!Š:u)m)!}:e!cqcцпцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоуо!$!:9:BEBRURkik„‚„”–”ЅІЅ­Њ­­Њ­ЅЂЅ”–”ŒŽŒ„†„{}{suskikcacZYZRQRJIJ:5:!=))ІJ:КZ)žJ!’:)ІR)ІRšJ!žJ)ЂJ1ЎR!Ž:‚1!†:y1a!U!k–sџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ111:5:BEBRURkik„‚„”–”ЅІЅ­Њ­­Њ­ЅІЅ”–”ŒŠŒ„‚„{y{kmkcecZ]ZRURJMJJIJB=B111!’:)ЎJ!Ž:!Š:!ЊJ!ЊJ!žBš:1ЎJJОZu)†:!’B†:])m)u)ХзЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkik111BEBRURkik„‚„”–”ЅІЅ­Њ­ЅІЅœžœœžœ”š”œšœЅІЅœžœ”–”„†„kmkcacJMJ:9::-1!Y1!I)a)}1)ЊJ)КJ!ЊBЂ:!ЂB)ЊJŽBa!)’Bm1e1!‚:q)очоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœžœ111BEBRURkmk{}{ŒŠŒ”–””–””–””’”„‚„{}{{y{suscaccacceckmkkmkkiksqskikZUZB=B:1:)q:!ЦJ)КJ!ЖJ)КJ!ЊB)ІJ)šJu1)‚Je1!i1)ŠB!q:овояѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжвж)()JMJcackmksqs„‚„{y{{}{”š”НКНХЪХХТХЮЮЮцчцХТХНКНЕВЕœЂœœšœ„‚„sqs„†„c]cJMJRMJ:YB!Њ:)ЪJ1ЪR1ЦR)КR)ВR)ЎR’Bq1q1)‚B!ŽB)i:smsœšœХЦХяяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяя:=:cacZYZsusŒŠŒ­Ў­олоцчцяяяїѓїяяяяяяЮЮЮцчцЮЪЮНОНЕЖЕ­Ў­­Њ­­Њ­œšœ”–”œžœŒŽŒ{y{c]Z:UB]))ІB)ІJ)КR!ЖJš:1uB!q:!†:)†B!}:cyk{y{sus„‚„”’”ХЦХяяяџџџџџџџџџяѓяяѓяџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїѓїcacZ]Zsusœšœ­Ў­ЅЊЅопоцчцяяяїїїяѓяяяяХЪХцуцЮЮЮХЦХХТХНОН­Ў­­Ў­ЅЂЅ”š”ЅЂЅœžœ”–”ŒŽŒ„†„c]c )†:К:!’:ZmZRMJcec{Š„”–”{†{Œ†Œ„†„ŒŠŒŒŽŒ„†„ŒŠŒŒŽŒХЦХоуоЮЮЮНЖНЕЎЕЮЦЮцуццуццчцяяяџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїsqscac„‚„œšœ­Ў­ЅЊЅопояыяяѓяцчцХЦХ­Ў­ŒŽŒЕЖЕЮЪЮЮЮЮХЦХХЦХНОНЕЖЕЅЊЅœšœЅІЅœžœœžœœžœœšœœšœJIJk†k{u{„}„kikŒŠŒsmskmkœžœŒŽŒ„†„ŒŽŒ”–””’””’”ŒŽŒ„†„sqssms:eJi)e!JqZ”’”{Š{ЅІЅжвжїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЦХZ]Z„†„ЅІЅЕВЕ­Ў­цчцяяяцчцЕЖЕsuscikcacœžœЕВЕЮвЮжвжЮЮЮХТХНОНЅІЅ”š”ЅІЅЅІЅœšœœžœœšœ”š”! !RQR”Ž”ŒŽŒ”’”kikŒŠŒ{}{{y{kmk„‚„œЂœ”–””–”ŒŽŒ”’””–”ŒŽŒkik]1!‚B)’J1ЂJ†1a!}1y)i)ЅО­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅ”’”НОН­Ў­ŒŽŒХЦХХТХЮЮЮ”–”œІЅ{‚„JQRЮзжJEJНКН„†„ŒŽŒ{y{„†„„‚„{}{”’”ŒŽŒ„†„œЂœœžœ”’”151cacJMJsqsŒŽŒcacœžœŒŠŒŒŠŒŒŽŒŒŠŒ„‚„”’”œžœœžœœžœ”’”ŒŽŒkmk‚:)’J1žJBЎZ)’Bm)1žRBЎZ!Š1q)цяцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕ„‚„„‚„œžœЅІЅХЦХЕЖЕцчц­Ў­”–”ХЮЮ)$)џћџЕЖЕЮЮЮХЦХНОНЕВЕЅЂЅŒŽŒ{}{suskeksqs”’”1-1kikkmkŒŠŒ{y{sqs„‚„”–”­Ў­œžœ”–”œšœœšœ”š”ЅЂЅЅІЅ­Њ­­Њ­”†”!q:!šB1ІJ:ЎR1žJq)1ЂJBЖZ!’:q!цяцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœšœ{y{ЕВЕХЦХжвжоуоНТНяяя­Њ­”žœ)() ЮвЮ)()їѓї­Ў­ХТХНОНЕЖЕЕВЕ­Ў­­Њ­ЅЂЅ”’”sqs„†„Z]Z151kmkkik”–””’””’””’”ŒŽŒ{y{­Њ­НКНœžœЅЂЅЅІЅЅІЅЅІЅЅІЅЅЊЅ­Њ­sus!ž::КR:ЊR)–J}1:ВR1ЊR)’BBŽRїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕœžœНОНХЦХХЪХолоНОНяяяЕВЕœЂЅB=B! !Юзж)-)яыя­Ў­НОННОНЕЖЕЕВЕ­Ў­ЅІЅœžœ”–”{y{ЅЂЅ„†„sus{y{”–””–”œšœœžœ”–”œžœ”’”ŒŠŒœžœХЦХЅІЅЅЊЅ­Њ­­Њ­ЕВЕЕЖЕ”Ž”!Š::ВR:ЎZ)’J†:BКZ1ІR)–JkЊ{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮ­Њ­НОНХЦХЮЮЮоуоХТХїїїЮЮЮœžœZ]ckmkœЂœ111жзж­Њ­НКННКНЕЖЕЕВЕ­Ў­­Њ­ЅЂЅ”–”{y{œžœŒŠŒ)()c]ccac”–”œšœЅІЅ­Њ­œЂœœЂœЅІЅ­Њ­ЅЂЅ”–”НТНЕЖЕЕВЕ­Ў­ЕЖЕХЦХ­Ў­Ѕ’œ1’B)’Bq)!š::ЎR)šJ}1„Ж”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжлжЕВЕХЦХжвжХЦХХЪХЕВЕопоолоœžœkqkcac{}{НОНœžœЅІЅЕВЕœšœЅІЅЅЂЅ”–”œžœ”–”{y{œžœ„‚„1-1”’”œšœ{}{sus”–”œžœ­Њ­ЅІЅЅЊЅЕВЕ­Ў­ЅЂЅœžœЅІЅНОНЕЖЕНКНХЪХ­Ў­ЕВЕ­Њ­kyk)q:!ž:)žB)–By1НзХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџопоНКНŒŽŒ„‚„ЅІЅЕКЕЮЮЮопоцыцНКНkmksqsЅІЅЮвЮНОНЕВЕ­Ў­ЕЖЕ”–”ЅІЅ”’”ŒŽŒ„‚„sqsRURŒŠŒ{y{:9:”’”œšœœžœœžœ{}{kek{}{ŒŽŒНОНЕЖЕЅЊЅ­Ў­­Ў­НОН­Њ­ЅЊЅЕВЕЕКЕХЪХНКНЕВЕЅšЅJyR)ЊJBКZ1ЂR!†BХлЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЪЮcec„‚„НОНЮЮЮопоцыцяѓяяѓяопооуоолоолоЮвЮХЪХХТХНКНЕВЕ”–”НКН­Њ­ЅЂЅ”’”„‚„sqsZYZcac”–”­Ў­œžœ”’”RQRНОНŒ’”„‚„„†„ŒŽŒНОННОН­Њ­НКН­Ў­ЕВЕЕЖЕЕЖЕЅІЅ­Ў­ЮЪЮЕЖЕœšœJŽZž:Š:ZžkїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЪЮЅЂЅŒŽŒЮЪЮЮЮЮопоцчцяяяяыяоуояыяопожзжЮЪЮХЦХЕЖЕНКНЕЖЕ”–”ЕВЕЅІЅЅЂЅ”’”„‚„suskmkRQRc]cc]cRURœžœЅІЅНОН)-)ЅЊ­­Ў­”š””–””’”ЕКЕЕВЕЕЖЕЕВЕЕЖЕЕКЕЅЂЅолоœžœ”’”ЕВЕНЖН„ЂŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжзжЅЂЅ”’”ХЦХЮЮЮжлжцчцяяяяыяоуояыяопоолоХЦХНОНЕЖЕХТХНОН”š”ЕЖЕЅІЅЅІЅŒŽŒ„‚„{y{sqsRURkekЅЂЅ­Ў­{}{kikНЦХЕКЕ­Њ­­Ў­œžœ”’”œšœНОННОНЕЖЕНОНЅЂЅопоЕЖЕЕВЕ”–””’”ЕЎ­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮ”š”ŒŽŒЮЮЮЮЪЮХЦХЮЮЮолооуожлжжлжХЦХХЪХЕЖЕ­Ў­­Њ­ЅІЅЕВЕŒŠŒЅЂЅœžœœžœ”–””–”ŒŠŒsusRURkikœžœ­Ў­ЕЖЕЕЖЕХЪХ)()ЕКНЕКЕНКН­Њ­­Ў­ЕВЕЅІЅЅІЅНОНХЦХЅЊЅопоЕЖЕЕВЕЕВЕЕВЕœЂœџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮ”š”{y{„†„”–”ЕВЕХЦХжвжцуцоуожлжНОНжвжХЦХНКНЕВЕ­Њ­ЅІЅœЂœŒŠŒ„†„„†„„‚„suskik„‚„JMJkikЕЖЕЕЖЕЕВЕЕЖЕЮвЮB=:)$!ЕОНœžœЕЖЕНОНЕКЕЕКЕЕКЕЕВЕœžœœžœЅІЅЕЖЕХТХХЦХЕЖЕЕЖЕНКНџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЪЮZ]Z{}{­Њ­ЅІЅжлжопоцчцопоЮЪЮЕЖЕ”–”НКНХЦХХЦХНОНЕЖЕНКНЕВЕЅІЅœžœ”–”ŒŠŒ„†„sqsJIJZYZJMJZUZ”š”ХЦХЮЪЮ sysŒŠŒ:9:ЕКЕ­Њ­œЂœœЂœ­Њ­жзжХЦХœžœ{‚„ЕКНœžœœžœ­Њ­œЂœНКНХЦХНОНџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮ{}{ЅЂЅЕЖЕЅЊЅопоопожлж­Ў­kikRURZYZŒ’”ЕЖЕНОНЕКЕЕКЕЕВЕЕВЕЅІЅœšœ”–”ŒŠŒ„‚„{}{{y{ZUZ{}{ЅІЅcecc]c”’”kmkZ]cНЦХ­ВЕЕКЕЅЊЅНКНЕВЕЅЂЅЕВЕœšœJIJcecZ]ZНТХЕВЕНКН”’”ŒŽŒ­Њ­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоло„‚„”–”­Ў­ЅІЅжзжолоЮЪЮ”–”ЅЎ­ЅЊ­sqsЮзжcecХТХЅЊЅЕКЕЕВЕЕВЕЅЊЅ”’””’”„†„„†„„‚„{}{cac„‚„­Њ­ŒŠŒЮЪЮЅІЅ„‚„ŒŠŒBABЅЂЅЕКЕЅІЅЕЖЕНКНХТХНОН{}{JMJkmk жпоЕЖЕ”–”ЮЮЮ­Ў­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуцŒŠŒ”–””’””’”ЕЖЕЕВЕНОНŒŽŒ”–”ХЮЮХТХœšœœžœ”–”„†„{y{kmk„‚„„‚„{y{sus„†„cac„‚„­Њ­ŒŠŒНТНЕКЕНОНХЦХœžœ­Ў­НОНЕВЕЅІЅЮЪЮЕВЕНОНХЦХŒŠŒJIJ{}{1-1жлоЕЖЕœšœЮЮЮХТХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяkmkkmkŒŽŒ­Њ­НОНЕЖЕопоœЂЅœžœ)()ЮвЮ! !ЮЮЮЅІЅ­Ў­­Њ­ЅЂЅœžœ”’”{y{kmkcacZUZZ]ZJIJcac”–”„‚„ХТХНОНХТХЮЪЮ­Њ­НОНЕКЕ­Ў­­Њ­­Ў­НТНжзжХЦХ”’”JMJŒŽŒBAB)-)жлжЅЂЅ„†„ЕЖЕЮЮЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkmk„†„­Ў­ЕВЕЮЪЮНКНоуо­Ў­œЂЅ:=:Юзж!$!жзжЅЊЅЕВЕЅІЅœžœ”–”„†„suskmkkmkkek{y{!$!RQRŒŽŒЅІЅНКНХЪХ­Њ­ХТХЮЪЮХЦХНОННОНЅЊЅ­Ў­ЕЖЕНКН!$)”š”Z]ZBABЮвж­Њ­­Ў­­Ў­ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{y{ŒŠŒ­Њ­НОНЮЪЮНКНцчцХЦХ”žœJIJZYZЕКН1-1опо­Њ­ЕВЕ­Њ­ЅЂЅœžœ„‚„kmkcacceckekŒŠŒ :=:cek”š”ŒŽŒЕЖЕХЦХХЦХХТХХЪХЅІЅоуоХЦХЕВЕZYZ ”–”ХЮЮ­ВЕЕЖЕНКНЮЮЮЮЪЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{y{ŒŽŒ­Ў­НКНЮЮЮЕЖЕопоЮвЮЅЊЅœЂœ”–” c]cЅІЅŒŠŒ”š””–”œšœЅІЅ”š”{y{cackikcecŒŽŒ ЅІЅ:=:sqsŒ’”­Њ­НОНХЦХЅІЅцуцЮЪЮжвжжзжŒŽŒ! !жвжЕЖЕНОНЮвЮЮЪЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŒŠŒ{y{”’”œšœЅІЅНКНЮЮЮопоЅІЅ:=::=:„‚„цчцЮЪЮЕЖЕ­Њ­œžœ{y{ŒŽŒcacJMJZ]ZZ]ZRQR„‚„!$! ЕЖЕ:5:RQRsus”–”ŒŽŒжзжЮЪЮЮЮЮЮЮЮжзжжвжЮЮЮЕВЕЅЊЅ­Ў­НОНЮЮЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{y{cac”–”НОНопоцчццчццчццчцяяяяѓяцыцжвжХЦХНКНЕВЕЅЊЅ„†„œšœsqskikkekkikZYZZYZ! !111:=:)()ЕЖЕ!!! !! !)-)Z]ckqs„†„œšœЕВЕНОНЮЪЮНКНЮЮЮЮвЮЮЮЮНКНЕВЕЕЖЕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„†„{y{НОНЮЪЮолоцчцяыяцчцопоцыцоуооложвжХЪХНОНЕЖЕ­Њ­„‚„”–”kmkkiksqs{}{„†„sus )()RURB=:ЕЖЕ!$!)())()cackik:9:BEBcec{}{œšœЅІЅХЦХЮЮЮжвжжзжжвжЮЮЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”š”{y{НОНЮЮЮопоцыццыцолоХЦХЮЮЮНОНЕКЕЕВЕ­Њ­ЅЂЅœЂœœžœ{y{”’”sqssus{}{„†„ŒŠŒŒŠŒRUR151RUZsy{{y{„ŠŒsqsZYZ)()!$!)$)cackik:9:BABBEBBEBRURsqs„†„ЅІЅНОНЮЪЮжвжжзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅ{}{НКННКНЕЖЕЕВЕ­Њ­œžœŒŠŒ„‚„sussqskikcaccacceccecRURkikZ]Zkiksus„†„ŒŠŒ”–”џџџџџџяѓя­Њ­Z]Z111)())())():9:kqskmkRURcekkqs:9::=:BEBJIJBAB”šœJMJcecsus”’”­Њ­ХЦХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­Ў­cecŒŠŒ„†„{}{„‚„”’””–””’””’”„†„„‚„{y{kmkcacZYZRURJEJBAB:9::=:JMJZ]ZkmkŒŽŒїћїџџџџџџџџџїћїНОН”’”kmkRURZYZZYZZYZsqs”–”{}{Z]ZZYZJMJBEBBAB”šœRQRRURZUZcaccikŒŽ”яяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅJMJZ]Z{y{”’”œžœЅІЅœЂœ”š””’”ŒŽŒ„†„{}{sqskikZ]ZRURJIJBAB:9:111111111:=:kikџџџџџџџџџџџџџџџџџџџџџїїїопожвжœžœ{y{kikcacZ]Zsqssqskmksuscac”šœJIJRURZYZc]cZ]ZZ]ZŒŽŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїZYZJEJcac{}{”–”ЅЂЅЅІЅœžœ”–””’”ŒŽŒ„†„{}{sqskikZ]ZRURJIJBAB:9:151151111111:9:НТНџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїяѓяжвж”’”sqskmksus„ŠŒ”šœœžœ­ВЕ„†„susZYZZYZc]ccac{}{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkik111JIJcec{}{”’”œšœ­Њ­­Њ­ЕЖЕœžœŒŽŒ„†„{}{sqskikZ]ZRURJIJBAB:9:151151151151BEBRURоуоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяѓяХЦХ”’”„ŠŒ„‚„„‚„„‚„ŒŠŒœžœ”’”sqsc]Z{}{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЦХ)-)151JIJcecŒŽŒ­Ў­ХЦХХТХХТХХТХœšœŒŠŒ„†„{}{sqskikZ]ZRURJIJBAB:9:151151111:5:JMJcacsqsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжвж­Њ­œžœ”’”ŒŽŒŒŽŒ”’”ЅІЅ­Ў­œšœџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕ)():5:JIJkecsusBMJsy{ЅІЅЅІЅЅІЅ”’”ŒŠŒ„†„{}{sqskikZ]ZRURJIJBAB:9:151151111ZYZœžœ{}{ZUZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжзжХЦХХЪЮжзжцыцїћїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕ)():5:JEJkek„‚„:AB19:ŒŠŒŒŠŒŒŠŒ„†„ŒŽŒ„†„{}{sqskikZ]ZRURJIJBAB:9:151151111BEBc]c:5:cecџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕ)()151BEBcec„†„:EB:EBkmkkmkkik{}{ŒŽŒ„†„{}{sqskikZ]ZRURJIJBAB:9:151151151)-)sqsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНКН)()151BEBcec„†„:EBBEJRQRRQRJMJsqsŒŠŒ„‚„{y{kmkcacZUZJMJBAB:=::9:151111151151)-)! !„†„џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНКН)()151JIJkmkŒŽŒ:ABBEJBEB!$!JIJ­Ў­ЮЮЮЮЪЮХЦХЮЪЮжзжХЦХХЦХœЂœŒŠŒcacBEB:=::5::=:JIJB=BŒŠŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНКН! !)-)sqsЅЂЅЕКЕkms:ABZ]ZBEBsusŒŽŒ”–””’””’””–”œšœ”š”ЅЊЅЕВЕЕВЕœžœsusZUZc]cZYZ„†„џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­Ў­BEB”–”ЕЖЕНКНЕВЕНКНœЂЅ{}{!$!JMJcaccecRURBAB:9:)-)жзжЕВЕ”–”„‚„cac{}{ŒŠŒ{}{sussqs{y{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжзж”’”­Ў­ЅЂЅœžœœžœœžœkek”’”!$!JMJkekc]c:=:)-))()џџџџџџџџџ{y{ œžœŒŠŒŒŽŒœЂœЕВЕЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџопо”–””–””–””–””–”kikJMJЅІЅ!$!JMJkekcacBAB151JMJ:9:џџџџџџџџџsusЅЂЅœšœœžœ{}{RURZYZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцчцЅІЅЕЖЕжзжkikkekkikkekЕЖЕ!!JIJcecc]c:=::9:kmkcacџџџџџџџџџsus:9:ZUZJMJJIJJIJJEJkmkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{}{ŒŽŒ”–””š”ХЦХ151RQRkmk{y{kikJIJBAB„†„ŒŠŒџџџџџџџџџЮЪЮ{y{JEJJIJBEBJMJ„†„џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­Ў­œžœ{}{{}{{}{„‚„{y{sus„‚„„‚„{y{{y{­Ў­ЕЖЕџџџџџџџџџџџџцыцœšœcecЅЂЅжзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџїїїяѓяЮЮЮЅЂЅ„‚„kikc]cRURJIJJEJBEBJIJ”’”џџџџџџџџџџџџџџџџџџїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџfwbuilder-5.1.0.3599/packaging/fwbuilder.spec.in0000644000175000017500000000571511733011756022176 0ustar sylvestresylvestre %define name fwbuilder %define version @VERSION@ %define release 1 %if "%_vendor" == "MandrakeSoft" %define guigroup System/Configuration/Networking %define compgroup System/Configuration/Networking %else %define guigroup Applications/System %define compgroup Applications/System %endif Summary: Firewall Builder Name: %{name} Version: %{version} Release: %{release}%{?dist} License: GPL2 Vendor: NetCitadel LLC., http://sourceforge.net/project/showfiles.php?group_id=5314 Group: %{guigroup} Url: http://www.fwbuilder.org/ Source: http://prdownloads.sourceforge.net/fwbuilder/%{name}-%{version}.tar.gz Packager: Vadim Kurland Buildroot: %{_tmppath}/%{name}-%{version}-root BuildRequires: libxml2-devel, libxslt-devel, openssl-devel %if "%_vendor" == "suse" BuildRequires: qt-devel %else BuildRequires: qt4-devel %endif Obsoletes: fwbuilder-ipt, fwbuilder-pf, fwbuilder-ipf, fwbuilder-ipfw, fwbuilder-pix, fwbuilder-iosacl, fwbuilder-cisco, libfwbuilder, libfwbuilder-devel Docdir: /usr/share/doc %description Firewall Builder consists of a GUI and set of policy compilers for various firewall platforms. It helps users maintain a database of objects and allows policy editing using simple drag-and-drop operations. GUI generates firewall description in the form of XML file, which compilers then interpret and generate platform-specific code. Several algorithms are provided for automated network objects discovery and bulk import of data. The GUI and policy compilers are completely independent, this provides for a consistent abstract model and the same GUI for different firewall platforms. %prep %setup ./autogen.sh %build %configure make -j5 all %install [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT make INSTALL_ROOT="${RPM_BUILD_ROOT}/" install rm -fr $RPM_BUILD_ROOT/usr/share/doc/%{name}-%{version} %clean [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %dir /usr/share/fwbuilder-%version /usr/share/fwbuilder-%version /usr/bin/fwbuilder /usr/bin/fwbedit /usr/bin/fwb_iosacl /usr/bin/fwb_ipf /usr/bin/fwb_ipfw /usr/bin/fwb_ipt /usr/bin/fwb_pf /usr/bin/fwb_pix /usr/bin/fwb_procurve_acl %doc doc/AUTHORS %doc doc/COPYING %doc doc/Credits %doc doc/ChangeLog %doc doc/PatchAcceptancePolicy.txt %doc doc/README.floppyfw %doc doc/README.iosacl %doc doc/README.ipf %doc doc/README.ipfw %doc doc/README.ipt %doc doc/README.pf %doc doc/README.pix %doc doc/README.pix_routing %doc doc/README.routing %doc doc/README.policy_import %doc doc/README.iosacl %doc doc/FWBuilder-Routing-LICENSE.txt %{_mandir}/man1/fwbuilder.1* %{_mandir}/man1/fwbedit.1* %{_mandir}/man1/fwb_iosacl.1* %{_mandir}/man1/fwb_ipf.1* %{_mandir}/man1/fwb_ipfw.1* %{_mandir}/man1/fwb_ipt.1* %{_mandir}/man1/fwb_pf.1* %{_mandir}/man1/fwb_pix.1* %{_datadir}/applications/*.desktop %{_datadir}/icons/hicolor/*/apps/%name.png fwbuilder-5.1.0.3599/packaging/fwbuilder.nsi0000644000175000017500000003104211733011756021420 0ustar sylvestresylvestre; fwbuilder.nsi ; ; !verbose 1 ;-------------------------------- ;Variables Var MUI_TEMP Var STARTMENU_FOLDER ; GENERATION is used to build the path in the registry, it should be coordinated ; with the path defined in FWBSettings class ; !define GENERATION "5.1" !define GENERATION_SHORT "51" !define VERSION "5.1.0.3599" !define APPNAME "FirewallBuilder${GENERATION}" ;------------------------------------------------------------------------------ ; GetWindowsVersion ; ; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/ ; Returns on top of stack ; ; Windows Version (95, 98, ME, NT x.x, 2000) ; or ; '' (Unknown Windows Version) ; ; Usage: ; Call GetWindowsVersion ; Pop $0 ; ; at this point $0 is "NT 4.0" or whatnot Function GetWindowsVersion Push $0 Push $9 ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion StrCmp $0 "" 0 lbl_winnt ; we are not NT. ReadRegStr $0 HKLM SOFTWARE\Microsoft\Windows\CurrentVersion VersionNumber StrCpy $9 $0 1 StrCmp $9 '4' 0 lbl_error StrCpy $9 $0 3 StrCmp $9 '4.0' lbl_win32_95 StrCmp $9 '4.9' lbl_win32_ME lbl_win32_98 lbl_win32_95: StrCpy $0 '95' Goto lbl_done lbl_win32_98: StrCpy $0 '98' Goto lbl_done lbl_win32_ME: StrCpy $0 'ME' Goto lbl_done lbl_winnt: StrCpy $9 $0 1 StrCmp $9 '3' lbl_winnt_x StrCmp $9 '4' lbl_winnt_x StrCmp $9 '5' lbl_winnt_5 StrCmp $9 '6' lbl_winnt_6 lbl_error lbl_winnt_x: StrCpy $0 "NT $0" 6 Goto lbl_done lbl_winnt_5: Strcpy $0 '2000' Goto lbl_done lbl_winnt_6: Strcpy $0 'Vista' Goto lbl_done lbl_error: Strcpy $0 '' lbl_done: Pop $9 Exch $0 FunctionEnd Function .onInit Call GetWindowsVersion Pop $0 StrCmp $0 "NT 4.0" lbl_done check_2000 check_2000: StrCmp $0 "2000" lbl_done check_vista check_vista: StrCmp $0 "Vista" lbl_done lbl_error lbl_error: MessageBox MB_OK "Firewall Builder supports only Windows 2000, Windows XP and Vista platform." Abort lbl_done: FunctionEnd Function un.UninstallSurveyPageText IfFileExists $PROFILE\fwb4*license* +4 0 IfFileExists $PROFILE\Documents\fwb4*license* +3 0 MessageBox MB_YESNO "Help us improve Firewall Builder! If you are \ uninstalling because you don't plan to use the software please fill out \ a short survey to tell us why you are leaving and what we can do better.\ $\n\ $\n\ Click Yes to open the survey in your web browser, click No to exit the \ uninstaller." IDNO +2 ExecShell open "http://www.fwbuilder.org/uninstall_survey.html" ; MessageBox MB_ICONSTOP "Continuing uninstaller" FunctionEnd ;**************************************************************************** ;Include Modern UI !include "MUI2.nsh" ;**************************************************************************** setCompressor lzma Name "Firewall Builder ${GENERATION}" Caption "Firewall Builder installation" OutFile "fwbuilder-${VERSION}.exe" ; Default installation folder InstallDir "C:\FWBuilder${GENERATION_SHORT}" ;**************************************************************************** ; We need to keep installation data and program settings in ; registry folders with different names. QSettings always looks into ; Current User registry first, so if the folders have the same names, ; then we store evaluation key in Current User, while it is better ; to put it in the Local Machine branch. ; ; So, installation data goes to HKLM Software\NetCitadel\FirewallBuilder\2.1 ; and settings to HKCU Software\NetCitadel\FirewallBuilder2_1 ; ; fwbuilder-lm determines folder path for the license file by ; reading key Install_Dir under HKLM Software\NetCitadel\FirewallBuilder\2.1 ; ;**************************************************************************** ; ; Get installation folder from registry if available InstallDirRegKey HKLM Software\NetCitadel\${APPNAME} "Install_Dir" ;**************************************************************************** ;Interface Settings !define MUI_ABORTWARNING ;Start Menu Folder Page Configuration !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\NetCitadel\${APPNAME}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" LicenseText "GNU GENERAL PUBLIC LICENSE" LicenseData "doc\COPYING" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP packaging\fwbuilder-160x60.bmp !define MUI_WELCOMEFINISHPAGE_BITMAP packaging\fwbuilder-164x314.bmp ;**************************************************************************** ; The following macros add PageEx statements !insertmacro MUI_PAGE_LICENSE "doc\COPYING" ; !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER !insertmacro MUI_PAGE_INSTFILES ; Uninstaller starts with a custom page that asks the user to fill survey !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES UninstPage custom un.UninstallSurveyPageText ; Set language !insertmacro MUI_LANGUAGE "English" ;**************************************************************************** ; Request elevated priviliges RequestExecutionLevel admin ;**************************************************************************** ; The stuff to install Section "FWBuilder (required)" ; Set output path to the installation directory. ; SetOutPath $INSTDIR SetOutPath $INSTDIR\resources File src\res\resources.xml File src\res\templates.xml File src\res\objects_init.xml File src\libfwbuilder\etc\fwbuilder.dtd File /r src\res\configlets File /r src\res\help File /r src\res\os File /r src\res\platform File /r src\libfwbuilder\migration SetOutPath $INSTDIR\resources\locale ; we have no working translations for v4 and v5 ; File src\libgui\*.qm SetOutPath $INSTDIR File /oname=COPYING.doc doc\COPYING File "doc\FWBuilder-Routing-LICENSE.txt" File "doc\README.iosacl" File "doc\README.ipt" File "doc\README.ipf" File "doc\README.ipfw" File "doc\README.pf" File "doc\README.pix" File "doc\README.pix_routing" File "doc\README.routing" File /oname=fwbuilder.ico "src\gui\fwbuilder-windows.ico" File /a "src\gui\release\fwbuilder.exe" File /a "src\fwbedit\release\fwbedit.exe" File /a "src\iosacl\release\fwb_iosacl.exe" File /a "src\ipt\release\fwb_ipt.exe" File /a "src\ipf\release\fwb_ipf.exe" File /a "src\ipfw\release\fwb_ipfw.exe" File /a "src\pf\release\fwb_pf.exe" File /a "src\pix\release\fwb_pix.exe" File /a "src\procurve_acl\release\fwb_procurve_acl.exe" File "c:\MinGW\bin\libiconv-2.dll" File "c:\MinGW\bin\libpthread-2.dll" File "c:\MinGW\bin\libgcc_s_dw2-1.dll" File "c:\MinGW\bin\libstdc++-6.dll" File "c:\local\bin\libxml2-2.dll" File "c:\local\bin\libxslt-1.dll" ; Install RCS for these files ; File "c:\local\bin\ci.exe" File "c:\local\bin\co.exe" File "c:\local\bin\rcs.exe" File "c:\local\bin\rcsdiff.exe" File "c:\local\bin\rlog.exe" File "c:\local\bin\diff.exe" File "c:\local\bin\rcslib.dll" ; File "c:\local\bin\netsnmp.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtCore4.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtGui4.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtNetwork4.dll" File "c:\local\qt-everywhere-commercial-src-4.7.3\bin\QtTest4.dll" File /nonfatal /oname=resources\locale\qt_de.qm "c:\local\qt-everywhere-commercial-src-4.7.3\translations\qt_de.qm" File /nonfatal /oname=resources\locale\qt_fr.qm "c:\local\qt-everywhere-commercial-src-4.7.3\translations\qt_fr.qm" File /nonfatal /oname=resources\locale\qt_ru.qm "c:\local\qt-everywhere-commercial-src-4.7.3\translations\qt_ru.qm" ;; Starting with 4.0.2, we now package putty tools with fwbuilder File "c:\PuTTY\plink.exe" File "c:\PuTTY\pscp.exe" ; Write the installation path into the registry WriteRegStr HKLM Software\NetCitadel\${APPNAME} "Install_Dir" "$INSTDIR" ; Write the uninstall keys for Windows WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "DisplayName" "Firewall Builder ${GENERATION}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "Publisher" "NetCitadel LLC" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" "DisplayVersion" "${VERSION}" ; Write file associations and icons WriteRegStr HKLM "Software\Classes\.fwb" "" "fwbfile" WriteRegStr HKLM "Software\Classes\fwbfile\shell\open\command" "" "$INSTDIR\fwbuilder.exe -noexec %1" WriteRegStr HKLM "Software\Classes\fwbfile\DefaultIcon" "" "$INSTDIR\fwbuilder.exe,0" WriteRegStr HKLM "Software\Classes\.fwl" "" "fwlfile" WriteRegStr HKLM "Software\Classes\fwlfile\shell\open\command" "" "$INSTDIR\fwbuilder.exe -noexec %1" WriteRegStr HKLM "Software\Classes\fwlfile\DefaultIcon" "" "$INSTDIR\fwbuilder.exe,0" ; Create registry entry for putty session with ssh keepalive WriteRegDWORD HKCU "Software\SimonTatham\PuTTY\Sessions\fwb_session_with_keepalive" "PingInterval" "0" WriteRegDWORD HKCU "Software\SimonTatham\PuTTY\Sessions\fwb_session_with_keepalive" "PingIntervalSecs" "10" ; ======================================================================== ; Configure installer to use our prepackaged plink.exe and pscp.exe but only if it was not configured before ; ; ******** THESE KEYS MUST MATCH THOSE USED BY the class FWBSettings ; ReadRegStr $0 HKCU "Software\netcitadel.com\${APPNAME}\${GENERATION}\SSH" "SSHPath" StrCmp $0 "" 0 +3 WriteRegStr HKCU "Software\netcitadel.com\${APPNAME}\${GENERATION}\SSH" "SSHPath" "$INSTDIR\plink.exe" WriteRegStr HKCU "Software\netcitadel.com\${APPNAME}\${GENERATION}\SSH" "SCPPath" "$INSTDIR\pscp.exe" ; ======================================================================== !insertmacro MUI_STARTMENU_WRITE_BEGIN Application ; Setting var context to "all" makes Start menu shortcuts appear for all ; users ; SetShellVarContext all CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder on the Web.lnk" "http://www.fwbuilder.org/" "" "$INSTDIR\fwbuilder.ico" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder.lnk" "$INSTDIR\fwbuilder.exe" "" "$INSTDIR\fwbuilder.ico" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 !insertmacro MUI_STARTMENU_WRITE_END WriteUninstaller "uninstall.exe" SectionEnd ;============================================================================= ; uninstall stuff UninstallText "This will uninstall FWBuilder. Hit next to continue." ;============================================================================= Section "Uninstall" ; remove registry keys DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FWBuilder ${GENERATION}" DeleteRegKey HKLM "Software\NetCitadel\${APPNAME}" ; delete obsolete registry folder, not used in v3.x but could be left over from older versions DeleteRegKey HKCU "Software\NetCitadel LLC\Firewall Builder" DeleteRegKey HKCU "Software\netcitadel.com\${APPNAME}" DeleteRegKey /ifempty HKCU "Software\netcitadel.com\${APPNAME}" DeleteRegKey /ifempty HKCU "Software\netcitadel.com" DeleteRegKey HKCR ".fwb" DeleteRegKey HKCR ".fwl" DeleteRegKey HKCR "fwbfile" DeleteRegKey HKCR "fwlfile" DeleteRegKey HKCR "FirewallBuilder.AssocFile.FWB" DeleteRegKey HKCR "FirewallBuilder.AssocFile.FWL" ; remove files ; MUST REMOVE UNINSTALLER, too Delete $INSTDIR\uninstall.exe Delete "$INSTDIR\*.*" Delete "$INSTDIR\migration\*.*" Delete "$INSTDIR\resources\os\*.*" Delete "$INSTDIR\resources\platform\*.*" Delete "$INSTDIR\resources\help\*.*" Delete "$INSTDIR\resources\configlets\*.*" Delete $INSTDIR\COPYING.doc RMDir /r "$INSTDIR" ; !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP ; Delete "$SMPROGRAMS\$MUI_TEMP\*.*" ; StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" ; Remove Start menu shortcuts !insertmacro MUI_STARTMENU_GETFOLDER Application $STARTMENU_FOLDER ; SetShellVarContext all Delete "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder on the Web.lnk" Delete "$SMPROGRAMS\$STARTMENU_FOLDER\FWBuilder.lnk" Delete "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" RMDir "$SMPROGRAMS\$STARTMENU_FOLDER" ; delete only if empty because there could be registry folders ; for our other products DeleteRegKey /ifempty HKLM "Software\NetCitadel" SectionEnd ; eof fwbuilder-5.1.0.3599/packaging/SLA.r0000644000175000017500000007055611733011756017541 0ustar sylvestresylvestredata 'LPic' (5000) { $"0002 0011 0003 0001 0000 0000 0002 0000" $"0008 0003 0000 0001 0004 0000 0004 0005" $"0000 000E 0006 0001 0005 0007 0000 0007" $"0008 0000 0047 0009 0000 0034 000A 0001" $"0035 000B 0001 0020 000C 0000 0011 000D" $"0000 005B 0004 0000 0033 000F 0001 000C" $"0010 0000 000B 000E 0000" }; data 'TEXT' (5002, "English") { " GNU GENERAL PUBLIC LICENSE\n" " Version 2, June 1991\n" "\n" " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n" " 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" " Everyone is permitted to copy and distribute verbatim copies\n" " of this license document, but changing it is not allowed.\n" "\n" " Preamble\n" "\n" " The licenses for most software are designed to take away your\n" "freedom to share and change it. By contrast, the GNU General Public\n" "License is intended to guarantee your freedom to share and change free\n" "software--to make sure the software is free for all its users. This\n" "General Public License applies to most of the Free Software\n" "Foundation\'s software and to any other program whose authors commit to\n" "using it. (Some other Free Software Foundation software is covered by\n" "the GNU Library General Public License instead.) You can apply it to\n" "your programs, too.\n" "\n" " When we speak of free software, we are referring to freedom, not\n" "price. Our General Public Licenses are designed to make sure that you\n" "have the freedom to distribute copies of free software (and charge for\n" "this service if you wish), that you receive source code or can get it\n" "if you want it, that you can change the software or use pieces of it\n" "in new free programs; and that you know you can do these things.\n" "\n" " To protect your rights, we need to make restrictions that forbid\n" "anyone to deny you these rights or to ask you to surrender the rights.\n" "These restrictions translate to certain responsibilities for you if you\n" "distribute copies of the software, or if you modify it.\n" "\n" " For example, if you distribute copies of such a program, whether\n" "gratis or for a fee, you must give the recipients all the rights that\n" "you have. You must make sure that they, too, receive or can get the\n" "source code. And you must show them these terms so they know their\n" "rights.\n" "\n" " We protect your rights with two steps: (1) copyright the software, and\n" "(2) offer you this license which gives you legal permission to copy,\n" "distribute and/or modify the software.\n" "\n" " Also, for each author\'s protection and ours, we want to make certain\n" "that everyone understands that there is no warranty for this free\n" "software. If the software is modified by someone else and passed on, we\n" "want its recipients to know that what they have is not the original, so\n" "that any problems introduced by others will not reflect on the original\n" "authors\' reputations.\n" "\n" " Finally, any free program is threatened constantly by software\n" "patents. We wish to avoid the danger that redistributors of a free\n" "program will individually obtain patent licenses, in effect making the\n" "program proprietary. To prevent this, we have made it clear that any\n" "patent must be licensed for everyone\'s free use or not licensed at all.\n" "\n" " The precise terms and conditions for copying, distribution and\n" "modification follow.\n" "\n" " GNU GENERAL PUBLIC LICENSE\n" " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" "\n" " 0. This License applies to any program or other work which contains\n" "a notice placed by the copyright holder saying it may be distributed\n" "under the terms of this General Public License. The \"Program\", below,\n" "refers to any such program or work, and a \"work based on the Program\"\n" "means either the Program or any derivative work under copyright law:\n" "that is to say, a work containing the Program or a portion of it,\n" "either verbatim or with modifications and/or translated into another\n" "language. (Hereinafter, translation is included without limitation in\n" "the term \"modification\".) Each licensee is addressed as \"you\".\n" "\n" "Activities other than copying, distribution and modification are not\n" "covered by this License; they are outside its scope. The act of\n" "running the Program is not restricted, and the output from the Program\n" "is covered only if its contents constitute a work based on the\n" "Program (independent of having been made by running the Program).\n" "Whether that is true depends on what the Program does.\n" "\n" " 1. You may copy and distribute verbatim copies of the Program\'s\n" "source code as you receive it, in any medium, provided that you\n" "conspicuously and appropriately publish on each copy an appropriate\n" "copyright notice and disclaimer of warranty; keep intact all the\n" "notices that refer to this License and to the absence of any warranty;\n" "and give any other recipients of the Program a copy of this License\n" "along with the Program.\n" "\n" "You may charge a fee for the physical act of transferring a copy, and\n" "you may at your option offer warranty protection in exchange for a fee.\n" "\n" " 2. You may modify your copy or copies of the Program or any portion\n" "of it, thus forming a work based on the Program, and copy and\n" "distribute such modifications or work under the terms of Section 1\n" "above, provided that you also meet all of these conditions:\n" "\n" " a) You must cause the modified files to carry prominent notices\n" " stating that you changed the files and the date of any change.\n" "\n" " b) You must cause any work that you distribute or publish, that in\n" " whole or in part contains or is derived from the Program or any\n" " part thereof, to be licensed as a whole at no charge to all third\n" " parties under the terms of this License.\n" "\n" " c) If the modified program normally reads commands interactively\n" " when run, you must cause it, when started running for such\n" " interactive use in the most ordinary way, to print or display an\n" " announcement including an appropriate copyright notice and a\n" " notice that there is no warranty (or else, saying that you provide\n" " a warranty) and that users may redistribute the program under\n" " these conditions, and telling the user how to view a copy of this\n" " License. (Exception: if the Program itself is interactive but\n" " does not normally print such an announcement, your work based on\n" " the Program is not required to print an announcement.)\n" "\n" "These requirements apply to the modified work as a whole. If\n" "identifiable sections of that work are not derived from the Program,\n" "and can be reasonably considered independent and separate works in\n" "themselves, then this License, and its terms, do not apply to those\n" "sections when you distribute them as separate works. But when you\n" "distribute the same sections as part of a whole which is a work based\n" "on the Program, the distribution of the whole must be on the terms of\n" "this License, whose permissions for other licensees extend to the\n" "entire whole, and thus to each and every part regardless of who wrote it.\n" "\n" "Thus, it is not the intent of this section to claim rights or contest\n" "your rights to work written entirely by you; rather, the intent is to\n" "exercise the right to control the distribution of derivative or\n" "collective works based on the Program.\n" "\n" "In addition, mere aggregation of another work not based on the Program\n" "with the Program (or with a work based on the Program) on a volume of\n" "a storage or distribution medium does not bring the other work under\n" "the scope of this License.\n" "\n" " 3. You may copy and distribute the Program (or a work based on it,\n" "under Section 2) in object code or executable form under the terms of\n" "Sections 1 and 2 above provided that you also do one of the following:\n" "\n" " a) Accompany it with the complete corresponding machine-readable\n" " source code, which must be distributed under the terms of Sections\n" " 1 and 2 above on a medium customarily used for software interchange; or,\n" "\n" " b) Accompany it with a written offer, valid for at least three\n" " years, to give any third party, for a charge no more than your\n" " cost of physically performing source distribution, a complete\n" " machine-readable copy of the corresponding source code, to be\n" " distributed under the terms of Sections 1 and 2 above on a medium\n" " customarily used for software interchange; or,\n" "\n" " c) Accompany it with the information you received as to the offer\n" " to distribute corresponding source code. (This alternative is\n" " allowed only for noncommercial distribution and only if you\n" " received the program in object code or executable form with such\n" " an offer, in accord with Subsection b above.)\n" "\n" "The source code for a work means the preferred form of the work for\n" "making modifications to it. For an executable work, complete source\n" "code means all the source code for all modules it contains, plus any\n" "associated interface definition files, plus the scripts used to\n" "control compilation and installation of the executable. However, as a\n" "special exception, the source code distributed need not include\n" "anything that is normally distributed (in either source or binary\n" "form) with the major components (compiler, kernel, and so on) of the\n" "operating system on which the executable runs, unless that component\n" "itself accompanies the executable.\n" "\n" "If distribution of executable or object code is made by offering\n" "access to copy from a designated place, then offering equivalent\n" "access to copy the source code from the same place counts as\n" "distribution of the source code, even though third parties are not\n" "compelled to copy the source along with the object code.\n" "\n" " 4. You may not copy, modify, sublicense, or distribute the Program\n" "except as expressly provided under this License. Any attempt\n" "otherwise to copy, modify, sublicense or distribute the Program is\n" "void, and will automatically terminate your rights under this License.\n" "However, parties who have received copies, or rights, from you under\n" "this License will not have their licenses terminated so long as such\n" "parties remain in full compliance.\n" "\n" " 5. You are not required to accept this License, since you have not\n" "signed it. However, nothing else grants you permission to modify or\n" "distribute the Program or its derivative works. These actions are\n" "prohibited by law if you do not accept this License. Therefore, by\n" "modifying or distributing the Program (or any work based on the\n" "Program), you indicate your acceptance of this License to do so, and\n" "all its terms and conditions for copying, distributing or modifying\n" "the Program or works based on it.\n" "\n" " 6. Each time you redistribute the Program (or any work based on the\n" "Program), the recipient automatically receives a license from the\n" "original licensor to copy, distribute or modify the Program subject to\n" "these terms and conditions. You may not impose any further\n" "restrictions on the recipients\' exercise of the rights granted herein.\n" "You are not responsible for enforcing compliance by third parties to\n" "this License.\n" "\n" " 7. If, as a consequence of a court judgment or allegation of patent\n" "infringement or for any other reason (not limited to patent issues),\n" "conditions are imposed on you (whether by court order, agreement or\n" "otherwise) that contradict the conditions of this License, they do not\n" "excuse you from the conditions of this License. If you cannot\n" "distribute so as to satisfy simultaneously your obligations under this\n" "License and any other pertinent obligations, then as a consequence you\n" "may not distribute the Program at all. For example, if a patent\n" "license would not permit royalty-free redistribution of the Program by\n" "all those who receive copies directly or indirectly through you, then\n" "the only way you could satisfy both it and this License would be to\n" "refrain entirely from distribution of the Program.\n" "\n" "If any portion of this section is held invalid or unenforceable under\n" "any particular circumstance, the balance of the section is intended to\n" "apply and the section as a whole is intended to apply in other\n" "circumstances.\n" "\n" "It is not the purpose of this section to induce you to infringe any\n" "patents or other property right claims or to contest validity of any\n" "such claims; this section has the sole purpose of protecting the\n" "integrity of the free software distribution system, which is\n" "implemented by public license practices. Many people have made\n" "generous contributions to the wide range of software distributed\n" "through that system in reliance on consistent application of that\n" "system; it is up to the author/donor to decide if he or she is willing\n" "to distribute software through any other system and a licensee cannot\n" "impose that choice.\n" "\n" "This section is intended to make thoroughly clear what is believed to\n" "be a consequence of the rest of this License.\n" "\n" " 8. If the distribution and/or use of the Program is restricted in\n" "certain countries either by patents or by copyrighted interfaces, the\n" "original copyright holder who places the Program under this License\n" "may add an explicit geographical distribution limitation excluding\n" "those countries, so that distribution is permitted only in or among\n" "countries not thus excluded. In such case, this License incorporates\n" "the limitation as if written in the body of this License.\n" "\n" " 9. The Free Software Foundation may publish revised and/or new versions\n" "of the General Public License from time to time. Such new versions will\n" "be similar in spirit to the present version, but may differ in detail to\n" "address new problems or concerns.\n" "\n" "Each version is given a distinguishing version number. If the Program\n" "specifies a version number of this License which applies to it and \"any\n" "later version\", you have the option of following the terms and conditions\n" "either of that version or of any later version published by the Free\n" "Software Foundation. If the Program does not specify a version number of\n" "this License, you may choose any version ever published by the Free Software\n" "Foundation.\n" "\n" " 10. If you wish to incorporate parts of the Program into other free\n" "programs whose distribution conditions are different, write to the author\n" "to ask for permission. For software which is copyrighted by the Free\n" "Software Foundation, write to the Free Software Foundation; we sometimes\n" "make exceptions for this. Our decision will be guided by the two goals\n" "of preserving the free status of all derivatives of our free software and\n" "of promoting the sharing and reuse of software generally.\n" "\n" " NO WARRANTY\n" "\n" " 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n" "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n" "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n" "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" "REPAIR OR CORRECTION.\n" "\n" " 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" "POSSIBILITY OF SUCH DAMAGES.\n" "\n" }; resource 'STR#' (5001, "German") { { /* array StringArray: 9 elements */ /* [1] */ "Deutsch", /* [2] */ "Akzeptieren", /* [3] */ "Ablehnen", /* [4] */ "Drucken", /* [5] */ "Sichern...", /* [6] */ "Klicken Sie auf вAkzeptierenг, wenn Sie mit den Bestimmungen des " "Software-Lizenzvertrages einverstanden sind. Falls nicht, klicken " "Sie bitte вAblehnenг an. Sie kšnnen die Software nur installieren, " "wenn Sie вAkzeptierenг angeklickt haben.", /* [7] */ "Software-Lizenzvertrag", /* [8] */ "Dieser Text kann nicht gesichert werden. Diese Festplatte ist " "mšglicherweise voll oder geschŸtzt oder der Ordner ist geschŸtzt.", /* [9] */ "Es kann nicht gedruckt werden. Bitte stellen Sie sicher, daЇ ein " "Drucker ausgewŠhlt ist." } }; resource 'STR#' (5002, "English") { { /* array StringArray: 9 elements */ /* [1] */ "English", /* [2] */ "Agree", /* [3] */ "Disagree", /* [4] */ "Print", /* [5] */ "Save...", /* [6] */ "IMPORTANT - Read this License Agreement carefully before clicking on " "the \"Agree\" button. By clicking on the \"Agree\" button, you agree " "to be bound by the terms of the License Agreement.", /* [7] */ "Software License Agreement", /* [8] */ "This text cannot be saved. This disk may be full or locked, or the file " "may be locked.", /* [9] */ "Unable to print. Make sure youеve selected a printer." } }; resource 'STR#' (5003, "Spanish") { { /* array StringArray: 9 elements */ /* [1] */ "Espa–ol", /* [2] */ "Aceptar", /* [3] */ "No aceptar", /* [4] */ "Imprimir", /* [5] */ "Guardar...", /* [6] */ "Si est‡ de acuerdo con los tŽrminos de esta licencia, pulse \"Aceptar\" " "para instalar el software. En el supuesto de que no estŽ de acuerdo con " "los tŽrminos de esta licencia, pulse \"No aceptar.\"", /* [7] */ "Licencia de Software", /* [8] */ "Este texto no se puede guardar. El disco puede estar lleno o bloqueado, " "o el archivo puede estar bloqueado.", /* [9] */ "No se puede imprimir. Compruebe que ha seleccionado una impresora." } }; resource 'STR#' (5004, "French") { { /* array StringArray: 9 elements */ /* [1] */ "Franais", /* [2] */ "Accepter", /* [3] */ "Refuser", /* [4] */ "Imprimer", /* [5] */ "Enregistrer...", /* [6] */ "Si vous acceptez les termes de la prŽsente licence, cliquez sur " "\"Accepter\" afin d'installer le logiciel. Si vous n'tes pas d'accord " "avec les termes de la licence, cliquez sur \"Refuser\".", /* [7] */ "Contrat de licence de logiciel", /* [8] */ "Ce texte ne peut tre sauvegardŽ. Le disque est peut-tre saturŽ ou " "verrouillŽ, ou bien le fichier est peut-tre verrouillŽ.", /* [9] */ "Impression impossible. Assurez-vous dеavoir sŽlectionnŽ une imprimante." } }; resource 'STR#' (5005, "Italian") { { /* array StringArray: 9 elements */ /* [1] */ "Italiano", /* [2] */ "Accetto", /* [3] */ "Rifiuto", /* [4] */ "Stampa", /* [5] */ "Registra...", /* [6] */ "Se accetti le condizioni di questa licenza, fai clic su \"Accetto\" per " "installare il software. Altrimenti fai clic su \"Rifiuto\".", /* [7] */ "Licenza Software", /* [8] */ "Non posso registrare il testo. Il disco potrebbe essere pieno o protetto " "oppure il documento potrebbe essere protetto.", /* [9] */ "Non posso stampare. Assicurati di aver selezionato una stampante." } }; resource 'STR#' (5006, "Japanese") { { /* array StringArray: 9 elements */ /* [1] */ "Japanese", /* [2] */ "“Џˆг‚Е‚м‚З", /* [3] */ "“Џˆг‚Е‚м‚Й‚ё", /* [4] */ "ˆѓќ‚З‚щ", /* [5] */ "•л‘Ж...", /* [6] */ "–{ƒ\\ƒtƒgƒEƒGƒAŽg—p‹–‘јŒ_–ё‚Ь№Œ‚Щ“Џˆг‚Г" "‚ъ‚щъ‡‚Щ‚ЭAƒ\\ƒtƒgƒEƒGƒA‚№ƒCƒ“ƒXƒg[ƒ‹" "‚З‚щ‚Н‚п‚Щu“Џˆг‚Е‚м‚Зv‚№‰Ÿ‚Е‚Ф‚­‚О‚Г‚Ђ" "B@“Џˆг‚Г‚ъ‚Ш‚Ђъ‡‚Щ‚ЭAu“Џˆг‚Е‚м‚Й‚ё" "v‚№‰Ÿ‚Е‚Ф‚­‚О‚Г‚ЂB", /* [7] */ "ƒ\\ƒtƒgƒEƒFƒAŽg—p‹–‘јŒ_–ё", /* [8] */ "‚Б‚ЬƒeƒLƒXƒg‚ЭA•л‘Ж‚Х‚Ћ‚м‚Й‚ёB‚Б‚ЬƒfƒB" "ƒXƒN‚Щ‹ѓ‚Ћ‚Њ–Г‚Ђ‚ЉƒƒbƒN‚Г‚ъ‚Ф‚Ђ‚щ‰Т”\\Ћ" "‚Њ‚ ‚ш‚м‚ЗB‚м‚Н‚ЭA‚Б‚Ьƒtƒ@ƒCƒ‹‚ЊƒƒbƒN" "‚Г‚ъ‚Ф‚Ђ‚щ‰Т”\\Ћ‚Њ‚ ‚ш‚м‚ЗB", /* [9] */ "ˆѓќ‚Х‚Ћ‚м‚Й‚ёBƒvƒŠƒ“ƒ^‚ЊГ‚Е‚­‘I‘№‚Г‚ъ" "‚Ф‚Ђ‚щ‚Б‚Ц‚№Šm”F‚Е‚Ф‚­‚О‚Г‚ЂB" } }; resource 'STR#' (5007, "Dutch") { { /* array StringArray: 9 elements */ /* [1] */ "Nederlands", /* [2] */ "Ja", /* [3] */ "Nee", /* [4] */ "Print", /* [5] */ "Bewaar...", /* [6] */ "Indien u akkoord gaat met de voorwaarden van deze licentie, kunt u op 'Ja' " "klikken om de programmatuur te installeren. Indien u niet akkoord gaat, " "klikt u op 'Nee'.", /* [7] */ "Softwarelicentie", /* [8] */ "De tekst kan niet worden bewaard. Het kan zijn dat uw schijf vol of " "beveiligd is of dat het bestand beveiligd is.", /* [9] */ "Afdrukken niet mogelijk. Zorg dat er een printer is geselecteerd." } }; resource 'STR#' (5008, "Swedish") { { /* array StringArray: 9 elements */ /* [1] */ "Svensk", /* [2] */ "GodkŠnns", /* [3] */ "Avbšjs", /* [4] */ "Skriv ut", /* [5] */ "Spara...", /* [6] */ "Om Du godkŠnner licensvillkoren klicka pŒ \"GodkŠnns\" fšr att installera " "programprodukten. Om Du inte godkŠnner licensvillkoren, klicka pŒ \"Avbšjs\".", /* [7] */ "Licensavtal fšr Programprodukt", /* [8] */ "Den hŠr texten kan inte sparas eftersom antingen skivan Šr full eller skivan " "och/eller dokumentet Šr lŒst.", /* [9] */ "Kan inte skriva ut. Kontrollera att du har valt en skrivare. " } }; resource 'STR#' (5009, "Brazilian Portuguese") { { /* array StringArray: 9 elements */ /* [1] */ "Portugus, Brasil", /* [2] */ "Concordar", /* [3] */ "Discordar", /* [4] */ "Imprimir", /* [5] */ "Salvar...", /* [6] */ "Se est‡ de acordo com os termos desta licena, pressione \"Concordar\" para " "instalar o software. Se n‹o est‡ de acordo, pressione \"Discordar\".", /* [7] */ "Licena de Uso de Software", /* [8] */ "Este texto n‹o pode ser salvo. O disco pode estar cheio ou\nbloqueado, ou o " "arquivo pode estar bloqueado.", /* [9] */ "N‹o Ž poss’vel imprimir. Comprove que voc selecionou uma impressora." } }; resource 'STR#' (5010, "Simplified Chinese") { { /* array StringArray: 9 elements */ /* [1] */ "Simplified Chinese", /* [2] */ "ЭЌвт", /* [3] */ "ВЛЭЌвт", /* [4] */ "ДђгЁ", /* [5] */ "ДцДЂЁ­", /* [6] */ "ШчЙћФњЭЌвтБОаэПЩа­вщЕФЬѕПюЃЌЧыАДЁАЭЌвтЁБ" "РДАВзАДЫШэМўЁЃШчЙћФњВЛЭЌвтЃЌЧыАДЁАВЛЭЌвт" "ЁБЁЃ", /* [7] */ "ШэМўаэПЩа­вщ", /* [8] */ "ВЛФмДцДЂетИіЮФМўЁЃДХХЬПЩФмБЛЫјЖЈЛђвбТњЃЌ" "вВаэЪЧЮФМўБЛЫјЖЈСЫЁЃ", /* [9] */ "ЮоЗЈДђгЁЁЃЧыШЗЖЈФњвббЁдёСЫвЛЬЈДђгЁЛњЁЃ" } }; resource 'STR#' (5011, "Traditional Chinese") { { /* array StringArray: 9 elements */ /* [1] */ "Traditional Chinese", /* [2] */ "ІPЗN", /* [3] */ "ЄЃІPЗN", /* [4] */ "ІCІL", /* [5] */ "РxІsЁK", /* [6] */ "ІpЊGБzІPЗNЅЛГ\\ЅiУвИЬЊКБјДкЁAНаЋіЁЇІPЗNЁЈ" "ЅHІwИЫГnХщЁCІpЊGЄЃІPЗNЁAНаЋіЁЇЄЃІPЗNЁЈЁC", /* [7] */ "ГnХщГ\\ЅiЈѓФГ", /* [8] */ "ЅЛЄхІrЕLЊkРxІsЁCГo­гКЯКаЅiЏрЄwКЁЉЮЌOТъЉw" "ЁAЉЮРЩЎзЄwИgТъЉwЁC", /* [9] */ "ЕLЊkІCІLЁCНаНTЉwБzЄwИgПяОмЄFІLЊэОїЁC" } }; resource 'STR#' (5012, "Danish") { { /* array StringArray: 9 elements */ /* [1] */ "Dansk", /* [2] */ "Enig", /* [3] */ "Uenig", /* [4] */ "Udskriv", /* [5] */ "Arkiver...", /* [6] */ "Hvis du accepterer betingelserne i licensaftalen, skal du klikke pŒ вEnigг " "for at installere softwaren. Klik pŒ вUenigг for at annullere installeringen.", /* [7] */ "Licensaftale for software", /* [8] */ "Teksten kan ikke arkiveres. Disken er evt. fuld eller lŒst, eller ogsŒ er " "arkivet lŒst.", /* [9] */ "Kan ikke udskrive. SПrg for, at der er valgt en printer." } }; resource 'STR#' (5013, "Finnish") { { /* array StringArray: 9 elements */ /* [1] */ "Suomi", /* [2] */ "HyvŠksyn", /* [3] */ "En hyvŠksy", /* [4] */ "Tulosta", /* [5] */ "TallennaЩ", /* [6] */ "HyvŠksy lisenssisopimuksen ehdot osoittamalla еHyvŠksyе. Jos et hyvŠksy " "sopimuksen ehtoja, osoita еEn hyvŠksyе.", /* [7] */ "Lisenssisopimus", /* [8] */ "TekstiŠ ei voida tallentaa. Levy voi olla tŠynnŠ tai lukittu.", /* [9] */ "TekstiŠ ei voida tulostaa. Varmista, ettŠ kirjoitin on valittu." } }; resource 'STR#' (5014, "French Canadian") { { /* array StringArray: 9 elements */ /* [1] */ "Franais canadien", /* [2] */ "Accepter", /* [3] */ "Refuser", /* [4] */ "Imprimer", /* [5] */ "Enregistrer...", /* [6] */ "Si vous acceptez les termes de la prŽsente licence, cliquez sur \"Accepter\" " "afin d'installer le logiciel. Si vous n'tes pas d'accord avec les termes de " "la licence, cliquez sur \"Refuser\".", /* [7] */ "Contrat de licence de logiciel", /* [8] */ "Ce texte ne peut tre sauvegardŽ. Le disque est peut-tre saturŽ ou verrouillŽ, " "ou bien le fichier est peut-tre verrouillŽ.", /* [9] */ "Impression impossible. Assurez-vous dеavoir sŽlectionnŽ une imprimante." } }; resource 'STR#' (5015, "Korean") { { /* array StringArray: 9 elements */ /* [1] */ "Korean", /* [2] */ "ЕПРЧ", /* [3] */ "ЕПРЧ ОШЧд", /* [4] */ "ЧСИАЦЎ", /* [5] */ "РњРх...", /* [6] */ "ЛчПы АшОрМ­РЧ ГЛПыПЁ ЕПРЧЧЯИщ, \"ЕПРЧ\" Дм" "УпИІ Д­ЗЏ МвЧСЦЎПўОюИІ МГФЁЧЯНЪНУПР. ЕПР" "ЧЧЯСі ОЪДТДйИщ, \"ЕПРЧ ОШЧд\" ДмУпИІ ДЉИЃН" "ЪНУПР.", /* [7] */ "ЛчПы АшОр ЕПРЧМ­", /* [8] */ "РЬ ХиНКЦЎИІ РњРхЧв Мі ОјНРДЯДй. РЬ Е№НКХ" "ЉДТ ВЫ УЁАХГЊ РсАм РжНРДЯДй. ЖЧДТ ЦФРЯРЬ" " РсАм РжРЛ МіЕЕ РжНРДЯДй.", /* [9] */ "ЧСИАЦЎЧв Мі ОјНРДЯДй. ЧСИАХЭИІ МБХУЧпДТС" "і ШЎРЮЧЯНЪНУПР." } }; resource 'STR#' (5016, "Norwegian") { { /* array StringArray: 9 elements */ /* [1] */ "Norsk", /* [2] */ "Enig", /* [3] */ "Ikke enig", /* [4] */ "Skriv ut", /* [5] */ "Arkiver...", /* [6] */ "Hvis De er enig i bestemmelsene i denne lisensavtalen, klikker De pŒ " "\"Enig\"-knappen for Œ installere programvaren. Hvis De ikke er enig, " "klikker De pŒ \"Ikke enig\".", /* [7] */ "Programvarelisensavtale", /* [8] */ "Denne teksten kan ikke arkiveres. Disken kan vОre full eller lŒst, " "eller filen kan vОre lŒst. ", /* [9] */ "Kan ikke skrive ut. Forsikre deg om at du har valgt en skriver. " } }; fwbuilder-5.1.0.3599/packaging/fwbuilder-makedmg.sh0000755000175000017500000000477211733011756022661 0ustar sylvestresylvestre#!/bin/sh # # Firewall Builder # # Copyright (C) 2012 NetCitadel, LLC # # Author: Vadim Kurland vadim@netcitadel.com # # This program is free software which we release under the GNU General Public # License. You may redistribute and/or modify this program under the terms # of that license as published by the Free Software Foundation; either # version 2 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 General Public License for more details. # # To get a copy of the GNU General Public License, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # MODULE_NAME=$1 BUNDLE=$2 test -z "$BUNDLE" && { echo "Usage: fwbuilder-makedmg.sh MODULE_NAME " exit 1 } # assuming the top of fwbuilder module source code is cwd when this # script is executed BUILD_ROOT_DIR="../../" . VERSION BASE_DMG_FILE_NAME=$(basename $BUNDLE | sed 's/\.app/.dmg/') BASE_RO_DMG_FILE_NAME=$(basename $BUNDLE | sed 's/\.app/-ro.dmg/') SLA_FILE="packaging/SLA.r" DMG_FILE="${BUILD_ROOT_DIR}/$BASE_DMG_FILE_NAME" DMG_RO_FILE="${BUILD_ROOT_DIR}/${BASE_RO_DMG_FILE_NAME}" /usr/bin/hdiutil create -srcfolder $BUNDLE \ -ov -fs HFS+ -volname "Firewall Builder $VERSION" $DMG_FILE # chmod 0664 $DMG_FILE # ################################################################ # How to add license agreement to the dms image # # http://developer.apple.com/documentation/DeveloperTools/Conceptual/SoftwareDistribution/Containers/chapter_3_section_4.html # # Need "Software License Agreements for UDIFs (DMG)" # http://developer.apple.com/sdk/index.html # Instructions are in this package. The SLA prototype in this SDK was in # a format that requires resource editor which I could not find. However # SLA prototype file provided in the buildDMG package found at # http://www.objectpark.org/buildDMG.html was usable. The prototype comes # in file SLA.r which can be edited with XCode (just do "open SLA.r"). # I added NetCitadel license text to the file SLA.r and checked it in # as modules/fwbuilder/files/packaging/SLA.r hdiutil convert -format UDCO $DMG_FILE -o $DMG_RO_FILE hdiutil unflatten $DMG_RO_FILE Rez /Developer/Headers/FlatCarbon/*.r $SLA_FILE -a -o $DMG_RO_FILE hdiutil flatten $DMG_RO_FILE mv $DMG_RO_FILE $DMG_FILE fwbuilder-5.1.0.3599/packaging/fwbuilder.spec0000644000175000017500000000571611733011756021572 0ustar sylvestresylvestre %define name fwbuilder %define version 5.1.0.3599 %define release 1 %if "%_vendor" == "MandrakeSoft" %define guigroup System/Configuration/Networking %define compgroup System/Configuration/Networking %else %define guigroup Applications/System %define compgroup Applications/System %endif Summary: Firewall Builder Name: %{name} Version: %{version} Release: %{release}%{?dist} License: GPL2 Vendor: NetCitadel LLC., http://sourceforge.net/project/showfiles.php?group_id=5314 Group: %{guigroup} Url: http://www.fwbuilder.org/ Source: http://prdownloads.sourceforge.net/fwbuilder/%{name}-%{version}.tar.gz Packager: Vadim Kurland Buildroot: %{_tmppath}/%{name}-%{version}-root BuildRequires: libxml2-devel, libxslt-devel, openssl-devel %if "%_vendor" == "suse" BuildRequires: qt-devel %else BuildRequires: qt4-devel %endif Obsoletes: fwbuilder-ipt, fwbuilder-pf, fwbuilder-ipf, fwbuilder-ipfw, fwbuilder-pix, fwbuilder-iosacl, fwbuilder-cisco, libfwbuilder, libfwbuilder-devel Docdir: /usr/share/doc %description Firewall Builder consists of a GUI and set of policy compilers for various firewall platforms. It helps users maintain a database of objects and allows policy editing using simple drag-and-drop operations. GUI generates firewall description in the form of XML file, which compilers then interpret and generate platform-specific code. Several algorithms are provided for automated network objects discovery and bulk import of data. The GUI and policy compilers are completely independent, this provides for a consistent abstract model and the same GUI for different firewall platforms. %prep %setup ./autogen.sh %build %configure make -j5 all %install [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT make INSTALL_ROOT="${RPM_BUILD_ROOT}/" install rm -fr $RPM_BUILD_ROOT/usr/share/doc/%{name}-%{version} %clean [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %dir /usr/share/fwbuilder-%version /usr/share/fwbuilder-%version /usr/bin/fwbuilder /usr/bin/fwbedit /usr/bin/fwb_iosacl /usr/bin/fwb_ipf /usr/bin/fwb_ipfw /usr/bin/fwb_ipt /usr/bin/fwb_pf /usr/bin/fwb_pix /usr/bin/fwb_procurve_acl %doc doc/AUTHORS %doc doc/COPYING %doc doc/Credits %doc doc/ChangeLog %doc doc/PatchAcceptancePolicy.txt %doc doc/README.floppyfw %doc doc/README.iosacl %doc doc/README.ipf %doc doc/README.ipfw %doc doc/README.ipt %doc doc/README.pf %doc doc/README.pix %doc doc/README.pix_routing %doc doc/README.routing %doc doc/README.policy_import %doc doc/README.iosacl %doc doc/FWBuilder-Routing-LICENSE.txt %{_mandir}/man1/fwbuilder.1* %{_mandir}/man1/fwbedit.1* %{_mandir}/man1/fwb_iosacl.1* %{_mandir}/man1/fwb_ipf.1* %{_mandir}/man1/fwb_ipfw.1* %{_mandir}/man1/fwb_ipt.1* %{_mandir}/man1/fwb_pf.1* %{_mandir}/man1/fwb_pix.1* %{_datadir}/applications/*.desktop %{_datadir}/icons/hicolor/*/apps/%name.png fwbuilder-5.1.0.3599/packaging/fwbuilder-164x314.bmp0000644000175000017500000045565611733011756022362 0ustar sylvestresylvestreBMЎ[6(Є:x[#.#.џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџїћїїїїїїїяѓяяѓяїїїїїїїћїїћїџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяѓяопоолооуоцуцїїїџџџџџџџџџџџџџџџџџџџџџџџџїїїцчццыцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџцыццчцоуоопооложзжжвжЮЮЮХЦХХТХНОННОНЕКЕЕЖЕЕЖЕЕЖЕНКННОННОНХТХХЪХЮЮЮжзжжзжолоопоцуццчццчцопожвжХТХ­Ў­Œš”ŒšŒНКНЮЪЮопоїїїџџџџџџџџџџџџжвжœІœ„Ž„œЂœНОНжзжцчцїїїїїїцчццуцоуоцуццчццчццчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїцчцопоолоЮвЮНТНЕВЕЅІЅœšœŒŽŒ„†„{}{sussqssqskmkkmkkikceccaccacc]cc]ccacZ]ZZ]Zcaccackiksqs{}{ŒŠŒœžœЅІЅ­Њ­ЅІЅ”’”s}sBmJ!m1!u1BiJRuZsŽ{ХЦХцчцџћџопо„’„)a:M!i)])BeJ”ž”­Ў­­Ў­Œ–Œcyccyk{Š{{†{{Ž„”ž”НТНжзжцыцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїцчцопожвжНКНЅЊЅ”–”„†„{}{„†„„†„„†„„†„„†„„‚„„‚„„‚„„‚„{}{{}{{y{sussqssqskmkkikcacc]cZ]ZZUZRQRRQRJIJBEBBAB:9:151151:9::A:)Q1a)m1i)!†B)ŽBu1a!BmJœІЅœЂœBuR])E!])q:])a))]:)Q1!Y1Q!IY!EY!]!EBeJ­Њ­ЮвЮїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїцуцжлжХТХЅЊЅŒŽŒsussus{}{ŒŠŒ”–”œžœœžœœžœœžœœžœ”š””’””’”ŒŽŒŒŽŒŒŠŒ„†„„‚„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJMJJIJBEB:=:111) )I)Y!AI!])e)!‚:q1]!e)Y)Y)e1!yBY)U)]1!q:)‚BY)Q!e)i)!q1a!]!!y1EIYBeJЕЖЕжзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяѓяопоХЦХЅЂЅsuscaccackmk{}{ŒŠŒ”’”œšœЅЂЅЅІЅЅІЅЅІЅЅІЅЅЂЅœžœ”š””–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJEJ:=:)51I)y:q:])Q!!‚:q1a!m)U!IQ)e1)†J1’Jq:1’J)y:!q:M!A!U!i)M!i)m)!y1e)]!e)QQkykНТНопоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїопоНОНŒŠŒZYZJIJRURcackmk{y{„†„”’”œšœЅЂЅЅІЅЅЊЅ­Њ­­Њ­ЅІЅЅЂЅœžœœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJEJB9:!M1}1)’J)ŽJa)u1!ŽB!ŠBi)1ŠB!m:i:e:)ŽR1–R:ЎZ!u::ŽJ1y:!e1a1Q!=q1q1=)Ž:q)]!i)!Š:Y!m)a)Œ’”ЮЪЮцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцчцЮЮЮŒŽŒJMJ:9:JEJRQRZ]Zkiksus„‚„ŒŠŒ”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­ЅІЅЅІЅœžœœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJB=B)E1}:BЎZRЪsBЊZ}:)’J!†:u1Ia:1ŽR!uB1šZ)’R1šR)ŽJ:šRm1a1!q:])m1!ŠB}:!u11’Be!Ue!!}1q)!Š:e!1]:­Ў­жзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуцНКНZ]Z111:9:BABJIJRURc]ckiksus{}{ŒŠŒ”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­ЅЊЅЅІЅœžœœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBAB:5:!i11žJ1žR)ŽBUe!!†:†:!y:mB!yJJВkRВk!uJ}Jq:!u:)’J!}:!ŽBi)q11šJ!‚:)’Bi)MQYUu1)šBm)a!kykХЪХцыцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцчцЕЖЕJIJ111:5::=:BEBJMJRURZ]Zkiksus{}{ŒŠŒ”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­ЅЊЅЅІЅœЂœœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBAB:5:!Q1!’B!ŽBu1!šJ)ЊR!’Bi!!Š:1šR:ІcU1:’ZcЮ{RЎkZВkBІZ1šRi)1šJi))ŠB!y1u1}1i!)‚1!‚1Mi)!‚:}1Ue!1e:НОНцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮRQR111151:9::=:BEBJMJRURZ]Zkiksus{}{ŒŠŒ”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­ЅЊЅЅІЅœЂœœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEB:=:191!y:!žB)ЂJ:КZ1ВR1ЊR‚1!Š:y1!†Bi:!}B:žRBšRRІZcЮscз{1ŽBi))‚:1šJ}:y1y1u)q)!y111’B1–BUm)!}1BeJНОНцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”’”1-1111151:9::=:BEBJMJRURZ]Zkiksus{}{ŒŠŒ”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­ЅЊЅЅІЅœЂœœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEBB=B1-1!M)–:–B:ОcJЮk1ЎR!’:}1i))–J1ЂRu1q1ŽB1ЎZ)žJ!’B!Ž:†:)ЂJ}1!’B!†:!u1:ЂJq)a!a!e!u1!}1!}1y1ZmZНКНопоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkmk151151151:9::=:BEBJMJRURZ]Zkiksqs{}{ŒŠŒ”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­­Њ­ЅІЅЅЂЅœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEBB=B111!A)Š1’1:ЖR)ЊR)ІJBКZ!Ž:†:‚:!†B!†B}:1ЂR!šJŽBŠ:y1}1)ІJq)!’B1ЊR)’B!Š:Uy)Š:m)!‚:i)m)y1)Q1{†„жвжџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџsqs151151151:9::=:BEBJMJRURZ]Zkeksqs{}{„†„”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­­Њ­ЅІЅЅЂЅœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEBB=B151!Y)š::КR1ВRJЪk:ВR1ІJ!–:)ЊJ)žR)šJJЦkcч„:ЊZ}1‚:!žJŠBŽB’J!–B1ЎR!šBy)Ž:q!!–:}1q)!‚:e)!‚1e)I!i)kŠkолоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœšœ151151151:9::=:BEBJMJRURZ]Zkeksqs{}{„†„”’”œšœЅЂЅЅІЅ­Њ­­Њ­­Њ­­Њ­ЅІЅЅЂЅœšœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEBBAB151)Y11ЖR:КR)ІBRвs1ЎRBЖZ!†1!šBBТc1КZ’:š:)ЎJ!ІJ!ЂJžJBТkBЪk1ЖZ)žJJЪkJЪkŠ1u)†1Ž:1ЂJ!Š:u1Y!m)e)!q1)Š:}1sŽsяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЪЮ:9:151151:9::=:BEBJMJRURZ]Zkeksqs{}{„†„”’”œšœœЂœЅІЅ­Њ­­Њ­­Њ­­Њ­ЅІЅЅЂЅœžœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEBBAB:5:)=1–:JЮcJЮk–:!ЊJ:ЖZy1!–:)ЊJ:Оc)ЊRšBŽ1ЂB1ВR–:Š)’:)ЎR:ЖRBЖZsч{q)m!u)u)1ЂJ!†:y1!‚:!}:)u:)†B:ЂJ!†:a!œЊЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџJIJ151151:9::=:BEBJMJRURZ]Zcecsqs{}{„†„”’””š”œЂœЅІЅ­Њ­­Њ­­Њ­­Њ­ЅІЅЅЂЅœžœ”–””’”ŒŽŒŒŠŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcecc]cZYZZUZRURJMJJMJJIJBEBBAB:9:)=1!‚:1ВR!ЂBŽ1!ЂJ:ЖZa!Ž1ž::ЖZ!ІJ!ЂB:ТZЂ:Ž)’1Ž1!’1:ЎJ1ЎRBОZ:ІJ]i!‚1)šJ)žJy1i)!’Bi))e1Iu):ЎR)’BB‚Jџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkmk151151:9::=:BEBJMJRURZ]Zcecsqs{}{„†„”’””š”œЂœЅІЅ­Њ­­Њ­­Њ­­Њ­ЅІЅЅЂЅœžœ”–””’”ŒŠŒ„†„„‚„{}{{y{sussqskmkkikceccacZ]ZZYZRURRQRRQRJMJJIJJEJBABBAB:=::5:)I1–1Ђ:!šB)ЊJ!–B]!a!Ž:)ЖR1КZ:ТZ:ЪZЊ:–)†!Ž)!ЂB1ЎJ!žB!ЂJBЦc}1‚:Qi):ЎR!ŽBq1u1m1)‚B:šJe!au)JŽcџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151:9::=:BEBJMJRURZ]Zcecsqs{y{„†„ŒŽŒ”–”œžœЅІЅЅЊЅ­Њ­ЅЊЅЅІЅЅІЅЅІЅЅЂЅЅЂЅЅІЅ­Њ­­Ў­ЕЖЕЕВЕЕВЕЕЖЕЕЖЕЕВЕ­Ў­­Њ­œšœ”–”ŒŽŒ„‚„suskikZYZRQRJIJBAB:9::9:151191!i1)Y1)9)!E)y)u)Q!Ž:)КR)ОR)КRЊ:!Ў::ТRž1ЎJЊBŽ))ЊJ)ЎRŽ1)žJ)’Ba!u):šJq)m)a!e))‚B:ВRBЎR1šJ}1sš{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНОН111151:9::=:BEBJMJRQRZ]Zcecsqs{y{„†„ŒŽŒ”–”œžœЅЊЅ­Ў­НКНХЦХЮвЮжзжопоцчцяыяцчцоуоопожзжжвжжвжЮЮЮЮЪЮХЪХХЦХХТХХЦХХТХНОННОННОННКННКНЕВЕЅЂЅ”’”„‚„kmkZYZBEB:5:1-11-11(1)A1q1q!ž1ЖB:ЮZ1ЦR!ЎB!ЎJ1ЪcЊ:!ЎB!ВJ)ВR†)Š1:ЊRBЊJy)e!!‚:1ŽJU)m1a)!y:1’J)–B)žJ)–B!‚:ЕОЕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуц:9:151:9::=:BEBJMJRURZ]Zceckmk{y{ŒŠŒœšœ­Ў­НОНХЪХЮЮЮХЦХНОНЕВЕЅЂЅ”’”„‚„sussqskmkkikcac„‚„„‚„Z]Zc]cZ]ZZ]ZZ]ZZYZZ]ZZYZZ]ZZ]Zcaccackiksqs{y{„†„ŒŽŒ„†„ŒŽŒ„†„sqsZ]ZJIJ:5::51!Š:!ОJ)ТJ)ТJ!КJ!ЖB!ВBВB)ЖJ:ЦZ:Ъc!ЊJy!ЂB:КZ!Š:BЖZUBЊZ:žR:–R1ŠJY!!u1!‚:y1)’B)šJ:†RопоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRQR151:9:B=BBEBJMJRQRZYZkmk„†„œžœ­Ў­ЕВЕ­Њ­œšœ„†„suskmkkikkiksqs„‚„”’””–””š”œšœœЂœЅІЅ”’”ЮЮЮЅІЅ­Њ­ЅІЅЅІЅœšœŒŠŒŒŽŒ”’”ŒŠŒ„‚„{y{kmkcacZYZRURJIJJMJ{}{RURRURcacsqssqssqsk]c:}JЖB)ТJ)ТJ!ОJКBЖB!ЖJBЪcJлk1ЦZ!ВJš:1КZ:КZ)ВZ!ІR–Bq1:ŠJ)qBY)u1!u1BВZ:ІRm))žJ:uJЅІЅжлжяяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{y{151:9::=:BABJIJcac„‚„œžœœЂœ”–”„†„{y{kikkik{}{”–”ЅЂЅНОНжвжжзжопоцчццчццуцопооложвж”’”опоХЦХНОННКНЕЖЕЕВЕ­Њ­ЅЊЅЅЊЅœžœЅЊЅЅІЅ”š””’””’”ŒŠŒŒŽŒkikЅЂЅsusJMJBEB:=::=:BABRQRReR!ІB1ЪR1ЪR1ЪR1ЦRBвcBвcBЮc!ЖB:ЪcJзk)ЖR!ЊJ!ЊJ1ОcЂJ)ЊR)žRm1U!i))†:!}1!ŽBBЖc1ЂR)žJ1eBkak{y{­Њ­жзжцыцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœžœ151:9::9:JMJsqs”’””–”„‚„kmkceckik­Ў­ЕВЕНКНЮЪЮжвжолоопоцуццчццчццчццчццуцоуоопожзж”’”оуоЮЪЮХЦХНТННКНЕЖЕ­Ў­ЕВЕЕВЕ­Ў­ЅЊЅЅІЅœЂœ”–””–”œšœœžœkikŒŽŒœžœŒŠŒ{y{kmkZ]ZJMJ:9:1-1!e1ž:)ІJ!ОJ)ЪR!ТJВ:ЖB!ЦR!ЖJ)ОR1КR:Цc!ІJ!ЂB!ЂB1ЖZ1ЎR†1‚1!‚:JВcBВZBВZ)šJBЎZy1:iJ{qssuskiksus­Њ­жзжцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХТХ111151ZUZ„†„ŒŽŒ{}{kikcecsusœšœsusœžœжвжЮЪЮЮЮЮжзжопоцуццыцяыяяыяяяяяыяцыццчццуцоло”’”цуцжвжЮЮЮХЦХХТХНКНЕЖЕЕВЕ­Ў­­Њ­ЅІЅЅІЅЅІЅЅІЅ”š”œžœœžœkik”’”­Њ­ŒŽŒ„‚„ŒŠŒŒŠŒ„‚„susZYZ:I:!M)!U)!Њ:)ЖJ!ТJ:ЮZ:вc!ТJ!ЎB1КRž11ЖR!ІJ)ЎJ!ЊJŽ:q1}))–J)šJJТc:ЎR!ŽB†:Š:!q:cqk{y{{y{{y{{y{ŒŽŒ{y{ЅЊЅжзжцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцыц:9:RUR„†„„†„kmkcackmkŒŠŒœšœ­Ў­{y{œšœжзжЮЮЮжзжолоцуццыцяяяяяяяяяяяяяяяяяяяыяцчцоуо”’”цчцжзжЮвЮЮЪЮХЦХНОННКНЕЖЕЕЖЕЕВЕ­Њ­­Њ­­Њ­­Ў­­Њ­œЂœЅІЅsusŒŽŒЅЂЅœžœ”š””–””’”„†„„‚„{y{kmkRYR:A:-!!$!)e:)šB!Š:1ТZ1ЦZ!ЎB!ЊBІBЎB!šB)e:cykkŽsJŽZ!šB!–BRšcZ–k1ŠJ‚11yJsys„‚„„‚„{}{{y{{}{œžœŒŠŒsus{y{ЅІЅжвжцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџcac{y{„‚„kikcac{y{„†„”’”œЂœЕВЕ{}{œšœжзжжвжолооуоцчцяыяяяяяѓяяѓяяѓяяяяяяяяыяцыцоуо”’”цчцжзжжвжЮЪЮХЦХХТХХТХНОННОННОН­Ў­­Њ­­Њ­­Ў­­Ў­ЅІЅœЂœsus”–”ЅЂЅœšœœšœ”š””–”ŒŠŒ„†„„†„„‚„sus{y{RMR!:MB:UB:КZBвc!КJ!ВB!ВB)žJRiZRMRBABc]c{†„JŽZsŽ{”’”Œ‚„„†„s‚{„‚„Œ†Œ„†„„†„„‚„„‚„„‚„œšœŒŽŒ„†„ŒŠŒ„‚„{}{ЅЂЅжвжцчцџџџџџџџџџџџџџџџџџџџџџџџџцчцопоопоцуцяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”’”„‚„kmkcacsus„‚„ŒŠŒ”–”ЅЂЅЕЖЕ{}{œšœоложвжопоцуццчцяяяяѓяяѓяяѓяяѓяяяяяяяяыяцыццуц”’”цчцжзжжвжЮЮЮЮЪЮЮЪЮХТХНТНХЦХХТХНКНЕВЕ­Ў­­Њ­­Ў­ЅЊЅ­Њ­„‚„”’”ЕЖЕЅЂЅœžœœšœœžœ”–”œšœ”’”ŒŠŒŒŠŒ”’”ŒŠŒRUR!!:mB!ЖJ!ОJЎBš:1’Jkuk„y„{}{RQR{y{RURc]cŒŠŒ­Њ­œžœŒŠŒ„†„„†„„†„„†„„†„„†„„†„„‚„œžœŒŽŒŒŠŒŒŽŒŒŽŒ”’”„†„„‚„ЅЂЅЮЮЮцчцџџџџџџџџџџџџоуожвжНТН­Ў­”ž”­Ў­ЮЪЮолоцчцџџџџџџяѓяяяяїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅ{y{ceckiksus{}{ŒŠŒ”–”ЅІЅЕЖЕ{}{œšœоложзжопоцчццыцяяяяѓяяѓяяѓяяѓяяяяяяяяыяцыцоуо”’”цчцжлжжзжЮвЮХЪХЮЪЮХЦХХЦХХЦХХТХНКНЕЖЕЕЖЕЕВЕ­Ў­­Ў­­Ў­„†„”’”ЕВЕЅЂЅ”–”œžœœšœœšœœžœœžœœžœ”’””’””–”„‚„)$):A:J‚Z1žJ)–BZ}c{}„„}{ŒŠŒ{}{RURЅІЅ„‚„susZ]ZZ]Z„†„ЅІЅœЂœŒŽŒ„†„„†„ŒŠŒŒŠŒŒŠŒ„‚„œžœ”–””–”ŒŽŒŒŽŒŒŽŒŒŽŒ”–”ŒŽŒ„‚„œžœЮЪЮцуцопожвжНОНœЂœk‚s1qBu1!e1Ryc{Š{ЕЖЕЮвЮЮЮЮЮЪЮНТНЮЪЮжзжопоцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЪХkmkcackiksus„‚„ŒŠŒ”š”ЅІЅЕЖЕ{}{œšœоложзжопоцчцяыяяяяяѓяїѓїяѓяяяяцуцжзжЮЮЮХЪХНТНœЂœХЦХЮЪЮЮвЮЮЮЮЮЮЮХЪХХЦХХЦХХТХХТХНТНЕКЕНКНЕЖЕЕВЕЕВЕ­Ў­sus”’”ЕЖЕЅЂЅœžœœžœœšœЅЂЅ”š”œžœœžœ”–”œžœŒŠŒ„‚„1-1RUR{q{sqs{}{„}„ŒŠŒŒŠŒ„‚„„‚„RURœžœ{}{„‚„„†„sqsZ]Zcac„‚„ЅЂЅЅІЅ”–”ŒŠŒ„†„ŒŠŒ„‚„œЂœœžœŒŽŒŒŽŒ”’””’”ŒŽŒŒŽŒ”’””–””’”„†„”’”­Њ­œžœc‚k!uBm1m1!‚By:i)a!!i1”–”œžœk†s:qJRyZŒ–Œ”ž”ЕЖЕопоџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŒŠŒcackiksus„†„ŒŽŒœšœЅІЅЕЖЕ{}{œšœопожзжоуоцчцяыяяяяяѓяяѓяцчцХЪХ­Ў­œžœ”’”ŒŠŒ„‚„kikŒŠŒЕВЕжзжжлжопоопоЮЮЮжвжжзжЮвЮЮЪЮХЦХНОНЕЖЕЕВЕ­Ў­­Ў­susœšœЕВЕœšœЅЂЅЅЂЅœšœ”–”œšœЅІЅ”š””’””–””’”„‚„)()RQR”’”œžœ”–”Œ†Œ„†„ŒŠŒ„†„„‚„RURœžœ{}{„‚„„‚„{}{{}{susceccec„‚„ЅІЅ­Ў­œšœŒŠŒ„‚„œЂœ”’”ŒŠŒŒŽŒ”–””’””–””–””–””–”œšœ”’”„‚„sms:aBi)!†B1žJ:ІR!‚B:ЎZ)’B)’B!Š:)e:)Y:e)!†:i)e)m)!i1„–„жзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћї„‚„kiksusŒŠŒ”–”ЅЂЅ­Њ­НОН{}{œšœопоолооуоцыцяяяїїїїћїяяяЮЪЮЕКЕ­ВЕ­ВЕЕЖЕЕКНЕОНЅЊ­JIJ„†„НКННКНЕЖЕНКННКННКННКННКННТНХЦХЮЮЮЮвЮЮЮЮХЪХХЦХ„‚„”–”ЕЖЕœžœœžœœšœœžœ”–”œžœœšœœšœœžœ”’””’”{}{111151)-)111cecœžœ­Ў­œšœ„†„ŒŠŒ{}{RURœžœ{}{{}{„‚„{}{{}{„‚„„‚„{}{sqskmk„‚„ЅІЅЕВЕŒŽŒœžœŒŽŒŒŠŒ”–””’””’””’””’””’””–””–”ŒŠŒ„}„RqZq:!’J)†Bu:)†BBЎZZЮsRЪk:ЊR)šB!‚1q1!‚B!y:)’Ju1e!!‚1!Ž:cŠkоуоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџsqs{y{ŒŠŒœžœ­Њ­ЕВЕХТХ„‚„œžœяяяцчццыцоуооложзжжвжХЪЮЕОНœІЅŒ’”s}{kqskmkkusЕКН15:c]cŒŽŒ”–”„†„{}{{}{sqskikkikceccaccaccackmk{}{”–”kmk{y{НКНЕКЕЕЖЕ­Њ­ЅЂЅ”–””–”œšœœžœœšœ”’”ŒŽŒ{}{:9:JIJcacZ]Z!$!:=:ZYZ”’”­Ў­ЅІЅ„‚„RURЅЂЅ„‚„„†„„†„„‚„„‚„„†„„†„ŒŽŒŒŠŒ„‚„sqs{}{„†„ŒŽŒЅІЅ­Ў­œšœ”’””’”ŒŽŒŒŽŒ”’””’””–””–”ŒŽŒ{}{1yJŽB!žR:–R)ŠJJТk!ŠBRЮsZЪke!]‚1!‚:)‚B1–JJЦkBЖZJОZ:ІJ)Ž:a„šŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{}{{}{ŒŽŒœЂœ­Ў­НОНжзжŒŽŒ„‚„НКНœžœŒŽŒ”’”œžœ­Њ­НКНХЪЮ”žœJMJ)-)!!$)­ВЕ1=B„‚„ХЦХоложвжЮЪЮЮЪЮ”–”œžœНТНЅЊЅœšœ”’”ŒŠŒ{y{kikRURJIJJEJJEJRQRsqsŒŠŒœžœ­Ў­ЅЊЅœžœ”’””’””’”ŒŽŒ{y{:5:BEBcackmk:=:”–”Z]ZBABRQRŒŠŒЅІЅZ]ZЅЂЅ„†„ŒŠŒŒŠŒŒŠŒŒŠŒŒŽŒŒŽŒ”’””’”ŒŠŒ{}{­Њ­„‚„„‚„ŒŠŒЅІЅНКНЕВЕœžœ”’””’””–””–””–””–””’”Œ‚„JuZ}:‚:‚B1’J]!y1:ЎZBКc:ЎR!†:Ya!1’J:ЊZZвsZЪky1†1BЎR1–Bm)НЦНџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„†„„‚„”’”­Ў­ХТХ­Ў­„†„ZYZRURcec„‚„ЅЊЅНОН”’”цыцїѓїопо”žœ)-))()­ВЕ1=B„‚„ЮЪЮопооложзжжзжœšœЅЊЅжзжХЦХХТХХЦХХЦХНКНЕЖЕ­Њ­ЅЂЅ”’”{}{kekJMJ:=::9:JIJkmkŒŽŒЅІЅœšœŒŽŒŒŠŒsus151BEBcackmk:=:ЅЂЅŒŽŒ„†„kmkJMJJMJZ]Z­Њ­ЕВЕœžœŒŽŒŒŽŒ”–””–””’””’””–””’”{}{ЕВЕ”’””–”ŒŽŒŒŠŒŒŽŒЅІЅНОННКНЅЊЅœšœ”š””š”œšœ”–”ŒŠŒc}km)q1‚:!†1y))šB:ІR1ЊR1ЎRBОZ1žJ}1y1u1JЦkZЦk)†:]i!!Š:‚1ЅВЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”’”ŒŽŒ­Њ­œžœZYZ:=:RQR„‚„­Њ­ХЦХжлжцчцоуо”’”яяяїїїопо”žœ111!!151­ВЕ1=B„†„ЮЮЮопожзжжвжжзжœžœЅІЅжзжНОННОННОНЕЖЕЕВЕЕЖЕ­Ў­­Ў­­Ў­­Њ­ЅІЅœžœ”–”{}{c]c:=:)-)JIJ„†„œžœ”–”sus111BEBcackmk:=:œЂœŒŠŒŒŠŒ”’”ŒŽŒ{}{cacRQRsus­Њ­НОНЕВЕœšœ”–”œšœœžœœžœœšœ„‚„НКН”–”œžœœšœœžœœšœ”’””’”ЅІЅНОННОН­Ў­œЂœœžœœšœ”’”{Ž„}11ІJ:ЊJ:КZ:ЖR1ЊJ:ВZBКZ:ЎR!–B)šBm)])’B1ІR:ЎZBОcJЖZy1u1y1ХЮХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЂЅ”š”ZYZ151Z]ZœžœНОНЮвЮжвжжзжжзжопооло”’”яяяїѓїопо”žœ15:!!!$!)():=:­ВЕ1=B„†ŒЮЮЮопооложзжжлжœžœЅІЅжвжХТХНОНЕКЕЕЖЕЕВЕЕЖЕЕВЕ­Ў­­Њ­ЅІЅЅЂЅЅЂЅœžœœžœœЂœcacRURZYZ)()JEJ”’”{}{)-)BEBcacsqs:=:œЂœŒŠŒŒŽŒŒŽŒŒŽŒ”’””–”ŒŽŒkmkZYZsqsЅІЅХЦХНКНЅІЅœšœœšœœšœ„†„НОНœšœЅЂЅœžœœžœЅІЅЅЂЅЅЂЅœšœ”–”ЅІЅНКНХТХЕВЕЅЂЅ”–”œЂœRŠc})}!1ЊJJТccч{!š:1ІJ!Ž:!‚1)’B!†:!Ž:!žBBЖZBЖZ1ІJ1ІJBВZ!†:1‚JяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЂЅBABRQR”–”НОНХТХХЦХЮЪЮЮЪЮЮЮЮжзжолооло”’”яяяїѓїопо”šœ:9:)$))-)111BEJ­ЖЕ1=BŒŠŒЮЮЮопооложзжжвжœžœЅІЅжвжХТХНОННКННКНЕЖЕ­Ў­ЕВЕ­Ў­­Њ­­Њ­ЅІЅœЂœœžœ”š”œšœZ]Zsus­Њ­{}{JEJ1-1kek151JEJcecsqs:=:œЂœŒŽŒŒŽŒ”’””’””’””’””–”œžœ”𔄂„kiksqsœžœЮЪЮЮЪЮ­Њ­œšœ„†„НОН”–”ЅІЅ­Ў­œЂœ­Њ­ЅІЅЅІЅЅІЅЅЊЅœЂœœšœЅЂЅЕЖЕХЦХЅЊЅ­Њ­”Ž”B‚R:КR)ЊJŽ1BТZ)ІJ:ЊRRЪk!y1y1:ЂJRЦcRвk)ІJ:ЖR1ІJ)–B1žJ!Ž:„ЂŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{y{cecЅЂЅЕВЕНКННОНХЦХХЦХЮЪЮЮЮЮЮЮЮжлжоло”’”яяяїѓїопо”šœ:AB!$!111:9::=:JQR­ЖЕ1=B„†ŒЮЪЮолоолоЮЪЮжзжœžœЅЂЅЮЪЮХЦХНТНЕЖЕЕЖЕЕЖЕЕВЕ­Ў­ЅІЅ­Ў­ЅІЅЅІЅœžœœšœœšœœžœZ]ZsqsЅІЅ”–””–”cac:=:BABRURkiksus:=:ЅЂЅ”’”ŒŽŒ”–””–””–””–””–”œšœЅЂЅЅЂЅЅІЅ{y{kmksus”š”ЮЪЮХЦХŒŠŒХЦХœžœЅІЅ­Ў­­Њ­ЅІЅ­Ў­­Њ­­Њ­­Њ­­Њ­­Њ­œžœœžœЅІЅœžœ­Ў­­Њ­R}Z–:JЦcBКZBВR1ІJ!Š:1ЊR:ЎZ)’B!Š:!š:Zлs!žB1ЊJ1žJe)!ŠB)’B­КЕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЂЅ”–”ЅЂЅ­Ў­ЕЖЕНОНХТХЮЪЮХЦХЮЪЮЮЮЮжлжоло”’”яяяїѓїопо”–”BEB111:=:BABBEBRUR­ЖЕ1=BŒŠŒЮЮЮоложвжЮЪЮолоЅЂЅЅЂЅЮЮЮНКННОННКНЕЖЕЕЖЕ­Ў­ЕЖЕЕЖЕ­Ў­­Њ­ЅІЅœЂœœžœœžœœžœcackmkЅІЅ”–””’”œšœZ]ZJIJ„‚„ŒŽŒB=Bœšœ”’””’””’””–””š”œšœœžœЅЂЅœžœ”š”œžœsqsЅІЅЕВЕ{}{susŒŽŒ„‚„жзжХТХЅІЅЅІЅ­Њ­œžœЅІЅЅЊЅ­Њ­­Њ­­Ў­­Ў­œžœНКН­Ў­œžœœšœЅЂЅZ’c–1!ž:)ЂJBКcRЦkJКc1ЂJ:ІR!ŽB)–B1ЂJ:ВR1ЂJ)–BRЪk1šJ1šJ!†BХЪХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНКН”–”ЅЊЅЕВЕЕКЕХТХХТХХЦХХТХХЦХжвжолоопо”’”яяяїѓїоуо”šœJIJ:9:BEBJMJJMJcecЕКЕ19:”–”ЮЪЮжзжЮЪЮЮЪЮЮЮЮœšœ­Њ­ЮЮЮЕЖЕНКННОНЕВЕНКНЕВЕ­Њ­ЅІЅЅІЅЅЊЅЅЊЅЅЂЅœžœœžœЅЂЅc]ckmkЅІЅœšœ”–””–”kmk111cac„‚„­Њ­ЅЂЅ”’””–”œšœœšœœšœ”–”œžœœžœœžœЅІЅsusЅІЅЕКЕЅЂЅЅІЅŒŽŒ{}{ŒŽŒЕЖЕжзжЮЮЮЕВЕœžœЅЊЅ­Њ­ЅЊЅ­Ў­­Њ­­Ў­œžœНОНЕЖЕ­Ў­ЅЊЅœžœ„ŽŒR‚c)šJ1ЎRBКcsу„1žR!ŠB!†B}1)šBBЖRBКZBВZ1ЂJ)žJBВc:ІR!y:жлжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХТХœžœ­Њ­ЕВЕНОНХТХХТХХЦХХЦХЮЪЮжвжопоопо”’”яяяїѓїцчцЅЎ­RQRBABJMJJMJRQRœЂЅ”šœ1=:­Ў­ЮЮЮХЦХЕЖЕХТХХЦХœšœЅІЅХЦХНКННОНЕЖЕЕВЕНКН­Ў­­Њ­­Њ­ЅІЅ­Њ­ЅІЅЅЂЅЅЂЅœžœЅЂЅc]csqsЅІЅ”–””’””–”kmkBEBcecBAB:9:ZYZ”’”ЕВЕ­Њ­œžœœžœЅЂЅЅІЅЅІЅЅІЅЅІЅЅЊЅ{y{ЅІЅЕВЕЅІЅœžœЅІЅ­Ў­œšœŒŠŒŒŠŒ­Ў­жвжоуоНКНЅЂЅЅЊЅ­Ў­ЕВЕ­Ў­œžœНОНЕЖЕ­Ў­­Ў­­Ў­­Њ­œ’œZ†c!žBBЎRcЪs:ЊR†:†:‚1!ЂB)ЂJ:ЖZRЪk:ЊR)–J)’J)’B1qBяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮ­Њ­­Ў­ЕЖЕНОНХЦХХЦХХЦХХЪХЮЮЮжзжопоопо”’”яяяїїїяѓяХЪЮŒ’”Z]Zcac{}{ЅЊ­ЅЎ­:=B„†„ЮЮЮЮЮЮЮвЮжвжНОНжвж­Ў­­Ў­жзжХТХНОНХТХХТХНОННКН­Ў­­Њ­­Њ­ЅІЅЅІЅЅЂЅœЂœœžœЅЂЅZ]ZsqsЅІЅ”–”ŒŽŒ”’”kikJIJ„†„ŒŽŒ„‚„cacBABJMJ„‚„­Ў­ЕКЕЕВЕœžœЅЂЅ­Њ­ЅІЅ­Њ­{}{ЅІЅЕВЕœžœ­Њ­ЕВЕЕЖЕ­Њ­ЅІЅ”–””’””’”ЅІЅХЪХжзжХЦХЕВЕ­Ў­­Њ­œžœНТНЕКЕ­Ў­ЕВЕ­Ў­­Ў­­Ў­œžœBŽR’1})}1‚1)Ž:!Ž11ЊJ:ЎR1ІJRОc)–B†:!Š:}1s’{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжзж­Њ­ЕВЕЕЖЕНКНХЦХХЪХЮЪЮЮЮЮЮвЮолоцчццчц­Њ­яяяяѓяяыяХЪХЅЊЅЅЎ­ЅЊ­”žœsy{BIJsu{­Ў­­Њ­œšœŒŠŒЕВЕœšœ­Њ­ŒŽŒ„‚„”’”ЅІЅЅЂЅœšœœЂœ­Њ­ЕВЕНКНХТХНОННОНЕВЕ­Њ­­Њ­œžœЅЂЅc]csqsЅЂЅ”’””’””–”kekJIJ„‚„ŒŠŒ”’”œžœ”š”{y{RQRJIJsqsЅІЅНОНЕЖЕЅЊЅ­Њ­­Њ­{}{ЅЂЅЕЖЕЅЊЅ­Њ­НКН­Ў­­Њ­ЕВЕЅЂЅœžœ­Ў­œžœ„†„ЅЂЅХТХжзжЮЮЮНКНœžœХТХХТХЕВЕ­Ў­­Ў­ЕВЕЕВЕ­Ў­ЅІЅsž{s–{RmZ!u:y)†1!–:!žB)–:)–B!Ž:m!y1!†:ЅЖ­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоло­Њ­ЕВЕЕЖЕНОНХТХЮЮЮжзжолооложвжХТХЕЖЕœžœ­Ў­ЕЖЕНОНХЦХЕВЕ”’”„ŠŒ„†Œ”–”ЕКЕХЦХЕКЕНКННТНЅІЅНОННКНœšœ”’”œžœ”–””’””–”ŒŠŒsqskikceckmkkmk{}{ŒŽŒœЂœЅЊЅЕВЕ­Ў­­Њ­cacsqsЅЂЅ”’”ŒŠŒŒŽŒcecJMJŒŠŒŒŠŒ”–””–”œšœЅЂЅœžœŒŽŒkikRQRcecœžœХЦХХЦХЕЖЕ{y{ЅІЅХЦХ­Ў­­Ў­­Ў­ЕЖЕЅІЅœšœЅІЅЅІЅ”–”­Ў­œžœНКН”–”œžœНОНолоЕВЕХТХНОНЅЊЅ­Ў­­Ў­ЕВЕЕВЕ­Ў­ЕВЕЕВЕ­Њ­{u{{Š{1šJ:КZ’:!žBBОZ)šBJТcBЊRm))ŠBопоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоло­Њ­­Ў­ЕЖЕХЪХЮЮЮХТХЅІЅ„†„sqssus„‚„œšœЕЖЕХЦХжлжцчцяыя”’”опояѓяопоцчцопожзжжзжопоЮЪЮНОНХТХЕВЕ­Ў­ЕЖЕНКННКНХТХХТХ­Њ­ŒŽŒНКН”š””–”„†„{y{kikZYZZYZZ]ZkmkŒŠŒZ]ZsqsЅІЅŒŠŒ„‚„„‚„cac! !RQRŒŠŒ”–”œšœ”–””–”œšœœžœœžœЅІЅ”š”{y{cacc]cŒŽŒЮЪЮ”–”œžœ­Ў­ЅЊЅ­Њ­ЅІЅ­Ў­œžœЕВЕ­Ў­­Њ­ЕКЕЕЖЕœžœЮЮЮ­Ў­­Њ­”–”œЂœœžœНКНопоХЦХЕВЕ­Ў­­Ў­ЕВЕЕВЕЕВЕЕЖЕ­Њ­{}{”–”!}::ВJRЪc:ВRBЖZ!Ž:!–BBКZ1žJ:ŽRцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџопоЅЊЅЕЖЕНОНЅЂЅkmkJIJRQRsus”š”ЕЖЕжвжцчцяыяяѓяїїїїѓїїѓї”’”ЮвЮоуоопоопоопоЮЮЮжзжжвжХТХХТХЮЮЮЕВЕНКННКНЕВЕ­Ў­ХТХЕВЕНКНŒŽŒХЦХЕВЕЕВЕЕВЕ­Њ­­Њ­œšœ„†„kmkRUR:9:111JIJ{}{ŒŽŒŒŠŒ{}{c]c! !RQRŒŽŒ”’””–”œšœœžœœšœœšœœžœœšœœšœ”𔄆„RQRsqscackmkЅІЅЮвЮЮЪЮЅІЅœЂœœžœЅІЅНКН­Ў­ЕВЕНКН­Њ­œšœжвж­Ў­ЕЖЕ­Њ­­Њ­ЅІЅœžœ­Њ­ЮЪЮопоЮвЮНКН­Ў­ЕВЕЕВЕЕВЕ­Њ­„‚„œІœ!Š:ž:!žB1ЊRRЪkJКcBЖZ)šJ:ЊR1‚JїїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуцЕВЕœžœkekBEBcac”’”ЕКЕжзжопоопооуоцчццчцяяяяяяяѓяяѓя”’”олоцуцжвжоложвжЮЪЮжзжжзжЮЮЮХТХХТХЮЮЮНКННТНХЦХЅЊЅ­Ў­ЕВЕЅІЅŒŠŒЕЖЕ­Њ­­Њ­ЅІЅЅІЅœžœЅІЅœžœ”š””’”„‚„kekJIJ151JMJ{}{ŒŠŒcac)-)RURŒŽŒ„†„”–”œžœ”–””–”œšœ”–””–””–”„†„{y{JMJŒŽŒsussqskik{y{­Њ­ЮвЮЮЪЮНОНЕВЕЕКЕЅЂЅЕЖЕЕЖЕЕЖЕœžœЮЮЮ­Њ­­Ў­­Њ­НКНЕЖЕ­Ў­­Њ­œžœЅЂЅНОНжлжжзжНТНЕВЕЕЖЕ­Ў­„†„НКН„šŒB’Z)ЊJ1ЊRcл{RОk!’B!ŠB!ŽBR’cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуц{y{JEJBEB„‚„ХЪХЮЪЮЮЪЮЮвЮжзжжлжопоцуццчццыцяяяяѓяїѓї”’”жвжцыцоложзжоложвжолоЮЮЮЮЮЮжзжЮЪЮЮЪЮХТХЕВЕЮЮЮНОНЕЖЕ­Ў­­Ў­ŒŠŒНОН­Ў­­Ў­ЅЂЅ­Њ­ЅІЅœšœ”–””’”ŒŠŒŒŠŒ„†„„‚„kmkJIJ151ZYZBAB BABœžœ­Њ­ЅЂЅœžœœšœœšœœšœ”–”œšœŒŠŒBABЕЖЕ­ЖЕœІЅŒŽŒ{y{{}{{y{sqssusœšœХЦХжвжНОНœЂœ­Ў­œžœ­Ў­œšœЮЮЮ­Ў­­Ў­­Њ­ЕЖЕНКНЕЖЕЕЖЕНКН­Ў­œžœ”–”­Њ­ЮЮЮжзжЮЪЮЕЖЕ„†„ХТХ­Њ­œšœ:šR!žBZЦkRКc)žJŽ:)ŠJЮзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮвЮRUR”š”susŒŠŒХТХНОНХЦХЮЮЮжзжжлжопоцчццуццыцяяяяѓяїѓї”’”олоцчцопоцуцопоЮЮЮжвжжзжХЦХЮЮЮЮЪЮНКНХЪХЕВЕХТХНТНЕЖЕНОНЕВЕ{y{ЕКЕ­Ў­ЅЊЅЅІЅЅІЅ­Њ­ЅЂЅ”–””’”„†„{}{{}{sussussusZYZ:=:JEJ:9:)-)111cecœžœЕЖЕ­Ў­ЅЂЅœžœœžœЅЂЅ„‚„­ВЕsus„ŠŒЅЊ­ЕКЕЅЊЅ„†„„‚„”–”sy{{y{ŒŽŒЕВЕЮЮЮХЦХ­Ў­­Њ­œšœЮЪЮЕВЕЕВЕНКННКНЕЖЕЕЖЕЕЖЕЕЖЕЕЖЕЕВЕœšœЕЖЕ”’”œšœНОНЮЪЮŒŠŒХЦХ­Ў­­І­{š„!’:’1)ŠB­ТЕХЮХжпжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоуоœžœЕЖЕ{}{ŒŽŒХТХХЦХХЦХЮЪЮЮЮЮжлжцуццуццчццыцяяяяыяяѓя”’”опояяяцыццчцоуоопожзжжвжЮЪЮХЪХЮЮЮЕЖЕНОНЕВЕЕВЕНОНЕВЕ­Ў­НОН{}{НОН­Ў­ЅІЅЅІЅЅЂЅЅІЅœšœœšœŒŽŒ„†„{}{{y{sussqskmkkmkcacJMJZ]ZsuskmkRQR:9:RQR„†„ЕВЕНКН­Ў­ЅІЅ„†„­Ў­!$!! !:=Bcik”š”ЕЖЕЅЊЅ„†„”–”­Њ­”–”{}{„†„­Њ­ХЦХХЦХœšœНОН­Њ­ЕЖЕ­Њ­ЕВЕЕВЕЕВЕНКНЕВЕЕЖЕЕВЕЅЂЅжзжЕВЕЅЂЅŒŽŒ„†„{}{ХТХЮЮЮНОН­Њ­”Ђ”{Њ„жлжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяя­Ў­ЕВЕ{}{”’”ХТХХТХХЦХЮЮЮЮЮЮолоопооуооуоцыцяыяяыяяяя”’”олояѓяцыццуццуцопоопоолоЮвЮЮЮЮХТХХЦХХТХЕВЕНКННОНХЦХЅЂЅ­Њ­ŒŽŒНКНœЂœ­Њ­œžœœžœЅЂЅœžœ”’”ŒŠŒ„†„„‚„{y{{y{sqskmkkikZ]ZJMJRUR{y{”’”ЅЂЅœšœsusJIJBEBkmkЅІЅХЦХœžœ­Ў­!$! )11cek­ЖЕЅЊ­œšœ­Ў­­Њ­ЅЂЅ”–”{y{ŒŠŒœšœ­Њ­ЮЮЮХЦХНОНЅІЅ­Ў­­Ў­ЕЖЕЕЖЕЕЖЕЕЖЕЕВЕœЂœжвжЕЖЕЕЖЕЕКЕ­Њ­ŒŽŒ{}{”’”ЕЖЕЮЪЮЮЪЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїѓїœžœЅІЅ„‚„”š”НТННОНЮЪЮХЦХЮЪЮжвжопооуоцчцяыяцчцяыяяѓя”’”олоїѓїцыццуцопожвжцуцжвжЮЮЮЮЮЮНТННОННКНЕЖЕНОННОННТНЕЖЕ­Ў­„†„ЕЖЕЅЂЅЅІЅ­Њ­ЅІЅЅІЅЅЊЅ”’”ŒŠŒ„†„„‚„{}{{}{sussqskekZ]ZJMJZ]Z{y{”’”œžœЅІЅ­Ў­­Њ­”’”kikJMJcac{y{­Ў­111 )11œЂЅ­Ў­”š”ЕВЕЅІЅœЂœЅЂЅŒŠŒЕЖЕŒŠŒŒŠŒ”’”ЕВЕжвжжвжНКНЕВЕЕВЕЕВЕЕЖЕНКНЕВЕЅЂЅжвжЕЖЕЕВЕ­Ў­ЕВЕНКННКН”–”sqs„‚„ЅЊЅЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœžœЅІЅ{}{ŒŠŒНОНХТХНТНЮЮЮжвжЮЪЮжлжолоцуцяяяяяяяѓяїїї”’”олояяяяыяцуцопооуоцчцЮвЮХТХХТХХЦХЕЖЕЮЮЮЮЪЮХТХХЦХЮЮЮЮЪЮХЦХ„‚„ХЦХЕВЕЅІЅЅІЅ­Њ­œšœЅІЅ”–”ŒŽŒŒŽŒ„†„„‚„{}{{y{suskikZYZJMJcac{}{”–”œЂœЅЊЅ­Њ­­Ў­­Ў­ЕВЕЅЊЅ„†„:9:­ВЕ:9:!$!! ! 111œЂЅЅЊЅœšœЕВЕЕВЕ­Њ­­Њ­ŒŽŒХЦХЅІЅЕЖЕЅІЅ”–””’”­Њ­ЮЪЮолоЮЪЮЕЖЕЕЖЕЕЖЕЕЖЕЅЂЅжвжЕЖЕНКНЕКЕ­Ў­ЕВЕ­Њ­ЕВЕЕЖЕœšœ{y{ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЂЅœЂœ{}{„‚„НОНХЪХНОНХЦХЮвЮжзжжвжопоцчцяыяяыяцчццуцжвжЮЮЮЮвЮЮЪЮЮЮЮНКНЕКЕНКНЅЊЅœšœЅІЅ”–”ŒŽŒŒŽŒ”’”„‚„ŒŠŒ”š””š”ЅЂЅsqsœžœЕВЕЕВЕЕЖЕЕВЕ­Ў­ЅІЅ”–”ŒŠŒŒŠŒ„†„„†„„‚„„‚„suskikZYZJMJZ]Z{}{”–”ЅЂЅ­Њ­­Ў­­Ў­­Ў­­Ў­ЕЖЕЕВЕBAB­ВЕBAB)-))()! !19:œЂЅЅЊ­œЂœЕЖЕЕЖЕ­Ў­­Ў­”’”ЮЮЮœšœЕВЕ­Ў­­Ў­ЅІЅœšœ”–”ЅІЅХЦХопоолоХЦХЕЖЕœЂœжвжЕЖЕНКНЕЖЕЕЖЕ­Њ­ЅЂЅ­Ў­ЕКЕ­Њ­­Ў­ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”š””š”„‚„ŒŠŒНОННКНжзжХЪХНКННОННОНЕЖЕЕЖЕ­Ў­ЕВЕНОНХЦХХЪХЮЮЮЮЪЮЮЪЮХЦХХТХНКНЕЖЕНОННОННОНЅЂЅЅІЅœЂœœšœŒŽŒŒŠŒ{}{suskikkikZYZcecsqs{}{„‚„”–”œšœЅІЅ­Њ­œžœ”–”ŒŽŒ„†„„‚„suskikZ]ZJMJZ]Z{}{”–”ЅЂЅ­Њ­­Ў­­Ў­­Њ­ЕВЕЕЖЕЕВЕB=B­ВЕJMJ:9:151)-)! !:=:œЂЅЕЖЕЅЊЅНКНЕЖЕЕВЕЕВЕ”–”ЮЪЮЕЖЕЕЖЕ­Ў­ЕЖЕЕВЕ­Њ­ЕВЕЕВЕœšœœžœНКНжлжолоЅІЅЮЮЮЕЖЕНКН­Ў­ЕКЕНОН­Ў­­Њ­ЕВЕ­Ў­ЕЖЕЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”š””’”{}{”š”ХЦХ­Ў­ЅІЅŒŠŒ{y{ŒŠŒŒŽŒ”–”ЕВЕХЦХжвжцуцяяяцыцяыяопожзжопожзж”’”жвжжзжЮЪЮЮЮЮХТХХЦХХТХХЦХНОНХТХНОНЕВЕЕВЕ­Њ­œžœ”’””’”suskikkmkcaccaccac{y{ŒŠŒœšœ”–”ŒŠŒ{y{kmkZYZZYZkik{}{”š”ЅІЅ­Ў­­Ў­­Ў­­Ў­ЕВЕЕВЕ­Ў­B=B­ЖЕRURBAB:=::5:)()BABœžœЅЊ­ЕЖЕолоХЦХЕВЕЅІЅ”–”жвжЕЖЕЕЖЕНКННКНЕЖЕЕЖЕНОНЕЖЕЕЖЕ­Ў­œšœœšœ­Њ­ЕВЕолоолоХЪХЕВЕНКННОНЕЖЕ­Ў­ЕЖЕЕВЕНКНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŒŠŒ”’”{y{sqs„‚„ZYZZ]ZsqsЅІЅХТХжвжжвжцчцяыяяыяяыяяяяяяяцчцопоолоцуцоло”’”жлжжзжЮвЮЮЮЮЮЪЮХТХНКНЕКЕЕВЕЕЖЕЕЖЕЕЖЕЕЖЕЕВЕ­Њ­ЅІЅЅЊЅsusœšœ­Њ­ŒŠŒ{y{kikZYZJIJBEBRUR{y{ŒŠŒsusRQR151kik”’”­Њ­­Њ­­Ў­ЕВЕ­Ў­ЕВЕЕВЕЕЖЕ­Ў­BAB­Ў­cekJIJJEJBAB151BIJœЂœ”šœkik”–”НОНолоЮЮЮ”–”оло­Ў­НКНЕЖЕЕКЕЕЖЕНОННКНЕВЕЕВЕ­Њ­”’”ЕВЕ­Њ­œšœœšœЕЖЕжвжолоХЪХЕЖЕ­Ў­ЕЖЕЕВЕНКНЕЖЕЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœšœ”’”cacJMJkek”–”{}{œšœжзжжзжолоолоцчцоуоопоцчццчццыцоуооуоопожзжоло”’”оложзжЮвЮХЦХХТХХЪХНКНЕЖЕЕКЕ­Ў­ЕВЕНКНЕЖЕ­Ў­­Њ­­Ў­ЅІЅ{}{”’”ЅІЅ”–””’””–”ŒŽŒ„‚„kikBEB)()BEBsuscec!$!!!:=:susЕВЕХТХНОНЕВЕЕВЕЕВЕНКНЕВЕJMJkqsœЂœJMJJMJJIJBABJMJ”žœ­Ў­œžœ{}{”’”ŒŠŒЅЊЅ”’”оуоЮвЮХТХЕЖЕЕКЕНОННКННТННКНЅЂЅŒ’”susŒŠŒŒŽŒ”–”ЅЊЅ”–”ŒŽŒœžœНОНжзжЮЮЮНОНЕЖЕЕВЕНОНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŒŠŒBEBZYZŒŽŒЕВЕХЦХŒŠŒœžœжзжжвжжзжолоолоопоцыцопооуоцуццуццыцопоопоопо”’”оуожзжЮЮЮЮЮЮНОНХЦХНОНХЦХНКНЕЖЕЕЖЕНКНЕВЕ­Њ­­Њ­ЅЊЅЕВЕ{}{”–”­Ў­”’”ŒŠŒ„†„ŒŠŒŒŠŒŒŠŒŒŠŒkmkBAB)$)JMJZ]ZkikZYZ:=::5:cecœžœНОНХЦХНКНЕЖЕ­Ў­cackmkœЂЅŒ’”RURJMJJIJJQRœЂЅЅЊ­ЅІЅŒŠŒжзж­Њ­œЂœŒŠŒœžœХТХолоолоХЦХНОНЕЖЕЕЖЕХТХcackikНТХ­Ў­œЂЅŒŠŒ„‚„”–”­Ў­œЂœŒŠŒ„†„ЅІЅХЦХЮЮЮХЦХЕКЕЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџsuskmkŒŽŒЅІЅЕВЕНКНŒŠŒ”–”жзжжзжопоолоопожлжоуоолоцчццуццчццчцоуоцчцоло”’”оуожвжЮЮЮХЦХНКНЕВЕЕЖЕ­Ў­ЕЖЕЕЖЕЕЖЕЕЖЕ­Ў­ЕВЕЕВЕЕВЕ­Ў­„‚„”š”ЅІЅ”’””’”„†„„†„„†„{y{„‚„„‚„{y{cacBEBRURkmk”’”œžœœšœJIJ)-)JMJ{y{ЕВЕЮЮЮНТНZ]ZХЦХ:9:Œ’”ЅЊ­{}{ZYZsqsЕКНЅЂЅ­Ў­ŒŠŒжзжХТХНОНЕВЕЅІЅ”’””–”ЕВЕжвжцуцжзжЮЪЮНКН:9:Z]Z”žœcik”–”­Ў­­ЖЕœžœŒŽŒЅІЅНОН­Ў­ŒŽŒ{y{”’”ЕЖЕЮЮЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœžœ{y{ŒŠŒœžœЅЊЅНОН„‚„”’”жлжжзжолоолоопоопоопоолоопоопоцуцжлжЮвЮЮЮЮЮЪЮЕВЕжзжЮЮЮХЦХХТХЕКЕЕЖЕЕЖЕХТХЕКЕЕЖЕ­Ў­ЕЖЕ­Ў­ЕВЕ­Ў­­Њ­ЅІЅ{}{ŒŽŒ­Њ­ŒŠŒŒŠŒŒŠŒ„‚„„‚„{}{{}{{y{{y{suscacRURsqs”’”ЅЂЅНКНcecsqsœšœcacJIJcacŒŽŒZYZопоЮЪЮZYZ:ABŒ’Œ­Ў­­ЖЕ”–”ЅЂЅ­Ў­ŒŠŒЮЪЮЕВЕ­Ў­ЕЖЕНКННОНЕЖЕœžœ”–”ЅІЅХТХопоолоJEBcacsys)-1JMJsy{ЅЊ­­ВЕœžœЕЖЕНОННКНЅЊЅkmk{y{{}{ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅ{y{ŒŠŒ”–”ЅІЅЕЖЕ„†„”’”жзжжвжоложзжопооуожвжопожзжНОНХТХ­Њ­œšœœžœœЂЅ„‚„­Њ­НОНЮЪЮЮЮЮХЦХХТХНТНЕЖЕХЦХНОНХЦХНОННОНЕКЕ­Ў­ЅІЅЅЂЅsus”–”ЅІЅŒŽŒ„†„„‚„{}{{}{„‚„{}{{y{{y{suscacZYZsqs”’”­Њ­ЕЖЕcac{y{ХЦХЕКЕ­Ў­ŒŠŒZ]ZJIJ{y{ЕЖЕоуоЕКЕZYZ!!!!)-){‚„ЕЖЕЕВЕŒŠŒжвж­Њ­НКН­Њ­НКНХЦХХТХЕКЕНКНЅІЅœžœœžœНКНJIJcac{}{   !!JQRЅЊ­­Ў­ЅЂЅЕЖЕНКНЕВЕ{}{ХТХœžœЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­Ў­{}{„†„”’”ЅЂЅЕВЕŒŽŒœžœЮЪЮЮЮЮолоопоолоолоЮЪЮЮЮЮХЦХЕКНЕКНЕКЕЕКЕЕОНЕОН­Ў­ZYZ{y{”’”ЅЂЅЅІЅœšœ”’””–”ŒŠŒŒŽŒЅЂЅœžœœžœ­Ў­­Ў­­Ў­НОН„†„ŒŽŒ­Њ­”–”„†„{}{„‚„{}{„‚„„‚„{y{{}{{y{cacZYZkmk”’”­Њ­НКНcacsusХЦХЕВЕЕЖЕХТХЕКЕЅЊЅ{}{cackikœžœжвжжзжНКН­Ў­НКНХТХЕВЕ„†„олоНОННОНЕВЕЕЖЕХТХХТХНКНХТХЕЖЕНОНХТХœЂœBABcac{‚„!!151œІЅ­Ў­ЅІЅНКННОН­Њ­{y{ХЦХНКНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕВЕsusŒŠŒ”–”œžœ­Ў­„‚„”–”жзжХТХЕЖЕЕЖЕ­Њ­ЕВЕНКНЕКЕЕОНœІЅŒ’”s}{kqskikkqsЕКН19:sqsœžœЕЖЕЕВЕœžœ”–””–””’””š”{}{{}{suskikkikceccacZYZcec{}{”–””’””–”ŒŽŒ”’”„‚„{y{{}{{}{{y{cecZYZsqsŒŽŒ­Ў­НКНc]c{y{ХЪХЕВЕЕКЕЕВЕЕЖЕНКНХТХНОНЅІЅ{}{kik„†„ЕЖЕоложзжЮЮЮЕЖЕ„†„ЮЮЮНТНЕКЕ­Ў­­Ў­ЕВЕЕЖЕЮЪЮНОННОНХТХЕЖЕ­Њ­ZYZZ]Z„†„!$!)()! !:9:œІЅ­Ў­­Ў­ЕКЕЕВЕ­Ў­{}{ХЦХНОНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕsus„‚„œžœЕВЕ­Њ­„‚„sqs„‚„„‚„”’”ЅІЅЅЂЅХТХХЦХЮЮЮ”žœJMJ)-)!!$)­ВЕ19:{y{ЕЖЕХТХНОНЕВЕ­Њ­œšœЕКЕНОНЅІЅЅЂЅЅЊЅ”–””–”ŒŽŒ{y{sqscacRQRRURRURZ]Zkmk{}{ŒŠŒŒŽŒŒŠŒ{y{susZ]ZRURsqs”–”­Њ­НКНcac{y{ХТХЕЖЕЕЖЕЕВЕЕЖЕЕВЕНОННКНХЦХХЪХНОН{}{kik{y{”–”ХЦХжзжŒŽŒЮвЮЕВЕХЦХНКН­Ў­НКНЕЖЕЮЪЮНТННКННКННКН­Њ­ZYZZ]ZŒŽŒ111111)-)!!:=BœЂЅЕЖЕЕЖЕНКННОНЕВЕ{y{ЮЪЮНОНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕВЕ{y{œžœ”’”sqscackik„‚„”’”­Њ­ЮЪЮЮЪЮ”’”опоцчцжло”žœ)-))()­ВЕ19:{u{ХТХЕЖЕЕВЕЅІЅЕВЕЅЂЅ­Ў­­Њ­ЅІЅЅЊЅЅІЅœšœœžœœžœœžœ”’”ŒŽŒ„†„sussqsc]cRQRBABJIJRURsus”’”„‚„RURJIJkikŒŠŒœЂœЕКЕcacsusХЦХНКННКНЕЖЕНОННКННОНХТХХТХХТХХЦХŒŠŒЅІЅХЦХ”–”{}{„‚„{y{ЮЮЮоложвжНОНЕКЕХТХНОННОНХТХХЦХНОННОН­Њ­ZYZZ]ZŒ’”:9::=:151)()BEBœЂЅœЂЅ”š”ЮЮЮжзжХТХ{}{ХЦХХЦХЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНТН„‚„c]cBEBcec{}{ЅЂЅЕКЕХЦХНОННОНЮЮЮ”’”опоцчцжзж”žœ111!!151­ВЕ1=B{y{ЕКЕНОННТН­Ў­ЕВЕœЂœœЂœ­Ў­­Њ­ЅІЅœšœœžœœšœœžœ”–””’”ŒŽŒ„†„{}{{y{sus{y{kmkJMJ:9:111JIJ{y{Z]ZBABZYZsusŒŽŒЅЊЅZ]ZsqsХТХНКННКННОННОННОНХТХХТХХЦХХЦХЮЪЮŒŠŒЅІЅжзжХЦХХТХ­Ў­œšœ„†„”š”НОНжлжопожвжХТХНОННКННОНХЦХХЦХ­Ў­Z]ZZYZ”žœBEBJEJBAB151BIJœЂЅЅЊ­„‚„„‚„”–”­Ў­{}{жвжХЪХЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕBABJMJ{}{œžœœЂœЕЖЕЕКЕЕЖЕНОНЮЪЮЮвЮ”’”опоцчцжлж”žœ15:!!!$!)():=:­ЖЕ1=Bsy{ЕЖЕНТНХТХНКНЕЖЕ”–”ЅІЅЕВЕЅІЅЅІЅЅЂЅЅЂЅЅЂЅœšœ”–”ŒŠŒŒŠŒ„‚„{y{sqskmksqssusRURkmk{y{BAB151111:=:Z]ZsusŒŽŒJMJcec­Ў­­Њ­ЕВЕЕЖЕНОННТНХТХХЦХХЦХХТХЮЪЮ„†„ЅІЅЮЮЮНТНХТХХЦХЮЪЮНОНЅЊЅ”’””’”­Њ­ЮЮЮцуцопоХЪХНКННОНХТХЕВЕsqs!$!ЕЖЕZ]ZJMJJIJBABJMJ”žœ­ВЕЕВЕ”’”ŒŠŒ„‚„kmkœšœХЦХЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕВЕZYZ{y{”’”œšœ­Њ­­Њ­­Ў­НКННКНжзжЮЪЮ”’”цуцяыяжло”šœ:9:)$))-)111BEJ­ЖЕ19:{y{НОНХЪХНОНЕЖЕЕЖЕœžœ­Њ­НКН­Ў­ЅІЅœžœœžœœžœ”š”ŒŽŒŒŽŒ„‚„{y{suskmkkikkmksqsJMJkmk„†„suscac!!111ZYZ:=:RUR”’””’”œžœЅЊЅ­Ў­ЕЖЕНКНХТХХТХХТХЮЪЮŒŠŒЅІЅжзжНОНХТХХЦХНТНХТХХТХХТХНТНЅІЅ”–”œšœЕЖЕжзжцчцжзжНОН­Њ­ЕЖЕkmk­Ў­Z]ZJMJJIJRQRœІЅЅЊЅ­Ў­”š”­Њ­ХЦХ­Њ­ŒŠŒsusЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЦХcecsusŒŠŒœšœЅЊЅЅІЅ­Њ­ЕВЕНОНЮЪЮЮЪЮ”’”опоцчцжло”šœ:AB!$!111:9::=:JQR­ЖЕ19:{y{НКНХЦХНОННОННТН”–”ЅІЅНКН­Њ­ЅІЅœЂœœžœœžœ”–”ŒŽŒŒŠŒ{}{sqskmkkikkekkiksqsJIJcec„‚„sqssqs)$))-1ZYZsqs„‚„ŒŠŒ”–”ЅЂЅ­Ў­ЕЖЕНКННОНХЦХ„†„ЅІЅжвжНОННТНХТХХТХНОНХЦХНОННТНХЦХНТН”–”ЕВЕœšœЅІЅХЦХоло­Њ­цыц{y{cec­В­Œ’”kiksusЕОНЅЂЅЕВЕ”’”­Њ­жвжХЦХХЪХНОНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮcecsus„†„”–”ЅЂЅ­Ў­ЕЖЕЕЖЕНТНХТХЮЪЮ”’”опоцчцжло”š”BEB111:=:BABBEBRURЕЖЕ19:{}{ЕЖЕХЪХЮЪЮНОНХТХ”’”­Њ­НКНЅІЅЅІЅœЂœœžœЅІЅœžœ”’”ŒŠŒ{y{sqskikceccaccacsqsJIJcec„‚„sqskmk! !!!:=:Z]Zsus„†„ŒŽŒœšœЅІЅ­Ў­НКН{}{œžœЮЮЮНОНХЦХХЦХХТХНОНЮЪЮНТНХТХХТХЕЖЕœžœопоХЦХЕКЕЅІЅœЂœœšœЮЮЮяыяœžœ! !!$!kqsЅЊЅ­ВЕŒ’”ЅЊЅХТХ”–”­Њ­ЮЮЮХТХХЦХЮЪЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжзжcecsus„†„”–”ЅЂЅ­Ў­НКНХЦХХЦХЮЪЮЮЮЮ”’”цчцяыяопо”žœJIJ:9:BEBJMJJMJcecЕКЕ19:ŒŽŒЮЮЮжзжЮЮЮЮЮЮЮЮЮœšœ­Ў­ХЦХНОННКНЕВЕ­Њ­ЅІЅЅІЅ”’”„‚„{y{kmkkikcaccaccecsqsJEJcac„†„suskmk!!!$!BEBcacsus„‚„ŒŽŒœžœkmk”’”НТНЕЖЕЕЖЕНТННОННТНХТХХТХХТХХТХНОНœžœолоХЦХЮЪЮЮЮЮХЦХЕЖЕЅЂЅЅІЅХЦХХЦХ„†„:=:!)()ŒŠŒНОНХЪХœšœ­Њ­ЮЮЮХЪХЮЪЮХЪХЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуцkiksusŒŠŒ”–”ЅІЅ­Ў­ЕЖЕХТХЮЮЮжзжжзжЅІЅоуоцчцжлжЅЎ­RQRBABJMJJMJRQRœЂЅ”žœ)-1{y{œžœœšœŒŽŒ”’””–”{}{{y{„‚„ŒŠŒœšœœЂœЅІЅ­Ў­ЅІЅ­Ў­ЅЊЅœšœŒŠŒsusceccacceckmkBEBcac„†„suskmk     cacsy{cac{}{ZYZsusœšœœžœЅЊЅЕВЕНКННОНХТХХЦХХТХНТННТНœžœолоХЪХЮЪЮЮЪЮЮЪЮЮЮЮЮЪЮНОН­Њ­ЅІЅЕВЕНОНХЦХжвжжзжХЦХЮЪЮ”š”­Њ­жзжЮЪЮЮЪЮЮЪЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяѓяkmksus„†„”–”ЅЊЅНОНХЦХЮЮЮХЦХНОН­Ў­œžœ­Њ­ЕВЕЕЖЕЕКН”–”Z]Zcac{}{ЅЊ­­ВЕ19:JMJ­Њ­ЕЖЕЕВЕ­Ў­œžœ”š””–”ŒŽŒ{}{suskmkceccaccaccacZYZZ]Zkiksus„‚„„†„„†„{}{{}{JEJcac„‚„sqskmk   kmkkmk151:9:c]c{}{„†„ŒŽŒœžœЅЊЅЕВЕЕЖЕЕКЕНКНХЦХНОНœšœопоЮЪЮЮЮЮЮЮЮЮЮЮЮЪЮЮЪЮЮЪЮЮЪЮХЦХЅІЅœžœЅЂЅЅІЅХТХжлжцуцЅЂЅ­Њ­жзжЮЪЮЮЪЮЮЪЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџsqs{y{”’”­Њ­­Ў­œžœ„†„sqs{y{„‚„”š”ЕЖЕНОНЮЮЮолоЅІЅŒ’”­ВЕ­ВЕœЂЅkus)11BIJЕЖЕоложзжЮЮЮЮЪЮХЦХНОННОНЕКЕЕВЕ­Њ­ЅЊЅœšœsusЅІЅ„†„sqscacJMJBAB:5::9:BABRURsqsJMJcecŒŽŒsqskik     kikkmk!!!$):9:RURkik{}{ŒŠŒ”’”œžœ­Њ­ЕВЕНКНЕЖЕ”–”жзжХЦХЮЪЮЮЪЮЮЪЮЮЪЮЮЪЮХЦХХЦХЮЪЮЅЊЅХТХЮЮЮ­Ў­”–”ŒŽŒЅЊЅ”’”­Њ­цчцжвжЮЪЮХЪХЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{}{”–”ŒŽŒcacJIJJMJkmk”’”ЕВЕЮЮЮжлжопоцчццыцяыяоуо{}„BIJ:AB:ABRUZŒŽ”жвжоуооложвжЮЮЮЮЪЮХЦХНОННКНЕЖЕ­Ў­­Ў­­Њ­œžœ{y{ЕЖЕ”’”ŒŠŒ{}{sqskikc]cRURJIJ:9:)-)!$!:9:sqs„†„kik! !!!     kikkmk!!! !! !! !! !)-)BABZYZsqs{}„ŒŠŒ”–”ЅЂЅЅІЅŒŠŒЮЪЮНТНХЦХХЪХХЦХХЪХЮЪЮХЦХХЦХЮЪЮЅІЅНТНЮЮЮЮЪЮЮЪЮНОНЅЂЅ„†„„‚„ЅЂЅХЪХопожлжЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„†„ZYZ:=:JMJ{}{ЅЊЅНОНЮЮЮжзжолоопооуоцуццуццуццыц”’”ЮЮЮжзжолоцуцяяяцчцопооложвжЮЮЮХЦХХЦХХТХНКНЕЖЕ­Ў­­Њ­ЅІЅœšœsqsЕВЕŒŠŒ„‚„suskmkkikceckikkmkkmkkekZUZ:9:! !B=Bcec! !111151)()   kikkmk!!! !! !!$!!$!)())())()151JIJZ]Zsus„‚„ŒŠŒsqsЕВЕ­Ў­ЕЖЕНКННОННТНХЦХХЦХХЦХЮЪЮЅІЅНТНжвжЮЪЮЮЪЮЮЮЮжвжЮЮЮЕКЕ”’”{y{„‚„­Њ­ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZYZ111sus­Њ­ЕВЕНОННТНЮЪЮжвжолоопооуоцчццуццчццчц”’”олояяяяыяцчцоуооуоопожлжжвжЮЮЮЮЪЮХТХНОННКНЕЖЕЕВЕ­Њ­ЅІЅ”–”kmkЕЖЕ„‚„{}{suskmkcecceckikkmksqssus{}{{}{kik:9:!$!)-)BABJIJ:=:! !   kikkmk!!! !! !!$!!$!)())-))-)1-1)-))()sqs{}{ZYZZ]ZŒŽŒŒŽŒœšœЅЂЅ­Њ­ЕВЕНКННОНХТХХЪХЅІЅНОНжзжЮЪЮЮЮЮЮЮЮЮЮЮжвжжвжжзжЮЪЮ­Њ­„†„ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„‚„RUR{}{ЕЖЕЕВЕНКНХТХЮЪЮжзжопоопоцуццчццыццыццчц”’”жлжцчццчцопоопооложлжжзжЮвЮЮЮЮХЦХХТХНОННКНЕЖЕ­Ў­­Њ­ЅІЅ”–”kikЕВЕ„‚„{y{sqskikkikkekkikkmksqs{y{{}{{}{{}{{}{ZYZ    :9:RURZ]ZJMJ)-) kikkmk!!! !! !!$!!$!)())-))-)111111)()sy{sy{111BABRURcecsus„‚„ŒŽŒ”–”œЂœ­Њ­­Ў­НОНœžœНКНжвжЮЪЮЮЮЮЮЮЮЮвЮЮвЮЮвЮЮвЮжвжжзжжвжЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœšœZUZ{y{ЕЖЕЕВЕНКНХТХЮЪЮжзжолооуоцчццчццчццчццчц”’”ЮЮЮоуооложзжжзжжвжЮЮЮХЪХХЦХХТХНОНЕКЕЕЖЕЕВЕ­Ў­­Њ­ЅІЅЅЂЅ”’”kikЕВЕ{}{{y{sqskmkkikkikkmksqs{y{{}{„‚„„‚„„‚„„‚„kik! !BABc]ccecRUR)$)kmscik ! !! !!$!!$!)())-))-)111111)-)sy{{y{111:9::9:BABJIJZUZkiksus„‚„ŒŠŒœšœЅІЅ”’”­Ў­ХЪХХЦХЮЪЮЮЮЮЮЮЮЮвЮЮвЮжвжжвжжвжжвжЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЂЅZUZ{y{НКНЕВЕНОНХЦХЮЮЮжвжжзжопооуооуоопооложлж”’”НОНЮЮЮХЪХХЦХХТХНОНЕЖЕЕЖЕЕВЕ­Ў­­Ў­ЅЊЅЅІЅЅЂЅœЂœœžœœšœ”–”ŒŠŒcacЅЊЅ{y{suskmkkikkikkmksqssus{}{„‚„„†„„†„„†„„†„cec )-)RURsqsЅІЅ”’”:9:!$!! !!$!)())-))-)111111)-)sy{{y{111:=:B=BBABBABBABJEJRQRZ]Zkik{y{ŒŠŒsus”’”ЕВЕЕВЕНОНХТХХЦХЮЪЮЮЮЮЮЮЮЮвЮжвжжвжЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­Њ­ZYZ{y{НКН­Ў­НКНХТХХЦХЮЪЮЮЮЮЮЮЮЮЮЮЮЮЮЮЮЮХЪХХТХ”’”­Ў­ЕЖЕ­Ў­­Њ­ЅІЅЅЂЅœžœœžœ”–””–””’”ŒŽŒŒŽŒŒŽŒŒŠŒŒŠŒ„†„„†„{}{ZUZ”š”sqskmkkikkekkikkmksqs{y{{}{„‚„„†„„†„„†„„†„„†„sus:9:)$)! !!!! !)()111JIJZ]Zsus„†„”–””šœ„†„sy{cackiksuskikJIJ)-)!!! !)())-)111111)-)sy{{y{111:=:B=BBABBEBBEBJIJJIJJIJJMJRURceccec{y{ŒŽŒ”–”ЅЂЅ­Ў­ЕЖЕНОНХТХХЪХЮЪЮЮЮЮЮЮЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕZ]Z{y{ЕЖЕ­Ў­ЕВЕЕЖЕЕКЕЕКЕНКНЕКЕЕЖЕЕВЕ­Ў­­Њ­ЅІЅ”’”ŒŽŒ”–”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussussqskmkkmksqskmkkmkkmkkmkkekJIJ„‚„caccacc]cZ]Zcacceckmksus{y{„‚„„†„„†„„†„„†„­Њ­џџџяяяНКНŒ’”{}{{‚„ŒŽ”œžœ”–”„ŠŒ{y{cacJMJ:9:111)())$!)$)111JMJkmk{y{sqsRQR:5:)())()1-1)-)sy{{y{111:=:B=BBABBEBBEBJIJJIJJMJJMJJMJJIJ{‚„„ŠŒcacsus„‚„ŒŽŒ”–”ЅІЅ­Ў­ЕЖЕНОНХЦХЮЪЮЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНОНZ]Zsus­Ў­ЅЂЅЅІЅЅЂЅЅЂЅœЂœœžœœšœ”–””’”ŒŽŒ„†„„‚„sqskmksuskmkkikkikcecceccacZ]ZZ]ZZYZRURRURZUZRURRURRURRURRQR:9:kekRQRRQRRQRRQRRURZYZcackiksqssus{}{„‚„„†„„‚„­Њ­џџџџџџџџџџџџџџџцыяЕЖЕcec:=:151)-)1-1111151151151:5::5:151111111:9:RQRsqs{}{susZYZ:=:)$)sqssy{111:=:B=BBABBEBBEBJIJJIJJMJJMJRQRJIJ„†„„†„JMJZYZcackiksus„‚„ŒŽŒœšœЅІЅЕВЕНКНЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХТХZYZkikœžœ”’”ŒŽŒŒŠŒ„†„„‚„{y{sussussussussussuskmkkmksussussussqssqskmkkmkkikceccacZ]ZZUZRURJMJJIJJEJBEBBAB111BEB:=:B=BBABBABJEJJMJRQRZYZcackikkmksus{y{{}{­Ў­џџџџџџџџџџџџџџџџџџџџџџџџжзжЅІЅkmkJIJBAB:=:BABBABBABBABBABBABBABB=B:=::9:B=:RQRkmk{}{sqs”–”{}„111151:=:BABBEBBEBJIJJIJJMJJMJRQRJIJ„†„„†„RQRZYZZYZZYZZ]Zceckmk{y{„‚„ŒŽŒœžœЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЦХRQRZYZ„†„sussqskikkikkmksus{}{„†„”’””–””–””–””–””’””’”ŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskmkkikcacZ]ZZUZRQRJMJJIJBEB:=::9:151111111111:5:BABBEBJMJRURZ]Zceckmksqs­Ў­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуц­ВЕ{‚„RURJIJJIJJIJBEBBEBBEBJEJJMJJMRZYZceckmk„‚„”’”­Њ­œЂœ{}{kikRQRBAB:=:BABJEJJIJJMJJMJRQRJIJ„†„„†„RQRZYZZYZZYZZ]ZZ]ZZ]Zcackiksqs{}{ЅІЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНТНBEBJIJkmkZ]Zc]ccecsusŒŠŒ”–”œžœЅЂЅЅІЅЅІЅЅЂЅœžœœšœ”–””–””’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJIJBABBAB:=::9:1511111-1)-)111151BABJIJRQRZYZcac­Ў­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяыяНОН”’”kikkiksqs„‚„ŒŽŒ”–”œЂЅœЂЅ”šœŒ’”„ŠŒ{y{kikZYZcac{y{ŒŠŒ„†„sqsZUZJEJBABJIJJMJRQRJIJ„†„„†„RQRZYZZYZZYZZ]ZZ]Zc]ccaccaccacceccacџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНОН:9::9:ZYZZ]Zkmk{}{ŒŽŒ”–”œžœЅЂЅЅІЅЅІЅЅІЅЅЂЅœžœœšœ”–””’””’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABBAB:=::9::5:151151151111111)-)111:9:JEJRQRЕВЕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџцыцЮвжЅІЅ„†„suskikcacZ]ZZYZRURRURZUZZYZZYZZUZZYZkik{}{ŒŽŒŒŠŒ{y{Z]ZJMJJIJJIJ„†„„†„RQRZYZZYZZYZZ]ZZ]Zc]ccaccaccacceccacяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЊЅBABJIJZ]Zkmk{y{„‚„ŒŽŒ”š”œžœЅЂЅЅІЅЅІЅЅІЅЅЂЅœžœœšœ”–””’””’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:1511511511511511511111-1111:=:­Њ­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжвж­Ў­„‚„kekcaccacceccecceccecceccecceccaccaccackmk{}{”’”ŒŽŒ{}{c]Z„ŠŒ„‚„JMJZUZZYZZYZZ]ZZ]Zc]ccaccaccacceccacяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅJIJJIJRURcackmk{y{„†„ŒŽŒœšœœžœЅІЅЅЊЅ­Њ­ЅЊЅЅІЅœЂœœšœ”–””’””’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151151151151:9:{y{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоуоНОН”’”sqskmkkmkkmkkmkkmkkmkkmkkikkikkikkikkik{}{”–”œžœ­ЎЕœЂЅkikZ]ZRURZUZZ]ZZ]Zc]ccaccaccacceccacяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{}{151BABJIJRURcackmk{y{„†„ŒŽŒœšœœЂœЅІЅЅЊЅ­Њ­­Њ­ЅІЅœЂœœšœ”–””’””’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151151151:9:BABJMJsqsопоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцыцХЦХЅЂЅ{}{sussus{y{{}{„†„ŒŽŒ”–”œžœœЂЅЅІЅœžœ”–””’”ŒŽŒ”–””š”ŒŽŒsqscacZYZZYZcaccaccacceccacяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{y{111:9:BABJIJRURcackmk{y{„†„ŒŽŒœšœœЂœЅІЅЅІЅЅЊЅЅІЅЅІЅЅЂЅœžœœžœ”–””’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151151151:9:BEBRQRZ]ZkmkцуцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяѓяЮвЮХЦХ­ВЕЅЊ­œЂЅœžœ”šœ”’”ŒŠŒ„‚„{}{{}{{y{{y{{y{„‚„ŒŽŒœšœœšœ”’”{y{kikZ]Zc]ccaccacяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅІЅ111151:9:BABJIJRURcackmk{y{„‚„ŒŽŒ”–”œЂœЅІЅ­Ў­ЕЖЕЕЖЕЕКЕНКННОНХЪХ­Њ­ŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151151151:9:BEBRURcaccec„‚„џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџолоНКН”–”„‚„„‚„„‚„„†„„†„„†„„†„„†„„†„„†„„‚„„‚„„†„”’”œžœœžœ”–”{}{kmkcacяѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїћїBEB151151:9:BABJIJRURc]ckmk{y{ŒŽŒЅЂЅЕВЕЕЖЕНКННОННТНХТХХТХХТХХТХХТХЅЂЅŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151151151:=:JIJRURcackikcecХЦХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоуоХТХЅЂЅŒŽŒŒŽŒŒŠŒŒŠŒŒŠŒŒŽŒŒŽŒŒŽŒŒŽŒŒŠŒŒŠŒŒŠŒŒŠŒ”–”œžœЅЂЅ”–”яѓяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЖЕ111151151:9:BABJIJRURc]ckik„‚„„†„kmkЅЊ­НОННКНЕЖЕЕЖЕЕЖЕЕЖЕЕЖЕЕЖЕНКНœžœŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151151:=::=:BEBZYZcackekkikŒŽŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяыяЮЪЮ­Ў­”–””’””’””’””’””’””’””’””’””’””–”œžœЕВЕХЪЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRURc]ckik„†„„†„1=BBMJsusœЂЅЕВЕ­Ў­­Ў­­Ў­­Ў­­Ў­­Ў­œšœŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151)-)kmk”’”kikZYZcackikkiksqsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяжвжЕКЕœžœœЂœ­Њ­НОНЮЪЮжзжцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZ]Zkik„†„ŒŠŒ:ABBEJ:ABJMRsusœšœЅЂЅЅЂЅЅЂЅЅЂЅЅЂЅ”–”ŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151)-)kmk­Ў­ЅІЅ”’”suskekkeksqsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZ]ZkikŒ†„”’”:ABBIJBIJBEJ:ABcikœšœ”–””–””–””–”ŒŽŒŒŽŒŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151)-)cecœžœœšœœžœœžœŒŽŒkmkkmkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZ]ZkikŒŠŒ”šœ:ABBIJBIJBIJ:EJcacŒŽŒŒŠŒŒŠŒŒŠŒŒŠŒŒŠŒ”’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151111c]cŒŽŒ{}{kmkZYZRQRkikkikџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZ]ZcecŒŠŒœžœ:ABBIJBIJBIJBEJZ]c{}{{}{{}{{}{{y{„†„”’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151:9:111!! Z]Zkikџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZ]ZcecŒŠŒœžœ:ABBIJBIJBIJBEJRYZsqssqssqssqskmk{}{”’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151:9:! !   ceckmkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZYZcecŒŠŒœžœ:ABBIJBIJBIJBIJRURceccaccaccaccac{y{”’”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151:9:)()! !kmkkikџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZYZcecŒŠŒœžœ:ABBIJBIJBIJBIJJQRZYZZUZZUZZUZRURsus”–”ŒŽŒŒŠŒ„†„„‚„{}{{y{sussqskikkekcacZ]ZZYZRURRQRJIJJEJBABB=B:=::9::5:151151151151151151:9:1-1! !! !! !! !111{}{cecџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRQRZ]ZkikŒŠŒœžœ:ABBIJBIJBIJBIJJIJJMJJMJJMJJMJJIJkik”’”ŒŠŒ„‚„„‚„{}{{y{sussqskmkkekcacZYZRQRRQRJIJJIJBEBBABBAB:=::9::9::5:151151151151151151:=:151)-))-))-))()B=BŒŽŒcacџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRURcackmk”’”œžœ:ABBIJBIJBIJBIJBIJBABBABBABBABBEBŒŽŒНОННОННТНХТХХЦХНОНЕКЕЕЖЕ­Ў­­Ў­­Ў­­Њ­ЅІЅœžœ”–”„†„sqsZ]ZJMJBAB151)-)1-1111111111151151151:=::=::9::9::9:151JMJ”–”Z]Zџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJZUZkeksqs”–”œžœ:=BBIJBIJBIJBIJ15:151!!)-):9:ŒŽŒЮЪЮЮЪЮХЦХХТХНТННКНЕЖЕЕЖЕЕЖЕЕЖЕНКННОНХЦХХТХХЦХЮЮЮжвжжзжЮЮЮНТН­Ў­ŒŽŒkmkJIJ:9:111)-)111151:=:BEBBEBBEBBEBBABZYZœžœZYZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9:BABJIJRURcec{y{­Њ­­ВЕ:=B:ABBIJBIJBMJ!$):5:!$!151BEBkmkœšœЅІЅЅІЅЅЂЅЅЂЅЅЂЅЅЂЅœЂœœžœœžœœžœœšœœšœ”š””–”œšœœžœœžœЅЂЅ­Ў­НОННОННОН­Њ­”’”kmkJMJ:9:151JIJRQRRQRRQRJMJcecœžœZYZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151151:9::9:BEBkmkЅІЅЮвЮоложзж­ЎЕZac:=BBEJBMJ)()BAB!$!:5:JEJRQRcec„†„œžœЅІЅЅЂЅЅЂЅœЂœœžœœžœœžœœžœœšœ”š””š””–””–””–””’””’”ŒŽŒŒŠŒŒŠŒŒŽŒ”’”œžœЅІЅЅЊЅœЂœ„†„ZYZZYZZYZZYZZYZsqsœšœRURџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151151111111cac­Ў­жзжжвжНКН­Њ­ЅІЅНОНЮЮЮ”–”JMJ:EB)-1JMJ!$!:5:JIJRURcaccackmkŒŠŒœšœœšœ”–””š””–””’””–”œšœœšœœšœ”’”ŒŽŒŒŽŒŒŽŒŒŽŒŒŠŒŒŠŒŒŠŒ„†„„†„„†„„‚„„‚„ŒŠŒŒŠŒkekkekkekkekcec{}{œšœRQRџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”151)-)BEBœžœжзжХТХ­Њ­ЅІЅЅІЅЅІЅЅІЅЅІЅЅЊЅХЦХНТНsy{151ZYZ!$!:5:JIJRURcacceccacZ]ZcacRURBEBBABBABJIJ:=:JIJRQRcec­Њ­œšœŒŽŒ„†„„†„„†„„‚„„‚„„†„„†„{y{{y{{y{sqskmksqssqssqssqssqs„†„œšœJMJџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”–”)-)cacЕЖЕХТХ­Њ­ЅІЅЅІЅЅІЅЅІЅЅІЅЅІЅЅЂЅЅЂЅœžœЕВЕХЦХRUZcec!$!:5:JIJRURcacceccecZ]ZRQRBAB151!$!)()BEB111џџџџџџяяяжвжЕЖЕ”–”{}{{}{sqsJMJJMJ{}{{}{{}{{}{{}{{}{{}{{y{{y{ŒŽŒ”–”JIJџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”’”cecНКН­Ў­ЅЂЅЅІЅЅІЅЅЂЅЅЂЅЅЂЅЅЂЅœЂœœžœœЂœœžœ„‚„Z]Z:9:sus!$!:5:JIJRURcacceccecZ]ZRQRBEB:5:)())-)RUR)()1-1111B=BџџџџџџџџџџџџџџџџџџжзжBEB! ! JMJŒŽŒ„†„„‚„„‚„„‚„„†„ŒŠŒ”’”œšœЕЖЕНОНZ]Zџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­Ў­ЅЊЅЅІЅЅЂЅЅЂЅЅЂЅœЂœœžœœžœœžœœžœœšœœšœ”–”kikBEBBABBAB„‚„!!!$!:5:JIJRURcacceccecZ]ZRQRBEB:5:)()1-1kik:9:B=BB=BRQRџџџџџџџџџџџџџџџџџџџџџ)()JMJœšœœšœЅІЅЕЖЕНОНЮЪЮЮЪЮХЪХНКН­Њ­ЅІЅœšœџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџолоЅЂЅœžœœžœœžœœžœœžœœšœœšœœšœ”š”œšœ”š”kmkJMJRQRRURJMJŒŽŒ!!!$!:5:JIJRURcacceccecZ]ZRQRBEB:5:)()111{}{JIJJMJJMJZ]Zџџџџџџџџџџџџџџџџџџџџџ1-1cacЅІЅЅІЅЅЂЅœžœ”’”{y{kikcacZYZRQRJMJ”’”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮœžœœšœœšœœšœ”–””–””–””–””’”ŒŠŒ{}{susc]cZ]Zc]cc]cZYZœšœ! !!$!:5:JIJRURcacceccecZ]ZRQRBEB:5:)$)151”’”ZYZZ]ZZ]Zkmkџџџџџџџџџџџџџџџџџџџџџ1-1!!kikcecZ]ZZUZRURRURRURRURRURRURRURRURcecџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџопо”–””–””–””–”ЅЂЅЕЖЕЮЪЮЅЂЅkmkkikkikkikkikkikkikkikcecЅЂЅ! !!$!:5:JIJRURcacceccecZ]ZRQRBEB:5:)$)151ЅЂЅkikkmkkmk{y{џџџџџџџџџџџџџџџџџџџџџ)()RQRsqsZUZZYZZYZZUZRURRURRURRURRQRRQRRQR{}{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХТХНТНжзжяяяџџџџџџџџџЕЖЕsussussussussussussussuskmkЅІЅ !$!:5:JIJRURcacceccecZ]ZRQRBEB:5:)$)151­Њ­{y{{}{{}{ŒŠŒџџџџџџџџџџџџџџџџџџџџџJMJcacsqsZUZRURRURRURRURRQRRQRRQRRQRJMJJMJRURжзжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕКЕ„‚„„‚„„‚„„‚„{}{{}{{y{„‚„„†„НКН)() )-)BABRURc]cceccacZ]ZRQRBEB151!$!111ЕЖЕŒŠŒŒŽŒŒŽŒ”š”џџџџџџџџџџџџџџџџџџїїї„‚„cecRQRRQRRQRRQRRQRJMJJMJJMJJMJJMJJMJZYZХЦХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНОНŒŠŒ„†„ŒŠŒŒŽŒœšœ­Ў­НОНЮЪЮЮЮЮХЦХЕЖЕЅЂЅŒŠŒ„‚„sqskikkmkkmkcecZ]ZRQRBEB111!$!1-1НКНœšœœžœœžœЅІЅџџџџџџџџџџџџџџџџџџџџџоло„‚„JMJJMJJMJJMJJMJJIJJIJJIJJIJJIJ„†„оуоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЦХЅІЅ­Њ­­Ў­ЕВЕЕВЕ­Њ­œšœ„‚„sqskekkmk„†„œžœ­Њ­ЕВЕНТНХЦХХЦХХТХНКННКНЕВЕ­Њ­­Ў­­Њ­ЮЮЮ­Њ­­Њ­­Њ­ЕВЕџџџџџџџџџџџџџџџџџџџџџџџџџџџНОНcacJIJJIJJIJJIJJIJRQR„†„ЮвЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжвжœžœŒŽŒ{y{kmkkekcaccaccaccaccaccacZ]ZZYZRURZYZZ]Zcacceckikkiksus{y{{y{sus{}{ЕВЕЮвЮНОНЕЖЕНОНџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяыя”–”JMJRQR{y{­Ў­цчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџолоНКНœšœsusceccaccacc]cZ]ZZ]ZZ]ZZYZZYZZYZZUZRURRURRQRRQRRQRJMJJMJJMJJIJJIJsusЕЖЕЮЮЮЮЪЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџопоцчцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцуцЮЪЮЕВЕœžœ„‚„kmkcacZYZRURRURRURRQRRQRRQRRQRRQRJMJJMJJMJJMJJIJBEBJIJ{}{ХЦХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїцуцжзжХЦХНКН­Ў­ЅІЅЅІЅЅЂЅ”–””–””–””’”œšœЅЂЅЅЂЅЅІЅ­Ў­ХЦХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџfwbuilder-5.1.0.3599/packaging/fwbuilder.control0000644000175000017500000000075111733011756022312 0ustar sylvestresylvestrePackage: fwbuilder Conflicts: fwbuilder (<=4.1.1-1), fwbuilder-common, fwbuilder-bsd, fwbuilder-linux, fwbuilder-doc, libfwbuilder Replaces: fwbuilder (<=4.1.1-1), fwbuilder-common, fwbuilder-bsd, fwbuilder-linux, fwbuilder-doc, libfwbuilder Priority: extra Section: checkinstall Maintainer: vadim@fwbuilder.org Version: 5.1.0.3599-1 Depends: libqt4-gui (>= 4.4.0), libqt4-network (>= 4.4.0), libxml2, libxslt1.1, libsnmp | libsnmp15 Description: Firewall Builder GUI and policy compilers fwbuilder-5.1.0.3599/packaging/fwb3-makebundle.sh0000755000175000017500000001527511733011756022241 0ustar sylvestresylvestre#!/bin/sh # # Firewall Builder # # Copyright (C) 2012 NetCitadel, LLC # # Author: Vadim Kurland vadim@netcitadel.com # # This program is free software which we release under the GNU General Public # License. You may redistribute and/or modify this program under the terms # of that license as published by the Free Software Foundation; either # version 2 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 General Public License for more details. # # To get a copy of the GNU General Public License, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # This script assembles Mac OS X bundle # #--------------------------------------------------------------------- # # function usage { echo "makebundle MODULE_NAME BUNDLE_ROOT" exit 1 } unset DISPLAY unset LD_LIBRARY_PATH MODULE_NAME=$1 BUNDLE_ROOT=$2 test -z "$BUNDLE_ROOT" && { usage exit 1 } export BUNDLE_ROOT # Assuming script is being run with fwbuilder top directory as # cwd. Need to switch to the top level build environment dir. test -d 'tools' || cd ../.. pwd eval $(python tools/module.py -s $MODULE_NAME) BUILD_ROOT_DIR=$(pwd) test -d ${BUILD_ROOT_DIR}/source || { echo "Can't find directory where source tree should be located: ${BUILD_ROOT_DIR}/source" exit 1 } #VERSIONED_MODULE_NAME=$(basename $BUNDLE_ROOT | sed 's/\.app//') VERSIONED_MODULE_NAME="$MODULE_NAME-$VERSION" echo "Module name: $MODULE_NAME" echo "Versioned module name: $VERSIONED_MODULE_NAME" QT_FRAMEWORKS="QtCore QtGui QtNetwork QtDBus QtXml" FWBUILDER_ROOT_DIR=$(find ${BUILD_ROOT_DIR}/source -name "$VERSIONED_MODULE_NAME" -o -name $MODULE_NAME -depth 1) echo echo "=== Building bundle ${BUNDLE_ROOT} " echo TMP_BUNDLE_DIR=$(ls -d ${FWBUILDER_ROOT_DIR}/src/gui/*.app) test -z "$TMP_BUNDLE_DIR" && { echo "Can not find GUI bundle inside of ${FWBUILDER_ROOT_DIR}/src/gui" exit 1 } TMP_BUNDLE=$(basename $TMP_BUNDLE_DIR) rm -rf $TMP_BUNDLE cp -R ${FWBUILDER_ROOT_DIR}/src/gui/$TMP_BUNDLE . echo "=== Running macdeployqt" macdeployqt ${TMP_BUNDLE} echo "=== Copying fwbuilder resources and libfwbuilder libraries" mkdir -p ${TMP_BUNDLE}/Contents/Resources mkdir -p ${TMP_BUNDLE}/Contents/Resources/os mkdir -p ${TMP_BUNDLE}/Contents/Resources/platform mkdir -p ${TMP_BUNDLE}/Contents/Resources/help mkdir -p ${TMP_BUNDLE}/Contents/Resources/configlets (cd ${FWBUILDER_ROOT_DIR}/src/res/; tar cf - --exclude .svn {*.xml,os/*.xml,platform/*.xml,help,configlets} ) | \ tar -C ${TMP_BUNDLE}/Contents/Resources -xf - mkdir -p ${TMP_BUNDLE}/Contents/Frameworks #echo "=== Copying libfwbuilder" # #cp ${LIBFWBUILDER_ROOT_DIR}/src/fwbuilder/libfwbuilder.?.dylib \ # ${TMP_BUNDLE}/Contents/Frameworks/ #cp ${LIBFWBUILDER_ROOT_DIR}/src/fwcompiler/libfwcompiler.?.dylib \ # ${TMP_BUNDLE}/Contents/Frameworks/ # #chmod u+w ${TMP_BUNDLE}/Contents/Frameworks/* cp ${FWBUILDER_ROOT_DIR}/src/libfwbuilder/etc/fwbuilder.dtd ${TMP_BUNDLE}/Contents/Resources mkdir -p ${TMP_BUNDLE}/Contents/Resources/migration cp ${FWBUILDER_ROOT_DIR}/src/libfwbuilder/migration/*.xslt ${TMP_BUNDLE}/Contents/Resources/migration echo "=== Copying binaries" cp -r ${FWBUILDER_ROOT_DIR}/src/fwbedit/fwbedit.app/Contents/MacOS/fwbedit \ ${TMP_BUNDLE}/Contents/MacOS/ for c in ipt pf ipf ipfw iosacl pix procurve_acl do cp -r ${FWBUILDER_ROOT_DIR}/src/$c/fwb_$c.app/Contents/MacOS/fwb_$c \ ${TMP_BUNDLE}/Contents/MacOS/ done chmod +x ${TMP_BUNDLE}/Contents/MacOS/fwb* for f in ${TMP_BUNDLE}/Contents/MacOS/fwb* do for framework in $QT_FRAMEWORKS do install_name_tool -change ${framework}.framework/Versions/4/${framework} \ @executable_path/../Frameworks/${framework}.framework/Versions/4/${framework} \ $f done done rm -rf $BUNDLE_ROOT mv $TMP_BUNDLE $BUNDLE_ROOT exit 0 echo "=== Copying qt.conf file" cp ${FWBUILDER_ROOT_DIR}/packaging/qt.conf ${BUNDLE_ROOT}/Contents/Resources echo "=== Copying .nib files" test -d /Library/Frameworks/QtGui.framework/Versions/4/Resources && \ cp -R /Library/Frameworks/QtGui.framework/Versions/4/Resources/* ${BUNDLE_ROOT}/Contents/Resources # we have no working translations in v4 and v5 # echo "=== Copying locales" # mkdir -p ${BUNDLE_ROOT}/Contents/Resources/locale # cp -r ${FWBUILDER_ROOT_DIR}/src/gui/*.qm ${BUNDLE_ROOT}/Contents/Resources/locale qt_translations=$(find /Developer/Applications/Qt/translations/ -name '*.qm') test -n "$qt_translations" && { for f in $qt_translations; do cp $f ${BUNDLE_ROOT}/Contents/Resources/locale/ done } echo "=== Setting up copies of QT frameworks" for framework in $QT_FRAMEWORKS do test -d /Library/Frameworks/${framework}.framework/Versions && { cp -R /Library/Frameworks/${framework}.framework/Versions/4/${framework} ${BUNDLE_ROOT}/Contents/Frameworks/ install_name_tool -id @executable_path/../Frameworks/${framework} \ ${BUNDLE_ROOT}/Contents/Frameworks/${framework} } done mkdir -p ${BUNDLE_ROOT}/Contents/plugins cp /Developer//Applications/Qt/plugins/accessible/libqtaccessiblewidgets.dylib \ ${BUNDLE_ROOT}/Contents/plugins/ install_name_tool -change QtCore.framework/Versions/4/QtCore \ @executable_path/../Frameworks/QtCore \ ${BUNDLE_ROOT}/Contents/Frameworks/QtGui install_name_tool -change QtCore.framework/Versions/4/QtCore \ @executable_path/../Frameworks/QtCore \ ${BUNDLE_ROOT}/Contents/Frameworks/QtNetwork install_name_tool -change QtCore.framework/Versions/4/QtCore \ @executable_path/../Frameworks/QtCore \ ${BUNDLE_ROOT}/Contents/Frameworks/QtXml test -f ${BUNDLE_ROOT}/Contents/Frameworks/QtDBus && { install_name_tool -change QtCore.framework/Versions/4/QtCore \ @executable_path/../Frameworks/QtCore \ ${BUNDLE_ROOT}/Contents/Frameworks/QtDBus install_name_tool -change QtXml.framework/Versions/4/QtXml \ @executable_path/../Frameworks/QtXml \ ${BUNDLE_ROOT}/Contents/Frameworks/QtDBus } install_name_tool -change QtCore.framework/Versions/4/QtCore \ @executable_path/../Frameworks/QtCore \ ${BUNDLE_ROOT}/Contents/plugins/libqtaccessiblewidgets.dylib install_name_tool -change QtGui.framework/Versions/4/QtGui \ @executable_path/../Frameworks/QtGui \ ${BUNDLE_ROOT}/Contents/plugins/libqtaccessiblewidgets.dylib for f in ${BUNDLE_ROOT}/Contents/MacOS/fwb* do for framework in $QT_FRAMEWORKS do install_name_tool -change ${framework}.framework/Versions/4/${framework} \ @executable_path/../Frameworks/${framework} \ $f done done fwbuilder-5.1.0.3599/config_tests/0000755000175000017500000000000011733011756017465 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/config_tests/qtdbus_test.cpp0000644000175000017500000000026111733011756022531 0ustar sylvestresylvestre #include #include #include main() { QApplication app(); QDBusConnection conn = QDBusConnection::systemBus(); } fwbuilder-5.1.0.3599/config_tests/qtdbus_test.pro0000644000175000017500000000025611733011756022553 0ustar sylvestresylvestre# -*- mode: makefile; tab-width: 4; -*- TEMPLATE = app unix { !macx: QT += network dbus macx: LIBS += -framework QtDBus } SOURCES = qtdbus_test.cpp TARGET = qtdbus_test fwbuilder-5.1.0.3599/test/0000755000175000017500000000000011733011756015755 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/iosacl/0000755000175000017500000000000011733011756017227 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/iosacl/testios20-v12.3.fw.orig0000755000175000017500000001056611733011756023142 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.3 ! !# files: * testios20-v12.3.fw ! ! testios20-v12.3:Policy:10: error: IP options match requires IOS v12.4 or later. ! testios20-v12.3:Policy:10: error: IP options match requires IOS v12.4 or later. ! testios20-v12.3:Policy:10: error: IP options match requires IOS v12.4 or later. ! testios20-v12.3:Policy:10: error: IP options match requires IOS v12.4 or later. ! testios20-v12.3:Policy:11: error: IP options match requires IOS v12.4 or later. ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios20-v12.3 no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule 0 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 2 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 10 (ethernet0) permit ip any any option lsr permit ip any any option record-route permit ip any any option ssr permit ip any any ! ! Rule 11 (ethernet0) permit ip any any option any-options ! ! Rule 12 (global) permit ip any any ! ! Rule 13 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule 2 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 12 (global) permit ip any any ! ! Rule 13 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule 0 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 1 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 12 (global) permit ip any any ! ! Rule 13 (global) deny ip any any log exit ip access-list extended e1_out ! ! Rule 0 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 1 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 12 (global) permit ip any any ! ! Rule 13 (global) deny ip any any log exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/testios20.fw.orig0000755000175000017500000001044311733011756022365 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.4 ! !# files: * testios20.fw ! ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios20 no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule 0 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 2 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 10 (ethernet0) permit ip any any option lsr permit ip any any option record-route permit ip any any option ssr permit ip any any ! ! Rule 11 (ethernet0) permit ip any any option any-options ! ! Rule 12 (ethernet0) permit tcp any any match-all -urg +ack -psh -rst -syn -fin ! ! Rule 13 (ethernet0) permit tcp any any match-all -urg +ack -psh -rst -syn -fin permit tcp any any match-all -urg -ack -psh -rst +syn -fin ! ! Rule 14 (ethernet0) permit tcp any any match-all -urg +ack -psh -rst +syn -fin ! ! Rule 15 (global) permit ip any any ! ! Rule 16 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule 2 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 15 (global) permit ip any any ! ! Rule 16 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule 0 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 1 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 15 (global) permit ip any any ! ! Rule 16 (global) deny ip any any log exit ip access-list extended e1_out ! ! Rule 0 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 1 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any any tos 16 ! ! Rule 7 (global) permit ip any any dscp 16 ! ! Rule 8 (global) permit ip any any dscp af11 ! ! Rule 9 (global) permit ip any any dscp 16 permit ip any any dscp af11 ! ! Rule 15 (global) permit ip any any ! ! Rule 16 (global) deny ip any any log exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/Makefile0000644000175000017500000000073011733011756020667 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_iosacl -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_iosacl -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/iosacl/testios3.fw.orig0000755000175000017500000005452711733011756022321 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * testios3.fw ! ! testios3:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios3 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.0 0.0.0.255 any deny ip any any exit interface ethernet1 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 host 1.1.1.1 eq 22 permit tcp 10.10.10.0 0.0.0.255 host 10.10.10.1 eq 22 ! ! Rule 4 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 10.10.10.0 0.0.0.255 permit tcp host 10.10.10.1 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 0 (ethernet0) deny ip 10.10.10.0 0.0.0.255 host 192.168.1.1 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.2 log deny ip 10.10.10.0 0.0.0.255 192.168.1.3 0.0.0.3 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.200 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.201 log deny ip 10.10.10.0 0.0.0.255 192.168.2.128 0.0.0.127 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.1 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.2 log deny ip 10.10.11.0 0.0.0.255 192.168.1.3 0.0.0.3 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.200 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.201 log deny ip 10.10.11.0 0.0.0.255 192.168.2.128 0.0.0.127 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.1 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.2 log deny ip 10.10.12.0 0.0.0.255 192.168.1.3 0.0.0.3 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.200 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.201 log deny ip 10.10.12.0 0.0.0.255 192.168.2.128 0.0.0.127 log ! ! Rule 1 (ethernet0) deny ip 10.10.10.0 0.0.0.255 host 58.33.181.83 log deny ip 10.10.10.0 0.0.0.255 host 58.53.82.190 log deny ip 10.10.10.0 0.0.0.255 host 58.231.13.78 log deny ip 10.10.10.0 0.0.0.255 host 61.150.47.112 log deny ip 10.10.10.0 0.0.0.255 host 61.184.14.102 log deny ip 10.10.10.0 0.0.0.255 host 64.106.85.186 log deny ip 10.10.10.0 0.0.0.255 host 70.228.60.100 log deny ip 10.10.10.0 0.0.0.255 host 80.51.236.6 log deny ip 10.10.10.0 0.0.0.255 host 80.243.72.149 log deny ip 10.10.10.0 0.0.0.255 host 80.249.77.34 log deny ip 10.10.10.0 0.0.0.255 host 81.2.36.254 log deny ip 10.10.10.0 0.0.0.255 host 81.196.74.125 log deny ip 10.10.10.0 0.0.0.255 host 82.77.37.174 log deny ip 10.10.10.0 0.0.0.255 host 82.117.221.205 log deny ip 10.10.10.0 0.0.0.255 host 82.143.196.17 log deny ip 10.10.10.0 0.0.0.255 host 84.90.8.198 log deny ip 10.10.10.0 0.0.0.255 host 151.8.224.178 log deny ip 10.10.10.0 0.0.0.255 host 168.156.76.20 log deny ip 10.10.10.0 0.0.0.255 host 193.207.126.36 log deny ip 10.10.10.0 0.0.0.255 host 195.136.186.35 log deny ip 10.10.10.0 0.0.0.255 host 196.15.136.15 log deny ip 10.10.10.0 0.0.0.255 host 201.10.180.138 log deny ip 10.10.10.0 0.0.0.255 host 201.17.93.16 log deny ip 10.10.10.0 0.0.0.255 host 201.36.156.121 log deny ip 10.10.10.0 0.0.0.255 host 202.96.112.93 log deny ip 10.10.10.0 0.0.0.255 host 202.103.25.253 log deny ip 10.10.10.0 0.0.0.255 host 203.162.3.209 log deny ip 10.10.10.0 0.0.0.255 host 203.209.124.144 log deny ip 10.10.10.0 0.0.0.255 host 210.106.193.237 log deny ip 10.10.10.0 0.0.0.255 host 210.222.114.102 log deny ip 10.10.10.0 0.0.0.255 host 211.144.143.143 log deny ip 10.10.10.0 0.0.0.255 host 211.172.218.237 log deny ip 10.10.10.0 0.0.0.255 host 211.250.16.132 log deny ip 10.10.10.0 0.0.0.255 host 212.21.241.31 log deny ip 10.10.10.0 0.0.0.255 host 212.100.212.100 log deny ip 10.10.10.0 0.0.0.255 host 218.18.72.252 log deny ip 10.10.10.0 0.0.0.255 host 218.39.114.122 log deny ip 10.10.10.0 0.0.0.255 host 218.55.115.43 log deny ip 10.10.10.0 0.0.0.255 host 218.104.138.146 log deny ip 10.10.10.0 0.0.0.255 host 219.132.104.160 log deny ip 10.10.10.0 0.0.0.255 host 220.71.17.86 log deny ip 10.10.10.0 0.0.0.255 host 220.81.50.105 log deny ip 10.10.10.0 0.0.0.255 host 220.91.99.46 log deny ip 10.10.10.0 0.0.0.255 host 221.14.249.242 log deny ip 10.10.10.0 0.0.0.255 host 221.166.177.135 log deny ip 10.10.10.0 0.0.0.255 host 221.198.33.38 log deny ip 10.10.10.0 0.0.0.255 host 221.202.160.233 log deny ip 10.10.10.0 0.0.0.255 host 221.205.54.125 log deny ip 10.10.10.0 0.0.0.255 host 221.217.44.248 log deny ip 10.10.10.0 0.0.0.255 host 222.100.212.223 log deny ip 10.10.10.0 0.0.0.255 host 222.121.118.144 log deny ip 10.10.10.0 0.0.0.255 host 222.174.113.2 log deny ip 10.10.11.0 0.0.0.255 host 58.33.181.83 log deny ip 10.10.11.0 0.0.0.255 host 58.53.82.190 log deny ip 10.10.11.0 0.0.0.255 host 58.231.13.78 log deny ip 10.10.11.0 0.0.0.255 host 61.150.47.112 log deny ip 10.10.11.0 0.0.0.255 host 61.184.14.102 log deny ip 10.10.11.0 0.0.0.255 host 64.106.85.186 log deny ip 10.10.11.0 0.0.0.255 host 70.228.60.100 log deny ip 10.10.11.0 0.0.0.255 host 80.51.236.6 log deny ip 10.10.11.0 0.0.0.255 host 80.243.72.149 log deny ip 10.10.11.0 0.0.0.255 host 80.249.77.34 log deny ip 10.10.11.0 0.0.0.255 host 81.2.36.254 log deny ip 10.10.11.0 0.0.0.255 host 81.196.74.125 log deny ip 10.10.11.0 0.0.0.255 host 82.77.37.174 log deny ip 10.10.11.0 0.0.0.255 host 82.117.221.205 log deny ip 10.10.11.0 0.0.0.255 host 82.143.196.17 log deny ip 10.10.11.0 0.0.0.255 host 84.90.8.198 log deny ip 10.10.11.0 0.0.0.255 host 151.8.224.178 log deny ip 10.10.11.0 0.0.0.255 host 168.156.76.20 log deny ip 10.10.11.0 0.0.0.255 host 193.207.126.36 log deny ip 10.10.11.0 0.0.0.255 host 195.136.186.35 log deny ip 10.10.11.0 0.0.0.255 host 196.15.136.15 log deny ip 10.10.11.0 0.0.0.255 host 201.10.180.138 log deny ip 10.10.11.0 0.0.0.255 host 201.17.93.16 log deny ip 10.10.11.0 0.0.0.255 host 201.36.156.121 log deny ip 10.10.11.0 0.0.0.255 host 202.96.112.93 log deny ip 10.10.11.0 0.0.0.255 host 202.103.25.253 log deny ip 10.10.11.0 0.0.0.255 host 203.162.3.209 log deny ip 10.10.11.0 0.0.0.255 host 203.209.124.144 log deny ip 10.10.11.0 0.0.0.255 host 210.106.193.237 log deny ip 10.10.11.0 0.0.0.255 host 210.222.114.102 log deny ip 10.10.11.0 0.0.0.255 host 211.144.143.143 log deny ip 10.10.11.0 0.0.0.255 host 211.172.218.237 log deny ip 10.10.11.0 0.0.0.255 host 211.250.16.132 log deny ip 10.10.11.0 0.0.0.255 host 212.21.241.31 log deny ip 10.10.11.0 0.0.0.255 host 212.100.212.100 log deny ip 10.10.11.0 0.0.0.255 host 218.18.72.252 log deny ip 10.10.11.0 0.0.0.255 host 218.39.114.122 log deny ip 10.10.11.0 0.0.0.255 host 218.55.115.43 log deny ip 10.10.11.0 0.0.0.255 host 218.104.138.146 log deny ip 10.10.11.0 0.0.0.255 host 219.132.104.160 log deny ip 10.10.11.0 0.0.0.255 host 220.71.17.86 log deny ip 10.10.11.0 0.0.0.255 host 220.81.50.105 log deny ip 10.10.11.0 0.0.0.255 host 220.91.99.46 log deny ip 10.10.11.0 0.0.0.255 host 221.14.249.242 log deny ip 10.10.11.0 0.0.0.255 host 221.166.177.135 log deny ip 10.10.11.0 0.0.0.255 host 221.198.33.38 log deny ip 10.10.11.0 0.0.0.255 host 221.202.160.233 log deny ip 10.10.11.0 0.0.0.255 host 221.205.54.125 log deny ip 10.10.11.0 0.0.0.255 host 221.217.44.248 log deny ip 10.10.11.0 0.0.0.255 host 222.100.212.223 log deny ip 10.10.11.0 0.0.0.255 host 222.121.118.144 log deny ip 10.10.11.0 0.0.0.255 host 222.174.113.2 log deny ip 10.10.12.0 0.0.0.255 host 58.33.181.83 log deny ip 10.10.12.0 0.0.0.255 host 58.53.82.190 log deny ip 10.10.12.0 0.0.0.255 host 58.231.13.78 log deny ip 10.10.12.0 0.0.0.255 host 61.150.47.112 log deny ip 10.10.12.0 0.0.0.255 host 61.184.14.102 log deny ip 10.10.12.0 0.0.0.255 host 64.106.85.186 log deny ip 10.10.12.0 0.0.0.255 host 70.228.60.100 log deny ip 10.10.12.0 0.0.0.255 host 80.51.236.6 log deny ip 10.10.12.0 0.0.0.255 host 80.243.72.149 log deny ip 10.10.12.0 0.0.0.255 host 80.249.77.34 log deny ip 10.10.12.0 0.0.0.255 host 81.2.36.254 log deny ip 10.10.12.0 0.0.0.255 host 81.196.74.125 log deny ip 10.10.12.0 0.0.0.255 host 82.77.37.174 log deny ip 10.10.12.0 0.0.0.255 host 82.117.221.205 log deny ip 10.10.12.0 0.0.0.255 host 82.143.196.17 log deny ip 10.10.12.0 0.0.0.255 host 84.90.8.198 log deny ip 10.10.12.0 0.0.0.255 host 151.8.224.178 log deny ip 10.10.12.0 0.0.0.255 host 168.156.76.20 log deny ip 10.10.12.0 0.0.0.255 host 193.207.126.36 log deny ip 10.10.12.0 0.0.0.255 host 195.136.186.35 log deny ip 10.10.12.0 0.0.0.255 host 196.15.136.15 log deny ip 10.10.12.0 0.0.0.255 host 201.10.180.138 log deny ip 10.10.12.0 0.0.0.255 host 201.17.93.16 log deny ip 10.10.12.0 0.0.0.255 host 201.36.156.121 log deny ip 10.10.12.0 0.0.0.255 host 202.96.112.93 log deny ip 10.10.12.0 0.0.0.255 host 202.103.25.253 log deny ip 10.10.12.0 0.0.0.255 host 203.162.3.209 log deny ip 10.10.12.0 0.0.0.255 host 203.209.124.144 log deny ip 10.10.12.0 0.0.0.255 host 210.106.193.237 log deny ip 10.10.12.0 0.0.0.255 host 210.222.114.102 log deny ip 10.10.12.0 0.0.0.255 host 211.144.143.143 log deny ip 10.10.12.0 0.0.0.255 host 211.172.218.237 log deny ip 10.10.12.0 0.0.0.255 host 211.250.16.132 log deny ip 10.10.12.0 0.0.0.255 host 212.21.241.31 log deny ip 10.10.12.0 0.0.0.255 host 212.100.212.100 log deny ip 10.10.12.0 0.0.0.255 host 218.18.72.252 log deny ip 10.10.12.0 0.0.0.255 host 218.39.114.122 log deny ip 10.10.12.0 0.0.0.255 host 218.55.115.43 log deny ip 10.10.12.0 0.0.0.255 host 218.104.138.146 log deny ip 10.10.12.0 0.0.0.255 host 219.132.104.160 log deny ip 10.10.12.0 0.0.0.255 host 220.71.17.86 log deny ip 10.10.12.0 0.0.0.255 host 220.81.50.105 log deny ip 10.10.12.0 0.0.0.255 host 220.91.99.46 log deny ip 10.10.12.0 0.0.0.255 host 221.14.249.242 log deny ip 10.10.12.0 0.0.0.255 host 221.166.177.135 log deny ip 10.10.12.0 0.0.0.255 host 221.198.33.38 log deny ip 10.10.12.0 0.0.0.255 host 221.202.160.233 log deny ip 10.10.12.0 0.0.0.255 host 221.205.54.125 log deny ip 10.10.12.0 0.0.0.255 host 221.217.44.248 log deny ip 10.10.12.0 0.0.0.255 host 222.100.212.223 log deny ip 10.10.12.0 0.0.0.255 host 222.121.118.144 log deny ip 10.10.12.0 0.0.0.255 host 222.174.113.2 log ! ! Rule 2 (ethernet0) deny ip 10.10.10.0 0.0.0.255 host 58.33.181.83 log deny ip 10.10.10.0 0.0.0.255 host 58.53.82.190 log deny ip 10.10.10.0 0.0.0.255 host 58.231.13.78 log deny ip 10.10.10.0 0.0.0.255 host 61.150.47.112 log deny ip 10.10.10.0 0.0.0.255 host 61.184.14.102 log deny ip 10.10.10.0 0.0.0.255 host 64.106.85.186 log deny ip 10.10.10.0 0.0.0.255 host 70.228.60.100 log deny ip 10.10.10.0 0.0.0.255 host 80.51.236.6 log deny ip 10.10.10.0 0.0.0.255 host 80.243.72.149 log deny ip 10.10.10.0 0.0.0.255 host 80.249.77.34 log deny ip 10.10.10.0 0.0.0.255 host 81.2.36.254 log deny ip 10.10.10.0 0.0.0.255 host 81.196.74.125 log deny ip 10.10.10.0 0.0.0.255 host 82.77.37.174 log deny ip 10.10.10.0 0.0.0.255 host 82.117.221.205 log deny ip 10.10.10.0 0.0.0.255 host 82.143.196.17 log deny ip 10.10.10.0 0.0.0.255 host 84.90.8.198 log deny ip 10.10.10.0 0.0.0.255 host 151.8.224.178 log deny ip 10.10.10.0 0.0.0.255 host 168.156.76.20 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.1 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.2 log deny ip 10.10.10.0 0.0.0.255 192.168.1.3 0.0.0.3 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.200 log deny ip 10.10.10.0 0.0.0.255 host 192.168.1.201 log deny ip 10.10.10.0 0.0.0.255 192.168.2.128 0.0.0.127 log deny ip 10.10.10.0 0.0.0.255 host 193.207.126.36 log deny ip 10.10.10.0 0.0.0.255 host 195.136.186.35 log deny ip 10.10.10.0 0.0.0.255 host 196.15.136.15 log deny ip 10.10.10.0 0.0.0.255 host 201.10.180.138 log deny ip 10.10.10.0 0.0.0.255 host 201.17.93.16 log deny ip 10.10.10.0 0.0.0.255 host 201.36.156.121 log deny ip 10.10.10.0 0.0.0.255 host 202.96.112.93 log deny ip 10.10.10.0 0.0.0.255 host 202.103.25.253 log deny ip 10.10.10.0 0.0.0.255 host 203.162.3.209 log deny ip 10.10.10.0 0.0.0.255 host 203.209.124.144 log deny ip 10.10.10.0 0.0.0.255 host 210.106.193.237 log deny ip 10.10.10.0 0.0.0.255 host 210.222.114.102 log deny ip 10.10.10.0 0.0.0.255 host 211.144.143.143 log deny ip 10.10.10.0 0.0.0.255 host 211.172.218.237 log deny ip 10.10.10.0 0.0.0.255 host 211.250.16.132 log deny ip 10.10.10.0 0.0.0.255 host 212.21.241.31 log deny ip 10.10.10.0 0.0.0.255 host 212.100.212.100 log deny ip 10.10.10.0 0.0.0.255 host 218.18.72.252 log deny ip 10.10.10.0 0.0.0.255 host 218.39.114.122 log deny ip 10.10.10.0 0.0.0.255 host 218.55.115.43 log deny ip 10.10.10.0 0.0.0.255 host 218.104.138.146 log deny ip 10.10.10.0 0.0.0.255 host 219.132.104.160 log deny ip 10.10.10.0 0.0.0.255 host 220.71.17.86 log deny ip 10.10.10.0 0.0.0.255 host 220.81.50.105 log deny ip 10.10.10.0 0.0.0.255 host 220.91.99.46 log deny ip 10.10.10.0 0.0.0.255 host 221.14.249.242 log deny ip 10.10.10.0 0.0.0.255 host 221.166.177.135 log deny ip 10.10.10.0 0.0.0.255 host 221.198.33.38 log deny ip 10.10.10.0 0.0.0.255 host 221.202.160.233 log deny ip 10.10.10.0 0.0.0.255 host 221.205.54.125 log deny ip 10.10.10.0 0.0.0.255 host 221.217.44.248 log deny ip 10.10.10.0 0.0.0.255 host 222.100.212.223 log deny ip 10.10.10.0 0.0.0.255 host 222.121.118.144 log deny ip 10.10.10.0 0.0.0.255 host 222.174.113.2 log deny ip 10.10.11.0 0.0.0.255 host 58.33.181.83 log deny ip 10.10.11.0 0.0.0.255 host 58.53.82.190 log deny ip 10.10.11.0 0.0.0.255 host 58.231.13.78 log deny ip 10.10.11.0 0.0.0.255 host 61.150.47.112 log deny ip 10.10.11.0 0.0.0.255 host 61.184.14.102 log deny ip 10.10.11.0 0.0.0.255 host 64.106.85.186 log deny ip 10.10.11.0 0.0.0.255 host 70.228.60.100 log deny ip 10.10.11.0 0.0.0.255 host 80.51.236.6 log deny ip 10.10.11.0 0.0.0.255 host 80.243.72.149 log deny ip 10.10.11.0 0.0.0.255 host 80.249.77.34 log deny ip 10.10.11.0 0.0.0.255 host 81.2.36.254 log deny ip 10.10.11.0 0.0.0.255 host 81.196.74.125 log deny ip 10.10.11.0 0.0.0.255 host 82.77.37.174 log deny ip 10.10.11.0 0.0.0.255 host 82.117.221.205 log deny ip 10.10.11.0 0.0.0.255 host 82.143.196.17 log deny ip 10.10.11.0 0.0.0.255 host 84.90.8.198 log deny ip 10.10.11.0 0.0.0.255 host 151.8.224.178 log deny ip 10.10.11.0 0.0.0.255 host 168.156.76.20 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.1 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.2 log deny ip 10.10.11.0 0.0.0.255 192.168.1.3 0.0.0.3 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.200 log deny ip 10.10.11.0 0.0.0.255 host 192.168.1.201 log deny ip 10.10.11.0 0.0.0.255 192.168.2.128 0.0.0.127 log deny ip 10.10.11.0 0.0.0.255 host 193.207.126.36 log deny ip 10.10.11.0 0.0.0.255 host 195.136.186.35 log deny ip 10.10.11.0 0.0.0.255 host 196.15.136.15 log deny ip 10.10.11.0 0.0.0.255 host 201.10.180.138 log deny ip 10.10.11.0 0.0.0.255 host 201.17.93.16 log deny ip 10.10.11.0 0.0.0.255 host 201.36.156.121 log deny ip 10.10.11.0 0.0.0.255 host 202.96.112.93 log deny ip 10.10.11.0 0.0.0.255 host 202.103.25.253 log deny ip 10.10.11.0 0.0.0.255 host 203.162.3.209 log deny ip 10.10.11.0 0.0.0.255 host 203.209.124.144 log deny ip 10.10.11.0 0.0.0.255 host 210.106.193.237 log deny ip 10.10.11.0 0.0.0.255 host 210.222.114.102 log deny ip 10.10.11.0 0.0.0.255 host 211.144.143.143 log deny ip 10.10.11.0 0.0.0.255 host 211.172.218.237 log deny ip 10.10.11.0 0.0.0.255 host 211.250.16.132 log deny ip 10.10.11.0 0.0.0.255 host 212.21.241.31 log deny ip 10.10.11.0 0.0.0.255 host 212.100.212.100 log deny ip 10.10.11.0 0.0.0.255 host 218.18.72.252 log deny ip 10.10.11.0 0.0.0.255 host 218.39.114.122 log deny ip 10.10.11.0 0.0.0.255 host 218.55.115.43 log deny ip 10.10.11.0 0.0.0.255 host 218.104.138.146 log deny ip 10.10.11.0 0.0.0.255 host 219.132.104.160 log deny ip 10.10.11.0 0.0.0.255 host 220.71.17.86 log deny ip 10.10.11.0 0.0.0.255 host 220.81.50.105 log deny ip 10.10.11.0 0.0.0.255 host 220.91.99.46 log deny ip 10.10.11.0 0.0.0.255 host 221.14.249.242 log deny ip 10.10.11.0 0.0.0.255 host 221.166.177.135 log deny ip 10.10.11.0 0.0.0.255 host 221.198.33.38 log deny ip 10.10.11.0 0.0.0.255 host 221.202.160.233 log deny ip 10.10.11.0 0.0.0.255 host 221.205.54.125 log deny ip 10.10.11.0 0.0.0.255 host 221.217.44.248 log deny ip 10.10.11.0 0.0.0.255 host 222.100.212.223 log deny ip 10.10.11.0 0.0.0.255 host 222.121.118.144 log deny ip 10.10.11.0 0.0.0.255 host 222.174.113.2 log deny ip 10.10.12.0 0.0.0.255 host 58.33.181.83 log deny ip 10.10.12.0 0.0.0.255 host 58.53.82.190 log deny ip 10.10.12.0 0.0.0.255 host 58.231.13.78 log deny ip 10.10.12.0 0.0.0.255 host 61.150.47.112 log deny ip 10.10.12.0 0.0.0.255 host 61.184.14.102 log deny ip 10.10.12.0 0.0.0.255 host 64.106.85.186 log deny ip 10.10.12.0 0.0.0.255 host 70.228.60.100 log deny ip 10.10.12.0 0.0.0.255 host 80.51.236.6 log deny ip 10.10.12.0 0.0.0.255 host 80.243.72.149 log deny ip 10.10.12.0 0.0.0.255 host 80.249.77.34 log deny ip 10.10.12.0 0.0.0.255 host 81.2.36.254 log deny ip 10.10.12.0 0.0.0.255 host 81.196.74.125 log deny ip 10.10.12.0 0.0.0.255 host 82.77.37.174 log deny ip 10.10.12.0 0.0.0.255 host 82.117.221.205 log deny ip 10.10.12.0 0.0.0.255 host 82.143.196.17 log deny ip 10.10.12.0 0.0.0.255 host 84.90.8.198 log deny ip 10.10.12.0 0.0.0.255 host 151.8.224.178 log deny ip 10.10.12.0 0.0.0.255 host 168.156.76.20 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.1 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.2 log deny ip 10.10.12.0 0.0.0.255 192.168.1.3 0.0.0.3 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.200 log deny ip 10.10.12.0 0.0.0.255 host 192.168.1.201 log deny ip 10.10.12.0 0.0.0.255 192.168.2.128 0.0.0.127 log deny ip 10.10.12.0 0.0.0.255 host 193.207.126.36 log deny ip 10.10.12.0 0.0.0.255 host 195.136.186.35 log deny ip 10.10.12.0 0.0.0.255 host 196.15.136.15 log deny ip 10.10.12.0 0.0.0.255 host 201.10.180.138 log deny ip 10.10.12.0 0.0.0.255 host 201.17.93.16 log deny ip 10.10.12.0 0.0.0.255 host 201.36.156.121 log deny ip 10.10.12.0 0.0.0.255 host 202.96.112.93 log deny ip 10.10.12.0 0.0.0.255 host 202.103.25.253 log deny ip 10.10.12.0 0.0.0.255 host 203.162.3.209 log deny ip 10.10.12.0 0.0.0.255 host 203.209.124.144 log deny ip 10.10.12.0 0.0.0.255 host 210.106.193.237 log deny ip 10.10.12.0 0.0.0.255 host 210.222.114.102 log deny ip 10.10.12.0 0.0.0.255 host 211.144.143.143 log deny ip 10.10.12.0 0.0.0.255 host 211.172.218.237 log deny ip 10.10.12.0 0.0.0.255 host 211.250.16.132 log deny ip 10.10.12.0 0.0.0.255 host 212.21.241.31 log deny ip 10.10.12.0 0.0.0.255 host 212.100.212.100 log deny ip 10.10.12.0 0.0.0.255 host 218.18.72.252 log deny ip 10.10.12.0 0.0.0.255 host 218.39.114.122 log deny ip 10.10.12.0 0.0.0.255 host 218.55.115.43 log deny ip 10.10.12.0 0.0.0.255 host 218.104.138.146 log deny ip 10.10.12.0 0.0.0.255 host 219.132.104.160 log deny ip 10.10.12.0 0.0.0.255 host 220.71.17.86 log deny ip 10.10.12.0 0.0.0.255 host 220.81.50.105 log deny ip 10.10.12.0 0.0.0.255 host 220.91.99.46 log deny ip 10.10.12.0 0.0.0.255 host 221.14.249.242 log deny ip 10.10.12.0 0.0.0.255 host 221.166.177.135 log deny ip 10.10.12.0 0.0.0.255 host 221.198.33.38 log deny ip 10.10.12.0 0.0.0.255 host 221.202.160.233 log deny ip 10.10.12.0 0.0.0.255 host 221.205.54.125 log deny ip 10.10.12.0 0.0.0.255 host 221.217.44.248 log deny ip 10.10.12.0 0.0.0.255 host 222.100.212.223 log deny ip 10.10.12.0 0.0.0.255 host 222.121.118.144 log deny ip 10.10.12.0 0.0.0.255 host 222.174.113.2 log ! ! Rule 3 (ethernet0) ! testios3:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode deny ip 10.10.10.0 0.0.0.255 192.0.2.0 0.0.0.255 log deny ip 10.10.11.0 0.0.0.255 192.0.2.0 0.0.0.255 log deny ip 10.10.12.0 0.0.0.255 192.0.2.0 0.0.0.255 log ! ! Rule 4 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 host 1.1.1.1 eq 22 permit tcp 10.10.10.0 0.0.0.255 host 10.10.10.1 eq 22 ! ! Rule 4 (global) deny ip any any log exit ip access-list extended e1_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 10.10.10.0 0.0.0.255 permit tcp host 10.10.10.1 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 4 (global) deny ip any any log exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/run.all0000755000175000017500000000100311733011756020522 0ustar sylvestresylvestre#!/bin/sh XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_iosacl -v -f $XMLFILE -xt $fwobj" done exit 0 XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_iosacl -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/iosacl/testios1-1.fw.orig0000755000175000017500000002500711733011756022444 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * testios1-1.fw ! ! dynamic interface eth0 ! ! Prolog script: ! ! This is prolog ! ! End of prolog script: ! hostname testios1-1 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.1 0.0.0.0 any deny ip any any exit interface ethernet0 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule 0 (ethernet0) ! anti-spoofing deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log ! ! Rule 1 (global) ! аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 7 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 9 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 10 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 13 (global) ! interface ethernet1 has address on network 10.10.10.0/24, ! therefore net-10.10.10 is behind the router and we do ! not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 14 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 15 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 16 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 19 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 20 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af11 ! ! Rule 21 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af12 ! ! Rule 22 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule 1 (global) ! аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 10 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 13 (global) ! interface ethernet1 has address on network 10.10.10.0/24, ! therefore net-10.10.10 is behind the router and we do ! not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 14 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 15 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 16 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 19 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 20 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af11 ! ! Rule 21 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af12 ! ! Rule 22 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 8 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 11 (ethernet1) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 exit ip access-list extended e1_out ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 11 (ethernet1) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Rule 0 (main) ! ! ip route 0.0.0.0 0.0.0.0 ! ip route 0.0.0.0 0.0.0.0 ethernet0 1 ! ! Epilog script: ! ! This is epilog for testing ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/testios5-1.fw.orig0000755000175000017500000001623311733011756022451 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:21 2011 PST by vadim ! ! Compiled for iosacl 12.4 ! !# files: * testios5-1.fw ! ! mirrored rules, using object-groups ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios5-1 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.0 0.0.0.255 any deny ip any any exit interface ethernet1 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out no object-group network id115980X79820.1.src.net.0 no object-group network id115999X79820.src.net.0 no object-group network id115999X79820.dst.net.0 no object-group service id116125X79820.srv.tcp.0 no object-group service id91445X81725.srv.tcp.0 object-group network id115980X79820.1.src.net.0 host 1.1.1.1 host 10.10.10.1 exit object-group network id115999X79820.src.net.0 22.22.21.0 /24 22.22.22.0 /24 exit object-group network id115999X79820.dst.net.0 10.10.10.0 /24 10.10.11.0 /24 exit object-group service id116125X79820.srv.tcp.0 tcp eq 80 tcp eq 443 exit object-group service id91445X81725.srv.tcp.0 tcp range 0 65535 tcp eq 80 exit ! ================ IPv4 ip access-list extended e0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 object-group id115980X79820.1.src.net.0 eq 22 ! ! Rule 0 (ethernet0) permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 ! ! Rule 1 (ethernet0) permit ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 2 (ethernet0) permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 permit ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 3 (ethernet0) deny ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 ! ! Rule 4 (ethernet0) permit tcp object-group id115999X79820.src.net.0 eq 80 object-group id115999X79820.dst.net.0 established ! ! Rule 5 (ethernet0) permit tcp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 eq 80 ! ! Rule 6 (ethernet0) permit tcp object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 eq 80 ! ! Rule 7 (ethernet0) permit udp object-group id115999X79820.src.net.0 eq 123 object-group id115999X79820.dst.net.0 ! ! Rule 8 (ethernet0) permit icmp object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 0 ! ! Rule 9 (ethernet0) permit icmp object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 0 permit tcp object-group id115999X79820.src.net.0 eq 80 object-group id115999X79820.dst.net.0 established permit tcp object-group id115999X79820.src.net.0 eq 443 object-group id115999X79820.dst.net.0 established permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 permit udp object-group id115999X79820.src.net.0 eq 123 object-group id115999X79820.dst.net.0 ! ! Rule 10 (ethernet0) permit tcp object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 match-all -urg +ack -psh -rst -syn -fin permit tcp object-group id115999X79820.src.net.0 eq 80 object-group id115999X79820.dst.net.0 established permit tcp object-group id115999X79820.src.net.0 eq 443 object-group id115999X79820.dst.net.0 established permit tcp object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 match-all -urg +ack -psh -rst +syn -fin permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 ! ! Rule 11 (ethernet0) permit object-group id91445X81725.srv.tcp.0 object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 ! ! Rule 12 (ethernet0) permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 exit ip access-list extended e0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp object-group id115980X79820.1.src.net.0 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 0 (ethernet0) permit ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 1 (ethernet0) permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 ! ! Rule 2 (ethernet0) permit ip object-group id115999X79820.src.net.0 object-group id115999X79820.dst.net.0 permit ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 3 (ethernet0) deny ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 4 (ethernet0) permit tcp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 eq 80 ! ! Rule 5 (ethernet0) permit tcp object-group id115999X79820.src.net.0 eq 80 object-group id115999X79820.dst.net.0 established ! ! Rule 6 (ethernet0) permit tcp object-group id115999X79820.dst.net.0 eq 80 object-group id115999X79820.src.net.0 established ! ! Rule 7 (ethernet0) permit udp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 eq 123 ! ! Rule 8 (ethernet0) permit icmp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 8 ! ! Rule 9 (ethernet0) permit icmp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 8 permit object-group id116125X79820.srv.tcp.0 object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 permit udp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 eq 123 ! ! Rule 10 (ethernet0) permit tcp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 match-all -urg +ack -psh -rst -syn -fin permit tcp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 match-all -urg +ack -psh -rst +syn -fin permit object-group id116125X79820.srv.tcp.0 object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 11 (ethernet0) permit tcp object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 established permit tcp object-group id115999X79820.dst.net.0 eq 80 object-group id115999X79820.src.net.0 established permit ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 ! ! Rule 12 (ethernet0) permit ip object-group id115999X79820.dst.net.0 object-group id115999X79820.src.net.0 exit ip access-list extended e1_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 object-group id115980X79820.1.src.net.0 eq 22 exit ip access-list extended e1_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp object-group id115980X79820.1.src.net.0 eq 22 10.10.10.0 0.0.0.255 exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/do-diff0000755000175000017500000000027311733011756020467 0ustar sylvestresylvestre#!/bin/sh N=$1 if which opendiff > /dev/null; then TOOL="opendiff" elif which tkdiff > /dev/null; then TOOL="tkdiff " else TOOL="diff -u -b -B" fi $TOOL ${N}.fw.orig ${N}.fw fwbuilder-5.1.0.3599/test/iosacl/testios4.fw.orig0000755000175000017500000001265611733011756022317 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.4 ! !# files: * testios4.fw ! ! using object-groups ! testios4:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios4 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.0 0.0.0.255 any deny ip any any exit interface ethernet1 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out no object-group network id47161X84238.1.src.net.0 no object-group network id47180X84238.src.net.0 no object-group network id47180X84238.dst.net.0 no object-group network id47192X84238.dst.net.0 no object-group network id47204X84238.dst.net.0 object-group network id47161X84238.1.src.net.0 host 1.1.1.1 host 10.10.10.1 exit object-group network id47180X84238.src.net.0 10.10.10.0 /24 10.10.11.0 /24 10.10.12.0 /24 exit object-group network id47180X84238.dst.net.0 192.168.1.1 /32 192.168.1.2 /32 192.168.1.3 /30 192.168.1.200 /32 192.168.1.201 /32 192.168.2.128 /25 exit object-group network id47192X84238.dst.net.0 58.33.181.83 /32 58.53.82.190 /32 58.231.13.78 /32 61.150.47.112 /32 61.184.14.102 /32 64.106.85.186 /32 70.228.60.100 /32 80.51.236.6 /32 80.243.72.149 /32 80.249.77.34 /32 81.2.36.254 /32 81.196.74.125 /32 82.77.37.174 /32 82.117.221.205 /32 82.143.196.17 /32 84.90.8.198 /32 151.8.224.178 /32 168.156.76.20 /32 193.207.126.36 /32 195.136.186.35 /32 196.15.136.15 /32 201.10.180.138 /32 201.17.93.16 /32 201.36.156.121 /32 202.96.112.93 /32 202.103.25.253 /32 203.162.3.209 /32 203.209.124.144 /32 210.106.193.237 /32 210.222.114.102 /32 211.144.143.143 /32 211.172.218.237 /32 211.250.16.132 /32 212.21.241.31 /32 212.100.212.100 /32 218.18.72.252 /32 218.39.114.122 /32 218.55.115.43 /32 218.104.138.146 /32 219.132.104.160 /32 220.71.17.86 /32 220.81.50.105 /32 220.91.99.46 /32 221.14.249.242 /32 221.166.177.135 /32 221.198.33.38 /32 221.202.160.233 /32 221.205.54.125 /32 221.217.44.248 /32 222.100.212.223 /32 222.121.118.144 /32 222.174.113.2 /32 exit object-group network id47204X84238.dst.net.0 58.33.181.83 /32 58.53.82.190 /32 58.231.13.78 /32 61.150.47.112 /32 61.184.14.102 /32 64.106.85.186 /32 70.228.60.100 /32 80.51.236.6 /32 80.243.72.149 /32 80.249.77.34 /32 81.2.36.254 /32 81.196.74.125 /32 82.77.37.174 /32 82.117.221.205 /32 82.143.196.17 /32 84.90.8.198 /32 151.8.224.178 /32 168.156.76.20 /32 192.168.1.1 /32 192.168.1.2 /32 192.168.1.3 /30 192.168.1.200 /32 192.168.1.201 /32 192.168.2.128 /25 193.207.126.36 /32 195.136.186.35 /32 196.15.136.15 /32 201.10.180.138 /32 201.17.93.16 /32 201.36.156.121 /32 202.96.112.93 /32 202.103.25.253 /32 203.162.3.209 /32 203.209.124.144 /32 210.106.193.237 /32 210.222.114.102 /32 211.144.143.143 /32 211.172.218.237 /32 211.250.16.132 /32 212.21.241.31 /32 212.100.212.100 /32 218.18.72.252 /32 218.39.114.122 /32 218.55.115.43 /32 218.104.138.146 /32 219.132.104.160 /32 220.71.17.86 /32 220.81.50.105 /32 220.91.99.46 /32 221.14.249.242 /32 221.166.177.135 /32 221.198.33.38 /32 221.202.160.233 /32 221.205.54.125 /32 221.217.44.248 /32 222.100.212.223 /32 222.121.118.144 /32 222.174.113.2 /32 exit ! ================ IPv4 ip access-list extended e0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 object-group id47161X84238.1.src.net.0 eq 22 ! ! Rule 4 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp object-group id47161X84238.1.src.net.0 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 0 (ethernet0) deny ip object-group id47180X84238.src.net.0 object-group id47180X84238.dst.net.0 log ! ! Rule 1 (ethernet0) deny ip object-group id47180X84238.src.net.0 object-group id47192X84238.dst.net.0 log ! ! Rule 2 (ethernet0) deny ip object-group id47180X84238.src.net.0 object-group id47204X84238.dst.net.0 log ! ! Rule 3 (ethernet0) ! testios4:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode deny ip object-group id47180X84238.src.net.0 192.0.2.0 0.0.0.255 log ! ! Rule 4 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 object-group id47161X84238.1.src.net.0 eq 22 ! ! Rule 4 (global) deny ip any any log exit ip access-list extended e1_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp object-group id47161X84238.1.src.net.0 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 4 (global) deny ip any any log exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/addr-table-1.tbl0000644000175000017500000000030411733011756022064 0ustar sylvestresylvestre# this is a comment # ; this should be a comment too ; 192.168.1.1 192.168.1.2/32 192.168.1.3/30 192.168.2.128/25 192.168.1.200/32 # comment again 192.168.1.201/32 # this should work, too fwbuilder-5.1.0.3599/test/iosacl/quick-cmp.sh0000755000175000017500000000144311733011756021461 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -B -w -I \"Generated\" -I 'Activating ' -I 'Firewall Builder fwb_iosacl v' -I 'Can not find file' -I '====' -I 'log '" for f in $(ls *.fw.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done exit 0 run_diffs_for_file() { xmlfile=$1 folder=$2 fwbedit list -f $xmlfile -o $folder -c -F%name% | sort | while read fwobj; do V="$fwobj <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" done } run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls # run_diffs_for_file cluster-tests.fwb /User/Clusters fwbuilder-5.1.0.3599/test/iosacl/testios2.fw.orig0000755000175000017500000003115411733011756022307 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * testios2.fw ! ! testios2:Routing:0: error: Object "test-addr-1" used as gateway in the routing rule 0 (main) is not reachable because it is not in any local network of the firewall ! testios2:Routing:1: error: Can not use both gateway address and interface in IOS routing rule ! testios2:Routing:0: error: MultiPath routing not supported by platform ! testios2:Routing:1: error: MultiPath routing not supported by platform ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios2 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.0 0.0.0.255 any deny ip any any exit interface ethernet1 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 host 1.1.1.1 eq 22 permit tcp 10.10.10.0 0.0.0.255 host 10.10.10.1 eq 22 ! ! Rule 0 (ethernet0) ! anti-spoofing deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log ! ! Rule 1 (global) deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 8 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 11 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (global) permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 19 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 10.10.10.0 0.0.0.255 permit tcp host 10.10.10.1 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 1 (global) deny ip any any log fragments ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 11 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 19 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 host 1.1.1.1 eq 22 permit tcp 10.10.10.0 0.0.0.255 host 10.10.10.1 eq 22 ! ! Rule 1 (global) deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 7 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 10 (ethernet1) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (global) permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 19 (global) deny ip any any log exit ip access-list extended e1_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 10.10.10.0 0.0.0.255 permit tcp host 10.10.10.1 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 1 (global) deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 10 (ethernet1) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (global) permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 19 (global) deny ip any any log exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Rule 0 (main) ! ! testios2:Routing:0: error: Object "test-addr-1" used as gateway in the routing rule 0 (main) is not reachable because it is not in any local network of the firewall ! ! Rule 1 (main) ! ! testios2:Routing:1: error: Can not use both gateway address and interface in IOS routing rule ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/firewall-ipv6-3.fw.orig0000755000175000017500000000501511733011756023357 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * firewall-ipv6-3.fw ! ! test "safety net" install in case when there are many rulesets ! ! Prolog script: ! ! ! End of prolog script: ! ! temporary access list for "safety net install" no ipv6 access-list tmp_acl ipv6 access-list tmp_acl permit ipv6 fe80::21d:9ff:aaaa:bbbb/64 any permit icmp any any deny ipv6 any any exit interface Ethernet0/0 no ipv6 traffic-filter in no ipv6 traffic-filter out ipv6 traffic-filter tmp_acl in exit no ip access-list extended e0_0_in no ip access-list extended e0_0_out no ipv6 access-list ipv6_e0_0_in no ipv6 access-list ipv6_e0_0_out no ipv6 access-list ipv6_fw-ipv6-3-ipv6-2_e0_0_in no ipv6 access-list ipv6_fw-ipv6-3-ipv6-2_e0_0_out ! ================ IPv4 ip access-list extended e0_0_in ! ! Rule fw-ipv6-3-ipv4 1 (global) permit 50 host 61.150.47.112 any dscp af12 permit 50 host 192.168.1.0 any dscp af12 exit ip access-list extended e0_0_out permit 50 host 61.150.47.112 any dscp af12 permit 50 host 192.168.1.0 any dscp af12 exit interface Ethernet0/0 ip access-group e0_0_in in exit interface Ethernet0/0 ip access-group e0_0_out out exit ! ================ IPv6 ipv6 access-list ipv6_e0_0_in ! ! Rule fw-ipv6-3-ipv6-1 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule fw-ipv6-3-ipv6-1 1 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log exit ipv6 access-list ipv6_e0_0_out ! ! Rule fw-ipv6-3-ipv6-1 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule fw-ipv6-3-ipv6-1 1 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log exit interface Ethernet0/0 ipv6 traffic-filter ipv6_e0_0_in in exit interface Ethernet0/0 ipv6 traffic-filter ipv6_e0_0_out out exit ! ================ IPv6 ipv6 access-list ipv6_fw-ipv6-3-ipv6-2_e0_0_in ! ! Rule fw-ipv6-3-ipv6-2 0 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 exit ipv6 access-list ipv6_fw-ipv6-3-ipv6-2_e0_0_out permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/firewall-ipv6-1.fw.orig0000755000175000017500000002744511733011756023370 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * firewall-ipv6-1.fw ! ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 3 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 4 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 4 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:2: error: Rule 'fw-ipv6-1-ipv6 2 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 6 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:2: error: Rule 'fw-ipv6-1-ipv6 2 (global)' shadows rule 'fw-ipv6-1-ipv6 6 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 10 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 10 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 11 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 11 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 11 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 11 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 12 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 12 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! ! Prolog script: ! ! ! End of prolog script: ! ! temporary access list for "safety net install" no ipv6 access-list tmp_acl ipv6 access-list tmp_acl permit ipv6 host fe80::21d:9ff:aaaa:bbbb any permit icmp any any deny ipv6 any any exit interface Ethernet0/0 no ipv6 traffic-filter in no ipv6 traffic-filter out ipv6 traffic-filter tmp_acl in exit no ip access-list extended fw-ipv6-1-ipv4_e0_0_in no ip access-list extended fw-ipv6-1-ipv4_e0_0_out no ipv6 access-list ipv6_e0_0_in no ipv6 access-list ipv6_e0_0_out ! ================ IPv4 ip access-list extended fw-ipv6-1-ipv4_e0_0_in ! ! Rule fw-ipv6-1-ipv4 1 (global) permit 50 host 61.150.47.112 any dscp af12 permit 50 host 192.168.1.0 any dscp af12 exit ip access-list extended fw-ipv6-1-ipv4_e0_0_out permit 50 host 61.150.47.112 any dscp af12 permit 50 host 192.168.1.0 any dscp af12 exit ! ================ IPv6 ipv6 access-list ipv6_e0_0_in ! ! Rule fw-ipv6-1-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule fw-ipv6-1-ipv6 1 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 3 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 4 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule fw-ipv6-1-ipv6 2 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:2: error: Rule 'fw-ipv6-1-ipv6 2 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:2: error: Rule 'fw-ipv6-1-ipv6 2 (global)' shadows rule 'fw-ipv6-1-ipv6 6 (global)' below it permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule fw-ipv6-1-ipv6 3 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 4 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-1-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-1-ipv6 5 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp 3ffe:1200:2000::/36 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule fw-ipv6-1-ipv6 6 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule fw-ipv6-1-ipv6 7 (global) permit ipv6 any host fe80::21d:9ff:fe8b:8e94 log ! ! Rule fw-ipv6-1-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule fw-ipv6-1-ipv6 9 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 10 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 11 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 12 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-1-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-1-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule fw-ipv6-1-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule fw-ipv6-1-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit ipv6 access-list ipv6_e0_0_out ! ! Rule fw-ipv6-1-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule fw-ipv6-1-ipv6 1 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 3 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 4 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:1: error: Rule 'fw-ipv6-1-ipv6 1 (global)' shadows rule 'fw-ipv6-1-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule fw-ipv6-1-ipv6 3 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 4 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:3: error: Rule 'fw-ipv6-1-ipv6 3 (global)' shadows rule 'fw-ipv6-1-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-1-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-1-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule fw-ipv6-1-ipv6 9 (global) ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 10 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 11 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 12 (global)' below it ! firewall-ipv6-1:fw-ipv6-1-ipv6:9: error: Rule 'fw-ipv6-1-ipv6 9 (global)' shadows rule 'fw-ipv6-1-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-1-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-1-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule fw-ipv6-1-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule fw-ipv6-1-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit interface Ethernet0/0 ipv6 traffic-filter ipv6_e0_0_in in exit interface Ethernet0/0 ipv6 traffic-filter ipv6_e0_0_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/firewall-ipv6-2.fw.orig0000755000175000017500000003004711733011756023361 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * firewall-ipv6-2.fw ! ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 3 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 4 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 4 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:2: error: Rule 'fw-ipv6-2-ipv6 2 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 6 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:2: error: Rule 'fw-ipv6-2-ipv6 2 (global)' shadows rule 'fw-ipv6-2-ipv6 6 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 10 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 10 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 11 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 11 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 11 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 11 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 12 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 12 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! ! Prolog script: ! ! ! End of prolog script: ! ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 1.1.1.0 0.0.0.255 any deny ip any any exit interface Ethernet0/0 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_0_in no ip access-list extended e0_0_out no ipv6 access-list ipv6_e0_0_in no ipv6 access-list ipv6_e0_0_out ! ================ IPv4 ip access-list extended e0_0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp host 1.1.1.100 host 1.1.1.1 eq 22 ! ! Rule fw-ipv6-2-ipv4 1 (global) permit 50 host 61.150.47.112 any dscp af12 permit 50 host 192.168.1.0 any dscp af12 exit ip access-list extended e0_0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 host 1.1.1.100 ! ! Rule fw-ipv6-2-ipv4 1 (global) permit 50 host 61.150.47.112 any dscp af12 permit 50 host 192.168.1.0 any dscp af12 exit interface Ethernet0/0 ip access-group e0_0_in in exit interface Ethernet0/0 ip access-group e0_0_out out exit ! ================ IPv6 ipv6 access-list ipv6_e0_0_in ! ! Rule fw-ipv6-2-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule fw-ipv6-2-ipv6 1 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 3 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 4 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule fw-ipv6-2-ipv6 2 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:2: error: Rule 'fw-ipv6-2-ipv6 2 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:2: error: Rule 'fw-ipv6-2-ipv6 2 (global)' shadows rule 'fw-ipv6-2-ipv6 6 (global)' below it permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule fw-ipv6-2-ipv6 3 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 4 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-2-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-2-ipv6 5 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp 3ffe:1200:2000::/36 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule fw-ipv6-2-ipv6 6 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule fw-ipv6-2-ipv6 7 (global) permit ipv6 any host fe80::21d:9ff:fe8b:8e94 log ! ! Rule fw-ipv6-2-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule fw-ipv6-2-ipv6 9 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 10 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 11 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 12 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-2-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-2-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule fw-ipv6-2-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule fw-ipv6-2-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit ipv6 access-list ipv6_e0_0_out ! ! Rule fw-ipv6-2-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule fw-ipv6-2-ipv6 1 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 3 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 4 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:1: error: Rule 'fw-ipv6-2-ipv6 1 (global)' shadows rule 'fw-ipv6-2-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule fw-ipv6-2-ipv6 3 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 4 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:3: error: Rule 'fw-ipv6-2-ipv6 3 (global)' shadows rule 'fw-ipv6-2-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-2-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule fw-ipv6-2-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule fw-ipv6-2-ipv6 9 (global) ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 10 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 11 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 12 (global)' below it ! firewall-ipv6-2:fw-ipv6-2-ipv6:9: error: Rule 'fw-ipv6-2-ipv6 9 (global)' shadows rule 'fw-ipv6-2-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-2-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule fw-ipv6-2-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule fw-ipv6-2-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule fw-ipv6-2-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit interface Ethernet0/0 ipv6 traffic-filter ipv6_e0_0_in in exit interface Ethernet0/0 ipv6 traffic-filter ipv6_e0_0_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/recycle0000755000175000017500000000007511733011756020605 0ustar sylvestresylvestre#!/bin/sh for f in *.fw; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/iosacl/dynamips1-og.fw.orig0000755000175000017500000001110411733011756023034 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.4 ! !# files: * dynamips1-og.fw ! ! IOS 12.4 with object-groups ! ! Prolog script: ! ! ! End of prolog script: ! no ip access-list extended fe0_0_in no ip access-list extended fe0_0_out no ipv6 access-list ipv6_fe0_0_in no ipv6 access-list ipv6_fe0_0_out no object-group network id29216X37699.src.net.0 no object-group service id29216X37699.srv.udp.0 no object-group network id18740X37673.dst.net.0 no object-group network id18964X37673.src.net.0 object-group network id29216X37699.src.net.0 host 61.150.47.112 host 192.168.1.0 exit object-group service id29216X37699.srv.udp.0 udp range 1024 65535 udp eq 161 exit object-group network id18740X37673.dst.net.0 10.3.14.0 /24 host 192.0.2.1 host 192.0.2.2 host 192.0.2.3 exit object-group network id18964X37673.src.net.0 host 192.0.2.1 host 192.0.2.2 host 192.0.2.3 exit ! ================ IPv4 ip access-list extended fe0_0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.3.14.0 0.0.0.255 host 10.3.14.114 eq 22 ! ! Rule 1 (FastEthernet0/0) ! object-groups can not be used for ipv6 permit icmp object-group id29216X37699.src.net.0 host 10.3.14.114 8 permit object-group id29216X37699.srv.udp.0 object-group id29216X37699.src.net.0 host 10.3.14.114 ! ! Rule 2 (FastEthernet0/0) permit icmp any object-group id18740X37673.dst.net.0 8 permit object-group id29216X37699.srv.udp.0 any object-group id18740X37673.dst.net.0 ! ! Rule 3 (FastEthernet0/0) permit icmp any object-group id18740X37673.dst.net.0 8 log permit udp any object-group id18740X37673.dst.net.0 eq 161 log ! ! Rule 4 (FastEthernet0/0) permit icmp any host 10.3.14.40 8 log permit object-group id29216X37699.srv.udp.0 any host 10.3.14.40 log ! ! Rule 5 (FastEthernet0/0) permit icmp any 10.3.14.0 0.0.0.255 8 log permit object-group id29216X37699.srv.udp.0 any 10.3.14.0 0.0.0.255 log ! ! Rule 6 (global) permit icmp object-group id18740X37673.dst.net.0 any 8 log permit object-group id29216X37699.srv.udp.0 object-group id18740X37673.dst.net.0 any log ! ! Rule 7 (global) permit icmp object-group id18740X37673.dst.net.0 any 8 log permit object-group id29216X37699.srv.udp.0 object-group id18740X37673.dst.net.0 any log ! ! Rule 8 (global) permit icmp host 10.3.14.40 any 8 log permit object-group id29216X37699.srv.udp.0 host 10.3.14.40 any log ! ! Rule 9 (FastEthernet0/0) permit udp object-group id18964X37673.src.net.0 any eq 161 ! ! Rule 10 (FastEthernet0/0) permit object-group id29216X37699.srv.udp.0 object-group id18964X37673.src.net.0 any ! ! Rule 11 (global) deny ip 10.3.14.0 0.0.0.255 any log ! ! Rule 12 (global) permit ip any host 10.3.14.114 exit ip access-list extended fe0_0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.3.14.114 eq 22 10.3.14.0 0.0.0.255 ! ! Rule 0 (FastEthernet0/0) permit ip host 10.3.14.114 any ! ! Rule 6 (global) permit icmp object-group id18740X37673.dst.net.0 any 8 log permit object-group id29216X37699.srv.udp.0 object-group id18740X37673.dst.net.0 any log ! ! Rule 7 (global) permit icmp object-group id18740X37673.dst.net.0 any 8 log permit object-group id29216X37699.srv.udp.0 object-group id18740X37673.dst.net.0 any log ! ! Rule 8 (global) permit icmp host 10.3.14.40 any 8 log permit object-group id29216X37699.srv.udp.0 host 10.3.14.40 any log ! ! Rule 11 (global) deny ip 10.3.14.0 0.0.0.255 any log exit interface FastEthernet0/0 ip access-group fe0_0_in in exit interface FastEthernet0/0 ip access-group fe0_0_out out exit ! ================ IPv6 ipv6 access-list ipv6_fe0_0_in ! ! Rule 1 (FastEthernet0/0) ! object-groups can not be used for ipv6 permit udp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 gt 1023 permit udp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 161 permit udp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 gt 1023 permit udp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 161 ! ! Rule 12 (global) permit ipv6 any host fe80::21d:9ff:fe8b:8e94 exit ipv6 access-list ipv6_fe0_0_out ! ! Rule 0 (FastEthernet0/0) permit ipv6 host fe80::21d:9ff:fe8b:8e94 any exit interface FastEthernet0/0 ipv6 traffic-filter ipv6_fe0_0_in in exit interface FastEthernet0/0 ipv6 traffic-filter ipv6_fe0_0_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/c3620.fw.orig0000755000175000017500000001421411733011756021266 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * c3620.fw ! ! ! Prolog script: ! ! ! End of prolog script: ! no service timestamp log datetime localtime logging buffered 6 logging console 6 no ip access-list extended e1_0_in no ip access-list extended e1_0_out no ip access-list extended e1_1_in no ip access-list extended e1_1_out no ip access-list extended fe0_0_in no ip access-list extended fe0_0_out ! ================ IPv4 ip access-list extended e1_0_in ! ! Rule -1 backup ssh access rule (automatic) remark -1 backup ssh access rule (automatic) permit tcp host 10.3.14.41 host 10.3.14.201 eq 22 permit tcp host 10.3.14.41 host 192.168.171.2 eq 22 ! ! Rule 1 (Ethernet1/0) ! this comment has empty lines at the end ! remark 1 (Ethernet1/0) remark this comment has empty lines at the end permit tcp any any eq 80 ! ! Rule 2 (Ethernet1/0) ! this comment has empty line in the middle ! ! last line remark 2 (Ethernet1/0) remark this comment has empty line in the middle remark last line permit tcp any any eq 443 ! ! Rule 5 (Ethernet1/0) remark 5 (Ethernet1/0) permit ip any 10.3.14.0 0.0.0.255 ! ! Rule 7 (global) remark 7 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 8 (global) remark 8 (global) permit tcp any 10.3.14.0 0.0.0.255 eq 22 permit udp any 10.3.14.0 0.0.0.255 eq 53 permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 9 (global) remark 9 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 10 (global) remark 10 (global) permit tcp any eq 80 10.3.14.0 0.0.0.255 established exit ip access-list extended e1_0_out ! ! Rule -2 backup ssh access rule (out) (automatic) remark -2 backup ssh access rule (out) (automatic) permit tcp host 10.3.14.201 eq 22 host 10.3.14.41 permit tcp host 192.168.171.2 eq 22 host 10.3.14.41 ! ! Rule 1 (Ethernet1/0) ! this comment has empty lines at the end ! remark 1 (Ethernet1/0) remark this comment has empty lines at the end permit tcp any any eq 80 ! ! Rule 2 (Ethernet1/0) ! this comment has empty line in the middle ! ! last line remark 2 (Ethernet1/0) remark this comment has empty line in the middle remark last line permit tcp any any eq 443 ! ! Rule 4 (Ethernet1/0) ! this comment ends with a whitespace remark 4 (Ethernet1/0) remark this comment ends with a whitespace permit ip 10.3.14.0 0.0.0.255 any exit ip access-list extended e1_1_in ! ! Rule -1 backup ssh access rule (automatic) remark -1 backup ssh access rule (automatic) permit tcp host 10.3.14.41 host 10.3.14.201 eq 22 permit tcp host 10.3.14.41 host 192.168.171.2 eq 22 ! ! Rule 0 (Ethernet1/1) ! interface eth 1/1 has only ! inbound access list remark 0 (Ethernet1/1) remark interface eth 1/1 has only remark inbound access list permit tcp any any eq 80 ! ! Rule 7 (global) remark 7 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 8 (global) remark 8 (global) permit tcp any 10.3.14.0 0.0.0.255 eq 22 permit udp any 10.3.14.0 0.0.0.255 eq 53 permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 9 (global) remark 9 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 10 (global) remark 10 (global) permit tcp any eq 80 10.3.14.0 0.0.0.255 established exit ip access-list extended e1_1_out ! ! Rule -2 backup ssh access rule (out) (automatic) remark -2 backup ssh access rule (out) (automatic) permit tcp host 10.3.14.201 eq 22 host 10.3.14.41 permit tcp host 192.168.171.2 eq 22 host 10.3.14.41 exit ip access-list extended fe0_0_in ! ! Rule -1 backup ssh access rule (automatic) remark -1 backup ssh access rule (automatic) permit tcp host 10.3.14.41 host 10.3.14.201 eq 22 permit tcp host 10.3.14.41 host 192.168.171.2 eq 22 ! ! Rule 3 (FastEthernet0/0) ! this comment starts with a whitespace remark 3 (FastEthernet0/0) remark this comment starts with a whitespace permit ip 10.3.14.0 0.0.0.255 any ! ! Rule 7 (global) remark 7 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 8 (global) remark 8 (global) permit tcp any 10.3.14.0 0.0.0.255 eq 22 permit udp any 10.3.14.0 0.0.0.255 eq 53 permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 9 (global) remark 9 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 10 (global) remark 10 (global) permit tcp any eq 80 10.3.14.0 0.0.0.255 established exit ip access-list extended fe0_0_out ! ! Rule -2 backup ssh access rule (out) (automatic) remark -2 backup ssh access rule (out) (automatic) permit tcp host 10.3.14.201 eq 22 host 10.3.14.41 permit tcp host 192.168.171.2 eq 22 host 10.3.14.41 ! ! Rule 6 (FastEthernet0/0) remark 6 (FastEthernet0/0) permit ip any 10.3.14.0 0.0.0.255 ! ! Rule 7 (global) remark 7 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 8 (global) remark 8 (global) permit tcp any 10.3.14.0 0.0.0.255 eq 22 permit udp any 10.3.14.0 0.0.0.255 eq 53 permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 9 (global) remark 9 (global) permit tcp any 10.3.14.0 0.0.0.255 established ! ! Rule 10 (global) remark 10 (global) permit tcp any eq 80 10.3.14.0 0.0.0.255 established exit interface Ethernet1/0 ip access-group e1_0_in in exit interface Ethernet1/0 ip access-group e1_0_out out exit interface Ethernet1/1 ip access-group e1_1_in in exit interface Ethernet1/1 ip access-group e1_1_out out exit interface FastEthernet0/0 ip access-group fe0_0_in in exit interface FastEthernet0/0 ip access-group fe0_0_out out exit ! ! Rule 0 (main) ! ! ! ip route 10.10.10.0 255.255.255.0 10.3.14.254 1 ! ! Rule 1 (main) ! ! ! ip route 10.10.11.0 255.255.255.0 FastEthernet0/0 1 ! ! Rule 2 (main) ! ! ! ip route 10.10.12.0 255.255.255.0 FastEthernet0/0 1 ! ! Rule 3 (main) ! ! ! ip route 0.0.0.0 0.0.0.0 Ethernet1/0 1 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/objects-for-regression-tests.fwb0000644000175000017500000143201111733011756025464 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk dscp af11 dscp af12 dscp af11 fwbuilder-5.1.0.3599/test/iosacl/testios5.fw.orig0000755000175000017500000003574011733011756022317 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:21 2011 PST by vadim ! ! Compiled for iosacl 12.4 ! !# files: * testios5.fw ! ! mirrored rules, not using object-groups ! ! Prolog script: ! ! ! End of prolog script: ! hostname testios5 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.0 0.0.0.255 any deny ip any any exit interface ethernet1 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 host 1.1.1.1 eq 22 permit tcp 10.10.10.0 0.0.0.255 host 10.10.10.1 eq 22 ! ! Rule 0 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 ! ! Rule 1 (ethernet0) permit ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 ! ! Rule 2 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 ! ! Rule 3 (ethernet0) deny ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 deny ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 ! ! Rule 4 (ethernet0) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.11.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 80 10.10.11.0 0.0.0.255 established ! ! Rule 5 (ethernet0) permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 80 permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 80 permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 80 permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 80 ! ! Rule 6 (ethernet0) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit tcp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 eq 80 permit tcp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit tcp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 eq 80 ! ! Rule 7 (ethernet0) permit udp 22.22.21.0 0.0.0.255 eq 123 10.10.10.0 0.0.0.255 permit udp 22.22.21.0 0.0.0.255 eq 123 10.10.11.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 123 10.10.10.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 123 10.10.11.0 0.0.0.255 ! ! Rule 8 (ethernet0) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit icmp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 0 permit icmp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit icmp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 0 ! ! Rule 9 (ethernet0) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit icmp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 0 permit icmp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit icmp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.11.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 80 10.10.11.0 0.0.0.255 established permit udp 22.22.21.0 0.0.0.255 eq 123 10.10.10.0 0.0.0.255 permit udp 22.22.21.0 0.0.0.255 eq 123 10.10.11.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 123 10.10.10.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 123 10.10.11.0 0.0.0.255 ! ! Rule 10 (ethernet0) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin permit tcp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 eq 80 permit tcp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin permit tcp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit tcp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin permit tcp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 eq 80 permit tcp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin ! ! Rule 11 (ethernet0) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit tcp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit tcp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit tcp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 ! ! Rule 12 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 option any-options permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp 16 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 option any-options permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 dscp 16 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 option any-options permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp 16 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 option any-options permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 dscp 16 ! ! Rule 13 (ethernet0) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit icmp 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 0 permit icmp 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit icmp 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 eq 179 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 79 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 179 10.10.11.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 79 10.10.11.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 179 10.10.10.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 79 10.10.10.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 179 10.10.11.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 79 10.10.11.0 0.0.0.255 established permit udp 22.22.21.0 0.0.0.255 eq 123 10.10.10.0 0.0.0.255 permit udp 22.22.21.0 0.0.0.255 eq 26000 10.10.10.0 0.0.0.255 permit udp 22.22.21.0 0.0.0.255 eq 123 10.10.11.0 0.0.0.255 permit udp 22.22.21.0 0.0.0.255 eq 26000 10.10.11.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 123 10.10.10.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 26000 10.10.10.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 123 10.10.11.0 0.0.0.255 permit udp 22.22.22.0 0.0.0.255 eq 26000 10.10.11.0 0.0.0.255 exit ip access-list extended e0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 10.10.10.0 0.0.0.255 permit tcp host 10.10.10.1 eq 22 10.10.10.0 0.0.0.255 ! ! Rule 0 (ethernet0) permit ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 ! ! Rule 1 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 ! ! Rule 2 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 permit ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 ! ! Rule 3 (ethernet0) deny ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 deny ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 deny ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 deny ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 ! ! Rule 4 (ethernet0) permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 80 permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 80 permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 80 permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 80 ! ! Rule 5 (ethernet0) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.11.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit tcp 22.22.22.0 0.0.0.255 eq 80 10.10.11.0 0.0.0.255 established ! ! Rule 6 (ethernet0) permit tcp 10.10.10.0 0.0.0.255 eq 80 22.22.21.0 0.0.0.255 established permit tcp 10.10.10.0 0.0.0.255 eq 80 22.22.22.0 0.0.0.255 established permit tcp 10.10.11.0 0.0.0.255 eq 80 22.22.21.0 0.0.0.255 established permit tcp 10.10.11.0 0.0.0.255 eq 80 22.22.22.0 0.0.0.255 established ! ! Rule 7 (ethernet0) permit udp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 123 permit udp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 123 permit udp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 123 permit udp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 123 ! ! Rule 8 (ethernet0) permit icmp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 8 permit icmp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 8 permit icmp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 8 permit icmp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 8 ! ! Rule 9 (ethernet0) permit icmp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 8 permit icmp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 8 permit icmp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 8 permit icmp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 8 permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 80 permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 80 permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 80 permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 80 permit udp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 123 permit udp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 123 permit udp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 123 permit udp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 123 ! ! Rule 10 (ethernet0) permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 10.10.10.0 0.0.0.255 eq 80 22.22.21.0 0.0.0.255 established permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 10.10.10.0 0.0.0.255 eq 80 22.22.22.0 0.0.0.255 established permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 10.10.11.0 0.0.0.255 eq 80 22.22.21.0 0.0.0.255 established permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 match-all -urg +ack -psh -rst -syn -fin permit tcp 10.10.11.0 0.0.0.255 eq 80 22.22.22.0 0.0.0.255 established permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 match-all -urg +ack -psh -rst +syn -fin ! ! Rule 11 (ethernet0) permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 established permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 established permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 established permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 established ! ! Rule 12 (ethernet0) permit ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 option any-options permit ip 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 dscp 16 permit ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 option any-options permit ip 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 dscp 16 permit ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 option any-options permit ip 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 dscp 16 permit ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 option any-options permit ip 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 dscp 16 ! ! Rule 13 (ethernet0) permit icmp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 0 permit icmp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 0 permit icmp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 0 permit icmp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 0 permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 179 permit tcp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 79 permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 179 permit tcp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 79 permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 179 permit tcp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 79 permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 179 permit tcp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 79 permit udp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 123 permit udp 10.10.10.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 26000 permit udp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 123 permit udp 10.10.10.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 26000 permit udp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 123 permit udp 10.10.11.0 0.0.0.255 22.22.21.0 0.0.0.255 eq 26000 permit udp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 123 permit udp 10.10.11.0 0.0.0.255 22.22.22.0 0.0.0.255 eq 26000 exit ip access-list extended e1_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp 10.10.10.0 0.0.0.255 host 1.1.1.1 eq 22 permit tcp 10.10.10.0 0.0.0.255 host 10.10.10.1 eq 22 exit ip access-list extended e1_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 10.10.10.0 0.0.0.255 permit tcp host 10.10.10.1 eq 22 10.10.10.0 0.0.0.255 exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/block-hosts.tbl0000644000175000017500000000163011733011756022162 0ustar sylvestresylvestre# # use this table to test run-time AddressTable object # (this is just a small collection of addresses that sent spam to me # on Nov 20 2005) # 151.8.224.178 # this is also a comment 168.156.76.20 193.207.126.36 195.136.186.35 196.15.136.15 201.10.180.138 201.17.93.16 201.36.156.121 202.103.25.253 202.96.112.93 203.162.3.209 203.209.124.144 210.106.193.237 210.222.114.102 211.144.143.143 211.172.218.237 211.250.16.132 212.100.212.100 212.21.241.31 218.104.138.146 218.18.72.252 218.39.114.122 218.55.115.43 219.132.104.160 220.71.17.86 220.81.50.105 220.91.99.46 221.14.249.242 221.166.177.135 221.198.33.38 221.202.160.233 221.205.54.125 221.217.44.248 222.100.212.223 222.121.118.144 222.174.113.2 58.231.13.78 58.33.181.83 58.53.82.190 61.150.47.112 61.184.14.102 64.106.85.186 70.228.60.100 80.243.72.149 80.249.77.34 80.51.236.6 81.196.74.125 81.2.36.254 82.117.221.205 82.143.196.17 82.77.37.174 84.90.8.198 fwbuilder-5.1.0.3599/test/iosacl/testios1.fw.orig0000755000175000017500000002543111733011756022307 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:20 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * testios1.fw ! ! ! Prolog script: ! ! This is prolog ! ! End of prolog script: ! hostname testios1 ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.10.1 0.0.0.0 any deny ip any any exit interface ethernet0 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e0_in no ip access-list extended e0_out no ip access-list extended e1_in no ip access-list extended e1_out ! ================ IPv4 ip access-list extended e0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp host 1.1.1.100 host 1.1.1.1 eq 22 permit tcp host 1.1.1.100 host 3.3.3.3 eq 22 permit tcp host 1.1.1.100 host 10.10.10.1 eq 22 ! ! Rule 0 (ethernet0) ! anti-spoofing deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log ! ! Rule 1 (global) ! аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 7 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 9 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 10 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 13 (global) ! interface ethernet1 has address on network 10.10.10.0/24, ! therefore net-10.10.10 is behind the router and we do ! not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 14 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 15 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 16 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 19 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 20 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af11 ! ! Rule 21 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af12 ! ! Rule 22 (global) deny ip any any log exit ip access-list extended e0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 1.1.1.1 eq 22 host 1.1.1.100 permit tcp host 3.3.3.3 eq 22 host 1.1.1.100 permit tcp host 10.10.10.1 eq 22 host 1.1.1.100 ! ! Rule 1 (global) ! аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ deny ip any any log fragments ! ! Rule 2 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 6 (ethernet0) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 10 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 12 (ethernet0) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ! ! Rule 13 (global) ! interface ethernet1 has address on network 10.10.10.0/24, ! therefore net-10.10.10 is behind the router and we do ! not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ! ! Rule 14 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ! ! Rule 15 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ! ! Rule 16 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ! ! Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ! ! Rule 18 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ! ! Rule 19 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ! ! Rule 20 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af11 ! ! Rule 21 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 dscp af12 ! ! Rule 22 (global) deny ip any any log exit ip access-list extended e1_in ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 8 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 11 (ethernet1) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 exit ip access-list extended e1_out ! ! Rule 3 (ethernet0,ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 4 (testios1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 5 (ethernet1) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ! ! Rule 11 (ethernet1) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 exit interface ethernet0 ip access-group e0_in in exit interface ethernet0 ip access-group e0_out out exit interface ethernet1 ip access-group e1_in in exit interface ethernet1 ip access-group e1_out out exit ! ! Epilog script: ! ! This is epilog for testing ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/auto-interface-test.fw.orig0000755000175000017500000001125411733011756024415 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * auto-interface-test.fw ! ! An example of Cisco router ! ! Prolog script: ! ! ! End of prolog script: ! ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 192.168.1.1 0.0.0.0 any deny ip any any exit interface FastEthernet0/0 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended e1_0_in no ip access-list extended e1_0_out no ip access-list extended e1_1_in no ip access-list extended e1_1_out no ip access-list extended fe0_0_in no ip access-list extended fe0_0_out no ipv6 access-list ipv6_Policy_v6_e1_0_in no ipv6 access-list ipv6_Policy_v6_e1_0_out no ipv6 access-list ipv6_Policy_v6_e1_1_in no ipv6 access-list ipv6_Policy_v6_e1_1_out no ipv6 access-list ipv6_Policy_v6_fe0_0_in no ipv6 access-list ipv6_Policy_v6_fe0_0_out ! ================ IPv4 ip access-list extended e1_0_in ! ! Rule 0 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 1 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 4 (global) permit ip 10.1.0.0 0.0.255.255 any exit ip access-list extended e1_0_out ! ! Rule 0 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 2 (global) permit ip 10.1.2.0 0.0.0.255 any ! ! Rule 3 (global) permit ip 10.1.3.0 0.0.0.255 any ! ! Rule 4 (global) permit ip 10.1.0.0 0.0.255.255 any exit ip access-list extended e1_1_in ! ! Rule 1 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 2 (global) permit ip 10.1.2.0 0.0.0.255 any ! ! Rule 4 (global) permit ip 10.1.0.0 0.0.255.255 any exit ip access-list extended e1_1_out ! ! Rule 0 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 2 (global) permit ip 10.1.2.0 0.0.0.255 any ! ! Rule 3 (global) permit ip 10.1.3.0 0.0.0.255 any ! ! Rule 4 (global) permit ip 10.1.0.0 0.0.255.255 any exit ip access-list extended fe0_0_in ! ! Rule 1 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 3 (global) permit ip 10.1.3.0 0.0.0.255 any ! ! Rule 4 (global) permit ip 10.1.0.0 0.0.255.255 any exit ip access-list extended fe0_0_out ! ! Rule 0 (global) permit ip 10.1.1.0 0.0.0.255 any ! ! Rule 2 (global) permit ip 10.1.2.0 0.0.0.255 any ! ! Rule 3 (global) permit ip 10.1.3.0 0.0.0.255 any ! ! Rule 4 (global) permit ip 10.1.0.0 0.0.255.255 any exit interface Ethernet1/0 ip access-group e1_0_in in exit interface Ethernet1/0 ip access-group e1_0_out out exit interface Ethernet1/1 ip access-group e1_1_in in exit interface Ethernet1/1 ip access-group e1_1_out out exit interface FastEthernet0/0 ip access-group fe0_0_in in exit interface FastEthernet0/0 ip access-group fe0_0_out out exit ! ================ IPv6 ipv6 access-list ipv6_Policy_v6_e1_0_in ! ! Rule Policy_v6 0 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 1 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 4 (global) permit ipv6 2001:1234::/48 any exit ipv6 access-list ipv6_Policy_v6_e1_0_out ! ! Rule Policy_v6 0 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 2 (global) permit ipv6 2001:1234:2::/64 any ! ! Rule Policy_v6 3 (global) permit ipv6 2001:1234:3::/64 any ! ! Rule Policy_v6 4 (global) permit ipv6 2001:1234::/48 any exit ipv6 access-list ipv6_Policy_v6_e1_1_in ! ! Rule Policy_v6 1 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 2 (global) permit ipv6 2001:1234:2::/64 any ! ! Rule Policy_v6 4 (global) permit ipv6 2001:1234::/48 any exit ipv6 access-list ipv6_Policy_v6_e1_1_out ! ! Rule Policy_v6 0 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 2 (global) permit ipv6 2001:1234:2::/64 any ! ! Rule Policy_v6 3 (global) permit ipv6 2001:1234:3::/64 any ! ! Rule Policy_v6 4 (global) permit ipv6 2001:1234::/48 any exit ipv6 access-list ipv6_Policy_v6_fe0_0_in ! ! Rule Policy_v6 1 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 3 (global) permit ipv6 2001:1234:3::/64 any ! ! Rule Policy_v6 4 (global) permit ipv6 2001:1234::/48 any exit ipv6 access-list ipv6_Policy_v6_fe0_0_out ! ! Rule Policy_v6 0 (global) permit ipv6 2001:1234:1::/64 any ! ! Rule Policy_v6 2 (global) permit ipv6 2001:1234:2::/64 any ! ! Rule Policy_v6 3 (global) permit ipv6 2001:1234:3::/64 any ! ! Rule Policy_v6 4 (global) permit ipv6 2001:1234::/48 any exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/ccie4u-r1.fw.orig0000755000175000017500000004527411733011756022237 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v5.0.1.3584 ! ! Generated Tue Nov 8 08:41:19 2011 PST by vadim ! ! Compiled for iosacl 12.1 ! !# files: * ccie4u-r1.fw ! ! CCIE4U router R1 ! 2600 ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 3 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:2: error: Rule 'r1-ipv6 2 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 6 (global)' below it ! ccie4u-r1:r1-ipv6:2: error: Rule 'r1-ipv6 2 (global)' shadows rule 'r1-ipv6 6 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 10 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 10 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 12 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 12 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ! Prolog script: ! ! ! End of prolog script: ! ! temporary access list for "safety net install" no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.1.1.0 0.0.0.0 any deny ip any any exit interface FastEthernet0/0 no ip access-group in no ip access-group out ip access-group tmp_acl in exit no ip access-list extended fe0_0_in no ip access-list extended fe0_0_out no ip access-list extended fe0_1_in no ip access-list extended fe0_1_out no ipv6 access-list ipv6_fe0_0_in no ipv6 access-list ipv6_fe0_0_out no ipv6 access-list ipv6_fe0_1_in no ipv6 access-list ipv6_fe0_1_out ! ================ IPv4 ip access-list extended fe0_0_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp host 10.1.1.100 host 10.1.1.1 eq 22 permit tcp host 10.1.1.100 host 10.1.2.1 eq 22 ! ! Rule r1-ipv4 1 (global) permit icmp any host 61.150.47.112 8 permit icmp any host 192.168.1.0 8 permit 50 any host 61.150.47.112 dscp af12 permit 50 any host 192.168.1.0 dscp af12 ! ! Rule r1-ipv4 2 (global) permit icmp host 61.150.47.112 any 8 permit icmp host 192.168.1.0 any 8 exit ip access-list extended fe0_0_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.1.1.1 eq 22 host 10.1.1.100 permit tcp host 10.1.2.1 eq 22 host 10.1.1.100 ! ! Rule r1-ipv4 1 (global) permit icmp any host 61.150.47.112 8 permit icmp any host 192.168.1.0 8 permit 50 any host 61.150.47.112 dscp af12 permit 50 any host 192.168.1.0 dscp af12 ! ! Rule r1-ipv4 2 (global) permit icmp host 61.150.47.112 any 8 permit icmp host 192.168.1.0 any 8 exit ip access-list extended fe0_1_in ! ! Rule -1 backup ssh access rule (automatic) permit tcp host 10.1.1.100 host 10.1.1.1 eq 22 permit tcp host 10.1.1.100 host 10.1.2.1 eq 22 ! ! Rule r1-ipv4 1 (global) permit icmp any host 61.150.47.112 8 permit icmp any host 192.168.1.0 8 permit 50 any host 61.150.47.112 dscp af12 permit 50 any host 192.168.1.0 dscp af12 ! ! Rule r1-ipv4 2 (global) permit icmp host 61.150.47.112 any 8 permit icmp host 192.168.1.0 any 8 exit ip access-list extended fe0_1_out ! ! Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.1.1.1 eq 22 host 10.1.1.100 permit tcp host 10.1.2.1 eq 22 host 10.1.1.100 ! ! Rule r1-ipv4 1 (global) permit icmp any host 61.150.47.112 8 permit icmp any host 192.168.1.0 8 permit 50 any host 61.150.47.112 dscp af12 permit 50 any host 192.168.1.0 dscp af12 ! ! Rule r1-ipv4 2 (global) permit icmp host 61.150.47.112 any 8 permit icmp host 192.168.1.0 any 8 exit interface FastEthernet0/0 ip access-group fe0_0_in in exit interface FastEthernet0/0 ip access-group fe0_0_out out exit interface FastEthernet0/1 ip access-group fe0_1_in in exit interface FastEthernet0/1 ip access-group fe0_1_out out exit ! ================ IPv6 ipv6 access-list ipv6_fe0_0_in ! ! Rule r1-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule r1-ipv6 1 (global) ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 3 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule r1-ipv6 2 (global) ! ccie4u-r1:r1-ipv6:2: error: Rule 'r1-ipv6 2 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:2: error: Rule 'r1-ipv6 2 (global)' shadows rule 'r1-ipv6 6 (global)' below it permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule r1-ipv6 3 (global) ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 5 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp 3ffe:1200:2000::/36 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule r1-ipv6 6 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule r1-ipv6 7 (global) permit ipv6 any host fe80::21d:9ff:fe8b:8e94 log ! ! Rule r1-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule r1-ipv6 9 (global) ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 10 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 12 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule r1-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule r1-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit ipv6 access-list ipv6_fe0_0_out ! ! Rule r1-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule r1-ipv6 1 (global) ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 3 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule r1-ipv6 3 (global) ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule r1-ipv6 9 (global) ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 10 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 12 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule r1-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule r1-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit ipv6 access-list ipv6_fe0_1_in ! ! Rule r1-ipv6 1 (global) ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 3 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule r1-ipv6 2 (global) ! ccie4u-r1:r1-ipv6:2: error: Rule 'r1-ipv6 2 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:2: error: Rule 'r1-ipv6 2 (global)' shadows rule 'r1-ipv6 6 (global)' below it permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule r1-ipv6 3 (global) ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 5 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp 3ffe:1200:2000::/36 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule r1-ipv6 6 (global) permit tcp host 2001:5c0:0:2::24 host fe80::21d:9ff:fe8b:8e94 eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 host fe80::21d:9ff:fe8b:8e94 eq 22 log ! ! Rule r1-ipv6 7 (global) permit ipv6 any host fe80::21d:9ff:fe8b:8e94 log ! ! Rule r1-ipv6 9 (global) ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 10 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 12 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule r1-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule r1-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit ipv6 access-list ipv6_fe0_1_out ! ! Rule r1-ipv6 0 (global) permit tcp fe80::/64 any eq 22 ! ! Rule r1-ipv6 1 (global) ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 3 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 5 (global)' below it ! ccie4u-r1:r1-ipv6:1: error: Rule 'r1-ipv6 1 (global)' shadows rule 'r1-ipv6 6 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 ! ! Rule r1-ipv6 3 (global) ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 13 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 4 (global)' below it ! ccie4u-r1:r1-ipv6:3: error: Rule 'r1-ipv6 3 (global)' shadows rule 'r1-ipv6 5 (global)' below it permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp 3ffe:1200:2000::/36 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 4 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 log permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 log ! ! Rule r1-ipv6 8 (global) permit ipv6 fe80::/64 any log ! ! Rule r1-ipv6 9 (global) ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 10 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 11 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 12 (global)' below it ! ccie4u-r1:r1-ipv6:9: error: Rule 'r1-ipv6 9 (global)' shadows rule 'r1-ipv6 13 (global)' below it permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 3ffe:1200:2000::/36 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 10 (global) permit ipv6 host 2001:5c0:0:2::24 any log permit ipv6 host 3ffe:1200:2001:1:8000::1 any log ! ! Rule r1-ipv6 11 (global) permit 50 host 2001:5c0:0:2::24 any dscp af11 permit 50 host 3ffe:1200:2001:1:8000::1 any dscp af11 ! ! Rule r1-ipv6 12 (global) permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established ! ! Rule r1-ipv6 13 (global) permit tcp host 2001:5c0:0:2::24 any eq 22 permit tcp host 3ffe:1200:2001:1:8000::1 any eq 22 permit udp host 2001:5c0:0:2::24 any eq 161 permit udp host 3ffe:1200:2001:1:8000::1 any eq 161 permit icmp host 2001:5c0:0:2::24 any 128 permit icmp host 3ffe:1200:2001:1:8000::1 any 128 permit tcp host 2001:5c0:0:2::24 any established permit tcp host 3ffe:1200:2001:1:8000::1 any established exit interface FastEthernet0/0 ipv6 traffic-filter ipv6_fe0_0_in in exit interface FastEthernet0/0 ipv6 traffic-filter ipv6_fe0_0_out out exit interface FastEthernet0/1 ipv6 traffic-filter ipv6_fe0_1_in in exit interface FastEthernet0/1 ipv6 traffic-filter ipv6_fe0_1_out out exit ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/iosacl/cluster-tests.fwb0000644000175000017500000070330211733011756022555 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/test/pf/0000755000175000017500000000000011733011756016362 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/pf/firewall21.conf.orig0000644000175000017500000000167711733011756022153 0ustar sylvestresylvestre # NAT compiler errors and warnings: # firewall21:NAT:3: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' # # Rule 0 (NAT) nat-anchor "ftp-proxy/*" rdr-anchor "ftp-proxy/*" # # Rule 1 (NAT) rdr proto tcp from 192.168.1.0/24 to any port 21 -> 127.0.0.1 port 8021 # # Rule 2 (NAT) nat-anchor "NAT_1" from 192.168.1.0/24 to any rdr-anchor "NAT_1" from 192.168.1.0/24 to any # # Rule 3 (NAT) # firewall21:NAT:3: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' nat-anchor "NAT_1" from 192.168.1.0/24 to any rdr-anchor "NAT_1" from 192.168.1.0/24 to any # # Rule 0 (global) anchor "ftp-proxy/*" inet from any to any no state # # Rule 1 (global) pass quick inet proto tcp from any to 127.0.0.1 port 8021 flags any # # Rule fallback rule # fallback rule block quick inet from any to any no state load anchor NAT_1 from "/etc/fw/firewall21-NAT_1.conf" fwbuilder-5.1.0.3599/test/pf/firewall107.fw.orig0000755000175000017500000002417711733011756021732 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:07 2011 PST by vadim # # files: * firewall107.fw /etc/fw/pf.fw # files: firewall107.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # vlan interface, static address, shell script format FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan101 vlan102 sync_bridge_interfaces sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" update_vlans_of_interface "em2 vlan101:101 vlan102:102" update_addresses_of_interface "em2" "" update_addresses_of_interface "vlan101 192.168.101.1/0xffffff00" "" update_addresses_of_interface "vlan102 192.168.102.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:07 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall-base-rulesets.conf.orig0000644000175000017500000000075511733011756024560 0ustar sylvestresylvestre # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE -1 -- DROP " load anchor mail_server_inbound from "/etc/fw/firewall-base-rulesets-mail_server_inbound.conf" load anchor mail_server_outbound from "/etc/fw/firewall-base-rulesets-mail_server_outbound.conf" load anchor web_server_inbound from "/etc/fw/firewall-base-rulesets-web_server_inbound.conf" load anchor web_server_outbound from "/etc/fw/firewall-base-rulesets-web_server_outbound.conf" fwbuilder-5.1.0.3599/test/pf/firewall34.conf.orig0000644000175000017500000000560611733011756022153 0ustar sylvestresylvestre # Tables: (4) table persist file "block-hosts.tbl" table persist table { 192.168.1.1 , 192.168.1.2 , 192.168.1.3/30 , 192.168.1.200 , 192.168.1.201 , 192.168.2.128/25 } table { 7.7.7.7 , 61.150.47.112 , 192.168.1.1 , 192.168.1.2 , 192.168.1.3/30 , 192.168.1.200 , 192.168.1.201 , 192.168.2.128/25 } # # Rule 0 (NAT) rdr on eth0.100 proto tcp from ! to (eth0.100) port 25 -> 192.168.1.10 port 25 # # Rule 1 (NAT) rdr on eth0.100 proto tcp from to (eth0.100) port 25 -> 192.168.1.10 port 25 rdr on eth0.100 proto tcp from to (eth0.100) port 25 -> 192.168.1.10 port 25 # # Rule 2 (NAT) nat on eth0.100 from 192.168.1.0/24 to ! -> (eth0.100) # # Rule 3 (NAT) rdr proto tcp from any to (eth0.100) port 25 -> { 192.168.1.1 , 192.168.1.2 , 192.168.1.200 , 192.168.1.201 , 192.168.1.3/30 , 192.168.2.128/25 } port 25 # # Rule 4 (NAT) rdr from any to (eth0.100) -> { 192.168.1.1 , 192.168.1.2 , 192.168.1.200 , 192.168.1.201 , 192.168.1.3/30 , 192.168.2.128/25 } # # Rule 5 (NAT) no nat from 192.168.1.0/24 to no rdr from 192.168.1.0/24 to # # Rule 6 (NAT) rdr from 192.168.1.0/24 to -> (lo) # # Rule 0 (global) pass quick inet from any to keep state label "RULE 0 -- ACCEPT on global " # # Rule 1 (global) block log quick inet from any to label "RULE 1 -- DROP on global " # # Rule 2 (global) block log quick inet from any to label "RULE 2 -- DROP on global " block log quick inet from any to label "RULE 2 -- DROP on global " # # Rule 3 (global) block log quick inet from any to label "RULE 3 -- DROP on global " # # Rule 4 (global) block log quick inet from to any label "RULE 4 -- DROP on global " # # Rule 5 (global) block quick inet proto tcp from any to port 25 label "RULE 5 -- DROP on global " block quick inet proto tcp from any to 61.150.47.112 port 25 label "RULE 5 -- DROP on global " # # Rule 6 (global) block log quick inet from to any label "RULE 6 -- DROP on global " # # Rule 7 (global) block log quick inet from to any label "RULE 7 -- DROP on global " block log quick inet from 61.150.47.112 to any label "RULE 7 -- DROP on global " # # Rule 9 (global) pass quick inet proto tcp from any to 192.168.1.10 port 25 keep state ( max-src-conn 5, overload flush global ) label "RULE 9 -- ACCEPT on global " # # Rule 10 (global) pass quick inet from 192.168.1.0/24 to any keep state label "RULE 10 -- ACCEPT on global " # # Rule 11 (global) block log quick inet from any to any label "RULE 11 -- DROP on global " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP on global " fwbuilder-5.1.0.3599/test/pf/firewall103.fw.orig0000755000175000017500000002421211733011756021714 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:02 2011 PST by vadim # # files: * firewall103.fw /etc/fw/pf.fw # files: firewall103.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # bridge interface, static address, shell script format FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" update_addresses_of_interface "em2" "" update_addresses_of_interface "em3" "" update_bridge_interface bridge0 "em2 em3" $IFCONFIG bridge0 -stp em2 $IFCONFIG bridge0 -stp em3 update_addresses_of_interface "bridge0 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:02 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall104-1.fw.orig0000755000175000017500000002405111733011756022054 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:05 2011 PST by vadim # # files: * firewall104-1.fw /etc/fw/pf.fw # files: firewall104-1.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # bridge interface, dynamic address, shell script format, OpenBSD 4.7 FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" update_addresses_of_interface "em2" "" update_addresses_of_interface "em3" "" update_bridge_interface bridge0 "em2 em3" $IFCONFIG bridge0 -stp em2 $IFCONFIG bridge0 -stp em3 } log "Activating firewall script generated Wed Nov 30 18:39:05 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall40-2.fw.orig0000755000175000017500000000734211733011756022000 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:22 2011 PST by vadim # # files: * firewall40-2.fw /etc/firewall40-2.fw # files: firewall40-2.conf /etc/firewall40-2.conf # # Compiled for pf 4.7 # # testing Route action for PF v4.7 and later FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "fxp0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "le1 192.0.2.1/0xffffff00" "" update_addresses_of_interface "le2 192.0.3.1/0xffffff00" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:22 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall40-2.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall1.fw.orig0000755000175000017500000000270111733011756021550 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:38:58 2011 PST by vadim # # files: * firewall1.fw /etc/fw/firewall1.fw # files: firewall1.conf /etc/fw/firewall1.conf # # Compiled for pf # # this object is used to test all kinds of negation in policy rules # Also using interface policy on eth1 to test specific case with negation and # rule shading depection # firewall1:Policy:10: warning: Changing rule direction due to self reference # firewall1:Policy:18: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:38:58 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_5_openbsd-3.fw.orig0000755000175000017500000001735511733011756024141 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:32 2011 PST by vadim # # files: * pf_cluster_5_openbsd-3.fw /etc/pf_cluster_5_openbsd-3.fw # files: pf_cluster_5_openbsd-3.conf /etc/pf_cluster_5_openbsd-3.conf # # Compiled for pf 4.6 # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan100 sync_carp_interfaces carp0 carp1 carp2 sync_pfsync_interfaces update_addresses_of_interface "en0 172.24.0.2/0xffffff00" "" update_addresses_of_interface "en1 192.168.1.2/0xffffff00" "" update_vlans_of_interface "en2 vlan100:100" update_addresses_of_interface "en2" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" update_addresses_of_interface "vlan100 172.20.0.2/0xffffff00" "" $IFCONFIG carp0 vhid 1 carpdev en0 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 1 carpdev en1 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" $IFCONFIG carp2 vhid 1 carpdev vlan100 update_addresses_of_interface "carp2 172.20.0.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:32 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_5_openbsd-3.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall111.fw.orig0000755000175000017500000000424311733011756021715 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:12 2011 PST by vadim # # files: * firewall111.fw /etc/fw/firewall111.fw # files: firewall111.conf /etc/fw/firewall111.conf # files: firewall111-Policy_1.conf /etc/fw/firewall111-Policy_1.conf # # Compiled for pf 4.0 # # testing rules with options tag, classify and route and combinations # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '8 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '9 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '18 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '19 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '20 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '21 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '30 (global)' below it FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:12 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall111.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall10-5.conf.orig0000644000175000017500000000170511733011756022303 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 keep state # # Rule 0 (enc0) # This adds "pass out ... keep state" # rule that compiler 2.1.14 # does not add automatically for pf 3.x # Note that checkbox "add 'keep state'" # is on in options pass out quick on enc0 inet from any to any keep state # # Rule 1 (eth0) pass in quick on eth0 inet proto tcp from 192.168.1.0/24 to any port { 80, 22 } keep state # # Rule 2 (lo0) pass quick on lo0 inet from any to any # # Rule 3 (enc0) # via ipsec pass quick on enc0 inet proto tcp from 33.33.33.0/24 to 192.168.1.0/24 port 80 keep state # # Rule 4 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall10-1.fw.orig0000755000175000017500000000227211733011756021771 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:00 2011 PST by vadim # # files: * firewall10-1.fw /etc/fw/firewall10-1.fw # files: firewall10-1.conf /etc/fw/firewall10-1.conf # # Compiled for pf 3.x # # PF 3.x, testing # "flags S/SA keep state" FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:00 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall10-1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall11.conf.orig0000644000175000017500000000154411733011756022143 0ustar sylvestresylvestre # Tables: (2) table { 192.168.1.10 , 192.168.1.20 } table { 192.168.1.0/24 , 192.168.2.0/24 } # Policy compiler errors and warnings: # firewall11:Policy:0: warning: Changing rule direction due to self reference # firewall11:Policy:1: warning: Changing rule direction due to self reference # # Rule 0 (global) # firewall11:Policy:0: warning: Changing rule direction due to self reference pass in quick inet proto tcp from to self port 22 flags S/SA keep state # # Rule 1 (global) # firewall11:Policy:1: warning: Changing rule direction due to self reference block in quick inet from any to self # # Rule 2 (global) pass quick inet from to any keep state # # Rule 3 (global) block quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall100.conf.orig0000644000175000017500000000101211733011756022210 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall10-6.fw.orig0000755000175000017500000000242011733011756021771 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:07 2011 PST by vadim # # files: * firewall10-6.fw /etc/fw/firewall10-6.fw # files: firewall10-6.conf /etc/fw/firewall10-6.conf # # Compiled for pf 4.0 # # PF 4.x, testing # "flags S/SA keep state" # "Accept tcp sessions opened # prior to restart" is ON # Using "pass all outgoing" FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:07 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall10-6.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_2_freebsd-1.fw.orig0000755000175000017500000001705111733011756024105 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:32 2011 PST by vadim # # files: * pf_cluster_2_freebsd-1.fw /etc/pf_cluster_2_freebsd-1.fw # files: pf_cluster_2_freebsd-1.conf /etc/pf_cluster_2_freebsd-1.conf # # Compiled for pf 4.0 # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_carp_interfaces carp0 carp1 sync_pfsync_interfaces pfsync0 update_addresses_of_interface "en0 172.24.0.2/0xffffff00" "" $IFCONFIG pfsync0 syncdev en0 $IFCONFIG pfsync0 up update_addresses_of_interface "en1 192.168.1.2/0xffffff00" "" $IFCONFIG carp0 vhid 101 pass secret advskew 5 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 100 pass secret advskew 5 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:32 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_2_freebsd-1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall-base-rulesets-web_server_outbound.conf.orig0000644000175000017500000000061511733011756030633 0ustar sylvestresylvestre# # Rule web_server_outbound 0 (global) pass out quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state label "RULE 0 -- ACCEPT " # # Rule web_server_outbound 1 (global) pass out quick inet proto tcp from any to any port 53 keep state label "RULE 1 -- ACCEPT " pass out quick inet proto udp from any to any port 53 keep state label "RULE 1 -- ACCEPT " fwbuilder-5.1.0.3599/test/pf/firewall5.conf.orig0000644000175000017500000000067311733011756022070 0ustar sylvestresylvestre set optimization normal # # Rule 0 (global) block log quick inet from any to any fragment block log quick inet proto 50 from any to any # # Rule 1 (global) block log quick inet from any to any fragment block log quick inet proto tcp from any to any flags ARSF/UAPRSF # # Rule 2 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall39.fw.orig0000755000175000017500000000273211733011756021647 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:20 2011 PST by vadim # # files: * firewall39.fw pf.fw # files: firewall39.conf pf.conf # files: firewall39-rule2_branch.conf /etc/fw/firewall39-rule2_branch.conf # files: firewall39-rule3_branch.conf /etc/fw/firewall39-rule3_branch.conf # files: firewall39-rule5_branch.conf /etc/fw/firewall39-rule5_branch.conf # # Compiled for pf # # testing branching rules # firewall39:rule2_branch:0: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:20 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall10-5.fw.orig0000755000175000017500000000241311733011756021772 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:06 2011 PST by vadim # # files: * firewall10-5.fw /etc/fw/firewall10-5.fw # files: firewall10-5.conf /etc/fw/firewall10-5.conf # # Compiled for pf 3.x # # PF 3.x, testing # "flags S/SA keep state" # "Accept tcp sessions opened # prior to restart" ON # Using "pass all outgoing" FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:06 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall10-5.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall22-NAT_1.conf.orig0000644000175000017500000000017411733011756023003 0ustar sylvestresylvestre# # Rule NAT_1 0 (NAT) nat on en1 from 192.168.1.0/24 to any -> (en1) nat on en0 from 192.168.1.0/24 to any -> (en0) fwbuilder-5.1.0.3599/test/pf/firewall40-2.conf.orig0000644000175000017500000000160111733011756022276 0ustar sylvestresylvestre # # Rule 0 (NAT) # Translate source address # for outgoing connections match out on le1 from 192.168.1.0/24 to any nat-to (le1) # # Rule 1 (NAT) # Translate source address # for outgoing connections match out on le2 from 192.168.1.0/24 to any nat-to (le2) # # Rule 0 (fxp0) pass in quick on fxp0 inet proto tcp from 192.168.1.0/24 to any port { 80, 25 } no state label "RULE 0 -- ACCEPT " route-to { ( le1 192.0.2.10 ) } # # Rule 1 (fxp0) pass in quick on fxp0 inet proto tcp from 192.168.1.0/24 to any port 22 no state label "RULE 1 -- ACCEPT " route-to { ( le2 192.0.3.10 ) } # # Rule 2 (fxp0) pass in quick on fxp0 inet proto tcp from 192.168.1.0/24 to any port 22 flags any label "RULE 2 -- ACCEPT " route-to { ( le2 192.0.3.10 ) } # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/Makefile0000644000175000017500000000072011733011756020021 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_pf -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_pf -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/pf/firewall38.fw.orig0000755000175000017500000000232711733011756021646 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:19 2011 PST by vadim # # files: * firewall38.fw /etc/fw/firewall38.fw # files: firewall38.conf /etc/fw/firewall38.conf # # Compiled for pf # # testing rules with tag service FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:19 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall38.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall110.fw.orig0000755000175000017500000000247411733011756021720 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:11 2011 PST by vadim # # files: * firewall110.fw /etc/fw/firewall110.fw # files: firewall110.conf /etc/fw/firewall110.conf # # Compiled for pf # # testing shadowing of rules with tag action # firewall110:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:11 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall110.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall80-4.5.conf.orig0000644000175000017500000000216711733011756022457 0ustar sylvestresylvestre # # Rule 0 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 no state # # Rule 1 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 keep state # # Rule 2 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 # # Rule 3 (global) # activate source tracking pass quick inet proto tcp from any to 33.33.33.34 port 22 keep state ( max-src-nodes 10 ) # # Rule 4 (global) # modulate state pass quick inet proto tcp from any to 33.33.33.34 port 22 modulate state ( max-src-nodes 10 ) # # Rule 5 (global) # synproxy pass quick inet proto tcp from any to 33.33.33.34 port 22 synproxy state ( max-src-nodes 10 ) # # Rule 6 (global) # keep state, no-sync, pflow pass quick inet proto tcp from any to 33.33.33.34 port 22 keep state ( no-sync, pflow, max-src-nodes 10 ) # # Rule 7 (global) pass quick inet from any to 33.33.33.34 # # Rule 8 (global) # synproxy pass quick inet from any to any # # Rule 9 (global) block log quick inet from any to any no state # # Rule fallback rule # fallback rule block quick inet from any to any no state fwbuilder-5.1.0.3599/test/pf/firewall6.fw.orig0000755000175000017500000000237011733011756021557 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:24 2011 PST by vadim # # files: * firewall6.fw /etc/fw/firewall6.fw # files: firewall6.conf /etc/fw/firewall6.conf # # Compiled for pf # # testing rule with firewall in dst and negation # firewall6:Policy:1: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:24 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall6.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall14.fw.orig0000755000175000017500000001361011733011756021635 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:14 2011 PST by vadim # # files: * firewall14.fw /etc/firewall14.fw # files: firewall14.conf /etc/firewall14.conf # # Compiled for pf 4.0 # # Testing scrub rules format PF < 4.6 FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan101 vlan103 update_vlans_of_interface "em0 vlan101:101 vlan103:103" update_addresses_of_interface "em0 10.1.1.50/0xffffff00" "" update_addresses_of_interface "pcn0 10.3.14.50/0xffffff00" "" update_addresses_of_interface "vlan101 10.100.101.1/0xffffff00" "" update_addresses_of_interface "vlan103 10.100.103.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:14 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall14.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall2-6.fw.orig0000755000175000017500000000762311733011756021724 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:17 2011 PST by vadim # # files: * firewall2-6.fw /etc/firewall2-6.fw # files: firewall2-6.conf /etc/firewall2-6.conf # # Compiled for pf # # tests for nat rules with inbound and outbound interfaces FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "em0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "em1 222.222.222.222/0xffffff00 222.222.222.40/0xffffff00" "" update_addresses_of_interface "em2 33.33.33.3/0xfffffff8 33.33.33.4/0xfffffff8" "" update_addresses_of_interface "em3 33.33.33.25/0xfffffff8" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:17 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall2-6.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall-ipv6-1.conf.orig0000644000175000017500000001046711733011756023025 0ustar sylvestresylvestre # Tables: (2) table { 2001:5c0:0:2::24 , 3ffe:1200:2000::/36 , 3ffe:1200:2001:1:8000::1 } table { 2001:5c0:0:2::24 , 3ffe:1200:2001:1:8000::1 } # Policy compiler errors and warnings: # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '7 (global)' below it # firewall-ipv6-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-1:Policy:3: warning: Changing rule direction due to self reference # firewall-ipv6-1:Policy:6: warning: Changing rule direction due to self reference # firewall-ipv6-1:Policy:7: warning: Changing rule direction due to self reference # # Rule 0 (lo) pass quick on lo inet6 from any to any keep state label "RULE 0 -- ACCEPT " # # Rule 1 (global) # this rule shadows the next. # Note that we add command line # flag -xt to the compiler pass quick inet6 proto tcp from fe80::/64 to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 1 -- ACCEPT " # # Rule 2 (global) # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it pass quick inet6 proto tcp from 2001:5c0:0:2::24 to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 2 -- ACCEPT " # # Rule 3 (global) # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '7 (global)' below it # firewall-ipv6-1:Policy:3: warning: Changing rule direction due to self reference pass in log quick inet6 proto tcp from 3ffe:1200:2001:1:8000::1 to self port 22 keep state label "RULE 3 -- ACCEPT " # # Rule 4 (global) # firewall-ipv6-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it pass log quick inet6 proto tcp from to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 4 -- ACCEPT " # # Rule 5 (global) pass log quick inet6 proto tcp from to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 5 -- ACCEPT " # # Rule 6 (global) # firewall-ipv6-1:Policy:6: warning: Changing rule direction due to self reference pass in log quick inet6 proto tcp from to self port 22 keep state label "RULE 6 -- ACCEPT " # # Rule 7 (global) # firewall-ipv6-1:Policy:7: warning: Changing rule direction due to self reference pass in log quick inet6 proto tcp from to self port 22 keep state label "RULE 7 -- ACCEPT " # # Rule 8 (global) pass in log quick inet6 from any to self keep state label "RULE 8 -- ACCEPT " # # Rule 9 (global) pass log quick inet6 from fe80::/64 to any keep state label "RULE 9 -- ACCEPT " # # Rule 10 (global) # firewall-ipv6-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it pass log quick inet6 from to any keep state label "RULE 10 -- ACCEPT " # # Rule 11 (global) pass log quick inet6 from to any keep state label "RULE 11 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet6 from any to any label "RULE 10000 -- DROP " load anchor Policy_ipv4 from "/etc/firewall-ipv6-1-Policy_ipv4.conf" fwbuilder-5.1.0.3599/test/pf/pf_cluster_2_freebsd-1.conf.orig0000644000175000017500000000107211733011756024407 0ustar sylvestresylvestre # # Rule -3 pfsync (automatic) pass quick on en0 inet proto pfsync from any to any label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/pf_cluster_1_openbsd-1.fw.orig0000755000175000017500000001712511733011756024126 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:31 2011 PST by vadim # # files: * pf_cluster_1_openbsd-1.fw /etc/pf_cluster_1_openbsd-1.fw # files: pf_cluster_1_openbsd-1.conf /etc/pf_cluster_1_openbsd-1.conf # # Compiled for pf 4.x # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_carp_interfaces carp0 carp1 sync_pfsync_interfaces pfsync0 update_addresses_of_interface "en0 172.24.0.2/0xffffff00 172.24.0.3/0xffffff00" "" $IFCONFIG pfsync0 syncdev en0 syncpeer 172.24.0.3 $IFCONFIG pfsync0 up update_addresses_of_interface "en1 192.168.1.2/0xffffff00" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" $IFCONFIG carp0 vhid 101 pass secret carpdev en0 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 100 pass secret carpdev en1 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:31 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_1_openbsd-1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall108.conf.orig0000644000175000017500000000101211733011756022220 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall-base-rulesets-mail_server_inbound.conf.orig0000644000175000017500000000045411733011756030600 0ustar sylvestresylvestre# # Rule mail_server_inbound 0 (global) pass in quick inet proto tcp from any to any port 25 keep state label "RULE 0 -- ACCEPT " # # Rule mail_server_inbound 1 (global) pass in quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state label "RULE 1 -- ACCEPT " fwbuilder-5.1.0.3599/test/pf/firewall7.conf.orig0000644000175000017500000000041311733011756022062 0ustar sylvestresylvestre # # Rule 0 (eth0) block in log quick on eth0 inet from any to 192.168.1.255 # # Rule 1 (global) pass quick inet proto udp from any to 192.168.1.255 port 68 keep state # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall40.fw.orig0000755000175000017500000000727511733011756021646 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:21 2011 PST by vadim # # files: * firewall40.fw /etc/firewall40.fw # files: firewall40.conf /etc/firewall40.conf # # Compiled for pf # # testing Route action FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "fxp0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "le1 192.0.2.1/0xffffff00" "" update_addresses_of_interface "le2 192.0.3.1/0xffffff00" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:21 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall40.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall10-2.conf.orig0000644000175000017500000000142111733011756022273 0ustar sylvestresylvestre set skip on lo0 # # Scrub rules # scrub in all fragment reassemble # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 modulate state # # Rule 0 (eth0) pass in quick on eth0 inet proto tcp from 192.168.1.0/24 to any port { 80, 22 } modulate state # # Rule 1 (lo0) pass quick on lo0 inet from any to any no state # # Rule 2 (enc0) # via ipsec pass quick on enc0 inet proto tcp from 33.33.33.0/24 to 192.168.1.0/24 port 80 keep state modulate state # # Rule 3 (global) block log quick inet from any to any no state # # Rule fallback rule # fallback rule block quick inet from any to any no state fwbuilder-5.1.0.3599/test/pf/firewall109-2.conf.orig0000644000175000017500000000101211733011756022360 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall-base-rulesets-web_server_inbound.conf.orig0000644000175000017500000000045211733011756030431 0ustar sylvestresylvestre# # Rule web_server_inbound 0 (global) pass in quick inet proto tcp from any to any port 80 keep state label "RULE 0 -- ACCEPT " # # Rule web_server_inbound 1 (global) pass in quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state label "RULE 1 -- ACCEPT " fwbuilder-5.1.0.3599/test/pf/firewall22.conf.orig0000644000175000017500000000151711733011756022145 0ustar sylvestresylvestre set state-policy if-bound # # Scrub rules # scrub in all fragment reassemble # NAT compiler errors and warnings: # firewall22:NAT:2: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' # # Rule 0 (NAT) nat-anchor "ftp-proxy/*" rdr-anchor "ftp-proxy/*" # # Rule 1 (NAT) nat-anchor "NAT_1" from 192.168.1.0/24 to any rdr-anchor "NAT_1" from 192.168.1.0/24 to any # # Rule 2 (NAT) # firewall22:NAT:2: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' nat-anchor "NAT_1" from 192.168.1.0/24 to any rdr-anchor "NAT_1" from 192.168.1.0/24 to any # # Rule 0 (global) block log quick inet from any to any no state # # Rule fallback rule # fallback rule block quick inet from any to any no state load anchor NAT_1 from "/etc/fw/firewall22-NAT_1.conf" fwbuilder-5.1.0.3599/test/pf/run.all0000755000175000017500000000076311733011756017671 0ustar sylvestresylvestre#!/bin/sh XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_pf -v -f $XMLFILE -xt $fwobj" done XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_pf -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/pf/firewall102.conf.orig0000644000175000017500000000101211733011756022212 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/pf_cluster_2_freebsd-2.fw.orig0000755000175000017500000001137511733011756024111 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:32 2011 PST by vadim # # files: * pf_cluster_2_freebsd-2.fw /etc/pf_cluster_2_freebsd-2.fw # files: pf_cluster_2_freebsd-2.conf /etc/pf_cluster_2_freebsd-2.conf # # Compiled for pf 4.0 # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_carp_interfaces carp0 carp1 update_addresses_of_interface "en0 172.24.0.3/0xffffff00" "" update_addresses_of_interface "en1 192.168.1.3/0xffffff00" "" $IFCONFIG carp0 vhid 101 pass secret advskew 10 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 100 pass secret advskew 10 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:32 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_2_freebsd-2.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_5_openbsd-4.conf.orig0000644000175000017500000000116511733011756024440 0ustar sylvestresylvestre # # Rule 0 (NAT) # rule is attached to physical interface en0 # but uses address of carp0 for translation nat on en0 from 192.168.1.0/24 to any -> (carp0) # # Rule -3 CARP (automatic) pass quick on vlan100 inet proto carp from any to any label "RULE -4 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -3 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE -1 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall9.conf.orig0000644000175000017500000000073111733011756022067 0ustar sylvestresylvestre # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule 0 (eth0) block in log quick on eth0 inet from any to 192.168.1.255 # # Rule 1 (lo) pass quick on lo inet from any to any keep state # # Rule 3 (global) pass quick inet proto udp from any to 192.168.1.255 port 68 keep state # # Rule 4 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall.fw.orig0000755000175000017500000001035111733011756021467 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:38:57 2011 PST by vadim # # files: * firewall.fw /etc/pf.fw # files: firewall.conf /etc/pf.conf # # Compiled for pf # # this is simple firewall with two interfaces. Test regular policy rules, including IP_fragments rule # firewall:Policy:18: error: Rule '18 (global)' shadows rule '21 (global)' below it # firewall:Policy:20: error: Rule '20 (global)' shadows rule '22 (global)' below it # firewall:Policy:20: error: Rule '20 (global)' shadows rule '23 (global)' below it # firewall:Policy:3: warning: Changing rule direction due to self reference # firewall:Policy:18: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.directed-broadcast=0 $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet.ip.sourceroute=0 $SYSCTL -w net.inet.ip.redirect=0 } prolog_commands() { : echo 'This is prolog script' } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "eth1 222.222.222.222/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:38:57 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall62.conf.orig0000644000175000017500000001201111733011756022140 0ustar sylvestresylvestre # Policy compiler errors and warnings: # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '10 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '10 (global)' below it # firewall62:Policy:1: warning: Changing rule direction due to self reference # firewall62:Policy:2: warning: Changing rule direction due to self reference # firewall62:Policy:4: warning: Changing rule direction due to self reference # firewall62:Policy:8: warning: Changing rule direction due to self reference # firewall62:Policy:9: warning: Changing rule direction due to self reference # firewall62:Policy:12: warning: Changing rule direction due to self reference # # Rule 0 (en0) # rule from FR 1948872 # should generate # pass in quick on en0 user proxy pass in quick on en0 inet from any to any user proxy label "RULE 0 -- ACCEPT " # # Rule 1 (global) # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it # firewall62:Policy:1: warning: Changing rule direction due to self reference pass out quick inet from self to any user { 2000, 500 } label "RULE 1 -- ACCEPT " # # Rule 2 (global) # firewall62:Policy:2: warning: Changing rule direction due to self reference pass out quick inet from self to any user 2000 label "RULE 2 -- ACCEPT " # # Rule 3 (global) # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it pass out quick inet proto tcp from self to any port 80 flags any label "RULE 3 -- ACCEPT " pass out quick inet from self to any user 2000 label "RULE 3 -- ACCEPT " # # Rule 4 (global) # firewall62:Policy:4: warning: Changing rule direction due to self reference pass out quick inet proto tcp from self to any port 80 flags any label "RULE 4 -- ACCEPT " pass out quick inet from self to any user 2000 label "RULE 4 -- ACCEPT " # # Rule 5 (global) pass out quick inet proto tcp from self to any port 80 flags any label "RULE 5 -- ACCEPT " pass out quick inet from self to any user 2000 label "RULE 5 -- ACCEPT " # # Rule 6 (global) pass quick inet from 192.168.1.1 to any user 2000 label "RULE 6 -- ACCEPT " # # Rule 7 (global) pass quick inet from 192.168.1.0/24 to any user 2000 label "RULE 7 -- ACCEPT " # # Rule 8 (global) # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '10 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall62:Policy:8: warning: Changing rule direction due to self reference pass in quick inet from any to self user 2000 label "RULE 8 -- ACCEPT " # # Rule 9 (global) # firewall62:Policy:9: warning: Changing rule direction due to self reference pass in quick inet from any to self user { 2000, 500 } label "RULE 9 -- ACCEPT " # # Rule 10 (global) pass in quick inet from any to self user 2000 label "RULE 10 -- ACCEPT " # # Rule 11 (global) pass quick inet from ! 192.168.1.0/24 to any user 2000 label "RULE 11 -- ACCEPT " # # Rule 12 (global) # firewall62:Policy:12: warning: Changing rule direction due to self reference pass in quick inet from any to ! self user 2000 label "RULE 12 -- ACCEPT " # # Rule 13 (global) block quick inet from any to any no state label "RULE 13 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall39-rule3_branch.conf.orig0000644000175000017500000000054411733011756024521 0ustar sylvestresylvestre # Tables: (1) table { 192.168.1.11 , 192.168.1.12 } # # Rule rule3_branch 0 (global) pass in quick inet from any to 192.168.1.10 keep state # # Rule rule3_branch 1 (global) pass quick inet from any to ! keep state # # Rule rule3_branch 2 (global) block log quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall-ipv6-3.conf.orig0000644000175000017500000000044011733011756023015 0ustar sylvestresylvestre # # Rule 0 (lo0) pass quick on lo0 inet6 from any to any keep state label "RULE 0 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet6 from any to any label "RULE 10000 -- DROP " load anchor Policy_ipv4 from "/etc/firewall-ipv6-3-Policy_ipv4.conf" fwbuilder-5.1.0.3599/test/pf/firewall5.fw.orig0000755000175000017500000000247711733011756021566 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:23 2011 PST by vadim # # files: * firewall5.fw /etc/fw/firewall5.fw # files: firewall5.conf /etc/fw/firewall5.conf # # Compiled for pf # # testing IP fragments and scrub FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.directed-broadcast=0 $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet.ip.sourceroute=0 $SYSCTL -w net.inet.ip.redirect=0 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:23 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall5.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall12.conf.orig0000644000175000017500000000404011733011756022136 0ustar sylvestresylvestre # Tables: (1) table { 22.22.22.22 , 22.22.23.22 } # # Rule 4 (NAT) rdr proto tcp from any to port 80 -> 127.0.0.1 port 8080 # # Rule 7 (NAT) nat on en0 proto udp from any port 6767 to any -> (en0) port 67 nat on en1 proto udp from any port 6767 to any -> (en1) port 67 # # Rule 9 (NAT) rdr proto tcp from any to any port 80 -> 127.0.0.1 port 8080 # # Rule 10 (NAT) # SDNAT rdr proto tcp from any to port 22 -> 192.168.1.10 port 22 nat on en0 proto tcp from any to 192.168.1.10 port 22 -> (en0) nat on en1 proto tcp from any to 192.168.1.10 port 22 -> (en1) # # Rule 11 (NAT) # SDNAT with source port rdr proto udp from any port 123 to -> 192.168.1.10 nat on en0 proto udp from any port 123 to 192.168.1.10 -> (en0) port 5050 nat on en1 proto udp from any port 123 to 192.168.1.10 -> (en1) port 5050 # # Rule 12 (NAT) # SDNAT with dest port rdr proto udp from 192.168.1.0/24 to any port 53 -> 192.168.1.10 port 1053 nat on en0 proto udp from 192.168.1.0/24 to 192.168.1.10 port 1053 -> (en0) nat on en1 proto udp from 192.168.1.0/24 to 192.168.1.10 port 1053 -> (en1) # # Rule 13 (NAT) # SDNAT # translate src and dst addresses # and src and dst ports rdr proto udp from 192.168.1.0/24 port 1024:65535 to any port 53 -> 192.168.1.10 port 1053 nat on en0 proto udp from 192.168.1.0/24 to 192.168.1.10 port 1053 -> (en0) port 32767:* nat on en1 proto udp from 192.168.1.0/24 to 192.168.1.10 port 1053 -> (en1) port 32767:* # # Rule 14 (NAT) # Matches destination port, translates source port nat on en0 proto udp from 192.168.1.0/24 to any port 53 -> (en0) port 5050 nat on en1 proto udp from 192.168.1.0/24 to any port 53 -> (en1) port 5050 # # Rule 0 (global) pass quick inet proto tcp from any to 22.22.22.23 port 8080 flags any label "RULE 0 -- ACCEPT " # # Rule 1 (global) block log quick inet from any to any no state label "RULE 1 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall8.conf.orig0000644000175000017500000000307611733011756022073 0ustar sylvestresylvestre # Tables: (2) table { ppp0 , 33.33.33.33 , 33.33.33.34 , 192.168.1.1 } table { 33.33.33.33 , 33.33.33.34 } # # Rule 0 (NAT) nat on eth1 from 192.168.1.0/24 to any -> (eth1) nat on eth0 from 192.168.1.0/24 to any -> (eth0) nat on ppp0 from 192.168.1.0/24 to any -> (ppp0) # # Rule 1 (NAT) nat on eth1 from 192.168.1.0/24 to any -> (eth1) # # Rule 2 (NAT) nat on eth1 from 192.168.1.0/24 to any -> 33.33.33.33 # # Rule 3 (NAT) rdr proto tcp from any to port 22 -> 192.168.1.100 port 22 # # Rule 4 (NAT) rdr on eth1 proto tcp from any to 33.33.33.34 port 22 -> 192.168.1.100 port 22 # # Rule 5 (NAT) rdr on eth1 proto tcp from any to 33.33.33.34 port 22 -> 192.168.1.100 port 22 # # Rule 6 (NAT) rdr on eth1 proto tcp from any to 33.33.33.34 port 22 -> 192.168.1.100 port 22 # # Rule 7 (NAT) rdr on eth1 proto tcp from any to 33.33.33.34 port 22 -> 192.168.1.100 port 22 # # Rule 8 (NAT) rdr proto tcp from 192.168.1.0/24 to any port 80 -> (eth1) port 80 # # Rule 0 (global) pass inet from any to any # # Rule 1 (global) pass log inet from any to any # # Rule 2 (global) pass quick inet proto tcp from any to 33.33.33.33 port 22 flags S/SA keep state # # Rule 3 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 flags S/SA keep state # # Rule 4 (global) pass quick inet proto tcp from any to port 22 flags S/SA keep state # # Rule 5 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/do-diff0000755000175000017500000000023311733011756017616 0ustar sylvestresylvestre#!/bin/sh N=$1 if which opendiff > /dev/null; then TOOL="opendiff" else TOOL="tkdiff -b -B " fi ${TOOL} firewall${N}.conf.orig firewall${N}.conf fwbuilder-5.1.0.3599/test/pf/firewall63.conf.orig0000644000175000017500000000065011733011756022147 0ustar sylvestresylvestre # # Rule 0 (global) block log quick inet from any to any tos 0x20 # # Rule 1 (global) block log quick inet from any to any tos 0x10 # # Rule 2 (global) block log quick inet from any to any tos 0x10 block log quick inet from any to any tos 0x20 # # Rule 4 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall103-1.conf.orig0000644000175000017500000000101211733011756022351 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/addr-table-1.tbl0000644000175000017500000000030411733011756021217 0ustar sylvestresylvestre# this is a comment # ; this should be a comment too ; 192.168.1.1 192.168.1.2/32 192.168.1.3/30 192.168.2.128/25 192.168.1.200/32 # comment again 192.168.1.201/32 # this should work, too fwbuilder-5.1.0.3599/test/pf/firewall10-4.conf.orig0000644000175000017500000000140211733011756022274 0ustar sylvestresylvestre set skip on lo0 # # Scrub rules # scrub in all fragment reassemble # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 flags any # # Rule 0 (eth0) pass in quick on eth0 inet proto tcp from 192.168.1.0/24 to any port { 80, 22 } flags any # # Rule 1 (lo0) pass quick on lo0 inet from any to any no state # # Rule 2 (enc0) # via ipsec pass quick on enc0 inet proto tcp from 33.33.33.0/24 to 192.168.1.0/24 port 80 flags any keep state # # Rule 3 (global) block log quick inet from any to any no state # # Rule fallback rule # fallback rule block quick inet from any to any no state fwbuilder-5.1.0.3599/test/pf/firewall102.fw.orig0000755000175000017500000000231611733011756021714 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:01 2011 PST by vadim # # files: * firewall102.fw /etc/fw/pf.fw # files: firewall102.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # routing rules, rc.conf format # firewall102:Routing:1: error: Gateway and interface are both empty in the rule # firewall102:Routing:1: error: Rules 0 (main) and 1 (main) define routes to the same destination 0.0.0.0/0.0.0.0 via different gateways. This configuration is not supported for freebsd # firewall102:Routing:4: warning: Two of the routing commands created from the gui routing rules 3 (main) and 4 (main) are identical, skipping the second. Revise them to avoid this warning gateway_enable="YES" network_interfaces="em0 em1" ifconfig_em0="10.3.14.81 netmask 0xffffff00 mtu 1490 " ifconfig_em1="10.1.1.81 netmask 0xffffff00" pf_enable="YES" pf_rules="/etc/fw/path\ with\ space/pf.conf" static_routes="route_0 route_1 route_2 route_3 route_4" route_route_0="default 10.1.1.1 " route_route_1="default " route_route_2="192.168.171.2 10.1.1.1 " route_route_3="22.22.22.0/24 10.1.1.1 " route_route_4="33.33.33.0/24 10.1.1.1 " fwbuilder-5.1.0.3599/test/pf/quick-cmp.sh0000755000175000017500000000062611733011756020616 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -B -w -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_pf v' -I 'Can not find file' -I '====' -I 'log '" for f in $(ls *.fw.orig *rc.conf*.orig *.conf.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done fwbuilder-5.1.0.3599/test/pf/firewall51-mail_server_outbound.conf.orig0000644000175000017500000000050311733011756026366 0ustar sylvestresylvestre# # Rule mail_server_outbound 0 (global) pass out quick inet proto tcp from any to any port { 53, 25 } keep state pass out quick inet proto udp from any to any port 53 keep state # # Rule mail_server_outbound 1 (global) pass out quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state fwbuilder-5.1.0.3599/test/pf/firewall109-3.conf.orig0000644000175000017500000000101211733011756022361 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/pf_cluster_1_openbsd-1.conf.orig0000644000175000017500000000365711733011756024441 0ustar sylvestresylvestre # Tables: (2) table { 172.24.0.1 , 172.24.0.2 , 192.168.1.1 , 192.168.1.2 } table { 172.24.0.1 , 172.24.0.2 } # # Rule 0 (NAT) nat on en0 from 192.168.1.0/24 to any -> (carp0) # # Rule 1 (NAT) nat on en0 from 192.168.1.0/24 to any -> 172.24.0.1 # # Rule 2 (NAT) nat from 192.168.1.0/24 to any -> 172.24.0.1 # # Rule 3 (NAT) nat on en0 from 192.168.1.0/24 to any -> { (en0) , (en0) } # # Rule 4 (NAT) nat on en0 from 192.168.1.0/24 to any -> (en0) # # Rule 5 (NAT) nat from 192.168.1.0/24 to any -> (en0) # # Rule 6 (NAT) rdr on en0 proto tcp from any to 172.24.0.1 port 80 -> 172.24.0.100 port 80 # # Rule 7 (NAT) rdr on en0 proto tcp from any to 172.24.0.1 port 80 -> 172.24.0.100 port 80 # # Rule 8 (NAT) rdr proto tcp from any to 172.24.0.1 port 80 -> 172.24.0.100 port 80 # # Rule -3 pfsync (automatic) pass quick on en0 inet proto pfsync from any to any label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -1 -- ACCEPT " # # Rule 0 (lo0) pass quick on lo0 inet from any to any label "RULE 0 -- ACCEPT " # # Rule 1 (global) pass quick inet from any to label "RULE 1 -- ACCEPT " # # Rule 2 (global) pass quick inet from to any label "RULE 2 -- ACCEPT " # # Rule 3 (global) pass quick inet from any to label "RULE 3 -- ACCEPT " # # Rule 4 (carp0) pass in quick on en0 inet from any to any label "RULE 4 -- ACCEPT " # # Rule 5 (carp0) pass in quick on en1 inet from any to any label "RULE 5 -- ACCEPT " # # Rule 6 (global) block log quick inet from any to any no state label "RULE 6 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall10-2.fw.orig0000755000175000017500000000227411733011756021774 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:01 2011 PST by vadim # # files: * firewall10-2.fw /etc/fw/firewall10-2.fw # files: firewall10-2.conf /etc/fw/firewall10-2.conf # # Compiled for pf 4.0 # # PF 4.x, testing # "flags S/SA keep state" FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:01 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall10-2.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall14-1.fw.orig0000755000175000017500000001362011733011756021774 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:14 2011 PST by vadim # # files: * firewall14-1.fw /etc/firewall14-1.fw # files: firewall14-1.conf /etc/firewall14-1.conf # # Compiled for pf 4.6 # # Testing scrub rules format PF 4.6 FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan101 vlan103 update_vlans_of_interface "em0 vlan101:101 vlan103:103" update_addresses_of_interface "em0 10.1.1.50/0xffffff00" "" update_addresses_of_interface "pcn0 10.3.14.50/0xffffff00" "" update_addresses_of_interface "vlan101 10.100.101.1/0xffffff00" "" update_addresses_of_interface "vlan103 10.100.103.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:14 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall14-1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall110.conf.orig0000644000175000017500000000116611733011756022223 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # Policy compiler errors and warnings: # firewall110:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # # Rule 0 (global) # see #1867 this rule is non-terminating and should not shadow next pass inet from any to any tag tag2 # # Rule 1 (global) # firewall110:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it pass quick inet from any to any keep state queue ssh_q # # Rule 2 (global) pass inet from any to any tag INTNET keep state # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall2-6.conf.orig0000644000175000017500000000303111733011756022217 0ustar sylvestresylvestre # # Rule 0 (NAT) # NETMAP and no -o itf nat from 192.168.1.0/24 to any -> 22.22.22.0/24 # # Rule 1 (NAT) nat on em1 from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 2 (NAT) # nat on em3 from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 3 (NAT) # nat on { em1 em3 } from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 4 (NAT) nat on { em1 em3 } from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 5 (NAT) # nat on ! em3 from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 6 (NAT) # nat on { em0 em2 } from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 7 (NAT) nat on { em0 em2 } from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 8 (NAT) rdr from any to 222.222.222.40 -> 192.168.1.10 # # Rule 9 (NAT) rdr on em0 from any to 222.222.222.40 -> 192.168.1.10 # # Rule 10 (NAT) rdr on { em0 em2 } from any to 222.222.222.40 -> 192.168.1.10 # # Rule 11 (NAT) rdr on { em0 em2 } from any to 222.222.222.40 -> 192.168.1.10 # # Rule 12 (NAT) rdr on ! em0 from any to 222.222.222.40 -> 192.168.1.10 # # Rule 13 (NAT) rdr on { em1 em3 } from any to 222.222.222.40 -> 192.168.1.10 # # Rule 14 (NAT) rdr on { em1 em3 } from any to 222.222.222.40 -> 192.168.1.10 # # Rule 15 (NAT) # REDIRECT rdr on em0 proto tcp from any to any port 80 -> 127.0.0.1 port 3128 # # Rule 0 (global) # 'catch all' rule block log quick inet from any to any label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall39-rule2_branch.conf.orig0000644000175000017500000000056511733011756024523 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall39:rule2_branch:0: warning: Changing rule direction due to self reference # # Rule rule2_branch 0 (global) # firewall39:rule2_branch:0: warning: Changing rule direction due to self reference pass in quick inet from any to self keep state # # Rule rule2_branch 1 (global) block log quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall104.conf.orig0000644000175000017500000000101211733011756022214 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall109.conf.orig0000644000175000017500000000101211733011756022221 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall-base-rulesets-mail_server_outbound.conf.orig0000644000175000017500000000062711733011756031003 0ustar sylvestresylvestre# # Rule mail_server_outbound 0 (global) pass out quick inet proto tcp from any to any port { 53, 25 } keep state label "RULE 0 -- ACCEPT " pass out quick inet proto udp from any to any port 53 keep state label "RULE 0 -- ACCEPT " # # Rule mail_server_outbound 1 (global) pass out quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state label "RULE 1 -- ACCEPT " fwbuilder-5.1.0.3599/test/pf/firewall105.conf.orig0000644000175000017500000000101211733011756022215 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall101.fw.orig0000755000175000017500000001510211733011756021710 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:00 2011 PST by vadim # # files: * firewall101.fw /etc/fw/pf.fw # files: firewall101.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # routing rules, shell script format # firewall101:Routing:1: error: Gateway and interface are both empty in the rule # firewall101:Routing:1: error: Rules 0 (main) and 1 (main) define routes to the same destination 0.0.0.0/0.0.0.0 via different gateways. This configuration is not supported for freebsd # firewall101:Routing:4: warning: Two of the routing commands created from the gui routing rules 3 (main) and 4 (main) are identical, skipping the second. Revise them to avoid this warning FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" $IFCONFIG em0 mtu 1490 update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:00 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 # ============== ROUTING RULES ============== TMPDIRNAME=`mktemp -d /tmp/.fwbuilder.XXXXXXXXXX` || exit 1 TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules netstat -rn -f inet | awk '$3 ~ /S/ && $NF !~ /lo0/ { print $0;}' | \ while read route gw rest; do route delete $route $gw; done # restore old routing rules (IFS=" "; for route_cmd in $oldRoutes; do (IFS=' '; $route_cmd); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 oldRoutes=$(netstat -rn -f inet | awk '/^$|Destination|Routing tables|Internet:/ {next;} {printf "route add %s %s\n",$1,$2;}') echo "Deleting routing rules previously set by user space processes..." netstat -rn -f inet | awk '$3 ~ /S/ { print $0;}' | grep -Ev 'lo0' | \ while read route gw rest; do route delete $route $gw; done echo "Activating routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # setting default via gateway # line 2 comment # route add default 10.1.1.1 || route_command_error "0 (main)" # # Rule 1 (main) # echo "Routing rule 1 (main)" # # empty rule # # firewall101:Routing:1: error: Gateway and interface are both empty in the rule # firewall101:Routing:1: error: Rules 0 (main) and 1 (main) define routes to the same destination 0.0.0.0/0.0.0.0 via different gateways. This configuration is not supported for freebsd route add default || route_command_error "1 (main)" # # Rule 2 (main) # echo "Routing rule 2 (main)" # route add 192.168.171.2 10.1.1.1 || route_command_error "2 (main)" # # Rule 3 (main) # echo "Routing rule 3 (main)" # route add 22.22.22.0/24 10.1.1.1 || route_command_error "3 (main)" # # Rule 4 (main) # echo "Routing rule 4 (main)" # # firewall101:Routing:4: warning: Two of the routing commands created from the gui routing rules 3 (main) and 4 (main) are identical, skipping the second. Revise them to avoid this warning route add 33.33.33.0/24 10.1.1.1 || route_command_error "4 (main)" restore_script_output echo "...done." epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall51-web_server_outbound.conf.orig0000644000175000017500000000047111733011756026225 0ustar sylvestresylvestre# # Rule web_server_outbound 0 (global) pass out quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state # # Rule web_server_outbound 1 (global) pass out quick inet proto tcp from any to any port 53 keep state pass out quick inet proto udp from any to any port 53 keep state fwbuilder-5.1.0.3599/test/pf/firewall34.fw.orig0000755000175000017500000000705311733011756021643 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:19 2011 PST by vadim # # files: * firewall34.fw /etc/fw/firewall34.fw # files: firewall34.conf /etc/fw/firewall34.conf # # Compiled for pf # # testing AddressTable object FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth1 192.168.1.100/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:19 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall34.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall9.fw.orig0000755000175000017500000000233211733011756021560 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:28 2011 PST by vadim # # files: * firewall9.fw /etc/fw/firewall9.fw # files: firewall9.conf /etc/fw/firewall9.conf # # Compiled for pf # # testing rules with broadcasts FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/local/bin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:28 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall9.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall70.conf.orig0000644000175000017500000000333511733011756022150 0ustar sylvestresylvestre # Policy compiler errors and warnings: # firewall70:Policy:0: warning: Changing rule direction due to self reference # firewall70:Policy:1: warning: Changing rule direction due to self reference # firewall70:Policy:2: warning: Changing rule direction due to self reference # firewall70:Policy:3: warning: Changing rule direction due to self reference # firewall70:Policy:4: warning: Changing rule direction due to self reference # firewall70:Policy:5: warning: Changing rule direction due to self reference # # Rule 0 (global) # firewall70:Policy:0: warning: Changing rule direction due to self reference pass in quick inet proto tcp from any to self port 22 flags S/SA keep state # # Rule 1 (en0) # firewall70:Policy:1: warning: Changing rule direction due to self reference pass in quick on en0 inet proto tcp from any to self port 22 flags S/SA keep state # # Rule 2 (en0,en1) # firewall70:Policy:2: warning: Changing rule direction due to self reference pass in quick on { en0 en1 } inet proto tcp from any to self port 22 flags S/SA keep state # # Rule 3 (en2,en0,en1,en3) # firewall70:Policy:3: warning: Changing rule direction due to self reference pass in quick on { en0 en1 en2 en3 } inet proto tcp from any to self port 22 flags S/SA keep state # # Rule 4 (en0) # firewall70:Policy:4: warning: Changing rule direction due to self reference pass in quick on { en1 en2 } inet proto tcp from any to self port 22 flags S/SA keep state # # Rule 5 (en0,en1) # firewall70:Policy:5: warning: Changing rule direction due to self reference pass in quick on en2 inet proto tcp from any to self port 22 flags S/SA keep state # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall106.conf.orig0000644000175000017500000000101211733011756022216 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall51-mail_server_inbound.conf.orig0000644000175000017500000000036411733011756026172 0ustar sylvestresylvestre# # Rule mail_server_inbound 0 (global) pass in quick inet proto tcp from any to any port 25 keep state # # Rule mail_server_inbound 1 (global) pass in quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state fwbuilder-5.1.0.3599/test/pf/firewall104-1.conf.orig0000644000175000017500000000101211733011756022352 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall6.conf.orig0000644000175000017500000000064711733011756022072 0ustar sylvestresylvestre # Policy compiler errors and warnings: # firewall6:Policy:1: warning: Changing rule direction due to self reference # # Rule 0 (eth1) block in log quick on eth1 inet from any to ! self # # Rule 1 (global) # firewall6:Policy:1: warning: Changing rule direction due to self reference block in quick inet from any to ! self # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall80.conf.orig0000644000175000017500000000126511733011756022151 0ustar sylvestresylvestre # # Rule 0 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 # # Rule 1 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 flags S/SA keep state # # Rule 2 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 flags S/SA keep state # # Rule 3 (global) pass quick inet proto tcp from any to 33.33.33.34 port 22 flags S/SA keep state ( max-src-nodes 10 ) # # Rule 4 (global) # synproxy pass quick inet proto tcp from any to 33.33.33.34 port 22 flags S/SA synproxy state # # Rule 5 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall103.conf.orig0000644000175000017500000000101211733011756022213 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall-ipv6-1-Policy_ipv4.conf.orig0000644000175000017500000000016011733011756025211 0ustar sylvestresylvestre# # Rule Policy_ipv4 0 (lo) pass quick on lo inet from any to any keep state label "RULE 0 -- ACCEPT " fwbuilder-5.1.0.3599/test/pf/firewall51.conf.orig0000644000175000017500000000160611733011756022146 0ustar sylvestresylvestre # # Rule 0 (global) anchor "mail_server_inbound" inet from any to 192.168.1.10 # # Rule 1 (global) anchor "mail_server_outbound" inet from 192.168.1.10 to any # # Rule 2 (global) anchor "web_server_inbound" inet from any to 192.168.1.20 # # Rule 3 (global) anchor "web_server_outbound" inet from 192.168.1.20 to any # # Rule 4 (global) anchor "rule2_branch" inet from 192.168.1.0/24 to any # # Rule fallback rule # fallback rule block quick inet from any to any load anchor mail_server_inbound from "/etc/fw/firewall51-mail_server_inbound.conf" load anchor mail_server_outbound from "/etc/fw/firewall51-mail_server_outbound.conf" load anchor rule2_branch from "/etc/fw/firewall51-rule2_branch.conf" load anchor web_server_inbound from "/etc/fw/firewall51-web_server_inbound.conf" load anchor web_server_outbound from "/etc/fw/firewall51-web_server_outbound.conf" fwbuilder-5.1.0.3599/test/pf/firewall111-Policy_1.conf.orig0000644000175000017500000000000011733011756023663 0ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/pf/firewall4.conf.orig0000644000175000017500000000515211733011756022064 0ustar sylvestresylvestre set optimization high-latency # Tables: (3) table { eth1 , 192.168.1.1 , 192.168.2.1 , 222.222.222.222 } table { self , 192.168.1.0/24 } table { 192.168.1.10 , 192.168.1.20 } # # Prolog script # # prolog commands go after table definitions # # End of prolog script # # # Rule 0 (NAT) nat on eth0 from 192.168.1.10 to any -> (eth0) nat on eth1 from 192.168.1.10 to any -> (eth1) nat on eth2 from 192.168.1.10 to any -> (eth2) nat on eth3 from 192.168.1.10 to any -> (eth3) # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth0) nat on eth1 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth1) nat on eth2 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth2) nat on eth3 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth3) # # Rule 2 (NAT) rdr proto tcp from any to port 22 -> 192.168.1.10 port 22 # # Rule 3 (NAT) # SDNAT rule rdr on eth3 proto tcp from 192.168.1.0/24 to 222.222.222.222 port 80 -> 192.168.1.10 port 80 nat on eth0 proto tcp from 192.168.1.0/24 to 192.168.1.10 port 80 -> (eth0) # # Rule 4 (NAT) nat on eth3 from 192.168.1.0/24 to any -> (eth3) # # Rule 5 (NAT) # eth1 is dynamic nat on eth1 proto tcp from 192.168.1.0/24 to any port 22 -> (eth1) # Policy compiler errors and warnings: # firewall4:Policy:6: warning: Changing rule direction due to self reference # # Rule 0 (global) anchor "ftp-proxy/*" inet from any to any # # Rule 1 (global) pass log quick inet proto tcp from any to (eth1) port 22 keep state # # Rule 2 (eth1) block log quick on eth1 inet proto icmp from ! 192.168.2.0/24 to any icmp-type 8 code 0 # # Rule 3 (eth1) # Anti-spoofing rule block in log quick on eth1 inet from self to any block in log quick on eth1 inet from 192.168.1.0/24 to any # # Rule 4 (eth1) # Anti-spoofing rule block out log quick on eth1 inet from ! to any # # Rule 5 (global) # hostF has the same IP address as firewal. pass log quick inet proto icmp from any to 192.168.1.1 icmp-type 8 code 0 keep state # # Rule 6 (global) # firewall4:Policy:6: warning: Changing rule direction due to self reference block in log quick inet proto icmp from ! to self icmp-type 3 # # Rule 7 (global) # testing negation in the policy rule block log quick inet proto icmp from ! to any icmp-type 3 # # Rule 9 (global) # 'masquerading' rule pass quick inet from 192.168.1.0/24 to any keep state # # Rule 10 (global) # 'catch all' rule block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall109-2.fw.orig0000755000175000017500000002454111733011756022066 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:09 2011 PST by vadim # # files: * firewall109-2.fw /etc/fw/pf.fw # files: firewall109-2.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # complex configuration with bridge and vlan, uses vlan interfaces with names not matching vlan IDs FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan8210 vlan9210 sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_vlans_of_interface "em1 vlan9210:210" update_addresses_of_interface "em1" "" update_vlans_of_interface "em2 vlan8210:210" update_addresses_of_interface "em2" "" update_addresses_of_interface "vlan8210" "" update_addresses_of_interface "vlan9210" "" update_bridge_interface bridge0 "vlan8210 vlan9210" $IFCONFIG bridge0 -stp vlan8210 $IFCONFIG bridge0 -stp vlan9210 update_addresses_of_interface "bridge0 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:09 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall103-1.fw.orig0000755000175000017500000002415511733011756022060 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:03 2011 PST by vadim # # files: * firewall103-1.fw /etc/fw/pf.fw # files: firewall103-1.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # bridge interface, static address, shell script format, OpenBSD 4.7 FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" update_addresses_of_interface "em2" "" update_addresses_of_interface "em3" "" update_bridge_interface bridge0 "em2 em3" $IFCONFIG bridge0 -stp em2 $IFCONFIG bridge0 -stp em3 update_addresses_of_interface "bridge0 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:03 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall8.fw.orig0000755000175000017500000000223511733011756021561 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:26 2011 PST by vadim # # files: * firewall8.fw /etc/firewall8.fw # files: firewall8.conf /etc/firewall8.conf # # Compiled for pf # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/sbin/pfctl" SYSCTL="/usr/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:26 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall8.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall38.conf.orig0000644000175000017500000000254611733011756022157 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # # Rule 0 (NAT) nat on le0 from 192.168.1.0/24 to any -> (le0) nat on enc1 from 192.168.1.0/24 to any -> (enc1) # # Rule 1 (NAT) nat on le0 from 192.168.1.0/24 to any tagged ipsec_tag -> (le0) nat on enc1 from 192.168.1.0/24 to any tagged ipsec_tag -> (enc1) # # Rule 0 (le0) pass in on le0 inet from any to any tag INTNET keep state # # Rule 1 (enc1) pass in quick on enc1 inet from any to any keep state # # Rule 2 (enc0) pass out quick on enc0 inet from any to any tagged INTNET keep state # # Rule 3 (enc0) pass out quick on enc0 inet proto tcp from any to any port 80 keep state # # Rule 4 (lo) pass quick on lo inet from any to any keep state # # Rule 5 (global) pass quick inet from any to any tagged ipsec_tag keep state # # Rule 6 (global) pass quick inet from any to any tagged ipsec_tag keep state pass quick inet from any to any tagged tag2 keep state # # Rule 8 (global) pass quick inet proto tcp from any to any port 80 keep state pass quick inet from any to any tagged ipsec_tag keep state # # Rule 10 (global) pass quick inet proto tcp from 192.168.1.0/24 to any port 25 queue mail # # Rule 11 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall10-4.fw.orig0000755000175000017500000000236411733011756021776 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:04 2011 PST by vadim # # files: * firewall10-4.fw /etc/fw/firewall10-4.fw # files: firewall10-4.conf /etc/fw/firewall10-4.conf # # Compiled for pf 4.0 # # PF 4.x, testing # "flags S/SA keep state" # "Accept tcp sessions opened # prior to restart" is ON FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:04 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall10-4.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall-ipv6-3.fw.orig0000755000175000017500000000216311733011756022513 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:31 2011 PST by vadim # # files: * firewall-ipv6-3.fw /etc/firewall-ipv6-3.fw # files: firewall-ipv6-3.conf /etc/firewall-ipv6-3.conf # files: firewall-ipv6-3-Policy_ipv4.conf /etc/firewall-ipv6-3-Policy_ipv4.conf # # Compiled for pf # gateway_enable="YES" ipv6_gateway_enable="YES" cloned_interfaces="vlan100 vlan101" ipv6_network_interfaces="ed0 lo0" network_interfaces="ed0 lo0 vlan100 vlan101" ifconfig_ed0="1.1.1.1 netmask 0xffffff00" ifconfig_ed0="fe80::21d:9ff:fe8b:8e94/64" ifconfig_ed0_alias0="10.10.10.1 netmask 0xffffff00" ifconfig_ed0_alias0="2001:db8::1/64" ifconfig_ed0_alias1="10.10.10.2 netmask 0xffffff00" ifconfig_ed0_alias1="2001:db8::2/64" vlans_ed1="vlan100 vlan101" create_args_vlan100="vlan 100 vlandev ed1" create_args_vlan101="vlan 101 vlandev ed1" ifconfig_lo0="127.0.0.1 netmask 0xff000000" ifconfig_lo0="::1/128" ifconfig_vlan100="172.16.1.1 netmask 0xfffffff0" ifconfig_vlan101="172.16.2.1 netmask 0xfffffff0" pf_enable="YES" pf_rules="/etc/firewall-ipv6-3.conf" fwbuilder-5.1.0.3599/test/pf/firewall100.fw.orig0000755000175000017500000001466011733011756021717 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:38:59 2011 PST by vadim # # files: * firewall100.fw /etc/fw/pf.fw # files: firewall100.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # routing rules # firewall100:Routing:1: error: Gateway and interface are both empty in the rule # firewall100:Routing:1: error: Rules 0 (main) and 1 (main) define routes to the same destination 0.0.0.0/0.0.0.0 via different gateways. This configuration is not supported for openbsd # firewall100:Routing:4: warning: Two of the routing commands created from the gui routing rules 3 (main) and 4 (main) are identical, skipping the second. Revise them to avoid this warning FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" $IFCONFIG em0 mtu 1490 update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:38:59 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 # ============== ROUTING RULES ============== TMPDIRNAME=`mktemp -d /tmp/.fwbuilder.XXXXXXXXXX` || exit 1 TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules route -n show -inet | awk '$3 ~ /S/ && $NF !~ /lo0/ { print $0;}' | \ while read route gw rest; do route delete $route $gw; done # restore old routing rules (IFS=" "; for route_cmd in $oldRoutes; do (IFS=' '; $route_cmd); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 oldRoutes=$(route -n show -inet | awk '{printf "route add %s %s\n",$1,$2;}') echo "Deleting routing rules previously set by user space processes..." route -n show -inet | grep S | grep -Ev 'lo0' | \ while read route gw rest; do route delete $route $gw; done echo "Activating routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # setting default via gateway # line 2 comment # route add default 10.1.1.1 || route_command_error "0 (main)" # # Rule 1 (main) # echo "Routing rule 1 (main)" # # empty rule # # firewall100:Routing:1: error: Gateway and interface are both empty in the rule # firewall100:Routing:1: error: Rules 0 (main) and 1 (main) define routes to the same destination 0.0.0.0/0.0.0.0 via different gateways. This configuration is not supported for openbsd route add default || route_command_error "1 (main)" # # Rule 2 (main) # echo "Routing rule 2 (main)" # route add 192.168.171.2 10.1.1.1 || route_command_error "2 (main)" # # Rule 3 (main) # echo "Routing rule 3 (main)" # route add 22.22.22.0/24 10.1.1.1 || route_command_error "3 (main)" # # Rule 4 (main) # echo "Routing rule 4 (main)" # # firewall100:Routing:4: warning: Two of the routing commands created from the gui routing rules 3 (main) and 4 (main) are identical, skipping the second. Revise them to avoid this warning route add 33.33.33.0/24 10.1.1.1 || route_command_error "4 (main)" restore_script_output echo "...done." epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall93.conf.orig0000644000175000017500000000631211733011756022153 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # Tables: (7) table { 22.22.22.0/28 , 192.168.1.10 } table { 22.22.22.0/28 , 192.168.1.10 } table { 192.168.171.2 } table { 192.168.1.1 , 192.168.1.2 , 192.168.1.3/30 , 192.168.1.200 , 192.168.1.201 , 192.168.2.0/24 , 192.168.2.128/25 } table { 3ffe:1200:2001:1:8000::1 , fe80::/64 } table { 192.168.1.0/24 , 192.168.2.0/24 , ::ffff:0:0:0/96 , fc00::/7 , fe80::/64 } table { 192.168.1.0/24 , 192.168.1.10 } # # Rule 0 (NAT) match out on em0 from 10.1.1.0/24 to any nat-to (em0) # Policy compiler errors and warnings: # firewall93:Policy:0: warning: Changing rule direction due to self reference # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT" # # Rule 0 (global) # firewall93:Policy:0: warning: Changing rule direction due to self reference pass in quick inet proto tcp from 10.3.14.0/24 to self port 22 label "RULE 0 -- ACCEPT" # # Rule 1 (global) pass quick inet from to any label "RULE 1 -- ACCEPT" # # Rule 2 (global) # see #2671 pass quick inet proto tcp from to any port 3128 label "RULE 2 -- ACCEPT" pass quick inet proto udp from to any port 53 label "RULE 2 -- ACCEPT" # # Rule 3 (global) # using the same group second time, # objects should not get duplicated # in the generated table. See #2671 pass quick inet from any to label "RULE 3 -- ACCEPT" # # Rule 4 (global) # just one object in the group pass quick inet from to any label "RULE 4 -- ACCEPT" # # Rule 5 (global) # object a-192.168.1.10 is a member # of at least two groups used in this rule pass quick inet from { , , } to any label "RULE 5 -- ACCEPT" # # Rule 6 (global) # the same rule, same objects as rule 3, # but different group with the same objects pass quick inet from to any label "RULE 6 -- ACCEPT" # # Rule 7 (global) block in quick inet from to any no state label "RULE 7 -- DROP" # # Rule 8 (global) # group uses address table object pass quick inet from any to label "RULE 8 -- ACCEPT" # # Rule 11 (global) block in quick inet from to any no state label "RULE 11 -- DROP" # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP" # # Rule 9 (global) block in quick inet6 from to any no state label "RULE 9 -- DROP" # # Rule 10 (global) # the same group second time, # check for duplicates. See #2671 block in quick inet6 from any to no state label "RULE 10 -- DROP" # # Rule 11 (global) block in quick inet6 from to any no state label "RULE 11 -- DROP" # # Rule fallback rule # fallback rule block quick inet6 from any to any no state label "RULE 10000 -- DROP" fwbuilder-5.1.0.3599/test/pf/firewall-ipv6-1.fw.orig0000755000175000017500000001171111733011756022510 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:30 2011 PST by vadim # # files: * firewall-ipv6-1.fw pf-ipv6.fw # files: firewall-ipv6-1.conf /etc/fw/pf-ipv6.conf # files: firewall-ipv6-1-Policy_ipv4.conf /etc/firewall-ipv6-1-Policy_ipv4.conf # # Compiled for pf # # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall-ipv6-1:Policy:3: error: Rule '3 (global)' shadows rule '7 (global)' below it # firewall-ipv6-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-1:Policy:3: warning: Changing rule direction due to self reference # firewall-ipv6-1:Policy:6: warning: Changing rule direction due to self reference # firewall-ipv6-1:Policy:7: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet6.ip6.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/0xffffff00" "" update_addresses_of_interface "lo ::1/128 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:30 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/pf-ipv6.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall39-rule5_branch.conf.orig0000644000175000017500000000000011733011756024506 0ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/pf/firewall103-2.fw.orig0000755000175000017500000002415511733011756022061 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:03 2011 PST by vadim # # files: * firewall103-2.fw /etc/fw/pf.fw # files: firewall103-2.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.0 # # bridge interface, static address, shell script format, OpenBSD <4.7 FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="brconfig" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" update_addresses_of_interface "em2" "" update_addresses_of_interface "em3" "" update_bridge_interface bridge0 "em2 em3" $IFCONFIG bridge0 -stp em2 $IFCONFIG bridge0 -stp em3 update_addresses_of_interface "bridge0 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:03 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall63.fw.orig0000755000175000017500000000247211733011756021645 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:25 2011 PST by vadim # # files: * firewall63.fw /etc/fw/firewall63.fw # files: firewall63.conf /etc/fw/firewall63.conf # # Compiled for pf # # testing tos matching FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.directed-broadcast=0 $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet.ip.sourceroute=0 $SYSCTL -w net.inet.ip.redirect=0 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:25 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall63.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall108.fw.orig0000755000175000017500000000145511733011756021725 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:08 2011 PST by vadim # # files: * firewall108.fw /etc/fw/pf.fw # files: firewall108.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # vlan interface, static address, rc.conf format gateway_enable="YES" cloned_interfaces="vlan101 vlan102" network_interfaces="em0 em1 vlan101 vlan102" ifconfig_em0="10.3.14.81 netmask 0xffffff00" ifconfig_em1="10.1.1.81 netmask 0xffffff00" vlans_em2="vlan101 vlan102" create_args_vlan101="vlan 101 vlandev em2" create_args_vlan102="vlan 102 vlandev em2" ifconfig_vlan101="192.168.101.1 netmask 0xffffff00" ifconfig_vlan102="192.168.102.1 netmask 0xffffff00" pf_enable="YES" pf_rules="/etc/fw/path\ with\ space/pf.conf" fwbuilder-5.1.0.3599/test/pf/firewall14.conf.orig0000644000175000017500000000075211733011756022146 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble no-df scrub out all random-id min-ttl 64 max-mss 1460 # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall-ipv6-2.fw.orig0000755000175000017500000001220211733011756022505 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:31 2011 PST by vadim # # files: * firewall-ipv6-2.fw pf.fw # files: firewall-ipv6-2.conf pf.conf # # Compiled for pf # # Combined ipv4/ipv6 policy ruleset # firewall-ipv6-2:Policy:5: error: Rule '5 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:5: error: Rule '5 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:7: warning: Changing rule direction due to self reference # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-2:Policy:3: warning: Changing rule direction due to self reference # firewall-ipv6-2:Policy:6: warning: Changing rule direction due to self reference # firewall-ipv6-2:Policy:7: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet6.ip6.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/0xffffff00" "" update_addresses_of_interface "lo ::1/128 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:31 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall3.fw.orig0000755000175000017500000000750011733011756021554 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:18 2011 PST by vadim # # files: * firewall3.fw /etc/firewall3.fw # files: firewall3.conf /etc/firewall3.conf # # Compiled for pf # # testing NAT rules with multiple objects in TSrc and TDst and NAT rule options # firewall3:Policy:0: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "le0 22.22.22.21/0xffffff00 22.22.22.22/0xffffff00 22.22.22.0/0xffffff00 22.22.22.1/0xffffff00" "" update_addresses_of_interface "le1 192.168.1.1/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:18 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall3.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall62.fw.orig0000755000175000017500000001342511733011756021644 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:24 2011 PST by vadim # # files: * firewall62.fw /etc/firewall62.fw # files: firewall62.conf /etc/firewall62.conf # # Compiled for pf 4.0 # # testing rules using UserService object # Note that iptables does not allow entering # iptables command that tries to match using module 'owner' in any chain # other than OUTPUT. This includes user defined chains too (it checks # how control passes to user defined chain and blocks command if # it appears that user defined chain gets control not from OUTPUT) # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall62:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall62:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '10 (global)' below it # firewall62:Policy:8: error: Rule '8 (global)' shadows rule '10 (global)' below it # firewall62:Policy:1: warning: Changing rule direction due to self reference # firewall62:Policy:2: warning: Changing rule direction due to self reference # firewall62:Policy:4: warning: Changing rule direction due to self reference # firewall62:Policy:8: warning: Changing rule direction due to self reference # firewall62:Policy:9: warning: Changing rule direction due to self reference # firewall62:Policy:12: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "en0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "en1 222.222.222.222/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:24 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall62.conf || exit 1 $PFCTL -F states epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall101.conf.orig0000644000175000017500000000101211733011756022211 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/recycle0000755000175000017500000000017211733011756017736 0ustar sylvestresylvestre#!/bin/sh for f in *.fw *rc.conf*; do j=${f}.orig mv $f $j done for f in *.conf; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/pf/firewall10-3.conf.orig0000644000175000017500000000131711733011756022300 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 keep state # # Rule 0 (eth0) pass in quick on eth0 inet proto tcp from 192.168.1.0/24 to any port { 80, 22 } keep state # # Rule 1 (lo0) pass quick on lo0 inet from any to any # # Rule 2 (enc0) # via ipsec pass quick on enc0 inet proto tcp from 33.33.33.0/24 to 192.168.1.0/24 port 80 keep state # # Rule 3 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall20.conf.orig0000644000175000017500000000130611733011756022137 0ustar sylvestresylvestre # # Rule 0 (NAT) nat on dc2 from 192.168.1.0/24 to any -> (dc2) nat on dc0 from 192.168.1.0/24 to any -> (dc0) nat on dc1 from 192.168.1.0/24 to any -> (dc1) # # Rule 1 (NAT) nat on dc1 from 192.168.1.0/24 to any -> (dc1) # # Rule 2 (NAT) nat on dc1 from 192.168.1.0/24 to any -> 222.222.222.20 # # Rule 3 (NAT) nat on dc0 from 192.168.1.0/24 to any -> 222.222.222.40 # # Rule 0 (dc0) pass in quick on dc0 inet from any to 222.222.222.22 keep state # # Rule 1 (dc1) pass out quick on dc1 inet from any to 222.222.222.22 keep state # # Rule 2 (global) block quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall11.fw.orig0000755000175000017500000000302411733011756021630 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:11 2011 PST by vadim # # files: * firewall11.fw /etc/firewall11.fw # files: firewall11.conf /etc/firewall11.conf # # Compiled for pf # # example to illustrate access to the firewall limited to only few # source addresses. Since in PF firewall is always part of "any", # have to explcitly add a rule to block ssh to the firewall # from other sources. # firewall11:Policy:0: warning: Changing rule direction due to self reference # firewall11:Policy:1: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/sbin/pfctl" SYSCTL="/usr/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:11 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall11.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall40-1.fw.orig0000755000175000017500000001221611733011756021773 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:21 2011 PST by vadim # # files: * firewall40-1.fw /etc/firewall40-1.fw # files: firewall40-1.conf /etc/firewall40-1.conf # files: firewall40-1-routes.conf /etc/firewall40-1-routes.conf # # Compiled for pf # # testing Route action # with load balancing # firewall40-1:Policy:9: error: Only one router specified with load balancing for rule action Route: 'route_through' # firewall40-1:Policy:10: error: Only one router specified with load balancing for rule action Route: 'route_through' # firewall40-1:Policy:11: error: Illegal IP address for next hop # firewall40-1:Policy:11: error: Only one router specified with load balancing for rule action Route: 'route_through' # firewall40-1:routes:1: error: Interface specification is required for action Route. # firewall40-1:routes:1: error: Only one router specified with load balancing for rule action Route: 'route_reply_through' # firewall40-1:routes:2: error: Interface specification is required for action Route. # firewall40-1:routes:2: error: Only one router specified with load balancing for rule action Route: 'route_copy_through' # firewall40-1:routes:6: error: Interface specification is required for action Route. # firewall40-1:routes:6: error: More than one router specified without load balancing for rule action Route: 'route_through' # firewall40-1:routes:7: error: Interface specification is required for action Route. # firewall40-1:routes:8: error: Interface specification is required for action Route. # firewall40-1:routes:9: error: Interface specification is required for action Route. # firewall40-1:routes:10: error: Interface specification is required for action Route. FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "fxp0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "le1 192.0.2.1/0xffffff00" "" update_addresses_of_interface "le2 192.0.3.1/0xffffff00" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:21 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall40-1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/run-clusters.all0000755000175000017500000000077311733011756021534 0ustar sylvestresylvestre#!/bin/sh #XMLFILE="objects-for-regression-tests.fwb" #fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ # sort | while read fwobj #do # echo "echo" # echo "echo \"============================ $fwobj\"" # echo "fwb_pf -v -f $XMLFILE -xt $fwobj" #done XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_pf -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/pf/firewall.conf.orig0000644000175000017500000001417611733011756022006 0ustar sylvestresylvestre set limit { frags 4000, states 10000, src-nodes 1000, tables 1000, table-entries 1000000 } set timeout interval 15 set timeout frag 40 set timeout tcp.first 120 set timeout tcp.opening 120 set timeout tcp.established 86400 set timeout tcp.closing 60 set timeout tcp.finwait 60 set timeout tcp.closed 30 set timeout udp.first 10 set timeout udp.single 10 set timeout udp.multiple 10 set timeout icmp.first 10 set timeout icmp.error 10 set timeout other.first 10 set timeout other.single 10 set timeout other.multiple 10 set timeout adaptive.start 6000 set timeout adaptive.end 12000 # # Scrub rules # scrub in all fragment reassemble # Tables: (3) table { 192.168.1.11 , 192.168.1.12/30 } table { 192.168.1.1 , 222.222.222.222 } table { 211.11.11.11 , 211.22.22.22 } # # Rule 0 (NAT) nat on eth1 from 192.168.1.0/24 to any -> (eth1) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule 2 (NAT) rdr proto tcp from any to port 25 -> 192.168.1.10 port 25 # # Rule 3 (NAT) rdr proto tcp from any to any port 80 -> 127.0.0.1 port 3128 # Policy compiler errors and warnings: # firewall:Policy:18: error: Rule '18 (global)' shadows rule '21 (global)' below it # firewall:Policy:20: error: Rule '20 (global)' shadows rule '22 (global)' below it # firewall:Policy:20: error: Rule '20 (global)' shadows rule '23 (global)' below it # firewall:Policy:3: warning: Changing rule direction due to self reference # firewall:Policy:18: warning: Changing rule direction due to self reference # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 flags S/SA modulate state label "RULE -1 - ACCEPT" # # Rule 0 (eth1) block in log quick on eth1 inet from any to self fragment label "RULE 0 - DROP" # # Rule 1 (eth1) # Automatically generated rule blocking short fragments block in log quick on eth1 inet from any to any fragment label "RULE 1 - DROP" # # Rule 2 (eth1) # Automatically generated anti-spoofing rule block in log quick on eth1 inet from self to any label "RULE 2 - DROP" block in log quick on eth1 inet from 192.168.1.0/24 to any label "RULE 2 - DROP" # # Rule 3 (eth0) # аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ, аŸб€аОаВаЕб€баЕаМ аКаОаНаВаЕб€б‚аАб†аИбŽ аВ Utf-8 # firewall:Policy:3: warning: Changing rule direction due to self reference pass in quick on eth0 inet proto udp from 192.168.1.0/24 to self port 53 keep state label "RULE 3 - ACCEPT" # # Rule 4 (eth0) # code should go into INPUT chain with # address in destination for comparison block in log quick on eth0 inet proto udp from any to 192.168.1.255 port 53 label "RULE 4 - DROP" # # Rule 5 (global) block log quick inet proto tcp from any to any flags S/UAPRSF label "** RULE 5" block log quick inet proto tcp from any to any flags ARSF/UAPRSF label "** RULE 5" # # Rule 6 (global) block log quick inet from any to any label "RULE 6 - DROP" # # Rule 9 (global) # this rule is limited to 4 simultaneous # connections by rule options pass quick inet proto tcp from to 192.168.1.10 port 53 flags S/SA modulate state ( max 4 ) label "RULE 9 - ACCEPT" # # Rule 10 (global) pass quick inet proto tcp from 33.33.33.0/24 port 20 to 192.168.1.10 port >= 1024 flags S/SA modulate state label "RULE 10 - ACCEPT" pass quick inet proto tcp from 33.33.33.0/24 to 192.168.1.10 port { 113, 80, 443, 143, 25, 22, 540 } flags S/SA modulate state label "RULE 10 - ACCEPT" # # Rule 11 (global) pass quick inet proto tcp from any to 192.168.1.10 port { 113, 13, 53, 2105, 21, 70, 80, 443, 143, 993, 6667, 6667, 543, 544, 389, 98, 3306, 2049, 119, 110, 5432, 515, 26000, 512, 513, 514, 4321, 25, 465, 1080, 3128, 22, 111, 23, 9999 >< 11001, 540, 7100 } flags S/SA modulate state ( max-src-nodes 10, max-src-states 10, max-src-conn-rate 3/15 ) label "RULE 11 - ACCEPT" # # Rule 12 (global) pass quick inet proto tcp from any to port { 113, 80, 443, 143, 25, 3128, 22, 540 } flags S/SA modulate state ( max 10, max-src-nodes 75, max-src-states 2 ) label "RULE 12 - ACCEPT" # # Rule 14 (global) pass quick inet proto icmp from any to 192.168.1.0/24 icmp-type { 3 , 0 code 0 , 11 code 0 , 11 code 1 } keep state label "RULE 14 - ACCEPT" pass quick inet proto tcp from any to 192.168.1.0/24 port 3128 flags S/SA modulate state label "RULE 14 - ACCEPT" # # Rule 16 (global) pass quick inet from any to 192.168.1.10 keep state label "RULE 16 - ACCEPT" # # Rule 18 (global) # Automatically generated 'masquerading' rule # firewall:Policy:18: error: Rule '18 (global)' shadows rule '21 (global)' below it # firewall:Policy:18: warning: Changing rule direction due to self reference pass out quick inet from self to any keep state label "RULE 18 - ACCEPT" pass quick inet from 192.168.1.0/24 to any keep state label "RULE 18 - ACCEPT" # # Rule 19 (global) # test for bug 1111267: "CustomService should specify protocol and parameters for it" # Should generate "proto { tcp udp icmp gre}" pass quick inet proto {tcp udp icmp gre} from any to any keep state label "RULE 19 - ACCEPT" # # Rule 20 (global) # bug #2791950 "no way to generate "pass out" rule with no interface" # Interface field should be "any", direction "outbound" # firewall:Policy:20: error: Rule '20 (global)' shadows rule '22 (global)' below it # firewall:Policy:20: error: Rule '20 (global)' shadows rule '23 (global)' below it pass out quick inet from any to any keep state label "RULE 20 - ACCEPT" # # Rule 21 (global) # bug #2791950 "no way to generate "pass out" rule with no interface" # pass out quick inet from 192.168.1.0/24 to any keep state label "RULE 21 - ACCEPT" # # Rule 22 (global) # bug #2791950 "no way to generate "pass out" rule with no interface" # pass out quick inet from any to 192.168.1.0/24 keep state label "RULE 22 - ACCEPT" # # Rule 23 (global) # Automatically generated 'catch all' rule block log quick inet from any to any label "RULE 23 - DROP" # # Rule fallback rule # fallback rule block log quick inet from any to any label "RULE 10000 - DROP" fwbuilder-5.1.0.3599/test/pf/firewall10-3.fw.orig0000755000175000017500000000235711733011756021777 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:02 2011 PST by vadim # # files: * firewall10-3.fw /etc/fw/firewall10-3.fw # files: firewall10-3.conf /etc/fw/firewall10-3.conf # # Compiled for pf 3.x # # PF 3.x, testing # "flags S/SA keep state" # "Accept tcp sessions opened # prior to restart" ON FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:02 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall10-3.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall92.fw.orig0000755000175000017500000000751311733011756021650 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:29 2011 PST by vadim # # files: * firewall92.fw /etc/fw/pf.fw # files: firewall92.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # syntax of the nat and rdr rules has changed in 4.7 # firewall92:NAT:2: error: No translation rules are not supported for PF 4.7, use negation to implement exclusions # firewall92:Policy:0: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "em0 10.3.14.81/0xffffff00 10.3.14.201/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:29 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall2-1.fw.orig0000755000175000017500000000504411733011756021712 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:16 2011 PST by vadim # # files: * firewall2-1.fw /etc/fw/firewall2-1.fw # files: firewall2-1.conf /etc/fw/firewall2-1.conf # # Compiled for pf # # testing different errors in NATCompiler_pf::VerifyRules # firewall2-1:NAT:17: warning: Rule branches to rule set NAT which branches back to it, creating a loop # firewall2-1:NAT:1: error: Negation in original service is not supported. # firewall2-1:NAT:2: error: Can not translate 'any' into a specific service. # firewall2-1:NAT:3: error: Can not use negation in translated source. # firewall2-1:NAT:4: error: Can not use negation in translated destination. # firewall2-1:NAT:5: error: Can not use negation in translated service. # firewall2-1:NAT:6: error: Translated service should be 'Original' or should contain single object. # firewall2-1:NAT:7: error: Translated service should be 'Original' or should contain single object. # firewall2-1:NAT:9: error: Can not use unnumbered interface in Translated Source of a Source translation rule. # firewall2-1:NAT:12: error: Can not use network or address range object in translated destination. # firewall2-1:NAT:13: error: Can not use network or address range object in translated destination. # firewall2-1:NAT:15: error: Can not use network or address range object in translated destination. # firewall2-1:NAT:16: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' # firewall2-1:NAT:16: error: Action 'Branch' needs NAT rule set to point to # firewall2-1:NAT:17: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:16 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall2-1.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall107.conf.orig0000644000175000017500000000101211733011756022217 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall4.fw.orig0000755000175000017500000000303311733011756021552 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:20 2011 PST by vadim # # files: * firewall4.fw pf.fw # files: firewall4.conf /etc/fw/pf.conf # # Compiled for pf # # this object is used to test a configuration where firewall has dynamic address # firewall4::: error: Dynamic interface eth1 should not have an IP address object attached to it. This IP address object will be ignored. # firewall4:ftp-proxy/*:: warning: The name of the Policy ruleset ftp-proxy/* ends with '/*', assuming it is externally controlled and skipping it. # firewall4:Policy:6: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:20 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_3_openbsd-4.fw.orig0000755000175000017500000001174311733011756024133 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:32 2011 PST by vadim # # files: * pf_cluster_3_openbsd-4.fw /etc/pf_cluster_3_openbsd-4.fw # files: pf_cluster_3_openbsd-4.conf /etc/pf_cluster_3_openbsd-4.conf # # Compiled for pf 4.6 # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_carp_interfaces carp0 carp1 carp2 update_addresses_of_interface "en0 172.24.0.3/0xffffff00" "" update_addresses_of_interface "en1 192.168.1.3/0xffffff00" "" update_addresses_of_interface "en2" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" update_addresses_of_interface "vlan100 172.20.0.3/0xffffff00" "" $IFCONFIG carp0 vhid 1 advskew 1 carpdev en0 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 1 advskew 1 carpdev en1 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" $IFCONFIG carp2 vhid 1 advskew 1 carpdev vlan100 update_addresses_of_interface "carp2 172.20.0.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:32 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_3_openbsd-4.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall12.fw.orig0000755000175000017500000000724211733011756021637 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:13 2011 PST by vadim # # files: * firewall12.fw /etc/fw/firewall12.fw # files: firewall12.conf /etc/fw/firewall12.conf # # Compiled for pf 4.0 # # This firewall does not do NAT for addresses, but translates port for a server FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "en0 22.22.22.22/0xffffff00" "" update_addresses_of_interface "en1 22.22.23.22/0xffffff00" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:13 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall12.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall39.conf.orig0000644000175000017500000000334311733011756022154 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # # Rule 0 (NAT) nat on le0 from 192.168.1.0/24 to any -> (le0) nat on enc1 from 192.168.1.0/24 to any -> (enc1) # # Rule 1 (NAT) nat on le0 from 192.168.1.0/24 to any tagged ipsec_tag -> (le0) nat on enc1 from 192.168.1.0/24 to any tagged ipsec_tag -> (enc1) # # Rule 0 (le0) pass in on le0 inet from any to any tag INTNET keep state # # Rule 1 (enc1) pass in quick on enc1 inet from any to any keep state # # Rule 2 (enc0) # logging is not allowed with 'anchor' # compiler should not generate 'log' keyword anchor "rule2_branch" in on enc0 inet proto 50 from any to any anchor "rule2_branch" in on enc0 inet proto 51 from any to any # # Rule 3 (enc0) anchor "rule3_branch" in on enc0 inet proto tcp from any to any port 80 # # Rule 4 (lo) pass quick on lo inet from any to any keep state # # Rule 5 (global) anchor "rule5_branch" inet proto 50 from any to any anchor "rule5_branch" inet proto 51 from any to any # # Rule 6 (global) pass quick inet proto 50 from any to any keep state pass quick inet proto 51 from any to any keep state # # Rule 7 (global) pass quick inet proto tcp from any to any port 80 keep state pass quick inet from any to any tagged ipsec_tag keep state # # Rule 9 (global) pass quick inet proto tcp from 192.168.1.0/24 to any port 25 queue mail # # Rule 10 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any load anchor rule2_branch from "/etc/fw/firewall39-rule2_branch.conf" load anchor rule3_branch from "/etc/fw/firewall39-rule3_branch.conf" load anchor rule5_branch from "/etc/fw/firewall39-rule5_branch.conf" fwbuilder-5.1.0.3599/test/pf/firewall41.fw.orig0000755000175000017500000001011311733011756021630 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:22 2011 PST by vadim # # files: * firewall41.fw /etc/firewall41.fw # files: firewall41.conf /etc/firewall41.conf # # Compiled for pf # # testing rule shadowing with run-time objects, rules with such objects should be ignored # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth0 1.1.1.1/0xffffff00" "" update_addresses_of_interface "eth1 2.2.2.2/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:22 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall41.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall-ipv6-2.conf.orig0000644000175000017500000001375511733011756023031 0ustar sylvestresylvestre # Tables: (5) table { 222.222.222.22 , 222.222.222.23 } table { 2001:5c0:0:2::24 , 3ffe:1200:2000::/36 , 3ffe:1200:2001:1:8000::1 } table { 61.150.47.112 , 74.125.224.144 , 74.125.224.145 , 74.125.224.146 , 74.125.224.147 , 74.125.224.148 , 192.168.1.0 } table { 2001:5c0:0:2::24 , 3ffe:1200:2001:1:8000::1 } table { 61.150.47.112 , 192.168.1.0 } # Policy compiler errors and warnings: # firewall-ipv6-2:Policy:5: error: Rule '5 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:5: error: Rule '5 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:7: warning: Changing rule direction due to self reference # # Rule 0 (lo) pass quick on lo inet from any to any keep state label "RULE 0 -- ACCEPT " # # Rule 4 (global) pass log quick inet proto tcp from to 1.1.1.1 port 22 keep state label "RULE 4 -- ACCEPT " # # Rule 5 (global) # firewall-ipv6-2:Policy:5: error: Rule '5 (global)' shadows rule '7 (global)' below it pass log quick inet proto tcp from to 1.1.1.1 port 22 keep state label "RULE 5 -- ACCEPT " # # Rule 7 (global) # firewall-ipv6-2:Policy:7: warning: Changing rule direction due to self reference pass in log quick inet proto tcp from to self port 22 keep state label "RULE 7 -- ACCEPT " # # Rule 8 (global) pass in log quick inet from any to self keep state label "RULE 8 -- ACCEPT " # # Rule 11 (global) pass log quick inet from to any keep state label "RULE 11 -- ACCEPT " # # Rule 12 (global) pass quick inet proto icmp from any to any icmp-type 8 code 0 keep state label "RULE 12 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " # Policy compiler errors and warnings: # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall-ipv6-2:Policy:3: warning: Changing rule direction due to self reference # firewall-ipv6-2:Policy:6: warning: Changing rule direction due to self reference # firewall-ipv6-2:Policy:7: warning: Changing rule direction due to self reference # # Rule 0 (lo) pass quick on lo inet6 from any to any keep state label "RULE 0 -- ACCEPT " # # Rule 1 (global) # this rule shadows the next. # Note that we add command line # flag -xt to the compiler pass quick inet6 proto tcp from fe80::/64 to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 1 -- ACCEPT " # # Rule 2 (global) # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it pass quick inet6 proto tcp from 2001:5c0:0:2::24 to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 2 -- ACCEPT " # # Rule 3 (global) # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '7 (global)' below it # firewall-ipv6-2:Policy:3: warning: Changing rule direction due to self reference pass in log quick inet6 proto tcp from 3ffe:1200:2001:1:8000::1 to self port 22 keep state label "RULE 3 -- ACCEPT " # # Rule 4 (global) # firewall-ipv6-2:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it pass log quick inet6 proto tcp from to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 4 -- ACCEPT " # # Rule 5 (global) pass log quick inet6 proto tcp from to fe80::21d:9ff:fe8b:8e94 port 22 keep state label "RULE 5 -- ACCEPT " # # Rule 6 (global) # firewall-ipv6-2:Policy:6: warning: Changing rule direction due to self reference pass in log quick inet6 proto tcp from to self port 22 keep state label "RULE 6 -- ACCEPT " # # Rule 7 (global) # firewall-ipv6-2:Policy:7: warning: Changing rule direction due to self reference pass in log quick inet6 proto tcp from to self port 22 keep state label "RULE 7 -- ACCEPT " # # Rule 8 (global) pass in log quick inet6 from any to self keep state label "RULE 8 -- ACCEPT " # # Rule 9 (global) pass log quick inet6 from fe80::/64 to any keep state label "RULE 9 -- ACCEPT " # # Rule 10 (global) # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it pass log quick inet6 from to any keep state label "RULE 10 -- ACCEPT " # # Rule 11 (global) pass log quick inet6 from to any keep state label "RULE 11 -- ACCEPT " # # Rule 12 (global) pass quick inet6 proto icmp6 from any to any keep state label "RULE 12 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet6 from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall2.conf.orig0000644000175000017500000002001511733011756022055 0ustar sylvestresylvestre set limit { frags 5000, states 10000 } set optimization aggressive set timeout tcp.first 5 set timeout tcp.opening 5 set timeout tcp.established 10 # # Prolog script # # prolog # prolog commands go after set commands # # End of prolog script # # # Scrub rules # scrub in all fragment reassemble no-df scrub out all random-id min-ttl 32 max-mss 1460 # Tables: (4) table { 192.168.1.10 , 192.168.1.20 } table { eth4 , 22.22.22.22 , 22.22.23.23 , 192.168.1.1 , 192.168.2.1 } table { 192.168.1.0/24 , 192.168.2.0/24 } table { self , 192.168.1.0/24 } # # Rule 0 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) nat on eth1 from 192.168.1.0/24 to any -> (eth1) nat on eth3 from 192.168.1.0/24 to any -> (eth3) nat on eth2 from 192.168.1.0/24 to any -> (eth2) nat on eth4 from 192.168.1.0/24 to any -> (eth4) # # Rule 1 (NAT) nat from to any -> 22.22.22.23 # # Rule 2 (NAT) nat from 192.168.1.0/24 to -> 192.168.1.1 # # Rule 3 (NAT) nat on eth0 proto tcp from 192.168.1.0/24 to any port 80 -> (eth0) nat on eth1 proto tcp from 192.168.1.0/24 to any port 80 -> (eth1) nat on eth3 proto tcp from 192.168.1.0/24 to any port 80 -> (eth3) nat on eth2 proto tcp from 192.168.1.0/24 to any port 80 -> (eth2) nat on eth4 proto tcp from 192.168.1.0/24 to any port 80 -> (eth4) # # Rule 4 (NAT) nat proto tcp from to any port 80 -> 22.22.22.23 # # Rule 5 (NAT) nat proto tcp from 192.168.1.0/24 to port 80 -> 192.168.1.1 # # Rule 6 (NAT) nat on eth0 proto 47 from 192.168.1.0/24 to any -> (eth0) nat on eth1 proto 47 from 192.168.1.0/24 to any -> (eth1) nat on eth3 proto 47 from 192.168.1.0/24 to any -> (eth3) nat on eth2 proto 47 from 192.168.1.0/24 to any -> (eth2) nat on eth4 proto 47 from 192.168.1.0/24 to any -> (eth4) # # Rule 7 (NAT) nat proto icmp from to any -> 22.22.22.23 # # Rule 8 (NAT) nat proto udp from 192.168.1.0/24 to port 53 -> 192.168.1.1 # # Rule 9 (NAT) rdr from any to 22.22.22.23 -> 192.168.1.10 # # Rule 10 (NAT) rdr proto tcp from any to 22.22.22.23 port 80 -> 192.168.1.10 port 80 rdr proto tcp from any to 22.22.22.23 port 119 -> 192.168.1.10 port 119 # # Rule 11 (NAT) rdr proto tcp from any to 22.22.22.22 port 119 -> 192.168.1.10 port 119 # # Rule 12 (NAT) nat from 192.168.1.20 to any -> 22.22.23.24 # # Rule 16 (NAT) rdr from any to -> 192.168.1.10 # # Rule 17 (NAT) rdr on eth1 from any to 22.22.22.22 -> 192.168.1.10 # # Rule 18 (NAT) rdr on eth1 from any to 22.22.22.22 -> 192.168.1.10 # # Rule 19 (NAT) rdr proto 47 from any to -> 192.168.1.10 # # Rule 20 (NAT) rdr proto tcp from any to port 10000:11000 -> 192.168.1.10 port 10000:* # # Rule 21 (NAT) rdr on eth1 proto tcp from any to 22.22.22.22 port 10000:11000 -> 192.168.1.10 port 10000:* # # Rule 22 (NAT) rdr on eth1 proto tcp from any to 22.22.22.22 port 10000:11000 -> 192.168.1.10 port 10000:* # # Rule 23 (NAT) rdr on eth1 proto tcp from any to 22.22.22.22 port 10000:11000 -> 192.168.1.10 port 10000:* nat on eth0 proto tcp from any to 192.168.1.10 port 10000:11000 -> 192.168.1.1 # # Rule 24 (NAT) rdr proto tcp from any to 22.22.22.23 port 80 -> 192.168.1.10 port 25 # # Rule 25 (NAT) rdr proto tcp from 192.168.1.0/24 to any port 80 -> 127.0.0.1 port 80 # # Rule 26 (NAT) rdr proto tcp from 192.168.1.0/24 to any port 80 -> (eth0) port 80 # # Rule 27 (NAT) rdr proto tcp from any to port 1080 -> 127.0.0.1 port 80 # # Rule 28 (NAT) # SF bug 3162862 rdr proto tcp from 192.168.1.0/24 to ! 192.168.1.0/24 port 80 -> 192.168.1.10 port 10000:* # # Rule 29 (NAT) # SF bug 3162862 rdr proto tcp from 192.168.1.0/24 to ! port 80 -> 192.168.1.10 port 10000:* # # Rule 30 (NAT) # SF bug 3162862 rdr proto tcp from 192.168.1.0/24 to ! port 80 -> 127.0.0.1 port 10000:* # # Rule 31 (NAT) # for bug 1111267: this custom service object has # "proto ..." in the protocol string, compiler can put # it in generated nat command in the right place. nat on eth1 proto {tcp udp icmp gre} from 192.168.1.0/24 to any -> 22.22.22.22 # # Rule 32 (NAT) # for bug 1111267: this custom service object # has "proto .." in the code string but we can't insert # it in the generated nat command b/c it would appear # in the wrong place, after "from". nat on eth1 from 192.168.1.0/24 to any -> 22.22.22.22 # # Rule 33 (NAT) nat on eth1 proto tcp from 192.168.1.0/24 to any -> 22.22.22.22 nat on eth1 proto udp from 192.168.1.0/24 to any -> 22.22.22.22 nat on eth1 proto 47 from 192.168.1.0/24 to any -> 22.22.22.22 nat on eth1 proto icmp from 192.168.1.0/24 to any -> 22.22.22.22 # # Rule 34 (NAT) nat on eth0 proto tcp from 192.168.1.0/24 to any port 80 -> (eth0) # # Rule 35 (NAT) nat on eth4 proto tcp from 192.168.1.0/24 to any port 80 -> (eth4) # # Rule 36 (NAT) rdr proto tcp from any to 22.22.22.22 port 119 -> { 192.168.1.10 , 255.255.255.255 } port 119 # # Rule 37 (NAT) rdr on eth1 proto tcp from any to (eth1) port 119 -> { 192.168.1.10 , 255.255.255.255 } port 119 round-robin # # Rule 38 (NAT) nat from eth0:network to any -> 22.22.22.0/24 # # Rule 39 (NAT) nat from eth0:network to any -> eth1:network # Policy compiler errors and warnings: # firewall2:Policy:12: warning: Changing rule direction due to self reference # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 keep state label "RULE -1 - ACCEPT **" # # Rule 0 (eth0) block in log quick on eth0 inet from ! 192.168.1.0/24 to any label "RULE 0 - DROP **" # # Rule 1 (eth1) # Anti-spoofing rule block in log quick on eth1 inet from self to any label "Iface: eth1 RULE 1 -- DROP **" block in log quick on eth1 inet from 192.168.1.0/24 to any label "Iface: eth1 RULE 1 -- DROP **" # # Rule 2 (f2i1,3) # rules 2,3,4 test group # usage in interface # all three rules should yield # the same config block in log quick on { eth1 eth3 } inet from self to any label "Iface: eth1 eth3 RULE 2 -- DROP **" block in log quick on { eth1 eth3 } inet from 192.168.1.0/24 to any label "Iface: eth1 eth3 RULE 2 -- DROP **" # # Rule 3 (f2i1,eth3) # Anti-spoofing rule block in log quick on { eth1 eth3 } inet from self to any label "Iface: eth1 eth3 RULE 3 -- DROP **" block in log quick on { eth1 eth3 } inet from 192.168.1.0/24 to any label "Iface: eth1 eth3 RULE 3 -- DROP **" # # Rule 4 (eth1,eth3) # Anti-spoofing rule block in log quick on { eth1 eth3 } inet from self to any label "Iface: eth1 eth3 RULE 4 -- DROP **" block in log quick on { eth1 eth3 } inet from 192.168.1.0/24 to any label "Iface: eth1 eth3 RULE 4 -- DROP **" # # Rule 5 (eth1) # Anti-spoofing rule block out log quick on eth1 inet from ! to any label "Iface: eth1 RULE 5 -- DROP **" # # Rule 6 (global) # block fragments block log quick inet from any to any fragment label "RULE 6 - DROP **" # # Rule 7 (global) # sends TCP RST and makes custom record in the log block return-rst log quick inet proto tcp from any to any port 113 label "IDENT" # # Rule 8 (global) pass quick inet from to 200.200.200.200 keep state label "RULE 8 - ACCEPT **" # # Rule 9 (global) pass quick inet from 200.200.200.200 to keep state label "RULE 9 - ACCEPT **" # # Rule 10 (global) # 'masquerading' rule pass quick inet from 192.168.1.0/24 to any keep state label "RULE 10 - ACCEPT **" # # Rule 12 (global) # firewall2:Policy:12: warning: Changing rule direction due to self reference pass in quick inet proto tcp from any to self port { 21, 80, 25 } keep state label "RULE 12 - ACCEPT **" pass quick inet proto tcp from any to 192.168.1.10 port { 21, 80, 25 } keep state label "RULE 12 - ACCEPT **" # # Rule 13 (global) # 'catch all' rule block log quick inet from any to any label "RULE 13 - DROP **" # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 - DROP **" fwbuilder-5.1.0.3599/test/pf/pf_cluster_4_pf.conf.orig0000644000175000017500000000111111733011756023240 0ustar sylvestresylvestre # # Rule -3 pfsync (automatic) pass quick on en0 inet proto pfsync from any to any keep state label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any keep state label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any keep state label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall92.conf.orig0000644000175000017500000000327611733011756022160 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # NAT compiler errors and warnings: # firewall92:NAT:2: error: No translation rules are not supported for PF 4.7, use negation to implement exclusions # # Rule 0 (NAT) match out on em0 from 10.1.1.0/24 to any nat-to (em0) # # Rule 1 (NAT) match in on em0 proto udp from ! 10.3.14.41 to 10.3.14.81 port 161 rdr-to 10.1.1.1 port 161 # # Rule 3 (NAT) match in on em0 proto udp from any to 10.3.14.81 port 161 rdr-to 10.1.1.1 port 161 # # Rule 4 (NAT) match out on em1 from 10.1.1.0/24 to any nat-to (em0) # # Rule 5 (NAT) match out on ! em0 from 10.1.1.0/24 to any nat-to 10.3.14.201 # Policy compiler errors and warnings: # firewall92:Policy:0: warning: Changing rule direction due to self reference # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) # firewall92:Policy:0: warning: Changing rule direction due to self reference pass in quick inet proto tcp from 10.3.14.0/24 to self port 22 label "RULE 0 -- ACCEPT " # # Rule 1 (global) pass quick inet from 10.1.1.0/24 to any label "RULE 1 -- ACCEPT " # # Rule 2 (global) match inet from any to 10.1.1.1 tag INTNET label "RULE 2 -- " # # Rule 3 (global) pass quick inet proto udp from any to any port 161 label "RULE 3 -- ACCEPT " # # Rule 4 (global) block log quick inet from any to any no state label "RULE 4 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall109-1.conf.orig0000644000175000017500000000101211733011756022357 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 1 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/objects-for-regression-tests.fwb0000644000175000017500000567524311733011756024643 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk -m ip_conntrack_talk -m ip_nat_talk proto {tcp udp icmp gre} fwbuilder-5.1.0.3599/test/pf/pf_cluster_5_openbsd-4.fw.orig0000755000175000017500000001174311733011756024135 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:32 2011 PST by vadim # # files: * pf_cluster_5_openbsd-4.fw /etc/pf_cluster_5_openbsd-4.fw # files: pf_cluster_5_openbsd-4.conf /etc/pf_cluster_5_openbsd-4.conf # # Compiled for pf 4.6 # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_carp_interfaces carp0 carp1 carp2 update_addresses_of_interface "en0 172.24.0.3/0xffffff00" "" update_addresses_of_interface "en1 192.168.1.3/0xffffff00" "" update_addresses_of_interface "en2" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" update_addresses_of_interface "vlan100 172.20.0.3/0xffffff00" "" $IFCONFIG carp0 vhid 1 advskew 1 carpdev en0 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 1 advskew 1 carpdev en1 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" $IFCONFIG carp2 vhid 1 advskew 1 carpdev vlan100 update_addresses_of_interface "carp2 172.20.0.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:32 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_5_openbsd-4.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall1.conf.orig0000644000175000017500000001341011733011756022055 0ustar sylvestresylvestre # # Prolog script # # prolog: # some pf command at the very top of the .conf file goes here # # End of prolog script # # # Scrub rules # scrub in all fragment reassemble # Tables: (6) table { 22.22.22.22 , 192.168.1.1 } table { 192.168.1.10 , 192.168.1.20 } table { self , 192.168.2.0/24 } table { 33.33.33.0/24 , 33.33.44.0/24 } table { 192.168.1.0/24 , 192.168.2.0/24 } table { 22.22.22.22 , 22.22.23.23 , 192.168.1.1 , 192.168.2.1 } # # Rule 0 (NAT) no nat from 192.168.1.0/24 to 192.168.2.0/24 no rdr from 192.168.1.0/24 to 192.168.2.0/24 # # Rule 1 (NAT) nat from 192.168.1.10 to any -> 22.22.22.23 # # Rule 2 (NAT) nat from ! 192.168.1.0/24 to 200.200.200.200 -> 22.22.22.23 # # Rule 3 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) nat on eth1 from 192.168.1.0/24 to any -> (eth1) nat on eth2 from 192.168.1.0/24 to any -> (eth2) nat on eth3 from 192.168.1.0/24 to any -> (eth3) # # Rule 4 (NAT) nat on eth1 from 192.168.1.0/24 to any -> (eth1) nat on eth3 from 192.168.1.0/24 to any -> (eth3) # # Rule 5 (NAT) # more examples # of NAT rules with # multiple objects in TSrc # in firewall3 nat from 192.168.1.0/24 to any -> { 22.22.22.50 , 22.22.22.51 } # # Rule 6 (NAT) nat on eth0 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth0) nat on eth1 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth1) nat on eth2 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth2) nat on eth3 from 192.168.1.0/24 to ! 192.168.2.0/24 -> (eth3) # # Rule 7 (NAT) nat on eth0 from 192.168.1.0/24 to ! -> (eth0) nat on eth1 from 192.168.1.0/24 to ! -> (eth1) nat on eth2 from 192.168.1.0/24 to ! -> (eth2) nat on eth3 from 192.168.1.0/24 to ! -> (eth3) # # Rule 8 (NAT) nat on eth0 from ! 192.168.2.0/24 to any -> (eth0) nat on eth1 from ! 192.168.2.0/24 to any -> (eth1) nat on eth2 from ! 192.168.2.0/24 to any -> (eth2) nat on eth3 from ! 192.168.2.0/24 to any -> (eth3) # # Rule 9 (NAT) rdr proto tcp from 192.168.1.0/24 to ! port 80 -> 127.0.0.1 port 3128 # # Rule 10 (NAT) rdr proto tcp from 192.168.1.0/24 to ! 192.168.1.1 port 80 -> 127.0.0.1 port 3128 # # Rule 11 (NAT) rdr proto tcp from to ! port 80 -> 127.0.0.1 port 3128 # # Rule 12 (NAT) rdr proto tcp from 192.168.1.0/24 to ! port 80 -> 127.0.0.1 port 3128 rdr proto tcp from 192.168.1.0/24 to ! port 81 -> 127.0.0.1 port 3128 # # Rule 13 (NAT) rdr proto tcp from 192.168.1.0/24 to ! port 80 -> 192.168.2.200 port 3128 rdr proto tcp from 192.168.1.0/24 to ! port 81 -> 192.168.2.200 port 3128 # # Rule 14 (NAT) rdr proto tcp from ! to port 80 -> 127.0.0.1 port 3128 # # Rule 15 (NAT) rdr proto tcp from ! 192.168.1.10 to any port 80 -> 127.0.0.1 port 3128 # # Rule 16 (NAT) rdr on eth1 proto tcp from to 22.22.22.22 port 80 -> 192.168.1.10 port 80 # Policy compiler errors and warnings: # firewall1:Policy:10: warning: Changing rule direction due to self reference # firewall1:Policy:18: warning: Changing rule direction due to self reference # # Rule 0 (eth0) block log quick on eth0 inet proto icmp from to ! block log quick on eth0 inet proto 50 from to ! # # Rule 1 (eth0) block quick on eth0 inet proto icmp from to ! block quick on eth0 inet proto 50 from to ! # # Rule 2 (eth1) # Anti-spoofing rule block in log quick on eth1 inet from self to any block in log quick on eth1 inet from 192.168.1.0/24 to any # # Rule 3 (eth1) # Anti-spoofing rule block out log quick on eth1 inet from ! 192.168.1.0/24 to any # # Rule 4 (eth1) # testing rule shading: this rule is not # shaded by rule #1 pass in quick on eth1 inet proto icmp from any to any icmp-type 8 code 0 keep state # # Rule 5 (global) block log quick inet proto tcp from any to any flags S/UAPRSF # # Rule 7 (global) # hostF has the same IP address as firewal. pass log quick inet proto icmp from any to 192.168.1.1 icmp-type 8 code 0 keep state # # Rule 8 (global) # testing negation in the policy rule block log quick inet proto icmp from ! 192.168.1.10 to any icmp-type 3 # # Rule 9 (global) # testing negation in the policy rule block log quick inet proto icmp from ! to any icmp-type 3 # # Rule 10 (global) # this rule is shaded by rule above. # firewall1:Policy:10: warning: Changing rule direction due to self reference block in log quick inet proto icmp from ! to self icmp-type 3 # # Rule 11 (global) # this rule shades rule below block log quick inet from ! to 192.168.1.0/24 # # Rule 12 (global) block log quick inet from to ! # # Rule 13 (global) # testing negation in the policy rule block return-icmp log quick inet from 192.168.1.10 to any # # Rule 16 (global) block log quick inet proto icmp from to ! block log quick inet proto 50 from to ! # # Rule 17 (global) # 'masquerading' rule pass quick inet from 192.168.1.0/24 to any keep state # # Rule 18 (global) # firewall1:Policy:18: warning: Changing rule direction due to self reference pass in quick inet proto tcp from any to self port 3128 keep state # # Rule 19 (eth0) # rule from http://www.benzedrine.cx/transquid.html # Used to permit connections to transparent # squid proxy. Should be "in $int_if" but destination # is loopback interface pass in quick on eth0 inet proto tcp from any to 127.0.0.1 port 3128 keep state # # Rule 20 (global) # 'catch all' rule block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall40-1.conf.orig0000644000175000017500000000702711733011756022305 0ustar sylvestresylvestre # # Rule 0 (NAT) # Translate source address # for outgoing connections nat on le1 from 192.168.1.0/24 to any -> (le1) # # Rule 1 (NAT) # Translate source address # for outgoing connections nat on le2 from 192.168.1.0/24 to any -> (le2) # Policy compiler errors and warnings: # firewall40-1:Policy:9: error: Only one router specified with load balancing for rule action Route: 'route_through' # firewall40-1:Policy:10: error: Only one router specified with load balancing for rule action Route: 'route_through' # firewall40-1:Policy:11: error: Illegal IP address for next hop # firewall40-1:Policy:11: error: Only one router specified with load balancing for rule action Route: 'route_through' # # Rule 0 (fxp0) pass in quick on fxp0 route-to { ( le1 192.0.2.1 ) , ( le1 192.0.2.2 ) , ( le1 192.0.2.3 ) } random inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 0 -- ACCEPT " # # Rule 1 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.2.1 ) , ( le2 192.0.2.2 ) , ( le2 192.0.2.3 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 1 -- ACCEPT " # # Rule 2 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.2.1 ) , ( le2 192.0.2.2 ) , ( le2 192.0.2.3 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 2 -- ACCEPT " # # Rule 3 (fxp0) pass in quick on fxp0 route-to { ( le1 192.0.2.1 ) , ( le1 192.0.2.2 ) , ( le1 192.0.2.3 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 label "RULE 3 -- ACCEPT " # # Rule 4 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.2.1 ) , ( le2 192.0.2.2 ) , ( le2 192.0.2.3 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 label "RULE 4 -- ACCEPT " # # Rule 5 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.2.1 ) , ( le2 192.0.2.2 ) , ( le2 192.0.2.3 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 label "RULE 5 -- ACCEPT " # # Rule 6 (fxp0) pass in quick on fxp0 route-to { ( le1 192.0.2.0/24 ) } random inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 6 -- ACCEPT " # # Rule 7 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.2.0/24 ) } source-hash inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 7 -- ACCEPT " # # Rule 8 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.2.0/255.255.255.0 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 8 -- ACCEPT " # # Rule 9 (fxp0) # this should fail because # it has one address for the next # hop and it is /32. # Run compiler with # command line argument -xt # to convert errors to warnings # and make it generate .conf # file anyway pass in quick on fxp0 route-to { ( le2 192.0.2.1 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 9 -- ACCEPT " # # Rule 10 (fxp0) # this should fail because # it has one address for the next # hop and it is /32. pass in quick on fxp0 route-to { ( le2 192.0.2.1/32 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 10 -- ACCEPT " # # Rule 11 (fxp0) # this should fail because # it ip address in next hop # is illegal pass in quick on fxp0 route-to { ( le2 192.0.300.1/32 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 11 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " load anchor routes from "/etc/firewall40-1-routes.conf" fwbuilder-5.1.0.3599/test/pf/firewall106.fw.orig0000755000175000017500000000255111733011756021721 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:06 2011 PST by vadim # # files: * firewall106.fw /etc/fw/pf.fw # files: firewall106.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # bridge interface, dynamic address, rc.conf format, with STP # firewall106:Routing:1: error: Gateway and interface are both empty in the rule # firewall106:Routing:1: error: Rules 0 (main) and 1 (main) define routes to the same destination 0.0.0.0/0.0.0.0 via different gateways. This configuration is not supported for freebsd # firewall106:Routing:4: warning: Two of the routing commands created from the gui routing rules 3 (main) and 4 (main) are identical, skipping the second. Revise them to avoid this warning gateway_enable="YES" cloned_interfaces="bridge0" network_interfaces="bridge0 em0 em1" ifconfig_em0="10.3.14.81 netmask 0xffffff00" ifconfig_em1="10.1.1.81 netmask 0xffffff00" ifconfig_em2="up" ifconfig_em3="up" ifconfig_bridge0="addm em2 stp em2 addm em3 stp em3 up DHCP" pf_enable="YES" pf_rules="/etc/fw/path\ with\ space/pf.conf" static_routes="route_0 route_1 route_2 route_3 route_4" route_route_0="default 10.1.1.1 " route_route_1="default " route_route_2="192.168.171.2 10.1.1.1 " route_route_3="22.22.22.0/24 10.1.1.1 " route_route_4="33.33.33.0/24 10.1.1.1 " fwbuilder-5.1.0.3599/test/pf/block-hosts.tbl0000644000175000017500000000157711733011756021327 0ustar sylvestresylvestre# # use this table to test run-time AddressTable object # (this is just a small collection of addresses that sent spam to me # on Nov 20 2005) # 151.8.224.178 168.156.76.20 193.207.126.36 195.136.186.35 196.15.136.15 201.10.180.138 201.17.93.16 201.36.156.121 202.103.25.253 202.96.112.93 203.162.3.209 203.209.124.144 210.106.193.237 210.222.114.102 211.144.143.143 211.172.218.237 211.250.16.132 212.100.212.100 212.21.241.31 218.104.138.146 218.18.72.252 218.39.114.122 218.55.115.43 219.132.104.160 220.71.17.86 220.81.50.105 220.91.99.46 221.14.249.242 221.166.177.135 221.198.33.38 221.202.160.233 221.205.54.125 221.217.44.248 222.100.212.223 222.121.118.144 222.174.113.2 58.231.13.78 58.33.181.83 58.53.82.190 61.150.47.112 61.184.14.102 64.106.85.186 70.228.60.100 80.243.72.149 80.249.77.34 80.51.236.6 81.196.74.125 81.2.36.254 82.117.221.205 82.143.196.17 82.77.37.174 84.90.8.198 fwbuilder-5.1.0.3599/test/pf/pf_cluster_1_openbsd-2.conf.orig0000644000175000017500000000365711733011756024442 0ustar sylvestresylvestre # Tables: (2) table { 172.24.0.1 , 172.24.0.3 , 192.168.1.1 , 192.168.1.3 } table { 172.24.0.1 , 172.24.0.3 } # # Rule 0 (NAT) nat on en0 from 192.168.1.0/24 to any -> (carp0) # # Rule 1 (NAT) nat on en0 from 192.168.1.0/24 to any -> 172.24.0.1 # # Rule 2 (NAT) nat from 192.168.1.0/24 to any -> 172.24.0.1 # # Rule 3 (NAT) nat on en0 from 192.168.1.0/24 to any -> { (en0) , (en0) } # # Rule 4 (NAT) nat from 192.168.1.0/24 to any -> (en0) # # Rule 5 (NAT) nat on en0 from 192.168.1.0/24 to any -> (en0) # # Rule 6 (NAT) rdr on en0 proto tcp from any to 172.24.0.1 port 80 -> 172.24.0.100 port 80 # # Rule 7 (NAT) rdr on en0 proto tcp from any to 172.24.0.1 port 80 -> 172.24.0.100 port 80 # # Rule 8 (NAT) rdr proto tcp from any to 172.24.0.1 port 80 -> 172.24.0.100 port 80 # # Rule -3 pfsync (automatic) pass quick on en0 inet proto pfsync from any to any label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -1 -- ACCEPT " # # Rule 0 (lo0) pass quick on lo0 inet from any to any label "RULE 0 -- ACCEPT " # # Rule 1 (global) pass quick inet from any to label "RULE 1 -- ACCEPT " # # Rule 2 (global) pass quick inet from to any label "RULE 2 -- ACCEPT " # # Rule 3 (global) pass quick inet from any to label "RULE 3 -- ACCEPT " # # Rule 4 (carp0) pass in quick on en0 inet from any to any label "RULE 4 -- ACCEPT " # # Rule 5 (carp0) pass in quick on en1 inet from any to any label "RULE 5 -- ACCEPT " # # Rule 6 (global) block log quick inet from any to any no state label "RULE 6 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall91.conf.orig0000644000175000017500000000060211733011756022145 0ustar sylvestresylvestre # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 flags S/SA keep state label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall109-1.fw.orig0000755000175000017500000000174711733011756022070 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:09 2011 PST by vadim # # files: * firewall109-1.fw /etc/fw/pf.fw # files: firewall109-1.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # complex configuration with bridge and vlan, rc.conf format gateway_enable="YES" cloned_interfaces="vlan101 vlan102 bridge0" network_interfaces="bridge0 em0 vlan101 vlan102" ifconfig_em0="10.3.14.81 netmask 0xffffff00" ifconfig_em1="up media 100baseTX mediaopt full-duplex" vlans_em2="vlan101 vlan102" create_args_vlan101="vlan 101 vlandev em2" create_args_vlan102="vlan 102 vlandev em2" ifconfig_em2="up media 100baseTX mediaopt full-duplex" ifconfig_vlan101="192.168.101.1 netmask 0xffffff00" ifconfig_vlan102="192.168.102.1 netmask 0xffffff00" ifconfig_bridge0="addm em1 -stp em1 addm em2 -stp em2 up 192.168.1.1 netmask 0xffffff00" pf_enable="YES" pf_rules="/etc/fw/path\ with\ space/pf.conf" fwbuilder-5.1.0.3599/test/pf/firewall51-web_server_inbound.conf.orig0000644000175000017500000000036211733011756026023 0ustar sylvestresylvestre# # Rule web_server_inbound 0 (global) pass in quick inet proto tcp from any to any port 80 keep state # # Rule web_server_inbound 1 (global) pass in quick inet proto icmp from any to any icmp-type { 3 , 8 code 0 } keep state fwbuilder-5.1.0.3599/test/pf/firewall13.fw.orig0000755000175000017500000000455611733011756021645 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:13 2011 PST by vadim # # files: * firewall13.fw /etc/fw/firewall13.fw # files: firewall13.conf /etc/fw/firewall13.conf # # Compiled for pf # # testing detection of empty groups # firewall13:NAT:0: warning: Empty group or address table object 'egroup' # firewall13:NAT:0: warning: After removal of all empty groups and address table objects rule element OSrc becomes 'any' in the rule 0 (NAT) # Dropping rule 0 (NAT) because option 'Ignore rules with empty groups' is in effect # firewall13:NAT:1: warning: Empty group or address table object 'egroup' # firewall13:NAT:2: warning: Empty group or address table object 'sgroup' # firewall13:NAT:2: warning: After removal of all empty groups and address table objects rule element OSrv becomes 'any' in the rule 2 (NAT) # Dropping rule 2 (NAT) because option 'Ignore rules with empty groups' is in effect # firewall13:Policy:0: warning: Empty group or address table object 'egroup2' # firewall13:Policy:1: warning: Empty group or address table object 'sgroup' # firewall13:Policy:1: warning: After removal of all empty groups and address table objects rule element Srv becomes 'any' in the rule 1 (global) # Dropping rule 1 (global) because option 'Ignore rules with empty groups' is in effect FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.directed-broadcast=0 $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet.ip.sourceroute=0 $SYSCTL -w net.inet.ip.redirect=0 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:13 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall13.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall41.conf.orig0000644000175000017500000000305211733011756022142 0ustar sylvestresylvestre # Tables: (3) table persist file "block-hosts.tbl" table persist table { 192.168.1.1 , 192.168.1.2 , 192.168.1.3/30 , 192.168.1.200 , 192.168.1.201 , 192.168.2.128/25 } # Policy compiler errors and warnings: # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode # # Rule 0 (global) pass out log quick inet from self to www.heise.de keep state label "RULE 0 -- ACCEPT " # # Rule 1 (global) pass out log quick inet from self to keep state label "RULE 1 -- ACCEPT " # # Rule 2 (global) pass out log quick inet from self to keep state label "RULE 2 -- ACCEPT " pass out log quick inet from self to keep state label "RULE 2 -- ACCEPT " # # Rule 3 (global) # firewall41:Policy:3: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode pass out log quick inet from self to 192.0.2.0/24 keep state label "RULE 3 -- ACCEPT " # # Rule 4 (global) pass out log quick inet from self to 1.1.1.1 keep state label "RULE 4 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/pf_cluster_3_openbsd-4.conf.orig0000644000175000017500000000402111733011756024430 0ustar sylvestresylvestre # Tables: (1) table { 172.20.0.1 , 172.20.0.3 , 172.24.0.1 , 172.24.0.3 , 192.168.1.1 , 192.168.1.3 } # # Rule -3 CARP (automatic) pass quick on vlan100 inet proto carp from any to any label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -1 -- ACCEPT " # # Rule 0 (carp0) block in log quick on en0 inet from to any no state label "RULE 0 -- DROP " # # Rule 1 (carp0) pass quick on en0 inet from any to any label "RULE 1 -- ACCEPT " # # Rule 2 (carp0,carp1) pass quick on { en0 en1 } inet proto tcp from any to port 22 label "RULE 2 -- ACCEPT " # # Rule 3 (cl3 itf) pass quick on { en0 en1 } inet proto tcp from any to port 22 label "RULE 3 -- ACCEPT " # # Rule 4 (carp0) pass quick on { en1 en2 vlan100 } inet from any to any label "RULE 4 -- ACCEPT " # # Rule 5 (carp0,carp1) pass quick on { en2 vlan100 } inet from any to any label "RULE 5 -- ACCEPT " # # Rule 6 (carp0,carp1,carp2) pass quick on en2 inet from any to any label "RULE 6 -- ACCEPT " # # Rule 7 (carp0) pass in quick on { en1 en2 vlan100 } inet from any to any label "RULE 7 -- ACCEPT " # # Rule 8 (carp0,carp1) pass in quick on { en2 vlan100 } inet from any to any label "RULE 8 -- ACCEPT " # # Rule 9 (carp0) pass out quick on { en1 en2 vlan100 } inet from any to any label "RULE 9 -- ACCEPT " # # Rule 10 (carp0,carp1) pass out quick on { en2 vlan100 } inet from any to any label "RULE 10 -- ACCEPT " # # Rule 11 (carp0) pass quick on { en1 en2 vlan100 } inet from any to label "RULE 11 -- ACCEPT " # # Rule 12 (carp0,carp1) pass quick on { en2 vlan100 } inet from any to label "RULE 12 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall7.fw.orig0000755000175000017500000000223311733011756021556 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:25 2011 PST by vadim # # files: * firewall7.fw /etc/fw/firewall7.fw # files: firewall7.conf /etc/fw/firewall7.conf # # Compiled for pf # # testing rules with broadcasts FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:25 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall7.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall-base-rulesets.fw.orig0000755000175000017500000001025111733011756024242 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:30 2011 PST by vadim # # files: * firewall-base-rulesets.fw /etc/fw/firewall-base-rulesets.fw # files: firewall-base-rulesets.conf /etc/fw/firewall-base-rulesets.conf # files: firewall-base-rulesets-web_server_inbound.conf /etc/fw/firewall-base-rulesets-web_server_inbound.conf # files: firewall-base-rulesets-mail_server_inbound.conf /etc/fw/firewall-base-rulesets-mail_server_inbound.conf # files: firewall-base-rulesets-mail_server_outbound.conf /etc/fw/firewall-base-rulesets-mail_server_outbound.conf # files: firewall-base-rulesets-web_server_outbound.conf /etc/fw/firewall-base-rulesets-web_server_outbound.conf # # Compiled for pf # # this firewall is used to test a rule in the global policy of object "firewall" FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "en0 33.33.33.33/0xffffff00" "" update_addresses_of_interface "en1 172.16.1.1/0xffffff00" "" update_addresses_of_interface "en2 192.168.100.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:30 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall-base-rulesets.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall21.fw.orig0000755000175000017500000000327311733011756021637 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:16 2011 PST by vadim # # files: * firewall21.fw /etc/fw/firewall21.fw # files: firewall21.conf /etc/fw/firewall21.conf # files: firewall21-NAT_1.conf /etc/fw/firewall21-NAT_1.conf # # Compiled for pf 4.0 # # branching in NAT rules # PF v4.0-4.2 # firewall21:ftp-proxy/*:: warning: The name of the NAT ruleset ftp-proxy/* ends with '/*', assuming it is externally controlled and skipping it. # firewall21:ftp-proxy/*:: warning: The name of the Policy ruleset ftp-proxy/* ends with '/*', assuming it is externally controlled and skipping it. # firewall21:NAT:3: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/local/bin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:16 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall21.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_3_openbsd-3.fw.orig0000755000175000017500000001735511733011756024137 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:32 2011 PST by vadim # # files: * pf_cluster_3_openbsd-3.fw /etc/pf_cluster_3_openbsd-3.fw # files: pf_cluster_3_openbsd-3.conf /etc/pf_cluster_3_openbsd-3.conf # # Compiled for pf 4.6 # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan100 sync_carp_interfaces carp0 carp1 carp2 sync_pfsync_interfaces update_addresses_of_interface "en0 172.24.0.2/0xffffff00" "" update_addresses_of_interface "en1 192.168.1.2/0xffffff00" "" update_vlans_of_interface "en2 vlan100:100" update_addresses_of_interface "en2" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" update_addresses_of_interface "vlan100 172.20.0.2/0xffffff00" "" $IFCONFIG carp0 vhid 1 carpdev en0 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 1 carpdev en1 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" $IFCONFIG carp2 vhid 1 carpdev vlan100 update_addresses_of_interface "carp2 172.20.0.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:32 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_3_openbsd-3.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall2-1.conf.orig0000644000175000017500000000545311733011756022224 0ustar sylvestresylvestre set limit { frags 5000, states 10000 } set optimization aggressive set timeout tcp.first 5 set timeout tcp.opening 5 set timeout tcp.established 10 # # Prolog script # # prolog # prolog commands go after set commands # # End of prolog script # # # Scrub rules # scrub in all fragment reassemble no-df scrub out all random-id min-ttl 32 max-mss 1460 # Tables: (1) table { 22.22.22.22 , 192.168.1.1 } # NAT compiler errors and warnings: # firewall2-1:NAT:1: error: Negation in original service is not supported. # firewall2-1:NAT:2: error: Can not translate 'any' into a specific service. # firewall2-1:NAT:3: error: Can not use negation in translated source. # firewall2-1:NAT:4: error: Can not use negation in translated destination. # firewall2-1:NAT:5: error: Can not use negation in translated service. # firewall2-1:NAT:6: error: Translated service should be 'Original' or should contain single object. # firewall2-1:NAT:7: error: Translated service should be 'Original' or should contain single object. # firewall2-1:NAT:9: error: Can not use unnumbered interface in Translated Source of a Source translation rule. # firewall2-1:NAT:12: error: Can not use network or address range object in translated destination. # firewall2-1:NAT:13: error: Can not use network or address range object in translated destination. # firewall2-1:NAT:15: error: Can not use network or address range object in translated destination. # firewall2-1:NAT:16: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' # firewall2-1:NAT:16: error: Action 'Branch' needs NAT rule set to point to # firewall2-1:NAT:17: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' # # Rule 0 (NAT) rdr on { eth1 eth0 } from any to -> 192.168.1.10 # # Rule 8 (NAT) no nat proto tcp from 192.168.1.0/24 to any no rdr proto tcp from 192.168.1.0/24 to any # # Rule 10 (NAT) no nat proto tcp from any to 22.22.22.22 no rdr proto tcp from any to 22.22.22.22 # # Rule 11 (NAT) rdr proto tcp from any to (eth1) port 1080 -> { 192.168.1.10 , 192.168.1.20 } port 1080 # # Rule 14 (NAT) nat from 192.168.1.0/24 to any -> 22.22.22.0/28 # # Rule 17 (NAT) # firewall2-1:NAT:17: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' nat-anchor "NAT" proto tcp from 192.168.1.0/24 to any port 1080 rdr-anchor "NAT" proto tcp from 192.168.1.0/24 to any port 1080 # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 keep state label "RULE -1 - ACCEPT **" # # Rule 0 (global) # 'catch all' rule block log quick inet from any to any label "RULE 0 - DROP **" # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 - DROP **" fwbuilder-5.1.0.3599/test/pf/firewall-ipv6-3-Policy_ipv4.conf.orig0000644000175000017500000000016211733011756025215 0ustar sylvestresylvestre# # Rule Policy_ipv4 0 (lo0) pass quick on lo0 inet from any to any keep state label "RULE 0 -- ACCEPT " fwbuilder-5.1.0.3599/test/pf/firewall20.fw.orig0000755000175000017500000000223311733011756021631 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:15 2011 PST by vadim # # files: * firewall20.fw /etc/fw/firewall20.fw # files: firewall20.conf /etc/fw/firewall20.conf # # Compiled for pf # # firewall using proxy arp FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:15 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall20.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall105.fw.orig0000755000175000017500000000130311733011756021712 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:05 2011 PST by vadim # # files: * firewall105.fw /etc/fw/pf.fw # files: firewall105.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # bridge interface, static address, rc.conf format gateway_enable="YES" cloned_interfaces="bridge0" network_interfaces="bridge0 em0 em1" ifconfig_em0="10.3.14.81 netmask 0xffffff00" ifconfig_em1="10.1.1.81 netmask 0xffffff00" ifconfig_em2="up" ifconfig_em3="up" ifconfig_bridge0="addm em2 -stp em2 addm em3 -stp em3 up 192.168.1.1 netmask 0xffffff00" pf_enable="YES" pf_rules="/etc/fw/path\ with\ space/pf.conf" fwbuilder-5.1.0.3599/test/pf/pf_cluster_3_openbsd-3.conf.orig0000644000175000017500000000402111733011756024427 0ustar sylvestresylvestre # Tables: (1) table { 172.20.0.1 , 172.20.0.2 , 172.24.0.1 , 172.24.0.2 , 192.168.1.1 , 192.168.1.2 } # # Rule -3 CARP (automatic) pass quick on vlan100 inet proto carp from any to any label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -1 -- ACCEPT " # # Rule 0 (carp0) block in log quick on en0 inet from to any no state label "RULE 0 -- DROP " # # Rule 1 (carp0) pass quick on en0 inet from any to any label "RULE 1 -- ACCEPT " # # Rule 2 (carp0,carp1) pass quick on { en0 en1 } inet proto tcp from any to port 22 label "RULE 2 -- ACCEPT " # # Rule 3 (cl3 itf) pass quick on { en0 en1 } inet proto tcp from any to port 22 label "RULE 3 -- ACCEPT " # # Rule 4 (carp0) pass quick on { en1 en2 vlan100 } inet from any to any label "RULE 4 -- ACCEPT " # # Rule 5 (carp0,carp1) pass quick on { en2 vlan100 } inet from any to any label "RULE 5 -- ACCEPT " # # Rule 6 (carp0,carp1,carp2) pass quick on en2 inet from any to any label "RULE 6 -- ACCEPT " # # Rule 7 (carp0) pass in quick on { en1 en2 vlan100 } inet from any to any label "RULE 7 -- ACCEPT " # # Rule 8 (carp0,carp1) pass in quick on { en2 vlan100 } inet from any to any label "RULE 8 -- ACCEPT " # # Rule 9 (carp0) pass out quick on { en1 en2 vlan100 } inet from any to any label "RULE 9 -- ACCEPT " # # Rule 10 (carp0,carp1) pass out quick on { en2 vlan100 } inet from any to any label "RULE 10 -- ACCEPT " # # Rule 11 (carp0) pass quick on { en1 en2 vlan100 } inet from any to label "RULE 11 -- ACCEPT " # # Rule 12 (carp0,carp1) pass quick on { en2 vlan100 } inet from any to label "RULE 12 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall13.conf.orig0000644000175000017500000000314711733011756022146 0ustar sylvestresylvestre # NAT compiler errors and warnings: # firewall13:NAT:0: warning: Empty group or address table object 'egroup' # firewall13:NAT:0: warning: After removal of all empty groups and address table objects rule element OSrc becomes 'any' in the rule 0 (NAT) # Dropping rule 0 (NAT) because option 'Ignore rules with empty groups' is in effect # firewall13:NAT:1: warning: Empty group or address table object 'egroup' # firewall13:NAT:2: warning: Empty group or address table object 'sgroup' # firewall13:NAT:2: warning: After removal of all empty groups and address table objects rule element OSrv becomes 'any' in the rule 2 (NAT) # Dropping rule 2 (NAT) because option 'Ignore rules with empty groups' is in effect # # Rule 1 (NAT) # firewall13:NAT:1: warning: Empty group or address table object 'egroup' rdr proto tcp from 200.200.200.200 to 22.22.22.23 port 6667 -> 192.168.1.10 port 6667 # Policy compiler errors and warnings: # firewall13:Policy:0: warning: Empty group or address table object 'egroup2' # firewall13:Policy:1: warning: Empty group or address table object 'sgroup' # firewall13:Policy:1: warning: After removal of all empty groups and address table objects rule element Srv becomes 'any' in the rule 1 (global) # Dropping rule 1 (global) because option 'Ignore rules with empty groups' is in effect # # Rule 0 (global) # firewall13:Policy:0: warning: Empty group or address table object 'egroup2' pass quick inet from 200.200.200.200 to 192.168.1.10 keep state # # Rule 2 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall104.fw.orig0000755000175000017500000002411611733011756021720 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:04 2011 PST by vadim # # files: * firewall104.fw /etc/fw/pf.fw # files: firewall104.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # bridge interface, dynamic address, shell script format, with STP FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" update_addresses_of_interface "em2" "" update_addresses_of_interface "em3" "" update_bridge_interface bridge0 "em2 em3" $IFCONFIG bridge0 stp em2 $IFCONFIG bridge0 stp em3 } log "Activating firewall script generated Wed Nov 30 18:39:04 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall10-6.conf.orig0000644000175000017500000000140211733011756022276 0ustar sylvestresylvestre set skip on lo0 # # Scrub rules # scrub in all fragment reassemble # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 flags any # # Rule 0 (eth0) pass in quick on eth0 inet proto tcp from 192.168.1.0/24 to any port { 80, 22 } flags any # # Rule 1 (lo0) pass quick on lo0 inet from any to any no state # # Rule 2 (enc0) # via ipsec pass quick on enc0 inet proto tcp from 33.33.33.0/24 to 192.168.1.0/24 port 80 flags any keep state # # Rule 3 (global) block log quick inet from any to any no state # # Rule fallback rule # fallback rule block quick inet from any to any no state fwbuilder-5.1.0.3599/test/pf/firewall109.fw.orig0000755000175000017500000002461211733011756021726 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:08 2011 PST by vadim # # files: * firewall109.fw /etc/fw/pf.fw # files: firewall109.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # complex configuration with bridge and vlan FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } BRCONFIG="$IFCONFIG" missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } sync_carp_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } sync_pfsync_interfaces() { $IFCONFIG | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan101 vlan102 sync_bridge_interfaces bridge0 sync_carp_interfaces sync_pfsync_interfaces update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1" "" $IFCONFIG em1 media 100baseTX mediaopt full-duplex update_vlans_of_interface "em2 vlan101:101 vlan102:102" update_addresses_of_interface "em2" "" $IFCONFIG em2 media 100baseTX mediaopt full-duplex update_addresses_of_interface "vlan101 192.168.101.1/0xffffff00" "" update_addresses_of_interface "vlan102 192.168.102.1/0xffffff00" "" update_bridge_interface bridge0 "em1 em2" $IFCONFIG bridge0 -stp em1 $IFCONFIG bridge0 -stp em2 update_addresses_of_interface "bridge0 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:08 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_2_freebsd-2.conf.orig0000644000175000017500000000107211733011756024410 0ustar sylvestresylvestre # # Rule -3 pfsync (automatic) pass quick on en0 inet proto pfsync from any to any label "RULE -3 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/pf_cluster_1_openbsd-2.fw.orig0000755000175000017500000001144111733011756024122 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:31 2011 PST by vadim # # files: * pf_cluster_1_openbsd-2.fw /etc/pf_cluster_1_openbsd-2.fw # files: pf_cluster_1_openbsd-2.conf /etc/pf_cluster_1_openbsd-2.conf # # Compiled for pf 4.x # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } sync_carp_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_carp_interfaces carp0 carp1 update_addresses_of_interface "en0 172.24.0.3/0xffffff00 172.24.0.2/0xffffff00" "" update_addresses_of_interface "en1 192.168.1.3/0xffffff00" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" $IFCONFIG carp0 vhid 101 pass secret advskew 1 carpdev en0 update_addresses_of_interface "carp0 172.24.0.1/0xffffff00" "" $IFCONFIG carp1 vhid 100 pass secret advskew 1 carpdev en1 update_addresses_of_interface "carp1 192.168.1.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:31 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/pf_cluster_1_openbsd-2.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall91.fw.orig0000755000175000017500000001351511733011756021646 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:28 2011 PST by vadim # # files: * firewall91.fw /etc/fw/pf.fw # files: firewall91.conf /etc/fw/pf.conf # # Compiled for pf # FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG -A | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG -A | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : sync_vlan_interfaces vlan101 vlan103 update_vlans_of_interface "em0 vlan101:101 vlan103:103" update_addresses_of_interface "em0 10.1.1.50/0xffffff00" "" update_addresses_of_interface "pcn0 10.3.14.50/0xffffff00" "" update_addresses_of_interface "vlan101 10.100.101.1/0xffffff00" "" update_addresses_of_interface "vlan103 10.100.103.1/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:28 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/pf_cluster_5_openbsd-3.conf.orig0000644000175000017500000000116511733011756024437 0ustar sylvestresylvestre # # Rule 0 (NAT) # rule is attached to physical interface en0 # but uses address of carp0 for translation nat on en0 from 192.168.1.0/24 to any -> (carp0) # # Rule -3 CARP (automatic) pass quick on vlan100 inet proto carp from any to any label "RULE -4 -- ACCEPT " # # Rule -2 CARP (automatic) pass quick on en1 inet proto carp from any to any label "RULE -3 -- ACCEPT " # # Rule -1 CARP (automatic) pass quick on en0 inet proto carp from any to any label "RULE -2 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE -1 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall70.fw.orig0000755000175000017500000000343211733011756021640 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:26 2011 PST by vadim # # files: * firewall70.fw /etc/fw/firewall70.fw # files: firewall70.conf /etc/fw/firewall70.conf # # Compiled for pf # # testing for unpotected interfaces # firewall70:Policy:0: warning: Changing rule direction due to self reference # firewall70:Policy:1: warning: Changing rule direction due to self reference # firewall70:Policy:2: warning: Changing rule direction due to self reference # firewall70:Policy:3: warning: Changing rule direction due to self reference # firewall70:Policy:4: warning: Changing rule direction due to self reference # firewall70:Policy:5: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.directed-broadcast=0 $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet.ip.sourceroute=0 $SYSCTL -w net.inet.ip.redirect=0 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:26 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall70.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall40-1-routes.conf.orig0000644000175000017500000000717411733011756023627 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall40-1:routes:1: error: Interface specification is required for action Route. # firewall40-1:routes:1: error: Only one router specified with load balancing for rule action Route: 'route_reply_through' # firewall40-1:routes:2: error: Interface specification is required for action Route. # firewall40-1:routes:2: error: Only one router specified with load balancing for rule action Route: 'route_copy_through' # firewall40-1:routes:6: error: Interface specification is required for action Route. # firewall40-1:routes:6: error: More than one router specified without load balancing for rule action Route: 'route_through' # firewall40-1:routes:7: error: Interface specification is required for action Route. # firewall40-1:routes:8: error: Interface specification is required for action Route. # firewall40-1:routes:9: error: Interface specification is required for action Route. # firewall40-1:routes:10: error: Interface specification is required for action Route. # # Rule routes 0 (fxp0) # route_through, load balancing random pass in quick on fxp0 route-to { ( le1 192.0.2.1 ) , ( le1 192.0.2.2 ) , ( le1 192.0.2.3 ) } random inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 0 -- ACCEPT " # # Rule routes 1 (fxp0) # error: interface is required pass in quick on fxp0 reply-to { ( 192.0.2.1 ) } random inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 1 -- ACCEPT " # # Rule routes 2 (fxp0) # error: interface is required pass in quick on fxp0 dup-to { ( 192.0.2.1 ) } random inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 2 -- ACCEPT " # # Rule routes 3 (fxp0) # fastroute pass in quick on fxp0 fastroute inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 3 -- ACCEPT " # # Rule routes 4 (fxp0) # fastroute pass in quick on fxp0 fastroute inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 4 -- ACCEPT " # # Rule routes 5 (fxp0) # fastroute pass in quick on fxp0 fastroute inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 5 -- ACCEPT " # # Rule routes 6 (fxp0) # route_through, load balancing none # error: interface is required pass in quick on fxp0 route-to { ( 192.0.2.1 ) , ( 192.0.2.2 ) , ( 192.0.2.3 ) } inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 6 -- ACCEPT " # # Rule routes 7 (fxp0) # route_through, load balancing bitmask # error: interface is required pass in quick on fxp0 route-to { ( 192.0.2.1 ) , ( 192.0.2.2 ) , ( 192.0.2.3 ) } bitmask inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 7 -- ACCEPT " # # Rule routes 8 (fxp0) # route_through, load balancing random # error: interface is required pass in quick on fxp0 route-to { ( 192.0.2.1 ) , ( 192.0.2.2 ) , ( 192.0.2.3 ) } random inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 8 -- ACCEPT " # # Rule routes 9 (fxp0) # route_through, load balancing source hash # error: interface is required pass in quick on fxp0 route-to { ( 192.0.2.1 ) , ( 192.0.2.2 ) , ( 192.0.2.3 ) } source-hash inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 9 -- ACCEPT " # # Rule routes 10 (fxp0) # route_through, load balancing round robin # error: interface is required pass in quick on fxp0 route-to { ( 192.0.2.1 ) , ( 192.0.2.2 ) , ( 192.0.2.3 ) } round-robin inet proto tcp from 192.168.1.0/24 to any port 80 keep state label "RULE 10 -- ACCEPT " # # Rule routes 11 (global) block log quick inet from any to any label "RULE 11 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall21-NAT_1.conf.orig0000644000175000017500000000017411733011756023002 0ustar sylvestresylvestre# # Rule NAT_1 0 (NAT) nat on en1 from 192.168.1.0/24 to any -> (en1) nat on en0 from 192.168.1.0/24 to any -> (en0) fwbuilder-5.1.0.3599/test/pf/firewall109-3.fw.orig0000755000175000017500000000161211733011756022061 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:10 2011 PST by vadim # # files: * firewall109-3.fw /etc/fw/pf.fw # files: firewall109-3.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # complex configuration with bridge and vlan, uses vlan interfaces with names not matching vlan IDs. rc.conf format gateway_enable="YES" cloned_interfaces="vlan8210 vlan9210 bridge0" network_interfaces="bridge0 em0" ifconfig_em0="10.3.14.81 netmask 0xffffff00" vlans_em1="vlan9210" create_args_vlan9210="vlan 210 vlandev em1" vlans_em2="vlan8210" create_args_vlan8210="vlan 210 vlandev em2" ifconfig_vlan8210="up" ifconfig_vlan9210="up" ifconfig_bridge0="addm vlan8210 -stp vlan8210 addm vlan9210 -stp vlan9210 up 192.168.1.1 netmask 0xffffff00" pf_enable="YES" pf_rules="/etc/fw/path\ with\ space/pf.conf" fwbuilder-5.1.0.3599/test/pf/firewall40.conf.orig0000644000175000017500000000206711733011756022146 0ustar sylvestresylvestre # # Rule 0 (NAT) # Translate source address # for outgoing connections nat on le1 from 192.168.1.0/24 to any -> (le1) # # Rule 1 (NAT) # Translate source address # for outgoing connections nat on le2 from 192.168.1.0/24 to any -> (le2) # # Rule 0 (lo0) pass quick on lo0 inet from any to any label "RULE 0 -- ACCEPT " # # Rule 1 (fxp0) pass quick on fxp0 inet from 192.168.1.0/24 to 192.168.1.0/24 label "RULE 1 -- ACCEPT " # # Rule 2 (fxp0) pass in quick on fxp0 route-to { ( le1 192.0.2.10 ) } inet proto tcp from 192.168.1.0/24 to any port { 80, 25 } label "RULE 2 -- ACCEPT " # # Rule 3 (fxp0) pass in quick on fxp0 route-to { ( le2 192.0.3.10 ) } inet proto tcp from 192.168.1.0/24 to any port 22 label "RULE 3 -- ACCEPT " # # Rule 4 (global) pass out quick inet from self to any keep state label "RULE 4 -- ACCEPT " # # Rule 5 (global) block log quick inet from any to any label "RULE 5 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall111.conf.orig0000644000175000017500000001325611733011756022227 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # Policy compiler errors and warnings: # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '8 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '9 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '18 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '19 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '20 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '21 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '30 (global)' below it # # Rule 0 (global) pass inet from any to any tag tag2 no state # # Rule 1 (global) pass inet from any to any tag tag2 # # Rule 2 (global) # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '18 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '19 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '20 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '21 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '30 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '7 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '8 (global)' below it # firewall111:Policy:2: error: Rule '2 (global)' shadows rule '9 (global)' below it pass quick inet from any to any tag tag2 # # Rule 3 (global) pass quick inet from any to any tag tag2 no state # # Rule 4 (global) pass inet from any to any tag tag2 no state # # Rule 5 (global) anchor "Policy_1" inet from any to any tag tag2 no state # # Rule 6 (global) pass inet from any to any no state queue ssh_q # # Rule 7 (global) pass inet from any to any queue ssh_q # # Rule 8 (global) pass quick inet from any to any queue ssh_q # # Rule 9 (global) pass quick inet from any to any no state queue ssh_q # # Rule 10 (global) pass inet from any to any no state queue ssh_q # # Rule 11 (global) anchor "Policy_1" inet from any to any no state queue ssh_q # # Rule 12 (global) pass in route-to { ( le0 192.168.1.100 ) } inet from any to any no state pass out route-to { ( le0 192.168.1.100 ) } inet from any to any no state # # Rule 13 (global) pass in route-to { ( le0 192.168.1.100 ) } inet from any to any pass out route-to { ( le0 192.168.1.100 ) } inet from any to any # # Rule 14 (global) pass in quick route-to { ( le0 192.168.1.100 ) } inet from any to any pass out quick route-to { ( le0 192.168.1.100 ) } inet from any to any # # Rule 15 (global) pass in quick route-to { ( le0 192.168.1.100 ) } inet from any to any no state pass out quick route-to { ( le0 192.168.1.100 ) } inet from any to any no state # # Rule 16 (global) pass in route-to { ( le0 192.168.1.100 ) } inet from any to any no state pass out route-to { ( le0 192.168.1.100 ) } inet from any to any no state # # Rule 17 (global) anchor "Policy_1" in route-to { ( le0 192.168.1.100 ) } inet from any to any no state anchor "Policy_1" out route-to { ( le0 192.168.1.100 ) } inet from any to any no state # # Rule 18 (global) pass inet from any to any tag tag2 no state queue ssh_q # # Rule 19 (global) pass inet from any to any tag tag2 queue ssh_q # # Rule 20 (global) pass quick inet from any to any tag tag2 queue ssh_q # # Rule 21 (global) pass quick inet from any to any tag tag2 no state queue ssh_q # # Rule 22 (global) pass inet from any to any tag tag2 no state queue ssh_q # # Rule 23 (global) anchor "Policy_1" inet from any to any tag tag2 no state queue ssh_q # # Rule 24 (global) pass in route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q pass out route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q # # Rule 25 (global) pass in route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 queue ssh_q pass out route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 queue ssh_q # # Rule 26 (global) pass in quick route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 queue ssh_q pass out quick route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 queue ssh_q # # Rule 27 (global) pass in quick route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q pass out quick route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q # # Rule 28 (global) pass in route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q pass out route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q # # Rule 29 (global) anchor "Policy_1" in route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q anchor "Policy_1" out route-to { ( le0 192.168.1.100 ) } inet from any to any tag tag2 no state queue ssh_q # # Rule 30 (global) block quick inet from any to any no state # # Rule fallback rule # fallback rule block quick inet from any to any no state load anchor Policy_1 from "/etc/fw/firewall111-Policy_1.conf" fwbuilder-5.1.0.3599/test/pf/firewall80.fw.orig0000755000175000017500000000231011733011756021633 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:27 2011 PST by vadim # # files: * firewall80.fw /etc/firewall80.fw # files: firewall80.conf /etc/firewall80.conf # # Compiled for pf ge_3.7 # # Testin state tracking options FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/sbin/pfctl" SYSCTL="/usr/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall80.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall22.fw.orig0000755000175000017500000000305411733011756021635 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:17 2011 PST by vadim # # files: * firewall22.fw /etc/fw/firewall22.fw # files: firewall22.conf /etc/fw/firewall22.conf # files: firewall22-NAT_1.conf /etc/fw/firewall22-NAT_1.conf # # Compiled for pf 4.3 # # branching in NAT rules # PF v4.3 and later # firewall22:ftp-proxy/*:: warning: The name of the NAT ruleset ftp-proxy/* ends with '/*', assuming it is externally controlled and skipping it. # firewall22:NAT:2: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/local/bin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:17 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall22.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall51-rule2_branch.conf.orig0000644000175000017500000000026711733011756024514 0ustar sylvestresylvestre # Tables: (1) table { 192.168.1.0/24 , 192.168.2.0/24 } # # Rule rule2_branch 0 (global) block log quick inet from ! to any fwbuilder-5.1.0.3599/test/pf/firewall33.conf.orig0000644000175000017500000000612311733011756022145 0ustar sylvestresylvestre # Tables: (4) table { 157.166.226.25 , 157.166.226.26 , 157.166.255.18 , 157.166.255.19 } table { www.google.com , 157.166.226.25 , 157.166.226.26 , 157.166.255.18 , 157.166.255.19 } table { www.google.com , www.cnn.com } table { 74.125.224.144 , 74.125.224.145 , 74.125.224.146 , 74.125.224.147 , 74.125.224.148 , 157.166.226.25 , 157.166.226.26 , 157.166.255.18 , 157.166.255.19 } # # Rule 0 (NAT) nat on eth0.100 from any to -> (eth0.100) # # Rule 1 (NAT) nat on eth0.100 from any to www.cnn.com -> (eth0.100) # # Rule 2 (NAT) nat on eth0.100 from any to -> (eth0.100) # # Rule 3 (NAT) nat on eth0.100 from any to ! -> (eth0.100) # Policy compiler errors and warnings: # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # # Rule 0 (global) pass quick inet from to any keep state label "RULE 0 -- ACCEPT on global " # # Rule 1 (global) pass quick inet from www.cnn.com to any keep state label "RULE 1 -- ACCEPT on global " # # Rule 2 (global) # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode pass quick inet from 192.0.2.1 to any keep state label "RULE 2 -- ACCEPT on global " # # Rule 3 (global) pass quick inet from buildmaster to any keep state label "RULE 3 -- ACCEPT on global " # # Rule 4 (global) block quick inet from any to ! label "RULE 4 -- DROP on global " # # Rule 5 (global) block quick inet from any to ! www.cnn.com label "RULE 5 -- DROP on global " # # Rule 6 (global) # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode pass quick inet from any to ! 192.0.2.1 keep state label "RULE 6 -- ACCEPT on global " # # Rule 7 (global) pass quick inet from any to ! buildmaster keep state label "RULE 7 -- ACCEPT on global " # # Rule 8 (global) pass quick inet from any to ! keep state label "RULE 8 -- ACCEPT on global " # # Rule 9 (global) pass quick inet from any to ! keep state label "RULE 9 -- ACCEPT on global " # # Rule 10 (global) pass quick inet from any to ! keep state label "RULE 10 -- ACCEPT on global " # # Rule 11 (global) block log quick inet from any to any label "RULE 11 -- DROP on global " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP on global " fwbuilder-5.1.0.3599/test/pf/cluster-tests.fwb0000644000175000017500000104203211733011756021705 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/test/pf/firewall2.fw.orig0000755000175000017500000000246111733011756021554 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:15 2011 PST by vadim # # files: * firewall2.fw /etc/fw/firewall2.fw # files: firewall2.conf /etc/fw/firewall2.conf # # Compiled for pf # # this object has several interfaces and shows different rules for NAT. Also testing policy rule options # firewall2:Policy:12: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:15 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall2.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall93.fw.orig0000755000175000017500000000732311733011756021650 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:29 2011 PST by vadim # # files: * firewall93.fw /etc/fw/pf.fw # files: firewall93.conf /etc/fw/path\ with\ space/pf.conf # # Compiled for pf 4.7 # # testing option т€œpreserve group and addresses table object namesт€ # firewall93:Policy:0: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "em0 10.3.14.81/0xffffff00" "" update_addresses_of_interface "em1 10.1.1.81/0xffffff00" "" } log "Activating firewall script generated Wed Nov 30 18:39:29 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall51.fw.orig0000755000175000017500000000323011733011756021633 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:23 2011 PST by vadim # # files: * firewall51.fw /etc/fw/firewall51.fw # files: firewall51.conf /etc/fw/firewall51.conf # files: firewall51-rule2_branch.conf /etc/fw/firewall51-rule2_branch.conf # files: firewall51-mail_server_inbound.conf /etc/fw/firewall51-mail_server_inbound.conf # files: firewall51-mail_server_outbound.conf /etc/fw/firewall51-mail_server_outbound.conf # files: firewall51-web_server_inbound.conf /etc/fw/firewall51-web_server_inbound.conf # files: firewall51-web_server_outbound.conf /etc/fw/firewall51-web_server_outbound.conf # # Compiled for pf # # testing branching rules that point # at rule sets defined in object # firewall-base-rulesets FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:23 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall51.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall80-4.5.fw.orig0000755000175000017500000000233311733011756022144 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:27 2011 PST by vadim # # files: * firewall80-4.5.fw /etc/firewall80-4.5.fw # files: firewall80-4.5.conf /etc/firewall80-4.5.conf # # Compiled for pf 4.5 # # Testin state tracking options FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/usr/sbin/pfctl" SYSCTL="/usr/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Wed Nov 30 18:39:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/firewall80-4.5.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall3.conf.orig0000644000175000017500000000234211733011756022061 0ustar sylvestresylvestre set optimization conservative # # Scrub rules # scrub in all no-df scrub out all random-id # # Prolog script # # prolog # prolog commands go after scrub commands # # End of prolog script # # # Rule 0 (NAT) nat on le0 from 192.168.1.0/24 to any -> 22.22.22.21 # # Rule 1 (NAT) nat on le0 from 192.168.1.0/24 to any -> (le0) bitmask # # Rule 2 (NAT) nat from 192.168.1.0/24 to any -> 22.22.22.0/28 source-hash # # Rule 3 (NAT) nat from 192.168.1.0/24 to any -> { 22.22.22.1 , 22.22.22.2/31 , 22.22.22.4 , 22.22.22.5 } round-robin static-port # # Rule 4 (NAT) rdr from any to 22.22.22.21 -> { 192.168.1.10 , 192.168.1.20 } round-robin # Policy compiler errors and warnings: # firewall3:Policy:0: warning: Changing rule direction due to self reference # # Rule 0 (global) # All other attempts to connect to # the firewall are denied and logged # firewall3:Policy:0: warning: Changing rule direction due to self reference block in log quick inet from any to self label "RULE 0 -- DROP " # # Rule 1 (global) pass quick inet from 192.168.1.0/24 to any keep state ( max 1000 ) label "RULE 1 -- ACCEPT " # # Rule fallback rule # fallback rule block quick inet from any to any label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall10-1.conf.orig0000644000175000017500000000136011733011756022274 0ustar sylvestresylvestre # # Scrub rules # scrub in all fragment reassemble # # Rule 1 (NAT) nat on eth0 from 192.168.1.0/24 to any -> (eth0) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 192.168.1.100 to self port 22 flags S/SA keep state # # Rule 0 (eth0) pass in quick on eth0 inet proto tcp from 192.168.1.0/24 to any port { 80, 22 } flags S/SA keep state # # Rule 1 (lo0) pass quick on lo0 inet from any to any # # Rule 2 (enc0) # via ipsec pass quick on enc0 inet proto tcp from 33.33.33.0/24 to 192.168.1.0/24 port 80 flags S/SA keep state # # Rule 3 (global) block log quick inet from any to any # # Rule fallback rule # fallback rule block quick inet from any to any fwbuilder-5.1.0.3599/test/pf/firewall33.fw.orig0000755000175000017500000001004511733011756021635 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v5.0.1.3591 # # Generated Wed Nov 30 18:39:18 2011 PST by vadim # # files: * firewall33.fw /etc/fw/firewall33.fw # files: firewall33.conf /etc/fw/firewall33.conf # # Compiled for pf # # testing DNSName object # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth1 192.168.1.100/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Wed Nov 30 18:39:18 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $PFCTL -f /etc/fw/firewall33.conf || exit 1 epilog_commandsfwbuilder-5.1.0.3599/test/pf/firewall103-2.conf.orig0000644000175000017500000000077211733011756022366 0ustar sylvestresylvestre set timeout udp.single 5 # # Scrub rules # scrub all reassemble tcp no-df scrub out all random-id min-ttl 1 max-mss 1460 # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/pf/firewall14-1.conf.orig0000644000175000017500000000076211733011756022305 0ustar sylvestresylvestre # # Scrub rules # match all scrub (reassemble tcp no-df ) match out all scrub (random-id min-ttl 64 max-mss 1460) # # Rule backup ssh access rule # backup ssh access rule pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT " # # Rule 0 (global) block log quick inet from any to any no state label "RULE 0 -- DROP " # # Rule fallback rule # fallback rule block quick inet from any to any no state label "RULE 10000 -- DROP " fwbuilder-5.1.0.3599/test/ipf/0000755000175000017500000000000011733011756016533 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/ipf/firewall1.fw.orig0000755000175000017500000000343211733011756021723 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:26 2011 PST by vadim # # files: * firewall1.fw /etc/ipf.fw # files: firewall1-ipf.conf /etc/fw/ipf.conf # files: firewall1-nat.conf /etc/fw/nat.conf # # Compiled for ipf # # this object is used to test all kinds of negation in policy rules # Currently negation in NAT is not supported for ipf, therefore all rules in NAT with # negation are disabled # firewall1:Policy:9: warning: Changing rule direction due to self reference # firewall1:Policy:9: warning: Changing rule direction due to self reference # firewall1:Policy:10: warning: Changing rule direction due to self reference # firewall1:Policy:12: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:26 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/fw/ipf.conf $IPNAT -f /etc/fw/nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall8-ipf.conf.orig0000755000175000017500000000154311733011756023020 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall8:Policy:0: warning: Changing rule direction due to self reference # # Rule 0 (global) # firewall8:Policy:0: warning: Changing rule direction due to self reference pass in quick proto tcp from any to 33.33.33.33 port = 22 flags S keep state pass in quick proto tcp from any to 33.33.33.34 port = 22 flags S keep state pass in quick proto tcp from any to 192.168.1.1 port = 22 flags S keep state # # Rule 1 (global) pass out quick proto tcp from any to 33.33.33.33 port = 22 flags S keep state pass out quick proto tcp from any to 33.33.33.34 port = 22 flags S keep state # # Rule 4 (global) block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/Makefile0000644000175000017500000000072411733011756020176 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) # CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_ipf -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_ipf -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/ipf/firewall8-nat.conf.orig0000755000175000017500000000467111733011756023031 0ustar sylvestresylvestre# # Rule 0 (NAT) map ppp0 from 192.168.1.0/24 to any -> 0/32 portmap tcp/udp auto map ppp0 from 192.168.1.0/24 to any -> 0/32 map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 # # Rule 1 (NAT) map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 # # Rule 2 (NAT) map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 # # Rule 3 (NAT) rdr ppp0 from any to any port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 4 (NAT) rdr ppp0 from any to any port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 5 (NAT) rdr ppp0 from any to any port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 6 (NAT) rdr ppp0 from any to any port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 7 (NAT) rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 8 (NAT) rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp fwbuilder-5.1.0.3599/test/ipf/run.all0000755000175000017500000000077511733011756020045 0ustar sylvestresylvestre#!/bin/sh XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipf -v -f $XMLFILE -xt $fwobj" done exit 0 XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipf -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/ipf/firewall4-ipf.conf.orig0000755000175000017500000000665011733011756023020 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall4:Policy:6: warning: Changing rule direction due to self reference # firewall4:Policy:6: warning: Changing rule direction due to self reference # # Rule 0 (eth1) # Anti-spoofing rule block in log quick on eth1 from 192.168.1.1 to any block in log quick on eth1 from 192.168.2.1 to any block in log quick on eth1 from 222.222.222.222 to any block in log quick on eth1 from 192.168.1.0/24 to any # # Rule 1 (eth1) # Anti-spoofing rule skip 4 out on eth1 from 192.168.1.1 to any skip 3 out on eth1 from 192.168.2.1 to any skip 2 out on eth1 from 222.222.222.222 to any skip 1 out on eth1 from 192.168.1.0/24 to any block out log quick on eth1 from any to any # # Rule 2 (eth1) block in log quick on eth1 proto icmp from any to any icmp-type 8 code 0 block out log quick on eth1 proto icmp from any to any icmp-type 8 code 0 # # Rule 3 (eth1) skip 1 in on eth1 proto icmp from 192.168.2.0/24 to any icmp-type 8 code 0 skip 1 out on eth1 proto icmp from 192.168.2.0/24 to any icmp-type 8 code 0 block in log quick on eth1 proto icmp from any to any icmp-type 8 code 0 block out log quick on eth1 proto icmp from any to any icmp-type 8 code 0 # # Rule 4 (global) # hostF has the same IP address as firewal. pass in log quick proto icmp from any to 192.168.1.1 icmp-type 8 code 0 keep state pass out log quick proto icmp from any to 192.168.1.1 icmp-type 8 code 0 keep state # # Rule 5 (global) # testing negation in the policy rule skip 2 in proto icmp from 192.168.1.10 to any icmp-type 3 skip 1 in proto icmp from 192.168.1.20 to any icmp-type 3 skip 2 out proto icmp from 192.168.1.10 to any icmp-type 3 skip 1 out proto icmp from 192.168.1.20 to any icmp-type 3 block in log quick proto icmp from any to any icmp-type 3 block out log quick proto icmp from any to any icmp-type 3 # # Rule 6 (global) # firewall4:Policy:6: warning: Changing rule direction due to self reference skip 8 in proto icmp from 192.168.1.10 to 192.168.1.1 icmp-type 3 skip 7 in proto icmp from 192.168.1.10 to 192.168.2.1 icmp-type 3 skip 6 in proto icmp from 192.168.1.10 to 222.222.222.222 icmp-type 3 skip 5 in proto icmp from 192.168.1.20 to 192.168.1.1 icmp-type 3 skip 4 in proto icmp from 192.168.1.20 to 192.168.2.1 icmp-type 3 skip 3 in proto icmp from 192.168.1.20 to 222.222.222.222 icmp-type 3 block in log quick proto icmp from any to 192.168.1.1 icmp-type 3 block in log quick proto icmp from any to 192.168.2.1 icmp-type 3 block in log quick proto icmp from any to 222.222.222.222 icmp-type 3 # # Rule 8 (global) # 'masquerading' rule pass in quick proto icmp from 192.168.1.0/24 to any keep state pass in quick proto tcp from 192.168.1.0/24 to any keep state pass in quick proto udp from 192.168.1.0/24 to any keep state pass in quick from 192.168.1.0/24 to any pass out quick proto icmp from 192.168.1.0/24 to any keep state pass out quick proto tcp from 192.168.1.0/24 to any keep state pass out quick proto udp from 192.168.1.0/24 to any keep state pass out quick from 192.168.1.0/24 to any # # Rule 10 (global) # 'catch all' rule block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall.fw.orig0000755000175000017500000001051111733011756021636 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:26 2011 PST by vadim # # files: * firewall.fw ipf.fw # files: firewall-ipf.conf ipf.conf # files: firewall-nat.conf nat.conf # # Compiled for ipf # # this is simple firewall with two interfaces. Test regular policy rules, including IP_fragments rule # firewall:Policy:4: warning: Changing rule direction due to self reference # firewall:Policy:8: warning: Changing rule direction due to self reference # firewall:Policy:19: warning: Changing rule direction due to self reference # firewall:Policy:19: warning: Changing rule direction due to self reference # firewall:Policy:20: warning: Changing rule direction due to self reference # firewall:Policy:: warning: ipfilter can not match "any IP option" # firewall:Policy:: warning: ipfilter can not match "any IP option" FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth0 192.168.1.1/0xffffff00" "" update_addresses_of_interface "eth1 222.222.222.222/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Sat Mar 12 19:44:26 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f ipf.conf $IPNAT -f nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall5.fw.orig0000755000175000017500000000337511733011756021735 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:27 2011 PST by vadim # # files: * firewall5.fw /etc/firewall5.fw # files: firewall5-ipf.conf /etc/firewall5-ipf.conf # files: firewall5-nat.conf /etc/firewall5-nat.conf # # Compiled for ipf # # Dynamic interface ppp0 # firewall5:Policy:0: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } getaddr() { intf=$1 varname=$2 L=`ifconfig $1 | grep 'inet '` if [ -z "$L" ]; then L="inet 0.0.0.0/32" fi set $L a=$2 eval "$varname=$a" } getaddr ppp0 i_ppp0 verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C cat /etc/firewall5-ipf.conf | grep -v '#' | sed "s/ (ppp0) / $i_ppp0 /" | $IPF -I -f - cat /etc/firewall5-nat.conf | grep -v '#' | sed "s/ (ppp0) / $i_ppp0 /" | $IPNAT -f - $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall1-ipf.conf.orig0000755000175000017500000002324511733011756023014 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall1:Policy:9: warning: Changing rule direction due to self reference # firewall1:Policy:9: warning: Changing rule direction due to self reference # firewall1:Policy:10: warning: Changing rule direction due to self reference # firewall1:Policy:12: warning: Changing rule direction due to self reference # # Rule 0 (eth0) skip 11 in on eth0 proto icmp from 22.22.22.22 to 22.22.22.22 skip 10 in on eth0 proto icmp from 22.22.22.22 to 192.168.1.1 skip 9 in on eth0 proto icmp from 192.168.1.1 to 22.22.22.22 skip 8 in on eth0 proto icmp from 192.168.1.1 to 192.168.1.1 skip 7 in on eth0 proto 50 from 22.22.22.22 to 22.22.22.22 skip 6 in on eth0 proto 50 from 22.22.22.22 to 192.168.1.1 skip 5 in on eth0 proto 50 from 192.168.1.1 to 22.22.22.22 skip 4 in on eth0 proto 50 from 192.168.1.1 to 192.168.1.1 skip 11 out on eth0 proto icmp from 22.22.22.22 to 22.22.22.22 skip 10 out on eth0 proto icmp from 22.22.22.22 to 192.168.1.1 skip 9 out on eth0 proto icmp from 192.168.1.1 to 22.22.22.22 skip 8 out on eth0 proto icmp from 192.168.1.1 to 192.168.1.1 skip 7 out on eth0 proto 50 from 22.22.22.22 to 22.22.22.22 skip 6 out on eth0 proto 50 from 22.22.22.22 to 192.168.1.1 skip 5 out on eth0 proto 50 from 192.168.1.1 to 22.22.22.22 skip 4 out on eth0 proto 50 from 192.168.1.1 to 192.168.1.1 block in log quick on eth0 proto icmp from 22.22.22.22 to any block in log quick on eth0 proto icmp from 192.168.1.1 to any block in log quick on eth0 proto 50 from 22.22.22.22 to any block in log quick on eth0 proto 50 from 192.168.1.1 to any block out log quick on eth0 proto icmp from 22.22.22.22 to any block out log quick on eth0 proto icmp from 192.168.1.1 to any block out log quick on eth0 proto 50 from 22.22.22.22 to any block out log quick on eth0 proto 50 from 192.168.1.1 to any # # Rule 1 (eth0) skip 11 in on eth0 proto icmp from 192.168.1.10 to 192.168.1.10 skip 10 in on eth0 proto icmp from 192.168.1.10 to 192.168.1.20 skip 9 in on eth0 proto icmp from 192.168.1.20 to 192.168.1.10 skip 8 in on eth0 proto icmp from 192.168.1.20 to 192.168.1.20 skip 7 in on eth0 proto 50 from 192.168.1.10 to 192.168.1.10 skip 6 in on eth0 proto 50 from 192.168.1.10 to 192.168.1.20 skip 5 in on eth0 proto 50 from 192.168.1.20 to 192.168.1.10 skip 4 in on eth0 proto 50 from 192.168.1.20 to 192.168.1.20 skip 11 out on eth0 proto icmp from 192.168.1.10 to 192.168.1.10 skip 10 out on eth0 proto icmp from 192.168.1.10 to 192.168.1.20 skip 9 out on eth0 proto icmp from 192.168.1.20 to 192.168.1.10 skip 8 out on eth0 proto icmp from 192.168.1.20 to 192.168.1.20 skip 7 out on eth0 proto 50 from 192.168.1.10 to 192.168.1.10 skip 6 out on eth0 proto 50 from 192.168.1.10 to 192.168.1.20 skip 5 out on eth0 proto 50 from 192.168.1.20 to 192.168.1.10 skip 4 out on eth0 proto 50 from 192.168.1.20 to 192.168.1.20 block in quick on eth0 proto icmp from 192.168.1.10 to any block in quick on eth0 proto icmp from 192.168.1.20 to any block in quick on eth0 proto 50 from 192.168.1.10 to any block in quick on eth0 proto 50 from 192.168.1.20 to any block out quick on eth0 proto icmp from 192.168.1.10 to any block out quick on eth0 proto icmp from 192.168.1.20 to any block out quick on eth0 proto 50 from 192.168.1.10 to any block out quick on eth0 proto 50 from 192.168.1.20 to any # # Rule 2 (eth1) # Anti-spoofing rule block in log quick on eth1 from 22.22.22.22 to any block in log quick on eth1 from 22.22.23.23 to any block in log quick on eth1 from 192.168.1.1 to any block in log quick on eth1 from 192.168.2.1 to any block in log quick on eth1 from 192.168.1.0/24 to any # # Rule 3 (eth1) # Anti-spoofing rule skip 1 out on eth1 from 192.168.1.0/24 to any block out log quick on eth1 from any to any # # Rule 4 (lo) pass in quick on lo proto icmp from any to any keep state pass in quick on lo proto tcp from any to any keep state pass in quick on lo proto udp from any to any keep state pass in quick on lo from any to any pass out quick on lo proto icmp from any to any keep state pass out quick on lo proto tcp from any to any keep state pass out quick on lo proto udp from any to any keep state pass out quick on lo from any to any # # Rule 5 (global) block in log quick proto tcp from any to any flags S/UAPRSF block out log quick proto tcp from any to any flags S/UAPRSF # # Rule 7 (global) # hostF has the same IP address as firewal. pass in log quick proto icmp from any to 192.168.1.1 icmp-type 8 code 0 keep state pass out log quick proto icmp from any to 192.168.1.1 icmp-type 8 code 0 keep state # # Rule 8 (global) # testing negation in the policy rule skip 2 in proto icmp from 192.168.1.10 to any icmp-type 3 skip 1 in proto icmp from 192.168.1.20 to any icmp-type 3 skip 2 out proto icmp from 192.168.1.10 to any icmp-type 3 skip 1 out proto icmp from 192.168.1.20 to any icmp-type 3 block in log quick proto icmp from any to any icmp-type 3 block out log quick proto icmp from any to any icmp-type 3 # # Rule 9 (global) # firewall1:Policy:9: warning: Changing rule direction due to self reference skip 11 in proto icmp from 192.168.1.10 to 22.22.22.22 icmp-type 3 skip 10 in proto icmp from 192.168.1.10 to 22.22.23.23 icmp-type 3 skip 9 in proto icmp from 192.168.1.10 to 192.168.1.1 icmp-type 3 skip 8 in proto icmp from 192.168.1.10 to 192.168.2.1 icmp-type 3 skip 7 in proto icmp from 192.168.1.20 to 22.22.22.22 icmp-type 3 skip 6 in proto icmp from 192.168.1.20 to 22.22.23.23 icmp-type 3 skip 5 in proto icmp from 192.168.1.20 to 192.168.1.1 icmp-type 3 skip 4 in proto icmp from 192.168.1.20 to 192.168.2.1 icmp-type 3 block in log quick proto icmp from any to 22.22.22.22 icmp-type 3 block in log quick proto icmp from any to 22.22.23.23 icmp-type 3 block in log quick proto icmp from any to 192.168.1.1 icmp-type 3 block in log quick proto icmp from any to 192.168.2.1 icmp-type 3 # # Rule 10 (global) # firewall1:Policy:10: warning: Changing rule direction due to self reference skip 5 out from 22.22.22.22 to 192.168.1.0/24 skip 4 out from 22.22.23.23 to 192.168.1.0/24 skip 3 out from 192.168.1.1 to 192.168.1.0/24 skip 2 out from 192.168.2.1 to 192.168.1.0/24 skip 1 in from 192.168.2.0/24 to 192.168.1.0/24 skip 1 out from 192.168.2.0/24 to 192.168.1.0/24 block in log quick from any to 192.168.1.0/24 block out log quick from any to 192.168.1.0/24 # # Rule 11 (global) skip 5 in from 192.168.1.0/24 to 192.168.1.10 skip 4 in from 192.168.1.0/24 to 192.168.1.20 skip 3 in from 192.168.2.0/24 to 192.168.1.10 skip 2 in from 192.168.2.0/24 to 192.168.1.20 skip 5 out from 192.168.1.0/24 to 192.168.1.10 skip 4 out from 192.168.1.0/24 to 192.168.1.20 skip 3 out from 192.168.2.0/24 to 192.168.1.10 skip 2 out from 192.168.2.0/24 to 192.168.1.20 block in log quick from 192.168.1.0/24 to any block in log quick from 192.168.2.0/24 to any block out log quick from 192.168.1.0/24 to any block out log quick from 192.168.2.0/24 to any # # Rule 12 (global) # firewall1:Policy:12: warning: Changing rule direction due to self reference skip 4 in from any to 22.22.22.22 skip 3 in from any to 22.22.23.23 skip 2 in from any to 192.168.1.1 skip 1 in from any to 192.168.2.1 block in quick from any to any block out quick from any to any # # Rule 15 (global) skip 11 in proto icmp from 22.22.22.22 to 22.22.22.22 skip 10 in proto icmp from 22.22.22.22 to 192.168.1.1 skip 9 in proto icmp from 192.168.1.1 to 22.22.22.22 skip 8 in proto icmp from 192.168.1.1 to 192.168.1.1 skip 7 in proto 50 from 22.22.22.22 to 22.22.22.22 skip 6 in proto 50 from 22.22.22.22 to 192.168.1.1 skip 5 in proto 50 from 192.168.1.1 to 22.22.22.22 skip 4 in proto 50 from 192.168.1.1 to 192.168.1.1 skip 11 out proto icmp from 22.22.22.22 to 22.22.22.22 skip 10 out proto icmp from 22.22.22.22 to 192.168.1.1 skip 9 out proto icmp from 192.168.1.1 to 22.22.22.22 skip 8 out proto icmp from 192.168.1.1 to 192.168.1.1 skip 7 out proto 50 from 22.22.22.22 to 22.22.22.22 skip 6 out proto 50 from 22.22.22.22 to 192.168.1.1 skip 5 out proto 50 from 192.168.1.1 to 22.22.22.22 skip 4 out proto 50 from 192.168.1.1 to 192.168.1.1 block in log quick proto icmp from 22.22.22.22 to any block in log quick proto icmp from 192.168.1.1 to any block in log quick proto 50 from 22.22.22.22 to any block in log quick proto 50 from 192.168.1.1 to any block out log quick proto icmp from 22.22.22.22 to any block out log quick proto icmp from 192.168.1.1 to any block out log quick proto 50 from 22.22.22.22 to any block out log quick proto 50 from 192.168.1.1 to any # # Rule 16 (global) # 'masquerading' rule pass in quick proto icmp from 192.168.1.0/24 to any keep state pass in quick proto tcp from 192.168.1.0/24 to any keep state pass in quick proto udp from 192.168.1.0/24 to any keep state pass in quick from 192.168.1.0/24 to any pass out quick proto icmp from 192.168.1.0/24 to any keep state pass out quick proto tcp from 192.168.1.0/24 to any keep state pass out quick proto udp from 192.168.1.0/24 to any keep state pass out quick from 192.168.1.0/24 to any # # Rule 17 (global) # 'catch all' rule block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/do-diff0000755000175000017500000000025211733011756017770 0ustar sylvestresylvestre#!/bin/sh T=$1 N=$2 if which opendiff > /dev/null; then TOOL="opendiff" else TOOL="tkdiff -b -B " fi ${TOOL} firewall${N}-${T}.conf.orig firewall${N}-${T}.conf fwbuilder-5.1.0.3599/test/ipf/host-ipf.conf.orig0000755000175000017500000001332511733011756022101 0ustar sylvestresylvestre# Policy compiler errors and warnings: # host:Policy:4: warning: Changing rule direction due to self reference # host:Policy:5: warning: Changing rule direction due to self reference # host:Policy:6: warning: Changing rule direction due to self reference # # Rule 0 (eth0) pass in log quick on eth0 proto icmp from 22.22.22.22 to 22.22.22.22 keep state pass in log quick on eth0 proto tcp from 22.22.22.22 to 22.22.22.22 keep state pass in log quick on eth0 proto udp from 22.22.22.22 to 22.22.22.22 keep state pass in log quick on eth0 from 22.22.22.22 to 22.22.22.22 pass out log quick on eth0 proto icmp from 22.22.22.22 to 22.22.22.22 keep state pass out log quick on eth0 proto tcp from 22.22.22.22 to 22.22.22.22 keep state pass out log quick on eth0 proto udp from 22.22.22.22 to 22.22.22.22 keep state pass out log quick on eth0 from 22.22.22.22 to 22.22.22.22 # # Rule 1 (lo) # allow everything on loopback pass in quick on lo proto icmp from any to 22.22.22.22 keep state pass in quick on lo proto icmp from any to 127.0.0.1 keep state pass in quick on lo proto tcp from any to 22.22.22.22 keep state pass in quick on lo proto tcp from any to 127.0.0.1 keep state pass in quick on lo proto udp from any to 22.22.22.22 keep state pass in quick on lo proto udp from any to 127.0.0.1 keep state pass in quick on lo from any to 22.22.22.22 pass in quick on lo from any to 127.0.0.1 # # Rule 2 (lo) # allow everything on loopback pass out quick on lo proto icmp from 22.22.22.22 to any keep state pass out quick on lo proto icmp from 127.0.0.1 to any keep state pass out quick on lo proto tcp from 22.22.22.22 to any keep state pass out quick on lo proto tcp from 127.0.0.1 to any keep state pass out quick on lo proto udp from 22.22.22.22 to any keep state pass out quick on lo proto udp from 127.0.0.1 to any keep state pass out quick on lo from 22.22.22.22 to any pass out quick on lo from 127.0.0.1 to any # # Rule 3 (lo) pass in log quick on lo proto icmp from 22.22.22.22 to 22.22.22.22 keep state pass in log quick on lo proto icmp from 22.22.22.22 to 127.0.0.1 keep state pass in log quick on lo proto icmp from 127.0.0.1 to 22.22.22.22 keep state pass in log quick on lo proto icmp from 127.0.0.1 to 127.0.0.1 keep state pass in log quick on lo proto tcp from 22.22.22.22 to 22.22.22.22 keep state pass in log quick on lo proto tcp from 22.22.22.22 to 127.0.0.1 keep state pass in log quick on lo proto tcp from 127.0.0.1 to 22.22.22.22 keep state pass in log quick on lo proto tcp from 127.0.0.1 to 127.0.0.1 keep state pass in log quick on lo proto udp from 22.22.22.22 to 22.22.22.22 keep state pass in log quick on lo proto udp from 22.22.22.22 to 127.0.0.1 keep state pass in log quick on lo proto udp from 127.0.0.1 to 22.22.22.22 keep state pass in log quick on lo proto udp from 127.0.0.1 to 127.0.0.1 keep state pass in log quick on lo from 22.22.22.22 to 22.22.22.22 pass in log quick on lo from 22.22.22.22 to 127.0.0.1 pass in log quick on lo from 127.0.0.1 to 22.22.22.22 pass in log quick on lo from 127.0.0.1 to 127.0.0.1 pass out log quick on lo proto icmp from 22.22.22.22 to 22.22.22.22 keep state pass out log quick on lo proto icmp from 22.22.22.22 to 127.0.0.1 keep state pass out log quick on lo proto icmp from 127.0.0.1 to 22.22.22.22 keep state pass out log quick on lo proto icmp from 127.0.0.1 to 127.0.0.1 keep state pass out log quick on lo proto tcp from 22.22.22.22 to 22.22.22.22 keep state pass out log quick on lo proto tcp from 22.22.22.22 to 127.0.0.1 keep state pass out log quick on lo proto tcp from 127.0.0.1 to 22.22.22.22 keep state pass out log quick on lo proto tcp from 127.0.0.1 to 127.0.0.1 keep state pass out log quick on lo proto udp from 22.22.22.22 to 22.22.22.22 keep state pass out log quick on lo proto udp from 22.22.22.22 to 127.0.0.1 keep state pass out log quick on lo proto udp from 127.0.0.1 to 22.22.22.22 keep state pass out log quick on lo proto udp from 127.0.0.1 to 127.0.0.1 keep state pass out log quick on lo from 22.22.22.22 to 22.22.22.22 pass out log quick on lo from 22.22.22.22 to 127.0.0.1 pass out log quick on lo from 127.0.0.1 to 22.22.22.22 pass out log quick on lo from 127.0.0.1 to 127.0.0.1 # # Rule 4 (global) # block fragments # host:Policy:4: warning: Changing rule direction due to self reference block in log quick from any to 22.22.22.22 with short # # Rule 5 (global) # host:Policy:5: warning: Changing rule direction due to self reference pass in quick proto icmp from any to 22.22.22.22 icmp-type 3 keep state pass in quick proto tcp from any to 22.22.22.22 port = 21 keep state pass in quick proto tcp from any to 22.22.22.22 port = 80 keep state pass in quick proto tcp from any to 22.22.22.22 port = 25 keep state pass in quick proto tcp from any to 22.22.22.22 port = 22 keep state pass in quick proto tcp from any to 22.22.22.22 port = 23 keep state # # Rule 6 (global) # allow all outgoing connections # host:Policy:6: warning: Changing rule direction due to self reference pass out quick proto icmp from 22.22.22.22 to any keep state pass out quick proto tcp from 22.22.22.22 to any keep state pass out quick proto udp from 22.22.22.22 to any keep state pass out quick from 22.22.22.22 to any # # Rule 7 (global) # 'catch all' rule block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/addr-table-1.tbl0000644000175000017500000000030411733011756021370 0ustar sylvestresylvestre# this is a comment # ; this should be a comment too ; 192.168.1.1 192.168.1.2/32 192.168.1.3/30 192.168.2.128/25 192.168.1.200/32 # comment again 192.168.1.201/32 # this should work, too fwbuilder-5.1.0.3599/test/ipf/firewall4-nat.conf.orig0000755000175000017500000000450411733011756023020 0ustar sylvestresylvestre# # Rule 0 (NAT) map eth1 from 192.168.1.10/32 to any -> 0/32 portmap tcp/udp auto map eth1 from 192.168.1.10/32 to any -> 0/32 map eth0 from 192.168.1.10/32 to any -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.10/32 to any -> 192.168.1.1/32 map eth2 from 192.168.1.10/32 to any -> 192.168.2.1/32 portmap tcp/udp auto map eth2 from 192.168.1.10/32 to any -> 192.168.2.1/32 map eth3 from 192.168.1.10/32 to any -> 222.222.222.222/32 portmap tcp/udp auto map eth3 from 192.168.1.10/32 to any -> 222.222.222.222/32 # # Rule 1 (NAT) map eth3 from 192.168.1.10/32 to any -> 222.222.222.222/32 portmap tcp/udp auto map eth3 from 192.168.1.10/32 to any -> 222.222.222.222/32 # # Rule 2 (NAT) map eth3 from 192.168.1.10/32 to any -> 222.222.222.222/32 portmap tcp/udp auto map eth3 from 192.168.1.10/32 to any -> 222.222.222.222/32 # # Rule 3 (NAT) map eth1 from 192.168.1.10/32 to any -> 0/32 portmap tcp/udp auto map eth1 from 192.168.1.10/32 to any -> 0/32 # # Rule 5 (NAT) rdr eth1 from any to any port = 22 -> 192.168.1.10 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.10 port 22 tcp rdr eth2 from any to 192.168.2.1/32 port = 22 -> 192.168.1.10 port 22 tcp rdr eth3 from any to 222.222.222.222/32 port = 22 -> 192.168.1.10 port 22 tcp # # Rule 6 (NAT) rdr eth0 from 192.168.1.0/24 to any port = 80 -> 192.168.2.1 port 3128 tcp rdr eth0 from 192.168.1.0/24 to any port = 443 -> 192.168.2.1 port 3128 tcp # # Rule 7 (NAT) rdr eth0 from 192.168.1.0/24 to any port = 80 -> 192.168.2.1 port 3128 tcp rdr eth0 from 192.168.1.0/24 to any port = 443 -> 192.168.2.1 port 3128 tcp # # Rule 8 (NAT) rdr eth0 from any to any port = 80 -> 192.168.1.1 port 3128 tcp rdr eth1 from any to any port = 80 -> 0/32 port 3128 tcp rdr eth2 from any to any port = 80 -> 192.168.2.1 port 3128 tcp rdr eth3 from any to any port = 80 -> 222.222.222.222 port 3128 tcp rdr eth0 from any to any port = 443 -> 192.168.1.1 port 3128 tcp rdr eth1 from any to any port = 443 -> 0/32 port 3128 tcp rdr eth2 from any to any port = 443 -> 192.168.2.1 port 3128 tcp rdr eth3 from any to any port = 443 -> 222.222.222.222 port 3128 tcp # # Rule 10 (NAT) map eth1 from any to any -> 0/32 proxy port 514 rcmd/tcp # # Rule 11 (NAT) map eth1 from 192.168.1.0/24 to any -> 0/32 proxy port 21 ftp/tcp fwbuilder-5.1.0.3599/test/ipf/firewall5-ipf.conf.orig0000755000175000017500000000202311733011756023007 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall5:Policy:0: warning: Changing rule direction due to self reference # # Rule 0 (global) # firewall5:Policy:0: warning: Changing rule direction due to self reference pass in quick proto tcp from any to 33.33.33.33 port = 22 flags S keep state pass in quick proto tcp from any to 33.33.33.34 port = 22 flags S keep state pass in quick proto tcp from any to 192.168.1.1 port = 22 flags S keep state # # Rule 1 (global) pass in quick proto tcp from any to (ppp0) port = 22 flags S keep state pass out quick proto tcp from any to (ppp0) port = 22 flags S keep state # # Rule 2 (global) pass out quick proto tcp from any to 33.33.33.33 port = 22 flags S keep state pass out quick proto tcp from any to 33.33.33.34 port = 22 flags S keep state # # Rule 5 (global) block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/quick-cmp.sh0000755000175000017500000000061011733011756020760 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -B -w -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipf v' -I 'Can not find file' -I '====' -I 'log '" for f in $(ls *.fw.orig *.conf.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done fwbuilder-5.1.0.3599/test/ipf/firewall7-ipf.conf.orig0000755000175000017500000000115011733011756023011 0ustar sylvestresylvestre# # Rule 0 (eth0) block in log quick on eth0 from any to 192.168.1.255 # # Rule 1 (eth1) block in log quick on eth1 from any to 22.22.22.22 block in log quick on eth1 from any to 22.22.23.23 block in log quick on eth1 from any to 192.168.1.1 block in log quick on eth1 from any to 192.168.2.1 # # Rule 2 (global) pass in quick proto udp from any to 192.168.1.255 port = 68 keep state pass out quick proto udp from any to 192.168.1.255 port = 68 keep state # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall1-nat.conf.orig0000755000175000017500000000257511733011756023023 0ustar sylvestresylvestre# # Rule 1 (NAT) map eth0 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth1 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth2 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth3 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth0 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth1 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth2 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth3 from 192.168.1.10/32 to any -> 22.22.22.23/32 # # Rule 3 (NAT) map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 map eth2 from 192.168.1.0/24 to any -> 192.168.2.1/32 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to any -> 192.168.2.1/32 # # Rule 4 (NAT) map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 fwbuilder-5.1.0.3599/test/ipf/firewall5-nat.conf.orig0000755000175000017500000000470511733011756023024 0ustar sylvestresylvestre# # Rule 0 (NAT) map ppp0 from 192.168.1.0/24 to any -> 0/32 portmap tcp/udp auto map ppp0 from 192.168.1.0/24 to any -> 0/32 map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 # # Rule 1 (NAT) map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.34/32 # # Rule 2 (NAT) map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 33.33.33.33/32 # # Rule 3 (NAT) rdr ppp0 from any to (ppp0) port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 4 (NAT) rdr ppp0 from any to (ppp0) port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 5 (NAT) rdr ppp0 from any to (ppp0) port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 6 (NAT) rdr ppp0 from any to (ppp0) port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 7 (NAT) rdr eth1 from any to 33.33.33.33/32 port = 22 -> 192.168.1.100 port 22 tcp rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 8 (NAT) rdr eth1 from any to 33.33.33.34/32 port = 22 -> 192.168.1.100 port 22 tcp fwbuilder-5.1.0.3599/test/ipf/host.fw.orig0000755000175000017500000000275411733011756021020 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:28 2011 PST by vadim # # files: * host.fw /etc/fw/host.fw # files: host-ipf.conf /etc/fw/host-ipf.conf # # Compiled for ipf # # firewall protects host it is running on # host:Policy:4: warning: Changing rule direction due to self reference # host:Policy:5: warning: Changing rule direction due to self reference # host:Policy:6: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:28 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/fw/host-ipf.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall34.fw.orig0000755000175000017500000000742611733011756022020 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:27 2011 PST by vadim # # files: * firewall34.fw /etc/fw/firewall34.fw # files: firewall34-ipf.conf /etc/fw/firewall34-ipf.conf # files: firewall34-nat.conf /etc/fw/firewall34-nat.conf # # Compiled for ipf # # testing AddressTable object FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth1 192.168.1.100/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Sat Mar 12 19:44:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/fw/firewall34-ipf.conf $IPNAT -f /etc/fw/firewall34-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall9-nat.conf.orig0000755000175000017500000000273511733011756023031 0ustar sylvestresylvestre# # Rule 0 (NAT) map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 map le0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map le0 from 192.168.1.0/24 to any -> 192.168.1.1/32 # # Rule 1 (NAT) map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 # # Rule 2 (NAT) map le0 from 192.168.1.0/24 to any -> 0/0 # # Rule 3 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 4 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 5 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.1 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.1 port 22 tcp # # Rule 6 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 7 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 8 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.1 port 22 tcp # # Rule 9 (NAT) rdr le0 from any to any port = 22 -> 192.168.1.100 port 22 tcp rdr le1 from any to any port = 22 -> 192.168.1.100 port 22 tcp fwbuilder-5.1.0.3599/test/ipf/firewall9.fw.orig0000755000175000017500000000270311733011756021733 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:28 2011 PST by vadim # # files: * firewall9.fw /etc/firewall9.fw # files: firewall9-ipf.conf /etc/firewall9-ipf.conf # files: firewall9-nat.conf /etc/firewall9-nat.conf # # Compiled for ipf # # firewall9:Policy:5: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:28 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/firewall9-ipf.conf $IPNAT -f /etc/firewall9-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall35-nat.conf.orig0000755000175000017500000000273511733011756023110 0ustar sylvestresylvestre# # Rule 0 (NAT) map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 map le0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map le0 from 192.168.1.0/24 to any -> 192.168.1.1/32 # # Rule 1 (NAT) map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map le1 from 192.168.1.0/24 to any -> 22.22.22.22/32 # # Rule 2 (NAT) map le0 from 192.168.1.0/24 to any -> 0/0 # # Rule 3 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 4 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 5 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.1 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.1 port 22 tcp # # Rule 6 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp rdr le0 from any to 192.168.1.1/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 7 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.100 port 22 tcp # # Rule 8 (NAT) rdr le1 from any to 22.22.22.22/32 port = 22 -> 192.168.1.1 port 22 tcp # # Rule 9 (NAT) rdr le0 from any to any port = 22 -> 192.168.1.100 port 22 tcp rdr le1 from any to any port = 22 -> 192.168.1.100 port 22 tcp fwbuilder-5.1.0.3599/test/ipf/firewall11-nat.conf.orig0000755000175000017500000000022411733011756023071 0ustar sylvestresylvestre# # Rule 0 (NAT) rdr ng0 from any to any -> 10.0.0.1 ip rdr ng1 from any to any -> 10.0.0.1 ip rdr fxp0 from any to 10.0.0.1/32 -> 10.0.0.1 ip fwbuilder-5.1.0.3599/test/ipf/firewall8.fw.orig0000755000175000017500000000270311733011756021732 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:28 2011 PST by vadim # # files: * firewall8.fw /etc/firewall8.fw # files: firewall8-ipf.conf /etc/firewall8-ipf.conf # files: firewall8-nat.conf /etc/firewall8-nat.conf # # Compiled for ipf # # firewall8:Policy:0: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:28 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/firewall8-ipf.conf $IPNAT -f /etc/firewall8-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall10.fw.orig0000755000175000017500000000256011733011756022004 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:26 2011 PST by vadim # # files: * firewall10.fw /etc/firewall10.fw # files: firewall10-ipf.conf /etc/firewall10-ipf.conf # # Compiled for ipf # # firewall10:Policy:2: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:26 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/firewall10-ipf.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall-nat.conf.orig0000755000175000017500000000174011733011756022733 0ustar sylvestresylvestre# # Rule 0 (NAT) # comment : rule 0 map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 map eth1 from 192.168.1.0/24 to any -> 222.222.222.222/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 222.222.222.222/32 # # Rule 1 (NAT) rdr eth0 from any to 192.168.1.1/32 port = 25 -> 192.168.1.10 port 25 tcp rdr eth1 from any to 222.222.222.222/32 port = 25 -> 192.168.1.10 port 25 tcp # # Rule 2 (NAT) rdr eth1 from any to any port = 80 -> 222.222.222.222 port 3128 tcp rdr eth0 from any to any port = 80 -> 192.168.1.1 port 3128 tcp # # Rule 3 (NAT) rdr eth0 from 192.168.1.0/24 to any port = 80 -> 192.168.1.1 port 3128 tcp rdr eth0 from 192.168.1.0/24 to any port = 443 -> 192.168.1.1 port 3128 tcp # # Rule 4 (NAT) rdr eth0 from 192.168.1.0/24 to any port = 80 -> 222.222.222.222 port 3128 tcp rdr eth0 from 192.168.1.0/24 to any port = 443 -> 222.222.222.222 port 3128 tcp fwbuilder-5.1.0.3599/test/ipf/recycle0000755000175000017500000000025211733011756020106 0ustar sylvestresylvestre#!/bin/sh for f in *.fw; do j=${f}.orig mv $f $j done for f in *-ipf.conf; do j=${f}.orig mv $f $j done for f in *-nat.conf; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/ipf/firewall34-nat.conf.orig0000755000175000017500000000000011733011756023066 0ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/ipf/firewall11.fw.orig0000755000175000017500000000760111733011756022006 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:26 2011 PST by vadim # # files: * firewall11.fw /etc/firewall11.fw # files: firewall11-ipf.conf /etc/firewall11-ipf.conf # files: firewall11-nat.conf /etc/firewall11-nat.conf # # Compiled for ipf # # firewall11:Policy:1: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "fxp0 10.0.0.1/0xffffff00" "" update_addresses_of_interface "fxp1" "" update_addresses_of_interface "lo0 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Sat Mar 12 19:44:26 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/firewall11-ipf.conf $IPNAT -f /etc/firewall11-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall-ipf.conf.orig0000755000175000017500000006632711733011756022743 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall:Policy:4: warning: Changing rule direction due to self reference # firewall:Policy:8: warning: Changing rule direction due to self reference # firewall:Policy:19: warning: Changing rule direction due to self reference # firewall:Policy:19: warning: Changing rule direction due to self reference # firewall:Policy:20: warning: Changing rule direction due to self reference # firewall:Policy:: warning: ipfilter can not match "any IP option" # firewall:Policy:: warning: ipfilter can not match "any IP option" # # Rule backup ssh access rule # backup ssh access rule pass in quick proto tcp from 192.168.1.100 to 192.168.1.1 port = 22 flags S keep state pass in quick proto tcp from 192.168.1.100 to 222.222.222.222 port = 22 flags S keep state # # Rule 0 (eth1) block in log level local0.warning quick on eth1 from any to 192.168.1.1 with short block in log level local0.warning quick on eth1 from any to 222.222.222.222 with short # # Rule 1 (eth1) # Automatically generated rule blocking short fragments block in log level local0.warning quick on eth1 from any to any with short # # Rule 2 (eth1) # Automatically generated anti-spoofing rule block in log level local0.warning quick on eth1 from 192.168.1.1 to any block in log level local0.warning quick on eth1 from 222.222.222.222 to any block in log level local0.warning quick on eth1 from 192.168.1.0/24 to any # # Rule 3 (eth1) # аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ pass in quick on eth1 proto icmp from 22.22.22.0/24 to any keep state pass in quick on eth1 proto icmp from 33.33.33.0/24 to any keep state pass in quick on eth1 proto tcp from 22.22.22.0/24 to any flags S keep state pass in quick on eth1 proto tcp from 33.33.33.0/24 to any flags S keep state pass in quick on eth1 proto udp from 22.22.22.0/24 to any keep state pass in quick on eth1 proto udp from 33.33.33.0/24 to any keep state pass in quick on eth1 from 22.22.22.0/24 to any pass in quick on eth1 from 33.33.33.0/24 to any # # Rule 4 (eth0) # firewall:Policy:4: warning: Changing rule direction due to self reference pass in quick on eth0 proto udp from 192.168.1.0/24 to 192.168.1.1 port = 53 keep state pass in quick on eth0 proto udp from 192.168.1.0/24 to 222.222.222.222 port = 53 keep state # # Rule 5 (eth0) block in log level local0.warning quick on eth0 proto udp from any to 192.168.1.255 port = 53 # # Rule 6 (global) block in log level local0.warning quick proto icmp from any to any block in log level local0.warning quick proto tcp from any to any flags S/UAPRSF block in log level local0.warning quick proto tcp from any to any flags ARSF/UAPRSF block out log level local0.warning quick proto icmp from any to any block out log level local0.warning quick proto tcp from any to any flags S/UAPRSF block out log level local0.warning quick proto tcp from any to any flags ARSF/UAPRSF # # Rule 7 (global) block return-icmp-as-dest (3) in log level local0.warning quick from any to any with opt rr block return-icmp-as-dest (3) in log level local0.warning quick from any to any with opt lsrr opt ssrr block return-icmp-as-dest (3) in log level local0.warning quick from any to any with opt ts block return-icmp-as-dest (3) in log level local0.warning quick from any to any block out log level local0.warning quick from any to any with opt rr block out log level local0.warning quick from any to any with opt lsrr opt ssrr block out log level local0.warning quick from any to any with opt ts block out log level local0.warning quick from any to any # # Rule 8 (global) # firewall:Policy:8: warning: Changing rule direction due to self reference block return-icmp-as-dest (3) in quick proto 50 from any to 192.168.1.1 block return-icmp-as-dest (3) in quick proto 50 from any to 222.222.222.222 # # Rule 11 (global) pass in quick proto tcp from 211.11.11.11 to 192.168.1.10 port = 53 flags S keep state pass in quick proto tcp from 211.22.22.22 to 192.168.1.10 port = 53 flags S keep state pass out quick proto tcp from 211.11.11.11 to 192.168.1.10 port = 53 flags S keep state pass out quick proto tcp from 211.22.22.22 to 192.168.1.10 port = 53 flags S keep state # # Rule 12 (global) pass in quick proto tcp from any to 192.168.1.10 port = 113 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 13 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 53 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 2105 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 21 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 70 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 80 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 443 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 143 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 993 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 6667 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 543 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 544 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 389 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 98 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 3306 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 2049 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 119 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 110 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 5432 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 515 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 26000 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 512 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 513 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 514 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 4321 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 25 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 465 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 1080 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 3128 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 22 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 111 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 23 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port 9999 >< 10041 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 540 flags S keep state pass in quick proto tcp from any to 192.168.1.10 port = 7100 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 113 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 13 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 53 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 2105 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 21 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 70 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 80 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 443 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 143 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 993 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 6667 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 543 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 544 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 389 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 98 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 3306 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 2049 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 119 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 110 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 5432 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 515 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 26000 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 512 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 513 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 514 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 4321 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 25 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 465 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 1080 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 3128 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 22 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 111 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 23 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port 9999 >< 10041 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 540 flags S keep state pass out quick proto tcp from any to 192.168.1.10 port = 7100 flags S keep state # # Rule 13 (global) pass in quick proto icmp from any to 192.168.1.0/24 icmp-type 3 keep state pass in quick proto icmp from any to 192.168.1.0/24 icmp-type 0 code 0 keep state pass in quick proto icmp from any to 192.168.1.0/24 icmp-type 11 code 0 keep state pass in quick proto icmp from any to 192.168.1.0/24 icmp-type 11 code 1 keep state pass in quick proto tcp from any to 192.168.1.0/24 port = 3128 flags S keep state pass out quick proto icmp from any to 192.168.1.0/24 icmp-type 3 keep state pass out quick proto icmp from any to 192.168.1.0/24 icmp-type 0 code 0 keep state pass out quick proto icmp from any to 192.168.1.0/24 icmp-type 11 code 0 keep state pass out quick proto icmp from any to 192.168.1.0/24 icmp-type 11 code 1 keep state pass out quick proto tcp from any to 192.168.1.0/24 port = 3128 flags S keep state # # Rule 14 (global) skip 2 in from any to 192.168.1.11 skip 1 in from any to 192.168.1.12/30 skip 8 in from any to any pass in quick proto tcp from any to any port = 113 flags S keep state pass in quick proto tcp from any to any port = 80 flags S keep state pass in quick proto tcp from any to any port = 443 flags S keep state pass in quick proto tcp from any to any port = 143 flags S keep state pass in quick proto tcp from any to any port = 25 flags S keep state pass in quick proto tcp from any to any port = 3128 flags S keep state pass in quick proto tcp from any to any port = 22 flags S keep state pass in quick proto tcp from any to any port = 540 flags S keep state skip 2 out from any to 192.168.1.11 skip 1 out from any to 192.168.1.12/30 skip 8 out from any to any pass out quick proto tcp from any to any port = 113 flags S keep state pass out quick proto tcp from any to any port = 80 flags S keep state pass out quick proto tcp from any to any port = 443 flags S keep state pass out quick proto tcp from any to any port = 143 flags S keep state pass out quick proto tcp from any to any port = 25 flags S keep state pass out quick proto tcp from any to any port = 3128 flags S keep state pass out quick proto tcp from any to any port = 22 flags S keep state pass out quick proto tcp from any to any port = 540 flags S keep state # # Rule 15 (global) pass in quick proto tcp from any to 192.168.1.11 port = 113 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 80 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 443 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 143 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 25 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 3128 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 22 flags S keep state pass in quick proto tcp from any to 192.168.1.11 port = 540 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 113 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 80 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 443 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 143 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 25 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 3128 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 22 flags S keep state pass out quick proto tcp from any to 192.168.1.11 port = 540 flags S keep state # # Rule 16 (global) skip 5 in from any to 192.168.1.11 skip 4 in from any to 192.168.1.12 skip 3 in from any to 192.168.1.13 skip 2 in from any to 192.168.1.14 skip 1 in from any to 192.168.1.15 skip 8 in from any to any pass in quick proto tcp from any to any port = 113 flags S keep state pass in quick proto tcp from any to any port = 80 flags S keep state pass in quick proto tcp from any to any port = 443 flags S keep state pass in quick proto tcp from any to any port = 143 flags S keep state pass in quick proto tcp from any to any port = 25 flags S keep state pass in quick proto tcp from any to any port = 3128 flags S keep state pass in quick proto tcp from any to any port = 22 flags S keep state pass in quick proto tcp from any to any port = 540 flags S keep state skip 5 out from any to 192.168.1.11 skip 4 out from any to 192.168.1.12 skip 3 out from any to 192.168.1.13 skip 2 out from any to 192.168.1.14 skip 1 out from any to 192.168.1.15 skip 8 out from any to any pass out quick proto tcp from any to any port = 113 flags S keep state pass out quick proto tcp from any to any port = 80 flags S keep state pass out quick proto tcp from any to any port = 443 flags S keep state pass out quick proto tcp from any to any port = 143 flags S keep state pass out quick proto tcp from any to any port = 25 flags S keep state pass out quick proto tcp from any to any port = 3128 flags S keep state pass out quick proto tcp from any to any port = 22 flags S keep state pass out quick proto tcp from any to any port = 540 flags S keep state # # Rule 17 (global) pass in log level local0.warning quick proto icmp from 192.168.1.1 to 192.168.1.1 keep state pass in log level local0.warning quick proto icmp from 192.168.1.1 to 222.222.222.222 keep state pass in log level local0.warning quick proto icmp from 222.222.222.222 to 192.168.1.1 keep state pass in log level local0.warning quick proto icmp from 222.222.222.222 to 222.222.222.222 keep state pass in log level local0.warning quick proto tcp from 192.168.1.1 to 192.168.1.1 flags S keep state pass in log level local0.warning quick proto tcp from 192.168.1.1 to 222.222.222.222 flags S keep state pass in log level local0.warning quick proto tcp from 222.222.222.222 to 192.168.1.1 flags S keep state pass in log level local0.warning quick proto tcp from 222.222.222.222 to 222.222.222.222 flags S keep state pass in log level local0.warning quick proto udp from 192.168.1.1 to 192.168.1.1 keep state pass in log level local0.warning quick proto udp from 192.168.1.1 to 222.222.222.222 keep state pass in log level local0.warning quick proto udp from 222.222.222.222 to 192.168.1.1 keep state pass in log level local0.warning quick proto udp from 222.222.222.222 to 222.222.222.222 keep state pass in log level local0.warning quick from 192.168.1.1 to 192.168.1.1 pass in log level local0.warning quick from 192.168.1.1 to 222.222.222.222 pass in log level local0.warning quick from 222.222.222.222 to 192.168.1.1 pass in log level local0.warning quick from 222.222.222.222 to 222.222.222.222 pass out log level local0.warning quick proto icmp from 192.168.1.1 to 192.168.1.1 keep state pass out log level local0.warning quick proto icmp from 192.168.1.1 to 222.222.222.222 keep state pass out log level local0.warning quick proto icmp from 222.222.222.222 to 192.168.1.1 keep state pass out log level local0.warning quick proto icmp from 222.222.222.222 to 222.222.222.222 keep state pass out log level local0.warning quick proto tcp from 192.168.1.1 to 192.168.1.1 flags S keep state pass out log level local0.warning quick proto tcp from 192.168.1.1 to 222.222.222.222 flags S keep state pass out log level local0.warning quick proto tcp from 222.222.222.222 to 192.168.1.1 flags S keep state pass out log level local0.warning quick proto tcp from 222.222.222.222 to 222.222.222.222 flags S keep state pass out log level local0.warning quick proto udp from 192.168.1.1 to 192.168.1.1 keep state pass out log level local0.warning quick proto udp from 192.168.1.1 to 222.222.222.222 keep state pass out log level local0.warning quick proto udp from 222.222.222.222 to 192.168.1.1 keep state pass out log level local0.warning quick proto udp from 222.222.222.222 to 222.222.222.222 keep state pass out log level local0.warning quick from 192.168.1.1 to 192.168.1.1 pass out log level local0.warning quick from 192.168.1.1 to 222.222.222.222 pass out log level local0.warning quick from 222.222.222.222 to 192.168.1.1 pass out log level local0.warning quick from 222.222.222.222 to 222.222.222.222 # # Rule 19 (global) # firewall:Policy:19: warning: Changing rule direction due to self reference pass in quick proto icmp from 192.168.1.1 to 192.168.1.1 keep state pass in quick proto icmp from 192.168.1.1 to 222.222.222.222 keep state pass in quick proto icmp from 222.222.222.222 to 192.168.1.1 keep state pass in quick proto icmp from 222.222.222.222 to 222.222.222.222 keep state pass in quick proto tcp from 192.168.1.1 to 192.168.1.1 flags S keep state pass in quick proto tcp from 192.168.1.1 to 222.222.222.222 flags S keep state pass in quick proto tcp from 222.222.222.222 to 192.168.1.1 flags S keep state pass in quick proto tcp from 222.222.222.222 to 222.222.222.222 flags S keep state pass in quick proto udp from 192.168.1.1 to 192.168.1.1 keep state pass in quick proto udp from 192.168.1.1 to 222.222.222.222 keep state pass in quick proto udp from 222.222.222.222 to 192.168.1.1 keep state pass in quick proto udp from 222.222.222.222 to 222.222.222.222 keep state pass in quick from 192.168.1.1 to 192.168.1.1 pass in quick from 192.168.1.1 to 222.222.222.222 pass in quick from 222.222.222.222 to 192.168.1.1 pass in quick from 222.222.222.222 to 222.222.222.222 pass out quick proto icmp from 192.168.1.1 to 192.168.1.1 keep state pass out quick proto icmp from 192.168.1.1 to 222.222.222.222 keep state pass out quick proto icmp from 222.222.222.222 to 192.168.1.1 keep state pass out quick proto icmp from 222.222.222.222 to 222.222.222.222 keep state pass out quick proto tcp from 192.168.1.1 to 192.168.1.1 flags S keep state pass out quick proto tcp from 192.168.1.1 to 222.222.222.222 flags S keep state pass out quick proto tcp from 222.222.222.222 to 192.168.1.1 flags S keep state pass out quick proto tcp from 222.222.222.222 to 222.222.222.222 flags S keep state pass out quick proto udp from 192.168.1.1 to 192.168.1.1 keep state pass out quick proto udp from 192.168.1.1 to 222.222.222.222 keep state pass out quick proto udp from 222.222.222.222 to 192.168.1.1 keep state pass out quick proto udp from 222.222.222.222 to 222.222.222.222 keep state pass out quick from 192.168.1.1 to 192.168.1.1 pass out quick from 192.168.1.1 to 222.222.222.222 pass out quick from 222.222.222.222 to 192.168.1.1 pass out quick from 222.222.222.222 to 222.222.222.222 pass out quick proto icmp from 192.168.1.1 to 33.33.33.33 keep state pass out quick proto icmp from 192.168.1.1 to 33.33.33.34 keep state pass out quick proto icmp from 222.222.222.222 to 33.33.33.33 keep state pass out quick proto icmp from 222.222.222.222 to 33.33.33.34 keep state pass out quick proto tcp from 192.168.1.1 to 33.33.33.33 flags S keep state pass out quick proto tcp from 192.168.1.1 to 33.33.33.34 flags S keep state pass out quick proto tcp from 222.222.222.222 to 33.33.33.33 flags S keep state pass out quick proto tcp from 222.222.222.222 to 33.33.33.34 flags S keep state pass out quick proto udp from 192.168.1.1 to 33.33.33.33 keep state pass out quick proto udp from 192.168.1.1 to 33.33.33.34 keep state pass out quick proto udp from 222.222.222.222 to 33.33.33.33 keep state pass out quick proto udp from 222.222.222.222 to 33.33.33.34 keep state pass out quick from 192.168.1.1 to 33.33.33.33 pass out quick from 192.168.1.1 to 33.33.33.34 pass out quick from 222.222.222.222 to 33.33.33.33 pass out quick from 222.222.222.222 to 33.33.33.34 pass in quick proto icmp from 33.33.33.33 to 192.168.1.1 keep state pass in quick proto icmp from 33.33.33.33 to 222.222.222.222 keep state pass in quick proto icmp from 33.33.33.34 to 192.168.1.1 keep state pass in quick proto icmp from 33.33.33.34 to 222.222.222.222 keep state pass in quick proto tcp from 33.33.33.33 to 192.168.1.1 flags S keep state pass in quick proto tcp from 33.33.33.33 to 222.222.222.222 flags S keep state pass in quick proto tcp from 33.33.33.34 to 192.168.1.1 flags S keep state pass in quick proto tcp from 33.33.33.34 to 222.222.222.222 flags S keep state pass in quick proto udp from 33.33.33.33 to 192.168.1.1 keep state pass in quick proto udp from 33.33.33.33 to 222.222.222.222 keep state pass in quick proto udp from 33.33.33.34 to 192.168.1.1 keep state pass in quick proto udp from 33.33.33.34 to 222.222.222.222 keep state pass in quick from 33.33.33.33 to 192.168.1.1 pass in quick from 33.33.33.33 to 222.222.222.222 pass in quick from 33.33.33.34 to 192.168.1.1 pass in quick from 33.33.33.34 to 222.222.222.222 skip 3 in from 33.33.33.33 to any skip 2 in from 33.33.33.34 to any skip 1 in from 192.168.1.1 to any skip 24 in from any to any pass in quick proto icmp from any to 33.33.33.33 keep state pass in quick proto icmp from any to 33.33.33.34 keep state pass in quick proto icmp from any to 192.168.1.1 keep state skip 3 in from 33.33.33.33 to any skip 2 in from 33.33.33.34 to any skip 1 in from 192.168.1.1 to any skip 17 in from any to any pass in quick proto tcp from any to 33.33.33.33 flags S keep state pass in quick proto tcp from any to 33.33.33.34 flags S keep state pass in quick proto tcp from any to 192.168.1.1 flags S keep state skip 3 in from 33.33.33.33 to any skip 2 in from 33.33.33.34 to any skip 1 in from 192.168.1.1 to any skip 10 in from any to any pass in quick proto udp from any to 33.33.33.33 keep state pass in quick proto udp from any to 33.33.33.34 keep state pass in quick proto udp from any to 192.168.1.1 keep state skip 3 in from 33.33.33.33 to any skip 2 in from 33.33.33.34 to any skip 1 in from 192.168.1.1 to any skip 3 in from any to any pass in quick from any to 33.33.33.33 pass in quick from any to 33.33.33.34 pass in quick from any to 192.168.1.1 skip 3 out from 33.33.33.33 to any skip 2 out from 33.33.33.34 to any skip 1 out from 192.168.1.1 to any skip 24 out from any to any pass out quick proto icmp from any to 33.33.33.33 keep state pass out quick proto icmp from any to 33.33.33.34 keep state pass out quick proto icmp from any to 192.168.1.1 keep state skip 3 out from 33.33.33.33 to any skip 2 out from 33.33.33.34 to any skip 1 out from 192.168.1.1 to any skip 17 out from any to any pass out quick proto tcp from any to 33.33.33.33 flags S keep state pass out quick proto tcp from any to 33.33.33.34 flags S keep state pass out quick proto tcp from any to 192.168.1.1 flags S keep state skip 3 out from 33.33.33.33 to any skip 2 out from 33.33.33.34 to any skip 1 out from 192.168.1.1 to any skip 10 out from any to any pass out quick proto udp from any to 33.33.33.33 keep state pass out quick proto udp from any to 33.33.33.34 keep state pass out quick proto udp from any to 192.168.1.1 keep state skip 3 out from 33.33.33.33 to any skip 2 out from 33.33.33.34 to any skip 1 out from 192.168.1.1 to any skip 3 out from any to any pass out quick from any to 33.33.33.33 pass out quick from any to 33.33.33.34 pass out quick from any to 192.168.1.1 # # Rule 20 (global) # Automatically generated 'masquerading' rule # firewall:Policy:20: warning: Changing rule direction due to self reference pass out quick proto icmp from 192.168.1.1 to any keep state pass out quick proto icmp from 222.222.222.222 to any keep state pass out quick proto tcp from 192.168.1.1 to any flags S keep state pass out quick proto tcp from 222.222.222.222 to any flags S keep state pass out quick proto udp from 192.168.1.1 to any keep state pass out quick proto udp from 222.222.222.222 to any keep state pass out quick from 192.168.1.1 to any pass out quick from 222.222.222.222 to any pass in quick proto icmp from 192.168.1.0/24 to any keep state pass in quick proto tcp from 192.168.1.0/24 to any flags S keep state pass in quick proto udp from 192.168.1.0/24 to any keep state pass in quick from 192.168.1.0/24 to any pass out quick proto icmp from 192.168.1.0/24 to any keep state pass out quick proto tcp from 192.168.1.0/24 to any flags S keep state pass out quick proto udp from 192.168.1.0/24 to any keep state pass out quick from 192.168.1.0/24 to any # # Rule 21 (global) # Automatically generated 'catch all' rule block in log level daemon.alert quick from any to any block out log level daemon.alert quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall4.fw.orig0000755000175000017500000000334011733011756021724 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:27 2011 PST by vadim # # files: * firewall4.fw /etc/fw/firewall4.fw # files: firewall4-ipf.conf /etc/fw/firewall4-ipf.conf # files: firewall4-nat.conf /etc/fw/firewall4-nat.conf # # Compiled for ipf # # this object is used to test a configuration where firewall has dynamic address # firewall4::: error: Dynamic interface eth1 should not have an IP address object attached to it. This IP address object will be ignored. # firewall4:Policy:6: warning: Changing rule direction due to self reference # firewall4:Policy:6: warning: Changing rule direction due to self reference FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/usr/sbin/ipf" IPNAT="/usr/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/fw/firewall4-ipf.conf $IPNAT -f /etc/fw/firewall4-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall35.fw.orig0000755000175000017500000000262711733011756022017 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:27 2011 PST by vadim # # files: * firewall35.fw /etc/firewall35.fw # files: firewall35-ipf.conf /etc/firewall35-ipf.conf # files: firewall35-nat.conf /etc/firewall35-nat.conf # # Compiled for ipf # # Testing action Custom FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/firewall35-ipf.conf $IPNAT -f /etc/firewall35-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall11-ipf.conf.orig0000755000175000017500000000245211733011756023072 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall11:Policy:1: warning: Changing rule direction due to self reference # # Rule 0 (ng0) pass in quick on ng0 proto icmp from any to keep state pass in quick on ng0 proto tcp from any to keep state pass in quick on ng0 proto udp from any to keep state pass in quick on ng0 from any to # # Rule 1 (global) # firewall11:Policy:1: warning: Changing rule direction due to self reference pass in quick proto icmp from any to 10.0.0.1 keep state pass in quick proto tcp from any to 10.0.0.1 keep state pass in quick proto udp from any to 10.0.0.1 keep state pass in quick from any to 10.0.0.1 # # Rule 2 (global) pass in quick proto icmp from any to keep state pass in quick proto tcp from any to keep state pass in quick proto udp from any to keep state pass in quick from any to pass out quick proto icmp from any to keep state pass out quick proto tcp from any to keep state pass out quick proto udp from any to keep state pass out quick from any to # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/objects-for-regression-tests.fwb0000644000175000017500000140420411733011756024773 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk -m ip_conntrack_talk -m ip_nat_talk fwbuilder-5.1.0.3599/test/ipf/large_policy_test.fwb0000644000175000017500000004013411733011756022745 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/test/ipf/firewall35-ipf.conf.orig0000755000175000017500000000127511733011756023102 0ustar sylvestresylvestre# # Rule 0 (le1) auth in quick on le1 from 192.168.1.0/24 to any # # Rule 1 (le1) skip 1 in on le1 from 192.168.1.0/24 to any auth in quick on le1 from any to any # # Rule 2 (le1) pass in quick on le1 proto icmp from 192.168.1.0/24 to any keep state pass in quick on le1 proto tcp from 192.168.1.0/24 to any flags S keep state pass in quick on le1 proto udp from 192.168.1.0/24 to any keep state pass in quick on le1 from 192.168.1.0/24 to any # # Rule 3 (global) block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall2-ipf.conf.orig0000755000175000017500000001171511733011756023014 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall2:Policy:9: warning: Changing rule direction due to self reference # # Rule 0 (eth1) # Anti-spoofing rule block in log quick on eth1 from 22.22.22.22 to any block in log quick on eth1 from 22.22.23.23 to any block in log quick on eth1 from 192.168.1.1 to any block in log quick on eth1 from 192.168.2.1 to any block in log quick on eth1 from 192.168.1.0/24 to any # # Rule 1 (eth1) # Anti-spoofing rule skip 5 out on eth1 from 22.22.22.22 to any skip 4 out on eth1 from 22.22.23.23 to any skip 3 out on eth1 from 192.168.1.1 to any skip 2 out on eth1 from 192.168.2.1 to any skip 1 out on eth1 from 192.168.1.0/24 to any block out log quick on eth1 from any to any # # Rule 2 (global) # block fragments block in log quick from any to any with short block out log quick from any to any with short # # Rule 3 (global) # sends TCP RST and makes custom record in the log block return-rst in log quick proto tcp from any to any port = 113 block out log quick proto tcp from any to any port = 113 # # Rule 4 (global) # sends TCP RST and makes custom record in the log block return-icmp-as-dest (0) in log quick proto udp from any to any port = 161 block out log quick proto udp from any to any port = 161 # # Rule 5 (global) pass in quick proto icmp from 192.168.1.10 to 200.200.200.200 keep state pass in quick proto icmp from 192.168.1.20 to 200.200.200.200 keep state pass in quick proto tcp from 192.168.1.10 to 200.200.200.200 keep state pass in quick proto tcp from 192.168.1.20 to 200.200.200.200 keep state pass in quick proto udp from 192.168.1.10 to 200.200.200.200 keep state pass in quick proto udp from 192.168.1.20 to 200.200.200.200 keep state pass in quick from 192.168.1.10 to 200.200.200.200 pass in quick from 192.168.1.20 to 200.200.200.200 pass out quick proto icmp from 192.168.1.10 to 200.200.200.200 keep state pass out quick proto icmp from 192.168.1.20 to 200.200.200.200 keep state pass out quick proto tcp from 192.168.1.10 to 200.200.200.200 keep state pass out quick proto tcp from 192.168.1.20 to 200.200.200.200 keep state pass out quick proto udp from 192.168.1.10 to 200.200.200.200 keep state pass out quick proto udp from 192.168.1.20 to 200.200.200.200 keep state pass out quick from 192.168.1.10 to 200.200.200.200 pass out quick from 192.168.1.20 to 200.200.200.200 # # Rule 6 (global) pass in quick proto icmp from 200.200.200.200 to 192.168.1.10 keep state pass in quick proto icmp from 200.200.200.200 to 192.168.1.20 keep state pass in quick proto tcp from 200.200.200.200 to 192.168.1.10 keep state pass in quick proto tcp from 200.200.200.200 to 192.168.1.20 keep state pass in quick proto udp from 200.200.200.200 to 192.168.1.10 keep state pass in quick proto udp from 200.200.200.200 to 192.168.1.20 keep state pass in quick from 200.200.200.200 to 192.168.1.10 pass in quick from 200.200.200.200 to 192.168.1.20 pass out quick proto icmp from 200.200.200.200 to 192.168.1.10 keep state pass out quick proto icmp from 200.200.200.200 to 192.168.1.20 keep state pass out quick proto tcp from 200.200.200.200 to 192.168.1.10 keep state pass out quick proto tcp from 200.200.200.200 to 192.168.1.20 keep state pass out quick proto udp from 200.200.200.200 to 192.168.1.10 keep state pass out quick proto udp from 200.200.200.200 to 192.168.1.20 keep state pass out quick from 200.200.200.200 to 192.168.1.10 pass out quick from 200.200.200.200 to 192.168.1.20 # # Rule 7 (global) # 'masquerading' rule pass in quick proto icmp from 192.168.1.0/24 to any keep state pass in quick proto tcp from 192.168.1.0/24 to any keep state pass in quick proto udp from 192.168.1.0/24 to any keep state pass in quick from 192.168.1.0/24 to any pass out quick proto icmp from 192.168.1.0/24 to any keep state pass out quick proto tcp from 192.168.1.0/24 to any keep state pass out quick proto udp from 192.168.1.0/24 to any keep state pass out quick from 192.168.1.0/24 to any # # Rule 8 (global) # host-fw2 has the same address as # one of the firewall's interfaces pass in log quick proto tcp from any to 22.22.22.22 port = 21 keep state pass out log quick proto tcp from any to 22.22.22.22 port = 21 keep state # # Rule 9 (global) # firewall2:Policy:9: warning: Changing rule direction due to self reference pass in log quick proto tcp from any to 22.22.23.23 port = 21 keep state pass in log quick proto tcp from any to 192.168.1.1 port = 21 keep state pass in log quick proto tcp from any to 192.168.2.1 port = 21 keep state # # Rule 10 (global) # 'catch all' rule block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall7.fw.orig0000755000175000017500000000244411733011756021733 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:28 2011 PST by vadim # # files: * firewall7.fw /etc/fw/firewall7.fw # files: firewall7-ipf.conf /etc/fw/firewall7-ipf.conf # # Compiled for ipf # # testing rules with broadcasts FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:28 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/fw/firewall7-ipf.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipf/firewall2-nat.conf.orig0000755000175000017500000005006311733011756023017 0ustar sylvestresylvestre# NAT compiler errors and warnings: # firewall2:NAT:17: warning: Expanding port range test-TCP creates 41 rules # # Rule 0 (NAT) map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 map eth2 from 192.168.1.0/24 to any -> 192.168.2.1/32 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to any -> 192.168.2.1/32 # # Rule 1 (NAT) map eth0 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth1 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth3 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth2 from 192.168.1.10/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth0 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth1 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth3 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth2 from 192.168.1.10/32 to any -> 22.22.22.23/32 map eth0 from 192.168.1.20/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth1 from 192.168.1.20/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth3 from 192.168.1.20/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth2 from 192.168.1.20/32 to any -> 22.22.22.23/32 portmap tcp/udp auto map eth0 from 192.168.1.20/32 to any -> 22.22.22.23/32 map eth1 from 192.168.1.20/32 to any -> 22.22.22.23/32 map eth3 from 192.168.1.20/32 to any -> 22.22.22.23/32 map eth2 from 192.168.1.20/32 to any -> 22.22.22.23/32 # # Rule 2 (NAT) map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 proxy port 21 ftp/tcp map eth3 from 192.168.1.0/24 to any -> 22.22.23.23/32 proxy port 21 ftp/tcp map eth0 from 192.168.1.0/24 to any -> 192.168.1.1/32 proxy port 21 ftp/tcp map eth2 from 192.168.1.0/24 to any -> 192.168.2.1/32 proxy port 21 ftp/tcp map eth1 from 192.168.1.0/24 to any port = 22 -> 22.22.22.22/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to any port = 22 -> 22.22.23.23/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any port = 22 -> 192.168.1.1/32 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to any port = 22 -> 192.168.2.1/32 portmap tcp/udp auto # # Rule 3 (NAT) map eth1 from 192.168.1.0/24 to any port = 22 -> 22.22.22.22/32 portmap tcp/udp auto # # Rule 4 (NAT) map eth1 from 192.168.1.0/24 to any -> 22.22.22.22/32 proxy port 500 ipsec/udp # # Rule 5 (NAT) map eth0 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 map eth1 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 map eth3 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 map eth2 from 192.168.1.0/24 to 192.168.1.10/32 -> 192.168.1.1/32 map eth0 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 map eth1 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 map eth3 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 map eth2 from 192.168.1.0/24 to 192.168.1.20/32 -> 192.168.1.1/32 # # Rule 7 (NAT) rdr eth1 from any to 22.22.22.23/32 port = 80 -> 192.168.1.10 port 80 tcp rdr eth1 from any to 22.22.22.23/32 port = 119 -> 192.168.1.10 port 119 tcp # # Rule 8 (NAT) # load balancing rule rdr eth1 from any to 22.22.22.23/32 port = 80 -> 192.168.1.10,192.168.1.20 port 80 tcp round-robin rdr eth1 from any to 22.22.22.23/32 port = 80 -> 192.168.1.100 port 80 tcp round-robin # # Rule 9 (NAT) # load balancing rule rdr eth1 from any to 22.22.22.23/32 port = 80 -> 192.168.1.10,192.168.1.20 port 80 tcp round-robin rdr eth1 from any to 22.22.22.23/32 port = 80 -> 192.168.1.100 port 80 tcp round-robin # # Rule 10 (NAT) map eth0 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 map eth1 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 map eth3 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 map eth2 from 192.168.1.0/24 to 192.168.2.10/32 -> 192.168.2.1/32 # # Rule 11 (NAT) rdr eth1 from any to 22.22.22.24/32 port = 80 -> 192.168.2.10 port 80 tcp # # Rule 12 (NAT) rdr eth1 from any to 22.22.22.22/32 port = 119 -> 192.168.1.10 port 119 tcp # # Rule 13 (NAT) map eth0 from 192.168.1.20/32 to any -> 22.22.23.24/32 portmap tcp/udp auto map eth1 from 192.168.1.20/32 to any -> 22.22.23.24/32 portmap tcp/udp auto map eth3 from 192.168.1.20/32 to any -> 22.22.23.24/32 portmap tcp/udp auto map eth2 from 192.168.1.20/32 to any -> 22.22.23.24/32 portmap tcp/udp auto map eth0 from 192.168.1.20/32 to any -> 22.22.23.24/32 map eth1 from 192.168.1.20/32 to any -> 22.22.23.24/32 map eth3 from 192.168.1.20/32 to any -> 22.22.23.24/32 map eth2 from 192.168.1.20/32 to any -> 22.22.23.24/32 # # Rule 15 (NAT) # NETMAP map eth0 from 192.168.1.0/24 to any -> 22.22.22.0/24 portmap tcp/udp auto map eth1 from 192.168.1.0/24 to any -> 22.22.22.0/24 portmap tcp/udp auto map eth3 from 192.168.1.0/24 to any -> 22.22.22.0/24 portmap tcp/udp auto map eth2 from 192.168.1.0/24 to any -> 22.22.22.0/24 portmap tcp/udp auto map eth0 from 192.168.1.0/24 to any -> 22.22.22.0/24 map eth1 from 192.168.1.0/24 to any -> 22.22.22.0/24 map eth3 from 192.168.1.0/24 to any -> 22.22.22.0/24 map eth2 from 192.168.1.0/24 to any -> 22.22.22.0/24 # # Rule 17 (NAT) # firewall2:NAT:17: warning: Expanding port range test-TCP creates 41 rules rdr eth1 from any to 22.22.22.22/32 port = 10000 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10000 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10000 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10000 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10001 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10001 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10001 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10001 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10002 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10002 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10002 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10002 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10003 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10003 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10003 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10003 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10004 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10004 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10004 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10004 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10005 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10005 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10005 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10005 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10006 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10006 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10006 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10006 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10007 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10007 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10007 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10007 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10008 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10008 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10008 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10008 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10009 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10009 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10009 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10009 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10010 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10010 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10010 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10010 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10011 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10011 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10011 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10011 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10012 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10012 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10012 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10012 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10013 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10013 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10013 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10013 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10014 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10014 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10014 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10014 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10015 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10015 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10015 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10015 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10016 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10016 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10016 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10016 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10017 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10017 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10017 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10017 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10018 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10018 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10018 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10018 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10019 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10019 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10019 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10019 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10020 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10020 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10020 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10020 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10021 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10021 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10021 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10021 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10022 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10022 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10022 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10022 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10023 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10023 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10023 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10023 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10024 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10024 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10024 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10024 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10025 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10025 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10025 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10025 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10026 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10026 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10026 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10026 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10027 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10027 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10027 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10027 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10028 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10028 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10028 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10028 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10029 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10029 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10029 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10029 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10030 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10030 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10030 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10030 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10031 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10031 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10031 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10031 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10032 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10032 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10032 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10032 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10033 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10033 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10033 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10033 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10034 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10034 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10034 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10034 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10035 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10035 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10035 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10035 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10036 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10036 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10036 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10036 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10037 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10037 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10037 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10037 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10038 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10038 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10038 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10038 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10039 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10039 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10039 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10039 -> 192.168.1.10 port 10000 tcp rdr eth1 from any to 22.22.22.22/32 port = 10040 -> 192.168.1.10 port 10000 tcp rdr eth3 from any to 22.22.23.23/32 port = 10040 -> 192.168.1.10 port 10000 tcp rdr eth0 from any to 192.168.1.1/32 port = 10040 -> 192.168.1.10 port 10000 tcp rdr eth2 from any to 192.168.2.1/32 port = 10040 -> 192.168.1.10 port 10000 tcp # # Rule 18 (NAT) rdr eth1 from any to 22.22.22.23/32 port = 80 -> 192.168.1.10 port 25 tcp # # Rule 19 (NAT) map eth2 from 192.168.1.0/24 to 192.168.2.0/24 -> 0/0 proxy port 21 ftp/tcp # # Rule 20 (NAT) map eth2 from 192.168.1.0/24 to 192.168.2.0/24 -> 0/0 proxy port 1720 h323/tcp map eth2 from 192.168.1.0/24 to 192.168.2.0/24 -> 0/0 proxy port 21 ftp/tcp # # Rule 21 (NAT) map eth2 from 192.168.1.0/24 to 192.168.2.0/24 port = 80 -> 0/0 # # Rule 22 (NAT) map eth2 from 192.168.1.0/24 to 192.168.2.0/24 -> 0/0 # # Rule 23 (NAT) map eth2 from 192.168.1.0/24 to 192.168.2.0/24 -> 0/0 fwbuilder-5.1.0.3599/test/ipf/firewall10-ipf.conf.orig0000755000175000017500000001715711733011756023101 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall10:Policy:2: warning: Changing rule direction due to self reference # # Rule 0 (global) count in from any to any count out from any to any # # Rule 1 (global) skip 5 in from 192.168.1.10 to any skip 4 in from 192.168.1.20 to any skip 3 in from 192.168.1.100 to any skip 2 in from 192.168.1.110 to any skip 1 in from 192.168.1.120 to any skip 18 in from any to any skip 4 in from any to 192.168.2.10 skip 3 in from any to 192.168.2.20 skip 2 in from any to 192.168.2.30 skip 1 in from any to 192.168.2.40 skip 13 in from any to any skip 12 in proto tcp from any to any port = 21 skip 11 in proto tcp from any to any port = 80 skip 10 in proto tcp from any to any port = 119 skip 9 in proto tcp from any to any port = 25 skip 5 out from 192.168.1.10 to any skip 4 out from 192.168.1.20 to any skip 3 out from 192.168.1.100 to any skip 2 out from 192.168.1.110 to any skip 1 out from 192.168.1.120 to any skip 18 out from any to any skip 4 out from any to 192.168.2.10 skip 3 out from any to 192.168.2.20 skip 2 out from any to 192.168.2.30 skip 1 out from any to 192.168.2.40 skip 13 out from any to any skip 12 out proto tcp from any to any port = 21 skip 11 out proto tcp from any to any port = 80 skip 10 out proto tcp from any to any port = 119 skip 9 out proto tcp from any to any port = 25 skip 4 in from any to 192.168.2.10 skip 3 in from any to 192.168.2.20 skip 2 in from any to 192.168.2.30 skip 1 in from any to 192.168.2.40 skip 4 in from any to any pass in quick proto tcp from any to any port = 21 flags S keep state pass in quick proto tcp from any to any port = 80 flags S keep state pass in quick proto tcp from any to any port = 119 flags S keep state pass in quick proto tcp from any to any port = 25 flags S keep state skip 4 out from any to 192.168.2.10 skip 3 out from any to 192.168.2.20 skip 2 out from any to 192.168.2.30 skip 1 out from any to 192.168.2.40 skip 4 out from any to any pass out quick proto tcp from any to any port = 21 flags S keep state pass out quick proto tcp from any to any port = 80 flags S keep state pass out quick proto tcp from any to any port = 119 flags S keep state pass out quick proto tcp from any to any port = 25 flags S keep state # # Rule 2 (global) # firewall10:Policy:2: warning: Changing rule direction due to self reference skip 1 in from 192.168.1.0/24 to any skip 11 in from any to any skip 3 in from any to 22.22.22.22 skip 2 in from any to 192.168.1.1 skip 1 in from any to 192.168.2.0 skip 7 in from any to any pass in quick proto icmp from any to any icmp-type 3 keep state pass in quick proto icmp from any to any icmp-type 0 code 0 keep state pass in quick proto icmp from any to any icmp-type 11 code 0 keep state pass in quick proto icmp from any to any icmp-type 11 code 1 keep state pass in quick proto tcp from 192.168.1.0/24 to 22.22.22.22 port = 22 flags S keep state pass in quick proto tcp from 192.168.1.0/24 to 192.168.1.1 port = 22 flags S keep state pass in quick proto tcp from 192.168.1.0/24 to 192.168.2.0 port = 22 flags S keep state # # Rule 3 (global) skip 5 in from 192.168.1.10 to any skip 4 in from 192.168.1.20 to any skip 3 in from 192.168.1.100 to any skip 2 in from 192.168.1.110 to any skip 1 in from 192.168.1.120 to any skip 9 in from any to any skip 4 in from any to 192.168.2.10 skip 3 in from any to 192.168.2.20 skip 2 in from any to 192.168.2.30 skip 1 in from any to 192.168.2.40 skip 4 in from any to any block in quick proto tcp from any to any port = 21 block in quick proto tcp from any to any port = 80 block in quick proto tcp from any to any port = 119 block in quick proto tcp from any to any port = 25 skip 5 out from 192.168.1.10 to any skip 4 out from 192.168.1.20 to any skip 3 out from 192.168.1.100 to any skip 2 out from 192.168.1.110 to any skip 1 out from 192.168.1.120 to any skip 9 out from any to any skip 4 out from any to 192.168.2.10 skip 3 out from any to 192.168.2.20 skip 2 out from any to 192.168.2.30 skip 1 out from any to 192.168.2.40 skip 4 out from any to any block out quick proto tcp from any to any port = 21 block out quick proto tcp from any to any port = 80 block out quick proto tcp from any to any port = 119 block out quick proto tcp from any to any port = 25 # # Rule 4 (global) skip 1 in from 192.168.1.10 to any skip 9 in from any to any skip 4 in from any to 192.168.2.10 skip 3 in from any to 192.168.2.20 skip 2 in from any to 192.168.2.30 skip 1 in from any to 192.168.2.40 skip 4 in from any to any block in quick proto tcp from any to any port = 21 block in quick proto tcp from any to any port = 80 block in quick proto tcp from any to any port = 119 block in quick proto tcp from any to any port = 25 skip 1 out from 192.168.1.10 to any skip 9 out from any to any skip 4 out from any to 192.168.2.10 skip 3 out from any to 192.168.2.20 skip 2 out from any to 192.168.2.30 skip 1 out from any to 192.168.2.40 skip 4 out from any to any block out quick proto tcp from any to any port = 21 block out quick proto tcp from any to any port = 80 block out quick proto tcp from any to any port = 119 block out quick proto tcp from any to any port = 25 # # Rule 5 (global) skip 5 in from 192.168.1.10 to any skip 4 in from 192.168.1.20 to any skip 3 in from 192.168.1.100 to any skip 2 in from 192.168.1.110 to any skip 1 in from 192.168.1.120 to any skip 4 in from any to any block in quick proto tcp from any to 192.168.2.10 port = 21 block in quick proto tcp from any to 192.168.2.10 port = 80 block in quick proto tcp from any to 192.168.2.10 port = 119 block in quick proto tcp from any to 192.168.2.10 port = 25 skip 5 out from 192.168.1.10 to any skip 4 out from 192.168.1.20 to any skip 3 out from 192.168.1.100 to any skip 2 out from 192.168.1.110 to any skip 1 out from 192.168.1.120 to any skip 4 out from any to any block out quick proto tcp from any to 192.168.2.10 port = 21 block out quick proto tcp from any to 192.168.2.10 port = 80 block out quick proto tcp from any to 192.168.2.10 port = 119 block out quick proto tcp from any to 192.168.2.10 port = 25 # # Rule 6 (global) skip 5 in from 192.168.1.10 to any skip 4 in from 192.168.1.20 to any skip 3 in from 192.168.1.100 to any skip 2 in from 192.168.1.110 to any skip 1 in from 192.168.1.120 to any skip 4 in from any to any block in quick proto tcp from any to 192.168.2.10 port = 80 block in quick proto tcp from any to 192.168.2.20 port = 80 block in quick proto tcp from any to 192.168.2.30 port = 80 block in quick proto tcp from any to 192.168.2.40 port = 80 skip 5 out from 192.168.1.10 to any skip 4 out from 192.168.1.20 to any skip 3 out from 192.168.1.100 to any skip 2 out from 192.168.1.110 to any skip 1 out from 192.168.1.120 to any skip 4 out from any to any block out quick proto tcp from any to 192.168.2.10 port = 80 block out quick proto tcp from any to 192.168.2.20 port = 80 block out quick proto tcp from any to 192.168.2.30 port = 80 block out quick proto tcp from any to 192.168.2.40 port = 80 # # Rule 7 (global) block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall9-ipf.conf.orig0000755000175000017500000000444611733011756023026 0ustar sylvestresylvestre# Policy compiler errors and warnings: # firewall9:Policy:5: warning: Changing rule direction due to self reference # # Rule 0 (le1) skip 1 in on le1 from 33.33.33.0/24 to any block in log quick on le1 from any to any # # Rule 1 (le1) pass in quick on le1 proto icmp from 33.33.33.0/24 to 192.168.1.10 icmp-type 3 keep state pass in quick on le1 proto icmp from 33.33.33.0/24 to 192.168.1.10 icmp-type 0 code 0 keep state pass in quick on le1 proto icmp from 33.33.33.0/24 to 192.168.1.10 icmp-type 11 code 0 keep state pass in quick on le1 proto icmp from 33.33.33.0/24 to 192.168.1.10 icmp-type 11 code 1 keep state pass in quick on le1 proto tcp from 33.33.33.0/24 to 192.168.1.10 port = 22 flags S keep state # # Rule 2 (le1) skip 6 in on le1 from 22.22.22.22 to any skip 5 in on le1 from 192.168.1.1 to any skip 4 in on le1 from 192.168.1.0/24 to any pass in quick on le1 proto icmp from any to any keep state pass in quick on le1 proto tcp from any to any flags S keep state pass in quick on le1 proto udp from any to any keep state pass in quick on le1 from any to any # # Rule 3 (global) count in from any to any count out from any to any # # Rule 4 (global) count in log from any to any count out log from any to any # # Rule 5 (global) # firewall9:Policy:5: warning: Changing rule direction due to self reference pass in quick proto tcp from any to 22.22.22.22 port = 22 flags S keep state pass in quick proto tcp from any to 192.168.1.1 port = 22 flags S keep state # # Rule 6 (global) pass in quick proto icmp from 192.168.1.0/24 to any keep state pass in quick proto tcp from 192.168.1.0/24 to any flags S keep state pass in quick proto udp from 192.168.1.0/24 to any keep state pass in quick from 192.168.1.0/24 to any pass out quick proto icmp from 192.168.1.0/24 to any keep state pass out quick proto tcp from 192.168.1.0/24 to any flags S keep state pass out quick proto udp from 192.168.1.0/24 to any keep state pass out quick from 192.168.1.0/24 to any # # Rule 7 (global) block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall34-ipf.conf.orig0000755000175000017500000000742311733011756023102 0ustar sylvestresylvestre# # Rule 0 (global) pass in quick proto icmp from any to 192.168.1.1 keep state pass in quick proto icmp from any to 192.168.1.2 keep state pass in quick proto icmp from any to 192.168.1.3/30 keep state pass in quick proto icmp from any to 192.168.1.200 keep state pass in quick proto icmp from any to 192.168.1.201 keep state pass in quick proto icmp from any to 192.168.2.128/25 keep state pass in quick proto tcp from any to 192.168.1.1 keep state pass in quick proto tcp from any to 192.168.1.2 keep state pass in quick proto tcp from any to 192.168.1.3/30 keep state pass in quick proto tcp from any to 192.168.1.200 keep state pass in quick proto tcp from any to 192.168.1.201 keep state pass in quick proto tcp from any to 192.168.2.128/25 keep state pass in quick proto udp from any to 192.168.1.1 keep state pass in quick proto udp from any to 192.168.1.2 keep state pass in quick proto udp from any to 192.168.1.3/30 keep state pass in quick proto udp from any to 192.168.1.200 keep state pass in quick proto udp from any to 192.168.1.201 keep state pass in quick proto udp from any to 192.168.2.128/25 keep state pass in quick from any to 192.168.1.1 pass in quick from any to 192.168.1.2 pass in quick from any to 192.168.1.3/30 pass in quick from any to 192.168.1.200 pass in quick from any to 192.168.1.201 pass in quick from any to 192.168.2.128/25 pass out quick proto icmp from any to 192.168.1.1 keep state pass out quick proto icmp from any to 192.168.1.2 keep state pass out quick proto icmp from any to 192.168.1.3/30 keep state pass out quick proto icmp from any to 192.168.1.200 keep state pass out quick proto icmp from any to 192.168.1.201 keep state pass out quick proto icmp from any to 192.168.2.128/25 keep state pass out quick proto tcp from any to 192.168.1.1 keep state pass out quick proto tcp from any to 192.168.1.2 keep state pass out quick proto tcp from any to 192.168.1.3/30 keep state pass out quick proto tcp from any to 192.168.1.200 keep state pass out quick proto tcp from any to 192.168.1.201 keep state pass out quick proto tcp from any to 192.168.2.128/25 keep state pass out quick proto udp from any to 192.168.1.1 keep state pass out quick proto udp from any to 192.168.1.2 keep state pass out quick proto udp from any to 192.168.1.3/30 keep state pass out quick proto udp from any to 192.168.1.200 keep state pass out quick proto udp from any to 192.168.1.201 keep state pass out quick proto udp from any to 192.168.2.128/25 keep state pass out quick from any to 192.168.1.1 pass out quick from any to 192.168.1.2 pass out quick from any to 192.168.1.3/30 pass out quick from any to 192.168.1.200 pass out quick from any to 192.168.1.201 pass out quick from any to 192.168.2.128/25 # # Rule 7 (global) pass in quick proto tcp from any to 192.168.1.10 port = 25 keep state pass out quick proto tcp from any to 192.168.1.10 port = 25 keep state # # Rule 8 (global) pass in quick proto icmp from 192.168.1.0/24 to any keep state pass in quick proto tcp from 192.168.1.0/24 to any keep state pass in quick proto udp from 192.168.1.0/24 to any keep state pass in quick from 192.168.1.0/24 to any pass out quick proto icmp from 192.168.1.0/24 to any keep state pass out quick proto tcp from 192.168.1.0/24 to any keep state pass out quick proto udp from 192.168.1.0/24 to any keep state pass out quick from 192.168.1.0/24 to any # # Rule 9 (global) block in log quick from any to any block out log quick from any to any # # Rule fallback rule # fallback rule block in quick from any to any block out quick from any to any fwbuilder-5.1.0.3599/test/ipf/firewall2.fw.orig0000755000175000017500000000314511733011756021725 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v4.2.0.3499 # # Generated Sat Mar 12 19:44:27 2011 PST by vadim # # files: * firewall2.fw /etc/fw/firewall2.fw # files: firewall2-ipf.conf /etc/fw/firewall2-ipf.conf # files: firewall2-nat.conf /etc/fw/firewall2-nat.conf # # Compiled for ipf # # this object has several interfaces and shows different rules for NAT. Also testing policy rule options # firewall2:Policy:9: warning: Changing rule direction due to self reference # firewall2:NAT:17: warning: Expanding port range test-TCP creates 41 rules FWDIR=`dirname $0` IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { : } epilog_commands() { : } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:27 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C $IPF -I -f /etc/fw/firewall2-ipf.conf $IPNAT -f /etc/fw/firewall2-nat.conf $IPF -s epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -Efwbuilder-5.1.0.3599/test/ipfw/0000755000175000017500000000000011733011756016722 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/ipfw/firewall1.fw.orig0000755000175000017500000002056211733011756022115 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall1.fw /etc/firewall1.fw # # # # Compiled for ipfw # # this object is used to test all kinds of negation in policy rules # Currently negation in NAT is not supported for ipf, therefore all rules in NAT with # negation are disabled # firewall1:Policy:9: warning: Changing rule direction due to self reference # firewall1:Policy:9: warning: Changing rule direction due to self reference # firewall1:Policy:10: warning: Changing rule direction due to self reference # firewall1:Policy:13: warning: Changing rule direction due to self reference cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/Library/Application Support/PeerGuardian/ipfwFast" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (eth0) "$IPFW" add 10 set 1 skipto 130 icmp from 22.22.22.22 to 22.22.22.22 via eth0 || exit 1 "$IPFW" add 20 set 1 skipto 130 icmp from 22.22.22.22 to 192.168.1.1 via eth0 || exit 1 "$IPFW" add 30 set 1 skipto 130 icmp from 192.168.1.1 to 22.22.22.22 via eth0 || exit 1 "$IPFW" add 40 set 1 skipto 130 icmp from 192.168.1.1 to 192.168.1.1 via eth0 || exit 1 "$IPFW" add 50 set 1 skipto 130 50 from 22.22.22.22 to 22.22.22.22 via eth0 || exit 1 "$IPFW" add 60 set 1 skipto 130 50 from 22.22.22.22 to 192.168.1.1 via eth0 || exit 1 "$IPFW" add 70 set 1 skipto 130 50 from 192.168.1.1 to 22.22.22.22 via eth0 || exit 1 "$IPFW" add 80 set 1 skipto 130 50 from 192.168.1.1 to 192.168.1.1 via eth0 || exit 1 "$IPFW" add 90 set 1 drop log icmp from 22.22.22.22 to any via eth0 || exit 1 "$IPFW" add 100 set 1 drop log icmp from 192.168.1.1 to any via eth0 || exit 1 "$IPFW" add 110 set 1 drop log 50 from 22.22.22.22 to any via eth0 || exit 1 "$IPFW" add 120 set 1 drop log 50 from 192.168.1.1 to any via eth0 || exit 1 # # Rule 1 (eth0) "$IPFW" add 130 set 1 skipto 250 icmp from 192.168.1.10 to 192.168.1.10 via eth0 || exit 1 "$IPFW" add 140 set 1 skipto 250 icmp from 192.168.1.10 to 192.168.1.20 via eth0 || exit 1 "$IPFW" add 150 set 1 skipto 250 icmp from 192.168.1.20 to 192.168.1.10 via eth0 || exit 1 "$IPFW" add 160 set 1 skipto 250 icmp from 192.168.1.20 to 192.168.1.20 via eth0 || exit 1 "$IPFW" add 170 set 1 skipto 250 50 from 192.168.1.10 to 192.168.1.10 via eth0 || exit 1 "$IPFW" add 180 set 1 skipto 250 50 from 192.168.1.10 to 192.168.1.20 via eth0 || exit 1 "$IPFW" add 190 set 1 skipto 250 50 from 192.168.1.20 to 192.168.1.10 via eth0 || exit 1 "$IPFW" add 200 set 1 skipto 250 50 from 192.168.1.20 to 192.168.1.20 via eth0 || exit 1 "$IPFW" add 210 set 1 drop icmp from 192.168.1.10 to any via eth0 || exit 1 "$IPFW" add 220 set 1 drop icmp from 192.168.1.20 to any via eth0 || exit 1 "$IPFW" add 230 set 1 drop 50 from 192.168.1.10 to any via eth0 || exit 1 "$IPFW" add 240 set 1 drop 50 from 192.168.1.20 to any via eth0 || exit 1 # # Rule 2 (eth1) # Anti-spoofing rule "$IPFW" add 250 set 1 drop log all from me to any in recv eth1 || exit 1 "$IPFW" add 260 set 1 drop log all from 192.168.1.0/24 to any in recv eth1 || exit 1 # # Rule 3 (eth1) # Anti-spoofing rule "$IPFW" add 270 set 1 skipto 290 all from 192.168.1.0/24 to any out xmit eth1 || exit 1 "$IPFW" add 280 set 1 drop log all from any to any out xmit eth1 || exit 1 # # Rule 4 (lo) "$IPFW" add 290 set 1 permit all from any to any via lo keep-state || exit 1 # # Rule 5 (global) "$IPFW" add 300 set 1 drop log tcp from any to any tcpflags !fin,syn,!rst,!psh,!ack,!urg || exit 1 # # Rule 7 (global) # hostF has the same IP address as firewal. "$IPFW" add 310 set 1 permit log icmp from any to 192.168.1.1 icmptypes 8 keep-state || exit 1 # # Rule 8 (global) # testing negation in the policy rule "$IPFW" add 320 set 1 skipto 350 icmp from 192.168.1.10 to any icmptypes 3 || exit 1 "$IPFW" add 330 set 1 skipto 350 icmp from 192.168.1.20 to any icmptypes 3 || exit 1 "$IPFW" add 340 set 1 drop log icmp from any to any icmptypes 3 || exit 1 # # Rule 9 (global) # firewall1:Policy:9: warning: Changing rule direction due to self reference "$IPFW" add 350 set 1 skipto 380 icmp from 192.168.1.10 to me icmptypes 3 in || exit 1 "$IPFW" add 360 set 1 skipto 380 icmp from 192.168.1.20 to me icmptypes 3 in || exit 1 "$IPFW" add 370 set 1 drop log icmp from any to me icmptypes 3 in || exit 1 # # Rule 10 (global) # firewall1:Policy:10: warning: Changing rule direction due to self reference "$IPFW" add 380 set 1 skipto 410 all from me to 192.168.1.0/24 out || exit 1 "$IPFW" add 390 set 1 skipto 410 all from 192.168.2.0/24 to 192.168.1.0/24 || exit 1 "$IPFW" add 400 set 1 drop log all from any to 192.168.1.0/24 || exit 1 # # Rule 11 (global) "$IPFW" add 410 set 1 skipto 440 tcp from 22.22.22.0/24 to 192.168.1.10 80 || exit 1 "$IPFW" add 420 set 1 skipto 440 tcp from 33.33.33.0/24 to 192.168.1.10 80 || exit 1 "$IPFW" add 430 set 1 permit tcp from any to 192.168.1.10 80 setup keep-state || exit 1 # # Rule 12 (global) "$IPFW" add 440 set 1 skipto 500 all from 192.168.1.0/24 to 192.168.1.10 || exit 1 "$IPFW" add 450 set 1 skipto 500 all from 192.168.1.0/24 to 192.168.1.20 || exit 1 "$IPFW" add 460 set 1 skipto 500 all from 192.168.2.0/24 to 192.168.1.10 || exit 1 "$IPFW" add 470 set 1 skipto 500 all from 192.168.2.0/24 to 192.168.1.20 || exit 1 "$IPFW" add 480 set 1 drop log all from 192.168.1.0/24 to any || exit 1 "$IPFW" add 490 set 1 drop log all from 192.168.2.0/24 to any || exit 1 # # Rule 13 (global) # firewall1:Policy:13: warning: Changing rule direction due to self reference "$IPFW" add 500 set 1 skipto 520 all from any to me in || exit 1 "$IPFW" add 510 set 1 drop all from any to any || exit 1 # # Rule 16 (global) "$IPFW" add 520 set 1 skipto 640 icmp from 22.22.22.22 to 22.22.22.22 || exit 1 "$IPFW" add 530 set 1 skipto 640 icmp from 22.22.22.22 to 192.168.1.1 || exit 1 "$IPFW" add 540 set 1 skipto 640 icmp from 192.168.1.1 to 22.22.22.22 || exit 1 "$IPFW" add 550 set 1 skipto 640 icmp from 192.168.1.1 to 192.168.1.1 || exit 1 "$IPFW" add 560 set 1 skipto 640 50 from 22.22.22.22 to 22.22.22.22 || exit 1 "$IPFW" add 570 set 1 skipto 640 50 from 22.22.22.22 to 192.168.1.1 || exit 1 "$IPFW" add 580 set 1 skipto 640 50 from 192.168.1.1 to 22.22.22.22 || exit 1 "$IPFW" add 590 set 1 skipto 640 50 from 192.168.1.1 to 192.168.1.1 || exit 1 "$IPFW" add 600 set 1 drop log icmp from 22.22.22.22 to any || exit 1 "$IPFW" add 610 set 1 drop log icmp from 192.168.1.1 to any || exit 1 "$IPFW" add 620 set 1 drop log 50 from 22.22.22.22 to any || exit 1 "$IPFW" add 630 set 1 drop log 50 from 192.168.1.1 to any || exit 1 # # Rule 17 (global) # 'masquerading' rule "$IPFW" add 640 set 1 permit all from 192.168.1.0/24 to any keep-state || exit 1 # # Rule 18 (global) # 'catch all' rule "$IPFW" add 650 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 660 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/Makefile0000644000175000017500000000072611733011756020367 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) # CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_ipfw -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_ipfw -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/ipfw/run.all0000755000175000017500000000077711733011756020236 0ustar sylvestresylvestre#!/bin/sh XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipfw -v -f $XMLFILE -xt $fwobj" done exit 0 XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipfw -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/ipfw/firewall.fw.orig0000755000175000017500000001546711733011756022044 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:43 2011 PST by vadim # # files: * firewall.fw ipfw.fw # # # # Compiled for ipfw # # this is simple firewall with two interfaces. Test regular policy rules, including IP_fragments rule # firewall:Policy:3: warning: Changing rule direction due to self reference # firewall:Policy:9: warning: Changing rule direction due to self reference # firewall:Policy:20: warning: Changing rule direction due to self reference # firewall:Policy:6: warning: ipfw can not match "any IP option" # firewall:Policy:8: warning: ipfw can not match "any IP option" set -x cd /etc/fw || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/usr/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:43 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule backup ssh access rule # backup ssh access rule "$IPFW" add 9 set 1 permit tcp from me to 192.168.1.100 out established keep-state "$IPFW" add 10 set 1 permit tcp from 192.168.1.100 to me 22 in setup keep-state || exit 1 # # Rule 0 (eth1) "$IPFW" add 20 set 1 drop log all from any to me frag in recv eth1 || exit 1 # # Rule 1 (eth1) # Automatically generated rule blocking short fragments "$IPFW" add 30 set 1 drop log all from any to any frag in recv eth1 || exit 1 # # Rule 2 (eth1) # Automatically generated anti-spoofing rule "$IPFW" add 40 set 1 drop log all from me to any in recv eth1 || exit 1 "$IPFW" add 50 set 1 drop log all from 192.168.1.0/24 to any in recv eth1 || exit 1 # # Rule 3 (eth0) # аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ # firewall:Policy:3: warning: Changing rule direction due to self reference "$IPFW" add 60 set 1 permit udp from 192.168.1.0/24 to me 53 in recv eth0 keep-state || exit 1 # # Rule 4 (eth0) "$IPFW" add 70 set 1 drop log udp from any to 192.168.1.255 53 in recv eth0 || exit 1 # # Rule 5 (global) "$IPFW" add 80 set 1 drop log tcp from any to any tcpflags !fin,syn,!rst,!psh,!ack,!urg || exit 1 "$IPFW" add 90 set 1 drop log tcp from any to any tcpflags fin,syn,rst,!psh,ack,!urg || exit 1 # # Rule 6 (global) "$IPFW" add 100 set 1 unreach port log all from any to any || exit 1 # # Rule 7 (global) "$IPFW" add 110 set 1 unreach port log all from any to any ipoptions rr || exit 1 # # Rule 8 (global) "$IPFW" add 120 set 1 unreach port log all from any to any ipoptions rr || exit 1 "$IPFW" add 130 set 1 unreach port log all from any to any ipoptions lsrr,ssrr || exit 1 "$IPFW" add 140 set 1 unreach port log all from any to any ipoptions ts || exit 1 "$IPFW" add 150 set 1 unreach port log all from any to any || exit 1 # # Rule 9 (global) # firewall:Policy:9: warning: Changing rule direction due to self reference "$IPFW" add 160 set 1 unreach port 50 from any to me in || exit 1 # # Rule 12 (global) "$IPFW" add 170 set 1 permit tcp from 211.11.11.11 to 192.168.1.10 53 setup keep-state || exit 1 "$IPFW" add 180 set 1 permit tcp from 211.22.22.22 to 192.168.1.10 53 setup keep-state || exit 1 # # Rule 13 (global) "$IPFW" add 190 set 1 permit tcp from any to 192.168.1.10 10000-11000,113,13,53,2105,21,70,80,443,143,993,6667,6667,543,544,389,98,3306,2049,119,110,5432,515,26000,512,513,514,4321,25,465,1080,3128,22,111,23,540,7100 setup keep-state || exit 1 # # Rule 14 (global) "$IPFW" add 200 set 1 permit tcp from any to 192.168.1.11 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 # # Rule 15 (global) "$IPFW" add 210 set 1 permit tcp from any to 192.168.1.11 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 "$IPFW" add 220 set 1 permit tcp from any to 192.168.1.12/30 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 # # Rule 16 (global) "$IPFW" add 230 set 1 permit tcp from any to 192.168.1.11 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 "$IPFW" add 240 set 1 permit tcp from any to 192.168.1.12 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 "$IPFW" add 250 set 1 permit tcp from any to 192.168.1.13 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 "$IPFW" add 260 set 1 permit tcp from any to 192.168.1.14 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 "$IPFW" add 270 set 1 permit tcp from any to 192.168.1.15 113,80,443,143,25,3128,22,540 setup keep-state || exit 1 # # Rule 17 (global) "$IPFW" add 280 set 1 permit icmp from any to 192.168.1.0/24 icmptypes 3,0,11,11 keep-state || exit 1 "$IPFW" add 290 set 1 permit tcp from any to 192.168.1.0/24 3128 setup keep-state || exit 1 # # Rule 18 (global) "$IPFW" add 300 set 1 permit icmp from any to 192.168.1.0/24 icmptypes 3,0,11,11 keep-state || exit 1 "$IPFW" add 310 set 1 permit tcp from any 20 to 192.168.1.0/24 1024-65535 setup keep-state || exit 1 "$IPFW" add 320 set 1 permit tcp from any to 192.168.1.0/24 10000-11000 setup keep-state || exit 1 "$IPFW" add 330 set 1 permit tcp from any to 192.168.1.0/24 6000-6063,113,13,53,2105,21,70,80,443,143,993,6667,6667,543,544,389,98,3306,2049,119,110,5432,515,26000,512,513,514,4321,25,465,1080,3128,22,111,23,540,7100 setup keep-state || exit 1 # # Rule 19 (global) "$IPFW" add 340 set 1 permit log all from me to me keep-state || exit 1 # # Rule 20 (global) # Automatically generated 'masquerading' rule # firewall:Policy:20: warning: Changing rule direction due to self reference "$IPFW" add 350 set 1 permit all from me to any out keep-state || exit 1 "$IPFW" add 360 set 1 permit all from 192.168.1.0/24 to any keep-state || exit 1 # # Rule 21 (global) # Automatically generated 'catch all' rule "$IPFW" add 370 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 380 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/do-diff0000755000175000017500000000033211733011756020156 0ustar sylvestresylvestre#!/bin/sh N=$1 if which opendiff > /dev/null 2>&1; then TOOL="opendiff" elif which tkdiff > /dev/null 2>&1; then TOOL="tkdiff -b -B " else TOOL="diff -b -B " fi ${TOOL} firewall${N}.fw.orig firewall${N}.fw fwbuilder-5.1.0.3599/test/ipfw/quick-cmp.sh0000755000175000017500000000144111733011756021152 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -B -w -I \"Generated\" -I 'Activating ' -I 'Firewall Builder fwb_ipfw v' -I 'Can not find file' -I '====' -I 'log '" for f in $(ls *.fw.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done exit 0 run_diffs_for_file() { xmlfile=$1 folder=$2 fwbedit list -f $xmlfile -o $folder -c -F%name% | sort | while read fwobj; do V="$fwobj <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" done } run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls # run_diffs_for_file cluster-tests.fwb /User/Clusters fwbuilder-5.1.0.3599/test/ipfw/host.fw.orig0000755000175000017500000000564011733011756021204 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:45 2011 PST by vadim # # files: * host.fw /etc/host.fw # # # # Compiled for ipfw # # firewall protects host it is running on # host:Policy:4: warning: Changing rule direction due to self reference # host:Policy:5: warning: Changing rule direction due to self reference # host:Policy:6: warning: Changing rule direction due to self reference cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:45 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (eth0) "$IPFW" add 10 set 1 permit log all from me to me via eth0 keep-state || exit 1 # # Rule 1 (lo) # allow everything on loopback "$IPFW" add 20 set 1 permit all from any to me in recv lo keep-state || exit 1 # # Rule 2 (lo) # allow everything on loopback "$IPFW" add 30 set 1 permit all from me to any out xmit lo keep-state || exit 1 # # Rule 3 (lo) "$IPFW" add 40 set 1 permit log all from me to me via lo keep-state || exit 1 # # Rule 4 (global) # block fragments # host:Policy:4: warning: Changing rule direction due to self reference "$IPFW" add 50 set 1 drop log all from any to me frag in || exit 1 # # Rule 5 (global) # host:Policy:5: warning: Changing rule direction due to self reference "$IPFW" add 60 set 1 permit icmp from any to me icmptypes 3 in keep-state || exit 1 "$IPFW" add 70 set 1 permit tcp from any to me 21,80,25,22,23 in setup keep-state || exit 1 # # Rule 6 (global) # allow all outgoing connections # host:Policy:6: warning: Changing rule direction due to self reference "$IPFW" add 80 set 1 permit all from me to any out keep-state || exit 1 # # Rule 7 (global) # 'catch all' rule "$IPFW" add 90 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 100 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/firewall34.fw.orig0000755000175000017500000000435411733011756022204 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall34.fw /etc/firewall34.fw # # # # Compiled for ipfw # # Testing actions Pipe, Classify, Custom cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 # ================ IPv4 # ================ Rule set Policy # # Rule 0 (rl1) # port 8668 is natd "$IPFW" add 10 set 1 divert 8668 all from 192.168.1.0/24 to any via rl1 || exit 1 # # Rule 1 (global) # rule doing divert to natd (8668) should go before check-state "$IPFW" add 20 set 1 check-state all from any to any || exit 1 # # Rule 2 (global) "$IPFW" add 30 set 1 divert 1234 tcp from 192.168.1.0/24 to any 22 || exit 1 # # Rule 3 (global) "$IPFW" add 40 set 1 queue 2 tcp from 192.168.1.0/24 to any 22 || exit 1 # # Rule 4 (global) "$IPFW" add 50 set 1 pipe 1 tcp from 192.168.1.0/24 to any 80 || exit 1 # # Rule 5 (global) "$IPFW" add 60 set 1 prob .80 log all from 192.168.1.0/24 to any || exit 1 # # Rule 6 (global) "$IPFW" add 70 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 80 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/firewall9.fw.orig0000755000175000017500000000577711733011756022140 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall9.fw /etc/firewall9.fw # # # # Compiled for ipfw # # firewall9:Policy:5: warning: Changing rule direction due to self reference cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (firewall9:eth1) "$IPFW" add 10 set 1 skipto 30 all from 33.33.33.0/24 to any in recv firewall9:eth1 || exit 1 "$IPFW" add 20 set 1 drop log all from any to any in recv firewall9:eth1 || exit 1 # # Rule 1 (firewall9:eth1) "$IPFW" add 30 set 1 permit icmp from 33.33.33.0/24 to 192.168.1.10 icmptypes 3,0,11,11 in recv firewall9:eth1 keep-state || exit 1 "$IPFW" add 40 set 1 permit tcp from 33.33.33.0/24 to 192.168.1.10 22 in recv firewall9:eth1 setup keep-state || exit 1 # # Rule 2 (firewall9:eth1) "$IPFW" add 50 set 1 skipto 80 all from me to any in recv firewall9:eth1 || exit 1 "$IPFW" add 60 set 1 skipto 80 all from 192.168.1.0/24 to any in recv firewall9:eth1 || exit 1 "$IPFW" add 70 set 1 permit all from any to any in recv firewall9:eth1 keep-state || exit 1 # # Rule 3 (global) "$IPFW" add 80 set 1 count all from any to any || exit 1 # # Rule 4 (global) "$IPFW" add 90 set 1 count log all from any to any || exit 1 # # Rule 5 (global) # firewall9:Policy:5: warning: Changing rule direction due to self reference "$IPFW" add 100 set 1 permit tcp from any to me 22 in setup keep-state || exit 1 # # Rule 6 (global) "$IPFW" add 110 set 1 permit all from 192.168.1.0/24 to any keep-state || exit 1 # # Rule 7 (global) "$IPFW" add 120 set 1 permit tcp from any to any established || exit 1 # # Rule 8 (global) "$IPFW" add 130 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 140 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/firewall8.fw.orig0000755000175000017500000000436011733011756022122 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall8.fw /etc/firewall8.fw # # # # Compiled for ipfw # # firewall8:Policy:0: warning: Changing rule direction due to self reference cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (global) # firewall8:Policy:0: warning: Changing rule direction due to self reference "$IPFW" add 10 set 1 permit tcp from any to me 22 in setup keep-state || exit 1 # # Rule 1 (global) "$IPFW" add 20 set 1 permit tcp from any to 33.33.33.33 22 setup keep-state || exit 1 "$IPFW" add 30 set 1 permit tcp from any to 33.33.33.34 22 setup keep-state || exit 1 # # Rule 2 (global) "$IPFW" add 40 set 1 permit tcp from any to 33.33.33.33 22 setup keep-state || exit 1 # # Rule 3 (global) "$IPFW" add 50 set 1 permit tcp from any to 33.33.33.34 22 setup keep-state || exit 1 # # Rule 4 (global) "$IPFW" add 60 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 70 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/recycle0000755000175000017500000000007511733011756020300 0ustar sylvestresylvestre#!/bin/sh for f in *.fw; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/ipfw/firewall4.fw.orig0000755000175000017500000000730711733011756022122 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall4.fw /etc/firewall4.fw # # # # Compiled for ipfw # # this object is used to test a configuration where firewall has dynamic address # firewall4::: error: Dynamic interface eth1 should not have an IP address object attached to it. This IP address object will be ignored. # firewall4:Policy:6: warning: Changing rule direction due to self reference # firewall4:Policy:6: warning: Changing rule direction due to self reference cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/usr/sbin/ipf" IPNAT="/usr/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (eth1) # Anti-spoofing rule "$IPFW" add 10 set 1 drop log all from me to any in recv eth1 || exit 1 "$IPFW" add 20 set 1 drop log all from 192.168.1.0/24 to any in recv eth1 || exit 1 # # Rule 1 (eth1) # Anti-spoofing rule "$IPFW" add 30 set 1 skipto 60 all from me to any out xmit eth1 || exit 1 "$IPFW" add 40 set 1 skipto 60 all from 192.168.1.0/24 to any out xmit eth1 || exit 1 "$IPFW" add 50 set 1 drop log all from any to any out xmit eth1 || exit 1 # # Rule 2 (eth1) "$IPFW" add 60 set 1 drop log icmp from any to any icmptypes 8 via eth1 || exit 1 # # Rule 3 (eth1) "$IPFW" add 70 set 1 skipto 90 icmp from 192.168.2.0/24 to any icmptypes 8 via eth1 || exit 1 "$IPFW" add 80 set 1 drop log icmp from any to any icmptypes 8 via eth1 || exit 1 # # Rule 4 (global) # hostF has the same IP address as firewal. "$IPFW" add 90 set 1 permit log icmp from any to 192.168.1.1 icmptypes 8 keep-state || exit 1 # # Rule 5 (global) # testing negation in the policy rule "$IPFW" add 100 set 1 skipto 130 icmp from 192.168.1.10 to any icmptypes 3 || exit 1 "$IPFW" add 110 set 1 skipto 130 icmp from 192.168.1.20 to any icmptypes 3 || exit 1 "$IPFW" add 120 set 1 drop log icmp from any to any icmptypes 3 || exit 1 # # Rule 6 (global) # firewall4:Policy:6: warning: Changing rule direction due to self reference "$IPFW" add 130 set 1 skipto 160 icmp from 192.168.1.10 to me icmptypes 3 in || exit 1 "$IPFW" add 140 set 1 skipto 160 icmp from 192.168.1.20 to me icmptypes 3 in || exit 1 "$IPFW" add 150 set 1 drop log icmp from any to me icmptypes 3 in || exit 1 # # Rule 8 (global) # 'masquerading' rule "$IPFW" add 160 set 1 permit all from 192.168.1.0/24 to any keep-state || exit 1 # # Rule 10 (global) # 'catch all' rule "$IPFW" add 170 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 180 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/mac.fw.orig0000755000175000017500000000572211733011756020770 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:45 2011 PST by vadim # # files: * mac.fw /etc/mac.fw # # # # Compiled for ipfw # # mac:Policy:1: warning: Changing rule direction due to self reference # mac:Policy:3: warning: Changing rule direction due to self reference # mac:Policy:4: warning: Changing rule direction due to self reference set -x cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" IPFW="/sbin/ipfw" SYSCTL="/usr/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : $SYSCTL -w net.inet.ip.forwarding=1 $SYSCTL -w net.inet.ip.sourceroute=0 $SYSCTL -w net.inet.ip.redirect=0 } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:45 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (lo0) "$IPFW" add 10 set 1 permit all from any to any via lo0 keep-state || exit 1 # # Rule 1 (global) # mac:Policy:1: warning: Changing rule direction due to self reference "$IPFW" add 20 set 1 permit tcp from any to me established in keep-state || exit 1 # # Rule 2 (global) "$IPFW" add 30 set 1 drop log all from any to any frag || exit 1 "$IPFW" add 40 set 1 drop log tcp from any to any tcpflags fin,syn,!rst,psh,ack,urg || exit 1 # # Rule 3 (global) # mac:Policy:3: warning: Changing rule direction due to self reference "$IPFW" add 50 set 1 permit icmp from any to me icmptypes 3,0,11,11 in keep-state || exit 1 "$IPFW" add 60 set 1 permit tcp from any to me 25,22 in setup keep-state || exit 1 "$IPFW" add 70 set 1 permit udp from any to me in keep-state || exit 1 # # Rule 4 (global) # mac:Policy:4: warning: Changing rule direction due to self reference "$IPFW" add 80 set 1 permit icmp from me to any icmptypes 3,0,11,11 out keep-state || exit 1 "$IPFW" add 90 set 1 permit tcp from me to any out setup keep-state || exit 1 "$IPFW" add 100 set 1 permit udp from me to any 68,67,53 out keep-state || exit 1 # # Rule 5 (global) "$IPFW" add 110 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 120 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/objects-for-regression-tests.fwb0000644000175000017500000107566611733011756025202 0ustar sylvestresylvestre -m ip_conntrack_talk -m ip_nat_talk established established established -m state --state ESTABLISHED,RELATED fwbuilder-5.1.0.3599/test/ipfw/firewall7.fw.orig0000755000175000017500000000343011733011756022116 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall7.fw /etc/firewall7.fw # # # # Compiled for ipfw # # testing rules with broadcasts cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (eth0) "$IPFW" add 10 set 1 drop log all from any to 192.168.1.255 in recv eth0 || exit 1 # # Rule 1 (eth1) "$IPFW" add 20 set 1 drop log all from any to me in recv eth1 || exit 1 # # Rule 2 (global) "$IPFW" add 30 set 1 permit udp from any to 192.168.1.255 68 keep-state || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 40 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/firewall2.fw.orig0000755000175000017500000000762011733011756022116 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall2.fw /etc/firewall2.fw # # # # Compiled for ipfw # # this object has several interfaces and shows different rules for NAT. Also testing policy rule options # firewall2:Policy:12: warning: Changing rule direction due to self reference cd /etc || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (eth1) "$IPFW" add 10 set 1 permit tcp from any to any established in recv eth1 keep-state || exit 1 # # Rule 1 (eth1) "$IPFW" add 20 set 1 permit tcp from any to any established in recv eth1 || exit 1 # # Rule 2 (eth1) "$IPFW" add 30 set 1 permit tcp from any 80 to any established in recv eth1 || exit 1 # # Rule 3 (eth1) # Anti-spoofing rule "$IPFW" add 40 set 1 drop log all from me to any in recv eth1 || exit 1 "$IPFW" add 50 set 1 drop log all from 192.168.1.0/24 to any in recv eth1 || exit 1 # # Rule 4 (eth1) # Anti-spoofing rule "$IPFW" add 60 set 1 skipto 90 all from me to any out xmit eth1 || exit 1 "$IPFW" add 70 set 1 skipto 90 all from 192.168.1.0/24 to any out xmit eth1 || exit 1 "$IPFW" add 80 set 1 drop log all from any to any out xmit eth1 || exit 1 # # Rule 5 (global) # block fragments "$IPFW" add 90 set 1 drop log all from any to any frag || exit 1 # # Rule 6 (global) # sends TCP RST and makes custom record in the log "$IPFW" add 100 set 1 reset log tcp from any to any 113 || exit 1 # # Rule 7 (global) # sends TCP RST and makes custom record in the log "$IPFW" add 110 set 1 unreach net log udp from any to any 161 || exit 1 # # Rule 8 (global) "$IPFW" add 120 set 1 permit all from 192.168.1.10 to 200.200.200.200 keep-state || exit 1 "$IPFW" add 130 set 1 permit all from 192.168.1.20 to 200.200.200.200 keep-state || exit 1 # # Rule 9 (global) "$IPFW" add 140 set 1 permit all from 200.200.200.200 to 192.168.1.10 keep-state || exit 1 "$IPFW" add 150 set 1 permit all from 200.200.200.200 to 192.168.1.20 keep-state || exit 1 # # Rule 10 (global) # 'masquerading' rule "$IPFW" add 160 set 1 permit all from 192.168.1.0/24 to any keep-state || exit 1 # # Rule 11 (global) # host-fw2 has the same address as # one of the firewall's interfaces "$IPFW" add 170 set 1 permit log tcp from any to 22.22.22.22 21 setup keep-state || exit 1 # # Rule 12 (global) # firewall2:Policy:12: warning: Changing rule direction due to self reference "$IPFW" add 180 set 1 permit log tcp from any to me 21 in setup keep-state || exit 1 # # Rule 13 (global) # 'catch all' rule "$IPFW" add 190 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 200 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/ipfw/firewall33.fw.orig0000755000175000017500000002123411733011756022177 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v4.2.0.3499 # # Generated Sat Mar 12 19:44:44 2011 PST by vadim # # files: * firewall33.fw /etc/fw/firewall33.fw # # # # Compiled for ipfw # # testing DNSName object # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode cd /etc/fw || exit 1 IFCONFIG="/sbin/ifconfig" PFCTL="/sbin/pfctl" IPFW="/sbin/ipfw" IPF="/sbin/ipf" IPNAT="/sbin/ipnat" SYSCTL="/sbin/sysctl" LOGGER="/usr/bin/logger" log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } verify_interfaces() { : } set_kernel_vars() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : update_addresses_of_interface "eth1 192.168.1.100/0xffffff00" "" update_addresses_of_interface "lo 127.0.0.1/0xff000000" "" } log "Activating firewall script generated Sat Mar 12 19:44:44 2011 by vadim" set_kernel_vars configure_interfaces prolog_commands "$IPFW" set disable 1 "$IPFW" add 1 set 1 check-state ip from any to any # ================ IPv4 # ================ Rule set Policy # # Rule 0 (global) "$IPFW" add 10 set 1 permit all from 157.166.224.25 to any keep-state || exit 1 "$IPFW" add 20 set 1 permit all from 157.166.224.26 to any keep-state || exit 1 "$IPFW" add 30 set 1 permit all from 157.166.226.25 to any keep-state || exit 1 "$IPFW" add 40 set 1 permit all from 157.166.226.26 to any keep-state || exit 1 "$IPFW" add 50 set 1 permit all from 157.166.255.18 to any keep-state || exit 1 "$IPFW" add 60 set 1 permit all from 157.166.255.19 to any keep-state || exit 1 # # Rule 1 (global) "$IPFW" add 70 set 1 permit all from www.cnn.com to any keep-state || exit 1 # # Rule 2 (global) # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode "$IPFW" add 80 set 1 permit all from 192.0.2.1 to any keep-state || exit 1 # # Rule 3 (global) "$IPFW" add 90 set 1 permit all from buildmaster to any keep-state || exit 1 # # Rule 4 (global) "$IPFW" add 100 set 1 skipto 170 all from any to 157.166.224.25 || exit 1 "$IPFW" add 110 set 1 skipto 170 all from any to 157.166.224.26 || exit 1 "$IPFW" add 120 set 1 skipto 170 all from any to 157.166.226.25 || exit 1 "$IPFW" add 130 set 1 skipto 170 all from any to 157.166.226.26 || exit 1 "$IPFW" add 140 set 1 skipto 170 all from any to 157.166.255.18 || exit 1 "$IPFW" add 150 set 1 skipto 170 all from any to 157.166.255.19 || exit 1 "$IPFW" add 160 set 1 drop all from any to any || exit 1 # # Rule 5 (global) "$IPFW" add 170 set 1 skipto 190 all from any to www.cnn.com || exit 1 "$IPFW" add 180 set 1 drop all from any to any || exit 1 # # Rule 6 (global) # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode "$IPFW" add 190 set 1 skipto 210 all from any to 192.0.2.1 || exit 1 "$IPFW" add 200 set 1 permit all from any to any keep-state || exit 1 # # Rule 7 (global) "$IPFW" add 210 set 1 skipto 230 all from any to buildmaster || exit 1 "$IPFW" add 220 set 1 permit all from any to any keep-state || exit 1 # # Rule 8 (global) "$IPFW" add 230 set 1 skipto 350 all from any to 74.125.224.48 || exit 1 "$IPFW" add 240 set 1 skipto 350 all from any to 74.125.224.49 || exit 1 "$IPFW" add 250 set 1 skipto 350 all from any to 74.125.224.50 || exit 1 "$IPFW" add 260 set 1 skipto 350 all from any to 74.125.224.51 || exit 1 "$IPFW" add 270 set 1 skipto 350 all from any to 74.125.224.52 || exit 1 "$IPFW" add 280 set 1 skipto 350 all from any to 157.166.224.25 || exit 1 "$IPFW" add 290 set 1 skipto 350 all from any to 157.166.224.26 || exit 1 "$IPFW" add 300 set 1 skipto 350 all from any to 157.166.226.25 || exit 1 "$IPFW" add 310 set 1 skipto 350 all from any to 157.166.226.26 || exit 1 "$IPFW" add 320 set 1 skipto 350 all from any to 157.166.255.18 || exit 1 "$IPFW" add 330 set 1 skipto 350 all from any to 157.166.255.19 || exit 1 "$IPFW" add 340 set 1 permit all from any to any keep-state || exit 1 # # Rule 9 (global) "$IPFW" add 350 set 1 skipto 380 all from any to www.google.com || exit 1 "$IPFW" add 360 set 1 skipto 380 all from any to www.cnn.com || exit 1 "$IPFW" add 370 set 1 permit all from any to any keep-state || exit 1 # # Rule 10 (global) "$IPFW" add 380 set 1 skipto 460 all from any to www.google.com || exit 1 "$IPFW" add 390 set 1 skipto 460 all from any to 157.166.224.25 || exit 1 "$IPFW" add 400 set 1 skipto 460 all from any to 157.166.224.26 || exit 1 "$IPFW" add 410 set 1 skipto 460 all from any to 157.166.226.25 || exit 1 "$IPFW" add 420 set 1 skipto 460 all from any to 157.166.226.26 || exit 1 "$IPFW" add 430 set 1 skipto 460 all from any to 157.166.255.18 || exit 1 "$IPFW" add 440 set 1 skipto 460 all from any to 157.166.255.19 || exit 1 "$IPFW" add 450 set 1 permit all from any to any keep-state || exit 1 # # Rule 11 (global) "$IPFW" add 460 set 1 drop log all from any to any || exit 1 # # Rule fallback rule # fallback rule "$IPFW" add 470 set 1 drop all from any to any || exit 1 epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1fwbuilder-5.1.0.3599/test/combined/0000755000175000017500000000000011733011756017535 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/combined/objects.fwb0000644000175000017500000007444711733011756021706 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/test/pix/0000755000175000017500000000000011733011756016555 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/pix/firewall1.fw.orig0000755000175000017500000001046711733011756021753 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:01 2011 PDT by vadim ! ! Compiled for pix 6.1 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall1.fw ! ! this object is used to test all kinds of negation in policy rules ! firewall1::: error: Dynamic interface eth1 should not have an IP address object attached to it. This IP address object will be ignored. ! C firewall1:Policy:9: error: Dynamic interface can be used in the policy rule only in v6.3 or later. ! C firewall1:Policy:9: error: Dynamic interface can be used in the policy rule only in v6.3 or later. ! N firewall1:NAT:4: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'dmz' is going to be used as real and mapped interface in the generated nat command. ! N firewall1:NAT:5: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'dmz' is going to be used as real and mapped interface in the generated nat command. ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0 inside security100 nameif eth1 outside security0 nameif eth2 dmz security50 no logging buffered no logging console no logging timestamp no logging on telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server no service resetinbound no service resetoutside no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound no sysopt route dnat floodguard disable !################ ! ! Rule 2 (eth1) ! Anti-spoofing rule access-list outside_acl_in deny ip host 192.168.1.1 any access-list outside_acl_in deny ip host 192.168.2.1 any access-list outside_acl_in deny ip 192.168.1.0 255.255.255.0 any ! ! Rule 3 (eth0) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 4 (eth1) icmp permit any 8 outside access-list outside_acl_in permit icmp any interface outside 8 icmp permit any 11 outside access-list outside_acl_in permit icmp any interface outside 11 ! ! Rule 5 (eth1) access-list outside_acl_in permit icmp any any 8 access-list outside_acl_in permit icmp any any 11 ! ! Rule 6 (eth1,eth2) access-list outside_acl_in permit icmp any interface outside 8 access-list outside_acl_in permit icmp any interface outside 11 icmp permit any 8 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 8 icmp permit any 11 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 11 ! ! Rule 9 (global) ! firewall1:Policy:9: error: Dynamic interface can be used in the policy rule only in v6.3 or later. telnet 0.0.0.0 0.0.0.0 inside telnet 0.0.0.0 0.0.0.0 dmz ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 dmz ! ! Rule 11 (global) ! hostF has the same IP address as firewal. icmp permit any 8 inside access-list inside_acl_in permit icmp any host 192.168.1.1 8 ! ! Rule 19 (global) ! 'masquerading' rule access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 20 (global) ! 'catch all' rule access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 1 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.10 255.255.255.255 0 0 ! ! Rule 4 (NAT) ! firewall1:NAT:4: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'dmz' is going to be used as real and mapped interface in the generated nat command. global (outside) 2 interface nat (inside) 2 192.168.1.0 255.255.255.0 0 0 global (dmz) 2 interface ! nat (dmz) 2 192.168.2.0 255.255.255.0 0 0 ! ! ! Rule 5 (NAT) ! firewall1:NAT:5: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'dmz' is going to be used as real and mapped interface in the generated nat command. ! ! ! ! ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/cluster1_pix2.fw.orig0000755000175000017500000001536311733011756022571 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:17 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: yes ! Assume firewall is part of any: yes ! !# files: * cluster1_pix2.fw ! ! ! pix2::: warning: Interface Ethernet0 has vlan subinterfaces, it can not be used for ACL. Marking this interface "unprotected" to exclude it. ! ! Prolog script: ! ! ! End of prolog script: ! hostname pix2 interface Ethernet1 nameif inside ip address 10.3.14.207 255.255.255.0 standby 10.3.14.206 security-level 100 exit interface Ethernet0 no nameif no ip address no security-level exit interface Ethernet2 description LAN/STATE Failover Interface no nameif exit interface Ethernet0.101 vlan 101 nameif outside ip address 192.0.2.254 255.255.255.0 standby 192.0.2.253 security-level 0 exit interface Ethernet0.102 vlan 102 nameif dmz20 ip address 10.0.0.254 255.255.255.0 standby 10.0.0.253 security-level 20 exit failover lan unit secondary failover lan interface failover Ethernet2 failover lan enable failover key super_secret failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover link failover Ethernet2 failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global !################ clear xlate clear config static clear config global clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object-group network id2913X78273.src.net.0 network-object host 10.3.14.206 network-object host 10.3.14.207 exit object-group network id2913X78273.src.net.1 network-object host 172.17.1.253 network-object host 172.17.1.254 network-object host 192.0.2.253 network-object host 192.0.2.254 exit object-group network id2913X78273.src.net.2 network-object host 10.0.0.253 network-object host 10.0.0.254 exit object-group network id55439X897.src.net.0 network-object host 172.17.1.253 network-object host 192.0.2.253 exit object-group network id3401X82678.dst.net.0 network-object host 172.17.1.254 network-object host 192.0.2.254 exit ! ! Rule 0 (Ethernet0.101) ! anti spoofing rule access-list outside_in deny ip object-group id2913X78273.src.net.0 any log 3 interval 300 access-list outside_in deny ip object-group id2913X78273.src.net.1 any log 3 interval 300 access-list outside_in deny ip object-group id2913X78273.src.net.2 any log 3 interval 300 access-list outside_in deny ip 10.3.14.0 255.255.255.0 any log 3 interval 300 ! ! Rule 1 (global) ! SSH Access to firewall is permitted ! only from internal network ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 2 (global) ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 3 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp host 10.3.14.206 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp object-group id55439X897.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp host 10.0.0.253 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 ! ! Rule 4 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp object-group id2913X78273.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp object-group id2913X78273.src.net.1 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp object-group id2913X78273.src.net.2 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 ! ! Rule 5 (Ethernet0.101,Ethernet0.102) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ! ! Rule 6 (cl1 itf) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ! ! Rule 7 (Ethernet0.101,Ethernet0.102) access-list outside_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list outside_out permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_out permit udp any 10.3.14.0 255.255.255.0 eq 53 ! ! Rule 8 (cl1 itf) access-list outside_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list outside_out permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_out permit udp any 10.3.14.0 255.255.255.0 eq 53 ! ! Rule 9 (global) ! All other attempts to connect to ! the firewall are denied and logged access-list inside_in deny ip any object-group id2913X78273.src.net.0 log 3 interval 300 access-list inside_in deny ip any object-group id2913X78273.src.net.1 log 3 interval 300 access-list inside_in deny ip any object-group id2913X78273.src.net.2 log 3 interval 300 ! ! Rule 10 (global) access-list inside_in permit ip 10.3.14.0 255.255.255.0 any access-list inside_out permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 11 (global) access-list inside_in deny ip any any log 3 interval 300 access-list inside_out deny ip any any log 3 interval 300 access-group dmz20_in in interface dmz20 access-group dmz20_out out interface dmz20 access-group inside_in in interface inside access-group inside_out out interface inside access-group outside_in in interface outside access-group outside_out out interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id4606X78273.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id4606X78273.0 tcp 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/Makefile0000644000175000017500000000072211733011756020216 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_pix -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_pix -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/pix/cluster1_pix1.fw.orig0000755000175000017500000001517011733011756022564 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:17 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: yes ! Assume firewall is part of any: yes ! !# files: * cluster1_pix1.fw ! ! ! pix1::: warning: Interface Ethernet0 has vlan subinterfaces, it can not be used for ACL. Marking this interface "unprotected" to exclude it. ! ! Prolog script: ! ! ! End of prolog script: ! hostname pix1 interface Ethernet1 nameif inside ip address 10.3.14.206 255.255.255.0 standby 10.3.14.207 security-level 100 exit interface Ethernet0 no nameif no ip address no security-level exit interface Ethernet2 description LAN/STATE Failover Interface no nameif exit interface Ethernet0.101 vlan 101 nameif outside ip address 192.0.2.253 255.255.255.0 standby 192.0.2.254 security-level 0 exit interface Ethernet0.102 vlan 102 nameif dmz20 ip address 10.0.0.253 255.255.255.0 standby 10.0.0.254 security-level 20 exit failover lan unit primary failover lan interface failover Ethernet2 failover lan enable failover key super_secret failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover link failover Ethernet2 failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global !################ clear xlate clear config static clear config global clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object-group network id2913X78273.src.net.0 network-object host 10.3.14.206 network-object host 10.3.14.207 exit object-group network id2913X78273.src.net.1 network-object host 172.17.1.253 network-object host 172.17.1.254 network-object host 192.0.2.253 network-object host 192.0.2.254 exit object-group network id2913X78273.src.net.2 network-object host 10.0.0.253 network-object host 10.0.0.254 exit object-group network id55439X897.src.net.0 network-object host 172.17.1.253 network-object host 192.0.2.253 exit ! ! Rule 0 (Ethernet0.101) ! anti spoofing rule access-list outside_in deny ip object-group id2913X78273.src.net.0 any log 2 interval 300 access-list outside_in deny ip object-group id2913X78273.src.net.1 any log 2 interval 300 access-list outside_in deny ip object-group id2913X78273.src.net.2 any log 2 interval 300 access-list outside_in deny ip 10.3.14.0 255.255.255.0 any log 2 interval 300 ! ! Rule 1 (global) ! SSH Access to firewall is permitted ! only from internal network ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 2 (global) ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 3 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp host 10.3.14.206 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp object-group id55439X897.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp host 10.0.0.253 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 ! ! Rule 4 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp object-group id2913X78273.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp object-group id2913X78273.src.net.1 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp object-group id2913X78273.src.net.2 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 ! ! Rule 5 (Ethernet0.101,Ethernet0.102) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ! ! Rule 6 (cl1 itf) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ssh 0.0.0.0 0.0.0.0 dmz20 ! ! Rule 7 (Ethernet0.101,Ethernet0.102) access-list outside_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list outside_out permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_out permit udp any 10.3.14.0 255.255.255.0 eq 53 ! ! Rule 8 (cl1 itf) access-list outside_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list outside_out permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_in permit udp any 10.3.14.0 255.255.255.0 eq 53 access-list dmz20_out permit udp any 10.3.14.0 255.255.255.0 eq 53 ! ! Rule 9 (global) ! All other attempts to connect to ! the firewall are denied and logged access-list inside_in deny ip any object-group id2913X78273.src.net.0 log 2 interval 300 access-list inside_in deny ip any object-group id2913X78273.src.net.1 log 2 interval 300 access-list inside_in deny ip any object-group id2913X78273.src.net.2 log 2 interval 300 ! ! Rule 10 (global) access-list inside_in permit ip 10.3.14.0 255.255.255.0 any access-list inside_out permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 11 (global) access-list inside_in deny ip any any log 2 interval 300 access-list inside_out deny ip any any log 2 interval 300 access-group dmz20_in in interface dmz20 access-group dmz20_out out interface dmz20 access-group inside_in in interface inside access-group inside_out out interface inside access-group outside_in in interface outside access-group outside_out out interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id4606X78273.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id4606X78273.0 tcp 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/fwsm2.fw.orig0000755000175000017500000003173411733011756021123 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:15 2011 PDT by vadim ! ! Compiled for fwsm 4.x ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * fwsm2.fw ! ! C fwsm2:Policy:18: error: Rule '18 (global)' shadows rule '20 (global)' below it ! C fwsm2:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C fwsm2:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule ! ! Prolog script: ! ! ! End of prolog script: ! hostname fwsm2 interface ethernet1 nameif outside security-level 0 exit interface ethernet0 nameif inside security-level 100 exit interface ethernet2 nameif dmz security-level 50 exit logging host inside 192.168.1.30 logging queue 512 logging facility 16 logging trap 0 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear config ssh aaa authentication ssh console LOCAL ssh timeout 5 clear config snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 poll snmp-server host inside 192.168.1.22 trap no service resetinbound sysopt connection tcpmss 1380 sysopt nodnsalias inbound sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect ils inspect rsh inspect rtsp inspect sip inspect skinny inspect esmtp inspect sqlnet service-policy global_policy global !################ access-list mode auto clear config access-list tmp_acl access-list tmp_acl permit ip 192.168.1.0 255.255.255.0 any access-list tmp_acl deny ip any any access-group tmp_acl in interface outside access-group tmp_acl in interface inside access-group tmp_acl in interface dmz clear xlate clear config static clear config global clear config nat clear config access-list dmz_acl_in clear config access-list inside_acl_in clear config access-list outside_acl_in clear config icmp clear config telnet clear config object-group object-group network id17298X54624.dst.net.0 network-object host 211.11.11.11 network-object host 211.22.22.22 exit object-group service id17298X54624.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 22 port-object eq 540 exit object-group icmp-type id17335X54624.srv.icmp.0 icmp-object 3 icmp-object 0 icmp-object 11 exit object-group service id17347X54624.srv.tcp.0 tcp port-object eq 70 port-object eq 6667 port-object eq 3128 port-object eq 23 exit object-group service id17347X54624.srv.udp.0 udp port-object eq 53 port-object eq 161 exit object-group network id17384X54624.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit object-group network id17398X54624.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id17410X54624.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id17435X54624.dst.net.0 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 exit object-group service id17435X54624.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 3128 port-object eq 22 port-object eq 540 exit object-group network id17448X54624.dst.net.0 network-object 192.168.1.11 255.255.255.255 network-object 192.168.1.12 255.255.255.252 exit object-group service id17461X54624.srv.tcp.0 tcp port-object eq 113 port-object eq 13 port-object eq 53 port-object eq 2105 port-object eq 21 port-object eq 70 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 993 port-object eq 6667 port-object eq 6667 port-object eq 543 port-object eq 544 port-object eq 389 port-object eq 98 port-object eq 3306 port-object eq 2049 port-object eq 119 port-object eq 110 port-object eq 5432 port-object eq 515 port-object eq 26000 port-object eq 512 port-object eq 513 port-object eq 514 port-object eq 4321 port-object eq 25 port-object eq 465 port-object eq 1080 port-object eq 3128 port-object eq 22 port-object eq 111 port-object eq 23 port-object range 10000 11000 port-object eq 540 port-object eq 7100 exit ! ! Rule 2 (ethernet1) icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list outside_acl_in permit icmp any any 3 ! ! Rule 3 (ethernet1) ! anti-spoofing rule ! fwsm2:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 4 (ethernet0) ssh 192.168.1.0 255.255.255.0 inside ! ! Rule 5 (ethernet0) access-list inside_acl_in permit tcp any object-group id17298X54624.dst.net.0 object-group id17298X54624.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id17298X54624.dst.net.0 object-group id17298X54624.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id17298X54624.dst.net.0 object-group id17298X54624.srv.tcp.0 ! ! Rule 6 (ethernet0) access-list inside_acl_in deny ip any host 192.168.1.255 ! ! Rule 8 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id17335X54624.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id17335X54624.srv.icmp.0 access-list dmz_acl_in permit icmp any host 192.168.1.10 object-group id17335X54624.srv.icmp.0 ! ! Rule 9 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 access-list inside_acl_in permit icmp any host 192.168.1.10 access-list dmz_acl_in permit icmp any host 192.168.1.10 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id17347X54624.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id17347X54624.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group id17347X54624.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group id17347X54624.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group id17347X54624.srv.udp.0 access-list dmz_acl_in permit udp any host 192.168.1.10 object-group id17347X54624.srv.udp.0 access-list outside_acl_in permit 47 any host 192.168.1.10 access-list inside_acl_in permit 47 any host 192.168.1.10 access-list dmz_acl_in permit 47 any host 192.168.1.10 ! ! Rule 10 (global) access-list outside_acl_in permit icmp any host 22.22.22.22 3 log 0 interval 300 icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 log 0 interval 300 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 log 0 interval 300 access-list outside_acl_in permit icmp any any 3 log 0 interval 300 access-list inside_acl_in permit icmp any any 3 log 0 interval 300 access-list dmz_acl_in permit icmp any any 3 log 0 interval 300 access-list outside_acl_in permit 47 any any log 0 interval 300 access-list inside_acl_in permit 47 any any log 0 interval 300 access-list dmz_acl_in permit 47 any any log 0 interval 300 access-list outside_acl_in permit 50 any any log 0 interval 300 access-list inside_acl_in permit 50 any any log 0 interval 300 access-list dmz_acl_in permit 50 any any log 0 interval 300 ! ! Rule 12 (global) access-list outside_acl_in permit ip object-group id17298X54624.dst.net.0 object-group id17384X54624.dst.net.0 ! ! Rule 13 (global) ! fwsm2:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule access-list inside_acl_in permit tcp host 192.168.1.10 object-group id17398X54624.dst.net.0 eq 3128 ! ! Rule 14 (global) access-list outside_acl_in permit tcp any object-group id17410X54624.dst.net.0 eq 3128 access-list inside_acl_in permit tcp any object-group id17410X54624.dst.net.0 eq 3128 access-list dmz_acl_in permit tcp any object-group id17410X54624.dst.net.0 eq 3128 ! ! Rule 15 (global) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 dmz access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list dmz_acl_in permit icmp any host 192.168.2.1 3 ! ! Rule 16 (global) access-list outside_acl_in permit tcp any object-group id17435X54624.dst.net.0 object-group id17435X54624.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id17435X54624.dst.net.0 object-group id17435X54624.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id17435X54624.dst.net.0 object-group id17435X54624.srv.tcp.0 ! ! Rule 17 (global) access-list outside_acl_in permit tcp any object-group id17448X54624.dst.net.0 object-group id17435X54624.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id17448X54624.dst.net.0 object-group id17435X54624.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id17448X54624.dst.net.0 object-group id17435X54624.srv.tcp.0 ! ! Rule 18 (global) ! fwsm2:Policy:18: error: Rule '18 (global)' shadows rule '20 (global)' below it access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id17461X54624.srv.tcp.0 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id17461X54624.srv.tcp.0 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id17461X54624.srv.tcp.0 ! ! Rule 19 (global) ! objects hostA and hostB are ! redundant and should be removed by ! removeRedundantAddressesFromDst access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 ! ! Rule 20 (global) access-list outside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list inside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list dmz_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 ! ! Rule 23 (global) access-list outside_acl_in permit ip host 22.22.22.22 host 22.22.22.22 log 0 interval 300 access-list inside_acl_in permit ip host 192.168.1.1 host 192.168.1.1 log 0 interval 300 access-list dmz_acl_in permit ip host 192.168.2.1 host 192.168.2.1 log 0 interval 300 ! ! Rule 24 (global) access-list outside_acl_in permit ip host 22.22.22.22 any access-list inside_acl_in permit ip host 192.168.1.1 any access-list dmz_acl_in permit ip host 192.168.2.1 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 25 (global) access-list outside_acl_in deny ip any any log 0 interval 300 access-list inside_acl_in deny ip any any log 0 interval 300 access-list dmz_acl_in deny ip any any log 0 interval 300 access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 global (dmz) 1 interface ! ! ! Rule 1 (NAT) nat (dmz) 1 0.0.0.0 0.0.0.0 0 0 ! ! Rule 2 (NAT) nat (inside) 1 0.0.0.0 0.0.0.0 0 0 ! ! ! Rule 3 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 4 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! Rule 5 (NAT) static (inside,outside) tcp interface 25 192.168.1.10 25 0 0 ! ! Rule 6 (NAT) global (inside) 8 interface nat (dmz) 8 192.168.2.0 255.255.255.0 outside ! ! Rule 7 (NAT) clear config access-list nat0.inside access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 8 (NAT) access-list nat0.inside permit ip host 192.168.1.11 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.12 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.13 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.14 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.15 192.168.2.0 255.255.255.0 ! ! Rule 9 (NAT) nat (dmz) 0 0 0 ! ! Rule 10 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 11 (NAT) static (inside,dmz) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall6.fw.orig0000755000175000017500000000406411733011756021754 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:08 2011 PDT by vadim ! ! Compiled for pix 6.2 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall6.fw ! ! testing rule with firewall in dst and negation ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0 inside security100 nameif eth1 outside security0 nameif eth2 dmz security50 logging host outside 10.3.14.30 logging queue 512 logging facility 20 logging trap 4 logging buffered 5 logging console 0 logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout uauth 2:0:0 absolute clear ssh aaa authentication ssh console LOCAL clear snmp-server no snmp-server enable traps clear ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound no sysopt route dnat floodguard disable !################ clear xlate clear static clear global clear nat clear access-list clear icmp clear telnet ! ! Rule 0 (eth1) access-list outside_acl_in deny ip any host 22.22.22.22 ! ! Rule 1 (global) access-list inside_acl_in deny ip any host 192.168.1.1 access-list outside_acl_in deny ip any host 22.22.22.22 access-list dmz_acl_in deny ip any host 192.168.2.1 access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) static (inside,dmz) 192.168.10.0 192.168.10.0 netmask 255.255.255.0 static (inside,dmz) 192.168.20.0 192.168.20.0 netmask 255.255.255.0 ! ! Rule 1 (NAT) static (inside,outside) 192.168.1.1 192.168.1.1 netmask 255.255.255.255 ! ! Rule 2 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.10 255.255.255.255 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall14.fw.orig0000755000175000017500000000342611733011756022034 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:03 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall14.fw ! ! testing dual NAT per user's request ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard enable !################ ! ! Rule 0 (global) access-list inside_acl_in permit ip 10.1.2.0 255.255.255.0 any ! ! Rule 1 (global) access-list outside_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id3FA74FDE.0 permit ip host 10.1.2.27 any nat (inside) 1 access-list id3FA74FDE.0 0 0 ! ! Rule 1 (NAT) access-list id3FA74FCE.0 permit ip host 209.165.201.11 any static (outside,inside) interface access-list id3FA74FCE.0 0 0 ! ! Rule 2 (NAT) access-list id3FA7502F.0 permit ip host 10.1.2.27 any static (inside,outside) interface access-list id3FA7502F.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/run.all0000755000175000017500000000076511733011756020066 0ustar sylvestresylvestre#!/bin/sh XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_pix -v -f $XMLFILE -xt $fwobj" done XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_pix -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/pix/test_net_zone_2.fw.orig0000755000175000017500000000371311733011756023162 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:17 2011 PDT by vadim ! ! Compiled for pix 6.1 ! Outbound ACLs: not supported ! Emulate outbound ACLs: no ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * test_net_zone_2.fw ! ! testing security levels and labels ! N test_net_zone_2:NAT:0: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! N test_net_zone_2:NAT:0: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! ! Prolog script: ! ! ! End of prolog script: ! nameif ethernet0 outside security0 nameif ethernet1 inside security100 no logging buffered no logging console no logging timestamp no logging on telnet timeout -1 aaa authentication ssh console LOCAL ssh timeout -1 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound no sysopt route dnat floodguard disable !################ ! ! Rule 0 (global) access-list outside_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) ! test_net_zone_2:NAT:0: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. global (outside) 1 interface nat (outside) 1 192.168.1.0 255.255.255.0 0 0 nat (outside) 1 192.168.1.11 255.255.255.255 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/real.fw.orig0000755000175000017500000000547711733011756021015 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:17 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * real.fw ! ! ! Prolog script: ! ! ! End of prolog script: ! hostname real nameif ethernet0 outside security0 ip address outside dhcp setroute retry 10 nameif ethernet1 inside security100 ip address inside 10.3.14.204 255.255.255.0 logging host inside 10.3.14.10 format emblem logging queue 1000 logging facility 16 logging trap 0 no logging buffered no logging console no logging timestamp logging on logging device-id string real_firewall timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout rpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 absolute telnet timeout 5 clear ssh aaa authentication ssh console LOCAL ssh timeout 5 clear snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 10.3.14.40 poll clear ntp ntp server 10.3.14.30 source inside no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable fixup protocol dns maximum-length 65535 fixup protocol ftp 21 fixup protocol http 80 fixup protocol icmp error !################ clear xlate clear static clear global clear nat clear access-list clear icmp clear telnet ! ! Rule 0 (global) access-list inside_acl_in remark 0 (global) access-list inside_acl_in permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 1 (global) ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 2 (global) icmp permit any 0 outside access-list outside_acl_in remark 2 (global) access-list outside_acl_in permit icmp any interface outside 0 icmp permit any 0 inside access-list inside_acl_in remark 2 (global) access-list inside_acl_in permit icmp any host 10.3.14.204 0 ! ! Rule 3 (global) access-list outside_acl_in remark 3 (global) access-list outside_acl_in permit tcp any host 10.3.14.30 eq 80 access-list inside_acl_in remark 3 (global) access-list inside_acl_in permit tcp any host 10.3.14.30 eq 80 ! ! Rule 4 (global) access-list outside_acl_in remark 4 (global) access-list outside_acl_in deny ip any any log 5 interval 120 access-list inside_acl_in remark 4 (global) access-list inside_acl_in deny ip any any log 5 interval 120 access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id3D385E43.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id3D385E43.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall.fw.orig0000755000175000017500000007263311733011756021675 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:01 2011 PDT by vadim ! ! Compiled for pix 6.2 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall.fw ! ! this is simple firewall with two interfaces. Test regular policy rules, including IP_fragments rule ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '1 (ethernet1)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '2 (ethernet1)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '3 (ethernet1)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '3 (ethernet1)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '3 (ethernet1)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '3 (ethernet1)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '4 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '4 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '4 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '6 (ethernet0)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '8 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '8 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '8 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '10 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '10 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '10 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '12 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '12 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '12 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '12 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '13 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '14 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '20 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '24 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '24 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '24 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '24 (global)' below it ! C firewall:Policy:0: error: Rule '0 (global)' shadows rule '25 (global)' below it ! C firewall:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule ! N firewall:NAT:6: warning: Original destination is ignored in 'nat' NAT rules when compiling for PIX v6.2 and earlier. ! R firewall:Routing:3: error: Interface and gateway rule elements can not be empty in the PIX routing rule ! R firewall:Routing:4: error: Interface and gateway rule elements can not be empty in the PIX routing rule ! R firewall:Routing:5: error: Interface and gateway rule elements can not be empty in the PIX routing rule ! R firewall:Routing:7: error: MultiPath routing not supported by platform ! R firewall:Routing:8: warning: Two of the sub rules created from the gui routing rules 7 (main) and 8 (main) are identical, skipping the second. Revise them to avoid this warning ! ! Prolog script: ! ! ! End of prolog script: ! hostname firewall nameif ethernet1 outside security0 nameif ethernet0 inside security100 nameif ethernet2 dmz security50 logging host inside 192.168.1.30 logging queue 512 logging facility 16 logging trap 1 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear ssh aaa authentication ssh console LOCAL ssh timeout 5 clear snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 poll snmp-server host inside 192.168.1.22 trap clear ntp ntp server 192.168.1.20 source inside prefer no service resetinbound no service resetoutside sysopt connection tcpmss 1380 sysopt connection timewait sysopt security fragguard sysopt nodnsalias inbound sysopt nodnsalias outbound no sysopt route dnat floodguard disable fixup protocol ftp 21 fixup protocol http 80 fixup protocol h323 h225 1720 fixup protocol h323 ras 1718-1719 fixup protocol ils 389 fixup protocol rsh 514 fixup protocol rtsp 554 fixup protocol sip 5060 fixup protocol skinny 2000 fixup protocol smtp 25 fixup protocol sqlnet 1521 !################ clear access-list tmp_acl access-list tmp_acl permit ip 192.168.1.0 255.255.255.0 any access-list tmp_acl deny ip any any access-group tmp_acl in interface outside access-group tmp_acl in interface inside access-group tmp_acl in interface dmz clear xlate clear static clear global clear nat clear access-list dmz_acl_in clear access-list inside_acl_in clear access-list outside_acl_in clear icmp clear telnet clear object-group object-group network id3C4E4C38.dst.net.0 network-object host 211.11.11.11 network-object host 211.22.22.22 exit object-group service id3C4E4C38.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 22 port-object eq 540 exit object-group icmp-type id3D8FCE32.srv.icmp.0 icmp-object 3 icmp-object 0 icmp-object 11 exit object-group service pol-firewall2-2.srv.tcp.0 tcp port-object eq 70 port-object eq 6667 port-object eq 3128 port-object eq 23 exit object-group service pol-firewall2-2.srv.udp.0 udp port-object eq 53 port-object eq 161 exit object-group network pol-firewall2-3.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit object-group network id3E155E82.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id3D0F8031.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id3CD87B1E.dst.net.0 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 exit object-group service id3CD87B1E.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 3128 port-object eq 22 port-object eq 540 exit object-group network id3CD8770E.dst.net.0 network-object 192.168.1.11 255.255.255.255 network-object 192.168.1.12 255.255.255.252 exit object-group service pol-firewall2-4.srv.tcp.0 tcp port-object eq 113 port-object eq 13 port-object eq 53 port-object eq 2105 port-object eq 21 port-object eq 70 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 993 port-object eq 6667 port-object eq 6667 port-object eq 543 port-object eq 544 port-object eq 389 port-object eq 98 port-object eq 3306 port-object eq 2049 port-object eq 119 port-object eq 110 port-object eq 5432 port-object eq 515 port-object eq 26000 port-object eq 512 port-object eq 513 port-object eq 514 port-object eq 4321 port-object eq 25 port-object eq 465 port-object eq 1080 port-object eq 3128 port-object eq 22 port-object eq 111 port-object eq 23 port-object range 10000 11000 port-object eq 540 port-object eq 7100 exit ! ! Rule -1 backup ssh access rule (automatic) ssh 192.168.1.100 255.255.255.255 inside ! ! Rule 0 (global) ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '1 (ethernet1)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '10 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '12 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '13 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '14 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '15 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '16 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '17 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '18 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '19 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '2 (ethernet1)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '20 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '23 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '24 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '25 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '3 (ethernet1)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '4 (ethernet0)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '5 (ethernet0)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '6 (ethernet0)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '8 (global)' below it ! firewall:Policy:0: error: Rule '0 (global)' shadows rule '9 (global)' below it access-list outside_acl_in deny ip any any access-list inside_acl_in deny ip any any access-list dmz_acl_in deny ip any any ! ! Rule 2 (ethernet1) ! аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list outside_acl_in permit icmp any any 3 ! ! Rule 3 (ethernet1) ! anti-spoofing rule ! firewall:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 4 (ethernet0) ssh 192.168.1.0 255.255.255.0 inside ! ! Rule 5 (ethernet0) access-list inside_acl_in permit tcp any object-group id3C4E4C38.dst.net.0 object-group id3C4E4C38.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id3C4E4C38.dst.net.0 object-group id3C4E4C38.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id3C4E4C38.dst.net.0 object-group id3C4E4C38.srv.tcp.0 ! ! Rule 6 (ethernet0) access-list inside_acl_in deny ip any host 192.168.1.255 ! ! Rule 8 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id3D8FCE32.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id3D8FCE32.srv.icmp.0 access-list dmz_acl_in permit icmp any host 192.168.1.10 object-group id3D8FCE32.srv.icmp.0 ! ! Rule 9 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 access-list inside_acl_in permit icmp any host 192.168.1.10 access-list dmz_acl_in permit icmp any host 192.168.1.10 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group pol-firewall2-2.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group pol-firewall2-2.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group pol-firewall2-2.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group pol-firewall2-2.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group pol-firewall2-2.srv.udp.0 access-list dmz_acl_in permit udp any host 192.168.1.10 object-group pol-firewall2-2.srv.udp.0 access-list outside_acl_in permit 47 any host 192.168.1.10 access-list inside_acl_in permit 47 any host 192.168.1.10 access-list dmz_acl_in permit 47 any host 192.168.1.10 ! ! Rule 10 (global) access-list outside_acl_in permit icmp any host 22.22.22.22 3 icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 access-list outside_acl_in permit icmp any any 3 access-list inside_acl_in permit icmp any any 3 access-list dmz_acl_in permit icmp any any 3 access-list outside_acl_in permit 47 any any access-list inside_acl_in permit 47 any any access-list dmz_acl_in permit 47 any any access-list outside_acl_in permit 50 any any access-list inside_acl_in permit 50 any any access-list dmz_acl_in permit 50 any any ! ! Rule 12 (global) access-list outside_acl_in permit ip object-group id3C4E4C38.dst.net.0 object-group pol-firewall2-3.dst.net.0 ! ! Rule 13 (global) ! firewall:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule access-list inside_acl_in permit tcp host 192.168.1.10 object-group id3E155E82.dst.net.0 eq 3128 ! ! Rule 14 (global) access-list outside_acl_in permit tcp any object-group id3D0F8031.dst.net.0 eq 3128 access-list inside_acl_in permit tcp any object-group id3D0F8031.dst.net.0 eq 3128 access-list dmz_acl_in permit tcp any object-group id3D0F8031.dst.net.0 eq 3128 ! ! Rule 15 (global) http 192.168.1.0 255.255.255.0 inside icmp permit 192.168.1.0 255.255.255.0 3 inside access-list inside_acl_in permit icmp 192.168.1.0 255.255.255.0 host 192.168.1.1 3 ! ! Rule 16 (global) access-list outside_acl_in permit tcp any object-group id3CD87B1E.dst.net.0 object-group id3CD87B1E.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id3CD87B1E.dst.net.0 object-group id3CD87B1E.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id3CD87B1E.dst.net.0 object-group id3CD87B1E.srv.tcp.0 ! ! Rule 17 (global) access-list outside_acl_in permit tcp any object-group id3CD8770E.dst.net.0 object-group id3CD87B1E.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id3CD8770E.dst.net.0 object-group id3CD87B1E.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id3CD8770E.dst.net.0 object-group id3CD87B1E.srv.tcp.0 ! ! Rule 18 (global) access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group pol-firewall2-4.srv.tcp.0 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group pol-firewall2-4.srv.tcp.0 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group pol-firewall2-4.srv.tcp.0 ! ! Rule 19 (global) ! objects hostA and hostB are ! redundant and should be removed by ! removeRedundantAddressesFromDst access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list outside_acl_in permit udp any 192.168.1.0 255.255.255.0 eq 4000 access-list inside_acl_in permit udp any 192.168.1.0 255.255.255.0 eq 4000 access-list dmz_acl_in permit udp any 192.168.1.0 255.255.255.0 eq 4000 ! ! Rule 20 (global) access-list outside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list inside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list dmz_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 ! ! Rule 23 (global) access-list outside_acl_in permit ip host 22.22.22.22 host 22.22.22.22 access-list inside_acl_in permit ip host 192.168.1.1 host 192.168.1.1 access-list dmz_acl_in permit ip host 192.168.2.1 host 192.168.2.1 ! ! Rule 24 (global) access-list outside_acl_in permit ip host 22.22.22.22 any access-list inside_acl_in permit ip host 192.168.1.1 any access-list dmz_acl_in permit ip host 192.168.2.1 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 25 (global) access-list outside_acl_in deny ip any any access-list inside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 global (dmz) 1 interface ! ! ! Rule 1 (NAT) nat (dmz) 1 0.0.0.0 0.0.0.0 0 0 ! ! Rule 2 (NAT) nat (inside) 1 0.0.0.0 0.0.0.0 0 0 ! ! ! Rule 3 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 4 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! Rule 5 (NAT) static (inside,outside) tcp interface 25 192.168.1.10 25 0 0 ! ! Rule 6 (NAT) ! firewall:NAT:6: warning: Original destination is ignored in 'nat' NAT rules when compiling for PIX v6.2 and earlier. global (inside) 8 interface nat (dmz) 8 192.168.2.0 255.255.255.0 outside ! ! Rule 7 (NAT) clear access-list nat0.inside access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 8 (NAT) access-list nat0.inside permit ip host 192.168.1.11 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.12 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.13 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.14 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.15 192.168.2.0 255.255.255.0 ! ! Rule 9 (NAT) nat (dmz) 0 0 0 ! ! Rule 10 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 11 (NAT) static (inside,dmz) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Rule 0 (main) ! ! "Routing rule 0 (main)" ! ! ! route outside 0.0.0.0 0.0.0.0 22.22.22.254 1 ! ! Rule 1 (main) ! ! "Routing rule 1 (main)" ! ! ! route inside 10.3.14.0 255.255.255.0 192.168.1.254 1 ! ! Rule 2 (main) ! ! "Routing rule 2 (main)" ! ! ! route inside 10.1.2.0 255.255.255.0 192.168.1.254 1 ! ! Rule 3 (main) ! ! "Routing rule 3 (main)" ! ! ! ! firewall:Routing:3: error: Interface and gateway rule elements can not be empty in the PIX routing rule route 10.1.3.0 255.255.255.0 192.168.1.254 1 ! ! Rule 4 (main) ! ! "Routing rule 4 (main)" ! ! ! ! firewall:Routing:4: error: Interface and gateway rule elements can not be empty in the PIX routing rule route inside 10.1.4.0 255.255.255.0 1 ! ! Rule 5 (main) ! ! "Routing rule 5 (main)" ! ! ! ! firewall:Routing:5: error: Interface and gateway rule elements can not be empty in the PIX routing rule route 10.1.5.0 255.255.255.0 1 ! ! Rule 6 (main) ! ! "Routing rule 6 (main)" ! ! ! route outside 33.33.33.0 255.255.255.0 22.22.22.100 1 ! ! Rule 7 (main) ! ! "Routing rule 7 (main)" ! ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/do-diff0000755000175000017500000000031311733011756020010 0ustar sylvestresylvestre#!/bin/sh N=$1 if which opendiff > /dev/null; then TOOL="opendiff" elif which tkdiff > /dev/null; then TOOL="tkdiff " else TOOL="diff -u -b -B" fi $TOOL firewall${N}.fw.orig firewall${N}.fw fwbuilder-5.1.0.3599/test/pix/firewall82.fw.orig0000755000175000017500000001051211733011756022033 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:11 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall82.fw ! ! test for the warning issued when translated address is used in ! policy rule. HEre we have slightly different NAT than in firewall81 ! C firewall82:Policy:1: warning: Object firewall82:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. ! C firewall82:Policy:2: warning: Object firewall82:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. ! C firewall82:Policy:3: warning: Object firewall82:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif inside security-level 100 exit interface FastEthernet1 nameif outside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object object service http.0 service tcp destination eq 80 exit object network hostA:eth0.0 host 192.168.1.10 exit ! ! Rule 0 (global) ! matching "any" icmp and "all" tcp ! in one service-group ! access-list inside_acl_in deny icmp any object hostA:eth0.0 access-list outside_acl_in deny icmp any object hostA:eth0.0 access-list inside_acl_in deny tcp any object hostA:eth0.0 access-list outside_acl_in deny tcp any object hostA:eth0.0 ! ! Rule 1 (FastEthernet1) ! test rule using translated address in dst ! firewall82:Policy:1: warning: Object firewall82:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 ! ! Rule 2 (global) ! test rule using translated address in dst ! firewall82:Policy:2: warning: Object firewall82:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 ! ! Rule 3 (global) ! test rule using translated address in dst ! firewall82:Policy:3: warning: Object firewall82:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. http 0.0.0.0 0.0.0.0 inside http 0.0.0.0 0.0.0.0 outside ! ! Rule 4 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 http.0 description "0 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/addr-table-1.tbl0000644000175000017500000000030411733011756021412 0ustar sylvestresylvestre# this is a comment # ; this should be a comment too ; 192.168.1.1 192.168.1.2/32 192.168.1.3/30 192.168.2.128/25 192.168.1.200/32 # comment again 192.168.1.201/32 # this should work, too fwbuilder-5.1.0.3599/test/pix/quick-cmp.sh0000755000175000017500000000076611733011756021016 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -B -w -I \"! Generated\" -I 'Activating ' -I '! Firewall Builder fwb_pix v' -I 'Can not find file' -I '===='" SDIFFCMD="sdiff -b -B -W -I \"! Generated\" -I 'Activating ' -I '! Firewall Builder fwb_pix v' -I 'Can not find file' -I '===='" for f in $(ls *.fw.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done fwbuilder-5.1.0.3599/test/pix/firewall101.fw.orig0000755000175000017500000000253611733011756022112 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:01 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall101.fw ! ! this firewall generates "short" config (only acls and nat rules, no interface configuration, timeouts and inspectors) ! ! Prolog script: ! ! ! End of prolog script: ! ! This script was generated with option "Generate only access-list, access-group, ! nat, static, global" commands turned on in the "Script" tab of the firewall ! object advanced settings dialog. Skipping system configuration commands. !################ object-group network id63559X5474.src.net.0 network-object 192.168.10.0 255.255.255.0 network-object 192.168.20.0 255.255.255.0 exit ! ! Rule 0 (global) access-list inside_acl_in permit ip object-group id63559X5474.src.net.0 host 192.168.1.20 ! ! Rule 1 (global) access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/fwsm3.fw.orig0000755000175000017500000003157411733011756021126 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:15 2011 PDT by vadim ! ! Compiled for fwsm 3.2 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * fwsm3.fw ! ! C fwsm3:Policy:18: error: Rule '18 (global)' shadows rule '20 (global)' below it ! C fwsm3:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C fwsm3:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule ! ! Prolog script: ! ! ! End of prolog script: ! hostname fwsm3 interface ethernet1 nameif outside security-level 0 exit interface ethernet0 nameif inside security-level 100 exit interface ethernet2 nameif dmz security-level 50 exit logging host inside 192.168.1.30 logging queue 512 logging facility 16 logging trap 0 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear config ssh aaa authentication ssh console LOCAL ssh timeout 5 clear config snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 poll snmp-server host inside 192.168.1.22 trap no service resetinbound sysopt connection tcpmss 1380 sysopt nodnsalias inbound sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect ils inspect rsh inspect rtsp inspect sip inspect skinny inspect esmtp inspect sqlnet service-policy global_policy global !################ access-list mode auto clear config access-list tmp_acl access-list tmp_acl permit ip 192.168.1.0 255.255.255.0 any access-list tmp_acl deny ip any any access-group tmp_acl in interface outside access-group tmp_acl in interface inside access-group tmp_acl in interface dmz clear xlate clear config static clear config global clear config nat clear config access-list dmz_acl_in clear config access-list inside_acl_in clear config access-list outside_acl_in clear config icmp clear config telnet clear config object-group object-group network id37010X447.dst.net.0 network-object host 211.11.11.11 network-object host 211.22.22.22 exit object-group service id37010X447.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 22 port-object eq 540 exit object-group icmp-type id37094X447.srv.icmp.0 icmp-object 3 icmp-object 0 icmp-object 11 exit object-group service id37122X447.srv.tcp.0 tcp port-object eq 70 port-object eq 6667 port-object eq 3128 port-object eq 23 exit object-group service id37122X447.srv.udp.0 udp port-object eq 53 port-object eq 161 exit object-group network id37207X447.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit object-group network id37237X447.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id37265X447.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id37322X447.dst.net.0 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 exit object-group service id37322X447.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 3128 port-object eq 22 port-object eq 540 exit object-group network id37351X447.dst.net.0 network-object 192.168.1.11 255.255.255.255 network-object 192.168.1.12 255.255.255.252 exit object-group service id37380X447.srv.tcp.0 tcp port-object eq 113 port-object eq 13 port-object eq 53 port-object eq 2105 port-object eq 21 port-object eq 70 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 993 port-object eq 6667 port-object eq 6667 port-object eq 543 port-object eq 544 port-object eq 389 port-object eq 98 port-object eq 3306 port-object eq 2049 port-object eq 119 port-object eq 110 port-object eq 5432 port-object eq 515 port-object eq 26000 port-object eq 512 port-object eq 513 port-object eq 514 port-object eq 4321 port-object eq 25 port-object eq 465 port-object eq 1080 port-object eq 3128 port-object eq 22 port-object eq 111 port-object eq 23 port-object range 10000 11000 port-object eq 540 port-object eq 7100 exit ! ! Rule 2 (ethernet1) icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list outside_acl_in permit icmp any any 3 ! ! Rule 3 (ethernet1) ! anti-spoofing rule ! fwsm3:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 4 (ethernet0) ssh 192.168.1.0 255.255.255.0 inside ! ! Rule 5 (ethernet0) access-list inside_acl_in permit tcp any object-group id37010X447.dst.net.0 object-group id37010X447.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id37010X447.dst.net.0 object-group id37010X447.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id37010X447.dst.net.0 object-group id37010X447.srv.tcp.0 ! ! Rule 6 (ethernet0) access-list inside_acl_in deny ip any host 192.168.1.255 ! ! Rule 8 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id37094X447.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id37094X447.srv.icmp.0 access-list dmz_acl_in permit icmp any host 192.168.1.10 object-group id37094X447.srv.icmp.0 ! ! Rule 9 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 access-list inside_acl_in permit icmp any host 192.168.1.10 access-list dmz_acl_in permit icmp any host 192.168.1.10 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id37122X447.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id37122X447.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group id37122X447.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group id37122X447.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group id37122X447.srv.udp.0 access-list dmz_acl_in permit udp any host 192.168.1.10 object-group id37122X447.srv.udp.0 access-list outside_acl_in permit 47 any host 192.168.1.10 access-list inside_acl_in permit 47 any host 192.168.1.10 access-list dmz_acl_in permit 47 any host 192.168.1.10 ! ! Rule 10 (global) access-list outside_acl_in permit icmp any host 22.22.22.22 3 log 0 interval 300 icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 log 0 interval 300 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 log 0 interval 300 access-list outside_acl_in permit icmp any any 3 log 0 interval 300 access-list inside_acl_in permit icmp any any 3 log 0 interval 300 access-list dmz_acl_in permit icmp any any 3 log 0 interval 300 access-list outside_acl_in permit 47 any any log 0 interval 300 access-list inside_acl_in permit 47 any any log 0 interval 300 access-list dmz_acl_in permit 47 any any log 0 interval 300 access-list outside_acl_in permit 50 any any log 0 interval 300 access-list inside_acl_in permit 50 any any log 0 interval 300 access-list dmz_acl_in permit 50 any any log 0 interval 300 ! ! Rule 12 (global) access-list outside_acl_in permit ip object-group id37010X447.dst.net.0 object-group id37207X447.dst.net.0 ! ! Rule 13 (global) ! fwsm3:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule access-list inside_acl_in permit tcp host 192.168.1.10 object-group id37237X447.dst.net.0 eq 3128 ! ! Rule 14 (global) access-list outside_acl_in permit tcp any object-group id37265X447.dst.net.0 eq 3128 access-list inside_acl_in permit tcp any object-group id37265X447.dst.net.0 eq 3128 access-list dmz_acl_in permit tcp any object-group id37265X447.dst.net.0 eq 3128 ! ! Rule 15 (global) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 dmz access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list dmz_acl_in permit icmp any host 192.168.2.1 3 ! ! Rule 16 (global) access-list outside_acl_in permit tcp any object-group id37322X447.dst.net.0 object-group id37322X447.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id37322X447.dst.net.0 object-group id37322X447.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id37322X447.dst.net.0 object-group id37322X447.srv.tcp.0 ! ! Rule 17 (global) access-list outside_acl_in permit tcp any object-group id37351X447.dst.net.0 object-group id37322X447.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id37351X447.dst.net.0 object-group id37322X447.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id37351X447.dst.net.0 object-group id37322X447.srv.tcp.0 ! ! Rule 18 (global) ! fwsm3:Policy:18: error: Rule '18 (global)' shadows rule '20 (global)' below it access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id37380X447.srv.tcp.0 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id37380X447.srv.tcp.0 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id37380X447.srv.tcp.0 ! ! Rule 19 (global) ! objects hostA and hostB are ! redundant and should be removed by ! removeRedundantAddressesFromDst access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 ! ! Rule 20 (global) access-list outside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list inside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list dmz_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 ! ! Rule 23 (global) access-list outside_acl_in permit ip host 22.22.22.22 host 22.22.22.22 log 0 interval 300 access-list inside_acl_in permit ip host 192.168.1.1 host 192.168.1.1 log 0 interval 300 access-list dmz_acl_in permit ip host 192.168.2.1 host 192.168.2.1 log 0 interval 300 ! ! Rule 24 (global) access-list outside_acl_in permit ip host 22.22.22.22 any access-list inside_acl_in permit ip host 192.168.1.1 any access-list dmz_acl_in permit ip host 192.168.2.1 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 25 (global) access-list outside_acl_in deny ip any any log 0 interval 300 access-list inside_acl_in deny ip any any log 0 interval 300 access-list dmz_acl_in deny ip any any log 0 interval 300 access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 global (dmz) 1 interface ! ! ! Rule 1 (NAT) nat (dmz) 1 0.0.0.0 0.0.0.0 0 0 ! ! Rule 2 (NAT) nat (inside) 1 0.0.0.0 0.0.0.0 0 0 ! ! ! Rule 3 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 4 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! Rule 5 (NAT) static (inside,outside) tcp interface 25 192.168.1.10 25 0 0 ! ! Rule 6 (NAT) global (inside) 8 interface nat (dmz) 8 192.168.2.0 255.255.255.0 outside ! ! Rule 7 (NAT) clear config access-list nat0.inside access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 8 (NAT) access-list nat0.inside permit ip host 192.168.1.11 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.12 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.13 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.14 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.15 192.168.2.0 255.255.255.0 ! ! Rule 9 (NAT) nat (dmz) 0 0 0 ! ! Rule 10 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 11 (NAT) static (inside,dmz) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall34.fw.orig0000755000175000017500000001413111733011756022031 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:08 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: no ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall34.fw ! ! testing AddressTable object ! C firewall34:Policy:1: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode ! C firewall34:Policy:1: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0.100 outside security0 nameif eth1 inside security100 no logging buffered no logging console no logging timestamp no logging on telnet timeout -1 aaa authentication ssh console LOCAL ssh timeout -1 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable !################ object-group network id16988X10208.dst.net.0 network-object 192.168.1.1 255.255.255.255 network-object 192.168.1.2 255.255.255.255 network-object 192.168.1.3 255.255.255.252 network-object 192.168.1.200 255.255.255.255 network-object 192.168.1.201 255.255.255.255 exit object-group network id4390C25825682.dst.net.0 network-object 58.33.181.83 255.255.255.255 network-object 58.53.82.190 255.255.255.255 network-object 58.231.13.78 255.255.255.255 network-object 61.150.47.112 255.255.255.255 network-object 61.184.14.102 255.255.255.255 network-object 64.106.85.186 255.255.255.255 network-object 70.228.60.100 255.255.255.255 network-object 80.51.236.6 255.255.255.255 network-object 80.243.72.149 255.255.255.255 network-object 80.249.77.34 255.255.255.255 network-object 81.2.36.254 255.255.255.255 network-object 81.196.74.125 255.255.255.255 network-object 82.77.37.174 255.255.255.255 network-object 82.117.221.205 255.255.255.255 network-object 82.143.196.17 255.255.255.255 network-object 84.90.8.198 255.255.255.255 network-object 151.8.224.178 255.255.255.255 network-object 168.156.76.20 255.255.255.255 network-object 193.207.126.36 255.255.255.255 network-object 195.136.186.35 255.255.255.255 network-object 196.15.136.15 255.255.255.255 network-object 201.10.180.138 255.255.255.255 network-object 201.17.93.16 255.255.255.255 network-object 201.36.156.121 255.255.255.255 network-object 202.96.112.93 255.255.255.255 network-object 202.103.25.253 255.255.255.255 network-object 203.162.3.209 255.255.255.255 network-object 203.209.124.144 255.255.255.255 network-object 210.106.193.237 255.255.255.255 network-object 210.222.114.102 255.255.255.255 network-object 211.144.143.143 255.255.255.255 network-object 211.172.218.237 255.255.255.255 network-object 211.250.16.132 255.255.255.255 network-object 212.21.241.31 255.255.255.255 network-object 212.100.212.100 255.255.255.255 network-object 218.18.72.252 255.255.255.255 network-object 218.39.114.122 255.255.255.255 network-object 218.55.115.43 255.255.255.255 network-object 218.104.138.146 255.255.255.255 network-object 219.132.104.160 255.255.255.255 network-object 220.71.17.86 255.255.255.255 network-object 220.81.50.105 255.255.255.255 network-object 220.91.99.46 255.255.255.255 network-object 221.14.249.242 255.255.255.255 network-object 221.166.177.135 255.255.255.255 network-object 221.198.33.38 255.255.255.255 network-object 221.202.160.233 255.255.255.255 network-object 221.205.54.125 255.255.255.255 network-object 221.217.44.248 255.255.255.255 network-object 222.100.212.223 255.255.255.255 network-object 222.121.118.144 255.255.255.255 network-object 222.174.113.2 255.255.255.255 exit object-group network id21263X16880.src.net.0 network-object 10.1.0.0 255.255.255.0 network-object 10.1.2.0 255.255.255.0 network-object 10.1.3.0 255.255.255.0 network-object 10.1.4.0 255.255.255.0 exit ! ! Rule 0 (global) access-list outside_acl_in permit ip any 192.168.2.128 255.255.255.128 access-list inside_acl_in permit ip any 192.168.2.128 255.255.255.128 access-list outside_acl_in permit ip any object-group id16988X10208.dst.net.0 access-list inside_acl_in permit ip any object-group id16988X10208.dst.net.0 ! ! Rule 1 (global) ! firewall34:Policy:1: error: File not found for Address Table: missing table (file_does_not_exist.tbl) Using dummy address in test mode access-list outside_acl_in permit ip any 192.0.2.0 255.255.255.0 access-list inside_acl_in permit ip any 192.0.2.0 255.255.255.0 ! ! Rule 2 (global) access-list outside_acl_in deny ip any object-group id4390C25825682.dst.net.0 log 6 interval 300 access-list inside_acl_in deny ip any object-group id4390C25825682.dst.net.0 log 6 interval 300 ! ! Rule 3 (global) access-list outside_acl_in deny tcp any object-group id4390C25825682.dst.net.0 eq 25 access-list inside_acl_in deny tcp any object-group id4390C25825682.dst.net.0 eq 25 ! ! Rule 5 (global) access-list outside_acl_in deny ip object-group id4390C25825682.dst.net.0 any log 6 interval 300 ! ! Rule 6 (global) access-list outside_acl_in deny ip object-group id4390C25825682.dst.net.0 any log 6 interval 300 ! ! Rule 7 (global) access-list outside_acl_in permit ip object-group id4390C25825682.dst.net.0 any ! ! Rule 8 (global) ! for #1917 access-list outside_acl_in deny ip object-group id21263X16880.src.net.0 any ! ! Rule 10 (global) access-list outside_acl_in permit tcp any host 192.168.1.10 eq 25 access-list inside_acl_in permit tcp any host 192.168.1.10 eq 25 ! ! Rule 11 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 12 (global) access-list outside_acl_in deny ip any any log 6 interval 300 access-list inside_acl_in deny ip any any log 6 interval 300 access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/fwsm1.fw.orig0000755000175000017500000003150411733011756021115 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:14 2011 PDT by vadim ! ! Compiled for fwsm 2.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * fwsm1.fw ! ! C fwsm1:Policy:18: error: Rule '18 (global)' shadows rule '20 (global)' below it ! C fwsm1:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C fwsm1:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule ! ! Prolog script: ! ! ! End of prolog script: ! hostname fwsm1 nameif ethernet1 outside security0 nameif ethernet0 inside security100 nameif ethernet2 dmz security50 logging host inside 192.168.1.30 logging queue 512 logging facility 16 logging trap 0 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear ssh aaa authentication ssh console LOCAL ssh timeout 5 clear snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 poll snmp-server host inside 192.168.1.22 trap no service resetinbound no service resetoutside sysopt connection tcpmss 1380 sysopt nodnsalias inbound sysopt nodnsalias outbound floodguard disable fixup protocol ftp 21 fixup protocol h323 h225 1720 fixup protocol h323 ras 1718-1719 fixup protocol http 80 fixup protocol ils 389 fixup protocol rsh 514 fixup protocol rtsp 554 fixup protocol sip 5060 fixup protocol skinny 2000 fixup protocol smtp 25 fixup protocol sqlnet 1521 !################ access-list mode auto clear access-list tmp_acl access-list tmp_acl permit ip 192.168.1.0 255.255.255.0 any access-list tmp_acl deny ip any any access-group tmp_acl in interface outside access-group tmp_acl in interface inside access-group tmp_acl in interface dmz clear xlate clear static clear global clear nat clear access-list dmz_acl_in clear access-list inside_acl_in clear access-list outside_acl_in clear icmp clear telnet clear object-group object-group network id444A03DE9567.dst.net.0 network-object host 211.11.11.11 network-object host 211.22.22.22 exit object-group service id444A03DE9567.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 22 port-object eq 540 exit object-group icmp-type id444A04039567.srv.icmp.0 icmp-object 3 icmp-object 0 icmp-object 11 exit object-group service id444A040F9567.srv.tcp.0 tcp port-object eq 70 port-object eq 6667 port-object eq 3128 port-object eq 23 exit object-group service id444A040F9567.srv.udp.0 udp port-object eq 53 port-object eq 161 exit object-group network id444A04349567.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit object-group network id444A04429567.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id444A044E9567.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id444A04679567.dst.net.0 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 exit object-group service id444A04679567.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 3128 port-object eq 22 port-object eq 540 exit object-group network id444A04749567.dst.net.0 network-object 192.168.1.11 255.255.255.255 network-object 192.168.1.12 255.255.255.252 exit object-group service id444A04819567.srv.tcp.0 tcp port-object eq 113 port-object eq 13 port-object eq 53 port-object eq 2105 port-object eq 21 port-object eq 70 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 993 port-object eq 6667 port-object eq 6667 port-object eq 543 port-object eq 544 port-object eq 389 port-object eq 98 port-object eq 3306 port-object eq 2049 port-object eq 119 port-object eq 110 port-object eq 5432 port-object eq 515 port-object eq 26000 port-object eq 512 port-object eq 513 port-object eq 514 port-object eq 4321 port-object eq 25 port-object eq 465 port-object eq 1080 port-object eq 3128 port-object eq 22 port-object eq 111 port-object eq 23 port-object range 10000 11000 port-object eq 540 port-object eq 7100 exit ! ! Rule 2 (ethernet1) icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list outside_acl_in permit icmp any any 3 ! ! Rule 3 (ethernet1) ! anti-spoofing rule ! fwsm1:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 4 (ethernet0) ssh 192.168.1.0 255.255.255.0 inside ! ! Rule 5 (ethernet0) access-list inside_acl_in permit tcp any object-group id444A03DE9567.dst.net.0 object-group id444A03DE9567.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id444A03DE9567.dst.net.0 object-group id444A03DE9567.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id444A03DE9567.dst.net.0 object-group id444A03DE9567.srv.tcp.0 ! ! Rule 6 (ethernet0) access-list inside_acl_in deny ip any host 192.168.1.255 ! ! Rule 8 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id444A04039567.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id444A04039567.srv.icmp.0 access-list dmz_acl_in permit icmp any host 192.168.1.10 object-group id444A04039567.srv.icmp.0 ! ! Rule 9 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 access-list inside_acl_in permit icmp any host 192.168.1.10 access-list dmz_acl_in permit icmp any host 192.168.1.10 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id444A040F9567.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id444A040F9567.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group id444A040F9567.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group id444A040F9567.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group id444A040F9567.srv.udp.0 access-list dmz_acl_in permit udp any host 192.168.1.10 object-group id444A040F9567.srv.udp.0 access-list outside_acl_in permit 47 any host 192.168.1.10 access-list inside_acl_in permit 47 any host 192.168.1.10 access-list dmz_acl_in permit 47 any host 192.168.1.10 ! ! Rule 10 (global) access-list outside_acl_in permit icmp any host 22.22.22.22 3 log 0 interval 300 icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 log 0 interval 300 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 log 0 interval 300 access-list outside_acl_in permit icmp any any 3 log 0 interval 300 access-list inside_acl_in permit icmp any any 3 log 0 interval 300 access-list dmz_acl_in permit icmp any any 3 log 0 interval 300 access-list outside_acl_in permit 47 any any log 0 interval 300 access-list inside_acl_in permit 47 any any log 0 interval 300 access-list dmz_acl_in permit 47 any any log 0 interval 300 access-list outside_acl_in permit 50 any any log 0 interval 300 access-list inside_acl_in permit 50 any any log 0 interval 300 access-list dmz_acl_in permit 50 any any log 0 interval 300 ! ! Rule 12 (global) access-list outside_acl_in permit ip object-group id444A03DE9567.dst.net.0 object-group id444A04349567.dst.net.0 ! ! Rule 13 (global) ! fwsm1:Policy:13: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule access-list inside_acl_in permit tcp host 192.168.1.10 object-group id444A04429567.dst.net.0 eq 3128 ! ! Rule 14 (global) access-list outside_acl_in permit tcp any object-group id444A044E9567.dst.net.0 eq 3128 access-list inside_acl_in permit tcp any object-group id444A044E9567.dst.net.0 eq 3128 access-list dmz_acl_in permit tcp any object-group id444A044E9567.dst.net.0 eq 3128 ! ! Rule 15 (global) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 dmz access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list dmz_acl_in permit icmp any host 192.168.2.1 3 ! ! Rule 16 (global) access-list outside_acl_in permit tcp any object-group id444A04679567.dst.net.0 object-group id444A04679567.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id444A04679567.dst.net.0 object-group id444A04679567.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id444A04679567.dst.net.0 object-group id444A04679567.srv.tcp.0 ! ! Rule 17 (global) access-list outside_acl_in permit tcp any object-group id444A04749567.dst.net.0 object-group id444A04679567.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id444A04749567.dst.net.0 object-group id444A04679567.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id444A04749567.dst.net.0 object-group id444A04679567.srv.tcp.0 ! ! Rule 18 (global) ! fwsm1:Policy:18: error: Rule '18 (global)' shadows rule '20 (global)' below it access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id444A04819567.srv.tcp.0 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id444A04819567.srv.tcp.0 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id444A04819567.srv.tcp.0 ! ! Rule 19 (global) ! objects hostA and hostB are ! redundant and should be removed by ! removeRedundantAddressesFromDst access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 ! ! Rule 20 (global) access-list outside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list inside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list dmz_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 ! ! Rule 23 (global) access-list outside_acl_in permit ip host 22.22.22.22 host 22.22.22.22 log 0 interval 300 access-list inside_acl_in permit ip host 192.168.1.1 host 192.168.1.1 log 0 interval 300 access-list dmz_acl_in permit ip host 192.168.2.1 host 192.168.2.1 log 0 interval 300 ! ! Rule 24 (global) access-list outside_acl_in permit ip host 22.22.22.22 any access-list inside_acl_in permit ip host 192.168.1.1 any access-list dmz_acl_in permit ip host 192.168.2.1 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 25 (global) access-list outside_acl_in deny ip any any log 0 interval 300 access-list inside_acl_in deny ip any any log 0 interval 300 access-list dmz_acl_in deny ip any any log 0 interval 300 access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 global (dmz) 1 interface ! ! ! Rule 1 (NAT) nat (dmz) 1 0.0.0.0 0.0.0.0 0 0 ! ! Rule 2 (NAT) nat (inside) 1 0.0.0.0 0.0.0.0 0 0 ! ! ! Rule 3 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 4 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! Rule 5 (NAT) static (inside,outside) tcp interface 25 192.168.1.10 25 0 0 ! ! Rule 6 (NAT) global (inside) 8 interface nat (dmz) 8 192.168.2.0 255.255.255.0 outside ! ! Rule 7 (NAT) clear access-list nat0.inside access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 8 (NAT) access-list nat0.inside permit ip host 192.168.1.11 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.12 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.13 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.14 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.15 192.168.2.0 255.255.255.0 ! ! Rule 9 (NAT) nat (dmz) 0 0 0 ! ! Rule 10 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 11 (NAT) static (inside,dmz) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall9.fw.orig0000755000175000017500000000330511733011756021754 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:11 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall9.fw ! ! this firewall has no rules at all. ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth1 dmz security50 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout rpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable fixup protocol ctiqbe 2748 fixup protocol dns maximum-length 65535 fixup protocol ftp 21 fixup protocol h323 h225 1720 fixup protocol h323 ras 1718-1719 fixup protocol http 80 fixup protocol icmp error fixup protocol ils 389 fixup protocol mgcp 2427 fixup protocol mgcp 2727 fixup protocol pptp 1723 fixup protocol rsh fixup protocol rtsp 554 fixup protocol sip 5060 fixup protocol sip udp fixup protocol skinny 2000 fixup protocol smtp 25 fixup protocol sqlnet 1521 fixup protocol tftp 69 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall8.fw.orig0000755000175000017500000000547411733011756021764 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:09 2011 PDT by vadim ! ! Compiled for pix 6.2 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall8.fw ! ! N firewall8:NAT:5: warning: Original destination is ignored in 'nat' NAT rules when compiling for PIX v6.2 and earlier. ! N firewall8:NAT:6: warning: Original destination is ignored in 'nat' NAT rules when compiling for PIX v6.2 and earlier. ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth1 dmz security50 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound sysopt route dnat floodguard enable fixup protocol ftp 21 !################ ! ! Rule 0 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 1 (global) access-list outside_acl_in permit ip any 192.168.1.0 255.255.255.0 access-list dmz_acl_in permit ip any 192.168.1.0 255.255.255.0 access-list inside_acl_in permit ip any 192.168.1.0 255.255.255.0 ! ! Rule 2 (global) access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 global (outside) 1 interface ! ! ! Rule 1 (NAT) ! ! ! Rule 2 (NAT) ! ! ! Rule 3 (NAT) nat (dmz) 1 192.168.2.0 255.255.255.0 0 0 ! ! Rule 4 (NAT) static (dmz,outside) interface 192.168.2.100 0 0 ! ! Rule 5 (NAT) ! firewall8:NAT:5: warning: Original destination is ignored in 'nat' NAT rules when compiling for PIX v6.2 and earlier. global (inside) 1 interface ! ! ! Rule 6 (NAT) ! firewall8:NAT:6: warning: Original destination is ignored in 'nat' NAT rules when compiling for PIX v6.2 and earlier. global (dmz) 1 interface ! ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall10.fw.orig0000755000175000017500000003067311733011756022034 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:01 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall10.fw ! ! big policy. Testing compiler performance ! C firewall10:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! ! Prolog script: ! ! ! End of prolog script: ! hostname firewall10 nameif ethernet1 outside security0 nameif ethernet0 inside security100 nameif ethernet2 dmz security50 logging host inside 192.168.1.30 logging queue 512 logging facility 16 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 trap snmp-server host inside 192.168.1.22 poll ntp server 192.168.1.20 source inside no service resetinbound no service resetoutside sysopt connection tcpmss 1380 sysopt connection timewait sysopt nodnsalias inbound sysopt nodnsalias outbound floodguard disable fixup protocol ftp 21 fixup protocol h323 h225 1720 fixup protocol h323 ras 1718-1719 fixup protocol http 80 fixup protocol ils 389 fixup protocol rsh 514 fixup protocol rtsp 554 fixup protocol sip 5060 fixup protocol skinny 2000 fixup protocol smtp 25 fixup protocol sqlnet 1521 !################ object-group network id3DB0FA90.dst.net.0 network-object host 211.11.11.11 network-object host 211.22.22.22 exit object-group service id3DB0FA90.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 22 port-object eq 540 exit object-group icmp-type id3DB0F9C7.srv.icmp.0 icmp-object 3 icmp-object 0 icmp-object 11 exit object-group service id3DB0F9BD.srv.tcp.0 tcp port-object eq 70 port-object eq 6667 port-object eq 3128 port-object eq 23 exit object-group service id3DB0F9BD.srv.udp.0 udp port-object eq 53 port-object eq 161 exit object-group network id3DB0F9E6.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit object-group network id3DB10695.src.net.0 network-object 192.168.1.0 255.255.255.0 network-object 192.168.10.0 255.255.255.0 network-object 192.168.20.0 255.255.255.0 exit object-group network id3DB10695.src.net.1 network-object 192.168.2.0 255.255.255.0 network-object 192.168.3.0 255.255.255.0 exit object-group network id3DB10695.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 network-object host 192.168.1.20 exit object-group network id3DB0F9F2.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id3DB0F9FC.dst.net.0 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 exit object-group service id3DB0F9FC.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 3128 port-object eq 22 port-object eq 540 exit object-group network id3DB0FA07.dst.net.0 network-object 192.168.1.11 255.255.255.255 network-object 192.168.1.12 255.255.255.252 exit object-group service id3DB0FA12.srv.tcp.0 tcp port-object eq 113 port-object eq 13 port-object eq 53 port-object eq 2105 port-object eq 21 port-object eq 70 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 993 port-object eq 6667 port-object eq 6667 port-object eq 543 port-object eq 544 port-object eq 389 port-object eq 98 port-object eq 3306 port-object eq 2049 port-object eq 119 port-object eq 110 port-object eq 5432 port-object eq 515 port-object eq 26000 port-object eq 512 port-object eq 513 port-object eq 514 port-object eq 4321 port-object eq 25 port-object eq 465 port-object eq 1080 port-object eq 3128 port-object eq 22 port-object eq 111 port-object eq 23 port-object range 10000 11000 port-object eq 540 port-object eq 7100 exit ! ! Rule 3 (ethernet1) ! anti-spoofing rule ! firewall10:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any log 6 interval 300 ! ! Rule 5 (ethernet0) access-list inside_acl_in permit tcp any object-group id3DB0FA90.dst.net.0 object-group id3DB0FA90.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id3DB0FA90.dst.net.0 object-group id3DB0FA90.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id3DB0FA90.dst.net.0 object-group id3DB0FA90.srv.tcp.0 ! ! Rule 7 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id3DB0F9C7.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id3DB0F9C7.srv.icmp.0 access-list dmz_acl_in permit icmp any host 192.168.1.10 object-group id3DB0F9C7.srv.icmp.0 ! ! Rule 8 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 access-list inside_acl_in permit icmp any host 192.168.1.10 access-list dmz_acl_in permit icmp any host 192.168.1.10 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id3DB0F9BD.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id3DB0F9BD.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group id3DB0F9BD.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group id3DB0F9BD.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group id3DB0F9BD.srv.udp.0 access-list dmz_acl_in permit udp any host 192.168.1.10 object-group id3DB0F9BD.srv.udp.0 access-list outside_acl_in permit 47 any host 192.168.1.10 access-list inside_acl_in permit 47 any host 192.168.1.10 access-list dmz_acl_in permit 47 any host 192.168.1.10 ! ! Rule 9 (global) icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 log 6 interval 300 icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 log 6 interval 300 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 log 6 interval 300 access-list outside_acl_in permit icmp any any 3 log 6 interval 300 access-list inside_acl_in permit icmp any any 3 log 6 interval 300 access-list dmz_acl_in permit icmp any any 3 log 6 interval 300 access-list outside_acl_in permit 47 any any log 6 interval 300 access-list inside_acl_in permit 47 any any log 6 interval 300 access-list dmz_acl_in permit 47 any any log 6 interval 300 access-list outside_acl_in permit 50 any any log 6 interval 300 access-list inside_acl_in permit 50 any any log 6 interval 300 access-list dmz_acl_in permit 50 any any log 6 interval 300 ! ! Rule 11 (global) access-list outside_acl_in permit ip object-group id3DB0FA90.dst.net.0 object-group id3DB0F9E6.dst.net.0 ! ! Rule 12 (global) access-list outside_acl_in permit ip 192.168.4.0 255.255.255.0 host 192.168.1.1 access-list inside_acl_in permit ip object-group id3DB10695.src.net.0 host 192.168.1.1 access-list dmz_acl_in permit ip object-group id3DB10695.src.net.1 host 192.168.1.1 access-list outside_acl_in permit ip 192.168.4.0 255.255.255.0 object-group id3DB10695.dst.net.0 access-list inside_acl_in permit ip object-group id3DB10695.src.net.0 object-group id3DB10695.dst.net.0 access-list dmz_acl_in permit ip object-group id3DB10695.src.net.1 object-group id3DB10695.dst.net.0 ! ! Rule 13 (global) access-list outside_acl_in permit tcp any object-group id3DB0F9F2.dst.net.0 eq 3128 access-list inside_acl_in permit tcp any object-group id3DB0F9F2.dst.net.0 eq 3128 access-list dmz_acl_in permit tcp any object-group id3DB0F9F2.dst.net.0 eq 3128 ! ! Rule 14 (global) access-list outside_acl_in permit tcp any object-group id3DB0F9FC.dst.net.0 object-group id3DB0F9FC.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id3DB0F9FC.dst.net.0 object-group id3DB0F9FC.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id3DB0F9FC.dst.net.0 object-group id3DB0F9FC.srv.tcp.0 ! ! Rule 15 (global) access-list outside_acl_in permit tcp any object-group id3DB0FA07.dst.net.0 object-group id3DB0F9FC.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id3DB0FA07.dst.net.0 object-group id3DB0F9FC.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id3DB0FA07.dst.net.0 object-group id3DB0F9FC.srv.tcp.0 ! ! Rule 16 (global) access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id3DB0FA12.srv.tcp.0 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id3DB0FA12.srv.tcp.0 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id3DB0FA12.srv.tcp.0 ! ! Rule 19 (global) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 dmz access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list dmz_acl_in permit icmp any host 192.168.2.1 3 ! ! Rule 20 (global) access-list outside_acl_in permit ip host 22.22.22.22 host 22.22.22.22 log 6 interval 300 access-list inside_acl_in permit ip host 192.168.1.1 host 192.168.1.1 log 6 interval 300 access-list dmz_acl_in permit ip host 192.168.2.1 host 192.168.2.1 log 6 interval 300 ! ! Rule 21 (global) access-list outside_acl_in permit ip host 22.22.22.22 any access-list inside_acl_in permit ip host 192.168.1.1 any access-list dmz_acl_in permit ip host 192.168.2.1 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 22 (global) access-list outside_acl_in deny ip any any log 6 interval 300 access-list inside_acl_in deny ip any any log 6 interval 300 access-list dmz_acl_in deny ip any any log 6 interval 300 access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id3DB0F916.0 permit ip 192.168.1.0 255.255.255.0 any nat (inside) 1 access-list id3DB0F916.0 0 0 global (dmz) 1 interface ! ! ! Rule 1 (NAT) access-list id3DB0F924.0 permit ip 192.168.2.0 255.255.255.0 any access-list id3DB0F924.0 permit ip 192.168.3.0 255.255.255.0 any nat (dmz) 1 access-list id3DB0F924.0 0 0 ! ! Rule 2 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 3 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! Rule 4 (NAT) access-list id3DB0F94E.0 permit tcp host 192.168.1.10 eq 25 any static (inside,outside) tcp interface 25 access-list id3DB0F94E.0 0 0 ! ! Rule 5 (NAT) ! policy NAT ! rule global (inside) 7 interface access-list id3DB0F95C.0 permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0 access-list id3DB0F95C.0 permit ip 192.168.3.0 255.255.255.0 192.168.1.0 255.255.255.0 nat (dmz) 7 access-list id3DB0F95C.0 outside ! ! Rule 6 (NAT) ! policy NAT ! rule access-list id3F9353DD.0 permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 access-list id3F9353DD.0 permit ip 192.168.1.0 255.255.255.0 192.168.3.0 255.255.255.0 nat (inside) 1 access-list id3F9353DD.0 0 0 ! ! Rule 7 (NAT) access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.3.0 255.255.255.0 ! ! Rule 8 (NAT) access-list nat0.inside permit ip host 192.168.1.10 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.10 192.168.3.0 255.255.255.0 ! ! Rule 9 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 10 (NAT) static (inside,dmz) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Rule 11 (NAT) static (inside,outside) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/fwsm4.fw.orig0000755000175000017500000000720311733011756021117 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:15 2011 PDT by vadim ! ! Compiled for fwsm 4.x ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * fwsm4.fw ! ! using manual commit mode ! ! Prolog script: ! ! ! End of prolog script: ! hostname fwsm4 interface ethernet1 nameif outside security-level 0 exit interface ethernet0 nameif inside security-level 100 exit interface ethernet2 nameif dmz security-level 50 exit logging host inside 192.168.1.30 logging queue 512 logging facility 16 logging trap 0 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear config ssh aaa authentication ssh console LOCAL ssh timeout 5 clear config snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 poll snmp-server host inside 192.168.1.22 trap no service resetinbound sysopt connection tcpmss 1380 sysopt nodnsalias inbound sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect ils inspect rsh inspect rtsp inspect sip inspect skinny inspect esmtp inspect sqlnet service-policy global_policy global !################ access-list mode manual clear config access-list tmp_acl access-list commit access-list tmp_acl permit ip 192.168.1.0 255.255.255.0 any access-list tmp_acl deny ip any any access-list commit access-group tmp_acl in interface outside access-group tmp_acl in interface inside access-group tmp_acl in interface dmz clear xlate clear config static clear config global clear config nat clear config access-list dmz_acl_in clear config access-list inside_acl_in clear config access-list outside_acl_in clear config icmp clear config telnet access-list commit clear config object-group object-group network id59803X13930.src.net.0 network-object 10.0.0.0 255.255.255.0 network-object 10.1.0.0 255.255.255.0 network-object 172.16.0.1 255.255.255.255 network-object 172.16.0.2 255.255.255.255 exit ! ! Rule 1 (ethernet1) ! need this rule to generate at least one object group icmp permit 10.0.0.0 255.255.255.0 3 outside access-list outside_acl_in permit icmp 10.0.0.0 255.255.255.0 host 22.22.22.22 3 icmp permit 10.1.0.0 255.255.255.0 3 outside access-list outside_acl_in permit icmp 10.1.0.0 255.255.255.0 host 22.22.22.22 3 icmp permit host 172.16.0.1 3 outside access-list outside_acl_in permit icmp host 172.16.0.1 host 22.22.22.22 3 icmp permit host 172.16.0.2 3 outside access-list outside_acl_in permit icmp host 172.16.0.2 host 22.22.22.22 3 access-list outside_acl_in permit icmp object-group id59803X13930.src.net.0 any 3 ! ! Rule 2 (global) access-list outside_acl_in deny ip any any log 0 interval 300 access-list inside_acl_in deny ip any any log 0 interval 300 access-list dmz_acl_in deny ip any any log 0 interval 300 access-list commit access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 global (dmz) 1 interface ! ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall3.fw.orig0000755000175000017500000000705411733011756021753 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:06 2011 PDT by vadim ! ! Compiled for pix 6.2 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall3.fw ! ! testing icmp and ssh/telnet commands ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0 inside security100 nameif eth1 outside security0 nameif eth2 dmz security50 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear ssh aaa authentication ssh console LOCAL ssh timeout 5 clear snmp-server no snmp-server enable traps clear ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound no sysopt route dnat floodguard disable !################ clear access-list clear icmp clear telnet ! ! Rule 0 (eth0) ssh 0.0.0.0 0.0.0.0 inside access-list inside_acl_in permit tcp any any eq 22 ! ! Rule 1 (eth0) ssh 0.0.0.0 0.0.0.0 inside ! ! Rule 2 (eth0) icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list inside_acl_in permit icmp any any 3 ! ! Rule 3 (eth0) access-list inside_acl_in permit icmp any host 192.168.1.1 3 ! ! Rule 4 (eth1) ssh 0.0.0.0 0.0.0.0 outside access-list outside_acl_in permit tcp any any eq 22 ! ! Rule 5 (eth1) ssh 0.0.0.0 0.0.0.0 outside ! ! Rule 6 (eth1) icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list outside_acl_in permit icmp any any 3 ! ! Rule 7 (eth1) access-list outside_acl_in permit icmp any host 22.22.22.22 3 ! ! Rule 8 (global) access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list outside_acl_in permit icmp any host 22.22.22.22 3 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 access-list inside_acl_in permit icmp any any 3 access-list outside_acl_in permit icmp any any 3 access-list dmz_acl_in permit icmp any any 3 ! ! Rule 9 (global) access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list dmz_acl_in permit icmp any host 192.168.2.1 3 ! ! Rule 10 (global) ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 dmz access-list inside_acl_in permit tcp any any eq 22 access-list outside_acl_in permit tcp any any eq 22 access-list dmz_acl_in permit tcp any any eq 22 ! ! Rule 11 (global) ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 dmz ! ! Rule 12 (global) telnet 0.0.0.0 0.0.0.0 inside telnet 0.0.0.0 0.0.0.0 outside telnet 0.0.0.0 0.0.0.0 dmz access-list inside_acl_in permit tcp any any eq 23 access-list outside_acl_in permit tcp any any eq 23 access-list dmz_acl_in permit tcp any any eq 23 ! ! Rule 13 (global) telnet 0.0.0.0 0.0.0.0 inside telnet 0.0.0.0 0.0.0.0 outside telnet 0.0.0.0 0.0.0.0 dmz ! ! Rule 14 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/recycle0000755000175000017500000000007511733011756020133 0ustar sylvestresylvestre#!/bin/sh for f in *.fw; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/pix/firewall11.fw.orig0000755000175000017500000000551111733011756022026 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:02 2011 PDT by vadim ! ! Compiled for pix 6.2 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall11.fw ! ! testing conversion of objects into their natted addresses when outside interface has multiple addresses and nat rule uses ip address which is not the first one under interface. Nat rules 3-4-5 and global policy rule 0 ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth1 dmz security50 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound sysopt route dnat floodguard enable !################ ! ! Rule 0 (global) access-list outside_acl_in permit tcp any host 10.5.80.20 eq 80 access-list outside_acl_in permit tcp any host 192.168.1.10 eq 80 access-list dmz_acl_in permit tcp any host 192.168.1.10 eq 80 access-list inside_acl_in permit tcp any host 192.168.1.10 eq 80 ! ! Rule 1 (global) access-list inside_acl_in permit tcp any host 192.168.1.20 eq 1500 ! ! Rule 2 (global) access-list outside_acl_in deny tcp any any range 1000 10001 access-list dmz_acl_in deny tcp any any range 1000 10001 access-list inside_acl_in deny tcp any any range 1000 10001 ! ! Rule 3 (global) access-list outside_acl_in permit ip any 192.168.1.0 255.255.255.0 access-list dmz_acl_in permit ip any 192.168.1.0 255.255.255.0 access-list inside_acl_in permit ip any 192.168.1.0 255.255.255.0 ! ! Rule 4 (global) access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (dmz) 1 interface nat (inside) 1 192.168.1.0 255.255.255.0 0 0 ! ! Rule 1 (NAT) global (outside) 1 interface ! nat (dmz) 1 192.168.2.0 255.255.255.0 0 0 ! ! Rule 2 (NAT) ! ! ! ! Rule 3 (NAT) static (inside,outside) tcp 10.5.80.20 80 192.168.1.10 80 netmask 255.255.240.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall92.fw.orig0000755000175000017500000000642111733011756022040 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:13 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall92.fw ! ! testing new style ASA 8.3 nat commands ! no-nat rules ("identity nat") ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif inside security-level 100 exit interface FastEthernet1 nameif outside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object service http.0 service tcp destination eq 80 exit object service smtp.0 service tcp destination eq 25 exit object network spamhost1.0 host 61.150.47.112 exit object network hostA:eth0.0 host 192.168.1.10 exit object network Internal_net.0 subnet 192.168.1.0 255.255.255.0 exit object network internal_subnet_1.0 subnet 192.168.1.0 255.255.255.192 exit object network internal_subnet_2.0 subnet 192.168.1.64 255.255.255.192 exit object network test_range_1.0 range 192.168.1.11 192.168.1.15 exit object-group network id20655X6113.osrc.net.0 network-object object internal_subnet_1.0 network-object object internal_subnet_2.0 exit object-group network id20600X6113.osrc.net.0 network-object object test_range_1.0 exit ! ! Rule 0 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) nat (inside,outside) source static Internal_net.0 Internal_net.0 service http.0 http.0 description "0 (NAT)" ! ! Rule 1 (NAT) nat (inside,outside) source static hostA:eth0.0 hostA:eth0.0 service smtp.0 smtp.0 description "1 (NAT)" ! ! Rule 2 (NAT) nat (inside,outside) source static hostA:eth0.0 hostA:eth0.0 destination static spamhost1.0 spamhost1.0 service smtp.0 smtp.0 description "2 (NAT)" ! ! Rule 3 (NAT) nat (inside,outside) source static id20655X6113.osrc.net.0 id20655X6113.osrc.net.0 service smtp.0 smtp.0 description "3 (NAT)" ! ! Rule 4 (NAT) nat (inside,outside) source static id20600X6113.osrc.net.0 id20600X6113.osrc.net.0 destination static spamhost1.0 spamhost1.0 service smtp.0 smtp.0 description "4 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall81.fw.orig0000755000175000017500000001145711733011756022043 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:10 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall81.fw ! ! test for the warning issued when translated address is used in ! policy rule ! C firewall81:Policy:1: warning: Object firewall81:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. ! C firewall81:Policy:2: warning: Object firewall81:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. ! C firewall81:Policy:3: warning: Object firewall81:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif inside security-level 100 exit interface FastEthernet1 nameif outside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object object service http.0 service tcp destination eq 80 exit object network hostA:eth0.0 host 192.168.1.10 exit ! ! Rule 0 (global) ! matching "any" icmp and "all" tcp ! in one service-group ! access-list inside_acl_in deny icmp any object hostA:eth0.0 access-list outside_acl_in deny icmp any object hostA:eth0.0 access-list inside_acl_in deny tcp any object hostA:eth0.0 access-list outside_acl_in deny tcp any object hostA:eth0.0 ! ! Rule 1 (FastEthernet1) ! test rule using translated address in dst ! firewall81:Policy:1: warning: Object firewall81:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 ! ! Rule 2 (global) ! test rule using translated address in dst ! firewall81:Policy:2: warning: Object firewall81:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 ! ! Rule 3 (global) ! test rule using translated address in dst ! firewall81:Policy:3: warning: Object firewall81:FastEthernet1:ip that represents translated address in a NAT rule 0 (NAT) is used in a policy rule of ASA v8.3 firewall. Starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. http 0.0.0.0 0.0.0.0 inside http 0.0.0.0 0.0.0.0 outside ! ! Rule 4 (global) ! for #1942 ! using custom service access-list inside_acl_in deny tcp any object hostA:eth0.0 neq 8080 access-list outside_acl_in deny tcp any object hostA:eth0.0 neq 8080 ! ! Rule 5 (global) ! for #1942 ! using custom service access-list inside_acl_in deny tcp any object hostA:eth0.0 neq 8080 access-list outside_acl_in deny tcp any object hostA:eth0.0 neq 8080 access-list inside_acl_in deny tcp any object hostA:eth0.0 eq 3128 access-list outside_acl_in deny tcp any object hostA:eth0.0 eq 3128 ! ! Rule 6 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 http.0 description "0 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall21-1.fw.orig0000755000175000017500000001600311733011756022163 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:04 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall21-1.fw ! ! testing outbound ACLs ! this is a copy of firewall21 except with different version ! v6.3, outbound ACLs are not supported ! C firewall21-1:Policy:12: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21-1:Policy:14: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21-1:Policy:18: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21-1:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21-1:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21-1:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth1 dmz security50 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard enable fixup protocol ftp 21 !################ ! ! Rule 0 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 1 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 2 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 3 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 4 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 5 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 6 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 7 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 8 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 9 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 10 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 11 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 12 (eth1) ! dmz -> intnet ! firewall21-1:Policy:12: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 13 (eth1) ! dmz -> intnet access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 15 (eth2) ! dmz -> intnet access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 16 (eth2) ! dmz -> intnet access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 17 (eth2) ! dmz -> intnet access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 18 (eth1,eth2) ! dmz -> intnet ! firewall21-1:Policy:18: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 19 (eth0,eth1) access-list outside_acl_in deny ip host 10.5.70.20 any log 0 interval 300 access-list outside_acl_in deny ip host 192.168.2.20 any log 0 interval 300 access-list outside_acl_in deny ip host 192.168.1.20 any log 0 interval 300 access-list outside_acl_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 access-list dmz_acl_in deny ip host 10.5.70.20 any log 0 interval 300 access-list dmz_acl_in deny ip host 192.168.2.20 any log 0 interval 300 access-list dmz_acl_in deny ip host 192.168.1.20 any log 0 interval 300 access-list dmz_acl_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 20 (eth0,eth1) ! firewall21-1:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 21 (global) access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id4529FE6016799.0 permit ip 192.168.1.0 255.255.255.0 any nat (inside) 1 access-list id4529FE6016799.0 0 0 ! ! Rule 1 (NAT) access-list id4529FE6E16799.0 permit ip 192.168.2.0 255.255.255.0 any nat (dmz) 1 access-list id4529FE6E16799.0 0 0 ! ! Rule 2 (NAT) access-list id4529FE7C16799.0 permit ip host 192.168.2.100 any static (dmz,outside) interface access-list id4529FE7C16799.0 0 0 ! ! Rule 3 (NAT) global (inside) 3 interface access-list id4529FE8A16799.0 permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0 nat (dmz) 3 access-list id4529FE8A16799.0 outside ! ! Rule 4 (NAT) global (dmz) 4 interface access-list id4529FE9816799.0 permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 4 access-list id4529FE9816799.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall4.fw.orig0000755000175000017500000000727411733011756021760 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:08 2011 PDT by vadim ! ! Compiled for pix 6.2 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall4.fw ! ! this object is used to test "Replace NAT'ted objects with their translations" option ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0 inside security100 nameif eth1 dmz1 security40 nameif eth2 dmz2 security50 nameif eth3 outside security0 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout uauth 2:0:0 absolute telnet timeout -1 clear ssh aaa authentication ssh console LOCAL ssh timeout -1 clear snmp-server no snmp-server enable traps clear ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound no sysopt route dnat floodguard disable !################ clear xlate clear static clear global clear nat clear access-list clear icmp clear telnet clear object-group object-group service id3D79A1C2.srv.tcp.0 tcp port-object eq 80 port-object eq 22 exit object-group network id3D79A1E4.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit ! ! Rule 0 (global) access-list inside_acl_in permit tcp any host 192.168.1.10 eq 22 access-list dmz1_acl_in permit tcp any host 192.168.1.10 eq 22 access-list dmz2_acl_in permit tcp any host 192.168.2.1 eq 22 access-list dmz2_acl_in permit tcp any host 192.168.1.10 eq 22 access-list outside_acl_in permit tcp any host 222.222.222.222 eq 22 access-list outside_acl_in permit tcp any host 192.168.1.10 eq 22 ! ! Rule 1 (global) access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id3D79A1C2.srv.tcp.0 access-list dmz1_acl_in permit tcp any host 192.168.1.10 object-group id3D79A1C2.srv.tcp.0 access-list dmz2_acl_in permit tcp any host 192.168.2.1 eq 22 access-list dmz2_acl_in permit tcp any host 192.168.1.10 object-group id3D79A1C2.srv.tcp.0 access-list outside_acl_in permit tcp any host 222.222.222.222 eq 22 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id3D79A1C2.srv.tcp.0 ! ! Rule 2 (global) access-list inside_acl_in permit tcp any object-group id3D79A1E4.dst.net.0 eq 22 access-list dmz1_acl_in permit tcp any object-group id3D79A1E4.dst.net.0 eq 22 access-list dmz2_acl_in permit tcp any host 192.168.2.1 eq 22 access-list dmz2_acl_in permit tcp any object-group id3D79A1E4.dst.net.0 eq 22 access-list outside_acl_in permit tcp any host 222.222.222.222 eq 22 access-list outside_acl_in permit tcp any object-group id3D79A1E4.dst.net.0 eq 22 ! ! Rule 3 (global) ! 'masquerading' rule access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 4 (global) ! 'catch all' rule access-list inside_acl_in deny ip any any access-list dmz1_acl_in deny ip any any access-list dmz2_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group dmz1_acl_in in interface dmz1 access-group dmz2_acl_in in interface dmz2 access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) static (inside,outside) tcp interface 22 192.168.1.10 22 0 0 ! ! Rule 1 (NAT) static (inside,dmz2) tcp interface 22 192.168.1.10 22 0 0 ! ! Rule 2 (NAT) static (inside,dmz2) tcp interface 22 192.168.1.10 22 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall12.fw.orig0000755000175000017500000001054211733011756022027 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:03 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall12.fw ! ! this firewall has DMZ using routable address ! ! Prolog script: ! ! ! End of prolog script: ! hostname firewall12 nameif ethernet0 outside security0 ip address outside dhcp setroute retry 10 nameif ethernet1 inside security100 ip address inside 10.3.14.20 255.255.255.0 nameif ethernet2 dmz50 security50 ip address dmz50 192.0.2.1 255.255.255.0 logging host inside 10.3.14.10 format emblem logging queue 1000 logging facility 16 no logging buffered no logging console no logging timestamp logging on logging device-id string real_firewall timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout rpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 snmp-server community public snmp-server enable traps snmp-server host inside 10.3.14.40 poll ntp server 10.3.14.30 source inside no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable fixup protocol dns maximum-length 65535 fixup protocol ftp 21 fixup protocol http 80 fixup protocol icmp error !################ object-group network id3F8F95CD.dst.net.0 network-object host 192.0.2.20 network-object host 192.0.2.21 network-object host 192.0.2.23 exit ! ! Rule 0 (global) access-list inside_acl_in remark 0 (global) access-list inside_acl_in permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 1 (global) ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 2 (global) icmp permit any 0 outside access-list outside_acl_in remark 2 (global) access-list outside_acl_in permit icmp any interface outside 0 icmp permit any 0 inside access-list inside_acl_in remark 2 (global) access-list inside_acl_in permit icmp any host 10.3.14.20 0 icmp permit any 0 dmz50 access-list dmz50_acl_in remark 2 (global) access-list dmz50_acl_in permit icmp any host 192.0.2.1 0 ! ! Rule 3 (global) ! this comment ! consists of ! 3 lines of text access-list outside_acl_in remark 3 (global) access-list outside_acl_in remark this comment access-list outside_acl_in remark consists of access-list outside_acl_in remark 3 lines of text access-list outside_acl_in permit tcp any interface outside eq 80 access-list outside_acl_in permit tcp any object-group id3F8F95CD.dst.net.0 eq 80 access-list inside_acl_in remark 3 (global) access-list inside_acl_in remark this comment access-list inside_acl_in remark consists of access-list inside_acl_in remark 3 lines of text access-list inside_acl_in permit tcp any object-group id3F8F95CD.dst.net.0 eq 80 access-list dmz50_acl_in remark 3 (global) access-list dmz50_acl_in remark this comment access-list dmz50_acl_in remark consists of access-list dmz50_acl_in remark 3 lines of text access-list dmz50_acl_in permit tcp any object-group id3F8F95CD.dst.net.0 eq 80 ! ! Rule 4 (global) access-list outside_acl_in remark 4 (global) access-list outside_acl_in permit tcp any interface outside eq 80 ! ! Rule 5 (global) access-list dmz50_acl_in remark 5 (global) access-list dmz50_acl_in permit tcp any host 192.0.2.1 eq 80 ! ! Rule 6 (global) access-list outside_acl_in remark 6 (global) access-list outside_acl_in deny ip any any log 5 interval 120 access-list inside_acl_in remark 6 (global) access-list inside_acl_in deny ip any any log 5 interval 120 access-list dmz50_acl_in remark 6 (global) access-list dmz50_acl_in deny ip any any log 5 interval 120 access-group dmz50_acl_in in interface dmz50 access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id3F8F9592.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id3F8F9592.0 0 0 global (dmz50) 1 interface ! ! ! Rule 1 (NAT) access-list id3F8F95A0.0 permit tcp host 10.3.14.30 eq 80 any static (inside,outside) tcp interface 80 access-list id3F8F95A0.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall94.fw.orig0000755000175000017500000000330111733011756022034 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:13 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall94.fw ! ! test using address ranges in policy rule ! ! Prolog script: ! ! ! End of prolog script: ! interface Ethernet0/0 nameif outside security-level 0 exit interface Ethernet0/1 nameif inside security-level 100 exit no logging buffered no logging console no logging timestamp no logging on telnet timeout -1 clear config ssh aaa authentication ssh console LOCAL ssh timeout -1 clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy service-policy global_policy global !################ clear config access-list clear config icmp clear config telnet clear config object-group clear config object object network inside-range-1.0 range 10.0.0.5 10.0.0.10 exit object network inside-range-2.0 range 10.0.0.8 10.0.0.15 exit object-group network id26782X14355.src.net.0 network-object object inside-range-1.0 network-object object inside-range-2.0 exit ! ! Rule 0 (global) access-list inside_acl_in remark 0 (global) access-list inside_acl_in deny ip object-group id26782X14355.src.net.0 any log 6 interval 300 access-group inside_acl_in in interface inside ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/cluster1-1_pix2.fw.orig0000755000175000017500000001233111733011756022717 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:17 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: yes ! Assume firewall is part of any: yes ! !# files: * cluster1-1_pix2.fw ! ! ! pix2::: warning: Interface Ethernet0 has vlan subinterfaces, it can not be used for ACL. Marking this interface "unprotected" to exclude it. ! ! Prolog script: ! ! ! End of prolog script: ! hostname pix2 interface Ethernet1 nameif inside ip address 10.3.14.207 255.255.255.0 standby 10.3.14.206 security-level 100 exit interface Ethernet0 no nameif no ip address no security-level exit interface Ethernet2 description LAN/STATE Failover Interface no nameif exit interface Ethernet0.101 vlan 101 nameif outside ip address 192.0.2.254 255.255.255.0 standby 192.0.2.253 security-level 0 exit interface Ethernet0.102 vlan 102 nameif dmz20 ip address 10.0.0.254 255.255.255.0 standby 10.0.0.253 security-level 20 exit failover lan unit secondary failover lan interface failover Ethernet2 failover lan enable failover key super_secret failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover link failover Ethernet2 failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global !################ clear xlate clear config static clear config global clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object-group network id56590X61097.src.net.0 network-object host 10.3.14.206 network-object host 10.3.14.207 exit object-group network id56590X61097.src.net.1 network-object host 172.17.1.253 network-object host 172.17.1.254 network-object host 192.0.2.253 network-object host 192.0.2.254 exit object-group network id56590X61097.src.net.2 network-object host 10.0.0.253 network-object host 10.0.0.254 exit object-group network id56627X61097.src.net.0 network-object host 172.17.1.253 network-object host 192.0.2.253 exit ! ! Rule 0 (Ethernet0.101) ! anti spoofing rule access-list outside_in deny ip object-group id56590X61097.src.net.0 any log 3 interval 300 access-list outside_in deny ip object-group id56590X61097.src.net.1 any log 3 interval 300 access-list outside_in deny ip object-group id56590X61097.src.net.2 any log 3 interval 300 access-list outside_in deny ip 10.3.14.0 255.255.255.0 any log 3 interval 300 ! ! Rule 1 (global) ! SSH Access to firewall is permitted ! only from internal network ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 2 (global) ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 3 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp host 10.3.14.206 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp object-group id56627X61097.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp host 10.0.0.253 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 ! ! Rule 4 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp object-group id56590X61097.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp object-group id56590X61097.src.net.1 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 access-list inside_out permit udp object-group id56590X61097.src.net.2 10.3.14.0 255.255.255.0 eq 53 log 3 interval 300 ! ! Rule 5 (global) ! All other attempts to connect to ! the firewall are denied and logged access-list inside_in deny ip any object-group id56590X61097.src.net.0 log 3 interval 300 access-list inside_in deny ip any object-group id56590X61097.src.net.1 log 3 interval 300 access-list inside_in deny ip any object-group id56590X61097.src.net.2 log 3 interval 300 ! ! Rule 6 (global) access-list inside_in permit ip 10.3.14.0 255.255.255.0 any access-list inside_out permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 7 (global) access-list inside_in deny ip any any log 3 interval 300 access-list inside_out deny ip any any log 3 interval 300 access-group inside_in in interface inside access-group inside_out out interface inside access-group outside_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id56689X61097.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id56689X61097.0 tcp 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall23.fw.orig0000755000175000017500000000421511733011756022031 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:06 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall23.fw ! ! lots of different combinations of objects in the NAT rules ! User sets inbound and outbound interfaces in NAT rules ! ! Prolog script: ! ! ! End of prolog script: ! nameif ethernet0 inside security100 nameif ethernet1 outside security0 nameif ethernet2 dmz security50 no logging buffered no logging console no logging timestamp no logging on telnet timeout 5 clear ssh aaa authentication ssh console LOCAL ssh timeout 5 clear snmp-server no snmp-server enable traps clear ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable clear xlate clear static clear global clear nat ! ! Rule 0 (NAT) global (outside) 1 interface access-list id1641246X21763.0 permit ip 192.168.1.0 255.255.255.0 any global (dmz) 1 interface ! ! ! Rule 1 (NAT) ! global (outside) 1 interface ! ! ! Rule 2 (NAT) ! ! ! ! Rule 3 (NAT) ! ! global (dmz) 1 interface ! ! ! ! Rule 4 (NAT) access-list id626114X21763.0 permit ip 192.168.1.0 255.255.255.0 any nat (outside) 1 access-list id626114X21763.0 0 0 ! ! ! Rule 5 (NAT) access-list id36895X21071.0 permit tcp host 192.168.1.1 eq 6667 any static (inside,outside) tcp interface 6667 access-list id36895X21071.0 0 0 ! ! Rule 6 (NAT) access-list id36809X21071.0 permit tcp host 192.168.1.10 eq 6667 any ! ! Rule 7 (NAT) access-list id36809X21071.0 permit tcp host 192.168.1.10 eq 6667 any ! ! Rule 8 (NAT) access-list id36809X21071.0 permit tcp host 192.168.1.10 eq 6667 any static (inside,outside) tcp interface 6667 access-list id36809X21071.0 0 0 access-list id1641340X21763.1 permit tcp host 192.168.1.10 eq 6667 any static (inside,dmz) tcp interface 6667 access-list id1641340X21763.1 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/objects-for-regression-tests.fwb0000644000175000017500000421661611733011756025030 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk -m ip_conntrack_talk -m ip_nat_talk tcp destination neq 8080 neq 8080 fwbuilder-5.1.0.3599/test/pix/block-hosts.tbl0000644000175000017500000000163011733011756021510 0ustar sylvestresylvestre# # use this table to test run-time AddressTable object # (this is just a small collection of addresses that sent spam to me # on Nov 20 2005) # 151.8.224.178 # this is also a comment 168.156.76.20 193.207.126.36 195.136.186.35 196.15.136.15 201.10.180.138 201.17.93.16 201.36.156.121 202.103.25.253 202.96.112.93 203.162.3.209 203.209.124.144 210.106.193.237 210.222.114.102 211.144.143.143 211.172.218.237 211.250.16.132 212.100.212.100 212.21.241.31 218.104.138.146 218.18.72.252 218.39.114.122 218.55.115.43 219.132.104.160 220.71.17.86 220.81.50.105 220.91.99.46 221.14.249.242 221.166.177.135 221.198.33.38 221.202.160.233 221.205.54.125 221.217.44.248 222.100.212.223 222.121.118.144 222.174.113.2 58.231.13.78 58.33.181.83 58.53.82.190 61.150.47.112 61.184.14.102 64.106.85.186 70.228.60.100 80.243.72.149 80.249.77.34 80.51.236.6 81.196.74.125 81.2.36.254 82.117.221.205 82.143.196.17 82.77.37.174 84.90.8.198 fwbuilder-5.1.0.3599/test/pix/firewall13.fw.orig0000755000175000017500000000570411733011756022034 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:03 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall13.fw ! ! various policy NAT rules per examples from ! http://www.cisco.com/en/US/products/sw/secursw/ps2120/products_configuration_guide_chapter09186a0080172786.html#1113601 ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard enable !################ ! ! Rule 0 (global) access-list outside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 1 (global) access-list outside_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id3FA349A3.0 permit ip 10.1.2.0 255.255.255.0 209.165.201.0 255.255.255.224 ! ! Rule 1 (NAT) global (outside) 1 interface access-list id3FA34CB5.0 permit ip 10.1.2.0 255.255.255.0 209.165.200.224 255.255.255.224 ! ! Rule 2 (NAT) access-list id3FA349A3.0 permit tcp 10.1.2.0 255.255.255.0 host 209.165.201.11 eq 80 nat (inside) 1 access-list id3FA349A3.0 0 0 ! ! Rule 3 (NAT) access-list id3FA34CB5.0 permit tcp 10.1.2.0 255.255.255.0 host 209.165.201.11 eq 23 ! ! Rule 4 (NAT) ! ! ! ! Rule 5 (NAT) access-list id3FA35071.0 permit ip host 10.1.2.27 209.165.201.0 255.255.255.224 static (inside,outside) interface access-list id3FA35071.0 0 0 ! ! Rule 6 (NAT) access-list id3FA35063.0 permit ip host 10.1.2.27 209.165.200.224 255.255.255.224 static (inside,outside) interface access-list id3FA35063.0 0 0 ! ! Rule 7 (NAT) access-list id3FA44ABB.0 permit tcp host 10.1.2.27 eq 80 host 209.165.200.225 access-list id3FA44ABB.1 permit tcp host 10.1.2.27 eq 81 host 209.165.200.225 access-list id3FA44ABB.0 permit tcp host 10.1.2.27 eq 80 host 209.165.201.11 static (inside,outside) tcp interface 80 access-list id3FA44ABB.0 0 0 access-list id3FA44ABB.1 permit tcp host 10.1.2.27 eq 81 host 209.165.201.11 static (inside,outside) tcp interface 81 access-list id3FA44ABB.1 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/networks-table-1.txt0000644000175000017500000000006011733011756022411 0ustar sylvestresylvestre10.1.0.0/24 10.1.2.0/24 10.1.3.0/24 10.1.4.0/24 fwbuilder-5.1.0.3599/test/pix/firewall90.fw.orig0000755000175000017500000002563711733011756022050 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:11 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall90.fw ! ! testing new style ASA 8.3 nat commands ! SNAT rules ! N firewall90:NAT:13: error: Option 'translate dns' can not be used in combination with destination matching or translation ! N firewall90:NAT:14: error: Option 'translate dns' can not be used in combination with service matching or translation ! N firewall90:NAT:19: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! N firewall90:NAT:24: error: CustomService objects are not supported in NAT rules ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif inside security-level 100 exit interface FastEthernet1 nameif outside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object service http.0 service tcp destination eq 80 exit object service smtp.0 service tcp destination eq 25 exit object service smtps.0 service tcp destination eq 465 exit object service squid.0 service tcp destination eq 3128 exit object network spamhost1.0 host 61.150.47.112 exit object network external_gw_1.0 host 22.22.22.254 exit object network external_gw2.0 host 22.22.22.100 exit object network spamhost2.0 host 61.150.47.113 exit object network hostA:eth0.0 host 192.168.1.10 exit object network Internal_net.0 subnet 192.168.1.0 255.255.255.0 exit object network internal_subnet_1.0 subnet 192.168.1.0 255.255.255.192 exit object network internal_subnet_2.0 subnet 192.168.1.64 255.255.255.192 exit object network ext_subnet.0 subnet 22.22.22.128 255.255.255.224 exit object network ext_subnet-192.0 subnet 22.22.22.128 255.255.255.192 exit object network test_range_1.0 range 192.168.1.11 192.168.1.15 exit object network outside_range.0 range 22.22.22.21 22.22.22.25 exit object network outside_range-1.0 range 22.22.22.30 22.22.22.40 exit object network firewall90:FastEthernet1:ip.0 host 22.22.22.22 exit object network firewall90:FastEthernet1:ip-1.0 host 22.22.22.23 exit object-group network id178211X29963.osrc.net.0 network-object object internal_subnet_1.0 network-object object internal_subnet_2.0 exit object-group network id21353X4994.osrc.net.0 network-object object Internal_net.0 network-object object internal_subnet_1.0 network-object object internal_subnet_2.0 exit object-group network id20069X32406.osrc.net.0 network-object object test_range_1.0 exit object-group network id130599X29063.tsrc.net.0 network-object object outside_range.0 network-object object firewall90:FastEthernet1:ip.0 network-object object external_gw2.0 exit object-group network id20720X27505.tsrc.net.0 network-object object outside_range.0 network-object object external_gw2.0 exit object-group network id241772X29764.tsrc.net.0 network-object object outside_range.0 exit object-group network id643092X27990.tsrc.net.0 network-object object ext_subnet.0 exit object-group network id21121X3710.tsrc.net.0 network-object object outside_range-1.0 network-object object external_gw2.0 exit object-group network id21177X3720.tsrc.net.0 network-object object ext_subnet.0 exit object-group network id77971X5929.odst.net.0 network-object object spamhost1.0 network-object object spamhost2.0 exit object-group network id77971X5929.tsrc.net.0 network-object object outside_range-1.0 network-object object external_gw2.0 exit object-group network id77971X5929.tsrc.net.1 network-object object outside_range-1.0 network-object object external_gw2.0 exit object-group network id78630X30274.src.net.0 network-object 10.1.2.0 255.255.255.0 network-object 10.1.3.0 255.255.255.0 exit ! ! Rule 0 (global) access-list outside_acl_in deny ip object-group id78630X30274.src.net.0 any ! ! Rule 1 (global) ! for #1942 ! using custom service access-list inside_acl_in deny tcp any object hostA:eth0.0 tcp destination neq 8080 access-list outside_acl_in deny tcp any object hostA:eth0.0 tcp destination neq 8080 ! ! Rule 2 (global) ! for #1942 ! using custom service access-list inside_acl_in deny tcp any object hostA:eth0.0 tcp destination neq 8080 access-list outside_acl_in deny tcp any object hostA:eth0.0 tcp destination neq 8080 access-list inside_acl_in deny tcp any object hostA:eth0.0 eq 3128 access-list outside_acl_in deny tcp any object hostA:eth0.0 eq 3128 ! ! Rule 3 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) nat (inside,outside) source dynamic Internal_net.0 interface service http.0 http.0 description "0 (NAT)" ! ! Rule 1 (NAT) nat (inside,outside) source static hostA:eth0.0 firewall90:FastEthernet1:ip-1.0 destination static spamhost1.0 spamhost1.0 service smtp.0 smtp.0 description "1 (NAT)" ! ! Rule 2 (NAT) nat (inside,outside) source static hostA:eth0.0 interface service smtp.0 smtp.0 description "2 (NAT)" ! ! Rule 3 (NAT) nat (inside,outside) source dynamic id178211X29963.osrc.net.0 firewall90:FastEthernet1:ip-1.0 service smtp.0 smtp.0 description "3 (NAT)" ! ! Rule 4 (NAT) ! for #1928 ! note that group in OSrc includes another group nat (inside,outside) source dynamic id21353X4994.osrc.net.0 firewall90:FastEthernet1:ip-1.0 service smtp.0 smtp.0 description "4 (NAT)" ! ! Rule 5 (NAT) nat (inside,outside) source dynamic id20069X32406.osrc.net.0 firewall90:FastEthernet1:ip-1.0 destination static spamhost1.0 spamhost1.0 service smtp.0 smtp.0 description "5 (NAT)" ! ! Rule 6 (NAT) nat (inside,outside) source static hostA:eth0.0 firewall90:FastEthernet1:ip-1.0 destination static spamhost1.0 external_gw_1.0 service smtp.0 smtp.0 description "6 (NAT)" ! ! Rule 7 (NAT) ! For #1907 nat (inside,outside) source dynamic hostA:eth0.0 id130599X29063.tsrc.net.0 service smtp.0 smtp.0 description "7 (NAT)" ! ! Rule 8 (NAT) ! For #1907 nat (inside,outside) source dynamic hostA:eth0.0 id20720X27505.tsrc.net.0 interface service smtp.0 smtp.0 description "8 (NAT)" ! ! Rule 9 (NAT) ! For #1907 nat (inside,outside) source dynamic hostA:eth0.0 id241772X29764.tsrc.net.0 interface service smtp.0 smtp.0 description "9 (NAT)" ! ! Rule 10 (NAT) ! For #1907 nat (inside,outside) source static hostA:eth0.0 hostA:eth0.0 service smtp.0 smtp.0 description "10 (NAT)" ! ! Rule 11 (NAT) ! For #1907 nat (inside,outside) source dynamic hostA:eth0.0 id643092X27990.tsrc.net.0 interface service smtp.0 smtp.0 description "11 (NAT)" ! ! Rule 12 (NAT) ! for #1902 nat (inside,outside) source dynamic internal_subnet_1.0 firewall90:FastEthernet1:ip-1.0 dns description "12 (NAT)" ! ! Rule 13 (NAT) ! for #1902 ! can't use dns with destination matching or translation ! firewall90:NAT:13: error: Option 'translate dns' can not be used in combination with destination matching or translation nat (inside,outside) source dynamic internal_subnet_1.0 firewall90:FastEthernet1:ip-1.0 destination static spamhost1.0 spamhost1.0 dns description "13 (NAT)" ! ! Rule 14 (NAT) ! for #1902 ! cant use dns with service translation either ! firewall90:NAT:14: error: Option 'translate dns' can not be used in combination with service matching or translation nat (inside,outside) source dynamic internal_subnet_1.0 firewall90:FastEthernet1:ip-1.0 service smtp.0 smtp.0 dns description "14 (NAT)" ! ! Rule 15 (NAT) ! for #1908 ! "static" vs "dynamic" nat (inside,outside) source static hostA:eth0.0 firewall90:FastEthernet1:ip-1.0 description "15 (NAT)" ! ! Rule 16 (NAT) ! for #1908 ! "static" vs "dynamic" nat (inside,outside) source dynamic hostA:eth0.0 id241772X29764.tsrc.net.0 description "16 (NAT)" ! ! Rule 17 (NAT) ! for #1908 "static" vs "dynamic" ! for #1885 "named object" - create ! for #1907 "multiple objects in TSrc" ! network object to define address range, then add it to object-group nat (inside,outside) source dynamic hostA:eth0.0 id21121X3710.tsrc.net.0 interface description "17 (NAT)" ! ! Rule 18 (NAT) ! for #1908, #1916 "static" vs "dynamic" ! for #1907 "multiple objects in TSrc" nat (inside,outside) source dynamic hostA:eth0.0 id21177X3720.tsrc.net.0 interface description "18 (NAT)" ! ! Rule 19 (NAT) ! for #1908 ! "static" vs "dynamic" ! firewall90:NAT:19: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. nat (outside,outside) source dynamic id241772X29764.tsrc.net.0 firewall90:FastEthernet1:ip-1.0 description "19 (NAT)" ! ! Rule 20 (NAT) ! for #1908 ! "static" vs "dynamic" nat (inside,outside) source dynamic internal_subnet_1.0 firewall90:FastEthernet1:ip-1.0 description "20 (NAT)" ! ! Rule 21 (NAT) ! for #1908 ! "static" vs "dynamic" nat (inside,outside) source static internal_subnet_1.0 firewall90:FastEthernet1:ip-1.0 description "21 (NAT)" ! ! Rule 22 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 squid.0 description "22 (NAT)" ! ! Rule 23 (NAT) ! multiple objects in OSrc, ODst, OSrv and TSrc in various combinations nat (inside,outside) source dynamic id178211X29963.osrc.net.0 id77971X5929.tsrc.net.0 interface destination static id77971X5929.odst.net.0 id77971X5929.odst.net.0 service smtp.0 smtp.0 description "23 (NAT)" nat (inside,outside) source dynamic id178211X29963.osrc.net.0 id77971X5929.tsrc.net.1 interface destination static id77971X5929.odst.net.0 id77971X5929.odst.net.0 service smtps.0 smtps.0 description "23 (NAT)" ! ! Rule 25 (NAT) ! for #1916 ! "static" vs "dynamic" when TSrc is subnet nat (inside,outside) source static internal_subnet_1.0 ext_subnet-192.0 description "25 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall21.fw.orig0000755000175000017500000001626611733011756022040 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:04 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall21.fw ! ! testing outbound ACLs ! v7.0, outbound ACLs are supported ! option 'generate outbound acls' is OFF ! C firewall21:Policy:12: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21:Policy:14: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21:Policy:18: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall21:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! interface eth0 nameif outside security-level 0 exit interface eth1 nameif dmz security-level 50 exit interface eth2 nameif inside security-level 100 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp service-policy global_policy global !################ ! ! Rule 0 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 1 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 2 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 3 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 4 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 5 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 6 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 7 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 8 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 9 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 10 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 11 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 12 (eth1) ! dmz -> intnet ! firewall21:Policy:12: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 13 (eth1) ! dmz -> intnet access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 15 (eth2) ! dmz -> intnet access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 16 (eth2) ! dmz -> intnet access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 17 (eth2) ! dmz -> intnet access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 18 (eth1,eth2) ! dmz -> intnet ! firewall21:Policy:18: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 19 (eth0,eth1) access-list outside_acl_in deny ip host 10.5.70.20 any log 0 interval 300 access-list outside_acl_in deny ip host 192.168.2.20 any log 0 interval 300 access-list outside_acl_in deny ip host 192.168.1.20 any log 0 interval 300 access-list outside_acl_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 access-list dmz_acl_in deny ip host 10.5.70.20 any log 0 interval 300 access-list dmz_acl_in deny ip host 192.168.2.20 any log 0 interval 300 access-list dmz_acl_in deny ip host 192.168.1.20 any log 0 interval 300 access-list dmz_acl_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 20 (eth0,eth1) ! firewall21:Policy:20: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 21 (global) access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id45293EF520039.0 permit ip 192.168.1.0 255.255.255.0 any nat (inside) 1 access-list id45293EF520039.0 tcp 0 0 ! ! Rule 1 (NAT) access-list id45293F0320039.0 permit ip 192.168.2.0 255.255.255.0 any nat (dmz) 1 access-list id45293F0320039.0 tcp 0 0 ! ! Rule 2 (NAT) access-list id45293F1120039.0 permit ip host 192.168.2.100 any static (dmz,outside) interface access-list id45293F1120039.0 tcp 0 0 ! ! Rule 3 (NAT) global (inside) 3 interface access-list id45293F1F20039.0 permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0 nat (dmz) 3 access-list id45293F1F20039.0 outside ! ! Rule 4 (NAT) global (dmz) 4 interface access-list id45293F2D20039.0 permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 4 access-list id45293F2D20039.0 tcp 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall20.fw.orig0000755000175000017500000001201611733011756022024 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:04 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall20.fw ! ! testing outbound ACLs ! v6.3, emulation of outbound ACLs is on ! C firewall20:Policy:5: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall20:Policy:7: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall20:Policy:7: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall20:Policy:7: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! nameif eth0 outside security0 nameif eth1 dmz security50 nameif eth2 inside security100 no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout rpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard enable fixup protocol ftp 21 !################ ! ! Rule 0 (global) access-list outside_acl_in permit ip any host 192.168.1.10 access-list dmz_acl_in permit ip any host 192.168.1.10 access-list inside_acl_in permit ip any host 192.168.1.10 ! ! Rule 1 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 2 (global) access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 3 (eth1) ! dmz -> intnet access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 4 (eth2) ! dmz -> intnet access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 5 (eth1,eth2) ! dmz -> intnet ! firewall20:Policy:5: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list inside_acl_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_acl_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 6 (eth0,eth1) access-list outside_acl_in deny ip host 10.5.70.20 any log 0 interval 300 access-list outside_acl_in deny ip host 192.168.2.20 any log 0 interval 300 access-list outside_acl_in deny ip host 192.168.1.20 any log 0 interval 300 access-list outside_acl_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 access-list dmz_acl_in deny ip host 10.5.70.20 any log 0 interval 300 access-list dmz_acl_in deny ip host 192.168.2.20 any log 0 interval 300 access-list dmz_acl_in deny ip host 192.168.1.20 any log 0 interval 300 access-list dmz_acl_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 7 (eth0,eth1) ! firewall20:Policy:7: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list dmz_acl_in permit ip 192.168.2.0 255.255.255.0 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 8 (global) access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id4528A51F20039.0 permit ip 192.168.1.0 255.255.255.0 any nat (inside) 1 access-list id4528A51F20039.0 0 0 ! ! Rule 1 (NAT) access-list id4528A54A20039.0 permit ip 192.168.2.0 255.255.255.0 any nat (dmz) 1 access-list id4528A54A20039.0 0 0 ! ! Rule 2 (NAT) access-list id4528A55820039.0 permit ip host 192.168.2.100 any static (dmz,outside) interface access-list id4528A55820039.0 0 0 ! ! Rule 3 (NAT) global (inside) 3 interface access-list id4528A56620039.0 permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0 nat (dmz) 3 access-list id4528A56620039.0 outside ! ! Rule 4 (NAT) global (dmz) 4 interface access-list id4528A57420039.0 permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 4 access-list id4528A57420039.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall91.fw.orig0000755000175000017500000001065711733011756022045 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.0.3557 ! ! Generated Wed Jul 6 17:49:22 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall91.fw ! ! testing new style ASA 8.3 nat commands ! DNAT rules ! N firewall91:NAT:8: error: Can not translate multiple services into one service in one rule. ! N firewall91:NAT:9: error: Translated service should be 'Original' or should contain single object. ! N firewall91:NAT:13: error: Oiginal destination can not be "any" in rules that translate destination ! N firewall91:NAT:14: error: Oiginal destination can not be "any" in rules that translate destination ! N firewall91:NAT:15: error: Oiginal destination can not be "any" in rules that translate destination ! N firewall91:NAT:16: error: Oiginal destination can not be "any" in rules that translate destination ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif inside security-level 100 exit interface FastEthernet1 nameif outside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object object service http.0 service tcp destination eq 80 exit object service https.0 service tcp destination eq 443 exit object service squid.0 service tcp destination eq 3128 exit object network external_gw2.0 host 22.22.22.100 exit object network hostA:eth0.0 host 192.168.1.10 exit object network internal_subnet_1.0 subnet 192.168.1.0 255.255.255.192 exit object network test_range_1.0 range 192.168.1.11 192.168.1.15 exit object network outside_range.0 range 22.22.22.21 22.22.22.25 exit ! ! Rule 0 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 description "0 (NAT)" ! ! Rule 1 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 description "1 (NAT)" ! ! Rule 2 (NAT) nat (outside,inside) source static any any destination static external_gw2.0 hostA:eth0.0 description "2 (NAT)" ! ! Rule 3 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 http.0 description "3 (NAT)" ! ! Rule 4 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 http.0 description "4 (NAT)" ! ! Rule 5 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 squid.0 description "5 (NAT)" ! ! Rule 6 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service https.0 https.0 description "6 (NAT)" ! ! Rule 7 (NAT) nat (outside,inside) source static any any destination static interface hostA:eth0.0 service http.0 http.0 description "7 (NAT)" ! ! Rule 10 (NAT) ! for #1941 nat (outside,inside) source static any any destination static outside_range.0 hostA:eth0.0 description "10 (NAT)" ! ! Rule 11 (NAT) ! for #1941 nat (inside,outside) source dynamic internal_subnet_1.0 interface destination static outside_range.0 hostA:eth0.0 description "11 (NAT)" ! ! Rule 12 (NAT) ! translating one range into another. nat (outside,inside) source static any any destination static outside_range.0 test_range_1.0 description "12 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall50.fw.orig0000755000175000017500000003636411733011756022043 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:08 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall50.fw ! ! this is simple firewall with two interfaces. Test regular policy rules, including IP_fragments rule. PIX 7.0 ! C firewall50:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall50:Policy:9: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! C firewall50:Policy:15: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule ! C firewall50:Policy:29: error: PIX does not support checking for IP options in ACLs. ! ! Prolog script: ! ! ! End of prolog script: ! hostname firewall50 interface ethernet1 nameif outside security-level 0 exit interface ethernet0 nameif inside security-level 100 exit interface ethernet2 nameif dmz security-level 50 exit logging host inside 192.168.1.30 logging queue 512 logging facility 16 logging trap 0 no logging buffered no logging console no logging timestamp logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 clear config ssh aaa authentication ssh console LOCAL ssh timeout 5 clear config snmp-server snmp-server community public snmp-server enable traps snmp-server host inside 192.168.1.20 poll snmp-server host inside 192.168.1.22 trap clear config ntp ntp server 192.168.1.20 source inside prefer no service resetinbound no service resetoutside sysopt connection tcpmss 1380 sysopt connection timewait sysopt nodnsalias inbound sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect ils inspect rsh inspect rtsp inspect sip inspect skinny inspect esmtp inspect sqlnet service-policy global_policy global !################ clear config access-list tmp_acl access-list tmp_acl permit ip 192.168.1.0 255.255.255.0 any access-list tmp_acl deny ip any any access-group tmp_acl in interface outside access-group tmp_acl in interface inside access-group tmp_acl in interface dmz clear xlate clear config static clear config global clear config nat clear config access-list dmz_acl_in clear config access-list inside_acl_in clear config access-list outside_acl_in clear config icmp clear config telnet clear config object-group clear config object object-group network id45142FA628543.dst.net.0 network-object host 211.11.11.11 network-object host 211.22.22.22 exit object-group service id45142FA628543.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 22 port-object eq 540 exit object-group icmp-type id45142FCB28543.srv.icmp.0 icmp-object 3 icmp-object 0 icmp-object 11 exit object-group service id45142FD728543.srv.tcp.0 tcp port-object eq 70 port-object eq 6667 port-object eq 3128 port-object eq 23 exit object-group service id45142FD728543.srv.udp.0 udp port-object eq 53 port-object eq 161 exit object-group network id45142FFC28543.dst.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit object-group network id4514300A28543.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id4514301628543.dst.net.0 network-object 192.168.1.250 255.255.255.254 network-object 192.168.1.252 255.255.255.252 exit object-group network id4514302F28543.dst.net.0 network-object host 192.168.1.11 network-object host 192.168.1.12 network-object host 192.168.1.13 network-object host 192.168.1.14 network-object host 192.168.1.15 exit object-group service id4514302F28543.srv.tcp.0 tcp port-object eq 113 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 25 port-object eq 3128 port-object eq 22 port-object eq 540 exit object-group network id4514303C28543.dst.net.0 network-object 192.168.1.11 255.255.255.255 network-object 192.168.1.12 255.255.255.252 exit object-group service id4514304928543.srv.tcp.0 tcp port-object eq 113 port-object eq 13 port-object eq 53 port-object eq 2105 port-object eq 21 port-object eq 70 port-object eq 80 port-object eq 443 port-object eq 143 port-object eq 993 port-object eq 6667 port-object eq 6667 port-object eq 543 port-object eq 544 port-object eq 389 port-object eq 98 port-object eq 3306 port-object eq 2049 port-object eq 119 port-object eq 110 port-object eq 5432 port-object eq 515 port-object eq 26000 port-object eq 512 port-object eq 513 port-object eq 514 port-object eq 4321 port-object eq 25 port-object eq 465 port-object eq 1080 port-object eq 3128 port-object eq 22 port-object eq 111 port-object eq 23 port-object range 10000 11000 port-object eq 540 port-object eq 7100 exit ! ! Rule 2 (ethernet1) icmp permit any 3 outside access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list outside_acl_in permit icmp any any 3 ! ! Rule 3 (ethernet1) ! anti-spoofing rule ! firewall50:Policy:3: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 4 (ethernet0) ssh 192.168.1.0 255.255.255.0 inside ! ! Rule 5 (ethernet0) access-list inside_acl_in permit tcp any object-group id45142FA628543.dst.net.0 object-group id45142FA628543.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id45142FA628543.dst.net.0 object-group id45142FA628543.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id45142FA628543.dst.net.0 object-group id45142FA628543.srv.tcp.0 ! ! Rule 6 (ethernet0) access-list inside_acl_in deny ip any host 192.168.1.255 ! ! Rule 8 (global) access-list dmz_acl_in permit tcp host 192.168.2.10 host 192.168.1.10 eq 22 ! ! Rule 9 (ethernet2,ethernet0) ! firewall50:Policy:9: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in permit tcp host 192.168.2.10 host 192.168.1.10 eq 22 access-list dmz_acl_in permit tcp host 192.168.2.10 host 192.168.1.10 eq 22 access-list dmz_acl_in permit tcp host 192.168.2.10 host 192.168.1.10 eq 22 ! ! Rule 10 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id45142FCB28543.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id45142FCB28543.srv.icmp.0 access-list dmz_acl_in permit icmp any host 192.168.1.10 object-group id45142FCB28543.srv.icmp.0 ! ! Rule 11 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 access-list inside_acl_in permit icmp any host 192.168.1.10 access-list dmz_acl_in permit icmp any host 192.168.1.10 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id45142FD728543.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id45142FD728543.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group id45142FD728543.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group id45142FD728543.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group id45142FD728543.srv.udp.0 access-list dmz_acl_in permit udp any host 192.168.1.10 object-group id45142FD728543.srv.udp.0 access-list outside_acl_in permit 47 any host 192.168.1.10 access-list inside_acl_in permit 47 any host 192.168.1.10 access-list dmz_acl_in permit 47 any host 192.168.1.10 ! ! Rule 12 (global) access-list outside_acl_in permit icmp any host 22.22.22.22 3 log 0 interval 300 icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 log 0 interval 300 icmp permit any 3 dmz access-list dmz_acl_in permit icmp any host 192.168.2.1 3 log 0 interval 300 access-list outside_acl_in permit icmp any any 3 log 0 interval 300 access-list inside_acl_in permit icmp any any 3 log 0 interval 300 access-list dmz_acl_in permit icmp any any 3 log 0 interval 300 access-list outside_acl_in permit 47 any any log 0 interval 300 access-list inside_acl_in permit 47 any any log 0 interval 300 access-list dmz_acl_in permit 47 any any log 0 interval 300 access-list outside_acl_in permit 50 any any log 0 interval 300 access-list inside_acl_in permit 50 any any log 0 interval 300 access-list dmz_acl_in permit 50 any any log 0 interval 300 ! ! Rule 14 (global) access-list outside_acl_in permit ip object-group id45142FA628543.dst.net.0 object-group id45142FFC28543.dst.net.0 ! ! Rule 15 (global) ! firewall50:Policy:15: warning: MAC address matching is not supported. One or several MAC addresses removed from source in the rule access-list inside_acl_in permit tcp host 192.168.1.10 object-group id4514300A28543.dst.net.0 eq 3128 ! ! Rule 16 (global) access-list outside_acl_in permit tcp any object-group id4514301628543.dst.net.0 eq 3128 access-list inside_acl_in permit tcp any object-group id4514301628543.dst.net.0 eq 3128 access-list dmz_acl_in permit tcp any object-group id4514301628543.dst.net.0 eq 3128 ! ! Rule 17 (global) ssh 0.0.0.0 0.0.0.0 outside ssh 0.0.0.0 0.0.0.0 inside ssh 0.0.0.0 0.0.0.0 dmz access-list outside_acl_in permit icmp any host 22.22.22.22 3 access-list inside_acl_in permit icmp any host 192.168.1.1 3 access-list dmz_acl_in permit icmp any host 192.168.2.1 3 ! ! Rule 18 (global) access-list outside_acl_in permit tcp any object-group id4514302F28543.dst.net.0 object-group id4514302F28543.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id4514302F28543.dst.net.0 object-group id4514302F28543.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id4514302F28543.dst.net.0 object-group id4514302F28543.srv.tcp.0 ! ! Rule 19 (global) access-list outside_acl_in permit tcp any object-group id4514303C28543.dst.net.0 object-group id4514302F28543.srv.tcp.0 access-list inside_acl_in permit tcp any object-group id4514303C28543.dst.net.0 object-group id4514302F28543.srv.tcp.0 access-list dmz_acl_in permit tcp any object-group id4514303C28543.dst.net.0 object-group id4514302F28543.srv.tcp.0 ! ! Rule 20 (global) access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id4514304928543.srv.tcp.0 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id4514304928543.srv.tcp.0 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 object-group id4514304928543.srv.tcp.0 ! ! Rule 21 (global) ! objects hostA and hostB are ! redundant and should be removed by ! removeRedundantAddressesFromDst access-list outside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list inside_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 access-list dmz_acl_in permit tcp any 192.168.1.0 255.255.255.0 eq 1494 ! ! Rule 22 (global) access-list outside_acl_in permit udp any range 10000 10010 host 192.168.1.10 access-list inside_acl_in permit udp any range 10000 10010 host 192.168.1.10 access-list dmz_acl_in permit udp any range 10000 10010 host 192.168.1.10 access-list outside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list inside_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list dmz_acl_in permit tcp any gt 1023 host 192.168.1.10 eq 80 access-list outside_acl_in permit tcp any range 20000 20020 host 192.168.1.10 access-list inside_acl_in permit tcp any range 20000 20020 host 192.168.1.10 access-list dmz_acl_in permit tcp any range 20000 20020 host 192.168.1.10 ! ! Rule 25 (global) access-list outside_acl_in permit ip host 22.22.22.22 host 22.22.22.22 log 0 interval 300 access-list inside_acl_in permit ip host 192.168.1.1 host 192.168.1.1 log 0 interval 300 access-list dmz_acl_in permit ip host 192.168.2.1 host 192.168.2.1 log 0 interval 300 ! ! Rule 26 (global) access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 27 (global) access-list outside_acl_in permit ip host 22.22.22.22 any access-list inside_acl_in permit ip host 192.168.1.1 any access-list dmz_acl_in permit ip host 192.168.2.1 any access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 28 (global) access-list outside_acl_in deny ip any any log 0 interval 300 access-list inside_acl_in deny ip any any log 0 interval 300 access-list dmz_acl_in deny ip any any log 0 interval 300 access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface clear config access-list id451430AE28543.0 access-list id451430AE28543.0 permit ip 192.168.1.0 255.255.255.0 any nat (inside) 1 access-list id451430AE28543.0 tcp 0 0 global (dmz) 1 interface ! ! ! Rule 1 (NAT) nat (dmz) 1 0.0.0.0 0.0.0.0 tcp 0 0 ! ! Rule 2 (NAT) nat (inside) 1 0.0.0.0 0.0.0.0 tcp 0 0 ! ! ! Rule 3 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 4 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! Rule 5 (NAT) clear config access-list id451430F428543.0 access-list id451430F428543.0 permit tcp host 192.168.1.10 eq 25 any static (inside,outside) tcp interface 25 access-list id451430F428543.0 tcp 0 0 ! ! Rule 6 (NAT) clear config access-list id47B71DF021818.0 access-list id47B71DF021818.0 permit tcp host 192.168.1.10 eq 25 any ! ! Rule 7 (NAT) access-list id47B71DF021818.0 permit tcp host 192.168.1.10 eq 25 any ! ! Rule 8 (NAT) access-list id47B71DF021818.0 permit tcp host 192.168.1.10 eq 25 any static (inside,outside) tcp interface 2525 access-list id47B71DF021818.0 tcp 0 0 ! ! Rule 9 (NAT) global (inside) 8 interface clear config access-list id4514310228543.0 access-list id4514310228543.0 permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0 nat (dmz) 8 access-list id4514310228543.0 outside ! ! Rule 10 (NAT) clear config access-list nat0.inside access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 11 (NAT) access-list nat0.inside permit ip host 192.168.1.11 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.12 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.13 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.14 192.168.2.0 255.255.255.0 access-list nat0.inside permit ip host 192.168.1.15 192.168.2.0 255.255.255.0 ! ! Rule 12 (NAT) nat (dmz) 0 0 0 ! ! Rule 13 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 14 (NAT) static (inside,dmz) 192.168.1.10 192.168.1.10 netmask 255.255.255.255 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/pix515.fw.orig0000755000175000017500000001032211733011756021106 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:16 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * pix515.fw ! ! Similar to fw 1, but the firewall is used as DHCP and DNS server for internal network. ! This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside. ! Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall can send DNS queries to servers out on the Internet. Another rule permits DNS queries from internal network to the firewall. Special rules permit DHCP requests from internal network and replies sent by the firewall. ! ! Prolog script: ! ! ! End of prolog script: ! interface ethernet0 nameif outside security-level 0 exit interface ethernet1 nameif inside security-level 100 exit logging buffered 6 no logging console logging timestamp logging on logging device-id hostname timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global !################ clear config access-list tmp_acl access-list tmp_acl permit ip 10.3.14.42 255.255.255.255 any access-list tmp_acl deny ip any any access-group tmp_acl in interface outside access-group tmp_acl in interface inside clear xlate clear config static clear config global clear config nat clear config access-list inside_acl_in clear config access-list outside_acl_in clear config icmp clear config telnet ! ! Rule -1 backup ssh access rule (automatic) ssh 10.3.14.42 255.255.255.255 inside ! ! Rule 0 (global) ssh 10.3.14.0 255.255.255.0 inside access-list inside_acl_in remark 0 (global) access-list inside_acl_in permit tcp 10.3.14.0 255.255.255.0 host 10.3.14.206 eq 53 access-list inside_acl_in permit udp 10.3.14.0 255.255.255.0 host 10.3.14.206 eq 53 ! ! Rule 1 (global) access-list outside_acl_in remark 1 (global) access-list outside_acl_in permit tcp any host 192.168.1.1 eq 2525 access-list outside_acl_in permit tcp any host 10.3.14.50 eq 25 access-list inside_acl_in remark 1 (global) access-list inside_acl_in permit tcp any host 10.3.14.50 eq 25 ! ! Rule 3 (global) access-list outside_acl_in remark 3 (global) access-list outside_acl_in permit ip host 192.168.1.1 any access-list inside_acl_in remark 3 (global) access-list inside_acl_in permit ip host 10.3.14.206 any ! ! Rule 4 (global) access-list inside_acl_in remark 4 (global) access-list inside_acl_in permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 5 (global) access-list outside_acl_in remark 5 (global) access-list outside_acl_in deny ip any any log 6 interval 300 access-list inside_acl_in remark 5 (global) access-list inside_acl_in deny ip any any log 6 interval 300 access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface clear config access-list id47B7A71421818.0 access-list id47B7A71421818.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id47B7A71421818.0 tcp 0 0 ! ! Rule 1 (NAT) clear config access-list id47B7C22E21818.0 access-list id47B7C22E21818.0 permit tcp host 10.3.14.50 eq 25 any static (inside,outside) tcp interface 2525 access-list id47B7C22E21818.0 tcp 0 0 ! ! Rule 0 (main) ! ! "Routing rule 0 (main)" ! ! The default metric on PIX is 1, so the GUI default value of 0 becomes 1 in ! the compiled rules. ! route inside 192.168.10.0 255.255.255.0 10.3.14.254 1 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall80.fw.orig0000755000175000017500000001301211733011756022027 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:09 2011 PDT by vadim ! ! Compiled for pix 8.2 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall80.fw ! ! testing rules with broadcasts ! N firewall80:NAT:0: error: CustomService objects are not supported in NAT rules ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif outside security-level 100 exit interface FastEthernet1 nameif inside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config static clear config global clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object-group icmp-type id19186X29796.srv.icmp.0 icmp-object 0 icmp-object 8 exit object-group service id19186X29796.srv.tcp.0 tcp port-object eq 53 port-object eq 25 exit object-group service id19186X29796.srv.udp.0 udp port-object eq 53 port-object eq 123 exit object-group icmp-type id21447X11252.srv.icmp.0 icmp-object 3 icmp-object 8 exit ! ! Rule 0 (FastEthernet1) ssh 0.0.0.0 0.0.0.0 inside ! ! Rule 1 (FastEthernet1) access-list inside_acl_in permit tcp any host 22.22.22.22 eq 22 ! ! Rule 2 (global) access-list outside_acl_in permit tcp any host 192.168.1.10 eq 22 access-list inside_acl_in permit tcp any host 192.168.1.10 eq 22 ! ! Rule 3 (FastEthernet1) icmp permit any 3 inside access-list inside_acl_in permit icmp any host 192.168.1.1 3 ! ! Rule 4 (global) access-list outside_acl_in permit icmp any host 192.168.1.10 object-group id19186X29796.srv.icmp.0 access-list inside_acl_in permit icmp any host 192.168.1.10 object-group id19186X29796.srv.icmp.0 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id19186X29796.srv.tcp.0 access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id19186X29796.srv.tcp.0 access-list outside_acl_in permit udp any host 192.168.1.10 object-group id19186X29796.srv.udp.0 access-list inside_acl_in permit udp any host 192.168.1.10 object-group id19186X29796.srv.udp.0 access-list outside_acl_in permit 50 any host 192.168.1.10 access-list inside_acl_in permit 50 any host 192.168.1.10 access-list outside_acl_in permit 51 any host 192.168.1.10 access-list inside_acl_in permit 51 any host 192.168.1.10 ! ! Rule 5 (global) ! matching source ports access-list outside_acl_in deny udp any range 10000 10010 host 192.168.1.10 access-list inside_acl_in deny udp any range 10000 10010 host 192.168.1.10 access-list outside_acl_in deny tcp any gt 1023 host 192.168.1.10 eq 80 access-list inside_acl_in deny tcp any gt 1023 host 192.168.1.10 eq 80 ! ! Rule 6 (global) access-list outside_acl_in deny tcp any range 20000 20020 host 192.168.1.10 access-list inside_acl_in deny tcp any range 20000 20020 host 192.168.1.10 access-list outside_acl_in deny tcp any range 30000 30030 host 192.168.1.10 access-list inside_acl_in deny tcp any range 30000 30030 host 192.168.1.10 ! ! Rule 7 (global) ! matching "any" icmp and "all" tcp ! in one service-group ! access-list outside_acl_in deny icmp any host 192.168.1.10 access-list inside_acl_in deny icmp any host 192.168.1.10 access-list outside_acl_in deny tcp any host 192.168.1.10 access-list inside_acl_in deny tcp any host 192.168.1.10 ! ! Rule 8 (global) ! for #1938 matching ! mixed services icmp permit 192.168.1.0 255.255.255.192 3 inside icmp permit 192.168.1.0 255.255.255.192 8 inside access-list inside_acl_in permit icmp 192.168.1.0 255.255.255.192 host 192.168.1.1 object-group id21447X11252.srv.icmp.0 access-list inside_acl_in permit icmp 192.168.1.0 255.255.255.192 any object-group id21447X11252.srv.icmp.0 access-list inside_acl_in permit tcp 192.168.1.0 255.255.255.192 any eq 3128 access-list inside_acl_in permit udp 192.168.1.0 255.255.255.192 any eq 53 ! ! Rule 9 (global) ! for #1942 ! using custom service access-list outside_acl_in deny tcp any host 192.168.1.10 neq 8080 access-list inside_acl_in deny tcp any host 192.168.1.10 neq 8080 ! ! Rule 10 (global) ! for #1942 ! using custom service access-list outside_acl_in deny tcp any host 192.168.1.10 neq 8080 access-list inside_acl_in deny tcp any host 192.168.1.10 neq 8080 access-list outside_acl_in deny tcp any host 192.168.1.10 eq 3128 access-list inside_acl_in deny tcp any host 192.168.1.10 eq 3128 ! ! Rule 11 (global) access-list outside_acl_in deny ip any any access-list inside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall22.fw.orig0000755000175000017500000001701211733011756022027 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:06 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: yes ! Assume firewall is part of any: no ! !# files: * firewall22.fw ! ! testing outbound ACLs ! v7.0, outbound ACLs are supported ! option 'generate outbound acls' is ON ! ! Prolog script: ! no sysopt connection timewait no sysopt security fragguard no sysopt nodnsalias inbound no sysopt nodnsalias outbound ! ! End of prolog script: ! interface eth0 nameif outside security-level 0 exit interface eth1 nameif dmz security-level 50 exit interface eth2 nameif inside security-level 100 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:2:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute telnet timeout 5 aaa authentication ssh console LOCAL ssh timeout 5 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default inspect ftp service-policy global_policy global !################ ! ! Rule 0 (global) access-list outside_in permit ip any host 192.168.1.10 access-list dmz_in permit ip any host 192.168.1.10 access-list inside_in permit ip any host 192.168.1.10 access-list inside_out permit ip any host 192.168.1.10 ! ! Rule 1 (global) access-list outside_in permit ip any host 192.168.1.10 access-list dmz_in permit ip any host 192.168.1.10 access-list inside_in permit ip any host 192.168.1.10 ! ! Rule 2 (global) access-list outside_out permit ip any host 192.168.1.10 access-list dmz_out permit ip any host 192.168.1.10 access-list inside_out permit ip any host 192.168.1.10 ! ! Rule 3 (global) access-list inside_in permit ip 192.168.1.0 255.255.255.0 any access-list outside_out permit ip 192.168.1.0 255.255.255.0 any access-list dmz_out permit ip 192.168.1.0 255.255.255.0 any access-list inside_out permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 4 (global) access-list outside_in permit ip 192.168.1.0 255.255.255.0 any access-list dmz_in permit ip 192.168.1.0 255.255.255.0 any access-list inside_in permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 5 (global) access-list outside_out permit ip 192.168.1.0 255.255.255.0 any access-list dmz_out permit ip 192.168.1.0 255.255.255.0 any access-list inside_out permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 6 (global) access-list dmz_in permit ip 192.168.2.0 255.255.255.0 any access-list outside_out permit ip 192.168.2.0 255.255.255.0 any access-list dmz_out permit ip 192.168.2.0 255.255.255.0 any access-list inside_out permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 7 (global) access-list outside_in permit ip 192.168.2.0 255.255.255.0 any access-list dmz_in permit ip 192.168.2.0 255.255.255.0 any access-list inside_in permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 8 (global) access-list outside_out permit ip 192.168.2.0 255.255.255.0 any access-list dmz_out permit ip 192.168.2.0 255.255.255.0 any access-list inside_out permit ip 192.168.2.0 255.255.255.0 any ! ! Rule 9 (global) access-list dmz_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 access-list inside_out permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 10 (global) access-list outside_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 access-list dmz_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 access-list inside_in permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 11 (global) access-list outside_out permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 access-list dmz_out permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 access-list inside_out permit ip 192.168.2.0 255.255.255.0 host 192.168.1.10 ! ! Rule 12 (eth1) ! dmz -> intnet access-list dmz_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_out permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 13 (eth1) ! dmz -> intnet access-list dmz_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 14 (eth1) ! dmz -> intnet access-list dmz_out permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 15 (eth2) ! dmz -> intnet access-list inside_in permit ip host 192.168.2.23 host 192.168.1.10 access-list inside_out permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 16 (eth2) ! dmz -> intnet access-list inside_in permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 17 (eth2) ! dmz -> intnet access-list inside_out permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 18 (eth1,eth2) ! dmz -> intnet access-list dmz_in permit ip host 192.168.2.23 host 192.168.1.10 access-list dmz_out permit ip host 192.168.2.23 host 192.168.1.10 access-list inside_in permit ip host 192.168.2.23 host 192.168.1.10 access-list inside_out permit ip host 192.168.2.23 host 192.168.1.10 ! ! Rule 19 (eth0,eth1) access-list outside_in deny ip host 10.5.70.20 any log 0 interval 300 access-list outside_in deny ip host 192.168.2.20 any log 0 interval 300 access-list outside_in deny ip host 192.168.1.20 any log 0 interval 300 access-list outside_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 access-list dmz_in deny ip host 10.5.70.20 any log 0 interval 300 access-list dmz_in deny ip host 192.168.2.20 any log 0 interval 300 access-list dmz_in deny ip host 192.168.1.20 any log 0 interval 300 access-list dmz_in deny ip 192.168.1.0 255.255.255.0 any log 0 interval 300 ! ! Rule 20 (eth0,eth1) access-list outside_out permit ip host 10.5.70.20 any access-list outside_out permit ip 192.168.2.0 255.255.255.0 any access-list outside_out permit ip 192.168.1.0 255.255.255.0 any access-list dmz_out permit ip host 192.168.2.20 any access-list dmz_out permit ip 192.168.2.0 255.255.255.0 any access-list dmz_out permit ip 192.168.1.0 255.255.255.0 any ! ! Rule 21 (global) access-list outside_in deny ip any any access-list dmz_in deny ip any any access-list inside_in deny ip any any access-list outside_out deny ip any any access-list dmz_out deny ip any any access-list inside_out deny ip any any access-group dmz_in in interface dmz access-group dmz_out out interface dmz access-group inside_in in interface inside access-group inside_out out interface inside access-group outside_in in interface outside access-group outside_out out interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id4529E45516799.0 permit ip 192.168.1.0 255.255.255.0 any nat (inside) 1 access-list id4529E45516799.0 tcp 0 0 ! ! Rule 1 (NAT) access-list id4529E46316799.0 permit ip 192.168.2.0 255.255.255.0 any nat (dmz) 1 access-list id4529E46316799.0 tcp 0 0 ! ! Rule 2 (NAT) access-list id4529E47116799.0 permit ip host 192.168.2.100 any static (dmz,outside) interface access-list id4529E47116799.0 tcp 0 0 ! ! Rule 3 (NAT) global (inside) 3 interface access-list id4529E47F16799.0 permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0 nat (dmz) 3 access-list id4529E47F16799.0 outside ! ! Rule 4 (NAT) global (dmz) 4 interface access-list id4529E48D16799.0 permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 4 access-list id4529E48D16799.0 tcp 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall83.fw.orig0000755000175000017500000000542711733011756022045 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:11 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall83.fw ! ! test for the warning issued when translated address is used in ! policy rule. Here we have SNAT rule and warning should not be issued ! ! Prolog script: ! ! ! End of prolog script: ! interface FastEthernet0 nameif inside security-level 100 exit interface FastEthernet1 nameif outside security-level 0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 3:0:0 timeout conn 1:0:0 timeout udp 0:2:0 timeout sunrpc 0:10:0 timeout h323 0:5:0 timeout sip 0:30:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 2:0:0 absolute clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global policy-map type inspect ip-options ip-options-map parameters eool action allow router-alert action clear !################ clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object object service http.0 service tcp destination eq 80 exit object network hostA:eth0.0 host 192.168.1.10 exit ! ! Rule 0 (global) ! matching "any" icmp and "all" tcp ! in one service-group ! access-list inside_acl_in deny icmp any object hostA:eth0.0 access-list outside_acl_in deny icmp any object hostA:eth0.0 access-list inside_acl_in deny tcp any object hostA:eth0.0 access-list outside_acl_in deny tcp any object hostA:eth0.0 ! ! Rule 1 (FastEthernet1) ! test rule using translated address in dst access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 ! ! Rule 2 (global) ! test rule using translated address in dst access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 ! ! Rule 3 (global) ! test rule using translated address in dst http 0.0.0.0 0.0.0.0 inside http 0.0.0.0 0.0.0.0 outside ! ! Rule 4 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) nat (inside,outside) source static hostA:eth0.0 interface service http.0 http.0 description "0 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/cluster1-1_pix1.fw.orig0000755000175000017500000001232711733011756022723 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:17 2011 PDT by vadim ! ! Compiled for pix 7.0 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: yes ! Assume firewall is part of any: yes ! !# files: * cluster1-1_pix1.fw ! ! ! pix1::: warning: Interface Ethernet0 has vlan subinterfaces, it can not be used for ACL. Marking this interface "unprotected" to exclude it. ! ! Prolog script: ! ! ! End of prolog script: ! hostname pix1 interface Ethernet1 nameif inside ip address 10.3.14.206 255.255.255.0 standby 10.3.14.207 security-level 100 exit interface Ethernet0 no nameif no ip address no security-level exit interface Ethernet2 description LAN/STATE Failover Interface no nameif exit interface Ethernet0.101 vlan 101 nameif outside ip address 192.0.2.253 255.255.255.0 standby 192.0.2.254 security-level 0 exit interface Ethernet0.102 vlan 102 nameif dmz20 ip address 10.0.0.253 255.255.255.0 standby 10.0.0.254 security-level 20 exit failover lan unit primary failover lan interface failover Ethernet2 failover lan enable failover key super_secret failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover link failover Ethernet2 failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 failover no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global !################ clear xlate clear config static clear config global clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object-group network id56590X61097.src.net.0 network-object host 10.3.14.206 network-object host 10.3.14.207 exit object-group network id56590X61097.src.net.1 network-object host 172.17.1.253 network-object host 172.17.1.254 network-object host 192.0.2.253 network-object host 192.0.2.254 exit object-group network id56590X61097.src.net.2 network-object host 10.0.0.253 network-object host 10.0.0.254 exit object-group network id56627X61097.src.net.0 network-object host 172.17.1.253 network-object host 192.0.2.253 exit ! ! Rule 0 (Ethernet0.101) ! anti spoofing rule access-list outside_in deny ip object-group id56590X61097.src.net.0 any log 2 interval 300 access-list outside_in deny ip object-group id56590X61097.src.net.1 any log 2 interval 300 access-list outside_in deny ip object-group id56590X61097.src.net.2 any log 2 interval 300 access-list outside_in deny ip 10.3.14.0 255.255.255.0 any log 2 interval 300 ! ! Rule 1 (global) ! SSH Access to firewall is permitted ! only from internal network ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 2 (global) ssh 10.3.14.0 255.255.255.0 inside ! ! Rule 3 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp host 10.3.14.206 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp object-group id56627X61097.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp host 10.0.0.253 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 ! ! Rule 4 (global) ! Firewall uses one of the machines ! on internal network for DNS access-list inside_out permit udp object-group id56590X61097.src.net.0 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp object-group id56590X61097.src.net.1 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 access-list inside_out permit udp object-group id56590X61097.src.net.2 10.3.14.0 255.255.255.0 eq 53 log 2 interval 300 ! ! Rule 5 (global) ! All other attempts to connect to ! the firewall are denied and logged access-list inside_in deny ip any object-group id56590X61097.src.net.0 log 2 interval 300 access-list inside_in deny ip any object-group id56590X61097.src.net.1 log 2 interval 300 access-list inside_in deny ip any object-group id56590X61097.src.net.2 log 2 interval 300 ! ! Rule 6 (global) access-list inside_in permit ip 10.3.14.0 255.255.255.0 any access-list inside_out permit ip 10.3.14.0 255.255.255.0 any ! ! Rule 7 (global) access-list inside_in deny ip any any log 2 interval 300 access-list inside_out deny ip any any log 2 interval 300 access-group inside_in in interface inside access-group inside_out out interface inside access-group outside_in in interface outside ! ! Rule 0 (NAT) global (outside) 1 interface access-list id56689X61097.0 permit ip 10.3.14.0 255.255.255.0 any nat (inside) 1 access-list id56689X61097.0 tcp 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/cluster-tests.fwb0000644000175000017500000051361311733011756022107 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/test/pix/firewall2.fw.orig0000755000175000017500000001440111733011756021744 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:04 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall2.fw ! ! lots of different combinations of objects in the NAT rules ! C firewall2:Policy:1: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0 inside security100 nameif eth1 outside security0 nameif eth2 dmz security50 no logging buffered no logging console no logging timestamp no logging on telnet timeout 5 clear ssh aaa authentication ssh console LOCAL ssh timeout 5 clear snmp-server no snmp-server enable traps clear ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable !################ clear xlate clear static clear global clear nat clear access-list clear icmp clear telnet clear object-group object-group service id3D6EF08C.srv.tcp.0 tcp port-object eq 80 port-object eq 119 exit object-group network id3D8FCCDE.src.net.0 network-object host 192.168.1.10 network-object host 192.168.1.20 exit ! ! Rule 0 (eth1) ! Anti-spoofing rule access-list outside_acl_in deny ip host 192.168.1.1 any log 6 interval 300 access-list outside_acl_in deny ip host 22.22.22.22 any log 6 interval 300 access-list outside_acl_in deny ip host 192.168.2.1 any log 6 interval 300 access-list outside_acl_in deny ip 192.168.1.0 255.255.255.0 any log 6 interval 300 ! ! Rule 1 (eth1) ! Anti-spoofing rule ! firewall2:Policy:1: warning: Rule with direction 'Outbound' was suppressed because generation of outbound access lists is turned off in firewall object settings access-list inside_acl_in deny ip 192.168.1.0 255.255.255.0 any log 6 interval 300 ! ! Rule 2 (global) access-list inside_acl_in permit tcp any host 192.168.1.10 object-group id3D6EF08C.srv.tcp.0 access-list outside_acl_in permit tcp any host 22.22.22.22 eq 80 access-list outside_acl_in permit tcp any host 22.22.22.22 eq 119 access-list outside_acl_in permit tcp any host 192.168.1.10 object-group id3D6EF08C.srv.tcp.0 access-list dmz_acl_in permit tcp any host 192.168.1.10 object-group id3D6EF08C.srv.tcp.0 ! ! Rule 3 (global) access-list inside_acl_in permit ip object-group id3D8FCCDE.src.net.0 host 200.200.200.200 ! ! Rule 4 (global) access-list outside_acl_in permit ip host 200.200.200.200 object-group id3D8FCCDE.src.net.0 ! ! Rule 6 (global) access-list inside_acl_in deny ip any any access-list outside_acl_in deny ip any any access-list dmz_acl_in deny ip any any access-group dmz_acl_in in interface dmz access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) access-list nat0.inside permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list nat0.inside ! ! Rule 1 (NAT) static (inside,dmz) 192.168.1.0 192.168.1.0 netmask 255.255.255.0 ! ! Rule 2 (NAT) global (outside) 1 interface access-list id3AFB66C8.0 permit ip 192.168.1.0 255.255.255.0 any global (dmz) 1 interface ! ! ! Rule 3 (NAT) access-list id3AFB66C8.0 permit ip host 192.168.1.10 any ! access-list id3AFB66C8.0 permit ip host 192.168.1.20 any ! ! ! Rule 4 (NAT) access-list id3AFB66C8.0 permit ip host 192.168.1.11 any ! access-list id3AFB66C8.0 permit ip 192.168.1.12 255.255.255.252 any ! ! ! Rule 5 (NAT) access-list id3D1C2292.0 permit ip 192.168.2.0 255.255.255.0 any nat (dmz) 1 access-list id3D1C2292.0 0 0 ! ! Rule 6 (NAT) ! ! ! Rule 7 (NAT) global (outside) 1 interface ! ! ! Rule 8 (NAT) ! ! ! Rule 9 (NAT) ! ! ! ! Rule 10 (NAT) global (outside) 1 22.22.22.0 netmask 255.255.255.0 ! ! ! Rule 11 (NAT) global (outside) 1 22.22.22.21-22.22.22.25 netmask 255.255.255.0 ! ! ! ! Rule 12 (NAT) global (dmz) 1 interface access-list id3D1C1104.0 permit ip host 192.168.1.10 192.168.2.0 255.255.255.0 ! ! Rule 13 (NAT) access-list id3D1C1D30.0 permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 1 access-list id3D1C1D30.0 0 0 ! ! Rule 14 (NAT) ! ! ! Rule 16 (NAT) access-list id3D1BFFA4.0 permit ip host 192.168.1.10 any static (inside,outside) interface access-list id3D1BFFA4.0 0 0 ! ! Rule 17 (NAT) access-list id3D1C0835.0 permit tcp host 192.168.1.10 eq 6667 any static (inside,outside) tcp interface 6667 access-list id3D1C0835.0 0 0 ! ! Rule 18 (NAT) access-list id16986X27842.0 permit tcp host 192.168.1.1 eq 6667 any static (inside,outside) tcp interface 6667 access-list id16986X27842.0 0 0 ! ! Rule 19 (NAT) access-list id414351C7.0 permit tcp host 192.168.1.10 eq 80 any ! ! Rule 20 (NAT) access-list id414351C7.0 permit tcp host 192.168.1.10 eq 80 any static (inside,outside) tcp interface 80 access-list id414351C7.0 0 0 ! ! Rule 21 (NAT) access-list id3AFB69BD.0 permit ip host 192.168.1.10 any static (inside,outside) interface access-list id3AFB69BD.0 0 0 ! ! Rule 22 (NAT) access-list id3D1BFFCE.0 permit ip 192.168.1.0 255.255.255.0 any static (inside,outside) 22.22.22.0 access-list id3D1BFFCE.0 0 0 ! ! Rule 24 (NAT) access-list id3D1BFFF6.0 permit ip host 192.168.1.10 192.168.2.0 255.255.255.0 static (inside,dmz) interface access-list id3D1BFFF6.0 0 0 ! ! Rule 25 (NAT) access-list id3BEEF6D2.0 permit tcp host 192.168.1.10 eq 119 any static (inside,outside) tcp interface 119 access-list id3BEEF6D2.0 0 0 ! ! Rule 27 (NAT) access-list id3B7313C4.0 permit tcp host 192.168.1.10 eq 3128 any static (inside,outside) tcp interface 80 access-list id3B7313C4.0 0 0 ! ! Rule 28 (NAT) access-list id47B6CF3421818.0 permit tcp host 192.168.1.10 eq 3128 any ! ! Rule 29 (NAT) access-list id36573X14603.0 permit tcp host 192.168.1.10 eq 3128 any static (inside,outside) tcp interface 80 access-list id36573X14603.0 0 0 ! ! Rule 30 (NAT) access-list id47B6CF3421818.0 permit tcp host 192.168.1.10 eq 3128 any static (inside,outside) tcp interface 80 access-list id47B6CF3421818.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall93.fw.orig0000755000175000017500000000375511733011756022050 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:13 2011 PDT by vadim ! ! Compiled for pix 8.3 ! Outbound ACLs: supported ! Emulate outbound ACLs: yes ! Generating outbound ACLs: no ! Assume firewall is part of any: yes ! !# files: * firewall93.fw ! ! test for #1949 ! split NAT rule by OSrc to make sure objects in OSrc match network zones of ! inetrfaces ! ! Prolog script: ! ! ! End of prolog script: ! interface Ethernet0/0 nameif outside security-level 0 exit interface Ethernet0/1 nameif inside security-level 100 exit interface Ethernet0/2 nameif dmz security-level 10 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:30 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global clear xlate clear config nat clear config object-group clear config object object network dmz-range-1.0 range 172.16.0.10 172.16.0.15 exit object network inside-range-1.0 range 10.0.0.1 10.0.0.5 exit object-group network id26270X5313.osrc.net.0 network-object object inside-range-1.0 exit object-group network id26270X5313.osrc.net.1 network-object object dmz-range-1.0 exit ! ! Rule 0 (NAT) nat (inside,outside) source dynamic id26270X5313.osrc.net.0 interface description "0 (NAT)" nat (dmz,outside) source dynamic id26270X5313.osrc.net.1 interface description "0 (NAT)" ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/pix/firewall33.fw.orig0000755000175000017500000001266711733011756022044 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v5.0.1.3581 ! ! Generated Wed Oct 19 16:51:07 2011 PDT by vadim ! ! Compiled for pix 6.3 ! Outbound ACLs: not supported ! Emulate outbound ACLs: no ! Generating outbound ACLs: no ! Assume firewall is part of any: no ! !# files: * firewall33.fw ! ! testing DNSName object ! C firewall33:Policy:3: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode ! C firewall33:Policy:4: error: Run-time AddressTable and DNSName objects are not supported. ! C firewall33:Policy:7: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode ! C firewall33:Policy:7: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode ! C firewall33:Policy:8: error: Run-time AddressTable and DNSName objects are not supported. ! N firewall33:NAT:1: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! N firewall33:NAT:1: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! N firewall33:NAT:1: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! N firewall33:NAT:1: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. ! N firewall33:NAT:2: error: Run-time AddressTable and DNSName objects are not supported. ! ! Prolog script: ! ! ! End of prolog script: ! nameif eth0.100 outside security0 nameif eth1 inside security100 no logging buffered no logging console no logging timestamp no logging on telnet timeout -1 aaa authentication ssh console LOCAL ssh timeout -1 no snmp-server enable traps no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound floodguard disable !################ object-group network id43867C2418346.src.net.0 network-object host 157.166.226.25 network-object host 157.166.226.26 network-object host 157.166.255.18 network-object host 157.166.255.19 exit object-group network id438728A918346.dst.net.0 network-object host 74.125.224.112 network-object host 74.125.224.113 network-object host 74.125.224.114 network-object host 74.125.224.115 network-object host 74.125.224.116 network-object host 157.166.226.25 network-object host 157.166.226.26 network-object host 157.166.255.18 network-object host 157.166.255.19 exit ! ! Rule 0 (eth0.100) access-list outside_acl_in deny ip 192.168.1.0 255.255.255.0 any ! ! Rule 1 (global) access-list outside_acl_in permit ip object-group id43867C2418346.src.net.0 any ! ! Rule 3 (global) ! firewall33:Policy:3: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode access-list outside_acl_in permit ip host 192.0.2.1 any ! ! Rule 5 (global) access-list outside_acl_in deny ip any object-group id43867C2418346.src.net.0 access-list inside_acl_in deny ip any object-group id43867C2418346.src.net.0 ! ! Rule 7 (global) ! firewall33:Policy:7: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode access-list outside_acl_in permit ip any host 192.0.2.1 access-list inside_acl_in permit ip any host 192.0.2.1 ! ! Rule 9 (global) access-list outside_acl_in permit ip any object-group id438728A918346.dst.net.0 access-list inside_acl_in permit ip any object-group id438728A918346.dst.net.0 ! ! Rule 11 (global) access-list outside_acl_in deny ip any any log 6 interval 300 access-list inside_acl_in deny ip any any log 6 interval 300 access-group inside_acl_in in interface inside access-group outside_acl_in in interface outside ! ! Rule 0 (NAT) access-list id43867C4918346.0 permit ip host 192.168.1.10 any static (inside,outside) interface access-list id43867C4918346.0 0 0 ! ! Rule 1 (NAT) ! firewall33:NAT:1: warning: Objects used in Original Source and Translated Source of the rule dictate that the same interface 'outside' is going to be used as real and mapped interface in the generated nat command. global (outside) 1 interface access-list id43876E2618346.0 permit ip any host 157.166.226.25 access-list id43876E2618346.0 permit ip any host 157.166.226.26 access-list id43876E2618346.0 permit ip any host 157.166.255.18 access-list id43876E2618346.0 permit ip any host 157.166.255.19 nat (outside) 1 access-list id43876E2618346.0 0 0 ! ! Epilog script: ! ! End of epilog script: ! fwbuilder-5.1.0.3599/test/ipt/0000755000175000017500000000000011733011756016551 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/ipt/firewall23-3.fw.orig0000755000175000017500000002214211733011756022164 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:27 2012 PDT by vadim # # files: * firewall23-3.fw /etc/fw/firewall23-3.fw # # Compiled for iptables 1.3.0 # # This is BRIDGING FIREWALL # with one bridge and wildcard bridge port interfaces. # Since there is only one bridge, there is no need to add -i br0 / -o br0 # see SF bug #3439613 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'filter', rule set Policy # # Rule 0 (vnet+) # echo "Rule 0 (vnet+)" # $IPTABLES -A INPUT -m physdev --physdev-in vnet+ -m state --state NEW -j ACCEPT # # Rule 1 (vnet+) # echo "Rule 1 (vnet+)" # # -o br0 $IPTABLES -A OUTPUT -m physdev --physdev-is-bridged --physdev-out vnet+ -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:27 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall15.fw.orig0000755000175000017500000002434511733011756022034 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:12 2012 PDT by vadim # # files: * firewall15.fw /etc/fw/firewall15.fw # # Compiled for iptables (any version) # # Testing "Accept TCP sessions opened prior to firewall restart flag" # in combination with "Assume firewall is part of any" - both # flags are OFF here FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 22.22.22.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (lo) # echo "Rule 0 (lo)" # # option 'assume firewall is part of any' # is off, but this rule should go into # INPUT/OUTPUT chains anyway $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A FORWARD -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:12 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall40-2.fw.orig0000755000175000017500000003050311733011756022162 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:52 2012 PDT by vadim # # files: * firewall40-2.fw /etc/firewall40-2.fw # # Compiled for iptables 1.4.0 # # more complex and realistic combination of Tag and Route rules that are in the separate Policy rule set. Here the top Policy rule set is empty # firewall40-2:Policy_1:3: error: Option Route is deprecated. You can use Custom Action to generate iptables command using '-j ROUTE' target if it is supported by your firewall OS # firewall40-2:Policy_1:4: error: Option Route is deprecated. You can use Custom Action to generate iptables command using '-j ROUTE' target if it is supported by your firewall OS FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 lo eth2 eth1" for i in eth0 lo eth2 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.0.100.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # Translate source address # for outgoing connections $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 # ================ Table 'mangle', rule set Policy_1 # # Rule Policy_1 0 (eth0) # echo "Rule Policy_1 0 (eth0)" # $IPTABLES -N Policy_1 -t mangle $IPTABLES -t mangle -A Policy_1 -i eth0 -m state --state NEW -j MARK --set-mark 1 $IPTABLES -t mangle -A Policy_1 -i eth0 -m state --state NEW -j CONNMARK --save-mark # # Rule Policy_1 1 (eth2) # echo "Rule Policy_1 1 (eth2)" # $IPTABLES -t mangle -A Policy_1 -i eth2 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A Policy_1 -i eth2 -m state --state NEW -j CONNMARK --save-mark # # Rule Policy_1 6 (global) # echo "Rule Policy_1 6 (global)" # $IPTABLES -N Cid55227X22068.0 -t mangle $IPTABLES -t mangle -A Policy_1 -s 192.168.1.0/24 -m state --state NEW -j Cid55227X22068.0 $IPTABLES -t mangle -A Cid55227X22068.0 -d 22.22.22.0/24 -j MARK --set-mark 8 $IPTABLES -t mangle -A Cid55227X22068.0 -d 33.33.33.0/24 -j MARK --set-mark 8 # ================ Table 'filter', rule set Policy_1 # # Rule Policy_1 2 (global) # echo "Rule Policy_1 2 (global)" # # This permits access from internal net # to the Internet and DMZ $IPTABLES -N Policy_1 $IPTABLES -A Policy_1 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule Policy_1 5 (global) # echo "Rule Policy_1 5 (global)" # $IPTABLES -N Policy_1_5 $IPTABLES -A Policy_1 -j Policy_1_5 $IPTABLES -A Policy_1_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -A Policy_1_5 -j DROP # # Rule Policy_1 6 (global) # echo "Rule Policy_1 6 (global)" # $IPTABLES -N Cid55227X22068.0 $IPTABLES -A Policy_1 -s 192.168.1.0/24 -m state --state NEW -j Cid55227X22068.0 $IPTABLES -A Cid55227X22068.0 -d 22.22.22.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " $IPTABLES -A Cid55227X22068.0 -d 33.33.33.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:52 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall16.fw.orig0000755000175000017500000003436011733011756022033 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:12 2012 PDT by vadim # # files: * firewall16.fw /etc/fw/firewall16.fw # # Compiled for iptables (any version) # # testing translation from outside to the web server on DMZ, need to see what happens if clients on internal net connect to the NATted address of this server. This is a kind of "NAT back to the same subnet" with a twist. # This firewall also has option "local NAT" enabled. NAT rules 0,2-7 should generate code in the OUTPUT and POSTROUTING chains. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # should generate code in both PREROUTING # and OUTPUT chain because option "local NAT" # is enabled $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.22 --dport 80 -j DNAT --to-destination 192.168.2.10:80 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.22 --dport 80 -j DNAT --to-destination 192.168.2.10:80 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 80 -j DNAT --to-destination 192.168.2.10:80 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.22 --dport 80 -j DNAT --to-destination 192.168.2.10:80 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.22 --dport 80 -j DNAT --to-destination 192.168.2.10:80 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.1 --dport 80 -j DNAT --to-destination 192.168.2.10:80 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:3128 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 8080 -j DNAT --to-destination 192.168.1.10:3128 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -s 192.168.2.1 --dport 8080 -j DNAT --to-destination 192.168.1.10:3128 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -s 192.168.2.1 --dport 8080 -j DNAT --to-destination 192.168.1.10:3128 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 22.22.23.22 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.22 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.2.1 -j SNAT --to-source 22.22.23.22 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 22.22.23.22 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.22 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.2.1 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.22 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.2.1 -j SNAT --to-source 22.22.23.22 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.2.1 -j SNAT --to-source 22.22.23.22 # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 22.22.23.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -j ACCEPT # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 22.22.23.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -j ACCEPT # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -s 192.168.2.1 -j ACCEPT # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -s 192.168.2.1 -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -j RULE_1 $IPTABLES -A INPUT -j RULE_1 $IPTABLES -A FORWARD -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:12 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall1.fw.orig0000755000175000017500000014024311733011756021743 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:07 2012 PDT by vadim # # files: * firewall1.fw /etc/fw/firewall1.fw # # Compiled for iptables (any version) # # this object is used to test all kinds of negation in policy and NAT rules. # Assume firewall is part of any is ON FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.0/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 22.22.22.23/24" "" update_addresses_of_interface "eth2 192.168.2.1/24 192.168.2.0/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth3 22.22.23.23/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s ! 192.168.1.0/24 -d 200.200.200.200 -j SNAT --to-source 22.22.22.23 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -s ! 192.168.1.0/24 -d 200.200.200.200 --dport 80 -j SNAT --to-source 22.22.22.23 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d ! 192.168.2.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -d ! 192.168.2.0/24 -j SNAT --to-source 22.22.23.23 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 -d ! 192.168.2.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 -d ! 192.168.2.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -N Cid3CCA1B57.0 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j Cid3CCA1B57.0 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j Cid3CCA1B57.0 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j Cid3CCA1B57.0 $IPTABLES -t nat -A Cid3CCA1B57.0 -d 192.168.1.0/24 -j RETURN $IPTABLES -t nat -A Cid3CCA1B57.0 -d 192.168.2.0/24 -j RETURN $IPTABLES -t nat -A Cid3CCA1B57.0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A Cid3CCA1B57.0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A Cid3CCA1B57.0 -j SNAT --to-source 192.168.2.1 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -N Cid3EB38983.0 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j Cid3EB38983.0 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j Cid3EB38983.0 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j Cid3EB38983.0 $IPTABLES -t nat -A Cid3EB38983.0 -d 192.168.1.0/24 -j RETURN $IPTABLES -t nat -A Cid3EB38983.0 -d 192.168.2.0/24 -j RETURN $IPTABLES -t nat -A Cid3EB38983.0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A Cid3EB38983.0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A Cid3EB38983.0 -j SNAT --to-source 192.168.2.1 # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s ! 192.168.2.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s ! 192.168.2.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth0 -s ! 192.168.2.0/24 -j SNAT --to-source 192.168.1.1 # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -N Cid3BD8D94B.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j Cid3BD8D94B.0 $IPTABLES -t nat -A Cid3BD8D94B.0 -d 22.22.22.22 -j RETURN $IPTABLES -t nat -A Cid3BD8D94B.0 -d 22.22.23.23 -j RETURN $IPTABLES -t nat -A Cid3BD8D94B.0 -d 192.168.1.1 -j RETURN $IPTABLES -t nat -A Cid3BD8D94B.0 -d 192.168.2.1 -j RETURN $IPTABLES -t nat -A Cid3BD8D94B.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -N Cid3BD8D9DD.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j Cid3BD8D9DD.0 $IPTABLES -t nat -A Cid3BD8D9DD.0 -d 192.168.1.1 -j RETURN $IPTABLES -t nat -A Cid3BD8D9DD.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -N Cid3BBC0EA4.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.10 --dport 80 -j Cid3BBC0EA4.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.20 --dport 80 -j Cid3BBC0EA4.0 $IPTABLES -t nat -A Cid3BBC0EA4.0 -d 192.168.1.0/24 -j RETURN $IPTABLES -t nat -A Cid3BBC0EA4.0 -d 192.168.2.0/24 -j RETURN $IPTABLES -t nat -A Cid3BBC0EA4.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # $IPTABLES -t nat -N Cid3BBC0F93.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.0/24 --dport 80 -j Cid3BBC0F93.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.0/24 --dport 80 -j Cid3BBC0F93.0 $IPTABLES -t nat -A Cid3BBC0F93.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid3BBC0F93.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid3BBC0F93.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 15 (NAT) # echo "Rule 15 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j REDIRECT --to-ports 3128 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.23 --dport 4000:4010 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 5000 -d 22.22.22.23 --dport 5000:5010 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 9000 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 6667,3128 -j DNAT --to-destination 192.168.1.10 # # Rule 17 (NAT) # echo "Rule 17 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.0/24 --dport 80 -j DNAT --to-destination :3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.0/24 --dport 80 -j DNAT --to-destination :3128 # # Rule 18 (NAT) # echo "Rule 18 (NAT)" # $IPTABLES -t nat -N Cid3EB38A91.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid3EB38A91.0 $IPTABLES -t nat -A Cid3EB38A91.0 -d 192.168.1.0/24 -j RETURN $IPTABLES -t nat -A Cid3EB38A91.0 -d 192.168.2.0/24 -j RETURN $IPTABLES -t nat -A Cid3EB38A91.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination :3128 # ================ Table 'filter', rule set GOOD_GUYS # # Rule GOOD_GUYS 0 (global) # echo "Rule GOOD_GUYS 0 (global)" # $IPTABLES -N GOOD_GUYS $IPTABLES -N Cid40710X74808.0 $IPTABLES -A GOOD_GUYS -j Cid40710X74808.0 $IPTABLES -A Cid40710X74808.0 -s 1.1.1.0/24 -j RETURN $IPTABLES -A Cid40710X74808.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -N GOOD_GUYS_0_3 $IPTABLES -A Cid40710X74808.0 -j GOOD_GUYS_0_3 $IPTABLES -A GOOD_GUYS_0_3 -j LOG --log-level debug $IPTABLES -A GOOD_GUYS_0_3 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -N Cid3C5987DC.1 $IPTABLES -A INPUT -i eth0 -s 22.22.22.22 -j Cid3C5987DC.1 $IPTABLES -N Cid3C5987DC.0 $IPTABLES -A Cid3C5987DC.1 -p icmp -j Cid3C5987DC.0 $IPTABLES -A Cid3C5987DC.1 -p 50 -j Cid3C5987DC.0 $IPTABLES -N Cid3C5987DC.2 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -j Cid3C5987DC.2 $IPTABLES -A Cid3C5987DC.2 -p icmp -j Cid3C5987DC.0 $IPTABLES -A Cid3C5987DC.2 -p 50 -j Cid3C5987DC.0 $IPTABLES -N Cid3C5987DC.3 $IPTABLES -A FORWARD -i eth0 -s 22.22.22.22 -j Cid3C5987DC.3 $IPTABLES -A Cid3C5987DC.3 -p icmp -j Cid3C5987DC.0 $IPTABLES -A Cid3C5987DC.3 -p 50 -j Cid3C5987DC.0 $IPTABLES -N Cid3C5987DC.4 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -j Cid3C5987DC.4 $IPTABLES -A Cid3C5987DC.4 -p icmp -j Cid3C5987DC.0 $IPTABLES -A Cid3C5987DC.4 -p 50 -j Cid3C5987DC.0 $IPTABLES -A Cid3C5987DC.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3C5987DC.0 -d 192.168.1.1 -j RETURN $IPTABLES -N In_RULE_0_3 $IPTABLES -A Cid3C5987DC.0 -m hashlimit --hashlimit 1/hour --hashlimit-burst 2 --hashlimit-mode srcip,srcport --hashlimit-name htable_rule_0 -j In_RULE_0_3 $IPTABLES -A In_RULE_0_3 -j LOG --log-level debug $IPTABLES -A In_RULE_0_3 -j DROP $IPTABLES -N Cid3C5987DC.6 $IPTABLES -A OUTPUT -o eth0 -s 22.22.22.22 -j Cid3C5987DC.6 $IPTABLES -N Cid3C5987DC.5 $IPTABLES -A Cid3C5987DC.6 -p icmp -j Cid3C5987DC.5 $IPTABLES -A Cid3C5987DC.6 -p 50 -j Cid3C5987DC.5 $IPTABLES -N Cid3C5987DC.7 $IPTABLES -A OUTPUT -o eth0 -s 192.168.1.1 -j Cid3C5987DC.7 $IPTABLES -A Cid3C5987DC.7 -p icmp -j Cid3C5987DC.5 $IPTABLES -A Cid3C5987DC.7 -p 50 -j Cid3C5987DC.5 $IPTABLES -A Cid3C5987DC.5 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3C5987DC.5 -d 192.168.1.1 -j RETURN $IPTABLES -N Out_RULE_0_3 $IPTABLES -A Cid3C5987DC.5 -m hashlimit --hashlimit 1/hour --hashlimit-burst 2 --hashlimit-mode srcip,srcport --hashlimit-name htable_rule_0 -j Out_RULE_0_3 $IPTABLES -A Out_RULE_0_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_0_3 -j DROP # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -N Cid3CD34BEF.1 $IPTABLES -A INPUT -i eth0 -p icmp -j Cid3CD34BEF.1 $IPTABLES -A INPUT -i eth0 -p 50 -j Cid3CD34BEF.1 $IPTABLES -N Cid3CD34BEF.0 $IPTABLES -A Cid3CD34BEF.1 -s 192.168.1.10 -j Cid3CD34BEF.0 $IPTABLES -A Cid3CD34BEF.1 -s 192.168.1.20 -j Cid3CD34BEF.0 $IPTABLES -N Cid3CD34BEF.2 $IPTABLES -A FORWARD -i eth0 -p icmp -j Cid3CD34BEF.2 $IPTABLES -A FORWARD -i eth0 -p 50 -j Cid3CD34BEF.2 $IPTABLES -A Cid3CD34BEF.2 -s 192.168.1.10 -j Cid3CD34BEF.0 $IPTABLES -A Cid3CD34BEF.2 -s 192.168.1.20 -j Cid3CD34BEF.0 $IPTABLES -A Cid3CD34BEF.0 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid3CD34BEF.0 -d 192.168.1.20 -j RETURN $IPTABLES -A Cid3CD34BEF.0 -m hashlimit --hashlimit 1/hour --hashlimit-burst 2 --hashlimit-mode dstip,dstport --hashlimit-name htable_rule_1 -j DROP $IPTABLES -N Cid3CD34BEF.4 $IPTABLES -A FORWARD -o eth0 -p icmp -j Cid3CD34BEF.4 $IPTABLES -A FORWARD -o eth0 -p 50 -j Cid3CD34BEF.4 $IPTABLES -N Cid3CD34BEF.3 $IPTABLES -A Cid3CD34BEF.4 -s 192.168.1.10 -j Cid3CD34BEF.3 $IPTABLES -A Cid3CD34BEF.4 -s 192.168.1.20 -j Cid3CD34BEF.3 $IPTABLES -A Cid3CD34BEF.3 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid3CD34BEF.3 -d 192.168.1.20 -j RETURN $IPTABLES -A Cid3CD34BEF.3 -m hashlimit --hashlimit 1/hour --hashlimit-burst 2 --hashlimit-mode dstip,dstport --hashlimit-name htable_rule_1 -j DROP # # Rule 2 (eth1) # echo "Rule 2 (eth1)" # # Anti-spoofing rule $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 22.22.22.22 -j In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 22.22.23.23 -j In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 192.168.2.1 -j In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 22.22.22.22 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 22.22.23.23 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_2 $IPTABLES -A In_RULE_2 -j LOG --log-level debug $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # # Anti-spoofing rule $IPTABLES -N Out_RULE_3 $IPTABLES -A OUTPUT -o eth1 -s ! 192.168.1.0/24 -j Out_RULE_3 $IPTABLES -A FORWARD -o eth1 -s ! 192.168.1.0/24 -j Out_RULE_3 $IPTABLES -A Out_RULE_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_3 -j DROP # # Rule 4 (eth1) # echo "Rule 4 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid40DBCD36.0 $IPTABLES -A OUTPUT -o eth1 -j Cid40DBCD36.0 $IPTABLES -A Cid40DBCD36.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid40DBCD36.0 -s 22.22.23.23 -j RETURN $IPTABLES -A Cid40DBCD36.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid40DBCD36.0 -s 192.168.2.1 -j RETURN $IPTABLES -N Out_RULE_4_3 $IPTABLES -A Cid40DBCD36.0 -j Out_RULE_4_3 $IPTABLES -A Out_RULE_4_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_4_3 -j DROP $IPTABLES -N Cid40DBCD36.1 $IPTABLES -A FORWARD -o eth1 -j Cid40DBCD36.1 $IPTABLES -A Cid40DBCD36.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid40DBCD36.1 -j Out_RULE_4_3 # # Rule 5 (eth2) # echo "Rule 5 (eth2)" # $IPTABLES -A INPUT -i eth2 -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2 -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2 -s 192.168.2.0/24 -m state --state NEW -j ACCEPT # # Rule 6 (eth2) # echo "Rule 6 (eth2)" # $IPTABLES -N In_RULE_6 $IPTABLES -A INPUT -i ! eth2 -s 192.168.2.0/24 -j In_RULE_6 $IPTABLES -A FORWARD -i ! eth2 -s 192.168.2.0/24 -j In_RULE_6 $IPTABLES -A In_RULE_6 -j LOG --log-level debug $IPTABLES -A In_RULE_6 -j DROP # # Rule 7 (eth1,eth3) # echo "Rule 7 (eth1,eth3)" # $IPTABLES -N In_RULE_7 $IPTABLES -A INPUT -i eth0 -s 22.22.23.128/25 -j In_RULE_7 $IPTABLES -A INPUT -i eth0 -s 33.33.33.0/24 -j In_RULE_7 $IPTABLES -A INPUT -i eth2 -s 22.22.23.128/25 -j In_RULE_7 $IPTABLES -A INPUT -i eth2 -s 33.33.33.0/24 -j In_RULE_7 $IPTABLES -A FORWARD -i eth0 -s 22.22.23.128/25 -j In_RULE_7 $IPTABLES -A FORWARD -i eth0 -s 33.33.33.0/24 -j In_RULE_7 $IPTABLES -A FORWARD -i eth2 -s 22.22.23.128/25 -j In_RULE_7 $IPTABLES -A FORWARD -i eth2 -s 33.33.33.0/24 -j In_RULE_7 $IPTABLES -A In_RULE_7 -j LOG --log-level debug $IPTABLES -A In_RULE_7 -j DROP # # Rule 8 (lo) # echo "Rule 8 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 9 (eth0,eth2) # echo "Rule 9 (eth0,eth2)" # $IPTABLES -N Cid433D045026912.0 $IPTABLES -A INPUT -i eth0 -j Cid433D045026912.0 $IPTABLES -A INPUT -i eth2 -j Cid433D045026912.0 $IPTABLES -A FORWARD -i eth0 -j Cid433D045026912.0 $IPTABLES -A FORWARD -i eth2 -j Cid433D045026912.0 $IPTABLES -A Cid433D045026912.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid433D045026912.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N In_RULE_9_3 $IPTABLES -A Cid433D045026912.0 -j In_RULE_9_3 $IPTABLES -A In_RULE_9_3 -j LOG --log-level debug $IPTABLES -A In_RULE_9_3 -j DROP # # Rule 10 (eth1,eth3) # echo "Rule 10 (eth1,eth3)" # $IPTABLES -N Cid434D389E26912.0 $IPTABLES -A INPUT -i eth1 -m state --state NEW -j Cid434D389E26912.0 $IPTABLES -A INPUT -i eth3 -m state --state NEW -j Cid434D389E26912.0 $IPTABLES -A FORWARD -i eth1 -m state --state NEW -j Cid434D389E26912.0 $IPTABLES -A FORWARD -i eth3 -m state --state NEW -j Cid434D389E26912.0 $IPTABLES -A Cid434D389E26912.0 -s 22.22.23.128/25 -j RETURN $IPTABLES -A Cid434D389E26912.0 -s 33.33.33.0/24 -j RETURN $IPTABLES -A Cid434D389E26912.0 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N RULE_11 $IPTABLES -A RULE_11 -j RETURN $IPTABLES -A OUTPUT -j RULE_11 $IPTABLES -A INPUT -j RULE_11 $IPTABLES -A FORWARD -j RULE_11 # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N RULE_12 $IPTABLES -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_12 $IPTABLES -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_12 $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level debug $IPTABLES -A RULE_12 -j DROP # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N Cid3B9AB902.0 $IPTABLES -A OUTPUT -j Cid3B9AB902.0 $IPTABLES -A INPUT -j Cid3B9AB902.0 $IPTABLES -A FORWARD -j Cid3B9AB902.0 $IPTABLES -A Cid3B9AB902.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -N RULE_13_3 $IPTABLES -A Cid3B9AB902.0 -j RULE_13_3 $IPTABLES -A RULE_13_3 -j LOG --log-level debug $IPTABLES -A RULE_13_3 -j DROP # # Rule 14 (global) # echo "Rule 14 (global)" # # hostF has the same IP address as firewal. $IPTABLES -N RULE_14 $IPTABLES -A OUTPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_14 $IPTABLES -A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_14 $IPTABLES -A RULE_14 -j LOG --log-level debug $IPTABLES -A RULE_14 -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -N Cid434B03D526912.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid434B03D526912.0 $IPTABLES -A INPUT -m state --state NEW -j Cid434B03D526912.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid434B03D526912.0 $IPTABLES -A Cid434B03D526912.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid434B03D526912.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid434B03D526912.0 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # testing negation in the policy rule $IPTABLES -N Cid3B021E10.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid3B021E10.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid3B021E10.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid3B021E10.0 $IPTABLES -A Cid3B021E10.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid3B021E10.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_16_3 $IPTABLES -A Cid3B021E10.0 -m limit --limit 10/minute -j RULE_16_3 $IPTABLES -A RULE_16_3 -j LOG --log-level debug $IPTABLES -A RULE_16_3 -j DROP # # Rule 17 (global) # echo "Rule 17 (global)" # # testing negation in the policy rule $IPTABLES -N Cid40C0D096.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport --dports 80,443 -j Cid40C0D096.0 $IPTABLES -A INPUT -p tcp -m tcp -m multiport --dports 80,443 -j Cid40C0D096.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 80,443 -j Cid40C0D096.0 $IPTABLES -A Cid40C0D096.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid40C0D096.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_17_3 $IPTABLES -A Cid40C0D096.0 -m limit --limit 10/minute -j RULE_17_3 $IPTABLES -A RULE_17_3 -j LOG --log-level debug $IPTABLES -A RULE_17_3 -j RETURN # # Rule 18 (global) # echo "Rule 18 (global)" # # testing negation in the policy rule $IPTABLES -N Cid40C0D10A.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -j Cid40C0D10A.0 $IPTABLES -A INPUT -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -j Cid40C0D10A.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -j Cid40C0D10A.0 $IPTABLES -A Cid40C0D10A.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid40C0D10A.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_18_3 $IPTABLES -A Cid40C0D10A.0 -m limit --limit 10/minute -j RULE_18_3 $IPTABLES -A RULE_18_3 -j LOG --log-level debug $IPTABLES -A RULE_18_3 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # $IPTABLES -N Cid3B0B4A13.1 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid3B0B4A13.1 $IPTABLES -N Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.1 -d 22.22.22.22 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.1 -d 22.22.23.23 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.1 -d 192.168.1.1 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.1 -d 192.168.2.1 -j Cid3B0B4A13.0 $IPTABLES -N Cid3B0B4A13.2 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid3B0B4A13.2 $IPTABLES -A Cid3B0B4A13.2 -d 22.22.22.22 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.2 -d 22.22.23.23 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.2 -d 192.168.1.1 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.2 -d 192.168.2.1 -j Cid3B0B4A13.0 $IPTABLES -A Cid3B0B4A13.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid3B0B4A13.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_19_3 $IPTABLES -A Cid3B0B4A13.0 -j RULE_19_3 $IPTABLES -A RULE_19_3 -j LOG --log-level debug $IPTABLES -A RULE_19_3 -j DROP # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -N Cid3B5535B7.0 $IPTABLES -A OUTPUT -d 192.168.1.0/24 -j Cid3B5535B7.0 $IPTABLES -A Cid3B5535B7.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid3B5535B7.0 -s 22.22.23.23 -j RETURN $IPTABLES -A Cid3B5535B7.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid3B5535B7.0 -s 192.168.2.1 -j RETURN $IPTABLES -N Out_RULE_20_3 $IPTABLES -A Cid3B5535B7.0 -j Out_RULE_20_3 $IPTABLES -A Out_RULE_20_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_20_3 -j DROP $IPTABLES -N Cid3B5535B7.1 $IPTABLES -A INPUT -d 192.168.1.0/24 -j Cid3B5535B7.1 $IPTABLES -A FORWARD -d 192.168.1.0/24 -j Cid3B5535B7.1 $IPTABLES -A Cid3B5535B7.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_20_3 $IPTABLES -A Cid3B5535B7.1 -j RULE_20_3 $IPTABLES -A RULE_20_3 -j LOG --log-level debug $IPTABLES -A RULE_20_3 -j DROP # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N Cid40F1D905.0 $IPTABLES -A OUTPUT -d 192.168.1.0/24 -j Cid40F1D905.0 $IPTABLES -A Cid40F1D905.0 -s 192.168.1.1 -j RETURN $IPTABLES -N Out_RULE_21_3 $IPTABLES -A Cid40F1D905.0 -j Out_RULE_21_3 $IPTABLES -A Out_RULE_21_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_21_3 -j DROP $IPTABLES -N Cid40F1D905.1 $IPTABLES -A INPUT -d 192.168.1.0/24 -j Cid40F1D905.1 $IPTABLES -A FORWARD -d 192.168.1.0/24 -j Cid40F1D905.1 $IPTABLES -A Cid40F1D905.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_21_3 $IPTABLES -A Cid40F1D905.1 -j RULE_21_3 $IPTABLES -A RULE_21_3 -j LOG --log-level debug $IPTABLES -A RULE_21_3 -j DROP # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N Cid3E74DF71.0 $IPTABLES -A INPUT -s 222.222.222.40 -j Cid3E74DF71.0 $IPTABLES -A INPUT -s 222.222.222.41 -j Cid3E74DF71.0 $IPTABLES -A FORWARD -s 222.222.222.40 -j Cid3E74DF71.0 $IPTABLES -A FORWARD -s 222.222.222.41 -j Cid3E74DF71.0 $IPTABLES -A Cid3E74DF71.0 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid3E74DF71.0 -d 192.168.1.20 -j RETURN $IPTABLES -N RULE_22_3 $IPTABLES -A Cid3E74DF71.0 -j RULE_22_3 $IPTABLES -A RULE_22_3 -j LOG --log-level debug $IPTABLES -A RULE_22_3 -j DROP # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -N Cid3B11F63D.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -j Cid3B11F63D.0 $IPTABLES -A INPUT -s 192.168.2.0/24 -j Cid3B11F63D.0 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j Cid3B11F63D.0 $IPTABLES -A OUTPUT -s 192.168.2.0/24 -j Cid3B11F63D.0 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j Cid3B11F63D.0 $IPTABLES -A FORWARD -s 192.168.2.0/24 -j Cid3B11F63D.0 $IPTABLES -A Cid3B11F63D.0 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid3B11F63D.0 -d 192.168.1.20 -j RETURN $IPTABLES -N RULE_23_3 $IPTABLES -A Cid3B11F63D.0 -j RULE_23_3 $IPTABLES -A RULE_23_3 -j LOG --log-level debug $IPTABLES -A RULE_23_3 -j DROP # # Rule 24 (global) # echo "Rule 24 (global)" # # testing negation in service field $IPTABLES -N Cid3B021E6F.0 $IPTABLES -A OUTPUT -d 192.168.1.10 -j Cid3B021E6F.0 $IPTABLES -A OUTPUT -d 192.168.1.20 -j Cid3B021E6F.0 $IPTABLES -A FORWARD -d 192.168.1.10 -j Cid3B021E6F.0 $IPTABLES -A FORWARD -d 192.168.1.20 -j Cid3B021E6F.0 $IPTABLES -A Cid3B021E6F.0 -p tcp -m tcp -m multiport --dports 25,22 -j RETURN $IPTABLES -N RULE_24_3 $IPTABLES -A Cid3B021E6F.0 -j RULE_24_3 $IPTABLES -A RULE_24_3 -j LOG --log-level debug $IPTABLES -A RULE_24_3 -j DROP # # Rule 25 (global) # echo "Rule 25 (global)" # # testing negation in service field $IPTABLES -N Cid3CCA2CF4.0 $IPTABLES -A OUTPUT -d 192.168.1.10 -m state --state NEW -j Cid3CCA2CF4.0 $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j Cid3CCA2CF4.0 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cid3CCA2CF4.0 $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j Cid3CCA2CF4.0 $IPTABLES -A Cid3CCA2CF4.0 -p tcp -m tcp -m multiport --dports 25,22 -j RETURN $IPTABLES -N RULE_25_3 $IPTABLES -A Cid3CCA2CF4.0 -j RULE_25_3 $IPTABLES -A RULE_25_3 -j LOG --log-level debug $IPTABLES -A RULE_25_3 -j ACCEPT # # Rule 26 (global) # echo "Rule 26 (global)" # # testing negation in service field $IPTABLES -N Cid3EA925F1.0 $IPTABLES -A OUTPUT -d 192.168.1.10 -m state --state NEW -j Cid3EA925F1.0 $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j Cid3EA925F1.0 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cid3EA925F1.0 $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j Cid3EA925F1.0 $IPTABLES -A Cid3EA925F1.0 -p tcp -m tcp --dport 25 -j RETURN $IPTABLES -N RULE_26_3 $IPTABLES -A Cid3EA925F1.0 -j RULE_26_3 $IPTABLES -A RULE_26_3 -j LOG --log-level debug $IPTABLES -A RULE_26_3 -j ACCEPT # # Rule 27 (global) # echo "Rule 27 (global)" # # testing negation in service field $IPTABLES -N Cid3EA9225C.0 $IPTABLES -A OUTPUT -d 192.168.1.10 -m state --state NEW -j Cid3EA9225C.0 $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j Cid3EA9225C.0 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cid3EA9225C.0 $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j Cid3EA9225C.0 $IPTABLES -A Cid3EA9225C.0 -p icmp -m icmp --icmp-type any -j RETURN $IPTABLES -N RULE_27_3 $IPTABLES -A Cid3EA9225C.0 -j RULE_27_3 $IPTABLES -A RULE_27_3 -j LOG --log-level debug $IPTABLES -A RULE_27_3 -j ACCEPT # # Rule 28 (global) # echo "Rule 28 (global)" # # testing negation in service field $IPTABLES -N Cid4144E299.1 $IPTABLES -A OUTPUT -m state --state NEW -j Cid4144E299.1 $IPTABLES -A INPUT -m state --state NEW -j Cid4144E299.1 $IPTABLES -A FORWARD -m state --state NEW -j Cid4144E299.1 $IPTABLES -A Cid4144E299.1 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid4144E299.1 -d 192.168.1.20 -j RETURN $IPTABLES -N Cid4144E299.0 $IPTABLES -A Cid4144E299.1 -j Cid4144E299.0 $IPTABLES -A Cid4144E299.0 -p icmp -m icmp --icmp-type any -j RETURN $IPTABLES -A Cid4144E299.0 -j ACCEPT # # Rule 29 (global) # echo "Rule 29 (global)" # # testing negation in service field $IPTABLES -N Cid41449248.1 $IPTABLES -A OUTPUT -m state --state NEW -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j Cid41449248.1 $IPTABLES -N Cid41449248.0 $IPTABLES -A Cid41449248.1 -d 192.168.1.10 -j Cid41449248.0 $IPTABLES -A Cid41449248.1 -d 192.168.1.20 -j Cid41449248.0 $IPTABLES -N Cid41449248.2 $IPTABLES -A FORWARD -m state --state NEW -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j Cid41449248.2 $IPTABLES -A Cid41449248.2 -d 192.168.1.10 -j Cid41449248.0 $IPTABLES -A Cid41449248.2 -d 192.168.1.20 -j Cid41449248.0 $IPTABLES -A Cid41449248.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -A Cid41449248.0 -j ACCEPT # # Rule 30 (global) # echo "Rule 30 (global)" # # testing negation in service field $IPTABLES -N Cid414532F3.1 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j Cid414532F3.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j Cid414532F3.1 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -m state --state NEW -j Cid414532F3.1 $IPTABLES -A Cid414532F3.1 -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RETURN $IPTABLES -N Cid414532F3.0 $IPTABLES -A Cid414532F3.1 -j Cid414532F3.0 $IPTABLES -A Cid414532F3.0 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid414532F3.0 -d 192.168.1.20 -j RETURN $IPTABLES -A Cid414532F3.0 -j ACCEPT # # Rule 31 (global) # echo "Rule 31 (global)" # # testing negation in service field $IPTABLES -N Cid41449257.1 $IPTABLES -A OUTPUT -d 192.168.1.10 -m state --state NEW -j Cid41449257.1 $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j Cid41449257.1 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cid41449257.1 $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j Cid41449257.1 $IPTABLES -A Cid41449257.1 -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RETURN $IPTABLES -N Cid41449257.0 $IPTABLES -A Cid41449257.1 -j Cid41449257.0 $IPTABLES -A Cid41449257.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -A Cid41449257.0 -j ACCEPT # # Rule 32 (global) # echo "Rule 32 (global)" # $IPTABLES -N Cid4368F08A15884.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j Cid4368F08A15884.1 $IPTABLES -N Cid4368F08A15884.0 $IPTABLES -A Cid4368F08A15884.1 -s 22.22.22.22 -j Cid4368F08A15884.0 $IPTABLES -A Cid4368F08A15884.1 -s 22.22.23.23 -j Cid4368F08A15884.0 $IPTABLES -A Cid4368F08A15884.1 -s 192.168.1.1 -j Cid4368F08A15884.0 $IPTABLES -A Cid4368F08A15884.1 -s 192.168.2.1 -j Cid4368F08A15884.0 $IPTABLES -A Cid4368F08A15884.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid4368F08A15884.0 -d 22.22.23.23 -j RETURN $IPTABLES -A Cid4368F08A15884.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid4368F08A15884.0 -d 192.168.2.1 -j RETURN $IPTABLES -A Cid4368F08A15884.0 -j ACCEPT $IPTABLES -N Cid4368F08A15884.2 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j Cid4368F08A15884.2 $IPTABLES -A Cid4368F08A15884.2 -s 22.22.22.22 -j ACCEPT $IPTABLES -A Cid4368F08A15884.2 -s 22.22.23.23 -j ACCEPT $IPTABLES -A Cid4368F08A15884.2 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid4368F08A15884.2 -s 192.168.2.1 -j ACCEPT # # Rule 33 (global) # echo "Rule 33 (global)" # $IPTABLES -N Cid3E74D8BB.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid3E74D8BB.1 $IPTABLES -N Cid3E74D8BB.0 $IPTABLES -A Cid3E74D8BB.1 -s 22.22.22.22 -j Cid3E74D8BB.0 $IPTABLES -A Cid3E74D8BB.1 -s 22.22.23.23 -j Cid3E74D8BB.0 $IPTABLES -A Cid3E74D8BB.1 -s 192.168.1.1 -j Cid3E74D8BB.0 $IPTABLES -A Cid3E74D8BB.1 -s 192.168.2.1 -j Cid3E74D8BB.0 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.2.0/24 --dport 22 -m state --state NEW -j Cid3E74D8BB.0 $IPTABLES -A Cid3E74D8BB.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3E74D8BB.0 -d 22.22.23.23 -j RETURN $IPTABLES -A Cid3E74D8BB.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3E74D8BB.0 -d 192.168.2.1 -j RETURN $IPTABLES -A Cid3E74D8BB.0 -j ACCEPT $IPTABLES -N Cid3E74D8BB.3 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid3E74D8BB.3 $IPTABLES -N Cid3E74D8BB.2 $IPTABLES -A Cid3E74D8BB.3 -s 22.22.22.22 -j Cid3E74D8BB.2 $IPTABLES -A Cid3E74D8BB.3 -s 22.22.23.23 -j Cid3E74D8BB.2 $IPTABLES -A Cid3E74D8BB.3 -s 192.168.1.1 -j Cid3E74D8BB.2 $IPTABLES -A Cid3E74D8BB.3 -s 192.168.2.1 -j Cid3E74D8BB.2 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.2.0/24 --dport 22 -m state --state NEW -j Cid3E74D8BB.2 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.2.0/24 --dport 22 -m state --state NEW -j Cid3E74D8BB.2 $IPTABLES -A Cid3E74D8BB.2 -d 192.168.1.0/24 -j RETURN $IPTABLES -A Cid3E74D8BB.2 -j ACCEPT # # Rule 34 (global) # echo "Rule 34 (global)" # $IPTABLES -N Cid3B45739A.1 $IPTABLES -A INPUT -s 22.22.22.22 -j Cid3B45739A.1 $IPTABLES -N Cid3B45739A.0 $IPTABLES -A Cid3B45739A.1 -p icmp -j Cid3B45739A.0 $IPTABLES -A Cid3B45739A.1 -p 50 -j Cid3B45739A.0 $IPTABLES -N Cid3B45739A.2 $IPTABLES -A INPUT -s 192.168.1.1 -j Cid3B45739A.2 $IPTABLES -A Cid3B45739A.2 -p icmp -j Cid3B45739A.0 $IPTABLES -A Cid3B45739A.2 -p 50 -j Cid3B45739A.0 $IPTABLES -N Cid3B45739A.3 $IPTABLES -A OUTPUT -s 22.22.22.22 -j Cid3B45739A.3 $IPTABLES -A Cid3B45739A.3 -p icmp -j Cid3B45739A.0 $IPTABLES -A Cid3B45739A.3 -p 50 -j Cid3B45739A.0 $IPTABLES -N Cid3B45739A.4 $IPTABLES -A OUTPUT -s 192.168.1.1 -j Cid3B45739A.4 $IPTABLES -A Cid3B45739A.4 -p icmp -j Cid3B45739A.0 $IPTABLES -A Cid3B45739A.4 -p 50 -j Cid3B45739A.0 $IPTABLES -A Cid3B45739A.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3B45739A.0 -d 192.168.1.1 -j RETURN $IPTABLES -N RULE_34_3 $IPTABLES -A Cid3B45739A.0 -j RULE_34_3 $IPTABLES -A RULE_34_3 -j LOG --log-level debug $IPTABLES -A RULE_34_3 -j DROP # # Rule 35 (global) # echo "Rule 35 (global)" # # double negation rule $IPTABLES -N Cid4067B2C2.1 $IPTABLES -A OUTPUT -j Cid4067B2C2.1 $IPTABLES -A INPUT -j Cid4067B2C2.1 $IPTABLES -A FORWARD -j Cid4067B2C2.1 $IPTABLES -A Cid4067B2C2.1 -d 192.168.1.10 -j RETURN $IPTABLES -A Cid4067B2C2.1 -d 192.168.1.20 -j RETURN $IPTABLES -N Cid4067B2C2.0 $IPTABLES -A Cid4067B2C2.1 -j Cid4067B2C2.0 $IPTABLES -A Cid4067B2C2.0 -p tcp -m tcp -m multiport --dports 3128,8080 -j RETURN $IPTABLES -N RULE_35_3 $IPTABLES -A Cid4067B2C2.0 -j RULE_35_3 $IPTABLES -A RULE_35_3 -j LOG --log-level debug $IPTABLES -A RULE_35_3 -j DROP # # Rule 36 (global) # echo "Rule 36 (global)" # $IPTABLES -N Cid41A88DF6.0 $IPTABLES -A INPUT -m state --state NEW -j Cid41A88DF6.0 $IPTABLES -A Cid41A88DF6.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid41A88DF6.0 -d 192.168.2.1 -j RETURN $IPTABLES -A Cid41A88DF6.0 -j ACCEPT $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m state --state NEW -j ACCEPT # # Rule 37 (global) # echo "Rule 37 (global)" # $IPTABLES -N Cid41B5176E.0 $IPTABLES -A OUTPUT -d 192.168.1.0/24 -m state --state NEW -j Cid41B5176E.0 $IPTABLES -A Cid41B5176E.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid41B5176E.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid41B5176E.0 -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 38 (global) # echo "Rule 38 (global)" # $IPTABLES -N Cid4143BD3F.0 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 25 -m state --state NEW -j Cid4143BD3F.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 25 -m state --state NEW -j Cid4143BD3F.0 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 25 -m state --state NEW -j Cid4143BD3F.0 $IPTABLES -A Cid4143BD3F.0 -m time --timestart 00:00 --timestop 23:59 --days Sat -j RETURN $IPTABLES -A Cid4143BD3F.0 -m time --timestart 00:00 --timestop 23:59 --days Sun -j RETURN $IPTABLES -A Cid4143BD3F.0 -j ACCEPT # # Rule 39 (global) # echo "Rule 39 (global)" # $IPTABLES -N Cid4143BD1A.0 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -m state --state NEW -j Cid4143BD1A.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -m state --state NEW -j Cid4143BD1A.0 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -m state --state NEW -j Cid4143BD1A.0 $IPTABLES -A Cid4143BD1A.0 -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RETURN $IPTABLES -A Cid4143BD1A.0 -j ACCEPT # # Rule 40 (global) # echo "Rule 40 (global)" # $IPTABLES -N Cid1515316X29460.0 $IPTABLES -A INPUT -p tcp -m tcp -d ! 192.168.1.0/24 --dport 80 -j Cid1515316X29460.0 $IPTABLES -A Cid1515316X29460.0 -s 22.22.22.22 -j DROP $IPTABLES -A Cid1515316X29460.0 -s 22.22.23.23 -j DROP $IPTABLES -A Cid1515316X29460.0 -s 192.168.1.1 -j DROP $IPTABLES -A Cid1515316X29460.0 -s 192.168.2.1 -j DROP $IPTABLES -N Cid1515316X29460.1 $IPTABLES -A OUTPUT -p tcp -m tcp -d ! 192.168.1.0/24 --dport 80 -j Cid1515316X29460.1 $IPTABLES -A Cid1515316X29460.1 -s 22.22.22.22 -j DROP $IPTABLES -A Cid1515316X29460.1 -s 22.22.23.23 -j DROP $IPTABLES -A Cid1515316X29460.1 -s 192.168.1.1 -j DROP $IPTABLES -A Cid1515316X29460.1 -s 192.168.2.1 -j DROP # # Rule 41 (global) # echo "Rule 41 (global)" # $IPTABLES -N Cid1515397X29460.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s ! 192.168.1.0/24 --dport 80 -j Cid1515397X29460.0 $IPTABLES -A Cid1515397X29460.0 -d 22.22.22.22 -j DROP $IPTABLES -A Cid1515397X29460.0 -d 22.22.23.23 -j DROP $IPTABLES -A Cid1515397X29460.0 -d 192.168.1.1 -j DROP $IPTABLES -A Cid1515397X29460.0 -d 192.168.2.1 -j DROP $IPTABLES -N Cid1515397X29460.1 $IPTABLES -A INPUT -p tcp -m tcp -s ! 192.168.1.0/24 --dport 80 -j Cid1515397X29460.1 $IPTABLES -A Cid1515397X29460.1 -d 22.22.22.22 -j DROP $IPTABLES -A Cid1515397X29460.1 -d 22.22.23.23 -j DROP $IPTABLES -A Cid1515397X29460.1 -d 192.168.1.1 -j DROP $IPTABLES -A Cid1515397X29460.1 -d 192.168.2.1 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:07 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces prolog_commands reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall36-2.fw.orig0000755000175000017500000002642311733011756022175 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:45 2012 PDT by vadim # # files: * firewall36-2.fw /etc/firewall36-2.fw # # Compiled for iptables (any version) # # Testing routing configuration where routing rules install simple (not ECMP) default route FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth2" for i in eth0 eth1 lo eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.0.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v 'proto kernel' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add default via 192.0.2.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:45 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/fw1.fw.orig0000755000175000017500000004171411733011756020555 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:35 2012 PDT by vadim # # files: * fw1.fw /etc/fw1.fw # # Compiled for iptables (any version) # # This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside. # Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0 # fw1:NAT:8: error: NAT rule can not change service types: TCPService to UDPService # fw1:NAT:8: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. # fw1:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 fe80::21d:9ff:fe8b:8e94/64 192.168.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -j ACCEPT # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # # source port only $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 --sport 123 -j SNAT --to-source :5050 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # dest port only $IPTABLES -t nat -A PREROUTING -p udp -m udp -s 192.168.1.0/24 --dport 53 -j DNAT --to-destination :1053 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # # SDNAT $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.0.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -d 192.168.1.10 --dport 22 -j SNAT --to-source 192.168.1.1 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # # SDNAT with source port $IPTABLES -t nat -A PREROUTING -p udp -m udp --sport 123 -d 192.0.2.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p udp -m udp --sport 123 -d 192.168.1.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth1 -p udp -m udp --sport 123 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1:5050 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # # SDNAT with dest port $IPTABLES -t nat -A PREROUTING -p udp -m udp -s 192.168.1.0/24 --dport 53 -j DNAT --to-destination 192.168.1.10:1053 $IPTABLES -t nat -A POSTROUTING -o eth1 -p udp -m udp -s 192.168.1.0/24 -d 192.168.1.10 --dport 1053 -j SNAT --to-source 192.168.1.1 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # # SDNAT # translate src and dst addresses # and src and dst ports $IPTABLES -t nat -A PREROUTING -p udp -m udp -s 192.168.1.0/24 --sport 1024:65535 --dport 53 -j DNAT --to-destination 192.168.1.10:1053 $IPTABLES -t nat -A POSTROUTING -o eth1 -p udp -m udp -s 192.168.1.0/24 -d 192.168.1.10 --dport 1053 -j SNAT --to-source 192.168.1.1:32767-65535 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 --dport 53 -j SNAT --to-source :5050 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # anti spoofing rule $IPTABLES -N Cid45745X95438.0 $IPTABLES -A FORWARD -i + -d 192.168.171.2 -m state --state NEW -j Cid45745X95438.0 $IPTABLES -N In_RULE_0 $IPTABLES -A Cid45745X95438.0 -s 192.0.2.1 -j In_RULE_0 $IPTABLES -A Cid45745X95438.0 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A FORWARD -i + -s 192.168.1.0/24 -d 192.168.171.2 -m state --state NEW -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # # fw1:Policy:1: error: Rule '1 (global)' shadows rule '2 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # fw1:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_3 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- ACCEPT " $IPTABLES -A RULE_3 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_4 $IPTABLES -A OUTPUT -d 192.0.2.1 -m state --state NEW -j RULE_4 $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j RULE_4 $IPTABLES -A INPUT -m state --state NEW -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -A RULE_4 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 1 --tcp-flags SYN SYN -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 1 --tcp-flags SYN SYN -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 1 --tcp-flags SYN SYN -m state --state NEW -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -p tcp -m tcp -j RULE_6 $IPTABLES -A INPUT -p tcp -m tcp -j RULE_6 $IPTABLES -A FORWARD -p tcp -m tcp -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- REJECT " $IPTABLES -A RULE_6 -p tcp -m tcp -j REJECT --reject-with tcp-reset $IPTABLES -A OUTPUT -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A FORWARD -j RULE_6 $IPTABLES -A RULE_6 -j REJECT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:35 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/test-shadowing-3.fw.orig0000755000175000017500000003616311733011756023162 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:41 2012 PDT by vadim # # files: * test-shadowing-3.fw /etc/test-shadowing-3.fw # # Compiled for iptables (any version) # # testing shadowing detection # compiler runs with -xt flag # testing shadowing when rules have non-default options # test-shadowing-3:Policy_3:0: error: Rule 'Policy_3 0 (eth0)' shadows rule 'Policy_3 1 (eth0)' below it # test-shadowing-3:Policy_5:0: error: Rule 'Policy_5 0 (eth0)' shadows rule 'Policy_5 1 (eth0)' below it # test-shadowing-3:Policy_6:0: error: Rule 'Policy_6 0 (global)' shadows rule 'Policy_6 1 (global)' below it # test-shadowing-3:Policy_7:0: error: Rule 'Policy_7 0 (global)' shadows rule 'Policy_7 1 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 eth2" for i in eth0 eth1 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 22.22.22.22/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_1 # # Rule Policy_1 0 (eth0) # echo "Rule Policy_1 0 (eth0)" # # connlimit $IPTABLES -N Policy_1 $IPTABLES -A Policy_1 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m connlimit --connlimit-above 10 -j ACCEPT # # Rule Policy_1 1 (eth0) # echo "Rule Policy_1 1 (eth0)" # $IPTABLES -A Policy_1 -o eth0 -s 192.168.1.0/24 -j DROP # ================ Table 'filter', rule set Policy_2 # # Rule Policy_2 0 (eth0) # echo "Rule Policy_2 0 (eth0)" # # hashlimit $IPTABLES -N Policy_2 $IPTABLES -A Policy_2 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 10/second --hashlimit-name test -j ACCEPT # # Rule Policy_2 1 (eth0) # echo "Rule Policy_2 1 (eth0)" # $IPTABLES -A Policy_2 -o eth0 -s 192.168.1.0/24 -j DROP # ================ Table 'filter', rule set Policy_3 # # Rule Policy_3 0 (eth0) # echo "Rule Policy_3 0 (eth0)" # # 50/sec # test-shadowing-3:Policy_3:0: error: Rule 'Policy_3 0 (eth0)' shadows rule 'Policy_3 1 (eth0)' below it $IPTABLES -N Policy_3 $IPTABLES -A Policy_3 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 50/second --hashlimit-mode srcip --hashlimit-name test -j ACCEPT # # Rule Policy_3 1 (eth0) # echo "Rule Policy_3 1 (eth0)" # # 50/sec $IPTABLES -A Policy_3 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 50/second --hashlimit-mode srcip --hashlimit-name test -j ACCEPT # ================ Table 'filter', rule set Policy_4 # # Rule Policy_4 0 (eth0) # echo "Rule Policy_4 0 (eth0)" # # 30/sec $IPTABLES -N Policy_4 $IPTABLES -A Policy_4 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 30/second --hashlimit-mode srcip --hashlimit-name test -j ACCEPT # # Rule Policy_4 1 (eth0) # echo "Rule Policy_4 1 (eth0)" # # 50/sec $IPTABLES -A Policy_4 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 50/second --hashlimit-mode srcip --hashlimit-name test -j ACCEPT # # Rule Policy_4 2 (eth0) # echo "Rule Policy_4 2 (eth0)" # # htable_rule_4 $IPTABLES -A Policy_4 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 10/second --hashlimit-mode srcip --hashlimit-name htable_rule_4 -j ACCEPT # # Rule Policy_4 3 (eth0) # echo "Rule Policy_4 3 (eth0)" # # htable_rule_5 $IPTABLES -A Policy_4 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 10/second --hashlimit-mode srcip --hashlimit-name htable_rule_5 -j ACCEPT # ================ Table 'filter', rule set Policy_5 # # Rule Policy_5 0 (eth0) # echo "Rule Policy_5 0 (eth0)" # # 50/sec # test-shadowing-3:Policy_5:0: error: Rule 'Policy_5 0 (eth0)' shadows rule 'Policy_5 1 (eth0)' below it $IPTABLES -N Policy_5 $IPTABLES -A Policy_5 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 50/second --hashlimit-mode srcip --hashlimit-name test -j ACCEPT # # Rule Policy_5 1 (eth0) # echo "Rule Policy_5 1 (eth0)" # # 30/sec $IPTABLES -A Policy_5 -o eth0 -s 192.168.1.0/24 -m state --state NEW -m hashlimit --hashlimit 30/second --hashlimit-mode srcip --hashlimit-name test -j ACCEPT # ================ Table 'filter', rule set Policy_6 # # Rule Policy_6 0 (global) # echo "Rule Policy_6 0 (global)" # # test-shadowing-3:Policy_6:0: error: Rule 'Policy_6 0 (global)' shadows rule 'Policy_6 1 (global)' below it $IPTABLES -N Policy_6 $IPTABLES -A Policy_6 -i + -s 192.168.11.0/24 -j DROP # # Rule Policy_6 1 (global) # echo "Rule Policy_6 1 (global)" # $IPTABLES -A Policy_6 -i + -s 192.168.11.10/31 -j DROP # ================ Table 'filter', rule set Policy_7 # # Rule Policy_7 0 (global) # echo "Rule Policy_7 0 (global)" # # test-shadowing-3:Policy_7:0: error: Rule 'Policy_7 0 (global)' shadows rule 'Policy_7 1 (global)' below it $IPTABLES -N Policy_7 $IPTABLES -A Policy_7 -i + -s 192.168.11.10/31 -j DROP # # Rule Policy_7 1 (global) # echo "Rule Policy_7 1 (global)" # $IPTABLES -A Policy_7 -i + -s 192.168.11.11 -j DROP # ================ Table 'filter', rule set Policy_8 # # Rule Policy_8 0 (global) # echo "Rule Policy_8 0 (global)" # # even though this is a trivial case, # I had a bug with handling networks with netmask /31 that broke it $IPTABLES -N Policy_8 $IPTABLES -A Policy_8 -i + -s 24.56.78.90 -j DROP # # Rule Policy_8 1 (global) # echo "Rule Policy_8 1 (global)" # $IPTABLES -A Policy_8 -i + -s 222.222.222.0/24 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # limit $IPTABLES -A FORWARD -o eth0 -s 192.168.1.0/24 -m state --state NEW -m limit --limit 10/second -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A FORWARD -o eth0 -s 192.168.1.0/24 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-ipt-reset-prolog-after-interfaces.fw.orig0000755000175000017500000003073211733011756031177 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:29 2012 PDT by vadim # # files: * firewall-ipv6-ipt-reset-prolog-after-interfaces.fw /etc/firewall-ipv6-ipt-reset-prolog-after-interfaces.fw # # Compiled for iptables (any version) # # Policy is configured as dual address family. Usigng iptables-restore. Prolog is after configuration of interfaces FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" echo "This is prolog" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A INPUT -m state --state NEW -j ACCEPT " echo "-A FORWARD -i + -m state --state NEW -j ACCEPT " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A INPUT -m state --state NEW -j ACCEPT " echo "-A FORWARD -i + -m state --state NEW -j ACCEPT " # echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:29 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall95.fw.orig0000755000175000017500000002304411733011756022037 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:19 2012 PDT by vadim # # files: * firewall95.fw /etc/fw/firewall95.fw # # Compiled for iptables 1.3.0 # # firewall has intrface with netmask /31 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0" for i in eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.10/31" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # address 192.168.1.11 should not be considered a broadcast on the subnet attached to eth0 $IPTABLES -A OUTPUT -d 192.168.1.11 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.11 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:19 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall39.fw.orig0000755000175000017500000006217411733011756022044 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:49 2012 PDT by vadim # # files: * firewall39.fw /etc/fw/firewall39.fw # # Compiled for iptables (any version) # # testing branching rules # normal script mode (not using iptables-restore) # firewall39:Policy:14: warning: Rule branches to rule set rule6_branch which branches back to it, creating a loop # firewall39:rule6_branch:0: warning: Rule branches to rule set Policy which branches back to it, creating a loop FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 22.22.23.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -j ACCEPT # ================ Table 'mangle', rule set Policy # # Rule 7 (global) # echo "Rule 7 (global)" # # green rules branch # also in mangle table $IPTABLES -N rule0_branch -t mangle $IPTABLES -t mangle -A PREROUTING -p 50 -j rule0_branch $IPTABLES -t mangle -A PREROUTING -p ah -j rule0_branch $IPTABLES -t mangle -A POSTROUTING -p 50 -j rule0_branch $IPTABLES -t mangle -A POSTROUTING -p ah -j rule0_branch $IPTABLES -t mangle -A FORWARD -p 50 -j rule0_branch $IPTABLES -t mangle -A FORWARD -p ah -j rule0_branch # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N rule1_branch -t mangle $IPTABLES -t mangle -A PREROUTING -p 50 -j rule1_branch $IPTABLES -t mangle -A PREROUTING -p ah -j rule1_branch $IPTABLES -t mangle -A POSTROUTING -p 50 -j rule1_branch $IPTABLES -t mangle -A POSTROUTING -p ah -j rule1_branch $IPTABLES -t mangle -A FORWARD -p 50 -j rule1_branch $IPTABLES -t mangle -A FORWARD -p ah -j rule1_branch # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid464C29BB3999.0 -t mangle $IPTABLES -t mangle -A PREROUTING -s ! 192.168.1.0/24 -j Cid464C29BB3999.0 $IPTABLES -N rule2_branch -t mangle $IPTABLES -t mangle -A Cid464C29BB3999.0 -p 50 -j rule2_branch $IPTABLES -t mangle -A Cid464C29BB3999.0 -p ah -j rule2_branch $IPTABLES -N Cid464C29BB3999.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -s ! 192.168.1.0/24 -j Cid464C29BB3999.1 $IPTABLES -t mangle -A Cid464C29BB3999.1 -p 50 -j rule2_branch $IPTABLES -t mangle -A Cid464C29BB3999.1 -p ah -j rule2_branch $IPTABLES -N Cid464C29BB3999.2 -t mangle $IPTABLES -t mangle -A FORWARD -s ! 192.168.1.0/24 -j Cid464C29BB3999.2 $IPTABLES -t mangle -A Cid464C29BB3999.2 -p 50 -j rule2_branch $IPTABLES -t mangle -A Cid464C29BB3999.2 -p ah -j rule2_branch # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # $IPTABLES -N rule3_branch -t mangle $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -j rule3_branch $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -j rule3_branch $IPTABLES -t mangle -A FORWARD -i eth1 -p 50 -j rule3_branch $IPTABLES -t mangle -A FORWARD -i eth1 -p ah -j rule3_branch # # Rule 11 (eth1) # echo "Rule 11 (eth1)" # $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -j rule3_branch $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -j rule3_branch $IPTABLES -t mangle -A FORWARD -o eth1 -p 50 -j rule3_branch $IPTABLES -t mangle -A FORWARD -o eth1 -p ah -j rule3_branch # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N rule4_branch -t mangle $IPTABLES -t mangle -A PREROUTING -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch $IPTABLES -t mangle -A POSTROUTING -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch $IPTABLES -t mangle -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N rule5_branch -t mangle $IPTABLES -t mangle -A PREROUTING -s 192.168.1.0/24 -j rule5_branch $IPTABLES -t mangle -A POSTROUTING -s 192.168.1.0/24 -j rule5_branch $IPTABLES -t mangle -A FORWARD -s 192.168.1.0/24 -j rule5_branch # ================ Table 'filter', rule set rule_4_0_branch # # Rule rule_4_0_branch 0 (eth2) # echo "Rule rule_4_0_branch 0 (eth2)" # $IPTABLES -N rule_4_0_branch $IPTABLES -A rule_4_0_branch -o eth2 -m state --state NEW -j ACCEPT # # Rule rule_4_0_branch 1 (global) # echo "Rule rule_4_0_branch 1 (global)" # $IPTABLES -N rule_4_0_branch_1 $IPTABLES -A rule_4_0_branch -j rule_4_0_branch_1 $IPTABLES -A rule_4_0_branch_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A rule_4_0_branch_1 -j DROP # ================ Table 'filter', rule set rule_4_1_branch # # Rule rule_4_1_branch 0 (eth2) # echo "Rule rule_4_1_branch 0 (eth2)" # $IPTABLES -N rule_4_1_branch $IPTABLES -A rule_4_1_branch -o eth2 -m state --state NEW -j ACCEPT # # Rule rule_4_1_branch 1 (global) # echo "Rule rule_4_1_branch 1 (global)" # $IPTABLES -N rule_4_1_branch_1 $IPTABLES -A rule_4_1_branch -j rule_4_1_branch_1 $IPTABLES -A rule_4_1_branch_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A rule_4_1_branch_1 -j DROP # ================ Table 'filter', rule set rule0_branch # # Rule rule0_branch 0 (global) # echo "Rule rule0_branch 0 (global)" # $IPTABLES -N rule0_branch $IPTABLES -N rule0_branch_0 $IPTABLES -A rule0_branch -m state --state NEW -j rule0_branch_0 $IPTABLES -A rule0_branch_0 -j LOG --log-level info --log-prefix "RULE 0 -- ACCEPT " $IPTABLES -A rule0_branch_0 -j ACCEPT # ================ Table 'filter', rule set rule1_branch # # Rule rule1_branch 0 (global) # echo "Rule rule1_branch 0 (global)" # $IPTABLES -N rule1_branch $IPTABLES -N rule1_branch_0 $IPTABLES -A rule1_branch -d 192.168.2.10 -j rule1_branch_0 $IPTABLES -A rule1_branch_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A rule1_branch_0 -j DROP # # Rule rule1_branch 1 (global) # echo "Rule rule1_branch 1 (global)" # $IPTABLES -A rule1_branch -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set rule2_branch # # Rule rule2_branch 0 (global) # echo "Rule rule2_branch 0 (global)" # $IPTABLES -N rule2_branch $IPTABLES -N rule2_branch_0 $IPTABLES -A rule2_branch -d ! 192.168.2.10 -j rule2_branch_0 $IPTABLES -A rule2_branch_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A rule2_branch_0 -j DROP # # Rule rule2_branch 1 (global) # echo "Rule rule2_branch 1 (global)" # $IPTABLES -A rule2_branch -s 222.222.222.0/24 -d 192.168.2.10 -m state --state NEW -j ACCEPT # # Rule rule2_branch 2 (global) # echo "Rule rule2_branch 2 (global)" # $IPTABLES -N rule2_branch_2 $IPTABLES -A rule2_branch -j rule2_branch_2 $IPTABLES -A rule2_branch_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A rule2_branch_2 -j DROP # ================ Table 'filter', rule set rule3_branch # # Rule rule3_branch 0 (eth1) # echo "Rule rule3_branch 0 (eth1)" # $IPTABLES -N rule3_branch $IPTABLES -A rule3_branch -i eth1 -d 22.22.23.22 -m state --state NEW -j ACCEPT $IPTABLES -A rule3_branch -i eth1 -d 192.168.1.22 -m state --state NEW -j ACCEPT $IPTABLES -A rule3_branch -i eth1 -d 192.168.2.1 -m state --state NEW -j ACCEPT # # Rule rule3_branch 1 (global) # echo "Rule rule3_branch 1 (global)" # $IPTABLES -N rule3_branch_1 $IPTABLES -A rule3_branch -j rule3_branch_1 $IPTABLES -A rule3_branch_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A rule3_branch_1 -j DROP # ================ Table 'filter', rule set rule4_branch # # Rule rule4_branch 0 (eth1) # echo "Rule rule4_branch 0 (eth1)" # $IPTABLES -N rule4_branch $IPTABLES -N In_rule4_branch_0 $IPTABLES -A rule4_branch -i eth1 -j In_rule4_branch_0 $IPTABLES -A In_rule4_branch_0 -j LOG --log-level info --log-prefix "RULE 0 -- BRANCH " $IPTABLES -A In_rule4_branch_0 -j rule_4_0_branch # # Rule rule4_branch 1 (eth0) # echo "Rule rule4_branch 1 (eth0)" # $IPTABLES -N In_rule4_branch_1 $IPTABLES -A rule4_branch -i eth0 -j In_rule4_branch_1 $IPTABLES -A In_rule4_branch_1 -j LOG --log-level info --log-prefix "RULE 1 -- BRANCH " $IPTABLES -A In_rule4_branch_1 -j rule_4_1_branch # ================ Table 'filter', rule set rule6_branch # # Rule rule6_branch 0 (global) # echo "Rule rule6_branch 0 (global)" # $IPTABLES -N rule6_branch $IPTABLES -N Policy $IPTABLES -A rule6_branch -j Policy # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p 50 -j rule0_branch $IPTABLES -A OUTPUT -p ah -j rule0_branch $IPTABLES -A INPUT -p 50 -j rule0_branch $IPTABLES -A INPUT -p ah -j rule0_branch $IPTABLES -A FORWARD -p 50 -j rule0_branch $IPTABLES -A FORWARD -p ah -j rule0_branch # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -p 50 -j RULE_1 $IPTABLES -A OUTPUT -p ah -j RULE_1 $IPTABLES -A INPUT -p 50 -j RULE_1 $IPTABLES -A INPUT -p ah -j RULE_1 $IPTABLES -A FORWARD -p 50 -j RULE_1 $IPTABLES -A FORWARD -p ah -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- BRANCH " $IPTABLES -A RULE_1 -j rule1_branch # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid445DA31230753.0 $IPTABLES -A OUTPUT -s ! 192.168.1.0/24 -j Cid445DA31230753.0 $IPTABLES -N RULE_2 $IPTABLES -A Cid445DA31230753.0 -p 50 -j RULE_2 $IPTABLES -A Cid445DA31230753.0 -p ah -j RULE_2 $IPTABLES -N Cid445DA31230753.1 $IPTABLES -A INPUT -s ! 192.168.1.0/24 -j Cid445DA31230753.1 $IPTABLES -A Cid445DA31230753.1 -p 50 -j RULE_2 $IPTABLES -A Cid445DA31230753.1 -p ah -j RULE_2 $IPTABLES -N Cid445DA31230753.2 $IPTABLES -A OUTPUT -s ! 192.168.1.0/24 -j Cid445DA31230753.2 $IPTABLES -A Cid445DA31230753.2 -p 50 -j RULE_2 $IPTABLES -A Cid445DA31230753.2 -p ah -j RULE_2 $IPTABLES -N Cid445DA31230753.3 $IPTABLES -A FORWARD -s ! 192.168.1.0/24 -j Cid445DA31230753.3 $IPTABLES -A Cid445DA31230753.3 -p 50 -j RULE_2 $IPTABLES -A Cid445DA31230753.3 -p ah -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- BRANCH " $IPTABLES -A RULE_2 -j rule2_branch # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # $IPTABLES -A INPUT -i eth1 -p 50 -j rule3_branch $IPTABLES -A INPUT -i eth1 -p ah -j rule3_branch $IPTABLES -A FORWARD -i eth1 -p 50 -j rule3_branch $IPTABLES -A FORWARD -i eth1 -p ah -j rule3_branch # # Rule 4 (eth1) # echo "Rule 4 (eth1)" # $IPTABLES -A OUTPUT -o eth1 -p 50 -j rule3_branch $IPTABLES -A OUTPUT -o eth1 -p ah -j rule3_branch $IPTABLES -A FORWARD -o eth1 -p 50 -j rule3_branch $IPTABLES -A FORWARD -o eth1 -p ah -j rule3_branch # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N rule5_branch $IPTABLES -A INPUT -s 192.168.1.0/24 -j rule5_branch $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j rule5_branch $IPTABLES -A FORWARD -s 192.168.1.0/24 -j rule5_branch # # Rule 7 (global) # echo "Rule 7 (global)" # # green rules branch # also in mangle table $IPTABLES -A OUTPUT -p 50 -j rule0_branch $IPTABLES -A OUTPUT -p ah -j rule0_branch $IPTABLES -A INPUT -p 50 -j rule0_branch $IPTABLES -A INPUT -p ah -j rule0_branch $IPTABLES -A FORWARD -p 50 -j rule0_branch $IPTABLES -A FORWARD -p ah -j rule0_branch # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -p 50 -j RULE_8 $IPTABLES -A OUTPUT -p ah -j RULE_8 $IPTABLES -A INPUT -p 50 -j RULE_8 $IPTABLES -A INPUT -p ah -j RULE_8 $IPTABLES -A FORWARD -p 50 -j RULE_8 $IPTABLES -A FORWARD -p ah -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- BRANCH " $IPTABLES -A RULE_8 -j rule1_branch # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid464C29BB3999.0 $IPTABLES -A OUTPUT -s ! 192.168.1.0/24 -j Cid464C29BB3999.0 $IPTABLES -N RULE_9 $IPTABLES -A Cid464C29BB3999.0 -p 50 -j RULE_9 $IPTABLES -A Cid464C29BB3999.0 -p ah -j RULE_9 $IPTABLES -N Cid464C29BB3999.1 $IPTABLES -A INPUT -s ! 192.168.1.0/24 -j Cid464C29BB3999.1 $IPTABLES -A Cid464C29BB3999.1 -p 50 -j RULE_9 $IPTABLES -A Cid464C29BB3999.1 -p ah -j RULE_9 $IPTABLES -N Cid464C29BB3999.2 $IPTABLES -A OUTPUT -s ! 192.168.1.0/24 -j Cid464C29BB3999.2 $IPTABLES -A Cid464C29BB3999.2 -p 50 -j RULE_9 $IPTABLES -A Cid464C29BB3999.2 -p ah -j RULE_9 $IPTABLES -N Cid464C29BB3999.3 $IPTABLES -A FORWARD -s ! 192.168.1.0/24 -j Cid464C29BB3999.3 $IPTABLES -A Cid464C29BB3999.3 -p 50 -j RULE_9 $IPTABLES -A Cid464C29BB3999.3 -p ah -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- BRANCH " $IPTABLES -A RULE_9 -j rule2_branch # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # $IPTABLES -A INPUT -i eth1 -p 50 -j rule3_branch $IPTABLES -A INPUT -i eth1 -p ah -j rule3_branch $IPTABLES -A FORWARD -i eth1 -p 50 -j rule3_branch $IPTABLES -A FORWARD -i eth1 -p ah -j rule3_branch # # Rule 11 (eth1) # echo "Rule 11 (eth1)" # $IPTABLES -A OUTPUT -o eth1 -p 50 -j rule3_branch $IPTABLES -A OUTPUT -o eth1 -p ah -j rule3_branch $IPTABLES -A FORWARD -o eth1 -p 50 -j rule3_branch $IPTABLES -A FORWARD -o eth1 -p ah -j rule3_branch # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -j rule4_branch # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -j rule5_branch $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j rule5_branch $IPTABLES -A FORWARD -s 192.168.1.0/24 -j rule5_branch # # Rule 14 (global) # echo "Rule 14 (global)" # # testing loop in branching rules $IPTABLES -A INPUT -s 192.168.1.0/24 -j rule6_branch $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j rule6_branch $IPTABLES -A FORWARD -s 192.168.1.0/24 -j rule6_branch # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -N RULE_16 $IPTABLES -A INPUT -s 222.222.222.0/24 -j RULE_16 $IPTABLES -A FORWARD -s 222.222.222.0/24 -j RULE_16 $IPTABLES -A RULE_16 -j LOG --log-level info --log-prefix "RULE 16 -- CUSTOM " $IPTABLES -A RULE_16 -j TARPIT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -N RULE_17 $IPTABLES -A OUTPUT -j RULE_17 $IPTABLES -A INPUT -j RULE_17 $IPTABLES -A FORWARD -j RULE_17 $IPTABLES -A RULE_17 -j LOG --log-level info --log-prefix "RULE 17 -- DENY " $IPTABLES -A RULE_17 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:49 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall32.fw.orig0000755000175000017500000002714311733011756022032 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:37 2012 PDT by vadim # # files: * firewall32.fw /etc/fw/firewall32.fw # # Compiled for iptables (any version) # # testing AddressTable FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" getaddr eth0.100 i_eth0_100 getaddr6 eth0.100 i_eth0_100_v6 getnet eth0.100 i_eth0_100_network getnet6 eth0.100 i_eth0_100_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -t nat -A PREROUTING -d $i_eth0_100 -j DNAT --to-destination 192.168.1.10 done # ================ Table 'filter', rule set Policy_fw32 # # Rule Policy_fw32 0 (eth0.100) # echo "Rule Policy_fw32 0 (eth0.100)" # for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A INPUT -i eth0.100 -s $i_eth0_100 -j DROP done $IPTABLES -A INPUT -i eth0.100 -s 192.168.1.0/24 -j DROP for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A FORWARD -i eth0.100 -s $i_eth0_100 -j DROP done $IPTABLES -A FORWARD -i eth0.100 -s 192.168.1.0/24 -j DROP # # Rule Policy_fw32 1 (global) # echo "Rule Policy_fw32 1 (global)" # $IPTABLES -A INPUT -s 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.3/30 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.200 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.201 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.2.128/25 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.3/30 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.200 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.201 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.2.128/25 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.3/30 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.200 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.201 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.2.128/25 -m state --state NEW -j ACCEPT # # Rule Policy_fw32 2 (global) # echo "Rule Policy_fw32 2 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule Policy_fw32 3 (global) # echo "Rule Policy_fw32 3 (global)" # $IPTABLES -N Policy_fw32_3 $IPTABLES -A OUTPUT -j Policy_fw32_3 $IPTABLES -A INPUT -j Policy_fw32_3 $IPTABLES -A FORWARD -j Policy_fw32_3 $IPTABLES -A Policy_fw32_3 -j LOG --log-level debug --log-prefix "RULE 3 -- DENY on global " $IPTABLES -A Policy_fw32_3 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:37 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/Makefile0000644000175000017500000000072211733011756020212 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_ipt -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_ipt -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/ipt/firewall38.fw.orig0000755000175000017500000004222211733011756022033 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:48 2012 PDT by vadim # # files: * firewall38.fw /etc/fw/firewall38.fw # # Compiled for iptables 1.3.0 # # testing TAG rules # using iptables-restore FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # ================ Table 'filter', rule set Policy # # Rule 1 (global) echo "-A OUTPUT -p 50 -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 1 -- CONTINUE \"" echo "-A OUTPUT -p ah -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 1 -- CONTINUE \"" echo "-A INPUT -p 50 -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 1 -- CONTINUE \"" echo "-A INPUT -p ah -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 1 -- CONTINUE \"" echo "-A FORWARD -p 50 -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 1 -- CONTINUE \"" echo "-A FORWARD -p ah -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 1 -- CONTINUE \"" # # Rule 2 (global) echo ":Cid43BBF1AD9745.0 - [0:0]" echo "-A OUTPUT -s ! 192.168.1.0/24 -m state --state NEW -j Cid43BBF1AD9745.0 " echo "-A Cid43BBF1AD9745.0 -p 50 -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo "-A Cid43BBF1AD9745.0 -p ah -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo ":Cid43BBF1AD9745.1 - [0:0]" echo "-A INPUT -s ! 192.168.1.0/24 -m state --state NEW -j Cid43BBF1AD9745.1 " echo "-A Cid43BBF1AD9745.1 -p 50 -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo "-A Cid43BBF1AD9745.1 -p ah -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo ":Cid43BBF1AD9745.2 - [0:0]" echo "-A OUTPUT -s ! 192.168.1.0/24 -m state --state NEW -j Cid43BBF1AD9745.2 " echo "-A Cid43BBF1AD9745.2 -p 50 -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo "-A Cid43BBF1AD9745.2 -p ah -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo ":Cid43BBF1AD9745.3 - [0:0]" echo "-A FORWARD -s ! 192.168.1.0/24 -m state --state NEW -j Cid43BBF1AD9745.3 " echo "-A Cid43BBF1AD9745.3 -p 50 -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" echo "-A Cid43BBF1AD9745.3 -p ah -j LOG --log-level info --log-prefix \"RULE 2 -- CONTINUE \"" # # Rule 5 (global) echo "-A INPUT -p tcp -m tcp -s 22.22.23.22 --dport 80 -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 5 -- CONTINUE \"" echo "-A OUTPUT -p tcp -m tcp -s 22.22.23.22 --dport 80 -m state --state NEW -j LOG --log-level info --log-prefix \"RULE 5 -- CONTINUE \"" # # Rule 9 (global) echo "-A OUTPUT -m mark --mark 16 -m state --state NEW -j ACCEPT " echo "-A INPUT -m mark --mark 16 -m state --state NEW -j ACCEPT " echo "-A FORWARD -m mark --mark 16 -m state --state NEW -j ACCEPT " # # Rule 10 (global) echo "-A OUTPUT -m mark ! --mark 16 -m state --state NEW -j ACCEPT " echo "-A INPUT -m mark ! --mark 16 -m state --state NEW -j ACCEPT " echo "-A FORWARD -m mark ! --mark 16 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo "-A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -m mark --mark 16 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT " echo "-A INPUT -m mark --mark 16 -m state --state NEW -j ACCEPT " echo "-A FORWARD -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT " echo "-A FORWARD -m mark --mark 16 -m state --state NEW -j ACCEPT " # # Rule 12 (global) echo ":Cid43EC87C832486.0 - [0:0]" echo "-A OUTPUT -m state --state NEW -j Cid43EC87C832486.0 " echo "-A INPUT -m state --state NEW -j Cid43EC87C832486.0 " echo "-A FORWARD -m state --state NEW -j Cid43EC87C832486.0 " echo "-A Cid43EC87C832486.0 -p tcp -m tcp --dport 80 -j RETURN " echo "-A Cid43EC87C832486.0 -m mark --mark 16 -j RETURN " echo "-A Cid43EC87C832486.0 -j ACCEPT " # # Rule 13 (global) echo "-A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 80 -j QUEUE " echo "-A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -j QUEUE " # # Rule 14 (global) echo "-A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 15 (global) echo ":RULE_15 - [0:0]" echo "-A OUTPUT -j RULE_15 " echo "-A INPUT -j RULE_15 " echo "-A FORWARD -j RULE_15 " echo "-A RULE_15 -j LOG --log-level info --log-prefix \"RULE 15 -- DENY \"" echo "-A RULE_15 -j DROP " # echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" # ================ Table 'mangle', rule set Policy # # Rule 0 (global) echo "-A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16" echo "-A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16" echo "-A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 16" echo "-A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 16" # # Rule 1 (global) echo "-A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16" echo "-A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16" echo "-A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 16" echo "-A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 16" # # Rule 2 (global) echo ":Cid43BBF1AD9745.0 - [0:0]" echo "-A OUTPUT -s ! 192.168.1.0/24 -m state --state NEW -j Cid43BBF1AD9745.0 " echo "-A Cid43BBF1AD9745.0 -p 50 -j MARK --set-mark 16" echo "-A Cid43BBF1AD9745.0 -p ah -j MARK --set-mark 16" echo ":Cid43BBF1AD9745.1 - [0:0]" echo "-A PREROUTING -s ! 192.168.1.0/24 -m state --state NEW -j Cid43BBF1AD9745.1 " echo "-A Cid43BBF1AD9745.1 -p 50 -j MARK --set-mark 16" echo "-A Cid43BBF1AD9745.1 -p ah -j MARK --set-mark 16" # # Rule 3 (eth1) echo "-A PREROUTING -i eth1 -p 50 -m state --state NEW -j MARK --set-mark 16" echo "-A PREROUTING -i eth1 -p ah -m state --state NEW -j MARK --set-mark 16" # # Rule 4 (global) # rule comment: rule 4 echo "-A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j MARK --set-mark 2" # # Rule 5 (global) echo "-A OUTPUT -p tcp -m tcp -s 22.22.23.22 --dport 80 -m state --state NEW -j MARK --set-mark 2" # # Rule 6 (eth1) echo "-A OUTPUT -o eth1 -p tcp -m tcp -s 22.22.23.22 --dport 80 -m state --state NEW -j MARK --set-mark 2" # # Rule 7 (eth1) echo "-A PREROUTING -i eth1 -p tcp -m tcp -s 22.22.23.22 --dport 80 -m state --state NEW -j MARK --set-mark 2" # # Rule 8 (eth1) echo ":Cid462EA8B230547.0 - [0:0]" echo "-A OUTPUT -o eth1 -p tcp -m tcp --dport 80 -m state --state NEW -j Cid462EA8B230547.0 " echo "-A Cid462EA8B230547.0 -s 22.22.23.22 -j RETURN " echo "-A Cid462EA8B230547.0 -j MARK --set-mark 2" echo "-A POSTROUTING -o eth1 -p tcp -m tcp --dport 80 -m state --state NEW -j MARK --set-mark 2" # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s 22.22.23.22 -j SNAT --to-source 22.22.23.22 " echo "-A POSTROUTING -o eth1 -s 192.168.1.22 -j SNAT --to-source 22.22.23.22 " echo "-A POSTROUTING -o eth1 -s 192.168.2.1 -j SNAT --to-source 22.22.23.22 " echo "-A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.22 " # # Rule 1 (NAT) echo "-A POSTROUTING -o eth1 -s 192.168.1.0/24 -m mark --mark 16 -j SNAT --to-source 22.22.23.22 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:48 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/test-shadowing-2.fw.orig0000755000175000017500000002705711733011756023163 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:40 2012 PDT by vadim # # files: * test-shadowing-2.fw /etc/test-shadowing-2.fw # # Compiled for iptables (any version) # # testing shadowing detection # compiler runs with -xt flag # firewall is NOT assumed to be part of any # test-shadowing-2:Policy:0: error: Rule '0 (eth0)' shadows rule '1 (eth0)' below it # test-shadowing-2:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # test-shadowing-2:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # test-shadowing-2:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # test-shadowing-2:Policy:4: error: Rule '4 (global)' shadows rule '5 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 eth2" for i in eth0 eth1 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 22.22.22.22/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # shades rule below # test-shadowing-2:Policy:0: error: Rule '0 (eth0)' shadows rule '1 (eth0)' below it $IPTABLES -A FORWARD -o eth0 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A FORWARD -o eth0 -s 192.168.1.10 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall is part # of any for this rule # test-shadowing-2:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # # this rule should shadow rule below it because # it uses IPService object with protocol 0 # test-shadowing-2:Policy:4: error: Rule '4 (global)' shadows rule '5 (global)' below it $IPTABLES -A FORWARD -p all -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 6667 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N RULE_6 $IPTABLES -A FORWARD -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:40 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/fw-A.fw.orig0000755000175000017500000005047211733011756020653 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:35 2012 PDT by vadim # # files: * fw-A.fw /sw/FWbuilder/fw-A.fw # # Compiled for iptables 1.3.0 # # fw-A:Routing:0: error: Object "gw_200" used as gateway in the routing rule 0 (main) is not reachable because it is not in any local network of the firewall # fw-A:Routing:0: error: Object "gw_200" used as gateway in the routing rule 0 (main) is not in the same local network as interface eth3 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG find_program $IFENSLAVE } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } missing_bond() { bond_intf=$1 cmd=$2 test "$cmd" = "down" && { echo "# Bring unconfigured bonding interface $bond_intf down" $FWBDEBUG $IP link set $bond_intf down } } missing_slave() { slave=$1 cmd=$2 oldIFS=$IFS IFS="@" set $slave intf=$1 bond_interface=$2 IFS=$oldIFS test "$cmd" = "-d" && { echo "# Delete bonding interface slave: $bond_interface $intf" $FWBDEBUG $IFENSLAVE -d $bond_interface $intf } || { echo "# Add bonding interface slave: $bond_interface $intf" $FWBDEBUG $IP link set $bond_interface up $FWBDEBUG $IFENSLAVE $bond_interface $intf } } load_bonding_module() { bonding_interfaces=$1 shift module_parameters=$* PROC_DIR="/proc/net/bonding/" test -d $PROC_DIR || { cmd="$MODPROBE bonding $module_parameters" test -n "$FWBDEBUG" && echo "# $cmd" || $cmd || { # Module load failed. cat </dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: bond0 eth2 eth3 bond1 lo eth6 eth0 eth1 bond0.2 bond0.1 eth2.201 eth2.202 eth4 eth5" for i in bond0 eth2 eth3 bond1 lo eth6 eth0 eth1 bond0.2 bond0.1 eth2.201 eth2.202 eth4 eth5 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces load_bonding_module "bond0 bond1" max_bonds=2 mode=802.3ad xmit_hash_policy=layer2 miimon=100 update_bonding bond0 eth0 eth1 update_bonding bond1 eth4 eth5 clear_bonding_except_known bond0 bond1 update_vlans_of_interface "bond0 bond0.2 bond0.1" update_vlans_of_interface "eth2 eth2.201 eth2.202" clear_vlans_except_known bond0.2@bond0 bond0.1@bond0 eth2.201@eth2 eth2.202@eth2 update_addresses_of_interface "eth3 192.0.2.11/24" "" update_addresses_of_interface "bond1 192.168.11.11/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth6 192.168.6.11/24" "" update_addresses_of_interface "bond0.2 192.168.2.11/24" "" update_addresses_of_interface "bond0.1 192.168.1.11/24" "" update_addresses_of_interface "eth2.201 192.168.201.11/24" "" update_addresses_of_interface "eth2.202 192.168.202.11/24" "" clear_addresses_except_known_interfaces bond0 eth2 eth3 bond1 lo eth6 eth0 eth1 bond0.2 bond0.1 eth2.201 eth2.202 eth4 eth5 } script_body() { echo 1 > /proc/sys/net/ipv4/ip_dynaddr echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 0 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 250000 > /proc/sys/net/ipv4/netfilter/ip_conntrack_max echo 250000 > /sys/module/ip_conntrack/parameters/hashsize echo 1 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v 'proto kernel' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # # fw-A:Routing:0: error: Object "gw_200" used as gateway in the routing rule 0 (main) is not in the same local network as interface eth3 # fw-A:Routing:0: error: Object "gw_200" used as gateway in the routing rule 0 (main) is not reachable because it is not in any local network of the firewall $IP route add default via 200.200.200.200 dev eth3 \ || route_command_error "0 (main)" # # Rule 1 (main) # echo "Routing rule 1 (main)" # # for 1410: gateway matches subnet of a vlan interface # $IP route add 192.168.101.0/24 via 192.168.1.200 dev bond0.1 \ || route_command_error "1 (main)" # # Rule 2 (main) # echo "Routing rule 2 (main)" # # for 1410: gateway matches subnet of a vlan interface # $IP route add 192.168.102.0/24 via 192.168.2.200 dev bond0.2 \ || route_command_error "2 (main)" # # Rule 3 (main) # echo "Routing rule 3 (main)" # # # $IP route add 192.168.111.0/24 via 192.168.11.200 dev bond1 \ || route_command_error "3 (main)" # # Rule 4 (main) # echo "Routing rule 4 (main)" # # for 1410: gateway matches subnet of a vlan interface # $IP route add 192.168.211.0/24 via 192.168.201.200 dev eth2.201 \ || route_command_error "4 (main)" # # Rule 5 (main) # echo "Routing rule 5 (main)" # # for 1410: gateway matches subnet of a vlan interface # $IP route add 192.168.212.0/24 via 192.168.202.200 dev eth2.202 \ || route_command_error "5 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:35 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall6.fw.orig0000755000175000017500000004157511733011756021760 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:58 2012 PDT by vadim # # files: * firewall6.fw /etc/fw/firewall6.fw # # Compiled for iptables (any version) # # testing rule with firewall in dst and negation # also testing "Destination NAT Onto the Same Network" per Turorial chapter 3.5 # testing a rule with src=dst=firewall6 in the global policy (should use all interfaces including loopback) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth3 22.22.23.23/24 22.22.23.24/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.20 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.24 --dport 80 -j DNAT --to-destination 192.168.1.20 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # this is SDNAT rule, it translates # both source and destination # this rule should be equivalent to two rules above $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 -d 22.22.23.24 --dport 80 -j DNAT --to-destination 192.168.1.20 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.20 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.11-192.168.1.12 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.11 --dport 80 -j SNAT --to-source 192.168.1.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.12 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.11-192.168.1.12 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.11 --dport 80 -j SNAT --to-source 192.168.1.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.12 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.11-192.168.1.12 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.11-192.168.1.12 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.11-192.168.1.12 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 80 -j DNAT --to-destination 192.168.1.11-192.168.1.12 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.11 --dport 80 -j SNAT --to-source 192.168.1.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.12 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.100 --dport 80 -j DNAT --to-destination 192.168.1.100:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s ! 192.168.1.100 -d 192.168.1.100 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -N Cid3F9F8382.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j Cid3F9F8382.0 $IPTABLES -t nat -A Cid3F9F8382.0 -d 222.222.222.40 -j RETURN $IPTABLES -t nat -A Cid3F9F8382.0 -d 222.222.222.41 -j RETURN $IPTABLES -t nat -A Cid3F9F8382.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.100:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.100 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # $IPTABLES -N Cid3C699028.0 $IPTABLES -A INPUT -i eth1 -j Cid3C699028.0 $IPTABLES -A Cid3C699028.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3C699028.0 -d 22.22.23.23 -j RETURN $IPTABLES -A Cid3C699028.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3C699028.0 -d 192.168.2.1 -j RETURN $IPTABLES -N In_RULE_0_3 $IPTABLES -A Cid3C699028.0 -j In_RULE_0_3 $IPTABLES -A In_RULE_0_3 -j LOG --log-level debug --log-prefix "RULE 0 -- DENY global" $IPTABLES -A In_RULE_0_3 -j DROP $IPTABLES -N In_RULE_0 $IPTABLES -A FORWARD -i eth1 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level debug --log-prefix "RULE 0 -- DENY global" $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N Cid3C698FB2.0 $IPTABLES -A INPUT -j Cid3C698FB2.0 $IPTABLES -A Cid3C698FB2.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3C698FB2.0 -d 22.22.23.23 -j RETURN $IPTABLES -A Cid3C698FB2.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3C698FB2.0 -d 192.168.2.1 -j RETURN $IPTABLES -N In_RULE_1_3 $IPTABLES -A Cid3C698FB2.0 -j In_RULE_1_3 $IPTABLES -A In_RULE_1_3 -j LOG --log-level debug --log-prefix "RULE 1 -- DENY global" $IPTABLES -A In_RULE_1_3 -j DROP $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -j RULE_1 $IPTABLES -A FORWARD -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level debug --log-prefix "RULE 1 -- DENY global" $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid3E9C86DD.0 $IPTABLES -A INPUT -s 22.22.22.22 -m state --state NEW -j Cid3E9C86DD.0 $IPTABLES -A INPUT -s 22.22.23.23 -m state --state NEW -j Cid3E9C86DD.0 $IPTABLES -A INPUT -s 127.0.0.1 -m state --state NEW -j Cid3E9C86DD.0 $IPTABLES -A INPUT -s 192.168.1.1 -m state --state NEW -j Cid3E9C86DD.0 $IPTABLES -A INPUT -s 192.168.2.1 -m state --state NEW -j Cid3E9C86DD.0 $IPTABLES -A Cid3E9C86DD.0 -d 22.22.22.22 -j ACCEPT $IPTABLES -A Cid3E9C86DD.0 -d 22.22.23.23 -j ACCEPT $IPTABLES -A Cid3E9C86DD.0 -d 127.0.0.1 -j ACCEPT $IPTABLES -A Cid3E9C86DD.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E9C86DD.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -N Cid3E9C86DD.1 $IPTABLES -A OUTPUT -s 22.22.22.22 -m state --state NEW -j Cid3E9C86DD.1 $IPTABLES -A OUTPUT -s 22.22.23.23 -m state --state NEW -j Cid3E9C86DD.1 $IPTABLES -A OUTPUT -s 127.0.0.1 -m state --state NEW -j Cid3E9C86DD.1 $IPTABLES -A OUTPUT -s 192.168.1.1 -m state --state NEW -j Cid3E9C86DD.1 $IPTABLES -A OUTPUT -s 192.168.2.1 -m state --state NEW -j Cid3E9C86DD.1 $IPTABLES -A Cid3E9C86DD.1 -d 22.22.22.22 -j ACCEPT $IPTABLES -A Cid3E9C86DD.1 -d 22.22.23.23 -j ACCEPT $IPTABLES -A Cid3E9C86DD.1 -d 127.0.0.1 -j ACCEPT $IPTABLES -A Cid3E9C86DD.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E9C86DD.1 -d 192.168.2.1 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid141025X15403.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j Cid141025X15403.0 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j Cid141025X15403.0 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j Cid141025X15403.0 $IPTABLES -A Cid141025X15403.0 -d 222.222.222.40 -j RETURN $IPTABLES -A Cid141025X15403.0 -d 222.222.222.41 -j RETURN $IPTABLES -A Cid141025X15403.0 -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:58 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall24.fw.orig0000755000175000017500000003243311733011756022031 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:28 2012 PDT by vadim # # files: * firewall24.fw /etc/fw/firewall24.fw # # Compiled for iptables (any version) # # testing rules on unnumbered interface tun* FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0 192.168.1.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (tun*) # echo "Rule 0 (tun*)" # $IPTABLES -A INPUT -i tun+ -m state --state NEW -j ACCEPT # # Rule 1 (tun*) # echo "Rule 1 (tun*)" # $IPTABLES -A INPUT -i tun+ -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i tun+ -m state --state NEW -j ACCEPT # # Rule 2 (tun*) # echo "Rule 2 (tun*)" # $IPTABLES -A OUTPUT -o tun+ -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o tun+ -m state --state NEW -j ACCEPT # # Rule 3 (tun*) # echo "Rule 3 (tun*)" # $IPTABLES -A INPUT -i tun+ -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i tun+ -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o tun+ -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o tun+ -m state --state NEW -j ACCEPT # # Rule 4 (tun*) # echo "Rule 4 (tun*)" # $IPTABLES -A INPUT -i tun+ -p udp -m udp -m multiport --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i tun+ -p udp -m udp -m multiport --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 5 (tun*) # echo "Rule 5 (tun*)" # $IPTABLES -A INPUT -i tun+ -d 192.168.1.255 -m state --state NEW -j ACCEPT # # Rule 6 (tun*) # echo "Rule 6 (tun*)" # $IPTABLES -A INPUT -i tun+ -d 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 7 (tun*) # echo "Rule 7 (tun*)" # $IPTABLES -A INPUT -i tun+ -d 224.0.1.141 -m state --state NEW -j ACCEPT # # Rule 8 (tun*) # echo "Rule 8 (tun*)" # $IPTABLES -A INPUT -i tun+ -d 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i tun+ -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 9 (tun*) # echo "Rule 9 (tun*)" # $IPTABLES -A INPUT -i tun+ -d ! 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i tun+ -d ! 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.10 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 192.168.1.10 --dport 68 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 192.168.1.0 --dport 68 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A OUTPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A OUTPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -N RULE_16 $IPTABLES -A OUTPUT -d 192.168.1.10 -j RULE_16 $IPTABLES -A FORWARD -d 192.168.1.10 -j RULE_16 $IPTABLES -A RULE_16 -j LOG --log-level debug $IPTABLES -A RULE_16 -j DROP # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:28 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall14.fw.orig0000755000175000017500000002626411733011756022035 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:11 2012 PDT by vadim # # files: * firewall14.fw /etc/fw/firewall14.fw # # Compiled for iptables (any version) # # special configuration with overlapping subnets on external and dmz interfaces # testing NAT rules (especially choice of interfaces for -o ) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24 22.22.23.160/24 22.22.23.40/24" "" update_addresses_of_interface "eth2 22.22.23.132/25" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.160 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d ! 22.22.23.128/25 -j SNAT --to-source 22.22.23.160 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 22.22.23.128/25 -j SNAT --to-source 22.22.23.132 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 22.22.23.128/25 -j SNAT --to-source 22.22.23.132 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # # I guess this rule does not make much sense $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d 22.22.23.128/25 -j SNAT --to-source 22.22.23.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d 22.22.23.128/25 -j SNAT --to-source 22.22.23.160 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -d 22.22.23.128/25 -j SNAT --to-source 22.22.23.22 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -d 22.22.23.128/25 -j SNAT --to-source 22.22.23.40 } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:11 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall2-6.fw.orig0000755000175000017500000003700311733011756022106 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:31 2012 PDT by vadim # # files: * firewall2-6.fw /etc/fw/firewall2-6.fw # # Compiled for iptables (any version) # # tests for nat rules with inbound and outbound interfaces # firewall2-6:NAT:6: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:7: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:8: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:9: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:10: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:11: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:12: error: Can not use inbound interface specification with rules that translate source because iptables does not allow "-i" in POSTROUTING chain # firewall2-6:NAT:17: error: Can not use outbound interface specification with rules that translate destination because iptables does not allow "-o" in PREROUTING chain # firewall2-6:NAT:17: error: Can not use outbound interface specification with rules that translate destination because iptables does not allow "-o" in PREROUTING chain # firewall2-6:NAT:18: error: Can not use outbound interface specification with rules that translate destination because iptables does not allow "-o" in PREROUTING chain # firewall2-6:NAT:19: error: Can not use outbound interface specification with rules that translate destination because iptables does not allow "-o" in PREROUTING chain # firewall2-6:NAT:20: error: Can not use outbound interface specification with rules that translate destination because iptables does not allow "-o" in PREROUTING chain # firewall2-6:NAT:21: error: Can not use outbound interface specification with rules that translate destination because iptables does not allow "-o" in PREROUTING chain # firewall2-6::: warning: Can not add virtual address 22.22.22.0 (object external_net) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24 222.222.222.40/24" "" update_addresses_of_interface "eth3 33.33.33.25/29" "" update_addresses_of_interface "eth2 33.33.33.3/29 33.33.33.4/29" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # NETMAP and no -o itf $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o ! eth3 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 222.222.222.40 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -d 222.222.222.40 -j DNAT --to-destination 192.168.1.10 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # $IPTABLES -t nat -A PREROUTING -i eth1 -d 222.222.222.40 -j DNAT --to-destination 192.168.1.10 # # Rule 15 (NAT) # echo "Rule 15 (NAT)" # $IPTABLES -t nat -A PREROUTING -i eth3 -d 222.222.222.40 -j DNAT --to-destination 192.168.1.10 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # $IPTABLES -t nat -A PREROUTING -i eth1 -d 222.222.222.40 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -i eth3 -d 222.222.222.40 -j DNAT --to-destination 192.168.1.10 # # Rule 22 (NAT) # echo "Rule 22 (NAT)" # # rule for SF feature request 1954286 $IPTABLES -t nat -A PREROUTING -i eth2 -p tcp -m tcp --dport 3996:4000 -j DNAT --to-destination 192.168.1.10 # # Rule 23 (NAT) # echo "Rule 23 (NAT)" # # REDIRECT $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # 'catch all' rule $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 0 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:31 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall73.fw.orig0000755000175000017500000003207511733011756022037 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:08 2012 PDT by vadim # # files: * firewall73.fw /etc/fw/firewall73.fw # # Compiled for iptables 1.4.3 # # testing for "-i +" that is generated # when interface rule element is "any" # but direction is inbound. Trying different # combinations. Bug 2822098 # "Firewall is part of any" is on FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 33.33.33.33/24" "" update_addresses_of_interface "eth1 172.16.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -j DROP $IPTABLES -A FORWARD -i eth0 -j DROP $IPTABLES -A OUTPUT -o eth0 -j DROP $IPTABLES -A FORWARD -o eth0 -j DROP # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A INPUT -i eth0 -j DROP $IPTABLES -A FORWARD -i eth0 -j DROP # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # $IPTABLES -A OUTPUT -o eth0 -j DROP $IPTABLES -A FORWARD -o eth0 -j DROP # # Rule 3 (lo) # echo "Rule 3 (lo)" # $IPTABLES -A INPUT -i lo -j DROP $IPTABLES -A OUTPUT -o lo -j DROP # # Rule 4 (lo) # echo "Rule 4 (lo)" # $IPTABLES -A INPUT -i lo -j DROP # # Rule 5 (lo) # echo "Rule 5 (lo)" # $IPTABLES -A OUTPUT -o lo -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -A OUTPUT -j DROP $IPTABLES -A INPUT -j DROP $IPTABLES -A FORWARD -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -j DROP $IPTABLES -A FORWARD -i + -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -j DROP $IPTABLES -A FORWARD -o + -j DROP # # Rule 9 (eth0) # echo "Rule 9 (eth0)" # $IPTABLES -A INPUT -i eth0 -j DROP $IPTABLES -A OUTPUT -o eth0 -d 33.33.33.33 -j DROP $IPTABLES -A OUTPUT -o eth0 -d 172.16.1.1 -j DROP # # Rule 10 (eth0) # echo "Rule 10 (eth0)" # $IPTABLES -A INPUT -i eth0 -j DROP # # Rule 11 (eth0) # echo "Rule 11 (eth0)" # $IPTABLES -A OUTPUT -o eth0 -d 33.33.33.33 -j DROP $IPTABLES -A OUTPUT -o eth0 -d 172.16.1.1 -j DROP # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A OUTPUT -d 33.33.33.33 -j DROP $IPTABLES -A OUTPUT -d 172.16.1.1 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A INPUT -j DROP # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A OUTPUT -d 33.33.33.33 -j DROP $IPTABLES -A OUTPUT -d 172.16.1.1 -j DROP $IPTABLES -A FORWARD -o + -d 33.33.33.33 -j DROP $IPTABLES -A FORWARD -o + -d 172.16.1.1 -j DROP # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # $IPTABLES -A INPUT -i eth0 -s 33.33.33.33 -j DROP $IPTABLES -A INPUT -i eth0 -s 172.16.1.1 -j DROP $IPTABLES -A FORWARD -i eth0 -s 33.33.33.33 -j DROP $IPTABLES -A FORWARD -i eth0 -s 172.16.1.1 -j DROP $IPTABLES -A OUTPUT -o eth0 -j DROP # # Rule 16 (eth0) # echo "Rule 16 (eth0)" # $IPTABLES -A INPUT -i eth0 -s 33.33.33.33 -j DROP $IPTABLES -A INPUT -i eth0 -s 172.16.1.1 -j DROP $IPTABLES -A FORWARD -i eth0 -s 33.33.33.33 -j DROP $IPTABLES -A FORWARD -i eth0 -s 172.16.1.1 -j DROP # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # $IPTABLES -A OUTPUT -o eth0 -j DROP # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -A INPUT -s 33.33.33.33 -j DROP $IPTABLES -A INPUT -s 172.16.1.1 -j DROP $IPTABLES -A OUTPUT -j DROP # # Rule 19 (global) # echo "Rule 19 (global)" # $IPTABLES -A INPUT -s 33.33.33.33 -j DROP $IPTABLES -A INPUT -s 172.16.1.1 -j DROP $IPTABLES -A FORWARD -i + -s 33.33.33.33 -j DROP $IPTABLES -A FORWARD -i + -s 172.16.1.1 -j DROP # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -A OUTPUT -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:08 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall37-2.fw.orig0000755000175000017500000005566511733011756022210 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:47 2012 PDT by vadim # # files: * firewall37-2.fw /etc/fw/firewall37-2.fw # # Compiled for iptables (any version) # # testing TAG and CLASSIFY rules and combinations # normal script mode (not using iptables-restore) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', rule set classify_2 # # Rule classify_2 0 (global) # echo "Rule classify_2 0 (global)" # $IPTABLES -N classify_2 -t mangle $IPTABLES -t mangle -A classify_2 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:12 # ================ Table 'mangle', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j CLASSIFY --set-class 1:2 # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j CLASSIFY --set-class 1:2 # # Rule 3 (eth0) # echo "Rule 3 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 4 (eth0) # echo "Rule 4 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s ! 192.168.1.0/24 -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s ! 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 5 (eth0) # echo "Rule 5 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s ! 192.168.1.0/24 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s ! 192.168.1.0/24 -m state --state NEW -j CLASSIFY --set-class 1:2 # # Rule 6 (eth0) # echo "Rule 6 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s ! 192.168.1.0/24 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s ! 192.168.1.0/24 -m state --state NEW -j CLASSIFY --set-class 1:2 # # Rule 7 (eth0) # echo "Rule 7 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -s ! 192.168.1.0/24 -j MARK --set-mark 2 $IPTABLES -t mangle -A POSTROUTING -i eth0 -s ! 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 8 (eth0) # echo "Rule 8 (eth0)" # $IPTABLES -N Cid591898X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -j Cid591898X26049.0 $IPTABLES -t mangle -A Cid591898X26049.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591898X26049.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591898X26049.0 -j MARK --set-mark 2 $IPTABLES -N Cid591898X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -j Cid591898X26049.1 $IPTABLES -t mangle -A Cid591898X26049.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591898X26049.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591898X26049.1 -j CLASSIFY --set-class 1:2 # # Rule 9 (eth0) # echo "Rule 9 (eth0)" # $IPTABLES -N Cid591842X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -m state --state NEW -j Cid591842X26049.0 $IPTABLES -t mangle -A Cid591842X26049.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591842X26049.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591842X26049.0 -j MARK --set-mark 2 $IPTABLES -N Cid591842X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -m state --state NEW -j Cid591842X26049.1 $IPTABLES -t mangle -A Cid591842X26049.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591842X26049.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591842X26049.1 -j CLASSIFY --set-class 1:2 # # Rule 10 (eth0) # echo "Rule 10 (eth0)" # $IPTABLES -N Cid591786X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -m state --state NEW -j Cid591786X26049.0 $IPTABLES -t mangle -A Cid591786X26049.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591786X26049.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591786X26049.0 -j MARK --set-mark 2 $IPTABLES -N Cid591786X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -m state --state NEW -j Cid591786X26049.1 $IPTABLES -t mangle -A Cid591786X26049.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591786X26049.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591786X26049.1 -j CLASSIFY --set-class 1:2 # # Rule 11 (eth0) # echo "Rule 11 (eth0)" # $IPTABLES -N Cid591730X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -j Cid591730X26049.0 $IPTABLES -t mangle -A Cid591730X26049.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591730X26049.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591730X26049.0 -j MARK --set-mark 2 $IPTABLES -N Cid591730X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -j Cid591730X26049.1 $IPTABLES -t mangle -A Cid591730X26049.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid591730X26049.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid591730X26049.1 -j CLASSIFY --set-class 1:2 # # Rule 12 (eth0) # echo "Rule 12 (eth0)" # $IPTABLES -N Cid994929X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -j Cid994929X26049.0 $IPTABLES -t mangle -A Cid994929X26049.0 -p icmp -m icmp --icmp-type 8/0 -j MARK --set-mark 2 $IPTABLES -t mangle -A Cid994929X26049.0 -p tcp -m tcp --dport 80 -j MARK --set-mark 2 $IPTABLES -N Cid994929X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -j Cid994929X26049.1 $IPTABLES -t mangle -A Cid994929X26049.1 -p icmp -m icmp --icmp-type 8/0 -j CLASSIFY --set-class 1:2 $IPTABLES -t mangle -A Cid994929X26049.1 -p tcp -m tcp --dport 80 -j CLASSIFY --set-class 1:2 # # Rule 13 (eth0) # echo "Rule 13 (eth0)" # $IPTABLES -N Cid994873X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j Cid994873X26049.0 $IPTABLES -t mangle -A Cid994873X26049.0 -p icmp -m icmp --icmp-type 8/0 -j MARK --set-mark 2 $IPTABLES -t mangle -A Cid994873X26049.0 -p tcp -m tcp --dport 80 -j MARK --set-mark 2 $IPTABLES -N Cid994873X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j Cid994873X26049.1 $IPTABLES -t mangle -A Cid994873X26049.1 -p icmp -m icmp --icmp-type 8/0 -j CLASSIFY --set-class 1:2 $IPTABLES -t mangle -A Cid994873X26049.1 -p tcp -m tcp --dport 80 -j CLASSIFY --set-class 1:2 # # Rule 14 (eth0) # echo "Rule 14 (eth0)" # $IPTABLES -N Cid994817X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j Cid994817X26049.0 $IPTABLES -t mangle -A Cid994817X26049.0 -p icmp -m icmp --icmp-type 8/0 -j MARK --set-mark 2 $IPTABLES -t mangle -A Cid994817X26049.0 -p tcp -m tcp --dport 80 -j MARK --set-mark 2 $IPTABLES -N Cid994817X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -m state --state NEW -j Cid994817X26049.1 $IPTABLES -t mangle -A Cid994817X26049.1 -p icmp -m icmp --icmp-type 8/0 -j CLASSIFY --set-class 1:2 $IPTABLES -t mangle -A Cid994817X26049.1 -p tcp -m tcp --dport 80 -j CLASSIFY --set-class 1:2 # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # $IPTABLES -N Cid994761X26049.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -j Cid994761X26049.0 $IPTABLES -t mangle -A Cid994761X26049.0 -p icmp -m icmp --icmp-type 8/0 -j MARK --set-mark 2 $IPTABLES -t mangle -A Cid994761X26049.0 -p tcp -m tcp --dport 80 -j MARK --set-mark 2 $IPTABLES -N Cid994761X26049.1 -t mangle $IPTABLES -t mangle -A POSTROUTING -i eth0 -s 192.168.1.0/24 -j Cid994761X26049.1 $IPTABLES -t mangle -A Cid994761X26049.1 -p icmp -m icmp --icmp-type 8/0 -j CLASSIFY --set-class 1:2 $IPTABLES -t mangle -A Cid994761X26049.1 -p tcp -m tcp --dport 80 -j CLASSIFY --set-class 1:2 # # Rule 16 (global) # echo "Rule 16 (global)" # # test for #2405 # branching in mangle; branch rule set # uses CLASSIFY that is ivalid in PREROUTING # "Assume fw is part of any" is off for this rule $IPTABLES -t mangle -A PREROUTING -j classify_2 $IPTABLES -t mangle -A POSTROUTING -j classify_2 $IPTABLES -t mangle -A FORWARD -j classify_2 # # Rule 17 (global) # echo "Rule 17 (global)" # # test for #2405 # branching in mangle; branch rule set # uses CLASSIFY that is ivalid in PREROUTING # "Assume fw is part of any" is off for this rule # Should create branch in OUTPUT instead of # enumerating all ip addresses of the fw in PREROUTING $IPTABLES -t mangle -A PREROUTING -s 22.22.23.22 -j classify_2 $IPTABLES -t mangle -A PREROUTING -s 192.168.1.22 -j classify_2 $IPTABLES -t mangle -A PREROUTING -s 192.168.2.1 -j classify_2 $IPTABLES -t mangle -A POSTROUTING -s 22.22.23.22 -j classify_2 $IPTABLES -t mangle -A POSTROUTING -s 192.168.1.22 -j classify_2 $IPTABLES -t mangle -A POSTROUTING -s 192.168.2.1 -j classify_2 $IPTABLES -t mangle -A FORWARD -s 22.22.23.22 -j classify_2 $IPTABLES -t mangle -A FORWARD -s 192.168.1.22 -j classify_2 $IPTABLES -t mangle -A FORWARD -s 192.168.2.1 -j classify_2 # ================ Table 'filter', rule set Policy # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 3 (eth0) # echo "Rule 3 (eth0)" # $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -j ACCEPT # # Rule 5 (eth0) # echo "Rule 5 (eth0)" # $IPTABLES -A INPUT -i eth0 -s ! 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth0 -s ! 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 7 (eth0) # echo "Rule 7 (eth0)" # $IPTABLES -A INPUT -i eth0 -s ! 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -s ! 192.168.1.0/24 -j ACCEPT # # Rule 9 (eth0) # echo "Rule 9 (eth0)" # $IPTABLES -N Cid591842X26049.0 $IPTABLES -A INPUT -i eth0 -m state --state NEW -j Cid591842X26049.0 $IPTABLES -A FORWARD -i eth0 -m state --state NEW -j Cid591842X26049.0 $IPTABLES -A Cid591842X26049.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid591842X26049.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid591842X26049.0 -j ACCEPT # # Rule 11 (eth0) # echo "Rule 11 (eth0)" # $IPTABLES -N Cid591730X26049.0 $IPTABLES -A INPUT -i eth0 -j Cid591730X26049.0 $IPTABLES -A FORWARD -i eth0 -j Cid591730X26049.0 $IPTABLES -A Cid591730X26049.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid591730X26049.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid591730X26049.0 -j ACCEPT # # Rule 13 (eth0) # echo "Rule 13 (eth0)" # $IPTABLES -N Cid994873X26049.0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j Cid994873X26049.0 $IPTABLES -A Cid994873X26049.0 -p icmp -m icmp --icmp-type 8/0 -j ACCEPT $IPTABLES -A Cid994873X26049.0 -p tcp -m tcp --dport 80 -j ACCEPT $IPTABLES -N Cid994873X26049.1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j Cid994873X26049.1 $IPTABLES -A Cid994873X26049.1 -p icmp -m icmp --icmp-type 8/0 -j ACCEPT $IPTABLES -A Cid994873X26049.1 -p tcp -m tcp --dport 80 -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # $IPTABLES -N Cid994761X26049.0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -j Cid994761X26049.0 $IPTABLES -A Cid994761X26049.0 -p icmp -m icmp --icmp-type 8/0 -j ACCEPT $IPTABLES -A Cid994761X26049.0 -p tcp -m tcp --dport 80 -j ACCEPT $IPTABLES -N Cid994761X26049.1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -j Cid994761X26049.1 $IPTABLES -A Cid994761X26049.1 -p icmp -m icmp --icmp-type 8/0 -j ACCEPT $IPTABLES -A Cid994761X26049.1 -p tcp -m tcp --dport 80 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # test for #2405 # branching in mangle; branch rule set # uses CLASSIFY that is ivalid in PREROUTING # "Assume fw is part of any" is off for this rule $IPTABLES -N classify_2 $IPTABLES -A FORWARD -j classify_2 # # Rule 17 (global) # echo "Rule 17 (global)" # # test for #2405 # branching in mangle; branch rule set # uses CLASSIFY that is ivalid in PREROUTING # "Assume fw is part of any" is off for this rule # Should create branch in OUTPUT instead of # enumerating all ip addresses of the fw in PREROUTING $IPTABLES -A OUTPUT -j classify_2 # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -N RULE_18 $IPTABLES -A OUTPUT -j RULE_18 $IPTABLES -A INPUT -j RULE_18 $IPTABLES -A FORWARD -j RULE_18 $IPTABLES -A RULE_18 -j LOG --log-level info --log-prefix "RULE 18 -- DENY " $IPTABLES -A RULE_18 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:47 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall61-1.4.fw.orig0000755000175000017500000003512111733011756022327 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:02 2012 PDT by vadim # # files: * firewall61-1.4.fw /etc/firewall61-1.4.fw # # Compiled for iptables 1.4.0 # # testing time litmiting for iptables 1.4.0 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'mangle', rule set fw61-Policy # # Rule fw61-Policy 0 (global) # echo "Rule fw61-Policy 0 (global)" # $IPTABLES -N fw61-Policy -t mangle $IPTABLES -N fw61-Policy_0 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --weekdays Sat -j fw61-Policy_0 $IPTABLES -t mangle -A fw61-Policy_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -t mangle -A fw61-Policy_0 -j DROP # # Rule fw61-Policy 1 (global) # echo "Rule fw61-Policy 1 (global)" # $IPTABLES -N fw61-Policy_1 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --weekdays Sun -j fw61-Policy_1 $IPTABLES -t mangle -A fw61-Policy_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -t mangle -A fw61-Policy_1 -j DROP # # Rule fw61-Policy 2 (global) # echo "Rule fw61-Policy 2 (global)" # $IPTABLES -N fw61-Policy_2 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 18:00 --timestop 23:59 -j fw61-Policy_2 $IPTABLES -t mangle -A fw61-Policy_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -t mangle -A fw61-Policy_2 -j DROP # # Rule fw61-Policy 3 (global) # echo "Rule fw61-Policy 3 (global)" # $IPTABLES -N fw61-Policy_3 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --weekdays Sat,Sun -j fw61-Policy_3 $IPTABLES -t mangle -A fw61-Policy_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -t mangle -A fw61-Policy_3 -j DROP # # Rule fw61-Policy 4 (global) # echo "Rule fw61-Policy 4 (global)" # $IPTABLES -N fw61-Policy_4 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 09:00 --timestop 17:00 --weekdays Mon,Tue,Wed,Thu,Fri -j fw61-Policy_4 $IPTABLES -t mangle -A fw61-Policy_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -t mangle -A fw61-Policy_4 -j DROP # # Rule fw61-Policy 5 (global) # echo "Rule fw61-Policy 5 (global)" # $IPTABLES -N fw61-Policy_5 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:01 --timestop 02:02 --weekdays Sun,Mon -j fw61-Policy_5 $IPTABLES -t mangle -A fw61-Policy_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -t mangle -A fw61-Policy_5 -j DROP # # Rule fw61-Policy 6 (global) # echo "Rule fw61-Policy 6 (global)" # $IPTABLES -N fw61-Policy_6 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --datestart 2008-03-13T01:01:00 --datestop 2010-01-01T02:02:00 --weekdays Sun,Mon -j fw61-Policy_6 $IPTABLES -t mangle -A fw61-Policy_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -t mangle -A fw61-Policy_6 -j DROP # # Rule fw61-Policy 7 (global) # echo "Rule fw61-Policy 7 (global)" # $IPTABLES -N fw61-Policy_7 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --datestart 2008-03-13T00:00:00 --datestop 2010-01-01T01:00:00 --weekdays Fri,Sat -j fw61-Policy_7 $IPTABLES -t mangle -A fw61-Policy_7 -j LOG --log-level info --log-prefix "RULE 7 -- DENY " $IPTABLES -t mangle -A fw61-Policy_7 -j DROP # # Rule fw61-Policy 8 (global) # echo "Rule fw61-Policy 8 (global)" # $IPTABLES -N fw61-Policy_8 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:00 --timestop 02:00 --weekdays Fri,Sat -j fw61-Policy_8 $IPTABLES -t mangle -A fw61-Policy_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -t mangle -A fw61-Policy_8 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- BRANCH " $IPTABLES -N fw61-Policy $IPTABLES -A RULE_0 -j fw61-Policy # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IP6TABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'filter', rule set Policy_ipv6 # # Rule Policy_ipv6 0 (global) # echo "Rule Policy_ipv6 0 (global)" # $IP6TABLES -N Policy_ipv6_0 $IP6TABLES -A OUTPUT -j Policy_ipv6_0 $IP6TABLES -A INPUT -j Policy_ipv6_0 $IP6TABLES -A FORWARD -j Policy_ipv6_0 $IP6TABLES -A Policy_ipv6_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IP6TABLES -A Policy_ipv6_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:02 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall40.fw.orig0000755000175000017500000003115311733011756022025 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:50 2012 PDT by vadim # # files: * firewall40.fw /etc/firewall40.fw # # Compiled for iptables 1.4.0 # # more complex and realistic combination of Tag and Route rules # firewall40:Policy:3: error: Option Route is deprecated. You can use Custom Action to generate iptables command using '-j ROUTE' target if it is supported by your firewall OS # firewall40:Policy:4: error: Option Route is deprecated. You can use Custom Action to generate iptables command using '-j ROUTE' target if it is supported by your firewall OS FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 lo eth2 eth1" for i in eth0 lo eth2 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.0.100.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # Translate source address # for outgoing connections $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 # ================ Table 'mangle', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -t mangle -A PREROUTING -i eth0 -m state --state NEW -j MARK --set-mark 1 $IPTABLES -t mangle -A PREROUTING -i eth0 -m state --state NEW -j CONNMARK --save-mark # # Rule 1 (eth2) # echo "Rule 1 (eth2)" # $IPTABLES -t mangle -A PREROUTING -i eth2 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A PREROUTING -i eth2 -m state --state NEW -j CONNMARK --save-mark # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid37084X26841.0 -t mangle $IPTABLES -t mangle -A PREROUTING -s 192.168.1.0/24 -m state --state NEW -j Cid37084X26841.0 $IPTABLES -t mangle -A Cid37084X26841.0 -d 22.22.22.0/24 -j MARK --set-mark 8 $IPTABLES -t mangle -A Cid37084X26841.0 -d 33.33.33.0/24 -j MARK --set-mark 8 # ================ Table 'filter', rule set Policy # # Rule 2 (global) # echo "Rule 2 (global)" # # This permits access from internal net # to the Internet and DMZ $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -j RULE_5 $IPTABLES -A INPUT -j RULE_5 $IPTABLES -A FORWARD -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -A RULE_5 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid37084X26841.0 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j Cid37084X26841.0 $IPTABLES -A Cid37084X26841.0 -d 22.22.22.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " $IPTABLES -A Cid37084X26841.0 -d 33.33.33.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " $IPTABLES -N Cid37084X26841.1 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j Cid37084X26841.1 $IPTABLES -A Cid37084X26841.1 -d 22.22.22.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " $IPTABLES -A Cid37084X26841.1 -d 33.33.33.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:50 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall42.fw.orig0000755000175000017500000002331511733011756022030 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:55 2012 PDT by vadim # # files: * firewall42.fw /etc/fw/firewall42.fw # # Compiled for iptables (any version) # # simple test for a rule that matches local broadcast and should go into INPUT chain, but internal interface of the firewall is dynamic so compiler can not determine that given address is broadcast. Using fake interface to make this address match. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 192.168.1.255 --dport 67 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 255.255.255.255 --dport 67 -m state --state NEW -j ACCEPT # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 224.0.1.141 --dport 67 -m state --state NEW -j ACCEPT # # Rule 3 (eth0) # echo "Rule 3 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 0.0.0.0 -d 255.255.255.255 --dport 67 -m state --state NEW -j ACCEPT # # Rule 4 (eth0) # echo "Rule 4 (eth0)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -s $i_eth0 -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT done } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:55 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall71.fw.orig0000755000175000017500000002716011733011756022034 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:06 2012 PDT by vadim # # files: * firewall71.fw /etc/fw/firewall71.fw # # Compiled for iptables 1.4.0 # # this firewall uses iptables-restore format. # two rule sets for the filter table, no rules in mangle, to make sure there is only one COMMIT for both # option "Clamp MSS to MTU" should be off because it puts rule # in mangle table. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: eth0 eth2" for i in eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # backup ssh access echo "-A INPUT -p tcp -m tcp -s 192.168.1.1/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT " echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop TCP sessions opened prior firewall restart echo "-A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " # drop packets that do not match any valid state echo "-A OUTPUT -m state --state INVALID -j DROP " echo "-A INPUT -m state --state INVALID -j DROP " echo "-A FORWARD -m state --state INVALID -j DROP " # ================ Table 'filter', rule set fw71_policy_2 # # Rule fw71_policy_2 0 (global) echo ":fw71_policy_2 - [0:0]" echo ":fw71_policy_2_0 - [0:0]" echo "-A fw71_policy_2 -j fw71_policy_2_0 " echo "-A fw71_policy_2_0 -j LOG " echo "-A fw71_policy_2_0 -j DROP " # # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo ":Cid42351X60089.0 - [0:0]" echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j Cid42351X60089.0 " echo "-A Cid42351X60089.0 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid42351X60089.0 -s 192.168.2.0/24 -j ACCEPT " echo ":Cid42351X60089.1 - [0:0]" echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j Cid42351X60089.1 " echo "-A Cid42351X60089.1 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid42351X60089.1 -s 192.168.2.0/24 -j ACCEPT " # # Rule 1 (global) echo ":RULE_1 - [0:0]" echo "-A OUTPUT -j RULE_1 " echo "-A INPUT -j RULE_1 " echo "-A FORWARD -j RULE_1 " echo "-A RULE_1 -j LOG " echo "-A RULE_1 -j fw71_policy_2 " # # Rule 2 (global) # Automatically generated 'catch all' rule echo ":RULE_2 - [0:0]" echo "-A OUTPUT -j RULE_2 " echo "-A INPUT -j RULE_2 " echo "-A FORWARD -j RULE_2 " echo "-A RULE_2 -j LOG " echo "-A RULE_2 -j DROP " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:06 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/run.all0000755000175000017500000000101711733011756020051 0ustar sylvestresylvestre#!/bin/sh make -j2 -k all exit 0 XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipt -v -f $XMLFILE -xt $fwobj" done XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipt -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-8.fw.orig0000755000175000017500000003671211733011756022716 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:27 2012 PDT by vadim # # files: * firewall-ipv6-8.fw /etc/firewall-ipv6-8.fw # # Compiled for iptables 1.4.0 # # matching multicast with different directions FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', rule set Policy_OSPF # # Rule Policy_OSPF 2 (global) echo ":Policy_OSPF - [0:0]" echo "-A Policy_OSPF -j DROP " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # rules to permit IPv6 Neighbor discovery echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy_OSPF # # Rule Policy_OSPF 0 (eth0) echo ":Policy_OSPF - [0:0]" echo "-A Policy_OSPF -i eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A Policy_OSPF -i eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " echo "-A Policy_OSPF -o eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A Policy_OSPF -o eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " # # Rule Policy_OSPF 1 (global) echo "-A Policy_OSPF -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A Policy_OSPF -s fe80::/10 -d fe80::/10 -j ACCEPT " # # Rule Policy_OSPF 2 (global) echo "-A Policy_OSPF -j DROP " # # ================ Table 'filter', rule set Policy_v6 # # Rule Policy_v6 0 (eth0) # see #1523 echo "-A INPUT -i eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A FORWARD -i eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " echo "-A FORWARD -o eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A FORWARD -o eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " # # Rule Policy_v6 1 (eth0) # see #1523 echo "-A INPUT -i eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 2 (eth0) # see #1523 echo "-A FORWARD -o eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 3 (eth0) # see #1523 echo "-A FORWARD -o eth0 -s fe80::21d:9ff:fe8b:aaaa -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 4 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 5 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -s fe80::21d:9ff:fe8b:8e94 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 6 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -s fe80::21d:9ff:fe8b:8e94 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 7 (eth0) # see #1523 echo "-A INPUT -i eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A INPUT -i eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " echo "-A FORWARD -i eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " echo "-A OUTPUT -o eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " echo "-A OUTPUT -o eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " echo "-A FORWARD -o eth0 -s fe80::/10 -d fe80::/10 -j ACCEPT " # # Rule Policy_v6 8 (eth0) # see #1523 echo "-A INPUT -i eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 9 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -s fe80::/10 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 11 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 12 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -s fe80::21d:9ff:fe8b:8e94 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 13 (eth0) # see #1523 echo "-A OUTPUT -o eth0 -s fe80::21d:9ff:fe8b:8e94 -d ff00::/8 -j ACCEPT " # # Rule Policy_v6 14 (global) echo "-A OUTPUT -p 89 -j Policy_OSPF " echo "-A INPUT -p 89 -j Policy_OSPF " echo "-A FORWARD -p 89 -j Policy_OSPF " # # Rule Policy_v6 15 (eth0) echo "-A INPUT -i eth0 -p 89 -j Policy_OSPF " echo "-A FORWARD -i eth0 -p 89 -j Policy_OSPF " echo "-A OUTPUT -o eth0 -p 89 -j Policy_OSPF " echo "-A FORWARD -o eth0 -p 89 -j Policy_OSPF " # echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:27 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall26.fw.orig0000755000175000017500000004335311733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:31 2012 PDT by vadim # # files: * firewall26.fw /etc/fw/firewall26.fw # # Compiled for iptables 1.4.0 # # this firewall uses iptables-restore format # One interface has dynamic address, script uses echo to generated iptables commands and then pipes them to iptables-restore # firewall26::: warning: Can not add virtual address for object address # firewall26::: warning: Can not add virtual address for object address FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: ppp eth0 eth2" for i in ppp eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" getaddr ppp i_ppp getaddr6 ppp i_ppp_v6 getnet ppp i_ppp_network getnet6 ppp i_ppp_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # backup ssh access echo "-A INPUT -p tcp -m tcp -s 192.168.1.1/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT " echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop TCP sessions opened prior firewall restart echo "-A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " # drop packets that do not match any valid state echo "-A OUTPUT -m state --state INVALID -j DROP " echo "-A INPUT -m state --state INVALID -j DROP " echo "-A FORWARD -m state --state INVALID -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (ppp) # ppp clients get addresses on 10.1.1.0 echo ":In_RULE_0 - [0:0]" echo "-A INPUT -i ppp -s ! 10.1.1.0/24 -j In_RULE_0 " echo "-A FORWARD -i ppp -s ! 10.1.1.0/24 -j In_RULE_0 " echo "-A In_RULE_0 -j LOG " echo "-A In_RULE_0 -j DROP " # # Rule 1 (ppp) # ppp clients can not connect to the firewall echo ":In_RULE_1 - [0:0]" for i_ppp in $i_ppp_list do test -n "$i_ppp" && echo "-A INPUT -i ppp -d $i_ppp -j In_RULE_1 " done echo "-A In_RULE_1 -j LOG " echo "-A In_RULE_1 -j DROP " # # Rule 2 (ppp) echo ":In_RULE_2 - [0:0]" echo "-A INPUT -i ppp -j In_RULE_2 " echo "-A In_RULE_2 -j LOG " echo "-A In_RULE_2 -j DROP " # # Rule 3 (ppp) # ppp clients can only connect to the mail # server and web proxy on DMZ echo "-A FORWARD -i ppp -p tcp -m tcp -m multiport -d 192.168.2.10 --dports 25,3128 -m state --state NEW -j ACCEPT " # # Rule 4 (ppp) # ppp clients can not connect to # anything else on DMZ and # internal net echo ":In_RULE_4 - [0:0]" echo "-A INPUT -i ppp -d 192.168.1.0/24 -j In_RULE_4 " echo "-A INPUT -i ppp -d 192.168.2.0/24 -j In_RULE_4 " echo "-A FORWARD -i ppp -d 192.168.1.0/24 -j In_RULE_4 " echo "-A FORWARD -i ppp -d 192.168.2.0/24 -j In_RULE_4 " echo "-A In_RULE_4 -j LOG " echo "-A In_RULE_4 -j DROP " # # Rule 5 (eth2) echo ":In_RULE_5 - [0:0]" echo "-A INPUT -i eth2 -s ! 192.168.2.0/24 -j In_RULE_5 " echo "-A FORWARD -i eth2 -s ! 192.168.2.0/24 -j In_RULE_5 " echo "-A In_RULE_5 -j LOG " echo "-A In_RULE_5 -j DROP " # # Rule 6 (global) # hostF has the same IP address as firewal. echo ":RULE_6 - [0:0]" echo "-A OUTPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_6 " echo "-A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_6 " echo "-A RULE_6 -j LOG " echo "-A RULE_6 -j ACCEPT " # # Rule 7 (global) echo ":Cid418C4619.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid418C4619.0 " for i_ppp in $i_ppp_list do test -n "$i_ppp" && echo "-A Cid418C4619.0 -d $i_ppp -j ACCEPT " done echo "-A Cid418C4619.0 -d 192.168.1.1 -j ACCEPT " echo "-A Cid418C4619.0 -d 192.168.2.1 -j ACCEPT " echo "-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT " # # Rule 8 (global) for i_ppp in $i_ppp_list do test -n "$i_ppp" && echo "-A OUTPUT -p tcp -m tcp -d $i_ppp --dport 22 -m state --state NEW -j ACCEPT " done for i_ppp in $i_ppp_list do test -n "$i_ppp" && echo "-A INPUT -p tcp -m tcp -d $i_ppp --dport 22 -m state --state NEW -j ACCEPT " done # # Rule 9 (global) echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT " # # Rule 10 (global) echo "-A OUTPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":Cid418C4642.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid418C4642.0 " echo "-A Cid418C4642.0 -d 192.168.1.1 -j ACCEPT " echo "-A Cid418C4642.0 -d 192.168.2.1 -j ACCEPT " echo ":Cid418C4642.1 - [0:0]" echo "-A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid418C4642.1 " echo "-A Cid418C4642.1 -d 192.168.1.1 -j ACCEPT " echo "-A Cid418C4642.1 -d 192.168.2.1 -j ACCEPT " # # Rule 12 (global) echo ":Cid418C464D.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid418C464D.0 " echo ":RULE_12 - [0:0]" echo "-A Cid418C464D.0 -d 192.168.1.1 -j RULE_12 " echo "-A Cid418C464D.0 -d 192.168.2.1 -j RULE_12 " echo ":Cid418C464D.1 - [0:0]" echo "-A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid418C464D.1 " echo "-A Cid418C464D.1 -d 192.168.1.1 -j RULE_12 " echo "-A Cid418C464D.1 -d 192.168.2.1 -j RULE_12 " echo "-A RULE_12 -j LOG " echo "-A RULE_12 -j ACCEPT " # # Rule 13 (global) # firewall is part of Any, so compiler should # generate code in both FORWARD and # OUTPUT chains echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j ACCEPT " # # Rule 14 (global) # firewall is part of Any, compiler should # generate code for both FORWARD and # INPUT chains echo "-A INPUT -s 200.200.200.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 200.200.200.200 -m state --state NEW -j ACCEPT " # # Rule 15 (global) # because firewall has interface on network # internal_net, compiler should generate code # for both FORWARD and INPUT chains echo "-A INPUT -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 16 (global) echo ":Cid418C4676.0 - [0:0]" echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j Cid418C4676.0 " echo "-A Cid418C4676.0 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid418C4676.0 -s 192.168.2.0/24 -j ACCEPT " echo ":Cid418C4676.1 - [0:0]" echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j Cid418C4676.1 " echo "-A Cid418C4676.1 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid418C4676.1 -s 192.168.2.0/24 -j ACCEPT " # # Rule 17 (global) # Automatically generated 'catch all' rule echo ":RULE_17 - [0:0]" echo "-A OUTPUT -j RULE_17 " echo "-A INPUT -j RULE_17 " echo "-A FORWARD -j RULE_17 " echo "-A RULE_17 -j LOG " echo "-A RULE_17 -j DROP " # echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o ppp -s 192.168.1.0/24 -j MASQUERADE " echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 " # # Rule 1 (NAT) echo "-A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 " echo "-A POSTROUTING -o ppp -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 " # # Rule 2 (NAT) for i_ppp in $i_ppp_list do test -n "$i_ppp" && echo "-A PREROUTING -p tcp -m tcp -d $i_ppp --dport 22 -j DNAT --to-destination 192.168.1.10:22 " done echo "-A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " echo "-A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " # # Rule 3 (NAT) echo "-A PREROUTING -s 192.168.1.0/24 -d ! 200.200.200.200 -j DNAT --to-destination 192.168.2.10 " echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.10 -j SNAT --to-source 192.168.2.1 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:31 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-6.fw.orig0000755000175000017500000002527011733011756022711 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:26 2012 PDT by vadim # # files: * firewall-ipv6-6.fw /etc/firewall-ipv6-6.fw # # Compiled for iptables (any version) # # one interfaces with both ipv4 and ipv6 addresses FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_v6 # # Rule Policy_v6 0 (eth0) # echo "Rule Policy_v6 0 (eth0)" # $IP6TABLES -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:26 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/vrrp_cluster_2_linux-1.fw.orig0000755000175000017500000004475711733011756024422 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * vrrp_cluster_2_linux-1.fw /etc/vrrp_cluster_2_linux-1.fw # # Compiled for iptables 1.4.0 # # FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth0.100" for i in eth0 eth1 lo eth0.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_vlans_of_interface "eth0 eth0.100" clear_vlans_except_known eth0.100@eth0 update_addresses_of_interface "eth0 172.24.0.2/16" "172.24.0.1/24" update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0.100 192.168.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 10/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 10/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -8 VRRP (automatic) # echo "Rule -8 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -7 VRRP (automatic) # echo "Rule -7 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.4 -d 224.0.0.18 -j ACCEPT # # Rule -6 VRRP (automatic) # echo "Rule -6 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.3 -d 224.0.0.18 -j ACCEPT # # Rule -5 VRRP (automatic) # echo "Rule -5 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -4 VRRP (automatic) # echo "Rule -4 VRRP (automatic)" # $IPTABLES -A INPUT -i eth0 -p vrrp -s 172.24.0.4 -d 224.0.0.18 -j ACCEPT # # Rule -3 VRRP (automatic) # echo "Rule -3 VRRP (automatic)" # $IPTABLES -A INPUT -i eth0 -p vrrp -s 172.24.0.3 -d 224.0.0.18 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid5188X25627.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid5188X25627.0 $IPTABLES -A Cid5188X25627.0 -d 192.168.1.3 -j ACCEPT $IPTABLES -A Cid5188X25627.0 -d 192.168.1.4 -j ACCEPT $IPTABLES -N Cid5188X25627.1 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid5188X25627.1 $IPTABLES -A Cid5188X25627.1 -d 192.168.1.3 -j ACCEPT $IPTABLES -A Cid5188X25627.1 -d 192.168.1.4 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.2 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.2 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.100.1 -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_8 $IPTABLES -A INPUT -m state --state NEW -j RULE_8 $IPTABLES -A FORWARD -m state --state NEW -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -j RULE_9 $IPTABLES -A INPUT -j RULE_9 $IPTABLES -A FORWARD -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/heartbeat_cluster_1_d_linux-2-d.fw.orig0000755000175000017500000005526611733011756026111 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:41 2012 PDT by vadim # # files: * heartbeat_cluster_1_d_linux-2-d.fw firewall.sh # # Compiled for iptables (any version) # # This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside. # Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0 # heartbeat_cluster_1_d:NAT:4: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-1-d' because its address in unknown. # heartbeat_cluster_1_d:NAT:: warning: Empty inet address in object id57982X27834 # heartbeat_cluster_1_d:Policy:7: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-1-d' because its address in unknown. # heartbeat_cluster_1_d:Policy:7: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-1-d' because its address in unknown. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth2 eth2.100" for i in eth0 eth1 lo eth2 eth2.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.254/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2.100 172.20.0.2/24" "" getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 done # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 --random done # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.100 done # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # # heartbeat_cluster_1_d:NAT:4: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-1-d' because its address in unknown. $IPTABLES -t nat -A PREROUTING -d -j DNAT --to-destination 192.168.1.100 # ================ Table 'filter', rule set Policy # # Rule -8 heartbeat (automatic) # echo "Rule -8 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth2.100 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -7 heartbeat (automatic) # echo "Rule -7 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth2.100 -p udp -m udp -s 172.20.0.1 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -6 heartbeat (automatic) # echo "Rule -6 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -5 heartbeat (automatic) # echo "Rule -5 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -s 192.168.1.1 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_0 for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A INPUT -i eth0 -s $i_eth0 -m state --state NEW -j In_RULE_0 done $IPTABLES -A INPUT -i eth0 -s 172.20.0.2 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.254 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_0 for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A FORWARD -i eth0 -s $i_eth0 -m state --state NEW -j In_RULE_0 done $IPTABLES -A FORWARD -i eth0 -s 172.20.0.2 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.254 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (lo) # echo "Rule 1 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_3 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- ACCEPT " $IPTABLES -A RULE_3 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # fw is part of any and networks for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 6 (global) # echo "Rule 6 (global)" # # fw is NOT part of any and networks for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 7 (global) # echo "Rule 7 (global)" # # heartbeat_cluster_1_d:Policy:7: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-1-d' because its address in unknown. for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 8 (global) # echo "Rule 8 (global)" # # fw is part of any $IPTABLES -N Cid307958X52019.0 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid307958X52019.0 $IPTABLES -A Cid307958X52019.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid307958X52019.0 -s 192.168.1.254 -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # # fw is not part of any $IPTABLES -N Cid625000X52019.0 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid625000X52019.0 $IPTABLES -A Cid625000X52019.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid625000X52019.0 -s 192.168.1.254 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # # fw is not part of any $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.254 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.2 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.1 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.1 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_12 for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -d $i_eth0 -j RULE_12 done $IPTABLES -A OUTPUT -d 172.20.0.2 -j RULE_12 $IPTABLES -A OUTPUT -d 192.168.1.2 -j RULE_12 $IPTABLES -A OUTPUT -d 192.168.1.254 -j RULE_12 $IPTABLES -A INPUT -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level info --log-prefix "RULE 12 -- DENY " $IPTABLES -A RULE_12 -j DROP # # Rule 13 (eth0) # echo "Rule 13 (eth0)" # $IPTABLES -A INPUT -i ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o ! eth0 -m state --state NEW -j ACCEPT # # Rule 14 (eth0,eth1) # echo "Rule 14 (eth0,eth1)" # $IPTABLES -A INPUT -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2.100 -m state --state NEW -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o ! eth0 -m state --state NEW -j ACCEPT # # Rule 16 (eth0,eth1) # echo "Rule 16 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2.100 -m state --state NEW -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i ! eth0 -m state --state NEW -j ACCEPT # # Rule 18 (eth0,eth1) # echo "Rule 18 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2.100 -m state --state NEW -j ACCEPT # # Rule 19 (eth0) # echo "Rule 19 (eth0)" # # fw is part of any is OFF $IPTABLES -A FORWARD -o ! eth0 -m state --state NEW -j ACCEPT # # Rule 20 (eth0,eth1) # echo "Rule 20 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A FORWARD -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2.100 -m state --state NEW -j ACCEPT # # Rule 21 (eth0) # echo "Rule 21 (eth0)" # $IPTABLES -A INPUT -i ! eth0 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o ! eth0 -d $i_eth0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o ! eth0 -d 172.20.0.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o ! eth0 -d 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o ! eth0 -d 192.168.1.254 -m state --state NEW -j ACCEPT # # Rule 22 (eth0,eth1) # echo "Rule 22 (eth0,eth1)" # $IPTABLES -A INPUT -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2.100 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth2 -d $i_eth0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o eth2 -d 172.20.0.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -d 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -d 192.168.1.254 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth2.100 -d $i_eth0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o eth2.100 -d 172.20.0.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2.100 -d 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2.100 -d 192.168.1.254 -m state --state NEW -j ACCEPT # # Rule 23 (eth0) # echo "Rule 23 (eth0)" # # fw is part of any is OFF $IPTABLES -A INPUT -i ! eth0 -m state --state NEW -j ACCEPT # # Rule 24 (eth0,eth1) # echo "Rule 24 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A INPUT -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2.100 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall60.fw.orig0000755000175000017500000002727211733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:59 2012 PDT by vadim # # files: * firewall60.fw /etc/firewall60.fw # # Compiled for iptables (any version) # # testing time litmiting for iptables < 1.4.0 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_0 $IPTABLES -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_0 $IPTABLES -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sun -j RULE_1 $IPTABLES -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sun -j RULE_1 $IPTABLES -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sun -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 $IPTABLES -A OUTPUT -m time --timestart 18:00 --timestop 23:59 -j RULE_2 $IPTABLES -A INPUT -m time --timestart 18:00 --timestop 23:59 -j RULE_2 $IPTABLES -A FORWARD -m time --timestart 18:00 --timestop 23:59 -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A RULE_2 -j DROP # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j RULE_3 $IPTABLES -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j RULE_3 $IPTABLES -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -A RULE_3 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N RULE_4 $IPTABLES -A OUTPUT -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RULE_4 $IPTABLES -A INPUT -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RULE_4 $IPTABLES -A FORWARD -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -A RULE_4 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:59 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-5.fw.orig0000755000175000017500000002507011733011756022706 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:24 2012 PDT by vadim # # files: * firewall-ipv6-5.fw /etc/firewall-ipv6-5.fw # # Compiled for iptables (any version) # # two interfaces, one has ipv4 address, another ipv6 # Combined ipv6+ipv6 ruleset. Only interface with address # that matches address family should be used in generated rule FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 1.1.1.1/24" "" update_addresses_of_interface "eth1 fe80::21d:9ff:fe8b:8e94/64" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT # # Rule 2 (eth1,eth0) # echo "Rule 2 (eth1,eth0)" # $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # $IP6TABLES -A INPUT -i eth1 -p tcp -m tcp --dport 22 -j ACCEPT # # Rule 2 (eth1,eth0) # echo "Rule 2 (eth1,eth0)" # $IP6TABLES -A INPUT -i eth1 -p tcp -m tcp --dport 22 -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:24 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall.fw.orig0000755000175000017500000020347311733011756021667 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:06 2012 PDT by vadim # # files: * firewall.fw /etc/fw/firewall.fw # # Compiled for iptables (any version) # # this is simple firewall with two interfaces. Test regular policy rules, including IP_fragments rule # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall:NAT:11: warning: SNAT rule can not match MAC address. Object CA(host-with-mac-1:1) removed from the rule # firewall:NAT:16: warning: SNAT rule can not match MAC address. Object CA(host-with-mac-1:1) removed from the rule # firewall:NAT:: warning: Empty inet address in object id3BF1B3E8-pa # firewall:NAT:: warning: Empty inet address in object id3BF1B3E8-pa # firewall:NAT:: warning: Empty inet address in object id3E0BD74A # firewall:NAT:: warning: Empty inet address in object id3E0BD74A # firewall:NAT:: warning: Empty inet address in object id3DB0B351-pa # firewall:NAT:: warning: Empty inet address in object id3DB0B351-pa # firewall:NAT:: warning: Empty inet address in object id3BF1B3E8-pa # firewall:NAT:: warning: Empty inet address in object id3BF1B3E8-pa # firewall:Policy:36: warning: Empty MAC address in rule # firewall:Policy:37: warning: Empty MAC address in rule # firewall:Policy:38: warning: Empty MAC address in rule # firewall:Policy:39: warning: Empty MAC address in rule # firewall:Policy:40: warning: Empty MAC address in rule # firewall:Policy:40: warning: Empty MAC address in rule # firewall:Policy:41: warning: Can not match MAC address of the firewall (chain OUTPUT) # firewall:Policy:36: warning: Empty MAC address in rule # firewall:Policy:37: warning: Empty MAC address in rule # firewall:Policy:38: warning: Empty MAC address in rule # firewall:Policy:39: warning: Empty MAC address in rule # firewall:Policy:40: warning: Empty MAC address in rule # firewall:Policy:40: warning: Empty MAC address in rule FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/usr/local/sbin/modprobe" IPTABLES="/usr/local/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/usr/local/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth1 eth0" for i in eth1 eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth1 222.222.222.222/24 222.222.222.0/32 222.222.222.1/32 222.222.222.2/32 222.222.222.3/32 222.222.222.4/32 222.222.222.5/32 222.222.222.6/32 222.222.222.7/32 222.222.222.8/32 222.222.222.9/32 222.222.222.10/32 222.222.222.11/32 222.222.222.12/32 222.222.222.13/32 222.222.222.14/32 222.222.222.15/32 222.222.222.16/32 222.222.222.17/32 222.222.222.18/32 222.222.222.19/32 222.222.222.20/32 222.222.222.21/32 222.222.222.22/32 222.222.222.23/32 222.222.222.24/32 222.222.222.25/32 222.222.222.26/32 222.222.222.27/32 222.222.222.28/32 222.222.222.29/32 222.222.222.30/32 222.222.222.31/32 222.222.222.32/32 222.222.222.33/32 222.222.222.34/32 222.222.222.35/32 222.222.222.36/32 222.222.222.37/32 222.222.222.38/32 222.222.222.39/32 222.222.222.40/32 222.222.222.41/32 222.222.222.42/32 222.222.222.43/32 222.222.222.44/32 222.222.222.45/32 222.222.222.46/32 222.222.222.47/32 222.222.222.48/32 222.222.222.49/32 222.222.222.50/32 222.222.222.51/32 222.222.222.52/32 222.222.222.53/32 222.222.222.54/32 222.222.222.55/32 222.222.222.56/32 222.222.222.57/32 222.222.222.58/32 222.222.222.59/32 222.222.222.60/32 222.222.222.61/32 222.222.222.62/32 222.222.222.63/32 222.222.222.64/32 222.222.222.65/32 222.222.222.66/32 222.222.222.67/32 222.222.222.68/32 222.222.222.69/32 222.222.222.70/32 222.222.222.71/32 222.222.222.72/32 222.222.222.73/32 222.222.222.74/32 222.222.222.75/32 222.222.222.76/32 222.222.222.77/32 222.222.222.78/32 222.222.222.79/32 222.222.222.80/32 222.222.222.81/32 222.222.222.82/32 222.222.222.83/32 222.222.222.84/32 222.222.222.85/32 222.222.222.86/32 222.222.222.87/32 222.222.222.88/32 222.222.222.89/32 222.222.222.90/32 222.222.222.91/32 222.222.222.92/32 222.222.222.93/32 222.222.222.94/32 222.222.222.95/32 222.222.222.96/32 222.222.222.97/32 222.222.222.98/32 222.222.222.99/32 222.222.222.100/32 222.222.222.101/32 222.222.222.102/32 222.222.222.103/32 222.222.222.104/32 222.222.222.105/32 222.222.222.106/32 222.222.222.107/32 222.222.222.108/32 222.222.222.109/32 222.222.222.110/32 222.222.222.111/32 222.222.222.112/32 222.222.222.113/32 222.222.222.114/32 222.222.222.115/32 222.222.222.116/32 222.222.222.117/32 222.222.222.118/32 222.222.222.119/32 222.222.222.120/32 222.222.222.121/32 222.222.222.122/32 222.222.222.123/32 222.222.222.124/32 222.222.222.125/32 222.222.222.126/32 222.222.222.127/32 222.222.222.128/32 222.222.222.129/32 222.222.222.130/32 222.222.222.131/32 222.222.222.132/32 222.222.222.133/32 222.222.222.134/32 222.222.222.135/32 222.222.222.136/32 222.222.222.137/32 222.222.222.138/32 222.222.222.139/32 222.222.222.140/32 222.222.222.141/32 222.222.222.142/32 222.222.222.143/32 222.222.222.144/32 222.222.222.145/32 222.222.222.146/32 222.222.222.147/32 222.222.222.148/32 222.222.222.149/32 222.222.222.150/32 222.222.222.151/32 222.222.222.152/32 222.222.222.153/32 222.222.222.154/32 222.222.222.155/32 222.222.222.156/32 222.222.222.157/32 222.222.222.158/32 222.222.222.159/32 222.222.222.160/32 222.222.222.161/32 222.222.222.162/32 222.222.222.163/32 222.222.222.164/32 222.222.222.165/32 222.222.222.166/32 222.222.222.167/32 222.222.222.168/32 222.222.222.169/32 222.222.222.170/32 222.222.222.171/32 222.222.222.172/32 222.222.222.173/32 222.222.222.174/32 222.222.222.175/32 222.222.222.176/32 222.222.222.177/32 222.222.222.178/32 222.222.222.179/32 222.222.222.180/32 222.222.222.181/32 222.222.222.182/32 222.222.222.183/32 222.222.222.184/32 222.222.222.185/32 222.222.222.186/32 222.222.222.187/32 222.222.222.188/32 222.222.222.189/32 222.222.222.190/32 222.222.222.191/32 222.222.222.192/32 222.222.222.193/32 222.222.222.194/32 222.222.222.195/32 222.222.222.196/32 222.222.222.197/32 222.222.222.198/32 222.222.222.199/32 222.222.222.200/32 222.222.222.201/32 222.222.222.202/32 222.222.222.203/32 222.222.222.204/32 222.222.222.205/32 222.222.222.206/32 222.222.222.207/32 222.222.222.208/32 222.222.222.209/32 222.222.222.210/32 222.222.222.211/32 222.222.222.212/32 222.222.222.213/32 222.222.222.214/32 222.222.222.215/32 222.222.222.216/32 222.222.222.217/32 222.222.222.218/32 222.222.222.219/32 222.222.222.220/32 222.222.222.221/32 222.222.222.222/32 222.222.222.223/32 222.222.222.224/32 222.222.222.225/32 222.222.222.226/32 222.222.222.227/32 222.222.222.228/32 222.222.222.229/32 222.222.222.230/32 222.222.222.231/32 222.222.222.232/32 222.222.222.233/32 222.222.222.234/32 222.222.222.235/32 222.222.222.236/32 222.222.222.237/32 222.222.222.238/32 222.222.222.239/32 222.222.222.240/32 222.222.222.241/32 222.222.222.242/32 222.222.222.243/32 222.222.222.244/32 222.222.222.245/32 222.222.222.246/32 222.222.222.247/32 222.222.222.248/32 222.222.222.249/32 222.222.222.250/32 222.222.222.251/32 222.222.222.252/32 222.222.222.253/32 222.222.222.254/32 222.222.222.40/24 222.222.222.41/24" "" update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.20/24 192.168.1.10/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # backup ssh access $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.100/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.100/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.222 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 222.222.222.0/24 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # firewall:NAT:2: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10/31 -j SNAT --to-source 222.222.222.10-222.222.222.100 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.12/30 -j SNAT --to-source 222.222.222.10-222.222.222.100 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.16/28 -j SNAT --to-source 222.222.222.10-222.222.222.100 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.32/27 -j SNAT --to-source 222.222.222.10-222.222.222.100 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.64/27 -j SNAT --to-source 222.222.222.10-222.222.222.100 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.96/30 -j SNAT --to-source 222.222.222.10-222.222.222.100 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.100 -j SNAT --to-source 222.222.222.10-222.222.222.100 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.20 --dport 80 -j DNAT --to-destination :3128 $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -s 192.168.1.0/24 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -d 22.22.22.23 --dport 4000:4010 -j SNAT --to-source 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -d 22.22.22.23 --dport 3128 -j SNAT --to-source 192.168.1.10 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 25 -j DNAT --to-destination 192.168.1.10:25 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 25 -j DNAT --to-destination 192.168.1.10:25 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 222.222.222.222 --icmp-type 8/0 -j DNAT --to-destination 192.168.1.10 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 222.222.222.222 --icmp-type 8/0 -j DNAT --to-destination 192.168.1.10 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 1000:1010 -d 192.168.1.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 1000:1010 -d 222.222.222.222 -j DNAT --to-destination 192.168.1.10 # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --sport 1000:1010 -j SNAT --to-source 222.222.222.222:1000-1010 # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # # firewall:NAT:11: warning: SNAT rule can not match MAC address. Object CA(host-with-mac-1:1) removed from the rule $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 25 -j SNAT --to-source 222.222.222.222 # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:70 -d 222.222.222.40 --dport 25 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:70 -d 222.222.222.41 --dport 25 -j DNAT --to-destination 192.168.1.10 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source aa:bb:cc:dd:ee:ff -s 192.168.1.15 -d 222.222.222.40 --dport 25 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source aa:bb:cc:dd:ee:ff -s 192.168.1.15 -d 222.222.222.41 --dport 25 -j DNAT --to-destination 192.168.1.10 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # # hsould match mac and ip addresses $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:71 -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:71 -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:70 -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:70 -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10 # # Rule 15 (NAT) # echo "Rule 15 (NAT)" # # ensure generated rules match different mac addresses $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source aa:bb:cc:dd:ee:ff -s 192.168.1.15 -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m mac --mac-source aa:bb:cc:dd:ee:ff -s 192.168.1.15 -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # # should match mac and ip addresses # firewall:NAT:16: warning: SNAT rule can not match MAC address. Object CA(host-with-mac-1:1) removed from the rule $IPTABLES -t nat -N Cid445F52DE31658.0 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j Cid445F52DE31658.0 $IPTABLES -t nat -A Cid445F52DE31658.0 -d 61.150.47.112 -j RETURN $IPTABLES -t nat -A Cid445F52DE31658.0 -d 223.223.223.223 -j RETURN $IPTABLES -t nat -A Cid445F52DE31658.0 -p tcp -m tcp --dport 80 -j SNAT --to-source 222.222.222.222 # # Rule 17 (NAT) # echo "Rule 17 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 1024:65535 -d 192.168.1.1 --dport 80 -j DNAT --to-destination 192.168.1.10:80 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 1024:65535 -d 222.222.222.222 --dport 80 -j DNAT --to-destination 192.168.1.10:80 # # Rule 18 (NAT) # echo "Rule 18 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 53 -d 192.168.1.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --sport 53 -d 222.222.222.222 -j DNAT --to-destination 192.168.1.10 # # Rule 19 (NAT) # echo "Rule 19 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 4000:4010 -j DNAT --to-destination 192.168.1.10:4000-4010 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 4000:4010 -j DNAT --to-destination 192.168.1.10:4000-4010 # # Rule 20 (NAT) # echo "Rule 20 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 4000:4010 -j SNAT --to-source 222.222.222.222 # # Rule 21 (NAT) # echo "Rule 21 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.10 --dport 3128 -j DNAT --to-destination :80 # # Rule 22 (NAT) # echo "Rule 22 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 3128 -j DNAT --to-destination :80 # # Rule 23 (NAT) # echo "Rule 23 (NAT)" # # should use multiport # and account for # no more than 15 ports # per rule $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 222.222.222.222 --dports 113,13,53,2105,21,70,80,443,143,993,6667,6667,543,544,389 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 222.222.222.222 --dports 98,3306,2049,119,110,5432,515,26000,512,513,514,4321,25,465,1080 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 222.222.222.222 --dports 3128,22,111,23,540,7100 -j DNAT --to-destination 192.168.1.10 # # Rule 24 (NAT) # echo "Rule 24 (NAT)" # # should use multiport # and account for # no more than 15 ports # per rule $IPTABLES -t nat -N Cid3EF4288E.0 $IPTABLES -t nat -A PREROUTING -d 222.222.222.222 -j Cid3EF4288E.0 $IPTABLES -t nat -A Cid3EF4288E.0 -p tcp -m tcp --dport 10000:11000 -j RETURN $IPTABLES -t nat -A Cid3EF4288E.0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,143,993,6667,6667,543,544,389 -j RETURN $IPTABLES -t nat -A Cid3EF4288E.0 -p tcp -m tcp -m multiport --dports 98,3306,2049,119,110,5432,515,26000,512,513,514,4321,25,465,1080 -j RETURN $IPTABLES -t nat -A Cid3EF4288E.0 -p tcp -m tcp -m multiport --dports 3128,22,111,23,540,7100 -j RETURN $IPTABLES -t nat -A Cid3EF4288E.0 -j DNAT --to-destination 192.168.1.10 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # # Automatically generated rule blocking short fragments $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth1 -p all -f -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -p all -f -j In_RULE_0 $IPTABLES -A In_RULE_0 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # # б‚аЕбб‚аОаВб‹аЙ аКаОаМаМаЕаНб‚аАб€аИаЙ аПаО-б€бƒббаКаИ. аŸб€аОаВаЕб€баЕаМ аКаОаНаВаЕб€б‚аАб†аИбŽ аИаЗ/аВ Utf8 $IPTABLES -N Cid3B09D29D.0 $IPTABLES -A INPUT -i eth1 -p all -f -j Cid3B09D29D.0 $IPTABLES -N In_RULE_1 $IPTABLES -A Cid3B09D29D.0 -d 192.168.1.1 -j In_RULE_1 $IPTABLES -A Cid3B09D29D.0 -d 222.222.222.222 -j In_RULE_1 $IPTABLES -A In_RULE_1 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (eth1) # echo "Rule 2 (eth1)" # # Automatically generated anti-spoofing rule $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 222.222.222.222 -j In_RULE_2 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 222.222.222.222 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_2 $IPTABLES -A In_RULE_2 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # $IPTABLES -N Cid47421X33852.0 $IPTABLES -A INPUT -i eth1 -p udp -m udp --dport 53 -m state --state NEW -j Cid47421X33852.0 $IPTABLES -A Cid47421X33852.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid47421X33852.0 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid47421X33852.1 $IPTABLES -A OUTPUT -o eth1 -p udp -m udp --dport 53 -m state --state NEW -j Cid47421X33852.1 $IPTABLES -A Cid47421X33852.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid47421X33852.1 -d 222.222.222.222 -j ACCEPT # # Rule 4 (eth1) # echo "Rule 4 (eth1)" # # rule in FORWARD chain with # -o eth1 and dest address of the firewall # is pretty much impossible $IPTABLES -A INPUT -i eth1 -p udp -m udp -d 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT # # Rule 5 (eth1) # echo "Rule 5 (eth1)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -d 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT # # Rule 6 (eth1) # echo "Rule 6 (eth1)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -d 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT # # Rule 7 (eth1) # echo "Rule 7 (eth1)" # $IPTABLES -N Cid112281X33852.0 $IPTABLES -A INPUT -i eth1 -p udp -m udp --dport 53 -m state --state NEW -j Cid112281X33852.0 $IPTABLES -A Cid112281X33852.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid112281X33852.0 -s 222.222.222.222 -j ACCEPT $IPTABLES -N Cid112281X33852.1 $IPTABLES -A FORWARD -i eth1 -p udp -m udp --dport 53 -m state --state NEW -j Cid112281X33852.1 $IPTABLES -A Cid112281X33852.1 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid112281X33852.1 -s 222.222.222.222 -j ACCEPT $IPTABLES -N Cid112281X33852.2 $IPTABLES -A OUTPUT -o eth1 -p udp -m udp --dport 53 -m state --state NEW -j Cid112281X33852.2 $IPTABLES -A Cid112281X33852.2 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid112281X33852.2 -s 222.222.222.222 -j ACCEPT # # Rule 8 (eth1) # echo "Rule 8 (eth1)" # # keep FORWARD chain # because it is needed for anti-spoofing rules $IPTABLES -A INPUT -i eth1 -p udp -m udp -s 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p udp -m udp -s 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -s 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT # # Rule 9 (eth1) # echo "Rule 9 (eth1)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -s 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -p udp -m udp -s 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p udp -m udp -s 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p udp -m udp -s 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -s 222.222.222.222 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p udp -m udp -s 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT # # Rule 10 (eth0) # echo "Rule 10 (eth0)" # $IPTABLES -N Cid3B92DFC5.0 $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 192.168.1.0/24 --dport 53 -m state --state NEW -j Cid3B92DFC5.0 $IPTABLES -A Cid3B92DFC5.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3B92DFC5.0 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid3B92DFC5.1 $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -s 192.168.1.0/24 --dport 53 -m state --state NEW -j Cid3B92DFC5.1 $IPTABLES -A Cid3B92DFC5.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3B92DFC5.1 -d 222.222.222.222 -j ACCEPT # # Rule 11 (eth0) # echo "Rule 11 (eth0)" # # code should go into INPUT chain with # address in destination for comparison $IPTABLES -N In_RULE_11 $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 192.168.1.255 --dport 53 -j In_RULE_11 $IPTABLES -A In_RULE_11 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A In_RULE_11 -j DROP # # Rule 12 (eth0) # echo "Rule 12 (eth0)" # $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT # # Rule 13 (eth0,eth1) # echo "Rule 13 (eth0,eth1)" # # reject using connlimit $IPTABLES -A INPUT -i eth0 -d 192.168.1.1 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j DROP $IPTABLES -A INPUT -i eth0 -d 222.222.222.222 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j DROP $IPTABLES -A INPUT -i eth1 -d 192.168.1.1 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j DROP $IPTABLES -A INPUT -i eth1 -d 222.222.222.222 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j DROP # # Rule 14 (eth0,eth1) # echo "Rule 14 (eth0,eth1)" # # reject using connlimit $IPTABLES -A INPUT -i eth0 -d 192.168.1.1 -m dstlimit --dstlimit 2/second --dstlimit-burst 5 --dstlimit-mode destip --dstlimit-name htable_rule_14 -j DROP $IPTABLES -A INPUT -i eth0 -d 222.222.222.222 -m dstlimit --dstlimit 2/second --dstlimit-burst 5 --dstlimit-mode destip --dstlimit-name htable_rule_14 -j DROP $IPTABLES -A INPUT -i eth1 -d 192.168.1.1 -m dstlimit --dstlimit 2/second --dstlimit-burst 5 --dstlimit-mode destip --dstlimit-name htable_rule_14 -j DROP $IPTABLES -A INPUT -i eth1 -d 222.222.222.222 -m dstlimit --dstlimit 2/second --dstlimit-burst 5 --dstlimit-mode destip --dstlimit-name htable_rule_14 -j DROP # # Rule 15 (eth0,eth1) # echo "Rule 15 (eth0,eth1)" # $IPTABLES -A INPUT -i eth0 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth0 -d 222.222.222.222 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -d 222.222.222.222 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # OUTPUT $IPTABLES -N Cid469F1D0830391.0 $IPTABLES -A OUTPUT -d 1.1.1.1 -j Cid469F1D0830391.0 $IPTABLES -A Cid469F1D0830391.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid469F1D0830391.0 -s 222.222.222.222 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # INTPUT with "-i +" # "-i +" is redundant if chain is INPUT, # optimization removes it $IPTABLES -N Cid469F1CF730391.0 $IPTABLES -A INPUT -s 1.1.1.1 -j Cid469F1CF730391.0 $IPTABLES -A Cid469F1CF730391.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid469F1CF730391.0 -d 222.222.222.222 -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # OUTPUT + FORWARD $IPTABLES -A OUTPUT -d 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -o + -d 1.1.1.1 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # INPUT + FORWARD $IPTABLES -A INPUT -s 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -i + -s 1.1.1.1 -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # # OUTPUT + FORWARD $IPTABLES -A OUTPUT -d 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -d 1.1.1.1 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # # INPUT + FORWARD $IPTABLES -A INPUT -s 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -s 1.1.1.1 -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N RULE_22 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type any -j RULE_22 $IPTABLES -A OUTPUT -p tcp -m tcp --tcp-flags ALL NONE -j RULE_22 $IPTABLES -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_22 $IPTABLES -A OUTPUT -p tcp -m tcp --tcp-flags ALL ACK,RST,SYN,FIN -j RULE_22 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type any -j RULE_22 $IPTABLES -A INPUT -p tcp -m tcp --tcp-flags ALL NONE -j RULE_22 $IPTABLES -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_22 $IPTABLES -A INPUT -p tcp -m tcp --tcp-flags ALL ACK,RST,SYN,FIN -j RULE_22 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type any -j RULE_22 $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags ALL NONE -j RULE_22 $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_22 $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags ALL ACK,RST,SYN,FIN -j RULE_22 $IPTABLES -A RULE_22 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A RULE_22 -j DROP # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -A OUTPUT -p all -m ipv4options --rr -j DROP $IPTABLES -A OUTPUT -p all -m ipv4options --lsrr --ssrr -j DROP $IPTABLES -A OUTPUT -p all -m ipv4options --ts -j DROP $IPTABLES -A INPUT -p all -m ipv4options --rr -j DROP $IPTABLES -A INPUT -p all -m ipv4options --lsrr --ssrr -j DROP $IPTABLES -A INPUT -p all -m ipv4options --ts -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --rr -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --lsrr --ssrr -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --ts -j DROP # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -A OUTPUT -p all -m ipv4options --any-opt -j DROP $IPTABLES -A INPUT -p all -m ipv4options --any-opt -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --any-opt -j DROP # # Rule 25 (global) # echo "Rule 25 (global)" # $IPTABLES -A OUTPUT -p all -m dscp --dscp-class AF4 -m ipv4options --lsrr --ra -j DROP $IPTABLES -A INPUT -p all -m dscp --dscp-class AF4 -m ipv4options --lsrr --ra -j DROP $IPTABLES -A FORWARD -p all -m dscp --dscp-class AF4 -m ipv4options --lsrr --ra -j DROP # # Rule 26 (global) # echo "Rule 26 (global)" # $IPTABLES -N RULE_26 $IPTABLES -A OUTPUT -p tcp -m state --state ESTABLISHED --tcp-flags SYN,ACK,RST,URG ACK -j RULE_26 $IPTABLES -A OUTPUT -p tcp -m state --state ESTABLISHED --tcp-flags SYN,FIN,RST,URG,PSH RST -j RULE_26 $IPTABLES -A INPUT -p tcp -m state --state ESTABLISHED --tcp-flags SYN,ACK,RST,URG ACK -j RULE_26 $IPTABLES -A INPUT -p tcp -m state --state ESTABLISHED --tcp-flags SYN,FIN,RST,URG,PSH RST -j RULE_26 $IPTABLES -A FORWARD -p tcp -m state --state ESTABLISHED --tcp-flags SYN,ACK,RST,URG ACK -j RULE_26 $IPTABLES -A FORWARD -p tcp -m state --state ESTABLISHED --tcp-flags SYN,FIN,RST,URG,PSH RST -j RULE_26 $IPTABLES -A RULE_26 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A RULE_26 -j DROP # # Rule 28 (global) # echo "Rule 28 (global)" # # both src and dst have multiple interfaces $IPTABLES -N Cid3EE24E9C.0 $IPTABLES -A INPUT -s 192.168.1.1 -m state --state NEW -j Cid3EE24E9C.0 $IPTABLES -A INPUT -s 222.222.222.222 -m state --state NEW -j Cid3EE24E9C.0 $IPTABLES -A Cid3EE24E9C.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3EE24E9C.0 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid3EE24E9C.1 $IPTABLES -A OUTPUT -s 192.168.1.1 -m state --state NEW -j Cid3EE24E9C.1 $IPTABLES -A OUTPUT -s 222.222.222.222 -m state --state NEW -j Cid3EE24E9C.1 $IPTABLES -A Cid3EE24E9C.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3EE24E9C.1 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid3EE24E9C.2 $IPTABLES -A OUTPUT -s 192.168.1.1 -m state --state NEW -j Cid3EE24E9C.2 $IPTABLES -A OUTPUT -s 222.222.222.222 -m state --state NEW -j Cid3EE24E9C.2 $IPTABLES -A Cid3EE24E9C.2 -d 33.33.33.33 -j ACCEPT $IPTABLES -A Cid3EE24E9C.2 -d 172.16.1.1 -j ACCEPT $IPTABLES -A Cid3EE24E9C.2 -d 192.168.100.1 -j ACCEPT $IPTABLES -N Cid3EE24E9C.3 $IPTABLES -A INPUT -d 192.168.1.1 -m state --state NEW -j Cid3EE24E9C.3 $IPTABLES -A INPUT -d 222.222.222.222 -m state --state NEW -j Cid3EE24E9C.3 $IPTABLES -A Cid3EE24E9C.3 -s 33.33.33.33 -j ACCEPT $IPTABLES -A Cid3EE24E9C.3 -s 172.16.1.1 -j ACCEPT $IPTABLES -A Cid3EE24E9C.3 -s 192.168.100.1 -j ACCEPT $IPTABLES -N Cid3EE24E9C.4 $IPTABLES -A FORWARD -s 33.33.33.33 -m state --state NEW -j Cid3EE24E9C.4 $IPTABLES -A FORWARD -s 172.16.1.1 -m state --state NEW -j Cid3EE24E9C.4 $IPTABLES -A FORWARD -s 192.168.100.1 -m state --state NEW -j Cid3EE24E9C.4 $IPTABLES -A Cid3EE24E9C.4 -d 33.33.33.33 -j ACCEPT $IPTABLES -A Cid3EE24E9C.4 -d 172.16.1.1 -j ACCEPT $IPTABLES -A Cid3EE24E9C.4 -d 192.168.100.1 -j ACCEPT # # Rule 29 (global) # echo "Rule 29 (global)" # $IPTABLES -A FORWARD -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -d 192.168.1.10 -m state --state NEW -j ACCEPT # # Rule 30 (global) # echo "Rule 30 (global)" # $IPTABLES -N Cid3E0AA611.0 $IPTABLES -A INPUT -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -m state --state NEW -j Cid3E0AA611.0 $IPTABLES -A Cid3E0AA611.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E0AA611.0 -d 222.222.222.222 -j ACCEPT # # Rule 31 (global) # echo "Rule 31 (global)" # $IPTABLES -A FORWARD -m mac --mac-source 00:10:4b:de:e9:70 -d 192.168.1.10 -m state --state NEW -j ACCEPT # # Rule 32 (global) # echo "Rule 32 (global)" # $IPTABLES -N Cid3E0AA504.0 $IPTABLES -A INPUT -m mac --mac-source 00:10:4b:de:e9:70 -m state --state NEW -j Cid3E0AA504.0 $IPTABLES -A Cid3E0AA504.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E0AA504.0 -d 222.222.222.222 -j ACCEPT # # Rule 33 (global) # echo "Rule 33 (global)" # $IPTABLES -A FORWARD -m mac --mac-source 00:10:4b:de:e9:70 -d 200.200.200.200 -m state --state NEW -j ACCEPT # # Rule 34 (global) # echo "Rule 34 (global)" # $IPTABLES -N Cid3E0F40D5.0 $IPTABLES -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -s 192.168.1.15 -m state --state NEW -j Cid3E0F40D5.0 $IPTABLES -A Cid3E0F40D5.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E0F40D5.0 -d 222.222.222.222 -j ACCEPT # # Rule 35 (global) # echo "Rule 35 (global)" # $IPTABLES -N Cid3E0F452C.0 $IPTABLES -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -m state --state NEW -j Cid3E0F452C.0 $IPTABLES -A Cid3E0F452C.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E0F452C.0 -d 222.222.222.222 -j ACCEPT # # Rule 36 (global) # echo "Rule 36 (global)" # # firewall:Policy:36: warning: Empty MAC address in rule $IPTABLES -N Cid3DB0B422.0 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cid3DB0B422.0 $IPTABLES -A Cid3DB0B422.0 -m mac --mac-source 00:10:4b:de:e9:70 -j ACCEPT $IPTABLES -A Cid3DB0B422.0 -m mac --mac-source 00:10:4b:de:e9:71 -j ACCEPT $IPTABLES -A Cid3DB0B422.0 -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT $IPTABLES -A Cid3DB0B422.0 -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -j ACCEPT # # Rule 37 (global) # echo "Rule 37 (global)" # # firewall:Policy:37: warning: Empty MAC address in rule $IPTABLES -N Cid3DB0B628.0 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cid3DB0B628.0 $IPTABLES -A Cid3DB0B628.0 -m mac --mac-source 00:10:4b:de:e9:70 -j ACCEPT $IPTABLES -A Cid3DB0B628.0 -m mac --mac-source 00:10:4b:de:e9:71 -j ACCEPT $IPTABLES -A Cid3DB0B628.0 -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT $IPTABLES -A Cid3DB0B628.0 -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -j ACCEPT $IPTABLES -A Cid3DB0B628.0 -s 192.168.1.20 -j ACCEPT # # Rule 38 (global) # echo "Rule 38 (global)" # # firewall:Policy:38: warning: Empty MAC address in rule $IPTABLES -N Cid3DE474B7.0 $IPTABLES -A FORWARD -p tcp -m tcp --sport 53 -d 192.168.1.10 -m state --state NEW -j Cid3DE474B7.0 $IPTABLES -A Cid3DE474B7.0 -m mac --mac-source 00:10:4b:de:e9:70 -j ACCEPT $IPTABLES -A Cid3DE474B7.0 -m mac --mac-source 00:10:4b:de:e9:71 -j ACCEPT $IPTABLES -A Cid3DE474B7.0 -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT $IPTABLES -A Cid3DE474B7.0 -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -j ACCEPT # # Rule 39 (global) # echo "Rule 39 (global)" # # firewall:Policy:39: warning: Empty MAC address in rule $IPTABLES -N Cpol-firewall2-2.0 $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 10000:11000 -m state --state NEW -j Cpol-firewall2-2.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport -d 192.168.1.10 --dports 113,13,53,2105,21,70,80,443,143,993,6667,6667,543,544,389 -m state --state NEW -j Cpol-firewall2-2.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport -d 192.168.1.10 --dports 98,3306,2049,119,110,5432,515,26000,512,513,514,4321,25,465,1080 -m state --state NEW -j Cpol-firewall2-2.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport -d 192.168.1.10 --dports 3128,22,111,23,540,7100 -m state --state NEW -j Cpol-firewall2-2.0 $IPTABLES -A Cpol-firewall2-2.0 -m mac --mac-source 00:10:4b:de:e9:70 -j ACCEPT $IPTABLES -A Cpol-firewall2-2.0 -m mac --mac-source 00:10:4b:de:e9:71 -j ACCEPT $IPTABLES -A Cpol-firewall2-2.0 -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT $IPTABLES -A Cpol-firewall2-2.0 -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -j ACCEPT # # Rule 40 (global) # echo "Rule 40 (global)" # # firewall:Policy:40: warning: Empty MAC address in rule $IPTABLES -N Cid445FAA6D31658.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j Cid445FAA6D31658.0 $IPTABLES -A Cid445FAA6D31658.0 -m mac --mac-source 00:10:4b:de:e9:70 -j ACCEPT $IPTABLES -A Cid445FAA6D31658.0 -m mac --mac-source 00:10:4b:de:e9:71 -j ACCEPT $IPTABLES -A Cid445FAA6D31658.0 -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT $IPTABLES -A Cid445FAA6D31658.0 -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -j ACCEPT $IPTABLES -N Cid445FAA6D31658.1 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -m state --state NEW -j Cid445FAA6D31658.1 $IPTABLES -A Cid445FAA6D31658.1 -m mac --mac-source 00:10:4b:de:e9:70 -j ACCEPT $IPTABLES -A Cid445FAA6D31658.1 -m mac --mac-source 00:10:4b:de:e9:71 -j ACCEPT $IPTABLES -A Cid445FAA6D31658.1 -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT $IPTABLES -A Cid445FAA6D31658.1 -m mac --mac-source 00:10:4b:de:e9:6f -s 192.168.1.10 -j ACCEPT # # Rule 41 (global) # echo "Rule 41 (global)" # # firewall:Policy:41: warning: Can not match MAC address of the firewall (chain OUTPUT) $IPTABLES -A OUTPUT -s 192.168.1.1 -d 192.168.1.10 -m state --state NEW -j ACCEPT # # Rule 42 (global) # echo "Rule 42 (global)" # $IPTABLES -N Cpol-firewall2-3.0 $IPTABLES -A FORWARD -d 192.168.1.10 -m state --state NEW -j Cpol-firewall2-3.0 $IPTABLES -N Cpol-firewall2-3.1 $IPTABLES -A Cpol-firewall2-3.0 -s 211.11.11.11 -j Cpol-firewall2-3.1 $IPTABLES -A Cpol-firewall2-3.0 -s 211.22.22.22 -j Cpol-firewall2-3.1 $IPTABLES -N RULE_42 $IPTABLES -A Cpol-firewall2-3.1 -m time --timestart 18:00 --timestop 23:59 -j RULE_42 $IPTABLES -A Cpol-firewall2-3.1 -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_42 $IPTABLES -A Cpol-firewall2-3.1 -m time --timestart 00:00 --timestop 23:59 --days Sun -j RULE_42 $IPTABLES -A Cpol-firewall2-3.1 -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j RULE_42 $IPTABLES -A RULE_42 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A RULE_42 -j ACCEPT # # Rule 43 (global) # echo "Rule 43 (global)" # $IPTABLES -N Cid3FB8455E.0 $IPTABLES -A FORWARD -p tcp -m tcp --dport 10000:11000 -m state --state NEW -j Cid3FB8455E.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,143,993,6667,6667,543,544,389 -m state --state NEW -j Cid3FB8455E.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 98,3306,2049,119,110,5432,515,26000,512,513,514,4321,25,465,1080 -m state --state NEW -j Cid3FB8455E.0 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 3128,22,111,23,540,7100 -m state --state NEW -j Cid3FB8455E.0 $IPTABLES -N Cid3FB8455E.1 $IPTABLES -A Cid3FB8455E.0 -s 211.11.11.11 -j Cid3FB8455E.1 $IPTABLES -A Cid3FB8455E.0 -s 211.22.22.22 -j Cid3FB8455E.1 $IPTABLES -A Cid3FB8455E.1 -d 192.168.1.10 -j ACCEPT $IPTABLES -A Cid3FB8455E.1 -d 192.168.1.20 -j ACCEPT # # Rule 44 (global) # echo "Rule 44 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp --sport 1024:65535 -d 192.168.1.10 --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp --sport 1024:65535 -d 192.168.1.10 --dport 80 -m state --state NEW -j ACCEPT # # Rule 45 (global) # echo "Rule 45 (global)" # # Rule #20 test: from Rock $IPTABLES -A OUTPUT -p tcp -m tcp --sport 1024:65535 -d 192.168.1.10 --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp --sport 53 -d 192.168.1.10 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport -d 192.168.1.10 --dports 53,3128 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp --sport 1024:65535 -d 192.168.1.10 --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp --sport 53 -d 192.168.1.10 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -m multiport -d 192.168.1.10 --dports 53,3128 -m state --state NEW -j ACCEPT # # Rule 46 (global) # echo "Rule 46 (global)" # $IPTABLES -N Cpol-firewall2-4.0 $IPTABLES -A OUTPUT -d 192.168.1.0/24 -m state --state NEW -j Cpol-firewall2-4.0 $IPTABLES -A Cpol-firewall2-4.0 -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.0 -p icmp -m icmp --icmp-type 0/0 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.0 -p icmp -m icmp --icmp-type 11/0 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.0 -p icmp -m icmp --icmp-type 11/1 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.0 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT $IPTABLES -N Cpol-firewall2-4.1 $IPTABLES -A INPUT -d 192.168.1.0/24 -m state --state NEW -j Cpol-firewall2-4.1 $IPTABLES -A Cpol-firewall2-4.1 -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.1 -p icmp -m icmp --icmp-type 0/0 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.1 -p icmp -m icmp --icmp-type 11/0 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.1 -p icmp -m icmp --icmp-type 11/1 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.1 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT $IPTABLES -N Cpol-firewall2-4.2 $IPTABLES -A FORWARD -d 192.168.1.0/24 -m state --state NEW -j Cpol-firewall2-4.2 $IPTABLES -A Cpol-firewall2-4.2 -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.2 -p icmp -m icmp --icmp-type 0/0 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.2 -p icmp -m icmp --icmp-type 11/0 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.2 -p icmp -m icmp --icmp-type 11/1 -j ACCEPT $IPTABLES -A Cpol-firewall2-4.2 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT # # Rule 47 (global) # echo "Rule 47 (global)" # $IPTABLES -N Cid3CD8770E.0 $IPTABLES -A OUTPUT -d 192.168.1.11 -m state --state NEW -j Cid3CD8770E.0 $IPTABLES -A OUTPUT -d 192.168.1.12/30 -m state --state NEW -j Cid3CD8770E.0 $IPTABLES -A Cid3CD8770E.0 -p tcp -m tcp -m multiport --dports 113,80,443,143,25,22,540 -j ACCEPT $IPTABLES -A Cid3CD8770E.0 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT $IPTABLES -N Cid3CD8770E.1 $IPTABLES -A INPUT -d 192.168.1.11 -m state --state NEW -j Cid3CD8770E.1 $IPTABLES -A INPUT -d 192.168.1.12/30 -m state --state NEW -j Cid3CD8770E.1 $IPTABLES -A Cid3CD8770E.1 -p tcp -m tcp -m multiport --dports 113,80,443,143,25,22,540 -j ACCEPT $IPTABLES -A Cid3CD8770E.1 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT $IPTABLES -N Cid3CD8770E.2 $IPTABLES -A FORWARD -d 192.168.1.11 -m state --state NEW -j Cid3CD8770E.2 $IPTABLES -A FORWARD -d 192.168.1.12/30 -m state --state NEW -j Cid3CD8770E.2 $IPTABLES -A Cid3CD8770E.2 -p tcp -m tcp -m multiport --dports 113,80,443,143,25,22,540 -j ACCEPT $IPTABLES -A Cid3CD8770E.2 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT # # Rule 48 (global) # echo "Rule 48 (global)" # $IPTABLES -N Cid3CD87B1E.0 $IPTABLES -A OUTPUT -d 192.168.1.11 -m state --state NEW -j Cid3CD87B1E.0 $IPTABLES -A OUTPUT -d 192.168.1.12 -m state --state NEW -j Cid3CD87B1E.0 $IPTABLES -A OUTPUT -d 192.168.1.13 -m state --state NEW -j Cid3CD87B1E.0 $IPTABLES -A OUTPUT -d 192.168.1.14 -m state --state NEW -j Cid3CD87B1E.0 $IPTABLES -A OUTPUT -d 192.168.1.15 -m state --state NEW -j Cid3CD87B1E.0 $IPTABLES -A Cid3CD87B1E.0 -p tcp -m tcp -m multiport --dports 113,80,443,143,25,22,540 -j ACCEPT $IPTABLES -A Cid3CD87B1E.0 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT $IPTABLES -N Cid3CD87B1E.1 $IPTABLES -A FORWARD -d 192.168.1.11 -m state --state NEW -j Cid3CD87B1E.1 $IPTABLES -A FORWARD -d 192.168.1.12 -m state --state NEW -j Cid3CD87B1E.1 $IPTABLES -A FORWARD -d 192.168.1.13 -m state --state NEW -j Cid3CD87B1E.1 $IPTABLES -A FORWARD -d 192.168.1.14 -m state --state NEW -j Cid3CD87B1E.1 $IPTABLES -A FORWARD -d 192.168.1.15 -m state --state NEW -j Cid3CD87B1E.1 $IPTABLES -A Cid3CD87B1E.1 -p tcp -m tcp -m multiport --dports 113,80,443,143,25,22,540 -j ACCEPT $IPTABLES -A Cid3CD87B1E.1 -m ip_conntrack_talk -m ip_nat_talk -j ACCEPT # # Rule 49 (global) # echo "Rule 49 (global)" # # group "special combined srv" # has couple of UDP services, # plus "ALL UDP" service, which has # empty ports specs. This is special # case for multiport. $IPTABLES -N Cid3E1FD93A.0 $IPTABLES -A INPUT -p udp -m udp -s 192.168.1.0/24 -m state --state NEW -j Cid3E1FD93A.0 $IPTABLES -A INPUT -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -m state --state NEW -j Cid3E1FD93A.0 $IPTABLES -A Cid3E1FD93A.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E1FD93A.0 -d 222.222.222.222 -j ACCEPT # # Rule 50 (global) # echo "Rule 50 (global)" # # another test case for multiport: this rule # has 16 TCP services and should be split onto # two rules. If both rules use "-m multiport", then # rule with a single service should use "--dports". # It may be acceptable to not use multiport # in the rule with a single service at all. $IPTABLES -N Cid41D0F052.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 10000:11000 -m state --state NEW -j Cid41D0F052.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport -s 192.168.1.0/24 --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -m state --state NEW -j Cid41D0F052.0 $IPTABLES -N RULE_50 $IPTABLES -A Cid41D0F052.0 -d 192.168.1.11 -j RULE_50 $IPTABLES -A Cid41D0F052.0 -d 192.168.1.12/30 -j RULE_50 $IPTABLES -N Cid41D0F052.1 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 10000:11000 -m state --state NEW -j Cid41D0F052.1 $IPTABLES -A INPUT -p tcp -m tcp -m multiport -s 192.168.1.0/24 --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -m state --state NEW -j Cid41D0F052.1 $IPTABLES -A Cid41D0F052.1 -d 192.168.1.11 -j RULE_50 $IPTABLES -A Cid41D0F052.1 -d 192.168.1.12/30 -j RULE_50 $IPTABLES -N Cid41D0F052.2 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 10000:11000 -m state --state NEW -j Cid41D0F052.2 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport -s 192.168.1.0/24 --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -m state --state NEW -j Cid41D0F052.2 $IPTABLES -A Cid41D0F052.2 -d 192.168.1.11 -j RULE_50 $IPTABLES -A Cid41D0F052.2 -d 192.168.1.12/30 -j RULE_50 $IPTABLES -A RULE_50 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A RULE_50 -j ACCEPT # # Rule 51 (global) # echo "Rule 51 (global)" # $IPTABLES -N Cid3B58E180.0 $IPTABLES -A INPUT -s 192.168.1.1 -m state --state NEW -j Cid3B58E180.0 $IPTABLES -A INPUT -s 222.222.222.222 -m state --state NEW -j Cid3B58E180.0 $IPTABLES -N RULE_51 $IPTABLES -A Cid3B58E180.0 -d 192.168.1.1 -j RULE_51 $IPTABLES -A Cid3B58E180.0 -d 222.222.222.222 -j RULE_51 $IPTABLES -N Cid3B58E180.1 $IPTABLES -A OUTPUT -s 192.168.1.1 -m state --state NEW -j Cid3B58E180.1 $IPTABLES -A OUTPUT -s 222.222.222.222 -m state --state NEW -j Cid3B58E180.1 $IPTABLES -A Cid3B58E180.1 -d 192.168.1.1 -j RULE_51 $IPTABLES -A Cid3B58E180.1 -d 222.222.222.222 -j RULE_51 $IPTABLES -A RULE_51 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A RULE_51 -j ACCEPT # # Rule 52 (global) # echo "Rule 52 (global)" # $IPTABLES -N Cid3D41A4F4.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid3D41A4F4.0 $IPTABLES -N Cid3D41A4F4.1 $IPTABLES -A Cid3D41A4F4.0 -s 192.168.1.1 -j Cid3D41A4F4.1 $IPTABLES -A Cid3D41A4F4.0 -s 222.222.222.222 -j Cid3D41A4F4.1 $IPTABLES -A Cid3D41A4F4.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3D41A4F4.1 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid3D41A4F4.2 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid3D41A4F4.2 $IPTABLES -N Cid3D41A4F4.3 $IPTABLES -A Cid3D41A4F4.2 -s 192.168.1.1 -j Cid3D41A4F4.3 $IPTABLES -A Cid3D41A4F4.2 -s 222.222.222.222 -j Cid3D41A4F4.3 $IPTABLES -A Cid3D41A4F4.3 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3D41A4F4.3 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid3D41A4F4.4 $IPTABLES -A OUTPUT -p udp -m udp -d 200.200.200.200 --dport 161 -m state --state NEW -j Cid3D41A4F4.4 $IPTABLES -A Cid3D41A4F4.4 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3D41A4F4.4 -s 222.222.222.222 -j ACCEPT # # Rule 53 (global) # echo "Rule 53 (global)" # # Automatically generated 'masquerading' rule $IPTABLES -A INPUT -s 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 222.222.222.222 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 222.222.222.222 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 54 (global) # echo "Rule 54 (global)" # # similar to a standard 'masquerading' # rule, but not so permissive as it does # not allow access to the firewall $IPTABLES -N Cid3CE894DA.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j Cid3CE894DA.0 $IPTABLES -A Cid3CE894DA.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3CE894DA.0 -d 222.222.222.222 -j RETURN $IPTABLES -A Cid3CE894DA.0 -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 55 (global) # echo "Rule 55 (global)" # $IPTABLES -N Cid40F1CFA3.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j Cid40F1CFA3.0 $IPTABLES -A Cid40F1CFA3.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid40F1CFA3.0 -d 222.222.222.222 -j RETURN $IPTABLES -A Cid40F1CFA3.0 -j ACCEPT $IPTABLES -N Cid40F1CFA3.1 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j Cid40F1CFA3.1 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j Cid40F1CFA3.1 $IPTABLES -A Cid40F1CFA3.1 -d 33.33.33.0/24 -j RETURN $IPTABLES -A Cid40F1CFA3.1 -j ACCEPT # # Rule 56 (global) # echo "Rule 56 (global)" # $IPTABLES -N Cid413D6500.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -m state --state NEW -j Cid413D6500.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -m state --state NEW -j Cid413D6500.0 $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -m state --state NEW -j Cid413D6500.0 $IPTABLES -N Cid413D6500.1 $IPTABLES -A Cid413D6500.0 -s 192.168.1.0/24 -j Cid413D6500.1 $IPTABLES -A Cid413D6500.0 -s 192.168.2.0/24 -j Cid413D6500.1 $IPTABLES -A Cid413D6500.1 -d 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid413D6500.1 -d 192.168.2.0/24 -j ACCEPT $IPTABLES -N Cid413D6500.2 $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -m state --state NEW -j Cid413D6500.2 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -m state --state NEW -j Cid413D6500.2 $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -m state --state NEW -j Cid413D6500.2 $IPTABLES -N Cid413D6500.3 $IPTABLES -A Cid413D6500.2 -s 192.168.1.0/24 -j Cid413D6500.3 $IPTABLES -A Cid413D6500.2 -s 192.168.2.0/24 -j Cid413D6500.3 $IPTABLES -A Cid413D6500.3 -d 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid413D6500.3 -d 192.168.2.0/24 -j ACCEPT $IPTABLES -N Cid413D6500.4 $IPTABLES -A FORWARD -p tcp -m tcp --dport 10000:11000 -m state --state NEW -j Cid413D6500.4 $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -m state --state NEW -j Cid413D6500.4 $IPTABLES -A FORWARD -p udp -m udp -m multiport --dports 53,161 -m state --state NEW -j Cid413D6500.4 $IPTABLES -N Cid413D6500.5 $IPTABLES -A Cid413D6500.4 -s 192.168.1.0/24 -j Cid413D6500.5 $IPTABLES -A Cid413D6500.4 -s 192.168.2.0/24 -j Cid413D6500.5 $IPTABLES -A Cid413D6500.5 -d 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid413D6500.5 -d 192.168.2.0/24 -j ACCEPT # # Rule 57 (global) # echo "Rule 57 (global)" # # Automatically generated 'catch all' rule $IPTABLES -N RULE_57 $IPTABLES -A OUTPUT -j RULE_57 $IPTABLES -A INPUT -j RULE_57 $IPTABLES -A FORWARD -j RULE_57 $IPTABLES -A RULE_57 -m limit --limit 5/second -j LOG --log-level 7 --log-prefix "CUSTOM LOGGING" $IPTABLES -A RULE_57 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all # backup ssh access $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.100/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.100/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:06 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall5.fw.orig0000755000175000017500000004553511733011756021757 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:56 2012 PDT by vadim # # files: * firewall5.fw /etc/fw/firewall5.fw # # Compiled for iptables (any version) # # testing firewall_is_part_of_any_and_networks. Also testing SNAT and DNAT rules when external interface has dynamic address. # dynamic interface ppp0 has an address object attached to it (interface used to be static and had an address, then got converted to dynamic but address object is still there). Compiler should ignore this address object and issue a warning. # All "configure interfaces" options are off, testing shell functions for this case. # firewall5::: error: Dynamic interface ppp0 should not have an IP address object attached to it. This IP address object will be ignored. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces getaddr ppp0 i_ppp0 getaddr6 ppp0 i_ppp0_v6 getnet ppp0 i_ppp0_network getnet6 ppp0 i_ppp0_v6_network getaddr ppp1 i_ppp1 getaddr6 ppp1 i_ppp1_v6 getnet ppp1 i_ppp1_network getnet6 ppp1 i_ppp1_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o ppp0 -s 192.168.1.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o ppp1 -s 192.168.1.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 77.77.77.77 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 77.77.77.77 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.1 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.1 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.2.1 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.2.1 -j SNAT --to-source 22.22.22.23 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $i_ppp0 --dport 22 -j DNAT --to-destination 192.168.1.10:22 done for i_ppp1 in $i_ppp1_list do test -n "$i_ppp1" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $i_ppp1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 done $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 # ================ Table 'filter', rule set Policy # # Rule 0 (ppp0) # echo "Rule 0 (ppp0)" # $IPTABLES -N Cid3E4A05B9.0 $IPTABLES -A INPUT -i ppp0 -j Cid3E4A05B9.0 $IPTABLES -A FORWARD -i ppp0 -j Cid3E4A05B9.0 for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A Cid3E4A05B9.0 -s $i_ppp0 -j RETURN done $IPTABLES -A Cid3E4A05B9.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -N In_RULE_0_3 $IPTABLES -A Cid3E4A05B9.0 -j In_RULE_0_3 $IPTABLES -A In_RULE_0_3 -j LOG $IPTABLES -A In_RULE_0_3 -j DROP # # Rule 1 (ppp1) # echo "Rule 1 (ppp1)" # $IPTABLES -N Cid3E8F5B72.0 $IPTABLES -A INPUT -i ppp1 -j Cid3E8F5B72.0 $IPTABLES -A FORWARD -i ppp1 -j Cid3E8F5B72.0 for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A Cid3E8F5B72.0 -s $i_ppp0 -j RETURN done $IPTABLES -A Cid3E8F5B72.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -N In_RULE_1_3 $IPTABLES -A Cid3E8F5B72.0 -j In_RULE_1_3 $IPTABLES -A In_RULE_1_3 -j LOG $IPTABLES -A In_RULE_1_3 -j DROP # # Rule 2 (ppp1,ppp0) # echo "Rule 2 (ppp1,ppp0)" # $IPTABLES -N Cid212010X42308.0 $IPTABLES -A INPUT -i ppp0 -j Cid212010X42308.0 $IPTABLES -A INPUT -i ppp1 -j Cid212010X42308.0 $IPTABLES -A FORWARD -i ppp0 -j Cid212010X42308.0 $IPTABLES -A FORWARD -i ppp1 -j Cid212010X42308.0 for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A Cid212010X42308.0 -s $i_ppp0 -j RETURN done for i_ppp1 in $i_ppp1_list do test -n "$i_ppp1" && $IPTABLES -A Cid212010X42308.0 -s $i_ppp1 -j RETURN done $IPTABLES -A Cid212010X42308.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -N In_RULE_2_3 $IPTABLES -A Cid212010X42308.0 -j In_RULE_2_3 $IPTABLES -A In_RULE_2_3 -j LOG $IPTABLES -A In_RULE_2_3 -j DROP # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 for i_ppp0 in $i_ppp0_list do for i_ppp1 in $i_ppp1_list do test -n "$i_ppp0" && test -n "$i_ppp1" && $IPTABLES -A INPUT -s $i_ppp0 -d $i_ppp1 -j RULE_3 done done for i_ppp0 in $i_ppp0_list do for i_ppp1 in $i_ppp1_list do test -n "$i_ppp0" && test -n "$i_ppp1" && $IPTABLES -A OUTPUT -s $i_ppp0 -d $i_ppp1 -j RULE_3 done done $IPTABLES -A RULE_3 -j LOG $IPTABLES -A RULE_3 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A OUTPUT -p tcp -m tcp -d $i_ppp0 --dport 22 -m state --state NEW -j ACCEPT done for i_ppp1 in $i_ppp1_list do test -n "$i_ppp1" && $IPTABLES -A OUTPUT -p tcp -m tcp -d $i_ppp1 --dport 22 -m state --state NEW -j ACCEPT done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A INPUT -p tcp -m tcp -d $i_ppp0 --dport 22 -m state --state NEW -j ACCEPT done for i_ppp1 in $i_ppp1_list do test -n "$i_ppp1" && $IPTABLES -A INPUT -p tcp -m tcp -d $i_ppp1 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 5 (global) # echo "Rule 5 (global)" # # hostF has the same IP address as firewal. $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_5 $IPTABLES -A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid3E4A0454.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid3E4A0454.0 for i_ppp1 in $i_ppp1_list do test -n "$i_ppp1" && $IPTABLES -A Cid3E4A0454.0 -d $i_ppp1 -j ACCEPT done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A Cid3E4A0454.0 -d $i_ppp0 -j ACCEPT done $IPTABLES -A Cid3E4A0454.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E4A0454.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid3E987157.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3E987157.0 $IPTABLES -A Cid3E987157.0 -d 77.77.77.77 -j ACCEPT $IPTABLES -A Cid3E987157.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E987157.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -N Cid3E987157.1 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3E987157.1 $IPTABLES -A Cid3E987157.1 -d 77.77.77.77 -j ACCEPT $IPTABLES -A Cid3E987157.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E987157.1 -d 192.168.2.1 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N Cid3E9871F4.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3E9871F4.0 $IPTABLES -N RULE_10 $IPTABLES -A Cid3E9871F4.0 -d 77.77.77.77 -j RULE_10 $IPTABLES -A Cid3E9871F4.0 -d 192.168.1.1 -j RULE_10 $IPTABLES -A Cid3E9871F4.0 -d 192.168.2.1 -j RULE_10 $IPTABLES -N Cid3E9871F4.1 $IPTABLES -A FORWARD -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3E9871F4.1 $IPTABLES -A Cid3E9871F4.1 -d 77.77.77.77 -j RULE_10 $IPTABLES -A Cid3E9871F4.1 -d 192.168.1.1 -j RULE_10 $IPTABLES -A Cid3E9871F4.1 -d 192.168.2.1 -j RULE_10 $IPTABLES -A RULE_10 -j LOG $IPTABLES -A RULE_10 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # firewall is part of Any, so compiler should # generate code in both FORWARD and # OUTPUT chains $IPTABLES -A OUTPUT -d 200.200.200.200 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 200.200.200.200 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # firewall is part of Any, compiler should # generate code for both FORWARD and # INPUT chains $IPTABLES -A INPUT -s 200.200.200.200 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 200.200.200.200 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # because firewall has interface on network # internal_net, compiler should generate code # for both FORWARD and INPUT chains $IPTABLES -A INPUT -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -N Cid3B19C5CA.0 $IPTABLES -A OUTPUT -d 200.200.200.200 -m state --state NEW -j Cid3B19C5CA.0 $IPTABLES -A Cid3B19C5CA.0 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid3B19C5CA.0 -s 192.168.2.0/24 -j ACCEPT $IPTABLES -N Cid3B19C5CA.1 $IPTABLES -A FORWARD -d 200.200.200.200 -m state --state NEW -j Cid3B19C5CA.1 $IPTABLES -A Cid3B19C5CA.1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid3B19C5CA.1 -s 192.168.2.0/24 -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # Automatically generated 'catch all' rule $IPTABLES -N RULE_15 $IPTABLES -A OUTPUT -j RULE_15 $IPTABLES -A INPUT -j RULE_15 $IPTABLES -A FORWARD -j RULE_15 $IPTABLES -A RULE_15 -j LOG $IPTABLES -A RULE_15 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:56 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/rh90.fw.orig0000755000175000017500000002720711733011756020643 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:38 2012 PDT by vadim # # files: * rh90.fw /etc/rh90.fw # # Compiled for iptables (any version) # # This is an example of a firewall protecting a host ( a server or a workstation). Only SSH access to the host is permitted. Host has dynamic address. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 lo" for i in eth0 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 10.3.14.58/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 10.3.14.58 -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 10.3.14.58 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (lo) # echo "Rule 1 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # SSH Access to the host; useful ICMP # types; ping request $IPTABLES -N Cid41528C32.0 $IPTABLES -A OUTPUT -d 10.3.14.58 -m state --state NEW -j Cid41528C32.0 $IPTABLES -A Cid41528C32.0 -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A Cid41528C32.0 -p icmp -m icmp --icmp-type 0/0 -j ACCEPT $IPTABLES -A Cid41528C32.0 -p icmp -m icmp --icmp-type 8/0 -j ACCEPT $IPTABLES -A Cid41528C32.0 -p icmp -m icmp --icmp-type 11/0 -j ACCEPT $IPTABLES -A Cid41528C32.0 -p icmp -m icmp --icmp-type 11/1 -j ACCEPT $IPTABLES -A Cid41528C32.0 -p tcp -m tcp --dport 22 -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 0/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 11/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 11/1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A INPUT -s 10.3.14.58 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N RULE_4 $IPTABLES -A OUTPUT -j RULE_4 $IPTABLES -A INPUT -j RULE_4 $IPTABLES -A FORWARD -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -A RULE_4 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:38 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall2-4.fw.orig0000755000175000017500000004236011733011756022106 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:28 2012 PDT by vadim # # files: * firewall2-4.fw /etc/fw/firewall2-4.fw # # Compiled for iptables (any version) # # tests for error conditions in NATCompiler_ipt::VerifyRules # firewall2-4:NAT:0: error: Can not use negation in translated source # firewall2-4:NAT:1: error: Can not use negation in translated destination. # firewall2-4:NAT:2: error: Can not use negation in translated service. # firewall2-4:NAT:3: error: Translated service should be 'Original' or should contain single object. # firewall2-4:NAT:4: error: Translated service should be 'Original' or should contain single object. # firewall2-4:NAT:5: error: Non-contiguous address range in Translated Destination in load balancing NAT rule # firewall2-4:NAT:7: error: Action 'Branch' needs NAT rule set to point to # firewall2-4:NAT:9: error: Can not use unnumbered interface in Translated Source of a Source translation rule. # firewall2-4:NAT:10: error: Original and translated source should both be networks of the same size. # firewall2-4:NAT:12: error: Can not use service object in Translated Service if Original Service is 'Any'. # firewall2-4:NAT:13: error: NAT rule can not change service types: UDPService to TCPService # firewall2-4:NAT:13: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. # firewall2-4:NAT:14: error: NAT rule can not change service types: UDPService to TCPService # firewall2-4:NAT:14: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. # firewall2-4:NAT:14: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.10/24 192.168.1.20/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 22.22.22.0/32 22.22.22.1/32 22.22.22.2/32 22.22.22.3/32 22.22.22.4/32 22.22.22.5/32 22.22.22.6/32 22.22.22.7/32 22.22.22.8/32 22.22.22.9/32 22.22.22.10/32 22.22.22.11/32 22.22.22.12/32 22.22.22.13/32 22.22.22.14/32 22.22.22.15/32 22.22.22.16/32 22.22.22.17/32 22.22.22.18/32 22.22.22.19/32 22.22.22.20/32 22.22.22.21/32 22.22.22.22/32 22.22.22.23/32 22.22.22.24/32 22.22.22.25/32 22.22.22.26/32 22.22.22.27/32 22.22.22.28/32 22.22.22.29/32 22.22.22.30/32 22.22.22.31/32 22.22.22.32/32 22.22.22.33/32 22.22.22.34/32 22.22.22.35/32 22.22.22.36/32 22.22.22.37/32 22.22.22.38/32 22.22.22.39/32 22.22.22.40/32 22.22.22.41/32 22.22.22.42/32 22.22.22.43/32 22.22.22.44/32 22.22.22.45/32 22.22.22.46/32 22.22.22.47/32 22.22.22.48/32 22.22.22.49/32 22.22.22.50/32 22.22.22.51/32 22.22.22.52/32 22.22.22.53/32 22.22.22.54/32 22.22.22.55/32 22.22.22.56/32 22.22.22.57/32 22.22.22.58/32 22.22.22.59/32 22.22.22.60/32 22.22.22.61/32 22.22.22.62/32 22.22.22.63/32 22.22.22.64/32 22.22.22.65/32 22.22.22.66/32 22.22.22.67/32 22.22.22.68/32 22.22.22.69/32 22.22.22.70/32 22.22.22.71/32 22.22.22.72/32 22.22.22.73/32 22.22.22.74/32 22.22.22.75/32 22.22.22.76/32 22.22.22.77/32 22.22.22.78/32 22.22.22.79/32 22.22.22.80/32 22.22.22.81/32 22.22.22.82/32 22.22.22.83/32 22.22.22.84/32 22.22.22.85/32 22.22.22.86/32 22.22.22.87/32 22.22.22.88/32 22.22.22.89/32 22.22.22.90/32 22.22.22.91/32 22.22.22.92/32 22.22.22.93/32 22.22.22.94/32 22.22.22.95/32 22.22.22.96/32 22.22.22.97/32 22.22.22.98/32 22.22.22.99/32 22.22.22.100/32 22.22.22.101/32 22.22.22.102/32 22.22.22.103/32 22.22.22.104/32 22.22.22.105/32 22.22.22.106/32 22.22.22.107/32 22.22.22.108/32 22.22.22.109/32 22.22.22.110/32 22.22.22.111/32 22.22.22.112/32 22.22.22.113/32 22.22.22.114/32 22.22.22.115/32 22.22.22.116/32 22.22.22.117/32 22.22.22.118/32 22.22.22.119/32 22.22.22.120/32 22.22.22.121/32 22.22.22.122/32 22.22.22.123/32 22.22.22.124/32 22.22.22.125/32 22.22.22.126/32 22.22.22.127/32 22.22.22.128/32 22.22.22.129/32 22.22.22.130/32 22.22.22.131/32 22.22.22.132/32 22.22.22.133/32 22.22.22.134/32 22.22.22.135/32 22.22.22.136/32 22.22.22.137/32 22.22.22.138/32 22.22.22.139/32 22.22.22.140/32 22.22.22.141/32 22.22.22.142/32 22.22.22.143/32 22.22.22.144/32 22.22.22.145/32 22.22.22.146/32 22.22.22.147/32 22.22.22.148/32 22.22.22.149/32 22.22.22.150/32 22.22.22.151/32 22.22.22.152/32 22.22.22.153/32 22.22.22.154/32 22.22.22.155/32 22.22.22.156/32 22.22.22.157/32 22.22.22.158/32 22.22.22.159/32 22.22.22.160/32 22.22.22.161/32 22.22.22.162/32 22.22.22.163/32 22.22.22.164/32 22.22.22.165/32 22.22.22.166/32 22.22.22.167/32 22.22.22.168/32 22.22.22.169/32 22.22.22.170/32 22.22.22.171/32 22.22.22.172/32 22.22.22.173/32 22.22.22.174/32 22.22.22.175/32 22.22.22.176/32 22.22.22.177/32 22.22.22.178/32 22.22.22.179/32 22.22.22.180/32 22.22.22.181/32 22.22.22.182/32 22.22.22.183/32 22.22.22.184/32 22.22.22.185/32 22.22.22.186/32 22.22.22.187/32 22.22.22.188/32 22.22.22.189/32 22.22.22.190/32 22.22.22.191/32 22.22.22.192/32 22.22.22.193/32 22.22.22.194/32 22.22.22.195/32 22.22.22.196/32 22.22.22.197/32 22.22.22.198/32 22.22.22.199/32 22.22.22.200/32 22.22.22.201/32 22.22.22.202/32 22.22.22.203/32 22.22.22.204/32 22.22.22.205/32 22.22.22.206/32 22.22.22.207/32 22.22.22.208/32 22.22.22.209/32 22.22.22.210/32 22.22.22.211/32 22.22.22.212/32 22.22.22.213/32 22.22.22.214/32 22.22.22.215/32 22.22.22.216/32 22.22.22.217/32 22.22.22.218/32 22.22.22.219/32 22.22.22.220/32 22.22.22.221/32 22.22.22.222/32 22.22.22.223/32 22.22.22.224/32 22.22.22.225/32 22.22.22.226/32 22.22.22.227/32 22.22.22.228/32 22.22.22.229/32 22.22.22.230/32 22.22.22.231/32 22.22.22.232/32 22.22.22.233/32 22.22.22.234/32 22.22.22.235/32 22.22.22.236/32 22.22.22.237/32 22.22.22.238/32 22.22.22.239/32 22.22.22.240/32 22.22.22.241/32 22.22.22.242/32 22.22.22.243/32 22.22.22.244/32 22.22.22.245/32 22.22.22.246/32 22.22.22.247/32 22.22.22.248/32 22.22.22.249/32 22.22.22.250/32 22.22.22.251/32 22.22.22.252/32 22.22.22.253/32 22.22.22.254/32" "" update_addresses_of_interface "eth2 192.168.2.1/24 192.168.2.40/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # # firewall2-4:NAT:5: error: Non-contiguous address range in Translated Destination in load balancing NAT rule $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10-192.168.1.20 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10-192.168.1.20 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.20 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j NETMAP --to 22.22.22.0/24 # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.0/24 -j SNAT --to-source 192.168.2.1 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # 'catch all' rule $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 0 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:28 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/do-diff0000755000175000017500000000033711733011756020012 0ustar sylvestresylvestre#!/bin/sh N=$1 if which opendiff > /dev/null 2>&1; then TOOL="opendiff" elif which tkdiff > /dev/null 2>&1; then TOOL="tkdiff -b -B " else TOOL="diff -U 8 -b -B " fi ${TOOL} firewall${N}.fw.orig firewall${N}.fw fwbuilder-5.1.0.3599/test/ipt/firewall82.fw.orig0000755000175000017500000002577611733011756022051 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:12 2012 PDT by vadim # # files: * firewall82.fw /etc/firewall82.fw # # Compiled for iptables (any version) # # This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside. # Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0 # firewall82:Policy:0: warning: Rule branches to rule set Policy_A which branches back to it, creating a loop FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE # ================ Table 'filter', rule set Policy_A # # Rule Policy_A 0 (global) # echo "Rule Policy_A 0 (global)" # $IPTABLES -N Policy_A $IPTABLES -N Policy_B $IPTABLES -A Policy_A -j Policy_B # # Rule Policy_A 1 (global) # echo "Rule Policy_A 1 (global)" # # recursive branching $IPTABLES -N Policy $IPTABLES -A Policy_A -j Policy # # Rule Policy_A 2 (global) # echo "Rule Policy_A 2 (global)" # $IPTABLES -A Policy_A -j Policy_A # ================ Table 'filter', rule set Policy_B # # Rule Policy_B 0 (global) # echo "Rule Policy_B 0 (global)" # $IPTABLES -A Policy_B -d 192.0.2.100 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -j Policy_A $IPTABLES -A INPUT -j Policy_A $IPTABLES -A FORWARD -j Policy_A } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:12 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/vrrp_cluster_1_linux-1.fw.orig0000755000175000017500000005071211733011756024405 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * vrrp_cluster_1_linux-1.fw /etc/vrrp_cluster_1_linux-1.fw # # Compiled for iptables 1.4.0 # # # vrrp_cluster_1:Routing:1: error: Object "gw1" used as gateway in the routing rule 1 (main) is not in the same local network as interface eth1 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth0.100" for i in eth0 eth1 lo eth0.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_vlans_of_interface "eth0 eth0.100" clear_vlans_except_known eth0.100@eth0 update_addresses_of_interface "eth0 172.24.0.2/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0.100 192.168.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 10/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 10/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -6 VRRP (automatic) # echo "Rule -6 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -5 VRRP (automatic) # echo "Rule -5 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.3 -d 224.0.0.18 -j ACCEPT # # Rule -4 VRRP (automatic) # echo "Rule -4 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -3 VRRP (automatic) # echo "Rule -3 VRRP (automatic)" # $IPTABLES -A INPUT -i eth0 -p vrrp -s 172.24.0.3 -d 224.0.0.18 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.2 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.2 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.100.1 -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_8 $IPTABLES -A INPUT -m state --state NEW -j RULE_8 $IPTABLES -A FORWARD -m state --state NEW -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -j RULE_9 $IPTABLES -A INPUT -j RULE_9 $IPTABLES -A FORWARD -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # Rule 1 (main) # echo "Routing rule 1 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # ============== EQUAL COST MULTI PATH ============ # echo "Activating ecmp routing rules..." # # Multipath Rule derived from the following routing rules: # # Rule 0 (main) # # Rule 1 (main) # # $IP route add 172.24.1.0/24 \ nexthop via 172.24.0.100 dev eth0 \ nexthop via 172.24.0.100 dev eth1 \ || route_command_error "1" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/linux-2.fw.orig0000755000175000017500000005464011733011756021360 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v4.2.0.3425 # # Generated Fri Jan 7 13:12:17 2011 PST by vadim # # files: * linux-2.fw # # Compiled for iptables (any version) # # linux-2:to_fw:: warning: ignoring cluster rule set "to_fw" because member firewall "linux-2" has rule set with the same name. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" test -x "$LOGGER" && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 $PGM /dev/null 2>&1; test $? = 127 && { echo "$PGM not found" exit 1 } } check_tools() { find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.3/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.3/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.3 --dport 22 -j DNAT --to-destination 192.168.1.100 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 20/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 20/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -N C.0 $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j C.0 $IPTABLES -A C.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A C.0 -s 192.168.100.1 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.3 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.3 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 7 (global) # echo "Rule 7 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A FORWARD -d 172.24.0.2 -j to_fw $IPTABLES -A FORWARD -d 192.168.1.2 -j to_fw $IPTABLES -A FORWARD -d 192.168.100.1 -j to_fw # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -d 172.24.0.1 -j DROP $IPTABLES -A OUTPUT -d 172.24.0.3 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.1 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.3 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # # fw is part of any $IPTABLES -N Cid997025X96143.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid997025X96143.0 $IPTABLES -A Cid997025X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 172.24.0.3 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.3 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # fw is NOT part of any $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # fw is NOT part of any $IPTABLES -N Cid143289X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143289X96143.0 $IPTABLES -A Cid143289X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid143289X96143.0 -s 172.24.0.3 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # fw is NOT part of any $IPTABLES -N Cid1946680X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1946680X96143.0 $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.3 -j ACCEPT # # Rule 14 (eth0) # echo "Rule 14 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid378955X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.0 $IPTABLES -A Cid378955X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.0 -s 172.24.0.3 -j ACCEPT $IPTABLES -N Cid378955X96143.1 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.1 $IPTABLES -A Cid378955X96143.1 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.1 -s 172.24.0.3 -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid1801407X96143.0 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1801407X96143.0 $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.3 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # fw is NOT part of any $IPTABLES -A OUTPUT -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid143343X96143.0 $IPTABLES -A FORWARD -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143343X96143.0 $IPTABLES -A Cid143343X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid143343X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # fw is NOT part of any $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241935X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.0 $IPTABLES -A Cid2241935X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241935X96143.1 $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.1 $IPTABLES -A Cid2241935X96143.1 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.1 -s 192.168.100.1 -j ACCEPT # # Rule 18 (eth0) # echo "Rule 18 (eth0)" # # fw is NOT part of any $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241981X96143.0 $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241981X96143.0 $IPTABLES -A Cid2241981X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241981X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using interface of another cluster in the rule $IPTABLES -N Cid8228X45618.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid8228X45618.0 $IPTABLES -A Cid8228X45618.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.100 -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -N Cid147047X84105.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid147047X84105.0 $IPTABLES -A Cid147047X84105.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.100 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N RULE_21 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_21 $IPTABLES -A INPUT -m state --state NEW -j RULE_21 $IPTABLES -A FORWARD -m state --state NEW -j RULE_21 $IPTABLES -A RULE_21 -j LOG --log-level info --log-prefix "RULE 21 -- DENY " $IPTABLES -A RULE_21 -j DROP # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N RULE_22 $IPTABLES -A OUTPUT -j RULE_22 $IPTABLES -A INPUT -j RULE_22 $IPTABLES -A FORWARD -j RULE_22 $IPTABLES -A RULE_22 -j LOG --log-level info --log-prefix "RULE 22 -- DENY " $IPTABLES -A RULE_22 -j DROP # ============== ROUTING RULES ============== TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" (umask 077 && mkdir $TMPDIRNAME) || exit 1 # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules (IFS=" "; for route in $oldRoutes; do (IFS=' '; $IP route add $route); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) oldRoutes=$($IP route show | sort -k 2) echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 172.24.1.0/24 via 172.24.0.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Fri Jan 7 13:12:17 2011 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/server-cluster-1_server-2.fw.orig0000755000175000017500000002445611733011756024734 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * server-cluster-1_server-2.fw /etc/fw/server-cluster-1_server-2.fw # # Compiled for iptables (any version) # # fw is part of any is OFF # ip forwarding is OFF FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: lo eth0" for i in lo eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0 192.168.1.2/24" "192.168.1.100/24" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o lo -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i lo -p udp -m udp -s 127.0.0.1 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -2 heartbeat (automatic) # echo "Rule -2 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -1 heartbeat (automatic) # echo "Rule -1 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 192.168.1.1 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule 0 (global) # echo "Rule 0 (global)" # # test for ticket #1338 $IPTABLES -A INPUT -s 192.168.1.2 -j DROP $IPTABLES -A INPUT -s 192.168.1.100 -j DROP } ip_forward() { : echo 0 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/openais_cluster_1_linux-1.fw.orig0000755000175000017500000005102111733011756025044 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * openais_cluster_1_linux-1.fw /etc/openais_cluster_1_linux-1.fw # # Compiled for iptables 1.4.0 # # # openais_cluster_1:Routing:1: error: Object "gw1" used as gateway in the routing rule 1 (main) is not in the same local network as interface eth1 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth0.100" for i in eth0 eth1 lo eth0.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_vlans_of_interface "eth0 eth0.100" clear_vlans_except_known eth0.100@eth0 update_addresses_of_interface "eth0 172.24.0.2/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0.100 192.168.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 10/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 10/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 openais (automatic) # echo "Rule -4 openais (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 226.94.1.1 --dport 5405 -j ACCEPT # # Rule -3 openais (automatic) # echo "Rule -3 openais (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 172.24.0.3 -d 226.94.1.1 --dport 5405 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -A OUTPUT -d 172.24.0.1 -j DROP $IPTABLES -A OUTPUT -d 172.24.0.2 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.1 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.2 -j DROP $IPTABLES -A OUTPUT -d 192.168.100.1 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N RULE_7 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_7 $IPTABLES -A OUTPUT -d 172.24.0.2 -j RULE_7 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_7 $IPTABLES -A OUTPUT -d 192.168.1.2 -j RULE_7 $IPTABLES -A OUTPUT -d 192.168.100.1 -j RULE_7 $IPTABLES -A INPUT -j RULE_7 $IPTABLES -A RULE_7 -j LOG --log-level info --log-prefix "RULE 7 -- DENY " $IPTABLES -A RULE_7 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_9 $IPTABLES -A INPUT -m state --state NEW -j RULE_9 $IPTABLES -A FORWARD -m state --state NEW -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -j RULE_10 $IPTABLES -A INPUT -j RULE_10 $IPTABLES -A FORWARD -j RULE_10 $IPTABLES -A RULE_10 -j LOG --log-level info --log-prefix "RULE 10 -- DENY " $IPTABLES -A RULE_10 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # Rule 1 (main) # echo "Routing rule 1 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # ============== EQUAL COST MULTI PATH ============ # echo "Activating ecmp routing rules..." # # Multipath Rule derived from the following routing rules: # # Rule 0 (main) # # Rule 1 (main) # interface vrrp1 belongs to a different firewall (cluster) # $IP route add 172.24.1.0/24 \ nexthop via 172.24.0.100 dev eth0 \ nexthop via 172.24.0.100 dev eth1 \ || route_command_error "1" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/emtpy-table.tbl0000644000175000017500000000007511733011756021501 0ustar sylvestresylvestre# this is an empty address table file # it has no addresses fwbuilder-5.1.0.3599/test/ipt/addr-table-1.tbl0000644000175000017500000000042511733011756021412 0ustar sylvestresylvestre# this is a comment # ; this should be a comment too ; 192.168.1.1 192.168.1.2/32 192.168.1.3/30 192.168.2.128/25 192.168.1.200/32 # comment again 192.168.1.201/32 # this should work, too # ipv6 addresses 2001:458:20:100:250:b7ff:fe00:2af/128 fe80::21d:9ff:fe8b:8e94/64 fwbuilder-5.1.0.3599/test/ipt/quick-cmp.sh0000755000175000017500000000147511733011756021010 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -w -I \"^ *$\" -I \" *# *$\" -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipt v' -I 'Can not find file' -I '====' -I 'log '" for f in $(ls *.fw.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done exit 0 run_diffs_for_file() { xmlfile=$1 folder=$2 fwbedit list -f $xmlfile -o $folder -c -F%name% | sort | while read fwobj; do V="$fwobj <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" done } run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls # run_diffs_for_file cluster-tests.fwb /User/Clusters fwbuilder-5.1.0.3599/test/ipt/firewall61-1.3.x.fw.orig0000755000175000017500000003501411733011756022575 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:01 2012 PDT by vadim # # files: * firewall61-1.3.x.fw /etc/firewall61-1.3.x.fw # # Compiled for iptables 1.3.0 # # testing time litmiting for iptables 1.3.x # firewall61-1.3.x:Policy_ipv6:: warning: target TCPMSS is not supported by ip6tables before v1.3.8 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'mangle', rule set fw61-Policy # # Rule fw61-Policy 0 (global) # echo "Rule fw61-Policy 0 (global)" # $IPTABLES -N fw61-Policy -t mangle $IPTABLES -N fw61-Policy_0 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --days Sat -j fw61-Policy_0 $IPTABLES -t mangle -A fw61-Policy_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -t mangle -A fw61-Policy_0 -j DROP # # Rule fw61-Policy 1 (global) # echo "Rule fw61-Policy 1 (global)" # $IPTABLES -N fw61-Policy_1 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --days Sun -j fw61-Policy_1 $IPTABLES -t mangle -A fw61-Policy_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -t mangle -A fw61-Policy_1 -j DROP # # Rule fw61-Policy 2 (global) # echo "Rule fw61-Policy 2 (global)" # $IPTABLES -N fw61-Policy_2 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 18:00 --timestop 23:59 -j fw61-Policy_2 $IPTABLES -t mangle -A fw61-Policy_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -t mangle -A fw61-Policy_2 -j DROP # # Rule fw61-Policy 3 (global) # echo "Rule fw61-Policy 3 (global)" # $IPTABLES -N fw61-Policy_3 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j fw61-Policy_3 $IPTABLES -t mangle -A fw61-Policy_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -t mangle -A fw61-Policy_3 -j DROP # # Rule fw61-Policy 4 (global) # echo "Rule fw61-Policy 4 (global)" # $IPTABLES -N fw61-Policy_4 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j fw61-Policy_4 $IPTABLES -t mangle -A fw61-Policy_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -t mangle -A fw61-Policy_4 -j DROP # # Rule fw61-Policy 5 (global) # echo "Rule fw61-Policy 5 (global)" # $IPTABLES -N fw61-Policy_5 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_5 $IPTABLES -t mangle -A fw61-Policy_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -t mangle -A fw61-Policy_5 -j DROP # # Rule fw61-Policy 6 (global) # echo "Rule fw61-Policy 6 (global)" # $IPTABLES -N fw61-Policy_6 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_6 $IPTABLES -t mangle -A fw61-Policy_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -t mangle -A fw61-Policy_6 -j DROP # # Rule fw61-Policy 7 (global) # echo "Rule fw61-Policy 7 (global)" # $IPTABLES -N fw61-Policy_7 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 01:00 --days Fri,Sat -j fw61-Policy_7 $IPTABLES -t mangle -A fw61-Policy_7 -j LOG --log-level info --log-prefix "RULE 7 -- DENY " $IPTABLES -t mangle -A fw61-Policy_7 -j DROP # # Rule fw61-Policy 8 (global) # echo "Rule fw61-Policy 8 (global)" # $IPTABLES -N fw61-Policy_8 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:00 --timestop 02:00 --days Fri,Sat -j fw61-Policy_8 $IPTABLES -t mangle -A fw61-Policy_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -t mangle -A fw61-Policy_8 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- BRANCH " $IPTABLES -N fw61-Policy $IPTABLES -A RULE_0 -j fw61-Policy # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules # target TCPMSS is not supported by ip6tables before v1.3.8 # ================ Table 'filter', rule set Policy_ipv6 # # Rule Policy_ipv6 0 (global) # echo "Rule Policy_ipv6 0 (global)" # $IP6TABLES -N Policy_ipv6_0 $IP6TABLES -A OUTPUT -j Policy_ipv6_0 $IP6TABLES -A INPUT -j Policy_ipv6_0 $IP6TABLES -A FORWARD -j Policy_ipv6_0 $IP6TABLES -A Policy_ipv6_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IP6TABLES -A Policy_ipv6_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:01 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall82_A.fw.orig0000755000175000017500000002463011733011756022275 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:13 2012 PDT by vadim # # files: * firewall82_A.fw /etc/fw/firewall82_A.fw # # Compiled for iptables (any version) # # this object is used to hold branch rulesets for firewall82 # firewall82_A:Policy_A:1: warning: Rule branches to rule set Policy_A which branches back to it, creating a loop # firewall82_A:Policy_A:1: warning: Rule branches to rule set Policy which branches back to it, creating a loop # firewall82_A:Policy_A:2: warning: Rule branches to rule set Policy_A which branches back to it, creating a loop FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_B # # Rule Policy_B 0 (global) # echo "Rule Policy_B 0 (global)" # $IPTABLES -N Policy_B $IPTABLES -A Policy_B -d 192.0.2.100 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N Policy $IPTABLES -N Policy_A $IPTABLES -A Policy -j Policy_A # ================ Table 'filter', rule set Policy_A # # Rule Policy_A 0 (global) # echo "Rule Policy_A 0 (global)" # $IPTABLES -A OUTPUT -j Policy_B $IPTABLES -A INPUT -j Policy_B $IPTABLES -A FORWARD -j Policy_B # # Rule Policy_A 1 (global) # echo "Rule Policy_A 1 (global)" # # recursive branching $IPTABLES -A OUTPUT -j Policy $IPTABLES -A INPUT -j Policy $IPTABLES -A FORWARD -j Policy # # Rule Policy_A 2 (global) # echo "Rule Policy_A 2 (global)" # $IPTABLES -A OUTPUT -j Policy_A $IPTABLES -A INPUT -j Policy_A $IPTABLES -A FORWARD -j Policy_A } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:13 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/vrrp_cluster_2_linux-2.fw.orig0000755000175000017500000003772111733011756024414 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * vrrp_cluster_2_linux-2.fw /etc/vrrp_cluster_2_linux-2.fw # # Compiled for iptables 1.4.0 # FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.3/16" "172.24.0.1/24" update_addresses_of_interface "eth1 192.168.1.3/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 20/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 20/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -8 VRRP (automatic) # echo "Rule -8 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -7 VRRP (automatic) # echo "Rule -7 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.4 -d 224.0.0.18 -j ACCEPT # # Rule -6 VRRP (automatic) # echo "Rule -6 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.2 -d 224.0.0.18 -j ACCEPT # # Rule -5 VRRP (automatic) # echo "Rule -5 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -4 VRRP (automatic) # echo "Rule -4 VRRP (automatic)" # $IPTABLES -A INPUT -i eth0 -p vrrp -s 172.24.0.4 -d 224.0.0.18 -j ACCEPT # # Rule -3 VRRP (automatic) # echo "Rule -3 VRRP (automatic)" # $IPTABLES -N Cid3009X69605.2.0 $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -j Cid3009X69605.2.0 $IPTABLES -A Cid3009X69605.2.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.2.0 -s 192.168.100.1 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid5188X25627.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid5188X25627.0 $IPTABLES -A Cid5188X25627.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid5188X25627.0 -d 192.168.1.4 -j ACCEPT $IPTABLES -N Cid5188X25627.1 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid5188X25627.1 $IPTABLES -A Cid5188X25627.1 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid5188X25627.1 -d 192.168.1.4 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.3 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.3 -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_8 $IPTABLES -A INPUT -m state --state NEW -j RULE_8 $IPTABLES -A FORWARD -m state --state NEW -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -j RULE_9 $IPTABLES -A INPUT -j RULE_9 $IPTABLES -A FORWARD -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-nd-ns-1.fw.orig0000755000175000017500000003153311733011756023720 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:30 2012 PDT by vadim # # files: * firewall-ipv6-nd-ns-1.fw /etc/firewall-ipv6-nd-ns-1.fw # # Compiled for iptables 1.4.0 # # automatic ND/NS rules FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 192.0.2.1/24" "" } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # rules to permit IPv6 Neighbor discovery echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:30 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall82_B.fw.orig0000755000175000017500000002241711733011756022277 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:13 2012 PDT by vadim # # files: * firewall82_B.fw /etc/fw/firewall82_B.fw # # Compiled for iptables (any version) # # this object is used to hold branch rulesets for firewall82 and firewall82_A FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_B # # Rule Policy_B 0 (global) # echo "Rule Policy_B 0 (global)" # $IPTABLES -A OUTPUT -d 192.0.2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.0.2.100 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:13 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall28.fw.orig0000755000175000017500000002563611733011756022044 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:34 2012 PDT by vadim # # files: * firewall28.fw /etc/fw/firewall28.fw # # Compiled for iptables (any version) # # firewall28:Policy:0: error: Rule '0 (global)' shadows rule '1 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.0/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.22 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # this rule should shadow rule #1 because # it uses IPService object with protocol 0 # firewall28:Policy:0: error: Rule '0 (global)' shadows rule '1 (global)' below it $IPTABLES -A OUTPUT -p all -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p all -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p all -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 6667 -j RULE_1 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 6667 -j RULE_1 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 6667 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -j RULE_3 $IPTABLES -A INPUT -j RULE_3 $IPTABLES -A FORWARD -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -A RULE_3 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:34 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-7.fw.orig0000755000175000017500000003172011733011756022707 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:26 2012 PDT by vadim # # files: * firewall-ipv6-7.fw /etc/firewall-ipv6-7.fw # # Compiled for iptables 1.4.0 # # one interface has dynamic address, testing functions that get the address at run time FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # rules to permit IPv6 Neighbor discovery echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:26 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/server-cluster-1_server-1.fw.orig0000755000175000017500000002510011733011756024716 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * server-cluster-1_server-1.fw /etc/fw/server-cluster-1_server-1.fw # # Compiled for iptables (any version) # # fw is part of any is OFF # ip forwarding is OFF # server-cluster-1:Policy:0: error: Rule '0 (global)' shadows rule '1 (global)' below it # server-cluster-1:Policy:0: error: Rule '0 (global)' shadows rule '1 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: lo eth0" for i in lo eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0 192.168.1.1/24" "192.168.1.100/24" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o lo -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i lo -p udp -m udp -s 127.0.0.1 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -2 heartbeat (automatic) # echo "Rule -2 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -1 heartbeat (automatic) # echo "Rule -1 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 192.168.1.2 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule 0 (global) # echo "Rule 0 (global)" # # test for ticket #1338 # server-cluster-1:Policy:0: error: Rule '0 (global)' shadows rule '1 (global)' below it $IPTABLES -A INPUT -s 192.168.1.1 -j DROP $IPTABLES -A INPUT -s 192.168.1.100 -j DROP } ip_forward() { : echo 0 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/do-all-diff0000755000175000017500000000055611733011756020563 0ustar sylvestresylvestre#!/usr/bin/perl $XMLFILE=@ARGV[0]; if (-x "/usr/bin/opendiff") { $TOOL="opendiff"; } else { $TOOL="tkdiff -b -B "; } while (<>) { $str=$_; while ( $str=~ /]+name="([^"]*).*$"/; $fw=$1; printf "$TOOL %s.fw.orig %s.fw\n",$fw,$fw; $str=~ s/^.*]+name="$fw"[^>]+>//; } } fwbuilder-5.1.0.3599/test/ipt/host.fw.orig0000755000175000017500000002623111733011756021032 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:36 2012 PDT by vadim # # files: * host.fw /etc/fw/host.fw # # Compiled for iptables (any version) # # firewall protects host it is running on FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level debug $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (lo) # echo "Rule 1 (lo)" # # allow everything on loopback $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT # # Rule 2 (lo) # echo "Rule 2 (lo)" # # allow everything on loopback $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (lo) # echo "Rule 3 (lo)" # $IPTABLES -N Cid3BD8ECC6.0 $IPTABLES -A INPUT -i lo -s 22.22.22.22 -m state --state NEW -j Cid3BD8ECC6.0 $IPTABLES -A INPUT -i lo -s 127.0.0.1 -m state --state NEW -j Cid3BD8ECC6.0 $IPTABLES -N In_RULE_3 $IPTABLES -A Cid3BD8ECC6.0 -d 22.22.22.22 -j In_RULE_3 $IPTABLES -A Cid3BD8ECC6.0 -d 127.0.0.1 -j In_RULE_3 $IPTABLES -A In_RULE_3 -j LOG --log-level debug $IPTABLES -A In_RULE_3 -j ACCEPT $IPTABLES -N Cid3BD8ECC6.1 $IPTABLES -A OUTPUT -o lo -s 22.22.22.22 -m state --state NEW -j Cid3BD8ECC6.1 $IPTABLES -A OUTPUT -o lo -s 127.0.0.1 -m state --state NEW -j Cid3BD8ECC6.1 $IPTABLES -N Out_RULE_3 $IPTABLES -A Cid3BD8ECC6.1 -d 22.22.22.22 -j Out_RULE_3 $IPTABLES -A Cid3BD8ECC6.1 -d 127.0.0.1 -j Out_RULE_3 $IPTABLES -A Out_RULE_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_3 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -s 22.22.22.22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # # 'catch all' rule $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -m limit --limit 10/minute --limit-burst 50 -j RULE_8 $IPTABLES -A INPUT -m limit --limit 10/minute --limit-burst 50 -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level debug --log-prefix "CATCH ALL RULE" $IPTABLES -A RULE_8 -j DROP } ip_forward() { : echo 0 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:36 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall34.fw.orig0000755000175000017500000005215611733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:41 2012 PDT by vadim # # files: * firewall34.fw /etc/fw/firewall34.fw # # Compiled for iptables (any version) # # testing AddressTable object # firewall34:Policy:12: warning: Empty group or address table object 'empty table' # firewall34:Policy:12: warning: After removal of all empty groups and address table objects rule element Dst becomes 'any' in the rule 12 (global) # Dropping rule 12 (global) because option 'Ignore rules with empty groups' is in effect FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "addr-table-1:a" "addr-table-1.tbl" check_file "block_these" "block-hosts.tbl" } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" getaddr eth0.100 i_eth0_100 getaddr6 eth0.100 i_eth0_100_v6 getnet eth0.100 i_eth0_100_network getnet6 eth0.100 i_eth0_100_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -N Cid4389EEB018346.0 for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $i_eth0_100 --dport 25 -j Cid4389EEB018346.0 done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -t nat -A Cid4389EEB018346.0 -s $at_block_these -j RETURN done $IPTABLES -t nat -A Cid4389EEB018346.0 -p tcp -m tcp --dport 25 -j DNAT --to-destination 192.168.1.10 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -N Cid43891B6E674.0 $IPTABLES -t nat -A POSTROUTING -o eth0.100 -s 192.168.1.0/24 -j Cid43891B6E674.0 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -t nat -A Cid43891B6E674.0 -d $at_block_these -j RETURN done $IPTABLES -t nat -A Cid43891B6E674.0 -j MASQUERADE # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.3/30 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.200 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.201 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.2.128/25 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.3/30 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.200 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.1.201 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 192.168.2.128/25 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.3/30 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.200 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.201 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.2.128/25 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -d $at_block_these -j RULE_1 done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A FORWARD -d $at_block_these -j RULE_1 done $IPTABLES -A RULE_1 -j LOG --log-level debug --log-prefix "RULE 1 -- DENY on global " $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -d $at_block_these -j RULE_2 done $IPTABLES -A OUTPUT -d 61.150.47.112 -j RULE_2 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A FORWARD -d $at_block_these -j RULE_2 done $IPTABLES -A FORWARD -d 61.150.47.112 -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level debug --log-prefix "RULE 2 -- DENY on global " $IPTABLES -A RULE_2 -j DROP # # Rule 3 (global) # echo "Rule 3 (global)" # grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -p tcp -m tcp -d $at_block_these --dport 25 -j DROP done $IPTABLES -A OUTPUT -p tcp -m tcp -d 61.150.47.112 --dport 25 -j DROP grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A FORWARD -p tcp -m tcp -d $at_block_these --dport 25 -j DROP done $IPTABLES -A FORWARD -p tcp -m tcp -d 61.150.47.112 --dport 25 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && { grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0_100 -d $at_block_these --dport 25 -j DROP done } done for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0_100 -d 61.150.47.112 --dport 25 -j DROP done # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N RULE_5 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A INPUT -s $at_block_these -j RULE_5 done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A FORWARD -s $at_block_these -j RULE_5 done $IPTABLES -A RULE_5 -j LOG --log-level debug --log-prefix "RULE 5 -- DENY on global " $IPTABLES -A RULE_5 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N RULE_6 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A INPUT -s $at_block_these -j RULE_6 done $IPTABLES -A INPUT -s 61.150.47.112 -j RULE_6 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A FORWARD -s $at_block_these -j RULE_6 done $IPTABLES -A FORWARD -s 61.150.47.112 -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level debug --log-prefix "RULE 6 -- DENY on global " $IPTABLES -A RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid4388F5A9674.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid4388F5A9674.0 $IPTABLES -A INPUT -m state --state NEW -j Cid4388F5A9674.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid4388F5A9674.0 grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A Cid4388F5A9674.0 -s $at_block_these -j RETURN done $IPTABLES -A Cid4388F5A9674.0 -s 61.150.47.112 -j RETURN $IPTABLES -A Cid4388F5A9674.0 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N Cid4392312525682.0 for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A INPUT -s $i_eth0_100 -m state --state NEW -j Cid4392312525682.0 done for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A OUTPUT -s $i_eth0_100 -m state --state NEW -j Cid4392312525682.0 done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A Cid4392312525682.0 -d $at_block_these -j RETURN done $IPTABLES -A Cid4392312525682.0 -d 61.150.47.112 -j RETURN $IPTABLES -A Cid4392312525682.0 -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 25 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 25 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N RULE_11 $IPTABLES -A OUTPUT -j RULE_11 $IPTABLES -A INPUT -j RULE_11 $IPTABLES -A FORWARD -j RULE_11 $IPTABLES -A RULE_11 -j LOG --log-level debug --log-prefix "RULE 11 -- DENY on global " $IPTABLES -A RULE_11 -j DROP # # Rule 13 (global) # echo "Rule 13 (global)" # # using address table # object with no addresses $IPTABLES -N RULE_13 $IPTABLES -A OUTPUT -d 22.22.22.0/24 -j RULE_13 $IPTABLES -A FORWARD -d 22.22.22.0/24 -j RULE_13 $IPTABLES -A RULE_13 -j LOG --log-level debug --log-prefix "RULE 13 -- DENY on global " $IPTABLES -A RULE_13 -j DROP # # Rule 14 (global) # echo "Rule 14 (global)" # # using connlimit # option. Connlimit # is only valid in combination # with "-p tcp -m tcp" $IPTABLES -N Cid45948F957794.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 25 -m state --state NEW -m connlimit --connlimit-above 2 -j Cid45948F957794.0 $IPTABLES -A Cid45948F957794.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid45948F957794.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid45948F957794.0 -d 192.168.1.3/30 -j ACCEPT $IPTABLES -A Cid45948F957794.0 -d 192.168.1.200 -j ACCEPT $IPTABLES -A Cid45948F957794.0 -d 192.168.1.201 -j ACCEPT $IPTABLES -A Cid45948F957794.0 -d 192.168.2.128/25 -j ACCEPT $IPTABLES -N Cid45948F957794.1 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 25 -m state --state NEW -m connlimit --connlimit-above 2 -j Cid45948F957794.1 $IPTABLES -A Cid45948F957794.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid45948F957794.1 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid45948F957794.1 -d 192.168.1.3/30 -j ACCEPT $IPTABLES -A Cid45948F957794.1 -d 192.168.1.200 -j ACCEPT $IPTABLES -A Cid45948F957794.1 -d 192.168.1.201 -j ACCEPT $IPTABLES -A Cid45948F957794.1 -d 192.168.2.128/25 -j ACCEPT $IPTABLES -N Cid45948F957794.2 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 25 -m state --state NEW -m connlimit --connlimit-above 2 -j Cid45948F957794.2 $IPTABLES -A Cid45948F957794.2 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid45948F957794.2 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid45948F957794.2 -d 192.168.1.3/30 -j ACCEPT $IPTABLES -A Cid45948F957794.2 -d 192.168.1.200 -j ACCEPT $IPTABLES -A Cid45948F957794.2 -d 192.168.1.201 -j ACCEPT $IPTABLES -A Cid45948F957794.2 -d 192.168.2.128/25 -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_addr_table_1_a=$1; $IPTABLES -A OUTPUT -d $at_addr_table_1_a -m state --state NEW -j ACCEPT done grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_addr_table_1_a=$1; $IPTABLES -A FORWARD -d $at_addr_table_1_a -m state --state NEW -j ACCEPT done # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_ipv6 # # Rule Policy_ipv6 0 (global) # echo "Rule Policy_ipv6 0 (global)" # $IP6TABLES -A OUTPUT -d 2001:458:20:100:250:b7ff:fe00:2af -m state --state NEW -j ACCEPT $IP6TABLES -A OUTPUT -d fe80::21d:9ff:fe8b:8e94/64 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d 2001:458:20:100:250:b7ff:fe00:2af -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d fe80::21d:9ff:fe8b:8e94/64 -m state --state NEW -j ACCEPT # # Rule Policy_ipv6 1 (global) # echo "Rule Policy_ipv6 1 (global)" # $IP6TABLES -N Policy_ipv6_1 $IP6TABLES -A OUTPUT -j Policy_ipv6_1 $IP6TABLES -A INPUT -j Policy_ipv6_1 $IP6TABLES -A FORWARD -j Policy_ipv6_1 $IP6TABLES -A Policy_ipv6_1 -j LOG --log-level debug --log-prefix "RULE 1 -- DENY on global " $IP6TABLES -A Policy_ipv6_1 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall9.fw.orig0000755000175000017500000005746511733011756021770 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:15 2012 PDT by vadim # # files: * firewall9.fw /etc/fw/firewall9.fw # # Compiled for iptables (any version) # # testing rules with action-on-reject "TCP reset" # firewall9:Policy:1: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall9:Policy:2: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall9:Policy:6: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall9:Policy:7: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N Cid3D4DF362.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 6667 -j Cid3D4DF362.0 $IPTABLES -N RULE_0 $IPTABLES -A Cid3D4DF362.0 -d 22.22.22.22 -j RULE_0 $IPTABLES -A Cid3D4DF362.0 -d 192.168.1.1 -j RULE_0 $IPTABLES -A INPUT -p tcp -m tcp --dport 6667 -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level debug --log-prefix "RULE 0 -- REJECT global" $IPTABLES -A RULE_0 -p tcp -m tcp -j REJECT --reject-with tcp-reset # # Rule 1 (global) # echo "Rule 1 (global)" # # firewall9:Policy:1: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N Cid3D4DF36C.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 53 -j Cid3D4DF36C.0 $IPTABLES -N RULE_1 $IPTABLES -A Cid3D4DF36C.0 -d 22.22.22.22 -j RULE_1 $IPTABLES -A Cid3D4DF36C.0 -d 192.168.1.1 -j RULE_1 $IPTABLES -A INPUT -p udp -m udp --dport 53 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level debug --log-prefix "RULE 1 -- REJECT global" $IPTABLES -A RULE_1 -j REJECT --reject-with icmp-net-unreachable # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall9:Policy:2: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N Cid3D4DF376.0 $IPTABLES -A OUTPUT -p icmp -j Cid3D4DF376.0 $IPTABLES -A OUTPUT -p 50 -j Cid3D4DF376.0 $IPTABLES -N RULE_2 $IPTABLES -A Cid3D4DF376.0 -d 22.22.22.22 -j RULE_2 $IPTABLES -A Cid3D4DF376.0 -d 192.168.1.1 -j RULE_2 $IPTABLES -A INPUT -p icmp -j RULE_2 $IPTABLES -A INPUT -p 50 -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level debug --log-prefix "RULE 2 -- REJECT global" $IPTABLES -A RULE_2 -j REJECT --reject-with icmp-net-unreachable # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N Cid3D4DF380.0 $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -j Cid3D4DF380.0 $IPTABLES -N RULE_3_1 $IPTABLES -A Cid3D4DF380.0 -d 22.22.22.22 -j RULE_3_1 $IPTABLES -A Cid3D4DF380.0 -d 192.168.1.1 -j RULE_3_1 $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -j RULE_3_1 $IPTABLES -A RULE_3_1 -j LOG --log-level debug --log-prefix "RULE 3 -- REJECT global" $IPTABLES -A RULE_3_1 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid3D4DF380.1 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -j Cid3D4DF380.1 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j Cid3D4DF380.1 $IPTABLES -N RULE_3_2 $IPTABLES -A Cid3D4DF380.1 -d 22.22.22.22 -j RULE_3_2 $IPTABLES -A Cid3D4DF380.1 -d 192.168.1.1 -j RULE_3_2 $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -j RULE_3_2 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j RULE_3_2 $IPTABLES -A RULE_3_2 -j LOG --log-level debug --log-prefix "RULE 3 -- REJECT global" $IPTABLES -A RULE_3_2 -p tcp -m tcp -j REJECT --reject-with tcp-reset # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid3D4DF38A.0 $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -j Cid3D4DF38A.0 $IPTABLES -A Cid3D4DF38A.0 -d 22.22.22.22 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid3D4DF38A.0 -d 192.168.1.1 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid3D4DF38A.1 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -j Cid3D4DF38A.1 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j Cid3D4DF38A.1 $IPTABLES -A Cid3D4DF38A.1 -p tcp -m tcp -d 22.22.22.22 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid3D4DF38A.1 -p tcp -m tcp -d 192.168.1.1 -j REJECT --reject-with tcp-reset $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -j REJECT --reject-with tcp-reset $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j REJECT --reject-with tcp-reset # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid3D4DF394.0 $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -j Cid3D4DF394.0 $IPTABLES -A Cid3D4DF394.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3D4DF394.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3D4DF394.0 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A FORWARD -p udp -m udp -m multiport --dports 53,161 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid3D4DF394.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -j Cid3D4DF394.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j Cid3D4DF394.1 $IPTABLES -A Cid3D4DF394.1 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3D4DF394.1 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3D4DF394.1 -p tcp -m tcp -j REJECT --reject-with tcp-reset $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -j REJECT --reject-with tcp-reset $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j REJECT --reject-with tcp-reset $IPTABLES -A FORWARD -p tcp -m tcp --dport 10000:11000 -j REJECT --reject-with tcp-reset $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j REJECT --reject-with tcp-reset # # Rule 6 (global) # echo "Rule 6 (global)" # # firewall9:Policy:6: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N Cid3D4DF39E.0 $IPTABLES -A OUTPUT -d 22.22.22.22 -j Cid3D4DF39E.0 $IPTABLES -A OUTPUT -d 192.168.1.1 -j Cid3D4DF39E.0 $IPTABLES -A INPUT -j Cid3D4DF39E.0 $IPTABLES -A Cid3D4DF39E.0 -p tcp -m tcp --dport 10000:11000 -j RETURN $IPTABLES -A Cid3D4DF39E.0 -p tcp -m tcp --dport 113 -j RETURN $IPTABLES -A Cid3D4DF39E.0 -p udp -m udp -m multiport --dports 53,161 -j RETURN $IPTABLES -A Cid3D4DF39E.0 -j REJECT --reject-with icmp-net-unreachable # # Rule 7 (global) # echo "Rule 7 (global)" # # firewall9:Policy:7: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N Cid3D4DF3A8.0 $IPTABLES -A OUTPUT -d 22.22.22.22 -j Cid3D4DF3A8.0 $IPTABLES -A OUTPUT -d 192.168.1.1 -j Cid3D4DF3A8.0 $IPTABLES -A INPUT -j Cid3D4DF3A8.0 $IPTABLES -A Cid3D4DF3A8.0 -p tcp -m tcp --dport 10000:11000 -j RETURN $IPTABLES -A Cid3D4DF3A8.0 -p tcp -m tcp --dport 113 -j RETURN $IPTABLES -A Cid3D4DF3A8.0 -p udp -m udp -m multiport --dports 53,161 -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid3D4DF3A8.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -j LOG --log-level debug --log-prefix "RULE 7 -- REJECT global" $IPTABLES -A RULE_7_3 -j REJECT --reject-with icmp-net-unreachable # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j REJECT --reject-with tcp-reset # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid4144FFAE.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -j Cid4144FFAE.0 $IPTABLES -A Cid4144FFAE.0 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid4144FFAE.0 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -N Cid4144FFAE.1 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j Cid4144FFAE.1 $IPTABLES -A Cid4144FFAE.1 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid4144FFAE.1 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -N Cid4144FFAE.2 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -j Cid4144FFAE.2 $IPTABLES -A Cid4144FFAE.2 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid4144FFAE.2 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N Cid41456B50.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid41456B50.0 $IPTABLES -A Cid41456B50.0 -s 192.168.1.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid41456B50.0 -s 192.168.2.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid41456B50.1 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid41456B50.1 $IPTABLES -A Cid41456B50.1 -s 192.168.1.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid41456B50.1 -s 192.168.2.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid41456B50.2 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid41456B50.2 $IPTABLES -A Cid41456B50.2 -s 192.168.1.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid41456B50.2 -s 192.168.2.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid41456B50.3 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -j Cid41456B50.3 $IPTABLES -A Cid41456B50.3 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid41456B50.3 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -N Cid41456B50.4 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j Cid41456B50.4 $IPTABLES -A Cid41456B50.4 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid41456B50.4 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -N Cid41456B50.5 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -j Cid41456B50.5 $IPTABLES -A Cid41456B50.5 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid41456B50.5 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N Cid41456B75.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid41456B75.0 $IPTABLES -A Cid41456B75.0 -s 192.168.1.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid41456B75.0 -s 192.168.2.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid41456B75.1 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid41456B75.1 $IPTABLES -A Cid41456B75.1 -s 192.168.1.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid41456B75.1 -s 192.168.2.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid41456B75.2 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid41456B75.2 $IPTABLES -A Cid41456B75.2 -s 192.168.1.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A Cid41456B75.2 -s 192.168.2.0/24 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid41456B75.3 $IPTABLES -A INPUT -p tcp -m tcp --dport 21 -j Cid41456B75.3 $IPTABLES -A Cid41456B75.3 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid41456B75.3 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -N Cid41456B75.4 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 21 -j Cid41456B75.4 $IPTABLES -A Cid41456B75.4 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid41456B75.4 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -N Cid41456B75.5 $IPTABLES -A FORWARD -p tcp -m tcp --dport 21 -j Cid41456B75.5 $IPTABLES -A Cid41456B75.5 -p tcp -m tcp -s 192.168.1.0/24 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid41456B75.5 -p tcp -m tcp -s 192.168.2.0/24 -j REJECT --reject-with tcp-reset # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N Cid206275X37109.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -j Cid206275X37109.0 $IPTABLES -A Cid206275X37109.0 -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid206275X37109.0 -p tcp -m tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset $IPTABLES -N Cid206275X37109.1 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j Cid206275X37109.1 $IPTABLES -A Cid206275X37109.1 -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid206275X37109.1 -p tcp -m tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset $IPTABLES -N Cid206275X37109.2 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j Cid206275X37109.2 $IPTABLES -A Cid206275X37109.2 -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid206275X37109.2 -p tcp -m tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A INPUT -p udp -m udp -s 192.168.1.0/24 --dport 53 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A OUTPUT -p udp -m udp -s 192.168.1.0/24 --dport 53 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -A FORWARD -p udp -m udp -s 192.168.1.0/24 --dport 53 -j REJECT --reject-with icmp-net-unreachable $IPTABLES -N Cid206293X37109.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -j Cid206293X37109.0 $IPTABLES -A Cid206293X37109.0 -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid206293X37109.0 -p tcp -m tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset $IPTABLES -N Cid206293X37109.1 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j Cid206293X37109.1 $IPTABLES -A Cid206293X37109.1 -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid206293X37109.1 -p tcp -m tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset $IPTABLES -N Cid206293X37109.2 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j Cid206293X37109.2 $IPTABLES -A Cid206293X37109.2 -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset $IPTABLES -A Cid206293X37109.2 -p tcp -m tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:15 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall18.fw.orig0000755000175000017500000003544411733011756022041 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:14 2012 PDT by vadim # # files: * firewall18.fw /etc/fw/firewall18.fw # # Compiled for iptables (any version) # # this firewall translates outgoing connections using address of the particular interface (not external one). Also testing different cmbinations of objects in the policy rules on loopback interface. Finally, testing for a situation when dynamic interface "shades" a rule with old broadcast FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth2 eth0 eth1 lo ppp0" for i in eth2 eth0 eth1 lo ppp0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth2 66.66.66.1/25" "" update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 66.66.66.130/25" "" update_addresses_of_interface "lo 127.0.0.1/8" "" getaddr ppp0 i_ppp0 getaddr6 ppp0 i_ppp0_v6 getnet ppp0 i_ppp0_network getnet6 ppp0 i_ppp0_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -t nat -A POSTROUTING -o eth1 -s $i_ppp0 -j SNAT --to-source 66.66.66.130 done $IPTABLES -t nat -A POSTROUTING -o eth1 -s 66.66.66.1 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 66.66.66.130 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.1 -j SNAT --to-source 66.66.66.130 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -t nat -A POSTROUTING -o eth1 -s $i_ppp0 -j SNAT --to-source 66.66.66.130 done $IPTABLES -t nat -A POSTROUTING -o eth1 -s 66.66.66.1 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 66.66.66.130 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.1 -j SNAT --to-source 66.66.66.130 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 66.66.66.130 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 66.66.66.130 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -t nat -A POSTROUTING -o eth+ -s $i_ppp0 -j SNAT --to-source 66.66.66.130 done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -t nat -A POSTROUTING -o ppp+ -s $i_ppp0 -j SNAT --to-source 66.66.66.130 done $IPTABLES -t nat -A POSTROUTING -o eth+ -s 66.66.66.1 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 66.66.66.1 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 66.66.66.130 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 66.66.66.130 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.1 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.1 -j SNAT --to-source 66.66.66.130 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j SNAT --to-source 66.66.66.130 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 66.66.66.1 -j SNAT --to-source 66.66.66.130 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 66.66.66.1 -j SNAT --to-source 66.66.66.130 # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # using address range object # 255.255.255.255-255.255.255.255 $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth0 -d 255.255.255.255 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A In_RULE_0 -j DROP $IPTABLES -N Out_RULE_0 $IPTABLES -A OUTPUT -o eth0 -d 255.255.255.255 -j Out_RULE_0 $IPTABLES -A Out_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A Out_RULE_0 -j DROP # # Rule 1 (lo) # echo "Rule 1 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 2 (ppp0) # echo "Rule 2 (ppp0)" # # anti-spoofing rule $IPTABLES -N In_RULE_2 for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A INPUT -i ppp0 -s $i_ppp0 -j In_RULE_2 done $IPTABLES -A INPUT -i ppp0 -s 66.66.66.1 -j In_RULE_2 $IPTABLES -A INPUT -i ppp0 -s 66.66.66.130 -j In_RULE_2 $IPTABLES -A INPUT -i ppp0 -s 192.168.1.1 -j In_RULE_2 for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A FORWARD -i ppp0 -s $i_ppp0 -j In_RULE_2 done $IPTABLES -A FORWARD -i ppp0 -s 66.66.66.1 -j In_RULE_2 $IPTABLES -A FORWARD -i ppp0 -s 66.66.66.130 -j In_RULE_2 $IPTABLES -A FORWARD -i ppp0 -s 192.168.1.1 -j In_RULE_2 $IPTABLES -A In_RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (ppp0) # echo "Rule 3 (ppp0)" # # but old broadcast is permitted $IPTABLES -A INPUT -i ppp0 -s 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N RULE_4 $IPTABLES -A OUTPUT -j RULE_4 $IPTABLES -A INPUT -j RULE_4 $IPTABLES -A FORWARD -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -A RULE_4 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:14 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-prolog-after-flush.fw.orig0000755000175000017500000002760011733011756026263 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:32 2012 PDT by vadim # # files: * firewall-ipv6-prolog-after-flush.fw /etc/firewall-ipv6-prolog-after-flush.fw # # Compiled for iptables (any version) # # Policy is configured as dual address family. Prolog is after iptables reset and flush FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" echo "This is prolog" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i + -m state --state NEW -j ACCEPT # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IP6TABLES -N drop_invalid $IP6TABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A INPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A FORWARD -m state --state INVALID -j drop_invalid $IP6TABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IP6TABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IP6TABLES -A INPUT -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -i + -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:32 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall61-1.2.6.fw.orig0000755000175000017500000003557411733011756022505 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:01 2012 PDT by vadim # # files: * firewall61-1.2.6.fw /etc/firewall61-1.2.6.fw # # Compiled for iptables ge_1.2.6 # # testing time litmiting for iptables 1.2.6 # firewall61-1.2.6:Policy_ipv6:: warning: target TCPMSS is not supported by ip6tables before v1.3.8 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', rule set fw61-Policy # # Rule fw61-Policy 0 (global) # echo "Rule fw61-Policy 0 (global)" # $IPTABLES -N fw61-Policy -t mangle $IPTABLES -N fw61-Policy_0 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --days Sat -j fw61-Policy_0 $IPTABLES -t mangle -A fw61-Policy_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -t mangle -A fw61-Policy_0 -j DROP # # Rule fw61-Policy 1 (global) # echo "Rule fw61-Policy 1 (global)" # $IPTABLES -N fw61-Policy_1 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --days Sun -j fw61-Policy_1 $IPTABLES -t mangle -A fw61-Policy_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -t mangle -A fw61-Policy_1 -j DROP # # Rule fw61-Policy 2 (global) # echo "Rule fw61-Policy 2 (global)" # $IPTABLES -N fw61-Policy_2 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 18:00 --timestop 23:59 -j fw61-Policy_2 $IPTABLES -t mangle -A fw61-Policy_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -t mangle -A fw61-Policy_2 -j DROP # # Rule fw61-Policy 3 (global) # echo "Rule fw61-Policy 3 (global)" # $IPTABLES -N fw61-Policy_3 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j fw61-Policy_3 $IPTABLES -t mangle -A fw61-Policy_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -t mangle -A fw61-Policy_3 -j DROP # # Rule fw61-Policy 4 (global) # echo "Rule fw61-Policy 4 (global)" # $IPTABLES -N fw61-Policy_4 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j fw61-Policy_4 $IPTABLES -t mangle -A fw61-Policy_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -t mangle -A fw61-Policy_4 -j DROP # # Rule fw61-Policy 5 (global) # echo "Rule fw61-Policy 5 (global)" # $IPTABLES -N fw61-Policy_5 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_5 $IPTABLES -t mangle -A fw61-Policy_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -t mangle -A fw61-Policy_5 -j DROP # # Rule fw61-Policy 6 (global) # echo "Rule fw61-Policy 6 (global)" # $IPTABLES -N fw61-Policy_6 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_6 $IPTABLES -t mangle -A fw61-Policy_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -t mangle -A fw61-Policy_6 -j DROP # # Rule fw61-Policy 7 (global) # echo "Rule fw61-Policy 7 (global)" # $IPTABLES -N fw61-Policy_7 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 00:00 --timestop 01:00 --days Fri,Sat -j fw61-Policy_7 $IPTABLES -t mangle -A fw61-Policy_7 -j LOG --log-level info --log-prefix "RULE 7 -- DENY " $IPTABLES -t mangle -A fw61-Policy_7 -j DROP # # Rule fw61-Policy 8 (global) # echo "Rule fw61-Policy 8 (global)" # $IPTABLES -N fw61-Policy_8 -t mangle $IPTABLES -t mangle -A fw61-Policy -m time --timestart 01:00 --timestop 02:00 --days Fri,Sat -j fw61-Policy_8 $IPTABLES -t mangle -A fw61-Policy_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -t mangle -A fw61-Policy_8 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- BRANCH " $IPTABLES -N fw61-Policy $IPTABLES -A RULE_0 -j fw61-Policy # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_1 $IPTABLES -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_1 $IPTABLES -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP # ================ IPv6 # ================ Table 'filter', automatic rules # target TCPMSS is not supported by ip6tables before v1.3.8 # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_ipv6 # # Rule Policy_ipv6 0 (global) # echo "Rule Policy_ipv6 0 (global)" # $IP6TABLES -N Policy_ipv6_0 $IP6TABLES -A OUTPUT -j Policy_ipv6_0 $IP6TABLES -A INPUT -j Policy_ipv6_0 $IP6TABLES -A FORWARD -j Policy_ipv6_0 $IP6TABLES -A Policy_ipv6_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IP6TABLES -A Policy_ipv6_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:01 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/heartbeat_cluster_1_linux-2.fw.orig0000755000175000017500000005564711733011756025370 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:41 2012 PDT by vadim # # files: * heartbeat_cluster_1_linux-2.fw /etc/heartbeat_cluster_1_linux-2.fw # # Compiled for iptables 1.4.0 # # linux-2:to_fw:: warning: ignoring cluster rule set "to_fw" because member firewall "linux-2" has rule set with the same name. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.3/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.3/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 20/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 20/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -N Cid3009X69605.2.0 $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j Cid3009X69605.2.0 $IPTABLES -A Cid3009X69605.2.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.2.0 -s 192.168.100.1 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.3 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.3 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 7 (global) # echo "Rule 7 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A FORWARD -d 172.24.0.2 -j to_fw $IPTABLES -A FORWARD -d 192.168.1.2 -j to_fw $IPTABLES -A FORWARD -d 192.168.100.1 -j to_fw # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -d 172.24.0.1 -j DROP $IPTABLES -A OUTPUT -d 172.24.0.3 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.1 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.3 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # # fw is part of any $IPTABLES -N Cid997025X96143.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid997025X96143.0 $IPTABLES -A Cid997025X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 172.24.0.3 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.3 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # fw is NOT part of any $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # fw is NOT part of any $IPTABLES -N Cid143289X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143289X96143.0 $IPTABLES -A Cid143289X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid143289X96143.0 -s 172.24.0.3 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # fw is NOT part of any $IPTABLES -N Cid1946680X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1946680X96143.0 $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.3 -j ACCEPT # # Rule 14 (eth0) # echo "Rule 14 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid378955X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.0 $IPTABLES -A Cid378955X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.0 -s 172.24.0.3 -j ACCEPT $IPTABLES -N Cid378955X96143.1 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.1 $IPTABLES -A Cid378955X96143.1 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.1 -s 172.24.0.3 -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid1801407X96143.0 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1801407X96143.0 $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.3 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # fw is NOT part of any $IPTABLES -A OUTPUT -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid143343X96143.0 $IPTABLES -A FORWARD -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143343X96143.0 $IPTABLES -A Cid143343X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid143343X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # fw is NOT part of any $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241935X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.0 $IPTABLES -A Cid2241935X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241935X96143.1 $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.1 $IPTABLES -A Cid2241935X96143.1 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.1 -s 192.168.100.1 -j ACCEPT # # Rule 18 (eth0) # echo "Rule 18 (eth0)" # # fw is NOT part of any $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241981X96143.0 $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241981X96143.0 $IPTABLES -A Cid2241981X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241981X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using interface of another cluster in the rule $IPTABLES -N Cid8228X45618.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid8228X45618.0 $IPTABLES -A Cid8228X45618.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.100 -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -N Cid147047X84105.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid147047X84105.0 $IPTABLES -A Cid147047X84105.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.100 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N RULE_21 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_21 $IPTABLES -A INPUT -m state --state NEW -j RULE_21 $IPTABLES -A FORWARD -m state --state NEW -j RULE_21 $IPTABLES -A RULE_21 -j LOG --log-level info --log-prefix "RULE 21 -- DENY " $IPTABLES -A RULE_21 -j DROP # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N RULE_22 $IPTABLES -A OUTPUT -j RULE_22 $IPTABLES -A INPUT -j RULE_22 $IPTABLES -A FORWARD -j RULE_22 $IPTABLES -A RULE_22 -j LOG --log-level info --log-prefix "RULE 22 -- DENY " $IPTABLES -A RULE_22 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 172.24.1.0/24 via 172.24.0.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall41-1.fw.orig0000755000175000017500000003705011733011756022166 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:53 2012 PDT by vadim # # files: * firewall41-1.fw /etc/firewall41-1.fw # # Compiled for iptables 1.4.1.1 # # testing run time address table objects with module set # firewall41-1::: warning: Can not add virtual address for object atbl.1 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $IPSET } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_module_ipset() { $IPSET --list > /dev/null 2>&1 || { echo "Detected an error with ipset utility :" $IPSET -V exit 1 } } reload_address_table() { addrtbl_name=$1 data_file=$2 test -z "$addrtbl_name" -o -z "$data_file" && { echo "Usage: reload_address_table address_table_object_name file_name" exit 1 } $IPSET -X tmp_fwb_set:ip -q $IPSET -X tmp_fwb_set:net -q $IPSET -N tmp_fwb_set:ip iphash $IPSET -N tmp_fwb_set:net nethash grep -Ev '^#|^;|^\s*$' $data_file | while read L ; do set $L addr=$1 if echo $addr | grep -q "/" then $IPSET -A tmp_fwb_set:net $addr else $IPSET -A tmp_fwb_set:ip $addr fi done $IPSET --list ${addrtbl_name}:ip >/dev/null || $IPSET -N ${addrtbl_name}:ip iphash $IPSET --list ${addrtbl_name}:net >/dev/null || $IPSET -N ${addrtbl_name}:net nethash $IPSET -W ${addrtbl_name}:ip tmp_fwb_set:ip $IPSET -W ${addrtbl_name}:net tmp_fwb_set:net $IPSET --list ${addrtbl_name} >/dev/null || { $IPSET -N ${addrtbl_name} setlist } $IPSET --list ${addrtbl_name} | grep -q ${addrtbl_name}:ip || { $IPSET -A ${addrtbl_name} ${addrtbl_name}:ip } $IPSET --list ${addrtbl_name} | grep -q ${addrtbl_name}:net || { $IPSET -A ${addrtbl_name} ${addrtbl_name}:net } $IPSET -X tmp_fwb_set:ip $IPSET -X tmp_fwb_set:net } add_to_address_table() { addrtbl_name=$1 data_file=$2 address=$3 test -z "$addrtbl_name" -o -z "$data_file" -o -z "$address" && { echo "Usage: add_to_address_table address_table_object_name file_name address" exit 1 } echo $address >> $data_file if echo $address | grep -q "/" then $IPSET -A ${addrtbl_name}:net $address else $IPSET -A ${addrtbl_name}:ip $address fi } remove_from_address_table() { addrtbl_name=$1 data_file=$2 address=$3 test -z "$addrtbl_name" -o -z "$data_file" -o -z "$address" && { echo "Usage: remove_from_address_table address_table_object_name file_name address" exit 1 } escaped_addr=$(echo $address | sed 's!/!\\/!') sed -i "/^ *$escaped_addr *\$/d" $data_file if echo $address | grep -q "/" then $IPSET -D ${addrtbl_name}:net $address else $IPSET -D ${addrtbl_name}:ip $address fi } test_address_table() { addrtbl_name=$1 address=$2 test -z "$addrtbl_name" -o -z "$address" && { echo "Usage: test_address_table address_table_object_name address" exit 1 } if echo $address | grep -q "/" then $IPSET -T ${addrtbl_name}:net $address else $IPSET -T ${addrtbl_name}:ip $address fi } load_run_time_address_table_files() { : reload_address_table "atbl.1" "addr-table-1.tbl" reload_address_table "block_these" "block-hosts.tbl" } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "atbl.1" "addr-table-1.tbl" check_file "block_these" "block-hosts.tbl" } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 1.1.1.1/24" "" update_addresses_of_interface "eth1 2.2.2.2/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -m set --set atbl.1 src -j SNAT --to-source 1.1.1.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -N Cid2287813X9995.0 $IPTABLES -t nat -A POSTROUTING -o eth0 -j Cid2287813X9995.0 $IPTABLES -t nat -A Cid2287813X9995.0 -m set --set atbl.1 src -j RETURN $IPTABLES -t nat -A Cid2287813X9995.0 -j SNAT --to-source 1.1.1.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -m set --set atbl.1 dst -j DNAT --to-destination 192.168.1.10 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -m set --set atbl.1 dst -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N Cid1162747X27867.0 $IPTABLES -A INPUT -m set ! --set atbl.1 dst -m state --state NEW -j Cid1162747X27867.0 $IPTABLES -A Cid1162747X27867.0 -s 1.1.1.1 -j ACCEPT $IPTABLES -A Cid1162747X27867.0 -s 2.2.2.2 -j ACCEPT $IPTABLES -A OUTPUT -m set ! --set atbl.1 dst -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A OUTPUT -m set ! --set atbl.1 dst -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A OUTPUT -m set --set atbl.1 dst -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m set --set block_these dst -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -A INPUT -m set --set atbl.1 src -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid1162799X27867.0 $IPTABLES -A OUTPUT -m set ! --set atbl.1 src -m state --state NEW -j Cid1162799X27867.0 $IPTABLES -A Cid1162799X27867.0 -d 1.1.1.1 -j ACCEPT $IPTABLES -A Cid1162799X27867.0 -d 2.2.2.2 -j ACCEPT $IPTABLES -A INPUT -m set ! --set atbl.1 src -m state --state NEW -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -A INPUT -m set ! --set atbl.1 src -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -m set --set atbl.1 src -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m set --set block_these src -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -m set --set atbl.1 dst -j DROP $IPTABLES -A FORWARD -m set --set atbl.1 dst -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:53 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files check_module_ipset load_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; reload_address_table) reload_address_table $2 $3 ;; add_to_address_table) add_to_address_table $2 $3 $4 ;; remove_from_address_table) remove_from_address_table $2 $3 $4 ;; test_address_table) test_address_table $2 $3 ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces|reload_address_table|add_to_address_table|remove_from_address_table|test_address_table]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-ipt-reset-prolog-after-flush.fw.orig0000755000175000017500000003105711733011756030176 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:27 2012 PDT by vadim # # files: * firewall-ipv6-ipt-reset-prolog-after-flush.fw /etc/firewall-ipv6-ipt-reset-prolog-after-flush.fw # # Compiled for iptables (any version) # # Policy is configured as dual address family. Usigng iptables-restore. Prolog is after iptables reset and flush # Prolog place "after policy reset" can not be used when policy is activated with iptables-restore FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" echo "This is prolog" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A INPUT -m state --state NEW -j ACCEPT " echo "-A FORWARD -i + -m state --state NEW -j ACCEPT " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A INPUT -m state --state NEW -j ACCEPT " echo "-A FORWARD -i + -m state --state NEW -j ACCEPT " # echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:27 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall8.fw.orig0000755000175000017500000002252311733011756021752 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:10 2012 PDT by vadim # # files: * firewall8.fw /etc/fw/firewall8.fw # # Compiled for iptables (any version) # # this firewall is used to test a rule in the global policy of object "firewall" FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 33.33.33.33/24" "" update_addresses_of_interface "eth1 172.16.1.1/24" "" update_addresses_of_interface "eth2 192.168.100.1/24" "" getaddr ppp0 i_ppp0 getaddr6 ppp0 i_ppp0_v6 getnet ppp0 i_ppp0_network getnet6 ppp0 i_ppp0_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:10 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall10.fw.orig0000755000175000017500000003445411733011756022031 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:08 2012 PDT by vadim # # files: * firewall10.fw /etc/fw/firewall10.fw # # Compiled for iptables 1.2.9 # # testing rules with action-on-reject "TCP reset" # in this firewall, unlike in firewall9, this option is set globally instead of setting it # in the rule options FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N Cid3D4F0A58.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 6667 -j Cid3D4F0A58.0 $IPTABLES -N RULE_0 $IPTABLES -A Cid3D4F0A58.0 -d 22.22.22.22 -j RULE_0 $IPTABLES -A Cid3D4F0A58.0 -d 192.168.1.1 -j RULE_0 $IPTABLES -A INPUT -p tcp -m tcp --dport 6667 -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level debug $IPTABLES -A RULE_0 -j REJECT --reject-with icmp-admin-prohibited # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N Cid3D4F0A62.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 53 -j Cid3D4F0A62.0 $IPTABLES -N RULE_1 $IPTABLES -A Cid3D4F0A62.0 -d 22.22.22.22 -j RULE_1 $IPTABLES -A Cid3D4F0A62.0 -d 192.168.1.1 -j RULE_1 $IPTABLES -A INPUT -p udp -m udp --dport 53 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level debug $IPTABLES -A RULE_1 -j REJECT --reject-with icmp-host-unreachable # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid3D4F0A6C.0 $IPTABLES -A OUTPUT -p icmp -j Cid3D4F0A6C.0 $IPTABLES -A OUTPUT -p 50 -j Cid3D4F0A6C.0 $IPTABLES -N RULE_2 $IPTABLES -A Cid3D4F0A6C.0 -d 22.22.22.22 -j RULE_2 $IPTABLES -A Cid3D4F0A6C.0 -d 192.168.1.1 -j RULE_2 $IPTABLES -A INPUT -p icmp -j RULE_2 $IPTABLES -A INPUT -p 50 -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level debug $IPTABLES -A RULE_2 -j REJECT --reject-with icmp-host-unreachable # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N Cid3D4F0A76.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -j Cid3D4F0A76.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j Cid3D4F0A76.0 $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -j Cid3D4F0A76.0 $IPTABLES -N RULE_3 $IPTABLES -A Cid3D4F0A76.0 -d 22.22.22.22 -j RULE_3 $IPTABLES -A Cid3D4F0A76.0 -d 192.168.1.1 -j RULE_3 $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -j RULE_3 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j RULE_3 $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level debug $IPTABLES -A RULE_3 -j REJECT --reject-with icmp-host-unreachable # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid3D4F0A80.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -j Cid3D4F0A80.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j Cid3D4F0A80.0 $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -j Cid3D4F0A80.0 $IPTABLES -A Cid3D4F0A80.0 -d 22.22.22.22 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A Cid3D4F0A80.0 -d 192.168.1.1 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -j REJECT --reject-with icmp-host-unreachable # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid3D4F0A8A.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 10000:11000 -j Cid3D4F0A8A.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j Cid3D4F0A8A.0 $IPTABLES -A INPUT -p udp -m udp -m multiport --dports 53,161 -j Cid3D4F0A8A.0 $IPTABLES -A Cid3D4F0A8A.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3D4F0A8A.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3D4F0A8A.0 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A OUTPUT -p tcp -m tcp --dport 10000:11000 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A OUTPUT -p udp -m udp -m multiport --dports 53,161 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A FORWARD -p tcp -m tcp --dport 10000:11000 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j REJECT --reject-with icmp-host-unreachable $IPTABLES -A FORWARD -p udp -m udp -m multiport --dports 53,161 -j REJECT --reject-with icmp-host-unreachable # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid3D4F0A94.0 $IPTABLES -A OUTPUT -d 22.22.22.22 -j Cid3D4F0A94.0 $IPTABLES -A OUTPUT -d 192.168.1.1 -j Cid3D4F0A94.0 $IPTABLES -A INPUT -j Cid3D4F0A94.0 $IPTABLES -A Cid3D4F0A94.0 -p tcp -m tcp --dport 10000:11000 -j RETURN $IPTABLES -A Cid3D4F0A94.0 -p tcp -m tcp --dport 113 -j RETURN $IPTABLES -A Cid3D4F0A94.0 -p udp -m udp -m multiport --dports 53,161 -j RETURN $IPTABLES -A Cid3D4F0A94.0 -j REJECT --reject-with icmp-host-unreachable # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid3D4F0A9E.0 $IPTABLES -A OUTPUT -d 22.22.22.22 -j Cid3D4F0A9E.0 $IPTABLES -A OUTPUT -d 192.168.1.1 -j Cid3D4F0A9E.0 $IPTABLES -A INPUT -j Cid3D4F0A9E.0 $IPTABLES -A Cid3D4F0A9E.0 -p tcp -m tcp --dport 10000:11000 -j RETURN $IPTABLES -A Cid3D4F0A9E.0 -p tcp -m tcp --dport 113 -j RETURN $IPTABLES -A Cid3D4F0A9E.0 -p udp -m udp -m multiport --dports 53,161 -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid3D4F0A9E.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -j LOG --log-level debug $IPTABLES -A RULE_7_3 -j REJECT --reject-with icmp-host-unreachable } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:08 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/heartbeat_cluster_1_linux-1.fw.orig0000755000175000017500000006355111733011756025360 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:41 2012 PDT by vadim # # files: * heartbeat_cluster_1_linux-1.fw /etc/heartbeat_cluster_1_linux-1.fw # # Compiled for iptables 1.4.0 # # # linux-1:to_fw:: warning: ignoring cluster rule set "to_fw" because member firewall "linux-1" has rule set with the same name. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth0.100" for i in eth0 eth1 lo eth0.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_vlans_of_interface "eth0 eth0.100" clear_vlans_except_known eth0.100@eth0 update_addresses_of_interface "eth0 172.24.0.2/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0.100 192.168.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 10/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 10/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 172.24.0.3 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 7 (global) # echo "Rule 7 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -d 172.24.0.1 -j DROP $IPTABLES -A OUTPUT -d 172.24.0.2 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.1 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.2 -j DROP $IPTABLES -A OUTPUT -d 192.168.100.1 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # # fw is part of any $IPTABLES -N Cid997025X96143.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid997025X96143.0 $IPTABLES -A Cid997025X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # fw is NOT part of any $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # fw is NOT part of any $IPTABLES -N Cid143289X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143289X96143.0 $IPTABLES -A Cid143289X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid143289X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid143289X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # fw is NOT part of any $IPTABLES -N Cid1946680X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1946680X96143.0 $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid1946680X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 14 (eth0) # echo "Rule 14 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid378955X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.0 $IPTABLES -A Cid378955X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid378955X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -N Cid378955X96143.1 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.1 $IPTABLES -A Cid378955X96143.1 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.1 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid378955X96143.1 -s 192.168.100.1 -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid1801407X96143.0 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1801407X96143.0 $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid1801407X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # fw is NOT part of any $IPTABLES -N Cid143343X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143343X96143.0 $IPTABLES -A Cid143343X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid143343X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid2241935X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.0 $IPTABLES -A Cid2241935X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241935X96143.1 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.1 $IPTABLES -A Cid2241935X96143.1 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.1 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 18 (eth0) # echo "Rule 18 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid2241981X96143.0 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241981X96143.0 $IPTABLES -A Cid2241981X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241981X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using interface of another cluster in the rule $IPTABLES -N Cid8228X45618.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid8228X45618.0 $IPTABLES -A Cid8228X45618.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.100 -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -N Cid147047X84105.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid147047X84105.0 $IPTABLES -A Cid147047X84105.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.100 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N RULE_21 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_21 $IPTABLES -A INPUT -m state --state NEW -j RULE_21 $IPTABLES -A FORWARD -m state --state NEW -j RULE_21 $IPTABLES -A RULE_21 -j LOG --log-level info --log-prefix "RULE 21 -- DENY " $IPTABLES -A RULE_21 -j DROP # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N RULE_22 $IPTABLES -A OUTPUT -j RULE_22 $IPTABLES -A INPUT -j RULE_22 $IPTABLES -A FORWARD -j RULE_22 $IPTABLES -A RULE_22 -j LOG --log-level info --log-prefix "RULE 22 -- DENY " $IPTABLES -A RULE_22 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 172.24.1.0/24 via 172.24.0.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/vrrp_cluster_1_linux-2.fw.orig0000755000175000017500000004365411733011756024415 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * vrrp_cluster_1_linux-2.fw /etc/vrrp_cluster_1_linux-2.fw # # Compiled for iptables 1.4.0 # # vrrp_cluster_1:Routing:1: error: Object "gw1" used as gateway in the routing rule 1 (main) is not in the same local network as interface eth1 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.3/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.3/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 20/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 20/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -6 VRRP (automatic) # echo "Rule -6 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -5 VRRP (automatic) # echo "Rule -5 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.2 -d 224.0.0.18 -j ACCEPT # # Rule -4 VRRP (automatic) # echo "Rule -4 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -3 VRRP (automatic) # echo "Rule -3 VRRP (automatic)" # $IPTABLES -N Cid3009X69605.2.0 $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -j Cid3009X69605.2.0 $IPTABLES -A Cid3009X69605.2.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.2.0 -s 192.168.100.1 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.3 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.3 -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_8 $IPTABLES -A INPUT -m state --state NEW -j RULE_8 $IPTABLES -A FORWARD -m state --state NEW -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -j RULE_9 $IPTABLES -A INPUT -j RULE_9 $IPTABLES -A FORWARD -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # Rule 1 (main) # echo "Routing rule 1 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # ============== EQUAL COST MULTI PATH ============ # echo "Activating ecmp routing rules..." # # Multipath Rule derived from the following routing rules: # # Rule 0 (main) # # Rule 1 (main) # # $IP route add 172.24.1.0/24 \ nexthop via 172.24.0.100 dev eth0 \ nexthop via 172.24.0.100 dev eth1 \ || route_command_error "1" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-3.fw.orig0000755000175000017500000004475311733011756022715 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:22 2012 PDT by vadim # # files: * firewall-ipv6-3.fw /etc/firewall-ipv6-3.fw # # Compiled for iptables (any version) # # Simple policy that makes sense in ipv4 but translates into a few wide-matching rules in ipv6. Policy is configured as dual address family # firewall-ipv6-3:fw-ipv6-3:2: error: Rule 'fw-ipv6-3 2 (global)' shadows rule 'fw-ipv6-3 3 (global)' below it # firewall-ipv6-3:fw-ipv6-3:4: error: Rule 'fw-ipv6-3 4 (global)' shadows rule 'fw-ipv6-3 6 (global)' below it # firewall-ipv6-3:fw-ipv6-3:2: error: Rule 'fw-ipv6-3 2 (global)' shadows rule 'fw-ipv6-3 3 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 # ================ Table 'filter', rule set fw-ipv6-3 # # Rule fw-ipv6-3 0 (global) # echo "Rule fw-ipv6-3 0 (global)" # $IPTABLES -N In_fw-ipv6-3_0 $IPTABLES -A INPUT -m state --state NEW -j In_fw-ipv6-3_0 $IPTABLES -A In_fw-ipv6-3_0 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 0 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A In_fw-ipv6-3_0 -j ACCEPT # # Rule fw-ipv6-3 1 (global) # echo "Rule fw-ipv6-3 1 (global)" # $IPTABLES -A INPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 2 (global) # echo "Rule fw-ipv6-3 2 (global)" # # firewall-ipv6-3:fw-ipv6-3:2: error: Rule 'fw-ipv6-3 2 (global)' shadows rule 'fw-ipv6-3 3 (global)' below it $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 3 (global) # echo "Rule fw-ipv6-3 3 (global)" # $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 4 (global) # echo "Rule fw-ipv6-3 4 (global)" # # INPUT, OUTPUT, FORWARD # firewall-ipv6-3:fw-ipv6-3:4: error: Rule 'fw-ipv6-3 4 (global)' shadows rule 'fw-ipv6-3 6 (global)' below it $IPTABLES -A INPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 1.1.1.0/24 -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 5 (global) # echo "Rule fw-ipv6-3 5 (global)" # # INPUT, OUTPUT, FORWARD $IPTABLES -A OUTPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 1.1.1.0/24 -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 6 (global) # echo "Rule fw-ipv6-3 6 (global)" # # for bug 2047082 $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 7 (global) # echo "Rule fw-ipv6-3 7 (global)" # $IPTABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 8 (global) # echo "Rule fw-ipv6-3 8 (global)" # $IPTABLES -N fw-ipv6-3_8 $IPTABLES -A OUTPUT -d 72.55.148.116 -j fw-ipv6-3_8 $IPTABLES -A OUTPUT -d 207.251.84.150 -j fw-ipv6-3_8 $IPTABLES -A FORWARD -d 72.55.148.116 -j fw-ipv6-3_8 $IPTABLES -A FORWARD -d 207.251.84.150 -j fw-ipv6-3_8 $IPTABLES -A fw-ipv6-3_8 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 8 -- DENY " --ulog-qthreshold 1 $IPTABLES -A fw-ipv6-3_8 -j DROP # # Rule fw-ipv6-3 9 (global) # echo "Rule fw-ipv6-3 9 (global)" # # ipv4 address range for bug 2820152 $IPTABLES -N fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.1 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.2/31 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.4/30 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.8/29 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.16/28 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.32/27 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.64/27 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.96/30 -j fw-ipv6-3_9 $IPTABLES -A OUTPUT -d 192.168.1.100 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.1 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.2/31 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.4/30 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.8/29 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.16/28 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.32/27 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.64/27 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.96/30 -j fw-ipv6-3_9 $IPTABLES -A FORWARD -d 192.168.1.100 -j fw-ipv6-3_9 $IPTABLES -A fw-ipv6-3_9 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 9 -- DENY " --ulog-qthreshold 1 $IPTABLES -A fw-ipv6-3_9 -j DROP # # Rule fw-ipv6-3 10 (global) # echo "Rule fw-ipv6-3 10 (global)" # # ipv4 address range for bug 2820152 $IPTABLES -N fw-ipv6-3_10 $IPTABLES -A OUTPUT -d 255.255.255.255 -j fw-ipv6-3_10 $IPTABLES -A INPUT -d 255.255.255.255 -j fw-ipv6-3_10 $IPTABLES -A fw-ipv6-3_10 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 10 -- DENY " --ulog-qthreshold 1 $IPTABLES -A fw-ipv6-3_10 -j DROP # # Rule fw-ipv6-3 11 (global) # echo "Rule fw-ipv6-3 11 (global)" # $IPTABLES -N fw-ipv6-3_11 $IPTABLES -A OUTPUT -j fw-ipv6-3_11 $IPTABLES -A INPUT -j fw-ipv6-3_11 $IPTABLES -A FORWARD -j fw-ipv6-3_11 $IPTABLES -A fw-ipv6-3_11 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 11 -- DENY " --ulog-qthreshold 1 $IPTABLES -A fw-ipv6-3_11 -j DROP # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IP6TABLES -N drop_invalid $IP6TABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A INPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A FORWARD -m state --state INVALID -j drop_invalid $IP6TABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IP6TABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set fw-ipv6-3 # # Rule fw-ipv6-3 0 (global) # echo "Rule fw-ipv6-3 0 (global)" # $IP6TABLES -N In_fw-ipv6-3_0 $IP6TABLES -A INPUT -m state --state NEW -j In_fw-ipv6-3_0 $IP6TABLES -A In_fw-ipv6-3_0 -j LOG --log-level info --log-prefix "RULE 0 -- ACCEPT " $IP6TABLES -A In_fw-ipv6-3_0 -j ACCEPT # # Rule fw-ipv6-3 6 (global) # echo "Rule fw-ipv6-3 6 (global)" # # for bug 2047082 $IP6TABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 7 (global) # echo "Rule fw-ipv6-3 7 (global)" # $IP6TABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IP6TABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule fw-ipv6-3 11 (global) # echo "Rule fw-ipv6-3 11 (global)" # $IP6TABLES -N fw-ipv6-3_11 $IP6TABLES -A OUTPUT -j fw-ipv6-3_11 $IP6TABLES -A INPUT -j fw-ipv6-3_11 $IP6TABLES -A FORWARD -j fw-ipv6-3_11 $IP6TABLES -A fw-ipv6-3_11 -j LOG --log-level info --log-prefix "RULE 11 -- DENY " $IP6TABLES -A fw-ipv6-3_11 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:22 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/heartbeat_cluster_2_linux-1.fw.orig0000755000175000017500000005102011733011756025345 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:41 2012 PDT by vadim # # files: * heartbeat_cluster_2_linux-1.fw /etc/heartbeat_cluster_2_linux-1.fw # # Compiled for iptables 1.4.0 # # # linux-1:to_fw:: warning: ignoring cluster rule set "to_fw" because member firewall "linux-1" has rule set with the same name. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth0.100" for i in eth0 eth1 lo eth0.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_vlans_of_interface "eth0 eth0.100" clear_vlans_except_known eth0.100@eth0 update_addresses_of_interface "eth0 172.24.0.2/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0.100 192.168.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 10/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 10/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 172.24.0.3 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 172.24.0.3 --dport 694 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 172.24.0.3 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 172.24.0.3 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 7 (global) # echo "Rule 7 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_8 $IPTABLES -A OUTPUT -d 172.24.0.2 -j RULE_8 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_8 $IPTABLES -A OUTPUT -d 192.168.1.2 -j RULE_8 $IPTABLES -A OUTPUT -d 192.168.100.1 -j RULE_8 $IPTABLES -A INPUT -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_10 $IPTABLES -A INPUT -m state --state NEW -j RULE_10 $IPTABLES -A FORWARD -m state --state NEW -j RULE_10 $IPTABLES -A RULE_10 -j LOG --log-level info --log-prefix "RULE 10 -- DENY " $IPTABLES -A RULE_10 -j DROP # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N RULE_11 $IPTABLES -A OUTPUT -j RULE_11 $IPTABLES -A INPUT -j RULE_11 $IPTABLES -A FORWARD -j RULE_11 $IPTABLES -A RULE_11 -j LOG --log-level info --log-prefix "RULE 11 -- DENY " $IPTABLES -A RULE_11 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 172.24.1.0/24 via 172.24.0.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-1.fw.orig0000755000175000017500000006025711733011756022710 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:21 2012 PDT by vadim # # files: * firewall-ipv6-1.fw /etc/firewall-ipv6-1.fw # # Compiled for iptables (any version) # # Using ULOG globally, but ipv6 rules # should fall back to LOG because # there is no ULOG for ip6tables yet # Bug 2141911 # firewall-ipv6-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-1:Policy:13: error: Rule '13 (global)' shadows rule '15 (global)' below it # firewall-ipv6-1:Policy:14: error: Rule '14 (global)' shadows rule '16 (global)' below it # firewall-ipv6-1:Policy:14: error: Rule '14 (global)' shadows rule '17 (global)' below it # firewall-ipv6-1:Policy:13: error: Rule '13 (global)' shadows rule '17 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 7 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 9 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 10 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 11 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 12 (global)' below it # firewall-ipv6-1:Policy_ipv6:8: error: Rule 'Policy_ipv6 8 (global)' shadows rule 'Policy_ipv6 13 (global)' below it # firewall-ipv6-1:Policy_ipv6:0: error: Rule 'Policy_ipv6 0 (global)' shadows rule 'Policy_ipv6 14 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:6: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:7: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:8: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:8: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:8: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:9: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:10: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-1:Policy_ipv6:: warning: Backup ssh access rule could not be added to IPv6 policy because specified address '1.1.1.2' is invalid FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0" for i in eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # backup ssh access $IPTABLES -A INPUT -p tcp -m tcp -s 1.1.1.2/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d 1.1.1.2/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy # # Rule 4 (global) # echo "Rule 4 (global)" # # firewall-ipv6-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it $IPTABLES -N Cid4834D3108571.0 $IPTABLES -A INPUT -p tcp -m tcp -d 1.1.1.1 --dport 22 -m state --state NEW -j Cid4834D3108571.0 $IPTABLES -N RULE_4 $IPTABLES -A Cid4834D3108571.0 -s 61.150.47.112 -j RULE_4 $IPTABLES -A Cid4834D3108571.0 -s 192.168.1.0 -j RULE_4 $IPTABLES -A RULE_4 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 4 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A RULE_4 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid4835041F8571.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid4835041F8571.0 $IPTABLES -N RULE_6 $IPTABLES -A Cid4835041F8571.0 -s 61.150.47.112 -j RULE_6 $IPTABLES -A Cid4835041F8571.0 -s 192.168.1.0 -j RULE_6 $IPTABLES -A RULE_6 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 6 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A RULE_6 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N In_RULE_7 $IPTABLES -A INPUT -m state --state NEW -j In_RULE_7 $IPTABLES -A In_RULE_7 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 7 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A In_RULE_7 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N RULE_10 $IPTABLES -A INPUT -s 61.150.47.112 -m state --state NEW -j RULE_10 $IPTABLES -A INPUT -s 192.168.1.0 -m state --state NEW -j RULE_10 $IPTABLES -A FORWARD -s 61.150.47.112 -m state --state NEW -j RULE_10 $IPTABLES -A FORWARD -s 192.168.1.0 -m state --state NEW -j RULE_10 $IPTABLES -A RULE_10 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 10 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A RULE_10 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A INPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # firewall-ipv6-1:Policy:13: error: Rule '13 (global)' shadows rule '15 (global)' below it # firewall-ipv6-1:Policy:13: error: Rule '13 (global)' shadows rule '17 (global)' below it $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # INPUT, OUTPUT, FORWARD $IPTABLES -A INPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 1.1.1.0/24 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # INPUT, OUTPUT, FORWARD $IPTABLES -A OUTPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 1.1.1.0/24 -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N RULE_21 $IPTABLES -A OUTPUT -d 72.55.148.116 -j RULE_21 $IPTABLES -A OUTPUT -d 207.251.84.150 -j RULE_21 $IPTABLES -A FORWARD -d 72.55.148.116 -j RULE_21 $IPTABLES -A FORWARD -d 207.251.84.150 -j RULE_21 $IPTABLES -A RULE_21 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 21 -- DENY " --ulog-qthreshold 1 $IPTABLES -A RULE_21 -j DROP # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # rules to permit IPv6 Neighbor discovery $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT # drop packets that do not match any valid state and log them $IP6TABLES -N drop_invalid $IP6TABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A INPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A FORWARD -m state --state INVALID -j drop_invalid $IP6TABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IP6TABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy_ipv6 # # Rule Policy_ipv6 0 (global) # echo "Rule Policy_ipv6 0 (global)" # # for bug 2047082 # firewall-ipv6-1:Policy_ipv6:0: error: Rule 'Policy_ipv6 0 (global)' shadows rule 'Policy_ipv6 14 (global)' below it $IP6TABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule Policy_ipv6 1 (global) # echo "Rule Policy_ipv6 1 (global)" # $IP6TABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IP6TABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule Policy_ipv6 3 (global) # echo "Rule Policy_ipv6 3 (global)" # # INPUT, OUTPUT, FORWARD $IP6TABLES -A INPUT -s fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A OUTPUT -s fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -s fe80::/64 -m state --state NEW -j ACCEPT # # Rule Policy_ipv6 4 (global) # echo "Rule Policy_ipv6 4 (global)" # # INPUT, OUTPUT, FORWARD $IP6TABLES -A OUTPUT -d fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A INPUT -d fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d fe80::/64 -m state --state NEW -j ACCEPT # # Rule Policy_ipv6 5 (global) # echo "Rule Policy_ipv6 5 (global)" # # for bug 2462927, ipv6 networks with /32 # netmask $IP6TABLES -A INPUT -s 2001:db8::/32 -j DROP $IP6TABLES -A INPUT -s 3fff:ffff::/16 -j DROP $IP6TABLES -A INPUT -s 3fff:ffff::/32 -j DROP # # Rule Policy_ipv6 6 (global) # echo "Rule Policy_ipv6 6 (global)" # # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 10 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 11 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 12 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 7 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: error: Rule 'Policy_ipv6 6 (global)' shadows rule 'Policy_ipv6 9 (global)' below it # firewall-ipv6-1:Policy_ipv6:6: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -d fe80::21d:9ff:fe8b:8e94 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 7 (global) # echo "Rule Policy_ipv6 7 (global)" # # firewall-ipv6-1:Policy_ipv6:7: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 8 (global) # echo "Rule Policy_ipv6 8 (global)" # # firewall-ipv6-1:Policy_ipv6:8: error: Rule 'Policy_ipv6 8 (global)' shadows rule 'Policy_ipv6 13 (global)' below it # firewall-ipv6-1:Policy_ipv6:8: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A FORWARD -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 9 (global) # echo "Rule Policy_ipv6 9 (global)" # # firewall-ipv6-1:Policy_ipv6:9: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A INPUT -p tcp -m tcp --dport 993 -m state --state NEW -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 10 (global) # echo "Rule Policy_ipv6 10 (global)" # # firewall-ipv6-1:Policy_ipv6:10: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A INPUT -p tcp -m tcp -m multiport --dports 3268,3269,445,42,53,88,389,636,135,139 -m state --state NEW -j ACCEPT $IP6TABLES -A INPUT -p udp -m udp -m multiport --dports 53,88,138,137 -m state --state NEW -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 11 (global) # echo "Rule Policy_ipv6 11 (global)" # $IP6TABLES -A OUTPUT -p ipv6-icmp -d fe80::21d:9ff:fe8b:8e94 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 12 (global) # echo "Rule Policy_ipv6 12 (global)" # $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 13 (global) # echo "Rule Policy_ipv6 13 (global)" # $IP6TABLES -A OUTPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A FORWARD -p ipv6-icmp -j ACCEPT # # Rule Policy_ipv6 14 (global) # echo "Rule Policy_ipv6 14 (global)" # $IP6TABLES -A OUTPUT -s fe80::21d:9ff:fe8b:8e94 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:21 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall63.fw.orig0000755000175000017500000002462611733011756022041 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:04 2012 PDT by vadim # # files: * firewall63.fw /etc/firewall63.fw # # Compiled for iptables 1.4.0 # # testing TOS and DSCP matching FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p all -m tos --tos 0x20 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p all -m tos --tos 0x20 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p all -m tos --tos 0x20 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A OUTPUT -p all -m dscp --dscp 0x20 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p all -m dscp --dscp 0x20 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p all -m dscp --dscp 0x20 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A OUTPUT -p all -m dscp --dscp-class BE -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p all -m dscp --dscp-class BE -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p all -m dscp --dscp-class BE -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:04 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall41-2.fw.orig0000755000175000017500000003236711733011756022175 0ustar sylvestresylvestre#!/bin/sh /etc/rc.common # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v4.2.0.3437 # # Generated Mon Jan 17 19:23:11 2011 PST by vadim # # files: * firewall41-2.fw # # Compiled for iptables 1.4.3 # # testing run time address table objects with module set # use module set is turned off # firewall41-2::: warning: Can not add virtual address for object atbl.1 START=46 EXTRA_COMMANDS="status interfaces test_interfaces" FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="" IPTABLES="/usr/sbin/iptables" IP6TABLES="/usr/sbin/ip6tables" IPTABLES_RESTORE="/usr/sbin/iptables-restore" IP6TABLES_RESTORE="/usr/sbin/ip6tables-restore" IP="/usr/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/usr/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" test -x "$LOGGER" && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 $PGM >/dev/null 2>&1; test $? = 127 && { echo "$PGM not found" exit 1 } } check_tools() { find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "atbl.1" "addr-table-1.tbl" check_file "block_these" "block-hosts.tbl" } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi insmod ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 1.1.1.1/24" "" update_addresses_of_interface "eth1 2.2.2.2/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -t nat -A POSTROUTING -o eth+ -s $at_atbl_1 -j SNAT --to-source 1.1.1.1 done # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -N Cid2101361X9995.0 $IPTABLES -t nat -A POSTROUTING -o eth+ -j Cid2101361X9995.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -t nat -A Cid2101361X9995.0 -s $at_atbl_1 -j RETURN done $IPTABLES -t nat -A Cid2101361X9995.0 -o eth+ -j SNAT --to-source 1.1.1.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -t nat -A PREROUTING -d $at_atbl_1 -j DNAT --to-destination 192.168.1.10 done # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -m state --state NEW -j ACCEPT done # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N Cid4374297X29460.0 $IPTABLES -A INPUT -s 1.1.1.1 -m state --state NEW -j Cid4374297X29460.0 $IPTABLES -A INPUT -s 2.2.2.2 -m state --state NEW -j Cid4374297X29460.0 $IPTABLES -A OUTPUT -s 1.1.1.1 -m state --state NEW -j Cid4374297X29460.0 $IPTABLES -A OUTPUT -s 2.2.2.2 -m state --state NEW -j Cid4374297X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374297X29460.0 -d $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374297X29460.0 -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid4374309X29460.0 $IPTABLES -A OUTPUT -s 1.1.1.1 -m state --state NEW -j Cid4374309X29460.0 $IPTABLES -A OUTPUT -s 2.2.2.2 -m state --state NEW -j Cid4374309X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374309X29460.0 -d $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374309X29460.0 -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -m state --state NEW -j ACCEPT done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -d $at_block_these -m state --state NEW -j ACCEPT done # # Rule 4 (global) # echo "Rule 4 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A INPUT -s $at_atbl_1 -m state --state NEW -j ACCEPT done # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid4374346X29460.0 $IPTABLES -A OUTPUT -d 1.1.1.1 -m state --state NEW -j Cid4374346X29460.0 $IPTABLES -A OUTPUT -d 2.2.2.2 -m state --state NEW -j Cid4374346X29460.0 $IPTABLES -A INPUT -d 1.1.1.1 -m state --state NEW -j Cid4374346X29460.0 $IPTABLES -A INPUT -d 2.2.2.2 -m state --state NEW -j Cid4374346X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374346X29460.0 -s $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374346X29460.0 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid4374358X29460.0 $IPTABLES -A INPUT -d 1.1.1.1 -m state --state NEW -j Cid4374358X29460.0 $IPTABLES -A INPUT -d 2.2.2.2 -m state --state NEW -j Cid4374358X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374358X29460.0 -s $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374358X29460.0 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A INPUT -s $at_atbl_1 -m state --state NEW -j ACCEPT done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A INPUT -s $at_block_these -m state --state NEW -j ACCEPT done # # Rule 8 (global) # echo "Rule 8 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -j DROP done grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A FORWARD -d $at_atbl_1 -j DROP done } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } start() { log "Activating firewall script generated Mon Jan 17 19:23:11 2011 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands } stop() { stop_action } status() { status_action } interfaces() { configure_interfaces } test_interfaces() { FWBDEBUG="echo" configure_interfaces } fwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-2.fw.orig0000755000175000017500000010624111733011756022703 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:21 2012 PDT by vadim # # files: * firewall-ipv6-2.fw /etc/firewall-ipv6-2.fw # # Compiled for iptables (any version) # # Using ULOG globally, but ipv6 rules # should fall back to LOG because # there is no ULOG for ip6tables yet # Bug 2141911 # firewall-ipv6-2:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall-ipv6-2:Policy:15: error: Rule '15 (global)' shadows rule '17 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '18 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '19 (global)' below it # firewall-ipv6-2:Policy:15: error: Rule '15 (global)' shadows rule '19 (global)' below it # firewall-ipv6-2:Policy:20: error: Rule '20 (global)' shadows rule '22 (global)' below it # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '27 (global)' below it # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '28 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '29 (global)' below it # firewall-ipv6-2:Policy:20: error: Rule '20 (global)' shadows rule '30 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it # firewall-ipv6-2:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it # firewall-ipv6-2:Policy:11: error: Rule '11 (global)' shadows rule '12 (global)' below it # firewall-ipv6-2:Policy:11: error: Rule '11 (global)' shadows rule '12 (global)' below it # firewall-ipv6-2:Policy:13: error: Rule '13 (global)' shadows rule '14 (global)' below it # firewall-ipv6-2:Policy:15: error: Rule '15 (global)' shadows rule '17 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '18 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '19 (global)' below it # firewall-ipv6-2:Policy:15: error: Rule '15 (global)' shadows rule '19 (global)' below it # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '25 (global)' below it # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '27 (global)' below it # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '28 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '29 (global)' below it # firewall-ipv6-2:Policy:22: error: Rule '22 (global)' shadows rule '30 (global)' below it # firewall-ipv6-2:Policy:16: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:16: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:16: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:18: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:18: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:18: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:19: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:19: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:19: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:27: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:27: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:28: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:29: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:29: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:29: warning: Making rule stateless because it matches ICMPv6 # firewall-ipv6-2:Policy:: warning: Backup ssh access rule could not be added to IPv6 policy because specified address '1.1.1.2' is invalid FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0" for i in eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # backup ssh access $IPTABLES -A INPUT -p tcp -m tcp -s 1.1.1.2/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d 1.1.1.2/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy # # Rule 4 (global) # echo "Rule 4 (global)" # # firewall-ipv6-2:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it $IPTABLES -N Cid56136X87590.0 $IPTABLES -A INPUT -p tcp -m tcp -d 1.1.1.1 --dport 22 -m state --state NEW -j Cid56136X87590.0 $IPTABLES -N RULE_4 $IPTABLES -A Cid56136X87590.0 -s 61.150.47.112 -j RULE_4 $IPTABLES -A Cid56136X87590.0 -s 192.168.1.0 -j RULE_4 $IPTABLES -A RULE_4 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 4 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A RULE_4 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid56160X87590.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid56160X87590.0 $IPTABLES -N RULE_6 $IPTABLES -A Cid56160X87590.0 -s 61.150.47.112 -j RULE_6 $IPTABLES -A Cid56160X87590.0 -s 192.168.1.0 -j RULE_6 $IPTABLES -A RULE_6 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 6 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A RULE_6 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '27 (global)' below it # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '28 (global)' below it $IPTABLES -N In_RULE_7 $IPTABLES -A INPUT -m state --state NEW -j In_RULE_7 $IPTABLES -A In_RULE_7 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 7 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A In_RULE_7 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # # firewall-ipv6-2:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N RULE_12 $IPTABLES -A INPUT -s 61.150.47.112 -m state --state NEW -j RULE_12 $IPTABLES -A INPUT -s 192.168.1.0 -m state --state NEW -j RULE_12 $IPTABLES -A FORWARD -s 61.150.47.112 -m state --state NEW -j RULE_12 $IPTABLES -A FORWARD -s 192.168.1.0 -m state --state NEW -j RULE_12 $IPTABLES -A RULE_12 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 12 -- ACCEPT " --ulog-qthreshold 1 $IPTABLES -A RULE_12 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A INPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # firewall-ipv6-2:Policy:15: error: Rule '15 (global)' shadows rule '17 (global)' below it # firewall-ipv6-2:Policy:15: error: Rule '15 (global)' shadows rule '19 (global)' below it $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # # INPUT, OUTPUT, FORWARD # firewall-ipv6-2:Policy:20: error: Rule '20 (global)' shadows rule '22 (global)' below it # firewall-ipv6-2:Policy:20: error: Rule '20 (global)' shadows rule '30 (global)' below it $IPTABLES -A INPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 1.1.1.0/24 -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # # INPUT, OUTPUT, FORWARD $IPTABLES -A OUTPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 1.1.1.0/24 -m state --state NEW -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # # for bug 2047082 $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N RULE_24 $IPTABLES -A OUTPUT -d 72.55.148.116 -j RULE_24 $IPTABLES -A OUTPUT -d 207.251.84.150 -j RULE_24 $IPTABLES -A FORWARD -d 72.55.148.116 -j RULE_24 $IPTABLES -A FORWARD -d 207.251.84.150 -j RULE_24 $IPTABLES -A RULE_24 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 24 -- DENY " --ulog-qthreshold 1 $IPTABLES -A RULE_24 -j DROP # # Rule 30 (global) # echo "Rule 30 (global)" # $IPTABLES -A OUTPUT -s 1.1.1.1 -m state --state NEW -j ACCEPT # # Rule 32 (global) # echo "Rule 32 (global)" # # ipv4 address range for bug 2820152 $IPTABLES -N RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.2/31 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.4/30 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.8/29 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.16/28 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.32/27 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.64/27 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.96/30 -j RULE_32 $IPTABLES -A OUTPUT -d 192.168.1.100 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.1 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.2/31 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.4/30 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.8/29 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.16/28 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.32/27 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.64/27 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.96/30 -j RULE_32 $IPTABLES -A FORWARD -d 192.168.1.100 -j RULE_32 $IPTABLES -A RULE_32 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 32 -- DENY " --ulog-qthreshold 1 $IPTABLES -A RULE_32 -j DROP # # Rule 33 (global) # echo "Rule 33 (global)" # # ipv4 address range for bug 2820152 $IPTABLES -N RULE_33 $IPTABLES -A OUTPUT -d 255.255.255.255 -j RULE_33 $IPTABLES -A INPUT -d 255.255.255.255 -j RULE_33 $IPTABLES -A RULE_33 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 33 -- DENY " --ulog-qthreshold 1 $IPTABLES -A RULE_33 -j DROP # # Rule 34 (global) # echo "Rule 34 (global)" # $IPTABLES -N RULE_34 $IPTABLES -A OUTPUT -j RULE_34 $IPTABLES -A INPUT -j RULE_34 $IPTABLES -A FORWARD -j RULE_34 $IPTABLES -A RULE_34 -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 34 -- DENY " --ulog-qthreshold 1 $IPTABLES -A RULE_34 -j DROP # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IP6TABLES -N drop_invalid $IP6TABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A INPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A FORWARD -m state --state INVALID -j drop_invalid $IP6TABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IP6TABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # this rule shadows the next. # Note that we add command line # flag -xt to the compiler $IP6TABLES -A INPUT -p tcp -m tcp -s fe80::/64 -d fe80::21d:9ff:fe8b:8e94 --dport 22 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '3 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:1: error: Rule '1 (global)' shadows rule '6 (global)' below it $IP6TABLES -A INPUT -p tcp -m tcp -s 2001:5c0:0:2::24 -d fe80::21d:9ff:fe8b:8e94 --dport 22 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '4 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '5 (global)' below it # firewall-ipv6-2:Policy:2: error: Rule '2 (global)' shadows rule '6 (global)' below it $IP6TABLES -N RULE_2 $IP6TABLES -A INPUT -p tcp -m tcp -s 3ffe:1200:2001:1:8000::1 --dport 22 -m state --state NEW -j RULE_2 $IP6TABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- ACCEPT " $IP6TABLES -A RULE_2 -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # firewall-ipv6-2:Policy:3: error: Rule '3 (global)' shadows rule '5 (global)' below it $IP6TABLES -N Cid56124X87590.0 $IP6TABLES -A INPUT -p tcp -m tcp -d fe80::21d:9ff:fe8b:8e94 --dport 22 -m state --state NEW -j Cid56124X87590.0 $IP6TABLES -N RULE_3 $IP6TABLES -A Cid56124X87590.0 -s 2001:5c0:0:2::24 -j RULE_3 $IP6TABLES -A Cid56124X87590.0 -s 3ffe:1200:2000::/36 -j RULE_3 $IP6TABLES -A Cid56124X87590.0 -s 3ffe:1200:2001:1:8000::1 -j RULE_3 $IP6TABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- ACCEPT " $IP6TABLES -A RULE_3 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IP6TABLES -N Cid56136X87590.0 $IP6TABLES -A INPUT -p tcp -m tcp -d fe80::21d:9ff:fe8b:8e94 --dport 22 -m state --state NEW -j Cid56136X87590.0 $IP6TABLES -N RULE_4 $IP6TABLES -A Cid56136X87590.0 -s 2001:5c0:0:2::24 -j RULE_4 $IP6TABLES -A Cid56136X87590.0 -s 3ffe:1200:2001:1:8000::1 -j RULE_4 $IP6TABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- ACCEPT " $IP6TABLES -A RULE_4 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IP6TABLES -N Cid56148X87590.0 $IP6TABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid56148X87590.0 $IP6TABLES -N RULE_5 $IP6TABLES -A Cid56148X87590.0 -s 2001:5c0:0:2::24 -j RULE_5 $IP6TABLES -A Cid56148X87590.0 -s 3ffe:1200:2000::/36 -j RULE_5 $IP6TABLES -A Cid56148X87590.0 -s 3ffe:1200:2001:1:8000::1 -j RULE_5 $IP6TABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IP6TABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IP6TABLES -N Cid56160X87590.0 $IP6TABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid56160X87590.0 $IP6TABLES -N RULE_6 $IP6TABLES -A Cid56160X87590.0 -s 2001:5c0:0:2::24 -j RULE_6 $IP6TABLES -A Cid56160X87590.0 -s 3ffe:1200:2001:1:8000::1 -j RULE_6 $IP6TABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- ACCEPT " $IP6TABLES -A RULE_6 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '27 (global)' below it # firewall-ipv6-2:Policy:7: error: Rule '7 (global)' shadows rule '28 (global)' below it $IP6TABLES -N In_RULE_7 $IP6TABLES -A INPUT -m state --state NEW -j In_RULE_7 $IP6TABLES -A In_RULE_7 -j LOG --log-level info --log-prefix "RULE 7 -- ACCEPT " $IP6TABLES -A In_RULE_7 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # # firewall-ipv6-2:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it $IP6TABLES -A OUTPUT -d e80::21d:9ff:fe8b:8e94 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d e80::21d:9ff:fe8b:8e94 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IP6TABLES -A OUTPUT -d e80::21d:9ff:fe8b:8e94 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d e80::21d:9ff:fe8b:8e94 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # # firewall-ipv6-2:Policy:10: error: Rule '10 (global)' shadows rule '25 (global)' below it $IP6TABLES -N RULE_10 $IP6TABLES -A INPUT -s fe80::/64 -m state --state NEW -j RULE_10 $IP6TABLES -A OUTPUT -s fe80::/64 -m state --state NEW -j RULE_10 $IP6TABLES -A FORWARD -s fe80::/64 -m state --state NEW -j RULE_10 $IP6TABLES -A RULE_10 -j LOG --log-level info --log-prefix "RULE 10 -- ACCEPT " $IP6TABLES -A RULE_10 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # firewall-ipv6-2:Policy:11: error: Rule '11 (global)' shadows rule '12 (global)' below it $IP6TABLES -N RULE_11 $IP6TABLES -A INPUT -s 2001:5c0:0:2::24 -m state --state NEW -j RULE_11 $IP6TABLES -A INPUT -s 3ffe:1200:2000::/36 -m state --state NEW -j RULE_11 $IP6TABLES -A INPUT -s 3ffe:1200:2001:1:8000::1 -m state --state NEW -j RULE_11 $IP6TABLES -A FORWARD -s 2001:5c0:0:2::24 -m state --state NEW -j RULE_11 $IP6TABLES -A FORWARD -s 3ffe:1200:2000::/36 -m state --state NEW -j RULE_11 $IP6TABLES -A FORWARD -s 3ffe:1200:2001:1:8000::1 -m state --state NEW -j RULE_11 $IP6TABLES -A RULE_11 -j LOG --log-level info --log-prefix "RULE 11 -- ACCEPT " $IP6TABLES -A RULE_11 -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IP6TABLES -N RULE_12 $IP6TABLES -A INPUT -s 2001:5c0:0:2::24 -m state --state NEW -j RULE_12 $IP6TABLES -A INPUT -s 3ffe:1200:2001:1:8000::1 -m state --state NEW -j RULE_12 $IP6TABLES -A FORWARD -s 2001:5c0:0:2::24 -m state --state NEW -j RULE_12 $IP6TABLES -A FORWARD -s 3ffe:1200:2001:1:8000::1 -m state --state NEW -j RULE_12 $IP6TABLES -A RULE_12 -j LOG --log-level info --log-prefix "RULE 12 -- ACCEPT " $IP6TABLES -A RULE_12 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '18 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '19 (global)' below it # firewall-ipv6-2:Policy:16: error: Rule '16 (global)' shadows rule '29 (global)' below it # firewall-ipv6-2:Policy:16: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A FORWARD -p ipv6-icmp -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # firewall-ipv6-2:Policy:18: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128/0 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128/0 -j ACCEPT $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type 128/0 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # firewall-ipv6-2:Policy:19: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128/0 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128/0 -j ACCEPT $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type 128/0 -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # # for bug 2047082 # firewall-ipv6-2:Policy:22: error: Rule '22 (global)' shadows rule '30 (global)' below it $IP6TABLES -A OUTPUT -m state --state NEW -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IP6TABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IP6TABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule 25 (global) # echo "Rule 25 (global)" # # INPUT, OUTPUT, FORWARD $IP6TABLES -A INPUT -s fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A OUTPUT -s fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -s fe80::/64 -m state --state NEW -j ACCEPT # # Rule 26 (global) # echo "Rule 26 (global)" # # INPUT, OUTPUT, FORWARD $IP6TABLES -A OUTPUT -d fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A INPUT -d fe80::/64 -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -d fe80::/64 -m state --state NEW -j ACCEPT # # Rule 27 (global) # echo "Rule 27 (global)" # # firewall-ipv6-2:Policy:27: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -d fe80::21d:9ff:fe8b:8e94 -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule 28 (global) # echo "Rule 28 (global)" # # firewall-ipv6-2:Policy:28: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT # # Rule 29 (global) # echo "Rule 29 (global)" # # firewall-ipv6-2:Policy:29: warning: Making rule stateless because it matches ICMPv6 $IP6TABLES -A OUTPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A INPUT -p ipv6-icmp -j ACCEPT $IP6TABLES -A FORWARD -p ipv6-icmp -j ACCEPT # # Rule 30 (global) # echo "Rule 30 (global)" # $IP6TABLES -A OUTPUT -s fe80::21d:9ff:fe8b:8e94 -m state --state NEW -j ACCEPT # # Rule 31 (global) # echo "Rule 31 (global)" # # test for bug 2463048 # "custom services should have IPv4/v6 setting" # rule should compile for ipv6 b/c custom service # object "ipv6 source route" is configured as "ipv6" $IP6TABLES -N RULE_31 $IP6TABLES -A OUTPUT -m rt --rt-type 0 -j RULE_31 $IP6TABLES -A INPUT -m rt --rt-type 0 -j RULE_31 $IP6TABLES -A FORWARD -m rt --rt-type 0 -j RULE_31 $IP6TABLES -A RULE_31 -j LOG --log-level info --log-prefix "RULE 31 -- DENY " $IP6TABLES -A RULE_31 -j DROP # # Rule 34 (global) # echo "Rule 34 (global)" # $IP6TABLES -N RULE_34 $IP6TABLES -A OUTPUT -j RULE_34 $IP6TABLES -A INPUT -j RULE_34 $IP6TABLES -A FORWARD -j RULE_34 $IP6TABLES -A RULE_34 -j LOG --log-level info --log-prefix "RULE 34 -- DENY " $IP6TABLES -A RULE_34 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all # backup ssh access $IPTABLES -A INPUT -p tcp -m tcp -s 1.1.1.2/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d 1.1.1.2/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:21 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall23-2.fw.orig0000755000175000017500000002264611733011756022174 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:26 2012 PDT by vadim # # files: * firewall23-2.fw /etc/fw/firewall23-2.fw # # Compiled for iptables 1.3.0 # # This is BRIDGING FIREWALL # with two bridges and wildcard bridge port interfaces # see SF bug #3439613 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'filter', rule set Policy # # Rule 0 (vnet+) # echo "Rule 0 (vnet+)" # # -i br0 $IPTABLES -A INPUT -i br0 -m physdev --physdev-in vnet+ -m state --state NEW -j ACCEPT # # Rule 1 (vnet+) # echo "Rule 1 (vnet+)" # # -i br1 $IPTABLES -A INPUT -i br1 -m physdev --physdev-in vnet+ -m state --state NEW -j ACCEPT # # Rule 2 (vnet+) # echo "Rule 2 (vnet+)" # # -o br0 $IPTABLES -A OUTPUT -o br0 -m physdev --physdev-is-bridged --physdev-out vnet+ -m state --state NEW -j ACCEPT # # Rule 3 (vnet+) # echo "Rule 3 (vnet+)" # # -o br1 $IPTABLES -A OUTPUT -o br1 -m physdev --physdev-is-bridged --physdev-out vnet+ -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:26 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall3.fw.orig0000755000175000017500000004126111733011756021745 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:36 2012 PDT by vadim # # files: * firewall3.fw /etc/fw/firewall3.fw # # Compiled for iptables (any version) # # this object is used to test negation in policy rules with "Assume firewall is part of 'Any'" turned OFF FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 # ================ Table 'filter', rule set Policy # # Rule 0 (lo) # echo "Rule 0 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # $IPTABLES -N In_RULE_1 $IPTABLES -A FORWARD -i eth1 -p all -f -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level debug $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # $IPTABLES -N In_RULE_2 $IPTABLES -A FORWARD -i eth0 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A In_RULE_2 -j LOG --log-level debug $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth0,eth2) # echo "Rule 3 (eth0,eth2)" # $IPTABLES -N In_RULE_3 $IPTABLES -A FORWARD -i eth0 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth2 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A In_RULE_3 -j LOG --log-level debug $IPTABLES -A In_RULE_3 -j DROP # # Rule 4 (eth0) # echo "Rule 4 (eth0)" # # testing choice of chains in case when several interfaces # are used and rule matches on any or broadcast $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 5 (eth0,eth2) # echo "Rule 5 (eth0,eth2)" # # testing choice of chains in case when several interfaces # are used and rule matches on any or broadcast $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 6 (eth0) # echo "Rule 6 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 7 (eth0,eth2) # echo "Rule 7 (eth0,eth2)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # # Anti-spoofing rule $IPTABLES -N In_RULE_10 $IPTABLES -A FORWARD -i eth1 -s 22.22.22.22 -j In_RULE_10 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_10 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_10 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_10 $IPTABLES -A In_RULE_10 -j LOG --log-level debug $IPTABLES -A In_RULE_10 -j DROP # # Rule 11 (eth1) # echo "Rule 11 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid3B02271D.0 $IPTABLES -A OUTPUT -o eth1 -j Cid3B02271D.0 $IPTABLES -A Cid3B02271D.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid3B02271D.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid3B02271D.0 -s 192.168.2.1 -j RETURN $IPTABLES -N Out_RULE_11_3 $IPTABLES -A Cid3B02271D.0 -j Out_RULE_11_3 $IPTABLES -A Out_RULE_11_3 -j LOG --log-level debug $IPTABLES -A Out_RULE_11_3 -j DROP $IPTABLES -N Cid3B02271D.1 $IPTABLES -A FORWARD -o eth1 -j Cid3B02271D.1 $IPTABLES -A Cid3B02271D.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid3B02271D.1 -j Out_RULE_11_3 # # Rule 12 (global) # echo "Rule 12 (global)" # # hostF has the same IP address as firewal. $IPTABLES -N RULE_12 $IPTABLES -A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level debug $IPTABLES -A RULE_12 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # testing negation in the policy rule $IPTABLES -N Cid3B0226DF.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid3B0226DF.0 $IPTABLES -A Cid3B0226DF.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid3B0226DF.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_14_3 $IPTABLES -A Cid3B0226DF.0 -j RULE_14_3 $IPTABLES -A RULE_14_3 -j LOG --log-level debug $IPTABLES -A RULE_14_3 -j DROP # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A FORWARD -d ! 33.33.33.0/24 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -N Cid40F57E72.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid40F57E72.0 $IPTABLES -A Cid40F57E72.0 -d 33.33.33.0/24 -j RETURN $IPTABLES -A Cid40F57E72.0 -d 222.222.222.0/24 -j RETURN $IPTABLES -A Cid40F57E72.0 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -N Cid41A8EF1D.0 $IPTABLES -A INPUT -m state --state NEW -j Cid41A8EF1D.0 $IPTABLES -A Cid41A8EF1D.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid41A8EF1D.0 -d 192.168.2.1 -j RETURN $IPTABLES -A Cid41A8EF1D.0 -j ACCEPT $IPTABLES -A FORWARD -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # testing negation in service field $IPTABLES -N Cid3B0226EA.0 $IPTABLES -A FORWARD -d 192.168.1.10 -j Cid3B0226EA.0 $IPTABLES -A FORWARD -d 192.168.1.20 -j Cid3B0226EA.0 $IPTABLES -A Cid3B0226EA.0 -p tcp -m tcp -m multiport --dports 25,22 -j RETURN $IPTABLES -N RULE_18_3 $IPTABLES -A Cid3B0226EA.0 -j RULE_18_3 $IPTABLES -A RULE_18_3 -j LOG --log-level debug $IPTABLES -A RULE_18_3 -j DROP # # Rule 19 (global) # echo "Rule 19 (global)" # # 'masquerading' rule $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # # 'catch all' rule $IPTABLES -N RULE_20 $IPTABLES -A FORWARD -j RULE_20 $IPTABLES -A RULE_20 -j LOG --log-level debug $IPTABLES -A RULE_20 -j DROP # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N Cid440D600617760.0 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid440D600617760.0 $IPTABLES -A Cid440D600617760.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid440D600617760.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid440D600617760.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid440D600617760.0 -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N Cid440D880417760.0 $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid440D880417760.0 $IPTABLES -A Cid440D880417760.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid440D880417760.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid440D880417760.0 -d 192.168.2.1 -j RETURN $IPTABLES -A Cid440D880417760.0 -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 23 (eth1,eth0,eth2) # echo "Rule 23 (eth1,eth0,eth2)" # # this rule should go only to the FORWARD # chain but should have "-i eth" clause $IPTABLES -A FORWARD -i eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:36 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall62.fw.orig0000755000175000017500000004461311733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:03 2012 PDT by vadim # # files: * firewall62.fw /etc/firewall62.fw # # Compiled for iptables 1.4.0 # # testing rules using UserService object # Note that iptables does not allow entering # iptables command that tries to match using module 'owner' in any chain # other than OUTPUT. This includes user defined chains too (it checks # how control passes to user defined chain and blocks command if # it appears that user defined chain gets control not from OUTPUT) # firewall62:Policy:0: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:2: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:4: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:5: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:5: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:6: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:7: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:8: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:8: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:9: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:9: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:10: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:10: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:11: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:11: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:12: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:13: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:16: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:16: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:17: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall62:Policy:17: warning: Iptables does not support module 'owner' in a chain other than OUTPUT FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # firewall62:Policy:0: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall62:Policy:2: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -N Cid484A599620246.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j Cid484A599620246.0 $IPTABLES -A Cid484A599620246.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid484A599620246.0 -s 222.222.222.222 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # firewall62:Policy:4: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -s 192.168.1.1 -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # firewall62:Policy:5: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # firewall62:Policy:6: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -N Cid4848F1BB20246.0 $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j Cid4848F1BB20246.0 $IPTABLES -A Cid4848F1BB20246.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid4848F1BB20246.0 -d 222.222.222.222 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # # firewall62:Policy:8: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -s ! 192.168.1.0/24 -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # # firewall62:Policy:9: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # # bug 2186568 # firewall62:Policy:10: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m owner --uid-owner 500 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # bug 2186568 # firewall62:Policy:11: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -N Cid55369X1137.0 $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j Cid55369X1137.0 $IPTABLES -A OUTPUT -m owner --uid-owner 500 -m state --state NEW -j Cid55369X1137.0 $IPTABLES -A Cid55369X1137.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid55369X1137.0 -d 222.222.222.222 -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # bug 2186568 # firewall62:Policy:12: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -m owner ! --uid-owner 2000 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # bug 2186568 # firewall62:Policy:13: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -N Cid72626X1137.0 $IPTABLES -A OUTPUT -m owner ! --uid-owner 2000 -m state --state NEW -j Cid72626X1137.0 $IPTABLES -A Cid72626X1137.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid72626X1137.0 -d 222.222.222.222 -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # bug 2186568 $IPTABLES -N Cid124556X1137.0 $IPTABLES -A INPUT -s 192.168.1.1 -m state --state NEW -j Cid124556X1137.0 $IPTABLES -A INPUT -s 222.222.222.222 -m state --state NEW -j Cid124556X1137.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid124556X1137.0 $IPTABLES -A Cid124556X1137.0 -m owner --uid-owner 2000 -j RETURN $IPTABLES -A Cid124556X1137.0 -m owner --uid-owner 500 -j RETURN $IPTABLES -A Cid124556X1137.0 -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # bug 2186568 $IPTABLES -N Cid124573X1137.0 $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j Cid124573X1137.0 $IPTABLES -A OUTPUT -d 222.222.222.222 -m state --state NEW -j Cid124573X1137.0 $IPTABLES -A INPUT -m state --state NEW -j Cid124573X1137.0 $IPTABLES -A Cid124573X1137.0 -m owner --uid-owner 2000 -j RETURN $IPTABLES -A Cid124573X1137.0 -m owner --uid-owner 500 -j RETURN $IPTABLES -A Cid124573X1137.0 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # bug 2186568 # firewall62:Policy:16: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m owner --uid-owner 500 -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # bug 2186568 # firewall62:Policy:17: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -N Cid89930X1137.0 $IPTABLES -A OUTPUT -m owner --uid-owner 2000 -m state --state NEW -j Cid89930X1137.0 $IPTABLES -A OUTPUT -m owner --uid-owner 500 -m state --state NEW -j Cid89930X1137.0 $IPTABLES -A Cid89930X1137.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid89930X1137.0 -d 222.222.222.222 -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -A OUTPUT -j DROP $IPTABLES -A INPUT -j DROP $IPTABLES -A FORWARD -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:03 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall30.fw.orig0000755000175000017500000002265611733011756022034 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:36 2012 PDT by vadim # # files: * firewall30.fw /etc/fw/firewall30.fw # # Compiled for iptables (any version) # # testing shading of rules using MAC addresses FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -m mac --mac-source 00:10:4b:de:e9:6f -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m mac --mac-source 00:10:4b:de:e9:6f -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A INPUT -m mac --mac-source 00:10:4b:de:e9:70 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m mac --mac-source 00:10:4b:de:e9:70 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 $IPTABLES -A OUTPUT -j RULE_2 $IPTABLES -A INPUT -j RULE_2 $IPTABLES -A FORWARD -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level debug --log-prefix "RULE 2 -- DENY global" $IPTABLES -A RULE_2 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:36 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/recycle0000755000175000017500000000007511733011756020127 0ustar sylvestresylvestre#!/bin/sh for f in *.fw; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/ipt/firewall2-5.fw.orig0000755000175000017500000003261511733011756022111 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:30 2012 PDT by vadim # # files: * firewall2-5.fw /etc/fw/firewall2-5.fw # # Compiled for iptables (any version) # # various tests for the "-o itf" clause in SNAT rules # firewall2-5:NAT:4: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) # firewall2-5:NAT:6: error: Original and translated source should both be networks of the same size. # firewall2-5:NAT:7: warning: Adding of virtual address for address range is not implemented (object range 33 30-33) # firewall2-5::: warning: Can not add virtual address 22.22.22.0 (object external_net) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24 222.222.222.40/24 222.222.222.41/24" "" update_addresses_of_interface "eth3 33.33.33.25/29" "" update_addresses_of_interface "eth2 33.33.33.3/29 33.33.33.4/29" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # NETMAP and no -o itf $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.41 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.222 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.222 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # # should be -o eth1 # firewall2-5:NAT:4: warning: Adding of virtual address for address range is not implemented (object r-222.222.222.0) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.10-222.222.222.100 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # # should be -o eth2 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 33.33.33.1-33.33.33.3 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # # partially matches eth3 # firewall2-5:NAT:7: warning: Adding of virtual address for address range is not implemented (object range 33 30-33) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 33.33.33.30-33.33.33.33 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # # should be two rules: -o eth2 and -o eth3 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 33.33.33.1-33.33.33.33 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # # should be -o eth2 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 33.33.33.3 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 33.33.33.4 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # 'catch all' rule $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 0 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:30 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/vrrp_cluster_2_linux-3.fw.orig0000755000175000017500000003627611733011756024421 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * vrrp_cluster_2_linux-3.fw /etc/vrrp_cluster_2_linux-3.fw # # Compiled for iptables (any version) # FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.4/16" "172.24.0.1/24" update_addresses_of_interface "eth1 192.168.1.4/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set Policy # # Rule -6 VRRP (automatic) # echo "Rule -6 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -5 VRRP (automatic) # echo "Rule -5 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.3 -d 224.0.0.18 -j ACCEPT # # Rule -4 VRRP (automatic) # echo "Rule -4 VRRP (automatic)" # $IPTABLES -A INPUT -i eth1 -p vrrp -s 192.168.1.2 -d 224.0.0.18 -j ACCEPT # # Rule -3 VRRP (automatic) # echo "Rule -3 VRRP (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -j ACCEPT # # Rule -2 VRRP (automatic) # echo "Rule -2 VRRP (automatic)" # $IPTABLES -A INPUT -i eth0 -p vrrp -s 172.24.0.3 -d 224.0.0.18 -j ACCEPT # # Rule -1 VRRP (automatic) # echo "Rule -1 VRRP (automatic)" # $IPTABLES -N Cid8278X18284.0.0 $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -j Cid8278X18284.0.0 $IPTABLES -A Cid8278X18284.0.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid8278X18284.0.0 -s 192.168.100.1 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.4 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.4 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.4 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.4 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.4 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid5188X25627.0 $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid5188X25627.0 $IPTABLES -A Cid5188X25627.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid5188X25627.0 -d 192.168.1.3 -j ACCEPT $IPTABLES -N Cid5188X25627.1 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid5188X25627.1 $IPTABLES -A Cid5188X25627.1 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid5188X25627.1 -d 192.168.1.3 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_6 $IPTABLES -A OUTPUT -d 172.24.0.4 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_6 $IPTABLES -A OUTPUT -d 192.168.1.4 -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_8 $IPTABLES -A INPUT -m state --state NEW -j RULE_8 $IPTABLES -A FORWARD -m state --state NEW -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -j RULE_9 $IPTABLES -A INPUT -j RULE_9 $IPTABLES -A FORWARD -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall11.fw.orig0000755000175000017500000004010011733011756022013 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:09 2012 PDT by vadim # # files: * firewall11.fw /etc/fw/firewall11.fw # # Compiled for iptables (any version) # # testing rules with broadcasts and multicasts and action-on-reject 'TCP reset'. # This is BRIDGING FIREWALL # Firewall is part of any is OFF # Interfaces eth0 and eth1 are parts of the bridge; Interface eth2 is external interface (doing NAT and routing on this interface) Interface eth3 is connected to protected network and is used to manage firewall. This is rather realistic configuration for the bridging firewall FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth3 10.1.1.1/32" "" getaddr eth2 i_eth2 getaddr6 eth2 i_eth2_v6 getnet eth2 i_eth2_network getnet6 eth2 i_eth2_v6_network getaddr br0 i_br0 getaddr6 br0 i_br0_v6 getnet br0 i_br0_network getnet6 br0 i_br0_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o br0 -s 192.168.1.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 10.1.1.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # see bug #1693 , SF bug 3048516 # combination of using SNAT instead of MASQ, # source port translation and dynamic interface for i_br0 in $i_br0_list do test -n "$i_br0" && $IPTABLES -t nat -A POSTROUTING -o br0 -p tcp -m tcp -s 192.168.1.0/24 --sport 1000:1010 -j SNAT --to-source $i_br0:1000-1010 done # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # # see SF bug 3057503 for i_br0 in $i_br0_list do test -n "$i_br0" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination $i_br0:3128 done # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A FORWARD -i eth0 -d 192.168.1.255 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A FORWARD -i eth0 -d 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # $IPTABLES -A FORWARD -o eth0 -d 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 3 (eth0) # echo "Rule 3 (eth0)" # $IPTABLES -A FORWARD -i eth0 -d 255.255.255.255 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth0 -d 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 4 (eth0) # echo "Rule 4 (eth0)" # $IPTABLES -A FORWARD -i eth0 -d 224.0.1.141 -m state --state NEW -j ACCEPT # # Rule 5 (eth0) # echo "Rule 5 (eth0)" # $IPTABLES -A FORWARD -i eth0 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 6 (eth0) # echo "Rule 6 (eth0)" # $IPTABLES -A FORWARD -i eth0 -d ! 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 7 (br0) # echo "Rule 7 (br0)" # $IPTABLES -A INPUT -i br0 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 8 (br0) # echo "Rule 8 (br0)" # $IPTABLES -A INPUT -i br0 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 9 (br0) # echo "Rule 9 (br0)" # for i_br0 in $i_br0_list do test -n "$i_br0" && $IPTABLES -A INPUT -i br0 -p tcp -m tcp -d $i_br0 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 10 (br0) # echo "Rule 10 (br0)" # $IPTABLES -N In_RULE_10 $IPTABLES -A INPUT -i br0 -j In_RULE_10 $IPTABLES -A FORWARD -i br0 -j In_RULE_10 $IPTABLES -A In_RULE_10 -j LOG --log-level debug $IPTABLES -A In_RULE_10 -j DROP $IPTABLES -N Out_RULE_10 $IPTABLES -A OUTPUT -o br0 -j Out_RULE_10 $IPTABLES -A FORWARD -o br0 -j Out_RULE_10 $IPTABLES -A Out_RULE_10 -j LOG --log-level debug $IPTABLES -A Out_RULE_10 -j DROP # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A FORWARD -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N Cid3D94D513.0 $IPTABLES -A FORWARD -p udp -m udp --dport 68 -m state --state NEW -j Cid3D94D513.0 $IPTABLES -A Cid3D94D513.0 -d 192.168.1.10 -j ACCEPT $IPTABLES -A Cid3D94D513.0 -d 192.168.1.255 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A FORWARD -p udp -m udp -d 192.168.1.0 --dport 68 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A FORWARD -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A FORWARD -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -A FORWARD -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -N RULE_18 $IPTABLES -A FORWARD -d 192.168.1.10 -j RULE_18 $IPTABLES -A RULE_18 -j LOG --log-level debug $IPTABLES -A RULE_18 -j DROP # # Rule 19 (global) # echo "Rule 19 (global)" # # this rule should generate commands # in both INPUT and FORWARD chains # because this is a bridging firewall # see bug #811860 $IPTABLES -N Cid3DD4BBC7.0 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid3DD4BBC7.0 for i_br0 in $i_br0_list do test -n "$i_br0" && $IPTABLES -A Cid3DD4BBC7.0 -d $i_br0 -j ACCEPT done for i_eth2 in $i_eth2_list do test -n "$i_eth2" && $IPTABLES -A Cid3DD4BBC7.0 -d $i_eth2 -j ACCEPT done $IPTABLES -A Cid3DD4BBC7.0 -d 10.1.1.1 -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # for i_br0 in $i_br0_list do test -n "$i_br0" && $IPTABLES -A FORWARD -d $i_br0 -m state --state NEW -j ACCEPT done for i_eth2 in $i_eth2_list do test -n "$i_eth2" && $IPTABLES -A FORWARD -d $i_eth2 -m state --state NEW -j ACCEPT done $IPTABLES -A FORWARD -d 10.1.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -A FORWARD -d 10.1.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 10.1.1.1 -m state --state NEW -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -N RULE_23 $IPTABLES -A FORWARD -j RULE_23 $IPTABLES -A RULE_23 -j LOG --log-level debug $IPTABLES -A RULE_23 -j DROP # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N RULE_24 $IPTABLES -A OUTPUT -j RULE_24 $IPTABLES -A INPUT -j RULE_24 $IPTABLES -A FORWARD -j RULE_24 $IPTABLES -A RULE_24 -j LOG --log-level debug $IPTABLES -A RULE_24 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:09 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall40-1.fw.orig0000755000175000017500000003130511733011756022162 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:51 2012 PDT by vadim # # files: * firewall40-1.fw /etc/firewall40-1.fw # # Compiled for iptables 1.4.0 # # more complex and realistic combination of Tag and Route rules that are in the separate Policy rule set # firewall40-1:Policy_1:3: error: Option Route is deprecated. You can use Custom Action to generate iptables command using '-j ROUTE' target if it is supported by your firewall OS # firewall40-1:Policy_1:4: error: Option Route is deprecated. You can use Custom Action to generate iptables command using '-j ROUTE' target if it is supported by your firewall OS FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 lo eth2 eth1" for i in eth0 lo eth2 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.0.100.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # Translate source address # for outgoing connections $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 # ================ Table 'mangle', rule set Policy_1 # # Rule Policy_1 0 (eth0) # echo "Rule Policy_1 0 (eth0)" # $IPTABLES -N Policy_1 -t mangle $IPTABLES -t mangle -A Policy_1 -i eth0 -m state --state NEW -j MARK --set-mark 1 $IPTABLES -t mangle -A Policy_1 -i eth0 -m state --state NEW -j CONNMARK --save-mark # # Rule Policy_1 1 (eth2) # echo "Rule Policy_1 1 (eth2)" # $IPTABLES -t mangle -A Policy_1 -i eth2 -m state --state NEW -j MARK --set-mark 2 $IPTABLES -t mangle -A Policy_1 -i eth2 -m state --state NEW -j CONNMARK --save-mark # # Rule Policy_1 6 (global) # echo "Rule Policy_1 6 (global)" # $IPTABLES -N Cid55038X29165.0 -t mangle $IPTABLES -t mangle -A Policy_1 -s 192.168.1.0/24 -m state --state NEW -j Cid55038X29165.0 $IPTABLES -t mangle -A Cid55038X29165.0 -d 22.22.22.0/24 -j MARK --set-mark 8 $IPTABLES -t mangle -A Cid55038X29165.0 -d 33.33.33.0/24 -j MARK --set-mark 8 # ================ Table 'filter', rule set Policy_1 # # Rule Policy_1 2 (global) # echo "Rule Policy_1 2 (global)" # # This permits access from internal net # to the Internet and DMZ $IPTABLES -N Policy_1 $IPTABLES -A Policy_1 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule Policy_1 5 (global) # echo "Rule Policy_1 5 (global)" # $IPTABLES -N Policy_1_5 $IPTABLES -A Policy_1 -j Policy_1_5 $IPTABLES -A Policy_1_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -A Policy_1_5 -j DROP # # Rule Policy_1 6 (global) # echo "Rule Policy_1 6 (global)" # $IPTABLES -N Cid55038X29165.0 $IPTABLES -A Policy_1 -s 192.168.1.0/24 -m state --state NEW -j Cid55038X29165.0 $IPTABLES -A Cid55038X29165.0 -d 22.22.22.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " $IPTABLES -A Cid55038X29165.0 -d 33.33.33.0/24 -j LOG --log-level info --log-prefix "RULE 6 -- CONTINUE " # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # any rule here to make top Policy ruleset non-empty $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A RULE_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:51 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/run-clusters.all0000755000175000017500000000037311733011756021717 0ustar sylvestresylvestre#!/bin/sh XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_ipt -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/ipt/firewall31.fw.orig0000755000175000017500000003224011733011756022023 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:37 2012 PDT by vadim # # files: * firewall31.fw /etc/fw/firewall31.fw # # Compiled for iptables (any version) # # used to test time matching rules FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 33.33.33.33/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" getaddr ppp0 i_ppp0 getaddr6 ppp0 i_ppp0_v6 getnet ppp0 i_ppp0_network getnet6 ppp0 i_ppp0_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_0 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_0 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m time --timestart 00:00 --timestop 23:59 --days Sat -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -m time --timestart 18:00 --timestop 23:59 -j RULE_1 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -m time --timestart 18:00 --timestop 23:59 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -m time --timestart 18:00 --timestop 23:59 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- ACCEPT " $IPTABLES -A RULE_1 -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RULE_3 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RULE_3 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- ACCEPT " $IPTABLES -A RULE_3 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid4299E23B.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j Cid4299E23B.0 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j Cid4299E23B.0 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j Cid4299E23B.0 $IPTABLES -A Cid4299E23B.0 -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j RETURN $IPTABLES -N RULE_4_3 $IPTABLES -A Cid4299E23B.0 -j RULE_4_3 $IPTABLES -A RULE_4_3 -j LOG --log-level info --log-prefix "RULE 4 -- ACCEPT " $IPTABLES -A RULE_4_3 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid4299E247.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j Cid4299E247.0 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j Cid4299E247.0 $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j Cid4299E247.0 $IPTABLES -A Cid4299E247.0 -m time --timestart 00:00 --timestop 23:59 --days Sat -j RETURN $IPTABLES -A Cid4299E247.0 -m time --timestart 00:00 --timestop 23:59 --days Sun -j RETURN $IPTABLES -N RULE_5_3 $IPTABLES -A Cid4299E247.0 -j RULE_5_3 $IPTABLES -A RULE_5_3 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5_3 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -j RULE_6 $IPTABLES -A INPUT -j RULE_6 $IPTABLES -A FORWARD -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:37 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-4-1.fw.orig0000755000175000017500000003705711733011756023053 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:24 2012 PDT by vadim # # files: * firewall-ipv6-4-1.fw /etc/firewall-ipv6-4-1.fw # # Compiled for iptables 1.4.0 # # Policy is configured as dual address family. Using iptables-restore. Firewall is NOT part of any # firewall-ipv6-4-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall-ipv6-4-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-4-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo ":In_RULE_0 - [0:0]" echo "-A INPUT -m state --state NEW -j In_RULE_0 " echo "-A In_RULE_0 -j ULOG --ulog-nlgroup 1 --ulog-prefix \"RULE 0 -- ACCEPT \" --ulog-qthreshold 1 " echo "-A In_RULE_0 -j ACCEPT " # # Rule 1 (global) echo "-A OUTPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT " # # Rule 2 (global) # firewall-ipv6-4-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it echo "-A FORWARD -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT " # # Rule 3 (global) echo "-A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT " # # Rule 4 (global) # INPUT, OUTPUT, FORWARD # firewall-ipv6-4-1:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it echo "-A FORWARD -s 1.1.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 5 (global) # INPUT, OUTPUT, FORWARD echo "-A FORWARD -d 1.1.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 6 (global) # for bug 2047082 # echo "-A OUTPUT -m state --state NEW -j ACCEPT " # # Rule 7 (global) echo "-A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT " echo "-A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT " # # Rule 8 (global) echo ":RULE_8 - [0:0]" echo "-A FORWARD -d 72.55.148.116 -j RULE_8 " echo "-A FORWARD -d 207.251.84.150 -j RULE_8 " echo "-A RULE_8 -j ULOG --ulog-nlgroup 1 --ulog-prefix \"RULE 8 -- DENY \" --ulog-qthreshold 1 " echo "-A RULE_8 -j DROP " # # Rule 9 (global) # ipv4 address range for bug 2820152 echo "-A FORWARD -m iprange --dst-range 192.168.1.1-192.168.1.100 -m state --state NEW -j ACCEPT " # # Rule 10 (global) # ipv4 address range for bug 2820152 echo "-A INPUT -d 255.255.255.255 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":RULE_11 - [0:0]" echo "-A FORWARD -j RULE_11 " echo "-A RULE_11 -j ULOG --ulog-nlgroup 1 --ulog-prefix \"RULE 11 -- DENY \" --ulog-qthreshold 1 " echo "-A RULE_11 -j DROP " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s 1.1.1.0/24 -j MASQUERADE " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo ":In_RULE_0 - [0:0]" echo "-A INPUT -m state --state NEW -j In_RULE_0 " echo "-A In_RULE_0 -j LOG --log-level info --log-prefix \"RULE 0 -- ACCEPT \"" echo "-A In_RULE_0 -j ACCEPT " # # Rule 6 (global) # for bug 2047082 # echo "-A OUTPUT -m state --state NEW -j ACCEPT " # # Rule 7 (global) echo "-A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT " echo "-A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":RULE_11 - [0:0]" echo "-A FORWARD -j RULE_11 " echo "-A RULE_11 -j LOG --log-level info --log-prefix \"RULE 11 -- DENY \"" echo "-A RULE_11 -j DROP " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s fe80::/64 -j MASQUERADE " # echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:24 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall92.fw.orig0000755000175000017500000002672111733011756022041 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:16 2012 PDT by vadim # # files: * firewall92.fw /etc/fw/firewall92.fw # # Compiled for iptables (any version) # # rules for the TOR transparent proxy per # https://trac.torproject.org/projects/tor/wiki/TheOnionRouter/TransparentProxy # See ticket 1685 # firewall92:NAT:2: error: NAT rule can not change service types: CustomService to TCPService # firewall92:NAT:2: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A OUTPUT -p udp -m udp -m owner --uid-owner anonymous -j REDIRECT --to-ports 53 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m owner --uid-owner anonymous -j REDIRECT --to-ports 9040 # ================ Table 'filter', rule set Policy_1 # # Rule Policy_1 0 (global) # echo "Rule Policy_1 0 (global)" # $IPTABLES -N Policy_1 $IPTABLES -N Cid1009688X9517.0 $IPTABLES -A Policy_1 -o + -p tcp -m tcp --dport 9040 -j Cid1009688X9517.0 $IPTABLES -A Policy_1 -o + -p udp -m udp --dport 53 -j Cid1009688X9517.0 $IPTABLES -N Out_Policy_1_0 $IPTABLES -A Cid1009688X9517.0 -s 192.0.2.1 -j Out_Policy_1_0 $IPTABLES -A Cid1009688X9517.0 -s 192.168.1.1 -j Out_Policy_1_0 $IPTABLES -A Out_Policy_1_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A Out_Policy_1_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -m owner --uid-owner anonymous -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -m owner --uid-owner anonymous -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # # matching module owner here # and tcp and udp ports in the branch $IPTABLES -A OUTPUT -m owner --uid-owner anonymous -j Policy_1 # # Rule 2 (global) # echo "Rule 2 (global)" # # this only matches module owner $IPTABLES -N Out_RULE_2 $IPTABLES -A OUTPUT -m owner --uid-owner anonymous -j Out_RULE_2 $IPTABLES -A Out_RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A Out_RULE_2 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:16 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall2-1.fw.orig0000755000175000017500000022104511733011756022102 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:21 2012 PDT by vadim # # files: * firewall2-1.fw /etc/fw/firewall2-1.fw # # Compiled for iptables lt_1.2.6 # # copy of firewall2 but old iptables version # firewall2-1:NAT:20: warning: Adding of virtual address for address range is not implemented (object ext_range) # firewall2-1:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it # firewall2-1:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '12 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '13 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '14 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '20 (global)' below it # firewall2-1:Policy:25: error: Rule '25 (global)' shadows rule '26 (global)' below it # firewall2-1:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-1:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-1:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-1:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall2-1:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-1:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.10/24 192.168.1.50/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 22.22.22.23/24 22.22.22.24/24 22.22.22.25/24 22.22.22.0/32 22.22.22.1/32 22.22.22.2/32 22.22.22.3/32 22.22.22.4/32 22.22.22.5/32 22.22.22.6/32 22.22.22.7/32 22.22.22.8/32 22.22.22.9/32 22.22.22.10/32 22.22.22.11/32 22.22.22.12/32 22.22.22.13/32 22.22.22.14/32 22.22.22.15/32 22.22.22.16/32 22.22.22.17/32 22.22.22.18/32 22.22.22.19/32 22.22.22.20/32 22.22.22.21/32 22.22.22.22/32 22.22.22.23/32 22.22.22.24/32 22.22.22.25/32 22.22.22.26/32 22.22.22.27/32 22.22.22.28/32 22.22.22.29/32 22.22.22.30/32 22.22.22.31/32 22.22.22.32/32 22.22.22.33/32 22.22.22.34/32 22.22.22.35/32 22.22.22.36/32 22.22.22.37/32 22.22.22.38/32 22.22.22.39/32 22.22.22.40/32 22.22.22.41/32 22.22.22.42/32 22.22.22.43/32 22.22.22.44/32 22.22.22.45/32 22.22.22.46/32 22.22.22.47/32 22.22.22.48/32 22.22.22.49/32 22.22.22.50/32 22.22.22.51/32 22.22.22.52/32 22.22.22.53/32 22.22.22.54/32 22.22.22.55/32 22.22.22.56/32 22.22.22.57/32 22.22.22.58/32 22.22.22.59/32 22.22.22.60/32 22.22.22.61/32 22.22.22.62/32 22.22.22.63/32 22.22.22.64/32 22.22.22.65/32 22.22.22.66/32 22.22.22.67/32 22.22.22.68/32 22.22.22.69/32 22.22.22.70/32 22.22.22.71/32 22.22.22.72/32 22.22.22.73/32 22.22.22.74/32 22.22.22.75/32 22.22.22.76/32 22.22.22.77/32 22.22.22.78/32 22.22.22.79/32 22.22.22.80/32 22.22.22.81/32 22.22.22.82/32 22.22.22.83/32 22.22.22.84/32 22.22.22.85/32 22.22.22.86/32 22.22.22.87/32 22.22.22.88/32 22.22.22.89/32 22.22.22.90/32 22.22.22.91/32 22.22.22.92/32 22.22.22.93/32 22.22.22.94/32 22.22.22.95/32 22.22.22.96/32 22.22.22.97/32 22.22.22.98/32 22.22.22.99/32 22.22.22.100/32 22.22.22.101/32 22.22.22.102/32 22.22.22.103/32 22.22.22.104/32 22.22.22.105/32 22.22.22.106/32 22.22.22.107/32 22.22.22.108/32 22.22.22.109/32 22.22.22.110/32 22.22.22.111/32 22.22.22.112/32 22.22.22.113/32 22.22.22.114/32 22.22.22.115/32 22.22.22.116/32 22.22.22.117/32 22.22.22.118/32 22.22.22.119/32 22.22.22.120/32 22.22.22.121/32 22.22.22.122/32 22.22.22.123/32 22.22.22.124/32 22.22.22.125/32 22.22.22.126/32 22.22.22.127/32 22.22.22.128/32 22.22.22.129/32 22.22.22.130/32 22.22.22.131/32 22.22.22.132/32 22.22.22.133/32 22.22.22.134/32 22.22.22.135/32 22.22.22.136/32 22.22.22.137/32 22.22.22.138/32 22.22.22.139/32 22.22.22.140/32 22.22.22.141/32 22.22.22.142/32 22.22.22.143/32 22.22.22.144/32 22.22.22.145/32 22.22.22.146/32 22.22.22.147/32 22.22.22.148/32 22.22.22.149/32 22.22.22.150/32 22.22.22.151/32 22.22.22.152/32 22.22.22.153/32 22.22.22.154/32 22.22.22.155/32 22.22.22.156/32 22.22.22.157/32 22.22.22.158/32 22.22.22.159/32 22.22.22.160/32 22.22.22.161/32 22.22.22.162/32 22.22.22.163/32 22.22.22.164/32 22.22.22.165/32 22.22.22.166/32 22.22.22.167/32 22.22.22.168/32 22.22.22.169/32 22.22.22.170/32 22.22.22.171/32 22.22.22.172/32 22.22.22.173/32 22.22.22.174/32 22.22.22.175/32 22.22.22.176/32 22.22.22.177/32 22.22.22.178/32 22.22.22.179/32 22.22.22.180/32 22.22.22.181/32 22.22.22.182/32 22.22.22.183/32 22.22.22.184/32 22.22.22.185/32 22.22.22.186/32 22.22.22.187/32 22.22.22.188/32 22.22.22.189/32 22.22.22.190/32 22.22.22.191/32 22.22.22.192/32 22.22.22.193/32 22.22.22.194/32 22.22.22.195/32 22.22.22.196/32 22.22.22.197/32 22.22.22.198/32 22.22.22.199/32 22.22.22.200/32 22.22.22.201/32 22.22.22.202/32 22.22.22.203/32 22.22.22.204/32 22.22.22.205/32 22.22.22.206/32 22.22.22.207/32 22.22.22.208/32 22.22.22.209/32 22.22.22.210/32 22.22.22.211/32 22.22.22.212/32 22.22.22.213/32 22.22.22.214/32 22.22.22.215/32 22.22.22.216/32 22.22.22.217/32 22.22.22.218/32 22.22.22.219/32 22.22.22.220/32 22.22.22.221/32 22.22.22.222/32 22.22.22.223/32 22.22.22.224/32 22.22.22.225/32 22.22.22.226/32 22.22.22.227/32 22.22.22.228/32 22.22.22.229/32 22.22.22.230/32 22.22.22.231/32 22.22.22.232/32 22.22.22.233/32 22.22.22.234/32 22.22.22.235/32 22.22.22.236/32 22.22.22.237/32 22.22.22.238/32 22.22.22.239/32 22.22.22.240/32 22.22.22.241/32 22.22.22.242/32 22.22.22.243/32 22.22.22.244/32 22.22.22.245/32 22.22.22.246/32 22.22.22.247/32 22.22.22.248/32 22.22.22.249/32 22.22.22.250/32 22.22.22.251/32 22.22.22.252/32 22.22.22.253/32 22.22.22.254/32" "" update_addresses_of_interface "eth3 22.22.23.23/24 22.22.25.50/24 22.22.23.24/24" "" update_addresses_of_interface "eth2 192.168.2.1/24 192.168.2.40/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.24 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.25 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -N Cid31547X1798.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid31547X1798.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid31547X1798.0 $IPTABLES -t nat -A Cid31547X1798.0 -s 22.22.22.22 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.0 -s 22.22.23.23 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.0 -s 22.22.25.50 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.0 -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.0 -s 192.168.2.40 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.10 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.11 -j ACCEPT $IPTABLES -t nat -N Cid31547X1798.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid31547X1798.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid31547X1798.1 $IPTABLES -t nat -A Cid31547X1798.1 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.1 -s 192.168.1.20 -j ACCEPT $IPTABLES -t nat -N Cid31547X1798.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.10 -j Cid31547X1798.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.11 -j Cid31547X1798.2 $IPTABLES -t nat -A Cid31547X1798.2 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid31547X1798.2 -s 192.168.1.20 -j ACCEPT # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -N Cid31565X1798.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.10 -j Cid31565X1798.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.20 -j Cid31565X1798.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.10 -j Cid31565X1798.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.20 -j Cid31565X1798.0 $IPTABLES -t nat -A Cid31565X1798.0 -d 192.168.2.10 -j RETURN $IPTABLES -t nat -A Cid31565X1798.0 -d 192.168.2.11 -j RETURN $IPTABLES -t nat -A Cid31565X1798.0 -j ACCEPT # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.23.23 -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.25.50 -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -s 200.200.200.200 -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.24 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.25 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.24 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.25 --destination-port 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 17 (NAT) # echo "Rule 17 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 # # Rule 18 (NAT) # echo "Rule 18 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.20 -j SNAT --to-source 22.22.23.24 # # Rule 19 (NAT) # echo "Rule 19 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 $IPTABLES -t nat -A OUTPUT -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 # # Rule 20 (NAT) # echo "Rule 20 (NAT)" # # firewall2-1:NAT:20: warning: Adding of virtual address for address range is not implemented (object ext_range) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.100-22.22.22.110 # # Rule 21 (NAT) # echo "Rule 21 (NAT)" # # NETMAP $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 22 (NAT) # echo "Rule 22 (NAT)" # # NETMAP $IPTABLES -t nat -A PREROUTING -d 22.22.22.0/24 -j NETMAP --to 192.168.1.0/24 # # Rule 23 (NAT) # echo "Rule 23 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 # # Rule 24 (NAT) # echo "Rule 24 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.10 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 25 (NAT) # echo "Rule 25 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 # # Rule 26 (NAT) # echo "Rule 26 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 443 -j REDIRECT --to-ports 3128 # # Rule 27 (NAT) # echo "Rule 27 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 # # Rule 28 (NAT) # echo "Rule 28 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 # # Rule 29 (NAT) # echo "Rule 29 (NAT)" # # transparent proxy rule $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -d ! 22.22.22.23 -j DNAT --to-destination 192.168.2.10 # # Rule 31 (NAT) # echo "Rule 31 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 # # Rule 32 (NAT) # echo "Rule 32 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 # # Rule 33 (NAT) # echo "Rule 33 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 34 (NAT) # echo "Rule 34 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s ! 192.168.1.10 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 35 (NAT) # echo "Rule 35 (NAT)" # $IPTABLES -t nat -N Cid31935X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid31935X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid31935X1798.0 $IPTABLES -t nat -A Cid31935X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid31935X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid31935X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # # Rule 36 (NAT) # echo "Rule 36 (NAT)" # $IPTABLES -t nat -N Cid31949X1798.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -j Cid31949X1798.1 $IPTABLES -t nat -A Cid31949X1798.1 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid31949X1798.1 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -N Cid31949X1798.0 $IPTABLES -t nat -A Cid31949X1798.1 -j Cid31949X1798.0 $IPTABLES -t nat -A Cid31949X1798.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -t nat -A Cid31949X1798.0 -j SNAT --to-source 192.168.1.1 # # Rule 37 (NAT) # echo "Rule 37 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 38 (NAT) # echo "Rule 38 (NAT)" # # this is the "exception" rule # used in support req. originally $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 39 (NAT) # echo "Rule 39 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 40 (NAT) # echo "Rule 40 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 41 (NAT) # echo "Rule 41 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid32019X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid32019X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid32019X1798.0 $IPTABLES -t nat -A Cid32019X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32019X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32019X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 42 (NAT) # echo "Rule 42 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid32033X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid32033X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid32033X1798.0 $IPTABLES -t nat -A Cid32033X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32033X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32033X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 43 (NAT) # echo "Rule 43 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid32047X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid32047X1798.0 $IPTABLES -t nat -A Cid32047X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32047X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32047X1798.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 44 (NAT) # echo "Rule 44 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 45 (NAT) # echo "Rule 45 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid32075X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid32075X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid32075X1798.0 $IPTABLES -t nat -A Cid32075X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32075X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32075X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # # Anti-spoofing rule # firewall2-1:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 0 -- DENY " --ulog-qthreshold 1 $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid31178X1798.0 $IPTABLES -A OUTPUT -o eth1 -j Cid31178X1798.0 $IPTABLES -A Cid31178X1798.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid31178X1798.0 -s 22.22.23.23 -j RETURN $IPTABLES -A Cid31178X1798.0 -s 22.22.25.50 -j RETURN $IPTABLES -A Cid31178X1798.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid31178X1798.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid31178X1798.0 -s 192.168.2.40 -j RETURN $IPTABLES -N Out_RULE_1_3 $IPTABLES -A Cid31178X1798.0 -j Out_RULE_1_3 $IPTABLES -A Out_RULE_1_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 1 -- DENY " --ulog-qthreshold 1 $IPTABLES -A Out_RULE_1_3 -j DROP $IPTABLES -N Cid31178X1798.1 $IPTABLES -A FORWARD -o eth1 -j Cid31178X1798.1 $IPTABLES -A Cid31178X1798.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid31178X1798.1 -j Out_RULE_1_3 # # Rule 2 (fw2i1,3) # echo "Rule 2 (fw2i1,3)" # # testing group in "interface" # this rule should be identical to rule 3 $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_2 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_2 $IPTABLES -A In_RULE_2 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 2 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth1,eth3) # echo "Rule 3 (eth1,eth3)" # $IPTABLES -N In_RULE_3 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_3 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --destination-port 68,67 -j In_RULE_3 $IPTABLES -A In_RULE_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 3 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_3 -j DROP # # Rule 4 (eth1,eth3) # echo "Rule 4 (eth1,eth3)" # # testing choice of chains in case when several # interfaces are used and rule matches 'any' or # broadcast # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-1:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT # # Rule 5 (eth1,eth3) # echo "Rule 5 (eth1,eth3)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT # # Rule 6 (eth1,eth3) # echo "Rule 6 (eth1,eth3)" # $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --destination-port 68,67 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid31255X1798.0 $IPTABLES -A OUTPUT -j Cid31255X1798.0 $IPTABLES -A INPUT -j Cid31255X1798.0 $IPTABLES -A FORWARD -j Cid31255X1798.0 $IPTABLES -A Cid31255X1798.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid31255X1798.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 7 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_7_3 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # # block fragments $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -p all -f -j RULE_8 $IPTABLES -A INPUT -p all -f -j RULE_8 $IPTABLES -A FORWARD -p all -f -j RULE_8 $IPTABLES -A RULE_8 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 8 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # # sends TCP RST and makes custom record # in the log $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A RULE_9 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "IDENT" --ulog-qthreshold 1 $IPTABLES -A RULE_9 -p tcp -m tcp -j REJECT --reject-with tcp-reset # # Rule 10 (global) # echo "Rule 10 (global)" # # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '12 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '13 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '14 (global)' below it # firewall2-1:Policy:10: error: Rule '10 (global)' shadows rule '20 (global)' below it # firewall2-1:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A INPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A RULE_10 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 10 - REJECT **" --ulog-qthreshold 1 $IPTABLES -A RULE_10 -j REJECT --reject-with icmp-net-unreachable # # Rule 11 (global) # echo "Rule 11 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid112778X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid112778X70161.0 $IPTABLES -A Cid112778X70161.0 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid112778X70161.0 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid112778X70161.0 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid112778X70161.0 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid112778X70161.0 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid112778X70161.0 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid112778X70161.0 -d 192.168.1.100 -j ACCEPT $IPTABLES -N Cid112778X70161.1 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid112778X70161.1 $IPTABLES -A Cid112778X70161.1 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid112778X70161.1 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid112778X70161.1 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid112778X70161.1 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid112778X70161.1 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid112778X70161.1 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid112778X70161.1 -d 192.168.1.100 -j ACCEPT $IPTABLES -N Cid112778X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid112778X70161.2 $IPTABLES -A Cid112778X70161.2 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid112778X70161.2 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid112778X70161.2 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid112778X70161.2 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid112778X70161.2 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid112778X70161.2 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid112778X70161.2 -d 192.168.1.100 -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94383X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94383X70161.0 $IPTABLES -A Cid94383X70161.0 -s 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid94383X70161.0 -s 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid94383X70161.0 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid94383X70161.0 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid94383X70161.0 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid94383X70161.0 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid94383X70161.0 -s 192.168.1.100 -j ACCEPT $IPTABLES -N Cid94383X70161.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94383X70161.1 $IPTABLES -A Cid94383X70161.1 -s 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid94383X70161.1 -s 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid94383X70161.1 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid94383X70161.1 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid94383X70161.1 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid94383X70161.1 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid94383X70161.1 -s 192.168.1.100 -j ACCEPT $IPTABLES -N Cid94383X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94383X70161.2 $IPTABLES -A Cid94383X70161.2 -s 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid94383X70161.2 -s 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid94383X70161.2 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid94383X70161.2 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid94383X70161.2 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid94383X70161.2 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid94383X70161.2 -s 192.168.1.100 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid131133X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid131133X70161.0 $IPTABLES -N Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.10/31 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.12/30 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.16/28 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.32/27 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.64/27 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.96/30 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.0 -s 222.222.222.100 -j Cid131133X70161.1 $IPTABLES -A Cid131133X70161.1 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid131133X70161.1 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid131133X70161.1 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid131133X70161.1 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid131133X70161.1 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid131133X70161.1 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid131133X70161.1 -d 192.168.1.100 -j ACCEPT $IPTABLES -N Cid131133X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid131133X70161.2 $IPTABLES -N Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.10/31 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.12/30 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.16/28 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.32/27 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.64/27 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.96/30 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.2 -s 222.222.222.100 -j Cid131133X70161.3 $IPTABLES -A Cid131133X70161.3 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid131133X70161.3 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid131133X70161.3 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid131133X70161.3 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid131133X70161.3 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid131133X70161.3 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid131133X70161.3 -d 192.168.1.100 -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid131116X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid131116X70161.0 $IPTABLES -N Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.10/31 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.12/30 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.16/28 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.32/27 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.64/27 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.96/30 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.0 -s 192.168.1.100 -j Cid131116X70161.1 $IPTABLES -A Cid131116X70161.1 -d 222.222.222.10/31 -j ACCEPT $IPTABLES -A Cid131116X70161.1 -d 222.222.222.12/30 -j ACCEPT $IPTABLES -A Cid131116X70161.1 -d 222.222.222.16/28 -j ACCEPT $IPTABLES -A Cid131116X70161.1 -d 222.222.222.32/27 -j ACCEPT $IPTABLES -A Cid131116X70161.1 -d 222.222.222.64/27 -j ACCEPT $IPTABLES -A Cid131116X70161.1 -d 222.222.222.96/30 -j ACCEPT $IPTABLES -A Cid131116X70161.1 -d 222.222.222.100 -j ACCEPT $IPTABLES -N Cid131116X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid131116X70161.2 $IPTABLES -N Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.10/31 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.12/30 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.16/28 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.32/27 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.64/27 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.96/30 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.2 -s 192.168.1.100 -j Cid131116X70161.3 $IPTABLES -A Cid131116X70161.3 -d 222.222.222.10/31 -j ACCEPT $IPTABLES -A Cid131116X70161.3 -d 222.222.222.12/30 -j ACCEPT $IPTABLES -A Cid131116X70161.3 -d 222.222.222.16/28 -j ACCEPT $IPTABLES -A Cid131116X70161.3 -d 222.222.222.32/27 -j ACCEPT $IPTABLES -A Cid131116X70161.3 -d 222.222.222.64/27 -j ACCEPT $IPTABLES -A Cid131116X70161.3 -d 222.222.222.96/30 -j ACCEPT $IPTABLES -A Cid131116X70161.3 -d 222.222.222.100 -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94366X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94366X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94366X70161.0 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94366X70161.0 $IPTABLES -A Cid94366X70161.0 -d 192.168.1.10/31 -j RETURN $IPTABLES -A Cid94366X70161.0 -d 192.168.1.12/30 -j RETURN $IPTABLES -A Cid94366X70161.0 -d 192.168.1.16/28 -j RETURN $IPTABLES -A Cid94366X70161.0 -d 192.168.1.32/27 -j RETURN $IPTABLES -A Cid94366X70161.0 -d 192.168.1.64/27 -j RETURN $IPTABLES -A Cid94366X70161.0 -d 192.168.1.96/30 -j RETURN $IPTABLES -A Cid94366X70161.0 -d 192.168.1.100 -j RETURN $IPTABLES -A Cid94366X70161.0 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94349X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94349X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94349X70161.0 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94349X70161.0 $IPTABLES -A Cid94349X70161.0 -s 192.168.1.10/31 -j RETURN $IPTABLES -A Cid94349X70161.0 -s 192.168.1.12/30 -j RETURN $IPTABLES -A Cid94349X70161.0 -s 192.168.1.16/28 -j RETURN $IPTABLES -A Cid94349X70161.0 -s 192.168.1.32/27 -j RETURN $IPTABLES -A Cid94349X70161.0 -s 192.168.1.64/27 -j RETURN $IPTABLES -A Cid94349X70161.0 -s 192.168.1.96/30 -j RETURN $IPTABLES -A Cid94349X70161.0 -s 192.168.1.100 -j RETURN $IPTABLES -A Cid94349X70161.0 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94331X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94331X70161.0 $IPTABLES -A Cid94331X70161.0 -d 192.168.1.0 -j RETURN $IPTABLES -A Cid94331X70161.0 -j ACCEPT $IPTABLES -N Cid94331X70161.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94331X70161.1 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94331X70161.1 $IPTABLES -A Cid94331X70161.1 -d 192.168.1.10/31 -j RETURN $IPTABLES -A Cid94331X70161.1 -d 192.168.1.12/30 -j RETURN $IPTABLES -A Cid94331X70161.1 -d 192.168.1.16/28 -j RETURN $IPTABLES -A Cid94331X70161.1 -d 192.168.1.32/27 -j RETURN $IPTABLES -A Cid94331X70161.1 -d 192.168.1.64/27 -j RETURN $IPTABLES -A Cid94331X70161.1 -d 192.168.1.96/30 -j RETURN $IPTABLES -A Cid94331X70161.1 -d 192.168.1.100 -j RETURN $IPTABLES -A Cid94331X70161.1 -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94313X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94313X70161.0 $IPTABLES -A Cid94313X70161.0 -s 192.168.1.0 -j RETURN $IPTABLES -A Cid94313X70161.0 -j ACCEPT $IPTABLES -N Cid94313X70161.1 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94313X70161.1 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94313X70161.1 $IPTABLES -A Cid94313X70161.1 -s 192.168.1.10/31 -j RETURN $IPTABLES -A Cid94313X70161.1 -s 192.168.1.12/30 -j RETURN $IPTABLES -A Cid94313X70161.1 -s 192.168.1.16/28 -j RETURN $IPTABLES -A Cid94313X70161.1 -s 192.168.1.32/27 -j RETURN $IPTABLES -A Cid94313X70161.1 -s 192.168.1.64/27 -j RETURN $IPTABLES -A Cid94313X70161.1 -s 192.168.1.96/30 -j RETURN $IPTABLES -A Cid94313X70161.1 -s 192.168.1.100 -j RETURN $IPTABLES -A Cid94313X70161.1 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using module iprange if # iptables version is >= 1.2.11 # also test for bug #2526173 $IPTABLES -N RULE_19 $IPTABLES -A INPUT -s 0.0.0.0 -j RULE_19 $IPTABLES -A OUTPUT -s 0.0.0.0 -j RULE_19 $IPTABLES -A RULE_19 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 19 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_19 -j DROP # # Rule 20 (global) # echo "Rule 20 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A INPUT -p udp -m udp -s 192.168.1.1 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -N Cid80837X35957.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid80837X35957.0 $IPTABLES -A Cid80837X35957.0 -s 192.168.1.2/31 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.4/30 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.8/29 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid80837X35957.0 -s 192.168.1.100 -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -s 192.168.1.1 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -N Cid80837X35957.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid80837X35957.1 $IPTABLES -A Cid80837X35957.1 -s 192.168.1.2/31 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.4/30 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.8/29 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid80837X35957.1 -s 192.168.1.100 -j ACCEPT $IPTABLES -N Cid80837X35957.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid80837X35957.2 $IPTABLES -A Cid80837X35957.2 -s 192.168.1.2/31 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.4/30 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.8/29 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid80837X35957.2 -s 192.168.1.100 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N Cid31303X1798.0 $IPTABLES -A INPUT -p icmp -s 192.168.2.0/24 -m state --state NEW -j Cid31303X1798.0 $IPTABLES -N RULE_21 $IPTABLES -A Cid31303X1798.0 -d 192.168.2.1 -j RULE_21 $IPTABLES -A Cid31303X1798.0 -d 192.168.2.40 -j RULE_21 $IPTABLES -A RULE_21 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 21 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_21 -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N Cid31315X1798.0 $IPTABLES -A FORWARD -d 211.11.11.11 -m state --state NEW -j Cid31315X1798.0 $IPTABLES -A Cid31315X1798.0 -s 192.168.1.10 -j ACCEPT $IPTABLES -A Cid31315X1798.0 -s 192.168.1.20 -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -N Cid31328X1798.0 $IPTABLES -A FORWARD -s 211.11.11.11 -m state --state NEW -j Cid31328X1798.0 $IPTABLES -A Cid31328X1798.0 -d 192.168.1.10 -j ACCEPT $IPTABLES -A Cid31328X1798.0 -d 192.168.1.20 -j ACCEPT # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N Cid31341X1798.0 $IPTABLES -A OUTPUT -p tcp -m tcp -j Cid31341X1798.0 $IPTABLES -A INPUT -p tcp -m tcp -j Cid31341X1798.0 $IPTABLES -A FORWARD -p tcp -m tcp -j Cid31341X1798.0 $IPTABLES -A Cid31341X1798.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid31341X1798.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid31341X1798.0 -p tcp -m tcp -j REJECT --reject-with tcp-reset $IPTABLES -N Cid31341X1798.1 $IPTABLES -A OUTPUT -j Cid31341X1798.1 $IPTABLES -A INPUT -j Cid31341X1798.1 $IPTABLES -A FORWARD -j Cid31341X1798.1 $IPTABLES -A Cid31341X1798.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid31341X1798.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid31341X1798.1 -j REJECT --reject-with icmp-net-unreachable # # Rule 25 (global) # echo "Rule 25 (global)" # # firewall2-1:Policy:25: error: Rule '25 (global)' shadows rule '26 (global)' below it $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.2.0/24 -m state --state NEW -j ACCEPT # # Rule 26 (global) # echo "Rule 26 (global)" # $IPTABLES -N RULE_26 $IPTABLES -A INPUT -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A RULE_26 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 26 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_26 -j DROP # # Rule 27 (global) # echo "Rule 27 (global)" # # host-fw2 has the same address as # one of the firewall's interfaces $IPTABLES -N RULE_27 $IPTABLES -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_27 $IPTABLES -A INPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_27 $IPTABLES -A RULE_27 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 27 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_27 -j ACCEPT # # Rule 28 (global) # echo "Rule 28 (global)" # $IPTABLES -N Cid31391X1798.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid31391X1798.0 $IPTABLES -N RULE_28 $IPTABLES -A Cid31391X1798.0 -d 22.22.22.22 -j RULE_28 $IPTABLES -A Cid31391X1798.0 -d 22.22.23.23 -j RULE_28 $IPTABLES -A Cid31391X1798.0 -d 22.22.25.50 -j RULE_28 $IPTABLES -A Cid31391X1798.0 -d 192.168.1.1 -j RULE_28 $IPTABLES -A Cid31391X1798.0 -d 192.168.2.1 -j RULE_28 $IPTABLES -A Cid31391X1798.0 -d 192.168.2.40 -j RULE_28 $IPTABLES -N Cid31391X1798.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid31391X1798.1 $IPTABLES -A Cid31391X1798.1 -d 22.22.22.22 -j RULE_28 $IPTABLES -A Cid31391X1798.1 -d 22.22.23.23 -j RULE_28 $IPTABLES -A Cid31391X1798.1 -d 22.22.25.50 -j RULE_28 $IPTABLES -A Cid31391X1798.1 -d 192.168.1.1 -j RULE_28 $IPTABLES -A Cid31391X1798.1 -d 192.168.2.1 -j RULE_28 $IPTABLES -A Cid31391X1798.1 -d 192.168.2.40 -j RULE_28 $IPTABLES -A RULE_28 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 28 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_28 -j ACCEPT # # Rule 29 (global) # echo "Rule 29 (global)" # # 'catch all' rule $IPTABLES -N RULE_29 $IPTABLES -A OUTPUT -j RULE_29 $IPTABLES -A INPUT -j RULE_29 $IPTABLES -A FORWARD -j RULE_29 $IPTABLES -A RULE_29 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 29 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_29 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:21 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall81.fw.orig0000755000175000017500000002666011733011756022041 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:11 2012 PDT by vadim # # files: * firewall81.fw /etc/fw/firewall81.fw # # Compiled for iptables (any version) # # This firewall has no "top" rule set objects. # firewall81::: warning: Missing top level NAT ruleset # firewall81::: warning: Missing top level Policy ruleset # firewall81:NAT_2:0: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' # firewall81:NAT_2:0: warning: NAT branching rule does not have information about targets used in the branch ruleset to choose proper chain in the nat table. Will split the rule and place it in both PREROUTNING and POSTROUTING # firewall81:NAT_2:1: warning: NAT branching rule does not have information about targets used in the branch ruleset to choose proper chain in the nat table. Will split the rule and place it in both PREROUTNING and POSTROUTING # firewall81:Policy:: warning: Log prefix has been truncated to 29 characters # firewall81:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'nat', rule set NAT_2 # # Rule NAT_2 0 (NAT) # echo "Rule NAT_2 0 (NAT)" # # Branch rule with actual translation. # Translation is ignored and warning should be issued # firewall81:NAT_2:0: warning: NAT branching rule does not have information about targets used in the branch ruleset to choose proper chain in the nat table. Will split the rule and place it in both PREROUTNING and POSTROUTING # firewall81:NAT_2:0: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' $IPTABLES -t nat -N NAT_1 $IPTABLES -t nat -A POSTROUTING -d 192.0.2.1 -j NAT_1 $IPTABLES -t nat -A PREROUTING -d 192.0.2.1 -j NAT_1 # # Rule NAT_2 1 (NAT) # echo "Rule NAT_2 1 (NAT)" # # DNAT Rule # firewall81:NAT_2:1: warning: NAT branching rule does not have information about targets used in the branch ruleset to choose proper chain in the nat table. Will split the rule and place it in both PREROUTNING and POSTROUTING $IPTABLES -t nat -A POSTROUTING -j NAT_1 $IPTABLES -t nat -A PREROUTING -j NAT_1 # ================ Table 'nat', rule set NAT_1 # # Rule NAT_1 0 (NAT) # echo "Rule NAT_1 0 (NAT)" # # DNAT Rule $IPTABLES -t nat -N NAT_1_PREROUTING $IPTABLES -t nat -A NAT_1_PREROUTING -d 192.0.2.1 -j DNAT --to-destination 192.168.1.10 # # Rule NAT_1 1 (NAT) # echo "Rule NAT_1 1 (NAT)" # # SNAT rule $IPTABLES -t nat -N NAT_1_POSTROUTING $IPTABLES -t nat -A NAT_1_POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 # ================ Table 'nat', rule set NAT_1 # # Rule NAT_1 0 (NAT) # echo "Rule NAT_1 0 (NAT)" # # DNAT Rule $IPTABLES -t nat -A NAT_1_PREROUTING -d 192.0.2.1 -j DNAT --to-destination 192.168.1.10 # # Rule NAT_1 1 (NAT) # echo "Rule NAT_1 1 (NAT)" # # SNAT rule $IPTABLES -t nat -A NAT_1_POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N Policy $IPTABLES -N RULE_0 $IPTABLES -A Policy -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level debug --log-prefix "RULE 0 -- DENY on interface g" $IPTABLES -A RULE_0 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:11 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall23-1.fw.orig0000755000175000017500000004261611733011756022172 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:25 2012 PDT by vadim # # files: * firewall23-1.fw /etc/fw/firewall23-1.fw # # Compiled for iptables 1.3.0 # # This is BRIDGING FIREWALL # Testing module physdev FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "br0 192.168.1.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'mangle', rule set Policy # # Rule 13 (eth2) # echo "Rule 13 (eth2)" # $IPTABLES -t mangle -A POSTROUTING -m physdev --physdev-is-bridged --physdev-out eth2 -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -j CLASSIFY --set-class 1:12 # # Rule 14 (eth3) # echo "Rule 14 (eth3)" # $IPTABLES -t mangle -A POSTROUTING -m physdev --physdev-is-bridged --physdev-out eth3 -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -j CLASSIFY --set-class 2:12 # # Rule 15 (eth2) # echo "Rule 15 (eth2)" # $IPTABLES -t mangle -A POSTROUTING -m physdev --physdev-is-bridged --physdev-out eth2 -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -j CLASSIFY --set-class 1:12 # ================ Table 'filter', rule set Policy # # Rule 0 (eth2,eth3) # echo "Rule 0 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m physdev --physdev-in eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m physdev --physdev-in eth3 -m state --state NEW -j ACCEPT # # Rule 1 (eth2,eth3) # echo "Rule 1 (eth2,eth3)" # $IPTABLES -A INPUT -m physdev --physdev-in eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m physdev --physdev-in eth3 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -m state --state NEW -j ACCEPT # # Rule 2 (eth2,eth3) # echo "Rule 2 (eth2,eth3)" # $IPTABLES -N In_RULE_2 $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 192.168.1.10 -m state --state NEW -j In_RULE_2 $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 192.168.1.20 -m state --state NEW -j In_RULE_2 $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 192.168.1.10 -m state --state NEW -j In_RULE_2 $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 192.168.1.20 -m state --state NEW -j In_RULE_2 $IPTABLES -A In_RULE_2 -j LOG --log-level debug $IPTABLES -A In_RULE_2 -j ACCEPT # # Rule 3 (eth2,eth3) # echo "Rule 3 (eth2,eth3)" # # testing for bug 1593221 $IPTABLES -N Cid45546AAE30629.0 $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -s 192.168.1.0/24 -m state --state NEW -j Cid45546AAE30629.0 $IPTABLES -N In_RULE_3 $IPTABLES -A Cid45546AAE30629.0 -d 192.168.1.10 -j In_RULE_3 $IPTABLES -A Cid45546AAE30629.0 -d 192.168.1.20 -j In_RULE_3 $IPTABLES -N Cid45546AAE30629.1 $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -s 192.168.1.0/24 -m state --state NEW -j Cid45546AAE30629.1 $IPTABLES -A Cid45546AAE30629.1 -d 192.168.1.10 -j In_RULE_3 $IPTABLES -A Cid45546AAE30629.1 -d 192.168.1.20 -j In_RULE_3 $IPTABLES -A In_RULE_3 -j LOG --log-level debug $IPTABLES -A In_RULE_3 -j ACCEPT # # Rule 4 (eth2,eth3) # echo "Rule 4 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 192.168.1.255 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 192.168.1.255 -m state --state NEW -j ACCEPT # # Rule 5 (eth2,eth3) # echo "Rule 5 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 255.255.255.255 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 6 (eth2,eth3) # echo "Rule 6 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 224.0.1.141 -m state --state NEW -j ACCEPT # # Rule 7 (eth2,eth3) # echo "Rule 7 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 8 (eth2,eth3) # echo "Rule 8 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-is-bridged --physdev-out eth2 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m physdev --physdev-is-bridged --physdev-out eth3 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 9 (eth2,eth3) # echo "Rule 9 (eth2,eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -d ! 192.168.1.0/24 -j DROP $IPTABLES -A FORWARD -m physdev --physdev-in eth3 -d ! 192.168.1.0/24 -j DROP # # Rule 10 (eth2) # echo "Rule 10 (eth2)" # $IPTABLES -A FORWARD -m physdev --physdev-is-bridged --physdev-out eth2 -d 224.0.0.0/4 -m state --state NEW -j ACCEPT # # Rule 11 (eth2) # echo "Rule 11 (eth2)" # $IPTABLES -A FORWARD -m physdev --physdev-in eth2 -s 192.168.1.10 -d 224.0.0.0/4 -m state --state NEW -j ACCEPT # # Rule 12 (eth3) # echo "Rule 12 (eth3)" # $IPTABLES -A FORWARD -m physdev --physdev-is-bridged --physdev-out eth3 -s 192.168.1.10 -d 224.0.0.0/4 -m state --state NEW -j ACCEPT # # Rule 15 (eth2) # echo "Rule 15 (eth2)" # $IPTABLES -A FORWARD -m physdev --physdev-is-bridged --physdev-out eth2 -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -j LOG --log-level debug # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.10 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 192.168.1.10 --dport 68 -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -A OUTPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # $IPTABLES -A OUTPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N RULE_21 $IPTABLES -A OUTPUT -d 192.168.1.10 -j RULE_21 $IPTABLES -A FORWARD -d 192.168.1.10 -j RULE_21 $IPTABLES -A RULE_21 -j LOG --log-level debug $IPTABLES -A RULE_21 -j DROP # # Rule 22 (global) # echo "Rule 22 (global)" # # this rule should generate commands # in both INPUT and FORWARD chains # because this is a bridging firewall # see bug #811860 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m state --state NEW -j ACCEPT # # Rule 24 (global) # echo "Rule 24 (global)" # # interface of another firewall # (firewall11) # Why do we need to test for this? $IPTABLES -A OUTPUT -d 10.1.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 10.1.1.1 -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:25 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall21-1.fw.orig0000755000175000017500000003111711733011756022162 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:20 2012 PDT by vadim # # files: * firewall21-1.fw /etc/fw/firewall21-1.fw # # Compiled for iptables 1.4.3 # # two dynamic interfaces in the same policy or NAT rule # iptables v1.4.3 # firewall21-1:Policy:: warning: Log prefix has been truncated to 29 characters # firewall21-1:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.168.1.100/24" "" getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.10 done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A PREROUTING -d $i_eth1 -j DNAT --to-destination 192.168.1.10 done # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.10 --random --persistent done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A PREROUTING -d $i_eth1 -j DNAT --to-destination 192.168.1.10 --random --persistent done # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE --random # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 --persistent done # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 --random --persistent done # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth0 -s $i_eth0 -m state --state NEW -j ACCEPT done # # Rule 1 (global) # echo "Rule 1 (global)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A INPUT -s $i_eth0 -m state --state NEW -j ACCEPT done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A INPUT -s $i_eth1 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -s $i_eth0 -m state --state NEW -j ACCEPT done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A OUTPUT -s $i_eth1 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d $i_eth0 --dports 68,67 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A INPUT -p udp -m udp -m multiport -d $i_eth0 --dports 68,67 -m state --state NEW -j ACCEPT done # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -j RULE_3 $IPTABLES -A INPUT -j RULE_3 $IPTABLES -A FORWARD -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level debug --log-prefix "RULE 3 -- DENY on interface g" $IPTABLES -A RULE_3 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:20 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall4.fw.orig0000755000175000017500000005613311733011756021752 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:50 2012 PDT by vadim # # files: * firewall4.fw /etc/fw/firewall4.fw # # Compiled for iptables (any version) # # this object is used to test a configuration where firewall has dynamic address # firewall4::: error: Dynamic interface eth1 should not have an IP address object attached to it. This IP address object will be ignored. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth3 222.222.222.222/24 222.222.222.40/24 222.222.222.41/24" "" getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.10 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.10 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.10 -j SNAT --to-source 222.222.222.222 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 222.222.222.41 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 222.222.222.41 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d ! 192.168.2.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -d ! 192.168.2.0/24 -j SNAT --to-source 222.222.222.222 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A POSTROUTING -o eth1 -s $i_eth1 -j MASQUERADE done $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.1 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.2.1 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth1 -s 222.222.222.222 -j MASQUERADE # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $i_eth1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 done $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 22 -j DNAT --to-destination 192.168.1.10:22 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $i_eth1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 done # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # # Anti-spoofing rule $IPTABLES -N In_RULE_0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A INPUT -i eth1 -s $i_eth1 -j In_RULE_0 done $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 222.222.222.222 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A FORWARD -i eth1 -s $i_eth1 -j In_RULE_0 done $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 222.222.222.222 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid3B0C63EB.0 $IPTABLES -A OUTPUT -o eth1 -j Cid3B0C63EB.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3B0C63EB.0 -s $i_eth1 -j RETURN done $IPTABLES -A Cid3B0C63EB.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid3B0C63EB.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid3B0C63EB.0 -s 222.222.222.222 -j RETURN $IPTABLES -N Out_RULE_1_3 $IPTABLES -A Cid3B0C63EB.0 -j Out_RULE_1_3 $IPTABLES -A Out_RULE_1_3 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A Out_RULE_1_3 -j DROP $IPTABLES -N Cid3B0C63EB.1 $IPTABLES -A FORWARD -o eth1 -j Cid3B0C63EB.1 $IPTABLES -A Cid3B0C63EB.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid3B0C63EB.1 -j Out_RULE_1_3 # # Rule 2 (eth1) # echo "Rule 2 (eth1)" # $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -p icmp -m icmp -s ! 192.168.2.0/24 --icmp-type 8/0 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -p icmp -m icmp -s ! 192.168.2.0/24 --icmp-type 8/0 -j In_RULE_2 $IPTABLES -A In_RULE_2 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A In_RULE_2 -j DROP $IPTABLES -N Out_RULE_2 $IPTABLES -A OUTPUT -o eth1 -p icmp -m icmp -s ! 192.168.2.0/24 --icmp-type 8/0 -j Out_RULE_2 $IPTABLES -A FORWARD -o eth1 -p icmp -m icmp -s ! 192.168.2.0/24 --icmp-type 8/0 -j Out_RULE_2 $IPTABLES -A Out_RULE_2 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A Out_RULE_2 -j DROP # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # $IPTABLES -N Cid3E49FEF2.0 $IPTABLES -A INPUT -i eth1 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid3E49FEF2.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3E49FEF2.0 -d $i_eth1 -j ACCEPT done $IPTABLES -A Cid3E49FEF2.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E49FEF2.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -A Cid3E49FEF2.0 -d 222.222.222.222 -j ACCEPT # # Rule 4 (eth1) # echo "Rule 4 (eth1)" # $IPTABLES -N In_RULE_4 $IPTABLES -A INPUT -i eth1 -p icmp -m icmp --icmp-type 8/0 -j In_RULE_4 $IPTABLES -A FORWARD -i eth1 -p icmp -m icmp --icmp-type 8/0 -j In_RULE_4 $IPTABLES -A In_RULE_4 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A In_RULE_4 -j DROP $IPTABLES -N Out_RULE_4 $IPTABLES -A OUTPUT -o eth1 -p icmp -m icmp --icmp-type 8/0 -j Out_RULE_4 $IPTABLES -A FORWARD -o eth1 -p icmp -m icmp --icmp-type 8/0 -j Out_RULE_4 $IPTABLES -A Out_RULE_4 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A Out_RULE_4 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # # OUTPUT $IPTABLES -N Cid469EDB0514508.0 $IPTABLES -A OUTPUT -d 1.1.1.1 -j Cid469EDB0514508.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid469EDB0514508.0 -s $i_eth1 -j ACCEPT done $IPTABLES -A Cid469EDB0514508.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid469EDB0514508.0 -s 192.168.2.1 -j ACCEPT $IPTABLES -A Cid469EDB0514508.0 -s 222.222.222.222 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # INTPUT with "-i +" # the "-i +" option is redundant if chain is INPUT, # it should be removed by optimization $IPTABLES -N Cid469F02B014773.0 $IPTABLES -A INPUT -s 1.1.1.1 -j Cid469F02B014773.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid469F02B014773.0 -d $i_eth1 -j ACCEPT done $IPTABLES -A Cid469F02B014773.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid469F02B014773.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -A Cid469F02B014773.0 -d 222.222.222.222 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # # OUTPUT + FORWARD $IPTABLES -A OUTPUT -d 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -o + -d 1.1.1.1 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # # INPUT + FORWARD $IPTABLES -A INPUT -s 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -i + -s 1.1.1.1 -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # # OUTPUT + FORWARD $IPTABLES -A OUTPUT -d 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -d 1.1.1.1 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # # INPUT + FORWARD $IPTABLES -A INPUT -s 1.1.1.1 -j ACCEPT $IPTABLES -A FORWARD -s 1.1.1.1 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N Cid3B0C63B4.1 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid3B0C63B4.1 $IPTABLES -N Cid3B0C63B4.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3B0C63B4.1 -d $i_eth1 -j Cid3B0C63B4.0 done $IPTABLES -A Cid3B0C63B4.1 -d 192.168.1.1 -j Cid3B0C63B4.0 $IPTABLES -A Cid3B0C63B4.1 -d 192.168.2.1 -j Cid3B0C63B4.0 $IPTABLES -A Cid3B0C63B4.1 -d 222.222.222.222 -j Cid3B0C63B4.0 $IPTABLES -N Cid3B0C63B4.2 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid3B0C63B4.2 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3B0C63B4.2 -d $i_eth1 -j Cid3B0C63B4.0 done $IPTABLES -A Cid3B0C63B4.2 -d 192.168.1.1 -j Cid3B0C63B4.0 $IPTABLES -A Cid3B0C63B4.2 -d 192.168.2.1 -j Cid3B0C63B4.0 $IPTABLES -A Cid3B0C63B4.2 -d 222.222.222.222 -j Cid3B0C63B4.0 $IPTABLES -A Cid3B0C63B4.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid3B0C63B4.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_11_3 $IPTABLES -A Cid3B0C63B4.0 -j RULE_11_3 $IPTABLES -A RULE_11_3 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A RULE_11_3 -j DROP # # Rule 12 (global) # echo "Rule 12 (global)" # # testing negation in the policy rule $IPTABLES -N Cid3B0C63A9.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid3B0C63A9.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid3B0C63A9.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid3B0C63A9.0 $IPTABLES -A Cid3B0C63A9.0 -s 192.168.1.10 -j RETURN $IPTABLES -A Cid3B0C63A9.0 -s 192.168.1.20 -j RETURN $IPTABLES -N RULE_12_3 $IPTABLES -A Cid3B0C63A9.0 -j RULE_12_3 $IPTABLES -A RULE_12_3 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A RULE_12_3 -j DROP # # Rule 13 (global) # echo "Rule 13 (global)" # # testing negation in service field $IPTABLES -N Cid3B0C63BF.1 $IPTABLES -A OUTPUT -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j Cid3B0C63BF.1 $IPTABLES -N Cid3B0C63BF.0 $IPTABLES -A Cid3B0C63BF.1 -d 192.168.1.10 -j Cid3B0C63BF.0 $IPTABLES -A Cid3B0C63BF.1 -d 192.168.1.20 -j Cid3B0C63BF.0 $IPTABLES -N Cid3B0C63BF.2 $IPTABLES -A FORWARD -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j Cid3B0C63BF.2 $IPTABLES -A Cid3B0C63BF.2 -d 192.168.1.10 -j Cid3B0C63BF.0 $IPTABLES -A Cid3B0C63BF.2 -d 192.168.1.20 -j Cid3B0C63BF.0 $IPTABLES -A Cid3B0C63BF.0 -p tcp -m tcp -m multiport --dports 25,22 -j RETURN $IPTABLES -N RULE_13_3 $IPTABLES -A Cid3B0C63BF.0 -j RULE_13_3 $IPTABLES -A RULE_13_3 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A RULE_13_3 -j DROP # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -N RULE_14 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 25 -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j RULE_14 $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 25 -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j RULE_14 $IPTABLES -A RULE_14 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A RULE_14 -j DROP # # Rule 15 (global) # echo "Rule 15 (global)" # # should permit access to all # addresses that belong to # the firewall, but not to those # that are used in NAT rules # and are added as virtual # addresses $IPTABLES -N Cid3E4DD6AD.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 25 -m state --state NEW -j Cid3E4DD6AD.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3E4DD6AD.0 -d $i_eth1 -j ACCEPT done $IPTABLES -A Cid3E4DD6AD.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E4DD6AD.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -A Cid3E4DD6AD.0 -d 222.222.222.222 -j ACCEPT $IPTABLES -N Cid3E4DD6AD.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 25 -m state --state NEW -j Cid3E4DD6AD.1 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3E4DD6AD.1 -d $i_eth1 -j ACCEPT done $IPTABLES -A Cid3E4DD6AD.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3E4DD6AD.1 -d 192.168.2.1 -j ACCEPT $IPTABLES -A Cid3E4DD6AD.1 -d 222.222.222.222 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # 'masquerading' rule $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -N Cid3E20A8E1.0 $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j Cid3E20A8E1.0 for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A Cid3E20A8E1.0 -d $i_eth1 -j RETURN done $IPTABLES -A Cid3E20A8E1.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3E20A8E1.0 -d 192.168.2.1 -j RETURN $IPTABLES -A Cid3E20A8E1.0 -d 222.222.222.222 -j RETURN $IPTABLES -A Cid3E20A8E1.0 -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # 'catch all' rule $IPTABLES -N RULE_19 $IPTABLES -A OUTPUT -j RULE_19 $IPTABLES -A INPUT -j RULE_19 $IPTABLES -A FORWARD -j RULE_19 $IPTABLES -A RULE_19 -j ULOG --ulog-nlgroup 7 --ulog-cprange 64 --ulog-qthreshold 1 $IPTABLES -A RULE_19 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:50 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall12.fw.orig0000755000175000017500000003767011733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:09 2012 PDT by vadim # # files: * firewall12.fw /etc/fw/firewall12.fw # # Compiled for iptables (any version) # # This firewall does not do NAT for addresses, but translates port for a server # firewall12:NAT:16: error: NAT rule can not change service types: TCPService to UDPService # firewall12:NAT:16: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. # firewall12::: warning: Can not add virtual address for object fw1:eth0:ip # firewall12::: warning: Can not add virtual address for object fw1:eth1:ip # firewall12::: warning: Can not add virtual address for object fw1:eth0:ip # firewall12::: warning: Can not add virtual address for object fw1:eth1:ip # firewall12::: warning: Can not add virtual address for object fw1:eth0:ip # firewall12::: warning: Can not add virtual address for object fw1:eth1:ip # firewall12::: warning: Can not add virtual address for object fw1:eth0:ip # firewall12::: warning: Can not add virtual address for object fw1:eth1:ip # firewall12::: warning: Can not add virtual address for object fw1:eth0:ip # firewall12::: warning: Can not add virtual address for object fw1:eth1:ip # firewall12::: warning: Can not add virtual address for object fw1:eth0:ip # firewall12::: warning: Can not add virtual address for object fw1:eth1:ip FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 22.22.22.22/24 22.22.22.23/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination :8080 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.22 --dport 80 -j DNAT --to-destination :8080 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.22 --dport 80 -j DNAT --to-destination :8080 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j REDIRECT --to-ports 8080 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.22 --dport 80 -j REDIRECT --to-ports 8080 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j REDIRECT --to-ports 8080 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.22 --dport 80 -j REDIRECT --to-ports 8080 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 22.22.22.22:8080 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.22 --dport 80 -j DNAT --to-destination 22.22.22.22:8080 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # # port-only translation $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp --sport 6767 -j SNAT --to-source :67 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p udp -m udp --sport 6767 -j SNAT --to-source 22.22.23.22:67 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # # port-only translation $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # # SDNAT $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.0.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -d 192.168.1.10 --dport 22 -j SNAT --to-source 192.0.2.1 $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -d 192.168.1.10 --dport 22 -j SNAT --to-source 192.168.1.1 # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # # SDNAT with source port $IPTABLES -t nat -A PREROUTING -p udp -m udp --sport 123 -d 192.0.2.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p udp -m udp --sport 123 -d 192.168.1.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp --sport 123 -d 192.168.1.10 -j SNAT --to-source 192.0.2.1:5050 $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp --sport 123 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1:5050 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # # SDNAT with dest port $IPTABLES -t nat -A PREROUTING -p udp -m udp -s 192.168.1.0/24 --dport 53 -j DNAT --to-destination 192.168.1.10:1053 $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 -d 192.168.1.10 --dport 1053 -j SNAT --to-source 192.0.2.1 $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 -d 192.168.1.10 --dport 1053 -j SNAT --to-source 192.168.1.1 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # # SDNAT # translate src and dst addresses # and src and dst ports $IPTABLES -t nat -A PREROUTING -p udp -m udp -s 192.168.1.0/24 --sport 1024:65535 --dport 53 -j DNAT --to-destination 192.168.1.10:1053 $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 -d 192.168.1.10 --dport 1053 -j SNAT --to-source 192.0.2.1:32767-65535 $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 -d 192.168.1.10 --dport 1053 -j SNAT --to-source 192.168.1.1:32767-65535 # # Rule 15 (NAT) # echo "Rule 15 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -p udp -m udp -s 192.168.1.0/24 --dport 53 -j SNAT --to-source :5050 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 22.22.22.23 --dport 8080 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 22.22.22.23 --dport 8080 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -j RULE_1 $IPTABLES -A INPUT -j RULE_1 $IPTABLES -A FORWARD -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:09 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall41.fw.orig0000755000175000017500000003420611733011756022030 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:53 2012 PDT by vadim # # files: * firewall41.fw /etc/firewall41.fw # # Compiled for iptables (any version) # # testing rule shadowing with run-time objects, rules with such objects should be ignored # firewall41:Policy:5: error: File not found for Address Table: missing table (this_table_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:5: error: File not found for Address Table: missing table (this_table_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:6: error: DNSName object "does not resolve" (compile time) can not resolve dns name "does_not_resolve.local" (AF_INET): Host or network 'does_not_resolve.local' not found; last error: Unknown error Using dummy address in test mode # firewall41:Policy:5: error: Rule '5 (global)' shadows rule '6 (global)' below it # firewall41:Policy:6: error: DNSName object "does not resolve" (compile time) can not resolve dns name "does_not_resolve.local" (AF_INET): Host or network 'does_not_resolve.local' not found; last error: Unknown error Using dummy address in test mode # firewall41:Policy:5: error: Rule '5 (global)' shadows rule '6 (global)' below it # firewall41:Policy:5: error: File not found for Address Table: missing table (this_table_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:6: error: DNSName object "does not resolve" (compile time) can not resolve dns name "does_not_resolve.local" (AF_INET): Host or network 'does_not_resolve.local' not found; last error: Unknown error Using dummy address in test mode FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "atbl.1" "addr-table-1.tbl" check_file "block_these" "block-hosts.tbl" } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 1.1.1.1/24" "" update_addresses_of_interface "eth1 2.2.2.2/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -d www.heise.de -m state --state NEW -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- ACCEPT " $IPTABLES -A RULE_0 -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -m state --state NEW -j RULE_1 done $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- ACCEPT " $IPTABLES -A RULE_1 -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid44F707E428576.0 $IPTABLES -A INPUT -d 1.1.1.1 -m state --state NEW -j Cid44F707E428576.0 $IPTABLES -N RULE_2 $IPTABLES -A Cid44F707E428576.0 -s 1.1.1.1 -j RULE_2 $IPTABLES -A Cid44F707E428576.0 -s 2.2.2.2 -j RULE_2 $IPTABLES -A OUTPUT -d 1.1.1.1 -m state --state NEW -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- ACCEPT " $IPTABLES -A RULE_2 -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -j RULE_3 done grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A FORWARD -d $at_atbl_1 -j RULE_3 done $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -A RULE_3 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # # testing for bug #1086 # when two run-time objects are used in the rule, compiler adds blank command that blocks (permits) any to any $IPTABLES -N RULE_4 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -m state --state NEW -j RULE_4 done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -d $at_block_these -m state --state NEW -j RULE_4 done $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- ACCEPT " $IPTABLES -A RULE_4 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # there should be warning saying the table could not be found # firewall41:Policy:5: error: File not found for Address Table: missing table (this_table_does_not_exist.tbl) Using dummy address in test mode # firewall41:Policy:5: error: Rule '5 (global)' shadows rule '6 (global)' below it $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -d 192.0.2.0/24 -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -A RULE_5 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # # firewall41:Policy:6: error: DNSName object "does not resolve" (compile time) can not resolve dns name "does_not_resolve.local" (AF_INET): Host or network 'does_not_resolve.local' not found; last error: Unknown error Using dummy address in test mode $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -d 192.0.2.1 -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -A RULE_6 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:53 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall35.fw.orig0000755000175000017500000004216011733011756022031 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:41 2012 PDT by vadim # # files: * firewall35.fw /etc/fw/firewall35.fw # # Compiled for iptables (any version) # # testing AddressTable object # like firewall34, but uses different script format FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "block_these" "block-hosts.tbl" } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" getaddr eth0.100 i_eth0_100 getaddr6 eth0.100 i_eth0_100_v6 getnet eth0.100 i_eth0_100_network getnet6 eth0.100 i_eth0_100_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # ================ Table 'filter', rule set block_local_bcast # # Rule block_local_bcast 0 (global) # an attempt to build rule blocking local broadcast packets on the subnet where firewall has dynamic interface echo ":block_local_bcast - [0:0]" echo "-A block_local_bcast -d 192.168.222.255 -j DROP " # # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.2 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.3/30 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.200 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.201 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.2.128/25 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 192.168.1.2 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 192.168.1.3/30 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 192.168.1.200 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 192.168.1.201 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 192.168.2.128/25 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.2 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.3/30 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.201 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.2.128/25 -m state --state NEW -j ACCEPT " # # Rule 1 (global) echo ":RULE_1 - [0:0]" grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A OUTPUT -d $at_block_these -j RULE_1 " done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A FORWARD -d $at_block_these -j RULE_1 " done echo "-A RULE_1 -j LOG --log-level debug --log-prefix \"RULE 1 -- DENY on global \"" echo "-A RULE_1 -j DROP " # # Rule 2 (global) echo ":RULE_2 - [0:0]" grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A OUTPUT -d $at_block_these -j RULE_2 " done echo "-A OUTPUT -d 61.150.47.112 -j RULE_2 " grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A FORWARD -d $at_block_these -j RULE_2 " done echo "-A FORWARD -d 61.150.47.112 -j RULE_2 " echo "-A RULE_2 -j LOG --log-level debug --log-prefix \"RULE 2 -- DENY on global \"" echo "-A RULE_2 -j DROP " # # Rule 3 (global) grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A OUTPUT -p tcp -m tcp -d $at_block_these --dport 25 -j DROP " done echo "-A OUTPUT -p tcp -m tcp -d 61.150.47.112 --dport 25 -j DROP " grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A FORWARD -p tcp -m tcp -d $at_block_these --dport 25 -j DROP " done echo "-A FORWARD -p tcp -m tcp -d 61.150.47.112 --dport 25 -j DROP " # # Rule 4 (global) for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && { grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A OUTPUT -p tcp -m tcp -s $i_eth0_100 -d $at_block_these --dport 25 -j DROP " done } done for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && echo "-A OUTPUT -p tcp -m tcp -s $i_eth0_100 -d 61.150.47.112 --dport 25 -j DROP " done # # Rule 5 (global) # test rule for the discussion # https://sourceforge.net/projects/fwbuilder/forums/forum/16372/topic/3733964/index/page/1 echo "-A INPUT -j block_local_bcast " # # Rule 6 (global) echo ":RULE_6 - [0:0]" grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A INPUT -s $at_block_these -j RULE_6 " done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A FORWARD -s $at_block_these -j RULE_6 " done echo "-A RULE_6 -j LOG --log-level debug --log-prefix \"RULE 6 -- DENY on global \"" echo "-A RULE_6 -j DROP " # # Rule 7 (global) echo ":RULE_7 - [0:0]" grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A INPUT -s $at_block_these -j RULE_7 " done echo "-A INPUT -s 61.150.47.112 -j RULE_7 " grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A FORWARD -s $at_block_these -j RULE_7 " done echo "-A FORWARD -s 61.150.47.112 -j RULE_7 " echo "-A RULE_7 -j LOG --log-level debug --log-prefix \"RULE 7 -- DENY on global \"" echo "-A RULE_7 -j DROP " # # Rule 8 (global) echo ":Cid4392555025682.0 - [0:0]" echo "-A OUTPUT -m state --state NEW -j Cid4392555025682.0 " echo "-A INPUT -m state --state NEW -j Cid4392555025682.0 " echo "-A FORWARD -m state --state NEW -j Cid4392555025682.0 " grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A Cid4392555025682.0 -s $at_block_these -j RETURN " done echo "-A Cid4392555025682.0 -s 61.150.47.112 -j RETURN " echo "-A Cid4392555025682.0 -j ACCEPT " # # Rule 9 (global) echo ":Cid4392555D25682.0 - [0:0]" for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && echo "-A INPUT -s $i_eth0_100 -m state --state NEW -j Cid4392555D25682.0 " done for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && echo "-A OUTPUT -s $i_eth0_100 -m state --state NEW -j Cid4392555D25682.0 " done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A Cid4392555D25682.0 -d $at_block_these -j RETURN " done echo "-A Cid4392555D25682.0 -d 61.150.47.112 -j RETURN " echo "-A Cid4392555D25682.0 -j ACCEPT " # # Rule 10 (global) echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 25 -m state --state NEW -j ACCEPT " echo "-A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 25 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo "-A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 12 (global) echo ":RULE_12 - [0:0]" echo "-A OUTPUT -j RULE_12 " echo "-A INPUT -j RULE_12 " echo "-A FORWARD -j RULE_12 " echo "-A RULE_12 -j LOG --log-level debug --log-prefix \"RULE 12 -- DENY on global \"" echo "-A RULE_12 -j DROP " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo ":Cid4392558F25682.0 - [0:0]" for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && echo "-A PREROUTING -p tcp -m tcp -d $i_eth0_100 --dport 25 -j Cid4392558F25682.0 " done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A Cid4392558F25682.0 -s $at_block_these -j RETURN " done echo "-A Cid4392558F25682.0 -p tcp -m tcp --dport 25 -j DNAT --to-destination 192.168.1.10 " # # Rule 1 (NAT) echo ":Cid4392559D25682.0 - [0:0]" echo "-A POSTROUTING -o eth0.100 -s 192.168.1.0/24 -j Cid4392559D25682.0 " grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; echo "-A Cid4392559D25682.0 -d $at_block_these -j RETURN " done echo "-A Cid4392559D25682.0 -j MASQUERADE " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/test-shadowing-1.fw.orig0000755000175000017500000003350411733011756023154 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:40 2012 PDT by vadim # # files: * test-shadowing-1.fw /etc/test-shadowing-1.fw # # Compiled for iptables (any version) # # testing shadowing detection # compiler runs with -xt flag # firewall is assumed to be part of any # test-shadowing-1:Policy:0: error: Rule '0 (eth0)' shadows rule '1 (eth0)' below it # test-shadowing-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # test-shadowing-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # test-shadowing-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # test-shadowing-1:Policy:4: error: Rule '4 (global)' shadows rule '5 (global)' below it # test-shadowing-1:Policy:6: error: Rule '6 (global)' shadows rule '7 (global)' below it # test-shadowing-1:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 eth2" for i in eth0 eth1 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 22.22.22.22/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # shades rule below # test-shadowing-1:Policy:0: error: Rule '0 (eth0)' shadows rule '1 (eth0)' below it $IPTABLES -A OUTPUT -o eth0 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth0 -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -N Out_RULE_1 $IPTABLES -A FORWARD -o eth0 -s 192.168.1.10 -j Out_RULE_1 $IPTABLES -A Out_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A Out_RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall is part # of any for this rule # test-shadowing-1:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N Cid4514B3E62143.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -j Cid4514B3E62143.0 $IPTABLES -A Cid4514B3E62143.0 -s 22.22.22.22 -j DROP $IPTABLES -A Cid4514B3E62143.0 -s 192.168.1.1 -j DROP $IPTABLES -A Cid4514B3E62143.0 -s 192.168.2.1 -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # # test-shadowing-1:Policy:4: error: Rule '4 (global)' shadows rule '5 (global)' below it $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 21 -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 21 -j DROP $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 21 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # # test-shadowing-1:Policy:6: error: Rule '6 (global)' shadows rule '7 (global)' below it $IPTABLES -A INPUT -p udp -m udp -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -p udp -m udp -s 192.168.1.0/24 --dport 123 -j DROP $IPTABLES -A OUTPUT -p udp -m udp -s 192.168.1.0/24 --dport 123 -j DROP $IPTABLES -A FORWARD -p udp -m udp -s 192.168.1.0/24 --dport 123 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # # this rule should shadow rule below it because # it uses IPService object with protocol 0 # test-shadowing-1:Policy:8: error: Rule '8 (global)' shadows rule '9 (global)' below it $IPTABLES -A INPUT -p all -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p all -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p all -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j DROP $IPTABLES -A OUTPUT -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j DROP $IPTABLES -A FORWARD -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:40 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall94.fw.orig0000755000175000017500000003530211733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:18 2012 PDT by vadim # # files: * firewall94.fw /etc/fw/firewall94.fw # # Compiled for iptables 1.3.0 # # testing rules that use address ranges that include or not include fw FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0" for i in eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::20c:29ff:fe28:c078/64 192.168.1.2/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # address range in src includes firewall $IPTABLES -A INPUT -m iprange --src-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -m iprange --src-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m iprange --src-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A INPUT -m iprange --src-range 192.168.1.3-192.168.1.5 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m iprange --src-range 192.168.1.3-192.168.1.5 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # address range in src includes firewall $IPTABLES -A OUTPUT -m iprange --src-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m iprange --src-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A FORWARD -m iprange --src-range 192.168.1.3-192.168.1.5 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # address range in dst includes firewall $IPTABLES -A OUTPUT -m iprange --dst-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m iprange --dst-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m iprange --dst-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -A OUTPUT -m iprange --dst-range 192.168.1.3-192.168.1.5 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m iprange --dst-range 192.168.1.3-192.168.1.5 -m state --state NEW -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # address range in dst includes firewall $IPTABLES -A INPUT -m iprange --dst-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m iprange --dst-range 192.168.1.1-192.168.1.3 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A FORWARD -m iprange --dst-range 192.168.1.3-192.168.1.5 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A INPUT -s 255.255.255.255 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A OUTPUT -s 255.255.255.255 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -A OUTPUT -s 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -s 255.255.255.255 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A INPUT -s 0.0.0.0 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A OUTPUT -s 0.0.0.0 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A OUTPUT -s 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A OUTPUT -s 0.0.0.0 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -A OUTPUT -d 0.0.0.0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -d 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -A OUTPUT -d 255.255.255.255 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 0.0.0.0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 255.255.255.255 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -d 255.255.255.255 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.0/24 -d 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -A INPUT -d 0.0.0.0 -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -d 0.0.0.0 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:18 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall72-1.4.3.fw.orig0000755000175000017500000004120211733011756022467 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:07 2012 PDT by vadim # # files: * firewall72-1.4.3.fw /etc/fw/firewall72-1.4.3.fw # # Compiled for iptables 1.4.3 # # this firewall is used to test a rule in the global policy of object "firewall" # firewall72-1.4.3:Policy:10: error: Rule '10 (eth1)' shadows rule '13 (eth1)' below it # firewall72-1.4.3:Policy:10: error: Rule '10 (eth1)' shadows rule '14 (eth1)' below it # firewall72-1.4.3:Policy:15: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall72-1.4.3::: warning: Can not add virtual address for object address # firewall72-1.4.3::: warning: Can not add virtual address for object address FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 33.33.33.33/24" "" update_addresses_of_interface "eth1 172.16.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ ! -s 192.168.1.0/24 -d 200.200.200.200 -j SNAT --to-source 22.22.22.23 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp ! -s 192.168.1.0/24 -d 200.200.200.200 --dport 80 -j SNAT --to-source 22.22.22.23 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 ! -d 192.168.2.0/24 -j SNAT --to-source 33.33.33.33 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 ! -d 192.168.2.0/24 -j SNAT --to-source 172.16.1.1 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 ! -d 192.168.2.0/24 --dport 80 -j SNAT --to-source 33.33.33.33 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 ! -d 192.168.2.0/24 --dport 80 -j SNAT --to-source 172.16.1.1 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -N Cid213031X8629.0 $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j Cid213031X8629.0 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j Cid213031X8629.0 $IPTABLES -t nat -A Cid213031X8629.0 -d 192.168.1.0/24 -j RETURN $IPTABLES -t nat -A Cid213031X8629.0 -d 192.168.2.0/24 -j RETURN $IPTABLES -t nat -A Cid213031X8629.0 -j SNAT --to-source 172.16.1.1 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 ! -d 192.168.1.1 --dport 80 -j REDIRECT --to-ports 3128 # ================ Table 'filter', rule set Policy # # Rule 0 (lo) # echo "Rule 0 (lo)" # $IPTABLES -A INPUT ! -i lo -s 127.0.0.1 -j DROP $IPTABLES -A FORWARD ! -i lo -s 127.0.0.1 -j DROP $IPTABLES -A OUTPUT ! -o lo -s 127.0.0.1 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # $IPTABLES -N Cid170430X8629.0 $IPTABLES -A OUTPUT -o eth1 ! -s 192.168.1.0/24 -j Cid170430X8629.0 $IPTABLES -A Cid170430X8629.0 -d 33.33.33.33 -j DROP $IPTABLES -A Cid170430X8629.0 -d 172.16.1.1 -j DROP $IPTABLES -N Cid170430X8629.1 $IPTABLES -A FORWARD -o eth1 ! -s 192.168.1.0/24 -j Cid170430X8629.1 $IPTABLES -A Cid170430X8629.1 -d 33.33.33.33 -j DROP $IPTABLES -A Cid170430X8629.1 -d 172.16.1.1 -j DROP # # Rule 2 (eth1) # echo "Rule 2 (eth1)" # $IPTABLES -N Cid170442X8629.0 $IPTABLES -A INPUT -i eth1 ! -d 192.168.1.0/24 -j Cid170442X8629.0 $IPTABLES -A Cid170442X8629.0 -s 33.33.33.33 -j DROP $IPTABLES -A Cid170442X8629.0 -s 172.16.1.1 -j DROP $IPTABLES -N Cid170442X8629.1 $IPTABLES -A FORWARD -i eth1 ! -d 192.168.1.0/24 -j Cid170442X8629.1 $IPTABLES -A Cid170442X8629.1 -s 33.33.33.33 -j DROP $IPTABLES -A Cid170442X8629.1 -s 172.16.1.1 -j DROP # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N Cid170454X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid170454X8629.0 $IPTABLES -A Cid170454X8629.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -A Cid170454X8629.0 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid170466X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid170466X8629.0 $IPTABLES -A Cid170466X8629.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -A Cid170466X8629.0 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid170478X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid170478X8629.0 $IPTABLES -A Cid170478X8629.0 -p icmp -m icmp --icmp-type 3/1 -j RETURN $IPTABLES -A Cid170478X8629.0 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid170490X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid170490X8629.0 $IPTABLES -A Cid170490X8629.0 -p icmp -m icmp --icmp-type 3/1 -j RETURN $IPTABLES -A Cid170490X8629.0 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid170502X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid170502X8629.0 $IPTABLES -A Cid170502X8629.0 -p 47 -j RETURN $IPTABLES -A Cid170502X8629.0 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N Cid170514X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid170514X8629.0 $IPTABLES -A Cid170514X8629.0 -p tcp -m tcp --tcp-flags ALL NONE -j RETURN $IPTABLES -A Cid170514X8629.0 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A OUTPUT -d 172.16.1.1 -m mark ! --mark 16 -j DROP $IPTABLES -A INPUT -d 172.16.1.1 -m mark ! --mark 16 -j DROP # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # # Should use ! -i eth1 eventually # firewall72-1.4.3:Policy:10: error: Rule '10 (eth1)' shadows rule '13 (eth1)' below it # firewall72-1.4.3:Policy:10: error: Rule '10 (eth1)' shadows rule '14 (eth1)' below it $IPTABLES -A FORWARD ! -i eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 11 (eth1) # echo "Rule 11 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -N Cid170550X8629.0 $IPTABLES -A FORWARD ! -i eth1 -d 192.168.1.0/24 -j Cid170550X8629.0 $IPTABLES -A Cid170550X8629.0 -p tcp -m tcp --tcp-flags ALL NONE -j RETURN $IPTABLES -A Cid170550X8629.0 -j DROP # # Rule 12 (eth1) # echo "Rule 12 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -A OUTPUT ! -o eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A FORWARD ! -o eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 13 (eth1) # echo "Rule 13 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -A FORWARD ! -i eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A OUTPUT ! -o eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A FORWARD ! -o eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 14 (eth1) # echo "Rule 14 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -A FORWARD ! -i eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A OUTPUT ! -o eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A FORWARD ! -o eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 15 (global) # echo "Rule 15 (global)" # # firewall72-1.4.3:Policy:15: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -d 172.16.1.1 -m owner ! --uid-owner 500 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:07 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall36.fw.orig0000755000175000017500000003161111733011756022031 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:43 2012 PDT by vadim # # files: * firewall36.fw /etc/firewall36.fw # # Compiled for iptables (any version) # # testing routing rules # routing ruleset installs ECMP default # ROUTE target is deprecated in 4.3.0 # firewall36:Routing:4: warning: Rule has been suppressed because it contains IPv6 objects and Firewall Builder does not support IPv6 routing rules at this time FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth2" for i in eth0 eth1 lo eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.0.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v 'proto kernel' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # Rule 1 (main) # echo "Routing rule 1 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # Rule 2 (main) # echo "Routing rule 2 (main)" # # # $IP route add 192.168.2.0/24 via 192.168.1.254 dev eth1 \ || route_command_error "2 (main)" # # Rule 3 (main) # echo "Routing rule 3 (main)" # # # $IP route add 22.22.22.100/30 via 192.168.1.254 dev eth1 \ || route_command_error "3 (main)" $IP route add 22.22.22.104/30 via 192.168.1.254 dev eth1 \ || route_command_error "3 (main)" $IP route add 22.22.22.108/31 via 192.168.1.254 dev eth1 \ || route_command_error "3 (main)" $IP route add 22.22.22.110 via 192.168.1.254 dev eth1 \ || route_command_error "3 (main)" # # Rule 5 (main) # echo "Routing rule 5 (main)" # # # $IP route add 192.168.1.0/24 dev eth1 \ || route_command_error "5 (main)" $IP route add 192.168.2.0/24 dev eth1 \ || route_command_error "5 (main)" # # ============== EQUAL COST MULTI PATH ============ # echo "Activating ecmp routing rules..." # # Multipath Rule derived from the following routing rules: # # Rule 0 (main) # # Rule 1 (main) # # $IP route add default \ nexthop dev eth0 \ nexthop dev eth2 \ || route_command_error "1" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:43 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall23.fw.orig0000755000175000017500000003161611733011756022032 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:23 2012 PDT by vadim # # files: * firewall23.fw /etc/fw/firewall23.fw # # Compiled for iptables (any version) # # This is BRIDGING FIREWALL FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "br0 192.168.1.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth*) # echo "Rule 0 (eth*)" # $IPTABLES -A INPUT -i eth+ -m state --state NEW -j ACCEPT # # Rule 1 (eth*) # echo "Rule 1 (eth*)" # $IPTABLES -A INPUT -i eth+ -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth+ -m state --state NEW -j ACCEPT # # Rule 2 (eth*) # echo "Rule 2 (eth*)" # $IPTABLES -A FORWARD -i eth+ -d 192.168.1.255 -m state --state NEW -j ACCEPT # # Rule 3 (eth*) # echo "Rule 3 (eth*)" # $IPTABLES -A FORWARD -i eth+ -d 255.255.255.255 -m state --state NEW -j ACCEPT # # Rule 4 (eth*) # echo "Rule 4 (eth*)" # $IPTABLES -A FORWARD -i eth+ -d 224.0.1.141 -m state --state NEW -j ACCEPT # # Rule 5 (eth*) # echo "Rule 5 (eth*)" # $IPTABLES -A FORWARD -i eth+ -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 6 (eth*) # echo "Rule 6 (eth*)" # $IPTABLES -A FORWARD -i eth+ -d ! 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.10 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -d 192.168.1.10 --dport 68 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A OUTPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 192.168.1.20 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.1.141 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.20 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -A OUTPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.10 --dport 6667 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N RULE_12 $IPTABLES -A OUTPUT -d 192.168.1.10 -j RULE_12 $IPTABLES -A FORWARD -d 192.168.1.10 -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level debug $IPTABLES -A RULE_12 -j DROP # # Rule 13 (global) # echo "Rule 13 (global)" # # this rule should generate commands # in both INPUT and FORWARD chains # because this is a bridging firewall # see bug #811860 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # interface of another firewall # (firewall11) # Why do we need to test for this? $IPTABLES -A OUTPUT -d 10.1.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 10.1.1.1 -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:23 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-nd-ns-2.fw.orig0000755000175000017500000003244011733011756023717 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:30 2012 PDT by vadim # # files: * firewall-ipv6-nd-ns-2.fw /etc/firewall-ipv6-nd-ns-2.fw # # Compiled for iptables 1.4.0 # # automatic ND/NS rules, bridging fw FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 192.0.2.1/24" "" } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # rules to permit IPv6 Neighbor discovery echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT " echo "-A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT " echo "-A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:30 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/objects-for-regression-tests.fwb0000644000175000017500001344337111733011756025024 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk -m ip_conntrack_talk -m ip_nat_talk -p tcp -m state --state ESTABLISHED --tcp-flags SYN,ACK,RST,URG ACK -p tcp -m state --state ESTABLISHED --tcp-flags SYN,FIN,RST,URG,PSH RST -m string --string test_pattern -m string --string test_pattern -p tcp ! --syn -dport 5190 -m state --state NEW -m rt --rt-type 0 -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -m owner --uid-owner anonymous -m owner --uid-owner anonymous -m owner --uid-owner anonymous fwbuilder-5.1.0.3599/test/ipt/firewall37-1.fw.orig0000755000175000017500000010626711733011756022202 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:46 2012 PDT by vadim # # files: * firewall37-1.fw /etc/fw/firewall37-1.fw # # Compiled for iptables (any version) # # testing TAG and CLASSIFY rules # same as firewall37 except rules are made to be terminating FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark $IPTABLES -t mangle -A OUTPUT -j CONNMARK --restore-mark # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 22.22.23.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -j ACCEPT # ================ Table 'mangle', rule set rule27_branch # # Rule rule27_branch 0 (global) # echo "Rule rule27_branch 0 (global)" # $IPTABLES -N rule27_branch -t mangle $IPTABLES -t mangle -A rule27_branch -p tcp -m tcp --tcp-flags ALL ACK -j CLASSIFY --set-class 1:16 # ================ Table 'mangle', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # terminating target $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 1 (global) # echo "Rule 1 (global)" # # terminating target $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 2 (global) # echo "Rule 2 (global)" # # terminating target $IPTABLES -N Cid45AB5AC525451.0 -t mangle $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -t mangle -A Cid45AB5AC525451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5AC525451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5AC525451.0 -j MARK --set-mark 16 # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # # terminating target $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 4 (eth1) # echo "Rule 4 (eth1)" # # temrinating target $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 5 (global) # echo "Rule 5 (global)" # # terminating and CONNMARK $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 6 (global) # echo "Rule 6 (global)" # # terminating and CONNMARK $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 7 (global) # echo "Rule 7 (global)" # # terminating and CONNMARK $IPTABLES -N Cid45AB5B0225451.0 -t mangle $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -t mangle -A Cid45AB5B0225451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5B0225451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5B0225451.0 -j MARK --set-mark 10 $IPTABLES -t mangle -A Cid45AB5B0225451.0 -j CONNMARK --save-mark # # Rule 8 (eth1) # echo "Rule 8 (eth1)" # # terminating and CONNMARK $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j MARK --set-mark 8 $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j MARK --set-mark 8 $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 9 (eth1) # echo "Rule 9 (eth1)" # # terminating and CONNMARK $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 9 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 9 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 9 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j MARK --set-mark 9 $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 11 (global) # echo "Rule 11 (global)" # # testing for bug #1618381 # this rule, and the next one, should place # CLASSIFY rule in a separate chain # and pass control to it using -g $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j CLASSIFY --set-class 1:10 # # Rule 12 (eth0) # echo "Rule 12 (eth0)" # # second rule for bug #1618381 $IPTABLES -t mangle -A POSTROUTING -o eth0 -j CLASSIFY --set-class 1:11 # # Rule 13 (global) # echo "Rule 13 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5BAD25451.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j Cid45AB5BAD25451.0 $IPTABLES -t mangle -A Cid45AB5BAD25451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5BAD25451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5BAD25451.0 -j CLASSIFY --set-class 1:10 # # Rule 14 (global) # echo "Rule 14 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5BBA25451.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j Cid45AB5BBA25451.0 $IPTABLES -t mangle -A POSTROUTING -p tcp -m tcp --dport 80 -j Cid45AB5BBA25451.0 $IPTABLES -t mangle -A Cid45AB5BBA25451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5BBA25451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5BBA25451.0 -j CLASSIFY --set-class 1:10 # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # bug #1618381 # this rule uses multiport # and has to be split because # of that $IPTABLES -t mangle -A POSTROUTING -o eth0 -p tcp -m tcp --dport 10000:11000 -j CLASSIFY --set-class 1:11 $IPTABLES -t mangle -A POSTROUTING -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j CLASSIFY --set-class 1:11 $IPTABLES -t mangle -A POSTROUTING -o eth0 -p udp -m udp -m multiport --dports 53,161 -j CLASSIFY --set-class 1:11 # # Rule 16 (global) # echo "Rule 16 (global)" # # testing for bug #1618381 # this rule, and the next one, should place # CLASSIFY rule in a separate chain # and pass control to it using -g $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j CLASSIFY --set-class 1:10 # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # second rule for bug #1618381 $IPTABLES -t mangle -A POSTROUTING -o eth0 -j CLASSIFY --set-class 1:11 # # Rule 18 (eth0) # echo "Rule 18 (eth0)" # $IPTABLES -t mangle -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:11 # # Rule 19 (global) # echo "Rule 19 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5BF925451.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j Cid45AB5BF925451.0 $IPTABLES -t mangle -A Cid45AB5BF925451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5BF925451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5BF925451.0 -j CLASSIFY --set-class 1:10 # # Rule 20 (global) # echo "Rule 20 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5C0625451.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j Cid45AB5C0625451.0 $IPTABLES -t mangle -A POSTROUTING -p tcp -m tcp --dport 80 -j Cid45AB5C0625451.0 $IPTABLES -t mangle -A Cid45AB5C0625451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5C0625451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid45AB5C0625451.0 -j CLASSIFY --set-class 1:10 # # Rule 21 (eth0) # echo "Rule 21 (eth0)" # # bug #1618381 # this rule uses multiport # and has to be split because # of that $IPTABLES -t mangle -A POSTROUTING -o eth0 -p tcp -m tcp --dport 10000:11000 -j CLASSIFY --set-class 1:11 $IPTABLES -t mangle -A POSTROUTING -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j CLASSIFY --set-class 1:11 $IPTABLES -t mangle -A POSTROUTING -o eth0 -p udp -m udp -m multiport --dports 53,161 -j CLASSIFY --set-class 1:11 # # Rule 22 (global) # echo "Rule 22 (global)" # # bug #1618381 # should generate branching code # in both filter and mangle tables $IPTABLES -t mangle -A PREROUTING -p tcp -m tcp -j rule27_branch $IPTABLES -t mangle -A POSTROUTING -p tcp -m tcp -j rule27_branch $IPTABLES -t mangle -A FORWARD -p tcp -m tcp -j rule27_branch # ================ Table 'filter', rule set rule27_branch # # Rule rule27_branch 0 (global) # echo "Rule rule27_branch 0 (global)" # $IPTABLES -N rule27_branch $IPTABLES -A rule27_branch -p tcp -m tcp --tcp-flags ALL ACK -j ACCEPT # # Rule rule27_branch 1 (global) # echo "Rule rule27_branch 1 (global)" # $IPTABLES -N rule27_branch_1 $IPTABLES -A rule27_branch -p tcp -m tcp --dport 80 -m state --state NEW -j rule27_branch_1 $IPTABLES -A rule27_branch_1 -j LOG --log-level info --log-prefix "RULE 1 -- ACCEPT " $IPTABLES -A rule27_branch_1 -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # terminating target $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p ah -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # # terminating target $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j RULE_1 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j RULE_1 $IPTABLES -A INPUT -p 50 -m state --state NEW -j RULE_1 $IPTABLES -A INPUT -p ah -m state --state NEW -j RULE_1 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j RULE_1 $IPTABLES -A FORWARD -p ah -m state --state NEW -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- ACCEPT " $IPTABLES -A RULE_1 -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # terminating target $IPTABLES -N Cid45AB5AC525451.0 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -A INPUT -p 50 -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -A INPUT -p ah -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -A FORWARD -p ah -m state --state NEW -j Cid45AB5AC525451.0 $IPTABLES -A Cid45AB5AC525451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid45AB5AC525451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_2_3 $IPTABLES -A Cid45AB5AC525451.0 -j RULE_2_3 $IPTABLES -A RULE_2_3 -j LOG --log-level info --log-prefix "RULE 2 -- ACCEPT " $IPTABLES -A RULE_2_3 -j ACCEPT # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # # terminating target $IPTABLES -A INPUT -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 4 (eth1) # echo "Rule 4 (eth1)" # # temrinating target $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # terminating and CONNMARK $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p ah -m state --state NEW -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # terminating and CONNMARK $IPTABLES -N RULE_6 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j RULE_6 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j RULE_6 $IPTABLES -A INPUT -p 50 -m state --state NEW -j RULE_6 $IPTABLES -A INPUT -p ah -m state --state NEW -j RULE_6 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j RULE_6 $IPTABLES -A FORWARD -p ah -m state --state NEW -j RULE_6 $IPTABLES -A RULE_6 -j LOG --log-level info --log-prefix "RULE 6 -- ACCEPT " $IPTABLES -A RULE_6 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # # terminating and CONNMARK $IPTABLES -N Cid45AB5B0225451.0 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -A INPUT -p 50 -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -A INPUT -p ah -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -A FORWARD -p ah -m state --state NEW -j Cid45AB5B0225451.0 $IPTABLES -A Cid45AB5B0225451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid45AB5B0225451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid45AB5B0225451.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -j LOG --log-level info --log-prefix "RULE 7 -- ACCEPT " $IPTABLES -A RULE_7_3 -j ACCEPT # # Rule 8 (eth1) # echo "Rule 8 (eth1)" # # terminating and CONNMARK $IPTABLES -A INPUT -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 9 (eth1) # echo "Rule 9 (eth1)" # # terminating and CONNMARK $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 80 -j QUEUE $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -j QUEUE # # Rule 11 (global) # echo "Rule 11 (global)" # # testing for bug #1618381 # this rule, and the next one, should place # CLASSIFY rule in a separate chain # and pass control to it using -g $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j ACCEPT # # Rule 12 (eth0) # echo "Rule 12 (eth0)" # # second rule for bug #1618381 $IPTABLES -A INPUT -i eth0 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5BAD25451.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5BAD25451.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5BAD25451.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid45AB5BAD25451.0 $IPTABLES -A Cid45AB5BAD25451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid45AB5BAD25451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid45AB5BAD25451.0 -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5BBA25451.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5BBA25451.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j Cid45AB5BBA25451.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5BBA25451.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -j Cid45AB5BBA25451.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid45AB5BBA25451.0 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -j Cid45AB5BBA25451.0 $IPTABLES -A Cid45AB5BBA25451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid45AB5BBA25451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid45AB5BBA25451.0 -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # bug #1618381 # this rule uses multiport # and has to be split because # of that $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # testing for bug #1618381 # this rule, and the next one, should place # CLASSIFY rule in a separate chain # and pass control to it using -g $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # second rule for bug #1618381 $IPTABLES -A INPUT -i eth0 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -j ACCEPT # # Rule 18 (eth0) # echo "Rule 18 (eth0)" # $IPTABLES -N Out_RULE_18 $IPTABLES -A OUTPUT -o eth0 -s 192.168.1.0/24 -j Out_RULE_18 $IPTABLES -A FORWARD -o eth0 -s 192.168.1.0/24 -j Out_RULE_18 $IPTABLES -A Out_RULE_18 -j LOG --log-level info --log-prefix "RULE 18 -- ACCEPT " $IPTABLES -A Out_RULE_18 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5BF925451.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5BF925451.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5BF925451.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid45AB5BF925451.0 $IPTABLES -A Cid45AB5BF925451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid45AB5BF925451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid45AB5BF925451.0 -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # # testing for bug #1618381 $IPTABLES -N Cid45AB5C0625451.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5C0625451.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j Cid45AB5C0625451.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid45AB5C0625451.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -j Cid45AB5C0625451.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid45AB5C0625451.0 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -j Cid45AB5C0625451.0 $IPTABLES -A Cid45AB5C0625451.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid45AB5C0625451.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid45AB5C0625451.0 -j ACCEPT # # Rule 21 (eth0) # echo "Rule 21 (eth0)" # # bug #1618381 # this rule uses multiport # and has to be split because # of that $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # # bug #1618381 # should generate branching code # in both filter and mangle tables $IPTABLES -A OUTPUT -p tcp -m tcp -j rule27_branch $IPTABLES -A INPUT -p tcp -m tcp -j rule27_branch $IPTABLES -A FORWARD -p tcp -m tcp -j rule27_branch # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N RULE_24 $IPTABLES -A OUTPUT -j RULE_24 $IPTABLES -A INPUT -j RULE_24 $IPTABLES -A FORWARD -j RULE_24 $IPTABLES -A RULE_24 -j LOG --log-level info --log-prefix "RULE 24 -- DENY " $IPTABLES -A RULE_24 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:46 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall17.fw.orig0000755000175000017500000003366211733011756022040 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:14 2012 PDT by vadim # # files: * firewall17.fw /etc/fw/firewall17.fw # # Compiled for iptables (any version) # # doing SNAT with virtual addresses of two external interface # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters # firewall17:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 33.33.33.33/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth3 22.22.23.23/24 44.44.44.44/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # compiler should add "-o eth2" $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 33.33.33.33 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # # compiler should add "-o eth2" $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 44.44.44.44 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # $IPTABLES -N Cid3E1C6BE3.0 $IPTABLES -A INPUT -i eth1 -j Cid3E1C6BE3.0 $IPTABLES -A Cid3E1C6BE3.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3E1C6BE3.0 -d 22.22.23.23 -j RETURN $IPTABLES -A Cid3E1C6BE3.0 -d 33.33.33.33 -j RETURN $IPTABLES -A Cid3E1C6BE3.0 -d 44.44.44.44 -j RETURN $IPTABLES -A Cid3E1C6BE3.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3E1C6BE3.0 -d 192.168.2.1 -j RETURN $IPTABLES -N In_RULE_0_3 $IPTABLES -A Cid3E1C6BE3.0 -j In_RULE_0_3 $IPTABLES -A In_RULE_0_3 -j LOG --log-level debug --log-prefix "RULE 0 -- DENY on interface g" $IPTABLES -A In_RULE_0_3 -j DROP $IPTABLES -N In_RULE_0 $IPTABLES -A FORWARD -i eth1 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level debug --log-prefix "RULE 0 -- DENY on interface g" $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N rule0acct $IPTABLES -A rule0acct -j RETURN $IPTABLES -A OUTPUT -j rule0acct $IPTABLES -A INPUT -j rule0acct $IPTABLES -A FORWARD -j rule0acct # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 $IPTABLES -A OUTPUT -j RULE_2 $IPTABLES -A INPUT -j RULE_2 $IPTABLES -A FORWARD -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level debug --log-prefix "RULE 2 -- ACCOUNTING on inter" $IPTABLES -N rule1acct $IPTABLES -A rule1acct -j RETURN $IPTABLES -A RULE_2 -j rule1acct # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -j RULE_3 $IPTABLES -A INPUT -j RULE_3 $IPTABLES -A FORWARD -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level debug --log-prefix "RULE 3 -- ACCOUNTING on inter" $IPTABLES -A RULE_3 -j RETURN # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N RULE_4 $IPTABLES -A RULE_4 -j RETURN $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.11 -d 192.168.2.10 --dport 4000:4010 -j RULE_4 $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.11 -d 192.168.2.10 --dport 22 -j RULE_4 # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid3E1C6BC9.0 $IPTABLES -A INPUT -j Cid3E1C6BC9.0 $IPTABLES -A Cid3E1C6BC9.0 -d 22.22.22.22 -j RETURN $IPTABLES -A Cid3E1C6BC9.0 -d 22.22.23.23 -j RETURN $IPTABLES -A Cid3E1C6BC9.0 -d 33.33.33.33 -j RETURN $IPTABLES -A Cid3E1C6BC9.0 -d 44.44.44.44 -j RETURN $IPTABLES -A Cid3E1C6BC9.0 -d 192.168.1.1 -j RETURN $IPTABLES -A Cid3E1C6BC9.0 -d 192.168.2.1 -j RETURN $IPTABLES -N In_RULE_5_3 $IPTABLES -A Cid3E1C6BC9.0 -j In_RULE_5_3 $IPTABLES -A In_RULE_5_3 -j LOG --log-level debug --log-prefix "RULE 5 -- DENY on interface g" $IPTABLES -A In_RULE_5_3 -j DROP $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -j RULE_5 $IPTABLES -A FORWARD -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level debug --log-prefix "RULE 5 -- DENY on interface g" $IPTABLES -A RULE_5 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:14 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/block-hosts.tbl0000644000175000017500000000176011733011756021510 0ustar sylvestresylvestre# # use this table to test run-time AddressTable object # (this is just a small collection of addresses that sent spam to me # on Nov 20 2005) # ; this is a comment, too ; empty lines are allowed and should be skipped by the script 151.8.224.178 # this is also a comment 168.156.76.20 193.207.126.36 195.136.186.35 196.15.136.15 201.10.180.138 201.17.93.16 201.36.156.121 202.103.25.253 202.96.112.93 203.162.3.209 203.209.124.144 210.106.193.237 210.222.114.102 211.144.143.143 211.172.218.237 211.250.16.132 212.100.212.100 212.21.241.31 218.104.138.146 218.18.72.252 218.39.114.122 218.55.115.43 219.132.104.160 220.71.17.86 220.81.50.105 220.91.99.46 221.14.249.242 221.166.177.135 221.198.33.38 221.202.160.233 221.205.54.125 221.217.44.248 222.100.212.223 222.121.118.144 222.174.113.2 58.231.13.78 58.33.181.83 58.53.82.190 61.150.47.112 61.184.14.102 64.106.85.186 70.228.60.100 80.243.72.149 80.249.77.34 80.51.236.6 81.196.74.125 81.2.36.254 82.117.221.205 82.143.196.17 82.77.37.174 84.90.8.198 fwbuilder-5.1.0.3599/test/ipt/large_policy_test.fwb0000644000175000017500000037524011733011756022774 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/test/ipt/firewall27.fw.orig0000755000175000017500000004255311733011756022040 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:33 2012 PDT by vadim # # files: * firewall27.fw /etc/fw/firewall27.fw # # Compiled for iptables 1.4.0 # # this firewall uses iptables-restore format # all interfaces have static addresses, script pipes iptables commands straight to iptables-restore # firewall27::: warning: Can not add virtual address for object address # firewall27::: warning: Can not add virtual address for object address FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: ppp eth0 eth2" for i in ppp eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "ppp 192.0.2.1/24" "" update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # backup ssh access echo "-A INPUT -p tcp -m tcp -s 192.168.1.1/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT " echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop TCP sessions opened prior firewall restart echo "-A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " # drop packets that do not match any valid state echo "-A OUTPUT -m state --state INVALID -j DROP " echo "-A INPUT -m state --state INVALID -j DROP " echo "-A FORWARD -m state --state INVALID -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (ppp) # ppp clients get addresses on 10.1.1.0 echo ":In_RULE_0 - [0:0]" echo "-A INPUT -i ppp -s ! 10.1.1.0/24 -j In_RULE_0 " echo "-A FORWARD -i ppp -s ! 10.1.1.0/24 -j In_RULE_0 " echo "-A In_RULE_0 -j LOG " echo "-A In_RULE_0 -j DROP " # # Rule 1 (ppp) # ppp clients can not connect to the firewall echo ":In_RULE_1 - [0:0]" echo "-A INPUT -i ppp -d 192.0.2.1 -j In_RULE_1 " echo "-A In_RULE_1 -j LOG " echo "-A In_RULE_1 -j DROP " # # Rule 2 (ppp) echo ":In_RULE_2 - [0:0]" echo "-A INPUT -i ppp -j In_RULE_2 " echo "-A In_RULE_2 -j LOG " echo "-A In_RULE_2 -j DROP " # # Rule 3 (ppp) # ppp clients can only connect to the mail # server and web proxy on DMZ echo "-A FORWARD -i ppp -p tcp -m tcp -m multiport -d 192.168.2.10 --dports 25,3128 -m state --state NEW -j ACCEPT " # # Rule 4 (ppp) # ppp clients can not connect to # anything else on DMZ and # internal net echo ":In_RULE_4 - [0:0]" echo "-A INPUT -i ppp -d 192.168.1.0/24 -j In_RULE_4 " echo "-A INPUT -i ppp -d 192.168.2.0/24 -j In_RULE_4 " echo "-A FORWARD -i ppp -d 192.168.1.0/24 -j In_RULE_4 " echo "-A FORWARD -i ppp -d 192.168.2.0/24 -j In_RULE_4 " echo "-A In_RULE_4 -j LOG " echo "-A In_RULE_4 -j DROP " # # Rule 5 (eth2) echo ":In_RULE_5 - [0:0]" echo "-A INPUT -i eth2 -s ! 192.168.2.0/24 -j In_RULE_5 " echo "-A FORWARD -i eth2 -s ! 192.168.2.0/24 -j In_RULE_5 " echo "-A In_RULE_5 -j LOG " echo "-A In_RULE_5 -j DROP " # # Rule 6 (global) # hostF has the same IP address as firewal. echo ":RULE_6 - [0:0]" echo "-A OUTPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_6 " echo "-A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_6 " echo "-A RULE_6 -j LOG " echo "-A RULE_6 -j ACCEPT " # # Rule 7 (global) echo ":Cid4183D051.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid4183D051.0 " echo "-A Cid4183D051.0 -d 192.0.2.1 -j ACCEPT " echo "-A Cid4183D051.0 -d 192.168.1.1 -j ACCEPT " echo "-A Cid4183D051.0 -d 192.168.2.1 -j ACCEPT " echo "-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT " # # Rule 8 (global) echo "-A OUTPUT -p tcp -m tcp -d 192.0.2.1 --dport 22 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -d 192.0.2.1 --dport 22 -m state --state NEW -j ACCEPT " # # Rule 9 (global) echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT " # # Rule 10 (global) echo "-A OUTPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":Cid4183D07A.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid4183D07A.0 " echo "-A Cid4183D07A.0 -d 192.168.1.1 -j ACCEPT " echo "-A Cid4183D07A.0 -d 192.168.2.1 -j ACCEPT " echo ":Cid4183D07A.1 - [0:0]" echo "-A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid4183D07A.1 " echo "-A Cid4183D07A.1 -d 192.168.1.1 -j ACCEPT " echo "-A Cid4183D07A.1 -d 192.168.2.1 -j ACCEPT " # # Rule 12 (global) echo ":Cid4183D085.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid4183D085.0 " echo ":RULE_12 - [0:0]" echo "-A Cid4183D085.0 -d 192.168.1.1 -j RULE_12 " echo "-A Cid4183D085.0 -d 192.168.2.1 -j RULE_12 " echo ":Cid4183D085.1 - [0:0]" echo "-A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid4183D085.1 " echo "-A Cid4183D085.1 -d 192.168.1.1 -j RULE_12 " echo "-A Cid4183D085.1 -d 192.168.2.1 -j RULE_12 " echo "-A RULE_12 -j LOG " echo "-A RULE_12 -j ACCEPT " # # Rule 13 (global) # firewall is part of Any, so compiler should # generate code in both FORWARD and # OUTPUT chains echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j ACCEPT " # # Rule 14 (global) # firewall is part of Any, compiler should # generate code for both FORWARD and # INPUT chains echo "-A INPUT -s 200.200.200.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 200.200.200.200 -m state --state NEW -j ACCEPT " # # Rule 15 (global) # because firewall has interface on network # internal_net, compiler should generate code # for both FORWARD and INPUT chains echo "-A INPUT -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 16 (global) echo ":Cid4183D0AE.0 - [0:0]" echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j Cid4183D0AE.0 " echo "-A Cid4183D0AE.0 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid4183D0AE.0 -s 192.168.2.0/24 -j ACCEPT " echo ":Cid4183D0AE.1 - [0:0]" echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j Cid4183D0AE.1 " echo "-A Cid4183D0AE.1 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid4183D0AE.1 -s 192.168.2.0/24 -j ACCEPT " # # Rule 17 (global) # Automatically generated 'catch all' rule echo ":RULE_17 - [0:0]" echo "-A OUTPUT -j RULE_17 " echo "-A INPUT -j RULE_17 " echo "-A FORWARD -j RULE_17 " echo "-A RULE_17 -j LOG " echo "-A RULE_17 -j DROP " # echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o ppp -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 " echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 " # # Rule 1 (NAT) echo "-A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 " echo "-A POSTROUTING -o ppp -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 " # # Rule 2 (NAT) echo "-A PREROUTING -p tcp -m tcp -d 192.0.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " echo "-A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " echo "-A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " # # Rule 3 (NAT) echo "-A PREROUTING -s 192.168.1.0/24 -d ! 200.200.200.200 -j DNAT --to-destination 192.168.2.10 " echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.10 -j SNAT --to-source 192.168.2.1 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:33 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall2-3.fw.orig0000755000175000017500000015525411733011756022114 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:25 2012 PDT by vadim # # files: * firewall2-3.fw /etc/fw/firewall2-3.fw # # Compiled for iptables ge_1.2.6 # # copy of firewall2, version >= 1.2.6 # firewall2-3:NAT:20: warning: Adding of virtual address for address range is not implemented (object ext_range) # firewall2-3:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-3:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-3:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-3:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall2-3:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-3:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.10/24 192.168.1.50/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 22.22.22.23/24 22.22.22.24/24 22.22.22.25/24 22.22.22.0/32 22.22.22.1/32 22.22.22.2/32 22.22.22.3/32 22.22.22.4/32 22.22.22.5/32 22.22.22.6/32 22.22.22.7/32 22.22.22.8/32 22.22.22.9/32 22.22.22.10/32 22.22.22.11/32 22.22.22.12/32 22.22.22.13/32 22.22.22.14/32 22.22.22.15/32 22.22.22.16/32 22.22.22.17/32 22.22.22.18/32 22.22.22.19/32 22.22.22.20/32 22.22.22.21/32 22.22.22.22/32 22.22.22.23/32 22.22.22.24/32 22.22.22.25/32 22.22.22.26/32 22.22.22.27/32 22.22.22.28/32 22.22.22.29/32 22.22.22.30/32 22.22.22.31/32 22.22.22.32/32 22.22.22.33/32 22.22.22.34/32 22.22.22.35/32 22.22.22.36/32 22.22.22.37/32 22.22.22.38/32 22.22.22.39/32 22.22.22.40/32 22.22.22.41/32 22.22.22.42/32 22.22.22.43/32 22.22.22.44/32 22.22.22.45/32 22.22.22.46/32 22.22.22.47/32 22.22.22.48/32 22.22.22.49/32 22.22.22.50/32 22.22.22.51/32 22.22.22.52/32 22.22.22.53/32 22.22.22.54/32 22.22.22.55/32 22.22.22.56/32 22.22.22.57/32 22.22.22.58/32 22.22.22.59/32 22.22.22.60/32 22.22.22.61/32 22.22.22.62/32 22.22.22.63/32 22.22.22.64/32 22.22.22.65/32 22.22.22.66/32 22.22.22.67/32 22.22.22.68/32 22.22.22.69/32 22.22.22.70/32 22.22.22.71/32 22.22.22.72/32 22.22.22.73/32 22.22.22.74/32 22.22.22.75/32 22.22.22.76/32 22.22.22.77/32 22.22.22.78/32 22.22.22.79/32 22.22.22.80/32 22.22.22.81/32 22.22.22.82/32 22.22.22.83/32 22.22.22.84/32 22.22.22.85/32 22.22.22.86/32 22.22.22.87/32 22.22.22.88/32 22.22.22.89/32 22.22.22.90/32 22.22.22.91/32 22.22.22.92/32 22.22.22.93/32 22.22.22.94/32 22.22.22.95/32 22.22.22.96/32 22.22.22.97/32 22.22.22.98/32 22.22.22.99/32 22.22.22.100/32 22.22.22.101/32 22.22.22.102/32 22.22.22.103/32 22.22.22.104/32 22.22.22.105/32 22.22.22.106/32 22.22.22.107/32 22.22.22.108/32 22.22.22.109/32 22.22.22.110/32 22.22.22.111/32 22.22.22.112/32 22.22.22.113/32 22.22.22.114/32 22.22.22.115/32 22.22.22.116/32 22.22.22.117/32 22.22.22.118/32 22.22.22.119/32 22.22.22.120/32 22.22.22.121/32 22.22.22.122/32 22.22.22.123/32 22.22.22.124/32 22.22.22.125/32 22.22.22.126/32 22.22.22.127/32 22.22.22.128/32 22.22.22.129/32 22.22.22.130/32 22.22.22.131/32 22.22.22.132/32 22.22.22.133/32 22.22.22.134/32 22.22.22.135/32 22.22.22.136/32 22.22.22.137/32 22.22.22.138/32 22.22.22.139/32 22.22.22.140/32 22.22.22.141/32 22.22.22.142/32 22.22.22.143/32 22.22.22.144/32 22.22.22.145/32 22.22.22.146/32 22.22.22.147/32 22.22.22.148/32 22.22.22.149/32 22.22.22.150/32 22.22.22.151/32 22.22.22.152/32 22.22.22.153/32 22.22.22.154/32 22.22.22.155/32 22.22.22.156/32 22.22.22.157/32 22.22.22.158/32 22.22.22.159/32 22.22.22.160/32 22.22.22.161/32 22.22.22.162/32 22.22.22.163/32 22.22.22.164/32 22.22.22.165/32 22.22.22.166/32 22.22.22.167/32 22.22.22.168/32 22.22.22.169/32 22.22.22.170/32 22.22.22.171/32 22.22.22.172/32 22.22.22.173/32 22.22.22.174/32 22.22.22.175/32 22.22.22.176/32 22.22.22.177/32 22.22.22.178/32 22.22.22.179/32 22.22.22.180/32 22.22.22.181/32 22.22.22.182/32 22.22.22.183/32 22.22.22.184/32 22.22.22.185/32 22.22.22.186/32 22.22.22.187/32 22.22.22.188/32 22.22.22.189/32 22.22.22.190/32 22.22.22.191/32 22.22.22.192/32 22.22.22.193/32 22.22.22.194/32 22.22.22.195/32 22.22.22.196/32 22.22.22.197/32 22.22.22.198/32 22.22.22.199/32 22.22.22.200/32 22.22.22.201/32 22.22.22.202/32 22.22.22.203/32 22.22.22.204/32 22.22.22.205/32 22.22.22.206/32 22.22.22.207/32 22.22.22.208/32 22.22.22.209/32 22.22.22.210/32 22.22.22.211/32 22.22.22.212/32 22.22.22.213/32 22.22.22.214/32 22.22.22.215/32 22.22.22.216/32 22.22.22.217/32 22.22.22.218/32 22.22.22.219/32 22.22.22.220/32 22.22.22.221/32 22.22.22.222/32 22.22.22.223/32 22.22.22.224/32 22.22.22.225/32 22.22.22.226/32 22.22.22.227/32 22.22.22.228/32 22.22.22.229/32 22.22.22.230/32 22.22.22.231/32 22.22.22.232/32 22.22.22.233/32 22.22.22.234/32 22.22.22.235/32 22.22.22.236/32 22.22.22.237/32 22.22.22.238/32 22.22.22.239/32 22.22.22.240/32 22.22.22.241/32 22.22.22.242/32 22.22.22.243/32 22.22.22.244/32 22.22.22.245/32 22.22.22.246/32 22.22.22.247/32 22.22.22.248/32 22.22.22.249/32 22.22.22.250/32 22.22.22.251/32 22.22.22.252/32 22.22.22.253/32 22.22.22.254/32" "" update_addresses_of_interface "eth3 22.22.23.23/24 22.22.25.50/24 22.22.23.24/24" "" update_addresses_of_interface "eth2 192.168.2.1/24 192.168.2.40/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.24 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.25 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -N Cid35496X1833.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid35496X1833.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid35496X1833.0 $IPTABLES -t nat -A Cid35496X1833.0 -s 22.22.22.22 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.0 -s 22.22.23.23 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.0 -s 22.22.25.50 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.0 -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.0 -s 192.168.2.40 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.10 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.11 -j ACCEPT $IPTABLES -t nat -N Cid35496X1833.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid35496X1833.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid35496X1833.1 $IPTABLES -t nat -A Cid35496X1833.1 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.1 -s 192.168.1.20 -j ACCEPT $IPTABLES -t nat -N Cid35496X1833.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.10 -j Cid35496X1833.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.11 -j Cid35496X1833.2 $IPTABLES -t nat -A Cid35496X1833.2 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid35496X1833.2 -s 192.168.1.20 -j ACCEPT # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -N Cid35514X1833.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.10 -j Cid35514X1833.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.20 -j Cid35514X1833.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.10 -j Cid35514X1833.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.20 -j Cid35514X1833.0 $IPTABLES -t nat -A Cid35514X1833.0 -d 192.168.2.10 -j RETURN $IPTABLES -t nat -A Cid35514X1833.0 -d 192.168.2.11 -j RETURN $IPTABLES -t nat -A Cid35514X1833.0 -j ACCEPT # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.23.23 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.25.50 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -s 200.200.200.200 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.24 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.25 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.24 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.25 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 17 (NAT) # echo "Rule 17 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 # # Rule 18 (NAT) # echo "Rule 18 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.20 -j SNAT --to-source 22.22.23.24 # # Rule 19 (NAT) # echo "Rule 19 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 $IPTABLES -t nat -A OUTPUT -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 # # Rule 20 (NAT) # echo "Rule 20 (NAT)" # # firewall2-3:NAT:20: warning: Adding of virtual address for address range is not implemented (object ext_range) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.100-22.22.22.110 # # Rule 21 (NAT) # echo "Rule 21 (NAT)" # # NETMAP $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 22 (NAT) # echo "Rule 22 (NAT)" # # NETMAP $IPTABLES -t nat -A PREROUTING -d 22.22.22.0/24 -j NETMAP --to 192.168.1.0/24 # # Rule 23 (NAT) # echo "Rule 23 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 # # Rule 24 (NAT) # echo "Rule 24 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.10 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 25 (NAT) # echo "Rule 25 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 # # Rule 26 (NAT) # echo "Rule 26 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 443 -j REDIRECT --to-ports 3128 # # Rule 27 (NAT) # echo "Rule 27 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 # # Rule 28 (NAT) # echo "Rule 28 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 # # Rule 29 (NAT) # echo "Rule 29 (NAT)" # # transparent proxy rule $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -d ! 22.22.22.23 -j DNAT --to-destination 192.168.2.10 # # Rule 31 (NAT) # echo "Rule 31 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 # # Rule 32 (NAT) # echo "Rule 32 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 # # Rule 33 (NAT) # echo "Rule 33 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 34 (NAT) # echo "Rule 34 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s ! 192.168.1.10 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 35 (NAT) # echo "Rule 35 (NAT)" # $IPTABLES -t nat -N Cid35884X1833.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid35884X1833.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid35884X1833.0 $IPTABLES -t nat -A Cid35884X1833.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid35884X1833.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid35884X1833.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # # Rule 36 (NAT) # echo "Rule 36 (NAT)" # $IPTABLES -t nat -N Cid35898X1833.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -j Cid35898X1833.1 $IPTABLES -t nat -A Cid35898X1833.1 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid35898X1833.1 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -N Cid35898X1833.0 $IPTABLES -t nat -A Cid35898X1833.1 -j Cid35898X1833.0 $IPTABLES -t nat -A Cid35898X1833.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -t nat -A Cid35898X1833.0 -j SNAT --to-source 192.168.1.1 # # Rule 37 (NAT) # echo "Rule 37 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 38 (NAT) # echo "Rule 38 (NAT)" # # this is the "exception" rule # used in support req. originally $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 39 (NAT) # echo "Rule 39 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 40 (NAT) # echo "Rule 40 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 41 (NAT) # echo "Rule 41 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid35968X1833.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid35968X1833.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid35968X1833.0 $IPTABLES -t nat -A Cid35968X1833.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid35968X1833.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid35968X1833.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 42 (NAT) # echo "Rule 42 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid35982X1833.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid35982X1833.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid35982X1833.0 $IPTABLES -t nat -A Cid35982X1833.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid35982X1833.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid35982X1833.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 43 (NAT) # echo "Rule 43 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid35996X1833.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid35996X1833.0 $IPTABLES -t nat -A Cid35996X1833.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid35996X1833.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid35996X1833.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 44 (NAT) # echo "Rule 44 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 45 (NAT) # echo "Rule 45 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid36024X1833.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid36024X1833.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid36024X1833.0 $IPTABLES -t nat -A Cid36024X1833.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid36024X1833.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid36024X1833.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # # Anti-spoofing rule $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 0 -- DENY " --ulog-qthreshold 1 $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid35127X1833.0 $IPTABLES -A OUTPUT -o eth1 -j Cid35127X1833.0 $IPTABLES -A Cid35127X1833.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid35127X1833.0 -s 22.22.23.23 -j RETURN $IPTABLES -A Cid35127X1833.0 -s 22.22.25.50 -j RETURN $IPTABLES -A Cid35127X1833.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid35127X1833.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid35127X1833.0 -s 192.168.2.40 -j RETURN $IPTABLES -N Out_RULE_1_3 $IPTABLES -A Cid35127X1833.0 -j Out_RULE_1_3 $IPTABLES -A Out_RULE_1_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 1 -- DENY " --ulog-qthreshold 1 $IPTABLES -A Out_RULE_1_3 -j DROP $IPTABLES -N Cid35127X1833.1 $IPTABLES -A FORWARD -o eth1 -j Cid35127X1833.1 $IPTABLES -A Cid35127X1833.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid35127X1833.1 -j Out_RULE_1_3 # # Rule 2 (fw2i1,3) # echo "Rule 2 (fw2i1,3)" # # testing group in "interface" # this rule should be identical to rule 3 $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A In_RULE_2 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 2 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth1,eth3) # echo "Rule 3 (eth1,eth3)" # $IPTABLES -N In_RULE_3 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A In_RULE_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 3 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_3 -j DROP # # Rule 4 (eth1,eth3) # echo "Rule 4 (eth1,eth3)" # # testing choice of chains in case when several # interfaces are used and rule matches 'any' or # broadcast $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 5 (eth1,eth3) # echo "Rule 5 (eth1,eth3)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 6 (eth1,eth3) # echo "Rule 6 (eth1,eth3)" # $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid35204X1833.0 $IPTABLES -A OUTPUT -j Cid35204X1833.0 $IPTABLES -A INPUT -j Cid35204X1833.0 $IPTABLES -A FORWARD -j Cid35204X1833.0 $IPTABLES -A Cid35204X1833.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid35204X1833.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 7 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_7_3 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # # block fragments $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -p all -f -j RULE_8 $IPTABLES -A INPUT -p all -f -j RULE_8 $IPTABLES -A FORWARD -p all -f -j RULE_8 $IPTABLES -A RULE_8 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 8 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # # sends TCP RST and makes custom record # in the log $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A RULE_9 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "IDENT" --ulog-qthreshold 1 $IPTABLES -A RULE_9 -p tcp -m tcp -j REJECT --reject-with tcp-reset # # Rule 10 (global) # echo "Rule 10 (global)" # # firewall2-3:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A INPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A RULE_10 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 10 - REJECT **" --ulog-qthreshold 1 $IPTABLES -A RULE_10 -j REJECT --reject-with icmp-net-unreachable # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N Cid35252X1833.0 $IPTABLES -A INPUT -p icmp -s 192.168.2.0/24 -m state --state NEW -j Cid35252X1833.0 $IPTABLES -N RULE_11 $IPTABLES -A Cid35252X1833.0 -d 192.168.2.1 -j RULE_11 $IPTABLES -A Cid35252X1833.0 -d 192.168.2.40 -j RULE_11 $IPTABLES -A RULE_11 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 11 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_11 -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N Cid35264X1833.0 $IPTABLES -A FORWARD -d 211.11.11.11 -m state --state NEW -j Cid35264X1833.0 $IPTABLES -A Cid35264X1833.0 -s 192.168.1.10 -j ACCEPT $IPTABLES -A Cid35264X1833.0 -s 192.168.1.20 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N Cid35277X1833.0 $IPTABLES -A FORWARD -s 211.11.11.11 -m state --state NEW -j Cid35277X1833.0 $IPTABLES -A Cid35277X1833.0 -d 192.168.1.10 -j ACCEPT $IPTABLES -A Cid35277X1833.0 -d 192.168.1.20 -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -N Cid35290X1833.0 $IPTABLES -A OUTPUT -p tcp -m tcp -j Cid35290X1833.0 $IPTABLES -A INPUT -p tcp -m tcp -j Cid35290X1833.0 $IPTABLES -A FORWARD -p tcp -m tcp -j Cid35290X1833.0 $IPTABLES -A Cid35290X1833.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid35290X1833.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid35290X1833.0 -p tcp -m tcp -j REJECT --reject-with tcp-reset $IPTABLES -N Cid35290X1833.1 $IPTABLES -A OUTPUT -j Cid35290X1833.1 $IPTABLES -A INPUT -j Cid35290X1833.1 $IPTABLES -A FORWARD -j Cid35290X1833.1 $IPTABLES -A Cid35290X1833.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid35290X1833.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid35290X1833.1 -j REJECT --reject-with icmp-net-unreachable # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.2.0/24 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # $IPTABLES -N RULE_16 $IPTABLES -A INPUT -s 192.168.1.0/24 -j RULE_16 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j RULE_16 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j RULE_16 $IPTABLES -A RULE_16 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 16 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_16 -j DROP # # Rule 17 (global) # echo "Rule 17 (global)" # # host-fw2 has the same address as # one of the firewall's interfaces $IPTABLES -N RULE_17 $IPTABLES -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_17 $IPTABLES -A INPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_17 $IPTABLES -A RULE_17 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 17 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_17 -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # $IPTABLES -N Cid35340X1833.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid35340X1833.0 $IPTABLES -N RULE_18 $IPTABLES -A Cid35340X1833.0 -d 22.22.22.22 -j RULE_18 $IPTABLES -A Cid35340X1833.0 -d 22.22.23.23 -j RULE_18 $IPTABLES -A Cid35340X1833.0 -d 22.22.25.50 -j RULE_18 $IPTABLES -A Cid35340X1833.0 -d 192.168.1.1 -j RULE_18 $IPTABLES -A Cid35340X1833.0 -d 192.168.2.1 -j RULE_18 $IPTABLES -A Cid35340X1833.0 -d 192.168.2.40 -j RULE_18 $IPTABLES -N Cid35340X1833.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid35340X1833.1 $IPTABLES -A Cid35340X1833.1 -d 22.22.22.22 -j RULE_18 $IPTABLES -A Cid35340X1833.1 -d 22.22.23.23 -j RULE_18 $IPTABLES -A Cid35340X1833.1 -d 22.22.25.50 -j RULE_18 $IPTABLES -A Cid35340X1833.1 -d 192.168.1.1 -j RULE_18 $IPTABLES -A Cid35340X1833.1 -d 192.168.2.1 -j RULE_18 $IPTABLES -A Cid35340X1833.1 -d 192.168.2.40 -j RULE_18 $IPTABLES -A RULE_18 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 18 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_18 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # 'catch all' rule $IPTABLES -N RULE_19 $IPTABLES -A OUTPUT -j RULE_19 $IPTABLES -A INPUT -j RULE_19 $IPTABLES -A FORWARD -j RULE_19 $IPTABLES -A RULE_19 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 19 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_19 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:25 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/test_fw.fw.orig0000755000175000017500000004420011733011756021524 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:38 2012 PDT by vadim # # files: * test_fw.fw /etc/test_fw.fw # # Compiled for iptables (any version) # # This firewall has three interfaces. Eth0 faces outside and has a static routable address; eth1 faces inside; eth2 is connected to DMZ subnet. # Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0, DMZ is 192.168.2.0/255.255.255.0. Since DMZ used private IP address, it needs NAT. There is a mail relay host located on DMZ (object 'server on dmz'). Policy rules permit SMTP connections to it from the Internet and allow this server to connect to a host on internal network 'internal server'. All other access from DMZ to internal net is denied. To provide access to the mail relay its private address is mapped to firewall's outside interface address by NAT rule #1. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth2" for i in eth0 eth1 lo eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 fe80::20c:29ff:fed2:cca1/64 192.168.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # no need to translate # between DMZ and # internal net $IPTABLES -t nat -A POSTROUTING -s 192.168.2.0/24 -d 192.168.1.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.2.0/24 -d 192.168.1.0/24 -j ACCEPT # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # # Translate source address # for outgoing connections $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.2.0/24 -j SNAT --to-source 192.0.2.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 192.0.2.1 -j DNAT --to-destination 192.168.2.10 # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.0.2.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.2.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.2.0/24 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.0.2.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.2.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.2.0/24 -m state --state NEW -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (lo) # echo "Rule 1 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.10 --dport 53 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_4 $IPTABLES -A OUTPUT -d 192.0.2.1 -m state --state NEW -j RULE_4 $IPTABLES -A OUTPUT -d 192.168.1.1 -m state --state NEW -j RULE_4 $IPTABLES -A OUTPUT -d 192.168.2.1 -m state --state NEW -j RULE_4 $IPTABLES -A INPUT -m state --state NEW -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -A RULE_4 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # # Quickly reject attempts to connect # to ident server to avoid SMTP delays $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j REJECT $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j REJECT $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j REJECT # # Rule 6 (global) # echo "Rule 6 (global)" # # Mail relay on DMZ can accept # connections from hosts on the # Internet $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 25 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 25 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # # this rule permits a mail relay # located on DMZ to connect # to internal mail server $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.2.10 -d 192.168.1.10 --dport 25 -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # # Mail relay needs DNS and can # connect to mail servers on the # Internet $IPTABLES -A INPUT -p tcp -m tcp -m multiport -s 192.168.2.10 -d ! 192.168.1.0/24 --dports 53,25 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -s 192.168.2.10 -d ! 192.168.1.0/24 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -m multiport -s 192.168.2.10 -d ! 192.168.1.0/24 --dports 53,25 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -s 192.168.2.10 -d ! 192.168.1.0/24 --dport 53 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # # All other access from DMZ to # internal net is denied $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -s 192.168.2.0/24 -d 192.168.1.0/24 -j RULE_9 $IPTABLES -A INPUT -s 192.168.2.0/24 -d 192.168.1.0/24 -j RULE_9 $IPTABLES -A FORWARD -s 192.168.2.0/24 -d 192.168.1.0/24 -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # # This permits access from internal net # to the Internet and DMZ $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N RULE_11 $IPTABLES -A OUTPUT -j RULE_11 $IPTABLES -A INPUT -j RULE_11 $IPTABLES -A FORWARD -j RULE_11 $IPTABLES -A RULE_11 -j LOG --log-level info --log-prefix "RULE 11 -- DENY " $IPTABLES -A RULE_11 -j DROP # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_OSPF # # Rule Policy_OSPF 0 (eth1) # echo "Rule Policy_OSPF 0 (eth1)" # $IP6TABLES -N Policy_OSPF $IP6TABLES -A Policy_OSPF -i eth1 -s fe80::/10 -d ff00::/8 -j ACCEPT $IP6TABLES -A Policy_OSPF -i eth1 -s fe80::/10 -d fe80::/10 -j ACCEPT $IP6TABLES -A Policy_OSPF -o eth1 -s fe80::/10 -d ff00::/8 -j ACCEPT $IP6TABLES -A Policy_OSPF -o eth1 -s fe80::/10 -d fe80::/10 -j ACCEPT # ================ Table 'filter', rule set Policy_v6 # # Rule Policy_v6 0 (eth1) # echo "Rule Policy_v6 0 (eth1)" # $IP6TABLES -A OUTPUT -o eth1 -s fe80::/10 -d ff00::/8 -j ACCEPT # # Rule Policy_v6 1 (global) # echo "Rule Policy_v6 1 (global)" # $IP6TABLES -A OUTPUT -p 89 -j Policy_OSPF $IP6TABLES -A INPUT -p 89 -j Policy_OSPF $IP6TABLES -A FORWARD -p 89 -j Policy_OSPF } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:38 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall2-2.fw.orig0000755000175000017500000017372311733011756022114 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:23 2012 PDT by vadim # # files: * firewall2-2.fw /etc/fw/firewall2-2.fw # # Compiled for iptables 1.4.0 # # another copy of firewall2 but new iptables version # firewall2-2:NAT:20: warning: Adding of virtual address for address range is not implemented (object ext_range) # firewall2-2:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it # firewall2-2:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '12 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '13 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '14 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '20 (global)' below it # firewall2-2:Policy:25: error: Rule '25 (global)' shadows rule '26 (global)' below it # firewall2-2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-2:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall2-2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2-2:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.10/24 192.168.1.50/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 22.22.22.23/24 22.22.22.24/24 22.22.22.25/24 22.22.22.0/32 22.22.22.1/32 22.22.22.2/32 22.22.22.3/32 22.22.22.4/32 22.22.22.5/32 22.22.22.6/32 22.22.22.7/32 22.22.22.8/32 22.22.22.9/32 22.22.22.10/32 22.22.22.11/32 22.22.22.12/32 22.22.22.13/32 22.22.22.14/32 22.22.22.15/32 22.22.22.16/32 22.22.22.17/32 22.22.22.18/32 22.22.22.19/32 22.22.22.20/32 22.22.22.21/32 22.22.22.22/32 22.22.22.23/32 22.22.22.24/32 22.22.22.25/32 22.22.22.26/32 22.22.22.27/32 22.22.22.28/32 22.22.22.29/32 22.22.22.30/32 22.22.22.31/32 22.22.22.32/32 22.22.22.33/32 22.22.22.34/32 22.22.22.35/32 22.22.22.36/32 22.22.22.37/32 22.22.22.38/32 22.22.22.39/32 22.22.22.40/32 22.22.22.41/32 22.22.22.42/32 22.22.22.43/32 22.22.22.44/32 22.22.22.45/32 22.22.22.46/32 22.22.22.47/32 22.22.22.48/32 22.22.22.49/32 22.22.22.50/32 22.22.22.51/32 22.22.22.52/32 22.22.22.53/32 22.22.22.54/32 22.22.22.55/32 22.22.22.56/32 22.22.22.57/32 22.22.22.58/32 22.22.22.59/32 22.22.22.60/32 22.22.22.61/32 22.22.22.62/32 22.22.22.63/32 22.22.22.64/32 22.22.22.65/32 22.22.22.66/32 22.22.22.67/32 22.22.22.68/32 22.22.22.69/32 22.22.22.70/32 22.22.22.71/32 22.22.22.72/32 22.22.22.73/32 22.22.22.74/32 22.22.22.75/32 22.22.22.76/32 22.22.22.77/32 22.22.22.78/32 22.22.22.79/32 22.22.22.80/32 22.22.22.81/32 22.22.22.82/32 22.22.22.83/32 22.22.22.84/32 22.22.22.85/32 22.22.22.86/32 22.22.22.87/32 22.22.22.88/32 22.22.22.89/32 22.22.22.90/32 22.22.22.91/32 22.22.22.92/32 22.22.22.93/32 22.22.22.94/32 22.22.22.95/32 22.22.22.96/32 22.22.22.97/32 22.22.22.98/32 22.22.22.99/32 22.22.22.100/32 22.22.22.101/32 22.22.22.102/32 22.22.22.103/32 22.22.22.104/32 22.22.22.105/32 22.22.22.106/32 22.22.22.107/32 22.22.22.108/32 22.22.22.109/32 22.22.22.110/32 22.22.22.111/32 22.22.22.112/32 22.22.22.113/32 22.22.22.114/32 22.22.22.115/32 22.22.22.116/32 22.22.22.117/32 22.22.22.118/32 22.22.22.119/32 22.22.22.120/32 22.22.22.121/32 22.22.22.122/32 22.22.22.123/32 22.22.22.124/32 22.22.22.125/32 22.22.22.126/32 22.22.22.127/32 22.22.22.128/32 22.22.22.129/32 22.22.22.130/32 22.22.22.131/32 22.22.22.132/32 22.22.22.133/32 22.22.22.134/32 22.22.22.135/32 22.22.22.136/32 22.22.22.137/32 22.22.22.138/32 22.22.22.139/32 22.22.22.140/32 22.22.22.141/32 22.22.22.142/32 22.22.22.143/32 22.22.22.144/32 22.22.22.145/32 22.22.22.146/32 22.22.22.147/32 22.22.22.148/32 22.22.22.149/32 22.22.22.150/32 22.22.22.151/32 22.22.22.152/32 22.22.22.153/32 22.22.22.154/32 22.22.22.155/32 22.22.22.156/32 22.22.22.157/32 22.22.22.158/32 22.22.22.159/32 22.22.22.160/32 22.22.22.161/32 22.22.22.162/32 22.22.22.163/32 22.22.22.164/32 22.22.22.165/32 22.22.22.166/32 22.22.22.167/32 22.22.22.168/32 22.22.22.169/32 22.22.22.170/32 22.22.22.171/32 22.22.22.172/32 22.22.22.173/32 22.22.22.174/32 22.22.22.175/32 22.22.22.176/32 22.22.22.177/32 22.22.22.178/32 22.22.22.179/32 22.22.22.180/32 22.22.22.181/32 22.22.22.182/32 22.22.22.183/32 22.22.22.184/32 22.22.22.185/32 22.22.22.186/32 22.22.22.187/32 22.22.22.188/32 22.22.22.189/32 22.22.22.190/32 22.22.22.191/32 22.22.22.192/32 22.22.22.193/32 22.22.22.194/32 22.22.22.195/32 22.22.22.196/32 22.22.22.197/32 22.22.22.198/32 22.22.22.199/32 22.22.22.200/32 22.22.22.201/32 22.22.22.202/32 22.22.22.203/32 22.22.22.204/32 22.22.22.205/32 22.22.22.206/32 22.22.22.207/32 22.22.22.208/32 22.22.22.209/32 22.22.22.210/32 22.22.22.211/32 22.22.22.212/32 22.22.22.213/32 22.22.22.214/32 22.22.22.215/32 22.22.22.216/32 22.22.22.217/32 22.22.22.218/32 22.22.22.219/32 22.22.22.220/32 22.22.22.221/32 22.22.22.222/32 22.22.22.223/32 22.22.22.224/32 22.22.22.225/32 22.22.22.226/32 22.22.22.227/32 22.22.22.228/32 22.22.22.229/32 22.22.22.230/32 22.22.22.231/32 22.22.22.232/32 22.22.22.233/32 22.22.22.234/32 22.22.22.235/32 22.22.22.236/32 22.22.22.237/32 22.22.22.238/32 22.22.22.239/32 22.22.22.240/32 22.22.22.241/32 22.22.22.242/32 22.22.22.243/32 22.22.22.244/32 22.22.22.245/32 22.22.22.246/32 22.22.22.247/32 22.22.22.248/32 22.22.22.249/32 22.22.22.250/32 22.22.22.251/32 22.22.22.252/32 22.22.22.253/32 22.22.22.254/32" "" update_addresses_of_interface "eth3 22.22.23.23/24 22.22.25.50/24 22.22.23.24/24" "" update_addresses_of_interface "eth2 192.168.2.1/24 192.168.2.40/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.24 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.25 # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -N Cid32503X1798.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid32503X1798.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid32503X1798.0 $IPTABLES -t nat -A Cid32503X1798.0 -s 22.22.22.22 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.0 -s 22.22.23.23 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.0 -s 22.22.25.50 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.0 -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.0 -s 192.168.2.40 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.10 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.11 -j ACCEPT $IPTABLES -t nat -N Cid32503X1798.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid32503X1798.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid32503X1798.1 $IPTABLES -t nat -A Cid32503X1798.1 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.1 -s 192.168.1.20 -j ACCEPT $IPTABLES -t nat -N Cid32503X1798.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.10 -j Cid32503X1798.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.11 -j Cid32503X1798.2 $IPTABLES -t nat -A Cid32503X1798.2 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid32503X1798.2 -s 192.168.1.20 -j ACCEPT # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -N Cid32521X1798.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.10 -j Cid32521X1798.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.20 -j Cid32521X1798.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.10 -j Cid32521X1798.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.20 -j Cid32521X1798.0 $IPTABLES -t nat -A Cid32521X1798.0 -d 192.168.2.10 -j RETURN $IPTABLES -t nat -A Cid32521X1798.0 -d 192.168.2.11 -j RETURN $IPTABLES -t nat -A Cid32521X1798.0 -j ACCEPT # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.23.23 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.25.50 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -s 200.200.200.200 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.24 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.25 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.24 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.25 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 17 (NAT) # echo "Rule 17 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 # # Rule 18 (NAT) # echo "Rule 18 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.20 -j SNAT --to-source 22.22.23.24 # # Rule 19 (NAT) # echo "Rule 19 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 $IPTABLES -t nat -A OUTPUT -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 # # Rule 20 (NAT) # echo "Rule 20 (NAT)" # # firewall2-2:NAT:20: warning: Adding of virtual address for address range is not implemented (object ext_range) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.100-22.22.22.110 # # Rule 21 (NAT) # echo "Rule 21 (NAT)" # # NETMAP $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 22 (NAT) # echo "Rule 22 (NAT)" # # NETMAP $IPTABLES -t nat -A PREROUTING -d 22.22.22.0/24 -j NETMAP --to 192.168.1.0/24 # # Rule 23 (NAT) # echo "Rule 23 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 # # Rule 24 (NAT) # echo "Rule 24 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.10 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 25 (NAT) # echo "Rule 25 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 # # Rule 26 (NAT) # echo "Rule 26 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 443 -j REDIRECT --to-ports 3128 # # Rule 27 (NAT) # echo "Rule 27 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 # # Rule 28 (NAT) # echo "Rule 28 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 # # Rule 29 (NAT) # echo "Rule 29 (NAT)" # # transparent proxy rule $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -d ! 22.22.22.23 -j DNAT --to-destination 192.168.2.10 # # Rule 31 (NAT) # echo "Rule 31 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 # # Rule 32 (NAT) # echo "Rule 32 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 # # Rule 33 (NAT) # echo "Rule 33 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 34 (NAT) # echo "Rule 34 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s ! 192.168.1.10 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 35 (NAT) # echo "Rule 35 (NAT)" # $IPTABLES -t nat -N Cid32891X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid32891X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid32891X1798.0 $IPTABLES -t nat -A Cid32891X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32891X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32891X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # # Rule 36 (NAT) # echo "Rule 36 (NAT)" # $IPTABLES -t nat -N Cid32905X1798.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -j Cid32905X1798.1 $IPTABLES -t nat -A Cid32905X1798.1 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32905X1798.1 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -N Cid32905X1798.0 $IPTABLES -t nat -A Cid32905X1798.1 -j Cid32905X1798.0 $IPTABLES -t nat -A Cid32905X1798.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -t nat -A Cid32905X1798.0 -j SNAT --to-source 192.168.1.1 # # Rule 37 (NAT) # echo "Rule 37 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 38 (NAT) # echo "Rule 38 (NAT)" # # this is the "exception" rule # used in support req. originally $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 39 (NAT) # echo "Rule 39 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 40 (NAT) # echo "Rule 40 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 41 (NAT) # echo "Rule 41 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid32975X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid32975X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid32975X1798.0 $IPTABLES -t nat -A Cid32975X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32975X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32975X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 42 (NAT) # echo "Rule 42 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid32989X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid32989X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid32989X1798.0 $IPTABLES -t nat -A Cid32989X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid32989X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid32989X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 43 (NAT) # echo "Rule 43 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid33003X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid33003X1798.0 $IPTABLES -t nat -A Cid33003X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid33003X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid33003X1798.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 44 (NAT) # echo "Rule 44 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 45 (NAT) # echo "Rule 45 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid33031X1798.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid33031X1798.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid33031X1798.0 $IPTABLES -t nat -A Cid33031X1798.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid33031X1798.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid33031X1798.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # # Anti-spoofing rule # firewall2-2:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 0 -- DENY " --ulog-qthreshold 1 $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid32134X1798.0 $IPTABLES -A OUTPUT -o eth1 -j Cid32134X1798.0 $IPTABLES -A Cid32134X1798.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid32134X1798.0 -s 22.22.23.23 -j RETURN $IPTABLES -A Cid32134X1798.0 -s 22.22.25.50 -j RETURN $IPTABLES -A Cid32134X1798.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid32134X1798.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid32134X1798.0 -s 192.168.2.40 -j RETURN $IPTABLES -N Out_RULE_1_3 $IPTABLES -A Cid32134X1798.0 -j Out_RULE_1_3 $IPTABLES -A Out_RULE_1_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 1 -- DENY " --ulog-qthreshold 1 $IPTABLES -A Out_RULE_1_3 -j DROP $IPTABLES -N Cid32134X1798.1 $IPTABLES -A FORWARD -o eth1 -j Cid32134X1798.1 $IPTABLES -A Cid32134X1798.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid32134X1798.1 -j Out_RULE_1_3 # # Rule 2 (fw2i1,3) # echo "Rule 2 (fw2i1,3)" # # testing group in "interface" # this rule should be identical to rule 3 $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A In_RULE_2 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 2 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth1,eth3) # echo "Rule 3 (eth1,eth3)" # $IPTABLES -N In_RULE_3 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A In_RULE_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 3 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_3 -j DROP # # Rule 4 (eth1,eth3) # echo "Rule 4 (eth1,eth3)" # # testing choice of chains in case when several # interfaces are used and rule matches 'any' or # broadcast # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2-2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 5 (eth1,eth3) # echo "Rule 5 (eth1,eth3)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 6 (eth1,eth3) # echo "Rule 6 (eth1,eth3)" # $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid32211X1798.0 $IPTABLES -A OUTPUT -j Cid32211X1798.0 $IPTABLES -A INPUT -j Cid32211X1798.0 $IPTABLES -A FORWARD -j Cid32211X1798.0 $IPTABLES -A Cid32211X1798.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid32211X1798.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 7 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_7_3 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # # block fragments $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -p all -f -j RULE_8 $IPTABLES -A INPUT -p all -f -j RULE_8 $IPTABLES -A FORWARD -p all -f -j RULE_8 $IPTABLES -A RULE_8 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 8 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # # sends TCP RST and makes custom record # in the log $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A RULE_9 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "IDENT" --ulog-qthreshold 1 $IPTABLES -A RULE_9 -p tcp -m tcp -j REJECT --reject-with tcp-reset # # Rule 10 (global) # echo "Rule 10 (global)" # # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '12 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '13 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '14 (global)' below it # firewall2-2:Policy:10: error: Rule '10 (global)' shadows rule '20 (global)' below it # firewall2-2:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A INPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A RULE_10 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 10 - REJECT **" --ulog-qthreshold 1 $IPTABLES -A RULE_10 -j REJECT --reject-with icmp-net-unreachable # # Rule 11 (global) # echo "Rule 11 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A OUTPUT -p udp -m udp -m iprange --dst-range 192.168.1.10-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -m iprange --dst-range 192.168.1.10-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A INPUT -p udp -m udp -m iprange --src-range 192.168.1.10-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -m iprange --src-range 192.168.1.10-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A FORWARD -p udp -m udp -m iprange --src-range 222.222.222.10-222.222.222.100 --dst-range 192.168.1.10-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A FORWARD -p udp -m udp -m iprange --src-range 192.168.1.10-192.168.1.100 --dst-range 222.222.222.10-222.222.222.100 --dport 161 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94453X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94453X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94453X70161.0 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94453X70161.0 $IPTABLES -A Cid94453X70161.0 -m iprange --dst-range 192.168.1.10-192.168.1.100 -j RETURN $IPTABLES -A Cid94453X70161.0 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94436X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94436X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94436X70161.0 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94436X70161.0 $IPTABLES -A Cid94436X70161.0 -m iprange --src-range 192.168.1.10-192.168.1.100 -j RETURN $IPTABLES -A Cid94436X70161.0 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94418X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94418X70161.0 $IPTABLES -A Cid94418X70161.0 -d 192.168.1.0 -j RETURN $IPTABLES -A Cid94418X70161.0 -j ACCEPT $IPTABLES -N Cid94418X70161.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94418X70161.1 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94418X70161.1 $IPTABLES -A Cid94418X70161.1 -m iprange --dst-range 192.168.1.10-192.168.1.100 -j RETURN $IPTABLES -A Cid94418X70161.1 -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid94400X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94400X70161.0 $IPTABLES -A Cid94400X70161.0 -s 192.168.1.0 -j RETURN $IPTABLES -A Cid94400X70161.0 -j ACCEPT $IPTABLES -N Cid94400X70161.1 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid94400X70161.1 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid94400X70161.1 $IPTABLES -A Cid94400X70161.1 -m iprange --src-range 192.168.1.10-192.168.1.100 -j RETURN $IPTABLES -A Cid94400X70161.1 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using module iprange if # iptables version is >= 1.2.11 # also test for bug #2526173 $IPTABLES -N RULE_19 $IPTABLES -A INPUT -s 0.0.0.0 -j RULE_19 $IPTABLES -A OUTPUT -s 0.0.0.0 -j RULE_19 $IPTABLES -A RULE_19 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 19 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_19 -j DROP # # Rule 20 (global) # echo "Rule 20 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A INPUT -p udp -m udp -m iprange --src-range 192.168.1.1-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -m iprange --src-range 192.168.1.1-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p udp -m udp -m iprange --src-range 192.168.1.1-192.168.1.100 --dport 161 -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N Cid32259X1798.0 $IPTABLES -A INPUT -p icmp -m icmp -s 192.168.2.0/24 --icmp-type any -m state --state NEW -j Cid32259X1798.0 $IPTABLES -N RULE_21 $IPTABLES -A Cid32259X1798.0 -d 192.168.2.1 -j RULE_21 $IPTABLES -A Cid32259X1798.0 -d 192.168.2.40 -j RULE_21 $IPTABLES -A RULE_21 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 21 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_21 -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N Cid32271X1798.0 $IPTABLES -A FORWARD -d 211.11.11.11 -m state --state NEW -j Cid32271X1798.0 $IPTABLES -A Cid32271X1798.0 -s 192.168.1.10 -j ACCEPT $IPTABLES -A Cid32271X1798.0 -s 192.168.1.20 -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -N Cid32284X1798.0 $IPTABLES -A FORWARD -s 211.11.11.11 -m state --state NEW -j Cid32284X1798.0 $IPTABLES -A Cid32284X1798.0 -d 192.168.1.10 -j ACCEPT $IPTABLES -A Cid32284X1798.0 -d 192.168.1.20 -j ACCEPT # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N Cid32297X1798.0 $IPTABLES -A OUTPUT -p tcp -m tcp -j Cid32297X1798.0 $IPTABLES -A INPUT -p tcp -m tcp -j Cid32297X1798.0 $IPTABLES -A FORWARD -p tcp -m tcp -j Cid32297X1798.0 $IPTABLES -A Cid32297X1798.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid32297X1798.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid32297X1798.0 -p tcp -m tcp -j REJECT --reject-with tcp-reset $IPTABLES -N Cid32297X1798.1 $IPTABLES -A OUTPUT -j Cid32297X1798.1 $IPTABLES -A INPUT -j Cid32297X1798.1 $IPTABLES -A FORWARD -j Cid32297X1798.1 $IPTABLES -A Cid32297X1798.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid32297X1798.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid32297X1798.1 -j REJECT --reject-with icmp-net-unreachable # # Rule 25 (global) # echo "Rule 25 (global)" # # firewall2-2:Policy:25: error: Rule '25 (global)' shadows rule '26 (global)' below it $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.2.0/24 -m state --state NEW -j ACCEPT # # Rule 26 (global) # echo "Rule 26 (global)" # $IPTABLES -N RULE_26 $IPTABLES -A INPUT -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A RULE_26 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 26 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_26 -j DROP # # Rule 27 (global) # echo "Rule 27 (global)" # # host-fw2 has the same address as # one of the firewall's interfaces $IPTABLES -N RULE_27 $IPTABLES -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_27 $IPTABLES -A INPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_27 $IPTABLES -A RULE_27 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 27 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_27 -j ACCEPT # # Rule 28 (global) # echo "Rule 28 (global)" # $IPTABLES -N Cid32347X1798.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid32347X1798.0 $IPTABLES -N RULE_28 $IPTABLES -A Cid32347X1798.0 -d 22.22.22.22 -j RULE_28 $IPTABLES -A Cid32347X1798.0 -d 22.22.23.23 -j RULE_28 $IPTABLES -A Cid32347X1798.0 -d 22.22.25.50 -j RULE_28 $IPTABLES -A Cid32347X1798.0 -d 192.168.1.1 -j RULE_28 $IPTABLES -A Cid32347X1798.0 -d 192.168.2.1 -j RULE_28 $IPTABLES -A Cid32347X1798.0 -d 192.168.2.40 -j RULE_28 $IPTABLES -N Cid32347X1798.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid32347X1798.1 $IPTABLES -A Cid32347X1798.1 -d 22.22.22.22 -j RULE_28 $IPTABLES -A Cid32347X1798.1 -d 22.22.23.23 -j RULE_28 $IPTABLES -A Cid32347X1798.1 -d 22.22.25.50 -j RULE_28 $IPTABLES -A Cid32347X1798.1 -d 192.168.1.1 -j RULE_28 $IPTABLES -A Cid32347X1798.1 -d 192.168.2.1 -j RULE_28 $IPTABLES -A Cid32347X1798.1 -d 192.168.2.40 -j RULE_28 $IPTABLES -A RULE_28 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 28 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_28 -j ACCEPT # # Rule 29 (global) # echo "Rule 29 (global)" # # 'catch all' rule $IPTABLES -N RULE_29 $IPTABLES -A OUTPUT -j RULE_29 $IPTABLES -A INPUT -j RULE_29 $IPTABLES -A FORWARD -j RULE_29 $IPTABLES -A RULE_29 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 29 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_29 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:23 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-prolog-top.fw.orig0000755000175000017500000002754611733011756024656 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:33 2012 PDT by vadim # # files: * firewall-ipv6-prolog-top.fw /etc/firewall-ipv6-prolog-top.fw # # Compiled for iptables (any version) # # Policy is configured as dual address family. Prolog is on top of the policy FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" echo "This is prolog" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i + -m state --state NEW -j ACCEPT # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IP6TABLES -N drop_invalid $IP6TABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A INPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A FORWARD -m state --state INVALID -j drop_invalid $IP6TABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IP6TABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IP6TABLES -A INPUT -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -i + -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:33 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-ipt-reset-prolog-top.fw.orig0000755000175000017500000003066311733011756026562 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:29 2012 PDT by vadim # # files: * firewall-ipv6-ipt-reset-prolog-top.fw /etc/firewall-ipv6-ipt-reset-prolog-top.fw # # Compiled for iptables (any version) # # Policy is configured as dual address family. Usigng iptables-restore. Prolog is on top of the policy FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" echo "This is prolog" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A INPUT -m state --state NEW -j ACCEPT " echo "-A FORWARD -i + -m state --state NEW -j ACCEPT " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo "-A INPUT -m state --state NEW -j ACCEPT " echo "-A FORWARD -i + -m state --state NEW -j ACCEPT " # echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:29 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall36-1.fw.orig0000755000175000017500000002645111733011756022175 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:43 2012 PDT by vadim # # files: * firewall36-1.fw /etc/firewall36-1.fw # # Compiled for iptables (any version) # # Testing routing configuration where routing rules do not install default route FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth2" for i in eth0 eth1 lo eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.0.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 192.168.2.0/24 via 192.168.1.254 dev eth1 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:43 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall13.fw.orig0000755000175000017500000002530411733011756022026 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:11 2012 PDT by vadim # # files: * firewall13.fw /etc/fw/firewall13.fw # # Compiled for iptables (any version) # # Testing empty groups thing # firewall13:NAT:0: warning: Empty group or address table object 'empty Ogroup' # firewall13:NAT:0: warning: After removal of all empty groups and address table objects rule element OSrc becomes 'any' in the rule 0 (NAT) # Dropping rule 0 (NAT) because option 'Ignore rules with empty groups' is in effect # firewall13:NAT:1: warning: Empty group or address table object 'empty Ogroup2' # firewall13:NAT:1: warning: After removal of all empty groups and address table objects rule element OSrc becomes 'any' in the rule 1 (NAT) # Dropping rule 1 (NAT) because option 'Ignore rules with empty groups' is in effect # firewall13:Policy:0: warning: Empty group or address table object 'empty Ogroup2' # firewall13:Policy:0: warning: After removal of all empty groups and address table objects rule element Src becomes 'any' in the rule 0 (global) # Dropping rule 0 (global) because option 'Ignore rules with empty groups' is in effect # firewall13:Policy:1: warning: Empty group or address table object 'empty Sgroup' # firewall13:Policy:1: warning: After removal of all empty groups and address table objects rule element Srv becomes 'any' in the rule 1 (global) # Dropping rule 1 (global) because option 'Ignore rules with empty groups' is in effect FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 22.22.22.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 $IPTABLES -A OUTPUT -j RULE_2 $IPTABLES -A INPUT -j RULE_2 $IPTABLES -A FORWARD -j RULE_2 $IPTABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A RULE_2 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:11 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/linux-1.fw.orig0000755000175000017500000006302511733011756021354 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v4.2.0.3425 # # Generated Fri Jan 7 13:12:17 2011 PST by vadim # # files: * linux-1.fw # # Compiled for iptables (any version) # # # linux-1:to_fw:: warning: ignoring cluster rule set "to_fw" because member firewall "linux-1" has rule set with the same name. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" test -x "$LOGGER" && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 $PGM /dev/null 2>&1; test $? = 127 && { echo "$PGM not found" exit 1 } } check_tools() { find_program $IPTABLES find_program $MODPROBE find_program $IP find_program $VCONFIG } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth0.100" for i in eth0 eth1 lo eth0.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_vlans_of_interface "eth0 eth0.100" clear_vlans_except_known eth0.100@eth0 update_addresses_of_interface "eth0 172.24.0.2/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.2/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0.100 192.168.100.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.2 --dport 22 -j DNAT --to-destination 192.168.1.100 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.100.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 172.24.0.1 --dport 22 -j DNAT --to-destination 192.168.1.100 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 10/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 10/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 172.24.0.3 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.2 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.100.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 7 (global) # echo "Rule 7 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A OUTPUT -d 172.24.0.1 -j DROP $IPTABLES -A OUTPUT -d 172.24.0.2 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.1 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.2 -j DROP $IPTABLES -A OUTPUT -d 192.168.100.1 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # # fw is part of any $IPTABLES -N Cid997025X96143.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid997025X96143.0 $IPTABLES -A Cid997025X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid997025X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # fw is NOT part of any $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # fw is NOT part of any $IPTABLES -N Cid143289X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143289X96143.0 $IPTABLES -A Cid143289X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid143289X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid143289X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # fw is NOT part of any $IPTABLES -N Cid1946680X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1946680X96143.0 $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1946680X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid1946680X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 14 (eth0) # echo "Rule 14 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid378955X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.0 $IPTABLES -A Cid378955X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid378955X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -N Cid378955X96143.1 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid378955X96143.1 $IPTABLES -A Cid378955X96143.1 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid378955X96143.1 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid378955X96143.1 -s 192.168.100.1 -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid1801407X96143.0 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid1801407X96143.0 $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.1 -j ACCEPT $IPTABLES -A Cid1801407X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid1801407X96143.0 -s 192.168.100.1 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # fw is NOT part of any $IPTABLES -N Cid143343X96143.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid143343X96143.0 $IPTABLES -A Cid143343X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid143343X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid2241935X96143.0 $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.0 $IPTABLES -A Cid2241935X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -N Cid2241935X96143.1 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241935X96143.1 $IPTABLES -A Cid2241935X96143.1 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241935X96143.1 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 18 (eth0) # echo "Rule 18 (eth0)" # # fw is NOT part of any $IPTABLES -N Cid2241981X96143.0 $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j Cid2241981X96143.0 $IPTABLES -A Cid2241981X96143.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid2241981X96143.0 -s 192.168.100.1 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -s 172.24.0.3 --dport 22 -m state --state NEW -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using interface of another cluster in the rule $IPTABLES -N Cid8228X45618.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid8228X45618.0 $IPTABLES -A Cid8228X45618.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.2 -j ACCEPT $IPTABLES -A Cid8228X45618.0 -s 192.168.1.100 -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # $IPTABLES -N Cid147047X84105.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid147047X84105.0 $IPTABLES -A Cid147047X84105.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.2 -j ACCEPT $IPTABLES -A Cid147047X84105.0 -d 192.168.1.100 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N RULE_21 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_21 $IPTABLES -A INPUT -m state --state NEW -j RULE_21 $IPTABLES -A FORWARD -m state --state NEW -j RULE_21 $IPTABLES -A RULE_21 -j LOG --log-level info --log-prefix "RULE 21 -- DENY " $IPTABLES -A RULE_21 -j DROP # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N RULE_22 $IPTABLES -A OUTPUT -j RULE_22 $IPTABLES -A INPUT -j RULE_22 $IPTABLES -A FORWARD -j RULE_22 $IPTABLES -A RULE_22 -j LOG --log-level info --log-prefix "RULE 22 -- DENY " $IPTABLES -A RULE_22 -j DROP # ============== ROUTING RULES ============== TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" (umask 077 && mkdir $TMPDIRNAME) || exit 1 # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules (IFS=" "; for route in $oldRoutes; do (IFS=' '; $IP route add $route); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) oldRoutes=$($IP route show | sort -k 2) echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 172.24.1.0/24 via 172.24.0.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Fri Jan 7 13:12:17 2011 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall37.fw.orig0000755000175000017500000013507411733011756022042 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:45 2012 PDT by vadim # # files: * firewall37.fw /etc/fw/firewall37.fw # # Compiled for iptables (any version) # # testing TAG and CLASSIFY rules # normal script mode (not using iptables-restore) # firewall37:mangle_rules:7: warning: Empty group or address table object 'empty Ogroup' # firewall37:mangle_rules:7: warning: After removal of all empty groups and address table objects rule element Src becomes 'any' in the rule mangle_rules 7 (global) # Dropping rule mangle_rules 7 (global) because option 'Ignore rules with empty groups' is in effect FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.22/24" "" update_addresses_of_interface "eth1 22.22.23.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', automatic rules $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark $IPTABLES -t mangle -A OUTPUT -j CONNMARK --restore-mark # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -s 22.22.23.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.22 -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A OUTPUT -j ACCEPT $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j ACCEPT $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -j ACCEPT # ================ Table 'mangle', rule set mymark # # Rule mymark 0 (global) # echo "Rule mymark 0 (global)" # $IPTABLES -N mymark -t mangle $IPTABLES -t mangle -A mymark -d 192.168.2.0/24 -m state --state NEW -j MARK --set-mark 16 # # Rule mymark 1 (global) # echo "Rule mymark 1 (global)" # $IPTABLES -t mangle -A mymark -m state --state NEW -j MARK --set-mark 2 # ================ Table 'mangle', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 5 (eth1) # echo "Rule 5 (eth1)" # $IPTABLES -N Cid43501X5007.0 -t mangle $IPTABLES -t mangle -A OUTPUT -o eth1 -s 22.22.23.22 -m state --state NEW -j Cid43501X5007.0 $IPTABLES -t mangle -A Cid43501X5007.0 -p 50 -j MARK --set-mark 16 $IPTABLES -t mangle -A Cid43501X5007.0 -p ah -j MARK --set-mark 16 # # Rule 6 (eth1) # echo "Rule 6 (eth1)" # $IPTABLES -N Cid43518X5007.0 -t mangle $IPTABLES -t mangle -A OUTPUT -o eth1 -s 22.22.23.22 -m state --state NEW -j Cid43518X5007.0 $IPTABLES -t mangle -A Cid43518X5007.0 -p 50 -j MARK --set-mark 16 $IPTABLES -t mangle -A Cid43518X5007.0 -p ah -j MARK --set-mark 16 # # Rule 7 (eth1) # echo "Rule 7 (eth1)" # $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 8 (eth1) # echo "Rule 8 (eth1)" # $IPTABLES -N Cid43554X5007.0 -t mangle $IPTABLES -t mangle -A OUTPUT -o eth1 -s 22.22.23.22 -j Cid43554X5007.0 $IPTABLES -t mangle -A Cid43554X5007.0 -p 50 -j MARK --set-mark 16 $IPTABLES -t mangle -A Cid43554X5007.0 -p ah -j MARK --set-mark 16 # # Rule 9 (eth1) # echo "Rule 9 (eth1)" # $IPTABLES -N Cid43571X5007.0 -t mangle $IPTABLES -t mangle -A OUTPUT -o eth1 -s 22.22.23.22 -j Cid43571X5007.0 $IPTABLES -t mangle -A Cid43571X5007.0 -p 50 -j MARK --set-mark 16 $IPTABLES -t mangle -A Cid43571X5007.0 -p ah -j MARK --set-mark 16 # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -j MARK --set-mark 16 # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N Cid43BBCC139745.0 -t mangle $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -t mangle -A Cid43BBCC139745.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid43BBCC139745.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid43BBCC139745.0 -j MARK --set-mark 16 # # Rule 12 (eth1) # echo "Rule 12 (eth1)" # $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 13 (eth1) # echo "Rule 13 (eth1)" # $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 14 (eth1) # echo "Rule 14 (eth1)" # $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 16 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j MARK --set-mark 16 # # Rule 15 (global) # echo "Rule 15 (global)" # # using CONNMARK $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 16 (global) # echo "Rule 16 (global)" # # using CONNMARK $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 17 (global) # echo "Rule 17 (global)" # # using CONNMARK $IPTABLES -N Cid4483A4DF1810.0 -t mangle $IPTABLES -t mangle -A OUTPUT -p 50 -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -t mangle -A OUTPUT -p ah -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -t mangle -A PREROUTING -p 50 -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -t mangle -A PREROUTING -p ah -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -t mangle -A Cid4483A4DF1810.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid4483A4DF1810.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid4483A4DF1810.0 -j MARK --set-mark 10 $IPTABLES -t mangle -A Cid4483A4DF1810.0 -j CONNMARK --save-mark # # Rule 18 (eth1) # echo "Rule 18 (eth1)" # # using CONNMARK $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A PREROUTING -i eth1 -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -i eth1 -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 19 (eth1) # echo "Rule 19 (eth1)" # # using CONNMARK $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -o eth1 -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A OUTPUT -o eth1 -p ah -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A POSTROUTING -o eth1 -p 50 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A POSTROUTING -o eth1 -p ah -m state --state NEW -j CONNMARK --save-mark # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -t mangle -A POSTROUTING -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -t mangle -A POSTROUTING -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N Cid451E56936383.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -j Cid451E56936383.0 $IPTABLES -t mangle -A Cid451E56936383.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid451E56936383.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid451E56936383.0 -j CLASSIFY --set-class 1:2 # # Rule 25 (global) # echo "Rule 25 (global)" # $IPTABLES -N Cid451E56A46383.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -j Cid451E56A46383.0 $IPTABLES -t mangle -A Cid451E56A46383.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid451E56A46383.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid451E56A46383.0 -j CLASSIFY --set-class 1:2 # # Rule 26 (eth1) # echo "Rule 26 (eth1)" # $IPTABLES -t mangle -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 27 (eth1) # echo "Rule 27 (eth1)" # $IPTABLES -t mangle -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 28 (eth1) # echo "Rule 28 (eth1)" # $IPTABLES -t mangle -A POSTROUTING -o ! eth1 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 29 (eth1) # echo "Rule 29 (eth1)" # $IPTABLES -t mangle -A POSTROUTING -o ! eth1 -s 192.168.1.0/24 -j CLASSIFY --set-class 1:2 # # Rule 30 (global) # echo "Rule 30 (global)" # $IPTABLES -t mangle -A POSTROUTING -s 22.22.23.22 -j CLASSIFY --set-class 1:2 $IPTABLES -t mangle -A POSTROUTING -s 192.168.1.22 -j CLASSIFY --set-class 1:2 $IPTABLES -t mangle -A POSTROUTING -s 192.168.2.1 -j CLASSIFY --set-class 1:2 # # Rule 31 (global) # echo "Rule 31 (global)" # # testing for bug #1618381 # classify action is non-terminating # in this firewall object $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j CLASSIFY --set-class 1:10 # # Rule 32 (eth0) # echo "Rule 32 (eth0)" # # second rule for bug #1618381 $IPTABLES -t mangle -A POSTROUTING -o eth0 -j CLASSIFY --set-class 1:11 # # Rule 33 (global) # echo "Rule 33 (global)" # # testing for bug #1618381 $IPTABLES -N Cid459A026219324.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j Cid459A026219324.0 $IPTABLES -t mangle -A Cid459A026219324.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid459A026219324.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid459A026219324.0 -j CLASSIFY --set-class 1:10 # # Rule 34 (global) # echo "Rule 34 (global)" # # testing for bug #1618381 $IPTABLES -N Cid459A5AFB19324.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -p icmp -m icmp --icmp-type 3 -j Cid459A5AFB19324.0 $IPTABLES -t mangle -A POSTROUTING -p tcp -m tcp --dport 80 -j Cid459A5AFB19324.0 $IPTABLES -t mangle -A Cid459A5AFB19324.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -t mangle -A Cid459A5AFB19324.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -t mangle -A Cid459A5AFB19324.0 -j CLASSIFY --set-class 1:10 # # Rule 35 (eth0) # echo "Rule 35 (eth0)" # # bug #1618381 # this rule uses multiport # and has to be split because # of that $IPTABLES -t mangle -A POSTROUTING -o eth0 -p tcp -m tcp --dport 10000:11000 -j CLASSIFY --set-class 1:11 $IPTABLES -t mangle -A POSTROUTING -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j CLASSIFY --set-class 1:11 $IPTABLES -t mangle -A POSTROUTING -o eth0 -p udp -m udp -m multiport --dports 53,161 -j CLASSIFY --set-class 1:11 # # Rule 37 (global) # echo "Rule 37 (global)" # $IPTABLES -t mangle -A PREROUTING -j mymark $IPTABLES -t mangle -A POSTROUTING -j mymark $IPTABLES -t mangle -A FORWARD -j mymark # ================ Table 'mangle', rule set mangle_rules # # Rule mangle_rules 0 (global) # echo "Rule mangle_rules 0 (global)" # $IPTABLES -t mangle -A OUTPUT -m mark ! --mark 0 -m state --state NEW -j ACCEPT $IPTABLES -t mangle -A INPUT -m mark ! --mark 0 -m state --state NEW -j ACCEPT $IPTABLES -t mangle -A PREROUTING -m mark ! --mark 0 -m state --state NEW -j ACCEPT # # Rule mangle_rules 1 (global) # echo "Rule mangle_rules 1 (global)" # $IPTABLES -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j MARK --set-mark 1 $IPTABLES -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -m state --state NEW -j MARK --set-mark 1 $IPTABLES -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW -j CONNMARK --save-mark $IPTABLES -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -m state --state NEW -j CONNMARK --save-mark # # Rule mangle_rules 2 (global) # echo "Rule mangle_rules 2 (global)" # $IPTABLES -t mangle -A POSTROUTING -m mark --mark 1 -j CLASSIFY --set-class 1:12 # # Rule mangle_rules 4 (global) # echo "Rule mangle_rules 4 (global)" # $IPTABLES -t mangle -A INPUT -s 72.55.148.116 -m mark --mark 1 -m state --state NEW -j ACCEPT $IPTABLES -t mangle -A PREROUTING -s 72.55.148.116 -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 5 (global) # echo "Rule mangle_rules 5 (global)" # $IPTABLES -t mangle -A INPUT -s 6bone.net -m mark --mark 1 -m state --state NEW -j ACCEPT $IPTABLES -t mangle -A PREROUTING -s 6bone.net -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 6 (global) # echo "Rule mangle_rules 6 (global)" # $IPTABLES -N Cid122277X13558.0 -t mangle $IPTABLES -t mangle -A INPUT -m mark --mark 1 -m state --state NEW -j Cid122277X13558.0 $IPTABLES -t mangle -A Cid122277X13558.0 -s 6bone.net -j ACCEPT $IPTABLES -t mangle -A Cid122277X13558.0 -s ny6ix.net -j ACCEPT $IPTABLES -N Cid122277X13558.1 -t mangle $IPTABLES -t mangle -A PREROUTING -m mark --mark 1 -m state --state NEW -j Cid122277X13558.1 $IPTABLES -t mangle -A Cid122277X13558.1 -s 6bone.net -j ACCEPT $IPTABLES -t mangle -A Cid122277X13558.1 -s ny6ix.net -j ACCEPT # # Rule mangle_rules 8 (global) # echo "Rule mangle_rules 8 (global)" # $IPTABLES -t mangle -A OUTPUT -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 9 (global) # echo "Rule mangle_rules 9 (global)" # $IPTABLES -t mangle -A OUTPUT -s 22.22.23.22 -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 10 (global) # echo "Rule mangle_rules 10 (global)" # $IPTABLES -N Cid207332X13558.0 -t mangle $IPTABLES -t mangle -A OUTPUT -m mark --mark 1 -m state --state NEW -j Cid207332X13558.0 $IPTABLES -t mangle -A Cid207332X13558.0 -d 22.22.23.22 -j ACCEPT $IPTABLES -t mangle -A Cid207332X13558.0 -d 192.168.1.22 -j ACCEPT $IPTABLES -t mangle -A Cid207332X13558.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -t mangle -A INPUT -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 11 (global) # echo "Rule mangle_rules 11 (global)" # $IPTABLES -t mangle -A PREROUTING -i + -s ! 192.168.1.0/24 -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 12 (global) # echo "Rule mangle_rules 12 (global)" # $IPTABLES -t mangle -A PREROUTING -i + -s ! 1.1.1.1 -m mark --mark 1 -m state --state NEW -j ACCEPT # # Rule mangle_rules 13 (global) # echo "Rule mangle_rules 13 (global)" # $IPTABLES -N Cid480281X13558.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i + -m mark --mark 1 -m state --state NEW -j Cid480281X13558.0 $IPTABLES -t mangle -A Cid480281X13558.0 -s 72.55.148.116 -j RETURN $IPTABLES -t mangle -A Cid480281X13558.0 -j ACCEPT # # Rule mangle_rules 14 (global) # echo "Rule mangle_rules 14 (global)" # $IPTABLES -N Cid480300X13558.0 -t mangle $IPTABLES -t mangle -A PREROUTING -i + -m mark --mark 1 -m state --state NEW -j Cid480300X13558.0 $IPTABLES -t mangle -A Cid480300X13558.0 -s 6bone.net -j RETURN $IPTABLES -t mangle -A Cid480300X13558.0 -j ACCEPT # # Rule mangle_rules 15 (global) # echo "Rule mangle_rules 15 (global)" # # rules in mangle-only ruleset with action # Accept normally go to PREROUTING, # but if direction is set to outbound, # they go to POSTROUTING. This is just # a convention since there is no better # criteria as to how to tell the compiler # that such rule should be placed in # POSTROUTING. $IPTABLES -N Cid43052X80179.0 -t mangle $IPTABLES -t mangle -A POSTROUTING -o + -m mark --mark 1 -m state --state NEW -j Cid43052X80179.0 $IPTABLES -t mangle -A Cid43052X80179.0 -s 6bone.net -j ACCEPT $IPTABLES -t mangle -A Cid43052X80179.0 -s ny6ix.net -j ACCEPT # ================ Table 'filter', rule set mymark # # Rule mymark 0 (global) # echo "Rule mymark 0 (global)" # $IPTABLES -N mymark $IPTABLES -A mymark -d 192.168.2.0/24 -m state --state NEW -j ACCEPT # # Rule mymark 1 (global) # echo "Rule mymark 1 (global)" # $IPTABLES -A mymark -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p ah -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j RULE_1 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j RULE_1 $IPTABLES -A INPUT -p 50 -m state --state NEW -j RULE_1 $IPTABLES -A INPUT -p ah -m state --state NEW -j RULE_1 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j RULE_1 $IPTABLES -A FORWARD -p ah -m state --state NEW -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- ACCEPT " $IPTABLES -A RULE_1 -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid483502D710047.0 $IPTABLES -A INPUT -p 50 -m state --state NEW -j Cid483502D710047.0 $IPTABLES -A INPUT -p ah -m state --state NEW -j Cid483502D710047.0 $IPTABLES -A Cid483502D710047.0 -s 22.22.23.22 -j ACCEPT $IPTABLES -A Cid483502D710047.0 -s 192.168.1.22 -j ACCEPT $IPTABLES -A Cid483502D710047.0 -s 192.168.2.1 -j ACCEPT $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p ah -m state --state NEW -j ACCEPT # # Rule 3 (eth1) # echo "Rule 3 (eth1)" # $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid483502E810047.0 $IPTABLES -A INPUT -p 50 -m state --state NEW -j Cid483502E810047.0 $IPTABLES -A INPUT -p ah -m state --state NEW -j Cid483502E810047.0 $IPTABLES -N RULE_4 $IPTABLES -A Cid483502E810047.0 -s 22.22.23.22 -j RULE_4 $IPTABLES -A Cid483502E810047.0 -s 192.168.1.22 -j RULE_4 $IPTABLES -A Cid483502E810047.0 -s 192.168.2.1 -j RULE_4 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j RULE_4 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level info --log-prefix "RULE 4 -- ACCEPT " $IPTABLES -A RULE_4 -j ACCEPT # # Rule 5 (eth1) # echo "Rule 5 (eth1)" # $IPTABLES -N Cid43501X5007.0 $IPTABLES -A OUTPUT -o eth1 -s 22.22.23.22 -m state --state NEW -j Cid43501X5007.0 $IPTABLES -A Cid43501X5007.0 -p 50 -j ACCEPT $IPTABLES -A Cid43501X5007.0 -p ah -j ACCEPT # # Rule 6 (eth1) # echo "Rule 6 (eth1)" # $IPTABLES -N Cid43518X5007.0 $IPTABLES -A OUTPUT -o eth1 -s 22.22.23.22 -m state --state NEW -j Cid43518X5007.0 $IPTABLES -A Cid43518X5007.0 -p 50 -j ACCEPT $IPTABLES -A Cid43518X5007.0 -p ah -j ACCEPT # # Rule 7 (eth1) # echo "Rule 7 (eth1)" # $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 8 (eth1) # echo "Rule 8 (eth1)" # $IPTABLES -N Cid43554X5007.0 $IPTABLES -A OUTPUT -o eth1 -s 22.22.23.22 -j Cid43554X5007.0 $IPTABLES -A Cid43554X5007.0 -p 50 -j ACCEPT $IPTABLES -A Cid43554X5007.0 -p ah -j ACCEPT # # Rule 9 (eth1) # echo "Rule 9 (eth1)" # $IPTABLES -N Cid43571X5007.0 $IPTABLES -A OUTPUT -o eth1 -s 22.22.23.22 -j Cid43571X5007.0 $IPTABLES -A Cid43571X5007.0 -p 50 -j ACCEPT $IPTABLES -A Cid43571X5007.0 -p ah -j ACCEPT # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # $IPTABLES -A OUTPUT -o eth1 -p 50 -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N Cid43BBCC139745.0 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -A INPUT -p 50 -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -A INPUT -p ah -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -A FORWARD -p ah -m state --state NEW -j Cid43BBCC139745.0 $IPTABLES -A Cid43BBCC139745.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid43BBCC139745.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_11_3 $IPTABLES -A Cid43BBCC139745.0 -j RULE_11_3 $IPTABLES -A RULE_11_3 -j LOG --log-level info --log-prefix "RULE 11 -- ACCEPT " $IPTABLES -A RULE_11_3 -j ACCEPT # # Rule 12 (eth1) # echo "Rule 12 (eth1)" # $IPTABLES -A INPUT -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 13 (eth1) # echo "Rule 13 (eth1)" # $IPTABLES -A INPUT -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 14 (eth1) # echo "Rule 14 (eth1)" # $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # using CONNMARK $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p ah -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # using CONNMARK $IPTABLES -N RULE_16 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j RULE_16 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j RULE_16 $IPTABLES -A INPUT -p 50 -m state --state NEW -j RULE_16 $IPTABLES -A INPUT -p ah -m state --state NEW -j RULE_16 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j RULE_16 $IPTABLES -A FORWARD -p ah -m state --state NEW -j RULE_16 $IPTABLES -A RULE_16 -j LOG --log-level info --log-prefix "RULE 16 -- ACCEPT " $IPTABLES -A RULE_16 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # using CONNMARK $IPTABLES -N Cid4483A4DF1810.0 $IPTABLES -A OUTPUT -p 50 -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -A OUTPUT -p ah -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -A INPUT -p 50 -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -A INPUT -p ah -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -A FORWARD -p 50 -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -A FORWARD -p ah -m state --state NEW -j Cid4483A4DF1810.0 $IPTABLES -A Cid4483A4DF1810.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid4483A4DF1810.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_17_3 $IPTABLES -A Cid4483A4DF1810.0 -j RULE_17_3 $IPTABLES -A RULE_17_3 -j LOG --log-level info --log-prefix "RULE 17 -- ACCEPT " $IPTABLES -A RULE_17_3 -j ACCEPT # # Rule 18 (eth1) # echo "Rule 18 (eth1)" # # using CONNMARK $IPTABLES -A INPUT -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 19 (eth1) # echo "Rule 19 (eth1)" # # using CONNMARK $IPTABLES -A OUTPUT -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p ah -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p 50 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth1 -p ah -m state --state NEW -j ACCEPT # # Rule 20 (global) # echo "Rule 20 (global)" # # tag 0 matches packet that has not been marked yet. $IPTABLES -A OUTPUT -m mark ! --mark 0 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -m mark ! --mark 0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -m mark ! --mark 0 -m state --state NEW -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.2.10 --dport 80 -j QUEUE $IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.2.10 --dport 80 -j QUEUE # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -N RULE_23 $IPTABLES -A INPUT -s 192.168.1.0/24 -j RULE_23 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j RULE_23 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j RULE_23 $IPTABLES -A RULE_23 -j LOG --log-level info --log-prefix "RULE 23 -- ACCEPT " $IPTABLES -A RULE_23 -j ACCEPT # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N Cid451E56936383.0 $IPTABLES -A OUTPUT -j Cid451E56936383.0 $IPTABLES -A INPUT -j Cid451E56936383.0 $IPTABLES -A FORWARD -j Cid451E56936383.0 $IPTABLES -A Cid451E56936383.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid451E56936383.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid451E56936383.0 -j ACCEPT # # Rule 25 (global) # echo "Rule 25 (global)" # $IPTABLES -N Cid451E56A46383.0 $IPTABLES -A OUTPUT -j Cid451E56A46383.0 $IPTABLES -A INPUT -j Cid451E56A46383.0 $IPTABLES -A FORWARD -j Cid451E56A46383.0 $IPTABLES -A Cid451E56A46383.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid451E56A46383.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_25_3 $IPTABLES -A Cid451E56A46383.0 -j RULE_25_3 $IPTABLES -A RULE_25_3 -j LOG --log-level info --log-prefix "RULE 25 -- ACCEPT " $IPTABLES -A RULE_25_3 -j ACCEPT # # Rule 26 (eth1) # echo "Rule 26 (eth1)" # $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -o eth1 -s 192.168.1.0/24 -j ACCEPT # # Rule 27 (eth1) # echo "Rule 27 (eth1)" # $IPTABLES -N In_RULE_27 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_27 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_27 $IPTABLES -A In_RULE_27 -j LOG --log-level info --log-prefix "RULE 27 -- ACCEPT " $IPTABLES -A In_RULE_27 -j ACCEPT $IPTABLES -N Out_RULE_27 $IPTABLES -A OUTPUT -o eth1 -s 192.168.1.0/24 -j Out_RULE_27 $IPTABLES -A FORWARD -o eth1 -s 192.168.1.0/24 -j Out_RULE_27 $IPTABLES -A Out_RULE_27 -j LOG --log-level info --log-prefix "RULE 27 -- ACCEPT " $IPTABLES -A Out_RULE_27 -j ACCEPT # # Rule 28 (eth1) # echo "Rule 28 (eth1)" # $IPTABLES -A INPUT -i ! eth1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -i ! eth1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A OUTPUT -o ! eth1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A FORWARD -o ! eth1 -s 192.168.1.0/24 -j ACCEPT # # Rule 29 (eth1) # echo "Rule 29 (eth1)" # $IPTABLES -N In_RULE_29 $IPTABLES -A INPUT -i ! eth1 -s 192.168.1.0/24 -j In_RULE_29 $IPTABLES -A FORWARD -i ! eth1 -s 192.168.1.0/24 -j In_RULE_29 $IPTABLES -A In_RULE_29 -j LOG --log-level info --log-prefix "RULE 29 -- ACCEPT " $IPTABLES -A In_RULE_29 -j ACCEPT $IPTABLES -N Out_RULE_29 $IPTABLES -A OUTPUT -o ! eth1 -s 192.168.1.0/24 -j Out_RULE_29 $IPTABLES -A FORWARD -o ! eth1 -s 192.168.1.0/24 -j Out_RULE_29 $IPTABLES -A Out_RULE_29 -j LOG --log-level info --log-prefix "RULE 29 -- ACCEPT " $IPTABLES -A Out_RULE_29 -j ACCEPT # # Rule 31 (global) # echo "Rule 31 (global)" # # testing for bug #1618381 # classify action is non-terminating # in this firewall object $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j ACCEPT # # Rule 32 (eth0) # echo "Rule 32 (eth0)" # # second rule for bug #1618381 $IPTABLES -A INPUT -i eth0 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -j ACCEPT # # Rule 33 (global) # echo "Rule 33 (global)" # # testing for bug #1618381 $IPTABLES -N Cid459A026219324.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid459A026219324.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid459A026219324.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid459A026219324.0 $IPTABLES -A Cid459A026219324.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid459A026219324.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid459A026219324.0 -j ACCEPT # # Rule 34 (global) # echo "Rule 34 (global)" # # testing for bug #1618381 $IPTABLES -N Cid459A5AFB19324.0 $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j Cid459A5AFB19324.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 80 -j Cid459A5AFB19324.0 $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j Cid459A5AFB19324.0 $IPTABLES -A INPUT -p tcp -m tcp --dport 80 -j Cid459A5AFB19324.0 $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -j Cid459A5AFB19324.0 $IPTABLES -A FORWARD -p tcp -m tcp --dport 80 -j Cid459A5AFB19324.0 $IPTABLES -A Cid459A5AFB19324.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid459A5AFB19324.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid459A5AFB19324.0 -j ACCEPT # # Rule 35 (eth0) # echo "Rule 35 (eth0)" # # bug #1618381 # this rule uses multiport # and has to be split because # of that $IPTABLES -A INPUT -i eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A INPUT -i eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A FORWARD -i eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp --dport 10000:11000 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p tcp -m tcp -m multiport --dports 113,13,53,2105,21,70,80,443,6667,119,25,3128,22,23,540 -j ACCEPT $IPTABLES -A FORWARD -o eth0 -p udp -m udp -m multiport --dports 53,161 -j ACCEPT # # Rule 36 (global) # echo "Rule 36 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j TCPMSS --set-mss 1400 # # Rule 37 (global) # echo "Rule 37 (global)" # $IPTABLES -N RULE_37 $IPTABLES -A OUTPUT -j RULE_37 $IPTABLES -A INPUT -j RULE_37 $IPTABLES -A FORWARD -j RULE_37 $IPTABLES -A RULE_37 -j LOG --log-level info --log-prefix "RULE 37 -- BRANCH " $IPTABLES -A RULE_37 -j mymark # # Rule 38 (global) # echo "Rule 38 (global)" # $IPTABLES -N RULE_38 $IPTABLES -A OUTPUT -j RULE_38 $IPTABLES -A INPUT -j RULE_38 $IPTABLES -A FORWARD -j RULE_38 $IPTABLES -A RULE_38 -j LOG --log-level info --log-prefix "RULE 38 -- DENY " $IPTABLES -A RULE_38 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:45 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/heartbeat_cluster_1_d_linux-1-d.fw.orig0000755000175000017500000005460711733011756026106 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:41 2012 PDT by vadim # # files: * heartbeat_cluster_1_d_linux-1-d.fw firewall.sh # # Compiled for iptables (any version) # # This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside. # Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0 # heartbeat_cluster_1_d:Policy:7: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-2-d' because its address in unknown. # heartbeat_cluster_1_d:Policy:7: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-2-d' because its address in unknown. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo eth2 eth2.100" for i in eth0 eth1 lo eth2 eth2.100 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth1 192.168.1.1/24" "192.168.1.254/24" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2.100 172.20.0.1/24" "" getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 done # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 --random done # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.100 done # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.100 done # ================ Table 'filter', rule set Policy # # Rule -8 heartbeat (automatic) # echo "Rule -8 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth2.100 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -7 heartbeat (automatic) # echo "Rule -7 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth2.100 -p udp -m udp -s 172.20.0.2 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -6 heartbeat (automatic) # echo "Rule -6 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -5 heartbeat (automatic) # echo "Rule -5 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -s 192.168.1.2 -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 224.0.10.100 --dport 694 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3780 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_0 for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A INPUT -i eth0 -s $i_eth0 -m state --state NEW -j In_RULE_0 done $IPTABLES -A INPUT -i eth0 -s 172.20.0.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.254 -m state --state NEW -j In_RULE_0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_0 for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A FORWARD -i eth0 -s $i_eth0 -m state --state NEW -j In_RULE_0 done $IPTABLES -A FORWARD -i eth0 -s 172.20.0.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.254 -m state --state NEW -j In_RULE_0 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (lo) # echo "Rule 1 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_3 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level info --log-prefix "RULE 3 -- ACCEPT " $IPTABLES -A RULE_3 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # fw is part of any and networks for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 6 (global) # echo "Rule 6 (global)" # # fw is NOT part of any and networks for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 7 (global) # echo "Rule 7 (global)" # # heartbeat_cluster_1_d:Policy:7: error: Can not build rule using dynamic interface 'eth0' of the object 'linux-2-d' because its address in unknown. for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p tcp -m tcp -s $i_eth0 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT done # # Rule 8 (global) # echo "Rule 8 (global)" # # fw is part of any $IPTABLES -N Cid307958X52019.0 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid307958X52019.0 $IPTABLES -A Cid307958X52019.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid307958X52019.0 -s 192.168.1.254 -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # # fw is not part of any $IPTABLES -N Cid625000X52019.0 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 22 -m state --state NEW -j Cid625000X52019.0 $IPTABLES -A Cid625000X52019.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -A Cid625000X52019.0 -s 192.168.1.254 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # # fw is not part of any $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.254 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.1 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.2 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.2 -d 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # All other attempts to connect to # the firewall are denied and logged $IPTABLES -N RULE_12 for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -d $i_eth0 -j RULE_12 done $IPTABLES -A OUTPUT -d 172.20.0.1 -j RULE_12 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_12 $IPTABLES -A OUTPUT -d 192.168.1.254 -j RULE_12 $IPTABLES -A INPUT -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level info --log-prefix "RULE 12 -- DENY " $IPTABLES -A RULE_12 -j DROP # # Rule 13 (eth0) # echo "Rule 13 (eth0)" # $IPTABLES -A INPUT -i ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o ! eth0 -m state --state NEW -j ACCEPT # # Rule 14 (eth0,eth1) # echo "Rule 14 (eth0,eth1)" # $IPTABLES -A INPUT -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2.100 -m state --state NEW -j ACCEPT # # Rule 15 (eth0) # echo "Rule 15 (eth0)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i ! eth0 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o ! eth0 -m state --state NEW -j ACCEPT # # Rule 16 (eth0,eth1) # echo "Rule 16 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2.100 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2.100 -m state --state NEW -j ACCEPT # # Rule 17 (eth0) # echo "Rule 17 (eth0)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i ! eth0 -m state --state NEW -j ACCEPT # # Rule 18 (eth0,eth1) # echo "Rule 18 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A FORWARD -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i eth2.100 -m state --state NEW -j ACCEPT # # Rule 19 (eth0) # echo "Rule 19 (eth0)" # # fw is part of any is OFF $IPTABLES -A FORWARD -o ! eth0 -m state --state NEW -j ACCEPT # # Rule 20 (eth0,eth1) # echo "Rule 20 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A FORWARD -o eth2 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -o eth2.100 -m state --state NEW -j ACCEPT # # Rule 21 (eth0) # echo "Rule 21 (eth0)" # $IPTABLES -A INPUT -i ! eth0 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o ! eth0 -d $i_eth0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o ! eth0 -d 172.20.0.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o ! eth0 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o ! eth0 -d 192.168.1.254 -m state --state NEW -j ACCEPT # # Rule 22 (eth0,eth1) # echo "Rule 22 (eth0,eth1)" # $IPTABLES -A INPUT -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2.100 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth2 -d $i_eth0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o eth2 -d 172.20.0.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2 -d 192.168.1.254 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth2.100 -d $i_eth0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o eth2.100 -d 172.20.0.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2.100 -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth2.100 -d 192.168.1.254 -m state --state NEW -j ACCEPT # # Rule 23 (eth0) # echo "Rule 23 (eth0)" # # fw is part of any is OFF $IPTABLES -A INPUT -i ! eth0 -m state --state NEW -j ACCEPT # # Rule 24 (eth0,eth1) # echo "Rule 24 (eth0,eth1)" # # fw is part of any is OFF $IPTABLES -A INPUT -i eth2 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth2.100 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:41 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall7.fw.orig0000755000175000017500000003145211733011756021752 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:04 2012 PDT by vadim # # files: * firewall7.fw /etc/fw/firewall7.fw # # Compiled for iptables (any version) # # testing rules with broadcasts and multicasts and action-on-reject "TCP reset" # testing rules used for DHCP relay running on the firewall between interfaces eth0 and eth2 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth3 22.22.23.23/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 192.168.1.255 --dport 67 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 255.255.255.255 --dport 67 -m state --state NEW -j ACCEPT # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 224.0.1.141 --dport 67 -m state --state NEW -j ACCEPT # # Rule 3 (eth0) # echo "Rule 3 (eth0)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -s 0.0.0.0 -d 255.255.255.255 --dport 67 -m state --state NEW -j ACCEPT # # Rule 4 (eth0) # echo "Rule 4 (eth0)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -s 192.168.1.1 -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 5 (eth2) # echo "Rule 5 (eth2)" # $IPTABLES -A OUTPUT -o eth2 -p udp -m udp -s 192.168.2.1 -d 192.168.2.10 --dport 67 -m state --state NEW -j ACCEPT # # Rule 6 (eth2) # echo "Rule 6 (eth2)" # $IPTABLES -A INPUT -i eth2 -p udp -m udp -s 192.168.2.10 -d 192.168.1.1 --dport 67 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N RULE_7 $IPTABLES -A OUTPUT -d 255.255.255.255 -j RULE_7 $IPTABLES -A OUTPUT -d 192.168.1.255 -j RULE_7 $IPTABLES -A INPUT -d 255.255.255.255 -j RULE_7 $IPTABLES -A INPUT -d 192.168.1.255 -j RULE_7 $IPTABLES -A RULE_7 -j LOG --log-level debug $IPTABLES -A RULE_7 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # # compiler should place rule in INPUT chain because this is broadcast destination $IPTABLES -A OUTPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # # compiler should place rule in INPUT chain because this is broadcast destination $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 192.168.1.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # # compiler should place rule in INPUT chain because this is broadcast destination $IPTABLES -A OUTPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p udp -m udp -d 255.255.255.255 --dport 68 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N RULE_11 $IPTABLES -A OUTPUT -d 224.0.1.141 -m state --state NEW -j RULE_11 $IPTABLES -A INPUT -d 224.0.1.141 -m state --state NEW -j RULE_11 $IPTABLES -A RULE_11 -j LOG --log-level debug $IPTABLES -A RULE_11 -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N RULE_12 $IPTABLES -A OUTPUT -d 224.0.0.5 -m state --state NEW -j RULE_12 $IPTABLES -A INPUT -d 224.0.0.5 -m state --state NEW -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level debug $IPTABLES -A RULE_12 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -A OUTPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.5 -m state --state NEW -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # $IPTABLES -A OUTPUT -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # $IPTABLES -A OUTPUT -d 224.0.0.0/4 -j DROP $IPTABLES -A INPUT -d 224.0.0.0/4 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:04 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall61-1.2.5.fw.orig0000755000175000017500000003757411733011756022506 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:59 2012 PDT by vadim # # files: * firewall61-1.2.5.fw /etc/firewall61-1.2.5.fw # # Compiled for iptables lt_1.2.6 # # testing time litmiting for iptables 1.2.5 # firewall61-1.2.5:Policy_ipv6:: warning: target TCPMSS is not supported by ip6tables before v1.3.8 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 222.222.222.222/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'mangle', rule set fw61-Policy # # Rule fw61-Policy 0 (global) # echo "Rule fw61-Policy 0 (global)" # $IPTABLES -N fw61-Policy_0 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sat -j fw61-Policy_0 $IPTABLES -t mangle -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sat -j fw61-Policy_0 $IPTABLES -t mangle -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sat -j fw61-Policy_0 $IPTABLES -t mangle -A fw61-Policy_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -t mangle -A fw61-Policy_0 -j DROP # # Rule fw61-Policy 1 (global) # echo "Rule fw61-Policy 1 (global)" # $IPTABLES -N fw61-Policy_1 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sun -j fw61-Policy_1 $IPTABLES -t mangle -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sun -j fw61-Policy_1 $IPTABLES -t mangle -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sun -j fw61-Policy_1 $IPTABLES -t mangle -A fw61-Policy_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -t mangle -A fw61-Policy_1 -j DROP # # Rule fw61-Policy 2 (global) # echo "Rule fw61-Policy 2 (global)" # $IPTABLES -N fw61-Policy_2 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 18:00 --timestop 23:59 -j fw61-Policy_2 $IPTABLES -t mangle -A INPUT -m time --timestart 18:00 --timestop 23:59 -j fw61-Policy_2 $IPTABLES -t mangle -A FORWARD -m time --timestart 18:00 --timestop 23:59 -j fw61-Policy_2 $IPTABLES -t mangle -A fw61-Policy_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -t mangle -A fw61-Policy_2 -j DROP # # Rule fw61-Policy 3 (global) # echo "Rule fw61-Policy 3 (global)" # $IPTABLES -N fw61-Policy_3 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j fw61-Policy_3 $IPTABLES -t mangle -A INPUT -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j fw61-Policy_3 $IPTABLES -t mangle -A FORWARD -m time --timestart 00:00 --timestop 23:59 --days Sat,Sun -j fw61-Policy_3 $IPTABLES -t mangle -A fw61-Policy_3 -j LOG --log-level info --log-prefix "RULE 3 -- DENY " $IPTABLES -t mangle -A fw61-Policy_3 -j DROP # # Rule fw61-Policy 4 (global) # echo "Rule fw61-Policy 4 (global)" # $IPTABLES -N fw61-Policy_4 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j fw61-Policy_4 $IPTABLES -t mangle -A INPUT -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j fw61-Policy_4 $IPTABLES -t mangle -A FORWARD -m time --timestart 09:00 --timestop 17:00 --days Mon,Tue,Wed,Thu,Fri -j fw61-Policy_4 $IPTABLES -t mangle -A fw61-Policy_4 -j LOG --log-level info --log-prefix "RULE 4 -- DENY " $IPTABLES -t mangle -A fw61-Policy_4 -j DROP # # Rule fw61-Policy 5 (global) # echo "Rule fw61-Policy 5 (global)" # $IPTABLES -N fw61-Policy_5 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_5 $IPTABLES -t mangle -A INPUT -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_5 $IPTABLES -t mangle -A FORWARD -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_5 $IPTABLES -t mangle -A fw61-Policy_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -t mangle -A fw61-Policy_5 -j DROP # # Rule fw61-Policy 6 (global) # echo "Rule fw61-Policy 6 (global)" # $IPTABLES -N fw61-Policy_6 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_6 $IPTABLES -t mangle -A INPUT -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_6 $IPTABLES -t mangle -A FORWARD -m time --timestart 01:01 --timestop 02:02 --days Sun,Mon -j fw61-Policy_6 $IPTABLES -t mangle -A fw61-Policy_6 -j LOG --log-level info --log-prefix "RULE 6 -- DENY " $IPTABLES -t mangle -A fw61-Policy_6 -j DROP # # Rule fw61-Policy 7 (global) # echo "Rule fw61-Policy 7 (global)" # $IPTABLES -N fw61-Policy_7 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 00:00 --timestop 01:00 --days Fri,Sat -j fw61-Policy_7 $IPTABLES -t mangle -A INPUT -m time --timestart 00:00 --timestop 01:00 --days Fri,Sat -j fw61-Policy_7 $IPTABLES -t mangle -A FORWARD -m time --timestart 00:00 --timestop 01:00 --days Fri,Sat -j fw61-Policy_7 $IPTABLES -t mangle -A fw61-Policy_7 -j LOG --log-level info --log-prefix "RULE 7 -- DENY " $IPTABLES -t mangle -A fw61-Policy_7 -j DROP # # Rule fw61-Policy 8 (global) # echo "Rule fw61-Policy 8 (global)" # $IPTABLES -N fw61-Policy_8 -t mangle $IPTABLES -t mangle -A OUTPUT -m time --timestart 01:00 --timestop 02:00 --days Fri,Sat -j fw61-Policy_8 $IPTABLES -t mangle -A INPUT -m time --timestart 01:00 --timestop 02:00 --days Fri,Sat -j fw61-Policy_8 $IPTABLES -t mangle -A FORWARD -m time --timestart 01:00 --timestop 02:00 --days Fri,Sat -j fw61-Policy_8 $IPTABLES -t mangle -A fw61-Policy_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -t mangle -A fw61-Policy_8 -j DROP # ================ IPv6 # ================ Table 'filter', automatic rules # target TCPMSS is not supported by ip6tables before v1.3.8 # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy_ipv6 # # Rule Policy_ipv6 0 (global) # echo "Rule Policy_ipv6 0 (global)" # $IP6TABLES -N Policy_ipv6_0 $IP6TABLES -A OUTPUT -j Policy_ipv6_0 $IP6TABLES -A INPUT -j Policy_ipv6_0 $IP6TABLES -A FORWARD -j Policy_ipv6_0 $IP6TABLES -A Policy_ipv6_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IP6TABLES -A Policy_ipv6_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:59 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall90.fw.orig0000755000175000017500000002343511733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:15 2012 PDT by vadim # # files: * firewall90.fw /etc/fw/firewall90.fw # # Compiled for iptables (any version) # # test for ipv4options module FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0" for i in eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A FORWARD -p all -m dscp --dscp-class AF4 -m ipv4options --lsrr --ra -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A FORWARD -p all -m ipv4options --rr -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --lsrr --ssrr -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --ts -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A FORWARD -p all -m ipv4options --any-opt -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:15 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-base-rulesets.fw.orig0000755000175000017500000003155411733011756024442 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:19 2012 PDT by vadim # # files: * firewall-base-rulesets.fw /etc/fw/firewall-base-rulesets.fw # # Compiled for iptables (any version) # # this firewall is used to test a rule in the global policy of object "firewall" FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 33.33.33.33/24" "" update_addresses_of_interface "eth1 172.16.1.1/24" "" update_addresses_of_interface "eth2 192.168.100.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set web_server_inbound # # Rule web_server_inbound 0 (global) # echo "Rule web_server_inbound 0 (global)" # $IPTABLES -N web_server_inbound $IPTABLES -A web_server_inbound -i + -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT # # Rule web_server_inbound 1 (global) # echo "Rule web_server_inbound 1 (global)" # $IPTABLES -A web_server_inbound -i + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A web_server_inbound -i + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule web_server_inbound 2 (global) # echo "Rule web_server_inbound 2 (global)" # $IPTABLES -N web_server_inbound_2 $IPTABLES -A web_server_inbound -p tcp -m tcp --dport 3306 -j web_server_inbound_2 $IPTABLES -A web_server_inbound_2 -j LOG --log-level info --log-prefix "web_server_inbound/2 -- DENY" $IPTABLES -A web_server_inbound_2 -j DROP # ================ Table 'filter', rule set mail_server_inbound # # Rule mail_server_inbound 0 (global) # echo "Rule mail_server_inbound 0 (global)" # $IPTABLES -N mail_server_inbound $IPTABLES -A mail_server_inbound -i + -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT # # Rule mail_server_inbound 1 (global) # echo "Rule mail_server_inbound 1 (global)" # $IPTABLES -A mail_server_inbound -i + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A mail_server_inbound -i + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set mail_server_outbound # # Rule mail_server_outbound 0 (global) # echo "Rule mail_server_outbound 0 (global)" # $IPTABLES -N mail_server_outbound $IPTABLES -A mail_server_outbound -o + -p tcp -m tcp -m multiport --dports 53,25 -m state --state NEW -j ACCEPT $IPTABLES -A mail_server_outbound -o + -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT # # Rule mail_server_outbound 1 (global) # echo "Rule mail_server_outbound 1 (global)" # $IPTABLES -A mail_server_outbound -o + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A mail_server_outbound -o + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set web_server_outbound # # Rule web_server_outbound 0 (global) # echo "Rule web_server_outbound 0 (global)" # $IPTABLES -N web_server_outbound $IPTABLES -A web_server_outbound -o + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A web_server_outbound -o + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule web_server_outbound 1 (global) # echo "Rule web_server_outbound 1 (global)" # $IPTABLES -A web_server_outbound -o + -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A web_server_outbound -o + -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set base-ruleset # # Rule base-ruleset 0 (global) # echo "Rule base-ruleset 0 (global)" # $IPTABLES -N base-ruleset $IPTABLES -N Cid41961X1271.0 $IPTABLES -A base-ruleset -p tcp -m tcp --dport 22 -m state --state NEW -j Cid41961X1271.0 $IPTABLES -A Cid41961X1271.0 -d 33.33.33.33 -j ACCEPT $IPTABLES -A Cid41961X1271.0 -d 172.16.1.1 -j ACCEPT $IPTABLES -A Cid41961X1271.0 -d 192.168.100.1 -j ACCEPT } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:19 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall21.fw.orig0000755000175000017500000003101011733011756022014 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:19 2012 PDT by vadim # # files: * firewall21.fw /etc/fw/firewall21.fw # # Compiled for iptables (any version) # # two dynamic interfaces in the same policy or NAT rule # firewall21:Policy:: warning: Log prefix has been truncated to 29 characters # firewall21:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth2 192.168.1.100/24" "" getaddr eth0 i_eth0 getaddr6 eth0 i_eth0_v6 getnet eth0 i_eth0_network getnet6 eth0 i_eth0_v6_network getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.10 done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A PREROUTING -d $i_eth1 -j DNAT --to-destination 192.168.1.10 done # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A PREROUTING -d $i_eth0 -j DNAT --to-destination 192.168.1.10 --random done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -t nat -A PREROUTING -d $i_eth1 -j DNAT --to-destination 192.168.1.10 --random done # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE --random # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 done # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source $i_eth0 --random done # ================ Table 'filter', rule set Policy # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -o eth0 -s $i_eth0 -m state --state NEW -j ACCEPT done # # Rule 1 (global) # echo "Rule 1 (global)" # for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A INPUT -s $i_eth0 -m state --state NEW -j ACCEPT done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A INPUT -s $i_eth1 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -s $i_eth0 -m state --state NEW -j ACCEPT done for i_eth1 in $i_eth1_list do test -n "$i_eth1" && $IPTABLES -A OUTPUT -s $i_eth1 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d $i_eth0 --dports 68,67 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT for i_eth0 in $i_eth0_list do test -n "$i_eth0" && $IPTABLES -A INPUT -p udp -m udp -m multiport -d $i_eth0 --dports 68,67 -m state --state NEW -j ACCEPT done # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N RULE_3 $IPTABLES -A OUTPUT -j RULE_3 $IPTABLES -A INPUT -j RULE_3 $IPTABLES -A FORWARD -j RULE_3 $IPTABLES -A RULE_3 -j LOG --log-level debug --log-prefix "RULE 3 -- DENY on interface g" $IPTABLES -A RULE_3 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:19 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/fwbuilder.fw.orig0000755000175000017500000003317211733011756022042 0ustar sylvestresylvestre#!/bin/sh /etc/rc.common # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:54 2012 PDT by vadim # # files: * fwbuilder.fw /etc/init.d/fwbuilder.fw # # Compiled for iptables 1.4.3 # # testing run time address table objects with module set # use module set is turned off # firewall41-2::: warning: Can not add virtual address for object atbl.1 START=46 EXTRA_COMMANDS="status interfaces test_interfaces" FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="" IPTABLES="/usr/sbin/iptables" IP6TABLES="/usr/sbin/ip6tables" IPTABLES_RESTORE="/usr/sbin/iptables-restore" IP6TABLES_RESTORE="/usr/sbin/ip6tables-restore" IP="/usr/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/usr/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "atbl.1" "addr-table-1.tbl" check_file "block_these" "block-hosts.tbl" } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi insmod ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 1.1.1.1/24" "" update_addresses_of_interface "eth1 2.2.2.2/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -t nat -A POSTROUTING -o eth+ -s $at_atbl_1 -j SNAT --to-source 1.1.1.1 done # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -N Cid2101361X9995.0 $IPTABLES -t nat -A POSTROUTING -o eth+ -j Cid2101361X9995.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -t nat -A Cid2101361X9995.0 -s $at_atbl_1 -j RETURN done $IPTABLES -t nat -A Cid2101361X9995.0 -j SNAT --to-source 1.1.1.1 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -t nat -A PREROUTING -d $at_atbl_1 -j DNAT --to-destination 192.168.1.10 done # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -m state --state NEW -j ACCEPT done # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N Cid4374297X29460.0 $IPTABLES -A INPUT -s 1.1.1.1 -m state --state NEW -j Cid4374297X29460.0 $IPTABLES -A INPUT -s 2.2.2.2 -m state --state NEW -j Cid4374297X29460.0 $IPTABLES -A OUTPUT -s 1.1.1.1 -m state --state NEW -j Cid4374297X29460.0 $IPTABLES -A OUTPUT -s 2.2.2.2 -m state --state NEW -j Cid4374297X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374297X29460.0 -d $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374297X29460.0 -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N Cid4374309X29460.0 $IPTABLES -A OUTPUT -s 1.1.1.1 -m state --state NEW -j Cid4374309X29460.0 $IPTABLES -A OUTPUT -s 2.2.2.2 -m state --state NEW -j Cid4374309X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374309X29460.0 -d $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374309X29460.0 -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -m state --state NEW -j ACCEPT done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A OUTPUT -d $at_block_these -m state --state NEW -j ACCEPT done # # Rule 4 (global) # echo "Rule 4 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A INPUT -s $at_atbl_1 -m state --state NEW -j ACCEPT done # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid4374346X29460.0 $IPTABLES -A OUTPUT -d 1.1.1.1 -m state --state NEW -j Cid4374346X29460.0 $IPTABLES -A OUTPUT -d 2.2.2.2 -m state --state NEW -j Cid4374346X29460.0 $IPTABLES -A INPUT -d 1.1.1.1 -m state --state NEW -j Cid4374346X29460.0 $IPTABLES -A INPUT -d 2.2.2.2 -m state --state NEW -j Cid4374346X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374346X29460.0 -s $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374346X29460.0 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid4374358X29460.0 $IPTABLES -A INPUT -d 1.1.1.1 -m state --state NEW -j Cid4374358X29460.0 $IPTABLES -A INPUT -d 2.2.2.2 -m state --state NEW -j Cid4374358X29460.0 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A Cid4374358X29460.0 -s $at_atbl_1 -j RETURN done $IPTABLES -A Cid4374358X29460.0 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A INPUT -s $at_atbl_1 -m state --state NEW -j ACCEPT done grep -Ev '^#|^;|^\s*$' block-hosts.tbl | while read L ; do set $L; at_block_these=$1; $IPTABLES -A INPUT -s $at_block_these -m state --state NEW -j ACCEPT done # # Rule 8 (global) # echo "Rule 8 (global)" # grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A OUTPUT -d $at_atbl_1 -j DROP done grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A FORWARD -d $at_atbl_1 -j DROP done } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } start() { log "Activating firewall script generated Sun Mar 18 21:16:54 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands } stop() { stop_action } status() { status_action } interfaces() { configure_interfaces } test_interfaces() { FWBDEBUG="echo" configure_interfaces } fwbuilder-5.1.0.3599/test/ipt/firewall20.fw.orig0000755000175000017500000004721611733011756022032 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:17 2012 PDT by vadim # # files: * firewall20.fw /etc/fw/firewall20.fw # # Compiled for iptables (any version) # # testing firewall_is_part_of_any_and_networks # also testing SNAT and DNAT rules when external interface # has dynamic address # dynamic interface ppp0 has an address object attached to it # (interface used to be static and had an address, then got # converted to dynamic but address object is still there). Compiler # should ignore this address object and issue a warning. # firewall20::: error: Dynamic interface ppp* should not have an IP address object attached to it. This IP address object will be ignored. # firewall20::: warning: Can not add virtual address for object address # firewall20::: warning: Can not add virtual address for object address FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: eth0 eth2" for i in eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j MASQUERADE # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j MASQUERADE --random # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -t nat -A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j SNAT --to-source $addr done done # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $addr --dport 22 -j DNAT --to-destination 192.168.1.10:22 done done $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -d ! 200.200.200.200 -j DNAT --to-destination 192.168.2.10 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.10 -j SNAT --to-source 192.168.2.1 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10 getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d $addr --dport 22 -j DNAT --to-destination 192.168.1.10 done done # ================ Table 'filter', rule set Policy # # Rule 0 (ppp*) # echo "Rule 0 (ppp*)" # # ppp clients get addresses on 10.1.1.0 $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i ppp+ -s ! 10.1.1.0/24 -j In_RULE_0 $IPTABLES -A FORWARD -i ppp+ -s ! 10.1.1.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (ppp*) # echo "Rule 1 (ppp*)" # # ppp clients can not connect to the firewall $IPTABLES -N In_RULE_1 getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -A INPUT -i ppp+ -d $addr -j In_RULE_1 done done $IPTABLES -A In_RULE_1 -j LOG $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (ppp*) # echo "Rule 2 (ppp*)" # $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i ppp+ -j In_RULE_2 $IPTABLES -A In_RULE_2 -j LOG $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (ppp*) # echo "Rule 3 (ppp*)" # # ppp clients can only connect to the mail # server and web proxy on DMZ $IPTABLES -A FORWARD -i ppp+ -p tcp -m tcp -m multiport -d 192.168.2.10 --dports 25,3128 -m state --state NEW -j ACCEPT # # Rule 4 (ppp*) # echo "Rule 4 (ppp*)" # # ppp clients can not connect to # anything else on DMZ and # internal net $IPTABLES -N In_RULE_4 $IPTABLES -A INPUT -i ppp+ -d 192.168.1.0/24 -j In_RULE_4 $IPTABLES -A INPUT -i ppp+ -d 192.168.2.0/24 -j In_RULE_4 $IPTABLES -A FORWARD -i ppp+ -d 192.168.1.0/24 -j In_RULE_4 $IPTABLES -A FORWARD -i ppp+ -d 192.168.2.0/24 -j In_RULE_4 $IPTABLES -A In_RULE_4 -j LOG $IPTABLES -A In_RULE_4 -j DROP # # Rule 5 (ppp*) # echo "Rule 5 (ppp*)" # $IPTABLES -A INPUT -i ppp+ -s ! 33.33.33.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i ppp+ -s ! 33.33.33.0/24 -m state --state NEW -j ACCEPT # # Rule 6 (eth2) # echo "Rule 6 (eth2)" # $IPTABLES -N In_RULE_6 $IPTABLES -A INPUT -i eth2 -s ! 192.168.2.0/24 -j In_RULE_6 $IPTABLES -A FORWARD -i eth2 -s ! 192.168.2.0/24 -j In_RULE_6 $IPTABLES -A In_RULE_6 -j LOG $IPTABLES -A In_RULE_6 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # # hostF has the same IP address as firewal. $IPTABLES -N RULE_7 $IPTABLES -A OUTPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_7 $IPTABLES -A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_7 $IPTABLES -A RULE_7 -j LOG $IPTABLES -A RULE_7 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N Cid3EFBC67F.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid3EFBC67F.0 getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -A Cid3EFBC67F.0 -d $addr -j ACCEPT done done $IPTABLES -A Cid3EFBC67F.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3EFBC67F.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -A OUTPUT -p tcp -m tcp -d $addr --dport 22 -m state --state NEW -j ACCEPT done done getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IPTABLES -A INPUT -p tcp -m tcp -d $addr --dport 22 -m state --state NEW -j ACCEPT done done # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N Cid3EFBC6A8.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3EFBC6A8.0 $IPTABLES -A Cid3EFBC6A8.0 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3EFBC6A8.0 -d 192.168.2.1 -j ACCEPT $IPTABLES -N Cid3EFBC6A8.1 $IPTABLES -A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3EFBC6A8.1 $IPTABLES -A Cid3EFBC6A8.1 -d 192.168.1.1 -j ACCEPT $IPTABLES -A Cid3EFBC6A8.1 -d 192.168.2.1 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N Cid3EFBC6B3.0 $IPTABLES -A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3EFBC6B3.0 $IPTABLES -N RULE_13 $IPTABLES -A Cid3EFBC6B3.0 -d 192.168.1.1 -j RULE_13 $IPTABLES -A Cid3EFBC6B3.0 -d 192.168.2.1 -j RULE_13 $IPTABLES -N Cid3EFBC6B3.1 $IPTABLES -A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid3EFBC6B3.1 $IPTABLES -A Cid3EFBC6B3.1 -d 192.168.1.1 -j RULE_13 $IPTABLES -A Cid3EFBC6B3.1 -d 192.168.2.1 -j RULE_13 $IPTABLES -A RULE_13 -j LOG $IPTABLES -A RULE_13 -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # firewall is part of Any, so compiler should # generate code in both FORWARD and # OUTPUT chains $IPTABLES -A OUTPUT -d 200.200.200.200 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 200.200.200.200 -m state --state NEW -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # firewall is part of Any, compiler should # generate code for both FORWARD and # INPUT chains $IPTABLES -A INPUT -s 200.200.200.200 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 200.200.200.200 -m state --state NEW -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # because firewall has interface on network # internal_net, compiler should generate code # for both FORWARD and INPUT chains $IPTABLES -A INPUT -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # $IPTABLES -N Cid3EFBC6DC.0 $IPTABLES -A OUTPUT -d 200.200.200.200 -m state --state NEW -j Cid3EFBC6DC.0 $IPTABLES -A Cid3EFBC6DC.0 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid3EFBC6DC.0 -s 192.168.2.0/24 -j ACCEPT $IPTABLES -N Cid3EFBC6DC.1 $IPTABLES -A FORWARD -d 200.200.200.200 -m state --state NEW -j Cid3EFBC6DC.1 $IPTABLES -A Cid3EFBC6DC.1 -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A Cid3EFBC6DC.1 -s 192.168.2.0/24 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # Automatically generated 'catch all' rule $IPTABLES -N RULE_19 $IPTABLES -A OUTPUT -j RULE_19 $IPTABLES -A INPUT -j RULE_19 $IPTABLES -A FORWARD -j RULE_19 $IPTABLES -A RULE_19 -j LOG $IPTABLES -A RULE_19 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:17 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall20-ipv6.fw.orig0000755000175000017500000003011211733011756022677 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:18 2012 PDT by vadim # # files: * firewall20-ipv6.fw /etc/fw/firewall20-ipv6.fw # # Compiled for iptables (any version) # # testing firewall_is_part_of_any_and_networks # also testing SNAT and DNAT rules when external interface has dynamic address # dynamic interface ppp0 has an address object attached to it (interface used to be static and had an address, then got converted to dynamic but address object is still there). Compiler should ignore this address object and issue a warning. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: eth0 eth2" for i in eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::1/64 192.168.1.1/24" "" update_addresses_of_interface "eth2 2001:470:1f05:590::1/64 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv6 # ================ Table 'filter', rule set Policy # # Rule 1 (ppp*) # echo "Rule 1 (ppp*)" # # ppp clients can not connect to the firewall $IP6TABLES -N In_RULE_1 getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr6 $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IP6TABLES -A INPUT -i ppp+ -d $addr -j In_RULE_1 done done $IP6TABLES -A In_RULE_1 -j LOG $IP6TABLES -A In_RULE_1 -j DROP # # Rule 2 (ppp*) # echo "Rule 2 (ppp*)" # $IP6TABLES -N In_RULE_2 $IP6TABLES -A INPUT -i ppp+ -j In_RULE_2 $IP6TABLES -A In_RULE_2 -j LOG $IP6TABLES -A In_RULE_2 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # $IP6TABLES -N Cid30296X26784.0 $IP6TABLES -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid30296X26784.0 getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr6 $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IP6TABLES -A Cid30296X26784.0 -d $addr -j ACCEPT done done $IP6TABLES -A Cid30296X26784.0 -d 2001:470:1f05:590::1 -j ACCEPT $IP6TABLES -A Cid30296X26784.0 -d fe80::1 -j ACCEPT $IP6TABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr6 $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IP6TABLES -A OUTPUT -p tcp -m tcp -d $addr --dport 22 -m state --state NEW -j ACCEPT done done getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr6 $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && $IP6TABLES -A INPUT -p tcp -m tcp -d $addr --dport 22 -m state --state NEW -j ACCEPT done done # # Rule 18 (global) # echo "Rule 18 (global)" # $IP6TABLES -N RULE_18 $IP6TABLES -A OUTPUT -m rt --rt-type 0 -j RULE_18 $IP6TABLES -A INPUT -m rt --rt-type 0 -j RULE_18 $IP6TABLES -A FORWARD -m rt --rt-type 0 -j RULE_18 $IP6TABLES -A RULE_18 -j LOG $IP6TABLES -A RULE_18 -j DROP # # Rule 19 (global) # echo "Rule 19 (global)" # # Automatically generated 'catch all' rule $IP6TABLES -N RULE_19 $IP6TABLES -A OUTPUT -j RULE_19 $IP6TABLES -A INPUT -j RULE_19 $IP6TABLES -A FORWARD -j RULE_19 $IP6TABLES -A RULE_19 -j LOG $IP6TABLES -A RULE_19 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:18 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall72-1.3.x.fw.orig0000755000175000017500000004120211733011756022573 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:07 2012 PDT by vadim # # files: * firewall72-1.3.x.fw /etc/fw/firewall72-1.3.x.fw # # Compiled for iptables 1.3.0 # # this firewall is used to test a rule in the global policy of object "firewall" # firewall72-1.3.x:Policy:10: error: Rule '10 (eth1)' shadows rule '13 (eth1)' below it # firewall72-1.3.x:Policy:10: error: Rule '10 (eth1)' shadows rule '14 (eth1)' below it # firewall72-1.3.x:Policy:15: warning: Iptables does not support module 'owner' in a chain other than OUTPUT # firewall72-1.3.x::: warning: Can not add virtual address for object address # firewall72-1.3.x::: warning: Can not add virtual address for object address FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 33.33.33.33/24" "" update_addresses_of_interface "eth1 172.16.1.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s ! 192.168.1.0/24 -d 200.200.200.200 -j SNAT --to-source 22.22.22.23 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -s ! 192.168.1.0/24 -d 200.200.200.200 --dport 80 -j SNAT --to-source 22.22.22.23 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -d ! 192.168.2.0/24 -j SNAT --to-source 33.33.33.33 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d ! 192.168.2.0/24 -j SNAT --to-source 172.16.1.1 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d ! 192.168.2.0/24 --dport 80 -j SNAT --to-source 33.33.33.33 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 -d ! 192.168.2.0/24 --dport 80 -j SNAT --to-source 172.16.1.1 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -N Cid212911X8629.0 $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j Cid212911X8629.0 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j Cid212911X8629.0 $IPTABLES -t nat -A Cid212911X8629.0 -d 192.168.1.0/24 -j RETURN $IPTABLES -t nat -A Cid212911X8629.0 -d 192.168.2.0/24 -j RETURN $IPTABLES -t nat -A Cid212911X8629.0 -j SNAT --to-source 172.16.1.1 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 -d ! 192.168.1.1 --dport 80 -j REDIRECT --to-ports 3128 # ================ Table 'filter', rule set Policy # # Rule 0 (lo) # echo "Rule 0 (lo)" # $IPTABLES -A INPUT -i ! lo -s 127.0.0.1 -j DROP $IPTABLES -A FORWARD -i ! lo -s 127.0.0.1 -j DROP $IPTABLES -A OUTPUT -o ! lo -s 127.0.0.1 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # $IPTABLES -N Cid107355X8629.0 $IPTABLES -A OUTPUT -o eth1 -s ! 192.168.1.0/24 -j Cid107355X8629.0 $IPTABLES -A Cid107355X8629.0 -d 33.33.33.33 -j DROP $IPTABLES -A Cid107355X8629.0 -d 172.16.1.1 -j DROP $IPTABLES -N Cid107355X8629.1 $IPTABLES -A FORWARD -o eth1 -s ! 192.168.1.0/24 -j Cid107355X8629.1 $IPTABLES -A Cid107355X8629.1 -d 33.33.33.33 -j DROP $IPTABLES -A Cid107355X8629.1 -d 172.16.1.1 -j DROP # # Rule 2 (eth1) # echo "Rule 2 (eth1)" # $IPTABLES -N Cid107338X8629.0 $IPTABLES -A INPUT -i eth1 -d ! 192.168.1.0/24 -j Cid107338X8629.0 $IPTABLES -A Cid107338X8629.0 -s 33.33.33.33 -j DROP $IPTABLES -A Cid107338X8629.0 -s 172.16.1.1 -j DROP $IPTABLES -N Cid107338X8629.1 $IPTABLES -A FORWARD -i eth1 -d ! 192.168.1.0/24 -j Cid107338X8629.1 $IPTABLES -A Cid107338X8629.1 -s 33.33.33.33 -j DROP $IPTABLES -A Cid107338X8629.1 -s 172.16.1.1 -j DROP # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N Cid107321X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid107321X8629.0 $IPTABLES -A Cid107321X8629.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -A Cid107321X8629.0 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid107304X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid107304X8629.0 $IPTABLES -A Cid107304X8629.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -A Cid107304X8629.0 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid107287X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid107287X8629.0 $IPTABLES -A Cid107287X8629.0 -p icmp -m icmp --icmp-type 3/1 -j RETURN $IPTABLES -A Cid107287X8629.0 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid107270X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid107270X8629.0 $IPTABLES -A Cid107270X8629.0 -p icmp -m icmp --icmp-type 3/1 -j RETURN $IPTABLES -A Cid107270X8629.0 -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid107253X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid107253X8629.0 $IPTABLES -A Cid107253X8629.0 -p 47 -j RETURN $IPTABLES -A Cid107253X8629.0 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N Cid107236X8629.0 $IPTABLES -A INPUT -d 172.16.1.1 -j Cid107236X8629.0 $IPTABLES -A Cid107236X8629.0 -p tcp -m tcp --tcp-flags ALL NONE -j RETURN $IPTABLES -A Cid107236X8629.0 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A OUTPUT -d 172.16.1.1 -m mark ! --mark 16 -j DROP $IPTABLES -A INPUT -d 172.16.1.1 -m mark ! --mark 16 -j DROP # # Rule 10 (eth1) # echo "Rule 10 (eth1)" # # Should use ! -i eth1 eventually # firewall72-1.3.x:Policy:10: error: Rule '10 (eth1)' shadows rule '13 (eth1)' below it # firewall72-1.3.x:Policy:10: error: Rule '10 (eth1)' shadows rule '14 (eth1)' below it $IPTABLES -A FORWARD -i ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 11 (eth1) # echo "Rule 11 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -N Cid107185X8629.0 $IPTABLES -A FORWARD -i ! eth1 -d 192.168.1.0/24 -j Cid107185X8629.0 $IPTABLES -A Cid107185X8629.0 -p tcp -m tcp --tcp-flags ALL NONE -j RETURN $IPTABLES -A Cid107185X8629.0 -j DROP # # Rule 12 (eth1) # echo "Rule 12 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -A OUTPUT -o ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A FORWARD -o ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 13 (eth1) # echo "Rule 13 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -A FORWARD -i ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A OUTPUT -o ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A FORWARD -o ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 14 (eth1) # echo "Rule 14 (eth1)" # # Should use ! -i eth1 eventually $IPTABLES -A FORWARD -i ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A OUTPUT -o ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP $IPTABLES -A FORWARD -o ! eth1 -p tcp -m tcp -d 192.168.1.0/24 --tcp-flags ALL NONE -j DROP # # Rule 15 (global) # echo "Rule 15 (global)" # # firewall72-1.3.x:Policy:15: warning: Iptables does not support module 'owner' in a chain other than OUTPUT $IPTABLES -A OUTPUT -d 172.16.1.1 -m owner ! --uid-owner 500 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:07 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-4.fw.orig0000755000175000017500000004420411733011756022705 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:23 2012 PDT by vadim # # files: * firewall-ipv6-4.fw /etc/firewall-ipv6-4.fw # # Compiled for iptables (any version) # # Simple policy that makes sense in ipv4 but translates into a few wide-matching rules in ipv6. Policy is configured as dual address family. Using iptables-restore. # firewall-ipv6-4:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it # firewall-ipv6-4:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it # firewall-ipv6-4:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP6TABLES_RESTORE find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" getaddr eth1 i_eth1 getaddr6 eth1 i_eth1_v6 getnet eth1 i_eth1_network getnet6 eth1 i_eth1_v6_network } script_body() { # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo ":In_RULE_0 - [0:0]" echo "-A INPUT -m state --state NEW -j In_RULE_0 " echo "-A In_RULE_0 -j ULOG --ulog-nlgroup 1 --ulog-prefix \"RULE 0 -- ACCEPT \" --ulog-qthreshold 1 " echo "-A In_RULE_0 -j ACCEPT " # # Rule 1 (global) echo "-A INPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -p icmp -m icmp -s 1.1.1.1 --icmp-type 8/0 -m state --state NEW -j ACCEPT " # # Rule 2 (global) # firewall-ipv6-4:Policy:2: error: Rule '2 (global)' shadows rule '3 (global)' below it echo "-A OUTPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT " echo "-A INPUT -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT " echo "-A FORWARD -p icmp -m icmp --icmp-type any -m state --state NEW -j ACCEPT " # # Rule 3 (global) echo "-A OUTPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT " echo "-A INPUT -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT " echo "-A FORWARD -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT " # # Rule 4 (global) # INPUT, OUTPUT, FORWARD # firewall-ipv6-4:Policy:4: error: Rule '4 (global)' shadows rule '6 (global)' below it echo "-A INPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -s 1.1.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 1.1.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 5 (global) # INPUT, OUTPUT, FORWARD echo "-A OUTPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 1.1.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 1.1.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 6 (global) # for bug 2047082 # echo "-A OUTPUT -m state --state NEW -j ACCEPT " # # Rule 7 (global) echo "-A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT " echo "-A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT " # # Rule 8 (global) echo ":RULE_8 - [0:0]" echo "-A OUTPUT -d 72.55.148.116 -j RULE_8 " echo "-A OUTPUT -d 207.251.84.150 -j RULE_8 " echo "-A FORWARD -d 72.55.148.116 -j RULE_8 " echo "-A FORWARD -d 207.251.84.150 -j RULE_8 " echo "-A RULE_8 -j ULOG --ulog-nlgroup 1 --ulog-prefix \"RULE 8 -- DENY \" --ulog-qthreshold 1 " echo "-A RULE_8 -j DROP " # # Rule 9 (global) # ipv4 address range for bug 2820152 echo "-A OUTPUT -d 192.168.1.1 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.2/31 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.4/30 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.8/29 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.16/28 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.32/27 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.64/27 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.96/30 -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d 192.168.1.100 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.1 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.2/31 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.4/30 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.8/29 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.16/28 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.32/27 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.64/27 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.96/30 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 192.168.1.100 -m state --state NEW -j ACCEPT " # # Rule 10 (global) # ipv4 address range for bug 2820152 echo "-A OUTPUT -d 255.255.255.255 -m state --state NEW -j ACCEPT " echo "-A INPUT -d 255.255.255.255 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":RULE_11 - [0:0]" echo "-A OUTPUT -j RULE_11 " echo "-A INPUT -j RULE_11 " echo "-A FORWARD -j RULE_11 " echo "-A RULE_11 -j ULOG --ulog-nlgroup 1 --ulog-prefix \"RULE 11 -- DENY \" --ulog-qthreshold 1 " echo "-A RULE_11 -j DROP " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s 1.1.1.0/24 -j MASQUERADE " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES # ================ IPv6 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop packets that do not match any valid state and log them echo ":drop_invalid - [0:0]" echo "-A OUTPUT -m state --state INVALID -j drop_invalid " echo "-A INPUT -m state --state INVALID -j drop_invalid " echo "-A FORWARD -m state --state INVALID -j drop_invalid " echo "-A drop_invalid -j LOG --log-level debug --log-prefix \"INVALID state -- DENY \"" echo "-A drop_invalid -j DROP " # ================ Table 'filter', rule set Policy # # Rule 0 (global) echo ":In_RULE_0 - [0:0]" echo "-A INPUT -m state --state NEW -j In_RULE_0 " echo "-A In_RULE_0 -j LOG --log-level info --log-prefix \"RULE 0 -- ACCEPT \"" echo "-A In_RULE_0 -j ACCEPT " # # Rule 6 (global) # for bug 2047082 # echo "-A OUTPUT -m state --state NEW -j ACCEPT " # # Rule 7 (global) echo "-A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT " echo "-A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT " echo "-A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":RULE_11 - [0:0]" echo "-A OUTPUT -j RULE_11 " echo "-A INPUT -j RULE_11 " echo "-A FORWARD -j RULE_11 " echo "-A RULE_11 -j LOG --log-level info --log-prefix \"RULE 11 -- DENY \"" echo "-A RULE_11 -j DROP " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o eth1 -s fe80::/64 -j MASQUERADE " # echo COMMIT ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:23 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/ipcop1.fw.orig0000755000175000017500000001203111733011756021241 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v4.2.0.3437 # # Generated Mon Jan 17 19:25:17 2011 PST by vadim # # files: * ipcop1.fw # # Compiled for iptables (any version) # # Endian firewall appliance, 2 interfaces: # br0 is GREEN # eth1 is RED # Do not forget to change IP addresses to # match your firewall. PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" test -x "$LOGGER" && $LOGGER -p info "$1" } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by AddressTable object $1" exit 1 } } getInterfaceVarName() { echo $1 | sed 's/\./_/' } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } find_program() { PGM=$1 $PGM /dev/null 2>&1; test $? = 127 && { echo "$PGM not found" exit 1 } } check_tools() { find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "atbl.1" "addr-table-1.tbl" } verify_interfaces() { : echo "Verifying interfaces: et0 eth1" for i in et0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } script_body() { # ================ IPv4 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 10.3.14.40 --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 10.3.14.40 --dport 80 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A INPUT -s 192.168.1.1 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.2 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.3/30 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.200 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.201 -j RULE_1 $IPTABLES -A INPUT -s 192.168.2.128/25 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.1 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.2 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.3/30 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.200 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.201 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.2.128/25 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A INPUT -s $at_atbl_1 -j RULE_2 done grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A FORWARD -s $at_atbl_1 -j RULE_2 done $IPTABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A RULE_2 -j DROP } reset_all() { : reset_iptables_v4 } case "$1" in start) check_tools check_run_time_address_table_files verify_interfaces prolog_commands script_body epilog_commands ;; stop) # on IPCOP "/etc/rc.firewall stop" purges all tables and chains # and then calls this script with command "stop", but there is # nothing left for us to do here. ;; reload) $0 stop $0 start ;; *) echo "Usage $0 {start|stop|reload}" ;; esac fwbuilder-5.1.0.3599/test/ipt/firewall91.fw.orig0000755000175000017500000002352511733011756022037 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:16 2012 PDT by vadim # # files: * firewall91.fw /etc/fw/firewall91.fw # # Compiled for iptables 1.4.3 # # test for ipv4options module for v1.4.3 and later FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0" for i in eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A FORWARD -p all -m dscp --dscp-class AF4 -m ipv4options --flags lsrr,router-alert -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A FORWARD -p all -m ipv4options --flags record-route -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --flags lsrr,ssrr -j DROP $IPTABLES -A FORWARD -p all -m ipv4options --flags timestamp -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A FORWARD -p all -m ipv4options --any -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:16 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall70.fw.orig0000755000175000017500000003342311733011756022032 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:05 2012 PDT by vadim # # files: * firewall70.fw iptables.sh # # Compiled for iptables (any version) # # this firewall translates outgoing connections using address of the particular interface (not external one). Also testing different cmbinations of objects in the policy rules on loopback interface. Finally, testing for a situation when dynamic interface "shades" a rule with old broadcast # Also the name of the script on the firewall is different # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars_0' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars_0' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars_0' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars_0' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:not_quite_long_ruleset_name:0: error: Chain name 'not_quite_long_ruleset_name_0_3' is longer than 30 characters. Rule not_quite_long_ruleset_name 0 (global) # firewall70:not_quite_long_ruleset_name:0: error: Chain name 'not_quite_long_ruleset_name_0_3' is longer than 30 characters. Rule not_quite_long_ruleset_name 0 (global) # firewall70:not_quite_long_ruleset_name:0: error: Chain name 'not_quite_long_ruleset_name_0_3' is longer than 30 characters. Rule not_quite_long_ruleset_name 0 (global) # firewall70:not_quite_long_ruleset_name:0: error: Chain name 'not_quite_long_ruleset_name_0_3' is longer than 30 characters. Rule not_quite_long_ruleset_name 0 (global) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 66.66.66.130/25" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set very_long_ruleset_name_should_be_gt_30_chars # # Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # echo "Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global)" # # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) # firewall70:very_long_ruleset_name_should_be_gt_30_chars:0: error: Chain name 'very_long_ruleset_name_should_be_gt_30_chars_0' is longer than 30 characters. Rule very_long_ruleset_name_should_be_gt_30_chars 0 (global) $IPTABLES -N very_long_ruleset_name_should_be_gt_30_chars $IPTABLES -N very_long_ruleset_name_should_be_gt_30_chars_0 $IPTABLES -A very_long_ruleset_name_should_be_gt_30_chars -j very_long_ruleset_name_should_be_gt_30_chars_0 $IPTABLES -A very_long_ruleset_name_should_be_gt_30_chars_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A very_long_ruleset_name_should_be_gt_30_chars_0 -j DROP # ================ Table 'filter', rule set not_quite_long_ruleset_name # # Rule not_quite_long_ruleset_name 0 (global) # echo "Rule not_quite_long_ruleset_name 0 (global)" # # firewall70:not_quite_long_ruleset_name:0: error: Chain name 'not_quite_long_ruleset_name_0_3' is longer than 30 characters. Rule not_quite_long_ruleset_name 0 (global) $IPTABLES -N not_quite_long_ruleset_name $IPTABLES -N Cid208737X59595.0 $IPTABLES -A not_quite_long_ruleset_name -s 22.22.22.0/24 -j Cid208737X59595.0 $IPTABLES -A not_quite_long_ruleset_name -s 33.33.33.0/24 -j Cid208737X59595.0 $IPTABLES -A Cid208737X59595.0 -d 66.66.66.130 -j RETURN $IPTABLES -A Cid208737X59595.0 -d 192.168.1.1 -j RETURN $IPTABLES -N not_quite_long_ruleset_name_0_3 $IPTABLES -A Cid208737X59595.0 -j not_quite_long_ruleset_name_0_3 $IPTABLES -A not_quite_long_ruleset_name_0_3 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A not_quite_long_ruleset_name_0_3 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:05 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall50.fw.orig0000755000175000017500000002532711733011756022034 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:56 2012 PDT by vadim # # files: * firewall50.fw /etc/fw/firewall50.fw # # Compiled for iptables (any version) # # testing action 'Continue' FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set rule2_branch # # Rule rule2_branch 0 (global) # echo "Rule rule2_branch 0 (global)" # $IPTABLES -N rule2_branch $IPTABLES -N Cid4734305F19714.0 $IPTABLES -A rule2_branch -j Cid4734305F19714.0 $IPTABLES -A Cid4734305F19714.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid4734305F19714.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N rule2_branch_0_3 $IPTABLES -A Cid4734305F19714.0 -j rule2_branch_0_3 $IPTABLES -A rule2_branch_0_3 -j LOG --log-level debug $IPTABLES -A rule2_branch_0_3 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 $IPTABLES -A INPUT -s 192.168.2.0/24 $IPTABLES -A OUTPUT -s 192.168.1.0/24 $IPTABLES -A OUTPUT -s 192.168.2.0/24 $IPTABLES -A FORWARD -s 192.168.1.0/24 $IPTABLES -A FORWARD -s 192.168.2.0/24 # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A INPUT -s 192.168.0.0/16 -j RULE_1 $IPTABLES -A OUTPUT -s 192.168.0.0/16 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.0.0/16 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level debug $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A INPUT -s 192.168.0.0/16 -j rule2_branch $IPTABLES -A OUTPUT -s 192.168.0.0/16 -j rule2_branch $IPTABLES -A FORWARD -s 192.168.0.0/16 -j rule2_branch # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -N Cid4733CF6F19714.0 $IPTABLES -A OUTPUT -j Cid4733CF6F19714.0 $IPTABLES -A INPUT -j Cid4733CF6F19714.0 $IPTABLES -A FORWARD -j Cid4733CF6F19714.0 $IPTABLES -A Cid4733CF6F19714.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid4733CF6F19714.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N RULE_3_3 $IPTABLES -A Cid4733CF6F19714.0 -j RULE_3_3 $IPTABLES -A RULE_3_3 -j LOG --log-level debug $IPTABLES -A RULE_3_3 -j DROP # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N RULE_4 $IPTABLES -A OUTPUT -j RULE_4 $IPTABLES -A INPUT -j RULE_4 $IPTABLES -A FORWARD -j RULE_4 $IPTABLES -A RULE_4 -j LOG --log-level debug $IPTABLES -A RULE_4 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:56 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/rc.firewall.local0000755000175000017500000001212211733011756021776 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:31:01 2012 PDT by vadim # # files: * rc.firewall.local /etc/rc.d//rc.firewall.local # # Compiled for iptables (any version) # # Endian firewall appliance, 2 interfaces: # br0 is GREEN # eth1 is RED # Do not forget to change IP addresses to # match your firewall. PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by AddressTable object $1" exit 1 } } getInterfaceVarName() { echo $1 | sed 's/\./_/' } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : check_file "atbl.1" "addr-table-1.tbl" } verify_interfaces() { : echo "Verifying interfaces: et0 eth1" for i in et0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } script_body() { # ================ IPv4 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 10.3.14.40 --dport 80 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -d 10.3.14.40 --dport 80 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A INPUT -s 192.168.1.1 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.2 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.3/30 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.200 -j RULE_1 $IPTABLES -A INPUT -s 192.168.1.201 -j RULE_1 $IPTABLES -A INPUT -s 192.168.2.128/25 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.1 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.2 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.3/30 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.200 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.1.201 -j RULE_1 $IPTABLES -A FORWARD -s 192.168.2.128/25 -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A RULE_1 -j DROP # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -N RULE_2 grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A INPUT -s $at_atbl_1 -j RULE_2 done grep -Ev '^#|^;|^\s*$' addr-table-1.tbl | while read L ; do set $L; at_atbl_1=$1; $IPTABLES -A FORWARD -s $at_atbl_1 -j RULE_2 done $IPTABLES -A RULE_2 -j LOG --log-level info --log-prefix "RULE 2 -- DENY " $IPTABLES -A RULE_2 -j DROP } reset_all() { : reset_iptables_v4 } case "$1" in start) check_tools check_run_time_address_table_files verify_interfaces prolog_commands script_body epilog_commands ;; stop) # on IPCOP "/etc/rc.firewall stop" purges all tables and chains # and then calls this script with command "stop", but there is # nothing left for us to do here. ;; reload) $0 stop $0 start ;; *) echo "Usage $0 {start|stop|reload}" ;; esac fwbuilder-5.1.0.3599/test/ipt/heartbeat_cluster_2_linux-2.fw.orig0000755000175000017500000004465311733011756025364 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * heartbeat_cluster_2_linux-2.fw /etc/heartbeat_cluster_2_linux-2.fw # # Compiled for iptables 1.4.0 # # linux-2:to_fw:: warning: ignoring cluster rule set "to_fw" because member firewall "linux-2" has rule set with the same name. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.3/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.3/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 20/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 20/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 heartbeat (automatic) # echo "Rule -4 heartbeat (automatic)" # $IPTABLES -N Cid3009X69605.3.0 $IPTABLES -A OUTPUT -o eth0 -p udp -m udp --dport 694 -j Cid3009X69605.3.0 $IPTABLES -A Cid3009X69605.3.0 -d 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.3.0 -d 192.168.100.1 -j ACCEPT # # Rule -3 heartbeat (automatic) # echo "Rule -3 heartbeat (automatic)" # $IPTABLES -N Cid3009X69605.2.0 $IPTABLES -A INPUT -i eth0 -p udp -m udp --dport 694 -j Cid3009X69605.2.0 $IPTABLES -A Cid3009X69605.2.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.2.0 -s 192.168.100.1 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -N Cid3009X69605.1.0 $IPTABLES -A OUTPUT -o eth0 -p udp -m udp --dport 3781 -j Cid3009X69605.1.0 $IPTABLES -A Cid3009X69605.1.0 -d 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.1.0 -d 192.168.100.1 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -N Cid3009X69605.0.0 $IPTABLES -A INPUT -i eth0 -p udp -m udp --dport 3781 -j Cid3009X69605.0.0 $IPTABLES -A Cid3009X69605.0.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.0.0 -s 192.168.100.1 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.1 -j to_fw $IPTABLES -A OUTPUT -d 172.24.0.3 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.1 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.3 -j to_fw $IPTABLES -A INPUT -j to_fw # # Rule 7 (global) # echo "Rule 7 (global)" # # branch rule set is different in members linux-1 and linux-2 $IPTABLES -A OUTPUT -d 172.24.0.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.1.2 -j to_fw $IPTABLES -A OUTPUT -d 192.168.100.1 -j to_fw $IPTABLES -A FORWARD -d 172.24.0.2 -j to_fw $IPTABLES -A FORWARD -d 192.168.1.2 -j to_fw $IPTABLES -A FORWARD -d 192.168.100.1 -j to_fw # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_8 $IPTABLES -A OUTPUT -d 172.24.0.3 -j RULE_8 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_8 $IPTABLES -A OUTPUT -d 192.168.1.3 -j RULE_8 $IPTABLES -A INPUT -j RULE_8 $IPTABLES -A RULE_8 -j LOG --log-level info --log-prefix "RULE 8 -- DENY " $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_10 $IPTABLES -A INPUT -m state --state NEW -j RULE_10 $IPTABLES -A FORWARD -m state --state NEW -j RULE_10 $IPTABLES -A RULE_10 -j LOG --log-level info --log-prefix "RULE 10 -- DENY " $IPTABLES -A RULE_10 -j DROP # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -N RULE_11 $IPTABLES -A OUTPUT -j RULE_11 $IPTABLES -A INPUT -j RULE_11 $IPTABLES -A FORWARD -j RULE_11 $IPTABLES -A RULE_11 -j LOG --log-level info --log-prefix "RULE 11 -- DENY " $IPTABLES -A RULE_11 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # # $IP route add 172.24.1.0/24 via 172.24.0.100 dev eth0 \ || route_command_error "0 (main)" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall25.fw.orig0000755000175000017500000005372211733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:30 2012 PDT by vadim # # files: * firewall25.fw /etc/fw/firewall25.fw # # Compiled for iptables 1.4.0 # # this firewall uses iptables-restore format. Firewall has wildcard interface ppp*; script is generated dynamically and then piped to iptables-restore # two rule sets for the filter table, to make sure there is only # one COMMIT for both # firewall25::: error: Dynamic interface ppp* should not have an IP address object attached to it. This IP address object will be ignored. # firewall25:policy_2_mangle:1: error: Action Reject is not allowed in mangle table # firewall25::: warning: Can not add virtual address for object address # firewall25::: warning: Can not add virtual address for object address FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: eth0 eth2" for i in eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # backup ssh access echo "-A INPUT -p tcp -m tcp -s 192.168.1.1/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT " echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop TCP sessions opened prior firewall restart echo "-A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " # drop packets that do not match any valid state echo "-A OUTPUT -m state --state INVALID -j DROP " echo "-A INPUT -m state --state INVALID -j DROP " echo "-A FORWARD -m state --state INVALID -j DROP " # ================ Table 'filter', rule set policy_2 # # Rule policy_2 0 (eth2) echo ":policy_2 - [0:0]" echo "-A policy_2 -o eth2 -m state --state NEW -j ACCEPT " # # Rule policy_2 1 (global) echo ":policy_2_1 - [0:0]" echo "-A policy_2 -j policy_2_1 " echo "-A policy_2_1 -j LOG " echo "-A policy_2_1 -j DROP " # # ================ Table 'filter', rule set mangle_ruleset # # Rule mangle_ruleset 0 (global) echo ":mangle_ruleset - [0:0]" echo ":mangle_ruleset_0 - [0:0]" echo "-A mangle_ruleset -j mangle_ruleset_0 " echo "-A mangle_ruleset_0 -j LOG " echo "-A mangle_ruleset_0 -j DROP " # # ================ Table 'filter', rule set Policy # # Rule 0 (ppp*) # ppp clients get addresses on 10.1.1.0 echo ":In_RULE_0 - [0:0]" echo "-A INPUT -i ppp+ -s ! 10.1.1.0/24 -j In_RULE_0 " echo "-A FORWARD -i ppp+ -s ! 10.1.1.0/24 -j In_RULE_0 " echo "-A In_RULE_0 -j LOG " echo "-A In_RULE_0 -j DROP " # # Rule 1 (ppp*) # ppp clients can not connect to the firewall echo ":In_RULE_1 - [0:0]" getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && echo "-A INPUT -i ppp+ -d $addr -j In_RULE_1 " done done echo "-A In_RULE_1 -j LOG " echo "-A In_RULE_1 -j DROP " # # Rule 2 (ppp*) echo ":In_RULE_2 - [0:0]" echo "-A INPUT -i ppp+ -j In_RULE_2 " echo "-A In_RULE_2 -j LOG " echo "-A In_RULE_2 -j DROP " # # Rule 3 (ppp*) # ppp clients can only connect to the mail # server and web proxy on DMZ echo "-A FORWARD -i ppp+ -p tcp -m tcp -m multiport -d 192.168.2.10 --dports 25,3128 -m state --state NEW -j ACCEPT " # # Rule 4 (ppp*) # ppp clients can not connect to # anything else on DMZ and # internal net echo ":In_RULE_4 - [0:0]" echo "-A INPUT -i ppp+ -d 192.168.1.0/24 -j In_RULE_4 " echo "-A INPUT -i ppp+ -d 192.168.2.0/24 -j In_RULE_4 " echo "-A FORWARD -i ppp+ -d 192.168.1.0/24 -j In_RULE_4 " echo "-A FORWARD -i ppp+ -d 192.168.2.0/24 -j In_RULE_4 " echo "-A In_RULE_4 -j LOG " echo "-A In_RULE_4 -j DROP " # # Rule 5 (eth2) echo ":In_RULE_5 - [0:0]" echo "-A INPUT -i eth2 -s ! 192.168.2.0/24 -j In_RULE_5 " echo "-A FORWARD -i eth2 -s ! 192.168.2.0/24 -j In_RULE_5 " echo "-A In_RULE_5 -j LOG " echo "-A In_RULE_5 -j DROP " # # Rule 6 (global) # hostF has the same IP address as firewal. echo ":RULE_6 - [0:0]" echo "-A OUTPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_6 " echo "-A INPUT -p icmp -m icmp -d 192.168.1.1 --icmp-type 8/0 -m state --state NEW -j RULE_6 " echo "-A RULE_6 -j LOG " echo "-A RULE_6 -j ACCEPT " # # Rule 7 (global) echo ":Cid417C681B.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j Cid417C681B.0 " getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && echo "-A Cid417C681B.0 -d $addr -j ACCEPT " done done echo "-A Cid417C681B.0 -d 192.168.1.1 -j ACCEPT " echo "-A Cid417C681B.0 -d 192.168.2.1 -j ACCEPT " echo "-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT " # # Rule 8 (global) getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && echo "-A OUTPUT -p tcp -m tcp -d $addr --dport 22 -m state --state NEW -j ACCEPT " done done getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && echo "-A INPUT -p tcp -m tcp -d $addr --dport 22 -m state --state NEW -j ACCEPT " done done # # Rule 9 (global) echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -d 192.168.1.1 --dport 22 -m state --state NEW -j ACCEPT " # # Rule 10 (global) echo "-A OUTPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT " echo "-A INPUT -p tcp -m tcp -m multiport -d 192.168.1.1 --dports 22,23 -m state --state NEW -j ACCEPT " # # Rule 11 (global) echo ":Cid417C6844.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid417C6844.0 " echo "-A Cid417C6844.0 -d 192.168.1.1 -j ACCEPT " echo "-A Cid417C6844.0 -d 192.168.2.1 -j ACCEPT " echo ":Cid417C6844.1 - [0:0]" echo "-A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid417C6844.1 " echo "-A Cid417C6844.1 -d 192.168.1.1 -j ACCEPT " echo "-A Cid417C6844.1 -d 192.168.2.1 -j ACCEPT " # # Rule 12 (global) echo ":Cid417C684F.0 - [0:0]" echo "-A OUTPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid417C684F.0 " echo ":RULE_12 - [0:0]" echo "-A Cid417C684F.0 -d 192.168.1.1 -j RULE_12 " echo "-A Cid417C684F.0 -d 192.168.2.1 -j RULE_12 " echo ":Cid417C684F.1 - [0:0]" echo "-A INPUT -p tcp -m tcp -m multiport --dports 22,23 -m state --state NEW -j Cid417C684F.1 " echo "-A Cid417C684F.1 -d 192.168.1.1 -j RULE_12 " echo "-A Cid417C684F.1 -d 192.168.2.1 -j RULE_12 " echo "-A RULE_12 -j LOG " echo "-A RULE_12 -j ACCEPT " # # Rule 13 (global) # firewall is part of Any, so compiler should # generate code in both FORWARD and # OUTPUT chains echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j ACCEPT " # # Rule 14 (global) # firewall is part of Any, compiler should # generate code for both FORWARD and # INPUT chains echo "-A INPUT -s 200.200.200.200 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 200.200.200.200 -m state --state NEW -j ACCEPT " # # Rule 15 (global) # because firewall has interface on network # internal_net, compiler should generate code # for both FORWARD and INPUT chains echo "-A INPUT -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT " echo "-A FORWARD -s 192.168.1.10 -d 192.168.1.0/24 -m state --state NEW -j ACCEPT " # # Rule 16 (global) echo ":Cid417C6878.0 - [0:0]" echo "-A OUTPUT -d 200.200.200.200 -m state --state NEW -j Cid417C6878.0 " echo "-A Cid417C6878.0 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid417C6878.0 -s 192.168.2.0/24 -j ACCEPT " echo ":Cid417C6878.1 - [0:0]" echo "-A FORWARD -d 200.200.200.200 -m state --state NEW -j Cid417C6878.1 " echo "-A Cid417C6878.1 -s 192.168.1.0/24 -j ACCEPT " echo "-A Cid417C6878.1 -s 192.168.2.0/24 -j ACCEPT " # # Rule 17 (global) # this rule should go to mangle table, # since we also have default rule that goes to mangle (TCPMSS) # and pure mangle ruleset, making sure all rules for # mangle table end up with one COMMIT echo "-A OUTPUT -m state --state NEW -j LOG " echo "-A INPUT -m state --state NEW -j LOG " echo "-A FORWARD -m state --state NEW -j LOG " # # Rule 18 (global) echo "-A OUTPUT -j policy_2 " echo "-A INPUT -j policy_2 " echo "-A FORWARD -j policy_2 " # # Rule 20 (eth0) echo "-A INPUT -i eth0 -j policy_2 " echo "-A FORWARD -i eth0 -j policy_2 " # # Rule 22 (global) # Automatically generated 'catch all' rule echo ":RULE_22 - [0:0]" echo "-A OUTPUT -j RULE_22 " echo "-A INPUT -j RULE_22 " echo "-A FORWARD -j RULE_22 " echo "-A RULE_22 -j LOG " echo "-A RULE_22 -j DROP " # echo COMMIT echo '*mangle' # ================ Table 'mangle', automatic rules echo "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" # ================ Table 'mangle', rule set policy_2_mangle # # Rule policy_2_mangle 0 (eth2) echo ":policy_2_mangle - [0:0]" echo "-A policy_2_mangle -o eth2 -m state --state NEW -j ACCEPT " # # Rule policy_2_mangle 1 (global) # SF bug report 3034628 # "iptables does not allow target REJECT in mangle table" # firewall25:policy_2_mangle:1: error: Action Reject is not allowed in mangle table echo ":policy_2_mangle_1 - [0:0]" echo "-A policy_2_mangle -p tcp -m tcp --dport 70 -j policy_2_mangle_1 " echo "-A policy_2_mangle_1 -j LOG " # # Rule policy_2_mangle 2 (global) echo ":policy_2_mangle_2 - [0:0]" echo "-A policy_2_mangle -j policy_2_mangle_2 " echo "-A policy_2_mangle_2 -j LOG " echo "-A policy_2_mangle_2 -j DROP " # # ================ Table 'mangle', rule set Policy # # Rule 17 (global) # this rule should go to mangle table, # since we also have default rule that goes to mangle (TCPMSS) # and pure mangle ruleset, making sure all rules for # mangle table end up with one COMMIT echo "-A OUTPUT -m state --state NEW -j MARK --set-mark 10" echo "-A PREROUTING -m state --state NEW -j MARK --set-mark 10" # # Rule 18 (global) echo ":policy_2 - [0:0]" echo "-A PREROUTING -j policy_2 " echo "-A POSTROUTING -j policy_2 " echo "-A FORWARD -j policy_2 " # # Rule 19 (global) echo "-A PREROUTING -j policy_2_mangle " echo "-A POSTROUTING -j policy_2_mangle " echo "-A FORWARD -j policy_2_mangle " # # Rule 20 (eth0) echo "-A PREROUTING -i eth0 -j policy_2 " echo "-A FORWARD -i eth0 -j policy_2 " # # Rule 21 (eth0) echo "-A PREROUTING -i eth0 -j policy_2_mangle " echo "-A FORWARD -i eth0 -j policy_2_mangle " # echo COMMIT echo '*nat' # ================ Table 'nat', rule set NAT echo :PREROUTING ACCEPT [0:0] echo :POSTROUTING ACCEPT [0:0] echo :OUTPUT ACCEPT [0:0] # # Rule 0 (NAT) echo "-A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j MASQUERADE " echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 " # # Rule 1 (NAT) echo "-A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 " echo "-A POSTROUTING -o ppp+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.23 " # # Rule 2 (NAT) getinterfaces ppp | while read I; do ivar=$(getInterfaceVarName $I) getaddr $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && echo "-A PREROUTING -p tcp -m tcp -d $addr --dport 22 -j DNAT --to-destination 192.168.1.10:22 " done done echo "-A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " echo "-A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 22 -j DNAT --to-destination 192.168.1.10:22 " # # Rule 3 (NAT) echo "-A PREROUTING -s 192.168.1.0/24 -d ! 200.200.200.200 -j DNAT --to-destination 192.168.2.10 " echo "-A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.10 -j SNAT --to-source 192.168.2.1 " # echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:30 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-ipv6-prolog-after-interfaces.fw.orig0000755000175000017500000002761511733011756027273 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:32 2012 PDT by vadim # # files: * firewall-ipv6-prolog-after-interfaces.fw /etc/firewall-ipv6-prolog-after-interfaces.fw # # Compiled for iptables (any version) # # Policy is configured as dual address family. Prolog is after configuration of interfaces FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" echo "This is prolog" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::21d:9ff:fe8b:8e94/64 1.1.1.1/24" "" update_addresses_of_interface "eth1 22.22.22.22/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 1.1.1.0/24 -j SNAT --to-source 22.22.22.22 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -i + -m state --state NEW -j ACCEPT # ================ IPv6 # ================ Table 'filter', automatic rules # accept established sessions $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop packets that do not match any valid state and log them $IP6TABLES -N drop_invalid $IP6TABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A INPUT -m state --state INVALID -j drop_invalid $IP6TABLES -A FORWARD -m state --state INVALID -j drop_invalid $IP6TABLES -A drop_invalid -j LOG --log-level debug --log-prefix "INVALID state -- DENY " $IP6TABLES -A drop_invalid -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IP6TABLES -A INPUT -m state --state NEW -j ACCEPT $IP6TABLES -A FORWARD -i + -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:32 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat ipv6" configure_interfaces verify_interfaces prolog_commands reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall29.fw.orig0000755000175000017500000003011511733011756022031 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:34 2012 PDT by vadim # # files: * firewall29.fw /etc/fw/firewall29.fw # # Compiled for iptables (any version) # # two dynamic interfaces in the same policy or NAT rule. Interfaces have a dot in their names # firewall29:Policy:: warning: Log prefix has been truncated to 29 characters # firewall29:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" getaddr eth0.200 i_eth0_200 getaddr6 eth0.200 i_eth0_200_v6 getnet eth0.200 i_eth0_200_network getnet6 eth0.200 i_eth0_200_v6_network getaddr eth0.100 i_eth0_100 getaddr6 eth0.100 i_eth0_100_v6 getnet eth0.100 i_eth0_100_network getnet6 eth0.100 i_eth0_100_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -t nat -A PREROUTING -d $i_eth0_100 -j DNAT --to-destination 192.168.1.10 done for i_eth0_200 in $i_eth0_200_list do test -n "$i_eth0_200" && $IPTABLES -t nat -A PREROUTING -d $i_eth0_200 -j DNAT --to-destination 192.168.1.10 done # ================ Table 'filter', rule set Policy # # Rule 0 (eth0.200) # echo "Rule 0 (eth0.200)" # for i_eth0_200 in $i_eth0_200_list do test -n "$i_eth0_200" && $IPTABLES -A OUTPUT -o eth0.200 -s $i_eth0_200 -m state --state NEW -j ACCEPT done # # Rule 1 (global) # echo "Rule 1 (global)" # for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A INPUT -s $i_eth0_100 -m state --state NEW -j ACCEPT done for i_eth0_200 in $i_eth0_200_list do test -n "$i_eth0_200" && $IPTABLES -A INPUT -s $i_eth0_200 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -A OUTPUT -s $i_eth0_100 -m state --state NEW -j ACCEPT done for i_eth0_200 in $i_eth0_200_list do test -n "$i_eth0_200" && $IPTABLES -A OUTPUT -s $i_eth0_200 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT for i_eth0_200 in $i_eth0_200_list do test -n "$i_eth0_200" && $IPTABLES -A OUTPUT -p udp -m udp -m multiport -d $i_eth0_200 --dports 68,67 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT for i_eth0_200 in $i_eth0_200_list do test -n "$i_eth0_200" && $IPTABLES -A INPUT -p udp -m udp -m multiport -d $i_eth0_200 --dports 68,67 -m state --state NEW -j ACCEPT done # # Rule 3 (global) # echo "Rule 3 (global)" # # should be --connlimit-above 10 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m connlimit --connlimit-above 10 -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # should be ! --connlimit-above 10 $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m connlimit \! --connlimit-above 10 -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -j RULE_5 $IPTABLES -A INPUT -j RULE_5 $IPTABLES -A FORWARD -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level debug --log-prefix "RULE 5 -- DENY on interface g" $IPTABLES -A RULE_5 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:34 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/optimizer_test.fwb0000644000175000017500000020045511733011756022340 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/test/ipt/firewall80.fw.orig0000755000175000017500000002465111733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:10 2012 PDT by vadim # # files: * firewall80.fw /etc/fw/firewall80.fw # # Compiled for iptables (any version) # # Branch rules in NAT # firewall80:NAT:0: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT_1 # # Rule NAT_1 0 (NAT) # echo "Rule NAT_1 0 (NAT)" # # DNAT Rule $IPTABLES -t nat -N NAT_1_PREROUTING $IPTABLES -t nat -A NAT_1_PREROUTING -d 192.0.2.1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -d 192.0.2.1 -j DNAT --to-destination 192.168.1.10 # # Rule NAT_1 1 (NAT) # echo "Rule NAT_1 1 (NAT)" # # SNAT rule $IPTABLES -t nat -N NAT_1_POSTROUTING $IPTABLES -t nat -A NAT_1_POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.0.2.1 # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # Branch rule with actual translation. Translation is ignored and warning should be issued # firewall80:NAT:0: warning: Translated Src, Dst and Srv are ignored in the NAT rule with action 'Branch' $IPTABLES -t nat -A POSTROUTING -d 192.0.2.1 -j NAT_1_POSTROUTING $IPTABLES -t nat -A PREROUTING -d 192.0.2.1 -j NAT_1_PREROUTING # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # # DNAT Rule $IPTABLES -t nat -A POSTROUTING -j NAT_1_POSTROUTING $IPTABLES -t nat -A PREROUTING -j NAT_1_PREROUTING # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # for #1686 $IPTABLES -t nat -A POSTROUTING -p tcp -m tcp -s 192.0.2.1 --dport 10000:11000 -j NAT_1_POSTROUTING $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.0.2.1 --dport 10000:11000 -j NAT_1_PREROUTING # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # # for #1686 $IPTABLES -t nat -A POSTROUTING -p tcp -m tcp -s 192.0.2.1 --dport 10000:11000 -j NAT_1_POSTROUTING $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.0.2.1 --dport 10000:11000 -j NAT_1_PREROUTING } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:10 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall22.fw.orig0000755000175000017500000002340411733011756022025 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:22 2012 PDT by vadim # # files: * firewall22.fw /etc/fw/firewall22.fw # # Compiled for iptables 1.2.9 # # testing NAT rules using custom services FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -m string --string test_pattern -j SNAT --to-source 192.168.2.1 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 192.168.2.1 -m string --string test_pattern -j DNAT --to-destination 192.168.1.10 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -m string --string test_pattern -j DNAT --to-destination 200.200.200.200 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d 200.200.200.200 -m string --string test_pattern -j SNAT --to-source 192.168.2.1 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth1 -s ! 192.168.2.0/24 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s ! 192.168.2.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -j LOG $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -N RULE_1 $IPTABLES -A OUTPUT -j RULE_1 $IPTABLES -A INPUT -j RULE_1 $IPTABLES -A FORWARD -j RULE_1 $IPTABLES -A RULE_1 -j LOG --log-level error $IPTABLES -A RULE_1 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:22 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/cluster-tests.fwb0000644000175000017500000143042711733011756022105 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/test/ipt/firewall2.fw.orig0000755000175000017500000022531011733011756021743 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:17 2012 PDT by vadim # # files: * firewall2.fw /etc/fw/firewall2.fw # # Compiled for iptables (any version) # # this object has several interfaces and shows different rules for NAT. Also testing policy rule options # firewall2:NAT:22: warning: Adding of virtual address for address range is not implemented (object ext_range) # firewall2:NAT:51: error: NAT rule can not change service types: CustomService to TCPService # firewall2:NAT:51: error: Translated Service should be either 'Original' or should contain object of the same type as Original Service. # firewall2:Policy:0: error: Rule '0 (eth1)' shadows rule '2 (fw2i1,3)' below it # firewall2:Policy:0: error: Rule '0 (eth1)' shadows rule '2 (fw2i1,3)' below it # firewall2:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it # firewall2:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it # firewall2:Policy:2: error: Rule '2 (fw2i1,3)' shadows rule '3 (eth1,eth3)' below it # firewall2:Policy:2: error: Rule '2 (fw2i1,3)' shadows rule '3 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '12 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '13 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '14 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '20 (global)' below it # firewall2:Policy:25: error: Rule '25 (global)' shadows rule '26 (global)' below it # firewall2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. # firewall2:Policy:29: error: Object 'net-err' has address or netmask 0.0.0.0, which is equivalent to 'any'. This is likely an error. # firewall2:Policy:29: error: Object 'net-err' has address or netmask 0.0.0.0, which is equivalent to 'any'. This is likely an error. # firewall2:Policy:29: error: Object 'net-err' has address or netmask 0.0.0.0, which is equivalent to 'any'. This is likely an error. # firewall2:Policy:: warning: Log prefix has been truncated to 29 characters # firewall2:Policy:: warning: Log prefix has been truncated to 29 characters FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24 192.168.1.10/24 192.168.1.50/24" "" update_addresses_of_interface "eth1 22.22.22.22/24 22.22.22.23/24 22.22.22.24/24 22.22.22.25/24 22.22.22.0/32 22.22.22.1/32 22.22.22.2/32 22.22.22.3/32 22.22.22.4/32 22.22.22.5/32 22.22.22.6/32 22.22.22.7/32 22.22.22.8/32 22.22.22.9/32 22.22.22.10/32 22.22.22.11/32 22.22.22.12/32 22.22.22.13/32 22.22.22.14/32 22.22.22.15/32 22.22.22.16/32 22.22.22.17/32 22.22.22.18/32 22.22.22.19/32 22.22.22.20/32 22.22.22.21/32 22.22.22.22/32 22.22.22.23/32 22.22.22.24/32 22.22.22.25/32 22.22.22.26/32 22.22.22.27/32 22.22.22.28/32 22.22.22.29/32 22.22.22.30/32 22.22.22.31/32 22.22.22.32/32 22.22.22.33/32 22.22.22.34/32 22.22.22.35/32 22.22.22.36/32 22.22.22.37/32 22.22.22.38/32 22.22.22.39/32 22.22.22.40/32 22.22.22.41/32 22.22.22.42/32 22.22.22.43/32 22.22.22.44/32 22.22.22.45/32 22.22.22.46/32 22.22.22.47/32 22.22.22.48/32 22.22.22.49/32 22.22.22.50/32 22.22.22.51/32 22.22.22.52/32 22.22.22.53/32 22.22.22.54/32 22.22.22.55/32 22.22.22.56/32 22.22.22.57/32 22.22.22.58/32 22.22.22.59/32 22.22.22.60/32 22.22.22.61/32 22.22.22.62/32 22.22.22.63/32 22.22.22.64/32 22.22.22.65/32 22.22.22.66/32 22.22.22.67/32 22.22.22.68/32 22.22.22.69/32 22.22.22.70/32 22.22.22.71/32 22.22.22.72/32 22.22.22.73/32 22.22.22.74/32 22.22.22.75/32 22.22.22.76/32 22.22.22.77/32 22.22.22.78/32 22.22.22.79/32 22.22.22.80/32 22.22.22.81/32 22.22.22.82/32 22.22.22.83/32 22.22.22.84/32 22.22.22.85/32 22.22.22.86/32 22.22.22.87/32 22.22.22.88/32 22.22.22.89/32 22.22.22.90/32 22.22.22.91/32 22.22.22.92/32 22.22.22.93/32 22.22.22.94/32 22.22.22.95/32 22.22.22.96/32 22.22.22.97/32 22.22.22.98/32 22.22.22.99/32 22.22.22.100/32 22.22.22.101/32 22.22.22.102/32 22.22.22.103/32 22.22.22.104/32 22.22.22.105/32 22.22.22.106/32 22.22.22.107/32 22.22.22.108/32 22.22.22.109/32 22.22.22.110/32 22.22.22.111/32 22.22.22.112/32 22.22.22.113/32 22.22.22.114/32 22.22.22.115/32 22.22.22.116/32 22.22.22.117/32 22.22.22.118/32 22.22.22.119/32 22.22.22.120/32 22.22.22.121/32 22.22.22.122/32 22.22.22.123/32 22.22.22.124/32 22.22.22.125/32 22.22.22.126/32 22.22.22.127/32 22.22.22.128/32 22.22.22.129/32 22.22.22.130/32 22.22.22.131/32 22.22.22.132/32 22.22.22.133/32 22.22.22.134/32 22.22.22.135/32 22.22.22.136/32 22.22.22.137/32 22.22.22.138/32 22.22.22.139/32 22.22.22.140/32 22.22.22.141/32 22.22.22.142/32 22.22.22.143/32 22.22.22.144/32 22.22.22.145/32 22.22.22.146/32 22.22.22.147/32 22.22.22.148/32 22.22.22.149/32 22.22.22.150/32 22.22.22.151/32 22.22.22.152/32 22.22.22.153/32 22.22.22.154/32 22.22.22.155/32 22.22.22.156/32 22.22.22.157/32 22.22.22.158/32 22.22.22.159/32 22.22.22.160/32 22.22.22.161/32 22.22.22.162/32 22.22.22.163/32 22.22.22.164/32 22.22.22.165/32 22.22.22.166/32 22.22.22.167/32 22.22.22.168/32 22.22.22.169/32 22.22.22.170/32 22.22.22.171/32 22.22.22.172/32 22.22.22.173/32 22.22.22.174/32 22.22.22.175/32 22.22.22.176/32 22.22.22.177/32 22.22.22.178/32 22.22.22.179/32 22.22.22.180/32 22.22.22.181/32 22.22.22.182/32 22.22.22.183/32 22.22.22.184/32 22.22.22.185/32 22.22.22.186/32 22.22.22.187/32 22.22.22.188/32 22.22.22.189/32 22.22.22.190/32 22.22.22.191/32 22.22.22.192/32 22.22.22.193/32 22.22.22.194/32 22.22.22.195/32 22.22.22.196/32 22.22.22.197/32 22.22.22.198/32 22.22.22.199/32 22.22.22.200/32 22.22.22.201/32 22.22.22.202/32 22.22.22.203/32 22.22.22.204/32 22.22.22.205/32 22.22.22.206/32 22.22.22.207/32 22.22.22.208/32 22.22.22.209/32 22.22.22.210/32 22.22.22.211/32 22.22.22.212/32 22.22.22.213/32 22.22.22.214/32 22.22.22.215/32 22.22.22.216/32 22.22.22.217/32 22.22.22.218/32 22.22.22.219/32 22.22.22.220/32 22.22.22.221/32 22.22.22.222/32 22.22.22.223/32 22.22.22.224/32 22.22.22.225/32 22.22.22.226/32 22.22.22.227/32 22.22.22.228/32 22.22.22.229/32 22.22.22.230/32 22.22.22.231/32 22.22.22.232/32 22.22.22.233/32 22.22.22.234/32 22.22.22.235/32 22.22.22.236/32 22.22.22.237/32 22.22.22.238/32 22.22.22.239/32 22.22.22.240/32 22.22.22.241/32 22.22.22.242/32 22.22.22.243/32 22.22.22.244/32 22.22.22.245/32 22.22.22.246/32 22.22.22.247/32 22.22.22.248/32 22.22.22.249/32 22.22.22.250/32 22.22.22.251/32 22.22.22.252/32 22.22.22.253/32 22.22.22.254/32" "" update_addresses_of_interface "eth3 22.22.23.23/24 22.22.25.50/24 22.22.23.24/24" "" update_addresses_of_interface "eth2 192.168.2.1/24 192.168.2.40/24" "" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 3 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 0/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/0 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p icmp -m icmp -s 192.168.1.0/24 --icmp-type 11/1 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 50 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 $IPTABLES -t nat -A POSTROUTING -o eth1 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -p 88 -s 192.168.1.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.23.23 $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth3 -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 5 (NAT) # echo "Rule 5 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.25.50 # # Rule 6 (NAT) # echo "Rule 6 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 # # Rule 7 (NAT) # echo "Rule 7 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.23 --random $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.24 --random $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.10 -j SNAT --to-source 22.22.22.25 --random # # Rule 8 (NAT) # echo "Rule 8 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1 # # Rule 9 (NAT) # echo "Rule 9 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.0/24 -j SNAT --to-source 192.168.2.1 # # Rule 10 (NAT) # echo "Rule 10 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.0/24 -j SNAT --to-source 192.168.2.1 $IPTABLES -t nat -A POSTROUTING -o eth2 -s 192.168.1.0/24 -d 192.168.2.0/24 -j SNAT --to-source 192.168.2.40 # # Rule 11 (NAT) # echo "Rule 11 (NAT)" # $IPTABLES -t nat -N Cid3D1519E8.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid3D1519E8.0 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid3D1519E8.0 $IPTABLES -t nat -A Cid3D1519E8.0 -s 22.22.22.22 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.0 -s 22.22.23.23 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.0 -s 22.22.25.50 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.0 -s 192.168.1.1 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.0 -s 192.168.2.1 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.0 -s 192.168.2.40 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.10 -j ACCEPT $IPTABLES -t nat -A OUTPUT -d 192.168.2.11 -j ACCEPT $IPTABLES -t nat -N Cid3D1519E8.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.10 -j Cid3D1519E8.1 $IPTABLES -t nat -A POSTROUTING -d 192.168.2.11 -j Cid3D1519E8.1 $IPTABLES -t nat -A Cid3D1519E8.1 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.1 -s 192.168.1.20 -j ACCEPT $IPTABLES -t nat -N Cid3D1519E8.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.10 -j Cid3D1519E8.2 $IPTABLES -t nat -A PREROUTING -d 192.168.2.11 -j Cid3D1519E8.2 $IPTABLES -t nat -A Cid3D1519E8.2 -s 192.168.1.10 -j ACCEPT $IPTABLES -t nat -A Cid3D1519E8.2 -s 192.168.1.20 -j ACCEPT # # Rule 12 (NAT) # echo "Rule 12 (NAT)" # $IPTABLES -t nat -N Cid3D151BA0.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.10 -j Cid3D151BA0.0 $IPTABLES -t nat -A POSTROUTING -s 192.168.1.20 -j Cid3D151BA0.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.10 -j Cid3D151BA0.0 $IPTABLES -t nat -A PREROUTING -s 192.168.1.20 -j Cid3D151BA0.0 $IPTABLES -t nat -A Cid3D151BA0.0 -d 192.168.2.10 -j RETURN $IPTABLES -t nat -A Cid3D151BA0.0 -d 192.168.2.11 -j RETURN $IPTABLES -t nat -A Cid3D151BA0.0 -j ACCEPT # # Rule 13 (NAT) # echo "Rule 13 (NAT)" # $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 50 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p 88 -d 22.22.22.23 -j DNAT --to-destination 192.168.1.10 # # Rule 14 (NAT) # echo "Rule 14 (NAT)" # $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 3 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 0/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/1 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 15 (NAT) # echo "Rule 15 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.23.23 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -s 22.22.25.50 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 16 (NAT) # echo "Rule 16 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -s 200.200.200.200 -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 18 (NAT) # echo "Rule 18 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.24 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -m multiport -d 22.22.22.25 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.23 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.24 --dports 80,119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m multiport -d 22.22.22.25 --dports 80,119 -j DNAT --to-destination 192.168.1.10 # # Rule 19 (NAT) # echo "Rule 19 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 119 -j DNAT --to-destination 192.168.1.10 # # Rule 20 (NAT) # echo "Rule 20 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.20 -j SNAT --to-source 22.22.23.24 # # Rule 21 (NAT) # echo "Rule 21 (NAT)" # $IPTABLES -t nat -A PREROUTING -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 $IPTABLES -t nat -A OUTPUT -d 22.22.23.24 -j DNAT --to-destination 192.168.1.20 # # Rule 22 (NAT) # echo "Rule 22 (NAT)" # # firewall2:NAT:22: warning: Adding of virtual address for address range is not implemented (object ext_range) $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 22.22.22.100-22.22.22.110 # # Rule 23 (NAT) # echo "Rule 23 (NAT)" # # NETMAP $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 24 (NAT) # echo "Rule 24 (NAT)" # # NETMAP $IPTABLES -t nat -A PREROUTING -d 22.22.22.0/24 -j NETMAP --to 192.168.1.0/24 # # Rule 25 (NAT) # echo "Rule 25 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.1 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.2.40 --dport 10000:11000 -j DNAT --to-destination 192.168.1.10:10000-11000 # # Rule 26 (NAT) # echo "Rule 26 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.23.23 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.25.50 --dport 80 -j DNAT --to-destination 192.168.1.10 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 192.168.1.10 --dport 80 -j SNAT --to-source 192.168.1.1 # # Rule 27 (NAT) # echo "Rule 27 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.23 --dport 80 -j DNAT --to-destination 192.168.1.10:25 # # Rule 28 (NAT) # echo "Rule 28 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 80 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.23.23 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.25.50 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.1 --dport 443 -j REDIRECT --to-ports 3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.2.40 --dport 443 -j REDIRECT --to-ports 3128 # # Rule 29 (NAT) # echo "Rule 29 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.10-192.168.1.100 # # Rule 30 (NAT) # echo "Rule 30 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 8080 -j DNAT --to-destination 192.168.1.11-192.168.1.15 # # Rule 31 (NAT) # echo "Rule 31 (NAT)" # # transparent proxy rule $IPTABLES -t nat -A PREROUTING -s 192.168.1.0/24 -d ! 22.22.22.23 -j DNAT --to-destination 192.168.2.10 # # Rule 33 (NAT) # echo "Rule 33 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080 # # Rule 34 (NAT) # echo "Rule 34 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:8080 # # Rule 35 (NAT) # echo "Rule 35 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 36 (NAT) # echo "Rule 36 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s ! 192.168.1.10 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s ! 192.168.1.10 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 37 (NAT) # echo "Rule 37 (NAT)" # $IPTABLES -t nat -N Cid40F195C3.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid40F195C3.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -d ! 192.168.1.50 --dport 80 -j Cid40F195C3.0 $IPTABLES -t nat -A Cid40F195C3.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid40F195C3.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid40F195C3.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # # Rule 38 (NAT) # echo "Rule 38 (NAT)" # $IPTABLES -t nat -N Cid40F1C52F.1 $IPTABLES -t nat -A POSTROUTING -o eth0 -j Cid40F1C52F.1 $IPTABLES -t nat -A Cid40F1C52F.1 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid40F1C52F.1 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -N Cid40F1C52F.0 $IPTABLES -t nat -A Cid40F1C52F.1 -j Cid40F1C52F.0 $IPTABLES -t nat -A Cid40F1C52F.0 -p tcp -m tcp --dport 80 -j RETURN $IPTABLES -t nat -A Cid40F1C52F.0 -j SNAT --to-source 192.168.1.1 # # Rule 39 (NAT) # echo "Rule 39 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.10:3128 $IPTABLES -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.10 --dport 3128 -j SNAT --to-source 192.168.1.1 # # Rule 40 (NAT) # echo "Rule 40 (NAT)" # # this is the "exception" rule # used in support req. originally $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 41 (NAT) # echo "Rule 41 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 42 (NAT) # echo "Rule 42 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 43 (NAT) # echo "Rule 43 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid46D67A4324736.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid46D67A4324736.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid46D67A4324736.0 $IPTABLES -t nat -A Cid46D67A4324736.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid46D67A4324736.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid46D67A4324736.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 44 (NAT) # echo "Rule 44 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid46D67A5924736.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid46D67A5924736.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid46D67A5924736.0 $IPTABLES -t nat -A Cid46D67A5924736.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid46D67A5924736.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid46D67A5924736.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:3128 # # Rule 45 (NAT) # echo "Rule 45 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid46D49F3624736.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid46D49F3624736.0 $IPTABLES -t nat -A Cid46D49F3624736.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid46D49F3624736.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid46D49F3624736.0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # # Rule 46 (NAT) # echo "Rule 46 (NAT)" # # "exception" rule in the pair # from a support req. $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --dport 80 -j SNAT --to-source 22.22.22.22 $IPTABLES -t nat -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.20 --dport 80 -j SNAT --to-source 22.22.22.22 # # Rule 47 (NAT) # echo "Rule 47 (NAT)" # # testing transparent proxy # roules for a support req. $IPTABLES -t nat -N Cid46D6AA2F24736.0 $IPTABLES -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j Cid46D6AA2F24736.0 $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 80 -j Cid46D6AA2F24736.0 $IPTABLES -t nat -A Cid46D6AA2F24736.0 -s 192.168.1.10 -j RETURN $IPTABLES -t nat -A Cid46D6AA2F24736.0 -s 192.168.1.20 -j RETURN $IPTABLES -t nat -A Cid46D6AA2F24736.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.50:3128 # # Rule 48 (NAT) # echo "Rule 48 (NAT)" # $IPTABLES -t nat -A PREROUTING -p tcp -m tcp -s 192.168.1.0/24 --dport 3050:3051 -j DNAT --to-destination :700 $IPTABLES -t nat -A POSTROUTING -o eth+ -p tcp -m tcp -s 192.168.1.0/24 --dport 700 -j SNAT --to-source 192.168.1.10 # # Rule 49 (NAT) # echo "Rule 49 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp --dport 9040 -j REDIRECT --to-ports 9040 # # Rule 50 (NAT) # echo "Rule 50 (NAT)" # $IPTABLES -t nat -A OUTPUT -p tcp -m tcp -m owner --uid-owner anonymous -j REDIRECT --to-ports 9040 # # Rule 52 (NAT) # echo "Rule 52 (NAT)" # $IPTABLES -t nat -A OUTPUT -p udp -m udp -m owner --uid-owner anonymous -j REDIRECT --to-ports 53 # ================ Table 'filter', rule set Policy # # Rule 0 (eth1) # echo "Rule 0 (eth1)" # # Anti-spoofing rule # firewall2:Policy:0: error: Rule '0 (eth1)' shadows rule '2 (fw2i1,3)' below it # firewall2:Policy:0: error: Rule '0 (eth1)' shadows rule '3 (eth1,eth3)' below it $IPTABLES -N In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A INPUT -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.22.22 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.23.23 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 22.22.25.50 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.1 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.2.40 -j In_RULE_0 $IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j In_RULE_0 $IPTABLES -A In_RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 0 -- DENY " --ulog-qthreshold 1 $IPTABLES -A In_RULE_0 -j DROP # # Rule 1 (eth1) # echo "Rule 1 (eth1)" # # Anti-spoofing rule $IPTABLES -N Cid3AFB6710.0 $IPTABLES -A OUTPUT -o eth1 -j Cid3AFB6710.0 $IPTABLES -A Cid3AFB6710.0 -s 22.22.22.22 -j RETURN $IPTABLES -A Cid3AFB6710.0 -s 22.22.23.23 -j RETURN $IPTABLES -A Cid3AFB6710.0 -s 22.22.25.50 -j RETURN $IPTABLES -A Cid3AFB6710.0 -s 192.168.1.1 -j RETURN $IPTABLES -A Cid3AFB6710.0 -s 192.168.2.1 -j RETURN $IPTABLES -A Cid3AFB6710.0 -s 192.168.2.40 -j RETURN $IPTABLES -N Out_RULE_1_3 $IPTABLES -A Cid3AFB6710.0 -j Out_RULE_1_3 $IPTABLES -A Out_RULE_1_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "Iface: global RULE 1 -- DENY " --ulog-qthreshold 1 $IPTABLES -A Out_RULE_1_3 -j DROP $IPTABLES -N Cid3AFB6710.1 $IPTABLES -A FORWARD -o eth1 -j Cid3AFB6710.1 $IPTABLES -A Cid3AFB6710.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid3AFB6710.1 -j Out_RULE_1_3 # # Rule 2 (fw2i1,3) # echo "Rule 2 (fw2i1,3)" # # testing group in "interface" # this rule should be identical to rule 3 # firewall2:Policy:2: error: Rule '2 (fw2i1,3)' shadows rule '3 (eth1,eth3)' below it $IPTABLES -N In_RULE_2 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_2 $IPTABLES -A In_RULE_2 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 2 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_2 -j DROP # # Rule 3 (eth1,eth3) # echo "Rule 3 (eth1,eth3)" # $IPTABLES -N In_RULE_3 $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A FORWARD -i eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 --dports 68,67 -j In_RULE_3 $IPTABLES -A In_RULE_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 3 - DENY **" --ulog-qthreshold 1 $IPTABLES -A In_RULE_3 -j DROP # # Rule 4 (eth1,eth3) # echo "Rule 4 (eth1,eth3)" # # testing choice of chains in case when several # interfaces are used and rule matches 'any' or # broadcast # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '5 (eth1,eth3)' below it # firewall2:Policy:4: error: Rule '4 (eth1,eth3)' shadows rule '6 (eth1,eth3)' below it $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 5 (eth1,eth3) # echo "Rule 5 (eth1,eth3)" # $IPTABLES -A INPUT -i eth1 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth3 -p udp -m udp -m multiport -s 0.0.0.0 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 6 (eth1,eth3) # echo "Rule 6 (eth1,eth3)" # $IPTABLES -A OUTPUT -o eth1 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth3 -p udp -m udp -m multiport -s 192.168.1.0/24 -d 255.255.255.255 --dports 68,67 -m state --state NEW -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid3D6748D9.0 $IPTABLES -A OUTPUT -j Cid3D6748D9.0 $IPTABLES -A INPUT -j Cid3D6748D9.0 $IPTABLES -A FORWARD -j Cid3D6748D9.0 $IPTABLES -A Cid3D6748D9.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -N RULE_7_3 $IPTABLES -A Cid3D6748D9.0 -j RULE_7_3 $IPTABLES -A RULE_7_3 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 7 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_7_3 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # # block fragments $IPTABLES -N RULE_8 $IPTABLES -A OUTPUT -p all -f -j RULE_8 $IPTABLES -A INPUT -p all -f -j RULE_8 $IPTABLES -A FORWARD -p all -f -j RULE_8 $IPTABLES -A RULE_8 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 8 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_8 -j DROP # # Rule 9 (global) # echo "Rule 9 (global)" # # sends TCP RST and makes custom record # in the log $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A INPUT -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A FORWARD -p tcp -m tcp --dport 113 -j RULE_9 $IPTABLES -A RULE_9 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "IDENT" --ulog-qthreshold 1 $IPTABLES -A RULE_9 -p tcp -m tcp -j REJECT --reject-with tcp-reset # # Rule 10 (global) # echo "Rule 10 (global)" # # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '11 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '12 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '13 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '14 (global)' below it # firewall2:Policy:10: error: Rule '10 (global)' shadows rule '20 (global)' below it # firewall2:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A INPUT -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -j RULE_10 $IPTABLES -A RULE_10 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 10 - REJECT **" --ulog-qthreshold 1 $IPTABLES -A RULE_10 -j REJECT --reject-with icmp-net-unreachable # # Rule 11 (global) # echo "Rule 11 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid39895X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid39895X70161.0 $IPTABLES -A Cid39895X70161.0 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid39895X70161.0 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid39895X70161.0 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid39895X70161.0 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid39895X70161.0 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid39895X70161.0 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid39895X70161.0 -d 192.168.1.100 -j ACCEPT $IPTABLES -N Cid39895X70161.1 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid39895X70161.1 $IPTABLES -A Cid39895X70161.1 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid39895X70161.1 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid39895X70161.1 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid39895X70161.1 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid39895X70161.1 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid39895X70161.1 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid39895X70161.1 -d 192.168.1.100 -j ACCEPT $IPTABLES -N Cid39895X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid39895X70161.2 $IPTABLES -A Cid39895X70161.2 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid39895X70161.2 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid39895X70161.2 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid39895X70161.2 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid39895X70161.2 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid39895X70161.2 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid39895X70161.2 -d 192.168.1.100 -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid39909X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid39909X70161.0 $IPTABLES -A Cid39909X70161.0 -s 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid39909X70161.0 -s 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid39909X70161.0 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid39909X70161.0 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid39909X70161.0 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid39909X70161.0 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid39909X70161.0 -s 192.168.1.100 -j ACCEPT $IPTABLES -N Cid39909X70161.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid39909X70161.1 $IPTABLES -A Cid39909X70161.1 -s 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid39909X70161.1 -s 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid39909X70161.1 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid39909X70161.1 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid39909X70161.1 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid39909X70161.1 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid39909X70161.1 -s 192.168.1.100 -j ACCEPT $IPTABLES -N Cid39909X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid39909X70161.2 $IPTABLES -A Cid39909X70161.2 -s 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid39909X70161.2 -s 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid39909X70161.2 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid39909X70161.2 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid39909X70161.2 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid39909X70161.2 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid39909X70161.2 -s 192.168.1.100 -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid131093X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid131093X70161.0 $IPTABLES -N Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.10/31 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.12/30 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.16/28 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.32/27 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.64/27 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.96/30 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.0 -s 222.222.222.100 -j Cid131093X70161.1 $IPTABLES -A Cid131093X70161.1 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid131093X70161.1 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid131093X70161.1 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid131093X70161.1 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid131093X70161.1 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid131093X70161.1 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid131093X70161.1 -d 192.168.1.100 -j ACCEPT $IPTABLES -N Cid131093X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid131093X70161.2 $IPTABLES -N Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.10/31 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.12/30 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.16/28 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.32/27 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.64/27 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.96/30 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.2 -s 222.222.222.100 -j Cid131093X70161.3 $IPTABLES -A Cid131093X70161.3 -d 192.168.1.10/31 -j ACCEPT $IPTABLES -A Cid131093X70161.3 -d 192.168.1.12/30 -j ACCEPT $IPTABLES -A Cid131093X70161.3 -d 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid131093X70161.3 -d 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid131093X70161.3 -d 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid131093X70161.3 -d 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid131093X70161.3 -d 192.168.1.100 -j ACCEPT # # Rule 14 (global) # echo "Rule 14 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid131076X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid131076X70161.0 $IPTABLES -N Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.10/31 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.12/30 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.16/28 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.32/27 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.64/27 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.96/30 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.0 -s 192.168.1.100 -j Cid131076X70161.1 $IPTABLES -A Cid131076X70161.1 -d 222.222.222.10/31 -j ACCEPT $IPTABLES -A Cid131076X70161.1 -d 222.222.222.12/30 -j ACCEPT $IPTABLES -A Cid131076X70161.1 -d 222.222.222.16/28 -j ACCEPT $IPTABLES -A Cid131076X70161.1 -d 222.222.222.32/27 -j ACCEPT $IPTABLES -A Cid131076X70161.1 -d 222.222.222.64/27 -j ACCEPT $IPTABLES -A Cid131076X70161.1 -d 222.222.222.96/30 -j ACCEPT $IPTABLES -A Cid131076X70161.1 -d 222.222.222.100 -j ACCEPT $IPTABLES -N Cid131076X70161.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid131076X70161.2 $IPTABLES -N Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.10/31 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.12/30 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.16/28 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.32/27 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.64/27 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.96/30 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.2 -s 192.168.1.100 -j Cid131076X70161.3 $IPTABLES -A Cid131076X70161.3 -d 222.222.222.10/31 -j ACCEPT $IPTABLES -A Cid131076X70161.3 -d 222.222.222.12/30 -j ACCEPT $IPTABLES -A Cid131076X70161.3 -d 222.222.222.16/28 -j ACCEPT $IPTABLES -A Cid131076X70161.3 -d 222.222.222.32/27 -j ACCEPT $IPTABLES -A Cid131076X70161.3 -d 222.222.222.64/27 -j ACCEPT $IPTABLES -A Cid131076X70161.3 -d 222.222.222.96/30 -j ACCEPT $IPTABLES -A Cid131076X70161.3 -d 222.222.222.100 -j ACCEPT # # Rule 15 (global) # echo "Rule 15 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid57999X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid57999X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid57999X70161.0 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid57999X70161.0 $IPTABLES -A Cid57999X70161.0 -d 192.168.1.10/31 -j RETURN $IPTABLES -A Cid57999X70161.0 -d 192.168.1.12/30 -j RETURN $IPTABLES -A Cid57999X70161.0 -d 192.168.1.16/28 -j RETURN $IPTABLES -A Cid57999X70161.0 -d 192.168.1.32/27 -j RETURN $IPTABLES -A Cid57999X70161.0 -d 192.168.1.64/27 -j RETURN $IPTABLES -A Cid57999X70161.0 -d 192.168.1.96/30 -j RETURN $IPTABLES -A Cid57999X70161.0 -d 192.168.1.100 -j RETURN $IPTABLES -A Cid57999X70161.0 -j ACCEPT # # Rule 16 (global) # echo "Rule 16 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid58016X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid58016X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid58016X70161.0 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid58016X70161.0 $IPTABLES -A Cid58016X70161.0 -s 192.168.1.10/31 -j RETURN $IPTABLES -A Cid58016X70161.0 -s 192.168.1.12/30 -j RETURN $IPTABLES -A Cid58016X70161.0 -s 192.168.1.16/28 -j RETURN $IPTABLES -A Cid58016X70161.0 -s 192.168.1.32/27 -j RETURN $IPTABLES -A Cid58016X70161.0 -s 192.168.1.64/27 -j RETURN $IPTABLES -A Cid58016X70161.0 -s 192.168.1.96/30 -j RETURN $IPTABLES -A Cid58016X70161.0 -s 192.168.1.100 -j RETURN $IPTABLES -A Cid58016X70161.0 -j ACCEPT # # Rule 17 (global) # echo "Rule 17 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid76132X70161.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid76132X70161.0 $IPTABLES -A Cid76132X70161.0 -d 192.168.1.0 -j RETURN $IPTABLES -A Cid76132X70161.0 -j ACCEPT $IPTABLES -N Cid76132X70161.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid76132X70161.1 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid76132X70161.1 $IPTABLES -A Cid76132X70161.1 -d 192.168.1.10/31 -j RETURN $IPTABLES -A Cid76132X70161.1 -d 192.168.1.12/30 -j RETURN $IPTABLES -A Cid76132X70161.1 -d 192.168.1.16/28 -j RETURN $IPTABLES -A Cid76132X70161.1 -d 192.168.1.32/27 -j RETURN $IPTABLES -A Cid76132X70161.1 -d 192.168.1.64/27 -j RETURN $IPTABLES -A Cid76132X70161.1 -d 192.168.1.96/30 -j RETURN $IPTABLES -A Cid76132X70161.1 -d 192.168.1.100 -j RETURN $IPTABLES -A Cid76132X70161.1 -j ACCEPT # # Rule 18 (global) # echo "Rule 18 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -N Cid76149X70161.0 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid76149X70161.0 $IPTABLES -A Cid76149X70161.0 -s 192.168.1.0 -j RETURN $IPTABLES -A Cid76149X70161.0 -j ACCEPT $IPTABLES -N Cid76149X70161.1 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid76149X70161.1 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid76149X70161.1 $IPTABLES -A Cid76149X70161.1 -s 192.168.1.10/31 -j RETURN $IPTABLES -A Cid76149X70161.1 -s 192.168.1.12/30 -j RETURN $IPTABLES -A Cid76149X70161.1 -s 192.168.1.16/28 -j RETURN $IPTABLES -A Cid76149X70161.1 -s 192.168.1.32/27 -j RETURN $IPTABLES -A Cid76149X70161.1 -s 192.168.1.64/27 -j RETURN $IPTABLES -A Cid76149X70161.1 -s 192.168.1.96/30 -j RETURN $IPTABLES -A Cid76149X70161.1 -s 192.168.1.100 -j RETURN $IPTABLES -A Cid76149X70161.1 -j ACCEPT # # Rule 19 (global) # echo "Rule 19 (global)" # # using module iprange if # iptables version is >= 1.2.11 # also test for bug #2526173 $IPTABLES -N RULE_19 $IPTABLES -A INPUT -s 0.0.0.0 -j RULE_19 $IPTABLES -A OUTPUT -s 0.0.0.0 -j RULE_19 $IPTABLES -A RULE_19 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 19 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_19 -j DROP # # Rule 20 (global) # echo "Rule 20 (global)" # # using module iprange if # iptables version is >= 1.2.11 $IPTABLES -A INPUT -p udp -m udp -s 192.168.1.1 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -N Cid42387X35957.0 $IPTABLES -A INPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid42387X35957.0 $IPTABLES -A Cid42387X35957.0 -s 192.168.1.2/31 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.4/30 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.8/29 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid42387X35957.0 -s 192.168.1.100 -j ACCEPT $IPTABLES -A OUTPUT -p udp -m udp -s 192.168.1.1 --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -N Cid42387X35957.1 $IPTABLES -A OUTPUT -p udp -m udp --dport 161 -m state --state NEW -j Cid42387X35957.1 $IPTABLES -A Cid42387X35957.1 -s 192.168.1.2/31 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.4/30 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.8/29 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid42387X35957.1 -s 192.168.1.100 -j ACCEPT $IPTABLES -N Cid42387X35957.2 $IPTABLES -A FORWARD -p udp -m udp --dport 161 -m state --state NEW -j Cid42387X35957.2 $IPTABLES -A Cid42387X35957.2 -s 192.168.1.2/31 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.4/30 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.8/29 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.16/28 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.32/27 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.64/27 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.96/30 -j ACCEPT $IPTABLES -A Cid42387X35957.2 -s 192.168.1.100 -j ACCEPT # # Rule 21 (global) # echo "Rule 21 (global)" # $IPTABLES -N Cid3DD1E1E0.0 $IPTABLES -A INPUT -p icmp -m icmp -s 192.168.2.0/24 --icmp-type any -m state --state NEW -j Cid3DD1E1E0.0 $IPTABLES -N RULE_21 $IPTABLES -A Cid3DD1E1E0.0 -d 192.168.2.1 -j RULE_21 $IPTABLES -A Cid3DD1E1E0.0 -d 192.168.2.40 -j RULE_21 $IPTABLES -A RULE_21 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 21 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_21 -j ACCEPT # # Rule 22 (global) # echo "Rule 22 (global)" # $IPTABLES -N Cid3D8FC846.0 $IPTABLES -A FORWARD -d 211.11.11.11 -m state --state NEW -j Cid3D8FC846.0 $IPTABLES -A Cid3D8FC846.0 -s 192.168.1.10 -j ACCEPT $IPTABLES -A Cid3D8FC846.0 -s 192.168.1.20 -j ACCEPT # # Rule 23 (global) # echo "Rule 23 (global)" # $IPTABLES -N Cid3D8FC984.0 $IPTABLES -A FORWARD -s 211.11.11.11 -m state --state NEW -j Cid3D8FC984.0 $IPTABLES -A Cid3D8FC984.0 -d 192.168.1.10 -j ACCEPT $IPTABLES -A Cid3D8FC984.0 -d 192.168.1.20 -j ACCEPT # # Rule 24 (global) # echo "Rule 24 (global)" # $IPTABLES -N Cid3DCBFEA0.0 $IPTABLES -A OUTPUT -p tcp -m tcp -j Cid3DCBFEA0.0 $IPTABLES -A INPUT -p tcp -m tcp -j Cid3DCBFEA0.0 $IPTABLES -A FORWARD -p tcp -m tcp -j Cid3DCBFEA0.0 $IPTABLES -A Cid3DCBFEA0.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid3DCBFEA0.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid3DCBFEA0.0 -p tcp -m tcp -j REJECT --reject-with tcp-reset $IPTABLES -N Cid3DCBFEA0.1 $IPTABLES -A OUTPUT -j Cid3DCBFEA0.1 $IPTABLES -A INPUT -j Cid3DCBFEA0.1 $IPTABLES -A FORWARD -j Cid3DCBFEA0.1 $IPTABLES -A Cid3DCBFEA0.1 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid3DCBFEA0.1 -s 192.168.2.0/24 -j RETURN $IPTABLES -A Cid3DCBFEA0.1 -j REJECT --reject-with icmp-net-unreachable # # Rule 25 (global) # echo "Rule 25 (global)" # # firewall2:Policy:25: error: Rule '25 (global)' shadows rule '26 (global)' below it $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.2.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.2.0/24 -m state --state NEW -j ACCEPT # # Rule 26 (global) # echo "Rule 26 (global)" # $IPTABLES -N RULE_26 $IPTABLES -A INPUT -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A FORWARD -s 192.168.1.0/24 -j RULE_26 $IPTABLES -A RULE_26 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 26 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_26 -j DROP # # Rule 27 (global) # echo "Rule 27 (global)" # # host-fw2 has the same address as # one of the firewall's interfaces $IPTABLES -N RULE_27 $IPTABLES -A OUTPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_27 $IPTABLES -A INPUT -p tcp -m tcp -d 22.22.22.22 --dport 21 -m state --state NEW -m limit --limit 5/minute --limit-burst 10 -j RULE_27 $IPTABLES -A RULE_27 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 27 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_27 -j ACCEPT # # Rule 28 (global) # echo "Rule 28 (global)" # $IPTABLES -N Cid3C447BCB.0 $IPTABLES -A OUTPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid3C447BCB.0 $IPTABLES -N RULE_28 $IPTABLES -A Cid3C447BCB.0 -d 22.22.22.22 -j RULE_28 $IPTABLES -A Cid3C447BCB.0 -d 22.22.23.23 -j RULE_28 $IPTABLES -A Cid3C447BCB.0 -d 22.22.25.50 -j RULE_28 $IPTABLES -A Cid3C447BCB.0 -d 192.168.1.1 -j RULE_28 $IPTABLES -A Cid3C447BCB.0 -d 192.168.2.1 -j RULE_28 $IPTABLES -A Cid3C447BCB.0 -d 192.168.2.40 -j RULE_28 $IPTABLES -N Cid3C447BCB.1 $IPTABLES -A INPUT -p tcp -m tcp --dport 21 -m state --state NEW -j Cid3C447BCB.1 $IPTABLES -A Cid3C447BCB.1 -d 22.22.22.22 -j RULE_28 $IPTABLES -A Cid3C447BCB.1 -d 22.22.23.23 -j RULE_28 $IPTABLES -A Cid3C447BCB.1 -d 22.22.25.50 -j RULE_28 $IPTABLES -A Cid3C447BCB.1 -d 192.168.1.1 -j RULE_28 $IPTABLES -A Cid3C447BCB.1 -d 192.168.2.1 -j RULE_28 $IPTABLES -A Cid3C447BCB.1 -d 192.168.2.40 -j RULE_28 $IPTABLES -A RULE_28 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 28 - ACCEPT **" --ulog-qthreshold 1 $IPTABLES -A RULE_28 -j ACCEPT # # Rule 29 (global) # echo "Rule 29 (global)" # # 'catch all' rule # firewall2:Policy:29: error: Object 'net-err' has address or netmask 0.0.0.0, which is equivalent to 'any'. This is likely an error. $IPTABLES -N RULE_29 $IPTABLES -A INPUT -s 1.2.3.0/0 -j RULE_29 $IPTABLES -A OUTPUT -s 1.2.3.0/0 -j RULE_29 $IPTABLES -A FORWARD -s 1.2.3.0/0 -j RULE_29 $IPTABLES -A RULE_29 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 29 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_29 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:17 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall93.fw.orig0000755000175000017500000003173311733011756022041 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:18 2012 PDT by vadim # # files: * firewall93.fw /etc/fw/firewall93.fw # # Compiled for iptables (any version) # # testing shell code generated for dynamic interface with "-" in the name FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 ppp0 ppp-dsl" for i in eth0 ppp0 ppp-dsl ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 fe80::20c:29ff:fe28:c078/64 192.0.2.1/24" "" getaddr ppp0 i_ppp0 getaddr6 ppp0 i_ppp0_v6 getnet ppp0 i_ppp0_network getnet6 ppp0 i_ppp0_v6_network getaddr ppp-dsl i_ppp_dsl getaddr6 ppp-dsl i_ppp_dsl_v6 getnet ppp-dsl i_ppp_dsl_network getnet6 ppp-dsl i_ppp_dsl_v6_network } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (ppp0) # echo "Rule 0 (ppp0)" # for i_ppp_dsl in $i_ppp_dsl_list do test -n "$i_ppp_dsl" && $IPTABLES -A INPUT -i ppp0 -s $i_ppp_dsl -m state --state NEW -j ACCEPT done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A INPUT -i ppp0 -s $i_ppp0 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -i ppp0 -s 192.0.2.1 -m state --state NEW -j ACCEPT for i_ppp_dsl in $i_ppp_dsl_list do test -n "$i_ppp_dsl" && $IPTABLES -A FORWARD -i ppp0 -s $i_ppp_dsl -m state --state NEW -j ACCEPT done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A FORWARD -i ppp0 -s $i_ppp0 -m state --state NEW -j ACCEPT done $IPTABLES -A FORWARD -i ppp0 -s 192.0.2.1 -m state --state NEW -j ACCEPT # # Rule 1 (ppp-dsl) # echo "Rule 1 (ppp-dsl)" # for i_ppp_dsl in $i_ppp_dsl_list do test -n "$i_ppp_dsl" && $IPTABLES -A INPUT -i ppp-dsl -s $i_ppp_dsl -m state --state NEW -j ACCEPT done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A INPUT -i ppp-dsl -s $i_ppp0 -m state --state NEW -j ACCEPT done $IPTABLES -A INPUT -i ppp-dsl -s 192.0.2.1 -m state --state NEW -j ACCEPT for i_ppp_dsl in $i_ppp_dsl_list do test -n "$i_ppp_dsl" && $IPTABLES -A FORWARD -i ppp-dsl -s $i_ppp_dsl -m state --state NEW -j ACCEPT done for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A FORWARD -i ppp-dsl -s $i_ppp0 -m state --state NEW -j ACCEPT done $IPTABLES -A FORWARD -i ppp-dsl -s 192.0.2.1 -m state --state NEW -j ACCEPT # ================ IPv6 # ================ Table 'filter', rule set Policy_v6 # # Rule Policy_v6 0 (ppp-dsl) # echo "Rule Policy_v6 0 (ppp-dsl)" # $IP6TABLES -N Policy_v6 for i_ppp_dsl_v6 in $i_ppp_dsl_v6_list do test -n "$i_ppp_dsl_v6" && $IP6TABLES -A Policy_v6 -i ppp-dsl -s $i_ppp_dsl_v6 -m state --state NEW -j ACCEPT done for i_ppp0_v6 in $i_ppp0_v6_list do test -n "$i_ppp0_v6" && $IP6TABLES -A Policy_v6 -i ppp-dsl -s $i_ppp0_v6 -m state --state NEW -j ACCEPT done $IP6TABLES -A Policy_v6 -i ppp-dsl -s fe80::20c:29ff:fe28:c078 -m state --state NEW -j ACCEPT # # Rule Policy_v6 1 (ppp0) # echo "Rule Policy_v6 1 (ppp0)" # for i_ppp_dsl_v6 in $i_ppp_dsl_v6_list do test -n "$i_ppp_dsl_v6" && $IP6TABLES -A Policy_v6 -i ppp0 -s $i_ppp_dsl_v6 -m state --state NEW -j ACCEPT done for i_ppp0_v6 in $i_ppp0_v6_list do test -n "$i_ppp0_v6" && $IP6TABLES -A Policy_v6 -i ppp0 -s $i_ppp0_v6 -m state --state NEW -j ACCEPT done $IP6TABLES -A Policy_v6 -i ppp0 -s fe80::20c:29ff:fe28:c078 -m state --state NEW -j ACCEPT } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 reset_iptables_v6 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:18 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " ipv6" configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall2-7.fw.orig0000755000175000017500000003015611733011756022111 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:33 2012 PDT by vadim # # files: * firewall2-7.fw /etc/fw/firewall2-7.fw # # Compiled for iptables (any version) # # tests for nat rules with inbound and outbound interfaces with complex interface configuration # firewall2-7::: warning: Can not add virtual address 22.22.22.0 (object external_net) FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth3 33.33.33.25/29" "" update_addresses_of_interface "eth2 33.33.33.3/29 33.33.33.4/29" "" update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "bridge0 10.1.1.1/24" "" update_addresses_of_interface "vlan101 222.222.222.222/24 222.222.222.40/24" "" } script_body() { echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # drop TCP sessions opened prior firewall restart $IPTABLES -A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP $IPTABLES -A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP # drop packets that do not match any valid state and log them $IPTABLES -N drop_invalid $IPTABLES -A OUTPUT -m state --state INVALID -j drop_invalid $IPTABLES -A INPUT -m state --state INVALID -j drop_invalid $IPTABLES -A FORWARD -m state --state INVALID -j drop_invalid $IPTABLES -A drop_invalid -j ULOG --ulog-nlgroup 1 --ulog-qthreshold 1 --ulog-prefix "INVALID state -- DENY " $IPTABLES -A drop_invalid -j DROP # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # # NETMAP and no -o itf $IPTABLES -t nat -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 22.22.22.0/24 # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o bridge+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o eth+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 $IPTABLES -t nat -A POSTROUTING -o vlan+ -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o vlan101 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # # $IPTABLES -t nat -A POSTROUTING -o ! eth3 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.40 # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # # REDIRECT $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # 'catch all' rule $IPTABLES -N RULE_0 $IPTABLES -A OUTPUT -j RULE_0 $IPTABLES -A INPUT -j RULE_0 $IPTABLES -A FORWARD -j RULE_0 $IPTABLES -A RULE_0 -m limit --limit 5/second -j ULOG --ulog-nlgroup 1 --ulog-prefix "RULE 0 - DENY **" --ulog-qthreshold 1 $IPTABLES -A RULE_0 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:33 2012 by vadim" check_tools check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all prolog_commands script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall51.fw.orig0000755000175000017500000003363211733011756022033 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:58 2012 PDT by vadim # # files: * firewall51.fw /etc/fw/firewall51.fw # # Compiled for iptables (any version) # # testing branching rules that point # at rule sets defined in object # firewall-base-rulesets FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set rule2_branch # # Rule rule2_branch 0 (global) # echo "Rule rule2_branch 0 (global)" # $IPTABLES -N rule2_branch $IPTABLES -N Cid484A060A4626.0 $IPTABLES -A rule2_branch -j Cid484A060A4626.0 $IPTABLES -A Cid484A060A4626.0 -s 192.168.1.0/24 -j RETURN $IPTABLES -A Cid484A060A4626.0 -s 192.168.2.0/24 -j RETURN $IPTABLES -N rule2_branch_0_3 $IPTABLES -A Cid484A060A4626.0 -j rule2_branch_0_3 $IPTABLES -A rule2_branch_0_3 -j LOG --log-level debug $IPTABLES -A rule2_branch_0_3 -j DROP # ================ Table 'filter', rule set mail_server_inbound # # Rule mail_server_inbound 0 (global) # echo "Rule mail_server_inbound 0 (global)" # $IPTABLES -N mail_server_inbound $IPTABLES -A mail_server_inbound -i + -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT # # Rule mail_server_inbound 1 (global) # echo "Rule mail_server_inbound 1 (global)" # $IPTABLES -A mail_server_inbound -i + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A mail_server_inbound -i + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set mail_server_outbound # # Rule mail_server_outbound 0 (global) # echo "Rule mail_server_outbound 0 (global)" # $IPTABLES -N mail_server_outbound $IPTABLES -A mail_server_outbound -o + -p tcp -m tcp -m multiport --dports 53,25 -m state --state NEW -j ACCEPT $IPTABLES -A mail_server_outbound -o + -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT # # Rule mail_server_outbound 1 (global) # echo "Rule mail_server_outbound 1 (global)" # $IPTABLES -A mail_server_outbound -o + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A mail_server_outbound -o + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set web_server_inbound # # Rule web_server_inbound 0 (global) # echo "Rule web_server_inbound 0 (global)" # $IPTABLES -N web_server_inbound $IPTABLES -A web_server_inbound -i + -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT # # Rule web_server_inbound 1 (global) # echo "Rule web_server_inbound 1 (global)" # $IPTABLES -A web_server_inbound -i + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A web_server_inbound -i + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule web_server_inbound 2 (global) # echo "Rule web_server_inbound 2 (global)" # $IPTABLES -N web_server_inbound_2 $IPTABLES -A web_server_inbound -p tcp -m tcp --dport 3306 -j web_server_inbound_2 $IPTABLES -A web_server_inbound_2 -j LOG --log-level debug --log-prefix "web_server_inbound/2 -- DENY" $IPTABLES -A web_server_inbound_2 -j DROP # ================ Table 'filter', rule set web_server_outbound # # Rule web_server_outbound 0 (global) # echo "Rule web_server_outbound 0 (global)" # $IPTABLES -N web_server_outbound $IPTABLES -A web_server_outbound -o + -p icmp -m icmp --icmp-type 3 -m state --state NEW -j ACCEPT $IPTABLES -A web_server_outbound -o + -p icmp -m icmp --icmp-type 8/0 -m state --state NEW -j ACCEPT # # Rule web_server_outbound 1 (global) # echo "Rule web_server_outbound 1 (global)" # $IPTABLES -A web_server_outbound -o + -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A web_server_outbound -o + -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT # ================ Table 'filter', rule set base-ruleset # # Rule base-ruleset 0 (global) # echo "Rule base-ruleset 0 (global)" # $IPTABLES -N base-ruleset $IPTABLES -N Cid41961X1271.0 $IPTABLES -A base-ruleset -p tcp -m tcp --dport 22 -m state --state NEW -j Cid41961X1271.0 $IPTABLES -A Cid41961X1271.0 -d 33.33.33.33 -j ACCEPT $IPTABLES -A Cid41961X1271.0 -d 172.16.1.1 -j ACCEPT $IPTABLES -A Cid41961X1271.0 -d 192.168.100.1 -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.10 -j mail_server_inbound $IPTABLES -A FORWARD -d 192.168.1.10 -j mail_server_inbound # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A INPUT -s 192.168.1.10 -j mail_server_outbound $IPTABLES -A FORWARD -s 192.168.1.10 -j mail_server_outbound # # Rule 2 (global) # echo "Rule 2 (global)" # $IPTABLES -A OUTPUT -d 192.168.1.20 -j web_server_inbound $IPTABLES -A FORWARD -d 192.168.1.20 -j web_server_inbound # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A INPUT -s 192.168.1.20 -j web_server_outbound $IPTABLES -A FORWARD -s 192.168.1.20 -j web_server_outbound # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -A OUTPUT -j base-ruleset $IPTABLES -A INPUT -j base-ruleset $IPTABLES -A FORWARD -j base-ruleset # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -j rule2_branch $IPTABLES -A OUTPUT -s 192.168.1.0/24 -j rule2_branch $IPTABLES -A FORWARD -s 192.168.1.0/24 -j rule2_branch } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:58 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/openais_cluster_1_linux-2.fw.orig0000755000175000017500000004367711733011756025067 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:42 2012 PDT by vadim # # files: * openais_cluster_1_linux-2.fw /etc/openais_cluster_1_linux-2.fw # # Compiled for iptables 1.4.0 # # openais_cluster_1:Routing:1: error: Object "gw1" used as gateway in the routing rule 1 (main) is not in the same local network as interface eth1 FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1 lo" for i in eth0 eth1 lo ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 172.24.0.3/16" "172.24.0.1/16" update_addresses_of_interface "eth1 192.168.1.3/24" "192.168.1.1/24" update_addresses_of_interface "lo 127.0.0.1/8" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 172.24.0.1 # ================ Table 'filter', rule set to_fw # # Rule to_fw 0 (global) # echo "Rule to_fw 0 (global)" # # hashlimit 20/sec $IPTABLES -N to_fw $IPTABLES -N to_fw_0 $IPTABLES -A to_fw -m hashlimit --hashlimit 20/second --hashlimit-name htable_rule_0 -j to_fw_0 $IPTABLES -A to_fw_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A to_fw_0 -j DROP # ================ Table 'filter', rule set Policy # # Rule -4 openais (automatic) # echo "Rule -4 openais (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 226.94.1.1 --dport 5405 -j ACCEPT # # Rule -3 openais (automatic) # echo "Rule -3 openais (automatic)" # $IPTABLES -N Cid3009X69605.2.0 $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 226.94.1.1 --dport 5405 -j Cid3009X69605.2.0 $IPTABLES -A Cid3009X69605.2.0 -s 172.24.0.2 -j ACCEPT $IPTABLES -A Cid3009X69605.2.0 -s 192.168.100.1 -j ACCEPT # # Rule -2 CONNTRACK (automatic) # echo "Rule -2 CONNTRACK (automatic)" # $IPTABLES -A OUTPUT -o eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule -1 CONNTRACK (automatic) # echo "Rule -1 CONNTRACK (automatic)" # $IPTABLES -A INPUT -i eth0 -p udp -m udp -d 225.0.0.50 --dport 3781 -j ACCEPT # # Rule 0 (eth0) # echo "Rule 0 (eth0)" # $IPTABLES -A INPUT -i eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p vrrp -d 224.0.0.18 -m state --state NEW -j ACCEPT # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # anti spoofing rule $IPTABLES -N In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A INPUT -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 172.24.0.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.1 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.3 -m state --state NEW -j In_RULE_1 $IPTABLES -A FORWARD -i eth0 -s 192.168.1.0/24 -m state --state NEW -j In_RULE_1 $IPTABLES -A In_RULE_1 -j LOG --log-level info --log-prefix "RULE 1 -- DENY " $IPTABLES -A In_RULE_1 -j DROP # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 22 -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # # SSH Access to firewall is permitted # only from internal network $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.3 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 22 -m state --state NEW -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # # Firewall uses one of the machines # on internal network for DNS $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A OUTPUT -p udp -m udp -d 192.168.1.0/24 --dport 53 -m state --state NEW -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- ACCEPT " $IPTABLES -A RULE_5 -j ACCEPT # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -A OUTPUT -d 172.24.0.1 -j DROP $IPTABLES -A OUTPUT -d 172.24.0.3 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.1 -j DROP $IPTABLES -A OUTPUT -d 192.168.1.3 -j DROP $IPTABLES -A INPUT -j DROP # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N RULE_7 $IPTABLES -A OUTPUT -d 172.24.0.1 -j RULE_7 $IPTABLES -A OUTPUT -d 172.24.0.3 -j RULE_7 $IPTABLES -A OUTPUT -d 192.168.1.1 -j RULE_7 $IPTABLES -A OUTPUT -d 192.168.1.3 -j RULE_7 $IPTABLES -A INPUT -j RULE_7 $IPTABLES -A RULE_7 -j LOG --log-level info --log-prefix "RULE 7 -- DENY " $IPTABLES -A RULE_7 -j DROP # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A INPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -s 192.168.1.0/24 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.168.1.0/24 -m state --state NEW -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N RULE_9 $IPTABLES -A OUTPUT -m state --state NEW -j RULE_9 $IPTABLES -A INPUT -m state --state NEW -j RULE_9 $IPTABLES -A FORWARD -m state --state NEW -j RULE_9 $IPTABLES -A RULE_9 -j LOG --log-level info --log-prefix "RULE 9 -- DENY " $IPTABLES -A RULE_9 -j DROP # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N RULE_10 $IPTABLES -A OUTPUT -j RULE_10 $IPTABLES -A INPUT -j RULE_10 $IPTABLES -A FORWARD -j RULE_10 $IPTABLES -A RULE_10 -j LOG --log-level info --log-prefix "RULE 10 -- DENY " $IPTABLES -A RULE_10 -j DROP # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v '\( proto kernel \)\|\(default via \)' | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." # # Rule 0 (main) # echo "Routing rule 0 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # Rule 1 (main) # echo "Routing rule 1 (main)" # # Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below. # # ============== EQUAL COST MULTI PATH ============ # echo "Activating ecmp routing rules..." # # Multipath Rule derived from the following routing rules: # # Rule 0 (main) # # Rule 1 (main) # interface vrrp1 belongs to a different firewall (cluster) # $IP route add 172.24.1.0/24 \ nexthop via 172.24.0.100 dev eth0 \ nexthop via 172.24.0.100 dev eth1 \ || route_command_error "1" restore_script_output echo "...done." } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:42 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall74.fw.orig0000755000175000017500000002344311733011756022037 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:09 2012 PDT by vadim # # files: * firewall74.fw /etc/fw/firewall74.fw # # Compiled for iptables 1.4.0 # # this firewall uses iptables-restore format and has no rules FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IPTABLES_RESTORE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : echo "Verifying interfaces: eth0 eth2" for i in eth0 eth2 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth2 192.168.2.1/24" "" } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 ( echo '*filter' # ================ Table 'filter', automatic rules echo :INPUT DROP [0:0] echo :FORWARD DROP [0:0] echo :OUTPUT DROP [0:0] # accept established sessions echo "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT " echo "-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT " # backup ssh access echo "-A INPUT -p tcp -m tcp -s 192.168.1.1/255.255.255.255 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT " echo "-A OUTPUT -p tcp -m tcp -d 192.168.1.1/255.255.255.255 --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT " # drop TCP sessions opened prior firewall restart echo "-A INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " echo "-A FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP " # drop packets that do not match any valid state echo "-A OUTPUT -m state --state INVALID -j DROP " echo "-A INPUT -m state --state INVALID -j DROP " echo "-A FORWARD -m state --state INVALID -j DROP " echo COMMIT ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:09 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall19.fw.orig0000755000175000017500000003724011733011756022036 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:15 2012 PDT by vadim # # files: * firewall19.fw /etc/fw/firewall19.fw # # Compiled for iptables (any version) # # testing different cmbinations of objects in the policy rules on loopback interface # firewall19:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth2 eth0 eth1 lo ppp0" for i in eth2 eth0 eth1 lo ppp0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth2 66.66.66.1/25" "" update_addresses_of_interface "eth0 192.168.1.1/24" "" update_addresses_of_interface "eth1 66.66.66.130/25" "" update_addresses_of_interface "lo 127.0.0.1/8" "" getaddr ppp0 i_ppp0 getaddr6 ppp0 i_ppp0_v6 getnet ppp0 i_ppp0_network getnet6 ppp0 i_ppp0_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (lo) # echo "Rule 0 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A OUTPUT -o lo -d $i_ppp0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o lo -d 66.66.66.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 66.66.66.130 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 127.0.0.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 192.168.1.1 -m state --state NEW -j ACCEPT # # Rule 1 (lo) # echo "Rule 1 (lo)" # $IPTABLES -A INPUT -i lo -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i lo -d 66.66.66.130 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i lo -d 66.66.66.1 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i lo -d 127.0.0.1 -m state --state NEW -j ACCEPT for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A INPUT -i lo -d $i_ppp0 -m state --state NEW -j ACCEPT done $IPTABLES -A OUTPUT -o lo -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 66.66.66.130 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 66.66.66.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 127.0.0.1 -m state --state NEW -j ACCEPT for i_ppp0 in $i_ppp0_list do test -n "$i_ppp0" && $IPTABLES -A OUTPUT -o lo -d $i_ppp0 -m state --state NEW -j ACCEPT done # # Rule 2 (lo) # echo "Rule 2 (lo)" # $IPTABLES -A INPUT -i lo -d 192.168.1.1 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 192.168.1.1 -m state --state NEW -j ACCEPT # # Rule 3 (lo) # echo "Rule 3 (lo)" # $IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 2/second -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 2/second -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 2/second -j ACCEPT # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N RULE_5 $IPTABLES -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_5 $IPTABLES -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_5 $IPTABLES -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RULE_5 $IPTABLES -A RULE_5 -j LOG --log-level info --log-prefix "RULE 5 -- DENY " $IPTABLES -A RULE_5 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # $IPTABLES -N Cid3EFBA6FE.0 $IPTABLES -A OUTPUT -j Cid3EFBA6FE.0 $IPTABLES -A INPUT -j Cid3EFBA6FE.0 $IPTABLES -A FORWARD -j Cid3EFBA6FE.0 $IPTABLES -A Cid3EFBA6FE.0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -A Cid3EFBA6FE.0 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 5190 --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 5190 --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 5190 --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -A INPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 5190 --tcp-flags SYN,RST,ACK SYN -j REJECT --reject-with icmp-host-prohibited $IPTABLES -A OUTPUT -p tcp -m tcp -s 192.168.1.0/24 --dport 5190 --tcp-flags SYN,RST,ACK SYN -j REJECT --reject-with icmp-host-prohibited $IPTABLES -A FORWARD -p tcp -m tcp -s 192.168.1.0/24 --dport 5190 --tcp-flags SYN,RST,ACK SYN -j REJECT --reject-with icmp-host-prohibited # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid40038EB9.0 $IPTABLES -A OUTPUT -j Cid40038EB9.0 $IPTABLES -A INPUT -j Cid40038EB9.0 $IPTABLES -A FORWARD -j Cid40038EB9.0 $IPTABLES -A Cid40038EB9.0 -p tcp -m tcp --dport 5190 --tcp-flags SYN,RST,ACK SYN -j RETURN $IPTABLES -A Cid40038EB9.0 -j REJECT --reject-with icmp-host-prohibited # # Rule 10 (global) # echo "Rule 10 (global)" # # firewall19:Policy:10: warning: Rule action 'Reject' with TCP RST can be used only with TCP services. $IPTABLES -A INPUT -s 192.168.1.0/24 -p tcp ! --syn -dport 5190 -m state --state NEW -j REJECT --reject-with icmp-host-prohibited $IPTABLES -A OUTPUT -s 192.168.1.0/24 -p tcp ! --syn -dport 5190 -m state --state NEW -j REJECT --reject-with icmp-host-prohibited $IPTABLES -A FORWARD -s 192.168.1.0/24 -p tcp ! --syn -dport 5190 -m state --state NEW -j REJECT --reject-with icmp-host-prohibited # # Rule 11 (global) # echo "Rule 11 (global)" # $IPTABLES -A OUTPUT -p tcp -m tcp -d 66.66.66.130 --dport 3128 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d 127.0.0.1 --dport 3128 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -d 66.66.66.130 --dport 3128 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp -d 127.0.0.1 --dport 3128 -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -N RULE_12 $IPTABLES -A OUTPUT -j RULE_12 $IPTABLES -A INPUT -j RULE_12 $IPTABLES -A FORWARD -j RULE_12 $IPTABLES -A RULE_12 -j LOG --log-level info --log-prefix "RULE 12 -- DENY " $IPTABLES -A RULE_12 -j DROP } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:15 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall33-1.fw.orig0000755000175000017500000003672211733011756022174 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:40 2012 PDT by vadim # # files: * firewall33-1.fw /etc/fw/firewall33-1.fw # # Compiled for iptables (any version) # # firewall33-1:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33-1:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33-1:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33-1:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: eth0 eth1" for i in eth0 eth1 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "eth0 192.0.2.1/24" "" update_addresses_of_interface "eth1 192.168.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N Policy $IPTABLES -A Policy -s 157.166.226.25 -m state --state NEW -j ACCEPT $IPTABLES -A Policy -s 157.166.226.26 -m state --state NEW -j ACCEPT $IPTABLES -A Policy -s 157.166.255.18 -m state --state NEW -j ACCEPT $IPTABLES -A Policy -s 157.166.255.19 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A Policy -s www.cnn.com -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall33-1:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode $IPTABLES -A Policy -s 192.0.2.1 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A Policy -s buildmaster -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid4386E38318346.0 $IPTABLES -A Policy -j Cid4386E38318346.0 $IPTABLES -A Cid4386E38318346.0 -d 157.166.226.25 -j RETURN $IPTABLES -A Cid4386E38318346.0 -d 157.166.226.26 -j RETURN $IPTABLES -A Cid4386E38318346.0 -d 157.166.255.18 -j RETURN $IPTABLES -A Cid4386E38318346.0 -d 157.166.255.19 -j RETURN $IPTABLES -A Cid4386E38318346.0 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid4386E37718346.0 $IPTABLES -A Policy -j Cid4386E37718346.0 $IPTABLES -A Cid4386E37718346.0 -d www.cnn.com -j RETURN $IPTABLES -A Cid4386E37718346.0 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # # firewall33-1:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode $IPTABLES -N Cid43867C3018346.0 $IPTABLES -A Policy -m state --state NEW -j Cid43867C3018346.0 $IPTABLES -A Cid43867C3018346.0 -d 192.0.2.1 -j RETURN $IPTABLES -A Cid43867C3018346.0 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid4386C10D18346.0 $IPTABLES -A Policy -m state --state NEW -j Cid4386C10D18346.0 $IPTABLES -A Cid4386C10D18346.0 -d buildmaster -j RETURN $IPTABLES -A Cid4386C10D18346.0 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N Cid438728A918346.0 $IPTABLES -A Policy -m state --state NEW -j Cid438728A918346.0 $IPTABLES -A Cid438728A918346.0 -d 74.125.224.112 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.113 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.114 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.115 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.116 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.226.25 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.226.26 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.255.18 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.255.19 -j RETURN $IPTABLES -A Cid438728A918346.0 -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid438728BA18346.0 $IPTABLES -A Policy -m state --state NEW -j Cid438728BA18346.0 $IPTABLES -A Cid438728BA18346.0 -d www.cnn.com -j RETURN $IPTABLES -A Cid438728BA18346.0 -d www.google.com -j RETURN $IPTABLES -A Cid438728BA18346.0 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N Cid438728CD18346.0 $IPTABLES -A Policy -m state --state NEW -j Cid438728CD18346.0 $IPTABLES -A Cid438728CD18346.0 -d www.google.com -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.226.25 -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.226.26 -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.255.18 -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.255.19 -j RETURN $IPTABLES -A Cid438728CD18346.0 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # test for bug #1905718 # Group of DNS Name objects considered empty $IPTABLES -A Policy -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A Policy -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A Policy -d 72.55.148.116 -m state --state NEW -j ACCEPT $IPTABLES -A Policy -d 207.251.84.150 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N RULE_13 $IPTABLES -A Policy -j RULE_13 $IPTABLES -A RULE_13 -j LOG --log-level info --log-prefix "RULE 13 -- DENY " $IPTABLES -A RULE_13 -j DROP # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # # branches to firewall33:Policy which uses DNSName objects # testing for bug 1485 $IPTABLES -A OUTPUT -j Policy $IPTABLES -A INPUT -j Policy $IPTABLES -A FORWARD -j Policy } ip_forward() { : echo 1 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:40 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall-server-1-s.fw.orig0000755000175000017500000002472411733011756023571 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:17:33 2012 PDT by vadim # # files: * firewall-server-1-s.fw /etc/fw/firewall-server-1-s.fw # # Compiled for iptables (any version) # # fw is part of any is OFF # ip forwarding is OFF # firewall-server-1-s:Policy:0: error: Rule '0 (eth0)' shadows rule '1 (eth0)' below it # firewall-server-1-s:Policy:0: error: Rule '0 (eth0)' shadows rule '2 (eth0)' below it # firewall-server-1-s:Policy:0: error: Rule '0 (eth0)' shadows rule '3 (eth0)' below it FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $MODPROBE find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : OPTS=$1 MODULES_DIR="/lib/modules/`uname -r`/kernel/net/" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done } verify_interfaces() { : echo "Verifying interfaces: lo eth0" for i in lo eth0 ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth0 192.168.1.1/24" "" } script_body() { # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'filter', rule set Policy # # Rule 1 (eth0) # echo "Rule 1 (eth0)" # # ticket #1338: local override of "Assume fw is part of any" # only INPUT chain because ip forwarding is off $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -j DROP # # Rule 2 (eth0) # echo "Rule 2 (eth0)" # # ticket #1338: "assume fw is part of any" is off, ip forwarding is off $IPTABLES -N Cid2293081X29313.0 $IPTABLES -A INPUT -i eth0 -s 127.0.0.1 -j Cid2293081X29313.0 $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -j Cid2293081X29313.0 $IPTABLES -A Cid2293081X29313.0 -d 127.0.0.1 -j DROP $IPTABLES -A Cid2293081X29313.0 -d 192.168.1.1 -j DROP # # Rule 3 (eth0) # echo "Rule 3 (eth0)" # # ticket #1338: "assume fw is part of any" is off, ip forwarding is off $IPTABLES -A INPUT -i eth0 -s 192.168.1.1 -d 192.168.1.1 -j DROP } ip_forward() { : echo 0 > /proc/sys/net/ipv4/ip_forward } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:17:33 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules " " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/ipt/firewall33.fw.orig0000755000175000017500000004267611733011756022043 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v5.0.2.3596 # # Generated Sun Mar 18 21:16:40 2012 PDT by vadim # # files: * firewall33.fw /etc/fw/firewall33.fw # # Compiled for iptables (any version) # # testing DNSName object # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode FWBDEBUG="" PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" export PATH LSMOD="/sbin/lsmod" MODPROBE="/sbin/modprobe" IPTABLES="/sbin/iptables" IP6TABLES="/sbin/ip6tables" IPTABLES_RESTORE="/sbin/iptables-restore" IP6TABLES_RESTORE="/sbin/ip6tables-restore" IP="/sbin/ip" IFCONFIG="/sbin/ifconfig" VCONFIG="/sbin/vconfig" BRCTL="/sbin/brctl" IFENSLAVE="/sbin/ifenslave" IPSET="/usr/sbin/ipset" LOGGER="/usr/bin/logger" log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getaddr() { getaddr_internal $1 $2 "-4" } getaddr6() { getaddr_internal $1 $2 "-6" } getnet() { getnet_internal $1 $2 "-4" } getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES find_program $IP } reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } check_run_time_address_table_files() { : } load_modules() { : } verify_interfaces() { : } prolog_commands() { echo "Running prolog script" } epilog_commands() { echo "Running epilog script" } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : # Configure interfaces update_addresses_of_interface "lo 127.0.0.1/8" "" update_addresses_of_interface "eth1 192.168.1.100/24" "" getaddr eth0.100 i_eth0_100 getaddr6 eth0.100 i_eth0_100_v6 getnet eth0.100 i_eth0_100_network getnet6 eth0.100 i_eth0_100_v6_network } script_body() { echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl # ================ IPv4 # ================ Table 'filter', automatic rules # accept established sessions $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # ================ Table 'nat', rule set NAT # # Rule 0 (NAT) # echo "Rule 0 (NAT)" # for i_eth0_100 in $i_eth0_100_list do test -n "$i_eth0_100" && $IPTABLES -t nat -A PREROUTING -d $i_eth0_100 -j DNAT --to-destination 192.168.1.10 done # # Rule 1 (NAT) # echo "Rule 1 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d 157.166.226.25 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d 157.166.226.26 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d 157.166.255.18 -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d 157.166.255.19 -j MASQUERADE # # Rule 2 (NAT) # echo "Rule 2 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d www.cnn.com -j MASQUERADE # # Rule 3 (NAT) # echo "Rule 3 (NAT)" # $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d www.google.com -j MASQUERADE $IPTABLES -t nat -A POSTROUTING -o eth0.100 -d www.cnn.com -j MASQUERADE # # Rule 4 (NAT) # echo "Rule 4 (NAT)" # $IPTABLES -t nat -N Cid43876E7B18346.0 $IPTABLES -t nat -A POSTROUTING -o eth0.100 -j Cid43876E7B18346.0 $IPTABLES -t nat -A Cid43876E7B18346.0 -d www.google.com -j RETURN $IPTABLES -t nat -A Cid43876E7B18346.0 -d www.cnn.com -j RETURN $IPTABLES -t nat -A Cid43876E7B18346.0 -j MASQUERADE # ================ Table 'filter', rule set Policy # # Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -A INPUT -s 157.166.226.25 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 157.166.226.26 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 157.166.255.18 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -s 157.166.255.19 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 157.166.226.25 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 157.166.226.26 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 157.166.255.18 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 157.166.255.19 -m state --state NEW -j ACCEPT # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A INPUT -s www.cnn.com -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s www.cnn.com -m state --state NEW -j ACCEPT # # Rule 2 (global) # echo "Rule 2 (global)" # # firewall33:Policy:2: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode $IPTABLES -A INPUT -s 192.0.2.1 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 192.0.2.1 -m state --state NEW -j ACCEPT # # Rule 3 (global) # echo "Rule 3 (global)" # $IPTABLES -A INPUT -s buildmaster -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s buildmaster -m state --state NEW -j ACCEPT # # Rule 4 (global) # echo "Rule 4 (global)" # $IPTABLES -N Cid4386E38318346.0 $IPTABLES -A OUTPUT -j Cid4386E38318346.0 $IPTABLES -A INPUT -j Cid4386E38318346.0 $IPTABLES -A FORWARD -j Cid4386E38318346.0 $IPTABLES -A Cid4386E38318346.0 -d 157.166.226.25 -j RETURN $IPTABLES -A Cid4386E38318346.0 -d 157.166.226.26 -j RETURN $IPTABLES -A Cid4386E38318346.0 -d 157.166.255.18 -j RETURN $IPTABLES -A Cid4386E38318346.0 -d 157.166.255.19 -j RETURN $IPTABLES -A Cid4386E38318346.0 -j DROP # # Rule 5 (global) # echo "Rule 5 (global)" # $IPTABLES -N Cid4386E37718346.0 $IPTABLES -A OUTPUT -j Cid4386E37718346.0 $IPTABLES -A INPUT -j Cid4386E37718346.0 $IPTABLES -A FORWARD -j Cid4386E37718346.0 $IPTABLES -A Cid4386E37718346.0 -d www.cnn.com -j RETURN $IPTABLES -A Cid4386E37718346.0 -j DROP # # Rule 6 (global) # echo "Rule 6 (global)" # # firewall33:Policy:6: error: DNSName object "buildmaster (ct)" (compile time) can not resolve dns name "buildmaster" (AF_INET): Host or network 'buildmaster' not found; last error: Unknown error Using dummy address in test mode $IPTABLES -N Cid43867C3018346.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid43867C3018346.0 $IPTABLES -A INPUT -m state --state NEW -j Cid43867C3018346.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid43867C3018346.0 $IPTABLES -A Cid43867C3018346.0 -d 192.0.2.1 -j RETURN $IPTABLES -A Cid43867C3018346.0 -j ACCEPT # # Rule 7 (global) # echo "Rule 7 (global)" # $IPTABLES -N Cid4386C10D18346.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid4386C10D18346.0 $IPTABLES -A INPUT -m state --state NEW -j Cid4386C10D18346.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid4386C10D18346.0 $IPTABLES -A Cid4386C10D18346.0 -d buildmaster -j RETURN $IPTABLES -A Cid4386C10D18346.0 -j ACCEPT # # Rule 8 (global) # echo "Rule 8 (global)" # $IPTABLES -N Cid438728A918346.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid438728A918346.0 $IPTABLES -A INPUT -m state --state NEW -j Cid438728A918346.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid438728A918346.0 $IPTABLES -A Cid438728A918346.0 -d 74.125.224.112 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.113 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.114 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.115 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 74.125.224.116 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.226.25 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.226.26 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.255.18 -j RETURN $IPTABLES -A Cid438728A918346.0 -d 157.166.255.19 -j RETURN $IPTABLES -A Cid438728A918346.0 -j ACCEPT # # Rule 9 (global) # echo "Rule 9 (global)" # $IPTABLES -N Cid438728BA18346.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid438728BA18346.0 $IPTABLES -A INPUT -m state --state NEW -j Cid438728BA18346.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid438728BA18346.0 $IPTABLES -A Cid438728BA18346.0 -d www.cnn.com -j RETURN $IPTABLES -A Cid438728BA18346.0 -d www.google.com -j RETURN $IPTABLES -A Cid438728BA18346.0 -j ACCEPT # # Rule 10 (global) # echo "Rule 10 (global)" # $IPTABLES -N Cid438728CD18346.0 $IPTABLES -A OUTPUT -m state --state NEW -j Cid438728CD18346.0 $IPTABLES -A INPUT -m state --state NEW -j Cid438728CD18346.0 $IPTABLES -A FORWARD -m state --state NEW -j Cid438728CD18346.0 $IPTABLES -A Cid438728CD18346.0 -d www.google.com -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.226.25 -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.226.26 -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.255.18 -j RETURN $IPTABLES -A Cid438728CD18346.0 -d 157.166.255.19 -j RETURN $IPTABLES -A Cid438728CD18346.0 -j ACCEPT # # Rule 11 (global) # echo "Rule 11 (global)" # # test for bug #1905718 # Group of DNS Name objects considered empty $IPTABLES -A OUTPUT -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d ny6ix.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 6bone.net -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d ny6ix.net -m state --state NEW -j ACCEPT # # Rule 12 (global) # echo "Rule 12 (global)" # $IPTABLES -A OUTPUT -d 72.55.148.116 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -d 207.251.84.150 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 72.55.148.116 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -d 207.251.84.150 -m state --state NEW -j ACCEPT # # Rule 13 (global) # echo "Rule 13 (global)" # $IPTABLES -N RULE_13 $IPTABLES -A OUTPUT -j RULE_13 $IPTABLES -A INPUT -j RULE_13 $IPTABLES -A FORWARD -j RULE_13 $IPTABLES -A RULE_13 -j LOG --log-level debug --log-prefix "RULE 13 -- DENY on global " $IPTABLES -A RULE_13 -j DROP } ip_forward() { : } reset_all() { : reset_iptables_v4 } block_action() { reset_all } stop_action() { reset_all $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT } check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated Sun Mar 18 21:16:40 2012 by vadim" check_tools prolog_commands check_run_time_address_table_files load_modules "nat " configure_interfaces verify_interfaces reset_all script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]" ;; esac exit $RETVALfwbuilder-5.1.0.3599/test/procurve_acl/0000755000175000017500000000000011733011756020441 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/test/procurve_acl/Makefile0000644000175000017500000000074411733011756022106 0ustar sylvestresylvestre FW_OBJECTS := $(shell fwbedit list -f objects-for-regression-tests.fwb -o /User/Firewalls -c -F%name% | sort) CL_OBJECTS := $(shell fwbedit list -f cluster-tests.fwb -o /User/Clusters -c -F%name% | sort) $(FW_OBJECTS): fwb_procurve_acl -f objects-for-regression-tests.fwb -xt $@ $(CL_OBJECTS): fwb_procurve_acl -f cluster-tests.fwb -xt -xc $@ .PHONY: all firewalls clusters $(FW_OBJECTS) $(CL_OBJECTS) all: firewalls clusters firewalls: $(FW_OBJECTS) clusters: $(CL_OBJECTS) fwbuilder-5.1.0.3599/test/procurve_acl/testhp2.fw.orig0000755000175000017500000004451611733011756023344 0ustar sylvestresylvestre; ; This is automatically generated file. DO NOT MODIFY ! ; ; Firewall Builder fwb_procurve_acl v4.2.0.3499 ; ; Generated Fri Mar 11 12:20:05 2011 PST by vadim ; ; Compiled for procurve_acl K.13 ; ;# files: * testhp2.fw ; ; Using "no clear acl" script option ; ; Prolog script: ; ; ; End of prolog script: ; ; ================ IPv4 ip access-list extended vlan_10_in permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_10_out permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_20_in permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_20_out permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_401_in permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_401_out permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 deny ip any any log exit ip access-list extended vlan_402_in permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_402_out permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_40_in permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 deny ip any any log exit ip access-list extended vlan_40_out permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 deny ip any any log exit vlan 10 ip access-group vlan_10_in in vlan 10 ip access-group vlan_10_out out vlan 20 ip access-group vlan_20_in in vlan 20 ip access-group vlan_20_out out vlan 401 ip access-group vlan_401_in in vlan 401 ip access-group vlan_401_out out vlan 402 ip access-group vlan_402_in in vlan 402 ip access-group vlan_402_out out vlan 40 ip access-group vlan_40_in in vlan 40 ip access-group vlan_40_out out ; ; Epilog script: ; ; End of epilog script: ; fwbuilder-5.1.0.3599/test/procurve_acl/run.all0000755000175000017500000000101711733011756021741 0ustar sylvestresylvestre#!/bin/sh XMLFILE="objects-for-regression-tests.fwb" fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_procurve_acl -v -f $XMLFILE -xt $fwobj" done exit 0 XMLFILE="cluster-tests.fwb" fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \ sort | while read fwobj do echo "echo" echo "echo \"============================ $fwobj\"" echo "fwb_procurve_acl -v -f $XMLFILE -xt -xc $fwobj" done fwbuilder-5.1.0.3599/test/procurve_acl/addr-table-1.tbl0000644000175000017500000000030411733011756023276 0ustar sylvestresylvestre# this is a comment # ; this should be a comment too ; 192.168.1.1 192.168.1.2/32 192.168.1.3/30 192.168.2.128/25 192.168.1.200/32 # comment again 192.168.1.201/32 # this should work, too fwbuilder-5.1.0.3599/test/procurve_acl/quick-cmp.sh0000755000175000017500000000145111733011756022672 0ustar sylvestresylvestre#!/bin/sh DIFFCMD="diff -C 5 -c -b -B -w -I \"Generated\" -I 'Activating ' -I 'Firewall Builder fwb_procurve_acl v' -I 'Can not find file' -I '====' -I 'log '" for f in $(ls *.fw.orig) do V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" new_f=$(echo $f | sed 's/.orig//') echo "$DIFFCMD $f $new_f" done exit 0 run_diffs_for_file() { xmlfile=$1 folder=$2 fwbedit list -f $xmlfile -o $folder -c -F%name% | sort | while read fwobj; do V="$fwobj <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" echo "echo \"$V\" | cut -c1-72" echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" done } run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls # run_diffs_for_file cluster-tests.fwb /User/Clusters fwbuilder-5.1.0.3599/test/procurve_acl/recycle0000755000175000017500000000007511733011756022017 0ustar sylvestresylvestre#!/bin/sh for f in *.fw; do j=${f}.orig mv $f $j done fwbuilder-5.1.0.3599/test/procurve_acl/objects-for-regression-tests.fwb0000644000175000017500000100677111733011756026710 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk dscp af11 dscp af12 dscp af11 fwbuilder-5.1.0.3599/test/procurve_acl/block-hosts.tbl0000644000175000017500000000163011733011756023374 0ustar sylvestresylvestre# # use this table to test run-time AddressTable object # (this is just a small collection of addresses that sent spam to me # on Nov 20 2005) # 151.8.224.178 # this is also a comment 168.156.76.20 193.207.126.36 195.136.186.35 196.15.136.15 201.10.180.138 201.17.93.16 201.36.156.121 202.103.25.253 202.96.112.93 203.162.3.209 203.209.124.144 210.106.193.237 210.222.114.102 211.144.143.143 211.172.218.237 211.250.16.132 212.100.212.100 212.21.241.31 218.104.138.146 218.18.72.252 218.39.114.122 218.55.115.43 219.132.104.160 220.71.17.86 220.81.50.105 220.91.99.46 221.14.249.242 221.166.177.135 221.198.33.38 221.202.160.233 221.205.54.125 221.217.44.248 222.100.212.223 222.121.118.144 222.174.113.2 58.231.13.78 58.33.181.83 58.53.82.190 61.150.47.112 61.184.14.102 64.106.85.186 70.228.60.100 80.243.72.149 80.249.77.34 80.51.236.6 81.196.74.125 81.2.36.254 82.117.221.205 82.143.196.17 82.77.37.174 84.90.8.198 fwbuilder-5.1.0.3599/test/procurve_acl/testhp4.fw.orig0000755000175000017500000007744511733011756023355 0ustar sylvestresylvestre; ; This is automatically generated file. DO NOT MODIFY ! ; ; Firewall Builder fwb_procurve_acl v4.2.0.3499 ; ; Generated Fri Mar 11 12:20:05 2011 PST by vadim ; ; Compiled for procurve_acl K.13 ; ;# files: * testhp4.fw ; ; Using "safety net" script option, management interface is not a vlan ; ; Prolog script: ; ; ; End of prolog script: ; ; temporary access list for "safety net install" interface a1 no ip access-group tmp_acl in exit no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.11.10 0.0.0.0 any deny ip any any exit interface a1 ip access-group tmp_acl in exit interface a1 no ip access-group a1_in in exit no ip access-list extended a1_in interface a1 no ip access-group a1_out out exit no ip access-list extended a1_out no vlan 10 ip access-group vlan_10_in in no ip access-list extended vlan_10_in no vlan 10 ip access-group vlan_10_out out no ip access-list extended vlan_10_out no vlan 20 ip access-group vlan_20_in in no ip access-list extended vlan_20_in no vlan 20 ip access-group vlan_20_out out no ip access-list extended vlan_20_out no vlan 401 ip access-group vlan_401_in in no ip access-list extended vlan_401_in no vlan 401 ip access-group vlan_401_out out no ip access-list extended vlan_401_out no vlan 402 ip access-group vlan_402_in in no ip access-list extended vlan_402_in no vlan 402 ip access-group vlan_402_out out no ip access-list extended vlan_402_out no vlan 40 ip access-group vlan_40_in in no ip access-list extended vlan_40_in no vlan 40 ip access-group vlan_40_out out no ip access-list extended vlan_40_out ; ================ IPv4 ip access-list extended a1_in ; ; Rule -1 backup ssh access rule (automatic) remark "-1 backup ssh access rule (automatic)" permit tcp host 10.10.11.10 host 10.10.1.1 eq 22 permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) remark "6 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended a1_out ; ; Rule -2 backup ssh access rule (out) (automatic) remark "-2 backup ssh access rule (out) (automatic)" permit tcp host 10.10.1.1 eq 22 host 10.10.11.10 permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_10_in ; ; Rule -1 backup ssh access rule (automatic) remark "-1 backup ssh access rule (automatic)" permit tcp host 10.10.11.10 host 10.10.1.1 eq 22 permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 0 (vlan 10) ; anti-spoofing remark "0 (vlan 10)" remark anti-spoofing deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 2 (vlan 20,vlan 10) remark "2 (vlan 20,vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) remark "3 (testhp1 itf)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 4 (vlan 10) remark "4 (vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) remark "6 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 7 (vlan 10) remark "7 (vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 10 (vlan 10) remark "10 (vlan 10)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_10_out ; ; Rule -2 backup ssh access rule (out) (automatic) remark "-2 backup ssh access rule (out) (automatic)" permit tcp host 10.10.1.1 eq 22 host 10.10.11.10 permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 2 (vlan 20,vlan 10) remark "2 (vlan 20,vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) remark "3 (testhp1 itf)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 4 (vlan 10) remark "4 (vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 10 (vlan 10) remark "10 (vlan 10)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_20_in ; ; Rule -1 backup ssh access rule (automatic) remark "-1 backup ssh access rule (automatic)" permit tcp host 10.10.11.10 host 10.10.1.1 eq 22 permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 2 (vlan 20,vlan 10) remark "2 (vlan 20,vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) remark "3 (testhp1 itf)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 5 (vlan 20) remark "5 (vlan 20)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) remark "6 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 8 (vlan 20) remark "8 (vlan 20)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 11 (vlan 20) remark "11 (vlan 20)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_20_out ; ; Rule -2 backup ssh access rule (out) (automatic) remark "-2 backup ssh access rule (out) (automatic)" permit tcp host 10.10.1.1 eq 22 host 10.10.11.10 permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 2 (vlan 20,vlan 10) remark "2 (vlan 20,vlan 10)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) remark "3 (testhp1 itf)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 5 (vlan 20) remark "5 (vlan 20)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 11 (vlan 20) remark "11 (vlan 20)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_401_in ; ; Rule -1 backup ssh access rule (automatic) remark "-1 backup ssh access rule (automatic)" permit tcp host 10.10.11.10 host 10.10.1.1 eq 22 permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) remark "6 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_401_out ; ; Rule -2 backup ssh access rule (out) (automatic) remark "-2 backup ssh access rule (out) (automatic)" permit tcp host 10.10.1.1 eq 22 host 10.10.11.10 permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_402_in ; ; Rule -1 backup ssh access rule (automatic) remark "-1 backup ssh access rule (automatic)" permit tcp host 10.10.11.10 host 10.10.1.1 eq 22 permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) remark "6 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_402_out ; ; Rule -2 backup ssh access rule (out) (automatic) remark "-2 backup ssh access rule (out) (automatic)" permit tcp host 10.10.1.1 eq 22 host 10.10.11.10 permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_40_in ; ; Rule -1 backup ssh access rule (automatic) remark "-1 backup ssh access rule (automatic)" permit tcp host 10.10.11.10 host 10.10.1.1 eq 22 permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) remark "1 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) remark "6 (global)" permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) remark "9 (global)" permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 remark "12 (global)" remark "interface ethernet1 has address on network 10.10.10.0/24," remark "therefore net-10.10.10 is behind the router and we do" remark "not need to put rules 12-18 in outbound acl of eth0" permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) remark "13 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) remark "14 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) remark "15 (global)" permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) remark "16 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) remark "17 (global)" permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) remark "18 (global)" permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) remark "19 (global)" permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) remark "20 (global)" permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit ip access-list extended vlan_40_out ; ; Rule -2 backup ssh access rule (out) (automatic) remark "-2 backup ssh access rule (out) (automatic)" permit tcp host 10.10.1.1 eq 22 host 10.10.11.10 permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 21 (global) remark "21 (global)" deny ip any any log exit interface a1 ip access-group a1_in in exit interface a1 ip access-group a1_out out exit vlan 10 ip access-group vlan_10_in in vlan 10 ip access-group vlan_10_out out vlan 20 ip access-group vlan_20_in in vlan 20 ip access-group vlan_20_out out vlan 401 ip access-group vlan_401_in in vlan 401 ip access-group vlan_401_out out vlan 402 ip access-group vlan_402_in in vlan 402 ip access-group vlan_402_out out vlan 40 ip access-group vlan_40_in in vlan 40 ip access-group vlan_40_out out ; ; Epilog script: ; ; End of epilog script: ; fwbuilder-5.1.0.3599/test/procurve_acl/testhp1.fw.orig0000755000175000017500000010771011733011756023337 0ustar sylvestresylvestre; ; This is automatically generated file. DO NOT MODIFY ! ; ; Firewall Builder fwb_procurve_acl v4.2.0.3499 ; ; Generated Fri Mar 11 12:20:05 2011 PST by vadim ; ; Compiled for procurve_acl K.13 ; ;# files: * testhp1.fw ; ; ; Prolog script: ; ; ; End of prolog script: ; interface a1 no ip access-group a1_in in exit no ip access-list extended a1_in interface a1 no ip access-group a1_out out exit no ip access-list extended a1_out interface a2 no ip access-group a2_in in exit no ip access-list extended a2_in interface a2 no ip access-group a2_out out exit no ip access-list extended a2_out interface b1 no ip access-group b1_in in exit no ip access-list extended b1_in interface b1 no ip access-group b1_out out exit no ip access-list extended b1_out interface b2 no ip access-group b2_in in exit no ip access-list extended b2_in interface b2 no ip access-group b2_out out exit no ip access-list extended b2_out no vlan 10 ip access-group vlan_10_in in no ip access-list extended vlan_10_in no vlan 10 ip access-group vlan_10_out out no ip access-list extended vlan_10_out no vlan 20 ip access-group vlan_20_in in no ip access-list extended vlan_20_in no vlan 20 ip access-group vlan_20_out out no ip access-list extended vlan_20_out no vlan 401 ip access-group vlan_401_in in no ip access-list extended vlan_401_in no vlan 401 ip access-group vlan_401_out out no ip access-list extended vlan_401_out no vlan 402 ip access-group vlan_402_in in no ip access-list extended vlan_402_in no vlan 402 ip access-group vlan_402_out out no ip access-list extended vlan_402_out no vlan 40 ip access-group vlan_40_in in no ip access-list extended vlan_40_in no vlan 40 ip access-group vlan_40_out out no ip access-list extended vlan_40_out ; ================ IPv4 ip access-list extended a1_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (a1) permit ip any 10.10.10.0 0.0.0.255 ; ; Rule 22 (a1,a2) permit ip any 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended a1_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended a2_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 22 (a1,a2) permit ip any 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended a2_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended b1_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended b1_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended b2_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended b2_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_10_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 0 (vlan 10) ; anti-spoofing deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 4 (vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 7 (vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 10 (vlan 10) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_10_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 4 (vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 10 (vlan 10) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_20_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 5 (vlan 20) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 8 (vlan 20) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 11 (vlan 20) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_20_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 5 (vlan 20) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 11 (vlan 20) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_401_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_401_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_402_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_402_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_40_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 23 (global) deny ip any any log exit ip access-list extended vlan_40_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 23 (global) deny ip any any log exit interface a1 ip access-group a1_in in exit interface a1 ip access-group a1_out out exit interface a2 ip access-group a2_in in exit interface a2 ip access-group a2_out out exit interface b1 ip access-group b1_in in exit interface b1 ip access-group b1_out out exit interface b2 ip access-group b2_in in exit interface b2 ip access-group b2_out out exit vlan 10 ip access-group vlan_10_in in vlan 10 ip access-group vlan_10_out out vlan 20 ip access-group vlan_20_in in vlan 20 ip access-group vlan_20_out out vlan 401 ip access-group vlan_401_in in vlan 401 ip access-group vlan_401_out out vlan 402 ip access-group vlan_402_in in vlan 402 ip access-group vlan_402_out out vlan 40 ip access-group vlan_40_in in vlan 40 ip access-group vlan_40_out out ; ; Epilog script: ; ; End of epilog script: ; fwbuilder-5.1.0.3599/test/procurve_acl/testhp3.fw.orig0000755000175000017500000005626211733011756023346 0ustar sylvestresylvestre; ; This is automatically generated file. DO NOT MODIFY ! ; ; Firewall Builder fwb_procurve_acl v4.2.0.3499 ; ; Generated Fri Mar 11 12:20:05 2011 PST by vadim ; ; Compiled for procurve_acl K.13 ; ;# files: * testhp3.fw ; ; Using "safety net" script option ; ; Prolog script: ; ; ; End of prolog script: ; ; temporary access list for "safety net install" no vlan 40 ip access-group tmp_acl in no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip 10.10.11.10 0.0.0.0 any deny ip any any exit vlan 40 ip access-group tmp_acl in no vlan 10 ip access-group vlan_10_in in no ip access-list extended vlan_10_in no vlan 10 ip access-group vlan_10_out out no ip access-list extended vlan_10_out no vlan 20 ip access-group vlan_20_in in no ip access-list extended vlan_20_in no vlan 20 ip access-group vlan_20_out out no ip access-list extended vlan_20_out no vlan 401 ip access-group vlan_401_in in no ip access-list extended vlan_401_in no vlan 401 ip access-group vlan_401_out out no ip access-list extended vlan_401_out no vlan 402 ip access-group vlan_402_in in no ip access-list extended vlan_402_in no vlan 402 ip access-group vlan_402_out out no ip access-list extended vlan_402_out no vlan 40 ip access-group vlan_40_in in no ip access-list extended vlan_40_in no vlan 40 ip access-group vlan_40_out out no ip access-list extended vlan_40_out ; ================ IPv4 ip access-list extended vlan_10_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 0 (vlan 10) ; anti-spoofing deny ip 10.10.10.0 0.0.0.255 any log deny ip 10.10.11.0 0.0.0.255 any log deny ip 10.10.12.0 0.0.0.255 any log ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 4 (vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 7 (vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 10 (vlan 10) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_10_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 4 (vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 10 (vlan 10) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_20_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 5 (vlan 20) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 8 (vlan 20) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 11 (vlan 20) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_20_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 2 (vlan 20,vlan 10) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 3 (testhp1 itf) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 5 (vlan 20) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 11 (vlan 20) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_401_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_401_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_402_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_402_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_40_in ; ; Rule -1 backup ssh access rule (automatic) permit tcp host 10.10.11.10 host 10.10.10.1 eq 22 permit tcp host 10.10.11.10 host 10.10.11.1 eq 22 permit tcp host 10.10.11.10 host 10.10.12.1 eq 22 ; ; Rule 1 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 6 (global) permit ip any 10.10.10.0 0.0.0.255 permit ip any 10.10.11.0 0.0.0.255 permit ip any 10.10.12.0 0.0.0.255 ; ; Rule 9 (global) permit ip 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.21.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.22.0 0.0.0.255 10.10.12.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.10.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.11.0 0.0.0.255 permit ip 22.22.23.0 0.0.0.255 10.10.12.0 0.0.0.255 ; ; Rule 12 (global) ; interface ethernet1 has address on network 10.10.10.0/24, ; therefore net-10.10.10 is behind the router and we do ; not need to put rules 12-18 in outbound acl of eth0 permit 47 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 permit 51 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 13 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 3 permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 11 ; ; Rule 14 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 21 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 80 ; ; Rule 15 (global) permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 4000 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 500 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 53 ; ; Rule 16 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 established ; ; Rule 17 (global) permit tcp 22.22.21.0 0.0.0.255 eq 80 10.10.10.0 0.0.0.255 established ; ; Rule 18 (global) permit icmp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 0 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 179 permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 79 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 123 permit udp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 eq 26000 ; ; Rule 19 (global) permit tcp 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 20 (global) permit 50 22.22.21.0 0.0.0.255 10.10.10.0 0.0.0.255 ; ; Rule 21 (global) deny ip any any log exit ip access-list extended vlan_40_out ; ; Rule -2 backup ssh access rule (out) (automatic) permit tcp host 10.10.10.1 eq 22 host 10.10.11.10 permit tcp host 10.10.11.1 eq 22 host 10.10.11.10 permit tcp host 10.10.12.1 eq 22 host 10.10.11.10 ; ; Rule 21 (global) deny ip any any log exit vlan 10 ip access-group vlan_10_in in vlan 10 ip access-group vlan_10_out out vlan 20 ip access-group vlan_20_in in vlan 20 ip access-group vlan_20_out out vlan 401 ip access-group vlan_401_in in vlan 401 ip access-group vlan_401_out out vlan 402 ip access-group vlan_402_in in vlan 402 ip access-group vlan_402_out out vlan 40 ip access-group vlan_40_in in vlan 40 ip access-group vlan_40_out out ; ; Epilog script: ; ; End of epilog script: ; fwbuilder-5.1.0.3599/definitions.h0000644000175000017500000000225211733011756017463 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Define global macros and constants in this file if they are used in the GUI, compilers and tools */ #ifndef __DEFINITIONS_ #define __DEFINITIONS_ // Various #defines that are needed both in the GUI and compilers // definitions for ipfw classify methods #define DIVERTSOCKET 0 #define DUMMYNETPIPE 1 #define DUMMYNETQUEUE 2 #endif fwbuilder-5.1.0.3599/qmake.inc.in0000644000175000017500000001315611733011756017202 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # ########## fwbuilder/qmake.inc.in # QTDIR = $$(QTDIR) TEMPLATE = app DEFINES += $$(DEFINES) LANGUAGE = C++ UI_DIR = ui MANDIR = @MANDIR@ DOCDIR = @DOCDIR@ HAVE_QTDBUS = @HAVE_QTDBUS@ HAVE_CPPUNIT = @HAVE_CPPUNIT@ CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@ CPPUNIT_LIBS = @CPPUNIT_LIBS@ # CONFIG -= nostrip # CONFIG += release CONFIG += debug unix { PREFIX = @PREFIX@ ANTLR_INCLUDEPATH = @ANTLR_INCLUDEPATH@ ANTLR_LIBS = @ANTLR_LIBS@ QMAKE_CXX = @CCACHE@ @DISTCC@ $$QMAKE_CXX INCLUDEPATH += .. ../.. INCLUDEPATH += @XML_CFLAGS_Q@ @XSLT_CFLAGS_Q@ LIBS += @PTHREAD_LIBS@ @XML_LIBS@ @XSLT_LIBS@ @LIBSNMP_LIBS@ @LIB_RESOLV@ @LIBS@ UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj QMAKE_CFLAGS_DEBUG += -Wno-unused-parameter QMAKE_CFLAGS_RELEASE += -Wno-unused-parameter QMAKE_CXXFLAGS_DEBUG += -Wno-unused-parameter QMAKE_CXXFLAGS_RELEASE += -Wno-unused-parameter !macx { exec_prefix = @EXEC_PREFIX@ DESTDIR = ICONSDIR = @ICONSDIR@ target.path = $$PREFIX/bin dtd.path = @RES_DIR@/ migration.path = @RES_DIR@/migration doc.path = @DOCDIR@ datadir.path = @DATADIR@ res.path = @RES_DIR@ res_os.path = $$res.path/os/ res_platform.path = $$res.path/platform/ res_help_C.path = $$res.path/help/C res_help_en_US.path = $$res.path/help/en_US res_desktop.path = @DATADIR@/applications/ res_configlets.path = $$res.path/configlets # INSTALLS += icns # LIBS += @LIBS@ PKGLOCALEDIR = $$res.path/locale CONFIG += warn_on # DEFINES += __STDC_FORMAT_MACROS } } win32 { # Keep this as a absolute full path. For some reason, when # I leave it is up to qmake to define this variable, and it # makes it "xcopy /i /y /s /q", I get an error "Invalid number of parameters" # even though command line looks correct. Chances are, there is another # xcopy somewhere on the system that gets used, but I could not find it. # Setting this variable using full path works. QMAKE_COPY_DIR = C:\\Windows\\System32\\xcopy /I /Y /S /Q PREFIX = "c:/tmp/build_root" DOCDIR = "$$PREFIX/doc/fwbuilder" exec_prefix = "$$PREFIX" MANDIR = "$$PREFIX/man/" DESTDIR = "" doc.path = $$DOCDIR target.path = $$PREFIX/ res.path = $$PREFIX/resources res_os.path = $$res.path/os res_platform.path = $$res.path/platform res_help_C.path = $$res.path/help/C res_help_en_US.path = $$res.path/help/en_US res_configlets.path = $$res.path/configlets PKGLOCALEDIR = $$res.path/locale CONFIG += qt thread rtti stl warn_on release CONFIG -= debug BINARY_SUBDIR = release DEFINES += LIBXML_STATIC LIBXSLT_STATIC DEFINES += LIBEXSLT_STATIC XMLSEC_STATIC INCLUDEPATH += "../.." INCLUDEPATH += c:/local/include c:/local/include/libxml2 c:/MinGW/include LIBS += -L "c:/local/lib" LIBS += -l xslt -l xml2 -l iconv -l pthread -l netsnmp -l ws2_32 # workaround for QT += dbus not working atm # Standard QT binary Windows distribution does not include QtDBus library # Checked with 4.4.1 and 4.4.3 06/12/2009 # LIBS += -lQtDBus target.path = $$PREFIX/bin # on windows we use antlr DLL HAVE_ANTLR_RUNTIME = 1 HAVE_EXTERNAL_ANTLR = 0 antlr.path = $$PREFIX/lib # Qt on windows does not have DBus framework support, turn parts of .pro files off # HAVE_QTDBUS = ANTLR_INCLUDEPATH = .. ANTLR_LIBS = ../antlr/release/libantlr.a # our parsers are linked as a library (code is in src/parsers) FWBPARSER_LIB = ../parsers/release/libfwbparser.a # fwtransfer library for secuwall (and possibly other os/platform) # override the name for windows # FWTRANSFER_LIB = ../fwtransfer/release/libfwtransfer.a } macx { // PREFIX = "$$DESTDIR" DOCDIR = "$$PREFIX/doc/" MANDIR = "$$PREFIX/share/man" # These do not really matter because we never run make install on Mac OS X target.path = $$PREFIX/ res.path = $$PREFIX/resources/ res_os.path = $$res.path/os res_platform.path = $$res.path/platform res_help_C.path = $$res.path/help/C res_help_en_US.path = $$res.path/help/en_US res_configlets.path = $$res.path/configlets icns.files = fwbuilder.icns icns.path = $$PREFIX/ PKGLOCALEDIR = $$res.path/locale # If I build on 10.6 without these, generated binary depends on # /usr/lib/libxml2.2.dynlib that has compatibility version 10.0.0 # which does not work on 10.5 where its compatibility version is # 9.0.0. Chances are, the same thing may be happening with other # dependency libraries. Building on 10.6 with deployment target 10.5 # should solve the problem QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5 QMAKE_MAC_SDK = /Developer/SDKs/MacOSX10.5.sdk CONFIG += qt thread rtti stl warn_on debug # release # not compiling for PPC because of problems on Snow Leopard CONFIG += x86 # See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=211852 # for why ppc architecture is commented out. # If Trolltech does not fix it by the time of release v3.0, will have # to figure out workaround (turn off precompiled headers ?) # CONFIG += ppc INCLUDEPATH += $(INSTALL_ROOT)/$$PREFIX/include/ INCLUDEPATH += /usr/include/libxml2 /usr/include QMAKE_LIBS_QT = QMAKE_LIBS_QT_THREAD = # LIBS += $$LIBS_FWBUILDER LIBS += -lxml2 -lz LIBS += -lpthread -lssl -lcrypto } FWB_SIG = $$(FWB_SIG) if (isEmpty(FWB_SIG)) { FWB_SIG=26932 } DEFINES += FWB_SIG=$$FWB_SIG QMAKE_CXXFLAGS_DEBUG += -D__STDC_FORMAT_MACROS QMAKE_CXXFLAGS_RELEASE += -D__STDC_FORMAT_MACROS exists(qmake2.inc) { include(qmake2.inc) } INSTALLS += target fwbuilder-5.1.0.3599/.gitignore0000644000175000017500000000135111733011756016766 0ustar sylvestresylvestrecore *.a *.o *.so* *.log *.status *.guess *.sub *.cache *.m4 *.fw *.conf *.app !src/gui/FwbuilderInfo.plist *.dylib *.spec *.control *.nsi build_num test/ipt/secuwall-1 Makefile !test/*/Makefile install* !src/res/configlets/*/install* ltmain.sh configure libtool qmake.inc config.h .obj .moc .ui qtdbus_test fwbedit qrc_MainRes.cpp fwb_iosacl fwb_ipf fwb_ipfw fwb_ipt fwb_pf fwb_pix fwb_procurve_acl transfer_secuwall .configure_marker .build_marker src/unit_tests/*/*Test src/unit_tests/*/*Tests src/unit_tests/*/*.output src/unit_tests/generatedScriptTests*/generatedScriptTests* src/unit_tests/generatedScriptTestsSecuwall/ref.* src/unit_tests/generatedScriptTestsSecuwall/secuwall-1/ src/unit_tests/generatedScriptTestsSecuwall/secuwall-2/ fwbuilder-5.1.0.3599/m4/0000755000175000017500000000000011733011756015316 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/m4/po.m40000644000175000017500000004265211733011756016207 0ustar sylvestresylvestre# po.m4 serial 3 (gettext-0.14) dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. dnl Checks for all prerequisites of the po subdirectory. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AM_NLS])dnl dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.12 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU msgfmt. if test "$GMSGFMT" != ":"; then dnl If it is no GNU msgfmt we define it as : so that the dnl Makefiles still can work. if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` AC_MSG_RESULT( [found $GMSGFMT program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi fi dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po fi AC_OUTPUT_COMMANDS([ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) dnl Postprocesses a Makefile in a directory containing PO files. AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], [ # When this code is run, in config.status, two variables have already been # set: # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, # - LINGUAS is the value of the environment variable LINGUAS at configure # time. changequote(,)dnl # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Find a way to echo strings without interpreting backslash. if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then gt_echo='echo' else if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then gt_echo='printf %s\n' else echo_func () { cat < "$ac_file.tmp" if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` cat >> "$ac_file.tmp" < /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/_/-/g'` cat >> "$ac_file.tmp" <> "$ac_file.tmp" <, 1995-2000. dnl Bruno Haible , 2000-2003. AC_DEFUN([AM_NLS], [ AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) ]) AC_DEFUN([AM_MKINSTALLDIRS], [ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but $(top_srcdir). dnl Try to locate it. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then case "$ac_aux_dir" in /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; esac fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) ]) fwbuilder-5.1.0.3599/install.sh0000755000175000017500000001272111733011756017006 0ustar sylvestresylvestre#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 fwbuilder-5.1.0.3599/fwbuilder3.pro0000644000175000017500000000062311733011756017567 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # TEMPLATE = subdirs SUBDIRS = src doc DOLLAR = $ build_tests.commands = ./unit_tests.sh make build_tests build_tests.depends = all run_tests.commands = ./unit_tests.sh make run_tests run_tests.depends = all tests.depends = run_tests clean_tests.commands = ./unit_tests.sh make clean_tests QMAKE_EXTRA_TARGETS += build_tests run_tests clean_tests tests fwbuilder-5.1.0.3599/acinclude.m40000644000175000017500000003104611733011756017173 0ustar sylvestresylvestre# generated automatically by aclocal 1.10.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. dnl ______ /usr/share/aclocal/Installed_Packages/acx_pthread.m4 ______ dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) dnl dnl This macro figures out how to build C programs using POSIX dnl threads. It sets the PTHREAD_LIBS output variable to the threads dnl library and linker flags, and the PTHREAD_CFLAGS output variable dnl to any special C compiler flags that are needed. (The user can also dnl force certain compiler flags/libs to be tested by setting these dnl environment variables.) dnl dnl Also sets PTHREAD_CC to any special C compiler that is needed for dnl multi-threaded programs (defaults to the value of CC otherwise). dnl (This is necessary on AIX to use the special cc_r compiler alias.) dnl dnl If you are only building threads programs, you may wish to dnl use these variables in your default LIBS, CFLAGS, and CC: dnl dnl LIBS="$PTHREAD_LIBS $LIBS" dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" dnl CC="$PTHREAD_CC" dnl dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). dnl dnl ACTION-IF-FOUND is a list of shell commands to run if a threads dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands dnl to run it if it is not found. If ACTION-IF-FOUND is not specified, dnl the default action will define HAVE_PTHREAD. dnl dnl Please let the authors know if this macro fails on any platform, dnl or if you have any other suggestions or comments. This macro was dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org) dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread dnl macros posted by AFC to the autoconf macro repository. We are also dnl grateful for the helpful feedback of numerous users. dnl dnl @version %Id: acx_pthread.m4,v 1.3 2002/12/12 23:15:12 guidod Exp % dnl @author Steven G. Johnson and Alejandro Forero Cuervo AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # pthread: Linux, etcetera # --thread-safe: KAI C++ case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthread or # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [acx_pthread_ok=yes]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: threads are created detached by default # and the JOINABLE attribute has a nonstandard name (UNDETACHED). AC_MSG_CHECKING([for joinable pthread attribute]) AC_TRY_LINK([#include ], [int attr=PTHREAD_CREATE_JOINABLE;], ok=PTHREAD_CREATE_JOINABLE, ok=unknown) if test x"$ok" = xunknown; then AC_TRY_LINK([#include ], [int attr=PTHREAD_CREATE_UNDETACHED;], ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) fi if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, [Define to the necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_RESULT(${ok}) if test x"$ok" = xunknown; then AC_MSG_WARN([we do not know how to create joinable pthreads]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with cc_r AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_RESTORE ])dnl ACX_PTHREAD dnl dnl AM_PATH_CPPUNIT(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) dnl AC_DEFUN([AM_PATH_CPPUNIT], [ AC_ARG_WITH(cppunit-prefix,[ --with-cppunit-prefix=PFX Prefix where CppUnit is installed (optional)], cppunit_config_prefix="$withval", cppunit_config_prefix="") AC_ARG_WITH(cppunit-exec-prefix,[ --with-cppunit-exec-prefix=PFX Exec prefix where CppUnit is installed (optional)], cppunit_config_exec_prefix="$withval", cppunit_config_exec_prefix="") if test x$cppunit_config_exec_prefix != x ; then cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix" if test x${CPPUNIT_CONFIG+set} != xset ; then CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config fi fi if test x$cppunit_config_prefix != x ; then cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix" if test x${CPPUNIT_CONFIG+set} != xset ; then CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config fi fi AC_PATH_PROG(CPPUNIT_CONFIG, cppunit-config, no) cppunit_version_min=$1 AC_MSG_CHECKING(for Cppunit - version >= $cppunit_version_min) no_cppunit="" if test "$CPPUNIT_CONFIG" = "no" ; then AC_MSG_RESULT(no) no_cppunit=yes else CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags` CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs` cppunit_version=`$CPPUNIT_CONFIG --version` cppunit_major_version=`echo $cppunit_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` cppunit_minor_version=`echo $cppunit_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` cppunit_micro_version=`echo $cppunit_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` cppunit_major_min=`echo $cppunit_version_min | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` if test "x${cppunit_major_min}" = "x" ; then cppunit_major_min=0 fi cppunit_minor_min=`echo $cppunit_version_min | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` if test "x${cppunit_minor_min}" = "x" ; then cppunit_minor_min=0 fi cppunit_micro_min=`echo $cppunit_version_min | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` if test "x${cppunit_micro_min}" = "x" ; then cppunit_micro_min=0 fi cppunit_version_proper=`expr \ $cppunit_major_version \> $cppunit_major_min \| \ $cppunit_major_version \= $cppunit_major_min \& \ $cppunit_minor_version \> $cppunit_minor_min \| \ $cppunit_major_version \= $cppunit_major_min \& \ $cppunit_minor_version \= $cppunit_minor_min \& \ $cppunit_micro_version \>= $cppunit_micro_min ` if test "$cppunit_version_proper" = "1" ; then AC_MSG_RESULT([$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version]) else AC_MSG_RESULT(no) no_cppunit=yes fi fi if test "x$no_cppunit" = x ; then ifelse([$2], , :, [$2]) else CPPUNIT_CFLAGS="" CPPUNIT_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(CPPUNIT_CFLAGS) AC_SUBST(CPPUNIT_LIBS) ]) fwbuilder-5.1.0.3599/config.h.in0000644000175000017500000000424111733011756017022 0ustar sylvestresylvestre #include "VERSION.h" #undef BUILD_NUM /* Define if you have the header file. */ #undef HAVE_X11_SM_SMLIB_H /* Name of package */ #undef PACKAGE /* OS */ #undef OS /* OS */ #undef OS_CYGWIN #undef OS_MINGW #undef OS_MACOSX #undef OS_SOLARIS #undef OS_FREEBSD #undef OS_OPENBSD #undef OS_LINUX #undef OS_UNKNOWN #if defined(OS_SOLARIS) || defined(OS_FREEBSD) || defined(OS_OPENBSD) || defined(OS_LINUX) || defined(OS_MACOSX) #define OS_UNIX 1 #endif #if defined(_WIN32) #define OS_WIN32 1 #endif /* distribution (for Linux) */ #undef DISTRO /* prefix dir */ #undef PREFIX #define MANIFEST_MARKER "# files: " #undef RCS_DIR #undef RCS_FILE_NAME #undef RCSDIFF_FILE_NAME #undef RLOG_FILE_NAME #undef CI_FILE_NAME #undef CO_FILE_NAME #undef HAVE_LOCALE_H #undef HAVE_GETOPT_H #undef HAVE_SETLOCALE #undef HAVE_SETENV #undef HAVE_PUTENV #undef HAVE_SIGNAL #undef HAVE_SIGNAL_H #undef HAVE_PTY_H #undef HAVE_LIBUTIL_H #undef HAVE_UTIL_H #undef HAVE_UNISTD_H #ifdef HAVE_GETOPT_H # define HAVE_DECL_GETOPT HAVE_GETOPT_H #endif #undef HAVE_STRUCT_TM_TM_ZONE #undef TM_IN_SYS_TIME #undef HAVE_FORKPTY #undef HAVE_CFMAKERAW /* * This is needed for Solaris */ #undef __PRAGMA_REDEFINE_EXTNAME #undef HAVE_CATGETS #undef HAVE_GETTEXT #undef HAVE_LC_MESSAGES #undef HAVE_STPCPY #undef HAVE_LIBSM #undef HAVE_MEMPCPY #undef HAVE_STRCHR #undef HAVE_ANTLR_RUNTIME #undef HAVE_QTDBUS #undef HAVE_CPPUNIT /* * on some platforms (OpenBSD) the second parameter to dlopen is different */ #undef DLOPEN_MODE #if 0 #ifdef __cplusplus using namespace std; /* #ifndef __STD #define __STD std #endif */ #endif #endif #ifdef _WIN32 #define SNPRINTF _snprintf #define VSNPRINTF _vsnprintf #define WINVER 0x0502 #define PACKAGE_LOCALE_DIR "" #define PACKAGE_DATA_DIR "" #define PACKAGE_SOURCE_DIR "" /* * Normally this macro defines directory where system-wide QT * translations are installed. We do not use it on win32 since * we can't assume user has QT installed on their machine. */ #define QTTRANSLATIONSDIR "." #else #undef PACKAGE_LOCALE_DIR #undef PACKAGE_DATA_DIR #undef PACKAGE_SOURCE_DIR #define SNPRINTF snprintf #define VSNPRINTF vsnprintf #endif fwbuilder-5.1.0.3599/autogen.sh0000755000175000017500000000222711733011756017002 0ustar sylvestresylvestre#!/bin/sh MAKE=`which gnumake 2>/dev/null` if test ! -x "$MAKE" ; then MAKE=`which gmake` ; fi if test ! -x "$MAKE" ; then MAKE=`which make` ; fi HAVE_GNU_MAKE=`$MAKE --version|grep -c "Free Software Foundation"` if test "$HAVE_GNU_MAKE" != "1"; then echo Could not find GNU make on this system, can not proceed with build. exit 1 else echo Found GNU Make at $MAKE ... good. fi if test ! -x "`which aclocal`" then echo "You need aclocal and autoconf to generate configure and Makefile." echo "Please install autoconf package." exit 1 fi if test -x "`which libtoolize`" then LIBTOOLIZE="libtoolize" else if test -x "`which glibtoolize`" then LIBTOOLIZE="glibtoolize" else echo "You need libtoolize to generate autoconf and libtool scripts." echo "Please install libtool package." exit 1 fi fi $LIBTOOLIZE --dry-run --install > /dev/null 2>&1 && { LIBTOOLIZE_ARGS="--force --copy --install" } || { LIBTOOLIZE_ARGS="--force --copy" } echo This script runs configure ... $LIBTOOLIZE $LIBTOOLIZE_ARGS which acinclude >/dev/null 2>&1 && acinclude which aclocal >/dev/null 2>&1 && aclocal autoconf ./configure ${CFGARGS} $* fwbuilder-5.1.0.3599/unit_tests.sh0000755000175000017500000000037511733011756017543 0ustar sylvestresylvestre#!/bin/sh QMAKE="${QMAKE:-qmake}" QMAKEPARAMS="${QMAKESPEC:+ -spec $QMAKESPEC}" set -e find . -mindepth 1 -type d -name unit_tests | while read directory do echo "===> Running tests in $directory" (cd $directory && $QMAKE $QMAKEPARAMS && "$@") done fwbuilder-5.1.0.3599/VERSION0000644000175000017500000000063111733011756016046 0ustar sylvestresylvestre#-*- mode: shell-script; tab-width: 4; -*- FWB_MAJOR_VERSION=5 FWB_MINOR_VERSION=1 FWB_MICRO_VERSION=0 # build number is like "nano" version number. I am incrementing build # number during development cycle # BUILD_NUM="3599" VERSION="$FWB_MAJOR_VERSION.$FWB_MINOR_VERSION.$FWB_MICRO_VERSION.$BUILD_NUM" GENERATION="$FWB_MAJOR_VERSION.$FWB_MINOR_VERSION" # Data format version FWBUILDER_XML_VERSION=22 fwbuilder-5.1.0.3599/doc/0000755000175000017500000000000011733011756015543 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/doc/ReleaseNotes_template.html0000644000175000017500000000316311733011756022720 0ustar sylvestresylvestre

Firewall Builder Release Notes


Version 2.0.1


Released MM/DD/YY
GUI and compilers v2.0.1 require API library libfwbuilder version 2.0.1

Summary

For those who wish to build from source, instructions are outlined in the document "Install and Build instructions" on our web site here

What's new

  • Improvements in the GUI:


  • Improvements in policy compiler for iptables:



  • Improvements in policy compiler for ipfilter:

  • Improvements in policy compilers for all platforms:

  • New components:





Bugs fixed in libfwbuilder API:



Bugs fixed in GUI:



Bugs fixed in iptables policy compiler fwb_ipt:



Bugs fixed in iptables policy compiler fwb_ipf:



Bugs fixed in iptables policy compiler fwb_pf:

fwbuilder-5.1.0.3599/doc/transfer_secuwall.1.txt0000644000175000017500000000332711733011756022173 0ustar sylvestresylvestreTRANSFER_SECUWALL(1) ==================== NAME ---- transfer_secuwall - secunet wall configuration export utility SYNOPSIS -------- *transfer_secuwall* [-l] [-h] [-n] -v 'volumeid' [-f 'filename.xml'] [-d 'workdir'] [-a 'templatedir'] 'firewall_object_name' The switches -a, -f and -d are optional. If they are not specified, the appropriate defaults are used. DESCRIPTION ----------- transfer_secuwall(1) is a helper utility to compress and export secunet wall host OS specific firewall configuration to a portable device. It is also capable of searching and displaying all transfer devices of a system which are suitable for config transfer. OPTIONS ------- *-l*:: List all portable devices of the system. *-h*:: Display help text. *-n*:: Append firewall object name to transfer tarball. The default is *false*. *-v*:: Transfer partition. Specifies the destination partition for firewall configuration export (e.g. /dev/sdc1). *-f*:: Firewall Builder XML file with object definition of firewall to export config. If not specified, the filename will be constructed from the 'workdir' and 'firewall_object_name' values: 'workdir' \+ 'fwobjectname' \+ .fwb *-d*:: Defines the working directory. If not specified, the current directory will be used. *-a*:: Append files from given template directory to transfer tarball. 'firewall_object_name':: Firewall object name. EXAMPLES -------- $ transfer_secuwall -f /tmp/cluster.fwb -d /tmp -v /dev/sdc1 fw3 This will export the configuration of secunet wall firewall *fw3* to the partition */dev/sdc1*, using the Firewall Builder XML file *cluster.fwb* in the working directory */tmp*. AUTHOR ------ Written by Reto Buerki . fwbuilder-5.1.0.3599/doc/fwb_ipfw.10000644000175000017500000000377211733011756017441 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_ipfw 1 "" FWB "Firewall Builder" .SH NAME fwb_ipfw \- Policy compiler for ipfw .SH SYNOPSIS .B fwb_ipfw .B [-vVx] .B [-d wdir] .B [-o output.fw] .B [-i] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_ipfw is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for ipfw - a firewall and traffic shaper in FreeBSD (see ipfw(8)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates firewall configuration and activation script. The generated file has a name that starts with the name of the firewall object, with an extension ".fw". It is a shell script that flushes current policy, then loads new filter and nat rules. The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates firewall activation script in this directory. If this parameter is missing, then all files will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-i" When this option is present, the last argument on the command line is supposed to be firewall object ID rather than its name .IP "-x" Generate debugging information while working. This option is intended for debugging only and may produce lots of cryptic messages. .SH NOTES Support for ipfw was added in version 1.0.10 of Firewall Builder .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_pf(1) .BR fwb_ipf(1) .P fwbuilder-5.1.0.3599/doc/Credits0000644000175000017500000001303311733011756017063 0ustar sylvestresylvestre$Id: Credits 899 2005-12-14 06:58:43Z vkurland $ We would like to thank the following people who helped us in various ways to make this project happen: Special thanks to Friedhelm Dќsterhіft for help with XML development and initial XSLT filters implementation. For icons for Firewall Builder v2.x : Hector Rivera Falu For icons and a first web site: Tanya Soussokolova For debugging on SuSE, building packages for SuSE and for help with answering support requests: Marc Pfefferkorn For German translation for Firewall Builder v1.x: Marc Pfefferkorn Jens Hektor Axel Stenkamp For localization patch (gettext support) and French translation for Firewall Builder v1.x: Florent MANENS For French translation for Firewall Builder v2.x Jean-Michel PourЬЉ For Japanese translation for Firewall Builder v2.x Tadashi Jokagi For Swedish translation for Firewall Builder v2.x: Daniel Nylander For ideas, suggestions, patches and contributions: ------------------------------------------------------------- Friedhelm Dќsterhіft" - many suggestions and prototype for DTD. Jeremy T. Bouse - package maintainer for Debian - libxml2 support. - X.509 certificate generation druid assistance - iptables/iproute2 patches Carlo Wood - many valuable patches and bug reports - suggestions regarding rpm building process and changes to spec file Jochen Friedrich - ideas for future development Vadim Fedukovich - help with OpenSSL and answering related questions. David Gullasch and stephan_r@users.sourceforge.net - firewall policy installation script Igor Morozov - first attempt at Win32 porting and a prototype Mark Vevers - for an idea and a patch that fixes optimizer in fwb_ipt Patch information: Author: Mark Vevers Copyright (c) 2004 Research Machines Plc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Compal GmbH, Germany, Tidei Maurizio, fwbuilder-routing@compal.de - For contribution of the code that adds support for static routing for Linux Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Steven Mestdagh - for the code for the static routing configutation for PIX Copyright (c) 2008 Steven Mestdagh Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Heiko Helmle - for valuable ideas and suggestions that lead to improvement of support for Linux static routing configuration fwbuilder-5.1.0.3599/doc/README.floppyfw0000644000175000017500000000424611733011756020276 0ustar sylvestresylvestre How to generate firewall script for floppyfw (http://www.zelow.no/floppyfw/index.html) 1. in Firewall dialog, tab "Firewall", set the following parameters: - "Load modules" - OFF - "Create virtual addresses for NAT rules" - ON - "Use numeric log levels" - ON 2. download and install rpm "fwbuilder-floppyfw-0.9.7" 3. in "Compile/Install" tab configure full path and name of the install script "/usr/bin/floppyfw_install.sh". Now you can compile policy in a usual way using menu Rules->Compile and then install it to floppyfw floppy using menu Rules->Install. Install script makes certain checks to verify that floppy you use indeed contains floppyfw code. Install script depends on mtools package. 4. some useful configuration parameters for floppyfw: - activate serial console for kernel boot-time messages and shell: in file "config" : SERIAL_CONSOLE=ttyS0 in file "syslinux.cfg" add "console=ttyS0,9600" kernel parameters: ------- file config ---------------------- # Choose the serial port for the console "n" for none. SERIAL_CONSOLE=ttyS0 ------------------------------------------ ------- file syslinux.cfg ---------------- default floppyfw display floppyfw.msg label floppyfw kernel vmlinuz append initrd=initrd.gz root=/dev/fd0 console=ttyS0,9600 ether=0,0,0,eth0 ether=0,0,0,eth1 ------------------------------------------ - logging via syslog: in file "config" set USE_SYSLOG=y and add "-R" to log to remote loghost ------- file config ---------------------- # Turning on syslogd and klogd. # This is a nice thing but will eat CPU which is why it is turned # off by default. # USE_SYSLOG=y # This SYSLOG does not use syslogd.conf so we have to set things here. # Flags: # Log to /dev/tty3 instead of /var/log/messages which aren't exactly a # good idea on a ramdisk. # -O /dev/tty3 # Log to network. host:port # -R 10.42.42.42:514 # Log to both network and file: # -L # --MARK-- 0 is no mark. # -m 0 # SYSLOG_FLAGS="-m 360 -O /dev/tty3" SYSLOG_FLAGS="-m 360 -R 10.42.42.4:514" ------------------------------------------ - do not forget to add rule to the firewall policy to permit sending syslog packets from firewall to your loghost fwbuilder-5.1.0.3599/doc/fwb_ipfw21.10000644000175000017500000000355311733011756017601 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_ipfw 1 "" FWB "Firewall Builder" .SH NAME fwb_ipfw \- Policy compiler for ipfw .SH SYNOPSIS .B fwb_ipfw .B [-vVx] .B [-d wdir] .B [-o output.fw] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_ipfw is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for ipfw - a firewall and traffic shaper in FreeBSD (see ipfw(8)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates firewall configuration and activation script. The generated file has a name that starts with the name of the firewall object, with an extension ".fw". It is a shell script that flushes current policy, then loads new filter and nat rules. The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates firewall activation script in this directory. If this parameter is missing, then all files will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-x" Generate debugging information while working. This option is intended for debugging only and may produce lots of cryptic messages. .SH NOTES Support for ipfw was added in version 1.0.10 of Firewall Builder .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_pf(1) .BR fwb_ipf(1) .P fwbuilder-5.1.0.3599/doc/README.iosacl0000644000175000017500000000704011733011756017675 0ustar sylvestresylvestre Policy compiler for Cisco IOS Access lists has been implemented as part of the Firewall Builder GUI as of version 2.1.12. The first functional build were importer worked on all supported OS was build 270 (May 22, 2007) Support for Cisco IOS access lists in Firewall Builder v2.1.12, build 270: ---------------------------------------------------------------- Features implemented in this version: - The compiler generates extended ACLs using "ip access-list extended" command. ACL names are automatically generated using abbreviated interface names and direction symbols to make it easy to figure out which ACL is which. Compiler uses rather minimal set of options of the "ip access-list" command and should generate code that will work for IOS 12.x. I did not test with 11.x but I am pretty sure it will work, at least with the latest versions of 11.x. - Compiler can also add commands to configure logging. - The GUI includes built-in installer for routers which works just like installer for PIX. Both installers were updated however to improve support for the automatic roll-back feature in case you lose connect with the firewall or the router because of an error in the policy. Now you can make installer schedule reboot in a few minutes, then upload new policy or ACLs and then cancel reboot if upload was successful. While before auto-rollback option was only available if you installed in the test mode, now you can always use it. Test mode means that installer does not save configuration in the permanent memory, as before. - All three installation methods that were available for PIX are now available for routers: you can make it clear all access lists and then load new ones or just update access lists without clearing. The last method (the "safety net" method) creates temporary acl to permit communication with the management station, assigns it to the interface marked as management interface, then clears all access lists and loads new ones and in the end swaps proper list on the management interface. This helps prevent locking yourself out of the router in the middle of the installation process in case of an error in the ACL and at the same time does not leave the router with no acls for the time it takes to install new policy. In combination with automatic roll-back, installation process is pretty reliable. - New option has been added to the interface object, called "unprotected". This allows you to mark some interfaces to be skipped by the compiler when it picks interfaces for ACL rules. This should be useful when you have routers with many interfaces and only want to add ACLs to some of them. Also, you can explicitly put interface objects into policy rules and specify direction if you want to do this manually. - Since router ACLs have no state, all rules should be created in the policy pretty much like you do it on the router, including rules that permit reply packets. New option has been added to the TCP Service object, called "established". This makes compiler use option "established" in rules it generates if it is supported by the firewall platform. Compilers for iptables, ipfilter, pf and PIX can not use objects with this option and treat it as an error because corresponding platforms do not support it. IPFW, on the other hand, supports it so compiler fwb_ipfw can use it. Shortcomings of this version: - "tos", "precedence" and "time-range" options are not supported - "igmp" access lists can no be generated fwbuilder-5.1.0.3599/doc/README.pix0000644000175000017500000004176511733011756017237 0ustar sylvestresylvestre Firewall Builder for PIX Version 3.0.0 Summary of Features Usage: Like all Firewall Builder policy compilers, policy compiler for PIX has the following command line options: fwb_pix [-vV] [-d wdir] -f data_file.xml object_name +------------------------------------------------------------------------+ | -f FILE | Specify the name of the data file to be processed. | |---------+--------------------------------------------------------------| | -d wdir | Specify working directory. Compiler creates file with PIX | | | configuration in this directory. If this parameter is | | | missing, then PIX configuration will be placed in the | | | current working directory. | |---------+--------------------------------------------------------------| | -v | Be verbose: compiler prints diagnostic messages while it | | | works. | |---------+--------------------------------------------------------------| | -V | Print version number and quit. | +------------------------------------------------------------------------+ Compiler reads objects definitions and firewall description from the data file specified with '-f' option and generates resultant Cisco PIX configuration file. The configuration is written to the file with the name the same as the name of the firewall object, plus extension '.fw'. Normally you won't have to call policy compiler on the command line because Firewall Builder GUI does it automatically when you use main menu item 'Rules/Compile'. The GUI calls compiler with options -f and -d (if working directory is specificed in the GUI Options dialog). Option '-v' can be added in the 'Compile/Install' tab of the firewall object dialog. Network Zones In order to be able to assign generated access lists to interfaces of the firewall, policy compiler needs information about network topology. This information is relayed to it through the special parameter on firewall's interface called Network Zone. Network Zone is a network object or a group of objects that reflect all networks that are located 'behind' given interface. In other words, it is assumed that only packets with source addresses belonging to the Network Zone can enter this interface. See Users Guide for more detailed explanation of this concept. Policy: When rule includes services 'telnet' or 'ssh' and destination is firewall itself or one of its interfaces, compiler generates commands 'telnet' or 'ssh'. When rule includes any ICMP service and destination is firewall or one of its interfaces, compiler generates command 'icmp' In all other cases compiler generates 'access-list' and attaches it to one or several interfaces. Compiler can emulate outbound ACL. We do not use commands 'outbound/apply' since they are deprecated and Cisco recommends using access lists. Compiler supports address range objects; it expands them to the set of individual addresses. Since PIX does not support checking for IP options, rules that use IP Service objects with any options will cause compiler to stop processing of the policy and print error message. The same goes for checking TCP options and flags. There is one exception though: for IP object with options 'all fragments' or "'short' fragments" compiler generates command 'sysopt security fragguard' Where possible, compiler creates and uses object-groups. In this version different object-groups may contain the same objects, this will be fixed in the future releases. Policy compiler can perform check for shadowing rules, this is controlled by an option in the GUI. NAT Compiler supports global pools; for rules that use network or address range objects in Translated Source, compiler creates global pools with appropriate addresses. Dynamic translation rules where Translated Source is a firewall or one of its interfaces generate global pool with option 'interface' Dynamic translation rules that create translation going from lower security level interface to the one with higher security level generate command 'nat ... outside' Compiler generates 'nat 0 ' commands for rules that require no translation NAT compiler can perform the following checks for rule consistency and correctness: * check for duplicate 'nat' rules * check for overlapping global pools * check for overlapping 'static' rules * check for 'static' rules overlapping with global pools 'timeout' commands User can configure 'timeout' commands using 'Advanced' dialog in the Firewall tab of the firewall object dialog. Firewall Builder has information about default values of all parameters for 'timeout' commands for PIX v6.1 and 6.2. All configured timeout commands can be reset to their default values with a button 'Set all to defaults'. 'fixup' commands User can configure 'fixup' commands using 'Advanced' dialog in the Firewall tab of the firewall object dialog. Firewall Builder has information about default values for all parameters for 'fixup' commands for PIX v 6.1 and 6.2. All configured fixup commands can be reset to their default values with a button 'Set all to defaults'. 'logging' commands Policy compiler can generate 'logging' commands for syslog, internal buffer and console logging. For syslog user can specify server name or address, syslog message queue size, facility and level. For internal buffer and console logging the level can be specified. User can also enable logging timestamps for syslog logging. All logging parameters are located in the 'Advanced' dialog in the Firewall tab of the firewall object dialog. 'ntp' commands Policy compiler can generate commands to configure NTP protocol. Up to three NTP servers can be spcified, one of which can be marked as preferred. 'snmp' commands Policy compiler can generate commands to configure SNMP agent. SNMP communities can be specified in the GUI. SNMP 'sysinfo' data, such as location and contact can also be defined in the GUI. Two SNMP servers can be configured, each of them can be configured for polling, traps or both. Compiler can also generate command 'snmp-server enable traps' to send log messages as SNMP trap notifications. 'sysopt' and 'floodguard' commands Policy compiler can use the following 'sysopt' commands which are controlled by the GUI elements in the 'Advanced' dialog in the Firewall tab of the firewall object dialog: * sysopt connection tcpmss * sysopt connection timewait * sysopt security fragguard * sysopt nodnsalias inbound * sysopt nodnsalias outbound * sysopt route dnat Compiler can also generate command 'floodguard enable/disable'. Options found in the "Firewall" tab of the firewall dialog and their meaning: +------------------------------------------------------------------------+ | Version: | PIX OS version, choices are 6.1 and 6.2 | |----------------+-------------------------------------------------------| | Prolog Script: | this is a list of any PIX configuration commands that | | | will be included on top of generated configuration | | | file. No syntax or other checks are done on commands | | | in this list. | |----------------+-------------------------------------------------------| | Epilog Script: | this is a list of any PIX configuration commands that | | | will be appended at the end of generated | | | configuration file. No syntax or other checks are | | | done on commands in this list. | +------------------------------------------------------------------------+ Policy Compiler Options: +------------------------------------------------------------------------+ | Assume firewall | For all rules where source or destination is 'any', | | is part of Any | compiler generates PIX commands as if there was one | | | more rule with firewall objects in the same rule | | | element. In the case of PIX there is a difference | | | only if service in the rule uses objects | | | representing ssh, telnet and any icmp protocols, in | | | which case it generates commands "ssh", "telnet" or | | | "icmp" in addition to the regular access list | | | command. | |------------------+-----------------------------------------------------| | Replace NAT'ed | PIX inspects packet with access lists before it | | objects with | performs address translation. Many other firewall | | their | platforms do it the other way around. This option | | translations in | turns on emulation of the firewall that does NAT | | policy rules | first. | |------------------+-----------------------------------------------------| | Emulate outbound | Normally PIX does not support outbound access | | ACLs | lists.This option turns on amulation of outbound | | | ACLs. | |------------------+-----------------------------------------------------| | Generate 'clear' | If this option is ON, compiler generates 'clear' | | commands | commands to reset any pre-existing access lists, | | | object-group, nat, global, static, telnet, ssh and | | | other commands. | |------------------+-----------------------------------------------------| | Optimize | simplifies nat rules if object in Original Source | | 'default nat' | is the same as the Network zone of one of the | | rules | interfaces. Network zone of the interfaces defines | | | all networks that are located "behind" this | | | interface. This means that packets entering the | | | interface may have source address only belonging to | | | the Network zone of this interface. Since policy | | | compiler can correctly assign nat rule to the | | | interface using information about its Network Zone, | | | explicit specification of the source address can be | | | omitted. | |------------------+-----------------------------------------------------| | Ignore empty | Policy compiler can find and eliminate empty groups | | groups in rules | if they are used in the policy rules. If this | | | option is OFF, compiler treats empty groups as an | | | error and aborts compilation. If it is ON, then it | | | removes empty groups from rule elements. If rule | | | element becomes empty (that is, becomes 'any') | | | after the last empty group has been removed, then | | | the whole rule is ignored. This may be useful if | | | you need to control access to or from flexible | | | group of hosts and do not want to make changes to | | | the firewall policy rules. In this case you can | | | create a group of hosts or networks and use it in | | | the rule. Any changes to the set of hosts that need | | | control can now be made in the group, with the rule | | | staying intact. If for some reason the group | | | becomes empty because all hosts have been removed, | | | compiler will ignore the rule instead of treating | | | empty group as 'any'. | +------------------------------------------------------------------------+ Script formatting: +------------------------------------------------------------------------+ | Comment the code | If this option is activated, compiler adds comments | | | to the configuration file | |------------------+-----------------------------------------------------| | Group similar | If this option is activated, compiler groups | | commands | similar commands next to each other, just like PIX | | together | device does it in the output of "show config" | | | command. Otherwise commands are grouped logically: | | | first go all object-group commands, then all | | | access-lists, then all nat, global and static | | | commands. Commands access-list, nat, global and | | | static are grouped by the rules they were generated | | | for, as they appear in the GUI. If one rule | | | requires several access-list commands assigned to | | | different interfaces, these commands are grouped | | | together. Command "show conf" groups access-list | | | commands by their interface. | +------------------------------------------------------------------------+ Verification of Policy Rules: +------------------------------------------------------------------------+ | Detect rule | Shadowing happens because a rule is a superset of a | | shadowing in the | subsequent rule and any packets potentially matched | | policy | by a subsequent rule have already been matched by a | | | prior rule. If this option is activated, compiler | | | detects this situation and abort compilation with | | | an error message. | +------------------------------------------------------------------------+ Verification of NAT rules: +------------------------------------------------------------------------+ | Check for | If this option is activated, compiler checks | | duplicate nat | generated configuration for duplicate 'nat' | | rules | commands | |------------------+-----------------------------------------------------| | Check for | If this option is activated, compiler checks | | overlapping | generated configuration for overlapping 'global' | | global pools | address pools | |------------------+-----------------------------------------------------| | Check for | If this option is activated, compiler checks | | overlapping | generated configuration for 'static' commands that | | statics | use overlapping address ranges. | |------------------+-----------------------------------------------------| | Check for | If this option is activated, compiler checks | | overlapping | generated configuration for 'global' and 'static | | global pools and | commands using overlapping address ranges. | | statics | | +------------------------------------------------------------------------+ Caveats: PIX does not support filtering by MAC address. Although GUI provides entry field for the MAC address, it is ignored by PIX policy compiler. static translation (DNAT) rules create in fact bidirectional translation (not only translation from outside to inside, but also in the opposite direction using the same addresses). This is caused by the behavior of PIX command 'static' and can't be easily fixed. GUI option Logging is ignored because PIX can not turn logging on and off, it always logs blocked packets. There are no rule options available as of yet. Unlike in Linux/iptables and other firewall platforms, PIX inspects packet before it does NAT. Therefore policy rules that control access to NAT'ted hosts should use objects, representing translated addresses instead of objects representing real hosts. Firewall Builder provides an emulation for the mode where NAT happens before the policy (ACL) inspection. Use checkbox "Replace NAT'ed objects with their translations in policy rules" to turn on this emulation. You can use objects representing real servers in the policy rules if this option is on. Version 3.0 does not support IPSEC configuration. fwbuilder-5.1.0.3599/doc/fwb_compile_all.10000644000175000017500000000266411733011756020753 0ustar sylvestresylvestre.TH fwb_compile_all 1 "" FWB "Firewall Builder" .SH NAME fwb_compile_all \- Wrapper script that compiles policies for multiple firewall objects .SH SYNOPSIS .B fwb_compile_all .RB -f file.xml .RB [-d wdir] .RB [-av] [obj[ obj ...]] .SH "DESCRIPTION" .B fwb_compile_all is a wrapper script that compiles policies for several firewall objects in one batch job. This script takes a list of firewall object names on the command line (or '-a' command line option, see below) and calls policy compiler for each one. The script correctly determines which policy compiler is needed depending on the firewall platform of each object. .SH OPTIONS .IP "-a" The script processes all firewall objects in the "/Firewalls" subtree. .IP "-d wdir" Specify working directory. Compiler creates file with iptables script in this directory. If this parameter is missing, then iptables script will be placed in the current working directory. .IP "-f FILE" Specify the name of the data file to be processed. .IP "-v" Script passes this option to the compiler, this makes it print diagnostic messages indicating its progress. .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1) .BR fwb_ipf(1) .BR fwb_pf(1) .BR fwbedit(1), .BR fwblookup(1) .P fwbuilder-5.1.0.3599/doc/transfer_secuwall.10000644000175000017500000000427711733011756021362 0ustar sylvestresylvestre.\" Title: transfer_secuwall .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 .\" Date: 02/12/2010 .\" Manual: .\" Source: .\" .TH "TRANSFER_SECUWALL" "1" "02/12/2010" "" "" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" transfer_secuwall \- secunet wall configuration export utility .SH "SYNOPSIS" \fBtransfer_secuwall\fR [\-l] [\-h] [\-n] \-v \fIvolumeid\fR [\-f \fIfilename\&.xml\fR] [\-d \fIworkdir\fR] [\-a \fItemplatedir\fR] \fIfirewall_object_name\fR .sp The switches \-a, \-f and \-d are optional\&. If they are not specified, the appropriate defaults are used\&. .sp .SH "DESCRIPTION" transfer_secuwall(1) is a helper utility to compress and export secunet wall host OS specific firewall configuration to a portable device\&. .sp It is also capable of searching and displaying all transfer devices of a system which are suitable for config transfer\&. .sp .SH "OPTIONS" .PP \fB\-l\fR .RS 4 List all portable devices of the system\&. .RE .PP \fB\-h\fR .RS 4 Display help text\&. .RE .PP \fB\-n\fR .RS 4 Append firewall object name to transfer tarball\&. The default is \fBfalse\fR\&. .RE .PP \fB\-v\fR .RS 4 Transfer partition\&. Specifies the destination partition for firewall configuration export (e\&.g\&. /dev/sdc1)\&. .RE .PP \fB\-f\fR .RS 4 Firewall Builder XML file with object definition of firewall to export config\&. If not specified, the filename will be constructed from the \fIworkdir\fR and \fIfirewall_object_name\fR values: \fIworkdir\fR + \fIfwobjectname\fR + \&.fwb .RE .PP \fB\-d\fR .RS 4 Defines the working directory\&. If not specified, the current directory will be used\&. .RE .PP \fB\-a\fR .RS 4 Append files from given template directory to transfer tarball\&. .RE .PP \fIfirewall_object_name\fR .RS 4 Firewall object name\&. .RE .SH "EXAMPLES" $ transfer_secuwall \-f /tmp/cluster\&.fwb \-d /tmp \-v /dev/sdc1 fw3 .sp This will export the configuration of secunet wall firewall \fBfw3\fR to the partition \fB/dev/sdc1\fR, using the Firewall Builder XML file \fBcluster\&.fwb\fR in the working directory \fB/tmp\fR\&. .sp .SH "AUTHOR" Written by Reto Buerki \&. .sp fwbuilder-5.1.0.3599/doc/doc.pro0000644000175000017500000000267711733011756017046 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../qmake.inc) win32 { CONFIG -= embed_manifest_exe } win32 { QMAKE_RUN_CC = echo QMAKE_RUN_CXX = echo QMAKE_LINK = echo } !win32 { QMAKE_RUN_CC = @echo > /dev/null QMAKE_RUN_CXX = @echo > /dev/null QMAKE_LINK = @echo > /dev/null } TARGET = doc doc.files = AUTHORS \ ChangeLog \ COPYING \ Credits \ README.floppyfw \ README.ipf \ README.ipfw \ README.ipt \ README.pf \ README.pix \ README.pix_routing \ README.routing \ README.iosacl \ README.policy_import \ FWBuilder-Routing-LICENSE.txt \ PatchAcceptancePolicy.txt doc.path = $$DOCDIR man.files = fwbedit.1 \ fwbuilder.1 \ fwb_iosacl.1 \ fwb_ipf.1 \ fwb_ipfw.1 \ fwb_ipt.1 \ fwb_pf.1 \ fwb_pix.1 \ export_secuwall.1 \ # fwb_install.1 \ # fwb_compile_all.1 \ man.path = $$MANDIR/man1 INSTALLS -= target INSTALLS += doc INSTALLS += man fwbuilder-5.1.0.3599/doc/fwb_ipf.10000644000175000017500000000661311733011756017247 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_ipf 1 "" FWB "Firewall Builder" .SH NAME fwb_ipf \- Policy compiler for ipfilter .SH SYNOPSIS .B fwb_ipf .B [-vVx] .B [-d wdir] .B [-o output.fw] .B [-i] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_ipf is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for ipfilter. Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates ipfilter configuration files and firewall activation script. All generated files have names that start with the name of the firewall object. Firewall activation script has extension ".fw" and is simple shell script that flushes current policy, loads new filter and nat rules and then activates ipfilter. IPFilter configuration file name starts with the name of the firewall object, plus "-ipf.conf". NAT configuration file name also starts with the name of the firewall object, plus "-nat.conf". For example, if firewall object has name "myfirewall", then compiler will create three files: "myfirewall.fw", "myfirewall-pf.conf", "myfirewall-nat.conf". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates firewall activation script and ipfilter configuration files in this directory. If this parameter is missing, then all files will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-i" When this option is present, the last argument on the command line is supposed to be firewall object ID rather than its name .IP "-x" Generate debugging information while working. This option is intended for debugging only and may produce lots of cryptic messages. .SH NOTES Support for ipf returned in version 1.0.1 of Firewall Builder Supported features: .IP o both ipf.conf and nat.conf files are generated .IP o negation in policy rules .IP o stateful inspection in individual rule can be turned off in rule options dialog. By default compiler adds "keep state" or "modulate state" to each rule with action 'pass' .IP o rule options dialog provides a choice of icmp or tcp rst replies for rules with action "Reject" .IP o compiler adds flag "allow-opts" if match on ip options is needed .IP o compiler can generate rules matching on TCP flags .IP o compiler can generate script adding ip aliases for NAT rules using addresses that do not belong to any interface of the firewall .IP o compiler always adds rule "block quick all" at the very bottom of the script to ensure "block all by default" policy even if the policy is empty. .IP o Address ranges in both policy and NAT .PP Features that are not supported (yet) .IP o negation in NAT .IP o custom services .PP Features that won't be supported (at least not anytime soon) .IP o policy routing .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/open_source_licenses.txt0000644000175000017500000013503511733011756022521 0ustar sylvestresylvestreopen_source_licenses.txt Firewall Builder The following copyright statements and licenses apply to various open source software components that are distributed with Firewall Builder and other NetCitadel LLC software products. The NetCitadel, LLC product that includes this file does not necessarily use all the open source software components referred to below. ======================================================================= The XML Parser for Gnome license Except where otherwise noted in the source code (trio files, hash.c and list.c) covered by a similar licence but with different Copyright notices: Copyright (C) 1998-2002 Daniel Veillard. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is fur- nished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Daniel Veillard shall not be used in advertising or otherwise to promote the sale, use or other deal- ings in this Software without prior written authorization from him. -------------------------------------------------------------------------- CMU/UCD copyright notice and license Various copyrights apply to this package, listed in 3 separate parts below. Please make sure that you all the parts. Up until 2001, the project was based at UC Davis, and the first part covers all code written during this time. From 2001 onwards, the project has been based at SourceForge, and Networks Associates Technology, Inc hold the copyright on behalf of the wider Net-SNMP community, covering all derivative work done since then. An additional copyright section has been added as Part 3 below also under a BSD license for the work contributed by Cambridge Broadband Ltd. to the project since 2001. Code has been contributed to this project by many people over the years it has been in development, and a full list of contributors can be found in the README file under the THANKS section. ---- Part 1: CMU/UCD copyright notice: (BSD like) ----- Copyright 1989, 1991, 1992 by Carnegie Mellon University Derivative Work - 1996, 1998-2000 Copyright 1996, 1998-2000 The Regents of the University of California All Rights Reserved Permission to use, copy, modify and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of CMU and The Regents of the University of California not be used in advertising or publicity pertaining to distribution of the software without specific written permission. CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CMU OR THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ---- Part 2: Networks Associates Technology, Inc copyright notice (BSD) ----- Copyright (c) 2001-2002, Networks Associates Technology, Inc All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Networks Associates Technology, Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---- Part 3: Cambridge Broadband Ltd. copyright notice (BSD) ----- Portions of this code are copyright (c) 2001-2002, Cambridge Broadband Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of Cambridge Broadband Ltd. may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------- OpenSSL License LICENSE ISSUES ============== The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit. See below for the actual license texts. Actually both licenses are BSD-style Open Source licenses. In case of any license issues related to OpenSSL please contact openssl-core@openssl.org. OpenSSL License --------------- /* ==================================================================== * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@openssl.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ Original SSLeay License ----------------------- /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ -------------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! -------------------------------------------------------------------------- The following is applicable to zlib.h. /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.1.4, March 11th, 2002 Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly jloup@gzip.org Mark Adler madler@alumni.caltech.edu */ -------------------------------------------------------------------------- The following is applicable to Libresolv. /* * Copyright (c) 1983, 1987, 1989 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANYWAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ -------------------------------------------------------------------------- Starting with version 4.0.2, Firewall Builder for Windows package includes putty utilities by Simon Tatham. http://www.chiark.greenend.org.uk/~sgtatham/putty/ PuTTY license page: http://www.chiark.greenend.org.uk/~sgtatham/putty/licence.html The PuTTY executables and source code are distributed under the MIT licence, which is similar in effect to the BSD licence. (This licence is Open Source certified and complies with the Debian Free Software Guidelines.) The precise licence text, as given in the About box and in the file LICENCE in the source distribution, is as follows: PuTTY is copyright 1997-2010 Simon Tatham. Portions copyright Robert de Bath, Joris van Rantwijk, Delian Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus Kuhn, Colin Watson, and CORE SDI S.A. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. In particular, anybody (even companies) can use PuTTY without restriction (even for commercial purposes) and owe nothing to me or anybody else. Also, apart from having to maintain the copyright notice and the licence text in derivative products, anybody (even companies) can adapt the PuTTY source code into their own programs and products (even commercial products) and owe nothing to me or anybody else. And, of course, there is no warranty and if PuTTY causes you damage you're on your own, so don't use it if you're unhappy with that. In particular, note that the MIT licence is compatible with the GNU GPL. So if you want to incorporate PuTTY or pieces of PuTTY into a GPL program, there's no problem with that. -------------------------------------------------------------------------- starting with version 4.1.3, Firewall Builder includes uint128 class by Evan Teran http://www.codef00.com/coding.php * Copyright (c) 2008 * Evan Teran * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * copyright notice and this permission notice appear in supporting * documentation, and that the same name not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. We make no representations about the * suitability this software for any purpose. It is provided "as is" * without express or implied warranty. fwbuilder-5.1.0.3599/doc/README.pf0000644000175000017500000001115211733011756017027 0ustar sylvestresylvestrefwb_pf(1) Firewall Builder fwb_pf(1) NNAAMMEE fwb_pf - Policy compiler for OpenBSD packet filter "pf" SSYYNNOOPPSSIISS ffwwbb__ppff [[--vvVVxx]] [[--dd wwddiirr]] --ff ddaattaa__ffiillee..xxmmll object_name DDEESSCCRRIIPPTTIIOONN ffwwbb__ppff is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for OpenBSD Packet Filter (pf). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates pf configuration files and firewall activation script. All generated files have names that start with the name of the firewall object. Firewall activation script has exten­ sion ".fw" and is simple shell script that flushes current policy, loads new filter and nat rules and then activates pf. PF configuration file name starts with the name of the firewall object, plus "-pf.conf". NAT configuration file name also starts with the name of the firewall object, plus "-nat.conf". For example, if firewall object has name "myfirewall", then compiler will create three files: "myfirewall.fw", "myfirewall-pf.conf", "myfirewall- nat.conf". The data file and the name of the firewall objects must be specified on the command line. Other command line parame­ ters are optional. OOPPTTIIOONNSS -f FILE Specify the name of the data file to be processed. -d wdir Specify working directory. Compiler creates firewall activation script and PF configuration files in this directory. If this parameter is missing, then all files will be placed in the cur­ rent working directory. -v Be verbose: compiler prints diagnostic messages when it works. -V Print version number and quit. -x Generate debugging information while working. This option is intended for debugging only and may pro­ duce lots of cryptic messages. NNOOTTEESS Support for PF has been introduced in version 1.0.1 of Firewall Builder Supported features: o both pf.conf and nat.conf files are generated o negation in policy and NAT rules o grouping in "from", "to" and ports using '{' '}' syntax o if checkbox "Scrub" is checked in the rule options dialog, and rule's action is Accept, the compiler generates two (almost) identical rules: first with action 'scrub' and the second with action 'pass quick' o stateful inspection in individual rule can be turned off in rule options dialog. By default com­ piler adds "keep state" or "modulate state" to each rule with action 'pass' o rule options dialog provides a choice of icmp or tcp rst replies for rules with action "Reject" o compiler adds flag "allow-opts" if match on ip options is needed o compiler can generate rules matching on TCP flags o compiler can generate script adding ip aliases for NAT rules using addresses that do not belong to any interface of the firewall o compiler always adds rule "block quick all" at the very bottom of the script to ensure "block all by default" policy even if the policy is empty. o Address ranges in both policy and NAT Features that are not supported (yet) o custom services What will not be supported (at least not anytime soon) o policy routing UURRLL Firewall Builder home page is located at the following URL: hhttttpp::////wwwwww..ffwwbbuuiillddeerr..oorrgg// BBUUGGSS Please report bugs using bug tracking system on Source­ Forge: hhttttpp::////ssoouurrcceeffoorrggee..nneett//ttrraacckkeerr//??ggrroouupp__iidd==55331144&&aattiidd==110055331144 SSEEEE AALLSSOO ffwwbbuuiillddeerr((11)),, ffwwbb__iipptt((11)),, ffwwbb__iippff((11)) FWB fwb_pf(1) fwbuilder-5.1.0.3599/doc/fwb_iosacl.10000644000175000017500000000502011733011756017732 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_pix 1 "" FWB "Firewall Builder" .SH NAME fwb_ipt \- Policy compiler for Cisco IOS ACL .SH SYNOPSIS .B fwb_iosacl .B [-vV] .B [-d wdir] .B [-4] .B [-6] .B [-i] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_iosacl is firewall policy compiler component of Firewall Builder (see fwbuilder(1)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates resultant Cisco IOS ACL configuration file. The configuration is written to the file with the name the same as the name of the firewall object, plus extension ".fw". Compiler generates extended access lists for Cisco routers running IOS v12.x using "ip access-list " syntax. Compiler also generates "ip access-group" commands to assign access lists to interfaces. Generated ACL configuration can be uploaded to the router manually or using built-in installer in the fwbuilder(1) GUI. The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-4" Generate iptables script for IPv4 part of the policy. If any rules of the firewall refer to IPv6 addresses, compiler will skip these rules. Options "-4" and "-6" are exclusive. If neither option is used, compiler tries to generate both parts of the script, although generation of the IPv6 part is controlled by the option "Enable IPv6 support" in the "IPv6" tab of the firewall object advanced settings dialog. This option is off by default. .IP "-6" Generate iptables script for IPv6 part of the policy. If any rules of the firewall refer to IPv6 addresses, compiler will skip these rules. .IP "-f FILE" Specify the name of the data file to be processed. .IP "-d wdir" Specify working directory. Compiler creates file with ACL configuration in this directory. If this parameter is missing, then generated ACL will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-i" When this option is present, the last argument on the command line is supposed to be firewall object ID rather than its name .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_pix(1), .BR fwb_ipfw(1), .BR fwb_ipf(1), .BR fwb_ipt(1) .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/README.ipt0000644000175000017500000000411111733011756017213 0ustar sylvestresylvestrefwb_ipt(1) Firewall Builder fwb_ipt(1) NNAAMMEE fwb_ipt - Policy compiler for iptables SSYYNNOOPPSSIISS ffwwbb__iipptt [[--wwvvVV]] [[--dd wwddiirr]] --ff ddaattaa__ffiillee..xxmmll object_name DDEESSCCRRIIPPTTIIOONN ffwwbb__iipptt is firewall policy compiler component of Firewall Builder (see fwbuilder(1)). Compiler reads objects defini­ tions and firewall description from the data file speci­ fied with "-f" option and generates resultant iptables script. The script is written to the file with the name the same as the name of the firewall object, plus exten­ sion ".fw". The data file and the name of the firewall objects must be specified on the command line. Other command line parame­ ters are optional. OOPPTTIIOONNSS -f FILE Specify the name of the data file to be processed. -d wdir Specify working directory. Compiler creates file with iptables script in this directory. If this parameter is missing, then iptables script will be placed in the current working directory. -w Supress compiler's warnings -v Be verbose: compiler prints diagnostic messages when it works. -V Print version number and quit. UURRLL Firewall Builder home page is located at the following URL: hhttttpp::////wwwwww..ffwwbbuuiillddeerr..oorrgg// BBUUGGSS Please report bugs using bug tracking system on Source­ Forge: hhttttpp::////ssoouurrcceeffoorrggee..nneett//ttrraacckkeerr//??ggrroouupp__iidd==55331144&&aattiidd==110055331144 SSEEEE AALLSSOO ffwwbbuuiillddeerr((11)),, ffwwbb__iippff((11)),, ffwwbb__ppff((11)) FWB fwb_ipt(1) fwbuilder-5.1.0.3599/doc/fwb_ipt.10000644000175000017500000000653511733011756017270 0ustar sylvestresylvestre.TH fwb_ipt 1 "" FWB "Firewall Builder" .SH NAME fwb_ipt \- Policy compiler for iptables .SH SYNOPSIS .B fwb_ipt .RB -f data_file.xml .RB [-4] .RB [-6] .RB [-V] .RB [-d wdir] .RB [-i] .RB [-o output.fw] .RB [-O fw1_id,fw1_output.fw[,fw2_id,fw2_output.fw]] .RB [-v] .RB [-xc] .RB [-xn N] .RB [-xp N] .RB [-xt] object_name .SH "DESCRIPTION" .B fwb_ipt is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates resultant iptables script. The script is written to the file with the name the same as the name of the firewall object, plus extension ".fw". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-4" Generate iptables script for IPv4 part of the policy. If any rules of the firewall refer to IPv6 addresses, compiler will skip these rules. Options "-4" and "-6" are exclusive. If neither option is used, compiler tries to generate both parts of the script, although generation of the IPv6 part is controlled by the option "Enable IPv6 support" in the "IPv6" tab of the firewall object advanced settings dialog. This option is off by default. .IP "-6" Generate iptables script for IPv6 part of the policy. If any rules of the firewall refer to IPv6 addresses, compiler will skip these rules. .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-O fw1_id,fw1_output.fw[,fw2_id,fw2_output.fw]" The argument is a comma separated list of firewall object IDs and corresponding output file names. This option is used by fwbuilder GUI while compiling firewall clusters. .IP "-d wdir" Specify working directory. Compiler creates file with iptables script in this directory. If this parameter is missing, then iptables script will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-i" When this option is present, the last argument on the command line is supposed to be firewall object ID rather than its name .IP "-xc" When output file name is determined automatically (i.e. flags -o or -O are not present), the file name is composed of the cluster name and member firewall name rather than just member firewall name. This is used mostly for testing when the same member firewall object can be a part of different clusters with different configurations. .IP "-xt" This flag makes compiler treat all fatal errors as warnings and continue processing rules. Generated configuration script most likely will be incorrect but will include error message as a comment; this flag is used for testing and debugging. .IP "-xp N" Debugging flag: this causes compiler to print detailed description of the policy rule number "N" as it precesses it, step by step. .IP "-xn N" Debugging flag: this causes compiler to print detailed description of the NAT rule number "N" as it precesses it, step by step. .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipf(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/README.routing0000644000175000017500000002152211733011756020113 0ustar sylvestresylvestre //=========================================================================\\ || Firewall Builder Routing Add-On || || || || Copyright (c) 2004 Compal GmbH, Germany || || Tidei Maurizio, fwbuilder-routing at compal.de || || || \\=========================================================================// Index 1 - Requirements 2 - Features 3 - Problems 4 - Future (1) Requirements ================ The routing rules composed in the gui can be compiled using the ip tables compiler, which now generates "ip route" commands, too. The "ip" command is available since Linux 2.2. The other compilers (ipf, ipfw, pf and cisco pix) simply ignore the routing rules. If you want to use ECMP routing rules (Equal Cost Multi Path), make sure your kernel is compiled with the CONFIG_IP_ROUTE_MULTIPATH option. (2) Features ============ The GUI's routing add-on offers object based definition of the routing rules, exactly the same way as you define policy rules. This enables you to use the same objects you already defined to build the firewall policy in your routing rules. You won't have to update them separately when you change something in your network. In the GUI a routing rule is composed of a Destination, a Gateway, an Interface, a Metric and the Comment. The following table shows what can be inserted for this elements: | | | | | |Destination |Gateway |Interface |Metric |Comment ------------------------|-------------------------------|---------------|---------------|-------|-------- What can be inserted? |all Objects under the |- ip-adress |- interface |int |text |library's "Objects" section: |- interface | | | |- address ranges |- host | | | |- addresses | | | | |- groups | | | | |- hosts | | | | |- networks | | | | ------------------------|-------------------------------|---------------|---------------|-------|-------- Restrictions |none |Only one |The interface |0-255 |none | |interface or |has to be a | | | |host with ONE |child of the | | | |ip adress can |current fire- | | | |be inserted |wall | | ------------------------|-------------------------------|---------------|---------------|-------|-------- Default value |"Default" (0.0.0.0/0) |none |none |0 |"" | | | | | To build a valid routing rule you have to insert at least one of the two elements gateway and interface. More than one path can be sprecified for one destination. "This approach is called 'Equal-Cost Multi-Path Routing' and is used for load balancing (Note that this does not provide failover). With ECMP, a router potentially has several available next hops towards any given destination. A new gateway is chosen for each new source/destination IP pair. This means that, for example, one FTP connection will use only one link, but new connection to a different server will use another link. This also means that routes to often-used sites will always be over the same provider. But on big backbones this should distribute traffic fine. Also this has another good feature - single connection packets do not get reordered and therefore do not kill TCP performance." (The last Paragraph is a quotation from "http://www.mikrotik.com/Documentation/manual_2.7/IP/Route.html") To create an ECMP rule simply specify several rules with different paths, i.e. different combinations of Gateway and Interface, for the same Destination and with the same metric. Example: Destination Gateway Interface Metric Comment hostA hostB eth1 0 first possible route hostA hostC 0 second possible route hostA eth3 0 third possible route If you try to insert a non-valid object in a field, it will be ignored and a message box informs you of the mistake. The "Default" route can be specified by inserting a new rule or deleting all the destination of an existing rule. Before compiling the rules, they traverse several checks, to make sure that only complete, non-ambiguous and non-concurring rules are translated into ip commands. Follow the instructions of the compiler to correct the errors. If no error was found, the rules are automatically classified in ECMP rules and non-ECMP. The ECMP rules are written out in a separated section of the firewall script after the "normal" routing rules. (3) Problems ============ 1. Please note that when executing a firewall script all existing routing rules previously set by user space processes will be deleted. To see which rules will be deleted, you can use the command "ip route show". All lines not including "proto kernel" will be deleted upon reload of the firewall script. 2. *** NOTE FOR REDHAT 8.0 *** Redhat seems to reset routing rules explicitly upon system startup. Therefore its hard to distinguish interface rules from rules setup by the user. On Redhat systems you need to include the interface basic routing rules into your fwbuilder routing setup. IF YOU DO NOT FOLLOW THIS HINT, YOUR MACHINE WILL FREEZE ANY NETWORK TRAFFIC UPON START OF THE FIREWALL SCRIPT. This means e.g. if eth0 has network 192.168.3.0/24 attached to it, you need to add a route with Destination=Network(192.168.3.0/24), Gateway empty and Interface=eth0. We encountered this problem on redhat 8.0. Other versions and distros might be affected too. Debian sarge and SuSE Linux work fine without interface routing rules being included in fwbuilders routing rules. 3. If the firewall script states that the ECMP routes could not be installed on your system, make sure your Kernel was compiled with the CONFIG_IP_ROUTE_MULTIPATH option or renounce to ECMP rules. 4. If you have interfaces with a dynamic address or a point-to-point address and you try to insert a routing rule for the default gateway, compilation might fail, stateing "gateway not reachable". Typically this is the case for DSL dialup links. Solution: leave the gateway field empty. Just specify the interface. Example: The firewall connects itself to the internet by a DSL link via interface ppp0. During dialup pppd configures the default route: default via 62.14.190.33 dev ppp After specifying a routing rule in fwbuilder Destination=default, Gateway empty, Interface=ppp0 and running the script on the firewall, the route looks like: default dev ppp0 scope link Besides this, the kernel generates another route automaticelly upon default gw setup: 62.14.190.33 dev ppp0 proto kernel scope link src 191.54.12.143 We tested this on Debian/sarge with kernel 2.4.27. Technical explanation: On compilation, fwbuilder checks if gateways are reachable through any local network of the firewall. Otherwise setting up routing rules will fail on the firewall upon install. In case of point-to-point interfaces fwbuilder doesn't know the point-to-point address of the interface. Therefore this check fails since for fwbuilder it looks like the gateway is not from any local network. The only workaround available so far is to leave the gateway empty and to specify the interface only. Pakets will find their way to the internet anyway, since they are traveling over a point-to-point interface. (4) Future ========== Ideas, that could be implemented in the future, are: - Multiple customizable routing tables The idea is to add an option to the policy rules enabling the user to mark matching packets with a color. For every used color a new routing table would have to be built, that will be used only for packets marked with the associated color. - Load balancing Another idea is to integrate more sophisticated load balancing options in fwbuilder's GUI. fwbuilder-5.1.0.3599/doc/README.cluster0000644000175000017500000001335311733011756020110 0ustar sylvestresylvestre Firewall Builder Clustering Add-On ================================== Copyright (c) 2009 secunet Security Networks AG, Germany Copyright (c) 2009 Adrian-Ken Rueegsegger Copyright (c) 2009 Reto Buerki Index ----- 1 - Introduction 2 - Definition 3 - Usage 4 - Example 5 - Things to consider 6 - References Introduction ------------ The Firewall Builder Clustering Add-On provides the possibility to manage multiple firewall objects together as one Cluster object. Cluster objects are used to configure HA (High Availability) features like conntrack [1] and VRRP [2] (Virtual Router Redundancy Protocol). Definition ---------- In the context of this Add-On a 'cluster' object is regarded as a meta-object grouping multiple firewall objects. This allows for a much simpler and convenient configuration of a HA scenario. The configuration is done once for the meta-object 'Cluster' and automatically compiled and distributed for each cluster member firewall. [cluster] (meta-object) | | +-----------------+-----------------+ | | | [fw1] (object) [fw2] (object) [fwX] (object) Usage ----- To use the clustering feature, you need to create firewalls which will be part of a HA cluster and create the cluster itself. The following two sections describe the necessary steps. Firewall configuration ~~~~~~~~~~~~~~~~~~~~~~ Make sure that all firewalls of a cluster use the same host OS and platform. The host OS and platform of all cluster member firewalls must match the one specified for the cluster itself. The following diagram defines two firewalls configured appropriately as cluster members: [fw1] [OS: secunet wall, Platform: iptables] | +---o eth0: outside (ext) | +---o IP: 172.24.0.2/255.255.0.0 | +---o eth1: inside +---o IP: 192.168.1.2/255.255.255.0 [fw2] [OS: secunet wall, Platform: iptables] | +---o eth0: outside (ext) | +---o IP: 172.24.0.3/255.255.0.0 | +---o eth1: inside +---o IP: 192.168.1.3/255.255.255.0 Both firewalls have an outside and an inside interface. In a cluster scenario, these interfaces will be combined to a redundant VRRP cluster interface. VRRP requires all interfaces joined to a VRRP group to be in the same subnet, with unique IP addresses. Cluster configuration ~~~~~~~~~~~~~~~~~~~~~ Now it's time to create a Cluster object which will act as meta-object for fw1 and fw2: [cluster1] [OS: secunet wall, Platform: iptables] | +---o eth0: outside (ext) | +---o IP: 172.24.0.1/255.255.0.0 | +---o Failover group0 (vrrp) | +---o eth1: inside (mgmt) | +---o IP: 192.168.1.1/255.255.255.0 | +---o Failover group1 (vrrp) | +---o State synchronization group (conntrack) Use the 'Manage Members' button to add firewall interfaces to the failover and state synchronization groups of the cluster. Additionally you need to specify which firewall interface is to act as master of the group. The firewall interfaces added to the state synchronization group will be used to keep the state information of the cluster members in sync. Typically the internal management interfaces are chosen as members of the conntrack group. For all cluster groups the IP addresses of it's firewall member interfaces have to be in the same subnet and the subnet mask must be identical to the one of the cluster interface. The following table shows the mapping of interfaces to cluster groups for our example configuration: +-----------------+--------------------+ | group | mapped interfaces | +-----------------+--------------------+ | State sync | fw1:eth1, fw2:eth1 | | Failover group0 | fw1:eth0, fw2:eth0 | | Failover group1 | fw1:eth1, fw2:eth1 | +-----------------+--------------------+ NAT/Policy/Routing Rules ~~~~~~~~~~~~~~~~~~~~~~~~ NAT, policy and routing rules are configured on the cluster meta-object. Rules are specified in the usual manner. Use the cluster object or it's interfaces as rule elements as you would for a regular firewall. Compilation/Installation/Export ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's possible to compile and install firewalls which are part of a cluster by selecting the cluster meta-object and the corresponding action (Compile/Install). If you perform such an action on the cluster meta-object, all member firewalls will be selected automatically. Thus the cluster object provides a convenient way to perform actions on all cluster member firewalls. NOTE: If you compile/install a firewall which is part of a cluster by using the compile/install action of the firewall directly, the cluster parts will be omitted from the generated script. Cluster template ~~~~~~~~~~~~~~~~ This Add-On includes Cluster templates which can be used as starting point for complex cluster configurations. Enable the 'Use preconfigured template cluster object' checkbox when creating a new cluster object to use these templates. Example ------- The scenario described in this README can be found as example Firewall Builder file here [3]. For more examples on how to configure different cluster scenarios see the Firewall Builder Cookbook. Things to consider ------------------ * Host OS and platform of firewall members must match OS and platform of the cluster. * Cluster member firewalls must have at least one physical interface attached. * All IP addresses of interfaces added to a cluster group must be in the same subnet. * All addresses of a cluster group must be unique. * Cluster interface names must be unique per cluster. References ---------- [1] - http://conntrack-tools.netfilter.org/ [2] - RFC3768 - Virtual Router Redundancy Protocol (VRRP) [3] - doc/cluster_examples.fwb fwbuilder-5.1.0.3599/doc/README.pix_routing0000644000175000017500000000157611733011756021002 0ustar sylvestresylvestre Code for the static routing configutation for PIX has been contributed to the poroject by Steven Mestdagh under the terms of MIT license. From: Steven Mestdagh To: Vadim Kurland ??? Subject: Re: fwbuilder: routing for pix compiler It supports compiling rules to add static routes, i.e. if the routing table contains entries as: destination, gateway, interface, metric then these are written as: route The default metric on PIX is 1, so the GUI default value of 0 becomes 1 in the compiled rules. Below is an example of a typically generated rule: route outside 10.0.1.0 255.255.255.0 172.17.0.1 1 It does not support compiling any rules for routing protocols like OSPF, BGP, etc. Configuration of routing protocols should just be added to the prolog or epilog. fwbuilder-5.1.0.3599/doc/README_animated_tutorial0000644000175000017500000001741411733011756022217 0ustar sylvestresylvestreааНаИаМаАб†аИб аДаИаАаЛаОаГаА баОбб‚аОаИб‚ аИаЗ б‚аАаКаИб… аКаЛаАббаОаВ: TutorialDialog TutorialAnimator TutorialHelper MouseBlocker аšаАаЖаДб‹аЙ аИаЗ аНаИб… аПб€аЕаДбб‚аАаВаЛаЕаН .cpp аИ .h б„аАаЙаЛаОаМ, аА аК TutorialDialog аЕбб‚бŒ аЕб‰аЕ .ui б„аАаЙаЛ б аИаНб‚аЕб€б„аЕаЙбаОаМ. аЇб‚аО аИ аКаАаК аДаЕаЛаАаЕб‚ аКаАаЖаДб‹аЙ аКаЛаАбб: TutorialDialog а­б‚аО баАаМ аИаНб‚аЕб€б„аЕаЙб, аВ аКаОб‚аОб€аОаМ аДаЕаМаОаНбб‚б€аИб€бƒаЕб‚бб html б„аАаЙаЛ б аИаНбб‚б€бƒаКб†аИбаМаИ. аžаН б‚аАаКаЖаЕ баОаДаЕб€аЖаИб‚ баЛаАаЙаДаЕб€ аДаЛб б€аЕаГбƒаЛаИб€аОаВаКаИ баКаОб€аОбб‚аИ аДаЕаМаОаНбб‚б€аАб†аИаИ аИ аКаНаОаПаКбƒ Demonstrate, аНаАаЖаАб‚аИаЕ аНаА аКаОб‚аОб€бƒбŽ аЗаАаПбƒбаКаАаЕб‚ аАаНаИаМаАб†аИбŽ. аЁаОаДаЕб€аЖаИаМаОаЕ аИаНбб‚б€бƒаКб†аИаЙ аЗаАб€бƒаЖаАаЕб‚бб аИаЗ б„аАаЙаЛаА :/Tutorial/html/pageN.html б€аЕббƒб€баОаВ аПб€аОаГб€аАаМаМб‹. аšаНаОаПаКаИ next аИ previous аАаКб‚аИаВаНб‹ аВ аЗаАаВаИбаИаМаОбб‚аИ аОб‚ аНаАаЛаИб‡аИб б„аАаЙаЛаА аДаЛб баЛаЕаДбƒбŽб‰аЕаЙ/аПб€аОбˆаЛаОаЙ бб‚б€аАаНаИб†б‹. аЁаКаОб€аОбб‚бŒ б€аЕаГбƒаЛаИб€бƒаЕб‚бб аОб‚ 20 аДаО 70. а­б‚аО аБаАаЗаОаВаОаЕ аИ аМаИаНаИаМаАаЛбŒаНаОаЕ аЗаНаАб‡аЕаНаИаЕ баКаОб€аОбб‚аИ аВ аМаИаЛаИбаЕаКбƒаНаДаАб…, аБб‹бб‚б€аЕаЕ аКаОб‚аОб€аОаГаО аНаЕ аБбƒаДаЕб‚ аПб€аОаИбб…аОаДаИб‚бŒ аНаИаОаДаНаО аДаЕаЙбб‚аВаИб‚аЕ аАаНаИаМаАб†аИаИ. ааАаПб€аИаМаЕб€, баИаМбƒаЛбб†аИб аВаВаОаДаА б аКаЛаАаВаИаАб‚бƒб€б‹ аБбƒаДаЕб‚ аПб€аОаИбб…аОаДаИб‚бŒ б аПаАбƒаЗаОаЙ аВ бб‚аО аЗаНаАб‡аЕаНаИаЕ аМаЕаЖаДбƒ аНаАаЖаАб‚аИбаМаИ аНаА аКаНаОаПаКаИ. аŸаО аНаАаЖаАб‚аИбŽ аКаНаОаПаКаИ Demonstrate бб‡аИб‚б‹аВаАаЕб‚бб б„аАаЙаЛ :/Tutorial/commands/pageN.txt аИаЗ б€аЕббƒб€баОаВ аПб€аОаГб€аАаМаМб‹, аВ аКаОб‚аОб€аОаМ аДаОаЛаЖаНб‹ аНаАб…аОаДаИб‚бŒбб аИаНбб‚б€бƒаКб†аИаИ аПаО аАаНаИаМаАб†аИаИ аДаЕаЙбб‚аВаИаЙ аОаПаИбаАаНб‹б… аВ html б„аАаЙаЛаЕ, аКаОб‚аОб€б‹аЙ аОб‚аОаБб€аАаЖаАаЕб‚бб аВ аДаАаНаНб‹аЙ аМаОаМаЕаНб‚. а”аЛб аАаНаИаМаАб†аИаИ баОаЗаДаАаЕб‚бб аИаНбб‚аАаНб аКаЛаАбб TutorialAnimator б аАб€аГбƒаМаЕаНб‚аАаМаИ: ббб‹аЛаКаОаЙ аНаА TutorialDialog аИ б‚аЕаКбб‚аОаМ б„аАаЙаЛаА аКаОаМаМаАаНаД. а”аАаЛаЕаЕ аЗаАаПбƒбаКаАаЕб‚ аЕаГаО, аПаОбаЛаЕ б‡аЕаГаО бƒаПб€аАаВаЛаЕаНаИаЕ аПаЕб€аЕаДаАаЕб‚бб бб‚аОаМбƒ аКаЛаАбббƒ. TutorialAnimator аЏаВаЛбаЕб‚бб аНаАбаЛаЕаДаНаИаКаОаМ QThread, б‡б‚аОаБб‹ аНаЕ аБаЛаОаКаИб€аОаВаАб‚бŒбб аПб€аИ аОб‚аКб€б‹б‚аИаИ аМаОаДаАаЛбŒаНб‹б… аДаИаАаЛаОаГаОаВ аИ аМаЕаНбŽ. аŸб€аИ аИаНаИб†аИаАаЛаИаЗаАб†аИаИ аПаЕб€аВб‹аМ аДаЕаЛаОаМ аПб€бб‡аЕб‚ TutorialDialog аИ б€аАаЗаБаИаВаАаЕб‚ аПаОаЛбƒб‡аЕаНб‹аЙ б‚аЕаКбб‚ б„аАаЙаЛаА аКаОаМаАаНаД аНаА бб‚б€аОаКаИ, аКаАаЖаДаАб аИаЗ аКаОб‚аОб€б‹б… баВаЛбаЕб‚бб аОб‚аДаЕаЛбŒаНаОаЙ аКаОаМаАаНаДаОаЙ. аЁаОаЗаДаАаЕб‚ аИаНбб‚аАаНб аКаЛаАббаА TutorialHelper аВ GUI аПаОб‚аОаКаЕ, б‡аЕб€аЕаЗ аКаОб‚аОб€б‹аЙ аБбƒаДаЕб‚ аПаОаЗаЖаЕ аМаАаНаИаПбƒаЛаИб€аОаВаАб‚бŒ аИаНб‚аЕб€б„аЕаЙбаОаМ. аŸб€аИ аЗаАаПбƒбаКаЕ аБаЛаОаКаИб€бƒаЕб‚ аВаВаОаД аИ аДаВаИаЖаЕаНаИб аМб‹бˆаКаИ аПб€аИ аПаОаМаОб‰аИ аМаЕб‚аОаДаОаВ blockInput аИ blockMouse аИаЗ аКаЛаАббаА TutorialHelper. аŸаОбаЛаЕ б‡аЕаГаО аНаАб‡аИаНаАаЕб‚ аПаОбаЛаЕаДаОаВаАб‚аЕаЛбŒаНаО аВб‹аПаОаЛаНбб‚бŒ аКаОаМаМаАаНаДб‹ аПаОаЛбƒб‡аЕаНб‹аЕ аПб€аИ аИаНаИб†аИаАаЛаИаЗаАб†аИаИ. а’ аДаАаНаНб‹аЙ аМаОаМаЕаНб‚ аПаОаДаДаЕб€аЖаИаВаАбŽб‚бб баЛаЕаДбƒбŽб‰аИаЕ аКаОаМаМаАаНаДб‹: moveMouse X Y moveMouse objectName1 [objectName2 [... objectNameN]] clickWidget objectName1 [objectName2 [... objectNameN]] typeWidget objectName1 [objectName2 [... objectNameN]] text hoverMenuItem menuName itemName|itemIndex clickMenuItem menuName itemName|itemIndex selectComboItem objectName1 [objectName2 [... objectNameN]] itemIndex selectListItem objectName1 [objectName2 [... objectNameN]] itemIndex selectTab objectName1 [objectName2 [... objectNameN]] itemIndex wait SECONDS moveMouse - аПаЕб€аЕаМаЕбб‚аИб‚бŒ бƒаКаАаЗаАб‚аЕаЛбŒ аМб‹бˆаИ аВ бƒаКаАаЗаАаНбƒбŽ б‚аОб‡аКбƒ аИаЛаИ аВ б†аЕаНб‚б€ аВаИаДаЖаЕб‚аА. clickWidget - аПаЕб€аЕаМаЕбб‚аИб‚бŒ бƒаКаАаЗаАб‚аЕаЛбŒ аМб‹бˆаИ аВ б†аЕаНб‚б€ аВаИаДаЖаЕб‚аА аИ аКаЛаИаКаНбƒб‚бŒ. typeWidget - аНаАаПаЕб‡аАб‚аАб‚бŒ б‚аЕаКбб‚ аНаА аКаЛаАаВаИаАб‚бƒб€аЕ аКаОаГаДаА бƒаКаАаЗаАаНб‹аЙ аОаБбŒаЕаКб‚ аВ б„аОаКбƒбаЕ. hoveMenuItem - аПаЕб€аЕаМаЕбб‚аИб‚бŒ бƒаКаАаЗаАб‚аЕаЛбŒ аМб‹бˆаИ аНаА аПбƒаНаКб‚ аМаЕаНбŽ. clickMenuItem - аКаЛаИаКаНбƒб‚бŒ аПбƒаНаКб‚ аМаЕаНбŽ аМб‹бˆбŒбŽ. selectComboItem - аОб‚аКб€б‹б‚бŒ combo box аИ аВб‹аБб€аАб‚бŒ аВ аНаЕаМ баЛаЕаМаЕаНб‚. selectListItem - аВб‹аБб€аАб‚бŒ баЛаЕаМаЕаНб‚ аВ баПаИбаКаЕ аПб€аИ аПаОаМаОб‰аИ аМб‹бˆаИ. selectTab - аВб‹аБб€аАб‚бŒ аВаКаЛаАаДаКбƒ QTabWidget аПб€аИ аПаОаМаОб‰аИ аМб‹бˆаИ wait - аОаЖаИаДаАб‚бŒ бƒаКаАаЗаАаНаОаЕ аКаОаЛ-аВаО баЕаКбƒаНаД. а”аЛб аКаАаЖаДаОаЙ аИаЗ аНаИб… аЕбб‚бŒ аОб‚аДаЕаЛбŒаНб‹аЙ аМаЕб‚аОаД, аКаОб‚аОб€б‹аЙ аЕаЕ аОаБб€аАаБаАб‚б‹аВаАаЕб‚. а’баЕ аМаАаНаИаПбƒаЛбб†аИаИ б аИаНб‚аЕб€б„аЕаЙбаОаМ аПб€аОаИбб…аОаДбб‚ б‡аЕб€аЕаЗ аКаЛаАбб TutorialHelper, аКаОб‚аОб€б‹аЙ аБб‹аЛ баОаЗаДаАаН б€аАаНбŒбˆаЕ аИ аВб‹аПаОаЛаНбаЕб‚бб аВ GUI аПаОб‚аОаКаЕ. ааО б‚аАаК аКаАаК аИаЗ б‚б€аЕаДаА, аВ аКаОб‚аОб€аОаМ TutorialAnimator, аВб‹аЗаОаВ аМаЕб‚аОаДаА TutorialHelper аПб€аИаВаЕаДаЕб‚ аК аЕаГаО аВб‹аПаОаЛаНаЕаНаИбŽ аНаЕ аВ GUI-аПаОб‚аОаКаЕ, аДаЛб аВб‹аЗаОаВаА бб‚аИб… аМаЕб‚аОаДаОаВ аИбаПаОаЛбŒаЗбƒаЕб‚бб QMetaObject::invokeMethod б аАб€аГбƒаМаЕаНб‚аОаМ Qt::BlockedQueuedConnection. а­б‚аО аПаОаЗаВаОаЛбаЕб‚ аВб‹аПаОаЛаНаИб‚бŒ аМаЕб‚аОаД аКаОаГаДаА аВб‹аПаОаЛаНаЕаНаИаЕ аПб€аОаГб€аАаМаМб‹ аВаЕб€аНаЕб‚бб аВ аОбаНаОаВаНаОаЙ аПаОб‚аОаК аИ аБаЛаОаКаИб€аОаВаАб‚бŒ аВб‹аПаОаЛаНаЕаНаИаЕ аПаОб‚аОаКаА TutorialAnimator аПаОаКаА аВб‹аЗаВаАаНб‹аЙ аМаЕб‚аОаД аНаЕ аВб‹аПаОаЛаНаИб‚бб. а­б‚аОб‚ аКаЛаАбб б‚аАаКаЖаЕ баОаДаЕб€аЖаИб‚ б‚аАаКаИаЕ аПаОаЛаЕаЗаНб‹аЕ аМаЕб‚аОаДб‹ аКаАаК findChild, findWidget аИ getWidget, аКаОб‚аОб€б‹аЙ аНаАаВаЕб€аНбаКаА аПб€аИаГаОаДбб‚бб б‚аАаКаЖаЕ аДаЛб аНаАаПаИбаАаНаИб unit-б‚аЕбб‚аОаВ. аžаНаИ аПаОаЗаВаОаЛббŽб‚ б€аЕаКбƒб€баИаВаНаО аИбаКаАб‚бŒ аОаБбŒаЕаКб‚б‹ аПаО аДаЕб€аЕаВбƒ аОаБбŒаЕаКб‚аОаВ аПб€аОаГб€аАаМаМб‹. а”аЛб бб‚аОаГаО аИбаПаОаЛбŒаЗбƒаЕб‚бб аПаОаИбаК аВ бˆаИб€аИаНбƒ. а’ аОб‚аЛаИб‡аИаИ аОб‚ бб‚аАаНаДаАб€б‚аНаОаЙ б„бƒаНаКб†аИаИ findChild, бб‚аИ аМаЕб‚аОаДб‹ бƒаМаЕбŽб‚ аИбаКаАб‚бŒ аНаЕ аПб€аОбб‚аО аПаЕб€аВб‹аЙ аОаБбŒаЕаКб‚ б бƒаКаАаЗаАаНб‹аМ аИаМаЕаНаЕаМ, аА аПаОбаЛаЕаДаНаИаЙ аОаБбŒаЕаКб‚ аВ б†аЕаПаОб‡аКаЕ аНаАбаЛаЕаДаОаВаАаНаИб. ааАаПб€аИаМаЕб€, аКаОаМаМаАаНаДаА clickWidget MainWindow SomeWidget TargetButton аОаЗаНаАб‡аАаЕб‚: аНаАаЙб‚аИ аВаИаДаЖаЕб‚ MainWindow, аВ аНаЕаМ SomeWidget, аВ аНаЕаМ TargetButton аИ аКаЛаИаКаНбƒб‚бŒ аЕаЕ. аЂаАаКаЖаЕ аПаОаДаДаЕб€аЖаИаВаАаЕб‚бб аПаОаИбаК аПаО аИаМаЕаНаИ аКаЛаАббаА: w#className. ааАаПб€аИаМаЕб€6 moveMouse w#FWWindow objectTreeView - аНаАаЙб‚аИ аОаБбŒаЕаКб‚ аКаЛаАббаА FWWindow, аВ аКаОб‚аОб€аОаМ аНаАаЙб‚аИ objectTreeView аИ аПаЕб€аЕаМаЕбб‚аИб‚бŒ аКбƒб€баОб€ аМб‹бˆаИ аВ аЕаГаО б†аЕаНб‚б€. TutorialHelper а­б‚аОб‚ аКаЛаАбб баОаДаЕб€аЖаИб‚ аВбаЕ аМаЕб‚аОаДб‹ аПаО аМаАаНаИаПбƒаЛаИб€аОаВаАаНаИбŽ аИаНб‚аЕб€б„аЕаЙбаОаМ. а•аГаО аМаЕб‚аОаДб‹ аВб‹аЗб‹аВаАбŽб‚бб аИаЗ TutorialAnimator, аНаО аДаОаЛаЖаНб‹ аВб‹аПаОаЛаНбб‚бŒбб аВ GUI аПаОб‚аОаКаЕ. аžаН б‚аАаКаЖаЕ баОаДаЕб€аЖаИб‚ аМаЕб‚аОаДб‹ blockInput аДаЛб аБаЛаОаКаИб€аОаВаКаИ аВаВаОаДаА аИ blockMouse аДаЛб аБаЛаОаКаИб€аОаВаКаИ аДаВаИаЖаЕаНаИб аМб‹бˆаИ, аКаОб‚аОб€б‹аЕ аМаОаГбƒб‚ аВб‹аПаОаЛаНбб‚бŒбб б аЛбŽаБаОаГаО аПаОб‚аОаКаА. MouseBlocker ааАбаЛаЕаДаНаИаК QThread, аКаОб‚аОб€б‹аЙ аКаОаГаДаА аЗаАаПбƒб‰аЕаН аКаАаЖаДб‹аЕ 10 аМаИаЛаИбаЕаКбƒаНаД аПаЕб€аЕаМаЕб‰аАаЕб‚ бƒаКаАаЗаАб‚аЕаЛбŒ аМб‹бˆаИ аВ аЕаГаО б‚аЕаКбƒб‰аЕаЕ аПаОаЛаОаЖаЕаНаИаЕ. а­б‚аО аПаОаЛаНаОбб‚бŒбŽ аБаЛаОаКаИб€бƒаЕб‚ аПаЕб€аЕаМаЕб‰аЕаНаИаЕ аМб‹бˆаИ аПаОаЛбŒаЗаОаВаАб‚аЕаЛаЕаМ. а˜баПаОаЛбŒаЗбƒаЕб‚бб б‡аЕб€аЕаЗ TutorialHelper::blockMouse.fwbuilder-5.1.0.3599/doc/cluster_examples.fwb0000644000175000017500000025677711733011756021652 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/doc/fwbedit.10000644000175000017500000002536711733011756017266 0ustar sylvestresylvestre.TH fwbedit 1 "" FWB "Firewall Builder" .SH NAME fwbedit \- General purpose object tree editing tool .SH SYNOPSIS .B fwbedit .RB command .RB [options] .SH "DESCRIPTION" .B fwbedit is a general purpose object tree editing tool for Firewall Builder (see fwbuilder(1)). This tool can be used in the shell scripts written for batch-processing of the Firewall Builder data files. Fwbedit can perform the following operations on the objects and the tree: create new object, delete existing object, modify attributes of an object, add a reference to the given object to a group, remove reference to an object from a group, upgrade data file and check object tree in the file and repair it if necessary. Both object and a group can be defined by their ID or by their name and a full path in the tree (see section .B EXAMPLES below). .SH COMMANDS AND OPTIONS: .B new -f file.fwb -t objtype -n name -p parent [-c comment] [-a attrs] Creates new object. -f file.fwb data file -t objtype create new object of this type -p parent create new object as a child of this object. This parameter is mandatory. If you are adding an address to an interface, corresponding interface onkect must be specified as the parent. Similarly if you need to add an interface to a host or a firewall, corresponding host or firewall object is the parent. If you are adding an object to one of the standard folders, the parent is the library you want to add the object to or correct full path to the folder in the tree. -n name the name of the new object -c txt specify comment for the new object -a attribute1[,attribute2...] : specify attributes that define parameters of the new object (see below) .B delete -f file.fwb -o object Deletes object specified by its full path in the tree or object ID. -f file.fwb data file -o object object to be deleted, full path or ID .B modify -f file.fwb -o object -c comment [-a attrs] Modifies object specified by its full path in the tree or object ID. Object can not be renamed using this operation. -f file.fwb data file -o object object to be deleted, full path or ID -c txt specify comment for the new object -a attribute1[,attribute2...] : specify attributes that define parameters of the new object (see below) .B list -f file.fwb -o object [-r|-c] [-d|-Fformat] Prints name and ID of an object. -f file.fwb data file -o object object to print, full path or ID -r print specified object and all objects under it in the tree -c print only children objects of the given object but do not print the object itself. -d print full dump of all object's attributes including internal debugging information if available, this can be very verbose. -Fformat_string Program recognizes macros in the format string and replaces them with values of corresponding object's attributes. Macro is the name of the attribute surrounded with '%', such as '%name%' or '%address%'. Here is the list of some attribute names: "id", "name", "path", "comment", "type", "address", "netmask", "dnsname". TCP and UDP service objects provide attributes "src_range_start", "src_range_end", "dst_range_start", "dst_range_end" for the source and destination port ranges. ICMP and ICMP6 service objects have attributes "icmp_type" and "icmp_code". .B add -f file.fwb -g group -o object Adds object specified by path or ID to a group, also specified by its path or ID. -f file.fwb data file -g group group the object should be added to, full path or ID -o object object to be deleted, full path or ID .B remove -f file.fwb -g group -o object Removes object from a group. -f file.fwb data file -g group group the object should be removed from, full path or ID -o object object to be deleted, full path or ID .B upgrade -f file.fwb Upgrades data file to the latest data format version. -f file.fwb data file .B checktree -f file.fwb Checks consistency and correctness of the object tree in the given data file and repairs it if necessary. -f file.fwb data file .B merge -f file1.fwb -i file2.fwb Objects from the file2.fwb are merged with objects in file1 and combined object tree saved in file1.fwb -f file.fwb data file #1 -i file.fwb data file #2 .B import -f file1.fwb -i firewall_config.txt -o path_to_firewall_object [-d] Firewall configuration from file firewall_config.txt is parsed and imported into data file file1.fwb. The program creates new firewall object located in the library and with the name defined by its path path_to_firewall_object. -f file.fwb data file #1 -i config.txt firewall configuration file -o object_path full path to the firewall object that will be created. This has to be full path, beginning with the library name, such as "/User/Firewalls/my_new_firewall" -d avoid creating duplicate objects on import currently (as of v4.2.0) fwbuilder supports import of iptables configuration saved with iptables-save command, as well as import of Cisco router IOS configuration, Cisco PIX, ASA and FWSM firewalls saved with "show run" command. .SH ATTRIBUTES FOR THE NEW OBJECTS, BY TYPE .PP .PP -t Firewall -a platform, host OS .PP -t IPv4 -a IP address [,netmask] .PP -t IPv6 -a IPv6 address [,masklen] .PP -t DNSName -a DNS record,run time .PP -t AddressRange -a start address, end address .PP -t ObjectGroup .PP -t Network -a address,netmask .PP -t NetworkIPv6 -a ipv6_address,netmask_length .PP -t Interval -a start time,start date,start day,end time, end date, end day .PP -t Interface -a security level,address type (dynamic or unnumbered),management .PP -t Host .PP -t TCPService -a source port range start,end,destination port range start,end,UAPRSF,UAPRSF .PP -t UDPService -a source port range start,end,Destination port range start,end .PP -t ICMPService -a ICMP type,ICMP code .PP -t IPService -a protocol number,lsrr/ssrr/rr/ts/fragm/short_fragm .SH EXAMPLES .PP Print contents of the object /User/Firewalls/firewall/eth0 according to the provided format. Note that object of the type "Interface" does not have attribute that would define its address, IP address is defined by its child object of the type IPv4 or IPv6. .PP fwbedit list -f x.fwb -o /User/Firewalls/firewall/eth0 -F "type=%type% name=%name% id=%id% %comment%" .PP Print contents of the object /User/Firewalls/firewall/eth0 and all its child objects. This is the way to see addresses and netmasks. Interface object does not have attribiute "address" so the program ignores macro "%address%" when it prints interface. .PP fwbedit list -f x.fwb -o /User/Firewalls/firewall/eth0 -F "type=%type% name=%name% id=%id% %comment% %address%" -r .PP Print group object /User/Objects/Addresses .PP fwbedit list -f x.fwb -o /User/Objects/Addresses -F "type=%type% name=%name% id=%id% %comment%" .PP Print group object /User/Objects/Addresses and all address objects inside of it: .PP fwbedit list -f x.fwb -o /User/Objects/Addresses -F "type=%type% name=%name% id=%id% %comment%" -r .PP Print address objects inside group /User/Objects/Addresses but do not print the group object itself: .PP fwbedit list -f x.fwb -o /User/Objects/Addresses -F "type=%type% name=%name% id=%id% %comment%" -c .PP Print addresses and netmasks of all interfaces of all firewalls in the form of their full object tree path, followed by the type, id, address and netmask: .PP fwbedit list -f x.fwb -o /User/Firewalls -F "%path% %type% %id% %address% %netmask%" -r | grep IP .PP Print names, platform and version information for all firewall objects defined in the data file: .PP fwbedit list -f x.fwb -o /User/Firewalls -F "%name% platform: %platform% version: %version%" -c .PP Print name, source and destination port ranges for all TCP services in the folder TCP of the user-defined group User: .PP fwbedit list -f x.fwb -o /User/Services/TCP -c -F "name='%name%' est=%established% \t %src_range_start%-%src_range_end% : %dst_range_start%-%dst_range_end%" .PP Print icmp type and code for all ICMP services in the folder ICMP of the user-defined group User: .PP fwbedit list -f x.fwb -o /User/Services/ICMP -c -F "name='%name%' icmp_type=%icmp_type% icmp_code=%icmp_code%" .PP Add IPv6 address to one of the interfaces of firewall object "firewall": .PP fwbedit new -f x.fwb -p /User/Firewalls/firewall/eth3 -t IPv6 -n eth3-v6-addr -a 2001:470:1f05:590::2,64 .PP Add reference to the Host object 'A' to the group 'B': .PP fwbedit add -f x.fwb -g /User/Objects/Groups/B -o /User/Objects/Hosts/A .PP Add reference to the object with ID id3D71A1BA to the group with ID id3D151943. If objects with given IDs do not exist, fwbedit prints an error message and does not make any changes in the data file. .PP fwbedit add -f x.fwb -o id3D71A1BA -g id3D151943 .PP Add reference to the object with ID id3D71A1BA to the group 'testgroup': .PP fwbedit add -f x.fwb -o id3D71A1BA -g /User/Objects/Groups/testgroup .PP .PP The following script uses fwbedit "list" command to print IDs of all Address objects in the folder /User/Objects/Addresses , then cycles through the obtained list and uses fwbedit to add them to the group "group1". .LP fwbedit list -f x.fwb -o /User/Objects/Addresses -F "%id%" -c | \\ while read id; do \\ fwbedit add -f x.fwb -g /User/Objects/Groups/group1 -o $id; \\ done .PP Here is slightly more complex example. The following script uses fwbedit "list" command to print types and IDs of all Address objects in the folder /User/Objects/Addresses , then filters them using grep to get only IPv6 objects and finally cycles through the obtained list and uses fwbedit to add them to the group "group1". .LP fwbedit list -f x.fwb -o /User/Objects/Addresses -F "%type% %id%" -c | \\ grep IPv6 | \\ while read type id; do \\ fwbedit add -f x.fwb -g /User/Objects/Groups/group1 -o $id; \\ done .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .P fwbuilder-5.1.0.3599/doc/ChangeLog0000644000175000017500000265314711733011756017337 0ustar sylvestresylvestre2012-03-21 Vadim Kurland * running autoconf, configure as part of windows build. Merged qmake .pro and .inc files for Windows, Mac and Linux builds. Moved files needed for Windows and Mac packaging to the "packaging" directory. 2012-03-19 Vadim Kurland * version 5.1.0 * switching to GPL for Mac OS X and Windows. 2012-03-18 Vadim Kurland * CompilerDriver.cpp (CompilerDriver::populateClusterElements): fixes #2686 "automatic rules for heartbeat are not generated for vlan subinterfaces" * clusterMembersDialog.cpp (clusterMembersDialog::clusterMembersDialog): fixes #2685 "Clicking "Manage Members" in a vlan subinterface of a cluster causes crash". 2012-02-20 Vadim Kurland * configlets/linux24/routing_functions (OLD_ROUTES): fixes SF bug 3489096 "dd-wrt-jffs: all routes are deleted if there is an error". The problem affects all supported Linux-like systems. Shell code that restores old static routing table entries in case of an error with commands adding new routing entries was broken and left the machine with no routes at all. * configlets/linux24/routing_functions: using mktemp to create temporary directory. If mktemp is not available, fall back onto less secure but guaranteed to work method where I generate randomized the name of the temporary directory using process ID. * OSConfigurator_linux24_interfaces.cpp (printInterfaceConfigurationCommands): fixes #2684 "fix address deletion in configlet update_addresses". This only applies to Linux firewalls and configurations where an interface has two or more ip addresses. If user deleted one of the addresses that happens to be the "primary" address of the interface in the GUI, generated script deleted both addresses on the firewall machine instead of just one and left interface with no addresses at all. The fix is to use /proc variable /proc/sys/net/ipv4/conf/all/promote_secondaries that makes the kernel "promote" secondary address to a "primary" status when primary address is deleted. Default behavior in Linux kernel is to delete all addresses when primary address is deleted. 2012-02-13 Vadim Kurland * qmake.inc.in (QMAKE_CXXFLAGS_DEBUG): fix for SF bug #3468802. Need to define macro __STDC_FORMAT_MACROS. This still needs to be tested on all build machines. build 3594 2012-01-02 Vadim Kurland * PolicyCompiler_ipt.cpp (specialCaseAddressRangeInRE::processNext): fixed SF bug #3468358 "change in rule-compilation between 5.0.0 and 5.0.1". Rule with cluster interface in "Destination" should compile into matching ip addresses assigned to the cluster interface object and corresponding member firewall's interface object, but in v5.0.1 it only matched member interface address. This bug triggered when iptables version was set to 1.2.11 or greater. This was a regression from v5.0.0 * VERSION (FWB_MICRO_VERSION): v 5.0.2 2011-12-23 Vadim Kurland * v5.0.1 released 2011-12-07 Vadim Kurland * pix.g (nat_command_last_parameters): fixes #2678 Policy importer for PIX/ASA could not parse nat command with parameter "outside" * PIXImporterNat.cpp (PIXImporter::buildNoNATRule): fixes #2679 Policy importer for PIX/ASA could not import "nat exemption" rule (for example: "nat (inside) 0 access-list EXEMPT") * pix.g (nat_addr_match): fixes #2677 Policy importer for PIX/ASA could not parse command "nat (inside) 1 0 0" * iptAdvancedDialog.cpp (iptAdvancedDialog::iptAdvancedDialog): fixed strings that should be translated; these strings caused problems when translation was loaded at the run time. 2011-11-30 Vadim Kurland * NATCompiler_pf.cpp (NATCompiler_pf::compile): fixes #2674 NAT compiler for PF crashed when AttachedNetworks object was used in Translated Source of a NAT rule. 2011-11-28 Vadim Kurland * NATCompiler_PrintRule.cpp (_printIpSetMatch): fixed SF bug #3443609 Return of ID: 3059893": iptables "--set" option deprecated". Need to use --match-set instead of --set if iptables version is >= 1.4.4. The fix done for #3059893 was only in the policy compiler but needs to be done in both policy and nat compilers. * PolicyCompiler_PrintRule.cpp (_printDirectionAndInterface): more fixes for SF bug #3439613. Adding "-i" / "-o" clause to match parent bridge interface. This allows us to correctly match which bridge the packet comes through in configurations using wildcard bridge port interfaces. For example, when br0 and br1 have "vnet+" bridge port interface, iptables can still correctly match which bridge the packet went through using "-o br0" or "-o br1" clause. This can be useful in installations with many bridged interfaces that get created and destroyed dynamically, e.g. with virtual machines. Note that the "-i br0" / "-o br0" clause is only added when there is more than one bridge interface and bridge port name ends with a wild card symbol "+" 2011-11-21 Vadim Kurland * TableFactory.cpp (TableFactory::createTablesForRE): see #2671 Duplicate objects appear in PF table when option "preserve group and addresses table object names" is in effect. This happened if the same user-defined group was used in multiple rules or different rule element of the same rule. In this case generated PF table would have several copies of the same addresses. * TableFactory.cpp (TableFactory::createTablesForRE): see #2672 PF option "preserve group and addresses table object names" does not work right when the same object is used in several different groups. If the same object was a member of multiple groups and these groups were used in the same or different rules of the same PF firewall, compiler used all groups in all rules. This could create match for objects that were not intended to be part of some rules. This problem has been fixed. Note that configuration with a combination of ipv4 and ipv6 objects as members of the same user-defined group when group is used in mixed ipv4+ipv6 rule set still does not work right. In this case compiler generates table that exactly reflects configuration user created in the GUI (i.e. includes both ipv4 and ipv6 addresses) and then uses this table in both "inet" and "inet6" rules. * PolicyCompiler_pf.cpp (createTables): With this fix, when option "preserve group and addresses table object names" is in effect, compiler for PF will create named tables for the user-defined object group even if it contains just one object. * PolicyCompiler_PrintRule.cpp (_printDirectionAndInterface): SF bug #3439613. physdev module does not allow --physdev-out for non-bridged traffic anymore. We should add --physdev-is-bridged to make sure this matches only bridged packets. 2011-11-16 Vadim Kurland * InetAddrMask.cpp (InetAddrMask::setNetworkAndBroadcastAddress): fixed bug (no number) introduced when I was working on #2670. Setting broadcast address in the network object with netmask /31 to 255.255.255.255 broke rule shadowing algorithm. 2011-11-15 Vadim Kurland * CustomServiceDialog.cpp (loadFWObject): fixes #2669 "Cant inspect custom Service object in Standard objects library". 2011-11-10 Vadim Kurland * configlets/linux24/check_utilities: fixes #2664 Update error message when "which" command fails. Generated iptables script uses "which" to check if all utilities it uses exist on the machine. We should also check if "which" itself exists and issue meaningful error message if not. * IC_PlatformWarningPage.cpp (initializePage): fixes #2668 Remove "static routes" from the explanation text in ASA/PIX import dialog. We can not import PIX/ASA routing configuration at this time. 2011-11-08 Vadim Kurland * InetAddrMask.cpp (setNetworkAndBroadcastAddress): see #2670. Per RFC3021 network with netmask /31 has no network and direct broadcast addresses. * PolicyCompiler_ipt.cpp (specialCaseAddressRangeInRE): fixed bug in the rule processor that replaces AddressRange object that represents single address with an IPv4 object. Also eliminated code redundancy. * PolicyCompiler_ipt.cpp (splitIfDstMatchingAddressRange): fixes #2663 "Rule with "old-broadcast" object results in invalid iptables INPUT chain". Compiler was choosing chain INPUT with direction "outbound" for rules that had old broadcast address in "Source", this lead to invalid iptables configuration with chain INPUT and "-o eth0" interface match clause. * ObjectMatcher.cpp (checkComplexMatchForSingleAddress): see #2663 Special handling of the "old broadcast" address. This address (0.0.0.0) should be treated just like 255.255.255.255 when we check if an address "matches" the firewall. * RuleSetViewDelegate.cpp (sizeHint): fixes #2665 "Adding text to comment causes rule to go from 2 rows to 1 row" * ACL.cpp (ciscoACL::trimLine): fixed SF bug 3435004: "Empty lines in comment result in "Incomplete Command" in IOS". * CompilerDriver_pf_run.cpp (CompilerDriver_pf::run): fixed SF bug #3429377 "PF: IPv6 rules are not added in IPv4/IPv6 ruleset (anchor)". Compiler for PF did not inlcude rules generated for IPv6 in generated PF anchor configuration files. * CompilerDriver_pf_run.cpp (CompilerDriver_pf::run): fixed SF bug 3428992: "PF: rules order problem with IPv4 and IPv6". Compiler for PF should group ipv4 and ipv6 NAT rules together, before it generates ipv4 and ipv6 policy rules. * BaseObjectDialog.cpp (connectSignalsOfAllWidgetsToSlotChange): fixed SF bug #3433587 "Manual edit of new service Destination Port END value fails". This bug made it impossible to edit the value of the end of the port range because as soon as the value became less than the value of the beginning the range, the GUI would reset it to be equal to the value of the beginning of the range. This affected both TCP and UDP service object dialogs. * PolicyCompiler_ipfw_writers.cpp (PrintRule::_printAddr): fixed SF bug #3426843 "ipfw doesn't work for self-reference, in 5.0.0.3568 version". 2011-10-19 Vadim Kurland * PolicyCompiler_pix.cpp (AddressRangesIfTcpServiceToFW::processNext): see #2662 "Crash when compiling ASA rule with IP range". Need to split address range if it is used in "source" of a rule that controls telnet, ssh or http to the firewall itself and firewall's version is >= 8.3. Commands "ssh", "telnet" and "http" (those that control access on the corresponding protocols to the firewall itself) accept only ip address of a host or a network as their argument. They do not accept address range, named object or object group. This is so at least as of ASA 8.3. Since we expand address ranges only for versions < 8.3 and use named object for 8.3 and later, we need to make this additional check and still expand address ranges in rules that will later convert to "ssh", "telnet" or "http" command. Compiler also generates redundant object-group statement with CIDR blocks generated from the address range but does not use this group in the rule. This does not break generated configuration but the object-group is redundant since it is never used. This will be rectified in future versions. * CompilerDriver_files.cpp (CompilerDriver::getOutputFileNameInternal): fixed a bug (no number): if the file name user entered in "Output file name" field in the "advanced settings" dialog of a firewall object ended with a white space, policy installer failed with an error "No such file or directory" * build 5.0.1.3583 2011-10-02 Vadim Kurland * shell_functions: see SF bug #3416900 "Replace `command` with `which`". Generated script (Linux/iptables) used to use "command -v" to check if command line tools it needs are present on the system. This was used to find iptables, lsmod, modprobe, ifconfig, vconfig, logger and others. Some embedded Linux distributions, notably TomatoUSB, come without support for "command". Switching to "which" that is more ubuquitous and should be available pretty much everywhere. 2011-09-29 Vadim Kurland * SSHSession.cpp (startSession): enable fwbuilder to take advantage of GSSAPIAuthentication with openssh using suggestion by Matthias Witte witte@netzquadrat.de * PolicyCompiler_ipt.cpp (compile): fixes SF bug #3414382 "Segfault in fwb_ipt dealing with empty groups". Compiler for iptables used to crash when an empty group was used in the "Interface" column of a policy rule. 2011-09-24 Vadim Kurland * NamedObjectsAndGroupsSupport.cpp (CreateObjectGroups::processNext): fixes #2660 "compiler for IOSACL crashed when address range appears in a rule AND object-group option is turned ON" 2011-09-19 Vadim Kurland * PolicyCompiler_cisco_acls.cpp (setInterfaceAndDirectionBySrc): see #2656 "Generated Cisco ASA access-list has duplicate entry". * snmp.cpp (SNMPCrawler::run_impl): fixes #2658 "snmp network discovery creates duplicate address and network objects" * ND_ProgressPage.h (class ND_ProgressPage): see #2657 snmp network discovery crashed if option "Confine scan to network" was used. * iosInterfaces.cpp (iosInterfaces::basicValidateInterfaceName): see #2655 Interface names are not allowed to have dash "-" even with interface verification off. We should allow "-" in the interface name for Cisco IOS 2011-09-04 Vadim Kurland * IPTImporter.cpp (IPTImporter::isSupportedTable): see #2653 Importer for iptables checks that netfilter table used in the original iptables config is one of the tables we support. Currently only "filter", "mangle" and "nat" are supported. Also see #2651, #2652 * FWObjectDatabase_tree_ops.cpp (_recursively_copy_subtree): see #2654 fixes GUI crash that occured if user copied a rule from file A to file B, then closed file B, opened file C and tried to copy the same rule from A to C' 2011-08-30 Vadim Kurland * fixes SF bug 3247094 "Nomenclature of IP address edit dialog". Network ipv6 dialog says "Prefix length". * linux24advanceddialog_q.ui: fixes SF bug 3302121 "cosmetic mis-format in fwb Linux paths dialog" * DNSNameDialog.cpp (applyChanges): fixes SF bug 3388055 Adding a "DNS Name" with a trailing space causes failure. 2011-08-25 Vadim Kurland * see #2646 and SF bug 3395658: Added few ipv4 and ipv6 network objects to the Standard objects library: TEST-NET-2, TEST-NET-3 (RFC 5735, RFC 5737), translated-ipv4, mapped-ipv4, Teredo, unique-local and few others. * ObjectManipulator.cpp (openLibForObject): fixes #2648 "right mouse click on firewall object in "Deleted objects" library causes GUI crash" * PolicyCompiler_ipt.cpp (processNext): fixes #2650 "rules with address range that includes firewall address in Src are placed in OUTPUT chain even though addresses that do not match the firewall should go in FORWARD" 2011-08-14 Vadim Kurland * InetAddr.cpp (InetAddr::isValidV4Netmask): function InetAddr::isValidV4Netmask() checks that netmask represented by the object consists of a sequence of "1" bits, followed by the sequence of "0" bits and therefore does not have zeroes in the middle. * NetworkDialog.cpp (NetworkDialog::validate): added check to make sure user does not enter netmask with zeroes in the middle for the IPv4 network object. Netmasks like that are not supported by fwbuilder. * RuleSetView.cpp (RuleSetView::addColumnRelatedMenu): fixes #2643 "GUI crashes when user cuts a rule, then right-mouse click in any rule element of another" 2011-08-11 Vadim Kurland * freebsd/carp_interface: see #2638 "When CARP password is empty the advskew value is not read". Should skip "pass " parameter of the ifconfig command that creates carp interface if user did not set up any password. * OSConfigurator_linux24_interfaces.cpp (validateInterfaces): see #2639 "support for vlan subinterfaces of bridge interfaces (e.g. br0.5)". Currently fwbuilder can not generate script to configure vlan subinterfaces of bridge interfaces, however if user did not request this configuration script to be generated, compiler should not abort when it encounters this combination. * InterfaceEditorWidget.cpp (validateAddress): fixes #2641 "newFirewall dialog does not accept ipv6 addresses with long prefixes". The dialog did not allow ipv6 addresses of inetrfaces with netmask > 64 bit. * newFirewallDialog.cpp (cleanup): fixes #2642 "GUI crashes if user cancels newFirewall dialog". * RuleOptionsDialog.cpp (fillInterfaces): the drop-down list of interfaces for the "route-through" rule option for PF and iptables should include not only cluster interfaces, but also interfaces of all members. This way, we can make compiler generate configuration "pass in quick on em0 route-to { ( em0 10.1.1.2 ) } ... " for a rule of a PF cluster. Here "em0" is an interface of a member, not the cluster. 2011-08-08 Vadim Kurland * configlets/freebsd/rc_conf_carp_interface: see #2636 "carp : Incorrect output in rc.conf.local format". Should use create_args_carp0 instead of ifconfig_carp0 to set up CARP interface vhid, pass and adskew parameters. 2011-08-05 Vadim Kurland * RuleElement.cpp (RuleElementItf::validateChild): see #2635 Object type AttachedNetworks is not allowed in the "interface" rule element. 2011-08-03 Vadim Kurland * newFirewallDialog_from_template.cpp (replaceReferencesToObject): see #2628 fixed crash that happened if user create new firewall object from a template and changed one of the ip addresses, while another firewall object created from the same template already existed in the tree. 2011-08-02 Vadim Kurland * instDialog_ui_ops.cpp (instDialog::getInstOptions): moved "batch install" button from the main installer wizard to the dialog where user enters their password. Now user can start in a non-batch install mode but continue in batch install mode at any time if all their firewalls authenticate with the same user name and password. 2011-08-01 Vadim Kurland * pix.g (static_command_common_last_parameters): changed token name from "ESP" to "ESP_WORD" to avoid conflict with macro "ESP" that happened during build on OpenSolaris * unit_tests/ObjectMatcherTest/ObjectMatcherTest.cpp (matchTest): fixed unit test (ObjectMatcher matches ipv6 only when internal flag is set accordingly) * VERSION: set version to 5.0.1 2011-07-28 vadim * version 5.0.0. release 2011-07-22 vadim * ObjectManipulator.h (QWidget): see #2622 "Remove Back and Forward buttons". We have decided behavior of the GUI was too complicated since user can both act on objects directly and navigate backwards and forwards to the objects found in their browsing history. Navigation using browsing history was broken when quick filter was in use, too. All in all, it feels the value of "back" and "forward" buttons was relatively low. 2011-07-21 vadim * XMLTools.cpp (convert): see #2577 Updated error message that appears when user tries to open .fwb file created by the future version of fwbuilder. * TextFileEditor.cpp (save): fixes #2567 "If file doesn't exist when clicking 'edit file', then you have to hit save button twice". The bug affected "edit file" function in the Address Table object dialog. * NATCompiler_pf_writers.cpp (_printAddr): fixes #2590 "PF: NAT compiler fails when run-time address table object is used in a rule" * RoutingCompiler.cpp (processNext): fixes #2565 "Run-time dns name or address table in routing policy -> crash". Compiler for PF crashed if user placed run-time DNSName object in "destination" of a routing rule. * RuleSetModel.cpp (initRule): see #2515 Expanded set of options the user can change to pre-set parameters in the new policy rules they create. Now user can set default values for action ("Deny" or "Accept"), direction, the "stateless" flag and logging. * FindObjectWidget.cpp (matchAttr): see #2516 "Enhance Find to include searching for IP addresses in ranges". Function "find" now finds ip addresses inside address ranges. 2011-07-20 vadim * FWBTree.cpp (init_statics): see #2619 "Attempting to copy-and-paste a tag service results in an error". Pasting of a TagService object to the "Tag Services" group did not work. * RuleSetView.cpp (itemDoubleClicked): fixes #2566, #2618 Fix for the regression introduced when I worked on #2566 "Double-clicking on rule when program first starts results in empty editor pane". Double click on the rule number should not do anything, but double click on rule options, comment and other fields should open the editor. Change done for #2566 broke this. 2011-07-20 Vadim Kurland * ObjectMatcher.cpp (dispatch): removed optimization in dispatch(IPv4*,void*) and dispatch(IPv6*, void*) that assumed address matches a host or a firewall if it is located somewhere in the subtree rooted at the firewall object. This assumption fails if the address is a child of a Variable that belongs to the Variables folder of this firewall. Instead, always calling checkComplexMatchForSingleAddress() which uses Interface::findAllInterfaces() and therefore only matches against addresses that belong to the interfaces. See #2598 * PolicyCompiler_ipt.cpp (processSingleObjectNegationInRE): consolidated rule processors that deal with single object negation into one class. Also, taking into account Variables. * Interface.cpp (findAllInterfaces): added more efficient way to get a list of all interfaces of a firewall. This function assumes interfaces are direct children of the firewall and each interface may have a subinterface (one level deep). This function is faster because it does not scan whole tree rooted at the firewall object which might be large if firewall has lots of rules. 2011-07-19 vadim * NATCompiler_ipt.cpp (processNext): fixed SF bug 3371301 "Error compiling with VLAN and masquerade". Iptables NAT rules with vlan interface configured as "dynamic" and no ip address in Translated Source caused compiler crash. 2011-07-18 theron * Fixed #2511: make sure auto-scroll of items in ObjectTreeView works, otherwise it's impossible to move an item into a user-defined folder if there are lots of intervening items. 2011-07-13 theron * Fixed #2505: make sure that objects that we show are members of a dynamic group are actually objects. Previously we were showing stuff like FirewallOptions objects. To make sure that dynamic group expansion is done the same way in the UI and for the compiler, also fixed #2502 (consolidate logic for DynamicGroup). * Modified checks (added for #2514) for empty path in an Address Table object. It's valid to have an empty path for the situation where a user wants to use an ipset in place of the table. However, if there is a path and it comes out blank in getSourceNameAsPath() then that means %DATADIR% expansion failed. * Fixed #2440. Now when a firewall is matched in the quick filter, all child elements (e.g. policies, interfaces) will be displayed as well. * Fixed #2523: save the expanded/collapsed state of the tree when the user starts typing something into the quick filter. When the quick filter is cleared, re-expand any items that started off expanded (so we get the union of expanded items displayed by quick filter plus what the user started with expanded). * Tried to fix #2507: set a size for the "type" column in the dynamic group dialog (on some platforms it comes out so narrow you can't see it, despite it having ResizeToContents). 2011-07-11 theron * Implemented #2514, support for address table alternate paths. There's a "data directory" setting under user preferences. If the user selects an address table file using "choose file" and that file is "inside" the data directory, then the appropriate part of the path is replaced with %DATADIR% as a variable. If the address table is marked "run-time" then the path is taken from the firewall data directory option. 2011-07-11 Vadim Kurland * TableFactory.cpp (createTablesForRE): see #2513 "Group and Address Table name persistence in generated config". Compiler for PF can now preserve names of object groups, dynamic groups, compile-time AddressTable and compile-time DNSName objects in the generated pf.conf file. This is optional and is controlled by a checkbox in the firewall settings dialog. 2011-07-09 vadim * pf.g (rule_extended): see #2551 Importer should parse PF rules that use "route-to", "reply-to" and "dup-to" options in both pre-4.7 and 4.7 formats. In PF 4.7 these parameters moved to the end of the rule and are now part of the "filteropts" block of parameters. * PFImporter.cpp (pushPolicyRule): see #2551 Importer should correctly import "pool type" parameter that follows source routing rule options "route-to", "reply-to" and "dup-to". Also, since currently fwbuilder does not support source routing rules with multiple different interface-gateway pairs (only one interface in combination with one or multiple gateway addresses are supported), importer displays warning and marks rules as "broken" when it encounters this configuration. * ObjectManipulator_slots.cpp (makeSubinterface): see #2561 operation of making an interface a subinterface should be performed using undo/redo command. Also, this should take care of inconvenient scrolling of the object tree after this operation. * ObjectManipulator.cpp (addSubinterfaceSubmenu): see #2562 "Crash when making an interface that has subinterfaces a subinterface of another interfrace". If an interface has subinterfaces, it should not be allowed to become subinterface of another interface. 2011-07-08 vadim * ObjectManipulator_slots.cpp (makeSubinterface): see #2561 "Add context menu to move an interface to be a child of another interface". New context menu (submenu) allows user to move an interface in the tree to make it a subinterface of another interface. * parsers/pf.g: see #2556 "PF import: impor of rules referring to undefined macros". Importer now records all parser errors in the comments of rules where they occurred and marks these rules "broken" by coloring them red. Behavior on import of pf.conf file with undefined macros is inconsistent at this time: undefined macro that appears in a rule where parser expects ip addresses is converted to a run-time DNSName object with name "$macro", a warning is displayed and rule is marked as "broken". Undefined macro in the position of interface name, port name or other parameters triggers generic parser error that looks like "Parser error: line 26:19: unexpected token: $ext". The rule is marked as "broken" and the error is recorded in the comment. * PFImporterRun.cpp (substituteMacros): see #2556 "PF import: impor of rules referring to undefined macros". Importer displays warnings for all undefined macros found in the file, even if there are several. * objectSignature.cpp: fixes #2559 "Crash on import when at least one DynamicGroup object already exists in the object tree." 2011-07-07 Vadim Kurland * RoutingCompiler.cpp (processNext): see #2191 "Crash when compiling a route with table object". Compiler for PF crashed when run-time AddressTable object was used in RDst of a routing rule. * PFImporter.cpp (makeAddressObj): see #2546 "PF import - negation inside of inline tables is ignored". Since we can not import address lists or tables that contain a mix of negated and non-negated items, importer should display an error when it enounters one of these and mark all rules that use it as "broken" (rule is colored red and error message is added to the comment). * PFImporter.cpp (makeAddressObj): see #2556 "PF import: impor of rules referring to undefined macros". If pf.conf file uses an undefined macro (there is $macro somewhere but the macro has never been defined), importer issues a warning, creates run-time DNSName object with the name "$macro" and marks all rules where it is used as broken, that is, rules are colored red and the error message is added to the comment field. Using run-time DNSName object makes compiler use "$macro" in the generated pf rule which means fwbuilder generates exactly the same pf rule as the one it tried to import. * PFImporterRun.cpp (run): see #2554 "PF import: create groups of address objects for macros where possible". Importer for PF recognizes macros that define lists of ip addresses, interfaces or host names and creates object groups with the same name from them. Only macros that contain at least one ip address in the list are recognized. * PF import: check if a macro used somewhere in the file to be imported is actually defined and abort if not * PF import: see #2551 making sure rules that have route-to option get the call to setRoute() in the importer 2011-07-06 Vadim Kurland * applied two patches by Vadim Zhukov persgray@gmail.com to replace calls to sprintf with safer calls to snprintf and fix some compiler warnings. * Importer.cpp (addStandardImportComment): see #2552 "PF import: add ability to suppress comments referring to line numbers in the original file". * PFImporter.cpp (pushPolicyRule): see #2551 "PF Import - source routing rules are not imported with rule options set". Importer should import "route-to" rule parameters. * PFImporter.cpp (newAddressTableObject): see #2546 "PF import - negation inside of inline tables is ignored". We can not import PF table definition that has some addresses negated. * PFImporterRun.cpp (run): see #2550 "PF import - recursive macros are not supported". Importer for PF should interpret macro definitions that use other macros. See #2545 "PF import error when using macro names with same base name and incrementing digit suffix". Importer should correctly interpret a macro that has name of another macro as a substring of its own name. 2011-07-05 vadim * PolicyCompiler_pf_writers.cpp (processNext): see #2549 "Update generated route-to configuration for PF versions 4.7 and later", SF bug 3348931. The "route-to" parameter moved to the end of pass rules in PF 4.7 * pf.g: fixed bug in PF import: address lists such as "{ addr1, addr2, ... }" defined as macros or inside the rule could not be imported correctly. * pf.g: we should be able to import both "block quick log" and "block log quick". 2011-06-29 theron * Fixed #2547, made keyword add/remove buttons same size. 2011-06-29 theron * Fixed #2540. On mac we can get a drop event even if dragMoveEvent() says the drop is invalid. So in ObjectTreeView we validate the drop the same we we validate in dragMove to make sure the drop is valid. * Fixed #2542. Catch exception inside preprocessor loop so that loop continues after error (for unit tests). Also make sure to set ".loaded" variable before calling loadFromSource so that if an exception happens we won't try to load it again later. * Fixed #2539. Make sure user folders are added properly. Also deal with case of an object that has a folder attribute that doesn't exist in the parent's subfolders list (shouldn't ever happen, but in case it does it no longer crashes). Also make sure that subfolders don't have commas in them. * Partially fixed #2544. Adding new icons for dynamic group. 2011-06-27 theron * Fixed #2530, where adding a subfolder opens the parent folder in the object editor. * Fixed #2529, where dragging and dropping items between subfolders could cause a crash. * Fixed #2528, display icon next to "new subfolder" menu item. * Added feature #2517: directory location caching. Use FWBSettings::{get|set}OpenFileDir() any time we use QFileDialog so that the directory you navigated to last time shows up in the next file dialog. This behavior is overridden by setting a working directory. If the directory no longer exists, gracefully fall back to something sensible. 2011-06-23 theron * Added support for creating user-defined subfolders. The subfolders exist purely in the display and are not reflected in the FWObject tree, in order to keep changes in the back-end to a minimum. New attribute "subfolders" on a system folder tells the gui what additional child elements to display in the tree, and attribute "folder" on any FWObject tells gui which child tree element to put it in. 2011-06-22 Vadim Kurland * ObjectManipulator_ops.cpp (autorename): fixed #2520 "Attached Network objects are not renamed if a firewall is renamed" * AttachedNetworksDialog.cpp (addAddressToList): see #2519 Avoid creating duplicate network objects for the AttachedNetwork object if the parent interface has multiple ip addresses that belong to the same subnet. * CompilerDriver.cpp (CompilerDriver): fixed #2521 "Compile fails if firewall has locked interface that is set to dynamic". * NATCompiler_pf_writers.cpp (_printProtocol): see #2524 'avoid " {tcp udp icmp} " in place of protocol'. NAT compiler for PF does not need to generate protocol match "proto {tcp udp icmp}" when service object used in the NAT rule is "any". The reason this was done this way is lost in the mist of time; it's been like this since very early versions of fwbuilder. 2011-06-21 vadim * NATCompiler_pf.cpp (compile): fixed #2428 "PF compiler crashes when ipv4+ipv6 NAT rule uses only ipv4 address". This has been reported as SF bug 3305234. 2011-06-20 Vadim Kurland * ObjectManipulator_slots.cpp (forward): see #2493 implemented "forward" function in addition to the "back" function, added a button to the roolbar, using new icons for Back and Forward buttons. * src.pro (SUBDIRS): see #2477 removed transfer agent code. * gui.pro: see #2506 Removed obsolete localization files (Russian and Japanese). These were incomplete and have never been updated for v4. 2011-06-10 Theron Tock * implementation of keywords associated with objects in the GUI; ability to filter by keywords, dialog layout changes to add GUI controls for keywords. * imlementation of the DynamicGroup object type. Dynamic group automatically expands to a set of objects using matching rules that at this time can match object types and keywords. 2011-06-09 Vadim Kurland * fixed several GUI crashes that happened when user performed various operations on the object tree that contained locked objects. see #2487 2011-06-04 vadim * FWWindow_editor.cpp (openEditor): this change is a part of the GUI usability improvements: when user double clicks on a firewall object to open it in the editor, rule set view panel switches to the rule set of that firewall. To decide which rule set to show, the program scans history of the objects the user opened before in the same GUI session and shows that firewall's rule set they opened last. If user never opened any rule sets of this firewall, then the first Policy object is shown. See #2465. * RuleSetView.cpp (itemDoubleClicked): as part of the GUI usability improvements, its behavior when user double clicks on "any" in a rule has changed. Now the program opens object "any" in the editor and shows prompt text that explains its behavior. The editor stays read-only and should appear grayed-out if palette is set up for that. This reverses the change made for #1731. See #2454. 2011-06-03 vadim * applied patch to provide configure command line option to specify path to ccache. Thanks to user "a. k. huettel " on SourceForge. * NATCompiler_pf.cpp (_expand_addr): see #2455 NAT Compiler for PF should use "(interface)" syntax to the right of "->" in NAT rules. This now works for all interfaces, including those that have ip addresses in fwbuilder configuration, when interface object appears in "Translated Source" in a nat rule. When firewall object appears in "Translated Source", it gets replaced with a set of its interfaces which also get translated into "-> (interface)". * NATCompiler_ipt.cpp (compile): see #2456 Added support for single object negation in "Inbound Interface" and "Outbound Interface" columns in compiler for iptables. * NATCompiler_pf.cpp (compile): see #2456 Added support for single object negation in "Interface" rule element of PF NAT rules. Now compiler can produce PF commands such as "nat on ! em0 ... " (for PF <4.7) or "match on ! em0 ..." (for PF >= 4.7) * Compiler.cpp (singleObjectNegation::processNext): moved rule processor that processes single object negation in any rule element to the base class Compiler. 2011-06-02 Vadim Kurland * pf.g (set_rule): see #2464 implemented import of PF "set timeout", "set limit" and other "set" commands. Known limitations: - commands "set ruleset-optimization", "set loginterface", "set block-policy", "set state-defaults", "set require-order", "set fingerprints", "set reassemble", "set hostid" are not supported. 2011-05-30 vadim * pf.g (nat_rule): see #2449 Implementd import of PF "nat" rules. Known limitations: - as of v4.2 we can not generate optinal parameters for the "source-hash" pooltype. "sticky-address" is not supported either. - Interface group names are not recognized 2011-05-27 vadim * PFImporter.cpp: see #2394 pf.conf import. This version implements import of pf.conf configuration with the following limitations: - anchors are not imported. Anchor rules are imported but rules inside anchors are not. - only pf.conf configurations designed with the use of keyword "quick" can be imported. - Macros are expanded during import and are not recreated as objects. Tables are imported as run-time AddressTable obejcts configured with the file name, or object groups. - User has to specify host OS and PF version number during import process because interpretation of rules with default settings of some parameters is version-dependent. - Import of IPv6 addresses and ICMPv6 matches in pf.conf is not supported at this time. - Import of TCP flag matches for flags 'E' and 'W' is not supported. - Import of "include" clause is not supported - Import of "user" and "group" matches is not supported 2011-05-26 Vadim Kurland * PolicyCompiler_pf.cpp (compile): see #2434 "PF compiler should use 'self' keyword where appropriate". Compiler for PF now uses keyword 'self' in rules where firewall object is used in Source or Destination. * fwcompiler/Compiler.cpp (processNext): added rule processor to replace firewall object with special run-time object "self" in Source and Destination rule elements. This rule processor can be used in policy compilers for any platform. 2011-05-17 vadim * FWObjectDatabase_tree_ops.cpp (merge): see #2420 "Crash when selecting New Firewall and existing firewall has interface that is locked". Fixed GUI crash that happened on some operations if an object in the tree was locked. For example, if the user locked an interface of one of the firewall objects that then proceeded to create new firewall object, the GUI would crash. The problem was not limited to locking specifically interface objects. 2011-05-15 vadim * IPTImporter.cpp (pushPolicyRule): see #2411 Implemented import of iptables rules with target CLASSIFY. 2011-05-14 vadim * CompilerDriver_ipt.cpp (findBranchesInMangleTable): see #2405 "Tag and classify actions dont work properly with branches". When branching rule points to a rule set that has rules with Tag and Classify options, branching should occur in mangle table even when checkbox "create branch in mangle table" is not checked. The fix in this change is tentative as it creates branch in chains PREROUTING, POSTROUTING and OUTPUT. Since target CLASSIFY is only allowed in POSTROUTING, this may create conflict. Need to test more. * AttachedNetworks.cpp (AttachedNetworks): see #1580 New object type: network object that automatically matches subnets an interface is attached to. The object can be a child of an interface. The object is optional and is not created automatically for all interfaces; user can add it using context menu associated with an interface. Dialog for this object allows editing of the name and comment. List of network addresses represented by this object is always generated automatically. Compiler for PF translates this object to "en0:network" construct that is supported by PF. Compiler for iptables expands it to the list of ipv4 and ipv6 networks defined by the addresses of the parent interface if interface has static addresses. If interface is confgiured as "dynamic" and has no address in fwbuilder, then compiler treats AttachedNetworks object as run-time and uses shell function to determine network addresses during activation of the firewall script. Compilers for other firewall platforms always treat this object as compile-time and abort if it is used with dynamic interface. 2011-05-13 vadim * PolicyCompiler_ipt.cpp (processNext): see #2402 "Tag action should be done in PREROUTING so it can be acted on later". If a rule has both tagging and classification options, the rule should be split so that iptables command doing tagging goes in PREROUTING and rule doing classification goes into POSTROUTING chain. * PolicyCompiler_ipt.cpp (processNext): see #2401 "Deprecating Route option for iptables". This target is not included in any of the popular Linux distributions (checked in Ubuntu, Fedora and CentOS). The GUI dialog and all support in the compiler will be removed in future version of fwbuilder. Beginning with 4.3.0, compiler aborts with an error when it encounters a rule using this option. In older versions of fwbuilder (4.2.x and before) this option was presented as an action "Route". * CompilerDriver_ipt_run.cpp (run): see #2400 'Mixing Actions "Accept" and "Classify" results in incorrect rules', see #2399 'Mixing Actions "Accept" and "Tag" results in incorrect ruleset'. After we made Tag, Classify and Route rule options instead of actions, rules that mix these options with actions "Accept" and others, except for "Continue", should be treated differently. The action are now implemented using iptables rules in the table "filter" and additional rules in table "mangle" is used to implement only tagging, classification or routing. Generated script does not change default action in table "mangle" and assumes it is "ACCEPT" so adding rules with target ACCEPT in mangle table should not be necessary. Another change because of this affects branching rules that use option "create branch in mangle table in addition to the filter table". These rules used to duplicate the same action and logging rules in mangle. Now they dont do this and only create rules in mangle if branch rule set performs tagging, classification or routing. 2011-05-11 vadim * v4.2.2 released * newFirewallDialog.cpp (finishClicked): fixes #2395 "Crash when setting installer directory location" and fixes #2396 "Crash when changing firewall name". These two bug reports where the manifestation of the same problem that was introduced by the fix for #2380. When user hits OK in the newFirewallDialog and it merges temporary object tree into the main object tree, it should call fixTree() to fix all pointers to the root of the tree. 2011-05-10 vadim * v4.2.1 released 2011-05-10 Vadim Kurland * fwbuilder 4.2.1.3540 released; started v4.3.0 * merged from branch multiple_actions to add changes that implement conversion of actions Tag, Classify and Route to options. Now one policy rule can have any combination of these options. See #2367. 2011-05-09 Vadim Kurland * FWCmdAddObject.cpp (redo): fixes #2391 "selecting 'new library' when editor panel not on 'editor' tab causes crash" 2011-05-06 vadim * PolicyCompiler_pf_writers.cpp (_printQueue): see #2390 Classify does not generate "queue" string for rules created in V4.2.1.3538 This completes the fix for the bug #2385. 2011-05-05 Vadim Kurland * FWObjectDatabase_19.xslt: see #2385 "PF action Classify uses wrong parameter". This change fixes a bug introduced in 4.2.0 that affects rules with action Classify in PF firewalls. The bug causes the following problems: For users who built their rules before v4.2.0: - rules compile normally, both in the single rule compile and when the whole firewall is compiled - if they opened the action of one of such rules in the action editor, the classification string would look empty - if they entered new classification string in the editor, compiler kept using the old one (which they can not see or change in the editor) For users who tried to build rules with action Classify with v4.2.0: - no matter what classification string they enter in the action dialog, generated code does not use it 2011-05-04 Vadim Kurland * FWObjectDatabase_18.xslt: XSLT transformation to upgrade data files from DTD v18 to DTD v19. This transformation finds "PolicyRule" elements with missing "Itf" child elements and fixes them by adding such element with a reference pointint to "any". Fixes #2383 * fwbuilder.dtd.in: Element "Itf" (an interface) of "PolicyRule" should be required. DTD version increment. 2011-05-03 vadim * PolicyCompiler_ipt.cpp (processNext): see #2367 "Multiple actions per policy rule". Options "Tag", "Classify" and "Route" work with iptables in a combination with any action. This implementation has one restriction: option Route can not be used in combination with options Tag or Classify and any action that is not Continue. This is because option Route can yield rules in PREROUTING or POSTROUTING chains that are also used by options Tag and Classify. For this combination we create two user-defined chains that perform routing and tagging (or classification). In case of a terminating action both chains end with it. This means if one matches the packet, the other is never going to see it. Non-terminating action "Continue" does not create this problem. This limitation may be removed in future versions of fwbuilder. 2011-05-03 vadim * newFirewallDialog.cpp (finishClicked): see #2380 "Firewall object is created in the middle of the "new firewall" wizard and clicking Back creates two firewall objects". If user chose to create new firewall object from a template and clicked Back after choosing the template, the program actually created two firewall objects but only one was visible in the tree. 2011-04-30 vadim * RuleSetModel.cpp (objectChanged): see #2373 "GUI becomes unresponsive for a long time when an object that is used in a large number of rules is modified". The program spent too much time resizing rule set view columns. 2011-04-29 vadim * UsageResolver.cpp (findFirewallsForObject): see #2373 "GUI becomes unresponsive for a long time when an object that is used in a large number of rules is modified". This bug only affected configurations with very large rule sets (1500 rules) where lots of rules used the same object. The change in UsageResolver eliminates unnecessary scanning of all rule sets to check if the affected rule set might be used as a branch. The program used to scan the same objects many times. * iosaclAdvancedDialog.cpp (accept): fixes #2368 and SF bug 3294457 "External install script". External install script name and arguments weren't saved for IOS firewall objects. * snmpNetworkDiscoveryWizard/ND_ProgressPage.h: fixes #2370, #2371 "broken signals in network discovery wizard". Network discovery wizard was not correctly initializased and did not work. 2011-04-25 Vadim Kurland * instDialog_ui_ops.cpp (readInstallerOptionsFromDialog): tentative fix for SF bug 3169045 "Batch installer lists IPv4 address as management address". Built-in installer wanted to use management interface address in batch mode even when alternative address or putty session name was provided. This happens only in batch mode install. * VERSION (GENERATION): version 4.2.0 released; started 4.2.1 2011-04-20 vadim * configlets/pix_os/script_skeleton: fixed bug (no #): "clear" commands were not added when option "generate only access-list, access-group, nat, static..." was in effect; also making sure "clear" commands for object-groups and ssh are not added when option "do not add clear commands" is on. This affects PIX/ASA/FWSM. 2011-04-19 Vadim Kurland * RoutingCompiler_ipt.cpp (compile): see #2359 "Crash when compiling single rule with IPv6 destination and IPv4 gateway or interface". Routing compiler for iptables does not support ipv6 at this time and will issue a warning when user tries to place ipv6 address or network in a routing rule. The warning does not appear when ipv6 address is a member of a group used in the rule. Also see #1575. 2011-04-17 vadim * fwbedit.cpp (main): added command line switch "-d" to function "import" in fwbedit. This switch activates object deduplication on import. 2011-04-15 vadim * fwbedit.cpp (main): see #2328 "Add ability to run firewall import from the command line". This has been implemented as a new function "import" in fwbedit. See man page fwbedit(1) and "fwbedit -h" for more details. * iptables.g (multiport_tcp_udp_port_spec): see #2245 fixed bug in parser for iptables that prevented correct import of iptables rules using module "multiport" with port range matches. 2011-04-14 vadim * CompilerDriver_pix_run.cpp (pixSecurityLevelChecks): see #2351 Security levels of ASA and FWSM interfaces do not have to be unique. Removed check that enforced this. * IPTImporterRun.cpp (run): see #2275 Importer for iptables now correctly handles both "intrapositioned" ("-s ! address") and "extrapositioned" ("! -s address") negation. * platform/fwsm.xml: see #2295 Added FWSM version "3.2". According to Cisco documentation, FWSM version 3.2 matches PIX 7. * platform/pix.xml: see #2348: "Accounting action is not valid for FWSM platform". Actions "Accounting" and "Reject" should not appear in the drop-down list of actions in the GUI if platform is pix or fwsm. * PolicyCompiler_pix.cpp (printPreambleCommands): see #2347 "FWSM move up the "access-list mode auto-commit" command". Command that configures access list commit mode should be issued before any commands that clear and configure access lists. Also in this change moving commands that set up temporary access list to the top of the script. * PolicyCompiler_pix.cpp (printClearCommands): see #2322 If this is FWSM and if manual commit mode is used, need to commit after clearing ACLs before we clear object groups. 2011-04-13 Vadim Kurland * IPTImporter.cpp (pushPolicyRule): see #2338 "Empty Mangle Policy object created on import". Iptables rules in the table 'mangle' will be imported in the dedicated Policy rule set with name "Mangle". Rules that use chains FORWARD and POSTROUTING in table 'mangle' can not be reproduced and will be marked as "bad" (color red and corresponding comment). * configlets/fwsm_os/ntp: see #2344 fwbuilder should not generate any "ntp" commands for FWSM because NTP can not be configured on FWSM. * OSConfigurator_pix_os.cpp (_printSysopt): see #2345 More fixes for FWSM 4.x: "service resetoutbound", "timeout xlate", "timeout sunrpc" * OSConfigurator_pix_os.cpp (_printInterfaceConfiguration): see #2343 "Interface nameif error when installing generated config for FWSM". Use correct "nameif" command sytax in FWSM 2.x and 4.x. * OSConfigurator_pix_os.cpp (_printSSHConfiguration): see #2344 "FWSM install errors for clear commands". Using correct syntax for "clear" commands for FWSM v4.x 2011-04-11 vadim * PolicyCompiler_PrintRule.cpp (_printTarget): see #2235 "Modified rule action for Continue". Rules with action "Continue" should translate into iptables commands without "-j TARGET" parameter. If such rule also has logging enabled, it should use target "-j LOG" instead of generating additional chain. * IPTImporter.cpp (pushPolicyRule): see #2206 Iptables commands with no "-j TARGET" parameter should be imported using action "Continue". * iptables.g (comment): see #2336 Importer for iptables recognizes version stored in the top comment by iptables-save and sets version in the firewall object it creates. 2011-04-10 vadim * utils.cpp (expand_interface_with_phys_address): see #2324 "NAT + MAC-matching rules not generated properly". Iptables NAT rules matching a group of host objects with both IP and MAC addresses each in "Original Source" were not generated properly. * PolicyCompiler_PrintRule.cpp (_printOptionalGlobalRules): SF bug 3178186 "Add ND/NS allow rules for the FORWARD chain". Rules that are added automatically to ipv6 Linux firewall to permit neighbor discovery packets should be also added to the FORWARD chain if the firewall is a bridge. * ObjectManipulator_create_new.cpp (actuallyCreateObject): see #2229 "Multiple new objects with the same name". The GUI should automatically choose unique object names for new objects. * platforms.cpp (setInterfaceTypes): see #2224 "FreeBSD - Bridge interfaces with the name vlan don't show as Bridge Port Interfaces". This actually applies to all OS where we support vlan and bridge interfaces. Fwbuilder GUI should allow the user to set subinterface type to both "ethernet" and "vlan" when its parent interface has type "bridge". Setting subinterface type to "ethernet" makes it bridge port, while setting the type to "vlan" signals policy compiler that it should generate code to configure real vlan interface. If the name of the subinterface does not include the name of the parent, such as "vlan101", or when the name does not match vlan ID, such as "vlan8101", global preferences option "Verify interface names and autoconfigure their parameters..." should turned off. The option is located in the Preferences dialog, tab "Objects". 2011-04-08 vadim * FWBSettings.cpp (init): fixed bug (no #): "Show text description in rule columns" does not persist across sessions * clusterMembersDialog.cpp (createMember): see SF bug 3211769 "Member interfaces not sorted". Sorting interfaces by name in the dialog where user adds them to the cluster member group. * os/ios.xml: see #2330 "Crash when creating a cluster of IOS router firewalls". Added support for basic IOS router clusters. No failover protocol support at this time, but the cluster can be configured with protocol "None" and fwbuilder will do address substitutions at compile time. * PolicyCompiler_cisco.cpp (processNext): see #2308 "ASA rules with service set to "http" and destination set to asa firewall object should generate different command syntax". Policy rules that have firewall object in Destination and http object in Service now generate "http" commands. This is similar to how fwbuilder generates "ssh", "telnet" and "icmp" commands to permit corresponding services to the firewall itself. * pix.g (static_starts_with_tcp_udp): more fixes for import of PIX/ASA "static" command in different variations. See #2334 * ObjectEditor.cpp (changed): see #2335 "GUI switches between data files upon closing editor panel". If user opened two data files in the GUI and was in the process of editing objects in one of them, the GUI would flip to the other file under certin circumstances. 2011-04-07 vadim * PIXImporterNat.cpp (buildDNATRule): resolved several problems with import of "static" commands that use access list that matches source or destination tcp/udp ports. See #2326, #2327 * pix.g (network_top_level_command): see #2295 fixes in the grammar to support import of FWSM configs * PIXImporter.cpp (fixServiceObjectUsedForBothSrcAndDstPorts): see #2265 "ASA 8.3 acl import: access-list commands using two named objects or object-groups", see #2290 "Access lists that include mix of service objects and inline service definitions are not properly imported". To import access-list command that matches both source and destination tcp/udp ports and uses object-group in either match I should create a new service group with a collection of TCP or UDP service objects matching all combinations of source and destination port ranges defined by the rule. This should work when one or both matches use object-group in combination with inline port match. * PIXImporter.cpp (pushPolicyRule): see #2297 Added warning when importer enounters access-list command that matches tcp or udp ports with "neq" port operators in both source and destination. This configuration is not supported by import at this time. * PIXImporterNat.cpp (buildSNATRule): see #2319 "Imported nat rules with multi-line access-lists have only the first entry" * PIXImporterRun.cpp (run): see #2167 Implemented import of "names" and "name" commands in PIX/ASA configs. * CompilerDriver_pix_run.cpp (pixNetworkZoneChecks): see SF bug 3213019 "FWSM Network zone and IPv6". Currently we do not support ipv6 with PIX/ASA and FWSM. If user creates a group to be used as network zone object and places ipv6 address in it, this address should be ignored while compiling the policy but this should not be an error. * FirewallInstaller.cpp (executeExternalInstallScript): see SF bug 3212988 "external script makes getopt difficult". User-defined parameters for the external script moved to the end of the command line. * res/os/fwsm_os.xml: updated filesystem path on FWSM where fwbuilder built-in installer should place generated configuration when it is installed using scp. Currently using path "disk:". 2011-04-05 vadim * pix.g (static_command_common_last_parameters): see #2314 "Import of static NAT statements drops netmask value and uses host instead". "Netmask" parameter of a "static" command applies to the real address. * PIXImporterNat.cpp (buildDNATRule): see #2313 "NAT with access-list destination address and original service not set". "Nat" and "static" commands that use access-list should import all components of the access-list command (source, destination and service/protocol). * PIXImporterNat.cpp (buildSNATRule): see #2310 "Imported global / nat rule has wrong interface defined". Importer mixed up inbound and outbound interfaces in NAT commands created from combination of "global" and "nat" PIX/ASA commands. * pix.g (nat_new_top_level_command): since import of ASA8.3 "new" nat commands is not implemented yet, importer should issue a warning when such command is encountered. See #2315 2011-04-01 vadim * FWObject.cpp (insert_before): see #2171 "Undoing delete of rule ends up with rules being created with duplicate rule numbers". Also see #2172 "Crash when deleting rule - related to #2171". When user deleted the last rule in a rule set, then used Undo to restore it, the program lost track of rules in the rule set and became unstable. * FWObject.cpp (shallowDuplicate): see #2286 "Crash when closing file". The GUI crashed if user imported iptables or pix configuration, then deleted a rule and tried to close project window. * PIXImporter.cpp (mirrorServiceObjectRecursively): see #2291 The same service object-group that matches some tcp or udp ports can be used to match both source and destination ports in an access-list command. Importer should recognize when such group is used to match source ports and create mirrored group with potentially mirrored service objects. This should work when group includes other groups. * FWWindow_editor.cpp (openOptEditor): fixes #2307 "GUI switches to another file after editor panel is closed" 2011-03-31 vadim * parsers/pix.g (http_command): see #2164 fixed import of "ssh" commands and added import of "http" commands * objectMaker.h (ObjectMakerErrorTracker): see #2302 Importer should log and continue when it encounters an error. This matches its behavior in older versions and makes it more resilient to changes in target platform firewall languages. Rule that had an error or unrecognized syntax in it should be marked by changing its color to red and an explanation should be added to its comment. * PIXImporterNat.cpp (buildSNATRule): import of PIX/ASA "global" and "nat" commands works. 2011-03-30 vadim * PIXImporterNat.cpp (buildDNATRule): import of PIX/ASA "static" commands works for the most part. Needs more testing. 2011-03-28 vadim * ObjectManipulator.cpp (getDeleteMenuState): see #2226 fixed GUI crash that happened when user tried to delete or cut an object from locked library. * RuleOptionsDialog.cpp (loadFWObject): see #2230 the GUI should allow limit-burst values of up to 10000 2011-03-27 vadim * import/PIXImporter.cpp (addLogging): see #2279 Support for import of ASA access-list lines with log levels and intervals * parsers/pix.g (tcp_udp_port_spec): see #2284 fixed import of tcp/udp port ranges using mix of port numbers and port names * getServByName.cpp (getPortByName): see #2268 Making sure all tcp and udp port names are recognized on import; also since PIX/ASA converts udp port numbersin "show run" output to the same names as if they were tcp, using the same name mapping table. 2011-03-25 vadim * Importer.cpp (pushRule): fixes #2280 Rules created from PIX config import showed an icon that indicated non-default combination of rule options, yet all rule options looked normal when opened in the editor. * parsers/pix.g (icmp_top_level_command): see #2164 Implemented import of "ssh", "telnet" and "icmp" PIX/ASA commands. These commands are imported as regular rules in the main Policy ruleset. * PIXImporter.cpp (finalize): see #2277 "Create policy objects for ASA access-lists that are not applied in an access-group". Policy rule set will be created and populated with rules found in the corresponding access-list even if this access-list is not applied to an interface with access-group command. * parsers/pix.g (tcp_udp_rule_extended): see #2273 Improvements in the parser for PIX/ASA configs to make it recognize object-group and named object names used to define source port, destination address or destination port in "access-list ... tcp|udp" rules, including ambiguous situation when an object-group appears after source address specification because this group can define either source port or destination address. 2011-03-24 vadim * ASA8ObjectGroup.cpp: see #2263 looks like "object-group service" that includes named objects defined as "service-object" can not be used in access-list commands and therefore is useless. Unless I misunderstood and there is a way to use it, I should not generate ASA configuration like this: object-group service id5102X14531.srv.tcp.0 tcp service-object object http.0 service-object object https.0 Object-group with "tcp" or "udp" type-suffix in the end does not allow "service-object" statements at all, so this configuration is incorrect anyway. However even without "tcp" in the end to make "service-object" references acceptable, the group can be built but can not be used in access-list statements. Instead, the group should use port-object statements: object-group service id5102X14531.srv.tcp.0 tcp port-object eq 80 port-object eq 443 * IOSImporter.cpp (createTCPUDPServicePair): see #2267 added support for import of object-group and service-object statements of type "tcp-udp" (these get imported as service group object with two tcp and udp service objects). * getServByName.cpp (getPortByName): see #2268 updated list of named tcp and udp ports recognized by the importer for Cisco ASA. It is still unclear what port does the name "cifs" correspond to. 2011-03-23 vadim * addressObjectMaker.cpp (createObject): see #1548 Improved algorithm used to deduplicate Network objects on import. * FWWindow.cpp (prepareToolsMenu): fixed SF bug 3238026: build failure on systems without net-snmp development libraries. 2011-03-22 vadim * parsers/pix.g (acl_xoperator_src): first attempt at PIX/ASA access-list import. Not done yet. * parsers/pix.g (port_object): see #2234 added support for import of "obejct-group service name tcp|udp" constructs in ASA 8.3 with subsequent "port-object" statements. 2011-03-21 vadim * PortRangeConverter.h (PortRangeConverter): see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and pix access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary. 2011-03-20 vadim * ImportFirewallConfigurationWizard.cpp (accept): see #2253 "importer should not creates objects while still in the middle of the wizard". Importer wizard creates new objects in the object tree only when user clicks Finish and abandons results if they click Cancel. 2011-03-19 vadim * IOSImporter.cpp (createTCPUDPNeqObject): see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group. * objectMaker.cpp (findMatchingObject): see #2240 better deduplication algorithm on import: we consider objects created from in-line address/netmask and port specifications found inside object-group, access-list, filter or nat commands "anonymous" objects. These objects get automatically generated names and are deduplicated using only their relevant attributes but not names. Objects created from pix named object ("object network foo", "object service bar") statements are considered "named" objects. They get the name matching the name in corresponding pix config line and are deduplicated using both relevant attributes and the name. 2011-03-17 vadim * PIXImporter.cpp (newObjectGroupNetwork): see #2234 Added support for import of PIX/ASA "object-group" statements. * FirewallInstaller.cpp (getActivationCmd): see #2239 Added variable "firewall_name" to configlets that define commands installer runs on the firewall to activate new policy (all platforms). 2011-03-16 vadim * Importer.cpp (prepareForDeduplication): fixed #1548 "Object de-duplication during import process". Also SourceForge 3030072 "remove duplicates during any import". Now the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import. 2011-03-14 vadim * pix.g (named_object_network): see #2223 Implemented import of named objects for Cisco PIX and ASA ("object network name" and "object service name") 2011-03-12 vadim * Compiler.cpp (expandGroupsInRuleElement): sorting objects in the rule element by name after group is expanded, this helps ensure stable ordering of objects in generated configuration. * Compiler.cpp (replaceClusterInterfaceInItfRE::processNext): sorting objects in rule element after cluster interfaces have been replaced, this helps ensure stable ordering of objects in generated configuration. * FWObject.h (FWObjectNameCmpPredicate): moved this class from gui-specific module to libfwbuilder as it is universally useful. It can compare FWObject objects by name and can optionally can follow references; it can be used with std::sort() to sort lists of FWObject pointers or directly sort rule elements. * Compiler.cpp (_init): see #2212 "Performance improvement in compilers". This change brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10. 2011-03-11 vadim * FWObject.cpp (add): fixes #2209 "do not allow the same object to be child of different objects in the tree". Method FWObject::add() enforces this. Subsequent clean-up and fixes in many places to follow this logic. This makes code much cleaner, better organized and more reliable. 2011-03-10 vadim * libfwbuilder/src/fwcompiler/Compiler.cpp (Compiler): see #2207 fixed memory leak in policy compilers. The impact of this leak was especially severe on Windows with very large object databases. 2011-03-08 vadim * CustomServiceDialog.cpp (loadFWObject): fixes #2201 "Some fields of locked object are editable". Some input fields of the Custom Service object dialog were editable even when object was locked read-only. * GroupObjectDialog.cpp (loadFWObject): fixes #2203 "Crash when attempting to add an object to a locked group". * PolicyCompiler.cpp (checkForShadowing): see #2204 "Shadowing detected for rule with action Continue". Policy rules with action "Continue" should not shadow other rules and can not be shadowed. * Importer.cpp (addStandardRuleComment): see #2189 Program adds the file name and the line number to comments of policy and nat rules it creates during import. * IPTImporter.cpp (pushPolicyRule): see #2202 importer for iptables creates Custom Service object to match combination of states it does not recognize. This includes "NEW,ESTABLISHED". 2011-03-07 vadim * IPTImporter.cpp (pushNATRule): see #2197 "iptables nat rules in chain OUTPUT not imported correctly" * iptables.g (nat_addr_range): see #2194 "iptables import problem with SNAT rule translating to an address range". NAT rules translating into address range with "-j SNAT --to-source 192.168.1.1-192.168.1.10" did not import correctly * IPTImporter.cpp (pushNATRule): fixes #2195 "incorrect iptables import of nat rule with NETMAP target" * IPTImporter.cpp (pushNATRule): see #2196 "iptables nat rules with target REDIRECT not imported". Iptables NAT rules with target REDIRECT where not imported correctly. * IPTImporter.cpp (pushNATRule): see #2190 "support for import of branches in NAT rules for iptables". Implemented import of NAT rules in user-defined chains for iptables, these translate into branching NAT rules in fwbuilder. 2011-03-06 vadim * Importer.cpp (ignoreCurrentInterface): see #2152 "ASA Import - shutdown interfaces". Importer recognizes and skips ASA interfaces in "shutdown" mode. * IPTImporter.cpp (pushNATRule): see #2181 "Update iptables importer to detect inbound & outbound interfaces in NAT rules". Importer can now import nat rules with "-i" or "-o" interface spec. * NATCompiler_ipt.cpp (processNext): see #2170 "Compiler should generate error for invalid iptables NAT configs". Now that we allow the user to specify inbound and outbound interfaces in iptables NAT rules, compiler should verify that combination of requested "-i" and "-o" interfaces is in fact valid. For example iptables does not allow "-o" interface spec with rules that go into PREROUTING chain (DNAT rules) or "-i" interface spec with rules in POSTROUTING chain (SNAT rules). * IPTImporter.cpp (pushPolicyRule): see #2189 Policy importer warnings and errors now include line numbers to help find relevant lines in the original configuration file. 2011-03-05 vadim * importFirewallConfigurationWizard/IC_ProgressPage.cpp (logLine): see #2183 "count errors and warnings generated by the importer and show the numbers in the progress page of the wizard". Configuration import wizard now shows counters of warnings and errors generated by the importer. * FWBMainWindow_q.ui: see #2162 menu item "File / Import Policy" renamed to "File / Import Firewall". This menu item launches wizard that imports existing iptables, Cisco router IOS or Cisco PIX/ASA config. 2011-03-04 vadim * IC_NetworkZonesPage.cpp (setNetworkZones): see #2161 policy import wizard shows the page where user can set up network zones of interfaces if firewall platform was determined to be PIX. * IC_PlatformWarningPage.cpp (initializePage): see #2161 "import workflow and automatic detection of firewall platform from the config file". When user imports existing firewall configuration, the GUI automatically detects firewall platform from the format of the config file and shows platform-specific warning to explain what parts of the config can and can not be imported. It also detects firewall host name where possible (currently Cisco IOS and ASA/PIX). Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved. 2011-03-01 vadim * importAddressListWizard/ImportAddressListWizard.cpp (ImportAddressListWizard): see #2163 code that imports addresses from a file in /etc/hosts format moved to its own wizard; using QWizard and QWizardPage classes with correct implementation of page sequencing and validation; old discovery druid has been disabled. SNMP discovery and ios/pix/iptables configuration import will move to their own wizards later. 2011-02-27 vadim * DiscoveryDruid.cpp (finishClicked): fixes #2156 "After import the firewall should be opened in object tree". * instDialog_ui_ops.cpp (readInstallerOptionsFromFirewallObject): fixes #2160 "Installer reports error "Generated script file .fw not found."". The problem was intorduced earlier while fixing #2047 2011-02-26 vadim * DiscoveryDruid.cpp (finishClicked): see #2153 "Add Network Zone explanation and selection dialog to ASA/PIX import". Wizard shows additional page when user imports PIX/ASA config. This page explains concept of network zones and offers UI to let them choose network objects or groups as a network zone of each interface. * PIXImporter.cpp (rearrangeVlanInterfaces): see #2145 "ASA Import of VLAN interfaces - Advanced Interface Settings not available". Vlan interfaces discovered in the process of PIX configuration import should be created as subinterfaces of the corresponding parent with correct interface type and vlan id. * parsers/pix.g (intf_address): fixes #2146 Issue a warning when parser encounters "standby" parameter in an interface configuration. We do not support import of PIX failover configuration at this time. * platforms.cpp (findBestVersionMatch): fixes #2147 "ASA Import - some versions are not detected correctly". when user imports PIX/ASA configuration, firewall object will automatically be configured with the version setting that best fits version indicated in the imported configuration. Note that fwbuilder does not provide the list of version numbers that match PIX/ASA versions exactly, for example we do not have settings "7.1" and "7.2". Devices running these versions of PIX/ASA software should be configured with version "7.0" in fwbuilder. 2011-02-25 vadim * parsers/pix.g (intf_address): see #87 "Import of PIX configuration". Basic grammar that can parse host name, version, interfaces, their names, labels, addresses, security levels and few other things for PIX 6, 7 and ASA 8. PIX standby configuration is not parsed (so we can't import cluster configuration at this time). More work needs to be done to import named objects, object groups, as well as policy and nat rules. 2011-02-24 Vadim Kurland * FirewallInstaller.cpp (getGeneratedFileName): see #2047 "Inspect generated files button shows different path information". Do not pass full path to the output file as an argument of the "-o" option when the GUI launches policy compiler. Since the "-d" option passes directory path where files sould be saved, actual file names do not need to be absolute path, except if the user entered absolute path for the output file name in the firewall settings dialog. * configlets/freebsd/installer_commands_root: see #2143 "installer should run /etc/rc.d/pf script to reload PF rules on FreeBSD when generated script is in rc.conf format" * AddressTableDialog.cpp (browse): see #2140 "Attempting to create new Address Table file results in read-only error". Implemented support for the workflow when user wants to create the file used to feed addresses to the AddressTable object. * AddressTableEditor.cpp (load): fixes #2139 "Provide "Cancel" button if Address Table file is read-only". IF the file configured with Address Table object is read-only, the GUI shows warning when user clicks "Edit" button and offers a choice: open it for viewing read-only or cancel. 2011-02-23 vadim * AddressTableEditor.cpp (save): fixes #2135 "Editing table objects". Dialog of the AddressTable object now offers button "Edit" that lets the user edit address table file. This only works if the file is located on the same machine where the GUI is running, so it is probably most useful for compile time objects. 2011-02-22 Vadim Kurland * configlets/linux24/shell_functions: see #2130 "unnecessary output when iptables script runs on the firewall". Ever since I switched to using "command" to verify that various system utilities generated script needs are present and can be used, the scirpt produced extra lines in the log printing full path and names to /usr/bin/logger, /sbin/ip etc. These lines are unnecessary and should not be there. This problem was introduced some time during the work on 4.2.0 * instOptionsDialog.cpp (instOptionsDialog): fixes #2129 'deprecate "test install" function'. We have decided to deprecate test install because it is rather heavy-handed on Linux and PIX where it reboots the firewall and plain does not work on *BSD. 2011-02-21 vadim * PolicyCompiler_ipt.cpp (processNext): fixes #2008 "option "--physdev-out" is not allowed in OUTPUT chain". After this change, compiler avoids INPUT/OUTPUT chain if interface in the rule column "Interface" is a bridge port and firewall is bridging firewall (which means we are going to use --physdev-in or --physdev-out option for this rule). * newFirewallDialog.cpp (monitor): see #2126 Using snmp sysDescr OID to guess version of the new firewall when it is created using snmp polling. * platform/pix.xml: see #1990 "Change default value for Cisco ASA/PIX 7+ to generate outbound ACLs". Newly created PIX/ASA firewall objects will now have "generate outbound acl" option turned on by default. * newFirewallDialog.cpp (showPage): fixes #1678 "When creating a firewall from template it appears that a default template is selected". When user arrives at the page where they choose template to create new firewall object from, the first template should be automatically selected. * AddressRangeDialog.cpp (applyChanges): fixes #1971 "Address range can be created with end address lower than start address". Address Range object dialog should not let the user enter range end address which is lower than range start address. Dialog behavior is now similar to the behavior of the tcp and udp service dialog where user can not enter port range end number lower than port range start number. * InterfaceData.cpp (guessLabel): fixes #2113 "ASA/PIX SNMP discovery - assign default labels based on interface description". Added pattern to match Cisco ASA interface description which is different from Cisco PIX interface descriptions as returned via snmp. 2011-02-20 vadim * BaseCompiler.cpp (getErrorsForRule): fixes #2124 "some error messages get multiplied when compiler splits rules". Under certain circumstances error messages could appear multiple times in the generated script. * Compiler.cpp (_expand_interface): fixes #1920 "Setting host interface to unnumbered after it has been assigned IP address doesn't have desired effect". Compiler still used ip addresses that belonged to the interface even if it switchd to "unnumbered". These children address objects should be ignored. 2011-02-19 vadim * NATCompiler_pix.cpp (processNext): see #2098 Added support for user-configurable inbound and outbound interfaces in Cisco PIX/ASA NAT rules. Two new columns appear in the rule set view: "Inbound Interface" and "Outbound Interface". If user leaves one or both columns blank, the GUI shows "Auto" in there and policy compiler picks corresponding interface automatically. Leaving both columns blank ("Auto") triggers backwards-compatible automatic behavior where both interfaces are picked automatically. Multiple interface objects and groups of interfaces are allowed in these columns. * ClusterInterfaceWidget.cpp (getInterfaceData): fixes #2117 "CARP interfaces in cluster that use VLAN interaces have no interface set to MASTER". When PF cluster configuration was built using vlan interfaces of member firewalls, CARP interfaces were not properly configured with master/slave choice user makes on the first page of the new cluster wizard. * configlets/bsd/update_addresses: fixes #2116 "When CARP interface IP address can't be assigned error or warning should appear". The problem actually affects any type of interface. Generated script should abort with an error termination code when ifconfig fails to assign ip address to an interface. 2011-02-17 vadim * NATCompiler_ipt.cpp (processNext): see #2097 #133 "support for inbound and outbound interface columns in iptables NAT rules". This also addresses SF feature requests 1954286 "DNAT with interface as condition not possible" and 621023 "manipulating interface in NAT rule". * platforms.cpp (setDefaultFailoverGroupAttributes): fixes #2101 "CARP interfaces are set with same advskew". When new PF cluster is created, master advskew paramerer will be set to 10 and backup to 20 to make it deterministic. * NATCompiler_ipf.cpp (processNext): see #133, fixes #2108 making nat compiler for ipfilter work with interface column, however the column is not exposed to the user. Compiler behavior should be backwards compatible with older versions of fwbuilder. * NATCompiler_pf.cpp (processNext): see #133. MErged code from the branch, running tests. Making sure rules that have firewall object in ODst and interface columnblank end up with rdr command without "on interface" clause as before. * stopped making builds on Ubuntu Hardy. Old Qt (4.4.1) means more and more parts of the code do not compile and require workarounds, sometimes with loss of functionality in the GUI. v4.1.3 will be the last officially released version of fwbuilder to work on Hardy. 2011-02-16 vadim * NATCompiler_pf.cpp (compile): fixes #2095 added support for groups and multiple objects in column "Interface" for PF NAT rules. These translate into { em0 em1 em2 } groups in generated pf.conf lines. * NATCompiler_pf.cpp (compile): fixes #2096 added support for negation in Interface column for PF NAT rules. Sets of interfaces are converted to complementary sets using complete list of interfaces of the firewall. * carpOptionsDialog.cpp (validate): fixes #2100 carp password should be optional parameter * OSConfigurator_bsd_interfaces.cpp (configureInterfaces): make sure we print "ifconfig" commands for mtu and other parameters for all interfaces, including those with no ip addresses and bridge ports (unnumbered interfaces used to be skipped before) * ObjectTreeView.cpp (startDrag): fixes #2099 "Object list scrolls up to the last edited object". Object tree used to scroll spontaneously when user started dragging an object from it to a rule. * configlets/bsd/update_vlans: see #2105: generated script now supports vlan interfaces with names that do not match vlan IDs (OpenBSD, FreeBSD, shell script format). * OSConfigurator_bsd_interfaces.cpp (sort_interface_names): see #1807, #2104: arrange interface configuration commands in the generated scritpt in such order that bridge and carp interfaces are configured after all other interfaces are done. * compiler_lib/CompilerDriver.cpp (commonChecks2): see #2103 removed interface name validation check in compilers, this check will only be done in the GUI. Comiler still verifies bridge inetrface configuration and makes sure vlan interfaces that should also be bridge ports are created as copies. * InterfaceDialog.cpp (applyChanges): see #2103 "complex vlan/bridge configurations are not supported by the interface validation code". Added checkbox to let the user turn off interface name validation functions in the GUI. Checkbox is located in the global Preferences dialog, tab Objects, subtab Interface. For backwards compatibility, the checkbox is turned on by default. When it is off, the GUI does not validate the name of inetrfaces and subinterfaces and turns off checks that enforced interface name patterns for VLAN, bridge and bodning interfaces. It also turns off check for the validity of vlan ID derived from vlan interface name and turns off automatic configuration of interface type and vlan ID. These checks sometimes were in the way of building complex configurations that involved multiple vlan interfaces with names not matching their IDs. This also fixes SF bug #3066714 "please dont stop me from creating a new interface" where user wanted to create interface "veth201.0" on Linux but the GUI blocked this operation because the name seemed to match vlan interface pattern. 2011-02-15 vadim * ActionsDialog.cpp (setRule): see #1871 "PF Actions Tag and Classify can be terminating or non-terminating". Added checkbox to the action properties dialog for actions Tag and Classify for PF that lets the user choose if these actions should be terminating or not. Old behavior (Tag was non-terminating and Classify was terminating) is reflected in default settings of the checkboxes. Terminating rules generate "pass quick" commands, while non-terminating rules generate "pass" commands (no "quick" option). * libfwbuilder/migration/FWObjectDatabase_17.xslt: see #133 Working on adding interfaces to the NAT rule model. There will be two inetrfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded. 2011-02-14 vadim * OSConfigurator_bsd_interfaces.cpp (configureInterfaces): fixes #2091 "ethernet intrface options a used twice if the interface is a bridge port". When an interface appeared twice in the firewall configuration, such as when it is used as a bridge port and vlan parent interface, options configured for it in its settings dialog were added twice to the generated configuration. * OSConfigurator_freebsd.cpp (interfaceConfigLineBridge): fixes #2092 "option "stp" should be optional in the ifconfig command that builds bridge interface for FreeBSD". The dialog provides checkbox "Enable STP", parameter "stp" will be added to the ifconfig command only when the checkbox is turned on. * pfAdvancedDialog.cpp (pfAdvancedDialog): fixes #1866 "support for pf option set state-policy", #1868 "support for pf option set block-policy", #1869 "support for pf option set debug". 2011-02-13 vadim * configlets/freebsd/carp_interface: see #2074 On FreeBSD ifconfig does not understand parameter carpdev * PolicyCompiler_pf.cpp (checkForShadowingPlatformSpecific): see #1867 "PF: rule with non-terminating action Tag shadows other rules below it". Since action Tag is non-terminating, rules with this action should not shadow other rules. * instConf.cpp (clear): see #2088 "Installer caches putty session". Need to initialize putty_session properly and clear it in clear(). * snmp.cpp (run_impl): See #2084 "snmp discovery takes forever on devices with large routing tables". This takes very long time on decides with large routing tables. This code was implemented long time ago and apparently routing data was intended to be used to discover "external" interfaces, but it is unclear if this is still done. The concept of external/internal currently exists only for platforms that support security levels (PIX) and there we guess levels by matching addresses against RFC1918 and let the user user adjust levels manually anyway. 2011-02-12 vadim * ObjectManipulator_tree_ops.cpp (expandOrCollapseCurrentTreeNode): fixes #1895 "Add context menu option to expand all child nodes in object tree". Added menu item "Expand" to the context menu associated with all objects in the object tree. This item recursively expands all tree nodes under the given object and automatically changes to "Collapse" if the item is expanded. Also changed behavior of the double click on the object in tree: before, double click opened object in the editor and expanded or collapsed subtree. Now it only opens object in the editor but does not expand/collapse subtree. * fixes #2083 Added new services to the Standard Objects Library: rtmp, xmpp-client, xmpp-server, nrpe 2011-02-11 vadim * instDialog_ui_ops.cpp (verifyManagementAddress): see #2073 "Add additional information or workflow when no management inferface configured". The error message shown to the user when no interfaces has been marked as "management" is now more verbose and provides instructions how to do this. Also, if user provided alternative address to be used to communicate with the firewall, the check for the management interface is not performed since it is not needed. * configlets/bsd/update_carp: see #2078 added verbose error message in a situation when "ifconfig carp0 create" command fails to create CARP interface. * OSConfigurator_bsd_interfaces.cpp (interfaceIfconfigLine): fixes #2058 "Ability to configure mtu and metric of regular inetrfaces". "Advanced settings" dialog of the interface object provides controls to configure MTU and possibly add any additional ifconfig parameters. This is available for OpenBSD and FreeBSD. 2011-02-10 vadim * NamedObjectsManagerPIX.cpp (getClearCommands): fixes #2060 "Existing configuration objects are not cleared in PIX 6.3". Commands used to clear object groups and objects have different syntax in PIX 6.3 and PIX 7 and later. * linux24/check_utilities: fixes #1999 "log() does not work" Using built-in utitlity "command" to verify that all the tools generated script needs to function properly are available and can be accessed either via direct full path or are in the PATH variable. This includes the check for the logger tool that is used to make log record when firewall is activated. * OSConfigurator_freebsd.cpp (interfaceConfigLineVlan): fixes #2071 "vlandev missing in the vlan definition (when using rc.conf.local )" * NATCompiler_ipt.cpp (getAddressTableVarName): fixed SF bug #3102044 "Colon in (runtime) Address Table name". Variable used to process addresses in the run-time address table should not use character ":" even if it appears in the Address Table object name. * instDialog_ui_ops.cpp (summary): fixed SF bug 3169045: "Batch installer lists IPv4 address as management address". The "summary" display in the installer progress log output will now show putty session name if it is used instead of the management address. * NATCompiler_pf.cpp (processNext): fixes #2069 "PF: allow multiple objects in ODst of redirecting nat rule". This fixes SF bug 3162862 "NAT - more than one object in original destination" * newFirewallDialog_from_template.cpp (replaceReferencesToNetworks): fixes #1979 "New firewall created with Cisco c36xx template results in network object in interface column in Policy" * ObjectManipulator_tree_ops.cpp (getTreeLabel): fixes #2067 "Add way to show interface label in object tree". The tree now shows interface name and label if the label is not empty. * configlets/bsd/update_vlans: fixes #2066 "Existing VLAN interfaces are not properly removed from FreeBSD and install script fails" 2011-02-09 Vadim Kurland * RuleSetView.cpp (showToolTip): fixes #1915 "tooltip shown when mouse is over rule number should be added to the list of suppressed tooltips when 'Advanced user mode' is in effect" * platforms.cpp (setDefaultFailoverGroupAttributes): fixes #2064 "CARP interfaces are not properly installed on FreeBSD cluster". I need to populate failover group objects with some reasonable defaults when they are created. * configlets/freebsd/installer_commands_root: fixes #2065 "activation commands on FreeBSD and OpenBSD lose script exit status". Sequence of commands ran by the built-in installer on *BSD firewalls were losing exit status of the script which meant installer always declared installation a "success" even when there were errors. 2011-02-08 vadim * SSHUnx.cpp (SSHUnx): fixes #2061 "Installer shows success for failed installed on FreeBSD due to corrupt script file". Added bunch of common shell error messages to make sure installer recognizes them and mark install as a failure even if ssh fails to pass termination code. * instDialog.cpp (showPage): fixes #2037 "If there is an error when compiling firewall then installer should be aborted". Compile/install wizard should disable "Next" button after compile phase is done if all firewalls failed to compile with no errors. * configlets/bsd/update_bridge: fixes #2042 "add configlet and shell functions to manage bridge interfaces via shell script on OpenBSD and FreeBSD". Bridge interfaces are managed incrementally, that is, the script creates and destroys them as needed, then adds or removes bridge ports, to bring bridge configuration in sync with what is defined in fwbuilder GUI. * CompilerDriver_pf_run.cpp (run): fixes #2054 "Add support for load anchor PF command". Instead of loading anchors using "pfctl -a anchor -f file" command in the .fw initialization script, now generated PF configuration uses "load anchor" commands in the pf.conf file. This way, we can load anchors correctly when PF configuration is activated from the generated rc.conf.local file where only one pf.conf file can be referenced. 2011-02-07 Vadim Kurland * CompilerDriver_pix_run.cpp (run): fixes #2055 "Compiler shows success, but there was a fatal error in the config". The bug has been introduced recently (in 4.2.0) and really affected all compilers. * AddressTableDialog.cpp (browse): fixes #1914 "Address table object file name is not created properly if user clicks outside Editor panel" 2011-02-06 vadim * SSHUnx.cpp (SSHUnx): fixes #2049 "Installer reports success even if there was an error while creating static routes". Added our own error message generated when command used to add static route fails to the list of error messages recognized by the installer. * OSConfigurator_freebsd.cpp (updateBridgeOfInterface): see #1889, #2043 Added support for bridge interface configuration in BSD. 2011-02-05 vadim * SSHUnx.cpp (SSHUnx): see #2039 "Installer reports success even if pfctl can't load config file". Added more pfctl error messages to the list to make code more robust. * CompilerDriver_pf.cpp (printStaticOptions): fixes #2038 "pfctl error when firewall settings include scrub option for reassembly". Command "scrub all reassemble tcp" does not allow direction. Tested and verified on OpenBSD 4.2 and FreeBSD 8.1 2011-02-04 vadim * freebsdInterfaces.cpp (manageIpAddresses): fixes #2032 "support for DHCP interfaces in rc.conf mode". Include dynamic interfaces inin the list of interfaces generated script manages when the script is in rc.conf format. This addds lines similar to 'ifconfig_em0="DHCP"'. 2011-02-03 vadim * RoutingCompiler_freebsd_writers.cpp (RoutingRuleToString): fixes #2026 Compiler can now generate static routing configuration in rc.conf format for FreeBSD. * pfAdvancedDialog.cpp (pfAdvancedDialog): fixes #2021 "since rc.conf format is only supported for FreeBSD, the option in the dialog should not be available for other OS" 2011-02-02 vadim * OSConfigurator_freebsd.cpp: see #1888 "Add option to generate rc.conf.local file for BSD systems". Added ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their ipv4 and ipv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF. 2011-02-01 vadim * CompilerDriver_files.cpp (determineOutputFileNames): See #2015 "Add support for setting names of generated .fw and .conf files separately for PF". Added second input field in the "advanced settings" dialog, tab "Compiler" for the firewall platform "PF". Now user can set the name for both the generated .fw initialization script and .conf PF configuration file, as well as names for both files on the firewall. Support for this is generic and the same functions work for other platforms if corresponding input field in the dialog exists. The name of the initialization script is set as follows: 1) if user provided -o command line switch to the compiler, its argument is used. 2) if -o switch was not present but the name was configured in the firewall settings dialog, it is used. 3) if none of them were present, the name is constructed from the name of the firewall object with suffix .fw. The name of the .conf PF configuration file is taken from the settings dialog, but if it is blank, then it is constructed from the name of the initialization script but with suffix .conf. 2011-01-31 Vadim Kurland * RoutingCompiler_bsd_writers.cpp (_printAddr): see #1890 "Add support for configuring static routes on BSD". Implemented support for simple static routing rules. ECMP and routing via interface (routing to directly reachable subnets) are not supported. Generated script preserves static routing entries that existed before and attempts to recover in case of error. Needs testing. 2011-01-30 vadim * FWWindow_editor.cpp (clearEditorAndSearchPanels): see #2006 "Crash when closing editor panel with find-and-replace". The GUI crashed if user tried to close editor panel at the bottom after closing objects+rules panel and while some object was still displayed in the editor. 2011-01-28 vadim * newFirewallDialog.cpp (fillInterfaceNZList): fixes #2000 "New dialog window in New Firewall wizard for ASA / PIX - Network Zone explanation". Added page to the new firewall wizard to let the user configure network zones of interfaces when chosen firewall platform supports network zones (only PIX/ASA right now). * newFirewallDialog.cpp (fillInterfaceSLList): fixes #1983 "ASA multiple interfaces have the same security level". Using table widget with spin-boxes to let the user edit security levels of interfaces conveniently. 2011-01-27 vadim * ProjectPanel.cpp (closeEvent): fixes #1998 "Crash after running find-and-replace then closing file". Specific sequence of actions and only on Mac OSX caused GUI to crash. To fix, I clear editor panel when user closes project window using MDI window title menu item "Close" or "Close" button. * ProjectPanel.cpp (registerModifiedObject): see #1996 "Crash when finding and replacing a large number of objects". When "find and replace" function was used to replace large number of objects in a rule set, it generated stream of calls to updateLastModifiedTimestampForAllFirewalls() which caused corresponding stream of events to update various parts of the GUI, both in the tree and rule set views. This caused weird corruption and crash on Windows. Trying to resolve the issue by optimizing the part that updated "last modified" timestamp on the firewall since all parts of the rule set updated in one call to "find and replace" function belong to the same firewall. * IOSImporterRun.cpp (run): see #1931 "Update failed import behavior". Added meaningful error messages for when policy importer fails to create firewall object or does not create interface objects or any rules. * Rule.cpp (removeRef): fixes #1997 "add removeRef and addRef methods to class NATRule". Now undo and redo correctly remove and restore references to NAT rule sets in NAT rules with action Branch. * Rule.cpp (addRef): fixes #1991 "Undo does not restore object as a parameter of policy rule action Branch or Tag after it was deleted deleted". Now Undo restores references to rule sets and tag services as arguments of corresponding policy rules, as well as references to objects configured as interface network zones. * Interface.cpp (removeRef): fixes #1987 "Deleting object that is used as Network Zone for ASA/PIX interface results in inconsistent behavior". When an object that is used as a network zone of an interface is deleted, it should be removed from the interface configuration as well. * Cluster.cpp (init): fixes #1995 "Crash when compiling a cluster with identical firewalls". Method Cluster::init() must call base class method Firewall::init() to get child Policy, NAT and Routing objects created. * CompilerDriver_pix_run.cpp (run): fixes #1994 "Crash when compiling a firewall in an imported Library". Compilers should reset any read-only flags in the copy of object tree they work with before they make any modifications. 2011-01-26 vadim * ProjectPanel_events.cpp (event): see #1994 "Crash when compiling a firewall in an imported Library". To prevent crash, added check to make sure firewall object is not read-only before an attempt to update its "last compiled" or "last installed" timestamp. * ProjectPanel_file_ops.cpp (fileExport): fixes #1993 "V4.2 on Windows - export Library shows the file type as Firewall Builder 2" * FWBSettings.h (SETTINGS_PATH_PREFIX): fixes #1992 " V4.2 on Windows - installer error can't find Secure Shell utility" * init.cpp (init): fixed #1989 "variables respath and librespath are redundant and copy Constants::getTemplateDirectory()". Got rid of global variables sysfname, tempfname, librespath, respath and localepath; will now use class Constants to keep this information. 2011-01-25 vadim * src/fwbuilder/libfwbuilder-config.h.in: fixes #1937 "RES_DIR macro is defined twice". Got rid of duplicate definition of this macro. * FWObject.cpp (updateNonStandardObjectReferences): see #1985 added virtual function updateNonStandardObjectReferences() that is supposed to update any references to objects stored as attributes. * ACL.cpp (trimLine): fixes #1986 "Cisco ASA remarks should be truncated to 100 characters or less". Trimming all lines used for access list remarks to <100 characters. Remarks can only be less than 101 characters on PIX/ASA and less than 100 characters on IOS. 2011-01-24 Vadim Kurland * PolicyCompiler.cpp (addMgmtRule): fixes #1966 "IOSACL: object-group can get name that consists of only suffix". Compiler generated object-group statements with names such as ".src.net.0" in some cases. * ObjectIconView.cpp (dragEnterEvent): see #1980 "Objects from Deleted Objects should not be allowed to be used in rules". Added checks to not allow drag&drop of an object from Deleted Objects library into rules and groups. * NamedObject.cpp (createServiceObjectCommand): See #1958 "consistently use "exit" to get out of nested context in pix config". Using "exit" to exit from nested context while adding network or service object in generated PIX/ASA configuraton. * PolicyCompiler_pix.cpp (compile): see #1970 "ASA Policy - single IPv6 icmp object allowed in rules". Since we do not support ipv6 for PIX/ASA at this time, policy compiler should drop the rule if ipv6 address or icmpv6 service is used and issue a warning. * PolicyCompiler_pix_v6_acls.cpp (processNext): see #1981 "ASA / FWSM Policy - Generate warning message if rule will not generate config data" 2011-01-22 vadim * ObjectManipulator.cpp (contextMenuRequested): context menu item that opens object in the editor should be named "Inspect" when the object is read-only because the editor would not allow the user to change it. * ObjectManipulator.cpp (contextMenuRequested): fixed #1926 "Crash when moving object in Standard library". Context menu item "Move" should be disabled when the object is located in the read-only library. * GroupObjectDialog.cpp (setupPopupMenu): see #1976 "Crash when deleting firewall object from rule after export / import library" Crash occurred as the result of the following sequence of actions in the GUI: 1) use context menu item "Cut" to delete an object in the tree, 2) open object group or rule and use context menu item "Paste" to add it, 3) export library to an external file, 4) import this library into different data file, 5) save the data file. Saved data file is invalid XML since it has unsatisfied reference and some operations on it cause crash. The problem is that since it is a reference to the object that is being added in case of both groups and rules, we end up with a group or rule with a reference to an object that is located in Deleted Objects library. Deleted Objects library is not included when a library file is merged into data file and this leads to a dangling reference. The fix is to not allow Paste if object in the clipboard has been deleted. * NamedObjectsAndGroupsSupport.cpp (saveObjectGroups): see #1968, #1972 Class NamedObjectsManager maintains its own copy of object tree that holds object group objects it creates during compiler passes. This allows me to maitain one common set of object groups for both policy and nat compilers and avoid creating duplicate and redundant object-group statements. * NamedObjectsManagerPIX.cpp (getClearCommands): see #1968, #1972 class NamedObjectsManager (and derived classes for IOS and PIX) generate "clear" commands. This way, I can generate correct set of "clear" commands that take into account any named objects and object-groups that could be created during both policy and nat compiler passes. 2011-01-21 vadim * FWObject.cpp (init): see #1972 Seaprated object creation and initialization. Some complex objects need to create a set of standard child objects. Previously this was done in a special type of constructor which required pointer to the object tree root (FWObjectDatabase*). This created problems with implementation of the method to register functions that create objects of new types outside of the API. Now all objects have just a basic set of constructors, plus method init() that can initialize them. * FWObjectDatabase_create_object.cpp (registerObjectType): see #1972 implemented mechanism that allows me to register new object types created and used outside of libfwbuilder API. This means FWObjectDatabase can then copy and manipulate object trees that use these new object types. 2011-01-20 vadim * NamedObjectsAndGroupsSupport.cpp (getNamedObjectsDefinitions): see #1963 "move printing of object-group definitions to NamedObjectManager::getNamedObjectsDefinitions()". Consolidated code that works with named objects and object groups in the class NamedObjectManager. This class manages all the objects and in the end generates commands. * PolicyCompiler_cisco (printClearCommands): Refactored parts that generate "clear" commands to make sure they are printed in the right order at the top of the generated configuration. Previously compiler placed "clear global", "clear static" and "clear nat" commands above the NAT section but below policy section. Since ASA8.3 nat commands can use named objects and object groups, and since I have added support for object groups in ASA 8.3 policy rules, I now need to clear objects and object groups at the very beginning of the generated config. However in order to be able to clear objects and object-groups, I need to clear access-lists and nat commands that might be using them first. So, all clear commands are now grouped at the beginning of the generated configuration. This affects pix/asa, iosacl and procurve_acl platforms. * NamedObjectsAndGroupsSupport.cpp (printObjectsForRE): See #1959 "ASA Policy - ranges are broken into composite network instead of using range command". I have to create named objects for address ranges and put them into an object-group, which I can then use in access-list commands. * PolicyCompiler_pix.cpp (compile): See #1965 "ASA Policy - PIX 6.1 configurations use object groups". Policy compiler for PIX is now aware that object-group statement was introduced in PIX v6.2 and avoids using object-groups when firewall object version is set to 6.1 * NamedObjectsAndGroupsSupport.cpp (processNext): made names automatically assigned to object-groups in generated PIX configuration shorter by removing interface label prefix. 2011-01-19 vadim * PolicyCompiler_pix.cpp (compile): See #1959 "ASA Policy - ranges are broken into composite network instead of using range command." Added support for address ranges using named network object with parameter "range" for ASA 8.3 and later. NOTE: if a network or ip address object is used in a nat rule for ASA 8.3, a named object has to be created for it since ASA 8.3 does not accept ip addresses or subnets in "nat" commands. In the situation like this, if the same address or network object is used in any Policy rule, the same named object will be used in the generated access-lists command. * NamedObjectsAndGroupsSupport.cpp (getNamedObjectsDefinitions): see #1959 Moved generation of the code that defines named objects to class NamedObjectManager. This allows me to put all named object commands on top of the generated policy, nat and routing configurations and make sure each object is defined only once. Still need to do #1963 - move code that generates commands to define object-groups to class NamedObjectManager. * NATCompiler_asa8.cpp (processNext): see #1954 "ASA NAT - generate warning if nat rule is split and one of the resulting nat rules have the same real interface and mapped interface". Compiler issues warning when objects used in OSrc and TSrc of a NAT rule make it use the same interface as both real and mapped interface in the generated nat command. This check is only done for ASA 8.3 NAT rules. 2011-01-19 Vadim Kurland * NamedObject.cpp (sanitizeObjectName): see #1953 "ASA NAT - two host objects in the same rule result in incorrect config". We now register and keep track of all named objects to make sure their names are unique. * newHostDialog.cpp (finishClicked): see #1953 "ASA NAT - two host objects in the same rule result in incorrect config". Objects that represent addresses of interfaces of a host object created using template will be automatically renamed to follow standard naming convention "host_name:interface_name:ip" to avoid creating duplicate names. * PolicyCompiler_pix_writers.cpp: see #1960 add support for CustomService for PIX policy rules. Note that CustomService objects are only supported in Policy rules since nat commands in ASA 8.3 require use of named objects and it is difficult to implement correct named objects and object-groups with protocol parameter and custom services. 2011-01-18 Vadim Kurland * PIXObjectGroup.cpp: ASA 8.3 see #1942, #1943 fixed generation of the "object-group" statements by adding protocol keyword at the end so that the group can be used in access-list commands. It looks like mixed service groups that have no protocol keyword at the end of the line that defines them cause error "specified object group has wrong type; expecting service type". I am going to avoid using mixed service groups because of this. 2011-01-17 vadim * ASA8TwiceNatLogic.cpp (getAutomaticType): fixes #1916 "nat rule must be "static" when subnet is present in TSrc" * ServiceRuleProcessors.cpp (condition): see #1942 improved support for CustomService objects for ASA 8.3. Generate separate named object and object-group for these objects, then split policy and nat rules so that only one custom service object is left in each rule and then use object-group to match it. Note: this has been rolled back. There is no support for CustomService objects in NAT rules. * PolicyCompiler_pix.cpp (processNext): fixes #1948 "incorrect configuration created when a CustomService object is used in a policy rule for PIX/ASA v<8.3". Since we do not support custom service objects in policy and nat rules for versions older than 8.3, added check to generate fatal error when such object is used. * NamedObjectsAndGroupsSupport.cpp (init): fixes #1945 "object-group names include ever-growing suffix". Object-groups created by the compiler for PIX/ASA had numerical suffix that was constantly increasing when user used single-rule compile function in the GUI. * PolicyCompiler_pix.cpp (compile): fixed #1944 "ASA Policy - duplicate network object groups created for mixed service group with TCP dst and TCP src port range objects". Need to convert address range objects to subnets early, before the rule is split for any reason, to make sure object groups created later match and are reused. * NamedObjectsAndGroupsSupport.cpp (processNext): See #1943 "ASA Policy - mixed service group with TCP destination port range and standard TCP object generates invalid config". Protocol word "tcp" was missing after "deny" in the generated rule. * NATCompiler_asa8.h (fwcompiler): see #1949 "ASA NAT - split objects if OSrc contains objects that are in more than one network zone". 2011-01-16 vadim * NamedObjectsAndGroupsSupport.cpp (processNext): Added support for CustomService objects in policy and nat rules for asa 8.3 using named objects and object-groups. -- see #1942 "ASA NAT - if custom service is included in service group incorrect config generated" -- see #1929 "move map named_objects inside class NamedObjectManager" -- see #1946 "restrict generation of the named objects by PolicyCompiler_pix to ASA 8" -- see #1885 "named network and service objects in pix8" Note: this has been rolled back. There is no support for CustomService objects in NAT rules. * NATCompiler_pix.cpp (processNext): see #1941 "ASA NAT - compiler complains about range in original destination". NAT rules translating destination allow Address Range objects in ODst or TDst for ASA 8.3 * NamedObject.cpp (NamedObject): see #1940 "ASA NAT - fwbuilder host objects interface ip is reserved keyword". Added list of reserved words used in IOS and ASA software to make sure generated named objects do not conflict. Will maintain single super-set of reserved words instead of separate set for each version of IOS and ASA. * PolicyCompiler_pix.cpp (compile): fixed #1938 "icmp" commands were not generated for ASA 8.x policy rules. * NATCompiler_asa8.cpp (processNext): See #1927. Added check for NAT rules that request translation of destination address but have ODst "any". This only applies to ASA 8.3; these rules are prohibited. 2011-01-14 vadim * NATCompiler_asa8_writers.cpp (printSDNAT): fixes #1932 "Add description field to generated NAT rules for ASA". NAT rules generated for ASA 8.3 and later will have "description" keyword added, with rule label as an argument. Rule label includes word "NAT" and rule number. * libfwbuilder/src/fwbuilder/InetAddrMask.cpp (getOverlap): fixes #1934 "libfwbuilder::getOverlap() incorrectly calculates overlap between ipv4 networks". This should also fix SF bug 3156376 "Can not find interface with network zone that includes address range". 2011-01-13 vadim * NATCompiler_asa8.cpp (compile): refs #1928 "Support for object-group in OSrc". Implemented support for object-group and named objects for Osrc and ODst in ASA 8.3 NAT rules. * PolicyCompiler_cisco.cpp (removeRedundantAddresses): fixed #1917 "Duplicate objects are not detected". Compiler should detect duplicate objects that may be created in a rule element when user combines Address Table object with other address or network objects there. * ASA8ObjectGroup.cpp (toString): refs #1885 Compiler uses named objects and objects groups to build configurations that use address ranges in TSrc in NAT rules. (only ASA 8.3 and later) 2011-01-12 Vadim Kurland * NATCompiler_asa8_writers.cpp (printSDNAT): refs #1907 "ASA NAT - fwbuilder doesn't support multiple translated sources in a single NAT rule". Compiler uses object-group to translate NAT rules that have multiple objects in Translated Source. * PolicyCompiler_pix_writers.cpp (_printLog): fixed #1913 "ASA/PIX rules with logging enabled don't have log set unless user modifies Firewall Settings". Added default log level setting to the resource xml file for platform "pix", set to "informational". ACL lines now get "log " keyword followed by the log level taken from the rule options, or if that was not configured, from the firewall object settings, or if that is not configured, the default. 2011-01-11 vadim * NATCompiler_asa8_writers.cpp (printSDNAT): refs #1908 "ASA NAT - cannot configure static NAT translations with (inside,outside)". Added NAT rule option to make source nat rules "static". The option is presented to the user as three radio buttons in the NAT rule options dialog which is only enabled when platform is "pix" and version >= 8.3. Policy compiler generates "twice nat" rules with keyword "static" in the following cases: when TSrc is "original", so the rule translates destination and not source or when numbers of ip addresses represented by OSrc and TSrc are equal. If TSrc is not "original" and represents different number of ip addresses than OSrc, compiler looks at the new rule option. User can use or override automatic algorithm using radio buttons in the NAT rule options dialog. * NATCompiler_asa8_writers.cpp (printSDNAT): refs #1902 "Add NAT rule option "translate dns" for PIX". The option is only available for ASA 8.3 or later. * NATCompiler_asa8_writers.cpp (printSDNAT): fixed #1909 "ASA NAT - static nat port translation where service is the same for original service and translated service not generated correctly" 2011-01-10 vadim * PolicyCompiler_pix.cpp (compile): fixed #1862 "fwb_pix crash". Compiler fwb_pix crashed when DNSName run-time object was used in a rule, but worked fine and issued an error when used in single-rule compile mode. * Helper.cpp (findInterfaceByNetzone): fixed #1906 "ASA NAT - Address objects are not properly identified by network zone and have the wrong real interface". The problem should have affected both "old" (PIX 6 and 7) and "new" (ASA 8.3) configuration. When an Address object was used in Original Source of a NAT rule, compiler used wrong interface in the (interfac1,interface2) pair in "nat" command. * CompilerDriver_pix_run.cpp (run): fixed #1905 "fwbuilder crash when compiling a rule with hosts folder as destination". Compiler issues a warning when an empty group object is used in a rule, but GUI crashed when user tried to compile this rule using single-rule compile function. The change actually affects all policy compilers and makes sure the GUI catches exception and does not crash, and prints any errors generated by the compiler in the compiler output panel when single-rule compile function is used. * CompilerDriver_ipt.cpp (findBranchesInMangleTable): fixed #1879 "gui crash". Both GUI and fwb_ipt crashed trying to compile a rule with action Branch that was not configured to point to any rule set. 2011-01-07 vadim * NATCompiler_pix.cpp (NATCompiler_pix): fixes #1901 "add destructor to NATCompiler_pix and NATCompiler_asa8". This eliminates memory leak. * ASA8Object.cpp (ASA8Object): refs #1885 "named network and service objects in pix8". So far, these objects are only used for nat configuration. * NATCompiler_asa8_writers.cpp (processNext): fixes #1903 "correct order of clear commands for ASA 8.3" * NATCompiler_asa8_writers.cpp (printSDNAT): refs #1886 "new nat configuration in pix 8.3". Initial support for new style nat configuation. 2011-01-04 vadim * platform/fwsm.xml: FWSM v4.x does not have "fixup" command, instead, we should use policy-map and class commands. * OSConfigurator_pix_os_inspectors_pix8.cpp (_printPolicyMapTypeInspect): refs #1893 fixes #1883 "inspect ip options in pix8". Added support for "policy-map type inspect ip-options" command in PIX v8.2 and later. At this time, of all possible types of "policy-map type inspect" command only "ip-options" is implemented. * PIX8ObjectGroup.cpp (toString): refs #1882 "Mixed service groups in PIX8". Added pix versions 8.0 and 8.3; added support for mixed servcie groups in pix 8.0 and later. * PolicyCompiler_srvre_functions.cpp (processNext): fixed #1892 "move rule processor class separateServiceObject to PolicyCompiler". This rule processor used to be implemented only in the compiler for PF, but since it has very general meaning, the same function was duplicated in other compilers as well. Moved the class to libfwbuilder and reimplemented several other rule processors to inherit from this class to avoid further duplication for code. * PolicyCompiler_pix.cpp (compile): fixed #1891 "problems with TCP and UDP services with source ports". Policy compiler for PIX did not generate correct PIX ACL lines when one Policy rule tried to match several TCP and/or UDP objects matching source ports. 2010-12-29 vadim * VERSION (VERSION): started 4.2.0 This version is the first one to merge libfwbuilder and fwbuilder packages. Libfwbuilder is now in the src/libfwbuilder subtree inside fwbuilder code tree. RPM .spec files and DEB .control files are now located in the packaging directory inside fwbuilder code tree. Changes in the versioning format: I am going to use build number as a "nano" version number, composing complete version as "4.2.0.3425". The "-N" suffix in rpm and deb package names will be used for package release number and most of the time will be "-1". This suffix should reflect minor differences in the package that do not affect code at all. 2010-12-16 Vadim Kurland * ActionsDialog.cpp (fillInterfaces): fixed #1872: "vlan interface does not appear in the list of interfaces for route-to action for PF". 2010-12-12 Vadim Kurland * VERSION (FWB_MICRO_VERSION): started 4.1.4 2010-12-05 Mike Horn * minor updates to main help dialog text to fix broken/outdated links 2010-12-02 Vadim Kurland * OSConfigurator_linux24.cpp (OSConfigurator_linux24::getInterfaceVarName): fixed #1856 "Pemit '-' in Linux interface names". OpenWRT uses name "ppp-dsl" for PPPoE interfaces. In addition to that, Linux bridge interfaces may have names with a "-" such as "br-lan". We will now permit a "-" in Linux interface names. * FWWIndow.cpp: Fixes #1858 'Remove "Summary of features" page from the package' and #1857 'Remove "Getting Started" guide from the package'. We have dediced to keep documentation and other content like this on the web site. Button "Watch Getting Started Tutorial" in the Tip of the Day dialog opens tutorial hosted on the web site in a web browser. 2010-11-16 Vadim Kurland * check_utilities: fixed #1851 "no need to check for modprobe when host OS is "dd-wrt" and possibly other embedded Linux systems". Generated script does not use modprobe utility when host OS is set to "DD-WRT" or "OpenWRT" and should not try to find this utility on the system. This is also related to the SourceForge bug 3032293 2010-11-16 Vadim Kurland * newclusterdialog_q.ui: fixed #1848 Text formatting clean up - New cluster wizard dialog 2010-11-15 Vadim Kurland * InetAddr.cpp (InetAddr::opGT): (change in libfwbuilder) added module uint128 (128-bt arithmetics by Evan Teran). Implemented basic operations with ipv6 addresses using this module. See #1834. Now all policy compilers can correctly compare ipv6 addresses used in rules with ipv6 addresses of interfaces. This helps perform various optimizations and fixes issues with the algorithm used to pick the right interface for the Cisco IOS ACL compiled from a policy rule with an empty "interface" rule element and direction "both". 2010-11-11 Vadim Kurland * newClusterDialog_create.cpp (copyRuleSets): Fixed SF bug #3106168 "Branch destinations lost when adding to cluster". Since the order in which I copy rule sets is undefined and because they may have references to each other via branching rules, I need to fix references after I create all of them. * configlets/linux24/load_modules: fixed #1844 "generated script fails if module nf_conntrack_ipv6 does not exist". Generated script tries to load module nf_conntrack_ipv6 if user defined any ipv6 rules, however the script should not fail if the module is not installed. * src/gui/gui.pro (LIBS): fixed #1840: fixed build on Mandriva 2010, all static libraries should go first on the linker command line. 2010-11-10 Vadim Kurland * NATCompiler_ipt.cpp (processNext): fixed SF bug 3103582 "Cant create redirect rule in cluster firewall object". Iptables nat rule with target REDIRECT could not be built in a cluster configuration. It should be possible to do this by putting cluster object in Translated Destination. * OSConfigurator_linux24_interfaces.cpp (printDynamicAddressesConfigurationCommands): fixed #1838 "function configure_interfaces() does not manage ip addresses of vlan interfaces". This function used to take into account only interfaces that were direct children objects of the firewall. Since vlan interfaces are children of the corresponding physical interface, they were not included. * FirewallInstaller.cpp (getGeneratedFileFullPath): fixed #1837 "generated script gets .fw suffix even when user set output file name". Suffix .fw should not be appended to the name entered by the user in the "output file name" input field in the firewall settings dialog. * PolicyCompiler_ipfw_writers.cpp (processNext): fixed #1836 "installer hangs and fails after activation of ipfw policy". As soon as .fw script swapped ipfw sets usig command "ipfw sawp" and deleted temporary set 1, ssh session would hang and eventually break. We optionally add ipfw rules to permit ssh session used to manage the firewall, as well as a rule to permit reply packets but the latter rule was not built correctly. It should match source and destination reversed, as well as match keyword "established" and recreate state with "keep-state". This rule automatically recreates state for the established ssh session over which firewall policy is being managed. Also added a comment to the firewall settings dialog for ipfw to remind the user that address or subnet they use with this automatic rule should be as narrow as possible. * instOptionsDialog.cpp (instOptionsDialog): see #1832 if user wants to use putty session, show session name instead of the ip address in the "Address that will be used to communicate with the firewall" input field in the installer options dialog. 2010-11-09 Vadim Kurland * Helper.cpp (Helper::findInterfaceByAddress): see #1834 Fixed matching algorithm that determins which interface a rule should be associated with for Cisco IOS ACLs. Previously compiler did not compare subnets properly and because of that it interpreted some configurations incorrectly. For example in the case with a network object 10.0.0.0/8 in "source" and an interface with address 10.0.0.1/24 (network should not be considered matching) compiler considered this interface matching and assigned the rule to the interface only with direction "inbound". * FirewallInstaller.cpp (FirewallInstaller::packSCPArgs): see #1832 pscp.exe supports putty session in place of the target name but not if argument "-load session_name" is also present. Plink.exe does the same. We can not use fwb_session_with_keepalive if user wants to use putty session. 2010-11-08 Vadim Kurland * FirewallInstaller.cpp (FirewallInstaller::packSCPArgs): See #1832, SF bug 3097419 "installer uses bare IP address instead of putty session name". It appears pscp.exe on Windows can use putty session name in place of the host name. This change restores old behavior where session name was used like that but does it for both plink.exe and pscp.exe. This only affects users who run fwbuilder GUI on Windows 2010-11-05 Roman Bovsunivskiy * see #1809 "Add Firewall Setting in Logging settings for default log setting on new rules". Added a tab "Policy Rule" to the "Objects" page of the global preferences dialog; checkbox in this tab allows the user to choose whether new policy rules should be created with logging turned on or off. 2010-11-04 Roman Bovsunivskiy * see #1826 "Please place all unit tests in one directory". All GUI and other unit tests moved to the directory src/unit_tests 2010-11-03 Roman Bovsunivskiy * code refactoring: see #1822 "refactor all GUI classes into libgui library and link executable with it" * see #1787 "new fw name input field should have focus when new firewall wizard opens" * see #1823 "Add Preference option for Advanced / Power users". Added checkbox to the Preferences dialog, this checkbox turns off some tooltips that can be annoying for users who are sufficiently familiar with the GUI 2010-11-02 Vadim Kurland * OSConfigurator_linux24_interfaces.cpp (printVerifyInterfacesCommands): fixed #1824 "should not try to verify wildcard interfaces". 2010-11-01 Vadim Kurland * CompilerDriver.cpp (CompilerDriver::getAbsOutputFileName): fixed SF bug 3090249 "fwb_ipt ignores -d option ". Documented behavior is for the compiler to create files in the directory specified by the argument of the "-d" command line flag. If flag "-d" is not provided, files should be created in the current directory. 2010-10-29 Vadim Kurland * PolicyCompiler_ipt.cpp (checkForStatefulICMP6Rules::processNext): fixed SF bug 3094273 "no state needed for ipv6-icmp in ip6tables". Rules that match ICMPv6 objects should be stateless. Compiler will check for this and reset "stateful" flag of a rule and issue warning if the rule was built stateful in the GUI. This could be version-dependent, we may need to revisit this in the future when netfilter fixes the underlying issue. Some resources: https://bugzilla.redhat.com/show_bug.cgi?id=243739 https://bugs.launchpad.net/ubuntu/+source/iptables/+bug/479105 * src/res/objects_init.xml.in: added ICMPv6 object "parameter problem" (type 4, any code) per SF feature request 3094743. Also added service group object "ipv6 unreachable messages" that includes ICMPv6 messages "destination unreachable", "packet too big", "parameter problem" and "time exceeded" per SF feature request 3094758 * configlets/linux24/automatic_rules: implemented SF feature request 3094738 "Set the HL to 255 for IPv6 Neighbor Discovery". Neighbor discovery packets must have hop limit of 255 per RFC 2461. Automatically generated rules that match neighbor discovery packets will math hooplimit 255. * configlets/linux24/update_addresses: fixed SF bug 3091069: "Routing configuration failed". Iptables script generated by fwbuilder did not configure broadcast when it added ip addresses to interfaces. Using "ip addr add ADDR/NM boradcast + dev INTF" syntax to do this. * OSConfigurator_bsd.cpp (compare_names): fixed #1807 "wrong order of address assignment in the generated OpenBSD/PF/CARP cluster configuration". Need to assign ip addresses to regular interfaces before trying to assign them to carp interfaces. * configlets/linux24/load_modules: fixed #1820 "skip module "nf_conntrack_ipv6" if generated script has no ipv6 rules" Shell function load_modules should not try to load module nf_conntrack_ipv6 if generated script does not load any ipv6 rules. Loading this module fails if ipv6 has been disabled in the kernel. 2010-10-29 Vadim Kurland * run_time_wrappers: fix for the SF bug #3095615 "reopen no PREROUTING rule with *-Interface - ID: 3077132". Configlet used wrong shell variable to access ip address of a wildcard interface. * VERSION (FWB_MICRO_VERSION): started 4.1.3 2010-10-07 Vadim Kurland * configlets/pix_os/installer_commands_reg_user: using command "terminal width 256" to turn off ANSI commands in the PIX command echo. * FindObjectWidget.cpp (showObject): rolled back change done in r3320 (refs #1790) "When an object is found using Find and the object is in the object tree, the keyboard focus shifts to the Object Panel". That change broke highlighting of the found object in rules. * refs #336 "Need template for PIX firewall"; added template for PIX 50X (501 and 506) 2010-10-06 Vadim Kurland * FWWindow.cpp (FWWindow::showIntroDialog): fixed compile problem with old Qt (v < 4.5.0). * FWWindow.cpp (FWWindow::showIntroDialog): See #1765, #1779 Will show a dialog inviting the user to watch Quick Start Guide on the web site when they run the GUI for the first few times. The dialog is shown instead of the Time of the day dialog. Switching to the tip of the day after 5 starts. * RoutingCompiler_pix.cpp (emptyRDstOrRItf::processNext): fixed #1783 "PIX routing entries require interface, but PIX config will compile without interface in Routing rule". Policy compiler for PIX now checks that both "interface" and "gateway" rule elements are not empty. 2010-10-05 Vadim Kurland * OSConfigurator_linux24.cpp (printRunTimeWrappers): fixed SF bug 3077132 "no PREROUTING rule with *-Interface". Rules matching addresses of a wildcard interface (e.g. "ppp*") were not properly generated. * RuleSetView.cpp (updateSelectionSensitiveActions): fixed SF bug 3039681 "context-menu items inconsistent for Single/Multiple rules". When several rules are selected in rule set, some context menu itmes should turn to plural. * FWWindow.cpp (prepareRulesMenu): fixed #1778 "main menu Rules should have the same items that context RuleSetView menu when no rules are selected" 2010-10-04 Vadim Kurland * ObjectManipulator.cpp (showObjectInTree): fixed #1777 "scroll new fw object to the top of the tree view panel once its created" This has side effect in that some other operations that open an object in the tree will also sc roll the tree to position this object at the top. * FWBSettings.cpp (setCustomTemplatesEnabled): fixed #1791 "Add preference flag to enable / disable the Custom templates button on the New Firewall Wizard". Use of the custom template library to create new firewall object is now optional, controlled by a checkbox in the "Object" tab of the gobal preferenes dialog. New users will have this option turned off by default, however existing users will see it enabled for backwards compatibility. * FindObjectWidget.cpp (showObject): fixed #1790 "When an object is found using Find and the object is in the object tree, the keyboard focus shifts to the Object Panel". The "find" pabel now retains keyboard focus after it shows found object in the tree, this allows the user to just hit Enter on the keyboard to find the next object. * FindObjectWidget.cpp (objectDeleted): fixed #1785 "Deleting graphic icon of object from Find tab should also remove the text name or label" * newFirewallDialog.cpp (changed): fixed #1770 Eliminated pause that happened when user switched from page 0 to page 1 of the new firewall wizard. Pause was caused by the DNS queries the program ran trying to determine ip address of the firewall using the name provided on the first page of the wizard. Now DNS query is launched only if user wants to create interfaces uses snmp scan. * InterfaceEditorWidget.cpp (InterfaceEditorWidget): fixed #1772 improved design of the widget used to edit ip addresses and other attributes of an interface in the new firewall, new host and new cluster wizards. Removed "MAC Address" imput field and rearranged other input fields according to the result of usability tests. * SSHCisco.cpp (SSHCisco): fixed #1784 added Cisco ASA (PIX) error message "cannot add route entry" to the list of errors that built-in installer recognizes and marks install process as "Failure". * newFirewallDialog.cpp (showPage): fixed #1767 improved UI in the new firewall and new host dialogs where user chooses file for the custom template library or uses standard template library. 2010-10-03 Vadim Kurland * ObjectManipulator_create_new.cpp (ObjectManipulator::createNewObject): fixed #1776 once new firewall is created, automatically open its Policy * FWWindow.cpp (FWWindow::showIntroDialog): fixed #1765, #1779 Move quick start guide to the web site. The "Quick Start Guide" is now part of the web site and the GUI only shows a dialog-invitation to watch it. 2010-10-01 Vadim Kurland * FWBSettings.cpp (getABTestingGroup): fixed #1763 Implemented basic facility for A/B testing within the GUI 2010-09-30 Vadim Kurland * FindObjectWidget.cpp (keyPressEvent): fixed #1755 "hitting enter after editing search attribute in the Find panel should trigger search" * FindObjectWidget.cpp (matchAttr): fixed #1760 'Search by attribute "name" should search by name or label'. * FindObjectWidget.cpp (objectInserted): fixed #1757 Allow searching by attributes even after an object is dropped into the drop area in search panel. * newFirewallDialog.cpp (browseTemplate): fixed #1759 "Use default template library" button seems to do nothing. This button should only be enabled if user switched to their own library of template objects. The button should be disabled if they switched back to the standard template library or never switched to their own one. * newHostDialog.cpp (finishClicked): fixed #1761 "blank interface name is possible in new host wizard" * FWObjectPropertiesFactory.cpp (getInterfaceNameExamplesForHostOS): fixed #1753 "Set interface name hint based on firewall platform and host OS". The placeholder text in the interface name and label input fields in the new firewall wizard will depend on the host OS chosen in the first page of the wizard. * utils.cpp (validateName): fixed #1751 "Don't allow interface names to be blank". The GUI should not allow the name of any object to be blank. 2010-09-29 Vadim Kurland * ProjectPanel.cpp (ProjectPanel::inspect): fixed #1718 "Inspect generated files" dialog says "Multiple firewalls" even when there is only one * InterfaceEditorWidget.cpp (InterfaceEditorWidget::InterfaceEditorWidget): added "placeholder" text to the interface name and label input fields. This text is displayed in greyed-out small font inside the imput field but is cleared as soon as user starts their input. The text gives user a prompt as of what is expected in each input field. The "placeholder" text support is available only in Qt 4.7 and later so the code is conditional on the version of Qt. * WorkflowIcons.cpp (WorkflowIcons::openTutorial): fixed #1733 "Add button for video tutorial link". Shortcut button "Watch Getting Started Tutorial" opens page with video tutorials in the standard browser. * InterfaceEditorWidget.cpp (InterfaceEditorWidget::isValid): fixed #1746 "Force user to change interface name in New Firewall wizard". When user creates interfaces for the new firewall or host using manual method and clicks on the "+" button to add a tab for the new interface in the wizard page, the interface tab is created with blank name. Wizard later checks the name when user clicks Finish to create new firewall or host object and does not let them do this while interface name is still blank. Error dialog reminds that the name of the interface must match the name of the interface on the machine. * ProjectPanel.cpp (ProjectPanel::updateFirewallName): fixed #1745 "Remove path data from text above rules window that shows firewall name". 2010-09-28 Vadim Kurland * ObjectManipulator_create_new.cpp (reminderAboutStandardLib): refs #1748 "Add dialog about Standard Library when user creates first Service object". First time users will see an informational dialog reminding them about the Standard objects library when they create their first service object. 2010-09-27 Vadim Kurland * src/gui/Tutorial/introduction/html/page0.html: refs #1737 Added "Quick Start Guide" tutorial that demonstrates basic features and key concepts of Firewall Builder. The tutorial is accessible via Help / Tutorials menu and is shown to the first-time user on the GUI startup instead of the "tip of the day" dialog. * FWObjectPropertiesFactory.cpp (getObjectPropertiesDetailed): system folders in the tree now have tooltips that explain what kind of objects belong there. * RuleSetView.cpp (showToolTip): Added text to the tooltips shown for the "Direction" and "Action" rule elements to remind user that to change these rule parameters they need to click right mouse button to open list of possible settings * RuleSetView.cpp (showToolTip): fixed #1744 "Add tooltip to the rule number". The column in the RuleSetView? where rule number is shown now has a tooltip to remind the user that they can click right mouse button to the the context menu and use keyboard shortcut "x" to compile the rule * FWBSettings.cpp (init): fixed #1743 "change default for the option 'Show text descriptions for direction and action'". The option should be on by default. * RuleSetView.cpp (showToolTip): fixed #1730 "Add background help text and images to empty policy window". Showing tooltip in the empty space in the rule set view, this tooltip provides hints on how to edit rules which should be useful for the beginners. 2010-09-26 Vadim Kurland * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed #1741 "there is no way to undelete a library object". * FWCmdMoveObject.cpp (FWCmdMoveObject::notify): fixed #1740 "Deleted library remains in the drop-down list". If option "Show deleted objects" was turned off in the Preferences dialog and user deleted a library, it remained in the drop-down list of libraries and its object tree was still displayed in the object tree panel. * listOfLibrariesModel.cpp (ListOfLibrariesModel::addStaticItems): fixed #1728 "Update Library drop down menu". Library drop down list shows an item "Object libraries:" at the top that can not be selected and that always stays on top as libraries are added, removed and renamed. The list always stays sorted in ascending order. Library names are indented by 2 spaces to make them visually distinguishable from the prompt item at the top. Implementation uses class ListOfLibrariesModel that inherits QStringListModel. * PrefsDialog.cpp (PrefsDialog::PrefsDialog): fixed #1739 "remove "tooltip delay" input form preferences dialog". Qt4 does not allow for changing tooltip delay. 2010-09-24 Vadim Kurland * RuleSetView.cpp (itemDoubleClicked): refs #1731 Change double-clicking on "Any" object behavior. Double click on "any" in a rule does not try to open object "any" in the tree and editor panel. * FWObjectPropertiesFactory.cpp (getObjectPropertiesDetailed): refs #1731 Change double-clicking on "Any" object behavior. Tooltip shown for the object "any" in rules says "to modify the rule drag and drop an object from the tree here" instead of atributes of the object "any". * FWBSettings.cpp (init): fixed #1738 "Enable tooltips by default" * ObjectManipulator.cpp (editSelectedObject): fixed #1729 "double clicking a folder in the tree should expand it rather than open it in the editor". * ObjectTreeView.cpp (edit): fixed #1732 "Double clicking on object with child objects should auto expand them". Double clicking on objects and folders in the tree expands and collapses them, as well as opens object in the editor. * ObjectManipulator.cpp (expandObjectInTree): fixed #1715 "automatically expand new firewall and new host objects in the tree once they are created" * configlets/linux24/check_utilities: fixed #1714 "make checking for MODPROBE conditional". There is no need to check if modprobe utility exists on the firewall machine if it is not used by the script. 2010-09-22 Vadim Kurland * instDialog_ui_ops.cpp (instDialog::readInstallerOptionsFromFirewallObject): fixed #1724 . There was a problem with pscp.exe and putty sessions. Plink.exe accepts session name in place of the host name on the command line, but pscp.exe does not. We ask user to enter session name in the "alternative name or address to use to communicate with the firewall" input field in the "Installer" tab of the firewall settings dialog and then use it in place of the host name in the command line for pscp.exe and plink.exe. This works with plink.exe but breaks pscp.exe which interprets it as a host name and fails with an error ""ssh_init: Host does not exist". The fix checks if what user entered in the "alternative host or address field" is a session name and uses different command line with pscp.exe 2010-09-20 Vadim Kurland * NATCompiler_ipt.cpp (compile): fixed SF bug #3071667 "Compilation segfault with DNS address in NAT rule". Added rule processors to replace Run-time DNSName and Address Table objects in TSrc and TDst. 2010-09-16 Vadim Kurland * SSHSession.cpp: Refs #1699 installation session status was reset from "failure" to "success" in a configuration where fwbuilder gui was running on Windows and talked to Cisco router using pscp.exe and plink.exe and ssh session failed because of authentication failure. This happened because plink.exe terminated with return status "success" even in case of authentication failure. * generatedScriptTestsIpfilter.cpp (GeneratedScriptTest::runCompiler): unit tests to test manifest and activation commands in the generated .fw script for ipfilter. Refs #1702 * FirewallInstaller.cpp (FirewallInstaller::getGeneratedFileFullPath): fixed how we append suffix ".fw" to the name of generated script when it is preconfigured in the firewall settings dialog and already includes ".fw" suffix (it was added twice). * CompilerDriver_ipf_run.cpp (CompilerDriver_ipf::run): fixed #1702 "Wrong path in the activation script for ipfilter". Activation command embedded in the generated .fw script used local path to the generated .conf file on the machine where fwbuilder compiler was running. 2010-09-14 Vadim Kurland * FirewallInstaller.cpp (getGeneratedFileFullPath): fixed SF bug 3049665 "Firewall Settings -> Output file name misses .fw extension" * CompilerDriver_ipt_policy.cpp (processPolicyRuleSet): fixed #1707 "call function "prolog_commands" from the main iptables script part instead of function "script_body" when prolog should be executed after iptables reset" * configlets/linux24/script_skeleton (cmd): fixed SF bug 3060325 "Address table object and prolog script conflict". Generated script should run prolog before checking and loading run-time address tables. * NATCompiler_PrintRule.cpp (processNext): fixed SF bug 3057503 "DNAT rule with dynamic IP has a white space, causing error". * PolicyCompiler_PrintRule.cpp (_printIpSetMatch): fixed #1705 "iptables (v>=1.4.4) "--set option deprecated ..." (SF bug 3059893) Option "--set" has been deprecated and renamed "--match-set" in iptales 1.4.4 * CompilerDriver_pf.cpp (printPathForAllTools): fixed SF bug 3061034 "ifconfig definition missing". Script generated for the ipfw firewall on Mac OS X missed definition of variable IFCONFIG. 2010-09-13 Vadim Kurland * IPTImporter.cpp (addPktTypeMatch), iptables.g: fixed #1703 "importing iptables line with module pkttype causes parser error". We do not have any object with the behavior closely resembling that of iptables module "pkttype" so the importer creates CustomService object with the code taken from the original iptables rule. SF bug 3065435 * VERSION (FWB_MICRO_VERSION): started 4.1.2 2010-08-20 Vadim Kurland * v4.1.1 released 2010-08-19 Vadim Kurland * NATCompiler_ipt.cpp (splitNATBranchRule::processNext): fixed #1686 "can not generate basic NAT branching rule". NAT branching rules were not generated in single rule compile mode because compiler needs information about targets used in the branch rule set rules to decide which chain the branching rule should be placed in. Now it will use PREROUTING and POSTROUTING in single compile mode but issue a warning. * NATCompiler_ipt.cpp (VerifyRules2::processNext): fixed #1685 "iptables redirecting NAT rules in the OUTPUT chain". NAT rules should be allowed to translate from CustomService to TCP or UDP service, provided CustomService object is configured with matching protocol. See also change in libfwbuilder NATCompiler::classifyNATRule::processNext. * NATCompiler_ipt.cpp (localNATRule::processNext): see #1685 "iptables redirecting NAT rules in the OUTPUT chain". This fix makes it possible to create iptables NAT rule with target REDIRECT in the OUTPUT chain. The rule should have firewall object in OSrc and TDst rule elements. * NATCompiler_PrintRule.cpp (PrintRule::processNext): fixed #1693 SF bug 3048516 "NAT rule with 'Use SNAT instead MASQ' doesn't work". NAT rule using combination of the option "Use SNAT instead of MASQ", dynamic address of an interface and source port translation produced iptables command with incorrect syntax. 2010-08-18 Vadim Kurland * Helper.cpp (list): fixed #1691 , this is a better fix for the problem reported in the earlier bug (see #1690). Function Helper::findInterfaceByNetzone() throws FWException, this changed in v4.1.0 with a fix for #1653. 2010-08-17 Vadim Kurland * procurveInterfaces.cpp (procurveInterfaces::parseVlan): fixed #1683 class procurveInterfaces interprets interface "DEFAULT_VLAN" as vlan interface with vlan id 1. * newFirewallDialog.cpp (newFirewallDialog::finishClicked): fixed #1683 When user creates new firewall using snmp scan, fwbuilder will now guess and assign the type to interfaces that look like vlans for the given platform and host OS. * safety_net_acl: fixed #1687 "temporary access list commands syntax is incorrect". Temporary ACL generated for the Procurve platform was incorrect. * PolicyCompiler_cisco.cpp (PolicyCompiler_cisco::setAllNetworkZonesToAny): fixed #1690 "IOS ACL and Procurve ACL compilers fail because interfaces are not assumed to have network zone "any" anymore". Compilers for Cisco IOS ACL and Procurve ACL always assumed all interfaces have network zone "any". Recent changes made in 4.1.0 changed that and compilers stopped working for some rule configurations. * (PolicyCompiler_cisco::createACLObject): fixed #1688 "Procurve ACL remarks should be in quotes if they include space" 2010-08-14 Vadim Kurland * FirewallInstallerProcurve.cpp (FirewallInstallerProcurve::packInstallJobsList): Policy installer for HP Procurve. Currently only works in line-by-line mode (no support for scp). Tested with Procurve firmware K14.31 on ProCurve J9470A Switch 3500-24. Caveat: manager access should not be configured with user name (that is, no "password manager user-name foo") * set version to 4.1.1 2010-08-10 Vadim Kurland * v4.1.0 released 2010-08-08 Vadim Kurland * ObjectManipulator_ops.cpp (ObjectManipulator::actuallyDeleteObject): fixed #1674 "Crash while using Undo Stack". Operation "Cut" should be represented by an undo macro object and should appear as one operation on the undo stack. * ObjectManipulator.cpp (ObjectManipulator::getMenuState): fixed #1676 "Crash when deleting an interface that has multiple IP addresses and not all addresses are selected for deletion" 2010-08-06 vadim * ObjectManipulator_tree_ops.cpp (ObjectManipulator::clearObjects): fixed crash that happened on Mac if the GUI was started with a file name as command line argument. The issue was introduced recently when GUI state update was reimplemented as an event. 2010-08-05 Vadim Kurland * ProjectPanel_events.cpp (event): fixed #1660 "Crash when cut-and-pasting firewall between libraries". GUI crashed if user performed the following sequence: cut an object, switch to a different object library, try to paste using keyboard shortcut Ctrl-V while library object was selected in the tree. 2010-08-04 Vadim Kurland * IPTImporter.cpp (IPTImporter::finalize): fixed #1664 "Policy import creates firewall object w/o version". This also fixes crash reported in SF bug #3036934 * pixAdvancedDialog.cpp (pixAdvancedDialog::displayCommands): fixed SF bug #3038945 "ASA inspect configurations not saved". Under some circumstances the GUI did not save changes made in the "Inspectors" tab of the PIX advanced settings dialog into the object. * ObjectManipulator_tree_ops.cpp (ObjectManipulator::removeObjectFromHistory): fixed #1661 "Crash after deleting firewall" a sequence where user deleted an object and then hit "Back" button caused crash. 2010-08-03 Vadim Kurland * pixAdvancedDialog.cpp (pixAdvancedDialog): fixed SF bug #3038948 "ASA logging severity levels are incremented". Log levels in the "Logging" tab of the PIX firewall advanced settings were incremented every time user opened the dialog and then clicked OK. * PolicyCompiler_PrintRule.cpp (_printIP): fixed SF bug #3038636 @v4.1b, "iptables v1.4.8: unknown option `--ra'". Ipv4options module has changed in iptables 1.4.3 and now accepts different set of parameters. Policy compiler generates new parameters if user set version in the firewall object dialog to "1.4.3 or later". 2010-08-02 Vadim Kurland * InterfaceDialog.cpp (loadFWObject): fixed #1657 "When no network zone is defined on the interface, the Interface object editor says it is "Any" which is a lie" * configlets/linux24/run_time_address_tables: fixed #1652 "support for adding single address to address table in the generated script". Generated iptables script now provides functions "add_to_address_table", "remove_from_address_table" and "test_address_table" that let administrator add or remove single ip address to a given address_table. * OSConfigurator_linux24.cpp (printRunTimeAddressTablesCode): fixed #1654 "Support for run-time Address Tables with empty file in iptables". This is an implementation of the same feature we already have for PF. If the file name in the configuration of the run-time Address Table object is blank, policy compiler generates firewall configuration that uses ipset with the name the same as the name of the object but does not generate code to load addresses from a file into it. All control of the ipset is left for the user. * Helper.cpp (findInterfaceByNetzone): fixed #1653 "Crash when compiling a rule for Cisco PIX with incorrect network zone". 2010-07-29 Vadim Kurland * instDialog_installer.cpp (instDialog::installerSuccess): fixed #1639 "Add success message to the bottom of the process log for the installer". Added a message to the installer log to display installation status. * stop_action: "stop" action should reset ipv4 iptables configuration only if firewall object configuration defines any ipv4 rules. This is how generated script works for ipv6; behavior for ipv4 and ipv6 should be similar. Fixes SF bug #3036541 "IPV6 only firewall resets ipv4 stack" * script_skeleton (cmd): added action "block" to the "usage" string of the generated iptables script 2010-07-28 Vadim Kurland * PolicyCompiler_ipt.cpp (checkActionInMangleTable::processNext): fixed SF bug 3034628 "iptables does not allow target REJECT in mangle table". Iptables does not support target REJECT in mangle table. Added check to the policy compiler to make it detect this situation and issue an error. * FWWindow.cpp (FWWindow::compile): fixed SF bug 3035426 "canceled save writes .fwb ". The program created file with name ".fwb" if user started with an empty project paje, created some objects, then hit "Compile" but then clicked "Cancel" when offered a chance to save objects into a new data file. * CompilerDriver.cpp (CompilerDriver::_findImportedRuleSetsRecursively): fixed #1631 "Process branch rule sets recursively". Policy compilers used to look only one level deep while processing branching rules. They should allow for arbitrary nesting and correctly avoid infinite loops if user creates looped branches. Compiler issues a warning when it detects looped bracnhing. This fixes SF bug 3033462 "nested shared branch rules between servers not working". * UsageResolver.cpp (UsageResolver::findWhereUsedRecursively): fixed #1632 "dependencies created by branching rule sets should be processed recursively". In the case of multi-level branches the GUI should trace all references to find all firewalls affected by a change of an object used in the rule. 2010-07-27 Vadim Kurland * configlets/linux24/block_action: fixed #1640 "default policy when the script is stopped should be optional". The "stop" command used to be interpreted by the iptables script generated by fwbuilder in a way that it blocked all connections going to, from and through the firewall. Luc Paulin pointed out that this behavior is incompatible with other firewall management scripts, such as /etc/rc.d/init.d/iptables on Fedora Linux or ufw on Ubuntu, where "stop" means disabling the firewall. In v4.1 the "stop" command flushed all chains in all tables and sets default policy to ACCEPT. New command "block" does what "stop" used to do before, that is, flushes all chains in all tables and sets default policy to "DROP". The option to add a rule to permit ssh access from the management workstation when firewall is stopped now adds this rule when firewall script is run with "block" command instead. 2010-07-26 Vadim Kurland * configlets/linux24/run_time_address_tables: implemented support for mixed address lists for run-time address table objects using ipset module. Normally, one ipset set can either contain individual ip addresses or subnets. We create a "setlist" type set that includes two sub-sets, one for ip addresses and the other for subnets. Function reload_address_table in the configlet run_time_address_tables takes care of managing these three sets automatically. Address list file has the same format as for all other supported types of Address Table object: one address per line, subnets are defined using '/bitlength' or '/netmask' syntax, comments start with '#' or ';' character. 2010-07-24 Vadim Kurland * code cleanup. Removed bunch of warnings and cleaned up some test cases using small patches from Mike Slifcak slif@bellsouth.net 2010-07-23 Vadim Kurland * Fixes #1635: included code generated by the configlet run_time_address_tables into script for all linux-based host OS (dd-wrt, openwrt, ipcop) even though most of they do not support ipset at this time. If ipset is not supported because iptables version is too old or the module is simply not available for the platform, user can just uncheck the checkbox in the firewall settings dialog and code generated by the configlet will support method of loading addresses from the file at run time based on script variables and a "while" loop. * script_skeleton: added command line argument "reload_address_table" that calls function reload_address_table and takes two additional arguments: set name and file name. * script_skeleton (cmd): calling functions to check if data files used by run time address table objects are available before making any changes to iptables policy. If files are not available, the script aborts and leaves iptables in the original state. This fixes #1628 "generated script checks presence of the address table files after it sets default iptables policy to DROP". fixes #1628 * run_time_address_tables: new configlet that adds shell code to check if all run time address table data files are present on the firewall machine and that ipset utility works and can communicate the the kernel driver. This configlet also defines a function to reload one ipset with given name and data file name and function to reload all ipsets used in the generated script. Fixes #1625, #1627 * PolicyCompiler_PrintRule.cpp (PrintRule::normalizeSetName): fixed #1626 "convert space and other special characters found in the run time address table object into underscores". The name of the run-time Address Table object is used for the name of the ipset module set. Making sure the name is sanitized of the chanracters considered "special" by shell before it is used. * check_utilities: fixed #1625, #see 137: added ipset to the list of command line utilities generated iptables script can use. Script will check if the utility is present on the firewall if user requested use of iptables module "set" for run-time Address Table objects. Also added an input field for ipset in the advanced settings host OS dialog for Linux to let the user specify path to ipset if it is not standard. 2010-07-22 Vadim Kurland * PolicyCompiler_PrintRule.cpp: added support for iptables module "set" used to generate iptables command for rules with run-time AddressTable objects. This module is only available in iptables 1.4.1.1 and later, however some embedded platforms do not have it even though they ship later versions of iptables (e.g. OpenWRT). Use of this module is controlled by a checkbox in the iptables "advanced" settings dialog which is off by default. This checkbox becomes disabled when iptables version is set to < 1.4.1.1. * newClusterDialog_create.cpp (newClusterDialog::createNewCluster): fixed #1622 "Crash when configuring cluster". The GUI used to crash if user created a cluster copying rules of one of the cluster members while that rule set was opened in the rule set view. 2010-07-21 Vadim Kurland * iptadvanceddialog_q.ui: rearranged elements in the tab "Compiler" of the dialog to make it shorter and wider. Still needs some work to make it render better. * InterfaceEditorWidget.ui: set minimum height for the name, label and few other input fields because they came out squished on Mac. Fixes #1613. * FWWindow.cpp (fileNew): fixed #1611 "File/New should create new project panel". Like #1612, open new data file in a new project panel if current project panel has no data file associated with it but has unsaved changes. * FWWindow.cpp (loadFile): fixed #1612 "File/Open should create new project panel". If user has some unsaved changes in the default project panel (the one with no associated file) and then uses File/Open menu to open another data file, the file should open in a new project panel. 2010-07-20 Vadim Kurland * FWWindow.cpp (FWWindow::showEvent): default main window geometry should be 1000x600, wider than it used to be before. This is to make object dialogs fit in the main window without squishing. * routing_functions: added a copy of the routing_functions configlet to the dd-wrt-nvram and dd-wrt-jjfs because newest versions of DD-WRT lack mktemp. The original routing_functions configlet does not use mktemp either, but Gentoo (and possibly other distros) ship patched version that needs mktemp which breaks fwbuilder generated script on these versions of DD-WRT. Hopefully they won't patch the copy of routing_functions configlet. * StartTipDialog.cpp (StartTipDialog::StartTipDialog): fixed #1603 "Welcome dialog should show full version of the program". * set version to 4.1.0 and version of the data file format to "17". Data files need to be upgraded. Upgrade script changes the version and makes sure Standard objects library is read-only. Some users may have this library configured read-write in their data files because of a bug in the early versions of fwbuilder 4. * We have decided to release this version as 4.1.0 rather than 4.0.2. "4.0.2" will remain our internal testing version designation. 2010-07-19 Roman Bovsunivskiy * DiscoveryDruid_q.ui, newclusterdialog_q.ui, newfirewalldialog_q.ui: Set up default buttons in dialogs * DiscoveryDruid_q.ui, DiscoveryDruid.cpp, Importer.cpp: Added firewall name input field. * InterfaceEditorWidget.cpp: Button "Add address" now changes text to "Add anoter address" when there is at least one address in current interface. 2010-07-19 Vadim Kurland * objects_init.xml.in: fixed bug #3031721 "Qt has caught an exception thrown from an event handler." The "Standard" objects library was made read-write in one of the earlier builds 2010-07-17 Vadim Kurland * DiscoveryDruid.cpp (DiscoveryDruid::DiscoveryDruid): fixed #1597 import method "import configuration of a firewall" is disabled on the first page of the discovery druid 2010-07-15 Vadim Kurland * newFirewallDialog_from_template.cpp (newFirewallDialog::replaceReferencesToNetworks): fixed #1582 'tree is not refreshed after address substitutions in "new firewall" wizard' 2010-07-14 Vadim Kurland * FirewallInstaller.cpp (FirewallInstaller::packSCPArgs): fixed #1571 "Installer does not work if firewall object name contains spaces". Installer should use escaping to make sure file name with a space is correctly interpreted by the script it runs on the firewall. * DiscoveryDruid.cpp (DiscoveryDruid::loadDataFromImporter): fixed #1544 "fwbuilder crashes during import of file with rtf formatting data". The fix should prevent crashes in other cases when import was unsuccessful. 2010-07-13 Roman Bovsunivskiy * instdialogoptions_q.ui: Added "Cancell All" button to stop all firewalls installations, renamed OK button to "Install" * instDialog_ui_opts.cpp (instDialog::getInstOptions): added support for "Cancel All" dialog result code. 2010-07-12 Roman Bovsunivskiy * instDialog_ui_opts.cpp (intDialog::fillCompileSelectList): fixed wrong display of non-ascii symbols in cluster member compilation warning. * newFirewallDialog.cpp (newFirewallDialog::showPage): firewall names are now resolved to IP address. Added new input element for firewall IP address to use for SNMP interface discovery. 2010-07-11 Vadim Kurland * FirewallInstaller.cpp (FirewallInstaller::packSSHArgs): fixed bug 3027284: "redux settings for scp/ssh to respond to line failure". The solution for bug 3020381 used to force ssh and scp commands to use the parameters ServerAliveInterval and ConnectTimeout to activate and configure ssh keepalive protocol. These command line parameters were enforced and added to the input fields where user enters the path to ssh and scp utilities on the machine where fwbuilder GUI is running. This was confusing and poor GUI design as the program was changing fields that were supposed to be user-editable. This fix adds an input field for the timeout value in seconds to the "Installer" tab of the global preferences dialog. The program does not change strings entered by the user for ssh and scp path anymore. The same timeout value is used to set up ServerAliveInterval parameter for ssh, ConnectTimeout parameter for scp and registry entries required by plink and pscp on Windows. 2010-07-10 Vadim Kurland * Importer.cpp (Importer::getFirewallObject): fixed bug #3027272: "default values taken from unexpected sources". When new firewall object was created using "Import Policy" function, parts of its configuration were taken from default settings of an unexpected host OS. 2010-07-09 Roman Bovsunivskiy * newFirewallDialog.cpp (newFirewallDialog::finishClicked): fixed crash when clicking finish after getting error about wrong IP address or netmask * FirewallCodeViewer.cpp (FirewallCodeViewer::fileSelected): now when viewing again file that was viewed before scroll position is same as user left it. * instDialog_q.ui: renames "All" button to "Select all" and "None" to "Select none" * instDialog.cpp (instDialog::show): hide "Select all" and "Select none" buttons when there is only one firewall in list * instDialog.cpp (instDialog::showPage): next button on inspect page is now not enabled if dialog called for compile only 2010-07-05 Roman Bovsunivskiy * instDialog.cpp (instDialog::findFirewalls): sorting of filewall and cluster items in compile/install dialog is now case insensitive. * ProjectPanel.cpp (ProjectPanel::inspectAll) * ObjectManipulator.cpp (ObjectManipulator::inspet): inspect is now working with cluster objects. 2010-07-03 Vadim Kurland * RuleSetView.cpp (RuleSetView::restoreCollapsedGroups): fixed SourceForge bug 3020761 "printing from command line causes Segmentation fault". Fixes #1533 2010-06-28 Vadim Kurland * utils.cpp (parseCommandLine): See #1542 since now user can enter differet command line parameters together with the path to ssh and scp clients in the global Preferences dialog, we need to parse these properly. This is especially important if file paths or arguments contain white space characters. Unit tests are in src/gui/unit_tests/parseCommandLineTest 2010-06-26 Vadim Kurland * installer_commands_reg_user: all instllation commands should be on the single line in the configlet so they are sent to the firewall as one line. When these commands were on separate lines, linefeed characters between them appeared on the standard input of command "sudo -S" and broke installation process. This only happened in my tests when I ran GUI installer on windows and looked like some sort of a race. When all commands are on the one line the problem disappeared. Changed only configlets that used sudo as part of installation script. * CompilerDriver_pix_run.cpp (CompilerDriver_pix::pixNetworkZoneChecks): do not verify network zones of unprotected interfaces. Compiler does not allow the same obejct to be used as network zone of two different interfaces, which caused problems when a vlan parent interface has zone "Any". Vlan parent interface can not have ACLs attached to it and does not need any meaningful network zone, so "Any" is reasonable fill-in choice. However it coinsides with network zone of the "outside" interface which triggered this check. * SSHUnx.cpp (SSHUnx::stateMachine): SF bug 3020381: "Line failure should abort remote firewall install". If network connection is lost during firewall policy activation, policy installer should detect this, disconnect and declare installation session a failure. Prior to v4.0.2, installer detected network failures during policy copy (done with scp) or when it could not connect to the firewall at all, but hang if connection was lost in the middle of ssh session used to activate firewall policy. Now using ssh parameter "ServerAliveInterval" to make it detect connection failure. This does not work with plink.exe on Windows which does not support these command line options. Still looking for a solution. * FWBSettings.cpp (FWBSettings::init): automatically adding ssh parameters "-o ServerAliveInterval=2 -o ServerAliveCountMax=15" and scp parameter "-o ConnectTimeout=30" to the path to ssh and scp in the global preferecnes dialog, tab "Installer" to activate ssh keepalive. This way, user can change values if they need to. Default values define 30 sec timeout which should be rather conservative. On windows automatically configuring plink.exe and pscp.exe to load parameters of putty session "fwb_session_with_keepalive" that turns keepalives on. 2010-06-25 Roman Bovsunivskiy * FirewallCodeViewer.cpp (FirewallCodeViewer::FirewallCodeViewer): See #1346. Mostly completed implementation of the viewer panel that can be used to inspect generated firewall configuration files from within the GUI. The panel can be opened using a button in the mini-toolbar above firewall rules or as a page in the compile and install wizard. 2010-06-24 Vadim Kurland * OSConfigurator_linux24::printVirtualAddressesForNatCommands: fixed bug 3001228 "v4.0.0 iptables: NAT not creating interface addresses". Iptables script generated by fwbuilder used to include commands to configure virtual ip addresses for NAT only if option "configure interfaces" was turned on. Expected behavior is to generate these commands when option "Add virtual addresses for NAT" is turned on regardless of the setting of the option "configure interfaces". 2010-06-22 Roman Bovsunivskiy * fixed #1526 "Make sure GUI unit tests work in the environment where user turned off tip of the day dialog". Unit tests now use alternative settings file with all default values and do not depend on user's preferences. 2010-06-18 Roman Bovsunivskiy * fixed #1520 ("Comment field display clips comment text" 2010-06-17 Vadim Kurland * PolicyCompiler_ipt.cpp (specialCaseWithFWInDstAndOutbound::processNext): fixed #1523 "outbound ipv6 rule matching multicast ipv6 destination is not generated". The rule with network object fe80::/10 in source and ipv6 muticast ff00::/8 in destination did not produce correspondign ip6tables command. The change affects other cases with rules using broadcast or multicast objects that should be considered matching the firewall object. 2010-06-17 Roman Bovsunivskiy * RuleSetView.cpp: fixed SF bug 3016680 "Vertical scrollbar issue" rules with a lot of objects did not scroll properly vertically. * fixed #1493 "workflow icons in the big empty space". The GUI shows big buttons in the empty space in the right hand side of the main window when no firewall policy is not opened yet. These buttons provide simple shortcuts to the workflow functions useful for the novice users. Currently this includes "Create new firewall", "Import configuration of existing firewall" and "Watch Getting Started Tutorial". * fixed #1521 "GUI crashes upon exit on CentOS 5". This fixes SourceForge bug reports 3016482 "segfault with RHEL5 pre-built packages on CentOS 5.5" and 3015979 "fwbuilder not exiting in centos 5.5" 2010-06-16 Vadim Kurland * IPTImporter.cpp (IPTImporter::pushPolicyRule): fixed SF bug 3017084 "compiler adds extra quote characters to log-prefix string". 2010-06-15 Vadim Kurland * IPTImporterRun.cpp (IPTImporter::run): policy importer for iptables replaces --sport and --dport parameters of module multiport with --source-ports and --destination-ports to remove grammar ambiguity that arises from the use of the same parameters --sport and --dport by different iptables modules with different argument syntax. * iptables.g (match_iprange_src): Fixed SF bug 3016779: Policy importer for iptables should understand module iprange * FWWindow.cpp (FWWindow::prepareFileMenu): fixed bug 3016720 "import policy disabled after file close". Menu items "File/Import Library" and "File/Import policy" became disabled after user closed data file using "File/Close" and never became enabled again. 2010-06-14 Roman Bovsunivskiy * FWBSettings.cpp (FWBSettings::init): fixed #1504 Added (optional) text to the toolbar buttons. Text is turned on by default but can be turned off in the global Preferences dialog. * Preferences.cpp: fixed #1505 move "Clip comments in rules" checkbox to "Appearance" tab. 2010-06-14 Vadim Kurland * release_notes_4.0.2.html: Added release notes for v4.0.2 to the package. fixes #1515 * IPTImporter.cpp (IPTImporter::pushPolicyRule): fixed SF bug 3015641 "imported REJECT rule changed during compile". Importer of iptables rules did not handle properly parameters of the REJECT target. 2010-06-12 Vadim Kurland * IPTImporter.cpp (IPTImporter::pushPolicyRule): fixed #1516 policy importer for iptables should not use automatic ESTABLISHED rule. (See also SF bug 3012953). Policy importer for iptables always creates explicit rule to match ESTABLISHED,RELATED to make sure it goes into the same chain as the original rule. Also in the same fix, importer creates branch for iptables rules that match both regular service and state ESTABLISHED,RELATED. The service is matched in the main policy rule set, while ESTABLISHED,RELATED state is matched in the branch. * GroupObjectDialog.h (class GroupObjectDialog): fixed #1499 "GroupObjectDialogTest.cpp does not compile with gcc 3.4.6" and SF bug 3015307. There is no reason to make method insertObject() protected which caused problems (and hacky workaround) in the unit test. * IPTImporter.cpp (IPTImporter::finalize): fixed SF bug #3015305 "compile error XML validity ". The problem was introduced with a change that made policy importer cabaple of reproducing default policies of main chains. 2010-06-11 Vadim Kurland * fixed SF bug #3013743 "UI build warnings" * longtextdialog_q.ui, objconflictresolutiondialog_q.ui: fixed SF bug #3013735 "invalid pixmap properties during make". Fixed uic warnings. * IPServiceDialogTest.cpp (IPServiceDialogTest::testIpOptions): fixed SF bug #3013855 "various fixes for run_tests". Applied patch suggested by Michael J. Slifcak (with changes). * DiscoveryDruid.cpp (DiscoveryDruid::browseForImport): fixed SF bug #3013532 "file chooser dialog for import policy does not show all files". * IPTImporter.cpp (IPTImporter::finalize): fixed #1513 iptables importer should check default policy in standard chains. Importer creates rules at the bottom of the policy rule set to reproduce default policies in the built-in chains INPUT,OUTPUT,FORWARD. These rules are added only when default policy in these chains is set to ACCEPT because generated iptables script always sets default policies to DROP. Support for this in the mangle table is limited so far, only default policies in PREROUTING, OUTPUT and POSTROUTING can be implemented. Rules created for the commands that set default policy in chains FORWARD and INPUT will generate commands in PREROUTING chain instead. We will try to address this in the future if there is sufficient demand. 2010-06-08 Vadim Kurland * applied patch from slif@bellsouth.net to fix compiler warnings. Patch applied partially since not all fixes were appropriate. fixes #1510 * IPTImporter.cpp (IPTImporter::pushPolicyRule): fixed #1512 SF bug 3012953: iptables importer sometimes does not recognize rule with " ESTABLISHED,RELATED ". Parser properly processed iptables rules with state "RELATED,ESTABLISHED" but not when states were in the opposite order. * IPTImporter.cpp (IPTImporter::pushPolicyRule): policy importer for iptables can now parse numerical log levels. * Importer.cpp (Importer::getUDPService): fixed sourceforge bug 3012953 name of UDP and TCP objects created during import should follow the same pattern and not include "0-0" for the source ports if they are equal to zero. * IPTImporter.cpp (IPTImporter::IPTImporter): fixed #1511, SF bug 3012953: iptables import parse error icmp_type any 2010-06-07 Vadim Kurland * CompilerDriver_pix_run.cpp (CompilerDriver_pix::pixNetworkZoneChecks): fixed #1491 fwb_pix crashes trying to compile simple rule. Compiler should check validity of the object used as network zone of an interface. * FWBSettings.cpp (FWBSettings::init): fixed #1501 call qsrand(seed) to seed random generator before generating new UUID * TransferDevice.h (fwtransfer): fixed #1490 compile problem with Qt 4.7 * FWWindow.cpp (FWWindow::prepareRulesMenu): fixed #1489 removed unnecessary debugging messages. * interfaceProperties.cpp (interfaceProperties::manageIpAddresses): fixed #1506 SF bug #3011516: generated iptables script tries to update ip addresses of unnumbered interface. * v4.0.2 started 2010-06-06 vadim * FWBSettings.cpp (FWBSettings::FWBSettings): using separate settings object and file in the .ini format to store instance uuid to ensure uuid persistence on windows across upgrades done with complete deinstall. Fixes #1497 * UserWorkflow.cpp (UserWorkflow::flagsToQueryString): added user workflow progress flags for an attempted install and first successful install. Both flags are boolean true/false indicating that the even occurred. We do not track and do not report any information about the firewall, platform, rules etc. These flags will be used to determine how many users abandon the program before even trying to run install for real because it is too complicated or the UI is not good enough. Fixes #1495 * UserWorkflow.cpp (UserWorkflow::flagsToQueryString): added user workflow flag indicating that ssh/scp have been configured in the Prefereces dialog. The flag is boolean and registers only the fact that something was entered in ssh and scp fields. Actual path and programs used are not registered and reported. Fixes #1496 2010-06-03 vadim * v4.0.1 released 2010-06-02 vadim * Preprocessor.cpp (Preprocessor::findMultiAddressObjectsUsedInRules): change in libfwbuilder: fixed #1485 "dns name object is recognized as an empty group when it appears in shared rule set" 2010-06-02 yalovoy * fixes #1484 "paste below" function pastes rules out of order 1) copy 2 complete rules 2) go to a(nother) policy 3) right click on rule 0, say "paste rules below" => BUG: the two rules from the buffer become rules 0+2, the original rule 0 becomes rule 1 The original should stay rule 0, the two from buffer become 1+2 Affected files: FWCmdRule.cpp, FWCmdRule.h, RuleSetView.cpp 2010-06-01 vadim * Help.cpp (Help::downloadComplete): fixed #1482 Class Help should open window only after successful download * ObjConflictResolutionDialog.cpp (ObjConflictResolutionDialog::run): refs #1483 If program detects change in CustomService object and the change just adds code string for a platform that was not in the object in the user's data file, the change is accepted without showing the dialog. * ../src/res/objects_init.xml.in: fixed #1483 "missing code in the custom service object ESTABLISHED for ProCurve" 2010-05-31 vadim * FWWindow.cpp (FWWindow::checkForUpgrade): added mechanism for one-time announcements that can be pulled from the web site when version check server says there is one. Announcement is shown only once. To do this, I store time stamp when it was shown in settings using hash of the announcement url. * Help.cpp (Help::setSource): made class Help capable of downloading contents via HTTP. * FirewallDialog.cpp (FirewallDialog::fillVersion): fixed #1481 when user changes platform in the firewall object, its version should change too. 2010-05-28 vadim * ObjectManipulator.cpp (ObjectManipulator::editSelectedObject): see #1447 Reverting change done for ticket #1447 in r2892 and r2896 because of the user complaints. It appears to be more convenient if Policy, NAT and Routing objects open in the rule set view on double click but not in the editor. Second double clik opens these objects in the editor. 2010-05-25 vadim * configure.in (CPPUNIT_LIBS): fixed #1478 always use included antlr run-time library. Because of the fixes I've made in CircularQueue?.hpp in 2008 for 64 bit systems, we should always link with antlr run-time that is included with fwbuilder code tree rather than attempt to use the one that might be installed with the OS. 2010-05-24 vadim * UserWorkflow.cpp (UserWorkflow::report): see #1466 Implemented instrumentation that should help us improve user experience. Will track few things that new users do (or don't do) and report as a combination of boolean flags at the end of the GUI session. Reporting things such as if user ever looked at the "Getting Started" tutorial, if they created their first firewall object, modified any rules, tried to compile, install or import existing rule set. Information passed in the report is strictly a set of boolean flags, it is not identifiable and does not reveal what firewall platform they are using or anything about their objects and rules. List of flags is listed in the module UserWorkflow.h 2010-05-23 vadim * FWCmdAddObject.cpp (FWCmdAddObject::redo): fixed #1468 Open new object in the editor after it has been created. * applied patch by Vadim Jukov , maintainer of OpenBSD port. Patch fixes compile issues on OpenBSD 2010-05-22 yalovoy * fixes #1463 Always show branch rule set name with action "Branch" affected files: RuleSetView.cpp, RuleSetViewDelegate.cpp, RuleSetViewDelegate.h * fixes #1469 some actions should always display argument, even when text labels for actions and directions is off affected files: RuleSetViewDelegate.cpp 2010-05-21 vadim * RuleOptionsDialog.cpp (RuleOptionsDialog::loadFWObject): fixes #1467: "rule options dialog shows iptables parameters for procurve_acl" * FWObjectPropertiesFactory.cpp (FWObjectPropertiesFactory::getPolicyRuleOptions): fixes #1457 "tooltips for rule options seem to be broken". Tooltip always includes the line telling of the rule is "stateful" or "stateless", the function almost never returns empty string now. Added missing hashlimit parameters to the rule options tooltip. Some of the more rarely used hashlimit parameters are still not included in the tooltip. Improved tooltip formatting using html table. 2010-05-20 vadim * ProjectPanel.cpp (ProjectPanel::addRule): fixed #1461 Need obvious button to add new rule to the empty rule set * instDialog.cpp (instDialog::show): fixed #1462 "if you do a bulk install, and then want to do a single install, bulk mode is selected" * ActionsDialog.cpp (ActionsDialog::setRule): fixed #1464 SourceForge bug 3004274: "Branch rule set object displays improperly". Branch rule set attribute was not loaded properly into Branch action dialog for rules of PF firewalls. 2010-05-17 vadim * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printRule): restored function of the "comment the code" in the "Script options" of the firewall settings dialog for Cisco IOS ACL and ProCurve ACL. When this checkbox is off, comments are not added to generated script. * RuleSetViewDelegate.cpp (RuleSetViewDelegate::paintOptions): fixed #1460 "when "show icons in rules" is turned off, there is no way to tell when logging is turned on and non-default options are present in a rule". * fixed #1339 "Logging" icon appears looking the same as "Rule options" icon on Mac 2010-05-15 Vadim Kurland * linux24Interfaces.cpp (linux24Interfaces::basicValidateInterfaceName): fixed #1458 Should permit interface name "br-lan" for bridge interface on Linux. Bridge interfaces on Linux can have any name, including those with "-". OpenWRT creates bridge interface with the name "br-lan" by default. 2010-05-14 Vadim Kurland * update_addresses: fixed #1455 Function update_addresses() (host OS linux24 and derivatives) uses both ip and ifconfig. Should stick with /sbin/ip so the script works on systems where ifconfig is not installed. 2010-05-13 Vadim Kurland * FWObjectDropArea.cpp (FWObjectDropArea::editObject): fixed #1452 double click on a rule set in the branch action dialog should open it in rule set view * iptables.g (MATCH_RECENT_SET): see #1451 "policy importer should support some popular iptables modules". Added support for module "recent" and rules that match standard ip/icmp/udp/tcp protocols and at the same time module "mark", "length", "limit" or "recent". Rules like these are translated into a combination of a branching rule and additional rule in a branch rule set that implements module match. * iptables.g (multiport_tcp_udp_port_spec): fixes #1453 "iptables importer should parse multiport module parameter --ports". Module multuport with parameter "--ports" matches either source or destination port numbers. Importer creates two tcp (or udp) service objects to implement this match. * IPTImporter.cpp (IPTImporter::addSrv): See #1450, SourceForge ticket 3000809: iptables parser can now import "mark" module matches with hexadecimal parameters and "length" module matches. Also added check in the importer for broken iptables-save files where rules for any table are not terminated with "COMMIT". 2010-05-12 vadim * configlets/procurve/installer_commands_pre_config: commands for the installer for ProCurve * instDialog.cpp (instDialog::isCiscoFamily): Using the same built-in installer for Cisco and for ProCurve. * procurveaclAdvancedDialog.cpp (procurveaclAdvancedDialog::procurveaclAdvancedDialog): fixed #1449 options for ACL remarks and comments for ProCurve * PolicyCompiler_procurve_acl_writers.cpp (PolicyCompiler_procurve_acl::printAccessGroupCmd): generated commands that attach acl to a regular inetrface needed newline after "exit". * configlets/procurve/safety_net_acl: generating different commands in "Safety net" install mode depending on whether management interface is vlan or not. 2010-05-11 Vadim Kurland * ObjectManipulatorTest.cpp (ObjectManipulatorTest::editSelectedObject): see #1447 fixed unit test for this change * ../src/res/configlets/dd-wrt-jffs/installer_commands_root: fixes #1448 "need to commit nvram changes on DD-WRT". * ObjectManipulator.cpp (ObjectManipulator::editSelectedObject): fixes #1447: context menu item "Edit" associated with rule set object in the tree opens it in the rule set view and the editor panel. Menu item "Open" only opens it in the rule set view. This eliminates strange behavior where it would open in the rule set view on first click on "Edit" and then in the editor in the second click on "Edit". Double click used to work the same, the first double click opened in rule set view, the second in the editor. Now double click always opens in rule set view and the editor which is more consistent with the behavior for other object types. * PolicyCompiler_procurve_acl_writers.cpp (PolicyCompiler_procurve_acl::printAccessGroupCmd): ProCurve uses different syntax for vlan ACLs and ACLs bound to switch ports. Enabled "advanced interface settings" dialog for ProCurve interfaces. * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): button "Advanced interface settings" is controlled by element in the host OS xml resource file. Before, it was controlled by the element . I need this button and associated dialog for vlan interfaces on ProCurves, where vlan interfaces are not subinterfaces. 2010-05-10 vadim * CompilerDriver_procurve_acl_run.cpp (CompilerDriver_procurve_acl::run): See #1442 Support for HP ProCurve. Added experimental support for HP ProCurve "intelligent" switches (L3). Code is based on the policy compiler for Cisco IOS extended access lists. Differences include ';' character for comments, different naming convention for Vlan interfaces ("VLAN 2", with a space), requirement to unbind an ACL from interface before it can be cleared. * CompilerDriver_iosacl.cpp (CompilerDriver_iosacl::safetyNetInstall): using configlet "safety_net" to add temporary ACL for the "safety net" install method. 2010-05-05 Vadim Kurland * ProjectPanel_events.cpp (ProjectPanel::event): fixed #1443 GUI crashes compiling file opened read-only. If a file that was added to RCS was opened read-only and then any firewall object in it compiled, the GUI crashed trying to update "last_compiled" timestamp. * ssh_wrappers.cpp: fixed #1444 compile error on FreeBSD-Current Compiler issues error "/usr/include/utmp.h:2:2: error: #error has been replaced by h>" * started work on v4.0.1. VERSION set to 4.0.1 in libfwbuilder and fwbuilder 2010-05-04 Vadim Kurland * v 4.0.0 released 2010-05-02 Vadim Kurland * Helper.cpp (Helper::findInterfaceByNetzone): fixed #1439 "ssh access rule uses wrong interface in the generated PIX config" * instDialog_ui_ops.cpp (instDialog::opError): fixed #1438 "installer crashes when user interrupts install to PIX". This only affected installs to PIX cluster and only if user decided to interrupt the process. 2010-05-01 vadim * new_object.cpp (_modObject): fixed #1437: fwbedit should support object type Cluster. * fwbedit.cpp (usage): fixed #1435: typo in fwbedit "usage" text * new_object.cpp (_modObject): fixed #1434 "fwbedit modify comment operation expects an attribute" * instDialog.cpp (instDialog::show): fixes #1433 "batch install" checkbox should be enabled even when when there is only one cluster in the list of objects to compile and install. * CompilerDriver_ipt_policy.cpp (CompilerDriver_ipt::processPolicyRuleSet): fixes #1432 "automatic rule with --restore-mark is missing if rules using action Tag are not in the default Policy rule set". 2010-05-01 yalovoy * RuleSetView.cpp: fixes #1431 GUI crash adding rules to rule group 2010-05-01 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertFailoverRule): fixed #1411 outbound rule that permits VRRP should be added outside the loop to avoid duplicate rules for clusters with 3 or more members. 2010-04-29 Vadim Kurland * SSHSession.cpp (SSHSession::terminate): see #1426, #1428 QProcess sends signal "finished()" during event processing on windows, added checks for that. * instDialog.cpp (instDialog::mainLoopInstall): disabling and enabling "stop" button in the compile/install dialog appropriately 2010-04-28 Vadim Kurland * instDialog.cpp (instDialog::show): fixes #1429 "Finish" button is activated during compile. Also added unit test for this. 2010-04-27 vadim * CompilerDriver_ipt.cpp (CompilerDriver_ipt::dumpScript): fixes #1425 "iptables script generated for the empty rule set is broken". Compiler generated empty shell function for empty Policy rule set. It should always include at least automatic rules. * SSHSession.cpp (SSHSession::terminate): see #1426, #1428 use QProcess::waitForFinished() instead of just sleep() after we send TERM signal to the background process. Also let Qt process events to update the GUI while waiting. * instDialog_installer.cpp (instDialog::stopInstall): fixed #1428 button "Stop" in the installer dialog does not stop installer process * SSHSession.cpp (terminate): fixes #1426 "segfault when cancel while installing" (SF bug 2990333). No need to process events in terminate(); instead, using QProcess::waitForFinished() to give QProcess object opportunity to call this signal if user hit Cancel at just right time when background process has finished but QProcess has not noticed this yet. This situation caused crash reported in the SF bug. This problem appears to be specific to some versions of Qt. It does not happen with Qt 4.5.0 or Qt 4.6.2 but happens with 4.5.3. * instDialog_ui_ops.cpp (addToLog): working on #1426 "segfault when cancel while installing". SF bug 2990333. Processing of large chunks of compile or installer output took long time, especially scanning for errors and warnings which involves RegEx match. Splitting the buffer onto individual QString lines and matching each line against all error and warning pattern regexes made it much faster. Also do not call qApp->processEvents() from addtoLog() to avoid recursive call. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::checkForShadowingPlatformSpecific): see #1417 (SF bug 2992177) rule with greater limit module rate value shadows rule with lower rate value. Comments in the code explain why. 2010-04-26 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::checkForShadowingPlatformSpecific): additional fix for #1417 (SF bug 2992177): compiler should compare limit rate value and other parameters set for modules limit, connlimit and hashlimit while deciding if rules shadow each other. 2010-04-24 Vadim Kurland * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::checkForShadowingPlatformSpecific): fixes #1417 rule shadowing detection should recognize different rule options. Policy compiler for iptables takes into account rule options for modules limit, connlimit and hashlimit when it considers rules for rule shadowing. * instDialog.cpp (instDialog::show): fixed #1419: clear progress log display when instDialog is opened 2010-04-23 vadim * MangleTableCompiler_ipt.cpp (keepMangleTableRules::processNext): fixed #1415 "action branch that creates branch in mangle table should branch in FORWARD chain". Rule with "any" in src and dst and action Branch with option "branch in mangle table" will go into FORWARD chain in addition to the PREROUTING and POSTROUTING chains as before. Note that choice of PREROUTING or POSTROUTING chains depends on direction. 2010-04-23 Vadim Kurland * instDialog.cpp (instDialog::show): fixed #1418 "install checkboxes disappear from the compile/install dialog". This was a regression introduced when we fixed #547 ("User can open multiple compile/install dialogs") * instDialog_ui_ops.cpp (instDialog::checkIfNeedToCompile): see #1418 Simplified algorithm that decides whether compile and install checkboxes should be turned on in the install/compile dialog. Now always using Firewall::needsCompile() and Firewall::needsInstall(), which check "last_modified", "last_compiled" and "last_installed" timestamps. Before this change, the dialog also tried to take into account how the dialog was started, using main toolbar or menu or context menu or local toolbar. This was confusing and hard to test. * PolicyCompiler_PrintRule.cpp (PrintRule::_printTarget): fixes #1416 leading blank space in front of the custom action is missing. SF bug 2991397. 2010-04-22 vadim * NATCompiler_pf.cpp (VerifyRules::processNext): see #1401. Because of the change in the nat and rdr rules syntax in 4.7, I can no longer implement no-nat rules correctly for this version. They dropped the "no" keyword and their examples suggest using "pass" to implement exclusions for the nat rules. I need no-nat rule to just not translate but not make a decision whether the packet should be passed or dropped. In the new PF model, translation rules are just options on the matching policy rules and they do not offer any keyword or option to not translate. * NATCompiler_pf_writers.cpp (PrintRule::processNext): fixes #1401 nat rules syntax has changed in OpenBSD 4.7. Nat and rdr rules in 4.7 should be implemented using action "match" and keywords "nat-to" and "rdr-to" * PolicyCompiler_pf_writers.cpp (PrintRule::_printAction): fixes #1414: use "match" action for tagging. Policy rules with action Tag should use pf action "match" instead of "pass" if version is 4.6 or later. 2010-04-20 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertFailoverRule): fixes #1411 "automatic rules for the HA protocol should match source IP". Rules added for heartbeat in unicast mode already matched source IP, this change makes rules added for VRRP, OpenAIS and heartbeat in muticast mode also match source address. * configlets/ipf/script_skeleton: fixed #1409, SF bug 2985886. Depending on the combination of the activated options, shell functions in the generated launcher script could have no body, which is a syntax error in bash. 2010-04-09 vadim * RoutingCompiler_ipt.cpp (RoutingCompiler_ipt::epilog): fixed #1404 call to function restore_script_output in the generated iptables script is sometimes added without function definition * NATCompiler_pf.cpp (ReplaceFirewallObjectsODst::processNext): fixes #1397 PF compiler fix: destination nat rule with fw object in ODst should skip "on intf" * NATCompiler_ipt.cpp (AssignInterface::processNext): fixes #1403 refs #1150 "Using ip address of wrong interface" is broken in v4.0. This effectively rolls back change r2437. With no "Interface" column in the NAT rules, it is difficult to build rules with arbitrary "-o" clause using address for SNAT that does not match interface of the firewall, or especially rules with address for SNAT that does match some inetrface but with another interface in "-o". Keeping old documented behavior where object in TSrc dictated this. If the object was a child of the firewall (an interface or address), then the rule was attached to the interface using "-o". If the object is not a child of the firewall, then the rule is attached to all interfaces using "-o eth+" but skips unnumbered interfaces. Column "interface" should be added to the NAT rules in the future to avoid these complications. * ProjectPanel_state_ops.cpp (ProjectPanel::saveState): fixed #1402 GUI crashes on exit when no rules are opened in the ruleset panel view * ObjectTreeViewItem.cpp (ObjectTreeViewItem::data): fixed #1398 bold font and "*" in the tree indicate firewalls that require installation but should indicate those that require recompile 2010-04-08 Vadim Kurland * interfacePropertiesObjectFactory.cpp: fixed #1396, SF bug 2984193 Vlan error when OpenWrt is selected as host 2010-04-08 vadim * CompilerDriver.cpp (CompilerDriver::copyFailoverInterface): see #1394 there is no need to add a copy of member interface objects to the cluster anymore. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::_expand_interface): fixes #1394 Using existing virtual functions that expand multiple addresses to expand cluster interfaces. Added parameter bool expand_cluster_interfaces_fully to _expand_addr, _expand_addr_recursive and _expand_interface. Now expanding cluster interface in the Compiler::_expand_interface instead of PolicyCompiler_ipt::_expand_interface. Now it is possible to use interface of another cluster in rules (interface of a cluster object different from the one being compiled). * ProjectPanel_file_ops.cpp (ProjectPanel::exportLibraryTest): fixed #1395 "routing rules are not reported properly while exporting library" * configlets/linux24/update_addresses: fixed #1391 "function getaddr_internal does not work with point-to-point interfaces". In fact, fwbuilder v3 and v4 can not manage ip addresses of point-to-point interfaces. This fix makes generated script skip such interfaces and do not try to add, remove or change their ip addresses. Proper support for address management of point-to-point interfaces will be added in the future versions of the program. 2010-04-07 vadim * IPTImporter.cpp (IPTImporter::pushPolicyRule): see #1390 'update iptables importer to recognize rules with "-i intf -o intf"' 2010-04-01 vadim * src/res/os/dd-wrt-nvram.xml: Added direct support for DD-WRT in two modes: nvram and jffs 2010-04-01 Vadim Kurland * AddressRangeDialogTest.cpp (AddressRangeDialogTest::initTestCase): fixed #1366 - fixed unit test for AddressRangeDialog class 2010-03-29 vadim * RoutingCompiler_iosacl_writers.cpp (PrintRule::_printRItf): fixed #1379 "Should be able to build routing rules with interface as gateway for IOS". Routing rules for IOS now have column "Interface". Rules can be built either with explicit address of the gateway or interface. * PolicyCompiler_pf.cpp (PolicyCompiler_pf::compile): fixed #1375 Interface group is not expanded in "Interface" rule element by compiler for PF * FWObjectPropertiesFactory.cpp (FWObjectPropertiesFactory::getObjectProperties): fixed #1371 "interface properties look ugly when interface is a member of a group". 2010-03-28 Vadim Kurland * generatedScriptTestsLinux.cpp (GeneratedScriptTest::CheckUtilitiesTest): See #1370. This is a place for the future compiler unit tests. In the future we are going to migrate tests from test/ipt/ to this directory, using cppunit framework and functions added to the class Configlet per #1369 * Configlet.h (class Configlet): fixes #1369 "Framework for unit testing of code generation via configlets" 2010-03-28 vadim * configlets/openbsd/installer_commands_reg_user: see #1368 A fix for the problem that causes built-in installer to hang after updating configuration of PF firewalls. 2010-03-27 vadim * fixed #1360 "negation of cluster interfaces is broken". Rule with one or several cluster interfaces in the "Interface" rule element with negation should compile into a rule using all other interfaces of the member firewall, or using single object negation "!" if appropriate. This is also fixed in compiler for PF. Files: src/iptlib/PolicyCompiler_ipt.cpp src/pflib/PolicyCompiler_pf.cpp See also changes r591 , r592 in libfwbuilder * platforms.cpp (isDefaultPolicyRuleOptions): fixed #1365 "missing some flags for the "non-default" rule options for PF" * FWObjectPropertiesFactory.cpp (FWObjectPropertiesFactory::getPolicyRuleOptions): fixed #1364 "add synproxy and other missing pf rule options to the rule options tooltip" 2010-03-26 vadim * RuleSetModel.cpp (RuleSetModel::getDecoration): fixed #1363 "GUI crash in newClusterDialog". GUI crashed after a new cluster object has been created from two PF firewalls. * configlets/linux24/check_utilities: fixed #1359 "generated script hangs testing for iptables-restore" 2010-03-25 vadim * FWObjectPropertiesFactory.cpp (FWObjectPropertiesFactory::getObjectPropertiesBrief): fixed #1356 "Show number of rules in the rule set object in the second column of the tree" * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): fixed #1351 "synproxy rule option is broken" 2010-03-24 Roman Bovsunivskiy * unit tests for IPv4Dialog, IPv6dialog, NetworkDialog, NetworkIPv6dialog fixed #1329, #1327 2010-03-23 Vadim Kurland * using CppUnit::TestFixture in unit tests based on cppunit: ImporterTest.h UsageResolverTest.h RCSTest.h FWBTreeTest.h interfacePropertiesTest.h * configlets/linux24/check_utilities: fixes #1348 "check_tools should check IPTABLES and IPTABLES_RESTORE as well" 2010-03-20 vadim * FWWindow.cpp (FWWindow::updateGlobalToolbar): additional check for condition that happens in unit test 2010-03-19 vadim * FWWindow.cpp (FWWindow::updateGlobalToolbar): fixed SF bug 2973137 "'warning text goes here'". Main toolbar buttons "Compile" and "Install", as well as menu items Rules/Compile and Rules/Install should be disabled if currently opened data file has no firewalls to compile. * CompilerDriverFactory.cpp (CompilerDriverFactory::createCompilerDriver): fixed SF bug 2973221 "single rule compile (x) results in sigsegv". * SSHCisco.cpp (SSHCisco::stateMachine): fixed SF bug 2973136, fwbuilder bug #1347: ssh 'cancel' rule install sigsegv. Installer caused GUI crash if user hit "Cancel" at just the right moment. Apparently this also depends on the firewall platform (was discovered and reported for Cisco FWSM) and perhaps on how fast it responds to the installer commands. * platform/fwsm.xml: fixed SourceForge bug 2973121: Added support for FWSM v4.x * pixAdvancedDialog.cpp: fixed SourceForge bug 2973079 "pix typo" (typo in a tooltip) 2010-03-18 vadim * fixed SourceForge bug #2972699 "fwsm/pix syslog name". The dialog only accepts ip address for the syslog server. * configlets/ipfw/script_skeleton: fixed #1335 "Empty functions in ipfw script". Under some circumstances shell functions in the generated ipfw script could have no body; /bin/sh does not like that. * newFirewallDialog::createFirewallFromTemplate: fixes #1340 firewall object created from template does not inherit fw and host os settings. See the ticket and comment in the code for caveats. * templates.xml.in: set "stateless rule " option in template rules where it makes sense; turned ip forwarding and "assume fw is part of any" in the "web server" template object. 2010-03-16 * RCS.cpp, FWWindow.cpp: Fixed #1334 Program failed to open data file on Windows if it was stored on mounted network volume. "File/Open" operation terminated with no error but did not load the file. "File/Open Recent" ended with an error message that quoted file path as somehting like this: "Volume{3c50bdba-21b0-4ea5-b52f-aa5d9755f918}/test1.fwb" which was obviously incorrect and the file could not be loaded. 2010-03-15 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printOptionalGlobalRules): fixes #1333 "Add variable management_interface for the automatic_rules configlet". Variable "management_address" renamed "ssh_management_address" to avoid ambiguity. * ObjectManipulator.cpp (ObjectManipulator::editSelectedObject): change in the behavior of double click in the tree. Open rule set object in the editor if it is already opened in RuleSetView. If we just opened it in RuleSetView, check if the editor is visible and if yes, open the object in the editor right away. Fixes #1331 2010-03-13 vadim * using file name for the floating tree panel title. See #1317 * fixes #1326 MDI subwindow title is left "Untitled" when GUI starts with a file on the command line 2010-03-13 Roman Bovsunivskiy * Object tree panel should have title when detached. Fixes #1317 2010-03-08 yalovoy * RuleSetView.cpp: fixes #1315 menu item "Remove from group" is available for rules inside the group. "Create new group" action is fixed too. * fixes #1202: Main menu "Rules" does not match rule context menu Items in the main menu Rules should get disabled and enabled just like items in the context menu do. Affected files: RuleSetView.cpp, RuleSetView.h * src/gui/FWWindow.cpp: fixes #1322 main menu items "Rules" are broken 2010-03-07 vadim * FWWindow.cpp (FWWindow::startupLoad): final (hopefully) design of the welcome/startup window. Always showing startup tip dialog; added buttons to show "Getting started" and "summary of features" to the same dialog window. Fixes #1224 * renamed menu item Help/Welcome to Help/Summary of features. fixes #1311 2010-03-07 yalovoy * refs #1202: Main menu "Rules" does not match rule context menu Items in the main menu Rules should get disabled and enabled just like items in the context menu do. Added action: copyRuleAction; cutRuleAction; pasteRuleAboveAction; pasteRuleBelowAction; disableRuleAction; enableRuleAction; setColorEmptyAction; setColorRedAction; setColorBlueAction; setColorOrangeAction; setColorPurpleAction; setColorGrayAction; setColorYellowAction; setColorGreenAction; Affected files: FWWindow.cpp FWBMainWindow_q.ui RuleSetView.cpp RuleSetView.h 2010-03-07 Roman Bovsunivskiy * ticket #1307 "cluster names in cyrillic appear garbled in instDialog list" * ticket #1289 "turn off mouse wheel scrolling of tabs in the main window MDI area" * Ticket #1310 "New slots in startup dialog". Buttons in the startup tip dialog connected to slots that open "Getting started" tutorial and "Summary of features" 2010-03-06 vadim * FWWindow.cpp (FWWindow::checkForUpgrade): code that checks if upgrade is available shows warning dialog no more than once a day. Also framework for unit testing of this function. See #1309 2010-03-05 vadim * instDialog_ui_ops.cpp (instDialog::fillCompileSelectList): fixed #1305 "Compilation of cluster firewall". when user tries to compile a firewall object that is also a cluster member, but did not request compilation of the cluster, a warning should be presented. * fixed #1303 "Improve design of the global Preferences, tab Objects" 2010-03-04 vadim * pfAdvancedDialog.cpp (pfAdvancedDialog::doScrubToggled): fixed #1297 "change in scrub rules in PF 4.6". PF 4.6 stopped support for several reassemble options except for "reassemble tcp" and changed format for the "scrub" rules. * PolicyCompiler_cisco_acls.cpp (setInterfaceAndDirectionBySrc::processNext): recognize multicast when matching Network and NetworkIPv6 objects. Fixes #1298 * ObjectManipulator.cpp (ObjectManipulator::getDeleteMenuState): fixed #1301 "can not delete Policy object when it is in Deleted Objects lib". SF bug 2962628 2010-03-03 glitch.vk.crocodile.org * CompilerDriver_pix_run.cpp (CompilerDriver_pix::run): fixed #1296 "crash in fwb_pix". Compiler used to create copy of each network zone object, expanded it recursively and added network and address objects to the newly created group directly (rather than via references). This created objects that were referenced by two parents in the tree which caused crash in FWObject::destroyChildren() because an attempt to free the same block of memory twice. 2010-03-03 vadim * compiler_lib/CompilerDriver.cpp (CompilerDriver::commonChecks2): fixed #1292 Added check for interfaces with valid address and netmask 0.0.0.0 2010-03-03 glitch.vk.crocodile.org * iptables.g (port_def_with_incomplete_range): fixed #1294 'importer for iptables does not parse "--dport NNNN:"'. Policy importer for iptables should recognize the following variant of the --dport and --sport port ranges: "port1", "port1:port2", ":port1" and "port2:" 2010-03-03 vadim * IPTImporter.cpp (IPTImporter::finalize): fixed #1288 "all rules created by policy import have rule number 0" * FWWindowPrint.cpp (FWWindow::filePrint): fixed #1295 "File/Print does not work for clusters" * Importer.cpp (Importer::createAddress): fixed #1287 "policy importer (iptables) crashes when host name is used in iptables rule in place of an address". Importer now creates DNSName object. * fixed #1291 "deleted objects 'policy' problem". SF bug 2962628 If user ended up placing a 'policy' object in the 'Deleted Objects' library, it could not be deleted or opened. RuleSetView.cpp RuleSetModel.cpp ActionsDialog.cpp RuleSetDialog.cpp platforms.cpp * Helper.cpp: fixes #1293 When compiler searches for an interface that should match given address, it should skip unprotected interfaces. 2010-03-02 glitch.vk.crocodile.org * RCS.cpp (RCS::init): checking if RCS tools are installed on the system once in the beginning. This helps avoid unnecessary QProcess starts that make working with valgrind more difficult because of subprocess starts/stops. 2010-03-01 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): fixed time format for the iptables parameters --datestart, --datestop which is supposed to be ISO 8601 "T" notation but apparently with no support for time zone designators. Timezone desginators are an error in iptables 1.4.1.1 and 1.4.5, did not test newer versions. Fixes #1286 SourceForge bug #2961532 2010-02-28 vadim * (many files) fixed warning " format not a string literal and no format arguments". Fixes #1285 2010-02-28 yalovoy * refs #1202: Main menu "Rules" does not match rule context menu Items in the main menu Rules should get disabled and enabled just like items in the context menu do. Added action: insertRuleAction, addRuleAfterCurrentAction, addToGroupAboveAction, addToGroupBelowAction Affected files: FWWindow.cpp RuleSetView.cpp RuleSetView.h 2010-02-27 vadim * ../src/gui/Tutorial/getting_started/html/page0.html: "Getting Started" turorial is complete, it can be activated using main menu item "Help/Tutorials/Getting Started". 2010-02-27 glitch.vk.crocodile.org * unit_tests.sh (commands): Using Xvfb for GUI unit tests so they can run as an automated task. This was broken by r2602 2010-02-26 vadim * ../src/gui/TutorialDialog.cpp (TutorialDialog::showPage): TutorialDialog supports multiple tutorials. Each tutorial is presented in HTML with accompanying CSS stylesheet. fixes #1274 * ../src/res/configlets/bsd/update_vlans: fixes #1275 "script always deletes, then adds vlans back on OpenBSD" 2010-02-25 Roman Bovsunivskiy a2k0001@gmail.com * TutorialDialog.cpp (TutorialDialog::TutorialDialog): in-program tutorial "Getting Started". Activated using menu Help/Tutorial. Refs #1217 2010-02-19 vadim * ProjectPanel_state_ops.cpp (ProjectPanel::loadState): refs #1236 Crash on Mac. The GUI could be crashed by repetetivie scrolling of the tree and other parts of the main window with mouse scroll wheel on Mac * FindObjectWidget.cpp (FindObjectWidget::_findAll): fixed #1256 search in the policy of firewalls does not work. This problem was introduced whith a fix for #1250 2010-02-15 yalovoy * ProjectPanel.cpp: fixes #1244 GUI crash on exit Looks like it is sufficient to just open some data file, open rule set (I tried with Policy) and insert a rule in the middle. Then exist the program and it crashes. 2010-02-18 glitch.vk.crocodile.org * PolicyCompiler_iosacl.cpp (splitTCPServiceWithFlags::processNext): fixed #1247 incorrect use of tcp service with flags in object-group. "object-group service" does not seem to support tcp flags and "established" * ObjectTreeViewItem.cpp (ObjectTreeViewItem::data): fixed #1248 Filtering in the object-tree crashes the GUI, SourceForge bug #2954501 * ObjectManipulator_tree_ops.cpp (ObjectManipulator::updateObjectInTree): fixed #1249 GUI freezes when filters are applied. The GUI would freeze for a few seconds every time user modified anything in rules if a filter was applied to the tree at the same time. SourceForge bug #2954501 * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed #1255 context menu items "Lock" and "Unlock" are not updated after object is locked. * ProjectPanel_events.cpp (ProjectPanel::event): fixed #1253 Locking an object in the tree causes GUI crash. 2010-02-18 vadim * FWWindow.cpp (FWWindow::FWWindow): fixed #1252 The "New Object"-Dialog is always opened up twice when pressing + * FindObjectWidget.cpp (FindObjectWidget::_findAll): fixed #1250 The Find-Dialog searches 'Deleted Objects'-library although it's not enabled in the preferences. Sourceforge bug #2954501 * IPv4Dialog.cpp (IPv4Dialog::DNSlookup): fixed #1251 DNS-Lookups in Address-Objects don't work. Sourceforge bug #2954501 2010-02-17 vadim * PolicyCompiler_iosacl.cpp (mirrorRule::processNext): fixes #1241 "add mirror rule" checkbox for IOSACL. New feature: policy rule option "Add mirrored rule" (checkbox in the rule options dialog) makes policy compiler for IOS ACL automatically create a rule with mirrored source and destination addresses and service fields. This can be used to match "reply" packets using address and service parameters matched by this rule. The action of the mirrored rule is the same as that of this one. Firewall Builder recognizes the following services and creates "mirrored" versions as follows: - UDP service: mirrored service has source and destination port ranges reversed - TCP service: mirrored service has source and destination port ranges reversed and "established" flag inverted. If TCP service used in this rule does not have "established" flag, the mirrored service gets it, and the other way around. This is designed to simplify creating ACL rules to permit "reply" TCP packets - ICMP service: ICMP echo request is recognized, mirrored service becomes ICMP echo reply. Other ICMP types are simply copied to the mirrored service - ICMPv6 service: like with ICMP, ICMP echo request is recognized and other ICMPv6 types are just copied - IP service: mirrored service is a copy * ssh_wrappers.cpp (ssh_wrapper): fixed #1246 policy installer fails on Linux. Policy installer failed with error "bash: -c: line 6: syntax error: unexpected end of file" while trying to activate iptables script on Linux. This error was introduced in one of the recent builds. 2010-02-16 vadim * fixed #1243 "new cluster" operation creates failover groups that recursively refer to the interfaces of the same cluster. This happened when new cluster was created with a copy of rules from one of the firewalls. newClusterDialog_create.cpp * fixed #1235 "cluster with dynamic interface can not be used in rules". Fixes this and several other problems with policy and nat rules that use cluster inetrfaces with dynamic addresses. PolicyCompiler_ipt.cpp NATCompiler_ipt.cpp * fixed #1240 nat rule should get "on interface" when cluster interface is used in TSrc. NATCompiler_pf.cpp * Configlet.cpp (Configlet::expand): added basic protection against infinite loops in configlet expansion. 2010-02-15 vadim * Added template for the OpenWRT firewall. Fixes #1237 2010-02-15 glitch.vk.crocodile.org * working on memory leaks with the help of valgrind. Refs #1229 Help.cpp Help.h RCS.cpp StartTipDialog.cpp StartTipDialog.h ssh_wrappers.cpp 2010-02-15 yalovoy * refs #1202: Main menu "Rules" does not match rule context menu Items in the main menu Rules should get disabled and enabled just like items in the context menu do. Affected files: FWWindow.cpp RuleSetView.cpp RuleSetView.h 2010-02-14 glitch.vk.crocodile.org * ProjectPanel.cpp (ProjectPanel): refs #1229 memory leak problems. 2010-02-14 yalovoy * fixes #1228: removing consecutive rules from a group in a ruleset its currently only possible to remove either the single top rule or single last rule from a group it would be useful to be able to select say the first several rules or last several rules and remove them all at once or if you select all rules in the group it would then just remove the group. Affected files: FWWindow.cpp FWWindow.h: #1228 RuleSetView.cpp: #1228 RuleSetView.h: #1228 2010-02-14 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::_expand_interface): fixes #1234 When failover group object is used in the rule, rule gets placed in FORWARD chain. Working implementation follows these rules: 1) if cluster interface obejct is used in the rule, it is expanded to the set of addresses including cluster virtual IP address and all addresses of the corresponding member firewall interface; 2) Failover Group is treated as any regular object group. Expanding Failover group to the address of its parent (cluster interface) would work but seems counter-intuitive * PolicyCompiler_ipt.cpp (decideOnChainIfDstFW::processNext): fixes #1231 rules are placed FORWARD chain if firewall object is "bridging firewall". This bugfix concerns specific rule configuration used with bridging firewall where firewall object or one of its interfaces is used in "destination" and an interface which is not a bridge port is in the "interface" rule column. Rule like this should go into INPUT chain but compiler used to splut it and put generated iptables rules in both INPUT and FORWARD chains. Rule should be placed in the FORWARD chain only if interface in "interface" column is bridge port. The same algorithm also applies to rules with firewall or one if its interfaces in the "Source" column. 2010-02-13 vadim * OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces): New feature: incremental management of pfsync0 interface on OpenBSD. The script checks if interface exists and if not, it runs "ifconfig pfsync0 create" command to create it. If interface exists, the script only runs ifconfig to configure its parameters but does not try to create it again. If State Synchronization group object is deleted in fwbuilder GUI, interface pfsync0 will be deleted on the firewall by the script. * OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces): generated script compares vlan and carp interfaces of the firewall with objects created in fwbuilder GUI and deletes any such interfaces it finds if they are not defined in fwbuilder. This is done even when there are no vlan or carp interfaces in fwbuilder configuration. This code is added only when checkboxes "Configure VLAN interfaces" and "Configure CARP interfaces" are checked. * OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces): New feature: generated script adds and removes CARP interfaces incrementally. This means it is not going to run ifconfig command to create carp interface if it is already there and will run "ifconfig carp1 destroy" command if interface carp1 has been removed in fwbuilder GUI to delete it on the firewall. * OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces): New feature: incremental VLAN interface management for OpenBSD and FreeBSD. When user adds or removes VLAN subinterface in fwbuilder GUI, geenrated script executes appropriate ifconfig commands to add or remove corresponding vlan pseudo-interface on the firewall machine. 2010-02-12 vadim * OSConfigurator_bsd.cpp (OSConfigurator_bsd::updateAddressesOfInterfaceCall): New feature: incremental IP address management for OpenBSD and FreeBSD. Generated script adds and removes ipv4 and ipv6 addresses of interfaces as needed. When user adds an address in the fwbuilder object, the script adds it. Second run of the same script does nothing. If user removes an address in fwbuilder, generated script removes it from the interfaces to bring actual configuration of the machine in sync with fwbuilder objects. 2010-02-10 yalovoy * src/gui/RuleSetModel.cpp: fixes #1223: GUI crash while adding a host to a group To reproduce: - open test-fw1 / Policy by double clicking Policy object - expand Objects/Groups and Objects/Hosts tree branches - open group LDA-Servers by double clicking it - drag host ldap-server1 to the group dialog 2010-02-10 vadim * UsageResolver.cpp (list): fixes #1222 modification of host or fw settings of a member firewall does not trigger cluster recompile * InterfaceDialog.cpp (InterfaceDialog::validate): fixes #1221 warning dialogs for the incorrect interface name would not go away. If user entered incorrect name of the subinterace (e.g. name that is not a valid VLAN subinterface name) the GUI would pop up warning dialog infinitely. * ../src/gui/ProjectPanel_events.cpp (ProjectPanel::event): this change attempts to fix a bug that causes main menu item Edit / Paste (keyboard shortcut Ctrl-V) to stop working. The bug is hard to reproduce and we were not able to find reliable scenario to trigger it. * PolicyCompiler_ipt.cpp (specialCaseWithFWInDstAndOutbound::processNext): fixes #1220 "bridging fw rule using all multicast object in destination does not produce any iptables rules". 2010-02-07 vadim * src/gui/ClusterGroupDialog.cpp (ClusterGroupDialog::applyChanges): fixes #1215 "Edit protocol parameters" button gets disabled for no reason. This button would get disabled after certain manipulations in the cluster group object dialog even when no changes were made. * FWCmdChange.cpp (FWCmdChangeOptionsObject::notify): fixes #1212 Cluster object was not marked for recompile when user edited conntrack group parameters 2010-02-06 vadim * src/pflib/PolicyCompiler_pf_writers.cpp (PrintRule::processNext): fixes #1210 "syntax error in PF rule - "modulate state" is required". Per bug reported in the mailing list (and according to the pf.conf manual), pf.conf requires "keep state", "modulate state" or "synproxy"if any of the stateful tracking options are used in the rule. These include "max", "no-sync", "pflow", "sloppy", "source-track" and others. * src/pflib/PolicyCompiler_pf_writers.cpp (PrintRule::processNext): fixes #1209 "incorrect syntax in PF rules when only "Activate source tracking" option is on". Compiler sometimes generated empty "( )" in the end of the pf.conf line when there were no state tracking options * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertConntrackRule): fixes #1175 "There is no option for unicast on conntrac sync-group (like heartbeat)". User can now choose between multicast and unicast for conntrackd communication. * FWWindow.cpp (FWWindow::showWelcome): fixes #1213 Welcome screen. When user starts the program for the very first time, it shows a "Welcome" screen that lists summary of features of fwbuilder and provides a link to the Getting Started Guide on the web site. Link to the local copy of Release Notes is also provided. * InterfaceEditorWidget.cpp (InterfaceEditorWidget::isValid): "new cluster" visard should permit the user to create cluster interfaces without IP addresses for any failover protocol. Disable widgets used to add virtual ip addresses only for protocol "None". All other protocols permit adding addresses regardless of the OS resource file attribute "no_ip_ok". * linux24.xml, openwrt.xml: fixed #1172 It is ok for a cluster interface with failover protocol heartbeat to have no ip address. There are legitimate configurations where admin might want to run heartbeat over an inetrface which itself has no virtual ip address, for example to confine heartbeat packets to a dedicated link. 2010-02-02 vadim * FWObjectPropertiesFactory.cpp (FWObjectPropertiesFactory::getObjectPropertiesDetailed): fixes #1201 "add parent to the object properties tooltip". Include parent name in the tooltip that is shown for interface objects. This helps identify interfaces in rules, especially subinterfaces and interfaces with common names in complex configurations with many firewall objects. * NATCompiler_ipt.cpp (ReplaceFirewallObjectsTSrc::processNext): fixes #1200 "SNAT with cluster object in TSrc uses all interfaces". When a network or host address used in OSrc of a NAT rule matches one of the interfaces of the firewall or a cluster, there is not need to use this interface for the "-o" clause in SNAT rule. 2010-02-02 glitch.vk.crocodile.org * FWWindow.cpp (FWWindow::closeEvent): fixes #1207 'status "maximized" of internal subwindows is not saved correctly' 2010-02-01 vadim * FWWindow.cpp (FWWindow::fileExit): fixes #1197 "clicking Cancel in RCS log dialog cancels log but the program still exits". * CompilerDriver.cpp (CompilerDriver::populateClusterElements): see #1198. The check of subnets defined by the member and cluster interfaces has been removed. The check originally implemented by Secuwall developers looked only at the first address of the interface and ignored others. It also did not allow for the cluster interface netmask /32, which is the case with vrrpd. All in all, the value here does not seem to be worth the effort of implementing checks for all combinations. * ../src/res/configlets/linux24/update_addresses: fixes #1196 "shell function update_addresses_of_interface() does not ignore virtual addresses of cluster inetrfaces". When generated iptables script updates ip addresses of interfaces, it should ignore addresses managed by vrrpd, heartbeat or other failover daemons. The script did not ignore them and instead removed them from interfaces. * objects_init.xml: fixes #1194 "Add standard address objects for various multicast groups". Added address objects for standard multicast groups OSPF, RIP, EIGRP, DHCP server / relay agent, PIM, RSVP-ENCAPSULATION, VRRP, IGMP, OSPFIGP-TE, HSRP, mDNS, Link-local Multicast Name Resolution, Teredo. * ObjectManipulator.cpp (ObjectManipulator::updateCreateObjectMenu): fixes #1195 the GUI should enable "new object" button and menu item when objects_init.xml library is opened * platforms.cpp (isDefaultPolicyRuleOptions): fixes #1193 default setting for "Assume fw is part of any" per-rule option is "follow global" * ../src/res/os/linux24.xml: fixes #1192 "iptables script should skip virtual addresses configured on cluster interfaces while updating addresses of interfaces". The problem only affected cluster interfaces with VRRP failover protocol. * InterfaceEditorWidget.cpp (InterfaceEditorWidget::deleteAddress): fixes #1191 "broken behavior in InterfaceEditorWidget". When user added and then deleted bunch of ip addresses to an interface in the new firewall or new cluster wizard, addresses below the deleted row were ignored. * InterfaceEditorWidget.cpp (InterfaceEditorWidget::deleteAddress): fixes #1189 "GUI crash in newFirewall dialog upon completion". GUI crashed in the new firewall wizard if user deleted an address of an interface that had 3 or more addresses. 2010-01-31 vadim * NATCompiler_ipt.cpp (ReplaceFirewallObjectsTSrc::processNext): fixes #1185 "do not include member ip addresses for cluster NAT policies". For NAT rules in a cluster, make it use only cluster ip and ignore member ips. * PolicyCompiler_cisco_acls.cpp (setInterfaceAndDirectionBySrc::processNext): fixes #1187: "regression in compiler for PIX". Rules that have cluster or firewall object in src or dst that expands to a bunch of addresses that match network zones of different interfaces should still be assigned to the interface dictated by the combination of both src and dst. There is no need to add them to the ACL of inetrface 1 in direction "outbound" if destination belongs to the network zone of inetrface 2. Rule like that should only be assigned to interface 2, direction outbound. However this does not apply to anti-spoofing rules. * NATCompiler_ipt.cpp (AssignInterface::processNext): fixes #1184 "compiler/GUI crash compiling cluster NAT rule when cluster and members have dynamic interface". It should be possible to have cluster interface that is mapped to dynamic interfaces of the member firewalls and then use this interface or whole cluster object in rules. Compiler should expand cluster object and replace it with its interfaces and corresponding interfaces of the member firewall and then correctly handle dynamic ones. 2010-01-31 yalovoy * RuleSetModel.cpp: fixes #1182 rule number column is invisible when very first rule is created in a rule set * fixes #1164 focus moves in RuleSetView after paste If i am in a rule and place the selection to service field of say rule 1 and ctrl c and then arrow down the selection to service element in rule 2 and ctrl v the focus then moves back to the rule number element of rule 2 after the paste instead of staying on the service element. likewise if i am on an element and do ctrl x it brings the focus back to the rule number element. my first expectation was that the focus would remain on the service element of the rule and not brought back to the rule number element. i guess this has something to do with refresh of the gui and you are not keeping track of which element the selection was on for the last operation. Affected files: FWCmdRule.cpp FWCmdRule.h RuleSetView.cpp RuleSetView.h 2010-01-30 vadim * change in libfwbuilder. fixes #1173 "rule ID labels do not match rule numbers when disabled rules exist in rule set". Do not remove disabled rules in PolicyCompiler::prolog() because some compilers might use RuleSet::insertRuleAtTop() and other similar methods from prolog() or addPredefinedPolicyRules() and these methods renumber rules. As the result, labels stop matching rule positions when this is done because labels are configured in prolog() method of the base class. See fwbuilder ticket 1173. Instead of dropping disabled rules in prolog(), will keep them and drop them in rule processor Begin which is always the first in all compilers. * PolicyCompiler_ipt.cpp (checkInterfaceAgainstAddressFamily::processNext): fixes #1172 "fwb_ipt does not generate rule for cluster interface with no ip address". * OSConfigurator_linux24.cpp (OSConfigurator_linux24::processFirewallOptions): fixes #1177 "problems with commands for conntrack_max, hashsize and other advanced conntrack parameters". Needed to add a line break between shell commands that set up kernel variables and those that set up conntrack kernel variables. * FWWindow.cpp (FWWindow::showSub): fixes #1181 "save state of subwindow on maximize/restore". The GUI would revert to the non-maximized subwindows display if user de-maximized subwindow, then maximized it again and tried to open new data file. * ProjectPanel_file_ops.cpp (ProjectPanel::fileNew): fixes #1178 window title stays "[Untitled]" after File/new 2010-01-30 yalovoy * fixes #1159 GUI crash on redo() : FWCmdChange.cpp FWCmdChange.h * fixes #1121 changing "rules font" in global preferences has no effect PrefsDialog.cpp RuleSetModel.cpp RuleSetViewDelegate.cpp 2010-01-30 vadim * ../src/res/os/linux24.xml: fixes #1180 "heartbeat failover protocol uses virtual ip address". New cluster wizard did not allow the user to add ip address to cluster interface configured with heartbeat failover protocol. * ../src/gui/instDialog_ui_ops.cpp (instDialog::setFlags): fixes #1176 GUI crash while compiling cluster object with no StateSyncGroup. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertFailoverRule): fixes #1174 "OUTPUT rule is not generated for heartbeat". Automatically generated rules for cluster members using heartbeat should be placed in both INPUT and OUTPUT chains. * ../src/gui/FirewallDialog.cpp (FirewallDialog::applyChanges): fixes #1171: the warning dialog asking if ip address objects should be renamed automatically appears twice. when user renames cluster, firewall, host or interface object, the GUI asks if they want to rename ip address objects as well to make them adhere to some naming convention. The warning dialog appeared twice on Mac and Windows with Qt 4.6 2010-01-29 vadim * ../src/res/configlets/linux24/installer_commands_reg_user: try to cancel reboot only if one is pending. This avoids a warning saying "cant find pid of running shutdown" every time user installs updated iptables script on Linux firewall. Fixes #1169 Fwbuilder can schedule reboot in a few minutes if user installs updated policy in "test mode" and requests reboot as a brute-force rollback to safeguard against locking themselves out of the firewall in case of error in the policy. * ../src/gui/ObjectManipulator_ops.cpp (ObjectManipulator::autorename): cluster failover group objects are now included in the algorithm that automatically renames addresses of interfaces when user renames firewall or cluster object. Fixes #1170 * ../src/gui/ObjectManipulator_slots.cpp (ObjectManipulator::copyObj): show a not on the status bar whenever user copies an object to clipboard. fixes #1167 2010-01-28 vadim * ../src/gui/ProjectPanel.cpp (ProjectPanel::isManipulatorSelected): fixes #1130 "Ctrl-C , Ctrl-V shortcuts do not work for selected objects in rule elements". Global keyboard shortcuts Ctrl-C, Ctrl-V, Ctrl-X should work on objects in rule elements when keyboard focus belongs to the rule set view or on objects in the tree when focus is on the tree. This also fixes #1138 "ctrl+x and edit->cut problems in both Policy and NAT". These keyboard shortcuts operate only on objects in the tree and rule elements but not on rules. Visual difference between the state when whole rule is selected and the state when an object is selected in one of the rule elements is insufficient so making Ctrl-X cut whole rule may appear unextected for the user. 2010-01-26 vadim * RuleSetView.cpp (RuleSetView::showContextMenu): fixes #1155 context menu is not updated on rule enable/disable * NATCompiler_PrintRule.cpp (PrintRule::processNext): fixes #1147 --persistent option for DNAT and SNAT. This adds support for the "--persistent" option in NAT rules. Version should be set to 1.4.3 or later in the firewall object. * NATCompiler_PrintRule.cpp (PrintRule::processNext): fixes #1146 support for NAT MASQUERADE source port randomization. This adds support for the "--random" option for SNAT, DNAT and MASQUERADE targets in iptables NAT rules. User needs to turn on the checkbox that adds this option in NAT rules again 2010-01-26 yalovoy * RuleSetView.cpp: fixes #1145 show keyboard shortcuts for "move rule up/down" in the rule context menu * RuleSetView.cpp: fixes #1158 ctrl page up/down breaks arrowing in the ruleset 2010-01-26 vadim * FWCmdChange.cpp (FWCmdChange::notify): fixes #1139 GUI crash on click in undo panel view. Sequence that caused crash: 1) new firewall next next finish 2) rename firewall couple of times 3) click to top of undo stack and it crashes * DiscoveryDruid.cpp (DiscoveryDruid::createRealObjects): fixes #1144 after snmp discovery object attributes are not shown properly in the tree 2010-01-25 vadim * ProjectPanel_file_ops.cpp (ProjectPanel::chooseNewFileName): fixes #1157 Qt dialog does not detect conflict of filenames properly for linux. When user tried to create new file using File/New or save existing one using using File/SaveAs and entered a name without extension when prompted to enter the file name, the program would overwrite existing file with the same name and suffix ".fwb" without warning. This happened on Linux but did not happen on Mac OS X where dialog automatically added the suffix to the file name. * PolicyCompiler_pf.cpp (PolicyCompiler_pf::insertCarpRule): fixes #1152 CARP and pfsync rules should match "in" and "out". Automatically added rules for CARP and pfsync for the PF firewall should match in both directions, rather than just "out". * NATCompiler_ipt.cpp (AssignInterface::processNext): fixes #1150 "fwb_ipt should check AddressRange in TSrc against addresses of interfaces". Compiler for iptables finds interface that matches AddressRange object used in Translated Source of a NAT rule and uses it for the "-o intf" clause. Addresses of interface can match the range excactly or partially. Exact match is when range boundaries match the beginning and the end of the subnet defined by the interface address and netmask. Partial match is when one of the range boundaries belongs to the subnet but another one does not. In this case compiler uses inetrface but issues a warning. If interface has multiple ip addresses, all of them are taken into consideration and interface is used if at least one matches. If address range in TSrc is wide and matches subnets of several interfaces, compiler splits the rule and uses all of them but does not replace the range with narrower one and still issues a warning. * ProjectPanel.cpp (ProjectPanel::getDestDir): fixes #1149: ProjectPanel::getDestDir should use userDataDir dir on all OS 2010-01-24 yalovoy * #1127 GUI crash when clicking in undo panel 1) new firewall (set name, Next, Next, Finish) 2) add interface 3) open Policy rule set view 4) insert rule 5) drag interface to the "Interface" rule element of the rule 6) click on in the undo panel 6) click on the last entry in the undo panel Affected files: RuleSetModel.cpp * #1132 Keyboard shortcuts for moving rules with "move up", "move down" Affected files: src/gui/RuleSetView.cpp, src/gui/RuleSetView.h * #1131 after rule moves with "move up" or "move down", it loses selection Affected files: src/gui/RuleSetView.cpp, src/gui/RuleSetView.h, src/gui/FWCmdRule.cpp * #1142 GUI crash on moving rule into a group with russian name Affected files: src/gui/RuleSetModel.cpp 2010-01-23 vadim * ../src/gui/FWWindow.cpp (FWWindow::startupLoad): fixes #147: show Release Notes only once when user starts the program for the first time. When user upgrades to a new version, Release Notes for it will be shown once again. Show tip of the day on all subsequent runs, unless user disables it. * instDialog_ui_ops.cpp (instDialog::setFlags): fixes #1136: "install" checkbox appears next to the cluster object in instDialog and "compile" checkoxes appear next to cluster member firewalls. 2010-01-23 yalovoy * FWCmdRule.cpp (FWCmdRuleInsert::redoOnModel): refs #1127: GUI crash when clicking in undo panel. * FWCmdRule.h * RuleSetModel.cpp * RuleSetModel.h 2010-01-22 vadim * PolicyCompiler_iosacl.cpp (PolicyCompiler_iosacl::compile): fixes #1134: object-group clause can only be used with ipv4 access lists in IOS per http://www.cisco.com/en/US/docs/ios/sec_data_plane/configuration/guide/sec_object_group_acl.html#wp1058359 * IOSObjectGroup.cpp (IOSObjectGroup::toString): fixes #1107: support for "object-group" clause in IOS access lists. Fixed syntax for the subnet clause inside "object-group network". 2010-01-21 vadim * RuleOptionsDialog.cpp (RuleOptionsDialog::limitLabelChange): Added support for negation in the "-m limit --limit rate" clause for iptables. 2010-01-20 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printModules): fixes #1123, #1124: Text label next to the option that translates into --connlimit-above clause for the iptables "connlimit" module now matches description in the iptables manual. Added checkbox that allows the user to add negation to the generated code (make it ! --connlimit-above NN) * IOSObjectGroup.cpp (IOSObjectGroup::toString): Refs #1107: first draft of the object-groups support for Cisco IOS. Controlled by a checkbox in the "Advanced" settings dialog of the firewall object; this feature requires IOS v12.4(20)T or later and is off by default. * CompilerDriver.cpp (CompilerDriver::validateClusterGroups): fixes #1119 "add test for the integrity of failover cluster groups". Compilers require all failover group objects to be configured with interfaces of member firewalls. * PolicyCompiler_cisco_acls.cpp (setInterfaceAndDirectionBySrc::processNext): fixes #1120 "redundant commands generated for ssh access". Compiler for PIX generated two "ssh address netmask inside" commands for the same rule that permits ssh to the firewall. * CompilerDriver_pix_run.cpp (CompilerDriver_pix::assembleFwScript): fixes #1106 "fwb_pix does not include prolog". Prolog script was not included in generated configuration if firewall object was converted from some other platform because FirewallOptions? object inherited old "prolog_place" variable * Helper.cpp (Helper::findInterfaceByNetzone): fixes #1118 "fwb_pix uses wrong interface compiling the second cluster member". NAT compiler for PIX failed to find interface with correct network zone if interface was a child of another interface, e.g. vlan subinterface. * clusterMembersDialog.cpp (clusterMembersDialog::getSelectedMembers): fixes #1117 "failover group member editor loses interfaces". If failover group included vlan interfaces of the member firewalls, the dialog that appears when user clicks on "manage members" button would not show members at all. * NATCompiler_pix.cpp (NATCompiler_pix::_expand_interface): fixes #1115: "fwb_pix crash compiling cluster NAT rule set with interface in TSrc". A cluster interface was used in the TSrc rule element of a NAT rule. Cluster interfaces of PIX cluster have no ip addresses of their own (PIX HA pair uses ip addresses of the master unit), this caused rule element to become empty after interface object was supposed to be replaced with its ip address. 2010-01-19 vadim * ../src/cisco_lib/NATCompiler_pix.cpp (NATCompiler_pix::compile): fixes #1108: fwb_pix: incorrect access list is generated for "static". When a firewall or host object with an interface that was configured with netmask that was not 255.255.255.255 (i.e. configured correctly) was used in TDst of a NAT rule for PIX firewall, compiler generated configuration that used subnet instead of just the address of the inetrface. * (NATCompiler_pix::_expand_interface): reimplemented virtual method Compiler::_expand_interface() to process cluster interfaces. Using member interface instead of the cluster interface while compiling the rule. * (createNATCmd::processNext): fixes #1114: "fwb_pix crash when fw with dynamic interface is used in TDst". * ../src/iptlib/NATCompiler_ipt.cpp (VerifyRules2::processNext): fixes #1109: "rules that do not pass verifyRules() checks may cause compiler crash in test mode or gui crash in single rule compile mode" * CompilerDriver.cpp (CompilerDriver::formSingleRuleCompileOutput): fixes #1110: "when compiler detects fatal error and drops the rule that caused it, the error does not appear in the single rule compile output". * ../src/pflib/TableFactory.cpp (TableFactory::createTablesForRE): fixes #1111: "NAT compiler for PF does not recognize dynamic interface of the firewall in rule element". Compiler issued an error that it can not generate code using dynamic interface that does not belong to the firewall because its address is unknown. * ../src/cisco_lib/NATCompiler_pix.cpp (VerifyRules::processNext): fixes #1104: policy compiler for PIX crashed when it enountered NAT rule trying to trsnslate both source and destination addresses. * ../src/cisco_lib/Helper.cpp (triplet::hash): fixes #1105: compiler for PIX crashed when interface with dynamic address was used in ODst of a NAT rule. 2010-01-17 vadim * instDialog_ui_ops.cpp (instDialog::checkIfNeedToInstall): Regression: fixed #1092 "missing "install" checkboxes in the list of firewalls on the first page of the installer wizard". Checkboxes "install" disappeared randomly from the first page of the installer wizard. 2010-01-16 vadim * FWCmdAddObject.cpp (FWCmdAddObject::redo): fixes #1088 "duplicate objects on redo". Click on the last line in undo stack view created duplicate objects in the tree if some undo/redo commands created new objects. * ObjectManipulator_create_new.cpp (ObjectManipulator::newInterfaceAddress): fixes #1090: extra undo command added to the stack on "New address" * FWWindow.cpp (FWWindow::event): If user opens two data files with the same names but located in different directories, titles of the subwindows, the list in the main Windows menu and entries in the recently opened files list will display full path. See #936 * FWWindow.cpp (FWWindow::fileOpen, FWWindow::alreadyOpened): The GUI should not let the user open the same data file twice. If user tries to do this, even using different (e.g. relative) path, the program will instead activate project window that already holds this file. Still can not open the same data file in two subwindows. See #396 2010-01-15 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::compile): Using rule processor Compiler::checkForObjectsWithErrors to find objects with errors and generate proper calls to abort(). This exposes errors that happened when Preprocessor failed to resolve compile-time AddressTable and DNSName objects. If compiler runs in test mode, preprocessor did not abort but used dummy substitution addresses and continued. Call to checkForObjectsWithErrors generates proper error messages tied to rules. Using this rule processor in all compilers. Fixes #1087 * PolicyCompiler_ipt.cpp (processMultiAddressObjectsInRE::processNext): fixes #1086: incorrect processing of run time address tables. SourceForge bug 2932680. Rules with two run-time AddressTable objects in the same rule element (source or destination) were converted to the shell script that read addresses from the address table files, plus wrong iptables command that matched any to any. This change removes this extra command. * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printShellFunctions): fixes #1084 "if all user turns off all interface management and configuration checkboxes, the check_tools shell function is not added to the script but still called". Shell function "check_tools" verifies that system tools iptables script needs to operate properly are installed on the firewall. These are: ip, modprobe and optionally vconfig, brctl, ifenslave. The bug made compiler for iptables to add the call to the function but function definition was missing if user unchecked all "configure interfaces" checkboxes in the Script tab of firewall object settings dialog. * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): Refs #869 making sure non-english comments appear correctly in the single rule compile output and generated configuration files and scripts. 2010-01-14 vadim * FirewallInstaller.cpp: fixed #1083: "installer uses incorrect path when GUI runs on windows" (Sourceforge bug #2932446). Built-in installer used incorrect path on the firewall to store copy of the .fwb data file. This happened only when the GUI ran on Windows. * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): Added support for pf state tracking options "no-sync" and "pflow". Set version to "4.5" or "4.6" in the firewall object to be able to use these new options. 2010-01-13 vadim * CompilerDriver.cpp (CompilerDriver::commonChecks2): fixes #1080: "Add warning when "top" rule set is missing". All compilers issue a warning when the firewall has no top level NAT or Policy rule set. This could be an important error because rule set is used to generate iptables rules for the built-in chains INPUT/OUTPUT/FORWARD or the main PF rules. However there are legitimate cases when administrator may want to use fwbuilder to only generate iptables commands for a custom chain or configuration for a custom PF anchor, in which case this is not an error. Compilers generate warning for this condition to bring it to the attention of administrator but continue processing the rules. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::flushAndSetDefaultPolicy): fixes #178: "remove chain initialization commands in the single rule compile output". Lines that create chains do not need to be printed when user compiles just one rule, they take up display space and do not provide any useful information. * PolicyCompiler_PrintRuleIptRst.cpp (PrintRuleIptRst::_printRuleLabel): really fixed #869 '"compile rule" should also print the comment'. Printing rule comment in the compiler output in the single rule compile mode when firewall object is configured to use iptables-restore. Code that prints rule label and comment has been unified for compilers for all firewall platforms. 2010-01-12 vadim * TCPServiceDialog.cpp (TCPServiceDialog::applyChanges): fixed bug #1076: "when the start of a port range is greater than the end, the GUI goes into a loop showing error dialogs". Ths problem affected TCP and UDP service objects 2010-01-10 vadim * TableFactory.cpp (TableFactory::PrintTables): suppress comment "Tables: (0)" in the compiler for PF output when there are no tables. * CompilerDriver.cpp (CompilerDriver::findImportedRuleSets): fixed bug #1072: "member ruleset override produces empty config files for PF". In this case, cluster nat rule branched to a separate nat rule set. There was nat rule set with the same name in the member firewall but compiler seemed to ignore it and produced empty .conf file for this rule set. The warning about member having rule set with the same name was not issued * NATCompiler_pf.cpp (checkForDynamicInterfacesOfOtherObjects::findDynamicInterfaces): fixed bug #1071 "can't use dynamic cluster interface in NAT rules for PF". In this case, cluster has interface rl1 which is mapped to dynamic interfaces rl1 of two member firewalls. Cluster interface object is used in the TSrc of a NAT rule. Compiler refused to compile this rule with error "cluster:NAT:2: error: Can not build rule using dynamic interface 'rl1' of the object 'member1' because its address in unknown." 2010-01-09 Vadim Kurland * src/res/configlets/openwrt/installer_commands_root: Added support for OpenWRT. Generated iptables script has standard format of the OpenWRT system scripts and should be installed in /etc/init.d/. The script loads firewall policy when it is started with command line argument "start" and stops it when it runs with argument "stop". Other standard arguments recognized by OpenWRT startup scripts are also supported. To make the system run fwbuilder script during boot, run it with argument "enable". See Release Notes for more details. * OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces): Added support for configuring ipv6 addresses of interfaces for *BSD, including CARP cluster interfaces 2010-01-08 Vadim Kurland * NATCompiler_ipt.cpp (AssignInterface::processNext): fixed bug #1064: "Dedicated IPv6 interfaces show up in IPv4-NAT rules". Use interface only if it has addresses that match address family we compile for. * PolicyCompiler.cpp (PolicyCompiler::checkInterfacesForShadowing): (change in libfwbuilder) include interface rule element in the shadowing detection algorithm. See ticket #1068 2010-01-07 Vadim Kurland * FWObjectPropertiesFactory.cpp (FWObjectPropertiesFactory::getObjectPropertiesBrief): fixes #1059: "set attribute field in gui tree for policy and nat based on its settings". Show "top ruleset" and "ipv4" or "ipv6" in the second column of the object tree for rule set objects. * ProjectPanel_file_ops.cpp (ProjectPanel::loadLibrary): fixed bug #1053 "duplicate objects created on "Import library" operation". When user used "File/Import Library" function, the library is checked for objects with duplicate IDs. Library name is also checked for duplicates and changed by adding suffix "-1" if it matches existing library name. This means the same library can now be imported several times, which creates several copies (all with their unique IDs to make XML file valid) 2010-01-06 vadim * bug fixes in installer for PF: fixed commands it runs on the firewall when it authenticates as regular user. * ObjectManipulator_create_new.cpp (ObjectManipulator::newInterface): fixed bug #1051: GUI crash when user tried to add an interface to an interface. * CompilerDriver_pf.cpp (CompilerDriver_pf::getRemoteConfFileName): fixed bug #1049 (SourceForge bug #2927165) '(windows only) installer uses incorrect path on the OpenBSD firewall' 2010-01-01 vadim * instOptionsDialog.cpp (instOptionsDialog::instOptionsDialog): fixed bug #1043: added explanation of the risk associated with password caching to the Preferences dialog and Release Notes; checkbox "remember passwords" will be disabled if user name is not configured * ObjectManipulator_tree_ops.cpp (ObjectManipulator::updateLibName): fixed bug #1042: editing name of a library updates it in the tree but does not update it in the drop-down list 2009-12-29 vadim * RuleSetView.cpp (RuleSetView::restoreCurrentRowColumn): fixed bug that caused rule set view to scroll all the way to the top every time user modified any object used in the rules. Fixes #968 2009-12-28 vadim Ticket #1040 (Another GUI crash in newClusterDialog) closed by a2k fixed Ticket #1038 (GUI crash in newClusterDialog on Ubuntu 8.04) closed by a2k fixed: (In [2296]) Fixed #1038 Ticket #1014 (fix tab order of elements in iptadvanceddialog_q.ui) closed by a2k fixed: (In [2292]) Fixed #1013, #1014, #1015, #1016, #1017 Ticket #1015 (fix tab order in pixadvanceddialog_q.ui) closed by a2k fixed: (In [2292]) Fixed #1013, #1014, #1015, #1016, #1017 Ticket #1016 (fix tab order in pfadvanceddialog_q.ui) closed by a2k fixed: (In [2292]) Fixed #1013, #1014, #1015, #1016, #1017 Ticket #1017 (fix tab order in openbsdadvanceddialog_q.ui) closed by a2k fixed: (In [2292]) Fixed #1013, #1014, #1015, #1016, #1017 Ticket #1013 (fix tab order of elements in iosacladvanceddialog_q.ui) closed by a2k fixed: (In [2292]) Fixed #1013, #1014, #1015, #1016, #1017 Ticket #1030 (firewall name should be prepended with library name in the list on the ...) closed by a2k fixed: (In [2290]) Fixed #1030 Ticket #1025 (newCLuster dialog loses all interface addresses if user hits Back on the ...) closed by a2k fixed: (In [2289]) Fixed #1025, #1019 Ticket #1019 (unit test failure) closed by a2k fixed: (In [2289]) Fixed #1025, #1019 * instDialog_ui_ops.cpp (instDialog::setFlags): For the PIX cluster, built-in installer installs generated configuration only on the master member firewall. It determines which one is the master by looking in the StateSyncGroup object (state synchronization cluster group). Fixes #998 * fixed a bug in the rule options dialog: if user tried to edit iptables log prefix for the rule and deleted a character in the middle of the string, cursor jumped to the end of the line. Also, undo command was created for each keystroke in this input field. fixes #1037 2009-12-27 vadim * PolicyCompiler_iosacl.cpp (PolicyCompiler_iosacl::addDefaultPolicyRule): compiler for IOS ACL added only inbound automatic rule to permit ssh access from the management workstation but did not add a rule to permit reply packets. This fixes #993 * CompilerDriver_iosacl_run.cpp (CompilerDriver_iosacl::run): fixed bug (no #): compiler for iosacl failed to open output file because of the wrong path. * pfAdvancedDialog.cpp (pfAdvancedDialog::pfAdvancedDialog): fixed SF bug #2919941 "Wrong optimization flag for PF". If "For high latency" is selected the compiler outputs the following value for OpenBSD PF: "set optimization For high latency". Which is wrong syntax, should be high-latency. Fixes #1005 * bug fixes and changes 2009-12-27: Ticket #1032 ("creating cluster from selected firewalls" does not work) closed by vadim fixed: (In [2279]) Ticket #1031 ("New Cluster" function creates two undo commands and two cluster objects) closed by vadim fixed: (In [2278]) Ticket #969 ("Create and add to group" creates several undo commands) closed by yalovoy fixed: (In [2277]) 2009-12-26 vadim * ObjectManipulator_ops.cpp (ObjectManipulator::actuallyPasteTo): when an object was duplicated to another library, suffix "-1" was appended to its name even if there were no other objects with the same name. Also when an object was pasted into a group, its name was preserved. If the group had an object with the same name and user opened new one in the editor and tried to change anything, the program complained about duplicate name. fixes #1028 * newClusterDialog.cpp: program crashed when user tried to create new cluster dialog and turned the option to copy rules from one of the members to the cluster. Fixes #1026 2009-12-25 vadim * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed bug #1022: context menu item "New Interface" is disabled. if user selected an interface object in the tree and opens context menu, the "New Interface" menu item was always disabled. 2009-12-23 vadim * instOptionsDialog.cpp (instOptionsDialog::instOptionsDialog): Added support for the "dry run" installer option for Cisco routers. When this option is on, installer logs into the router and switches to the enable mode, but does not execute any actual commands. If scp is used to copy configuration to the router, installer will copy the file but will not activate it. This tests ssh session in general, login password, enable password and scp but does not make any changes to the router configuration. * OSConfigurator_pix_os.cpp (OSConfigurator_pix_os::_printSSHConfiguration): Implemented pushing of the PIX configuration using scp. This requires PIX v7, ssh v2 and scp should be enabled on the firewall. This method is much faster than running configuration line by line. Controlled by a checkbox in the pix advanced settings dialog. fixes #995 2009-12-22 vadim * 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 reloading the router. EEM appears in IOS 12.4 and supports background operations that can be triggered by some events on the router or by timers. In this new feature, fwbuilder creates EEM applet with a countdown timer that executes command "config replace nvram:startup-config force" when timer expires. User has the following options: - install updated ACL configuration and schedule automatic rollback in a few minutes. This can be used to test new policy and revert to the original one after some short period of time. This also helps to avoid a situation when updated policy blocks access to the router because of an error; rolling back to the ACL configuration that was running before the update will restore access automatically. - install updated ACL, schedule rollback in a few minutes but cancel rollback if installation of the new configuration was successful. This is mostly intended to prevent blocking access to the router in case of an error in the new ACL configuration. If fwbuilder was able to enter all lines of the new configuration all the way to the end, then new configuration does not block access and installer executes command "no event manager applet fwbuilder-rollback" to cancel scheduled rollback. 2009-12-21 vadim * bug fixes and changes for 2009-12-21: Ticket #982 (raise floating tree window when user switches between different project windows) closed by vadim fixed: (In [2233]) Ticket #981 (Error entering new service. User could not change port range start before changing port range end for TCP and UDP services) closed by vadim fixed: (In [2234]) Ticket #983 (crash on IOS configuration import) closed by vadim fixed: (In [2235]) Ticket #875 (unit tests for the policy importers) closed by a2k fixed: (In [2237]) Ticket #897 (Add paragraph to the release notes explaining new "conntrack" tab in host OS dialog for Linux) closed by vadim fixed: (In [2239]) Ticket #901 (mention support for openWRT in release notes) closed by vadim fixed: (In [2239]) Ticket #900 (mention support for ipcop in release notes) closed by vadim fixed: (In [2239]) Ticket #899 (paragraph about script structure and command line args in release notes) closed by vadim fixed: (In [2239]) Ticket #788 (review ChangeLog and update release notes for v4.0) closed by vadim fixed: (In [2240]) 2009-12-20 vadim * interfaceProperties.cpp (interfaceProperties::validateInterface): permit unnumbered cluster interfaces. If member firewalls have unnumbered interfaces that user wants to use in rules, then cluster needs corresponding cluster interface as well. Previously the GUI did not allow copy/paste of an unnumbered interface from a firewall to a cluster and compiler complained about such interface not having ip address. Now both operations are permitted. * minor bug fixes: Ticket #971 (cluster interface should inherit properties of the member interfaces) closed by vadim fixed: (In [2225]) refs #487 fixes #966, #971 Ticket #947 (Add new options to the "help" dialog) closed by vadim Ticket #975 (if fw object has empty platform, it can not be changed) closed by vadim fixed: (In [2228]) Ticket #977 (context menu items Delete and Cut are disabled if library is Template ...) closed by vadim fixed: (In [2229]) Ticket #974 (fw template 3 is broken) closed by vadim Ticket #979 (recognize extension .fwl for the template file) closed by vadim 2009-12-19 vadim * src/res/configlets/linux24/status_action: Fixes #954 : generated iptables script now recognizes "status" command line parameter. When the script runs with this parameter, its exist status code indicates the state of the firewall: 0 means iptables modules are loaded and some rules are configured; 3 means either modules are not loaded or there are no tables. The script can not verify that the rules are those configured in fwbuilder, it only verifies that modules are loaded and there are some rules. Configuration with no rules but with default policies, even if these policies are ACCEPT in all chanins, returns "0" return code. This is consistent with behavior of /etc/rc.d/init.d/iptables script on Fedora Core Linux. * RuleSetView.cpp (RuleSetView::changeAction): fixed #957: when user changes action of a policy rule, it should be opened in the editor only if the new action has some parameters that can be edited. Such actions as "accept" and "deny" have no parameters and it does not make sense to open blank editor panel. * Ticket #959 (context menu items appear rearranged) closed by a2k fixed: (In [2212]) Fixed #959 * Ticket #958 (when user compiles single firewall, skip the first page of the wizard) closed by a2k fixed: (In [2210]) Fixed #958 * Ticket #952 (tooltips in RuleSetView should be controlled by ...) closed by yalovoy fixed: (In [2209]) fixes #952 tooltips in RuleSetView? should be controlled by т€І * Ticket #941 (Add Rule Below adds the new rule above) closed by yalovoy fixed: (In [2208]) fixes #941 Add Rule Below adds the new rule above * Ticket #951 (double click on an object in the group member list should open it in the ...) closed by a2k fixed: (In [2206]) Fixed #951 * Ticket #931 (context menu item "New cluster from selected firewalls" should be enabled ...) closed by a2k fixed: (In [2205]) Fixed #931 2009-12-18 vadim * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): generated script can now install backup ssh access rule when it shuts down the firewall. This is optional and is controlled by a checkbox in the "advanced settings" dialog for iptables firewall. To shut down the firewall user should run the script with command line option "stop". fixes #939 2009-12-17 vadim * fixed bug in the GUI: when user duplicated an object, it was created with the same name as the original, then the program complained about duplicate name on every attempt to modify it. * creating IPv4 or IPv6 address object using main "New object" menu ended up creating two identical objects instead of one * built-in policy installer failed if the GUI was running on Windows, the firewall was running CentOS5 system and regular user account was used to authenticate * fixed bug in the GUI: it was not possible to add interface object to the "Interface" rule element of Policy and Routing rules. * fixed bug in the GUI: if the user hit Tab to move from one input field in the object editor to another after making some changes, keyboard focus jumped to the object tree. * improvement in the built-in policy installer: now installer dialog terminates background ssh or scp process if user clicks "Cancel" or closes dialog window in the middle of the process. * documentation: Added comment to all configlet files explaining how user can modify them. 2009-12-16 vadim * src/res/configlets/linux24/installer_commands_root: Added command "chomd +x" to make firewall script executable on the firewall. Before, this was only done when the program used regular user account rather than root. Fixes #909 * src/res/configlets/linux24/installer_commands_root: Built-in policy installer gets commands that it needs to execute on the firewall from configlets (small scripts using simple macro language) that are installed in the /usr/share/fwbuilder-3.1.0/configlets on Linux. User can modify them by making a copy in $HOME/fwbuilder/configlets without having to touch the code. Fixes #268. 2009-12-15 vadim * FirewallInstaller.cpp (FirewallInstaller::readManifest): fixed bug in installer: when the GUI ran on Windows, the path of the file on the firewall was generated with mixed separators '/' and '\'. As the result, pscp.exe failed to copy the file to the firewall. * OSConfigurator_linux24::printInterfaceConfigurationCommands: call shell function clear_addresses_except_known_interfaces() with a list of all interfaces configured in fwbuilder. This will clear ip addresses of interfaces that are not configured in fwbuilder and bring them down. Before, the call to this function did not include dynamic interfaces and as the result, the script deleted their addresses and brought them down. * ../src/res/os/linux24.xml: the GUI and compiler should not assume that when failover protocol is VRRP, then there should be interface vrrpN. This seems to be the case and the default only for Secunet Secuwall firewall. Vrrpd daemon on Linux does not create vrrp inetrfaces and just manipulates alias IP and MAC addresses. Fixes #895 * objects_init.xml: Standard objects library now comes with new IPv6 Network objects. These objects represent IPv6 networks that should not be routed on the Internet. Included: RFC3849 "Documentation Network" 2001:db8::; RFC4291 "Link local" fe80::/10; RFC4773 "Experimental Network" 2001:0000::/29 to 2001:01F8::/29. Also added a group "ipv6 private" that includes all these networks. Fixes #888 * instDialog.cpp (instDialog::instDialog): Moved "batch install" checkbox to the page that shows compiler progress so the user can decide to do batch install right before they perform installations instead of doing this before they start compile. 2009-12-14 vadim * src/res/configlets/linux24/automatic_rules: Generation of the automatic rules (matching ESTABLISHED and INVALID states, backup ssh access and others) now uses configlet. Fixes #883 * src/res/configlets/linux24/automatic_rules: generated script can now include automatic rules to match IPv6 neighbor discovery ICMP6 packets. This is controlled by a checkbox in the iptables "advanced" settings dialog and is off by default. Fixes #878 * PrefsDialog.cpp (PrefsDialog::accept): Added a place in the global Preferences dialog for options specific for different object types. First parameters include options for DNSName and AddressTable to let the user decide if the newly created objects of these types should be automatically configured with "Compile Time" or "Run Time" mode. Also, added an option that makes DNSName object editor copy the name of the object into the DNS record input field when new object is created or whenever the name changes. This is useful when the user does not want to keep object name and dns record different because they need to enter the name only once. * DNSNameDialog.cpp (DNSNameDialog::applyChanges): If global Preferences option "Use DNS Name object name for the DNS record" is turned on, copy the name into the record on every name change. Fixes #866 2009-12-11 vadim * GroupObjectDialog.cpp (GroupObjectDialog::newObject): Implemented feature request #2245537 "Add service object to service groups directly from groups". Group object dialog now has a button that shows a menu when clicked, this menu allows the user to create new object and add it to the group in one operation. This fixes #119 * ObjectManipulator::addNewObjectMenuItem: fixes #850 Redesigned methods used to create "new object" menu and call functions that create new objects to be able to build menus with limited sets of new object types. * ../src/gui/FWBTree.h (class FWBTree): added methods getTranslatableObjectTypeName and getTranslatableNewObjectMenuText that return translatable strings for the given object type name. 2009-12-09 vadim * FindWhereUsedWidget.cpp (FindWhereUsedWidget::_find): "Find where used" function can now find all uses of the given object, as well as all uses of its children. For example, if the object is firewall, then this function can find all groups and rules that refer to it directly, or to it and all its interfaces and their addresses. This extension is optional, it is controlled by a checkbox in the "Find" dialog. 2009-12-08 vadim * ../src/fwbedit/merge.cpp: fixed bug #2794851 (fwbuilder bug #202): "Ability to import Library using fwbedit". User can now merge objects from two files together using fwbedit just like the "Import library" function in the GUI. 2009-12-07 vadim * instDialog_ui_ops.cpp (instDialog::getInstOptions): fixed bug #2908220 (fwbuilder bug #803): "Running fwbuilder as root hardcodes batch install user". Built-in installer ignored user name entered in the installer options dialog and communicated with the firewall using the name of the user running the program. 2009-12-04 vadim * ../src/res/platform/pf.xml, iptables.xml: unified terminology for policy rule actions that create branching in the rule set or tag packets. Now we call these actions "Branch" and "Tag" for all platforms. Before, the name was different and matched original action on each platform, that is for PF it was "Anchor" and "Tag" and for iptables "Chain" and "Mark" respectively. 2009-12-01 vadim * src/res/configlets/linux24/run_time_wrappers: fixed #651: "support for dynamic ipv6 addresses is broken". When an interface with dynamic address was used in a rule in IPv6 rule set, generated shell script was supposed to read its IPV6 address and use it in the rule. This code was broken and never worked properly. Implemented idea for getaddr6 code suggested by , it now reads all IPv6 addresses of the interface and uses them in the rule via shell "for" loop. Implemented the same change for IPv4 as well. This changes behavior of the generated iptables script compared to fwbuilder v2 and v3 where it only used the first IPv4 address of the dynamic interface. In v3.1 and v4 it will use all addresses of such interface. 2009-11-29 vadim * newClusterDialog.cpp (newClusterDialog::finishClicked): New feature: the wizard that creates new cluster object starts with the list of firewall objects where the user can choose which firewalls should become members of the cluster. Next, the program finds interfaces of the member firewalls that have the same name and can be part of the cluster and creates cluster interfaces with the same name. Not all interfaces are eligible, for example bridge ports, bonding interface slaves or parents of vlan interfaces can not be used for the cluster. Cluster interfaces define failover groups. The user can add, remove or rename cluster interfaces, as well as change which interfaces of the member firewalls are used with each one. On the next page of the wizard user changes failover protocols and can add or remove or change ip addresses of cluster interfaces. Not all failover protocols require ip addresses, for example VRRP or CARP do but heartbeat or OpenAIS don't. Finally, the user can choose to use policy and NAT rules of one of the member firewalls to populate Policy and NAT rule sets of the new cluster. If this is done, all references to the original member firewall and its interfaces in rules are replaced with references to the cluster and its interfaces. The program also creates backup copies of the member firewall objects with the name with suffux "-bak" and clears Policy and NAT rule sets of the member firewall objects used with the cluster before new cluster is created. 2009-11-21 vadim * ObjectEditor.cpp (ObjectEditor::apply): New feature: behavior of all object dialogs has changed. According to the results of the user community opinion poll and discussion, object dialogs are losing button "Apply". All changes made in dialog entry fields are saved into the object immediately. This does not change the data in the .fwb file, only objects in memory. Combined with Undo, this allows for faster object editing and roll back of changes. * New feature: Undo/Redo facility. Undo supports changes to object parameters in editors, creation of new objects, deletion of objects, adding and removed objects to groups. Undo stack can be displayed in a special docked window. 2009-11-14 vadim * newFirewallDialog_from_template.cpp (newFirewallDialog::replaceReferencesToNetworks): New feature: when user creates new firewall from a template, the wizard dialog now offers a new page where they can change ip addresses of the interfaces of the template. User can change name, label, address, netmask, MAC address and type (regular/dynamic) of the interface, as well as add and delete interfaces. The program then creates interface objects with new parameters and updates policy and NAT rules of the template. It creates new Network and NetworkIPv6 objects using new addresses and replaces references to network objects that match old addresses with references to these new objects in rules and groups. This eliminates the need to do manual search and replace to update firewall object created from a template to make it match actual user network configuration. Fixes #613 2009-11-10 vadim * configlets/pix_os/failover_commands: New feature: Added ability to generate failover commands for PIX. Summary: - only "lan" type failover configuration is supported - one interface in each member firewall should be marked as "dedicated failover" interface. These interfaces must have the same name. - cluster should have interface with the same name as failover interface of the member firewalls; this cluster interface should have failover cluster group child object. The failover group is configured with failover interfaces of both members. One interface must be marked as "master". Compiler checks for this. - Protocol in this failover group should be configured as "PIX failover protocol" - cluster must have state synchronization cluster group object, configured with interfaces of member firewalls. Use the same interface as for the failover or another dedicated inetrface. In the latter case interface objects of the member firewalls used for state sync must be marked as "dedicated failover" as well. - Failover and state sync groups should have the same member firewall configured as "master". Compiler checks for this. - Regular interfaces: cluster should have interface object with the name matching corresponding interface of member firewalls. Each of these cluster interfaces should have failover cluster group child object configured with member firewall interfaces. Protocol in this failover group can be set to "None" (or blank). It is also not necessary to mark member interface as master. * OSConfigurator_pix_os.cpp (OSConfigurator_pix_os::_printInterfaceConfiguration): Using configlet to generate interface configuration commands for PIX. Now user can change generated script if necessary without making changes in the fwbuilder code. * ObjectManipulator.cpp (ObjectManipulator::libChanged): Experimental change in the GUI, new feature: Now the program does not switch object in the editor on a single click in the tree. User should double click object in the tree or use context menu item "Edit" to open object in the editor. User can select different object in the tree or switch to another library while editor has unsaved changes. This helps, for example, when they need to populate large object group and need to switch between libraries to find objects. Switching to another library or accidentally clicking on a wrong object in the tree does not cause editor to switch. 2009-11-09 vadim * CompilerDriver_pix_run.cpp (CompilerDriver_pix::run): Added support for failover configurations for PIX. - Interfaces of member firewalls used for failover configuration should be marked as "Dedicated failover" interfaces. They should have normal IP addresses. These interfaces will be used to generate "failover" commands in the PIX configuration. - Cluster should have interface with the same name as failover interfaces of the members, with protocol set to "PIX failover" and members configured as usual. This interface has no ip address. - Other interfaces of the cluster have the same name as corresponding interfaces of the member firewalls, protocol "None" and failover groups that define members as usual. These cluster interfaces also have no ip address. - Cluster state synchronization group uses protocol "PIX state synchrnization" and its members should be configured as usual. Use failover interfaces of the members as members of the state sync group. * Interface.cpp: Added attribute "dedicated_failover" to the Interface object. Interfaces with this attribute are treated like other "unprotected" interfaces, that is they are not used to attach ACLs to and not used in rules. Dedicated failover interfaces have special meaning in PIX configurations and are used to describe interfaces used for LAN failover. 2009-11-07 vadim * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printTCPFlags): Implemented TCP flag matching per #2865044: "Add TCP options support for IOS ACL". Uses extended ACL option "match-all" that supports list of TCP flags that should be set and cleared. This requires IOS v12.4 or later even though Cisco documentation seems to indicate this option was introduced in 12.3(4)T. Fixes #455 2009-11-06 vadim * PolicyCompiler_pix_writers.cpp (PrintRule::_printDstService): PIX does not support IP options matching, compiler issues warning. Fixes #567 * res/platform/iosacl.xml: Recognized IOS versions: 12.1, 12.2, 12.3, 12.4 * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printIPServiceOptions): Added support for IP options matching, requires IOS v12.4 or later. Fixes #566, #568 * configlets/sveasoft/script_skeleton: Fixes #571 /bin/sh on Sveasoft (busybox) does not like empty shell functions and fails with an error "36: Syntax error: "}" unexpected". Will call /bin/true as a placeholder so that if some other commands are added to the function body during template expansion, they are executed after /bin/true and their return code is preserved. If no commands are added, then the function body won't be empty and will return success. * NATCompiler_pf.cpp (NATCompiler_pf::compile): fixed bug #2889579: "fwb_pf crash when unnumbered interface is used in nat rule". Compiler for PF crashed when unnumbered interface was used in TSrc element of a NAT rule. * PolicyCompiler_PrintRule.cpp (PrintRule::_printSrcAddr): Fixed bug #2892100: "'Old boradcast' object produces 0/0 in iptables script". The bug triggered when iptables version was set to 1.3.x or later. "Old broadcast" object is defined as AddressRange with 0.0.0.0 as a start and end addresses of the range. Generated script should have "0.0.0.0" but the compiler uses "0/0" instead. 2009-11-04 Vadim Kurland * PolicyCompiler_ipfw_writers.cpp (PrintRule::_printDstService): Added support for IP options matching in ipfw using "ipoptions" keyword. Matching IPService object with "any options" attribute is not supported though. * IPServiceDialog.cpp (IPServiceDialog::loadFWObject): IPService object now has attribute "any options". If this attribute is turned on, compilers will generate configuration to match IP packets with any options present. Fixes #561 2009-11-03 Vadim Kurland * NATCompiler_ipt.cpp (dynamicInterfaceInTSrc::processNext): Implemented feature request #2829661: "SNAT instead of MASQUERADE on dynamic interfaces". NAT rule options dialog now has a checkbox that makes compiler use SNAT target instead of MASQUERADING when checked when TSrc has dynamic interface. Apparently MASQ target has problems when iptables NAT is used in combination with policy routing. Using SNAT with a variable that gets interface address solves the problem. By default this option is off, that is compiler uses MASQUERADE target when TSrc has dynamic interface. Fixes #560 * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::prolog): Fixed bug #2792847 (SourceForge) "cant turn off "part of any" for a rule if default is on". There was no way to turn option "Assume firewall is part of any" for just one rule when it was ON globally. Now this attribute is presented as a tri-state control in the rule options dialog, with options "Follow global setting", "On" and "Off". Now this option can be turned on and off in individual rules regardless of the global setting. Default is "follow global". Old "Off" maps to the new "follow global", old "On" maps to the new "On". Fixes #559. 2009-11-02 Vadim Kurland * PolicyCompiler_pf_writers.cpp (PrintRule::_printInterface): New feature: optimization in compiler for PF. Rules that have several interface objects (or a group) in the "Interface" column are compiled using "{ }" grouping to produce only one configuration line instead of several for such rule. Fixes #76 * PolicyCompiler_pf.cpp (SpecialServices::processNext): Compiler for PF generates "allow-opts" keyword when IPService object used in the rule has IP options. This includes new option "router-alert". Fixes #503 * IPServiceDialog.cpp (IPServiceDialog::applyChanges): Added GUI elements to support IP option "router-alert" which is now available as an attribute of IPService object. Fixes #502 2009-11-01 Vadim Kurland * CompilerDriver_pf.cpp (CompilerDriver_pf::printStaticOptions): Added support for PF configuration parameter "set state-policy" which can have values "if-bound" or "floating". The GUI input element provides these options in addition to the default empty option. If empty list item is selected, command "set state-policy" is not added to the generated .conf file at all. Fixes #423 2009-10-31 Vadim Kurland * instOptionsDialog.cpp (instOptionsDialog::instOptionsDialog): New feature: password caching. Built-in installer can remember firewall password (and enable password for Ciscos) for the duration of the session. Passwords are never stored permanenetly in any form, encrypted or plain text. The user needs to enter password once when they activate generated policy. If they keep the program open and need to modify and activate policy again, the password fields in the installer dialog can be filled automatically. The feature is optional and is off by default. Cached passwords are associated with the firewall object and account name used to activate policy. Implemented by a2k@codeminders.com 2009-10-22 vadim * RuleSetView.cpp (RuleSetView::itemDoubleClicked): Fixes #545. Change in the GUI behavior: both left and right mouse click on an object in rules should not select it in the tree. If user wants to open it in the tree, they can use context menu item "Reveal in the tree" or double click the object. This solves the following inconvenient behavior (quoting from email): 1) anytime I copy something and then right click to paste into a policy or nat it immediately changes the tree to the location of the object under the cursor which is usually to the standard library on any and then i have change it back to the user library. 2) if I want to compile a rule, unless I am careful and right click on the rule number instead of any field in the rule to select compile it move the tree to whatever is under the cursor. 2009-10-20 vadim * NATCompiler_pf_writers.cpp (PrintRule::processNext): Added support for branching NAT rules for PF. Compiler generates keyword "anchor" if PF version is 4.3 or later and "nat-anchor" and "rdr-anchor" for earlier versions. * platforms.cpp (getActionNameForPlatform): Human-readable names for Policy and NAT rule actions come from the platform .xml resource file (attribute "description"). This implements Feature Requests #1948874 and #1796803 * Support for branch rules in NAT rule sets. Currently only supported for iptables and PF. NAT rules get column "Action" for these platforms, with possible acctions "Translate" and "Branch". Action parameters dialog for the Branch action provides drop well where another NAT ruleset object can be dropped (just like with Branch action in the Policy rules). Action "Translate" performs translation as defined in the rule. Objects in the "Translated source/destination/service" are ignored in NAT rules with action "Branch" and a warning is issued at compile time. * NATCompiler_ipt.cpp (splitNATBranchRule::processNext): Support for branching NAT rules for iptables. Rules in the branch rule set are processed first and their targets and corresponding chains are recorded. These rules are placed in the user-defined chains with the name composed of the rule set name and the chain ("POSTROUTING" or "PREROUTING") that corresponds to the chosen target. Then top NAT rule set is processed. Branching rules found in it pass control to the chains used for the rules from the branching rule set. IF branching rule set uses a mix of SNAT and DNAT rules, the branching rule in the top rule set is split and placed in both PREROUTING and POSTROUTING chains as appropriate. 2009-10-14 vadim * src/res/configlets/linux24/conntrack: Implemented support for conntrack performance tuning parameters and tcp window tracking option. Parameters CONNTRACK_MAX and HASHSIZE are described at http://www.wallfire.org/misc/netfilter_conntrack_perf.txt. The conntrack_tcp_be_liberal option is described at http://conntrack-tools.netfilter.org/manual.html . Parameters can be set in the host OS dialog for Linux (added new tab "conntrack"). Commands that will be added to the generated script come from the new configlet "conntrack". Commands are different for iptables versions <1.4.0 and >=1.4.0. User can customize the commands by substituting the configlet if necessary. Fixes #198, #511. 2009-10-13 vadim * PolicyCompiler_ipf.cpp (SplitDirectionIpfilter::processNext): fixed bug #2874571: "ipfilter version 3.4.29 issues after introduction of 282860". Optimizations added for PF broke rule generation for ipfilter which does not allow rule without explicit direction specification. * FWBSettings.cpp (FWBSettings::getCollapsedRuleGroups): fixed bug #2872365: "problem with group names containing comma". State of the rule group with a comma in the name could not be saved in program settings and the group could not be expanded once it was collapsed. * CustomServiceDialog.cpp (CustomServiceDialog::loadFWObject): fixed bug #2870562: "custom service - protocol name options". Added protocol "ipv6-icmp" to the list of predefined protocols in the CustomService object and fixed the dialog to make it properly save protocol name entered by the user (the widget where user choses protocol name also supports editing so the user can enter any protocol name not offered in the list of standard protocols). * FWWindow.cpp (FWWindow::toolsDiscoveryDruid): fixed bug #2867550: "Discovery Druid dieswhen there is no active'project window". * debugDialog.cpp (debugDialog::debugDialog), DiscoveryDruid.cpp (DiscoveryDruid::DiscoveryDruid) Reversing the change made in 3.0.7 in the debug and discovery druid windows, the change was intended to make the window title bar show "close" button on Mac OS X. Unfortunately the caused the title bar to disappear all together on Linux under some window managers. Modal QT dialogs do not have title bar buttons on Mac OS X, but since they always have "OK", "Finish", "Close" or "Cancel" buttons as part of the dialog contents, absense of the "close" button in the title bar is not critical. * VERSION (VERSION): started v3.0.8 2009-10-07 vadim * FindWhereUsedWidget.cpp (FindWhereUsedWidget::itemClicked): "find where used" panel selects object in the tree or in rules on single click in the list of the results. To open the object in the editor user needs to switch to the editor tab in the bottom docked panel. 2009-10-03 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertFailoverRule): Added support for heartbeat over unicast. Protocol options dialog for heartbeat offers checkbox "Use unicast" (off by default, when checked, address input field for the multicast heartbeat address becomes disabled). When checkbox is checked, compiler automatically adds rules to permit unicast heartbeat health checks between addresses of interfaces which are members of the failover group. 2009-10-02 Vadim Kurland * ProjectPanel.cpp (topLevelChangedForTreePanel): Main window layout redesign: Panels that show object tree and object editor now use docked widget and are detachable. User can "float" these panels to be able to rearrange information on the screen. When panel showing objects tree is detached, it can be expanded to show multiple columns of information comfortably. Also, when the tree is detached, panel showing rules expands to occupy whole window which helps to see rules using objects with long names. This provides easy way to see attrivbutes of many objects at once. Panel that shows object editor dialogs also shows "find" and "find where used" dialogs in a Tab widget. This panel is part of the main window (it used to be part of the internal MDI subwindow) and also can be detached. Editor panel now occupies whole bottom part of the main window. Since editor dialogs show all relevant information about the object, the "Info" panel has been deprecated. Since the editor and search dialogs are now placed inside docked widget that has its own "close" button, "Close" buttons in these dialogs have been removed. 2009-09-30 vadim * ObjectManipulator.cpp (ObjectManipulator::setAttributesColumnEnabled): New feature: the GUI can show brief summary of object attributes in the second column in the object tree. This is controlled by a checkbox in the global preferences dialog, tab "Objects". This is off by default. The first column always shows object icon and its name, the second (optional) column shows its attributes. Interface label is shown in the second column. The width of both columns in the tree is set automatically to accommodate all the text, then can be adjusted by the user using mouse. Column width is saved in settings and will be restored upon program restart. Column width is saved per-file, per-library. 2009-09-23 vadim * ../src/res/configlets/linux24/update_bonding: Generated iptables script incrementally updates bonding interfaces: - It creates new bonding interfaces with parameters configured in the GUI if module 'bonding' is not loaded. This is what happens if fwbuilder script runs after reboot. - if there are no bonding interfaces in fwbuilder configuration, the script removes bonding module to kill any bonding interfaces that might exist on the machine - if you add new bonding interface in fwbuilder, the script checks if it exists on the machine. It will not create it because to do so, it would have to remove the module which kills other bonding interfaces. If this second bonding interface exists, it will be configured with slaves and addresses. If it does not exist, script aborts. In this case you need to either 1) reload module manually or 2) add max_bonds=2 to /etc/modules.conf and reboot or 3) unload module and run fwbuilder script again (if module is not loaded, the script loads it with correct max_bonds parameter) - if a bonding interface exists on the machine but not in fwbuilder configuration, the script removes all slaves from it and brings it down. It can not delete it because to do so it would need to remove the module, which kills other bonding interfaces. Limitation: currently all bonding interfaces will use the same protocol parameters. This is because module loading with parameter "-obond1" that is supposed to be the way to obtain more than one bonding interface and also the way to specify different parameters for different interfaces causes kernel panic in my tests. Tested with bonding module v3.5.0 and kernel 2.6.29.4-167.fc11.i686.PAE on Fedora Core 11. The only working way to get two bonding interfaces I could find is to load the module with parameter max_bonds=2, but this means all bonding interfaces work with the same protocol parameters. If bond interfaces are configured with different parameters in fwbuilder, compiler uses the first and issues warning for others. 2009-09-18 vadim * PolicyCompiler.cpp (ItfNegation::processNext): (change in libfwbuilder) fix for bug #2710034 "PF Compiler in 3.0.3 Unprotected Interface Bug". When we expand "interface" rule element which uses negation, skip unprotected interfaces. 2009-09-16 vadim * RoutingCompiler_ipt_writers.cpp (PrintRule::processNext): Fixed security issue with temporary file handling in the generated iptables script. The problem only affects Linux systems where Firewall Builder is used to generate static routing configuration. The problem exists in Firewall Builder versions 3.0.4, 3.0.5, 3.0.6 2009-09-14 vadim * standardized compiler error and warning messages using format fw_name:ruleset_name:rule_number: warning: message fw_name:ruleset_name:rule_number: error: message * dialogs that show compiler output recognize error and warning messages and highlight them using different color and bold font. 2009-09-07 vadim * single rule compile feature implemented for all platforms (iptables, ipfilter, pf, ipfw, iosacl, pix) and integrated with the GUI. Currently using keyboard shortcut "x". Fixes #23. 2009-09-06 vadim * RuleSetView_single_rule_compile.cpp (RuleSetView::compileForCurrentRow): Single rule compile implementation. Currently this is triggered by hitting keyboard key 'x', the event is processed by RuleSetView class which calls RuleSetView::compileForCurrentRow(). This creates compiler driver object and calls it to compile currently selected rule. The result is shown in the editor panel. User can select parts or the whole of the generated script in the editor panel but it is read-only. Works only with iptables yet. Refs #23. * src/iptlib/iptlib.pro (SOURCES): Moved all modules for fwb_ipt except main module ipt.cpp to a separate library so that they can be linked with either command line compiler fwb_ipt or the GUI. Refs #23 2009-09-05 vadim * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printDstService): fixed bug (no #): policy compiler for Cisco IOS ACL did not add icmp type to the generated ipv6 access-list statements for rules that matched ICMPv6 services. 2009-09-03 vadim * src/res/configlets/linux24/update_bridge: configlet that updates bridge interfaces will now completely synchronize interfaces with configuration created in fwbuilder even if no bridge interfaces are used in fwbuilder. Bridge interfaces that exist on the firewall but not in fwbuilder will be deleted and those that exist in fwbuilder but are missing on the machine will be added. Bridge ports are deleted and added after bridge interfaces have been synchronized. * src/res/configlets/linux24/update_vlans: fixed command line in the command that removed vlan interface 2009-08-30 vadim * instDialog_ui_ops.cpp (instDialog::addToLog): fixed bug #2847263 "Batch compiling incrementally slow". The time it took to add a log line to the progress window in the "Compile" dialog slowed down a lot as amount of text in QTextEditor increased. 2009-08-28 vadim * ProjectPanel.cpp (ProjectPanel::event): instead of several methods in FWWindow that scan all project panel windows and execute some operation, using user defined events. Currently have two events: dataModifiedEvent and updateObjectInTreeEvent. The first one signals that some object has changed so that ProjectPanel::event() can update timestamps and do other things. It then posts the second event, which it will catch and process on the next event processing run. The second event does UI updates. Both events carry file name and object ID. Only those ProjectPanel objects that have the same file process the event. Events are dispatched to project panels in FWWindow::event(). Concentrating all UI update logic in one place helps avoid unnecessary redraws. This replaces FWWIndow::updateLastModifiedTimestampForOneFirewall, FWWindow::updateLastModifiedTimestampForAllFirewalls, FWWindow::reloadAllWindowsWithFile. * interfaceProperties.cpp (interfaceProperties::manageIpAddresses): this is a generic method that implements a policy to decide whether generated script should manage ip addresses of a given interface. It checks if it belongs to a cluster or a firewall and failover protocol (if it belongs to a cluster). It fills two lists: one is the list of addresses that the interface should have and another is a list of interfaces the script must not remove even if they are assigned to the interface. The method uses data from host_os XML resource file. 2009-08-27 vadim * CompilerDriver.cpp (CompilerDriver::mergeRuleSets): See #372: this change reverses the logic of the program when it merges rule sets from the cluster into its member firewalls. In the original Secunet implementation rule sets of members were ignored and only one top level rule set from the cluster was ever used. Now we check if member firewall has rule set of the same name as cluster and use it if it is not empty and issue a warning. If rule set of the member firewall with the same name is empty, rules from the cluster are used. All rule sets of the cluster that do not match anything in member firewalls are merged into firewalls and used for compilation. This way, we can have multiple rule sets in the cluster and can have slightly different rules in member firewalls if necessary. See ticket #372 for more details and info for the documentation. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::addPredefinedPolicyRules): fixes #388: "automatic rules are added to second rule set in cluster member". IF a cluster member firewall had several policy rule set objects, automatic rules for conntrackd, vrrp, heartbeat were added multiple times. * OSConfigurator_linux24_interfaces.cpp (printInterfaceConfigurationCommands): fixes #387: add calls to update_addresses shell function in generated script even for interfaces with no ip addresses. This way, if such interface has an address on the machine, it will be removed. This helps synchronize configuration with fwbuilder when user removes all addresses from an interface and converts it to "unnumbered". Note that update_addresses never removes scope link and scope host addresses of the interface even if they are not configured in fwbuilder GUI. * PolicyCompiler_pf.cpp (SplitDirection::processNext): applied patch per #2844561: "PF Compiler Direction Both Duplicate for Route Action". Need to split the rule if direction is Both and action is Route. * newFirewallDialog.cpp (newFirewallDialog::templateSelected): fixed bug #2844596: "Crash during newFirewallDialog". GUI crashed if user clicked "next" in the new firewall dialog to open page with templates, then clicked "Back" and then "Next" again. * ObjectManipulator.cpp (ObjectManipulator::select): fixed bug #2845667 "Crash after find object". When host object was found using "Find object" function while searching by ip address, clicking on the selected host in the tree caused crash. * VERSION (LIBFWBUILDER_SOMAJOR): started 3.0.7 2009-08-26 vadim * ObjectManipulator.cpp (ObjectManipulator::validateForPaste): User should be able to add vlan interface to a bridge (vlan interface becomes bridge port). Fixes #384 * CompilerDriver.cpp (CompilerDriver::populateClusterElements): moved this method from class Compiler. fixes #367 * CompilerDriver_compile.cpp (compileSingleRule): entry point for single rule compile. Takes one argument - rule ID and returns a QMap where key is firewall name and value is generated script for this rule. Currently using this entry point in the command line compilers via cli argument -s rule_id. Fully implemented in fwb_ipt. Fixes #358, #206 * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): using std::auto_ptr to protect OSConfigurator, PolicyCompiler and NATCompiler objects and to properly delete them to avoid memory leaks in fwb_ipt. fixes #371 2009-08-24 vadim * CompilerDriver.cpp (CompilerDriver::commonChecks2): refactored bunch of common sense checks from compilers for ipt and pf into common module. This also fixes #337 by checking if it is ok for the cluster interface to have no ip address using xml resource file for the fw host OS. Protocols such as heartbeat and openais can operate when failover interface has no shared cluster address because these protocls can use multicast address. However configuration when cluster interface using one of these protocols has shared IP is also legit. The check here only suppresses error message when interface has no ip. * platforms.cpp (setInterfaceTypes): Fixes #335 : if interface name matches naming convention for vlan interfaces and vlan type is in the list that came from the resource file, then leave only vlan in the list we return. Note that if resource file says this subint can not be vlan, we dan't return vlan type on the list even if its name looks like it could be one. * ProjectPanel.cpp (ProjectPanel::updateTreeViewItemOrder): Removed ProjectPanel::updateTreeViewItemOrder() and removed call to it from ObjectEditor::notifyChangesApplied(). We take care of QT bug workaround for improper sorting in other places. This change fixes #329. 2009-08-21 vadim * ObjectManipulator.cpp (ObjectManipulator::newInterface): If newly created interface object is a top-level interface, always set its type to "ethernet". If it is subinterface, call guessInterfaceType() to guess. * ObjectManipulator.cpp (guessInterfaceType): fixes #334. the GUI guesses correct subinterface type when it is created and when user hits "Apply" in the interface object dialog after some changes have been made. If inetrface name matches one of the patterns of the vlan inetrface for the given OS, its type is set to "vlan" and vlan ID is assigned. If its name does not match naming pattern of a vlan interface but parent interface type is "bridge" or "bonding", subinterface type is set to "ethernet". This covers most of the use cases and makes subinterface type assignment automatic. * ObjectManipulator.cpp (ObjectManipulator::newInterfaceAddress): fixes #330: the name of the ip address of an interface should follow the schema "firewall:interface:subinterface:ip". The same schema should be followed when address object is automatically renamed when the user renames firewall or interface object. * ObjectManipulator.cpp (ObjectManipulator::copyObj): call Interface::getOptionsObject() at the beginning of copy and dragStart operations to make sure interface has options object later in paste and drop operations when we need it to do some validation checks. 2009-08-20 vadim * ObjectManipulator.cpp (ObjectManipulator::validateForPaste): perform checks for the valid vlan subinterface configuration for copy/paste and d&d drop operations; this uses the same algorithms as the check done when user renames an interface. This means user can not copy/paste or d&d interface "eth1.100" to make it a subinterface of "eth0" or top-level interface. * InterfaceDialog.cpp (InterfaceDialog::validate): Additional checks for validity of interface name: the name can not contain white space, if the name looks like vlan interface, checking if it is valid (base name must match name of the parent interface and vlan ID must be in the allowed range) * InterfaceDialog.cpp (InterfaceDialog::applyChanges): Fixes #328: "automatically assign vlan id to interface based on interface name". The GUI automatically sets interface type to "vlan" and configures vlan ID if user changes name of the interface to something that matches regex for vlan interfaces on given OS. This is done when user hits "Apply" button in the Interface object dialog. * src/compiler_lib/interfaceProperties.h (class interfaceProperties): refactored class linux24Intrfaces into class hierarchy with base class interfaceProperties and factory class interfacePropertiesObjectFactory. These classes are now part of the compiler extensions library in src/compiler_lib and can be used by both the GUI and compilers. * Configlet.cpp (Configlet::Configlet): New constructor for the class Configlet accepts os name perifx and default os name prefix. If configlet file is not found in the directory defined by the first prefix, the program tries to find it in the default place defined by the second prefix. * src/res/configlets/sveasoft/script_skeleton: Using separate configlets for Linksys/Sveasoft host os. 2009-08-19 vadim * ObjectManipulator.cpp (ObjectManipulator::newInterfaceAddress): fixes #318: New ip address of interface was always created with the same name even if there was an address object with the same name under the same interface. * OSConfigurator_linux24_interfaces.cpp (validateInterfaces): Tests for unsupported interface configurations, see #315, 324. The first test scans all subinterfaces of each interface and tries to find top level inetrfaces wth the same name, then checks their type. For the combination some_interface/br1, we look for the top level interface "br1" and if it exists and its type is "bridge", then this is unsupported configuration. This test does not allow subinterface to have the same name as a bridge interface regardless of the type of the parent interface. So, bridge/bridge or bonding/bridge combinations are not allowed. The test has to search top level interfaces because bridge port subinterfaces can be copies (e.g. when a vlan interface is at the same time a bridge port). The second test looks for the following combinations: 1) vlan interfaces under bridge interface (e.g. br0 = [eth1, eth2], vlan inetrface br0.100 is not supported) and 2) vlan interfaces as slaves of bonding interfaces (e.g. eth0.100, eth1.100, bond0 = [eth0.100, eth1.100], note the difference between this and vlan of bonding interface such as bond0.201). Only regular interfaces can be slaves of bonding interface. If subinterface type is "ethernet" but its name matches one of the vlan interface regexes, assume this is vlan. Slave subintrfaces do not have to be copies, one can have "eth4" only once, as a slave, so we cant search for a top level interface with the same name and rely on the subinterface type. 2009-08-18 vadim * ObjectManipulator.cpp (ObjectManipulator::makeNameUnique): The program should never change the name of vlan interface when such interface is being copied/pasted or dropped to become a subinterface. The name of the vlan interface carries vlan ID and changing name is not allowed. One of the typical usage patterns is to create vlan interface "eth0.101" and then immediately try to copy/paste it to under br0 to make it bridge port. In this case interface eth0.101 wont have type "8021q" just yet because the user did not open interface "advanced" settings dialog to set its type and VLAN ID. Users assume that if its name is "eth0.101", then it must be vlan interface. We should follow this assumption too. Also, check for names "vlanNNN" as well. * ObjectManipulator.cpp (ObjectManipulator::actuallyPasteTo): during "paste" operation, call makeNameUnique() to make the name of the copy unique before actually adding the object to its parent. Otherwise makeNameUnique() finds it and changes the name. * src/res/configlets/ipcop/script_skeleton: Using configlet to define script structure for generated IPCOP script. IPCOP script is executed as /etc/rc.d/rc.firewall.local and does not manage ip addresses of interfaces or vlan/bond/bridge interfaces so it does not need corresponding shell functions. Script can check if interfaces configured in fwbuilder GUI match actual appliance, so the shell code to do that is included. Since we should be able to use interfaces with addresses assigned dynamically in rules, the code that gets their addresses at run time is included. Code to check if data files used by run time address table objects exist is also included. Using configlets helps better manage what is included for the given os family ("linux24" or "ipcop" or some other in the future). Also, user can override our configlets by placing file with the same name in "fwbuilder/configlets" directory in their $HOME. 2009-08-17 vadim * src/res/configlets/linux24/shell_functions: cleaned up coding style in shell functions in configlets: using uniform 4 spaces indentation. * src/res/configlets/linux24/script_skeleton: This configlet defines structure of generated iptables script. Script recognizes the following command line options: start|stop|interfaces * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): Building whole iptables script from configlet. * OSConfigurator_linux24.cpp (OSConfigurator_linux24::configureInterfaces): See #314. Need to update vlans and bond interfaces first and only then deal with bridges because bridge may use bonding interface or vlan created in the first step. Unsupported configurations: vlan interfaces under bridge interface (e.g. br0 = [eth1, eth2], vlan inetrface br0.100 is not supported), bridge interface as part of bonding interface (e.g. bond0 = [br0, br1]), vlan interface as a slave of bonding interface (e.g. eth0.100, eth1.100, bond0 = [eth0.100, eth1.100]). Only regular interfaces can be slaves of bonding interface; vlans can be created under bonding interface (e.g. bond0.100), both regular interfaces and vlans can be bridge ports. Script first updates bonding interfaces, then updates all vlans, including possibly those under bonding interfaces, and finally updates bridge configurations using interfaces created in first two steps. 2009-08-12 vadim * NATCompiler_ipt.cpp (splitSDNATRule::processNext): fixed bug #2836321: "SNAT rule that changes Trans Src and Trans Port does not work". Dual translation rule that changes source address and destination port was not supported. 2009-08-10 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): For bug #2835193: "Modulate state doesnt work for PF". Check variable "modulate state" in rule optiopns and global firewall options. If checkbox is turned on in the firewall options, then we always use "modulate state". This option can also be turned on for an individual rule using rule options dialog. * pfAdvancedDialog.cpp (pfAdvancedDialog::pfAdvancedDialog): Fixed bug #2835193: "Modulate state doesnt work for PF". The name Xml attribute used to hold the value of "module state" option was entered incorrectly in the dialog. 2009-08-09 vadim * ipfw.cpp (main): compiler for ipfw uses new manifest format and supports remote file name for the generated .fw script Fixes #308 * ipf.cpp (main): compiler for ipfilter uses new manifest format and supports remote file names for generated .fw and .conf files. Fixes #307 * CompilerDriver_pf.cpp (CompilerDriver_pf::getRemoteConfFileName): compiler for PF uses new manifest format and supports remote file names for generated .fw and .conf files. Fixes #306 * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): compiler for iptables uses new manifest format to implement support for alternative name of the script on the firewall. Fixes #305 2009-08-08 vadim * instDialog.cpp: Installation process is controlled by sevral variables that the user can change in the "advanced" dialog for the firewall platform: Tab "Compiler": - output file name - script name on the firewall - for PF and ipfilter additionally .conf file name on the firewall Tab "Installer": - directory on the firewall where script should be installed - command that installer should execute on the firewall These variables have default values if input fields are left blank in the dialog as follows: output file name: the name of the firewall object, plus extension ".fw". For PF two files are generated: .fw and .conf; for ipfilter files .fw, -ipf.conf and -nat.conf are generated. script name on the firewall: the same as the output file name directory on the firewall: "/etc" command that installer executes to activate policy: installer runs script .fw If user enters alternative name in the "script name on the firewall", it is used when generated script is copied to the firewall. There are two input fields in the dialogs for PF and ipf where user can enter alternative name for the .fw script and .conf file. The name can be relative or absolute path. If it is a relative path or just a file name, it is treated as a file name in the directory specified by the "directory on the firewall" input field in the "Installer" tab. If the name is an absolute path, the directory entered in "directory on the firewall..." input field is ignored. If user entered alternative name for the script on the firewall, the command that installer should execute to activate it must be entered as well. If the alternative name was entered as an absolute path, activation command should take this into account and use the same absolute path. The command can start with "sudo " if user account used to copy and activate policy is not root. * iptAdvancedDialog.cpp (iptAdvancedDialog::iptAdvancedDialog): Added input fields to the "advanced" dialogs for iptables, pf, ipfilter and ipfw to make it possible to specify the name of the generated script on the firewall. With this change, fwbuilder can generate the script using unique name but use standard common name such as "rc.firewall" when the script is copied to the firewall machine. This is important when two firewalls that are part of a cluster are compiled at the same time. In this case we can not use name such as "rc.firewall" for the output script because file generated for the second firewall in the pair overwrites the one generated earlier for the first. Now we can use unique names for scripts generated for each member of the pair but copy them to the firewall machines using the same common name. Fixes #304 The implementation is not complete yet, I still need to make changes in the installer and policy compilers. 2009-08-07 vadim * src/res/configlets/linux24/process_bridge: Configlets that updated ip addresses, vlan, bridge and bonding interfaces bring interfaces up using $IFCONFIG command. Fixes #301 2009-08-06 vadim * ObjectManipulator.cpp (ObjectManipulator::actuallyPasteTo): When a subinterface is copied to make a subinterface of another interface, the type of the copy is reset to "ethernet". If the type was retained, it was easy to create subinterface with invalid type without obvious signs in the GUI that this has happened. For example, if vlan subinterface was copied to make subinterface of a bridge interface, it retained type "8021q" but ended up as a child of interface with the name that did not match. The intention was to use vlan subinterface as a bridge port, but compiler issued an error because of a subinterface having illegal name (name is only checked for vlan subinterfaces). Fixes #299 * PrefsDialog.cpp: Added a page to the global Preferences dialog where user can enable/disable target firewall platforms and host OS. Disabled platforms and OS do not appear in the drop-down lists in a "new firewall" and "new cluster" dialogs, as well as object editor panel. This helps reduce clutter if user only works with a couple of platforms and OS. Default setting of the status for each platform and os comes from the corresponding XML resource file. This way we can ship the program with some host OS or platforms disabled by default, but the user can still enable them. Settings in users preferences override default status setting in the resource file. Fixes #262 * ObjectManipulator.cpp (ObjectManipulator::newAddressRange): newly created objects get default name that is the same as the type name with no "New ..." prefix. * ObjectTreeView.cpp (ObjectTreeView::dropEvent): if user drags an object in the tree and drops it beyond the last tree item, the program should ignore this drop operation and do nothing (it used to crash). Added checks for this condition. Fixes #294 * ObjectManipulator.cpp (ObjectManipulator::makeNameUnique): while guessing the name of the new interface or trying to avoid duplicate names during copy/paste, we should not change names of the vlan interfaces. Fixes #296 2009-08-05 vadim * FWWindow.cpp (FWWindow::prepareToolsMenu): disable Tools/Discover menu if all internal windows were closed and there is no active object tree where discovered objects could be created. Fixes #291 * ObjectManipulator.cpp (ObjectManipulator::relocateTo): Added check for when user tries to drag&drop an object onto itself in the tree. Fixes #292 2009-08-04 vadim * ObjectManipulator.cpp (ObjectManipulator::newInterface): when user creates interfaces of a firewall or a cluster using context menu "Add Interface" in the object tree, the program finds interface that was created most recently and uses its name as a prototype, automatically incrementing its number. For example, if the user needs to create several "eth" interfaces, the program will automatically create "eth0", "eth1", "eth2" etc. whithout the need for the user to rename them. Fixes #277 * configure.in: Removed all .xml.in resource files in src/res/ src/res/os and src/res/platform. The only configurable attribute in these was "version", which is not required and was not used anywhere. Fixes #269 * PolicyCompiler_PrintRule.cpp (PrintRule::_printOptionalGlobalRules): automatically added rule that matches packets in state INVALID should use log prefix that says it is for state INVALID. The rule now ignores user-defined global logging prefix and always uses "INVALID state -- DENY ". Fixes #283 2009-08-04 Vadim Kurland * heartbeatOptionsDialog.cpp (heartbeatOptionsDialog::heartbeatOptionsDialog): Added GUI elements to allow the user to change multicast address for heartbeat. Deafault address is 224.0.10.100. Fixes #213 * clusterMembersDialog.cpp (clusterMembersDialog::firewallAdd): enabled multiple object selection in the left panel of the cluster member management dialog. User can select several interfaces using Ctrl-click (or Command-Click on Mac OS X) and then move them all to the right panel at once. Fixes #254 * ObjectEditor.cpp (ObjectEditor::notifyChangesApplied): Dialogs that have buttons to open "advanced" settings dialogs now save changes and disable "Apply" button when such additional dialog is opened. This includes Firewall, Interface, cluster group and few other objects. Previously changes were saved as well but the "Apply" button was not disabled, making impression that changes were not saved into the object. Fixes #286 2009-08-03 Vadim Kurland * ObjectManipulator.cpp (ObjectManipulator::autorename): See #273: "child objects not getting renamed". Autorename function should rename ip and mac addresses of interfaces and subinterfaces when the host or parent interface name changes. * newClusterDialog.cpp (newClusterDialog::finishClicked): See #211: "interface type mismatch between member interfaces and cluster interface". When cluster object was created manually and failover type was set to "heartbeat" or "openais" for its interfaces, the type was not properly set in created objects. 2009-08-02 vadim * ObjectTreeView.cpp (ObjectTreeView::dropEvent): Dragging several subinterfaces from one parent interface to another created bizzarre tree-like structure where each of these subinterfaces became subinterface of another. See #280. Fixed in r1254 * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertConntrackRule): Added test to make sure ip address entered by the user in the StateSync group dialog for conntrack is valid. Fixes #220 * CompilerDriver_ipt_cluster.cpp (CompilerDriver_ipt::processStateSyncGroups): The program did not find StateSync group member inetrfaces when they were subinterfaces and as the result compiler did not generate automatic policy rules for conntrack. Fixed in r1253 * ObjectManipulator.cpp (ObjectManipulator::prepareForInsertion): DTD does not allow nested subinterfaces; only one level of subinterfaces is supported. Interface::validateChild() now checks for this condition and the GUI shows detailed error message dialog when user tries to move interface that has subinterfaces under another interface using copy/paste or d&d. Fixes #275 * ObjectManipulator.cpp (ObjectManipulator::relocateTo): When user dragged an interface that has child objects (ip address, MAC address) and dropped it in a different place in the object tree, the program would show only the interface object in the new place but not its children. Should be using insertSubtree() to fix this. Fixes #276 2009-08-01 vadim * ProjectPanel_file_ops.cpp (ProjectPanel::chooseNewFileName): If user forgot to add .fwb suffix to the file name they entered in the "Save As" function, the program automatically adds it. See #234 * CompilerDriver.cpp (CompilerDriver::commonChecks): compiler should check that cluster member firewalls are configured to use different output file names. See #237 * OSConfigurator_linux24::printVerifyInterfacesCommands: function verify_interfaces uses configlet "verify_interfaces" and checks if all interfaces of the firewall defined in the GUI really exist, including bonding, vlan and bridge interfaces. * OSConfigurator_linux24::printInterfaceConfigurationCommands: Using configlet process_addresses to implement shell commands that incrementally add and remove addresses on interfaces. Added support for IPv6 addresses. Addresses found on the actual interfaces of the firewall are compared with those defined in fwbuilder objects and missing ones are added and those not defined in fwbuilder are deleted. If a firewall is a cluster member using heratbeat for failover, ip addresses associated with heartbeat failover groups are skipped. The script wont delete these on the firewall that is active at the moment when script runs and wont add them to the passive firewall because that would interfere with operation of heartbeat. The same is done for OpenAIS protocol. Fixes #270 , See #261 2009-07-31 vadim * OSConfigurator_linux24_interfaces.cpp (OSConfigurator_linux24::printVlanInterfaceConfigurationCommands): Using configlets to generate shell script that incrementally updates (adds and removed) VLAN, bridge and bonding interfaces. See #261 * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printShellFunctions): Using configlets to generate iptables script. * Configlet.cpp (Configlet::Configlet): generic class to read fragment of generated script from an external file, possibly do macro substitution and then insert the contents into generated script. Configlets are stored in files in the resources directory that is part if installed package (/usr/share/fwbuilder/configlets on Linux, fwbuilder31.app/Contents/Resources/configlets on Mac OS X, c:\FWBuilder31\resources\configlets on Windows) or in the subdirectory "fwbuilder/configlets" in users home directory on all OS. If configlet file is found in the home directory, it overrides the one installed with the package. This provides for simple way for users to override parts of the generated configuration scripts. Currently configlets are only impletened for Linux-based OS. Fixes #263 2009-07-30 vadim * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printShellFunctions): fixes #259 Generated script should check if brctl, vconfig and ifenslave tools are available before using them. * Host.cpp (Host::getManagementAddress): the program failed to retrieve ip address that should be used to talk to the fw when management interface was subinterface. Fixes #260 * linux24advanceddialog_q.ui: Fixes #258 fixed tab order in the dialog. 2009-07-29 vadim * linux24AdvancedDialog.cpp (linux24AdvancedDialog::linux24AdvancedDialog): Added input fields for vconfig, brctl and ifenslave to the host settings dialogs for linux24, linksys, ipcop, openwrt. See #256 * DiscoveryDruid.cpp (DiscoveryDruid::addInterface): Removed obsolete checkbox "Add virtual addresses", we always discover virtual addresses. Instead added checkbox "Add interfaces with no ip addresses". If this option is turned on, discovery druid creates interfaces with no ip addresses as "unnumbered". Even when this option is off, interfaces with no addresses are created if they are discovered to have vlan, bridge or bodning subinterfaces. Fixes #246 and 229 * NetworkDialog.cpp (NetworkDialog::validate): Fixes #251: do not allow 0 bit netmask for Network and NetworkIPv6 objects. * linux24Interfaces.cpp (linux24Interfaces::rearrangeInterfaces): Special treatment of the vlan subinterface that are members of bridge group: snmp discovery now creates subinterfaces for these vlan interfaces twice, first time as a child of the bridge interface and then also as a vlan subinterface of the parent physical interface. For example, in the confgiuration such as the following bridge name bridge id STP enabled interfaces br0 8000.000c29f6bebe no eth4.102 eth5 We create interface br0 with subinterfaces eth4.102, eth5, and also we create interface eth4 with subinterface eth4.102 * ObjectManipulator.cpp (ObjectManipulator::makeNameUnique): duplicate names are automatically fixed only if objects with the same name belong to the same parent. Identical names on different levels are allowed. For example, interface "eth0" can be direct child of a Firewall object (so it can have vlan subinterfaces) and a member of the bridge group where it is a child of another interface. 2009-07-28 vadim * NATCompiler_pf_writers.cpp (PrintRule::_printSrcPort): remove extra white space after tcp port spec if source port match was not used in the rule. * PolicyCompiler_pf.cpp (fillDirection::processNext): Applied patch per bug report #2828633: "Patch: Warning when changing rule direction in compiler". This adds warning when rule direction is changed by the compiler because object in source or destination was firewall itself. * PolicyCompiler_pf.cpp (PolicyCompiler_pf::compile): Implemented change per bug #2828602: "PF Compiler Direction Both no Duplication Patch". PF rules with direction "both" used to be split to make two rules, one with direction "inbound" and another with direction "outbound". This was an artefact of old rule generation model where user could choose to permit everything outbound and only generate inbound rules, or generate both inbound and outbound rules. Since we now always generate both in abd out rules and PF matches both directions when neither "in" or "out" is specificed, this splitting has become redundant. * Compiler_cluster.cpp (Compiler::populateClusterElements): while scanning interfaces-members of a failover group, use only those that are children of the firewall that we are compiling. fixes #242 "fwb_ipt generates duplicate automatic rules for heartbeat and other protocols" * FWWindow.cpp (FWWindow::disableActions): Always enable toolbar buttons "Compile" and "Install". Fixes #249 * FirewallDialog.cpp (FirewallDialog::validate): fixes #248 "setting firewall type as empty space crashes". Note that the combobox with firewall platforms will have separators instead of spaces if QT version is 4.5 or above. Separators are not selectable so this problem can not happen with late versions of QT. Old versions of QT do not support separators in QComboBox widget, which is why spaces are inserted in the list. This change makes the program validate platform and host os settings and not allow empty strings. * RoutingRuleOptionsDialog.cpp (RoutingRuleOptionsDialog::loadFWObject): fixes #247 - "lusters->fw->routing->insert rule->options causes segfault". Needed to check for Firewall and Cluster types here and in a few other places. * instDialog_ui_ops.cpp (instDialog::completeInstallerOptions): fixes #244: "installer does not check subinterfaces when it is looking for management interface" * OSConfigurator_linux24_interfaces.cpp (OSConfigurator_linux24::printVlanInterfaceConfigurationCommands): fixes #243 - need to set naming schema for vlan interfaces in a separate command before creating vlan interface. Doing so in one vconfig command causes error. * DiscoveryDruid.cpp (DiscoveryDruid::createRealObjects): discovery druid guesses which interfaces from the list found by SNMP crawler are vlan subinterfaces and creates them as children of the corresponding top level interface. It also sets interface type and vlan ID. Fixes #239 Bonding and bridge subinterfaces are also recognized. * DiscoveryDruid.cpp (DiscoveryDruid::createRealObjects): discovery druid sets firewall platform and host OS using information from sysDescr OID. fixes #241 * linux24Interfaces.cpp (linux24Interfaces::rearrangeInterfaces): this new class implements various algorithms used to guess which interfaces discovered by SNMP crawler might be vlan subinterfaces. It will also find bonding and bridge interfaces. Fixes #240 2009-07-27 vadim * clusterMembersDialog.cpp (clusterMembersDialog::createMember): support for subinterfaces as cluster group members. Fixes #235 2009-07-26 vadim * PolicyCompiler_ipt_optimizer.cpp (optimizeForMinusIOPlus::processNext): Better way to do optimization for "-i +", "-o +" for bug #2822098: check for interfaceStr equal to "*" instead of re->isAny() * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): check all interfaces, including subinterfaces to make sure all the ones marked as "regular" have IP addresses. * DialogFactory.cpp (DialogFactory::createClusterGroupOptionsDialog): fixed bug introduced in r1208 - clicking button "Edit protocol settings" in the failover group with type "heartbeat" failed to open the dialog. * PolicyCompiler_ipt_optimizer.cpp (optimizeForMinusIOPlus::processNext): Better way to do optimization for "-i +", "-o +" for bug #2822098: check for interfaceStr equal to "*" instead of re->isAny() 2009-07-25 vadim * OSConfigurator_linux24_interfaces.cpp (printInterfaceConfigurationCommands): the program did not create commands to add ip addresses to VLAN subinterfaces. Fixes #226 * openaisOptionsDialog.cpp (openaisOptionsDialog::openaisOptionsDialog): Added support for OpenAIS failover protocol in the GUI and policy compiler for iptables. Fixes #214 * newFirewallDialog.cpp (newFirewallDialog::finishClicked): the program left platform and os settings undefined of the new firewall object created from template. Fixes #210 * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertFailoverRule): Policy compiler for iptables adds automatic rules for heartbeat protocol if it is used for failover. Rules permit all udp port 694 in and out on the given interface. Refs #213 * Cluster.cpp (Cluster::getMembersList): need to scan not only StateSyncClusterGroup child objects but also all FailoverClusterGroup objects in order to find all member firewalls. The program used to look only at StateSyncClusterGroup objects, which meant it did not recognize any members if state sync group was empty. This fixes issue #4 in the bug #2826765: "problems and suggestions for 3.1.0-b1187". 2009-07-24 vadim * PolicyCompiler_ipt.cpp (decideOnChainIfDstFW::processNext): There was no rule in INPUT chain generated when cluster object was in "destination". Fixes #215 * CompilerDriver_ipt.cpp (CompilerDriver_ipt::processPolicyRuleSet): fixed problem #2 "duplicate rules" reported in the bug #2826765: "problems and suggestions for 3.1.0-b1187". Compiler did not add a call to the shell function reset_iptables_v4 to reset all chains. * Rule.cpp (PolicyRule::getBranch): fixed problem #4 "GUI crash when setting action to be a chain." reported in the bug #2826765: "problems and suggestions for 3.1.0-b1187". The GUI crashed when policy rule in the cluster policy was set to action "Chain". 2009-07-23 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::insertConntrackRule): automatically added rules that permit conntrackd messages use address and port configured in the protocol options for the state sync group for the cluster, or if these are empty, default values from the host OS xml resource file. Generated rules are configured to go into INPUT and OUTPUT chains. Refs #212 * conntrackOptionsDialog.cpp (conntrackOptionsDialog::conntrackOptionsDialog): make conntrackd multicast address and udp port configurable in the protocol options dialog for conntrackd state sync protocol. Default address and port are stored in the host OS xml resource file. Refs #212 2009-07-19 vadim * PolicyCompiler_ipt.cpp (specialCaseWithFWInDstAndOutbound::processNext): fixed bug #2823951: "unnecessary rules in FORWARD chain". Policy rules that have interface object in "Interface" column and direction "Both" generate unnecessary iptables commands in the FORWARD chain when destination matches one of the addresses that belong to the firewall. 2009-07-18 vadim * RuleSetView.cpp (RuleSetView::moveRule): fixed bug #2823668: "MDI window glitch". If the GUI had two or more MDI windows and user moved rules in one of them, the GUI switched to another after the operation was complete. * resources.xml.in: Removed unused XML elements from the resource file. A lot of the stuff was obsolete in there. * ObjectTreeView.cpp (ObjectTreeView::updateTreeItems): New icons for v4. Cleanup in the code to make sure we use proper icons everywhere. 2009-07-17 vadim * linux24.xml.in: Moved tables of allowed failover and state sync types as well as interface and subinterface types from the code in platforms.cpp to the OS resource files in src/res/os/*.xml.in Fixes #58 * fwbuilder.dtd.in (Library): fixed bug #2823424: "Deleting UserService object breaks data file format". When user deleted UserService object, it was moved to the "Deleted Objects" library which broke XML file because DTD did not allow UserService element as a child of Library 2009-07-16 vadim * newClusterDialog.cpp (newClusterDialog::shrinkListOfPlatforms): clean-up in the newClusterDialog class. List of platforms shown on the first page should include only platforms that support clustering. Fixes #197 * FWBTree.cpp (systemObjects): system group "Clusters" moves to the top level of the tree. Fixes #167 2009-07-15 vadim * PolicyCompiler_ipt_optimizer.cpp (optimizeForMinusIOPlus::processNext): fixed bug #2822098: "IPT: adds useless "-i +" iin some cases". Added optimization to remove redundant "-i +" and "-o +" if chain is INPUT or OUTPUT. 2009-07-14 vadim * PolicyCompiler_ipt.cpp (singleItfNegation::processNext): fixed bug #2819901: "sub-optimal expansion of negated interface". Policy rules with single interface object in "interface" rule element with negation should generate iptables commands using "-i ! itf" or "-o ! itf" rather than multiply the rule using all other interfaces of the firewall. Note that for iptables v1.4.3 and later, extrapositioned syntax is used, such as "! -i itf". * PolicyCompiler_PrintRule.cpp, NATCompiler_PrintRule.cpp: fixed bug #2821050: "loading new fw rules on iptables 1.4.3.2+ gives warnings". starting with v1.4.3.1 iptables started giving warnings when negation ("!") is used after --option. This fix adds version "1.4.3" to the list of recognized iptables versions in fwbuilder and makes compiler generate extrapositioned version of the option such as "! --option arg". 2009-07-13 vadim * iptAdvancedDialog.cpp (iptAdvancedDialog::iptAdvancedDialog): fixed bug #2820840: "IPT: prolog script+iptables-restore silent incompatibility". With this fix the GUI does not allow for the prolog script to be placed after policy reset if iptables-restore is used to activate iptables rules. Also policy compiler for iptables checks for this condition and aborts with an error message if prolog place is set to "after reset" but iptables-restore is used to activate policy. Configuration may end up with this combination of options if user set prolog place to "after reset" first and switched activation method to iptables-restore later. * ACL.cpp (ciscoACL::addRemark): fixed bug #1778536 "IOSACL - remark command". Remarks now include rule comments; if comment consists of several lines, each line is added using separate remark statement. This works for both IOS ACL and PIX platforms. 2009-07-12 vadim * printerStream.cpp (printerStream::printQTable): fix bug #2807724: "Print out FWB still not ok". Taking into account hidden rable rows associated with rule groups while printing rule sets. Before this fix some rules disappeared between pages in the printout. 2009-07-11 vadim * PrintingController.cpp (PrintingController::printRuleSet): bug #2807724: "Print out FWB still not ok". Rule groups were always printed expanded, even if they were collapsed by the user in the GUI. * OSConfigurator_openbsd.cpp (processFirewallOptions): fixed bug #2820162 "Bad sysctl name for OpenBSD pf" - the sysctl argument for IPv6 forwarding was incorrect. * AddressRange.h (libfwbuilder): fixed bug #2820152: "Address ranges and other such need IPv4/v6 typing". AddressRange object should be recognized and removed from the rule if it is used in ipv6 rule set. To do this, add virtual method hasInetAddress() (should return true) to indicate that this object has an address. This works since virtual method getAddressPtr() has been implemented anyway. * VERSION (VERSION): started v3.0.6 2009-07-11 vadim * FindObjectWidget.cpp (FindObjectWidget::inSelectedFirewall): Search and replace did not work in scope "policy of opened firewall" for cluster policies. Fixes #185 * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): since current implementation can not generate configuration commands for interfaces of the member firewalls using attributes of the cluster interface, disable GUI controls in the interface object dialog if it is an interface of a cluster. fixes #187 * Summary of changes in the "interface advanced options" dialogs for cluster interfaces. The "Advanced settings" button is now disabled in the dialog for the main cluster interface. The code has been changed to always check the type of the failover group instead of the interface type where it needs to determine failover protocol (vrrp, heartbeat or carp). All parameters of the failover protocol should be configured using failover group object. The "advanced options" dialog is still available for interfaces of the real firewalls and their subinterfaces. Fixes #109, refs #180, #183, #181, #187, #179, #163 2009-07-09 Vadim Kurland * OSConfigurator_linux24_interfaces.cpp (printInterfaceConfigurationCommands): user can now add loopback interface to the cluster object and use it in rules. This interface does not have failover group and has the usual 127.0.0.1/8 ip address. fixes #163 * OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces): ref #181: using failover group type instead of cluster interface type. * newClusterDialog.cpp (newClusterDialog::finishClicked): ref #183: set type of the cluster intrfaces to "cluster_intrface". Before, new cluster wizard unconditionally set it to "vrrp". Still need to add dialog elements to let user choose failover protocol. * linux24IfaceOptsDialog.cpp (linux24IfaceOptsDialog::linux24IfaceOptsDialog): fixes #180: hide "interface type" gui element from the "advanced" interface options dialog for the main interfaces of cluster objects. These interfaces have no parameters and their type always matches the type of failover cluster group object. All parameters of the failover protocol are set in the dialog of the failover group. * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): ref #180 : disable "Advanced settings" button in the interface object dialog if it is main intrface of a cluster object. 2009-06-29 Vadim Kurland * CompilerDriver_ipt_run.cpp (CompilerDriver_ipt::run): Compiler checks types of state sync and failover groups and aborts if it finds unsupported type. Fixes #164 * ClusterDialog.cpp (ClusterDialog::resetClusterGroupTypes): fix types of state sync and failover groups when user changes host OS and/or platform. Fixes #164 2009-06-28 Vadim Kurland * OSConfigurator_linux24_interfaces.cpp (printBondingInterfaceConfigurationCommands): Support for intrface bonding for generic Linux firewall. "Advanced" interface settings dialog provides three interface types: "vlan", "bridge", "bonding". For bonding interfaces, GUI controls are provided for the following parameters: mode, xmit_hash_policy and a free-style single line input field for other driver options. Fixes #172 * platforms.cpp (getInterfaceTypes): Support for "heartbeat" failover protocol in clusters: "heartbeat" interface type, "heartbeat" failover group type. Compiler adds rules to permit vrrp only when failover type is set to "vrrp". For "heartbeat" failover no rules are added atm. Fixes #169 * Compiler_cluster.cpp (Compiler::processFailoverGroup): (change in libfwbuilder) fixes #166: cluster should be allowed to have interfaces with the same name as interfaces of the member firewall (i.e. "eth0"). This is necessary to support failover protocols that do not create virtual interfaces, but rather operate over normal interfaces, such as heartbeat. 2009-06-23 vadim * pfAdvancedDialog.cpp (pfAdvancedDialog::pfAdvancedDialog): force the tab widget to open tab 0 on creation of the dialog. Often after the dialog was modified in Designer, it is left in the state when it opens on some random page. This fixes #155 "pf advanced settings dialog opens on tab "Script" by default" * OSConfigurator_bsd.h: common class for all supported BSD-like host OS (freebsd, openbsd, macosx). Using common base class to avoid code duplication. This fixes #162 "ifconfig commands to create carp and pfsync interfaces are not generated for FreeBSD". * ClusterGroupDialog.cpp (ClusterGroupDialog::addIcon): fixes #161: pfsync protocol does not require "master" setting in cluster group. * clusterMembersDialog.cpp (clusterMembersDialog::availableClicked): Let user click in any column of the list except the very first to select interface to be added to the list of cluster group members. * clusterMembersDialog.cpp (clusterMembersDialog::updateAvailableTree): fixes #111 "Member dialog should keep the tree on the left hand side expanded all the time". The left hand side panel used to collapse all available firewalls, thus hiding their interfaces from view every time user added an interface to the right hand side panel. * CompilerDriver.cpp (CompilerDriver::configure): Using separator "," between fw object id and file name instead of ':' which was a poor choice because it is part of the file path on Windows. Fixes #157 * CompilerDriver_pf.cpp (CompilerDriver_pf::getConfFileName): Using QT classes QFileInfo and QDir to manipulate output file names and paths portably. * freebsd.xml.in: Support CARP/pfsync clusters on FreeBSD. 2009-06-19 vadim * release_notes_3.1.0_en_US.html: fixes #146: A warning telling the user that the way bridging interfaces should be configured has changed. Uses a one-time dialog created per #145. Refs #145 #147. * FWWindow.cpp (FWWindow::startupLoad): Fixes #145: universal facility for a one-time dialog shown to the user on program start. These dialogs will have important information about the release. Dialog is shown once for each version. 2009-06-18 vadim * newFirewallDialog.cpp (newFirewallDialog::newFirewallDialog): Fixes #90: Interface attribute "bridgeport" has been deprecated, removing GUI controls in the new firewall dialog and interface dialog. * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): Fixes #143: If inetrface is a bridge port, then GUI elemnts "regular", "dynamic" "unnumbered" should be disabled b/c it can not have an ip address. Instead, showing text label "Bridge Port Interface". * ObjectManipulator.cpp (ObjectManipulator::relocateTo): Implemented drag&drop function to move objects from one place in the tree to another. Dragging with Ctrl button pressed creates a copy. Fixes #141. 2009-06-17 vadim * v3.0.5 released in the main production branch 2009-06-14 vadim * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): Ticket #55: (libfwbuilder) deprecated isExt() and setExt() methods. Platforms that care about interface being external should use security levels. Currently this is only PIX and it uses sec. levels already. Also removed dialog element in InterfaceDialog class and references to these methods elsewhere. Compilers did not use the flag "ext" already. 2009-06-11 vadim * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printRule): implemented feature request #1778536: "IOSACL - remark command". This adds support for the "remark" command in generated IOS ACL configuration. Controlled by the checkbox "Add ACL remarks" in the "Script" tab of the firewall object settings dialog. 2009-06-09 vadim * NATCompiler_pf_writers.cpp (PrintRule::_printSrcPort): fixed bug #2803702 "NAT rule with source port range in TSrv is broken for PF". NAT rules matching source port ranges and translating source port ranges should be possible. * NATCompiler.cpp (classifyNATRule::processNext): (change in libfwbuilder) fixed bug #2803689 "NAT rule matching dport but chaning sport is broken". NAT rules that match destination port but translate source port should be possible (and the opposite too). 2009-06-08 vadim * NATCompiler_ipt.cpp (splitSDNATRule::processNext): Improved support for NAT rules that translate both source and destination: now a rule like this can translate both source and destination addresses and at the same time source and destination port ranges. Compiler generates two iptables commands, one with SNAT and another with DNAT translation for a rule like this. * PolicyCompiler_ipt.cpp (checkForDynamicInterfacesOfOtherObjects::findDynamicInterfaces): Using Compiler::abort() instead of throwing exception on all error conditions in the compiler. * NATCompiler_PrintRule.cpp (PrintRule::processNext): Added support for SNAT rules that translate only source port of udp or tcp packets. This rule generate "-j SNAT --to-source :" with no address part. 2009-06-06 vadim * PolicyCompiler_pf.cpp (PolicyCompiler_pf::compile): fixed bug (no #): compiler for PF did not remove rules using IPv4 objects while compiling policy set to be "combined IPv4 and IPv6" for IPv6 and vice versa. As the result, it used to double some rules because the would appear both in IPv4 and IPv6 sections of generated .conf file. 2009-06-05 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printIP): fixed bug #2801548 "fwb_ipt should issue error for ipsrv with options for ipv6". Since IP options lsrr, ssrr, rr do not exist in ipv6, compiler should refuse to compile rules that request matching these options. * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printIPServiceOptions): fixed bug #2801547 "fwb_iosacl should issue an error for ipservice with options". IOS access lists can not match source routing options set in IPService object, compiler should issue an error and abort processing when an object like this is encountered in a rule. * IPServiceDialog.cpp (IPServiceDialog::loadFWObject): fixed bug #2801545 "IP Service object: lsrr, ssrr, rr options not saved". * PolicyCompiler_pf_writers.cpp (PrintRule::_printDstService): fixed bug #2801544 "missing space after tos option in pf config" 2009-06-04 vadim * IPTImporter.cpp (IPTImporter::pushPolicyRule): fixed bug #2801362 "Iptables policy import does not handle rules with ESTABLISED". Policy importer for iptables should properly handle rules that use combination of a "-p protocol" and match state "RELATED,ESTABLISHED". Example: -A INBOUND -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT This rule should translate into fwbuilder rule using CustomService object with code "-m state --state RELATED,ESTABLISHED" and protocol spec "tcp". 2009-06-03 vadim * ObjectManipulator.cpp (ObjectManipulator::findWhereUsedRecursively): fixed bug #2800625 "recursive groups cause infinite loop and crash in compiler". When a group included itself, compiler used to go into infinite loop and crash. The fix in this function also takes care of the situation when group A referenced group B, which in turn referenced group A again. * OSConfigurator_linux24_interfaces.cpp (OSConfigurator_linux24::printBridgeInterfaceConfigurationCommands): implemented support for bridge configuration on Linux using brctl tool. Of bridge options only "stp on" is supported, it turns on STP protocol support on the bridge. 2009-06-02 vadim * OSConfigurator_linux24.cpp (OSConfigurator_linux24::configureInterfaces): implemented support for VLAN interfaces for Linux24 host os. Generated script uses "vconfig" to create and configure vlan interfaces. GUI provides elements for VLAN ID and VLAN interface name type (VLAN_PLUS_VID (vlan0005), VLAN_PLUS_VID_NO_PAD (vlan5), DEV_PLUS_VID (eth0.0005), DEV_PLUS_VID_NO_PAD (eth0.5). Compiler verifies that the name of the vlan interface object matches requested name type. 2009-06-01 vadim * OSConfigurator_openbsd.cpp (OSConfigurator_openbsd::configureInterfaces): implemented support for pfsync interface configuration for OpenBSD. Unicast communication method can be configured using checkbox in the pfsync protocol options dialog. Compiler generates ifconfig commands to configure pfsync virtual interfaces if checkbox "Configure pfsync interfaces" is turned on in the pf "advanced" settings dialog. Only one pfsync interface per firewall is supported (pfsync0), only with IPv4 addresses. * OSConfigurator_openbsd.cpp (OSConfigurator_openbsd::configureInterfaces): implemented support for CARP interface configuration for OpenBSD. Generated script uses ifconfig to create and configure carpN interfaces. The script is added only if option "Configure CARP interfaces" is turned on in the "advanced" settings dialog for PF. Currently only IPv4 addresses are supported and only one address per CARP interface is configured. CARP password and VHID are defined in the failover protocol settings dialog that user can open by clicking "Protocol parameters" button in the Failover group object dialog. * newHostDialog.cpp (newHostDialog::selectedInterface): fixed the same error reported in bug #2799163: "crash on correcting an error". The GUI crashed if user tried to add, then delete interfaces in the new firewall wizard. The crash occurred when the last interface was deleted on the page where interfaces can be configured manually. This needed to be fixed in both "new firewall" and "new host" dialogs. 2009-05-31 vadim * FindObjectWidget.cpp (FindObjectWidget::findNext): fixed bug #2799315 "Find object" cant find object in rules of opened firewall. If scope was set to "policy of the opened firewall", "Find object" function could not find anything. It worked when scope was set to "policy of all firewalls". * RuleSetView.cpp (RuleSetView::contextMenu): fixed bug #2799254 "Erratic behavior when rule is removed from the group". If user tried to remove a rule from the middle of a group of rules, the GUI behaved erratically. It showed two groups with the same name, each of these two groups claimed to have more rules than it really did. Also only one of these two groups could be collapsed at the time. Other weird things also happened. The fix is to not allow removing a rule from the rule group if the rule is in the middle. * newFirewallDialog.cpp (newFirewallDialog::selectedInterface): fixed bug #2799163: "crash on correcting an error". The GUI crashed if user tried to add, then delete interfaces in the new firewall wizard. The crash occurred when the last interface was deleted on the page where interfaces can be configured manually. * ObjectTreeView.cpp (ObjectTreeView::dragMoveEvent): fixed bug #2799174: "Multiple instance crashes a bug". The GUI crashed if user tried to drag and drop an object between two different running copies. Copy/Paste and Drag&Drop between separate copies are not supported at this time. 2009-05-30 vadim * CompilerDriver_pf_run.cpp (CompilerDriver_pf::run): ref #22: compiler for PF uses CompilerDriver class. 2009-05-29 vadim * newFirewallDialog.cpp (newFirewallDialog::finishClicked): better fix for the bug #2796760 "Display error when adding new FW with multiple interfaces". 2009-05-28 vadim * ObjectManipulator.cpp (ObjectManipulator::actuallyCreateObject): fixed bug #2797791: "Display error when duplicating an object". * InterfaceData.cpp (InterfaceData::guessSecurityLevel): (change in libfwbuilder) set security level to 0 (insecure) by default. This makes all interfaces of the newly created firewall be "external" or "insecure" unless they were assigned labels or addresses from the private address space in which case guessSecurityLevel() assigns level 100. This addresses bug #2796760 "Display error when adding new FW with multiple interfaces". 2009-05-27 vadim * RCSFilePreview.cpp (RCSViewItem::operator<): implemented feature req. #2796238 "3.0.4 - FEAT REQ: Sort order for RCSFilePreview". RCS file preview dialog (the one that shows RCS revisions and RCS log records) can display revisions in the tree or list view style, controlled by radio-buttons. Style setting is saved in user preferences and persists from session to session. In both cases the view can be sorted by revision number or data. Sort column choice is also saved in preferences. By default program sorts by date and selects the latest revision. * ObjectManipulator.cpp (ObjectManipulator::actuallyPasteTo): fixed bug (no #): the GUI did not allow to copy/paste an address from one interface to another. This should be possible. * PolicyCompiler_pf_writers.cpp (PrintRule::_printAddr): fixed bug (no #): policy compiler for pf crashed when dynamic interface was used in source or destination of a policy rule. * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed bug #2793144 "Context menu item for the new User Service object is missing". 2009-05-21 vadim * ProjectPanel_file_ops.cpp (ProjectPanel::fileOpen): (finally) fixed the algorithm used to determine directory offered to the user when they use main menu File/Open to open a file: 1) if "work directory" is configured in preferences, always use it first; 2) if it is blank, use the same directory where currently opened file is located; 3) if this is the first file to be opened, use the same directory user used last time they ran the program (saved in user settings). * RuleSetView.cpp (RuleSetView::pasteObject): fixed bug #2794827 "crash when pasting from a Library in a another file". The GUI crashed if user tried to copy/paste an object from one data file into a rule in another. 2009-05-20 vadim * ObjectEditor.cpp (ObjectEditor::help): Added support for the built-in help page for all objects dialogs, including rule actions and options dialog. Implemented help pages for actions "Route", "Branch", "Tag", "Classify" and rule options dialogs for iptables and pf. Button "Help" is greyed out if corresponding help page is unavailable. * RuleSetView.cpp (RuleSetView::switchObjectInEditor): fixed bug #2794484 "Crash after click in the "Options" col of rule group title". 2009-05-16 vadim * PolicyCompiler_ipt.cpp (checkInterfaceAgainstAddressFamily::processNext): fixed bug #2792888: "interface with only v4 address is used in v6 rules". Compiler should drop rule if it is associate with an interface that does not have address that belongs to the address family declared for the rule set. If interface has only ipv4 address, it will never see ipv6 packets and therefore rules that have this interface in the "interface" rule element should not be included in the output generated for the ipv6 or combined ipv4+ipv6 rule sets. 2009-05-14 vadim * PolicyCompiler_pf.cpp (fillDirection::processNext): fixed bug #2791950 "no way to generate "pass out" rule with no interface". Compiler created two rules "pass out" and "pass in" for rules with no interface and direction "in" or "out". It should create one rule with direction defined by the rule in the GUI. 2009-05-12 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): fixed bug #2790927: "Add support for "sloppy" state tracking for PF". * FWWindowPrint.cpp (FWWindow::tableResolutionSettingChanged): Using slider widget to set table scaling factor; now user can choose any scaling factor between 1 and 200%. This fixes bug #2789903: "Table scaling when printing in 3.0.4" 2009-05-09 vadim * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printShellFunctions): Moved configuration for the location of kernel modules to host os resource file (attribute Target/options/default/modules_dir). The value of this attribute is different for OpenWRT. This fixes ticket #2. * DialogFactory.cpp (DialogFactory::createFWDialog): Now that we use common platform "iptables" for linux-based appliances and differentiate then by host_OS, dialog for IPCOP, Endian and OneShield is determined using combination of platform and host family attribute from the os resource file. * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printShellFunctions): Fixes #2: added host OS "OpenWRT"; the only difference at this time is the path to the directory where kernel modules are found. * ipt.cpp (main): Now that we use the same platform name for iptables on linux, ipcop, endian, oneshield and secuwall, there is no need in policy/nat/routing compiler classes for ipcop. * platform/iptables.xml.in: Unified support for different iptables appliances: configuration will require platform "iptables" and host os that corresponds to the chosen appliance. This matches support for Secuwall and is easier to maintain than separate platform-os pairs for each appliance. 2009-05-08 vadim * clusterMembersDialog.h (class clusterMembersDialog): Renamed class and module secuwallClusterConfDialog to clusterMembersDialog. This dialog is generic and is not specific to secunet wall in any way. This fixes #13. * PolicyCompiler_ipt.cpp (removeFW::processNext): fixes #15: using Compiler::isFirewallOrCluster to match object in rules to both firewall or it parent cluster. This helps compiler idenitify cluster in rules and choose correct chains (INPUT/OUTPUT) as if firewall object was there. * CompilerDriver.cpp (CompilerDriver::determineOutputFileName): this method implements logic that extracts enforced output file names from command line parameters of the compiler or determines these names automatically. * instDialog_compile.cpp (instDialog::prepareArgForCompiler): While compiling firewall cluster, passing output file name to the compiler using "-O" command line option. The old option "-o" is preserved for backwards compatibility and is used while compiling stand-alone firewall objects. 2009-05-07 vadim * instDialog_ui_ops.cpp (instDialog::createTreeItem): dialog that lists firewalls and clusters for compilation and installation puts checkbox for compile next to a cluster and checkbox for install next to a real firewall. Checkboxes are pre-checked if corresponding objects require compilation and installtion. Mutual dependencies between cluster and its members are tracked. this fixes #19 * ipt.cpp (main): Policy compiler for iptables accepts either Firewall or Cluster object as an argument. If Cluster is specified, compiler runs itself several times, generating script for each member firewall. Object can be defined by its name or ID as before. This fixes #18. * CompilerDriver.h (class CompilerDriver): Introduced class CompilerDriver that controls invocation of Policy, Mangle, NAT and Routing compilers for one firewall. The firewall may be part of a cluster, in which case we create several objects of this class and process each member firewall separately. * PolicyCompiler_secuwall.cpp (PolicyCompiler_secuwall::addMgmtRule): fixes #16: using RuleSet::insertRuleAtTop with arg hidden_rule to make automatic rules added for secunet wall "hidden". This way, these rules are ignored during shadowing detection and their position numbers are forced negative so that position numbers of regular rules do not change. 2009-05-06 vadim * FirewallInstallerCisco.cpp (FirewallInstallerCisco::activatePolicy): fixed bug #2787932 "External install script is not supported for PIX". 2009-05-04 vadim * instDialog_ui_ops.cpp (instDialog::fillCompileSelectList): dialog that shows list of firewalls for compilation and installation now uses QTreeWidget and displays firewall clusters and corresponding member firewalls as branches in the tree. The rest of the functionality remains the same as before. If user selected a cluster object in the object tree and clicked "Compile" in its context menu, only member firewalls of this clusters are going to be checked for compilation. Clicking "Compile" toolbar button or main menu selects all firewalls for compilation as before. Cluster objects can not be selected (do not have checkboxes in the widget) because compiler and installer works with actual firewall objects rather than cluster objects. This fixes ticket #7. 2009-05-02 vadim * DiscoveryDruid.cpp (DiscoveryDruid::DiscoveryDruid): fixed bug #2785671 "Menu 'Import Policy' opens wizard with wrong option checked". The "discovery druid' dialog would open on the first page (where user makes a choice which discovery method to use) even when called via main menu "File/Import Policy" and radio button for the SNMP discovery was activated. 2009-04-30 Vadim Kurland * ObjectManipulator.cpp (ObjectManipulator::addTreePage): fixed bug #2783780: using QTreeWidget::sortItems() instead of sortByColumn to sort objects in the tree. 2009-04-29 Vadim Kurland * RoutingCompiler_pix.cpp (RoutingCompiler_pix::prolog): fixes bug #2782645: "Can't compile for FWSM platform". Routing compiler for PIX should accept firewall object with platform "fwsm" as well as "pix". * ObjectManipulator.cpp (ObjectManipulator::actuallyCreateObject): fixes bug #2783780: "Tree objects not sorted in 3.0.4". Automatically re-sort object branch when new host or firewall object is created so that the new object is positioned in the alphabetic sorting order. 2009-04-27 vadim * ObjectManipulator.cpp (ObjectManipulator::getMenuState): for bug #2782289: "Crashes when deleting unused host object". Added safeguards to make it impossible to delete objects in the Standard library, as well as for a few other cases. Waiting for a clarification on the bug anyway. * ObjectListView.cpp (ObjectListView::dragObject): fixed bug #2781952: "fwbuilder (3.0.4-b794) crashes when creating a new group". The GUI crashed if user clicked and dragged mouse inside empty list of group members in the dialog of the new group object. 2009-04-17 vadim * ClusterDialog.cpp (ClusterDialog::ClusterDialog): Support for clusters of firewalls * Merging patches from Secunet Security Networks AG to add support for Secuwall firewall. * VERSION: start v3.1.0 branch v3_1_secunet 2009-04-15 vadim * ipcopAdvancedDialog.cpp (ipcopAdvancedDialog::ipcopAdvancedDialog): Integration with IPCOP, Endian and OneShield firewall apliances (all based on linux/iptables). This sets generate file name to "rc.firewall.local", destination directory on the firewall to "/etc/rc.d/" and activation command to "/etc/rc.d/rc.firewall restart". Provided resource files for ipcop, endian and oneshield platforms and os define default parameters, including path to iptables and other command line tools. Generated script performs minimal environment setting, because everything is supposed to be set up by the aplpiance itself. Iptables commands are put in the standard chains INPUT/OUTPUT/FORWARD, with user-defined chans created as required. At this time policy and NAT rules work. Rules added by fwbuilder are activated by the standard appliance firewall script rc.firewall after all IPCOP rules are added and before all hooks. This means rules created by fwbuilder do not replace rules added by the appliance, but work together with those. Prolog and epilog user-defined sections work as well. Prolog is always added on top of the rules generated by fwbuilder. Prolog and epilog sections can include any kind of shell commands, not only iptables rules. Two new firewall templates are provided: one for IPCOP/Endian firewall with two interfaces (br0 is GREEN and eth1 is RED) and another for the appliance with three interfaces (additionally eth2, as ORANGE). * ipt.cpp (main): implemented feature request #2454447 "Standard options for startup-script". Script generated by fwbuilder now accepts standard arguments "start" and "stop". Running the script with no argument is equivalent to "start" for backwards compatibility. Running script with argument "stop" resets iptables tables and chains and sets all to default policy DROP (beware!). 2009-04-11 vadim * platforms.cpp (setPlatform): Firewall platforms are grouped in the drop-down list that appears in the firewall object dialog and new firewall creation dialog. Platforms are grouped using XML element in the platform xml resource file. * newFirewallDialog.cpp (newFirewallDialog::finishClicked): remember firewall platform used to create new firewall object between sessions. Also limit set of host OS shown in the second combo box to only those supported by chosen firewall platform. * VERSION: start v3.1.0 * platforms.cpp (setHostOS): fill "hsot OS" drop-down list with OS names supported for the choosen firewall platform. 2009-04-10 vadim * ipt.cpp (dumpScript): fixed bug #2356131: "Iptables-restore option broken for multiple policy sets". Compiler inserted redundant line "echo COMMIT" to the iptables script if iptables-restore was used and there were no rules in the mangle table. * ObjectManipulator.cpp (ObjectManipulator::findWhereUsedRecursively): fixed bug #2744798 "dependency checking failed". In case when an object was used in a group and group used in a rule of a firewall, the program failed to properly update "last modified" attribute of the firewall when the object was changed. 2009-04-09 vadim * VERSION: start v3.0.5 2009-04-08 Vadim Kurland * v3.0.4 released, merged to the trunk, this comment is r796 2009-03-29 vadim * v3.0.4 release 2009-03-25 vadim * NATCompiler_pf_writers.cpp (PrintRule::_printPort): fixed bug #2712514: "Bug in PF NAT Writer - 'tagged' keyword". Keyword 'tagged' is only allowed on the left hand side of '->' in nat and rdr rules. * RuleElement.cpp (RuleElementTSrv::validateChild): (change in libfwbuilder) fixed bug #2712575: "NAT RuleSetView allows TagService to be in Translated Svc". TagService object should not be allowed in "Translated Service" in NAT rules. 2009-03-24 vadim * DialogData.cpp (DialogData::loadToWidget): fixed bug #2710309: "Bug in gui/DialogData.cpp when not using mapping.". There was a bug in DialogData.cpp that when setting the value of a combobox and not using a mapping array the requested value would not be selected. Applied patch provided by Tom Judge ( tomjudge ) * platforms.cpp (init_platforms): fixed bug #2710300 "Bug in gui/platforms.cpp". there was a discrepancy between the list of route-to options for PF and UI elements. * pf.cpp (main): more changes to add support for externally-controlled policy rulesets for PF: if policy ruelset name ends with "/*", the program assumes it is controlled by external means and does not compile rules in it and does not create .conf file from it. * PolicyCompiler_pf_writers.cpp (PrintRule::_printAction): Added support for anchor names with "/*" suffix for PF. Now the user can create policy ruleset with name e.g. "ftp-proxy/*" and then set up branching rule pointing to this ruleset. This ruleset is treated by the program in a special way. First, it allows characters "/" and "*" in the name of the ruleset (but only for PF firewalls). Second, compiler does not create a .conf file with rules from this ruleset, assuming that it will be controlled by external program such as ftp-proxy. See man page ftp-proxy(8) for examples. 2009-03-23 vadim * pf.cpp (main): fixed bug (no #): compiler for pf added code provided in the "prolog" section while option was set to "add after table definitions" in the incorrect place. 2009-03-22 vadim * RuleSetView.cpp (RuleSetView::updateGroups): fixed bug #2701593 "gui problem". Adding a rule to a policy with rule groups caused weird rule display - a rule immediately above rule group header would appear empty, with only "Source" shoring. 2009-03-19 vadim * iosacl.cpp (safetyNetInstall): fixed bug #2694146: "IPv6 temporary ACL blocks ICMPv6". Temporary ipv6 access list created for the "safety net install" should permit icmp. 2009-03-18 vadim * iosacl.cpp (safetyNetInstall): fixed bug #2694440 "Multiple policies cause multiple temporary ACLs": when "safety net install" option is used, temporary access list must be generated only once even when firewall object has multiple rulesets. * PolicyCompiler_iosacl.cpp (PolicyCompiler_iosacl::prolog): fixed bug #2694432 "IOS ACL syntax error with IPv6 host addresses & "safety net"": temporary access list created for IOS when option "safety net install" is used and ipv6 address is provided should use keyword "host" if provided address does not specify netmask. * fwbedit: properly saving data file after "checktree" operation 2009-03-17 vadim * PolicyCompiler_iosacl.cpp (PolicyCompiler_iosacl::prolog): fixed bug #2689978: "IOS ACL 'safety net' doesn't support IPv6?". Compiler did not process properly ipv6 address entered in the "safety net" install script option parameter. * iosaclAdvancedDialog.cpp, pixAdvancedDialog.cpp: fixed bug #2689987: "Typo in "script options" tab in 'Firewall settings'". * IPv6Dialog.cpp (IPv6Dialog::changed): fixed bug #2689958 "Error changing properties of a IPv6 address". Button "Apply" would stay greyed out when user changed network prefix length in IPv6 address dialog. 2009-03-12 vadim * PolicyCompiler_iosacl.cpp (PolicyCompiler_iosacl::prolog): fixed few bugs (no #) in policy compiler for Cisco IPv6 ACLs: - The "extended" keyword is not supported by IOS for IPv6 ACLs - keyword "established" is only valid in combination with protocol tcp. If standard CustomService objects "ESTABLISHED" and "ESTABLISHED ipv6" are used in a rule, enforce protocol to "tcp". - command to clear ipv6 access lists should be "no ipv6 access-list ipv6_management_in" - command to assign ipv6 acl to interface should be "ipv6 traffic-filter ipv6_acl in" * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printAddr): fixed bug (no #): compiler for IOS ACL used not to ignore netmasks of IPv4 and IPv6 objects and added them to the generated access list with netmask wildcard bits 255.255.255.255 which was equivalen to 'any'. 2009-03-11 vadim * RuleSetView.cpp (RuleSetView::createGroup): fixed bug (no #): if user selected some rules that belonged to a group and few other rules that did not belong to any group at the same time and used context menu to place all these rules in a new group, the GUI used to crash. 2009-03-06 vadim * ProjectPanel.h (class ProjectPanel): code clean-up: removed obsolete method getAddOnLibs() 2009-03-05 vadim * RoutingCompiler_ipt.cpp (addressRangesInDst::processNext): fixed bug #2666971 "fwb_ipt crashes when Address Range object in routing rule". Policy compiler for iptables crashed if Address Range object was used in "Destination" of a routing rule. * RuleSetView.cpp (RuleSetView::insertRule), ProjectPanel.cpp (ProjectPanel::closeEvent): fixed bug #2656815 "Copy/paste does not work properly". Fixed Copy/Paste problem with policy rules and crash reported in this bug report. 2009-03-04 vadim * iosacl.cpp (main), FirewallDialog::platformChanged(): fixed bug #2662290: "fwb_iosacl crash after firewall converted from iptables". If user changed platform setting of the firewall object, the program preserved its old version which was invalid for the new platform. 2009-03-02 vadim * RoutingCompiler_ipt_writers.cpp (PrintRule::processNext): finish fixes for bugs #2540389: "Routing Broken from 2.1 to 3.0.3" and #2356151 "Routing broken when default route has a 0 metric". Redirect script output to a file for the time when we remove static routing entries and add new ones to prevent ssh session from stalling. Restore output back to the terminal when script finishes or when an error is detected. Using idea suggested by Heiko Helmle 2009-02-27 vadim * RoutingCompiler_ipt_writers.cpp (PrintRule::processNext): fixed bugs #2540389: "Routing Broken from 2.1 to 3.0.3" and #2356151 "Routing broken when default route has a 0 metric". Generated script preserved default route when it deleted route entries before installing new ones. This was different in v2.1 where default was deleted together with other routing entries. The reason for this change (made some time in summer of 2008) was that if user did not define default route in their routing ruleset, the script would delete existing default without installing new one, leaving firewall with no default route at all. Now the script deletes default if there is new one to install and preserves it otherwise. * RoutingCompiler_ipt_writers.cpp (PrintRule::processNext): fixed bug (no #): if generated firewall script detects an error from one of the commands that install routing rules and runs function that restores previous routing entries, it should also run epilog commands. 2009-02-21 vadim * FirewallInstaller.cpp (FirewallInstaller::getDestinationDir): bugfix (bug was introduced in build 768). If user entered alternative activation command in the "installer" tab of the firewall object settings dialog, the program confused it with destination directory and tried to execute incorrect command to copy files to the firewall. This build (770) fixes this problem. * SSHUnx.cpp (SSHUnx::SSHUnx): New feature: built-in installer can now enter sudo password. There is no need to configure firewall management account for password-less sudo access anymore. 2009-02-19 vadim * FirewallInstaller.cpp (FirewallInstaller::getDestinationDir): fixed bug #2618772 ""test install" option does not work". If "test install" checkbox was checked in the installer options dialog, the program copied file to directory /etc/fw on the firewall but tried to find it in /etc/fw/tmp to run. * FirewallInstaller.cpp (FirewallInstaller::packSCPArgs): fix bug #2618686 "built-in installer can not handle ipv6 management address". Built-in installer did not properly for scp and ssh command like when it had to use IPv6 address to communicate with firewall. 2009-02-17 vadim * Management.cpp (Management::fromXML): (change in libfwbuilder): fixed bug #2609796 "internal object Management does not accept ipv6 address". Class Management should accept ipv6 address. The problem was that if an interface of the firewall had only ipv6 address and was marked as "management" interface, saving such configuration to .fwb file created broken data file that could not be loaded back. The error was: The program encountered error trying to load data file. The file has not been loaded. Error: Exception: Invalid IP address: 'aaaa:bbbb:cccc::1' XML element : Management where aaaa:bbbb:cccc: is ipv6 address. 2009-02-13 vadim * PolicyCompiler_ipt.cpp (finalizeChain::processNext): fixed bug #2597959 "rules disappear in ipv6 policy unless ipv4 forwarding is on". Example: IPv6 policy, rule where fw object and internal network are in source, destination is "any". If option "assume firewall is part of any" was turned off and ipv6 forwarding was on but ipv4 forwarding was off, this rule did not yield any iptables commands in generated script. * iosaclAdvancedDialog.cpp (iosaclAdvancedDialog::accept): fixed bug #2597949 "GUI crash in IOS ACL "advanced" settings dialog". GUI crashed upon click OK in the firewall settings dialog for the IOS ACL firewall. 2009-02-06 vadim * src/gui/Icons/accept_25.png: fixed bug #2565164 "Colorblind friendly Accept & Deny Icons". Accept and Deny icons were indistinguishable for red-green colorblind people. New icons incorporate standard symbolics for the "Aceept" and "deny" functions to make them sufficiently different besides the color. 2009-02-05 vadim * src/res/os/linux24.xml.in: fixed bug #2568819 "generated script created on windows is not executable". If the GUI runs on Windows, produced .fw script lacks executable permission bit ('x') when it is copied over to the firewall with pscp.exe. Because of this, activation command "sudo -S /etc/fw/script.fw" can not run it and installation fails. Need to run "chmod" as part of the activation sequence. (We used to run chmod as part of the copy sequence when copying was done with ssh/plink.exe. Now that the copy is done with scp/pscp.exe, there is no way to change permissions bits on the firewall side during copy). * OSConfigurator_linux24.cpp: add empty line after user's code in prolog and epilog shell functions to make sure shell syntax is not violated if user does not end prolog or epilog code with linefeed. 2009-01-31 Vadim Kurland * ipt.cpp (processPolicyRuleSet): fixed bug #2550074: "Automatic rules for filter table included twice in iptables". If user had two policy ruleset objects marked as "top" rule set, then automaitc rules were added twice. 2009-01-27 Vadim Kurland * ipt.cpp (main): bug #535146: "firewall script: exit code for ip6tables overwrites iptables". If generated iptables script used iptables-restore to activate the policy and contained both ipv4 and ipv6 iptables policies, return code from iptables-restore was overwritten with return code from ip6tables-restore and only the latter was returned as the return code of the script. To fix this, prolog and epilog commands were moved to shell functions prolog_commands and epilog_commands which are called from various places in the script. Script checks return code of iptables-restore and ip6tables-restore and if an error is detected from either, it runs epilog_commands and terminates, returning error code obtained from iptables-restore (or ip6tables-restore). In case of error, we always run epilog but do not turn ip forwarding on in the kernel. Also, if prolog place is set to "After iptables reset" in the GUI and script uses iptables-restore, prolog commands are executed just before iptables rules are sent to iptables-restore. This means if iptables-restore is used, position "after iptables reset" is equivalent to position "on top of the script". If iptables-restore is not used and prolog position is "after iptables reset", then prolog commands are executed right after the script flushes all chains in all tables and sets deault policy for all chains. Other positions of prolog commands in the script (on top and after interface configuration) are naffected and work as before. 2009-01-24 vadim * objects_init.xml.in: Added CustomService object "ESTABLISHED ipv6" which defines code for iptables, ipfw and IOS extended access lists for IPv6. * PolicyCompiler_ipfw_writers.cpp (PrintRule::_printProtocol): fixed behavior or policy compiler for ipfw which was broken in rev714 - it should print protocol "tcp" when custom service object that adds option "established" is used. This compiler worked like that before attribute "protocol" was added to the CustomService object. * platforms.cpp (getReadableRuleElementName): code refactoring: made it possible to translate ruleset table column names ("Source", "Destination" etc.). Currently only Russian translation is provided. 2009-01-23 vadim * FindWhereUsedWidget.cpp (FindWhereUsedWidget::createQTWidgetItem): fixed bug #2412334: "feature request: where used -> directly". There has been a change in the "Where used" function in v3.0 compared to the implementation in v2.1. New version showed not only rule elements and groups that referred to the given object, but also found all groups that referred to other groups that referred to the given object. Such recursive action was not always obvious to the user and was inconvenient when the function was used to find all places where given object was used with the goal to replace it with some other object. This fix reverts to the old behavior where only direct usages are reported by the "Where used" function. Elements of UI in this function have also been cleaned up and further unified with confirmation dialog shown when user tries to delete an object that is used in some groups and rules. * PolicyCompiler_PrintRule.cpp (PrintRule::_printChain): fixed bug #2507239: "length of iptables rule chain names not checked". Iptables does not allow chain names longer than 30 characters; policy compiler fwb_ipt should check for this. * PolicyCompiler_PrintRule.cpp (PrintRule::_printAddr): fixed bug #2526173: "fwb_ipt crashes due to old-broadcast". This bug was introduced when support for module iprange was sadded. Need special check for AddressRange objects where start and end of range addresses are equal. * NetworkDialog.cpp (NetworkDialog::addressEntered): fixed bug (no #): the GUI used to check ip address entered for the network object whenever user switched focus from the address input widget in the network object dialog to another widget or even a different application to look up the address. This caused the program to show error dialog if this happened when the address was incomplete. This change makes the program verify the address only when user clicks "Apply". 2009-01-19 Vadim Kurland * FWWindow.cpp (FWWindow::prepareFileOpenRecentMenu): Added menu Files/Open Recent. This implements feature req. #2499615 "open last used file". * FWWindow.cpp (FWWindow::startupLoad): open StartTipDialog from FWWindow rather than main() to make sure this dialog always remains on top of the main window. * ProjectPanel_file_ops.cpp (ProjectPanel::autoSave): fixed bug #2499569: "fwbuilder crashes after some hours". The auto-save function now saves data file only if it has been modified. Frequent saves exasperate small memory leaks that appear in some old versions of libxml2. 2009-01-17 Vadim Kurland * FWWindowPrint.cpp (FWWindow::filePrint): fixed bug (no #): the GUI crashed if user tried to use File/Print function when no ruleset was opened in the right hand panel. * printerStream.cpp (printerStream::printQTable): Applied patch by Paul@Auroragrp.Com that fixes problems with printing long rule sets. If rule set printout exceeded the length of the page, some rules at the bottom were cut off and lost. The patch corrects the problem by taking into account printer dpi while calculating position for page breaks. 2009-01-11 vadim * unknown.xml.in: fixed bug #2486558 "firewall platform "unknown" should support basic actions". 2009-01-10 vadim * DiscoveryDruid.cpp (DiscoveryDruid::loadDataFromCrawler): bug #2023261 "IPv6 - SNMP discovery of interfaces not working for IPv6". SNMP discovery can now read IPv6 addresses of interfaces using IP-MIB RFC4293. Not all snmp agents support this MIB, for example only recent versions of net-snmp support it. * starting with v3.0.4 build 739 snmp discovery is supported on Windows. 2009-01-06 vadim * RoutingCompiler_iosacl_writers.cpp (PrintRule::PrintRule): fixes to make code compile on Windows. 2009-01-05 vadim * RoutingCompiler_cisco.cpp (RoutingCompiler_cisco::compile): fixed bug (no #): routing compiler for pix refused to add more than one routing rule with an error saying that other rules were duplicates. Error was introduced in build 732. 2009-01-02 vadim * RoutingCompiler_iosacl.cpp (RoutingCompiler_iosacl::compile): Added support for generation of "ip route" commands for Cisco IOS. Variant of Cisco IOS "ip route" command where gateway is the name of one of the interfaces of the router is also supported. To get this, put interface object in the "gateway" column of the routing rule. * pix.xml.in, RuleSetView.cpp: Routing ruleset view shows column "interface" only for platforms that require it. Currently IOS does not require it, while other platforms for which routing commands generation is supported require it (iptables and PIX). 2009-01-01 vadim * RoutingCompiler_cisco.cpp: refactored PIX routing compiler by steven@openbsd.org to use it as a foundation of the routing compiler for both PIX and Cisco IOS (r731). * RoutingCompiler_pix.cpp: applied patch by Steven Mestdagh that adds support for static routing configuration for PIX. Patch tested and applied in r726. 2008-12-31 vadim * RuleSetView.cpp (RuleSetView::copyRule): fixed bug #2478528: "Crash when copying multiple policy rules". GUI crashed if user tried to copy/paste several rules, some of which belonged to rule group and some did not. 2008-12-30 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_clampTcpToMssRule): bug #2477775: "Clamp MTU doesn't work in ip6tables". iptables target TCPMSS is available in ip6tables only in 1.3.8 and later. * unfortunately the package is not going to work on Tiger because of the mismatch in versions of libnetsnmp library. If this library is packaged with the bundle, the program crashes because the code in libnetsnmp v15.1.0 (that comes with Leopard) depends on functions missing in libSystem on Tiger. If libnetsnmp is not packaged with the bundle, then stubs linked with the GUI on Leopard do not match libnetsnmp that comes with Tiger (older version). So, even though we now have universal Mac OS X binary, it will only work on Leopard. 2008-12-29 vadim * FirewallInstallerUnx.cpp (FirewallInstallerUnx::executeInstallScript) bug #2474949: "External install script: trailing spaces". Trimming leading and trailing white spaces in the external installation script and its arguments before running it. * runqmake.sh: starting with v3.0.4 build 717, building universal binary for Mac OS X (both x86 and ppc architectures) * bug #2474194 "Please Provide MacOS X PowerPC Builds": debugging universal binary package for Mac OS X, trying to make it work on Tiger as well 2008-12-28 vadim * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printDstService): support for the CustomService in compiler for IOS ACL, including support for address family, protocol and code string parameters. * PolicyCompiler_ipfw_writers.cpp (PrintRule::_printProtocol): support for the new "protocol" parameter of the CustomService object in compilers for ipfilter and ipfw. * NATCompiler_pf_writers.cpp (PrintRule::_printProtocol): 'checking for "proto ..." in the custom service code string before printing protocol part in policy and nat compilers for pf. 2008-12-27 vadim * feature req. #1111267 "CustomService should specify protocol and parameters for it". Support for protocol string in Custom Service in compilers for iptables and PF. * CustomServiceDialog.cpp (CustomServiceDialog::loadFWObject): feature requests #1111267 "CustomService should specify protocol and parameters for it" and #2463048 "custom services should have IPv4/v6 setting". Added corresponding input elements to the CustomService object dialog. * CustomService.h (libfwbuilder): feature requests #1111267 "CustomService should specify protocol and parameters for it" and #2463048 "custom services should have IPv4/v6 setting". Added attributes "protocol" and "address_family" to the CustomService object. Corresponding XML attributes are "#IMPLIED", this helps avoid having to provide XSLT auto-upgrade script for this version. Class CustomService returns "any" for the protocol and "ipv4" for address family if these attributes are missing. 2008-12-25 vadim * All policy compilers: using FWObjectDatabase::createClass methods to create rules and other objects in compilers wherever the type is known at the (code) compile time. This makes code cleaner and speeds it up a little because of eliminated cast() and string comparison. * changes in libfbuilder: eliminated excessive use of dynamic_cast and long chains of "if" comparing object type names in FWObjectDatabase in methods that create new objects of given type. 2008-12-23 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printSrcAddr): implemented feature req. #2353737 "use -m iprange". Using module iprange for AddressRange objects if iptables version is set to >=1.2.11. 2008-12-21 vadim * SSHSession.cpp (SSHSession::heartBeat): built-in installer periodically "pings" the other end to keep ssh session alive. This helps recreate state in the firewall state table if it is cleared when rules are reloaded, which in turn prevents installer from hanging. * PolicyCompiler_pf.cpp (PolicyCompiler_pf::addDefaultPolicyRule): Deprecated options "generate commands for both in and out" and "pass all outgoing" in compiler for PF. Before, user could choose whether compiler was to generate only commands to match inbound packets or both inbound and outbound. The distinction between these two modes became very minimal in the recent versions of fwbuilder because algorithm was mostly controlled by the setting of "direction" in the policy rules. Now these two options have been removed completely, the behavior of the compiler is as if option "generate both in and out" was used. * pf.cpp (main): Compiler can add command "pfctl -F states" after command "pfctl -f file.conf" to flush states that existed in memory from sessions opened prior to the policy reload. The reason is that some of these sessions might be denied by the new policy, but if state is not flushed, they will still work after policy reload. This is optional and is controller by checkbox in the "Script" tab of the "advanced" settings dialog for the PF firewall. 2008-12-20 vadim * PrintingController.cpp (PrintingController::addObjectsToTable): fixed bug #2388067: "Print out FWB 3.0.3 not ok". File/Print function failed to print objects used by rules of the firewall. 2008-12-19 vadim * ProjectPanel_file_ops.cpp (ProjectPanel::loadFile): Implemented feature request #2412323: "feature request: command line flag to skip RCSFilePreview". New command line switch "-r" makes the GUI automatically open RCS head revision of the file given on command line if the file is in RCS. If the file is not in RCS, the new switch does nothing and the file is opened as usual. 2008-12-18 vadim * RuleSetView.cpp (RuleSetView::renameGroup): fixed bug #2412310: "Umlauts in group names". The GUI should properly handle non-ascii characters in the rule group names 2008-12-15 vadim * ipt.cpp, ipfw.cpp, pf.cpp, iosacl.cpp: changes for FR #2431602: support for rulesets configured as "dual address family", that is, rulesets that should be compiled for both ipv4 and ipv6. Compiler processes rulesets like this twice, first for ipv4 and then for ipv6. On each pass it will only use address and service objects that match address family it uses for the ruleset. This also applies to "compile-time" DNSName objects, that is, it will use getaddrinfo() to get AF_INET address on ipv4 pass and AF_INET6 on ipv6 pass. Rules with "any" in rule elements in the "dual address family" ruleset yield iptables commands for both families. This was the reason I made setting exclusive in the first place. This means that users who do not want fwbuilder to generate ipv6 policy for them and want all ipv6 accepted, should not use "dual address family" setting. If the do, the bottom catch-all rule will install ip6tables command to block all ipv6 automatically even if all rules have absolutely no ipv6 objects at all. * RuleSetDialog.cpp (RuleSetDialog::applyChanges): implemented feature request #2431602: "Feature request: Unified policies (IPv4/v6)". RuleSet object now has two variables that define which address family it should be compiled for - ipv4 or ipv6. It is possible to have both set, in which case the same ruleset will be compiled for both address families. 2008-12-13 Vadim Kurland * VERSION (VERSION): started v3.0.4 * v3.0.3 released, merged to trunk. This comment is -r689 2008-12-08 Vadim Kurland * RuleSetView.cpp (RuleSetView::contextMenu): fixed bug #2407141 "label markers". Color label text set in Preferences was not used in the contet menus where user can actually apply those colors to rules. * RCS.cpp: fixed bug #2405909: "Umlauts in RCS log". RCS log is stored in RCS file in Utf8, need to convert it back from Utf8 on read. Technical note: rcs tools on windows do not seem to process properly rcs comments converted with toLocal8Bit, comment text comes out as '????' when inspected with rlog.exe from the command line. Comment text stored in Utf8, on the other hand, appears intact even though it can not be read in the output of rlog.exe. 2008-12-07 Vadim Kurland * FWObjectDatabase_tree_ops.cpp (_recursivelyCopySubtree): (change in libfwbuilder) additional fixes in algorithm that recursively copies object subtree between different data files. Making sure we do not create duplicates of groups referred to by other groups. * ObjectManipulator.cpp (ObjectManipulator::pasteObj): changes to speed up GUI when user copies many objects between different data files (do not reload and redraw object tree widget until last object is copied). Refactoring of the pasteObj to keep the same object ID mapping table for the duration of the bulk paste operation, this helps deduplicate objects. Also using the same ".copy_of_NNNN" object attribute to deduplicate objects. 2008-12-06 Vadim Kurland * iptables.g: Changes in grammar for iptables: removed ambiguitiesin parser; added lexer rules for elements of ipv6 address. Rules for IPV6 address parsing do not work yet, commented out as work in progress. No new functionality in the parser for iptables, only clean-up and preparations for ipv6. 2008-12-05 Vadim Kurland * InetAddr.cpp (InetAddr::toString): (change in libfwbuilder): Should use bits==128 because inet_net_ntop_ipv6 on FreeBSD applies mask constructed from the bits argument to the result, so with bits==0 it always returned "::/0" 2008-12-04 Vadim Kurland * ProjectPanel.cpp (ProjectPanel::closeEvent): (fixed bug (no #): need to check if object in the object editor panel has been modified and needs to be saved when user closes internal window using "close" button in its title bar. * FWWindow.cpp (FWWindow::closeEvent): fixed bug (no #): GUI crashed if user closed internal window so no object files were left open, then closed application using "close" button in the main window title bar. 2008-12-03 Vadim Kurland * iosacl.g (certificate): fixed bug #2334007: "Problem parsing Cisco config". Parser now recognizes IOS configuration lines "certificate", "ip community-list", "controller ... description". These lines are recognized and ignored, they should not stop parser from processing the rest of the configuration. * ipt.cpp (main): fixed bug #2378672: "fwb 3.0.2 build 676 iptables script is not executable". Generated .fw file should have executable permissions. 2008-12-02 Vadim Kurland * FWObjectDatabase_tree_ops.cpp (recursivelyCopySubtree): (change in libfwbuilder) fixed bug #2375327: "Crash copying multiple groups between different data files". Using better algorithm to copy objects between different data files. * ObjectManipulator.cpp (ObjectManipulator::duplicateWithDependencies): using FWObjectDatabase::recusrivelyCopySubtree() to copy objects if they are located in different data files. * FWObjectDatabase_tree_ops.cpp (_recursivelyCopySubtree): (change in libfwbuilder) Implemented additional check for object duplicates while copying objects. The problem happened when several object were copied in a batch operation (e.g. when user selected several objects in the GUI and then used copy/paste to copy them all). If some of these objects were groups that referred to other objects from the same batch, the program would copy the object and then create another copy of it when it copied the group using it. To avoid such multiplication it now creates special hidden attribute in the object when it makes a copy to keep track of the original object. When the same original object needs to be copied again, the program can find its copy in the target data tree using this attribute. This creates another problem because the attribute used to track original object is persistent for the duration of the program run. The scenario that leads to this is as follows: user copies object A, modifies it and then copies group B using the orignal of A. The end result is that the program does not recognize that the copy of A has changed and makes copy of group B use it anyway. This means the new group points at modified object A. This can not be easily fixed because we do not have "last_modified" attribute in each object. 2008-12-01 vadim * Started v3.0.3 * v3.0.2 released, merged -r565:676 to trunk. This changelog record is in rev 678 2008-11-28 vadim * FWWindow.cpp (FWWindow::prepareFileMenu): fixed bug #2353052 "fwbuilder crashes on import without open object file". Fixed in rev 676. * ipt.cpp (dumpScript): fixed bug 2356131 "Iptables-restore option broken for multiple policy sets". If firewall was configured to use iptables-restore to activate policy and if it had two or more policy rule sets, compiler used to put "echo COMMIT" line at the bottom of each ruleset. This was incorrect, iptables-restore expects only one COMMIT line at the end of each table. Fixed in rev 675. 2008-11-28 User Vadim * InetAddr.cpp (InetAddr::toString): (change in libfwbuilder) Our included copy of inet_net_ntop does not add "/netmask" to IPv6 addresses if argument #3 is -1 (bits). However, the same function included in libc on FreeBSD returns EINVAL for bits=-1. It appears the function in libc in FreeBSD is based on the same code as our copy, but has been updated and instead of doing check "if ((bits < -1) || (bits > 128))" probably checks for (bits < 0). Because of this, fwbuilder GUI crashed when user tried to create IPv6 network object on FreeBSD. To fix, will use bits=0 in call to inet_net_ntop in InetAddr::toString and then strip /0 that inet_net_ntop adds to the generated string. Both our copy of inet_net_ntop and the one shipped with FreeBSD add "/0" consistently, so this works on all platforms. 2008-11-26 Vadim Kurland * IPTImporter.cpp (IPTImporter::pushRule): fixed crash in the importer for iptables * iptables.g (m_comment): rudimentary support for iptables module "comment" 2008-11-24 Vadim Kurland * tcpservicedialog_q.ui: fixed bug #2333759: "A really small camp". Fixes in dialog layouts for KDE4 theme Oxygen * Build fixes for FreeBSD. * Added GUI elements for krcmd and ekshell options for ipfilter Thanks to Cy.Schubert@komquats.com for the patch! * Using QT4 stylesheet to improve layout of TCP Service, UDP Service and group object dialogs when program is used with KDE theme Oxygen. 2008-11-23 Vadim Kurland * Help.cpp, StartTipDialog.cpp: the GUI will use English help files for online help (where available) and "start tip" dialog if it is started in the non-enligsh locale and help file for this locale inot available. This is better than to show an empty dialog. 2008-11-22 vadim * StartTipDialog.cpp (StartTipDialog::StartTipDialog): Added "start tip" dialog that shows brief information on the online resources available to the user (web site URL, links to the Firewall Builder FAQ, HOWTOs, Cook Book). Linked pages open in the standard browser. * FWWindow.cpp: added menu item Help/Firewall Builder Help that opens a page with information about online resources for Firewall Builder (the same page that is shown in the "start tip" dialog). * ipf.cpp (main): fixed bug #2328330: "basic_string::erase error in fwb_ipf". Compiler for ipfilter aborted processing with error "basic_string::erase" when compilation was launched from the GUI. 2008-11-21 vadim * Improved Mac OS X bundle: included qt.conf file to make it look only inside the bundle for QT libraries and plugins, this eliminated warnings about QT libraries being loaded from two places if the system where fwbuilder GUI was running had QT installed on it. Now packaging QT accessibility plugin library, this should make the GUI run with acessibility features if accessibility aids are turned on system-wide. 2008-11-20 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printLogPrefix): fixed bug #2318639: "bug in logging (rule number)". Added logging prefix macro %R that gets expanded to the ruleset name. This can be useful in logging prefixes for rules in branch rulesets. 2008-11-19 vadim * printerStream.cpp (printerStream::begin): fixed printing with QT 4.4. QT 4.4 correctly sets physical resolution of the printer and sets its logical resolution to 1200dpi. This caused rulesets to be printed incorrectly on Windows and Mac where we use QT 4.4.1. This fix restores printing on these platforms. * Printing from command line: user can print firewall object and all its rulesets from command line without running the program in interactive GUI mode using command line "fwbuilder -f file -P fw_object -o print_output_file.pdf". Making sure this works on Mac OS X as well where the program should be launched as "fwbuilder3.app/Contents/MacOS/fwbuilder" * RuleSetView.cpp (RuleSetView::updateGroups): fixed printing from command line which was broken some time ago (perhaps in 3.0.1). When user prints firewall policy from command line using "fwbuilder -f file -P fw_object" all rule groups are always printed expanded. 2008-11-18 vadim * prefsdialog_q.ui: better layout of the first page of Preferences dialog to make sure long path to the working directory fits in the input widget. * SSHPIX.cpp (SSHPIX::stateMachine): bugfix: installer for Cisco routers and PIX could not find generated file because variable conffile is now always a full absolute path. This bug was introduced earlier during installer rewrite for v3.0.2. Tested installer for router and PIX using default generated file name, as well as custom generated file name, defined both as absolute and as relative path. Tested batch install of combination of a router and a pix in one batch (the same user account, then same enable password on both) 2008-11-17 Vadim Kurland * ObjectManipulator.cpp (ObjectManipulator::duplicateObject): fix bug #2303486: "Operation of duplicating firewall should switch policy". When firewall object is duplicated, the GUI should automatically open policy of the new object rather than keep policy of the original open. At the same time, reset lastModified, lastCompiled, lastInstalled of the new firewall instead of keeping copies from the original. * instDialog.cpp (instDialog::testFirewall): Check to make sure paths to ssh and scp utilities are properly configured in Preferences before running install. Show aprropriate error dialog to the user if path to ssh or scp is not configured. 2008-11-15 Vadim Kurland * antlr/CharScanner.hpp: applied patch for gcc 4.4 from bug# 2282828 "patch for gcc-4.4" * AddressTable.cpp (AddressTable::AddressTable): (change in libfwbuilder) fixed bug# 2293052 "Saving file with empy AddressTable produces corrupt XML". When new AddressTable object is created, its "filename" attribute is empty. If data file was saved right after such new AddressTable object was created, resultant file could not be loaded back into the program becaise it violated XML DTD. 2008-11-13 Vadim Kurland * IPTImporter.cpp (IPTImporter::pushPolicyRule): policy importer for iptables properly creates TagService objects and places them into action of the rule finds iptables rule with target "-j MARK" * IPTImporter.cpp (IPTImporter::pushPolicyRule): policy importer for iptables correctly imports user-defined chain, configures rule with action "Chain" and establishes association between it and ruleset created for the user-defined chain. Multiple rules with this action can point at the same ruleset. 2008-11-12 Vadim Kurland * IPTImporter.cpp (IPTImporter::finalize): fixed bug (no #): policy importer used to create separate Policy objects for chains INPUT, FORWARD, OUTPUT. * CircularQueue.hpp (OFFSET_MAX_RESIZE): a temporary fix for the problem in ANTLR that causes crash on import of very large config files. This affected import of both iptables and Cisco IOS configurations and depended just on their size. 2008-11-10 vadim * instOptionsDialog.cpp (instOptionsDialog::instOptionsDialog): for bug #2135827: "'Store a copy of fwb file...' very slow" - need to enable option "store copy of data file on the firewall" for the batch install. * RuleSetDialog.cpp (RuleSetDialog::applyChanges): fixed bug #2255591 Adding new ipv6 policy is always type "mangle". When user added new Policy object to the iptables firewall and made and saved any changes in the object editor (switched to "top rule set" or toggled setting "filter+mangle"="mangle only"), the setting of the ruleset would switch to "mangle only" and stick there. There was no way to switch it back to "filter+mangle". This is fixed in build 641. 2008-11-09 * Added updated Japanese translation by Tadashi Jokagi ( elf2000 ) from bug #2214440 * FirewallInstallerUnx.cpp(FirewallInstallerUnx::packInstallJobsList): fixed a bug introduced some time earlier and reported in the bug report #2135827: policy installer would only copy .fwb file to the firewall when "Store data file on the firewall" was activated and skipped actual generated policy file(s) (.fw). This only happened on Windows. 2008-11-01 vadim * fwbuilder/Rule.cpp (PolicyRule::PolicyRule): a bugfix in the PolicyRule class, fixes errors in some operations in policy compilers that were caused by switch to a more efficient way to find rule element objects in rules. 2008-10-30 vadim * Added Japanese translation by Tadashi Jokagi ( elf2000 ) Translation converted from the .po file generated for fwbuilder 2.1.19. Since translation was done for the old version of the product, it is incomplete, however at least menus seem to be translated. * ObjectIconView.cpp (ObjectIconView::event): fixed bug #2209210 "crash in fwbuilder: ObjectIconView.cpp:90:". The GUI crashed if user moved mouse cursor over object icons in a group object editor when tooltips were activated. 2008-10-26 Vadim Kurland * RuleSetView.cpp (RuleSetView::setRuleColor): making sure no rule operations are allowed when rule set or parent firewall object are read-only. This fixes GUI crash that happened when user tried to remove rule from a group in the read-only firewall. 2008-10-25 vadim * ProjectPanel_file_ops.cpp (ProjectPanel::loadFromRCS): more fixes for bug #2194829: use toLocal8Bit() instead of toLatin1() in all calls to libfwbuilder functions that deal with files (FWObjectDatabase::load() etc.), as well as system functions such as unlink(), rename(), access(). Now I can open, save, check out and check in file if it is in directory with non-ascii name and also can use non-ascii characters in RCS checkin log records. * instDialog_compile.cpp (instDialog::prepareArgForCompiler): fixed bug #2194829: "the gui can not locate data file in non-ascii directory". This seems to have happened only on Windows and Mac; if data file was located in the directory with the name with non-ascii characters, the gui generated incorrect command line for the compiler when user tried to compile the data file more than once. 2008-10-23 vadim * PolicyCompiler_ipt.cpp (isChainDescendantOfOutput): more for the bug #2186568 "Again User service - group/negate". Support for groups of user service with negation. Now have a framework to keep track of chain "descendants", so that compiler can tell if some chain can be traced back to INPUT or OUTPUT through the sequence of chains calling each other. 2008-10-22 vadim * various dialogs: fixed bug #2187094: "fwbuilder does not use system colors for text boxes". Some dialogs would not properly pick up KDE theme. This was especially visible if theme used dark background colors and white font, in which case many input fields in dialogs would use white text on white background. * PolicyCompiler_ipt.cpp (separateUserServices::processNext): fixed bug #2186568 "Again User service - group/negate". Compiler for iptables did not support groups and negation of the UserService objects. 2008-10-21 vadim * PolicyCompiler.cpp (PolicyCompiler::checkForShadowing): (change in libfwbuilder) Optimisations in the code that detects rule shadowing. Combined with improvements in classes Rule and RuleElement, this yields speed-up in shadowing detection by a factor of about 5. 2008-10-20 vadim * PolicyCompiler.cpp (PolicyCompiler::checkForShadowing): (change in libfwbuilder) Using internal caching to speed-up shadowing detection. This cuts time of shadowing detection almost in half for large policies with many rules. * dns.cpp (list): (change in libfwbuilder) getHostByName() used to insert duplicate IP addresses into the list of the results. Now making sure ip addresses in the result are unique. * Compiler.cpp (Compiler::_expand_addr_recursive): (change in libfwbuilder) change in the algorithm used to decide which interfaces of the host or firewall object to use in a rule when this host or firewall object is found in source or destination. Previously, compiler would skip loopback interface unless user associated the rule with loopback by putting it in the "Interface" rule element. This made it impossible to create rules with address 127.0.0.1 in destination but attached to interface other than loopback (such rule is used for transparent proxy configuration). Now if user explicitly put loopback interface object into rule element, we always keep it. However when compiler expands interfaces from a host or firewall object, it will skip loopback as before, unless the rule is attached to loopback interface. 2008-10-19 vadim * fixed object type icon in the RuleSet and Interface object dialogs. * ProjectPanel.cpp (ProjectPanel::openEditor): fixed bug: object editor panel resized itself erratically when user switched between objects while editor was open. This happened on Windows and Mac OS X. * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): fixed bug #2180556: "broken support for the "old" time module for iptables". Compiler generated incorrect parameters for the "time" module for versions <1.4.0 2008-10-18 vadim * PolicyCompiler_ipt.cpp (singleDstNegation::processNext): while processing single object negation, consider hosts and firewalls with one normal interface and loopback interface eligible (i.e. ignore loopback address even though formally such object has at least two ip addresses). * PolicyCompiler_ipt.cpp (singleDstNegation::processNext): fixed bug (no #): policy compiler for iptables did not handle correctly rules where a host that has multiple addresses was a single object in a rule element and had negation. * NATCompiler_ipt.cpp (singleObjectNegation::processNext): added support for single object negation in OSrc and ODst in NAT rules. This provides for more compact iptables script in the often used case where single object is used with negation in these elements of a NAT rule. Other improvements in handling NAT rules with negation. 2008-10-15 vadim * ipt.cpp (dumpScript): Explicitly use "\n" instead of endl to avoid implicit conversion to "\r\n" on Windows (generated script is for iptables which can only run on Linux, so it is safe to use "\n" instead of endl). 2008-10-13 Vadim Kurland * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::compile): fixed bug (no #): policy compiler for iptables would crash with assertion when AddressTable or DNSName object was used in a rule in pure mangle table ruleset. This could be related to crash reported in bug #2157121. 2008-10-11 Vadim Kurland * PolicyCompiler_ipt.cpp (finalizeChain::processNext): Always placing rules with action "Accept" in table mangle in chain PREROUTING * RuleSetDialog.cpp (RuleSetDialog::loadFWObject): Added attribute to the Policy object for iptables to indicate that this policy ruleset should be compiled into filter and mangle tables or only for the mangle table. This makes sense (and is only shown) for iptables firewalls. By default the attribute is set to "filter+mangle" which means compiler will try to figure out which table each rule should go to. However some combinations of service objects and actions are ambiguous and can be used in both filter and mangle tables. In cases like these, user can help by creating separate Policy ruleset that will be translated only into iptables rules in the mangle table. * PolicyCompiler_ipt.cpp (singleSrvNegation::processNext): fixed bug #2148378: "Negation does not work on Tag Service". Policy compiler for iptables should be able to use "!" single-object negation for TagService obejcts * ObjectTreeView.cpp (ObjectTreeView::updateTreeItems): fixed bug #2149503: ever since attribute "read-only" of FWObject has been converted from a dictionary entry to a member variable, the GUI could not properly check if an object is read-only and could not update context menu and icon in the object tree. This lead to unstable behavior when an object was set read-only because the GUI could not show corresponding icon to indicate its status change, did not switch context menu items and permitted operations that should not have been permitted. * ProjectPanel.cpp (ProjectPanel::getDeleteMenuState): fixed bug #2149585 "Deleting Routing object breaks file". The GUI should not allow the user to delete "Routing" ruleset object, as well as any other top-level ruleset object. This applies to both deleting them via context menu item or Delete key stroke. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::newIptables): fixed bug #2151898: "use of "--icmp-type any" iptables 1.2.6a". Iptables v1.2.6a and older do not have option "-m icmp --icmp-type any". * PrefsDialog.cpp (PrefsDialog::PrefsDialog): Added tab "Data File" to the Preferences dialog; added checkbox "Enable data file compression" to this tab. If this checkbox is turned on, the GUI will compress data file when it is saved to disk. * FWBSettings.cpp (FWBSettings::getCompression): saving data file compression flag in user settings. * ProjectPanel_file_ops.cpp (ProjectPanel::exportLibraryTo): added support for data file compression. This fixes bug# 2130128: "Option to compress the FWB file". * pix.pro, iosacl.pro: should be ../../install.sh rather than ../../install 2008-10-10 User Vadim * FirewallInstallerUnx.cpp: fixed bug #2158561: "Solaris fwb 3.0.2-b599 build prob" Fixed build problems on FreeBSD and Solaris * pix.pro, iosacl.pro: fixed bug #2158407: "iosacl and pix install probs" 2008-10-10 Vadim Kurland * iosacl.cpp (main): fixed bug #2154906 "Post script is missing / Cisco ACL handling". Prolog/epilog sections were not added to the generated script for Cisco IOS ACLs. 2008-10-09 vadim * ipt.cpp (main): Compiler for iptables uses QT functions to properly process non-ascii file names and firewall object names. Compiler correctly creates generated script when its file name contains non-ascii characters on all supported OS. The GUI can find the file and built-in installer can copy it to the firewall and activate it there. QT helps manage encodings and locales in OS-independent manner. Caveats: - Dependency on QT libraries means compilers can not be deployed on the firewall separately from the GUI. - pscp.exe on Windows does not seem to be able to pick up file with non-ascii characters in name when program runs on Windows with standard English locale. Could not test on Windows running with national locale. As a workaround, user can specify alternative name for the generated script in the firewall settings dialog (tab "Compiler"). - Support for non-ascii firewall object and generated script names is currently only available in compiler for iptables * instDialog_compile.cpp (instDialog::prepareArgForCompiler): always provide "-o" command line option to compilers when calling them from the GUI. The output file name defined this way can be encoded properly for the OS encoding and locale (compilers do not use QT so it is hard to do there). 2008-10-08 vadim * merged branch "new-installer" -r569:HEAD * PrefsDialog.cpp (PrefsDialog::accept): Added GUI control for the path to scp utility used by built-in policy installer * All compilers: firewall object can be specified by its ID in addition to by name. Command line option "-i" tells compiler that the last parameter of the command line is object ID. This works reliably when firewall object name contains non-ascii characters and the program runs under locale using 8 bit characters. Built-in installer now uses this method while calling all policy compilers. 2008-10-07 vadim * pf.cpp, ipf.cpp: Policy compilers for pf and ipf use file name and path specified with "-o" command line option for the name and path for all .fw and .conf files they generate. * instDialog.cpp: built-in installer finds all generated files when user specifies alternative name (possibly full path) for the generated script. * FirewallInstaller.cpp (FirewallInstaller::getGeneratedFileFullPath): built-in installer works properly when firewall name contains non-english characters. In this case generated firewall script also has name that contains non-english characters. * FWWindowPrint.cpp, RuleSetView.cpp, FWBSettings.h, ProjectPanel_state_ops.cpp: got rid of references to InterfacePolicy class; build fixes for FreeBSD 7 (should fix compile problems on other systems too, such as Solaris) 2008-10-06 vadim * SSHPIX.cpp (SSHPIX::stateMachine): fixed crash in built-in installer that happened when existing PIX configuration was saved before loading new one. * pixAdvancedDialog.cpp (pixAdvancedDialog::accept): fixed crash that happened when user opened PIX firewall "advanced" settings dialog and then tried to save changes by clicking OK. * FirewallInstaller.h (class FirewallInstaller): all installer logic moved to separate classes FirewallInstaller, FirewallInstallerCisco and FirewallInstallerUnx. These classes launch background process (via SSHSession or QProcess) and control all steps of policy installation and activation, but do not deal with the UI. This provides for good separation of functions between UI and core logic classes. The code is much cleaner and easier to maintain now. 2008-10-05 vadim * instDialog_unx.cpp (instDialog::copyFileOnUnx): Using scp (pscp.exe on windows) to copy files to the firewall. This helps improve performance of the installer. This fixes bug #2135827: "Store a copy of fwb file..." very slow * instDialog.cpp (instDialog::instDialog): refactored installer classes to make code more manageable. * VERSION: started 3.0.2 2008-10-04 Vadim Kurland * v3.0.1 released Oct 4, 2008. Merged branch "v3" r513:565 to trunk * global.h (SETTINGS_PATH_PREFIX): making sure all modules store settings under the same path prefix "3.0/" (applies to all OS). 2008-10-03 Vadim Kurland * GroupObjectDialog.cpp (GroupObjectDialog::iconContextMenu): fixed bug #2144122 "Segfault when trying to add an address to a group" * ProjectPanel_file_ops.cpp (ProjectPanel::chooseNewFileName): fixed bug #2144358 "Double check with 'save as'". The GUI used to ask twice if user wants to overwrite the file in Save As operation if file with given name already existed. * FWWindow.cpp (FWWindow::projectWindowClosed): fixed bug #2144114 "fwbuilder * exits if the last object file is closed". The GUI will not terminate after the last window is closed but instead will just show empty main window. * fwbedit.cpp (main): fixed bug #2143894: "fwbedit list does not show objects". Command "fwbedit list -f file" did not print anything unless option "-F" was supplied. This change adds default value for this option so that when it is missing, the command prints object path. * fwbedit.1: fixed bug #2143961: a typo in the man page fwbedit.1 2008-10-02 Vadim Kurland * instDialog.cpp (instDialog::finishInstall): fixed bug #2125604: "Cancel button does not kill the installer". Cancel button of the installer wizard in fact kills background process. Second issue raised in this bug report is that "Finish" button was always enabled. This is now fixed. * PolicyCompiler_PrintRule.cpp (PrintRule::_printTarget): fixed bug #2141911: "no ULOG for ip6tables". ULOG target has not been implemented for ip6tables yet, so the compiler should fall back to LOG target while compiling ipv6 policy. * RuleSetView.cpp (RuleSetView::updateGeometries): fixed crash that happened on Ubuntu with QT 4.3.x because of recursive call to updateGeometries() * fixed icon for rule action "Mark" 2008-09-30 Vadim Kurland * RuleSetView.cpp (PolicyView::PolicyView): constructors of rule set view classes (PolicyView, NATView, RoutingView) used to set "dirty" flag in the object database which caused the GUI to ask the user if they wanted to save modifications before exisitng the program even when there were no modifications made. This change fixes this annoying problem. 2008-09-29 Vadim Kurland * RuleSetView.cpp (RuleSetView::updateGroups): using setSpan to make row holding rule group head span across all columns. Without this, clicking on table cell in column >1 caused visual artifacts (cell color would turn white, possibly erasing part of the group name). * FindWhereUsedWidget.cpp (FindWhereUsedWidget::showObject): fixed bug #2129726: "Where Used" not working on collapsed groups. * RuleSetView.cpp (RuleSetView::paintEvent): fixed bug related to #2123152 "Fwbuilder 3.0.0 Gui very slow and doesn't refresh properly". There seems to be a bug in QT 4.4.1 (not sure of 4.4.0, definitely not in 4.3.x) which causes the last row of the rule set view table to come out blank when the table is redrawn. This happens when rows have very different height and looks like the last row comes out blank when user scrolls the table up. The last row is finally redrawn when most of it is already visible. 2008-09-26 Vadim Kurland * PolicyCompiler_pf_writers.cpp (PrintRule::_printAF): fixed bug (no #): policy compiler for PF used to insert both "inet" and "inet6" into generated pf.conf lines for the IPv6 policy. * RuleSetView.cpp (RuleSetView::getFullRuleGroupTitle): Added tooltip in the rule set view for the column showing rule group handle, the tooltip shows group name and number of rules. 2008-09-25 Vadim Kurland * FirewallDialog.cpp (FirewallDialog::openFWDialog): fixed bug #2105977: "Viewing firewall settings change state to edited". Opening firewall "advanced" settings dialog triggered internal flag that signalled that something in the object tree has changed. * FWObject.cpp (FWObject::setInt): (change in libfwbuilder) fixed bug #2128261: "fwbuilder thinks the file has changed when opened read-only". Operation "find where used" triggered "dirty" flag on the object tree even though it does not change anything. * NetworkDialog.cpp (NetworkDialog::addressEntered): Network and NetworkIPv6 object dialogs accept CIDR notation in the "address" input field. Netmask input field is filled automatically using "/NN" entered as part of the address when user hits Return or Tab or switches to another input element using mouse click. * ProjectPanel_file_ops.cpp (ProjectPanel::saveIfModified): fixed GUI crash that happened when user made modifications in the default object tree but did not save the changes and then tried to exit the program. * FWBTree.cpp (FWBTree::createNewLibrary): fixed bug #2126524: "User Service created in the Service Group section". * objects_init.xml.in: bug #2126524: "User Service created in the Service Group section" - added missing group UserServices to the standard objects file. 2008-09-24 Vadim Kurland * Network.cpp (Network::Network): (change in libfwbuilder) set netmask to /32 when new Network object is created. This used to be the default in fwbuilder v2.1. New default of 0.0.0.0 appears to be confusing and error-prone, by user's requests changing default back to /32. This fixes bug #2125542: New Address objects added with netmask of "0.0.0.0" * FWObjectPropertiesFactory.cpp (getObjectProperties): do not print netmask of the IPv4 and IPv6 objects in tooltips and "info" panel unless such object is child of an Interface. This fixes bug #2125542: New Address objects added with netmask of "0.0.0.0" * RuleSetView.cpp (RuleSetView::updateGeometries): fixed bug #2124804: "Policy list "jump" when using groups". Combination of rule groups and very tall rows in the rule set view caused problems with vertical scrolling. 2008-09-23 Vadim Kurland * RuleSetView.cpp (RuleSetView::insertRule): fixed bug #2123150: "add new rule below inserts at end of rulebase". The program used to append rule at the bottom of the policy when user tried to insert it n the middle when there were rule groups. * RuleSetView.cpp (RuleSetView::saveCollapsedGroups): fixed bug # 2106266: "Save collapse/expand state of groups in policy". The GUI will remember state of the rule groups (expanded/collapsed) between sessions. The state is saved in preferences. Groups are referenced by combination of file name (full path), firewall object name, ruleset name, group name. Since state is saved in preferences rather than in the data file, state of the rule groups is separate for each user. 2008-09-21 Vadim Kurland * NATCompiler_pix.cpp (mergeNATCmd::processNext): fixed crash in compiler for PIX that happened when compiler tried to merge "global" commands and some of the interfaces of the firewall had dynamic address. * FWObject.cpp (FWObject::fromXML): (change in libfwbuilder) converted attribute "ro" (read-only) from a dictionary variable to the member variable of class FWObject. We check read-only status of objects very often and dictionary lookups were slowing compiler down considerably. * FWObjectDatabase.cpp (FWObjectDatabase::getStringId): (change in libfwbuilder) generate unique string object id on demand instead of in the call to generateUniqeueId. This helps speed up compiler operations by a factor of about 3 because we generate unique int ID every time object is created or copied, yet string ID is only needed when object is stored in external XML file. Also using sprintf to assemble string ID, it works faster than ostringstream. * RoutingCompiler.cpp (reachableAddressInRGtw::processNext): (change in libfwbuilder) fixed crashes in RoutingCompiler that happened because Routing ruleset object being processed is disconnected from the firewall parent at the time compiler works with it. * RoutingCompiler.cpp (rItfChildOfFw::processNext): (change in libfwbuilder) fixed compiler error "Error (iptables): The object "eth0" used as interface in the routing rule 0 (main) is not a child of the firewall the rule belongs to!" that also happened because Routing ruleset object being processed is disconnected from the firewall parent at the time compiler works with it. 2008-09-19 Vadim Kurland * ipfw.cpp (main): Basic suport for IPv6 for ipfw. IPv6 rules should be kept in a separate policy, just like for all other platforms. Branching rules are not supported so there is no support for multiple policies (although there is no check for that at this time either). Both ipv4 and ipv6 rules are loaded into the same ipfw set "1" with globally unique increasing rule numbers. The order in which ipv4 and ipv6 policies are processed is controlled by an option in firewall settings dialog. * FWWindow.cpp (startupLoad): Using list of strings openDocFiles to pass names of the files that should be opened at start up time both when these names come from the command line and from odoc signal handler on Mac. This finally makes the GUI properly open a file given on the command line or via odoc signal (double clicking in Finder on Mac) in a single sub window, replacing default objects tree. 2008-09-16 Vadim Kurland * FWWindow.cpp (FWWindow::fileOpen): when the program is started without data file, it shows panel with just default objects, with a title "Untitled". If user opens data file, it is loaded into the same panel and its title changes accordingly. If user makes changes and then saves using "Save As", its title also changes accordingly (and there is still one panel). If user uses "File/New data file" and enters the name of the new data file, it is loaded into the same panel and its title changes accordingly. Still, after this there is only one panel. However if the panel shows contents of some data file, operations "File/Open" and "File/New" load second data file into a new panel. 2008-09-16 vadim * IPv4.cpp (IPv4::fromXML): (change in libfwbuilder) filter addresses and strip leading and trailing whitespaces and other non-digit characters before converting to InetAddr. This will help with annoying problem where v2.1 allowed such characters in address attributes of Address objects but v3.0 applies strict checks during file load and rejects such data files. 2008-09-15 vadim * ProjectPanel_file_ops.cpp (ProjectPanel::fileOpen): workaround for a problem that only appears on Mac: if user uses File/Open but cancels operation, the main window used to switch from the subwindow that was active to another one (usually the empty default window with only standard objects tree). * FWWindow.cpp (FWWindow::FWWindow): Experiment: since MDI looks very foreign on Mac and can not be fixed, trying tabbed presentation of internal subwindows. Only on Mac OS X. 2008-09-14 vadim * DiscoveryDruid.cpp, debugDialog.cpp, filePropDialog.cpp: enable "close" button in the dialog window title (it was not shown on Mac). 2008-09-14 Vadim Kurland * ProjectPanel_state_ops.cpp (ProjectPanel::loadLastOpenedLib): change in the logic applied when the program decided which library to open at start time. If a file is opened and there is settings record pointing to the library that was opened in this file last time the program was used, this library is opened. If there is no such settings record, the program tries to find the first not system library in the file but prefers the one named "User". If the program starts without data file, it shows library "User" from the standard objects file. * instDialog.cpp (instDialog::addToLog): better regex to recognize compiler erorrs. * TimeDialog.cpp (TimeDialog::loadFWObject): Changed format of the start and stop date fields in the Time Interval object to show year as four digits. Also enabled calendar in these widgets. * bug #2099700 "Association of the .fwb and .fwl file types with app". Implemented support for the association of the application and data file type on Windows. Double-clicking on .fwb and .fwl files in Explorer will now open application and load files automatically. 2008-09-13 Vadim Kurland * GroupObjectDialog.cpp (GroupObjectDialog::listContextMenu): fixed bug #2109833: "Crash on right mouse click in the object group". * FWWindow.cpp (FWWindow::prepareWindowsMenu): fixed bug #2109675: "file Title bar contains redundant info". Internal page title should be coordinated with items in the Windows main menu. There is also no need to add "Firewall Builder" to the title of internal windows. * instDialog.cpp (instDialog::interpretLogLine): fixed bug #2109660: "Compiler Progress: bar is incomplete". Compiler progress bar failed to show full length bar when operation was complete for some firewall platforms. * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed bug #2109431: "context menu item "Where used" is missing for rulesets". * RuleSetView.cpp (RuleSetView::selectRE): fixed bug # 2109432: "double click on results in "Where used" list opens wrong rule." * objects_init.xml.in: fix for bug #2099631: there used to be object "icmpv6 unreachables" in the Deleted Objects library in the file of standard objects that comes with the package. * FindWhereUsedWidget.cpp (FindWhereUsedWidget::showObject): fixed bug #2090332: "Where used search function does not always work.". WhereUsed function could not find firewall if it was used in its own rules. * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): fixed bug (no #): compiler for iptables used date entered for the beginning of the interval in "Time" object both for the beginning and for the end. 2008-09-12 Vadim Kurland * GroupObjectDialog.cpp (GroupObjectDialog::applyChanges): fixed bug #2107004: "Fwbuilder crashes while deleting objects in groups". I could only reproduce the crash when there were two identical objects in the group and I was trying to delete both. v3.0 does not allow the user to add the same object twice to the group so this condition should not be possible. 2008-09-11 Vadim Kurland * instDialog.cpp (instDialog::addToLog): working on bug #2105111: "use color for compiler status and errors". Compilation and installation status is color coded in the left panel of compile/install dialog (Error is red, Success is green). Also coloring compiler error messages red in the compiler progress panel. * RuleSetView.cpp (RuleSetView::updateGroups): fixed bug #2106124: "Crash after deletion of (last rule in + whole) rule group". * RuleSetView.cpp (RuleSetView::paintCell): working on bug #2106280: "option to change color of rule group head". Made rule group head colored in "medium dark", actual color depends on chosen QT theme. * RuleSetView.cpp (RuleTableModel::headerData): fixed bug #2106229 "Disable-Icon bad position in rule group". Icon that indicates that a rule is disabled used to be drawn in the wrong row of the ruleset table. * ProjectPanel_state_ops.cpp (ProjectPanel::loadLastOpenedLib): more for bug #2091225: "Can objects in the left pane remember last state.". If there is no record of the last library used by he user in the settings, the GUI opens library "User" or the first non-system library if there is non named "User". Minor bug-fix to prevent desynchronization of the tree view and pull-down list of libraries. 2008-09-10 Vadim Kurland * RuleSetView.cpp (RuleSetView::pasteRuleAbove): More checks for operations with rules and ruleset on the deleted Policy or NAT object. User should not be able to change anything in rule set object that has been deleted because it does not have parent firewall object. * FWWindow.cpp (FWWindow::prepareEditMenu): more fixes for bug #2100415: "cannot re-create or clone Routing object". Properly synchronizing main menu Edit to make sure user can not delete Ruleset objects. * instDialog.cpp (instDialog::initiateCopy): fixed bug (no #): if the name of the plink.exe program was specified in upper case in Preferences dialog, built-in installer failed to provide correct command line options to it. * ObjectManipulator.cpp (ObjectManipulator::getMenuState): fixed bug #2100415: "cannot re-create or clone Routing object". The GUI does not let the user to delete Routing object. Policy and NAT objects can be deleted as long as there is at least one more left. Also "top" rule set objects can not be deleted at all. * ObjectManipulator.cpp (ObjectManipulator::pasteTo): fixed bug (no #): added ability to copy/paste rule set objects. 2008-09-09 Vadim Kurland * FWBSettings.cpp (FWBSettings::setExpandedObjectIds): bug #2091225: "Can objects in the left pane remember last state.". The program saves state of the object tree branches (expanded or collapsed) between sessions. * FWBSettings.cpp (FWBSettings::getVisibleRuleSetId): bug #2099631 "GUI should rememver firewall object that was opened last". The program remembers opened ruleset between sessions. 2008-09-08 Vadim Kurland * fwbedit.cpp (usage): fixed "usage" in fwbedit, command line option that specifies object attributes for the command "new" is "-a", not "-o". Also fixed this in the man page. 2008-09-08 vadim * main.cpp (odocHandler): bug #2099700 "Association of the .fwb and .fwl file types with app on Mac". Implemented support for the association of the application and data file type on Mac OS X. Double-clicking on .fwb and .fwl files in Finder will now open application and load files automatically. User can open several files by selecting them in Finder and double-clicking. * main.cpp (main): remove "safe mode" command line flag -s because on Mac OS X the program is started with flag -psn when it is launched via finder. This caused undesired effects. 2008-09-06 Vadim Kurland * FWWindow.cpp (FWWindow::projectWindowClosed): fixed bug #2091520: "Crash FWB". The GUI crashed if user closed mdi window showing just standard objects and then tried to close the main window. * FWWindow.cpp (FWWindow::fileNew): fixed bug #2091507: "Create New Firewall problem.". If user created new data file using File/New main menu item, items in the main menu File used to stay disabled and file could only be saved using "File/Save As" (which did not make sense because the name has already been assigned to the file during File/New operation). * ProjectPanel_file_ops.cpp (ProjectPanel::fileSaveAs): bugfix: if user called "Save As" and then hit Cancel in the dialog where they choose file name, internal RCS object used to be deleted anyway. * v3.0.1 started * v3.0.0 released Sep 1, 2008. Merged branch "v3" r512 to trunk 2008-09-01 Vadim Kurland * res.pro: Do not try to install icons if variable ICONSDIR was not defined by configure. This is the case on FreeBSD, I do not know where application icons should be installed there. * ActionsDialog.cpp: more fixes for compile problems on FreeBSD 2008-08-31 Vadim Kurland * ObjectTreeViewItem.cpp: more fixes for compile problems on FreeBSD 2008-08-30 Vadim Kurland * PrefsDialog.cpp: more fixes for compile problems on FreeBSD * instDialog.cpp (instDialog::fillCompileSelectList): fixed a bug: firewall table in the compile/install dialog did not show "last compiled", "last modified", "last installed" time stamps on windows and mac. * RuleSetDialog.cpp: fixing compile problems on FreeBSD 7.0 * instDialog.cpp (instDialog::fillCompileSelectList): resize rows in the table that lists all firewalls for compile/install to make rows minimal required height. * FWWindow.cpp (FWWindow::FWWindow): fixed GUI crash that happened when user clicked toolbar button "Install" right after gui start before any data file was opened. * instDialog.cpp (instDialog::fillCompileSelectList): disabled font manipulations in install/compile dialog, it did not work right on windows * InterfaceDialog: layout adjustment for bug #2078671: "fwbuilder 3.0.0 build 487 - add/edit interface". Layout did not work quite right with QT4 themes Plastique and Oxygen with default font size 14. 2008-08-29 Vadim Kurland * ObjectEditor.cpp: more missing #include for FreeBSD * ObjectManipulator.cpp: Added missing #include for FreeBSD 7.0 port * making sure dialogs do not enforce font type and size if not necessary. Main window and install dialog used to override system font which led to problems with dialog layouts on some systems. 2008-08-27 Vadim Kurland * configure.in: Applied patch per bug #2079941: "Patch for configure.in --with-qmake". Patch adds option --with-qmake to configure in libfwbuilder and fwbuilder. * iosaclAdvancedDialog.cpp (toggleGenerateLogging): fixed bug #2078107: "IOS ACL compiler issue". Logging commands for IOS ACL were not generated properly (settings made in the GUI were ignored). Also added checkbox to completely enable or suppress generation of logging commands, this checkbox is off by default. This provides for better backwards compatibility for existing routers. * various object type dialogs: layout changes for bug #2078671: "fwbuilder 3.0.0 build 487 - add/edit interface". Dialogs did not look right under QT theme with large fonts. 2008-08-26 Vadim Kurland * instDialog.cpp (instDialog::addToLog): fixed bug (no #): compile and install progress window was stuck showing the topmost part of the output of the compiler or installer. Need to make the window automatically scroll and follow the output so that the latest output lines are always visible. 2008-08-24 Vadim Kurland * HttpGet.cpp (HttpGet::httpDone): reset last_error when new http operation begins to make sure we do not accumulate error messages on top of those from previous http ops. 2008-08-23 Vadim Kurland * PrefsDialog.cpp (PrefsDialog::checkSwUpdates): Added setting for http proxy used with automatic checks for the new version of the program. Proxy can be defined by "host:port" pair; if port is not specified, port 80 is assumed. * FWObject.cpp (FWObject::toXML): (change in libfwbuilder) moved saving of XML attributes name and comment from FWObject::toXML() to implementations of this virtual method in all classes that are supposed to have name and comment. When user created an object with empty name, the old code used to save such object into XML file w/o attribute "name" which violated DTD. This is fixed now. 2008-08-22 Vadim Kurland * RuleSetView.cpp (RuleSetView::keyPressEvent): fixed bug (no #): while navigating between rule elements using keyboard, it was not possible to reach the very last rule if ruleset contained rule groups * RuleSetView.cpp (RuleSetView::paintCell): do not draw green frame around rule group; draw black bracket line in the column #0 longer, almost to the bottom of the last rule row. Draw rule group head row grey to make it visually stand out. * ipt.cpp (main): additional fix for the bug #2051629 "group with dns names are handled as empty": Compiler should check if any rules of given address family exists before running preprocessor. This is to prevent it from trying to resolve DNSName objects for IPv6 when there are no ipv6 rules. 2008-08-21 Vadim Kurland * ProjectPanel_file_ops.cpp (ProjectPanel::load): truncating very long error messages that happen when GUI tries to load broken .fwb file. These error messages contain complete output of the XML parser which can be very long and does not fit in the normal error dialog. Message will be cut off at 1000 characters, which is enough to see the topmost part of the parser output. 2008-08-20 vadim * ObjectTreeView.cpp (ObjectTreeView::ObjectTreeView): Fixed GUI crash on Ubuntu Hardy that happened b/c of a bug in QT 4.3.4. Crash happened when user added second object to any branch of the tree. When second object was added to the tree, the program terminated with assertion "ASSERT: "left.level > right.level" in file itemviews/qtreeview.cpp". This did not happen with QT 4.4.1 and 4.3.2 (could not test with 4.3.5). The fix was to disable sorting in the QTreeView widget used to represent object tree. 2008-08-19 Vadim Kurland * NATCompiler_PrintRule.cpp (PrintRule::_printSrcService): fixed bug (no #): policy compielr for iptables used multiport module option "--destination-port" instead of "--dports" when version was set to 1.4.0. Option "--destination-port" is only for very old versions of iptables (<1.2.6). This change makes compiler properly compare version numbers rather than compare them as strings. * RuleSetView.cpp (RuleSetView::pasteRuleAbove): Permit copy/paste of individual rules between two data files. When a rule is copied this way, all objects used in this rule are copied as well. * FWWindow.cpp (FWWindow::recreateWindowsMenu): fixed typo in the main menu item name 2008-08-18 Vadim Kurland * Compiler.cpp (Compiler::complexMatch): (change in libfwbuilder) fixed bug (no #): policy compiler for iptables used chain OUTPUT instead of FORWARD if NetworkIPv6 was used in "source". 2008-08-17 Vadim Kurland * ipt.cpp (main): fixed bug #2054755: "Duplicate Chain". Compiler for iptables used to generate duplicate "iptables -N chain" commands for the same chain in some cases. * Preprocessor_pf.cpp (Preprocessor_pf::convertObject): fixed bug #2056510 "Compile time" address tables objects dont work. Preprocessor in compiler for PF for some reason used to convert all compile time AddressTable objects to run-time. There was no mention of this in changelog and no comment in the module. * RuleSetView.cpp (RuleSetView::copySelectedObject): fixed bug #2055984: "Negate Objects not work". the problem really was not related to negated objects, instead, user could not copy an object from rule element into clipboard more than once. Copying whole rule into clipboard worked fine, but individual object inside the rule could be placed in clipboard only one time. 2008-08-15 Vadim Kurland * Preprocessor.cpp (Preprocessor::isUsedByThisFirewall): fixed bug #2051629: "group with dns names are handled as empty". This bug triggered when object group that consisted of DNSName objects set to resolve at compile time was used in policy rule and at the same none of these DNSName objects were used in rules. If an object from the group was itself used in a rule, compiler properly converted it to address. But object was never used in rules by itself, it was not converted. 2008-08-14 Vadim Kurland * SSHUnx.cpp (SSHUnx::SSHUnx): fixed bug #2051005: "install to localhost fails with pam_thinkfinger". Built-in installer recognizes password prompt produced by pam_thinkfinger module that accepts both password or asks user to swipe finger against fingerprint reader device. Note that installer is likely to not work with fingerprint authentication because it will not wait once it gets to the point where pam_thinkfinger module asks for the password or fingerprint and will try to enter password. However with this change password prompt from pam_thinkfiger is recognized and password authentication becomes possible. 2008-08-13 Vadim Kurland * NATCompiler_ipt.cpp (NATCompiler_ipt::getInterfaceVarName): fixed bug 2047082: "Beta 3.0 Build 456: IPv4 & IPv6 mixed firewall". Compiler used ipv4 address of a dynamic interface in the ipv6 policy rules if interface address was determined dynamically at run time. This change makes compiler properly determine ipv4 address for ipv4 rules and ipv6 address for ipv6 rules. 2008-08-12 Vadim Kurland * ObjectListViewItem.cpp (ObjectListViewItem::operator<): (and several other places): code fixes to address warnings issued by gcc 4.3 * Helper.cpp (Helper::findInterfaceByNetzone): fixed bug in policy compiler for pix - it could not properly identify interface with network zone "any" * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed bug #2047992: "segfault cloning policies in version 3". "Duplicate" and "Move" context menu items should not be presented if an object for which context menu is called is policy or interface. * Rule.cpp (PolicyRule::removeRef): (change in libfwbuilder) fixed bug #2047991 "Drag & Drop in CHAIN actions, version 3". THe bug report consits of 3 parts, part 3 is "When I change the Action from CHAIN to ACCEPT and switch it back to CHAIN it still shows the last policy target I used. EVEN WHEN I DELETED this object meanwhile. I manually have to remove the policy object from the properties of the CHAIN action.". PolicyRule::removeRef removes references to RuleSets and TagSErvice objects from rule options when corresponding RuleSet or TagService object is deleted. 2008-08-11 Vadim Kurland * ObjectTreeView.cpp (ObjectTreeView::edit): double-clicking on an object in the tree opens it in the editor panel. Normally, QTreeWidget also expands or collapses tree branch on double click if the object has children. This was confusing. This change makes tree not expand and collapse branches on double click. * RoutingCompiler_ipt_writers.cpp (PrintRule::processNext): Applied a one-line patch from to fix problem in the generated iptables script where it would delete default route if routing rules were used. 2008-08-10 Vadim Kurland * FWWindow.cpp (FWWindow::checkForUpgrade): the GUI checks if updated version is available on startup by making simple HTTP GET request to the web site at http://www.fwbuilder.org. This can be turned off in the Preferences dialog. Preferences dialog also provides a button to perform this query at any time. If function is enabled in Preferences, it is performed at every time the GUI is launched. The query does not transmit any data to the server, but the URL of the query includes the version of the Firewall Builder. 2008-08-06 Vadim Kurland * new_object.cpp (newObject): fixed bug # 1997469: "Create a new User library via fwbedit". Fwbedit creates new library and populates it with correct set of standard folders. 2008-08-05 Vadim Kurland * pfAdvancedDialog_en_US.html: Help page for the advanced settings dialog for PF firewall 2008-08-04 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printActionOnReject): fixed bug #2037806: "Beta 3.0 Build 437: IPTABLES IPv6 policy ICMP reject action". Ip6tables target REJECT accepts different arguments for the --reject-with. * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug #2037809: "Beta 3.0 Build 437: IP6TABLES_RESTORE missing". Added missing variable declaration for IP6TABLES_RESTORE to the generated iptables script 2008-08-03 Vadim Kurland * ProjectPanel_file_ops.cpp: bug #2037314: "b449 does not build". More missing #include for gcc 4.3 * newhostdialog_q.ui: fixed bug # 2036963 "Add new Host Object on MacOSX". The "new host" dialog was too big and did not fit on low resolution screen * res.pro: Now installing fwbuilder.desktop file on Linux and application icons under $DATADIR/icons/hicolor/ (sizes 128x128 16x16 24x24 256x256 32x32 48x48 512x512 72x72) * bug #2036912 "fwbuilder b442 does not build". Added missing forward declarations and #include for gcc 4.3 * Applied patch for gcc 4.3 per bug #2036881 "gcc 4.3 patch for b442", Mandriva Cooker patch http://svn.mandriva.com/cgi-bin/viewvc.cgi/packages/cooker/fwbuilder/current/SOURCES/fwbuilder-3.0.0-gcc4.3.patch 2008-08-02 Vadim Kurland * iptAdvancedDialog_en_US.html: Added help file for the firewall settings dialog for iptables firewalls * Help.cpp (Help::Help): generic built-in help framework. Help files are created in .html format in src/res/help directory. Help files can be localized, locale name is part of the file name; we need to create separate file for each supported language. First dialog to get associated help panel that can be activated by clicking "Help" button is Linux 2.4/2.6 firewall host settings dialog. 2008-08-01 Vadim Kurland * ipt.pro: Eliminated dependency on QT in all policy compilers. Compiler binaries can be deployed on machines without QT and X11. * ObjectManipulator.cpp (ObjectManipulator::contextMenuRequested): fixed bug #2023243: "IPv6 - Some objects missing from context menus". Added items "New Address IPv6" and "New Network IPv6" to context menus associated with folders "Addresses" and "Networks" in the tree. 2008-08-01 Vadim Kurland * Fixed build on Mac, starting with rev 433 code is built with QT 4.4.1 and works on both Leopard and Tiger. * list_object.cpp (getAttributeValue): added command "list" to fwbedit. This command can print contents of one object, an object and all objects below it in the tree or contents of a group. Object's attributes can be arranged in the output according to the provided format string where attributes are represented by macros of the format "%attr_name%" where attr_name is the name of the attribute. * fwbedit.1: Man page fwbedit.1 has been updated with the list of commands, options, supported attributes and examples. * with addition of the "list" command to fwbedit, utility fwblookup has been deprecated and removed from the package and source code tree. 2008-07-31 Vadim Kurland * fwbedit.cpp (usage): Redesigned command line interface for fwbedit. The first command line argument is a command (one of "new", "delete", "modify", "list", "add", "remove", "upgrade" or "checktree") followed by options. Now fwbedit can be used not only to add or remove objects, but also to modify object attributes. The CLI is lot more consistent and can be extended with new commands in the future. 2008-07-30 Vadim Kurland * fwbedit.cpp: fixes for the bug #2030331: fwbedit/fwblookup issues: added option "-c" for fwbedit, with this option user can specify comment for the object being created; fixed both fwblookup and fwbedit to properly handle objects with duplicate names when operations are performed on objects specified by their path in the tree. Now, if several objects have the same name, operation will be performed on all such objects. Note that this includes deletion, that is, command "fwbedit -f file.fwb -l /User/Objects/Addresses/TestAddress" deletes all objects with name "TestAddress" if there are several. Added ability to create IPv6 and NetworkIPv6 objects in fwbedit. New command line option "-c text" can be used to set comment for the object created via "-t type -n name". 2008-07-30 vadim * fwbedit.cpp (main): fixed bug #1997475: "Adding Interface via fwbedit breaks .fwb file" 2008-07-28 * ObjectManipulator.cpp (ObjectManipulator::removeLib): fixed crash that happened upon exit on some platforms. Need to break away from the loop after lists were modified because iterators become undefined. 2008-07-28 Vadim Kurland * New application icon 2008-07-27 Vadim Kurland * ObjectManipulator.h (class ObjectManipulator): removed strange methods copyObjWithDeep and copyObj2Tree. Fixed drag&drop between different data files. Copy/Paste and D&D between different data files properly copy all dependencies and fix references in rules and groups. Tested with recursive groups (group references itself) and firewalls with rules referencing other firewalls with groups and other objects. * ObjectManipulator.cpp (ObjectManipulator::duplicateWithDependencies): duplicate object that references other objects and create copies of these other objects. Examples: firewall (rules reference other object) and groups. This method is used in "Paste" operation. Will use it for d&d as well. 2008-07-26 Vadim Kurland * ObjectManipulator.cpp (ObjectManipulator::moveObj): code refactoring and cleaning up. Movig all loops over mdi child windows from ObjectManipulator class to the FWWindow class that owns all children windows. Along the way fixed few bugs, such as restored functions "Duplicate to .. " and "Move to ..." that are available via context menu associated with an object in the tree. * ProjectPanel_file_ops.cpp (ProjectPanel::saveIfModified): refactored class ProjectPanel to keep code more organized in several modules. 2008-07-25 Vadim Kurland * FWWindow.cpp (FWWindow::closeEvent): properly checking for unsaved modifications when user hits File/Exit or tries to close main window. * ProjectPanel.cpp (ProjectPanel::fileCommit): fixed bug (no #): crash while doing File/Commit. * PolicyCompiler_ipt.cpp (checkForMatchingBroadcastAndMulticast): fixed bug (no #): crash in fwb_ipt when interface object is used in destination and chain is INPUT. * init.cpp: removed #include , trying to fix bug #2027918: "Cannot compile fwbuilder-3.0.0-b413 on x86_64" 2008-07-24 Vadim Kurland * RCS.cpp (RCS::RCS): If data file has been added to RCS, show its revision history properly sorted by the revision number in ascending order and automatically select the latest revision in the dialog 2008-07-24 vadim * init.cpp (guessExecPath): properly managing path to the bundle on Mac. 2008-07-22 Vadim Kurland * FWWindow.cpp: Applied patch to make code compile with gcc 4.3 per http://svn.mandriva.com/cgi-bin/viewvc.cgi/packages/cooker/fwbuilder/current/SOURCES/fwbuilder-3.0.0-gcc43.patch 2008-07-21 Vadim Kurland * ProjectPanel.h (libfwbuilder): Added missing declarations for gcc 4.3 per bug #2023292: "fwbuilder 3.0.0 does not build" * (libfwbuilder) Applied patch for gcc 4.3 per bug #2023676: "libfwbuilder does not build against gcc 4.3". * (libfwbuilder) fwbuilder.pro: removed unnecessary override in target.path to make it install in a proper place on 64 bit machines' 2008-07-20 * RuleSetView.cpp (RuleTableModel::insertRow): fixed bug (no #) which caused crash on windows when new rule group was created. This happened only on win32. 2008-07-20 Vadim Kurland * RuleSetView.cpp (RuleSetView::moveRule): fixed bug (no #): if rule set had several rule groups, moving rules within rule set did not work and caused weird effects. * NetworkIPv6.cpp (NetworkIPv6::NetworkIPv6): per bug #2023140: "Default prefix for IPv6 addresses" setting default netmask to /64 for NetworkIPv6 object. * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): fixed bug #2023141: "Can't set interface options". The GUI kept all controls in the interface object editor enabled when interface was child of a Host object, even though some controls do not apply to interfaces of a host. These controls were not saved into interface objects and the whoile behavior of the GUI was rather confusing. Now only proper controls are enabled when interface is a child of a host object. * RuleSetView.cpp (RuleSetView::removeRule): Fixed bug (no #): "remove rule" function used to remove wrong rule in the rule set if rule groups were used. 2008-07-18 * instDialog.cpp (instDialog::installerSuccess): bugfixes in the built-in installer on Windows in case of successfull and unsuccessfull termination of the process. Tests for when plink.exe asks whether user wants to accept new ssh host key from the firewall. 2008-07-18 Vadim Kurland * NATCompiler_PrintRule.cpp (PrintRule::_printAddr): fixed bugs in compiler for iptables where it sometimes would not print netmasks in ipv6 network objects in policy and nat rules. * Added control for IPv6 forwarding setting in "host settings" dialogs for Linux, OpenBSD and FreeBSD. This is in addition to the old ip forwarding control. Corresponding policy compilers add proper commands to generated scripts to turn ipv6 forwarding on or off in the kernel. * ipt.cpp (main): compiler for iptables puts build number in addition to the version number into "Generated with ..." comment in the produced script * instDialog.cpp (instDialog::installerError): fixed crash in the installer that happened when policy activation ended with an error * ipt.cpp (main): fixed bug (no #): if generated script used iptables-restore and if there were automatically generated rules in the magle table, for example for the "clamp MSS to MTU" rule, but no other rules in the mangle table, compiler would not add COMMIT. 2008-07-17 Vadim Kurland * PolicyCompiler_ipt.cpp (prepareForMultiport::processNext): fixed bug (no #) where compiler for iptables ignored ICMP6 Service objects used in the same rule in combination with tcp or udp service objects. * objects_init.xml.in: Added few more ICMPv6 objects to the Standard objects library: type name comment 133 routersol Router solicitation 134 routeradv Router advertisement 135 neighbrsol Neighbor solicitation 136 neighbradv Neighbor advertisement 137 redir Shorter route exists * ObjectManipulator.cpp (ObjectManipulator::delObj): fixed bug (no #): GUI crashed when user deleted one of the rule set objects of a firewall. * many dialogs: adjusted shape and size of many dialogs that used to be too big. * utils.cpp (getAddrByName): getAddrByName() works on all platforms and gets ipv4 and ipv6 addresses as requested. It looks like for it to work on Windows Vista machine needs to be configured with routable ipv6 addresses. When machine only had Link-local address on fe80:: net, even when ipv6 was enabled, getaddrinfo sent proper dns request for AAAA record, got reply but did not pass it back to the application. Once machine was configured with routable ipv6 address, getaddrinfo started working as expected. This problem was not observed on Linux and Mac OS X. * IPv6Dialog.cpp (IPv6Dialog::DNSlookup): Added "DNS Looup" button to the IPv6 object dialog. * dns.cpp (list): (libfwbuilder) Using getaddrinfo on all OS to perform dns lookup for different address families (AF_INET or AF_INET6). * utils.cpp (getAddrByName): using DNS::getHostByName instead of QT functions to perform host name lookup. This should allow us to do it for both AF_INET and AF_INET6 address families. Needs more testing. 2008-07-16 Vadim Kurland * ipt.cpp (dumpScript): Fixed bug (no #) that triggered when iptables script was geenrated with option that uses iptables-restore for activation. If ipv6 policy was empty, compiler added "( ) | ip6tables-restore" anyway which caused syntax errors. * RuleSetView.cpp (RuleSetView::addToGroupAbove): Additional check for a bug where adding very long list of rules to a rule group caused crash once. Bug is hard to reproduce. 2008-07-15 vadim * testing and bug fixes with QT 4.4. * Testing on Mac OS X and Windows Vista. 2008-07-08 vadim * fwcompiler.pro (LIBS): fixed build errors on Ubuntu Hardy. Background info: need to include -lfwbuilder while linking fwcompiler library on all Unix platforms because of the linker option -Wl,-Bsymbolic-functions . Discovered this on Ubuntu Hardy where libsnmp adds this option via net-snmp-config --libs 2008-07-07 Vadim Kurland * listOfLibraries.cpp (listOfLibraries::listOfLibraries): Removed support for add-on libraries in the GUI. User can now open their working file and external library file simultaneously and copy objects from one to another. This removes the need for the cumbersome add-on libraries feature. Will keep module listOfLibraries and corresponding code fragments in ProjectPanel and FWWindow until removal of this feature is validated by users. * PolicyCompiler_pf_writers.cpp: Support for "synproxy state" option for PF per FR #1098098: "Per-rule Synproxy" * templates.xml.in: Updated template firewall objects to include "top_rule_set" attribute. * RuleSetDialog.cpp (RuleSetDialog::loadFWObject): Added attribute "top_rule_set" to Policy, NAT and Routing objects. This attribute is controlled by a checkbox "Top rule set" in the corresponding object dialog. The attribute has platform-specific meanning. On iptables, "top" rule set goes into the built-in chains INPUT, OUTPUT, FORWARD; if this flag is unchecked, rules go into user-defined chain with the name the same as the name of the rule set. On PF, If this flag is unchecked, rules go into anchor with the name the same as the name of the rule set. On Ciscio IOS ACL If this flag is unchecked, generated access list will not be assigned to interfaces with "ip access-group" command and also the name of the ACL will be prefixed with the name of the rule set to make it unique. One policy, nat and routing rule set must be marked as "top". Other rule sets are secondary and will be placed in their own unique chains, anchors or access lists (depending on the platform). Control may or may not be passed to these chains and anchors. One way to pass control is by using rule action "Branch" in the top rule set. However if control is not passed that way, compiler will still generate corresponding commands which can be used by means external to the firewall builder. Auto-upgrade migration script will assign attribute "top_rule_set" to Policy objects with name "Policy", NAT objects with name "NAT" and Routing objects with name "Routing". This provides for consistent backwards-compatible behaviour after upgrade from v2.1 2008-07-06 Vadim Kurland * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printAddr): Support for IPv6 in Cisco IOS ACL compiler fwb_iosacl. * iptAdvancedDialog.cpp (iptAdvancedDialog::iptAdvancedDialog): Removed option "Enable IPv6 support" in the "advanced" dialog for all platforms. Now user needs to explicitly declare rule sets as ipv6. Since by default all rule sets are ipv4, there is no need in yet another parameter to enable ipv6 support. * RuleSetDialog.cpp (RuleSetDialog::applyChanges): Objects Policy, NAT and Routing now have attribute that tells compiler that corresponding rule set is ipv4 or ipv6. The attribute is controlled by radio-buttons in corresponding object dialog. Every policy or nat rule set is treated as exclusively either ipv4 or ipv6 by compilers, however the user can put objects of both address families in rules. This allows for creation of object groups that include objects of both address families. Such groups can be used in both ipv4 and ipv6 rule sets. Compilers pick objects that match address family declared for the rule set and drop others. One of the reasons why this attribute was added is to avoid generation of unwanted iptables or acl lines for rules that can not be unambiguously attributed to particular address family. Example of such rule is rule with "any" in both source and destination (e.g. "catch all and deny" rule typically found at the bottom of the policy). Without this attribute compilers tried to process every rule set for both ipv4 and ipv6. This way rule "any any any deny" found in ipv4 policy yielded corresponding line in the ipv6 policy, which was wrong. * instDialog.cpp (instDialog::installSelected): minor fixed in installer dialog (fixed progress bar and buffering of the compiler output) 2008-07-05 Vadim Kurland * PolicyCompiler_iosacl_writers.cpp (PrintRule::_printTOS): Support for TOS and DSCP matching in IOS access lists. * PolicyCompiler_pf_writers.cpp (PrintRule::_printDstService): Support for tos matching in compiler for pf. PF does not support DSCP matching. * PolicyCompiler_PrintRule.cpp (PrintRule::_printIP): Support for TOS and DSCP matching in compiler for iptables. * IPServiceDialog.cpp (IPServiceDialog::loadFWObject): Added support for attriutes "tos" and "dscp" in IPService object. FR #1948944: "support for TOS matching". * PolicyCompiler_PrintRule.cpp (PrintRule::_printModules): Implemented support for combinations of srcip, dstip, srcport, dstport options of the hashlimit module for iptables per bug #1812388: "add srcip,dstip to choices for hashlimit mode" 2008-07-03 Vadim Kurland * fwbuilder.1: updated man page for fwbuilder GUI. * ipt.cpp (main): document iptables version settings from the firewall object in generated script (for support and debugging). * MangleTableCompiler_ipt.cpp (flushAndSetDefaultPolicy): iptables rule with target TCPMSS generated for option "Clamp MSS to MTU" is valid only in mangle table in iptables 1.3.x and later. Still generate this command in the filter table for earlier versions of iptables * PrefsDialog.cpp (PrefsDialog::getFontDescription): Tab "Fonts" of the Preferences dialog shows currently selected fonts for both the tree and rules. 2008-07-02 Vadim Kurland * instDialog.cpp (instDialog::addToLog): fixes in built-in installer; pretty printing of the external process output; properly enable "next" and "finish" buttons. 2008-07-01 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printProtocol): compiler for iptables distinguishes ICMPService and ICMP6Service * objects_init.xml.in: Added few standard ICMP6 objects * ObjectManipulator.cpp (ObjectManipulator::newICMP6): Added support for ICMP6Service object type in the GUI * ICMP6Service.cpp (ICMP6Service::ICMP6Service): Added class ICMP6Service * fwbuilder.dtd.in: Added XML element ICMP6Service 2008-06-30 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printProtocol): do not generate "-m icmp6 --icmp6-type any" for ipv6 for object "any icmp". 2008-06-28 Vadim Kurland * DiscoveryDruid.cpp (DiscoveryDruid::loadDataFromDNS): object "discovery" by DNS zone transfer is not supported anymore. 2008-06-27 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printProtocol): should use "-p ipv6-icmp" for ipv6 rules. * PolicyCompiler_PrintRule.cpp (PrintRule::_printProtocol): skip "-p all" for ipv6 to avoid warning "Warning: never matched protocol: all. use exension match instead" 2008-06-26 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printIP): using "-m frag --fragmore" for IPService objects that should match ip fragments. * PolicyCompiler_PrintRule.cpp (PrintRule::_printDstService): compiler uses "--icmpv6-type" and "-m icmp6" options while generating ipv6 script. 2008-06-20 * FWWindowPrint.cpp: fixed bug # 1896771: "printing user defined chains". * main.cpp: implemented printing of the firewall object contents from CLI per bug #1996739: "Feature: CLI printing or policy export". Use command line flag "-P " to print and exit. 2008-06-16 * newHostDiaog.cpp: fixed bug #1899488: "Unable to set MAC address while adding a host" 2008-06-13 * GroupObjectDialog.cpp: implemented sorting by name and parameter in group dialogs per bug #646804: "No sort in Group". 2008-06-10 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): support for the "new" time module for iptables 2008-06-08 Vadim Kurland * merged branch "id-experiment" r233:HEAD 2008-06-07 Vadim Kurland * main.cpp (main): support for integer object ids 2008-06-06 Vadim Kurland * PolicyCompiler_pf_writers.cpp (PrintRule::_printUser): Support for UserService in compiler for PF. FR #1948872: "User based rules" * FWBSettings.cpp (FWBSettings::restoreGeometry): the program will remember window size and restore it on subsequent runs, but will not remember window position on the screen. This caused problems on Mac OS X (because window title bar and tool bar weren't taken into account, so window would slide up on every next run) 2008-06-05 Vadim Kurland * PolicyCompiler_ipt.cpp (checkUserServiceInWrongChains::processNext): Support for UserService in compiler for iptables. FR #1948872: "User based rules" * IPv6 suport implemented in the GUI and compilers for iptables and pf: FR #1517015, 1705261, 1706246, 1826325 * Rules with action Tag reference TagService objects. User drags and drops TagService object into a drop area in the rule action dialog. FR #1696841: "Mark action and TagService" 2008-06-05 * IPv4Dialog, NetworkDialog, newHostDialog, newFirewallDialog: netmask can be entered as bit length, in addition to the bit mask format supported before. Both formats are recognized. FR #995452, 1617297, 1666016 2008-06-05 Vadim Kurland * ipt.cpp, pf.cpp: Compilers for iptables and pf recognize branch rule sets that belong to different firewall objects. FR #737132: "Linkable Rules", #1224898 "Rule Link" * PolicyCompiler_ipt.cpp (dropTerminatingTargets::processNext): bugfix in the shadowing detection for non-terminating rules in the mangle table. * All compilers: all compilers include error and warning messages produced during compilation in the generated script. Messages are grouped by corresponding section (Policy, NAT, all branches etc.). Normally only warnings will be included because compilers stop when they encounter an error condition, however if compiler is being ran with "-xt" command line option, it does not stop and includes error messages in the output as well. This helps catch changes that generate warnings but do not translate into differences in generated configuration. 2008-06-02 Vadim Kurland * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): Support for --weekdays parameter in iptables 1.4.0 module "time". Per bugs #1914371: "iptables 1.4.0", #1806045: "latest 1.3.8 time match changed", #853364: "Time Restriction feature request". * platforms.cpp (list): Added iptables version 1.4.0 to the list. Will use it for the "new" time module support. Bugs #1914371: "iptables 1.4.0" and #1806045: "latest 1.3.8 time match changed" 2008-05-30 Vadim Kurland * pf.cpp (main): Like compiler for iptables, compiler for PF now supports multiple rule sets for policy and nat. Each rule set is translated into corresponding anchor .conf file. If some rule in another rule set references it via action Branch, corresponding "anchor" configuration line is generated, but if it is not references from any rule, the anchor .conf file is still created. Rule sets "Policy" and "NAT" are configured "main" or "root" and placed in the main .conf file with the name of the firewall object. 2008-05-29 Vadim Kurland * ipt.cpp (main): Compiler for iptables processes all Policy and NAT rulesets that firewall object has, regardless of whether they are referenced from any rules with action Branch or not. This is a change compared to the behavior of 2.1 which processed only those branch rule sets that were used in Branch rules. Each rule set that has name other than "Policy" is placed in a chain with the name the same as the name of the rule set. This way the user can create multiple rule sets and place them in different chains, control to these chains can be passed in the iptables commands supplied in prolog or epilog scripts. Another reason for this is to allow the user to place rules for ipv4 and ipv6 in separate rule sets. An attribute "address_family" will be added to objects Policy and NAT later on to be able to mark rule sets as belonging to either ipv4 or ipv6 address family. This separation helps avoid ambiguity that is possible in mixed rule sets (when both ipv4 and ipv6 rules are mixed in the same rule set). Suppose we allow the user to put both ipv4 and ipv6 rules in the same rule set and the user creates a rule with ipv4 object in Dst with negation. "Not host A", where "host A" translates into one ipv4 address should probably include "all ipv6" as well, which means that this simple rule can inadvertenly block all ipv6 without user even noticing it. This can be very confusing and difficult to troubleshoot. Placing rules acting on different address families into different rule sets helps avoid this problem. * ipt.cpp: Compiler for iptables can determine if a rule set is referenced by a rule with action Branch and option "branch in mangle table in addition to the filter table" and correctly places referenced rule set in both filter and mangle tables. 2008-05-29 * ObjectManipulator.cpp: new feature v3: Policy rules can now be arranged in multiple rule sets with names. These rule sets are shown in the tree under the firewall object (next to its interfaces). Each rule set is independent from others, user can add as many as they want. Rules with action "Branch" refer to existing rule sets, user associates them by dragging rule set object into action parameters dialog of the branching rule. This also fixes bug #1753297: "duplicate chain tab". 2008-05-23 Vadim Kurland * PolicyCompiler_ipt.cpp (countChainUsage::processNext): New feature: compiler for iptables keeps track of chain usage and removes unused chains from the generated iptables script. This helps optimize generated script and makes it smaller, especially in mixed IPv4/IPv6 configurations. 2008-05-22 Vadim Kurland * ipt.cpp (main): Policy compiler for iptables supports IPv6. Added command line switches "-4" and "-6" which force compiler to generate script for only one specified address family (by default it does both). Compiler can generate simple ipv6 iptables script. Generated script still can be improved but seems to be formally correct at this time. 2008-05-18 Vadim Kurland * OSConfigurator_linux24.cpp: compiler for iptables converted to use exclusively methods getAddressPtr and getNetmaskPtr. Checking for when Address object has no IP address where appropriate (getAddressPtr() returns NULL in this case). 2008-05-10 vadim * pf.cpp: (from 2.1) fixed bug #1961202: "Pf Timeouts overriden by Optimization". Compiler should generate "set optimization" command before "set timeout" commands. 2008-05-08 vadim * FWWindowPrint.cpp (printFirewall): (from 2.1): fixed bug #1562726: "policy print rule cut-off". Long rulesets would not print correctly on Windows, the bottom of the ruleset table was just printed solid grey with no rules visible. * PolicyCompiler.cpp (PolicyCompiler::checkForShadowing): (from 2.1): partial fix for bugs #1789059 "shadow issue when using action chain" and #1945149: "Shadowing test for rules with action "chain". The mechanism for rule shadowing detection we have at this time can only detect shadowing of one rule by another. In case of branching it is a combination of the branching rule and rules inside the branch that may shadow other rules. I plan to redesign this part of the code in the future, but it won't happen in upcoming v3. Meanwhile, I am fixing it in 2.1 by making compiler ignore rules with action Branch. 2008-05-05 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::processNext), RuleOptionsDialog.cpp (RuleOptionsDialog::loadFWObject): (from 2.1) fixed bug #1821573: "Rule options limits allow for multiple overload tables". PF allows only for one "overload" option per rule. * IPTImporter.cpp (IPTImporter::pushPolicyRule), (from 2.1) iptables.g (target_options): fixed bug #1949438: "parser expects decimal - hex is not accepted". Importer for iptables should be able to process "--set-mark" with hex argument. * fwbedit.1: (from 2.1) fixed bug #1949103: "manpage slightly broken". Minor fixes in fwbedit.1 man page. * PolicyCompiler_PrintRule.cpp (PrintRule::_printOptionalGlobalRules): (from 2.1) fixed bug# 1940504: "Clamp MSS to MTU". Iptables command that invokes "-j TCPMSS --clamp-mss-to-pmtu" in FORWARD chain should go before the one that matches "--state ESTABLISHED,RELATED" in order to work for the packets in these states. * RuleOptionsDialog.cpp (RuleOptionsDialog::loadFWObject): (from 2.1) fixed bug #1938985: Rate in hashlimit in local language 2008-04-28 * v3 feature: rules can be grouped in Policy, NAT and Routing. Group of rules can have a name and color and can be collapsed or expanded. Collapsed rule groups take room equivalent to one rule in the ruleset panel. This implements Feature Requests #1961702, 1938992, 1751141, 1602294, 1372620, 1083981, 1017566, 848553, 811542, 2008-04-13 Vadim Kurland * NATCompiler_PrintRule.cpp (PrintRule::_printAddr): fixed bug (no #): compiler fwb_ipt used to treat host objects as networks in TDst and generate iptables output with /netmask of the interface. * (various places in src/ipt): PREPARATION FOR IPV6: Changing IPv4::cast to dynamic_cast everywhere. In loops that walk child objects of interfaces, cast child objects to InetAddrMask* or to FWObject* instead of IPv4*. This is to facilitate support for ipv6 in the future. In all these places we need to use two aspects of the child objects: either their position in the tree, in which case FWObject* is sufficient, or their address/netmask, in which case we should use InetAddrMask. * (various places in src/pflib): PREPARATION FOR IPV6: Changing IPv4::cast to dynamic_cast everywhere. 2008-03-09 vadim * (from 2.1) pf.cpp: fixed bug #1899914: "Script to apply the new rules." It is enough to execute "pfctl -f file.conf" to load PF policy. There is no need to purge filter and nat rules first, then reload it. * (from 2.1) RCS.cpp (RCSEnvFix::RCSEnvFix): fixed bug #1908351: "rcs does not save log message and file remains locked" * (from 2.1) Compiler.cpp (emptyGroupsInRE::countChildren): (libfwbuilder) fixed bug #1905718: "Group of DNS Name objects considered empty" 2008-03-06 * v3 feature: Firewall Builder v3 GUI redesigned as MDI interfaces. Several data files can be opened simultaneously and objects dragged and dropped from one file to another. FR # 984979 "split window view of tabs". * v3 feature: the GUI allows the user to change font used for the UI, object tree and rules (separately). FR #1621799: "main window font_size & column resizing" (although column width is not saved). * v3 feature: The user can switch between icons 25x25 and 16x16 in rules. FR #1844437 "25x25 Icons to 16x16" 2008-03-05 vadim * VERSION: started v2.1.18 * src/cisco_lib, src/iosacl, src/pix: Code for policy compilers for Cisco IOS ACL and PIX has been released under GPL and merged into the main fwbuilder tree. 2008-02-18 vadim * CircularQueue.hpp (antlr): fixed crash of the policy importer on 64-bit systems. This fixes bug #1886575: "Seg Fault on reading vanilla Fedora iptables file". See comment in module CircularQueue.hpp for details. 2008-02-10 vadim * pt_BR.po: updated Brazilian Portuguese translation by Rubens Ferreira Neto and Jose Carlos Medeiros * PrefsDialog.cpp (PrefsDialog::PrefsDialog): fixed bug #1886570: Diagnostic related to Edit->Preferences. Removed harmless but annoying error message that appeared on stderr when user opened Preferences dialog. * IPTImporter.cpp (IPTImporter::pushPolicyRule): Fixed bug 1883536: "fwbuilder segfaults when importing iptables conf". Added support for TCPMSS target with option --clamp-mss-to-pmtu in iptables importer; also made importer upderstand option --tcp-option but skip it since it is not supported in fwbuilder. 2008-02-06 * RCS.cpp (RCSEnvFix::RCSEnvFix): fixed bug #1849392: "RCS using windows 2003 without administrator rights". Pass TMP and TEMP environment variables to RCS tools * pix_os.xml.in: more for the bug #1816798: "Installing policy on PIX 501 fails". The fix that was made for v2.1.16 did not cover test-mode install, which is now fixed too. Command "terminal pager " is valid only for PIX 7.x and caused error while installing policy on PIX 6.3. Removed this command from the install sequence, it was not essential. 2007-12-29 * SSHUnx.cpp (SSHUnx::stateMachine): using signal proper for qt4 (bytesWritten(quint64) instead of wroteToStdin) 2007-12-19 vadim * v2.1.16 release 2007-12-15 vadim * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printRunTimeWrappers): fixed bug #1851166: "Installscript does not test for destination ip address". The problem affected specific case of a firewall with two (or more) interfaces that get their address dynamically and a policy rule that has one such interface in source and another in destination. Generated iptables script retrieves actual addresses of both interfaces and assigns them to variables, then uses these variables in actual iptables rules. Special check is provided in case some interface did not obtain any ip address at a time of execution of the script. Previously such test was only done for one dynamic interface per rule. This change makes the script check for both. * ipt.cpp: bug #1850352: "Install script wrongly completes successful". Storing exit status of iptables-restore so that generated firewall script can return the same status after it executes commands that set kernel parameters and runs user-defined epilog code. * PolicyCompiler_pf_writers.cpp (PrintRule::_printRouteOptions): applied patch #1850357: "Add support fo load balancing with pf to PolicyRule::Route" by Tom Judge (tomjudge@users.sourceforge.net) that adds support for load balancing rules in PF. Extended the patch adding support for address/netmask format of the next hop. Added checks for illegal IP addresses and netmasks in the next hop. Test cases for the PF load balancing rules are in test/pf/objects-for-regression-tests.fwb, firewall object firewall40-1. 2007-12-13 vadim * linux24.xml.in: working on bug #1850352: "Install script wrongly completes successful". Added more checks to the installer scriptlet to make it properly terminate with non-zero error code if iptables-restore returned error. Previously "echo" in the end of the generated masked error code returned by iptables-restore and made the GUI report successfull install even when it terminated with an error. Also added test for the presence of pkill on the system so that the script does not try to run it if it is not available. * platforms.cpp (list): applied patch #1850368: 'PF 3.7 has support for "set skip on"'. Patch by tomjudge@users.sourceforge.net extends support for "set skip on" option to pf 3.7. * platforms.cpp (isDefaultPolicyRuleOptions): fixed bug #1850346: "GUI has 2 views on which actions should be stateless". Even though GUI made rules with action Route stateful by default, code that determined if combination of options of a given policy rules was default thought these rules should be stateless. * ipt.cpp: Applied patch 1835308: "Patch for adding "-q" option to fwb_ipt". Option "-q" suppresses timestamp that is normally included in the generated script. This way, if no objects or rules changed in the firewall builder, generated script will be exactly the same. Timestamps made generated script different even if nothing really changed in the objects, which made external version control systems detect changes when there were none. * PolicyCompiler_PrintRule.cpp (PrintRule::_printOptionalGlobalRules): fixed bug 1848204: "ULOG-Setting ignored for invalid packets", applied patch #1848609 provided by reporter. Code that matched and logged packets in state INVALID always used target LOG, which was a problem for iptables installations that only come with target ULOG. * tcpservicedialog_q.ui: patch #1849500: "tooltip patch for tcpservicedialog_q.ui". Additional tooltips in the TCP Service dialog to explain function of tcp flags masks and settings. 2007-12-12 vadim * ipt.cpp: fixed bug #1849328: "iptables restore unusable in 2.1.15". This bug was introduced by the change for the bug 1812295. If option "use iptables-restore to activate policy" is on, we always generate script that prints iptables commands using echo and sends them to the input of iptables-restore via pipe. * VERSION (FWB_MICRO_VERSION): begin v2.1.16 2007-12-08 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): fixed bug #1821576: "Rule option tracking gives inavlid config with default value". Compiler should skip max-src-nodes when it is set to default '0' in the GUI. * Added Brazilian Portuguese translation by Jose Carlos Medeiros 2007-11-25 vadim * Starting with build 320 Windows packages install on Vista 2007-11-15 vadim * FWObjectDropArea.cpp (FWObjectDropArea::paintEvent): more fixes for bug #1826558: need to fill background rectangle in "object drop" widget for search. * RuleSetView.cpp (RuleSetView::paintCell): more fixes for bug #1826558: need to fill background rectangle in action, options and comment columns. 2007-11-14 vadim * RuleSetView.cpp (RuleSetView::paintCell): fixed bug #1826558: "OSX 10.5 font problem". This problem appeared only in Mac OS X Leoprard (10.5) build, other platforms were unaffected. 2007-11-02 vadim * instDialog.cpp (instDialog::installSelected): previous fix for the bug #1811781: "Batch Install" was insufficient. Needed to clear altAddress input field in the install options dialog in case of the batch install. 2007-10-28 vadim * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::createPrintRuleProcessor): fixed bug #1812295: "Can't use runtime address tables AND iptabels-restore". Script generated by fwb_ipt used "here document" if the option "use iptables-restore to activate policy" was turned on. This did not work in case policy used any tun-time address table objects. Now generated script always uses "echo" to generate iptables commands that it sends to th standard input of iptables-restore. * instDialog.cpp (instDialog::doInstallPage): fixed bug #1811781: "Batch Install". Built-in installer used address of the first firewall of the batch to communicate with all firewalls in the "batch install" mode. * PolicyCompiler_pf.cpp (PolicyCompiler_pf::addDefaultPolicyRule): fixed bug #1800875 "'keep state' missing from pass out going traffic rule". Compilers for pf, ipf and ipfw were affected. * pix_os.xml.in: fixed bug #1816798: "Installing policy on PIX 501 fails". Command "terminal pager " is valid only for PIX 7.x and caused error while installing policy on PIX 6.3. Removed this command from the install sequence, it was not essential. 2007-10-06 vadim * ipfAdvancedDialog.cpp (ipfAdvancedDialog::ipfAdvancedDialog): applied patch by to add support for Kerberos rcmd and Kerberos ekshell proxies in ipfilter NAT rules. * VERSION (FWB_MICRO_VERSION): begin v2.1.15 2007-09-10 vadim * 2.1.14 release 2007-09-08 vadim * configure.in: patch by Carlos Silva to add third parameter to AC_DEFINE_UNQUOTED 2007-08-25 vadim * RuleOptionsDialog.cpp (RuleOptionsDialog::loadFWObject): fixed bug #1764971: "allowed value range for burst limit". Iptables "--limit-burst" option should not be limited in the GUI. * instDialog.cpp (instDialog::continueRun): fixed bug #1772722: "installer should recognize when it uses plink 0.60". We detect when installer uses plink on Windows by checking the name of the configured ssh client. The check should be case-insensitive. 2007-08-06 vadim * configure.in: applied patch by Carlos Silva to make configure.in use ANTLR C++ run-time installed on the system if it can find one; otherwise it uses copy in src/antlr 2007-08-05 vadim * IPTImporter.cpp: fixed bug (no num): importer for iptables should properly assign rule options when it finds "-m limit" and "--limit" options in the input file. * IPTImporter.cpp: added a workaround for a situation when several iptables commands pass control to the same user-define chaine in the iptables-save file. As of fwbuilder v2.1, branch ruleset is a child object of PolicyRule. This means two different rules can not point at the same branch ruleset. This is unfortunate but it is hard to fix in the current version because it requires changes XML DTD and API. Will do this in 3.0. Meanwhile, checking if branch ruleset with requested name already exists and change the name by adding suffix '1', '2' etc to make it different. Imported rule is marked as 'bad' (red background) and gets a comment explaining this. * iptables.g (tcp_flags_list): fixed bug #1764988: "iptables import -> GUI crash": syntax for TCP flag matching in iptables-save should allow for more than 2 flags in 'comp' part * iptables.g (target_options): added missing supprot for "--log-tcp-sequence", "--log-tcp-options" and "--log-ip-options" options for target LOG to iptables policy importer * iptables.g (protocol_word): fixed bug (no num): iptables policy importer should properly parse numeric protocol specification (e.g. "-p 47"). * Importer.cpp (Importer::getTCPService): fixed bug #1764988: "iptables import -> GUI crash": iptables policy importer recognizes and parses TCP flag parameters ALL and NONE * IPTImporter.cpp (IPTImporter::pushPolicyRule): fixed bug #1764988: "iptables import -> GUI crash": iptables policy importer recognizes and parses target RETURN 2007-08-01 Vadim * FirewallDialog.cpp: fixed bug reported in Debian Bug report #417685 - added missing #include to make code compile with gcc 4.3 * fixed bug #1761373: "libfwbuilder doesn't build on Mandriva cooker". Applied fixes to make the code compile with gcc 4.2 * VERSION: started 2.1.14 2007-07-18 vadim * PolicyCompiler_ipt.cpp (InterfaceAndDirection::processNext): compiler permits setting direction in the rule while interface field is "All". This generates iptables command in chain INPUT or OUTPUT with "-i +" or "-o +" interface specification to match all interfaces. 2007-07-14 vadim * platforms.cpp (isDefaultPolicyRuleOptions): platform "iosacl" does not have any rule options at this time; making sure we never show an icon indicating non-default options. * templates.xml: added simple template for Cisco router 36xx * pf.cpp (main): Added support for "set skip on " command for PF. If an interface is marked as "unprotected" in the GUI, compiler generates this command for it. This is useful for loopback or other virtual interfaces. * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): better compliance with PF 4.x. Feature Req. #1679793: "add 'no state' and 'flags any'". If version is set to 4.x, compiler skips "flags S/SA keep state" for rules mathcing tcp services. However, according to the section "1.2. Operational changes" in PF FAQ at http://www.openbsd.org/faq/upgrade41.html , there should be a way to add "keep state" explicitly for rules on interface enc0. Added this option to the rule options dialog. * pf.cpp (main): implemented support for PF limit options "src-nodes", "tables" and "table-entries". Feature Req. #1674919: "Support "set limit table-entries"" 2007-07-12 vadim * SSHSession.cpp: More key caching request and other messages for wider variety of ssh clients. * SSHPIX.cpp (SSHPIX::stateMachine): fixed bug #1753188: "policy activation fails on PIX and IOS". Installer failed if account used to authenticate to the router or PIX went straight to 'enable' mode after login. 2007-07-07 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::_printLogging): fixed bug #1747828: "anchors generation - "log" not supported". "Log" keyword is not allowed in "anchor" rules; compiler should not generate it even if user turned logging on in a rule with action 'Branch' * PolicyCompiler_ipt.cpp (checkForRestoreMarkInOutput::processNext): fixed bug #1747332: "missing CONNMARK/ restore mark in Output Chain" * PolicyCompiler_PrintRule.cpp (PrintRule::_flushAndSetDefaultPolicy): fixed bug #1746257: "fwbuilder breaks IPv6". Added an option to the firewall settings dialog for iptables that controls whether compiler should skip generation of the code to set default policy of all ipv6 chains to DROP. This option is off by default, that is compiler puts the code in. This helps maintain backwards compatibility with old data files that do not have this option, which is equivalent to this option being "off". 2007-07-06 vadim * ObjectManipulator.cpp (ObjectManipulator::unlockObject): fixed bug #1743117: "crash while editing any". Added check, user should not be able to unlock Standard objects library * FWObject.cpp (FWObject::shallowDuplicate): fixed bug #1740766: "lock not saved". This method now copies the value of "ro" attribute (read-only). Clear it in the caller if neccessary. Method duplicate() clears it after calling shallowDuplicate in order to be able to modify the object, then restores this attribute to its original value. 2007-06-23 vadim * v2.1.12 release * iptables.g (target_options): parser for iptables is aware of "--set-tos" target option. Even though fwbuilder does not support target TOS, importer should be able to import policy that uses it without crashing. 2007-06-20 vadim * FWWindowPrint.cpp (printFirewall): fixed bug #1739373: "FWB2111, register Routing not printed". Tab "Routing" was not included in the printed copy of firewall policies. * NATCompiler_pf.h: fixed bug #1740545: "AddressTable in NAT section". Policy compiler for PF crashed if AddressTable object was used in TDst element of a NAT rule. 2007-06-17 vadim * instDialog.cpp (instDialog::initiateCopy): fixed bug (no number) where installer failed to properly copy .fwb file over to the firewall if file name contained whitespace 2007-06-16 vadim * instDialog.cpp (instDialog::prepareInstallerOptions): discovered and fixed bug in the installer: if management interface of the firewall is dynamic (i.e. had no IP address) and address of the firewall was given in the "Installer" tab of the firewall object dialog, installer failed to copy it to the instOptionsDialog and filled corresponding entry field with 0.0.0.0 * OSConfigurator_linux24.cpp (OSConfigurator_linux24::printShellFunctions): fixed bug 1737733: "install script doesn't detect BROADCAST if eth is NO-CARRIER". If firewall script runs before network interface comes up (i.e. is still in NO-CARRIER state), script failed to add virtual addresses for NAT. 2007-06-13 vadim * ActionsDialog.cpp (registerOption): after changes made in the compiler to simplify algorithm used to decide which chain a rule with action Tag should go to, rule action option "Mark connections in PREROUTING chain" ( "ipt_mark_prerouting" ) has been deprecated. 2007-06-12 vadim * FWWindow.cpp (FWWindow::reopenFirewall): Added platform capability element "supports_nat" - if True, platform supports NAT rules so the main window should show tab "NAT" in the policy view. If this parameter is False, the tab disappears. * DiscoveryDruid.cpp (DiscoveryDruid::DiscoveryDruid): added main menu item "File -> Import Policy" that activates Discovery Druid and opens it on the page where user can choose configuration file for import. 2007-06-09 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_flushAndSetDefaultPolicy): fixed bug #1711595: "ip6tables DROPs". Compiler adds rules to permit any-to-any on loopback interface for ipv6 in addition to rules that set default policy to DROP for all chains in ipv6 2007-06-06 vadim * antlr.pro: Added ANTLR C++ runtime to the project under src/antlr 2007-06-05 vadim * PolicyCompiler_ipt.cpp (setChainPreroutingForTag::processNext): streamlined algorithm that assigns chain to a rule with action Tag. The goal is to always use chain PREROUTING for rules with direction Inbound or Both and a combination of OUTPUT and POSTROUTING for rules with direction Outbound and Both. 2007-06-02 vadim * DiscoveryDruid.cpp (DiscoveryDruid::importPlatformChanged): finalized rule importer GUI. 2007-06-01 vadim * IPTImporter.cpp (IPTImporter::pushNATRule): NAT import now works 2007-05-30 vadim * pf.cpp (main): fixed bug #1727715: "Policy Installer failed but indicates succes". Activation script for PF exits with non-zero return code if script activation fails. * IPTImporter.cpp (IPTImporter::addSrv): import of target MARK and TagService for iptables * IPTImporter.cpp (IPTImporter::pushRule): support for module "limit" in importer for iptables 2007-05-29 vadim * IPTImporter.cpp (IPTImporter::pushRule): meaningful import of iptables-restore files with all actions for filter table. Action "Continue" helps import iptables commands with targets LOG and ULOG. * PolicyCompiler_ipt.cpp (PolicyCompiler_ipt::compile): Added support for action "Continue" (an empty action) in the GUI and compiler for iptables. This action creates a rule that does nothing, however it generates iptables command with target "-j LOG" if logging is turned on. This can be useful if one wants only to log packets that match certain pattern but not make any policy decision in the same rule. 2007-05-28 vadim * IPTImporter.cpp (IPTImporter::pushRule): basic iptables-restore import works (only policy rules, only minimal set of modules) 2007-05-27 vadim * IPTImporter.cpp: initial work on iptables importer * OSConfigurator_linux24.cpp (OSConfigurator_linux24::generateCodeForProtocolHandlers): Fixed bug in the shell code that finds netfilter modules (missing closing '"'). This bug broke generated iptables script. Bug was introduced in 2.1.12 some time before build 270 2007-05-25 vadim * iosacl.g (vlan): ignore "vlan" commands while importing IOS config * IOSImporter.cpp (IOSImporter::finalize): IOS accesslists importer properly handles situation when the same list is applied to multiple interfaces with different directions. 2007-05-22 vadim * run-tests.sh: simple framework for automated unit tests * importer_test.cpp: unit test for Cisco IOS access lists importer * IOSImporter.cpp (IOSImporter::finalize): IOS access lists importer works with a large complex test file. Test can be imported and then compiled with no manual changes. * PolicyCompiler_ipt.cpp (InterfacePolicyRulesWithOptimization): allow for object group in "Interface" rule element 2007-05-21 vadim * DiscoveryDruid.cpp (DiscoveryDruid::loadDataFromImporter): finished configuration importer GUI 2007-05-16 vadim * RoutingCompiler_ipt_writers.cpp: fixed bug #1718791: "Bug with more than one router". This bug affected routing rules. * OSConfigurator_linux24.cpp (OSConfigurator_linux24::generateCodeForProtocolHandlers): fixed bug #1720022: "Fail to load modules .ko.gz". * MangleTableCompiler_ipt.cpp (keepMangleTableRules::processNext): fixed bug #1720480: '"-A POSTROUTING -i interface" in branching rules'. Compiler should not generate iptables commands in POSTROUTING chain with "-i interface" clause. 2007-05-15 vadim * DiscoveryDruid.cpp (DiscoveryDruid::importConfig): basic GUI support for the configuration importer * IOSImporter.h (class IOSImporter): derived class - importer for Cisco IOS ACLs * Importer.h: generalized policy importer framework. Requires grammar for each platform. * iosacl.g: ANTLR grammar for IOS ACLs. Only "access-list ", "ip access-list extended" and certain "interface" commands cam be parsed 2007-05-11 vadim * SSHSession.cpp (SSHSession::readFromStdout): note about built-in installer on windows. Installer seems to have broke with upgrade of QT to 3.3.8. Specifically, in SSHSession::readFromStdout(), proc->readStdout() returns a byte array that contains actual output from the device, with some garbage appeneded to it. The garbage is included in the size() count of QByteArray returned by readStdout so it gets included into the QString which we append to stdoutBuffer. This happens only on win32; reverting to QT 3.3.7 fixes the problem. 2007-05-10 vadim * SSHPIX.cpp (SSHPIX::stateMachine): implemented support for scheduled reload for PIX firewalls (for roll-back). * instOptionsDialog.cpp (instOptionsDialog::instOptionsDialog): PIX and Cisco routers (IOS) : built-in installer can schedule reboot of the firewall before activating new policy, then cancel it if the policy has been activated successfully. * instOptionsDialog.cpp (instOptionsDialog::instOptionsDialog): fixed long-standing problem with size of the built-in installer options dialog. The dialog was too big and did not properly resize itself when some options were hidden. * SSHIOS.cpp (SSHIOS::stateMachine): installer for Cisco routers 2007-05-09 vadim * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): added support for the new attribute "unprotected" for the Interface object in the GUI. Compilers skip this interface while assigning ACLs or policy rules to interfaces. This is supported only in the compiler for Cisco IOS ACLs at this time. 2007-05-08 vadim * iosAdvancedDialog.cpp (iosAdvancedDialog::iosAdvancedDialog): Added dialogs and resource files for Cisco IOS ACLs 2007-05-07 vadim * RuleSetView.cpp (RuleSetView::changeAction): setting option "stateless" appropriately when new rule is created. * objects_init.xml: added object "All TCP established" - a tcp object with open port range and flag "established" * PolicyCompiler_ipf.cpp (PolicyCompiler_ipf::compile): using rule processor CheckForTCPEstablished in compilers for iptables, ipf and pf to check for TCP service objects with flag "established". This is considered an error because these platforms do not provide support for "established". * PolicyCompiler_ipfw_writers.cpp (PrintRule::processNext): using new TCPService object flag "established" in compiler for ipfw. * PolicyCompiler_ipf.cpp (doSrcNegation::processNext) and PolicyCompiler_ipfw.cpp: rules created for negation with action 'Continue' should be stateless. * PolicyCompiler_ipt.cpp (Branching::expandBranch): fixed bug (no number): compiler used to not set unique internal id for rules in branches, which lead to chain names like 'C.0' in generated script. * PolicyCompiler_PrintRule.cpp (PrintRule::_printLogPrefix): fixed bug (no number): when a rule number is inserted into a log record in place of macro %N, it should be formatted as "N/M" for rules in a branch. * PolicyCompiler_ipt.cpp (decideOnChainForClassify::processNext): fixed bug (no number): setting chain for Classify action only if it has not been set before. Setting chain to POSTROUTING always broke things if a rule with action 'Classify' was used in a branch (so the chain has been set to that of the branch) * RuleSetView.cpp (RuleSetView::changeAction): working on bugs #1676635: "no way to match on state if the action is drop" and #1671910: "2.1.8 In 'Branch' acton compiler doesn't insert NEW stanza". Rule option 'stateless' is automatically set when user changes rule action so it becomes anything except 'Accept', 'Tag' or 'Route'. This option is also automatically cleared when action is switched to any of these three actions. The user can override these default settings by checking or unchecking the option in the rule options dialog. * PolicyCompiler_PrintRule.cpp: working on bugs #1676635: "no way to match on state if the action is drop" and #1671910: "2.1.8 In 'Branch' acton compiler doesn't insert NEW stanza". Rely only on rule option 'stateless' to decide whether the rule should have "-m state --state NEW". 2007-05-06 vadim * v2.1.12 started 2007-04-28 vadim * v2.1.11 release 2007-04-24 vadim * SSHUnx.cpp (SSHUnx::SSHUnx): fixed bug #1702830: "fwbuilder does not detect errors during policy install". Built-in installer detects error messages printed by iptables and iptables-restore and aborts installation process. Summary page shown in the end reflects this as failed install. * instOptionsDialog.cpp (instOptionsDialog::updateRollback): fixed bug #1701971: "Enabeling test mode doent activate the reboot interval". Checking "Test mode" checkbox in the installer options dialog should enable widgets that configure automatic reboot timeout. 2007-04-23 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printModules): bug #1699483: "hashlimit-htable-expire not set". Compiler automatically generates name for the --hashlimit-name option if it is not set in the GUI. * PolicyCompiler_ipt.cpp (TagIfSrcFw::processNext): fixed bug #1703954: "Mark target in postrouting chain". Packets that originate on the firewall should be marked in the OUTPUT chain. According to the netfilter packet flow diagram at http://www.shorewall.net/NetfilterOverview.html , rerouting happens after OUTPUT hook but before POSTROUTING hook. * FWBTree.cpp (FWBTree::isSystem): fixed bug #1703595: "build 230 crashes when seaching for a deleted object" 2007-04-13 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printModules): fixed bug 1699483: "hashlimit-htable-expire not set". Added GUI controls and compiler support for hashlimit module options "--hashlimit-name", "--hashlimit-htable-size", "--hashlimit-htable-max", "--hashlimit-htable-expire" and "--hashlimit-htable-gcinterval" * OSConfigurator_linux24.cpp (linux24::generateCodeForProtocolHandlers): fixed bug #1697832: "fc5 kernel 2.6.20 moved *conntrack* modules". Starting with kernel 2.6.20, netfilter installs *conntrack* modules in "/lib/modules/`uname -r`/kernel/net/netfilter/" rather than "/lib/modules/`uname -r`/kernel/net/ipv4/netfilter/". Modified shell code that finds and loads all "*conntrack*" and "*nat*" modules, it should now work with both old and new kernels. I do not know if this directory change was introduced only by Fedora or it is general for the netfilter. * TCPServiceDialog.cpp (TCPServiceDialog::validate): fixed bug #1695481: "compliation error with lower end port". Before, user could enter start port range number greater than the end port range number. Neither the GUI nor compiler noticed this, which resulted in the incorrect firewall configuration. This fix adds check in the GUI to not let the user enter port ranges like that. 2007-04-03 vadim * PolicyCompiler_ipf_writers.cpp (PrintRule::_printWith): fixed bug #1676845: "lsrr option not compiling" * PolicyCompiler_ipf_writers.cpp (PrintRule::_printWith): fixed bug #1678410: "Ipfilter compiler uses wrong keyword for "fragment"" * utils.cpp (getUserName): fixed bug #1684334: "RCS should use $LOGNAME when commit" * ActionsDialog.cpp (ActionsDialog::loadFWObject): fixed bug #1692411: "can't set accouting rule name (fwbuilder 2.1.11)" 2007-03-24 vadim * RuleSetView.cpp (RuleSetView::paintCell): fixed bug #1685741: "GUI crash: click on an empty part of obj tree, then desktop" 2007-03-21 vadim * ObjectTreeView.cpp (ObjectTreeView::focusOutEvent): working on the bug #1685741: "GUI crash: click on an empty part of obj tree, then desktop" 2007-03-18 vadim * InterfaceDialog.cpp (InterfaceDialog::loadFWObject): minor redesign of the interface object dialog to make network zone more prominent and easier to set when network and group objects have long names. 2007-03-13 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): fixed bug #1674940: "if max-src-conn == 0: syntax error". Options max-src-conn and max-src-states can not have value '0' * TimeDialog.cpp (TimeDialog::loadFWObject): redesigned TimeService object dialog * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): fixed bug #1672191: "Time limit generates unexpected iptables command" * PolicyCompiler_PrintRule.cpp (PrintRule::_printTimeInterval): Added support for --datestart and --datestop options for module 'time' in compiler for iptables * started v2.1.11 2007-02-17 vadim * RuleSetView.cpp (RuleSetView::findWhereUsedSlot): added an item "Where used" to the context menu associated with objects in rules * FWWindow.cpp (FWWindow::setPolicyBranchTabName): a workaround for the bug 1629461: "Policy tabs do not scroll @ window extent on OSX". The tab widget used to show policy, nat, routing and policy branch rulesets does not switch to a "folded" mode on Mac OS X when it needs to show more tabs that fit in the window. Since I can't figure out a way to force it to do that, I am dropping "Policy/" from the tab titles for branches to make them shorter. This will help users with policies with many branches, however it does not solve the problem because as they keep adding branches, at some point they won't fit in the window again. 2007-02-15 vadim * FWWindow.cpp (FWWindow::fileCompare): fixed bug #1659832: "No compile with QT without STL support" * instDialog.cpp (instDialog::initiateCopy): fixed bug #1661140: "built-in installer broken in 2.1.9 for PF". Installer incorrectly set name for files it copied to the firewall if compiler generated more than one file. Normally two files are generated for PF and ipfilter. * v2.1.10 started 2007-02-10 vadim * v2.1.9 release * main.cpp (tty_raw): bug #1650369: "[patch] please add support for GNU/kFreeBSD". Applied patch to make code compile on kFreeBSD. 2007-02-03 vadim * listOfLibraries.cpp (list): fixed bug #1620284: "conflict when adding library to Preferences/Libraries". When the user tried to add a library to the list in Preferemces/Libraries when a data file with the same object library was loaded, the GUI detected the conflict and showed error dialog. * FWWindow.cpp (FWWindow::fileCompare): New feature: new operation "Tools/Find Conflicting Objects in Two Data Files". This operation inspects two data files (either .fwb or .fwl) and finds conflicting objects. Conflicting objects have the same internal ID but different attributes. Two data files can not be merged, or one imported into another, if they contain such objects. This operation also helps identify changes made to objects in two copies of the same data file. This operation does not find objects present in one file but not in the other, such objects present no problem for merge or import operations. This operation works with two external files, neither of which needs to be opened in the program. Currently opened data file is not affected by this operation and objects in the tree do not change. In the process of this operation user is presented with series of dialogs showing conflicting objects side by side. In the end the program can generate report and write it to a text file. 2007-01-30 vadim * instDialog.cpp (instDialog::initiateCopy): more for the bug #1617501:"Install fails after compile". Making sure we always strip directory path from the file name if user specified full path for the policy file in the "Output file name" input field in the "Compiler" tab of firewall object dialog. Need to strip path when macro "%FWSCRIPT%" is substituted in installation scriptlets and in some other places. 2007-01-15 vadim * OSConfigurator_linux24.cpp (linux24::printRunTimeWrappers): fixed bug (no num.): data files used for run-time AddressTable objects can have empty lines, the script should skip them. 2007-01-14 vadim * iptAdvancedDialog.cpp (iptAdvancedDialog::iptAdvancedDialog): more for bug #1618381: "CLASSIFY/MARK are non-terminating". Emulation of the terminating behavior for Classify and Tag actions is now controlled by a global option in the "Compiler" tab of the firewall properties dialog. This means emulation can be turned on and off for all rules that might require it at once. It is impossible to mix such rules with terminating and non-termninating behavior. The reason for this is that shadowing detection algorithm can only work with either terminating or non-terminating rules, not with the mix. Hopefully this is the last change made for this bug. * PolicyCompiler_ipt.cpp (ipt::getAddressTableVarName): fixed bug #1632054: "Runtime AddressObjects FAIL to load if "Name:" contains "."". Compiler checks if the name of the run-time AddressTable object contains characters that have special meaning in sheel and relaces them with '_' when it generates the name of the temporary shell variable. * PolicyCompiler_ipt.cpp (splitNonTerminatingTargets): update for bug #1618381: "CLASSIFY/MARK are non-terminating". Adding iptables rule with target ACCEPT to make Tag and Classify rules terminating. This is controlled by checkbox in the action dialog for actions Classify and Tag. Default setting is off. 2007-01-09 vadim * FWWindow.cpp (FWWindow::scheduleRuleSetRedraw): fixed bug (no num.): GUI used show fanthom 'Policy', 'NAT' and 'Routing' tabs when user deleted objects from the Deleted Objects library, provided some of these objects were previously deleted firewalls. 2007-01-07 vadim * GroupObjectDialog.cpp (GroupObjectDialog::dropped): fixed bug #1624577: "group window doesn't stay open on multiple-adds". Using special flag to tell ObjectTreeView that it should ignore MouseReleaseEvent it gets after d&d operation, so it wont switch object in the editor panel. Note the bug triggered only on Mac OS X. * FWWindow.cpp (FWWindow::FWWindow): "Apply" and "Close" buttons in the objct editor panel should be of fixed size horizontally 2007-01-06 vadim * instDialog.cpp (instDialog::testFirewall): fixed bug #1617501:"Install fails after compile". The GUI got confused when user enter full path to the policy file in the "Output file name" input field in the "Compiler" tab of firewall object dialog. * SimpleTextEditor.cpp (SimpleTextEditor::loadFromFile): fixed bug 1619930: "Prolog tab's ScriptEditor's import fails to overwrite" * OSConfigurator_linux24.cpp (linux24::printRunTimeWrappers): fixed bug #1628989: "run-time-loaded rules don't accept ";" as line comment" * RuleOptionsDialog.cpp (RuleOptionsDialog::changed): fixed bug #1620206: "RuleOptions' "Apply" button greyed-out until menu selection" * SimpleTextEditor.cpp (SimpleTextEditor::SimpleTextEditor): fixed bug #1619842: "prolog "script editor" opens behind other windows" * RuleSetView.cpp (RuleSetView::removeRule): fixed bug #1629521: "can't delete empty chain/policy tab" * instOptionsDialog.cpp (instOptionsDialog::hidePIXOptions): installOptionsDialog was too large and did not fit on some laptop screens. Doing tricks to make sure the dialog properly resized after unused GUI elements are hidden. 2007-01-04 vadim * PolicyCompiler.cpp (DetectShadowingForNonTerminatingRules::processNext): (API change) fixed bug #1618381: "CLASSIFY/MARK are non-terminating". Non-terminating rules shadow each other "backwards", that is more general rule shadows other rules _above_ it. Added flag 'reverse' to the method find_more_general_rule and added new rule processor DetectShadowingForNonTerminatingRules that finds such cases of 'reverse' shadowing. Using it for rules in the mangle table for iptables. * PolicyCompiler_ipt.cpp (finalizeChain::processNext): working on bug #1618381 * For action Branch with option to add branching rule to the mangle table: we now generate rules in PREROUTING, POSTROUTING, INPUT, OUTPUT and FORWARD chains. This is because some targets can only work in PREROUTING or POSTROUTING chains but we do not know what rules will user put in the branch. So we need to branch in all chains * For rules in mangle table with direction set to Inbound or Outbound force chain to PREROUTING or POSTROUTING respectively early. This eliminates duplicates such as the same rule in PREROUTING and INPUT chains. Also since most (all?) targets that require mangle table go into either PREROUTING or POSTROUTING chains, it should be enough to use these two chains. 2007-01-01 vadim * ActionsDialog.cpp (ActionsDialog::setRule), PolicyCompiler_ipt.cpp (splitNonTerminatingTargets::processNext): working on bug #1618381: "CLASSIFY/MARK are non-terminating". Converting non-terminating targets MARK and CLASSIFY into equivalent of terminating targets using intermediate chain and "-g" option to pass control to it. Added a checkbox to the rule options dialog for action Classify for this, by default this feature is off. 2006-12-27 vadim * Compiler.cpp (Compiler::expandGroupsInRuleElement): fixed bug #1620925: "compile-time AddressTable object with empty file". Compile-time AddressTable object that uses file with no addresses should be treated as an empty group according to the "Ignore empty groups" option. Changes are made as follows: - Compiler::expandGroupsInRuleElement does not call s->setAnyElement(); to set rule element to 'any' before adding addresses from the group. This means that if group is empty, rule element remains empty (not even 'any', just with no children, i.e. with size()==0). Note that AddressTable::loadFromSource() leaves AddressTable object empty if the file does not have any addresses. - Compiler::emptyGroupsInRE specifically checks for run-time MultiAddress objects and skips them so they wont be treated as empty groups (since they are indeed empty). Compile-time MultiAddress objects are treated as groups and algorithm that depends on option 'ignore empty groups' is executed for both empty regular groups and empty compile-time MultiAddress objects. * PolicyCompiler_ipt_optimizer.cpp (optimize1::optimizeForRuleElement): fixed bug #1623113: 'connlimit fails in compiled "address table" rules' Module connlimit can only be used in iptables rules matching TCP services. Such iptables commands have "-p tcp" and/or "-m tcp" options. If a rule in fwbuilder uses TCP Service and connlimit option and has multiple objects in src and dst, optimizer used to split it to minimize matches. It however preserved connlimit option in all subrules, even though some of them did not have TCP service after the split. This lead to generation of incorrect iptables commands. * PolicyCompiler_ipt.cpp (Branching::expandBranch): fixed bug #1623338: "Can not disable rules in a branch". Compiler for iptables ignored flag 'disabled' on rules in a branch. 2006-12-26 vadim * VERSION (FWB_MICRO_VERSION): set version to 2.1.9 2006-12-03 vadim * v2.1.8 released 2006-11-30 vadim * FirewallDialog.cpp (FirewallDialog::applyChanges): fixed bug #1589743: "compiler setting should be erased when fw platform changes". If user configured firewall object to use thrid-party compiler, this setting should be erased when firewall platform of this object changes. 1) compilers are always platform-specific and old compiler most likely won't work with different platform; 2) 'advanced' firewall settings dialog may not have an entry field for the compiler (e.g. dialog for PIX does not have it) 2006-11-26 vadim * gui.pro (TARGET): All binaries are renamed to drop suffix '21'. Opinion poll amongs the mailing list sbscribers showed majority of users does not care for the ability to install and run both old and new versions of fwbuilder on the same machine. This feature creates substantial problems because of the symlinks to libfwbuilder libraries that have the same name regardless of the library version ('libfwbuilder.so' and 'libfwcompiler.so'). These symlinks are required on Linux and *BSD and can not be avoided easily. The only simple alternative was to rename libraries to libfwbuilder21 and libfwcompiler21. I was impartial and thought of doing this but FreeBSD port maintainer did not like this solution. Given that most users said in the poll they do not want this feature anyway, I am reverting binary and man page names back to the old standard scheme without suffix '21'. 2006-11-16 vadim * FindObjectWidget.cpp (FindObjectWidget::matchAttr): added back search by regexp - object name or port, protocol or ICMP type numbers can be defined as regular expressions. 2006-11-09 vadim * PolicyCompiler_PrintRule.cpp (PrintRule::_printDirectionAndInterface): fixed bug #1593221: "iptables filtering bridge problem - PHYSDEV: no physdev opti..." Some times rules were generated with "-m physdev" but witout "--physdev-in" or "--physdev-out" options. * PolicyCompiler_ipt.cpp (Branching::expandBranch): fixed bug #1592130: "Policy Chaining Issues". Policy compiler should expand rule subsets recursively * FWWindow.cpp (FWWindow::addPolicyBranchTab): working on bug #1592130: "Policy Chaining Issues". The GUI should properly display nested branch rulesets. * set version to 2.1.8 2006-10-30 vadim * v2.1.7 released 2006-10-28 vadim * RuleSetView.cpp (RuleSetView::paintCell): fixes for QT w/o STL support 2006-10-24 vadim * manually removed from findobjectwidget_q.ui and findwhereusedwidget_q.ui * build 155 2006-10-23 vadim * platforms.cpp (getRouteOptions_pf_ipf): fixed bug (no num): the program used to incorrectly save "route option" parameter that is used for pf anf ipf firewalls when user edited action "Routing" for iptables firewall. This would corrupt saved XML file if the program was used under non-English locale. 2006-10-22 vadim * ObjectTreeView.cpp (ObjectTreeView::updateTreeItems): eliminated useless creation of interim QPixmap objects. It appears this was responsible for creation of tons of extra pixmaps that triggered bug 1582130 on windows. Bug ##1582130: "GUI crashes on windows when very large data file is opened" is now fixed. 2006-10-21 vadim * ObjectManipulator.cpp (ObjectManipulator::addTreePage): working on bug #1582130: "GUI crashes on windows when very large data file is opened". Using QPixmapCache everywhere. * PixmapFactory.cpp (PixmapFactory::getPixmap): bug #1582130 "GUI crashes on windows when very large data file is opened". Ran into a known limitation on number of simultaneously created pixmaps on Windows. If the data file contains over 3000 obects or so, the GUI crashes on Windows. This is caused by the fact that GDI has global limit on the number of pixmaps. See here: http://lists.trolltech.com/qt-interest/2005-01/thread00679-0.html Using QPixmapCache class to cache and reuse pixmaps, using it via simple wrapper PixmapFactory that automatically creates pixmaps not found in the cache. 2006-10-20 vadim * listOfLibraries.cpp (listOfLibraries::listOfLibraries): fixes for QT w/o STL support on win32 2006-10-19 vadim * DialogData.cpp (DialogData::loadToWidget): properly using remapping tables while loading strings into QComboBox when program runs under international locale. Strings for qomboboxes are defined in platforms.cpp and need to be translated accordingly. 2006-10-16 vadim * RCSFileDialog.cpp (RCSFileDialog::getSelectedRev): fixed bug #1578502: "crashing opening file". The GUI crashed if the user switched "open file" dialog to detailed list mode and then tried to open a file. 2006-10-15 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::_printAction): All compilers print error mesage when they encounter unknow action in a rule * Preprocessor.cpp (Preprocessor::convertObject): fixed bug #1575355: "Compiler tries to resove deleted AddressTable objects". Using findWhereUsed to find if MultiAddress object is used in firewall being compiled so we don't try to resolve objects that are not used anywhere. * FWObjectDatabase.cpp (FWObjectDatabase::findObjectsInGroup): code refactoring: moved methods findObjectsInGroup and findWhereUsed from the GUI to API. 2006-10-08 vadim * v2.1.6 build 134: major improvements in support for outbound ACLs in PIX 7.0 in compiler for PIX. Added file 'v21_migration_notes.txt' to fwbuilder-pix package 2006-10-07 vadim * NATCompiler_PrintRule.cpp (PrintRule::_printDstService): fixed bug#1572735: "Wrong syntax with TagService in NAT table". Added mssing "-m mark" 2006-10-06 vadim * PolicyCompiler_ipfw.cpp (SpecialRuleActionsForShadowing::processNext): rule with action 'Pipe' or 'Custom' should not shadow other rules * PolicyCompiler_ipfw_writers.cpp (PrintRule::processNext): compiler for ipfw generates rule with action check-state depending on the setting of he option "Add rule to accept packets matching dynamic rules created for known sessions". This option is controlled by a checkbox in the firewall settings dialog. * TableFactory.cpp (TableFactory::PrintTables): if AddressTable object is configured to resolve at run time but file name is left blank, compiler for PF generates PF configuration as follows: "table persist". That is, it omits 'file "filename"' clause all together. This is useful if table is updated automatically using "max-src-conn, overload " option and does not need to be pre-populated with addresses from a file. 2006-10-05 vadim * pixAdvancedDialog.cpp (pixAdvancedDialog::pixAdvancedDialog): added option "Generate outbound ACLs" for PIX 7.0 2006-10-02 vadim * Checking in updated German translation by Hans Peter Dittler 2006-09-29 vadim * PolicyCompiler_ipt.cpp (ipt::compile): fixed bug #1567873: "CLASSIFY/Logging". eed to run rule processor decideOnChainForClassify before rule is split for negation or logging to properly pick up chain for action Classify. Previously rules with this action and either negation or logging would match packets in chains INPUT/OUTPUT/FORWARD but use chain POSTROUTING when applying action. 2006-09-28 vadim * pf.cpp (main): 'Prolog' section of the generated script can now be added in different places: - to the activation shell script, as before - at the very top of generated .conf file - after 'set' commands in the generated .conf file - after 'scrub' commands in the generated .conf file - after table definitions in the generated .conf file but before all policy commands 2006-09-26 vadim * checking in updated Russian localization by 2006-09-21 vadim * ObjectManipulator.cpp (ObjectManipulator::deleteObj): fixed bug #1562965: "no confirmation when deleting an object". In a scenario when user starts with an emty object tree, then adds a firewall with an interfaces, then tries to delete the interface, the GUI would just delete it without presenting the user with "Are you sure ?" confirmation dialog. 2006-09-20 vadim * PolicyCompiler_ipt.cpp (convertAnyToNotFWForShadowing::processNext): fixed bug #1562348: "a case of undetected rule shadowing". Compiler did not detect shadowing in the pair of rules where first rule was 'any any service' (flag 'firewall is part of any' is ON) and the second was 'fw any service' when global flag 'firewall is part of any' is OFF * confirmdeleteobjectdialog_q.ui: fixed bug #1561165: "Delete dialog box sizing incorrect" * FWObject.cpp (FWObject::shallowDuplicate): API change: fixed bug 1562290: "GUI crashes in discovery druid". FWObject::shallowDuplicate should add to database index only if dbroot is defined. If dbroot==NULL, trying to copy it from parameter x of shallowDuplicate (the object we are duplicating), but need to check if dbroot is != NULL after that as well, because object we are dulicating may not belong to any object tree. This is the case with interface objects created in SNMPQuery::fetchInterfaces 2006-09-17 vadim * PolicyCompiler_pf_writers.cpp (PrintRule::processNext): feature request #1531599: "max-src-conn and max-src-conn-rate". Added support for max-src-conn and max-src-conn-rate options n compiler for PF. * RuleOptionsDialog.cpp (RuleOptionsDialog::loadFWObject): feature request #1531599: "max-src-conn and max-src-conn-rate". Added GUI elements to support these PF options. 2006-09-16 vadim * SSHPIX.cpp (SSHPIX::stateMachine): fixed a bug in the code that deals with previously unseen ssh host key. Properly terminating session if user hits 'No'; stopping heartbeat timer while waiting for user input. * FWWindow.cpp (FWWindow::install): compile/install wizard is now a top level non-modal window, it can be used in parallel with the main window so one can inspect and fix rules while still looking at the output produced by the compiler, or work with objects and rules while pushing policy update to the firewall. 2006-09-15 vadim * instDialog.cpp (instDialog::installerError): fixed bug #1559697: "built-in installer crashes on incorrect password" 2006-09-14 vadim * FWObjectClipboard.h: clipboard holds list of object IDs instead of object copies. Clearing clipboard when an object is deleted from the "Deleted objects" library in ObjectManipulator::delObj. * FWWindow.cpp (FWWindow::load): calling FWObjectDatabase::reIndex to fix object reference counters and rebuild the index after object tree is loaded from .fwb file. Doing the same in all policy compilers. * NATCompiler_pf.cpp (splitForTSrc::processNext): fixed bug #1556984" "Nat statements in PF are missing (source-natting)" Compiler was too restrictive checking firewall's interfaces while generating 'nat' rules. It generated such rule only when it was able to find an interface with address/netmask combination that defined subnet to which TSrc address belonged. 2.0.X used to be more liberal and created nat rule even if such interface was not found, in such case it generated nat rule bound to all interfaces of the firewall. 2006-09-13 vadim * ActionsDialog.cpp (ActionsDialog::iptRouteContinueToggled): fixed bug #1557827: "iptables, routing, iif and continue". GUI enforces rules on options to iptables target ROUTE: 'continue' is mutually exclusive with --iif and --tee, therefore checking option 'Continue packet inspection' disables options 'Change inbound interface to' and 'Make a copy' (GUI elements are greyed out). 2006-09-10 vadim * FWWindow.cpp (FWWindow::scheduleRuleSetRedraw): using timer event to make sure rule sets are redrawn no more than once when needed. 2006-09-08 vadim * FWWindow.cpp (FWWindow::load): using FWObjectDatabase::addToIndexRecursive to quickly reindex whole database once datafile is loaded. This works very fast. Fixes everywhere for the new format of FWObjectDatabase::create 2006-09-07 vadim * FWWindow.cpp (FWWindow::load): improvements in the GUI ergonomics when working with very large data files: - The main window opens before the file specified on the command line is loaded - Using status bar to print messages indicating progress of the file loading process - Enforcing objects indexing after the file is loaded, this speeds things up later * ObjectEditor.cpp (ObjectEditor::actionChanged): fixed bug #1553394: "Options windows stays the same". 2006-09-05 vadim * FWWindow.cpp (FWWindow::killInstDialog): compile/install dialog is now not modal, this means the user can look at the policy and objects while compilation and/or installation is going on. This is especially convenient as it allows one to inspect the rules after failed compilation while still having compiler error on screen. * VERSION: set version to 2.1.6 * configure.in: added check to make sure qmake found by configure really is part of QT 3.x. This should help avoid build failures on systems where both QT 3.x and 4.x are installed and where /usr/bin/qmake is really QT 4.x qmake which we can not use. 2006-08-31 vadim * PolicyCompiler_ipfw.cpp (processMultiAddressObjectsInRE): checking for (currently unsupported) run-time AddressTable objects * All compilers: fixed bug #1544488: 'Error with DNS_name object when "resolve during run time"'. Needed to swap run-time DNSName and AddressTable objects with MultiAddressRunTime during rule shadowing run 2006-08-29 vadim * instDialog.cpp (readFromStdout): properly processing text coming from the background process if it comes buffered in chunks that include several lines of text and possibly incomplete last line. Previously, text would come out werdly formatted in the log window. * instDialog.cpp (processExited): detectig situation when background process (compiler) crashes or is killed * RuleSetView.cpp (fixRulePosition): this method fixes rule position if it is incorrect (this happens sometimes because of errors in auto-upgrade transformations). fixRulePosition checks if object the rule belongs to is read-only or belongs to a read-only subtree in the database and temporarily breaks the lock in order to be able to fix rule position. This method is recursive so it supports cases when several objects between the rule and database root are read-only. 2006-08-27 vadim * instDialog.cpp (prepareInstallerOptions): Added checkbox 'save copy of fwb file on the firewall' to the installer options dialog. If this checkbox is on, installer copies .fwb file to the firewall before it copies generated configuration and activates it. This can be used as last resort backup but should be avoided if firewall is managed from remote workstation and especially if many firewalls are managed from dedicated management workstation (because storing fwb file on each firewall means security policy of all firewalls resides on all every one of them). This option is off by default. 2006-08-26 vadim * ConfirmDeleteObjectDialog.cpp (findForObject): redesign of the dialog: now showing objects to be deleted and their parent objects in the same list with selection disabled. This removes confusion caused by the text in the dialog saying that 'seletect objects' were bout to be deleted and ability to select objects in the confirmation dialog. 2006-08-20 vadim * PolicyCompiler_pf.cpp (fillDirection::processNext): fixed bug #1543684: "fwb 2.1.5 IPFilter fallback rule issues". Fallback rule should be 'pass out' if option 'Pass all outgoing' is used. 2006-08-19 vadim * MangleTableCompiler_ipt.cpp (processNext): (new feature): added checkbox to the action 'Branch' for iptables "In addition to 'filter', create branching rule in 'mangle' table as well". When this parameter is activated, compiler creates branching rules in both filter and mangle tables; in mangle table it always uses chains PREROUTING, INPUT, OUTPUT and FORWARD. * PolicyCompiler_ipt.cpp (processNext): fixed bug #1534423 "2.1.5, mark action rules in branches". Added checkbox "Mark packets in PREROUTING chain" to the action "Tag" for iptables. Compiler places rule into PREROUTING chain when this parameter is activated. 2006-08-18 vadim * PolicyCompiler_ipt.cpp (compile): working on bug #1534423 "2.1.5, mark action rules in branches". Branch rules with action Tag go into mangle table. 2006-08-17 vadim * gui.cw: this file is used by QT to save descriptions of custom widgets * ObjectManipulator.h: added bunch of missing virtual destructors to various classes 2006-08-10 Vadim * ConfirmDeleteObjectDialog.cpp (ConfirmDeleteObjectDialog): completed implementation of feature request #1116454: "Where Used Option". When the user tries to delete an object from the tree, the GUI presents a list of groups and firewall rules where this object is used. 2006-08-09 Vadim * instDialog.cpp (findFirewalls): main menu item 'Compile' and corresponding toolbar button activate compilation/installation for all firewalls in all libraries. This fixes bug #1531007: "no firewall in comp/inst dialog if standard library selected" * utils.h (findByObjectType): added parameter bool skip_system_libs. This method will skip libraries DELETED_LIB and TEMPLATE_LIB if this parameter is true (which is its default value). 2006-08-08 Vadim * ObjectEditor.cpp (validateAndClose): fixed bug (no num.): "Apply" button in the editor panel would not activate when user reopened an object after it was edited and then editor panel closed. 2006-08-08 Vadim * ObjectEditor.cpp (apply): fixed bug #1531020: "gui behaviour on object renaming". Changing name of the selected object in the editor updated it in the tree but not in the rule set view. * ActionsDialog.cpp (applyChanges): fixed bug #1531008: "gui behaviour improvements". Gui used to reset rule selection after user selected different object in the tree. 2006-08-05 Vadim * newFirewallDialog.cpp (newFirewallDialog): fixed bug #1525808: "fwbuilder21: Windows are too large ". One of the pages of the firewall creation druid was too large vertically, as the result whole druid would not fit on screens 1024x768 with standard font bigger than 18pt * FindWhereUsedWidget.h (class FindWhereUsedWidget): Feature request #1116454: "Where Used Option". Ilya implemented "Find Where Used" function which quickly finds and shows rules of all firewalls that utilize a given object. 2006-07-23 vadim * RuleSetView.cpp (copyRule): still debugging problems caused by QT w/o STL support. Also got rid of methods RuleSetView::isSrc, isDst, isSrv etc, makes code cleaner cause these methods violated data access boundaries in the class hierarchy. 2006-07-22 vadim * FWObjectPropertiesFactory.cpp (getPolicyRuleOptions): fixes in bunch of places where code assumed QT is built with STL support 2006-07-20 vadim * PolicyCompiler_ipt_optimizer.cpp (processNext): checking if objects in srv are of the type TCPService or UDPService; if they are, treat srv as if it has one object even if there are several in it. This eliminates uncessesary rule splitting that optimizer used to do. * PolicyCompiler_ipt.cpp (compile): moved InterfacePolicyRulesWithOptimization further down the chain of rule processors to let other processors properly decide on chain for rules that are associated with multiple interfaces. Such rule is now treated as if it has one interface, and most of the chain and target decisions are made before the rule is split. When the rule is split in InterfacePolicyRulesWithOptimization, each part gets one interface from the original list. * PolicyCompiler_ipt.cpp (SrcNegation): all rule processors that work with negation reset "Interface" rule element in subrules they create except for the very first. * main.cpp (main): removed plays with styles on Mac, they proved unnecessary 2006-07-18 vadim * unit_tests.cpp (main): unit test for RCS module, currently only checks if rlog reading routing works right * RCS.cpp (RCS): trying to fix mysterious bug that causes RCS module to misinterpret RCS log in some cases and read modification date/time instead of the name of the user who apparently opened and locked the file. However in cases like that the file in fact is checked in and unlocked. Instead of reading rlog output line by line and using regex to parse each line separately, we now read the output in chunks using '------' as a separator. Each chunk corresponds to one revision and all regexps are written to work on the whole chunk instead of one line. 2006-07-17 vadim * RuleSetView.cpp (paintCell): When user selects an object in the rule set, all references to the same object in other rules are highlighted by drawing thin red frame around them. Similarly, when an object is selected in the tree, all references to it in the currently visible ruleset are similarly highlighted. This helps enforce the notion that all instances of the object in rules are really references to the same object, as well as helps locate these references visually. 2006-07-12 vadim * FWWindow.cpp (exportLibraryTo): user choses libraries for export using spearate modal dialog instead of built-in panel in the file choosing dialog in the "File/Export Library" function 2006-07-11 vadim * FWWindow.cpp (FWWindow): FindObjectWidget is not a custom widget anymore - this is a workaround for QT bug #85440 : http://www.trolltech.com/developer/task-tracker/index_html?id=85440&method=entry 2006-07-09 vadim * ObjectTreeView.cpp (contentsMouseReleaseEvent): bugfix: the GUI used to switch object in the editor if user tried to open a different library and expand/collapse subtree in it. It should not do this, expading/collapsing subtrees should not cause object switch in the editor. 2006-06-30 vadim * RuleSetView.cpp (paintCell): highlighting whole table cell for rule options/actions/directions/etc when corresponding rule element is selected. * Added title bar with icon and object type name to dialog panels for all object types 2006-06-25 vadim * PrefsDialog.cpp (PrefsDialog): removed "Data format" tab from the Preferences dialog. Option that turns off saving standard objects in every users data file was on by default for a long time, now it is time to remove the GUI control all together. * FWBSettings.h: using macro SETTINGS_PATH_PREFIX to define path prefix for settings. This makes it easier to change the prefix when new version is introduced 2006-06-23 vadim * DiscoveryDruid.cpp (): using QDns to get host names for discovered ip addresses instead of our own DNS methods 2006-06-21 vadim * NATCompiler_pf_writers.cpp (_printPort): fixed bug #1509411: "FWB does not build correct PF RDR port ranges". RDR rules should support port ranges in the RHS of "->" * qmake.inc.in: Passing CXXFLAGS from environment to the build process. Fedora engineers had to add a hack to their .spec file to do this, this change makes their hack unnecessary 2006-06-17 vadim * PolicyCompiler_pf_writers.cpp (_printRouteOptions): implemented spport for action Route for PF 2006-06-15 vadim * ObjectTreeView.cpp (contentsMouseReleaseEvent): fixed selection of multiple objects in the tree and interaction with editor. 2006-06-14 vadim * PolicyCompiler_ipt.cpp (processNext): implemented support for action Route for iptables 2006-06-13 vadim * RuleSetView.cpp (openObjectInTree): selecting object in a rule automatically opens it in the tree (both when editor opened and when it is closed) 2006-06-11 vadim * FWWindow.cpp (requestEditorOwnership): moved all the logic controlling switching between objects whith editor open to this method of FWWindow, this significantly simplifies other classes. Now we can properly process situations when user opens an object in a rule, edits it and then tries to open an object in the tree for editing. This also works in other situations when object with unsaved changes is opened in the editor and user tries to switch to another one, possibly in a different panel or widget. Still need to explore ways to maintain synchronized object highlighting in the tree and in rules. 2006-06-06 vadim * RuleSetView.cpp (maybeTip): directions are represented only by icons with no text; added tooltip for directions * ObjectEditor.cpp (validateAndSave): cleanup in ObjectEditor class - reusing method validateAndSave in methods close, validateAndClose * FirewallDialog.cpp (loadFWObject): "snmp" tab of the firewall object dialog has been deprecated 2006-06-04 vadim * RuleSetView.cpp (revealObjectInTree): change in the GUI behavior: - selection in the tree and ruleset are mutually exclusive, that is selecting an object in ruleset turn selection off in the tree and vice versa. Added menu item "Reveal in tree" to the context menu that appears when user clicks right mouse button on an object in ruleset. * PolicyCompiler_ipt.cpp (processNext): Added support for CONNMARK as an option for rules with action Tag. If a checkbox "Mark connections created by packets that match this rule" in rule options of a rule with action Tag is checked, compiler adds iptables command to save mark set by the Tag action into connmark module, and then adds another command at the beginning of the policy to restore it. 2006-06-03 vadim * ActionsDialog.cpp (setRule): New rule action: "Route", to be mapped to ROUTE target for iptables and 'route' option for pf and ipf 2006-05-31 vadim * RuleSetView.cpp (paintCell): When a group is opened in the editor, an object can be highlighted there which is different from the object highlighted in rules. Using alternatie color to highlight object in rules when user switches keyboard focus to the editor panel. This helps avoid confusion caused by identical look of objects highlighted in rules and group view. Currently using QColorGroup::midlight() to get color for when ruleset widget has no focus. This is probably incorrect because color should change when widget's colorGroup() changes from active to normal. Using midlight color may lead to incorrect results if QT theme does not define this color properly. 2006-05-25 vadim * ObjectManipulator.cpp (edit): GUI opens objects in the editor panel on single mouse click on an object in the tree if editor panel is opened. If it is closed, click just changes selection in the tree. Drag and drop works because object is opened in the editor on mouse release. Similarly, if user navigates in the tree using keyboard, object is opened in the editor on keyReleased event. Multiple selection works both by mouse and by keyboard. 2006-05-20 vadim * PolicyCompiler_pf.cpp (swapAddressTableObjectsInRE): AddressTable objects are converted to PF tables with the name of the object in both run-time and compile-time mode. This is so only for PF because other compilers simply expand compile-time AddressTable objects as a group of addresses (and lose its name in the process). Administrator can use compile-time AddressTable object to create tables with names known beforehand. In the future these tables can be used with 'overflow' rule option that updates tables automatically. * TableFactory.cpp (init): implemented persistent tables in compiler for PF: compiler maintains list of tables it creates between passes for NAT and policy rules. This reduces duplication if the same tables need to be created for both policy and NAT rules. Tables for branched rule sets (anchors) are generated separately and may duplicate those in the main rule set (although their name is different). 2006-05-16 vadim * PolicyCompiler_pf.cpp (processMultiAddressObjectsInRE): DNSName object now inherits MultiAddress, this allows for DNSName to be expanded into multiple addresses at compile time. Run time support hasn't changed because most fw platforms automatically expand domain name into all IP addresses defined as DNS A records for this name. 2006-05-14 vadim * FWWindow.cpp (unselectRules): rule set should lose focus when object editor is opened in a panel. Object shown in the editor is highlighted in the tree anyway. This works better during search when "find next" finds object in the tree * NATCompiler_PrintRule.cpp (processNext): fixed bug #1476797: "ipt NETMAP, POSTROUTING** chain --to problem with multiple network targets". * PolicyCompiler_PrintRule.cpp (_printModules): Added support for hashlimit module for iptables (with an option for older systems where the same module is called dstlimit) 2006-05-13 vadim * PolicyCompiler_PrintRule.cpp (_printModules): added support for connlimit module for iptables 2006-05-12 vadim * RuleOptionsDialog.cpp (loadFWObject): added input fieds for iptables module "connlimit" * Many dialogs: converting all object, rule options and actions editors from pop-up dialogs to built-in panels. 2006-05-07 vadim * PrefsDialog.cpp (accept): removed entry field for scp, it is not used by the installer. Cleaned up in all places where we check if path to ssh is configured to make sure installer can use it. * TableFactory.cpp (createTablesForRE): names for tables that go into an anchor have anchor name prepended to them as a prefix to ensure global uniqueness. One side effect of this is that AddressTable objects can only be used either in global rules or in an anchor, but not in both at the same time because the name of the table created for such object follows the name of the object and hence appears the same in the main rule set and in the anchor. 2006-05-06 vadim * pf.cpp (main): Added support for branching rules for PF, imlpemented via anchors. Rules defined in branches are stored in separate .conf files and loaded by the .fw file using pfctl -a -f Anchor rule files are also added to manifest in the .fw file to make sure the built-in installer will copy them to the firewall. * PolicyCompiler_ipt.cpp (processNext): support for branching rules for iptables (via user-ddefined chain, chain name is specified as action parameter for action 'Chain') * FWWindow.cpp (reopenFirewall): added support for policy branches. Setting rule action to "Chain" or "Anchor" (depending on platform) creates additional tab with a policy rule set. These rules represent a branch in the policy, implemented by means of a user-defined chain for iptables and anchor for pf. Chain or anchor name is set as action parameter through standard action options dialog. * FWWindow.cpp (fileSaveAs): fixed bug #1424880: "Save As" works incorrectly. "Save As" works as follows: * a new file is created with the name provided by user, this file captures the state of the object database as of the moment when user executed 'Save As' operation. * if the old file was not in RCS, then any changes made to it since it was saved to disk last time are lost. In other words, next time user opens the old file, its content will be as it was when it was saved to disk last time before using 'Save As' operation * if the old file was in RCS, then it is reverted to the head revision in RCS * fixed bug #1434321: firewall name heading incorrect after duplicate. After a firewall object is duplicated, the name of the new object as shown in the tree and in pull-down list of firewalls was incorrect. * ActionsDialog.cpp (setRule): Added GUI support for action 'Branch' (represented as 'Chain' for iptables and 'Anchor' for pf) 2006-04-30 vadim * platforms.cpp (getActionNameForPlatform): remapping names of some new actions depending on the target firewall platform. For example, action "Tag" appears as "Tag" for PF and as "Mark" for iptables. Also remapping name for actions Pipe and Accounting. This should help adoption of the new actions by people who are familiar with corresponding features of the target firewall platforms. Name mapping is done only for presentation; all internal references to actions use their abstract internal names both in the GUI and in all compilers. 2006-04-30 * PolicyCompiler_PrintRule.cpp (_printOptionalGlobalRules): fixed bug #1464806: "Global custom log prefix not applied to built in options". Autogenerated rule that blocks packets matching INVALID state will use globally set custom logging prefix. "-1" is used for the rule number; macro "%C" is replaced with the chain name "drop_invalid" * NATCompiler_pf_writers.cpp (processNext): fixed bug #1407328: "NAT / RDR Exception PF problem". "no nat" rule in PF can translate either into 'no nat' or 'no rdr', depending on what the user really needs to achieve. There is no way fwbuilder can guess right by just analysing this single rule, so it will generate both variants. 2006-04-23 vadim * SSHSession.h: fix for bug #1455772 did not work on windows where QProcess added '\0' to each line of the stream passed to the ssh client. On Unix we run fwbuilder as a wrapper for ssh client and can intercept and filter these characters but on windows we do not use wrapper and can't fix the problem that way. Better fix is to avoid QString (and therefore conversions UTF8 <-> Unicode) all together. Changed last parameter for constructor of SSHSession and derived classes from QStringList to list. Now instDialog reads script as sequence of bytes and does not convert it to Unicode, then passes to the ssh client via SSHSession as-is. In principle, this alleviates the need in the hack in main.cpp but I leave it there just in case. (Forward ported from 2.0.12) 2006-04-23 vadim * pixAdvancedDialog.cpp (displayCommands): changed title of the tab where user controls protocol inspectors from "Fixup" to "Inspect". Added a button to show commands that will be generated by the compiler for a current combination of inspector configuration, this button calls policy compiler fwb_pix and feeds XML to it via standard input. Doing this automatically every time user touches something in the inspector control widgets may be slow on underpowered machines or when the data tree is very large because the GUI needs to start external process, which reads and parses the whole XML file. 2006-04-22 vadim * pixAdvancedDialog.cpp (pixAdvancedDialog): calling fwb_pix to generate protocol inspection commands. Need to implement saving into a buffer in FWObjectDatabase to make this work. 2006-04-19 ilya * FWWindow.cpp (singleInstall): batch compile and intsall operations are possible when user selects several firewalls in the tree and uses context menu items "Compile" and "install". Selected firewalls are automatically checked in the batch install dialog. * FirewallDialog.cpp (loadFWObject): support for attribute "inactive" in Firewall. Inactive firewalls are not picked for batch compile and install operations. 2006-04-10 vadim * NATCompiler_ipf.cpp (processNext), ipfAdvancedDialog.cpp (ipfAdvancedDialog): Added support for PPTP and IRC proxies for ipfilter 2006-04-07 ilya * instDialog.cpp (selected): implemented batch compile and batch install modes. Requires some work to polish the UI but basic functionality works 2006-03-26 vadim * OSConfigurator_linux24.cpp (generateCodeForProtocolHandlers): fixed bug#1364060: "conntrack modules not found". The name of the 'conntrack' module in Linux 2.6 is 'ip_conntrack.ko' and 'ipt_conntack.ko'. Changed shell pattern to match new modules as well as old ones. * linux24.xml.in: made "chmod +x" part of the sequence that copieswall script to make the script is executable. This fixed bug #1455748: "make firewall script executable" * main.cpp (main): it appears some older versions of Qt have a bug referred to in the following article: http://lists.trolltech.com/qt-interest/2004-10/thread00024-0.html This bug causes '\0' to be appended to strings passed to/from QProcess if they are converted to/from utf-8. Added workaround in the ssh wrapper code to skip zeros. In combination with converting config file strings from/to utf-8 this fixes bug #1455772: "Problem with UTF8 Descriptions in FW Objects" * instDialog.cpp (initiateCopy): need to convert strings of the config file from utf-8 in order to be able to use methods of QString to process them. Strings are converted back to utf-8 right before they are sent to the background ssh process to be copied to the firewall in SSHSession::sendLine() 2006-03-22 vadim * PolicyCompiler_ipt.cpp (prolog): switched from Compiler::objcache to object index in FWObjectDatabase. Replaced calls to Compiler::getCachedObject with calls to FWReference::getPointer() everywhere 2006-03-20 vadim * ipf.cpp, ipt.cpp, pf.cpp, ipfw.cpp (main): added call to Preprocessor::compile() to convert DNSName and AddressTable objects before rule processing starts 2006-03-18 vadim * OSConfigurator_solaris.cpp (printPathForAllTools): fixed bug #1393004: "Solaris does not have "egrep -q". Since egrep shipped with Solaris does not have option '-q', using '-s' * ipf.cpp (main): fixed bug #1386226: "generated -nat.conf is not removed when nat rules removed.". Old fw-nat.conf was left in place when user deleted all NAT rules (the new one was not created either). Now compiler deletes *-ipf.conf and *-nat.conf files before creating new ones, also installer gets correct list of files to read. * PolicyCompiler_PrintRule.cpp (PolicyRuleToString): fixed bug #1375432: "fwb_ipt with twice -m state". Compiler used to generate options "-m state --state XYZ" twice in a situation when administrator uses custom service that already includes this code and rule is not stateless. 2006-03-15 ilya * ObjectManipulator.cpp (findFirewallsForObject): Using method findWhereUSed to find firewalls that require compile/install after an object is modified. 2006-03-15 vadim * ObjectManipulator.cpp (_findWhereUsed): generic recursive method that finds all groups and rules that use an object. 2006-03-10 ilya * ObjectManipulator.cpp (contextMenu): added temporary pop-up menu item 'simulate Install' for testing. * ObjectManipulator.cpp (__Is_Object_Ref_In_Firewall): added support for detection of firewall objects that require compile and install after any object in the tree is modified. The code keeps track of changes made to firewall's policy rules, as well as changes in all objects in the tree. After the user applies changes in an object editor, the program inspects every firewall trying to determine if the object is used in one of its rules. When one or more firewalls using this object are found, corresponding items in the tree are highlighted. Indirect usage, such as if the object is a member of a group that is used in a rule, is also detected. Multi-level group membership is detected too. 2006-03-07 vadim * All compilers: compiler prints only one 'success' message at the and of processing instead of after each section (policy, NAT etc). This makes it easier to keep track of its progress and is less confusing if it runs in a silent mode and takes a long time to process one section. Before, when it printed "Rules compiled successfully" after each section, the user could interpret this message as if compiler was done, while in fact it was still working on the next section 2006-03-06 vadim * PolicyCompiler_ipt.cpp (removeFW): restored rule processor that removes firewall object from src or dst to simplify rule if it uses OUTPUT or INPUT chain. Doing this only if original rule did not have negation and we do not add any virtual addresses for NAT. After removal the rule collapses to a simple command like this: iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT this works fine except if we have added virtual addresses for NAT. It is assumed that firewall object in rules represents combination of addresses configured in its interfaces in the GUI. Virtual addresses added for NAT are considered to be a side effect and connections should not be implicitly permitted to them by a rule with fw object in destination. The same applies to fw object in source. See bug #685947 for discussion. To avoid inadvertently opening holes in the firewall by a rule like that, we remove fw object only when it is safe to do so. 2006-03-05 vadim * PolicyCompiler_ipt.cpp (decideOnChainForClassify): setting chain to POSTROUTING for rules with action Classify. Also added checks for this action in all rule processors that split rules in order to assign them to INPUT/OUTPUT/FORWARD chains later because this is not needed for this action (since only one chain is allowed anyway) * PolicyCompiler_PrintRule.cpp (_printDstService): added checks for iptables version "1.3.0" * PolicyCompiler_PrintRule.cpp (_printDirectionAndInterface): added support for physdev module for bridging firewalls. This module is used if interface a rule is associated with is marked as bridge port and iptables version is set to 1.3.0 or later in the firewall settings. Feature Request #1000757: "bridging: using physdev" * All compilers: by default treating bridge port interfaces the same as unnumbered interfaces, unless target firewall platform provides special support for bridge ports, such as module 'physdev' in iptables * InterfaceDialog.cpp (loadFWObject): added support for bridge port interface 2006-03-04 vadim * fwbedit.cpp (main), fwblookup.cpp (main): using global variable instead of singleton FWObjectDatabase::db. FWObjectDatabase::db is not used in fwbuilder2 anywhere and can be eliminated. * FWObjectClipboard.cpp (add): must create new objects using current instance of FWObjectDatabase because it maintains internal object index. Replacing FWObjectDatabase::db with mw->db() to accomplish that * getting rid of singleton FWObjectDatabase::db in the GUI - replacing it everywhere with mw->db() 2006-02-28 Vadim * FWObjectPropertiesFactory.cpp (getObjectProperties): printing firewall's lastModified, lastCompiled and lastInstalled timestamps in the info window and in tooltips 2006-02-26 ilya * ObjectManipulator.cpp (updateLastModifiedTimestamp): added methods to keep timestamps for the moments when a Firewall has been modified, compiled and installed. Using these timestamps to provide visual indication for when a firewall needs to be installed using bold font for its name in the tree view. Will use the same mechanism to automatically suggest which firewalls to install when user hits "Install" menu item or toolbar button. Still need to implement object modification tracking to properly detect which firewall needs to be marked when an object is modified (an object can be used in a firewall rule directly or indirectly if it is a member of a group) 2006-02-19 vadim * FWWindow.cpp (reopenFirewall): the GUI shows "Routing" tab only if the corresponding policy compiler for a give host OS supports it. Using element in the res/os/OS.xml resource file. * FirewallDialog.cpp (fillVersion): fixed a bug where firewall versions would appear in a mixed order in the 'version' pull-down in firewall object dialog 2006-02-18 vadim * Added support for load balancing rules in PF * Added support for address ranges and network objects in TSrc in NAT rules for PF * Added support for pool types in NAT rules for PF ('bitmask', 'random', 'source-hash', 'round-robin') as well as 'static-port' option * PolicyCompiler_ipf_writers.cpp (_printAction): basic support for Custom action for ipfilter. Lack of examples for actions 'auth' and 'call' in ipfilter documentation or anywhere on the web makes it hard to implement right. * PolicyCompiler_ipfw_writers.cpp (_printAction): Added support for policy rule action Custom for ipfw * PolicyCompiler_ipfw_writers.cpp (_printAction): Fwbuilder policy rule action 'Classify' is mapped to ipfw actions 'pipe' or 'queue'. Fwbuilder policy rule action 'Pipe' is mapped to ipfw action 'divert' 2006-02-17 ilya * execDialog.cpp (saveLog): Added a button and function to save compile or install progress log to a file with extension .txt * killed startup wizard; the GUI starts accordingly to the setting on the first page of the Preferences dialog - it can either start up showing just standard objects library or automatically open file the user was editing last time the GUI was used. * object created using "Duplicate" menu item is automatically activated and opened in the editor 2006-02-15 vadim * PolicyCompiler_pf_writers.cpp (_printQueue): implemented support for action 'Classify' in compiler for PF, mapped to a filtering rule option 'queue _queue_name_' * PolicyCompiler_PrintRule.cpp (PrintRule): implemented support for actions 'Classify' and 'Custom' in compiler for iptables. Action 'Classify' is mapped to '-j CLASSIFY --set-class M:N'; action 'Custom' is used verbatim 2006-02-15 ilya * :version 2.1.5 * :Added new Actions 'Classify' and 'Custom'. * :Added new dialog NATRuleOptionsDialog. * RuleSetView: In NATView inserted new column "Options" for viewing of Nat Rule Options. 2006-02-11 ilya * DiscoveryDruid.cpp (checkSNMPCommunity): unified method to check validity of the host name/ip address for dns name server used for zone transfer and seed host used for snmp crawler 2006-02-09 vadim * PolicyCompiler_pf_writers.cpp (_printDstService): added support for the TagService object (using 'tagged') * PolicyCompiler_PrintRule.cpp (_printDstService): added support for the TagService service object (using --mark) 2006-02-09 ilya * DiscoveryDruid.cpp (DiscoveryDruid): improvements in the implementation of the address and name validity for snmp crawler seed host and dns server for dns zone import. Implemented support for IP aliases in snmp crawler 2006-02-05 ilya * DiscoveryDruid.cpp (save): saving/restoring parameters of the DiscoveryDruid between sessions 2006-01-27 ilya * DiscoveryDruid.cpp (changedSelected): proper implementation of long/short name generation for dns zone import; proper checks for correctness of the seed host address for snmp crawler; showing number of interfaces in discovered hosts on the results page 2006-01-21 vadim * gui.pro (IMAGES): grand icons clean-up and update. Removed old unused icons and images, added new icon theme by Irina Filvarova 2006-01-20 ilya * DiscoveryDruid.cpp (changedSelected): working version of discovey druid. Got rid of all calls to setModal, hence workarounds defined in qt_workarounds.h are not needed anymore 2006-01-16 vadim * DiscoveryDruid.cpp (stripObjects): minor formatting cleanup in DiscoveryDruid; fixed typos in DiscoveryDruid ('wasCanceled' -> 'wasCancelled'); refactored #includes to improve compilation speed in DiscoveryDruid * DiscoveryDruid.cpp: had to move '#include "DiscoveryDruid.h"' below all qt #include's to make code compile on windows. When this #include was above qt includes, compiler would stop with an error: ------------------------------------------------------------ C:\Qt\3.3.1\include\qlistbox.h(139) : warning C4003: not enough actual parameter s for macro 'index' C:\Qt\3.3.1\include\qlistbox.h(139) : error C2059: syntax error : ')' C:\Qt\3.3.1\include\qlistbox.h(139) : error C2143: syntax error : missing ')' be fore ';' ------------------------------------------------------------ I haven't figured out where does 'index' macro come from * discoverydruid_q.ui.h: added workarounds for missing QDialog::setModal in QT 3.1 * FWWindow.cpp (doCompile): since we now package platform and os resource files with externally packaged compilers, we do not need to use "-r" flag while calling compilers anymore 2006-01-10 ilya * DiscoveryDruid.cpp (startHostsScan): implemented object import from a file in "/etc/hosts" format. This includes druid page where user selects objects from the list, a page where they can assign object type for each record and a page where they chose a library new objects should be part of 2006-01-07 vadim * PolicyCompiler_ipfw_writers.cpp (_printAction): support for action Pipe in ipfw. This action can be implemented using "divert", "pipe" or "queue" rule actions in ipfw; the method is chosen using rule action parameters dialog in the GUI. * ActionsDialog.cpp (setRule): support for action Pipe for ipfw in the GUI. * PolicyCompiler_pf_writers.cpp (_printAction): added support for Tag action for PF 2006-01-03 vadim * ipt.cpp (main): implemented checks for the situation when compiler produces an empty script. In such cases we avoid printing any header or commit commands (such as '*mangle' and 'COMMIT' if iptables-restore format is used) * PolicyCompiler_ipt.cpp (processNext): implemented support for QUEUE target in compiler for iptables. Commands with this target are generated for fwbuilder rules with action "Pipe" * MangleTableCompiler_ipt.h: Implemented support for MARK target for iptables. Iptables commands with target MARK are generated for fwbuilder rules using action "Tag". Rules are placed in INPUT,OUTPUT and FORWARD chain of the "mangle" table, this ensures that DNAT happens before rules placed in the mangle table see the packet. PREROUTING chain in mangle table is executed before PREROUTING chain in the nat table, so placing tagging rules in the PREROUTING chain would make them fire before DNAT. POSTROUTING chain of the mangle table, as well as its FORWARD and OUTPUT chains, work before corresponding chains of the nat table. In all cases the goal is to make sure DNAT rules process the packet before, and SNAT rules process it after filtering and tagging rules. * AddressTableDialog.cpp (preview): AddressTable dialog "preview" function looks for the table file in the same directory as currently opened data file if file name is entered as relative path 2005-12-16 ilya * FWObjectPropertiesFactory.cpp : For objects of type 'interface' a path to library is included in "detailed properties". * FWWindow.cpp : Added new menu "/tools/Discovery Druid" * DiscoveryDruid.cpp : Created basic gui for Discovery druid 2005-12-16 ilya * SimpleTextView.cpp: new custom text viewer. * AddressTableDialog.cpp: file preview uses SimpleTextView. * newfirewalldialog_q.ui: Dialog size fixed (now all internal widgets are visible) * fwbedit.cpp : fixed run with unknown options. Added a new option: -u - interactive file upgrade 2005-12-14 ilya * Added detailed tooltips for rule options for all fw platforms * Redrawing policy view if user changes firewall version; this ensures that icon that indicates non-default rule options is correctly updated in case different versions of the same fw platform support different combinations of rule options. * Redesigned page of the new host dialog where user adds interfaces manually. Before buttons "add","Update","remove" were hidden because dialog was too small. 2005-12-13 vadim * po.pro: Added Swedish translation made by Daniel Nylander 2005-12-13 ilya * RuleSetView.cpp (maybeTip): added tooltips for rule elements Action and Options 2005-12-02 vadim * NATCompiler_ipf.cpp (processNext): Run-time AddressTable objects are not supported in ipfilter; added a placeholder for corresponding rule processors, aborting compilation when such object is detected in a rule * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug #1361564: "Prolog script env settings unavailable". Need to define env variables IPTABLES, LSMOD etc before prolog. (OSConfigurator_linux24::printChecksForRunTimeAddressTables): compiler for iptables inserts shell code to ensure that data files used in run-time AddressTable objects are present before firewall policy is activated. * PolicyCompiler_PrintRule.cpp (processNext): implemented run-time mode for AddressTable object in compiler for iptables. Current implementation *dos not* emulate dynamic table reloads as can be done for PF using "pfctl -t table -Treplace" command. The whole policy script must be run again if data file AddressTable object refers to changes. Current implementation does not allow comments in the data file 2005-12-01 ilya * version 2.1.4 * new object type TagService Actions 'Mark' and 'Queue' renamed as 'Tag' and 'Pipe' respectively. * fwbedit.cpp: fixing of absent 'TagServices' group added. * ActionsDialog.cpp: new actions control dialog * RuleSetView.cpp: changed actions context menu to use new parameters dialog (support of actions with parameters). 2005-11-24 vadim * PolicyCompiler_pf.cpp (processNext): added support for run-time AddressTable objects for PF. * PolicyCompiler_pf (PrintRule::_printAddr) * TableFactory.cpp (TableFactory::PrintTables): support for DNSName run-time mode in compiler for pf, ipfw and ipf * PolicyCompiler_PrintRule.cpp (_printAddr): support for DNSName run-time mode in compiler for iptables 2005-11-23 Vadim * AddressTable object dialog 2005-11-22 vadim * TableFactory.cpp (createTablesForRE): class TableFactory reuses existing tables separately for NAT and policy rules. Reuse of tables created for NAT in the policy rules is difficult because tables themselves are created in the temporary copy of the tree in the NAT compiler (the same applies to the objects - members of the tables) 2005-11-21 vadim * NATCompiler_pf_writers.cpp (_printAddr): Improvement in the compiler for PF: using '!' syntax for one-object negations * NATCompiler_pf.cpp (CeateTables): Improvement in the compiler for PF: Using tables for NAT rules * TableFactory.cpp (createTablesForRE): using the same class to generate tables for both policy and NAT rules for pf. Table names are composed using rule positions so that table names do not change between compiler runs (they used to change because they were created using rule IDs, which changed because compiler generated lots of copies of rules) 2005-11-14 Vadim * version 2.1.3 new object type DNSName using this method in Compiler::prolog to resolve DNSName objects that are supposed to be resolved at compile-time Redesigned RuleOptionsDialog to make room for new options Added actions MARK and QUEUE with basic support in API and GUI Added new object type AddressTable 2005-11-05 vadim * iptAdvancedDialog.cpp (iptAdvancedDialog): fixed bug #1349326 "ulogd option does not work". There was a typo in the class iptAdvancedDialog ( useULOG instead of use_ULOG ) *** Ported from 2.0.10 *** 2005-11-01 vadim * NATCompiler_ipt.cpp (processNext): fixed bug #1342495: "SNAT with address range". Compiler used to print warning "Adding virtual addresses for NAT is not supported for address range" even if adding virtual addresses for NAT was turned off. *** Ported from 2.0.10 *** 2005-10-26 vadim * PolicyCompiler_ipt.cpp (processNext): fixed bug #1313420: "OUTPUT chain is built wrong under certain conditions." Rules that have firewall in SRC and DST, while DST has negation, should be split so that the second generated rule goes into OUTPUT chain rather than FORWARD *** Ported from 2.0.10 *** 2005-10-24 vadim * FirewallDialog.cpp (openFWDialog): fixed bug #1315892: "fwbuilder crashes on missing OS template" The GUI crashed if user added new hostOS or firewall platform template under resources/os or resources/platforms, then reinstalled the package (and therefore lost their custom template files), then tried to open firewall or host OS settings dialog for the object using new template. *** Ported from 2.0.10 *** * RuleOptionsDialog.cpp (loadFWObject): fixed bug #1305933: "fwbuilder/Solaris: compilation errors". Another case of implicit type conversion QString->string which does not compile on systems with QT built w/o STL support. *** Ported from 2.0.10 *** * main.cpp: fixed bug #1304878: fwbuilder: signal.h required (Solaris). Using 'AC_CHECK_HEADERS([signal.h])' in configure.in to check for the appropriate #include. *** Ported from 2.0.10 *** * configure.in: fixed bug #1304764: "configure script: Sun make check fails". Need to use ${MAKE-make} instead of $ac_make when checking for GNU make. *** Ported from 2.0.10 *** * fixed bug #1304785: "fwbuilder - Solaris has no libutil". Using better way to check whether we need to link with libutil. *** Ported from 2.0.10 *** 2005-10-22 vadim * VERSION: set version to 2.0.10 in branch fwb2-2.0-maint 2005-09-29 Vadim * PolicyCompiler_ipt.cpp (InterfacePolicyRulesWithOptimization): new rule processor: checks if the rule is associated with an interface and uses setInterfaceId to record its id. If the rule is associated with multiple interfaces, splits the rule accordingly. Unlike basic processor PolicyCompiler::InterfacePolicyrules, this processor tries to optimize rules applied to multiple interfaces using user-defined chain ***** Policy compilers support multiple interfaces and negation in "Interface" rule element 2005-09-28 Vadim * RuleSetView.cpp (paintCell): merged interface policies with global policy. Keeping most of the code that implements interface policy tabs just in case. * set version to 2.1.2 2005-09-26 Vadim * RoutingRuleOptionsDialog.cpp (loadFWObject): Added support for routing rules. Using "fwbuilder-routing" patch provided by Tidei Maurizio * set version to 2.1.1 * ObjectManipulator.cpp (createObject),(newDNSName), newHostDialog.cpp (accept): added checks for broken object tree 2005-09-20 * DNSNameDialog.cpp (loadFWObject): new object type: DNSName (Illiya) 2005-09-17 * 2.0.9 release in branch fwb2-2.0-maint 2005-09-12 * fwsm.xml.in: Added support for Cisco FWSM (platform and host OS) * pixAdvancedDialog.cpp (pixAdvancedDialog): Added support for manual ACL commit in FWSM 2005-09-11 * SSHPIX.cpp (SSHPIX): enable_prompt should include string "Access Rules Download Complete" which is _sometimes_ printed by FWSM when in auto-commit mode. 2005-09-07 * ObjectManipulator.cpp (lockObject): Added ability to lock/unlock individual objects in the tree (Illiya) * GroupObjectDialog.cpp (listViewSelectionChanged): Illiya implemented Feature Req #1151208: "Allow multiple objects select to make an action (Group)" 2005-09-07 * SSHSession.cpp (cmpPrompt): overloaded method SSHSession::cmpPrompt to be able to specify prompt as a regular expression. This variant is very convenient for PIX prompts. 2005-09-05 * fixed bug #1254775: "RCS checkin fails on Windows when data file is too big". RCS tools failed to check the file in if it consisted of one huge line of text. This fix makes th GUI save data file (.fwb) in formatted form on Windows, just like on Linux. This means each XML element is saved on separate line instead of all of them being on the same line. 2005-09-04 * NATCompiler_pf.cpp (processNext): fixed bug #1276083: "Destination NAT rules". Old restriction on "rdr" rules that required service in OSrv is not valid anymore, pf supports rdr rules with no protocol specification. (ported from 2.0.9) 2005-09-04 Vadim Kurland * FWWindow.cpp (fileCommit): properly handling situation when user hits Cancel in check-in log dialog (should abort File/Commit operation entirely) * main.cpp (main): added a workaround to make the GUI work in Spanish locale (QT 3.3.4 ships with broken qt_es.qm file at least on Fedora-C4 and Mac OS X) 2005-08-31 * SSHUnx.cpp (stateMachine): fixed bug #1277129: "script is truncated when installed by the GUI running on Mac". Large script was getting truncated while copied to the firewall if GUI was running on Mac OS X (bugfix ported from 2.0.9) 2005-08-17 * fwbedit.cpp (usage): Finished implementation of RFE #1211612 "fwbedit - add object?". Using "-p","-L","n" and "-o" command line switches to specify parent, library, name and attributes of an object 2005-08-04 * fwbedit.cpp (main): Illiya is working on RFE #1211612: "fwbedit - add object?" and #1114501: "Data file repair". Fwbedit can now add objects as well as repair tree structure. Still needs some more work. 2005-07-31 * LINGUAS: Added Spanish translation, thanks to Carlos Lozano 2005-07-30 * Started v2.1.0 2005-07-30 * FWWindow.cpp (fileCommit): Illya implemented Feature Request #1187461 "Add "commit" menu item". This menu item commits opened data file to RCS but keeps it opened so the user can continue editing. 2005-07-29 * FWWindowPrint.cpp (addObjectsToTable): Illiya implemented Feature Request #1225393 "FeatureRequest Print comments on objects" 2005-07-23 * RuleSetView.cpp (dragMoveEvent): Illiya fixed bug #1226069: "Segfault: Drag&Drop between two instances" 2005-07-21 * platforms.cpp (getLogFacilities): Illiya moved definitions of log levels, log facilities and actions on reject to module platforms.cpp. Methods getLogLevel, getLogFacilities and getActionsOnReject return string lists suitable for using with DialogData to provide mapping between localized and english strings so that the user sees translated ones but enlish ones are written into FWOptions object and used by compilers. This fixes bugs #1240205: "Iilegal --log-level Information" and #1233165: "Illegal Logging-Limit string.". 2005-07-08 v2.0.8 released 2005-07-05 * SSHSession.cpp (allDataSent): calling allDataSent from heartBeat slot method because on windows signal 'wroteToStdin' is emitted before I had a chance to connect it to a slot in SSHUnx::stateMachine in state PUSHING_CONFIG after entire file has been transmitted. I used to send an extra '\n' to force signal 'wroteToStdin', but that made the file to be sligltly different on the receiving end and I do not like that. * RuleSetView.cpp (dragMoveEvent): not really a change: bug 1226069 "Segfault: Drag&Drop between two instances" requires redesign of the drag&drop mechanism so that live pointer to FWObject is not passed between sender and receiver. 2005-07-04 * SSHSession.cpp (startSession): fixed bug #1232478: "FWB shuts down on incorrect password". Bug was intorduced in build 624 while working on installer stalls and undescriptive ssh termination error when OpenSSH 4.0 was used. 2005-07-02 Vadim Kurland * main.cpp (main): ignore SIGHUP in the child process in ssh wrapper. Closing stdin at the end of the file copy sends SIGHUP to the child. By some reason, this caused ssh to terminate with error message "killed by signal 1" and return code 255 on Fedora C4 which uses OpenSSH v4.0p1 2005-07-02 * main.cpp (tty_raw): switched from TCSAFLUSH to TCSANOW in call to tcsetattr when we switch tty to raw mode in ssh wrapper code. This should fix mysterious stalls in the installer that were introduced when I worked on the wrapper code to fix bug #1213361 (problems with file copies on FreeBSD 5.4) * instDialog.cpp (initiateCopy): added missing "-v" option to ssh call used to copy policy script to the firewall if "verbose" checkbox is checked. This should help troubleshoot problems with installer when ssh fails and terminates with an error. 2005-06-25 * configure.in: need to call macro AC_PROG_MAKE_SET before using $ac_make to check for GNU make * configure.in: added check for cfmakeraw (which is absent on Solaris) * configure.in: make script continue if forkpty is not found, the program will use emulation. 2005-06-13 * FWObjectPropertiesFactory.cpp (getObjectPropertiesDetailed): sorting list of objects for tooltips. Sorting is done by object name, alphabetically. TODO: use locale-aware sort and ignore case of the letters. 2005-06-12 * main.cpp (main): need to switch the pipe and stdin in the child process to raw mode in order to ensure proper communication when fwbuilder works in ssh wrapper mode. This (really) fixes bug #1213361 * configure.in: Added path to QT where it is installed on 64-bit systems to the list configure tries while searching for QT 2005-06-11 * PolicyCompiler_ipt.cpp (processNext): fixed bug #1215279: "rate limiting rule logs everything". Rule utlilizing "limit" module to rate limit packets with logging logged every packet and dropped those that exceeded the limit. The fix makes it apply the limit first and then log only packets that were dropped. * main.cpp (forkpty): fixed bug #1072842: "fwbuilder: Solaris and forkpty". We need forkpty fr built-in installer but this function is not awailable on Solaris. I am adding re-implementation, but it hasn't been tested since I do not have Solaris machine. * FWObjectPropertiesFactory.cpp (getObjectPropertiesDetailed): fixed bug #1212179: "tool tips for TCP services cuts off some services". The gui would show very long tooltip for large groups; if the group was too large, the tooltip did not fit on the screen. * main.cpp (main): fixed bug #1213361: "PF on FreeBSD-5.4R". Bug description is misleading, the probem was caused by built-in installer rather than by compiler for PF. Installer would not copy generated script over ssh if the script was longer than some threshold and the gui was running on FreeBSD. 2005-06-05 * linux24.xml.in: fixed bug #1212121: "sudo shutdown doesn't work". Installer needs to schedule reboot when the user activates policy in a test mode. There was a bug in the installer script that improperly used sudo to run shutdown when installation was performed using regular user account. * linux24.xml.in: fixed bug #1212123: "executing file below /tmp as root". Avoiding world-writable directory /tmp/ while activating policy in the test mode. This change makes installer use subdirectory "tmp" under directory specified in the "intaller" tab of firewall settings dialog. That directory is expected to have proper permissions; subdirectory "tmp" can be created manually, otherwise installer creates it. Either way, it is not world-writable, therefore unauthorized users can not create scripts in it. * freebsd.xml.in: Using pkill to find running shutdown process and kill it to cancel pending reboot. Pkill simplifies the scriptlet so we don't need to deal with output redirection etc. Pkill is available on FreeBSD, Linux, OpenBSD and Solaris. * linux24.xml.in: another fix for a bug #1201406: "shutdown messages should be suppressed". Scriptlet has been modified to make sure it works in both sh and csh (user who installs the policy may have tcsh as their login shell, root may use tcsh too) 2005-05-30 * src/res/os/*.xml.in: fixed bug #1201406: "shutdown messages should be suppressed". Installation scriptlet tries to kill shutdown process, if there is one, to cancel pending shutdown that might have been left over from test install. If there is none, the script prints an error message "shutdown process not found" or similar, which confuses user. Needed to suppress these error messages. * fixed bug #1155351: "Remote install of FW rulset fails due to race condition". Generated ipfw firewall script could not be ran reliably over ssh session because "ipfw -f" flushes all rules and all state, which breaks ssh session. As soon as the script needed to print anything, it got I/O error from the system because TCP session for ssh was blocked; this stopped the script and did not let it activate new firewall policy. * PolicyCompiler_ipfw_writers.cpp (processNext): improvemet in the compiler for ipfw: added "established" rule on top of the regular backup ssh access rule; this allows to maintain management ssh session after the policy is reloaded. both "ipfw -f" and swapping sets flushes all states, so the ssh session used to upload and activate new policy breaks. A rule with "established" keyword maintains this session. * PolicyCompiler_ipfw_writers.cpp (processNext): improvement in the compiler for ipfw: using rule sets to atomically swap old and new rules. New rules are loaded in the set 1 and then swapped into set 0. If there is an error in a new rule set, it is caught while loading rules into inactive set 1, at which point script stops without changing old firewall rules. * PolicyCompiler_pf.cpp (addDefaultPolicyRule): implemented support for subnets for backup ssh access for pf,ipf,ipfw. Subnet can be defined using either full netmask or bitlength: both "192.168.1.0/255.255.255.0" and "192.168.1.0/24" are acceptable. Single host address works too, both as "192.168.1.10" and as "192.168.1.10/255.255.255.255" or "192.168.1.10/32". Incorrect address or netmask cause compiler to abort processing. 2005-05-28 * GroupDialog: fixed bug #1207983: "incorrect size of "I" and "L" buttons in the group view dialog". Tested with large font and cleaned up layout in many dialogs. * HostDialog.cpp (loadFWObject): removed 'snmp community' option from the Host object dialog - it was not used anywhere * ipt.cpp (main): fixed bug #1205665: "Error with summer time when compiling script". Sometimes timezone name has "'" in it which confuses shell and causes an error when generated script prints "Activating firewall policy..." log message * RCS.cpp (RCSEnvFix): fixed bug #1204067: "incorrect timezone handling in RCS". Windows version of RCS incorrectly converts check-in time when time zone is east of GMT. Had to use "-z" option on all RCS commands to explicitly set offset; "-zLT" produces wrong results in rlog. * fwb_compile_all (LIB): fixed bug #1200902: "fwb_compile_all does not work in 2.0". Script fwb_compile_all broke because of changes in data file format * PolicyCompiler_PrintRule.cpp (_printTimeInterval): fixed bug #191423: "Weekend Time restriction not created correctly". Rules with time restriction spanning from Saturday to Sunday were generated with incorrect "--day" option * objects_init.xml.in: fixed bug #210518: 'Incorrect ending day in the standard object "weekends"'. This object defined time interval ending at 23:59 on Monday instead of Sunday * implemented Feature Request #1145666: "Print RCS Log". File/Properties dialog can now print RCS log. Thanks to "Ilya V. Yalovoy" for the patch. 2005-05-23 * added updated German translation by Hans Peter Dittler 2005-05-20 * set version to 2.0.8 2005-05-08 * v2.0.7 released 2005-05-04 * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug #1195201: "getaddr function return error ip address". Yet another change in the way we use grep to find IP addresses of an interface on Linux. We can't use regex (bug #1123748) and need to filter out secondary addresses from the "ip addr show" output. It looks like "grep -v :" neatly solves the problem without using regex. 2005-05-02 * snmp.cpp: API change: Compiled all OIDs. The program may run on a system where MIBs are not installed, so we can not always use symbolic OID names Also using snmp_out_toggle_options to turn numeric output in all responses (equivalent to -On in snmp tools) 2005-05-01 * snmp.cpp (walk): API changes: verbose error message, printing response->errstat code as well as corresponding error string; this should help debug snmp -related problems better * snmp.cpp (walk): API changes: using snmp_error to print last snmp error string 2005-04-27 * implemented support for SNMP operations in Windows packages * qmake.inc files overhaul 2005-04-26 * newFirewallDialog.cpp (getInterfacesViaSNMP): switched to using QT class DNS to get host/firewall name in new HostDialog and newFirewallDialog classes. This seems to work better on Windows. Also added more locks to prevent reentering getInterfacesViaSNMP if user clicks the button multiple times in quick succession 2005-04-23 * newFirewallDialog.cpp (accept): fixed bug #1187248: using "find" for an address "192.168.10*" several times after a firewall objects has been created using templates caused GUI to crash 2005-04-17 * findDialog.cpp (matchAttr): implemented feature request #1151206: "Search for IP Addresses". "Find" dialog searches for objects by a combination of name and one of the following attributes: address, tcp/udp port, ip protocol number or icmp message type. Regular expressions can be used for both name and attribute. * ObjectTreeView.cpp (getSimplifiedSelection): fixed bug #1151212: "Collapsed sub-objects shouldn't be added if they are hidden". When user selects multiple objects in the tree some of which have child objects, those child objects used to be also selected and added to groups in addition to their parent objects via drag-and-drop operation. * GroupObjectDialog.cpp (pasteObj): fixed bug #1184791: "can not copy/paste multiple objects into a group" * FWWindow.cpp (doCompile): implemented feature req. #1151220: "Close" button should change is caption/title to "Install". When user clicks "Install" toolbar button or main menu item, the "Close" button in the pop-up window that displays compiler progress changes its text caption to "Install" 2005-04-13 * PolicyCompiler_ipt.cpp (addPredefinedPolicyRules): fixed bug #1181359: "Missing traling space in "INVALID state" syslog message" 2005-04-10 * instDialog.cpp (continueRun): Improvement in built-in installer: user can specify additional command line parameters for ssh that built-in installer runs to access firewall. This allows for alternative ssh port or alternative ssh identity to be used when accessing firewall. Parameters can be added in the "Installer" tab of firewall settings dialog for all platforms. 2005-04-09 * ipt.cpp (main): fixed bug #1179103: 'compiled rules can not be install'. Generated iptables script could not be used on systems with non-English locale where timezone name used local characters because these characters were printed as hex ( "台" ) and '&' caused problems with shell. Now using single quotes to make shell ignore any characters in the string. Will deal with proper printing of localazed timezone later. 2005-04-07 * OSConfigurator_freebsd.cpp (printPathForAllTools): function getaddr() falls back to 0.0.0.0/32 if dynamic interface has not been assigned an address yet or is down. Ipfilter policy using run-time substitution of dynamic interface addresses will be functional even if these interfaces are down or do not have IP address. 2005-04-05 * PolicyCompiler_PrintRule.cpp (_flushAndSetDefaultPolicy): fixed bug #1176890: "block IPv6". Generated iptables script sets default policies to DROP in all ipv6 filter chains. More detailed control can be implemented using prolog or epilog scripts. 2005-04-03 * PolicyCompiler_pf.cpp (separateSrcPort): fixed bug #1176051: "incorrect rule generated for TCP service ftp-data". If a rule used several TCP or UDP service objects and one of them has source port range configured, generated PF filter rule incorrectly matched on a combiantion of that source port range _and_ destination port ranges from all other service objects. This bug affected compilers for OpenBSD PF and ipfilter 2005-03-31 * FWWindowPrint.cpp (filePrint): fixed bug #1155163: "print does not print group contents". The program printed only number of objects contaned in object or service groups. Now it prints lists of member objects for all groups used in rules. If groups contain other groups, they are printed recursively. 2005-03-30 * objects_init.xml.in: fixed bug #1172620: "Add tcp service object for icslap". Added this object to the objects library "Standard". * FWWindow.cpp (info): fixed bug #1151243: "Maintain format of description text". The GUI ignored text formatting in object comment when displayed it in the info panel (lower left corner of the main windows) * FWOptions.cpp (toXML): API change: fixed bug #1173801: '"&" character in prolog/epilog'. Needed to call xmlEncodeSpecialChars to encode special characters in firewall options 2005-03-29 * ipf.cpp (printActivationCommandWithSubstitution): fixed bug #1173064: "support for dynamic interfaces in ipfilter". Actual address of dynamic interface is now determined at run-time in the policy activation script .fw generated by fwbuilder. If dynamic interface is used somewhere in the policy or nat rules, it will be replaced with its actual address by activation script before configuration is sent to ipf or ipnat for activation. This run-time substitution is done only if a checkbox is checked in the "Script options" tab of firewall settings dialog. Default behavior is to use "any". This is because ipfilter configuration files -ipf.conf and -nat.conf that rely on run-time substitution of dynamic interface address can not be loaded using standard activation scripts that come with FreeBSD. This also fixes another problem in fwb_ipf where it generated rdr and nat commands with address 0.0.0.0/32 if dynamic interface was used in a NAT rule. 2005-03-28 vadim * PolicyCompiler_PrintRule.cpp (_printMultiport): fixed bug #1160186: 'IPTables Compiler - Multiport Issue'. When 16 or 31 ports were used in a single rule, compiler generated command with conflicting options "-m multiport --dport" * NATCompiler_ipf.cpp (processNext): fixed bug #1173067: "support for port ranges in NAT rules (ipfilter)" - policy compiler for ipfilter should split DNAT rules (rdr) that use TCP or UDP objects with port ranges. A warning is issued if more than 20 rules are created. 2005-03-20 * utils.cpp (getFileDir): fixed bug #1157976: "patches to make fwbuilder compile under NetBSD 1.6". Applied patches. * newHostDialog.cpp (newHostDialog): fixed bug #1151219: "New Host creation window is not well dimensioned". Fixed wrong dialog page layout in the new host wizard. * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug #1123748: "busybox grep -E". Busybox in floppyfw is compiled without support for egrep (or grep -E). Switched to using "plain" grep. * InterfaceDialog.cpp (loadFWObject): fixed bug #1151052: "Not external interfaces marked as external". Dialog for an interface object that belongs to a host should not show checkbox "external (insecure) interface" * Tools.cpp: API change: fixed bug #1158870: "mutexes are not properly created on FreeBSD". Mutexes gethostbyname_mutex and gethostbyaddr_mutex were never created but used on OS where thread-safe resolver is not available. 2005-02-17 * v2.0.6 released 2005-02-17 * ipt.cpp (main): fixed bug #1123933 "iptables add_addr() expr binary not found". As it turns out, /usr/bin/ is not in PATH during boot time on Slackware. I added /usr/bin/ to PATH variable in generated iptables script. 2005-02-16 * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug #1123748 "busybox grep -E". Busybox does not support option "-E" with grep, however it has "egrep". 2005-02-12 * instDialog.cpp (instDialog): proper localization in the installer where it displays progress of the installation operation 2005-02-11 * main.cpp (main): Troubleshooting weird case of data file corruption during install * RCS.cpp (RCS): fixed bug #1120904: "GUI hangs when accessing RCS file". Improved parsing of rlog output. 2005-02-09 * utils.cpp (getUserName): working on bug #1118717: "fwbuilder 206 on Windows XP SP2: error checking out". Env variable USERNAME was not set in user's profile, which triggered this bug. Now using getuid to get user name on Unix and GetUserName on Windows. This should make the program more resilient for situations when environment variable LOGNAME or USERNAME is not set 2005-02-08 * ipt.cpp (main): Using getuid to read real user's ID on Unix 2005-02-07 * instDialog.cpp (continueRun): Fix for support request #1118039: "Error when Windows client calls plink -ssh". The problem is that putty ignores protocol and port specified in the session file if command line option -ssh is given. On the other hand, the sign of session usage is an empty user name, so we can check for that. If user name is empty, then putty will use current Windows account name to log in to the firewall and this is unlikely to work anyway. This seems to be a decent workaround. * printerStream.cpp (printQTable): further bugfixes in printing, in particular fixed a problem with partially greyed-out horizontal and vertical headers when ruleset was small enough to fit on the first page. 2005-02-05 * RuleSetView.cpp (selectionChanged): fixed bug #1030538: "incorrect highlighting when selecting multiple rules". This bug seems to be specific to Mac OS X * printerStream.cpp (printQTable): improvements in printing: - if a rule set does not fit on a single page, the program repeats table header on each page ("Source","Destination","Service" etc) - the program does not draw the whole rule set in memory anymore. Instead, it "scrolls" the table and only draws section that fits on a single page. This means we can now print really huge policies that can not be drawn as a whole because they exceed maximum coordinate value. Tested with a rule set that consists of 1200 rules which has size of 677x34884 pixels on my machine. 2005-02-03 * instDialog.cpp (selected): working on bug #1115412: "Problem installer FWbuilder 2.0.5 for Windows". Switched to command line option "-l" to specify user name for external ssh in installer. This was necessary because Van Dyke SecureCRT on Windows does not support user@host syntax. * instDialog.cpp: Installer verbose and quiet modes work as follows: - if quiet is off, verbose is off: prints everything that firewall script prints on stdout and stderr; does not add "-v" to calls to external ssh utilities - if quiet is off, verbose is on: adds "-v" to ssh command line - if quiet is on - supresses script output but still prints short messages to indicate when it copies files to the firewall and when it executes them 2005-02-01 * ObjectManipulator.cpp (delObj): slightly changed logic with user warnings in the object removal code. The program asks the user for confirmation if they remove an ordinary object from a regular library. Confirmation is not asked if object is removed from "Deleted objects" library or when a library is being deleted (in this case we ask a different quastion later anyway). This helps avoid double warning when a library is deleted. 2005-01-31 * POmakefile.in (POTFILES): Added module FWWindowPrint.cpp to the list of files processed for localization * FWWindowPrint.cpp (filePrint): Added small margin inside table cells in Legend and Object tables in the printout. 2005-01-30 * PolicyCompiler_ipt.cpp (processNext): fixed bug #1112470: "Problem with FW part of ANY in Bridged mode". If fw is considered part of any, we should place rule in INPUT/OUTPUT chains even if it is a bridging fw since fw itself may send or receive packets. * PolicyCompiler_ipt.cpp (accounting): implemented feature req. #1112980: "Need unique names for accounting rules". User can now specify a unique name for rules with action 'Accounting'; this name will be converted to a chain name. This simplifies accounting since chain name for such rule won't change if the user adds or removes rules above or below. * PolicyCompiler_ipt.cpp (accounting): fixed bug #1112976: "Accounting rule with logging produces looped iptables command" * FWWindowPrint.cpp (beginPage): implemented Feature Req. #1112778: "include date and time on printouts". Added date and time to the header on each printed page. * RuleSetView.cpp (paintCell): fixed bug #1112776: "some items touching seperator lines on printouts". Rule elements "Action", "Direction", "Options" and "Comment" were placed right at the top of the table cell which led to their clipping when rule set was printed on Mac OS X. Need more testing. * FWWindowPrint.cpp (filePrint): fixed bug #1112764: "some Objects are partially obscured in printout". Parts of the "Objects" table were clipped. Need to test some more. 2005-01-29 * FWBSettings.cpp (init): fixed bug #1112264: "Load last edited file" setting doesn't work. This was broken only on Mac OS X. * FWObjectDatabase.cpp (merge): API change: fixed bug #1105167: "Crash when importing a library that has been deleted". 2005-01-27 * NATCompiler_pf_writers.cpp (_printPort): not quite fixed bug #1105755 "Custom Service objects not working for PF compiler". User tried to generate a nat rule like this using CustomService object: nat on eth1 proto {tcp udp icmp gre} from 192.168.1.0/24 to any -> 22.22.22.22 Taken from the bug report: it turned out, I can not fix this. You are trying to use Custom Service object to insert protocol list into a "nat" rule. Normally, a service object such as TCP or UDP service generates two components for any rule where it is used: a protocol specification and port specification (type/ code spec for ICMP). PF is sensitive to the order of parameters in the rule, in particular, protocol must be defined after interface but before src/dst addresses in the rule, while port numbers go after addresses. Compiler easily retrieves this information from IP, TCP, UDP and ICMP services and places it in a proper slots in the rule it generates. CustomService does not have a notion of protocol and parameters for it, so compiler puts a string that is configured in the CustomService in the place reserved for port numbers. This means you can not use CustomService to specify protocols. There still was a bug in fwb_pf where it would print "custom_service" in place of protocol. This is fixed in 2.0.6 build 542. Protocols can not be inserted with Custom Service though. Feature request #1111267 "CustomService should specify protocol and parameters for it" has been opened * PolicyCompiler_ipt.cpp (processNext): fixed bug #1102629: "lost chain in accounting rules". Rules with multiple objects in one of the rule elements and action 'Accounting' generated code that ignored objects in that rule element * ObjectManipulator.cpp (newPhysicalAddress): fixed bug #1111244 "GUI allows to add more than one MAC address to an interface". There can only be one MAC address for each interface. * FWWindowPrint.cpp (printQTable): While printing rule sets, the program makes sure rule set tables are broken on the rule boundaries while switching to a new page. * Added "Page setup" dialog to set parameters such as printing header, printing of a legend and object lists etc. * fixed bug #1109174: "Cannot print rule base" - implemented printing 2005-01-25 * instDialog.cpp (selected): fixed bug #1109631: "can not copy firewall script to /etc on Linksys". Added an option ot all OS resource files that determines whether user is allowed to change installation directory on the firewall. Currently it is allowed on all supported OS except Linksys/Sveasoft because there /etc/ resides on read-only filesystem 2005-01-24 * PolicyCompiler_ipt.cpp (processNext): fixed bug #1101910: "Samba problem with Bridged Firewall". Need to split rule to take care of broadcasts forwarded by the bridge and broadcasts that are accepted by the firewall itself. Need to do this only if the rule is not associated with any bridging interface. * PolicyCompiler_PrintRule.cpp (_printOptionalGlobalRules): fixed bug #1106701: 'backup ssh access' and statefulness interation. Need to add rules matching states ESTABLISHED and RELATED for the backup ssh access to make sure it works even if global rule matching these states is disabled. * configure.in: fixed bug #1107838: "bug in configure script in fwbuilder 2.0.6". Need to specify path "./" when calling runqmake.sh * FWWindowPrint.cpp (filePrint): printing legend and a list of objects at the bottom of a printed document. * Compiler_ops.cpp (operator==): API change: fixed bug #1108861: "two rules using MAC address matching shadow each other". Need to check for MAC addresses while processing rules for shadowing. 2005-01-21 * FWWindowPrint.cpp (filePrint): Implemented printing of firewall rule sets. Using standard QT class QPrinter; can print to a system printers or to a file (PostScript), both in black and white or a color where available. Prints policies of the currently opened firewall. The program can calculate total number of pages and offer the user a choice in the Print dialog only if QT v3.2 and later is used. Each printed page has a header with the file name, RCS revision and a page number. Currently, the header can not be turned off (will implement in the future). 2005-01-07 * v2.0.5 released 2005-01-06 * RCS.cpp (isDiff): writing RCS log in UTF-8, this simplified localization 2005-01-02 * RCS.cpp (RCS): working on localization of RCS log entries. Build 516 converts log strings into 8bit string into locale-specific format on Unix before sending it to ci. Strings returned by rlog are converted from locale-specific format. No conversion is done on Windows and Mac OS X. * objects_init.xml.in: fixed bug (no num) that caused GUI crash when user created new firewall object using template with three interfaces. 2004-12-30 * PolicyCompiler_ipfw_writers.cpp (processNext): fixed bug #1093620: "path (to ipfw) with spaces fails". Generated script failed if path to ipfw contained space. I only worked around this problem for ipfw; paths to sysctl and logger must be standard and never contain spaces. * PolicyCompiler_ipfw.cpp (processNext): fixed bug #1093472: "ipfw port range(s) errors". There can only be one port range in a single ipfw rule. * PolicyCompiler_ipfw_writers.cpp (_printProtocol): fixed bug #1093461: "problem with 'established' in ipfw". Ipfw requires protocol to be set to 'tcp' if option 'established' is used in a rule. 2004-12-29 * RCS.cpp (RCS): fixed bug #1092810: "Multiline RCS comments are shown as a single line on windows". As it turned out, this bug affected all platforms. * RCS.cpp (ci): an attempt to fix a bug that does not allow to enter RCS comment using non-english locale. 2004-12-28 * PolicyCompiler_ipt.cpp (getInterfaceVarName): fixed bug #1059393: "function getaddr failed for eth1.0020". Generated script can now work with interfaces that have a dot in their name (such as "eth1.0020" - vlan interface) * PolicyCompiler_PrintRule.cpp (_printOptionalGlobalRules): fixed bug #1092141: "irritating FORWARD rule for established connections". Need rule in FORWARD chain only if ip forwarding is on or set to "no change" 2004-12-22 * Compiler.cpp (createRuleLabel): API change: fixed bug #1068119: "additional whitespace for Rule comments in .fw file". Added extra space between rule number and interface spec in rule comments. * PolicyCompiler_ipfw.cpp (processNext): fixed bug #1089866: "multiple services in one rule confuses ipfw compiler". If several UDP or TCP objects were used in the same policy rule and these service objects had source port ranges defined, the compiler would produce incorrect code by combining source port range specifications together in the same ipfw command. * main.cpp (main): Pull-down menu "On startup" in the "General" tab of the preferences dialog now has three items: "Load standard objects", "Load last edited file" and "Ask user what to do". The last item is default. * PolicyCompiler_PrintRule.cpp (_printProtocol): fixed bug #1089586: "default --icmp-type value is 0 in iptables < 1.2.9". The problem concerns policy rules using service object "any ICMP". A rule like this is supposed to match any ICMP packet. Few versions ago I had to add option "-m icmp" (and "-m udp", "-m tcp") because I've discovered that iptables-restore on some systems (linksys sveasoft firmware, iptables v1.2.11) refused to load rules without it. Now it turns out that iptables v < 1.2.9 (tested on 1.2.6a and 1.2.7a) implicitly adds equivalent of "--icmp-type 0" to rules with "-p icmp -m icmp" and without "--icmp-type" option. Since type 0 is actually icmp echo reply, a rule like this does not match "any ICMP" as it was supposed to do. Iptables 1.2.9 implicitly adds "--icmp-type 255" which matches any icmp type. Using "--icmp-type 255" on iptables 1.2.6 and 1.2.7 does not work (a rule does not match icmp packets with type different from 255). The fix generates "-p icmp -m icmp --icmp-type any" for iptables 1.2.9 and later, as well as when iptables version is not specified in the firewall object settings. It generates just "-p icmp" for versions < 1.2.9. 2004-12-19 * ObjectManipulator.cpp (newInterfaceAddress): GUI change: main menu item "Object/New Object/Address" and corresponding toolbar button always creates an Address object under Objects/Addresses folder in the tree. Address of an interface can be created using pop-up menu item "Add IP Address" 2004-12-16 * Bunch of cosmetic bugfixes in the GUI * PrefsDialog.cpp (setButtonColor): implemented feature request: colors that are used to color rules can be changed in Preferences dialog. 2004-12-13 * FWWindow.cpp (fileOpen): when user clicks menu item "File/Open" to open a new file, the GUI should save and close currently opened file only after the user chooses new file. If user clicks Cancel in the File/Open dialog, operation should be cancelled so the user can continue working with currently opened file. The same applies to operation File/New. 2004-12-12 * po.pro: fixed bug (no num): localization was broken on win32 and mac os x because translation files were not installed properly. * ObjectManipulator.cpp (pasteTo): improved behavior of the main menu "Edit" as well as pop-up menu that appears when user right mouse clicks on an object in the tree. Menu item "Paste" should only be enabled if the clipboard is not empty and objects that are stored in it can be pasted into selected object in the tree. 2004-12-10 * RCSFilePreview.cpp (selectedRevision): fixed bug (localization): RCS log entries made using non-ascii characters used to appear as '???' in Open File and File/Properties dialogs. * ObjectEditor.cpp (validateAndClose): more bugfixes for the behavior of the object editor dialogs. Dialog should ask if user wants to save data and then validate it when user clicks on [x] to close editor dialog. It used to validate the data first, then ask if they want to close dialog. 2004-12-09 * FWWindow.cpp (load): when user opens data file in the old format (fwbuilder v1.1.x, extension .xml) and after autoupgrade the program discovers that the same file with extension .fwb already exists, it offers the user a chance to choose different name. If user clicks "Cancel" at this point, the program cancel operation and reverts upgraded data file back to its original name and version. * listOfLibraries.cpp (add): fixed bug (internal #34) the program should issue a warning when user tries to add a library file (.fwl) that contains object library that already exists in the opened data file. * ObjectEditor.cpp (validate): Streamlined logic in the object editor dialog. This improves handling of the situation when user closes dialog by clicking on [x] while 1) there are unsaved data and/or 2) some of the object's parameters have illegal values. The dialog behavior also depends on the setting of the global flag "Autosave" that causes dialog to automatically save data when user switches between objects. 2004-12-08 * listOfLibraries.cpp (add): numerous fixes for localization 2004-12-05 * ObjectManipulator.h: numerous bugfixes: - properly synchronizing state of the items main menu with state of corresponding items in the pop-up menu that appears when user right-mouse-clicks on an object in the tree - fixes for non-localized text strings in dialogs (mostly "Continue", "Yes"/"No" etc. in many places) - proper localization of the human-readable version number text for iptables; also made info window print readable text instead of "lt_1.2.6" - cosmetic changes in some dialogs layout to make the look better when localized text makes strings much longer - firewall object dialog tab "Templates" has been hidden. It is unlikely that this feature will be implemented in 2.0.X series. 2004-12-04 * listOfLibraries.cpp (add): fixed bug (no num): the GUI crashed when user tried to add a library file for auto-load in Preferences/Libraries and the first library object in that file had a name using non-ascii characters * Bunch of other fixes to avoid '????' in various places for localized strings 2004-12-04 version 2.0.4 released 2004-12-02 * utils.cpp (fillLibraries): fixed bug (no num): if a library was assigned a name with non-ascii characters, it would appear distorted in the pull-down list in object dialogs. * fixed bug #1077496 ] Error compiling libfwbuilder in FreeBSD: The problem was caused by changed major version number of libnetsnmp library in the latest net-snmp port (v5.2) 2004-12-01 * FWWindow.cpp (openFirewall): fixed bug #1077072: "CrossPlatform Firewall Builder Crash" - pressing arrow down key on the keyboard right after the GUI started with no firewall objects defined caused crash. 2004-11-30 * po/ru.qm: Updated Russian translation 2004-11-25 * PolicyCompiler_ipt.cpp (splitIfSrcNegAndFw::processNext): fixed bug #1073491: incorrect code for rules using two interfaces with negation. If a rule had two (or more) interfaces of the firewall in the destination, with negation, the code generated by compiler would check one interface's address in INPUT chain and another in FORWARD chain. It should check addresses of all interfaces from the corresponding rule element in the INPUT chain and also check addresses and possibly services from other rule elements in the FORWARD chain. This bug affected rules with two or more interfaces both in source and destination. * po/LINGUAS: translators maintain Russian localization using QT linguist rather than gettext, removed ru locale from gettext Makefiles but left it in po.pro for installation * fwblookup.cpp: a fix to make it compile on FreeBSD w/o gnugetopt port * utils.cpp (addPopupMenuItem): minor fix to help localization ('add object' and operation on rules pull-down menus did not translate properly) 2004-11-23 * instDialog.cpp (continueRun): built-in installer checks exit status of the script it runs on the firewall and aborts installation sequence if it detects an error. OS resource files have been updated accordingly so they return exit status '1' in case of error and '0' when they succeed. * Compiler_ops.cpp (checkForShadowing): API change: still working on the IPService object shadowing changes. ip fragments object was shadowing GRE object, which was incorrect. Hopefully this change finally fixes it. 2004-11-21 * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug (no number): policy compiler for iptables used "tail -1" in the shell script that read actual IP addresses of interfaces of the firewall. This shell code failed to determine correct address of an interface that was configured with a secondary address. Reverted to using grep (I switched to tail when ran into limitations of one of the beta builds of Sveasoft Linksys firmware that did not have grep) 2004-11-18 * NATCompiler_ipt.cpp (processNext): fixed bug #1068936: "unnumbered interace not using MASQUERADE". Comiler for iptables will use target "MASQUERADE" if unnumbered interface is used in Translated Source in a NAT rule. * utils.cpp (fillLibraries): fixed bug (no num): group object dialog showed incorrect library name for groups located in the "Standard" library 2004-11-17 * listOfLibraries.cpp (add): fixed bug (no number): GUI could not find names of the object libraries in external library files that user added for automatic load in the Preferences dialog on Windows. It would find the name of the library in the first file, but failed to find library names in subsequent files and used the name from the first file. Since this library was only present in the first file, object tree was getting corrupted when the program attempted to load this library from every file configured for automatic pre-load. This only happened on Windows. * dns.cpp (init): API change: fixed bug (no number): program crashed on FreeBSD 5.3 when using SNMP to obtain parameters for hosts and interfaces. Crash occurred because of use of uninitialized mutex variables in module dns.cpp 2004-11-16 * main.cpp (main): improved error handling: if the GUI is started with a file on the command line or is configured to open a file automatically on startup and RCS can not check the file out, the GUI will come up empty (with only standard objects loaded). * po/ja.po: Added Japanese translation by Tadashi Jokagi * DialogFactory.cpp (createFWDialog): added XML element FWBuilderResources/Target/dialog to platform and host OS resource files. This element describes GUI dialog that should be opened for the firewall object for a given firewall platform or host OS. This is to be used with customized resource files, e.g. when user wants to add their own host OS resource file to change commands used to load and activate policy on the firewall. Such customized resource file will have unique "description" element (the value of this element appears in the pull-down menu in firewall object dialog) and the same values for "family" and "dialog" elements to indicate which firewall family it belongs to and which dialog should be used. Policy compilers consult "family" element to check if the firewall platform is supported by the compiler. * GroupObjectDialog.cpp (addIcon): fixed bug (no number): group object dialog corrupted object names if they contained non-ascii characters. 2004-11-13 * pixAdvancedDialog.cpp (pixAdvancedDialog): Removed "always new" mode for access lists and object groups for PIX configurations. This mode works well when user installs new configuration but causes problems if they want to reinstall the same configuration. Also converted old option "pix_add_clear_statements" to one of the confgiuration script modes. So, final list of script modes for PIX is as follows: - basic or old format when access lists are cleared and added from scratch. This is the simplest mode which can be used if management station connects to the firewall from inside. Remote management over IPSEC tunnel may be difficult since tunnel traffic is blocked as soon as "clear access-list" command is executed. - access-list and object-group commands are generated but "clear access-list" and "clear object-groups" commands are not added. User's installation scripts should take care of that. This option replaces old option pix_add_clear_statements (with opposite semantics) - temporary access list is created and added to outside interface, then main lists and object groups are added with permanent names and assigned to interfaces. Temporary list permits all traffic from a single subnet configured in the GUI via option pix_acl_temp_addr. Temporary list is small and is not cleared in the end. Temporary list helps maintain IPSEC tunnel for the time when access-lists are cleared and firewall is running with default acl that does implict deny for all traffic. 2004-11-12 * pf.cpp (main): fixed bug (no number): pfctl expects "-F Sources" and "-F Tables" command line options with "Sources" and "Tables" capitalized. * FWObjectDatabase.cpp (merge): API change: changes in the object database merge algorithm: when an object database we are trying to merge has non-empty "Deleted objects" library, deleted objects from this library should be ignored (they used to be deleted from the current tree). Likewise, when current tree has non-empty "Deleted objects" library and objects in it match objects being merged in, objects should be removed from "Deleted objects" library to avoid creating duplicate IDs with objects being merged in. 2004-11-10 * Compiler_ops.cpp (checkForShadowing): API change: fixed bug (no number): rule shadowing algorithm now assumes that IPService object with protocol number '0' shadows any other service just like 'any' does. * PolicyCompiler_ipt_optimizer.cpp (optimizeForRuleElement): fixed bug #1063953: "Wrong accept/multiport rule generated". Compiler generated wrong code for rules using multiple service objects of different types (TCP and UDP, or TCP and ICMP etc), multiple addresses in src or dst with option that requires using TCP RST for action REJECT. 2004-11-07 * SSHPIX.cpp (getACLs): New feature: added support for new configuration script formats for PIX in installer: - basic or old format when access lists are cleared and added from scratch - access lists have unique names each time policy is recompiled, lists are added without clearing. - access lists are added with temporary names and assigned to interfaces, then the same lists are added with permanent names, lists are swapped and temporary lists cleared Last two methods provide for instantaneous access list swap so that the firewall never runs with empty lists. This helps maintain access to the firewall if configuration is installed remotely. * SSHPIX.cpp: New feature: Installer always clears unused access lists after confgiuration is loaded. 2004-11-06 * fwcompiler/Compiler.cpp (complexMatch): fixed bug #1055937: "Any->all_multicasts not in INPUT Chain". Need to check if network objects are multicasts; assume that multicast always matches firewall object (e.g fwb_ipt will put rule with such network object in destination in INPUT chain) * instDialog.cpp (instDialog): Added an option to push PIX configuration to a standby firewall at the end of install. 2004-11-01 * NATCompiler_PrintRule.cpp (_printDstService): fixed bug (no number) where compiler for iptables used option "--destination-port" with module "multiport" for versions of iptables that do not understand it (1.2.6 and later, as well as default version setting 'any'). The option should be "--destination-ports" or "--dports". 2004-10-31 * FWBSettings.cpp (init): fixed bug (no number): Policy installer failed if the following conditions were met: - it was running on Linux, FreeBSD or Mac OS X - working directory configured in the "General" tab of the Preferences dialog did not exist and could not be created or its permissions did not allow user that runs the GUI to access it * NATCompiler_ipt.cpp (processNext): fixed bug (no number) in fwb_ipt that caused no-nat rules with firewall in OSrc to be placed only in OUTPUT chain. Packets originating on the firewall go into OUTPUT and POSTROUTING chains, so no-nat rules must be placed in both. Other minor improvements for NAT of the locally originated connections have been done as well. 2004-10-30 * NATCompiler_PrintRuleIptRst.cpp (_endRuleLine): fixed bug (no number): compiler placed extra quote '"' at the end of each NAT command in the script using iptables-restore; this happened only if all interfaces of the firewall had static addresses. * PolicyCompiler_PrintRule.cpp (_printProtocol): testing policy installation via iptables-restore with old versions of iptables (1.2.6a). Need to include "-m tcp", "-m udp" or "-m icmp", otherwise iptables-restore does not understand options "--dport", "--tcp-flags" and some others. Also had to use "--tcp-flags SYN,RST,ACK SYN" instea dof "--syn" for better backwards compatibility. 2004-10-26 * ipt.cpp (main): iptables: Added ability to instert shell commands defined in the prolog script in three places: - on the top of generated script - after interface configuration but before resetting existing iptables policy - after existing policy rules are flushed and optional global implied rules added but before all policy and NAT rules 2004-10-24 * PolicyCompiler_PrintRuleIptRst.cpp (_createChain): implemented Feature Request #1021201: "output iptables-restore compatible config from fwb_ipt". Policy compiler for iptables can use iptables-restore to activate firewall policy. Iptables-restore provides for atomic policy load and allows to load large policy much faster. Atomic load means the whole filter or nat table is activated at once, and if there is an error, nothing is changed. Compiler generates script in three possible formats: - the ususal shell script that adds rules one at a time by executing iptables command with an "-A" flag to add a rule; - commands are fed to iptables-restore, this format is used when all interfaces of the firewall have static IP addresses and script does not need to determine addresses at run time; - script determines IP addresses of interfaces and discovers dynamic interfaces that were defined as a "wildcard" interface in fwbuilder (e.g. 'ppp*'); code that is sent to iptables-restore is generated dynamically by the script at run time. Using iptables-restore is optional and is controlled by the checkbutton in the "Script options" tab of firewall settings dialog. Path to iptables-restore utility can be set in the "Paths" tab of the host settings dialog. * A change in the script generated by fwb_ipt: if iptables-restore is not used to load policy, generated shell script purges existing firewall policy (all tables and chains) and sets default chain policies after it configures interfaces of the firewall. Previously, it would flush tables and set default policy before it configured interfaces. 2004-10-23 * RuleSetView.cpp (pasteRuleAbove): fixed bug #1028866: "incorrect order when several rules copied using copy/paste". Pasting multiple rules into an empty policy caused rules to be inserted in the wrong order. * freebsdAdvancedDialog.cpp (freebsdAdvancedDialog): fixed bug #1046345: "ipfw - no option to specify ipfw executable". Added GUI control to let user specify alternative path to "ipfw" on FreeBSD. Control like that was previously available only for Mac OS X * PolicyCompiler_ipt.cpp (checkForMatchingBroadcastAndMulticast), Compiler.cpp (_complexMatchWithInterface): fixed bug #1040773: need to match network address as well as broadcast. Packets sent to the network address (192.168.1.0 for net 192.168.1.0/24) go in the broadcast frame and behave just like IP broadcast packets (sent to 192.168.1.1255 for the same net) * PolicyCompiler_ipt.cpp (finalizeChain::processNext): fixed bug #1040599: "unnecessary FORWARD rules". If ip forwarding is turned off in the host settings dialog of the linux-based firewall, compiler should not generate rules in FORWARD chain. 2004-10-20 * linux24.xml.in: Added element "Target/family" to all OS resource XML files. Compilers use "family" resource element to determine if host OS is supported. User may want to copy host OS resource file to modify installer scriptlets; as long as the family element is kept the same, compiler will accept new resource file. * linksys.xml.in: Added elements "Target/options/suppress_comments" and "Target/options/suppress_modules" to the OS resource files linksys.xml and linux24.xml. These options suppress printing comments in the generated script and remove commands that load kernel modules. These options are used for Linksys/Sveasoft appliance but can also be used for other firewalls based on Linux. 2004-10-19 * pf.cpp (main): Activation script for PF flushes only information about rules, nat, source and tables (it used to flush "all"). This preserves queue entries and states. * ipt.cpp (main): moved rule permitting backup ssh access from the management station to the firewall to the top of the script. This helps maintain ssh session, otherwise it may stall or break because stdout buffer is filled with diagnostic or progress output from the script that is printed after all chains are flushed but before rule permitting ssh to the firewall is added. If stdout buffer is full, ssh stops and tries to send the text to the management station but times out because firewall blocks it. * ipt.cpp: removed code that added iptables command to the "drop" table to drop and log all dropped packets. This rule used obsoleted patch-o-matic patch "drop" which is not available anymore. 2004-10-17 * ipt.cpp (main): fixed bug (no number): all policy compilers properly detect an error when the output file can not be created or overwritten and print error message to warn the user. * New feature: added support for prolog and epilog scripts for all firewall platforms. This was available for PIX for some time, now it has been added for all platforms. "Prolog/Epilog" tab of the firewall settings dialog allows for editing of two blocks of commands that will be added to the generated firewall script verbatim. Prolog block is added on top, while epilog block is added at the bottom. Both prolog and epilog are expected to be shell scripts and are added to the generated shell script that activates firewall. For iptables and ipfw all compiler generates is this shell script and prolog and epilog commands are inserted into it. These commands may execute some actions, as well as add any policy or nat commands. For ipf and pf prolog and epilog commands are added to the activation shell script ( .fw file); prolog is added immediately after the command that flushes all rules. This way user may either execute shell commands or add policy and/or nat rules by loading them from external file. 2004-10-10 * FWWindow.cpp (addFirewallToList): fixed bug (no number) introduced in 2.0.3 when GUI crashed if user tried to choose pull-down menu item in the firewall list after the very first firewall object has been created. * SSHPIX.cpp: Added #include to make code compile with gcc 3.4.2 and glibc 2.3.3 * ipt.cpp (main): fixed bug #1040788: fwb_ipt and user name. Compiler used to read environment variable "USER" to find out user's name. Sometimes this variable is not set, which caused compiler to abort. Using env variable LOGNAME in addition to USER. 2004-09-30 * v2.0.3 released 2004-09-28 * instDialog.cpp (instDialog): since config diff is broken for pix v6.3(3) (because it does not permit adding duplicate ACL entries), "save diff to file" option is temporary disabled. "Incremental" install renamed to "install only ACL,icmp,telnet,ssh,nat,global and static commands" 2004-09-27 * OSConfigurator_linux24.cpp (printPathForAllTools): script generated by compiler for iptables checks if /usr/sbin/ip exists on the firewall before it tries to use it to verify interfaces and configure IP addresses. This check is only performed if user activated options that use this tool. An error message "Interface eth0 does not exist" was generated if package iproute2 was not installed on the firewall, which was confusing. * FWWindow.cpp (doCompile): Added option "output file name" to firewall settings dialogs for all platforms. User can specify the name for the output file; this name is then used by built in installer in place of a macro %FWSCRIPT%. * ipt.cpp (main): Added command line option "-o" for all compilers * FWWindow.cpp (save): fixed bug #1035800: "Autosave failure opens error window repeatedly". This bug was in fact fixed earlier. 2004-09-26 * FWWindow.cpp (fileSaveAs): fixed bug #1035130: 'Persistent "Save" dialog box'. Certain combination of actions on user's part used to lead to an indefinite loop of "do you want to save the data" dialogs. The problem was triggered if user skipped choosing a name for the new file in startup dialog. * linux24.xml.in: fixed bug #1035132: "compile errors with default Linksys firewall object". This bug has been introduced in build 435. When user created a new firewall object using one of the template objects, the GUI would add bunch of garbage to the firewall options. This garbage violated XML DTD, so compilers and the GUI would not accept the data file anymore. 2004-09-25 * ipt.cpp (main): using "set -x" to turn debugging on in generated iptables script. This will work even if the script is activated with "sh script.fw" command. * OSConfigurator_linux24.cpp (generateCodeForProtocolHandlers): changed commmand line for sed to more portable version. We used to use 'stmt; stmt' syntax, which is not always portable. Switched to a supposedly more portable syntax using multiple "-e" command line options. 2004-09-23 * instDialog.cpp (getActivationCmd): fixed bug (no number): as of build #430, installer ignored activation command configured in the "install" tab of firewall settings dialog. Restored this functionality. * OSConfigurator_linux24.cpp (printPathForAllTools): just like with "tail -1", some busybox based systems require "head -1" to be changed to "head -n1" 2004-09-22 * instDialog.cpp (testRunRequested): fixed bugs in installer that prevented it from working on OpenBSD. Enabled shceduled reboot for all OS except PIX. 2004-09-21 * instDialog.cpp (testRunRequested): "schedule reboot" option is only enabled for linksys since it does not work on other platforms (yet) * FWWindow.cpp (openFirewall): implemented Feature Request #1032126: "Firewall label for clarity". Printing the name of the firewall object that is opened in the policy panel in a large font right above interface/policy tabs. This was easy to implement but I consider it an experiment. Will request feedback from users. * SSHSession.cpp (startSession): refactored code in built-in installer. Moved interaction with ssh to classes SSHSession, SSHUnx and SSHPIX. Moved "scriptlets" that are executed on firewall to activate policy in different modes to resource files. Using ssh rather than scp to copy policy script to unix-based firewalls (pscp.exe on Windows works only if the server supports sftp, but dropbear on Linksys does not support it so installer breaks if we use scp/pscp.exe to copy the policy). Still having problems with scheduled reboot option on Linux/BSD firewalls (it works on Linksys though). * OSConfigurator_linux24.cpp (printPathForAllTools): bugfix: some editions of busybox do not support "tail -1" syntax and require "tail -n1" 2004-09-19 * instDialog.cpp (getActivationCmd): Improvement in the built-in installer: added an option to schedule automatic firewall reboot in specified time (in minutes) after policy activation. This option is available for all firewall platforms but PIX. This option only works if user requested policy activation in a test mode, in which case policy is copied and activated on the firewall but not stored in the permanent location. After reboot the firewall reverts to the previous version of the policy. To cancel scheduled reboot, run installer again with "test run" option turned off. Installer stores the policy in the permanent location, activates it and cancels scheduled reboot. * src/res/os/linux24.xml.in and other: moved all commands used by built-in installer to resource files. 2004-09-18 * NATCompiler_pf.cpp (processNext): NAT rule of type DNAT (rdr rule) is assigned to an interface of the firewall if interface object or its address object is used in ODst. To get rdr rule without interface assignment, use an Address or a Host object that has the same IP address as that of firewall's interface but that is not a child of an interface. This is the same approach that is used in iptables. * PolicyCompiler_pf.cpp (compile): Compiler for pf always uses tables; this breaks compatibility with older OpenBSD systems (3.2 and 3.3) * PolicyCompiler_pf.cpp (findDynamicInterfaces): Compiler for pf puts interface name in a table even if interface is dynamic for rules that use multiple objects in src or dst and one of these objects is dynamic interface of the firewall that is being processed. Using dynamic interface of another object in a rule is still considered an error. Compiler puts the name of dynamic interface in a table verbatim, without brackets '(' ')' since pf does not replace dynamic interface with its address dynamically if it is used in a table (pfctl issues an error if interface is put in brackets) 2004-09-17 * OSConfigurator_linux24.cpp (configureInterfaces): flushing only secondary ip addresses on interfaces. This should fix a bug that caused linksys/sveasoft unit to lose default route upon reboot if external interface has static IP address. 2004-09-15 * PolicyCompiler_pf.cpp (addDefaultPolicyRule): fixed bug #1028980: "need an option to turn logging on on fallback rule" * PolicyCompiler_pf_writers.cpp (processNext): fixed bug #1028973: fwb_pf: missing "flags S/SA" in front of "modulate state" * pfAdvancedDialog.cpp (pfAdvancedDialog): added an option to permit tcp sessions opened prior to firewall restart. This is needed now since compiler generates "flags S/SA" for the "keep state" and "modulate state" rules which means firewall won't permit TCP sessions unless it saw opening SYN packet. * instDialog.cpp (getActivationCmd): improvements in policy installer: added an option for test run. When this option is activated, policy script is pushed to the firewall and is executed but is not stored there permanently. Firewall reverts to the last working configuration after reboot. * NATCompiler_ipt_writers.cpp (processNext): using abbreviated versions of "--dport", "--sport", "--dports", "--sports" options to make generated iptables script smaller. Also changed the name of the variables used to hold IP address of dynamic interface from "interface_" to "i_". All this should help to fit larger policies into small FLASH on linksys. These changes shrunk my test script from 7964 bytes to 7430 bytes 2004-09-14 * platforms.cpp (isDefaultOptions): fixed bug #1028078: "options.png is not displayed for "Assume firewall is part..." * pfAdvancedDialog.cpp (pfAdvancedDialog): fixed bug (no num): "firewall settings" dialog for OpenBSD pf did not save option "Use tables". * instDialog.cpp (getActivationCmd): implemented compression of the firewall script for Linksys/Sveasoft combo. Using gzip and uuencode/uudecode to compress the script and store it in flash variable 'fwb'. Installer prints flash memory stats after commiting changes. Installer uses scp to copy firewall script to the firewall and autogenerated prompt to detect when it logged in; it does not depend on Linksys shell prompt anymore. 2004-09-12 * PolicyCompiler_ipt.cpp (addPredefinedPolicyRules): implemented feature request #1023430: "add checkbox for INVALID support in fw settings". Added two checkboxes to the firewall settings dialog: one adds a rule to drop INVALID packets and another adds logging to the rule. * FWWindow.cpp (fileSaveAs): fixed bug #1026945: '"Save As" does not work if current file is in RCS' * FWWindow.cpp (removeFirewallFromList): fixed a bug (no number): after deleting a library firewall objects that belong to it were not removed from the pull-down list * PolicyCompiler_ipt_optimizer.cpp (optimizeForRuleElement): fixed bug #1026794: multiple SRC ntwks --> "iptables: invalid argument". Recent changes in optimizer introduced this bug. Rules with multiple objects in src or dst, TCP service, action Reject and option "reject with TCP RST" would generate iptables command that used option "--reject-with tcp-reset" without "-p tcp" * PolicyCompiler_pf_writers.cpp (_printDstAddr): fixed bug #1006906: "Negated network causes pass on network". Compiler for pf uses native negation syntax that is now available in pf 2004-09-11 * PolicyCompiler_ipt.cpp (TimeNegation): fixed bug #1022216: "negated time produces incorrect iptables rule". Implemented negation for the "Time" rule element for iptables * PolicyCompiler_ipt.cpp (processNext): fixed bug #1026509: "incorrect rules generated for dual negation with time". Compiler generated incorrect iptables commands for rules that had negation in two or more rule elements, one of which was Time. 2004-09-09 * OSConfigurator_linux24.cpp (prolog): rules that permit packets associated with ESTABLISHED,RELATED states moved to the beginning of the script before NAT rules. * PolicyCompiler_ipt_writers.cpp: added a checkbox and support in policy compiler for iptables to generate rules that drop packets that are associated with no know connection (state "INVALID") 2004-09-08 * Firewall.cpp (duplicate): API change: fixed bug (no number): all references to the interfaces, as well as their IP and MAC addresses, in policy and NAT rules should be replaced when Firewall object is duplicated. Until now only references to the firewall object itself and to its interfaces were replaced with references to the newly created copies of object. References to IP and MAC addresses still pointed at the old objects. * FWObjectDatabase.cpp (IDcounter): fixed bug #1022788: "GUI corrupts XML file after creating a second firewall". Global object ID counter was getting reset every time new FWObjectDatabase object was created. This lead to the ID collision if user quickly created and deleted complex objects (such as Firewall) and used database merge. This should also fix bug #1022785: "GUI corrupts XML file after creating a host entry" * PolicyCompiler_ipt_optimizer.cpp (processNext): fixed bug #1024861: "optimizer is broken in fwb_ipt". Used idea and a patch by Mark Vevers . Fixed compiler fwb_ipt generates more efficient iptables script for rules with multiple objects in all rule elements. The script is smaller and eliminates unnecessary comparisons for packet attributes. Every attribute (i.e. source address, destination address, protocol and port numbers) is checked by the script only once. This should help reduce load on firewalls with lots of complex rules. * VERSION: set version to 2.0.3 2004-08-31 * v2.0.2 released 2004-08-31 * ipt.cpp (main): fixed bug #1019943: "Missing ip addresses in the rule using interfaces" * linksysAdvancedDialog.cpp (linksysAdvancedDialog): fixed bug #1019691: "040829 nightly build doesn't add paths for linksys" 2004-08-30 * VERSION (VERSION): version 2.0.2, revision 1 * aboutdialog_q.ui.h (init): "About" dialog shows registration status (used only in non-GPL versions) 2004-08-28 * fixed FreeBSD port, now compiles on 5.3BETA 2004-08-25 * RuleOptionsDialog.cpp (loadFWObject): Added support for options "max", "max-src-nodes" and "max-src-states" in pf. These allow to limit number of concurrent state table entries ("max"), number of source addresses that can simultaneously have state table entries ("max-src-nodes") and number of simultaneous state entries per source address ("max-src-states") per rule. * LibExportDialog.cpp (accept): fixed bug #1015884: "Export more than one library fails with 0 references". Export library operation failed if user exported two libraries with groups or rules in one library referencing objects in the other. 2004-08-24 * pfAdvancedDialog.cpp (pfAdvancedDialog): Implemented support for all timeout settings in pf: tcp.first,tcp.opening,tcp.established, tcp.closing,tcp.finwait,tcp.closed,udp.first,udp.single,udp.multiple, icmp.first,icmp.error,other.first,other.single,other.multiple, including adaptive timeout scaling options adaptive.start and adaptive.end 2004-08-23 * FWBTree.cpp (getStandardSlotForObject): fixed bug #1014725: "adding new ICMP types". If user created service group with the name "ICMP", the GUI would place new ICMP objects under this group instead of the standard folder "ICMP". There was the same problem with other object types, too. * ObjectManipulator.cpp (simplifySelection): debugging in operations "delete object", "move object", "undelete". Making sure we can delete and undelete libraries, delete and move several objects at once, group several objects. There were problems if user selected several host or firewall objects using Shift-Click (although interface and address objects were not visible to the user, they were selected and acted upon in delete or move functions; this lead to unexected results or crashes). 2004-08-22 * templates.xml.in: added template firewall objects for Linksys firewall and a web server. * templates.xml.in: fixed bug #1013957: "incorrect NAT rule in firewall created from template #3". The problem was caused by incorrect ip address of interface "dmz" in the template object #3. * pixAdvancedDialog.cpp (pixAdvancedDialog): implemented a backup ssh access rule. The user specifies management station IP in the firewall settings dialog for PIX and compiler adds a rule on top of all other rules to permit ssh from this address to the firewall. 2004-08-21 * OSConfigurator_linux24.cpp (prolog): avoiding grep in the generated iptables script - Sveasoft Alchemy pre-5.2.3 does not have grep * API change: fixed bug #1012733: "configure --libdir=DIR will be ignored at installation". Needed to use macro _libdir to specify target directory for libraries. Used it in configure, qmake.in, libfwbuilder-config-2 and a .spec file * objects_init.xml.in: added new service objects to the Standard objects library: "xmas scan" (old object renamed "xmas scan - full"), rsync, distcc, cvspserver, cvsup, afp, whois, bgp, radius and radius acct, SSDP and UPnP. This fixes bug #1011248: "need two xmas scan service objects" * FWWindow.cpp (fileImport): function File/Import offers a choice of .fwl, .fwb and "all files" in the open file dialog. This fixes bug #1013485: "File/Import should allow to import .fwb file" * FWWindow.cpp (load): fixed bug #1008956: "Existing .fwb file gets overwritten if has wrong extension". If the GUI needs to rename a data file with old extension .xml to .fwb, it checks if a file with new extension exists and offers user a chance to choose a different name. It also treats symlinks in a special way: if user creates a symlink with extension .xml pointing at a file with extension .fwb, the GUI simply follows the link and works with .fwb file. This should work with Windows shortcuts, too. * instDialog.cpp (instDialog): built-in installer uses shell prompt string patterns configured in the host OS settings dialog for linksys. This fixes bug #1013022: "can not install policy script on linksts Alchemy pre-5.2" * linksysAdvancedDialog.cpp (linksysAdvancedDialog): Added host OS settings dialog for linksys/Sveasoft. Dialog provides entry fields for paths to iptables, lsmod, modprobe, logger tools and two shell prompt string patterns, this should help to work around changes in the shell prompt on Linksys. This fixes bug #1013018: "host OS settings" dialog is missing for linksys 2004-08-20 * ObjectManipulator.cpp (contextMenu): fixed bug #1009345: "Can only move one host object at a time between libraries" * ObjectManipulator.cpp (deleteObj): fixed bug #1013177: "deleting multiple hosts causes crash" * DTD change: fixed bug #1011617: "deleting physcal address object leads to the DTD violation" 2004-08-08 * PolicyCompiler_ipt_writers.cpp (_printDstService): fixed bug #1005148: "MAC matching - space missing". Space was missing between MAC address and custom service code. 2004-08-06 * listOfLibraries.cpp (add): fixed compile problem on systems where QT is built without STL support * PolicyCompiler_ipt_writers.cpp (_printLimit): fixed bug #1004153 "limit-burst = 0 is not valid". Iptables does not accept the rule using "limit-burst" option if it is set to zero. 2004-08-04 * ObjectManipulator.cpp (pasteTo): fixed bug #1003068: "object copy/paste not always working". IP address object could not be placed under interface using copy/paste operation. Now ip address object can be pasted to interface as well as to Objects/Addresses folder. * FWWindow.cpp (fileDiscard): Operation File/Discard closes the file, discards all the changes that have been made to it and replaces it with a fresh copy of the head revision from RCS. This works if user wants to abort file upgrade when they switch to the new version of fwbuilder. 2004-08-02 * FWObject.cpp (deleteChildren): fixed bug #1001833: "memory leak" - children objects were not deleted when FWObjectDatabase object was destroyed. * iptAdvancedDialog.cpp (accept): fixed bug #1002388: "Clamp MSS to MTU" option is missing in 2.0 2004-08-01 * objects_init.xml.in: there were two TCP Service objects "linuxconf" in the Standard objects library. Object with ID id3AED0D6D has been removed. It seems this object has been duplicated long time ago (at least it was like this in 1.1.2) * FWObject.cpp (getPath): fixed bug #1001725: "object with empty name can not be deleted". the problem was caused by the algorithm used in FWObject::getPath. If object had had a blank name, the path returned by this method would end with the name of its parent without slash. * FWWindow.cpp (showFirewalls): fixed bug #1000485: "Firewalls in the drop-down box not ordered". List of firewalls in the pull-down that controls policy views is now alphabetically sorted on program startup. * utils.cpp (fillLibraries): fixed bug #1000862: "Creating groups in Deleted Objects". Library "Deleted objects" should not be offered as a choice for "group objects" operation. * ObjectManipulator.cpp (contextMenu): fixed bug #1001275: "object duplication fails w/ no action". GUI used to not allow user to duplicate IP address object. Now any object can be duplicated so that the copy is placed under the same parent, including IP address. * ICMPServiceDialog.cpp (applyChanges): fixed bug #1001521: "Cant create ICMP service". ICMP Service dialog did not save icmp code and type numbers in the object. 2004-07-29 * 2.0 released, CVS tag set 2004-07-27 * FWWindow.cpp (install): the GUI calls external installer script if it is configured in firewall settings dialog when user clicks 'Install', otherwise it should use built-in installer. 2004-07-24 * RuleSetView.cpp (insertRule): correctly copying rule direction when interface rule is copied/pasted * instDialog.cpp (selected): proper error messages for management interface misconfigurations 2004-07-20 * ICMPServiceDialog.cpp (loadFWObject): ICMP service dialog allows for setting type and code to 'any' (-1) 2004-07-19 * OSConfigurator_linux24.cpp (processFirewallOptions): fixed bug #992969: "argument to log should be quoted" 2004-07-14 * PolicyCompiler_ipt.cpp (processNext): working on bug #990037: "Wrong rule generated: fw interface included in negated group". Rules with negation should not generate code in INPUT/OUTPUT chains if option "assume firewall is part of any" is off. * ObjectManipulator.cpp (delObj): fixed bug #990675: "Application crashes when deleting objects" 2004-07-11 * PolicyCompiler_ipt.cpp (splitIfSrcNegAndFw): optimized processing of policy rules where firewall object is used in src or dst with negation (possibly in combination with other objects). Before, generated script would match firewall's addresses in INPUT/OUTPUT and FORWARD chains which added redundant checks in the FORWARD chain. * NATCompiler_ipt.cpp (processNext): fixed bugs #935794: "dual translation and negation in fwb_ipt" and #986376: "Wrong result for negated source in NAT rules". Dual translation rule with negation in OSrc did not process negation in the second half (POSTROUTING rule, the one that translates the source). * NATCompiler_ipt.cpp (processNext): fixed bug #965558: "False ruleset generated for iptables (negate w/ nat)". There were problems with double negations in NAT rules (OSrc and ODst, or ODst and OSrv, etc). * OSConfigurator_linux24.cpp (printPathForAllTools): fixed bug #988860: "Logging missing when firewall start is aborted". When iptables script generated by fwb_ipt finds missing interfaces, it prints error message both on stdout and sends it to the log. 2004-07-10 * FWObject.cpp (_moveToDeletedObjects): now move deleted objects to the special library with id 'sysid99' rather than delete them completely. This serves two purposes: 1. can easily provide for undelete function which is very useful 2. can catch a situation when an object has been deleted fromt he external library but is still used in the data file * FWObjectDatabase.cpp: while merging object trees, checking for deleted objects. If an object is present in the current tree but has been deleted in the file being merged in, special form of conflict resolution dialog is shown. User has only one option - to delete the object from the file. Typical situation when this happens is when an object from external library is used in a rule or group in a data file, then this object is deleted in the external library. If this external library is preloaded and then the data file using this object is opened, conflict occurs because this object is present in the file but is in the "Deleted objects" in the library. The problem is that the library is read-only, so if we kept the object (actually, its copy coming from the data file), the user would not be able to delete it. So, not only object magically reappeared after it has been deleted from the library, it appeared in read-only library and can not be deleted anymore. To avoid this situation we must delete it in the file if it has been deleted in the library. * ObjectManipulator.cpp (delObj): "delete object" function moves it to "Deleted objects" library. * PrefsDialog.cpp (accept): Added checkbox "Show deleted objects" to the preferences dialog. If this option is on, user has access to deleted objects via library "Deleted objects". * ObjectManipulator.cpp (contextMenu): pull-down menu item "Move" turns into "Undelete" if an object is in "Deleted objects" library. This provides for a simple undelete function. 2004-07-09 * PolicyCompiler_ipt.cpp (processNext): fixed bug #925199: "compiles wrongly a double negation". Policy compiler for iptables generated incorrect code for rules where two rule elements used negation (i.e. both src and dst, or dst and srv, etc.) * PolicyCompiler_ipt.cpp (prolog): fixed bug #978854: "false rule generated for fw object in interface rule". Policy compiler for iptables generated incorrect code for rules using negated firewall object in source or destination when global option "assume firewall is part of any" was turned off. * fwb_ipt: implemented Feature Request #913273: make "assume fw is part of any" a per-rule option 2004-07-08 * FWWindow.cpp (setupAutoSave): Added an option for autosave - if this option is turned on, the gui periodically saves data to the file. The autosave interval can be set between 1 minute and 2 hours. * ipt.cpp (main): fixed bug #917422: "compiler misinterprets interface with addr 0.0.0.0". If an interface has IP address "0.0.0.0", it is considered an error. * added option "strip comments in the script" to the installer for Linksys and PIX * do "nvram uset rc_firewall" before loading fw script on Linksys * added the following to the list of errors for Linksys /dev/nvram: Cannot allocate memory * skip table "mangle" when flushing iptables rules 2004-07-07 * NATCompiler_ipt_writers.cpp (processNext): fwb_ipt does not include comments in the script if it is intended for linksys firewall. Linksys has small nvram and script should be kept small, otherwise it may not fit in nvram. * NATCompiler_pf.cpp (processNext): fixed bug #986518: "PF redirection always point to loopback address" 2004-07-06 * instDialog4.cpp (stateMachineLinksys): Activating policy on Linksys/Sveasoft wothout reboot (using command "nvram get rc_firewall | /bin/sh" instead) * OSConfigurator_linux24.cpp (prolog): added an option to firewall platforms iptables, ipfilter, pf and ipfw that sets up a policy rule to permit ssh access from one specified IP address to the firewall regardless of other rules. This is for a backup ssh access from the management workstation in case of an error in the policy that locks user out of the firewall. The option (a checkbox and entry field for the management station address) is located in the "Compiler" tab of the firewall settings dialog. A command that permits ssh to the firewall from the given address is added on top of all other rules. 2004-07-05 * RuleSetView.cpp (dropEvent): fixed bug #985187: "Usability bug: Copy objects from one rule to another". Dragging an object from one rule to another with Ctrl down makes a copy. If Ctrl is up, then the object is moved. * instDialog4.cpp (stateMachineLinksys): Added support for Linksys devices running Sveasoft firmware. Firewall object should be configured as platform "iptables", host OS "linksys". Policy installer works both using password and public key authentication. * NATCompiler_pf_writers.cpp (processNext): fixed bug #985527: pf NAT rules miss destination port specification. NAT rules that translate to "map" missed destination port specification. * main.cpp: the gui can now use external wrapper scipts for ssh and scp all the way (removed all direct references to commands "ssh" and "scp", use whatever is configured in preferences everywhere) 2004-07-04 * RuleSetView.cpp (contextMenu): fixed bugs in the rule selection. The user can select one rule with a simple left-click on the rule number, or multiple consequtive rules using shift-left-click. Selecting non-ajacent rules with ctrl-click is not supported; ctrl-click acts as normal click. Right-click calls context menu and uses existing selection if click is on one of the selected rules, or resets it if click is outside of the selection. 2004-06-29 * ObjectTreeView.cpp (dragObject): implemented drag and drop of multiple objects. User can select and then drag several objects from the tree to a group or a rule. * LibExportDialog.cpp (accept): a change in the export library algorithm. We now permit exporting several libraries to one file, but check that all these libraries have only references to each other and to objects in the Standard lib and have no references to objects in libraries that are not going to be exported to the same file. This ensures integrity of this file and helps avoid pulling objects from other libraries into it. User can edit objects in the exported libraries by opening this file as usual; the GUI does not preload libraries configured in Preferences/Libraries when .fwl file is opened and unlocks all libraries in this file so objects can be edited. This way user can edit objects and move them between libraries in the .fwl file. 2004-06-28 * RCS.cpp (RCSEnvFix): fixed a bug (no #) that appeared only on Windows: the GUI failed to check a file in to RCS if it was launched by windows explorer via file extension association. * platform.cpp: pull-down "versions" is now translatable and says "1.2.9 or later" for iptables v > 1.2.9 2004-06-26 * LibExportDialog.cpp: when a library is exported to a file, the program checks whether any groups or rules in this library use objects in the othe libraries. Only self-contained libraries can be exported. 2004-06-24 * PolicyCompiler_ipt.cpp (processNext): fixed bug #979484: "improper command for rule with servie any and action reject." For rules like that, and if rule options dialog does not specify particular way to handle this combination, the compiler splits the rule; the first iptables command rejects any tcp packet with TCP RST, while the second rejects everything else with ICMP message. * minor bugfixes in the gui * incorporated changes suggested by a user to make code compile with gcc 3.4 2004-06-23 * LINGUAS: added Vietnamese translation .po file * FWBSettings.cpp (init): Option "do not save standard libraries in the user's data file" is now ON by default. User can still turn it off though. * FWWindow.cpp (save): Usability fixes in methods that work with libraries: - libary files have extension .fwl - preloaded libraries are always read-only (flag RO is set when library file is loaded, regardless of the value this attribute has in the file) - user can open library file using normal File/Open operation. Read-only flag is cleared when library file is opened, so it can be edited. File can be added to RCS and saved using normal File/Save or File/SaveAs operations. - When user opens library file for editing, other libraries that are configured in Preferences/Libraries are not preloaded. 2004-06-22 * LibExportDialog.cpp (init): when object library is exported to a file, the file gets extension .fwl to distinguish it from the regular data file. The GUI allows to export only one library to a file. * FWWindow.cpp (fileDiscard): added main menu function "File/discard" which discard all changes that have been done to the data and saved to the file and checks out clean copy of its head revision from RCS. This provides for a quick way to roll back to the latest revision. Older revisions can be checked out from RCS using list of versions in the right hand panel in open file dialog (this creates a branch in RCS). 2004-06-20 * IPv4Dialog.cpp (DNSlookup): "DNS Lookup" button in the IP address dialog runs dns query for the name of the address object and if that fails, repeats query for the name of the host or firewall object this address belongs to. If address object is in the folder "Addresses", it does only one DNS lookup on its name. 2004-06-18 * ObjectManipulator.cpp (ObjectManipulator): disabled ability to drop objects into groups in the tree. It was confusing and not really useful. Objects can still be dropped into a group opened in the editor dialog. * ObjectTreeView.cpp (dragObject): enabled dragging of all objects in the tree. It turns out, QListView will highlight multiple items in the tree in Extended selection mode when user drags mouse across items _and_ the first item they started cursor move on is not drag-enabled. So, to avoid this unexpected highlighting behavior, need to enable drag of all objects. We then make sure that system folder can not be dropped anywhere. 2004-06-16 * Compiler_ops.cpp (checkForShadowing): fixed bug #906709: "A dynamic interface". Dynamic interface used to "shadow" old broadcast object (0.0.0.0) * OSConfigurator_linux24.cpp (configureInterfaces): fixed bug #912849: "Reorder activation of network interfaces in IPT" - script generated by the compiler for iptables sets default policy to DROP, flushes all rules and then reconfigures interfaces of the firewall (it used to reconfigure intefaces and then flush the rules). * IPv4Dialog.cpp (DNSlookup): Button "DNS lookup" in the IP address editor dialog does DNS lookup on the address object name if the object is located in the "Addresses" folder, or on the parent host object name if it belongs to an interface of a host or a firewall. * ObjectManipulator.cpp (moveObject): refactored "move object" functions and added debug printing. Trying to debug crash reported by one of the users. 2004-06-15 * ObjectEditor.cpp (hide): checking if screen position for the dialog is 0,0 and not storing this value. This should help to work around a weird bug where screen position of dialogs sometimes is returned as 0,0 when GUI runs in Gnome. * Object names and comments are stored in the object file in UTF-8 format. This allows for names and comments to be entered and displayed in local languages. Although object names can be localized, it is recommended to keep firewall names in plain ASCII because compilers do not support UTF-8 yet. This fixes very old bug #657156: "Special characters problem". 2004-06-13 * init.cpp (init): the program uses reasonable default for the directory where user might want to save their data files on each OS. ( $HOME on Unix, $HOME/Documents on Mac, $USERPROFILE/Documents in windows) * ObjectManipulator.cpp (updateObjName): whenever user changes the name of a firewall, host or an interface object, the GUI asks whether they want to also rename all IP and MAC addresses that belong to that firewall or host. If user agrees to rename them, the program generates names automatically using scheme 'host_name:interface_name:ip' and 'host_name:interface_name:mac' 2004-06-12 * newHostDialog.cpp (selected): implemented "new host" wizard. User can choose to add interfaces manually or can use a library of predefined host object templates. 2004-06-10 * PolicyCompiler_pf_writers.cpp (_printDstService): fixed a bug (no number) where fwb_pf would not include code defined by custom service object in the .conf file 2004-06-08 * ObjectManipulator.cpp (copyObj): implemented multi-object and multi-rule copy/cut/paste operations * ObjectManipulator.cpp (moveObject): implemented "move object" operation - moves object to another library; operation is accessed via pull-down menu in the object tree. 2004-06-06 * ObjectManipulator.cpp (groupObjects): added ability to select multiple objects in the tree. Currently the following operations are performed on multiple objects: delete, duplicate, group. * ObjectManipulator.cpp (groupObjects): operation of grouping of selected obejcts. User selects several objects in the tree and choses menu item "group" in the pull-down menu; the GUI brings up a dialog asking for the new group name and a library it should be put in. New group is created and all selected objects are automatically added to it when user hits "Create group" button. 2004-06-05 * pixAdvancedDialog.cpp (accept): added "Installer" tab to the PIX firewall settings dialog * FWBSettings.cpp (getScreenPosition): checking if the window fits in the screen before restoring its geometry. * ObjectListView.cpp (dragObject): setting hot spot in the center of the object icon for drag and drop. * FWObjectPropertiesFactory.cpp (getObjectPropertiesDetailed): showing group members in tooltips and conflict resolution dialog * ObjectEditor.cpp (ObjectEditor): redesigned ObjectEditor class. All individual object editor classes are now inherited from QDialog and are top-level windows. Class ObjectEditor is just a manager that opens and hides appropriate dialog and manages its size and position on the screen. Geometry is remembered separately for each dialog for each object type, so we can have group object editor open wider than, say, IP service object editor. Each object editor has its optimal size. * pfAdvancedDialog.cpp (pfAdvancedDialog): yet another redesign of PF firewall settings dialog. Using individual checkboxes to enable/disable each "limit" and "timeout" option * ipt.cpp (main): all compilers do not create any files if there was an error during rule processing (not even empty ones) 2004-06-04 * RuleSetView.cpp : Info window shows properties of an object selected in rules * RuleSetView.cpp (paintCell): added tooltips for objects in the policy view, using the same detailed properties text that is used for Info panel. * iptAdvancedDialog.cpp (accept): the actual command that installer should run on the firewall to activate the policy can now be specified in the "installer" tab of firewall settings dialog for all platforms. If this input field is left blank, installer will run firewall script, using sudo if user name used to authenticate to the firewall is not 'root'. On Windows, installer also does chmod +x on the file. * FWBSettings.cpp (setSSHPath): directory path and a file name for the secure file transfer and secure shell utilities can be configured in the Preferences (tab "SSH"). This allows for using of different SSH packages on Windows, as well as using SSH installed in a non-standard directory on Unix. 2004-06-03 * ObjectTreeView.cpp (dragObject): standard folders in the tree can not be dragged into groups or rules and open/close on double click. Regular objects open editor on doubleclick. * ipt.cpp (main): compiler for iptables sets up PATH environment variable at the beginning of the generated script. This is particularly useful if policy is compiled on windows or mac for Linux firewall that runs unknown version of Linux, so we cant be sure where standard tools such as iptables, lsmod etc are located. Most systems place them in /sbin, but for example SuSe places iptables in /usr/sbin. If policy is compiled on one of the Linux systems, we assume generated script will run on the same system (which may not be true, btw), but if we compile on Windows, there is no way to know where these tools are located beforehand. In this case we need PATH. User can always override this behavior and specify full path to all tools explicitly. 2004-06-02 * linux24.xml.in: changed "Linux 2.4" to "Linux 2.4/2.6" in all menu * iptAdvancedDialog.cpp (iptAdvancedDialog): removed "log all dropped packets" option from the firewall settings dialog for iptables. This option required p-o-m patch that has become obsoleted and is not included in p-o-m anymore. * FWWindow.cpp (install): when user hits "Install", the GUI checks if objects in the database were modified since policy of a firewall has been compiled last time. If existing policy file is older than the database, program offers the user to compile it before it is installed. There are options to recompile, install old copy or cancel the operation. 2004-05-31 * RuleSetView.cpp: Added support for operations that act on multiple rules: setting rule color, moving to a different position in rule set, disabling/enabling, deleting. User can select multiple rules by dragging mouse across several rows in the column that shows rule numbers. Copy/Cut/Paste operations of multiple rules are not supported yet. 2004-05-29 * RuleSetView.cpp (dragObject): implemented drag-and-drop of objects in the rules * utils.cpp (setDisabledPalette): all entry fields in the object editor are disabled if an object is read-only or is located in read-only library. Object editor is still opened for read-only objects, but since all fields are disabled, changes are not allowed. Opening object editor for read-only and standard objects allows for inspection of their properties. * FWWindow.cpp (load): file objects_init.xml does not include empty "User" library anymore. Instead, this library is created dynamically using method FWBTree::createNewLibrary when user creates new data file. This simplified things since 1) "User" library now has unique random ID in every data file so it can be safely exported and then imported back without any conflicts; 2) since its ID is unique, it can be renamed without creating any conflicts. The library is only created in FWWindow::load() (i.e. when new data file is created). It is not created when existing data file is loaded because it is supposed to be there. Old data files that still have this library with semi-standard ID will load it as before, but the ID loses its standard meaning. 2004-05-23 * filePropDialog.cpp (filePropDialog): added "File properties" main menu item and dialog * debugDialog.cpp (debugDialog): added "debug" menu item under "Help" 2004-05-20 * instDialog.cpp : built-in installer works with all supported firewall platforms: iptables, ipf, pf, ipfw and pix. * instDialog.cpp (instDialog): built-in installer reads list of files that policy compiler generated for a given firewall object ("manifest") from the .fw file and installs them on the firewall. One file in the manifest needs to be marked as executable, installer runs it after all files are copied. * all policy compilers: all compilers include a list of files generated for a given firewall object ("manifest") in .fw file. 2004-05-18 * RuleSetView.cpp (contextMenu): split long context menu that used to be shown when user clicked right mouse button on an object in a rule. Now this menu has only actions related to the object, while actions for the whole rule belong in the context menu shown when user clicks right mouse button on the rule number. * fr.po, ru.po: checked in updated French translation by Jean-Michel Poure and added some rudimentary Russian translation. Both translations are done in UTF-8. 2004-05-15 * init.cpp (init): define global var localepath that is initialized with a path to the directory where translation files (*.qm) are installed. This path is defined as $respath/locale on all systems (on Unix this typically is /usr/share/fwbuilder/locale, while on Windows and Mac it will be a subdirectory "locale" in the directory where the binary is installed) 2004-05-14 * ColorLabelMenuItem.cpp (ColorLabelMenuItem): implemented RFE #725461: "Colors". Added ability to color-code rules in the policy. User can pick one of the 7 predefined colors (plus none) in the pop-down menu that appears when they right-mouse-click on the policy or NAT rule. Custom text can be associated with each color using a panel in the Preferences dialog, this text appears as a tool tip when user flies mouse cursor over color buttons in the pop-down menu. 2004-05-12 * src/gui/ui: QT's ui translator uic creates code in this directory. This allows me to add generated files to the internationalization infrastructure (include in the .pot file). also added *.cpp files in src/gui/ui to cvs so translators can look at them to better understand context without having full QT development environment. 2004-05-09 * PolicyCompiler_ipt.cpp (processNext): fixed bug #934949: "duplicate rules". fwb_ipt created duplicate rules for a bridging firewall if fw object or its interfaces or their addresses were not in the source or desintaion 2004-05-04 * newFirewallDialog.cpp (accept): "new firewall" wizard can create a new firewall object using predefined templates from the file templates.xml (the file is a pat of the package and is installed in /usr/share/fwbuilder on Linux and in c:\FWBuilder\resources on Windows). User picks a template and the program creates a duplicate of the template object in the "User" object library. The wizard page where user picks template shows a diagram of the firewall configuration that illustrates its interfaces, their configuration and addresses. Comment text associated with template object explains its specific properties and is shown on the page as well. 2004-05-02 * templates.xml.in : a library of firewall object templates. This library is a part of the distribution and is installed in ${prefix}/share/fwbuilder on Linux and BSD and in C:FWBuilder/resources on windows (the same dir where standard objects are installed). This library is not loaded by default though. * listOfLibraries.cpp (listOfLibraries): Added a page to the preferences dialog to manage add-on libraries. The GUI maintains a list of available add-on libraries and allows user to define which ones will be automatically loaded when the GUI is started. The program always adds "standard" and "templates" libraries to the list, then scans directory $HOME/.fwbuilder/lib/ ( C:\FWBuilder\lib on windows) and adds all .fwb files found there to the list. It stores list of libraries in the user's preferences together with a boolean flag that is set if a library should be loaded on a start-up. Library added using main menu "Import Library" is also added to the list so the user can make the program load it automatically. 2004-04-29 * Makefile.in: Added support for internationalization. Using gettext 0.14.1. This is the first version where support for QT lanuage files is available, but it is not available in RedHat or other Linux distributions yet. Therefore had to copy some m4 macro colelctions from example to directory 'm4', as well as copied a Makefile.in and script remove-potcdate.sin to directory 'po'. New version of xgettext recognizes standard QT localization method tr() and can generate usual .pot files from strings used with it. The nwe msgfmt can generate .qm files from translated .po files. 2004-04-25 * instDialog.cpp (cmd): this method can be used whenever we need to execute several commands on the firewall sequentially. * (instDialog): install dialog hides incremental install options if 'diff' program can not be found (perhaps compiler that comes with it is not installed) * instDialog2.cpp (PIXincrementalInstall): integrated with fwb_pix_diff * instDialog2.cpp (PIXbackup): implemented function that stores backup copy of firewall configuration in a file 2004-04-18 * findDialog.cpp (find): 'find object' function is implemented by means of an external modeless dialog that allows for searching in the tree and or policy rules and supports matching with regular expressions. * newFirewallDialog.cpp (getInterfacesViaSNMP): 'new firewall' wizard can discover interfaces using SNMP. Finished work on the page where user can arrange interfaces according to their security levels. 2004-04-15 * newFirewallDialog.cpp (accept): added 'new firewall' wizard. Still need to work on the page where user sets security levels of interfaces. 2004-04-14 * VERSION (BETA): added a variable in the VERSION file that designates code revision as beta and stores beta testing period expiration time (+30 days). Currently only About dialog shows this time, but in the future I may make the program disable itself if it is used past this time. The released version won't have this limitation. This can be used to prompt people to upgrade, so I do not have to support old versions. 2004-04-11 * FWBSettings.cpp (restoreGeometry): added ability for dialogs to automatically remember and restore their geometry (size and relative position on the screen). Currently only main window, conflict resolution dialog and object editor dialogs do this. Geometry is stored in preferences. Main window comes up with a default geometry 100,100,750,600 (x,y,w,h) when no geometry is found in settings. 2004-04-10 * FWWindow.cpp (ConflictResolutionPredicate): implemented conflict detection and resolution for the "merge" operation. The same mechanism works for "open file" since it is also based on merge. When there is a conflict during merge, the program opens a dialog and asks the user which copy of the object they want to keep. 2004-04-09 * instDialog3.cpp (stateMachineSSHSUDO): builtin installer works with Linux/BSD systems using combination of ssh on the client side and sudo on the firewall. User provides a password for authentication and the program logs in into the firewall as that user, copies firewall script to "/etc/fw" (directory path is hardcoded), then executes it using sudo. Sudo should be configured for this user or group she belong to to be able to execute this script as root with no password. 2004-04-08 * instDialog.cpp (instDialog): added universal (hopefully) policy installer program. The program uses ssh in a background on both Unix and Windows (on Windows it requires putty/plink) to communicate with the firewall. Currently only supports PIX but I will add Linux/BSD later. Installer GUI asks user for a password. 2004-04-07 * RuleOptionsDialog.cpp (loadFWObject): added rule options dialog for ipt 2004-04-06 * FWWindow.cpp (search): implemented advanced search method that finds and highlights objects both in the tree and in any rule of any firewall. This resolves problem outlined in Feature Request #837448: '"Where used" only shows fw objects' 2004-04-04 * FWWindow.cpp (save): implemented saving data file without making copies of objects in the 'Standard' library (Feature Request #810504). This feature is considered experimental and is off by default. An option in Preferences dialog activates it. * FWWindow.cpp (load): All load is done via merging of the loaded file with a standard object tree. Now we can load files saved without copies of unused standard objects. * FWWindow.cpp (fileImport): implemented data import. Using method FWObjectDatabase::merge to merge imported data with current object tree. Only object IDs are compared, so modified standard object in the imported file will be ignored and its changes will be lost. 2004-04-03 * export.cpp (exportLibrary): Implemented library export * StartWizard.cpp (StartWizard): added simple startup wizard that asks user if they want to open existing file or create a new one. It also sets some useful preferences such as adds new file to RCS and makes the program automatically open it when it is started next time. * OSConfigurator_linux24.cpp (generateCodeForProtocolHandlers): Fixed bug #956544: "Error into load modules script generation", where generated script would not load kernel modules with names "module.ko.gz". Regular expression should match on ".ko.*$" to find these modules properly. Thanks to Andrey Kaminsky who pointed this out. * RuleSetView.cpp (doubleClicked): double-clicking on an object in the policy rule opens that object in the editor 2004-04-02 * ObjectManipulator.cpp (ObjectManipulator): using combobox widget instead of a tab widget for libraries. This way we can fit more libraries without making interface cluttered. 2004-03-31 * ipt.cpp (main): the GUI saves path to the DTD and resources in user's settings using QT QSettings class. Policy compilers and other tools can read this setting to quickly determine location of DTD and resources. 2004-03-29 * getting rid of STL classes in the GUI. The idea is to make GUI use QT classes in most of the code and use STL classes such as 'string', 'map', 'list' where it has to pass data to and from API which is STL-based. This should simplify using QT compiled without STL support (much less conversions between string and QString). 2004-03-28 * main.cpp (main): the data file can be specified on a command line both as an argument for option '-f' and after all options. Option '-f' is preserved for compatibility with old versions. Preferred method is to specify the file name as a parameter without any option: "fwbuilder file.fwb" 2004-03-27 * platforms.cpp (getVersionsForPlatform): usability improvement: "combo boxes" that do not allow typing in them should not have empty choices. Fixed this for a drop-down menu of version numbers in firewall dialog. 2004-03-26 * RuleSetView.cpp (insertRule): counting rules from zero in the GUI * (RuleSetView): this is not a change, I just wanted to document that I tested the GUI with a policy that has 1000 rules. I haven't noticed any delay in loading this policy compared with when it had <100 rules. 2004-03-25 * FWWindow.cpp (fileSaveAs): gui automatically chooses working dir if none is set and user calls 'file save as' menu item : * on Unix will use current dir. * on Windows will use user's document dir. * NATCompiler_ipt.cpp (processNext): added a workaround for a bug (no number): if address range object was used in SNAT or DNAT rule and option 'manage virtual addresses' was on, compilerwould not add virtual address properly. It still won't do it, but at least there is a check for this situation and it prints appropriate warning message. The problem with this is that if the range is large, we end up with potentially lots of virtual addresses. Let the user deal with this themselves. * ipt.cpp: compiler(s) understand new command line option '-R', which should specify a full path to the resources. This is useful on Windows and Mac where resources are installed in a non-fixed place by the GUI package, but need to be used by the compilers. 2004-03-24 * ObjectManipulator.cpp (contextMenu): each system group object in the tree has an item in its pop-down menu that allows user to quickly add an object to that group. * IPv4Dialog.cpp (DNSlookup): added ability to determine IP address of an Address object using DNS lookup (using QDns class) * FWBSettings.cpp (FWBSettings): explicitly setting scope for QSettings as "User" 2004-03-22 * ObjectManipulator.cpp (addTreePage): added attribute 'ro' to all elements in DTD (see API). This provides for a way of locking down parts of the tree. * ObjectManipulator.cpp (addTreePage): read-only subtrees are marked with an icon of a lock and text 'read-only' * objects_init.xml : standard objects tree is now read-only. User objects can not be moved into 'standard' tree and standard objects can not be edited but can be duplicated (a copy is automatically created in the first user-defined library, most often it is a library 'User') * FWWindow.cpp (install): GUI supplies a path to the firewall object as a parameter to installation script rather than just its name (as before). This is because the path has changed when library element has been added. Changes made in the GUI (send path instead of name) and in fwb_install script (to make it interpret path). 2004-03-21 * pixosAdvancedDialog.cpp (pixosAdvancedDialog): 'advanced host settings' dialog for PIX * RuleSetView.cpp (contentsMousePressEvent): selectedObject is chosen in mouse press and key press even handlers; got rid of currentChanged slot all together. This eliminated flicker that was caused by extra repaint of the cell when selected object was chosen in currentChanged slot. 2004-03-20 * DialogData.cpp (DialogOption): universal class to load and save data in dialogs * pixAdvancedDialog.cpp (pixAdvancedDialog): 'advanced' firewall options dialog for PIX. Implemented tabls 'Compiler options', 'Prolog/Epilog', 'Timeouts' and partially 'Fixups'. Fixup pages are disabled using resource string that defines which fixups are available in certain PIX version. * FirewallDialog.cpp (openFWDialog): firewall dialog saves version from the widget to the object before opening 'advanced' firewall options dialog. This is a departure from the dialog logic where all data is stored when user clicks 'Apply changes' button. 2004-03-19 * FWBSettings.cpp: added support for an "object autosave" option (automatic saving of changes in dialogs while switching between objects) * RuleSetView.cpp (insertRule): added main menu items "insert rule" and "add rule after current" * RuleSetView.cpp (contextMenu): added pop-up menu items for adding, removing and moving rules up and down, as well as standard copy/cut/paste operations on moves. Similar menu items added to the main menu. * RuleSetView.cpp (paintCell): implemented double-buffering in paintCell to improve performance and remove flickering 2004-03-17 * FWBSettings.cpp: saving the size of the info window in settings * RCSFileDialog.cpp (RCSFileDialog): 'open file' dialog automatically looks for files in the working directory configured in a global preferences dialog. * main.cpp (main): added a global setting "startup action" in Preferences. Currently two actions are available: "load standard objects" and "load last edited file". * FWBSettings.cpp (FWBSettings): a specialized wrapper for QSettings. I will be adding methods to this class to simplify access to whatever global program preferences and options I need. Currently it supports 'working dir' and 'info window style' settings. Settings are stored in a platform-depended way as QSettings does it. 2004-03-16 * NATCompiler_ipt_writers.cpp (_printOPorts): minor bugifx - fixed typo ( '==' -> '=' ) * ObjectEditor.cpp (closeEvent): object editor checks for modifications before closing if user closes it using window manager buttons. * FWWindow.cpp (unselectRules): the main window maintains single selection across objects in the tree and in the policy view. Selecting an object in the tree automatically unselects object in the policy and vice versa. Now I can implement copy/cut/paste functions driven by the main menu; these operations will work on the currently selected object either in the tree or in the policy. * FWWindow.cpp (editCut): copy/cut/paste operations work between the tree and policy views using both context menus and main menu. * ipt.cpp: output stream is created with a mode ios::binary on Windows * RCS.cpp (isDiff): having problems with rcsdiff.exe in windows, for now will assume that the file always changes and needs checkin comment. 2004-03-15 * RCS.cpp (co): using windows-specific functions to create a temporary file for the file checkout * global.h: added redefinition of macro assert to be able to use it on windows where we compile without debugging info. (the reason I do not build Debug version on win32 is because I use precompiled libraries libxml2 etc that are built using Release CRT, and I can't mix different runtimes). * RCS.cpp (co): GUI makes sure that if the file has been opened and locked by a user, another user can only open it read-only. The same user has a choice of opening it read-only or read-write. The latter case is useful in case of a program crash that leaves opened files in the locked state. * RCS.cpp (co): added ability to open older revision of the file read-only. Requested revision is checked out into temporary file, which is then loaded and immediately deleted. The object tree is locked read-only and 'save' and 'save as' operations are disabled. 2004-03-14 * RCS.cpp (add): using "rcs -i -kb" to add a file to RCS, this should help avoid extra CR in the file while working on windows because it makes RCS use binary mode while working with the file. 2004-03-13 * ObjectManipulator.cpp: GUI redesign: switched to a single window design. Object manipulation happens inside three classes: ObjectManipulator (the tree widgets and algorithms), ObjectEditor (a stack of editor widgets and a glue logic), obejct info browser (class QTextBrowser). Object editor appears as a non-modal dialog when user double-clicks an object in the tree. Single click updates data in the info window but does not open the editor. Objects can be selected in the tree in any supported way - keyboard arrows, keyboard shortcuts, hitting the first letter of the objects's name, mouse click. In any case, appropriate object is selected and info window is updated with its attributes. Info window has three modes: collapsed (there is no info window), showing only comment attrbibute and showing brief summary of object's parameters and a comment. User can switch between modes using a button located on the main window panel directly under the info widget. 2004-03-12 * build environment is based on qmake: file qmake.inc is included from qmake project files in all subdirectories. File qmake.inc defines all variables for all platforms, so project files in subdirs only add lists of files and take care of exceptions. File qmake.inc is generated by configure, but all substitutions are only needed for Unix and Mac. This file is checked in to cvs so it could be used on Windows without a need to run configure. All qmake project files in subdirectories need no substitutions by configure, so they all are checked in to cvs and can be used on windows right away. Qmake project files fwbuilder2.pro and src/src.pro use template 'subdirs' and make qmake descent into subdirectories and rebuild projects there. Now using qmake to generate Makefile and MSVC project files in src/fwblookup, src/fwbedit, src/ipt. Makes it easier to generate consistent MSVC projects without having to edit them manually. resource files (src/res/*.xml and src/res/*/*.xml) are generated by configure, however, since substitutions made in them are only relevant on Unix and Mac, generated files are checked in to cvs so they can be used on windows without running configure. No need to run configure (or autogen.sh) on Windows anymore. To build on Unix and Mac: $ autogen.sh $ make $ make install To build on windows: run qmake, then make in the root dir. of the project Open fwbuilder2.dsw in MSVC and rebuild all * NATCompiler_ipt.cpp, PolicyCompiler_ipt.cpp and others in src/ipt: code cleanup. Removed all unused variables and added handling for 'default' case in switch operators. 2004-03-10 * FWWindow.cpp (compile): implemented main menu items "Rules/compile" and "Rules/install". Still need to add toolbar buttons though. * execDialog.cpp (execDialog): a dialog for a background execution of external commands. This class is used to call external policy compilers and installer scripts. Uses QT class QProcess. * ipt.cpp: transfered compiler for iptables over to fwb2. Only minor changes: new file name schema (*.h, *.cpp); proper choice of the directory where resource files are located; eliminated last dependencies on glib 2004-03-09 * iptAdvancedDialog.cpp (accept): firewall settings dialog saves all data in the object. 2004-03-07 * iptAdvancedDialog.cpp (iptAdvancedDialog): firewall settings dialog for iptables. Saving of the data back in the firewall object is not implemented yet. * DialogFactory.cpp (createDialog): DialogFactory: class that creates dialogs for all object types. * FWBTree.cpp (FWBTree): refactored code: all methods that enforce our standard tree structure now belong to the class FWBTree * TimeDialog.cpp (applyChanges): added dialog for the Time interval object. 2004-03-06 * GroupObjectDialog.cpp (setupPopupMenu): added pop-up menu in the group view (both icon and list modes) with oprations copy,cut,paste and delete. * all dialogs: object is moved from library to library when user clicks 'apply changes' (before it would move immediately when the library was changed in the pop-down menu). * CustomServiceDialog.cpp (loadFWObject): added dialog for the Custom Service object 2004-03-05 * PropertyEditor.cpp (copyObj): added pop-up menu to object tree view; implemented functions 'duplicate', 'copy', 'cut', 'paste' 2004-03-04 * ObjectTreeView.cpp (contentsMouseReleaseEvent): objects in the tree are selected with double-click. 2004-03-03 * RuleSetView.cpp (getRE): added platform capabilities check for columns 'Time' and 'log/options' in policy views * RuleSetView.cpp (dragMoveEvent): support for d&d of Time objects 2004-03-02 * InterfaceDialog.cpp (loadFWObject): added dialog elements for interface security level, 'external' checkbox, network zone. * RCS.cpp (isDiff): added a wrapper for rcsdiff in RCS class 2004-02-29 * PropertyEditor.cpp (createObject): properly creating interfaces and addresses for the firewall object * further testing and improvements in RCS integration 2004-02-28 * FWWindow.cpp (load): file can be opened with or without RCS, a head revision or any specific revision, read-write or read-only. File name, revision number and read-only status is displayed on the main window's title bar. * FWWindow.cpp (load): added ability to open data files read-only * RCS.cpp (RCS): refactored the code, made class RCS a wrapper for the command-line rcs tools. It should be possible to use the same or similar interface for other version control system if needed. 2004-02-26 * RCSFilePreview.cpp (showFileRLog): Open File dialog shows RCS revisions of the chosen file in a preview panel. Added button "add to RCS" that allows user to add selected file to RCS right from the "open file" dialog. Added elements for opening file read-only and with or without locking (but these functions have not been implemented yet). 2004-02-23 * RCS.cpp (rlog): class RCS provides simple integration with RCS. Uses portable functions provided by QT to call external RCS programs. * configure.in: added checks for external RCS programs ci, co, rlog. 2004-02-22 * FWWindow.cpp: added basic integration with RCS. Every time a data file is opened, it is checked out from RCS and locked. If the file has not been added to RCS, an initial checkin is performed with a generic comment. Every time an opened file is saved (using "save" or "save as" menu), it is checked in and kept in a locked state. A new menu item "File/Close" has been added; this menu item checks the file in and removes lock (does 'ci -u') so other users can work on it, then it reopens a standard objects database in the GUI. Opening a file while another file is already opened in the GUI causes the latter to be closed (checked in and lock removed) and a new one opened as described above. still TODO: add a dialog to ask the user for a checkin comment text. Add a global option "Use RCS" so that using version control is optional. Test the whole thing on Windows. 2004-02-16 * PropertyEditor.cpp (PropertyEditor): added dialogs for interface, MAC address, network, address range and other objects. * FWObjectDrag.h: implemented custom drag class FWObjectDrag; all widgets dynamically check if the object being dragged can be dropped in them. User can drag objects from the tree into groups and rules, as well as from a group into the tree. 2004-02-08 * IPServiceDialog.cpp (libChanged): implemented gui elements and support for moving objects between libraries. 2004-01-20 * added dialog for object IPv4. This object can now be created in a standard place in the tree in a group Objects/Addresses as well as as a child object of interface (as before in fwbuilder 1). This allows for using object IPv4 as an abstract for an IP address which is simpler than using a Host object. 2004-01-04 * GroupObjectDialog.cpp: Experiment: user and standard object tree views have different background colors. This provides simple visual clue of what library the object shown in the editor panel belongs to. This is especially useful if a standard object is referenced from the user defined group and user opens it; in this case the tree switches from user-defined objects to the standard onces but this switch may not be evident from the first glance, thus user loses context and may be confused why his objects apparently have gone away. 2004-01-03 * PropertyEditor.cpp (PropertyEditor): property editor has window type "dialog" and always stays on top of the main window. Implemented simple history feature for the object navigation and added a button "Back" to the toolbar. * GroupObjectDialog.cpp (loadFWObject): group object dialog can now show group contents as a set of icons or as a list; switching between two modes is done using toggle buttons a-la file list modes in the "open file" dialog. * PropertyEditor.cpp (loadObjects): merged object tree and object property editor in one dialog. 2003-12-20 * main.cpp (main): resources and preferences files can now be found dynamically, using a full path to the directory the binary has been launched from. The RES_DIR macro defined in config.h now specifies relative path to the resource files starting from the application root dir. If program is installed in /usr/local/bin, then the application root is "/usr/local" and resources should be located in /usr/local/$RES_DIR directory. fwbuilder-5.1.0.3599/doc/examples.fwb0000644000175000017500000005407611733011756020075 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/doc/fwb_pix.10000644000175000017500000000425511733011756017271 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_pix 1 "" FWB "Firewall Builder" .SH NAME fwb_ipt \- Policy compiler for Cisco PIX .SH SYNOPSIS .B fwb_pix .RB -f data_file.xml .RB [-V] .RB [-d wdir] .RB [-i] .RB [-v] .RB [-xc] .RB [-xt] object_name .SH "DESCRIPTION" .B fwb_pix is firewall policy compiler component of Firewall Builder (see fwbuilder(1)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates resultant Cisco PIX configuration file. The configuration is written to the file with the name the same as the name of the firewall object, plus extension ".fw". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-d wdir" Specify working directory. Compiler creates file with PIX configuration in this directory. If this parameter is missing, then PIX configuration will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-i" When this option is present, the last argument on the command line is supposed to be firewall object ID rather than its name .IP "-xc" When output file name is determined automatically (i.e. flags -o or -O are not present), the file name is composed of the cluster name and member firewall name rather than just member firewall name. This is used mostly for testing when the same member firewall object can be a part of different clusters with different configurations. .IP "-xt" This flag makes compiler treat all fatal errors as warnings and continue processing rules. Generated configuration script most likely will be incorrect but will include error message as a comment; this flag is used for testing and debugging. .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipf(1), .BR fwb_ipt(1) .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/COPYING0000644000175000017500000004311011733011756016575 0ustar sylvestresylvestre GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. fwbuilder-5.1.0.3599/doc/README.ipf0000644000175000017500000001041211733011756017176 0ustar sylvestresylvestrefwb_ipf(1) Firewall Builder fwb_ipf(1) NNAAMMEE fwb_ipf - Policy compiler for ipfilter SSYYNNOOPPSSIISS ffwwbb__iippff [[--vvVVxx]] [[--dd wwddiirr]] --ff ddaattaa__ffiillee..xxmmll object_name DDEESSCCRRIIPPTTIIOONN ffwwbb__iippff is a firewall policy compiler component of Fire­ wall Builder (see fwbuilder(1)). This compiler generates code for ipfilter. Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates ipfilter configuration files and firewall activation script. All generated files have names that start with the name of the firewall object. Firewall activation script has exten­ sion ".fw" and is simple shell script that flushes current policy, loads new filter and nat rules and then activates ipfilter. IPFilter configuration file name starts with the name of the firewall object, plus "-ipf.conf". NAT configuration file name also starts with the name of the firewall object, plus "-nat.conf". For example, if fire­ wall object has name "myfirewall", then compiler will cre­ ate three files: "myfirewall.fw", "myfirewall-pf.conf", "myfirewall-nat.conf". The data file and the name of the firewall objects must be specified on the command line. Other command line parame­ ters are optional. OOPPTTIIOONNSS -f FILE Specify the name of the data file to be processed. -d wdir Specify working directory. Compiler creates firewall activation script and ipfilter configura­ tion files in this directory. If this parameter is missing, then all files will be placed in the cur­ rent working directory. -v Be verbose: compiler prints diagnostic messages when it works. -V Print version number and quit. -x Generate debugging information while working. This option is intended for debugging only and may pro­ duce lots of cryptic messages. NNOOTTEESS Support for ipf returned in version 1.0.1 of Firewall Builder Supported features: o both ipf.conf and nat.conf files are generated o negation in policy rules o stateful inspection in individual rule can be turned off in rule options dialog. By default com­ piler adds "keep state" or "modulate state" to each rule with action 'pass' o rule options dialog provides a choice of icmp or tcp rst replies for rules with action "Reject" o compiler adds flag "allow-opts" if match on ip options is needed o compiler can generate rules matching on TCP flags o compiler can generate script adding ip aliases for NAT rules using addresses that do not belong to any interface of the firewall o compiler always adds rule "block quick all" at the very bottom of the script to ensure "block all by default" policy even if the policy is empty. o Address ranges in both policy and NAT Features that are not supported (yet) o negation in NAT o custom services Features that won't be supported (at least not anytime soon) o policy routing UURRLL Firewall Builder home page is located at the following URL: hhttttpp::////wwwwww..ffwwbbuuiillddeerr..oorrgg// BBUUGGSS Please report bugs using bug tracking system on Source­ Forge: hhttttpp::////ssoouurrcceeffoorrggee..nneett//ttrraacckkeerr//??ggrroouupp__iidd==55331144&&aattiidd==110055331144 SSEEEE AALLSSOO ffwwbbuuiillddeerr((11)),, ffwwbb__iipptt((11)),, ffwwbb__ppff((11)) FWB fwb_ipf(1) fwbuilder-5.1.0.3599/doc/fwb_pf.10000644000175000017500000000722011733011756017071 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_pf 1 "" FWB "Firewall Builder" .SH NAME fwb_pf \- Policy compiler for OpenBSD packet filter "pf" .SH SYNOPSIS .B fwb_pf .B [-vVx] .B [-d wdir] .B [-o output.fw] .B [-i] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_pf is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for OpenBSD Packet Filter (pf). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates pf configuration files and firewall activation script. All generated files have names that start with the name of the firewall object. Firewall activation script has extension ".fw" and is simple shell script that flushes current policy, loads new filter and nat rules and then activates pf. PF configuration file name starts with the name of the firewall object, plus "-pf.conf". NAT configuration file name also starts with the name of the firewall object, plus "-nat.conf". For example, if firewall object has name "myfirewall", then compiler will create three files: "myfirewall.fw", "myfirewall-pf.conf", "myfirewall-nat.conf". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates firewall activation script and PF configuration files in this directory. If this parameter is missing, then all files will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-i" When this option is present, the last argument on the command line is supposed to be firewall object ID rather than its name .IP "-x" Generate debugging information while working. This option is intended for debugging only and may produce lots of cryptic messages. .SH NOTES Support for PF has been introduced in version 1.0.1 of Firewall Builder Supported features: .IP o both pf.conf and nat.conf files are generated .IP o negation in policy and NAT rules .IP o grouping in "from", "to" and ports using '{' '}' syntax .IP o if checkbox "Scrub" is checked in the rule options dialog, and rule's action is Accept, the compiler generates two (almost) identical rules: first with action 'scrub' and the second with action 'pass quick' .IP o stateful inspection in individual rule can be turned off in rule options dialog. By default compiler adds "keep state" or "modulate state" to each rule with action 'pass' .IP o rule options dialog provides a choice of icmp or tcp rst replies for rules with action "Reject" .IP o compiler adds flag "allow-opts" if match on ip options is needed .IP o compiler can generate rules matching on TCP flags .IP o compiler can generate script adding ip aliases for NAT rules using addresses that do not belong to any interface of the firewall .IP o compiler always adds rule "block quick all" at the very bottom of the script to ensure "block all by default" policy even if the policy is empty. .IP o Address ranges in both policy and NAT .PP Features that are not supported (yet) .IP o custom services .PP What will not be supported (at least not anytime soon) .IP o policy routing .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_ipf(1) .P fwbuilder-5.1.0.3599/doc/README.policy_import0000644000175000017500000001447011733011756021321 0ustar sylvestresylvestre Policy importer has been implemented as part of the Firewall Builder GUI as of version 2.1.12. The first functional build were importer worked on all supported OS was build 270 (May 22, 2007) Policy importer uses ANTLR lexer and parser ( http://www.antlr.org/ ) Version 2.7.7 is used in Firewall Builder v2.1.12 ( http://www.antlr2.org/ ) Firewall Builder needs ANTLR C++ runtime header files and library and include these in the source tree under src/antlr. Unless you want to change the grammar (*.g files) you don't need to install ANTLR separately. All relevant ANTLR files are included in the package. For more information on ANTRL see: http://www.antlr2.org Policy import iptables configurations (v2.1.12, build 281 and later) ---------------------------------------------------------------- Features implemented in this version : - Importer can parse iptables config saved using iptables-save utility. Because of the huge variety of iptables modules, Importer can only interpret basic iptables configuration and a subset of modules. Currently the following modules are supported: * state * multiport * limit * mark - Importer creates firewall object with all interfaces. It can not assign object name for the firewall object nor add IP and MAC addresses to interfaces because this information is not present in iptables-save file. - option "Assume firewall is part of 'any'" is off in the created firewall object. Import is done this way in order to preserve logic of chains INPUT, OUTPUT and FORWARD in the recreated fwbuilder rules. Rules that had chain INPUT in the imported script will have firewall object in "destination" in the corresponding fwbuilder rules. Firewall object is placed in "Source" for rules with chain OUTPUT. For rules with chain FORWARD rule elements "Source" and "Destination" are populated with objects created using options "-s" and "-d" of the original rules or left empty ("any"). - all recognized iptables rules are imported and interface and direction are set in all rules appropriately. Interface objects are created as parser finds them in the script. - targets ACCEPT, DROP, REJECT, MARK and others are converted to the corresponding fwbuilder policy rule actions. Unrecognized targets and converted to branching rules, where the name of the target becomes the name of the branch. - SNAT, DNAT, MASQUERADING, REDIRECT and NETMAP targets and their parameters are recognized in the NAT rules. - Address and service objects are created in the process for all addresses and ports used in all rules. - iptables rules can refer to tcp/udp ports both by name or by number. Importer can properly interpret both formats using system function getservbyname() to convert service name to the port number. Since the result of this function depends on the OS, some port names may not convert on some systems. For example, Windows can convert more limited set of service names compared to Linux or BSD. - targets LOG and ULOG are converted to the "logging" option in fwbuilder rules with action "Continue". This is an empty action that does not affect packet flow through the firewall but can be used in combination with "logging" option to log the packet. If such empty (logging-only) rule is undesired, it must be manually merged with some other rule in the policy. - "--log-prefix", and "--log-level" options of the LOG target are recognized - "--ulog-prefix" option of the ULOG target is recognized. Other options of the ULOG target are not. - Address and service objects are reused in the process of import. - in case when importer fails to parse some part of the iptables-save file, corresponding policy rule is colored red and appropriate diagnostic message added to its comment. The problem must be corrected manually. - comments ("#") found inside access lists are ignored. Shortcomings of this version: - user-defined chains in table "nat" are not supported - no import of time intervals - no MAC address matching import Policy import of Cisco IOS access lists (v2.1.12, build 270) ---------------------------------------------------------------- Features implemented in this version : - Importer can parse router config saved using "show run" command. Although importer can only interpret a subset of IOS configuration commands, other commands that it does not understand will be ignored and should not affect operation. No manual editing of the config is required prior to import. - Importer creates firewall object with all interfaces - firewall object name is assigned if "hostname" command is found in the configuration. If this command is not present, the name remains generic "New Firewall" - interface addresses are assigned if command "ip address" is found (multiple addresses per interface are supported). Interfaces without "ip address" in the configuration are marked as "unnumbered" in the firewall builder object tree. - all access lists are imported and interface and direction are set in all rules appropriately - Address and service objects are created in the process for all addresses and ports used in access lists - IOS access lists can define ip protocol, icmp code and type, and tcp/udp ports both by name or by number. Importer can properly interpret both formats. - "log", "log-input", "fragments", "established" keywords are supported and translated into rule or object options as appropriate. - Address and service objects are reused in the process of import. - in case when importer fails to parse some part of the access-list command, corresponding policy rule is colored in red and appropriate diagnostic message added to its comment. The problem must be corrected manually. - "remark" commands found inside access lists are translated into rule comments - comments ("!") found inside access lists are ignored. Shortcomings of this version: - importer does not use address and service objects that existed in the tree before the operation has started, it creates new ones. Deduplication only works for objects created in the process of import. - the following keywords available in extended access lists are not supported at this time: tos, precedence, time-range. - igmp access lists are not parsed. fwbuilder-5.1.0.3599/doc/FWBuilder-Routing-LICENSE.txt0000644000175000017500000000231611733011756022636 0ustar sylvestresylvestre Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. fwbuilder-5.1.0.3599/doc/fwb_install.10000644000175000017500000000707511733011756020142 0ustar sylvestresylvestre.\"-*- mode: nroff; tab-width: 4; -*- .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_install 1 "" FWB "Firewall Builder" .SH NAME fwb_install \- Firewall policy installation and activation script .SH SYNOPSIS .B fwb_install .B [-d wdir] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_install is firewall policy installation and activation script for Firewall Builder (see fwbuilder(1)). This script transfers compiled rulesets via ssh to a firewall and activates them. Optionally it transfers a backup of the .xml source file, too. .PP The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .PP The firewall rules should allow ssh traffic to the firewall, or you will lock yourself out. .PP .SH INSTALLATION You should have a ssh and sshd installed and configured properly. .PP Make a public/private keypair using ssh-keygen tool, the public key goes into ~$REMOTEUSER/.ssh/ on the firewall, $SSHIDENTITY locally points to the private key. Protect your key with a good passphrase! .PP Tell fwbuilder to use the script: enter /home/vadim/Projects/fwb/fwbuilder/../usr//bin/fwb_install (a full path and name for this script) in the "install script" entry field in the firewall object dialog. .PP To customize the script you can adjust the following variables inside of it : .PP .PD 0 .TP .B REMOTEDIR Specifies where the firewall script or configuration file will be placed on the firewall (default: "/etc/firewall") .TP .B REMOTEUSER Specifies the user on the firewall allowed to set up the firewall rulesets (default: "root") .TP .B DOXMLBACKUP Specifies whether we want to store a backup copy of the .xml on the firewall (default: "YES") .TP .B SSHIDENTITY location of private ssh key (default: "${HOME}/.ssh/id_dsa") .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-d wdir" Specify working directory. Policy compilers create firewall configurations and/or scripts in this directory. If this parameter is missing, then script looks in the current working directory. .SH CAVEATS The firewall rules should allow ssh traffic to the firewall, or you will lock yourself out. .PP The script uses address of firewall's interface which is marked as "management". The script aborts if there is no management interface. .PP There still is a depenency on the current DTD structure in that the script assumes that all firewalls are always located in the tree branch "Firewalls". This may change in the future; the script will need to be updated then. .PP This script has been developed and tested for iptables firewall on Linux systems. To the best of my knowledge, nobody used this script for any other firewall type or OS, however it should work for any firewall running on a Unix box where firewall configuration is represented in a form of a shell script. On example is ipfw used on FreeBSD or Mac OS X. .PP .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH AUTHOR David Gullasch , Changes and corrections by Vadim Kurland .SH DISCLAIMER (K) 2001 by David Gullasch , All rights reversed. Copy what you like, but give credit and include this note. Don't blame me when this script does not do what you want it to - there is no bug-free software. .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_ipf(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/fwbuilder.10000644000175000017500000000525311733011756017615 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwbuilder 1 "" FWB "Firewall Builder" .SH NAME fwbuilder \- Multiplatform firewall configuration tool .SH SYNOPSIS .B /usr/bin/fwbuilder .RB [-f file.fwb] .RB [-d] .RB [-h] .RB [-o file] .RB [-P object_name] .RB [-r] .RB [-v] .SH "DESCRIPTION" .B fwbuilder is the Graphic User Interface (GUI) component of Firewall Builder. Firewall Builder consists of a GUI and set of policy compilers for various firewall platforms. It helps users maintain a database of objects and allows policy editing using simple drag-and-drop operations. GUI generates firewall description in the form of XML file, which compilers then interpret and generate platform-specific code. Several algorithms are provided for automated network objects discovery and bulk import of data. The GUI and policy compilers are completely independent, this provides for a consistent abstract model and the same GUI for different firewall platforms. Firewall Builder supports firewalls based on iptables (Linux kernel 2.4.x and 2.6.x, see fwb_ipt(1)), ipfilter (variety of platforms including *BSD, Solaris and others, see fwb_ipf(1)), pf (OpenBSD and FreeBSD, see fwb_pf(1)), ipfw (FreeBSD and others), Cisco PIX (v6.x and 7.x) and Cisco IOS extended access lists. .SH OPTIONS .IP "-f FILE" Specify the name of the file to be loaded when program starts. .IP "-r" When this command line option is given in combination with -f file, the program automatically opens RCS head revision of the file if file is in RCS. If file is not in RCS, this option does nothing and the file is opened as usual. .IP "-d" Turns on debug mode. Note that in this mode the program generates lots of output on standard error. This is used for debugging. .IP "-h" Prints brief help message .IP "-o file" Specify the name of the file for the print output, see option "-P". .IP "-P object_name" Print rules and objects for the firewall object "object_name" and immediately exit. The program does not go into interactive mode. Print output will be placed in the file specified with "-o" option. If file name is not given with option "-o", print output is stored in the file "print.pdf" in the current directory. .SH FILES .IP $HOME/.qt/firewallbuilder2rc Fwbuilder v2.1 stores user preferences in this file. .IP $HOME/.config/netcitadel.com/Firewall\ Builder.conf Fwbuilder v3.0 stores user preferences in this file. .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwblookup(1), .BR fwb_ipt(1), .BR fwb_ipf(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/fwb_ipf21.10000644000175000017500000000637411733011756017416 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_ipf 1 "" FWB "Firewall Builder" .SH NAME fwb_ipf \- Policy compiler for ipfilter .SH SYNOPSIS .B fwb_ipf .B [-vVx] .B [-d wdir] .B [-o output.fw] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_ipf is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for ipfilter. Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates ipfilter configuration files and firewall activation script. All generated files have names that start with the name of the firewall object. Firewall activation script has extension ".fw" and is simple shell script that flushes current policy, loads new filter and nat rules and then activates ipfilter. IPFilter configuration file name starts with the name of the firewall object, plus "-ipf.conf". NAT configuration file name also starts with the name of the firewall object, plus "-nat.conf". For example, if firewall object has name "myfirewall", then compiler will create three files: "myfirewall.fw", "myfirewall-pf.conf", "myfirewall-nat.conf". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates firewall activation script and ipfilter configuration files in this directory. If this parameter is missing, then all files will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-x" Generate debugging information while working. This option is intended for debugging only and may produce lots of cryptic messages. .SH NOTES Support for ipf returned in version 1.0.1 of Firewall Builder Supported features: .IP o both ipf.conf and nat.conf files are generated .IP o negation in policy rules .IP o stateful inspection in individual rule can be turned off in rule options dialog. By default compiler adds "keep state" or "modulate state" to each rule with action 'pass' .IP o rule options dialog provides a choice of icmp or tcp rst replies for rules with action "Reject" .IP o compiler adds flag "allow-opts" if match on ip options is needed .IP o compiler can generate rules matching on TCP flags .IP o compiler can generate script adding ip aliases for NAT rules using addresses that do not belong to any interface of the firewall .IP o compiler always adds rule "block quick all" at the very bottom of the script to ensure "block all by default" policy even if the policy is empty. .IP o Address ranges in both policy and NAT .PP Features that are not supported (yet) .IP o negation in NAT .IP o custom services .PP Features that won't be supported (at least not anytime soon) .IP o policy routing .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/fwb_pf21.10000644000175000017500000000700111733011756017231 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwb_pf 1 "" FWB "Firewall Builder" .SH NAME fwb_pf \- Policy compiler for OpenBSD packet filter "pf" .SH SYNOPSIS .B fwb_pf .B [-vVx] .B [-d wdir] .B [-o output.fw] .B -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_pf is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). This compiler generates code for OpenBSD Packet Filter (pf). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates pf configuration files and firewall activation script. All generated files have names that start with the name of the firewall object. Firewall activation script has extension ".fw" and is simple shell script that flushes current policy, loads new filter and nat rules and then activates pf. PF configuration file name starts with the name of the firewall object, plus "-pf.conf". NAT configuration file name also starts with the name of the firewall object, plus "-nat.conf". For example, if firewall object has name "myfirewall", then compiler will create three files: "myfirewall.fw", "myfirewall-pf.conf", "myfirewall-nat.conf". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates firewall activation script and PF configuration files in this directory. If this parameter is missing, then all files will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .IP "-x" Generate debugging information while working. This option is intended for debugging only and may produce lots of cryptic messages. .SH NOTES Support for PF has been introduced in version 1.0.1 of Firewall Builder Supported features: .IP o both pf.conf and nat.conf files are generated .IP o negation in policy and NAT rules .IP o grouping in "from", "to" and ports using '{' '}' syntax .IP o if checkbox "Scrub" is checked in the rule options dialog, and rule's action is Accept, the compiler generates two (almost) identical rules: first with action 'scrub' and the second with action 'pass quick' .IP o stateful inspection in individual rule can be turned off in rule options dialog. By default compiler adds "keep state" or "modulate state" to each rule with action 'pass' .IP o rule options dialog provides a choice of icmp or tcp rst replies for rules with action "Reject" .IP o compiler adds flag "allow-opts" if match on ip options is needed .IP o compiler can generate rules matching on TCP flags .IP o compiler can generate script adding ip aliases for NAT rules using addresses that do not belong to any interface of the firewall .IP o compiler always adds rule "block quick all" at the very bottom of the script to ensure "block all by default" policy even if the policy is empty. .IP o Address ranges in both policy and NAT .PP Features that are not supported (yet) .IP o custom services .PP What will not be supported (at least not anytime soon) .IP o policy routing .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipt(1), .BR fwb_ipf(1) .P fwbuilder-5.1.0.3599/doc/cisco_doc_15244_example.fwb0000644000175000017500000025453611733011756022461 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/doc/fwbedit21.10000644000175000017500000000500311733011756017412 0ustar sylvestresylvestre.TH fwbedit 1 "" FWB "Firewall Builder" .LO 1 .SH NAME fwbedit \- General purpose object tree editing tool .SH SYNOPSIS .B fwbedit .RB [-a obj,grp] .RB [-r obj,grp] .RB [-d obj] .RB -f data_file.xml .SH "DESCRIPTION" .B fwbedit is a general purpose object tree editing tool for Firewall Builder (see fwbuilder(1)). This tool can be used in the shell scripts written for batch-processing of the Firewall Builder data files. Fwbedit can perform the following operations on the objects and the tree: add a reference to the given object to a group, remove reference to an object from a group and delete an object and all references to it from the tree. Both object and a group can be specified by their ID or by their name and a full path in the tree (see section .B EXAMPLES below). .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-a obj,grp" Adds reference to object 'obj' to the group 'grp'. .IP "-r obj,grp" Removes reference to object 'obj' from the group 'grp'. .IP "-d obj" Deletes object 'obj' and references to it from all groups and rules. .IP "-V" Prints version number and quit. .SH EXAMPLES .PP fwbedit -f x.xml -a /Objects/Hosts/A,/Objects/Groups/B .PP Adds reference to the Host object 'A' to the group 'B'. .PP .PP fwbedit -f x.xml -a id3D71A1BA,id3D151943 .PP Adds reference to the object with ID id3D71A1BA to the group with ID id3D151943. If objects with given IDs do not exist, fwbedit prints an error message and does not make any changes in the data file. .PP .PP fwbedit -f x.xml -a id3D71A1BA,/Objects/Groups/testgroup .PP Adds reference to the object with ID id3D71A1BA to the group 'testgroup'. .PP .PP fwbedit can be used in combination with fwblookup to execute operations on many objects: .LP fwblookup -f x.xml -lP /Objects/Hosts | \\ grep domain.com | \\ while read h; do \\ fwbedit -f x.xml -a $h,/Objects/Groups/domainGRP; \\ done .PP first, this script uses fwblookup to print full path of all Host objects (option -l in combination with option -P prints full path for all children objects of /Objects/Hosts), then uses grep to filter only those hosts that have 'domain.com' in their name, then cycles through the obtained list and uses fwbedit to add them to the group 'domainGRP'. .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwblookup(1), .P fwbuilder-5.1.0.3599/doc/fwb_ipt21.10000644000175000017500000000264311733011756017427 0ustar sylvestresylvestre.TH fwb_ipt 1 "" FWB "Firewall Builder" .SH NAME fwb_ipt \- Policy compiler for iptables .SH SYNOPSIS .B fwb_ipt .RB [-wvV] .RB [-d wdir] .RB [-o output.fw] .RB -f data_file.xml object_name .SH "DESCRIPTION" .B fwb_ipt is a firewall policy compiler component of Firewall Builder (see fwbuilder(1)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates resultant iptables script. The script is written to the file with the name the same as the name of the firewall object, plus extension ".fw". The data file and the name of the firewall objects must be specified on the command line. Other command line parameters are optional. .SH OPTIONS .IP "-f FILE" Specify the name of the data file to be processed. .IP "-o output.fw" Specify output file name .IP "-d wdir" Specify working directory. Compiler creates file with iptables script in this directory. If this parameter is missing, then iptables script will be placed in the current working directory. .IP "-v" Be verbose: compiler prints diagnostic messages when it works. .IP "-V" Print version number and quit. .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwbuilder(1), .BR fwb_ipf(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/AUTHORS0000644000175000017500000000040011733011756016605 0ustar sylvestresylvestre Vadim Kurland Main author: GUI, iptables compiler Vadim Zaliva libfwbuilder API design; XML DTD design; XML data storage implementation; implementation of printing fwbuilder-5.1.0.3599/doc/fwbuilder21.10000644000175000017500000000321111733011756017750 0ustar sylvestresylvestre.de Sp .if n .sp .if t .sp 0.4 .. .TH fwbuilder 1 "" FWB "Firewall Builder" .SH NAME fwbuilder \- Multiplatform firewall configuration tool .SH SYNOPSIS .B /usr/bin/fwbuilder [ .B -f file.xml ] .SH "DESCRIPTION" .B fwbuilder is the Graphic User Interface (GUI) component of Firewall Builder. Firewall Builder consists of a GUI and set of policy compilers for various firewall platforms. It helps users maintain a database of objects and allows policy editing using simple drag-and-drop operations. GUI generates firewall description in the form of XML file, which compilers then interpret and generate platform-specific code. Several algorithms are provided for automated network objects discovery and bulk import of data. The GUI and policy compilers are completely independent, this provides for a consistent abstract model and the same GUI for different firewall platforms. At the moment of this writing Firewall Builder supports firewalls based on iptables (available on Linux, kernel 2.4.x, see fwb_ipt(1)), ipfilter (available on a variety of platforms including *BSD, Solaris and others, see fwb_ipf(1)) and pf (available on OpenBSD 3.0, see fwb_pf(1)) .SH OPTIONS .IP "-f FILE" Specify the name of the file to be loaded when program starts. .SH FILES .IP $HOME/.qt/firewallbuilder2rc fwbuilder stores user preferences in this file .SH URL Firewall Builder home page is located at the following URL: .B http://www.fwbuilder.org/ .SH BUGS Please report bugs using bug tracking system on SourceForge: .BR http://sourceforge.net/tracker/?group_id=5314&atid=105314 .SH SEE ALSO .BR fwblookup(1), .BR fwb_ipt(1), .BR fwb_ipf(1), .BR fwb_pf(1) .P fwbuilder-5.1.0.3599/doc/README.ipfw0000644000175000017500000000506611733011756017376 0ustar sylvestresylvestrefwb_ipfw(1) Firewall Builder fwb_ipfw(1) NNAAMMEE fwb_ipfw - Policy compiler for ipfw SSYYNNOOPPSSIISS ffwwbb__iippffww [[--vvVVxx]] [[--dd wwddiirr]] --ff ddaattaa__ffiillee..xxmmll object_name DDEESSCCRRIIPPTTIIOONN ffwwbb__iippffww is a firewall policy compiler component of Fire­ wall Builder (see fwbuilder(1)). This compiler generates code for ipfw - a firewall and traffic shaper in FreeBSD (see ipfw(8)). Compiler reads objects definitions and firewall description from the data file specified with "-f" option and generates firewall configuration and acti­ vation script. The generated file has a name that starts with the name of the firewall object, with an extension ".fw". It is a shell script that flushes current policy, then loads new filter and nat rules. The data file and the name of the firewall objects must be specified on the command line. Other command line parame­ ters are optional. OOPPTTIIOONNSS -f FILE Specify the name of the data file to be processed. -d wdir Specify working directory. Compiler creates fire­ wall activation script in this directory. If this parameter is missing, then all files will be placed in the current working directory. -v Be verbose: compiler prints diagnostic messages when it works. -V Print version number and quit. -x Generate debugging information while working. This option is intended for debugging only and may pro­ duce lots of cryptic messages. NNOOTTEESS Support for ipfw was added in version 1.0.10 of Firewall Builder UURRLL Firewall Builder home page is located at the following URL: hhttttpp::////wwwwww..ffwwbbuuiillddeerr..oorrgg// BBUUGGSS Please report bugs using bug tracking system on Source­ Forge: hhttttpp::////ssoouurrcceeffoorrggee..nneett//ttrraacckkeerr//??ggrroouupp__iidd==55331144&&aattiidd==110055331144 SSEEEE AALLSSOO ffwwbbuuiillddeerr((11)),, ffwwbb__iipptt((11)),, ffwwbb__ppff((11)) ffwwbb__iippff((11)) FWB fwb_ipfw(1) fwbuilder-5.1.0.3599/doc/PatchAcceptancePolicy.txt0000644000175000017500000000315311733011756022474 0ustar sylvestresylvestre$Id: PatchAcceptancePolicy.txt 152 2004-03-27 17:11:54Z vkurland $ Firewall Buider Project welcomes user contributions. Because we would like not to be limited in future licensing options of the code, authors of all submitted patches must agree that their contribution is donated to our project under terms of following license (this is MIT license): ------------------------------------------------------------------------- Copyright (c) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------- When submitting the patch please state that you agree with this license. fwbuilder-5.1.0.3599/configure.in0000644000175000017500000004321411733011756017313 0ustar sylvestresylvestrednl $Id: configure.in,v 1.70 2007/06/07 02:33:53 vkurland Exp $ AC_INIT AC_CONFIG_SRCDIR([src/gui/main.cpp]) AC_CANONICAL_TARGET AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(src/libfwbuilder/src/fwbuilder/libfwbuilder-config.h) PACKAGE=fwbuilder AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [package]) AC_SUBST(PACKAGE) LT_INIT AC_CONFIG_MACRO_DIR([m4]) dnl dnl all version numbers are defined in the file VERSION dnl . ./VERSION RELEASE_NUM=$BUILD_NUM GENERATION_SHORT=$(echo $GENERATION | sed 's/\.//') AC_DEFINE_UNQUOTED(BUILD_NUM, "$BUILD_NUM") AC_SUBST(BUILD_NUM) AC_SUBST(RELEASE_NUM) AC_SUBST(FWB_MAJOR_VERSION) AC_SUBST(FWB_MINOR_VERSION) AC_SUBST(FWB_MICRO_VERSION) AC_SUBST(FWB_VERSION) AC_SUBST(GENERATION) AC_SUBST(GENERATION_SHORT) # libfwbuilder versions dnl AC_SUBST(LIBFWBUILDER_VERSION) AC_SUBST(FWBUILDER_XML_VERSION) AC_DEFINE_UNQUOTED(FWBUILDER_XML_VERSION, "$FWBUILDER_XML_VERSION") echo "Creating VERSION.h file..." cat < VERSION.h #define VERSION "$VERSION" #define GENERATION "$GENERATION" EOF dnl try to find QT dnl AC_ARG_WITH(qtdir,[ --with-qtdir=DIR Specify directory path for QT ]) if test -n "$with_qtdir"; then AC_MSG_CHECKING(Using QT in ) QTDIR="$with_qtdir"; export QTDIR AC_MSG_RESULT($QTDIR) fi # TODO: do we need to add $QTDIR/bin to PATH to find qmake? EXTENDED_PATH="/usr/local/bin:$PATH" AC_ARG_WITH(qmake, [ --with-qmake=qmake Specify the qmake to be used (debian qmake-qt4) ]) if test -n "$with_qmake"; then AC_PATH_PROG(QMAKE, $with_qmake, ,[$EXTENDED_PATH]) if test -z "$QMAKE"; then AC_MSG_ERROR("Could not find qmake") fi else AC_PATH_PROG(QMAKE, qmake, ,[$EXTENDED_PATH]) if test -z "$QMAKE"; then AC_PATH_PROG(QMAKE, qmake-qt4, ,[$EXTENDED_PATH]) if test -z "$QMAKE"; then AC_MSG_ERROR("Could not find qmake") fi fi fi AC_MSG_CHECKING(checking version of QT this qmake is part of) qmake_version=`$QMAKE -v 2>&1 | awk '/Using Qt version/ { print $4;}'` case $qmake_version in 4.*) AC_MSG_RESULT( $qmake_version ) ;; *) AC_MSG_ERROR( "$qmake_version -- v4.x is required") ;; esac AC_ARG_WITH(templatedir, [ --with-templatedir=DIR Specify directory path for fwbuilder template files ]) AC_ARG_WITH(docdir, [ --with-docdir=DIR Specify directory path for fwbuilder documentation files ]) AC_ARG_WITH(datadir, [ --with-datadir=DIR Specify directory path for fwbuilder data files ]) AC_C_BIGENDIAN(AC_DEFINE(WORDS_BIGENDIAN), AC_DEFINE(WORDS_LITTLEENDIAN), AC_MSG_ERROR(Failed to determine endianness!!)) LIBFWBUILDER_LIBDIR='-L${libdir}' dnl dnl Determine init dir and add definition to config.h. Program dnl determines prefix name of the directory it was started from dnl and prepends it to the RES_DIR dnl PREFIX=$ac_default_prefix if test "x$prefix" != "xNONE"; then PREFIX=$prefix fi AC_DEFINE_UNQUOTED(PREFIX, "${PREFIX}", [prefix]) AC_SUBST(PREFIX) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [version]) AC_SUBST(VERSION) AC_PROG_INSTALL AC_ISC_POSIX AC_PROG_CC dnl AM_PROG_CC_STDC AC_HEADER_STDC AC_PROG_CPP AC_PROG_CXX AC_PROG_CXXCPP dnl need this for intl to compile on FreeBSD and may be other platforms AC_CHECK_FUNCS(strchr memcpy) dnl AM_INIT_AUTOMAKE($PACKAGE, $VERSION) dnl AC_CANONICAL_HOST AC_PROG_MAKE_SET dnl Check for GNU make dnl AC_MSG_CHECKING(whether make is GNU Make) if ${MAKE-make} -q --version 2>/dev/null | grep '^GNU Make ' >/dev/null ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) if test "$host_vendor" = "sun" ; then AC_MSG_ERROR("SUN make does not work for building Firewall Builder. Please install GNU make") fi fi dnl some platform-dependent flags dnl dnl e.g. we need to set -I/sw/include before check for GETTEXT dnl GUILINKFLAGS= case "$build_os" in *solaris*) GUILINKFLAGS="-export-dynamic" ;; esac AC_SUBST(GUILINKFLAGS) dnl dnl forkpty is in libutil on Linux and BSD, while on Mac it is in libc dnl AC_CHECK_HEADERS( [pty.h libutil.h util.h],[],[],[#include ]) AC_CHECK_LIB(c,forkpty,[ AC_DEFINE_UNQUOTED(HAVE_FORKPTY, 1, [forkpty]) ],[ AC_CHECK_LIB(util,forkpty,[ AC_DEFINE_UNQUOTED(HAVE_FORKPTY, 1, [forkpty]) LIBS="-lutil $LIBS" ],[ AC_MSG_RESULT(["forkpty not found, will use emulation"]) ],[]) ],[]) AC_CHECK_LIB(c,cfmakeraw,[ AC_DEFINE_UNQUOTED(HAVE_CFMAKERAW, 1, [cfmakeraw]) ]) dnl standard LIBTOOL fragment dnl dnl commented out 12/20 - we now use qmake and do not need libtool dnl dnl AC_LIBTOOL_DLOPEN dnl AC_PROG_LIBTOOL dnl AC_SUBST(LIBTOOL_DEPS) dnl AM_PROG_LIBTOOL dnl AC_PROG_RANLIB AC_CHECK_HEADERS([getopt.h]) AC_CHECK_HEADERS([signal.h]) AC_CHECK_HEADERS([endian.h]) AC_CHECK_FUNCS(strtok_r) AC_CHECK_FUNCS(stat _stat signal) AC_STRUCT_TM AC_STRUCT_TIMEZONE AC_SUBST(LIBS) AC_LANG([C++]) AM_PATH_CPPUNIT(1.12.0, [HAVE_CPPUNIT="1"]) AC_DEFINE_UNQUOTED(HAVE_CPPUNIT, $HAVE_CPPUNIT) AC_SUBST(HAVE_CPPUNIT) AC_SUBST(CPPUNIT_CFLAGS) AC_SUBST(CPPUNIT_LIBS) dnl A check for antlr-runtime library used to be here but has been dnl removed. We should always use antlr runtime code incuded with dnl fwbuilder code tree because of the fixes I've done in dnl CurcularQueue.hpp module for 64 bit systems. This problem seems to dnl have been fixed in antlr v3 but until we convert all grammars to dnl the new antlr, we have to use provided antlr 2.7.7 with these dnl fixes. This means we can't use antlr runtime that comes with the dnl OS even if it is installed. ANTLR_INCLUDEPATH="`pwd`/src/" ANTLR_LIBS="`pwd`/src/antlr/libantlr.a" AC_SUBST(ANTLR_LIBS) AC_SUBST(ANTLR_INCLUDEPATH) dnl check for pthreads dnl dnl Somehow, standard macro tries -lpthreads, while pthread library really dnl is "libpthread" on Linux. Thus only test using -pthread suceeds, but dnl PTHREAD_LIBS macro ends up empty. ACX_PTHREAD([ test -z "$PTHREAD_LIBS" && test "$PTHREAD_CFLAGS" = "-pthread" && PTHREAD_LIBS="-pthread" echo "Found pthread library:" echo "PTHREAD_CFLAGS="$PTHREAD_CFLAGS echo "PTHREAD_LIBS="$PTHREAD_LIBS ] , [ AC_MSG_ERROR([POSIX threads library not present or not configured]) ]) dnl check for XML library AC_PATH_PROG(XML2_CONFIG, xml2-config, ,[$EXTENDED_PATH]) if test x$XML2_CONFIG = x ; then AC_MSG_ERROR([libxml2 not present or not configured]) else XML_CFLAGS="`$XML2_CONFIG --cflags`" XML_LIBS="`$XML2_CONFIG --libs`" fi XML_CFLAGS=`echo $XML_CFLAGS | sed 's/-I\/usr\/include //'` AC_SUBST(XML_CFLAGS) AC_SUBST(XML_LIBS) SAVE_LIBS=${LIBS} LIBS="$XML_LIBS $LIBS" AC_CHECK_FUNCS(xmlSaveFormatFileEnc) LIBS=${SAVE_LIBS} dnl check for XSLT library AC_PATH_PROG(XSLT_CONFIG, xslt-config, ,[$EXTENDED_PATH]) if test x$XSLT_CONFIG = x ; then AC_MSG_ERROR([libxslt not present or not configured]) else XSLT_CFLAGS="`$XSLT_CONFIG --cflags`" XSLT_LIBS="`$XSLT_CONFIG --libs`" fi XSLT_CFLAGS=`echo $XSLT_CFLAGS | sed 's/-I\/usr\/include //'` dnl dnl purely aestetical: xslt-config often reports the same flags as dnl xml2-config dnl ac_xslt_var="" for w in ${XSLT_CFLAGS}; do case " ${XML_CFLAGS} " in *\ $w\ *) ;; *) ac_xslt_var="$ac_xslt_var $w" ;; esac done XSLT_CFLAGS=$ac_xslt_var ac_xslt_var="" for w in ${XSLT_LIBS}; do case " ${XML_LIBS} " in *\ $w\ *) ;; *) ac_xslt_var="$ac_xslt_var $w" ;; esac done XSLT_LIBS=$ac_xslt_var AC_SUBST(XSLT_CFLAGS) AC_SUBST(XSLT_LIBS) dnl libXslt header libxslt/xsltconfig.h only present in newew version of libxslt dnl for instance it is not part of 1.0.1 but present in 1.0.7. AC_CHECK_HEADERS(libxslt/xsltconfig.h) dnl Check for bind specific headers and libraries dnl if they are present, use them, rather than ones dnl coming with libc. AC_CHECK_HEADER(bind/resolv.h, [ CPPFLAGS="$CPPFLAGS -I/usr/include/bind" HAVE_RESOLV_H=yes ] , [ AC_CHECK_HEADER(/usr/local/bind/include/resolv.h, [ CPPFLAGS="$CPPFLAGS -I/usr/local/bind/include/" HAVE_RESOLV_H=yes ], [ AC_CHECK_HEADERS([resolv.h], [ HAVE_RESOLV_H=yes ], [], [ #include #include ] ) ] ) ], [ #include ] ) LIB_RESOLV="" HAVE_RES_NQUERY="" AC_SUBST(LIB_RESOLV) dnl dnl prepare equivalents of *_CFLAGS variables for qmake dnl qmake requires these to be without "-I" dnl XML_CFLAGS_Q=`echo ${XML_CFLAGS} | sed 's/-I//g'` XSLT_CFLAGS_Q=`echo ${XSLT_CFLAGS} | sed 's/-I//g'` PTHREAD_CFLAGS_Q=`echo ${PTHREAD_CFLAGS} | sed 's/-I//g'` LIBS_Q=`echo ${LIBS} | sed 's/-I//g'` AC_SUBST(XML_CFLAGS_Q) AC_SUBST(XSLT_CFLAGS_Q) AC_SUBST(PTHREAD_CFLAGS_Q) AC_SUBST(LIBS_Q) dnl dnl We also support "--with-ucdsnmp=no" and "--without-ucdsnmp" dnl By default we assume user wants snmp support, provided script dnl can find the library dnl dnl Just in case we support both --with-ucdsnmp and --with-ucd-snmp dnl --vk dnl check_for_ucdsnmp=yes if test x$with_ucdsnmp = xno ; then check_for_ucdsnmp=no fi if test x$with_ucd_snmp = xno ; then check_for_ucdsnmp=no fi if test $check_for_ucdsnmp = yes ; then dnl dnl net-snmp library includes script net-snmp-config which I use to determine cflags dnl and libs. Unfortunately even if this script is there and is used flags, dnl the program may still not link with the library. Currently having this problem on dnl FreeBSD 4.7 - after upgrade of openssl, code using net-snmp stopped linking. That dnl is why I still try to do linking test even if script is present. dnl dnl Testing for presence of includes and doing linking test assures that -devel dnl package is indeed installed (primitive test program could link with libsnmp.so dnl even if -devel package is not installed and headers are not there). dnl AC_PATH_PROG(NET_SNMP_CONFIG, net-snmp-config, ,[$EXTENDED_PATH]) if test x$NET_SNMP_CONFIG != x ; then ac_LIBSNMP_LIBS="`$NET_SNMP_CONFIG --libs`" ac_LIBSNMP_CFLAGS="`$NET_SNMP_CONFIG --cflags`" AC_CHECK_LIB(netsnmp, init_snmp, [ HAVE_LIBSNMP="1" AC_DEFINE(HAVE_LIBSNMP) NET_SNMP="1" AC_DEFINE(NET_SNMP) LIBSNMP_LIBS=$ac_LIBSNMP_LIBS LIBSNMP_CFLAGS=$ac_LIBSNMP_CFLAGS AC_CHECK_LIB(netsnmp, snprint_objid, [ AC_DEFINE(HAVE_SNPRINT_OBJID) ], ,$ac_LIBSNMP_LIBS) ], ,$ac_LIBSNMP_LIBS) else AC_CHECK_HEADERS([ucd-snmp/asn1.h], [ AC_CHECK_HEADER(ucd-snmp/snmp.h, [ AC_CHECK_LIBSNMP( snmp ) if test "Z$HAVE_LIBSNMP" != "Z"; then UCD_SNMP="1" AC_DEFINE(UCD_SNMP) save_LIBS=$LIBS LIBS="$LIBSNMP_LIBS $LIBS" AC_CHECK_LIB(snmp, snprint_objid, [ AC_DEFINE(HAVE_SNPRINT_OBJID) ]) LIBS=$save_LIBS fi ], ,[ #include #include ]) ]) fi LIBS="${LIBSNMP_LIBS} ${LIBS}" fi AC_SUBST(LIBSNMP_LIBS) AC_CHECK_LIB(c, inet_net_ntop, [ AC_DEFINE_UNQUOTED(HAVE_INET_NET_NTOP, 1, [inet_net_ntop]) ],[ AC_CHECK_LIB(bind, inet_net_ntop, [ AC_DEFINE_UNQUOTED(HAVE_INET_NET_NTOP, 1, [inet_net_ntop]) LIBS="-lbind $LIBS" ]) ],[]) AC_CHECK_LIB(z, gzopen, [ LIBS="-lz ${LIBS}"], [ AC_MSG_ERROR([libz library not found]) ]) dnl dnl Determine init dir and add definition to config.h dnl PREFIX=$ac_default_prefix if test "x$prefix" != "xNONE"; then PREFIX=$prefix fi dnl ******************************************************************** if test "x$with_docdir" != "x"; then DOCDIR="${with_docdir}" else DOCDIR="${PREFIX}/share/doc/fwbuilder-${VERSION}" fi DOCDIRPATH=`dirname ${DOCDIR}` if test "x$with_datadir" != "x"; then DATADIR="${with_datadir}" else DATADIR="${PREFIX}/share/" fi ICONSDIR="" dnl do not insert spaces in these macros, even outside of [] AC_PATH_PROG(RCS_FILE_NAME,[rcs],[rcs],[$EXTENDED_PATH]) AC_PATH_PROG(RCSDIFF_FILE_NAME,[rcsdiff],[rcsdiff],[$EXTENDED_PATH]) AC_PATH_PROG(RLOG_FILE_NAME,[rlog],[rlog],[$EXTENDED_PATH]) AC_PATH_PROG(CI_FILE_NAME,[ci],[ci],[$EXTENDED_PATH]) AC_PATH_PROG(CO_FILE_NAME,[co],[co],[$EXTENDED_PATH]) AC_MSG_CHECKING(what OS this is) case ${host} in *-*-cygwin*) OS=cygwin OS_CYGWIN=1 AC_MSG_RESULT(Win32 cygwin) DEFAULT_RES_DIR="resources" ;; *-*-mingw32*) OS=mingw32 OS_MINGW=1 AC_MSG_RESULT(Win32 mingw) DEFAULT_RES_DIR="resources" RCS_FILE_NAME="rcs.exe" RCSDIFF_FILE_NAME="rcsdiff.exe" RLOG_FILE_NAME="rlog.exe" CI_FILE_NAME="ci.exe" CO_FILE_NAME="co.exe" ;; *-*-darwin*) OS=MacOSX OS_MACOSX=1 MANDIR="${PREFIX}/share/man/" AC_MSG_RESULT(MacOSX) DEFAULT_RES_DIR="../Resources" ;; *-*-solaris*) OS=Solaris OS_SOLARIS=1 MANDIR="${PREFIX}/share/man/" AC_MSG_RESULT(Solaris) DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder-${VERSION}" ;; *-*-freebsd*) OS=FreeBSD OS_FREEBSD=1 MANDIR="${PREFIX}/man/" AC_MSG_RESULT(FreeBSD) DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder-${VERSION}" ;; *-*-openbsd*) OS=OpenBSD OS_OPENBSD=1 MANDIR="${PREFIX}/man/" AC_MSG_RESULT(OpenBSD) DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder-${VERSION}" ;; *-*-kfreebsd*) OS=FreeBSD OS_FREEBSD=1 if test -f /etc/debian_version ; then DISTRO=Debian else DISTRO="Unknown" fi MANDIR="${PREFIX}/share/man/" AC_MSG_RESULT($DISTRO GNU/kFreeBSD) DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder-${VERSION}" ;; *-*-linux*) DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder-${VERSION}" OS=Linux OS_LINUX=1 if test -f /etc/debian_version ; then DISTRO=Debian elif test -f /etc/mandrake-release ; then DISTRO=Mandrake elif test -f /etc/slackware-version ; then DISTRO=Slackware elif test -f /etc/SuSE-release ; then DISTRO=SuSE elif test -f /etc/redhat-release ; then # # Mandrake has symlink /etc/redhat-release -> /etc/manrake-release , # so this check must be the last # DISTRO=RedHat else DISTRO="Unknown" fi MANDIR="${PREFIX}/share/man/" ICONSDIR="${DATADIR}/icons/hicolor/" AC_MSG_RESULT($DISTRO Linux) ;; *) OS=Unknown OS_UNKNOWN=1 DISTRO=Unknown MANDIR="${PREFIX}/share/man/" AC_MSG_RESULT(Unknown) DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder-${VERSION}" ;; esac if test "x$with_templatedir" != "x"; then RES_DIR="${with_templatedir}" else RES_DIR="$DEFAULT_RES_DIR" fi AC_DEFINE_UNQUOTED(RES_DIR, "$RES_DIR", [res_dir]) AC_SUBST(RES_DIR) AC_DEFINE_UNQUOTED(RCS_FILE_NAME, ["$RCS_FILE_NAME"], [rcs_file_name]) AC_DEFINE_UNQUOTED(RCSDIFF_FILE_NAME, ["$RCSDIFF_FILE_NAME"], [rcsdiff_file_name]) AC_DEFINE_UNQUOTED(RLOG_FILE_NAME, ["$RLOG_FILE_NAME"], [rlog_file_name]) AC_DEFINE_UNQUOTED(CI_FILE_NAME, ["$CI_FILE_NAME"], [ci_file_name]) AC_DEFINE_UNQUOTED(CO_FILE_NAME, ["$CO_FILE_NAME"], [co_file_name]) dnl prefix has bogus value while building RPM. Since program dnl should incrorporate full path to the templates directory into dnl the code via config.h file, we need to keep track of dnl this directory twice: TEMPLATE_DIR is what goes to config.h, while dnl "install" Makefile targets will use $(prefix) to build install dnl path TEMPLATE_DIR=$RES_DIR AC_DEFINE_UNQUOTED(LIBFWBUILDER_TEMPLATE_DIR, "${TEMPLATE_DIR}") AC_SUBST(TEMPLATE_DIR) AC_SUBST(OS) AC_DEFINE_UNQUOTED(OS, "${OS}", [os]) test -n "$OS_CYGWIN" && AC_DEFINE_UNQUOTED(OS_CYGWIN, "${OS_CYGWIN}", [cygwin]) test -n "$OS_MINGW" && AC_DEFINE_UNQUOTED(OS_MINGW, "${OS_MINGW}", [mingw]) test -n "$OS_MACOSX" && AC_DEFINE_UNQUOTED(OS_MACOSX, "${OS_MACOSX}", [macosx]) test -n "$OS_SOLARIS" && AC_DEFINE_UNQUOTED(OS_SOLARIS,"${OS_SOLARIS}",[solaris]) test -n "$OS_FREEBSD" && AC_DEFINE_UNQUOTED(OS_FREEBSD,"${OS_FREEBSD}",[freebsd]) test -n "$OS_OPENBSD" && AC_DEFINE_UNQUOTED(OS_OPENBSD,"${OS_OPENBSD}",[openbsd]) test -n "$OS_LINUX" && AC_DEFINE_UNQUOTED(OS_LINUX, "${OS_LINUX}", [linux]) test -n "$OS_SECUWALL" && AC_DEFINE_UNQUOTED(OS_SECUWALL, "${OS_SECUWALL}", [secuwall]) test -n "$OS_UNKNOWN" && AC_DEFINE_UNQUOTED(OS_UNKNOWN,"${OS_UNKNOWN}",[unknown]) AC_SUBST(DISTRO) AC_DEFINE_UNQUOTED(DISTRO, "${DISTRO}", [distro]) AC_SUBST(DOCDIRPATH) AC_DEFINE_UNQUOTED(DOCDIRPATH, "${DOCDIRPATH}", [docdirpath]) AC_SUBST(DOCDIR) AC_DEFINE_UNQUOTED(DOCDIR, "${DOCDIR}", [docdir]) AC_SUBST(DATADIR) AC_SUBST(MANDIR) AC_SUBST(ICONSDIR) AC_ARG_WITH(ccache,[ --with-ccache=yes Use ccache to speed up repeated compilation]) if test -n "$with_ccache"; then if test "x$with_ccache" != "xno"; then AC_PATH_PROG(CCACHE, ccache, , ) AC_SUBST(CCACHE) if test -n "$CCACHE" then ccache -s fi else CCACHE="" AC_SUBST(CCACHE) fi else AC_PATH_PROG(CCACHE, ccache, , ) AC_SUBST(CCACHE) if test -n "$CCACHE" then ccache -s fi fi AC_ARG_WITH(distcc,[ --with-distcc=N Use distcc with N parallel make count]) if test -n "$with_distcc"; then if test "x$with_distcc" != "xno"; then AC_PATH_PROG(HAVE_DISTCC, distcc, , ) if test -n "$HAVE_DISTCC"; then DISTCC=$HAVE_DISTCC AC_SUBST(DISTCC) PARALLEL_MAKE_COUNT=$with_distcc AC_SUBST(PARALLEL_MAKE_COUNT) fi fi else AC_PATH_PROG(HAVE_DISTCC, distcc, , ) if test -n "$HAVE_DISTCC"; then M_J=$(distcc -j 2>/dev/null) if test -n "$M_J"; then DISTCC=$HAVE_DISTCC AC_SUBST(DISTCC) PARALLEL_MAKE_COUNT=$M_J AC_SUBST(PARALLEL_MAKE_COUNT) fi fi fi AC_CONFIG_FILES([ qmake.inc src/res/objects_init.xml src/res/templates.xml src/libfwbuilder/qmake.inc src/libfwbuilder/etc/fwbuilder.dtd packaging/fwbuilder.control packaging/fwbuilder.spec packaging/fwbuilder-static-qt.spec packaging/fwbuilder.nsi]) AC_OUTPUT # QMAKE=$QMAKE CCACHE=$CCACHE QTDIR=$QTDIR ./runqmake.sh QMAKE=$QMAKE QTDIR=$QTDIR ./runqmake.sh fwbuilder-5.1.0.3599/src/0000755000175000017500000000000011733011756015565 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/src.pro0000644000175000017500000000057511733011756017105 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # # include(../qmake.inc) TEMPLATE = subdirs CONFIG += ordered TARGET = src SUBDIRS = libfwbuilder \ res \ antlr \ parsers \ import \ common \ compiler_lib \ iptlib \ ipt \ pflib \ pf \ ipf \ ipfw \ cisco_lib \ iosacl \ pix \ procurve_acl \ libgui \ fwbedit \ gui \ fwbuilder-5.1.0.3599/src/iosacl/0000755000175000017500000000000011733011756017037 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/iosacl/iosacl.cpp0000644000175000017500000001110511733011756021013 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #ifdef _WIN32 # include #else # include #endif #include #include #include #include #include #include #include #include "CompilerDriver_iosacl.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Constants.h" #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string &msg) const { msg.size(); // to make compiler happy about unused parameter cout << "Data file has been created in the old version of Firewall Builder.\nLoad it in the GUI to convert it to the new version." << endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for Cisco IOS ACL" << endl; cout << "Copyright 2007-2009 NetCitadel, LLC" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-tvV] [-f filename.xml] [-d destdir] [-o output.fw] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_iosacl *driver = new CompilerDriver_iosacl(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; delete driver; delete objdb; return ret; } catch(libfwbuilder::FWException &ex) { cerr << ex.toString() << endl; return 1; } catch (std::string s) { cerr << s << endl; return 1; } catch (std::exception ex) { cerr << "exception: " << ex.what() << endl; return 1; } catch (...) { cerr << "Unsupported exception"; return 1; } return 0; } fwbuilder-5.1.0.3599/src/iosacl/iosacl.pro0000644000175000017500000000152111733011756021032 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # # # PACKAGE = fwbuilder-iosacl-$$FWB_VERSION # # QMAKE_CXXFLAGS_DEBUG += -DPACKAGE="\"$$PACKAGE\"" # QMAKE_CXXFLAGS_RELEASE += -DPACKAGE="\"$$PACKAGE\"" SOURCES = iosacl.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32:CONFIG += console INCLUDEPATH += ../cisco_lib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../cisco_lib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../cisco_lib/$$BINARY_SUBDIR/libfwbcisco.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_iosacl fwbuilder-5.1.0.3599/src/import/0000755000175000017500000000000011733011756017077 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/import/IPTImporter.cpp0000644000175000017500000016221011733011756021763 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "IPTImporter.h" #include "getProtoByName.h" #include "getServByName.h" #include #include #include #include #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include #include extern int fwbdebug; using namespace std; using namespace libfwbuilder; // TODO: this should move to some common library, together with // getVersionsForPlatform() it uses. Currently these functions are // defined in libgui/platforms.cpp extern QString findBestVersionMatch(const QString &platform, const QString &discovered_version); IPTImporter::IPTImporter(FWObject *lib, std::istringstream &input, Logger *log, const std::string &fwname) : Importer(lib, "iptables", input, log, fwname) { service_group_name_seed = 0; aux_branch_number = 0; current_table = ""; current_chain = ""; current_state = ""; current_ruleset = NULL; current_rule = NULL; last_mark_rule = NULL; clear(); // mapping between REJECT target argument and our internal name for it. // See also comment in IPTImporter::pushPolicyRule() reject_action_arg_mapping["icmp-net-unreachable"] = "ICMP net unreachable"; reject_action_arg_mapping["net-unreach"] = "ICMP net unreachable"; reject_action_arg_mapping["icmp-host-unreachable"] = "ICMP host unreachable"; reject_action_arg_mapping["host-unreach"] = "ICMP host unreachable"; reject_action_arg_mapping["icmp-proto-unreachable"] = "ICMP protocol unreachable"; reject_action_arg_mapping["proto-unreach"] = "ICMP protocol unreachable"; reject_action_arg_mapping["icmp-port-unreachable"] = "ICMP port unreachable"; reject_action_arg_mapping["port-unreach"] = "ICMP port unreachable"; reject_action_arg_mapping["icmp-net-prohibited"] = "ICMP net prohibited"; reject_action_arg_mapping["net-prohib"] = "ICMP net prohibited"; reject_action_arg_mapping["icmp-host-prohibited"] = "ICMP host prohibited"; reject_action_arg_mapping["host-prohib"] = "ICMP host prohibited"; reject_action_arg_mapping["icmp-admin-prohibited"] = "ICMP admin prohibited"; reject_action_arg_mapping["admin-prohib"] = "ICMP admin prohibited"; } IPTImporter::~IPTImporter() { clear(); } void IPTImporter::clear() { Importer::clear(); if (!src_port_list.empty()) src_port_list.clear(); if (!dst_port_list.empty()) dst_port_list.clear(); if (!both_port_list.empty()) both_port_list.clear(); current_state = ""; i_intf = ""; o_intf = ""; target = ""; tmp_port_range_start = ""; tmp_port_range_end = ""; src_neg = dst_neg = srv_neg = intf_neg = tmp_neg = false; match_mark = ""; neg_match_mark = false; recent_match = ""; limit_val = ""; limit_suffix = ""; limit_burst = ""; length_spec = ""; pkt_type_spec = ""; if (!action_params.empty()) action_params.clear(); nat_addr1 = ""; nat_addr2 = ""; nat_nm = ""; nat_port_range_start = ""; nat_port_range_end = ""; using_iprange_src = false; iprange_src_from = ""; iprange_src_to = ""; using_iprange_dst = false; iprange_dst_from = ""; iprange_dst_to = ""; } void IPTImporter::registerTable(const string &table_name) { current_table = table_name; if ( ! isSupportedTable(table_name)) { QString err = QObject::tr( "Unrecognized netfilter table \"%1\". " "Only tables \"filter\", \"mangle\" and \"nat\" are supported.") .arg(QString::fromUtf8(table_name.c_str())); reportError(err); } } bool IPTImporter::isSupportedTable(const string &table_name) { return (table_name == "nat" || table_name == "filter" || table_name == "mangle"); } string IPTImporter::getBranchName(const std::string &suffix) { ostringstream str; str << current_chain << suffix << aux_branch_number; aux_branch_number++; return str.str(); } void IPTImporter::startSrcMultiPort() { src_port_list.clear(); } void IPTImporter::pushTmpPortSpecToSrcPortList() { src_port_list.push_back( str_tuple( tmp_port_range_start, tmp_port_range_end ) ); } void IPTImporter::startDstMultiPort() { dst_port_list.clear(); } void IPTImporter::pushTmpPortSpecToDstPortList() { dst_port_list.push_back( str_tuple( tmp_port_range_start, tmp_port_range_end ) ); } void IPTImporter::startBothMultiPort() { both_port_list.clear(); } void IPTImporter::pushTmpPortSpecToBothPortList() { both_port_list.push_back( str_tuple( tmp_port_range_start, tmp_port_range_end ) ); } FWObject* IPTImporter::createTCPUDPService(str_tuple &src_range, str_tuple &dst_range, const std::string &proto) { if (fwbdebug) { qDebug() << "Creating service " << proto.c_str(); qDebug() << "src range: " << src_range.first.c_str() << " - " << src_range.second.c_str(); qDebug() << "dst range: " << dst_range.first.c_str() << " - " << dst_range.second.c_str(); } ObjectSignature sig(error_tracker); sig.setSrcPortRange(src_range.first.c_str(), src_range.second.c_str(), proto.c_str()); sig.setDstPortRange(dst_range.first.c_str(), dst_range.second.c_str(), proto.c_str()); if (proto=="tcp") { sig.type_name = TCPService::TYPENAME; sig.established = established; sig.flags_mask = tcp_flags_mask; sig.flags_comp = tcp_flags_comp; } else { sig.type_name = UDPService::TYPENAME; } return commitObject( service_maker->createObject(sig)); } /* * TODO: fix this */ FWObject* IPTImporter::createTCPUDPService(const std::string &proto) { str_tuple empty_range("0","0"); // use src_port_list and dst_port_list // if this is multiport, should only be either src or dst port // if (src_port_list.size()>1 || dst_port_list.size()>1) { std::list olist; std::list list_names; std::list::iterator i; std::list *list_ptr; if (src_port_list.size()>1) list_ptr = &src_port_list; else list_ptr = &dst_port_list; std::string sig; if (src_port_list.size()>1) sig = proto + " src "; else sig = proto + " dst "; for (i = list_ptr->begin(); i != list_ptr->end(); ++i) { sig += (*i).first + ":" + (*i).second + "_"; } if (all_objects.count(sig)!=0) return all_objects[sig]; for (i = list_ptr->begin(); i != list_ptr->end(); ++i) { FWObject *o; o = createTCPUDPService( (list_ptr == &src_port_list) ? *i : empty_range, (list_ptr == &dst_port_list) ? *i : empty_range, proto); olist.push_back(o); list_names.push_back(o->getName()); } std::ostringstream s; s << service_group_name_seed; service_group_name_seed++; std::string name = proto + " group " + s.str(); if (fwbdebug) qDebug() << QString("Group of %1 services with name '%2', sig '%3'") .arg(proto.c_str()).arg(name.c_str()).arg(sig.c_str()); ObjectMaker maker(Library::cast(library), error_tracker); ServiceGroup *sg = ServiceGroup::cast( commitObject(maker.createObject(ServiceGroup::TYPENAME, name))); for (FWObject::iterator j=olist.begin(); j!=olist.end(); ++j) { sg->addRef(*j); } all_objects[sig] = sg; return sg; } else // single tcp/udp object { return createTCPUDPService( (src_port_list.size()>0) ? src_port_list.front() : empty_range, (dst_port_list.size()>0) ? dst_port_list.front() : empty_range, proto); } } FWObject* IPTImporter::createTCPService(const QString &) { return createTCPUDPService("tcp"); } FWObject* IPTImporter::createUDPService(const QString &) { return createTCPUDPService("udp"); } FWObject* IPTImporter::makeSrcObj() { if (using_iprange_src) { ObjectSignature sig(error_tracker); sig.type_name = AddressRange::TYPENAME; sig.setAddressRangeStart(iprange_src_from.c_str()); sig.setAddressRangeEnd(iprange_src_to.c_str()); return commitObject(address_maker->createObject(sig)); } else return Importer::makeSrcObj(); } FWObject* IPTImporter::makeDstObj() { if (using_iprange_dst) { ObjectSignature sig(error_tracker); sig.type_name = AddressRange::TYPENAME; sig.setAddressRangeStart(iprange_dst_from.c_str()); sig.setAddressRangeEnd(iprange_dst_to.c_str()); return commitObject(address_maker->createObject(sig)); } else return Importer::makeDstObj(); } void IPTImporter::addSrv() { // special case for the multiport module parameter "--ports". This // parameter matches source OR destination ports. Will created two // separate service objects in the same rule if (!both_port_list.empty()) { src_port_list.insert(src_port_list.begin(), both_port_list.begin(), both_port_list.end()); Importer::addSrv(); src_port_list.clear(); dst_port_list.insert(dst_port_list.begin(), both_port_list.begin(), both_port_list.end()); Importer::addSrv(); dst_port_list.clear(); } else Importer::addSrv(); } /* * Importer::addSrv() adds regular (IP/ICMP/UDP/TCP) service * object. If we have mark module match, implement it as * TagService object only if there is no IP/ICMP/UDP/TCP service * as well. Other modules, such as length, are added only if there * is nothing else. If we have more than one service to deal with, * mark rule as bad and issue warning. * * I check and issue warning after I try to add TagService because * I want to add it in case when there are no regular services * but there is "mark" and some other module in the original rule. * Priorities: 1) IP/ICMP/UDP/TCP service 2) TagService (module mark) * 3) any other module * */ void IPTImporter::processModuleMatches() { PolicyRule *rule = PolicyRule::cast(current_rule); RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); FWOptions *fwopt = getFirewallObject()->getOptionsObject(); assert(fwopt!=NULL); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); addAllModuleMatches(rule); // functions that addAllModuleMatches() calls actually clear // variables match_mark, length_spec etc. list module_match_options; module_match_options.push_back(match_mark); module_match_options.push_back(length_spec); module_match_options.push_back(recent_match); module_match_options.push_back(pkt_type_spec); int branch_depth = 0; for(list::iterator it=module_match_options.begin(); it!=module_match_options.end(); ++it) { if (!it->empty()) { if (branch_depth) { // at this time I create branches only one level deep QString err = QObject::tr( "Original rule combines match of tcp/udp/icmp " "protocols with two or more module matches, such as " "module 'mark', 'recent' or 'length'. Use additional " "branches to implement this complex match."); reportError(err); break; } ostringstream str; str << current_chain << "_" << rule->getPosition() << "_mod_match"; string branch_chain = str.str(); branch_depth++; PolicyRule *new_rule = createPolicyBranch(rule, branch_chain, true, true); addAllModuleMatches(new_rule); } } } void IPTImporter::addAllModuleMatches(PolicyRule *rule) { addLimitMatch(rule); addMarkMatch(rule); addLengthMatch(rule); addRecentMatch(rule); addPktTypeMatch(rule); } void IPTImporter::addMarkMatch(PolicyRule *rule) { RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); if (rule->getSrv()->isAny() && !match_mark.empty()) { ObjectSignature sig(error_tracker); sig.type_name = TagService::TYPENAME; sig.tag = match_mark.c_str(); srv->addRef( commitObject(service_maker->createObject(sig)) ); if (neg_match_mark) srv->setNeg(true); match_mark = ""; } } void IPTImporter::addLengthMatch(PolicyRule *rule) { RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); if (rule->getSrv()->isAny() && !length_spec.empty()) { // create custom service with module "length" ObjectSignature sig(error_tracker); sig.type_name = CustomService::TYPENAME; sig.platform = "iptables"; sig.code = QString("-m length --length %1").arg(length_spec.c_str()); sig.protocol_name = ""; srv->addRef(commitObject(service_maker->createObject(sig))); length_spec = ""; } } void IPTImporter::addPktTypeMatch(PolicyRule *rule) { RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); if (rule->getSrv()->isAny() && !pkt_type_spec.empty()) { // create custom service with module "pkttype" ObjectSignature sig(error_tracker); sig.type_name = CustomService::TYPENAME; sig.platform = "iptables"; sig.code = QString("-m pkttype --pkt-type %1").arg(pkt_type_spec.c_str()); sig.protocol_name = ""; srv->addRef(commitObject(service_maker->createObject(sig))); pkt_type_spec = ""; } } void IPTImporter::addLimitMatch(PolicyRule *rule) { FWOptions *ropt = rule->getOptionsObject(); assert(ropt!=NULL); if (target!="LOG" && !limit_val.empty()) { // TODO: this is where we should add support for hashlimit ropt->setStr("limit_value", limit_val); ropt->setStr("limit_suffix", std::string("/") + limit_suffix); if (!limit_burst.empty()) ropt->setStr("limit_burst", limit_burst); limit_val = ""; } } void IPTImporter::addRecentMatch(PolicyRule *rule) { RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); if (rule->getSrv()->isAny() && !recent_match.empty()) { // create custom service with module "recent" ObjectSignature sig(error_tracker); sig.type_name = CustomService::TYPENAME; sig.platform = "iptables"; sig.code = QString("-m recent %1").arg(recent_match.c_str()); sig.protocol_name = ""; srv->addRef(commitObject(service_maker->createObject(sig))); recent_match = ""; } } void IPTImporter::addStateMatch(libfwbuilder::PolicyRule *rule, const string &state) { RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); if (rule->getSrv()->isAny() && !state.empty()) { // create custom service with module "state" ObjectSignature sig(error_tracker); sig.type_name = CustomService::TYPENAME; sig.platform = "iptables"; sig.code = QString("-m state --state %1").arg(state.c_str()); sig.protocol_name = ""; srv->addRef(commitObject(service_maker->createObject(sig))); recent_match = ""; } } /** * Special method that takes a rule and converts it into a branching * rule, creates new rule set object, adds a rule to it and makes this * rule a copy of the rule passed as an argument. Returns pointer to * the new rule inside the branch rule set. Note that new rule inside * the branch rule set is a copy of the original rule, with its action * and other attributes. The original rule's action changes however * and becomes "Branch". */ PolicyRule* IPTImporter::createPolicyBranch( PolicyRule *rule, const std::string &branch_ruleset_name, bool clear_rule_elements, bool make_stateless) { UnidirectionalRuleSet *rs = branch_rulesets[branch_ruleset_name]; if (rs==NULL) rs = getUnidirRuleSet(branch_ruleset_name, Policy::TYPENAME); branch_rulesets[branch_ruleset_name] = rs; rs->ruleset->setName(branch_ruleset_name); FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); PolicyRule *new_rule = PolicyRule::cast(dbroot->create(PolicyRule::TYPENAME)); rs->ruleset->add(new_rule); new_rule->duplicate(rule); rule->setAction(PolicyRule::Branch); rule->setBranch(rs->ruleset); FWOptions *ropt = rule->getOptionsObject(); assert(ropt!=NULL); ropt->setBool("stateless", true); if (rule->getParent() != NULL) { ostringstream str1; str1 << "Called from ruleset " << rule->getParent()->getName() << ", rule " << rule->getPosition(); new_rule->setComment(str1.str()); } if (clear_rule_elements) { RuleElement* re; re = new_rule->getSrc(); re->reset(); re = new_rule->getDst(); re->reset(); re = new_rule->getSrv(); re->reset(); re = new_rule->getItf(); re->reset(); } if (make_stateless) { FWOptions *ropt = new_rule->getOptionsObject(); assert(ropt!=NULL); ropt->setBool("stateless", true); } addMessageToLog(QString("Created branch %1") .arg(QString::fromUtf8(branch_ruleset_name.c_str()))); return new_rule; } NATRule* IPTImporter::createNATBranch( NATRule *rule, const std::string &branch_ruleset_name, bool clear_rule_elements) { UnidirectionalRuleSet *rs = branch_rulesets[branch_ruleset_name]; if (rs==NULL) rs = getUnidirRuleSet(branch_ruleset_name, NAT::TYPENAME); branch_rulesets[branch_ruleset_name] = rs; rs->ruleset->setName(branch_ruleset_name); FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); NATRule *new_rule = NATRule::cast(dbroot->create(NATRule::TYPENAME)); rs->ruleset->add(new_rule); new_rule->duplicate(rule); rule->setRuleType(NATRule::NATBranch); rule->setBranch(rs->ruleset); if (rule->getParent() != NULL) { ostringstream str1; str1 << "Called from ruleset " << rule->getParent()->getName() << ", rule " << rule->getPosition(); new_rule->setComment(str1.str()); } if (clear_rule_elements) { RuleElement* re; re = new_rule->getOSrc(); re->reset(); re = new_rule->getODst(); re->reset(); re = new_rule->getOSrv(); re->reset(); re = new_rule->getTSrc(); re->reset(); re = new_rule->getTDst(); re->reset(); re = new_rule->getTSrv(); re->reset(); re = new_rule->getItfInb(); re->reset(); re = new_rule->getItfOutb(); re->reset(); } addMessageToLog( QString("Created branch %1") .arg(QString::fromUtf8(branch_ruleset_name.c_str()))); return new_rule; } void IPTImporter::pushRule() { // assert(current_ruleset!=NULL); if (current_rule==NULL) return; if (current_table=="nat") pushNATRule(); else pushPolicyRule(); } void IPTImporter::pushPolicyRule() { // populate all elements of the rule PolicyRule *rule = PolicyRule::cast(current_rule); rule->setLogging(false); FWOptions *fwopt = getFirewallObject()->getOptionsObject(); assert(fwopt!=NULL); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); bool skip_rule = false; PolicyRule::Action action = PolicyRule::Unknown; if (target=="ACCEPT") action = PolicyRule::Accept; if (target=="DROP") action = PolicyRule::Deny; if (target=="REJECT") { action = PolicyRule::Reject; if (action_params["reject_with"]=="tcp-reset") ropt->setStr("action_on_reject", "TCP RST"); else { /* * for historical reasons, the argument for action Reject * is stored in our XML as a human readable string such as * "ICMP admin prohibited" instead of some kind of a * computer readable code. Function getActionsOnReject() (see platforms.cpp) * returns a list of strings where every even string is one of * these codes and every odd string is translatable display name * (that by currently is the same string, except it can be translated). * Values in the map reject_action_arg_mapping must match internal * (untranslated) codes that we get from getActionsOnReject(), keys * in reject_action_arg_mapping must match iptables arguments for * the target REJECT */ QString iptables_reject_arg = action_params["reject_with"].c_str(); QString action_on_reject_code; if (reject_action_arg_mapping.count(iptables_reject_arg) > 0) action_on_reject_code = reject_action_arg_mapping[iptables_reject_arg]; else { action_on_reject_code = "ICMP admin prohibited"; QString err = QObject::tr( "Error: Line %1: Unknown parameter of target REJECT: %2.") .arg(getCurrentLineNumber()) .arg(iptables_reject_arg); reportError(err); // throw ImporterException(err); // ropt->setStr("color", getBadRuleColor()); // rule_comment += string(err.toUtf8().constData()); // *Importer::logger << err.toUtf8().constData(); } ropt->setStr("action_on_reject", action_on_reject_code.toStdString()); } } if (target=="QUEUE") action = PolicyRule::Pipe; if (target=="CLASSIFY") // #2367 { action = PolicyRule::Continue; rule->setClassification(true); ropt->setStr("classify_str", action_params["set_class"]); } if (target=="LOG") { action = PolicyRule::Continue; rule->setLogging(true); QString log_prefix = action_params["log_prefix"].c_str(); log_prefix.replace("\"", ""); ropt->setStr("log_prefix", log_prefix.toStdString()); ropt->setStr("log_tcp_seq", action_params["log_tcp_seq"]); ropt->setStr("log_tcp_options", action_params["log_tcp_options"]); ropt->setStr("log_ip_options", action_params["log_ip_options"]); string slevel = action_params["log_level"]; int llevel; std::istringstream str1(slevel); str1.exceptions(std::ios::failbit); try { str1 >> llevel; // log level defined as a number map levels; levels[0] = ""; levels[1] = "alert"; levels[2] = "crit"; levels[3] = "error"; levels[4] = "warning"; levels[5] = "notice"; levels[6] = "info"; levels[7] = "debug"; if (llevel <= 7) ropt->setStr("log_level", levels[llevel]); else { reportError(std::string("Unrecognized log level '") + slevel); } } catch (const std::exception &ex) { // not an integer ropt->setStr("log_level", slevel); } //ropt->setStr("log_level", action_params["log_level"]); if (!limit_val.empty()) { ropt->setStr("limit_value", limit_val); ropt->setStr("limit_suffix", std::string("/")+limit_suffix); if (!limit_burst.empty()) ropt->setStr("limit_burst", limit_burst); } } if (target=="ULOG") { action = PolicyRule::Continue; rule->setLogging(true); fwopt->setBool("use_ULOG", true); QString log_prefix = action_params["log_prefix"].c_str(); log_prefix.replace("\"", ""); ropt->setStr("log_prefix", log_prefix.toStdString()); } if (target=="MARK") { action = PolicyRule::Continue; rule->setTagging(true); last_mark_rule = rule; ObjectSignature sig(error_tracker); sig.type_name = TagService::TYPENAME; sig.tag = action_params["set_mark"].c_str(); FWObject *tag_service = commitObject(service_maker->createObject(sig)); rule->setTagObject(tag_service); } if (target=="CONNMARK") action = PolicyRule::Continue; if (target=="ROUTE") { action = PolicyRule::Continue; rule->setRouting(true); if (!action_params["route_iif"].empty()) newInterface(action_params["route_iif"]); if (!action_params["route_oif"].empty()) newInterface(action_params["route_oif"]); ropt->setStr("ipt_iif", action_params["route_iif"]); ropt->setStr("ipt_oif", action_params["route_oif"]); ropt->setStr("ipt_gw", action_params["route_gw"]); ropt->setBool("ipt_continue", !action_params["route_continue"].empty()); ropt->setBool("ipt_tee", !action_params["route_tee"].empty()); } if (target=="RETURN" || target.empty()) { action = PolicyRule::Continue; } if (target=="TCPMSS" && action_params["clamp-mss-to-pmtu"] == "--clamp-mss-to-pmtu") { fwopt->setBool("clamp_mss_to_mtu", true); skip_rule = true; addMessageToLog( QString("Warning: Using automatic rule controlled by option " "Clamp MSS to MTU")); } if (target=="TOS") { // special-case target TOS, create custom action // this is not very useful though because compiler can not properly // put such rule in POSTROUTING chain. action = PolicyRule::Custom; ropt->setStr("custom_str", "-j TOS --set-tos " + action_params["set_tos"]); } if (action==PolicyRule::Unknown) { if (fwbdebug) qDebug("Unknown target %s, creating branch", target.c_str()); // unknown target, consider it a branch // std::string branch_ruleset_name = target; action = PolicyRule::Branch; UnidirectionalRuleSet *rs = branch_rulesets[branch_ruleset_name]; if (rs==NULL) rs = getUnidirRuleSet(branch_ruleset_name, Policy::TYPENAME); branch_rulesets[branch_ruleset_name] = rs; rs->ruleset->setName(target); rule->setBranch(rs->ruleset); ropt->setBool("stateless", true); } rule->setAction(action); addSrc(); addDst(); addSrv(); RuleElementSrc *nsrc; RuleElementDst *ndst; rule->getSrc()->setNeg(src_neg); rule->getDst()->setNeg(dst_neg); rule->getSrv()->setNeg(srv_neg); rule->getItf()->setNeg(intf_neg); /* Recognize some typical rule patterns and set firewall and rule * options appropriately */ if (current_state == "NEW") { ropt->setBool("stateless", false); current_state = ""; } if (current_state == "RELATED,ESTABLISHED" || current_state == "ESTABLISHED,RELATED") { RuleElementSrv *srv = rule->getSrv(); std::string protocol = ""; FWObject *estab = NULL; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); FWObject *std_obj = dbroot->findInIndex(FWObjectDatabase::STANDARD_LIB_ID); estab = std_obj->findObjectByName(CustomService::TYPENAME, "ESTABLISHED"); if (estab == NULL) { ObjectSignature sig(error_tracker); sig.type_name = CustomService::TYPENAME; sig.platform = "iptables"; sig.code = QString("-m state --state RELATED,ESTABLISHED"); sig.protocol_name = ""; estab = service_maker->createObject(sig); } if (!rule->getSrv()->isAny()) { string branch_ruleset_name = getBranchName("_established_"); // two boolean args of createPolicyBranch() clear all rule elements // of the rule in the branch rule set and make it stateless PolicyRule *new_rule = createPolicyBranch(rule, branch_ruleset_name, true, true); new_rule->setDirection(PolicyRule::Both); RuleElement* re = new_rule->getSrv(); re->addRef(estab); } else { srv->clearChildren(); srv->addRef(estab); } addMessageToLog( QString( "Warning: Rule matches states 'RELATED,ESTABLISHED'. " "Consider using " "automatic rule controlled by the checkbox in the firewall " "settings dialog. Automatic rule matches in all standard chains " "which may be different from the original imported configuration. " "This requires manual checking." )); current_state = ""; } if (rule->getSrc()->isAny() && rule->getDst()->isAny() && rule->getSrv()->isAny() && current_state == "INVALID") { if (target=="DROP") fwopt->setBool("drop_invalid", true); if (target=="LOG") fwopt->setBool("log_invalid", true); skip_rule = true; addMessageToLog( QString("Warning: Using automatic rule controlled by option " "'Drop packet that do not match any known connection' " "to match state INVALID" )); current_state = ""; } // finally, process unrecognized combination of states if ( ! current_state.empty()) { RuleElementSrv *srv = rule->getSrv(); ObjectSignature sig(error_tracker); sig.type_name = CustomService::TYPENAME; sig.platform = "iptables"; sig.code = QString("-m state --state %1").arg(current_state.c_str()); sig.protocol_name = ""; FWObject *state_match_srv = commitObject(service_maker->createObject(sig)); if ( ! rule->getSrv()->isAny()) { string branch_ruleset_name = getBranchName("_state_match_"); // two boolean args of createPolicyBranch() clear all rule elements // of the rule in the branch rule set and make it stateless PolicyRule *new_rule = createPolicyBranch(rule, branch_ruleset_name, true, true); new_rule->setDirection(PolicyRule::Both); RuleElement* re = new_rule->getSrv(); re->addRef(state_match_srv); } else { srv->clearChildren(); srv->addRef(state_match_srv); } // no need to make rule stateless since compiler is smart enough to drop // --state NEW when service object adds its own state match // ropt->setBool("stateless", false); addMessageToLog( QString( "Warning: Rule matches combination of states '%1'. " "Iptables rules generated by fwbuilder can be stateless (match " "no state) or stateful (match state NEW). Fwbuilder also adds " "a rule at the top of the script to match states " "ESTABLISHED,RELATED. Combination of states '%2' does not fit " "these standard cases and to match it, the program created " "new Custom Service object. This may require manual checking." ) .arg(current_state.c_str()) .arg(current_state.c_str())); current_state = ""; } if (target=="CONNMARK" && last_mark_rule != NULL && !action_params["connmark_save_mark"].empty()) { FWOptions *lmr_ropt = last_mark_rule->getOptionsObject(); assert(lmr_ropt!=NULL); lmr_ropt->setBool("ipt_mark_connections", true); skip_rule = true; addMessageToLog( QString("Warning: Turned option on in previous rule " "with action Mark " "for '-j CONNMARK --save-mark' " )); } if (target=="CONNMARK" && !action_params["connmark_restore_mark"].empty()) { // this rule is added automatically in // MangleTableCompiler_ipt::flushAndSetDefaultPolicy() // if we have at least one rule with CONNMARK target in the policy skip_rule = true; addMessageToLog( QString("Warning: Skipping command with '-j CONNMARK --restore-mark' " "This rule is generated automatically." )); } if (!skip_rule) { /* we set "firewall_is_part_of_any_and_networks" to False */ rule_comment += "Chain " + current_chain + ". "; if (current_chain=="INPUT") { ndst = rule->getDst(); if (ndst->isAny()) ndst->addRef(getFirewallObject()); else rule_comment += "Does DST match one of the firewall's addresses?"; } if (current_chain=="OUTPUT") { nsrc = rule->getSrc(); if (nsrc->isAny()) nsrc->addRef(getFirewallObject()); else rule_comment += "Does SRC match one of the firewall's addresses?"; } if (current_table == "mangle") { if ( ! rule->getClassification() && (current_chain == "POSTROUTING" || current_chain == "FORWARD")) { QString err = QObject::tr( "Fwbuilder can not reproduce iptables rule in " "the table 'mangle', chain %1") .arg(current_chain.c_str()); reportError(err); markCurrentRuleBad(); } } // add rule to the right ruleset RuleSet *ruleset = NULL; std::string ruleset_name = ""; // if (isStandardChain(current_chain)) // { // ruleset = RuleSet::cast( // getFirewallObject()->getFirstByType(Policy::TYPENAME)); // assert(ruleset!=NULL); // } else // { // UnidirectionalRuleSet *rs = getUnidirRuleSet( // current_chain, Policy::TYPENAME); // assert(rs!=NULL); // ruleset = rs->ruleset; // } UnidirectionalRuleSet *rs = getUnidirRuleSet(current_chain, Policy::TYPENAME); assert(rs!=NULL); ruleset = rs->ruleset; ruleset->add(current_rule); // renumber to clean-up rule positions ruleset->renumberRules(); rule->setDirection(PolicyRule::Both); if ( !i_intf.empty() && !o_intf.empty()) { // The rule defines inbound and outbound interfaces simultaneously. // -i i_intf // -o o_intf // Making this rule inbound on i_intf, with action Branch // Branch points to a new rule set where we put a rule with // direction outbount on o_intf action = PolicyRule::Branch; string branch_ruleset_name = ruleset->getName() + "_" + o_intf; // note that this new rule only matches interface and // direction, everything else has been matched by the main // rule. There is no need for the rule in the branch to be stateful // (that is what the last bool argument for createPolicyBranch() is for) PolicyRule *new_rule = createPolicyBranch(rule, branch_ruleset_name, true, true); // Important: at this point we have assembled the // current_rule completely. This means all rule elements, // its action and options have been set above. By // duplicating it into new_rule, we set the same action in // the new_rule. We will change interface, direction and // action in the current_rule below. RuleElement* re; new_rule->setDirection(PolicyRule::Outbound); newInterface(o_intf); Interface *intf = all_interfaces[o_intf]; re = new_rule->getItf(); re->addRef(intf); rule->setDirection(PolicyRule::Inbound); newInterface(i_intf); intf = all_interfaces[i_intf]; re =rule->getItf(); re->addRef(intf); QString interfaces = QString("-i %1 -o %2").arg(i_intf.c_str()).arg(o_intf.c_str()); rule_comment += QString( " Both inbound and outbound interfaces " "in original iptables command: %1").arg(interfaces).toStdString(); addMessageToLog( QString("Warning: Creating branch ruleset '%1' to " "match inbound and outbound interfaces %2") .arg(branch_ruleset_name.c_str()).arg(interfaces)); } else { if ( !i_intf.empty()) { rule->setDirection(PolicyRule::Inbound); newInterface(i_intf); Interface *intf = all_interfaces[i_intf]; RuleElementItf* re =rule->getItf(); re->addRef(intf); } if ( !o_intf.empty()) { rule->setDirection(PolicyRule::Outbound); newInterface(o_intf); Interface *intf = all_interfaces[o_intf]; RuleElementItf* re =rule->getItf(); re->addRef(intf); } } processModuleMatches(); addStandardImportComment( current_rule, QString::fromUtf8(rule_comment.c_str())); } if ( ! isSupportedTable(current_table)) { QString err = QObject::tr( "Rule can not be imported correctly because " "original configuration uses " "unrecognized netfilter table \"%1\". ") .arg(QString::fromUtf8(current_table.c_str())); reportError(err); } if (error_tracker->hasWarnings()) { QStringList warn = error_tracker->getWarnings(); // parser errors and warnings are added to the log by // PFCfgParser::reportError() and PFCfgParser::reportWarning() // so we dont need to add them again here foreach(QString w, warn) { if (!w.startsWith("Parser warning:")) addMessageToLog("Warning: " + w); } markCurrentRuleBad(); } if (error_tracker->hasErrors()) { QStringList err = error_tracker->getErrors(); foreach(QString e, err) { if (!e.startsWith("Parser error:")) addMessageToLog("Error: " + e); } markCurrentRuleBad(); } current_rule = NULL; rule_comment = ""; clear(); } void IPTImporter::pushNATRule() { // populate all elements of the rule NATRule *rule = NATRule::cast(current_rule); FWOptions *fwopt = getFirewallObject()->getOptionsObject(); assert(fwopt!=NULL); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); addOSrc(); addODst(); addOSrv(); if (src_nm.empty()) src_nm = InetAddr::getAllOnes().toString(); if (dst_nm.empty()) dst_nm = InetAddr::getAllOnes().toString(); if (nat_nm.empty()) nat_nm = InetAddr::getAllOnes().toString(); NATRule::NATRuleTypes rule_type = NATRule::Unknown; if (target=="ACCEPT") { rule_type = NATRule::NONAT; } if (target=="MASQUERADE") { rule_type = NATRule::Masq; RuleElementTSrc *re = rule->getTSrc(); assert(re!=NULL); if ( !o_intf.empty() ) { newInterface(o_intf); Interface *intf = all_interfaces[o_intf]; re->addRef(intf); } else { re->addRef(getFirewallObject()); } } if (target=="SNAT") { rule_type = NATRule::SNAT; FWObject *tsrc = NULL; if (nat_addr1!=nat_addr2) { ObjectSignature sig(error_tracker); sig.type_name = AddressRange::TYPENAME; sig.setAddressRangeStart(nat_addr1.c_str()); sig.setAddressRangeEnd(nat_addr2.c_str()); tsrc = commitObject(address_maker->createObject(sig)); } else { ObjectSignature sig(error_tracker); sig.type_name = Address::TYPENAME; sig.setAddress(nat_addr1.c_str()); sig.setNetmask(nat_nm.c_str()); tsrc = commitObject(address_maker->createObject(sig)); } RuleElementTSrc *re = rule->getTSrc(); assert(re!=NULL); re->addRef(tsrc); if (!nat_port_range_start.empty()) { str_tuple empty_range("0", "0"); str_tuple nat_port_range(nat_port_range_start, nat_port_range_end); FWObject *s = createTCPUDPService(nat_port_range, empty_range, protocol); RuleElementTSrv *re = rule->getTSrv(); assert(re!=NULL); re->addRef(s); } if (!o_intf.empty()) { RuleElement *itf_o_re = rule->getItfOutb(); assert(itf_o_re!=NULL); newInterface(o_intf); Interface *intf = all_interfaces[o_intf]; itf_o_re->addRef(intf); } } if (target=="DNAT") { rule_type = NATRule::DNAT; // if chain is "OUTPUT", put fw object in OSrc if (current_chain == "OUTPUT") { RuleElementOSrc *re = rule->getOSrc(); assert(re!=NULL); re->addRef(getFirewallObject()); } FWObject *tdst = NULL; if (nat_addr1!=nat_addr2) { ObjectSignature sig(error_tracker); sig.type_name = AddressRange::TYPENAME; sig.setAddressRangeStart(nat_addr1.c_str()); sig.setAddressRangeEnd(nat_addr2.c_str()); tdst = commitObject(address_maker->createObject(sig)); } else { ObjectSignature sig(error_tracker); sig.type_name = Address::TYPENAME; sig.setAddress(nat_addr1.c_str()); sig.setNetmask(nat_nm.c_str()); tdst = commitObject(address_maker->createObject(sig)); } RuleElementTDst *re = rule->getTDst(); assert(re!=NULL); re->addRef(tdst); if (!nat_port_range_start.empty()) { str_tuple empty_range("0", "0"); str_tuple nat_port_range(nat_port_range_start, nat_port_range_end); FWObject *s = createTCPUDPService(empty_range, nat_port_range, protocol); RuleElementTSrv *re = rule->getTSrv(); assert(re!=NULL); re->addRef(s); } if (!i_intf.empty()) { RuleElement *itf_i_re = rule->getItfInb(); assert(itf_i_re!=NULL); newInterface(i_intf); Interface *intf = all_interfaces[i_intf]; itf_i_re->addRef(intf); } } if (target=="REDIRECT") { rule_type = NATRule::Redirect; RuleElementTDst *re = rule->getTDst(); assert(re!=NULL); re->addRef(getFirewallObject()); if (!nat_port_range_start.empty()) { str_tuple empty_range("0", "0"); str_tuple nat_port_range(nat_port_range_start, nat_port_range_end); FWObject *s = createTCPUDPService(empty_range, nat_port_range, protocol); RuleElementTSrv *re = rule->getTSrv(); assert(re!=NULL); re->addRef(s); } if ( ! o_intf.empty()) { RuleElement *itf_o_re = rule->getItfOutb(); assert(itf_o_re!=NULL); newInterface(o_intf); Interface *intf = all_interfaces[o_intf]; itf_o_re->addRef(intf); } } if (target=="NETMAP") { FWObject *o = NULL; if (!src_a.empty()) { rule_type = NATRule::SNetnat; RuleElementTSrc *tsrc = rule->getTSrc(); assert(tsrc!=NULL); ObjectSignature sig(error_tracker); sig.type_name = Address::TYPENAME; sig.setAddress(nat_addr1.c_str()); sig.setNetmask(nat_nm.c_str()); o = commitObject(address_maker->createObject(sig)); tsrc->addRef(o); } if (!dst_a.empty()) { rule_type = NATRule::DNetnat; RuleElementTDst *tdst = rule->getTDst(); assert(tdst!=NULL); ObjectSignature sig(error_tracker); sig.type_name = Address::TYPENAME; sig.setAddress(nat_addr1.c_str()); sig.setNetmask(nat_nm.c_str()); o = commitObject(address_maker->createObject(sig)); tdst->addRef(o); } } if (rule_type==NATRule::Unknown) { if (fwbdebug) qDebug("Unknown target %s, creating branch", target.c_str()); // unknown target, consider it a branch // std::string branch_ruleset_name = target; rule_type = NATRule::NATBranch; rule->setAction(NATRule::Branch); UnidirectionalRuleSet *rs = branch_rulesets[branch_ruleset_name]; if (rs==NULL) { rs = getUnidirRuleSet(branch_ruleset_name, NAT::TYPENAME); branch_rulesets[branch_ruleset_name] = rs; } rs->ruleset->setName(target); rule->setBranch(rs->ruleset); } rule->setRuleType(rule_type); // add rule to the right ruleset RuleSet *ruleset = NULL; std::string ruleset_name = ""; if (isStandardChain(current_chain)) { ruleset = RuleSet::cast( getFirewallObject()->getFirstByType(NAT::TYPENAME)); assert(ruleset!=NULL); ruleset->add(current_rule); } else { UnidirectionalRuleSet *rs = getUnidirRuleSet(current_chain, NAT::TYPENAME); assert(rs!=NULL); rs->ruleset->add(current_rule); ruleset = rs->ruleset; } // renumber to clean-up rule positions ruleset->renumberRules(); addStandardImportComment(current_rule, QString::fromUtf8(rule_comment.c_str())); if (error_tracker->hasErrors()) markCurrentRuleBad(); // RuleSet *nat = RuleSet::cast( // getFirewallObject()->getFirstByType(NAT::TYPENAME)); // assert( nat!=NULL ); // nat->add(current_rule); current_rule = NULL; rule_comment = ""; clear(); } Firewall* IPTImporter::finalize() { // scan all UnidirectionalRuleSet objects, set interface and // direction in all rules of corresponding RuleSet and merge all // UnidirectionalRuleSet into one RuleSet object. Attach this // object to the firewall. if (fwbdebug) qDebug("IPTImporter::finalize()"); if (haveFirewallObject()) { Firewall *fw = Firewall::cast(getFirewallObject()); if (fwbdebug) qDebug() << "fw=" << fw; fw->setStr("host_OS", "linux24"); Resources::setDefaultTargetOptions("linux24" , fw); fw->setStr("version", ""); // default version "any" string version = findBestVersionMatch( "iptables", discovered_version.c_str()).toStdString(); if ( ! version.empty()) fw->setStr("version", version); fw->getManagementObject(); // creates management obj FWOptions *fwopt = fw->getOptionsObject(); assert(fwopt!=NULL); fwopt->setBool("firewall_is_part_of_any_and_networks", false); // scan all UnidirectionalRuleSet objects and take care of // their default action std::map::iterator it; for (it=all_rulesets.begin(); it!=all_rulesets.end(); ++it) { // rs_index is a string composed of the table name and chain name // like "filter / FORWARD" or "mangle / PREROUTING" // This string is created in IPTImporter::getUnidirRuleSet() string rs_index = it->first; UnidirectionalRuleSet* rs = it->second; if (Policy::isA(rs->ruleset) && rs->default_action == PolicyRule::Accept) { FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); PolicyRule *rule = PolicyRule::cast( dbroot->create(PolicyRule::TYPENAME)); // check if all child objects were populated properly FWOptions *ropt = rule->getOptionsObject(); assert(ropt != NULL); ropt->setBool("stateless", true); rule->setAction(PolicyRule::Accept); rule->setLogging(false); ostringstream str1; str1 << "Default iptables policy in " << rs_index; rule->setComment(str1.str()); if (rs->name == "FORWARD") { rule->setDirection(PolicyRule::Both); if (rs_index.find("mangle") != string::npos) { QString err = QObject::tr( "Warning: Line %1: Can not reproduce default " "action in table 'mangle' chain 'FORWARD'. " "(Generated rule may not generate equivalent " "iptables command when compiled)" ); ropt->setStr("color", getBadRuleColor()); rule->setComment( err.arg( rs->default_action_line_number).toUtf8().constData()); addMessageToLog(err.arg(rs->default_action_line_number)); } } if (rs->name == "INPUT") { RuleElementDst* dst = rule->getDst(); assert(dst!=NULL); dst->addRef(fw); rule->setDirection(PolicyRule::Inbound); if (rs_index.find("mangle") != string::npos) { QString err = QObject::tr( "Warning: Line %1: Can not reproduce default " "action in table 'mangle' chain 'INPUT'. " "(Generated rule may not generate equivalent " "iptables command when compiled)" ); ropt->setStr("color", getBadRuleColor()); rule->setComment( err.arg( rs->default_action_line_number).toUtf8().constData()); addMessageToLog(err.arg(rs->default_action_line_number)); } } if (rs->name == "OUTPUT") { RuleElementSrc* src = rule->getSrc(); assert(src!=NULL); src->addRef(fw); rule->setDirection(PolicyRule::Outbound); } if (rs->name == "PREROUTING") { rule->setDirection(PolicyRule::Inbound); } if (rs->name == "POSTROUTING") { rule->setDirection(PolicyRule::Outbound); } rs->ruleset->add(rule); addMessageToLog( QString("Warning: Line %1: Added rule to reproduce default " "policy ACCEPT in %2") .arg(rs->default_action_line_number) .arg(rs_index.c_str())); } } list l2 = fw->getByType(Policy::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { RuleSet *rs = RuleSet::cast(*i); rs->renumberRules(); } l2 = fw->getByType(NAT::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { RuleSet *rs = RuleSet::cast(*i); rs->renumberRules(); } return getFirewallObject(); } else { return NULL; } } UnidirectionalRuleSet* IPTImporter::checkUnidirRuleSet( const std::string &ruleset_name) { string all_rulesets_index = current_table + "/" + ruleset_name; return all_rulesets[all_rulesets_index]; } UnidirectionalRuleSet* IPTImporter::getUnidirRuleSet( const std::string &ruleset_name, const string &ruleset_type_name) { string all_rulesets_index = current_table + "/" + ruleset_name; UnidirectionalRuleSet *rs = all_rulesets[all_rulesets_index]; if (rs == NULL) { RuleSet *ruleset = NULL; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); if (isStandardChain(ruleset_name)) { if (ruleset_type_name == NAT::TYPENAME) ruleset = RuleSet::cast( getFirewallObject()->getFirstByType(NAT::TYPENAME)); else { list policies = getFirewallObject()->getByType(Policy::TYPENAME); if (current_table == "mangle") { for (list::iterator it=policies.begin(); it!=policies.end(); ++it) { RuleSet *rs = RuleSet::cast(*it); FWOptions *rulesetopt = rs->getOptionsObject(); if (rulesetopt->getBool("mangle_only_rule_set")) { ruleset = rs; break; } } if (ruleset == NULL) { ruleset = RuleSet::cast(dbroot->create(Policy::TYPENAME)); FWOptions *rulesetopt = ruleset->getOptionsObject(); rulesetopt->setBool("mangle_only_rule_set", true); ruleset->setTop(true); ruleset->setName("Mangle"); getFirewallObject()->add(ruleset); } } else { for (list::iterator it=policies.begin(); it!=policies.end(); ++it) { RuleSet *rs = RuleSet::cast(*it); FWOptions *rulesetopt = rs->getOptionsObject(); if (rs->getName() == "Policy" && !rulesetopt->getBool("mangle_only_rule_set")) { ruleset = rs; break; } } if (ruleset == NULL) { ruleset = RuleSet::cast(dbroot->create(Policy::TYPENAME)); FWOptions *rulesetopt = ruleset->getOptionsObject(); rulesetopt->setBool("mangle_only_rule_set", false); ruleset->setTop(true); ruleset->setName("Policy"); getFirewallObject()->add(ruleset); } } } } else { ruleset = RuleSet::cast(dbroot->create(ruleset_type_name)); ruleset->setName(ruleset_name); getFirewallObject()->add(ruleset); } rs = new UnidirectionalRuleSet(); rs->name = ruleset_name; rs->ruleset = ruleset; all_rulesets[all_rulesets_index] = rs; } return rs; } void IPTImporter::newUnidirRuleSet(const string &chain_name, const string &ruleset_type) { current_ruleset = getUnidirRuleSet(chain_name, ruleset_type); // creates if new addMessageToLog( QString("New ruleset: %1 / %2") .arg(current_table.c_str()).arg(current_ruleset->name.c_str())); } bool IPTImporter::isStandardChain(const std::string &ipt_chain) { return (ipt_chain == "INPUT" || ipt_chain == "OUTPUT" || ipt_chain == "FORWARD" || ipt_chain == "PREROUTING" || ipt_chain == "POSTROUTING"); } fwbuilder-5.1.0.3599/src/import/objectMaker.h0000644000175000017500000001014311733011756021475 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OBJECT_MAKER_H_ #define _OBJECT_MAKER_H_ #include "fwbuilder/FWObject.h" #include "fwbuilder/Dispatch.h" #include "objectSignature.h" #include #include #include #include namespace libfwbuilder { class AddressRange; class AttachedNetworks; class Cluster; class CustomService; class Firewall; class Host; class ICMPService; class IPService; class IPv4; class IPv6; class Interface; class Library; class Network; class NetworkIPv6; class ObjectGroup; class ServiceGroup; class TCPService; class TagService; class UDPService; class physAddress; class UserService; }; class ObjectMakerException : public std::exception { QString err; public: ObjectMakerException(const std::string &e) { err = e.c_str(); } ObjectMakerException(const QString &e) { err = e; } virtual ~ObjectMakerException() throw() {} QString toString() { return err; } virtual const char* what() const throw() { return err.toStdString().c_str(); } }; class ObjectMakerErrorTracker { QStringList errors; bool error_status; QStringList warnings; bool warning_status; public: ObjectMakerErrorTracker() { error_status = false; warning_status = false; } void clear() { error_status = false; warning_status = false; errors.clear(); warnings.clear(); } void registerError(const QString &msg); void registerError(const std::string &msg); bool hasErrors() { return error_status; } QStringList getErrors() { return errors; } void registerWarning(const QString &msg); void registerWarning(const std::string &msg); bool hasWarnings() { return warning_status; } QStringList getWarnings() { return warnings; } }; class ObjectMaker { protected: ObjectMakerErrorTracker *error_tracker; libfwbuilder::Library *library; libfwbuilder::FWObject *last_created; QMap named_object_registry; QMap anon_object_registry; libfwbuilder::FWObject* findMatchingObject(const ObjectSignature &sig); void registerNamedObject(const ObjectSignature &sig, libfwbuilder::FWObject* obj); void registerAnonymousObject(const ObjectSignature &sig, libfwbuilder::FWObject* obj); public: ObjectMaker(libfwbuilder::Library *l, ObjectMakerErrorTracker *et) { library = l; error_tracker = et; last_created = NULL; } virtual ~ObjectMaker() {}; virtual void clear(); virtual libfwbuilder::FWObject* createObject(ObjectSignature &sig); libfwbuilder::FWObject *getLastCreatedObject() { return last_created; } void prepareForDeduplication(libfwbuilder::FWObject *root); libfwbuilder::FWObject* createObject(const std::string &objType, const std::string &objName); libfwbuilder::FWObject* createObject(libfwbuilder::FWObject *parent, const std::string &objType, const std::string &objName); libfwbuilder::FWObject* promoteToNamedObject(libfwbuilder::FWObject *obj, const std::string &objName); }; #endif fwbuilder-5.1.0.3599/src/import/IPTImporter.h0000644000175000017500000001243111733011756021427 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FWB_POLICY_IMPORTER_IPT_H_ #define _FWB_POLICY_IMPORTER_IPT_H_ #include #include #include #include #include #include "Importer.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Logger.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include #include #include class IPTImporter : public Importer { QMap reject_action_arg_mapping; int aux_branch_number; libfwbuilder::FWObject* createTCPUDPService(str_tuple &src_range, str_tuple &dst_range, const std::string &proto); libfwbuilder::FWObject* createTCPUDPService(const std::string &proto); virtual libfwbuilder::FWObject* createTCPService(const QString &name=""); virtual libfwbuilder::FWObject* createUDPService(const QString &name=""); virtual libfwbuilder::FWObject* makeSrcObj(); virtual libfwbuilder::FWObject* makeDstObj(); void processModuleMatches(); void addAllModuleMatches(libfwbuilder::PolicyRule *rule); void addMarkMatch(libfwbuilder::PolicyRule *rule); void addLengthMatch(libfwbuilder::PolicyRule *rule); void addLimitMatch(libfwbuilder::PolicyRule *rule); void addRecentMatch(libfwbuilder::PolicyRule *rule); void addPktTypeMatch(libfwbuilder::PolicyRule *rule); void addStateMatch(libfwbuilder::PolicyRule *rule, const std::string &state); std::string getBranchName(const std::string &suffix); libfwbuilder::PolicyRule* createPolicyBranch( libfwbuilder::PolicyRule *rule, const std::string &branch_name, bool clear_rule_elements, bool make_stateless); libfwbuilder::NATRule* createNATBranch( libfwbuilder::NATRule *rule, const std::string &branch_name, bool clear_rule_elements); public: int service_group_name_seed; std::string current_table; std::string current_chain; std::string current_state; std::string i_intf; std::string o_intf; std::string target; std::string tmp_port_range_start; std::string tmp_port_range_end; std::list src_port_list; std::list dst_port_list; std::list both_port_list; std::map action_params; // need to keep track of branches in 2.1 // should not be neccessary in 3.0 when multiple // rule can refer to the same branch ruleset std::map branch_rulesets; std::string match_mark; bool neg_match_mark; bool src_neg; bool dst_neg; bool srv_neg; bool intf_neg; bool tmp_neg; std::string limit_val; std::string limit_suffix; std::string limit_burst; std::string length_spec; std::string recent_match; std::string pkt_type_spec; std::string nat_addr1; std::string nat_addr2; std::string nat_nm; std::string nat_port_range_start; std::string nat_port_range_end; bool using_iprange_src; std::string iprange_src_from; std::string iprange_src_to; bool using_iprange_dst; std::string iprange_dst_from; std::string iprange_dst_to; libfwbuilder::PolicyRule *last_mark_rule; IPTImporter(libfwbuilder::FWObject *lib, std::istringstream &input, libfwbuilder::Logger *log, const std::string &fwname); ~IPTImporter(); virtual void run(); virtual void clear(); void startSrcMultiPort(); void pushTmpPortSpecToSrcPortList(); void startDstMultiPort(); void pushTmpPortSpecToDstPortList(); void startBothMultiPort(); void pushTmpPortSpecToBothPortList(); void pushPolicyRule(); void pushNATRule(); virtual void addSrv(); virtual void pushRule(); virtual UnidirectionalRuleSet* getUnidirRuleSet( const std::string &rsname, const std::string &ruleset_type_name); virtual UnidirectionalRuleSet* checkUnidirRuleSet( const std::string &rsname); virtual void newUnidirRuleSet(const std::string &name, const std::string &ruleset_type); // this method actually adds interfaces to the firewall object // and does final clean up. virtual libfwbuilder::Firewall* finalize(); bool isStandardChain(const std::string &ipt_chain); void registerTable(const std::string &table_name); bool isSupportedTable(const std::string &table_name); }; #endif fwbuilder-5.1.0.3599/src/import/PFImporterRun.cpp0000644000175000017500000002131711733011756022323 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/InetAddr.h" #include "PFImporter.h" #include #include #include #include #include #include #include #include #include "../parsers/PFCfgLexer.hpp" #include "../parsers/PFCfgParser.hpp" extern int fwbdebug; using namespace std; using namespace libfwbuilder; /* * Only this module depends on PFCfgLexer and PFCfgParser, * so only this file is recompiled when we change grammar */ void PFImporter::run() { QStringList err; QString parser_err = QObject::tr("Parser error:"); QString gen_err = QObject::tr("Error:"); std::ostringstream parser_debug; /* Do a bit of preprocessing of the input to simplify crazy grammar. * * Do the following (will add more stuff here in the future): * * - fold lines split with '\' * - find macro definitions and perform all macro sustitutions */ QMap named_addresses; QStringList whole_input_tmp; input.seekg (0, ios::beg); char buf[8192]; while (!input.eof()) { input.getline(buf, sizeof(buf)-1); whole_input_tmp.append(QString(buf)); } QString whole_input = whole_input_tmp.join("\n") + "\n"; QRegExp line_continuation("\\\\\\s*\n"); whole_input.replace(line_continuation, ""); QRegExp inline_comment("#.*$"); QRegExp macro_definition("^\\s*(\\S+)\\s*=\\s*(.*)$"); QRegExp list_of_items("^\\{\\s*((\\S+,?\\s*)+)\\s*\\}$"); QMap macros; QMap macros_source_lines; foreach(QString str, whole_input.split("\n")) { QString work_str = str; work_str.replace(inline_comment, ""); work_str = work_str.trimmed(); if (macro_definition.indexIn(work_str) != -1) { QString macro_name = macro_definition.cap(1); QString value = macro_definition.cap(2); value.replace('\"', ""); value = value.simplified(); macros[macro_name] = value; macros_source_lines[macro_name] = macro_definition.cap(0); } } QMapIterator it(macros); while (it.hasNext()) { it.next(); QString macro_name = it.key(); QString value = it.value(); substituteMacros(macros, value); macros[macro_name] = value; } it = macros; while (it.hasNext()) { it.next(); QString macro_name = it.key(); QString value = it.value(); qDebug() << "Macro: name=" << macro_name << "value=" << value; /* * Special case: if this macro defines list of addresses * in '{' '}', we convert it to a table with the same name * so that importer later on can create object group for * it. * * RegExp list_of_items assumes the string has been * stripped of any quotes and trimmed. */ if (list_of_items.indexIn(value) != -1) { qDebug() << "This macro defines a list"; /* * we only convert to table if the list contains at * least one ip address. We assume that if there is an * address there, then all items in the list must * represent addresses, host names or interface names * because pf does not allow mixed address/service * lists anywhere. */ QString list_str = list_of_items.cap(1); list_str.replace(",", ""); QStringList items = list_str.split(QRegExp("\\s"), QString::SkipEmptyParts); qDebug() << items; bool has_address = false; foreach(QString item, items) { qDebug() << "Item:" << item; if (!item.isEmpty() && (item.contains(':') || item.contains('.'))) { try { InetAddr(item.toStdString()); // stop the loop if string successfully // converts to an ip address has_address = true; break; } catch(FWException &ex) { ; } } } if (has_address) { /* * Convert as follows: * Macro: * name = "{ 1.1.1.1 2.2.2.2 }" * to a table: * table "{ 1.1.1.1 2.2.2.2 }" */ QString table_def("table <%1> %2"); whole_input.replace(macros_source_lines[macro_name], table_def.arg(macro_name).arg(value)); /* * And add a macro to the dictionary to map macro_name to * the table */ macros[macro_name] = "<" + macro_name + ">"; qDebug() << "Replacing macro definition with table:"; qDebug() << table_def.arg(macro_name).arg(value); } } } if (fwbdebug) qDebug() << "Macros defined in this file: " << macros; substituteMacros(macros, whole_input); if (fwbdebug) { qDebug() << "pf.conf file after line unfolding and macro substitution:"; qDebug() << whole_input; } istringstream normalized_input(whole_input.toStdString()); PFCfgLexer lexer(normalized_input); PFCfgParser parser(lexer); parser.importer = this; if (fwbdebug) parser.dbg = &std::cerr; else parser.dbg = &parser_debug; try { parser.cfgfile(); } catch(ANTLR_USE_NAMESPACE(antlr)ANTLRException &e) { err << parser_err + " " + e.toString().c_str(); } catch(ObjectMakerException &e) { err << gen_err + " " + e.toString(); } catch(ImporterException &e) { err << gen_err + " " + e.toString(); } catch(std::exception& e) { err << parser_err + " " + e.what(); } if (fwbdebug) { qDebug() << "haveFirewallObject()=" << haveFirewallObject() << "countInterfaces()=" << countInterfaces() << "countRules()=" << countRules(); } if (haveFirewallObject()) { if (countInterfaces()==0) err << noInterfacesErrorMessage(); if (countRules()==0) err << noRulesErrorMessage(); } else { err << parser_err; err << noFirewallErrorMessage(); err << commonFailureErrorMessage(); } if (!err.isEmpty()) *logger << err.join("\n").toUtf8().constData(); } void PFImporter::substituteMacros(const QMap ¯os, QString &buffer) { // make several passes: sometimes macros can use other macros QRegExp any_macro_instance("\\$(\\w+)\\W"); QSet undefined_macros; for (;;) { QMapIterator it(macros); while (it.hasNext()) { it.next(); QString macro_name = it.key(); QString macro_value = it.value(); QRegExp macro_instance(QString("\\$%1(?=\\W)").arg(macro_name)); buffer.replace(macro_instance, macro_value); } bool has_known_macros = false; int idx = 0; while ((idx = buffer.indexOf(any_macro_instance, idx)) != -1) { QString macro_name = any_macro_instance.cap(1); if (macros.contains(macro_name)) has_known_macros = true; else undefined_macros.insert(macro_name); idx++; } if (!has_known_macros) break; } foreach(QString macro_name, undefined_macros) { QString err; err = QObject::tr("Warning: Macro %1 is undefined").arg(macro_name); *logger << err.toUtf8().constData(); } } fwbuilder-5.1.0.3599/src/import/IcmpSpec.h0000644000175000017500000000330011733011756020747 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ICMP_SPEC_H_ #define _ICMP_SPEC_H_ #include #include #include class IcmpSpec { public: std::string icmp_type_name; std::string icmp_type_int; std::string icmp_code_name; std::string icmp_code_int; IcmpSpec() { icmp_type_name = ""; icmp_type_int = ""; icmp_code_name = ""; icmp_code_int = ""; } IcmpSpec(const IcmpSpec &other) { icmp_type_name = other.icmp_type_name; icmp_type_int = other.icmp_type_int; icmp_code_name = other.icmp_code_name; icmp_code_int = other.icmp_code_int; } IcmpSpec(const std::string s1, const std::string s2, const std::string s3, const std::string s4) { icmp_type_name = s1; icmp_type_int = s2; icmp_code_name = s3; icmp_code_int = s4; } }; #endif fwbuilder-5.1.0.3599/src/import/QStringListOperators.h0000644000175000017500000000227311733011756023376 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include extern QStringList& operator<<(QStringList &lst, const char* x); extern QStringList& operator<<(QStringList &lst, const std::string &x); extern QStringList& operator<<(QStringList &lst, int x); extern QStringList& operator<<(QStringList &lst, bool x); extern QStringList& operator<<(QStringList &lst, const QList &x); fwbuilder-5.1.0.3599/src/import/objectMaker.cpp0000644000175000017500000001621211733011756022033 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "objectMaker.h" #include "objectSignature.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Host.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Address.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/Service.h" // TODO: FWBTree needs to be refactored into an independent module #include "../libgui/FWBTree.h" #include #include #include extern int fwbdebug; using namespace libfwbuilder; using namespace std; void ObjectMakerErrorTracker::registerError(const QString &msg) { if ( ! errors.contains(msg)) errors.append(msg); error_status = true; } void ObjectMakerErrorTracker::registerError(const string &msg) { QString qs_msg = QString::fromUtf8(msg.c_str()); if ( ! errors.contains(qs_msg)) errors.append(qs_msg); error_status = true; } void ObjectMakerErrorTracker::registerWarning(const QString &msg) { if ( ! warnings.contains(msg)) warnings.append(msg); warning_status = true; } void ObjectMakerErrorTracker::registerWarning(const string &msg) { QString qs_msg = QString::fromUtf8(msg.c_str()); if ( ! warnings.contains(qs_msg)) warnings.append(qs_msg); warning_status = true; } //**************************************************************** void ObjectMaker::clear() { last_created = NULL; named_object_registry.clear(); anon_object_registry.clear(); } FWObject* ObjectMaker::findMatchingObject(const ObjectSignature &sig) { QString sig_str = sig.toString(); if ( ! sig.object_name.isEmpty()) { if (named_object_registry.count(sig_str) > 0) return library->getRoot()->findInIndex( named_object_registry[sig_str]); return NULL; } if (anon_object_registry.count(sig_str) > 0) return library->getRoot()->findInIndex(anon_object_registry[sig_str]); return NULL; } void ObjectMaker::registerNamedObject(const ObjectSignature &sig, FWObject* obj) { ObjectSignature anon_sig = sig; anon_sig.object_name = ""; QString as = anon_sig.toString(); if (anon_object_registry.count(as) > 0) anon_object_registry.remove(as); named_object_registry[sig.toString()] = (obj!=NULL) ? obj->getId() : -1; } void ObjectMaker::registerAnonymousObject(const ObjectSignature &sig, FWObject* obj) { ObjectSignature anon_sig = sig; anon_sig.object_name = ""; anon_object_registry[anon_sig.toString()] = (obj!=NULL) ? obj->getId() : -1; } /* * take anonymous object @obj and make named object from it. * * - assignin @objName * - check if this object is in standard objects library and if it is, create * a copy since we cant rename objects there * * Note that this means that returned pointer may point to a new object * rather than @obj */ FWObject* ObjectMaker::promoteToNamedObject(FWObject *obj, const std::string &objName) { if (obj->getLibrary()->getId() == FWObjectDatabase::STANDARD_LIB_ID) { FWObject *new_obj = library->getRoot()->create(obj->getTypeName()); new_obj->duplicate(obj); new_obj->setName(objName); ObjectSignature sig(error_tracker); new_obj->dispatch(&sig, (void*)(NULL)); registerNamedObject(sig, new_obj); return new_obj; } else { obj->setName(objName); ObjectSignature sig(error_tracker); obj->dispatch(&sig, (void*)(NULL)); registerNamedObject(sig, obj); return obj; } } //**************************************************************** FWObject* ObjectMaker::createObject(const std::string &objType, const std::string &objName) { assert(library!=NULL); FWBTree tree ; FWObject *slot = tree.getStandardSlotForObject(library,objType.c_str()); return createObject(slot, objType, objName); } FWObject* ObjectMaker::createObject(FWObject *parent, const std::string &objType, const std::string &objName) { assert(library!=NULL); FWObject* o = library->getRoot()->create(objType); if (parent != NULL) { if (parent->isReadOnly()) { QString pn = QString::fromUtf8(parent->getName().c_str()); if (parent->getLibrary()->isReadOnly()) // throw ObjectMakerException( error_tracker->registerError( QObject::tr("Can not add new objects to folder %1 because " "it belongs to a locked library").arg(pn)); else // throw ObjectMakerException( error_tracker->registerError( QObject::tr("Can not add new objects to folder %1 because " "it is locked").arg(pn)); } if (parent->getLibrary()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) { // throw ObjectMakerException( error_tracker->registerError( QObject::tr("Can not add new objects to the \"Deleted Objects\" " "library")); } parent->add(o); } o->setName(objName); return o; } FWObject* ObjectMaker::createObject(ObjectSignature &) { return NULL; } //**************************************************************** /* * scan the tree starting at @root and use registerObject to build * signatures for all address and service objects in order to be able * to use them on import */ void ObjectMaker::prepareForDeduplication(FWObject *root) { if (RuleSet::cast(root) || Rule::cast(root) || FWReference::cast(root) || Host::cast(root) || FWOptions::cast(root)) return; if (Address::cast(root) || MultiAddress::cast(root) || Service::cast(root)) { ObjectSignature sig(error_tracker); root->dispatch(&sig, (void*)(NULL)); registerNamedObject(sig, root); registerAnonymousObject(sig, root); // this erases sig.object_name } if (Library::isA(root) && root->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) return; for (FWObject::iterator it=root->begin(); it!=root->end(); ++it) { prepareForDeduplication(*it); } } fwbuilder-5.1.0.3599/src/import/AddressSpec.h0000644000175000017500000000471311733011756021455 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ADDRESS_SPEC_H_ #define _ADDRESS_SPEC_H_ #include #include #include #include class AddressSpec { public: typedef enum { UNKNOWN, ANY, HOST_NAME, HOST_ADDRESS, NETWORK_ADDRESS, SPECIAL_ADDRESS, INTERFACE_NAME, INTERFACE_NETWORK, INTERFACE_BROADCAST, INTERFACE_CONFIGURATION, INTERFACE_OR_HOST_NAME, TABLE } address_type; address_type at; bool neg; std::string address; std::string netmask; std::string broadcast; AddressSpec() { at = UNKNOWN; neg = false; address = ""; netmask = ""; broadcast = ""; } AddressSpec(const AddressSpec &other) { at = other.at; neg = other.neg; address = other.address; netmask = other.netmask; broadcast = other.broadcast; } AddressSpec(address_type _at, bool _neg, const std::string _addr, const std::string _nm) { at = _at; neg= _neg; address = _addr; netmask = _nm; } // This function is mostly used in unit tests QString toString() { QStringList str; QString address_type_as_string("type:%1"); str << "AddressSpec"; str << address_type_as_string.arg(at); str << QString((neg)? "neg:true" : "neg:false"); str << QString("addr:%1").arg(address.c_str()); str << QString("netm:%1").arg(netmask.c_str()); str << QString("bcast:%1").arg(broadcast.c_str()); return str.join("|"); } }; #endif fwbuilder-5.1.0.3599/src/import/PFImporter.cpp0000644000175000017500000013634611733011756021647 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "PFImporter.h" #include #include #include #include #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TCPUDPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "../libgui/platforms.h" #include #include extern int fwbdebug; // TODO: this should move to some common library, together with // getVersionsForPlatform() it uses. Currently these functions are // defined in libgui/platforms.cpp extern QString findBestVersionMatch(const QString &platform, const QString &discovered_version); using namespace std; using namespace libfwbuilder; PFImporter::PFImporter(FWObject *lib, std::istringstream &input, Logger *log, const std::string &fwname) : Importer(lib, "pf", input, log, fwname) { setPlatform("pf"); address_maker->setInvertedNetmasks(false); icmp_codes_to_reject_parameters["net-unr"] = "ICMP net unreachable"; icmp_codes_to_reject_parameters["0"] = "ICMP net unreachable"; icmp_codes_to_reject_parameters["host-unr"] = "ICMP host unreachable"; icmp_codes_to_reject_parameters["1"] = "ICMP host unreachable"; icmp_codes_to_reject_parameters["proto-unr"] = "ICMP protocol unreachable"; icmp_codes_to_reject_parameters["2"] = "ICMP protocol unreachable"; icmp_codes_to_reject_parameters["port-unr"] = "ICMP port unreachable"; icmp_codes_to_reject_parameters["3"] = "ICMP port unreachable"; icmp_codes_to_reject_parameters["net-prohib"] = "ICMP net prohibited"; icmp_codes_to_reject_parameters["9"] = "ICMP net prohibited"; icmp_codes_to_reject_parameters["host-prohib"] = "ICMP host prohibited"; icmp_codes_to_reject_parameters["10"] = "ICMP host prohibited"; icmp_codes_to_reject_parameters["filter-prohib"] = "ICMP admin prohibited"; icmp_codes_to_reject_parameters["13"] = "ICMP admin prohibited"; } PFImporter::~PFImporter() { } void PFImporter::clear() { rule_type = NATRule::Unknown; quick = false; direction = ""; address_family = ""; iface_group.clear(); proto_list.clear(); tmp_group.clear(); src_group.clear(); dst_group.clear(); nat_group.clear(); src_neg = false; dst_neg = false; tmp_neg = false; tmp_port_def = ""; tmp_port_op = ""; src_port_group.clear(); dst_port_group.clear(); nat_port_group.clear(); tmp_port_group.clear(); icmp_type_code_group.clear(); block_action_params.clear(); queue = ""; state_op = ""; logopts = ""; flags_check = ""; flags_mask = ""; tag = ""; tagged = ""; tagged_neg = false; route_type = UNKNOWN; route_group.clear(); pooltype_opt = ""; nat_rule_opt_2 = ""; // Do not clear name-value pairs lists of timeout and limits since // they is filled when we parse "set timeout", "set limit" // commands and then used in finalize() scrub_rule = false; Importer::clear(); } void PFImporter::clearTempVars() { Importer::clear(); } void PFImporter::addSrc() { PolicyRule *rule = PolicyRule::cast(current_rule); RuleElement *re = rule->getSrc(); list::iterator it; for (it=src_group.begin(); it!=src_group.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) re->addRef(obj); } } void PFImporter::addDst() { PolicyRule *rule = PolicyRule::cast(current_rule); RuleElement *re = rule->getDst(); list::iterator it; for (it=dst_group.begin(); it!=dst_group.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) re->addRef(obj); } } void PFImporter::addSrv() { PolicyRule *rule = PolicyRule::cast(current_rule); addServiceObjectsToRE(rule->getSrv()); } void PFImporter::addServiceObjectsToRE(RuleElement *re) { list::iterator it; for (it=proto_list.begin(); it!=proto_list.end(); ++it) { // TODO: need better interface to Importer::makeSrvObj() // function and other functions that it uses. protocol = *it; if (protocol == "icmp") { list::iterator i1; for (i1=icmp_type_code_group.begin(); i1!=icmp_type_code_group.end(); ++i1) { IcmpSpec is = *i1; ObjectSignature sig(error_tracker); sig.type_name = ICMPService::TYPENAME; if ( ! is.icmp_type_name.empty()) { sig.setIcmpFromName(is.icmp_type_name.c_str()); } else { sig.setIcmpType(is.icmp_type_int.c_str()); } if ( ! is.icmp_code_name.empty()) { sig.setIcmpCodeFromName(is.icmp_code_name.c_str()); } else { sig.setIcmpCode(is.icmp_code_int.c_str()); } FWObject *s = service_maker->createObject(sig); if (s) re->addRef(s); } } else { if (protocol == "tcp" || protocol == "udp") { // TODO: deal with cases where both source and destination // ports are matched. // See PIXImporter::fixServiceObjectUsedForBothSrcAndDstPorts() if (src_port_group.size() == 0 && dst_port_group.size() == 0) { // protocol has been defined but not ports to match ObjectSignature sig(error_tracker); buildTCPUDPObjectSingature( &sig, PortSpec(), PortSpec(), protocol.c_str(), flags_check.c_str(), flags_mask.c_str()); re->addRef(commitObject(service_maker->createObject(sig))); } else { addTCPUDPServiceObjectsToRE(re, protocol, src_port_group, dst_port_group, false); } } else { // protocol is not icmp, udp or tcp ObjectSignature sig(error_tracker); sig.type_name = IPService::TYPENAME; sig.setProtocol(protocol.c_str()); sig.fragments = fragments; re->addRef(commitObject(service_maker->createObject(sig))); } } } if (! tagged.empty()) { ObjectSignature sig(error_tracker); sig.type_name = TagService::TYPENAME; sig.tag = tagged.c_str(); re->addRef( commitObject(service_maker->createObject(sig)) ); if (tagged_neg) re->setNeg(true); tagged = ""; } } void PFImporter::addTCPUDPServiceObjectsToRE( RuleElement *re, const std::string &protocol, const list< PortSpec > &src_port_list, const list< PortSpec > &dst_port_list, bool for_nat_rhs) { list src_ports = src_port_list; if (src_port_list.size() == 0) src_ports.push_back(PortSpec()); list dst_ports = dst_port_list; if (dst_port_list.size() == 0) dst_ports.push_back(PortSpec()); list::const_iterator psis; list::const_iterator psid; for (psis=src_ports.begin(); psis!=src_ports.end(); ++psis) { PortSpec ps_src = *psis; for (psid=dst_ports.begin(); psid!=dst_ports.end(); ++psid) { PortSpec ps_dst = *psid; ObjectSignature sig(error_tracker); buildTCPUDPObjectSingature( &sig, ps_src, ps_dst, protocol.c_str(), (for_nat_rhs) ? "" : flags_check.c_str(), (for_nat_rhs) ? "" : flags_mask.c_str()); re->addRef(commitObject(service_maker->createObject(sig))); if (!for_nat_rhs && ps_dst.port_op == "!=") re->setNeg(true); } } } void PFImporter::addOSrc() { NATRule *rule = NATRule::cast(current_rule); RuleElement *re = rule->getOSrc(); list::iterator it; for (it=src_group.begin(); it!=src_group.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) re->addRef(obj); } } void PFImporter::addODst() { NATRule *rule = NATRule::cast(current_rule); RuleElement *re = rule->getODst(); list::iterator it; for (it=dst_group.begin(); it!=dst_group.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) re->addRef(obj); } } void PFImporter::addOSrv() { NATRule *rule = NATRule::cast(current_rule); addServiceObjectsToRE(rule->getOSrv()); } void PFImporter::addTSrc() { NATRule *rule = NATRule::cast(current_rule); RuleElement *re = rule->getTSrc(); list::iterator it; for (it=nat_group.begin(); it!=nat_group.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) re->addRef(obj); } } void PFImporter::addTDst() { NATRule *rule = NATRule::cast(current_rule); RuleElement *re = rule->getTDst(); list::iterator it; for (it=nat_group.begin(); it!=nat_group.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) re->addRef(obj); } } void PFImporter::addTSrvSNAT() { NATRule *rule = NATRule::cast(current_rule); if (protocol == "tcp" || protocol == "udp") { addTCPUDPServiceObjectsToRE(rule->getTSrv(), protocol, nat_port_group, list< PortSpec >(), true); // for_nat_rhs } } void PFImporter::addTSrvDNAT() { NATRule *rule = NATRule::cast(current_rule); if (protocol == "tcp" || protocol == "udp") { addTCPUDPServiceObjectsToRE(rule->getTSrv(), protocol, list< PortSpec >(), nat_port_group, true); // for_nat_rhs } } /* * Set source and destination port ranges in the object signature * object. */ bool PFImporter::buildTCPUDPObjectSingature(ObjectSignature *sig, const PortSpec &src_port, const PortSpec &dst_port, const QString &protocol, const QString &flags_check, const QString &flags_mask) { if (protocol == "tcp") sig->type_name = TCPService::TYPENAME; else sig->type_name = UDPService::TYPENAME; if (src_port.port_op == "<>" || dst_port.port_op == "<>") { error_tracker->registerError( QObject::tr("'except ranges' ('<>') for port numbers " "are not supported yet.")); return false; } if (src_port.port_op == "!=" || dst_port.port_op == "!=") { error_tracker->registerError( QObject::tr("'Port not equal' operation is not supported yet.")); } sig->port_range_inclusive = true; sig->setSrcPortRangeFromPortOpForPF(src_port.port_op.c_str(), src_port.port1.c_str(), src_port.port2.c_str(), protocol); sig->setDstPortRangeFromPortOpForPF(dst_port.port_op.c_str(), dst_port.port1.c_str(), dst_port.port2.c_str(), protocol); if (protocol == "tcp") { convertTcpFlags(sig->flags_comp, flags_check); convertTcpFlags(sig->flags_mask, flags_mask); } return true; } void PFImporter::convertTcpFlags(QList &flags_list, const QString &flags_str) { for (int i=0; iregisterError( QObject::tr("TCP flag matches 'E' and 'W' " "are not supported.")); } } qSort(flags_list); } FWObject* PFImporter::makeAddressObj(AddressSpec &as) { if (as.at == AddressSpec::ANY) return NULL; if (as.at == AddressSpec::INTERFACE_OR_HOST_NAME) { interfaceProperties *int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject( user_choice_host_os); if (int_prop->looksLikeInterface(as.address.c_str())) { Interface *intf = getInterfaceByName(as.address); if (intf == NULL) { // this interface was never used in "on " clause before newInterface(as.address); intf = getInterfaceByName(as.address); } return intf; } else { QString name = QString::fromUtf8(as.address.c_str()); if (name.startsWith('$')) { /* * We perform macro substitutions in * PFImporter::substituteMacros(), however if we get a * host name that starts with a '$' here, then this is * an undefined macro that could not be substituted. * Mark rule as bad but still create run-time DNSName * object. */ error_tracker->registerWarning( QObject::tr("Macro '%1' was undefined, rule may be broken") .arg(name)); } ObjectSignature sig(error_tracker); sig.type_name = DNSName::TYPENAME; sig.object_name = name; sig.dns_name = name; return address_maker->createObject(sig); } } if (as.at == AddressSpec::INTERFACE_NETWORK) { Interface *intf = getInterfaceByName(as.address); if (intf == NULL) { // this interface was never used in "on " clause before newInterface(as.address); intf = getInterfaceByName(as.address); } FWObject *o = intf->getFirstByType(AttachedNetworks::TYPENAME); if ( o != NULL ) { return o; } else { ObjectMaker maker(Library::cast(library), error_tracker); string name = intf->getName() + "-net"; AttachedNetworks *an = AttachedNetworks::cast( maker.createObject(intf, AttachedNetworks::TYPENAME, name)); an->setRunTime(true); an->setSourceName(intf->getName()); address_table_registry[name.c_str()] = an; return an; } } if (as.at == AddressSpec::INTERFACE_BROADCAST) { error_tracker->registerError( QObject::tr("import of 'interface:broadcast' is not supported.")); return NULL; } if (as.at == AddressSpec::HOST_ADDRESS) { return Importer::makeAddressObj(as.address, ""); } if (as.at == AddressSpec::NETWORK_ADDRESS) { return Importer::makeAddressObj(as.address, as.netmask); } if (as.at == AddressSpec::SPECIAL_ADDRESS) { if (as.address == "self") return getFirewallObject(); { error_tracker->registerError( QObject::tr("Warning: matching '%1' is not supported") .arg(as.address.c_str())); return NULL; } } if (as.at == AddressSpec::TABLE) { FWObject *at = address_table_registry[as.address.c_str()]; if (isObjectBroken(at)) { error_tracker->registerError(getBrokenObjectError(at)); } return at; } return NULL; } void PFImporter::addLogging() { PolicyRule *rule = PolicyRule::cast(current_rule); FWOptions *ropt = rule->getOptionsObject(); /* alerts Immediate action needed (severity=1) critical Critical conditions (severity=2) debugging Debugging messages (severity=7) disable Disable log option on this ACL element, (no log at all) emergencies System is unusable (severity=0) errors Error conditions (severity=3) inactive Keyword for disabling an ACL element informational Informational messages (severity=6) interval Configure log interval, default value is 300 sec notifications Normal but significant conditions (severity=5) warnings Warning conditions (severity=4) */ QMap logging_levels; logging_levels["alerts"] = "alert"; logging_levels["critical"] = "crit"; logging_levels["debugging"] = "debug"; logging_levels["emergencies"] = ""; logging_levels["errors"] = "error"; logging_levels["informational"] = "info"; logging_levels["notifications"] = "notice"; logging_levels["warnings"] = "warning"; logging_levels["0"] = ""; logging_levels["1"] = "alert"; logging_levels["2"] = "crit"; logging_levels["3"] = "error"; logging_levels["4"] = "warning"; logging_levels["5"] = "notice"; logging_levels["6"] = "info"; logging_levels["7"] = "debug"; // QStringList log_levels = getLogLevels("pix"); rule->setLogging(logging); QString log_level_qs = log_level.c_str(); if ( ! log_level_qs.isEmpty()) { if (logging_levels.count(log_level_qs) != 0) ropt->setStr("log_level", logging_levels[log_level_qs].toStdString()); else ropt->setStr("log_level", log_level); if (log_level_qs == "disable" || log_level_qs == "inactive") ropt->setBool("disable_logging_for_this_rule", true); } if ( ! log_interval.empty()) { bool ok = false; int log_interval_int = QString(log_interval.c_str()).toInt(&ok); if (ok) ropt->setInt("log_interval", log_interval_int); } } void PFImporter::pushRule() { if (PolicyRule::isA(current_rule)) pushPolicyRule(); else pushNATRule(); assert(current_rule!=NULL); if (error_tracker->hasWarnings()) { QStringList warn = error_tracker->getWarnings(); // parser errors and warnings are added to the log by // PFCfgParser::reportError() and PFCfgParser::reportWarning() // so we dont need to add them again here foreach(QString w, warn) { if (!w.startsWith("Parser warning:")) addMessageToLog("Warning: " + w); } markCurrentRuleBad(); } if (error_tracker->hasErrors()) { QStringList err = error_tracker->getErrors(); foreach(QString e, err) { if (!e.startsWith("Parser error:")) addMessageToLog("Error: " + e); } markCurrentRuleBad(); } current_rule = NULL; rule_comment = ""; clear(); } void PFImporter::pushPolicyRule() { RuleSet *ruleset = RuleSet::cast( getFirewallObject()->getFirstByType(Policy::TYPENAME)); // this importer does not use UnidirectionalRuleSet objects but // base class uses dictionary all_rulesets to do some checks (e.g. // countRules()) so we'll create one dummy UnidirectionalRuleSet object string ruleset_name = ruleset->getName(); if (checkUnidirRuleSet(ruleset_name) == NULL) { UnidirectionalRuleSet *rs = new UnidirectionalRuleSet(); rs->name = ruleset_name; rs->ruleset = ruleset; all_rulesets[ruleset_name] = rs; } assert(current_rule!=NULL); // populate all elements of the rule // Note that standard function // setInterfaceAndDirectionForRuleSet() assumes there is only one // interface, but here we can have a group. Information about // interfaces (even if there is only one) is stored in the list // iface_group // // importer->setInterfaceAndDirectionForRuleSet( // "", importer->iface, importer->direction); QString message_str = QString("filtering rule: action %1; interfaces: %2"); PolicyRule *rule = PolicyRule::cast(current_rule); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); if (action=="pass") { if (quick) rule->setAction(PolicyRule::Accept); else rule->setAction(PolicyRule::Continue); ropt->setBool("stateless", false); } if (action=="block") { rule->setAction(PolicyRule::Deny); ropt->setBool("stateless", true); if (block_action_params.size() > 0) { string block_return = block_action_params.front(); block_action_params.pop_front(); if (block_return == "drop") { ; // Action Drop accurately represents "block drop" } if (block_return == "return") { rule->setAction(PolicyRule::Reject); error_tracker->registerError( QObject::tr( "'block return' is not supported in fwbuilder, " "replacing with 'block return-icmp' ")); ropt->setStr("action_on_reject", "ICMP admin prohibited"); } if (block_return == "return-rst") { rule->setAction(PolicyRule::Reject); ropt->setStr("action_on_reject", "TCP RST"); } if (block_return == "return-icmp") { rule->setAction(PolicyRule::Reject); ropt->setStr("action_on_reject", "ICMP admin prohibited"); if (block_action_params.size() > 0) { string icmp_code = icmp_codes_to_reject_parameters[ block_action_params.front()]; block_action_params.pop_front(); if (icmp_code.empty()) error_tracker->registerError( QObject::tr( "Unrecognized icmp code parameter for " "'block return-icmp' action: %1") .arg(block_action_params.front().c_str())); ropt->setStr("action_on_reject", icmp_code); } } } } if (direction == "in") rule->setDirection(PolicyRule::Inbound); if (direction == "out") rule->setDirection(PolicyRule::Outbound); if (direction == "") rule->setDirection(PolicyRule::Both); QStringList interfaces; list::iterator it; for (it=iface_group.begin(); it!=iface_group.end(); ++it) { Interface *intf = getInterfaceByName(it->name); assert(intf!=NULL); RuleElement *re =rule->getItf(); re->addRef(intf); if (it->neg) re->setNeg(true); interfaces << it->name.c_str(); } /* * Set state-related rule options using variable state_op */ if (state_op.empty()) { // when "state" keyword is absent, behavior depends on the // version because different versions have different // defaults. Versions prior to 4.0 treat missing keyword as // "no state", while versions past 4.0 treat is as "keep // state". See also #2441. Rules with action "block" should // always be stateless by default. if (XMLTools::version_compare(user_choice_version, "4.0") < 0) ropt->setBool("stateless", true); else { if (action == "pass") ropt->setBool("stateless", false); } } if (state_op == "no") ropt->setBool("stateless", true); if (state_op == "modulate") ropt->setBool("pf_modulate_state", true); if (state_op == "keep") ropt->setBool("stateless", false); if (state_op == "synproxy") ropt->setBool("pf_synproxy", true); /* * Set tagging rule option using variable tag */ if ( ! tag.empty()) { ObjectSignature sig(error_tracker); sig.type_name = TagService::TYPENAME; sig.tag = tag.c_str(); FWObject *tobj = commitObject(service_maker->createObject(sig)); rule->setTagging(tobj != NULL); rule->setTagObject(tobj); } /* * Set queueing rule option using variable queue */ if (! queue.empty()) ropt->setStr("pf_classify_str", queue); /* * route-to options * */ if (route_type != UNKNOWN && route_group.size() != 0) { switch (route_type) { case ROUTE_TO: ropt->setStr("pf_route_option", "route_through"); break; case REPLY_TO: ropt->setStr("pf_route_option", "route_reply_through"); break; case DUP_TO: ropt->setStr("pf_route_option", "route_copy_through"); break; default: ; } /* * see initialization of routeLoadOptions_pf in function * init_platforms() in platforms.cpp for the list of strings * recognized by compilers as values of "pf_route_load_option" * rule option */ if (pooltype_opt == "bitmask") ropt->setStr("pf_route_load_option", "bitmask"); if (pooltype_opt == "random") ropt->setStr("pf_route_load_option", "random"); if (pooltype_opt == "source-hash") ropt->setStr("pf_route_load_option", "source_hash"); if (pooltype_opt == "round-robin") ropt->setStr("pf_route_load_option", "round_robin"); QStringList route_opt_addr; bool has_different_interfaces = false; string interface_name; QStringList reconstructed_parameter_string; list::iterator it; for (it=route_group.begin(); it!=route_group.end(); ++it) { RouteSpec &rs = *it; Interface *intf = getInterfaceByName(rs.iface); if (intf == NULL) { // this interface was never used in "on " clause before intf = newInterface(rs.iface); } if (interface_name.empty()) interface_name = intf->getName(); if (interface_name != intf->getName()) { has_different_interfaces = true; } ropt->setStr("pf_route_opt_if", rs.iface); QString gw; if (rs.netmask.empty()) gw = rs.address.c_str(); else gw = QString("%1/%2") .arg(rs.address.c_str()).arg(rs.netmask.c_str()); route_opt_addr << gw; reconstructed_parameter_string << QString("(%1 %2)") .arg(intf->getName().c_str()).arg(gw); } if (has_different_interfaces) { // currently we do not support route-to configuration // with multiple interface-gateway pairs. multiple // gateway addresses and only one interface // are allowed. These rules will be imported partially. error_tracker->registerWarning( QObject::tr("'route-to' parameters with multiple " "interface-gateway pairs are not supported: \"%1\"") .arg(reconstructed_parameter_string.join(", "))); } ropt->setStr("pf_route_opt_addr", route_opt_addr.join(",").toStdString()); rule->setRouting( ! ropt->getStr("pf_route_option").empty()); } /* * Protocols are in proto_list * Source addresses are in src_group * Destination addresses are in dst_group */ addSrc(); addDst(); addSrv(); /* * Set logging options using variables logging and logopts */ addLogging(); // then add it to the current ruleset ruleset->add(current_rule); addStandardImportComment( current_rule, QString::fromUtf8(rule_comment.c_str())); addMessageToLog(message_str.arg(action.c_str()).arg(interfaces.join(","))); } void PFImporter::pushNATRule() { RuleSet *ruleset = RuleSet::cast( getFirewallObject()->getFirstByType(NAT::TYPENAME)); // this importer does not use UnidirectionalRuleSet objects but // base class uses dictionary all_rulesets to do some checks (e.g. // countRules()) so we'll create one dummy UnidirectionalRuleSet object string ruleset_name = ruleset->getName(); if (checkUnidirRuleSet(ruleset_name) == NULL) { UnidirectionalRuleSet *rs = new UnidirectionalRuleSet(); rs->name = ruleset_name; rs->ruleset = ruleset; all_rulesets[ruleset_name] = rs; } assert(current_rule!=NULL); QString message_str = QString("nat rule: action %1; interfaces: %2"); NATRule *rule = NATRule::cast(current_rule); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); if (action=="nat") rule->setRuleType(NATRule::SNAT); if (action=="rdr") rule->setRuleType(NATRule::DNAT); if (action=="nonat") rule->setRuleType(NATRule::NONAT); rule->setAction(NATRule::Translate); // remember that even though NATRule has two interface rule elements // ("in" and "out"), compiler for PF only uses one, the "outbound" one. QStringList interfaces; list::iterator it; for (it=iface_group.begin(); it!=iface_group.end(); ++it) { Interface *intf = getInterfaceByName(it->name); assert(intf!=NULL); RuleElement *re =rule->getItfOutb(); re->addRef(intf); if (it->neg) re->setNeg(true); interfaces << it->name.c_str(); } addOSrc(); addODst(); addOSrv(); switch (rule->getRuleType()) { case NATRule::SNAT: addTSrc(); addTSrvSNAT(); break; case NATRule::DNAT: addTDst(); addTSrvDNAT(); break; case NATRule::NONAT: break; default: error_tracker->registerError( QObject::tr("NAT rules \"%1\" " "are not supported yet.").arg(action.c_str())); } if (pooltype_opt == "bitmask") ropt->setBool("pf_bitmask", true); if (pooltype_opt == "random") ropt->setBool("pf_random", true); if (pooltype_opt == "source-hash") ropt->setBool("pf_source_hash", true); if (pooltype_opt == "round-robin") ropt->setBool("pf_round_robin", true); if (nat_rule_opt_2 == "static-port") ropt->setBool("pf_static_port", true); // reset rule type. Rule type is used internally by the compilers // and is not stored in the object permanently. Rule type assigned // by the compiler may actually differ from what we use here // (e.g. some DNAT rules are identified as LB -- load balancing -- // rules by compilers) rule->setRuleType(NATRule::Unknown); // then add it to the current ruleset ruleset->add(current_rule); addStandardImportComment( current_rule, QString::fromUtf8(rule_comment.c_str())); addMessageToLog(message_str.arg(action.c_str()).arg(interfaces.join(","))); } Firewall* PFImporter::finalize() { // scan all UnidirectionalRuleSet objects, set interface and // direction in all rules of corresponding RuleSet and merge all // UnidirectionalRuleSet into one RuleSet object. Attach this // object to the firewall. if (fwbdebug) qDebug("PFImporter::finalize()"); if (haveFirewallObject()) { Firewall *fw = Firewall::cast(getFirewallObject()); // We can not "discover" host OS just by reading pf.conf file. // Assume FreeBSD fw->setStr("platform", "pf"); string host_os = "freebsd"; fw->setStr("host_OS", host_os); Resources::setDefaultTargetOptions(host_os , fw); FWOptions* options = fw->getOptionsObject(); // We may be able to infer at least something about the version // from the pf.conf file in the future. string version = findBestVersionMatch( "pf", discovered_version.c_str()).toStdString(); if ( ! version.empty()) fw->setStr("version", version); rearrangeVlanInterfaces(); list l1 = fw->getByType(Policy::TYPENAME); for (list::iterator i=l1.begin(); i!=l1.end(); ++i) { RuleSet *rs = RuleSet::cast(*i); rs->renumberRules(); } // Deal with NAT ruleset list l2 = fw->getByType(NAT::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { RuleSet *rs = RuleSet::cast(*i); rs->renumberRules(); } // We can not deduce ip addresses of interfaces from just // looking at pf.conf so lets just mark them all "dynamic" list l3 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l3.begin(); i!=l3.end(); ++i) { Interface *iface = Interface::cast(*i); iface->setUnnumbered(false); iface->setDyn(true); } // Log lines from now on should not start with original file line numbers setCurrentLineNumber(-1); // configure timeouts // mapping between PF timeout names and our option names map timeout_option_names; timeout_option_names["tcp.first"] = "pf_tcp_first"; timeout_option_names["tcp.opening"] = "pf_tcp_opening"; timeout_option_names["tcp.established"] = "pf_tcp_established"; timeout_option_names["tcp.closing"] = "pf_tcp_closing"; timeout_option_names["tcp.finwait"] = "pf_tcp_finwait"; timeout_option_names["tcp.closed"] = "pf_tcp_closed"; timeout_option_names["udp.first"] = "pf_udp_first"; timeout_option_names["udp.single"] = "pf_udp_single"; timeout_option_names["udp.multiple"] = "pf_udp_multiple"; timeout_option_names["icmp.first"] = "pf_icmp_first"; timeout_option_names["icmp.error"] = "pf_icmp_error"; timeout_option_names["other.first"] = "pf_other_first"; timeout_option_names["other.single"] = "pf_other_single"; timeout_option_names["other.multiple"] = "pf_other_multiple"; timeout_option_names["adaptive.start"] = "pf_adaptive_start"; timeout_option_names["adaptive.end"] = "pf_adaptive_end"; timeout_option_names["frag"] = "pf_timeout_frag"; timeout_option_names["interval"] = "pf_timeout_interval"; // looks like we do not support src.track as of 4.3 // timeout_option_names["src.track"] = "pf_src_track"; // mapping between PF timeout names and boolean option names that // activate setting of the corresponding timeout map timeout_activation_names; timeout_activation_names["tcp.first"] = "pf_set_tcp_first"; timeout_activation_names["tcp.opening"] = "pf_set_tcp_opening"; timeout_activation_names["tcp.established"] = "pf_set_tcp_established"; timeout_activation_names["tcp.closing"] = "pf_set_tcp_closing"; timeout_activation_names["tcp.finwait"] = "pf_set_tcp_finwait"; timeout_activation_names["tcp.closed"] = "pf_set_tcp_closed"; timeout_activation_names["udp.first"] = "pf_set_udp_first"; timeout_activation_names["udp.single"] = "pf_set_udp_single"; timeout_activation_names["udp.multiple"] = "pf_set_udp_multiple"; timeout_activation_names["icmp.first"] = "pf_set_icmp_first"; timeout_activation_names["icmp.error"] = "pf_set_icmp_error"; timeout_activation_names["other.first"] = "pf_set_other_first"; timeout_activation_names["other.single"] = "pf_set_other_single"; timeout_activation_names["other.multiple"] = "pf_set_other_multiple"; timeout_activation_names["adaptive.start"] = "pf_set_adaptive"; timeout_activation_names["adaptive.end"] = "pf_set_adaptive"; timeout_activation_names["frag"] = "pf_do_timeout_frag"; timeout_activation_names["interval"] = "pf_do_timeout_interval"; if (timeouts.size() > 0) { addMessageToLog(QObject::tr("Configuring timeouts:\n")); list::iterator it; for (it=timeouts.begin(); it!=timeouts.end(); ++it) { string name = it->first; bool ok = false; int value = QString(it->second.c_str()).toInt(&ok); addMessageToLog(QString("set timeout %1 %2\n") .arg(name.c_str()).arg(value)); if (timeout_activation_names.count(name) == 0) { addMessageToLog( QObject::tr("Error: Unknown timeout name %1\n") .arg(name.c_str())); } else { options->setBool(timeout_activation_names[name], true); options->setInt(timeout_option_names[name], value); } } } // configure limits map limit_option_names; limit_option_names["frags"] = "pf_limit_frags"; limit_option_names["states"] = "pf_limit_states"; limit_option_names["src-nodes"] = "pf_limit_src_nodes"; limit_option_names["tables"] = "pf_limit_tables"; limit_option_names["tables-entries"] = "pf_limit_table_entries"; // mapping between PF limit names and boolean option names that // activate setting of the corresponding limit map limit_activation_names; limit_activation_names["frags"] = "pf_do_limit_frags"; limit_activation_names["states"] = "pf_do_limit_states"; limit_activation_names["src-nodes"] = "pf_do_limit_src_nodes"; limit_activation_names["tables"] = "pf_do_limit_tables"; limit_activation_names["tables-entries"] = "pf_do_limit_table_entries"; if (limits.size() > 0) { addMessageToLog(QObject::tr("Configuring limits:\n")); list::iterator it; for (it=limits.begin(); it!=limits.end(); ++it) { string name = it->first; bool ok = false; int value = QString(it->second.c_str()).toInt(&ok); addMessageToLog(QString("set limit %1 %2\n") .arg(name.c_str()).arg(value)); if (limit_activation_names.count(name) == 0) { addMessageToLog( QObject::tr("Error: Unknown limit name %1\n") .arg(name.c_str())); } else { options->setBool(limit_activation_names[name], true); options->setInt(limit_option_names[name], value); } } } // cofigure other "set" commands // addMessageToLog(QObject::tr("Configuring set commands:\n")); if ( ! set_optimization.empty()) { options->setStr("pf_optimization", set_optimization); addMessageToLog(QString("set optimization %1\n") .arg(set_optimization.c_str())); } if ( ! set_block_policy.empty()) { options->setStr("pf_block_policy", set_block_policy); addMessageToLog(QString("set block-policy %1\n") .arg(set_block_policy.c_str())); } if ( ! set_state_policy.empty()) { options->setStr("pf_state_policy", set_state_policy); addMessageToLog(QString("set state-policy %1\n") .arg(set_state_policy.c_str())); } if (set_skip_on.size() != 0) { for (list::iterator it=set_skip_on.begin(); it!=set_skip_on.end(); ++it) { string skip_interface_name = *it; interfaceProperties *int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject( user_choice_host_os); if (int_prop->looksLikeInterface(skip_interface_name.c_str())) { Interface *intf = getInterfaceByName(skip_interface_name); if (intf == NULL) { // this interface was never used in "on // " clause before newInterface(skip_interface_name); intf = getInterfaceByName(skip_interface_name); intf->setUnprotected(true); addMessageToLog(QString("set skip on %1\n") .arg(intf->getName().c_str())); } } else { addMessageToLog( QObject::tr("Error: In 'set skip on %1' argument " "does not look like an interface name\n") .arg(skip_interface_name.c_str())); } } } if ( ! set_debug.empty()) { options->setStr("pf_set_debug", set_debug); addMessageToLog(QString("set debug %1\n").arg(set_debug.c_str())); } // Scrub options if (scrub_options.size() > 0) { options->setBool("pf_do_scrub", true); list::iterator it; for (it=scrub_options.begin(); it!=scrub_options.end(); ++it) { string name = it->first; string arg = it->second; addMessageToLog(QString("scrub %1 %2\n") .arg(name.c_str()).arg(arg.c_str())); if (name == "fragment") { if (arg == "reassemble") options->setBool("pf_scrub_reassemble", true); if (arg == "crop") options->setBool("pf_scrub_fragm_crop", true); if (arg == "drop-ovl") options->setBool("pf_scrub_fragm_drop_ovl", true); } if (name == "reassemble") options->setBool("pf_scrub_reassemble_tcp", true); if (name == "no-df") options->setBool("pf_scrub_no_df", true); if (name == "min-ttl") { options->setBool("pf_scrub_use_minttl", true); options->setStr("pf_scrub_minttl", arg); } if (name == "max-mss") { options->setBool("pf_scrub_use_maxmss", true); options->setStr("pf_scrub_maxmss", arg); } if (name == "random-id") options->setBool("pf_scrub_random_id", true); } } return fw; } else { return NULL; } } Interface* PFImporter::getInterfaceByName(const string &name) { map::iterator it; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *intf = it->second; if (intf->getName() == name) { return intf; } } return NULL; } void PFImporter::newAddressTableObject(const string &name, const string &file) { addMessageToLog(QString("Address Table: <%1> file %2") .arg(QString::fromUtf8(name.c_str())) .arg(QString::fromUtf8(file.c_str()))); ObjectMaker maker(Library::cast(library), error_tracker); ObjectSignature sig(error_tracker); sig.type_name = AddressTable::TYPENAME; sig.object_name = QString::fromUtf8(name.c_str()); QString filename = QString::fromUtf8(file.c_str()); filename.replace("\"", ""); sig.address_table_name = filename; FWObject *at = address_maker->createObject(sig); address_table_registry[sig.object_name] = at; } void PFImporter::newAddressTableObject(const string &name, list &addresses) { bool has_negations = false; QStringList addr_list; list::iterator it; for (it=addresses.begin(); it!=addresses.end(); ++it) { if (it->neg) has_negations = true; QString nm = QString(it->netmask.c_str()).trimmed(); if (!nm.isEmpty()) nm = "/" + nm; addr_list << QString("%1%2%3") .arg((it->neg)?"!":"").arg(it->address.c_str()).arg(nm); } addMessageToLog(QString("Address Table: <%1>: %2") .arg(QString::fromUtf8(name.c_str())) .arg(addr_list.join(", "))); ObjectMaker maker(Library::cast(library), error_tracker); FWObject *og = commitObject(maker.createObject(ObjectGroup::TYPENAME, name.c_str())); assert(og!=NULL); address_table_registry[name.c_str()] = og; if (has_negations) { // can not use error_tracker->registerError() here because // tables are created before importer encounters any rules and // so this error can not be associated with a rule. QString err = QObject::tr("Error: import of table definition with negated " "addresses is not supported."); addMessageToLog(err); err = QObject::tr("Address table '%1' has a mix of negated and non-negated " "addresses in the original file."); registerBrokenObject(og, err.arg(QString::fromUtf8(name.c_str()))); } for (it=addresses.begin(); it!=addresses.end(); ++it) { FWObject *obj = makeAddressObj(*it); if (obj) og->addRef(obj); } } fwbuilder-5.1.0.3599/src/import/PIXImporterRun.cpp0000644000175000017500000000740511733011756022460 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "PIXImporter.h" #include #include #include #include #include #include #include #include #include "../parsers/PIXCfgLexer.hpp" #include "../parsers/PIXCfgParser.hpp" extern int fwbdebug; using namespace std; /* * Only this module depends on PIXCfgLexer and PIXCfgParser, * so only this file is recompiled when we change grammar */ void PIXImporter::run() { QStringList err; QString parser_err = QObject::tr("Parser error:"); QString gen_err = QObject::tr("Error:"); std::ostringstream parser_debug; /* Do a bit of preprocessing of the input to simplify crazy grammar. * * Do the following (will add more stuff here in the future): * * - process "names" section: isolate "name" commands and build * dictionary of names and addresses, then scan input file and * replace names with addresses everywhere. */ QMap named_addresses; QStringList whole_input; input.seekg (0, ios::beg); char buf[8192]; while (!input.eof()) { input.getline(buf, sizeof(buf)-1); whole_input.append(QString(buf)); } foreach(QString str, whole_input) { if (str.startsWith("name ")) { QStringList items = str.split(" "); named_addresses[items[2]] = items[1]; } } QStringList normalized_input_buffer; foreach(QString str, whole_input) { if ( ! str.startsWith("name ")) { QMap::iterator it; for (it=named_addresses.begin(); it!=named_addresses.end(); ++it) { QString re("\\b%1\\b"); str.replace(QRegExp(re.arg(it.key())), it.value()); } } normalized_input_buffer.append(str); } istringstream normalized_input( normalized_input_buffer.join("\n").toStdString()); PIXCfgLexer lexer(normalized_input); PIXCfgParser parser(lexer); parser.importer = this; if (fwbdebug) parser.dbg = &std::cerr; else parser.dbg = &parser_debug; try { parser.cfgfile(); } catch(ANTLR_USE_NAMESPACE(antlr)ANTLRException &e) { err << parser_err + " " + e.toString().c_str(); } catch(ObjectMakerException &e) { err << gen_err + " " + e.toString(); } catch(ImporterException &e) { err << gen_err + " " + e.toString(); } catch(std::exception& e) { err << parser_err + " " + e.what(); } if (haveFirewallObject()) { if (countInterfaces()==0) err << noInterfacesErrorMessage(); if (countRules()==0) err << noRulesErrorMessage(); } else { err << parser_err; err << noFirewallErrorMessage(); err << commonFailureErrorMessage(); } if (!err.isEmpty()) *logger << err.join("\n").toUtf8().constData(); } fwbuilder-5.1.0.3599/src/import/PFImporter.h0000644000175000017500000001200611733011756021276 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FWB_POLICY_IMPORTER_PF_H_ #define _FWB_POLICY_IMPORTER_PF_H_ #include #include #include #include #include #include "IOSImporter.h" #include "AddressSpec.h" #include "InterfaceSpec.h" #include "PortSpec.h" #include "IcmpSpec.h" #include "RouteSpec.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Logger.h" #include "fwbuilder/Rule.h" #include "fwbuilder/NAT.h" #include class PFImporter : public Importer { void addServiceObjectsToRE(libfwbuilder::RuleElement *re); void addTCPUDPServiceObjectsToRE( libfwbuilder::RuleElement *re, const std::string &protocol, const std::list< PortSpec > &src_port_spec_list, const std::list< PortSpec > &dst_port_spec_list, bool for_nat_rhs); void substituteMacros(const QMap ¯os, QString &buffer); public: typedef enum { UNKNOWN, ROUTE_TO, REPLY_TO, DUP_TO} route_op_type; QMap address_table_registry; std::string direction; std::string address_family; bool quick; bool src_neg; bool dst_neg; bool tmp_neg; std::map icmp_codes_to_reject_parameters; std::list block_action_params; std::list iface_group; std::list proto_list; std::list< AddressSpec > src_group; std::list< AddressSpec > dst_group; std::list< AddressSpec > nat_group; std::list< AddressSpec > tmp_group; std::string tmp_port_op; std::string tmp_port_def; std::list< PortSpec > src_port_group; std::list< PortSpec > dst_port_group; std::list< PortSpec > nat_port_group; std::list< PortSpec > tmp_port_group; std::list< IcmpSpec > icmp_type_code_group; route_op_type route_type; std::list route_group; std::string queue; std::string state_op; std::string logopts; std::string flags_check; std::string flags_mask; std::string tag; bool tagged_neg; std::string tagged; std::string pooltype_opt; std::string nat_rule_opt_2; libfwbuilder::NATRule::NATRuleTypes rule_type; std::list timeouts; std::list limits; std::string set_optimization; std::string set_block_policy; std::string set_state_policy; std::string set_debug; std::list set_skip_on; std::list scrub_options; bool scrub_rule; PFImporter(libfwbuilder::FWObject *lib, std::istringstream &input, libfwbuilder::Logger *log, const std::string &fwname); ~PFImporter(); virtual void clear(); void clearTempVars(); virtual void run(); void pushPolicyRule(); void pushNATRule(); void buildDNATRule(); void buildSNATRule(); virtual void pushRule(); // this method actually adds interfaces to the firewall object // and does final clean up. virtual libfwbuilder::Firewall* finalize(); virtual libfwbuilder::FWObject* makeAddressObj(AddressSpec &as); virtual void addSrc(); virtual void addDst(); virtual void addSrv(); virtual void addOSrc(); virtual void addODst(); virtual void addOSrv(); virtual void addTSrc(); virtual void addTDst(); void addTSrvSNAT(); void addTSrvDNAT(); virtual void addLogging(); libfwbuilder::Interface* getInterfaceByName(const std::string &name); void newAddressTableObject(const std::string &name, const std::string &file); void newAddressTableObject(const std::string &name, std::list &addresses); bool buildTCPUDPObjectSingature(ObjectSignature *sig, const PortSpec &src_port, const PortSpec &dst_port, const QString &protocol, const QString &flags_check, const QString &flags_mask); void convertTcpFlags(QList &flags_list, const QString &flags_str); }; #endif fwbuilder-5.1.0.3599/src/import/serviceObjectMaker.h0000644000175000017500000000434111733011756023021 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _SERVICE_OBJECT_MAKER_H_ #define _SERVICE_OBJECT_MAKER_H_ #include "objectMaker.h" class ServiceObjectMaker : public ObjectMaker { int custom_service_code_tracker; std::map custom_service_codes; std::map tcp_flag_names; public: ServiceObjectMaker(libfwbuilder::Library *l, ObjectMakerErrorTracker *et); virtual ~ServiceObjectMaker(); virtual void clear(); virtual libfwbuilder::FWObject* createObject(ObjectSignature &sig); libfwbuilder::FWObject* getMirroredServiceObject(libfwbuilder::FWObject *obj); protected: virtual libfwbuilder::FWObject* getCustomService(const QString &platform, const QString &code, const QString &protocol); virtual libfwbuilder::FWObject* getTCPService(int srs, int sre, int drs, int dre, bool established, QList &flags_mask, QList &flags_comp); virtual libfwbuilder::FWObject* getUDPService(int srs, int sre, int drs, int dre); virtual libfwbuilder::FWObject* getTagService(const QString &tagcode); }; #endif fwbuilder-5.1.0.3599/src/import/QStringListOperators.cpp0000644000175000017500000000307411733011756023731 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "QStringListOperators.h" #include #include QStringList& operator<<(QStringList &lst, const char* x) { lst << QString::fromUtf8(x); return lst; } QStringList& operator<<(QStringList &lst, const std::string &x) { lst << QString::fromUtf8(x.c_str()); return lst; } QStringList& operator<<(QStringList &lst, int x) { QString s; lst << s.setNum(x); return lst; } QStringList& operator<<(QStringList &lst, bool x) { QString s; lst << s.setNum(x); return lst; } QStringList& operator<<(QStringList &lst, const QList &x) { QStringList r; foreach(int i, x) { QString s; r << s.setNum(i); } lst << "[" + r.join(",") + "]"; return lst; } fwbuilder-5.1.0.3599/src/import/Importer.cpp0000644000175000017500000007072511733011756021417 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Trying to avoid dependency on libgui (except for FWBTree, which * will be refactored into some other common module in the future). */ #include "../../config.h" #include "Importer.h" #include #include #include #include #include #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include #include #include #include extern int fwbdebug; using namespace libfwbuilder; using namespace std; // a functor to join list into a string with separator sep class join : public std::unary_function { std::string *result; std::string separator; public: join(std::string *res, const std::string &s) { result = res; separator = s; } void operator()(std::string &s); }; void join::operator()(string &s) { if (!result->empty()) *result += separator; *result += s; } std::string Importer::getBadRuleColor() { return "#C86E6E"; } void Importer::SaveTmpAddrToSrc() { src_a = tmp_a; src_nm = tmp_nm; } void Importer::SaveTmpAddrToDst() { dst_a = tmp_a; dst_nm = tmp_nm; } void Importer::SaveTmpPortToSrc() { src_port_op = tmp_port_op; src_port_spec = tmp_port_spec; } void Importer::SaveTmpPortToDst() { dst_port_op = tmp_port_op; dst_port_spec = tmp_port_spec; } Importer::Importer(FWObject *_lib, const std::string &_platform, std::istringstream &_input, Logger *log, const std::string &fwname) : input(_input) { this->fwname = fwname; library = _lib; fw = NULL; error_counter = 0; logger = log; platform = _platform; current_interface = NULL; current_ruleset = NULL; current_rule = NULL; error_tracker = new ObjectMakerErrorTracker(); address_maker = new AddressObjectMaker(Library::cast(library), error_tracker); service_maker = new ServiceObjectMaker(Library::cast(library), error_tracker); clear(); } void Importer::prepareForDeduplication() { address_maker->prepareForDeduplication(library->getRoot()); service_maker->prepareForDeduplication(library->getRoot()); } void Importer::run() { // create and run parsers in derived classes } Importer::~Importer() { all_rulesets.clear(); all_interfaces.clear(); delete address_maker; delete service_maker; delete error_tracker; } void Importer::clear() { last_comment.clear(); action = ""; protocol = ""; src_a = ""; src_nm = ""; src_port_op = ""; src_port_spec = ""; dst_a = ""; dst_nm = ""; dst_port_op = ""; dst_port_spec = ""; tmp_a = ""; tmp_nm = ""; tmp_port_op = ""; tmp_port_spec = ""; tmp_port_spec_2 = ""; tmp_range_1 = ""; tmp_range_2 = ""; logging = false; log_level = ""; log_interval = ""; established = false; fragments = false; icmp_spec = ""; icmp_code = ""; icmp_type = ""; time_range_name = ""; if (!tcp_flags_mask.empty()) tcp_flags_mask.clear(); if (!tcp_flags_comp.empty()) tcp_flags_comp.clear(); if (!tmp_tcp_flags_list.empty()) tmp_tcp_flags_list.clear(); error_tracker->clear(); } Firewall* Importer::getFirewallObject() { if (fw!=NULL) return fw; ObjectMaker maker(Library::cast(library), error_tracker); FWObject *nobj = commitObject( maker.createObject(Firewall::TYPENAME, fwname)); fw = Firewall::cast(nobj); fw->setStr("platform", platform); Resources::setDefaultTargetOptions(platform , fw); return fw; } /* * Creates firewall object and sets its name * * This assumes that configuration clase that declares host name * comes first (true for Ciscos, but may not be true for others) * */ void Importer::setHostName(const std::string &hn) { getFirewallObject()->setName(hn); addMessageToLog("Host name: " + hn); } void Importer::setDiscoveredVersion(const std::string &v) { discovered_version = v; addMessageToLog("Version: " + v); } void Importer::setDiscoveredPlatform(const std::string &v) { discovered_platform = v; addMessageToLog("Platform: " + v); } Interface* Importer::newInterface(const std::string &name) { if (all_interfaces.count(name)>0) return all_interfaces[name]; ObjectMaker maker(Library::cast(library), error_tracker); FWObject *nobj = commitObject( maker.createObject(getFirewallObject(), Interface::TYPENAME, name)); current_interface = Interface::cast(nobj); current_interface->setUnnumbered(true); all_interfaces[name] = current_interface; addMessageToLog(QObject::tr("New interface: %1").arg(name.c_str())); return current_interface; } /* * We call this when importer for PIX or IOS encounters interface in * state "shutdown" */ void Importer::ignoreCurrentInterface() { if (current_interface) { string name = current_interface->getName(); current_interface->getParent()->remove(current_interface); all_interfaces.erase(name); current_interface = NULL; } } void Importer::addAddressObjectToInterface(Interface*intf, const string &addr, const string &netm) { intf->setUnnumbered(false); if (addr == "dhcp") intf->setDyn(true); else { string aname = getFirewallObject()->getName() + ":" + intf->getName() + ":ip"; ObjectMaker maker(Library::cast(library), error_tracker); FWObject *nobj = commitObject( maker.createObject(intf, IPv4::TYPENAME, aname)); IPv4::cast(nobj)->setAddress( InetAddr(addr) ); IPv4::cast(nobj)->setNetmask( InetAddr(netm) ); } } void Importer::addInterfaceAddress(const std::string &a, const std::string &nm) { if (current_interface!=NULL) { addAddressObjectToInterface(current_interface, a, nm); addMessageToLog("Interface address: " + a + "/" + nm); } } void Importer::addInterfaceAddress(const std::string &label, const std::string &a, const std::string &nm) { map::iterator it; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *intf = it->second; if (intf->getLabel() == label) { addAddressObjectToInterface(intf, a, nm); addMessageToLog("Interface address: " + a + "/" + nm); } } } void Importer::setInterfaceComment(const std::string &descr) { // current_interface can be NULL if parser encountered command // that looked like interface description but in reality was // description of something else. For example this happens when // it finds command "description" under "controller" in Cisco router // configuration. if (current_interface!=NULL) { current_interface->setComment(descr); addMessageToLog("Interface comment: " + descr); } } void Importer::setInterfaceLabel(const std::string &descr) { if (current_interface!=NULL) { current_interface->setLabel(descr); addMessageToLog("Interface label: " + descr); } } void Importer::setInterfaceParametes(const std::string &phys_intf_or_label, const std::string &label, const std::string &sec_level) { addMessageToLog("Interface parameters: " + phys_intf_or_label + " " + label + " " + sec_level); if (all_interfaces.count(phys_intf_or_label)) { // since first arg. is physical interface name, this must be pix6 // "nameif ethernet0 outside security0" Interface *intf = all_interfaces[phys_intf_or_label]; intf->setLabel(label); QRegExp pix6_sec_level("security(\\d+)"); if (pix6_sec_level.indexIn(sec_level.c_str()) > -1) intf->setSecurityLevel(pix6_sec_level.cap(1).toInt()); } else { // since first arg is not physical interface name, it must be a label // as in pix7 config // // interface Ethernet0.101 // vlan 101 // nameif outside // security-level 0 // ip address 192.0.2.253 255.255.255.0 setInterfaceLabel(phys_intf_or_label); } } void Importer::setInterfaceSecurityLevel(const std::string &seclevel) { if (current_interface!=NULL) { QString sl(seclevel.c_str()); current_interface->setSecurityLevel(sl.toInt()); } } void Importer::setInterfaceVlanId(const std::string &vlan_id) { if (current_interface!=NULL) { FWOptions *ifopt = (Interface::cast(current_interface))->getOptionsObject(); ifopt->setStr("type", "8021q"); ifopt->setStr("vlan_id", vlan_id); } } void Importer::addRuleComment(const std::string &comm) { rule_comment += comm; addMessageToLog("Rule comment: " + comm); } UnidirectionalRuleSet* Importer::checkUnidirRuleSet( const std::string &ruleset_name) { return all_rulesets[ruleset_name]; } UnidirectionalRuleSet* Importer::getUnidirRuleSet( const std::string &ruleset_name, const string &ruleset_type_name) { UnidirectionalRuleSet *rs = all_rulesets[ruleset_name]; if (rs==NULL) { // got 'ip access-group' command before the access list was defined rs = new UnidirectionalRuleSet(); rs->name = ruleset_name; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); rs->ruleset = RuleSet::cast(dbroot->create(ruleset_type_name)); rs->ruleset->setName(ruleset_name); all_rulesets[ruleset_name] = rs; // add this ruleset to the firewall temporarily // because ruleset must belong to the tree somewhere in // order for other objects to be added properly. getFirewallObject()->add(rs->ruleset); } return rs; } void Importer::setInterfaceAndDirectionForRuleSet( Interface *intf, const std::string &ruleset_name, const std::string &dir) { UnidirectionalRuleSet *rs = getUnidirRuleSet(ruleset_name, Policy::TYPENAME); string intf_name = intf->getName(); if (rs->intf_dir.count(intf_name)==0) rs->intf_dir[intf_name] = dir; else { // already have this interface with some direction // compare direction, if different, switcht to "both" if (rs->intf_dir[intf_name] != "both" && rs->intf_dir[intf_name] != dir) rs->intf_dir[intf_name] = "both"; } QString l("Interface %1 ruleset %2 direction '%3'"); addMessageToLog( l.arg(intf_name.c_str()).arg(ruleset_name.c_str()).arg(dir.c_str())); } /* * associate ruleset with interface * and direction * * if is empty, use current_interface * * Note that a ruleset may be associated with multiple interfaces * and each association can have different direction. */ void Importer::setInterfaceAndDirectionForRuleSet(const std::string &ruleset_name, const std::string &intf_name, const std::string &dir) { Interface *intf = NULL; if ( ! intf_name.empty()) { intf = all_interfaces[intf_name]; } else { if (current_interface) intf = current_interface; } if (intf == NULL) { // current_interface is NULL and _intf_name is empty. Not enough // information to associate ruleset with an interface. QString err("Can not associate rule set %1 with any interface\n"); addMessageToLog(err.arg(QString::fromUtf8(ruleset_name.c_str()))); } else setInterfaceAndDirectionForRuleSet(intf, ruleset_name, dir); } void Importer::newUnidirRuleSet(const string &ruleset_name, const string &ruleset_type) { current_ruleset = getUnidirRuleSet(ruleset_name, ruleset_type); // creates if new current_ruleset->created_from_line_number = getCurrentLineNumber(); //*logger << "Ruleset: " + ruleset_name + "\n"; } /* * Grammar must ensure the call to setDefaultAction() happens * after the call to newUnidirRuleSet() * */ void Importer::setDefaultAction(const std::string &iptables_action_name) { string default_action_str = "Deny"; if (iptables_action_name == "ACCEPT") { current_ruleset->default_action = PolicyRule::Accept; current_ruleset->default_action_line_number = getCurrentLineNumber(); default_action_str = "Accept"; } else current_ruleset->default_action = PolicyRule::Deny; addMessageToLog("Default action: " + default_action_str); } void Importer::newPolicyRule() { if (fwbdebug) qDebug() << "Importer::newPolicyRule()"; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); FWObject *nobj = dbroot->create(PolicyRule::TYPENAME); current_rule = Rule::cast(nobj); // check if all child objects were populated properly FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); ropt->setBool("stateless", true); } void Importer::newNATRule() { if (fwbdebug) qDebug() << "Importer::newNATRule()"; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); FWObject *nobj = dbroot->create(NATRule::TYPENAME); current_rule = Rule::cast(nobj); if (fwbdebug) qDebug() << "current_rule=" << current_rule; } void Importer::pushRule() { assert(current_ruleset!=NULL); assert(current_rule!=NULL); // populate all elements of the rule PolicyRule *rule = PolicyRule::cast(current_rule); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); if (action=="permit") { rule->setAction(PolicyRule::Accept); ropt->setBool("stateless", false); } if (action=="deny") { rule->setAction(PolicyRule::Deny); ropt->setBool("stateless", true); } rule->setDirection(PolicyRule::Both); addSrc(); addDst(); addSrv(); addLogging(); // then add it to the current ruleset current_ruleset->ruleset->add(current_rule); if (error_tracker->hasWarnings()) { QStringList warn = error_tracker->getWarnings(); // parser errors and warnings are added to the log by // PFCfgParser::reportError() and PFCfgParser::reportWarning() // so we dont need to add them again here foreach(QString w, warn) { if (!w.startsWith("Parser warning:")) addMessageToLog("Warning: " + w); } markCurrentRuleBad(); } if (error_tracker->hasErrors()) { QStringList err = error_tracker->getErrors(); foreach(QString e, err) { if (!e.startsWith("Parser error:")) addMessageToLog("Error: " + e); } markCurrentRuleBad(); } addStandardImportComment( current_rule, QString::fromUtf8(rule_comment.c_str())); current_rule = NULL; rule_comment = ""; clear(); } void Importer::setSrcSelf() { src_a = "self"; } void Importer::setDstSelf() { dst_a = "self"; } FWObject* Importer::makeAddressObj(const std::string addr, const std::string netm) { if (addr == "self") { return getFirewallObject(); } if ( (addr=="" && netm=="") || (addr==InetAddr::getAny().toString() && netm==InetAddr::getAny().toString())) return NULL; // this is 'any' ObjectSignature sig(error_tracker); sig.type_name = Address::TYPENAME; sig.setAddress(addr.c_str()); if (netm=="") sig.setNetmask(InetAddr::getAllOnes().toString().c_str(), address_maker->getInvertedNetmasks()); else sig.setNetmask(netm.c_str(), address_maker->getInvertedNetmasks()); return commitObject(address_maker->createObject(sig)); } FWObject* Importer::makeSrcObj() { return makeAddressObj(src_a, src_nm); } FWObject* Importer::makeDstObj() { return makeAddressObj(dst_a, dst_nm); } FWObject* Importer::makeSrvObj() { if (protocol=="") return NULL; // this is 'any' FWObject *s; if (protocol=="icmp") { ObjectSignature sig(error_tracker); sig.type_name = ICMPService::TYPENAME; if ( ! icmp_spec.empty()) { sig.setIcmpFromName(icmp_spec.c_str()); } else { sig.setIcmpType(icmp_type.c_str()); sig.setIcmpCode(icmp_code.c_str()); } s = service_maker->createObject(sig); } else { if (protocol=="tcp") { s = createTCPService(); } else { if (protocol=="udp") { s = createUDPService(); } else { ObjectSignature sig(error_tracker); sig.type_name = IPService::TYPENAME; sig.setProtocol(protocol.c_str()); sig.fragments = fragments; s = service_maker->createObject(sig); } } } // if create*Service returns NULL, this is 'any' return commitObject(s); } void Importer::addSrc() { PolicyRule *rule = PolicyRule::cast(current_rule); RuleElementSrc* src = rule->getSrc(); assert(src!=NULL); FWObject *s = makeSrcObj(); if (s) src->addRef( s ); } void Importer::addDst() { PolicyRule *rule = PolicyRule::cast(current_rule); RuleElementDst* dst = rule->getDst(); assert(dst!=NULL); FWObject *s = makeDstObj(); if (s) dst->addRef( s ); } void Importer::addSrv() { PolicyRule *rule = PolicyRule::cast(current_rule); RuleElementSrv* srv = rule->getSrv(); assert(srv!=NULL); FWObject *s = makeSrvObj(); if (s) srv->addRef( s ); } void Importer::addOSrc() { NATRule *rule = NATRule::cast(current_rule); RuleElementOSrc* src = rule->getOSrc(); assert(src!=NULL); FWObject *s = makeSrcObj(); if (s) src->addRef( s ); } void Importer::addODst() { NATRule *rule = NATRule::cast(current_rule); RuleElementODst* dst = rule->getODst(); assert(dst!=NULL); FWObject *s = makeDstObj(); if (s) dst->addRef( s ); } void Importer::addOSrv() { NATRule *rule = NATRule::cast(current_rule); RuleElementOSrv* srv = rule->getOSrv(); assert(srv!=NULL); FWObject *s= makeSrvObj(); if (s) srv->addRef( s ); } void Importer::addLogging() { PolicyRule *rule = PolicyRule::cast(current_rule); rule->setLogging(logging); // log_level // log_interval } Firewall* Importer::finalize() { return fw; } FWObject* Importer::createTCPService(const QString &) { // Default implementation return NULL; } FWObject* Importer::createUDPService(const QString &) { // Default implementation return NULL; } FWObject* Importer::createGroupOfInterfaces( const std::string &ruleset_name, std::list &interfaces) { std::string name = "intf-" + ruleset_name; // by including ruleset name (==acl name) into the signature we // force import to create separate interface group for each access list // even if interface set is the same as for some other access list. // This decision is rather arbitrary but it feels less confusing // compared to the case when interface groups cretaed from different // access lists are merged. If they are merged, the name refers to one // access list which looks weird in the GUI since rules may have been // imported from another access list. std::string sig = ruleset_name + "_"; std::for_each(interfaces.begin(), interfaces.end(), join(&sig, "_")); if (fwbdebug) qDebug() << QString("Interface group with name '%1', sig '%2'") .arg(name.c_str()).arg(sig.c_str()); if (all_objects.count(sig)!=0) return all_objects[sig]; ObjectMaker maker(Library::cast(library), error_tracker); ObjectGroup *og = ObjectGroup::cast( commitObject( maker.createObject(ObjectGroup::TYPENAME, name))); for (std::list::iterator j=interfaces.begin(); j!=interfaces.end(); ++j) { Interface *intf = all_interfaces[*j]; og->addRef(intf); } all_objects[sig] = og; return og; } /** * set color of the current rule (use red) and add comment * to indicate that the rule could not be properly parsed */ void Importer::markCurrentRuleBad() { FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); ropt->setStr("color", getBadRuleColor()); QStringList comment; if ( ! current_rule->getComment().empty()) comment.append(QString::fromUtf8(current_rule->getComment().c_str())); foreach(QString err, error_tracker->getWarnings()) comment.append(err); foreach(QString err, error_tracker->getErrors()) comment.append(err); current_rule->setComment(comment.join("\n").toUtf8().constData()); } void Importer::reportError(const std::string &comment) { reportError(QString::fromUtf8(comment.c_str())); } void Importer::reportError(const QString &comment) { error_counter++; QString err = QObject::tr("Error: %1").arg(comment); addMessageToLog(err); error_tracker->registerError(err); } int Importer::countRules() { int n = 0; std::map::iterator it; for (it=all_rulesets.begin(); it!=all_rulesets.end(); ++it) { // rs_index is a string composed of the table name and chain name // like "filter / FORWARD" or "mangle / PREROUTING" // This string is created in IPTImporter::getUnidirRuleSet() string rs_index = it->first; UnidirectionalRuleSet* rs = it->second; if (rs->ruleset) n += rs->ruleset->getRuleSetSize(); } return n; } int Importer::countInterfaces() { if (haveFirewallObject()) { Firewall *fw = Firewall::cast(getFirewallObject()); list all_interface_objects = fw->getByType(Interface::TYPENAME); return all_interface_objects.size(); } else return 0; } QString Importer::noFirewallErrorMessage() { return QObject::tr( "Could not find enough information in the data file " "to create firewall object." "\n\n" ); } QString Importer::noRulesErrorMessage() { return QObject::tr( "Could not find enough information in the data file " "to create any firewall rules." "\n\n" ); } QString Importer::noInterfacesErrorMessage() { return QObject::tr( "Could not find enough information in the data file " "to create firewall interface objects." "\n\n" ); } /* * This is a common error message shown by the importer when it fails * to create firewall object. Keeping it in the base class since it is * used in the finalize() function of all importer classes. */ QString Importer::commonFailureErrorMessage() { return QObject::tr( "Please check that the " "file you are trying to import is in one of supported " "formats. Currently fwbuilder can only import " "iptables configuration saved with " "'iptables-restore' command, Cisco routers (IOS), " "Cisco ASA, FWSM and PIX configurations saved with " "'show run' command and PF configuration from a pf.conf file." ); } void Importer::addMessageToLog(const std::string &msg) { addMessageToLog(QString::fromUtf8(msg.c_str())); } void Importer::addMessageToLog(const QString &msg) { if (getCurrentLineNumber() >= 0) { QString log_line("%1: %2\n"); *logger << log_line.arg(getCurrentLineNumber()).arg(msg).toUtf8().constData(); } else { *logger << msg.toUtf8().constData(); } } /** * This function adds "standard" comment to the object, plus text * passed as @additional_comment argument. If the object already has * some comment, it is preserved and new text is appended to it. If * flag add_standard_comments is false, then comment referring to the * line number in the original file is not added, but * @additional_comment is added anyway. Note that we also add comments * to rules in case of errors but those are not suppressed by the flag * add_standard_comments */ void Importer::addStandardImportComment(FWObject *obj, const QString &additional_comment) { if (obj == NULL) return; // what if this object has been found in a read-only library? if (obj->isReadOnly()) return; // this function may get called again if object is being reused if ( obj->getBool(".import-commited")) return; QStringList comment; if ( ! obj->getComment().empty()) comment << QString::fromUtf8(obj->getComment().c_str()); if ( ! additional_comment.isEmpty()) comment << additional_comment; if (add_standard_comments) { QString file_and_line("Created during import of %1 line %2"); comment << file_and_line .arg(QString::fromUtf8(input_file_name.c_str())) .arg(getCurrentLineNumber()); } obj->setComment(comment.join("\n").toUtf8().constData()); obj->setBool(".import-commited", true); } FWObject* Importer::commitObject(FWObject *obj) { // what if this object has been found in a read-only library? if (obj->isReadOnly()) return obj; if (obj) addStandardImportComment(obj, ""); return obj; } /* * Rearrange vlan interfaces. Importer creates all interfaces as * children of the firewall. Vlan interfaces should become * subinterfaces of the corresponding physical interfaces. */ void Importer::rearrangeVlanInterfaces() { std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( getFirewallObject())); list all_interface_objects = getFirewallObject()->getByTypeDeep(Interface::TYPENAME); list vlans; list::iterator it; for (it=all_interface_objects.begin(); it!=all_interface_objects.end(); ++it) { Interface *intf = Interface::cast(*it); FWOptions *ifopt = intf->getOptionsObject(); if (int_prop->looksLikeVlanInterface(intf->getName().c_str()) && ifopt->getStr("type")=="8021q") { qDebug() << "Found vlan interface" << intf->getName().c_str(); vlans.push_back(intf); } } for (it=vlans.begin(); it!=vlans.end(); ++it) { Interface *vlan_intf = Interface::cast(*it); qDebug() << "VLAN " << vlan_intf->getName().c_str(); QString base_name; int vlan_id; int_prop->parseVlan(vlan_intf->getName().c_str(), &base_name, &vlan_id); qDebug() << "base name" << base_name; if ( ! base_name.isEmpty()) { getFirewallObject()->remove(vlan_intf, false); // do not delete list::iterator it2; for (it2=all_interface_objects.begin(); it2!=all_interface_objects.end(); ++it2) { if (base_name == (*it2)->getName().c_str()) { (*it2)->add(vlan_intf, false); break; } } } } } void Importer::registerBrokenObject(FWObject *obj, const QString &err) { broken_objects[obj] = err; } bool Importer::isObjectBroken(FWObject *obj) { return broken_objects.count(obj) != 0; } QString Importer::getBrokenObjectError(FWObject *obj) { return broken_objects[obj]; } fwbuilder-5.1.0.3599/src/import/IOSImporter.cpp0000644000175000017500000003457411733011756021774 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" // #include "global.h" // #include "utils_no_qt.h" // #include "platforms.h" #include "IOSImporter.h" #include "getProtoByName.h" #include "getServByName.h" #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Library.h" #include #include extern int fwbdebug; using namespace std; using namespace libfwbuilder; IOSImporter::IOSImporter(FWObject *lib, std::istringstream &input, Logger *log, const std::string &fwname) : Importer(lib, "iosacl", input, log, fwname) { address_maker->setInvertedNetmasks(true); } IOSImporter::~IOSImporter() { all_rulesets.clear(); all_interfaces.clear(); } void IOSImporter::setInterfaceAndDirectionForRuleSet( const std::string &ruleset_name, const std::string &_intf_name, const std::string &_dir) { Importer::setInterfaceAndDirectionForRuleSet( ruleset_name, _intf_name, _dir); } ObjectSignature IOSImporter::packObjectSignatureTCPService() { // use src_port_op, src_port_spec, dst_port_op, dst_port_spec // port_op can be: lt (less than), gt (greater than), eq (equal), // neq (not equal), and range (inclusive range). ObjectSignature sig(error_tracker); sig.type_name = TCPService::TYPENAME; sig.port_range_inclusive = false; sig.setSrcPortRangeFromPortOpForCisco( src_port_op.c_str(), src_port_spec.c_str(), protocol.c_str()); sig.setDstPortRangeFromPortOpForCisco( dst_port_op.c_str(), dst_port_spec.c_str(), protocol.c_str()); sig.established = established; sig.flags_mask = tcp_flags_mask; sig.flags_comp = tcp_flags_comp; return sig; } ObjectSignature IOSImporter::packObjectSignatureUDPService() { // use src_port_op, src_port_spec, dst_port_op, dst_port_spec // port_op can be: lt (less than), gt (greater than), eq (equal), // neq (not equal), and range (inclusive range). ObjectSignature sig(error_tracker); sig.type_name = UDPService::TYPENAME; sig.port_range_inclusive = false; sig.setSrcPortRangeFromPortOpForCisco( src_port_op.c_str(), src_port_spec.c_str(), protocol.c_str()); sig.setDstPortRangeFromPortOpForCisco( dst_port_op.c_str(), dst_port_spec.c_str(), protocol.c_str()); return sig; } FWObject* IOSImporter::createTCPService(const QString &name) { if (src_port_op == "neq" || dst_port_op == "neq") return createTCPUDPNeqObject("tcp", name); ObjectSignature sig = packObjectSignatureTCPService(); if( ! name.isEmpty()) sig.object_name = name; return commitObject(service_maker->createObject(sig)); } FWObject* IOSImporter::createUDPService(const QString &name) { if (src_port_op == "neq" || dst_port_op == "neq") return createTCPUDPNeqObject("udp", name); ObjectSignature sig = packObjectSignatureUDPService(); if ( ! name.isEmpty()) sig.object_name = name; return commitObject(service_maker->createObject(sig)); } FWObject* IOSImporter::createTCPUDPServicePair(const QString &name) { FWObject *srv1 = createTCPService((name.isEmpty()) ? "" : name + "-tcp"); FWObject *srv2 = createUDPService((name.isEmpty()) ? "" : name + "-udp"); QString group_name = name; if (name.isEmpty()) { group_name = QString(srv1->getName().c_str()).replace("tcp ","tcp-udp "); } ObjectMaker maker(Library::cast(library), error_tracker); FWObject *grp = commitObject( maker.createObject(ServiceGroup::TYPENAME, group_name.toStdString())); grp->addRef(srv1); grp->addRef(srv2); return grp; } /* * create two tcp service objects to cover port ranges before * and after src_port_spec, put them into service group and * return pointer to the group. We ignore tcp ports and * "established" flag in combination with "neq" * */ FWObject* IOSImporter::createTCPUDPNeqObject(const QString &proto, const QString &name) { ObjectSignature sig(error_tracker); sig.port_range_inclusive = false; if (proto == "tcp") sig.type_name = TCPService::TYPENAME; if (proto == "udp") sig.type_name = UDPService::TYPENAME; if ( ! name.isEmpty()) sig.object_name = name; QString group_name; FWObject *srv1 = NULL; FWObject *srv2 = NULL; if (src_port_op == "neq") { if ( ! dst_port_spec.empty()) group_name = QString("%1 src neq %2 / dst %3") .arg(proto).arg(src_port_spec.c_str()).arg(dst_port_spec.c_str()); else group_name = QString("%1 src neq %2").arg(proto).arg(src_port_spec.c_str()); sig.setDstPortRangeFromPortOpForCisco( dst_port_op.c_str(), dst_port_spec.c_str(), proto); sig.setSrcPortRangeFromPortOpForCisco("lt", src_port_spec.c_str(), proto); srv1 = service_maker->createObject(sig); sig.setSrcPortRangeFromPortOpForCisco("gt", src_port_spec.c_str(), proto); srv2 = service_maker->createObject(sig); } if (dst_port_op == "neq") { if ( ! src_port_spec.empty()) group_name = QString("%1 src %2 / dst neq %3") .arg(proto).arg(src_port_spec.c_str()).arg(dst_port_spec.c_str()); else group_name = QString("%1 dst neq %2").arg(proto).arg(dst_port_spec.c_str()); sig.setSrcPortRangeFromPortOpForCisco( src_port_op.c_str(), src_port_spec.c_str(), proto); sig.setDstPortRangeFromPortOpForCisco("lt", dst_port_spec.c_str(), proto); srv1 = service_maker->createObject(sig); sig.setDstPortRangeFromPortOpForCisco("gt", dst_port_spec.c_str(), proto); srv2 = service_maker->createObject(sig); } assert(srv1 != NULL && srv2 != NULL); ObjectMaker maker(Library::cast(library), error_tracker); FWObject *grp = commitObject( maker.createObject(ServiceGroup::TYPENAME, group_name.toStdString())); grp->addRef(commitObject(srv1)); grp->addRef(commitObject(srv2)); return grp; } void IOSImporter::ignoreCurrentInterface() { if (current_interface) { QString err("Warning: interface %1 was not imported because it " "is in \"shutdown\" mode\n"); *Importer::logger << err.arg(current_interface->getName().c_str()).toStdString(); Importer::ignoreCurrentInterface(); // this clears current_interface } } void IOSImporter::pushRule() { assert(current_ruleset!=NULL); assert(current_rule!=NULL); // populate all elements of the rule addMessageToLog( QString("access list rule: access list %1, action %2") .arg(QString::fromUtf8(current_ruleset->ruleset->getName().c_str())) .arg(action.c_str())); Importer::pushRule(); } void IOSImporter::MergeRules::move(FWObject* r) { PolicyRule *rule = PolicyRule::cast(r); // Note that Policy object can have children that are objects of // classes PolicyRule and RuleSetOptions. If r does not cast to // PolicyRule, then it must be RuleSetOptions and we should just // skip it. if (rule==NULL) { r->getParent()->remove(r); return; } target_ruleset->reparent(rule); if (intf) { RuleElementItf* re =rule->getItf(); assert(re); re->addRef(intf); } rule->setDirection(dir); std::string prev_comment = rule->getComment(); rule->setComment( std::string("Imported from ") + ruleset_name + "\n" + prev_comment); } Firewall* IOSImporter::finalize() { // scan all UnidirectionalRuleSet objects, set interface and // direction in all rules of corresponding RuleSet and merge all // UnidirectionalRuleSet into one RuleSet object. Attach this // object to the firewall. if (fwbdebug) qDebug("IOSImporter::finalize()"); if (haveFirewallObject()) { Firewall *fw = Firewall::cast(getFirewallObject()); fw->setStr("host_OS", "ios"); Resources::setDefaultTargetOptions("ios" , fw); fw->setStr("version", ""); // default version "any" fw->getManagementObject(); // creates management obj FWObject *policy = getFirewallObject()->getFirstByType(Policy::TYPENAME); assert( policy!=NULL ); if (all_rulesets.size()!=0) { if (fwbdebug) { qDebug() << "Setting interface and direction for all rules"; qDebug() << "all_rulesets.size()=" << all_rulesets.size(); } std::map::iterator i; for (i=all_rulesets.begin(); i!=all_rulesets.end(); ++i) { UnidirectionalRuleSet *irs = (*i).second; if (fwbdebug) { qDebug() << " irs->name=" << irs->name.c_str(); qDebug() << " irs->intf_dir.size()=" << irs->intf_dir.size(); qDebug() << " irs->ruleset->size()=" << irs->ruleset->size(); } // optimization: If we have several interfaces for // the ruleset, create a group // But first group interfaces by direction so // that later we can merge rules into the policy // with proper combination of interface group and // direction. Remember that the same access list // can be used with multiple interfaces with different // directions each time. The same list can be applied // to the same interface both in and out (although in // this case we have already switched direction to "both") // if (irs->intf_dir.size()>1) { std::list all_in; std::list all_out; std::list all_both; std::map::iterator i; for (i = irs->intf_dir.begin(); i != irs->intf_dir.end(); ++i) { if ( (*i).second=="in") all_in.push_back( (*i).first ); if ( (*i).second=="out") all_out.push_back( (*i).first ); if ( (*i).second=="both") all_both.push_back( (*i).first ); } FWObject *og; if (all_in.size()>0) { og = createGroupOfInterfaces(irs->name, all_in); MergeRules mr(irs->name, og, PolicyRule::Inbound, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } if (all_out.size()>0) { og = createGroupOfInterfaces(irs->name, all_out); MergeRules mr(irs->name, og, PolicyRule::Outbound, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } if (all_both.size()>0) { og = createGroupOfInterfaces(irs->name, all_both); MergeRules mr(irs->name, og, PolicyRule::Both, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } } else { std::map::iterator j; for (j=irs->intf_dir.begin(); j!=irs->intf_dir.end(); ++j) { Interface *intf = all_interfaces[ (*j).first ]; std::string _dir = (*j).second; PolicyRule::Direction direction = PolicyRule::Both; if (_dir=="in") direction = PolicyRule::Inbound; if (_dir=="out") direction = PolicyRule::Outbound; // not all access lists are associated with interfaces if (intf!=NULL) { if (fwbdebug) qDebug() << " interface=" << intf->getName().c_str(); MergeRules mr(irs->name, intf, direction, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } } } // qDebug("ruleset done"); // call clearChidren() not recursive because children objects // of all rules should not be deleted irs->ruleset->clearChildren(false); getFirewallObject()->remove(irs->ruleset, false); delete irs->ruleset; } } list l2 = fw->getByType(Policy::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { RuleSet *rs = RuleSet::cast(*i); rs->renumberRules(); } return getFirewallObject(); } else { return NULL; } } fwbuilder-5.1.0.3599/src/import/addressObjectMaker.cpp0000644000175000017500000001417711733011756023351 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "addressObjectMaker.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "QStringListOperators.h" #include #include extern int fwbdebug; using namespace libfwbuilder; using namespace std; AddressObjectMaker::~AddressObjectMaker() {} FWObject* AddressObjectMaker::createObject(ObjectSignature &sig) { FWObject *obj = NULL; if (sig.type_name == AddressRange::TYPENAME) obj = createAddressRange(sig); if (sig.type_name == AddressTable::TYPENAME) obj = createAddressTable(sig); if (sig.type_name == DNSName::TYPENAME) obj = createDNSName(sig); if (obj == NULL) obj = createAddress(sig); // Now I should build new signature because actual object type has // only been determined in createAddress() ObjectSignature new_sig(error_tracker); if ( ! sig.object_name.isEmpty()) { obj->setName(sig.object_name.toUtf8().constData()); obj->dispatch(&new_sig, (void*)(NULL)); registerNamedObject(new_sig, obj); } else { obj->dispatch(&new_sig, (void*)(NULL)); registerAnonymousObject(new_sig, obj); } return obj; } FWObject* AddressObjectMaker::createAddress(ObjectSignature &sig) { ObjectSignature signature = sig; InetAddr netmask(signature.netmask.toStdString()); if ( netmask == InetAddr::getAllOnes() ) { QString name; try { signature.type_name = IPv4::TYPENAME; FWObject *obj = findMatchingObject(signature); if (obj) return obj; InetAddr obj_addr(sig.address.toStdString()); // testing if string converts to an address name = QString("h-") + sig.address; Address *a = Address::cast( ObjectMaker::createObject(IPv4::TYPENAME, name.toStdString())); a->setAddress(obj_addr); a->setNetmask(InetAddr(InetAddr::getAllOnes())); return a; } catch(FWException &ex) { // address text line can not be converted to ipv4 address. // Since parsers do not understand ipv6 yet, assume this // is a host address and create DNSName object signature.type_name = DNSName::TYPENAME; FWObject *obj = findMatchingObject(signature); if (obj) return obj; name = sig.address; DNSName *da = DNSName::cast( ObjectMaker::createObject(DNSName::TYPENAME, name.toStdString())); da->setSourceName(sig.address.toStdString()); da->setRunTime(true); return da; } } else { signature.type_name = Network::TYPENAME; FWObject *obj = findMatchingObject(signature); if (obj) return obj; QString name = QString("net-%1/%2") .arg(signature.address).arg(signature.netmask); Network *net = Network::cast( ObjectMaker::createObject(Network::TYPENAME, name.toStdString())); try { net->setAddress( InetAddr(sig.address.toStdString()) ); } catch (FWException &ex) { error_tracker->registerError( QString("Error converting address '%1'").arg(sig.address)); } // we have already verified netmask above net->setNetmask(netmask); return net; } return NULL; } FWObject* AddressObjectMaker::createAddressRange(ObjectSignature &sig) { FWObject *obj = findMatchingObject(sig); if (obj) return obj; QString addr1 = sig.address_range_start; QString addr2 = sig.address_range_end; QString name = QString("range-%1-%2").arg(addr1).arg(addr2); AddressRange *ar = AddressRange::cast( ObjectMaker::createObject(AddressRange::TYPENAME, name.toStdString())); try { ar->setRangeStart( InetAddr(addr1.toStdString()) ); } catch (FWException &ex) { error_tracker->registerError( QString("Error converting address '%1'").arg(addr1)); } try { ar->setRangeEnd( InetAddr(addr2.toStdString()) ); } catch (FWException &ex) { error_tracker->registerError( QString("Error converting address '%1'").arg(addr2)); } return ar; } FWObject* AddressObjectMaker::createAddressTable(ObjectSignature &sig) { FWObject *obj = findMatchingObject(sig); if (obj) return obj; AddressTable *at = AddressTable::cast( ObjectMaker::createObject(AddressTable::TYPENAME, sig.object_name.toUtf8().constData())); assert(at!=NULL); at->setRunTime(true); at->setSourceName(sig.address_table_name.toStdString()); return at; } FWObject* AddressObjectMaker::createDNSName(ObjectSignature &sig) { FWObject *obj = findMatchingObject(sig); if (obj) return obj; DNSName *dns_obj = DNSName::cast( ObjectMaker::createObject(DNSName::TYPENAME, sig.object_name.toUtf8().constData())); assert(dns_obj!=NULL); dns_obj->setRunTime(true); dns_obj->setSourceName(sig.dns_name.toStdString()); return dns_obj; } fwbuilder-5.1.0.3599/src/import/serviceObjectMaker.cpp0000644000175000017500000002326111733011756023356 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "serviceObjectMaker.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Library.h" #include "fwbuilder/ObjectMirror.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" // TODO: FWBTree needs to be refactored into an independent module #include "../libgui/FWBTree.h" #include "QStringListOperators.h" #include #include extern int fwbdebug; using namespace libfwbuilder; using namespace std; ServiceObjectMaker::ServiceObjectMaker(Library *l, ObjectMakerErrorTracker *et) : ObjectMaker(l, et) { custom_service_code_tracker = 0; tcp_flag_names[libfwbuilder::TCPService::URG] = "u"; tcp_flag_names[libfwbuilder::TCPService::ACK] = "a"; tcp_flag_names[libfwbuilder::TCPService::PSH] = "p"; tcp_flag_names[libfwbuilder::TCPService::RST] = "r"; tcp_flag_names[libfwbuilder::TCPService::SYN] = "s"; tcp_flag_names[libfwbuilder::TCPService::FIN] = "f"; tcp_flag_names[98]="N"; // NONE tcp_flag_names[99]="A"; // ALL // some "built-in" objects ObjectSignature sig(error_tracker); sig.type_name = IPService::TYPENAME; sig.protocol = 0; sig.fragments = false; registerAnonymousObject(sig, NULL); // "any" } ServiceObjectMaker::~ServiceObjectMaker() {} void ServiceObjectMaker::clear() { ObjectMaker::clear(); } FWObject* ServiceObjectMaker::createObject(ObjectSignature &sig) { assert( ! sig.type_name.isEmpty()); FWObject *obj = findMatchingObject(sig); // qDebug() << "Create object " << sig.toString() << " obj=" << obj; if (obj) return obj; if (sig.type_name == CustomService::TYPENAME) obj = getCustomService(sig.platform, sig.code, sig.protocol_name); if (sig.type_name == IPService::TYPENAME) { QString name; if (sig.protocol > 0) name = QString("ip-%1").arg(sig.protocol); else name = "ip"; if (sig.fragments) name += "-fragm"; obj = ObjectMaker::createObject(IPService::TYPENAME, name.toStdString()); obj->setInt("protocol_num", sig.protocol); obj->setBool("fragm", sig.fragments); obj->setBool("short_fragm", sig.short_fragments); obj->setBool("any_opt", sig.any_opt); obj->setStr("dscp", sig.dscp.toStdString()); obj->setStr("tos", sig.tos.toStdString()); obj->setBool("lsrr", sig.lsrr); obj->setBool("ssrr", sig.ssrr); obj->setBool("rr", sig.rr); obj->setBool("ts", sig.ts); obj->setBool("rtralt", sig.rtralt); obj->setBool("rtralt_value", sig.rtralt_value); } if (sig.type_name == ICMPService::TYPENAME) { QString name = QString("icmp %1/%2").arg(sig.icmp_type).arg(sig.icmp_code); obj = ObjectMaker::createObject(ICMPService::TYPENAME, name.toStdString()); obj->setInt("type", sig.icmp_type); obj->setInt("code", sig.icmp_code); } if (sig.type_name == TCPService::TYPENAME) obj = getTCPService(sig.src_port_range_start, sig.src_port_range_end, sig.dst_port_range_start, sig.dst_port_range_end, sig.established, sig.flags_mask, sig.flags_comp); if (sig.type_name == UDPService::TYPENAME) obj = getUDPService(sig.src_port_range_start, sig.src_port_range_end, sig.dst_port_range_start, sig.dst_port_range_end); if (sig.type_name == TagService::TYPENAME) obj = getTagService(sig.tag); if ( ! sig.object_name.isEmpty()) { obj->setName(sig.object_name.toUtf8().constData()); registerNamedObject(sig, obj); } else registerAnonymousObject(sig, obj); return obj; } FWObject* ServiceObjectMaker::getCustomService(const QString &platform, const QString &code, const QString &protocol) { QString custom_service_name_sig = platform + "-" + code; if (custom_service_codes.count(custom_service_name_sig) > 0) custom_service_code_tracker++; QStringList name; name << "cust-" << custom_service_code_tracker; if ( ! protocol.isEmpty()) name << "-" << protocol; CustomService *s = CustomService::cast( ObjectMaker::createObject(CustomService::TYPENAME, name.join("").toStdString())); if (!protocol.isEmpty()) s->setProtocol(protocol.toStdString()); s->setCodeForPlatform(platform.toStdString(), code.toStdString()); return s; } FWObject* ServiceObjectMaker::getTCPService(int srs, int sre, int drs, int dre, bool established, QList &flags_mask, QList &flags_comp) { QStringList nl; nl << QString("tcp %1:%2 / %3:%4").arg(srs).arg(sre).arg(drs).arg(dre); if (established) nl << "est"; if (!flags_mask.isEmpty() || !flags_comp.isEmpty()) { QStringList f; foreach(int x, flags_comp) f << tcp_flag_names[x]; f << "/"; foreach(int x, flags_mask) f << tcp_flag_names[x]; nl << f.join(""); } TCPService* s = TCPService::cast( ObjectMaker::createObject(TCPService::TYPENAME, nl.join(" ").toStdString())); s->setSrcRangeStart(srs); s->setSrcRangeEnd(sre); s->setDstRangeStart(drs); s->setDstRangeEnd(dre); if (!flags_mask.isEmpty() || !flags_comp.isEmpty()) { // TCP flags foreach(int x, flags_mask) { switch (x) { case 99: // ALL s->setAllTCPFlagMasks(); break; case 98: // NONE s->clearAllTCPFlagMasks(); break; default: s->setTCPFlagMask( TCPService::TCPFlag(x), true); } } foreach(int x, flags_comp) { switch (x) { case 99: // ALL s->setTCPFlag( TCPService::URG, true); s->setTCPFlag( TCPService::ACK, true); s->setTCPFlag( TCPService::PSH, true); s->setTCPFlag( TCPService::RST, true); s->setTCPFlag( TCPService::SYN, true); s->setTCPFlag( TCPService::FIN, true); break; case 98: // NONE s->clearAllTCPFlags(); break; default: s->setTCPFlag( TCPService::TCPFlag(x), true); } } } s->setEstablished(established); return s; } FWObject* ServiceObjectMaker::getUDPService(int srs, int sre, int drs, int dre) { QString name = QString("udp %1:%2 / %3:%4") .arg(srs).arg(sre).arg(drs).arg(dre); UDPService* s = UDPService::cast( ObjectMaker::createObject(UDPService::TYPENAME, name.toStdString())); s->setSrcRangeStart(srs); s->setSrcRangeEnd(sre); s->setDstRangeStart(drs); s->setDstRangeEnd(dre); return s; } FWObject* ServiceObjectMaker::getTagService(const QString &tagcode) { TagService *s = NULL; QString name = QString("tag-%1").arg(tagcode); s = TagService::cast( ObjectMaker::createObject(TagService::TYPENAME, name.toStdString())); assert(s!=NULL); s->setCode(tagcode.toStdString()); return s; } FWObject* ServiceObjectMaker::getMirroredServiceObject(FWObject *obj) { string new_name = obj->getName() + "-mirror"; QString qs_new_name = QString::fromUtf8(new_name.c_str()); FWObject *new_obj = NULL; if (TCPService::isA(obj) || UDPService::isA(obj)) { ObjectMirror mirror; new_obj = mirror.getMirroredService(Service::cast(obj)); if (new_obj!=NULL) { if (TCPService::isA(new_obj)) TCPService::cast(new_obj)->setEstablished(false); ObjectSignature sig(error_tracker); new_obj->dispatch(&sig, (void*)(NULL)); sig.object_name = ""; FWObject *matching_obj = findMatchingObject(sig); if (matching_obj) { delete new_obj; return matching_obj; } registerAnonymousObject(sig, new_obj); new_obj->setName(new_name); // obj may belong to the standard objects library if it was // deduplicated before FWObject *parent = obj->getParent(); if (parent->isReadOnly()) { FWBTree tree ; FWObject *slot = tree.getStandardSlotForObject( library, new_obj->getTypeName().c_str()); slot->add(new_obj); } else parent->add(new_obj); } } return new_obj; } fwbuilder-5.1.0.3599/src/import/PIXImporter.h0000644000175000017500000001373011733011756021436 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FWB_POLICY_IMPORTER_PIX_H_ #define _FWB_POLICY_IMPORTER_PIX_H_ #include #include #include #include #include #include "IOSImporter.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Logger.h" #include "fwbuilder/Rule.h" #include "fwbuilder/NAT.h" #include class GlobalPool { public: int num; std::string str_num; std::string pool_interface; std::string start; std::string end; std::string netmask; GlobalPool() { num = -1; str_num = ""; pool_interface = ""; start = ""; end = ""; netmask = ""; } GlobalPool& operator=(const GlobalPool &other); std::string toStdString(); QString toString(); }; class PIXImporter : public IOSImporter { libfwbuilder::FWObject* getMirroredServiceObject(libfwbuilder::FWObject *obj); libfwbuilder::FWObject* mirrorServiceObjectRecursively(libfwbuilder::FWObject *obj); void mixServiceObjects(libfwbuilder::FWObject *src_ports, libfwbuilder::FWObject *dst_ports, libfwbuilder::FWObject *service_group); void natRuleWithACL(libfwbuilder::NATRule *rule); public: QString named_object_name; QString named_object_comment; libfwbuilder::FWObject *current_named_object; QString object_group_name; QString object_group_comment; QString object_group_service_protocol; libfwbuilder::FWObject *current_object_group; QMap named_objects_registry; // variables for the nat rules libfwbuilder::NATRule::NATRuleTypes rule_type; std::string prenat_interface; std::string postnat_interface; std::string real_a; std::string real_nm; std::string mapped_a; std::string mapped_nm; std::string real_addr_acl; std::string mapped_port_spec; std::string real_port_spec; std::string static_max_conn; std::string static_max_emb_conn; std::string nat_num; std::string nat_a; std::string nat_nm; std::string nat_acl; GlobalPool tmp_global_pool; std::map > global_pools; PIXImporter(libfwbuilder::FWObject *lib, std::istringstream &input, libfwbuilder::Logger *log, const std::string &fwname); ~PIXImporter(); virtual void clear(); void clearTempVars(); void addGlobalPool(); virtual void run(); void pushPolicyRule(); void pushNATRule(); void buildDNATRule(); void buildSNATRule(); void buildNoNATRule(); virtual void pushRule(); // this method actually adds interfaces to the firewall object // and does final clean up. virtual libfwbuilder::Firewall* finalize(); virtual libfwbuilder::FWObject* makeSrcObj(); virtual libfwbuilder::FWObject* makeDstObj(); virtual libfwbuilder::FWObject* makeSrvObj(); virtual void addLogging(); void fixServiceObjectUsedForSrcPorts(); void fixServiceObjectUsedForBothSrcAndDstPorts(); /* * the difference is that in PIX, we get interface label instead * of its name in "access-group" command */ virtual void setInterfaceAndDirectionForRuleSet( const std::string &ruleset_name, const std::string &interface_name, const std::string &dir); virtual void newNamedObjectAddress(const std::string &name); virtual void newNamedObjectService(const std::string &name); /* * it looks like "description" line is always the last in the * named object block output of "show run" command on ASA, however * "description" is optional and we create the object when we see * "subnet", "host" or "service" line. This function adds * description to existing named object. */ virtual void setNamedObjectDescription(const std::string &txt); virtual void commitNamedAddressObject(); virtual void commitNamedAddressRangeObject(); virtual void commitNamedIPServiceObject(); virtual void commitNamedICMPServiceObject(); virtual void commitNamedTCPUDPServiceObject(); virtual libfwbuilder::FWObject* commitObject(libfwbuilder::FWObject *obj); virtual libfwbuilder::FWObject* setNameOfNamedObject( libfwbuilder::FWObject *obj); void newObjectGroupNetwork(const std::string &group_name); void newObjectGroupService(const std::string &group_name); void newObjectGroupProtocol(const std::string &group_name); void newObjectGroupICMP(const std::string &group_name); bool isKnownServiceGroupName(const std::string &object_group_name); void setObjectGroupServiceProtocol(const std::string &proto) { object_group_service_protocol = proto.c_str(); } void setObjectGroupDescription(const std::string &descr); void addNamedObjectToObjectGroup(const std::string &object_name); void addNetworkToObjectGroup(); void addIPServiceToObjectGroup(); void addTCPUDPServiceToObjectGroup(); void addICMPServiceToObjectGroup(); libfwbuilder::Interface* getInterfaceByLabel(const std::string &label); void rearrangeVlanInterfaces(); }; #endif fwbuilder-5.1.0.3599/src/import/IPTImporterRun.cpp0000644000175000017500000001303011733011756022443 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "IPTImporter.h" #include #include #include #include #include #include #include #include // parser and lexer for files produced by iptables-save #include "../parsers/IPTCfgLexer.hpp" #include "../parsers/IPTCfgParser.hpp" extern int fwbdebug; using namespace std; /* * Only this module depends on IPTCfgLexer and IPTCfgParser, * so only this file is recompiled when we change grammar */ void IPTImporter::run() { // it is probably safer to create an empty firewall if we do not have // ANTLR on the system rather than try to #ifdef out chunks of code // here and there in this module // // Obviously we should disable GUI elements that activate this importer // if ANTLR runtime is not available. // QStringList err; ostringstream parser_debug; /* Do a bit of preprocessing of the input to simplify crazy grammar. String * operations are easier to do with Qt QString class. * * Do the following (will add more stuff here in the future): * * - normalize parameters for the multiport module. Multiport accepts * parameters --source-ports and --sport and aparently in the older versions * --sports. Unfortunayely the same parameter "--sport" is used * to do port match with module tcp, udp and several others. Even though the * name of the parameter is the same, port specification can follow different * rules. For example, for multiport we can have port1[,port2], while for * modules tcp and udp it is port1[:port2]. This makes grammar difficult * to write. Need to convert parameters to the unique long form before * passing script to antlr */ input.seekg (0, ios::end); size_t input_size = input.tellg(); string normalized_input_buffer; normalized_input_buffer.reserve(input_size); QRegExp old_negation_short("(-[^- ])\\s!"); QRegExp old_negation_long("(--[^- ]+)\\s!"); input.seekg (0, ios::beg); char buf[8192]; while (!input.eof()) { input.getline(buf, sizeof(buf)-1); QString str(buf); if (str.contains("-m multiport")) { str.replace("--sports", "--source-ports"); str.replace("--sport", "--source-ports"); str.replace("--dports", "--destination-ports"); str.replace("--dport", "--destination-ports"); } // negation: "-s ! something" format is deprecated and is replaced with // "! -s something", but our parser understands only old format. int pos = 0; while (true) { QString option; int match_length = 0; int old_pos = 0; old_pos = old_negation_short.indexIn(str, pos); if (old_pos != -1) { option = old_negation_short.cap(1); match_length = old_negation_short.matchedLength(); } else { old_pos = old_negation_long.indexIn(str, pos); if (old_pos != -1) { option = old_negation_long.cap(1); match_length = old_negation_long.matchedLength(); } } if (old_pos == -1) break; QString new_format = QString("! %1").arg(option); str.replace(old_pos, match_length, new_format); pos = old_pos + match_length; } normalized_input_buffer.append(str.toStdString()); normalized_input_buffer.append("\n"); } assert(normalized_input_buffer.length() > 0); istringstream normalized_input(normalized_input_buffer); IPTCfgLexer lexer(normalized_input); IPTCfgParser parser(lexer); parser.importer = this; if (fwbdebug) parser.dbg = &std::cerr; else parser.dbg = &parser_debug; QString parser_err = QObject::tr("Parser error:"); QString gen_err = QObject::tr("Error:"); try { parser.cfgfile(); } catch(ANTLR_USE_NAMESPACE(antlr)ANTLRException &e) { err << parser_err + " " + e.toString().c_str(); } catch(ObjectMakerException &e) { err << gen_err + " " + e.toString(); } catch(ImporterException &e) { err << gen_err + " " + e.toString(); } catch(std::exception& e) { err << parser_err + " " + e.what(); } if (haveFirewallObject()) { if (countInterfaces()==0) err << noInterfacesErrorMessage(); if (countRules()==0) err << noRulesErrorMessage(); } else { err << parser_err; err << noFirewallErrorMessage(); err << commonFailureErrorMessage(); } if (!err.isEmpty()) *logger << err.join("\n").toUtf8().constData(); } fwbuilder-5.1.0.3599/src/import/PIXImporter.cpp0000644000175000017500000011307111733011756021770 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "PIXImporter.h" #include #include #include #include #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Library.h" #include "fwbuilder/TCPUDPService.h" #include "../libgui/platforms.h" #include #include extern int fwbdebug; // TODO: this should move to some common library, together with // getVersionsForPlatform() it uses. Currently these functions are // defined in libgui/platforms.cpp extern QString findBestVersionMatch(const QString &platform, const QString &discovered_version); using namespace std; using namespace libfwbuilder; PIXImporter::PIXImporter(FWObject *lib, std::istringstream &input, Logger *log, const std::string &fwname) : IOSImporter(lib, input, log, fwname) { setPlatform("pix"); address_maker->setInvertedNetmasks(false); // since parent class sets to true } PIXImporter::~PIXImporter() { global_pools.clear(); } /* * do not clear named_objects_registry because this function is called * when we start processing each named object, object-group and some other * lines in the config */ void PIXImporter::clear() { Importer::clear(); current_named_object = NULL; named_object_name = ""; named_object_comment = ""; current_object_group = NULL; object_group_name = ""; object_group_comment = ""; object_group_service_protocol = ""; rule_type = NATRule::Unknown; prenat_interface = ""; postnat_interface = ""; real_a = ""; real_nm = ""; mapped_a = ""; mapped_nm = ""; real_addr_acl = ""; mapped_port_spec = ""; real_port_spec = ""; static_max_conn = ""; static_max_emb_conn = ""; nat_num = ""; nat_a = ""; nat_nm = ""; nat_acl = ""; tmp_global_pool = GlobalPool(); } /* * this clears temporary variables inside Importer but does not touch * current_named_object and current_object_group */ void PIXImporter::clearTempVars() { Importer::clear(); } Interface* PIXImporter::getInterfaceByLabel(const string &label) { map::iterator it; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *intf = it->second; if (intf->getLabel() == label) { return intf; } } return NULL; } FWObject* PIXImporter::makeSrcObj() { if (src_nm == "interface") { Interface *intf = getInterfaceByLabel(src_a); if (intf) return intf; // throw ImporterException( reportError( QString("Cannot find interface with label '%1'").arg(src_a.c_str())); } if (named_objects_registry.count(src_a.c_str()) > 0) { return named_objects_registry[src_a.c_str()]; } return Importer::makeSrcObj(); } FWObject* PIXImporter::makeDstObj() { if (dst_nm == "interface") { Interface *intf = getInterfaceByLabel(dst_a); if (intf) return intf; // throw ImporterException( reportError( QString("Cannot find interface with label '%1'").arg(dst_a.c_str())); } if (named_objects_registry.count(dst_a.c_str()) > 0) { return named_objects_registry[dst_a.c_str()]; } return Importer::makeDstObj(); } FWObject* PIXImporter::makeSrvObj() { if (protocol=="tcp" || protocol=="udp") { if (!src_port_spec.empty() && named_objects_registry.count(src_port_spec.c_str()) > 0) return named_objects_registry[src_port_spec.c_str()]; if (!dst_port_spec.empty() && named_objects_registry.count(dst_port_spec.c_str()) > 0) return named_objects_registry[dst_port_spec.c_str()]; } if (protocol == "icmp") { if (!icmp_spec.empty() && named_objects_registry.count(icmp_spec.c_str()) > 0) return named_objects_registry[icmp_spec.c_str()]; } if (named_objects_registry.count(protocol.c_str()) > 0) return named_objects_registry[protocol.c_str()]; return Importer::makeSrvObj(); } /* * See #2291 * * Service group can be defined to match dstination ports but used to * match source ports in the access-list command. In ASA 8.0 and 8.3 the * following configuration is valid: * * object-group service test-service-1 tcp * port-object eq www * * Group test-service-1 can be used in the position in an access-list * command where it would match source ports. * */ void PIXImporter::fixServiceObjectUsedForSrcPorts() { if ((protocol=="tcp" || protocol=="udp") && ! src_port_spec.empty() && named_objects_registry.count(src_port_spec.c_str()) > 0) { FWObject *obj = named_objects_registry[src_port_spec.c_str()]; FWObject *new_obj = mirrorServiceObjectRecursively(obj); src_port_spec = new_obj->getName(); } } /* * see #2265 and 2290. If access-list command uses object groups * and/or in-line port matches for both source and destination * ports, we need to create several new TCPService or UDPService * objects to match all combinations of ports. However this is only * necessary when at least one of them (source or destination port match) * uses object-group or named object because configuration with two in-line * port matches is taken care in IOSImporter::createTCPService() * and IOSImporter::createUDPService() */ void PIXImporter::fixServiceObjectUsedForBothSrcAndDstPorts() { if (protocol=="tcp" || protocol=="udp") { // empty port_spec means no corresponding port match (either inline or // named object/object group) if (src_port_spec.empty() || dst_port_spec.empty()) return; FWObject *src_port_obj = NULL; FWObject *dst_port_obj = NULL; if (!src_port_spec.empty() && named_objects_registry.count(src_port_spec.c_str()) > 0) src_port_obj = named_objects_registry[src_port_spec.c_str()]; if (!dst_port_spec.empty() && named_objects_registry.count(dst_port_spec.c_str()) > 0) dst_port_obj = named_objects_registry[dst_port_spec.c_str()]; // if both src_port_obj and dst_port_obj are NULL, this means // both port operations are in-line port matches that will be // taken are of in the base class functions if (src_port_obj == NULL && dst_port_obj == NULL) return; // If only one of the two is NULL, use base class functions to // fill it in from its port_op and port_spec variables if (dst_port_obj == NULL) { src_port_spec = ""; src_port_op = ""; if (protocol=="tcp") dst_port_obj = createTCPService(); else dst_port_obj = createUDPService(); } if (src_port_obj == NULL) { dst_port_spec = ""; dst_port_op = ""; if (protocol=="tcp") src_port_obj = createTCPService(); else src_port_obj = createUDPService(); } // now we have service objects or groups of service objects for // both source and destination port match string group_name = QString("%1 port match line %2").arg(protocol.c_str()) .arg(getCurrentLineNumber()).toStdString(); newObjectGroupService(group_name); mixServiceObjects(src_port_obj, dst_port_obj, current_object_group); src_port_spec = ""; dst_port_spec = group_name; } } void PIXImporter::mixServiceObjects(FWObject *src_ports, FWObject *dst_ports, FWObject *service_group) { if (Group::cast(src_ports)!=NULL) { for (FWObject::iterator i1=src_ports->begin(); i1!=src_ports->end(); ++i1) { FWObject *o1 = FWReference::getObject(*i1); mixServiceObjects(o1, dst_ports, service_group); } return; } if (Group::cast(dst_ports)!=NULL) { for (FWObject::iterator i1=dst_ports->begin(); i1!=dst_ports->end(); ++i1) { FWObject *o1 = FWReference::getObject(*i1); mixServiceObjects(src_ports, o1, service_group); } return; } if (src_ports->getTypeName() != dst_ports->getTypeName()) { // this should not happen since ASA would not have allowed // access list rule with different source and destination // protocols but it does not hurt to check reportError( QString("Source and destination protocols do not match: '%1', '%2'") .arg(src_ports->getTypeName().c_str()) .arg(dst_ports->getTypeName().c_str())); return; } ObjectSignature sig(error_tracker); sig.type_name = src_ports->getTypeName().c_str(); sig.port_range_inclusive = false; sig.src_port_range_start = TCPUDPService::cast(src_ports)->getSrcRangeStart(); sig.src_port_range_end = TCPUDPService::cast(src_ports)->getSrcRangeEnd(); sig.dst_port_range_start = TCPUDPService::cast(dst_ports)->getDstRangeStart(); sig.dst_port_range_end = TCPUDPService::cast(dst_ports)->getDstRangeEnd(); service_group->addRef(commitObject(service_maker->createObject(sig))); } FWObject* PIXImporter::mirrorServiceObjectRecursively(FWObject *obj) { FWObject *res = NULL; string new_name = obj->getName() + "-mirror"; if (Service::cast(obj) != NULL) { FWObject *new_obj = service_maker->getMirroredServiceObject(obj); if (new_obj) named_objects_registry[QString::fromUtf8(new_name.c_str())] = new_obj; res = new_obj; } else { // newObjectGroupService creates new group object, // registers it as a named object and assigns pointer to // it to current_object_group newObjectGroupService(new_name); // if this group includes another group, we'll end up calling // mirrorServiceObjectRecursively() again and at this very // point will overwrite current_object_group with a pointer to // that group's mirror FWObject *new_group = current_object_group; for (FWObject::iterator it=obj->begin(); it!=obj->end(); ++it) { FWObject *new_obj = mirrorServiceObjectRecursively( FWReference::getObject(*it)); if (new_obj) new_group->addRef(commitObject(new_obj)); } res = new_group; current_object_group = new_group; } return res; } void PIXImporter::setInterfaceAndDirectionForRuleSet( const string &ruleset_name, const string &interface_label, const string &dir) { map::iterator it; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *intf = it->second; if (intf->getLabel() == interface_label) { Importer::setInterfaceAndDirectionForRuleSet(intf, ruleset_name, dir); return; } } QString err("Can not associate rule set %1 with any interface\n"); addMessageToLog(err.arg(QString::fromUtf8(ruleset_name.c_str()))); } void PIXImporter::addLogging() { PolicyRule *rule = PolicyRule::cast(current_rule); FWOptions *ropt = rule->getOptionsObject(); /* alerts Immediate action needed (severity=1) critical Critical conditions (severity=2) debugging Debugging messages (severity=7) disable Disable log option on this ACL element, (no log at all) emergencies System is unusable (severity=0) errors Error conditions (severity=3) inactive Keyword for disabling an ACL element informational Informational messages (severity=6) interval Configure log interval, default value is 300 sec notifications Normal but significant conditions (severity=5) warnings Warning conditions (severity=4) */ QMap logging_levels; logging_levels["alerts"] = "alert"; logging_levels["critical"] = "crit"; logging_levels["debugging"] = "debug"; logging_levels["emergencies"] = ""; logging_levels["errors"] = "error"; logging_levels["informational"] = "info"; logging_levels["notifications"] = "notice"; logging_levels["warnings"] = "warning"; logging_levels["0"] = ""; logging_levels["1"] = "alert"; logging_levels["2"] = "crit"; logging_levels["3"] = "error"; logging_levels["4"] = "warning"; logging_levels["5"] = "notice"; logging_levels["6"] = "info"; logging_levels["7"] = "debug"; // QStringList log_levels = getLogLevels("pix"); rule->setLogging(logging); QString log_level_qs = log_level.c_str(); if ( ! log_level_qs.isEmpty()) { if (logging_levels.count(log_level_qs) != 0) ropt->setStr("log_level", logging_levels[log_level_qs].toStdString()); else ropt->setStr("log_level", log_level); if (log_level_qs == "disable" || log_level_qs == "inactive") ropt->setBool("disable_logging_for_this_rule", true); } if ( ! log_interval.empty()) { bool ok = false; int log_interval_int = QString(log_interval.c_str()).toInt(&ok); if (ok) ropt->setInt("log_interval", log_interval_int); } } void PIXImporter::pushRule() { if (rule_type == NATRule::Unknown) pushPolicyRule(); else pushNATRule(); assert(current_rule!=NULL); if (error_tracker->hasWarnings()) { QStringList warn = error_tracker->getWarnings(); // parser errors and warnings are added to the log by // PFCfgParser::reportError() and PFCfgParser::reportWarning() // so we dont need to add them again here foreach(QString w, warn) { if (!w.startsWith("Parser warning:")) addMessageToLog("Warning: " + w); } markCurrentRuleBad(); } if (error_tracker->hasErrors()) { QStringList err = error_tracker->getErrors(); foreach(QString e, err) { if (!e.startsWith("Parser error:")) addMessageToLog("Error: " + e); } markCurrentRuleBad(); } current_rule = NULL; rule_comment = ""; clear(); } void PIXImporter::pushPolicyRule() { assert(current_ruleset!=NULL); assert(current_rule!=NULL); // populate all elements of the rule addMessageToLog( QString("filtering rule: access list %1, action %2") .arg(QString::fromUtf8(current_ruleset->ruleset->getName().c_str())) .arg(action.c_str())); PolicyRule *rule = PolicyRule::cast(current_rule); FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); if (action=="permit") { rule->setAction(PolicyRule::Accept); ropt->setBool("stateless", false); } if (action=="deny") { rule->setAction(PolicyRule::Deny); ropt->setBool("stateless", true); } rule->setDirection(PolicyRule::Both); // named service object or a group can be defined to match dstination // ports but used to match source ports in the access-list command. fixServiceObjectUsedForSrcPorts(); fixServiceObjectUsedForBothSrcAndDstPorts(); // special exception for rules with "neq" port operator in both // source and destination. #2297. We have decided to just issue a // warning at this time and let user fix the rule manually. We // should handle this case properly some day. if (src_port_op == "neq" && dst_port_op == "neq") { error_tracker->registerError( QObject::tr("Rule matches tcp or udp ports using \"neq\" port operator in " "both source and destination. This configuration is " "not supported by import at this time, please fix manually")); } addSrc(); addDst(); addSrv(); addLogging(); // then add it to the current ruleset current_ruleset->ruleset->add(current_rule); addStandardImportComment( current_rule, QString::fromUtf8(rule_comment.c_str())); } /* * Rearrange vlan interfaces. Importer creates all interfaces as * children of the firewall. Vlan interfaces should become * subinterfaces of the corresponding physical interfaces. */ void PIXImporter::rearrangeVlanInterfaces() { std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( getFirewallObject())); list all_interface_objects = getFirewallObject()->getByTypeDeep(Interface::TYPENAME); list vlans; list::iterator it; for (it=all_interface_objects.begin(); it!=all_interface_objects.end(); ++it) { Interface *intf = Interface::cast(*it); FWOptions *ifopt = intf->getOptionsObject(); if (int_prop->looksLikeVlanInterface(intf->getName().c_str()) && ifopt->getStr("type")=="8021q") { qDebug() << "Found vlan interface" << intf->getName().c_str(); vlans.push_back(intf); } } for (it=vlans.begin(); it!=vlans.end(); ++it) { Interface *vlan_intf = Interface::cast(*it); qDebug() << "VLAN " << vlan_intf->getName().c_str(); QString base_name; int vlan_id; int_prop->parseVlan(vlan_intf->getName().c_str(), &base_name, &vlan_id); qDebug() << "base name" << base_name; if ( ! base_name.isEmpty()) { getFirewallObject()->remove(vlan_intf, false); // do not delete list::iterator it2; for (it2=all_interface_objects.begin(); it2!=all_interface_objects.end(); ++it2) { if (base_name == (*it2)->getName().c_str()) { (*it2)->add(vlan_intf, false); break; } } } } } bool compare_ruleset_names(string a, string b) { if (a.find("ssh_commands") == 0) return true; if (a.find("telnet_commands") == 0) return true; if (a.find("icmp_commands") == 0) return true; if (a.find("http_commands") == 0) return true; return a < b; } Firewall* PIXImporter::finalize() { // scan all UnidirectionalRuleSet objects, set interface and // direction in all rules of corresponding RuleSet and merge all // UnidirectionalRuleSet into one RuleSet object. Attach this // object to the firewall. if (fwbdebug) qDebug("PIXImporter::finalize()"); if (haveFirewallObject()) { Firewall *fw = Firewall::cast(getFirewallObject()); if (! discovered_platform.empty()) { QString pl = QString(discovered_platform.c_str()).toLower(); if (pl == "asa") pl = "pix"; fw->setStr("platform", pl.toStdString()); string host_os; if (pl == "pix") host_os = "pix_os"; if (pl == "fwsm") host_os = "fwsm_os"; if (! host_os.empty()) { fw->setStr("host_OS", host_os); Resources::setDefaultTargetOptions(host_os , fw); } string version = findBestVersionMatch( pl, discovered_version.c_str()).toStdString(); if ( ! version.empty()) fw->setStr("version", version); } rearrangeVlanInterfaces(); FWObject *policy = getFirewallObject()->getFirstByType(Policy::TYPENAME); assert( policy!=NULL ); FWObject *nat = getFirewallObject()->getFirstByType(NAT::TYPENAME); assert( nat!=NULL ); if (all_rulesets.size()!=0) { if (fwbdebug) { qDebug() << "Setting interface and direction for all rules"; qDebug() << "all_rulesets.size()=" << all_rulesets.size(); } list ruleset_names; std::map::iterator i; for (i=all_rulesets.begin(); i!=all_rulesets.end(); ++i) { ruleset_names.push_back(i->first); } // sort rule sets by name, making sure "ssh_commands_*", // "telnet_commands_*" and "icmp_commands_*" stay on top ruleset_names.sort(compare_ruleset_names); list::iterator it; for (it=ruleset_names.begin(); it!=ruleset_names.end(); ++it) { string ruleset_name = *it; if (ruleset_name == "nat") continue; UnidirectionalRuleSet *irs = all_rulesets[ruleset_name]; if (irs->to_be_deleted) { irs->ruleset->clearChildren(false); getFirewallObject()->remove(irs->ruleset, false); delete irs->ruleset; continue; } if (fwbdebug) { qDebug() << " irs->name=" << irs->name.c_str(); qDebug() << " irs->intf_dir.size()=" << irs->intf_dir.size(); qDebug() << " irs->ruleset->getName()=" << irs->ruleset->getName().c_str(); qDebug() << " irs->ruleset->size()=" << irs->ruleset->size(); FWObject *p = irs->ruleset->getParent(); qDebug() << " irs->ruleset->getParent()=" << p; if (p) qDebug() << " " << p->getName().c_str(); qDebug() << " fw=" << fw; qDebug() << " policy=" << policy; } if (irs->intf_dir.size() == 0) { // no interface and direction information for this rule set // Perhaps no access-group command ? FWObjectDatabase *dbroot = fw->getRoot(); FWObject *new_ruleset = dbroot->create( irs->ruleset->getTypeName()); fw->add(new_ruleset); new_ruleset->duplicate(irs->ruleset); } // optimization: If we have several interfaces for // the ruleset, create a group // But first group interfaces by direction so // that later we can merge rules into the policy // with proper combination of interface group and // direction. Remember that the same access list // can be used with multiple interfaces with different // directions each time. The same list can be applied // to the same interface both in and out (although in // this case we have already switched direction to "both") // if (irs->intf_dir.size()>1) { std::list all_in; std::list all_out; std::list all_both; std::map::iterator i; for (i = irs->intf_dir.begin(); i != irs->intf_dir.end(); ++i) { if ( (*i).second=="in") all_in.push_back( (*i).first ); if ( (*i).second=="out") all_out.push_back( (*i).first ); if ( (*i).second=="both") all_both.push_back( (*i).first ); } FWObject *og; if (all_in.size()>0) { og = createGroupOfInterfaces(irs->name, all_in); MergeRules mr(irs->name, og, PolicyRule::Inbound, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } if (all_out.size()>0) { og = createGroupOfInterfaces(irs->name, all_out); MergeRules mr(irs->name, og, PolicyRule::Outbound, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } if (all_both.size()>0) { og = createGroupOfInterfaces(irs->name, all_both); MergeRules mr(irs->name, og, PolicyRule::Both, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } } else { std::map::iterator j; for (j=irs->intf_dir.begin(); j!=irs->intf_dir.end(); ++j) { string intf_name = (*j).first; Interface *intf = all_interfaces[intf_name]; std::string _dir = (*j).second; PolicyRule::Direction direction = PolicyRule::Both; if (_dir=="in") direction = PolicyRule::Inbound; if (_dir=="out") direction = PolicyRule::Outbound; if (fwbdebug) qDebug() << "Interface: " << intf << "dir: " << _dir.c_str(); // not all access lists are associated with interfaces if (intf != NULL) { if (fwbdebug) qDebug() << " interface: " << intf->getName().c_str(); MergeRules mr(irs->name, intf, direction, policy); while (irs->ruleset->size() > 0) mr.move(irs->ruleset->front()); } } } if (fwbdebug) qDebug("ruleset done"); // call clearChidren() not recursive because children objects // of all rules should not be deleted irs->ruleset->clearChildren(false); getFirewallObject()->remove(irs->ruleset, false); delete irs->ruleset; } } list l2 = fw->getByType(Policy::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { RuleSet *rs = RuleSet::cast(*i); rs->renumberRules(); } // Deal with NAT ruleset UnidirectionalRuleSet *nat_rs = all_rulesets["nat"]; if (nat_rs) { while (nat_rs->ruleset->size() > 0) { FWObject *r = nat_rs->ruleset->front(); nat->reparent(r); } NAT::cast(nat)->renumberRules(); nat_rs->ruleset->clearChildren(false); getFirewallObject()->remove(nat_rs->ruleset, false); delete nat_rs->ruleset; } return fw; } else { return NULL; } } /* * Named objects * * At least in the case of Cisco configurations, I can only create an * object after I saw the line "host ... ", "subnet ..." or "range * ..." so I know its type. This means things like the name and * comment are known before the type. I use methods * commitNamed*Object() to create objects once all information is available. * * I other platforms information about named objects may not be * arranged in this way, for example in PF configs named objects are * represented by macros which do not have explicit type and have all * information on one line. Still, in that case the same commit*() * method will work if called by the grammar after all variables have * been parsed and values assigned to temporary member variables * inside the Importer object. */ void PIXImporter::newNamedObjectAddress(const string &name) { named_object_name = QString::fromUtf8(name.c_str()); named_object_comment = ""; addMessageToLog("Named object (address) " + name); } void PIXImporter::newNamedObjectService(const string &name) { named_object_name = QString::fromUtf8(name.c_str()); named_object_comment = ""; addMessageToLog("Named object (service) " + name); } void PIXImporter::commitNamedAddressObject() { ObjectSignature sig(error_tracker); sig.object_name = named_object_name; sig.type_name = Address::TYPENAME; sig.address = tmp_a.c_str(); sig.netmask = tmp_nm.c_str(); current_named_object = commitObject(address_maker->createObject(sig)); named_objects_registry[named_object_name] = current_named_object; } void PIXImporter::commitNamedAddressRangeObject() { ObjectSignature sig(error_tracker); sig.object_name = named_object_name; sig.type_name = AddressRange::TYPENAME; sig.setAddressRangeStart(tmp_range_1.c_str()); sig.setAddressRangeEnd(tmp_range_2.c_str()); current_named_object = commitObject(address_maker->createObject(sig)); named_objects_registry[named_object_name] = current_named_object; } void PIXImporter::commitNamedIPServiceObject() { ObjectSignature sig(error_tracker); sig.object_name = named_object_name; sig.type_name = IPService::TYPENAME; sig.setProtocol(protocol.c_str()); sig.fragments = fragments; current_named_object = commitObject(service_maker->createObject(sig)); named_objects_registry[named_object_name] = current_named_object; } void PIXImporter::commitNamedICMPServiceObject() { ObjectSignature sig(error_tracker); sig.object_name = named_object_name; sig.type_name = ICMPService::TYPENAME; if ( ! icmp_spec.empty()) { sig.setIcmpFromName(icmp_spec.c_str()); } else { sig.setIcmpType(icmp_type.c_str()); sig.setIcmpCode(icmp_code.c_str()); } current_named_object = commitObject(service_maker->createObject(sig)); named_objects_registry[named_object_name] = current_named_object; } void PIXImporter::commitNamedTCPUDPServiceObject() { FWObject *obj; // have to use createTCPService because it processes "neq" port // operators and may create a group with two services nstead of // just tcp service. Same for udp. if (protocol == "tcp") obj = createTCPService(named_object_name); if (protocol == "udp") obj = createUDPService(named_object_name); current_named_object = commitObject(obj); named_objects_registry[named_object_name] = current_named_object; } FWObject* PIXImporter::commitObject(FWObject *obj) { return Importer::commitObject(obj); } FWObject* PIXImporter::setNameOfNamedObject(FWObject *obj) { if (obj->isReadOnly()) return obj; if ( ! named_object_name.isEmpty()) obj->setName(named_object_name.toUtf8().constData()); if ( ! object_group_name.isEmpty()) obj->setName(object_group_name.toUtf8().constData()); return obj; } /* * it looks like "description" line is always the last in the named * object block output of "show run" command on ASA, however * "description" is optional and we create the object when we see * "subnet", "host" or "service" line. This function adds description * to existing named object if it exists or just sets the variable * named_object_comment. I dont want to lose the ability to parse the * description if it happens to appear first in the named object * block. */ void PIXImporter::setNamedObjectDescription(const std::string &txt) { named_object_comment = QString::fromUtf8(txt.c_str()); if (current_named_object != NULL && ! named_object_name.isEmpty()) { current_named_object->setBool(".import-commited", false); current_named_object->setComment(""); addStandardImportComment(current_named_object, named_object_comment); } } /************************************************************************/ void PIXImporter::newObjectGroupNetwork(const string &name) { object_group_name = QString::fromUtf8(name.c_str()); object_group_comment = ""; ObjectMaker maker(Library::cast(library), error_tracker); current_object_group = setNameOfNamedObject( commitObject( maker.createObject(ObjectGroup::TYPENAME, name))); named_objects_registry[object_group_name] = current_object_group; addMessageToLog("Object Group (network) " + name); } void PIXImporter::newObjectGroupService(const string &name) { object_group_name = QString::fromUtf8(name.c_str()); object_group_comment = ""; ObjectMaker maker(Library::cast(library), error_tracker); current_object_group = setNameOfNamedObject( commitObject( maker.createObject(ServiceGroup::TYPENAME, name))); named_objects_registry[object_group_name] = current_object_group; object_group_service_protocol = ""; addMessageToLog("Object Group (service) " + name); } bool PIXImporter::isKnownServiceGroupName(const string &object_group_name) { QString qs_object_group_name = QString::fromUtf8(object_group_name.c_str()); if (fwbdebug) qDebug() << "isKnownServiceGroupName:" << qs_object_group_name; if (named_objects_registry.count(qs_object_group_name) > 0) { FWObject *grp = named_objects_registry[qs_object_group_name]; return ServiceGroup::isA(grp); } return false; } void PIXImporter::newObjectGroupProtocol(const string &name) { object_group_name = QString::fromUtf8(name.c_str()); object_group_comment = ""; ObjectMaker maker(Library::cast(library), error_tracker); current_object_group = setNameOfNamedObject( commitObject( maker.createObject(ServiceGroup::TYPENAME, name))); named_objects_registry[object_group_name] = current_object_group; addMessageToLog("Object Group (protocol) " + name); } void PIXImporter::newObjectGroupICMP(const string &name) { object_group_name = QString::fromUtf8(name.c_str()); object_group_comment = ""; ObjectMaker maker(Library::cast(library), error_tracker); current_object_group = setNameOfNamedObject( commitObject( maker.createObject(ServiceGroup::TYPENAME, name))); named_objects_registry[object_group_name] = current_object_group; addMessageToLog("Object Group (icmp) " + name); } void PIXImporter::setObjectGroupDescription(const std::string &descr) { object_group_comment = QString::fromUtf8(descr.c_str()); if (current_object_group != NULL && ! object_group_name.isEmpty()) { current_object_group->setBool(".import-commited", false); current_object_group->setComment(""); addStandardImportComment(current_object_group, object_group_comment); } } void PIXImporter::addNetworkToObjectGroup() { ObjectSignature sig(error_tracker); sig.type_name = Address::TYPENAME; sig.setAddress(tmp_a.c_str()); sig.setNetmask(tmp_nm.c_str()); current_object_group->addRef( commitObject(address_maker->createObject(sig))); } void PIXImporter::addNamedObjectToObjectGroup(const std::string &object_name) { QString no_name = QString::fromUtf8(object_name.c_str()); if (named_objects_registry.count(no_name) > 0) { current_object_group->addRef(named_objects_registry[no_name]); } else // throw ImporterException( reportError( QString("Attempt to add yet undefined named object '%1' " "to object group '%2'").arg(no_name).arg(object_group_name)); } void PIXImporter::addIPServiceToObjectGroup() { ObjectSignature sig(error_tracker); sig.type_name = IPService::TYPENAME; sig.setProtocol(protocol.c_str()); sig.fragments = fragments; FWObject *s = service_maker->createObject(sig); current_object_group->addRef(commitObject(s)); } void PIXImporter::addTCPUDPServiceToObjectGroup() { FWObject *new_obj = NULL; if (protocol.empty() && ! object_group_service_protocol.isEmpty()) protocol = object_group_service_protocol.toStdString(); if (protocol == "tcp") new_obj = createTCPService(); if (protocol == "udp") new_obj = createUDPService(); if (protocol == "tcp-udp") new_obj = createTCPUDPServicePair(); if (new_obj) current_object_group->addRef(commitObject(new_obj)); } void PIXImporter::addICMPServiceToObjectGroup() { ObjectSignature sig(error_tracker); sig.type_name = ICMPService::TYPENAME; if ( ! icmp_spec.empty()) { sig.setIcmpFromName(icmp_spec.c_str()); } else { sig.setIcmpType(icmp_type.c_str()); sig.setIcmpCode(icmp_code.c_str()); } FWObject *s = service_maker->createObject(sig); current_object_group->addRef(commitObject(s)); } fwbuilder-5.1.0.3599/src/import/RouteSpec.h0000644000175000017500000000263411733011756021166 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ROUTE_SPEC_H_ #define _ROUTE_SPEC_H_ #include #include #include class RouteSpec { public: std::string iface; std::string address; std::string netmask; RouteSpec() { iface = ""; address = ""; netmask = ""; } RouteSpec(const RouteSpec &other) { iface = other.iface; address = other.address; netmask = other.netmask; } RouteSpec(const std::string _iface, const std::string _addr, const std::string _nm) { iface = _iface; address = _addr; netmask = _nm; } }; #endif fwbuilder-5.1.0.3599/src/import/IOSImporterRun.cpp0000644000175000017500000000536111733011756022451 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" // #include "global.h" #include "IOSImporter.h" #include #include #include #include #include #include // parser and lexer for Cisco IOS access lists #include "../parsers/IOSCfgLexer.hpp" #include "../parsers/IOSCfgParser.hpp" extern int fwbdebug; /* * Only this module depends on IOSCfgLexer and IOSCfgParser, * so only this file is recompiled when we change grammar */ void IOSImporter::run() { // it is probably safer to create an empty firewall if we do not have // ANTLR on the system rather than try to #ifdef out chunks of code // here and there in this module // // Obviously we should disable GUI elements that activate this importer // if ANTLR runtime is not available. // QStringList err; QString parser_err = QObject::tr("Parser error:"); QString gen_err = QObject::tr("Error:"); std::ostringstream parser_debug; IOSCfgLexer lexer(input); IOSCfgParser parser(lexer); parser.importer = this; if (fwbdebug) parser.dbg = &std::cerr; else parser.dbg = &parser_debug; try { parser.cfgfile(); } catch(ANTLR_USE_NAMESPACE(antlr)ANTLRException &e) { err << parser_err + " " + e.toString().c_str(); } catch(ObjectMakerException &e) { err << gen_err + " " + e.toString(); } catch(ImporterException &e) { err << gen_err + " " + e.toString(); } catch(std::exception& e) { err << parser_err + " " + e.what(); } if (haveFirewallObject()) { if (countInterfaces()==0) err << noInterfacesErrorMessage(); if (countRules()==0) err << noRulesErrorMessage(); } else { err << parser_err; err << noFirewallErrorMessage(); err << commonFailureErrorMessage(); } if (!err.isEmpty()) *logger << err.join("\n").toUtf8().constData(); } fwbuilder-5.1.0.3599/src/import/PreImport.cpp0000644000175000017500000002060111733011756021523 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PreImport.h" #include #include using namespace std; class matchPFDirectionIn : public matchPFDirection { public: virtual bool operator()(const QString &str) { return str.contains(" in "); } }; class matchPFDirectionOut : public matchPFDirection { public: virtual bool operator()(const QString &str) { return str.contains(" out "); } }; class matchPFDirectionBoth : public matchPFDirection { public: virtual bool operator()(const QString &str) { return ! str.contains(" in ") && ! str.contains(" out "); } }; void PreImport::scan() { QList pix_re; pix_re << QRegExp("^ASA Version") << QRegExp("^PIX Version") << QRegExp("^FWSM Version") << QRegExp("^nat \\(\\S+,\\S+\\)") << QRegExp("^static \\(\\S+,\\S+\\)") << QRegExp("^global \\(") << QRegExp("^nameif \\S+") << QRegExp("^fixup \\S+"); QList fwsm_re; fwsm_re << QRegExp("^FWSM Version"); QList ios_re; ios_re << QRegExp("IOS Version") << QRegExp("^[vV]ersion 1[012]\\..*"); QList iptables_re; iptables_re << QRegExp("# Generated by iptables-save") << QRegExp("^:INPUT ") << QRegExp("^:OUTPUT ") << QRegExp("^:FORWARD ") << QRegExp("^-A INPUT ") << QRegExp("^-A OUTPUT ") << QRegExp("^-A FORWARD "); QList iptables_with_counters_re; iptables_with_counters_re << QRegExp("^\\[\\d+:\\d+\\] -A INPUT ") << QRegExp("^\\[\\d+:\\d+\\] -A OUTPUT ") << QRegExp("^\\[\\d+:\\d+\\] -A FORWARD "); QList pf_conf_re; pf_conf_re << QRegExp("^scrub\\s+\\S+") << QRegExp("^set\\s+timeout\\s+\\S+") << QRegExp("^pass\\s+") << QRegExp("^block\\s+") << QRegExp("^nat\\s+(?!\\()") << QRegExp("^rdr\\s+(?!\\()") << QRegExp("^table\\s+<\\S+>\\s+"); foreach (QString line, *buffer) { if (platform == UNKNOWN) { foreach (QRegExp re, pix_re) { if (re.indexIn(line) > -1) { platform = PIX; break; } } foreach (QRegExp re, fwsm_re) { if (re.indexIn(line) > -1) { platform = FWSM; break; } } foreach (QRegExp re, ios_re) { if (re.indexIn(line) > -1) { platform = IOSACL; break; } } foreach (QRegExp re, iptables_re) { if (re.indexIn(line) > -1) { platform = IPTABLES; break; } } foreach (QRegExp re, pf_conf_re) { if (re.indexIn(line) > -1) { platform = PF; break; } } } if (platform == IPTABLES) { foreach (QRegExp re, iptables_with_counters_re) { if (re.indexIn(line) > -1) { platform = IPTABLES_WITH_COUNTERS; break; } } } } /* * fwbuilder generates PF configuration that always uses "quick" * keyword to make the first matching rule stop processing. A lot * of existing pf.conf files use the other model where PF commands * do not use this keyword, so that all rules inspect the packet * and the last matching rule makes the decision. Fwbuilder can * not generate PF configuration in this style and can not import * it. We look for "block" command without "quick" parameter to * determine if the configuration offered for import is written in * this style. * We refuse to import policies that have "block" line with no * "quick" word, unless there are other command(s) with "quick" * after it. We should do this comparison keeping direction in * mind because it is possible to have "block in all" and then * "pass out quick something". It looks like a style with "block * all" at the top used to set up default policy is quite * popular. Configuration written in this style has "block all * log" at the top (or in the middle), followed by a bunch of * specific "pass quick" rules. We can import this if "block all * log" is the last rule, but not if it is followed by some pass * rules with no "quick". */ if (platform == PF) { matchPFDirectionIn dir_in; matchPFDirectionOut dir_out; matchPFDirectionBoth dir_both; if (isReversePFConfigurationStyle(dir_in) || isReversePFConfigurationStyle(dir_out) || isReversePFConfigurationStyle(dir_both)) { platform = PF_REVERSE; } } } bool PreImport::isReversePFConfigurationStyle(matchPFDirection &dir_op) { bool has_block_no_quick = false; bool has_command_with_quick_after_block = false; bool has_command_with_no_quick_after_block = false; QRegExp cont("\\\\\\s*\n"); QString line; QStringListIterator it(*buffer); while (it.hasNext()) { // first, unfold lines ending with "\" line = it.next(); int cont_idx; while ( (cont_idx = cont.indexIn(line)) > -1 && it.hasNext()) { line.insert(cont_idx, it.next()); } line = line.trimmed(); if (line.startsWith("#")) continue; if (line.isEmpty()) continue; if ( ! dir_op(line)) continue; if (line.contains(" quick")) { // check if after the line with "block" and no "quick" // comes a line with action "pass" and "quick" word. // This is a mixed-style policy and we can try to // import it. if (has_block_no_quick && (line.startsWith("pass ") || line.startsWith("block "))) { has_command_with_quick_after_block = true; continue; } } else { // check if this is a line with action "block" and no // "quick" word if (line.startsWith("block ")) { has_block_no_quick = true; continue; } if (has_block_no_quick) { has_command_with_no_quick_after_block = true; break; } } } return (has_block_no_quick && has_command_with_no_quick_after_block && ! has_command_with_quick_after_block); } QString PreImport::getPlatformAsString() { QString platform_string; switch (platform) { case PreImport::UNKNOWN: platform_string = ""; break; case PreImport::PIX: platform_string = "pix"; break; case PreImport::FWSM: platform_string = "fwsm"; break; case PreImport::IOSACL: platform_string = "iosacl"; break; case PreImport::IPTABLES: case PreImport::IPTABLES_WITH_COUNTERS: platform_string = "iptables"; break; case PreImport::PF: case PreImport::PF_REVERSE: platform_string = "pf"; break; } return platform_string; } fwbuilder-5.1.0.3599/src/import/addressObjectMaker.h0000644000175000017500000000337511733011756023014 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ADDRESS_OBJECT_MAKER_H_ #define _ADDRESS_OBJECT_MAKER_H_ #include "objectMaker.h" #include class AddressObjectMaker : public ObjectMaker { bool inverted_netmasks; public: AddressObjectMaker(libfwbuilder::Library *l, ObjectMakerErrorTracker *et) : ObjectMaker(l, et) { inverted_netmasks = false; } virtual ~AddressObjectMaker(); void setInvertedNetmasks(bool f) { inverted_netmasks = f; } bool getInvertedNetmasks() { return inverted_netmasks; } virtual libfwbuilder::FWObject* createObject(ObjectSignature &sig); protected: virtual libfwbuilder::FWObject* createAddress(ObjectSignature &sig); virtual libfwbuilder::FWObject* createAddressRange(ObjectSignature &sig); virtual libfwbuilder::FWObject* createAddressTable(ObjectSignature &sig); virtual libfwbuilder::FWObject* createDNSName(ObjectSignature &sig); }; #endif fwbuilder-5.1.0.3599/src/import/objectSignature.cpp0000644000175000017500000010153111733011756022734 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "objectMaker.h" #include "objectSignature.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/DynamicGroup.h" #include "QStringListOperators.h" #include "getProtoByName.h" #include "getServByName.h" #include #include #include extern int fwbdebug; using namespace libfwbuilder; using namespace std; QMap > ObjectSignature::icmp_names; QMap ObjectSignature::icmp_code_names; ObjectSignature::ObjectSignature(ObjectMakerErrorTracker *et) { error_tracker = et; port_range_inclusive = true; protocol = 0; fragments = false; short_fragments = false; any_opt = false; lsrr = false; ssrr = false; rr = false; ts = false; rtralt = false; rtralt_value = false; icmp_type = -1; icmp_code = -1; src_port_range_start = 0; src_port_range_end = 0; dst_port_range_start = 0; dst_port_range_end = 0; established = false; if (icmp_names.size() == 0) { // Cisco icmp names icmp_names["echo-reply"] = QPair(0, 0); icmp_names["unreachable"] = QPair(3, -1); // all "unreachables" icmp_names["net-unreachable"] = QPair(3, 0); icmp_names["host-unreachable"] = QPair(3, 1); icmp_names["protocol-unreachable"] = QPair(3, 2); icmp_names["port-unreachable"] = QPair(3, 3); icmp_names["packet-too-big"] = QPair(3, 4); icmp_names["source-route-failed"] = QPair(3, 5); icmp_names["network-unknown"] = QPair(3, 6); icmp_names["host-unknown"] = QPair(3, 7); icmp_names["host-isolated"] = QPair(3, 8); icmp_names["dod-net-prohibited"] = QPair(3, 9); icmp_names["dod-host-prohibited"] = QPair(3, 10); icmp_names["net-tos-unreachable"] = QPair(3, 11); icmp_names["host-tos-unreachable"] = QPair(3, 12); icmp_names["administratively-prohibited"] = QPair(3, 13); icmp_names["host-precedence-unreachable"] = QPair(3, 14); icmp_names["precedence-unreachable"] = QPair(3, 15); icmp_names["source-quench"] = QPair(4, 0); icmp_names["net-redirect"] = QPair(5, 0); icmp_names["host-redirect"] = QPair(5, 1); icmp_names["net-tos-redirect"] = QPair(5, 2); icmp_names["host-tos-redirect"] = QPair(5, 3); icmp_names["echo"] = QPair(8, 0); icmp_names["router-advertisement"] = QPair(9, 0); icmp_names["router-solicitation"] = QPair(10, 0); icmp_names["ttl-exceeded"] = QPair(11, 0); icmp_names["reassembly-timeout"] = QPair(11, 1); icmp_names["general-parameter-problem"] = QPair(12, 0); icmp_names["option-missing"] = QPair(12, 1); icmp_names["timestamp-request"] = QPair(13, 0); icmp_names["timestamp-reply"] = QPair(14, 0); icmp_names["information-request"] = QPair(15, 0); icmp_names["information-reply"] = QPair(16, 0); icmp_names["mask-request"] = QPair(17, 0); icmp_names["mask-reply"] = QPair(18, 0); // ASA 8.3 icmp names icmp_names["alternate-address"] = QPair(6, -1); icmp_names["conversion-error"] = QPair(31, -1); icmp_names["echo"] = QPair(8, -1); icmp_names["echo-reply"] = QPair(0, -1); icmp_names["information-reply"] = QPair(16, -1); icmp_names["information-request"] = QPair(15, -1); icmp_names["mask-reply"] = QPair(18, -1); icmp_names["mask-request"] = QPair(17, -1); icmp_names["mobile-redirect"] = QPair(32, -1); icmp_names["parameter-problem"] = QPair(12, -1); icmp_names["redirect"] = QPair(5, -1); icmp_names["router-advertisement"] = QPair(9, -1); icmp_names["router-solicitation"] = QPair(10, -1); icmp_names["source-quench"] = QPair(4, -1); icmp_names["time-exceeded"] = QPair(11, -1); icmp_names["timestamp-reply"] = QPair(14, -1); icmp_names["timestamp-request"] = QPair(13, -1); icmp_names["traceroute"] = QPair(30, -1); icmp_names["unreachable"] = QPair(3, -1); // iptables icmp names icmp_names["any"] = QPair(-1,-1); icmp_names["echo-reply"] = QPair(0,0); // all "unreachables" icmp_names["destination-unreachable"] = QPair(3,-1); icmp_names["network-unreachable"] = QPair(3,0); icmp_names["host-unreachable"] = QPair(3,1); icmp_names["protocol-unreachable"] = QPair(3,2); icmp_names["port-unreachable"] = QPair(3,3); icmp_names["fragmentation-needed"] = QPair(3,4); icmp_names["source-route-failed"] = QPair(3,5); icmp_names["network-unknown"] = QPair(3,6); icmp_names["host-unknown"] = QPair(3,7); icmp_names["host-isolated"] = QPair(3,8); icmp_names["network-prohibited"] = QPair(3,9); icmp_names["host-prohibited"] = QPair(3,10); icmp_names["TOS-network-unreachable"] = QPair(3,11); icmp_names["TOS-host-unreachable"] = QPair(3,12); icmp_names["communication-prohibited"] = QPair(3,13); icmp_names["host-precedence-violation"] = QPair(3,14); icmp_names["precedence-cutoff"] = QPair(3,15); icmp_names["source-quench"] = QPair(4,0); icmp_names["redirect"] = QPair(5,-1); icmp_names["network-redirect"] = QPair(5,0); icmp_names["host-redirect"] = QPair(5,1); icmp_names["TOS-network-redirect"] = QPair(5,2); icmp_names["TOS-host-redirect"] = QPair(5,3); icmp_names["echo-request"] = QPair(8,0); icmp_names["router-advertisement"] = QPair(9,0); icmp_names["router-solicitation"] = QPair(10,0); icmp_names["ttl-exceeded"] = QPair(11,0); icmp_names["time-exceeded"] = QPair(11,0); icmp_names["ttl-zero-during-transit"] = QPair(11,0); icmp_names["ttl-zero-during-reassembly"] = QPair(11,1); icmp_names["parameter-problem"] = QPair(12,0); icmp_names["ip-header-bad"] = QPair(12,0); icmp_names["required-option-missing"] = QPair(12,1); icmp_names["timestamp-request"] = QPair(13,0); icmp_names["timestamp-reply"] = QPair(14,0); icmp_names["information-request"] = QPair(15,0); icmp_names["information-reply"] = QPair(16,0); icmp_names["address-mask-request"] = QPair(17,0); icmp_names["address-mask-reply"] = QPair(18,0); // ICMP types defined in "man 4 icmp" on OpenBSD icmp_names["echorep"] = QPair(0,0); icmp_names["unreach"] = QPair(3,0); icmp_names["squench"] = QPair(4,0); icmp_names["redir"] = QPair(5,0); icmp_names["althost"] = QPair(6,0); icmp_names["echoreq"] = QPair(8,0); icmp_names["routeradv"] = QPair(9,0); icmp_names["routersol"] = QPair(10,0); icmp_names["timex"] = QPair(11,0); icmp_names["paramprob"] = QPair(12,0); icmp_names["timereq"] = QPair(13,0); icmp_names["timerep"] = QPair(14,0); icmp_names["inforeq"] = QPair(15,0); icmp_names["inforep"] = QPair(16,0); icmp_names["maskreq"] = QPair(17,0); icmp_names["maskrep"] = QPair(18,0); icmp_names["trace"] = QPair(30,0); icmp_names["dataconv"] = QPair(31,0); icmp_names["mobredir"] = QPair(32,0); icmp_names["ipv6-where"] = QPair(33,0); icmp_names["ipv6-here"] = QPair(34,0); icmp_names["mobregreq"] = QPair(35,0); icmp_names["mobregrep"] = QPair(36,0); icmp_names["skip"] = QPair(39,0); icmp_names["photuris"] = QPair(40,0); } /* ICMP codes defined in "man 4 icmp". These are used by PF Num Abbrev. Type Description 0 net-unr unreach Network unreachable 1 host-unr unreach Host unreachable 2 proto-unr unreach Protocol unreachable 3 port-unr unreach Port unreachable 4 needfrag unreach Fragmentation needed but DF bit set 5 srcfail unreach Source routing failed 6 net-unk unreach Network unknown 7 host-unk unreach Host unknown 8 isolate unreach Host isolated 9 net-prohib unreach Network administratively prohibited 10 host-prohib unreach Host administratively prohibited 11 net-tos unreach Invalid TOS for network 12 host-tos unreach Invalid TOS for host 13 filter-prohib unreach Prohibited access 14 host-preced unreach Precedence violation 15 cutoff-preced unreac Precedence cutoff 0 redir-net redir Shorter route for network 1 redir-host redir Shorter route for host 2 redir-tos-net redir Shorter route for TOS and network 3 redir-tos-host redir Shorter route for TOS and host 0 normal-adv routeradv Normal advertisement 16 common-adv routeradv Selective advertisement 0 transit timex Time exceeded in transit 1 reassemb timex Time exceeded in reassembly 0 badhead paramprob Invalid option pointer 1 optmiss paramprob Missing option 2 badlen paramprob Invalid length 1 unknown-ind photuris Unknown security index 2 auth-fail photuris Authentication failed 3 decrypt-fail photuris Decryption failed */ if (icmp_code_names.size() == 0) { icmp_code_names["net-unr"] = 0; icmp_code_names["host-unr"] = 1; icmp_code_names["proto-unr"] = 2; icmp_code_names["port-unr"] = 3; icmp_code_names["needfrag"] = 4; icmp_code_names["srcfail"] = 5; icmp_code_names["net-unk"] = 6; icmp_code_names["host-unk"] = 7; icmp_code_names["isolate"] = 8; icmp_code_names["net-prohib"] = 9; icmp_code_names["host-prohib"] = 10; icmp_code_names["net-tos"] = 11; icmp_code_names["host-tos"] = 12; icmp_code_names["filter-prohib"] = 13; icmp_code_names["host-preced"] = 14; icmp_code_names["cutoff-preced"] = 15; icmp_code_names["redir-net"] = 0; icmp_code_names["redir-host"] = 1; icmp_code_names["redir-tos-net"] = 2; icmp_code_names["redir-tos-host"] = 3; icmp_code_names["normal-adv"] = 0; icmp_code_names["common-adv"] = 16; icmp_code_names["transit"] = 0; icmp_code_names["reassemb"] = 1; icmp_code_names["badhead"] = 0; icmp_code_names["optmiss"] = 1; icmp_code_names["badlen"] = 2; icmp_code_names["unknown-ind"] = 1; icmp_code_names["auth-fail"] = 2; icmp_code_names["decrypt-fail"] = 3; } } ObjectSignature::ObjectSignature(const ObjectSignature &other) : libfwbuilder::Dispatch(other) { error_tracker = other.error_tracker; type_name = other.type_name; object_name = other.object_name; address = other.address; netmask = other.netmask; address_range_start = other.address_range_start; address_range_end = other.address_range_end; dns_name = other.dns_name; address_table_name = other.address_table_name; parent_interface_name = other.parent_interface_name; protocol = other.protocol; fragments = other.fragments; short_fragments = other.short_fragments; any_opt = other.any_opt; dscp = other.dscp; tos = other.tos; lsrr = other.lsrr; ssrr = other.ssrr; rr = other.rr; ts = other.ts; rtralt = other.rtralt; rtralt_value = other.rtralt_value; icmp_type = other.icmp_type; icmp_code = other.icmp_code; src_port_range_start = other.src_port_range_start; src_port_range_end = other.src_port_range_end; dst_port_range_start = other.dst_port_range_start; dst_port_range_end = other.dst_port_range_end; established = other.established; flags_mask = other.flags_mask; flags_comp = other.flags_comp; platform = other.platform; protocol_name = other.protocol_name; code = other.code; tag = other.tag; user_id = other.user_id; } void ObjectSignature::setAddress(const QString &s) { address = s; } void ObjectSignature::setAddressRangeStart(const QString &s) { address_range_start = s; } void ObjectSignature::setAddressRangeEnd(const QString &s) { address_range_end = s; } void ObjectSignature::setNetmask(const QString &netm, bool inverted_netmask) { InetAddr inetaddr_nm; try { inetaddr_nm = InetAddr(netm.toStdString()); if (inverted_netmask) inetaddr_nm = ~inetaddr_nm; } catch (FWException &ex) { if (netm.contains('.')) { // netmask has '.' in it but conversion failed. // throw ObjectMakerException( error_tracker->registerError( QString("Error converting netmask '%1'").arg(netm)); } else { // no dot in netmask, perhaps it is specified by its length? // If netmask is specified by length, need to use special // constructor for class Netmask to convert bool ok = false; int nm_len = netm.toInt(&ok); if (ok) { inetaddr_nm = InetAddr(nm_len); } else { // could not convert netmask as simple integer // throw ObjectMakerException( error_tracker->registerError( QString("Error converting netmask '%1'").arg(netm)); } } } netmask = inetaddr_nm.toString().c_str(); } void ObjectSignature::setProtocol(const QString &s) { // this assumes protocol is represented by a number bool ok = false; protocol = QString(s).toInt(&ok); if ( ! ok) { // could not convert protocol number protocol = GetProtoByName::getProtocolByName(s); if (protocol == -1) { protocol = 0; error_tracker->registerError( QString("Protocol '%1' is unknown").arg(s)); } } } void ObjectSignature::setIcmpFromName(const QString &s) { if (icmp_names.count(s) > 0) { QPair p = icmp_names[s]; icmp_type = p.first; icmp_code = p.second; } else error_tracker->registerError( QString("ICMP type name '%1' is unknown").arg(s)); } void ObjectSignature::setIcmpCodeFromName(const QString &s) { if (icmp_code_names.count(s) > 0) { icmp_code = icmp_code_names[s]; } else error_tracker->registerError( QString("ICMP code name '%1' is unknown").arg(s)); } void ObjectSignature::setIcmpType(const QString &s) { if (s.isEmpty()) icmp_type = -1; else { bool ok = false; icmp_type = s.toInt(&ok); if (!ok) { // could not convert icmp_type = -1; error_tracker->registerError( QString("ICMP type '%1' is unusable").arg(s)); } } } void ObjectSignature::setIcmpCode(const QString &s) { if (s.isEmpty()) icmp_code = -1; else { bool ok = false; icmp_code = s.toInt(&ok); if (!ok) { // could not convert icmp_code = -1; error_tracker->registerError( QString("ICMP code '%1' is unusable").arg(s)); } } } int ObjectSignature::portFromString(const QString &port_spec, const QString &proto, int default_port) { QString ps = port_spec.trimmed(); if (ps == "") return 0; if (ps == ":") return default_port; int port = GetServByName::getPortByName(ps, proto); if (port == -1) { error_tracker->registerError( QString("%1 port name '%2' is unknown").arg(proto).arg(ps)); port = 0; } return port; } void ObjectSignature::setSrcPortRange(const QString &range_start_spec, const QString &range_end_spec, const QString &proto) { src_port_range_start = portFromString(range_start_spec, proto, 0); src_port_range_end = portFromString(range_end_spec, proto, 65535); } void ObjectSignature::setDstPortRange(const QString &range_start_spec, const QString &range_end_spec, const QString &proto) { dst_port_range_start = portFromString(range_start_spec, proto, 0); dst_port_range_end = portFromString(range_end_spec, proto, 65535); } /* * Sets source port range from cisco-like port operation: * * eq www * gt smtp * lt 1024 * range 10000 10010 * * @port_op is operation ("lt", "gt", "eq", "range") * @port_spec is port number of service name * @proto is protocol name used for GetServByName::GetPortByName() */ void ObjectSignature::setSrcPortRangeFromPortOpForCisco(const QString &port_op, const QString &port_spec, const QString &proto) { QString portop = port_op.trimmed(); QString portspec = port_spec.trimmed(); src_port_range_start = 0; src_port_range_end = 0; QString range_start; QString range_end; QStringList sl = portspec.split(" "); if (sl.size() > 1) { range_start = sl[0]; range_end = sl[1]; } else { range_start = portspec; range_end = portspec; } src_port_range_start = portFromString(range_start, proto, 0); src_port_range_end = portFromString(range_end, proto, 65535); if (portop == "lt") src_port_range_start = 0; if (portop=="gt") src_port_range_end = 65535; if (portop=="eq") { src_port_range_start = src_port_range_end; } if (portop=="range") { // range_start and range_end have been set ; } if ( ! port_range_inclusive) { if (portop == "lt") src_port_range_end--; if (portop == "gt") src_port_range_start++; } } void ObjectSignature::setDstPortRangeFromPortOpForCisco(const QString &port_op, const QString &port_spec, const QString &proto) { QString portop = port_op.trimmed(); QString portspec = port_spec.trimmed(); dst_port_range_start = 0; dst_port_range_end = 0; QString range_start; QString range_end; QStringList sl = portspec.split(" "); if (sl.size() > 1) { range_start = sl[0]; range_end = sl[1]; } else { range_start = portspec; range_end = portspec; } dst_port_range_start = portFromString(range_start, proto, 0); dst_port_range_end = portFromString(range_end, proto, 65535); if (portop == "lt") dst_port_range_start = 0; if (portop=="gt") dst_port_range_end = 65535; if (portop=="eq") { dst_port_range_start = dst_port_range_end; } if (portop=="range") { // range_start and range_end have been set ; } if ( ! port_range_inclusive) { if (portop == "lt") dst_port_range_end--; if (portop == "gt") dst_port_range_start++; } } void ObjectSignature::setSrcPortRangeFromPortOpForPF(const QString &port_op, const QString &port1, const QString &port2, const QString &proto) { QString portop = port_op.trimmed(); src_port_range_start = 0; src_port_range_end = 0; QString range_start = port1; QString range_end = port2; src_port_range_start = portFromString(range_start, proto, 0); src_port_range_end = portFromString(range_end, proto, 65535); if (portop == "<") { src_port_range_start = 0; src_port_range_end--; } if (portop == "<=") { src_port_range_start = 0; } if (portop == ">") { src_port_range_start++; src_port_range_end = 65535; } if (portop == ">=") { src_port_range_end = 65535; } if (portop == "=") { src_port_range_start = src_port_range_end; } if (portop==":") { // range_start and range_end have been set ; } if (portop == "><") { src_port_range_end--; src_port_range_start++; } } void ObjectSignature::setDstPortRangeFromPortOpForPF(const QString &port_op, const QString &port1, const QString &port2, const QString &proto) { QString portop = port_op.trimmed(); dst_port_range_start = 0; dst_port_range_end = 0; QString range_start = port1; QString range_end = port2; dst_port_range_start = portFromString(range_start, proto, 0); dst_port_range_end = portFromString(range_end, proto, 65535); if (portop == "<") { dst_port_range_start = 0; dst_port_range_end--; } if (portop == "<=") { dst_port_range_start = 0; } if (portop == ">") { dst_port_range_start++; dst_port_range_end = 65535; } if (portop == ">=") { dst_port_range_end = 65535; } if (portop == "=") { dst_port_range_start = dst_port_range_end; } if (portop==":") { // range_start and range_end have been set ; } if (portop == "><") { dst_port_range_end--; dst_port_range_start++; } } QString ObjectSignature::toString() const { QStringList sig; sig << type_name; if ( ! object_name.isEmpty()) sig << object_name; if (type_name == IPv4::TYPENAME || type_name == IPv6::TYPENAME || type_name == Network::TYPENAME || type_name == NetworkIPv6::TYPENAME || type_name == Address::TYPENAME) sig << address << netmask; if (type_name == AddressRange::TYPENAME) sig << address_range_start << address_range_end; if (type_name == AttachedNetworks::TYPENAME) sig << parent_interface_name; if (type_name == DNSName::TYPENAME) sig << dns_name; if (type_name == AddressTable::TYPENAME) sig << address_table_name; if (type_name == CustomService::TYPENAME) sig << platform << code << protocol_name; if (type_name == ICMPService::TYPENAME || type_name == ICMP6Service::TYPENAME) sig << icmp_type << icmp_code; if (type_name == IPService::TYPENAME) sig << protocol << fragments << short_fragments << any_opt << dscp << tos << lsrr << ssrr << rr << ts << rtralt << rtralt_value; if (type_name == TCPService::TYPENAME) sig << src_port_range_start << src_port_range_end << dst_port_range_start << dst_port_range_end << established << flags_mask << flags_comp; if (type_name == UDPService::TYPENAME) sig << src_port_range_start << src_port_range_end << dst_port_range_start << dst_port_range_end; if (type_name == TagService::TYPENAME) sig << tag; if (type_name == ServiceGroup::TYPENAME || type_name == ObjectGroup::TYPENAME) sig << group_children_ids; if (type_name == UserService::TYPENAME) sig << protocol_name << user_id; return sig.join("||"); } void* ObjectSignature::dispatch(Network *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address = obj->getAddressPtr()->toString().c_str(); netmask = obj->getNetmaskPtr()->toString().c_str(); return this; } void* ObjectSignature::dispatch(NetworkIPv6 *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address = obj->getAddressPtr()->toString().c_str(); netmask = obj->getNetmaskPtr()->toString().c_str(); return this; } void* ObjectSignature::dispatch(IPv4 *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address = obj->getAddressPtr()->toString().c_str(); netmask = InetAddr::getAllOnes().toString().c_str(); return this; } void* ObjectSignature::dispatch(IPv6 *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address = obj->getAddressPtr()->toString().c_str(); netmask = InetAddr::getAllOnes(AF_INET6).toString().c_str(); return this; } void* ObjectSignature::dispatch(AddressRange *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address_range_start = obj->getRangeStart().toString().c_str(); address_range_end = obj->getRangeEnd().toString().c_str(); return this; } /* * Note that we do not track "compile time" / "run time" attribute of * the object because on import, only "run time" make sense */ void* ObjectSignature::dispatch(AddressTable *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address_table_name = QString::fromUtf8(obj->getSourceName().c_str()); return this; } /* * TODO: implement signature for DynamicGroup object so we can deduplicate them */ void* ObjectSignature::dispatch(DynamicGroup *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); return this; } void* ObjectSignature::dispatch(physAddress *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); address = obj->getPhysAddress().c_str(); return this; } void* ObjectSignature::dispatch(IPService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); protocol = obj->getProtocolNumber(); fragments = obj->getBool("fragm"); short_fragments = obj->getBool("short_fragm"); any_opt = obj->getBool("any_opt"); dscp = obj->getStr("dscp").c_str(); tos = obj->getStr("tos").c_str(); lsrr = obj->getBool("lsrr"); ssrr = obj->getBool("ssrr"); rr = obj->getBool("rr"); ts = obj->getBool("ts"); rtralt = obj->getBool("rtralt"); rtralt_value = obj->getBool("rtralt_value"); return this; } void* ObjectSignature::dispatch(ICMPService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); icmp_type = obj->getInt("type"); icmp_code = obj->getInt("code"); return this; } void* ObjectSignature::dispatch(ICMP6Service *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); icmp_type = obj->getInt("type"); icmp_code = obj->getInt("code"); return this; } void* ObjectSignature::dispatch(TCPService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); src_port_range_start = obj->getSrcRangeStart(); src_port_range_end = obj->getSrcRangeEnd(); dst_port_range_start = obj->getDstRangeStart(); dst_port_range_end = obj->getDstRangeEnd(); established = obj->getEstablished(); set flags = obj->getAllTCPFlags(); set::iterator it; for (it=flags.begin(); it!=flags.end(); ++it) flags_comp << *it; flags = obj->getAllTCPFlagMasks(); for (it=flags.begin(); it!=flags.end(); ++it) flags_mask << *it; qSort(flags_comp); qSort(flags_mask); return this; } void* ObjectSignature::dispatch(UDPService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); src_port_range_start = obj->getSrcRangeStart(); src_port_range_end = obj->getSrcRangeEnd(); dst_port_range_start = obj->getDstRangeStart(); dst_port_range_end = obj->getDstRangeEnd(); return this; } void* ObjectSignature::dispatch(CustomService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); platform = ""; code = ""; list platforms = obj->getAllKnownPlatforms(); foreach(std::string pl, platforms) { platform += pl.c_str(); code += obj->getCodeForPlatform(pl).c_str(); } protocol_name = obj->getProtocol().c_str(); return this; } void* ObjectSignature::dispatch(TagService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); tag = obj->getStr("tagcode").c_str(); return this; } /* * Note that we do not track "compile time" / "run time" attribute of * the object because on import, only "run time" make sense */ void* ObjectSignature::dispatch(DNSName *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); dns_name = obj->getSourceName().c_str(); return this; } void* ObjectSignature::dispatch(UserService *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); protocol_name = obj->getProtocolName().c_str(); user_id = obj->getUserId().c_str(); return this; } void* ObjectSignature::dispatch(AttachedNetworks *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); parent_interface_name = obj->getSourceName().c_str(); return this; } void* ObjectSignature::dispatch(ServiceGroup *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); for(FWObject::iterator it=obj->begin(); it!=obj->end(); ++it) { FWObject *c = FWReference::getObject(*it); group_children_ids << c->getId(); } return this; } void* ObjectSignature::dispatch(ObjectGroup *obj, void*) { object_name = QString::fromUtf8(obj->getName().c_str()); type_name = obj->getTypeName().c_str(); for(FWObject::iterator it=obj->begin(); it!=obj->end(); ++it) { FWObject *c = FWReference::getObject(*it); group_children_ids << c->getId(); } return this; } fwbuilder-5.1.0.3599/src/import/getServByName.h0000644000175000017500000000240211733011756021761 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GETSERVBYNAME_H_ #define _GETSERVBYNAME_H_ #include #include /* * Simple wrapper class for getservbyname() function to make sure we * get useful results even when this function does not work quite * right. */ class GetServByName { static QMap > ports; public: GetServByName() {}; static int getPortByName(const QString &name, const QString &proto); }; #endif fwbuilder-5.1.0.3599/src/import/getProtoByName.h0000644000175000017500000000251611733011756022153 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GETPROTOBYNAME_H_ #define _GETPROTOBYNAME_H_ #include #include /* * Simple wrapper class for getprotobyname() function to make sure we * get useful results even when this function does not work quite * right. For example, protocol "gre" does not resolve on Windows but * resolves to ip protocol 47 on Linux. */ class GetProtoByName { static QMap protocols; public: GetProtoByName() {}; static int getProtocolByName(const QString &name); }; #endif fwbuilder-5.1.0.3599/src/import/objectSignature.h0000644000175000017500000001441411733011756022404 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OBJECT_SIGNATURE_H_ #define _OBJECT_SIGNATURE_H_ #include "fwbuilder/FWObject.h" #include "fwbuilder/Dispatch.h" #include #include #include #include namespace libfwbuilder { class AddressRange; class AttachedNetworks; class Cluster; class CustomService; class Firewall; class Host; class ICMPService; class IPService; class IPv4; class IPv6; class Interface; class Library; class Network; class NetworkIPv6; class ObjectGroup; class ServiceGroup; class TCPService; class TagService; class UDPService; class physAddress; class UserService; class DynamicGroup; }; class ObjectMakerErrorTracker; class ObjectSignature : public libfwbuilder::Dispatch { static QMap > icmp_names; static QMap icmp_code_names; public: ObjectSignature(ObjectMakerErrorTracker *error_tracker); ObjectSignature(const ObjectSignature &other); ObjectMakerErrorTracker *error_tracker; bool port_range_inclusive; QString type_name; QString object_name; // for address-like objects QString address; QString netmask; QString address_range_start; QString address_range_end; QString dns_name; QString address_table_name; QString parent_interface_name; // for IP service int protocol; bool fragments; bool short_fragments; bool any_opt; QString dscp; QString tos; bool lsrr; bool ssrr; bool rr; bool ts; bool rtralt; bool rtralt_value; // for ICMP service int icmp_type; int icmp_code; // for tcp and udp int src_port_range_start; int src_port_range_end; int dst_port_range_start; int dst_port_range_end; // tcp only bool established; QList flags_mask; QList flags_comp; // custom service QString platform; QString protocol_name; QString code; // tag service QString tag; QList group_children_ids; // UserService QString user_id; // convenience methods that populate various attributes from // strings taken from imported configs void setAddress(const QString &s); void setNetmask(const QString &s, bool inverted_netmask=false); void setAddressRangeStart(const QString &s); void setAddressRangeEnd(const QString &s); void setProtocol(const QString &s); // set icmp type from string void setIcmpFromName(const QString &s); // set icmp code from string void setIcmpCodeFromName(const QString &s); // set icmp type from string that reads a number void setIcmpType(const QString &s); // set icmp code from string that reads a number void setIcmpCode(const QString &s); int portFromString(const QString &port_spec, const QString &proto, int default_port); void setSrcPortRange(const QString &range_start_spec, const QString &range_end_spec, const QString &proto); void setDstPortRange(const QString &range_start_spec, const QString &range_end_spec, const QString &proto); void setSrcPortRangeFromPortOpForCisco(const QString &port_op, const QString &port_spec, const QString &proto); void setDstPortRangeFromPortOpForCisco(const QString &port_op, const QString &port_spec, const QString &proto); void setSrcPortRangeFromPortOpForPF(const QString &port_op, const QString &port1, const QString &port2, const QString &proto); void setDstPortRangeFromPortOpForPF(const QString &port_op, const QString &port1, const QString &port2, const QString &proto); QString toString() const; // The following methods build signature from given object taking // into account its type virtual void* dispatch(libfwbuilder::Network*, void*); virtual void* dispatch(libfwbuilder::NetworkIPv6*, void*); virtual void* dispatch(libfwbuilder::IPv4*, void*); virtual void* dispatch(libfwbuilder::IPv6*, void*); virtual void* dispatch(libfwbuilder::AddressRange*, void*); virtual void* dispatch(libfwbuilder::AddressTable*, void*); virtual void* dispatch(libfwbuilder::physAddress*, void*); virtual void* dispatch(libfwbuilder::IPService*, void*); virtual void* dispatch(libfwbuilder::ICMPService*, void*); virtual void* dispatch(libfwbuilder::ICMP6Service*, void*); virtual void* dispatch(libfwbuilder::TCPService*, void*); virtual void* dispatch(libfwbuilder::UDPService*, void*); virtual void* dispatch(libfwbuilder::CustomService*, void*); virtual void* dispatch(libfwbuilder::TagService*, void*); virtual void* dispatch(libfwbuilder::DNSName*, void*); virtual void* dispatch(libfwbuilder::ObjectGroup*, void*); virtual void* dispatch(libfwbuilder::ServiceGroup*, void*); virtual void* dispatch(libfwbuilder::AttachedNetworks*, void*); virtual void* dispatch(libfwbuilder::UserService*, void*); virtual void* dispatch(libfwbuilder::DynamicGroup*, void*); }; #endif fwbuilder-5.1.0.3599/src/import/IOSImporter.h0000644000175000017500000000566011733011756021433 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FWB_POLICY_IMPORTER_IOS_H_ #define _FWB_POLICY_IMPORTER_IOS_H_ #include #include #include #include #include #include "Importer.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Logger.h" #include "fwbuilder/Policy.h" class IOSImporter : public Importer { protected: virtual libfwbuilder::FWObject* createTCPService(const QString &name=""); virtual libfwbuilder::FWObject* createUDPService(const QString &name=""); virtual libfwbuilder::FWObject* createTCPUDPServicePair(const QString &name=""); virtual libfwbuilder::FWObject* createTCPUDPNeqObject(const QString &proto, const QString &name=""); virtual ObjectSignature packObjectSignatureTCPService(); virtual ObjectSignature packObjectSignatureUDPService(); public: IOSImporter(libfwbuilder::FWObject *lib, std::istringstream &input, libfwbuilder::Logger *log, const std::string &fwname); ~IOSImporter(); virtual void run(); virtual void setInterfaceAndDirectionForRuleSet(const std::string &ruleset_name, const std::string &interface_name, const std::string &dir); virtual void ignoreCurrentInterface(); virtual void pushRule(); // this method actually adds interfaces to the firewall object // and does final clean up. virtual libfwbuilder::Firewall* finalize(); class MergeRules { std::string ruleset_name; libfwbuilder::FWObject *intf; libfwbuilder::PolicyRule::Direction dir; libfwbuilder::FWObject *target_ruleset; public: MergeRules(const std::string &_n, libfwbuilder::FWObject *i, libfwbuilder::PolicyRule::Direction d, libfwbuilder::FWObject *_rs) { ruleset_name = _n; intf = i; dir = d; target_ruleset = _rs; } void move(libfwbuilder::FWObject* r); }; }; #endif fwbuilder-5.1.0.3599/src/import/import.pro0000644000175000017500000000250511733011756021135 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib # SOURCES = QStringListOperators.cpp \ PreImport.cpp \ objectMaker.cpp \ objectSignature.cpp \ addressObjectMaker.cpp \ serviceObjectMaker.cpp \ getProtoByName.cpp \ getServByName.cpp \ Importer.cpp \ IOSImporter.cpp \ IOSImporterRun.cpp \ IPTImporter.cpp \ IPTImporterRun.cpp \ PIXImporter.cpp \ PIXImporterNat.cpp \ PIXImporterRun.cpp \ PFImporter.cpp \ PFImporterRun.cpp \ HEADERS = QStringListOperators.h \ PreImport.h \ objectMaker.h \ objectSignature.h \ addressObjectMaker.h \ serviceObjectMaker.h \ getProtoByName.h \ getServByName.h \ Importer.h \ IOSImporter.h \ IPTImporter.h \ PIXImporter.h \ PFImporter.h \ InterfaceSpec.h \ AddressSpec.h \ PortSpec.h \ IcmpSpec.h \ RouteSpec.h \ CONFIG += staticlib # need to add "." for g++ on mingw INCLUDEPATH += $$ANTLR_INCLUDEPATH ../libfwbuilder/src ../compiler_lib . DEPENDPATH += $$ANTLR_INCLUDEPATH ../libfwbuilder/src ../compiler_lib LIBS += $$ANTLR_LIBS DEFINES += $$ANTLR_DEFINES TARGET = import INSTALLS -= target fwbuilder-5.1.0.3599/src/import/PreImport.h0000644000175000017500000000315711733011756021177 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PRE_IMPORTER_H_ #define _PRE_IMPORTER_H_ #include #include class matchPFDirection { public: virtual bool operator()(const QString&) {return false;} }; /* * This class scans firewall configuration and tries to guess platform * and some other parameters */ class PreImport { const QStringList *buffer; public: enum Platforms { UNKNOWN, IPTABLES, IPTABLES_WITH_COUNTERS, PF, PF_REVERSE, IOSACL, PIX, FWSM } ; private: enum Platforms platform; public: PreImport(const QStringList *buf) { buffer = buf; platform = UNKNOWN; } void scan(); enum Platforms getPlatform() { return platform; } QString getPlatformAsString(); bool isReversePFConfigurationStyle(matchPFDirection &dir_op); }; #endif fwbuilder-5.1.0.3599/src/import/getProtoByName.cpp0000644000175000017500000000726711733011756022516 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "getProtoByName.h" #ifndef _WIN32 # include # include #else # include #endif QMap GetProtoByName::protocols; int GetProtoByName::getProtocolByName(const QString &name) { if (protocols.size() == 0) { protocols["icmp"] = 1; protocols["igmp"] = 2; protocols["ggp"] = 3; protocols["ipencap"] = 4; protocols["st"] = 5; protocols["tcp"] = 6; protocols["egp"] = 8; protocols["igp"] = 9; protocols["pup"] = 12; protocols["udp"] = 17; protocols["hmp"] = 20; protocols["xns-idp"] = 22; protocols["rdp"] = 27; protocols["iso-tp4"] = 29; protocols["xtp"] = 36; protocols["ddp"] = 37; protocols["idpr-cmtp"] = 38; protocols["ipv6"] = 41; protocols["ipv6-route"] = 43; protocols["ipv6-frag"]= 44; protocols["idrp"] = 45; protocols["rsvp"] = 46; protocols["gre"] = 47; protocols["esp"] = 50; protocols["ah"] = 51; protocols["skip"] = 57; protocols["ipv6-icmp"] = 58; protocols["ipv6-nonxt"] = 59; protocols["ipv6-opts"] = 60; protocols["rspf"] = 73; protocols["vmtp"] = 81; protocols["eigrp"] = 88; protocols["ospf"] = 89; protocols["ax.25"] = 93; protocols["ipip"] = 94; protocols["etherip"] = 97; protocols["encap"] = 98; protocols["pim"] = 103; protocols["ipcomp"] = 108; protocols["vrrp"] = 112; protocols["l2tp"] = 115; protocols["isis"] = 124; protocols["sctp"] = 132; protocols["fc"] = 133; protocols["udplite"] = 136; protocols["mpls-in-ip"] = 137; protocols["manet"] = 138; protocols["hip"] = 139; // these are found in Cisco configs. Some of these names // duplicate protocols listed above but a few are extras. protocols["ah"] = 51; protocols["ahp"] = 51; protocols["eigrp"] = 88; protocols["esp"] = 50; protocols["gre"] = 47; protocols["igmp"] = 2; protocols["igrp"] = 9; protocols["ip"] = 0; protocols["ipinip"] = 4; protocols["nos"] = 94; protocols["ospf"] = 89; protocols["pim"] = 103; protocols["pcp"] = 108; protocols["snp"] = 109; // ASA configs use protocol name "ipsec" as an alias for "esp" // and "pptp" as an alias for "gre" protocols["ipsec"] = 50; protocols["pptp"] = 47; } bool ok = false; int protocol = name.toInt(&ok); if (ok) return protocol; if (protocols.contains(name)) return protocols[name]; struct protoent *pe = getprotobyname(name.toAscii().constData()); if (pe!=NULL) return pe->p_proto; return -1; } fwbuilder-5.1.0.3599/src/import/InterfaceSpec.h0000644000175000017500000000436311733011756021771 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _INTERFACE_SPEC_H_ #define _INTERFACE_SPEC_H_ #include #include #include #include #include "AddressSpec.h" class InterfaceSpec { public: bool neg; std::string name; std::string label; std::list as; std::string hwaddr; std::list groups; InterfaceSpec() { neg = false; name = ""; label = ""; } InterfaceSpec(const InterfaceSpec &other) { neg = other.neg; name = other.name; label = other.label; as = other.as; hwaddr = other.hwaddr; groups = other.groups; } InterfaceSpec(bool _neg, const std::string _name) { neg = _neg; name = _name; } // This function is mostly used in unit tests QString toString() { QStringList str; str << "InterfaceSpec"; str << QString("name:%1").arg(name.c_str()); str << QString("label:%1").arg(label.c_str()); str << QString((neg)? "neg:true" : "neg:false"); str << QString("hwaddr:%1").arg(hwaddr.c_str()); for (std::list::iterator i=as.begin(); i!=as.end(); ++i) str << i->toString(); for (std::list::iterator i=groups.begin(); i!=groups.end(); ++i) str << QString("group:%1").arg((*i).c_str()); return str.join("|"); } }; #endif fwbuilder-5.1.0.3599/src/import/Importer.h0000644000175000017500000003144111733011756021054 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FWB_POLICY_IMPORTER_H_ #define _FWB_POLICY_IMPORTER_H_ #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Logger.h" #include "objectMaker.h" #include "addressObjectMaker.h" #include "serviceObjectMaker.h" #include #include #include #include #include #include typedef std::pair str_tuple; typedef std::vector str_vector; class Importer; /* * Used for platforms where interface and direction are set for the * whole ruleset (like in router access lists), as opposed to * platforms where interface and direction are set on a per-rule basis * (iptables) */ class UnidirectionalRuleSet { public: libfwbuilder::RuleSet* ruleset; std::string name; // interface names and directions std::map intf_dir; libfwbuilder::PolicyRule::Action default_action; int created_from_line_number; int default_action_line_number; bool to_be_deleted; UnidirectionalRuleSet() { created_from_line_number = -1; default_action_line_number = -1; default_action = libfwbuilder::PolicyRule::Deny; to_be_deleted = false; } }; class ImporterException : public std::exception { QString err; public: ImporterException(const std::string &e) { err = e.c_str(); } ImporterException(const QString &e) { err = e; } virtual ~ImporterException() throw() {} QString toString() { return err; } virtual const char* what() const throw() { return err.toStdString().c_str(); } }; class Importer { // firewall object // one instance of Importer creates only one firewall object. // // Do not access this member directly, always use getFirewallObject() // This ensures the object is created only when it is needed // so that if we get ane xception in parser early, we do not // create unnecessary object libfwbuilder::Firewall *fw; std::string fwname; protected: AddressObjectMaker *address_maker; ServiceObjectMaker *service_maker; int error_counter; // line number in the original stream being imported int current_line_number; libfwbuilder::FWObject *library; std::string input_file_name; std::istringstream &input; std::string platform; std::string discovered_platform; std::string discovered_version; std::string user_choice_host_os; std::string user_choice_version; libfwbuilder::Interface* current_interface; // map : ruleset name : ruleset // in case of IOS ACls or PIX policy ruleset name == acl name // all other platforms have single ruleset for policy // and another for NAT std::map all_rulesets; // map : interface name : interface std::map all_interfaces; // map : object signature : object // use this to quickly find objects to avoid creating duplicates std::map all_objects; // registry of broken objects. Sometimes we create an AddressTable // or a group object during import that may have some kind of a problem // that we leave for the user to fix manually. In order to be able to mark // all rules that use this object as "broken", we should register these // broken objects somewhere. std::map broken_objects; UnidirectionalRuleSet* current_ruleset; libfwbuilder::Rule* current_rule; void addAddressObjectToInterface(libfwbuilder::Interface*intf, const std::string &addr, const std::string &netm); std::string getBadRuleColor(); // this method returns fw. It is created if fw==NULL // Using getFirewallObject() instead of accessing fw directly // provides a way to create firewall object only when // it is really needed. libfwbuilder::Firewall* getFirewallObject(); // need to be able to tell if firewall object has really // been created during import. If the file is empty or in case of // a parser error firewall object may not have been created. // However in other cases there could have been an error after // the object was created. This method allows us to tell one // situation from another. bool haveFirewallObject() { return (fw!=NULL); } // checks if ruleset "rsname" exists. Returns pointer if yes, // otherwise returns NULL virtual UnidirectionalRuleSet* checkUnidirRuleSet(const std::string &rsname); // finds and rturns pointer to ruleset "rsname". If it does not // exists, it is created virtual UnidirectionalRuleSet* getUnidirRuleSet( const std::string &ruleset_name, const std::string &ruleset_type_name); virtual libfwbuilder::FWObject* createTCPService(const QString &name=""); virtual libfwbuilder::FWObject* createUDPService(const QString &name=""); // create libfwbuilder::ObjectGroup and place all interfaces in it // argument represents a list of interface names virtual libfwbuilder::FWObject* createGroupOfInterfaces( const std::string &ruleset_name, std::list &interfaces); virtual libfwbuilder::FWObject* makeAddressObj(const std::string addr, const std::string netm); virtual libfwbuilder::FWObject* makeSrcObj(); virtual libfwbuilder::FWObject* makeDstObj(); virtual libfwbuilder::FWObject* makeSrvObj(); // importer may need to create multiple objects for // either rule element for some platforms. It is more convenient to // make these special virtual methods rather than use createAddress // and createService every time. virtual void addSrc(); virtual void addDst(); virtual void addSrv(); virtual void addOSrc(); virtual void addODst(); virtual void addOSrv(); virtual void addLogging(); void registerBrokenObject(libfwbuilder::FWObject *o, const QString &err); bool isObjectBroken(libfwbuilder::FWObject*); QString getBrokenObjectError(libfwbuilder::FWObject*); public: ObjectMakerErrorTracker *error_tracker; // making logger public so I can access it from the code in the grammar libfwbuilder::Logger *logger; QStringList last_comment; bool add_standard_comments; // temporary variables used by parser to store values // Importer converts these into a proper rule using method // pushRule() // Method clear() resets all these variables to their defaults. // // TODO: need to add more variables to cover everything needed // for NAT rules std::string action; std::string protocol; std::string rule_comment; std::string src_a; std::string src_nm; std::string src_port_op; std::string src_port_spec; std::string dst_a; std::string dst_nm; std::string dst_port_op; std::string dst_port_spec; std::string tmp_a; std::string tmp_nm; std::string tmp_port_op; std::string tmp_port_spec; std::string tmp_port_spec_2; std::string tmp_range_1; std::string tmp_range_2; int tmp_tcp_flag_code; QList tmp_tcp_flags_list; QList tcp_flags_mask; QList tcp_flags_comp; bool logging; std::string log_level; std::string log_interval; bool established; bool fragments; std::string icmp_spec; std::string icmp_code; std::string icmp_type; std::string time_range_name; void SaveTmpAddrToSrc(); void SaveTmpAddrToDst(); void SaveTmpPortToSrc(); void SaveTmpPortToDst(); void setSrcSelf(); void setDstSelf(); virtual void clear(); Importer(libfwbuilder::FWObject *lib, const std::string &platform, std::istringstream &input, libfwbuilder::Logger *log, const std::string &fwname); virtual ~Importer(); virtual void run(); void setFileName(const std::string &fn) { input_file_name = fn; } void setPlatform(const std::string &pl) { platform = pl; } void prepareForDeduplication(); // add standard line to rule comment, this adds something like // "created during import from , line " virtual void addStandardImportComment(libfwbuilder::FWObject *obj, const QString &additional_comment); virtual libfwbuilder::FWObject* commitObject(libfwbuilder::FWObject *obj); int errorCounter() { return error_counter; } virtual void setDiscoveredPlatform(const std::string &v); virtual void setDiscoveredVersion(const std::string &v); void setUserChoiceHostOS(const std::string &s) { user_choice_host_os = s; } void setUserChoiceVersion(const std::string &s) { user_choice_version = s; } void setAddStandardCommentsFlag(bool f) { add_standard_comments = f; } virtual void setHostName(const std::string &hn); virtual libfwbuilder::Interface* newInterface(const std::string &interface_name); virtual void clearCurrentInterface() { current_interface = NULL; } virtual void ignoreCurrentInterface(); virtual void addInterfaceAddress(const std::string &a, const std::string &nm); virtual void addInterfaceAddress(const std::string &label, const std::string &a, const std::string &nm); virtual void setInterfaceComment(const std::string &descr); virtual void setInterfaceLabel(const std::string &descr); virtual void setInterfaceSecurityLevel(const std::string &seclevel); virtual void setInterfaceParametes(const std::string &phys_intf, const std::string &label, const std::string &sec_level); virtual void setInterfaceVlanId(const std::string &vlan_id); virtual void addRuleComment(const std::string &comm); /** * create new unidirectional ruleset. Unidirectional ruleset * has interface association and direction that apply to all rules * in the set. */ virtual void newUnidirRuleSet(const std::string &name, const std::string &ruleset_type); /** * Sets default action for the current rule set. */ virtual void setDefaultAction(const std::string &iptables_action_name); /** * add interface and direction setting to a ruleset. Note that the * same ruleset may be associated with multiple interfaces and * each association may have its own direction. */ virtual void setInterfaceAndDirectionForRuleSet( const std::string &ruleset_name, const std::string &interface_name, const std::string &dir); virtual void setInterfaceAndDirectionForRuleSet( libfwbuilder::Interface *intf, const std::string &ruleset_name, const std::string &dir); virtual void newPolicyRule(); virtual void newNATRule(); virtual void pushRule(); void setCurrentLineNumber(int n) { current_line_number = n; } int getCurrentLineNumber() { return current_line_number;} void markCurrentRuleBad(); void reportError(const std::string &comment); void reportError(const QString &comment); // this method actually adds interfaces to the firewall object // and does final clean up. virtual libfwbuilder::Firewall* finalize(); int countRules(); int countInterfaces(); QString noFirewallErrorMessage(); QString noRulesErrorMessage(); QString noInterfacesErrorMessage(); QString commonFailureErrorMessage(); // statistics int getNumberOfRuleSets(); int getTotalNumberOfRules(); int getNumberOfInterfaces(); void addMessageToLog(const std::string &msg); void addMessageToLog(const QString &msg); void rearrangeVlanInterfaces(); }; #endif fwbuilder-5.1.0.3599/src/import/getServByName.cpp0000644000175000017500000007050111733011756022321 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "getServByName.h" #ifndef _WIN32 # include # include #else # include #endif QMap > GetServByName::ports; int GetServByName::getPortByName(const QString &name, const QString &proto) { if (ports.size() == 0) { ports["tcp"]["tcpmux"] = 1; ports["tcp"]["echo"] = 7; ports["tcp"]["discard"] = 9; ports["tcp"]["systat"] = 11; ports["tcp"]["daytime"] = 13; ports["tcp"]["netstat"] = 15; ports["tcp"]["qotd"] = 17; ports["tcp"]["msp"] = 18; ports["tcp"]["chargen"] = 19; ports["tcp"]["ftp-data"] = 20; ports["tcp"]["ftp"] = 21; ports["tcp"]["ssh"] = 22; ports["tcp"]["telnet"] = 23; ports["tcp"]["smtp"] = 25; ports["tcp"]["time"] = 37; ports["tcp"]["nameserver"] = 42; ports["tcp"]["whois"] = 43; ports["tcp"]["tacacs"] = 49; ports["tcp"]["re-mail-ck"] = 50; ports["tcp"]["domain"] = 53; ports["tcp"]["mtp"] = 57; ports["tcp"]["tacacs-ds"] = 65; ports["tcp"]["bootps"] = 67; ports["tcp"]["bootpc"] = 68; ports["tcp"]["gopher"] = 70; ports["tcp"]["rje"] = 77; ports["tcp"]["finger"] = 79; ports["tcp"]["www"] = 80; ports["tcp"]["link"] = 87; ports["tcp"]["kerberos"] = 88; ports["tcp"]["supdup"] = 95; ports["tcp"]["hostnames"] = 101; ports["tcp"]["iso-tsap"] = 102; ports["tcp"]["acr-nema"] = 104; ports["tcp"]["csnet-ns"] = 105; ports["tcp"]["rtelnet"] = 107; ports["tcp"]["pop2"] = 109; ports["tcp"]["pop3"] = 110; ports["tcp"]["sunrpc"] = 111; ports["tcp"]["auth"] = 113; ports["tcp"]["sftp"] = 115; ports["tcp"]["uucp-path"] = 117; ports["tcp"]["nntp"] = 119; ports["tcp"]["ntp"] = 123; ports["tcp"]["pwdgen"] = 129; ports["tcp"]["loc-srv"] = 135; ports["tcp"]["netbios-ns"] = 137; ports["tcp"]["netbios-dgm"] = 138; ports["tcp"]["netbios-ssn"] = 139; ports["tcp"]["imap2"] = 143; ports["tcp"]["snmp"] = 161; ports["tcp"]["snmp-trap"] = 162; ports["tcp"]["cmip-man"] = 163; ports["tcp"]["cmip-agent"] = 164; ports["tcp"]["mailq"] = 174; ports["tcp"]["xdmcp"] = 177; ports["tcp"]["nextstep"] = 178; ports["tcp"]["bgp"] = 179; ports["tcp"]["prospero"] = 191; ports["tcp"]["irc"] = 194; ports["tcp"]["smux"] = 199; ports["tcp"]["at-rtmp"] = 201; ports["tcp"]["at-nbp"] = 202; ports["tcp"]["at-echo"] = 204; ports["tcp"]["at-zis"] = 206; ports["tcp"]["qmtp"] = 209; ports["tcp"]["z3950"] = 210; ports["tcp"]["ipx"] = 213; ports["tcp"]["imap3"] = 220; ports["tcp"]["pawserv"] = 345; ports["tcp"]["zserv"] = 346; ports["tcp"]["fatserv"] = 347; ports["tcp"]["rpc2portmap"] = 369; ports["tcp"]["codaauth2"] = 370; ports["tcp"]["clearcase"] = 371; ports["tcp"]["ulistserv"] = 372; ports["tcp"]["ldap"] = 389; ports["tcp"]["imsp"] = 406; ports["tcp"]["https"] = 443; ports["tcp"]["snpp"] = 444; ports["tcp"]["microsoft-ds"] = 445; ports["tcp"]["kpasswd"] = 464; ports["tcp"]["saft"] = 487; ports["tcp"]["isakmp"] = 500; ports["tcp"]["rtsp"] = 554; ports["tcp"]["nqs"] = 607; ports["tcp"]["npmp-local"] = 610; ports["tcp"]["npmp-gui"] = 611; ports["tcp"]["hmmp-ind"] = 612; ports["tcp"]["qmqp"] = 628; ports["tcp"]["ipp"] = 631; ports["tcp"]["exec"] = 512; ports["tcp"]["login"] = 513; ports["tcp"]["shell"] = 514; ports["tcp"]["printer"] = 515; ports["tcp"]["tempo"] = 526; ports["tcp"]["courier"] = 530; ports["tcp"]["conference"] = 531; ports["tcp"]["netnews"] = 532; ports["tcp"]["gdomap"] = 538; ports["tcp"]["uucp"] = 540; ports["tcp"]["klogin"] = 543; ports["tcp"]["kshell"] = 544; ports["tcp"]["afpovertcp"] = 548; ports["tcp"]["remotefs"] = 556; ports["tcp"]["nntps"] = 563; ports["tcp"]["submission"] = 587; ports["tcp"]["ldaps"] = 636; ports["tcp"]["tinc"] = 655; ports["tcp"]["silc"] = 706; ports["tcp"]["kerberos-adm"] = 749; ports["tcp"]["webster"] = 765; ports["tcp"]["rsync"] = 873; ports["tcp"]["ftps-data"] = 989; ports["tcp"]["ftps"] = 990; ports["tcp"]["telnets"] = 992; ports["tcp"]["imaps"] = 993; ports["tcp"]["ircs"] = 994; ports["tcp"]["pop3s"] = 995; ports["tcp"]["socks"] = 1080; ports["tcp"]["proofd"] = 1093; ports["tcp"]["rootd"] = 1094; ports["tcp"]["openvpn"] = 1194; ports["tcp"]["rmiregistry"] = 1099; ports["tcp"]["kazaa"] = 1214; ports["tcp"]["nessus"] = 1241; ports["tcp"]["lotusnote"] = 1352; ports["tcp"]["ms-sql-s"] = 1433; ports["tcp"]["ms-sql-m"] = 1434; ports["tcp"]["ingreslock"] = 1524; ports["tcp"]["prospero-np"] = 1525; ports["tcp"]["datametrics"] = 1645; ports["tcp"]["sa-msg-port"] = 1646; ports["tcp"]["kermit"] = 1649; ports["tcp"]["l2f"] = 1701; ports["tcp"]["radius"] = 1812; ports["tcp"]["radius-acct"] = 1813; ports["tcp"]["msnp"] = 1863; ports["tcp"]["unix-status"] = 1957; ports["tcp"]["log-server"] = 1958; ports["tcp"]["remoteping"] = 1959; ports["tcp"]["cisco-sccp"] = 2000; ports["tcp"]["search"] = 2010; ports["tcp"]["pipe_server"] = 2010; ports["tcp"]["nfs"] = 2049; ports["tcp"]["gnunet"] = 2086; ports["tcp"]["rtcm-sc104"] = 2101; ports["tcp"]["cvspserver"] = 2401; ports["tcp"]["venus"] = 2430; ports["tcp"]["venus-se"] = 2431; ports["tcp"]["codasrv"] = 2432; ports["tcp"]["codasrv-se"] = 2433; ports["tcp"]["mon"] = 2583; ports["tcp"]["dict"] = 2628; ports["tcp"]["gpsd"] = 2947; ports["tcp"]["gds_db"] = 3050; ports["tcp"]["icpv2"] = 3130; ports["tcp"]["mysql"] = 3306; ports["tcp"]["nut"] = 3493; ports["tcp"]["distcc"] = 3632; ports["tcp"]["daap"] = 3689; ports["tcp"]["svn"] = 3690; ports["tcp"]["suucp"] = 4031; ports["tcp"]["sysrqd"] = 4094; ports["tcp"]["remctl"] = 4373; ports["tcp"]["iax"] = 4569; ports["tcp"]["radmin-port"] = 4899; ports["tcp"]["rfe"] = 5002; ports["tcp"]["mmcc"] = 5050; ports["tcp"]["sip"] = 5060; ports["tcp"]["sip-tls"] = 5061; ports["tcp"]["aol"] = 5190; ports["tcp"]["xmpp-client"] = 5222; ports["tcp"]["xmpp-server"] = 5269; ports["tcp"]["cfengine"] = 5308; ports["tcp"]["mdns"] = 5353; ports["tcp"]["postgresql"] = 5432; ports["tcp"]["freeciv"] = 5556; ports["tcp"]["ggz"] = 5688; ports["tcp"]["x11"] = 6000; ports["tcp"]["x11-1"] = 6001; ports["tcp"]["x11-2"] = 6002; ports["tcp"]["x11-3"] = 6003; ports["tcp"]["x11-4"] = 6004; ports["tcp"]["x11-5"] = 6005; ports["tcp"]["x11-6"] = 6006; ports["tcp"]["x11-7"] = 6007; ports["tcp"]["gnutella-svc"] = 6346; ports["tcp"]["gnutella-rtr"] = 6347; ports["tcp"]["sge_qmaster"] = 6444; ports["tcp"]["sge_execd"] = 6445; ports["tcp"]["afs3-fileserver"] = 7000; ports["tcp"]["afs3-callback"] = 7001; ports["tcp"]["afs3-prserver"] = 7002; ports["tcp"]["afs3-vlserver"] = 7003; ports["tcp"]["afs3-kaserver"] = 7004; ports["tcp"]["afs3-volser"] = 7005; ports["tcp"]["afs3-errors"] = 7006; ports["tcp"]["afs3-bos"] = 7007; ports["tcp"]["afs3-update"] = 7008; ports["tcp"]["afs3-rmtsys"] = 7009; ports["tcp"]["font-service"] = 7100; ports["tcp"]["http-alt"] = 8080; ports["tcp"]["bacula-dir"] = 9101; ports["tcp"]["bacula-fd"] = 9102; ports["tcp"]["bacula-sd"] = 9103; ports["tcp"]["amanda"] = 10080; ports["tcp"]["hkp"] = 11371; ports["tcp"]["bprd"] = 13720; ports["tcp"]["bpdbm"] = 13721; ports["tcp"]["bpjava-msvc"] = 13722; ports["tcp"]["vnetd"] = 13724; ports["tcp"]["bpcd"] = 13782; ports["tcp"]["vopied"] = 13783; ports["tcp"]["wnn6"] = 22273; ports["tcp"]["kerberos4"] = 750; ports["tcp"]["kerberos_master"] = 751; ports["tcp"]["krb_prop"] = 754; ports["tcp"]["krbupdate"] = 760; ports["tcp"]["swat"] = 901; ports["tcp"]["kpop"] = 1109; ports["tcp"]["knetd"] = 2053; ports["tcp"]["eklogin"] = 2105; ports["tcp"]["kx"] = 2111; ports["tcp"]["iprop"] = 2121; ports["tcp"]["supfilesrv"] = 871; ports["tcp"]["supfiledbg"] = 1127; ports["tcp"]["linuxconf"] = 98; ports["tcp"]["poppassd"] = 106; ports["tcp"]["ssmtp"] = 465; ports["tcp"]["moira_db"] = 775; ports["tcp"]["moira_update"] = 777; ports["tcp"]["spamd"] = 783; ports["tcp"]["omirr"] = 808; ports["tcp"]["customs"] = 1001; ports["tcp"]["skkserv"] = 1178; ports["tcp"]["rmtcfg"] = 1236; ports["tcp"]["wipld"] = 1300; ports["tcp"]["xtel"] = 1313; ports["tcp"]["xtelw"] = 1314; ports["tcp"]["support"] = 1529; ports["tcp"]["cfinger"] = 2003; ports["tcp"]["frox"] = 2121; ports["tcp"]["ninstall"] = 2150; ports["tcp"]["zebrasrv"] = 2600; ports["tcp"]["zebra"] = 2601; ports["tcp"]["ripd"] = 2602; ports["tcp"]["ripngd"] = 2603; ports["tcp"]["ospfd"] = 2604; ports["tcp"]["bgpd"] = 2605; ports["tcp"]["ospf6d"] = 2606; ports["tcp"]["ospfapi"] = 2607; ports["tcp"]["isisd"] = 2608; ports["tcp"]["afbackup"] = 2988; ports["tcp"]["afmbackup"] = 2989; ports["tcp"]["xtell"] = 4224; ports["tcp"]["fax"] = 4557; ports["tcp"]["hylafax"] = 4559; ports["tcp"]["distmp3"] = 4600; ports["tcp"]["munin"] = 4949; ports["tcp"]["enbd-cstatd"] = 5051; ports["tcp"]["enbd-sstatd"] = 5052; ports["tcp"]["pcrd"] = 5151; ports["tcp"]["noclog"] = 5354; ports["tcp"]["hostmon"] = 5355; ports["tcp"]["nsca"] = 5667; ports["tcp"]["mrtd"] = 5674; ports["tcp"]["bgpsim"] = 5675; ports["tcp"]["canna"] = 5680; ports["tcp"]["sane-port"] = 6566; ports["tcp"]["ircd"] = 6667; ports["tcp"]["zope-ftp"] = 8021; ports["tcp"]["tproxy"] = 8081; ports["tcp"]["omniorb"] = 8088; ports["tcp"]["clc-build-daemon"] = 8990; ports["tcp"]["xinetd"] = 9098; ports["tcp"]["git"] = 9418; ports["tcp"]["zope"] = 9673; ports["tcp"]["webmin"] = 10000; ports["tcp"]["kamanda"] = 10081; ports["tcp"]["amandaidx"] = 10082; ports["tcp"]["amidxtape"] = 10083; ports["tcp"]["smsqp"] = 11201; ports["tcp"]["xpilot"] = 15345; ports["tcp"]["sgi-cad"] = 17004; ports["tcp"]["isdnlog"] = 20011; ports["tcp"]["vboxd"] = 20012; ports["tcp"]["binkp"] = 24554; ports["tcp"]["asp"] = 27374; ports["tcp"]["csync2"] = 30865; ports["tcp"]["dircproxy"] = 57000; ports["tcp"]["tfido"] = 60177; ports["tcp"]["fido"] = 60179; ports["udp"]["echo"] = 7; ports["udp"]["discard"] = 9; ports["udp"]["daytime"] = 13; ports["udp"]["msp"] = 18; ports["udp"]["chargen"] = 19; ports["udp"]["fsp"] = 21; ports["udp"]["ssh"] = 22; ports["udp"]["time"] = 37; ports["udp"]["rlp"] = 39; ports["udp"]["tacacs"] = 49; ports["udp"]["re-mail-ck"] = 50; ports["udp"]["domain"] = 53; ports["udp"]["tacacs-ds"] = 65; ports["udp"]["bootps"] = 67; ports["udp"]["bootpc"] = 68; ports["udp"]["tftp"] = 69; ports["udp"]["gopher"] = 70; ports["udp"]["www"] = 80; ports["udp"]["kerberos"] = 88; ports["udp"]["acr-nema"] = 104; ports["udp"]["csnet-ns"] = 105; ports["udp"]["rtelnet"] = 107; ports["udp"]["pop2"] = 109; ports["udp"]["pop3"] = 110; ports["udp"]["sunrpc"] = 111; ports["udp"]["ntp"] = 123; ports["udp"]["pwdgen"] = 129; ports["udp"]["loc-srv"] = 135; ports["udp"]["netbios-ns"] = 137; ports["udp"]["netbios-dgm"] = 138; ports["udp"]["netbios-ssn"] = 139; ports["udp"]["imap2"] = 143; ports["udp"]["snmp"] = 161; ports["udp"]["snmp-trap"] = 162; ports["udp"]["cmip-man"] = 163; ports["udp"]["cmip-agent"] = 164; ports["udp"]["mailq"] = 174; ports["udp"]["xdmcp"] = 177; ports["udp"]["nextstep"] = 178; ports["udp"]["bgp"] = 179; ports["udp"]["prospero"] = 191; ports["udp"]["irc"] = 194; ports["udp"]["smux"] = 199; ports["udp"]["at-rtmp"] = 201; ports["udp"]["at-nbp"] = 202; ports["udp"]["at-echo"] = 204; ports["udp"]["at-zis"] = 206; ports["udp"]["qmtp"] = 209; ports["udp"]["z3950"] = 210; ports["udp"]["ipx"] = 213; ports["udp"]["imap3"] = 220; ports["udp"]["pawserv"] = 345; ports["udp"]["zserv"] = 346; ports["udp"]["fatserv"] = 347; ports["udp"]["rpc2portmap"] = 369; ports["udp"]["codaauth2"] = 370; ports["udp"]["clearcase"] = 371; ports["udp"]["ulistserv"] = 372; ports["udp"]["ldap"] = 389; ports["udp"]["imsp"] = 406; ports["udp"]["https"] = 443; ports["udp"]["snpp"] = 444; ports["udp"]["microsoft-ds"] = 445; ports["udp"]["kpasswd"] = 464; ports["udp"]["saft"] = 487; ports["udp"]["isakmp"] = 500; ports["udp"]["rtsp"] = 554; ports["udp"]["nqs"] = 607; ports["udp"]["npmp-local"] = 610; ports["udp"]["npmp-gui"] = 611; ports["udp"]["hmmp-ind"] = 612; ports["udp"]["qmqp"] = 628; ports["udp"]["ipp"] = 631; ports["udp"]["biff"] = 512; ports["udp"]["who"] = 513; ports["udp"]["syslog"] = 514; ports["udp"]["talk"] = 517; ports["udp"]["ntalk"] = 518; ports["udp"]["route"] = 520; ports["udp"]["timed"] = 525; ports["udp"]["netwall"] = 533; ports["udp"]["gdomap"] = 538; ports["udp"]["afpovertcp"] = 548; ports["udp"]["nntps"] = 563; ports["udp"]["submission"] = 587; ports["udp"]["ldaps"] = 636; ports["udp"]["tinc"] = 655; ports["udp"]["silc"] = 706; ports["udp"]["webster"] = 765; ports["udp"]["rsync"] = 873; ports["udp"]["telnets"] = 992; ports["udp"]["imaps"] = 993; ports["udp"]["ircs"] = 994; ports["udp"]["pop3s"] = 995; ports["udp"]["socks"] = 1080; ports["udp"]["proofd"] = 1093; ports["udp"]["rootd"] = 1094; ports["udp"]["openvpn"] = 1194; ports["udp"]["rmiregistry"] = 1099; ports["udp"]["kazaa"] = 1214; ports["udp"]["nessus"] = 1241; ports["udp"]["lotusnote"] = 1352; ports["udp"]["ms-sql-s"] = 1433; ports["udp"]["ms-sql-m"] = 1434; ports["udp"]["ingreslock"] = 1524; ports["udp"]["prospero-np"] = 1525; ports["udp"]["datametrics"] = 1645; ports["udp"]["sa-msg-port"] = 1646; ports["udp"]["kermit"] = 1649; ports["udp"]["l2f"] = 1701; ports["udp"]["radius"] = 1812; ports["udp"]["radius-acct"] = 1813; ports["udp"]["msnp"] = 1863; ports["udp"]["cisco-sccp"] = 2000; ports["udp"]["nfs"] = 2049; ports["udp"]["gnunet"] = 2086; ports["udp"]["rtcm-sc104"] = 2101; ports["udp"]["cvspserver"] = 2401; ports["udp"]["venus"] = 2430; ports["udp"]["venus-se"] = 2431; ports["udp"]["codasrv"] = 2432; ports["udp"]["codasrv-se"] = 2433; ports["udp"]["mon"] = 2583; ports["udp"]["dict"] = 2628; ports["udp"]["gpsd"] = 2947; ports["udp"]["gds_db"] = 3050; ports["udp"]["icpv2"] = 3130; ports["udp"]["mysql"] = 3306; ports["udp"]["nut"] = 3493; ports["udp"]["distcc"] = 3632; ports["udp"]["daap"] = 3689; ports["udp"]["svn"] = 3690; ports["udp"]["suucp"] = 4031; ports["udp"]["sysrqd"] = 4094; ports["udp"]["remctl"] = 4373; ports["udp"]["iax"] = 4569; ports["udp"]["radmin-port"] = 4899; ports["udp"]["rfe"] = 5002; ports["udp"]["mmcc"] = 5050; ports["udp"]["sip"] = 5060; ports["udp"]["sip-tls"] = 5061; ports["udp"]["aol"] = 5190; ports["udp"]["xmpp-client"] = 5222; ports["udp"]["xmpp-server"] = 5269; ports["udp"]["cfengine"] = 5308; ports["udp"]["mdns"] = 5353; ports["udp"]["postgresql"] = 5432; ports["udp"]["freeciv"] = 5556; ports["udp"]["ggz"] = 5688; ports["udp"]["x11"] = 6000; ports["udp"]["x11-1"] = 6001; ports["udp"]["x11-2"] = 6002; ports["udp"]["x11-3"] = 6003; ports["udp"]["x11-4"] = 6004; ports["udp"]["x11-5"] = 6005; ports["udp"]["x11-6"] = 6006; ports["udp"]["x11-7"] = 6007; ports["udp"]["gnutella-svc"] = 6346; ports["udp"]["gnutella-rtr"] = 6347; ports["udp"]["sge_qmaster"] = 6444; ports["udp"]["sge_execd"] = 6445; ports["udp"]["afs3-fileserver"] = 7000; ports["udp"]["afs3-callback"] = 7001; ports["udp"]["afs3-prserver"] = 7002; ports["udp"]["afs3-vlserver"] = 7003; ports["udp"]["afs3-kaserver"] = 7004; ports["udp"]["afs3-volser"] = 7005; ports["udp"]["afs3-errors"] = 7006; ports["udp"]["afs3-bos"] = 7007; ports["udp"]["afs3-update"] = 7008; ports["udp"]["afs3-rmtsys"] = 7009; ports["udp"]["font-service"] = 7100; ports["udp"]["http-alt"] = 8080; ports["udp"]["bacula-dir"] = 9101; ports["udp"]["bacula-fd"] = 9102; ports["udp"]["bacula-sd"] = 9103; ports["udp"]["amanda"] = 10080; ports["udp"]["hkp"] = 11371; ports["udp"]["bprd"] = 13720; ports["udp"]["bpdbm"] = 13721; ports["udp"]["bpjava-msvc"] = 13722; ports["udp"]["vnetd"] = 13724; ports["udp"]["bpcd"] = 13782; ports["udp"]["vopied"] = 13783; ports["udp"]["wnn6"] = 22273; ports["udp"]["kerberos4"] = 750; ports["udp"]["kerberos_master"] = 751; ports["udp"]["passwd_server"] = 752; ports["udp"]["zephyr-srv"] = 2102; ports["udp"]["zephyr-clt"] = 2103; ports["udp"]["zephyr-hm"] = 2104; ports["udp"]["poppassd"] = 106; ports["udp"]["moira_ureg"] = 779; ports["udp"]["omirr"] = 808; ports["udp"]["customs"] = 1001; ports["udp"]["predict"] = 1210; ports["udp"]["ninstall"] = 2150; ports["udp"]["afbackup"] = 2988; ports["udp"]["afmbackup"] = 2989; ports["udp"]["noclog"] = 5354; ports["udp"]["hostmon"] = 5355; ports["udp"]["rplay"] = 5555; ports["udp"]["omniorb"] = 8088; ports["udp"]["mandelspawn"] = 9359; ports["udp"]["kamanda"] = 10081; ports["udp"]["smsqp"] = 11201; ports["udp"]["xpilot"] = 15345; ports["udp"]["sgi-cmsd"] = 17001; ports["udp"]["sgi-crsd"] = 17002; ports["udp"]["sgi-gcd"] = 17003; ports["udp"]["isdnlog"] = 20011; ports["udp"]["vboxd"] = 20012; ports["udp"]["asp"] = 27374; // these are found in Cisco configs. Some of these names duplicate // protocols listed above but a few are extras. // http://www.cisco.com/en/US/docs/security/asa/asa80/configuration/guide/ports.html // // this is a mix of port names from PIX/ASA and IOS ports["tcp"]["aol"] = 5190; // America Online ports["tcp"]["bgp"] = 179; // Border Gateway Protocol, RFC 1163 ports["tcp"]["chargen"] = 19; // Character Generator // about the port value for cifs: // http://serverfault.com/questions/71582/list-of-cisco-asa-pre-defined-services ports["tcp"]["cifs"] = 3020; ports["tcp"]["citrix-ica"] = 1494; // Citrix Independent Computing // Architecture (ICA) protocol ports["tcp"]["cmd"] = 514; // Similar to exec except that cmd // has automatic authentication ports["tcp"]["ctiqbe"] = 2748; // Computer Telephony Interface // Quick Buffer Encoding ports["tcp"]["daytime"] = 13; // Day time, RFC 867 ports["tcp"]["discard"] = 9; // Discard ports["tcp"]["domain"] = 53; // DNS ports["tcp"]["echo"] = 7; // Echo ports["tcp"]["exec"] = 512; // Remote process execution ports["tcp"]["finger"] = 79; // Finger ports["tcp"]["ftp"] = 21; // File Transfer Protocol (control port) ports["tcp"]["ftp-data"] = 20; // File Transfer Protocol (data port) ports["tcp"]["gopher"] = 70; // Gopher ports["tcp"]["h323"] = 1720; // H.323 call signalling ports["tcp"]["hostname"] = 101; // NIC Host Name Server ports["tcp"]["https"] = 443; // HTTP over SSL ports["tcp"]["ident"] = 113; // Ident authentication service ports["tcp"]["imap4"] = 143; // Internet Message Access Protocol, // version 4 ports["tcp"]["irc"] = 194; // Internet Relay Chat protocol ports["tcp"]["kerberos"] = 750; // Kerberos ports["tcp"]["klogin"] = 543; // KLOGIN ports["tcp"]["kshell"] = 544; // Korn Shell ports["tcp"]["ldap"] = 389; // Lightweight Directory Access // Protocol ports["tcp"]["ldaps"] = 636; // Lightweight Directory Access // Protocol (SSL) ports["tcp"]["login"] = 513; // Remote login ports["tcp"]["lotusnotes"] = 1352; // IBM Lotus Notes ports["tcp"]["lpd"] = 515; // Line Printer Daemon - printer spooler ports["tcp"]["netbios-ssn"] = 139; // NetBIOS Session Service ports["tcp"]["nfs"] = 2049; ports["tcp"]["nntp"] = 119; // Network News Transfer Protocol ports["tcp"]["pcanywhere-data"] = 5631; // pcAnywhere data ports["tcp"]["pim-auto-rp"] = 496; // Protocol Independent Multicast, // reverse path flooding, dense mode ports["tcp"]["pop2"] = 109; // Post Office Protocol - Version 2 ports["tcp"]["pop3"] = 110; // Post Office Protocol - Version 3 ports["tcp"]["pptp"] = 1723; // Point-to-Point Tunneling Protocol ports["tcp"]["rsh"] = 514; ports["tcp"]["rtsp"] = 554; ports["tcp"]["smtp"] = 25; // Simple Mail Transport Protocol ports["tcp"]["sqlnet"] = 1521; // Structured Query Language Network ports["tcp"]["ssh"] = 22; // Secure Shell ports["tcp"]["sip"] = 5060; ports["tcp"]["sunrpc"] = 111; // 111 Sun Remote Procedure Call ports["tcp"]["syslog"] = 514; ports["tcp"]["tacacs"] = 49; // Terminal Access Controller // Access Control System Plus ports["tcp"]["tacacs-ds"] = 63; // ??? ports["tcp"]["talk"] = 517; // Talk ports["tcp"]["telnet"] = 23; // RFC 854 Telnet ports["tcp"]["time"] = 37; // ??? ports["tcp"]["uucp"] = 540; // UNIX-to-UNIX Copy Program ports["tcp"]["whois"] = 43; // Who Is ports["tcp"]["http"] = 80; ports["tcp"]["www"] = 80; // World Wide Web ports["udp"]["biff"] = 512; // Used by mail system to notify // users that new mail is received ports["udp"]["bootpc"] = 68; // Bootstrap Protocol Client ports["udp"]["bootps"] = 67; // Bootstrap Protocol Server ports["udp"]["cifs"] = 3020; ports["udp"]["discard"] = 9; // Discard ports["udp"]["dnsix"] = 195; // DNSIX Session Management // Module Audit Redirector ports["udp"]["domain"] = 53; // DNS ports["udp"]["echo"] = 7; ports["udp"]["isakmp"] = 500; // Internet Security Association // and Key Management Protocol ports["udp"]["kerberos"] = 750; // Kerberos ports["udp"]["mobile-ip"] = 434; // MobileIP-Agent ports["udp"]["nameserver"] = 42; // Host Name Server ports["udp"]["netbios-dgm"] = 138; // NetBIOS Datagram Service ports["udp"]["netbios-ns"] = 137; // NetBIOS Name Service ports["udp"]["netbios-ss"] = 139; ports["udp"]["nfs"] = 2049; ports["udp"]["ntp"] = 123; // Network Time Protocol ports["udp"]["pcanywhere-status"] = 5632; // pcAnywhere status ports["udp"]["pim-auto-rp"] = 496; // Protocol Independent Multicast, // reverse path flooding, dense mode ports["udp"]["radius"] = 1645; // Remote Authentication Dial-In // User Service ports["udp"]["radius-acct"] = 1646; // Remote Authentication Dial-In // User Service (accounting) ports["udp"]["rip"] = 520; // Routing Information Protocol ports["udp"]["rtsp"] = 554; ports["udp"]["secureid-udp"] = 5510; // SecureID over ports["udp"]["sip"] = 5060; ports["udp"]["snmp"] = 161; // Simple Network Management Protocol ports["udp"]["snmptrap"] = 162; // Simple Network Management Protocol // - Trap ports["udp"]["sunrpc"] = 111; // 111 Sun Remote Procedure Call ports["udp"]["syslog"] = 514; // System Log ports["udp"]["tacacs"] = 49; // Terminal Access Controller // Access Control System Plus ports["udp"]["talk"] = 517; // Talk ports["udp"]["tftp"] = 69; // Trivial File Transfer Protocol ports["udp"]["time"] = 37; // Time ports["udp"]["who"] = 513; // Who ports["udp"]["xdmcp"] = 177; // X Display Manager Control Protocol } bool ok = false; int port = name.toInt(&ok); if (ok) return port; if (ports.contains(proto) && ports[proto].contains(name)) return ports[proto][name]; // I guess this can be considered a hack. For some reason ASA // converts all UDP ports in "show run" to the same names as if // they were tcp. if ((proto == "udp" || proto == "tcp-udp") && ports["tcp"].contains(name)) return ports["tcp"][name]; struct servent *se = getservbyname(name.toAscii().constData(), proto.toAscii().constData()); if (se!=NULL) { int port = ntohs(se->s_port); //free(se); return port; } return -1; } fwbuilder-5.1.0.3599/src/import/PortSpec.h0000644000175000017500000000337111733011756021013 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PORT_SPEC_H_ #define _PORT_SPEC_H_ #include #include #include class PortSpec { public: std::string port1; std::string port2; std::string port_op; PortSpec() { port1 = ""; port2 = ""; port_op = ""; } PortSpec(const PortSpec &other) { port1 = other.port1; port2 = other.port2; port_op = other.port_op; } PortSpec(const std::string s1, const std::string s2, const std::string s3) { port1 = s1; port2 = s2; port_op = s3; } void setFromPortRange(const std::string &port_range) { std::size_t n = port_range.find(':'); if ( n != std::string::npos ) { port1 = port_range.substr(0, n); port2 = port_range.substr(n+1); port_op = ":"; } } std::string toString() { return std::string("PortSpec: ") + port_op + " " + port1 + " " + port2; } }; #endif fwbuilder-5.1.0.3599/src/import/PIXImporterNat.cpp0000644000175000017500000003350211733011756022433 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "PIXImporter.h" #include #include #include #include #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/NAT.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Library.h" #include "../libgui/platforms.h" #include #include extern int fwbdebug; using namespace libfwbuilder; using namespace std; QString GlobalPool::toString() { QString l("number %1, interface %2, address range %3-%4, netmask %5 "); return l.arg(num).arg(pool_interface.c_str()) .arg(start.c_str()).arg(end.c_str()).arg(netmask.c_str()); } string GlobalPool::toStdString() { return toString().toStdString(); } GlobalPool& GlobalPool::operator=(const GlobalPool &other) { num = other.num; pool_interface = other.pool_interface; start = other.start; end = other.end; netmask = other.netmask; return *this; } void PIXImporter::addGlobalPool() { bool ok = false; int n; n = QString(tmp_global_pool.str_num.c_str()).toInt(&ok); if (ok) { tmp_global_pool.num = n; global_pools[tmp_global_pool.num].push_back(tmp_global_pool); addMessageToLog("Global address pool: " + tmp_global_pool.toString()); } } void PIXImporter::pushNATRule() { assert(current_ruleset!=NULL); switch (rule_type) { case NATRule::DNAT: buildDNATRule(); break; case NATRule::SNAT: buildSNATRule(); break; default: assert(rule_type!=NATRule::DNAT && rule_type!=NATRule::SNAT); } } /* * DNAT rule. * * Using real_a, real_nm, mapped_a, mapped_nm, real_addr_acl, * real_port_spec, mapped_port_spec, prenat_interface, * postnat_interface */ void PIXImporter::buildDNATRule() { addMessageToLog(QString("Destination translation rule (\"static\" command)")); newNATRule(); NATRule *rule = NATRule::cast(current_rule); Interface *pre_intf = getInterfaceByLabel(prenat_interface); Interface *post_intf = getInterfaceByLabel(postnat_interface); rule->setAction(NATRule::Translate); if (real_nm.empty()) real_nm = InetAddr::getAllOnes().toString(); if (mapped_nm.empty()) mapped_nm = InetAddr::getAllOnes().toString(); if ( ! mapped_a.empty()) { if (mapped_a == "interface") { RuleElementODst* odst = rule->getODst(); assert(odst!=NULL); odst->addRef(post_intf); } else { dst_a = mapped_a; dst_nm = mapped_nm; addODst(); } } if ( ! real_a.empty()) { dst_a = real_a; dst_nm = real_nm; RuleElement* tdst = rule->getTDst(); assert(tdst!=NULL); FWObject *s = makeDstObj(); if (s) tdst->addRef( s ); } if ( ! mapped_port_spec.empty()) { src_port_spec = ""; dst_port_op = "eq"; dst_port_spec = mapped_port_spec; RuleElement* osrv = rule->getOSrv(); assert(osrv!=NULL); FWObject *s = Importer::makeSrvObj(); if (s) osrv->addRef( s ); } if ( ! real_port_spec.empty()) { src_port_spec = ""; dst_port_op = "eq"; dst_port_spec = real_port_spec; RuleElement* tsrv = rule->getTSrv(); assert(tsrv!=NULL); FWObject *s = Importer::makeSrvObj(); if (s) tsrv->addRef( s ); } RuleElement *itf_i_re = rule->getItfInb(); assert(itf_i_re!=NULL); itf_i_re->addRef(post_intf); RuleElement *itf_o_re = rule->getItfOutb(); assert(itf_o_re!=NULL); itf_o_re->addRef(pre_intf); if ( ! real_addr_acl.empty()) { UnidirectionalRuleSet *rs = all_rulesets[real_addr_acl]; if (rs) { for(FWObject::iterator rs_it=rs->ruleset->begin(); rs_it!=rs->ruleset->end(); ++rs_it) { PolicyRule *policy_rule = PolicyRule::cast(*rs_it); if (policy_rule) { FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); NATRule *nat_rule = NATRule::cast( dbroot->create(NATRule::TYPENAME)); nat_rule->duplicate(rule); RuleElement* osrc = nat_rule->getOSrc(); RuleElement* osrv = nat_rule->getOSrv(); RuleElement* tdst = nat_rule->getTDst(); RuleElement* tsrv = nat_rule->getTSrv(); /* copy objects from a policy rule into * rule elements of a nat rule * * Src --> TDst * Dst --> OSrc * * If Srv matches destination ports, it should be mirrored and * placed in OSrv * * If it matches source ports, it goes to TSrv, mirrored * */ RuleElement *re = policy_rule->getSrc(); FWObject::iterator it; for (it=re->begin(); it!=re->end(); ++it) tdst->addRef(FWReference::getObject(*it)); re = policy_rule->getDst(); for (it=re->begin(); it!=re->end(); ++it) osrc->addRef(FWReference::getObject(*it)); re = policy_rule->getSrv(); for (it=re->begin(); it!=re->end(); ++it) { FWObject *old_obj = FWReference::getObject(*it); TCPUDPService *tcpudp = TCPUDPService::cast( mirrorServiceObjectRecursively(old_obj)); if (tcpudp == NULL) tsrv->addRef(old_obj); else { if (tcpudp->getSrcRangeEnd() > 0) osrv->addRef(tcpudp); if (tcpudp->getDstRangeEnd() > 0) tsrv->addRef(tcpudp); } } current_ruleset->ruleset->add(nat_rule); addStandardImportComment( nat_rule, QString::fromUtf8(rule_comment.c_str())); } } rs->to_be_deleted = true; } } else { // add it to the current ruleset current_ruleset->ruleset->add(rule); addStandardImportComment(rule, QString::fromUtf8(rule_comment.c_str())); } } /* * SNAT rule. Using rule_type, global_pools, prenat_interface, * nat_num, nat_a, nat_nm, nat_acl, max_conn, max_emb_conn * * Note that there can be multiple global pools with the same number * and same or different interfaces. In that case we should create * multiple SNAT rules. */ void PIXImporter::buildSNATRule() { addMessageToLog(QString("Source translation rule (\"nat\" command)")); bool ok = false; int pool_num = QString(nat_num.c_str()).toInt(&ok); // Parser matches INT_CONST so it can't be anything but integer... assert (ok); if (pool_num == 0) buildNoNATRule(); else { foreach(GlobalPool pool, global_pools[pool_num]) { if (fwbdebug) { qDebug() << "NAT command num=" << pool_num; qDebug() << "nat_a=" << nat_a.c_str() << "nat_nm=" << nat_nm.c_str(); qDebug() << "Using pool " << pool.toString(); } Interface *post_intf = getInterfaceByLabel(pool.pool_interface); newNATRule(); NATRule *rule = NATRule::cast(current_rule); Interface *pre_intf = getInterfaceByLabel(prenat_interface); rule->setAction(NATRule::Translate); if ( ! nat_a.empty()) { // makeSrcObj() uses these variables src_a = nat_a; src_nm = nat_nm; RuleElement* osrc = rule->getOSrc(); assert(osrc!=NULL); FWObject *s = makeSrcObj(); if (s) osrc->addRef( s ); } ObjectSignature sig(error_tracker); FWObject *addr = NULL; if (pool.start == "interface") { addr = post_intf; } else { if (pool.start == pool.end) { sig.type_name = Address::TYPENAME; sig.address = pool.start.c_str(); sig.netmask = pool.netmask.c_str(); } else { sig.type_name = AddressRange::TYPENAME; sig.setAddressRangeStart(pool.start.c_str()); sig.setAddressRangeEnd(pool.end.c_str()); } addr = commitObject(address_maker->createObject(sig)); } RuleElement* tsrc = rule->getTSrc(); assert(tsrc!=NULL); if (addr) tsrc->addRef( addr ); if (pre_intf) { RuleElement *itf_i_re = rule->getItfInb(); assert(itf_i_re!=NULL); itf_i_re->addRef(pre_intf); } if (post_intf) { RuleElement *itf_o_re = rule->getItfOutb(); assert(itf_o_re!=NULL); itf_o_re->addRef(post_intf); } if ( ! nat_acl.empty()) { natRuleWithACL(rule); } else { // add it to the current ruleset current_ruleset->ruleset->add(rule); addStandardImportComment(rule, QString::fromUtf8(rule_comment.c_str())); } } } } void PIXImporter::buildNoNATRule() { addMessageToLog(QString("NAT exemption rule (\"nat (interface) 0\" command)")); if (fwbdebug) { qDebug() << "NAT command num=0"; qDebug() << "nat_a=" << nat_a.c_str() << "nat_nm=" << nat_nm.c_str(); } newNATRule(); NATRule *rule = NATRule::cast(current_rule); rule->setRuleType(libfwbuilder::NATRule::NONAT); Interface *pre_intf = getInterfaceByLabel(prenat_interface); rule->setAction(NATRule::Translate); if ( ! nat_a.empty()) { // makeSrcObj() uses these variables src_a = nat_a; src_nm = nat_nm; RuleElement* osrc = rule->getOSrc(); assert(osrc!=NULL); FWObject *s = makeSrcObj(); if (s) osrc->addRef( s ); } RuleElement *itf_i_re = rule->getItfInb(); assert(itf_i_re!=NULL); itf_i_re->addRef(pre_intf); if ( ! nat_acl.empty()) { natRuleWithACL(rule); } else { // add it to the current ruleset current_ruleset->ruleset->add(rule); addStandardImportComment(rule, QString::fromUtf8(rule_comment.c_str())); } } void PIXImporter::natRuleWithACL(NATRule *rule) { UnidirectionalRuleSet *rs = all_rulesets[nat_acl]; if (rs) { for(FWObject::iterator rs_it=rs->ruleset->begin(); rs_it!=rs->ruleset->end(); ++rs_it) { PolicyRule *policy_rule = PolicyRule::cast(*rs_it); if (policy_rule) { FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); NATRule *nat_rule = NATRule::cast( dbroot->create(NATRule::TYPENAME)); nat_rule->duplicate(rule); RuleElement* osrc = nat_rule->getOSrc(); RuleElement* odst = nat_rule->getODst(); RuleElement* osrv = nat_rule->getOSrv(); /* copy objects from a policy rule into "original" * rule elements of a nat rule * * Src --> OSrc * Dst --> ODst * Srv --> OSrv */ RuleElement *re = policy_rule->getSrc(); FWObject::iterator it; for (it=re->begin(); it!=re->end(); ++it) osrc->addRef(FWReference::getObject(*it)); re = policy_rule->getDst(); for (it=re->begin(); it!=re->end(); ++it) odst->addRef(FWReference::getObject(*it)); re = policy_rule->getSrv(); for (it=re->begin(); it!=re->end(); ++it) osrv->addRef(FWReference::getObject(*it)); current_ruleset->ruleset->add(nat_rule); addStandardImportComment( nat_rule, QString::fromUtf8(rule_comment.c_str())); } } rs->to_be_deleted = true; } } fwbuilder-5.1.0.3599/src/parsers/0000755000175000017500000000000011733011756017244 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/parsers/IOSCfgParser.cpp0000644000175000017500000013472011733011756022206 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20090306): "iosacl.g" -> "IOSCfgParser.cpp"$ */ #line 43 "iosacl.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IOSCfgParser.cpp" #include "IOSCfgParser.hpp" #include #include #include #line 49 "iosacl.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 20 "IOSCfgParser.cpp" #line 1 "iosacl.g" #line 22 "IOSCfgParser.cpp" IOSCfgParser::IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,k) { } IOSCfgParser::IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,2) { } IOSCfgParser::IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,k) { } IOSCfgParser::IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,2) { } IOSCfgParser::IOSCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)LLkParser(state,2) { } void IOSCfgParser::cfgfile() { try { // for error handling { // ( ... )+ int _cnt3=0; for (;;) { switch ( LA(1)) { case LINE_COMMENT: { comment(); break; } case IOSVERSION: { version(); break; } case HOSTNAME: { hostname(); break; } case IP: { ip_commands(); break; } case INTRFACE: { intrface(); break; } case CONTROLLER: { controller(); break; } case VLAN: { vlan(); break; } case ACCESS_LIST: { access_list_commands(); break; } case EXIT: { exit(); break; } case DESCRIPTION: { description(); break; } case SHUTDOWN: { shutdown(); break; } case CERTIFICATE: { certificate(); break; } case QUIT: { quit(); break; } case WORD: { unknown_command(); break; } case NEWLINE: { match(NEWLINE); break; } default: { if ( _cnt3>=1 ) { goto _loop3; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());} } } _cnt3++; } _loop3:; } // ( ... )+ } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_0); } else { throw; } } } void IOSCfgParser::comment() { try { // for error handling match(LINE_COMMENT); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IOSCfgParser::version() { ANTLR_USE_NAMESPACE(antlr)RefToken v = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(IOSVERSION); v = LT(1); match(NUMBER); if ( inputState->guessing==0 ) { #line 193 "iosacl.g" *dbg << "VERSION " << v->getText() << std::endl; #line 177 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::hostname() { try { // for error handling match(HOSTNAME); { switch ( LA(1)) { case STRING: { match(STRING); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 200 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->setHostName( LT(0)->getText() ); *dbg << "HOSTNAME " << "LT0=" << LT(0)->getText() << std::endl; #line 221 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::ip_commands() { try { // for error handling match(IP); { switch ( LA(1)) { case ACCESS_LIST: { ip_access_list_ext(); break; } case ACCESS_GROUP: case ADDRESS: { interface_known_ip_commands(); break; } case COMMUNITY_LIST: { community_list_command(); break; } case ICMP: case TCP: case HOST: { ip_unused_command(); break; } case WORD: { unknown_command(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::intrface() { ANTLR_USE_NAMESPACE(antlr)RefToken in = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(INTRFACE); in = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 527 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; #line 300 "IOSCfgParser.cpp" } { switch ( LA(1)) { case POINT_TO_POINT: { match(POINT_TO_POINT); if ( inputState->guessing==0 ) { #line 535 "iosacl.g" importer->addMessageToLog( QString("Warning: point-to-point interfaces " "are not supported")); #line 314 "IOSCfgParser.cpp" } break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::controller() { try { // for error handling match(CONTROLLER); if ( inputState->guessing==0 ) { #line 517 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->clearCurrentInterface(); consumeUntil(NEWLINE); #line 351 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::vlan() { try { // for error handling match(VLAN); { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 507 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->clearCurrentInterface(); consumeUntil(NEWLINE); #line 393 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::access_list_commands() { ANTLR_USE_NAMESPACE(antlr)RefToken acl_num = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ACCESS_LIST); acl_num = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 216 "iosacl.g" importer->newUnidirRuleSet( std::string("acl_") + acl_num->getText(), libfwbuilder::Policy::TYPENAME); *dbg << acl_num->getLine() << ":" << " ACL #" << acl_num->getText() << " "; #line 421 "IOSCfgParser.cpp" } { if ((LA(1) == PERMIT) && (LA(2) == IPV4 || LA(2) == ANY)) { permit_std(); } else if ((LA(1) == DENY) && (LA(2) == IPV4 || LA(2) == ANY)) { deny_std(); } else if ((LA(1) == PERMIT) && (_tokenSet_3.member(LA(2)))) { permit_ext(); } else if ((LA(1) == DENY) && (_tokenSet_3.member(LA(2)))) { deny_ext(); } else if ((LA(1) == REMARK)) { remark(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::exit() { try { // for error handling match(EXIT); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::description() { try { // for error handling match(DESCRIPTION); if ( inputState->guessing==0 ) { #line 547 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setInterfaceComment( descr ); *dbg << " DESCRIPTION " << descr << std::endl; //consumeUntil(NEWLINE); #line 489 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::shutdown() { try { // for error handling match(SHUTDOWN); if ( inputState->guessing==0 ) { #line 583 "iosacl.g" *dbg<< LT(1)->getLine() << ":" << " INTERFACE SHUTDOWN " << std::endl; #line 512 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::certificate() { try { // for error handling match(CERTIFICATE); match(WORD); if ( inputState->guessing==0 ) { #line 185 "iosacl.g" consumeUntil(NEWLINE); consumeUntil(QUIT); #line 536 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::quit() { try { // for error handling match(QUIT); if ( inputState->guessing==0 ) { #line 153 "iosacl.g" consumeUntil(NEWLINE); #line 558 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::unknown_command() { try { // for error handling match(WORD); if ( inputState->guessing==0 ) { #line 178 "iosacl.g" consumeUntil(NEWLINE); #line 580 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::ip_access_list_ext() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ACCESS_LIST); match(EXTENDED); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 238 "iosacl.g" importer->newUnidirRuleSet( name->getText(), libfwbuilder::Policy::TYPENAME ); *dbg << name->getLine() << ":" << " ACL ext " << name->getText() << std::endl; #line 608 "IOSCfgParser.cpp" } match(NEWLINE); { // ( ... )* for (;;) { switch ( LA(1)) { case PERMIT: { permit_ext(); break; } case DENY: { deny_ext(); break; } case REMARK: { remark(); break; } default: if ((LA(1) == LINE_COMMENT) && (_tokenSet_1.member(LA(2)))) { comment(); } else if ((LA(1) == NEWLINE) && (_tokenSet_1.member(LA(2)))) { match(NEWLINE); } else { goto _loop18; } } } _loop18:; } // ( ... )* if ( inputState->guessing==0 ) { #line 255 "iosacl.g" *dbg << LT(0)->getLine() << ":" << " ACL end" << std::endl << std::endl; #line 649 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::interface_known_ip_commands() { try { // for error handling { if ((LA(1) == ACCESS_GROUP) && (LA(2) == WORD)) { access_group_by_name(); } else if ((LA(1) == ACCESS_GROUP) && (LA(2) == INT_CONST)) { access_group_by_number(); } else if ((LA(1) == ADDRESS)) { intf_address(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::community_list_command() { try { // for error handling match(COMMUNITY_LIST); if ( inputState->guessing==0 ) { #line 171 "iosacl.g" consumeUntil(NEWLINE); #line 701 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::ip_unused_command() { try { // for error handling switch ( LA(1)) { case ICMP: { match(ICMP); break; } case TCP: { match(TCP); break; } case HOST: { match(HOST); if ( inputState->guessing==0 ) { #line 164 "iosacl.g" consumeUntil(NEWLINE); #line 736 "IOSCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::permit_std() { try { // for error handling match(PERMIT); if ( inputState->guessing==0 ) { #line 290 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; #line 768 "IOSCfgParser.cpp" } rule_std(); if ( inputState->guessing==0 ) { #line 297 "iosacl.g" importer->pushRule(); #line 776 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::deny_std() { try { // for error handling match(DENY); if ( inputState->guessing==0 ) { #line 303 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; #line 801 "IOSCfgParser.cpp" } rule_std(); match(NEWLINE); if ( inputState->guessing==0 ) { #line 310 "iosacl.g" importer->pushRule(); #line 810 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::permit_ext() { try { // for error handling match(PERMIT); if ( inputState->guessing==0 ) { #line 263 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; #line 835 "IOSCfgParser.cpp" } rule_ext(); if ( inputState->guessing==0 ) { #line 270 "iosacl.g" importer->pushRule(); #line 843 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IOSCfgParser::deny_ext() { try { // for error handling match(DENY); if ( inputState->guessing==0 ) { #line 276 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; #line 868 "IOSCfgParser.cpp" } rule_ext(); match(NEWLINE); if ( inputState->guessing==0 ) { #line 283 "iosacl.g" importer->pushRule(); #line 877 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IOSCfgParser::remark() { try { // for error handling match(REMARK); if ( inputState->guessing==0 ) { #line 566 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string rem; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { rem += LT(1)->getText() + " "; consume(); } importer->addRuleComment( rem ); *dbg << " REMARK " << rem << std::endl; //consumeUntil(NEWLINE); #line 909 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IOSCfgParser::rule_ext() { try { // for error handling { switch ( LA(1)) { case IP: case WORD: { ip_protocols(); hostaddr_ext(); if ( inputState->guessing==0 ) { #line 320 "iosacl.g" importer->SaveTmpAddrToSrc(); *dbg << "(src) "; #line 935 "IOSCfgParser.cpp" } hostaddr_ext(); if ( inputState->guessing==0 ) { #line 321 "iosacl.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 941 "IOSCfgParser.cpp" } { switch ( LA(1)) { case TIME_RANGE: { time_range(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case FRAGMENTS: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FRAGMENTS: { fragments(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case ICMP: { match(ICMP); if ( inputState->guessing==0 ) { #line 327 "iosacl.g" importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; #line 1065 "IOSCfgParser.cpp" } hostaddr_ext(); if ( inputState->guessing==0 ) { #line 331 "iosacl.g" importer->SaveTmpAddrToSrc(); *dbg << "(src) "; #line 1071 "IOSCfgParser.cpp" } hostaddr_ext(); if ( inputState->guessing==0 ) { #line 332 "iosacl.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 1077 "IOSCfgParser.cpp" } { if ((LA(1) == WORD || LA(1) == INT_CONST) && (_tokenSet_4.member(LA(2)))) { icmp_spec(); } else if ((_tokenSet_5.member(LA(1))) && (_tokenSet_6.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } { switch ( LA(1)) { case TIME_RANGE: { time_range(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case FRAGMENTS: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FRAGMENTS: { fragments(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case TCP: case UDP: { { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 339 "iosacl.g" importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; #line 1230 "IOSCfgParser.cpp" } hostaddr_ext(); if ( inputState->guessing==0 ) { #line 343 "iosacl.g" importer->SaveTmpAddrToSrc(); *dbg << "(src) "; #line 1236 "IOSCfgParser.cpp" } { switch ( LA(1)) { case P_EQ: case P_GT: case P_LT: case P_NEQ: case P_RANGE: { xoperator(); if ( inputState->guessing==0 ) { #line 344 "iosacl.g" importer->SaveTmpPortToSrc(); #line 1250 "IOSCfgParser.cpp" } break; } case HOST: case IPV4: case ANY: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } hostaddr_ext(); if ( inputState->guessing==0 ) { #line 345 "iosacl.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 1270 "IOSCfgParser.cpp" } { switch ( LA(1)) { case P_EQ: case P_GT: case P_LT: case P_NEQ: case P_RANGE: { xoperator(); if ( inputState->guessing==0 ) { #line 346 "iosacl.g" importer->SaveTmpPortToDst(); #line 1284 "IOSCfgParser.cpp" } break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case ESTABLISHED: case FRAGMENTS: case TIME_RANGE: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ESTABLISHED: { established(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case TIME_RANGE: { time_range(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case FRAGMENTS: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FRAGMENTS: { fragments(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case LOG: case LOG_INPUT: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case PERMIT: case DENY: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case REMARK: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 352 "iosacl.g" *dbg << std::endl; #line 1484 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IOSCfgParser::rule_std() { try { // for error handling { hostaddr_std(); if ( inputState->guessing==0 ) { #line 360 "iosacl.g" importer->SaveTmpAddrToSrc(); *dbg << "(std) "; #line 1505 "IOSCfgParser.cpp" } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case IP: case QUIT: case WORD: case CERTIFICATE: case IOSVERSION: case HOSTNAME: case ACCESS_LIST: case VLAN: case CONTROLLER: case INTRFACE: case DESCRIPTION: case SHUTDOWN: case EXIT: case LINE_COMMENT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } if ( inputState->guessing==0 ) { #line 363 "iosacl.g" *dbg << std::endl; #line 1546 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_2); } else { throw; } } } void IOSCfgParser::ip_protocols() { try { // for error handling { switch ( LA(1)) { case IP: { match(IP); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 371 "iosacl.g" importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; #line 1586 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_7); } else { throw; } } } void IOSCfgParser::hostaddr_ext() { ANTLR_USE_NAMESPACE(antlr)RefToken h = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken m = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling switch ( LA(1)) { case HOST: { { match(HOST); h = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 423 "iosacl.g" importer->tmp_a = h->getText(); importer->tmp_nm = "0.0.0.0"; *dbg << h->getText() << "/0.0.0.0"; #line 1620 "IOSCfgParser.cpp" } break; } case IPV4: { { a = LT(1); match(IPV4); m = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 430 "iosacl.g" importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); #line 1639 "IOSCfgParser.cpp" } break; } case ANY: { match(ANY); if ( inputState->guessing==0 ) { #line 437 "iosacl.g" importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; #line 1653 "IOSCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_8); } else { throw; } } } void IOSCfgParser::time_range() { ANTLR_USE_NAMESPACE(antlr)RefToken tr_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(TIME_RANGE); tr_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 489 "iosacl.g" importer->time_range_name = tr_name->getText(); *dbg << "time_range " << tr_name->getText() << " "; #line 1686 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void IOSCfgParser::fragments() { try { // for error handling match(FRAGMENTS); if ( inputState->guessing==0 ) { #line 482 "iosacl.g" importer->fragments = true; *dbg << "fragments "; #line 1709 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_10); } else { throw; } } } void IOSCfgParser::log() { try { // for error handling { switch ( LA(1)) { case LOG: { match(LOG); break; } case LOG_INPUT: { match(LOG_INPUT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 468 "iosacl.g" importer->logging = true; *dbg << "logging "; #line 1749 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IOSCfgParser::icmp_spec() { ANTLR_USE_NAMESPACE(antlr)RefToken icmp_type = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken icmp_code = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken icmp_word = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case INT_CONST: { { icmp_type = LT(1); match(INT_CONST); icmp_code = LT(1); match(INT_CONST); } if ( inputState->guessing==0 ) { #line 379 "iosacl.g" importer->icmp_type = icmp_type->getText(); importer->icmp_code = icmp_code->getText(); importer->icmp_spec = ""; *dbg << icmp_type->getText() << " " << icmp_code->getText() << " "; #line 1787 "IOSCfgParser.cpp" } break; } case WORD: { icmp_word = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 388 "iosacl.g" importer->icmp_spec = icmp_word->getText(); *dbg << icmp_word->getText() << " "; #line 1801 "IOSCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IOSCfgParser::xoperator() { try { // for error handling switch ( LA(1)) { case P_EQ: case P_GT: case P_LT: case P_NEQ: { single_port_op(); break; } case P_RANGE: { port_range(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_11); } else { throw; } } } void IOSCfgParser::established() { try { // for error handling match(ESTABLISHED); if ( inputState->guessing==0 ) { #line 475 "iosacl.g" importer->established = true; *dbg << "established "; #line 1865 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IOSCfgParser::hostaddr_std() { ANTLR_USE_NAMESPACE(antlr)RefToken h = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken m = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling if ((LA(1) == IPV4) && (_tokenSet_12.member(LA(2)))) { { h = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 446 "iosacl.g" importer->tmp_a = h->getText(); importer->tmp_nm = "0.0.0.0"; *dbg << h->getText() << "/0.0.0.0"; #line 1896 "IOSCfgParser.cpp" } } else if ((LA(1) == IPV4) && (LA(2) == IPV4)) { { a = LT(1); match(IPV4); m = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 453 "iosacl.g" importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); #line 1913 "IOSCfgParser.cpp" } } else if ((LA(1) == ANY)) { match(ANY); if ( inputState->guessing==0 ) { #line 460 "iosacl.g" importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; #line 1925 "IOSCfgParser.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_12); } else { throw; } } } void IOSCfgParser::single_port_op() { try { // for error handling { switch ( LA(1)) { case P_EQ: { match(P_EQ); break; } case P_GT: { match(P_GT); break; } case P_LT: { match(P_LT); break; } case P_NEQ: { match(P_NEQ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 399 "iosacl.g" importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; #line 1980 "IOSCfgParser.cpp" } port_spec(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_11); } else { throw; } } } void IOSCfgParser::port_range() { try { // for error handling match(P_RANGE); if ( inputState->guessing==0 ) { #line 407 "iosacl.g" importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; #line 2004 "IOSCfgParser.cpp" } port_spec(); port_spec(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_11); } else { throw; } } } void IOSCfgParser::port_spec() { try { // for error handling { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 415 "iosacl.g" importer->tmp_port_spec += (std::string(" ") + LT(0)->getText()); *dbg << LT(0)->getText() << " "; #line 2046 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_13); } else { throw; } } } void IOSCfgParser::access_group_by_name() { ANTLR_USE_NAMESPACE(antlr)RefToken acln = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken dir = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ACCESS_GROUP); acln = LT(1); match(WORD); dir = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 609 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( acln->getText(), "", dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << acln->getText() << "'" << " " << dir->getText() << std::endl; #line 2081 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_14); } else { throw; } } } void IOSCfgParser::access_group_by_number() { ANTLR_USE_NAMESPACE(antlr)RefToken acln = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken dir = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ACCESS_GROUP); acln = LT(1); match(INT_CONST); dir = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 625 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( std::string("acl_") + acln->getText(), "", dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << acln->getText() << "'" << " " << dir->getText() << std::endl; #line 2116 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_14); } else { throw; } } } void IOSCfgParser::intf_address() { ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken m = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken s = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ADDRESS); a = LT(1); match(IPV4); m = LT(1); match(IPV4); { switch ( LA(1)) { case SECONDARY: { s = LT(1); match(SECONDARY); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 638 "iosacl.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->addInterfaceAddress(a->getText(), m->getText()); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << a->getText() << "/" << m->getText() << " "; if (s) { *dbg << s->getText(); } *dbg << std::endl; #line 2172 "IOSCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_14); } else { throw; } } } void IOSCfgParser::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* IOSCfgParser::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "NEWLINE", "\"ip\"", "\"quit\"", "\"icmp\"", "\"tcp\"", "\"host\"", "\"community-list\"", "WORD", "\"certificate\"", "\"version\"", "NUMBER", "\"hostname\"", "STRING", "\"access-list\"", "INT_CONST", "\"extended\"", "\"permit\"", "\"deny\"", "\"udp\"", "\"eq\"", "\"gt\"", "\"lt\"", "\"neq\"", "\"range\"", "IPV4", "\"any\"", "\"log\"", "\"log-input\"", "\"established\"", "\"fragments\"", "\"time-range\"", "\"vlan\"", "\"controller\"", "\"interface\"", "\"point-to-point\"", "\"description\"", "\"remark\"", "\"shutdown\"", "\"access-group\"", "\"address\"", "\"secondary\"", "\"exit\"", "LINE_COMMENT", "\"standard\"", "Whitespace", "HEX_CONST", "NEG_INT_CONST", "DIGIT", "HEXDIGIT", "PIPE_CHAR", "NUMBER_SIGN", "PERCENT", "AMPERSAND", "APOSTROPHE", "OPENING_PAREN", "CLOSING_PAREN", "STAR", "PLUS", "COMMA", "MINUS", "DOT", "SLASH", "COLON", "SEMICOLON", "LESS_THAN", "EQUALS", "GREATER_THAN", "QUESTION", "COMMERCIAL_AT", "OPENING_SQUARE", "CLOSING_SQUARE", "CARET", "UNDERLINE", "OPENING_BRACE", "CLOSING_BRACE", "TILDE", 0 }; const unsigned long IOSCfgParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL }; // EOF const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_0(_tokenSet_0_data_,4); const unsigned long IOSCfgParser::_tokenSet_1_data_[] = { 3324018UL, 25528UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // "permit" "deny" "vlan" "controller" "interface" "description" "remark" // "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_1(_tokenSet_1_data_,4); const unsigned long IOSCfgParser::_tokenSet_2_data_[] = { 178290UL, 25272UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // "vlan" "controller" "interface" "description" "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_2(_tokenSet_2_data_,4); const unsigned long IOSCfgParser::_tokenSet_3_data_[] = { 4196768UL, 0UL, 0UL, 0UL }; // "ip" "icmp" "tcp" WORD "udp" const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_3(_tokenSet_3_data_,4); const unsigned long IOSCfgParser::_tokenSet_4_data_[] = { 3224811634UL, 25534UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // INT_CONST "permit" "deny" "log" "log-input" "fragments" "time-range" // "vlan" "controller" "interface" "description" "remark" "shutdown" "exit" // LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_4(_tokenSet_4_data_,4); const unsigned long IOSCfgParser::_tokenSet_5_data_[] = { 3224549490UL, 25534UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // "permit" "deny" "log" "log-input" "fragments" "time-range" "vlan" "controller" // "interface" "description" "remark" "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_5(_tokenSet_5_data_,4); const unsigned long IOSCfgParser::_tokenSet_6_data_[] = { 3229089778UL, 28600UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" "icmp" "tcp" "host" "community-list" WORD "certificate" // "version" NUMBER "hostname" STRING "access-list" INT_CONST "permit" // "deny" "udp" "log" "log-input" "vlan" "controller" "interface" "description" // "remark" "shutdown" "access-group" "address" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_6(_tokenSet_6_data_,4); const unsigned long IOSCfgParser::_tokenSet_7_data_[] = { 805306880UL, 0UL, 0UL, 0UL }; // "host" IPV4 "any" const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_7(_tokenSet_7_data_,4); const unsigned long IOSCfgParser::_tokenSet_8_data_[] = { 4290165362UL, 25535UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" "host" WORD "certificate" "version" "hostname" // "access-list" INT_CONST "permit" "deny" "eq" "gt" "lt" "neq" "range" // IPV4 "any" "log" "log-input" "established" "fragments" "time-range" // "vlan" "controller" "interface" "description" "remark" "shutdown" "exit" // LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_8(_tokenSet_8_data_,4); const unsigned long IOSCfgParser::_tokenSet_9_data_[] = { 3224549490UL, 25530UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // "permit" "deny" "log" "log-input" "fragments" "vlan" "controller" "interface" // "description" "remark" "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_9(_tokenSet_9_data_,4); const unsigned long IOSCfgParser::_tokenSet_10_data_[] = { 3224549490UL, 25528UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // "permit" "deny" "log" "log-input" "vlan" "controller" "interface" "description" // "remark" "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_10(_tokenSet_10_data_,4); const unsigned long IOSCfgParser::_tokenSet_11_data_[] = { 4029856370UL, 25535UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" "host" WORD "certificate" "version" "hostname" // "access-list" "permit" "deny" IPV4 "any" "log" "log-input" "established" // "fragments" "time-range" "vlan" "controller" "interface" "description" // "remark" "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_11(_tokenSet_11_data_,4); const unsigned long IOSCfgParser::_tokenSet_12_data_[] = { 3221403762UL, 25272UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" WORD "certificate" "version" "hostname" "access-list" // "log" "log-input" "vlan" "controller" "interface" "description" "shutdown" // "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_12(_tokenSet_12_data_,4); const unsigned long IOSCfgParser::_tokenSet_13_data_[] = { 4030118514UL, 25535UL, 0UL, 0UL }; // EOF NEWLINE "ip" "quit" "host" WORD "certificate" "version" "hostname" // "access-list" INT_CONST "permit" "deny" IPV4 "any" "log" "log-input" // "established" "fragments" "time-range" "vlan" "controller" "interface" // "description" "remark" "shutdown" "exit" LINE_COMMENT const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_13(_tokenSet_13_data_,4); const unsigned long IOSCfgParser::_tokenSet_14_data_[] = { 16UL, 0UL, 0UL, 0UL }; // NEWLINE const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgParser::_tokenSet_14(_tokenSet_14_data_,4); fwbuilder-5.1.0.3599/src/parsers/IPTCfgParserTokenTypes.txt0000644000175000017500000000460511733011756024271 0ustar sylvestresylvestre// $ANTLR 2.7.7 (20090306): iptables.g -> IPTCfgParserTokenTypes.txt$ IPTCfgParser // output token vocab name NEWLINE=4 NUMBER_SIGN=5 IPTABLES_SAVE_HEADER=6 THREE_COMPONENT_VERSION=7 IPV4=8 COMMIT="COMMIT"=9 STAR=10 WORD=11 INPUT="INPUT"=12 FORWARD="FORWARD"=13 OUTPUT="OUTPUT"=14 PREROUTING="PREROUTING"=15 POSTROUTING="POSTROUTING"=16 COLON=17 MINUS=18 OPENING_SQUARE=19 INT_CONST=20 CLOSING_SQUARE=21 ADD_RULE=22 EXCLAMATION=23 UNSUPPORTED_OPTION=24 DIGIT=25 SLASH=26 OPT_MODULE=27 OPT_SRC=28 OPT_DST=29 OPT_IN_INTF=30 OPT_OUT_INTF=31 TCP="tcp"=32 UDP="udp"=33 ICMP="icmp"=34 OPT_PROTO=35 OPT_TARGET=36 REJECT_WITH=37 LOG_PREFIX=38 STRING=39 LOG_TCP_SEQ=40 LOG_TCP_OPT=41 LOG_IP_OPT=42 ULOG_PREFIX=43 LOG_LEVEL=44 SET_CLASS=45 SET_MARK=46 HEX_CONST=47 SET_TOS=48 SAVE_MARK=49 RESTORE_MARK=50 CONTINUE=51 ROUTE_IIF=52 ROUTE_OIF=53 ROUTE_GW=54 ROUTE_TEE=55 TO_SOURCE=56 TO_DESTINATION=57 TO_PORTS=58 TO_NETMAP=59 CLAMP_MSS=60 OPT_FRAGM=61 INVALID="INVALID"=62 NEW="NEW"=63 ESTABLISHED="ESTABLISHED"=64 RELATED="RELATED"=65 M_STATE="state"=66 MATCH_STATE=67 COMMA=68 M_MARK="mark"=69 MATCH_MARK=70 M_LIMIT="limit"=71 MATCH_LIMIT=72 MATCH_LIMIT_BURST=73 M_RECENT="recent"=74 M_IPRANGE="iprange"=75 MATCH_IPRANGE_SRC=76 MATCH_IPRANGE_DST=77 MATCH_RECENT_SET=78 MATCH_RECENT_RCHECK=79 MATCH_RECENT_UPDATE=80 MATCH_RECENT_REMOVE=81 MATCH_RECENT_RTTL=82 RSOURCE=83 MATCH_RECENT_RDEST=84 MATCH_RECENT_NAME=85 MATCH_RECENT_SECONDS=86 MATCH_RECENT_HITCOUNT=87 M_LENGTH="length"=88 MATCH_LENGTH=89 M_PKTTYPE="pkttype"=90 MATCH_PKT_TYPE=91 WORD_BROADCAST="broadcast"=92 WORD_MULTICAST="multicast"=93 WORD_UNICAST="unicast"=94 M_MPORT="multiport"=95 M_COMMENT="comment"=96 MATCH_COMMENT=97 MATCH_SRC_MULTIPORT=98 MATCH_DST_MULTIPORT=99 MATCH_BOTH_MULTIPORT=100 MATCH_ICMP_TYPE=101 MATCH_SRC_PORT=102 MATCH_SRC_PORT_SHORT=103 MATCH_DST_PORT=104 MATCH_DST_PORT_SHORT=105 MATCH_SYN=106 SYN="SYN"=107 ACK="ACK"=108 FIN="FIN"=109 RST="RST"=110 URG="URG"=111 PSH="PSH"=112 ALL="ALL"=113 NONE="NONE"=114 MATCH_TCP_FLAGS=115 MATCH_TCP_OPTION=116 Whitespace=117 IPV6=118 MAC_ADDRESS=119 NEG_INT_CONST=120 HEXDIGIT=121 NUM_3DIGIT=122 NUM_HEX_4DIGIT=123 NUMBER=124 ULOG_QTHR=125 ULOG_NLG=126 ULOG_CPR=127 PERCENT=128 AMPERSAND=129 APOSTROPHE=130 OPENING_PAREN=131 CLOSING_PAREN=132 PLUS=133 DOT=134 SEMICOLON=135 LESS_THAN=136 EQUALS=137 GREATER_THAN=138 QUESTION=139 COMMERCIAL_AT=140 CARET=141 UNDERLINE=142 OPENING_BRACE=143 CLOSING_BRACE=144 TILDE=145 fwbuilder-5.1.0.3599/src/parsers/pix.g0000644000175000017500000022046511733011756020225 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ header "pre_include_hpp" { // gets inserted before antlr generated includes in the header // file #include "PIXImporter.h" } header "post_include_hpp" { // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class PIXImporter; } header "pre_include_cpp" { // gets inserted before the antlr generated includes in the cpp // file } header "post_include_cpp" { // gets inserted after the antlr generated includes in the cpp // file #include #include } header { // gets inserted after generated namespace specifications in the // header file. But outside the generated class. } options { language="Cpp"; } class PIXCfgParser extends Parser; options { k = 2; // when default error handler is disabled, parser errors cause // exception and terminate parsing process. We can catch the exception // and make the error appear in importer log, but import process // terminates which is not always optimal // // defaultErrorHandler = false; // see http://www.antlr2.org/doc/options.html } { // additional methods and members public: std::ostream *dbg; PIXImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); std::cerr << s << std::endl; } } cfgfile : ( comment | version | hostname | community_list_command | unknown_ip_command | intrface | nameif_top_level | intf_address | controller | access_list_commands | ssh_command | telnet_command | http_command | icmp_top_level_command | nat_top_level_command | global_top_level_command | static_top_level_command | access_group | exit | certificate | quit | names_section | name_entry | named_object_network | named_object_service | object_group_network | object_group_service | object_group_protocol | object_group_icmp_8_0 | object_group_icmp_8_3 | crypto | no_commands | timeout_command | dns_command | service_top_level_command | pim_top_level_command | network_top_level_command | unknown_command | NEWLINE )+ ; //**************************************************************** quit : QUIT { consumeUntil(NEWLINE); } ; //**************************************************************** community_list_command : IP COMMUNITY_LIST { consumeUntil(NEWLINE); } ; //**************************************************************** timeout_command : TIMEOUT { consumeUntil(NEWLINE); } ; //**************************************************************** // need this because we have token PIM used in a different context pim_top_level_command : PIM { consumeUntil(NEWLINE); } ; //**************************************************************** // need this because we have token NETWORK used in a different context network_top_level_command : NETWORK { consumeUntil(NEWLINE); } ; //**************************************************************** // just skip this line since we pre-process names in PIXImporterRun.cpp names_section : NAMES ; name_entry : NAME ( name_entry_ipv4 | name_entry_ipv6 ) ; name_entry_ipv4 : IPV4 WORD ; name_entry_ipv6 : IPV6 WORD ; //**************************************************************** // // these are used in access-list and named object definitions // ip_protocol_names : ( AH | EIGRP | ESP_WORD | GRE | IGMP | IGRP | IP | IPINIP | IPSEC | NOS | OSPF | PCP | PIM | PPTP | SNP ) ; //**************************************************************** named_object_network : OBJECT NETWORK name:WORD NEWLINE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNamedObjectAddress(name->getText()); *dbg << name->getLine() << ":" << " Named Object " << name->getText() << std::endl; } ( named_object_nat | named_object_description | named_object_network_parameters )* ; named_object_network_parameters : ( host_addr | range_addr | subnet_addr ) NEWLINE ; named_object_nat : nat_top_level_command { *dbg << "Named object with singleton nat command" << std::endl; importer->addMessageToLog( QString("Warning: " "Import of named objects with \"nat\" command " "is not supported at this time")); consumeUntil(NEWLINE); } ; named_object_description : DESCRIPTION { importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setNamedObjectDescription(descr); *dbg << " DESCRIPTION " << descr << std::endl; } NEWLINE ; host_addr : HOST single_addr { importer->commitNamedAddressObject(); } ; single_addr : (h:IPV4 | v6:IPV6) { importer->setCurrentLineNumber(LT(0)->getLine()); if (h) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; *dbg << importer->tmp_a << " "; } if (v6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } } ; range_addr : (RANGE r1:IPV4 r2:IPV4) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->tmp_range_1 = r1->getText(); importer->tmp_range_2 = r2->getText(); importer->commitNamedAddressRangeObject(); *dbg << r1->getText() << "/" << r2->getText(); } ; subnet_addr : (SUBNET ((a:IPV4 nm:IPV4) | v6:IPV6)) { importer->setCurrentLineNumber(LT(0)->getLine()); if (a) { importer->tmp_a = a->getText(); importer->tmp_nm = nm->getText(); importer->commitNamedAddressObject(); *dbg << a->getText() << "/" << nm->getText(); } if (v6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } } ; //**************************************************************** // Unfortunately any keyword can be used as named object name // named_object_service : OBJECT SERVICE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); } (WORD | HTTP | SSH | TELNET) { importer->newNamedObjectService(LT(0)->getText()); *dbg << " NAMED OBJECT " << LT(0)->getText() << std::endl; } NEWLINE ( named_object_description | named_object_service_parameters )* ; named_object_service_parameters : ( service_icmp | service_icmp6 | service_tcp_udp | service_other | service_unknown ) NEWLINE ; service_icmp : SERVICE ICMP ( icmp_type:INT_CONST { importer->icmp_type = LT(0)->getText(); } | icmp_names { importer->icmp_spec = LT(0)->getText(); } ) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->commitNamedICMPServiceObject(); *dbg << "NAMED OBJECT SERVICE ICMP " << LT(0)->getText() << " "; } ; service_icmp6 : SERVICE ICMP6 (INT_CONST | WORD) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Warning: " "Import of IPv6 addresses and servcies " "is not supported at this time")); *dbg << "NAMED OBJECT SERVICE ICMP6 " << LT(0)->getText() << " "; consumeUntil(NEWLINE); } ; service_tcp_udp : SERVICE (TCP|UDP) { importer->protocol = LT(0)->getText(); *dbg << "NAMED OBJECT SERVICE " << LT(0)->getText() << " "; } ( src_port_spec )? ( dst_port_spec )? { importer->setCurrentLineNumber(LT(0)->getLine()); importer->commitNamedTCPUDPServiceObject(); } ; src_port_spec : SOURCE xoperator { importer->SaveTmpPortToSrc(); } ; dst_port_spec : ( DESTINATION )? xoperator { importer->SaveTmpPortToDst(); } ; service_other : SERVICE ( INT_CONST | ip_protocol_names) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->commitNamedIPServiceObject(); *dbg << "NAMED OBJECT SERVICE " << LT(0)->getText() << " "; } ; // we should create a placeholder object even when its protocol is // unknown because this object may be used in some object groups or // acls later on. Add a note to the object comment to clarify there // has been a parser error. Note that this is done because of the // overall liberal policy of the importer that tries to import as much // as possible even when some constructs are not recognized. service_unknown : SERVICE WORD { importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = "ip"; importer->commitNamedIPServiceObject(); std::string err = "Warning: Unknown service name " + LT(0)->getText(); importer->setNamedObjectDescription(err); importer->addMessageToLog(err); *dbg << "UNKNOWN SERVICE " << LT(0)->getText() << " "; } ; //**************************************************************** object_group_network : OBJECT_GROUP NETWORK name:WORD NEWLINE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupNetwork(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; } ( object_group_network_parameters )* ; object_group_network_parameters : ( object_group_description | group_object | network_object ) NEWLINE ; object_group_description : DESCRIPTION { importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setObjectGroupDescription(descr); *dbg << " DESCRIPTION " << descr << std::endl; } ; group_object : GROUP_OBJECT name:WORD { importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; } ; network_object : NETWORK_OBJECT { importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); } ( ( (a:IPV4 nm:IPV4) | v6:IPV6 ) { if (a) { importer->tmp_a = a->getText(); importer->tmp_nm = nm->getText(); importer->addNetworkToObjectGroup(); *dbg << a->getText() << "/" << nm->getText(); } if (v6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } } | HOST ( h:IPV4 | hv6:IPV6) { if (h) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; importer->addNetworkToObjectGroup(); *dbg << h->getText() << "/255.255.255.255"; } if (hv6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } } | OBJECT name:WORD { importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; } ) ; //**************************************************************** object_group_protocol : OBJECT_GROUP PROTOCOL name:WORD NEWLINE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupProtocol(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; } ( object_group_protocol_parameters )+ ; object_group_protocol_parameters : ( object_group_description | group_object | protocol_object ) NEWLINE ; protocol_object : PROTOCOL_OBJECT { importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); } ( ( INT_CONST | ICMP | TCP | UDP | ip_protocol_names) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->addIPServiceToObjectGroup(); *dbg << " GROUP MEMBER " << LT(0)->getText() << " "; } | ICMP6 { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } | OBJECT name:WORD { importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; } ) ; //**************************************************************** object_group_icmp_8_0 : OBJECT_GROUP ICMP_OBJECT name:WORD NEWLINE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupICMP(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; } ( object_group_icmp_parameters )* ; object_group_icmp_8_3 : OBJECT_GROUP ICMP_TYPE name:WORD NEWLINE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupICMP(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; } ( object_group_icmp_parameters )* ; object_group_icmp_parameters : ( object_group_description | group_object | icmp_object ) NEWLINE ; icmp_object : ICMP_OBJECT { importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); } ( ( icmp_type:INT_CONST { importer->icmp_type = LT(0)->getText(); } | icmp_names { importer->icmp_spec = LT(0)->getText(); } ) { importer->addICMPServiceToObjectGroup(); *dbg << " SERVICE ICMP " << LT(0)->getText() << " "; } | OBJECT name:WORD { importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; } ) ; //**************************************************************** object_group_service : OBJECT_GROUP SERVICE name:WORD ( tcp:TCP | udp:UDP | tcpudp:TCP_UDP )? NEWLINE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupService(name->getText()); if (tcp) importer->setObjectGroupServiceProtocol("tcp"); if (udp) importer->setObjectGroupServiceProtocol("udp"); if (tcpudp) importer->setObjectGroupServiceProtocol("tcp-udp"); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; } ( object_group_service_parameters )* ; object_group_service_parameters : ( object_group_description | group_object | service_object | port_object ) NEWLINE ; service_object : SERVICE_OBJECT { importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); } ( ( INT_CONST | ip_protocol_names) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->addIPServiceToObjectGroup(); *dbg << " GROUP MEMBER " << LT(0)->getText() << " "; } | ( TCP | UDP | TCP_UDP ) { importer->protocol = LT(0)->getText(); *dbg << " SERVICE TCP/UDP" << LT(0)->getText() << " "; } ( src_port_spec )? ( dst_port_spec )? { importer->addTCPUDPServiceToObjectGroup(); } | ICMP ( icmp_type:INT_CONST { importer->icmp_type = LT(0)->getText(); } | icmp_names { importer->icmp_spec = LT(0)->getText(); } ) { importer->addICMPServiceToObjectGroup(); *dbg << " SERVICE ICMP " << LT(0)->getText() << " "; } | OBJECT name:WORD { importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; } ) ; port_object { importer->tmp_port_spec = ""; importer->tmp_port_spec_2 = ""; } : PORT_OBJECT xoperator { importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << " PORT OBJECT TCP/UDP " << LT(0)->getText() << " " << std::endl; importer->SaveTmpPortToDst(); importer->addTCPUDPServiceToObjectGroup(); *dbg << std::endl; } ; //**************************************************************** crypto : CRYPTO { consumeUntil(NEWLINE); } ; //**************************************************************** unknown_ip_command : IP WORD { consumeUntil(NEWLINE); } ; //**************************************************************** unknown_command : WORD { consumeUntil(NEWLINE); } ; //**************************************************************** dns_command : DNS { consumeUntil(NEWLINE); } ; //**************************************************************** // //asa5505(config)# service ? // // call-home Enable or disable Smart Call-Home // internal Advanced settings (use only under Cisco supervision) // password-recovery Password recovery configuration // resetinbound Send reset to a denied inbound TCP packet // resetoutbound Send reset to a denied outbound TCP packet // resetoutside Send reset to a denied TCP packet to outside interface service_top_level_command : SERVICE ( CALL_HOME | INTERNAL | PASSWORD_RECOVERY | RESETINBOUND | RESETOUTBOUND | RESETOUTSIDE ) { consumeUntil(NEWLINE); } ; //**************************************************************** no_commands : NO { *dbg << " TOP LEVEL \"NO\" COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); } ; //**************************************************************** certificate : CERTIFICATE WORD { consumeUntil(NEWLINE); consumeUntil(QUIT); } ; //**************************************************************** version { std::string platform; } : ( PIX_WORD | ASA_WORD | FWSM_WORD ) { platform = LT(0)->getText(); } VERSION_WORD_CAP NUMBER { importer->setCurrentLineNumber(LT(0)->getLine()); importer->setDiscoveredPlatform(platform); importer->setDiscoveredVersion(LT(0)->getText()); *dbg << "VERSION " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); } ; //**************************************************************** hostname : HOSTNAME ( STRING | WORD ) { importer->setCurrentLineNumber(LT(0)->getLine()); // we get host name in the import wizard //importer->setHostName( LT(0)->getText() ); *dbg << "HOSTNAME " << "LT0=" << LT(0)->getText() << std::endl; } ; //**************************************************************** access_list_commands : ACCESS_LIST name:WORD { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet( name->getText(), libfwbuilder::Policy::TYPENAME ); *dbg << name->getLine() << ":" << " ACL ext " << name->getText() << std::endl; } ( permit_extended | deny_extended | permit_standard | deny_standard | comment | remark | NEWLINE ) { *dbg << LT(0)->getLine() << ":" << " ACL line end" << std::endl << std::endl; } ; //**************************************************************** permit_extended: ( EXTENDED )? PERMIT { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; } rule_extended NEWLINE { importer->pushRule(); } ; deny_extended: ( EXTENDED )? DENY { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; } rule_extended NEWLINE { importer->pushRule(); } ; permit_standard: STANDARD PERMIT { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; } rule_standard NEWLINE { importer->pushRule(); } ; deny_standard: STANDARD DENY { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; } rule_standard NEWLINE { importer->pushRule(); } ; //**************************************************************** // the difference between standard and extended acls should be in these rules // standard acl only matches destination address rule_standard : { importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; importer->SaveTmpAddrToSrc(); } hostaddr_expr { importer->SaveTmpAddrToDst(); *dbg << "(dst) " << std::endl; } ; rule_extended : ( ip_protocols hostaddr_expr { importer->SaveTmpAddrToSrc(); *dbg << "(src) "; } hostaddr_expr { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } (time_range)? (fragments)? (log)? | ICMP { importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; } hostaddr_expr { importer->SaveTmpAddrToSrc(); *dbg << "(src) "; } hostaddr_expr { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } // at this point: // configure mode commands/options: // <0-255> Enter ICMP type number (0 - 255) // alternate-address // conversion-error // echo // echo-reply // inactive Keyword for disabling an ACL element // . . . . more icmp service names // object-group ICMP object-group for destination port // . . . . more icmp service names // ( OBJECT_GROUP grp_name:WORD { importer->icmp_spec = grp_name->getText(); *dbg << "service gorup: " << grp_name->getText() << std::endl; } | icmp_spec )? (time_range)? (fragments)? (log)? | tcp_udp_rule_extended ) { *dbg << std::endl; } ; tcp_udp_rule_extended : ( TCP | UDP ) { importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; } hostaddr_expr { importer->SaveTmpAddrToSrc(); *dbg << "(src) "; } ( (OBJECT_GROUP) => ( // This object-group can be either // source port or destination address // // Using disambiguating predicate; it must be the first element // in the production (i.e. nothing should precede {}?) { importer->isKnownServiceGroupName(LT(2)->getText()) }? OBJECT_GROUP src_grp_name:WORD { importer->src_port_spec = src_grp_name->getText(); *dbg << "src port spec: " << src_grp_name->getText() << std::endl; } // destination address spec follows; hostaddr_expr matches // OBJECT | OBJECT_GROUP among pure addresses hostaddr_expr_1 { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } acl_tcp_udp_dst_port_spec | // still object-group after src address but this group is not // a known service group - must be dest. address group hostaddr_expr_2 { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } acl_tcp_udp_dst_port_spec ) | // not "object-group" keyword after src address spec. OBJECT dst_addr_name:WORD (acl_xoperator_dst)? (established)? { // looks like "object foo" at this point can only be dest addr. // (judging by cli prompts on 8.3) importer->tmp_a = dst_addr_name->getText(); importer->tmp_nm = ""; importer->SaveTmpAddrToDst(); *dbg << "dst addr object " << dst_addr_name->getText() << " "; } acl_tcp_udp_dst_port_spec | // if not object-group and object, then it can optionally // be regular inline port spec, followed by dest address spec ( xoperator { importer->SaveTmpPortToSrc(); } )? hostaddr_expr_3 { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } acl_tcp_udp_dst_port_spec ) (time_range)? (fragments)? (log)? ; //**************************************************************** acl_tcp_udp_dst_port_spec : ( // destination port spec. Can be blank, a named // object, object-group or inline (OBJECT_GROUP) => ( // This object-group can be only destination port OBJECT_GROUP dst_port_group_name:WORD { importer->dst_port_spec = dst_port_group_name->getText(); *dbg << "dst port spec: " << dst_port_group_name->getText() << std::endl; } (established)? ) | // not "object-group" OBJECT dst_port_obj_name:WORD { importer->dst_port_spec = dst_port_obj_name->getText(); *dbg << "dst addr object " << dst_port_obj_name->getText() << std::endl; } (established)? | // if not object-group and object, then it can optionally // be regular inline port spec (acl_xoperator_dst)? (established)? ) ; acl_xoperator_dst : xoperator { importer->SaveTmpPortToDst(); } ; xoperator { importer->tmp_port_spec = ""; } : single_port_op | port_range ; //**************************************************************** single_port_op : (P_EQ | P_GT | P_LT | P_NEQ ) { importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; } port_spec ; port_spec : { importer->tmp_port_spec_2 = ""; } tcp_udp_port_spec { importer->tmp_port_spec = std::string(" ") + importer->tmp_port_spec_2; *dbg << LT(0)->getText() << " " << importer->tmp_port_spec; } ; port_range : RANGE pair_of_ports_spec { importer->tmp_port_op = "range"; *dbg << "range " << importer->tmp_port_spec; } ; pair_of_ports_spec : { importer->tmp_port_spec_2 = ""; } tcp_udp_port_spec { importer->tmp_port_spec += importer->tmp_port_spec_2; } tcp_udp_port_spec { importer->tmp_port_spec += " "; importer->tmp_port_spec += importer->tmp_port_spec_2; } ; // note that some words coincide as names of protocols or ports and // can be used in other parts of configuration tcp_udp_port_spec : (tcp_udp_port_names | WORD | INT_CONST) { importer->tmp_port_spec_2 = LT(0)->getText(); } ; // tokens that can be tcp/udp port names (but can also be used for // something else). If I ever decide to make tokens for every known // port name, they should be added here tcp_udp_port_names : ( ECHO | HOSTNAME | PPTP | SSH | TELNET | HTTP ) ; established : ESTABLISHED { importer->established = true; *dbg << "established "; } ; //**************************************************************** ip_protocols : ( ( ip_protocol_names | ICMP6 ) { importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; } | ( ( OBJECT | OBJECT_GROUP ) name:WORD ) { importer->protocol = name->getText(); *dbg << "protocol " << name->getText() << " "; } ) ; icmp_spec : ( (INT_CONST) => (icmp_type:INT_CONST icmp_code:INT_CONST) { importer->icmp_type = icmp_type->getText(); importer->icmp_code = icmp_code->getText(); importer->icmp_spec = ""; *dbg << icmp_type->getText() << " " << icmp_code->getText() << " "; } | icmp_names { importer->icmp_spec = LT(0)->getText(); *dbg << LT(0)->getText() << " "; } ) ; icmp_names : ( ALTERNATE_ADDRESS | CONVERSION_ERROR | ECHO | ECHO_REPLY | INFORMATION_REPLY | INFORMATION_REQUEST | MASK_REPLY | MASK_REQUEST | MOBILE_REDIRECT | PARAMETER_PROBLEM | REDIRECT | ROUTER_ADVERTISEMENT | ROUTER_SOLICITATION | SOURCE_QUENCH | TIME_EXCEEDED | TIMESTAMP_REPLY | TIMESTAMP_REQUEST | TRACEROUTE | UNREACHABLE ) ; //**************************************************************** // using these to help with debugging hostaddr_expr_1 : hostaddr_expr ; hostaddr_expr_2 : hostaddr_expr ; hostaddr_expr_3 : hostaddr_expr ; hostaddr_expr : INTRFACE interface_label { importer->tmp_a = LT(0)->getText(); importer->tmp_nm = "interface"; *dbg << "object " << LT(0)->getText() << " "; } | ( ( OBJECT | OBJECT_GROUP ) name:WORD ) { importer->tmp_a = name->getText(); importer->tmp_nm = ""; *dbg << "object " << name->getText() << " "; } | (HOST h:IPV4) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; *dbg << h->getText() << "/255.255.255.255"; } | (a:IPV4 m:IPV4) { importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); } | ANY { importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; } ; //**************************************************************** log : (LOG | LOG_INPUT) { importer->logging = true; } ( ( ( INT_CONST | LOG_LEVEL_ALERTS | LOG_LEVEL_CRITICAL | LOG_LEVEL_DEBUGGING | LOG_LEVEL_EMERGENCIES | LOG_LEVEL_ERRORS | LOG_LEVEL_INFORMATIONAL | LOG_LEVEL_NOTIFICATIONS | LOG_LEVEL_WARNINGS | LOG_LEVEL_DISABLE | LOG_LEVEL_INACTIVE ) { importer->log_level = LT(0)->getText(); } )? ( ( INTERVAL INT_CONST ) { importer->log_interval = LT(0)->getText(); } )? ) { // if (importer->log_level == "log") importer->log_level = ""; // if (importer->log_interval == "log") importer->log_interval = ""; *dbg << "logging level '" << importer->log_level << "' interval '" << importer->log_interval << "'"; } ; fragments : FRAGMENTS { importer->fragments = true; *dbg << "fragments "; } ; time_range : TIME_RANGE tr_name:WORD { importer->time_range_name = tr_name->getText(); *dbg << "time_range " << tr_name->getText() << " "; } ; //**************************************************************** controller : CONTROLLER { importer->clearCurrentInterface(); consumeUntil(NEWLINE); } ; //**************************************************************** // // **************** PIX 6 "interface" command: // // interface [ [shutdown]] // [no] interface [logical|physical] [shutdown] // interface change-vlan // show interface // // Example: // // interface ethernet0 auto // interface ethernet1 auto // nameif ethernet0 outside security0 // nameif ethernet1 inside security100 // // **************** PIX 7 "interface" command // // interface // interface . // no interface . // // Examples: // // interface Ethernet0 // no nameif // no security-level // no ip address // ! // interface Ethernet0.101 // vlan 101 // nameif outside // security-level 0 // ip address 192.0.2.253 255.255.255.0 // ! // vlans in pix6 config format are not parsed intrface : INTRFACE ( interface_command_6 | interface_command_7 ) ; // unfortunately word "outside" is used as a keyword in nat commands // and is also common interface label interface_label : WORD | OUTSIDE ; interface_command_6 : in:WORD pix6_interface_hw_speed // pix 6 { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; } ; interface_command_7 {bool have_interface_parameters = false;} : in:WORD NEWLINE { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; } ( ( interface_parameters {have_interface_parameters = true;} )* ( LINE_COMMENT | EXIT ) { if ( ! have_interface_parameters ) { importer->ignoreCurrentInterface(); *dbg<< LT(1)->getLine() << ":" << " EMPTY INTERFACE " << std::endl; } } ) ; pix6_interface_hw_speed : ( AUI | AUTO | BNC | ( INT_CONST ( FULL | BASET | BASETX | AUTO ) ) ) ; nameif_top_level { std::string intf_name, intf_label, sec_level; } : NAMEIF WORD { intf_name = LT(0)->getText(); } interface_label { intf_label = LT(0)->getText(); } WORD { sec_level = LT(0)->getText(); } { importer->setInterfaceParametes(intf_name, intf_label, sec_level); *dbg << " NAMEIF: " << intf_name << " " << intf_label << " " << sec_level << std::endl; } ; interface_parameters : { importer->setCurrentLineNumber(LT(0)->getLine()); } ( intf_address | vlan_interface | sec_level | nameif | interface_description | switchport | shutdown | interface_no_commands | unsupported_interface_commands ) NEWLINE ; vlan_interface : VLAN vlan_id:INT_CONST { importer->setInterfaceVlanId(vlan_id->getText()); *dbg << " VLAN: " << vlan_id->getText() << std::endl; } ; unsupported_interface_commands : ( SPEED | DUPLEX | DDNS | FORWARD | DELAY | HOLD_TIME | IGMP | IPV6_C | MANAGEMENT_ONLY | MAC_ADDRESS | MULTICAST | OSPF | PIM | PPPOE | RIP ) { *dbg << " UNSUPPORTED INTERFACE COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); } ; interface_no_commands : NO (NAMEIF | IP | SEC_LEVEL | SHUTDOWN) { *dbg << " INTERFACE \"NO\" COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); } ; sec_level : SEC_LEVEL sec_level:INT_CONST { importer->setInterfaceSecurityLevel(sec_level->getText()); *dbg << "SEC_LEVEL: " << sec_level->getText() << std::endl; } ; // // If there is a word after label, then there must be sec_level // also. Otherwise there must be nothing. // // In case of pix6 configs, "nameif" is not really inside interface // context but is rather located at the top level, the same level // where "interface" line is found. Also, pix6 places all definitions // of physical interfaces ("interface") first, then all nameif lines // under them. Even though match for nameif is in the interface // context in the grammar, function setInterfaceParametes() can locate // right interface using its first parameter. // nameif : NAMEIF interface_label { importer->setInterfaceParametes(LT(0)->getText(), "", ""); *dbg << " NAMEIF: " << LT(0)->getText() << std::endl; } ; // interface description // Use it for comment interface_description : DESCRIPTION { *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setInterfaceComment( descr ); *dbg << " DESCRIPTION " << descr << std::endl; //consumeUntil(NEWLINE); } ; shutdown : SHUTDOWN { importer->ignoreCurrentInterface(); *dbg<< LT(1)->getLine() << ":" << " INTERFACE SHUTDOWN " << std::endl; } ; // Interface IP address. // // **************** PIX 6 // // ip address outside dhcp setroute retry 10 // ip address inside 10.3.14.202 255.255.255.0 // // **************** PIX 7 // // interface Ethernet0.101 // vlan 101 // nameif outside // security-level 0 // ip address 192.0.2.253 255.255.255.0 // ! // // interface Vlan1 // nameif inside // security-level 100 // ip address dhcp setroute // ! intf_address : IP ADDRESS (v6_ip_address | v7_ip_address) ; v6_ip_address : v6_dhcp_address | v6_static_address; v6_dhcp_address { std::string lbl; } : interface_label { lbl = LT(0)->getText(); } dhcp:DHCP { std::string addr = dhcp->getText(); importer->addInterfaceAddress(lbl, addr, ""); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << std::endl; // there can be some other parameters after "dhcp", such as // "setroute", "retry" etc. which we do not support consumeUntil(NEWLINE); } ; v6_static_address { std::string lbl; } : interface_label { lbl = LT(0)->getText(); } a:IPV4 m:IPV4 { std::string addr = a->getText(); std::string netm = m->getText(); importer->addInterfaceAddress(lbl, addr, netm); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << "/" << netm << std::endl; // in case there are some other parameters after address and netmask consumeUntil(NEWLINE); } ; v7_ip_address : v7_dhcp_address | v7_static_address; v7_dhcp_address : dhcp:DHCP { std::string addr = dhcp->getText(); importer->addInterfaceAddress(addr, ""); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << std::endl; consumeUntil(NEWLINE); } // NEWLINE ; v7_static_address : a:IPV4 m:IPV4 (s:STANDBY)? { std::string addr = a->getText(); std::string netm = m->getText(); importer->addInterfaceAddress(addr, netm); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << "/" << netm << std::endl; // there can be other parameters after address/netmask pair, such as "standby" // We do not parse them yet. if (s) { importer->addMessageToLog( QString("Warning: failover IP detected. " "Failover is not supported by import " "at this time")); } consumeUntil(NEWLINE); } // NEWLINE ; switchport : SWITCHPORT ACCESS VLAN vlan_num:INT_CONST { importer->addMessageToLog("Switch port vlan " + vlan_num->getText()); *dbg << "Switch port vlan " << vlan_num->getText() << std::endl; } ; //**************************************************************** // pretend ssh commands are rules in access lists with names // "ssh_commands_" + interface_label ssh_command : SSH { importer->clear(); } ( ( TIMEOUT INT_CONST ) { // set ssh timeout here } | SCOPY | VERSION_WORD_LOW INT_CONST | ( hostaddr_expr { importer->SaveTmpAddrToSrc(); } interface_label ) { std::string intf_label = LT(0)->getText(); std::string acl_name = "ssh_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); importer->action = "permit"; importer->setDstSelf(); importer->protocol = "tcp"; importer->dst_port_op = "eq"; importer->dst_port_spec = "ssh"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); *dbg << std::endl; } ) ; telnet_command : TELNET { importer->clear(); } ( ( TIMEOUT INT_CONST ) | ( hostaddr_expr { importer->SaveTmpAddrToSrc(); } interface_label ) { std::string intf_label = LT(0)->getText(); std::string acl_name = "telnet_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); importer->action = "permit"; importer->setDstSelf(); importer->protocol = "tcp"; importer->dst_port_op = "eq"; importer->dst_port_spec = "telnet"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); *dbg << std::endl; } ) ; // pretend ssh commands are rules in access lists with names // "htto_commands_" + interface_label http_command : HTTP { importer->clear(); } ( ( AUTHENTICATION_CERTIFICATE | REDIRECT | SERVER ) { consumeUntil(NEWLINE); } | ( hostaddr_expr { importer->SaveTmpAddrToSrc(); } interface_label ) { std::string intf_label = LT(0)->getText(); std::string acl_name = "http_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); importer->action = "permit"; importer->setDstSelf(); importer->protocol = "tcp"; importer->dst_port_op = "eq"; importer->dst_port_spec = "www"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); *dbg << std::endl; } ) ; // icmp command is non-determenistic syntactically because WORD can be // used as a name of icmp type or as interface label. I am going to // define all icmp types as tokens in icmp_types_for_icmp_command // Looks like "icmp" command accepts limited set of icmp type names // and can accept numeric code. // icmp_top_level_command : ICMP ( ( UNREACHABLE { consumeUntil(NEWLINE); } ) | ( (permit:PERMIT | deny:DENY) { importer->clear(); } hostaddr_expr { importer->SaveTmpAddrToSrc(); } ( icmp_types_for_icmp_command )? interface_label { std::string intf_label = LT(0)->getText(); std::string acl_name = "icmp_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); if (permit) importer->action = "permit"; if (deny) importer->action = "deny"; importer->setDstSelf(); importer->protocol = "icmp"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); } ) ) ; icmp_types_for_icmp_command : INT_CONST { importer->icmp_type = LT(0)->getText(); importer->icmp_code = "0"; importer->icmp_spec = ""; } | (ECHO | ECHO_REPLY | TIME_EXCEEDED | UNREACHABLE) { importer->icmp_type = ""; importer->icmp_code = "0"; importer->icmp_spec = LT(0)->getText(); } ; //**************************************************************** // remark. According to the Cisco docs, can only be used // within access list // Use it for the current rule comment remark : REMARK { importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string rem; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { rem += LT(1)->getText() + " "; consume(); } importer->addRuleComment( rem ); *dbg << " REMARK " << rem << std::endl; //consumeUntil(NEWLINE); } ; //**************************************************************** access_group : ACCESS_GROUP aclname:WORD dir:WORD INTRFACE interface_label { std::string intf_label = LT(0)->getText(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( aclname->getText(), intf_label, dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << aclname->getText() << "'" << " " << intf_label << " " << dir->getText() << std::endl; } ; //**************************************************************** exit: EXIT ; comment : (LINE_COMMENT | COLON_COMMENT) ; //**************************************************************** // NAT commands nat_top_level_command : NAT OPENING_PAREN { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); } ( nat_old_top_level_command | nat_new_top_level_command ) ; nat_old_top_level_command : interface_label { importer->prenat_interface = LT(0)->getText(); } CLOSING_PAREN { importer->newUnidirRuleSet("nat", libfwbuilder::NAT::TYPENAME ); *dbg << " SNAT rule "; importer->rule_type = libfwbuilder::NATRule::SNAT; } // <0-2147483647> The of this group of hosts/networks. INT_CONST { importer->nat_num = LT(0)->getText(); } // Hostname or A.B.C.D The hosts/networks in this group // access-list Specify access-list name after this keyword nat_addr_match ( nat_command_last_parameters )* NEWLINE { importer->pushNATRule(); *dbg << std::endl; } ; nat_addr_match : single_addr // real { importer->nat_a = importer->tmp_a; } // A.B.C.D IP netmask to apply to the local IP address // ( single_addr { importer->nat_nm = importer->tmp_a; } )? | INT_CONST { if (LT(0)->getText() != std::string("0")) { importer->reportError( std::string("Unknown string ")+LT(0)->getText()+ std::string("; expected \"0\"")); *dbg << " UNKNOWN STRING " << LT(0)->getText(); } importer->nat_a = "0.0.0.0"; } ( INT_CONST { if (LT(0)->getText() != std::string("0")) { importer->reportError( std::string("Unknown string ")+LT(0)->getText()+ std::string("; expected \"0\"")); *dbg << " UNKNOWN STRING " << LT(0)->getText(); } importer->nat_nm = "0.0.0.0"; } )? | ACCESS_LIST acl_name:WORD { importer->nat_acl = acl_name->getText(); } ; nat_command_last_parameters : // nat (real_ifc) nat_id real_ip [mask [dns] [outside] [[tcp] tcp_max_conns [emb_limit]] [udp udp_max_conns] [norandomseq]] // // here we deal with parameters starting with "dns". Note that compiler // does not know anything about max_conns and emb_limit options anyway // // // <0-65535> The maximum number of simultaneous TCP connections // dns Rewrite DNS address record // norandomseq Disable TCP sequence number randomization // outside Enable Outside NAT // tcp Configure TCP specific parameters // udp Configure UDP specific parameters // nat_and_static_command_common_last_parameters | OUTSIDE ; nat_new_top_level_command : interface_label COMMA interface_label CLOSING_PAREN { importer->addMessageToLog( QString("Warning: Import of ASA 8.3 nat command " "is not supported at this time")); consumeUntil(NEWLINE); } ; global_top_level_command : GLOBAL OPENING_PAREN { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); } interface_label { importer->tmp_global_pool.pool_interface = LT(0)->getText(); } CLOSING_PAREN num:INT_CONST { importer->tmp_global_pool.str_num = num->getText(); importer->tmp_global_pool.netmask = "255.255.255.255"; *dbg << " GLOBAL POOL " << importer->tmp_global_pool.str_num << " " << importer->tmp_global_pool.pool_interface; } // WORD Enter IP address or a range of IP addresses [-] // interface Specifies PAT using the IP address at the interface ( INTRFACE { importer->tmp_global_pool.start = LT(0)->getText(); importer->tmp_global_pool.end = LT(0)->getText(); } | single_addr { importer->tmp_global_pool.start = importer->tmp_a; importer->tmp_global_pool.end = importer->tmp_a; } ) ( MINUS single_addr { importer->tmp_global_pool.end = importer->tmp_a; } )? // netmask Specify netmask for the IP address(es) after this keyword // ( NETMASK IPV4 { importer->tmp_global_pool.netmask = LT(0)->getText(); } )? NEWLINE { importer->addGlobalPool(); *dbg << " " << importer->tmp_global_pool.start << " " << importer->tmp_global_pool.end << " " << importer->tmp_global_pool.netmask << std::endl; } ; static_top_level_command : STATIC OPENING_PAREN { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); } interface_label { importer->prenat_interface = LT(0)->getText(); } COMMA interface_label { importer->postnat_interface = LT(0)->getText(); } CLOSING_PAREN { importer->newUnidirRuleSet("nat", libfwbuilder::NAT::TYPENAME ); *dbg << " DNAT rule "; importer->rule_type = libfwbuilder::NATRule::DNAT; } // Hostname or A.B.C.D Global or mapped address // interface Global address overload from interface // tcp TCP to be used as transport protocol // udp UDP to be used as transport protocol ( static_starts_with_hostaddr | static_starts_with_tcp_udp ) NEWLINE { importer->pushNATRule(); *dbg << std::endl; } ; static_starts_with_hostaddr : static_mapped_addr_match // Hostname or A.B.C.D Real IP address of the host or hosts // access-list Configure access-list name after this keyw static_real_addr_match ( static_command_common_last_parameters )* ; static_mapped_addr_match : ( single_addr { importer->mapped_a = importer->tmp_a; importer->mapped_nm = importer->tmp_nm; *dbg << "mapped: " << importer->mapped_a; } | INTRFACE { importer->mapped_a = "interface"; importer->mapped_nm = ""; *dbg << "mapped: " << importer->mapped_a; } ) ; static_real_addr_match : ( single_addr // real { importer->real_a = importer->tmp_a; importer->real_nm = importer->tmp_nm; *dbg << "real: " << importer->real_a; } | ACCESS_LIST acl_name:WORD { importer->real_addr_acl = acl_name->getText(); *dbg << "real: " << importer->real_addr_acl; } ) ; static_starts_with_tcp_udp : ( TCP | UDP ) { importer->protocol = LT(0)->getText(); *dbg << " SERVICE TCP/UDP " << LT(0)->getText() << " "; } // Hostname or A.B.C.D Global or mapped address // interface Global address overload from interface static_mapped_addr_match // <0-65535> Enter port number (0 - 65535) // aol // bgp // chargen tcp_udp_port_spec { importer->mapped_port_spec = importer->tmp_port_spec_2; *dbg << "mapped port " << importer->mapped_port_spec << " "; } // Hostname or A.B.C.D Real IP address of the host or hosts // access-list Configure access-list name after this keyword ( single_addr // real { importer->real_a = importer->tmp_a; importer->real_nm = importer->tmp_nm; *dbg << "real: " << importer->real_a; } // <0-65535> Enter port number (0 - 65535) // aol // bgp // chargen tcp_udp_port_spec { importer->real_port_spec = importer->tmp_port_spec_2; *dbg << "real port " << importer->real_port_spec << " "; } | ACCESS_LIST acl_name:WORD { importer->real_addr_acl = acl_name->getText(); *dbg << "real: " << importer->real_addr_acl; } ) // <0-65535> The maximum number of simultaneous tcp connections the loc // hosts are to allow, default is 0 which means unlimited // connections. Idle connections are closed after the time // specified by the timeout conn command // dns Use the created xlate to rewrite DNS address record // netmask Configure Netmask to apply to IP addresses // norandomseq Disable TCP sequence number randomization // tcp Configure TCP specific parameters // udp Configure UDP specific parameters ( static_command_common_last_parameters )* ; static_command_common_last_parameters : // <0-65535> The maximum number of simultaneous tcp connections // dns Use the created xlate to rewrite DNS address record // netmask Configure Netmask to apply to IP addresses // norandomseq Disable TCP sequence number randomization // tcp Configure TCP specific parameters // udp Configure UDP specific parameters // nat_and_static_command_common_last_parameters | NETMASK nm:IPV4 { importer->real_nm = nm->getText(); *dbg << "real netmask: " << importer->real_nm; } ; nat_and_static_command_common_last_parameters : // <0-65535> The maximum number of simultaneous tcp connections // dns Use the created xlate to rewrite DNS address record // netmask Configure Netmask to apply to IP addresses // norandomseq Disable TCP sequence number randomization // tcp Configure TCP specific parameters // udp Configure UDP specific parameters // DNS { importer->addMessageToLog( QString("Warning: 'nat' and 'static' command option 'dns' is not supported")); } | NORANDOMSEQ { importer->addMessageToLog( QString("Warning: 'nat' and 'static' command option 'norandomseq' is not supported")); } | (TCP | UDP)? max_conn:INT_CONST (max_emb_conn:INT_CONST)? { importer->static_max_conn = max_conn->getText(); if (max_emb_conn) importer->static_max_emb_conn = max_emb_conn->getText(); } ; //**************************************************************** class PIXCfgLexer extends Lexer; options { k = 3; // ASCII only charVocabulary = '\3'..'\377'; } tokens { EXIT = "exit"; QUIT = "quit"; NO = "no"; HOSTNAME = "hostname"; CERTIFICATE = "certificate"; INTRFACE = "interface"; CONTROLLER = "controller"; DESCRIPTION = "description"; REMARK = "remark"; SHUTDOWN = "shutdown"; SPEED = "speed"; DUPLEX = "duplex"; DELAY = "delay"; DNS = "dns"; DDNS = "ddns"; FORWARD = "forward"; HOLD_TIME = "hold-time"; IPV6_C = "ipv6"; MAC_ADDRESS = "mac-address"; MANAGEMENT_ONLY = "management-only"; MULTICAST = "multicast"; NETMASK = "netmask"; INTERVAL = "interval"; OUTSIDE = "outside"; VLAN = "vlan"; SWITCHPORT = "switchport"; ACCESS = "access"; SEC_LEVEL = "security-level"; ACCESS_LIST = "access-list"; ACCESS_GROUP = "access-group"; ADDRESS = "address"; SECONDARY = "secondary"; STANDBY = "standby"; COMMUNITY_LIST = "community-list"; PERMIT = "permit"; DENY = "deny"; DHCP = "dhcp"; SETROUTE = "setroute"; // protocols for 'permit' and 'deny' commands IP = "ip"; ICMP = "icmp"; ICMP6 = "icmp6"; TCP = "tcp"; UDP = "udp"; TCP_UDP = "tcp-udp"; DESTINATION = "destination"; SOURCE = "source"; AH = "ah"; EIGRP = "eigrp"; ESP_WORD = "esp"; GRE = "gre"; IGMP = "igmp"; IGRP = "igrp"; IPINIP = "ipinip"; IPSEC = "ipsec"; NOS = "nos"; OSPF = "ospf"; PCP = "pcp"; PIM = "pim"; PPTP = "pptp"; RIP = "rip"; SNP = "snp"; HOST = "host"; ANY = "any"; P_EQ = "eq"; P_GT = "gt"; P_LT = "lt"; P_NEQ = "neq"; RANGE = "range"; LOG = "log"; LOG_INPUT = "log-input"; LOG_LEVEL_ALERTS = "alerts"; LOG_LEVEL_CRITICAL = "critical"; LOG_LEVEL_DEBUGGING = "debugging"; LOG_LEVEL_EMERGENCIES = "emergencies"; LOG_LEVEL_ERRORS = "errors"; LOG_LEVEL_INFORMATIONAL = "informational"; LOG_LEVEL_NOTIFICATIONS = "notifications"; LOG_LEVEL_WARNINGS = "warnings"; LOG_LEVEL_DISABLE = "disable"; LOG_LEVEL_INACTIVE = "inactive"; ESTABLISHED = "established"; FRAGMENTS = "fragments"; TIME_RANGE = "time-range"; EXTENDED = "extended" ; STANDARD = "standard" ; PIX_WORD = "PIX" ; ASA_WORD = "ASA" ; FWSM_WORD = "FWSM" ; VERSION_WORD_CAP = "Version" ; VERSION_WORD_LOW = "version" ; CRYPTO = "crypto"; // OBJECT = "object"; // OBJECT_GROUP = "object-group"; GROUP_OBJECT = "group-object"; NETWORK_OBJECT = "network-object"; SERVICE_OBJECT = "service-object"; PORT_OBJECT = "port-object"; PROTOCOL_OBJECT = "protocol-object"; ICMP_OBJECT = "icmp-object"; ICMP_TYPE = "icmp-type"; NETWORK = "network"; SERVICE = "service"; PROTOCOL = "protocol"; SUBNET = "subnet"; NAT = "nat"; GLOBAL = "global"; STATIC = "static"; SSH = "ssh"; TELNET = "telnet"; AUI = "aui"; AUTO = "auto"; BNC = "bnc"; BASET = "baseT"; FULL = "full"; BASETX = "baseTX"; TIMEOUT = "timeout"; ALTERNATE_ADDRESS = "alternate-address"; CONVERSION_ERROR = "conversion-error"; ECHO = "echo"; ECHO_REPLY = "echo-reply"; INFORMATION_REPLY = "information-reply"; INFORMATION_REQUEST = "information-request"; MASK_REPLY = "mask-reply"; MASK_REQUEST = "mask-request"; MOBILE_REDIRECT = "mobile-redirect"; PARAMETER_PROBLEM = "parameter-problem"; REDIRECT = "redirect"; ROUTER_ADVERTISEMENT = "router-advertisement"; ROUTER_SOLICITATION = "router-solicitation"; SOURCE_QUENCH = "source-quench"; TIME_EXCEEDED = "time-exceeded"; TIMESTAMP_REPLY = "timestamp-reply"; TIMESTAMP_REQUEST = "timestamp-request"; TRACEROUTE = "traceroute"; UNREACHABLE = "unreachable"; NORANDOMSEQ = "norandomseq"; SCOPY = "scopy"; CALL_HOME = "call-home"; INTERNAL = "internal"; PASSWORD_RECOVERY = "password-recovery"; RESETINBOUND = "resetinbound"; RESETOUTBOUND = "resetoutbound"; RESETOUTSIDE = "resetoutside"; HTTP = "http"; AUTHENTICATION_CERTIFICATE = "authentication-certificate"; SERVER = "server"; NAME = "name"; NAMES = "names"; NAMEIF = "nameif"; OBJECT = "object"; OBJECT_GROUP = "object-group"; } LINE_COMMENT : "!" (~('\r' | '\n'))* NEWLINE ; // This is for lines like these that appear at the top of "show run" // : Saved // : COLON_COMMENT : COLON (~('\r' | '\n'))* NEWLINE ; Whitespace : ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) { _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; } ; //COMMENT_START : '!' ; NEWLINE : ( "\r\n" | '\r' | '\n' ) { newline(); } ; protected INT_CONST:; protected HEX_CONST:; protected NUMBER:; protected NEG_INT_CONST:; protected DIGIT : '0'..'9' ; protected HEXDIGIT : 'a'..'f' ; NUMBER_ADDRESS_OR_WORD : ( ( DIGIT ) => ( ( (DIGIT)+ DOT (DIGIT)+ DOT (DIGIT)+ ) => ( (DIGIT)+ DOT (DIGIT)+ DOT (DIGIT)+ DOT (DIGIT)+ ) { _ttype = IPV4; } | ( (DIGIT)+ DOT (DIGIT)+ )=> ( (DIGIT)+ DOT (DIGIT)+ ) { _ttype = NUMBER; } | ( DIGIT )+ { _ttype = INT_CONST; } ) | ( ( 'a'..'f' | '0'..'9' )+ COLON ) => ( ( ( 'a'..'f' | '0'..'9' )+ ( COLON ( 'a'..'f' | '0'..'9' )* )+ ) { _ttype = IPV6; } ) | // making sure ',' '(' ')' are not part of WORD ( 'a'..'z' | 'A'..'Z' | '$' ) ( '!'..'\'' | '*' | '+' | '-' | '.' | '/' | '0'..'9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A'..'Z' | '\\' | '^' | '_' | '`' | 'a'..'z' )* { _ttype = WORD; } ) ; STRING : '"' (~'"')* '"'; PIPE_CHAR : '|'; NUMBER_SIGN : '#' ; // DOLLAR : '$' ; PERCENT : '%' ; AMPERSAND : '&' ; APOSTROPHE : '\'' ; OPENING_PAREN : '(' ; CLOSING_PAREN : ')' ; STAR : '*' ; PLUS : '+' ; COMMA : ',' ; MINUS : '-' ; DOT : '.' ; SLASH : '/' ; COLON : ':' ; SEMICOLON : ';' ; LESS_THAN : '<' ; EQUALS : '=' ; GREATER_THAN : '>' ; QUESTION : '?' ; COMMERCIAL_AT : '@' ; OPENING_SQUARE : '[' ; CLOSING_SQUARE : ']' ; CARET : '^' ; UNDERLINE : '_' ; OPENING_BRACE : '{' ; CLOSING_BRACE : '}' ; TILDE : '~' ; EXLAMATION : '!'; fwbuilder-5.1.0.3599/src/parsers/IfconfigLinuxCfgParserTokenTypes.hpp0000644000175000017500000000310411733011756026342 0ustar sylvestresylvestre#ifndef INC_IfconfigLinuxCfgParserTokenTypes_hpp_ #define INC_IfconfigLinuxCfgParserTokenTypes_hpp_ /* $ANTLR 2.7.7 (20100319): "ifconfig_linux.g" -> "IfconfigLinuxCfgParserTokenTypes.hpp"$ */ #ifndef CUSTOM_API # define CUSTOM_API #endif #ifdef __cplusplus struct CUSTOM_API IfconfigLinuxCfgParserTokenTypes { #endif enum { EOF_ = 1, NEWLINE = 4, DOUBLE_NEWLINE = 5, LINE_COMMENT = 6, PRIORITY = 7, MEDIA = 8, STATUS = 9, WORD = 10, UP = 11, UPPER_BROADCAST = 12, UPPER_POINTOPOINT = 13, UPPER_LOOPBACK = 14, UPPER_NOARP = 15, UPPER_RUNNING = 16, LOOPBACK = 17, INTERRUPT = 18, COLLISIONS = 19, COLON = 20, RX = 21, TX = 22, DOT = 23, INT_CONST = 24, LINK = 25, ENCAP = 26, HWADDR = 27, MAC_ADDRESS = 28, INET = 29, ADDR = 30, IPV4 = 31, BCAST = 32, MASK = 33, P_T_P = 34, INET6 = 35, IPV6 = 36, SLASH = 37, SCOPE = 38, HOST = 39, GLOBAL = 40, GROUPS = 41, FLAGS = 42, BROADCAST = 43, NETMASK = 44, PREFIXLEN = 45, SCOPEID = 46, MTU = 47, LLADR = 48, Whitespace = 49, HEX_CONST = 50, NUMBER = 51, NEG_INT_CONST = 52, HEX_DIGIT = 53, DIGIT = 54, NUM_3DIGIT = 55, NUM_HEX_4DIGIT = 56, NUMBER_ADDRESS_OR_WORD = 57, PERCENT = 58, AMPERSAND = 59, STAR = 60, MINUS = 61, EQUAL = 62, QUESTION = 63, OPENING_PAREN = 64, CLOSING_PAREN = 65, OPENING_SQUARE = 66, CLOSING_SQUARE = 67, OPENING_BRACE = 68, CLOSING_BRACE = 69, LESS_THAN = 70, GREATER_THAN = 71, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus }; #endif #endif /*INC_IfconfigLinuxCfgParserTokenTypes_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IPTCfgLexer.hpp0000644000175000017500000001554411733011756022042 0ustar sylvestresylvestre#ifndef INC_IPTCfgLexer_hpp_ #define INC_IPTCfgLexer_hpp_ #line 38 "iptables.g" // gets inserted before antlr generated includes in the header // file #include "IPTImporter.h" #line 11 "IPTCfgLexer.hpp" #include /* $ANTLR 2.7.7 (20090306): "iptables.g" -> "IPTCfgLexer.hpp"$ */ #include #include #include #include "IPTCfgParserTokenTypes.hpp" #include #line 45 "iptables.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class IPTImporter; #line 28 "IPTCfgLexer.hpp" #line 74 "iptables.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 34 "IPTCfgLexer.hpp" class CUSTOM_API IPTCfgLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public IPTCfgParserTokenTypes { #line 1 "iptables.g" #line 38 "IPTCfgLexer.hpp" private: void initLiterals(); public: bool getCaseSensitiveLiterals() const { return true; } public: IPTCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in); IPTCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); IPTCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); public: void mIPTABLES_SAVE_HEADER(bool _createToken); public: void mWhitespace(bool _createToken); public: void mNEWLINE(bool _createToken); protected: void mIPV4(bool _createToken); protected: void mTHREE_COMPONENT_VERSION(bool _createToken); protected: void mIPV6(bool _createToken); protected: void mMAC_ADDRESS(bool _createToken); protected: void mINT_CONST(bool _createToken); protected: void mHEX_CONST(bool _createToken); protected: void mNEG_INT_CONST(bool _createToken); protected: void mDIGIT(bool _createToken); protected: void mHEXDIGIT(bool _createToken); protected: void mNUM_3DIGIT(bool _createToken); protected: void mNUM_HEX_4DIGIT(bool _createToken); public: void mNUMBER(bool _createToken); public: void mWORD(bool _createToken); public: void mSTRING(bool _createToken); protected: void mUNSUPPORTED_OPTION(bool _createToken); public: void mRSOURCE(bool _createToken); public: void mADD_RULE(bool _createToken); public: void mMATCH_STATE(bool _createToken); public: void mMATCH_SRC_MULTIPORT(bool _createToken); public: void mMATCH_DST_MULTIPORT(bool _createToken); public: void mMATCH_BOTH_MULTIPORT(bool _createToken); public: void mMATCH_SRC_PORT(bool _createToken); public: void mMATCH_DST_PORT(bool _createToken); public: void mMATCH_SRC_PORT_SHORT(bool _createToken); public: void mMATCH_DST_PORT_SHORT(bool _createToken); public: void mMATCH_SYN(bool _createToken); public: void mMATCH_TCP_FLAGS(bool _createToken); public: void mMATCH_TCP_OPTION(bool _createToken); public: void mMATCH_ICMP_TYPE(bool _createToken); public: void mMATCH_MARK(bool _createToken); public: void mMATCH_LENGTH(bool _createToken); public: void mMATCH_LIMIT(bool _createToken); public: void mMATCH_LIMIT_BURST(bool _createToken); public: void mMATCH_RECENT_NAME(bool _createToken); public: void mMATCH_RECENT_RCHECK(bool _createToken); public: void mMATCH_RECENT_UPDATE(bool _createToken); public: void mMATCH_RECENT_REMOVE(bool _createToken); public: void mMATCH_RECENT_SECONDS(bool _createToken); public: void mMATCH_RECENT_HITCOUNT(bool _createToken); public: void mMATCH_RECENT_RTTL(bool _createToken); public: void mMATCH_RECENT_RDEST(bool _createToken); public: void mMATCH_RECENT_SET(bool _createToken); public: void mMATCH_IPRANGE_SRC(bool _createToken); public: void mMATCH_IPRANGE_DST(bool _createToken); public: void mMATCH_COMMENT(bool _createToken); public: void mMATCH_PKT_TYPE(bool _createToken); public: void mREJECT_WITH(bool _createToken); public: void mSET_CLASS(bool _createToken); public: void mSET_MARK(bool _createToken); public: void mSAVE_MARK(bool _createToken); public: void mRESTORE_MARK(bool _createToken); public: void mSET_TOS(bool _createToken); public: void mCONTINUE(bool _createToken); public: void mROUTE_IIF(bool _createToken); public: void mROUTE_OIF(bool _createToken); public: void mROUTE_GW(bool _createToken); public: void mROUTE_TEE(bool _createToken); public: void mLOG_PREFIX(bool _createToken); public: void mLOG_LEVEL(bool _createToken); public: void mLOG_TCP_SEQ(bool _createToken); public: void mLOG_TCP_OPT(bool _createToken); public: void mLOG_IP_OPT(bool _createToken); public: void mULOG_PREFIX(bool _createToken); public: void mULOG_QTHR(bool _createToken); public: void mULOG_NLG(bool _createToken); public: void mULOG_CPR(bool _createToken); public: void mTO_SOURCE(bool _createToken); public: void mTO_DESTINATION(bool _createToken); public: void mTO_PORTS(bool _createToken); public: void mTO_NETMAP(bool _createToken); public: void mCLAMP_MSS(bool _createToken); public: void mOPT_MODULE(bool _createToken); public: void mOPT_SRC(bool _createToken); public: void mOPT_DST(bool _createToken); public: void mOPT_IN_INTF(bool _createToken); public: void mOPT_OUT_INTF(bool _createToken); public: void mOPT_PROTO(bool _createToken); public: void mOPT_TARGET(bool _createToken); public: void mOPT_FRAGM(bool _createToken); public: void mEXCLAMATION(bool _createToken); public: void mNUMBER_SIGN(bool _createToken); public: void mPERCENT(bool _createToken); public: void mAMPERSAND(bool _createToken); public: void mAPOSTROPHE(bool _createToken); public: void mOPENING_PAREN(bool _createToken); public: void mCLOSING_PAREN(bool _createToken); public: void mSTAR(bool _createToken); public: void mPLUS(bool _createToken); public: void mCOMMA(bool _createToken); public: void mMINUS(bool _createToken); public: void mDOT(bool _createToken); public: void mSLASH(bool _createToken); public: void mCOLON(bool _createToken); public: void mSEMICOLON(bool _createToken); public: void mLESS_THAN(bool _createToken); public: void mEQUALS(bool _createToken); public: void mGREATER_THAN(bool _createToken); public: void mQUESTION(bool _createToken); public: void mCOMMERCIAL_AT(bool _createToken); public: void mOPENING_SQUARE(bool _createToken); public: void mCLOSING_SQUARE(bool _createToken); public: void mCARET(bool _createToken); public: void mUNDERLINE(bool _createToken); public: void mOPENING_BRACE(bool _createToken); public: void mCLOSING_BRACE(bool _createToken); public: void mTILDE(bool _createToken); private: static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; }; #endif /*INC_IPTCfgLexer_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IfconfigLinuxCfgParser.hpp0000644000175000017500000000742311733011756024324 0ustar sylvestresylvestre#ifndef INC_IfconfigLinuxCfgParser_hpp_ #define INC_IfconfigLinuxCfgParser_hpp_ #line 25 "ifconfig_linux.g" // gets inserted before antlr generated includes in the header // file #include "IfconfigImporter.h" #line 11 "IfconfigLinuxCfgParser.hpp" #include /* $ANTLR 2.7.7 (20100319): "ifconfig_linux.g" -> "IfconfigLinuxCfgParser.hpp"$ */ #include #include #include "IfconfigLinuxCfgParserTokenTypes.hpp" #include #line 32 "ifconfig_linux.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class IfconfigImporter; #line 29 "IfconfigLinuxCfgParser.hpp" #line 57 "ifconfig_linux.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 35 "IfconfigLinuxCfgParser.hpp" class CUSTOM_API IfconfigLinuxCfgParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public IfconfigLinuxCfgParserTokenTypes { #line 82 "ifconfig_linux.g" // additional methods and members public: std::ostream *dbg; IfconfigImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); std::cerr << s << std::endl; } #line 39 "IfconfigLinuxCfgParser.hpp" public: void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory ); protected: IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k); public: IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf); protected: IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k); public: IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer); IfconfigLinuxCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state); int getNumTokens() const { return IfconfigLinuxCfgParser::NUM_TOKENS; } const char* getTokenName( int type ) const { if( type > getNumTokens() ) return 0; return IfconfigLinuxCfgParser::tokenNames[type]; } const char* const* getTokenNames() const { return IfconfigLinuxCfgParser::tokenNames; } public: void cfgfile(); public: void comment(); public: void interface_line(); public: void hwaddr_line(); public: void inet_address(); public: void inet6_address(); public: void groups(); public: void interface_flags(); public: void interface_statistics(); public: void unknown_line(); public: void groups_list(); public: ANTLR_USE_NAMESPACE(antlr)RefAST getAST() { return returnAST; } protected: ANTLR_USE_NAMESPACE(antlr)RefAST returnAST; private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS static const int NUM_TOKENS = 72; #else enum { NUM_TOKENS = 72 }; #endif static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; }; #endif /*INC_IfconfigLinuxCfgParser_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PFCfgParserTokenTypes.txt0000644000175000017500000001230411733011756024135 0ustar sylvestresylvestre// $ANTLR 2.7.7 (20100319): pf.g -> PFCfgParserTokenTypes.txt$ PFCfgParser // output token vocab name NEWLINE=4 COMMENT_START=5 INCLUDE_COMMAND="include"=6 WORD=7 EQUAL=8 ANTISPOOF="antispoof"=9 ALTQ="altq"=10 QUEUE="queue"=11 SET="set"=12 TIMEOUT="timeout"=13 "ruleset-optimization"=14 LITERAL_optimization="optimization"=15 LITERAL_aggressive="aggressive"=16 LITERAL_conservative="conservative"=17 "high-latency"=18 LITERAL_normal="normal"=19 LITERAL_satellite="satellite"=20 LITERAL_limit="limit"=21 LITERAL_loginterface="loginterface"=22 "block-policy"=23 DROP="drop"=24 RETURN="return"=25 "state-policy"=26 "if-bound"=27 LITERAL_floating="floating"=28 "state-defaults"=29 "require-order"=30 LITERAL_fingerprints="fingerprints"=31 LITERAL_skip="skip"=32 ON="on"=33 OPENING_BRACE=34 COMMA=35 CLOSING_BRACE=36 LITERAL_debug="debug"=37 LITERAL_reassemble="reassemble"=38 LITERAL_hostid="hostid"=39 "tcp.first"=40 "tcp.opening"=41 "tcp.established"=42 "tcp.closing"=43 "tcp.finwait"=44 "tcp.closed"=45 "udp.first"=46 "udp.single"=47 "udp.multiple"=48 "icmp.first"=49 "icmp.error"=50 "other.first"=51 "other.single"=52 "other.multiple"=53 LITERAL_frag="frag"=54 LITERAL_interval="interval"=55 "src.track"=56 "adaptive.start"=57 "adaptive.end"=58 INT_CONST=59 LITERAL_frags="frags"=60 LITERAL_states="states"=61 "src-nodes"=62 LITERAL_tables="tables"=63 "tables-entries"=64 SCRUB="scrub"=65 MATCH="match"=66 TABLE="table"=67 LESS_THAN=68 GREATER_THAN=69 PERSIST="persist"=70 CONST_WORD="const"=71 COUNTERS="counters"=72 FILE="file"=73 STRING=74 EXLAMATION=75 COLON=76 NETWORK="network"=77 BROADCAST="broadcast"=78 PEER="peer"=79 SELF="self"=80 IPV4=81 NUMBER=82 SLASH=83 NO="no"=84 NAT="nat"=85 PASS="pass"=86 MINUS=87 STATIC_PORT="static-port"=88 RDR="rdr"=89 OPENING_PAREN=90 CLOSING_PAREN=91 PORT="port"=92 IPV6=93 STAR=94 BITMASK="bitmask"=95 RANDOM="random"=96 SOURCE_HASH="source-hash"=97 HEX_KEY="hex-key"=98 STRING_KEY="string-key"=99 ROUND_ROBIN="round-robin"=100 STICKY_ADDRESS="sticky-address"=101 BINAT="binat"=102 BLOCK="block"=103 RETURN_RST="return-rst"=104 TTL=105 RETURN_ICMP="return-icmp"=106 RETURN_ICMP6=107 IN_WORD="in"=108 OUT_WORD="out"=109 LOG="log"=110 QUICK="quick"=111 ALL="all"=112 USER="user"=113 TO="to"=114 INET="inet"=115 INET6="inet6"=116 PROTO="proto"=117 IP="ip"=118 ICMP="icmp"=119 IGMP="igmp"=120 TCP="tcp"=121 UDP="udp"=122 RDP="rdp"=123 RSVP="rsvp"=124 GRE="gre"=125 ESP_WORD="esp"=126 AH="ah"=127 EIGRP="eigrp"=128 OSPF="ospf"=129 IPIP="ipip"=130 VRRP="vrrp"=131 L2TP="l2tp"=132 ISIS="isis"=133 FROM="from"=134 URPF_FAILED="urpf-failed"=135 ANY="any"=136 NO_ROUTE="no-route"=137 MACRO=138 ROUTE_TO="route-to"=139 REPLY_TO="reply-to"=140 DUP_TO="dup-to"=141 GROUP="group"=142 LITERAL_fragment="fragment"=143 LITERAL_crop="crop"=144 "drop-ovl"=145 "no-df"=146 "min-ttl"=147 "max-mss"=148 "random-id"=149 FLAGS="flags"=150 ICMP_TYPE="icmp-type"=151 ICMP_CODE="code"=152 LITERAL_echorep="echorep"=153 LITERAL_unreach="unreach"=154 LITERAL_squench="squench"=155 LITERAL_redir="redir"=156 LITERAL_althost="althost"=157 LITERAL_echoreq="echoreq"=158 LITERAL_routeradv="routeradv"=159 LITERAL_routersol="routersol"=160 LITERAL_timex="timex"=161 LITERAL_paramprob="paramprob"=162 LITERAL_timereq="timereq"=163 LITERAL_timerep="timerep"=164 LITERAL_inforeq="inforeq"=165 LITERAL_inforep="inforep"=166 LITERAL_maskreq="maskreq"=167 LITERAL_maskrep="maskrep"=168 LITERAL_trace="trace"=169 LITERAL_dataconv="dataconv"=170 LITERAL_mobredir="mobredir"=171 "ipv6-where"=172 "ipv6-here"=173 LITERAL_mobregreq="mobregreq"=174 LITERAL_mobregrep="mobregrep"=175 LITERAL_photuris="photuris"=176 "net-unr"=177 "host-unr"=178 "proto-unr"=179 "port-unr"=180 LITERAL_needfrag="needfrag"=181 LITERAL_srcfail="srcfail"=182 "net-unk"=183 "host-unk"=184 LITERAL_isolate="isolate"=185 "net-prohib"=186 "host-prohib"=187 "net-tos"=188 "host-tos"=189 "filter-prohib"=190 "host-preced"=191 "cutoff-preced"=192 "redir-net"=193 "redir-host"=194 "redir-tos-net"=195 "redir-tos-host"=196 "normal-adv"=197 "common-adv"=198 LITERAL_transit="transit"=199 LITERAL_reassemb="reassemb"=200 LITERAL_badhead="badhead"=201 LITERAL_optmiss="optmiss"=202 LITERAL_badlen="badlen"=203 "unknown-ind"=204 "auth-fail"=205 "decrypt-fail"=206 ICMP6_TYPE="icmp6-type"=207 TAGGED="tagged"=208 TAG="tag"=209 KEEP="keep"=210 MODULATE="modulate"=211 SYNPROXY="synproxy"=212 STATE="state"=213 LABEL="label"=214 EXIT="exit"=215 QUIT="quit"=216 INTRFACE="interface"=217 ICMP6="icmp6"=218 IGRP="igrp"=219 IPSEC="ipsec"=220 NOS="nos"=221 PCP="pcp"=222 PIM="pim"=223 PPTP="pptp"=224 RIP="rip"=225 SNP="snp"=226 HOST="host"=227 RANGE="range"=228 LOG_LEVEL_ALERTS="alerts"=229 LOG_LEVEL_CRITICAL="critical"=230 LOG_LEVEL_DEBUGGING="debugging"=231 LOG_LEVEL_EMERGENCIES="emergencies"=232 LOG_LEVEL_ERRORS="errors"=233 LOG_LEVEL_INFORMATIONAL="informational"=234 LOG_LEVEL_NOTIFICATIONS="notifications"=235 LOG_LEVEL_WARNINGS="warnings"=236 LOG_LEVEL_DISABLE="disable"=237 LOG_LEVEL_INACTIVE="inactive"=238 Whitespace=239 HEX_CONST=240 NEG_INT_CONST=241 HEX_DIGIT=242 DIGIT=243 NUM_3DIGIT=244 NUM_HEX_4DIGIT=245 NUMBER_ADDRESS_OR_WORD=246 PIPE_CHAR=247 PERCENT=248 AMPERSAND=249 APOSTROPHE=250 PLUS=251 DOT=252 SEMICOLON=253 QUESTION=254 COMMERCIAL_AT=255 OPENING_SQUARE=256 CLOSING_SQUARE=257 CARET=258 UNDERLINE=259 TILDE=260 DOUBLE_QUOTE=261 fwbuilder-5.1.0.3599/src/parsers/IfconfigLinuxCfgLexer.hpp0000644000175000017500000000727011733011756024147 0ustar sylvestresylvestre#ifndef INC_IfconfigLinuxCfgLexer_hpp_ #define INC_IfconfigLinuxCfgLexer_hpp_ #line 25 "ifconfig_linux.g" // gets inserted before antlr generated includes in the header // file #include "IfconfigImporter.h" #line 11 "IfconfigLinuxCfgLexer.hpp" #include /* $ANTLR 2.7.7 (20100319): "ifconfig_linux.g" -> "IfconfigLinuxCfgLexer.hpp"$ */ #include #include #include #include "IfconfigLinuxCfgParserTokenTypes.hpp" #include #line 32 "ifconfig_linux.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class IfconfigImporter; #line 29 "IfconfigLinuxCfgLexer.hpp" #line 57 "ifconfig_linux.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 35 "IfconfigLinuxCfgLexer.hpp" class CUSTOM_API IfconfigLinuxCfgLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public IfconfigLinuxCfgParserTokenTypes { #line 1 "ifconfig_linux.g" #line 39 "IfconfigLinuxCfgLexer.hpp" private: void initLiterals(); public: bool getCaseSensitiveLiterals() const { return true; } public: IfconfigLinuxCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in); IfconfigLinuxCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); IfconfigLinuxCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); public: void mLINE_COMMENT(bool _createToken); public: void mNEWLINE(bool _createToken); public: void mWhitespace(bool _createToken); protected: void mINT_CONST(bool _createToken); protected: void mHEX_CONST(bool _createToken); protected: void mNUMBER(bool _createToken); protected: void mNEG_INT_CONST(bool _createToken); protected: void mCOLON(bool _createToken); protected: void mHEX_DIGIT(bool _createToken); protected: void mDIGIT(bool _createToken); protected: void mNUM_3DIGIT(bool _createToken); protected: void mNUM_HEX_4DIGIT(bool _createToken); protected: void mMAC_ADDRESS(bool _createToken); public: void mNUMBER_ADDRESS_OR_WORD(bool _createToken); public: void mPERCENT(bool _createToken); public: void mAMPERSAND(bool _createToken); public: void mSTAR(bool _createToken); public: void mMINUS(bool _createToken); public: void mDOT(bool _createToken); public: void mSLASH(bool _createToken); public: void mEQUAL(bool _createToken); public: void mQUESTION(bool _createToken); public: void mOPENING_PAREN(bool _createToken); public: void mCLOSING_PAREN(bool _createToken); public: void mOPENING_SQUARE(bool _createToken); public: void mCLOSING_SQUARE(bool _createToken); public: void mOPENING_BRACE(bool _createToken); public: void mCLOSING_BRACE(bool _createToken); public: void mLESS_THAN(bool _createToken); public: void mGREATER_THAN(bool _createToken); private: static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; }; #endif /*INC_IfconfigLinuxCfgLexer_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IOSCfgLexer.cpp0000644000175000017500000012654011733011756022032 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20090306): "iosacl.g" -> "IOSCfgLexer.cpp"$ */ #line 43 "iosacl.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IOSCfgLexer.cpp" #include "IOSCfgLexer.hpp" #include #include #include #include #include #include #include #line 49 "iosacl.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 25 "IOSCfgLexer.cpp" #line 1 "iosacl.g" #line 27 "IOSCfgLexer.cpp" IOSCfgLexer::IOSCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in) : ANTLR_USE_NAMESPACE(antlr)CharScanner(new ANTLR_USE_NAMESPACE(antlr)CharBuffer(in),true) { initLiterals(); } IOSCfgLexer::IOSCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib) : ANTLR_USE_NAMESPACE(antlr)CharScanner(ib,true) { initLiterals(); } IOSCfgLexer::IOSCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)CharScanner(state,true) { initLiterals(); } void IOSCfgLexer::initLiterals() { literals["host"] = 9; literals["log"] = 30; literals["access-list"] = 17; literals["interface"] = 37; literals["remark"] = 40; literals["certificate"] = 12; literals["exit"] = 45; literals["udp"] = 22; literals["point-to-point"] = 38; literals["tcp"] = 8; literals["controller"] = 36; literals["eq"] = 23; literals["ip"] = 5; literals["access-group"] = 42; literals["time-range"] = 34; literals["version"] = 13; literals["community-list"] = 10; literals["icmp"] = 7; literals["description"] = 39; literals["secondary"] = 44; literals["lt"] = 25; literals["range"] = 27; literals["log-input"] = 31; literals["standard"] = 47; literals["gt"] = 24; literals["permit"] = 20; literals["extended"] = 19; literals["address"] = 43; literals["established"] = 32; literals["neq"] = 26; literals["quit"] = 6; literals["vlan"] = 35; literals["any"] = 29; literals["deny"] = 21; literals["shutdown"] = 41; literals["hostname"] = 15; literals["fragments"] = 33; } ANTLR_USE_NAMESPACE(antlr)RefToken IOSCfgLexer::nextToken() { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; for (;;) { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; int _ttype = ANTLR_USE_NAMESPACE(antlr)Token::INVALID_TYPE; resetText(); try { // for lexical and char stream error handling switch ( LA(1)) { case 0x21 /* '!' */ : { mLINE_COMMENT(true); theRetToken=_returnToken; break; } case 0xa /* '\n' */ : case 0xd /* '\r' */ : { mNEWLINE(true); theRetToken=_returnToken; break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { mNUMBER(true); theRetToken=_returnToken; break; } case 0x2e /* '.' */ : { mDOT(true); theRetToken=_returnToken; break; } case 0x24 /* '$' */ : case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { mWORD(true); theRetToken=_returnToken; break; } case 0x22 /* '\"' */ : { mSTRING(true); theRetToken=_returnToken; break; } case 0x7c /* '|' */ : { mPIPE_CHAR(true); theRetToken=_returnToken; break; } case 0x23 /* '#' */ : { mNUMBER_SIGN(true); theRetToken=_returnToken; break; } case 0x25 /* '%' */ : { mPERCENT(true); theRetToken=_returnToken; break; } case 0x26 /* '&' */ : { mAMPERSAND(true); theRetToken=_returnToken; break; } case 0x27 /* '\'' */ : { mAPOSTROPHE(true); theRetToken=_returnToken; break; } case 0x28 /* '(' */ : { mOPENING_PAREN(true); theRetToken=_returnToken; break; } case 0x29 /* ')' */ : { mCLOSING_PAREN(true); theRetToken=_returnToken; break; } case 0x2a /* '*' */ : { mSTAR(true); theRetToken=_returnToken; break; } case 0x2b /* '+' */ : { mPLUS(true); theRetToken=_returnToken; break; } case 0x2c /* ',' */ : { mCOMMA(true); theRetToken=_returnToken; break; } case 0x2d /* '-' */ : { mMINUS(true); theRetToken=_returnToken; break; } case 0x2f /* '/' */ : { mSLASH(true); theRetToken=_returnToken; break; } case 0x3a /* ':' */ : { mCOLON(true); theRetToken=_returnToken; break; } case 0x3b /* ';' */ : { mSEMICOLON(true); theRetToken=_returnToken; break; } case 0x3c /* '<' */ : { mLESS_THAN(true); theRetToken=_returnToken; break; } case 0x3d /* '=' */ : { mEQUALS(true); theRetToken=_returnToken; break; } case 0x3e /* '>' */ : { mGREATER_THAN(true); theRetToken=_returnToken; break; } case 0x3f /* '?' */ : { mQUESTION(true); theRetToken=_returnToken; break; } case 0x40 /* '@' */ : { mCOMMERCIAL_AT(true); theRetToken=_returnToken; break; } case 0x5b /* '[' */ : { mOPENING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5d /* ']' */ : { mCLOSING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5e /* '^' */ : { mCARET(true); theRetToken=_returnToken; break; } case 0x5f /* '_' */ : { mUNDERLINE(true); theRetToken=_returnToken; break; } case 0x7b /* '{' */ : { mOPENING_BRACE(true); theRetToken=_returnToken; break; } case 0x7d /* '}' */ : { mCLOSING_BRACE(true); theRetToken=_returnToken; break; } case 0x7e /* '~' */ : { mTILDE(true); theRetToken=_returnToken; break; } default: if ((_tokenSet_0.member(LA(1)))) { mWhitespace(true); theRetToken=_returnToken; } else { if (LA(1)==EOF_CHAR) { uponEOF(); _returnToken = makeToken(ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE); } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } if ( !_returnToken ) goto tryAgain; // found SKIP token _ttype = _returnToken->getType(); _ttype = testLiteralsTable(_ttype); _returnToken->setType(_ttype); return _returnToken; } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& e) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamRecognitionException(e); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamIOException& csie) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamIOException(csie.io); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamException& cse) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamException(cse.getMessage()); } tryAgain:; } } void IOSCfgLexer::mLINE_COMMENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LINE_COMMENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("!"); { // ( ... )* for (;;) { if ((_tokenSet_1.member(LA(1)))) { { match(_tokenSet_1); } } else { goto _loop85; } } _loop85:; } // ( ... )* if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mWhitespace(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = Whitespace; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x3 /* '\3' */ : case 0x4 /* '\4' */ : case 0x5 /* '\5' */ : case 0x6 /* '\6' */ : case 0x7 /* '\7' */ : case 0x8 /* '\10' */ : { matchRange('\3','\10'); break; } case 0x9 /* '\t' */ : { match('\t' /* charlit */ ); break; } case 0xb /* '\13' */ : { match('\13' /* charlit */ ); break; } case 0xc /* '\14' */ : { match('\14' /* charlit */ ); break; } case 0xe /* '\16' */ : case 0xf /* '\17' */ : case 0x10 /* '\20' */ : case 0x11 /* '\21' */ : case 0x12 /* '\22' */ : case 0x13 /* '\23' */ : case 0x14 /* '\24' */ : case 0x15 /* '\25' */ : case 0x16 /* '\26' */ : case 0x17 /* '\27' */ : case 0x18 /* '\30' */ : case 0x19 /* '\31' */ : case 0x1a /* '\32' */ : case 0x1b /* '\33' */ : case 0x1c /* '\34' */ : case 0x1d /* '\35' */ : case 0x1e /* '\36' */ : case 0x1f /* '\37' */ : { matchRange('\16','\37'); break; } case 0x20 /* ' ' */ : { match(' ' /* charlit */ ); break; } default: if (((LA(1) >= 0x7f && LA(1) <= 0xff))) { matchRange('\177',static_cast('\377')); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( inputState->guessing==0 ) { #line 756 "iosacl.g" _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; #line 484 "IOSCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mNEWLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEWLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { if ((LA(1) == 0xd /* '\r' */ ) && (LA(2) == 0xa /* '\n' */ )) { match("\r\n"); } else if ((LA(1) == 0xd /* '\r' */ ) && (true)) { match('\r' /* charlit */ ); } else if ((LA(1) == 0xa /* '\n' */ )) { match('\n' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 761 "iosacl.g" newline(); #line 517 "IOSCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mINT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mHEX_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mNEG_INT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEG_INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('0','9'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mHEXDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEXDIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; switch ( LA(1)) { case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : { matchRange('A','F'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mNUMBER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { bool synPredMatched104 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_2.member(LA(2))) && (_tokenSet_2.member(LA(3))) && (_tokenSet_2.member(LA(4))) && (_tokenSet_2.member(LA(5))) && (_tokenSet_2.member(LA(6))) && (_tokenSet_2.member(LA(7))) && (true) && (true) && (true))) { int _m104 = mark(); synPredMatched104 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt99=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt99>=1 ) { goto _loop99; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt99++; } _loop99:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt101=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt101>=1 ) { goto _loop101; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt101++; } _loop101:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt103=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt103>=1 ) { goto _loop103; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt103++; } _loop103:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched104 = false; } rewind(_m104); inputState->guessing--; } if ( synPredMatched104 ) { { { // ( ... )+ int _cnt107=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt107>=1 ) { goto _loop107; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt107++; } _loop107:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt109=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt109>=1 ) { goto _loop109; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt109++; } _loop109:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt111=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt111>=1 ) { goto _loop111; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt111++; } _loop111:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt113=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt113>=1 ) { goto _loop113; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt113++; } _loop113:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 781 "iosacl.g" _ttype = IPV4; #line 753 "IOSCfgLexer.cpp" } } else { bool synPredMatched119 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_2.member(LA(2))) && (_tokenSet_2.member(LA(3))) && (true) && (true) && (true) && (true) && (true) && (true) && (true))) { int _m119 = mark(); synPredMatched119 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt116=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt116>=1 ) { goto _loop116; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt116++; } _loop116:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt118=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt118>=1 ) { goto _loop118; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt118++; } _loop118:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched119 = false; } rewind(_m119); inputState->guessing--; } if ( synPredMatched119 ) { { { // ( ... )+ int _cnt122=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt122>=1 ) { goto _loop122; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt122++; } _loop122:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt124=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt124>=1 ) { goto _loop124; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt124++; } _loop124:; } // ( ... )+ } } else if ((LA(1) == 0x30 /* '0' */ ) && (LA(2) == 0x78 /* 'x' */ )) { { match('0' /* charlit */ ); match('x' /* charlit */ ); { // ( ... )+ int _cnt129=0; for (;;) { if ((_tokenSet_3.member(LA(1)))) { mHEXDIGIT(false); } else { if ( _cnt129>=1 ) { goto _loop129; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt129++; } _loop129:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 787 "iosacl.g" _ttype = HEX_CONST; #line 856 "IOSCfgLexer.cpp" } } else if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true)) { { // ( ... )+ int _cnt126=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt126>=1 ) { goto _loop126; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt126++; } _loop126:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 785 "iosacl.g" _ttype = INT_CONST; #line 877 "IOSCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mDOT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('.' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mWORD(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = WORD; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x24 /* '$' */ : { match('$' /* charlit */ ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x21 /* '!' */ : case 0x22 /* '\"' */ : case 0x23 /* '#' */ : case 0x24 /* '$' */ : case 0x25 /* '%' */ : case 0x26 /* '&' */ : case 0x27 /* '\'' */ : case 0x28 /* '(' */ : case 0x29 /* ')' */ : case 0x2a /* '*' */ : case 0x2b /* '+' */ : case 0x2c /* ',' */ : case 0x2d /* '-' */ : case 0x2e /* '.' */ : case 0x2f /* '/' */ : { matchRange('!','/'); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x3a /* ':' */ : { match(':' /* charlit */ ); break; } case 0x3b /* ';' */ : { match(';' /* charlit */ ); break; } case 0x3c /* '<' */ : { match('<' /* charlit */ ); break; } case 0x3d /* '=' */ : { match('=' /* charlit */ ); break; } case 0x3e /* '>' */ : { match('>' /* charlit */ ); break; } case 0x3f /* '?' */ : { match('?' /* charlit */ ); break; } case 0x40 /* '@' */ : { match('@' /* charlit */ ); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x5c /* '\\' */ : { match('\\' /* charlit */ ); break; } case 0x5e /* '^' */ : { match('^' /* charlit */ ); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } case 0x60 /* '`' */ : { match('`' /* charlit */ ); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } default: { goto _loop133; } } } _loop133:; } // ( ... )* if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mSTRING(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STRING; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\"' /* charlit */ ); { // ( ... )* for (;;) { if ((_tokenSet_4.member(LA(1)))) { matchNot('\"' /* charlit */ ); } else { goto _loop136; } } _loop136:; } // ( ... )* match('\"' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mPIPE_CHAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PIPE_CHAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('|' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mNUMBER_SIGN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_SIGN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('#' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mPERCENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PERCENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('%' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mAMPERSAND(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = AMPERSAND; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('&' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mAPOSTROPHE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = APOSTROPHE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\'' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mOPENING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('(' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCLOSING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(')' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mSTAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('*' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mPLUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PLUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('+' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCOMMA(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMA; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(',' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mMINUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MINUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('-' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mSLASH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SLASH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('/' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(':' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mSEMICOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SEMICOLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(';' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mLESS_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LESS_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('<' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mEQUALS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EQUALS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('=' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mGREATER_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = GREATER_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('>' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mQUESTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = QUESTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('?' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCOMMERCIAL_AT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMERCIAL_AT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('@' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mOPENING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('[' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCLOSING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(']' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCARET(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CARET; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('^' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mUNDERLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = UNDERLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('_' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mOPENING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('{' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mCLOSING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('}' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IOSCfgLexer::mTILDE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TILDE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('~' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } const unsigned long IOSCfgLexer::_tokenSet_0_data_[] = { 4294958072UL, 1UL, 0UL, 2147483648UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgLexer::_tokenSet_0(_tokenSet_0_data_,16); const unsigned long IOSCfgLexer::_tokenSet_1_data_[] = { 4294958072UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! \" # $ % // & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G // H I J K L M N O const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgLexer::_tokenSet_1(_tokenSet_1_data_,16); const unsigned long IOSCfgLexer::_tokenSet_2_data_[] = { 0UL, 67059712UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // . 0 1 2 3 4 5 6 7 8 9 const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgLexer::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long IOSCfgLexer::_tokenSet_3_data_[] = { 0UL, 67043328UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 A B C D E F const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgLexer::_tokenSet_3(_tokenSet_3_data_,10); const unsigned long IOSCfgLexer::_tokenSet_4_data_[] = { 4294967288UL, 4294967291UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 // 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! # $ // % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F // G H I J K L M N O const ANTLR_USE_NAMESPACE(antlr)BitSet IOSCfgLexer::_tokenSet_4(_tokenSet_4_data_,16); fwbuilder-5.1.0.3599/src/parsers/PIXCfgLexer.hpp0000644000175000017500000000757511733011756022053 0ustar sylvestresylvestre#ifndef INC_PIXCfgLexer_hpp_ #define INC_PIXCfgLexer_hpp_ #line 25 "pix.g" // gets inserted before antlr generated includes in the header // file #include "PIXImporter.h" #line 11 "PIXCfgLexer.hpp" #include /* $ANTLR 2.7.7 (20090306): "pix.g" -> "PIXCfgLexer.hpp"$ */ #include #include #include #include "PIXCfgParserTokenTypes.hpp" #include #line 32 "pix.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class PIXImporter; #line 28 "PIXCfgLexer.hpp" #line 56 "pix.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 34 "PIXCfgLexer.hpp" class CUSTOM_API PIXCfgLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public PIXCfgParserTokenTypes { #line 1 "pix.g" #line 38 "PIXCfgLexer.hpp" private: void initLiterals(); public: bool getCaseSensitiveLiterals() const { return true; } public: PIXCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in); PIXCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); PIXCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); public: void mLINE_COMMENT(bool _createToken); public: void mNEWLINE(bool _createToken); public: void mCOLON_COMMENT(bool _createToken); public: void mCOLON(bool _createToken); public: void mWhitespace(bool _createToken); protected: void mINT_CONST(bool _createToken); protected: void mHEX_CONST(bool _createToken); protected: void mNUMBER(bool _createToken); protected: void mNEG_INT_CONST(bool _createToken); protected: void mDIGIT(bool _createToken); protected: void mHEXDIGIT(bool _createToken); public: void mNUMBER_ADDRESS_OR_WORD(bool _createToken); public: void mDOT(bool _createToken); public: void mSTRING(bool _createToken); public: void mPIPE_CHAR(bool _createToken); public: void mNUMBER_SIGN(bool _createToken); public: void mPERCENT(bool _createToken); public: void mAMPERSAND(bool _createToken); public: void mAPOSTROPHE(bool _createToken); public: void mOPENING_PAREN(bool _createToken); public: void mCLOSING_PAREN(bool _createToken); public: void mSTAR(bool _createToken); public: void mPLUS(bool _createToken); public: void mCOMMA(bool _createToken); public: void mMINUS(bool _createToken); public: void mSLASH(bool _createToken); public: void mSEMICOLON(bool _createToken); public: void mLESS_THAN(bool _createToken); public: void mEQUALS(bool _createToken); public: void mGREATER_THAN(bool _createToken); public: void mQUESTION(bool _createToken); public: void mCOMMERCIAL_AT(bool _createToken); public: void mOPENING_SQUARE(bool _createToken); public: void mCLOSING_SQUARE(bool _createToken); public: void mCARET(bool _createToken); public: void mUNDERLINE(bool _createToken); public: void mOPENING_BRACE(bool _createToken); public: void mCLOSING_BRACE(bool _createToken); public: void mTILDE(bool _createToken); public: void mEXLAMATION(bool _createToken); private: static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; }; #endif /*INC_PIXCfgLexer_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IPTCfgParser.cpp0000644000175000017500000024722011733011756022210 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20090306): "iptables.g" -> "IPTCfgParser.cpp"$ */ #line 55 "iptables.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IPTCfgParser.cpp" #include "IPTCfgParser.hpp" #include #include #include #line 61 "iptables.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #include "fwbuilder/TCPService.h" #include "fwbuilder/Logger.h" #include #line 25 "IPTCfgParser.cpp" #line 1 "iptables.g" #line 27 "IPTCfgParser.cpp" IPTCfgParser::IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,k) { } IPTCfgParser::IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,2) { } IPTCfgParser::IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,k) { } IPTCfgParser::IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,2) { } IPTCfgParser::IPTCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)LLkParser(state,2) { } void IPTCfgParser::cfgfile() { try { // for error handling { // ( ... )+ int _cnt3=0; for (;;) { switch ( LA(1)) { case NUMBER_SIGN: { comment(); break; } case STAR: { start_table(); break; } case COLON: { create_chain(); break; } case ADD_RULE: { add_rule(); break; } case COMMIT: { commit(); break; } case NEWLINE: { match(NEWLINE); break; } default: { if ( _cnt3>=1 ) { goto _loop3; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());} } } _cnt3++; } _loop3:; } // ( ... )+ } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_0); } else { throw; } } } void IPTCfgParser::comment() { try { // for error handling match(NUMBER_SIGN); { // ( ... )* for (;;) { if ((LA(1) == IPTABLES_SAVE_HEADER)) { match(IPTABLES_SAVE_HEADER); { switch ( LA(1)) { case THREE_COMPONENT_VERSION: { match(THREE_COMPONENT_VERSION); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 151 "iptables.g" importer->setCurrentLineNumber(LT(0)->getLine()); std::string version = LT(0)->getText(); importer->setDiscoveredVersion(version); *dbg << "VERSION " << version << std::endl; consumeUntil(NEWLINE); #line 145 "IPTCfgParser.cpp" } } else { goto _loop7; } } _loop7:; } // ( ... )* if ( inputState->guessing==0 ) { #line 159 "iptables.g" consumeUntil(NEWLINE); #line 160 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IPTCfgParser::start_table() { try { // for error handling match(STAR); match(WORD); if ( inputState->guessing==0 ) { #line 181 "iptables.g" if (!importer->current_table.empty()) { // we did not see COMMIT *(importer->logger) << "********************************\n"; *(importer->logger) << "Missing COMMIT for the table " << importer->current_table << "\n"; *(importer->logger) << "Perhaps the file is broken ?" << "\n"; *(importer->logger) << "********************************\n"; *dbg << "Missing COMMIT for the table " << importer->current_table; *dbg << "Perhaps the file is broken ?"; // push last rule importer->pushRule(); // clear current table importer->current_table = ""; } importer->registerTable(LT(0)->getText()); *dbg << "TABLE " << LT(0)->getText() << std::endl; #line 200 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IPTCfgParser::create_chain() { try { // for error handling match(COLON); chain_def(); if ( inputState->guessing==0 ) { #line 216 "iptables.g" importer->setCurrentLineNumber(LT(0)->getLine()); if (importer->current_table=="nat") importer->newUnidirRuleSet(LT(0)->getText(), libfwbuilder::NAT::TYPENAME); else importer->newUnidirRuleSet(LT(0)->getText(), libfwbuilder::Policy::TYPENAME); *dbg << "NEW CHAIN " << LT(0)->getText() << std::endl; #line 230 "IPTCfgParser.cpp" } { switch ( LA(1)) { case WORD: { match(WORD); break; } case MINUS: { match(MINUS); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 227 "iptables.g" importer->setDefaultAction(LT(0)->getText()); *dbg << "DEFAULT ACTION " << LT(0)->getText() << std::endl; #line 256 "IPTCfgParser.cpp" } { switch ( LA(1)) { case OPENING_SQUARE: { match(OPENING_SQUARE); match(INT_CONST); match(COLON); match(INT_CONST); match(CLOSING_SQUARE); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case NUMBER_SIGN: case COMMIT: case STAR: case COLON: case ADD_RULE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IPTCfgParser::add_rule() { try { // for error handling match(ADD_RULE); chain_def(); if ( inputState->guessing==0 ) { #line 237 "iptables.g" // push previous rule *dbg << std::endl; importer->pushRule(); // start new one importer->setCurrentLineNumber(LT(0)->getLine()); if (importer->current_table=="nat") importer->newNATRule(); else importer->newPolicyRule(); importer->current_chain = LT(0)->getText(); *dbg << "add_rule: line=" << LT(0)->getLine() << " chain=" << LT(0)->getText(); #line 317 "IPTCfgParser.cpp" } { // ( ... )+ int _cnt17=0; for (;;) { if ((_tokenSet_2.member(LA(1)))) { ipt_option(); } else { if ( _cnt17>=1 ) { goto _loop17; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());} } _cnt17++; } _loop17:; } // ( ... )+ match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IPTCfgParser::commit() { try { // for error handling match(COMMIT); if ( inputState->guessing==0 ) { #line 169 "iptables.g" // push last rule importer->pushRule(); *dbg << " COMMIT" << std::endl; // clear current table importer->current_table = ""; #line 358 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void IPTCfgParser::chain_def() { try { // for error handling { switch ( LA(1)) { case INPUT: { match(INPUT); break; } case FORWARD: { match(FORWARD); break; } case OUTPUT: { match(OUTPUT); break; } case PREROUTING: { match(PREROUTING); break; } case POSTROUTING: { match(POSTROUTING); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_3); } else { throw; } } } void IPTCfgParser::ipt_option() { try { // for error handling { switch ( LA(1)) { case EXCLAMATION: { negation(); break; } case OPT_SRC: { src(); break; } case OPT_DST: { dst(); break; } case OPT_IN_INTF: { i_intf(); break; } case OPT_OUT_INTF: { o_intf(); break; } case OPT_PROTO: { proto(); break; } case OPT_TARGET: { target(); break; } case OPT_FRAGM: { fragm(); break; } case MATCH_ICMP_TYPE: { icmp_type_spec(); break; } case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: { basic_tcp_udp_port_spec(); break; } case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: { multiport_tcp_udp_port_spec(); break; } case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { tcp_options(); break; } case MATCH_LIMIT: { match_limit(); break; } case MATCH_LIMIT_BURST: { match_limit_burst(); break; } case MATCH_LENGTH: { match_length(); break; } case MATCH_IPRANGE_SRC: { match_iprange_src(); break; } case MATCH_IPRANGE_DST: { match_iprange_dst(); break; } case MINUS: case UNSUPPORTED_OPTION: { unknown_option(); break; } default: if ((LA(1) == OPT_MODULE) && (_tokenSet_4.member(LA(2)))) { module(); } else if ((LA(1) == OPT_MODULE) && (LA(2) == M_MARK)) { match_mark(); } else if ((LA(1) == OPT_MODULE) && (LA(2) == M_RECENT)) { match_recent(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::negation() { try { // for error handling match(EXCLAMATION); if ( inputState->guessing==0 ) { #line 303 "iptables.g" importer->tmp_neg = true; #line 561 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::module() { try { // for error handling match(OPT_MODULE); { switch ( LA(1)) { case M_STATE: { m_state(); break; } case M_MPORT: { m_mport(); break; } case ICMP: { m_icmp(); break; } case TCP: { m_tcp(); break; } case UDP: { m_udp(); break; } case M_LIMIT: { m_limit(); break; } case M_LENGTH: { m_length(); break; } case M_IPRANGE: { m_iprange(); break; } case M_COMMENT: { m_comment(); break; } case M_PKTTYPE: { m_pkttype(); break; } case WORD: { m_unknown_module(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_mark() { try { // for error handling match(OPT_MODULE); m_mark(); { switch ( LA(1)) { case EXCLAMATION: { match(EXCLAMATION); if ( inputState->guessing==0 ) { #line 731 "iptables.g" importer->neg_match_mark = true; #line 665 "IPTCfgParser.cpp" } break; } case MATCH_MARK: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(MATCH_MARK); { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case HEX_CONST: { match(HEX_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 733 "iptables.g" importer->tmp_neg = false; importer->match_mark = LT(0)->getText(); *dbg << " MATCH MARK " << LT(0)->getText(); #line 705 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_recent() { try { // for error handling match(OPT_MODULE); m_recent(); { // ( ... )+ int _cnt95=0; for (;;) { if (((LA(1) >= MATCH_RECENT_SET && LA(1) <= MATCH_RECENT_HITCOUNT))) { recent_opts(); } else { if ( _cnt95>=1 ) { goto _loop95; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());} } _cnt95++; } _loop95:; } // ( ... )+ } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::src() { try { // for error handling match(OPT_SRC); if ( inputState->guessing==0 ) { #line 381 "iptables.g" *dbg << " SRC="; importer->src_neg = importer->tmp_neg; importer->tmp_neg = false; #line 759 "IPTCfgParser.cpp" } { { switch ( LA(1)) { case WORD: { match(WORD); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 387 "iptables.g" importer->src_a = LT(0)->getText(); *dbg << LT(0)->getText(); #line 786 "IPTCfgParser.cpp" } { switch ( LA(1)) { case SLASH: { match(SLASH); { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 392 "iptables.g" importer->src_nm = LT(0)->getText(); *dbg << "/" << LT(0)->getText(); #line 817 "IPTCfgParser.cpp" } break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::dst() { try { // for error handling match(OPT_DST); if ( inputState->guessing==0 ) { #line 401 "iptables.g" *dbg << " DST="; importer->dst_neg = importer->tmp_neg; importer->tmp_neg = false; #line 881 "IPTCfgParser.cpp" } { { switch ( LA(1)) { case WORD: { match(WORD); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 407 "iptables.g" importer->dst_a = LT(0)->getText(); *dbg << LT(0)->getText(); #line 908 "IPTCfgParser.cpp" } { switch ( LA(1)) { case SLASH: { match(SLASH); { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 412 "iptables.g" importer->dst_nm = LT(0)->getText(); *dbg << "/" << LT(0)->getText(); #line 939 "IPTCfgParser.cpp" } break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::i_intf() { try { // for error handling match(OPT_IN_INTF); if ( inputState->guessing==0 ) { #line 421 "iptables.g" importer->intf_neg = importer->tmp_neg; importer->tmp_neg = false; #line 1002 "IPTCfgParser.cpp" } match(WORD); if ( inputState->guessing==0 ) { #line 426 "iptables.g" importer->i_intf = LT(0)->getText(); *dbg << " I_INTF=" << LT(0)->getText(); #line 1011 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::o_intf() { try { // for error handling match(OPT_OUT_INTF); if ( inputState->guessing==0 ) { #line 434 "iptables.g" importer->intf_neg = importer->tmp_neg; importer->tmp_neg = false; #line 1034 "IPTCfgParser.cpp" } match(WORD); if ( inputState->guessing==0 ) { #line 439 "iptables.g" importer->o_intf = LT(0)->getText(); *dbg << " O_INTF=" << LT(0)->getText(); #line 1043 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::proto() { try { // for error handling match(OPT_PROTO); if ( inputState->guessing==0 ) { #line 450 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; #line 1066 "IPTCfgParser.cpp" } protocol_word(); if ( inputState->guessing==0 ) { #line 455 "iptables.g" std::string tmp_s = LT(0)->getText(); importer->protocol.resize(tmp_s.size()); std::transform(tmp_s.begin(), tmp_s.end(), importer->protocol.begin(), ::tolower); *dbg << " PROTO=" << importer->protocol; #line 1080 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::target() { ANTLR_USE_NAMESPACE(antlr)RefToken t = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OPT_TARGET); t = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 468 "iptables.g" importer->target = LT(0)->getText(); *dbg << " TARGET=" << t->getText(); #line 1106 "IPTCfgParser.cpp" } { // ( ... )* for (;;) { if ((_tokenSet_6.member(LA(1)))) { target_options(); } else { goto _loop54; } } _loop54:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::fragm() { try { // for error handling match(OPT_FRAGM); if ( inputState->guessing==0 ) { #line 680 "iptables.g" importer->fragments = true; *dbg << " FRAGM"; #line 1141 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::icmp_type_spec() { try { // for error handling match(MATCH_ICMP_TYPE); { switch ( LA(1)) { case WORD: { match(WORD); if ( inputState->guessing==0 ) { #line 970 "iptables.g" importer->icmp_spec = LT(0)->getText(); *dbg << " ICMP_SPEC=" << LT(0)->getText(); #line 1169 "IPTCfgParser.cpp" } break; } case INT_CONST: { { match(INT_CONST); if ( inputState->guessing==0 ) { #line 977 "iptables.g" importer->icmp_type = LT(0)->getText(); importer->icmp_code = "-1"; *dbg << " ICMP_TYPE=" << LT(0)->getText(); #line 1184 "IPTCfgParser.cpp" } { switch ( LA(1)) { case SLASH: { match(SLASH); match(INT_CONST); if ( inputState->guessing==0 ) { #line 984 "iptables.g" importer->icmp_code = LT(0)->getText(); *dbg << " ICMP_CODE=" << LT(0)->getText(); #line 1198 "IPTCfgParser.cpp" } break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::basic_tcp_udp_port_spec() { try { // for error handling switch ( LA(1)) { case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: { { switch ( LA(1)) { case MATCH_SRC_PORT: { match(MATCH_SRC_PORT); break; } case MATCH_SRC_PORT_SHORT: { match(MATCH_SRC_PORT_SHORT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1066 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; #line 1290 "IPTCfgParser.cpp" } { switch ( LA(1)) { case WORD: case INT_CONST: { port_def_with_range(); break; } case COLON: { port_def_with_incomplete_range(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1071 "iptables.g" importer->pushTmpPortSpecToSrcPortList(); #line 1316 "IPTCfgParser.cpp" } break; } case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: { { switch ( LA(1)) { case MATCH_DST_PORT: { match(MATCH_DST_PORT); break; } case MATCH_DST_PORT_SHORT: { match(MATCH_DST_PORT_SHORT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1076 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; #line 1347 "IPTCfgParser.cpp" } { switch ( LA(1)) { case WORD: case INT_CONST: { port_def_with_range(); break; } case COLON: { port_def_with_incomplete_range(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1081 "iptables.g" importer->pushTmpPortSpecToDstPortList(); #line 1373 "IPTCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::multiport_tcp_udp_port_spec() { try { // for error handling { switch ( LA(1)) { case MATCH_SRC_MULTIPORT: { { match(MATCH_SRC_MULTIPORT); if ( inputState->guessing==0 ) { #line 901 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; importer->startSrcMultiPort(); *dbg << " SRC MULTIPORT="; #line 1410 "IPTCfgParser.cpp" } port_def_with_range(); if ( inputState->guessing==0 ) { #line 908 "iptables.g" importer->pushTmpPortSpecToSrcPortList(); #line 1418 "IPTCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); port_def_with_range(); if ( inputState->guessing==0 ) { #line 912 "iptables.g" importer->pushTmpPortSpecToSrcPortList(); #line 1430 "IPTCfgParser.cpp" } } else { goto _loop114; } } _loop114:; } // ( ... )* } break; } case MATCH_DST_MULTIPORT: { { match(MATCH_DST_MULTIPORT); if ( inputState->guessing==0 ) { #line 919 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; importer->startDstMultiPort(); *dbg << " DST MULTIPORT="; #line 1455 "IPTCfgParser.cpp" } port_def_with_range(); if ( inputState->guessing==0 ) { #line 926 "iptables.g" importer->pushTmpPortSpecToDstPortList(); #line 1463 "IPTCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); port_def_with_range(); if ( inputState->guessing==0 ) { #line 930 "iptables.g" importer->pushTmpPortSpecToDstPortList(); #line 1475 "IPTCfgParser.cpp" } } else { goto _loop117; } } _loop117:; } // ( ... )* } break; } case MATCH_BOTH_MULTIPORT: { { match(MATCH_BOTH_MULTIPORT); if ( inputState->guessing==0 ) { #line 937 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; importer->startBothMultiPort(); *dbg << " MULTIPORT PORTS="; #line 1500 "IPTCfgParser.cpp" } port_def_with_range(); if ( inputState->guessing==0 ) { #line 944 "iptables.g" importer->pushTmpPortSpecToBothPortList(); #line 1508 "IPTCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); port_def_with_range(); if ( inputState->guessing==0 ) { #line 948 "iptables.g" importer->pushTmpPortSpecToBothPortList(); #line 1520 "IPTCfgParser.cpp" } } else { goto _loop120; } } _loop120:; } // ( ... )* } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::tcp_options() { try { // for error handling { switch ( LA(1)) { case MATCH_SYN: { syn(); break; } case MATCH_TCP_FLAGS: { tcp_flags(); break; } case MATCH_TCP_OPTION: { tcp_option(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1111 "iptables.g" importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; #line 1582 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_limit() { try { // for error handling match(MATCH_LIMIT); limit_rate(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_limit_burst() { try { // for error handling match(MATCH_LIMIT_BURST); match(INT_CONST); if ( inputState->guessing==0 ) { #line 765 "iptables.g" importer->limit_burst = LT(0)->getText(); *dbg << " LIMIT BURST " << LT(0)->getText(); #line 1622 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_length() { try { // for error handling match(MATCH_LENGTH); length_spec(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_iprange_src() { try { // for error handling match(MATCH_IPRANGE_SRC); { switch ( LA(1)) { case WORD: { match(WORD); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 788 "iptables.g" importer->iprange_src_from = LT(0)->getText(); importer->using_iprange_src = true; #line 1679 "IPTCfgParser.cpp" } match(MINUS); { switch ( LA(1)) { case WORD: { match(WORD); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 793 "iptables.g" importer->iprange_src_to = LT(0)->getText(); #line 1705 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::match_iprange_dst() { try { // for error handling match(MATCH_IPRANGE_DST); { switch ( LA(1)) { case WORD: { match(WORD); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 799 "iptables.g" importer->iprange_dst_from = LT(0)->getText(); importer->using_iprange_dst = true; #line 1746 "IPTCfgParser.cpp" } match(MINUS); { switch ( LA(1)) { case WORD: { match(WORD); break; } case IPV4: { match(IPV4); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 804 "iptables.g" importer->iprange_dst_to = LT(0)->getText(); #line 1772 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::unknown_option() { try { // for error handling if ((LA(1) == MINUS) && (LA(2) == WORD)) { { match(MINUS); match(WORD); if ( inputState->guessing==0 ) { #line 312 "iptables.g" importer->reportError( std::string("Unknown option: -")+LT(0)->getText()); *dbg << " UNKNOWN OPTION=-" << LT(0)->getText(); #line 1799 "IPTCfgParser.cpp" } { switch ( LA(1)) { case WORD: case INT_CONST: case DIGIT: { unknown_parameter(); break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } } else if ((LA(1) == MINUS) && (LA(2) == MINUS)) { { { match(MINUS); match(MINUS); match(WORD); } if ( inputState->guessing==0 ) { #line 322 "iptables.g" importer->reportError( std::string("Unknown option: --")+LT(0)->getText()); *dbg << " UNKNOWN OPTION=--" << LT(0)->getText(); #line 1863 "IPTCfgParser.cpp" } { switch ( LA(1)) { case WORD: case INT_CONST: case DIGIT: { unknown_parameter(); break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } } else if ((LA(1) == UNSUPPORTED_OPTION)) { { match(UNSUPPORTED_OPTION); if ( inputState->guessing==0 ) { #line 332 "iptables.g" importer->reportError( std::string("Unknown option: ")+LT(0)->getText()); *dbg << " UNKNOWN OPTION=" << LT(0)->getText(); #line 1923 "IPTCfgParser.cpp" } { switch ( LA(1)) { case WORD: case INT_CONST: case DIGIT: { unknown_parameter(); break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::unknown_parameter() { #line 341 "iptables.g" std::string s; #line 1991 "IPTCfgParser.cpp" try { // for error handling if ((LA(1) == INT_CONST || LA(1) == DIGIT) && (LA(2) == SLASH)) { { { { switch ( LA(1)) { case DIGIT: { match(DIGIT); if ( inputState->guessing==0 ) { #line 347 "iptables.g" s+=LT(0)->getText(); #line 2005 "IPTCfgParser.cpp" } break; } case INT_CONST: { match(INT_CONST); if ( inputState->guessing==0 ) { #line 349 "iptables.g" s+=LT(0)->getText(); #line 2015 "IPTCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(SLASH); if ( inputState->guessing==0 ) { #line 351 "iptables.g" s+=LT(0)->getText(); #line 2029 "IPTCfgParser.cpp" } match(WORD); if ( inputState->guessing==0 ) { #line 352 "iptables.g" s+=LT(0)->getText(); #line 2035 "IPTCfgParser.cpp" } } if ( inputState->guessing==0 ) { #line 354 "iptables.g" importer->reportError( std::string("Unknown parameter: ")+s); *dbg << " UNKNOWN PARMETER=" << s; #line 2045 "IPTCfgParser.cpp" } } } else if ((LA(1) == WORD || LA(1) == INT_CONST || LA(1) == DIGIT) && (_tokenSet_5.member(LA(2)))) { { { switch ( LA(1)) { case DIGIT: { match(DIGIT); break; } case INT_CONST: { match(INT_CONST); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 363 "iptables.g" importer->reportError( std::string("Unknown parameter: ")+LT(0)->getText()); *dbg << " UNKNOWN PARMETER=" << LT(0)->getText(); #line 2081 "IPTCfgParser.cpp" } } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_state() { try { // for error handling match(M_STATE); match(MATCH_STATE); if ( inputState->guessing==0 ) { #line 701 "iptables.g" importer->current_state = ""; #line 2110 "IPTCfgParser.cpp" } state_word(); if ( inputState->guessing==0 ) { #line 705 "iptables.g" importer->current_state += LT(0)->getText(); #line 2118 "IPTCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); state_word(); if ( inputState->guessing==0 ) { #line 710 "iptables.g" importer->current_state += std::string(",") + LT(0)->getText(); #line 2130 "IPTCfgParser.cpp" } } else { goto _loop76; } } _loop76:; } // ( ... )* if ( inputState->guessing==0 ) { #line 714 "iptables.g" *dbg << " STATE MATCH=" << importer->current_state; #line 2145 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_mport() { try { // for error handling match(M_MPORT); if ( inputState->guessing==0 ) { #line 873 "iptables.g" *dbg << " MULTIPORT"; #line 2167 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_icmp() { try { // for error handling match(ICMP); if ( inputState->guessing==0 ) { #line 960 "iptables.g" importer->protocol = "icmp"; *dbg << " ICMP"; #line 2190 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_tcp() { try { // for error handling match(TCP); if ( inputState->guessing==0 ) { #line 1099 "iptables.g" importer->protocol = "tcp"; *dbg << " TCP"; #line 2213 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_udp() { try { // for error handling match(UDP); if ( inputState->guessing==0 ) { #line 1090 "iptables.g" importer->protocol = "udp"; *dbg << " UDP"; #line 2236 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_limit() { try { // for error handling match(M_LIMIT); if ( inputState->guessing==0 ) { #line 743 "iptables.g" *dbg << " LIMIT"; #line 2258 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_length() { try { // for error handling match(M_LENGTH); if ( inputState->guessing==0 ) { #line 838 "iptables.g" *dbg << " LENGTH"; #line 2280 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_iprange() { try { // for error handling match(M_IPRANGE); if ( inputState->guessing==0 ) { #line 782 "iptables.g" *dbg << " IPRANGE"; #line 2302 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_comment() { try { // for error handling match(M_COMMENT); match(MATCH_COMMENT); match(STRING); if ( inputState->guessing==0 ) { #line 881 "iptables.g" *dbg << " COMMENT=" << LT(0)->getText(); #line 2326 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_pkttype() { try { // for error handling match(M_PKTTYPE); match(MATCH_PKT_TYPE); pkt_type_spec(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_unknown_module() { try { // for error handling match(WORD); if ( inputState->guessing==0 ) { #line 688 "iptables.g" *dbg << " UNKNOWN MODULE=" << LT(0)->getText(); importer->reportError( std::string("Unknown module: ")+LT(0)->getText()); #line 2367 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::protocol_word() { try { // for error handling { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } case ICMP: { match(ICMP); break; } case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::target_options() { ANTLR_USE_NAMESPACE(antlr)RefToken major = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken minor = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case REJECT_WITH: { match(REJECT_WITH); match(WORD); if ( inputState->guessing==0 ) { #line 479 "iptables.g" importer->action_params["reject_with"] = LT(0)->getText(); *dbg << " REJECT WITH=" << LT(0)->getText(); #line 2444 "IPTCfgParser.cpp" } break; } case LOG_PREFIX: { match(LOG_PREFIX); { switch ( LA(1)) { case WORD: { match(WORD); break; } case STRING: { match(STRING); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 485 "iptables.g" importer->action_params["log_prefix"] = LT(0)->getText(); *dbg << " LOG PREFIX=" << LT(0)->getText(); #line 2475 "IPTCfgParser.cpp" } break; } case LOG_TCP_SEQ: { match(LOG_TCP_SEQ); if ( inputState->guessing==0 ) { #line 491 "iptables.g" importer->action_params["log_tcp_seq"] = LT(0)->getText(); *dbg << " LOG TCP SEQUENCE="; #line 2488 "IPTCfgParser.cpp" } break; } case LOG_TCP_OPT: { match(LOG_TCP_OPT); if ( inputState->guessing==0 ) { #line 497 "iptables.g" importer->action_params["log_tcp_options"] = LT(0)->getText(); *dbg << " LOG TCP OPTIONS="; #line 2501 "IPTCfgParser.cpp" } break; } case LOG_IP_OPT: { match(LOG_IP_OPT); if ( inputState->guessing==0 ) { #line 503 "iptables.g" importer->action_params["log_ip_options"] = LT(0)->getText(); *dbg << " LOG IP OPTIONS="; #line 2514 "IPTCfgParser.cpp" } break; } case ULOG_PREFIX: { match(ULOG_PREFIX); { switch ( LA(1)) { case WORD: { match(WORD); break; } case STRING: { match(STRING); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 509 "iptables.g" importer->action_params["log_prefix"] = LT(0)->getText(); *dbg << " ULOG PREFIX=" << LT(0)->getText(); #line 2545 "IPTCfgParser.cpp" } break; } case LOG_LEVEL: { match(LOG_LEVEL); { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 515 "iptables.g" importer->action_params["log_level"] = LT(0)->getText(); *dbg << " LOG LEVEL=" << LT(0)->getText(); #line 2576 "IPTCfgParser.cpp" } break; } case SET_CLASS: { match(SET_CLASS); major = LT(1); match(INT_CONST); match(COLON); minor = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 521 "iptables.g" importer->action_params["set_class"] = major->getText() + ":" + minor->getText(); *dbg << " SET CLASS=" << major->getText() + ":" + minor->getText(); #line 2595 "IPTCfgParser.cpp" } break; } case SET_MARK: { match(SET_MARK); { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case HEX_CONST: { match(HEX_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 528 "iptables.g" importer->action_params["set_mark"] = LT(0)->getText(); *dbg << " SET MARK=" << LT(0)->getText(); #line 2626 "IPTCfgParser.cpp" } break; } case SAVE_MARK: { match(SAVE_MARK); if ( inputState->guessing==0 ) { #line 546 "iptables.g" importer->action_params["connmark_save_mark"] = "--save-mark"; *dbg << " SAVE MARK"; #line 2639 "IPTCfgParser.cpp" } break; } case RESTORE_MARK: { match(RESTORE_MARK); if ( inputState->guessing==0 ) { #line 552 "iptables.g" importer->action_params["connmark_restore_mark"] = "--restore-mark"; *dbg << " RESTORE MARK"; #line 2652 "IPTCfgParser.cpp" } break; } case CONTINUE: { match(CONTINUE); if ( inputState->guessing==0 ) { #line 558 "iptables.g" importer->action_params["route_continue"] = "--continue"; *dbg << " CONTINUE"; #line 2665 "IPTCfgParser.cpp" } break; } case ROUTE_IIF: { match(ROUTE_IIF); match(WORD); if ( inputState->guessing==0 ) { #line 564 "iptables.g" importer->action_params["route_iif"] = LT(0)->getText(); *dbg << " ROUTE_IIF=" << LT(0)->getText(); #line 2679 "IPTCfgParser.cpp" } break; } case ROUTE_OIF: { match(ROUTE_OIF); match(WORD); if ( inputState->guessing==0 ) { #line 570 "iptables.g" importer->action_params["route_oif"] = LT(0)->getText(); *dbg << " ROUTE_OIF=" << LT(0)->getText(); #line 2693 "IPTCfgParser.cpp" } break; } case ROUTE_GW: { match(ROUTE_GW); match(IPV4); if ( inputState->guessing==0 ) { #line 576 "iptables.g" importer->action_params["route_gw"] = LT(0)->getText(); *dbg << " ROUTE_GW=" << LT(0)->getText(); #line 2707 "IPTCfgParser.cpp" } break; } case ROUTE_TEE: { match(ROUTE_TEE); if ( inputState->guessing==0 ) { #line 582 "iptables.g" importer->action_params["route_tee"] = "--tee"; *dbg << " ROUTE_TEE"; #line 2720 "IPTCfgParser.cpp" } break; } case TO_SOURCE: { match(TO_SOURCE); if ( inputState->guessing==0 ) { #line 588 "iptables.g" *dbg << " TO-SOURCE"; #line 2732 "IPTCfgParser.cpp" } nat_spec(); break; } case TO_DESTINATION: { match(TO_DESTINATION); if ( inputState->guessing==0 ) { #line 594 "iptables.g" *dbg << " TO-DESTINATION"; #line 2745 "IPTCfgParser.cpp" } nat_spec(); break; } case TO_PORTS: { match(TO_PORTS); redirect_spec(); break; } case TO_NETMAP: { match(TO_NETMAP); if ( inputState->guessing==0 ) { #line 602 "iptables.g" *dbg << " TO-NETMAP"; #line 2764 "IPTCfgParser.cpp" } { match(IPV4); if ( inputState->guessing==0 ) { #line 607 "iptables.g" importer->nat_addr1 = LT(0)->getText(); importer->nat_addr2 = LT(0)->getText(); *dbg << LT(0)->getText(); #line 2775 "IPTCfgParser.cpp" } match(SLASH); { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 613 "iptables.g" importer->nat_nm = LT(0)->getText(); *dbg << "/" << LT(0)->getText(); #line 2802 "IPTCfgParser.cpp" } } break; } case CLAMP_MSS: { match(CLAMP_MSS); if ( inputState->guessing==0 ) { #line 620 "iptables.g" importer->action_params["clamp-mss-to-pmtu"] = "--clamp-mss-to-pmtu"; *dbg << " TO-NETMAP"; #line 2816 "IPTCfgParser.cpp" } break; } default: if ((LA(1) == SET_TOS) && (LA(2) == HEX_CONST)) { match(SET_TOS); match(HEX_CONST); if ( inputState->guessing==0 ) { #line 534 "iptables.g" importer->action_params["set_tos"] = LT(0)->getText(); *dbg << " SET TOS=" << LT(0)->getText(); #line 2830 "IPTCfgParser.cpp" } } else if ((LA(1) == SET_TOS) && (LA(2) == WORD)) { match(SET_TOS); match(WORD); if ( inputState->guessing==0 ) { #line 540 "iptables.g" importer->action_params["set_tos"] = LT(0)->getText(); *dbg << " SET TOS=" << LT(0)->getText(); #line 2842 "IPTCfgParser.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_7); } else { throw; } } } void IPTCfgParser::nat_spec() { try { // for error handling nat_addr_range(); { switch ( LA(1)) { case COLON: { match(COLON); nat_port_def_with_range(); break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case REJECT_WITH: case LOG_PREFIX: case LOG_TCP_SEQ: case LOG_TCP_OPT: case LOG_IP_OPT: case ULOG_PREFIX: case LOG_LEVEL: case SET_CLASS: case SET_MARK: case SET_TOS: case SAVE_MARK: case RESTORE_MARK: case CONTINUE: case ROUTE_IIF: case ROUTE_OIF: case ROUTE_GW: case ROUTE_TEE: case TO_SOURCE: case TO_DESTINATION: case TO_PORTS: case TO_NETMAP: case CLAMP_MSS: case OPT_FRAGM: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 631 "iptables.g" *dbg << " " << importer->nat_addr1 << "-" << importer->nat_addr2 << ":" << importer->nat_port_range_start << "-" << importer->nat_port_range_end; #line 2944 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_7); } else { throw; } } } void IPTCfgParser::redirect_spec() { try { // for error handling nat_port_def_with_range(); if ( inputState->guessing==0 ) { #line 666 "iptables.g" *dbg << " TO-PORTS " << importer->nat_addr1 << "-" << importer->nat_addr2 << ":" << importer->nat_port_range_start << "-" << importer->nat_port_range_end; #line 2973 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_7); } else { throw; } } } void IPTCfgParser::nat_addr_range() { ANTLR_USE_NAMESPACE(antlr)RefToken a1 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken a2 = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling bool synPredMatched67 = false; if (((LA(1) == IPV4) && (LA(2) == MINUS))) { int _m67 = mark(); synPredMatched67 = true; inputState->guessing++; try { { match(IPV4); match(MINUS); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched67 = false; } rewind(_m67); inputState->guessing--; } if ( synPredMatched67 ) { { a1 = LT(1); match(IPV4); match(MINUS); a2 = LT(1); match(IPV4); if ( inputState->guessing==0 ) { #line 647 "iptables.g" importer->nat_port_range_start = ""; importer->nat_port_range_end = ""; importer->nat_addr1 = a1->getText(); importer->nat_addr2 = a2->getText(); #line 3023 "IPTCfgParser.cpp" } } } else if ((LA(1) == IPV4) && (_tokenSet_8.member(LA(2)))) { match(IPV4); if ( inputState->guessing==0 ) { #line 656 "iptables.g" importer->nat_port_range_start = ""; importer->nat_port_range_end = ""; importer->nat_addr1 = LT(0)->getText(); importer->nat_addr2 = LT(0)->getText(); #line 3037 "IPTCfgParser.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_8); } else { throw; } } } void IPTCfgParser::nat_port_def_with_range() { try { // for error handling bool synPredMatched137 = false; if (((LA(1) == WORD || LA(1) == INT_CONST) && (LA(2) == MINUS))) { int _m137 = mark(); synPredMatched137 = true; inputState->guessing++; try { { { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(MINUS); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched137 = false; } rewind(_m137); inputState->guessing--; } if ( synPredMatched137 ) { { { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1043 "iptables.g" importer->nat_port_range_start = LT(0)->getText(); importer->nat_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); #line 3119 "IPTCfgParser.cpp" } match(MINUS); { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1049 "iptables.g" importer->nat_port_range_end = LT(0)->getText(); *dbg << ":" << LT(0)->getText(); #line 3146 "IPTCfgParser.cpp" } } } else if ((LA(1) == WORD || LA(1) == INT_CONST) && (_tokenSet_7.member(LA(2)))) { { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1056 "iptables.g" importer->nat_port_range_start = LT(0)->getText(); importer->nat_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); #line 3176 "IPTCfgParser.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_7); } else { throw; } } } void IPTCfgParser::state_word() { try { // for error handling { switch ( LA(1)) { case INVALID: { match(INVALID); break; } case NEW: { match(NEW); break; } case ESTABLISHED: { match(ESTABLISHED); break; } case RELATED: { match(RELATED); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void IPTCfgParser::m_mark() { try { // for error handling match(M_MARK); if ( inputState->guessing==0 ) { #line 723 "iptables.g" *dbg << " MARK"; #line 3245 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_10); } else { throw; } } } void IPTCfgParser::limit_rate() { try { // for error handling match(INT_CONST); if ( inputState->guessing==0 ) { #line 754 "iptables.g" importer->limit_val = LT(0)->getText(); #line 3265 "IPTCfgParser.cpp" } match(SLASH); match(WORD); if ( inputState->guessing==0 ) { #line 756 "iptables.g" importer->limit_suffix = LT(0)->getText(); #line 3272 "IPTCfgParser.cpp" } if ( inputState->guessing==0 ) { #line 757 "iptables.g" *dbg << " MATCH LIMIT " << importer->limit_val << "/" << importer->limit_suffix; #line 3281 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::m_recent() { try { // for error handling match(M_RECENT); if ( inputState->guessing==0 ) { #line 774 "iptables.g" *dbg << " RECENT"; #line 3303 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_11); } else { throw; } } } void IPTCfgParser::recent_opts() { try { // for error handling switch ( LA(1)) { case MATCH_RECENT_SET: case MATCH_RECENT_RCHECK: case MATCH_RECENT_UPDATE: case MATCH_RECENT_REMOVE: case MATCH_RECENT_RTTL: case RSOURCE: case MATCH_RECENT_RDEST: { recent_args_no_param(); break; } case MATCH_RECENT_NAME: case MATCH_RECENT_SECONDS: case MATCH_RECENT_HITCOUNT: { recent_args_param(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_12); } else { throw; } } } void IPTCfgParser::recent_args_no_param() { try { // for error handling { switch ( LA(1)) { case MATCH_RECENT_SET: { match(MATCH_RECENT_SET); break; } case MATCH_RECENT_RCHECK: { match(MATCH_RECENT_RCHECK); break; } case MATCH_RECENT_UPDATE: { match(MATCH_RECENT_UPDATE); break; } case MATCH_RECENT_REMOVE: { match(MATCH_RECENT_REMOVE); break; } case MATCH_RECENT_RTTL: { match(MATCH_RECENT_RTTL); break; } case RSOURCE: { match(RSOURCE); break; } case MATCH_RECENT_RDEST: { match(MATCH_RECENT_RDEST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 826 "iptables.g" importer->recent_match += LT(0)->getText() + " "; #line 3403 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_12); } else { throw; } } } void IPTCfgParser::recent_args_param() { try { // for error handling { switch ( LA(1)) { case MATCH_RECENT_NAME: { match(MATCH_RECENT_NAME); break; } case MATCH_RECENT_SECONDS: { match(MATCH_RECENT_SECONDS); break; } case MATCH_RECENT_HITCOUNT: { match(MATCH_RECENT_HITCOUNT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 830 "iptables.g" importer->recent_match += LT(0)->getText() + " "; #line 3445 "IPTCfgParser.cpp" } { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 832 "iptables.g" importer->recent_match += LT(0)->getText() + " "; #line 3468 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_12); } else { throw; } } } void IPTCfgParser::length_spec() { try { // for error handling match(INT_CONST); if ( inputState->guessing==0 ) { #line 849 "iptables.g" importer->length_spec = LT(0)->getText(); #line 3488 "IPTCfgParser.cpp" } match(COLON); match(INT_CONST); if ( inputState->guessing==0 ) { #line 851 "iptables.g" importer->length_spec += ":"; importer->length_spec += LT(0)->getText(); #line 3496 "IPTCfgParser.cpp" } if ( inputState->guessing==0 ) { #line 853 "iptables.g" *dbg << " MATCH LENGTH " << importer->length_spec; #line 3503 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::pkt_type_spec() { try { // for error handling { switch ( LA(1)) { case WORD_BROADCAST: { match(WORD_BROADCAST); break; } case WORD_MULTICAST: { match(WORD_MULTICAST); break; } case WORD_UNICAST: { match(WORD_UNICAST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 864 "iptables.g" importer->pkt_type_spec = LT(0)->getText(); *dbg << " PKT_TYPE " << importer->pkt_type_spec; #line 3548 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } /**************************************************************** * port definition that allows for port range. That parser should * recognize constructs * * port1 ---> range_start = range_end = port1 * port1:port2 ---> range_start = port1 range_end = port2 * port1: ---> range_start = port1 range_end = 65535 * :port2 ---> range_start = 0 range_end = port2 */ void IPTCfgParser::port_def_with_range() { try { // for error handling { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1014 "iptables.g" importer->tmp_port_range_start = LT(0)->getText(); importer->tmp_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); #line 3598 "IPTCfgParser.cpp" } { switch ( LA(1)) { case COLON: { match(COLON); { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case COMMA: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1021 "iptables.g" importer->tmp_port_range_end = LT(0)->getText(); *dbg << ":" << LT(0)->getText(); #line 3661 "IPTCfgParser.cpp" } break; } case NEWLINE: case MINUS: case EXCLAMATION: case UNSUPPORTED_OPTION: case OPT_MODULE: case OPT_SRC: case OPT_DST: case OPT_IN_INTF: case OPT_OUT_INTF: case OPT_PROTO: case OPT_TARGET: case OPT_FRAGM: case COMMA: case MATCH_LIMIT: case MATCH_LIMIT_BURST: case MATCH_IPRANGE_SRC: case MATCH_IPRANGE_DST: case MATCH_LENGTH: case MATCH_SRC_MULTIPORT: case MATCH_DST_MULTIPORT: case MATCH_BOTH_MULTIPORT: case MATCH_ICMP_TYPE: case MATCH_SRC_PORT: case MATCH_SRC_PORT_SHORT: case MATCH_DST_PORT: case MATCH_DST_PORT_SHORT: case MATCH_SYN: case MATCH_TCP_FLAGS: case MATCH_TCP_OPTION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void IPTCfgParser::port_def_no_range() { try { // for error handling { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 996 "iptables.g" importer->tmp_port_range_start = LT(0)->getText(); importer->tmp_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); #line 3742 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_0); } else { throw; } } } void IPTCfgParser::port_def_with_incomplete_range() { try { // for error handling match(COLON); { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1030 "iptables.g" importer->tmp_port_range_start = "0"; importer->tmp_port_range_end = LT(0)->getText(); *dbg << "PORT 0:" << LT(0)->getText(); #line 3784 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::syn() { try { // for error handling match(MATCH_SYN); if ( inputState->guessing==0 ) { #line 1118 "iptables.g" importer->tcp_flags_mask.clear(); importer->tcp_flags_mask.push_back(libfwbuilder::TCPService::SYN); importer->tcp_flags_mask.push_back(libfwbuilder::TCPService::RST); importer->tcp_flags_mask.push_back(libfwbuilder::TCPService::ACK); importer->tcp_flags_comp.clear(); importer->tcp_flags_comp.push_back(libfwbuilder::TCPService::SYN); #line 3812 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::tcp_flags() { try { // for error handling match(MATCH_TCP_FLAGS); tcp_flags_list(); if ( inputState->guessing==0 ) { #line 1169 "iptables.g" importer->tcp_flags_mask = importer->tmp_tcp_flags_list; importer->tmp_tcp_flags_list.clear(); #line 3836 "IPTCfgParser.cpp" } tcp_flags_list(); if ( inputState->guessing==0 ) { #line 1174 "iptables.g" importer->tcp_flags_comp = importer->tmp_tcp_flags_list; importer->tmp_tcp_flags_list.clear(); *dbg << " TCP FLAGS="; foreach(int x, importer->tcp_flags_mask) *dbg << x << "|"; *dbg << " "; foreach(int x, importer->tcp_flags_comp) *dbg << x << "|"; #line 3851 "IPTCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::tcp_option() { try { // for error handling match(MATCH_TCP_OPTION); match(INT_CONST); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void IPTCfgParser::tcp_flag_word() { try { // for error handling { switch ( LA(1)) { case SYN: { match(SYN); if ( inputState->guessing==0 ) { #line 1131 "iptables.g" importer->tmp_tcp_flag_code = libfwbuilder::TCPService::SYN; #line 3891 "IPTCfgParser.cpp" } break; } case ACK: { match(ACK); if ( inputState->guessing==0 ) { #line 1133 "iptables.g" importer->tmp_tcp_flag_code = libfwbuilder::TCPService::ACK; #line 3901 "IPTCfgParser.cpp" } break; } case FIN: { match(FIN); if ( inputState->guessing==0 ) { #line 1135 "iptables.g" importer->tmp_tcp_flag_code = libfwbuilder::TCPService::FIN; #line 3911 "IPTCfgParser.cpp" } break; } case RST: { match(RST); if ( inputState->guessing==0 ) { #line 1137 "iptables.g" importer->tmp_tcp_flag_code = libfwbuilder::TCPService::RST; #line 3921 "IPTCfgParser.cpp" } break; } case URG: { match(URG); if ( inputState->guessing==0 ) { #line 1139 "iptables.g" importer->tmp_tcp_flag_code = libfwbuilder::TCPService::URG; #line 3931 "IPTCfgParser.cpp" } break; } case PSH: { match(PSH); if ( inputState->guessing==0 ) { #line 1141 "iptables.g" importer->tmp_tcp_flag_code = libfwbuilder::TCPService::PSH; #line 3941 "IPTCfgParser.cpp" } break; } case ALL: { match(ALL); if ( inputState->guessing==0 ) { #line 1143 "iptables.g" importer->tmp_tcp_flag_code = 99; #line 3951 "IPTCfgParser.cpp" } break; } case NONE: { match(NONE); if ( inputState->guessing==0 ) { #line 1145 "iptables.g" importer->tmp_tcp_flag_code = 98; #line 3961 "IPTCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_13); } else { throw; } } } void IPTCfgParser::tcp_flags_list() { try { // for error handling if ( inputState->guessing==0 ) { #line 1150 "iptables.g" importer->tmp_tcp_flags_list.clear(); importer->tmp_tcp_flag_code = 0; #line 3991 "IPTCfgParser.cpp" } tcp_flag_word(); if ( inputState->guessing==0 ) { #line 1155 "iptables.g" importer->tmp_tcp_flags_list.push_back(importer->tmp_tcp_flag_code); #line 3999 "IPTCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); tcp_flag_word(); if ( inputState->guessing==0 ) { #line 1160 "iptables.g" importer->tmp_tcp_flags_list.push_back( importer->tmp_tcp_flag_code); #line 4012 "IPTCfgParser.cpp" } } else { goto _loop156; } } _loop156:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_14); } else { throw; } } } void IPTCfgParser::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* IPTCfgParser::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "NEWLINE", "NUMBER_SIGN", "IPTABLES_SAVE_HEADER", "THREE_COMPONENT_VERSION", "IPV4", "\"COMMIT\"", "STAR", "WORD", "\"INPUT\"", "\"FORWARD\"", "\"OUTPUT\"", "\"PREROUTING\"", "\"POSTROUTING\"", "COLON", "MINUS", "OPENING_SQUARE", "INT_CONST", "CLOSING_SQUARE", "ADD_RULE", "EXCLAMATION", "UNSUPPORTED_OPTION", "DIGIT", "SLASH", "OPT_MODULE", "OPT_SRC", "OPT_DST", "OPT_IN_INTF", "OPT_OUT_INTF", "\"tcp\"", "\"udp\"", "\"icmp\"", "OPT_PROTO", "OPT_TARGET", "REJECT_WITH", "LOG_PREFIX", "STRING", "LOG_TCP_SEQ", "LOG_TCP_OPT", "LOG_IP_OPT", "ULOG_PREFIX", "LOG_LEVEL", "SET_CLASS", "SET_MARK", "HEX_CONST", "SET_TOS", "SAVE_MARK", "RESTORE_MARK", "CONTINUE", "ROUTE_IIF", "ROUTE_OIF", "ROUTE_GW", "ROUTE_TEE", "TO_SOURCE", "TO_DESTINATION", "TO_PORTS", "TO_NETMAP", "CLAMP_MSS", "OPT_FRAGM", "\"INVALID\"", "\"NEW\"", "\"ESTABLISHED\"", "\"RELATED\"", "\"state\"", "MATCH_STATE", "COMMA", "\"mark\"", "MATCH_MARK", "\"limit\"", "MATCH_LIMIT", "MATCH_LIMIT_BURST", "\"recent\"", "\"iprange\"", "MATCH_IPRANGE_SRC", "MATCH_IPRANGE_DST", "MATCH_RECENT_SET", "MATCH_RECENT_RCHECK", "MATCH_RECENT_UPDATE", "MATCH_RECENT_REMOVE", "MATCH_RECENT_RTTL", "RSOURCE", "MATCH_RECENT_RDEST", "MATCH_RECENT_NAME", "MATCH_RECENT_SECONDS", "MATCH_RECENT_HITCOUNT", "\"length\"", "MATCH_LENGTH", "\"pkttype\"", "MATCH_PKT_TYPE", "\"broadcast\"", "\"multicast\"", "\"unicast\"", "\"multiport\"", "\"comment\"", "MATCH_COMMENT", "MATCH_SRC_MULTIPORT", "MATCH_DST_MULTIPORT", "MATCH_BOTH_MULTIPORT", "MATCH_ICMP_TYPE", "MATCH_SRC_PORT", "MATCH_SRC_PORT_SHORT", "MATCH_DST_PORT", "MATCH_DST_PORT_SHORT", "MATCH_SYN", "\"SYN\"", "\"ACK\"", "\"FIN\"", "\"RST\"", "\"URG\"", "\"PSH\"", "\"ALL\"", "\"NONE\"", "MATCH_TCP_FLAGS", "MATCH_TCP_OPTION", "Whitespace", "IPV6", "MAC_ADDRESS", "NEG_INT_CONST", "HEXDIGIT", "NUM_3DIGIT", "NUM_HEX_4DIGIT", "NUMBER", "ULOG_QTHR", "ULOG_NLG", "ULOG_CPR", "PERCENT", "AMPERSAND", "APOSTROPHE", "OPENING_PAREN", "CLOSING_PAREN", "PLUS", "DOT", "SEMICOLON", "LESS_THAN", "EQUALS", "GREATER_THAN", "QUESTION", "COMMERCIAL_AT", "CARET", "UNDERLINE", "OPENING_BRACE", "CLOSING_BRACE", "TILDE", 0 }; const unsigned long IPTCfgParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_0(_tokenSet_0_data_,6); const unsigned long IPTCfgParser::_tokenSet_1_data_[] = { 4326962UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE NUMBER_SIGN "COMMIT" STAR COLON ADD_RULE const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_1(_tokenSet_1_data_,6); const unsigned long IPTCfgParser::_tokenSet_2_data_[] = { 4186177536UL, 536870936UL, 33567488UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST OPT_IN_INTF // OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM MATCH_LIMIT MATCH_LIMIT_BURST // MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH MATCH_SRC_MULTIPORT // MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE MATCH_SRC_PORT // MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT MATCH_SYN MATCH_TCP_FLAGS // MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_2(_tokenSet_2_data_,8); const unsigned long IPTCfgParser::_tokenSet_3_data_[] = { 4186179584UL, 536870936UL, 33567488UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // WORD MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM MATCH_LIMIT // MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH MATCH_SRC_MULTIPORT // MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE MATCH_SRC_PORT // MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT MATCH_SYN MATCH_TCP_FLAGS // MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_3(_tokenSet_3_data_,8); const unsigned long IPTCfgParser::_tokenSet_4_data_[] = { 2048UL, 7UL, 2231371908UL, 1UL, 0UL, 0UL, 0UL, 0UL }; // WORD "tcp" "udp" "icmp" "state" "limit" "iprange" "length" "pkttype" // "multiport" "comment" const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_4(_tokenSet_4_data_,8); const unsigned long IPTCfgParser::_tokenSet_5_data_[] = { 4186177552UL, 536870936UL, 33567488UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM MATCH_LIMIT // MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH MATCH_SRC_MULTIPORT // MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE MATCH_SRC_PORT // MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT MATCH_SYN MATCH_TCP_FLAGS // MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_5(_tokenSet_5_data_,8); const unsigned long IPTCfgParser::_tokenSet_6_data_[] = { 0UL, 536837984UL, 0UL, 0UL, 0UL, 0UL }; // REJECT_WITH LOG_PREFIX LOG_TCP_SEQ LOG_TCP_OPT LOG_IP_OPT ULOG_PREFIX // LOG_LEVEL SET_CLASS SET_MARK SET_TOS SAVE_MARK RESTORE_MARK CONTINUE // ROUTE_IIF ROUTE_OIF ROUTE_GW ROUTE_TEE TO_SOURCE TO_DESTINATION TO_PORTS // TO_NETMAP CLAMP_MSS const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_6(_tokenSet_6_data_,6); const unsigned long IPTCfgParser::_tokenSet_7_data_[] = { 4186177552UL, 1073708920UL, 33567488UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET REJECT_WITH LOG_PREFIX // LOG_TCP_SEQ LOG_TCP_OPT LOG_IP_OPT ULOG_PREFIX LOG_LEVEL SET_CLASS SET_MARK // SET_TOS SAVE_MARK RESTORE_MARK CONTINUE ROUTE_IIF ROUTE_OIF ROUTE_GW // ROUTE_TEE TO_SOURCE TO_DESTINATION TO_PORTS TO_NETMAP CLAMP_MSS OPT_FRAGM // MATCH_LIMIT MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH // MATCH_SRC_MULTIPORT MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE // MATCH_SRC_PORT MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT // MATCH_SYN MATCH_TCP_FLAGS MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_7(_tokenSet_7_data_,8); const unsigned long IPTCfgParser::_tokenSet_8_data_[] = { 4186308624UL, 1073708920UL, 33567488UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE COLON MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC // OPT_DST OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET REJECT_WITH LOG_PREFIX // LOG_TCP_SEQ LOG_TCP_OPT LOG_IP_OPT ULOG_PREFIX LOG_LEVEL SET_CLASS SET_MARK // SET_TOS SAVE_MARK RESTORE_MARK CONTINUE ROUTE_IIF ROUTE_OIF ROUTE_GW // ROUTE_TEE TO_SOURCE TO_DESTINATION TO_PORTS TO_NETMAP CLAMP_MSS OPT_FRAGM // MATCH_LIMIT MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH // MATCH_SRC_MULTIPORT MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE // MATCH_SRC_PORT MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT // MATCH_SYN MATCH_TCP_FLAGS MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_8(_tokenSet_8_data_,8); const unsigned long IPTCfgParser::_tokenSet_9_data_[] = { 4186177552UL, 536870936UL, 33567504UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM COMMA MATCH_LIMIT // MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH MATCH_SRC_MULTIPORT // MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE MATCH_SRC_PORT // MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT MATCH_SYN MATCH_TCP_FLAGS // MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_9(_tokenSet_9_data_,8); const unsigned long IPTCfgParser::_tokenSet_10_data_[] = { 8388608UL, 0UL, 64UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EXCLAMATION MATCH_MARK const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_10(_tokenSet_10_data_,8); const unsigned long IPTCfgParser::_tokenSet_11_data_[] = { 0UL, 0UL, 16760832UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // MATCH_RECENT_SET MATCH_RECENT_RCHECK MATCH_RECENT_UPDATE MATCH_RECENT_REMOVE // MATCH_RECENT_RTTL RSOURCE MATCH_RECENT_RDEST MATCH_RECENT_NAME MATCH_RECENT_SECONDS // MATCH_RECENT_HITCOUNT const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_11(_tokenSet_11_data_,8); const unsigned long IPTCfgParser::_tokenSet_12_data_[] = { 4186177552UL, 536870936UL, 50328320UL, 1574908UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM MATCH_LIMIT // MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_RECENT_SET // MATCH_RECENT_RCHECK MATCH_RECENT_UPDATE MATCH_RECENT_REMOVE MATCH_RECENT_RTTL // RSOURCE MATCH_RECENT_RDEST MATCH_RECENT_NAME MATCH_RECENT_SECONDS MATCH_RECENT_HITCOUNT // MATCH_LENGTH MATCH_SRC_MULTIPORT MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT // MATCH_ICMP_TYPE MATCH_SRC_PORT MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT // MATCH_SYN MATCH_TCP_FLAGS MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_12(_tokenSet_12_data_,8); const unsigned long IPTCfgParser::_tokenSet_13_data_[] = { 4186177552UL, 536870936UL, 33567504UL, 2097148UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM COMMA MATCH_LIMIT // MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH MATCH_SRC_MULTIPORT // MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE MATCH_SRC_PORT // MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT MATCH_SYN "SYN" // "ACK" "FIN" "RST" "URG" "PSH" "ALL" "NONE" MATCH_TCP_FLAGS MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_13(_tokenSet_13_data_,8); const unsigned long IPTCfgParser::_tokenSet_14_data_[] = { 4186177552UL, 536870936UL, 33567488UL, 2097148UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE MINUS EXCLAMATION UNSUPPORTED_OPTION OPT_MODULE OPT_SRC OPT_DST // OPT_IN_INTF OPT_OUT_INTF OPT_PROTO OPT_TARGET OPT_FRAGM MATCH_LIMIT // MATCH_LIMIT_BURST MATCH_IPRANGE_SRC MATCH_IPRANGE_DST MATCH_LENGTH MATCH_SRC_MULTIPORT // MATCH_DST_MULTIPORT MATCH_BOTH_MULTIPORT MATCH_ICMP_TYPE MATCH_SRC_PORT // MATCH_SRC_PORT_SHORT MATCH_DST_PORT MATCH_DST_PORT_SHORT MATCH_SYN "SYN" // "ACK" "FIN" "RST" "URG" "PSH" "ALL" "NONE" MATCH_TCP_FLAGS MATCH_TCP_OPTION const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgParser::_tokenSet_14(_tokenSet_14_data_,8); fwbuilder-5.1.0.3599/src/parsers/IfconfigBSDCfgLexer.cpp0000644000175000017500000013042411733011756023451 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20100319): "ifconfig_bsd.g" -> "IfconfigBSDCfgLexer.cpp"$ */ #line 43 "ifconfig_bsd.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IfconfigBSDCfgLexer.cpp" #include "IfconfigBSDCfgLexer.hpp" #include #include #include #include #include #include #include #line 49 "ifconfig_bsd.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 25 "IfconfigBSDCfgLexer.cpp" #line 1 "ifconfig_bsd.g" #line 27 "IfconfigBSDCfgLexer.cpp" IfconfigBSDCfgLexer::IfconfigBSDCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in) : ANTLR_USE_NAMESPACE(antlr)CharScanner(new ANTLR_USE_NAMESPACE(antlr)CharBuffer(in),true) { initLiterals(); } IfconfigBSDCfgLexer::IfconfigBSDCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib) : ANTLR_USE_NAMESPACE(antlr)CharScanner(ib,true) { initLiterals(); } IfconfigBSDCfgLexer::IfconfigBSDCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)CharScanner(state,true) { initLiterals(); } void IfconfigBSDCfgLexer::initLiterals() { literals["priority"] = 7; literals["broadcast"] = 21; literals["Scope"] = 35; literals["scopeid"] = 26; literals["Host"] = 30; literals["UP"] = 39; literals["groups"] = 27; literals["HWaddr"] = 49; literals["encap"] = 37; literals["NOARP"] = 43; literals["Mask"] = 34; literals["netmask"] = 19; literals["RUNNING"] = 44; literals["inet"] = 17; literals["media"] = 8; literals["BROADCAST"] = 40; literals["P-t-P"] = 33; literals["prefixlen"] = 25; literals["Loopback"] = 38; literals["Interrupt"] = 48; literals["Bcast"] = 32; literals["mtu"] = 36; literals["inet6"] = 22; literals["status"] = 9; literals["LOOPBACK"] = 42; literals["Link"] = 28; literals["TX"] = 46; literals["addr"] = 31; literals["RX"] = 45; literals["Global"] = 29; literals["POINTOPOINT"] = 41; literals["flags"] = 12; literals["lladdr"] = 50; literals["collisions"] = 47; } ANTLR_USE_NAMESPACE(antlr)RefToken IfconfigBSDCfgLexer::nextToken() { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; for (;;) { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; int _ttype = ANTLR_USE_NAMESPACE(antlr)Token::INVALID_TYPE; resetText(); try { // for lexical and char stream error handling switch ( LA(1)) { case 0x23 /* '#' */ : { mLINE_COMMENT(true); theRetToken=_returnToken; break; } case 0xa /* '\n' */ : case 0xd /* '\r' */ : { mNEWLINE(true); theRetToken=_returnToken; break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : case 0x3a /* ':' */ : case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { mNUMBER_ADDRESS_OR_WORD(true); theRetToken=_returnToken; break; } case 0x25 /* '%' */ : { mPERCENT(true); theRetToken=_returnToken; break; } case 0x26 /* '&' */ : { mAMPERSAND(true); theRetToken=_returnToken; break; } case 0x2a /* '*' */ : { mSTAR(true); theRetToken=_returnToken; break; } case 0x2d /* '-' */ : { mMINUS(true); theRetToken=_returnToken; break; } case 0x2e /* '.' */ : { mDOT(true); theRetToken=_returnToken; break; } case 0x2f /* '/' */ : { mSLASH(true); theRetToken=_returnToken; break; } case 0x3d /* '=' */ : { mEQUAL(true); theRetToken=_returnToken; break; } case 0x3f /* '?' */ : { mQUESTION(true); theRetToken=_returnToken; break; } case 0x28 /* '(' */ : { mOPENING_PAREN(true); theRetToken=_returnToken; break; } case 0x29 /* ')' */ : { mCLOSING_PAREN(true); theRetToken=_returnToken; break; } case 0x5b /* '[' */ : { mOPENING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5d /* ']' */ : { mCLOSING_SQUARE(true); theRetToken=_returnToken; break; } case 0x7b /* '{' */ : { mOPENING_BRACE(true); theRetToken=_returnToken; break; } case 0x7d /* '}' */ : { mCLOSING_BRACE(true); theRetToken=_returnToken; break; } case 0x3c /* '<' */ : { mLESS_THAN(true); theRetToken=_returnToken; break; } case 0x3e /* '>' */ : { mGREATER_THAN(true); theRetToken=_returnToken; break; } default: if ((_tokenSet_0.member(LA(1)))) { mWhitespace(true); theRetToken=_returnToken; } else { if (LA(1)==EOF_CHAR) { uponEOF(); _returnToken = makeToken(ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE); } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } if ( !_returnToken ) goto tryAgain; // found SKIP token _ttype = _returnToken->getType(); _ttype = testLiteralsTable(_ttype); _returnToken->setType(_ttype); return _returnToken; } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& e) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamRecognitionException(e); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamIOException& csie) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamIOException(csie.io); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamException& cse) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamException(cse.getMessage()); } tryAgain:; } } void IfconfigBSDCfgLexer::mLINE_COMMENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LINE_COMMENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("#"); { // ( ... )* for (;;) { if ((_tokenSet_1.member(LA(1)))) { { match(_tokenSet_1); } } else { goto _loop18; } } _loop18:; } // ( ... )* mNEWLINE(false); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mNEWLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEWLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { if ((LA(1) == 0xd /* '\r' */ ) && (LA(2) == 0xa /* '\n' */ )) { match("\r\n"); } else if ((LA(1) == 0xd /* '\r' */ ) && (true)) { match('\r' /* charlit */ ); } else if ((LA(1) == 0xa /* '\n' */ )) { match('\n' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 388 "ifconfig_bsd.g" newline(); #line 357 "IfconfigBSDCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mWhitespace(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = Whitespace; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x3 /* '\3' */ : case 0x4 /* '\4' */ : case 0x5 /* '\5' */ : case 0x6 /* '\6' */ : case 0x7 /* '\7' */ : case 0x8 /* '\10' */ : { matchRange('\3','\10'); break; } case 0x9 /* '\t' */ : { match('\t' /* charlit */ ); break; } case 0xb /* '\13' */ : { match('\13' /* charlit */ ); break; } case 0xc /* '\14' */ : { match('\14' /* charlit */ ); break; } case 0xe /* '\16' */ : case 0xf /* '\17' */ : case 0x10 /* '\20' */ : case 0x11 /* '\21' */ : case 0x12 /* '\22' */ : case 0x13 /* '\23' */ : case 0x14 /* '\24' */ : case 0x15 /* '\25' */ : case 0x16 /* '\26' */ : case 0x17 /* '\27' */ : case 0x18 /* '\30' */ : case 0x19 /* '\31' */ : case 0x1a /* '\32' */ : case 0x1b /* '\33' */ : case 0x1c /* '\34' */ : case 0x1d /* '\35' */ : case 0x1e /* '\36' */ : case 0x1f /* '\37' */ : { matchRange('\16','\37'); break; } case 0x20 /* ' ' */ : { match(' ' /* charlit */ ); break; } default: if (((LA(1) >= 0x7f && LA(1) <= 0xff))) { matchRange('\177',static_cast('\377')); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( inputState->guessing==0 ) { #line 294 "ifconfig_bsd.g" _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; #line 438 "IfconfigBSDCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mINT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mHEX_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mNUMBER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mNEG_INT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEG_INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mCOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mHEX_DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : { matchRange('A','F'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('0','9'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mNUM_3DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_3DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { matchRange('0','9'); } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mNUM_HEX_4DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_HEX_4DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; mHEX_DIGIT(false); { if ((_tokenSet_2.member(LA(1)))) { { mHEX_DIGIT(false); } { if ((_tokenSet_2.member(LA(1)))) { { mHEX_DIGIT(false); } { if ((_tokenSet_2.member(LA(1)))) { mHEX_DIGIT(false); } else { } } } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mMAC_ADDRESS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MAC_ADDRESS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mNUMBER_ADDRESS_OR_WORD(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_ADDRESS_OR_WORD; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; bool synPredMatched43 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_3.member(LA(2))) && (_tokenSet_3.member(LA(3))))) { int _m43 = mark(); synPredMatched43 = true; inputState->guessing++; try { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched43 = false; } rewind(_m43); inputState->guessing--; } if ( synPredMatched43 ) { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); } if ( inputState->guessing==0 ) { #line 336 "ifconfig_bsd.g" _ttype = IPV4; #line 708 "IfconfigBSDCfgLexer.cpp" } } else { bool synPredMatched47 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m47 = mark(); synPredMatched47 = true; inputState->guessing++; try { { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); { match(_tokenSet_5); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched47 = false; } rewind(_m47); inputState->guessing--; } if ( synPredMatched47 ) { { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } if ( inputState->guessing==0 ) { #line 348 "ifconfig_bsd.g" _ttype = MAC_ADDRESS; #line 758 "IfconfigBSDCfgLexer.cpp" } } else { bool synPredMatched50 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m50 = mark(); synPredMatched50 = true; inputState->guessing++; try { { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched50 = false; } rewind(_m50); inputState->guessing--; } if ( synPredMatched50 ) { { bool synPredMatched55 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m55 = mark(); synPredMatched55 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt54=0; for (;;) { if ((_tokenSet_2.member(LA(1)))) { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); } else { if ( _cnt54>=1 ) { goto _loop54; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt54++; } _loop54:; } // ( ... )+ match(':' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched55 = false; } rewind(_m55); inputState->guessing--; } if ( synPredMatched55 ) { { { // ( ... )+ int _cnt58=0; for (;;) { if ((_tokenSet_2.member(LA(1)))) { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); } else { if ( _cnt58>=1 ) { goto _loop58; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt58++; } _loop58:; } // ( ... )+ match(':' /* charlit */ ); { if ((_tokenSet_2.member(LA(1)))) { mNUM_HEX_4DIGIT(false); { // ( ... )* for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } else { goto _loop61; } } _loop61:; } // ( ... )* } else { } } } if ( inputState->guessing==0 ) { #line 357 "ifconfig_bsd.g" _ttype = IPV6; #line 855 "IfconfigBSDCfgLexer.cpp" } } else if ((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3)))) { mNUM_HEX_4DIGIT(false); { // ( ... )+ int _cnt63=0; for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } else { if ( _cnt63>=1 ) { goto _loop63; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt63++; } _loop63:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 360 "ifconfig_bsd.g" _ttype = IPV6; #line 878 "IfconfigBSDCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 362 "ifconfig_bsd.g" _ttype = IPV6; #line 889 "IfconfigBSDCfgLexer.cpp" } } else { bool synPredMatched65 = false; if (((LA(1) == 0x3a /* ':' */ ) && (LA(2) == 0x3a /* ':' */ ) && (_tokenSet_2.member(LA(3))))) { int _m65 = mark(); synPredMatched65 = true; inputState->guessing++; try { { match(':' /* charlit */ ); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched65 = false; } rewind(_m65); inputState->guessing--; } if ( synPredMatched65 ) { match(':' /* charlit */ ); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); { // ( ... )* for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } else { goto _loop67; } } _loop67:; } // ( ... )* if ( inputState->guessing==0 ) { #line 365 "ifconfig_bsd.g" _ttype = IPV6; #line 931 "IfconfigBSDCfgLexer.cpp" } } else { bool synPredMatched73 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_3.member(LA(2))) && (_tokenSet_3.member(LA(3))))) { int _m73 = mark(); synPredMatched73 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt70=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt70>=1 ) { goto _loop70; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt70++; } _loop70:; } // ( ... )+ match('.' /* charlit */ ); { // ( ... )+ int _cnt72=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt72>=1 ) { goto _loop72; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt72++; } _loop72:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched73 = false; } rewind(_m73); inputState->guessing--; } if ( synPredMatched73 ) { { { // ( ... )+ int _cnt76=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt76>=1 ) { goto _loop76; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt76++; } _loop76:; } // ( ... )+ match('.' /* charlit */ ); { // ( ... )+ int _cnt78=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt78>=1 ) { goto _loop78; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt78++; } _loop78:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 372 "ifconfig_bsd.g" _ttype = NUMBER; #line 1014 "IfconfigBSDCfgLexer.cpp" } } else if ((LA(1) == 0x3a /* ':' */ ) && (LA(2) == 0x3a /* ':' */ ) && (true)) { match(':' /* charlit */ ); match(':' /* charlit */ ); if ( inputState->guessing==0 ) { #line 367 "ifconfig_bsd.g" _ttype = IPV6; #line 1023 "IfconfigBSDCfgLexer.cpp" } } else if ((LA(1) == 0x30 /* '0' */ ) && (LA(2) == 0x58 /* 'X' */ || LA(2) == 0x78 /* 'x' */ )) { match('0' /* charlit */ ); { switch ( LA(1)) { case 0x78 /* 'x' */ : { match('x' /* charlit */ ); break; } case 0x58 /* 'X' */ : { match('X' /* charlit */ ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } mHEX_DIGIT(false); { // ( ... )* for (;;) { if ((_tokenSet_2.member(LA(1)))) { mHEX_DIGIT(false); } else { goto _loop83; } } _loop83:; } // ( ... )* if ( inputState->guessing==0 ) { #line 376 "ifconfig_bsd.g" _ttype = HEX_CONST; #line 1062 "IfconfigBSDCfgLexer.cpp" } } else if ((LA(1) == 0x3a /* ':' */ ) && (true)) { match(':' /* charlit */ ); if ( inputState->guessing==0 ) { #line 369 "ifconfig_bsd.g" _ttype = COLON; #line 1070 "IfconfigBSDCfgLexer.cpp" } } else if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true)) { { // ( ... )+ int _cnt80=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt80>=1 ) { goto _loop80; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt80++; } _loop80:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 374 "ifconfig_bsd.g" _ttype = INT_CONST; #line 1091 "IfconfigBSDCfgLexer.cpp" } } else if ((_tokenSet_6.member(LA(1))) && (true) && (true)) { { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x22 /* '\"' */ : { match('\"' /* charlit */ ); break; } case 0x24 /* '$' */ : { match('$' /* charlit */ ); break; } case 0x25 /* '%' */ : { match('%' /* charlit */ ); break; } case 0x26 /* '&' */ : { match('&' /* charlit */ ); break; } case 0x2d /* '-' */ : { match('-' /* charlit */ ); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x3b /* ';' */ : { match(';' /* charlit */ ); break; } case 0x3f /* '?' */ : { match('?' /* charlit */ ); break; } case 0x40 /* '@' */ : { match('@' /* charlit */ ); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x5c /* '\\' */ : { match('\\' /* charlit */ ); break; } case 0x5e /* '^' */ : { match('^' /* charlit */ ); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } case 0x60 /* '`' */ : { match('`' /* charlit */ ); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } default: { goto _loop86; } } } _loop86:; } // ( ... )* if ( inputState->guessing==0 ) { #line 384 "ifconfig_bsd.g" _ttype = WORD; #line 1311 "IfconfigBSDCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } }}}} _ttype = testLiteralsTable(_ttype); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mPERCENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PERCENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('%' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mAMPERSAND(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = AMPERSAND; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('&' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mSTAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('*' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mMINUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MINUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('-' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mDOT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('.' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mSLASH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SLASH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('/' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mEQUAL(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EQUAL; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('=' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mQUESTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = QUESTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('?' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mOPENING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('(' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mCLOSING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(')' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mOPENING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('[' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mCLOSING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(']' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mOPENING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('{' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mCLOSING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('}' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mLESS_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LESS_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('<' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigBSDCfgLexer::mGREATER_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = GREATER_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('>' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } const unsigned long IfconfigBSDCfgLexer::_tokenSet_0_data_[] = { 4294958072UL, 1UL, 0UL, 2147483648UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_0(_tokenSet_0_data_,16); const unsigned long IfconfigBSDCfgLexer::_tokenSet_1_data_[] = { 4294958072UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! \" # $ % // & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G // H const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_1(_tokenSet_1_data_,16); const unsigned long IfconfigBSDCfgLexer::_tokenSet_2_data_[] = { 0UL, 67043328UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 A B C D E F const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long IfconfigBSDCfgLexer::_tokenSet_3_data_[] = { 0UL, 67059712UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // . 0 1 2 3 4 5 6 7 8 9 const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_3(_tokenSet_3_data_,10); const unsigned long IfconfigBSDCfgLexer::_tokenSet_4_data_[] = { 0UL, 134152192UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 : A B C D E F const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_4(_tokenSet_4_data_,10); const unsigned long IfconfigBSDCfgLexer::_tokenSet_5_data_[] = { 4294967288UL, 4227858431UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 // 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! \" # // $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 ; < = > ? @ A B C D E F // G H const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_5(_tokenSet_5_data_,16); const unsigned long IfconfigBSDCfgLexer::_tokenSet_6_data_[] = { 0UL, 0UL, 134217726UL, 134217726UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // A B C D E F G H const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgLexer::_tokenSet_6(_tokenSet_6_data_,10); fwbuilder-5.1.0.3599/src/parsers/IfconfigLinuxCfgLexer.cpp0000644000175000017500000013067611733011756024151 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20100319): "ifconfig_linux.g" -> "IfconfigLinuxCfgLexer.cpp"$ */ #line 43 "ifconfig_linux.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IfconfigLinuxCfgLexer.cpp" #include "IfconfigLinuxCfgLexer.hpp" #include #include #include #include #include #include #include #line 49 "ifconfig_linux.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 25 "IfconfigLinuxCfgLexer.cpp" #line 1 "ifconfig_linux.g" #line 27 "IfconfigLinuxCfgLexer.cpp" IfconfigLinuxCfgLexer::IfconfigLinuxCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in) : ANTLR_USE_NAMESPACE(antlr)CharScanner(new ANTLR_USE_NAMESPACE(antlr)CharBuffer(in),true) { initLiterals(); } IfconfigLinuxCfgLexer::IfconfigLinuxCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib) : ANTLR_USE_NAMESPACE(antlr)CharScanner(ib,true) { initLiterals(); } IfconfigLinuxCfgLexer::IfconfigLinuxCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)CharScanner(state,true) { initLiterals(); } void IfconfigLinuxCfgLexer::initLiterals() { literals["priority"] = 7; literals["broadcast"] = 43; literals["Scope"] = 38; literals["scopeid"] = 46; literals["Host"] = 39; literals["UP"] = 11; literals["groups"] = 41; literals["HWaddr"] = 27; literals["encap"] = 26; literals["NOARP"] = 15; literals["Mask"] = 33; literals["netmask"] = 44; literals["RUNNING"] = 16; literals["inet"] = 29; literals["media"] = 8; literals["BROADCAST"] = 12; literals["P-t-P"] = 34; literals["prefixlen"] = 45; literals["Loopback"] = 17; literals["Interrupt"] = 18; literals["Bcast"] = 32; literals["mtu"] = 47; literals["inet6"] = 35; literals["status"] = 9; literals["LOOPBACK"] = 14; literals["Link"] = 25; literals["TX"] = 22; literals["addr"] = 30; literals["RX"] = 21; literals["Global"] = 40; literals["POINTOPOINT"] = 13; literals["flags"] = 42; literals["lladdr"] = 48; literals["collisions"] = 19; } ANTLR_USE_NAMESPACE(antlr)RefToken IfconfigLinuxCfgLexer::nextToken() { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; for (;;) { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; int _ttype = ANTLR_USE_NAMESPACE(antlr)Token::INVALID_TYPE; resetText(); try { // for lexical and char stream error handling switch ( LA(1)) { case 0x23 /* '#' */ : { mLINE_COMMENT(true); theRetToken=_returnToken; break; } case 0xa /* '\n' */ : case 0xd /* '\r' */ : { mNEWLINE(true); theRetToken=_returnToken; break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : case 0x3a /* ':' */ : case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { mNUMBER_ADDRESS_OR_WORD(true); theRetToken=_returnToken; break; } case 0x25 /* '%' */ : { mPERCENT(true); theRetToken=_returnToken; break; } case 0x26 /* '&' */ : { mAMPERSAND(true); theRetToken=_returnToken; break; } case 0x2a /* '*' */ : { mSTAR(true); theRetToken=_returnToken; break; } case 0x2d /* '-' */ : { mMINUS(true); theRetToken=_returnToken; break; } case 0x2e /* '.' */ : { mDOT(true); theRetToken=_returnToken; break; } case 0x2f /* '/' */ : { mSLASH(true); theRetToken=_returnToken; break; } case 0x3d /* '=' */ : { mEQUAL(true); theRetToken=_returnToken; break; } case 0x3f /* '?' */ : { mQUESTION(true); theRetToken=_returnToken; break; } case 0x28 /* '(' */ : { mOPENING_PAREN(true); theRetToken=_returnToken; break; } case 0x29 /* ')' */ : { mCLOSING_PAREN(true); theRetToken=_returnToken; break; } case 0x5b /* '[' */ : { mOPENING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5d /* ']' */ : { mCLOSING_SQUARE(true); theRetToken=_returnToken; break; } case 0x7b /* '{' */ : { mOPENING_BRACE(true); theRetToken=_returnToken; break; } case 0x7d /* '}' */ : { mCLOSING_BRACE(true); theRetToken=_returnToken; break; } case 0x3c /* '<' */ : { mLESS_THAN(true); theRetToken=_returnToken; break; } case 0x3e /* '>' */ : { mGREATER_THAN(true); theRetToken=_returnToken; break; } default: if ((_tokenSet_0.member(LA(1)))) { mWhitespace(true); theRetToken=_returnToken; } else { if (LA(1)==EOF_CHAR) { uponEOF(); _returnToken = makeToken(ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE); } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } if ( !_returnToken ) goto tryAgain; // found SKIP token _ttype = _returnToken->getType(); _ttype = testLiteralsTable(_ttype); _returnToken->setType(_ttype); return _returnToken; } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& e) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamRecognitionException(e); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamIOException& csie) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamIOException(csie.io); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamException& cse) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamException(cse.getMessage()); } tryAgain:; } } void IfconfigLinuxCfgLexer::mLINE_COMMENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LINE_COMMENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("#"); { // ( ... )* for (;;) { if ((_tokenSet_1.member(LA(1)))) { { match(_tokenSet_1); } } else { goto _loop32; } } _loop32:; } // ( ... )* mNEWLINE(false); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mNEWLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEWLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { if ((LA(1) == 0xd /* '\r' */ ) && (LA(2) == 0xa /* '\n' */ )) { match("\r\n"); } else if ((LA(1) == 0xd /* '\r' */ ) && (true)) { match('\r' /* charlit */ ); } else if ((LA(1) == 0xa /* '\n' */ )) { match('\n' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 448 "ifconfig_linux.g" newline(); #line 357 "IfconfigLinuxCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mWhitespace(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = Whitespace; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x3 /* '\3' */ : case 0x4 /* '\4' */ : case 0x5 /* '\5' */ : case 0x6 /* '\6' */ : case 0x7 /* '\7' */ : case 0x8 /* '\10' */ : { matchRange('\3','\10'); break; } case 0x9 /* '\t' */ : { match('\t' /* charlit */ ); break; } case 0xb /* '\13' */ : { match('\13' /* charlit */ ); break; } case 0xc /* '\14' */ : { match('\14' /* charlit */ ); break; } case 0xe /* '\16' */ : case 0xf /* '\17' */ : case 0x10 /* '\20' */ : case 0x11 /* '\21' */ : case 0x12 /* '\22' */ : case 0x13 /* '\23' */ : case 0x14 /* '\24' */ : case 0x15 /* '\25' */ : case 0x16 /* '\26' */ : case 0x17 /* '\27' */ : case 0x18 /* '\30' */ : case 0x19 /* '\31' */ : case 0x1a /* '\32' */ : case 0x1b /* '\33' */ : case 0x1c /* '\34' */ : case 0x1d /* '\35' */ : case 0x1e /* '\36' */ : case 0x1f /* '\37' */ : { matchRange('\16','\37'); break; } case 0x20 /* ' ' */ : { match(' ' /* charlit */ ); break; } default: if (((LA(1) >= 0x7f && LA(1) <= 0xff))) { matchRange('\177',static_cast('\377')); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( inputState->guessing==0 ) { #line 354 "ifconfig_linux.g" _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; #line 438 "IfconfigLinuxCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mINT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mHEX_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mNUMBER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mNEG_INT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEG_INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mCOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mHEX_DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : { matchRange('A','F'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('0','9'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mNUM_3DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_3DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { matchRange('0','9'); } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mNUM_HEX_4DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_HEX_4DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; mHEX_DIGIT(false); { if ((_tokenSet_2.member(LA(1)))) { { mHEX_DIGIT(false); } { if ((_tokenSet_2.member(LA(1)))) { { mHEX_DIGIT(false); } { if ((_tokenSet_2.member(LA(1)))) { mHEX_DIGIT(false); } else { } } } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mMAC_ADDRESS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MAC_ADDRESS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mNUMBER_ADDRESS_OR_WORD(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_ADDRESS_OR_WORD; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; bool synPredMatched57 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_3.member(LA(2))) && (_tokenSet_3.member(LA(3))))) { int _m57 = mark(); synPredMatched57 = true; inputState->guessing++; try { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched57 = false; } rewind(_m57); inputState->guessing--; } if ( synPredMatched57 ) { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); } if ( inputState->guessing==0 ) { #line 396 "ifconfig_linux.g" _ttype = IPV4; #line 708 "IfconfigLinuxCfgLexer.cpp" } } else { bool synPredMatched61 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m61 = mark(); synPredMatched61 = true; inputState->guessing++; try { { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); { match(_tokenSet_5); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched61 = false; } rewind(_m61); inputState->guessing--; } if ( synPredMatched61 ) { { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } if ( inputState->guessing==0 ) { #line 408 "ifconfig_linux.g" _ttype = MAC_ADDRESS; #line 758 "IfconfigLinuxCfgLexer.cpp" } } else { bool synPredMatched64 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m64 = mark(); synPredMatched64 = true; inputState->guessing++; try { { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched64 = false; } rewind(_m64); inputState->guessing--; } if ( synPredMatched64 ) { { bool synPredMatched69 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m69 = mark(); synPredMatched69 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt68=0; for (;;) { if ((_tokenSet_2.member(LA(1)))) { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); } else { if ( _cnt68>=1 ) { goto _loop68; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt68++; } _loop68:; } // ( ... )+ match(':' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched69 = false; } rewind(_m69); inputState->guessing--; } if ( synPredMatched69 ) { { { // ( ... )+ int _cnt72=0; for (;;) { if ((_tokenSet_2.member(LA(1)))) { mNUM_HEX_4DIGIT(false); match(':' /* charlit */ ); } else { if ( _cnt72>=1 ) { goto _loop72; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt72++; } _loop72:; } // ( ... )+ match(':' /* charlit */ ); { if ((_tokenSet_2.member(LA(1)))) { mNUM_HEX_4DIGIT(false); { // ( ... )* for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } else { goto _loop75; } } _loop75:; } // ( ... )* } else { } } } if ( inputState->guessing==0 ) { #line 417 "ifconfig_linux.g" _ttype = IPV6; #line 855 "IfconfigLinuxCfgLexer.cpp" } } else if ((_tokenSet_2.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3)))) { mNUM_HEX_4DIGIT(false); { // ( ... )+ int _cnt77=0; for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } else { if ( _cnt77>=1 ) { goto _loop77; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt77++; } _loop77:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 420 "ifconfig_linux.g" _ttype = IPV6; #line 878 "IfconfigLinuxCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 422 "ifconfig_linux.g" _ttype = IPV6; #line 889 "IfconfigLinuxCfgLexer.cpp" } } else { bool synPredMatched79 = false; if (((LA(1) == 0x3a /* ':' */ ) && (LA(2) == 0x3a /* ':' */ ) && (_tokenSet_2.member(LA(3))))) { int _m79 = mark(); synPredMatched79 = true; inputState->guessing++; try { { match(':' /* charlit */ ); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched79 = false; } rewind(_m79); inputState->guessing--; } if ( synPredMatched79 ) { match(':' /* charlit */ ); match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); { // ( ... )* for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); mNUM_HEX_4DIGIT(false); } else { goto _loop81; } } _loop81:; } // ( ... )* if ( inputState->guessing==0 ) { #line 425 "ifconfig_linux.g" _ttype = IPV6; #line 931 "IfconfigLinuxCfgLexer.cpp" } } else { bool synPredMatched87 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_3.member(LA(2))) && (_tokenSet_3.member(LA(3))))) { int _m87 = mark(); synPredMatched87 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt84=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt84>=1 ) { goto _loop84; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt84++; } _loop84:; } // ( ... )+ match('.' /* charlit */ ); { // ( ... )+ int _cnt86=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt86>=1 ) { goto _loop86; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt86++; } _loop86:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched87 = false; } rewind(_m87); inputState->guessing--; } if ( synPredMatched87 ) { { { // ( ... )+ int _cnt90=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt90>=1 ) { goto _loop90; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt90++; } _loop90:; } // ( ... )+ match('.' /* charlit */ ); { // ( ... )+ int _cnt92=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt92>=1 ) { goto _loop92; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt92++; } _loop92:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 432 "ifconfig_linux.g" _ttype = NUMBER; #line 1014 "IfconfigLinuxCfgLexer.cpp" } } else if ((LA(1) == 0x3a /* ':' */ ) && (LA(2) == 0x3a /* ':' */ ) && (true)) { match(':' /* charlit */ ); match(':' /* charlit */ ); if ( inputState->guessing==0 ) { #line 427 "ifconfig_linux.g" _ttype = IPV6; #line 1023 "IfconfigLinuxCfgLexer.cpp" } } else if ((LA(1) == 0x30 /* '0' */ ) && (LA(2) == 0x58 /* 'X' */ || LA(2) == 0x78 /* 'x' */ )) { match('0' /* charlit */ ); { switch ( LA(1)) { case 0x78 /* 'x' */ : { match('x' /* charlit */ ); break; } case 0x58 /* 'X' */ : { match('X' /* charlit */ ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } mHEX_DIGIT(false); { // ( ... )* for (;;) { if ((_tokenSet_2.member(LA(1)))) { mHEX_DIGIT(false); } else { goto _loop97; } } _loop97:; } // ( ... )* if ( inputState->guessing==0 ) { #line 436 "ifconfig_linux.g" _ttype = HEX_CONST; #line 1062 "IfconfigLinuxCfgLexer.cpp" } } else if ((LA(1) == 0x3a /* ':' */ ) && (true)) { match(':' /* charlit */ ); if ( inputState->guessing==0 ) { #line 429 "ifconfig_linux.g" _ttype = COLON; #line 1070 "IfconfigLinuxCfgLexer.cpp" } } else if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true)) { { // ( ... )+ int _cnt94=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt94>=1 ) { goto _loop94; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt94++; } _loop94:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 434 "ifconfig_linux.g" _ttype = INT_CONST; #line 1091 "IfconfigLinuxCfgLexer.cpp" } } else if ((_tokenSet_6.member(LA(1))) && (true) && (true)) { { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x22 /* '\"' */ : { match('\"' /* charlit */ ); break; } case 0x24 /* '$' */ : { match('$' /* charlit */ ); break; } case 0x25 /* '%' */ : { match('%' /* charlit */ ); break; } case 0x26 /* '&' */ : { match('&' /* charlit */ ); break; } case 0x2d /* '-' */ : { match('-' /* charlit */ ); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x3b /* ';' */ : { match(';' /* charlit */ ); break; } case 0x3f /* '?' */ : { match('?' /* charlit */ ); break; } case 0x40 /* '@' */ : { match('@' /* charlit */ ); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x5c /* '\\' */ : { match('\\' /* charlit */ ); break; } case 0x5e /* '^' */ : { match('^' /* charlit */ ); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } case 0x60 /* '`' */ : { match('`' /* charlit */ ); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } default: { goto _loop100; } } } _loop100:; } // ( ... )* if ( inputState->guessing==0 ) { #line 444 "ifconfig_linux.g" _ttype = WORD; #line 1311 "IfconfigLinuxCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } }}}} _ttype = testLiteralsTable(_ttype); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mPERCENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PERCENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('%' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mAMPERSAND(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = AMPERSAND; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('&' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mSTAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('*' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mMINUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MINUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('-' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mDOT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('.' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mSLASH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SLASH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('/' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mEQUAL(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EQUAL; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('=' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mQUESTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = QUESTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('?' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mOPENING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('(' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mCLOSING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(')' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mOPENING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('[' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mCLOSING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(']' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mOPENING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('{' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mCLOSING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('}' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mLESS_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LESS_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('<' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IfconfigLinuxCfgLexer::mGREATER_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = GREATER_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('>' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } const unsigned long IfconfigLinuxCfgLexer::_tokenSet_0_data_[] = { 4294958072UL, 1UL, 0UL, 2147483648UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_0(_tokenSet_0_data_,16); const unsigned long IfconfigLinuxCfgLexer::_tokenSet_1_data_[] = { 4294958072UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! \" # $ % // & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_1(_tokenSet_1_data_,16); const unsigned long IfconfigLinuxCfgLexer::_tokenSet_2_data_[] = { 0UL, 67043328UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 A B C D E F const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long IfconfigLinuxCfgLexer::_tokenSet_3_data_[] = { 0UL, 67059712UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // . 0 1 2 3 4 5 6 7 8 9 const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_3(_tokenSet_3_data_,10); const unsigned long IfconfigLinuxCfgLexer::_tokenSet_4_data_[] = { 0UL, 134152192UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 : A B C D E F const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_4(_tokenSet_4_data_,10); const unsigned long IfconfigLinuxCfgLexer::_tokenSet_5_data_[] = { 4294967288UL, 4227858431UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 // 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! \" # // $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 ; < = > ? @ A B C D E F // G const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_5(_tokenSet_5_data_,16); const unsigned long IfconfigLinuxCfgLexer::_tokenSet_6_data_[] = { 0UL, 0UL, 134217726UL, 134217726UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // A B C D E F G const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgLexer::_tokenSet_6(_tokenSet_6_data_,10); fwbuilder-5.1.0.3599/src/parsers/PFCfgParserTokenTypes.hpp0000644000175000017500000001267511733011756024120 0ustar sylvestresylvestre#ifndef INC_PFCfgParserTokenTypes_hpp_ #define INC_PFCfgParserTokenTypes_hpp_ /* $ANTLR 2.7.7 (20100319): "pf.g" -> "PFCfgParserTokenTypes.hpp"$ */ #ifndef CUSTOM_API # define CUSTOM_API #endif #ifdef __cplusplus struct CUSTOM_API PFCfgParserTokenTypes { #endif enum { EOF_ = 1, NEWLINE = 4, COMMENT_START = 5, INCLUDE_COMMAND = 6, WORD = 7, EQUAL = 8, ANTISPOOF = 9, ALTQ = 10, QUEUE = 11, SET = 12, TIMEOUT = 13, // "ruleset-optimization" = 14 LITERAL_optimization = 15, LITERAL_aggressive = 16, LITERAL_conservative = 17, // "high-latency" = 18 LITERAL_normal = 19, LITERAL_satellite = 20, LITERAL_limit = 21, LITERAL_loginterface = 22, // "block-policy" = 23 DROP = 24, RETURN = 25, // "state-policy" = 26 // "if-bound" = 27 LITERAL_floating = 28, // "state-defaults" = 29 // "require-order" = 30 LITERAL_fingerprints = 31, LITERAL_skip = 32, ON = 33, OPENING_BRACE = 34, COMMA = 35, CLOSING_BRACE = 36, LITERAL_debug = 37, LITERAL_reassemble = 38, LITERAL_hostid = 39, // "tcp.first" = 40 // "tcp.opening" = 41 // "tcp.established" = 42 // "tcp.closing" = 43 // "tcp.finwait" = 44 // "tcp.closed" = 45 // "udp.first" = 46 // "udp.single" = 47 // "udp.multiple" = 48 // "icmp.first" = 49 // "icmp.error" = 50 // "other.first" = 51 // "other.single" = 52 // "other.multiple" = 53 LITERAL_frag = 54, LITERAL_interval = 55, // "src.track" = 56 // "adaptive.start" = 57 // "adaptive.end" = 58 INT_CONST = 59, LITERAL_frags = 60, LITERAL_states = 61, // "src-nodes" = 62 LITERAL_tables = 63, // "tables-entries" = 64 SCRUB = 65, MATCH = 66, TABLE = 67, LESS_THAN = 68, GREATER_THAN = 69, PERSIST = 70, CONST_WORD = 71, COUNTERS = 72, FILE = 73, STRING = 74, EXLAMATION = 75, COLON = 76, NETWORK = 77, BROADCAST = 78, PEER = 79, SELF = 80, IPV4 = 81, NUMBER = 82, SLASH = 83, NO = 84, NAT = 85, PASS = 86, MINUS = 87, STATIC_PORT = 88, RDR = 89, OPENING_PAREN = 90, CLOSING_PAREN = 91, PORT = 92, IPV6 = 93, STAR = 94, BITMASK = 95, RANDOM = 96, SOURCE_HASH = 97, HEX_KEY = 98, STRING_KEY = 99, ROUND_ROBIN = 100, STICKY_ADDRESS = 101, BINAT = 102, BLOCK = 103, RETURN_RST = 104, TTL = 105, RETURN_ICMP = 106, RETURN_ICMP6 = 107, IN_WORD = 108, OUT_WORD = 109, LOG = 110, QUICK = 111, ALL = 112, USER = 113, TO = 114, INET = 115, INET6 = 116, PROTO = 117, IP = 118, ICMP = 119, IGMP = 120, TCP = 121, UDP = 122, RDP = 123, RSVP = 124, GRE = 125, ESP_WORD = 126, AH = 127, EIGRP = 128, OSPF = 129, IPIP = 130, VRRP = 131, L2TP = 132, ISIS = 133, FROM = 134, URPF_FAILED = 135, ANY = 136, NO_ROUTE = 137, MACRO = 138, ROUTE_TO = 139, REPLY_TO = 140, DUP_TO = 141, GROUP = 142, LITERAL_fragment = 143, LITERAL_crop = 144, // "drop-ovl" = 145 // "no-df" = 146 // "min-ttl" = 147 // "max-mss" = 148 // "random-id" = 149 FLAGS = 150, ICMP_TYPE = 151, ICMP_CODE = 152, LITERAL_echorep = 153, LITERAL_unreach = 154, LITERAL_squench = 155, LITERAL_redir = 156, LITERAL_althost = 157, LITERAL_echoreq = 158, LITERAL_routeradv = 159, LITERAL_routersol = 160, LITERAL_timex = 161, LITERAL_paramprob = 162, LITERAL_timereq = 163, LITERAL_timerep = 164, LITERAL_inforeq = 165, LITERAL_inforep = 166, LITERAL_maskreq = 167, LITERAL_maskrep = 168, LITERAL_trace = 169, LITERAL_dataconv = 170, LITERAL_mobredir = 171, // "ipv6-where" = 172 // "ipv6-here" = 173 LITERAL_mobregreq = 174, LITERAL_mobregrep = 175, LITERAL_photuris = 176, // "net-unr" = 177 // "host-unr" = 178 // "proto-unr" = 179 // "port-unr" = 180 LITERAL_needfrag = 181, LITERAL_srcfail = 182, // "net-unk" = 183 // "host-unk" = 184 LITERAL_isolate = 185, // "net-prohib" = 186 // "host-prohib" = 187 // "net-tos" = 188 // "host-tos" = 189 // "filter-prohib" = 190 // "host-preced" = 191 // "cutoff-preced" = 192 // "redir-net" = 193 // "redir-host" = 194 // "redir-tos-net" = 195 // "redir-tos-host" = 196 // "normal-adv" = 197 // "common-adv" = 198 LITERAL_transit = 199, LITERAL_reassemb = 200, LITERAL_badhead = 201, LITERAL_optmiss = 202, LITERAL_badlen = 203, // "unknown-ind" = 204 // "auth-fail" = 205 // "decrypt-fail" = 206 ICMP6_TYPE = 207, TAGGED = 208, TAG = 209, KEEP = 210, MODULATE = 211, SYNPROXY = 212, STATE = 213, LABEL = 214, EXIT = 215, QUIT = 216, INTRFACE = 217, ICMP6 = 218, IGRP = 219, IPSEC = 220, NOS = 221, PCP = 222, PIM = 223, PPTP = 224, RIP = 225, SNP = 226, HOST = 227, RANGE = 228, LOG_LEVEL_ALERTS = 229, LOG_LEVEL_CRITICAL = 230, LOG_LEVEL_DEBUGGING = 231, LOG_LEVEL_EMERGENCIES = 232, LOG_LEVEL_ERRORS = 233, LOG_LEVEL_INFORMATIONAL = 234, LOG_LEVEL_NOTIFICATIONS = 235, LOG_LEVEL_WARNINGS = 236, LOG_LEVEL_DISABLE = 237, LOG_LEVEL_INACTIVE = 238, Whitespace = 239, HEX_CONST = 240, NEG_INT_CONST = 241, HEX_DIGIT = 242, DIGIT = 243, NUM_3DIGIT = 244, NUM_HEX_4DIGIT = 245, NUMBER_ADDRESS_OR_WORD = 246, PIPE_CHAR = 247, PERCENT = 248, AMPERSAND = 249, APOSTROPHE = 250, PLUS = 251, DOT = 252, SEMICOLON = 253, QUESTION = 254, COMMERCIAL_AT = 255, OPENING_SQUARE = 256, CLOSING_SQUARE = 257, CARET = 258, UNDERLINE = 259, TILDE = 260, DOUBLE_QUOTE = 261, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus }; #endif #endif /*INC_PFCfgParserTokenTypes_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PFCfgLexer.hpp0000644000175000017500000000751111733011756021706 0ustar sylvestresylvestre#ifndef INC_PFCfgLexer_hpp_ #define INC_PFCfgLexer_hpp_ #line 25 "pf.g" // gets inserted before antlr generated includes in the header // file #include "PFImporter.h" #line 11 "PFCfgLexer.hpp" #include /* $ANTLR 2.7.7 (20100319): "pf.g" -> "PFCfgLexer.hpp"$ */ #include #include #include #include "PFCfgParserTokenTypes.hpp" #include #line 32 "pf.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class PFImporter; #line 29 "PFCfgLexer.hpp" #line 57 "pf.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 35 "PFCfgLexer.hpp" class CUSTOM_API PFCfgLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public PFCfgParserTokenTypes { #line 1 "pf.g" #line 39 "PFCfgLexer.hpp" private: void initLiterals(); public: bool getCaseSensitiveLiterals() const { return true; } public: PFCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in); PFCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); PFCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); public: void mWhitespace(bool _createToken); public: void mCOMMENT_START(bool _createToken); public: void mNEWLINE(bool _createToken); protected: void mINT_CONST(bool _createToken); protected: void mHEX_CONST(bool _createToken); protected: void mNUMBER(bool _createToken); protected: void mNEG_INT_CONST(bool _createToken); protected: void mCOLON(bool _createToken); protected: void mHEX_DIGIT(bool _createToken); protected: void mDIGIT(bool _createToken); protected: void mNUM_3DIGIT(bool _createToken); protected: void mNUM_HEX_4DIGIT(bool _createToken); public: void mNUMBER_ADDRESS_OR_WORD(bool _createToken); public: void mSTRING(bool _createToken); public: void mPIPE_CHAR(bool _createToken); public: void mPERCENT(bool _createToken); public: void mAMPERSAND(bool _createToken); public: void mAPOSTROPHE(bool _createToken); public: void mSTAR(bool _createToken); public: void mPLUS(bool _createToken); public: void mCOMMA(bool _createToken); public: void mMINUS(bool _createToken); public: void mDOT(bool _createToken); public: void mSLASH(bool _createToken); public: void mSEMICOLON(bool _createToken); public: void mEQUAL(bool _createToken); public: void mQUESTION(bool _createToken); public: void mCOMMERCIAL_AT(bool _createToken); public: void mOPENING_PAREN(bool _createToken); public: void mCLOSING_PAREN(bool _createToken); public: void mOPENING_SQUARE(bool _createToken); public: void mCLOSING_SQUARE(bool _createToken); public: void mOPENING_BRACE(bool _createToken); public: void mCLOSING_BRACE(bool _createToken); public: void mCARET(bool _createToken); public: void mUNDERLINE(bool _createToken); public: void mTILDE(bool _createToken); public: void mEXLAMATION(bool _createToken); public: void mLESS_THAN(bool _createToken); public: void mGREATER_THAN(bool _createToken); public: void mDOUBLE_QUOTE(bool _createToken); private: static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; }; #endif /*INC_PFCfgLexer_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IfconfigBSDCfgParserTokenTypes.hpp0000644000175000017500000000310711733011756025656 0ustar sylvestresylvestre#ifndef INC_IfconfigBSDCfgParserTokenTypes_hpp_ #define INC_IfconfigBSDCfgParserTokenTypes_hpp_ /* $ANTLR 2.7.7 (20100319): "ifconfig_bsd.g" -> "IfconfigBSDCfgParserTokenTypes.hpp"$ */ #ifndef CUSTOM_API # define CUSTOM_API #endif #ifdef __cplusplus struct CUSTOM_API IfconfigBSDCfgParserTokenTypes { #endif enum { EOF_ = 1, NEWLINE = 4, DOUBLE_NEWLINE = 5, LINE_COMMENT = 6, PRIORITY = 7, MEDIA = 8, STATUS = 9, WORD = 10, COLON = 11, FLAGS = 12, EQUAL = 13, INT_CONST = 14, LLADDR = 15, MAC_ADDRESS = 16, INET = 17, IPV4 = 18, NETMASK = 19, HEX_CONST = 20, BROADCAST = 21, INET6 = 22, IPV6 = 23, PERCENT = 24, PREFIXLEN = 25, SCOPEID = 26, GROUPS = 27, LINK = 28, GLOBAL = 29, HOST = 30, ADDR = 31, BCAST = 32, P_T_P = 33, MASK = 34, SCOPE = 35, MTU = 36, ENCAP = 37, LOOPBACK = 38, UP = 39, UPPER_BROADCAST = 40, UPPER_POINTOPOINT = 41, UPPER_LOOPBACK = 42, UPPER_NOARP = 43, UPPER_RUNNING = 44, RX = 45, TX = 46, COLLISIONS = 47, INTERRUPT = 48, HWADDR = 49, LLADR = 50, Whitespace = 51, NUMBER = 52, NEG_INT_CONST = 53, HEX_DIGIT = 54, DIGIT = 55, NUM_3DIGIT = 56, NUM_HEX_4DIGIT = 57, NUMBER_ADDRESS_OR_WORD = 58, AMPERSAND = 59, STAR = 60, MINUS = 61, DOT = 62, SLASH = 63, QUESTION = 64, OPENING_PAREN = 65, CLOSING_PAREN = 66, OPENING_SQUARE = 67, CLOSING_SQUARE = 68, OPENING_BRACE = 69, CLOSING_BRACE = 70, LESS_THAN = 71, GREATER_THAN = 72, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus }; #endif #endif /*INC_IfconfigBSDCfgParserTokenTypes_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PIXCfgLexer.cpp0000644000175000017500000015272611733011756022045 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20090306): "pix.g" -> "PIXCfgLexer.cpp"$ */ #line 42 "pix.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "PIXCfgLexer.cpp" #include "PIXCfgLexer.hpp" #include #include #include #include #include #include #include #line 48 "pix.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 25 "PIXCfgLexer.cpp" #line 1 "pix.g" #line 27 "PIXCfgLexer.cpp" PIXCfgLexer::PIXCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in) : ANTLR_USE_NAMESPACE(antlr)CharScanner(new ANTLR_USE_NAMESPACE(antlr)CharBuffer(in),true) { initLiterals(); } PIXCfgLexer::PIXCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib) : ANTLR_USE_NAMESPACE(antlr)CharScanner(ib,true) { initLiterals(); } PIXCfgLexer::PIXCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)CharScanner(state,true) { initLiterals(); } void PIXCfgLexer::initLiterals() { literals["parameter-problem"] = 91; literals["full"] = 125; literals["FWSM"] = 67; literals["port-object"] = 54; literals["notifications"] = 111; literals["duplex"] = 131; literals["dns"] = 56; literals["no"] = 63; literals["static"] = 163; literals["esp"] = 18; literals["time-range"] = 117; literals["gre"] = 19; literals["timestamp-request"] = 98; literals["echo"] = 81; literals["speed"] = 130; literals["warnings"] = 112; literals["resetoutbound"] = 61; literals["timeout"] = 8; literals["eigrp"] = 17; literals["icmp-type"] = 51; literals["permit"] = 74; literals["remark"] = 153; literals["network"] = 10; literals["igmp"] = 20; literals["range"] = 32; literals["destination"] = 44; literals["setroute"] = 166; literals["vlan"] = 129; literals["debugging"] = 107; literals["controller"] = 118; literals["interface"] = 101; literals["dhcp"] = 145; literals["aui"] = 122; literals["Version"] = 68; literals["auto"] = 123; literals["subnet"] = 33; literals["time-exceeded"] = 96; literals["outside"] = 119; literals["shutdown"] = 143; literals["group-object"] = 46; literals["eq"] = 77; literals["fragments"] = 116; literals["norandomseq"] = 164; literals["unreachable"] = 100; literals["delay"] = 134; literals["ip"] = 6; literals["security-level"] = 142; literals["mobile-redirect"] = 90; literals["ospf"] = 25; literals["name"] = 12; literals["errors"] = 109; literals["mask-request"] = 89; literals["PIX"] = 65; literals["any"] = 102; literals["ASA"] = 66; literals["pptp"] = 27; literals["redirect"] = 92; literals["forward"] = 133; literals["timestamp-reply"] = 97; literals["description"] = 30; literals["alerts"] = 105; literals["netmask"] = 162; literals["lt"] = 79; literals["internal"] = 58; literals["bnc"] = 124; literals["global"] = 160; literals["nos"] = 24; literals["extended"] = 73; literals["certificate"] = 64; literals["service"] = 34; literals["telnet"] = 37; literals["udp"] = 42; literals["hold-time"] = 135; literals["management-only"] = 137; literals["baseT"] = 126; literals["ipinip"] = 22; literals["standby"] = 146; literals["crypto"] = 55; literals["object"] = 29; literals["pim"] = 9; literals["secondary"] = 165; literals["emergencies"] = 108; literals["disable"] = 113; literals["mask-reply"] = 88; literals["tcp"] = 41; literals["tcp-udp"] = 52; literals["source"] = 43; literals["names"] = 11; literals["icmp"] = 38; literals["http"] = 35; literals["call-home"] = 57; literals["log"] = 103; literals["snp"] = 28; literals["mac-address"] = 138; literals["established"] = 82; literals["deny"] = 75; literals["information-request"] = 87; literals["ssh"] = 36; literals["protocol-object"] = 49; literals["gt"] = 78; literals["ah"] = 16; literals["interval"] = 115; literals["resetoutside"] = 62; literals["ddns"] = 132; literals["ipv6"] = 136; literals["rip"] = 141; literals["baseTX"] = 127; literals["access-group"] = 154; literals["critical"] = 106; literals["standard"] = 76; literals["quit"] = 5; literals["community-list"] = 7; literals["network-object"] = 47; literals["hostname"] = 70; literals["server"] = 152; literals["information-reply"] = 86; literals["icmp6"] = 40; literals["authentication-certificate"] = 151; literals["switchport"] = 147; literals["ipsec"] = 23; literals["conversion-error"] = 84; literals["host"] = 31; literals["echo-reply"] = 85; literals["nameif"] = 128; literals["pcp"] = 26; literals["service-object"] = 53; literals["nat"] = 156; literals["access-list"] = 72; literals["informational"] = 110; literals["igrp"] = 21; literals["traceroute"] = 99; literals["address"] = 144; literals["log-input"] = 104; literals["router-advertisement"] = 93; literals["resetinbound"] = 60; literals["router-solicitation"] = 94; literals["access"] = 148; literals["icmp-object"] = 50; literals["source-quench"] = 95; literals["scopy"] = 149; literals["protocol"] = 48; literals["object-group"] = 45; literals["inactive"] = 114; literals["multicast"] = 139; literals["exit"] = 121; literals["version"] = 150; literals["neq"] = 80; literals["alternate-address"] = 83; literals["password-recovery"] = 59; } ANTLR_USE_NAMESPACE(antlr)RefToken PIXCfgLexer::nextToken() { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; for (;;) { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; int _ttype = ANTLR_USE_NAMESPACE(antlr)Token::INVALID_TYPE; resetText(); try { // for lexical and char stream error handling switch ( LA(1)) { case 0xa /* '\n' */ : case 0xd /* '\r' */ : { mNEWLINE(true); theRetToken=_returnToken; break; } case 0x24 /* '$' */ : case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { mNUMBER_ADDRESS_OR_WORD(true); theRetToken=_returnToken; break; } case 0x2e /* '.' */ : { mDOT(true); theRetToken=_returnToken; break; } case 0x22 /* '\"' */ : { mSTRING(true); theRetToken=_returnToken; break; } case 0x7c /* '|' */ : { mPIPE_CHAR(true); theRetToken=_returnToken; break; } case 0x23 /* '#' */ : { mNUMBER_SIGN(true); theRetToken=_returnToken; break; } case 0x25 /* '%' */ : { mPERCENT(true); theRetToken=_returnToken; break; } case 0x26 /* '&' */ : { mAMPERSAND(true); theRetToken=_returnToken; break; } case 0x27 /* '\'' */ : { mAPOSTROPHE(true); theRetToken=_returnToken; break; } case 0x28 /* '(' */ : { mOPENING_PAREN(true); theRetToken=_returnToken; break; } case 0x29 /* ')' */ : { mCLOSING_PAREN(true); theRetToken=_returnToken; break; } case 0x2a /* '*' */ : { mSTAR(true); theRetToken=_returnToken; break; } case 0x2b /* '+' */ : { mPLUS(true); theRetToken=_returnToken; break; } case 0x2c /* ',' */ : { mCOMMA(true); theRetToken=_returnToken; break; } case 0x2d /* '-' */ : { mMINUS(true); theRetToken=_returnToken; break; } case 0x2f /* '/' */ : { mSLASH(true); theRetToken=_returnToken; break; } case 0x3b /* ';' */ : { mSEMICOLON(true); theRetToken=_returnToken; break; } case 0x3c /* '<' */ : { mLESS_THAN(true); theRetToken=_returnToken; break; } case 0x3d /* '=' */ : { mEQUALS(true); theRetToken=_returnToken; break; } case 0x3e /* '>' */ : { mGREATER_THAN(true); theRetToken=_returnToken; break; } case 0x3f /* '?' */ : { mQUESTION(true); theRetToken=_returnToken; break; } case 0x40 /* '@' */ : { mCOMMERCIAL_AT(true); theRetToken=_returnToken; break; } case 0x5b /* '[' */ : { mOPENING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5d /* ']' */ : { mCLOSING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5e /* '^' */ : { mCARET(true); theRetToken=_returnToken; break; } case 0x5f /* '_' */ : { mUNDERLINE(true); theRetToken=_returnToken; break; } case 0x7b /* '{' */ : { mOPENING_BRACE(true); theRetToken=_returnToken; break; } case 0x7d /* '}' */ : { mCLOSING_BRACE(true); theRetToken=_returnToken; break; } case 0x7e /* '~' */ : { mTILDE(true); theRetToken=_returnToken; break; } default: if ((LA(1) == 0x21 /* '!' */ ) && ((LA(2) >= 0x3 /* '\3' */ && LA(2) <= 0xff))) { mLINE_COMMENT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x3a /* ':' */ ) && ((LA(2) >= 0x3 /* '\3' */ && LA(2) <= 0xff))) { mCOLON_COMMENT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x3a /* ':' */ ) && (true)) { mCOLON(true); theRetToken=_returnToken; } else if ((_tokenSet_0.member(LA(1)))) { mWhitespace(true); theRetToken=_returnToken; } else if ((LA(1) == 0x21 /* '!' */ ) && (true)) { mEXLAMATION(true); theRetToken=_returnToken; } else { if (LA(1)==EOF_CHAR) { uponEOF(); _returnToken = makeToken(ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE); } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } if ( !_returnToken ) goto tryAgain; // found SKIP token _ttype = _returnToken->getType(); _ttype = testLiteralsTable(_ttype); _returnToken->setType(_ttype); return _returnToken; } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& e) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamRecognitionException(e); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamIOException& csie) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamIOException(csie.io); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamException& cse) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamException(cse.getMessage()); } tryAgain:; } } void PIXCfgLexer::mLINE_COMMENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LINE_COMMENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("!"); { // ( ... )* for (;;) { if ((_tokenSet_1.member(LA(1)))) { { match(_tokenSet_1); } } else { goto _loop285; } } _loop285:; } // ( ... )* mNEWLINE(false); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mNEWLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEWLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { if ((LA(1) == 0xd /* '\r' */ ) && (LA(2) == 0xa /* '\n' */ )) { match("\r\n"); } else if ((LA(1) == 0xd /* '\r' */ ) && (true)) { match('\r' /* charlit */ ); } else if ((LA(1) == 0xa /* '\n' */ )) { match('\n' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 2548 "pix.g" newline(); #line 548 "PIXCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCOLON_COMMENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON_COMMENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; mCOLON(false); { // ( ... )* for (;;) { if ((_tokenSet_1.member(LA(1)))) { { match(_tokenSet_1); } } else { goto _loop289; } } _loop289:; } // ( ... )* mNEWLINE(false); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(':' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mWhitespace(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = Whitespace; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x3 /* '\3' */ : case 0x4 /* '\4' */ : case 0x5 /* '\5' */ : case 0x6 /* '\6' */ : case 0x7 /* '\7' */ : case 0x8 /* '\10' */ : { matchRange('\3','\10'); break; } case 0x9 /* '\t' */ : { match('\t' /* charlit */ ); break; } case 0xb /* '\13' */ : { match('\13' /* charlit */ ); break; } case 0xc /* '\14' */ : { match('\14' /* charlit */ ); break; } case 0xe /* '\16' */ : case 0xf /* '\17' */ : case 0x10 /* '\20' */ : case 0x11 /* '\21' */ : case 0x12 /* '\22' */ : case 0x13 /* '\23' */ : case 0x14 /* '\24' */ : case 0x15 /* '\25' */ : case 0x16 /* '\26' */ : case 0x17 /* '\27' */ : case 0x18 /* '\30' */ : case 0x19 /* '\31' */ : case 0x1a /* '\32' */ : case 0x1b /* '\33' */ : case 0x1c /* '\34' */ : case 0x1d /* '\35' */ : case 0x1e /* '\36' */ : case 0x1f /* '\37' */ : { matchRange('\16','\37'); break; } case 0x20 /* ' ' */ : { match(' ' /* charlit */ ); break; } default: if (((LA(1) >= 0x7f && LA(1) <= 0xff))) { matchRange('\177',static_cast('\377')); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( inputState->guessing==0 ) { #line 2543 "pix.g" _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; #line 672 "PIXCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mINT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mHEX_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mNUMBER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mNEG_INT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEG_INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('0','9'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mHEXDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEXDIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('a','f'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mNUMBER_ADDRESS_OR_WORD(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_ADDRESS_OR_WORD; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { bool synPredMatched338 = false; if (((_tokenSet_2.member(LA(1))) && (_tokenSet_3.member(LA(2))) && (true))) { int _m338 = mark(); synPredMatched338 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt337=0; for (;;) { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } default: { if ( _cnt337>=1 ) { goto _loop337; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } _cnt337++; } _loop337:; } // ( ... )+ mCOLON(false); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched338 = false; } rewind(_m338); inputState->guessing--; } if ( synPredMatched338 ) { { { { // ( ... )+ int _cnt342=0; for (;;) { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } default: { if ( _cnt342>=1 ) { goto _loop342; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } _cnt342++; } _loop342:; } // ( ... )+ { // ( ... )+ int _cnt346=0; for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { mCOLON(false); { // ( ... )* for (;;) { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } default: { goto _loop345; } } } _loop345:; } // ( ... )* } else { if ( _cnt346>=1 ) { goto _loop346; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt346++; } _loop346:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 2589 "pix.g" _ttype = IPV6; #line 914 "PIXCfgLexer.cpp" } } } else { bool synPredMatched303 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true))) { int _m303 = mark(); synPredMatched303 = true; inputState->guessing++; try { { mDIGIT(false); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched303 = false; } rewind(_m303); inputState->guessing--; } if ( synPredMatched303 ) { { bool synPredMatched312 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m312 = mark(); synPredMatched312 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt307=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt307>=1 ) { goto _loop307; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt307++; } _loop307:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt309=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt309>=1 ) { goto _loop309; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt309++; } _loop309:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt311=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt311>=1 ) { goto _loop311; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt311++; } _loop311:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched312 = false; } rewind(_m312); inputState->guessing--; } if ( synPredMatched312 ) { { { // ( ... )+ int _cnt315=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt315>=1 ) { goto _loop315; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt315++; } _loop315:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt317=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt317>=1 ) { goto _loop317; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt317++; } _loop317:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt319=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt319>=1 ) { goto _loop319; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt319++; } _loop319:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt321=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt321>=1 ) { goto _loop321; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt321++; } _loop321:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 2577 "pix.g" _ttype = IPV4; #line 1061 "PIXCfgLexer.cpp" } } else { bool synPredMatched327 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_4.member(LA(2))) && (_tokenSet_4.member(LA(3))))) { int _m327 = mark(); synPredMatched327 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt324=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt324>=1 ) { goto _loop324; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt324++; } _loop324:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt326=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt326>=1 ) { goto _loop326; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt326++; } _loop326:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched327 = false; } rewind(_m327); inputState->guessing--; } if ( synPredMatched327 ) { { { // ( ... )+ int _cnt330=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt330>=1 ) { goto _loop330; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt330++; } _loop330:; } // ( ... )+ mDOT(false); { // ( ... )+ int _cnt332=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt332>=1 ) { goto _loop332; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt332++; } _loop332:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 2580 "pix.g" _ttype = NUMBER; #line 1144 "PIXCfgLexer.cpp" } } else if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true)) { { // ( ... )+ int _cnt334=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt334>=1 ) { goto _loop334; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt334++; } _loop334:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 2582 "pix.g" _ttype = INT_CONST; #line 1165 "PIXCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } } else if ((_tokenSet_5.member(LA(1))) && (true) && (true)) { { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x24 /* '$' */ : { match('$' /* charlit */ ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x21 /* '!' */ : case 0x22 /* '\"' */ : case 0x23 /* '#' */ : case 0x24 /* '$' */ : case 0x25 /* '%' */ : case 0x26 /* '&' */ : case 0x27 /* '\'' */ : { matchRange('!','\''); break; } case 0x2a /* '*' */ : { match('*' /* charlit */ ); break; } case 0x2b /* '+' */ : { match('+' /* charlit */ ); break; } case 0x2d /* '-' */ : { match('-' /* charlit */ ); break; } case 0x2e /* '.' */ : { match('.' /* charlit */ ); break; } case 0x2f /* '/' */ : { match('/' /* charlit */ ); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x3a /* ':' */ : { match(':' /* charlit */ ); break; } case 0x3b /* ';' */ : { match(';' /* charlit */ ); break; } case 0x3c /* '<' */ : { match('<' /* charlit */ ); break; } case 0x3d /* '=' */ : { match('=' /* charlit */ ); break; } case 0x3e /* '>' */ : { match('>' /* charlit */ ); break; } case 0x3f /* '?' */ : { match('?' /* charlit */ ); break; } case 0x40 /* '@' */ : { match('@' /* charlit */ ); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x5c /* '\\' */ : { match('\\' /* charlit */ ); break; } case 0x5e /* '^' */ : { match('^' /* charlit */ ); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } case 0x60 /* '`' */ : { match('`' /* charlit */ ); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } default: { goto _loop349; } } } _loop349:; } // ( ... )* if ( inputState->guessing==0 ) { #line 2597 "pix.g" _ttype = WORD; #line 1427 "PIXCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mDOT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('.' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mSTRING(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STRING; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\"' /* charlit */ ); { // ( ... )* for (;;) { if ((_tokenSet_6.member(LA(1)))) { matchNot('\"' /* charlit */ ); } else { goto _loop352; } } _loop352:; } // ( ... )* match('\"' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mPIPE_CHAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PIPE_CHAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('|' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mNUMBER_SIGN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_SIGN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('#' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mPERCENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PERCENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('%' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mAMPERSAND(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = AMPERSAND; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('&' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mAPOSTROPHE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = APOSTROPHE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\'' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mOPENING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('(' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCLOSING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(')' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mSTAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('*' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mPLUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PLUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('+' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCOMMA(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMA; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(',' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mMINUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MINUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('-' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mSLASH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SLASH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('/' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mSEMICOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SEMICOLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(';' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mLESS_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LESS_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('<' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mEQUALS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EQUALS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('=' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mGREATER_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = GREATER_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('>' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mQUESTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = QUESTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('?' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCOMMERCIAL_AT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMERCIAL_AT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('@' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mOPENING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('[' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCLOSING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(']' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCARET(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CARET; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('^' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mUNDERLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = UNDERLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('_' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mOPENING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('{' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mCLOSING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('}' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mTILDE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TILDE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('~' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PIXCfgLexer::mEXLAMATION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EXLAMATION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('!' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } const unsigned long PIXCfgLexer::_tokenSet_0_data_[] = { 4294958072UL, 1UL, 0UL, 2147483648UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x7f 0x80 0x81 // 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f // 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d // 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab // 0xac 0xad 0xae 0xaf 0xb0 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 // 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_0(_tokenSet_0_data_,16); const unsigned long PIXCfgLexer::_tokenSet_1_data_[] = { 4294958072UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! \" # $ % // & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G // H I J K L M N O P Q R S T U V W X Y Z [ 0x5c ] ^ _ ` a b c d e f g h // i j k l m n o p q r s t u v w x y z { | } ~ 0x7f 0x80 0x81 0x82 0x83 // 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 // 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f // 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad // 0xae 0xaf 0xb0 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb // 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_1(_tokenSet_1_data_,16); const unsigned long PIXCfgLexer::_tokenSet_2_data_[] = { 0UL, 67043328UL, 0UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 a b c d e f const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long PIXCfgLexer::_tokenSet_3_data_[] = { 0UL, 134152192UL, 0UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 : a b c d e f const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_3(_tokenSet_3_data_,10); const unsigned long PIXCfgLexer::_tokenSet_4_data_[] = { 0UL, 67059712UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // . 0 1 2 3 4 5 6 7 8 9 const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_4(_tokenSet_4_data_,10); const unsigned long PIXCfgLexer::_tokenSet_5_data_[] = { 0UL, 16UL, 134217726UL, 134217726UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // $ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g // h i j k l m n o p q r s t u v w x y z const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_5(_tokenSet_5_data_,10); const unsigned long PIXCfgLexer::_tokenSet_6_data_[] = { 4294967288UL, 4294967291UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 // 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! # $ // % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F // G H I J K L M N O P Q R S T U V W X Y Z [ 0x5c ] ^ _ ` a b c d e f g // h i j k l m n o p q r s t u v w x y z { | } ~ 0x7f 0x80 0x81 0x82 0x83 // 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 // 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f // 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad // 0xae 0xaf 0xb0 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb // 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgLexer::_tokenSet_6(_tokenSet_6_data_,16); fwbuilder-5.1.0.3599/src/parsers/PIXCfgLexer.txt0000644000175000017500000027421211733011756022075 0ustar sylvestresylvestreANTLR-generated file resulting from grammar pix.g Diagnostic output Terence Parr, MageLang Institute with John Lilley, Empathy Software ANTLR Version 2.7.7 (20090306); 1989-2005 *** Header Action. This action will appear at the top of all generated files. // gets inserted after generated namespace specifications in the // header file. But outside the generated class. *** End of Header Action *** Lexer Preamble Action. This action will appear before the declaration of your lexer class: *** End of Lexer Preamble Action *** Your lexer class is called 'PIXCfgLexer' and is a subclass of 'CharScanner'. *** User-defined lexer class members: These are the member declarations that you defined for your class: *** End of user-defined lexer class members *** String literals used in the parser The following string literals were used in the parser. An actual code generator would arrange to place these literals into a table in the generated lexer, so that actions in the generated lexer could match token text against the literals. String literals used in the lexer are not listed here, as they are incorporated into the mainstream lexer processing. *** End of string literals used by the parser *** Lexer nextToken rule: The lexer nextToken rule is synthesized from all of the user-defined lexer rules. It logically consists of one big alternative block with each user-defined rule being an alternative. The grammar analyzer has determined that the synthesized nextToken rule is non-deterministic (i.e., it has ambiguities) This means that there is some overlap of the character lookahead for two or more of your lexer rules. Start of an alternative block. The lookahead set for this block is: k==1: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ']', '^', '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } k==2: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } k==3: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: {'!' } k==2: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Rule Reference: mLINE_COMMENT Otherwise, Alternate(2) will be taken IF: The lookahead set: { '\n', '\r' } is matched. Rule Reference: mNEWLINE Otherwise, Alternate(3) will be taken IF: The lookahead set: k==1: {':' } k==2: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Rule Reference: mCOLON_COMMENT Otherwise, Alternate(4) will be taken IF: The lookahead set: k==1: {':' } k==2: { } is matched. Rule Reference: mCOLON Otherwise, Alternate(5) will be taken IF: The lookahead set: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Rule Reference: mWhitespace Otherwise, Alternate(6) will be taken IF: The lookahead set: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } k==2: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 'a', 'b', 'c', 'd', 'e', 'f' } k==3: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Rule Reference: mNUMBER Otherwise, Alternate(7) will be taken IF: The lookahead set: { '.' } is matched. Rule Reference: mDOT Otherwise, Alternate(8) will be taken IF: The lookahead set: k==1: { '$', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } k==2: { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } k==3: { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } is matched. Rule Reference: mWORD Otherwise, Alternate(9) will be taken IF: The lookahead set: { '"' } is matched. Rule Reference: mSTRING Otherwise, Alternate(10) will be taken IF: The lookahead set: { '|' } is matched. Rule Reference: mPIPE_CHAR Otherwise, Alternate(11) will be taken IF: The lookahead set: { '#' } is matched. Rule Reference: mNUMBER_SIGN Otherwise, Alternate(12) will be taken IF: The lookahead set: { '%' } is matched. Rule Reference: mPERCENT Otherwise, Alternate(13) will be taken IF: The lookahead set: { '&' } is matched. Rule Reference: mAMPERSAND Otherwise, Alternate(14) will be taken IF: The lookahead set: { '\'' } is matched. Rule Reference: mAPOSTROPHE Otherwise, Alternate(15) will be taken IF: The lookahead set: { '(' } is matched. Rule Reference: mOPENING_PAREN Otherwise, Alternate(16) will be taken IF: The lookahead set: { ')' } is matched. Rule Reference: mCLOSING_PAREN Otherwise, Alternate(17) will be taken IF: The lookahead set: { '*' } is matched. Rule Reference: mSTAR Otherwise, Alternate(18) will be taken IF: The lookahead set: { '+' } is matched. Rule Reference: mPLUS Otherwise, Alternate(19) will be taken IF: The lookahead set: { ',' } is matched. Rule Reference: mCOMMA Otherwise, Alternate(20) will be taken IF: The lookahead set: { '-' } is matched. Rule Reference: mMINUS Otherwise, Alternate(21) will be taken IF: The lookahead set: { '/' } is matched. Rule Reference: mSLASH Otherwise, Alternate(22) will be taken IF: The lookahead set: { ';' } is matched. Rule Reference: mSEMICOLON Otherwise, Alternate(23) will be taken IF: The lookahead set: { '<' } is matched. Rule Reference: mLESS_THAN Otherwise, Alternate(24) will be taken IF: The lookahead set: { '=' } is matched. Rule Reference: mEQUALS Otherwise, Alternate(25) will be taken IF: The lookahead set: { '>' } is matched. Rule Reference: mGREATER_THAN Otherwise, Alternate(26) will be taken IF: The lookahead set: { '?' } is matched. Rule Reference: mQUESTION Otherwise, Alternate(27) will be taken IF: The lookahead set: { '@' } is matched. Rule Reference: mCOMMERCIAL_AT Otherwise, Alternate(28) will be taken IF: The lookahead set: { '[' } is matched. Rule Reference: mOPENING_SQUARE Otherwise, Alternate(29) will be taken IF: The lookahead set: { ']' } is matched. Rule Reference: mCLOSING_SQUARE Otherwise, Alternate(30) will be taken IF: The lookahead set: { '^' } is matched. Rule Reference: mCARET Otherwise, Alternate(31) will be taken IF: The lookahead set: { '_' } is matched. Rule Reference: mUNDERLINE Otherwise, Alternate(32) will be taken IF: The lookahead set: { '{' } is matched. Rule Reference: mOPENING_BRACE Otherwise, Alternate(33) will be taken IF: The lookahead set: { '}' } is matched. Rule Reference: mCLOSING_BRACE Otherwise, Alternate(34) will be taken IF: The lookahead set: { '~' } is matched. Rule Reference: mTILDE Otherwise, Alternate(35) will be taken IF: The lookahead set: k==1: {'!' } k==2: { } is matched. Rule Reference: mEXLAMATION OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. *** End of nextToken lexer rule. *** User-defined Lexer rules: *** Lexer Rule: mLINE_COMMENT Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '!' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '!' } is matched. Match string literal "!" Start ZERO-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { '\r' } is matched. Match character '\r' Otherwise, Alternate(2) will be taken IF: The lookahead set: { '\n' } is matched. Match character '\n' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ZERO-OR-MORE block. Rule Reference: mNEWLINE OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mLINE_COMMENT *** Lexer Rule: mNEWLINE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '\n', '\r' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '\n', '\r' } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: k==1: {'\n', '\r' } k==2: {'\n' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: {'\r' } k==2: {'\n' } is matched. Match string literal "\r\n" Otherwise, Alternate(2) will be taken IF: The lookahead set: k==1: {'\r' } k==2: { } is matched. Match character '\r' Otherwise, Alternate(3) will be taken IF: The lookahead set: { '\n' } is matched. Match character '\n' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: newline(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mNEWLINE *** Lexer Rule: mCOLON_COMMENT Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { ':' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { ':' } is matched. Rule Reference: mCOLON Start ZERO-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { '\r' } is matched. Match character '\r' Otherwise, Alternate(2) will be taken IF: The lookahead set: { '\n' } is matched. Match character '\n' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ZERO-OR-MORE block. Rule Reference: mNEWLINE OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCOLON_COMMENT *** Lexer Rule: mCOLON Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { ':' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { ':' } is matched. Match character ':' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCOLON *** Lexer Rule: mWhitespace Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\u000b', '\u000c', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008' } is matched. Match character range: '\003'..'\010' Otherwise, Alternate(2) will be taken IF: The lookahead set: { '\t' } is matched. Match character '\t' Otherwise, Alternate(3) will be taken IF: The lookahead set: { '\u000b' } is matched. Match character '\013' Otherwise, Alternate(4) will be taken IF: The lookahead set: { '\u000c' } is matched. Match character '\f' Otherwise, Alternate(5) will be taken IF: The lookahead set: { '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f' } is matched. Match character range: '\016'..'\037' Otherwise, Alternate(6) will be taken IF: The lookahead set: { '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Match character range: '\177'..'\377' Otherwise, Alternate(7) will be taken IF: The lookahead set: { ' ' } is matched. Match character ' ' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mWhitespace *** Lexer Rule: mINT_CONST Access: protected Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: MATCHES ALL is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mINT_CONST *** Lexer Rule: mHEX_CONST Access: protected Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: MATCHES ALL is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mHEX_CONST *** Lexer Rule: mNEG_INT_CONST Access: protected Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: MATCHES ALL is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mNEG_INT_CONST *** Lexer Rule: mDIGIT Access: protected Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Match character range: '0'..'9' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mDIGIT *** Lexer Rule: mHEXDIGIT Access: protected Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { 'a', 'b', 'c', 'd', 'e', 'f' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Match character range: 'a'..'f' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mHEXDIGIT *** Lexer Rule: mNUMBER Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Start of alternative block. Warning: This alternative block is non-deterministic Start of an alternative block. The lookahead set for this block is: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } k==2: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 'a', 'b', 'c', 'd', 'e', 'f' } k==3: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 'a', 'b', 'c', 'd', 'e', 'f' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==2: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==3: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched, AND the syntactic predicate: Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. is matched. Start of alternative block. Warning: This alternative block is non-deterministic Start of an alternative block. The lookahead set for this block is: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==2: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==3: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==2: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==3: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched, AND the syntactic predicate: Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: _ttype = IPV4; Otherwise, Alternate(2) will be taken IF: The lookahead set: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==2: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==3: { '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched, AND the syntactic predicate: Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Rule Reference: mDOT Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Otherwise, Alternate(3) will be taken IF: The lookahead set: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==2: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } k==3: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Rule Reference: mDIGIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. ACTION: _ttype = INT_CONST; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Otherwise, Alternate(2) will be taken IF: The lookahead set: k==1: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } k==2: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 'a', 'b', 'c', 'd', 'e', 'f' } k==3: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', 'a', 'b', 'c', 'd', 'e', 'f' } is matched, AND the syntactic predicate: Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Match character range: 'a'..'f' Otherwise, Alternate(2) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Match character range: '0'..'9' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. End ONE-OR-MORE block. Rule Reference: mCOLON OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { 'a', 'b', 'c', 'd', 'e', 'f' } is matched. Match character range: 'a'..'f' Otherwise, Alternate(2) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Match character range: '0'..'9' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. End ONE-OR-MORE block. Rule Reference: mCOLON OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: _ttype = IPV6; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mNUMBER *** Lexer Rule: mDOT Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '.' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '.' } is matched. Match character '.' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mDOT *** Lexer Rule: mWORD Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '$', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '$', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { '$', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } is matched. Match character range: 'a'..'z' Otherwise, Alternate(2) will be taken IF: The lookahead set: { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' } is matched. Match character range: 'A'..'Z' Otherwise, Alternate(3) will be taken IF: The lookahead set: { '$' } is matched. Match character '$' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start ZERO-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/' } is matched. Match character range: '!'..'/' Otherwise, Alternate(2) will be taken IF: The lookahead set: { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } is matched. Match character range: '0'..'9' Otherwise, Alternate(3) will be taken IF: The lookahead set: { ':' } is matched. Match character ':' Otherwise, Alternate(4) will be taken IF: The lookahead set: { ';' } is matched. Match character ';' Otherwise, Alternate(5) will be taken IF: The lookahead set: { '<' } is matched. Match character '<' Otherwise, Alternate(6) will be taken IF: The lookahead set: { '=' } is matched. Match character '=' Otherwise, Alternate(7) will be taken IF: The lookahead set: { '>' } is matched. Match character '>' Otherwise, Alternate(8) will be taken IF: The lookahead set: { '?' } is matched. Match character '?' Otherwise, Alternate(9) will be taken IF: The lookahead set: { '@' } is matched. Match character '@' Otherwise, Alternate(10) will be taken IF: The lookahead set: { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' } is matched. Match character range: 'A'..'Z' Otherwise, Alternate(11) will be taken IF: The lookahead set: { '\\' } is matched. Match character '\\' Otherwise, Alternate(12) will be taken IF: The lookahead set: { '^' } is matched. Match character '^' Otherwise, Alternate(13) will be taken IF: The lookahead set: { '_' } is matched. Match character '_' Otherwise, Alternate(14) will be taken IF: The lookahead set: { '`' } is matched. Match character '`' Otherwise, Alternate(15) will be taken IF: The lookahead set: { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } is matched. Match character range: 'a'..'z' OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. End ZERO-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mWORD *** Lexer Rule: mSTRING Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '"' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '"' } is matched. Match character '"' Start ZERO-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\t', '\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f', ' ', '!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\u007f', '\u0080', '\u0081', '\u0082', '\u0083', '\u0084', '\u0085', '\u0086', '\u0087', '\u0088', '\u0089', '\u008a', '\u008b', '\u008c', '\u008d', '\u008e', '\u008f', '\u0090', '\u0091', '\u0092', '\u0093', '\u0094', '\u0095', '\u0096', '\u0097', '\u0098', '\u0099', '\u009a', '\u009b', '\u009c', '\u009d', '\u009e', '\u009f', '\u00a0', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\u00ad', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff' } is matched. Match character NOT '"' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ZERO-OR-MORE block. Match character '"' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mSTRING *** Lexer Rule: mPIPE_CHAR Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '|' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '|' } is matched. Match character '|' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mPIPE_CHAR *** Lexer Rule: mNUMBER_SIGN Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '#' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '#' } is matched. Match character '#' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mNUMBER_SIGN *** Lexer Rule: mPERCENT Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '%' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '%' } is matched. Match character '%' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mPERCENT *** Lexer Rule: mAMPERSAND Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '&' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '&' } is matched. Match character '&' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mAMPERSAND *** Lexer Rule: mAPOSTROPHE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '\'' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '\'' } is matched. Match character '\'' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mAPOSTROPHE *** Lexer Rule: mOPENING_PAREN Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '(' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '(' } is matched. Match character '(' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mOPENING_PAREN *** Lexer Rule: mCLOSING_PAREN Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { ')' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { ')' } is matched. Match character ')' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCLOSING_PAREN *** Lexer Rule: mSTAR Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '*' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '*' } is matched. Match character '*' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mSTAR *** Lexer Rule: mPLUS Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '+' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '+' } is matched. Match character '+' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mPLUS *** Lexer Rule: mCOMMA Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { ',' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { ',' } is matched. Match character ',' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCOMMA *** Lexer Rule: mMINUS Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '-' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '-' } is matched. Match character '-' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mMINUS *** Lexer Rule: mSLASH Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '/' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '/' } is matched. Match character '/' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mSLASH *** Lexer Rule: mSEMICOLON Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { ';' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { ';' } is matched. Match character ';' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mSEMICOLON *** Lexer Rule: mLESS_THAN Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '<' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '<' } is matched. Match character '<' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mLESS_THAN *** Lexer Rule: mEQUALS Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '=' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '=' } is matched. Match character '=' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mEQUALS *** Lexer Rule: mGREATER_THAN Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '>' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '>' } is matched. Match character '>' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mGREATER_THAN *** Lexer Rule: mQUESTION Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '?' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '?' } is matched. Match character '?' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mQUESTION *** Lexer Rule: mCOMMERCIAL_AT Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '@' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '@' } is matched. Match character '@' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCOMMERCIAL_AT *** Lexer Rule: mOPENING_SQUARE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '[' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '[' } is matched. Match character '[' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mOPENING_SQUARE *** Lexer Rule: mCLOSING_SQUARE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { ']' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { ']' } is matched. Match character ']' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCLOSING_SQUARE *** Lexer Rule: mCARET Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '^' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '^' } is matched. Match character '^' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCARET *** Lexer Rule: mUNDERLINE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '_' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '_' } is matched. Match character '_' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mUNDERLINE *** Lexer Rule: mOPENING_BRACE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '{' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '{' } is matched. Match character '{' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mOPENING_BRACE *** Lexer Rule: mCLOSING_BRACE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '}' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '}' } is matched. Match character '}' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mCLOSING_BRACE *** Lexer Rule: mTILDE Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '~' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '~' } is matched. Match character '~' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mTILDE *** Lexer Rule: mEXLAMATION Access: public Return value: lexical rule returns an implicit token type Start of an alternative block. The lookahead set for this block is: { '!' } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { '!' } is matched. Match character '!' OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. *** End Lexer Rule: mEXLAMATION *** End User-defined Lexer rules: fwbuilder-5.1.0.3599/src/parsers/IPTCfgLexer.cpp0000644000175000017500000027322611733011756022040 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20090306): "iptables.g" -> "IPTCfgLexer.cpp"$ */ #line 55 "iptables.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IPTCfgLexer.cpp" #include "IPTCfgLexer.hpp" #include #include #include #include #include #include #include #line 61 "iptables.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #include "fwbuilder/TCPService.h" #include "fwbuilder/Logger.h" #include #line 30 "IPTCfgLexer.cpp" #line 1 "iptables.g" #line 32 "IPTCfgLexer.cpp" IPTCfgLexer::IPTCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in) : ANTLR_USE_NAMESPACE(antlr)CharScanner(new ANTLR_USE_NAMESPACE(antlr)CharBuffer(in),true) { initLiterals(); } IPTCfgLexer::IPTCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib) : ANTLR_USE_NAMESPACE(antlr)CharScanner(ib,true) { initLiterals(); } IPTCfgLexer::IPTCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)CharScanner(state,true) { initLiterals(); } void IPTCfgLexer::initLiterals() { literals["FIN"] = 109; literals["RST"] = 110; literals["NEW"] = 63; literals["comment"] = 96; literals["ESTABLISHED"] = 64; literals["recent"] = 74; literals["limit"] = 71; literals["POSTROUTING"] = 16; literals["INPUT"] = 12; literals["ACK"] = 108; literals["URG"] = 111; literals["mark"] = 69; literals["iprange"] = 75; literals["multiport"] = 95; literals["pkttype"] = 90; literals["broadcast"] = 92; literals["NONE"] = 114; literals["multicast"] = 93; literals["ALL"] = 113; literals["length"] = 88; literals["PSH"] = 112; literals["SYN"] = 107; literals["udp"] = 33; literals["PREROUTING"] = 15; literals["FORWARD"] = 13; literals["INVALID"] = 62; literals["OUTPUT"] = 14; literals["state"] = 66; literals["unicast"] = 94; literals["RELATED"] = 65; literals["icmp"] = 34; literals["tcp"] = 32; literals["COMMIT"] = 9; } ANTLR_USE_NAMESPACE(antlr)RefToken IPTCfgLexer::nextToken() { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; for (;;) { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; int _ttype = ANTLR_USE_NAMESPACE(antlr)Token::INVALID_TYPE; resetText(); try { // for lexical and char stream error handling switch ( LA(1)) { case 0xa /* '\n' */ : case 0xd /* '\r' */ : { mNEWLINE(true); theRetToken=_returnToken; break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { mNUMBER(true); theRetToken=_returnToken; break; } case 0x24 /* '$' */ : case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { mWORD(true); theRetToken=_returnToken; break; } case 0x22 /* '\"' */ : { mSTRING(true); theRetToken=_returnToken; break; } case 0x21 /* '!' */ : { mEXCLAMATION(true); theRetToken=_returnToken; break; } case 0x23 /* '#' */ : { mNUMBER_SIGN(true); theRetToken=_returnToken; break; } case 0x25 /* '%' */ : { mPERCENT(true); theRetToken=_returnToken; break; } case 0x26 /* '&' */ : { mAMPERSAND(true); theRetToken=_returnToken; break; } case 0x27 /* '\'' */ : { mAPOSTROPHE(true); theRetToken=_returnToken; break; } case 0x28 /* '(' */ : { mOPENING_PAREN(true); theRetToken=_returnToken; break; } case 0x29 /* ')' */ : { mCLOSING_PAREN(true); theRetToken=_returnToken; break; } case 0x2a /* '*' */ : { mSTAR(true); theRetToken=_returnToken; break; } case 0x2b /* '+' */ : { mPLUS(true); theRetToken=_returnToken; break; } case 0x2c /* ',' */ : { mCOMMA(true); theRetToken=_returnToken; break; } case 0x2e /* '.' */ : { mDOT(true); theRetToken=_returnToken; break; } case 0x2f /* '/' */ : { mSLASH(true); theRetToken=_returnToken; break; } case 0x3a /* ':' */ : { mCOLON(true); theRetToken=_returnToken; break; } case 0x3b /* ';' */ : { mSEMICOLON(true); theRetToken=_returnToken; break; } case 0x3c /* '<' */ : { mLESS_THAN(true); theRetToken=_returnToken; break; } case 0x3d /* '=' */ : { mEQUALS(true); theRetToken=_returnToken; break; } case 0x3e /* '>' */ : { mGREATER_THAN(true); theRetToken=_returnToken; break; } case 0x3f /* '?' */ : { mQUESTION(true); theRetToken=_returnToken; break; } case 0x40 /* '@' */ : { mCOMMERCIAL_AT(true); theRetToken=_returnToken; break; } case 0x5b /* '[' */ : { mOPENING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5d /* ']' */ : { mCLOSING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5e /* '^' */ : { mCARET(true); theRetToken=_returnToken; break; } case 0x5f /* '_' */ : { mUNDERLINE(true); theRetToken=_returnToken; break; } case 0x7b /* '{' */ : { mOPENING_BRACE(true); theRetToken=_returnToken; break; } case 0x7d /* '}' */ : { mCLOSING_BRACE(true); theRetToken=_returnToken; break; } case 0x7e /* '~' */ : { mTILDE(true); theRetToken=_returnToken; break; } default: if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x64 /* 'd' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x73 /* 's' */ ) && (LA(6) == 0x74 /* 't' */ ) && (LA(7) == 0x69 /* 'i' */ ) && (LA(8) == 0x6e /* 'n' */ ) && (LA(9) == 0x61 /* 'a' */ ) && (LA(10) == 0x74 /* 't' */ ) && (LA(11) == 0x69 /* 'i' */ ) && (LA(12) == 0x6f /* 'o' */ ) && (LA(13) == 0x6e /* 'n' */ ) && (LA(14) == 0x2d /* '-' */ ) && (LA(15) == 0x70 /* 'p' */ ) && (LA(16) == 0x6f /* 'o' */ ) && (LA(17) == 0x72 /* 'r' */ ) && (LA(18) == 0x74 /* 't' */ ) && (LA(19) == 0x73 /* 's' */ )) { mMATCH_DST_MULTIPORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x64 /* 'd' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x73 /* 's' */ ) && (LA(6) == 0x74 /* 't' */ ) && (LA(7) == 0x69 /* 'i' */ ) && (LA(8) == 0x6e /* 'n' */ ) && (LA(9) == 0x61 /* 'a' */ ) && (LA(10) == 0x74 /* 't' */ ) && (LA(11) == 0x69 /* 'i' */ ) && (LA(12) == 0x6f /* 'o' */ ) && (LA(13) == 0x6e /* 'n' */ ) && (LA(14) == 0x2d /* '-' */ ) && (LA(15) == 0x70 /* 'p' */ ) && (LA(16) == 0x6f /* 'o' */ ) && (LA(17) == 0x72 /* 'r' */ ) && (LA(18) == 0x74 /* 't' */ ) && (true)) { mMATCH_DST_PORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x75 /* 'u' */ ) && (LA(6) == 0x72 /* 'r' */ ) && (LA(7) == 0x63 /* 'c' */ ) && (LA(8) == 0x65 /* 'e' */ ) && (LA(9) == 0x2d /* '-' */ ) && (LA(10) == 0x70 /* 'p' */ ) && (LA(11) == 0x6f /* 'o' */ ) && (LA(12) == 0x72 /* 'r' */ ) && (LA(13) == 0x74 /* 't' */ ) && (LA(14) == 0x73 /* 's' */ )) { mMATCH_SRC_MULTIPORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x75 /* 'u' */ ) && (LA(6) == 0x72 /* 'r' */ ) && (LA(7) == 0x63 /* 'c' */ ) && (LA(8) == 0x65 /* 'e' */ ) && (LA(9) == 0x2d /* '-' */ ) && (LA(10) == 0x70 /* 'p' */ ) && (LA(11) == 0x6f /* 'o' */ ) && (LA(12) == 0x72 /* 'r' */ ) && (LA(13) == 0x74 /* 't' */ ) && (true)) { mMATCH_SRC_PORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x67 /* 'g' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x74 /* 't' */ ) && (LA(8) == 0x63 /* 'c' */ ) && (LA(9) == 0x70 /* 'p' */ ) && (LA(10) == 0x2d /* '-' */ ) && (LA(11) == 0x73 /* 's' */ )) { mLOG_TCP_SEQ(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x67 /* 'g' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x74 /* 't' */ ) && (LA(8) == 0x63 /* 'c' */ ) && (LA(9) == 0x70 /* 'p' */ ) && (LA(10) == 0x2d /* '-' */ ) && (LA(11) == 0x6f /* 'o' */ )) { mLOG_TCP_OPT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x69 /* 'i' */ ) && (LA(5) == 0x6d /* 'm' */ ) && (LA(6) == 0x69 /* 'i' */ ) && (LA(7) == 0x74 /* 't' */ ) && (LA(8) == 0x2d /* '-' */ )) { mMATCH_LIMIT_BURST(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x75 /* 'u' */ ) && (LA(4) == 0x6c /* 'l' */ ) && (LA(5) == 0x6f /* 'o' */ ) && (LA(6) == 0x67 /* 'g' */ ) && (LA(7) == 0x2d /* '-' */ ) && (LA(8) == 0x70 /* 'p' */ )) { mULOG_PREFIX(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x75 /* 'u' */ ) && (LA(4) == 0x6c /* 'l' */ ) && (LA(5) == 0x6f /* 'o' */ ) && (LA(6) == 0x67 /* 'g' */ ) && (LA(7) == 0x2d /* '-' */ ) && (LA(8) == 0x71 /* 'q' */ )) { mULOG_QTHR(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x75 /* 'u' */ ) && (LA(4) == 0x6c /* 'l' */ ) && (LA(5) == 0x6f /* 'o' */ ) && (LA(6) == 0x67 /* 'g' */ ) && (LA(7) == 0x2d /* '-' */ ) && (LA(8) == 0x6e /* 'n' */ )) { mULOG_NLG(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x75 /* 'u' */ ) && (LA(4) == 0x6c /* 'l' */ ) && (LA(5) == 0x6f /* 'o' */ ) && (LA(6) == 0x67 /* 'g' */ ) && (LA(7) == 0x2d /* '-' */ ) && (LA(8) == 0x63 /* 'c' */ )) { mULOG_CPR(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x63 /* 'c' */ ) && (LA(5) == 0x70 /* 'p' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x66 /* 'f' */ )) { mMATCH_TCP_FLAGS(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x63 /* 'c' */ ) && (LA(5) == 0x70 /* 'p' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x6f /* 'o' */ )) { mMATCH_TCP_OPTION(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x69 /* 'i' */ ) && (LA(5) == 0x6d /* 'm' */ ) && (LA(6) == 0x69 /* 'i' */ ) && (LA(7) == 0x74 /* 't' */ ) && (true)) { mMATCH_LIMIT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x74 /* 't' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x63 /* 'c' */ )) { mSET_CLASS(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x74 /* 't' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x6d /* 'm' */ )) { mSET_MARK(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x74 /* 't' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x74 /* 't' */ )) { mSET_TOS(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x67 /* 'g' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x70 /* 'p' */ )) { mLOG_PREFIX(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x67 /* 'g' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x6c /* 'l' */ )) { mLOG_LEVEL(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x67 /* 'g' */ ) && (LA(6) == 0x2d /* '-' */ ) && (LA(7) == 0x69 /* 'i' */ )) { mLOG_IP_OPT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x2d /* '-' */ ) && (LA(6) == 0x73 /* 's' */ )) { mTO_SOURCE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x2d /* '-' */ ) && (LA(6) == 0x64 /* 'd' */ )) { mTO_DESTINATION(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x2d /* '-' */ ) && (LA(6) == 0x70 /* 'p' */ )) { mTO_PORTS(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x6d /* 'm' */ )) { mMATCH_RECENT_REMOVE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x63 /* 'c' */ )) { mMATCH_RECENT_SECONDS(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x74 /* 't' */ ) && (true)) { mMATCH_RECENT_SET(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x63 /* 'c' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x6d /* 'm' */ )) { mMATCH_COMMENT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x6a /* 'j' */ )) { mREJECT_WITH(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x65 /* 'e' */ ) && (LA(5) == 0x73 /* 's' */ )) { mRESTORE_MARK(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x63 /* 'c' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (LA(5) == 0x6e /* 'n' */ )) { mCONTINUE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x73 /* 's' */ )) { mRSOURCE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x74 /* 't' */ )) { mMATCH_STATE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x70 /* 'p' */ ) && (LA(4) == 0x6f /* 'o' */ )) { mMATCH_BOTH_MULTIPORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x70 /* 'p' */ )) { mMATCH_SRC_PORT_SHORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x64 /* 'd' */ ) && (LA(4) == 0x70 /* 'p' */ )) { mMATCH_DST_PORT_SHORT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x79 /* 'y' */ )) { mMATCH_SYN(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x69 /* 'i' */ ) && (LA(4) == 0x63 /* 'c' */ )) { mMATCH_ICMP_TYPE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6c /* 'l' */ ) && (LA(4) == 0x65 /* 'e' */ )) { mMATCH_LENGTH(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x63 /* 'c' */ )) { mMATCH_RECENT_RCHECK(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x75 /* 'u' */ ) && (LA(4) == 0x70 /* 'p' */ )) { mMATCH_RECENT_UPDATE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x74 /* 't' */ )) { mMATCH_RECENT_RTTL(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x72 /* 'r' */ ) && (LA(4) == 0x64 /* 'd' */ )) { mMATCH_RECENT_RDEST(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x72 /* 'r' */ )) { mMATCH_IPRANGE_SRC(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x64 /* 'd' */ ) && (LA(4) == 0x73 /* 's' */ )) { mMATCH_IPRANGE_DST(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x70 /* 'p' */ ) && (LA(4) == 0x6b /* 'k' */ )) { mMATCH_PKT_TYPE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x73 /* 's' */ ) && (LA(4) == 0x61 /* 'a' */ )) { mSAVE_MARK(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x69 /* 'i' */ ) && (LA(4) == 0x69 /* 'i' */ )) { mROUTE_IIF(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x65 /* 'e' */ )) { mROUTE_TEE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x74 /* 't' */ ) && (LA(4) == 0x6f /* 'o' */ ) && (true)) { mTO_NETMAP(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x63 /* 'c' */ ) && (LA(4) == 0x6c /* 'l' */ )) { mCLAMP_MSS(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6d /* 'm' */ )) { mMATCH_MARK(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6e /* 'n' */ )) { mMATCH_RECENT_NAME(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x68 /* 'h' */ )) { mMATCH_RECENT_HITCOUNT(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x6f /* 'o' */ )) { mROUTE_OIF(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x2d /* '-' */ ) && (LA(3) == 0x67 /* 'g' */ )) { mROUTE_GW(true); theRetToken=_returnToken; } else if ((LA(1) == 0x20 /* ' ' */ ) && (LA(2) == 0x47 /* 'G' */ )) { mIPTABLES_SAVE_HEADER(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x41 /* 'A' */ )) { mADD_RULE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x6d /* 'm' */ )) { mOPT_MODULE(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x73 /* 's' */ )) { mOPT_SRC(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x64 /* 'd' */ )) { mOPT_DST(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x69 /* 'i' */ )) { mOPT_IN_INTF(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x6f /* 'o' */ )) { mOPT_OUT_INTF(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x70 /* 'p' */ )) { mOPT_PROTO(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x6a /* 'j' */ )) { mOPT_TARGET(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (LA(2) == 0x66 /* 'f' */ )) { mOPT_FRAGM(true); theRetToken=_returnToken; } else if ((_tokenSet_0.member(LA(1))) && (true)) { mWhitespace(true); theRetToken=_returnToken; } else if ((LA(1) == 0x2d /* '-' */ ) && (true)) { mMINUS(true); theRetToken=_returnToken; } else { if (LA(1)==EOF_CHAR) { uponEOF(); _returnToken = makeToken(ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE); } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } if ( !_returnToken ) goto tryAgain; // found SKIP token _ttype = _returnToken->getType(); _ttype = testLiteralsTable(_ttype); _returnToken->setType(_ttype); return _returnToken; } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& e) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamRecognitionException(e); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamIOException& csie) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamIOException(csie.io); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamException& cse) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamException(cse.getMessage()); } tryAgain:; } } void IPTCfgLexer::mIPTABLES_SAVE_HEADER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = IPTABLES_SAVE_HEADER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(" Generated by iptables-save v"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mWhitespace(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = Whitespace; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x3 /* '\3' */ : case 0x4 /* '\4' */ : case 0x5 /* '\5' */ : case 0x6 /* '\6' */ : case 0x7 /* '\7' */ : case 0x8 /* '\10' */ : { matchRange('\3','\10'); break; } case 0x9 /* '\t' */ : { match('\t' /* charlit */ ); break; } case 0xb /* '\13' */ : { match('\13' /* charlit */ ); break; } case 0xc /* '\14' */ : { match('\14' /* charlit */ ); break; } case 0xe /* '\16' */ : case 0xf /* '\17' */ : case 0x10 /* '\20' */ : case 0x11 /* '\21' */ : case 0x12 /* '\22' */ : case 0x13 /* '\23' */ : case 0x14 /* '\24' */ : case 0x15 /* '\25' */ : case 0x16 /* '\26' */ : case 0x17 /* '\27' */ : case 0x18 /* '\30' */ : case 0x19 /* '\31' */ : case 0x1a /* '\32' */ : case 0x1b /* '\33' */ : case 0x1c /* '\34' */ : case 0x1d /* '\35' */ : case 0x1e /* '\36' */ : case 0x1f /* '\37' */ : { matchRange('\16','\37'); break; } case 0x20 /* ' ' */ : { match(' ' /* charlit */ ); break; } default: if (((LA(1) >= 0x7f && LA(1) <= 0xff))) { matchRange('\177',static_cast('\377')); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( inputState->guessing==0 ) { #line 1250 "iptables.g" _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; #line 723 "IPTCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mNEWLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEWLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { if ((LA(1) == 0xd /* '\r' */ ) && (LA(2) == 0xa /* '\n' */ )) { match("\r\n"); } else if ((LA(1) == 0xd /* '\r' */ ) && (true)) { match('\r' /* charlit */ ); } else if ((LA(1) == 0xa /* '\n' */ )) { match('\n' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 1252 "iptables.g" newline(); resetText(); #line 756 "IPTCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mIPV4(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = IPV4; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mTHREE_COMPONENT_VERSION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = THREE_COMPONENT_VERSION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mIPV6(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = IPV6; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMAC_ADDRESS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MAC_ADDRESS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mINT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mHEX_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mNEG_INT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEG_INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('0','9'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mHEXDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEXDIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; switch ( LA(1)) { case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : { matchRange('A','F'); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mNUM_3DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_3DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { matchRange('0','9'); } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mNUM_HEX_4DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_HEX_4DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; mHEXDIGIT(false); { if ((_tokenSet_1.member(LA(1)))) { { mHEXDIGIT(false); } { if ((_tokenSet_1.member(LA(1)))) { { mHEXDIGIT(false); } { if ((_tokenSet_1.member(LA(1)))) { mHEXDIGIT(false); } else { } } } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mNUMBER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; bool synPredMatched186 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_2.member(LA(2))) && (_tokenSet_2.member(LA(3))) && (_tokenSet_2.member(LA(4))) && (_tokenSet_2.member(LA(5))) && (_tokenSet_2.member(LA(6))) && (_tokenSet_2.member(LA(7))) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true))) { int _m186 = mark(); synPredMatched186 = true; inputState->guessing++; try { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched186 = false; } rewind(_m186); inputState->guessing--; } if ( synPredMatched186 ) { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); if ( inputState->guessing==0 ) { #line 1319 "iptables.g" _ttype = IPV4; #line 1036 "IPTCfgLexer.cpp" } } } else { bool synPredMatched189 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_2.member(LA(2))) && (_tokenSet_2.member(LA(3))) && (_tokenSet_2.member(LA(4))) && (_tokenSet_2.member(LA(5))) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true))) { int _m189 = mark(); synPredMatched189 = true; inputState->guessing++; try { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched189 = false; } rewind(_m189); inputState->guessing--; } if ( synPredMatched189 ) { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); if ( inputState->guessing==0 ) { #line 1323 "iptables.g" _ttype = THREE_COMPONENT_VERSION; #line 1070 "IPTCfgLexer.cpp" } } } else if ((LA(1) == 0x30 /* '0' */ ) && (LA(2) == 0x78 /* 'x' */ )) { { match('0' /* charlit */ ); match('x' /* charlit */ ); { // ( ... )+ int _cnt193=0; for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEXDIGIT(false); } else { if ( _cnt193>=1 ) { goto _loop193; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt193++; } _loop193:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 1327 "iptables.g" _ttype = HEX_CONST; #line 1096 "IPTCfgLexer.cpp" } } else if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true) && (true)) { { // ( ... )+ int _cnt195=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt195>=1 ) { goto _loop195; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt195++; } _loop195:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 1329 "iptables.g" _ttype = INT_CONST; #line 1117 "IPTCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } _ttype = testLiteralsTable(_ttype); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mWORD(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = WORD; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x24 /* '$' */ : { match('$' /* charlit */ ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x21 /* '!' */ : case 0x22 /* '\"' */ : case 0x23 /* '#' */ : case 0x24 /* '$' */ : case 0x25 /* '%' */ : case 0x26 /* '&' */ : case 0x27 /* '\'' */ : case 0x28 /* '(' */ : case 0x29 /* ')' */ : case 0x2a /* '*' */ : case 0x2b /* '+' */ : { matchRange('!','+'); break; } case 0x2d /* '-' */ : { match('-' /* charlit */ ); break; } case 0x2e /* '.' */ : { match('.' /* charlit */ ); break; } case 0x2f /* '/' */ : { match('/' /* charlit */ ); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x3a /* ':' */ : { match(':' /* charlit */ ); break; } case 0x3b /* ';' */ : { match(';' /* charlit */ ); break; } case 0x3c /* '<' */ : { match('<' /* charlit */ ); break; } case 0x3d /* '=' */ : { match('=' /* charlit */ ); break; } case 0x3e /* '>' */ : { match('>' /* charlit */ ); break; } case 0x3f /* '?' */ : { match('?' /* charlit */ ); break; } case 0x40 /* '@' */ : { match('@' /* charlit */ ); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x5e /* '^' */ : { match('^' /* charlit */ ); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } case 0x60 /* '`' */ : { match('`' /* charlit */ ); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } default: { goto _loop199; } } } _loop199:; } // ( ... )* if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSTRING(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STRING; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\"' /* charlit */ ); { // ( ... )* for (;;) { if ((_tokenSet_3.member(LA(1)))) { matchNot('\"' /* charlit */ ); } else { goto _loop202; } } _loop202:; } // ( ... )* match('\"' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mUNSUPPORTED_OPTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = UNSUPPORTED_OPTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mRSOURCE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = RSOURCE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--rsource"); if ( inputState->guessing==0 ) { #line 1353 "iptables.g" _ttype = UNSUPPORTED_OPTION; #line 1433 "IPTCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mADD_RULE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ADD_RULE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-A"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_STATE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_STATE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--state"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_SRC_MULTIPORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_SRC_MULTIPORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--source-ports"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_DST_MULTIPORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_DST_MULTIPORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--destination-ports"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_BOTH_MULTIPORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_BOTH_MULTIPORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--ports"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_SRC_PORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_SRC_PORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--source-port"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_DST_PORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_DST_PORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--destination-port"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_SRC_PORT_SHORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_SRC_PORT_SHORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--sport"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_DST_PORT_SHORT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_DST_PORT_SHORT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--dport"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_SYN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_SYN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--syn"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_TCP_FLAGS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_TCP_FLAGS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--tcp-flags"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_TCP_OPTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_TCP_OPTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--tcp-option"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_ICMP_TYPE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_ICMP_TYPE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--icmp-type"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_MARK(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_MARK; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--mark"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_LENGTH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_LENGTH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--length"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_LIMIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_LIMIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--limit"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_LIMIT_BURST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_LIMIT_BURST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--limit-burst"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_NAME(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_NAME; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--name"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_RCHECK(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_RCHECK; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--rcheck"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_UPDATE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_UPDATE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--update"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_REMOVE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_REMOVE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--remove"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_SECONDS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_SECONDS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--seconds"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_HITCOUNT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_HITCOUNT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--hitcount"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_RTTL(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_RTTL; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--rttl"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_RDEST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_RDEST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--rdest"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_RECENT_SET(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_RECENT_SET; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--set"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_IPRANGE_SRC(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_IPRANGE_SRC; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--src-range"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_IPRANGE_DST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_IPRANGE_DST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--dst-range"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_COMMENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_COMMENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--comment"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMATCH_PKT_TYPE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MATCH_PKT_TYPE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--pkt-type"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mREJECT_WITH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = REJECT_WITH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--reject-with"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSET_CLASS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SET_CLASS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--set-class"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSET_MARK(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SET_MARK; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--set-mark"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSAVE_MARK(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SAVE_MARK; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--save-mark"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mRESTORE_MARK(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = RESTORE_MARK; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--restore-mark"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSET_TOS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SET_TOS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--set-tos"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCONTINUE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CONTINUE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--continue"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mROUTE_IIF(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ROUTE_IIF; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--iif"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mROUTE_OIF(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ROUTE_OIF; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--oif"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mROUTE_GW(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ROUTE_GW; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--gw"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mROUTE_TEE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ROUTE_TEE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--tee"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mLOG_PREFIX(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LOG_PREFIX; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--log-prefix"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mLOG_LEVEL(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LOG_LEVEL; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--log-level"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mLOG_TCP_SEQ(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LOG_TCP_SEQ; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--log-tcp-sequence"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mLOG_TCP_OPT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LOG_TCP_OPT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--log-tcp-options"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mLOG_IP_OPT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LOG_IP_OPT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--log-ip-options"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mULOG_PREFIX(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ULOG_PREFIX; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--ulog-prefix"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mULOG_QTHR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ULOG_QTHR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--ulog-qthreshold"); if ( inputState->guessing==0 ) { #line 1421 "iptables.g" _ttype = UNSUPPORTED_OPTION; #line 2110 "IPTCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mULOG_NLG(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ULOG_NLG; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--ulog-nlgroup"); if ( inputState->guessing==0 ) { #line 1422 "iptables.g" _ttype = UNSUPPORTED_OPTION; #line 2129 "IPTCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mULOG_CPR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = ULOG_CPR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--ulog-cprange"); if ( inputState->guessing==0 ) { #line 1423 "iptables.g" _ttype = UNSUPPORTED_OPTION; #line 2148 "IPTCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mTO_SOURCE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TO_SOURCE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--to-source"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mTO_DESTINATION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TO_DESTINATION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--to-destination"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mTO_PORTS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TO_PORTS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--to-ports"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mTO_NETMAP(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TO_NETMAP; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--to"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCLAMP_MSS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLAMP_MSS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("--clamp-mss-to-pmtu"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_MODULE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_MODULE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-m"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_SRC(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_SRC; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-s"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_DST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_DST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-d"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_IN_INTF(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_IN_INTF; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-i"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_OUT_INTF(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_OUT_INTF; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-o"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_PROTO(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_PROTO; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-p"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_TARGET(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_TARGET; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-j"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPT_FRAGM(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPT_FRAGM; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match("-f"); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mEXCLAMATION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EXCLAMATION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('!' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mNUMBER_SIGN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_SIGN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('#' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mPERCENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PERCENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('%' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mAMPERSAND(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = AMPERSAND; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('&' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mAPOSTROPHE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = APOSTROPHE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\'' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPENING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('(' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCLOSING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(')' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSTAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('*' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mPLUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PLUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('+' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCOMMA(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMA; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(',' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mMINUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MINUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('-' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mDOT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('.' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSLASH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SLASH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('/' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(':' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mSEMICOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SEMICOLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(';' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mLESS_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LESS_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('<' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mEQUALS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EQUALS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('=' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mGREATER_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = GREATER_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('>' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mQUESTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = QUESTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('?' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCOMMERCIAL_AT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMERCIAL_AT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('@' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPENING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('[' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCLOSING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(']' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCARET(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CARET; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('^' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mUNDERLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = UNDERLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('_' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mOPENING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('{' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mCLOSING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('}' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void IPTCfgLexer::mTILDE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TILDE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('~' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } const unsigned long IPTCfgLexer::_tokenSet_0_data_[] = { 4294958072UL, 1UL, 0UL, 2147483648UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x7f 0x80 0x81 // 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f // 0x90 0x91 const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgLexer::_tokenSet_0(_tokenSet_0_data_,16); const unsigned long IPTCfgLexer::_tokenSet_1_data_[] = { 0UL, 67043328UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgLexer::_tokenSet_1(_tokenSet_1_data_,10); const unsigned long IPTCfgLexer::_tokenSet_2_data_[] = { 0UL, 67059712UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // . 0 1 2 3 4 5 6 7 8 9 const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgLexer::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long IPTCfgLexer::_tokenSet_3_data_[] = { 4294967288UL, 4294967291UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 // 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! # $ // % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F // G H I J K L M N O P Q R S T U V W X Y Z [ 0x5c ] ^ _ ` a b c d e f g // h i j k l m n o p q r s t u v w x y z { | } ~ 0x7f 0x80 0x81 0x82 0x83 // 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 const ANTLR_USE_NAMESPACE(antlr)BitSet IPTCfgLexer::_tokenSet_3(_tokenSet_3_data_,16); fwbuilder-5.1.0.3599/src/parsers/IfconfigBSDCfgParser.cpp0000644000175000017500000002170611733011756023630 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20100319): "ifconfig_bsd.g" -> "IfconfigBSDCfgParser.cpp"$ */ #line 43 "ifconfig_bsd.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IfconfigBSDCfgParser.cpp" #include "IfconfigBSDCfgParser.hpp" #include #include #include #line 49 "ifconfig_bsd.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 20 "IfconfigBSDCfgParser.cpp" #line 1 "ifconfig_bsd.g" #line 22 "IfconfigBSDCfgParser.cpp" IfconfigBSDCfgParser::IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,k) { } IfconfigBSDCfgParser::IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,2) { } IfconfigBSDCfgParser::IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,k) { } IfconfigBSDCfgParser::IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,2) { } IfconfigBSDCfgParser::IfconfigBSDCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)LLkParser(state,2) { } void IfconfigBSDCfgParser::cfgfile() { Tracer traceInOut(this, "cfgfile"); try { // for error handling { // ( ... )* for (;;) { switch ( LA(1)) { case LINE_COMMENT: { comment(); break; } case LLADDR: { hwaddr_line(); break; } case INET: { inet_address(); break; } case INET6: { inet6_address(); break; } case GROUPS: { groups(); break; } case NEWLINE: { match(NEWLINE); break; } case DOUBLE_NEWLINE: { match(DOUBLE_NEWLINE); break; } default: if ((LA(1) == WORD) && (LA(2) == COLON)) { interface_line(); } else if (((LA(1) >= PRIORITY && LA(1) <= WORD)) && (_tokenSet_0.member(LA(2)))) { unknown_line(); } else { goto _loop3; } } } _loop3:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void IfconfigBSDCfgParser::comment() { Tracer traceInOut(this, "comment"); try { // for error handling match(LINE_COMMENT); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::interface_line() { Tracer traceInOut(this, "interface_line"); ANTLR_USE_NAMESPACE(antlr)RefToken in = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 165 "ifconfig_bsd.g" InterfaceSpec is; #line 128 "IfconfigBSDCfgParser.cpp" try { // for error handling in = LT(1); match(WORD); match(COLON); match(FLAGS); match(EQUAL); match(INT_CONST); #line 168 "ifconfig_bsd.g" // interface name and status is.name = in->getText(); importer->newInterface(is); consumeUntil(NEWLINE); #line 144 "IfconfigBSDCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::hwaddr_line() { Tracer traceInOut(this, "hwaddr_line"); ANTLR_USE_NAMESPACE(antlr)RefToken addr = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(LLADDR); addr = LT(1); match(MAC_ADDRESS); #line 181 "ifconfig_bsd.g" importer->HwAddressForCurrentInterface(addr->getText()); #line 164 "IfconfigBSDCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::inet_address() { Tracer traceInOut(this, "inet_address"); ANTLR_USE_NAMESPACE(antlr)RefToken addr = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken netm = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken bcast = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 190 "ifconfig_bsd.g" AddressSpec as; #line 179 "IfconfigBSDCfgParser.cpp" try { // for error handling match(INET); addr = LT(1); match(IPV4); match(NETMASK); netm = LT(1); match(HEX_CONST); match(BROADCAST); bcast = LT(1); match(IPV4); #line 193 "ifconfig_bsd.g" as.at = AddressSpec::INTERFACE_CONFIGURATION; as.address = addr->getText(); as.netmask = netm->getText(); as.broadcast = bcast->getText(); importer->inetConfigurationForCurrentInterface(as); #line 199 "IfconfigBSDCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::inet6_address() { Tracer traceInOut(this, "inet6_address"); ANTLR_USE_NAMESPACE(antlr)RefToken addr = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken netm = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 205 "ifconfig_bsd.g" AddressSpec as; #line 213 "IfconfigBSDCfgParser.cpp" try { // for error handling match(INET6); addr = LT(1); match(IPV6); match(PERCENT); match(WORD); match(PREFIXLEN); netm = LT(1); match(INT_CONST); match(SCOPEID); match(HEX_CONST); #line 208 "ifconfig_bsd.g" as.at = AddressSpec::INTERFACE_CONFIGURATION; as.address = addr->getText(); as.netmask = netm->getText(); importer->inet6ConfigurationForCurrentInterface(as); #line 233 "IfconfigBSDCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::groups() { Tracer traceInOut(this, "groups"); try { // for error handling match(GROUPS); match(COLON); groups_list(); match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::unknown_line() { Tracer traceInOut(this, "unknown_line"); try { // for error handling { switch ( LA(1)) { case PRIORITY: { match(PRIORITY); break; } case MEDIA: { match(MEDIA); break; } case STATUS: { match(STATUS); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 152 "ifconfig_bsd.g" consumeUntil(NEWLINE); #line 292 "IfconfigBSDCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigBSDCfgParser::groups_list() { Tracer traceInOut(this, "groups_list"); try { // for error handling match(WORD); #line 224 "ifconfig_bsd.g" importer->addGroupToCurrentInterface(LT(0)->getText()); #line 307 "IfconfigBSDCfgParser.cpp" { // ( ... )* for (;;) { if ((LA(1) == WORD)) { match(WORD); #line 226 "ifconfig_bsd.g" importer->addGroupToCurrentInterface(LT(0)->getText()); #line 314 "IfconfigBSDCfgParser.cpp" } else { goto _loop14; } } _loop14:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_2); } } void IfconfigBSDCfgParser::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* IfconfigBSDCfgParser::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "NEWLINE", "DOUBLE_NEWLINE", "LINE_COMMENT", "\"priority\"", "\"media\"", "\"status\"", "WORD", "COLON", "\"flags\"", "EQUAL", "INT_CONST", "LLADDR", "MAC_ADDRESS", "\"inet\"", "IPV4", "\"netmask\"", "HEX_CONST", "\"broadcast\"", "\"inet6\"", "IPV6", "PERCENT", "\"prefixlen\"", "\"scopeid\"", "\"groups\"", "\"Link\"", "\"Global\"", "\"Host\"", "\"addr\"", "\"Bcast\"", "\"P-t-P\"", "\"Mask\"", "\"Scope\"", "\"mtu\"", "\"encap\"", "\"Loopback\"", "\"UP\"", "\"BROADCAST\"", "\"POINTOPOINT\"", "\"LOOPBACK\"", "\"NOARP\"", "\"RUNNING\"", "\"RX\"", "\"TX\"", "\"collisions\"", "\"Interrupt\"", "\"HWaddr\"", "\"lladdr\"", "Whitespace", "NUMBER", "NEG_INT_CONST", "HEX_DIGIT", "DIGIT", "NUM_3DIGIT", "NUM_HEX_4DIGIT", "NUMBER_ADDRESS_OR_WORD", "AMPERSAND", "STAR", "MINUS", "DOT", "SLASH", "QUESTION", "OPENING_PAREN", "CLOSING_PAREN", "OPENING_SQUARE", "CLOSING_SQUARE", "OPENING_BRACE", "CLOSING_BRACE", "LESS_THAN", "GREATER_THAN", 0 }; const unsigned long IfconfigBSDCfgParser::_tokenSet_0_data_[] = { 138577906UL, 0UL, 0UL, 0UL }; // EOF NEWLINE DOUBLE_NEWLINE LINE_COMMENT "priority" "media" "status" // WORD LLADDR "inet" "inet6" "groups" const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgParser::_tokenSet_0(_tokenSet_0_data_,4); const unsigned long IfconfigBSDCfgParser::_tokenSet_1_data_[] = { 2UL, 0UL, 0UL, 0UL }; // EOF const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgParser::_tokenSet_1(_tokenSet_1_data_,4); const unsigned long IfconfigBSDCfgParser::_tokenSet_2_data_[] = { 16UL, 0UL, 0UL, 0UL }; // NEWLINE const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigBSDCfgParser::_tokenSet_2(_tokenSet_2_data_,4); fwbuilder-5.1.0.3599/src/parsers/PIXCfgParser.cpp0000644000175000017500000046710211733011756022217 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20090306): "pix.g" -> "PIXCfgParser.cpp"$ */ #line 42 "pix.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "PIXCfgParser.cpp" #include "PIXCfgParser.hpp" #include #include #include #line 48 "pix.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 20 "PIXCfgParser.cpp" #line 1 "pix.g" #line 22 "PIXCfgParser.cpp" PIXCfgParser::PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,k) { } PIXCfgParser::PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,2) { } PIXCfgParser::PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,k) { } PIXCfgParser::PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,2) { } PIXCfgParser::PIXCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)LLkParser(state,2) { } void PIXCfgParser::cfgfile() { try { // for error handling { // ( ... )+ int _cnt3=0; for (;;) { switch ( LA(1)) { case LINE_COMMENT: case COLON_COMMENT: { comment(); break; } case PIX_WORD: case ASA_WORD: case FWSM_WORD: { version(); break; } case HOSTNAME: { hostname(); break; } case INTRFACE: { intrface(); break; } case NAMEIF: { nameif_top_level(); break; } case CONTROLLER: { controller(); break; } case ACCESS_LIST: { access_list_commands(); break; } case SSH: { ssh_command(); break; } case TELNET: { telnet_command(); break; } case HTTP: { http_command(); break; } case ICMP: { icmp_top_level_command(); break; } case NAT: { nat_top_level_command(); break; } case GLOBAL: { global_top_level_command(); break; } case STATIC: { static_top_level_command(); break; } case ACCESS_GROUP: { access_group(); break; } case EXIT: { exit(); break; } case CERTIFICATE: { certificate(); break; } case QUIT: { quit(); break; } case NAMES: { names_section(); break; } case NAME: { name_entry(); break; } case CRYPTO: { crypto(); break; } case NO: { no_commands(); break; } case TIMEOUT: { timeout_command(); break; } case DNS: { dns_command(); break; } case SERVICE: { service_top_level_command(); break; } case PIM: { pim_top_level_command(); break; } case NETWORK: { network_top_level_command(); break; } case WORD: { unknown_command(); break; } case NEWLINE: { match(NEWLINE); break; } default: if ((LA(1) == IP) && (LA(2) == COMMUNITY_LIST)) { community_list_command(); } else if ((LA(1) == IP) && (LA(2) == WORD)) { unknown_ip_command(); } else if ((LA(1) == IP) && (LA(2) == ADDRESS)) { intf_address(); } else if ((LA(1) == OBJECT) && (LA(2) == NETWORK)) { named_object_network(); } else if ((LA(1) == OBJECT) && (LA(2) == SERVICE)) { named_object_service(); } else if ((LA(1) == OBJECT_GROUP) && (LA(2) == NETWORK)) { object_group_network(); } else if ((LA(1) == OBJECT_GROUP) && (LA(2) == SERVICE)) { object_group_service(); } else if ((LA(1) == OBJECT_GROUP) && (LA(2) == PROTOCOL)) { object_group_protocol(); } else if ((LA(1) == OBJECT_GROUP) && (LA(2) == ICMP_OBJECT)) { object_group_icmp_8_0(); } else if ((LA(1) == OBJECT_GROUP) && (LA(2) == ICMP_TYPE)) { object_group_icmp_8_3(); } else { if ( _cnt3>=1 ) { goto _loop3; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());} } } _cnt3++; } _loop3:; } // ( ... )+ } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_0); } else { throw; } } } void PIXCfgParser::comment() { try { // for error handling { switch ( LA(1)) { case LINE_COMMENT: { match(LINE_COMMENT); break; } case COLON_COMMENT: { match(COLON_COMMENT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::version() { #line 874 "pix.g" std::string platform; #line 288 "PIXCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case PIX_WORD: { match(PIX_WORD); break; } case ASA_WORD: { match(ASA_WORD); break; } case FWSM_WORD: { match(FWSM_WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 878 "pix.g" platform = LT(0)->getText(); #line 319 "PIXCfgParser.cpp" } match(VERSION_WORD_CAP); match(NUMBER); if ( inputState->guessing==0 ) { #line 882 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->setDiscoveredPlatform(platform); importer->setDiscoveredVersion(LT(0)->getText()); *dbg << "VERSION " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); #line 332 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::hostname() { try { // for error handling match(HOSTNAME); { switch ( LA(1)) { case STRING: { match(STRING); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 893 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); // we get host name in the import wizard //importer->setHostName( LT(0)->getText() ); *dbg << "HOSTNAME " << "LT0=" << LT(0)->getText() << std::endl; #line 375 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::community_list_command() { try { // for error handling match(IP); match(COMMUNITY_LIST); if ( inputState->guessing==0 ) { #line 203 "pix.g" consumeUntil(NEWLINE); #line 398 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::unknown_ip_command() { try { // for error handling match(IP); match(WORD); if ( inputState->guessing==0 ) { #line 814 "pix.g" consumeUntil(NEWLINE); #line 421 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::intrface() { try { // for error handling match(INTRFACE); { if ((LA(1) == WORD) && (_tokenSet_2.member(LA(2)))) { interface_command_6(); } else if ((LA(1) == WORD) && (LA(2) == NEWLINE)) { interface_command_7(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::nameif_top_level() { #line 1474 "pix.g" std::string intf_name, intf_label, sec_level; #line 466 "PIXCfgParser.cpp" try { // for error handling match(NAMEIF); match(WORD); if ( inputState->guessing==0 ) { #line 1479 "pix.g" intf_name = LT(0)->getText(); #line 474 "PIXCfgParser.cpp" } interface_label(); if ( inputState->guessing==0 ) { #line 1480 "pix.g" intf_label = LT(0)->getText(); #line 480 "PIXCfgParser.cpp" } match(WORD); if ( inputState->guessing==0 ) { #line 1481 "pix.g" sec_level = LT(0)->getText(); #line 486 "PIXCfgParser.cpp" } if ( inputState->guessing==0 ) { #line 1482 "pix.g" importer->setInterfaceParametes(intf_name, intf_label, sec_level); *dbg << " NAMEIF: " << intf_name << " " << intf_label << " " << sec_level << std::endl; #line 497 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::intf_address() { try { // for error handling match(IP); match(ADDRESS); { switch ( LA(1)) { case WORD: case OUTSIDE: { v6_ip_address(); break; } case IPV4: case DHCP: { v7_ip_address(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::controller() { try { // for error handling match(CONTROLLER); if ( inputState->guessing==0 ) { #line 1386 "pix.g" importer->clearCurrentInterface(); consumeUntil(NEWLINE); #line 556 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::access_list_commands() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ACCESS_LIST); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 904 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet( name->getText(), libfwbuilder::Policy::TYPENAME ); *dbg << name->getLine() << ":" << " ACL ext " << name->getText() << std::endl; #line 586 "PIXCfgParser.cpp" } { switch ( LA(1)) { case LINE_COMMENT: case COLON_COMMENT: { comment(); break; } case REMARK: { remark(); break; } case NEWLINE: { match(NEWLINE); break; } default: if ((LA(1) == EXTENDED || LA(1) == PERMIT) && (_tokenSet_3.member(LA(2)))) { permit_extended(); } else if ((LA(1) == EXTENDED || LA(1) == DENY) && (_tokenSet_4.member(LA(2)))) { deny_extended(); } else if ((LA(1) == STANDARD) && (LA(2) == PERMIT)) { permit_standard(); } else if ((LA(1) == STANDARD) && (LA(2) == DENY)) { deny_standard(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 927 "pix.g" *dbg << LT(0)->getLine() << ":" << " ACL line end" << std::endl << std::endl; #line 630 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::ssh_command() { try { // for error handling match(SSH); if ( inputState->guessing==0 ) { #line 1732 "pix.g" importer->clear(); #line 652 "PIXCfgParser.cpp" } { switch ( LA(1)) { case TIMEOUT: { { match(TIMEOUT); match(INT_CONST); } if ( inputState->guessing==0 ) { #line 1737 "pix.g" // set ssh timeout here #line 667 "PIXCfgParser.cpp" } break; } case SCOPY: { match(SCOPY); break; } case VERSION_WORD_LOW: { match(VERSION_WORD_LOW); match(INT_CONST); break; } case IPV4: case OBJECT: case HOST: case OBJECT_GROUP: case INTRFACE: case ANY: { { hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1747 "pix.g" importer->SaveTmpAddrToSrc(); #line 696 "PIXCfgParser.cpp" } interface_label(); } if ( inputState->guessing==0 ) { #line 1752 "pix.g" std::string intf_label = LT(0)->getText(); std::string acl_name = "ssh_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); importer->action = "permit"; importer->setDstSelf(); importer->protocol = "tcp"; importer->dst_port_op = "eq"; importer->dst_port_spec = "ssh"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); *dbg << std::endl; #line 718 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::telnet_command() { try { // for error handling match(TELNET); if ( inputState->guessing==0 ) { #line 1772 "pix.g" importer->clear(); #line 748 "PIXCfgParser.cpp" } { switch ( LA(1)) { case TIMEOUT: { { match(TIMEOUT); match(INT_CONST); } break; } case IPV4: case OBJECT: case HOST: case OBJECT_GROUP: case INTRFACE: case ANY: { { hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1779 "pix.g" importer->SaveTmpAddrToSrc(); #line 774 "PIXCfgParser.cpp" } interface_label(); } if ( inputState->guessing==0 ) { #line 1784 "pix.g" std::string intf_label = LT(0)->getText(); std::string acl_name = "telnet_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); importer->action = "permit"; importer->setDstSelf(); importer->protocol = "tcp"; importer->dst_port_op = "eq"; importer->dst_port_spec = "telnet"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); *dbg << std::endl; #line 796 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::http_command() { try { // for error handling match(HTTP); if ( inputState->guessing==0 ) { #line 1806 "pix.g" importer->clear(); #line 826 "PIXCfgParser.cpp" } { switch ( LA(1)) { case REDIRECT: case AUTHENTICATION_CERTIFICATE: case SERVER: { { switch ( LA(1)) { case AUTHENTICATION_CERTIFICATE: { match(AUTHENTICATION_CERTIFICATE); break; } case REDIRECT: { match(REDIRECT); break; } case SERVER: { match(SERVER); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1811 "pix.g" consumeUntil(NEWLINE); #line 862 "PIXCfgParser.cpp" } break; } case IPV4: case OBJECT: case HOST: case OBJECT_GROUP: case INTRFACE: case ANY: { { hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1817 "pix.g" importer->SaveTmpAddrToSrc(); #line 880 "PIXCfgParser.cpp" } interface_label(); } if ( inputState->guessing==0 ) { #line 1822 "pix.g" std::string intf_label = LT(0)->getText(); std::string acl_name = "http_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); importer->action = "permit"; importer->setDstSelf(); importer->protocol = "tcp"; importer->dst_port_op = "eq"; importer->dst_port_spec = "www"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); *dbg << std::endl; #line 903 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::icmp_top_level_command() { ANTLR_USE_NAMESPACE(antlr)RefToken permit = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken deny = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ICMP); { switch ( LA(1)) { case UNREACHABLE: { { match(UNREACHABLE); if ( inputState->guessing==0 ) { #line 1852 "pix.g" consumeUntil(NEWLINE); #line 941 "PIXCfgParser.cpp" } } break; } case PERMIT: case DENY: { { { switch ( LA(1)) { case PERMIT: { permit = LT(1); match(PERMIT); break; } case DENY: { deny = LT(1); match(DENY); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1859 "pix.g" importer->clear(); #line 975 "PIXCfgParser.cpp" } hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1863 "pix.g" importer->SaveTmpAddrToSrc(); #line 983 "PIXCfgParser.cpp" } { switch ( LA(1)) { case INT_CONST: case ECHO: case ECHO_REPLY: case TIME_EXCEEDED: case UNREACHABLE: { icmp_types_for_icmp_command(); break; } case WORD: case OUTSIDE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } interface_label(); if ( inputState->guessing==0 ) { #line 1868 "pix.g" std::string intf_label = LT(0)->getText(); std::string acl_name = "icmp_commands_" + intf_label; importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet(acl_name, libfwbuilder::Policy::TYPENAME ); importer->newPolicyRule(); if (permit) importer->action = "permit"; if (deny) importer->action = "deny"; importer->setDstSelf(); importer->protocol = "icmp"; importer->setInterfaceAndDirectionForRuleSet( acl_name, intf_label, "in" ); importer->pushRule(); #line 1024 "PIXCfgParser.cpp" } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::nat_top_level_command() { try { // for error handling match(NAT); match(OPENING_PAREN); if ( inputState->guessing==0 ) { #line 1954 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 1057 "PIXCfgParser.cpp" } { if ((LA(1) == WORD || LA(1) == OUTSIDE) && (LA(2) == CLOSING_PAREN)) { nat_old_top_level_command(); } else if ((LA(1) == WORD || LA(1) == OUTSIDE) && (LA(2) == COMMA)) { nat_new_top_level_command(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void PIXCfgParser::global_top_level_command() { ANTLR_USE_NAMESPACE(antlr)RefToken num = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(GLOBAL); match(OPENING_PAREN); if ( inputState->guessing==0 ) { #line 2075 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 1094 "PIXCfgParser.cpp" } interface_label(); if ( inputState->guessing==0 ) { #line 2080 "pix.g" importer->tmp_global_pool.pool_interface = LT(0)->getText(); #line 1102 "PIXCfgParser.cpp" } match(CLOSING_PAREN); num = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 2085 "pix.g" importer->tmp_global_pool.str_num = num->getText(); importer->tmp_global_pool.netmask = "255.255.255.255"; *dbg << " GLOBAL POOL " << importer->tmp_global_pool.str_num << " " << importer->tmp_global_pool.pool_interface; #line 1117 "PIXCfgParser.cpp" } { switch ( LA(1)) { case INTRFACE: { match(INTRFACE); if ( inputState->guessing==0 ) { #line 2098 "pix.g" importer->tmp_global_pool.start = LT(0)->getText(); importer->tmp_global_pool.end = LT(0)->getText(); #line 1130 "PIXCfgParser.cpp" } break; } case IPV4: case IPV6: { single_addr(); if ( inputState->guessing==0 ) { #line 2104 "pix.g" importer->tmp_global_pool.start = importer->tmp_a; importer->tmp_global_pool.end = importer->tmp_a; #line 1144 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case MINUS: { match(MINUS); single_addr(); if ( inputState->guessing==0 ) { #line 2113 "pix.g" importer->tmp_global_pool.end = importer->tmp_a; #line 1165 "PIXCfgParser.cpp" } break; } case NEWLINE: case NETMASK: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case NETMASK: { match(NETMASK); match(IPV4); if ( inputState->guessing==0 ) { #line 2122 "pix.g" importer->tmp_global_pool.netmask = LT(0)->getText(); #line 1191 "PIXCfgParser.cpp" } break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); if ( inputState->guessing==0 ) { #line 2128 "pix.g" importer->addGlobalPool(); *dbg << " " << importer->tmp_global_pool.start << " " << importer->tmp_global_pool.end << " " << importer->tmp_global_pool.netmask << std::endl; #line 1215 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::static_top_level_command() { try { // for error handling match(STATIC); match(OPENING_PAREN); if ( inputState->guessing==0 ) { #line 2140 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 1239 "PIXCfgParser.cpp" } interface_label(); if ( inputState->guessing==0 ) { #line 2144 "pix.g" importer->prenat_interface = LT(0)->getText(); #line 1245 "PIXCfgParser.cpp" } match(COMMA); interface_label(); if ( inputState->guessing==0 ) { #line 2146 "pix.g" importer->postnat_interface = LT(0)->getText(); #line 1252 "PIXCfgParser.cpp" } match(CLOSING_PAREN); if ( inputState->guessing==0 ) { #line 2148 "pix.g" importer->newUnidirRuleSet("nat", libfwbuilder::NAT::TYPENAME ); *dbg << " DNAT rule "; importer->rule_type = libfwbuilder::NATRule::DNAT; #line 1262 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IPV4: case IPV6: case INTRFACE: { static_starts_with_hostaddr(); break; } case TCP: case UDP: { static_starts_with_tcp_udp(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); if ( inputState->guessing==0 ) { #line 2163 "pix.g" importer->pushNATRule(); *dbg << std::endl; #line 1292 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::access_group() { ANTLR_USE_NAMESPACE(antlr)RefToken aclname = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken dir = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ACCESS_GROUP); aclname = LT(1); match(WORD); dir = LT(1); match(WORD); match(INTRFACE); interface_label(); if ( inputState->guessing==0 ) { #line 1927 "pix.g" std::string intf_label = LT(0)->getText(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( aclname->getText(), intf_label, dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << aclname->getText() << "'" << " " << intf_label << " " << dir->getText() << std::endl; #line 1331 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::exit() { try { // for error handling match(EXIT); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::certificate() { try { // for error handling match(CERTIFICATE); match(WORD); if ( inputState->guessing==0 ) { #line 867 "pix.g" consumeUntil(NEWLINE); consumeUntil(QUIT); #line 1370 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::quit() { try { // for error handling match(QUIT); if ( inputState->guessing==0 ) { #line 196 "pix.g" consumeUntil(NEWLINE); #line 1392 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::names_section() { try { // for error handling match(NAMES); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::name_entry() { try { // for error handling match(NAME); { switch ( LA(1)) { case IPV4: { name_entry_ipv4(); break; } case IPV6: { name_entry_ipv6(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::named_object_network() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OBJECT); match(NETWORK); name = LT(1); match(WORD); match(NEWLINE); if ( inputState->guessing==0 ) { #line 258 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNamedObjectAddress(name->getText()); *dbg << name->getLine() << ":" << " Named Object " << name->getText() << std::endl; #line 1471 "PIXCfgParser.cpp" } { // ( ... )* for (;;) { switch ( LA(1)) { case DESCRIPTION: { named_object_description(); break; } case HOST: case RANGE: case SUBNET: { named_object_network_parameters(); break; } default: if ((LA(1) == NAT) && (LA(2) == OPENING_PAREN)) { named_object_nat(); } else { goto _loop18; } } } _loop18:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::named_object_service() { try { // for error handling match(OBJECT); match(SERVICE); if ( inputState->guessing==0 ) { #line 371 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 1521 "PIXCfgParser.cpp" } { switch ( LA(1)) { case WORD: { match(WORD); break; } case HTTP: { match(HTTP); break; } case SSH: { match(SSH); break; } case TELNET: { match(TELNET); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 376 "pix.g" importer->newNamedObjectService(LT(0)->getText()); *dbg << " NAMED OBJECT " << LT(0)->getText() << std::endl; #line 1557 "PIXCfgParser.cpp" } match(NEWLINE); { // ( ... )* for (;;) { if ((LA(1) == DESCRIPTION)) { named_object_description(); } else if ((LA(1) == SERVICE) && (_tokenSet_6.member(LA(2)))) { named_object_service_parameters(); } else { goto _loop35; } } _loop35:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::object_group_network() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OBJECT_GROUP); match(NETWORK); name = LT(1); match(WORD); match(NEWLINE); if ( inputState->guessing==0 ) { #line 491 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupNetwork(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; #line 1604 "PIXCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == DESCRIPTION || LA(1) == GROUP_OBJECT || LA(1) == NETWORK_OBJECT)) { object_group_network_parameters(); } else { goto _loop54; } } _loop54:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::object_group_service() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken tcp = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken udp = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken tcpudp = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OBJECT_GROUP); match(SERVICE); name = LT(1); match(WORD); { switch ( LA(1)) { case TCP: { tcp = LT(1); match(TCP); break; } case UDP: { udp = LT(1); match(UDP); break; } case TCP_UDP: { tcpudp = LT(1); match(TCP_UDP); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); if ( inputState->guessing==0 ) { #line 713 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupService(name->getText()); if (tcp) importer->setObjectGroupServiceProtocol("tcp"); if (udp) importer->setObjectGroupServiceProtocol("udp"); if (tcpudp) importer->setObjectGroupServiceProtocol("tcp-udp"); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; #line 1683 "PIXCfgParser.cpp" } { // ( ... )* for (;;) { if ((_tokenSet_7.member(LA(1)))) { object_group_service_parameters(); } else { goto _loop86; } } _loop86:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::object_group_protocol() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OBJECT_GROUP); match(PROTOCOL); name = LT(1); match(WORD); match(NEWLINE); if ( inputState->guessing==0 ) { #line 589 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupProtocol(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; #line 1726 "PIXCfgParser.cpp" } { // ( ... )+ int _cnt66=0; for (;;) { if ((LA(1) == DESCRIPTION || LA(1) == GROUP_OBJECT || LA(1) == PROTOCOL_OBJECT)) { object_group_protocol_parameters(); } else { if ( _cnt66>=1 ) { goto _loop66; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename());} } _cnt66++; } _loop66:; } // ( ... )+ } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::object_group_icmp_8_0() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OBJECT_GROUP); match(ICMP_OBJECT); name = LT(1); match(WORD); match(NEWLINE); if ( inputState->guessing==0 ) { #line 644 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupICMP(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; #line 1771 "PIXCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == DESCRIPTION || LA(1) == GROUP_OBJECT || LA(1) == ICMP_OBJECT)) { object_group_icmp_parameters(); } else { goto _loop74; } } _loop74:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::object_group_icmp_8_3() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(OBJECT_GROUP); match(ICMP_TYPE); name = LT(1); match(WORD); match(NEWLINE); if ( inputState->guessing==0 ) { #line 657 "pix.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupICMP(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; #line 1814 "PIXCfgParser.cpp" } { // ( ... )* for (;;) { if ((LA(1) == DESCRIPTION || LA(1) == GROUP_OBJECT || LA(1) == ICMP_OBJECT)) { object_group_icmp_parameters(); } else { goto _loop77; } } _loop77:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::crypto() { try { // for error handling match(CRYPTO); if ( inputState->guessing==0 ) { #line 807 "pix.g" consumeUntil(NEWLINE); #line 1848 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::no_commands() { try { // for error handling match(NO); if ( inputState->guessing==0 ) { #line 858 "pix.g" *dbg << " TOP LEVEL \"NO\" COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); #line 1872 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::timeout_command() { try { // for error handling match(TIMEOUT); if ( inputState->guessing==0 ) { #line 210 "pix.g" consumeUntil(NEWLINE); #line 1894 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::dns_command() { try { // for error handling match(DNS); if ( inputState->guessing==0 ) { #line 828 "pix.g" consumeUntil(NEWLINE); #line 1916 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::service_top_level_command() { try { // for error handling match(SERVICE); { switch ( LA(1)) { case CALL_HOME: { match(CALL_HOME); break; } case INTERNAL: { match(INTERNAL); break; } case PASSWORD_RECOVERY: { match(PASSWORD_RECOVERY); break; } case RESETINBOUND: { match(RESETINBOUND); break; } case RESETOUTBOUND: { match(RESETOUTBOUND); break; } case RESETOUTSIDE: { match(RESETOUTSIDE); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 851 "pix.g" consumeUntil(NEWLINE); #line 1976 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::pim_top_level_command() { try { // for error handling match(PIM); if ( inputState->guessing==0 ) { #line 218 "pix.g" consumeUntil(NEWLINE); #line 1998 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::network_top_level_command() { try { // for error handling match(NETWORK); if ( inputState->guessing==0 ) { #line 226 "pix.g" consumeUntil(NEWLINE); #line 2020 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::unknown_command() { try { // for error handling match(WORD); if ( inputState->guessing==0 ) { #line 821 "pix.g" consumeUntil(NEWLINE); #line 2042 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::name_entry_ipv4() { try { // for error handling match(IPV4); match(WORD); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::name_entry_ipv6() { try { // for error handling match(IPV6); match(WORD); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::ip_protocol_names() { try { // for error handling { switch ( LA(1)) { case AH: { match(AH); break; } case EIGRP: { match(EIGRP); break; } case ESP_WORD: { match(ESP_WORD); break; } case GRE: { match(GRE); break; } case IGMP: { match(IGMP); break; } case IGRP: { match(IGRP); break; } case IP: { match(IP); break; } case IPINIP: { match(IPINIP); break; } case IPSEC: { match(IPSEC); break; } case NOS: { match(NOS); break; } case OSPF: { match(OSPF); break; } case PCP: { match(PCP); break; } case PIM: { match(PIM); break; } case PPTP: { match(PPTP); break; } case SNP: { match(SNP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_8); } else { throw; } } } void PIXCfgParser::named_object_nat() { try { // for error handling nat_top_level_command(); if ( inputState->guessing==0 ) { #line 286 "pix.g" *dbg << "Named object with singleton nat command" << std::endl; importer->addMessageToLog( QString("Warning: " "Import of named objects with \"nat\" command " "is not supported at this time")); consumeUntil(NEWLINE); #line 2198 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void PIXCfgParser::named_object_description() { try { // for error handling match(DESCRIPTION); if ( inputState->guessing==0 ) { #line 297 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setNamedObjectDescription(descr); *dbg << " DESCRIPTION " << descr << std::endl; #line 2229 "PIXCfgParser.cpp" } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void PIXCfgParser::named_object_network_parameters() { try { // for error handling { switch ( LA(1)) { case HOST: { host_addr(); break; } case RANGE: { range_addr(); break; } case SUBNET: { subnet_addr(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void PIXCfgParser::host_addr() { try { // for error handling match(HOST); single_addr(); if ( inputState->guessing==0 ) { #line 313 "pix.g" importer->commitNamedAddressObject(); #line 2291 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::range_addr() { ANTLR_USE_NAMESPACE(antlr)RefToken r1 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken r2 = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { match(RANGE); r1 = LT(1); match(IPV4); r2 = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 337 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->tmp_range_1 = r1->getText(); importer->tmp_range_2 = r2->getText(); importer->commitNamedAddressRangeObject(); *dbg << r1->getText() << "/" << r2->getText(); #line 2325 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::subnet_addr() { ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken nm = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken v6 = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { match(SUBNET); { switch ( LA(1)) { case IPV4: { { a = LT(1); match(IPV4); nm = LT(1); match(IPV4); } break; } case IPV6: { v6 = LT(1); match(IPV6); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } if ( inputState->guessing==0 ) { #line 347 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); if (a) { importer->tmp_a = a->getText(); importer->tmp_nm = nm->getText(); importer->commitNamedAddressObject(); *dbg << a->getText() << "/" << nm->getText(); } if (v6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } #line 2389 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::single_addr() { ANTLR_USE_NAMESPACE(antlr)RefToken h = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken v6 = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case IPV4: { h = LT(1); match(IPV4); break; } case IPV6: { v6 = LT(1); match(IPV6); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 319 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); if (h) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; *dbg << importer->tmp_a << " "; } if (v6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } #line 2444 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_10); } else { throw; } } } void PIXCfgParser::named_object_service_parameters() { try { // for error handling { if ((LA(1) == SERVICE) && (LA(2) == ICMP)) { service_icmp(); } else if ((LA(1) == SERVICE) && (LA(2) == ICMP6)) { service_icmp6(); } else if ((LA(1) == SERVICE) && (LA(2) == TCP || LA(2) == UDP)) { service_tcp_udp(); } else if ((LA(1) == SERVICE) && (_tokenSet_11.member(LA(2)))) { service_other(); } else if ((LA(1) == SERVICE) && (LA(2) == WORD)) { service_unknown(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_12); } else { throw; } } } void PIXCfgParser::service_icmp() { ANTLR_USE_NAMESPACE(antlr)RefToken icmp_type = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(SERVICE); match(ICMP); { switch ( LA(1)) { case INT_CONST: { icmp_type = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 406 "pix.g" importer->icmp_type = LT(0)->getText(); #line 2510 "PIXCfgParser.cpp" } break; } case ECHO: case ALTERNATE_ADDRESS: case CONVERSION_ERROR: case ECHO_REPLY: case INFORMATION_REPLY: case INFORMATION_REQUEST: case MASK_REPLY: case MASK_REQUEST: case MOBILE_REDIRECT: case PARAMETER_PROBLEM: case REDIRECT: case ROUTER_ADVERTISEMENT: case ROUTER_SOLICITATION: case SOURCE_QUENCH: case TIME_EXCEEDED: case TIMESTAMP_REPLY: case TIMESTAMP_REQUEST: case TRACEROUTE: case UNREACHABLE: { icmp_names(); if ( inputState->guessing==0 ) { #line 411 "pix.g" importer->icmp_spec = LT(0)->getText(); #line 2540 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 415 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->commitNamedICMPServiceObject(); *dbg << "NAMED OBJECT SERVICE ICMP " << LT(0)->getText() << " "; #line 2557 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::service_icmp6() { try { // for error handling match(SERVICE); match(ICMP6); { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 423 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Warning: " "Import of IPv6 addresses and servcies " "is not supported at this time")); *dbg << "NAMED OBJECT SERVICE ICMP6 " << LT(0)->getText() << " "; consumeUntil(NEWLINE); #line 2604 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::service_tcp_udp() { try { // for error handling match(SERVICE); { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 435 "pix.g" importer->protocol = LT(0)->getText(); *dbg << "NAMED OBJECT SERVICE " << LT(0)->getText() << " "; #line 2645 "PIXCfgParser.cpp" } { switch ( LA(1)) { case SOURCE: { src_port_spec(); break; } case NEWLINE: case RANGE: case DESTINATION: case P_EQ: case P_GT: case P_LT: case P_NEQ: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case RANGE: case DESTINATION: case P_EQ: case P_GT: case P_LT: case P_NEQ: { dst_port_spec(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 441 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->commitNamedTCPUDPServiceObject(); #line 2698 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::service_other() { try { // for error handling match(SERVICE); { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: { ip_protocol_names(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 460 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->commitNamedIPServiceObject(); *dbg << "NAMED OBJECT SERVICE " << LT(0)->getText() << " "; #line 2755 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::service_unknown() { try { // for error handling match(SERVICE); match(WORD); if ( inputState->guessing==0 ) { #line 475 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = "ip"; importer->commitNamedIPServiceObject(); std::string err = "Warning: Unknown service name " + LT(0)->getText(); importer->setNamedObjectDescription(err); importer->addMessageToLog(err); *dbg << "UNKNOWN SERVICE " << LT(0)->getText() << " "; #line 2785 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::icmp_names() { try { // for error handling { switch ( LA(1)) { case ALTERNATE_ADDRESS: { match(ALTERNATE_ADDRESS); break; } case CONVERSION_ERROR: { match(CONVERSION_ERROR); break; } case ECHO: { match(ECHO); break; } case ECHO_REPLY: { match(ECHO_REPLY); break; } case INFORMATION_REPLY: { match(INFORMATION_REPLY); break; } case INFORMATION_REQUEST: { match(INFORMATION_REQUEST); break; } case MASK_REPLY: { match(MASK_REPLY); break; } case MASK_REQUEST: { match(MASK_REQUEST); break; } case MOBILE_REDIRECT: { match(MOBILE_REDIRECT); break; } case PARAMETER_PROBLEM: { match(PARAMETER_PROBLEM); break; } case REDIRECT: { match(REDIRECT); break; } case ROUTER_ADVERTISEMENT: { match(ROUTER_ADVERTISEMENT); break; } case ROUTER_SOLICITATION: { match(ROUTER_SOLICITATION); break; } case SOURCE_QUENCH: { match(SOURCE_QUENCH); break; } case TIME_EXCEEDED: { match(TIME_EXCEEDED); break; } case TIMESTAMP_REPLY: { match(TIMESTAMP_REPLY); break; } case TIMESTAMP_REQUEST: { match(TIMESTAMP_REQUEST); break; } case TRACEROUTE: { match(TRACEROUTE); break; } case UNREACHABLE: { match(UNREACHABLE); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_13); } else { throw; } } } void PIXCfgParser::src_port_spec() { try { // for error handling match(SOURCE); xoperator(); if ( inputState->guessing==0 ) { #line 448 "pix.g" importer->SaveTmpPortToSrc(); #line 2925 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_14); } else { throw; } } } void PIXCfgParser::dst_port_spec() { try { // for error handling { switch ( LA(1)) { case DESTINATION: { match(DESTINATION); break; } case RANGE: case P_EQ: case P_GT: case P_LT: case P_NEQ: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } xoperator(); if ( inputState->guessing==0 ) { #line 454 "pix.g" importer->SaveTmpPortToDst(); #line 2968 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::xoperator() { #line 1162 "pix.g" importer->tmp_port_spec = ""; #line 2984 "PIXCfgParser.cpp" try { // for error handling switch ( LA(1)) { case P_EQ: case P_GT: case P_LT: case P_NEQ: { single_port_op(); break; } case RANGE: { port_range(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_15); } else { throw; } } } void PIXCfgParser::object_group_network_parameters() { try { // for error handling { switch ( LA(1)) { case DESCRIPTION: { object_group_description(); break; } case GROUP_OBJECT: { group_object(); break; } case NETWORK_OBJECT: { network_object(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_16); } else { throw; } } } void PIXCfgParser::object_group_description() { try { // for error handling match(DESCRIPTION); if ( inputState->guessing==0 ) { #line 515 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setObjectGroupDescription(descr); *dbg << " DESCRIPTION " << descr << std::endl; #line 3073 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::group_object() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(GROUP_OBJECT); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 530 "pix.g" importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; #line 3101 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::network_object() { ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken nm = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken v6 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken h = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken hv6 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(NETWORK_OBJECT); if ( inputState->guessing==0 ) { #line 539 "pix.g" importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 3130 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IPV4: case IPV6: { { switch ( LA(1)) { case IPV4: { { a = LT(1); match(IPV4); nm = LT(1); match(IPV4); } break; } case IPV6: { v6 = LT(1); match(IPV6); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 545 "pix.g" if (a) { importer->tmp_a = a->getText(); importer->tmp_nm = nm->getText(); importer->addNetworkToObjectGroup(); *dbg << a->getText() << "/" << nm->getText(); } if (v6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } #line 3178 "PIXCfgParser.cpp" } break; } case HOST: { match(HOST); { switch ( LA(1)) { case IPV4: { h = LT(1); match(IPV4); break; } case IPV6: { hv6 = LT(1); match(IPV6); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 562 "pix.g" if (h) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; importer->addNetworkToObjectGroup(); *dbg << h->getText() << "/255.255.255.255"; } if (hv6) { importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); } #line 3222 "PIXCfgParser.cpp" } break; } case OBJECT: { match(OBJECT); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 579 "pix.g" importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; #line 3237 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::object_group_protocol_parameters() { try { // for error handling { switch ( LA(1)) { case DESCRIPTION: { object_group_description(); break; } case GROUP_OBJECT: { group_object(); break; } case PROTOCOL_OBJECT: { protocol_object(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_17); } else { throw; } } } void PIXCfgParser::protocol_object() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(PROTOCOL_OBJECT); if ( inputState->guessing==0 ) { #line 613 "pix.g" importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 3307 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: case ICMP: case INT_CONST: case TCP: case UDP: { { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case ICMP: { match(ICMP); break; } case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: { ip_protocol_names(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 619 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->addIPServiceToObjectGroup(); *dbg << " GROUP MEMBER " << LT(0)->getText() << " "; #line 3386 "PIXCfgParser.cpp" } break; } case ICMP6: { match(ICMP6); if ( inputState->guessing==0 ) { #line 627 "pix.g" importer->addMessageToLog( QString("Warning: IPv6 import is not supported. ")); consumeUntil(NEWLINE); #line 3400 "PIXCfgParser.cpp" } break; } case OBJECT: { match(OBJECT); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 634 "pix.g" importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; #line 3415 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::object_group_icmp_parameters() { try { // for error handling { switch ( LA(1)) { case DESCRIPTION: { object_group_description(); break; } case GROUP_OBJECT: { group_object(); break; } case ICMP_OBJECT: { icmp_object(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_18); } else { throw; } } } void PIXCfgParser::icmp_object() { ANTLR_USE_NAMESPACE(antlr)RefToken icmp_type = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(ICMP_OBJECT); if ( inputState->guessing==0 ) { #line 681 "pix.g" importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 3486 "PIXCfgParser.cpp" } { switch ( LA(1)) { case INT_CONST: case ECHO: case ALTERNATE_ADDRESS: case CONVERSION_ERROR: case ECHO_REPLY: case INFORMATION_REPLY: case INFORMATION_REQUEST: case MASK_REPLY: case MASK_REQUEST: case MOBILE_REDIRECT: case PARAMETER_PROBLEM: case REDIRECT: case ROUTER_ADVERTISEMENT: case ROUTER_SOLICITATION: case SOURCE_QUENCH: case TIME_EXCEEDED: case TIMESTAMP_REPLY: case TIMESTAMP_REQUEST: case TRACEROUTE: case UNREACHABLE: { { switch ( LA(1)) { case INT_CONST: { icmp_type = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 688 "pix.g" importer->icmp_type = LT(0)->getText(); #line 3522 "PIXCfgParser.cpp" } break; } case ECHO: case ALTERNATE_ADDRESS: case CONVERSION_ERROR: case ECHO_REPLY: case INFORMATION_REPLY: case INFORMATION_REQUEST: case MASK_REPLY: case MASK_REQUEST: case MOBILE_REDIRECT: case PARAMETER_PROBLEM: case REDIRECT: case ROUTER_ADVERTISEMENT: case ROUTER_SOLICITATION: case SOURCE_QUENCH: case TIME_EXCEEDED: case TIMESTAMP_REPLY: case TIMESTAMP_REQUEST: case TRACEROUTE: case UNREACHABLE: { icmp_names(); if ( inputState->guessing==0 ) { #line 693 "pix.g" importer->icmp_spec = LT(0)->getText(); #line 3552 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 697 "pix.g" importer->addICMPServiceToObjectGroup(); *dbg << " SERVICE ICMP " << LT(0)->getText() << " "; #line 3568 "PIXCfgParser.cpp" } break; } case OBJECT: { match(OBJECT); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 703 "pix.g" importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; #line 3583 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::object_group_service_parameters() { try { // for error handling { switch ( LA(1)) { case DESCRIPTION: { object_group_description(); break; } case GROUP_OBJECT: { group_object(); break; } case SERVICE_OBJECT: { service_object(); break; } case PORT_OBJECT: { port_object(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_19); } else { throw; } } } void PIXCfgParser::service_object() { ANTLR_USE_NAMESPACE(antlr)RefToken icmp_type = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(SERVICE_OBJECT); if ( inputState->guessing==0 ) { #line 742 "pix.g" importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 3659 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: case INT_CONST: { { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: { ip_protocol_names(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 748 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->addIPServiceToObjectGroup(); *dbg << " GROUP MEMBER " << LT(0)->getText() << " "; #line 3720 "PIXCfgParser.cpp" } break; } case TCP: case UDP: case TCP_UDP: { { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } case TCP_UDP: { match(TCP_UDP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 756 "pix.g" importer->protocol = LT(0)->getText(); *dbg << " SERVICE TCP/UDP" << LT(0)->getText() << " "; #line 3757 "PIXCfgParser.cpp" } { switch ( LA(1)) { case SOURCE: { src_port_spec(); break; } case NEWLINE: case RANGE: case DESTINATION: case P_EQ: case P_GT: case P_LT: case P_NEQ: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case RANGE: case DESTINATION: case P_EQ: case P_GT: case P_LT: case P_NEQ: { dst_port_spec(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 762 "pix.g" importer->addTCPUDPServiceToObjectGroup(); #line 3809 "PIXCfgParser.cpp" } break; } case ICMP: { match(ICMP); { switch ( LA(1)) { case INT_CONST: { icmp_type = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 769 "pix.g" importer->icmp_type = LT(0)->getText(); #line 3827 "PIXCfgParser.cpp" } break; } case ECHO: case ALTERNATE_ADDRESS: case CONVERSION_ERROR: case ECHO_REPLY: case INFORMATION_REPLY: case INFORMATION_REQUEST: case MASK_REPLY: case MASK_REQUEST: case MOBILE_REDIRECT: case PARAMETER_PROBLEM: case REDIRECT: case ROUTER_ADVERTISEMENT: case ROUTER_SOLICITATION: case SOURCE_QUENCH: case TIME_EXCEEDED: case TIMESTAMP_REPLY: case TIMESTAMP_REQUEST: case TRACEROUTE: case UNREACHABLE: { icmp_names(); if ( inputState->guessing==0 ) { #line 774 "pix.g" importer->icmp_spec = LT(0)->getText(); #line 3857 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 778 "pix.g" importer->addICMPServiceToObjectGroup(); *dbg << " SERVICE ICMP " << LT(0)->getText() << " "; #line 3873 "PIXCfgParser.cpp" } break; } case OBJECT: { match(OBJECT); name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 784 "pix.g" importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; #line 3888 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::port_object() { #line 791 "pix.g" importer->tmp_port_spec = ""; importer->tmp_port_spec_2 = ""; #line 3915 "PIXCfgParser.cpp" try { // for error handling match(PORT_OBJECT); xoperator(); if ( inputState->guessing==0 ) { #line 796 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << " PORT OBJECT TCP/UDP " << LT(0)->getText() << " " << std::endl; importer->SaveTmpPortToDst(); importer->addTCPUDPServiceToObjectGroup(); *dbg << std::endl; #line 3929 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::permit_extended() { try { // for error handling { switch ( LA(1)) { case EXTENDED: { match(EXTENDED); break; } case PERMIT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(PERMIT); if ( inputState->guessing==0 ) { #line 935 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; #line 3971 "PIXCfgParser.cpp" } rule_extended(); match(NEWLINE); if ( inputState->guessing==0 ) { #line 942 "pix.g" importer->pushRule(); #line 3980 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::deny_extended() { try { // for error handling { switch ( LA(1)) { case EXTENDED: { match(EXTENDED); break; } case DENY: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(DENY); if ( inputState->guessing==0 ) { #line 948 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; #line 4022 "PIXCfgParser.cpp" } rule_extended(); match(NEWLINE); if ( inputState->guessing==0 ) { #line 955 "pix.g" importer->pushRule(); #line 4031 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::permit_standard() { try { // for error handling match(STANDARD); match(PERMIT); if ( inputState->guessing==0 ) { #line 961 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; #line 4057 "PIXCfgParser.cpp" } rule_standard(); match(NEWLINE); if ( inputState->guessing==0 ) { #line 968 "pix.g" importer->pushRule(); #line 4066 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::deny_standard() { try { // for error handling match(STANDARD); match(DENY); if ( inputState->guessing==0 ) { #line 974 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; #line 4092 "PIXCfgParser.cpp" } rule_standard(); match(NEWLINE); if ( inputState->guessing==0 ) { #line 981 "pix.g" importer->pushRule(); #line 4101 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::remark() { try { // for error handling match(REMARK); if ( inputState->guessing==0 ) { #line 1909 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string rem; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { rem += LT(1)->getText() + " "; consume(); } importer->addRuleComment( rem ); *dbg << " REMARK " << rem << std::endl; //consumeUntil(NEWLINE); #line 4133 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::rule_extended() { ANTLR_USE_NAMESPACE(antlr)RefToken grp_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: case OBJECT: case ICMP6: case OBJECT_GROUP: { ip_protocols(); hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1006 "pix.g" importer->SaveTmpAddrToSrc(); *dbg << "(src) "; #line 4176 "PIXCfgParser.cpp" } hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1007 "pix.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 4182 "PIXCfgParser.cpp" } { switch ( LA(1)) { case TIME_RANGE: { time_range(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FRAGMENTS: { fragments(); break; } case NEWLINE: case LOG: case LOG_INPUT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case ICMP: { match(ICMP); if ( inputState->guessing==0 ) { #line 1013 "pix.g" importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; #line 4252 "PIXCfgParser.cpp" } hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1017 "pix.g" importer->SaveTmpAddrToSrc(); *dbg << "(src) "; #line 4258 "PIXCfgParser.cpp" } hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1018 "pix.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 4264 "PIXCfgParser.cpp" } { switch ( LA(1)) { case OBJECT_GROUP: { match(OBJECT_GROUP); grp_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 1035 "pix.g" importer->icmp_spec = grp_name->getText(); *dbg << "service gorup: " << grp_name->getText() << std::endl; #line 4280 "PIXCfgParser.cpp" } break; } case INT_CONST: case ECHO: case ALTERNATE_ADDRESS: case CONVERSION_ERROR: case ECHO_REPLY: case INFORMATION_REPLY: case INFORMATION_REQUEST: case MASK_REPLY: case MASK_REQUEST: case MOBILE_REDIRECT: case PARAMETER_PROBLEM: case REDIRECT: case ROUTER_ADVERTISEMENT: case ROUTER_SOLICITATION: case SOURCE_QUENCH: case TIME_EXCEEDED: case TIMESTAMP_REPLY: case TIMESTAMP_REQUEST: case TRACEROUTE: case UNREACHABLE: { icmp_spec(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case TIME_RANGE: { time_range(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FRAGMENTS: { fragments(); break; } case NEWLINE: case LOG: case LOG_INPUT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case TCP: case UDP: { tcp_udp_rule_extended(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1049 "pix.g" *dbg << std::endl; #line 4398 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::rule_standard() { try { // for error handling if ( inputState->guessing==0 ) { #line 991 "pix.g" importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; importer->SaveTmpAddrToSrc(); #line 4421 "PIXCfgParser.cpp" } hostaddr_expr(); if ( inputState->guessing==0 ) { #line 997 "pix.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) " << std::endl; #line 4430 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::hostaddr_expr() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken h = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken m = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling switch ( LA(1)) { case INTRFACE: { match(INTRFACE); interface_label(); if ( inputState->guessing==0 ) { #line 1296 "pix.g" importer->tmp_a = LT(0)->getText(); importer->tmp_nm = "interface"; *dbg << "object " << LT(0)->getText() << " "; #line 4462 "PIXCfgParser.cpp" } break; } case OBJECT: case OBJECT_GROUP: { { { switch ( LA(1)) { case OBJECT: { match(OBJECT); break; } case OBJECT_GROUP: { match(OBJECT_GROUP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } name = LT(1); match(WORD); } if ( inputState->guessing==0 ) { #line 1303 "pix.g" importer->tmp_a = name->getText(); importer->tmp_nm = ""; *dbg << "object " << name->getText() << " "; #line 4498 "PIXCfgParser.cpp" } break; } case HOST: { { match(HOST); h = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 1310 "pix.g" importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; *dbg << h->getText() << "/255.255.255.255"; #line 4516 "PIXCfgParser.cpp" } break; } case IPV4: { { a = LT(1); match(IPV4); m = LT(1); match(IPV4); } if ( inputState->guessing==0 ) { #line 1317 "pix.g" importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); #line 4535 "PIXCfgParser.cpp" } break; } case ANY: { match(ANY); if ( inputState->guessing==0 ) { #line 1324 "pix.g" importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; #line 4549 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_20); } else { throw; } } } void PIXCfgParser::ip_protocols() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: case ICMP6: { { switch ( LA(1)) { case IP: case PIM: case AH: case EIGRP: case ESP_WORD: case GRE: case IGMP: case IGRP: case IPINIP: case IPSEC: case NOS: case OSPF: case PCP: case PPTP: case SNP: { ip_protocol_names(); break; } case ICMP6: { match(ICMP6); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1243 "pix.g" importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; #line 4630 "PIXCfgParser.cpp" } break; } case OBJECT: case OBJECT_GROUP: { { { switch ( LA(1)) { case OBJECT: { match(OBJECT); break; } case OBJECT_GROUP: { match(OBJECT_GROUP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } name = LT(1); match(WORD); } if ( inputState->guessing==0 ) { #line 1249 "pix.g" importer->protocol = name->getText(); *dbg << "protocol " << name->getText() << " "; #line 4665 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_21); } else { throw; } } } void PIXCfgParser::time_range() { ANTLR_USE_NAMESPACE(antlr)RefToken tr_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(TIME_RANGE); tr_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 1376 "pix.g" importer->time_range_name = tr_name->getText(); *dbg << "time_range " << tr_name->getText() << " "; #line 4699 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_22); } else { throw; } } } void PIXCfgParser::fragments() { try { // for error handling match(FRAGMENTS); if ( inputState->guessing==0 ) { #line 1369 "pix.g" importer->fragments = true; *dbg << "fragments "; #line 4722 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_23); } else { throw; } } } void PIXCfgParser::log() { try { // for error handling { switch ( LA(1)) { case LOG: { match(LOG); break; } case LOG_INPUT: { match(LOG_INPUT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1335 "pix.g" importer->logging = true; #line 4761 "PIXCfgParser.cpp" } { { switch ( LA(1)) { case INT_CONST: case LOG_LEVEL_ALERTS: case LOG_LEVEL_CRITICAL: case LOG_LEVEL_DEBUGGING: case LOG_LEVEL_EMERGENCIES: case LOG_LEVEL_ERRORS: case LOG_LEVEL_INFORMATIONAL: case LOG_LEVEL_NOTIFICATIONS: case LOG_LEVEL_WARNINGS: case LOG_LEVEL_DISABLE: case LOG_LEVEL_INACTIVE: { { switch ( LA(1)) { case INT_CONST: { match(INT_CONST); break; } case LOG_LEVEL_ALERTS: { match(LOG_LEVEL_ALERTS); break; } case LOG_LEVEL_CRITICAL: { match(LOG_LEVEL_CRITICAL); break; } case LOG_LEVEL_DEBUGGING: { match(LOG_LEVEL_DEBUGGING); break; } case LOG_LEVEL_EMERGENCIES: { match(LOG_LEVEL_EMERGENCIES); break; } case LOG_LEVEL_ERRORS: { match(LOG_LEVEL_ERRORS); break; } case LOG_LEVEL_INFORMATIONAL: { match(LOG_LEVEL_INFORMATIONAL); break; } case LOG_LEVEL_NOTIFICATIONS: { match(LOG_LEVEL_NOTIFICATIONS); break; } case LOG_LEVEL_WARNINGS: { match(LOG_LEVEL_WARNINGS); break; } case LOG_LEVEL_DISABLE: { match(LOG_LEVEL_DISABLE); break; } case LOG_LEVEL_INACTIVE: { match(LOG_LEVEL_INACTIVE); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1352 "pix.g" importer->log_level = LT(0)->getText(); #line 4844 "PIXCfgParser.cpp" } break; } case NEWLINE: case INTERVAL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case INTERVAL: { { match(INTERVAL); match(INT_CONST); } if ( inputState->guessing==0 ) { #line 1357 "pix.g" importer->log_interval = LT(0)->getText(); #line 4870 "PIXCfgParser.cpp" } break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } if ( inputState->guessing==0 ) { #line 1360 "pix.g" // if (importer->log_level == "log") importer->log_level = ""; // if (importer->log_interval == "log") importer->log_interval = ""; *dbg << "logging level '" << importer->log_level << "' interval '" << importer->log_interval << "'"; #line 4893 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::icmp_spec() { ANTLR_USE_NAMESPACE(antlr)RefToken icmp_type = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken icmp_code = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case INT_CONST: { { icmp_type = LT(1); match(INT_CONST); icmp_code = LT(1); match(INT_CONST); } if ( inputState->guessing==0 ) { #line 1259 "pix.g" importer->icmp_type = icmp_type->getText(); importer->icmp_code = icmp_code->getText(); importer->icmp_spec = ""; *dbg << icmp_type->getText() << " " << icmp_code->getText() << " "; #line 4930 "PIXCfgParser.cpp" } break; } case ECHO: case ALTERNATE_ADDRESS: case CONVERSION_ERROR: case ECHO_REPLY: case INFORMATION_REPLY: case INFORMATION_REQUEST: case MASK_REPLY: case MASK_REQUEST: case MOBILE_REDIRECT: case PARAMETER_PROBLEM: case REDIRECT: case ROUTER_ADVERTISEMENT: case ROUTER_SOLICITATION: case SOURCE_QUENCH: case TIME_EXCEEDED: case TIMESTAMP_REPLY: case TIMESTAMP_REQUEST: case TRACEROUTE: case UNREACHABLE: { icmp_names(); if ( inputState->guessing==0 ) { #line 1268 "pix.g" importer->icmp_spec = LT(0)->getText(); *dbg << LT(0)->getText() << " "; #line 4961 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_13); } else { throw; } } } void PIXCfgParser::tcp_udp_rule_extended() { ANTLR_USE_NAMESPACE(antlr)RefToken src_grp_name = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken dst_addr_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1056 "pix.g" importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; #line 5011 "PIXCfgParser.cpp" } hostaddr_expr(); if ( inputState->guessing==0 ) { #line 1060 "pix.g" importer->SaveTmpAddrToSrc(); *dbg << "(src) "; #line 5017 "PIXCfgParser.cpp" } { bool synPredMatched131 = false; if (((_tokenSet_21.member(LA(1))) && (_tokenSet_24.member(LA(2))))) { int _m131 = mark(); synPredMatched131 = true; inputState->guessing++; try { { match(OBJECT_GROUP); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched131 = false; } rewind(_m131); inputState->guessing--; } if ( synPredMatched131 ) { { if (((LA(1) == OBJECT_GROUP) && (LA(2) == WORD))&&( importer->isKnownServiceGroupName(LT(2)->getText()) )) { match(OBJECT_GROUP); src_grp_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 1070 "pix.g" importer->src_port_spec = src_grp_name->getText(); *dbg << "src port spec: " << src_grp_name->getText() << std::endl; #line 5049 "PIXCfgParser.cpp" } hostaddr_expr_1(); if ( inputState->guessing==0 ) { #line 1078 "pix.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 5058 "PIXCfgParser.cpp" } acl_tcp_udp_dst_port_spec(); } else if ((_tokenSet_21.member(LA(1))) && (_tokenSet_24.member(LA(2)))) { hostaddr_expr_2(); if ( inputState->guessing==0 ) { #line 1087 "pix.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 5070 "PIXCfgParser.cpp" } acl_tcp_udp_dst_port_spec(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } else if ((LA(1) == OBJECT) && (LA(2) == WORD)) { match(OBJECT); dst_addr_name = LT(1); match(WORD); { if ((_tokenSet_25.member(LA(1))) && (_tokenSet_26.member(LA(2)))) { acl_xoperator_dst(); } else if ((_tokenSet_27.member(LA(1))) && (_tokenSet_28.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } { if ((LA(1) == ESTABLISHED) && (_tokenSet_27.member(LA(2)))) { established(); } else if ((_tokenSet_27.member(LA(1))) && (_tokenSet_29.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } if ( inputState->guessing==0 ) { #line 1096 "pix.g" // looks like "object foo" at this point can only be dest addr. // (judging by cli prompts on 8.3) importer->tmp_a = dst_addr_name->getText(); importer->tmp_nm = ""; importer->SaveTmpAddrToDst(); *dbg << "dst addr object " << dst_addr_name->getText() << " "; #line 5116 "PIXCfgParser.cpp" } acl_tcp_udp_dst_port_spec(); } else if ((_tokenSet_30.member(LA(1))) && (_tokenSet_31.member(LA(2)))) { { switch ( LA(1)) { case RANGE: case P_EQ: case P_GT: case P_LT: case P_NEQ: { xoperator(); if ( inputState->guessing==0 ) { #line 1110 "pix.g" importer->SaveTmpPortToSrc(); #line 5135 "PIXCfgParser.cpp" } break; } case IPV4: case OBJECT: case HOST: case OBJECT_GROUP: case INTRFACE: case ANY: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } hostaddr_expr_3(); if ( inputState->guessing==0 ) { #line 1114 "pix.g" importer->SaveTmpAddrToDst(); *dbg << "(dst) "; #line 5158 "PIXCfgParser.cpp" } acl_tcp_udp_dst_port_spec(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } { switch ( LA(1)) { case TIME_RANGE: { time_range(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FRAGMENTS: { fragments(); break; } case NEWLINE: case LOG: case LOG_INPUT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case LOG_INPUT: { log(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::hostaddr_expr_1() { try { // for error handling hostaddr_expr(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_27); } else { throw; } } } void PIXCfgParser::acl_tcp_udp_dst_port_spec() { ANTLR_USE_NAMESPACE(antlr)RefToken dst_port_group_name = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken dst_port_obj_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case OBJECT_GROUP: { { match(OBJECT_GROUP); dst_port_group_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 1132 "pix.g" importer->dst_port_spec = dst_port_group_name->getText(); *dbg << "dst port spec: " << dst_port_group_name->getText() << std::endl; #line 5270 "PIXCfgParser.cpp" } { switch ( LA(1)) { case ESTABLISHED: { established(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } break; } case OBJECT: { match(OBJECT); dst_port_obj_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 1142 "pix.g" importer->dst_port_spec = dst_port_obj_name->getText(); *dbg << "dst addr object " << dst_port_obj_name->getText() << std::endl; #line 5308 "PIXCfgParser.cpp" } { switch ( LA(1)) { case ESTABLISHED: { established(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: case RANGE: case P_EQ: case P_GT: case P_LT: case P_NEQ: case ESTABLISHED: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: { { switch ( LA(1)) { case RANGE: case P_EQ: case P_GT: case P_LT: case P_NEQ: { acl_xoperator_dst(); break; } case NEWLINE: case ESTABLISHED: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ESTABLISHED: { established(); break; } case NEWLINE: case LOG: case LOG_INPUT: case FRAGMENTS: case TIME_RANGE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_13); } else { throw; } } } void PIXCfgParser::hostaddr_expr_2() { try { // for error handling hostaddr_expr(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_27); } else { throw; } } } void PIXCfgParser::acl_xoperator_dst() { try { // for error handling xoperator(); if ( inputState->guessing==0 ) { #line 1157 "pix.g" importer->SaveTmpPortToDst(); #line 5435 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_27); } else { throw; } } } void PIXCfgParser::established() { try { // for error handling match(ESTABLISHED); if ( inputState->guessing==0 ) { #line 1232 "pix.g" importer->established = true; *dbg << "established "; #line 5458 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_27); } else { throw; } } } void PIXCfgParser::hostaddr_expr_3() { try { // for error handling hostaddr_expr(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_27); } else { throw; } } } void PIXCfgParser::single_port_op() { try { // for error handling { switch ( LA(1)) { case P_EQ: { match(P_EQ); break; } case P_GT: { match(P_GT); break; } case P_LT: { match(P_LT); break; } case P_NEQ: { match(P_NEQ); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1169 "pix.g" importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; #line 5523 "PIXCfgParser.cpp" } port_spec(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_15); } else { throw; } } } void PIXCfgParser::port_range() { try { // for error handling match(RANGE); pair_of_ports_spec(); if ( inputState->guessing==0 ) { #line 1188 "pix.g" importer->tmp_port_op = "range"; *dbg << "range " << importer->tmp_port_spec; #line 5548 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_15); } else { throw; } } } void PIXCfgParser::port_spec() { try { // for error handling if ( inputState->guessing==0 ) { #line 1177 "pix.g" importer->tmp_port_spec_2 = ""; #line 5569 "PIXCfgParser.cpp" } tcp_udp_port_spec(); if ( inputState->guessing==0 ) { #line 1181 "pix.g" importer->tmp_port_spec = std::string(" ") + importer->tmp_port_spec_2; *dbg << LT(0)->getText() << " " << importer->tmp_port_spec; #line 5578 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_15); } else { throw; } } } void PIXCfgParser::tcp_udp_port_spec() { try { // for error handling { switch ( LA(1)) { case PPTP: case HTTP: case SSH: case TELNET: case HOSTNAME: case ECHO: { tcp_udp_port_names(); break; } case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1212 "pix.g" importer->tmp_port_spec_2 = LT(0)->getText(); #line 5627 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_32); } else { throw; } } } void PIXCfgParser::pair_of_ports_spec() { try { // for error handling if ( inputState->guessing==0 ) { #line 1195 "pix.g" importer->tmp_port_spec_2 = ""; #line 5648 "PIXCfgParser.cpp" } tcp_udp_port_spec(); if ( inputState->guessing==0 ) { #line 1199 "pix.g" importer->tmp_port_spec += importer->tmp_port_spec_2; #line 5656 "PIXCfgParser.cpp" } tcp_udp_port_spec(); if ( inputState->guessing==0 ) { #line 1203 "pix.g" importer->tmp_port_spec += " "; importer->tmp_port_spec += importer->tmp_port_spec_2; #line 5665 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_15); } else { throw; } } } void PIXCfgParser::tcp_udp_port_names() { try { // for error handling { switch ( LA(1)) { case ECHO: { match(ECHO); break; } case HOSTNAME: { match(HOSTNAME); break; } case PPTP: { match(PPTP); break; } case SSH: { match(SSH); break; } case TELNET: { match(TELNET); break; } case HTTP: { match(HTTP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_32); } else { throw; } } } void PIXCfgParser::interface_label() { try { // for error handling switch ( LA(1)) { case WORD: { match(WORD); break; } case OUTSIDE: { match(OUTSIDE); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_33); } else { throw; } } } void PIXCfgParser::interface_command_6() { ANTLR_USE_NAMESPACE(antlr)RefToken in = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling in = LT(1); match(WORD); pix6_interface_hw_speed(); if ( inputState->guessing==0 ) { #line 1440 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; #line 5775 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::interface_command_7() { ANTLR_USE_NAMESPACE(antlr)RefToken in = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 1448 "pix.g" bool have_interface_parameters = false; #line 5792 "PIXCfgParser.cpp" try { // for error handling in = LT(1); match(WORD); match(NEWLINE); if ( inputState->guessing==0 ) { #line 1449 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; #line 5806 "PIXCfgParser.cpp" } { { // ( ... )* for (;;) { if ((_tokenSet_34.member(LA(1)))) { interface_parameters(); if ( inputState->guessing==0 ) { #line 1456 "pix.g" have_interface_parameters = true; #line 5816 "PIXCfgParser.cpp" } } else { goto _loop197; } } _loop197:; } // ( ... )* { switch ( LA(1)) { case LINE_COMMENT: { match(LINE_COMMENT); break; } case EXIT: { match(EXIT); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1458 "pix.g" if ( ! have_interface_parameters ) { importer->ignoreCurrentInterface(); *dbg<< LT(1)->getLine() << ":" << " EMPTY INTERFACE " << std::endl; } #line 5854 "PIXCfgParser.cpp" } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::pix6_interface_hw_speed() { try { // for error handling { switch ( LA(1)) { case AUI: { match(AUI); break; } case AUTO: { match(AUTO); break; } case BNC: { match(BNC); break; } case INT_CONST: { { match(INT_CONST); { switch ( LA(1)) { case FULL: { match(FULL); break; } case BASET: { match(BASET); break; } case BASETX: { match(BASETX); break; } case AUTO: { match(AUTO); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::interface_parameters() { try { // for error handling if ( inputState->guessing==0 ) { #line 1493 "pix.g" importer->setCurrentLineNumber(LT(0)->getLine()); #line 5948 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IP: { intf_address(); break; } case VLAN: { vlan_interface(); break; } case SEC_LEVEL: { sec_level(); break; } case NAMEIF: { nameif(); break; } case DESCRIPTION: { interface_description(); break; } case SWITCHPORT: { switchport(); break; } case SHUTDOWN: { shutdown(); break; } case NO: { interface_no_commands(); break; } case PIM: case IGMP: case OSPF: case SPEED: case DUPLEX: case DDNS: case FORWARD: case DELAY: case HOLD_TIME: case IPV6_C: case MANAGEMENT_ONLY: case MAC_ADDRESS: case MULTICAST: case PPPOE: case RIP: { unsupported_interface_commands(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_35); } else { throw; } } } void PIXCfgParser::vlan_interface() { ANTLR_USE_NAMESPACE(antlr)RefToken vlan_id = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(VLAN); vlan_id = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 1519 "pix.g" importer->setInterfaceVlanId(vlan_id->getText()); *dbg << " VLAN: " << vlan_id->getText() << std::endl; #line 6042 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::sec_level() { ANTLR_USE_NAMESPACE(antlr)RefToken sec_level = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(SEC_LEVEL); sec_level = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 1573 "pix.g" importer->setInterfaceSecurityLevel(sec_level->getText()); *dbg << "SEC_LEVEL: " << sec_level->getText() << std::endl; #line 6068 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::nameif() { try { // for error handling match(NAMEIF); interface_label(); if ( inputState->guessing==0 ) { #line 1592 "pix.g" importer->setInterfaceParametes(LT(0)->getText(), "", ""); *dbg << " NAMEIF: " << LT(0)->getText() << std::endl; #line 6092 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::interface_description() { try { // for error handling match(DESCRIPTION); if ( inputState->guessing==0 ) { #line 1601 "pix.g" *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setInterfaceComment( descr ); *dbg << " DESCRIPTION " << descr << std::endl; //consumeUntil(NEWLINE); #line 6123 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::switchport() { ANTLR_USE_NAMESPACE(antlr)RefToken vlan_num = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(SWITCHPORT); match(ACCESS); match(VLAN); vlan_num = LT(1); match(INT_CONST); if ( inputState->guessing==0 ) { #line 1722 "pix.g" importer->addMessageToLog("Switch port vlan " + vlan_num->getText()); *dbg << "Switch port vlan " << vlan_num->getText() << std::endl; #line 6151 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::shutdown() { try { // for error handling match(SHUTDOWN); if ( inputState->guessing==0 ) { #line 1616 "pix.g" importer->ignoreCurrentInterface(); *dbg<< LT(1)->getLine() << ":" << " INTERFACE SHUTDOWN " << std::endl; #line 6175 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::interface_no_commands() { try { // for error handling match(NO); { switch ( LA(1)) { case NAMEIF: { match(NAMEIF); break; } case IP: { match(IP); break; } case SEC_LEVEL: { match(SEC_LEVEL); break; } case SHUTDOWN: { match(SHUTDOWN); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1565 "pix.g" *dbg << " INTERFACE \"NO\" COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); #line 6227 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::unsupported_interface_commands() { try { // for error handling { switch ( LA(1)) { case SPEED: { match(SPEED); break; } case DUPLEX: { match(DUPLEX); break; } case DDNS: { match(DDNS); break; } case FORWARD: { match(FORWARD); break; } case DELAY: { match(DELAY); break; } case HOLD_TIME: { match(HOLD_TIME); break; } case IGMP: { match(IGMP); break; } case IPV6_C: { match(IPV6_C); break; } case MANAGEMENT_ONLY: { match(MANAGEMENT_ONLY); break; } case MAC_ADDRESS: { match(MAC_ADDRESS); break; } case MULTICAST: { match(MULTICAST); break; } case OSPF: { match(OSPF); break; } case PIM: { match(PIM); break; } case PPPOE: { match(PPPOE); break; } case RIP: { match(RIP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1557 "pix.g" *dbg << " UNSUPPORTED INTERFACE COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); #line 6333 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::v6_ip_address() { try { // for error handling if ((LA(1) == WORD || LA(1) == OUTSIDE) && (LA(2) == DHCP)) { v6_dhcp_address(); } else if ((LA(1) == WORD || LA(1) == OUTSIDE) && (LA(2) == IPV4)) { v6_static_address(); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::v7_ip_address() { try { // for error handling switch ( LA(1)) { case DHCP: { v7_dhcp_address(); break; } case IPV4: { v7_static_address(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::v6_dhcp_address() { ANTLR_USE_NAMESPACE(antlr)RefToken dhcp = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 1650 "pix.g" std::string lbl; #line 6404 "PIXCfgParser.cpp" try { // for error handling interface_label(); if ( inputState->guessing==0 ) { #line 1652 "pix.g" lbl = LT(0)->getText(); #line 6413 "PIXCfgParser.cpp" } dhcp = LT(1); match(DHCP); if ( inputState->guessing==0 ) { #line 1656 "pix.g" std::string addr = dhcp->getText(); importer->addInterfaceAddress(lbl, addr, ""); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << std::endl; // there can be some other parameters after "dhcp", such as // "setroute", "retry" etc. which we do not support consumeUntil(NEWLINE); #line 6428 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::v6_static_address() { ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken m = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 1667 "pix.g" std::string lbl; #line 6446 "PIXCfgParser.cpp" try { // for error handling interface_label(); if ( inputState->guessing==0 ) { #line 1669 "pix.g" lbl = LT(0)->getText(); #line 6455 "PIXCfgParser.cpp" } a = LT(1); match(IPV4); m = LT(1); match(IPV4); if ( inputState->guessing==0 ) { #line 1673 "pix.g" std::string addr = a->getText(); std::string netm = m->getText(); importer->addInterfaceAddress(lbl, addr, netm); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << "/" << netm << std::endl; // in case there are some other parameters after address and netmask consumeUntil(NEWLINE); #line 6472 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::v7_dhcp_address() { ANTLR_USE_NAMESPACE(antlr)RefToken dhcp = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling dhcp = LT(1); match(DHCP); if ( inputState->guessing==0 ) { #line 1689 "pix.g" std::string addr = dhcp->getText(); importer->addInterfaceAddress(addr, ""); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << std::endl; consumeUntil(NEWLINE); #line 6500 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::v7_static_address() { ANTLR_USE_NAMESPACE(antlr)RefToken a = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken m = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken s = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling a = LT(1); match(IPV4); m = LT(1); match(IPV4); { switch ( LA(1)) { case STANDBY: { s = LT(1); match(STANDBY); break; } case ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE: case NEWLINE: case QUIT: case IP: case TIMEOUT: case PIM: case NETWORK: case NAMES: case NAME: case WORD: case OBJECT: case SERVICE: case HTTP: case SSH: case TELNET: case ICMP: case OBJECT_GROUP: case CRYPTO: case DNS: case NO: case CERTIFICATE: case PIX_WORD: case ASA_WORD: case FWSM_WORD: case HOSTNAME: case ACCESS_LIST: case INTRFACE: case CONTROLLER: case LINE_COMMENT: case EXIT: case NAMEIF: case ACCESS_GROUP: case COLON_COMMENT: case NAT: case GLOBAL: case STATIC: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1700 "pix.g" std::string addr = a->getText(); std::string netm = m->getText(); importer->addInterfaceAddress(addr, netm); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << "/" << netm << std::endl; // there can be other parameters after address/netmask pair, such as "standby" // We do not parse them yet. if (s) { importer->addMessageToLog( QString("Warning: failover IP detected. " "Failover is not supported by import " "at this time")); } consumeUntil(NEWLINE); #line 6595 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_1); } else { throw; } } } void PIXCfgParser::icmp_types_for_icmp_command() { try { // for error handling switch ( LA(1)) { case INT_CONST: { match(INT_CONST); if ( inputState->guessing==0 ) { #line 1888 "pix.g" importer->icmp_type = LT(0)->getText(); importer->icmp_code = "0"; importer->icmp_spec = ""; #line 6622 "PIXCfgParser.cpp" } break; } case ECHO: case ECHO_REPLY: case TIME_EXCEEDED: case UNREACHABLE: { { switch ( LA(1)) { case ECHO: { match(ECHO); break; } case ECHO_REPLY: { match(ECHO_REPLY); break; } case TIME_EXCEEDED: { match(TIME_EXCEEDED); break; } case UNREACHABLE: { match(UNREACHABLE); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 1895 "pix.g" importer->icmp_type = ""; importer->icmp_code = "0"; importer->icmp_spec = LT(0)->getText(); #line 6666 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_36); } else { throw; } } } void PIXCfgParser::nat_old_top_level_command() { try { // for error handling interface_label(); if ( inputState->guessing==0 ) { #line 1963 "pix.g" importer->prenat_interface = LT(0)->getText(); #line 6695 "PIXCfgParser.cpp" } match(CLOSING_PAREN); if ( inputState->guessing==0 ) { #line 1967 "pix.g" importer->newUnidirRuleSet("nat", libfwbuilder::NAT::TYPENAME ); *dbg << " SNAT rule "; importer->rule_type = libfwbuilder::NATRule::SNAT; #line 6705 "PIXCfgParser.cpp" } match(INT_CONST); if ( inputState->guessing==0 ) { #line 1975 "pix.g" importer->nat_num = LT(0)->getText(); #line 6713 "PIXCfgParser.cpp" } nat_addr_match(); { // ( ... )* for (;;) { if ((_tokenSet_37.member(LA(1)))) { nat_command_last_parameters(); } else { goto _loop254; } } _loop254:; } // ( ... )* match(NEWLINE); if ( inputState->guessing==0 ) { #line 1987 "pix.g" importer->pushNATRule(); *dbg << std::endl; #line 6735 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void PIXCfgParser::nat_new_top_level_command() { try { // for error handling interface_label(); match(COMMA); interface_label(); match(CLOSING_PAREN); if ( inputState->guessing==0 ) { #line 2064 "pix.g" importer->addMessageToLog( QString("Warning: Import of ASA 8.3 nat command " "is not supported at this time")); consumeUntil(NEWLINE); #line 6763 "PIXCfgParser.cpp" } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_5); } else { throw; } } } void PIXCfgParser::nat_addr_match() { ANTLR_USE_NAMESPACE(antlr)RefToken acl_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling switch ( LA(1)) { case IPV4: case IPV6: { single_addr(); if ( inputState->guessing==0 ) { #line 1995 "pix.g" importer->nat_a = importer->tmp_a; #line 6790 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IPV4: case IPV6: { single_addr(); if ( inputState->guessing==0 ) { #line 2003 "pix.g" importer->nat_nm = importer->tmp_a; #line 6803 "PIXCfgParser.cpp" } break; } case NEWLINE: case INT_CONST: case TCP: case UDP: case DNS: case OUTSIDE: case NORANDOMSEQ: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case INT_CONST: { match(INT_CONST); if ( inputState->guessing==0 ) { #line 2009 "pix.g" if (LT(0)->getText() != std::string("0")) { importer->reportError( std::string("Unknown string ")+LT(0)->getText()+ std::string("; expected \"0\"")); *dbg << " UNKNOWN STRING " << LT(0)->getText(); } importer->nat_a = "0.0.0.0"; #line 6840 "PIXCfgParser.cpp" } { if ((LA(1) == INT_CONST) && (_tokenSet_38.member(LA(2)))) { match(INT_CONST); if ( inputState->guessing==0 ) { #line 2021 "pix.g" if (LT(0)->getText() != std::string("0")) { importer->reportError( std::string("Unknown string ")+LT(0)->getText()+ std::string("; expected \"0\"")); *dbg << " UNKNOWN STRING " << LT(0)->getText(); } importer->nat_nm = "0.0.0.0"; #line 6857 "PIXCfgParser.cpp" } } else if ((_tokenSet_38.member(LA(1))) && (_tokenSet_39.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } break; } case ACCESS_LIST: { match(ACCESS_LIST); acl_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 2034 "pix.g" importer->nat_acl = acl_name->getText(); #line 6879 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_38); } else { throw; } } } void PIXCfgParser::nat_command_last_parameters() { try { // for error handling switch ( LA(1)) { case INT_CONST: case TCP: case UDP: case DNS: case NORANDOMSEQ: { nat_and_static_command_common_last_parameters(); break; } case OUTSIDE: { match(OUTSIDE); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_38); } else { throw; } } } void PIXCfgParser::nat_and_static_command_common_last_parameters() { ANTLR_USE_NAMESPACE(antlr)RefToken max_conn = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken max_emb_conn = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling switch ( LA(1)) { case DNS: { match(DNS); if ( inputState->guessing==0 ) { #line 2306 "pix.g" importer->addMessageToLog( QString("Warning: 'nat' and 'static' command option 'dns' is not supported")); #line 6948 "PIXCfgParser.cpp" } break; } case NORANDOMSEQ: { match(NORANDOMSEQ); if ( inputState->guessing==0 ) { #line 2312 "pix.g" importer->addMessageToLog( QString("Warning: 'nat' and 'static' command option 'norandomseq' is not supported")); #line 6961 "PIXCfgParser.cpp" } break; } case INT_CONST: case TCP: case UDP: { { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } case INT_CONST: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } max_conn = LT(1); match(INT_CONST); { if ((LA(1) == INT_CONST) && (_tokenSet_40.member(LA(2)))) { max_emb_conn = LT(1); match(INT_CONST); } else if ((_tokenSet_40.member(LA(1))) && (_tokenSet_41.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } if ( inputState->guessing==0 ) { #line 2319 "pix.g" importer->static_max_conn = max_conn->getText(); if (max_emb_conn) importer->static_max_emb_conn = max_emb_conn->getText(); #line 7012 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_40); } else { throw; } } } void PIXCfgParser::static_starts_with_hostaddr() { try { // for error handling static_mapped_addr_match(); static_real_addr_match(); { // ( ... )* for (;;) { if ((_tokenSet_42.member(LA(1)))) { static_command_common_last_parameters(); } else { goto _loop268; } } _loop268:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::static_starts_with_tcp_udp() { ANTLR_USE_NAMESPACE(antlr)RefToken acl_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } if ( inputState->guessing==0 ) { #line 2216 "pix.g" importer->protocol = LT(0)->getText(); *dbg << " SERVICE TCP/UDP " << LT(0)->getText() << " "; #line 7088 "PIXCfgParser.cpp" } static_mapped_addr_match(); tcp_udp_port_spec(); if ( inputState->guessing==0 ) { #line 2230 "pix.g" importer->mapped_port_spec = importer->tmp_port_spec_2; *dbg << "mapped port " << importer->mapped_port_spec << " "; #line 7098 "PIXCfgParser.cpp" } { switch ( LA(1)) { case IPV4: case IPV6: { single_addr(); if ( inputState->guessing==0 ) { #line 2240 "pix.g" importer->real_a = importer->tmp_a; importer->real_nm = importer->tmp_nm; *dbg << "real: " << importer->real_a; #line 7113 "PIXCfgParser.cpp" } tcp_udp_port_spec(); if ( inputState->guessing==0 ) { #line 2251 "pix.g" importer->real_port_spec = importer->tmp_port_spec_2; *dbg << "real port " << importer->real_port_spec << " "; #line 7122 "PIXCfgParser.cpp" } break; } case ACCESS_LIST: { match(ACCESS_LIST); acl_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 2258 "pix.g" importer->real_addr_acl = acl_name->getText(); *dbg << "real: " << importer->real_addr_acl; #line 7137 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { // ( ... )* for (;;) { if ((_tokenSet_42.member(LA(1)))) { static_command_common_last_parameters(); } else { goto _loop277; } } _loop277:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_9); } else { throw; } } } void PIXCfgParser::static_mapped_addr_match() { try { // for error handling { switch ( LA(1)) { case IPV4: case IPV6: { single_addr(); if ( inputState->guessing==0 ) { #line 2183 "pix.g" importer->mapped_a = importer->tmp_a; importer->mapped_nm = importer->tmp_nm; *dbg << "mapped: " << importer->mapped_a; #line 7186 "PIXCfgParser.cpp" } break; } case INTRFACE: { match(INTRFACE); if ( inputState->guessing==0 ) { #line 2190 "pix.g" importer->mapped_a = "interface"; importer->mapped_nm = ""; *dbg << "mapped: " << importer->mapped_a; #line 7200 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_43); } else { throw; } } } void PIXCfgParser::static_real_addr_match() { ANTLR_USE_NAMESPACE(antlr)RefToken acl_name = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling { switch ( LA(1)) { case IPV4: case IPV6: { single_addr(); if ( inputState->guessing==0 ) { #line 2201 "pix.g" importer->real_a = importer->tmp_a; importer->real_nm = importer->tmp_nm; *dbg << "real: " << importer->real_a; #line 7238 "PIXCfgParser.cpp" } break; } case ACCESS_LIST: { match(ACCESS_LIST); acl_name = LT(1); match(WORD); if ( inputState->guessing==0 ) { #line 2208 "pix.g" importer->real_addr_acl = acl_name->getText(); *dbg << "real: " << importer->real_addr_acl; #line 7253 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_44); } else { throw; } } } void PIXCfgParser::static_command_common_last_parameters() { ANTLR_USE_NAMESPACE(antlr)RefToken nm = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling switch ( LA(1)) { case INT_CONST: case TCP: case UDP: case DNS: case NORANDOMSEQ: { nat_and_static_command_common_last_parameters(); break; } case NETMASK: { match(NETMASK); nm = LT(1); match(IPV4); if ( inputState->guessing==0 ) { #line 2290 "pix.g" importer->real_nm = nm->getText(); *dbg << "real netmask: " << importer->real_nm; #line 7299 "PIXCfgParser.cpp" } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { if( inputState->guessing == 0 ) { reportError(ex); recover(ex,_tokenSet_44); } else { throw; } } } void PIXCfgParser::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* PIXCfgParser::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "NEWLINE", "\"quit\"", "\"ip\"", "\"community-list\"", "\"timeout\"", "\"pim\"", "\"network\"", "\"names\"", "\"name\"", "IPV4", "WORD", "IPV6", "\"ah\"", "\"eigrp\"", "\"esp\"", "\"gre\"", "\"igmp\"", "\"igrp\"", "\"ipinip\"", "\"ipsec\"", "\"nos\"", "\"ospf\"", "\"pcp\"", "\"pptp\"", "\"snp\"", "\"object\"", "\"description\"", "\"host\"", "\"range\"", "\"subnet\"", "\"service\"", "\"http\"", "\"ssh\"", "\"telnet\"", "\"icmp\"", "INT_CONST", "\"icmp6\"", "\"tcp\"", "\"udp\"", "\"source\"", "\"destination\"", "\"object-group\"", "\"group-object\"", "\"network-object\"", "\"protocol\"", "\"protocol-object\"", "\"icmp-object\"", "\"icmp-type\"", "\"tcp-udp\"", "\"service-object\"", "\"port-object\"", "\"crypto\"", "\"dns\"", "\"call-home\"", "\"internal\"", "\"password-recovery\"", "\"resetinbound\"", "\"resetoutbound\"", "\"resetoutside\"", "\"no\"", "\"certificate\"", "\"PIX\"", "\"ASA\"", "\"FWSM\"", "\"Version\"", "NUMBER", "\"hostname\"", "STRING", "\"access-list\"", "\"extended\"", "\"permit\"", "\"deny\"", "\"standard\"", "\"eq\"", "\"gt\"", "\"lt\"", "\"neq\"", "\"echo\"", "\"established\"", "\"alternate-address\"", "\"conversion-error\"", "\"echo-reply\"", "\"information-reply\"", "\"information-request\"", "\"mask-reply\"", "\"mask-request\"", "\"mobile-redirect\"", "\"parameter-problem\"", "\"redirect\"", "\"router-advertisement\"", "\"router-solicitation\"", "\"source-quench\"", "\"time-exceeded\"", "\"timestamp-reply\"", "\"timestamp-request\"", "\"traceroute\"", "\"unreachable\"", "\"interface\"", "\"any\"", "\"log\"", "\"log-input\"", "\"alerts\"", "\"critical\"", "\"debugging\"", "\"emergencies\"", "\"errors\"", "\"informational\"", "\"notifications\"", "\"warnings\"", "\"disable\"", "\"inactive\"", "\"interval\"", "\"fragments\"", "\"time-range\"", "\"controller\"", "\"outside\"", "LINE_COMMENT", "\"exit\"", "\"aui\"", "\"auto\"", "\"bnc\"", "\"full\"", "\"baseT\"", "\"baseTX\"", "\"nameif\"", "\"vlan\"", "\"speed\"", "\"duplex\"", "\"ddns\"", "\"forward\"", "\"delay\"", "\"hold-time\"", "\"ipv6\"", "\"management-only\"", "\"mac-address\"", "\"multicast\"", "PPPOE", "\"rip\"", "\"security-level\"", "\"shutdown\"", "\"address\"", "\"dhcp\"", "\"standby\"", "\"switchport\"", "\"access\"", "\"scopy\"", "\"version\"", "\"authentication-certificate\"", "\"server\"", "\"remark\"", "\"access-group\"", "COLON_COMMENT", "\"nat\"", "OPENING_PAREN", "CLOSING_PAREN", "COMMA", "\"global\"", "MINUS", "\"netmask\"", "\"static\"", "\"norandomseq\"", "\"secondary\"", "\"setroute\"", "Whitespace", "HEX_CONST", "NEG_INT_CONST", "DIGIT", "HEXDIGIT", "NUMBER_ADDRESS_OR_WORD", "PIPE_CHAR", "NUMBER_SIGN", "PERCENT", "AMPERSAND", "APOSTROPHE", "STAR", "PLUS", "DOT", "SLASH", "COLON", "SEMICOLON", "LESS_THAN", "EQUALS", "GREATER_THAN", "QUESTION", "COMMERCIAL_AT", "OPENING_SQUARE", "CLOSING_SQUARE", "CARET", "UNDERLINE", "OPENING_BRACE", "CLOSING_BRACE", "TILDE", "EXLAMATION", 0 }; const unsigned long PIXCfgParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_0(_tokenSet_0_data_,8); const unsigned long PIXCfgParser::_tokenSet_1_data_[] = { 536895346UL, 2172657788UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "service" "http" "ssh" "telnet" "icmp" "object-group" "crypto" // "dns" "no" "certificate" "PIX" "ASA" "FWSM" "hostname" "access-list" // "interface" "controller" LINE_COMMENT "exit" "nameif" "access-group" // COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_1(_tokenSet_1_data_,12); const unsigned long PIXCfgParser::_tokenSet_2_data_[] = { 0UL, 128UL, 0UL, 469762048UL, 0UL, 0UL, 0UL, 0UL }; // INT_CONST "aui" "auto" "bnc" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_2(_tokenSet_2_data_,8); const unsigned long PIXCfgParser::_tokenSet_3_data_[] = { 1073676864UL, 10048UL, 1024UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "ip" "pim" "ah" "eigrp" "esp" "gre" "igmp" "igrp" "ipinip" "ipsec" "nos" // "ospf" "pcp" "pptp" "snp" "object" "icmp" "icmp6" "tcp" "udp" "object-group" // "permit" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_3(_tokenSet_3_data_,8); const unsigned long PIXCfgParser::_tokenSet_4_data_[] = { 1073676864UL, 10048UL, 2048UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "ip" "pim" "ah" "eigrp" "esp" "gre" "igmp" "igrp" "ipinip" "ipsec" "nos" // "ospf" "pcp" "pptp" "snp" "object" "icmp" "icmp6" "tcp" "udp" "object-group" // "deny" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_4(_tokenSet_4_data_,8); const unsigned long PIXCfgParser::_tokenSet_5_data_[] = { 3758120818UL, 2172657791UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "host" "range" "subnet" "service" "http" "ssh" // "telnet" "icmp" "object-group" "crypto" "dns" "no" "certificate" "PIX" // "ASA" "FWSM" "hostname" "access-list" "interface" "controller" LINE_COMMENT // "exit" "nameif" "access-group" COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_5(_tokenSet_5_data_,12); const unsigned long PIXCfgParser::_tokenSet_6_data_[] = { 536822336UL, 1984UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "ip" "pim" WORD "ah" "eigrp" "esp" "gre" "igmp" "igrp" "ipinip" "ipsec" // "nos" "ospf" "pcp" "pptp" "snp" "icmp" INT_CONST "icmp6" "tcp" "udp" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_6(_tokenSet_6_data_,8); const unsigned long PIXCfgParser::_tokenSet_7_data_[] = { 1073741824UL, 6307840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "description" "group-object" "service-object" "port-object" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_7(_tokenSet_7_data_,8); const unsigned long PIXCfgParser::_tokenSet_8_data_[] = { 2684362768UL, 8192UL, 0UL, 96UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 "object" "host" "object-group" "interface" "any" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_8(_tokenSet_8_data_,8); const unsigned long PIXCfgParser::_tokenSet_9_data_[] = { 16UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_9(_tokenSet_9_data_,8); const unsigned long PIXCfgParser::_tokenSet_10_data_[] = { 134275088UL, 16778936UL, 131392UL, 8388608UL, 0UL, 22UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 WORD IPV6 "pptp" "http" "ssh" "telnet" INT_CONST "tcp" // "udp" "dns" "hostname" "access-list" "echo" "outside" MINUS "netmask" // "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_10(_tokenSet_10_data_,12); const unsigned long PIXCfgParser::_tokenSet_11_data_[] = { 536805952UL, 128UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "ip" "pim" "ah" "eigrp" "esp" "gre" "igmp" "igrp" "ipinip" "ipsec" "nos" // "ospf" "pcp" "pptp" "snp" INT_CONST const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_11(_tokenSet_11_data_,8); const unsigned long PIXCfgParser::_tokenSet_12_data_[] = { 1610637170UL, 2172657788UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "service" "http" "ssh" "telnet" "icmp" "object-group" // "crypto" "dns" "no" "certificate" "PIX" "ASA" "FWSM" "hostname" "access-list" // "interface" "controller" LINE_COMMENT "exit" "nameif" "access-group" // COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_12(_tokenSet_12_data_,12); const unsigned long PIXCfgParser::_tokenSet_13_data_[] = { 16UL, 0UL, 0UL, 3146112UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "log" "log-input" "fragments" "time-range" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_13(_tokenSet_13_data_,8); const unsigned long PIXCfgParser::_tokenSet_14_data_[] = { 16UL, 4097UL, 122880UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "range" "destination" "eq" "gt" "lt" "neq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_14(_tokenSet_14_data_,8); const unsigned long PIXCfgParser::_tokenSet_15_data_[] = { 2684362768UL, 12289UL, 385024UL, 3146208UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 "object" "host" "range" "destination" "object-group" "eq" // "gt" "lt" "neq" "established" "interface" "any" "log" "log-input" "fragments" // "time-range" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_15(_tokenSet_15_data_,8); const unsigned long PIXCfgParser::_tokenSet_16_data_[] = { 1610637170UL, 2172706940UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "service" "http" "ssh" "telnet" "icmp" "object-group" // "group-object" "network-object" "crypto" "dns" "no" "certificate" "PIX" // "ASA" "FWSM" "hostname" "access-list" "interface" "controller" LINE_COMMENT // "exit" "nameif" "access-group" COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_16(_tokenSet_16_data_,12); const unsigned long PIXCfgParser::_tokenSet_17_data_[] = { 1610637170UL, 2172805244UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "service" "http" "ssh" "telnet" "icmp" "object-group" // "group-object" "protocol-object" "crypto" "dns" "no" "certificate" "PIX" // "ASA" "FWSM" "hostname" "access-list" "interface" "controller" LINE_COMMENT // "exit" "nameif" "access-group" COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_17(_tokenSet_17_data_,12); const unsigned long PIXCfgParser::_tokenSet_18_data_[] = { 1610637170UL, 2172936316UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "service" "http" "ssh" "telnet" "icmp" "object-group" // "group-object" "icmp-object" "crypto" "dns" "no" "certificate" "PIX" // "ASA" "FWSM" "hostname" "access-list" "interface" "controller" LINE_COMMENT // "exit" "nameif" "access-group" COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_18(_tokenSet_18_data_,12); const unsigned long PIXCfgParser::_tokenSet_19_data_[] = { 1610637170UL, 2178965628UL, 335UL, 54525984UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "service" "http" "ssh" "telnet" "icmp" "object-group" // "group-object" "service-object" "port-object" "crypto" "dns" "no" "certificate" // "PIX" "ASA" "FWSM" "hostname" "access-list" "interface" "controller" // LINE_COMMENT "exit" "nameif" "access-group" COLON_COMMENT "nat" "global" // "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_19(_tokenSet_19_data_,12); const unsigned long PIXCfgParser::_tokenSet_20_data_[] = { 2684379152UL, 8321UL, 4294959104UL, 11534847UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 WORD "object" "host" "range" INT_CONST "object-group" "eq" // "gt" "lt" "neq" "echo" "established" "alternate-address" "conversion-error" // "echo-reply" "information-reply" "information-request" "mask-reply" // "mask-request" "mobile-redirect" "parameter-problem" "redirect" "router-advertisement" // "router-solicitation" "source-quench" "time-exceeded" "timestamp-reply" // "timestamp-request" "traceroute" "unreachable" "interface" "any" "log" // "log-input" "fragments" "time-range" "outside" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_20(_tokenSet_20_data_,8); const unsigned long PIXCfgParser::_tokenSet_21_data_[] = { 2684362752UL, 8192UL, 0UL, 96UL, 0UL, 0UL, 0UL, 0UL }; // IPV4 "object" "host" "object-group" "interface" "any" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_21(_tokenSet_21_data_,8); const unsigned long PIXCfgParser::_tokenSet_22_data_[] = { 16UL, 0UL, 0UL, 1048960UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "log" "log-input" "fragments" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_22(_tokenSet_22_data_,8); const unsigned long PIXCfgParser::_tokenSet_23_data_[] = { 16UL, 0UL, 0UL, 384UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "log" "log-input" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_23(_tokenSet_23_data_,8); const unsigned long PIXCfgParser::_tokenSet_24_data_[] = { 536895504UL, 8193UL, 385024UL, 11534720UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 WORD "object" "range" "object-group" "eq" "gt" "lt" "neq" // "established" "log" "log-input" "fragments" "time-range" "outside" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_24(_tokenSet_24_data_,8); const unsigned long PIXCfgParser::_tokenSet_25_data_[] = { 0UL, 1UL, 122880UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "range" "eq" "gt" "lt" "neq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_25(_tokenSet_25_data_,8); const unsigned long PIXCfgParser::_tokenSet_26_data_[] = { 134234112UL, 184UL, 131136UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD "pptp" "http" "ssh" "telnet" INT_CONST "hostname" "echo" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_26(_tokenSet_26_data_,8); const unsigned long PIXCfgParser::_tokenSet_27_data_[] = { 536870928UL, 8193UL, 385024UL, 3146112UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "object" "range" "object-group" "eq" "gt" "lt" "neq" "established" // "log" "log-input" "fragments" "time-range" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_27(_tokenSet_27_data_,8); const unsigned long PIXCfgParser::_tokenSet_28_data_[] = { 671113074UL, 2172657917UL, 516431UL, 58720160UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "pptp" "object" "range" "service" "http" "ssh" "telnet" "icmp" INT_CONST // "object-group" "crypto" "dns" "no" "certificate" "PIX" "ASA" "FWSM" // "hostname" "access-list" "eq" "gt" "lt" "neq" "echo" "established" "interface" // "log" "log-input" "alerts" "critical" "debugging" "emergencies" "errors" // "informational" "notifications" "warnings" "disable" "inactive" "interval" // "fragments" "time-range" "controller" LINE_COMMENT "exit" "nameif" "access-group" // COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_28(_tokenSet_28_data_,12); const unsigned long PIXCfgParser::_tokenSet_29_data_[] = { 671113074UL, 2172657916UL, 131407UL, 58720160UL, 469762049UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "pptp" "object" "service" "http" "ssh" "telnet" "icmp" INT_CONST "object-group" // "crypto" "dns" "no" "certificate" "PIX" "ASA" "FWSM" "hostname" "access-list" // "echo" "interface" "log" "log-input" "alerts" "critical" "debugging" // "emergencies" "errors" "informational" "notifications" "warnings" "disable" // "inactive" "interval" "fragments" "time-range" "controller" LINE_COMMENT // "exit" "nameif" "access-group" COLON_COMMENT "nat" "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_29(_tokenSet_29_data_,12); const unsigned long PIXCfgParser::_tokenSet_30_data_[] = { 2684362752UL, 8193UL, 122880UL, 96UL, 0UL, 0UL, 0UL, 0UL }; // IPV4 "object" "host" "range" "object-group" "eq" "gt" "lt" "neq" "interface" // "any" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_30(_tokenSet_30_data_,8); const unsigned long PIXCfgParser::_tokenSet_31_data_[] = { 671113232UL, 8377UL, 516160UL, 11534720UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 WORD "pptp" "object" "range" "http" "ssh" "telnet" INT_CONST // "object-group" "hostname" "eq" "gt" "lt" "neq" "echo" "established" // "log" "log-input" "fragments" "time-range" "outside" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_31(_tokenSet_31_data_,8); const unsigned long PIXCfgParser::_tokenSet_32_data_[] = { 2818629648UL, 16791225UL, 516416UL, 3146208UL, 0UL, 20UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE IPV4 WORD IPV6 "pptp" "object" "host" "range" "http" "ssh" "telnet" // INT_CONST "tcp" "udp" "destination" "object-group" "dns" "hostname" // "access-list" "eq" "gt" "lt" "neq" "echo" "established" "interface" // "any" "log" "log-input" "fragments" "time-range" "netmask" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_32(_tokenSet_32_data_,12); const unsigned long PIXCfgParser::_tokenSet_33_data_[] = { 2684387186UL, 2172657917UL, 4294959439UL, 66060799UL, 3691118593UL, 9UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" IPV4 // WORD "object" "host" "range" "service" "http" "ssh" "telnet" "icmp" // INT_CONST "object-group" "crypto" "dns" "no" "certificate" "PIX" "ASA" // "FWSM" "hostname" "access-list" "eq" "gt" "lt" "neq" "echo" "established" // "alternate-address" "conversion-error" "echo-reply" "information-reply" // "information-request" "mask-reply" "mask-request" "mobile-redirect" // "parameter-problem" "redirect" "router-advertisement" "router-solicitation" // "source-quench" "time-exceeded" "timestamp-reply" "timestamp-request" // "traceroute" "unreachable" "interface" "any" "log" "log-input" "fragments" // "time-range" "controller" "outside" LINE_COMMENT "exit" "nameif" "dhcp" // "access-group" COLON_COMMENT "nat" CLOSING_PAREN COMMA "global" "static" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_33(_tokenSet_33_data_,12); const unsigned long PIXCfgParser::_tokenSet_34_data_[] = { 1108345408UL, 2147483648UL, 0UL, 0UL, 589823UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "ip" "pim" "igmp" "ospf" "description" "no" "nameif" "vlan" "speed" // "duplex" "ddns" "forward" "delay" "hold-time" "ipv6" "management-only" // "mac-address" "multicast" PPPOE "rip" "security-level" "shutdown" "switchport" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_34(_tokenSet_34_data_,12); const unsigned long PIXCfgParser::_tokenSet_35_data_[] = { 1108345408UL, 2147483648UL, 0UL, 50331648UL, 589823UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "ip" "pim" "igmp" "ospf" "description" "no" LINE_COMMENT "exit" "nameif" // "vlan" "speed" "duplex" "ddns" "forward" "delay" "hold-time" "ipv6" // "management-only" "mac-address" "multicast" PPPOE "rip" "security-level" // "shutdown" "switchport" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_35(_tokenSet_35_data_,12); const unsigned long PIXCfgParser::_tokenSet_36_data_[] = { 16384UL, 0UL, 0UL, 8388608UL, 0UL, 0UL, 0UL, 0UL }; // WORD "outside" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_36(_tokenSet_36_data_,8); const unsigned long PIXCfgParser::_tokenSet_37_data_[] = { 0UL, 16778880UL, 0UL, 8388608UL, 0UL, 16UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // INT_CONST "tcp" "udp" "dns" "outside" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_37(_tokenSet_37_data_,12); const unsigned long PIXCfgParser::_tokenSet_38_data_[] = { 16UL, 16778880UL, 0UL, 8388608UL, 0UL, 16UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE INT_CONST "tcp" "udp" "dns" "outside" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_38(_tokenSet_38_data_,12); const unsigned long PIXCfgParser::_tokenSet_39_data_[] = { 3758120818UL, 2172659455UL, 335UL, 62914592UL, 469762049UL, 25UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" WORD // "object" "description" "host" "range" "subnet" "service" "http" "ssh" // "telnet" "icmp" INT_CONST "tcp" "udp" "object-group" "crypto" "dns" // "no" "certificate" "PIX" "ASA" "FWSM" "hostname" "access-list" "interface" // "controller" "outside" LINE_COMMENT "exit" "nameif" "access-group" COLON_COMMENT // "nat" "global" "static" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_39(_tokenSet_39_data_,12); const unsigned long PIXCfgParser::_tokenSet_40_data_[] = { 16UL, 16778880UL, 0UL, 8388608UL, 0UL, 20UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE INT_CONST "tcp" "udp" "dns" "outside" "netmask" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_40(_tokenSet_40_data_,12); const unsigned long PIXCfgParser::_tokenSet_41_data_[] = { 3758129010UL, 2172659455UL, 335UL, 62914592UL, 469762049UL, 29UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE "quit" "ip" "timeout" "pim" "network" "names" "name" IPV4 // WORD "object" "description" "host" "range" "subnet" "service" "http" // "ssh" "telnet" "icmp" INT_CONST "tcp" "udp" "object-group" "crypto" // "dns" "no" "certificate" "PIX" "ASA" "FWSM" "hostname" "access-list" // "interface" "controller" "outside" LINE_COMMENT "exit" "nameif" "access-group" // COLON_COMMENT "nat" "global" "netmask" "static" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_41(_tokenSet_41_data_,12); const unsigned long PIXCfgParser::_tokenSet_42_data_[] = { 0UL, 16778880UL, 0UL, 0UL, 0UL, 20UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // INT_CONST "tcp" "udp" "dns" "netmask" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_42(_tokenSet_42_data_,12); const unsigned long PIXCfgParser::_tokenSet_43_data_[] = { 134275072UL, 184UL, 131392UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // IPV4 WORD IPV6 "pptp" "http" "ssh" "telnet" INT_CONST "hostname" "access-list" // "echo" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_43(_tokenSet_43_data_,8); const unsigned long PIXCfgParser::_tokenSet_44_data_[] = { 16UL, 16778880UL, 0UL, 0UL, 0UL, 20UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE INT_CONST "tcp" "udp" "dns" "netmask" "norandomseq" const ANTLR_USE_NAMESPACE(antlr)BitSet PIXCfgParser::_tokenSet_44(_tokenSet_44_data_,12); fwbuilder-5.1.0.3599/src/parsers/IOSCfgParser.hpp0000644000175000017500000001302711733011756022207 0ustar sylvestresylvestre#ifndef INC_IOSCfgParser_hpp_ #define INC_IOSCfgParser_hpp_ #line 27 "iosacl.g" // gets inserted before antlr generated includes in the header // file #include "IOSImporter.h" #line 11 "IOSCfgParser.hpp" #include /* $ANTLR 2.7.7 (20090306): "iosacl.g" -> "IOSCfgParser.hpp"$ */ #include #include #include "IOSCfgParserTokenTypes.hpp" #include #line 33 "iosacl.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class IOSImporter; #line 28 "IOSCfgParser.hpp" #line 57 "iosacl.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 34 "IOSCfgParser.hpp" class CUSTOM_API IOSCfgParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public IOSCfgParserTokenTypes { #line 74 "iosacl.g" // additional methods and members public: std::ostream *dbg; IOSImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); } #line 38 "IOSCfgParser.hpp" public: void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory ); protected: IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k); public: IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf); protected: IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k); public: IOSCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer); IOSCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state); int getNumTokens() const { return IOSCfgParser::NUM_TOKENS; } const char* getTokenName( int type ) const { if( type > getNumTokens() ) return 0; return IOSCfgParser::tokenNames[type]; } const char* const* getTokenNames() const { return IOSCfgParser::tokenNames; } public: void cfgfile(); public: void comment(); public: void version(); public: void hostname(); public: void ip_commands(); public: void intrface(); public: void controller(); public: void vlan(); public: void access_list_commands(); public: void exit(); public: void description(); public: void shutdown(); public: void certificate(); public: void quit(); public: void unknown_command(); public: void ip_access_list_ext(); public: void interface_known_ip_commands(); public: void community_list_command(); public: void ip_unused_command(); public: void permit_std(); public: void deny_std(); public: void permit_ext(); public: void deny_ext(); public: void remark(); public: void rule_ext(); public: void rule_std(); public: void ip_protocols(); public: void hostaddr_ext(); public: void time_range(); public: void fragments(); public: void log(); public: void icmp_spec(); public: void xoperator(); public: void established(); public: void hostaddr_std(); public: void single_port_op(); public: void port_range(); public: void port_spec(); public: void access_group_by_name(); public: void access_group_by_number(); public: void intf_address(); public: ANTLR_USE_NAMESPACE(antlr)RefAST getAST() { return returnAST; } protected: ANTLR_USE_NAMESPACE(antlr)RefAST returnAST; private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS static const int NUM_TOKENS = 80; #else enum { NUM_TOKENS = 80 }; #endif static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; static const unsigned long _tokenSet_7_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_7; static const unsigned long _tokenSet_8_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_8; static const unsigned long _tokenSet_9_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_9; static const unsigned long _tokenSet_10_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_10; static const unsigned long _tokenSet_11_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_11; static const unsigned long _tokenSet_12_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_12; static const unsigned long _tokenSet_13_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_13; static const unsigned long _tokenSet_14_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_14; }; #endif /*INC_IOSCfgParser_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PFCfgParser.cpp0000644000175000017500000046004111733011756022057 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20100319): "pf.g" -> "PFCfgParser.cpp"$ */ #line 43 "pf.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "PFCfgParser.cpp" #include "PFCfgParser.hpp" #include #include #include #line 49 "pf.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 20 "PFCfgParser.cpp" #line 1 "pf.g" #line 22 "PFCfgParser.cpp" PFCfgParser::PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,k) { } PFCfgParser::PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,2) { } PFCfgParser::PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,k) { } PFCfgParser::PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,2) { } PFCfgParser::PFCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)LLkParser(state,2) { } void PFCfgParser::cfgfile() { try { // for error handling { // ( ... )* for (;;) { switch ( LA(1)) { case COMMENT_START: { comment(); break; } case INCLUDE_COMMAND: { include_command(); break; } case WORD: { macro_definition(); break; } case ALTQ: { altq_rule(); break; } case ANTISPOOF: { antispoof_rule(); break; } case QUEUE: { queue_rule(); break; } case SET: { set_rule(); break; } case SCRUB: { scrub_rule(); break; } case MATCH: { match_rule(); break; } case TABLE: { table_rule(); break; } case NO: { no_nat_rule(); break; } case NAT: { nat_rule(); break; } case RDR: { rdr_rule(); break; } case BINAT: { binat_rule(); break; } case PASS: { pass_rule(); break; } case BLOCK: { block_rule(); break; } case NEWLINE: { match(NEWLINE); break; } default: { goto _loop3; } } } _loop3:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void PFCfgParser::comment() { try { // for error handling match(COMMENT_START); #line 159 "pf.g" QStringList str; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { str << QString::fromUtf8(LT(1)->getText().c_str()); consume(); } importer->last_comment << str.join(" "); #line 169 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::include_command() { try { // for error handling match(INCLUDE_COMMAND); #line 173 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'include' commands is not supported.")); consumeUntil(NEWLINE); #line 189 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::macro_definition() { try { // for error handling match(WORD); match(EQUAL); #line 184 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); consumeUntil(NEWLINE); #line 208 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::altq_rule() { try { // for error handling match(ALTQ); #line 204 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->error_tracker->registerError( QString("import of 'altq' commands is not supported.")); consumeUntil(NEWLINE); #line 228 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::antispoof_rule() { try { // for error handling match(ANTISPOOF); #line 193 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Warning: import of 'antispoof' commands has not been implemented yet.")); consumeUntil(NEWLINE); #line 248 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::queue_rule() { try { // for error handling match(QUEUE); #line 215 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->error_tracker->registerError( QString("import of 'queue' commands is not supported.")); consumeUntil(NEWLINE); #line 268 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_rule() { try { // for error handling match(SET); #line 226 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 285 "PFCfgParser.cpp" { switch ( LA(1)) { case TIMEOUT: { set_timeout(); break; } case 14: { set_ruleset_optimization(); break; } case LITERAL_optimization: { set_optimization(); break; } case LITERAL_limit: { set_limit(); break; } case LITERAL_loginterface: { set_loginterface(); break; } case 23: { set_block_policy(); break; } case 26: { set_state_policy(); break; } case 29: { set_state_defaults(); break; } case 30: { set_require_order(); break; } case LITERAL_fingerprints: { set_fingerprints(); break; } case LITERAL_skip: { set_skip(); break; } case LITERAL_debug: { set_debug(); break; } case LITERAL_reassemble: { set_reassemble(); break; } case LITERAL_hostid: { set_hostid(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::scrub_rule() { try { // for error handling match(SCRUB); #line 525 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "scrub"; *dbg << LT(1)->getLine() << ":" << " scrub "; #line 383 "PFCfgParser.cpp" rule_extended(); match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::match_rule() { try { // for error handling match(MATCH); #line 540 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "match"; *dbg << LT(1)->getLine() << ":" << " match "; #line 405 "PFCfgParser.cpp" rule_extended(); #line 548 "pf.g" if ( ! importer->scrub_rule) importer->pushRule(); #line 411 "PFCfgParser.cpp" match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::table_rule() { ANTLR_USE_NAMESPACE(antlr)RefToken name = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken file = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(TABLE); #line 557 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); #line 431 "PFCfgParser.cpp" match(LESS_THAN); name = LT(1); match(WORD); match(GREATER_THAN); { switch ( LA(1)) { case PERSIST: { match(PERSIST); break; } case NEWLINE: case OPENING_BRACE: case CONST_WORD: case COUNTERS: case FILE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case CONST_WORD: { match(CONST_WORD); #line 569 "pf.g" importer->addMessageToLog( QString("Warning: attribute \"const\" will be dropped from table configuration since this attribute is not supported at this time")); #line 467 "PFCfgParser.cpp" break; } case NEWLINE: case OPENING_BRACE: case COUNTERS: case FILE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case COUNTERS: { match(COUNTERS); #line 576 "pf.g" importer->addMessageToLog( QString("Warning: attribute \"counters\" will be dropped from table configuration since this attribute is not supported at this time")); #line 493 "PFCfgParser.cpp" break; } case NEWLINE: case OPENING_BRACE: case FILE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case FILE: { match(FILE); file = LT(1); match(STRING); #line 583 "pf.g" importer->newAddressTableObject( name->getText(), file->getText()); #line 520 "PFCfgParser.cpp" break; } case OPENING_BRACE: { match(OPENING_BRACE); tableaddr_spec(); { // ( ... )* for (;;) { if ((_tokenSet_2.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case WORD: case INT_CONST: case EXLAMATION: case SELF: case IPV4: case NUMBER: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } tableaddr_spec(); } else { goto _loop58; } } _loop58:; } // ( ... )* match(CLOSING_BRACE); #line 595 "pf.g" importer->newAddressTableObject( name->getText(), importer->tmp_group); #line 567 "PFCfgParser.cpp" break; } case NEWLINE: { match(NEWLINE); #line 601 "pf.g" // Special case: table definition without file name or list of addresses. // Create run-time AddressTable object with name but no file spec. importer->newAddressTableObject(name->getText(), ""); #line 579 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::no_nat_rule() { try { // for error handling match(NO); #line 676 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNATRule(); importer->action = "nonat"; *dbg << LT(1)->getLine() << ":" << " nonat "; #line 607 "PFCfgParser.cpp" { switch ( LA(1)) { case NAT: { nat_rule(); break; } case RDR: { rdr_rule(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::nat_rule() { try { // for error handling match(NAT); #line 693 "pf.g" if ( importer->action != "nonat" ) { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNATRule(); importer->action = "nat"; *dbg << LT(1)->getLine() << ":" << " nat "; } #line 648 "PFCfgParser.cpp" { switch ( LA(1)) { case PASS: { match(PASS); #line 705 "pf.g" importer->error_tracker->registerError( QString("import of 'nat pass' commands is not supported.")); #line 659 "PFCfgParser.cpp" { switch ( LA(1)) { case LOG: { logging(); break; } case NEWLINE: case ON: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: case ON: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ON: { intrface(); break; } case NEWLINE: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case INET: case INET6: { address_family(); break; } case NEWLINE: case EXLAMATION: case MINUS: case ALL: case TO: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case PROTO: { protospec(); break; } case NEWLINE: case EXLAMATION: case MINUS: case ALL: case TO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } hosts(); { switch ( LA(1)) { case EXLAMATION: case TAGGED: { tagged(); break; } case NEWLINE: case MINUS: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case TAG: { tag_clause(); #line 718 "pf.g" importer->error_tracker->registerError( QString("import of 'nat ... tag' commands is not supported.")); #line 819 "PFCfgParser.cpp" break; } case NEWLINE: case MINUS: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case MINUS: { match(MINUS); match(GREATER_THAN); { switch ( LA(1)) { case WORD: case IPV4: case OPENING_PAREN: { redirhost(); break; } case OPENING_BRACE: { redirhost_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 726 "pf.g" importer->nat_group = importer->tmp_group; #line 863 "PFCfgParser.cpp" { switch ( LA(1)) { case PORT: { portspec(); #line 731 "pf.g" importer->nat_port_group = importer->tmp_port_group; #line 873 "PFCfgParser.cpp" break; } case NEWLINE: case STATIC_PORT: case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { pooltype(); break; } case NEWLINE: case STATIC_PORT: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case STATIC_PORT: { match(STATIC_PORT); #line 737 "pf.g" importer->nat_rule_opt_2 = "static-port"; #line 919 "PFCfgParser.cpp" break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 740 "pf.g" importer->pushRule(); #line 948 "PFCfgParser.cpp" match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::rdr_rule() { try { // for error handling match(RDR); #line 749 "pf.g" if ( importer->action != "nonat" ) { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNATRule(); importer->action = "rdr"; *dbg << LT(1)->getLine() << ":" << " rdr "; } #line 972 "PFCfgParser.cpp" { switch ( LA(1)) { case PASS: { match(PASS); #line 761 "pf.g" importer->error_tracker->registerError( QString("import of 'nat pass' commands is not supported.")); #line 983 "PFCfgParser.cpp" { switch ( LA(1)) { case LOG: { logging(); break; } case NEWLINE: case ON: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: case ON: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ON: { intrface(); break; } case NEWLINE: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case INET: case INET6: { address_family(); break; } case NEWLINE: case EXLAMATION: case MINUS: case ALL: case TO: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case PROTO: { protospec(); break; } case NEWLINE: case EXLAMATION: case MINUS: case ALL: case TO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } hosts(); { switch ( LA(1)) { case EXLAMATION: case TAGGED: { tagged(); break; } case NEWLINE: case MINUS: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case TAG: { tag_clause(); #line 774 "pf.g" importer->error_tracker->registerError( QString("import of 'nat ... tag' commands is not supported.")); #line 1143 "PFCfgParser.cpp" break; } case NEWLINE: case MINUS: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case MINUS: { match(MINUS); match(GREATER_THAN); { switch ( LA(1)) { case WORD: case IPV4: case OPENING_PAREN: { redirhost(); break; } case OPENING_BRACE: { redirhost_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 782 "pf.g" importer->nat_group = importer->tmp_group; #line 1187 "PFCfgParser.cpp" { switch ( LA(1)) { case PORT: { portspec(); #line 787 "pf.g" importer->nat_port_group = importer->tmp_port_group; #line 1197 "PFCfgParser.cpp" break; } case NEWLINE: case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { pooltype(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 793 "pf.g" importer->pushRule(); #line 1250 "PFCfgParser.cpp" match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::binat_rule() { try { // for error handling match(BINAT); #line 925 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->error_tracker->registerError( QString("import of 'binat' commands is not supported.")); consumeUntil(NEWLINE); #line 1271 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::pass_rule() { try { // for error handling match(PASS); #line 948 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "pass"; *dbg << LT(1)->getLine() << ":" << " pass "; #line 1291 "PFCfgParser.cpp" rule_extended(); #line 956 "pf.g" importer->pushRule(); #line 1297 "PFCfgParser.cpp" match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::block_rule() { try { // for error handling match(BLOCK); #line 963 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "block"; *dbg << LT(1)->getLine() << ":" << " block "; #line 1318 "PFCfgParser.cpp" { switch ( LA(1)) { case DROP: case RETURN: case RETURN_RST: case RETURN_ICMP: case RETURN_ICMP6: { block_return(); break; } case NEWLINE: case QUEUE: case ON: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case IN_WORD: case OUT_WORD: case LOG: case QUICK: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } rule_extended(); #line 972 "pf.g" importer->pushRule(); #line 1381 "PFCfgParser.cpp" match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_timeout() { try { // for error handling match(TIMEOUT); { switch ( LA(1)) { case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case LITERAL_frag: case LITERAL_interval: case 56: case 57: case 58: { timeout_def(); break; } case OPENING_BRACE: { timeout_def_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_ruleset_optimization() { try { // for error handling match(14); #line 269 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set ruleset-optimization' commands is not supported.")); consumeUntil(NEWLINE); #line 1449 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_optimization() { try { // for error handling match(LITERAL_optimization); { switch ( LA(1)) { case LITERAL_aggressive: { match(LITERAL_aggressive); break; } case LITERAL_conservative: { match(LITERAL_conservative); break; } case 18: { match(18); break; } case LITERAL_normal: { match(LITERAL_normal); break; } case LITERAL_satellite: { match(LITERAL_satellite); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 291 "pf.g" importer->set_optimization = LT(0)->getText(); #line 1496 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_limit() { try { // for error handling match(LITERAL_limit); { switch ( LA(1)) { case LITERAL_frags: case LITERAL_states: case 62: case LITERAL_tables: case 64: { limit_def(); break; } case OPENING_BRACE: { limit_def_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_loginterface() { try { // for error handling match(LITERAL_loginterface); #line 302 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set loginterface' commands is not supported.")); consumeUntil(NEWLINE); #line 1549 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_block_policy() { try { // for error handling match(23); { switch ( LA(1)) { case DROP: { match(DROP); break; } case RETURN: { match(RETURN); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 314 "pf.g" importer->set_block_policy = LT(0)->getText(); #line 1581 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_state_policy() { try { // for error handling match(26); { switch ( LA(1)) { case 27: { match(27); break; } case LITERAL_floating: { match(LITERAL_floating); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 320 "pf.g" importer->set_state_policy = LT(0)->getText(); #line 1613 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_state_defaults() { try { // for error handling match(29); #line 326 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set state-defaults' commands is not supported.")); consumeUntil(NEWLINE); #line 1633 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_require_order() { try { // for error handling match(30); #line 338 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set require-order' commands is not supported.")); consumeUntil(NEWLINE); #line 1653 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_fingerprints() { try { // for error handling match(LITERAL_fingerprints); #line 350 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set fingerprints' commands is not supported.")); consumeUntil(NEWLINE); #line 1673 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_skip() { try { // for error handling match(LITERAL_skip); match(ON); skip_def(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_debug() { try { // for error handling match(LITERAL_debug); match(WORD); #line 386 "pf.g" importer->set_debug = LT(0)->getText(); #line 1703 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_reassemble() { try { // for error handling match(LITERAL_reassemble); #line 394 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set reassemble' commands is not supported.")); consumeUntil(NEWLINE); #line 1723 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::set_hostid() { try { // for error handling match(LITERAL_hostid); #line 406 "pf.g" importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set hostid' commands is not supported.")); consumeUntil(NEWLINE); #line 1743 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::timeout_def() { #line 424 "pf.g" std::string timeout_name, timeout_value; #line 1754 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case 40: { match(40); break; } case 41: { match(41); break; } case 42: { match(42); break; } case 43: { match(43); break; } case 44: { match(44); break; } case 45: { match(45); break; } case 46: { match(46); break; } case 47: { match(47); break; } case 48: { match(48); break; } case 49: { match(49); break; } case 50: { match(50); break; } case 51: { match(51); break; } case 52: { match(52); break; } case 53: { match(53); break; } case LITERAL_frag: { match(LITERAL_frag); break; } case LITERAL_interval: { match(LITERAL_interval); break; } case 56: { match(56); break; } case 57: { match(57); break; } case 58: { match(58); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 465 "pf.g" timeout_name = LT(0)->getText(); #line 1864 "PFCfgParser.cpp" match(INT_CONST); #line 469 "pf.g" timeout_value = LT(0)->getText(); importer->timeouts.push_back( std::pair(timeout_name, timeout_value)); #line 1872 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_3); } } void PFCfgParser::timeout_def_list() { try { // for error handling match(OPENING_BRACE); timeout_def(); { // ( ... )* for (;;) { if ((_tokenSet_4.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case LITERAL_frag: case LITERAL_interval: case 56: case 57: case 58: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } timeout_def(); } else { goto _loop42; } } _loop42:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::limit_def() { #line 487 "pf.g" std::string limit_name, limit_value; #line 1943 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case LITERAL_frags: { match(LITERAL_frags); break; } case LITERAL_states: { match(LITERAL_states); break; } case 62: { match(62); break; } case LITERAL_tables: { match(LITERAL_tables); break; } case 64: { match(64); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 500 "pf.g" limit_name = LT(0)->getText(); #line 1983 "PFCfgParser.cpp" match(INT_CONST); #line 504 "pf.g" limit_value = LT(0)->getText(); importer->limits.push_back( std::pair(limit_name, limit_value)); #line 1991 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_5); } } void PFCfgParser::limit_def_list() { try { // for error handling match(OPENING_BRACE); limit_def(); { // ( ... )* for (;;) { if ((_tokenSet_6.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case LITERAL_frags: case LITERAL_states: case 62: case LITERAL_tables: case 64: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } limit_def(); } else { goto _loop48; } } _loop48:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::skip_def() { try { // for error handling switch ( LA(1)) { case WORD: { match(WORD); #line 366 "pf.g" importer->set_skip_on.push_back(LT(0)->getText()); #line 2054 "PFCfgParser.cpp" break; } case OPENING_BRACE: { skip_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::skip_list() { try { // for error handling match(OPENING_BRACE); match(WORD); #line 375 "pf.g" importer->set_skip_on.push_back(LT(0)->getText()); #line 2081 "PFCfgParser.cpp" { // ( ... )* for (;;) { if ((LA(1) == WORD || LA(1) == COMMA)) { { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); } else { goto _loop32; } } _loop32:; } // ( ... )* match(WORD); #line 378 "pf.g" importer->set_skip_on.push_back(LT(0)->getText()); #line 2100 "PFCfgParser.cpp" } else { goto _loop33; } } _loop33:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void PFCfgParser::rule_extended() { try { // for error handling { switch ( LA(1)) { case IN_WORD: case OUT_WORD: { direction(); break; } case NEWLINE: case QUEUE: case ON: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case LOG: case QUICK: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case LOG: case QUICK: { quick_or_log(); break; } case NEWLINE: case QUEUE: case ON: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ON: { intrface(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { if (((LA(1) >= ROUTE_TO && LA(1) <= DUP_TO)) && (LA(2) == OPENING_BRACE || LA(2) == OPENING_PAREN)) { route(); } else if ((_tokenSet_7.member(LA(1))) && (_tokenSet_8.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } { switch ( LA(1)) { case INET: case INET6: { address_family(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case PROTO: { protospec(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { if ((_tokenSet_9.member(LA(1))) && (_tokenSet_10.member(LA(2)))) { hosts(); } else if ((_tokenSet_11.member(LA(1))) && (_tokenSet_12.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } { switch ( LA(1)) { case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case USER: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { filteropts(); break; } case NEWLINE: case ROUTE_TO: case REPLY_TO: case DUP_TO: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ROUTE_TO: case REPLY_TO: case DUP_TO: { route(); break; } case NEWLINE: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_13); } } void PFCfgParser::tableaddr_spec() { #line 609 "pf.g" AddressSpec as; #line 2454 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case EXLAMATION: { match(EXLAMATION); #line 610 "pf.g" as.neg = true; #line 2464 "PFCfgParser.cpp" break; } case WORD: case INT_CONST: case SELF: case IPV4: case NUMBER: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case WORD: { match(WORD); #line 613 "pf.g" // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); #line 2492 "PFCfgParser.cpp" { switch ( LA(1)) { case COLON: { match(COLON); { switch ( LA(1)) { case NETWORK: { match(NETWORK); #line 622 "pf.g" as.at = AddressSpec::INTERFACE_NETWORK; #line 2507 "PFCfgParser.cpp" break; } case BROADCAST: { match(BROADCAST); #line 627 "pf.g" as.at = AddressSpec::INTERFACE_BROADCAST; #line 2517 "PFCfgParser.cpp" break; } case PEER: { match(PEER); #line 632 "pf.g" importer->error_tracker->registerError( QString("import of 'interface:peer' is not supported.")); #line 2528 "PFCfgParser.cpp" break; } case INT_CONST: { match(INT_CONST); #line 638 "pf.g" importer->error_tracker->registerError( QString("import of 'interface:0' is not supported.")); #line 2539 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case WORD: case COMMA: case CLOSING_BRACE: case INT_CONST: case EXLAMATION: case SELF: case IPV4: case NUMBER: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case SELF: { match(SELF); #line 646 "pf.g" as.at = AddressSpec::SPECIAL_ADDRESS; as.address = "self"; #line 2577 "PFCfgParser.cpp" break; } case INT_CONST: case IPV4: case NUMBER: { { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case NUMBER: { match(NUMBER); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 653 "pf.g" as.at = AddressSpec::HOST_ADDRESS; as.address = LT(0)->getText(); #line 2612 "PFCfgParser.cpp" { switch ( LA(1)) { case SLASH: { match(SLASH); #line 659 "pf.g" as.at = AddressSpec::NETWORK_ADDRESS; #line 2622 "PFCfgParser.cpp" { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 663 "pf.g" as.netmask = LT(0)->getText(); #line 2645 "PFCfgParser.cpp" break; } case WORD: case COMMA: case CLOSING_BRACE: case INT_CONST: case EXLAMATION: case SELF: case IPV4: case NUMBER: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 668 "pf.g" importer->tmp_group.push_back(as); #line 2677 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_14); } } void PFCfgParser::logging() { try { // for error handling match(LOG); { switch ( LA(1)) { case OPENING_PAREN: { logopts(); break; } case NEWLINE: case ON: case EXLAMATION: case MINUS: case ALL: case TO: case INET: case INET6: case PROTO: case FROM: case TAGGED: case TAG: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1048 "pf.g" importer->logging = true; #line 2719 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_15); } } void PFCfgParser::intrface() { try { // for error handling match(ON); { switch ( LA(1)) { case WORD: case EXLAMATION: { ifspec(); break; } case OPENING_BRACE: { interface_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_16); } } void PFCfgParser::address_family() { try { // for error handling switch ( LA(1)) { case INET: { match(INET); break; } case INET6: { match(INET6); #line 1092 "pf.g" importer->address_family = LT(0)->getText(); #line 2773 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_17); } } void PFCfgParser::protospec() { try { // for error handling match(PROTO); proto_def(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_18); } } void PFCfgParser::hosts() { try { // for error handling switch ( LA(1)) { case ALL: { match(ALL); #line 1135 "pf.g" importer->src_group.push_back( AddressSpec(AddressSpec::ANY, false, "0.0.0.0", "0.0.0.0")); importer->dst_group.push_back( AddressSpec(AddressSpec::ANY, false, "0.0.0.0", "0.0.0.0")); #line 2814 "PFCfgParser.cpp" break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case MINUS: case OPENING_PAREN: case USER: case TO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { { switch ( LA(1)) { case FROM: { hosts_from(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case MINUS: case OPENING_PAREN: case USER: case TO: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case TO: { hosts_to(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case MINUS: case OPENING_PAREN: case USER: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_19); } } void PFCfgParser::tagged() { try { // for error handling { switch ( LA(1)) { case EXLAMATION: { match(EXLAMATION); #line 1694 "pf.g" importer->tagged_neg = true; #line 2958 "PFCfgParser.cpp" break; } case TAGGED: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(TAGGED); match(WORD); #line 1696 "pf.g" importer->tagged = LT(0)->getText(); #line 2977 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_20); } } void PFCfgParser::tag_clause() { try { // for error handling match(TAG); match(WORD); #line 1703 "pf.g" importer->tag = LT(0)->getText(); #line 2994 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_20); } } void PFCfgParser::redirhost() { #line 804 "pf.g" AddressSpec as; #line 3005 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case IPV4: { match(IPV4); #line 807 "pf.g" as.at = AddressSpec::HOST_ADDRESS; as.address = LT(0)->getText(); #line 3018 "PFCfgParser.cpp" { switch ( LA(1)) { case SLASH: { match(SLASH); #line 813 "pf.g" as.at = AddressSpec::NETWORK_ADDRESS; #line 3028 "PFCfgParser.cpp" { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 817 "pf.g" as.netmask = LT(0)->getText(); #line 3051 "PFCfgParser.cpp" break; } case NEWLINE: case WORD: case COMMA: case CLOSING_BRACE: case IPV4: case STATIC_PORT: case OPENING_PAREN: case PORT: case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case OPENING_PAREN: { match(OPENING_PAREN); match(WORD); #line 824 "pf.g" // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); #line 3087 "PFCfgParser.cpp" match(CLOSING_PAREN); break; } case WORD: { match(WORD); #line 832 "pf.g" // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); #line 3100 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 838 "pf.g" importer->tmp_group.push_back(as); #line 3113 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_21); } } void PFCfgParser::redirhost_list() { try { // for error handling match(OPENING_BRACE); redirhost(); { // ( ... )* for (;;) { if ((_tokenSet_22.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case WORD: case IPV4: case OPENING_PAREN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } redirhost(); } else { goto _loop101; } } _loop101:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_23); } } void PFCfgParser::portspec() { #line 863 "pf.g" PortSpec ps; #line 3168 "PFCfgParser.cpp" try { // for error handling match(PORT); { switch ( LA(1)) { case WORD: case INT_CONST: { port_def(); #line 867 "pf.g" ps.port1 = importer->tmp_port_def; ps.port2 = ps.port1; ps.port_op = "="; #line 3184 "PFCfgParser.cpp" break; } case IPV6: { match(IPV6); #line 876 "pf.g" ps.setFromPortRange(LT(0)->getText()); #line 3194 "PFCfgParser.cpp" { switch ( LA(1)) { case STAR: { match(STAR); #line 880 "pf.g" ps.port2 = "65535"; #line 3202 "PFCfgParser.cpp" break; } case NEWLINE: case STATIC_PORT: case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 883 "pf.g" importer->tmp_port_group.push_back(ps); #line 3232 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_24); } } void PFCfgParser::pooltype() { try { // for error handling { switch ( LA(1)) { case BITMASK: { match(BITMASK); #line 897 "pf.g" importer->pooltype_opt = "bitmask"; #line 3250 "PFCfgParser.cpp" break; } case RANDOM: { match(RANDOM); #line 899 "pf.g" importer->pooltype_opt = "random"; #line 3258 "PFCfgParser.cpp" break; } case SOURCE_HASH: { match(SOURCE_HASH); #line 901 "pf.g" importer->pooltype_opt = "source-hash"; #line 3266 "PFCfgParser.cpp" { switch ( LA(1)) { case HEX_KEY: { match(HEX_KEY); #line 904 "pf.g" importer->error_tracker->registerError( QString("import of commands with pool type 'source-hash hex-key' " "option is not supported")); #line 3278 "PFCfgParser.cpp" break; } case STRING_KEY: { match(STRING_KEY); #line 911 "pf.g" importer->error_tracker->registerError( QString("import of commands with pool type 'source-hash string-key' " "option is not supported")); #line 3290 "PFCfgParser.cpp" break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case STATIC_PORT: case OPENING_PAREN: case STICKY_ADDRESS: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case ROUND_ROBIN: { match(ROUND_ROBIN); #line 918 "pf.g" importer->pooltype_opt = "round-robin"; #line 3343 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case STICKY_ADDRESS: { match(STICKY_ADDRESS); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case STATIC_PORT: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_25); } } void PFCfgParser::port_def() { try { // for error handling { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1831 "pf.g" importer->tmp_port_def = LT(0)->getText(); #line 3433 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_26); } } void PFCfgParser::block_return() { try { // for error handling { switch ( LA(1)) { case DROP: { match(DROP); #line 980 "pf.g" importer->block_action_params.push_back("drop"); #line 3451 "PFCfgParser.cpp" break; } case RETURN: { match(RETURN); #line 982 "pf.g" importer->block_action_params.push_back("return"); #line 3459 "PFCfgParser.cpp" break; } case RETURN_RST: { match(RETURN_RST); #line 984 "pf.g" importer->block_action_params.push_back("return-rst"); #line 3467 "PFCfgParser.cpp" { switch ( LA(1)) { case TTL: { match(TTL); match(INT_CONST); #line 987 "pf.g" importer->error_tracker->registerError( QString("Import of \"block return-rst ttl number\" is not supported. ")); #line 3479 "PFCfgParser.cpp" break; } case NEWLINE: case QUEUE: case ON: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case IN_WORD: case OUT_WORD: case LOG: case QUICK: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case RETURN_ICMP: { match(RETURN_ICMP); #line 993 "pf.g" importer->block_action_params.push_back("return-icmp"); #line 3535 "PFCfgParser.cpp" { if ((LA(1) == OPENING_PAREN) && (_tokenSet_27.member(LA(2)))) { match(OPENING_PAREN); { switch ( LA(1)) { case 177: case 178: case 179: case 180: case LITERAL_needfrag: case LITERAL_srcfail: case 183: case 184: case LITERAL_isolate: case 186: case 187: case 188: case 189: case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: case LITERAL_transit: case LITERAL_reassemb: case LITERAL_badhead: case LITERAL_optmiss: case LITERAL_badlen: case 204: case 205: case 206: { icmp_code_by_name(); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 997 "pf.g" importer->block_action_params.push_back(LT(0)->getText()); #line 3588 "PFCfgParser.cpp" { switch ( LA(1)) { case COMMA: { match(COMMA); { switch ( LA(1)) { case 177: case 178: case 179: case 180: case LITERAL_needfrag: case LITERAL_srcfail: case 183: case 184: case LITERAL_isolate: case 186: case 187: case 188: case 189: case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: case LITERAL_transit: case LITERAL_reassemb: case LITERAL_badhead: case LITERAL_optmiss: case LITERAL_badlen: case 204: case 205: case 206: { icmp_code_by_name(); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1001 "pf.g" importer->error_tracker->registerError( QString("Import of \"block return-icmp (icmp_code, icmp6_code)\" is not supported")); #line 3646 "PFCfgParser.cpp" break; } case CLOSING_PAREN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(CLOSING_PAREN); } else if ((_tokenSet_28.member(LA(1))) && (_tokenSet_29.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } break; } case RETURN_ICMP6: { match(RETURN_ICMP6); #line 1010 "pf.g" importer->error_tracker->registerError( QString("Import of \"block return-icmp6\" is not supported")); importer->block_action_params.push_back("return-icmp"); #line 3679 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_28); } } void PFCfgParser::icmp_code_by_name() { try { // for error handling { switch ( LA(1)) { case 177: { match(177); break; } case 178: { match(178); break; } case 179: { match(179); break; } case 180: { match(180); break; } case LITERAL_needfrag: { match(LITERAL_needfrag); break; } case LITERAL_srcfail: { match(LITERAL_srcfail); break; } case 183: { match(183); break; } case 184: { match(184); break; } case LITERAL_isolate: { match(LITERAL_isolate); break; } case 186: { match(186); break; } case 187: { match(187); break; } case 188: { match(188); break; } case 189: { match(189); break; } case 190: { match(190); break; } case 191: { match(191); break; } case 192: { match(192); break; } case 193: { match(193); break; } case 194: { match(194); break; } case 195: { match(195); break; } case 196: { match(196); break; } case 197: { match(197); break; } case 198: { match(198); break; } case LITERAL_transit: { match(LITERAL_transit); break; } case LITERAL_reassemb: { match(LITERAL_reassemb); break; } case LITERAL_badhead: { match(LITERAL_badhead); break; } case LITERAL_optmiss: { match(LITERAL_optmiss); break; } case LITERAL_badlen: { match(LITERAL_badlen); break; } case 204: { match(204); break; } case 205: { match(205); break; } case 206: { match(206); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_30); } } void PFCfgParser::direction() { try { // for error handling { switch ( LA(1)) { case IN_WORD: { match(IN_WORD); break; } case OUT_WORD: { match(OUT_WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1031 "pf.g" importer->direction = LT(0)->getText(); #line 3888 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_31); } } void PFCfgParser::quick_or_log() { try { // for error handling { switch ( LA(1)) { case LOG: { match(LOG); { if ((LA(1) == OPENING_PAREN) && ((LA(2) >= ALL && LA(2) <= TO))) { logopts(); } else if ((_tokenSet_32.member(LA(1))) && (_tokenSet_33.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } #line 1039 "pf.g" importer->logging = true; #line 3917 "PFCfgParser.cpp" { switch ( LA(1)) { case QUICK: { match(QUICK); #line 1040 "pf.g" importer->quick = true; #line 3925 "PFCfgParser.cpp" break; } case NEWLINE: case QUEUE: case ON: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case QUICK: { match(QUICK); #line 1042 "pf.g" importer->quick = true; #line 3977 "PFCfgParser.cpp" { switch ( LA(1)) { case LOG: { match(LOG); { if ((LA(1) == OPENING_PAREN) && ((LA(2) >= ALL && LA(2) <= TO))) { logopts(); } else if ((_tokenSet_34.member(LA(1))) && (_tokenSet_8.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } #line 1043 "pf.g" importer->logging = true; #line 3996 "PFCfgParser.cpp" break; } case NEWLINE: case QUEUE: case ON: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_34); } } void PFCfgParser::route() { try { // for error handling switch ( LA(1)) { case ROUTE_TO: { route_to(); break; } case REPLY_TO: { reply_to(); break; } case DUP_TO: { dup_to(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_7); } } void PFCfgParser::filteropts() { try { // for error handling filteropt(); { // ( ... )* for (;;) { if ((_tokenSet_35.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case USER: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } filteropt(); } else { goto _loop207; } } _loop207:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_36); } } void PFCfgParser::logopts() { try { // for error handling match(OPENING_PAREN); logopt(); { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); #line 1055 "pf.g" importer->logopts += ","; #line 4159 "PFCfgParser.cpp" logopt(); } else { goto _loop142; } } _loop142:; } // ( ... )* match(CLOSING_PAREN); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_37); } } void PFCfgParser::logopt() { try { // for error handling switch ( LA(1)) { case ALL: { match(ALL); break; } case USER: { match(USER); break; } case TO: { match(TO); match(WORD); #line 1062 "pf.g" importer->logopts += LT(0)->getText(); #line 4199 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_38); } } void PFCfgParser::ifspec() { #line 1070 "pf.g" InterfaceSpec is; #line 4217 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case EXLAMATION: { match(EXLAMATION); #line 1071 "pf.g" is.neg = true; #line 4227 "PFCfgParser.cpp" break; } case WORD: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(WORD); #line 1073 "pf.g" is.name = LT(0)->getText(); importer->iface_group.push_back(is); importer->newInterface(is.name); #line 4247 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_39); } } void PFCfgParser::interface_list() { try { // for error handling match(OPENING_BRACE); ifspec(); { // ( ... )* for (;;) { if ((LA(1) == WORD || LA(1) == COMMA || LA(1) == EXLAMATION)) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case WORD: case EXLAMATION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } ifspec(); } else { goto _loop151; } } _loop151:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_16); } } void PFCfgParser::proto_def() { try { // for error handling { switch ( LA(1)) { case IP: case ICMP: case IGMP: case TCP: case UDP: case RDP: case RSVP: case GRE: case ESP_WORD: case AH: case EIGRP: case OSPF: case IPIP: case VRRP: case L2TP: case ISIS: { proto_name(); break; } case INT_CONST: { proto_number(); break; } case OPENING_BRACE: { proto_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_40); } } void PFCfgParser::proto_name() { try { // for error handling { switch ( LA(1)) { case IP: { match(IP); break; } case ICMP: { match(ICMP); break; } case IGMP: { match(IGMP); break; } case TCP: { match(TCP); break; } case UDP: { match(UDP); break; } case RDP: { match(RDP); break; } case RSVP: { match(RSVP); break; } case GRE: { match(GRE); break; } case ESP_WORD: { match(ESP_WORD); break; } case AH: { match(AH); break; } case EIGRP: { match(EIGRP); break; } case OSPF: { match(OSPF); break; } case IPIP: { match(IPIP); break; } case VRRP: { match(VRRP); break; } case L2TP: { match(L2TP); break; } case ISIS: { match(ISIS); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1112 "pf.g" importer->proto_list.push_back(LT(0)->getText()); #line 4441 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_40); } } void PFCfgParser::proto_number() { try { // for error handling match(INT_CONST); #line 1118 "pf.g" importer->proto_list.push_back(LT(0)->getText()); #line 4457 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_40); } } void PFCfgParser::proto_list() { try { // for error handling match(OPENING_BRACE); proto_def(); { // ( ... )* for (;;) { if ((_tokenSet_41.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case OPENING_BRACE: case INT_CONST: case IP: case ICMP: case IGMP: case TCP: case UDP: case RDP: case RSVP: case GRE: case ESP_WORD: case AH: case EIGRP: case OSPF: case IPIP: case VRRP: case L2TP: case ISIS: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } proto_def(); } else { goto _loop162; } } _loop162:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_40); } } void PFCfgParser::hosts_from() { try { // for error handling match(FROM); src_hosts_part(); { switch ( LA(1)) { case PORT: { src_port_part(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case MINUS: case OPENING_PAREN: case USER: case TO: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_42); } } void PFCfgParser::hosts_to() { try { // for error handling match(TO); dst_hosts_part(); { switch ( LA(1)) { case PORT: { dst_port_part(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case MINUS: case OPENING_PAREN: case USER: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_19); } } void PFCfgParser::src_hosts_part() { try { // for error handling { switch ( LA(1)) { case WORD: case OPENING_BRACE: case LESS_THAN: case EXLAMATION: case SELF: case IPV4: case OPENING_PAREN: case IPV6: case ANY: case NO_ROUTE: case MACRO: { common_hosts_part(); break; } case URPF_FAILED: { match(URPF_FAILED); #line 1158 "pf.g" importer->tmp_group.push_back( AddressSpec(AddressSpec::SPECIAL_ADDRESS, false, "urpf-failed", "")); #line 4664 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1164 "pf.g" importer->src_neg = importer->tmp_neg; importer->src_group.splice(importer->src_group.begin(), importer->tmp_group); #line 4679 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_43); } } void PFCfgParser::src_port_part() { try { // for error handling match(PORT); { switch ( LA(1)) { case WORD: case EQUAL: case INT_CONST: case LESS_THAN: case GREATER_THAN: case EXLAMATION: case IPV6: { port_op(); break; } case OPENING_BRACE: { port_op_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1752 "pf.g" importer->src_port_group.splice(importer->src_port_group.begin(), importer->tmp_port_group); #line 4720 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_42); } } void PFCfgParser::dst_hosts_part() { try { // for error handling common_hosts_part(); #line 1173 "pf.g" importer->dst_neg = importer->tmp_neg; importer->dst_group.splice(importer->dst_group.begin(), importer->tmp_group); #line 4738 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_44); } } void PFCfgParser::dst_port_part() { try { // for error handling match(PORT); { switch ( LA(1)) { case WORD: case EQUAL: case INT_CONST: case LESS_THAN: case GREATER_THAN: case EXLAMATION: case IPV6: { port_op(); break; } case OPENING_BRACE: { port_op_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1765 "pf.g" importer->dst_port_group.splice(importer->dst_port_group.begin(), importer->tmp_port_group); #line 4779 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_19); } } void PFCfgParser::common_hosts_part() { try { // for error handling switch ( LA(1)) { case ANY: { match(ANY); #line 1182 "pf.g" importer->tmp_group.push_back( AddressSpec(AddressSpec::ANY, false, "0.0.0.0", "0.0.0.0")); #line 4799 "PFCfgParser.cpp" break; } case NO_ROUTE: { match(NO_ROUTE); #line 1188 "pf.g" importer->tmp_group.push_back( AddressSpec(AddressSpec::SPECIAL_ADDRESS, false, "no-route", "")); #line 4810 "PFCfgParser.cpp" break; } case WORD: case LESS_THAN: case EXLAMATION: case SELF: case IPV4: case OPENING_PAREN: case IPV6: case MACRO: { host(); break; } case OPENING_BRACE: { host_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_43); } } void PFCfgParser::host() { ANTLR_USE_NAMESPACE(antlr)RefToken tn = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken in = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 1198 "pf.g" AddressSpec as; #line 4847 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case EXLAMATION: { match(EXLAMATION); #line 1199 "pf.g" as.neg = true; #line 4857 "PFCfgParser.cpp" break; } case WORD: case LESS_THAN: case SELF: case IPV4: case OPENING_PAREN: case IPV6: case MACRO: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case WORD: case MACRO: { { switch ( LA(1)) { case WORD: { match(WORD); break; } case MACRO: { match(MACRO); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1202 "pf.g" // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); #line 4905 "PFCfgParser.cpp" { switch ( LA(1)) { case COLON: { match(COLON); { switch ( LA(1)) { case NETWORK: { match(NETWORK); #line 1211 "pf.g" as.at = AddressSpec::INTERFACE_NETWORK; #line 4920 "PFCfgParser.cpp" break; } case BROADCAST: { match(BROADCAST); #line 1216 "pf.g" as.at = AddressSpec::INTERFACE_BROADCAST; #line 4930 "PFCfgParser.cpp" break; } case PEER: { match(PEER); #line 1221 "pf.g" importer->error_tracker->registerError( QString("import of 'interface:peer' is not supported.")); #line 4941 "PFCfgParser.cpp" break; } case INT_CONST: { match(INT_CONST); #line 1227 "pf.g" importer->error_tracker->registerError( QString("import of 'interface:0' is not supported.")); #line 4952 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: case WORD: case QUEUE: case COMMA: case CLOSING_BRACE: case LITERAL_reassemble: case SCRUB: case LESS_THAN: case EXLAMATION: case SELF: case IPV4: case NO: case MINUS: case OPENING_PAREN: case PORT: case IPV6: case USER: case TO: case MACRO: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case SELF: { match(SELF); #line 1235 "pf.g" as.at = AddressSpec::SPECIAL_ADDRESS; as.address = "self"; #line 5019 "PFCfgParser.cpp" break; } case IPV6: { match(IPV6); #line 1241 "pf.g" importer->error_tracker->registerError( QString("IPv6 import is not supported. ")); consumeUntil(NEWLINE); #line 5031 "PFCfgParser.cpp" break; } case IPV4: { match(IPV4); #line 1248 "pf.g" as.at = AddressSpec::HOST_ADDRESS; as.address = LT(0)->getText(); #line 5042 "PFCfgParser.cpp" { switch ( LA(1)) { case SLASH: { match(SLASH); #line 1254 "pf.g" as.at = AddressSpec::NETWORK_ADDRESS; #line 5052 "PFCfgParser.cpp" { switch ( LA(1)) { case IPV4: { match(IPV4); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1258 "pf.g" as.netmask = LT(0)->getText(); #line 5075 "PFCfgParser.cpp" break; } case NEWLINE: case WORD: case QUEUE: case COMMA: case CLOSING_BRACE: case LITERAL_reassemble: case SCRUB: case LESS_THAN: case EXLAMATION: case SELF: case IPV4: case NO: case MINUS: case OPENING_PAREN: case PORT: case IPV6: case USER: case TO: case MACRO: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case LESS_THAN: { match(LESS_THAN); tn = LT(1); match(WORD); match(GREATER_THAN); #line 1264 "pf.g" as.at = AddressSpec::TABLE; as.address = tn->getText(); #line 5137 "PFCfgParser.cpp" break; } case OPENING_PAREN: { match(OPENING_PAREN); in = LT(1); match(WORD); match(CLOSING_PAREN); #line 1270 "pf.g" // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = in->getText(); #line 5152 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1276 "pf.g" importer->tmp_group.push_back(as); #line 5165 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_45); } } void PFCfgParser::host_list() { try { // for error handling match(OPENING_BRACE); host(); { // ( ... )* for (;;) { if ((_tokenSet_46.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case WORD: case LESS_THAN: case EXLAMATION: case SELF: case IPV4: case OPENING_PAREN: case IPV6: case MACRO: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } host(); } else { goto _loop185; } } _loop185:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_43); } } void PFCfgParser::route_to() { try { // for error handling match(ROUTE_TO); { switch ( LA(1)) { case OPENING_PAREN: { routehost(); break; } case OPENING_BRACE: { routehost_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { pooltype(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1298 "pf.g" importer->route_type = PFImporter::ROUTE_TO; #line 5299 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_7); } } void PFCfgParser::reply_to() { try { // for error handling match(REPLY_TO); { switch ( LA(1)) { case OPENING_PAREN: { routehost(); break; } case OPENING_BRACE: { routehost_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { pooltype(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1305 "pf.g" importer->route_type = PFImporter::REPLY_TO; #line 5384 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_7); } } void PFCfgParser::dup_to() { try { // for error handling match(DUP_TO); { switch ( LA(1)) { case OPENING_PAREN: { routehost(); break; } case OPENING_BRACE: { routehost_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case BITMASK: case RANDOM: case SOURCE_HASH: case ROUND_ROBIN: { pooltype(); break; } case NEWLINE: case QUEUE: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case ALL: case USER: case TO: case INET: case INET6: case PROTO: case FROM: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1312 "pf.g" importer->route_type = PFImporter::DUP_TO; #line 5469 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_7); } } void PFCfgParser::routehost() { ANTLR_USE_NAMESPACE(antlr)RefToken h = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken v6 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken nm = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken nm6 = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 1317 "pf.g" RouteSpec rs; #line 5484 "PFCfgParser.cpp" try { // for error handling match(OPENING_PAREN); match(WORD); #line 1319 "pf.g" rs.iface = LT(0)->getText(); #line 5491 "PFCfgParser.cpp" { switch ( LA(1)) { case IPV4: { h = LT(1); match(IPV4); break; } case IPV6: { v6 = LT(1); match(IPV6); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case SLASH: { match(SLASH); { switch ( LA(1)) { case IPV4: { nm = LT(1); match(IPV4); break; } case INT_CONST: { nm6 = LT(1); match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case CLOSING_PAREN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1321 "pf.g" if (v6) { importer->error_tracker->registerError( QString("IPv6 import is not supported. ")); consumeUntil(NEWLINE); } else { if (h) rs.address = h->getText(); if (nm) rs.netmask = nm->getText(); importer->route_group.push_back(rs); } #line 5563 "PFCfgParser.cpp" match(CLOSING_PAREN); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_47); } } void PFCfgParser::routehost_list() { try { // for error handling match(OPENING_BRACE); routehost(); { // ( ... )* for (;;) { if ((LA(1) == COMMA || LA(1) == OPENING_PAREN)) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case OPENING_PAREN: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } routehost(); } else { goto _loop203; } } _loop203:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_48); } } void PFCfgParser::filteropt() { try { // for error handling switch ( LA(1)) { case USER: { user_match(); break; } case GROUP: { group_match(); break; } case FLAGS: { tcp_flags(); break; } case ICMP_TYPE: { icmp_type(); break; } case ICMP6_TYPE: { icmp6_type(); break; } case EXLAMATION: case TAGGED: { tagged(); break; } case TAG: { tag_clause(); break; } case NO: case KEEP: case MODULATE: case SYNPROXY: { state(); break; } case QUEUE: { queue(); break; } case LABEL: { label(); break; } case SCRUB: { match_rule_scrub_options(); break; } case LITERAL_reassemble: case OPENING_PAREN: case LITERAL_fragment: case 146: case 147: case 148: case 149: { scrub_options(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::user_match() { try { // for error handling match(USER); { switch ( LA(1)) { case WORD: case EQUAL: case INT_CONST: case LESS_THAN: case GREATER_THAN: case EXLAMATION: { user_group_op(); break; } case OPENING_BRACE: { user_group_op_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1386 "pf.g" importer->addMessageToLog( QString("Error: import of 'user' match is not supported.")); #line 5732 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::group_match() { try { // for error handling match(GROUP); { switch ( LA(1)) { case WORD: case EQUAL: case INT_CONST: case LESS_THAN: case GREATER_THAN: case EXLAMATION: { user_group_op(); break; } case OPENING_BRACE: { user_group_op_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1395 "pf.g" importer->addMessageToLog( QString("Error: import of 'group' match is not supported.")); #line 5772 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::tcp_flags() { ANTLR_USE_NAMESPACE(antlr)RefToken check = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken mask = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(FLAGS); { switch ( LA(1)) { case ANY: { match(ANY); #line 1505 "pf.g" importer->flags_check = "none"; importer->flags_mask = "none"; #line 5796 "PFCfgParser.cpp" break; } case WORD: case SLASH: { { switch ( LA(1)) { case WORD: { check = LT(1); match(WORD); break; } case SLASH: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(SLASH); { switch ( LA(1)) { case WORD: { mask = LT(1); match(WORD); break; } case NEWLINE: case QUEUE: case COMMA: case LITERAL_reassemble: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case USER: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1511 "pf.g" if (check) importer->flags_check = check->getText(); else importer->flags_check = "any"; if (mask) importer->flags_mask = mask->getText(); else importer->flags_mask = "all"; #line 5876 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::icmp_type() { try { // for error handling match(ICMP_TYPE); { switch ( LA(1)) { case LITERAL_skip: case INT_CONST: case LITERAL_echorep: case LITERAL_unreach: case LITERAL_squench: case LITERAL_redir: case LITERAL_althost: case LITERAL_echoreq: case LITERAL_routeradv: case LITERAL_routersol: case LITERAL_timex: case LITERAL_paramprob: case LITERAL_timereq: case LITERAL_timerep: case LITERAL_inforeq: case LITERAL_inforep: case LITERAL_maskreq: case LITERAL_maskrep: case LITERAL_trace: case LITERAL_dataconv: case LITERAL_mobredir: case 172: case 173: case LITERAL_mobregreq: case LITERAL_mobregrep: case LITERAL_photuris: { icmp_type_code(); break; } case OPENING_BRACE: { icmp_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::icmp6_type() { try { // for error handling match(ICMP6_TYPE); #line 1686 "pf.g" importer->error_tracker->registerError( QString("ICMP6 import is not supported. ")); consumeUntil(NEWLINE); #line 5956 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::state() { try { // for error handling { switch ( LA(1)) { case NO: { match(NO); break; } case KEEP: { match(KEEP); break; } case MODULATE: { match(MODULATE); break; } case SYNPROXY: { match(SYNPROXY); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1718 "pf.g" importer->state_op = LT(0)->getText(); #line 5999 "PFCfgParser.cpp" match(STATE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::queue() { try { // for error handling match(QUEUE); { switch ( LA(1)) { case WORD: { match(WORD); #line 1727 "pf.g" importer->queue += LT(0)->getText(); #line 6019 "PFCfgParser.cpp" break; } case OPENING_PAREN: { match(OPENING_PAREN); match(WORD); #line 1730 "pf.g" importer->queue += LT(0)->getText(); #line 6028 "PFCfgParser.cpp" { // ( ... )* for (;;) { if ((LA(1) == COMMA)) { match(COMMA); #line 1732 "pf.g" importer->queue += ","; #line 6035 "PFCfgParser.cpp" match(WORD); #line 1733 "pf.g" importer->queue += LT(0)->getText(); #line 6039 "PFCfgParser.cpp" } else { goto _loop260; } } _loop260:; } // ( ... )* match(CLOSING_PAREN); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::label() { try { // for error handling match(LABEL); match(STRING); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::match_rule_scrub_options() { try { // for error handling match(SCRUB); scrub_options(); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::scrub_options() { try { // for error handling { switch ( LA(1)) { case LITERAL_reassemble: case LITERAL_fragment: case 146: case 147: case 148: case 149: { scrub_option(); break; } case OPENING_PAREN: { scrub_option_list(); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::user_group_op() { try { // for error handling { switch ( LA(1)) { case EQUAL: case LESS_THAN: case GREATER_THAN: case EXLAMATION: { unary_op(); { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case WORD: case INT_CONST: { { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { if ((LA(1) == LESS_THAN || LA(1) == GREATER_THAN || LA(1) == COLON) && (_tokenSet_50.member(LA(2)))) { binary_op(); { switch ( LA(1)) { case WORD: { match(WORD); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } else if ((_tokenSet_51.member(LA(1))) && (_tokenSet_52.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_51); } } void PFCfgParser::user_group_op_list() { try { // for error handling match(OPENING_BRACE); user_group_op(); { // ( ... )* for (;;) { if ((_tokenSet_53.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case WORD: case EQUAL: case INT_CONST: case LESS_THAN: case GREATER_THAN: case EXLAMATION: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } user_group_op(); } else { goto _loop222; } } _loop222:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::unary_op() { try { // for error handling { switch ( LA(1)) { case EQUAL: { match(EQUAL); #line 1773 "pf.g" importer->tmp_port_op = "="; #line 6274 "PFCfgParser.cpp" break; } case EXLAMATION: { match(EXLAMATION); match(EQUAL); #line 1775 "pf.g" importer->tmp_port_op = "!="; #line 6283 "PFCfgParser.cpp" break; } default: if ((LA(1) == LESS_THAN) && (LA(2) == WORD || LA(2) == INT_CONST)) { match(LESS_THAN); #line 1777 "pf.g" importer->tmp_port_op = "<"; #line 6291 "PFCfgParser.cpp" } else if ((LA(1) == LESS_THAN) && (LA(2) == EQUAL)) { match(LESS_THAN); match(EQUAL); #line 1779 "pf.g" importer->tmp_port_op = "<="; #line 6298 "PFCfgParser.cpp" } else if ((LA(1) == GREATER_THAN) && (LA(2) == WORD || LA(2) == INT_CONST)) { match(GREATER_THAN); #line 1781 "pf.g" importer->tmp_port_op = ">"; #line 6304 "PFCfgParser.cpp" } else if ((LA(1) == GREATER_THAN) && (LA(2) == EQUAL)) { match(GREATER_THAN); match(EQUAL); #line 1783 "pf.g" importer->tmp_port_op = ">="; #line 6311 "PFCfgParser.cpp" } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_54); } } void PFCfgParser::binary_op() { try { // for error handling { switch ( LA(1)) { case LESS_THAN: { match(LESS_THAN); match(GREATER_THAN); #line 1789 "pf.g" importer->tmp_port_op = "<>"; #line 6336 "PFCfgParser.cpp" break; } case GREATER_THAN: { match(GREATER_THAN); match(LESS_THAN); #line 1791 "pf.g" importer->tmp_port_op = "><"; #line 6345 "PFCfgParser.cpp" break; } case COLON: { match(COLON); #line 1793 "pf.g" importer->tmp_port_op = ":"; #line 6353 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_54); } } void PFCfgParser::scrub_option() { try { // for error handling { switch ( LA(1)) { case LITERAL_fragment: { match(LITERAL_fragment); { switch ( LA(1)) { case LITERAL_reassemble: { match(LITERAL_reassemble); break; } case LITERAL_crop: { match(LITERAL_crop); break; } case 145: { match(145); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1457 "pf.g" importer->scrub_options.push_back( str_tuple("fragment", LT(0)->getText())); importer->scrub_rule = true; #line 6406 "PFCfgParser.cpp" break; } case LITERAL_reassemble: { match(LITERAL_reassemble); match(TCP); #line 1464 "pf.g" importer->scrub_options.push_back( str_tuple("reassemble", "tcp")); importer->scrub_rule = true; #line 6419 "PFCfgParser.cpp" break; } case 146: { match(146); #line 1471 "pf.g" importer->scrub_options.push_back( str_tuple(LT(0)->getText(), "")); importer->scrub_rule = true; #line 6431 "PFCfgParser.cpp" break; } case 147: { match(147); match(INT_CONST); #line 1478 "pf.g" importer->scrub_options.push_back( str_tuple("min-ttl", LT(0)->getText())); importer->scrub_rule = true; #line 6444 "PFCfgParser.cpp" break; } case 148: { match(148); match(INT_CONST); #line 1485 "pf.g" importer->scrub_options.push_back( str_tuple("max-mss", LT(0)->getText())); importer->scrub_rule = true; #line 6457 "PFCfgParser.cpp" break; } case 149: { match(149); #line 1492 "pf.g" importer->scrub_options.push_back( str_tuple(LT(0)->getText(), "")); importer->scrub_rule = true; #line 6469 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_55); } } void PFCfgParser::scrub_option_list() { try { // for error handling match(OPENING_PAREN); scrub_option(); { // ( ... )* for (;;) { if ((_tokenSet_56.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case LITERAL_reassemble: case LITERAL_fragment: case 146: case 147: case 148: case 149: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } scrub_option(); } else { goto _loop229; } } _loop229:; } // ( ... )* match(CLOSING_PAREN); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::icmp_type_code() { #line 1533 "pf.g" IcmpSpec is; #line 6535 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case LITERAL_skip: case LITERAL_echorep: case LITERAL_unreach: case LITERAL_squench: case LITERAL_redir: case LITERAL_althost: case LITERAL_echoreq: case LITERAL_routeradv: case LITERAL_routersol: case LITERAL_timex: case LITERAL_paramprob: case LITERAL_timereq: case LITERAL_timerep: case LITERAL_inforeq: case LITERAL_inforep: case LITERAL_maskreq: case LITERAL_maskrep: case LITERAL_trace: case LITERAL_dataconv: case LITERAL_mobredir: case 172: case 173: case LITERAL_mobregreq: case LITERAL_mobregrep: case LITERAL_photuris: { icmp_type_by_name(); #line 1535 "pf.g" is.icmp_type_name = LT(0)->getText(); #line 6569 "PFCfgParser.cpp" break; } case INT_CONST: { match(INT_CONST); #line 1537 "pf.g" is.icmp_type_int = LT(0)->getText(); #line 6577 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case ICMP_CODE: { match(ICMP_CODE); { switch ( LA(1)) { case 177: case 178: case 179: case 180: case LITERAL_needfrag: case LITERAL_srcfail: case 183: case 184: case LITERAL_isolate: case 186: case 187: case 188: case 189: case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: case LITERAL_transit: case LITERAL_reassemb: case LITERAL_badhead: case LITERAL_optmiss: case LITERAL_badlen: case 204: case 205: case 206: { icmp_code_by_name(); #line 1543 "pf.g" is.icmp_code_name = LT(0)->getText(); #line 6627 "PFCfgParser.cpp" break; } case INT_CONST: { match(INT_CONST); #line 1545 "pf.g" is.icmp_code_int = LT(0)->getText(); #line 6635 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case NEWLINE: case QUEUE: case LITERAL_skip: case COMMA: case CLOSING_BRACE: case LITERAL_reassemble: case INT_CONST: case SCRUB: case EXLAMATION: case NO: case OPENING_PAREN: case USER: case ROUTE_TO: case REPLY_TO: case DUP_TO: case GROUP: case LITERAL_fragment: case 146: case 147: case 148: case 149: case FLAGS: case ICMP_TYPE: case LITERAL_echorep: case LITERAL_unreach: case LITERAL_squench: case LITERAL_redir: case LITERAL_althost: case LITERAL_echoreq: case LITERAL_routeradv: case LITERAL_routersol: case LITERAL_timex: case LITERAL_paramprob: case LITERAL_timereq: case LITERAL_timerep: case LITERAL_inforeq: case LITERAL_inforep: case LITERAL_maskreq: case LITERAL_maskrep: case LITERAL_trace: case LITERAL_dataconv: case LITERAL_mobredir: case 172: case 173: case LITERAL_mobregreq: case LITERAL_mobregrep: case LITERAL_photuris: case ICMP6_TYPE: case TAGGED: case TAG: case KEEP: case MODULATE: case SYNPROXY: case LABEL: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1548 "pf.g" importer->icmp_type_code_group.push_back(is); #line 6713 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_57); } } void PFCfgParser::icmp_list() { try { // for error handling match(OPENING_BRACE); icmp_type_code(); { // ( ... )* for (;;) { if ((_tokenSet_58.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case LITERAL_skip: case INT_CONST: case LITERAL_echorep: case LITERAL_unreach: case LITERAL_squench: case LITERAL_redir: case LITERAL_althost: case LITERAL_echoreq: case LITERAL_routeradv: case LITERAL_routersol: case LITERAL_timex: case LITERAL_paramprob: case LITERAL_timereq: case LITERAL_timerep: case LITERAL_inforeq: case LITERAL_inforep: case LITERAL_maskreq: case LITERAL_maskrep: case LITERAL_trace: case LITERAL_dataconv: case LITERAL_mobredir: case 172: case 173: case LITERAL_mobregreq: case LITERAL_mobregrep: case LITERAL_photuris: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } icmp_type_code(); } else { goto _loop250; } } _loop250:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_49); } } void PFCfgParser::icmp_type_by_name() { try { // for error handling { switch ( LA(1)) { case LITERAL_echorep: { match(LITERAL_echorep); break; } case LITERAL_unreach: { match(LITERAL_unreach); break; } case LITERAL_squench: { match(LITERAL_squench); break; } case LITERAL_redir: { match(LITERAL_redir); break; } case LITERAL_althost: { match(LITERAL_althost); break; } case LITERAL_echoreq: { match(LITERAL_echoreq); break; } case LITERAL_routeradv: { match(LITERAL_routeradv); break; } case LITERAL_routersol: { match(LITERAL_routersol); break; } case LITERAL_timex: { match(LITERAL_timex); break; } case LITERAL_paramprob: { match(LITERAL_paramprob); break; } case LITERAL_timereq: { match(LITERAL_timereq); break; } case LITERAL_timerep: { match(LITERAL_timerep); break; } case LITERAL_inforeq: { match(LITERAL_inforeq); break; } case LITERAL_inforep: { match(LITERAL_inforep); break; } case LITERAL_maskreq: { match(LITERAL_maskreq); break; } case LITERAL_maskrep: { match(LITERAL_maskrep); break; } case LITERAL_trace: { match(LITERAL_trace); break; } case LITERAL_dataconv: { match(LITERAL_dataconv); break; } case LITERAL_mobredir: { match(LITERAL_mobredir); break; } case 172: { match(172); break; } case 173: { match(173); break; } case LITERAL_mobregreq: { match(LITERAL_mobregreq); break; } case LITERAL_mobregrep: { match(LITERAL_mobregrep); break; } case LITERAL_skip: { match(LITERAL_skip); break; } case LITERAL_photuris: { match(LITERAL_photuris); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_59); } } void PFCfgParser::port_op() { #line 1799 "pf.g" PortSpec ps; #line 6934 "PFCfgParser.cpp" try { // for error handling { switch ( LA(1)) { case EQUAL: case LESS_THAN: case GREATER_THAN: case EXLAMATION: { unary_op(); #line 1801 "pf.g" ps.port_op = importer->tmp_port_op; #line 6947 "PFCfgParser.cpp" port_def(); #line 1803 "pf.g" ps.port1 = importer->tmp_port_def; ps.port2 = importer->tmp_port_def; #line 6954 "PFCfgParser.cpp" break; } case WORD: case INT_CONST: { port_def(); #line 1809 "pf.g" ps.port1 = importer->tmp_port_def; ps.port2 = ps.port1; ps.port_op = "="; #line 6967 "PFCfgParser.cpp" { if ((LA(1) == LESS_THAN || LA(1) == GREATER_THAN || LA(1) == COLON) && (_tokenSet_50.member(LA(2)))) { binary_op(); #line 1815 "pf.g" ps.port_op = importer->tmp_port_op; #line 6973 "PFCfgParser.cpp" port_def(); #line 1816 "pf.g" ps.port2 = LT(0)->getText(); #line 6977 "PFCfgParser.cpp" } else if ((_tokenSet_60.member(LA(1))) && (_tokenSet_61.member(LA(2)))) { } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } break; } case IPV6: { match(IPV6); #line 1820 "pf.g" ps.setFromPortRange(LT(0)->getText()); #line 6995 "PFCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 1824 "pf.g" importer->tmp_port_group.push_back(ps); #line 7008 "PFCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_60); } } void PFCfgParser::port_op_list() { try { // for error handling match(OPENING_BRACE); port_op(); { // ( ... )* for (;;) { if ((_tokenSet_62.member(LA(1)))) { { switch ( LA(1)) { case COMMA: { match(COMMA); break; } case WORD: case EQUAL: case INT_CONST: case LESS_THAN: case GREATER_THAN: case EXLAMATION: case IPV6: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } port_op(); } else { goto _loop278; } } _loop278:; } // ( ... )* match(CLOSING_BRACE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_42); } } void PFCfgParser::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* PFCfgParser::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "NEWLINE", "COMMENT_START", "\"include\"", "WORD", "EQUAL", "\"antispoof\"", "\"altq\"", "\"queue\"", "\"set\"", "\"timeout\"", "\"ruleset-optimization\"", "\"optimization\"", "\"aggressive\"", "\"conservative\"", "\"high-latency\"", "\"normal\"", "\"satellite\"", "\"limit\"", "\"loginterface\"", "\"block-policy\"", "\"drop\"", "\"return\"", "\"state-policy\"", "\"if-bound\"", "\"floating\"", "\"state-defaults\"", "\"require-order\"", "\"fingerprints\"", "\"skip\"", "\"on\"", "OPENING_BRACE", "COMMA", "CLOSING_BRACE", "\"debug\"", "\"reassemble\"", "\"hostid\"", "\"tcp.first\"", "\"tcp.opening\"", "\"tcp.established\"", "\"tcp.closing\"", "\"tcp.finwait\"", "\"tcp.closed\"", "\"udp.first\"", "\"udp.single\"", "\"udp.multiple\"", "\"icmp.first\"", "\"icmp.error\"", "\"other.first\"", "\"other.single\"", "\"other.multiple\"", "\"frag\"", "\"interval\"", "\"src.track\"", "\"adaptive.start\"", "\"adaptive.end\"", "INT_CONST", "\"frags\"", "\"states\"", "\"src-nodes\"", "\"tables\"", "\"tables-entries\"", "\"scrub\"", "\"match\"", "\"table\"", "LESS_THAN", "GREATER_THAN", "\"persist\"", "\"const\"", "\"counters\"", "\"file\"", "STRING", "EXLAMATION", "COLON", "\"network\"", "\"broadcast\"", "\"peer\"", "\"self\"", "IPV4", "NUMBER", "SLASH", "\"no\"", "\"nat\"", "\"pass\"", "MINUS", "\"static-port\"", "\"rdr\"", "OPENING_PAREN", "CLOSING_PAREN", "\"port\"", "IPV6", "STAR", "\"bitmask\"", "\"random\"", "\"source-hash\"", "\"hex-key\"", "\"string-key\"", "\"round-robin\"", "\"sticky-address\"", "\"binat\"", "\"block\"", "\"return-rst\"", "TTL", "\"return-icmp\"", "RETURN_ICMP6", "\"in\"", "\"out\"", "\"log\"", "\"quick\"", "\"all\"", "\"user\"", "\"to\"", "\"inet\"", "\"inet6\"", "\"proto\"", "\"ip\"", "\"icmp\"", "\"igmp\"", "\"tcp\"", "\"udp\"", "\"rdp\"", "\"rsvp\"", "\"gre\"", "\"esp\"", "\"ah\"", "\"eigrp\"", "\"ospf\"", "\"ipip\"", "\"vrrp\"", "\"l2tp\"", "\"isis\"", "\"from\"", "\"urpf-failed\"", "\"any\"", "\"no-route\"", "MACRO", "\"route-to\"", "\"reply-to\"", "\"dup-to\"", "\"group\"", "\"fragment\"", "\"crop\"", "\"drop-ovl\"", "\"no-df\"", "\"min-ttl\"", "\"max-mss\"", "\"random-id\"", "\"flags\"", "\"icmp-type\"", "\"code\"", "\"echorep\"", "\"unreach\"", "\"squench\"", "\"redir\"", "\"althost\"", "\"echoreq\"", "\"routeradv\"", "\"routersol\"", "\"timex\"", "\"paramprob\"", "\"timereq\"", "\"timerep\"", "\"inforeq\"", "\"inforep\"", "\"maskreq\"", "\"maskrep\"", "\"trace\"", "\"dataconv\"", "\"mobredir\"", "\"ipv6-where\"", "\"ipv6-here\"", "\"mobregreq\"", "\"mobregrep\"", "\"photuris\"", "\"net-unr\"", "\"host-unr\"", "\"proto-unr\"", "\"port-unr\"", "\"needfrag\"", "\"srcfail\"", "\"net-unk\"", "\"host-unk\"", "\"isolate\"", "\"net-prohib\"", "\"host-prohib\"", "\"net-tos\"", "\"host-tos\"", "\"filter-prohib\"", "\"host-preced\"", "\"cutoff-preced\"", "\"redir-net\"", "\"redir-host\"", "\"redir-tos-net\"", "\"redir-tos-host\"", "\"normal-adv\"", "\"common-adv\"", "\"transit\"", "\"reassemb\"", "\"badhead\"", "\"optmiss\"", "\"badlen\"", "\"unknown-ind\"", "\"auth-fail\"", "\"decrypt-fail\"", "\"icmp6-type\"", "\"tagged\"", "\"tag\"", "\"keep\"", "\"modulate\"", "\"synproxy\"", "\"state\"", "\"label\"", "\"exit\"", "\"quit\"", "\"interface\"", "\"icmp6\"", "\"igrp\"", "\"ipsec\"", "\"nos\"", "\"pcp\"", "\"pim\"", "\"pptp\"", "\"rip\"", "\"snp\"", "\"host\"", "\"range\"", "\"alerts\"", "\"critical\"", "\"debugging\"", "\"emergencies\"", "\"errors\"", "\"informational\"", "\"notifications\"", "\"warnings\"", "\"disable\"", "\"inactive\"", "Whitespace", "HEX_CONST", "NEG_INT_CONST", "HEX_DIGIT", "DIGIT", "NUM_3DIGIT", "NUM_HEX_4DIGIT", "NUMBER_ADDRESS_OR_WORD", "PIPE_CHAR", "PERCENT", "AMPERSAND", "APOSTROPHE", "PLUS", "DOT", "SEMICOLON", "QUESTION", "COMMERCIAL_AT", "OPENING_SQUARE", "CLOSING_SQUARE", "CARET", "UNDERLINE", "TILDE", "DOUBLE_QUOTE", 0 }; const unsigned long PFCfgParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_0(_tokenSet_0_data_,10); const unsigned long PFCfgParser::_tokenSet_1_data_[] = { 7922UL, 0UL, 40894478UL, 192UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD "antispoof" "altq" "queue" // "set" "scrub" "match" "table" "no" "nat" "pass" "rdr" "binat" "block" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_1(_tokenSet_1_data_,10); const unsigned long PFCfgParser::_tokenSet_2_data_[] = { 128UL, 134217736UL, 460800UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD COMMA INT_CONST EXLAMATION "self" IPV4 NUMBER const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long PFCfgParser::_tokenSet_3_data_[] = { 7922UL, 134217496UL, 40894478UL, 192UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD "antispoof" "altq" "queue" // "set" COMMA CLOSING_BRACE "tcp.first" "tcp.opening" "tcp.established" // "tcp.closing" "tcp.finwait" "tcp.closed" "udp.first" "udp.single" "udp.multiple" // "icmp.first" "icmp.error" "other.first" "other.single" "other.multiple" // "frag" "interval" "src.track" "adaptive.start" "adaptive.end" "scrub" // "match" "table" "no" "nat" "pass" "rdr" "binat" "block" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_3(_tokenSet_3_data_,10); const unsigned long PFCfgParser::_tokenSet_4_data_[] = { 0UL, 134217480UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // COMMA "tcp.first" "tcp.opening" "tcp.established" "tcp.closing" "tcp.finwait" // "tcp.closed" "udp.first" "udp.single" "udp.multiple" "icmp.first" "icmp.error" // "other.first" "other.single" "other.multiple" "frag" "interval" "src.track" // "adaptive.start" "adaptive.end" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_4(_tokenSet_4_data_,10); const unsigned long PFCfgParser::_tokenSet_5_data_[] = { 7922UL, 4026531864UL, 40894479UL, 192UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD "antispoof" "altq" "queue" // "set" COMMA CLOSING_BRACE "frags" "states" "src-nodes" "tables" "tables-entries" // "scrub" "match" "table" "no" "nat" "pass" "rdr" "binat" "block" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_5(_tokenSet_5_data_,10); const unsigned long PFCfgParser::_tokenSet_6_data_[] = { 0UL, 4026531848UL, 1UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // COMMA "frags" "states" "src-nodes" "tables" "tables-entries" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_6(_tokenSet_6_data_,10); const unsigned long PFCfgParser::_tokenSet_7_data_[] = { 2064UL, 64UL, 68159490UL, 4128768UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN "all" // "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" "dup-to" // "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_7(_tokenSet_7_data_,16); const unsigned long PFCfgParser::_tokenSet_8_data_[] = { 8178UL, 134217805UL, 645598270UL, 4293329088UL, 4278190079UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" OPENING_BRACE COMMA "reassemble" INT_CONST "scrub" "match" // "table" LESS_THAN GREATER_THAN STRING EXLAMATION "self" IPV4 SLASH "no" // "nat" "pass" "rdr" OPENING_PAREN IPV6 "binat" "block" "all" "user" "to" // "proto" "ip" "icmp" "igmp" "tcp" "udp" "rdp" "rsvp" "gre" "esp" "ah" // "eigrp" "ospf" "ipip" "vrrp" "l2tp" "isis" "from" "urpf-failed" "any" // "no-route" MACRO "route-to" "reply-to" "dup-to" "group" "fragment" "crop" // "drop-ovl" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "echorep" "unreach" "squench" "redir" "althost" "echoreq" "routeradv" // "routersol" "timex" "paramprob" "timereq" "timerep" "inforeq" "inforep" // "maskreq" "maskrep" "trace" "dataconv" "mobredir" "ipv6-where" "ipv6-here" // "mobregreq" "mobregrep" "photuris" "icmp6-type" "tagged" "tag" "keep" // "modulate" "synproxy" "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_8(_tokenSet_8_data_,16); const unsigned long PFCfgParser::_tokenSet_9_data_[] = { 2064UL, 64UL, 68159490UL, 458752UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN "all" // "user" "to" "from" "route-to" "reply-to" "dup-to" "group" "fragment" // "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_9(_tokenSet_9_data_,16); const unsigned long PFCfgParser::_tokenSet_10_data_[] = { 8178UL, 134217805UL, 645598270UL, 33685696UL, 4278189952UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" OPENING_BRACE COMMA "reassemble" INT_CONST "scrub" "match" // "table" LESS_THAN GREATER_THAN STRING EXLAMATION "self" IPV4 SLASH "no" // "nat" "pass" "rdr" OPENING_PAREN IPV6 "binat" "block" "user" "tcp" "urpf-failed" // "any" "no-route" MACRO "route-to" "reply-to" "dup-to" "group" "fragment" // "crop" "drop-ovl" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "echorep" "unreach" "squench" "redir" "althost" "echoreq" "routeradv" // "routersol" "timex" "paramprob" "timereq" "timerep" "inforeq" "inforep" // "maskreq" "maskrep" "trace" "dataconv" "mobredir" "ipv6-where" "ipv6-here" // "mobregreq" "mobregrep" "photuris" "icmp6-type" "tagged" "tag" "keep" // "modulate" "synproxy" "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_10(_tokenSet_10_data_,16); const unsigned long PFCfgParser::_tokenSet_11_data_[] = { 2064UL, 64UL, 68159490UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN "user" // "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_11(_tokenSet_11_data_,16); const unsigned long PFCfgParser::_tokenSet_12_data_[] = { 8178UL, 134217805UL, 108530750UL, 33685696UL, 4278188288UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" OPENING_BRACE COMMA "reassemble" INT_CONST "scrub" "match" // "table" LESS_THAN GREATER_THAN STRING EXLAMATION SLASH "no" "nat" "pass" // "rdr" OPENING_PAREN "binat" "block" "user" "tcp" "any" "route-to" "reply-to" // "dup-to" "group" "fragment" "crop" "drop-ovl" "no-df" "min-ttl" "max-mss" // "random-id" "flags" "icmp-type" "echorep" "unreach" "squench" "redir" // "althost" "echoreq" "routeradv" "routersol" "timex" "paramprob" "timereq" // "timerep" "inforeq" "inforep" "maskreq" "maskrep" "trace" "dataconv" // "mobredir" "ipv6-where" "ipv6-here" "mobregreq" "mobregrep" "photuris" // "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_12(_tokenSet_12_data_,16); const unsigned long PFCfgParser::_tokenSet_13_data_[] = { 16UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_13(_tokenSet_13_data_,10); const unsigned long PFCfgParser::_tokenSet_14_data_[] = { 128UL, 134217752UL, 460800UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD COMMA CLOSING_BRACE INT_CONST EXLAMATION "self" IPV4 NUMBER const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_14(_tokenSet_14_data_,10); const unsigned long PFCfgParser::_tokenSet_15_data_[] = { 16UL, 2UL, 8390656UL, 3997696UL, 64UL, 0UL, 196608UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "on" EXLAMATION MINUS "all" "to" "inet" "inet6" "proto" "from" // "tagged" "tag" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_15(_tokenSet_15_data_,16); const unsigned long PFCfgParser::_tokenSet_16_data_[] = { 2064UL, 64UL, 76548098UL, 4128768UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "all" "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" // "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_16(_tokenSet_16_data_,16); const unsigned long PFCfgParser::_tokenSet_17_data_[] = { 2064UL, 64UL, 76548098UL, 2555904UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "all" "user" "to" "proto" "from" "route-to" "reply-to" "dup-to" "group" // "fragment" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_17(_tokenSet_17_data_,16); const unsigned long PFCfgParser::_tokenSet_18_data_[] = { 2064UL, 64UL, 76548098UL, 458752UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "all" "user" "to" "from" "route-to" "reply-to" "dup-to" "group" "fragment" // "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_18(_tokenSet_18_data_,16); const unsigned long PFCfgParser::_tokenSet_19_data_[] = { 2064UL, 64UL, 76548098UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "user" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_19(_tokenSet_19_data_,16); const unsigned long PFCfgParser::_tokenSet_20_data_[] = { 2064UL, 72UL, 76548098UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" COMMA "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "user" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_20(_tokenSet_20_data_,16); const unsigned long PFCfgParser::_tokenSet_21_data_[] = { 144UL, 24UL, 2499936256UL, 19UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE WORD COMMA CLOSING_BRACE IPV4 "static-port" OPENING_PAREN "port" // "bitmask" "random" "source-hash" "round-robin" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_21(_tokenSet_21_data_,10); const unsigned long PFCfgParser::_tokenSet_22_data_[] = { 128UL, 8UL, 67239936UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD COMMA IPV4 OPENING_PAREN const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_22(_tokenSet_22_data_,10); const unsigned long PFCfgParser::_tokenSet_23_data_[] = { 16UL, 0UL, 2432696320UL, 19UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "static-port" "port" "bitmask" "random" "source-hash" "round-robin" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_23(_tokenSet_23_data_,10); const unsigned long PFCfgParser::_tokenSet_24_data_[] = { 16UL, 0UL, 2164260864UL, 19UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "static-port" "bitmask" "random" "source-hash" "round-robin" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_24(_tokenSet_24_data_,10); const unsigned long PFCfgParser::_tokenSet_25_data_[] = { 2064UL, 64UL, 84936706UL, 4128768UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" "static-port" OPENING_PAREN // "all" "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" // "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_25(_tokenSet_25_data_,16); const unsigned long PFCfgParser::_tokenSet_26_data_[] = { 2448UL, 134217816UL, 2777684018UL, 393235UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE WORD EQUAL "queue" COMMA CLOSING_BRACE "reassemble" INT_CONST // "scrub" LESS_THAN GREATER_THAN EXLAMATION COLON "no" MINUS "static-port" // OPENING_PAREN IPV6 "bitmask" "random" "source-hash" "round-robin" "user" // "to" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_26(_tokenSet_26_data_,16); const unsigned long PFCfgParser::_tokenSet_27_data_[] = { 0UL, 134217728UL, 0UL, 0UL, 0UL, 4294836224UL, 32767UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // INT_CONST "net-unr" "host-unr" "proto-unr" "port-unr" "needfrag" "srcfail" // "net-unk" "host-unk" "isolate" "net-prohib" "host-prohib" "net-tos" // "host-tos" "filter-prohib" "host-preced" "cutoff-preced" "redir-net" // "redir-host" "redir-tos-net" "redir-tos-host" "normal-adv" "common-adv" // "transit" "reassemb" "badhead" "optmiss" "badlen" "unknown-ind" "auth-fail" // "decrypt-fail" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_27(_tokenSet_27_data_,16); const unsigned long PFCfgParser::_tokenSet_28_data_[] = { 2064UL, 66UL, 68159490UL, 4190208UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "on" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN // "in" "out" "log" "quick" "all" "user" "to" "inet" "inet6" "proto" "from" // "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_28(_tokenSet_28_data_,16); const unsigned long PFCfgParser::_tokenSet_29_data_[] = { 8178UL, 134217807UL, 645598270UL, 4294951104UL, 4278190079UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" "on" OPENING_BRACE COMMA "reassemble" INT_CONST "scrub" // "match" "table" LESS_THAN GREATER_THAN STRING EXLAMATION "self" IPV4 // SLASH "no" "nat" "pass" "rdr" OPENING_PAREN IPV6 "binat" "block" "log" // "quick" "all" "user" "to" "inet" "inet6" "proto" "ip" "icmp" "igmp" // "tcp" "udp" "rdp" "rsvp" "gre" "esp" "ah" "eigrp" "ospf" "ipip" "vrrp" // "l2tp" "isis" "from" "urpf-failed" "any" "no-route" MACRO "route-to" // "reply-to" "dup-to" "group" "fragment" "crop" "drop-ovl" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "echorep" "unreach" "squench" // "redir" "althost" "echoreq" "routeradv" "routersol" "timex" "paramprob" // "timereq" "timerep" "inforeq" "inforep" "maskreq" "maskrep" "trace" // "dataconv" "mobredir" "ipv6-where" "ipv6-here" "mobregreq" "mobregrep" // "photuris" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_29(_tokenSet_29_data_,16); const unsigned long PFCfgParser::_tokenSet_30_data_[] = { 2064UL, 134217817UL, 202377218UL, 131072UL, 4277991424UL, 131071UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "skip" COMMA CLOSING_BRACE "reassemble" INT_CONST "scrub" // EXLAMATION "no" OPENING_PAREN CLOSING_PAREN "user" "route-to" "reply-to" // "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "echorep" "unreach" "squench" "redir" "althost" // "echoreq" "routeradv" "routersol" "timex" "paramprob" "timereq" "timerep" // "inforeq" "inforep" "maskreq" "maskrep" "trace" "dataconv" "mobredir" // "ipv6-where" "ipv6-here" "mobregreq" "mobregrep" "photuris" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_30(_tokenSet_30_data_,16); const unsigned long PFCfgParser::_tokenSet_31_data_[] = { 2064UL, 66UL, 68159490UL, 4177920UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "on" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN // "log" "quick" "all" "user" "to" "inet" "inet6" "proto" "from" "route-to" // "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_31(_tokenSet_31_data_,16); const unsigned long PFCfgParser::_tokenSet_32_data_[] = { 2064UL, 66UL, 68159490UL, 4161536UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "on" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN // "quick" "all" "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" // "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_32(_tokenSet_32_data_,16); const unsigned long PFCfgParser::_tokenSet_33_data_[] = { 8178UL, 134217807UL, 645598270UL, 4294901952UL, 4278190079UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" "on" OPENING_BRACE COMMA "reassemble" INT_CONST "scrub" // "match" "table" LESS_THAN GREATER_THAN STRING EXLAMATION "self" IPV4 // SLASH "no" "nat" "pass" "rdr" OPENING_PAREN IPV6 "binat" "block" "all" // "user" "to" "inet" "inet6" "proto" "ip" "icmp" "igmp" "tcp" "udp" "rdp" // "rsvp" "gre" "esp" "ah" "eigrp" "ospf" "ipip" "vrrp" "l2tp" "isis" "from" // "urpf-failed" "any" "no-route" MACRO "route-to" "reply-to" "dup-to" // "group" "fragment" "crop" "drop-ovl" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "echorep" "unreach" "squench" "redir" "althost" // "echoreq" "routeradv" "routersol" "timex" "paramprob" "timereq" "timerep" // "inforeq" "inforep" "maskreq" "maskrep" "trace" "dataconv" "mobredir" // "ipv6-where" "ipv6-here" "mobregreq" "mobregrep" "photuris" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_33(_tokenSet_33_data_,16); const unsigned long PFCfgParser::_tokenSet_34_data_[] = { 2064UL, 66UL, 68159490UL, 4128768UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "on" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN // "all" "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" // "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_34(_tokenSet_34_data_,16); const unsigned long PFCfgParser::_tokenSet_35_data_[] = { 2048UL, 72UL, 68159490UL, 131072UL, 16564224UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "queue" COMMA "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN "user" // "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_35(_tokenSet_35_data_,16); const unsigned long PFCfgParser::_tokenSet_36_data_[] = { 16UL, 0UL, 0UL, 0UL, 14336UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "route-to" "reply-to" "dup-to" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_36(_tokenSet_36_data_,12); const unsigned long PFCfgParser::_tokenSet_37_data_[] = { 2064UL, 66UL, 76548098UL, 4161536UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "on" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "quick" "all" "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" // "dup-to" "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" // "flags" "icmp-type" "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" // "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_37(_tokenSet_37_data_,16); const unsigned long PFCfgParser::_tokenSet_38_data_[] = { 0UL, 8UL, 134217728UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // COMMA CLOSING_PAREN const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_38(_tokenSet_38_data_,10); const unsigned long PFCfgParser::_tokenSet_39_data_[] = { 2192UL, 88UL, 76548098UL, 4128768UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE WORD "queue" COMMA CLOSING_BRACE "reassemble" "scrub" EXLAMATION // "no" MINUS OPENING_PAREN "all" "user" "to" "inet" "inet6" "proto" "from" // "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_39(_tokenSet_39_data_,16); const unsigned long PFCfgParser::_tokenSet_40_data_[] = { 2064UL, 134217820UL, 76548098UL, 4291231744UL, 16578687UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" OPENING_BRACE COMMA CLOSING_BRACE "reassemble" INT_CONST // "scrub" EXLAMATION "no" MINUS OPENING_PAREN "all" "user" "to" "ip" "icmp" // "igmp" "tcp" "udp" "rdp" "rsvp" "gre" "esp" "ah" "eigrp" "ospf" "ipip" // "vrrp" "l2tp" "isis" "from" "route-to" "reply-to" "dup-to" "group" "fragment" // "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_40(_tokenSet_40_data_,16); const unsigned long PFCfgParser::_tokenSet_41_data_[] = { 0UL, 134217740UL, 0UL, 4290772992UL, 63UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // OPENING_BRACE COMMA INT_CONST "ip" "icmp" "igmp" "tcp" "udp" "rdp" "rsvp" // "gre" "esp" "ah" "eigrp" "ospf" "ipip" "vrrp" "l2tp" "isis" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_41(_tokenSet_41_data_,12); const unsigned long PFCfgParser::_tokenSet_42_data_[] = { 2064UL, 64UL, 76548098UL, 393216UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "user" "to" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" // "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" // "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_42(_tokenSet_42_data_,16); const unsigned long PFCfgParser::_tokenSet_43_data_[] = { 2064UL, 64UL, 344983554UL, 393216UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "port" "user" "to" "route-to" "reply-to" "dup-to" "group" "fragment" // "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_43(_tokenSet_43_data_,16); const unsigned long PFCfgParser::_tokenSet_44_data_[] = { 2064UL, 64UL, 344983554UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" MINUS OPENING_PAREN // "port" "user" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" // "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" // "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_44(_tokenSet_44_data_,16); const unsigned long PFCfgParser::_tokenSet_45_data_[] = { 2192UL, 88UL, 882051090UL, 393216UL, 16579584UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE WORD "queue" COMMA CLOSING_BRACE "reassemble" "scrub" LESS_THAN // EXLAMATION "self" IPV4 "no" MINUS OPENING_PAREN "port" IPV6 "user" "to" // MACRO "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_45(_tokenSet_45_data_,16); const unsigned long PFCfgParser::_tokenSet_46_data_[] = { 128UL, 8UL, 604178448UL, 0UL, 1024UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD COMMA LESS_THAN EXLAMATION "self" IPV4 OPENING_PAREN IPV6 MACRO const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_46(_tokenSet_46_data_,12); const unsigned long PFCfgParser::_tokenSet_47_data_[] = { 2064UL, 88UL, 2215643138UL, 4128787UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" COMMA CLOSING_BRACE "reassemble" "scrub" EXLAMATION // "no" OPENING_PAREN "bitmask" "random" "source-hash" "round-robin" "all" // "user" "to" "inet" "inet6" "proto" "from" "route-to" "reply-to" "dup-to" // "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_47(_tokenSet_47_data_,16); const unsigned long PFCfgParser::_tokenSet_48_data_[] = { 2064UL, 64UL, 2215643138UL, 4128787UL, 16578624UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN "bitmask" // "random" "source-hash" "round-robin" "all" "user" "to" "inet" "inet6" // "proto" "from" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" // "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" // "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_48(_tokenSet_48_data_,16); const unsigned long PFCfgParser::_tokenSet_49_data_[] = { 2064UL, 72UL, 68159490UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" COMMA "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN // "user" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_49(_tokenSet_49_data_,16); const unsigned long PFCfgParser::_tokenSet_50_data_[] = { 128UL, 134217728UL, 48UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD INT_CONST LESS_THAN GREATER_THAN const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_50(_tokenSet_50_data_,10); const unsigned long PFCfgParser::_tokenSet_51_data_[] = { 2448UL, 134217816UL, 68159538UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE WORD EQUAL "queue" COMMA CLOSING_BRACE "reassemble" INT_CONST // "scrub" LESS_THAN GREATER_THAN EXLAMATION "no" OPENING_PAREN "user" // "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" "min-ttl" // "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" "tag" // "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_51(_tokenSet_51_data_,16); const unsigned long PFCfgParser::_tokenSet_52_data_[] = { 8178UL, 134217821UL, 108534846UL, 33685696UL, 4278188288UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" OPENING_BRACE COMMA CLOSING_BRACE "reassemble" INT_CONST // "scrub" "match" "table" LESS_THAN GREATER_THAN STRING EXLAMATION COLON // SLASH "no" "nat" "pass" "rdr" OPENING_PAREN "binat" "block" "user" "tcp" // "any" "route-to" "reply-to" "dup-to" "group" "fragment" "crop" "drop-ovl" // "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "echorep" // "unreach" "squench" "redir" "althost" "echoreq" "routeradv" "routersol" // "timex" "paramprob" "timereq" "timerep" "inforeq" "inforep" "maskreq" // "maskrep" "trace" "dataconv" "mobredir" "ipv6-where" "ipv6-here" "mobregreq" // "mobregrep" "photuris" "icmp6-type" "tagged" "tag" "keep" "modulate" // "synproxy" "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_52(_tokenSet_52_data_,16); const unsigned long PFCfgParser::_tokenSet_53_data_[] = { 384UL, 134217736UL, 2096UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD EQUAL COMMA INT_CONST LESS_THAN GREATER_THAN EXLAMATION const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_53(_tokenSet_53_data_,10); const unsigned long PFCfgParser::_tokenSet_54_data_[] = { 128UL, 134217728UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD INT_CONST const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_54(_tokenSet_54_data_,10); const unsigned long PFCfgParser::_tokenSet_55_data_[] = { 2064UL, 72UL, 202377218UL, 131072UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" COMMA "reassemble" "scrub" EXLAMATION "no" OPENING_PAREN // CLOSING_PAREN "user" "route-to" "reply-to" "dup-to" "group" "fragment" // "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" // "tagged" "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_55(_tokenSet_55_data_,16); const unsigned long PFCfgParser::_tokenSet_56_data_[] = { 0UL, 72UL, 0UL, 0UL, 3964928UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // COMMA "reassemble" "fragment" "no-df" "min-ttl" "max-mss" "random-id" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_56(_tokenSet_56_data_,12); const unsigned long PFCfgParser::_tokenSet_57_data_[] = { 2064UL, 134217817UL, 68159490UL, 131072UL, 4277991424UL, 131071UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "skip" COMMA CLOSING_BRACE "reassemble" INT_CONST "scrub" // EXLAMATION "no" OPENING_PAREN "user" "route-to" "reply-to" "dup-to" // "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "echorep" "unreach" "squench" "redir" "althost" "echoreq" "routeradv" // "routersol" "timex" "paramprob" "timereq" "timerep" "inforeq" "inforep" // "maskreq" "maskrep" "trace" "dataconv" "mobredir" "ipv6-where" "ipv6-here" // "mobregreq" "mobregrep" "photuris" "icmp6-type" "tagged" "tag" "keep" // "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_57(_tokenSet_57_data_,16); const unsigned long PFCfgParser::_tokenSet_58_data_[] = { 0UL, 134217737UL, 0UL, 0UL, 4261412864UL, 131071UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // "skip" COMMA INT_CONST "echorep" "unreach" "squench" "redir" "althost" // "echoreq" "routeradv" "routersol" "timex" "paramprob" "timereq" "timerep" // "inforeq" "inforep" "maskreq" "maskrep" "trace" "dataconv" "mobredir" // "ipv6-where" "ipv6-here" "mobregreq" "mobregrep" "photuris" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_58(_tokenSet_58_data_,12); const unsigned long PFCfgParser::_tokenSet_59_data_[] = { 2064UL, 134217817UL, 68159490UL, 131072UL, 4294768640UL, 131071UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE "queue" "skip" COMMA CLOSING_BRACE "reassemble" INT_CONST "scrub" // EXLAMATION "no" OPENING_PAREN "user" "route-to" "reply-to" "dup-to" // "group" "fragment" "no-df" "min-ttl" "max-mss" "random-id" "flags" "icmp-type" // "code" "echorep" "unreach" "squench" "redir" "althost" "echoreq" "routeradv" // "routersol" "timex" "paramprob" "timereq" "timerep" "inforeq" "inforep" // "maskreq" "maskrep" "trace" "dataconv" "mobredir" "ipv6-where" "ipv6-here" // "mobregreq" "mobregrep" "photuris" "icmp6-type" "tagged" "tag" "keep" // "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_59(_tokenSet_59_data_,16); const unsigned long PFCfgParser::_tokenSet_60_data_[] = { 2448UL, 134217816UL, 613419058UL, 393216UL, 16578560UL, 0UL, 6258688UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // NEWLINE WORD EQUAL "queue" COMMA CLOSING_BRACE "reassemble" INT_CONST // "scrub" LESS_THAN GREATER_THAN EXLAMATION "no" MINUS OPENING_PAREN IPV6 // "user" "to" "route-to" "reply-to" "dup-to" "group" "fragment" "no-df" // "min-ttl" "max-mss" "random-id" "flags" "icmp-type" "icmp6-type" "tagged" // "tag" "keep" "modulate" "synproxy" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_60(_tokenSet_60_data_,16); const unsigned long PFCfgParser::_tokenSet_61_data_[] = { 8178UL, 134217821UL, 653990974UL, 33947840UL, 4278189824UL, 131071UL, 8355840UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // EOF NEWLINE COMMENT_START "include" WORD EQUAL "antispoof" "altq" "queue" // "set" "skip" OPENING_BRACE COMMA CLOSING_BRACE "reassemble" INT_CONST // "scrub" "match" "table" LESS_THAN GREATER_THAN STRING EXLAMATION COLON // "self" IPV4 SLASH "no" "nat" "pass" MINUS "rdr" OPENING_PAREN IPV6 "binat" // "block" "user" "to" "tcp" "any" "no-route" MACRO "route-to" "reply-to" // "dup-to" "group" "fragment" "crop" "drop-ovl" "no-df" "min-ttl" "max-mss" // "random-id" "flags" "icmp-type" "echorep" "unreach" "squench" "redir" // "althost" "echoreq" "routeradv" "routersol" "timex" "paramprob" "timereq" // "timerep" "inforeq" "inforep" "maskreq" "maskrep" "trace" "dataconv" // "mobredir" "ipv6-where" "ipv6-here" "mobregreq" "mobregrep" "photuris" // "icmp6-type" "tagged" "tag" "keep" "modulate" "synproxy" "state" "label" const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_61(_tokenSet_61_data_,16); const unsigned long PFCfgParser::_tokenSet_62_data_[] = { 384UL, 134217736UL, 536873008UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // WORD EQUAL COMMA INT_CONST LESS_THAN GREATER_THAN EXLAMATION IPV6 const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgParser::_tokenSet_62(_tokenSet_62_data_,10); fwbuilder-5.1.0.3599/src/parsers/iptables.g0000644000175000017500000011721411733011756021225 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Note about negation: this grammar parses only extrapositioned negation "! -s address" for all recognized options that can have it. Intrapositioned negation ("-s ! address") should be converted to extrapositioned in IPTImporter class before running the parser. */ header "pre_include_hpp" { // gets inserted before antlr generated includes in the header // file #include "IPTImporter.h" } header "post_include_hpp" { // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class IPTImporter; } header "pre_include_cpp" { // gets inserted before the antlr generated includes in the cpp // file } header "post_include_cpp" { // gets inserted after the antlr generated includes in the cpp // file #include #include #include "fwbuilder/TCPService.h" #include "fwbuilder/Logger.h" #include } header { // gets inserted after generated namespace specifications in the // header file. But outside the generated class. } options { language="Cpp"; } class IPTCfgParser extends Parser; options { k = 2; // defaultErrorHandler=false; } { // additional methods and members public: std::ostream *dbg; IPTImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); std::cerr << s << std::endl; } } cfgfile : ( comment | start_table | create_chain | add_rule | commit | NEWLINE )+ ; //**************************************************************** // comment can be iptables-save header or a regular comment // Examples of the header: // // # Generated by iptables-save v1.3.5 on Mon Apr 11 15:32:22 2011 // # Generated by iptables-save v1.4.1.1 on Fri Mar 4 12:14:55 2011 // comment : NUMBER_SIGN ( IPTABLES_SAVE_HEADER ( THREE_COMPONENT_VERSION | IPV4 ) { importer->setCurrentLineNumber(LT(0)->getLine()); std::string version = LT(0)->getText(); importer->setDiscoveredVersion(version); *dbg << "VERSION " << version << std::endl; consumeUntil(NEWLINE); } )* { consumeUntil(NEWLINE); } ; //**************************************************************** //**************************************************************** commit : COMMIT { // push last rule importer->pushRule(); *dbg << " COMMIT" << std::endl; // clear current table importer->current_table = ""; } ; //**************************************************************** start_table : STAR WORD { if (!importer->current_table.empty()) { // we did not see COMMIT *(importer->logger) << "********************************\n"; *(importer->logger) << "Missing COMMIT for the table " << importer->current_table << "\n"; *(importer->logger) << "Perhaps the file is broken ?" << "\n"; *(importer->logger) << "********************************\n"; *dbg << "Missing COMMIT for the table " << importer->current_table; *dbg << "Perhaps the file is broken ?"; // push last rule importer->pushRule(); // clear current table importer->current_table = ""; } importer->registerTable(LT(0)->getText()); *dbg << "TABLE " << LT(0)->getText() << std::endl; } ; //**************************************************************** chain_def : (INPUT | FORWARD | OUTPUT | PREROUTING | POSTROUTING | WORD) ; //**************************************************************** // // :INPUT DROP [2:104] // :FORWARD DROP [0:0] // :OUTPUT DROP [1:1492] // :Cid4089E41E.0 - [0:0] // :Cid45349B7222600.0 - [0:0] create_chain : COLON chain_def { importer->setCurrentLineNumber(LT(0)->getLine()); if (importer->current_table=="nat") importer->newUnidirRuleSet(LT(0)->getText(), libfwbuilder::NAT::TYPENAME); else importer->newUnidirRuleSet(LT(0)->getText(), libfwbuilder::Policy::TYPENAME); *dbg << "NEW CHAIN " << LT(0)->getText() << std::endl; } (WORD | MINUS) { importer->setDefaultAction(LT(0)->getText()); *dbg << "DEFAULT ACTION " << LT(0)->getText() << std::endl; } (OPENING_SQUARE INT_CONST COLON INT_CONST CLOSING_SQUARE)? ; //**************************************************************** add_rule : ADD_RULE chain_def { // push previous rule *dbg << std::endl; importer->pushRule(); // start new one importer->setCurrentLineNumber(LT(0)->getLine()); if (importer->current_table=="nat") importer->newNATRule(); else importer->newPolicyRule(); importer->current_chain = LT(0)->getText(); *dbg << "add_rule: line=" << LT(0)->getLine() << " chain=" << LT(0)->getText(); } ( ipt_option )+ NEWLINE ; //**************************************************************** ipt_option : ( negation | module | match_mark | match_recent | src | dst | i_intf | o_intf | proto | target | fragm | icmp_type_spec | basic_tcp_udp_port_spec | multiport_tcp_udp_port_spec | tcp_options | match_limit | match_limit_burst | match_length | match_iprange_src | match_iprange_dst | unknown_option ) ; //**************************************************************** negation : EXCLAMATION { importer->tmp_neg = true; } ; //**************************************************************** unknown_option : ( MINUS WORD { importer->reportError( std::string("Unknown option: -")+LT(0)->getText()); *dbg << " UNKNOWN OPTION=-" << LT(0)->getText(); } (unknown_parameter)? ) | ( ( MINUS MINUS WORD ) { importer->reportError( std::string("Unknown option: --")+LT(0)->getText()); *dbg << " UNKNOWN OPTION=--" << LT(0)->getText(); } (unknown_parameter)? ) | ( UNSUPPORTED_OPTION { importer->reportError( std::string("Unknown option: ")+LT(0)->getText()); *dbg << " UNKNOWN OPTION=" << LT(0)->getText(); } (unknown_parameter)? ) ; unknown_parameter { std::string s; } : ( ( ( DIGIT {s+=LT(0)->getText();} | INT_CONST {s+=LT(0)->getText();} ) SLASH {s+=LT(0)->getText();} WORD {s+=LT(0)->getText();} ) { importer->reportError( std::string("Unknown parameter: ")+s); *dbg << " UNKNOWN PARMETER=" << s; } ) | ( (DIGIT | INT_CONST | WORD) { importer->reportError( std::string("Unknown parameter: ")+LT(0)->getText()); *dbg << " UNKNOWN PARMETER=" << LT(0)->getText(); } ) ; //**************************************************************** // this matches "-m module", except for modules "mark" and "recent" // which have some parameters that look the same as parameters for // other modules. See match_mark and match_recent module : OPT_MODULE ( m_state | m_mport | m_icmp | m_tcp | m_udp | m_limit | m_length | m_iprange | m_comment | m_pkttype | m_unknown_module) ; //**************************************************************** src : OPT_SRC { *dbg << " SRC="; importer->src_neg = importer->tmp_neg; importer->tmp_neg = false; } ( (WORD | IPV4) { importer->src_a = LT(0)->getText(); *dbg << LT(0)->getText(); } (SLASH (IPV4 | INT_CONST) { importer->src_nm = LT(0)->getText(); *dbg << "/" << LT(0)->getText(); } )? ) ; //**************************************************************** dst : OPT_DST { *dbg << " DST="; importer->dst_neg = importer->tmp_neg; importer->tmp_neg = false; } ( (WORD | IPV4) { importer->dst_a = LT(0)->getText(); *dbg << LT(0)->getText(); } (SLASH (IPV4 | INT_CONST) { importer->dst_nm = LT(0)->getText(); *dbg << "/" << LT(0)->getText(); } )? ) ; //**************************************************************** i_intf : OPT_IN_INTF { importer->intf_neg = importer->tmp_neg; importer->tmp_neg = false; } WORD { importer->i_intf = LT(0)->getText(); *dbg << " I_INTF=" << LT(0)->getText(); } ; //**************************************************************** o_intf : OPT_OUT_INTF { importer->intf_neg = importer->tmp_neg; importer->tmp_neg = false; } WORD { importer->o_intf = LT(0)->getText(); *dbg << " O_INTF=" << LT(0)->getText(); } ; //**************************************************************** protocol_word : (TCP | UDP | ICMP | WORD | INT_CONST ) ; proto : OPT_PROTO { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; } protocol_word { std::string tmp_s = LT(0)->getText(); importer->protocol.resize(tmp_s.size()); std::transform(tmp_s.begin(), tmp_s.end(), importer->protocol.begin(), ::tolower); *dbg << " PROTO=" << importer->protocol; } ; //**************************************************************** target : OPT_TARGET t:WORD { importer->target = LT(0)->getText(); *dbg << " TARGET=" << t->getText(); } ( target_options )* ; //**************************************************************** target_options : ( REJECT_WITH WORD { importer->action_params["reject_with"] = LT(0)->getText(); *dbg << " REJECT WITH=" << LT(0)->getText(); } | LOG_PREFIX (WORD | STRING) { importer->action_params["log_prefix"] = LT(0)->getText(); *dbg << " LOG PREFIX=" << LT(0)->getText(); } | LOG_TCP_SEQ { importer->action_params["log_tcp_seq"] = LT(0)->getText(); *dbg << " LOG TCP SEQUENCE="; } | LOG_TCP_OPT { importer->action_params["log_tcp_options"] = LT(0)->getText(); *dbg << " LOG TCP OPTIONS="; } | LOG_IP_OPT { importer->action_params["log_ip_options"] = LT(0)->getText(); *dbg << " LOG IP OPTIONS="; } | ULOG_PREFIX (WORD | STRING) { importer->action_params["log_prefix"] = LT(0)->getText(); *dbg << " ULOG PREFIX=" << LT(0)->getText(); } | LOG_LEVEL (INT_CONST | WORD) { importer->action_params["log_level"] = LT(0)->getText(); *dbg << " LOG LEVEL=" << LT(0)->getText(); } | SET_CLASS major:INT_CONST COLON minor:INT_CONST { importer->action_params["set_class"] = major->getText() + ":" + minor->getText(); *dbg << " SET CLASS=" << major->getText() + ":" + minor->getText(); } | SET_MARK (INT_CONST | HEX_CONST) { importer->action_params["set_mark"] = LT(0)->getText(); *dbg << " SET MARK=" << LT(0)->getText(); } | SET_TOS HEX_CONST { importer->action_params["set_tos"] = LT(0)->getText(); *dbg << " SET TOS=" << LT(0)->getText(); } | SET_TOS WORD { importer->action_params["set_tos"] = LT(0)->getText(); *dbg << " SET TOS=" << LT(0)->getText(); } | SAVE_MARK { importer->action_params["connmark_save_mark"] = "--save-mark"; *dbg << " SAVE MARK"; } | RESTORE_MARK { importer->action_params["connmark_restore_mark"] = "--restore-mark"; *dbg << " RESTORE MARK"; } | CONTINUE { importer->action_params["route_continue"] = "--continue"; *dbg << " CONTINUE"; } | ROUTE_IIF WORD { importer->action_params["route_iif"] = LT(0)->getText(); *dbg << " ROUTE_IIF=" << LT(0)->getText(); } | ROUTE_OIF WORD { importer->action_params["route_oif"] = LT(0)->getText(); *dbg << " ROUTE_OIF=" << LT(0)->getText(); } | ROUTE_GW IPV4 { importer->action_params["route_gw"] = LT(0)->getText(); *dbg << " ROUTE_GW=" << LT(0)->getText(); } | ROUTE_TEE { importer->action_params["route_tee"] = "--tee"; *dbg << " ROUTE_TEE"; } | TO_SOURCE { *dbg << " TO-SOURCE"; } nat_spec | TO_DESTINATION { *dbg << " TO-DESTINATION"; } nat_spec | TO_PORTS redirect_spec | TO_NETMAP { *dbg << " TO-NETMAP"; } ( IPV4 { importer->nat_addr1 = LT(0)->getText(); importer->nat_addr2 = LT(0)->getText(); *dbg << LT(0)->getText(); } SLASH (IPV4 | INT_CONST) { importer->nat_nm = LT(0)->getText(); *dbg << "/" << LT(0)->getText(); } ) | CLAMP_MSS { importer->action_params["clamp-mss-to-pmtu"] = "--clamp-mss-to-pmtu"; *dbg << " TO-NETMAP"; } ) ; //**************************************************************** nat_spec : nat_addr_range (COLON nat_port_def_with_range)? { *dbg << " " << importer->nat_addr1 << "-" << importer->nat_addr2 << ":" << importer->nat_port_range_start << "-" << importer->nat_port_range_end; } ; //**************************************************************** nat_addr_range : (IPV4 MINUS) => ( a1:IPV4 MINUS a2:IPV4 { importer->nat_port_range_start = ""; importer->nat_port_range_end = ""; importer->nat_addr1 = a1->getText(); importer->nat_addr2 = a2->getText(); } ) | IPV4 { importer->nat_port_range_start = ""; importer->nat_port_range_end = ""; importer->nat_addr1 = LT(0)->getText(); importer->nat_addr2 = LT(0)->getText(); } ; //**************************************************************** redirect_spec : nat_port_def_with_range { *dbg << " TO-PORTS " << importer->nat_addr1 << "-" << importer->nat_addr2 << ":" << importer->nat_port_range_start << "-" << importer->nat_port_range_end; } ; //**************************************************************** fragm : OPT_FRAGM { importer->fragments = true; *dbg << " FRAGM"; } ; //**************************************************************** m_unknown_module : WORD { *dbg << " UNKNOWN MODULE=" << LT(0)->getText(); importer->reportError( std::string("Unknown module: ")+LT(0)->getText()); } ; //**************************************************************** state_word : ( INVALID | NEW | ESTABLISHED | RELATED ) ; m_state : M_STATE MATCH_STATE { importer->current_state = ""; } state_word { importer->current_state += LT(0)->getText(); } ( COMMA state_word { importer->current_state += std::string(",") + LT(0)->getText(); } )* { *dbg << " STATE MATCH=" << importer->current_state; } ; //**************************************************************** m_mark : M_MARK { *dbg << " MARK"; } ; //**************************************************************** match_mark : OPT_MODULE m_mark ( EXCLAMATION {importer->neg_match_mark = true;} )? MATCH_MARK (INT_CONST | HEX_CONST) { importer->tmp_neg = false; importer->match_mark = LT(0)->getText(); *dbg << " MATCH MARK " << LT(0)->getText(); } ; //**************************************************************** m_limit : M_LIMIT { *dbg << " LIMIT"; } ; //**************************************************************** match_limit : MATCH_LIMIT limit_rate ; limit_rate : INT_CONST { importer->limit_val = LT(0)->getText(); } SLASH WORD { importer->limit_suffix = LT(0)->getText(); } { *dbg << " MATCH LIMIT " << importer->limit_val << "/" << importer->limit_suffix; } ; match_limit_burst : MATCH_LIMIT_BURST INT_CONST { importer->limit_burst = LT(0)->getText(); *dbg << " LIMIT BURST " << LT(0)->getText(); } ; //**************************************************************** m_recent : M_RECENT { *dbg << " RECENT"; } ; //**************************************************************** m_iprange : M_IPRANGE { *dbg << " IPRANGE"; } ; match_iprange_src : MATCH_IPRANGE_SRC (WORD | IPV4) { importer->iprange_src_from = LT(0)->getText(); importer->using_iprange_src = true; } MINUS (WORD | IPV4) { importer->iprange_src_to = LT(0)->getText(); } ; match_iprange_dst : MATCH_IPRANGE_DST (WORD | IPV4) { importer->iprange_dst_from = LT(0)->getText(); importer->using_iprange_dst = true; } MINUS (WORD | IPV4) { importer->iprange_dst_to = LT(0)->getText(); } ; //**************************************************************** /* Unlike with other modules, this matches both "-m recent" and * module arguments * I am having difficulties writing grammar to catch negation * in front of arguments, such as ! --set */ match_recent : OPT_MODULE m_recent ( recent_opts )+ ; recent_opts: recent_args_no_param | recent_args_param ; recent_args_no_param: (MATCH_RECENT_SET | MATCH_RECENT_RCHECK | MATCH_RECENT_UPDATE | MATCH_RECENT_REMOVE | MATCH_RECENT_RTTL | RSOURCE | MATCH_RECENT_RDEST) { importer->recent_match += LT(0)->getText() + " "; } ; recent_args_param: (MATCH_RECENT_NAME | MATCH_RECENT_SECONDS | MATCH_RECENT_HITCOUNT) { importer->recent_match += LT(0)->getText() + " "; } (INT_CONST | WORD) { importer->recent_match += LT(0)->getText() + " "; } ; //**************************************************************** m_length : M_LENGTH { *dbg << " LENGTH"; } ; //**************************************************************** match_length : MATCH_LENGTH length_spec ; length_spec : INT_CONST { importer->length_spec = LT(0)->getText(); } COLON INT_CONST { importer->length_spec += ":"; importer->length_spec += LT(0)->getText(); } { *dbg << " MATCH LENGTH " << importer->length_spec; } ; //**************************************************************** m_pkttype: M_PKTTYPE MATCH_PKT_TYPE pkt_type_spec ; pkt_type_spec : (WORD_BROADCAST | WORD_MULTICAST | WORD_UNICAST) { importer->pkt_type_spec = LT(0)->getText(); *dbg << " PKT_TYPE " << importer->pkt_type_spec; } ; //**************************************************************** m_mport : M_MPORT { *dbg << " MULTIPORT"; } ; //**************************************************************** m_comment : M_COMMENT MATCH_COMMENT STRING { *dbg << " COMMENT=" << LT(0)->getText(); } ; //**************************************************************** /* * Note that there can be just one port (i.e. no ,port[,port] part) * * Note also that we do little preprocessing of the iptables lines * before passing them to the parser in IPTImporter::run(). Specifically, * we replace --sport and --dport with --source-ports and --destination-ports * for module multiport to avoid ambiguity that arises from different * rules that arguments for the --sport and --dport parameters can follow * depending on the module. */ multiport_tcp_udp_port_spec : ( ( MATCH_SRC_MULTIPORT { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; importer->startSrcMultiPort(); *dbg << " SRC MULTIPORT="; } port_def_with_range { importer->pushTmpPortSpecToSrcPortList(); } ( COMMA port_def_with_range { importer->pushTmpPortSpecToSrcPortList(); } )* ) | ( MATCH_DST_MULTIPORT { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; importer->startDstMultiPort(); *dbg << " DST MULTIPORT="; } port_def_with_range { importer->pushTmpPortSpecToDstPortList(); } ( COMMA port_def_with_range { importer->pushTmpPortSpecToDstPortList(); } )* ) | ( MATCH_BOTH_MULTIPORT { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; importer->startBothMultiPort(); *dbg << " MULTIPORT PORTS="; } port_def_with_range { importer->pushTmpPortSpecToBothPortList(); } ( COMMA port_def_with_range { importer->pushTmpPortSpecToBothPortList(); } )* ) ) ; //**************************************************************** m_icmp : ICMP { importer->protocol = "icmp"; *dbg << " ICMP"; } ; //**************************************************************** icmp_type_spec : MATCH_ICMP_TYPE ( WORD { importer->icmp_spec = LT(0)->getText(); *dbg << " ICMP_SPEC=" << LT(0)->getText(); } | ( INT_CONST { importer->icmp_type = LT(0)->getText(); importer->icmp_code = "-1"; *dbg << " ICMP_TYPE=" << LT(0)->getText(); } ( SLASH INT_CONST { importer->icmp_code = LT(0)->getText(); *dbg << " ICMP_CODE=" << LT(0)->getText(); } )? ) ) ; //**************************************************************** // port definition that does not allow for port range port_def_no_range : (WORD|INT_CONST) { importer->tmp_port_range_start = LT(0)->getText(); importer->tmp_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); } ; /**************************************************************** * port definition that allows for port range. That parser should * recognize constructs * * port1 ---> range_start = range_end = port1 * port1:port2 ---> range_start = port1 range_end = port2 * port1: ---> range_start = port1 range_end = 65535 * :port2 ---> range_start = 0 range_end = port2 */ port_def_with_range : (WORD|INT_CONST) { importer->tmp_port_range_start = LT(0)->getText(); importer->tmp_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); } ( COLON (WORD|INT_CONST)? { importer->tmp_port_range_end = LT(0)->getText(); *dbg << ":" << LT(0)->getText(); } )? ; port_def_with_incomplete_range : COLON (WORD|INT_CONST) { importer->tmp_port_range_start = "0"; importer->tmp_port_range_end = LT(0)->getText(); *dbg << "PORT 0:" << LT(0)->getText(); } ; //**************************************************************** // nat port definition that allows for port range // (uses '-' instead of ':') nat_port_def_with_range : ((WORD | INT_CONST) MINUS) => ( (WORD | INT_CONST) { importer->nat_port_range_start = LT(0)->getText(); importer->nat_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); } MINUS (WORD | INT_CONST) { importer->nat_port_range_end = LT(0)->getText(); *dbg << ":" << LT(0)->getText(); } ) | (WORD | INT_CONST) { importer->nat_port_range_start = LT(0)->getText(); importer->nat_port_range_end = LT(0)->getText(); *dbg << " PORT=" << LT(0)->getText(); } ; //**************************************************************** basic_tcp_udp_port_spec : (MATCH_SRC_PORT | MATCH_SRC_PORT_SHORT) { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; } (port_def_with_range | port_def_with_incomplete_range) { importer->pushTmpPortSpecToSrcPortList(); } | (MATCH_DST_PORT | MATCH_DST_PORT_SHORT) { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; } (port_def_with_range | port_def_with_incomplete_range) { importer->pushTmpPortSpecToDstPortList(); } ; //**************************************************************** m_udp : UDP { importer->protocol = "udp"; *dbg << " UDP"; } ; //**************************************************************** m_tcp : TCP { importer->protocol = "tcp"; *dbg << " TCP"; } ; //**************************************************************** // tcp options can follow "-p tcp", the "-m tcp" seems to be optional, // at least in the older versions of iptables tcp_options : ( syn | tcp_flags | tcp_option) { importer->srv_neg = importer->tmp_neg; importer->tmp_neg = false; } ; syn : MATCH_SYN { importer->tcp_flags_mask.clear(); importer->tcp_flags_mask.push_back(libfwbuilder::TCPService::SYN); importer->tcp_flags_mask.push_back(libfwbuilder::TCPService::RST); importer->tcp_flags_mask.push_back(libfwbuilder::TCPService::ACK); importer->tcp_flags_comp.clear(); importer->tcp_flags_comp.push_back(libfwbuilder::TCPService::SYN); } ; tcp_flag_word : ( SYN { importer->tmp_tcp_flag_code = libfwbuilder::TCPService::SYN; } | ACK { importer->tmp_tcp_flag_code = libfwbuilder::TCPService::ACK; } | FIN { importer->tmp_tcp_flag_code = libfwbuilder::TCPService::FIN; } | RST { importer->tmp_tcp_flag_code = libfwbuilder::TCPService::RST; } | URG { importer->tmp_tcp_flag_code = libfwbuilder::TCPService::URG; } | PSH { importer->tmp_tcp_flag_code = libfwbuilder::TCPService::PSH; } | ALL { importer->tmp_tcp_flag_code = 99; } | NONE { importer->tmp_tcp_flag_code = 98; } ) ; tcp_flags_list : { importer->tmp_tcp_flags_list.clear(); importer->tmp_tcp_flag_code = 0; } tcp_flag_word { importer->tmp_tcp_flags_list.push_back(importer->tmp_tcp_flag_code); } ( COMMA tcp_flag_word { importer->tmp_tcp_flags_list.push_back( importer->tmp_tcp_flag_code); } )* ; tcp_flags : MATCH_TCP_FLAGS tcp_flags_list { importer->tcp_flags_mask = importer->tmp_tcp_flags_list; importer->tmp_tcp_flags_list.clear(); } tcp_flags_list { importer->tcp_flags_comp = importer->tmp_tcp_flags_list; importer->tmp_tcp_flags_list.clear(); *dbg << " TCP FLAGS="; foreach(int x, importer->tcp_flags_mask) *dbg << x << "|"; *dbg << " "; foreach(int x, importer->tcp_flags_comp) *dbg << x << "|"; } ; // --tcp-option is not supported in fwbuilder at this time tcp_option : MATCH_TCP_OPTION INT_CONST ; //**************************************************************** class IPTCfgLexer extends Lexer; options { k = 20; // ASCII only charVocabulary = '\3'..'\377'; } tokens { INPUT = "INPUT"; FORWARD = "FORWARD"; OUTPUT = "OUTPUT"; PREROUTING = "PREROUTING"; POSTROUTING = "POSTROUTING"; INVALID = "INVALID"; NEW = "NEW"; ESTABLISHED = "ESTABLISHED"; RELATED = "RELATED"; COMMIT = "COMMIT"; M_STATE = "state"; M_COMMENT = "comment"; M_MPORT = "multiport"; M_MARK = "mark"; M_LIMIT = "limit" ; M_LENGTH = "length" ; M_RECENT = "recent" ; M_IPRANGE = "iprange" ; M_PKTTYPE = "pkttype" ; ICMP = "icmp"; TCP = "tcp"; UDP = "udp"; SYN = "SYN"; ACK = "ACK"; FIN = "FIN"; RST = "RST"; URG = "URG"; PSH = "PSH"; ALL = "ALL"; NONE = "NONE"; WORD_BROADCAST = "broadcast" ; WORD_MULTICAST = "multicast" ; WORD_UNICAST = "unicast" ; } // LINE_COMMENT : '#' (~('\r' | '\n'))* NEWLINE ; IPTABLES_SAVE_HEADER : " Generated by iptables-save v"; Whitespace : ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) { _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; } ; NEWLINE : ( "\r\n" | '\r' | '\n' ) { newline(); resetText(); } ; protected IPV4:; protected THREE_COMPONENT_VERSION:; protected IPV6:; protected MAC_ADDRESS:; protected INT_CONST:; protected HEX_CONST:; protected NEG_INT_CONST:; protected DIGIT : '0'..'9' ; protected HEXDIGIT : '0'..'9' | 'A'..'F' | 'a'..'f'; // ################################ // Rules for IPv4 and IPv6 partially based on ideas from // http://www.antlr.org:8080/pipermail/antlr-interest/2005-June/012661.html // Ruleset copied from the posting does not compile, antlr 2.7.7 seems to // hang while processing it. Commenting out rules for MAC_ADDRESS and // IPV6 makes antlr process grammar successfully (but defeats the purpose). protected NUM_3DIGIT: ('0'..'9') (('0'..'9') ('0'..'9')?)?; protected NUM_HEX_4DIGIT: HEXDIGIT ((HEXDIGIT) ((HEXDIGIT) (HEXDIGIT)?)?)?; // IPV6 // Note that '::' can only appear once in the address // but can be used to compress leading and/or trailing zeros in an address // // As of 12/2008 these rules do not work, antlr seems to hang while compiling // this grammar. // // IPV6_1: (NUM_HEX_4DIGIT ':' (NUM_HEX_4DIGIT | ':')* NUM_HEX_4DIGIT) // { $setType(IPV6); }; // // IPV6_2: (':' ':' (NUM_HEX_4DIGIT | ':')* NUM_HEX_4DIGIT) { $setType(IPV6); }; // // IPV6_3: ((NUM_HEX_4DIGIT | ':')* NUM_HEX_4DIGIT ':' ':') { $setType(IPV6); }; // // IPV6_4: ':' ':' { $setType(IPV6); }; NUMBER options { testLiterals = true; } : // IPv4 RULE (NUM_3DIGIT '.' NUM_3DIGIT '.') => ( NUM_3DIGIT '.' NUM_3DIGIT '.' NUM_3DIGIT '.' NUM_3DIGIT { $setType(IPV4); } ) | (NUM_3DIGIT '.' NUM_3DIGIT '.') => ( NUM_3DIGIT '.' NUM_3DIGIT '.' NUM_3DIGIT { $setType(THREE_COMPONENT_VERSION); } ) | ( '0' 'x' ( HEXDIGIT )+ ) { $setType(HEX_CONST); } | ( DIGIT )+ { $setType(INT_CONST); } ; WORD : ( 'a'..'z' | 'A'..'Z' | '$' ) ( '!'..'+' | '-' | '.' | '/' | '0'..'9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A'..'Z' | '^' | '_' | '`' | 'a'..'z' )* ; STRING : '"' (~'"')* '"'; // ------------------------------------------------------------------------ // I have to add these options even though I do not support them // protected UNSUPPORTED_OPTION:; //"--seconds" confuses lexer because it interprets it as "-" "-s" "econds" //SECONDS : "--seconds" { $setType(UNSUPPORTED_OPTION); }; // SET : "--set" { $setType(UNSUPPORTED_OPTION); }; // "--rsource" also confuses lexer which expects "--reject" RSOURCE : "--rsource" { $setType(UNSUPPORTED_OPTION); }; // ------------------------------------------------------------------------ ADD_RULE : "-A" ; MATCH_STATE : "--state" ; MATCH_SRC_MULTIPORT : "--source-ports" ; MATCH_DST_MULTIPORT : "--destination-ports" ; MATCH_BOTH_MULTIPORT : "--ports" ; MATCH_SRC_PORT : "--source-port" ; MATCH_DST_PORT : "--destination-port" ; MATCH_SRC_PORT_SHORT : "--sport" ; MATCH_DST_PORT_SHORT : "--dport" ; MATCH_SYN : "--syn" ; MATCH_TCP_FLAGS : "--tcp-flags" ; MATCH_TCP_OPTION : "--tcp-option" ; MATCH_ICMP_TYPE : "--icmp-type" ; MATCH_MARK : "--mark" ; MATCH_LENGTH : "--length" ; MATCH_LIMIT : "--limit" ; MATCH_LIMIT_BURST : "--limit-burst" ; MATCH_RECENT_NAME : "--name" ; MATCH_RECENT_RCHECK : "--rcheck" ; MATCH_RECENT_UPDATE : "--update" ; MATCH_RECENT_REMOVE : "--remove" ; MATCH_RECENT_SECONDS : "--seconds" ; MATCH_RECENT_HITCOUNT : "--hitcount" ; MATCH_RECENT_RTTL : "--rttl" ; MATCH_RECENT_RDEST : "--rdest" ; MATCH_RECENT_SET : "--set" ; MATCH_IPRANGE_SRC : "--src-range" ; MATCH_IPRANGE_DST : "--dst-range" ; MATCH_COMMENT : "--comment" ; MATCH_PKT_TYPE : "--pkt-type" ; // ---------------------------------------------------------------- // target options REJECT_WITH : "--reject-with" ; SET_CLASS : "--set-class" ; SET_MARK : "--set-mark" ; SAVE_MARK : "--save-mark" ; RESTORE_MARK : "--restore-mark" ; SET_TOS : "--set-tos" ; CONTINUE : "--continue" ; ROUTE_IIF : "--iif" ; ROUTE_OIF : "--oif" ; ROUTE_GW : "--gw" ; ROUTE_TEE : "--tee" ; LOG_PREFIX : "--log-prefix" ; LOG_LEVEL : "--log-level" ; LOG_TCP_SEQ : "--log-tcp-sequence"; LOG_TCP_OPT : "--log-tcp-options"; LOG_IP_OPT : "--log-ip-options"; ULOG_PREFIX : "--ulog-prefix" ; ULOG_QTHR : "--ulog-qthreshold" { $setType(UNSUPPORTED_OPTION); }; ULOG_NLG : "--ulog-nlgroup" { $setType(UNSUPPORTED_OPTION); }; ULOG_CPR : "--ulog-cprange" { $setType(UNSUPPORTED_OPTION); }; TO_SOURCE : "--to-source" ; TO_DESTINATION : "--to-destination" ; TO_PORTS : "--to-ports" ; TO_NETMAP : "--to" ; CLAMP_MSS : "--clamp-mss-to-pmtu" ; // ---------------------------------------------------------------- // these are the basic iptables options, not too many really OPT_MODULE : "-m" ; OPT_SRC : "-s" ; OPT_DST : "-d" ; OPT_IN_INTF : "-i" ; OPT_OUT_INTF : "-o" ; OPT_PROTO : "-p" ; OPT_TARGET : "-j" ; OPT_FRAGM : "-f" ; EXCLAMATION : '!' ; NUMBER_SIGN : '#' ; // DOLLAR : '$' ; PERCENT : '%' ; AMPERSAND : '&' ; APOSTROPHE : '\'' ; OPENING_PAREN : '(' ; CLOSING_PAREN : ')' ; STAR : '*' ; PLUS : '+' ; COMMA : ',' ; MINUS : '-' ; DOT : '.' ; SLASH : '/' ; COLON : ':' ; SEMICOLON : ';' ; LESS_THAN : '<' ; EQUALS : '=' ; GREATER_THAN : '>' ; QUESTION : '?' ; COMMERCIAL_AT : '@' ; OPENING_SQUARE : '[' ; CLOSING_SQUARE : ']' ; CARET : '^' ; UNDERLINE : '_' ; OPENING_BRACE : '{' ; CLOSING_BRACE : '}' ; TILDE : '~' ; fwbuilder-5.1.0.3599/src/parsers/IPTCfgParser.hpp0000644000175000017500000001450411733011756022212 0ustar sylvestresylvestre#ifndef INC_IPTCfgParser_hpp_ #define INC_IPTCfgParser_hpp_ #line 38 "iptables.g" // gets inserted before antlr generated includes in the header // file #include "IPTImporter.h" #line 11 "IPTCfgParser.hpp" #include /* $ANTLR 2.7.7 (20090306): "iptables.g" -> "IPTCfgParser.hpp"$ */ #include #include #include "IPTCfgParserTokenTypes.hpp" #include #line 45 "iptables.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class IPTImporter; #line 28 "IPTCfgParser.hpp" #line 74 "iptables.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 34 "IPTCfgParser.hpp" class CUSTOM_API IPTCfgParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public IPTCfgParserTokenTypes { #line 91 "iptables.g" // additional methods and members public: std::ostream *dbg; IPTImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); std::cerr << s << std::endl; } #line 38 "IPTCfgParser.hpp" public: void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory ); protected: IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k); public: IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf); protected: IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k); public: IPTCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer); IPTCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state); int getNumTokens() const { return IPTCfgParser::NUM_TOKENS; } const char* getTokenName( int type ) const { if( type > getNumTokens() ) return 0; return IPTCfgParser::tokenNames[type]; } const char* const* getTokenNames() const { return IPTCfgParser::tokenNames; } public: void cfgfile(); public: void comment(); public: void start_table(); public: void create_chain(); public: void add_rule(); public: void commit(); public: void chain_def(); public: void ipt_option(); public: void negation(); public: void module(); public: void match_mark(); public: void match_recent(); public: void src(); public: void dst(); public: void i_intf(); public: void o_intf(); public: void proto(); public: void target(); public: void fragm(); public: void icmp_type_spec(); public: void basic_tcp_udp_port_spec(); public: void multiport_tcp_udp_port_spec(); public: void tcp_options(); public: void match_limit(); public: void match_limit_burst(); public: void match_length(); public: void match_iprange_src(); public: void match_iprange_dst(); public: void unknown_option(); public: void unknown_parameter(); public: void m_state(); public: void m_mport(); public: void m_icmp(); public: void m_tcp(); public: void m_udp(); public: void m_limit(); public: void m_length(); public: void m_iprange(); public: void m_comment(); public: void m_pkttype(); public: void m_unknown_module(); public: void protocol_word(); public: void target_options(); public: void nat_spec(); public: void redirect_spec(); public: void nat_addr_range(); public: void nat_port_def_with_range(); public: void state_word(); public: void m_mark(); public: void limit_rate(); public: void m_recent(); public: void recent_opts(); public: void recent_args_no_param(); public: void recent_args_param(); public: void length_spec(); public: void pkt_type_spec(); public: void port_def_with_range(); public: void port_def_no_range(); public: void port_def_with_incomplete_range(); public: void syn(); public: void tcp_flags(); public: void tcp_option(); public: void tcp_flag_word(); public: void tcp_flags_list(); public: ANTLR_USE_NAMESPACE(antlr)RefAST getAST() { return returnAST; } protected: ANTLR_USE_NAMESPACE(antlr)RefAST returnAST; private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS static const int NUM_TOKENS = 146; #else enum { NUM_TOKENS = 146 }; #endif static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; static const unsigned long _tokenSet_7_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_7; static const unsigned long _tokenSet_8_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_8; static const unsigned long _tokenSet_9_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_9; static const unsigned long _tokenSet_10_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_10; static const unsigned long _tokenSet_11_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_11; static const unsigned long _tokenSet_12_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_12; static const unsigned long _tokenSet_13_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_13; static const unsigned long _tokenSet_14_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_14; }; #endif /*INC_IPTCfgParser_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/pf.g0000644000175000017500000014163411733011756020032 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ header "pre_include_hpp" { // gets inserted before antlr generated includes in the header // file #include "PFImporter.h" } header "post_include_hpp" { // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class PFImporter; } header "pre_include_cpp" { // gets inserted before the antlr generated includes in the cpp // file } header "post_include_cpp" { // gets inserted after the antlr generated includes in the cpp // file #include #include } header { // gets inserted after generated namespace specifications in the // header file. But outside the generated class. } options { language="Cpp"; } class PFCfgParser extends Parser; options { k = 2; // when default error handler is disabled, parser errors cause // exception and terminate parsing process. We can catch the exception // and make the error appear in importer log, but import process // terminates which is not always optimal // // defaultErrorHandler = false; // see http://www.antlr2.org/doc/options.html } { // additional methods and members public: std::ostream *dbg; PFImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); importer->error_tracker->registerError("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); importer->error_tracker->registerError("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); importer->error_tracker->registerError("Parser warning: " + s); std::cerr << s << std::endl; } } cfgfile : ( comment | include_command | macro_definition | altq_rule | antispoof_rule | queue_rule | set_rule | scrub_rule | match_rule | table_rule | no_nat_rule | nat_rule | rdr_rule | binat_rule | pass_rule | block_rule | // unknown_rule // | NEWLINE )* ; //**************************************************************** comment : COMMENT_START { QStringList str; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { str << QString::fromUtf8(LT(1)->getText().c_str()); consume(); } importer->last_comment << str.join(" "); } ; //**************************************************************** include_command : INCLUDE_COMMAND { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'include' commands is not supported.")); consumeUntil(NEWLINE); } ; //**************************************************************** macro_definition : WORD EQUAL { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); consumeUntil(NEWLINE); } ; //**************************************************************** antispoof_rule : ANTISPOOF { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Warning: import of 'antispoof' commands has not been implemented yet.")); consumeUntil(NEWLINE); } ; //**************************************************************** altq_rule : ALTQ { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->error_tracker->registerError( QString("import of 'altq' commands is not supported.")); consumeUntil(NEWLINE); } ; //**************************************************************** queue_rule : QUEUE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->error_tracker->registerError( QString("import of 'queue' commands is not supported.")); consumeUntil(NEWLINE); } ; //**************************************************************** set_rule : SET { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); } ( set_timeout | set_ruleset_optimization | set_optimization | set_limit | set_loginterface | set_block_policy | set_state_policy | set_state_defaults | set_require_order | set_fingerprints | set_skip | set_debug | set_reassemble | set_hostid ) ; set_timeout : TIMEOUT ( timeout_def | timeout_def_list ) ; set_ruleset_optimization : "ruleset-optimization" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set ruleset-optimization' commands is not supported.")); consumeUntil(NEWLINE); } ; set_optimization : "optimization" ( "aggressive" | "conservative" | "high-latency" | "normal" | "satellite" ) { importer->set_optimization = LT(0)->getText(); } ; set_limit : "limit" ( limit_def | limit_def_list ) ; set_loginterface : "loginterface" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set loginterface' commands is not supported.")); consumeUntil(NEWLINE); } ; set_block_policy : "block-policy" (DROP | RETURN) { importer->set_block_policy = LT(0)->getText(); } ; set_state_policy : "state-policy" ("if-bound" | "floating") { importer->set_state_policy = LT(0)->getText(); } ; set_state_defaults : "state-defaults" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set state-defaults' commands is not supported.")); consumeUntil(NEWLINE); } ; set_require_order : "require-order" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set require-order' commands is not supported.")); consumeUntil(NEWLINE); } ; set_fingerprints : "fingerprints" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set fingerprints' commands is not supported.")); consumeUntil(NEWLINE); } ; set_skip : "skip" ON skip_def ; skip_def : WORD { importer->set_skip_on.push_back(LT(0)->getText()); } | skip_list ; skip_list : OPENING_BRACE WORD { importer->set_skip_on.push_back(LT(0)->getText()); } ( ( COMMA )* WORD { importer->set_skip_on.push_back(LT(0)->getText()); } )* CLOSING_BRACE ; set_debug : "debug" WORD { importer->set_debug = LT(0)->getText(); } ; set_reassemble : "reassemble" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set reassemble' commands is not supported.")); consumeUntil(NEWLINE); } ; set_hostid : "hostid" { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( QString("Error: import of 'set hostid' commands is not supported.")); consumeUntil(NEWLINE); } ; /* timeout = ( "tcp.first" | "tcp.opening" | "tcp.established" | "tcp.closing" | "tcp.finwait" | "tcp.closed" | "udp.first" | "udp.single" | "udp.multiple" | "icmp.first" | "icmp.error" | "other.first" | "other.single" | "other.multiple" | "frag" | "interval" | "src.track" | "adaptive.start" | "adaptive.end" ) number */ timeout_def { std::string timeout_name, timeout_value; } : ( "tcp.first" | "tcp.opening" | "tcp.established" | "tcp.closing" | "tcp.finwait" | "tcp.closed" | "udp.first" | "udp.single" | "udp.multiple" | "icmp.first" | "icmp.error" | "other.first" | "other.single" | "other.multiple" | "frag" | "interval" | "src.track" | "adaptive.start" | "adaptive.end" ) { timeout_name = LT(0)->getText(); } INT_CONST { timeout_value = LT(0)->getText(); importer->timeouts.push_back( std::pair(timeout_name, timeout_value)); } ; timeout_def_list : OPENING_BRACE timeout_def ( ( COMMA )? timeout_def )* CLOSING_BRACE ; limit_def { std::string limit_name, limit_value; } : ( "frags" | "states" | "src-nodes" | "tables" | "tables-entries" ) { limit_name = LT(0)->getText(); } INT_CONST { limit_value = LT(0)->getText(); importer->limits.push_back( std::pair(limit_name, limit_value)); } ; limit_def_list : OPENING_BRACE limit_def ( ( COMMA )? limit_def )* CLOSING_BRACE ; //**************************************************************** scrub_rule : SCRUB { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "scrub"; *dbg << LT(1)->getLine() << ":" << " scrub "; } rule_extended // do not call pushRule() for scrub rules because we configure // scrub parameters as firewall options NEWLINE ; //**************************************************************** match_rule : MATCH { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "match"; *dbg << LT(1)->getLine() << ":" << " match "; } rule_extended { if ( ! importer->scrub_rule) importer->pushRule(); } NEWLINE ; //**************************************************************** table_rule : TABLE { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); } LESS_THAN name:WORD GREATER_THAN ( PERSIST ) ? ( CONST_WORD { importer->addMessageToLog( QString("Warning: attribute \"const\" will be dropped from table configuration since this attribute is not supported at this time")); } ) ? ( COUNTERS { importer->addMessageToLog( QString("Warning: attribute \"counters\" will be dropped from table configuration since this attribute is not supported at this time")); } )? ( FILE file:STRING { importer->newAddressTableObject( name->getText(), file->getText()); } | OPENING_BRACE tableaddr_spec ( ( COMMA )? tableaddr_spec )* CLOSING_BRACE { importer->newAddressTableObject( name->getText(), importer->tmp_group); } | NEWLINE { // Special case: table definition without file name or list of addresses. // Create run-time AddressTable object with name but no file spec. importer->newAddressTableObject(name->getText(), ""); } ) ; tableaddr_spec { AddressSpec as; } : ( EXLAMATION { as.neg = true; } )? ( WORD { // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); } ( COLON ( NETWORK { as.at = AddressSpec::INTERFACE_NETWORK; } | BROADCAST { as.at = AddressSpec::INTERFACE_BROADCAST; } | PEER { importer->error_tracker->registerError( QString("import of 'interface:peer' is not supported.")); } | INT_CONST { importer->error_tracker->registerError( QString("import of 'interface:0' is not supported.")); } ) )? | SELF { as.at = AddressSpec::SPECIAL_ADDRESS; as.address = "self"; } | // match NUMBER and INT_CONST to account for 10/8, 172.16/12 cases. ( IPV4 | NUMBER | INT_CONST ) { as.at = AddressSpec::HOST_ADDRESS; as.address = LT(0)->getText(); } ( SLASH { as.at = AddressSpec::NETWORK_ADDRESS; } ( IPV4 | INT_CONST ) { as.netmask = LT(0)->getText(); } )? ) { importer->tmp_group.push_back(as); } ; //**************************************************************** no_nat_rule : NO { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNATRule(); importer->action = "nonat"; *dbg << LT(1)->getLine() << ":" << " nonat "; } ( nat_rule | rdr_rule ) ; //**************************************************************** nat_rule : NAT { if ( importer->action != "nonat" ) { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNATRule(); importer->action = "nat"; *dbg << LT(1)->getLine() << ":" << " nat "; } } ( PASS { importer->error_tracker->registerError( QString("import of 'nat pass' commands is not supported.")); } ( logging )? )? ( intrface )? ( address_family )? ( protospec )? hosts ( tagged )? ( tag_clause { importer->error_tracker->registerError( QString("import of 'nat ... tag' commands is not supported.")); } )? ( MINUS GREATER_THAN ( redirhost | redirhost_list ) { importer->nat_group = importer->tmp_group; } ( portspec { importer->nat_port_group = importer->tmp_port_group; } )? ( pooltype )? ( STATIC_PORT { importer->nat_rule_opt_2 = "static-port"; } )? )? { importer->pushRule(); } NEWLINE ; //**************************************************************** rdr_rule : RDR { if ( importer->action != "nonat" ) { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNATRule(); importer->action = "rdr"; *dbg << LT(1)->getLine() << ":" << " rdr "; } } ( PASS { importer->error_tracker->registerError( QString("import of 'nat pass' commands is not supported.")); } ( logging )? )? ( intrface )? ( address_family )? ( protospec )? hosts ( tagged )? ( tag_clause { importer->error_tracker->registerError( QString("import of 'nat ... tag' commands is not supported.")); } )? ( MINUS GREATER_THAN ( redirhost | redirhost_list ) { importer->nat_group = importer->tmp_group; } ( portspec { importer->nat_port_group = importer->tmp_port_group; } )? ( pooltype )? )? { importer->pushRule(); } NEWLINE ; // redirhost = address [ "/" mask-bits ] // address = ( interface-name | interface-group | // "(" ( interface-name | interface-group ) ")" | // hostname | ipv4-dotted-quad | ipv6-coloned-hex ) // redirhost { AddressSpec as; } : ( IPV4 { as.at = AddressSpec::HOST_ADDRESS; as.address = LT(0)->getText(); } ( SLASH { as.at = AddressSpec::NETWORK_ADDRESS; } ( IPV4 | INT_CONST ) { as.netmask = LT(0)->getText(); } )? | OPENING_PAREN WORD { // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); } CLOSING_PAREN | WORD { // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); } ) { importer->tmp_group.push_back(as); } ; redirhost_list : OPENING_BRACE redirhost ( ( COMMA )? redirhost )* CLOSING_BRACE ; // portspec = "port" ( number | name ) [ ":" ( "*" | number | name ) ] // // // rdr The packet is redirected to another destination and possibly a dif- // ferent port. rdr rules can optionally specify port ranges instead // of single ports. rdr ... port 2000:2999 -> ... port 4000 redirects // ports 2000 to 2999 (inclusive) to port 4000. rdr ... port // 2000:2999 -> ... port 4000:* redirects port 2000 to 4000, 2001 to // 4001, ..., 2999 to 4999. // portspec { PortSpec ps; } : PORT ( port_def { ps.port1 = importer->tmp_port_def; ps.port2 = ps.port1; ps.port_op = "="; } | // lexer matches port range (1000:1010) as IPv6, see rule // NUMBER_ADDRESS_OR_WORD. Combination "1000:*" comes as IPV6 STAR IPV6 { ps.setFromPortRange(LT(0)->getText()); } ( STAR { ps.port2 = "65535"; } )? ) { importer->tmp_port_group.push_back(ps); } ; // pooltype = ( "bitmask" | "random" | // "source-hash" [ ( hex-key | string-key ) ] | // "round-robin" ) [ sticky-address ] // // Note that as of v4.2 we can not generate optinal parameters for the // "source-hash" pooltype. "sticky-address" is not supported either. // pooltype : ( BITMASK { importer->pooltype_opt = "bitmask"; } | RANDOM { importer->pooltype_opt = "random"; } | SOURCE_HASH { importer->pooltype_opt = "source-hash"; } ( HEX_KEY { importer->error_tracker->registerError( QString("import of commands with pool type 'source-hash hex-key' " "option is not supported")); } | STRING_KEY { importer->error_tracker->registerError( QString("import of commands with pool type 'source-hash string-key' " "option is not supported")); } )? | ROUND_ROBIN { importer->pooltype_opt = "round-robin"; } ) ( STICKY_ADDRESS )? ; //**************************************************************** binat_rule : BINAT { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->error_tracker->registerError( QString("import of 'binat' commands is not supported.")); consumeUntil(NEWLINE); } ; //**************************************************************** //unknown_rule : WORD // { // importer->clear(); // importer->setCurrentLineNumber(LT(0)->getLine()); // consumeUntil(NEWLINE); // } // ; //**************************************************************** pass_rule : PASS { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "pass"; *dbg << LT(1)->getLine() << ":" << " pass "; } rule_extended { importer->pushRule(); } NEWLINE ; block_rule : BLOCK { importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "block"; *dbg << LT(1)->getLine() << ":" << " block "; } ( block_return )? rule_extended { importer->pushRule(); } NEWLINE ; block_return : ( DROP { importer->block_action_params.push_back("drop"); } | RETURN { importer->block_action_params.push_back("return"); } | RETURN_RST { importer->block_action_params.push_back("return-rst"); } ( TTL INT_CONST { importer->error_tracker->registerError( QString("Import of \"block return-rst ttl number\" is not supported. ")); } )? | RETURN_ICMP { importer->block_action_params.push_back("return-icmp"); } ( OPENING_PAREN ( icmp_code_by_name | INT_CONST ) { importer->block_action_params.push_back(LT(0)->getText()); } ( COMMA ( icmp_code_by_name | INT_CONST ) { importer->error_tracker->registerError( QString("Import of \"block return-icmp (icmp_code, icmp6_code)\" is not supported")); } )? CLOSING_PAREN )? | RETURN_ICMP6 { importer->error_tracker->registerError( QString("Import of \"block return-icmp6\" is not supported")); importer->block_action_params.push_back("return-icmp"); } ) ; rule_extended : ( direction )? ( quick_or_log )? ( intrface )? ( route )? ( address_family )? ( protospec )? ( hosts )? ( filteropts )? ( route )? ; direction : ( IN_WORD | OUT_WORD ) { importer->direction = LT(0)->getText(); } ; // looks like both "block log quick" and "block quick log" are legitimate quick_or_log : ( LOG (logopts)? { importer->logging = true; } ( QUICK { importer->quick = true; } )? | QUICK { importer->quick = true; } ( LOG (logopts)? { importer->logging = true; } )? ) ; logging : LOG (logopts)? { importer->logging = true; } ; logopts : OPENING_PAREN logopt ( COMMA { importer->logopts += ","; } logopt )* CLOSING_PAREN ; logopt : ALL | USER | TO WORD { importer->logopts += LT(0)->getText(); } ; intrface : ON ( ifspec | interface_list ) ; ifspec { InterfaceSpec is; } : ( EXLAMATION { is.neg = true; } )? WORD { is.name = LT(0)->getText(); importer->iface_group.push_back(is); importer->newInterface(is.name); } ; interface_list : OPENING_BRACE ifspec ( ( COMMA )? ifspec )* CLOSING_BRACE ; address_family : INET | INET6 { importer->address_family = LT(0)->getText(); } ; protospec : PROTO proto_def ; proto_def : ( proto_name | proto_number | proto_list ) ; proto_name : (IP | ICMP | IGMP | TCP | UDP | RDP | RSVP | GRE | ESP_WORD | AH | EIGRP | OSPF | IPIP | VRRP | L2TP | ISIS ) { importer->proto_list.push_back(LT(0)->getText()); } ; proto_number : INT_CONST { importer->proto_list.push_back(LT(0)->getText()); } ; proto_list : OPENING_BRACE proto_def ( ( COMMA )? proto_def )* CLOSING_BRACE ; hosts : ALL { importer->src_group.push_back( AddressSpec(AddressSpec::ANY, false, "0.0.0.0", "0.0.0.0")); importer->dst_group.push_back( AddressSpec(AddressSpec::ANY, false, "0.0.0.0", "0.0.0.0")); } | ( hosts_from )? ( hosts_to )? ; hosts_from : FROM src_hosts_part ( src_port_part )? ; hosts_to : TO dst_hosts_part ( dst_port_part )? ; src_hosts_part : ( common_hosts_part | URPF_FAILED { importer->tmp_group.push_back( AddressSpec(AddressSpec::SPECIAL_ADDRESS, false, "urpf-failed", "")); } ) { importer->src_neg = importer->tmp_neg; importer->src_group.splice(importer->src_group.begin(), importer->tmp_group); } ; dst_hosts_part : common_hosts_part { importer->dst_neg = importer->tmp_neg; importer->dst_group.splice(importer->dst_group.begin(), importer->tmp_group); } ; common_hosts_part : ANY { importer->tmp_group.push_back( AddressSpec(AddressSpec::ANY, false, "0.0.0.0", "0.0.0.0")); } | NO_ROUTE { importer->tmp_group.push_back( AddressSpec(AddressSpec::SPECIAL_ADDRESS, false, "no-route", "")); } | host | host_list ; host { AddressSpec as; } : ( EXLAMATION { as.neg = true; } )? ( ( WORD | MACRO ) { // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = LT(0)->getText(); } ( COLON ( NETWORK { as.at = AddressSpec::INTERFACE_NETWORK; } | BROADCAST { as.at = AddressSpec::INTERFACE_BROADCAST; } | PEER { importer->error_tracker->registerError( QString("import of 'interface:peer' is not supported.")); } | INT_CONST { importer->error_tracker->registerError( QString("import of 'interface:0' is not supported.")); } ) )? | SELF { as.at = AddressSpec::SPECIAL_ADDRESS; as.address = "self"; } | IPV6 { importer->error_tracker->registerError( QString("IPv6 import is not supported. ")); consumeUntil(NEWLINE); } | IPV4 { as.at = AddressSpec::HOST_ADDRESS; as.address = LT(0)->getText(); } ( SLASH { as.at = AddressSpec::NETWORK_ADDRESS; } ( IPV4 | INT_CONST ) { as.netmask = LT(0)->getText(); } )? | LESS_THAN tn:WORD GREATER_THAN { as.at = AddressSpec::TABLE; as.address = tn->getText(); } | OPENING_PAREN in:WORD CLOSING_PAREN { // interface name or domain/host name as.at = AddressSpec::INTERFACE_OR_HOST_NAME; as.address = in->getText(); } ) { importer->tmp_group.push_back(as); } ; host_list : OPENING_BRACE host ( ( COMMA )? host )* CLOSING_BRACE ; // ************************************************************************ route : route_to | reply_to | dup_to ; route_to : ROUTE_TO ( routehost | routehost_list ) ( pooltype )? { importer->route_type = PFImporter::ROUTE_TO; } ; reply_to : REPLY_TO ( routehost | routehost_list ) ( pooltype )? { importer->route_type = PFImporter::REPLY_TO; } ; dup_to : DUP_TO ( routehost | routehost_list ) ( pooltype )? { importer->route_type = PFImporter::DUP_TO; } ; routehost { RouteSpec rs; } : OPENING_PAREN WORD { rs.iface = LT(0)->getText(); } (h:IPV4 | v6:IPV6) (SLASH (nm:IPV4 | nm6:INT_CONST))? { if (v6) { importer->error_tracker->registerError( QString("IPv6 import is not supported. ")); consumeUntil(NEWLINE); } else { if (h) rs.address = h->getText(); if (nm) rs.netmask = nm->getText(); importer->route_group.push_back(rs); } } CLOSING_PAREN ; routehost_list : OPENING_BRACE routehost ( ( COMMA )? routehost )* CLOSING_BRACE ; // ************************************************************************ filteropts : filteropt ( ( COMMA )? filteropt )* ; filteropt : user_match | group_match | tcp_flags | icmp_type | icmp6_type | tagged | tag_clause | state | queue | label | match_rule_scrub_options | scrub_options ; //************************************************************************ user_match : USER ( user_group_op | user_group_op_list ) { importer->addMessageToLog( QString("Error: import of 'user' match is not supported.")); } ; group_match : GROUP ( user_group_op | user_group_op_list ) { importer->addMessageToLog( QString("Error: import of 'group' match is not supported.")); } ; user_group_op : ( unary_op ( WORD | INT_CONST ) | ( WORD | INT_CONST ) ( binary_op ( WORD | INT_CONST ) )? ) ; user_group_op_list : OPENING_BRACE user_group_op ( ( COMMA )? user_group_op )* CLOSING_BRACE ; //************************************************************************ match_rule_scrub_options : SCRUB scrub_options ; scrub_options : ( scrub_option | scrub_option_list ) ; scrub_option_list : OPENING_PAREN scrub_option ( ( COMMA )? scrub_option )* CLOSING_PAREN ; scrub_option : ( "fragment" ( "reassemble" | "crop" | "drop-ovl" ) { importer->scrub_options.push_back( str_tuple("fragment", LT(0)->getText())); importer->scrub_rule = true; } | "reassemble" TCP { importer->scrub_options.push_back( str_tuple("reassemble", "tcp")); importer->scrub_rule = true; } | "no-df" { importer->scrub_options.push_back( str_tuple(LT(0)->getText(), "")); importer->scrub_rule = true; } | "min-ttl" INT_CONST { importer->scrub_options.push_back( str_tuple("min-ttl", LT(0)->getText())); importer->scrub_rule = true; } | "max-mss" INT_CONST { importer->scrub_options.push_back( str_tuple("max-mss", LT(0)->getText())); importer->scrub_rule = true; } | "random-id" { importer->scrub_options.push_back( str_tuple(LT(0)->getText(), "")); importer->scrub_rule = true; } ) ; tcp_flags : FLAGS ( ANY { importer->flags_check = "none"; importer->flags_mask = "none"; } | ( check:WORD )? SLASH ( mask:WORD )? { if (check) importer->flags_check = check->getText(); else importer->flags_check = "any"; if (mask) importer->flags_mask = mask->getText(); else importer->flags_mask = "all"; } ) ; icmp_type : ICMP_TYPE ( icmp_type_code | icmp_list ) ; icmp_type_code { IcmpSpec is; } : ( icmp_type_by_name { is.icmp_type_name = LT(0)->getText(); } | INT_CONST { is.icmp_type_int = LT(0)->getText(); } ) ( ICMP_CODE ( icmp_code_by_name { is.icmp_code_name = LT(0)->getText(); } | INT_CONST { is.icmp_code_int = LT(0)->getText(); } ) )? { importer->icmp_type_code_group.push_back(is); } ; icmp_type_by_name : ( "echorep" | "unreach" | "squench" | "redir" | "althost" | "echoreq" | "routeradv" | "routersol" | "timex" | "paramprob" | "timereq" | "timerep" | "inforeq" | "inforep" | "maskreq" | "maskrep" | "trace" | "dataconv" | "mobredir" | "ipv6-where" | "ipv6-here" | "mobregreq" | "mobregrep" | "skip" | "photuris" ) ; icmp_code_by_name : ( "net-unr" | "host-unr" | "proto-unr" | "port-unr" | "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" | "net-prohib" | "host-prohib" | "net-tos" | "host-tos" | "filter-prohib" | "host-preced" | "cutoff-preced" | "redir-net" | "redir-host" | "redir-tos-net" | "redir-tos-host" | "normal-adv" | "common-adv" | "transit" | "reassemb" | "badhead" | "optmiss" | "badlen" | "unknown-ind" | "auth-fail" | "decrypt-fail" ) ; icmp_list : OPENING_BRACE icmp_type_code ( ( COMMA )? icmp_type_code )* CLOSING_BRACE ; icmp6_type : ICMP6_TYPE { importer->error_tracker->registerError( QString("ICMP6 import is not supported. ")); consumeUntil(NEWLINE); } ; tagged : ( EXLAMATION { importer->tagged_neg = true; } )? TAGGED WORD { importer->tagged = LT(0)->getText(); } ; tag_clause : TAG WORD { importer->tag = LT(0)->getText(); } ; state : ( NO | KEEP | MODULATE | SYNPROXY ) { importer->state_op = LT(0)->getText(); } STATE ; queue : QUEUE ( WORD { importer->queue += LT(0)->getText(); } | OPENING_PAREN WORD { importer->queue += LT(0)->getText(); } ( COMMA { importer->queue += ","; } WORD { importer->queue += LT(0)->getText(); } )* CLOSING_PAREN ) ; label : LABEL STRING ; //**************************************************************** src_port_part : PORT ( port_op | port_op_list ) { importer->src_port_group.splice(importer->src_port_group.begin(), importer->tmp_port_group); } ; dst_port_part : PORT ( port_op | port_op_list ) { importer->dst_port_group.splice(importer->dst_port_group.begin(), importer->tmp_port_group); } ; unary_op : ( EQUAL { importer->tmp_port_op = "="; } | EXLAMATION EQUAL { importer->tmp_port_op = "!="; } | LESS_THAN { importer->tmp_port_op = "<"; } | LESS_THAN EQUAL { importer->tmp_port_op = "<="; } | GREATER_THAN { importer->tmp_port_op = ">"; } | GREATER_THAN EQUAL { importer->tmp_port_op = ">="; } ) ; binary_op : ( LESS_THAN GREATER_THAN { importer->tmp_port_op = "<>"; } | GREATER_THAN LESS_THAN { importer->tmp_port_op = "><"; } | COLON { importer->tmp_port_op = ":"; } ) ; // lexer matches port range (1000:1010) as IPv6, see rule // NUMBER_ADDRESS_OR_WORD port_op { PortSpec ps; } : ( unary_op { ps.port_op = importer->tmp_port_op; } port_def { ps.port1 = importer->tmp_port_def; ps.port2 = importer->tmp_port_def; } | port_def { ps.port1 = importer->tmp_port_def; ps.port2 = ps.port1; ps.port_op = "="; } ( binary_op { ps.port_op = importer->tmp_port_op; } port_def { ps.port2 = LT(0)->getText(); } )? | IPV6 { ps.setFromPortRange(LT(0)->getText()); } ) { importer->tmp_port_group.push_back(ps); } ; port_def : ( WORD | INT_CONST ) { importer->tmp_port_def = LT(0)->getText(); } ; port_op_list : OPENING_BRACE port_op ( ( COMMA )? port_op )* CLOSING_BRACE ; //**************************************************************** class PFCfgLexer extends Lexer; options { k = 3; // ASCII only charVocabulary = '\3'..'\377'; } tokens { INCLUDE_COMMAND = "include"; EXIT = "exit"; QUIT = "quit"; NO = "no"; INTRFACE = "interface"; PASS = "pass"; BLOCK = "block"; MATCH = "match"; QUICK = "quick"; IN_WORD = "in"; OUT_WORD = "out"; ON = "on"; PROTO = "proto"; FROM = "from"; TO = "to"; INET = "inet"; INET6 = "inet6"; // protocols IP = "ip"; ICMP = "icmp"; ICMP6 = "icmp6"; TCP = "tcp"; UDP = "udp"; AH = "ah"; EIGRP = "eigrp"; ESP_WORD = "esp"; GRE = "gre"; IGMP = "igmp"; IGRP = "igrp"; IPIP = "ipip"; IPSEC = "ipsec"; NOS = "nos"; OSPF = "ospf"; PCP = "pcp"; PIM = "pim"; PPTP = "pptp"; RIP = "rip"; SNP = "snp"; RDP = "rdp"; RSVP = "rsvp"; VRRP = "vrrp"; L2TP = "l2tp"; ISIS = "isis"; HOST = "host"; ANY = "any"; ALL = "all"; USER = "user"; GROUP = "group"; NETWORK = "network"; BROADCAST = "broadcast"; PEER = "peer"; PORT = "port"; RANGE = "range"; LOG = "log"; NO_ROUTE = "no-route"; SELF = "self"; URPF_FAILED = "urpf-failed"; LOG_LEVEL_ALERTS = "alerts"; LOG_LEVEL_CRITICAL = "critical"; LOG_LEVEL_DEBUGGING = "debugging"; LOG_LEVEL_EMERGENCIES = "emergencies"; LOG_LEVEL_ERRORS = "errors"; LOG_LEVEL_INFORMATIONAL = "informational"; LOG_LEVEL_NOTIFICATIONS = "notifications"; LOG_LEVEL_WARNINGS = "warnings"; LOG_LEVEL_DISABLE = "disable"; LOG_LEVEL_INACTIVE = "inactive"; TIMEOUT = "timeout"; ALTQ = "altq"; ANTISPOOF = "antispoof"; SET = "set"; SCRUB = "scrub"; NAT = "nat"; RDR = "rdr"; BINAT = "binat"; TABLE = "table"; CONST_WORD = "const"; PERSIST = "persist"; COUNTERS = "counters"; FILE = "file"; QUEUE = "queue"; LABEL = "label"; ROUTE_TO = "route-to"; REPLY_TO = "reply-to"; DUP_TO = "dup-to"; DROP = "drop"; RETURN = "return"; RETURN_RST = "return-rst"; RETURN_ICMP = "return-icmp"; TAG = "tag"; TAGGED = "tagged"; STATE = "state"; KEEP = "keep"; MODULATE = "modulate"; SYNPROXY = "synproxy"; FLAGS = "flags"; ICMP_TYPE = "icmp-type"; ICMP6_TYPE = "icmp6-type"; ICMP_CODE = "code"; BITMASK = "bitmask"; RANDOM = "random"; SOURCE_HASH = "source-hash"; HEX_KEY = "hex-key"; STRING_KEY = "string-key"; ROUND_ROBIN = "round-robin"; STICKY_ADDRESS = "sticky-address"; STATIC_PORT = "static-port"; } // LINE_COMMENT : "#" (~('\r' | '\n'))* NEWLINE ; Whitespace : ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) { $setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP); } ; COMMENT_START : '#' ; NEWLINE : ( "\r\n" | '\r' | '\n' ) { newline(); } ; protected INT_CONST:; protected HEX_CONST:; protected NUMBER:; protected NEG_INT_CONST:; protected COLON : ; protected HEX_DIGIT : ( '0'..'9' | 'a'..'f' | 'A'..'F') ; protected DIGIT : '0'..'9' ; protected NUM_3DIGIT: ('0'..'9') (('0'..'9') ('0'..'9')?)? ; protected NUM_HEX_4DIGIT: HEX_DIGIT ((HEX_DIGIT) ((HEX_DIGIT) (HEX_DIGIT)?)?)? ; // Unfortunately IPV6 rule below matches "1000:1010" or "1024:65535" // as IPV6. This is not a valid IPv6 address and it creates problems // with port ranges // NUMBER_ADDRESS_OR_WORD options { testLiterals = true; } : ( ( HEX_DIGIT )+ ':' ) => ( ( ( HEX_DIGIT )+ ( ':' ( HEX_DIGIT )* )+ ) { $setType(IPV6); } ) | ( ':' ) => ( (':' ':' ( HEX_DIGIT )+ ) => (':' ':' ( HEX_DIGIT )+ (':' ( HEX_DIGIT )+)*) {$setType(IPV6);} | (':' ':' ) { $setType(IPV6); } | ':' { $setType(COLON); } ) | ( NUM_3DIGIT '.' NUM_3DIGIT '.' ) => (NUM_3DIGIT '.' NUM_3DIGIT '.' NUM_3DIGIT '.' NUM_3DIGIT) { $setType(IPV4); } | ( (DIGIT)+ '.' (DIGIT)+ )=> ( (DIGIT)+ '.' (DIGIT)+ ) { $setType(NUMBER); } | ( DIGIT )+ { $setType(INT_CONST); } // Making sure ',' '(' ')' '=' '<' '>' '+' are not part of WORD. // Double quote " should be included, without it STRING does not match | ( 'a'..'z' | 'A'..'Z' ) ( '"' | '$' | '%' | '&' | '-' | '.' | '0'..'9' | ';' | '?' | '@' | 'A'..'Z' | '\\' | '^' | '_' | '`' | 'a'..'z' )* { $setType(WORD); } | ( '$' ) => ( '$' ( 'a'..'z' | 'A'..'Z' ) ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' )* { $setType(MACRO); } | '$' ) ; STRING : '"' (~'"')* '"'; PIPE_CHAR : '|'; // DOLLAR : '$' ; PERCENT : '%' ; AMPERSAND : '&' ; APOSTROPHE : '\'' ; STAR : '*' ; PLUS : '+' ; COMMA : ',' ; MINUS : '-' ; DOT : '.' ; SLASH : '/' ; // COLON : ':' ; SEMICOLON : ';' ; EQUAL : '='; QUESTION : '?' ; COMMERCIAL_AT : '@' ; OPENING_PAREN : '(' ; CLOSING_PAREN : ')' ; OPENING_SQUARE : '[' ; CLOSING_SQUARE : ']' ; OPENING_BRACE : '{' ; CLOSING_BRACE : '}' ; CARET : '^' ; UNDERLINE : '_' ; TILDE : '~' ; EXLAMATION : '!'; LESS_THAN : '<' ; GREATER_THAN : '>' ; DOUBLE_QUOTE : '"'; fwbuilder-5.1.0.3599/src/parsers/IfconfigBSDCfgParserTokenTypes.txt0000644000175000017500000000235111733011756025706 0ustar sylvestresylvestre// $ANTLR 2.7.7 (20100319): ifconfig_bsd.g -> IfconfigBSDCfgParserTokenTypes.txt$ IfconfigBSDCfgParser // output token vocab name NEWLINE=4 DOUBLE_NEWLINE=5 LINE_COMMENT=6 PRIORITY="priority"=7 MEDIA="media"=8 STATUS="status"=9 WORD=10 COLON=11 FLAGS="flags"=12 EQUAL=13 INT_CONST=14 LLADDR=15 MAC_ADDRESS=16 INET="inet"=17 IPV4=18 NETMASK="netmask"=19 HEX_CONST=20 BROADCAST="broadcast"=21 INET6="inet6"=22 IPV6=23 PERCENT=24 PREFIXLEN="prefixlen"=25 SCOPEID="scopeid"=26 GROUPS="groups"=27 LINK="Link"=28 GLOBAL="Global"=29 HOST="Host"=30 ADDR="addr"=31 BCAST="Bcast"=32 P_T_P="P-t-P"=33 MASK="Mask"=34 SCOPE="Scope"=35 MTU="mtu"=36 ENCAP="encap"=37 LOOPBACK="Loopback"=38 UP="UP"=39 UPPER_BROADCAST="BROADCAST"=40 UPPER_POINTOPOINT="POINTOPOINT"=41 UPPER_LOOPBACK="LOOPBACK"=42 UPPER_NOARP="NOARP"=43 UPPER_RUNNING="RUNNING"=44 RX="RX"=45 TX="TX"=46 COLLISIONS="collisions"=47 INTERRUPT="Interrupt"=48 HWADDR="HWaddr"=49 LLADR="lladdr"=50 Whitespace=51 NUMBER=52 NEG_INT_CONST=53 HEX_DIGIT=54 DIGIT=55 NUM_3DIGIT=56 NUM_HEX_4DIGIT=57 NUMBER_ADDRESS_OR_WORD=58 AMPERSAND=59 STAR=60 MINUS=61 DOT=62 SLASH=63 QUESTION=64 OPENING_PAREN=65 CLOSING_PAREN=66 OPENING_SQUARE=67 CLOSING_SQUARE=68 OPENING_BRACE=69 CLOSING_BRACE=70 LESS_THAN=71 GREATER_THAN=72 fwbuilder-5.1.0.3599/src/parsers/IOSCfgParserTokenTypes.txt0000644000175000017500000000251611733011756024266 0ustar sylvestresylvestre// $ANTLR 2.7.7 (20090306): iosacl.g -> IOSCfgParserTokenTypes.txt$ IOSCfgParser // output token vocab name NEWLINE=4 IP="ip"=5 QUIT="quit"=6 ICMP="icmp"=7 TCP="tcp"=8 HOST="host"=9 COMMUNITY_LIST="community-list"=10 WORD=11 CERTIFICATE="certificate"=12 IOSVERSION="version"=13 NUMBER=14 HOSTNAME="hostname"=15 STRING=16 ACCESS_LIST="access-list"=17 INT_CONST=18 EXTENDED="extended"=19 PERMIT="permit"=20 DENY="deny"=21 UDP="udp"=22 P_EQ="eq"=23 P_GT="gt"=24 P_LT="lt"=25 P_NEQ="neq"=26 P_RANGE="range"=27 IPV4=28 ANY="any"=29 LOG="log"=30 LOG_INPUT="log-input"=31 ESTABLISHED="established"=32 FRAGMENTS="fragments"=33 TIME_RANGE="time-range"=34 VLAN="vlan"=35 CONTROLLER="controller"=36 INTRFACE="interface"=37 POINT_TO_POINT="point-to-point"=38 DESCRIPTION="description"=39 REMARK="remark"=40 SHUTDOWN="shutdown"=41 ACCESS_GROUP="access-group"=42 ADDRESS="address"=43 SECONDARY="secondary"=44 EXIT="exit"=45 LINE_COMMENT=46 STANDARD="standard"=47 Whitespace=48 HEX_CONST=49 NEG_INT_CONST=50 DIGIT=51 HEXDIGIT=52 PIPE_CHAR=53 NUMBER_SIGN=54 PERCENT=55 AMPERSAND=56 APOSTROPHE=57 OPENING_PAREN=58 CLOSING_PAREN=59 STAR=60 PLUS=61 COMMA=62 MINUS=63 DOT=64 SLASH=65 COLON=66 SEMICOLON=67 LESS_THAN=68 EQUALS=69 GREATER_THAN=70 QUESTION=71 COMMERCIAL_AT=72 OPENING_SQUARE=73 CLOSING_SQUARE=74 CARET=75 UNDERLINE=76 OPENING_BRACE=77 CLOSING_BRACE=78 TILDE=79 fwbuilder-5.1.0.3599/src/parsers/IfconfigBSDCfgLexer.hpp0000644000175000017500000000722211733011756023455 0ustar sylvestresylvestre#ifndef INC_IfconfigBSDCfgLexer_hpp_ #define INC_IfconfigBSDCfgLexer_hpp_ #line 25 "ifconfig_bsd.g" // gets inserted before antlr generated includes in the header // file #include "IfconfigImporter.h" #line 11 "IfconfigBSDCfgLexer.hpp" #include /* $ANTLR 2.7.7 (20100319): "ifconfig_bsd.g" -> "IfconfigBSDCfgLexer.hpp"$ */ #include #include #include #include "IfconfigBSDCfgParserTokenTypes.hpp" #include #line 32 "ifconfig_bsd.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class IfconfigImporter; #line 29 "IfconfigBSDCfgLexer.hpp" #line 57 "ifconfig_bsd.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 35 "IfconfigBSDCfgLexer.hpp" class CUSTOM_API IfconfigBSDCfgLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public IfconfigBSDCfgParserTokenTypes { #line 1 "ifconfig_bsd.g" #line 39 "IfconfigBSDCfgLexer.hpp" private: void initLiterals(); public: bool getCaseSensitiveLiterals() const { return true; } public: IfconfigBSDCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in); IfconfigBSDCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); IfconfigBSDCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); public: void mLINE_COMMENT(bool _createToken); public: void mNEWLINE(bool _createToken); public: void mWhitespace(bool _createToken); protected: void mINT_CONST(bool _createToken); protected: void mHEX_CONST(bool _createToken); protected: void mNUMBER(bool _createToken); protected: void mNEG_INT_CONST(bool _createToken); protected: void mCOLON(bool _createToken); protected: void mHEX_DIGIT(bool _createToken); protected: void mDIGIT(bool _createToken); protected: void mNUM_3DIGIT(bool _createToken); protected: void mNUM_HEX_4DIGIT(bool _createToken); protected: void mMAC_ADDRESS(bool _createToken); public: void mNUMBER_ADDRESS_OR_WORD(bool _createToken); public: void mPERCENT(bool _createToken); public: void mAMPERSAND(bool _createToken); public: void mSTAR(bool _createToken); public: void mMINUS(bool _createToken); public: void mDOT(bool _createToken); public: void mSLASH(bool _createToken); public: void mEQUAL(bool _createToken); public: void mQUESTION(bool _createToken); public: void mOPENING_PAREN(bool _createToken); public: void mCLOSING_PAREN(bool _createToken); public: void mOPENING_SQUARE(bool _createToken); public: void mCLOSING_SQUARE(bool _createToken); public: void mOPENING_BRACE(bool _createToken); public: void mCLOSING_BRACE(bool _createToken); public: void mLESS_THAN(bool _createToken); public: void mGREATER_THAN(bool _createToken); private: static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; }; #endif /*INC_IfconfigBSDCfgLexer_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PIXCfgParser.hpp0000644000175000017500000002771711733011756022230 0ustar sylvestresylvestre#ifndef INC_PIXCfgParser_hpp_ #define INC_PIXCfgParser_hpp_ #line 25 "pix.g" // gets inserted before antlr generated includes in the header // file #include "PIXImporter.h" #line 11 "PIXCfgParser.hpp" #include /* $ANTLR 2.7.7 (20090306): "pix.g" -> "PIXCfgParser.hpp"$ */ #include #include #include "PIXCfgParserTokenTypes.hpp" #include #line 32 "pix.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class PIXImporter; #line 28 "PIXCfgParser.hpp" #line 56 "pix.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 34 "PIXCfgParser.hpp" class CUSTOM_API PIXCfgParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public PIXCfgParserTokenTypes { #line 81 "pix.g" // additional methods and members public: std::ostream *dbg; PIXImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); std::cerr << s << std::endl; } #line 38 "PIXCfgParser.hpp" public: void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory ); protected: PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k); public: PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf); protected: PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k); public: PIXCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer); PIXCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state); int getNumTokens() const { return PIXCfgParser::NUM_TOKENS; } const char* getTokenName( int type ) const { if( type > getNumTokens() ) return 0; return PIXCfgParser::tokenNames[type]; } const char* const* getTokenNames() const { return PIXCfgParser::tokenNames; } public: void cfgfile(); public: void comment(); public: void version(); public: void hostname(); public: void community_list_command(); public: void unknown_ip_command(); public: void intrface(); public: void nameif_top_level(); public: void intf_address(); public: void controller(); public: void access_list_commands(); public: void ssh_command(); public: void telnet_command(); public: void http_command(); public: void icmp_top_level_command(); public: void nat_top_level_command(); public: void global_top_level_command(); public: void static_top_level_command(); public: void access_group(); public: void exit(); public: void certificate(); public: void quit(); public: void names_section(); public: void name_entry(); public: void named_object_network(); public: void named_object_service(); public: void object_group_network(); public: void object_group_service(); public: void object_group_protocol(); public: void object_group_icmp_8_0(); public: void object_group_icmp_8_3(); public: void crypto(); public: void no_commands(); public: void timeout_command(); public: void dns_command(); public: void service_top_level_command(); public: void pim_top_level_command(); public: void network_top_level_command(); public: void unknown_command(); public: void name_entry_ipv4(); public: void name_entry_ipv6(); public: void ip_protocol_names(); public: void named_object_nat(); public: void named_object_description(); public: void named_object_network_parameters(); public: void host_addr(); public: void range_addr(); public: void subnet_addr(); public: void single_addr(); public: void named_object_service_parameters(); public: void service_icmp(); public: void service_icmp6(); public: void service_tcp_udp(); public: void service_other(); public: void service_unknown(); public: void icmp_names(); public: void src_port_spec(); public: void dst_port_spec(); public: void xoperator(); public: void object_group_network_parameters(); public: void object_group_description(); public: void group_object(); public: void network_object(); public: void object_group_protocol_parameters(); public: void protocol_object(); public: void object_group_icmp_parameters(); public: void icmp_object(); public: void object_group_service_parameters(); public: void service_object(); public: void port_object(); public: void permit_extended(); public: void deny_extended(); public: void permit_standard(); public: void deny_standard(); public: void remark(); public: void rule_extended(); public: void rule_standard(); public: void hostaddr_expr(); public: void ip_protocols(); public: void time_range(); public: void fragments(); public: void log(); public: void icmp_spec(); public: void tcp_udp_rule_extended(); public: void hostaddr_expr_1(); public: void acl_tcp_udp_dst_port_spec(); public: void hostaddr_expr_2(); public: void acl_xoperator_dst(); public: void established(); public: void hostaddr_expr_3(); public: void single_port_op(); public: void port_range(); public: void port_spec(); public: void tcp_udp_port_spec(); public: void pair_of_ports_spec(); public: void tcp_udp_port_names(); public: void interface_label(); public: void interface_command_6(); public: void interface_command_7(); public: void pix6_interface_hw_speed(); public: void interface_parameters(); public: void vlan_interface(); public: void sec_level(); public: void nameif(); public: void interface_description(); public: void switchport(); public: void shutdown(); public: void interface_no_commands(); public: void unsupported_interface_commands(); public: void v6_ip_address(); public: void v7_ip_address(); public: void v6_dhcp_address(); public: void v6_static_address(); public: void v7_dhcp_address(); public: void v7_static_address(); public: void icmp_types_for_icmp_command(); public: void nat_old_top_level_command(); public: void nat_new_top_level_command(); public: void nat_addr_match(); public: void nat_command_last_parameters(); public: void nat_and_static_command_common_last_parameters(); public: void static_starts_with_hostaddr(); public: void static_starts_with_tcp_udp(); public: void static_mapped_addr_match(); public: void static_real_addr_match(); public: void static_command_common_last_parameters(); public: ANTLR_USE_NAMESPACE(antlr)RefAST getAST() { return returnAST; } protected: ANTLR_USE_NAMESPACE(antlr)RefAST returnAST; private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS static const int NUM_TOKENS = 197; #else enum { NUM_TOKENS = 197 }; #endif static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; static const unsigned long _tokenSet_7_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_7; static const unsigned long _tokenSet_8_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_8; static const unsigned long _tokenSet_9_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_9; static const unsigned long _tokenSet_10_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_10; static const unsigned long _tokenSet_11_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_11; static const unsigned long _tokenSet_12_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_12; static const unsigned long _tokenSet_13_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_13; static const unsigned long _tokenSet_14_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_14; static const unsigned long _tokenSet_15_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_15; static const unsigned long _tokenSet_16_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_16; static const unsigned long _tokenSet_17_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_17; static const unsigned long _tokenSet_18_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_18; static const unsigned long _tokenSet_19_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_19; static const unsigned long _tokenSet_20_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_20; static const unsigned long _tokenSet_21_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_21; static const unsigned long _tokenSet_22_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_22; static const unsigned long _tokenSet_23_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_23; static const unsigned long _tokenSet_24_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_24; static const unsigned long _tokenSet_25_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_25; static const unsigned long _tokenSet_26_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_26; static const unsigned long _tokenSet_27_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_27; static const unsigned long _tokenSet_28_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_28; static const unsigned long _tokenSet_29_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_29; static const unsigned long _tokenSet_30_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_30; static const unsigned long _tokenSet_31_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_31; static const unsigned long _tokenSet_32_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_32; static const unsigned long _tokenSet_33_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_33; static const unsigned long _tokenSet_34_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_34; static const unsigned long _tokenSet_35_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_35; static const unsigned long _tokenSet_36_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_36; static const unsigned long _tokenSet_37_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_37; static const unsigned long _tokenSet_38_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_38; static const unsigned long _tokenSet_39_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_39; static const unsigned long _tokenSet_40_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_40; static const unsigned long _tokenSet_41_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_41; static const unsigned long _tokenSet_42_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_42; static const unsigned long _tokenSet_43_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_43; static const unsigned long _tokenSet_44_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_44; }; #endif /*INC_PIXCfgParser_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PIXCfgParserTokenTypes.hpp0000644000175000017500000000751211733011756024245 0ustar sylvestresylvestre#ifndef INC_PIXCfgParserTokenTypes_hpp_ #define INC_PIXCfgParserTokenTypes_hpp_ /* $ANTLR 2.7.7 (20090306): "pix.g" -> "PIXCfgParserTokenTypes.hpp"$ */ #ifndef CUSTOM_API # define CUSTOM_API #endif #ifdef __cplusplus struct CUSTOM_API PIXCfgParserTokenTypes { #endif enum { EOF_ = 1, NEWLINE = 4, QUIT = 5, IP = 6, COMMUNITY_LIST = 7, TIMEOUT = 8, PIM = 9, NETWORK = 10, NAMES = 11, NAME = 12, IPV4 = 13, WORD = 14, IPV6 = 15, AH = 16, EIGRP = 17, ESP_WORD = 18, GRE = 19, IGMP = 20, IGRP = 21, IPINIP = 22, IPSEC = 23, NOS = 24, OSPF = 25, PCP = 26, PPTP = 27, SNP = 28, OBJECT = 29, DESCRIPTION = 30, HOST = 31, RANGE = 32, SUBNET = 33, SERVICE = 34, HTTP = 35, SSH = 36, TELNET = 37, ICMP = 38, INT_CONST = 39, ICMP6 = 40, TCP = 41, UDP = 42, SOURCE = 43, DESTINATION = 44, OBJECT_GROUP = 45, GROUP_OBJECT = 46, NETWORK_OBJECT = 47, PROTOCOL = 48, PROTOCOL_OBJECT = 49, ICMP_OBJECT = 50, ICMP_TYPE = 51, TCP_UDP = 52, SERVICE_OBJECT = 53, PORT_OBJECT = 54, CRYPTO = 55, DNS = 56, CALL_HOME = 57, INTERNAL = 58, PASSWORD_RECOVERY = 59, RESETINBOUND = 60, RESETOUTBOUND = 61, RESETOUTSIDE = 62, NO = 63, CERTIFICATE = 64, PIX_WORD = 65, ASA_WORD = 66, FWSM_WORD = 67, VERSION_WORD_CAP = 68, NUMBER = 69, HOSTNAME = 70, STRING = 71, ACCESS_LIST = 72, EXTENDED = 73, PERMIT = 74, DENY = 75, STANDARD = 76, P_EQ = 77, P_GT = 78, P_LT = 79, P_NEQ = 80, ECHO = 81, ESTABLISHED = 82, ALTERNATE_ADDRESS = 83, CONVERSION_ERROR = 84, ECHO_REPLY = 85, INFORMATION_REPLY = 86, INFORMATION_REQUEST = 87, MASK_REPLY = 88, MASK_REQUEST = 89, MOBILE_REDIRECT = 90, PARAMETER_PROBLEM = 91, REDIRECT = 92, ROUTER_ADVERTISEMENT = 93, ROUTER_SOLICITATION = 94, SOURCE_QUENCH = 95, TIME_EXCEEDED = 96, TIMESTAMP_REPLY = 97, TIMESTAMP_REQUEST = 98, TRACEROUTE = 99, UNREACHABLE = 100, INTRFACE = 101, ANY = 102, LOG = 103, LOG_INPUT = 104, LOG_LEVEL_ALERTS = 105, LOG_LEVEL_CRITICAL = 106, LOG_LEVEL_DEBUGGING = 107, LOG_LEVEL_EMERGENCIES = 108, LOG_LEVEL_ERRORS = 109, LOG_LEVEL_INFORMATIONAL = 110, LOG_LEVEL_NOTIFICATIONS = 111, LOG_LEVEL_WARNINGS = 112, LOG_LEVEL_DISABLE = 113, LOG_LEVEL_INACTIVE = 114, INTERVAL = 115, FRAGMENTS = 116, TIME_RANGE = 117, CONTROLLER = 118, OUTSIDE = 119, LINE_COMMENT = 120, EXIT = 121, AUI = 122, AUTO = 123, BNC = 124, FULL = 125, BASET = 126, BASETX = 127, NAMEIF = 128, VLAN = 129, SPEED = 130, DUPLEX = 131, DDNS = 132, FORWARD = 133, DELAY = 134, HOLD_TIME = 135, IPV6_C = 136, MANAGEMENT_ONLY = 137, MAC_ADDRESS = 138, MULTICAST = 139, PPPOE = 140, RIP = 141, SEC_LEVEL = 142, SHUTDOWN = 143, ADDRESS = 144, DHCP = 145, STANDBY = 146, SWITCHPORT = 147, ACCESS = 148, SCOPY = 149, VERSION_WORD_LOW = 150, AUTHENTICATION_CERTIFICATE = 151, SERVER = 152, REMARK = 153, ACCESS_GROUP = 154, COLON_COMMENT = 155, NAT = 156, OPENING_PAREN = 157, CLOSING_PAREN = 158, COMMA = 159, GLOBAL = 160, MINUS = 161, NETMASK = 162, STATIC = 163, NORANDOMSEQ = 164, SECONDARY = 165, SETROUTE = 166, Whitespace = 167, HEX_CONST = 168, NEG_INT_CONST = 169, DIGIT = 170, HEXDIGIT = 171, NUMBER_ADDRESS_OR_WORD = 172, PIPE_CHAR = 173, NUMBER_SIGN = 174, PERCENT = 175, AMPERSAND = 176, APOSTROPHE = 177, STAR = 178, PLUS = 179, DOT = 180, SLASH = 181, COLON = 182, SEMICOLON = 183, LESS_THAN = 184, EQUALS = 185, GREATER_THAN = 186, QUESTION = 187, COMMERCIAL_AT = 188, OPENING_SQUARE = 189, CLOSING_SQUARE = 190, CARET = 191, UNDERLINE = 192, OPENING_BRACE = 193, CLOSING_BRACE = 194, TILDE = 195, EXLAMATION = 196, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus }; #endif #endif /*INC_PIXCfgParserTokenTypes_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IfconfigLinuxCfgParser.cpp0000644000175000017500000003304611733011756024317 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20100319): "ifconfig_linux.g" -> "IfconfigLinuxCfgParser.cpp"$ */ #line 43 "ifconfig_linux.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "IfconfigLinuxCfgParser.cpp" #include "IfconfigLinuxCfgParser.hpp" #include #include #include #line 49 "ifconfig_linux.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 20 "IfconfigLinuxCfgParser.cpp" #line 1 "ifconfig_linux.g" #line 22 "IfconfigLinuxCfgParser.cpp" IfconfigLinuxCfgParser::IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,k) { } IfconfigLinuxCfgParser::IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf) : ANTLR_USE_NAMESPACE(antlr)LLkParser(tokenBuf,2) { } IfconfigLinuxCfgParser::IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,k) { } IfconfigLinuxCfgParser::IfconfigLinuxCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer) : ANTLR_USE_NAMESPACE(antlr)LLkParser(lexer,2) { } IfconfigLinuxCfgParser::IfconfigLinuxCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)LLkParser(state,2) { } void IfconfigLinuxCfgParser::cfgfile() { Tracer traceInOut(this, "cfgfile"); try { // for error handling { // ( ... )* for (;;) { switch ( LA(1)) { case LINE_COMMENT: { comment(); break; } case HWADDR: { hwaddr_line(); break; } case INET: { inet_address(); break; } case INET6: { inet6_address(); break; } case GROUPS: { groups(); break; } case UP: case UPPER_BROADCAST: case UPPER_POINTOPOINT: case UPPER_LOOPBACK: case UPPER_NOARP: case UPPER_RUNNING: case LOOPBACK: { interface_flags(); break; } case INTERRUPT: case COLLISIONS: case RX: case TX: { interface_statistics(); break; } case NEWLINE: { match(NEWLINE); break; } case DOUBLE_NEWLINE: { match(DOUBLE_NEWLINE); break; } default: if ((LA(1) == WORD) && (LA(2) == COLON || LA(2) == DOT || LA(2) == LINK)) { interface_line(); } else if (((LA(1) >= PRIORITY && LA(1) <= WORD)) && (_tokenSet_0.member(LA(2)))) { unknown_line(); } else { goto _loop3; } } } _loop3:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_1); } } void IfconfigLinuxCfgParser::comment() { Tracer traceInOut(this, "comment"); try { // for error handling match(LINE_COMMENT); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::interface_line() { Tracer traceInOut(this, "interface_line"); ANTLR_USE_NAMESPACE(antlr)RefToken in1 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken in2 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken lbl1 = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken lbl2 = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 206 "ifconfig_linux.g" InterfaceSpec is; #line 150 "IfconfigLinuxCfgParser.cpp" try { // for error handling in1 = LT(1); match(WORD); { switch ( LA(1)) { case DOT: { match(DOT); in2 = LT(1); match(INT_CONST); break; } case COLON: case LINK: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } { switch ( LA(1)) { case COLON: { match(COLON); { switch ( LA(1)) { case WORD: { lbl1 = LT(1); match(WORD); break; } case INT_CONST: { lbl2 = LT(1); match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } break; } case LINK: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(LINK); match(ENCAP); match(COLON); match(WORD); #line 212 "ifconfig_linux.g" // interface name and status if (in2) is.name = in1->getText() + "." + in2->getText(); else is.name = in1->getText(); if (lbl1) is.label = lbl1->getText(); if (lbl2) is.label = lbl2->getText(); importer->newInterface(is); #line 225 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::hwaddr_line() { Tracer traceInOut(this, "hwaddr_line"); ANTLR_USE_NAMESPACE(antlr)RefToken addr = ANTLR_USE_NAMESPACE(antlr)nullToken; try { // for error handling match(HWADDR); addr = LT(1); match(MAC_ADDRESS); #line 227 "ifconfig_linux.g" importer->HwAddressForCurrentInterface(addr->getText()); #line 245 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::inet_address() { Tracer traceInOut(this, "inet_address"); ANTLR_USE_NAMESPACE(antlr)RefToken addr = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken bcast = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken netm = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 236 "ifconfig_linux.g" AddressSpec as; #line 260 "IfconfigLinuxCfgParser.cpp" try { // for error handling match(INET); match(ADDR); match(COLON); addr = LT(1); match(IPV4); #line 240 "ifconfig_linux.g" as.at = AddressSpec::INTERFACE_CONFIGURATION; as.address = addr->getText(); #line 273 "IfconfigLinuxCfgParser.cpp" { switch ( LA(1)) { case BCAST: case MASK: { { { switch ( LA(1)) { case BCAST: { match(BCAST); match(COLON); bcast = LT(1); match(IPV4); break; } case MASK: { break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(MASK); match(COLON); netm = LT(1); match(IPV4); } #line 246 "ifconfig_linux.g" as.netmask = netm->getText(); if (bcast) as.broadcast = bcast->getText(); #line 310 "IfconfigLinuxCfgParser.cpp" break; } case P_T_P: { { match(P_T_P); match(COLON); match(IPV4); match(MASK); match(COLON); match(IPV4); } #line 252 "ifconfig_linux.g" // we do not support p2p interfaces at this time #line 327 "IfconfigLinuxCfgParser.cpp" break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 256 "ifconfig_linux.g" importer->inetConfigurationForCurrentInterface(as); #line 340 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::inet6_address() { Tracer traceInOut(this, "inet6_address"); ANTLR_USE_NAMESPACE(antlr)RefToken addr = ANTLR_USE_NAMESPACE(antlr)nullToken; ANTLR_USE_NAMESPACE(antlr)RefToken netm = ANTLR_USE_NAMESPACE(antlr)nullToken; #line 264 "ifconfig_linux.g" AddressSpec as; #line 354 "IfconfigLinuxCfgParser.cpp" try { // for error handling match(INET6); match(ADDR); match(COLON); addr = LT(1); match(IPV6); match(SLASH); netm = LT(1); match(INT_CONST); match(SCOPE); match(COLON); { switch ( LA(1)) { case HOST: { match(HOST); break; } case LINK: { match(LINK); break; } case GLOBAL: { match(GLOBAL); break; } case INT_CONST: { match(INT_CONST); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 267 "ifconfig_linux.g" as.at = AddressSpec::INTERFACE_CONFIGURATION; as.address = addr->getText(); as.netmask = netm->getText(); importer->inet6ConfigurationForCurrentInterface(as); #line 402 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::groups() { Tracer traceInOut(this, "groups"); try { // for error handling match(GROUPS); match(COLON); groups_list(); match(NEWLINE); } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::interface_flags() { Tracer traceInOut(this, "interface_flags"); try { // for error handling { switch ( LA(1)) { case UP: { match(UP); break; } case UPPER_BROADCAST: { match(UPPER_BROADCAST); break; } case UPPER_POINTOPOINT: { match(UPPER_POINTOPOINT); break; } case UPPER_LOOPBACK: { match(UPPER_LOOPBACK); break; } case UPPER_NOARP: { match(UPPER_NOARP); break; } case UPPER_RUNNING: { match(UPPER_RUNNING); break; } case LOOPBACK: { match(LOOPBACK); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 178 "ifconfig_linux.g" consumeUntil(NEWLINE); #line 476 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::interface_statistics() { Tracer traceInOut(this, "interface_statistics"); try { // for error handling { switch ( LA(1)) { case INTERRUPT: case COLLISIONS: { { { switch ( LA(1)) { case INTERRUPT: { match(INTERRUPT); break; } case COLLISIONS: { match(COLLISIONS); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } match(COLON); } break; } case RX: { match(RX); break; } case TX: { match(TX); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 192 "ifconfig_linux.g" consumeUntil(NEWLINE); #line 536 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::unknown_line() { Tracer traceInOut(this, "unknown_line"); try { // for error handling { switch ( LA(1)) { case PRIORITY: { match(PRIORITY); break; } case MEDIA: { match(MEDIA); break; } case STATUS: { match(STATUS); break; } case WORD: { match(WORD); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltException(LT(1), getFilename()); } } } #line 156 "ifconfig_linux.g" consumeUntil(NEWLINE); #line 580 "IfconfigLinuxCfgParser.cpp" } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_0); } } void IfconfigLinuxCfgParser::groups_list() { Tracer traceInOut(this, "groups_list"); try { // for error handling match(WORD); #line 284 "ifconfig_linux.g" importer->addGroupToCurrentInterface(LT(0)->getText()); #line 595 "IfconfigLinuxCfgParser.cpp" { // ( ... )* for (;;) { if ((LA(1) == WORD)) { match(WORD); #line 286 "ifconfig_linux.g" importer->addGroupToCurrentInterface(LT(0)->getText()); #line 602 "IfconfigLinuxCfgParser.cpp" } else { goto _loop28; } } _loop28:; } // ( ... )* } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { reportError(ex); recover(ex,_tokenSet_2); } } void IfconfigLinuxCfgParser::initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& ) { } const char* IfconfigLinuxCfgParser::tokenNames[] = { "<0>", "EOF", "<2>", "NULL_TREE_LOOKAHEAD", "NEWLINE", "DOUBLE_NEWLINE", "LINE_COMMENT", "\"priority\"", "\"media\"", "\"status\"", "WORD", "\"UP\"", "\"BROADCAST\"", "\"POINTOPOINT\"", "\"LOOPBACK\"", "\"NOARP\"", "\"RUNNING\"", "\"Loopback\"", "\"Interrupt\"", "\"collisions\"", "COLON", "\"RX\"", "\"TX\"", "DOT", "INT_CONST", "\"Link\"", "\"encap\"", "\"HWaddr\"", "MAC_ADDRESS", "\"inet\"", "\"addr\"", "IPV4", "\"Bcast\"", "\"Mask\"", "\"P-t-P\"", "\"inet6\"", "IPV6", "SLASH", "\"Scope\"", "\"Host\"", "\"Global\"", "\"groups\"", "\"flags\"", "\"broadcast\"", "\"netmask\"", "\"prefixlen\"", "\"scopeid\"", "\"mtu\"", "\"lladdr\"", "Whitespace", "HEX_CONST", "NUMBER", "NEG_INT_CONST", "HEX_DIGIT", "DIGIT", "NUM_3DIGIT", "NUM_HEX_4DIGIT", "NUMBER_ADDRESS_OR_WORD", "PERCENT", "AMPERSAND", "STAR", "MINUS", "EQUAL", "QUESTION", "OPENING_PAREN", "CLOSING_PAREN", "OPENING_SQUARE", "CLOSING_SQUARE", "OPENING_BRACE", "CLOSING_BRACE", "LESS_THAN", "GREATER_THAN", 0 }; const unsigned long IfconfigLinuxCfgParser::_tokenSet_0_data_[] = { 678428658UL, 520UL, 0UL, 0UL }; // EOF NEWLINE DOUBLE_NEWLINE LINE_COMMENT "priority" "media" "status" // WORD "UP" "BROADCAST" "POINTOPOINT" "LOOPBACK" "NOARP" "RUNNING" "Loopback" // "Interrupt" "collisions" "RX" "TX" "HWaddr" "inet" "inet6" "groups" const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgParser::_tokenSet_0(_tokenSet_0_data_,4); const unsigned long IfconfigLinuxCfgParser::_tokenSet_1_data_[] = { 2UL, 0UL, 0UL, 0UL }; // EOF const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgParser::_tokenSet_1(_tokenSet_1_data_,4); const unsigned long IfconfigLinuxCfgParser::_tokenSet_2_data_[] = { 16UL, 0UL, 0UL, 0UL }; // NEWLINE const ANTLR_USE_NAMESPACE(antlr)BitSet IfconfigLinuxCfgParser::_tokenSet_2(_tokenSet_2_data_,4); fwbuilder-5.1.0.3599/src/parsers/parsers.pro0000644000175000017500000000151611733011756021450 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib # SOURCES = IOSCfgLexer.cpp \ IOSCfgParser.cpp \ IPTCfgLexer.cpp \ IPTCfgParser.cpp \ PIXCfgLexer.cpp \ PIXCfgParser.cpp \ PFCfgLexer.cpp \ PFCfgParser.cpp \ HEADERS = ../../config.h \ IOSCfgLexer.hpp \ IOSCfgParser.hpp \ IOSCfgParserTokenTypes.hpp \ IPTCfgLexer.hpp \ IPTCfgParser.hpp \ IPTCfgParserTokenTypes.hpp \ PIXCfgLexer.hpp \ PIXCfgParser.hpp \ PIXCfgParserTokenTypes.hpp \ PFCfgLexer.hpp \ PFCfgParser.hpp \ PFCfgParserTokenTypes.hpp \ CONFIG += staticlib INCLUDEPATH += $$ANTLR_INCLUDEPATH ../import ../libfwbuilder/src DEPENDPATH += $$ANTLR_INCLUDEPATH ../import ../libfwbuilder/src LIBS += $$ANTLR_LIBS DEFINES += $$ANTLR_DEFINES TARGET = fwbparser INSTALLS -= target fwbuilder-5.1.0.3599/src/parsers/IPTCfgParserTokenTypes.hpp0000644000175000017500000000610711733011756024240 0ustar sylvestresylvestre#ifndef INC_IPTCfgParserTokenTypes_hpp_ #define INC_IPTCfgParserTokenTypes_hpp_ /* $ANTLR 2.7.7 (20090306): "iptables.g" -> "IPTCfgParserTokenTypes.hpp"$ */ #ifndef CUSTOM_API # define CUSTOM_API #endif #ifdef __cplusplus struct CUSTOM_API IPTCfgParserTokenTypes { #endif enum { EOF_ = 1, NEWLINE = 4, NUMBER_SIGN = 5, IPTABLES_SAVE_HEADER = 6, THREE_COMPONENT_VERSION = 7, IPV4 = 8, COMMIT = 9, STAR = 10, WORD = 11, INPUT = 12, FORWARD = 13, OUTPUT = 14, PREROUTING = 15, POSTROUTING = 16, COLON = 17, MINUS = 18, OPENING_SQUARE = 19, INT_CONST = 20, CLOSING_SQUARE = 21, ADD_RULE = 22, EXCLAMATION = 23, UNSUPPORTED_OPTION = 24, DIGIT = 25, SLASH = 26, OPT_MODULE = 27, OPT_SRC = 28, OPT_DST = 29, OPT_IN_INTF = 30, OPT_OUT_INTF = 31, TCP = 32, UDP = 33, ICMP = 34, OPT_PROTO = 35, OPT_TARGET = 36, REJECT_WITH = 37, LOG_PREFIX = 38, STRING = 39, LOG_TCP_SEQ = 40, LOG_TCP_OPT = 41, LOG_IP_OPT = 42, ULOG_PREFIX = 43, LOG_LEVEL = 44, SET_CLASS = 45, SET_MARK = 46, HEX_CONST = 47, SET_TOS = 48, SAVE_MARK = 49, RESTORE_MARK = 50, CONTINUE = 51, ROUTE_IIF = 52, ROUTE_OIF = 53, ROUTE_GW = 54, ROUTE_TEE = 55, TO_SOURCE = 56, TO_DESTINATION = 57, TO_PORTS = 58, TO_NETMAP = 59, CLAMP_MSS = 60, OPT_FRAGM = 61, INVALID = 62, NEW = 63, ESTABLISHED = 64, RELATED = 65, M_STATE = 66, MATCH_STATE = 67, COMMA = 68, M_MARK = 69, MATCH_MARK = 70, M_LIMIT = 71, MATCH_LIMIT = 72, MATCH_LIMIT_BURST = 73, M_RECENT = 74, M_IPRANGE = 75, MATCH_IPRANGE_SRC = 76, MATCH_IPRANGE_DST = 77, MATCH_RECENT_SET = 78, MATCH_RECENT_RCHECK = 79, MATCH_RECENT_UPDATE = 80, MATCH_RECENT_REMOVE = 81, MATCH_RECENT_RTTL = 82, RSOURCE = 83, MATCH_RECENT_RDEST = 84, MATCH_RECENT_NAME = 85, MATCH_RECENT_SECONDS = 86, MATCH_RECENT_HITCOUNT = 87, M_LENGTH = 88, MATCH_LENGTH = 89, M_PKTTYPE = 90, MATCH_PKT_TYPE = 91, WORD_BROADCAST = 92, WORD_MULTICAST = 93, WORD_UNICAST = 94, M_MPORT = 95, M_COMMENT = 96, MATCH_COMMENT = 97, MATCH_SRC_MULTIPORT = 98, MATCH_DST_MULTIPORT = 99, MATCH_BOTH_MULTIPORT = 100, MATCH_ICMP_TYPE = 101, MATCH_SRC_PORT = 102, MATCH_SRC_PORT_SHORT = 103, MATCH_DST_PORT = 104, MATCH_DST_PORT_SHORT = 105, MATCH_SYN = 106, SYN = 107, ACK = 108, FIN = 109, RST = 110, URG = 111, PSH = 112, ALL = 113, NONE = 114, MATCH_TCP_FLAGS = 115, MATCH_TCP_OPTION = 116, Whitespace = 117, IPV6 = 118, MAC_ADDRESS = 119, NEG_INT_CONST = 120, HEXDIGIT = 121, NUM_3DIGIT = 122, NUM_HEX_4DIGIT = 123, NUMBER = 124, ULOG_QTHR = 125, ULOG_NLG = 126, ULOG_CPR = 127, PERCENT = 128, AMPERSAND = 129, APOSTROPHE = 130, OPENING_PAREN = 131, CLOSING_PAREN = 132, PLUS = 133, DOT = 134, SEMICOLON = 135, LESS_THAN = 136, EQUALS = 137, GREATER_THAN = 138, QUESTION = 139, COMMERCIAL_AT = 140, CARET = 141, UNDERLINE = 142, OPENING_BRACE = 143, CLOSING_BRACE = 144, TILDE = 145, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus }; #endif #endif /*INC_IPTCfgParserTokenTypes_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PIXCfgParser.txt0000644000175000017500000045547111733011756022262 0ustar sylvestresylvestreANTLR-generated file resulting from grammar pix.g Diagnostic output Terence Parr, MageLang Institute with John Lilley, Empathy Software ANTLR Version 2.7.7 (20090306); 1989-2005 *** Header Action. This action will appear at the top of all generated files. // gets inserted after generated namespace specifications in the // header file. But outside the generated class. *** End of Header Action *** Parser Preamble Action. This action will appear before the declaration of your parser class: *** End of Parser Preamble Action *** Your parser class is called 'PIXCfgParser' and is a subclass of 'LLkParser'. *** User-defined parser class members: These are the member declarations that you defined for your class: // additional methods and members public: std::ostream *dbg; PIXImporter *importer; *** End of user-defined parser class members *** Parser rules: *** Parser Rule: cfgfile Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } is matched. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: { NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } k==2: { EOF, NEWLINE, "quit", "ip", "community-list", "names", "name", IPV4, WORD, INT_CONST, "object", "network", "service", "object-group", "protocol", "icmp-type", "crypto", "certificate", "PIX", "ASA", "Version", "hostname", STRING, "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { LINE_COMMENT, COLON_COMMENT } is matched. Rule Reference: comment Otherwise, Alternate(2) will be taken IF: The lookahead set: { "PIX", "ASA" } is matched. Rule Reference: version Otherwise, Alternate(3) will be taken IF: The lookahead set: { "hostname" } is matched. Rule Reference: hostname Otherwise, Alternate(4) will be taken IF: The lookahead set: k==1: {"ip" } k==2: {"access-list" } is matched. Rule Reference: ip_access_list_ext Otherwise, Alternate(5) will be taken IF: The lookahead set: k==1: {"ip" } k==2: {"community-list" } is matched. Rule Reference: community_list_command Otherwise, Alternate(6) will be taken IF: The lookahead set: k==1: {"ip" } k==2: {WORD } is matched. Rule Reference: unknown_ip_command Otherwise, Alternate(7) will be taken IF: The lookahead set: { "interface" } is matched. Rule Reference: intrface Otherwise, Alternate(8) will be taken IF: The lookahead set: { "controller" } is matched. Rule Reference: controller Otherwise, Alternate(9) will be taken IF: The lookahead set: { "access-list" } is matched. Rule Reference: access_list_commands Otherwise, Alternate(10) will be taken IF: The lookahead set: { "exit" } is matched. Rule Reference: exit Otherwise, Alternate(11) will be taken IF: The lookahead set: { "certificate" } is matched. Rule Reference: certificate Otherwise, Alternate(12) will be taken IF: The lookahead set: { "quit" } is matched. Rule Reference: quit Otherwise, Alternate(13) will be taken IF: The lookahead set: { "names" } is matched. Rule Reference: names_section Otherwise, Alternate(14) will be taken IF: The lookahead set: { "name", INT_CONST } is matched. Rule Reference: name_entry Otherwise, Alternate(15) will be taken IF: The lookahead set: k==1: {"object" } k==2: {"network" } is matched. Rule Reference: named_object_network Otherwise, Alternate(16) will be taken IF: The lookahead set: k==1: {"object" } k==2: {"service" } is matched. Rule Reference: named_object_service Otherwise, Alternate(17) will be taken IF: The lookahead set: k==1: {"object-group" } k==2: {"network" } is matched. Rule Reference: object_group_network Otherwise, Alternate(18) will be taken IF: The lookahead set: k==1: {"object-group" } k==2: {"service" } is matched. Rule Reference: object_group_service Otherwise, Alternate(19) will be taken IF: The lookahead set: k==1: {"object-group" } k==2: {"protocol" } is matched. Rule Reference: object_group_protocol Otherwise, Alternate(20) will be taken IF: The lookahead set: k==1: {"object-group" } k==2: {"icmp-type" } is matched. Rule Reference: object_group_icmp Otherwise, Alternate(21) will be taken IF: The lookahead set: { "crypto" } is matched. Rule Reference: crypto Otherwise, Alternate(22) will be taken IF: The lookahead set: { WORD } is matched. Rule Reference: unknown_command Otherwise, Alternate(23) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {EOF } *** End Parser Rule: cfgfile *** Parser Rule: comment Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { LINE_COMMENT, COLON_COMMENT } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { LINE_COMMENT, COLON_COMMENT } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { LINE_COMMENT, COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { LINE_COMMENT } is matched. Match token LINE_COMMENT Otherwise, Alternate(2) will be taken IF: The lookahead set: { COLON_COMMENT } is matched. Match token COLON_COMMENT OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: comment *** Parser Rule: version Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "PIX", "ASA" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "PIX", "ASA" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "PIX", "ASA" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "PIX" } is matched. Match token PIX_WORD Otherwise, Alternate(2) will be taken IF: The lookahead set: { "ASA" } is matched. Match token ASA_WORD OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Match token VERSION_WORD Match token NUMBER ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->setDiscoveredVersion(LT(0)->getText()); *dbg << "VERSION " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: version *** Parser Rule: hostname Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "hostname" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "hostname" } is matched. Match token HOSTNAME Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, STRING } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { STRING } is matched. Match token STRING Otherwise, Alternate(2) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->setHostName( LT(0)->getText() ); *dbg << "HOSTNAME " << "LT0=" << LT(0)->getText() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: hostname *** Parser Rule: ip_access_list_ext Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip" } is matched. Match token IP Match token ACCESS_LIST Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet( name->getText(), libfwbuilder::Policy::TYPENAME ); *dbg << name->getLine() << ":" << " ACL ext " << name->getText() << std::endl; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "permit", "deny", LINE_COMMENT, "remark", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "permit" } is matched. Rule Reference: permit_ext Otherwise, Alternate(2) will be taken IF: The lookahead set: { "deny" } is matched. Rule Reference: deny_ext Otherwise, Alternate(3) will be taken IF: The lookahead set: { LINE_COMMENT, COLON_COMMENT } is matched. Rule Reference: comment Otherwise, Alternate(4) will be taken IF: The lookahead set: { "remark" } is matched. Rule Reference: remark Otherwise, Alternate(5) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: *dbg << LT(0)->getLine() << ":" << " ACL line end" << std::endl << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: ip_access_list_ext *** Parser Rule: community_list_command Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip" } is matched. Match token IP Match token COMMUNITY_LIST ACTION: consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: community_list_command *** Parser Rule: unknown_ip_command Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip" } is matched. Match token IP Match token WORD ACTION: consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: unknown_ip_command *** Parser Rule: intrface Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "interface" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "interface" } is matched. Match token INTRFACE Match token WORD, label=in ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; consumeUntil(NEWLINE); Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "description" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: interface_description Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: { "ip", "igmp", "ospf", "pim", "description", "vlan", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip", "no", "security-level", "nameif", "shutdown", "switchport" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: { "ip", "igmp", "ospf", "pim", "description", "vlan", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip", "no", "security-level", "nameif", "shutdown", "switchport" } is matched. Rule Reference: interface_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. Match token NEWLINE Match token LINE_COMMENT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: intrface *** Parser Rule: controller Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "controller" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "controller" } is matched. Match token CONTROLLER ACTION: importer->clearCurrentInterface(); consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: controller *** Parser Rule: access_list_commands Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "access-list" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "access-list" } is matched. Match token ACCESS_LIST Match token INT_CONST, label=acl_num ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newUnidirRuleSet( std::string("acl_") + acl_num->getText(), libfwbuilder::Policy::TYPENAME ); *dbg << acl_num->getLine() << ":" << " ACL #" << acl_num->getText() << " "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "permit", "deny", "remark" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "permit" } is matched. Rule Reference: permit_ext Otherwise, Alternate(2) will be taken IF: The lookahead set: { "deny" } is matched. Rule Reference: deny_ext Otherwise, Alternate(3) will be taken IF: The lookahead set: { "remark" } is matched. Rule Reference: remark OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: access_list_commands *** Parser Rule: exit Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "exit" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "exit" } is matched. Match token EXIT OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: exit *** Parser Rule: certificate Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "certificate" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "certificate" } is matched. Match token CERTIFICATE Match token WORD ACTION: consumeUntil(NEWLINE); consumeUntil(QUIT); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: certificate *** Parser Rule: quit Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "quit" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "quit" } is matched. Match token QUIT ACTION: consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: quit *** Parser Rule: names_section Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "names" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "names" } is matched. Match token NAMES ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( "Parser warning: \"names\" section detected. " "Import of configuration that uses \"names\" " "is not supported at this time"); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: names_section *** Parser Rule: name_entry Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "name", INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "name" } is matched. Match token NAME Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=a Match token WORD, label=n OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { INT_CONST } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=v6 OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: if (a) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog( "Name " + a->getText() + " " + n->getText()); *dbg << "Name " << a->getText() << " " << n->getText() << std::endl; } if (v6) { importer->addMessageToLog( "Parser warning: IPv6 import is not supported. "); consumeUntil(NEWLINE); } OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: name_entry *** Parser Rule: named_object_network Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "object" } is matched. Match token OBJECT Match token NETWORK Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNamedObjectAddress(name->getText()); *dbg << name->getLine() << ":" << " Named Object " << name->getText() << std::endl; Start ZERO-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: {"nat", "description", "host", "range", "subnet" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: {"nat", "description", "host", "range", "subnet" } is matched. Match token NEWLINE Rule Reference: named_object_network_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ZERO-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: named_object_network *** Parser Rule: named_object_service Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "object" } is matched. Match token OBJECT Match token SERVICE Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newNamedObjectService(name->getText()); *dbg << name->getLine() << ":" << " Named Object " << name->getText() << std::endl; Start ZERO-OR-MORE (...)+ block: Warning: This zero-or-more block is non-deterministic Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: {"description", "service" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: {"description", "service" } is matched. Match token NEWLINE Rule Reference: named_object_service_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ZERO-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: named_object_service *** Parser Rule: object_group_network Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "object-group" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "object-group" } is matched. Match token OBJECT_GROUP Match token NETWORK Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupNetwork(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: {"description", "group-object", "network-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: {"description", "group-object", "network-object" } is matched. Rule Reference: object_group_network_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_network *** Parser Rule: object_group_service Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "object-group" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "object-group" } is matched. Match token OBJECT_GROUP Match token SERVICE Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupService(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: {"description", "group-object", "service-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: {"description", "group-object", "service-object" } is matched. Rule Reference: object_group_service_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_service *** Parser Rule: object_group_protocol Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "object-group" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "object-group" } is matched. Match token OBJECT_GROUP Match token PROTOCOL Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupProtocol(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: {"description", "group-object", "protocol-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: {"description", "group-object", "protocol-object" } is matched. Rule Reference: object_group_protocol_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_protocol *** Parser Rule: object_group_icmp Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "object-group" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "object-group" } is matched. Match token OBJECT_GROUP Match token ICMP_TYPE Match token WORD, label=name ACTION: importer->clear(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->newObjectGroupICMP(name->getText()); *dbg << name->getLine() << ":" << " Object Group " << name->getText() << std::endl; Start ONE-OR-MORE (...)+ block: Start of an alternative block. The lookahead set for this block is: k==1: {NEWLINE } k==2: {"description", "group-object", "icmp-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: k==1: {NEWLINE } k==2: {"description", "group-object", "icmp-object" } is matched. Rule Reference: object_group_icmp_parameters OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. End ONE-OR-MORE block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_icmp *** Parser Rule: crypto Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "crypto" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "crypto" } is matched. Match token CRYPTO ACTION: consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: crypto *** Parser Rule: unknown_command Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { WORD } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD ACTION: consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: unknown_command *** Parser Rule: ip_protocol_names Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "ah" } is matched. Match token AH Otherwise, Alternate(2) will be taken IF: The lookahead set: { "eigrp" } is matched. Match token EIGRP Otherwise, Alternate(3) will be taken IF: The lookahead set: { "esp" } is matched. Match token ESP Otherwise, Alternate(4) will be taken IF: The lookahead set: { "gre" } is matched. Match token GRE Otherwise, Alternate(5) will be taken IF: The lookahead set: { "igmp" } is matched. Match token IGMP Otherwise, Alternate(6) will be taken IF: The lookahead set: { "igrp" } is matched. Match token IGRP Otherwise, Alternate(7) will be taken IF: The lookahead set: { "ip" } is matched. Match token IP Otherwise, Alternate(8) will be taken IF: The lookahead set: { "ipinip" } is matched. Match token IPINIP Otherwise, Alternate(9) will be taken IF: The lookahead set: { IPSEC } is matched. Match token IPSEC Otherwise, Alternate(10) will be taken IF: The lookahead set: { "nos" } is matched. Match token NOS Otherwise, Alternate(11) will be taken IF: The lookahead set: { "ospf" } is matched. Match token OSPF Otherwise, Alternate(12) will be taken IF: The lookahead set: { "pcp" } is matched. Match token PCP Otherwise, Alternate(13) will be taken IF: The lookahead set: { "pim" } is matched. Match token PIM Otherwise, Alternate(14) will be taken IF: The lookahead set: { PPTP } is matched. Match token PPTP Otherwise, Alternate(15) will be taken IF: The lookahead set: { SNP } is matched. Match token SNP OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", IPV4, WORD, INT_CONST, "object", "host", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "any", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: ip_protocol_names *** Parser Rule: named_object_network_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "nat", "description", "host", "range", "subnet" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "nat", "description", "host", "range", "subnet" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "nat", "description", "host", "range", "subnet" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "nat" } is matched. Rule Reference: named_object_nat Otherwise, Alternate(2) will be taken IF: The lookahead set: { "host" } is matched. Rule Reference: host_addr Otherwise, Alternate(3) will be taken IF: The lookahead set: { "range" } is matched. Rule Reference: range_addr Otherwise, Alternate(4) will be taken IF: The lookahead set: { "subnet" } is matched. Rule Reference: subnet_addr Otherwise, Alternate(5) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: named_object_description OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: named_object_network_parameters *** Parser Rule: named_object_nat Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "nat" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "nat" } is matched. Match token NAT ACTION: importer->addMessageToLog( "Parser warning: " "Import of named objects with \"nat\" command " "is not supported at this time"); consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: named_object_nat *** Parser Rule: host_addr Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "host" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "host" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "host" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "host" } is matched. Match token HOST Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=h Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=v6 OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); if (h) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; importer->commitNamedAddressObject(); *dbg << h->getText() << "/255.255.255.255"; } if (v6) { importer->addMessageToLog( "Parser warning: IPv6 import is not supported. "); consumeUntil(NEWLINE); } OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: host_addr *** Parser Rule: range_addr Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "range" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "range" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "range" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "range" } is matched. Match token RANGE Match token IPV4, label=r1 Match token IPV4, label=r2 OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->tmp_range_1 = r1->getText(); importer->tmp_range_2 = r2->getText(); importer->commitNamedAddressRangeObject(); *dbg << r1->getText() << "/" << r2->getText(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: range_addr *** Parser Rule: subnet_addr Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "subnet" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "subnet" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "subnet" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "subnet" } is matched. Match token SUBNET Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=a Match token IPV4, label=nm OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=v6 OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); if (a) { importer->tmp_a = a->getText(); importer->tmp_nm = nm->getText(); importer->commitNamedAddressObject(); *dbg << a->getText() << "/" << nm->getText(); } if (v6) { importer->addMessageToLog( "Parser warning: IPv6 import is not supported. "); consumeUntil(NEWLINE); } OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: subnet_addr *** Parser Rule: named_object_description Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "description" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Match token DESCRIPTION ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setNamedObjectDescription(descr); *dbg << " DESCRIPTION " << descr << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: named_object_description *** Parser Rule: named_object_service_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "description", "service" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "description", "service" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: k==1: {"description", "service" } k==2: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP, "object", "icmp", ICMP6, "tcp", "udp", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: {"service" } k==2: {"icmp" } is matched. Rule Reference: service_icmp Otherwise, Alternate(2) will be taken IF: The lookahead set: k==1: {"service" } k==2: {ICMP6 } is matched. Rule Reference: service_icmp6 Otherwise, Alternate(3) will be taken IF: The lookahead set: k==1: {"service" } k==2: {"tcp", "udp" } is matched. Rule Reference: service_tcp_udp Otherwise, Alternate(4) will be taken IF: The lookahead set: k==1: {"service" } k==2: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Rule Reference: service_other Otherwise, Alternate(5) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: named_object_description OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: named_object_service_parameters *** Parser Rule: service_icmp Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "service" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "service" } is matched. Match token SERVICE Match token ICMP Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=icmp_type ACTION: importer->icmp_type = LT(0)->getText(); Otherwise, Alternate(2) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=icmp_word ACTION: importer->icmp_spec = icmp_word->getText(); OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->commitNamedICMPServiceObject(); *dbg << "NAMED OBJECT SERVICE ICMP " << LT(0)->getText() << " "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: service_icmp *** Parser Rule: service_icmp6 Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "service" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "service" } is matched. Match token SERVICE Match token ICMP6 Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST Otherwise, Alternate(2) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->addMessageToLog("Parser warning: " "Import of IPv6 addresses and servcies " "is not supported at this time"); *dbg << "NAMED OBJECT SERVICE ICMP6 " << LT(0)->getText() << " "; consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: service_icmp6 *** Parser Rule: service_tcp_udp Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "service" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "service" } is matched. Match token SERVICE Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "tcp", "udp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "tcp" } is matched. Match token TCP Otherwise, Alternate(2) will be taken IF: The lookahead set: { "udp" } is matched. Match token UDP OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->protocol = LT(0)->getText(); *dbg << "NAMED OBJECT SERVICE " << LT(0)->getText() << " "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "source", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "source" } is matched. Rule Reference: src_port_spec Otherwise, Alternate(2) will be taken IF: The lookahead set: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "destination" } is matched. Rule Reference: dst_port_spec Otherwise, Alternate(2) will be taken IF: The lookahead set: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->commitNamedTCPUDPServiceObject(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: service_tcp_udp *** Parser Rule: service_other Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "service" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "service" } is matched. Match token SERVICE Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST Otherwise, Alternate(2) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Rule Reference: ip_protocol_names OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->commitNamedIPServiceObject(); *dbg << "NAMED OBJECT SERVICE " << LT(0)->getText() << " "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: service_other *** Parser Rule: src_port_spec Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "source" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "source" } is matched. Match token SOURCE Rule Reference: xoperator ACTION: importer->SaveTmpPortToSrc(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: src_port_spec *** Parser Rule: dst_port_spec Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "destination" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "destination" } is matched. Match token DESTINATION Rule Reference: xoperator ACTION: importer->SaveTmpPortToDst(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: dst_port_spec *** Parser Rule: xoperator Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "range", "eq", "gt", "lt", "neq" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "eq", "gt", "lt", "neq" } is matched. Rule Reference: single_port_op Otherwise, Alternate(2) will be taken IF: The lookahead set: { "range" } is matched. Rule Reference: port_range OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", IPV4, WORD, INT_CONST, "object", "host", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "any", "log", "log-input", "established", "fragments", "time-range", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: xoperator *** Parser Rule: object_group_network_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { NEWLINE } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "description", "group-object", "network-object" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: object_group_description Otherwise, Alternate(2) will be taken IF: The lookahead set: { "group-object" } is matched. Rule Reference: group_object Otherwise, Alternate(3) will be taken IF: The lookahead set: { "network-object" } is matched. Rule Reference: network_object OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_network_parameters *** Parser Rule: object_group_description Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "description" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Match token DESCRIPTION ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setObjectGroupDescription(descr); *dbg << " DESCRIPTION " << descr << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_description *** Parser Rule: group_object Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "group-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "group-object" } is matched. Match token GROUP_OBJECT Match token WORD, label=name ACTION: importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: group_object *** Parser Rule: network_object Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "network-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "network-object" } is matched. Match token NETWORK_OBJECT ACTION: importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, INT_CONST, "object", "host" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { IPV4, INT_CONST } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=a Match token IPV4, label=nm OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=v6 OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: if (a) { importer->tmp_a = a->getText(); importer->tmp_nm = nm->getText(); importer->addNetworkToObjectGroup(); *dbg << a->getText() << "/" << nm->getText(); } if (v6) { importer->addMessageToLog( "Parser warning: IPv6 import is not supported. "); consumeUntil(NEWLINE); } Otherwise, Alternate(2) will be taken IF: The lookahead set: { "host" } is matched. Match token HOST Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=h Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=hv6 OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: if (h) { importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; importer->addNetworkToObjectGroup(); *dbg << h->getText() << "/255.255.255.255"; } if (hv6) { importer->addMessageToLog( "Parser warning: IPv6 import is not supported. "); consumeUntil(NEWLINE); } Otherwise, Alternate(3) will be taken IF: The lookahead set: { "object" } is matched. Match token OBJECT Match token WORD, label=name ACTION: importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: network_object *** Parser Rule: object_group_protocol_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { NEWLINE } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "description", "group-object", "protocol-object" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: object_group_description Otherwise, Alternate(2) will be taken IF: The lookahead set: { "group-object" } is matched. Rule Reference: group_object Otherwise, Alternate(3) will be taken IF: The lookahead set: { "protocol-object" } is matched. Rule Reference: protocol_object OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_protocol_parameters *** Parser Rule: protocol_object Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "protocol-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "protocol-object" } is matched. Match token PROTOCOL_OBJECT ACTION: importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP, "object" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST Otherwise, Alternate(2) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Rule Reference: ip_protocol_names OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->addIPServiceToObjectGroup(); *dbg << " GROUP MEMBER " << LT(0)->getText() << " "; Otherwise, Alternate(2) will be taken IF: The lookahead set: { "object" } is matched. Match token OBJECT Match token WORD, label=name ACTION: importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: protocol_object *** Parser Rule: object_group_icmp_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { NEWLINE } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "description", "group-object", "icmp-object" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: object_group_description Otherwise, Alternate(2) will be taken IF: The lookahead set: { "group-object" } is matched. Rule Reference: group_object Otherwise, Alternate(3) will be taken IF: The lookahead set: { "icmp-object" } is matched. Rule Reference: icmp_object OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_icmp_parameters *** Parser Rule: icmp_object Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "icmp-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "icmp-object" } is matched. Match token ICMP_OBJECT ACTION: importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST, "object" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD, INT_CONST } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=icmp_type ACTION: importer->icmp_type = LT(0)->getText(); Otherwise, Alternate(2) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=icmp_word ACTION: importer->icmp_spec = icmp_word->getText(); OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->addICMPServiceToObjectGroup(); *dbg << " SERVICE ICMP " << LT(0)->getText() << " "; Otherwise, Alternate(2) will be taken IF: The lookahead set: { "object" } is matched. Match token OBJECT Match token WORD, label=name ACTION: importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: icmp_object *** Parser Rule: object_group_service_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { NEWLINE } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "description", "group-object", "service-object" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: object_group_description Otherwise, Alternate(2) will be taken IF: The lookahead set: { "group-object" } is matched. Rule Reference: group_object Otherwise, Alternate(3) will be taken IF: The lookahead set: { "service-object" } is matched. Rule Reference: service_object OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: object_group_service_parameters *** Parser Rule: service_object Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "service-object" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "service-object" } is matched. Match token SERVICE_OBJECT ACTION: importer->clearTempVars(); importer->setCurrentLineNumber(LT(0)->getLine()); Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP, "object", "icmp", "tcp", "udp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", INT_CONST, "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST Otherwise, Alternate(2) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Rule Reference: ip_protocol_names OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->protocol = LT(0)->getText(); importer->addIPServiceToObjectGroup(); *dbg << " GROUP MEMBER " << LT(0)->getText() << " "; Otherwise, Alternate(2) will be taken IF: The lookahead set: { "tcp", "udp" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "tcp", "udp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "tcp" } is matched. Match token TCP Otherwise, Alternate(2) will be taken IF: The lookahead set: { "udp" } is matched. Match token UDP OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->protocol = LT(0)->getText(); *dbg << " SERVICE TCP/UDP" << LT(0)->getText() << " "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "source", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "source" } is matched. Rule Reference: src_port_spec Otherwise, Alternate(2) will be taken IF: The lookahead set: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "destination" } is matched. Rule Reference: dst_port_spec Otherwise, Alternate(2) will be taken IF: The lookahead set: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->addTCPUDPServiceToObjectGroup(); Otherwise, Alternate(3) will be taken IF: The lookahead set: { "icmp" } is matched. Match token ICMP Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=icmp_type ACTION: importer->icmp_type = LT(0)->getText(); Otherwise, Alternate(2) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=icmp_word ACTION: importer->icmp_spec = icmp_word->getText(); OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->addICMPServiceToObjectGroup(); *dbg << " SERVICE ICMP " << LT(0)->getText() << " "; Otherwise, Alternate(4) will be taken IF: The lookahead set: { "object" } is matched. Match token OBJECT Match token WORD, label=name ACTION: importer->addNamedObjectToObjectGroup(name->getText()); *dbg << " GROUP MEMBER " << name->getLine() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: service_object *** Parser Rule: permit_ext Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "permit" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "permit" } is matched. Match token PERMIT ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; Rule Reference: rule_ext Match token NEWLINE ACTION: importer->pushRule(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: permit_ext *** Parser Rule: deny_ext Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "deny" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "deny" } is matched. Match token DENY ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; Rule Reference: rule_ext Match token NEWLINE ACTION: importer->pushRule(); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: deny_ext *** Parser Rule: remark Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "remark" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "remark" } is matched. Match token REMARK ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string rem; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { rem += LT(1)->getText() + " "; consume(); } importer->addRuleComment( rem ); *dbg << " REMARK " << rem << std::endl; //consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", WORD, INT_CONST, "object", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: remark *** Parser Rule: rule_ext Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP, "icmp", "tcp", "udp" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP, "icmp", "tcp", "udp" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP, "icmp", "tcp", "udp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Rule Reference: ip_protocols Rule Reference: hostaddr_ext ACTION: importer->SaveTmpAddrToSrc(); *dbg << "(src) "; Rule Reference: hostaddr_ext ACTION: importer->SaveTmpAddrToDst(); *dbg << "(dst) "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "fragments", "time-range" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "time-range" } is matched. Rule Reference: time_range Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input", "fragments" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "fragments" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "fragments" } is matched. Rule Reference: fragments Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "log", "log-input" } is matched. Rule Reference: log Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Otherwise, Alternate(2) will be taken IF: The lookahead set: { "icmp" } is matched. Match token ICMP ACTION: importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; Rule Reference: hostaddr_ext ACTION: importer->SaveTmpAddrToSrc(); *dbg << "(src) "; Rule Reference: hostaddr_ext ACTION: importer->SaveTmpAddrToDst(); *dbg << "(dst) "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, WORD, INT_CONST, "log", "log-input", "fragments", "time-range" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD, INT_CONST } is matched. Rule Reference: icmp_spec Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input", "fragments", "time-range" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "fragments", "time-range" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "time-range" } is matched. Rule Reference: time_range Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input", "fragments" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "fragments" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "fragments" } is matched. Rule Reference: fragments Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "log", "log-input" } is matched. Rule Reference: log Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Otherwise, Alternate(3) will be taken IF: The lookahead set: { "tcp", "udp" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "tcp", "udp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "tcp" } is matched. Match token TCP Otherwise, Alternate(2) will be taken IF: The lookahead set: { "udp" } is matched. Match token UDP OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; Rule Reference: hostaddr_ext ACTION: importer->SaveTmpAddrToSrc(); *dbg << "(src) "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, "host", "range", "eq", "gt", "lt", "neq", "any" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "range", "eq", "gt", "lt", "neq" } is matched. Rule Reference: xoperator ACTION: importer->SaveTmpPortToSrc(); Otherwise, Alternate(2) will be taken IF: The lookahead set: { IPV4, "host", "any" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Rule Reference: hostaddr_ext ACTION: importer->SaveTmpAddrToDst(); *dbg << "(dst) "; Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "range", "eq", "gt", "lt", "neq", "log", "log-input", "established", "fragments", "time-range" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "range", "eq", "gt", "lt", "neq" } is matched. Rule Reference: xoperator ACTION: importer->SaveTmpPortToDst(); Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input", "established", "fragments", "time-range" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "established", "fragments", "time-range" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "established" } is matched. Rule Reference: established Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input", "fragments", "time-range" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "fragments", "time-range" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "time-range" } is matched. Rule Reference: time_range Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input", "fragments" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input", "fragments" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "fragments" } is matched. Rule Reference: fragments Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE, "log", "log-input" } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "log", "log-input" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "log", "log-input" } is matched. Rule Reference: log Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: *dbg << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: rule_ext *** Parser Rule: ip_protocols Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip", "ah", "eigrp", "esp", "gre", "igmp", "igrp", "ipinip", IPSEC, "nos", "ospf", "pcp", "pim", PPTP, SNP } is matched. Rule Reference: ip_protocol_names ACTION: importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {IPV4, "host", "any" } *** End Parser Rule: ip_protocols *** Parser Rule: hostaddr_ext Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { IPV4, "host", "any" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "host" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "host" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "host" } is matched. Match token HOST Match token IPV4, label=h OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->tmp_a = h->getText(); importer->tmp_nm = "255.255.255.255"; *dbg << h->getText() << "/255.255.255.255"; Otherwise, Alternate(2) will be taken IF: The lookahead set: { IPV4 } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=a Match token IPV4, label=m OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); Otherwise, Alternate(3) will be taken IF: The lookahead set: { "any" } is matched. Match token ANY ACTION: importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { NEWLINE, IPV4, WORD, INT_CONST, "host", "range", "eq", "gt", "lt", "neq", "any", "log", "log-input", "established", "fragments", "time-range" } *** End Parser Rule: hostaddr_ext *** Parser Rule: time_range Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "time-range" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "time-range" } is matched. Match token TIME_RANGE Match token WORD, label=tr_name ACTION: importer->time_range_name = tr_name->getText(); *dbg << "time_range " << tr_name->getText() << " "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE, "log", "log-input", "fragments" } *** End Parser Rule: time_range *** Parser Rule: fragments Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "fragments" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "fragments" } is matched. Match token FRAGMENTS ACTION: importer->fragments = true; *dbg << "fragments "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE, "log", "log-input" } *** End Parser Rule: fragments *** Parser Rule: log Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "log", "log-input" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "log", "log-input" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "log", "log-input" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "log" } is matched. Match token LOG Otherwise, Alternate(2) will be taken IF: The lookahead set: { "log-input" } is matched. Match token LOG_INPUT OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->logging = true; *dbg << "logging "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: log *** Parser Rule: icmp_spec Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD, INT_CONST } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched, AND the syntactic predicate: Start of alternative block. Start of an alternative block. The lookahead set for this block is: { INT_CONST } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { INT_CONST } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=icmp_type Match token INT_CONST, label=icmp_code OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->icmp_type = icmp_type->getText(); importer->icmp_code = icmp_code->getText(); importer->icmp_spec = ""; *dbg << icmp_type->getText() << " " << icmp_code->getText() << " "; Otherwise, Alternate(2) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=icmp_word ACTION: importer->icmp_spec = icmp_word->getText(); *dbg << icmp_word->getText() << " "; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE, "log", "log-input", "fragments", "time-range" } *** End Parser Rule: icmp_spec *** Parser Rule: established Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "established" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "established" } is matched. Match token ESTABLISHED ACTION: importer->established = true; *dbg << "established "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE, "log", "log-input", "fragments", "time-range" } *** End Parser Rule: established *** Parser Rule: single_port_op Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "eq", "gt", "lt", "neq" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "eq", "gt", "lt", "neq" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "eq", "gt", "lt", "neq" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "eq" } is matched. Match token P_EQ Otherwise, Alternate(2) will be taken IF: The lookahead set: { "gt" } is matched. Match token P_GT Otherwise, Alternate(3) will be taken IF: The lookahead set: { "lt" } is matched. Match token P_LT Otherwise, Alternate(4) will be taken IF: The lookahead set: { "neq" } is matched. Match token P_NEQ OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; Rule Reference: port_spec OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", IPV4, WORD, INT_CONST, "object", "host", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "any", "log", "log-input", "established", "fragments", "time-range", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: single_port_op *** Parser Rule: port_range Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "range" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "range" } is matched. Match token RANGE Rule Reference: pair_of_ports_spec ACTION: importer->tmp_port_op = "range"; *dbg << "range "; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", IPV4, WORD, INT_CONST, "object", "host", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "any", "log", "log-input", "established", "fragments", "time-range", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: port_range *** Parser Rule: port_spec Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD, INT_CONST } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->tmp_port_spec = (std::string(" ") + LT(0)->getText()); *dbg << LT(0)->getText() << " " << importer->tmp_port_spec; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", IPV4, WORD, INT_CONST, "object", "host", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "any", "log", "log-input", "established", "fragments", "time-range", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: port_spec *** Parser Rule: pair_of_ports_spec Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD, INT_CONST } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=s1 Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=s2 OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD, INT_CONST } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=e1 Otherwise, Alternate(2) will be taken IF: The lookahead set: { INT_CONST } is matched. Match token INT_CONST, label=e2 OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: importer->tmp_port_spec = ""; if (s1) importer->tmp_port_spec += s1->getText(); if (s2) importer->tmp_port_spec += s2->getText(); importer->tmp_port_spec += " "; if (e1) importer->tmp_port_spec += e1->getText(); if (e2) importer->tmp_port_spec += e2->getText(); *dbg << "pair of ports: " << importer->tmp_port_spec; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: { EOF, NEWLINE, "quit", "ip", "names", "name", IPV4, WORD, INT_CONST, "object", "host", "destination", "object-group", "crypto", "certificate", "PIX", "ASA", "hostname", "access-list", "any", "log", "log-input", "established", "fragments", "time-range", "controller", "interface", LINE_COMMENT, "exit", COLON_COMMENT } *** End Parser Rule: pair_of_ports_spec *** Parser Rule: hostaddr_std Access: public Return value: none Start of an alternative block. The lookahead set for this block is: k==1: {IPV4, "any" } k==2: {EOF, IPV4 } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: {IPV4 } k==2: {EOF } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=h OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->tmp_a = h->getText(); importer->tmp_nm = "0.0.0.0"; *dbg << h->getText() << "/0.0.0.0"; Otherwise, Alternate(2) will be taken IF: The lookahead set: k==1: {IPV4 } k==2: {IPV4 } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=a Match token IPV4, label=m OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. ACTION: importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); Otherwise, Alternate(3) will be taken IF: The lookahead set: { "any" } is matched. Match token ANY ACTION: importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {EOF } *** End Parser Rule: hostaddr_std *** Parser Rule: interface_description Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "description" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "description" } is matched. Match token DESCRIPTION ACTION: *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setInterfaceComment( descr ); *dbg << " DESCRIPTION " << descr << std::endl; //consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: interface_description *** Parser Rule: interface_parameters Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { NEWLINE } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE } is matched. Match token NEWLINE ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "ip", "igmp", "ospf", "pim", "description", "vlan", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip", "no", "security-level", "nameif", "shutdown", "switchport" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "ip" } is matched. Rule Reference: intf_address Otherwise, Alternate(2) will be taken IF: The lookahead set: { "vlan" } is matched. Rule Reference: vlan_interface Otherwise, Alternate(3) will be taken IF: The lookahead set: { "security-level" } is matched. Rule Reference: sec_level Otherwise, Alternate(4) will be taken IF: The lookahead set: { "nameif" } is matched. Rule Reference: nameif Otherwise, Alternate(5) will be taken IF: The lookahead set: { "description" } is matched. Rule Reference: interface_description Otherwise, Alternate(6) will be taken IF: The lookahead set: { "switchport" } is matched. Rule Reference: switchport Otherwise, Alternate(7) will be taken IF: The lookahead set: { "shutdown" } is matched. Rule Reference: shutdown Otherwise, Alternate(8) will be taken IF: The lookahead set: { "no" } is matched. Rule Reference: interface_no_commands Otherwise, Alternate(9) will be taken IF: The lookahead set: { "igmp", "ospf", "pim", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip" } is matched. Rule Reference: unsupported_interface_commands OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: interface_parameters *** Parser Rule: intf_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "ip" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "ip" } is matched. Match token IP Match token ADDRESS Start of alternative block. Start of an alternative block. The lookahead set for this block is: { IPV4, WORD, "dhcp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Rule Reference: v6_ip_address Otherwise, Alternate(2) will be taken IF: The lookahead set: { IPV4, "dhcp" } is matched. Rule Reference: v7_ip_address OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: intf_address *** Parser Rule: vlan_interface Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "vlan" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "vlan" } is matched. Match token VLAN Match token INT_CONST, label=vlan_id ACTION: importer->setInterfaceVlanId(vlan_id->getText()); *dbg << " VLAN: " << vlan_id->getText() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: vlan_interface *** Parser Rule: sec_level Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "security-level" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "security-level" } is matched. Match token SEC_LEVEL Match token INT_CONST, label=sec_level ACTION: importer->setInterfaceSecurityLevel(sec_level->getText()); *dbg << "SEC_LEVEL: " << sec_level->getText() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: sec_level *** Parser Rule: nameif Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "nameif" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "nameif" } is matched. Match token NAMEIF Match token WORD, label=p_intf Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, WORD } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { WORD } is matched, AND the syntactic predicate: Start of alternative block. Start of an alternative block. The lookahead set for this block is: { WORD } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. is matched. Match token WORD, label=intf_label Match token WORD, label=sec_level Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { NEWLINE } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: std::string label = (intf_label) ? intf_label->getText() : ""; std::string seclevel = (sec_level) ? sec_level->getText() : ""; importer->setInterfaceParametes(p_intf->getText(), label, seclevel); *dbg << " NAMEIF: " << p_intf->getText() << label << seclevel << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: nameif *** Parser Rule: switchport Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "switchport" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "switchport" } is matched. Match token SWITCHPORT Match token ACCESS Match token VLAN Match token INT_CONST, label=vlan_num ACTION: importer->addMessageToLog("Switch port vlan " + vlan_num->getText()); *dbg << "Switch port vlan " << vlan_num->getText() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: switchport *** Parser Rule: shutdown Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "shutdown" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "shutdown" } is matched. Match token SHUTDOWN ACTION: importer->ignoreCurrentInterface(); *dbg<< LT(1)->getLine() << ":" << " INTERFACE SHUTDOWN " << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: shutdown *** Parser Rule: interface_no_commands Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "no" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "no" } is matched. Match token NO Match token WORD ACTION: *dbg << " INTERFACE \"NO\" COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: interface_no_commands *** Parser Rule: unsupported_interface_commands Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "igmp", "ospf", "pim", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "igmp", "ospf", "pim", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip" } is matched. Start of alternative block. Start of an alternative block. The lookahead set for this block is: { "igmp", "ospf", "pim", "speed", "duplex", "ddns", "forward", "delay", "hold-time", "ipv6", "mac-address", "multicast", PPPOE, "rip" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "speed" } is matched. Match token SPEED Otherwise, Alternate(2) will be taken IF: The lookahead set: { "duplex" } is matched. Match token DUPLEX Otherwise, Alternate(3) will be taken IF: The lookahead set: { "ddns" } is matched. Match token DDNS Otherwise, Alternate(4) will be taken IF: The lookahead set: { "forward" } is matched. Match token FORWARD Otherwise, Alternate(5) will be taken IF: The lookahead set: { "delay" } is matched. Match token DELAY Otherwise, Alternate(6) will be taken IF: The lookahead set: { "hold-time" } is matched. Match token HOLD_TIME Otherwise, Alternate(7) will be taken IF: The lookahead set: { "igmp" } is matched. Match token IGMP Otherwise, Alternate(8) will be taken IF: The lookahead set: { "ipv6" } is matched. Match token IPV6 Otherwise, Alternate(9) will be taken IF: The lookahead set: { "mac-address" } is matched. Match token MAC_ADDRESS Otherwise, Alternate(10) will be taken IF: The lookahead set: { "multicast" } is matched. Match token MULTICAST Otherwise, Alternate(11) will be taken IF: The lookahead set: { "ospf" } is matched. Match token OSPF Otherwise, Alternate(12) will be taken IF: The lookahead set: { "pim" } is matched. Match token PIM Otherwise, Alternate(13) will be taken IF: The lookahead set: { PPPOE } is matched. Match token PPPOE Otherwise, Alternate(14) will be taken IF: The lookahead set: { "rip" } is matched. Match token RIP OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: *dbg << " UNSUPPORTED INTERFACE COMMAND: " << LT(0)->getText() << std::endl; consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: unsupported_interface_commands *** Parser Rule: v6_ip_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: k==1: {WORD } k==2: {IPV4, "dhcp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: k==1: {WORD } k==2: {"dhcp" } is matched. Rule Reference: v6_dhcp_address Otherwise, Alternate(2) will be taken IF: The lookahead set: k==1: {WORD } k==2: {IPV4 } is matched. Rule Reference: v6_static_address OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: v6_ip_address *** Parser Rule: v7_ip_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { IPV4, "dhcp" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "dhcp" } is matched. Rule Reference: v7_dhcp_address Otherwise, Alternate(2) will be taken IF: The lookahead set: { IPV4 } is matched. Rule Reference: v7_static_address OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: v7_ip_address *** Parser Rule: v6_dhcp_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { WORD } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=lbl Match token DHCP, label=dhcp ACTION: std::string label = lbl->getText(); std::string addr = dhcp->getText(); importer->addInterfaceAddress(label, addr, ""); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << std::endl; // there can be some other parameters after "dhcp", such as "setroute", "retry" etc. // which we do not support consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: v6_dhcp_address *** Parser Rule: v6_static_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { WORD } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { WORD } is matched. Match token WORD, label=lbl Match token IPV4, label=a Match token IPV4, label=m ACTION: std::string label = lbl->getText(); std::string addr = a->getText(); std::string netm = m->getText(); importer->addInterfaceAddress(label, addr, netm); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << "/" << netm << std::endl; // in case there are some other parameters after address and netmask consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: v6_static_address *** Parser Rule: v7_dhcp_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "dhcp" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "dhcp" } is matched. Match token DHCP, label=dhcp ACTION: std::string addr = dhcp->getText(); importer->addInterfaceAddress(addr, ""); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << std::endl; consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: v7_dhcp_address *** Parser Rule: v7_static_address Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { IPV4 } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { IPV4 } is matched. Match token IPV4, label=a Match token IPV4, label=m Start of alternative block. Start of an alternative block. The lookahead set for this block is: { NEWLINE, "standby" } This block has multiple alternatives: Alternate(1) will be taken IF: The lookahead set: { "standby" } is matched. Match token STANDBY, label=s Otherwise, Alternate(2) will be taken IF: The lookahead set: { NEWLINE } is matched. OTHERWISE, a NoViableAlt exception will be thrown End of alternatives End of alternative block. ACTION: std::string addr = a->getText(); std::string netm = m->getText(); importer->addInterfaceAddress(addr, netm); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << addr << "/" << netm << std::endl; // there can be other parameters after address/netmask pair, such as "standby" // We do not parse them yet. if (s) { importer->addMessageToLog("Parser warning: failover IP detected. " "Failover is not supported by import " "at this time"); } consumeUntil(NEWLINE); OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {NEWLINE } *** End Parser Rule: v7_static_address *** Parser Rule: access_group_by_name Access: public Return value: none Start of an alternative block. The lookahead set for this block is: { "access-group" } This block has a single alternative Alternate(1) will be taken IF: The lookahead set: { "access-group" } is matched. Match token ACCESS_GROUP Match token WORD, label=acln Match token WORD, label=dir Match token INTRFACE Match token WORD, label=intf_label ACTION: importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( acln->getText(), intf_label->getText(), dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << acln->getText() << "'" << " " << intf_label->getText() << " " << dir->getText() << std::endl; OTHERWISE, a NoViableAlt exception will be thrown End of alternative block. Default error-handling will be generated, which catches all parser exceptions and consumes tokens until the follow-set is seen. The follow set for this rule is: k==1: {EOF } *** End Parser Rule: access_group_by_name *** End of parser rules *** End of parser fwbuilder-5.1.0.3599/src/parsers/iosacl.g0000644000175000017500000005140211733011756020670 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ header "pre_include_hpp" { // gets inserted before antlr generated includes in the header // file #include "IOSImporter.h" } header "post_include_hpp" { // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class IOSImporter; } header "pre_include_cpp" { // gets inserted before the antlr generated includes in the cpp // file } header "post_include_cpp" { // gets inserted after the antlr generated includes in the cpp // file #include #include } header { // gets inserted after generated namespace specifications in the // header file. But outside the generated class. } options { language="Cpp"; } class IOSCfgParser extends Parser; options { k = 2; // defaultErrorHandler=false; } { // additional methods and members public: std::ostream *dbg; IOSImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); } } cfgfile : ( comment | version | hostname | ip_commands | intrface | controller | vlan | access_list_commands | exit | description | shutdown | certificate | quit | unknown_command | NEWLINE )+ ; //**************************************************************** ip_commands : IP ( ip_access_list_ext | interface_known_ip_commands | community_list_command | ip_unused_command | unknown_command ) ; //**************************************************************** quit : QUIT { consumeUntil(NEWLINE); } ; //**************************************************************** // these are "ip ..." top level commands that we do not use but parser // should not abort on. Unlike unknown_command, these have known token as // a second word so they dont match unknown_command which expects WORD. ip_unused_command : ICMP | TCP | HOST { consumeUntil(NEWLINE); } ; //**************************************************************** community_list_command : COMMUNITY_LIST { consumeUntil(NEWLINE); } ; //**************************************************************** unknown_command : WORD { consumeUntil(NEWLINE); } ; //**************************************************************** certificate : CERTIFICATE WORD { consumeUntil(NEWLINE); consumeUntil(QUIT); } ; //**************************************************************** version : IOSVERSION v:NUMBER { *dbg << "VERSION " << v->getText() << std::endl; } ; //**************************************************************** hostname : HOSTNAME ( STRING | WORD ) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->setHostName( LT(0)->getText() ); *dbg << "HOSTNAME " << "LT0=" << LT(0)->getText() << std::endl; } ; //**************************************************************** // note that permit_ext and deny_ext eat NEWLINE. This is necessary // because the same parser rules are used for ip access-list commands, // where they should work the same way as LINE_COMMENT which eats // NEWLINE // access_list_commands : ACCESS_LIST acl_num:INT_CONST { importer->newUnidirRuleSet( std::string("acl_") + acl_num->getText(), libfwbuilder::Policy::TYPENAME); *dbg << acl_num->getLine() << ":" << " ACL #" << acl_num->getText() << " "; } ( permit_std | deny_std | permit_ext | deny_ext | remark ) ; //**************************************************************** ip_access_list_ext : ACCESS_LIST EXTENDED name:WORD { importer->newUnidirRuleSet( name->getText(), libfwbuilder::Policy::TYPENAME ); *dbg << name->getLine() << ":" << " ACL ext " << name->getText() << std::endl; } NEWLINE ( permit_ext | deny_ext | comment | remark | NEWLINE // to match end of each line and also empty lines )* { *dbg << LT(0)->getLine() << ":" << " ACL end" << std::endl << std::endl; } ; //**************************************************************** permit_ext: PERMIT { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; } rule_ext // NEWLINE { importer->pushRule(); } ; deny_ext: DENY { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; } rule_ext NEWLINE { importer->pushRule(); } ; //**************************************************************** permit_std: PERMIT { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "permit"; *dbg << LT(1)->getLine() << ":" << " permit "; } rule_std // NEWLINE { importer->pushRule(); } ; deny_std: DENY { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newPolicyRule(); importer->action = "deny"; *dbg << LT(1)->getLine() << ":" << " deny "; } rule_std NEWLINE { importer->pushRule(); } ; //**************************************************************** // the difference between standard and extended acls should be in these rules rule_ext : ( ip_protocols hostaddr_ext { importer->SaveTmpAddrToSrc(); *dbg << "(src) "; } hostaddr_ext { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } (time_range)? (fragments)? (log)? | ICMP { importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; } hostaddr_ext { importer->SaveTmpAddrToSrc(); *dbg << "(src) "; } hostaddr_ext { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } (icmp_spec)? (time_range)? (fragments)? (log)? | (TCP|UDP) { importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; } hostaddr_ext { importer->SaveTmpAddrToSrc(); *dbg << "(src) "; } (xoperator { importer->SaveTmpPortToSrc(); } )? hostaddr_ext { importer->SaveTmpAddrToDst(); *dbg << "(dst) "; } (xoperator { importer->SaveTmpPortToDst(); } )? (established)? (time_range)? (fragments)? (log)? ) { *dbg << std::endl; } ; //**************************************************************** rule_std : ( hostaddr_std { importer->SaveTmpAddrToSrc(); *dbg << "(std) "; } (log)? ) { *dbg << std::endl; } ; //**************************************************************** // ip_protocols : (IP | AHP | EIGRP | ESP | GRE | IGRP | IPINIP | NOS | OSPF | PCP | PIM ) ip_protocols : (IP | WORD ) { importer->protocol = LT(0)->getText(); *dbg << "protocol " << LT(0)->getText() << " "; }; icmp_spec : ( (INT_CONST) => (icmp_type:INT_CONST icmp_code:INT_CONST) { importer->icmp_type = icmp_type->getText(); importer->icmp_code = icmp_code->getText(); importer->icmp_spec = ""; *dbg << icmp_type->getText() << " " << icmp_code->getText() << " "; } | icmp_word:WORD { importer->icmp_spec = icmp_word->getText(); *dbg << icmp_word->getText() << " "; } ) ; xoperator : single_port_op | port_range ; single_port_op : (P_EQ | P_GT | P_LT | P_NEQ ) { importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; } port_spec ; port_range : P_RANGE { importer->tmp_port_op = LT(0)->getText(); *dbg << LT(0)->getText() << " "; } port_spec port_spec ; port_spec : (WORD|INT_CONST) { importer->tmp_port_spec += (std::string(" ") + LT(0)->getText()); *dbg << LT(0)->getText() << " "; } ; hostaddr_ext : (HOST h:IPV4) { importer->tmp_a = h->getText(); importer->tmp_nm = "0.0.0.0"; *dbg << h->getText() << "/0.0.0.0"; } | (a:IPV4 m:IPV4) { importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); } | ANY { importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; } ; hostaddr_std : (h:IPV4) { importer->tmp_a = h->getText(); importer->tmp_nm = "0.0.0.0"; *dbg << h->getText() << "/0.0.0.0"; } | (a:IPV4 m:IPV4) { importer->tmp_a = a->getText(); importer->tmp_nm = m->getText(); *dbg << a->getText() << "/" << m->getText(); } | ANY { importer->tmp_a = "0.0.0.0"; importer->tmp_nm = "0.0.0.0"; *dbg << "0.0.0.0/0.0.0.0"; } ; log : (LOG | LOG_INPUT) { importer->logging = true; *dbg << "logging "; } ; established : ESTABLISHED { importer->established = true; *dbg << "established "; } ; fragments : FRAGMENTS { importer->fragments = true; *dbg << "fragments "; } ; time_range : TIME_RANGE tr_name:WORD { importer->time_range_name = tr_name->getText(); *dbg << "time_range " << tr_name->getText() << " "; } ; //**************************************************************** // Need this not because we parse "vlan" commands, but because // "ip address" command may appear in the "vlan" context // So we properly clear current_interface in the Importer class // to let it know that it should ignore "ip address" that follows. // // Also, depending on the context, command "vlan" may have just // one argument (vlan number) or more. So we need to consume // all tokens until newline to accommodate for all possible formats. // This works because we ignore all of them. // vlan : VLAN (WORD | INT_CONST ) { importer->setCurrentLineNumber(LT(0)->getLine()); importer->clearCurrentInterface(); consumeUntil(NEWLINE); } ; //**************************************************************** controller : CONTROLLER { importer->setCurrentLineNumber(LT(0)->getLine()); importer->clearCurrentInterface(); consumeUntil(NEWLINE); } ; //**************************************************************** intrface : INTRFACE in:WORD { importer->setCurrentLineNumber(LT(0)->getLine()); importer->newInterface( in->getText() ); *dbg << in->getLine() << ":" << " INTRFACE: " << in->getText() << std::endl; } ( POINT_TO_POINT { importer->addMessageToLog( QString("Warning: point-to-point interfaces " "are not supported")); } )? NEWLINE ; // interface description // Use it for comment description : DESCRIPTION { importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string descr; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { descr += LT(1)->getText() + " "; consume(); } importer->setInterfaceComment( descr ); *dbg << " DESCRIPTION " << descr << std::endl; //consumeUntil(NEWLINE); } ; // remark. According to the Cisco docs, can only be used // within access list // Use it for the current rule comment remark : REMARK { importer->setCurrentLineNumber(LT(0)->getLine()); *dbg << LT(1)->getLine() << ":"; std::string rem; while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) { rem += LT(1)->getText() + " "; consume(); } importer->addRuleComment( rem ); *dbg << " REMARK " << rem << std::endl; //consumeUntil(NEWLINE); } // NEWLINE ; shutdown : SHUTDOWN { *dbg<< LT(1)->getLine() << ":" << " INTERFACE SHUTDOWN " << std::endl; } ; interface_known_ip_commands : ( access_group_by_name | access_group_by_number | intf_address ) NEWLINE ; // need this because "ospf", "bgp" and others are a known tokens // (needed for protocol and ports in access lists) and "ip ospf" and // similar are legit interface commands // ignore_interface_ip_commands : (BGP | OSPF | DHCP) // { // consumeUntil(NEWLINE); // } // ; access_group_by_name : ACCESS_GROUP acln:WORD dir:WORD { importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( acln->getText(), "", dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << acln->getText() << "'" << " " << dir->getText() << std::endl; } ; // for acess lists defined by numbers we add prefix "acl_" to the name // Making sure this is done consistently in both "access-list NNN" // and "ip access-group NNN" commands access_group_by_number : ACCESS_GROUP acln:INT_CONST dir:WORD { importer->setCurrentLineNumber(LT(0)->getLine()); importer->setInterfaceAndDirectionForRuleSet( std::string("acl_") + acln->getText(), "", dir->getText() ); *dbg << LT(1)->getLine() << ":" << " INTRFACE: ACL '" << acln->getText() << "'" << " " << dir->getText() << std::endl; } ; intf_address : ADDRESS a:IPV4 m:IPV4 (s:SECONDARY)? { importer->setCurrentLineNumber(LT(0)->getLine()); importer->addInterfaceAddress(a->getText(), m->getText()); *dbg << LT(1)->getLine() << ":" << " INTRFACE ADDRESS: " << a->getText() << "/" << m->getText() << " "; if (s) { *dbg << s->getText(); } *dbg << std::endl; } ; //**************************************************************** exit: EXIT ; comment : LINE_COMMENT ; // comment: COMMENT_START // { // *dbg << LT(1)->getLine() << ":"; // std::string comm; // while (LA(1) != ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE && LA(1) != NEWLINE) // { // comm += LT(1)->getText() + " "; // consume(); // } // importer->addInterfaceComment( comm ); // *dbg << " COMMENT " << comm << std::endl; // } // ; //**************************************************************** class IOSCfgLexer extends Lexer; options { k = 10; // ASCII only charVocabulary = '\3'..'\377'; } tokens { EXIT = "exit"; QUIT = "quit"; IOSVERSION = "version"; HOSTNAME = "hostname"; CERTIFICATE = "certificate"; INTRFACE = "interface"; CONTROLLER = "controller"; DESCRIPTION = "description"; REMARK = "remark"; SHUTDOWN = "shutdown"; VLAN = "vlan"; ACCESS_LIST = "access-list"; ACCESS_GROUP = "access-group"; ADDRESS = "address"; SECONDARY = "secondary"; COMMUNITY_LIST = "community-list"; PERMIT = "permit"; DENY = "deny"; // protocols for 'permit' and 'deny' commands IP = "ip"; ICMP = "icmp"; TCP = "tcp"; UDP = "udp"; // AHP = "ahp"; // EIGRP = "eigrp"; // ESP = "esp"; // GRE = "gre"; // IGMP = "igmp"; // IGRP = "igrp"; // IPINIP = "ipinip"; // NOS = "nos"; // OSPF = "ospf"; // PCP = "pcp"; // PIM = "pim"; HOST = "host"; ANY = "any"; P_EQ = "eq"; P_GT = "gt"; P_LT = "lt"; P_NEQ = "neq"; P_RANGE = "range"; LOG = "log"; LOG_INPUT = "log-input"; ESTABLISHED = "established"; FRAGMENTS = "fragments"; TIME_RANGE = "time-range"; EXTENDED = "extended" ; STANDARD = "standard" ; POINT_TO_POINT = "point-to-point" ; } LINE_COMMENT : "!" (~('\r' | '\n'))* ; // NEWLINE ; Whitespace : ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) { _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; } ; //COMMENT_START : '!' ; NEWLINE : ( "\r\n" | '\r' | '\n' ) { newline(); } ; protected INT_CONST:; protected HEX_CONST:; protected NEG_INT_CONST:; protected DIGIT : '0'..'9' ; protected HEXDIGIT : '0'..'9' | 'A'..'F' ; NUMBER : ( ( (DIGIT)+ DOT (DIGIT)+ DOT (DIGIT)+ )=> ( (DIGIT)+ DOT (DIGIT)+ DOT (DIGIT)+ DOT (DIGIT)+ ) { _ttype = IPV4; } | ( (DIGIT)+ DOT (DIGIT)+ )=> ( (DIGIT)+ DOT (DIGIT)+ ) | ( DIGIT )+ { _ttype = INT_CONST; } | ( '0' 'x' ( HEXDIGIT )+ ) { _ttype = HEX_CONST; } ) ; WORD : ( 'a'..'z' | 'A'..'Z' | '$' ) ( '!'..'/' | '0'..'9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A'..'Z' | '\\' | '^' | '_' | '`' | 'a'..'z' )* ; STRING : '"' (~'"')* '"'; PIPE_CHAR : '|'; NUMBER_SIGN : '#' ; // DOLLAR : '$' ; PERCENT : '%' ; AMPERSAND : '&' ; APOSTROPHE : '\'' ; OPENING_PAREN : '(' ; CLOSING_PAREN : ')' ; STAR : '*' ; PLUS : '+' ; COMMA : ',' ; MINUS : '-' ; DOT : '.' ; SLASH : '/' ; COLON : ':' ; SEMICOLON : ';' ; LESS_THAN : '<' ; EQUALS : '=' ; GREATER_THAN : '>' ; QUESTION : '?' ; COMMERCIAL_AT : '@' ; OPENING_SQUARE : '[' ; CLOSING_SQUARE : ']' ; CARET : '^' ; UNDERLINE : '_' ; OPENING_BRACE : '{' ; CLOSING_BRACE : '}' ; TILDE : '~' ; fwbuilder-5.1.0.3599/src/parsers/IfconfigLinuxCfgParserTokenTypes.txt0000644000175000017500000000234511733011756026400 0ustar sylvestresylvestre// $ANTLR 2.7.7 (20100319): ifconfig_linux.g -> IfconfigLinuxCfgParserTokenTypes.txt$ IfconfigLinuxCfgParser // output token vocab name NEWLINE=4 DOUBLE_NEWLINE=5 LINE_COMMENT=6 PRIORITY="priority"=7 MEDIA="media"=8 STATUS="status"=9 WORD=10 UP="UP"=11 UPPER_BROADCAST="BROADCAST"=12 UPPER_POINTOPOINT="POINTOPOINT"=13 UPPER_LOOPBACK="LOOPBACK"=14 UPPER_NOARP="NOARP"=15 UPPER_RUNNING="RUNNING"=16 LOOPBACK="Loopback"=17 INTERRUPT="Interrupt"=18 COLLISIONS="collisions"=19 COLON=20 RX="RX"=21 TX="TX"=22 DOT=23 INT_CONST=24 LINK="Link"=25 ENCAP="encap"=26 HWADDR="HWaddr"=27 MAC_ADDRESS=28 INET="inet"=29 ADDR="addr"=30 IPV4=31 BCAST="Bcast"=32 MASK="Mask"=33 P_T_P="P-t-P"=34 INET6="inet6"=35 IPV6=36 SLASH=37 SCOPE="Scope"=38 HOST="Host"=39 GLOBAL="Global"=40 GROUPS="groups"=41 FLAGS="flags"=42 BROADCAST="broadcast"=43 NETMASK="netmask"=44 PREFIXLEN="prefixlen"=45 SCOPEID="scopeid"=46 MTU="mtu"=47 LLADR="lladdr"=48 Whitespace=49 HEX_CONST=50 NUMBER=51 NEG_INT_CONST=52 HEX_DIGIT=53 DIGIT=54 NUM_3DIGIT=55 NUM_HEX_4DIGIT=56 NUMBER_ADDRESS_OR_WORD=57 PERCENT=58 AMPERSAND=59 STAR=60 MINUS=61 EQUAL=62 QUESTION=63 OPENING_PAREN=64 CLOSING_PAREN=65 OPENING_SQUARE=66 CLOSING_SQUARE=67 OPENING_BRACE=68 CLOSING_BRACE=69 LESS_THAN=70 GREATER_THAN=71 fwbuilder-5.1.0.3599/src/parsers/PIXCfgParserTokenTypes.txt0000644000175000017500000001027411733011756024274 0ustar sylvestresylvestre// $ANTLR 2.7.7 (20090306): pix.g -> PIXCfgParserTokenTypes.txt$ PIXCfgParser // output token vocab name NEWLINE=4 QUIT="quit"=5 IP="ip"=6 COMMUNITY_LIST="community-list"=7 TIMEOUT="timeout"=8 PIM="pim"=9 NETWORK="network"=10 NAMES="names"=11 NAME="name"=12 IPV4=13 WORD=14 IPV6=15 AH="ah"=16 EIGRP="eigrp"=17 ESP_WORD="esp"=18 GRE="gre"=19 IGMP="igmp"=20 IGRP="igrp"=21 IPINIP="ipinip"=22 IPSEC="ipsec"=23 NOS="nos"=24 OSPF="ospf"=25 PCP="pcp"=26 PPTP="pptp"=27 SNP="snp"=28 OBJECT="object"=29 DESCRIPTION="description"=30 HOST="host"=31 RANGE="range"=32 SUBNET="subnet"=33 SERVICE="service"=34 HTTP="http"=35 SSH="ssh"=36 TELNET="telnet"=37 ICMP="icmp"=38 INT_CONST=39 ICMP6="icmp6"=40 TCP="tcp"=41 UDP="udp"=42 SOURCE="source"=43 DESTINATION="destination"=44 OBJECT_GROUP="object-group"=45 GROUP_OBJECT="group-object"=46 NETWORK_OBJECT="network-object"=47 PROTOCOL="protocol"=48 PROTOCOL_OBJECT="protocol-object"=49 ICMP_OBJECT="icmp-object"=50 ICMP_TYPE="icmp-type"=51 TCP_UDP="tcp-udp"=52 SERVICE_OBJECT="service-object"=53 PORT_OBJECT="port-object"=54 CRYPTO="crypto"=55 DNS="dns"=56 CALL_HOME="call-home"=57 INTERNAL="internal"=58 PASSWORD_RECOVERY="password-recovery"=59 RESETINBOUND="resetinbound"=60 RESETOUTBOUND="resetoutbound"=61 RESETOUTSIDE="resetoutside"=62 NO="no"=63 CERTIFICATE="certificate"=64 PIX_WORD="PIX"=65 ASA_WORD="ASA"=66 FWSM_WORD="FWSM"=67 VERSION_WORD_CAP="Version"=68 NUMBER=69 HOSTNAME="hostname"=70 STRING=71 ACCESS_LIST="access-list"=72 EXTENDED="extended"=73 PERMIT="permit"=74 DENY="deny"=75 STANDARD="standard"=76 P_EQ="eq"=77 P_GT="gt"=78 P_LT="lt"=79 P_NEQ="neq"=80 ECHO="echo"=81 ESTABLISHED="established"=82 ALTERNATE_ADDRESS="alternate-address"=83 CONVERSION_ERROR="conversion-error"=84 ECHO_REPLY="echo-reply"=85 INFORMATION_REPLY="information-reply"=86 INFORMATION_REQUEST="information-request"=87 MASK_REPLY="mask-reply"=88 MASK_REQUEST="mask-request"=89 MOBILE_REDIRECT="mobile-redirect"=90 PARAMETER_PROBLEM="parameter-problem"=91 REDIRECT="redirect"=92 ROUTER_ADVERTISEMENT="router-advertisement"=93 ROUTER_SOLICITATION="router-solicitation"=94 SOURCE_QUENCH="source-quench"=95 TIME_EXCEEDED="time-exceeded"=96 TIMESTAMP_REPLY="timestamp-reply"=97 TIMESTAMP_REQUEST="timestamp-request"=98 TRACEROUTE="traceroute"=99 UNREACHABLE="unreachable"=100 INTRFACE="interface"=101 ANY="any"=102 LOG="log"=103 LOG_INPUT="log-input"=104 LOG_LEVEL_ALERTS="alerts"=105 LOG_LEVEL_CRITICAL="critical"=106 LOG_LEVEL_DEBUGGING="debugging"=107 LOG_LEVEL_EMERGENCIES="emergencies"=108 LOG_LEVEL_ERRORS="errors"=109 LOG_LEVEL_INFORMATIONAL="informational"=110 LOG_LEVEL_NOTIFICATIONS="notifications"=111 LOG_LEVEL_WARNINGS="warnings"=112 LOG_LEVEL_DISABLE="disable"=113 LOG_LEVEL_INACTIVE="inactive"=114 INTERVAL="interval"=115 FRAGMENTS="fragments"=116 TIME_RANGE="time-range"=117 CONTROLLER="controller"=118 OUTSIDE="outside"=119 LINE_COMMENT=120 EXIT="exit"=121 AUI="aui"=122 AUTO="auto"=123 BNC="bnc"=124 FULL="full"=125 BASET="baseT"=126 BASETX="baseTX"=127 NAMEIF="nameif"=128 VLAN="vlan"=129 SPEED="speed"=130 DUPLEX="duplex"=131 DDNS="ddns"=132 FORWARD="forward"=133 DELAY="delay"=134 HOLD_TIME="hold-time"=135 IPV6_C="ipv6"=136 MANAGEMENT_ONLY="management-only"=137 MAC_ADDRESS="mac-address"=138 MULTICAST="multicast"=139 PPPOE=140 RIP="rip"=141 SEC_LEVEL="security-level"=142 SHUTDOWN="shutdown"=143 ADDRESS="address"=144 DHCP="dhcp"=145 STANDBY="standby"=146 SWITCHPORT="switchport"=147 ACCESS="access"=148 SCOPY="scopy"=149 VERSION_WORD_LOW="version"=150 AUTHENTICATION_CERTIFICATE="authentication-certificate"=151 SERVER="server"=152 REMARK="remark"=153 ACCESS_GROUP="access-group"=154 COLON_COMMENT=155 NAT="nat"=156 OPENING_PAREN=157 CLOSING_PAREN=158 COMMA=159 GLOBAL="global"=160 MINUS=161 NETMASK="netmask"=162 STATIC="static"=163 NORANDOMSEQ="norandomseq"=164 SECONDARY="secondary"=165 SETROUTE="setroute"=166 Whitespace=167 HEX_CONST=168 NEG_INT_CONST=169 DIGIT=170 HEXDIGIT=171 NUMBER_ADDRESS_OR_WORD=172 PIPE_CHAR=173 NUMBER_SIGN=174 PERCENT=175 AMPERSAND=176 APOSTROPHE=177 STAR=178 PLUS=179 DOT=180 SLASH=181 COLON=182 SEMICOLON=183 LESS_THAN=184 EQUALS=185 GREATER_THAN=186 QUESTION=187 COMMERCIAL_AT=188 OPENING_SQUARE=189 CLOSING_SQUARE=190 CARET=191 UNDERLINE=192 OPENING_BRACE=193 CLOSING_BRACE=194 TILDE=195 EXLAMATION=196 fwbuilder-5.1.0.3599/src/parsers/PFCfgLexer.cpp0000644000175000017500000016371311733011756021710 0ustar sylvestresylvestre/* $ANTLR 2.7.7 (20100319): "pf.g" -> "PFCfgLexer.cpp"$ */ #line 43 "pf.g" // gets inserted before the antlr generated includes in the cpp // file #line 8 "PFCfgLexer.cpp" #include "PFCfgLexer.hpp" #include #include #include #include #include #include #include #line 49 "pf.g" // gets inserted after the antlr generated includes in the cpp // file #include #include #line 25 "PFCfgLexer.cpp" #line 1 "pf.g" #line 27 "PFCfgLexer.cpp" PFCfgLexer::PFCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in) : ANTLR_USE_NAMESPACE(antlr)CharScanner(new ANTLR_USE_NAMESPACE(antlr)CharBuffer(in),true) { initLiterals(); } PFCfgLexer::PFCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib) : ANTLR_USE_NAMESPACE(antlr)CharScanner(ib,true) { initLiterals(); } PFCfgLexer::PFCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state) : ANTLR_USE_NAMESPACE(antlr)CharScanner(state,true) { initLiterals(); } void PFCfgLexer::initLiterals() { literals["badhead"] = 201; literals["notifications"] = 235; literals["state-policy"] = 26; literals["floating"] = 28; literals["no"] = 84; literals["counters"] = 72; literals["esp"] = 126; literals["routersol"] = 160; literals["frags"] = 60; literals["reply-to"] = 140; literals["icmp.first"] = 49; literals["string-key"] = 99; literals["gre"] = 125; literals["pass"] = 86; literals["scrub"] = 65; literals["warnings"] = 236; literals["include"] = 6; literals["skip"] = 32; literals["timeout"] = 13; literals["eigrp"] = 128; literals["icmp-type"] = 151; literals["transit"] = 199; literals["inet"] = 115; literals["no-df"] = 146; literals["network"] = 77; literals["photuris"] = 176; literals["igmp"] = 120; literals["unreach"] = 154; literals["range"] = 228; literals["rsvp"] = 124; literals["debugging"] = 231; literals["host-tos"] = 189; literals["paramprob"] = 162; literals["user"] = 113; literals["interface"] = 217; literals["adaptive.end"] = 58; literals["limit"] = 21; literals["state-defaults"] = 29; literals["hex-key"] = 98; literals["net-unk"] = 183; literals["antispoof"] = 9; literals["udp.single"] = 47; literals["inforeq"] = 165; literals["ipv6-here"] = 173; literals["redir"] = 156; literals["static-port"] = 88; literals["common-adv"] = 198; literals["loginterface"] = 22; literals["ip"] = 118; literals["mobregreq"] = 174; literals["conservative"] = 17; literals["ospf"] = 129; literals["proto-unr"] = 179; literals["peer"] = 79; literals["inforep"] = 166; literals["errors"] = 233; literals["tables-entries"] = 64; literals["any"] = 136; literals["mobregrep"] = 175; literals["label"] = 214; literals["pptp"] = 224; literals["synproxy"] = 212; literals["debug"] = 37; literals["alerts"] = 229; literals["all"] = 112; literals["state"] = 213; literals["tag"] = 209; literals["in"] = 108; literals["tables"] = 63; literals["file"] = 73; literals["nos"] = 221; literals["src-nodes"] = 62; literals["ipv6-where"] = 172; literals["require-order"] = 30; literals["udp"] = 122; literals["states"] = 61; literals["sticky-address"] = 101; literals["return-icmp"] = 106; literals["redir-tos-net"] = 195; literals["pim"] = 223; literals["emergencies"] = 232; literals["squench"] = 155; literals["disable"] = 237; literals["flags"] = 150; literals["tcp"] = 121; literals["net-tos"] = 188; literals["reassemble"] = 38; literals["adaptive.start"] = 57; literals["frag"] = 54; literals["port"] = 92; literals["icmp"] = 119; literals["to"] = 114; literals["return-rst"] = 104; literals["normal-adv"] = 197; literals["optimization"] = 15; literals["log"] = 110; literals["fragment"] = 143; literals["snp"] = 226; literals["broadcast"] = 78; literals["icmp6-type"] = 207; literals["normal"] = 19; literals["code"] = 152; literals["if-bound"] = 27; literals["src.track"] = 56; literals["drop-ovl"] = 145; literals["routeradv"] = 159; literals["other.single"] = 52; literals["dup-to"] = 141; literals["bitmask"] = 95; literals["maskreq"] = 167; literals["ipip"] = 130; literals["tcp.closed"] = 45; literals["block"] = 103; literals["high-latency"] = 18; literals["udp.first"] = 46; literals["badlen"] = 203; literals["tcp.first"] = 40; literals["host-unr"] = 178; literals["ah"] = 127; literals["random-id"] = 149; literals["modulate"] = 211; literals["interval"] = 55; literals["maskrep"] = 168; literals["ruleset-optimization"] = 14; literals["trace"] = 169; literals["rip"] = 225; literals["urpf-failed"] = 135; literals["set"] = 12; literals["source-hash"] = 97; literals["critical"] = 230; literals["quit"] = 216; literals["icmp.error"] = 50; literals["const"] = 71; literals["altq"] = 10; literals["tcp.closing"] = 43; literals["port-unr"] = 180; literals["table"] = 67; literals["redir-tos-host"] = 196; literals["fingerprints"] = 31; literals["return"] = 25; literals["optmiss"] = 202; literals["match"] = 66; literals["keep"] = 210; literals["net-prohib"] = 186; literals["inet6"] = 116; literals["group"] = 142; literals["from"] = 134; literals["tcp.finwait"] = 44; literals["hostid"] = 39; literals["proto"] = 117; literals["vrrp"] = 131; literals["drop"] = 24; literals["l2tp"] = 132; literals["max-mss"] = 148; literals["isolate"] = 185; literals["timereq"] = 163; literals["aggressive"] = 16; literals["icmp6"] = 218; literals["echoreq"] = 158; literals["tcp.established"] = 42; literals["decrypt-fail"] = 206; literals["mobredir"] = 171; literals["other.first"] = 51; literals["ipsec"] = 220; literals["no-route"] = 137; literals["random"] = 96; literals["binat"] = 102; literals["srcfail"] = 182; literals["self"] = 80; literals["timerep"] = 164; literals["crop"] = 144; literals["host-preced"] = 191; literals["host"] = 227; literals["echorep"] = 153; literals["other.multiple"] = 53; literals["althost"] = 157; literals["udp.multiple"] = 48; literals["cutoff-preced"] = 192; literals["redir-host"] = 194; literals["rdr"] = 89; literals["tagged"] = 208; literals["on"] = 33; literals["round-robin"] = 100; literals["pcp"] = 222; literals["block-policy"] = 23; literals["persist"] = 70; literals["unknown-ind"] = 204; literals["redir-net"] = 193; literals["filter-prohib"] = 190; literals["nat"] = 85; literals["satellite"] = 20; literals["informational"] = 234; literals["needfrag"] = 181; literals["tcp.opening"] = 41; literals["igrp"] = 219; literals["quick"] = 111; literals["timex"] = 161; literals["host-unk"] = 184; literals["route-to"] = 139; literals["dataconv"] = 170; literals["rdp"] = 123; literals["net-unr"] = 177; literals["queue"] = 11; literals["isis"] = 133; literals["reassemb"] = 200; literals["inactive"] = 238; literals["out"] = 109; literals["min-ttl"] = 147; literals["auth-fail"] = 205; literals["exit"] = 215; literals["host-prohib"] = 187; } ANTLR_USE_NAMESPACE(antlr)RefToken PFCfgLexer::nextToken() { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; for (;;) { ANTLR_USE_NAMESPACE(antlr)RefToken theRetToken; int _ttype = ANTLR_USE_NAMESPACE(antlr)Token::INVALID_TYPE; resetText(); try { // for lexical and char stream error handling switch ( LA(1)) { case 0x23 /* '#' */ : { mCOMMENT_START(true); theRetToken=_returnToken; break; } case 0xa /* '\n' */ : case 0xd /* '\r' */ : { mNEWLINE(true); theRetToken=_returnToken; break; } case 0x24 /* '$' */ : case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : case 0x3a /* ':' */ : case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { mNUMBER_ADDRESS_OR_WORD(true); theRetToken=_returnToken; break; } case 0x7c /* '|' */ : { mPIPE_CHAR(true); theRetToken=_returnToken; break; } case 0x25 /* '%' */ : { mPERCENT(true); theRetToken=_returnToken; break; } case 0x26 /* '&' */ : { mAMPERSAND(true); theRetToken=_returnToken; break; } case 0x27 /* '\'' */ : { mAPOSTROPHE(true); theRetToken=_returnToken; break; } case 0x2a /* '*' */ : { mSTAR(true); theRetToken=_returnToken; break; } case 0x2b /* '+' */ : { mPLUS(true); theRetToken=_returnToken; break; } case 0x2c /* ',' */ : { mCOMMA(true); theRetToken=_returnToken; break; } case 0x2d /* '-' */ : { mMINUS(true); theRetToken=_returnToken; break; } case 0x2e /* '.' */ : { mDOT(true); theRetToken=_returnToken; break; } case 0x2f /* '/' */ : { mSLASH(true); theRetToken=_returnToken; break; } case 0x3b /* ';' */ : { mSEMICOLON(true); theRetToken=_returnToken; break; } case 0x3d /* '=' */ : { mEQUAL(true); theRetToken=_returnToken; break; } case 0x3f /* '?' */ : { mQUESTION(true); theRetToken=_returnToken; break; } case 0x40 /* '@' */ : { mCOMMERCIAL_AT(true); theRetToken=_returnToken; break; } case 0x28 /* '(' */ : { mOPENING_PAREN(true); theRetToken=_returnToken; break; } case 0x29 /* ')' */ : { mCLOSING_PAREN(true); theRetToken=_returnToken; break; } case 0x5b /* '[' */ : { mOPENING_SQUARE(true); theRetToken=_returnToken; break; } case 0x5d /* ']' */ : { mCLOSING_SQUARE(true); theRetToken=_returnToken; break; } case 0x7b /* '{' */ : { mOPENING_BRACE(true); theRetToken=_returnToken; break; } case 0x7d /* '}' */ : { mCLOSING_BRACE(true); theRetToken=_returnToken; break; } case 0x5e /* '^' */ : { mCARET(true); theRetToken=_returnToken; break; } case 0x5f /* '_' */ : { mUNDERLINE(true); theRetToken=_returnToken; break; } case 0x7e /* '~' */ : { mTILDE(true); theRetToken=_returnToken; break; } case 0x21 /* '!' */ : { mEXLAMATION(true); theRetToken=_returnToken; break; } case 0x3c /* '<' */ : { mLESS_THAN(true); theRetToken=_returnToken; break; } case 0x3e /* '>' */ : { mGREATER_THAN(true); theRetToken=_returnToken; break; } default: if ((LA(1) == 0x22 /* '\"' */ ) && ((LA(2) >= 0x3 /* '\3' */ && LA(2) <= 0xff))) { mSTRING(true); theRetToken=_returnToken; } else if ((_tokenSet_0.member(LA(1)))) { mWhitespace(true); theRetToken=_returnToken; } else if ((LA(1) == 0x22 /* '\"' */ ) && (true)) { mDOUBLE_QUOTE(true); theRetToken=_returnToken; } else { if (LA(1)==EOF_CHAR) { uponEOF(); _returnToken = makeToken(ANTLR_USE_NAMESPACE(antlr)Token::EOF_TYPE); } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } } if ( !_returnToken ) goto tryAgain; // found SKIP token _ttype = _returnToken->getType(); _ttype = testLiteralsTable(_ttype); _returnToken->setType(_ttype); return _returnToken; } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& e) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamRecognitionException(e); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamIOException& csie) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamIOException(csie.io); } catch (ANTLR_USE_NAMESPACE(antlr)CharStreamException& cse) { throw ANTLR_USE_NAMESPACE(antlr)TokenStreamException(cse.getMessage()); } tryAgain:; } } void PFCfgLexer::mWhitespace(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = Whitespace; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x3 /* '\3' */ : case 0x4 /* '\4' */ : case 0x5 /* '\5' */ : case 0x6 /* '\6' */ : case 0x7 /* '\7' */ : case 0x8 /* '\10' */ : { matchRange('\3','\10'); break; } case 0x9 /* '\t' */ : { match('\t' /* charlit */ ); break; } case 0xb /* '\13' */ : { match('\13' /* charlit */ ); break; } case 0xc /* '\14' */ : { match('\14' /* charlit */ ); break; } case 0xe /* '\16' */ : case 0xf /* '\17' */ : case 0x10 /* '\20' */ : case 0x11 /* '\21' */ : case 0x12 /* '\22' */ : case 0x13 /* '\23' */ : case 0x14 /* '\24' */ : case 0x15 /* '\25' */ : case 0x16 /* '\26' */ : case 0x17 /* '\27' */ : case 0x18 /* '\30' */ : case 0x19 /* '\31' */ : case 0x1a /* '\32' */ : case 0x1b /* '\33' */ : case 0x1c /* '\34' */ : case 0x1d /* '\35' */ : case 0x1e /* '\36' */ : case 0x1f /* '\37' */ : { matchRange('\16','\37'); break; } case 0x20 /* ' ' */ : { match(' ' /* charlit */ ); break; } default: if (((LA(1) >= 0x7f && LA(1) <= 0xff))) { matchRange('\177',static_cast('\377')); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( inputState->guessing==0 ) { #line 2001 "pf.g" _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; #line 622 "PFCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCOMMENT_START(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMENT_START; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('#' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mNEWLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEWLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { if ((LA(1) == 0xd /* '\r' */ ) && (LA(2) == 0xa /* '\n' */ )) { match("\r\n"); } else if ((LA(1) == 0xd /* '\r' */ ) && (true)) { match('\r' /* charlit */ ); } else if ((LA(1) == 0xa /* '\n' */ )) { match('\n' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } if ( inputState->guessing==0 ) { #line 2006 "pf.g" newline(); #line 669 "PFCfgLexer.cpp" } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mINT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mHEX_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mNUMBER(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mNEG_INT_CONST(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NEG_INT_CONST; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mHEX_DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = HEX_DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { switch ( LA(1)) { case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : { matchRange('a','f'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : { matchRange('A','F'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mDIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; matchRange('0','9'); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mNUM_3DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_3DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { { matchRange('0','9'); } { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { matchRange('0','9'); } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mNUM_HEX_4DIGIT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUM_HEX_4DIGIT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; mHEX_DIGIT(false); { if ((_tokenSet_1.member(LA(1)))) { { mHEX_DIGIT(false); } { if ((_tokenSet_1.member(LA(1)))) { { mHEX_DIGIT(false); } { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { } } } else { } } } else { } } if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mNUMBER_ADDRESS_OR_WORD(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = NUMBER_ADDRESS_OR_WORD; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; switch ( LA(1)) { case 0x3a /* ':' */ : { { bool synPredMatched322 = false; if (((LA(1) == 0x3a /* ':' */ ) && (LA(2) == 0x3a /* ':' */ ) && (_tokenSet_1.member(LA(3))))) { int _m322 = mark(); synPredMatched322 = true; inputState->guessing++; try { { match(':' /* charlit */ ); match(':' /* charlit */ ); { // ( ... )+ int _cnt321=0; for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { if ( _cnt321>=1 ) { goto _loop321; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt321++; } _loop321:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched322 = false; } rewind(_m322); inputState->guessing--; } if ( synPredMatched322 ) { { match(':' /* charlit */ ); match(':' /* charlit */ ); { // ( ... )+ int _cnt325=0; for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { if ( _cnt325>=1 ) { goto _loop325; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt325++; } _loop325:; } // ( ... )+ { // ( ... )* for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); { // ( ... )+ int _cnt328=0; for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { if ( _cnt328>=1 ) { goto _loop328; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt328++; } _loop328:; } // ( ... )+ } else { goto _loop329; } } _loop329:; } // ( ... )* } if ( inputState->guessing==0 ) { #line 2052 "pf.g" _ttype = IPV6; #line 977 "PFCfgLexer.cpp" } } else if ((LA(1) == 0x3a /* ':' */ ) && (LA(2) == 0x3a /* ':' */ ) && (true)) { { match(':' /* charlit */ ); match(':' /* charlit */ ); } if ( inputState->guessing==0 ) { #line 2054 "pf.g" _ttype = IPV6; #line 988 "PFCfgLexer.cpp" } } else if ((LA(1) == 0x3a /* ':' */ ) && (true)) { match(':' /* charlit */ ); if ( inputState->guessing==0 ) { #line 2056 "pf.g" _ttype = COLON; #line 996 "PFCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } break; } case 0x24 /* '$' */ : { { if ((LA(1) == 0x24 /* '$' */ ) && (_tokenSet_2.member(LA(2)))) { match('$' /* charlit */ ); { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } default: { goto _loop355; } } } _loop355:; } // ( ... )* if ( inputState->guessing==0 ) { #line 2080 "pf.g" _ttype = MACRO; #line 1172 "PFCfgLexer.cpp" } } else if ((LA(1) == 0x24 /* '$' */ ) && (true)) { match('$' /* charlit */ ); } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } break; } default: bool synPredMatched332 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_3.member(LA(2))) && (_tokenSet_3.member(LA(3))))) { int _m332 = mark(); synPredMatched332 = true; inputState->guessing++; try { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched332 = false; } rewind(_m332); inputState->guessing--; } if ( synPredMatched332 ) { { mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); match('.' /* charlit */ ); mNUM_3DIGIT(false); } if ( inputState->guessing==0 ) { #line 2061 "pf.g" _ttype = IPV4; #line 1218 "PFCfgLexer.cpp" } } else { bool synPredMatched339 = false; if ((((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (_tokenSet_3.member(LA(2))) && (_tokenSet_3.member(LA(3))))) { int _m339 = mark(); synPredMatched339 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt336=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt336>=1 ) { goto _loop336; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt336++; } _loop336:; } // ( ... )+ match('.' /* charlit */ ); { // ( ... )+ int _cnt338=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt338>=1 ) { goto _loop338; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt338++; } _loop338:; } // ( ... )+ } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched339 = false; } rewind(_m339); inputState->guessing--; } if ( synPredMatched339 ) { { { // ( ... )+ int _cnt342=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt342>=1 ) { goto _loop342; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt342++; } _loop342:; } // ( ... )+ match('.' /* charlit */ ); { // ( ... )+ int _cnt344=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt344>=1 ) { goto _loop344; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt344++; } _loop344:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 2064 "pf.g" _ttype = NUMBER; #line 1301 "PFCfgLexer.cpp" } } else { bool synPredMatched307 = false; if (((_tokenSet_1.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (true))) { int _m307 = mark(); synPredMatched307 = true; inputState->guessing++; try { { { // ( ... )+ int _cnt306=0; for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { if ( _cnt306>=1 ) { goto _loop306; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt306++; } _loop306:; } // ( ... )+ match(':' /* charlit */ ); } } catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& pe) { synPredMatched307 = false; } rewind(_m307); inputState->guessing--; } if ( synPredMatched307 ) { { { { // ( ... )+ int _cnt311=0; for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { if ( _cnt311>=1 ) { goto _loop311; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt311++; } _loop311:; } // ( ... )+ { // ( ... )+ int _cnt315=0; for (;;) { if ((LA(1) == 0x3a /* ':' */ )) { match(':' /* charlit */ ); { // ( ... )* for (;;) { if ((_tokenSet_1.member(LA(1)))) { mHEX_DIGIT(false); } else { goto _loop314; } } _loop314:; } // ( ... )* } else { if ( _cnt315>=1 ) { goto _loop315; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt315++; } _loop315:; } // ( ... )+ } if ( inputState->guessing==0 ) { #line 2046 "pf.g" _ttype = IPV6; #line 1382 "PFCfgLexer.cpp" } } } else if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ )) && (true) && (true)) { { // ( ... )+ int _cnt346=0; for (;;) { if (((LA(1) >= 0x30 /* '0' */ && LA(1) <= 0x39 /* '9' */ ))) { mDIGIT(false); } else { if ( _cnt346>=1 ) { goto _loop346; } else {throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn());} } _cnt346++; } _loop346:; } // ( ... )+ if ( inputState->guessing==0 ) { #line 2066 "pf.g" _ttype = INT_CONST; #line 1404 "PFCfgLexer.cpp" } } else if ((_tokenSet_2.member(LA(1))) && (true) && (true)) { { switch ( LA(1)) { case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } default: { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } } } { // ( ... )* for (;;) { switch ( LA(1)) { case 0x22 /* '\"' */ : { match('\"' /* charlit */ ); break; } case 0x24 /* '$' */ : { match('$' /* charlit */ ); break; } case 0x25 /* '%' */ : { match('%' /* charlit */ ); break; } case 0x26 /* '&' */ : { match('&' /* charlit */ ); break; } case 0x2d /* '-' */ : { match('-' /* charlit */ ); break; } case 0x2e /* '.' */ : { match('.' /* charlit */ ); break; } case 0x30 /* '0' */ : case 0x31 /* '1' */ : case 0x32 /* '2' */ : case 0x33 /* '3' */ : case 0x34 /* '4' */ : case 0x35 /* '5' */ : case 0x36 /* '6' */ : case 0x37 /* '7' */ : case 0x38 /* '8' */ : case 0x39 /* '9' */ : { matchRange('0','9'); break; } case 0x3b /* ';' */ : { match(';' /* charlit */ ); break; } case 0x3f /* '?' */ : { match('?' /* charlit */ ); break; } case 0x40 /* '@' */ : { match('@' /* charlit */ ); break; } case 0x41 /* 'A' */ : case 0x42 /* 'B' */ : case 0x43 /* 'C' */ : case 0x44 /* 'D' */ : case 0x45 /* 'E' */ : case 0x46 /* 'F' */ : case 0x47 /* 'G' */ : case 0x48 /* 'H' */ : case 0x49 /* 'I' */ : case 0x4a /* 'J' */ : case 0x4b /* 'K' */ : case 0x4c /* 'L' */ : case 0x4d /* 'M' */ : case 0x4e /* 'N' */ : case 0x4f /* 'O' */ : case 0x50 /* 'P' */ : case 0x51 /* 'Q' */ : case 0x52 /* 'R' */ : case 0x53 /* 'S' */ : case 0x54 /* 'T' */ : case 0x55 /* 'U' */ : case 0x56 /* 'V' */ : case 0x57 /* 'W' */ : case 0x58 /* 'X' */ : case 0x59 /* 'Y' */ : case 0x5a /* 'Z' */ : { matchRange('A','Z'); break; } case 0x5c /* '\\' */ : { match('\\' /* charlit */ ); break; } case 0x5e /* '^' */ : { match('^' /* charlit */ ); break; } case 0x5f /* '_' */ : { match('_' /* charlit */ ); break; } case 0x60 /* '`' */ : { match('`' /* charlit */ ); break; } case 0x61 /* 'a' */ : case 0x62 /* 'b' */ : case 0x63 /* 'c' */ : case 0x64 /* 'd' */ : case 0x65 /* 'e' */ : case 0x66 /* 'f' */ : case 0x67 /* 'g' */ : case 0x68 /* 'h' */ : case 0x69 /* 'i' */ : case 0x6a /* 'j' */ : case 0x6b /* 'k' */ : case 0x6c /* 'l' */ : case 0x6d /* 'm' */ : case 0x6e /* 'n' */ : case 0x6f /* 'o' */ : case 0x70 /* 'p' */ : case 0x71 /* 'q' */ : case 0x72 /* 'r' */ : case 0x73 /* 's' */ : case 0x74 /* 't' */ : case 0x75 /* 'u' */ : case 0x76 /* 'v' */ : case 0x77 /* 'w' */ : case 0x78 /* 'x' */ : case 0x79 /* 'y' */ : case 0x7a /* 'z' */ : { matchRange('a','z'); break; } default: { goto _loop349; } } } _loop349:; } // ( ... )* if ( inputState->guessing==0 ) { #line 2075 "pf.g" _ttype = WORD; #line 1629 "PFCfgLexer.cpp" } } else { throw ANTLR_USE_NAMESPACE(antlr)NoViableAltForCharException(LA(1), getFilename(), getLine(), getColumn()); } }}} _ttype = testLiteralsTable(_ttype); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mSTRING(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STRING; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\"' /* charlit */ ); { // ( ... )* for (;;) { if ((_tokenSet_5.member(LA(1)))) { matchNot('\"' /* charlit */ ); } else { goto _loop358; } } _loop358:; } // ( ... )* match('\"' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mPIPE_CHAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PIPE_CHAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('|' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mPERCENT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PERCENT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('%' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mAMPERSAND(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = AMPERSAND; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('&' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mAPOSTROPHE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = APOSTROPHE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\'' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mSTAR(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = STAR; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('*' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mPLUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = PLUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('+' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCOMMA(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMA; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(',' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mMINUS(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = MINUS; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('-' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mDOT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('.' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mSLASH(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SLASH; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('/' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mSEMICOLON(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = SEMICOLON; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(';' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mEQUAL(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EQUAL; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('=' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mQUESTION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = QUESTION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('?' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCOMMERCIAL_AT(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = COMMERCIAL_AT; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('@' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mOPENING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('(' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCLOSING_PAREN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_PAREN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(')' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mOPENING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('[' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCLOSING_SQUARE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_SQUARE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match(']' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mOPENING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = OPENING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('{' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCLOSING_BRACE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CLOSING_BRACE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('}' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mCARET(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = CARET; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('^' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mUNDERLINE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = UNDERLINE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('_' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mTILDE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = TILDE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('~' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mEXLAMATION(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = EXLAMATION; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('!' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mLESS_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = LESS_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('<' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mGREATER_THAN(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = GREATER_THAN; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('>' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } void PFCfgLexer::mDOUBLE_QUOTE(bool _createToken) { int _ttype; ANTLR_USE_NAMESPACE(antlr)RefToken _token; ANTLR_USE_NAMESPACE(std)string::size_type _begin = text.length(); _ttype = DOUBLE_QUOTE; ANTLR_USE_NAMESPACE(std)string::size_type _saveIndex; match('\"' /* charlit */ ); if ( _createToken && _token==ANTLR_USE_NAMESPACE(antlr)nullToken && _ttype!=ANTLR_USE_NAMESPACE(antlr)Token::SKIP ) { _token = makeToken(_ttype); _token->setText(text.substr(_begin, text.length()-_begin)); } _returnToken = _token; _saveIndex=0; } const unsigned long PFCfgLexer::_tokenSet_0_data_[] = { 4294958072UL, 1UL, 0UL, 2147483648UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xe 0xf 0x10 0x11 0x12 0x13 0x14 // 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x7f 0x80 0x81 // 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f // 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d // 0x9e 0x9f 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab // 0xac 0xad 0xae 0xaf 0xb0 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 // 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 // 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 // 0xd6 0xd7 0xd8 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 // 0xe4 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 // 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgLexer::_tokenSet_0(_tokenSet_0_data_,16); const unsigned long PFCfgLexer::_tokenSet_1_data_[] = { 0UL, 67043328UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgLexer::_tokenSet_1(_tokenSet_1_data_,10); const unsigned long PFCfgLexer::_tokenSet_2_data_[] = { 0UL, 0UL, 134217726UL, 134217726UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h // i j k l m n o p q r s t u v w x y z const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgLexer::_tokenSet_2(_tokenSet_2_data_,10); const unsigned long PFCfgLexer::_tokenSet_3_data_[] = { 0UL, 67059712UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // . 0 1 2 3 4 5 6 7 8 9 const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgLexer::_tokenSet_3(_tokenSet_3_data_,10); const unsigned long PFCfgLexer::_tokenSet_4_data_[] = { 0UL, 134152192UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0 1 2 3 4 5 6 7 8 9 : A B C D E F a b c d e f const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgLexer::_tokenSet_4(_tokenSet_4_data_,10); const unsigned long PFCfgLexer::_tokenSet_5_data_[] = { 4294967288UL, 4294967291UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 // 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f ! # $ // % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F // G H I J K L M N O P Q R S T U V W X Y Z [ 0x5c ] ^ _ ` a b c d e f g // h i j k l m n o p q r s t u v w x y z { | } ~ 0x7f 0x80 0x81 0x82 0x83 // 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 // 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f // 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad // 0xae 0xaf 0xb0 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb // 0xbc 0xbd 0xbe 0xbf 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 0xc8 0xc9 // 0xca 0xcb 0xcc 0xcd 0xce 0xcf 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 // 0xd8 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 // 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef 0xf0 0xf1 0xf2 0xf3 // 0xf4 0xf5 0xf6 0xf7 0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff const ANTLR_USE_NAMESPACE(antlr)BitSet PFCfgLexer::_tokenSet_5(_tokenSet_5_data_,16); fwbuilder-5.1.0.3599/src/parsers/IOSCfgLexer.hpp0000644000175000017500000000707611733011756022041 0ustar sylvestresylvestre#ifndef INC_IOSCfgLexer_hpp_ #define INC_IOSCfgLexer_hpp_ #line 27 "iosacl.g" // gets inserted before antlr generated includes in the header // file #include "IOSImporter.h" #line 11 "IOSCfgLexer.hpp" #include /* $ANTLR 2.7.7 (20090306): "iosacl.g" -> "IOSCfgLexer.hpp"$ */ #include #include #include #include "IOSCfgParserTokenTypes.hpp" #include #line 33 "iosacl.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include class IOSImporter; #line 28 "IOSCfgLexer.hpp" #line 57 "iosacl.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 34 "IOSCfgLexer.hpp" class CUSTOM_API IOSCfgLexer : public ANTLR_USE_NAMESPACE(antlr)CharScanner, public IOSCfgParserTokenTypes { #line 1 "iosacl.g" #line 38 "IOSCfgLexer.hpp" private: void initLiterals(); public: bool getCaseSensitiveLiterals() const { return true; } public: IOSCfgLexer(ANTLR_USE_NAMESPACE(std)istream& in); IOSCfgLexer(ANTLR_USE_NAMESPACE(antlr)InputBuffer& ib); IOSCfgLexer(const ANTLR_USE_NAMESPACE(antlr)LexerSharedInputState& state); ANTLR_USE_NAMESPACE(antlr)RefToken nextToken(); public: void mLINE_COMMENT(bool _createToken); public: void mWhitespace(bool _createToken); public: void mNEWLINE(bool _createToken); protected: void mINT_CONST(bool _createToken); protected: void mHEX_CONST(bool _createToken); protected: void mNEG_INT_CONST(bool _createToken); protected: void mDIGIT(bool _createToken); protected: void mHEXDIGIT(bool _createToken); public: void mNUMBER(bool _createToken); public: void mDOT(bool _createToken); public: void mWORD(bool _createToken); public: void mSTRING(bool _createToken); public: void mPIPE_CHAR(bool _createToken); public: void mNUMBER_SIGN(bool _createToken); public: void mPERCENT(bool _createToken); public: void mAMPERSAND(bool _createToken); public: void mAPOSTROPHE(bool _createToken); public: void mOPENING_PAREN(bool _createToken); public: void mCLOSING_PAREN(bool _createToken); public: void mSTAR(bool _createToken); public: void mPLUS(bool _createToken); public: void mCOMMA(bool _createToken); public: void mMINUS(bool _createToken); public: void mSLASH(bool _createToken); public: void mCOLON(bool _createToken); public: void mSEMICOLON(bool _createToken); public: void mLESS_THAN(bool _createToken); public: void mEQUALS(bool _createToken); public: void mGREATER_THAN(bool _createToken); public: void mQUESTION(bool _createToken); public: void mCOMMERCIAL_AT(bool _createToken); public: void mOPENING_SQUARE(bool _createToken); public: void mCLOSING_SQUARE(bool _createToken); public: void mCARET(bool _createToken); public: void mUNDERLINE(bool _createToken); public: void mOPENING_BRACE(bool _createToken); public: void mCLOSING_BRACE(bool _createToken); public: void mTILDE(bool _createToken); private: static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; }; #endif /*INC_IOSCfgLexer_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IfconfigBSDCfgParser.hpp0000644000175000017500000000723411733011756023635 0ustar sylvestresylvestre#ifndef INC_IfconfigBSDCfgParser_hpp_ #define INC_IfconfigBSDCfgParser_hpp_ #line 25 "ifconfig_bsd.g" // gets inserted before antlr generated includes in the header // file #include "IfconfigImporter.h" #line 11 "IfconfigBSDCfgParser.hpp" #include /* $ANTLR 2.7.7 (20100319): "ifconfig_bsd.g" -> "IfconfigBSDCfgParser.hpp"$ */ #include #include #include "IfconfigBSDCfgParserTokenTypes.hpp" #include #line 32 "ifconfig_bsd.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class IfconfigImporter; #line 29 "IfconfigBSDCfgParser.hpp" #line 57 "ifconfig_bsd.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 35 "IfconfigBSDCfgParser.hpp" class CUSTOM_API IfconfigBSDCfgParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public IfconfigBSDCfgParserTokenTypes { #line 82 "ifconfig_bsd.g" // additional methods and members public: std::ostream *dbg; IfconfigImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); std::cerr << s << std::endl; } #line 39 "IfconfigBSDCfgParser.hpp" public: void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory ); protected: IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k); public: IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf); protected: IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k); public: IfconfigBSDCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer); IfconfigBSDCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state); int getNumTokens() const { return IfconfigBSDCfgParser::NUM_TOKENS; } const char* getTokenName( int type ) const { if( type > getNumTokens() ) return 0; return IfconfigBSDCfgParser::tokenNames[type]; } const char* const* getTokenNames() const { return IfconfigBSDCfgParser::tokenNames; } public: void cfgfile(); public: void comment(); public: void interface_line(); public: void hwaddr_line(); public: void inet_address(); public: void inet6_address(); public: void groups(); public: void unknown_line(); public: void groups_list(); public: ANTLR_USE_NAMESPACE(antlr)RefAST getAST() { return returnAST; } protected: ANTLR_USE_NAMESPACE(antlr)RefAST returnAST; private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS static const int NUM_TOKENS = 73; #else enum { NUM_TOKENS = 73 }; #endif static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; }; #endif /*INC_IfconfigBSDCfgParser_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/IOSCfgParserTokenTypes.hpp0000644000175000017500000000317511733011756024240 0ustar sylvestresylvestre#ifndef INC_IOSCfgParserTokenTypes_hpp_ #define INC_IOSCfgParserTokenTypes_hpp_ /* $ANTLR 2.7.7 (20090306): "iosacl.g" -> "IOSCfgParserTokenTypes.hpp"$ */ #ifndef CUSTOM_API # define CUSTOM_API #endif #ifdef __cplusplus struct CUSTOM_API IOSCfgParserTokenTypes { #endif enum { EOF_ = 1, NEWLINE = 4, IP = 5, QUIT = 6, ICMP = 7, TCP = 8, HOST = 9, COMMUNITY_LIST = 10, WORD = 11, CERTIFICATE = 12, IOSVERSION = 13, NUMBER = 14, HOSTNAME = 15, STRING = 16, ACCESS_LIST = 17, INT_CONST = 18, EXTENDED = 19, PERMIT = 20, DENY = 21, UDP = 22, P_EQ = 23, P_GT = 24, P_LT = 25, P_NEQ = 26, P_RANGE = 27, IPV4 = 28, ANY = 29, LOG = 30, LOG_INPUT = 31, ESTABLISHED = 32, FRAGMENTS = 33, TIME_RANGE = 34, VLAN = 35, CONTROLLER = 36, INTRFACE = 37, POINT_TO_POINT = 38, DESCRIPTION = 39, REMARK = 40, SHUTDOWN = 41, ACCESS_GROUP = 42, ADDRESS = 43, SECONDARY = 44, EXIT = 45, LINE_COMMENT = 46, STANDARD = 47, Whitespace = 48, HEX_CONST = 49, NEG_INT_CONST = 50, DIGIT = 51, HEXDIGIT = 52, PIPE_CHAR = 53, NUMBER_SIGN = 54, PERCENT = 55, AMPERSAND = 56, APOSTROPHE = 57, OPENING_PAREN = 58, CLOSING_PAREN = 59, STAR = 60, PLUS = 61, COMMA = 62, MINUS = 63, DOT = 64, SLASH = 65, COLON = 66, SEMICOLON = 67, LESS_THAN = 68, EQUALS = 69, GREATER_THAN = 70, QUESTION = 71, COMMERCIAL_AT = 72, OPENING_SQUARE = 73, CLOSING_SQUARE = 74, CARET = 75, UNDERLINE = 76, OPENING_BRACE = 77, CLOSING_BRACE = 78, TILDE = 79, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus }; #endif #endif /*INC_IOSCfgParserTokenTypes_hpp_*/ fwbuilder-5.1.0.3599/src/parsers/PFCfgParser.hpp0000644000175000017500000003136011733011756022062 0ustar sylvestresylvestre#ifndef INC_PFCfgParser_hpp_ #define INC_PFCfgParser_hpp_ #line 25 "pf.g" // gets inserted before antlr generated includes in the header // file #include "PFImporter.h" #line 11 "PFCfgParser.hpp" #include /* $ANTLR 2.7.7 (20100319): "pf.g" -> "PFCfgParser.hpp"$ */ #include #include #include "PFCfgParserTokenTypes.hpp" #include #line 32 "pf.g" // gets inserted after antlr generated includes in the header file // outside any generated namespace specifications #include #include class PFImporter; #line 29 "PFCfgParser.hpp" #line 57 "pf.g" // gets inserted after generated namespace specifications in the // header file. But outside the generated class. #line 35 "PFCfgParser.hpp" class CUSTOM_API PFCfgParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public PFCfgParserTokenTypes { #line 82 "pf.g" // additional methods and members public: std::ostream *dbg; PFImporter *importer; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) { importer->addMessageToLog("Parser error: " + ex.toString()); importer->error_tracker->registerError("Parser error: " + ex.toString()); std::cerr << ex.toString() << std::endl; } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser error: " + s); importer->error_tracker->registerError("Parser error: " + s); std::cerr << s << std::endl; } /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { importer->addMessageToLog("Parser warning: " + s); importer->error_tracker->registerError("Parser warning: " + s); std::cerr << s << std::endl; } #line 39 "PFCfgParser.hpp" public: void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory ); protected: PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k); public: PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf); protected: PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k); public: PFCfgParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer); PFCfgParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state); int getNumTokens() const { return PFCfgParser::NUM_TOKENS; } const char* getTokenName( int type ) const { if( type > getNumTokens() ) return 0; return PFCfgParser::tokenNames[type]; } const char* const* getTokenNames() const { return PFCfgParser::tokenNames; } public: void cfgfile(); public: void comment(); public: void include_command(); public: void macro_definition(); public: void altq_rule(); public: void antispoof_rule(); public: void queue_rule(); public: void set_rule(); public: void scrub_rule(); public: void match_rule(); public: void table_rule(); public: void no_nat_rule(); public: void nat_rule(); public: void rdr_rule(); public: void binat_rule(); public: void pass_rule(); public: void block_rule(); public: void set_timeout(); public: void set_ruleset_optimization(); public: void set_optimization(); public: void set_limit(); public: void set_loginterface(); public: void set_block_policy(); public: void set_state_policy(); public: void set_state_defaults(); public: void set_require_order(); public: void set_fingerprints(); public: void set_skip(); public: void set_debug(); public: void set_reassemble(); public: void set_hostid(); public: void timeout_def(); public: void timeout_def_list(); public: void limit_def(); public: void limit_def_list(); public: void skip_def(); public: void skip_list(); public: void rule_extended(); public: void tableaddr_spec(); public: void logging(); public: void intrface(); public: void address_family(); public: void protospec(); public: void hosts(); public: void tagged(); public: void tag_clause(); public: void redirhost(); public: void redirhost_list(); public: void portspec(); public: void pooltype(); public: void port_def(); public: void block_return(); public: void icmp_code_by_name(); public: void direction(); public: void quick_or_log(); public: void route(); public: void filteropts(); public: void logopts(); public: void logopt(); public: void ifspec(); public: void interface_list(); public: void proto_def(); public: void proto_name(); public: void proto_number(); public: void proto_list(); public: void hosts_from(); public: void hosts_to(); public: void src_hosts_part(); public: void src_port_part(); public: void dst_hosts_part(); public: void dst_port_part(); public: void common_hosts_part(); public: void host(); public: void host_list(); public: void route_to(); public: void reply_to(); public: void dup_to(); public: void routehost(); public: void routehost_list(); public: void filteropt(); public: void user_match(); public: void group_match(); public: void tcp_flags(); public: void icmp_type(); public: void icmp6_type(); public: void state(); public: void queue(); public: void label(); public: void match_rule_scrub_options(); public: void scrub_options(); public: void user_group_op(); public: void user_group_op_list(); public: void unary_op(); public: void binary_op(); public: void scrub_option(); public: void scrub_option_list(); public: void icmp_type_code(); public: void icmp_list(); public: void icmp_type_by_name(); public: void port_op(); public: void port_op_list(); public: ANTLR_USE_NAMESPACE(antlr)RefAST getAST() { return returnAST; } protected: ANTLR_USE_NAMESPACE(antlr)RefAST returnAST; private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS static const int NUM_TOKENS = 262; #else enum { NUM_TOKENS = 262 }; #endif static const unsigned long _tokenSet_0_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0; static const unsigned long _tokenSet_1_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1; static const unsigned long _tokenSet_2_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2; static const unsigned long _tokenSet_3_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3; static const unsigned long _tokenSet_4_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4; static const unsigned long _tokenSet_5_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5; static const unsigned long _tokenSet_6_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6; static const unsigned long _tokenSet_7_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_7; static const unsigned long _tokenSet_8_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_8; static const unsigned long _tokenSet_9_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_9; static const unsigned long _tokenSet_10_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_10; static const unsigned long _tokenSet_11_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_11; static const unsigned long _tokenSet_12_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_12; static const unsigned long _tokenSet_13_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_13; static const unsigned long _tokenSet_14_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_14; static const unsigned long _tokenSet_15_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_15; static const unsigned long _tokenSet_16_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_16; static const unsigned long _tokenSet_17_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_17; static const unsigned long _tokenSet_18_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_18; static const unsigned long _tokenSet_19_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_19; static const unsigned long _tokenSet_20_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_20; static const unsigned long _tokenSet_21_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_21; static const unsigned long _tokenSet_22_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_22; static const unsigned long _tokenSet_23_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_23; static const unsigned long _tokenSet_24_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_24; static const unsigned long _tokenSet_25_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_25; static const unsigned long _tokenSet_26_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_26; static const unsigned long _tokenSet_27_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_27; static const unsigned long _tokenSet_28_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_28; static const unsigned long _tokenSet_29_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_29; static const unsigned long _tokenSet_30_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_30; static const unsigned long _tokenSet_31_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_31; static const unsigned long _tokenSet_32_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_32; static const unsigned long _tokenSet_33_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_33; static const unsigned long _tokenSet_34_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_34; static const unsigned long _tokenSet_35_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_35; static const unsigned long _tokenSet_36_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_36; static const unsigned long _tokenSet_37_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_37; static const unsigned long _tokenSet_38_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_38; static const unsigned long _tokenSet_39_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_39; static const unsigned long _tokenSet_40_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_40; static const unsigned long _tokenSet_41_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_41; static const unsigned long _tokenSet_42_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_42; static const unsigned long _tokenSet_43_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_43; static const unsigned long _tokenSet_44_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_44; static const unsigned long _tokenSet_45_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_45; static const unsigned long _tokenSet_46_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_46; static const unsigned long _tokenSet_47_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_47; static const unsigned long _tokenSet_48_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_48; static const unsigned long _tokenSet_49_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_49; static const unsigned long _tokenSet_50_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_50; static const unsigned long _tokenSet_51_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_51; static const unsigned long _tokenSet_52_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_52; static const unsigned long _tokenSet_53_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_53; static const unsigned long _tokenSet_54_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_54; static const unsigned long _tokenSet_55_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_55; static const unsigned long _tokenSet_56_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_56; static const unsigned long _tokenSet_57_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_57; static const unsigned long _tokenSet_58_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_58; static const unsigned long _tokenSet_59_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_59; static const unsigned long _tokenSet_60_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_60; static const unsigned long _tokenSet_61_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_61; static const unsigned long _tokenSet_62_data_[]; static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_62; }; #endif /*INC_PFCfgParser_hpp_*/ fwbuilder-5.1.0.3599/src/pf/0000755000175000017500000000000011733011756016172 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/pf/pf.pro0000644000175000017500000000124011733011756017316 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # SOURCES = pf.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32:CONFIG += console INCLUDEPATH += ../pflib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../pflib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../pflib/$$BINARY_SUBDIR/libfwbpf.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_pf fwbuilder-5.1.0.3599/src/pf/pf.cpp0000644000175000017500000001142111733011756017302 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include "CompilerDriver_pf.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for OpenBSD PF" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-x] [-v] [-V] [-f filename.xml] [-o output.fw] [-d destdir] [-D datadir] [-m] [-4|-6] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); IPService::addNamedProtocol(112, "carp"); IPService::addNamedProtocol(240, "pfsync"); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->merge(ndb, NULL); delete ndb; objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_pf *driver = new CompilerDriver_pf(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; delete driver; delete objdb; return ret; } catch(const FWException &ex) { cerr << ex.toString() << endl; return 1; #if __GNUC__ >= 3 /* need to check version because std::ios::failure does not seem to be * supported in gcc 2.9.5 on FreeBSD 4.10 */ } catch (const std::ios::failure &e) { cerr << "Error while opening or writing to the output file" << endl; return 1; #endif } catch (const std::string &s) { cerr << s; return 1; } catch (const std::exception &ex) { cerr << ex.what(); return 1; } catch (...) { cerr << "Unsupported exception"; return 1; } } fwbuilder-5.1.0.3599/src/ipf/0000755000175000017500000000000011733011756016343 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/ipf/ipf.cpp0000644000175000017500000001201611733011756017625 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #ifndef _WIN32 # include # include #else # include # include # include #endif #include #include #include #include #include #include #include "CompilerDriver_ipf.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Constants.h" #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; int fwbdebug = 0; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of "; cout << "Firewall Builder. Use fwbuilder GUI to convert it." << endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for ipfilter" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-x] [-v] [-V] [-f filename.xml] [-o output.fw] [-d destdir] [-m] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->merge(ndb, NULL); delete ndb; objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_ipf *driver = new CompilerDriver_ipf(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; delete driver; delete objdb; return ret; } catch(const FWException &ex) { cerr << ex.toString() << endl; return 1; #if __GNUC__ >= 3 /* need to check version because std::ios::failure does not seem to be * supported in gcc 2.9.5 on FreeBSD 4.10 */ } catch (const std::ios::failure &e) { cerr << "Error while opening or writing to the output file" << endl; return 1; #endif } catch (const std::string &s) { cerr << s; return 1; } catch (const std::exception &ex) { cerr << ex.what(); return 1; } catch (...) { cerr << "Unsupported exception"; return 1; } } fwbuilder-5.1.0.3599/src/ipf/ipf.pro0000644000175000017500000000130111733011756017636 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # SOURCES = ipf.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32:CONFIG += console # unix { !macx: CONFIG -= qt } INCLUDEPATH += ../pflib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../pflib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../pflib/$$BINARY_SUBDIR/libfwbpf.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_ipf fwbuilder-5.1.0.3599/src/libfwbuilder/0000755000175000017500000000000011733011756020237 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libfwbuilder/qmake.inc.in0000644000175000017500000000553511733011756022445 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # ######### libfwbuilder/qmake.inc.in # QTDIR = $$(QTDIR) TEMPLATE = lib DEFINES += $$(DEFINES) INCLUDEPATH += .. ../.. $$(INCLUDEPATH) DEPENDPATH += .. ../.. LANGUAGE = C++ HAVE_CPPUNIT = @HAVE_CPPUNIT@ CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@ CPPUNIT_LIBS = @CPPUNIT_LIBS@ CONFIG -= qt QMAKE_CXXFLAGS_DEBUG += -D__STDC_FORMAT_MACROS QMAKE_CXXFLAGS_RELEASE += -D__STDC_FORMAT_MACROS unix { CONFIG += warn_on debug UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj prefix = @prefix@ QMAKE_CXX = @CCACHE@ @DISTCC@ $$QMAKE_CXX # We put /usr/include into INCLUDEPATH to fix a problem compiling # fwbuilder/snmp.cpp on freebsd. INCLUDEPATH += /usr/include @XML_CFLAGS_Q@ @XSLT_CFLAGS_Q@ LIBS += @PTHREAD_LIBS@ @XML_LIBS@ @XSLT_LIBS@ @LIBSNMP_LIBS@ @LIB_RESOLV@ @LIBS@ QMAKE_CFLAGS_DEBUG += -Wno-unused-parameter QMAKE_CFLAGS_RELEASE += -Wno-unused-parameter QMAKE_CXXFLAGS_DEBUG += -Wno-unused-parameter @CXXFLAGS@ QMAKE_CXXFLAGS_RELEASE += -Wno-unused-parameter @CXXFLAGS@ exec_prefix = @EXEC_PREFIX@ DESTDIR = target.path = @LIBDIR@ dtd.path = @RES_DIR@/ migration.path = @RES_DIR@/migration doc.path = @DOCDIR@ } win32 { prefix = "c:/tmp/build_root" DOCDIR = "$$prefix/doc/" exec_prefix = "$$prefix" DESTDIR = "" target.path = "$$prefix/lib" dtd.path = "$$prefix/resources" migration.path = "$$prefix/resources/migration" doc.path = "$$prefix/doc/libfwbuilder" CONFIG -= debug CONFIG += thread rtti stl warn_on release CONFIG += staticlib DEFINES += LIBXML_STATIC LIBXSLT_STATIC INCLUDEPATH += c:/local/include c:/local/include/libxml2 c:/MinGW/include LIBS += -LC:\local\lib # LIBS += ws2_32.lib pthreadVC.lib LIBS += pthreadVC.lib LIBS += libxml2.lib libxslt_a.lib libz.a # zlib.lib } macx { prefix = "$$prefix" DOCDIR = "$$prefix/doc/" exec_prefix = "$$prefix" DESTDIR = # these path definitions are not used since we do not run make install on Mac # (see fwbuilder.def file where it is defined that we don't do that) # But I need to assign these variables some value to make qmake happy. target.path = "$$prefix/lib" dtd.path = "$$prefix/" migration.path = "$$prefix/migration" doc.path = "$$prefix/doc/" CONFIG += x86 # If I build on 10.6 without these, generated binary depends on # /usr/lib/libxml2.2.dynlib that has compatibility version 10.0.0 # which does not work on 10.5 where its compatibility version is # 9.0.0. Chances are, the same thing may be happening with other # dependency libraries. Building on 10.6 with deployment target 10.5 # should solve the problem QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5 QMAKE_MAC_SDK = /Developer/SDKs/MacOSX10.5.sdk QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/ } INSTALLS += target fwbuilder-5.1.0.3599/src/libfwbuilder/.gitignore0000644000175000017500000000002611733011756022225 0ustar sylvestresylvestrelibfwbuilder-config.h fwbuilder-5.1.0.3599/src/libfwbuilder/libfwbuilder.pro0000644000175000017500000000063211733011756023434 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # TEMPLATE = subdirs SUBDIRS = etc migration src DOLLAR = $ build_tests.commands = ./unit_tests.sh make build_tests build_tests.depends = all run_tests.commands = ./unit_tests.sh make run_tests run_tests.depends = all clean_tests.commands = ./unit_tests.sh make clean_tests tests.depends = run_tests QMAKE_EXTRA_TARGETS += build_tests run_tests clean_tests tests fwbuilder-5.1.0.3599/src/libfwbuilder/etc/0000755000175000017500000000000011733011756021012 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libfwbuilder/etc/fwbuilder.dtd0000644000175000017500000004306611733011756023503 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/etc/etc.pro0000644000175000017500000000042711733011756022312 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../qmake.inc) TEMPLATE = lib win32 { CONFIG -= embed_manifest_exe } QMAKE_RUN_CC = @echo QMAKE_RUN_CXX = @echo QMAKE_LINK = @echo QMAKE_LIB = @echo TARGET = etc dtd.files = fwbuilder.dtd INSTALLS -= target INSTALLS += dtd fwbuilder-5.1.0.3599/src/libfwbuilder/etc/fwbuilder.dtd.in0000644000175000017500000004311311733011756024101 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/src/0000755000175000017500000000000011733011756021026 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libfwbuilder/src/src.pro0000644000175000017500000000020211733011756022331 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # TEMPLATE = subdirs CONFIG += ordered TARGET = src SUBDIRS = fwbuilder fwcompiler fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/0000755000175000017500000000000011733011756023175 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/NATCompiler.h0000644000175000017500000004315111733011756025467 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NAT_COMPILER_HH__ #define __NAT_COMPILER_HH__ #include "fwcompiler/Compiler.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include namespace fwcompiler { #define DECLARE_NAT_RULE_PROCESSOR(_Name) \ friend class _Name; \ class _Name : public NATRuleProcessor { \ public: \ _Name(const std::string &n) : \ NATRuleProcessor(n) {}; \ virtual ~_Name() {}; \ virtual bool processNext(); \ }; class NATCompiler : public Compiler { protected: /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); public: NATCompiler(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : Compiler(_db, fw, ipv6_policy, _oscnf) {} virtual int prolog(); /** * detect if rule r2 shades rule r1 * returns: * * true if r2 shades r1 */ bool checkForShadowing(libfwbuilder::NATRule &r1, libfwbuilder::NATRule &r2); /** * detects if rules r1 and r2 are identical (that is, have the * same effect, rather than use the same objects) * * returns: * * true if r1 is identical to r2 */ bool cmpRules(libfwbuilder::NATRule &r1, libfwbuilder::NATRule &r2); /** * this processor assigns NATRuleType value to the rule, thus * classifying it for further processing */ DECLARE_NAT_RULE_PROCESSOR(classifyNATRule); /** * this class expands groups in src,dst,srv. It creates * references to new objects "in place" (that is, it does not * create new rules but rather uses rule elements of the old * ones) */ DECLARE_NAT_RULE_PROCESSOR(ExpandGroups); /** * this inspector replaces hosts and firewalls in src or dst * with references to their interfaces */ DECLARE_NAT_RULE_PROCESSOR(ExpandMultipleAddresses); /** * checks for unnumbered interface in rule elements (one can * not use unnumbered interfaces in rules). Call after * ExpandMultipleAddresses so that we have single object in * each rule element. */ class checkForUnnumbered : public NATRuleProcessor { public: checkForUnnumbered(const std::string &n) : NATRuleProcessor(n) {} virtual bool processNext(); }; /** * this processor splits rule element if src or dst contains * address range */ DECLARE_NAT_RULE_PROCESSOR(ExpandAddressRanges); /** * splits SNAT rule if ODst has multiple objects that belong * to subnets different interfaces of the firewall are on. We * need this to be able to pick interfaces of the firewall * for SNAT rule in ReplaceFirewallObjectsTSrc */ DECLARE_NAT_RULE_PROCESSOR(splitODstForSNAT); /** * this processor converts to atomic rules using all combinations * of objects in OSrc,ODst,TSrc,TDSt. It ignores OSrv and TSrv. */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForAddresses); /** * this processor converts to atomic rules using all * combinations of objects in OSrc,ODst,OSrv. It ignores * all "translated" rule elements. */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForOriginal); /** * this processor converts to atomic rules only for OSrcv */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForOSrv); /** * this processor converts to atomic rules only for TSrc */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForTSrc); /** * this processor converts to atomic rules only for TDst */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForTDst); /** * this processor converts to atomic rules only for TSrv */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForTSrv); /** * this processor converts to atomic rules only for ItfInb */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForItfInb); /** * this processor converts to atomic rules only for ItfOutb */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomicForItfOutb); /** * this processor converts to atomic rules using all combinations * of OSrc,ODst,OSrv,TSrc,TDst,TSrv */ DECLARE_NAT_RULE_PROCESSOR(ConvertToAtomic); /** * single object negation in OSrc */ class singleObjectNegationOSrc : public singleObjectNegation { public: singleObjectNegationOSrc(const std::string &n): singleObjectNegation(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * single object negation in ODst */ class singleObjectNegationODst : public Compiler::singleObjectNegation { public: singleObjectNegationODst(const std::string &n): singleObjectNegation(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * single object negation in ItfInb */ class singleObjectNegationItfInb : public Compiler::singleObjectNegation { public: singleObjectNegationItfInb(const std::string &n): singleObjectNegation(n,libfwbuilder::RuleElementItfInb::TYPENAME) {} }; /** * single object negation in ItfOutb */ class singleObjectNegationItfOutb : public Compiler::singleObjectNegation { public: singleObjectNegationItfOutb(const std::string &n): singleObjectNegation(n,libfwbuilder::RuleElementItfOutb::TYPENAME) {} }; /** * processes rules with negation in ItfOutb */ class ItfOutbNegation : public Compiler::fullInterfaceNegationInRE { public: ItfOutbNegation(const std::string &name) : fullInterfaceNegationInRE( name, libfwbuilder::RuleElementItfOutb::TYPENAME) {} }; /** * processes rules with negation in ItfInb */ class ItfInbNegation : public Compiler::fullInterfaceNegationInRE { public: ItfInbNegation(const std::string &name) : fullInterfaceNegationInRE( name, libfwbuilder::RuleElementItfInb::TYPENAME) {} }; /** * replace cluster interface objects with inetrfaces of the member * firewall in the Interface rule element */ class replaceClusterInterfaceInItfInb : public Compiler::replaceClusterInterfaceInItfRE { public: replaceClusterInterfaceInItfInb(const std::string &name) : replaceClusterInterfaceInItfRE( name, libfwbuilder::RuleElementItfInb::TYPENAME) {} }; /** * replace cluster interface objects with inetrfaces of the member * firewall in the Interface rule element */ class replaceClusterInterfaceInItfOutb : public Compiler::replaceClusterInterfaceInItfRE { public: replaceClusterInterfaceInItfOutb(const std::string &name) : replaceClusterInterfaceInItfRE( name,libfwbuilder::RuleElementItfOutb::TYPENAME) {} }; /** * expand groups in Interface rule element */ DECLARE_NAT_RULE_PROCESSOR(expandGroupsInItfInb); /** * expand groups in Interface rule element */ DECLARE_NAT_RULE_PROCESSOR(expandGroupsInItfOutb); /** * deals with recursive groups in OSrc. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInOSrc : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInOSrc(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * deals with recursive groups in ODst. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInODst : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInODst(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * deals with recursive groups in OSrv. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInOSrv : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInOSrv(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementOSrv::TYPENAME) {} }; /** * deals with recursive groups in TSrc. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInTSrc : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInTSrc(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementTSrc::TYPENAME) {} }; /** * deals with recursive groups in TDst. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInTDst : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInTDst(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementTDst::TYPENAME) {} }; /** * deals with recursive groups in TSrv. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInTSrv : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInTSrv(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementTSrv::TYPENAME) {} }; /** * deals with empty groups in OSrc. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInOSrc : public Compiler::emptyGroupsInRE { public: emptyGroupsInOSrc(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * deals with empty groups in ODst. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInODst : public Compiler::emptyGroupsInRE { public: emptyGroupsInODst(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * deals with empty groups in OSrv. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInOSrv : public Compiler::emptyGroupsInRE { public: emptyGroupsInOSrv(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementOSrv::TYPENAME) {} }; /** * deals with empty groups in TSrc. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInTSrc : public Compiler::emptyGroupsInRE { public: emptyGroupsInTSrc(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementTSrc::TYPENAME) {} }; /** * deals with empty groups in TDst. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInTDst : public Compiler::emptyGroupsInRE { public: emptyGroupsInTDst(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementTDst::TYPENAME) {} }; /** * deals with empty groups in TSrv. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInTSrv : public Compiler::emptyGroupsInRE { public: emptyGroupsInTSrv(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementTSrv::TYPENAME) {} }; /** * splits rule if one of the objects in OSrc is firewall * itself. This is needed because some platforms require * special processing for rules dealing with packets * originated on the firewall, or headed for the firewall * (notably iptables). */ class splitIfOSrcMatchesFw : public Compiler::splitIfRuleElementMatchesFW { public: splitIfOSrcMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * itself. This is needed because some platforms require * special processing for rules dealing with packets * originated on the firewall, or headed for the firewall * (notably iptables). * splits rule if one of the objects in ODst is firewall */ class splitIfODstMatchesFw : public Compiler::splitIfRuleElementMatchesFW { public: splitIfODstMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * splits rule if one of the objects in TSrc is firewall * itself. This is needed because some platforms require * special processing for rules dealing with packets * originated on the firewall, or headed for the firewall * (notably iptables). */ class splitIfTSrcMatchesFw : public Compiler::splitIfRuleElementMatchesFW { public: splitIfTSrcMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementTSrc::TYPENAME) {} }; /** * splits rule if one of the objects in TDst is firewall * itself. This is needed because some platforms require * special processing for rules dealing with packets * originated on the firewall, or headed for the firewall * (notably iptables). */ class splitIfTDstMatchesFw : public Compiler::splitIfRuleElementMatchesFW { public: splitIfTDstMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementTDst::TYPENAME) {} }; /** * many firewall platforms do not support filtering by MAC * addresses. Issue warning if MAC address is used in the rule * and remove it from the rule element. * * Call this processor after ExpandMultipleAddresses. */ class MACFiltering : public NATRuleProcessor { protected: std::string last_rule_lbl; /* return value: * true - ok * false - one or more MAC addresses have been removed, issue warning */ bool checkRuleElement(libfwbuilder::RuleElement *re); public: MACFiltering(const std::string &n) : NATRuleProcessor(n) {} virtual bool processNext(); }; /** * rule processors that replace MultiAddress objects with * MultiAddressRunTime equivalents */ class swapMultiAddressObjectsInOSrc : public Compiler::swapMultiAddressObjectsInRE { public: swapMultiAddressObjectsInOSrc(const std::string &n) : swapMultiAddressObjectsInRE( n, libfwbuilder::RuleElementOSrc::TYPENAME) {} }; class swapMultiAddressObjectsInODst : public Compiler::swapMultiAddressObjectsInRE { public: swapMultiAddressObjectsInODst(const std::string &n) : swapMultiAddressObjectsInRE( n, libfwbuilder::RuleElementODst::TYPENAME) {} }; class swapMultiAddressObjectsInTSrc : public Compiler::swapMultiAddressObjectsInRE { public: swapMultiAddressObjectsInTSrc(const std::string &n) : swapMultiAddressObjectsInRE( n, libfwbuilder::RuleElementTSrc::TYPENAME) {} }; class swapMultiAddressObjectsInTDst : public Compiler::swapMultiAddressObjectsInRE { public: swapMultiAddressObjectsInTDst(const std::string &n) : swapMultiAddressObjectsInRE( n, libfwbuilder::RuleElementTDst::TYPENAME) {} }; class RegisterGroupsAndTablesInOSrc : public RegisterGroupsAndTablesInRE { public: RegisterGroupsAndTablesInOSrc(const std::string &n) : RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementOSrc::TYPENAME) {} }; class RegisterGroupsAndTablesInODst : public RegisterGroupsAndTablesInRE { public: RegisterGroupsAndTablesInODst(const std::string &n) : RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementODst::TYPENAME) {} }; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Compiler_object_match.cpp0000644000175000017500000001345311733011756030163 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "Compiler.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/ObjectMatcher.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; bool Compiler::complexMatch(Address *obj1, Address *obj2, bool recognize_broadcasts, bool recognize_multicasts) { if (obj1==NULL || obj2==NULL) return false; ObjectMatcher om; om.setRecognizeBroadcasts(recognize_broadcasts); om.setRecognizeMulticasts(recognize_multicasts); om.setIPV6(ipv6); return om.complexMatch(obj1, obj2); } /** * This method finds interface of obj2 (which is usually * firewall object, but not necessarily so) which is connected * to the subnet on which obj1 is located. */ Interface* Compiler::findInterfaceFor(const Address *obj1, const Address *obj2) { list interfaces = obj2->getByTypeDeep(Interface::TYPENAME); list::iterator j; for (j=interfaces.begin(); j!=interfaces.end(); ++j ) { Interface *iface=Interface::cast(*j); assert(iface); if (iface->getId() == obj1->getId()) return iface; if ( iface->isRegular() && obj1->getAddressPtr() != NULL) { if (obj1->getAddressPtr()->isV4()) { FWObjectTypedChildIterator k= iface->findByType(IPv4::TYPENAME); for ( ; k!=k.end(); ++k ) { Address *addr = Address::cast(*k); assert(addr); if (checkIfAddressesMatch(addr, obj1)) return iface; } } if (obj1->getAddressPtr()->isV6()) { FWObjectTypedChildIterator k= iface->findByType(IPv6::TYPENAME); for ( ; k!=k.end(); ++k ) { Address *addr = Address::cast(*k); assert(addr); if (checkIfAddressesMatch(addr, obj1)) return iface; } } } } return NULL; } FWObject* Compiler::findAddressFor(const Address *obj1, const Address *obj2) { list interfaces = obj2->getByTypeDeep(Interface::TYPENAME); list::iterator j; for (j=interfaces.begin(); j!=interfaces.end(); ++j ) { Interface *iface=Interface::cast(*j); assert(iface); if (iface->getId() == obj1->getId() ) return iface; if ( iface->isRegular() && obj1->getAddressPtr()) { if (obj1->getAddressPtr()->isV4()) { FWObjectTypedChildIterator k= iface->findByType(IPv4::TYPENAME); for ( ; k!=k.end(); ++k ) { Address *addr = Address::cast(*k); assert(addr); if (checkIfAddressesMatch(addr, obj1)) return (*k); } } if (obj1->getAddressPtr()->isV6()) { FWObjectTypedChildIterator k= iface->findByType(IPv6::TYPENAME); for ( ; k!=k.end(); ++k ) { Address *addr = Address::cast(*k); assert(addr); if (checkIfAddressesMatch(addr, obj1)) return (*k); } } } } return NULL; } bool Compiler::checkIfAddressesMatch(const Address *a1, const Address *a2) { if (a1->getId() == a2->getId()) return true; if (*(a1->getAddressPtr()) == *(a2->getAddressPtr()) ) return true; if ((Network::constcast(a2)!=NULL || NetworkIPv6::constcast(a2)!=NULL || Interface::constcast(a2->getParent())) && a2->belongs(*(a1->getAddressPtr()))) return true; if ((Network::constcast(a1)!=NULL || NetworkIPv6::constcast(a1)!=NULL || Interface::constcast(a1->getParent())) && a1->belongs(*(a2->getAddressPtr()))) return true; return false; } bool Compiler::MatchesAddressFamily(FWObject *o) { if (Address::cast(o)) { const InetAddr *inet_addr = Address::cast(o)->getAddressPtr(); if (inet_addr) { if (ipv6) { if (inet_addr->isV6()) return true; } else { if (inet_addr->isV4()) return true; } } else { // Address object with no ip address (e.g. dynamic interface // or run-time address table) return true; } return false; } // not an address object at all return true; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/RoutingCompiler.cpp0000644000175000017500000007071311733011756027033 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "RoutingCompiler.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPRoute.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/MultiAddress.h" #include #include #include #include #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; int RoutingCompiler::prolog() { Compiler::prolog(); Routing *routing = Routing::cast(fw->getFirstByType(Routing::TYPENAME)); assert(routing); if (source_ruleset == NULL) source_ruleset = routing; source_ruleset->renumberRules(); temp_ruleset = new Routing(); // working copy of the routing fw->add( temp_ruleset ); temp_ruleset->setName(source_ruleset->getName()); int rule_counter = 0; for (FWObject::iterator i=source_ruleset->begin(); i!=source_ruleset->end(); i++) { Rule *r = Rule::cast(*i); if (r == NULL) continue; // skip RuleSetOptions object if (r->getLabel().empty()) r->setLabel( createRuleLabel("", "main", r->getPosition()) ); rule_counter++; } initialized = true; return rule_counter; } bool RoutingCompiler::cmpRules(const RoutingRule &r1, const RoutingRule &r2) { if (r1.getRDst()!=r2.getRDst()) return false; if (r1.getRGtw()!=r2.getRGtw()) return false; if (r1.getRItf()!=r2.getRItf()) return false; return true; } string RoutingCompiler::debugPrintRule(Rule *r) { RoutingRule *rule = RoutingRule::cast(r); RuleElementRDst *dstrel = rule->getRDst(); RuleElementRItf *itfrel = rule->getRItf(); RuleElementRGtw *gtwrel = rule->getRGtw(); ostringstream str; // str << setw(70) << setfill('-') << "-"; string dst, itf, gtw; FWObject *obj = FWReference::getObject(itfrel->front()); itf = (obj) ? obj->getName() : "NULL"; obj = FWReference::getObject(gtwrel->front()); gtw = (obj) ? obj->getName() : "NULL"; int no = 0; FWObject::iterator i1 = dstrel->begin(); while ( i1!=dstrel->end()) { str << endl; dst = " "; if (i1 != dstrel->end()) { FWObject *o = FWReference::getObject(*i1); dst = (o) ? o->getName() : "NULL"; } int w = 0; if (no==0) { str << rule->getLabel(); w = rule->getLabel().length(); } str << setw(10-w) << setfill(' ') << " "; str << setw(18) << setfill(' ') << dst.c_str() << " "; str << setw(18) << setfill(' ') << itf.c_str() << " "; str << setw(18) << setfill(' ') << gtw.c_str() << " "; str << setw(18) << setfill(' ') << " "; ++no; if ( i1 != dstrel->end() ) ++i1; } return str.str(); } bool RoutingCompiler::ExpandMultipleAddresses::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRDst *dst = rule->getRDst(); assert(dst); RuleElementRGtw *gtw = rule->getRGtw(); assert(gtw); compiler->_expand_addr(rule, dst, true); compiler->_expand_addr(rule, gtw, false); return true; } bool RoutingCompiler::ConvertToAtomicForDST::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; //RuleElementSrc *src=rule->getSrc(); assert(src); RuleElementRDst *dst=rule->getRDst(); assert(dst); for (FWObject::iterator it=dst->begin(); it!=dst->end(); ++it) { RoutingRule *r = compiler->dbcopy->createRoutingRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s = r->getRDst(); assert(s); s->clearChildren(); s->addRef(FWReference::getObject(*it)); tmp_queue.push_back(r); } return true; } bool RoutingCompiler::ExpandGroups::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRDst *dst=rule->getRDst(); assert(dst); compiler->expandGroupsInRuleElement(dst); return true; } bool RoutingCompiler::emptyRDstAndRItf::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRGtw *gtwrel=rule->getRGtw(); RuleElementRItf *itfrel=rule->getRItf(); if ( (FWReference::cast(itfrel->front())->getPointer())->getName()=="Any" &&\ (FWReference::cast(gtwrel->front())->getPointer())->getName()=="Any") { string msg; msg = "Gateway and interface are both empty in the rule"; compiler->abort(rule, msg.c_str()); } return true; } bool RoutingCompiler::singleAdressInRGtw::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRGtw *gtwrel=rule->getRGtw(); FWObject *o = FWReference::getObject(gtwrel->front()); if( gtwrel->checkSingleIPAdress(o) == false) { string msg; msg = "Object \"" + o->getName() + "\" used as a gateway in the routing rule " + rule->getLabel() + " has multiple ip adresses"; compiler->abort(rule, msg.c_str()); } return true; } // recursive network validity check bool RoutingCompiler::validateNetwork::checkValidNetwork(FWObject *o) { if( Network::cast(o) != NULL) { return ((Network *)o)->isValidRoutingNet(); } /* if we have a group containing networks and groups, we want to check them too */ if( ObjectGroup::cast(o) != NULL) { FWObjectTypedChildIterator child_i = o->findByType(FWObjectReference::TYPENAME); for ( ; child_i != child_i.end(); ++child_i) { FWObjectReference *child_r = FWObjectReference::cast(*child_i); assert(child_r); FWObject *child = child_r->getPointer(); Network *network; ObjectGroup *group; // Network if ((network=Network::cast(child)) != NULL) { if (checkValidNetwork(network) == false) { return false; } } else if ((group=ObjectGroup::cast(child)) != NULL) { // Group if (checkValidNetwork(group) == false) { return false; } } } } return true; } // Invalid routing destination network: network address and netmask mismatch. bool RoutingCompiler::validateNetwork::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRDst *dstrel=rule->getRDst(); FWObject *o = FWReference::cast(dstrel->front())->getPointer(); // currently we do not support run-time DNSName and AddressTable objects // in routing rules. MultiAddress *ma = MultiAddress::cast(o); if (ma && ma->isRunTime()) { compiler->abort(rule, "Use of dynamic run-time objects " "as destination in routing rules is not supported."); } if( checkValidNetwork(o) == false) { string msg; msg = "Object \"" + o->getName() + "\" used as destination in the routing rule " + rule->getLabel() + " has invalid netmask"; compiler->abort(rule, msg.c_str()); } return true; } // the IP address of the gateway has to be in a local network of the firewall bool RoutingCompiler::reachableAddressInRGtw::checkReachableIPAddress(FWObject *o) { // let's walk over all interfaces of this firewall list interfaces = compiler->fw->getByTypeDeep(Interface::TYPENAME); list::iterator intf; if( Host::cast(o) != NULL) { Host *host=Host::cast(o); const InetAddr *ip_host = host->getAddressPtr(); for (intf = interfaces.begin(); intf!=interfaces.end(); ++intf) { Interface *i_firewall = Interface::cast(*intf); for(FWObjectTypedChildIterator fw_ips = i_firewall->findByType(IPv4::TYPENAME); fw_ips!=fw_ips.end(); ++fw_ips) { IPv4 *ipv4_obj_firewall = IPv4::cast(*fw_ips); const InetAddr *addr = ipv4_obj_firewall->getAddressPtr(); const InetAddr *netm = ipv4_obj_firewall->getNetmaskPtr(); if (addr) { InetAddrMask fw_net(*addr, *netm); if (fw_net.belongs(*ip_host)) return true; } } } return false; } else if( Interface::cast(o) != NULL) { Interface *gw_interface=Interface::cast(o); const InetAddr *ip_gateway = gw_interface->getAddressPtr(); // walk over all interfaces of this firewall for (intf = interfaces.begin(); intf!=interfaces.end(); ++intf) { Interface *if_firewall=Interface::cast(*intf); FWObjectTypedChildIterator addresses = if_firewall->findByType(IPv4::TYPENAME); // check all IPv4 addresses of this firewall interface for ( ; addresses!=addresses.end(); ++addresses ) { IPv4 *ipv4_obj_firewall = IPv4::cast(*addresses); const InetAddr *addr = ipv4_obj_firewall->getAddressPtr(); const InetAddr *netm = ipv4_obj_firewall->getNetmaskPtr(); if (addr) { InetAddrMask fw_net(*addr, *netm); if (fw_net.belongs(*ip_gateway)) return true; } } } return false; } else if( IPv4::cast(o) != NULL) { IPv4 *ipv4=IPv4::cast(o); const InetAddr *ip_ipv4 = ipv4->getAddressPtr(); for (intf = interfaces.begin(); intf!=interfaces.end(); ++intf) { Interface *if_firewall=Interface::cast(*intf); FWObjectTypedChildIterator addresses = if_firewall->findByType(IPv4::TYPENAME); // check all IPv4 addresses of this firewall interface for ( ; addresses!=addresses.end(); ++addresses ) { IPv4 *ipv4_obj_firewall = IPv4::cast(*addresses); const InetAddr *addr = ipv4_obj_firewall->getAddressPtr(); const InetAddr *netm = ipv4_obj_firewall->getNetmaskPtr(); if (addr) { InetAddrMask fw_net(*addr, *netm); if (fw_net.belongs(*ip_ipv4)) return true; } } } return false; } else return true; return false; } // the IP address of the gateway has to be in a local network of the firewall bool RoutingCompiler::reachableAddressInRGtw::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRGtw *gtwrel=rule->getRGtw(); FWObject *o = FWReference::cast(gtwrel->front())->getPointer(); if( checkReachableIPAddress(o) == false) { string msg; msg = "Object \"" + o->getName() + "\" used as gateway in the routing rule " + rule->getLabel() + " is not reachable because it is not in any local network of the firewall"; compiler->abort(rule, msg.c_str()); } return true; } // the IP address of the gateway RGtw has to be in a network of the interface RItf bool RoutingCompiler::contradictionRGtwAndRItf::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRGtw *gtwrel=rule->getRGtw(); RuleElementRItf *itfrel=rule->getRItf(); FWObject *oRGtw = FWReference::cast(gtwrel->front())->getPointer(); FWObject *oRItf = FWReference::cast(itfrel->front())->getPointer(); if (oRItf->getName() == "Any") { return true; } if (Host::cast(oRGtw) != NULL || Interface::cast(oRGtw) != NULL || Address::cast(oRGtw)->dimension()==1) { const InetAddr* ip_interface = NULL; if ( Host::cast(oRGtw) != NULL) { Host *host=Host::cast(oRGtw); ip_interface = host->getAddressPtr(); } else if (Interface::cast(oRGtw) != NULL) { Interface *intf=Interface::cast(oRGtw); ip_interface = intf->getAddressPtr(); } else if (Address::cast(oRGtw)->dimension()==1) { Address *ipv4 = Address::cast(oRGtw); ip_interface = ipv4->getAddressPtr(); } if (ip_interface) { list obj_list = oRItf->getByType(IPv4::TYPENAME); for (list::iterator i=obj_list.begin(); i!=obj_list.end(); ++i) { Address *addr = Address::cast(*i); if (addr->belongs(*ip_interface)) return true; } } string msg; msg = "Object \"" + oRGtw->getName() + "\" used as gateway in the routing rule " + rule->getLabel() + " is not in the same local network as interface " + oRItf->getName(); compiler->abort(rule, msg.c_str()); } return true; } bool RoutingCompiler::interfaceOrGateway::processNext() { RoutingRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRItf *itfrel = rule->getRItf(); RuleElementRGtw *gtwrel = rule->getRGtw(); if (!itfrel->isAny() && !gtwrel->isAny()) { compiler->abort(rule, "Use either gateway or interface in a routing rule " "but not both at the same time"); } return true; } bool RoutingCompiler::rItfChildOfFw::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRItf *itfrel = rule->getRItf(); if (itfrel->isAny()) return true; FWObject *o = FWReference::cast(itfrel->front())->getPointer(); // the interface is not a child of the firewall. Could be // cluster interface though. In that case make sure the // firewall is a member of that cluster. Interface *iface = Interface::cast(o); if (iface) { FWObject *parent = Host::getParentHost(iface); //FWObject *parent = iface->getParentHost(); if (parent->getId() == compiler->fw->getId()) return true; Cluster *cluster = Cluster::cast(parent); if (cluster) { list members; cluster->getMembersList(members); list::iterator it; for (it=members.begin(); it!=members.end(); ++it) { if ((*it)->getId() == compiler->fw->getId()) return true; } } } string msg; msg = "Object \"" + o->getName() + "\" used as interface in the routing rule " + rule->getLabel() + " is not a child of the firewall the rule belongs to"; compiler->abort(rule, msg.c_str()); // even though we call abort() here, it does not actually stop the // program if it runs in the test mode. return true; } /* * Call this after converting to atomic rules by DST to be sure there * is just one object in DST. */ bool RoutingCompiler::sameDestinationDifferentGateways::processNext() { slurp(); if (tmp_queue.size()==0) return false; // map destination to gateway. std::map dst_to_gw; std::map dst_to_rule; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { RoutingRule *rule = RoutingRule::cast( *k ); RuleElementRDst *dstrel = rule->getRDst(); Address *dst = Address::cast(FWReference::getObject(dstrel->front())); const InetAddr* dst_addr = dst->getAddressPtr(); const InetAddr* dst_netm = dst->getNetmaskPtr(); string key = dst_addr->toString() + "/" + dst_netm->toString(); // RuleElementRItf *itfrel = rule->getRItf(); // FWObject *itf = FWReference::cast(itfrel->front())->getPointer(); RuleElementRGtw *gtwrel = rule->getRGtw(); Address *gtw = Address::cast(FWReference::getObject(gtwrel->front())); const InetAddr* gtw_addr = gtw->getAddressPtr(); const InetAddr* gtw_netm = gtw->getNetmaskPtr(); string val = gtw_addr->toString() + "/" + gtw_netm->toString(); if (!dst_to_gw[key].empty() && dst_to_gw[key] != val) { compiler->abort( rule, "Rules " + dst_to_rule[key] + " and " + rule->getLabel() + " define routes to the same destination " + key + " via different gateways. This configuration is not supported" " for " + compiler->fw->getStr("host_OS")); } else { dst_to_gw[key] = val; dst_to_rule[key] = rule->getLabel(); } } return true; } bool RoutingCompiler::competingRules::processNext() { RoutingRule *rule = getNext(); if (rule==NULL) return false; RuleElementRItf *itfrel = rule->getRItf(); FWObject *itf = FWReference::cast(itfrel->front())->getPointer(); RuleElementRGtw *gtwrel = rule->getRGtw(); FWObject *gtw = FWReference::cast(gtwrel->front())->getPointer(); string metric = rule->getMetricAsString(); string label = rule->getSortedDstIds(); ostringstream ostr; ostr << gtw->getId() << "_" << itf->getId(); string combiId = ostr.str(); if( label == "") compiler->abort( rule, "Place 'createSortedDstIdsLabel()' before 'competingRules()' " "in the rule processor chain"); dest_it = rules_seen_so_far.find(label); if( dest_it != rules_seen_so_far.end()) { // a rule with the same destination was already seen ///std::cout << "NO NEW DEST" << std::endl; gtwitf_it = dest_it->second.find(combiId); if( gtwitf_it != dest_it->second.end() ) { // ... this gateway and interface combination were already // seen for this destination ///std::cout << "NO NEW GTWITF" << std::endl; if( gtwitf_it->second.first == metric) { // ... and same metric => rule already exists, skip ///std::cout << "SAME METRIC" << std::endl; string msg; msg = "Routing rules " + gtwitf_it->second.second + " and " + rule->getLabel() + " are identical, skipping the second one. " + "Delete one of them to avoid this warning"; compiler->warning(rule, msg.c_str()); } else { // ... but different metric => what metric should I use? => abort ///std::cout << "DIFFERENT METRIC" << std::endl; string msg; msg = "Routing rules " + gtwitf_it->second.second + " and " + rule->getLabel() + " are identical except for the metric, " + "please delete one of them"; compiler->abort(rule, msg.c_str()); } } else { // ... this gateway and interface combination is new for // this destination ///std::cout << "NEW GTWITF" << std::endl;/// if(false) { // TODO_lowPrio: if ( // !compiler->fw->getOptionsObject()->getBool // ("equal_cost_multi_path") ) ...If multipath is // turned off, perform this check. // iterate all gtwitf combis in the map // dest_it->second and search for the current metric // ... but has the same metric => what route should I // use for this destination? => abort string msg; msg = "Routing rules " + gtwitf_it->second.second + " and " + rule->getLabel() + " have the same destination and same metric," "but different gateway and interface combination. " "Set the metrics to different values or " "enable ECMP (Equal Cost MultiPath) routing"; compiler->abort( msg.c_str() ); } else { // ... and different metric OR equal_cost_multi_path enabled => OK tmp_queue.push_back(rule); } dest_it->second[combiId] = pair< string, string>( metric, rule->getLabel()); } } else { // this destination is new //std::cout << "NEW DEST" << std::endl; /// //ruleinfo tmpRuleInfo = { gtw->getStr("id") + itf->getStr("id"), metric, rule->getLabel()}; //rules_seen_so_far[label] = tmpRuleInfo; map< string, pair< string, string> > gtw_itf_tmp; gtw_itf_tmp[combiId] = pair< string, string>( metric, rule->getLabel()); rules_seen_so_far[label] = gtw_itf_tmp; tmp_queue.push_back(rule); } return true; } bool RoutingCompiler::classifyRoutingRules::processNext() { assert(compiler!=NULL); assert(prev_processor!=NULL); slurp(); if (tmp_queue.size()==0) return false; for (std::deque::iterator tmp_queue_it=tmp_queue.begin(); tmp_queue_it!=tmp_queue.end(); ++tmp_queue_it) { RoutingRule *rule = RoutingRule::cast( *tmp_queue_it); rule->setRuleType( RoutingRule::SinglePath); RuleElementRItf *itfrel=rule->getRItf(); FWObject *itf = FWReference::cast(itfrel->front())->getPointer(); RuleElementRGtw *gtwrel=rule->getRGtw(); FWObject *gtw = FWReference::cast(gtwrel->front())->getPointer(); string metric = rule->getMetricAsString(); string label = rule->getSortedDstIds(); ostringstream ostr; ostr << gtw->getId() << "_" << itf->getId(); string combiId = ostr.str(); if( label == "") compiler->abort( rule, "Place 'createSortedDstIdsLabel()' right before " "'classifyRoutingRules()' in the rule processor chain"); dest_it = rules_seen_so_far.find(label); if( dest_it != rules_seen_so_far.end()) { // a rule with the same destination was already seen //std::cout << "classifyRoutingRules:NO NEW DEST" << std::endl;/// gtwitf_it = dest_it->second.find(combiId); if( gtwitf_it == dest_it->second.end() ) { // ... this gateway and interface combination is new for this destination //std::cout << "classifyRoutingRules:NEW GTWITF" << std::endl;/// for( gtwitf_it = dest_it->second.begin(); gtwitf_it != dest_it->second.end(); gtwitf_it++) { if( gtwitf_it->second.first == metric) { // ... but has the same metric as another rule with this Dst => multipath or abort //std::cout << "classifyRoutingRules:SAME METRIC" << std::endl;/// if(true) { //TODO: if ( compiler->fw->getOptionsObject()->getBool ("equal_cost_multi_path") ) rule->setRuleType( RoutingRule::MultiPath); gtwitf_it->second.second->setRuleType( RoutingRule::MultiPath); //std::cout << "classifyRoutingRules:the rules " << rule->getLabel() << " and " << gtwitf_it->second.second->getLabel() << " were set to multipath." << std::endl;/// } } } dest_it->second[combiId] = pair< string, RoutingRule*>( metric, rule); } } else { // this destination is new //std::cout << "classifyRoutingRules:NEW DEST" << std::endl;/// map< string, pair< string, RoutingRule*> > gtw_itf_tmp; gtw_itf_tmp[combiId] = pair< string, RoutingRule*>( metric, rule); rules_seen_so_far[label] = gtw_itf_tmp; } } return true; } bool RoutingCompiler::createSortedDstIdsLabel::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); // create a label with a sorted dst-id-list, to find identical destinations even if the order // of the dst objects differs within one rule RuleElementRDst *dstrel=rule->getRDst(); string label = rule->getLabel(); int bracepos = label.find("("); label.erase(0, bracepos); std::list idList; for (FWObject::iterator it=dstrel->begin(); it!=dstrel->end(); ++it) { idList.insert(idList.end(), FWObjectDatabase::getStringId( (FWReference::cast(*it)->getPointer())->getId())); } idList.sort(); for (std::list::iterator it=idList.begin(); it!=idList.end(); ++it) { label += " " + *it; } ///std::cout << "createDstLabel:LABEL: '" << label << "'" << endl; rule->setSortedDstIds( label); return true; } /* * This is identical to * PolicyCompiler_ipf::processMultiAddressObjectsInRE::processNext() * TODO: move the code to the class Compiler so it can be reused. */ bool RoutingCompiler::processMultiAddressObjectsInRE::processNext() { RoutingRule *rule = getNext(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) compiler->abort( rule, "Run-time AddressTable objects are not supported."); AddressTable *at = AddressTable::cast(o); if (at && at->isRunTime()) compiler->abort( rule, "Run-time AddressTable objects are not supported."); } tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Compiler_helpers.cpp0000644000175000017500000000125511733011756027200 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "Compiler.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Network.h" #include "fwbuilder/Service.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWServiceReference.h" using namespace fwcompiler; using namespace libfwbuilder; fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Compiler.cpp0000644000175000017500000015512711733011756025466 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include "Compiler.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; int Compiler::prolog() { temp = new Group(); temp->setName("Temp Group"); fw->add(temp, false); return 0; } void Compiler::epilog() { } void Compiler::abort(const string &errstr) throw(FWException) { BaseCompiler::abort(fw, source_ruleset, NULL, errstr); } void Compiler::abort(FWObject *rule, const string &errstr) throw(FWException) { BaseCompiler::abort(fw, source_ruleset, rule, errstr); } void Compiler::error(const string &errstr) { BaseCompiler::error(fw, source_ruleset, NULL, errstr); } void Compiler::error(FWObject *rule, const string &errstr) { BaseCompiler::error(fw, source_ruleset, rule, errstr); } void Compiler::warning(const string &errstr) { BaseCompiler::warning(fw, source_ruleset, NULL, errstr); } void Compiler::warning(FWObject *rule, const string &errstr) { BaseCompiler::warning(fw, source_ruleset, rule, errstr); } int Compiler::getCompiledScriptLength() { return int(output.tellp()); } string Compiler::getCompiledScript() { string res; res=output.str(); /* * NB: according to Rogue Wave docs, method basic_stringbuf::seekpos is public, * however implementation that comes with g++ 3.x declares it as protected * * Method str(const char*) is not described in Rogue Wave docs at * all. Stroustrup does not methion it either. */ // output.rdbuf()->seekpos(0); output.str(""); return res; } void Compiler::_init(FWObjectDatabase *_db, Firewall *_fw) { initialized = false; _cntr_ = 1; group_registry = NULL; temp_ruleset = NULL; debug = 0; debug_rule = -1; rule_debug_on = false; verbose = true; single_rule_mode = false; single_rule_ruleset_name = ""; single_rule_position = -1; dbcopy = NULL; persistent_objects = NULL; fw = NULL; fwopt = NULL; fw_id = -1; if (_db != NULL && _fw != NULL) { assert(_fw->getRoot() == _db); dbcopy = _db; fw = _fw; fwopt = fw->getOptionsObject(); fw_id = fw->getId(); // string fw_str_id = FWObjectDatabase::getStringId(_fw->getId()); // dbcopy = new FWObjectDatabase(*_db); // copies entire tree // fw = Firewall::cast( // dbcopy->findInIndex(FWObjectDatabase::getIntId(fw_str_id))); // fwopt = fw->getOptionsObject(); // fw_id = fw->getId(); } } Compiler::Compiler(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy) { source_ruleset = NULL; ruleSetName = ""; osconfigurator = NULL; countIPv6Rules = 0; ipv6 = ipv6_policy; persistent_objects = NULL; _init(_db, fw); } Compiler::Compiler(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf) { source_ruleset = NULL; ruleSetName = ""; osconfigurator = _oscnf; countIPv6Rules = 0; ipv6 = ipv6_policy; persistent_objects = NULL; _init(_db, fw); } // this constructor is used by class Preprocessor, it does not call _init Compiler::Compiler(FWObjectDatabase*, bool ipv6_policy) { source_ruleset = NULL; ruleSetName = ""; osconfigurator = NULL; countIPv6Rules = 0; ipv6 = ipv6_policy; initialized = false; _cntr_ = 1; persistent_objects = NULL; fw = NULL; temp_ruleset = NULL; debug = 0; debug_rule = -1; rule_debug_on = false; verbose = true; single_rule_mode = false; } Compiler::~Compiler() { deleteRuleProcessors(); dbcopy = NULL; } void Compiler::setPersistentObjects(Library* po) { persistent_objects = po; dbcopy->reparent(persistent_objects); persistent_objects->fixTree(); } void Compiler::setSourceRuleSet(RuleSet *rs) { FWObject *copy_rs = dbcopy->findInIndex(rs->getId()); source_ruleset = RuleSet::cast(copy_rs); } void Compiler::setSingleRuleCompileMode(const string &rule_id) { if (!rule_id.empty()) { Rule *rule = Rule::cast( dbcopy->findInIndex(FWObjectDatabase::getIntId(rule_id))); if (rule) { single_rule_mode = true; single_rule_compile_rule = rule; single_rule_position = rule->getPosition(); single_rule_ruleset_name = rule->getParent()->getName(); } } } string Compiler::createRuleLabel(const std::string &prefix, const string &txt, int rule_num) { ostringstream str; if (!prefix.empty()) str << prefix << " "; str << rule_num << " "; str << "(" << txt << ")"; return str.str(); } string Compiler::getUniqueRuleLabel() { ostringstream str; str << "R_" << _cntr_; _cntr_++; return str.str(); } void Compiler::compile() { assert(fw); } void Compiler::_expand_group_recursive(FWObject *o, list &ol) { /* * ref #50: ignore various Options child objects. In particular this * skips ClusterGroupOptions object which is a child of * FailoverClusterGroup and StateSyncClusterGroup objects. */ if (FWOptions::cast(o)) return; /* special case: MultiAddress. This class inherits ObjectGroup, but * should not be expanded if it is expanded at run time * * This is now redundant since we use class MultiAddressRunTime for * run-time address tables */ MultiAddress *adt = MultiAddress::cast(o); if ((Group::cast(o)!=NULL && adt==NULL) || (adt!=NULL && adt->isCompileTime())) { for (FWObject::iterator i2=o->begin(); i2!=o->end(); ++i2) { FWObject *o1 = FWReference::getObject(*i2); assert(o1); _expand_group_recursive(o1, ol); } } else { if (o->getId() == FWObjectDatabase::ANY_ADDRESS_ID) { o->ref(); ol.push_back( o ); } else { Address *oaddr = Address::cast(o); if (oaddr && oaddr->hasInetAddress()) { if (MatchesAddressFamily(o)) { o->ref(); ol.push_back( o ); } } else { // not an address object at all o->ref(); ol.push_back( o ); } } } } /* * Common interface to the operation of expanding of a group * recursively. This just calls internal function * _expand_group_recursive() */ void Compiler::expandGroup(FWObject *grp, list &ol) { for (FWObject::iterator i1=grp->begin(); i1!=grp->end(); ++i1) { FWObject *o = FWReference::getObject(*i1); assert(o); _expand_group_recursive(o, ol); } } /** * object 's' here is really src or dst or srv. Its children objects * should all be references */ void Compiler::expandGroupsInRuleElement(RuleElement *s) { list cl; expandGroup(s, cl); s->clearChildren(); //s->setAnyElement(); cl.sort(FWObjectNameCmpPredicate()); for(FWObject::iterator i2=cl.begin(); i2!=cl.end(); ++i2) { if (!s->validateChild(*i2)) abort(s->getParent(), "Object '" + (*i2)->getName() + "' can not be used in rule element " + s->getTypeName()); s->addRef( *i2 ); } } void Compiler::_expand_addr_recursive(Rule *rule, FWObject *s, list &ol, bool expand_cluster_interfaces_fully) { // Interface *rule_iface = Interface::cast(dbcopy->findInIndex(rule->getInterfaceId())); bool on_loopback = false; if (PolicyRule::isA(rule)) { RuleElement *intf_re = PolicyRule::cast(rule)->getItf(); Interface *rule_iface = Interface::cast(FWObjectReference::getObject(intf_re->front())); on_loopback = ( rule_iface && rule_iface->isLoopback() ); } list addrlist; for (FWObject::iterator i1=s->begin(); i1!=s->end(); ++i1) { FWObject *o = FWReference::getObject(*i1); assert(o); Address *addr = Address::cast(o); // this condition includes Host, Firewall and Interface if (addr && !addr->hasInetAddress()) { addrlist.push_back(o); continue; } // IPv4, IPv6, Network, NetworkIPv6 if (addr && addr->hasInetAddress() && MatchesAddressFamily(o)) { addrlist.push_back(o); continue; } if (o->getId() == FWObjectDatabase::ANY_ADDRESS_ID || MultiAddress::cast(o)!=NULL || Interface::cast(o) || physAddress::cast(o)) { addrlist.push_back(o); continue; } } if (addrlist.empty()) { if (RuleElement::cast(s)==NULL) ol.push_back(s); } else { for (list::iterator i2=addrlist.begin(); i2!=addrlist.end(); ++i2) { Interface *i2itf = Interface::cast(*i2); if (i2itf) { /* * skip copy of the member interface added in CompilerDriver::copyFailoverInterface */ if (i2itf->getBool("member_interface_copy")) continue; /* * Special case is loopback interface - skip it, but only if this rule is * not attached to loopback! * * Correction 10/20/2008: if user put loopback interface object into * rule element, keep it. However if we expanded it from a host or * firewall object, then skip it unless the rule is attached to * loopback interface. */ if (i2itf->isLoopback()) { if (RuleElement::cast(s) || on_loopback) _expand_interface( rule, i2itf, ol, expand_cluster_interfaces_fully); } else // this is not a loopback interface _expand_interface( rule, i2itf, ol, expand_cluster_interfaces_fully); continue; } _expand_addr_recursive(rule, *i2, ol, expand_cluster_interfaces_fully); } } } void Compiler::_expand_interface(Rule *rule, Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully) { /* * if this is an interface with dynamic address, then simply use it * (that is, do not use its children elements "Address") */ if (iface->isDyn()) { ol.push_back(iface); return; } /* * we use physAddress only if Host option "use_mac_addr_filter" of the * parent Host object is true */ FWObject *p = Host::getParentHost(iface); //FWObject *p = iface->getParentHost(); Host *hp = Host::cast(p); if (hp==NULL) return; // something is very broken FWOptions *hopt = hp->getOptionsObject(); bool use_mac = (hopt!=NULL && hopt->getBool("use_mac_addr_filter")); for (FWObject::iterator i1=iface->begin(); i1!=iface->end(); ++i1) { FWObject *o= *i1; if (physAddress::cast(o)!=NULL) { if (use_mac) ol.push_back(o); continue; } // Skip bridge ports Interface *subint = Interface::cast(o); if (subint) { if (subint->isBridgePort()) continue; _expand_interface(rule, subint, ol, expand_cluster_interfaces_fully); continue; } if ( ! iface->isUnnumbered() && Address::cast(o)!=NULL && MatchesAddressFamily(o)) ol.push_back(o); } if (expand_cluster_interfaces_fully && iface->isFailoverInterface()) { // See #1234 Cluster failover interface expands to its own addresses, // plus addresses of the corresponding member interface FailoverClusterGroup *fg = FailoverClusterGroup::cast( iface->getFirstByType(FailoverClusterGroup::TYPENAME)); Interface* member_intf = fg->getInterfaceForMemberFirewall(fw); if (member_intf) _expand_interface(rule, member_intf, ol, expand_cluster_interfaces_fully); else { // per #1394, if the cluster interface used in the rule does not // belong to the cluster being compiled, expand it to its own // address and addresses of all corresponding member interfaces for (FWObjectTypedChildIterator it = fg->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *other_intf = Interface::cast(FWObjectReference::getObject(*it)); assert(other_intf); _expand_interface(rule, other_intf, ol, expand_cluster_interfaces_fully); } } } } bool compare_addresses(FWObject *o1, FWObject *o2) { Address *a1 = Address::cast(o1); Address *a2 = Address::cast(o2); if (a1 == NULL || a2 == NULL) { // one or both could be MultiAddress objects (e.g. DNSName) return o1->getName() < o2->getName(); } const InetAddr *addr1 = a1->getAddressPtr(); const InetAddr *addr2 = a2->getAddressPtr(); if (addr1 == NULL) return true; if (addr2 == NULL) return false; return *addr1 < *addr2; } /** * internal: scans children of 's' and, if found host or firewall with * multiple interfaces, replaces reference to that host or firewall * with a set of references to its interfaces. Argument 's' should be * a pointer at either src or dst in the rule * */ void Compiler::_expand_addr(Rule *rule, FWObject *s, bool expand_cluster_interfaces_fully) { list cl; _expand_addr_recursive(rule, s, cl, expand_cluster_interfaces_fully); list expanded_addresses; for (FWObject::iterator i=cl.begin(); i!=cl.end(); ++i) { expanded_addresses.push_back(*i); } expanded_addresses.sort(compare_addresses); s->clearChildren(); for (list::iterator i1=expanded_addresses.begin(); i1!=expanded_addresses.end(); ++i1) { s->addRef( *i1 ); } } /** * replace address range objects in the rule element 're' with series of * regular address obejcts. Drop objects that do not match current * address family. */ void Compiler::_expandAddressRanges(Rule *rule, FWObject *re) { list cl; for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = FWReference::getObject(*i1); assert(o!=NULL); // if this is address range, check if it matches current address // family. If it is not address range, put it back into the rule element // If it is address range but it does not match address family, // throw it away. AddressRange *aro = AddressRange::cast(o); if (aro) { if (MatchesAddressFamily(o)) { InetAddr a1 = aro->getRangeStart(); InetAddr a2 = aro->getRangeEnd(); vector vn = libfwbuilder::convertAddressRange(a1,a2); if (vn.size() == 0) { abort(rule, "Address Range object '" + aro->getName() + "' can not be converted to set of addresses"); } for (vector::iterator i=vn.begin(); i!=vn.end(); i++) { Network *h = dbcopy->createNetwork(); h->setName(string("%n-")+(*i).toString()+string("%") ); h->setNetmask(*(i->getNetmaskPtr())); h->setAddress(*(i->getAddressPtr())); persistent_objects->add(h, false); cl.push_back(h); // see GroupRegistry::registerGroupObject() if (group_registry != NULL) { group_registry->setGroupRegistryKey( h, group_registry->getGroupRegistryKey(aro)); } } } } else { cl.push_back(o); } } re->clearChildren(); for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->addRef( *i1 ); } void Compiler::normalizePortRange(int &rs,int &re) { if (rs<0) rs=0; if (re<0) re=0; if (rs!=0 && re==0) re=rs; } void Compiler::debugRule() { for (FWObject::iterator i=source_ruleset->begin(); i!=source_ruleset->end(); i++) { Rule *rule = Rule::cast( *i ); if (rule == NULL) continue; if (rule_debug_on && rule->getPosition()==debug_rule ) { info(debugPrintRule(rule)); info("\n"); } } } /* * basic rule printing, not very useful. This method is overloaded in * derived classes */ string Compiler::debugPrintRule(libfwbuilder::Rule *rule) { return rule->getLabel(); } /** * adds rule processor to the chain and, if debugging is ON, also * adds rule processor "Debug" after that. Do not add Debug after * certain processors, such as SimplePrintProgress */ void Compiler::add(BasicRuleProcessor* rp) { rule_processors.push_back(rp); if (rule_debug_on && dynamic_cast(rp)==NULL) rule_processors.push_back(new Debug()); } void Compiler::runRuleProcessors() { list::iterator i=rule_processors.begin(); (*i)->setContext(this); list::iterator j=i; ++i; for ( ; i!=rule_processors.end(); ++i) { (*i)->setContext(this); (*i)->setDataSource( (*j) ); j=i; } while ((*j)->processNext()) ; } void Compiler::deleteRuleProcessors() { while (rule_processors.size() > 0) { BasicRuleProcessor *rp = rule_processors.front(); rule_processors.pop_front(); delete rp; } } Compiler::Begin::Begin() : BasicRuleProcessor("") { init=false; }; Compiler::Begin::Begin(const std::string &n) : BasicRuleProcessor(n) { init=false; }; bool Compiler::Begin::processNext() { assert(compiler!=NULL); if (!init) { for (FWObject::iterator i=compiler->source_ruleset->begin(); i!=compiler->source_ruleset->end(); ++i) { Rule *rule = Rule::cast(*i); if (rule == NULL) continue; if (rule->isDisabled()) continue; Rule *r = Rule::cast(compiler->dbcopy->create(rule->getTypeName())); compiler->temp_ruleset->add(r); r->duplicate(rule); tmp_queue.push_back( r ); } init = true; if (!name.empty()) compiler->info(string(" ") + name); return true; } return false; } bool Compiler::printTotalNumberOfRules::processNext() { assert(compiler!=NULL); assert(prev_processor!=NULL); slurp(); if (tmp_queue.size()==0) return false; if (compiler->verbose) { ostringstream str; str << " processing " << tmp_queue.size() << " rules"; compiler->info(str.str()); } return true; } bool Compiler::createNewCompilerPass::processNext() { assert(compiler!=NULL); assert(prev_processor!=NULL); slurp(); if (tmp_queue.size()==0) return false; compiler->info(pass_name); return true; } bool Compiler::Debug::processNext() { assert(compiler!=NULL); assert(prev_processor!=NULL); slurp(); if (tmp_queue.size()==0) return false; if (compiler->rule_debug_on) { string n = prev_processor->getName(); ostringstream str; str << endl << "--- " << n << " " << setw(74-n.length()) << setfill('-') << "-"; compiler->info(str.str()); for (std::deque::iterator i=tmp_queue.begin(); i!=tmp_queue.end(); ++i) { Rule *rule = Rule::cast(*i); if (compiler->rule_debug_on && rule->getPosition()==compiler->debug_rule ) { compiler->info(compiler->debugPrintRule(rule)); compiler->info("\n"); } } } return true; } bool Compiler::singleRuleFilter::processNext() { assert(compiler!=NULL); assert(prev_processor!=NULL); Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; if (!compiler->single_rule_mode) { tmp_queue.push_back(rule); return true; } if (compiler->single_rule_ruleset_name == compiler->ruleSetName && rule->getPosition() == compiler->single_rule_position) tmp_queue.push_back(rule); return true; } bool Compiler::simplePrintProgress::processNext() { Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; std::string rl=rule->getLabel(); if (rl!=current_rule_label) { if (compiler->verbose) { std::string s=" rule "+rl; compiler->info(s); } current_rule_label=rl; } tmp_queue.push_back(rule); return true; } /** * re_type can be either RuleElementSrc::TYPENAME or RuleElementDst::TYPENAME * or some other rule element */ bool Compiler::splitIfRuleElementMatchesFW::processNext() { Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); int nre = re->size(); list cl; for (list::iterator i1=re->begin(); nre>1 && i1!=re->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); Address *a = Address::cast(obj); assert(a!=NULL); if (a->getId() == compiler->fw->getId() || a->getInt("parent_cluster_id") == compiler->fw->getId() || compiler->complexMatch(a, compiler->fw)) { cl.push_back(*i1); nre--; Rule *new_rule = Rule::cast( compiler->dbcopy->create(rule->getTypeName()) ); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); RuleElement *new_re = RuleElement::cast( new_rule->getFirstByType(re_type)); new_re->clearChildren(); new_re->setAnyElement(); new_re->addRef( a ); tmp_queue.push_back(new_rule); } } if (!cl.empty()) { for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->remove( (*i1) ); } tmp_queue.push_back(rule); return true; } /* * This rule processor replaces firewall object in given rule element * with run-time DNSName object with name "self" and source name (A * record) set to "self". This is a trick in that when compliers see * objects like that in a rule, they just put source name in the * generated code verbatim. This is useful for firewall platforms that * support keyword "self" (e.g. PF). * * Always call this RE after splitIfFirewallInSrc or splitIfFirewallInDst */ bool Compiler::ReplaceFirewallObjectWithSelfInRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); if (obj == compiler->fw) { DNSName *self = DNSName::cast( compiler->persistent_objects->findObjectByName( DNSName::TYPENAME, "self")); if (self == NULL) { self = compiler->dbcopy->createDNSName(); self->setName("self"); self->setRunTime(true); self->setSourceName("self"); compiler->persistent_objects->add(self, false); } re->addRef(self); re->removeRef(compiler->fw); break; } } tmp_queue.push_back(rule); return true; } bool Compiler::RegisterGroupsAndTablesInRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; if (compiler->group_registry != NULL) { RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *obj = FWReference::getObject(*i); if (ObjectGroup::cast(obj)!=NULL && obj->size() > 0) { compiler->registerGroupObject(re, ObjectGroup::cast(obj)); } } } tmp_queue.push_back(rule); return true; } void Compiler::registerGroupObject(RuleElement *re, ObjectGroup *grp) { assert(group_registry!=NULL); list objects; expandGroup(grp, objects); group_registry->registerGroup(grp, objects); group_registry->registerGroupInRE(re, grp); } bool Compiler::equalObj::operator()(FWObject *o) { return o->getId()==obj->getId(); } bool Compiler::singleObjectNegation::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *rel = RuleElement::cast(rule->getFirstByType(re_type)); assert(rel); if (rel->getNeg() && rel->size()==1) { if (rel->getTypeName() == RuleElementItfInb::TYPENAME || rel->getTypeName() == RuleElementItfOutb::TYPENAME || rel->getTypeName() == RuleElementItf::TYPENAME ) { rel->setNeg(false); rel->setBool("single_object_negation", true); } else { FWObject *o = rel->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *reladdr = Address::cast(o); if ( reladdr && reladdr->countInetAddresses(true)==1 && !compiler->complexMatch(reladdr, compiler->fw)) { rel->setNeg(false); rel->setBool("single_object_negation", true); } } } tmp_queue.push_back(rule); return true; } /* * Process negation in the "Interface" rule element. Scan objects in * this RE, replace cluster interfaces with interfaces of the member, * then replace them with a list of all other interfaces of the member. * * Note that normally compiler should call * replaceClusterInterfaceInItf before calling this processor. This * means that this processor should never see cluster interfaces in * the RE. However I keep the code that deals with them in place to be * able to use this processor without prior call to * replaceClusterInterfaceInItf if necessary. * * TODO: make this code assert() if cluster interface appears in RE/ * * Note that rule processor singleObjectNegationItf deals with single * object negation in Interface rule elements. */ bool Compiler::fullInterfaceNegationInRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *itfre = RuleElement::cast(rule->getFirstByType(re_type)); if (itfre==NULL) compiler->abort(rule, "Missing interface rule element"); FWOptions *fwopt = compiler->getCachedFwOpt(); if (itfre->getNeg()) { // Use getByTypeDeep() to pick subinterfaces (vlans and such) list all_interfaces = compiler->fw->getByTypeDeep(Interface::TYPENAME); list work_interfaces; // skip unprotected interfaces bug #2710034 "PF Compiler in 3.0.3 // Unprotected Interface Bug" for (FWObject::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *intf = Interface::cast(*i); if (intf == NULL) continue; if (intf->isUnprotected()) continue; if (intf->isLoopback()) continue; // skip bridge ports, but use them if this is bridging firewall if ( ! fwopt->getBool("bridging_fw") && intf->isBridgePort()) continue; if (intf->getOptionsObject()->getBool("cluster_interface")) continue; work_interfaces.push_back(intf); } for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i) { // Only interface objects are allowed in the "Interface" rule element Interface *rule_iface = Interface::cast(FWReference::getObject(*i)); if (rule_iface == NULL) continue; // If this interface belongs to a cluster (which can only happen // if the rule set belongs to a cluster), then replace it with // corresponding interface of the member if (rule_iface->isFailoverInterface()) { FailoverClusterGroup *fg = FailoverClusterGroup::cast( rule_iface->getFirstByType(FailoverClusterGroup::TYPENAME)); if (fg) rule_iface = fg->getInterfaceForMemberFirewall(compiler->fw); } if (rule_iface) work_interfaces.remove(rule_iface); } itfre->reset(); itfre->setNeg(false); FWObject::iterator i; for (i=work_interfaces.begin(); i!=work_interfaces.end(); ++i) itfre->addRef(*i); } tmp_queue.push_back(rule); return true; } /* * Call this processor before ItfNegation (and in some compilers, * singleItfNegation). */ bool Compiler::replaceClusterInterfaceInItfRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *itfre = RuleElement::cast(rule->getFirstByType(re_type)); if (itfre==NULL) compiler->abort(rule, "Missing interface rule element"); map interface_replacement; for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i) { Interface *member_iface = NULL; // Only interface objects are allowed in the "Interface" rule element FWObject *o = FWReference::getObject(*i); Interface *rule_iface = Interface::cast(o); if (rule_iface == NULL) continue; // If this interface belongs to a cluster (which can only happen // if the rule set belongs to a cluster), then replace it with // corresponding interface of the member if (rule_iface->isFailoverInterface()) { FailoverClusterGroup *fg = FailoverClusterGroup::cast( rule_iface->getFirstByType(FailoverClusterGroup::TYPENAME)); if (fg) member_iface = fg->getInterfaceForMemberFirewall(compiler->fw); } if (member_iface) { interface_replacement[rule_iface] = member_iface; } } map::iterator r; for (r = interface_replacement.begin(); r != interface_replacement.end(); ++r) { itfre->removeRef(r->first); itfre->addRef(r->second); } itfre->sort(FWObjectNameCmpPredicate(true)); tmp_queue.push_back(rule); return true; } bool Compiler::eliminateDuplicatesInRE::processNext() { Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; if (comparator==NULL) comparator = new equalObj(); RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); list cl; for(list::iterator i=re->begin(); i!=re->end(); ++i) { FWObject *obj = FWReference::getObject(*i); if (obj == NULL) continue; comparator->set(obj); bool found = false; for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) { FWObject *o2 = *i1; if ( (*comparator)(o2) ) { found=true; break; } } if (!found) cl.push_back(obj); } if (!cl.empty()) { re->clearChildren(); for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->addRef( (*i1) ); } tmp_queue.push_back(rule); return true; } void Compiler::recursiveGroupsInRE::isRecursiveGroup(int grid, FWObject *obj) { for (FWObject::iterator i=obj->begin(); i!=obj->end(); i++) { FWObject *o = FWReference::getObject(*i); if (Group::cast(o)!=NULL) { if (o->getId()==grid || obj->getId()==o->getId()) { compiler->abort( "Group '" + o->getName() + "' references itself recursively"); } isRecursiveGroup(grid,o); isRecursiveGroup(o->getId(),o); } } } bool Compiler::recursiveGroupsInRE::processNext() { Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); if (re == NULL || re->isAny()) { tmp_queue.push_back(rule); return true; } std::list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if (Group::cast(o)!=NULL) isRecursiveGroup(o->getId(),o); } tmp_queue.push_back(rule); return true; } /* * counts children of obj recursively (that is, its direct children objects, plus * their children objects, etc. */ int Compiler::emptyGroupsInRE::countChildren(FWObject *obj) { if (obj->size()==0) return 0; int n=0; for (FWObject::iterator i=obj->begin(); i!=obj->end(); i++) { FWObject *o = FWReference::getObject(*i); // Check if this is a group, if yes, then count its children // recursively. Group itself does not count since it can be // empty, too. However if this is MultiAddress object with // run-time processing, it does not count as an empty group // since we have no way to know at compile time if it will // have some addresses at run time. So we just count it as a // regular object. if (MultiAddress::cast(o)!=NULL && MultiAddress::cast(o)->isRunTime()) n++; else { if (Group::cast(o)!=NULL) n += countChildren(o); else n++; // but if it is not a group, then we count it. } } return n; } bool Compiler::emptyGroupsInRE::processNext() { Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); if (re == NULL || re->isAny()) { tmp_queue.push_back(rule); return true; } std::list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if ( MultiAddress::cast(o)!=NULL && MultiAddress::cast(o)->isRunTime()) continue; if (Group::cast(o)!=NULL && countChildren(o)==0) cl.push_back(o); } if (!cl.empty()) { if ( compiler->fw->getOptionsObject()->getBool ("ignore_empty_groups") ) { for (FWObject::iterator i=cl.begin(); i!=cl.end(); i++) { FWObject *o= *i; ostringstream str; str << "Empty group or address table object '" << o->getName() << "'"; re->removeRef(o); compiler->warning(rule, str.str()); } if (re->isAny()) { ostringstream str; str << "After removal of all empty groups and address table objects rule element " << re->getTypeName() << " becomes 'any' in the rule " << rule->getLabel() << endl << "Dropping rule " << rule->getLabel() << " because option 'Ignore rules with empty groups' is in effect"; compiler->warning(rule, str.str()); return true; // dropping this rule } } else { std::string gr; int cntr = 0; for (FWObject::iterator i=cl.begin(); i!=cl.end(); i++) { FWObject *o= *i; if (cntr>0) gr += ","; gr += o->getName(); cntr++; } ostringstream str; str << "Empty group or address table object" << " '" << gr << "' is used in the rule" << " but option 'Ignore rules with empty groups' is off"; compiler->abort(rule, str.str()); } } tmp_queue.push_back(rule); return true; } /** * swaps MultiAddress objects that require run-time expansion with * MultiAddressRunTime equivalents */ bool Compiler::swapMultiAddressObjectsInRE::processNext() { Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); if (re == NULL || re->isAny()) { tmp_queue.push_back(rule); return true; } list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if (MultiAddress::cast(o)!=NULL && MultiAddress::cast(o)->isRunTime()) cl.push_back(MultiAddress::cast(o)); } if (!cl.empty()) { for (list::iterator i=cl.begin(); i!=cl.end(); i++) { MultiAddress *ma = *i; // Need to make sure the ID of the MultiAddressRunTime // object created here is stable and is always the same // for the same MultiAddress object. In particular this // ensures that we reuse tables between policy and NAT rules // in compiler for PF. There could be other similar cases // (object-group in compielr for pix may be ?) string mart_id_str = FWObjectDatabase::getStringId(ma->getId()) + "_runtime"; int mart_id = FWObjectDatabase::registerStringId(mart_id_str); MultiAddressRunTime *mart = MultiAddressRunTime::cast( compiler->dbcopy->findInIndex(mart_id)); if (mart==NULL) { mart = new MultiAddressRunTime(ma); // need to ensure stable ID for the runtime object, so // that when the same object is replaced in different // rulesets by different compiler passes, chosen // runtime object has the same ID and is identified as // the same by the compiler. mart->setId( mart_id ); compiler->dbcopy->addToIndex(mart); compiler->persistent_objects->add(mart); } re->removeRef(ma); re->addRef(mart); } tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } bool Compiler::expandMultipleAddressesInRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) ); if (re) compiler->_expand_addr(rule, re, true); tmp_queue.push_back(rule); return true; } bool Compiler::checkForObjectsWithErrors::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; for (FWObject::iterator it1=rule->begin(); it1!=rule->end(); it1++) { RuleElement *re = RuleElement::cast(*it1); if (re == NULL || re->isAny()) continue; for (FWObject::iterator it2=re->begin(); it2!=re->end(); it2++) { FWObject *obj = FWReference::getObject(*it2); if (obj->getBool(".rule_error")) { // it is ok to call abort this late in rule // processing. If the error was fatal, the code that // encounter it should have called abort() then. If it // continued, then we are in test mode and this call to // abort will continue too. In the worst case, we end up // with duplicate error messages in the test mode. compiler->abort(rule, obj->getStr(".error_msg")); } } } tmp_queue.push_back(rule); return true; } bool Compiler::replaceFailoverInterfaceInRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) ); if (re == NULL || re->isAny()) { tmp_queue.push_back(rule); return true; } // list of pointers to cluster interfaces used in the RE list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { Interface *intf = Interface::cast(FWReference::getObject(*i)); if (intf==NULL) continue; if (intf->isFailoverInterface()) cl.push_back(intf); else { // this could be a copy of cluster interface which belongs // to the firewall. This is done in // Compiler::processFailoverGroup. Dont use interface name // to distinguish cluster interface. Better method is to // check for the variable "cluster_interface". if (intf->getOptionsObject()->getBool("cluster_interface")) cl.push_back(intf); } } if (!cl.empty()) { for (list::iterator i=cl.begin(); i!=cl.end(); i++) { Interface *intf = *i; FailoverClusterGroup *fg = FailoverClusterGroup::cast( intf->getFirstByType(FailoverClusterGroup::TYPENAME)); if (fg) { Interface *other_interface = fg->getInterfaceForMemberFirewall(compiler->fw); re->removeRef(intf); re->addRef(other_interface); } else { string base_interface_id = intf->getOptionsObject()->getStr("base_interface_id"); if (!base_interface_id.empty()) { FWObject *base_interface = compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(base_interface_id)); if (base_interface) { re->removeRef(intf); re->addRef(base_interface); } } } } } tmp_queue.push_back(rule); return true; } bool Compiler::FindAddressFamilyInRE(FWObject *parent, bool ipv6) { Address *addr = Address::cast(parent); if (addr!=NULL) { const InetAddr *inet_addr = addr->getAddressPtr(); if (ipv6) return (inet_addr && inet_addr->isV6()); else return (inet_addr && inet_addr->isV4()); } for (FWObject::iterator i=parent->begin(); i!=parent->end(); i++) { FWObject *o = FWReference::getObject(*i); if (FindAddressFamilyInRE(o, ipv6)) return true; } return false; } void Compiler::DropAddressFamilyInRE(RuleElement *rel, bool drop_ipv6) { list objects_to_remove; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o = FWReference::getObject(*i); // skip "Any" if (o->getId() == FWObjectDatabase::ANY_ADDRESS_ID) continue; if (Address::cast(o) && Address::cast(o)->hasInetAddress()) { const InetAddr *inet_addr = Address::cast(o)->getAddressPtr(); if (inet_addr) { if (drop_ipv6 && inet_addr->isV6()) objects_to_remove.push_back(o); if (!drop_ipv6 && inet_addr->isV4()) objects_to_remove.push_back(o); } } } for (list::iterator i = objects_to_remove.begin(); i != objects_to_remove.end(); ++i) rel->removeRef(*i); } bool Compiler::dropRuleWithEmptyRE::isREEmpty(Rule *rule, const std::string &re_type) { RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); return re->size()==0; } /* * TODO: why rule elements Service, Interface and Time are not checked * for policy rules? */ bool Compiler::dropRuleWithEmptyRE::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; if (PolicyRule::cast(rule) && (isREEmpty(rule, RuleElementSrc::TYPENAME) || isREEmpty(rule, RuleElementDst::TYPENAME))) { if (!warning_str.empty()) compiler->warning(rule, warning_str); return true; } if (NATRule::cast(rule) && (isREEmpty(rule, RuleElementOSrc::TYPENAME) || isREEmpty(rule, RuleElementODst::TYPENAME) || isREEmpty(rule, RuleElementOSrv::TYPENAME) || isREEmpty(rule, RuleElementTSrc::TYPENAME) || isREEmpty(rule, RuleElementTDst::TYPENAME) || isREEmpty(rule, RuleElementTSrv::TYPENAME))) { if (!warning_str.empty())compiler->warning(rule, warning_str); return true; } if (RoutingRule::cast(rule) && (isREEmpty(rule, RuleElementRDst::TYPENAME) || isREEmpty(rule, RuleElementRGtw::TYPENAME) || isREEmpty(rule, RuleElementRItf::TYPENAME))) { if (!warning_str.empty()) compiler->warning(rule, warning_str); return true; } tmp_queue.push_back(rule); return true; } void Compiler::DropByServiceTypeInRE(RuleElement *rel, bool drop_ipv6) { list objects_to_remove; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o = FWReference::getObject(*i); // skip "Any" if (o->getId() == FWObjectDatabase::ANY_SERVICE_ID) continue; Service *svc = Service::cast(o); if (svc == NULL) { cerr << endl; cerr << "Rule " << Rule::cast(rel->getParent())->getLabel() << " Rule element " << rel->getTypeName() << endl; o->dump(true, false); } assert(svc); // Note that all service objects except for ICMPService and // CustomService can be used in both ipv4 and ipv6 contexts. if (drop_ipv6) { if (svc->isV6Only()) objects_to_remove.push_back(o); } else { if (svc->isV4Only()) objects_to_remove.push_back(o); } } for (list::iterator i = objects_to_remove.begin(); i != objects_to_remove.end(); ++i) rel->removeRef(*i); } bool Compiler::catchUnnumberedIfaceInRE(RuleElement *re) { bool err = false; Interface *iface; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if (o==NULL) { //Rule *rule = Rule::cast(re->getParent()); FWReference *refo = FWReference::cast(*i); string errmsg = string("catchUnnumberedIfaceInRE: Can't find object ") + string("in cache, ID=") + FWObjectDatabase::getStringId(refo->getPointerId()); abort(re->getParent(), errmsg); } err |= ((iface=Interface::cast(o))!=NULL && (iface->isUnnumbered() || iface->isBridgePort()) ); } return err; } Address* Compiler::getFirstSrc(PolicyRule *rule) { RuleElementSrc *src = rule->getSrc(); FWObject *o = FWReference::getObject(src->front()); return Address::cast(o); } Address* Compiler::getFirstDst(PolicyRule *rule) { RuleElementDst *dst = rule->getDst(); FWObject *o = FWReference::getObject(dst->front()); return Address::cast(o); } Service* Compiler::getFirstSrv(PolicyRule *rule) { RuleElementSrv *srv = rule->getSrv(); FWObject *o = FWReference::getObject(srv->front()); return Service::cast(o); } Interval* Compiler::getFirstWhen(PolicyRule *rule) { RuleElementInterval *when = rule->getWhen(); if (when==NULL) return NULL; // when is optional element FWObject *o = FWReference::getObject(when->front()); return Interval::cast(o); } Interface* Compiler::getFirstItf(PolicyRule *rule) { RuleElementItf *itf = rule->getItf(); if (itf==NULL || itf->size()==0) return NULL; // itf is optional element FWObject *o = FWReference::getObject(itf->front()); return Interface::cast(o); } Address* Compiler::getFirstOSrc(NATRule *rule) { RuleElementOSrc *osrc = rule->getOSrc(); assert(osrc!=NULL); FWObject *o = FWReference::getObject(osrc->front()); return Address::cast(o); } Address* Compiler::getFirstODst(NATRule *rule) { RuleElementODst *odst = rule->getODst(); assert(odst!=NULL); FWObject *o = FWReference::getObject(odst->front()); return Address::cast(o); } Service* Compiler::getFirstOSrv(NATRule *rule) { RuleElementOSrv *osrv = rule->getOSrv(); assert(osrv!=NULL); FWObject *o = FWReference::getObject(osrv->front()); return Service::cast(o); } Address* Compiler::getFirstTSrc(NATRule *rule) { RuleElementTSrc *tsrc = rule->getTSrc(); assert(tsrc!=NULL); FWObject *o = FWReference::getObject(tsrc->front()); return Address::cast(o); } Address* Compiler::getFirstTDst(NATRule *rule) { RuleElementTDst *tdst = rule->getTDst(); assert(tdst!=NULL); FWObject *o = FWReference::getObject(tdst->front()); return Address::cast(o); } Service* Compiler::getFirstTSrv(NATRule *rule) { RuleElementTSrv *tsrv = rule->getTSrv(); assert(tsrv!=NULL); FWObject *o = FWReference::getObject(tsrv->front()); return Service::cast(o); } /* * Compares given object with firewall or its parent cluster (if any). * Compares only IDs of these objects. Relies on class CompilerDriver * to set integer variable "parent_cluster_id" in the firewall object * if it is a member of a cluster. */ bool Compiler::isFirewallOrCluster(FWObject *obj) { int fw_id = fw->getId(); int cluster_id = fw->getInt("parent_cluster_id"); return obj->getId() == fw_id || obj->getId() == cluster_id; } string Compiler::printComment(Rule *rule, string &prev_rule_label, const std::string &prefix, bool suppress_comment) { ostringstream res; string rl = rule->getLabel(); if (rl != prev_rule_label) { if ( ! inSingleRuleCompileMode()) { res << prefix << " " << endl; res << prefix << " Rule " << rl << endl; } string comm = rule->getComment(); if ( ! suppress_comment && ! comm.empty()) { string::size_type c1, c2; c1 = 0; while ( (c2 = comm.find('\n', c1)) != string::npos ) { res << prefix << " " << comm.substr(c1, c2 - c1) << endl; c1 = c2 + 1; } string remainder = comm.substr(c1); if (!remainder.empty()) res << prefix << " " << remainder << endl; } string err = getErrorsForRule(rule, prefix + " "); if (!err.empty()) res << err << endl; prev_rule_label = rl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) res << prefix << " " << err << endl; return res.str(); } Address* Compiler::correctForCluster(Address *addr) { #ifdef DEBUG_FOR_DMZ cerr << "Compiler::correctForCluster " << addr << endl; if (addr) { cerr << " addr: " << addr->getName() << endl; } #endif Interface *intf = Interface::cast(addr); if (intf) { #ifdef DEBUG_FOR_DMZ cerr << " intf: " << intf->getName() << " isFailoverInterface: " << intf->isFailoverInterface() << endl; #endif } if (intf && intf->isFailoverInterface()) { FailoverClusterGroup *fg = FailoverClusterGroup::cast( intf->getFirstByType(FailoverClusterGroup::TYPENAME)); if (fg) { Address *other_intf = fg->getInterfaceForMemberFirewall(fw); #ifdef DEBUG_FOR_DMZ cerr << " fg: " << fg->getName() << endl; cerr << " other_intf: " << other_intf << endl; #endif if (other_intf) return other_intf; } } return addr; } /* keep only rules that have ipv4 addresses in src and dst * * This rule processor assumes all groups and multi-address objects * have already been expanded. * * TODO: figure out what to do with rules that have mix of ipv4 and ipv6 * addresses in different rule elements (such as ipv4 address in odst * and ipv6 address in tdst or similar) */ bool Compiler::DropRulesByAddressFamilyAndServiceType::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; for(FWObject::iterator it=rule->begin(); it!=rule->end(); ++it) { RuleElement *re = RuleElement::cast(*it); if (re == NULL) continue; // probably RuleOptions object bool orig_any = re->isAny(); if (orig_any) continue; FWObject *first_object = FWReference::getObject(re->front()); if (Address::cast(first_object) != NULL) compiler->DropAddressFamilyInRE(re, drop_ipv6); if (Service::cast(first_object) != NULL) compiler->DropByServiceTypeInRE(re, drop_ipv6); if (!orig_any && re->isAny()) { // removing all ipv6 addresses from rule element makes it 'any', drop // this rule if (!warning_str.empty()) compiler->warning(rule, warning_str); return true; } } tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/ServiceRuleProcessors.cpp0000644000175000017500000002343211733011756030220 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "Compiler.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWObjectDatabase.h" #include #include #include #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; /* * These rule processors should work for both Policy and NAT rules * without having to build specialized classes inheriting from these. */ bool Compiler::groupServices::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string re_type = PolicyRule::isA(rule) ? RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME; RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type)); if (re_srv->size()==1) { tmp_queue.push_back(rule); return true; } map > services; for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++) { Service *s = Service::cast(FWReference::getObject(*i)); assert(s); int proto = groupingCode(s); services[proto].push_back(s); } for (map >::iterator i1=services.begin(); i1!=services.end(); i1++) { list &sl=(*i1).second; Rule *r = Rule::cast(compiler->dbcopy->create(rule->getTypeName())); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElement *nsrv = RuleElement::cast(r->getFirstByType(re_type)); nsrv->clearChildren(); for (list::iterator j=sl.begin(); j!=sl.end(); j++) { nsrv->addRef( (*j) ); } tmp_queue.push_back(r); } return true; } int Compiler::groupServicesByProtocol::groupingCode(const Service *srv) { return srv->getProtocolNumber(); } int Compiler::groupTCPUDPServices::groupingCode(const Service *srv) { return ( TCPService::isA(srv) || UDPService::isA(srv)); } Compiler::separateServiceObject::separateServiceObject( const string &name) : BasicRuleProcessor(name) { } bool Compiler::separateServiceObject::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string re_type = PolicyRule::isA(rule) ? RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME; RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type)); if (re_srv->size()==1) { tmp_queue.push_back(rule); return true; } list services; for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast(o); assert(s!=NULL); if (condition(s)) { Rule *r = Rule::cast(compiler->dbcopy->create(rule->getTypeName())); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElement *nsrv = RuleElement::cast(r->getFirstByType(re_type)); nsrv->clearChildren(); nsrv->addRef( s ); tmp_queue.push_back(r); services.push_back(s); } } for (list::iterator i=services.begin(); i!=services.end(); i++) re_srv->removeRef( (*i) ); if (!re_srv->isAny()) tmp_queue.push_back(rule); return true; } /** * separate TCP/UDP services that specify source port (can * not be used in combination with destination port with * multiport) */ bool Compiler::separateSrcPort::condition(const Service *srv) { if ( TCPService::isA(srv) || UDPService::isA(srv)) { int srs = TCPUDPService::constcast(srv)->getSrcRangeStart(); int sre = TCPUDPService::constcast(srv)->getSrcRangeEnd(); compiler->normalizePortRange(srs,sre); return (srs!=0 || sre!=0); } return false; } bool Compiler::separateSrcAndDstPort::condition(const Service *srv) { if ( TCPService::isA(srv) || UDPService::isA(srv)) { int srs = TCPUDPService::constcast(srv)->getSrcRangeStart(); int sre = TCPUDPService::constcast(srv)->getSrcRangeEnd(); int drs = TCPUDPService::constcast(srv)->getDstRangeStart(); int dre = TCPUDPService::constcast(srv)->getDstRangeEnd(); compiler->normalizePortRange(srs,sre); compiler->normalizePortRange(drs,dre); return ( (srs!=0 || sre!=0) && (drs!=0 || dre!=0) ); } return false; } bool Compiler::separateTCPUDP::condition(const Service *srv) { return ( TCPService::isA(srv) || UDPService::isA(srv)); } bool Compiler::separateTagged::condition(const Service *srv) { return ( TagService::isA(srv)); } bool Compiler::separateCustom::condition(const Service *srv) { return ( CustomService::isA(srv)); } bool Compiler::separateUserServices::condition(const Service *srv) { return ( UserService::isA(srv)); } bool Compiler::separateTOS::condition(const Service *srv) { const IPService *ip = IPService::constcast(srv); return (ip && !ip->getTOSCode().empty()); } bool Compiler::splitIpOptions::condition(const Service *srv) { const IPService *ip = IPService::constcast(srv); return (ip && ip->hasIpOptions()); } bool Compiler::separateTCPWithFlags::condition(const Service *srv) { const TCPService *s = TCPService::constcast(srv); return (s && s->inspectFlags() ); } bool Compiler::separatePortRanges::condition(const Service *srv) { if ( TCPService::isA(srv) || UDPService::isA(srv) ) { unsigned srs = TCPUDPService::constcast(srv)->getSrcRangeStart(); unsigned sre = TCPUDPService::constcast(srv)->getSrcRangeEnd(); unsigned drs = TCPUDPService::constcast(srv)->getDstRangeStart(); unsigned dre = TCPUDPService::constcast(srv)->getDstRangeEnd(); if (srs!=0 && sre==0) sre = srs; if (drs!=0 && dre==0) dre = drs; /* * I also need to separate rules that use "Any UDP" and "Any TCP" * objects. These objects have all ports set to zero and iptables code * for them should just have "-p udp" or "-p tcp" without any * "--source-port" or "--destination-port" specification. Commands * like this do not combine with commands that do specify port because * they lose their "any udp"/"any tcp" meaning as soon as * "--source-port"/"--destination-port" is added. */ if (srs==0 && sre==0 && drs==0 && dre==0) { sre = 65535; dre = 65535; } return (srs!=sre || drs!=dre); } return false; } bool Compiler::verifyCustomServices::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string re_type = PolicyRule::isA(rule) ? RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME; RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type)); tmp_queue.push_back(rule); for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++) { FWObject *o = FWReference::getObject(*i); assert(o!=NULL); if (CustomService::isA(o) && CustomService::cast(o)->getCodeForPlatform(compiler->myPlatformName()).empty()) throw FWException("Custom service is not configured for the platform '"+compiler->myPlatformName()+"'. Rule "+rule->getLabel()); } return true; } bool Compiler::CheckForTCPEstablished::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string re_type = PolicyRule::isA(rule) ? RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME; RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type)); for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++) { FWObject *o = FWReference::getObject(*i); TCPService *s = TCPService::cast( o ); if (s==NULL) continue; if (s->getEstablished()) compiler->abort( rule, string("TCPService object with option \"established\" " "is not supported by firewall platform \"") + compiler->myPlatformName() + string("\". Use stateful rule instead.")); } tmp_queue.push_back(rule); return true; } bool Compiler::CheckForUnsupportedUserService::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string re_type = PolicyRule::isA(rule) ? RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME; RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type)); for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++) { FWObject *o = FWReference::getObject(*i); if (UserService::isA(o)) compiler->abort( rule, string("UserService object is not supported by ") + compiler->myPlatformName()); } tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/GroupRegistry.h0000644000175000017500000000366311733011756026203 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GROUP_REGISTRY_HH__ #define __GROUP_REGISTRY_HH__ #include "fwbuilder/FWObject.h" #include #include #include namespace libfwbuilder { class RuleElement; }; class GroupRegistry { // key: object Id, value: a set of names of groups it belongs to std::map > group_registry; // key: rule element id, value: a set of names of groups that belonged to it std::map > rule_element_groups; std::string getREKey(libfwbuilder::RuleElement *re); public: GroupRegistry(); void registerGroup(libfwbuilder::FWObject *grp, const std::list &objects); void registerGroupInRE(libfwbuilder::RuleElement *re, libfwbuilder::FWObject *grp); std::set getGroupsForRE(libfwbuilder::RuleElement *re); std::set getGroupsForObject(libfwbuilder::FWObject *obj); std::string getGroupRegistryKey(libfwbuilder::FWObject *obj); void setGroupRegistryKey(libfwbuilder::FWObject *obj, const std::string &key); }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/NATCompiler.cpp0000644000175000017500000007313311733011756026025 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "NATCompiler.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPUDPService.h" #include "fwbuilder/CustomService.h" #include #include #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; int NATCompiler::prolog() { Compiler::prolog(); NAT *nat = NAT::cast(fw->getFirstByType(NAT::TYPENAME)); assert(nat); if (source_ruleset == NULL) source_ruleset = nat; source_ruleset->renumberRules(); temp_ruleset = new NAT(); // working copy of the policy fw->add( temp_ruleset ); temp_ruleset->setName(source_ruleset->getName()); int global_num = 0; string label_prefix = ""; if (source_ruleset->getName() != "NAT") label_prefix = source_ruleset->getName(); int rule_counter = 0; for (FWObject::iterator i=source_ruleset->begin(); i!=source_ruleset->end(); i++) { Rule *r = Rule::cast(*i); if (r == NULL) continue; // skip RuleSetOptions object /* * do not remove disabled rules just yet because some * compilers might use RuleSet::insertRuleAtTop() and other * similar methods from prolog() or * addPredefinedPolicyRules()() and these methods renumber * rules (labels stop matching rule positions when this is * done because labels are configured in prolog() method of * the base class. See fwbuilder ticket 1173) */ //if (r->isDisabled()) continue; //r->setInterfaceId(-1); if (r->getLabel().empty()) r->setLabel( createRuleLabel(label_prefix, "NAT", r->getPosition()) ); r->setAbsRuleNumber(global_num); global_num++; rule_counter++; } initialized = true; return rule_counter; } bool NATCompiler::checkForShadowing(NATRule &r1, NATRule &r2) { Address *osrc1; //=getFirstOSrc(&r1); Address *odst1; //=getFirstODst(&r1); Service *osrv1; //=getFirstOSrv(&r1); Address *osrc2; //=getFirstOSrc(&r2); Address *odst2; //=getFirstODst(&r2); Service *osrv2; //=getFirstOSrv(&r2); FWObject::iterator i1 = r1.begin(); osrc1 = Address::cast(FWReference::cast((*i1)->front())->getPointer()); i1++; odst1 = Address::cast(FWReference::cast((*i1)->front())->getPointer()); i1++; osrv1 = Service::cast(FWReference::cast((*i1)->front())->getPointer()); i1 = r2.begin(); osrc2 = Address::cast(FWReference::cast((*i1)->front())->getPointer()); i1++; odst2 = Address::cast(FWReference::cast((*i1)->front())->getPointer()); i1++; osrv2 = Service::cast(FWReference::cast((*i1)->front())->getPointer()); if (osrc1==NULL || odst1==NULL || osrv1==NULL) throw FWException("Can not compare rules because rule "+r1.getLabel()+" has a group in one of its elements. Aborting."); if (osrc2==NULL || odst2==NULL || osrv2==NULL) throw FWException("Can not compare rules because rule "+r2.getLabel()+" has a group in one of its elements. Aborting."); return ( Compiler::checkForShadowing(*osrc1, *osrc2) && Compiler::checkForShadowing(*odst1, *odst2) && Compiler::checkForShadowing(*osrv1, *osrv2) ); // if ( (*osrc2 <= *osrc1) && (*odst2 <= *odst1) && (*osrv2 <= *osrv1) ) return 1; return false; } /* * TODO: implement this */ bool NATCompiler::cmpRules(NATRule&, NATRule&) { return false; } bool NATCompiler::classifyNATRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()!=NATRule::Unknown) return true; RuleElementTSrc *tsrcre = rule->getTSrc(); RuleElementTDst *tdstre = rule->getTDst(); RuleElementTSrv *tsrvre = rule->getTSrv(); Service *osrv = compiler->getFirstOSrv(rule); Address *tsrc = compiler->getFirstTSrc(rule); Address *tdst = compiler->getFirstTDst(rule); Service *tsrv = compiler->getFirstTSrv(rule); if (rule->getAction() == NATRule::Branch) { rule->setRuleType(NATRule::NATBranch); if (!tsrcre->isAny() || !tdstre->isAny() || !tsrvre->isAny()) { tsrcre->clearChildren(); tsrcre->setAnyElement(); tdstre->clearChildren(); tdstre->setAnyElement(); tsrvre->clearChildren(); tsrvre->setAnyElement(); compiler->warning( rule, "Translated Src, Dst and Srv are ignored in the NAT " "rule with action 'Branch'"); } return true; } if (tsrc->isAny() && tdst->isAny() && tsrv->isAny()) { rule->setRuleType(NATRule::NONAT); return true; } bool osrv_defines_src_port = false; bool osrv_defines_dst_port = false; bool tsrv_translates_src_port = false; bool tsrv_translates_dst_port = false; if (TCPUDPService::cast(osrv) && TCPUDPService::cast(tsrv)) { TCPUDPService *tu_osrv = TCPUDPService::cast(osrv); TCPUDPService *tu_tsrv = TCPUDPService::cast(tsrv); osrv_defines_src_port = (tu_osrv->getSrcRangeStart() != 0 && tu_osrv->getDstRangeStart() == 0); osrv_defines_dst_port = (tu_osrv->getSrcRangeStart() == 0 && tu_osrv->getDstRangeStart() != 0); tsrv_translates_src_port = (tu_tsrv->getSrcRangeStart() != 0 && tu_tsrv->getDstRangeStart() == 0); tsrv_translates_dst_port = (tu_tsrv->getSrcRangeStart() == 0 && tu_tsrv->getDstRangeStart() != 0); if (tsrv_translates_dst_port && tu_osrv->getDstRangeStart() == tu_tsrv->getDstRangeStart() && tu_osrv->getDstRangeEnd() == tu_tsrv->getDstRangeEnd()) tsrv_translates_dst_port = false; // osrv and tsrv define the same ports if (tsrv_translates_src_port && tu_osrv->getSrcRangeStart() == tu_tsrv->getSrcRangeStart() && tu_osrv->getSrcRangeEnd() == tu_tsrv->getSrcRangeEnd()) tsrv_translates_src_port = false; // osrv and tsrv define the same ports } if (!osrv->isAny() && !tsrv->isAny() && !( *osrv == *tsrv ) ) // have operator==, but do not have operator!= { bool translation_ok = true; if (osrv->getTypeName() != tsrv->getTypeName()) { translation_ok = false; // see #1685. Custom service needs special treatment if (CustomService::isA(osrv) && (Service::cast(osrv)->getProtocolName() == Service::cast(tsrv)->getProtocolName())) translation_ok = true; } if (!translation_ok) compiler->abort(rule, "NAT rule can not change service types: " + osrv->getTypeName() + " to " + tsrv->getTypeName()); } /* * SDNAT rule is rather special. We should split it onto two normal * rules, one SNAT and another DNAT and run this rule processor again * for each. This algorithm should be implemented for each platform * separately. Platforms where it does not seem possible to implement * at all should catch SDNAT rules and abort in their own * verifyNATRule processor. */ if ( ( ! tsrc->isAny() && ! tdst->isAny() ) || ( ! tsrc->isAny() && tsrv_translates_dst_port) || ( ! tdst->isAny() && tsrv_translates_src_port) ) { rule->setRuleType(NATRule::SDNAT); return true; } if ( (! tsrc->isAny() && tdst->isAny()) || (tsrc->isAny() && tdst->isAny() && tsrv_translates_src_port) ) { if ( ! tsrc->isAny() && Network::isA(tsrc) ) /* * this is Netnat rule ( NETMAP in iptables) * we always do additional sanity checks in VerifyRules */ rule->setRuleType(NATRule::SNetnat); else rule->setRuleType(NATRule::SNAT); return true; } if ( (tsrc->isAny() && ! tdst->isAny() ) || (tsrc->isAny() && tdst->isAny() && tsrv_translates_dst_port) ) { /* this is load balancing rule if there are multiple objects in TDst */ if ( tdstre->size()>1 ) rule->setRuleType(NATRule::LB); else { if (! tdst->isAny() && Network::isA(tdst) ) /* * this is Netnat rule ( NETMAP in iptables) * we always do additional sanity checks in VerifyRules */ rule->setRuleType(NATRule::DNetnat); else { /* * treat it as redirect only if TDst is a firewall object. Use DNAT * if it is interface or an address; this allows for "redirects" to specific * interface on the firewall which comes useful for example if http proxy is * running only on internal interface. */ if ( tdst->getId()==compiler->fw->getId()) rule->setRuleType(NATRule::Redirect); else rule->setRuleType(NATRule::DNAT); // if ( compiler->complexMatch(tdst,compiler->fw) ) rule->setRuleType(NATRule::Redirect); // else rule->setRuleType(NATRule::DNAT); } } return true; } compiler->abort(rule, "Unsupported NAT rule"); return false; } bool NATCompiler::ExpandMultipleAddresses::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *rel; switch (rule->getRuleType()) { case NATRule::NONAT: case NATRule::Return: { rel=rule->getOSrc(); assert(rel); compiler->_expand_addr(rule, rel, true); rel=rule->getODst(); assert(rel); compiler->_expand_addr(rule, rel, true); break; } case NATRule::SNAT: case NATRule::SDNAT: { rel=rule->getOSrc(); assert(rel); compiler->_expand_addr(rule, rel, true); rel=rule->getODst(); assert(rel); compiler->_expand_addr(rule, rel, true); rel=rule->getTSrc(); assert(rel); compiler->_expand_addr(rule, rel, false); rel=rule->getTDst(); assert(rel); compiler->_expand_addr(rule, rel, false); break; } case NATRule::DNAT: { rel=rule->getOSrc(); assert(rel); compiler->_expand_addr(rule, rel, true); rel=rule->getODst(); assert(rel); compiler->_expand_addr(rule, rel, false); rel=rule->getTSrc(); assert(rel); compiler->_expand_addr(rule, rel, false); rel=rule->getTDst(); assert(rel); compiler->_expand_addr(rule, rel, false); break; } case NATRule::Redirect: { rel=rule->getOSrc(); assert(rel); compiler->_expand_addr(rule, rel, true); rel=rule->getODst(); assert(rel); compiler->_expand_addr(rule, rel, false); rel=rule->getTSrc(); assert(rel); compiler->_expand_addr(rule, rel, false); break; } default: break; } return true; } bool NATCompiler::ExpandAddressRanges::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *rel; rel=rule->getOSrc(); assert(rel); compiler->_expandAddressRanges(rule,rel); rel=rule->getODst(); assert(rel); compiler->_expandAddressRanges(rule,rel); rel=rule->getTSrc(); assert(rel); compiler->_expandAddressRanges(rule,rel); rel=rule->getTDst(); assert(rel); compiler->_expandAddressRanges(rule,rel); return true; } bool NATCompiler::ExpandGroups::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *osrc=rule->getOSrc(); assert(osrc); RuleElement *odst=rule->getODst(); assert(odst); RuleElement *osrv=rule->getOSrv(); assert(osrv); RuleElement *tsrc=rule->getTSrc(); assert(tsrc); RuleElement *tdst=rule->getTDst(); assert(tdst); RuleElement *tsrv=rule->getTSrv(); assert(tsrv); compiler->expandGroupsInRuleElement(osrc); compiler->expandGroupsInRuleElement(odst); compiler->expandGroupsInRuleElement(osrv); compiler->expandGroupsInRuleElement(tsrc); compiler->expandGroupsInRuleElement(tdst); compiler->expandGroupsInRuleElement(tsrv); return true; } bool NATCompiler::expandGroupsInItfInb::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; RuleElementItfInb *itf = rule->getItfInb(); compiler->expandGroupsInRuleElement(itf); tmp_queue.push_back(rule); return true; } bool NATCompiler::expandGroupsInItfOutb::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; RuleElementItfOutb *itf = rule->getItfOutb(); compiler->expandGroupsInRuleElement(itf); tmp_queue.push_back(rule); return true; } bool NATCompiler::checkForUnnumbered::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if ( compiler->catchUnnumberedIfaceInRE( rule->getOSrc() ) || compiler->catchUnnumberedIfaceInRE( rule->getODst() ) || compiler->catchUnnumberedIfaceInRE( rule->getTSrc() ) || compiler->catchUnnumberedIfaceInRE( rule->getTDst() ) ) compiler->abort( rule, "Can not use unnumbered interfaces in rules. "); tmp_queue.push_back(rule); return true; } bool NATCompiler::ConvertToAtomicForOriginal::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); for (FWObject::iterator i1=osrc->begin(); i1!=osrc->end(); ++i1) { for (FWObject::iterator i2=odst->begin(); i2!=odst->end(); ++i2) { for (FWObject::iterator i3=osrv->begin(); i3!=osrv->end(); ++i3) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getOSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); s=r->getODst(); assert(s); s->clearChildren(); s->addCopyOf( *i2 ); s=r->getOSrv(); assert(s); s->clearChildren(); s->addCopyOf( *i3 ); tmp_queue.push_back(r); } } } return true; } bool NATCompiler::ConvertToAtomicForAddresses::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); for (FWObject::iterator i1=osrc->begin(); i1!=osrc->end(); ++i1) { for (FWObject::iterator i2=odst->begin(); i2!=odst->end(); ++i2) { for (FWObject::iterator i4=tsrc->begin(); i4!=tsrc->end(); ++i4) { for (FWObject::iterator i5=tdst->begin(); i5!=tdst->end(); ++i5) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getOSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); s=r->getODst(); assert(s); s->clearChildren(); s->addCopyOf( *i2 ); // s=r->getOSrv(); assert(s); // *s=*osrv; s=r->getTSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i4 ); s=r->getTDst(); assert(s); s->clearChildren(); s->addCopyOf( *i5 ); // s=r->getTSrv(); assert(s); // *s=*tsrv; tmp_queue.push_back(r); } } } } return true; } bool NATCompiler::ConvertToAtomicForOSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); for (FWObject::iterator i1=osrv->begin(); i1!=osrv->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getOSrv(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool NATCompiler::ConvertToAtomicForTSrc::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); for (FWObject::iterator i1=tsrc->begin(); i1!=tsrc->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getTSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool NATCompiler::ConvertToAtomicForTDst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementTDst *tsrc=rule->getTDst(); assert(tsrc); for (FWObject::iterator i1=tsrc->begin(); i1!=tsrc->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getTDst(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool NATCompiler::ConvertToAtomicForTSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementTSrv *tsrc=rule->getTSrv(); assert(tsrc); for (FWObject::iterator i1=tsrc->begin(); i1!=tsrc->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getTSrv(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool NATCompiler::ConvertToAtomicForItfInb::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementItfInb *itf_inb_re=rule->getItfInb(); assert(itf_inb_re); for (FWObject::iterator i1=itf_inb_re->begin(); i1!=itf_inb_re->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s = r->getItfInb(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool NATCompiler::ConvertToAtomicForItfOutb::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementItfOutb *itf_outb_re=rule->getItfOutb(); assert(itf_outb_re); for (FWObject::iterator i1=itf_outb_re->begin(); i1!=itf_outb_re->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s = r->getItfOutb(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool NATCompiler::ConvertToAtomic::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); for (FWObject::iterator i1=osrc->begin(); i1!=osrc->end(); ++i1) { for (FWObject::iterator i2=odst->begin(); i2!=odst->end(); ++i2) { for (FWObject::iterator i3=osrv->begin(); i3!=osrv->end(); ++i3) { for (FWObject::iterator i4=tsrc->begin(); i4!=tsrc->end(); ++i4) { for (FWObject::iterator i5=tdst->begin(); i5!=tdst->end(); ++i5) { for (FWObject::iterator i6=tsrv->begin(); i6!=tsrv->end(); ++i6) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getOSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); s=r->getODst(); assert(s); s->clearChildren(); s->addCopyOf( *i2 ); s=r->getOSrv(); assert(s); s->clearChildren(); s->addCopyOf( *i3 ); s=r->getTSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i4 ); s=r->getTDst(); assert(s); s->clearChildren(); s->addCopyOf( *i5 ); s=r->getTSrv(); assert(s); s->clearChildren(); s->addCopyOf( *i6 ); tmp_queue.push_back(r); } } } } } } return true; } bool NATCompiler::MACFiltering::checkRuleElement(RuleElement *re) { bool res=true; std::list lst; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if (physAddress::isA(o)) { lst.push_back(o); res=false; } } for (FWObject::iterator i1=lst.begin(); i1!=lst.end(); i1++) re->removeRef(*i1); return res; } bool NATCompiler::MACFiltering::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *osrc=rule->getOSrc(); RuleElement *odst=rule->getODst(); string lbl=rule->getLabel(); if ( ! checkRuleElement(osrc) ) { if (last_rule_lbl!=lbl) compiler->warning( rule, "MAC address matching is not supported. One or several MAC addresses removed from Original Source "); if (osrc->empty() || osrc->isAny()) compiler->abort( rule, "Original Source becomes 'Any' after all MAC addresses have been removed"); last_rule_lbl=lbl; } if ( ! checkRuleElement(odst) ) { if (last_rule_lbl!=lbl) compiler->warning( rule, "MAC address matching is not supported. One or several MAC addresses removed from Original Destination "); if (odst->empty() || odst->isAny()) compiler->abort( rule, "Original Destination becomes 'Any' after all MAC addresses have been removed"); last_rule_lbl=lbl; } return true; } /* * splits rule if ODst has multiple objects that belong to different * subnets */ bool NATCompiler::splitODstForSNAT::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if (rule->getRuleType()==NATRule::SNAT) { RuleElementODst *rel=rule->getODst(); if (!rel->isAny() && rel->size()>1) { map > il; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o = FWReference::getObject(*i); Address *a=Address::cast(o); string iid=""; Interface *iface=compiler->findInterfaceFor( a , compiler->fw ); if (iface!=NULL) iid=iface->getId(); il[iid].push_back( a ); } if (il.size()>1) { map >::iterator j; for (j=il.begin(); j!=il.end(); j++) { NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementODst *nodst=r->getODst(); nodst->clearChildren(); list::iterator k; for (k= j->second.begin(); k!=j->second.end(); k++) nodst->addRef( *k ); tmp_queue.push_back(r); } } else tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); return true; } string NATCompiler::debugPrintRule(libfwbuilder::Rule *r) { NATRule *rule = NATRule::cast(r); RuleElementOSrc *osrcrel = rule->getOSrc(); RuleElementODst *odstrel = rule->getODst(); RuleElementOSrv *osrvrel = rule->getOSrv(); RuleElementTSrc *tsrcrel = rule->getTSrc(); RuleElementTDst *tdstrel = rule->getTDst(); RuleElementTSrv *tsrvrel = rule->getTSrv(); RuleElementItfInb *itf_inb_rel = rule->getItfInb(); RuleElementItfOutb *itf_outb_rel = rule->getItfOutb(); ostringstream str; // str << setw(70) << setfill('-') << "-"; int no = 0; FWObject::iterator i1 = osrcrel->begin(); FWObject::iterator i2 = odstrel->begin(); FWObject::iterator i3 = osrvrel->begin(); FWObject::iterator i4 = tsrcrel->begin(); FWObject::iterator i5 = tdstrel->begin(); FWObject::iterator i6 = tsrvrel->begin(); FWObject::iterator i7 = itf_inb_rel->begin(); FWObject::iterator i8 = itf_outb_rel->begin(); while ( i1!=osrcrel->end() || i2!=odstrel->end() || i3!=osrvrel->end() || i4!=tsrcrel->end() || i5!=tdstrel->end() || i6!=tsrvrel->end() || i7!=itf_inb_rel->end() || i8!=itf_outb_rel->end()) { str << endl; string osrc = " "; string odst = " "; string osrv = " "; string tsrc = " "; string tdst = " "; string tsrv = " "; string itf_inb = " "; string itf_outb = " "; if (osrcrel->getNeg()) osrc = "!"; if (odstrel->getNeg()) odst = "!"; if (osrvrel->getNeg()) osrv = "!"; if (tsrcrel->getNeg()) tsrc = "!"; if (tdstrel->getNeg()) tdst = "!"; if (tsrvrel->getNeg()) tsrv = "!"; if (itf_inb_rel->getNeg()) itf_inb = "!"; if (itf_outb_rel->getNeg()) itf_outb = "!"; int osrc_id = -1; int odst_id = -1; int osrv_id = -1; int tsrc_id = -1; int tdst_id = -1; int tsrv_id = -1; int itf_inb_id = -1; int itf_outb_id = -1; if (i1!=osrcrel->end()) { FWObject *o = FWReference::getObject(*i1); osrc += o->getName(); osrc_id = o->getId(); } if (i2!=odstrel->end()) { FWObject *o = FWReference::getObject(*i2); odst += o->getName(); odst_id = o->getId(); } if (i3!=osrvrel->end()) { FWObject *o = FWReference::getObject(*i3); osrv += o->getName(); osrv_id = o->getId(); } if (i4!=tsrcrel->end()) { FWObject *o = FWReference::getObject(*i4); tsrc += o->getName(); tsrc_id = o->getId(); } if (i5!=tdstrel->end()) { FWObject *o = FWReference::getObject(*i5); tdst += o->getName(); tdst_id = o->getId(); } if (i6!=tsrvrel->end()) { FWObject *o = FWReference::getObject(*i6); tsrv += o->getName(); tsrv_id = o->getId(); } if (i7!=itf_inb_rel->end()) { FWObject *o = FWReference::getObject(*i7); itf_inb += o->getName(); itf_inb_id = o->getId(); } if (i8!=itf_outb_rel->end()) { FWObject *o = FWReference::getObject(*i8); itf_outb += o->getName(); itf_outb_id = o->getId(); } int w = 0; if (no==0) { str << rule->getLabel(); w = rule->getLabel().length(); } str << setw(8-w) << setfill(' ') << " "; str << setw(16) << setfill(' ') << osrc.c_str() << "(" << osrc_id << ")"; str << setw(16) << setfill(' ') << odst.c_str() << "(" << odst_id << ")"; str << setw(10) << setfill(' ') << osrv.c_str() << "(" << osrv_id << ")"; // str << endl; // // str << setw(8) << setfill(' ') << " "; str << setw(16) << setfill(' ') << tsrc.c_str() << "(" << tsrc_id << ")"; str << setw(16) << setfill(' ') << tdst.c_str() << "(" << tdst_id << ")"; str << setw(10) << setfill(' ') << tsrv.c_str() << "(" << tsrv_id << ")"; str << setw(10) << setfill(' ') << itf_inb.c_str() << "(" << itf_inb_id << ")"; str << setw(10) << setfill(' ') << itf_outb.c_str() << "(" << itf_outb_id << ")"; ++no; if ( i1!=osrcrel->end() ) ++i1; if ( i2!=odstrel->end() ) ++i2; if ( i3!=osrvrel->end() ) ++i3; if ( i4!=tsrcrel->end() ) ++i4; if ( i5!=tdstrel->end() ) ++i5; if ( i6!=tsrvrel->end() ) ++i6; if ( i7!=itf_inb_rel->end() ) ++i7; if ( i8!=itf_outb_rel->end() ) ++i8; } return str.str(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/BaseCompiler.cpp0000644000175000017500000001534111733011756026252 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include "BaseCompiler.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; FWCompilerException::FWCompilerException(Rule *r, const string &err) : FWException(err) { rule=r; } bool BaseCompiler::haveErrorsAndWarnings() { return (int(errors_buffer.tellp()) > 0); } string BaseCompiler::getErrors(const string &comment_sep) { ostringstream ostr; istringstream istr(errors_buffer.str()); while (!istr.eof()) { string tmpstr; getline(istr, tmpstr); if (tmpstr.length()) ostr << comment_sep << tmpstr << endl; } return ostr.str(); } void BaseCompiler::clearErrors() { errors_buffer.str(""); rule_errors.clear(); } string BaseCompiler::getErrorsForRule(Rule *rule, const std::string &comment_sep) { string rule_label = rule->getLabel(); rule_errors[rule_label].sort(); ostringstream ostr; list::iterator it; string prev; // used to remove duplicate messages for (it=rule_errors[rule_label].begin(); it!=rule_errors[rule_label].end(); ++it) { if (*it != prev) ostr << comment_sep << *it << endl; prev = *it; } return ostr.str(); } /* * Error and warning format: * * fw-object-name:ruleset-name:rule-number: message */ string BaseCompiler::stdErrorMessage(FWObject *fw, FWObject *ruleset, FWObject *rule, const std::string &errstr) { ostringstream tmpstr; // TODO: (some day) get rid of the argument @fw and use attribute // ".ruleset_owner" instead. Set this attribute in the place where // we prepare rules for processing and copy them to the // queue. This way, when CompilerDriver prepares rules from the // cluster, it can override the same attribute to make error and // warning messges refer to correct object that really owns rule // sets. string ruleset_owner; if (ruleset) { ruleset_owner = ruleset->getStr(".ruleset_owner"); } if (ruleset_owner.empty() && fw) ruleset_owner = fw->getName(); tmpstr << ruleset_owner << ":"; if (ruleset) tmpstr << ruleset->getName(); tmpstr << ":"; if (rule && Rule::cast(rule)) tmpstr << Rule::cast(rule)->getPosition(); tmpstr << ": "; tmpstr << level_macro << ": "; tmpstr << errstr; return tmpstr.str(); } string BaseCompiler::setLevel(const string &level, const string &errstr) { string str = errstr; while (str.at(str.length() - 1) == '\n') str = str.substr(0, str.length() - 1); size_t n = str.find(level_macro); if (n != string::npos) str.replace(n, level_macro.length(), level); return str; } void BaseCompiler::message(const std::string &level, FWObject *fw, FWObject *ruleset, FWObject *rule, const string &errstr) { string str = setLevel(level, stdErrorMessage(fw, ruleset, rule, errstr)); printError(str); Rule *cast_rule = Rule::cast(rule); if (cast_rule) { cast_rule->setCompilerMessage(str); rule_errors[cast_rule->getLabel()].push_back(str); } } void BaseCompiler::printError(const string &errstr) { if (!inEmbeddedMode()) { cout << flush; cerr << errstr << endl; } errors_buffer << errstr << endl; } /* * Note that when this code runs as part of the command line compiler * rather than as a single-rule compile function inside the GUI (that * is, it is not in embedded mode) and if test mode was activated * (usually via command line flag "-xt"), then abort() behaves as * error(), that is, it prints error message but does not terminate * the process but just returns. In embedded mode it always throws * exception to stop compiling */ void BaseCompiler::abort(const string &errstr) throw(FWException) { printError(errstr); if (inEmbeddedMode()) throw FatalErrorInSingleRuleCompileMode(errors_buffer.str()); status = FWCOMPILER_ERROR; if (test_mode) return; throw FWException("Fatal error"); } void BaseCompiler::abort(FWObject *fw, FWObject *ruleset, FWObject *rule, const string &errstr) throw(FWException) { message("error", fw, ruleset, rule, errstr); if (inEmbeddedMode()) throw FatalErrorInSingleRuleCompileMode(errors_buffer.str()); status = FWCOMPILER_ERROR; if (test_mode) return; throw FWException("Fatal error"); } void BaseCompiler::error(const string &str) { status = FWCOMPILER_ERROR; printError(str); } void BaseCompiler::error(FWObject *fw, FWObject *ruleset, FWObject *rule, const string &errstr) { status = FWCOMPILER_ERROR; message("error", fw, ruleset, rule, errstr); } void BaseCompiler::warning(const string &str) { printError(str); } void BaseCompiler::warning(FWObject *fw, FWObject *ruleset, FWObject *rule, const string &errstr) { message("warning", fw, ruleset, rule, errstr); } void BaseCompiler::info(const string &str) { if (!inEmbeddedMode()) { cout << str << endl << flush; } } void BaseCompiler::errorRegExp(std::list *err_regexp) { err_regexp->clear(); err_regexp->push_back("([^:]*):([^:]*):.*[Ee]rror:"); err_regexp->push_back("(Error(:| )[^\n]*)"); } void BaseCompiler::warningRegExp(std::list *warn_regexp) { warn_regexp->clear(); warn_regexp->push_back("([^:]*):([^:]*):.*[Ww]arning:"); warn_regexp->push_back("(Warning(:| )[^\n]*)"); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Preprocessor.h0000644000175000017500000000421111733011756026032 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ###################################################################### Class Preprocessor performs various operations on the original copy of the object database before other compilers are called to process rules. All other cmpilers create a local copy copy of the database and work with it, but Preprocessor works with the original database. Currently Preprocessor expands MultiAddress objects. Preprocessor can be overloaded as any other Compiler with customizations added to its prolog() or compile() methods. */ #ifndef __PREPROCESSOR_HH__ #define __PREPROCESSOR_HH__ #include "fwcompiler/Compiler.h" #include "fwbuilder/FWObjectDatabase.h" #include namespace fwcompiler { class Preprocessor : public Compiler { void findMultiAddressObjectsUsedInRules(libfwbuilder::FWObject *top); public: virtual std::string myPlatformName(); virtual ~Preprocessor(); Preprocessor(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy); /** * converts a single object. convertObjects calls this method for every * object that may need to be converted */ virtual void convertObject(libfwbuilder::FWObject *obj); virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/OSConfigurator.h0000644000175000017500000000365411733011756026262 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OSCONFIGURATOR_HH__ #define __OSCONFIGURATOR_HH__ #include "fwcompiler/Compiler.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/InetAddr.h" #include #include namespace fwcompiler { class OSConfigurator : public Compiler { int num_virtual_addresses_for_nat; public: virtual ~OSConfigurator(); OSConfigurator(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy); virtual void processFirewallOptions() {} virtual void addVirtualAddressForNAT(const libfwbuilder::Address*) {}; virtual void addVirtualAddressForNAT(const libfwbuilder::Network*) {}; void registerVirtualAddressForNat() { num_virtual_addresses_for_nat++; } int getNumOfVirtualAddressesForNat() { return num_virtual_addresses_for_nat; } virtual std::string printFunctions() { return ""; } virtual std::string printKernelVarsCommands() { return ""; } virtual std::string configureInterfaces() { return ""; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/BaseCompiler.h0000644000175000017500000001266011733011756025720 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BASE_COMPILER_HH__ #define __BASE_COMPILER_HH__ #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Rule.h" #include "fwcompiler/exceptions.h" #include namespace fwcompiler { class FWCompilerException : public libfwbuilder::FWException { libfwbuilder::Rule *rule; public: FWCompilerException(libfwbuilder::Rule *r,const std::string &err); libfwbuilder::Rule *getRule() const { return rule; } }; class BaseCompiler { std::string level_macro; // all errors generated by the compiler std::stringstream errors_buffer; // a dictionary mapping rule label to the list of errors associated // with it. std::map > rule_errors; // in test mode we trat fatal errors as errors and continue after // printing error message bool test_mode; // this is single-rule-compile mode; compiler is embedded in the GUI bool embedded_mode; /** * assembles standard error message using format similar to * the error message format of gcc. Useful to prepare errors * and warnings before calling error() or warning() methods */ std::string stdErrorMessage(libfwbuilder::FWObject *fw, libfwbuilder::FWObject *ruleset, libfwbuilder::FWObject *rule, const std::string &errstr); std::string setLevel(const std::string &level, const std::string &errstr); void printError(const std::string &errstr); void message(const std::string &level, libfwbuilder::FWObject *fw, libfwbuilder::FWObject *ruleset, libfwbuilder::FWObject *rule, const std::string &errstr); public: typedef enum {FWCOMPILER_SUCCESS, FWCOMPILER_ERROR} termination_status; protected: termination_status status; public: virtual void setTestMode() { test_mode = true; } bool inTestMode() { return test_mode; } virtual void setEmbeddedMode() { embedded_mode = true; } bool inEmbeddedMode() { return embedded_mode; } termination_status getStatus() { return status; } /** * prints error message and aborts the program. If compiler is * in testing mode (flag test_mode==true), then just prints * the error message and returns. */ virtual void abort(const std::string &errstr) throw(libfwbuilder::FWException); virtual void abort(libfwbuilder::FWObject *fw, libfwbuilder::FWObject *ruleset, libfwbuilder::FWObject *rule, const std::string &errstr) throw(libfwbuilder::FWException); /** * prints an error message and returns */ virtual void error(const std::string &warnstr); virtual void error(libfwbuilder::FWObject *fw, libfwbuilder::FWObject *ruleset, libfwbuilder::FWObject *rule, const std::string &warnstr); /** * prints warning message */ virtual void warning(const std::string &warnstr); virtual void warning(libfwbuilder::FWObject *fw, libfwbuilder::FWObject *ruleset, libfwbuilder::FWObject *rule, const std::string &warnstr); /** * prints info message. These are only printed to stdout if compiler * is not in embedded mode. In embedded mode info messages are ignored. */ virtual void info(const std::string &warnstr); virtual ~BaseCompiler() {}; BaseCompiler() { test_mode = false; embedded_mode = false; level_macro = "%LEVEL%"; status = FWCOMPILER_SUCCESS; }; std::string getErrors(const std::string &comment_sep); bool haveErrorsAndWarnings(); void clearErrors(); std::string getErrorsForRule(libfwbuilder::Rule *rule, const std::string &comment_sep); /** * fills a list of strings with regular expressions that match * error messages */ static void errorRegExp(std::list *err_regexp); /** * fills a list of strings with regular expressions that match * warning messages */ static void warningRegExp(std::list *warn_regexp); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/GroupRegistry.cpp0000644000175000017500000000524511733011756026534 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "GroupRegistry.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" using namespace libfwbuilder; using namespace std; GroupRegistry::GroupRegistry() {} /* * Generate stable key to be used as a key in rule_element_groups map. * This key should not change when rule processors create copies of * rules, this means we can't use rule and rule element ID. */ string GroupRegistry::getREKey(libfwbuilder::RuleElement *re) { Rule *rule = Rule::cast(re->getParent()); return rule->getLabel() + "_" + re->getTypeName(); } void GroupRegistry::registerGroup(FWObject *grp, const list &objects) { for (list::const_iterator it=objects.begin(); it!=objects.end(); ++it) { FWObject *o = FWReference::getObject(*it); string str_id = FWObjectDatabase::getStringId(o->getId()); group_registry[str_id].insert(grp->getName()); setGroupRegistryKey(o, str_id); } } /* * register a group as a member of given rule element. */ void GroupRegistry::registerGroupInRE(RuleElement *re, FWObject *grp) { string key_str = getREKey(re); rule_element_groups[key_str].insert(grp->getName()); } set GroupRegistry::getGroupsForRE(RuleElement *re) { string key_str = getREKey(re); return rule_element_groups[key_str]; } set GroupRegistry::getGroupsForObject(FWObject *obj) { return group_registry[getGroupRegistryKey(obj)]; } string GroupRegistry::getGroupRegistryKey(FWObject *obj) { return obj->getStr(".group_registry_key"); } void GroupRegistry::setGroupRegistryKey(FWObject *obj, const std::string &key) { obj->setStr(".group_registry_key", key); for (FWObject::iterator i=obj->begin(); i!=obj->end(); i++) { setGroupRegistryKey(*i, key); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Compiler.h0000644000175000017500000011362411733011756025127 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_HH__ #define __COMPILER_HH__ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwcompiler/BaseCompiler.h" #include "fwcompiler/RuleProcessor.h" #include "fwcompiler/exceptions.h" #include "fwcompiler/GroupRegistry.h" #include #include #include #include #include namespace libfwbuilder { class FWObject; class FWOptions; class FWObjectDatabase; class InetAddr; class Address; class Cluster; class FailoverClusterGroup; class StateSyncClusterGroup; class Service; class Interval; class IPv4; class IPv6; class Network; class NetworkIPv6; class AddressRange; class Host; class physAddress; class Firewall; class Interface; class Rule; class RuleSet; class PolicyRule; class NATRule; class RuleElement; }; namespace fwcompiler { class OSConfigurator; /* * operations (see Compiler_ops.cc) */ /** * this operator compares two objects to determine if they are * equivalent */ bool operator==(const libfwbuilder::Address &o1,const libfwbuilder::Address &o2); bool operator==(const libfwbuilder::Service &o1,const libfwbuilder::Service &o2); bool operator==(const libfwbuilder::Interval &o1,const libfwbuilder::Interval &o2); /** * this method finds intersection of two objects. Objects must * be of such types that have address (Host, Firewall, * Interface, Network) , otherwise it throws an exception * * TODO: implement this as a virtual method of respective classes * * this method is intended for internal use only */ std::vector _find_obj_intersection(libfwbuilder::Address *o1, libfwbuilder::Address *o2); /** * this method finds intersection of two services. If one or * both objects are not services, it throws exception * * this method is intended for internal use only */ std::vector _find_srv_intersection(libfwbuilder::Service *o1, libfwbuilder::Service *o2); /** * this method finds intersection of two ranges of ports * * this method is intended for internal use only */ bool _find_portrange_intersection(int rs1,int re1,int rs2,int re2,int &rsr,int &rer); struct threeTuple { libfwbuilder::Address *src; libfwbuilder::Address *dst; libfwbuilder::Service *srv; }; class Compiler : public BaseCompiler { void _init(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw); virtual void _expand_group_recursive(libfwbuilder::FWObject *o, std::list &ol); virtual void _expand_addr_recursive(libfwbuilder::Rule *rule, libfwbuilder::FWObject *s, std::list &ol, bool expand_cluster_interfaces_fully); /* bool _complexMatchWithInterface(libfwbuilder::Address *obj1, */ /* libfwbuilder::Interface *iface, */ /* bool recognize_broadcasts=true); */ /* bool _complexMatchWithAddress(const libfwbuilder::InetAddr *obj1_addr, */ /* libfwbuilder::Interface *iface, */ /* const std::string &address_type, */ /* bool recognize_broadcasts); */ bool checkIfAddressesMatch(const libfwbuilder::Address *a1, const libfwbuilder::Address *a2); protected: int _cntr_; bool initialized; int countIPv6Rules; bool ipv6; std::map object_comparison_cache; std::map rule_elements_cache; std::list rule_processors; /** * if object is Address, check if it matches address family * (i.e. if it is IPv6 or IPv4). If it is service, always return true. */ bool MatchesAddressFamily(libfwbuilder::FWObject *o); /** * this method finds intersection of two atomic rules. Resulting * rule may have multiple objects in src,dst and srv, so * converting to atomic may be necessary. If rules can not be * compared, then it throws an exception. If rules are compatible * but have nothing in common, then this method returns rule with * empty src,dst,srv. Use isEmpty(Rule &r) to check for this * condition * * This method creates and returns new object of class Rule * and does not modify r1 and r2 * * This method works only with interface, src, dst and srv and * completely ignores action and other rule options. * */ void getIntersection(libfwbuilder::PolicyRule &r1, libfwbuilder::PolicyRule &r2, libfwbuilder::PolicyRule &res); /** * this function checks if two rules intersect - that is, if there * is a non-empty intersection for each rule element. This * function does not calculate intersection, it just verifies that * it does exsit. */ bool intersect(libfwbuilder::PolicyRule &r1, libfwbuilder::PolicyRule &r2); /** * add rule processor to the list */ void add(BasicRuleProcessor* rp); /** * assembles chain of rule processors and executes it */ void runRuleProcessors(); /** * deletes chain of rule processors */ void deleteRuleProcessors(); /* * the following variables are simply a cache for frequently used * objects */ int fw_id; libfwbuilder::FWOptions *fwopt; public: int debug; int debug_rule; bool rule_debug_on; bool verbose; bool single_rule_mode; std::string single_rule_ruleset_name; int single_rule_position; libfwbuilder::Rule *single_rule_compile_rule; fwcompiler::OSConfigurator *osconfigurator; libfwbuilder::FWObjectDatabase *dbcopy; libfwbuilder::Library *persistent_objects; libfwbuilder::Firewall *fw; // group registry is optional, the object shuld be created outside // of the compiler and set using function setGroupRegistry(). GroupRegistry *group_registry; std::string ruleSetName;; libfwbuilder::RuleSet *source_ruleset; libfwbuilder::RuleSet *temp_ruleset; libfwbuilder::Group *temp; std::stringstream output; void registerGroupObject(libfwbuilder::RuleElement *re, libfwbuilder::ObjectGroup *grp); void registerIPv6Rule() { countIPv6Rules++; } bool haveIPv6Rules() { return countIPv6Rules > 0; } /** * returns first object referenced by given rule * element. Dereferences FWReference if first object is * reference. Uses cache, therefore is faster than * RuleElement::getFirst(true) */ libfwbuilder::Address* getFirstSrc(libfwbuilder::PolicyRule *rule); libfwbuilder::Address* getFirstDst(libfwbuilder::PolicyRule *rule); libfwbuilder::Service* getFirstSrv(libfwbuilder::PolicyRule *rule); libfwbuilder::Interval* getFirstWhen(libfwbuilder::PolicyRule *rule); libfwbuilder::Interface* getFirstItf(libfwbuilder::PolicyRule *rule); libfwbuilder::Address* getFirstOSrc(libfwbuilder::NATRule *rule); libfwbuilder::Address* getFirstODst(libfwbuilder::NATRule *rule); libfwbuilder::Service* getFirstOSrv(libfwbuilder::NATRule *rule); libfwbuilder::Address* getFirstTSrc(libfwbuilder::NATRule *rule); libfwbuilder::Address* getFirstTDst(libfwbuilder::NATRule *rule); libfwbuilder::Service* getFirstTSrv(libfwbuilder::NATRule *rule); /** * these methods compare two objects to determine if one of them * "shades" the other */ bool checkForShadowing(const libfwbuilder::Address &o1, const libfwbuilder::Address &o2); bool checkForShadowing(const libfwbuilder::Service &o1, const libfwbuilder::Service &o2); void resetObjectComparisonCache() { object_comparison_cache.clear(); } /** * a method to check for unnumbered interface in a rule * element (one can not use unnumbered interfaces in rules). */ bool catchUnnumberedIfaceInRE(libfwbuilder::RuleElement *re); /** * return true if any address object in source or destination is * of given type (can be IPv4 or IPv6). */ bool FindAddressFamilyInRE(libfwbuilder::FWObject *re, bool ipv6); /** * find ipv6 or ipv4 address objects in the given rule element * and remove reference to them */ void DropAddressFamilyInRE(libfwbuilder::RuleElement *rel, bool drop_ipv6); /** * similarly, remove reference to objects in service rule elements * based on their compatibility with ipv6 context. */ void DropByServiceTypeInRE(libfwbuilder::RuleElement *rel, bool drop_ipv6); /** * rule processor that "injects" rules into the conveyor */ class Begin : public BasicRuleProcessor { bool init; public: Begin(); Begin(const std::string &n); virtual bool processNext(); }; /** * this processor prints number of rules in the queue on cout * if compiler->verbose is true */ class printTotalNumberOfRules : public BasicRuleProcessor { public: virtual bool processNext(); }; /** * this processor creates what amounts to the new compiler * pass: it slurps all rules into buffer, then prints its own * name on cout and the releases rules to the next processor * one at a time. This way processors after this one in the * chain get to start working on the whole rule set from its * beginning. */ class createNewCompilerPass : public BasicRuleProcessor { std::string pass_name; public: createNewCompilerPass(const std::string &_name) : BasicRuleProcessor("New compiler pass") { pass_name=_name; }; virtual bool processNext(); }; /** * this processor prints rule numbers on cout (trivial * progress indicator) */ class simplePrintProgress : public BasicRuleProcessor { std::string current_rule_label; public: simplePrintProgress() : BasicRuleProcessor("Print progress") {}; virtual bool processNext(); }; /** * this processor splits rule if one of its rule elements * contains firewall itself. This processor is actually only a * base class. Derive it and pass rule element type name as a * second argument of its constructor. */ class splitIfRuleElementMatchesFW : public PolicyRuleProcessor { std::string re_type; public: splitIfRuleElementMatchesFW(const std::string &n, std::string _type) : PolicyRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /** * prepare for negation of single objects in rule elements */ class singleObjectNegation : public BasicRuleProcessor { std::string re_type; public: singleObjectNegation(const std::string &n,std::string _type): BasicRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /* * replace interfaces in the give RE with a set of all other * interfaces of the firewall. */ class fullInterfaceNegationInRE : public BasicRuleProcessor { std::string re_type; public: fullInterfaceNegationInRE(const std::string &n, std::string _type) : BasicRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /** * replace cluster interface objects with inetrfaces of the member * firewall in the Interface rule element */ class replaceClusterInterfaceInItfRE : public BasicRuleProcessor { std::string re_type; public: replaceClusterInterfaceInItfRE(const std::string &n, std::string _type) : BasicRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /** * eliminates duplicates in RuleElement 're_type'. Inherit * your own class using this one and supply actual rule * element type name through its constructor. * * Function class equalObj compares IDs of two object and * declares objects equal if their ID are the same. To * change comparison algorithm, inherit from this class, * overload its operator(), then create its instance in * constructor of eliminateDuplicatesInRE and assign to * member 'comparator' */ class equalObj { protected: libfwbuilder::FWObject *obj; public: equalObj(){obj=NULL;} virtual ~equalObj() {} void set(libfwbuilder::FWObject *o) {obj=o;} virtual bool operator()(libfwbuilder::FWObject *o); }; class eliminateDuplicatesInRE : public BasicRuleProcessor { std::string re_type; protected: equalObj *comparator; public: eliminateDuplicatesInRE(const std::string &n,const std::string _type): BasicRuleProcessor(n) { re_type=_type; comparator=NULL; } ~eliminateDuplicatesInRE() { if (comparator!=NULL) delete comparator; } virtual bool processNext(); }; /** * this processor checks for recursive groups, i.e. groups * that reference themselves */ class recursiveGroupsInRE : public BasicRuleProcessor { std::string re_type; void isRecursiveGroup(int grid, libfwbuilder::FWObject *gr); public: recursiveGroupsInRE(const std::string &n,const std::string &_type) : BasicRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /** * This rule processor checks for empty groups. Normally this * is a fatal error and compilation should be aborted, but * firewall option "ignore_rules_with_empty_groups" causes * compiler to remove this object from the rule element and * drop the rule all together if there are no more objects * left (rule element becomes "any") and continue work * (warning should be issued though). */ class emptyGroupsInRE : public BasicRuleProcessor { std::string re_type; int countChildren(libfwbuilder::FWObject *obj); void findEmptyGroupsInRE(); public: emptyGroupsInRE(const std::string &n,const std::string &_type) : BasicRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /** * Replace MultiAddress objects that require run-time address * expansion with corresponding MultiAddressRunTime objects */ class swapMultiAddressObjectsInRE : public BasicRuleProcessor { std::string re_type; public: swapMultiAddressObjectsInRE(const std::string &name, const std::string &t) : BasicRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; /** * this inspector replaces references to hosts and firewalls * in rule element with references to their interfaces */ class expandMultipleAddressesInRE : public BasicRuleProcessor { std::string re_type; public: expandMultipleAddressesInRE(const std::string &name, const std::string &t) : BasicRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; /** * drop rules that have ipv4 or ipv6 addresses (depending * on the argument ipv6 passed to the constructor) */ class DropRulesByAddressFamilyAndServiceType : public BasicRuleProcessor { std::string warning_str; bool drop_ipv6; public: DropRulesByAddressFamilyAndServiceType( const std::string &n, bool ipv6) : BasicRuleProcessor(n) { drop_ipv6 = ipv6; warning_str = ""; } virtual bool processNext(); protected: DropRulesByAddressFamilyAndServiceType( const std::string &n, const std::string &w, bool ipv6) : BasicRuleProcessor(n) { drop_ipv6 = ipv6; warning_str = w; } }; /** * Drop rule if any address object in source or destination is * ipv4 address. */ class DropIPv4Rules : public DropRulesByAddressFamilyAndServiceType { public: DropIPv4Rules(const std::string &n) : DropRulesByAddressFamilyAndServiceType(n, false) {}; }; /** * Drop rule if any address object in source or destination is * ipv6 address. */ class DropIPv6Rules : public DropRulesByAddressFamilyAndServiceType { public: DropIPv6Rules(const std::string &n) : DropRulesByAddressFamilyAndServiceType(n, true) {}; }; class DropIPv6RulesWithWarning : public DropRulesByAddressFamilyAndServiceType { public: DropIPv6RulesWithWarning(const std::string &n, const std::string &w) : DropRulesByAddressFamilyAndServiceType(n, w, true) {}; }; /** * drop rules that have empty rule elements */ class dropRuleWithEmptyRE : public BasicRuleProcessor { std::string warning_str; bool isREEmpty(libfwbuilder::Rule *rule, const std::string &re_type); public: dropRuleWithEmptyRE(const std::string &name) : BasicRuleProcessor(name) { warning_str = ""; } virtual bool processNext(); protected: dropRuleWithEmptyRE(const std::string &name, const std::string &_warning) : BasicRuleProcessor(name) { warning_str = _warning; } }; class dropRuleWithEmptyREWithWarning : public dropRuleWithEmptyRE { public: dropRuleWithEmptyREWithWarning(const std::string &name, const std::string &_warning) : dropRuleWithEmptyRE(name, _warning) { } }; /** * if MultiAddress object failed to convert itself to a group * of addresses and compiler runs in a test mode, we use dummy * test addresses instead. The error is detected by * preprocessor and at the moment not associated with any rule * (because preprocessor works with MultiAddress objects and * does not check which rule they are used in to improve * performance). This processor adds error message to the * rule using MultiAddress obejct like this. */ class checkForObjectsWithErrors : public BasicRuleProcessor { public: checkForObjectsWithErrors(const std::string &name) : BasicRuleProcessor(name) {} virtual bool processNext(); }; /** * Replace cluster interface object with corresponding real * interface */ class replaceFailoverInterfaceInRE : public BasicRuleProcessor { std::string re_type; public: replaceFailoverInterfaceInRE(const std::string &name, const std::string &t) : BasicRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; /** * generic rule debugger: prints name of the previous rule * processor in a chain and then a rule if its number is * compiler->debug_rule. Uses virtual method * Compiler::debugPrintRule to actually print the rule */ class Debug : public BasicRuleProcessor { public: virtual bool processNext(); }; /** * this rule processor skips all rules except the one with ID * set by call to setSingleRuleMode() */ class singleRuleFilter : public BasicRuleProcessor { public: virtual bool processNext(); }; /** * split rules with more than one service object, so that each * rule has services that satisfy some common criteria defined by * the virtual function groupingCode() */ class groupServices : public BasicRuleProcessor { protected: virtual int groupingCode(const libfwbuilder::Service *srv) =0; public: groupServices(const std::string &name) : BasicRuleProcessor(name) {} virtual bool processNext(); }; /** * split rules with more than one service object, so that each * rule has services with the same protocol */ class groupServicesByProtocol: public groupServices { protected: virtual int groupingCode(const libfwbuilder::Service *srv); public: groupServicesByProtocol(const std::string &name) : groupServices(name){} }; /** * split rules with more than one service object, so that all * tcp and udp services are in one rule and all other * protocols are in the other */ class groupTCPUDPServices: public groupServices { protected: virtual int groupingCode(const libfwbuilder::Service *srv); public: groupTCPUDPServices(const std::string &name) : groupServices(name){} }; /** * separate service object that satisfies condition * implemented in the virtual method "condition" so we have * exactly one such object per rule. */ class separateServiceObject : public BasicRuleProcessor { protected: virtual bool condition(const libfwbuilder::Service *srv) =0; public: separateServiceObject(const std::string &name); virtual bool processNext(); }; /** * separate TCP/UDP services (regardless of their source or * destination port configuration) */ class separateTCPUDP : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateTCPUDP(const std::string &name) : separateServiceObject(name) {} }; /** * separate TCP/UDP services that specify source port (can * not be used in combination with destination port with * multiport) */ class separateSrcPort : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateSrcPort(const std::string &name) : separateServiceObject(name) {} }; /** * separate TCP/UDP services that specify both source and * destination port */ class separateSrcAndDstPort : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateSrcAndDstPort(const std::string &name) : separateServiceObject(name) {} }; /** * separate Tag services so we have exactly one per rule. */ class separateTagged : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateTagged(const std::string &name) : separateServiceObject(name) {} }; /** * separate Custom services so we have exactly one per rule. */ class separateCustom : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateCustom(const std::string &name) : separateServiceObject(name) {} }; class separateUserServices : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateUserServices(const std::string &name) : separateServiceObject(name) {} }; /** * separate IPService objects with tos attrubute so we have * exactly one per rule. */ class separateTOS : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateTOS(const std::string &name) : separateServiceObject(name) {} }; /** * split rules with more than one IPService object with * options, so that each rule has only one such service */ class splitIpOptions : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: splitIpOptions(const std::string &name) : separateServiceObject(name) {} }; /** * separate TCP services with flags (can't use those in combination * with others in groups of services) */ class separateTCPWithFlags : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separateTCPWithFlags(const std::string &name) : separateServiceObject(name) {} }; /** * separate TCP and UDP services that match port ranges and * "any tcp" or "any udp" objects */ class separatePortRanges : public separateServiceObject { protected: virtual bool condition(const libfwbuilder::Service *srv); public: separatePortRanges(const std::string &name) : separateServiceObject(name) {} }; /** * verify if custom services used in rules are configured for * this platform */ class verifyCustomServices : public BasicRuleProcessor { public: verifyCustomServices(const std::string &name) : BasicRuleProcessor(name) {} virtual bool processNext(); }; /** * simply check if TCPService object with "established" flag * set is used in Service and abort with an error saying that * target firewall does not support this. Use for pretty much * every platform except ipfw and router ACLs */ class CheckForTCPEstablished : public BasicRuleProcessor { public: CheckForTCPEstablished(const std::string &name) : BasicRuleProcessor(name) {} virtual bool processNext(); }; /** * simply check if UserService objectis used in Service and * abort with an error saying that target firewall does not * support this. */ class CheckForUnsupportedUserService : public BasicRuleProcessor { public: CheckForUnsupportedUserService(const std::string &name) : BasicRuleProcessor(name) {} virtual bool processNext(); }; /** * This rule processor replaces firewall object with * DNSName object "self" configured as run-time with source * name "self". */ class ReplaceFirewallObjectWithSelfInRE : public BasicRuleProcessor { std::string re_type; public: ReplaceFirewallObjectWithSelfInRE(const std::string &n, std::string _type) : BasicRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; class RegisterGroupsAndTablesInRE : public BasicRuleProcessor { std::string re_type; public: RegisterGroupsAndTablesInRE(const std::string &n, const std::string _type) : BasicRuleProcessor(n) { re_type = _type; } virtual bool processNext(); }; friend class Compiler::RegisterGroupsAndTablesInRE; /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * returns cached firewall object ID */ int getFwId() { return fw_id; } /** * returns pointer to the cached firewall options object */ libfwbuilder::FWOptions* getCachedFwOpt() { return fwopt; } /** * internal: scans children of 's' and, if finds host or * firewall with multiple interfaces, replaces reference to * that host or firewall with a set of references to its * interfaces. Argument 's' should be a pointer at either src * or dst in the rule. Some platforms may require alterations * to * this algorithm, that's why it is virtual. */ virtual void _expand_addr(libfwbuilder::Rule *rule, libfwbuilder::FWObject *s, bool expand_cluster_interfaces_fully); /** * internal: scans child objects of interface iface, both IPv4 * and physAddress, and puts them in the list ol. Policy * compilers for platforms that support matching on MAC * address should reimplement this method and do whatever is * right for them (e.g. create combined address objects to * fuse information from IPv4 and physAddress together). * * Parameter @expand_cluster_interfaces_fully is used when * interface @iface belogns to a cluster and is failover * interface. If @expand_cluster_interfaces_fully is true, * this function scans failover group associated with this * interface and takes address of the member firewall for * which the policy is being compiled. If the cluster * interface belongs to a cluster that is not being compiled, * addresses of all members are returned instead. The address * of the cluster interface is always returned even when * @expand_cluster_interfaces_fully is false. */ virtual void _expand_interface(libfwbuilder::Rule *rule, libfwbuilder::Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully); /** * internal: like _expand_addr, but expands address range * objects */ void _expandAddressRanges(libfwbuilder::Rule *rule, libfwbuilder::FWObject *s); /* * normalizes port range (makes sure that niether range start * nor end is <0 and so on */ void normalizePortRange(int &rs,int &re); /** * This method returns true if one of the following conditions is met: * * 1. obj1 is the same as obj2 (compares ID of both objects), or * 2. obj1 is a child of obj2 on any depth, or * 3. address of obj1 matches that of any obj2's interfaces, or * 4. address of obj1 is a broadcast address of one of * the interfaces of obj2 * 5. address of obj1 is a broadcast (255.255.255.255) */ bool complexMatch(libfwbuilder::Address *obj1, libfwbuilder::Address *obj2, bool recognize_broadcasts=true, bool recognize_multicasts=true); libfwbuilder::Address* correctForCluster(libfwbuilder::Address *adr); /** * Compares given object with firewall or its parent cluster * (if any). Compares only IDs of these objects. Relies on * class CompilerDriver to set integer variable * "parent_cluster_id" in the firewall object if it is a * member of a cluster. */ bool isFirewallOrCluster(libfwbuilder::FWObject *obj); /** * This method finds interface of obj2 (which is usually * firewall object, but not necessarily so) which is connected * to the subnet on which obj1 is located. It also works if * obj1 is a network object, in this case it looks for the * interface that belongs to that network. */ libfwbuilder::Interface* findInterfaceFor( const libfwbuilder::Address *o1, const libfwbuilder::Address *o2); /** * This method finds an interface of the firewall obj2 which * belongs to the subnet on which obj1 is located and returns * IPv4 address object of this interface. It also works if * obj1 is a network object, in this case it looks for the * interface that belongs to that network. * * If obj1 is an Interface object, then corresponding Interface * object belonging to the firewall is returned (if found). */ libfwbuilder::FWObject* findAddressFor( const libfwbuilder::Address *o1, const libfwbuilder::Address *o2); virtual ~Compiler(); Compiler(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy); Compiler(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf); Compiler(libfwbuilder::FWObjectDatabase *_db, bool ipv6_policy); /** * overloaded methods: uses current firewall and ruleset objects */ virtual void abort(const std::string &errstr) throw(libfwbuilder::FWException); virtual void abort(libfwbuilder::FWObject *rule, const std::string &errstr) throw(libfwbuilder::FWException); virtual void error(const std::string &errstr); virtual void error(libfwbuilder::FWObject *rule, const std::string &errstr); virtual void warning(const std::string &errstr); virtual void warning(libfwbuilder::FWObject *rule, const std::string &errstr); void setDebugLevel(int dl) { debug=dl; } void setDebugRule(int dr) { debug_rule = dr; rule_debug_on = true; } void setVerbose(bool v) { verbose=v; } void setSingleRuleCompileMode(const std::string &rule_id); bool inSingleRuleCompileMode() { return single_rule_mode; } void setSourceRuleSet(libfwbuilder::RuleSet *rs); libfwbuilder::RuleSet* getSourceRuleSet() { return source_ruleset; } void setRuleSetName(const std::string &name) { ruleSetName = name; } std::string getRuleSetName() { return ruleSetName; } void setPersistentObjects(libfwbuilder::Library* po); std::string getCompiledScript(); int getCompiledScriptLength(); void setGroupRegistry(GroupRegistry *gr) { group_registry = gr; } void expandGroup(libfwbuilder::FWObject *grp, std::list &ol); void expandGroupsInRuleElement(libfwbuilder::RuleElement *s); /** * this method should return platform name. It is used * to construct proper error and warning messages. */ virtual std::string myPlatformName() { return ""; } std::string getUniqueRuleLabel(); virtual std::string createRuleLabel(const std::string &prefix, const std::string &txt, int rule_num); virtual std::string printComment(libfwbuilder::Rule *rule, std::string &prev_rule_label, const std::string &prefix, bool suppress_comment=false); /** * prolog return number of rules found */ virtual int prolog(); virtual void compile(); virtual void epilog(); /** * prints rule marked for debugging (its number * is in * debug_rule member variable) */ void debugRule(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Compiler_ops.cpp0000644000175000017500000005431511733011756026344 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Compiler.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPUDPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; /* * Interface has both address and a netmask, however what we need here is only * its address. If we were to use both, we would get the same behaviour as if * it was network, not just an interface of a single host. */ vector fwcompiler::_find_obj_intersection(Address *op1, Address *op2) { vector res; const InetAddr *addr1 = op1->getAddressPtr(); const InetAddr *netm1 = op1->getNetmaskPtr(); const InetAddr *addr2 = op2->getAddressPtr(); const InetAddr *netm2 = op2->getNetmaskPtr(); if (addr1==NULL || addr2==NULL) return res; const InetAddrMask n1( *addr1, (Interface::cast(op1)) ? InetAddr(InetAddr::getAllOnes()) : (*netm1) ); const InetAddrMask n2( *addr2, (Interface::cast(op2)) ? InetAddr(InetAddr::getAllOnes()) : (*netm2) ); vector intersection = libfwbuilder::getOverlap(n1,n2); for (vector::iterator i=intersection.begin(); i!=intersection.end(); i++) { InetAddrMask *n= &(*i); if (n->getNetmaskPtr()->isHostMask()) { IPv4 *h = new IPv4(); h->setAddress(*(n->getAddressPtr())); h->setName("h-"+n->getAddressPtr()->toString()); op1->getRoot()->add(h,false); res.push_back(h); } else { Network *net = new Network(); net->setAddress(*(n->getAddressPtr())); net->setNetmask(*(n->getNetmaskPtr())); net->setName("n-"+n->getAddressPtr()->toString()); op1->getRoot()->add(net,false); res.push_back(net); } } return res; } bool fwcompiler::_find_portrange_intersection(int rs1,int re1, int rs2,int re2, int &rsr,int &rer) { if (re2rs1 && re2rs1 && re2rs1 && rs2re1) { rsr=rs2; rer=re1; return true; } if (rs2>re1) return false; if (rs2re1) { rsr=rs1; rer=re1; return true; } if (rs1==rs2 && re1==re2) { rsr=rs1; rer=re1; return true; } return false; } vector fwcompiler::_find_srv_intersection(Service *op1, Service *op2) { vector res; if (op1->getTypeName()==op2->getTypeName()) { if ( IPService::cast(op1)) { /* TODO: check ip flags */ if (op1->getStr("protocol_num")==op2->getStr("protocol_num")) { res.push_back(op1); } return res; } if ( ICMPService::cast(op1)) { int t1=op1->getInt("type"); int t2=op2->getInt("type"); if (t1!=-1 && t2!=-1 && t1==t2) { res.push_back(op1); return res; } if (t1!=-1 && t2==-1) { res.push_back(op1); return res; } if (t1==-1 && t2!=-1) { res.push_back(op2); return res; } return res; } if ( TCPService::cast(op1) || UDPService::cast(op1) ) { int srs1=static_cast(op1)->getSrcRangeStart(); int sre1=static_cast(op1)->getSrcRangeEnd(); int drs1=static_cast(op1)->getDstRangeStart(); int dre1=static_cast(op1)->getDstRangeEnd(); int srs2=static_cast(op2)->getSrcRangeStart(); int sre2=static_cast(op2)->getSrcRangeEnd(); int drs2=static_cast(op2)->getDstRangeStart(); int dre2=static_cast(op2)->getDstRangeEnd(); int srsR,sreR,drsR,dreR; if ( ! _find_portrange_intersection(srs1,sre1,srs2,sre2,srsR,sreR) ) return res; if ( ! _find_portrange_intersection(drs1,dre1,drs2,dre2,drsR,dreR) ) return res; FWObject *nserv; if ( TCPService::cast(op1) ) { nserv=new TCPService(); op1->getRoot()->add(nserv,false); } if ( UDPService::cast(op1) ) { nserv=new UDPService(); op1->getRoot()->add(nserv,false); } nserv->setName(op1->getName()+"-"+op2->getName()); TCPUDPService::cast(nserv)->setSrcRangeStart(srsR); TCPUDPService::cast(nserv)->setSrcRangeEnd(sreR); TCPUDPService::cast(nserv)->setDstRangeStart(drsR); TCPUDPService::cast(nserv)->setDstRangeEnd(dreR); res.push_back(nserv); return res; } } /* * if objects are of the different types, then the only case allowed is * when one object is IPService */ if ( ! IPService::cast(op1) && IPService::cast(op2)) res.push_back(op1); if ( ! IPService::cast(op2) && IPService::cast(op1)) res.push_back(op2); return res; } /*************************************************************************/ bool fwcompiler::operator==(const Service &o1,const Service &o2) { if (o1.getId()==o2.getId()) return true; if (o1.getTypeName()==o2.getTypeName()) { if ( IPService::constcast(&o1)) { return (o1.getInt("protocol_num")==o2.getInt("protocol_num") && o1.getStr("fragm")==o2.getStr("fragm") && o1.getStr("short_fragm")==o2.getStr("short_fragm") && o1.getStr("lsrr")==o2.getStr("lsrr") && o1.getStr("ssrr")==o2.getStr("ssrr") && o1.getStr("rr")==o2.getStr("rr") && o1.getStr("ts")==o2.getStr("ts") ); } if ( ICMPService::constcast(&o1)) { return (o1.getInt("type")==o2.getInt("type")) && (o1.getInt("code")==o2.getInt("code")); } if ( UDPService::constcast(&o1) ) { int srs1=static_cast(&o1)->getSrcRangeStart(); int sre1=static_cast(&o1)->getSrcRangeEnd(); int drs1=static_cast(&o1)->getDstRangeStart(); int dre1=static_cast(&o1)->getDstRangeEnd(); int srs2=static_cast(&o2)->getSrcRangeStart(); int sre2=static_cast(&o2)->getSrcRangeEnd(); int drs2=static_cast(&o2)->getDstRangeStart(); int dre2=static_cast(&o2)->getDstRangeEnd(); return (srs1==srs2 && sre1==sre2 && drs1==drs2 && dre1==dre2); } if ( TCPService::constcast(&o1)) { int srs1=static_cast(&o1)->getSrcRangeStart(); int sre1=static_cast(&o1)->getSrcRangeEnd(); int drs1=static_cast(&o1)->getDstRangeStart(); int dre1=static_cast(&o1)->getDstRangeEnd(); int srs2=static_cast(&o2)->getSrcRangeStart(); int sre2=static_cast(&o2)->getSrcRangeEnd(); int drs2=static_cast(&o2)->getDstRangeStart(); int dre2=static_cast(&o2)->getDstRangeEnd(); const TCPService *tcp1=TCPService::constcast(&o1); const TCPService *tcp2=TCPService::constcast(&o2); return ( tcp1->getAllTCPFlags()==tcp2->getAllTCPFlags() && tcp1->getAllTCPFlagMasks()==tcp2->getAllTCPFlagMasks() && srs1==srs2 && sre1==sre2 && drs1==drs2 && dre1==dre2 ); } } return false; } bool fwcompiler::operator==(const Address &o1,const Address &o2) { if (o1.getId()==o2.getId()) return true; const InetAddr* o1b; const InetAddr* o1e; const InetAddr* o2b; const InetAddr* o2e; if (Interface::isA(&o1) && Interface::isA(&o2)) { const Interface *i1=Interface::constcast(&o1); const Interface *i2=Interface::constcast(&o2); if ( !i1->isRegular() && !i2->isRegular() ) { return i1->getName()==i2->getName(); } } if (physAddress::isA(&o1) && physAddress::isA(&o2)) { const physAddress *o1_pa =physAddress::constcast(&o1); const physAddress *o2_pa =physAddress::constcast(&o2); return o1_pa->getPhysAddress()==o2_pa->getPhysAddress(); } if (AddressRange::isA(&o1)) { o1b = &(AddressRange::constcast(&o1)->getRangeStart()); o1e = &(AddressRange::constcast(&o1)->getRangeEnd()); } else if (Network::isA(&o1)) { o1b = o1.getAddressPtr(); o1e = o1.getBroadcastAddressPtr(); } else { o1b = o1.getAddressPtr(); o1e = o1.getAddressPtr(); } if (AddressRange::isA(&o2)) { o2b = &(AddressRange::constcast(&o2)->getRangeStart()); o2e = &(AddressRange::constcast(&o2)->getRangeEnd()); } else if (Network::isA(&o2)) { o2b = o2.getAddressPtr(); o2e = o2.getBroadcastAddressPtr(); } else { o2b = o2.getAddressPtr(); o2e = o2.getAddressPtr(); } if (o1b==NULL || o2b==NULL || o1e==NULL || o2e==NULL) return false; return ((*o1b) == (*o2b) && (*o1e) == (*o2e)); } bool fwcompiler::operator==(const Interval &o1,const Interval &o2) { if (o1.getId()==o2.getId()) return true; int smin1, shour1, sday1, smonth1, syear1, sdayofweek1; int emin1, ehour1, eday1, emonth1, eyear1, edayofweek1; int smin2, shour2, sday2, smonth2, syear2, sdayofweek2; int emin2, ehour2, eday2, emonth2, eyear2, edayofweek2; o1.getStartTime( &smin1, &shour1, &sday1, &smonth1, &syear1, &sdayofweek1); o1.getEndTime( &emin1, &ehour1, &eday1, &emonth1, &eyear1, &edayofweek1); o2.getStartTime( &smin2, &shour2, &sday2, &smonth2, &syear2, &sdayofweek2); o2.getEndTime( &emin2, &ehour2, &eday2, &emonth2, &eyear2, &edayofweek2); return (smin1==smin2 && emin1==emin2 && shour1==shour2 && ehour1==ehour2 && sday1==sday2 && eday1==eday2 && smonth1==smonth2 && emonth1==emonth2 && syear1==syear2 && eyear1==eyear2 && sdayofweek1==sdayofweek2 && edayofweek1==edayofweek2); } /************************************************************************* bool fwcompiler::operator<=(const Address &o1,const Address &o2) { return (o1 == o2 || o1 < o2); } bool fwcompiler::operator<=(const Service &o1,const Service &o2) { return (o1 == o2 || o1 < o2); } */ /*************************************************************************/ #define RETURN(x) { object_comparison_cache[cache_key] = x; return x; } bool Compiler::checkForShadowing(const Service &o1, const Service &o2) { int cache_key = o1.getId() + (o2.getId() << 16); map::iterator it = object_comparison_cache.find(cache_key); if (it!=object_comparison_cache.end()) return it->second; if (o1.getId()==o2.getId()) RETURN(true); if (o1.isAny() && o2.isAny()) RETURN(false); if ( ! o1.isAny() && o2.isAny()) RETURN(true); if ( o1.isAny() && !o2.isAny()) RETURN(false); if (o1.getTypeName()==o2.getTypeName()) { const IPService *ip1; const IPService *ip2; if ((ip1=IPService::constcast(&o1))!=NULL) { ip2 = IPService::constcast(&o2); /* * Both objects are IPService * * can't use Service::getProtocolNumber member because it is not * defined as 'const'. Can't redefine it either since that will break * binary compatibility (as of v2.0.4) */ if (o1.getStr("fragm")!=o2.getStr("fragm") || o1.getStr("short_fragm")!=o2.getStr("short_fragm") || o1.getStr("lsrr")!=o2.getStr("lsrr") || o1.getStr("ssrr")!=o2.getStr("ssrr") || o1.getStr("rr")!=o2.getStr("rr") || o1.getStr("ts")!=o2.getStr("ts") ) RETURN(false); if (ip1->getTOSCode()!=ip2->getTOSCode() || ip1->getDSCPCode()!=ip2->getDSCPCode()) RETURN(false); if (o1.getInt("protocol_num")==o2.getInt("protocol_num")) RETURN(true); if (o1.getInt("protocol_num")!=0 && o2.getInt("protocol_num")==0) RETURN(true); RETURN(false); } if ( ICMPService::constcast(&o1)) { bool res = (o1.getInt("type")!=-1 && o2.getInt("type")==-1); RETURN(res); } if ( TCPService::constcast(&o1) ) { const TCPService *t1=TCPService::constcast(&o1); const TCPService *t2=TCPService::constcast(&o2); /* it seems STL does not define operator!= for class std::set */ if ( !( t1->getAllTCPFlags() == t2->getAllTCPFlags() && t1->getAllTCPFlagMasks() == t2->getAllTCPFlagMasks() ) ) RETURN(false); } if ( TCPService::constcast(&o1) || UDPService::constcast(&o1) ) { int srs1=static_cast(&o1)->getSrcRangeStart(); int sre1=static_cast(&o1)->getSrcRangeEnd(); int drs1=static_cast(&o1)->getDstRangeStart(); int dre1=static_cast(&o1)->getDstRangeEnd(); int srs2=static_cast(&o2)->getSrcRangeStart(); int sre2=static_cast(&o2)->getSrcRangeEnd(); int drs2=static_cast(&o2)->getDstRangeStart(); int dre2=static_cast(&o2)->getDstRangeEnd(); if (srs1==0 && sre1==0) sre1 = 65536; if (drs1==0 && dre1==0) dre1 = 65536; if (srs2==0 && sre2==0) sre2 = 65536; if (drs2==0 && dre2==0) dre2 = 65536; bool res = (srs1>=srs2 && sre1<=sre2 && drs1>=drs2 && dre1<=dre2); RETURN(res); } if ( TagService::constcast(&o1)) { string tagvalue1 = TagService::constcast(&o1)->getCode(); string tagvalue2 = TagService::constcast(&o2)->getCode(); bool res = (tagvalue1 == tagvalue2); RETURN(res); } if ( UserService::constcast(&o1)) { string uid1 = UserService::constcast(&o1)->getUserId(); string uid2 = UserService::constcast(&o2)->getUserId(); bool res = (uid1 == uid2); RETURN(res); } RETURN(false); } /* * if objects are of the different types, then the only case allowed is * when one object is IPService */ if (IPService::constcast(&o2) && ! IPService::constcast(&o1) ) { /* if o2 is IP Service and o1 is not, then o2 only shades o1 * when all flags are cleared in o2 */ bool res = ( o2.getInt("protocol_num")==0 && o2.getStr("fragm")!="True" && o2.getStr("short_fragm")!="True" && o2.getStr("lsrr")!="True" && o2.getStr("ssrr")!="True" && o2.getStr("rr")!="True" && o2.getStr("ts")!="True"); RETURN(res); } RETURN(false); throw FWException("trying to compare objects of incompatible types: \ o1: "+o1.getName()+" ("+o1.getTypeName()+") o2: "+o2.getName()+" ("+o2.getTypeName()+")"); } bool Compiler::checkForShadowing(const Address &o1,const Address &o2) { int cache_key = o1.getId() + (o2.getId() << 16); map::iterator it = object_comparison_cache.find(cache_key); if (it!=object_comparison_cache.end()) return it->second; if (o1.getId()==o2.getId()) RETURN(true); if (Interface::isA(&o1)) { const Interface *intf=Interface::constcast(&o1); if (!intf->isRegular()) RETURN(false); } if (Interface::isA(&o2)) { const Interface *intf=Interface::constcast(&o2); if (!intf->isRegular()) RETURN(false); } if (physAddress::isA(&o1) && physAddress::isA(&o2)) { const physAddress *o1_pa =physAddress::constcast(&o1); const physAddress *o2_pa =physAddress::constcast(&o2); bool res = (o1_pa->getPhysAddress()==o2_pa->getPhysAddress()); RETURN(res); } const InetAddr *o1b; const InetAddr *o1e; const InetAddr *o2b; const InetAddr *o2e; if (AddressRange::isA(&o1)) { o1b = &(AddressRange::constcast(&o1)->getRangeStart()); o1e = &(AddressRange::constcast(&o1)->getRangeEnd()); } else { if (Network::isA(&o1)) { o1b = static_cast(&o1)->getFirstHostPtr(); o1e = static_cast(&o1)->getLastHostPtr(); } else { o1b = o1.getAddressPtr(); o1e = o1.getAddressPtr(); } } if (AddressRange::isA(&o2)) { o2b = &(AddressRange::constcast(&o2)->getRangeStart()); o2e = &(AddressRange::constcast(&o2)->getRangeEnd()); } else { if (Network::isA(&o2)) { o2b = static_cast(&o2)->getFirstHostPtr(); o2e = static_cast(&o2)->getLastHostPtr(); } else { o2b = o2.getAddressPtr(); o2e = o2.getAddressPtr(); } } #if 0 cerr << "# o1=" << o1.getName() << " [" << o1.getTypeName() << "] " << o1b->toString() << "-" << o1e->toString() << "(" << o1.dimension() << ")" << " o2=" << o2.getName() << " [" << o2.getTypeName() << "] " << o2b->toString() << "-" << o2e->toString() << "(" << o2.dimension() << ")" << " " << int( ((*o1b)>(*o2b) || (*o1b)==(*o2b)) && ((*o1e)<(*o2e) || (*o1e)==(*o2e)) ) << endl; #endif // if any of the objects has no ip address, then we can not // check for shadowing and return false. examples of objects with // no real ip address: physAddress, Interface with no child IPv4/IPv6 // object. High level compilers should make sure they process rules // to the point where no such objects are left before they call // this method. if (o1b==NULL || o2b==NULL || o1e==NULL || o2e==NULL) RETURN(false); if (o1.isAny() && o2.isAny()) RETURN(true); if (o1.isAny() && !o2.isAny()) RETURN(false); if (!o1.isAny() && o2.isAny()) RETURN(true); bool res = ( ((*o2b) < (*o1b) || (*o1b) == (*o2b)) && ((*o1e) < (*o2e) || (*o1e) == (*o2e)) ); RETURN(res); } bool Compiler::intersect(PolicyRule &r1, PolicyRule &r2) { string act1 = r1.getActionAsString(); string act2 = r2.getActionAsString(); bool res_act; res_act = (act1=="Continue" || act2=="Continue" || act1==act2); if (res_act==false) return false; RuleElementItf *intf1_re = r1.getItf(); FWObject *rule1_iface = FWObjectReference::getObject(intf1_re->front()); int iface1 = rule1_iface->getId(); RuleElementItf *intf2_re = r2.getItf(); FWObject *rule2_iface = FWObjectReference::getObject(intf2_re->front()); int iface2 = rule2_iface->getId(); // int iface1 = r1.getInterfaceId(); // int iface2 = r2.getInterfaceId(); // bool res_iface; // res_iface = (intf1_re->isAny() || intf2_re->isAny() || iface1==iface2); // if (res_iface==false) return false; // if both rules have interfaces and these interfaces are different, they // cant intersect if ( ! intf1_re->isAny() && ! intf2_re->isAny() && iface1!=iface2) return false; vector v1 = _find_obj_intersection( getFirstSrc(&r1) , getFirstSrc(&r2) ); if (v1.empty()) return false; vector v2 = _find_obj_intersection( getFirstDst(&r1) , getFirstDst(&r2) ); if (v2.empty()) return false; vector v3 = _find_srv_intersection( getFirstSrv(&r1) , getFirstSrv(&r2) ); if (v3.empty()) return false; return true; } void Compiler::getIntersection(PolicyRule &r1, PolicyRule &r2, PolicyRule &res) { string act1 = r1.getActionAsString(); string act2 = r2.getActionAsString(); /* * "CONTINUE" is "broad" action, so chose another one, whatever it is */ if (act1=="Continue") res.setAction(act2); if (act2=="Continue") res.setAction(act1); string any_id; // FWObject *any; RuleElementSrc *nsrc = res.getSrc(); nsrc->clearChildren(); RuleElementDst *ndst = res.getDst(); ndst->clearChildren(); RuleElementSrv *nsrv = res.getSrv(); nsrv->clearChildren(); RuleElementItf *intf_re = r1.getItf(); FWObject *rule1_iface = FWObjectReference::getObject(intf_re->front()); int iface1 = rule1_iface->getId(); intf_re = r2.getItf(); FWObject *rule2_iface = FWObjectReference::getObject(intf_re->front()); int iface2 = rule2_iface->getId(); if (iface1 != iface2) return ; string lbl = "'" + r1.getLabel() + "' & '" + r2.getLabel() + "'"; res.setLabel(lbl); vector v1 = _find_obj_intersection( getFirstSrc(&r1) , getFirstSrc(&r2) ); vector v2 = _find_obj_intersection( getFirstDst(&r1) , getFirstDst(&r2) ); vector v3 = _find_srv_intersection( getFirstSrv(&r1) , getFirstSrv(&r2) ); for (vector::iterator i1=v1.begin(); i1!=v1.end(); ++i1) nsrc->addRef(*i1); for (vector::iterator i2=v2.begin(); i2!=v2.end(); ++i2) ndst->addRef(*i2); for (vector::iterator i3=v3.begin(); i3!=v3.end(); ++i3) nsrv->addRef(*i3); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/exceptions.h0000644000175000017500000000240311733011756025526 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FATALERRORINSINGLERULECOMPILEMODE_HH #define FATALERRORINSINGLERULECOMPILEMODE_HH #include "fwbuilder/FWException.h" #include class FatalErrorInSingleRuleCompileMode : public libfwbuilder::FWException { public: FatalErrorInSingleRuleCompileMode() : libfwbuilder::FWException("") {}; FatalErrorInSingleRuleCompileMode(const std::string &err) : libfwbuilder::FWException(err) {}; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/OSConfigurator.cpp0000644000175000017500000000226311733011756026610 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; OSConfigurator::~OSConfigurator() {} OSConfigurator::OSConfigurator(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy) : Compiler(_db, fw, ipv6_policy) { num_virtual_addresses_for_nat = 0; }; fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/Preprocessor.cpp0000644000175000017500000001063711733011756026376 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Preprocessor.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/RuleSet.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; static int infinite_recursion_breaker = 0; string Preprocessor::myPlatformName() { return "generic_preprocessor"; } Preprocessor::~Preprocessor() { dbcopy = NULL; } Preprocessor::Preprocessor(FWObjectDatabase *_db, Firewall *_fw, bool ipv6_policy) : Compiler(NULL, _fw, ipv6_policy) { // This is the main difference between Preprocessor and other // compilers. All compilers create a copy of the whole database // and work with it, but Preprocessor works with the original // database. Therefore it copies only pointer here. dbcopy = _db; fw_id = _fw->getId(); fwopt = _fw->getOptionsObject(); string fw_str_id = FWObjectDatabase::getStringId(_fw->getId()); fw = Firewall::cast( dbcopy->findInIndex(FWObjectDatabase::getIntId(fw_str_id))); } void Preprocessor::convertObject(FWObject *obj) { MultiAddress *adt = MultiAddress::cast(obj); if (adt!=NULL && adt->isCompileTime()) { adt->loadFromSource(ipv6, getCachedFwOpt(), inTestMode()); } } int Preprocessor::prolog() { return 0; } void Preprocessor::findMultiAddressObjectsUsedInRules(FWObject *top) { if (top->getInt(".recursion_breaker") == infinite_recursion_breaker) return; top->setInt(".recursion_breaker", infinite_recursion_breaker); for (FWObject::iterator i=top->begin(); i!=top->end(); ++i) { FWObject *obj = *i; PolicyRule *rule = PolicyRule::cast(obj); if (rule && rule->getAction() == PolicyRule::Branch) { RuleSet *branch_ruleset = rule->getBranch(); if (branch_ruleset) findMultiAddressObjectsUsedInRules(branch_ruleset); } FWReference *ref = FWReference::cast(obj); if (ref == NULL) findMultiAddressObjectsUsedInRules(obj); else { FWObject *obj_ptr = FWReference::getObject(obj); if (obj_ptr->getInt(".loaded") == infinite_recursion_breaker) continue; obj_ptr->setInt(".loaded", infinite_recursion_breaker); try { convertObject(obj_ptr); } catch (FWException &ex) { abort(ex.toString()); } // Note that MultiAddress inherits ObjectGroup if (Group::cast(obj_ptr)) findMultiAddressObjectsUsedInRules(obj_ptr); } } } void Preprocessor::compile() { // find all MultiAddress objects used in rules of this firewall, // directly or as group members. A bit of optimisation: // MultiAddress objects (DNSName and AddressTable) can not be used // in netowrk zone of interfaces and rule actions. // Note: fw belongs to the original object tree rather than dbcopy infinite_recursion_breaker++; FWObject *rule_copy = NULL; if (single_rule_mode) { rule_copy = dbcopy->findInIndex(single_rule_compile_rule->getId()); findMultiAddressObjectsUsedInRules(rule_copy); } else { FWObject *fwcopy = dbcopy->findInIndex(fw->getId()); findMultiAddressObjectsUsedInRules(fwcopy); } /* resolving MultiAddress objects */ // convertObjectsRecursively(dbcopy); } void Preprocessor::epilog() {} fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/PolicyCompiler.cpp0000644000175000017500000010230111733011756026630 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "PolicyCompiler.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/FailoverClusterGroup.h" #include #include #include #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; int PolicyCompiler::prolog() { Compiler::prolog(); Policy *policy = Policy::cast(fw->getFirstByType(Policy::TYPENAME)); assert(policy); if (source_ruleset == NULL) source_ruleset = policy; source_ruleset->renumberRules(); temp_ruleset = new Policy(); // working copy of the policy fw->add( temp_ruleset ); temp_ruleset->setName(source_ruleset->getName()); int global_num = 0; string label_prefix = ""; if (source_ruleset->getName() != "Policy") label_prefix = source_ruleset->getName(); int rule_counter = 0; for (FWObject::iterator i=source_ruleset->begin(); i!=source_ruleset->end(); i++) { PolicyRule *r = PolicyRule::cast(*i); if (r == NULL) continue; // skip RuleSetOptions object /* * do not remove disabled rules just yet because some * compilers might use RuleSet::insertRuleAtTop() and other * similar methods from prolog() or * addPredefinedPolicyRules()() and these methods renumber * rules (labels stop matching rule positions when this is * done because labels are configured in prolog() method of * the base class. See fwbuilder ticket 1173) */ //if (r->isDisabled()) continue; if (r->getLabel().empty()) { RuleElementItf *itfre = r->getItf(); assert(itfre); if (itfre->isAny()) { r->setLabel( createRuleLabel(label_prefix, "global", r->getPosition()) ); } else { string interfaces = ""; for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i) { FWObject *o = FWReference::getObject(*i); if (interfaces!="") interfaces += ","; interfaces += o->getName(); } r->setLabel( createRuleLabel(label_prefix, interfaces, r->getPosition()) ); } } r->setAbsRuleNumber(global_num); global_num++; rule_counter++; } initialized = true; return rule_counter; } /* * detects if tule r2 shades rule r1. */ bool PolicyCompiler::checkForShadowing(PolicyRule &r1, PolicyRule &r2) { RuleElement *srcrel1; RuleElement *dstrel1; RuleElement *srvrel1; RuleElement *srcrel2; RuleElement *dstrel2; RuleElement *srvrel2; FWObject::iterator i1 = r1.begin(); srcrel1 = RuleElement::cast(*i1); i1++; dstrel1 = RuleElement::cast(*i1); i1++; srvrel1 = RuleElement::cast(*i1); i1 = r2.begin(); srcrel2 = RuleElement::cast(*i1); i1++; dstrel2 = RuleElement::cast(*i1); i1++; srvrel2 = RuleElement::cast(*i1); if (srcrel1->getNeg()) return false; if (dstrel1->getNeg()) return false; if (srvrel1->getNeg()) return false; if (srcrel2->getNeg()) return false; if (dstrel2->getNeg()) return false; if (srvrel2->getNeg()) return false; /* * TODO: actually, route rule may shadow other rules if it * translates into "final" target, that is stops processing. This * may or may not be so, depending on the platform and combination * of rule options. */ if (r1.getRouting() || r2.getRouting()) return false; PolicyRule::Action r1_action = r1.getAction(); PolicyRule::Action r2_action = r2.getAction(); if (r1_action==PolicyRule::Accounting || r2_action==PolicyRule::Accounting ) return false; /* * this is delicate case: negation. We consider r2 to "shade" r1 * only if r2 is above r1 in the policy; if r1 originally had * negation and has been split, such as for example done in * fwb_ipt, then some of the produced rules have action Return. If * r2 has action != Return and r1 has action Return, we ignore r1. */ if (r1_action==PolicyRule::Return || r2_action==PolicyRule::Return ) return false; /* * the problem with branching rules is that it is combination of * the head rule and rules in the branch rather than a single rule * that can shadow other rules below them. Our current mechanism for * shadowing detection does not support this so all we can do is * skip rules with action Branch. */ if (r1_action==PolicyRule::Branch || r2_action==PolicyRule::Branch ) return false; /* * rules with action continue do not make final decision and * therefore can not shadow other rules (but can be shadowed) */ if (/* r1_action==PolicyRule::Continue || */ r2_action==PolicyRule::Continue ) return false; Address *src1; Address *dst1; Service *srv1; Address *src2; Address *dst2; Service *srv2; map::iterator it = rule_elements_cache.find(r1.getId()); if (it!=rule_elements_cache.end()) { threeTuple *tt = it->second; src1 = tt->src; dst1 = tt->dst; srv1 = tt->srv; } else { src1 = Address::cast(FWReference::cast(srcrel1->front())->getPointer()); dst1 = Address::cast(FWReference::cast(dstrel1->front())->getPointer()); srv1 = Service::cast(FWReference::cast(srvrel1->front())->getPointer()); threeTuple *tt = new struct threeTuple; tt->src = src1; tt->dst = dst1; tt->srv = srv1; rule_elements_cache[r1.getId()] = tt; } it = rule_elements_cache.find(r2.getId()); if (it!=rule_elements_cache.end()) { threeTuple *tt = it->second; src2 = tt->src; dst2 = tt->dst; srv2 = tt->srv; } else { src2 = Address::cast(FWReference::cast(srcrel2->front())->getPointer()); dst2 = Address::cast(FWReference::cast(dstrel2->front())->getPointer()); srv2 = Service::cast(FWReference::cast(srvrel2->front())->getPointer()); threeTuple *tt = new struct threeTuple; tt->src = src2; tt->dst = dst2; tt->srv = srv2; rule_elements_cache[r2.getId()] = tt; } if (src1==NULL || dst1==NULL || srv1==NULL) throw FWException("Can not compare rules because rule " + r1.getLabel() + " has a group in one of its elements. Aborting."); if (src2==NULL || dst2==NULL || srv2==NULL) throw FWException("Can not compare rules because rule " + r2.getLabel() + " has a group in one of its elements. Aborting."); if (MultiAddressRunTime::isA(src1) || MultiAddressRunTime::isA(dst1) || MultiAddressRunTime::isA(src2) || MultiAddressRunTime::isA(dst2)) return false; PolicyRule::Direction dir1 = r1.getDirection(); PolicyRule::Direction dir2 = r2.getDirection(); if (dir1 == PolicyRule::Both) dir1 = dir2; if (dir2 == PolicyRule::Both) dir2 = dir1; if (dir1 != dir2) return false; return ( Compiler::checkForShadowing(*src1, *src2) && Compiler::checkForShadowing(*dst1, *dst2) && Compiler::checkForShadowing(*srv1, *srv2) ); // complete: 3'5" return false; } /** * compare interfaces of rules r1 and r2. * * Return true if r2 shadows r1 (only inetrface rule element is * checked) * * If interface element is "all" (empty), it shadows any specific * interface in the other rule, also "all" shadows "all". If neither * is "all", return true if both rules refer the same interface, * otherwise return false. */ bool PolicyCompiler::checkInterfacesForShadowing(PolicyRule &r1, PolicyRule &r2) { RuleElementItf *intf1_re = r1.getItf(); FWObject *rule1_iface = FWObjectReference::getObject(intf1_re->front()); RuleElementItf *intf2_re = r2.getItf(); FWObject *rule2_iface = FWObjectReference::getObject(intf2_re->front()); int intf1_id = rule1_iface->getId(); int intf2_id = rule2_iface->getId(); if (intf2_re->isAny()) return true; // "eth0" -- "all" or "all" -- "all" return (intf1_id == intf2_id); } bool PolicyCompiler::cmpRules(PolicyRule &r1, PolicyRule &r2) { if (r1.getSrc()->getNeg()!=r2.getSrc()->getNeg()) return false; if (r1.getDst()->getNeg()!=r2.getDst()->getNeg()) return false; if (r1.getSrv()->getNeg()!=r2.getSrv()->getNeg()) return false; if (r2.getSrc()->getNeg()!=r2.getSrc()->getNeg()) return false; if (r2.getDst()->getNeg()!=r2.getDst()->getNeg()) return false; if (r2.getSrv()->getNeg()!=r2.getSrv()->getNeg()) return false; Address *src1=getFirstSrc(&r1); Address *dst1=getFirstDst(&r1); Service *srv1=getFirstSrv(&r1); Address *src2=getFirstSrc(&r2); Address *dst2=getFirstDst(&r2); Service *srv2=getFirstSrv(&r2); if (src1==NULL || dst1==NULL || srv1==NULL) throw FWException("Can not compare rules because rule " + r1.getLabel() + " has a group in one of its elements. Aborting."); if (src2==NULL || dst2==NULL || srv2==NULL) throw FWException("Can not compare rules because rule " + r2.getLabel() + " has a group in one of its elements. Aborting."); PolicyRule::Direction dir1=r1.getDirection(); PolicyRule::Direction dir2=r2.getDirection(); if (dir1==PolicyRule::Both) dir1=dir2; if (dir2==PolicyRule::Both) dir2=dir1; if (dir1!=dir2) return false; return ( (*src1 == *src2) && (*dst1 == *dst2) && (*srv1 == *srv2) ); } bool PolicyCompiler::InterfacePolicyRules::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementItf *itfre = rule->getItf(); assert(itfre); if (itfre->isAny()) { // rule->setInterfaceId(-1); tmp_queue.push_back(rule); return true; } for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i) { FWObject *o = FWReference::getObject(*i); if (ObjectGroup::isA(o)) { // a group in "interface" rule element. GUI checks that only // interfaces are allowed in such group, but we should check anyway. for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) { FWObject *o1 = FWReference::getObject(*i); if (!Interface::isA(o1)) { compiler->warning( "Object '" + o1->getName() + "', which is not an interface, is a member of the group '" + o->getName() + "' used in 'Interface' element of a rule."); continue; } PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementItf *nitf = r->getItf(); nitf->clearChildren(); nitf->setAnyElement(); nitf->addRef(o1); tmp_queue.push_back(r); } } else { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementItf *nitf = r->getItf(); nitf->clearChildren(); nitf->setAnyElement(); nitf->addRef(o); tmp_queue.push_back(r); } } return true; } bool PolicyCompiler::ExpandGroups::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementSrc *src=rule->getSrc(); assert(src); RuleElementDst *dst=rule->getDst(); assert(dst); RuleElementSrv *srv=rule->getSrv(); assert(srv); compiler->expandGroupsInRuleElement(src); compiler->expandGroupsInRuleElement(dst); compiler->expandGroupsInRuleElement(srv); return true; } bool PolicyCompiler::expandGroupsInSrv::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementSrv *srv = rule->getSrv(); compiler->expandGroupsInRuleElement(srv); tmp_queue.push_back(rule); return true; } bool PolicyCompiler::expandGroupsInItf::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementItf *itf = rule->getItf(); compiler->expandGroupsInRuleElement(itf); tmp_queue.push_back(rule); return true; } bool PolicyCompiler::ExpandMultipleAddresses::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *src=rule->getSrc(); assert(src); RuleElementDst *dst=rule->getDst(); assert(dst); compiler->_expand_addr(rule, src, true); compiler->_expand_addr(rule, dst, true); tmp_queue.push_back(rule); return true; } void PolicyCompiler::addressRanges::expandAddressRangesInSrc(PolicyRule *rule) { RuleElementSrc *src = rule->getSrc(); assert(src); compiler->_expandAddressRanges(rule, src); } void PolicyCompiler::addressRanges::expandAddressRangesInDst(PolicyRule *rule) { RuleElementDst *dst = rule->getDst(); assert(dst); compiler->_expandAddressRanges(rule, dst); } bool PolicyCompiler::addressRanges::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; expandAddressRangesInSrc(rule); expandAddressRangesInDst(rule); tmp_queue.push_back(rule); return true; } Rule* PolicyCompiler::getDifference(PolicyRule &r1, PolicyRule &r2) { PolicyRule *r = new PolicyRule(); *r = r1; FWObject *nsrc = getFirstSrc(r); nsrc->clearChildren(); FWObject *ndst = getFirstDst(r); ndst->clearChildren(); Service *nsrv = getFirstSrv(r); nsrv->clearChildren(); RuleElementItf *intf_re = r1.getItf(); FWObject *rule1_iface = FWObjectReference::getObject(intf_re->front()); int iface1 = rule1_iface->getId(); intf_re = r2.getItf(); FWObject *rule2_iface = FWObjectReference::getObject(intf_re->front()); int iface2 = rule2_iface->getId(); if (iface1 != iface2) return r; /* vector v1=_substract_obj( r1.getSrc() , r2.getSrc() ); vector v2=_substract_obj( r1.getDst() , r2.getDst() ); vector v3=_substract_srv( r1.getSrv() , r2.getSrv() ); for (vector::iterator i=v1.begin(); i!=v1.end(); ++i) nsrc->addRef(*i); for (vector::iterator i=v2.begin(); i!=v2.end(); ++i) ndst->addRef(*i); for (vector::iterator i=v3.begin(); i!=v3.end(); ++i) nsrv->addRef(*i); */ return r; } list::iterator PolicyCompiler::find_more_specific_rule( PolicyRule *rule, bool check_interface, const list::iterator &start_here, const list::iterator &stop_here, PolicyRule **intersection) { list::iterator j; for (j=start_here ; j!=stop_here; j++) { PolicyRule *r = PolicyRule::cast( *j ); if (! check_interface || (rule->getStr("acl")==r->getStr("acl")) ) { try { if (! intersect( *rule, *r )) continue; if (debug>=9) { cerr << "********* getIntersection: ------------------\n"; cerr << debugPrintRule(rule); cerr << debugPrintRule(r); cerr << "----------------------------------------------\n"; } PolicyRule *ir=new PolicyRule(); /* need to place this rule into the tree somewhere so references will * get resolved */ temp_ruleset->add( ir ); /* copy attributes from the current rule we are looking at. Do not change * this part of the algorithm as pix compiler relies upon it. */ ir->duplicate(r); getIntersection(*rule , *r, *ir ); if (! ir->isEmpty()) { if (debug>=9) { cerr << debugPrintRule(ir); cerr << "------------------------------------------------\n"; } if (intersection!=NULL) *intersection=ir; return j; } } catch (FWException ex) { cerr << " *** Exception: " << ex.toString() << endl; } } } return j; } /* * checks if one of the children of RuleElement is a host, IPv4 or * network object with address 0.0.0.0 and netmask 0.0.0.0. * * Exceptions: * - object 'any' * - interface with dynamic address. * * In addition check for address A.B.C.D/0 which is most likely a * mistake if A.B.C.D != 0.0.0.0. See #475 */ Address* PolicyCompiler::checkForZeroAddr::findZeroAddress(RuleElement *re) { Address *a=NULL; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); assert(o!=NULL); MultiAddress *maddr = MultiAddress::cast(o); if (maddr && maddr->isRunTime()) continue; Address *addr = Address::cast(o); if (addr==NULL && o!=NULL) compiler->warning( re->getParent(), string("findZeroAddress: Unknown object in rule element: ") + o->getName() + " type=" + o->getTypeName()); if (addr && addr->hasInetAddress()) { if (Interface::cast(o)!=NULL && (Interface::cast(o)->isDyn() || Interface::cast(o)->isUnnumbered() || Interface::cast(o)->isBridgePort())) continue; if ( ! addr->isAny()) { const InetAddr *ad = addr->getAddressPtr(); const InetAddr *nm = addr->getNetmaskPtr(); // AddressRange has address but not netmask // AddressRange with address 0.0.0.0 is acceptable // (not equivalent to "any") if (ad->isAny() && nm!=NULL && nm->isAny()) { a = addr; break; } // Address A.B.C.D/0 is most likely a mistake if // A.B.C.D != 0.0.0.0 if ((Network::cast(addr) || NetworkIPv6::cast(addr)) && !ad->isAny() && nm!=NULL && nm->isAny()) { a = addr; break; } } } } return a; } Address* PolicyCompiler::checkForZeroAddr::findHostWithNoInterfaces( RuleElement *re) { for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); assert(o!=NULL); Host *addr = Host::cast(o); if (addr!=NULL && addr->front()!=NULL) { FWObject::iterator it; it=addr->begin(); while (it!=addr->end() && !Interface::isA(*it)) ++it; if (it==addr->end()) return addr; // has no interfaces } } return NULL; } /* * looks for objects with address 0.0.0.0 and aborts compilation if * finds such object */ bool PolicyCompiler::checkForZeroAddr::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; Address *a=NULL; a = findHostWithNoInterfaces( rule->getSrc() ); if (a==NULL) a = findHostWithNoInterfaces( rule->getDst() ); if (a!=NULL) compiler->abort( rule, "Object '"+a->getName()+ "' has no interfaces, therefore it does not have " "address and can not be used in the rule."); a = findZeroAddress( rule->getSrc() ); if (a==NULL) a = findZeroAddress( rule->getDst() ); if (a!=NULL) { string err="Object '"+a->getName()+"'"; if (IPv4::cast(a)!=NULL) // || IPv6::cast(a)!=NULL { FWObject *p=a->getParent(); Interface *iface = Interface::cast(p); if (iface!=NULL) { err+=" (an address of interface "; if (iface->getLabel()!="") err+=iface->getLabel(); else err+=iface->getName(); err+=" )"; } } err += " has address or netmask 0.0.0.0, which is equivalent to 'any'. " "This is likely an error."; compiler->abort(rule, err); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler::checkForUnnumbered::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( compiler->catchUnnumberedIfaceInRE( rule->getSrc() ) || compiler->catchUnnumberedIfaceInRE( rule->getDst() ) ) compiler->abort( rule, "Can not use unnumbered interfaces in rules."); tmp_queue.push_back(rule); return true; } bool PolicyCompiler::ConvertToAtomicForAddresses::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *src=rule->getSrc(); assert(src); RuleElementDst *dst=rule->getDst(); assert(dst); for (FWObject::iterator i1=src->begin(); i1!=src->end(); ++i1) { for (FWObject::iterator i2=dst->begin(); i2!=dst->end(); ++i2) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); s=r->getDst(); assert(s); s->clearChildren(); s->addCopyOf( *i2 ); tmp_queue.push_back(r); } } return true; } bool PolicyCompiler::ConvertToAtomicForIntervals::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementInterval *ivl=rule->getWhen(); if (ivl==NULL || ivl->isAny()) { tmp_queue.push_back(rule); return true; } for (FWObject::iterator i1=ivl->begin(); i1!=ivl->end(); ++i1) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getWhen(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); tmp_queue.push_back(r); } return true; } bool PolicyCompiler::ConvertToAtomic::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *src=rule->getSrc(); assert(src); RuleElementDst *dst=rule->getDst(); assert(dst); RuleElementSrv *srv=rule->getSrv(); assert(srv); for (FWObject::iterator i1=src->begin(); i1!=src->end(); i1++) { for (FWObject::iterator i2=dst->begin(); i2!=dst->end(); i2++) { for (FWObject::iterator i3=srv->begin(); i3!=srv->end(); i3++) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getSrc(); assert(s); s->clearChildren(); s->addCopyOf( *i1 ); s=r->getDst(); assert(s); s->clearChildren(); s->addCopyOf( *i2 ); s=r->getSrv(); assert(s); s->clearChildren(); s->addCopyOf( *i3 ); tmp_queue.push_back(r); } } } return true; } bool PolicyCompiler::checkForShadowingPlatformSpecific(PolicyRule * /*UNUSED r1 */, PolicyRule * /*UNUSED r2 */) { return true; } std::deque::iterator PolicyCompiler::findMoreGeneralRule::find_more_general_rule( PolicyRule *rule, bool check_interface, const std::deque::iterator &start_here, const std::deque::iterator &stop_here, bool reverse) { PolicyCompiler *pcomp=dynamic_cast(compiler); if (compiler->debug>=9) { cerr << "********* searching for more general rule: -------------\n"; cerr << compiler->debugPrintRule(rule); cerr << endl; } std::deque::iterator j; for (j=start_here ; j!=stop_here; j++) { PolicyRule *r = PolicyRule::cast( *j ); bool intf_cr = false; if (reverse) intf_cr = pcomp->checkInterfacesForShadowing( *r , *rule ); else intf_cr = pcomp->checkInterfacesForShadowing( *rule , *r ); if (! check_interface || intf_cr) { bool cr = false; if (reverse) cr = pcomp->checkForShadowing( *r , *rule ); else cr = pcomp->checkForShadowing( *rule , *r ); if ( cr && pcomp->checkForShadowingPlatformSpecific(rule, r)) { if (compiler->debug>=9) { cerr << r->getLabel() << ": FOUND more general rule:\n"; cerr << compiler->debugPrintRule(r); cerr << endl; } return j; } else { if (compiler->debug>=9) cerr << r->getLabel() << ": rules do not intersect \n"; continue; } } } return j; } bool PolicyCompiler::DetectShadowing::processNext() { PolicyRule *rule; rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); // to pass it to the next processor, if any if (rule->isFallback()) return true; // do not check fallback .. if (rule->isHidden()) return true; // ... and hidden rules std::deque::iterator i = find_more_general_rule(rule, true, rules_seen_so_far.begin(), rules_seen_so_far.end(), false); if (i!=rules_seen_so_far.end()) { Rule *r = *i; /* * find_more_general finds more general _or_ equivalent rule */ if (r && r->getAbsRuleNumber() != rule->getAbsRuleNumber() && ! (*r == *rule) ) { compiler->abort( r, "Rule '" + r->getLabel() + "' shadows rule '" + rule->getLabel() + "' below it"); } } rules_seen_so_far.push_back(rule); return true; } bool PolicyCompiler::DetectShadowingForNonTerminatingRules::processNext() { PolicyRule *rule; rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); // to pass it to the next processor, if any if (rule->isFallback()) return true; // do not check fallback .. if (rule->isHidden()) return true; // ... and hidden rules std::deque::iterator i = find_more_general_rule(rule, true, rules_seen_so_far.begin(), rules_seen_so_far.end(), true); // <<<<<<< NB! if (i!=rules_seen_so_far.end()) { Rule *r = *i; /* * find_more_general finds more general _or_ equivalent rule */ if (r && r->getAbsRuleNumber() != rule->getAbsRuleNumber() && ! (*r == *rule) ) { compiler->abort( rule, "Non-terminating rule '" + rule->getLabel() + "' shadows rule '" + r->getLabel() + "' above it"); } } rules_seen_so_far.push_back(rule); return true; } bool PolicyCompiler::MACFiltering::checkRuleElement(RuleElement *re) { bool res=true; std::list lst; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if (physAddress::isA(o)) { lst.push_back(o); res=false; } } for (FWObject::iterator i1=lst.begin(); i1!=lst.end(); i1++) re->removeRef(*i1); return res; } bool PolicyCompiler::MACFiltering::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *src=rule->getSrc(); RuleElement *dst=rule->getDst(); string lbl=rule->getLabel(); if ( ! checkRuleElement(src) ) { if (last_rule_lbl!=lbl) compiler->warning( rule, "MAC address matching is not supported. " "One or several MAC addresses removed from source in the rule"); if (src->empty() || src->isAny()) compiler->abort( rule, "Source becomes 'Any' after all MAC addresses " "have been removed in the rule"); last_rule_lbl=lbl; } if ( ! checkRuleElement(dst) ) { if (last_rule_lbl!=lbl) compiler->warning( rule, "MAC address matching is not supported. " "One or several MAC addresses removed from destination in the rule"); if (dst->empty() || dst->isAny()) compiler->abort( rule, "Destination becomes 'Any' after all MAC addresses " "have been removed in the rule "); last_rule_lbl=lbl; } return true; } string PolicyCompiler::debugPrintRule(Rule *r) { PolicyRule *rule=PolicyRule::cast(r); // FWOptions *ruleopt =rule->getOptionsObject(); RuleElementSrc *srcrel = rule->getSrc(); RuleElementDst *dstrel = rule->getDst(); RuleElementSrv *srvrel = rule->getSrv(); RuleElementItf *itfrel = rule->getItf(); // int iface_id = rule->getInterfaceId(); // Interface *rule_iface = Interface::cast(dbcopy->findInIndex(iface_id)); ostringstream str; // str << setw(70) << setfill('-') << "-"; int no=0; FWObject::iterator i1=srcrel->begin(); FWObject::iterator i2=dstrel->begin(); FWObject::iterator i3=srvrel->begin(); FWObject::iterator i4=itfrel->begin(); while ( i1!=srcrel->end() || i2!=dstrel->end() || i3!=srvrel->end() || i4!=itfrel->end()) { str << endl; string src=" "; string dst=" "; string srv=" "; string itf=" "; int src_id = -1; int dst_id = -1; int srv_id = -1; if (srcrel->getNeg()) src = "!"; if (dstrel->getNeg()) dst = "!"; if (srvrel->getNeg()) srv = "!"; if (itfrel->getNeg()) itf = "!"; if (i1!=srcrel->end()) { FWObject *o = FWReference::getObject(*i1); src += o->getName(); src_id = o->getId(); } if (i2!=dstrel->end()) { FWObject *o = FWReference::getObject(*i2); dst += o->getName(); dst_id = o->getId(); } if (i3!=srvrel->end()) { FWObject *o = FWReference::getObject(*i3); srv += o->getName(); srv_id = o->getId(); } if (i4!=itfrel->end()) { ostringstream str; FWObject *o = FWReference::getObject(*i4); str << o->getName() << "(" << o->getId() << ")"; itf += str.str(); } int w = 0; if (no==0) { str << rule->getLabel(); w = rule->getLabel().length(); } str << setw(10-w) << setfill(' ') << " "; str << setw(18) << setfill(' ') << src.c_str() << "(" << src_id << ")"; str << setw(18) << setfill(' ') << dst.c_str() << "(" << dst_id << ")"; str << setw(12) << setfill(' ') << srv.c_str() << "(" << srv_id << ")"; str << setw(8) << setfill(' ') << itf.c_str(); if (no==0) { str << setw(9) << setfill(' ') << rule->getActionAsString().c_str(); str << setw(12) << setfill(' ') << rule->getDirectionAsString().c_str(); if (rule->getLogging()) str << " LOG"; } else str << setw(18) << setfill(' ') << " "; ++no; if ( i1!=srcrel->end() ) ++i1; if ( i2!=dstrel->end() ) ++i2; if ( i3!=srvrel->end() ) ++i3; if ( i4!=itfrel->end() ) ++i4; } return str.str(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/fwcompiler.pro0000644000175000017500000000157711733011756026100 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib CONFIG += staticlib INCLUDEPATH += "../../../../" # SOURCES = BaseCompiler.cpp \ Compiler.cpp \ Compiler_helpers.cpp \ Compiler_ops.cpp \ Compiler_object_match.cpp \ Preprocessor.cpp \ NATCompiler.cpp \ OSConfigurator.cpp \ PolicyCompiler.cpp \ ServiceRuleProcessors.cpp \ RoutingCompiler.cpp \ GroupRegistry.cpp HEADERS = BaseCompiler.h \ Compiler.h \ Preprocessor.h \ NATCompiler.h \ OSConfigurator.h \ PolicyCompiler.h \ RuleProcessor.h \ RoutingCompiler.h \ exceptions.h \ GroupRegistry.h TARGET = fwcompiler # target.path = "$$prefix/lib" # no need to install headers in fortress #headers.files = $$HEADERS #headers.path = "$$prefix/include/fwb-4/fwcompiler" #INSTALLS += headers # and no need to install .a library INSTALLS -= target fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/RuleProcessor.h0000644000175000017500000001570211733011756026162 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Zaliva , Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RULE_PROCESSOR_HH__ #define __RULE_PROCESSOR_HH__ #include #include "fwbuilder/Rule.h" namespace fwcompiler { class Compiler; /** * This class represents Rule processing chain elements. It * takes input from other processor and produces modified output * via getNextRule() method. * * For cases when one input rule produce several output rules * internal temporary queue is provided. * * This is abstract class. Implementator should subclass it * and implement processNext() method. * * @author Vadim Zaliva , Vadim Kurland */ class BasicRuleProcessor { public: BasicRuleProcessor() { compiler=NULL; prev_processor=NULL; name=""; do_once=false; } BasicRuleProcessor(const std::string &_name) { compiler=NULL; prev_processor=NULL; name=_name; do_once=false; } virtual ~BasicRuleProcessor() { // Delete unused elements while(!tmp_queue.empty()) { // libfwbuilder::Rule *x = tmp_queue.front(); tmp_queue.pop_front(); // delete x; } } /** * Ties this rule processor to the compiler. Parameter _comp * is policy compiler object that is using this processor. */ void setContext(Compiler *_comp) { compiler=_comp; } /** * Connects this rule processor to the previous in the chain. * Parameter _src is source processor which will be used to * obtain input from. */ void setDataSource(BasicRuleProcessor *_src) { prev_processor=_src; } /** * sets name for this rule processor. Name is used in debug * print */ void setName(const std::string &_name) { name=_name; } /** * returns name of this processor */ std::string getName() { return name; } /** * Returns next rule or NULL if no more is availiable. */ libfwbuilder::Rule *getNextRule() { while(tmp_queue.empty() && processNext()) ; if(tmp_queue.empty()) { return NULL; } else { libfwbuilder::Rule *res = tmp_queue.front(); tmp_queue.pop_front(); return res; } } /** * some processors work on the whole rule set rather than on * a single rule. This method reads input data stream while * rules are coming from the previous rule processor and fill * tmp_queue, then return true if there are rules in the * queue and false otherwise. Using this instead of getNext * in processNext in rule processors that need the whole rule * set. This method executes only once and returns false upon * subsequent calls right away. */ bool slurp() { if (!do_once) { libfwbuilder::Rule *rule; while ( (rule=prev_processor->getNextRule())!=NULL) tmp_queue.push_back(rule); do_once=true; return (tmp_queue.size()!=0); } return false; } /** * Implementor should implement this method in a manner it * process one or more source elements and adds results to tmp * queue. It is prefferable to process just one source element * at a time. * * @return false if no more elements could be produced. */ virtual bool processNext() = 0; protected: std::string name; std::deque tmp_queue; BasicRuleProcessor *prev_processor; Compiler *compiler; bool do_once; }; /** * This class provides convenient interface by adding * dynamic_cast so that pointer to the rule returned from getNext * would have type PolicyRule* */ class PolicyRuleProcessor : public BasicRuleProcessor { public: PolicyRuleProcessor() : BasicRuleProcessor() {} PolicyRuleProcessor(const std::string &_name) : BasicRuleProcessor(_name) {} /** * Returns next rule to be processed or NULL if no more is availiable. */ virtual libfwbuilder::PolicyRule* getNext() { return dynamic_cast( prev_processor->getNextRule() ); } }; /** * This class provides convenient interface by adding * dynamic_cast so that pointer to the rule returned from getNext * would have type NATRule* */ class NATRuleProcessor : public BasicRuleProcessor { public: NATRuleProcessor() : BasicRuleProcessor() {} NATRuleProcessor(const std::string &_name) : BasicRuleProcessor(_name) {} /** * Returns next rule to be processed or NULL if no more is availiable. */ virtual libfwbuilder::NATRule* getNext() { return dynamic_cast( prev_processor->getNextRule() ); } }; /** * This class provides convenient interface by adding * dynamic_cast so that pointer to the rule returned from getNext * would have type RoutingRule* */ class RoutingRuleProcessor : public BasicRuleProcessor { public: RoutingRuleProcessor() : BasicRuleProcessor() {} RoutingRuleProcessor(const std::string &_name) : BasicRuleProcessor(_name) {} /** * Returns next rule to be processed or NULL if no more is availiable. */ virtual libfwbuilder::RoutingRule* getNext() { return dynamic_cast( prev_processor->getNextRule() ); } }; }; #endif // __RULE_PROCESSOR_HH__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/PolicyCompiler.h0000644000175000017500000004540111733011756026304 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICY_COMPILER_HH__ #define __POLICY_COMPILER_HH__ #include "fwcompiler/Compiler.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include namespace fwcompiler { #define DECLARE_POLICY_RULE_PROCESSOR(_Name) \ friend class _Name; \ class _Name : public PolicyRuleProcessor { \ public: \ _Name(const std::string &n) : \ PolicyRuleProcessor(n) {}; \ virtual ~_Name() {}; \ virtual bool processNext(); \ }; class PolicyCompiler : public Compiler { protected: /** * this method scans source_ruleset looking for atomic rule * which yields non-empty intersection with atomic rule r. * * it can start scan either from the beginning of source_ruleset, * or from iterator 'start_here' * * it returns iterator pointing at rule it has found (so we * can continue search later) * * if parameter 'intersection' is not NULL, it is assumed to * be a pointer to a pointer at the object of class Rule. It * is used to return a pointer at intersection of rule 'rule' * and rule this function had found */ std::list::iterator find_more_specific_rule(libfwbuilder::PolicyRule *r, bool check_interface, const std::list::iterator &start_here, const std::list::iterator &stop_here, libfwbuilder::PolicyRule **intersection=NULL); public: PolicyCompiler(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : Compiler(_db, fw, ipv6_policy, _oscnf) {} /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * this method substracts atomic rule r2 from atomic rule r1. * Resulting rule may have multiple objects in src,dst or srv, * so converting to atomic may be necessary. If rules can not * be compared, then it throws an exception. If resultant rule * is empty, method returns rule with empty src,dst,srv * * NOT IMPLEMENTED YET */ libfwbuilder::Rule* getDifference(libfwbuilder::PolicyRule &r1, libfwbuilder::PolicyRule &r2); /** * detects if rule r2 shades rule r1 * returns: * * true if r2 shades r1 */ bool checkForShadowing(libfwbuilder::PolicyRule &r1, libfwbuilder::PolicyRule &r2); /** * virtual method to let policy compiler check rules using * options specific for the given fw platform. Base class * PolicyCompiler has no visibility into platform-specific * options and can not do this. */ virtual bool checkForShadowingPlatformSpecific(libfwbuilder::PolicyRule *r1, libfwbuilder::PolicyRule *r2); /** * compare interfaces of rules r1 and r2. * * Return true if r2 shadows r1 (only inetrface rule element * is checked) * * If interface element is "all" (empty), it shadows any * specific interface in the other rule, also "all" shadows * "all". If neither is "all", return true if both rules refer * the same interface, otherwise return false. */ bool checkInterfacesForShadowing(libfwbuilder::PolicyRule &r1, libfwbuilder::PolicyRule &r2); /** * detects if rules r1 and r2 are identical (that is, have the * same effect, rather than use the same objects) * * returns: * * true if r1 is identical to r2 */ bool cmpRules(libfwbuilder::PolicyRule &r1, libfwbuilder::PolicyRule &r2); /** * this processor checks if the rule is associated with an * interface and uses setInterfaceId to record its id. If the * rule is associated with multiple interfaces, this processor * splits the rule accordingly. */ DECLARE_POLICY_RULE_PROCESSOR(InterfacePolicyRules); /** * this class expands groups in src,dst,srv. It creates * references to new objects "in place" (that is, it does not * create new rules but rather uses rule elements of the old * ones) */ DECLARE_POLICY_RULE_PROCESSOR(ExpandGroups); /** * expand groups in Srv */ DECLARE_POLICY_RULE_PROCESSOR(expandGroupsInSrv); /** * expand groups in Interface rule element */ DECLARE_POLICY_RULE_PROCESSOR(expandGroupsInItf); /** * this inspector replaces references to hosts and firewalls * in dst with references to their interfaces */ class ExpandMultipleAddressesInSrc : public Compiler::expandMultipleAddressesInRE { public: ExpandMultipleAddressesInSrc(const std::string &n) : expandMultipleAddressesInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class ExpandMultipleAddressesInDst : public Compiler::expandMultipleAddressesInRE { public: ExpandMultipleAddressesInDst(const std::string &n) : expandMultipleAddressesInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; class ReplaceFirewallObjectWithSelfInSrc : public Compiler::ReplaceFirewallObjectWithSelfInRE { public: ReplaceFirewallObjectWithSelfInSrc(const std::string &n) : ReplaceFirewallObjectWithSelfInRE( n, libfwbuilder::RuleElementSrc::TYPENAME) {} }; class ReplaceFirewallObjectWithSelfInDst : public Compiler::ReplaceFirewallObjectWithSelfInRE { public: ReplaceFirewallObjectWithSelfInDst(const std::string &n) : ReplaceFirewallObjectWithSelfInRE( n, libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * single object negation in Src */ class singleObjectNegationSrc : public singleObjectNegation { public: singleObjectNegationSrc(const std::string &n): singleObjectNegation(n, libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * single object negation in Dst */ class singleObjectNegationDst : public Compiler::singleObjectNegation { public: singleObjectNegationDst(const std::string &n): singleObjectNegation(n, libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * single object negation in Itf */ class singleObjectNegationItf : public Compiler::singleObjectNegation { public: singleObjectNegationItf(const std::string &n): singleObjectNegation(n, libfwbuilder::RuleElementItf::TYPENAME) {} }; /** * processes rules with negation in Itf. * Compiler::fullInterfaceNegationInRE replaces interface object * with a set of "other" interfaces of the firewall. */ class ItfNegation : public Compiler::fullInterfaceNegationInRE { public: ItfNegation(const std::string &name) : fullInterfaceNegationInRE( name, libfwbuilder::RuleElementItf::TYPENAME) {} }; /** * replace cluster interface objects with inetrfaces of the member * firewall in the Interface rule element */ class replaceClusterInterfaceInItf : public Compiler::replaceClusterInterfaceInItfRE { public: replaceClusterInterfaceInItf(const std::string &name) : replaceClusterInterfaceInItfRE( name, libfwbuilder::RuleElementItf::TYPENAME) {} }; /** * this inspector replaces references to hosts and firewalls * in src or dst with references to their interfaces * * TODO: move to class Compiler because this might be useful * for both PolicyCompiler and NATCompiler */ DECLARE_POLICY_RULE_PROCESSOR(ExpandMultipleAddresses); /** * this processor splits rule element if src or dst contains * address range */ class addressRanges : public PolicyRuleProcessor { protected: void expandAddressRangesInSrc(libfwbuilder::PolicyRule *rule); void expandAddressRangesInDst(libfwbuilder::PolicyRule *rule); public: addressRanges(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * checks for unnumbered interface in rule elements (one can * not use unnumbered interfaces in rules). Call after * ExpandMultipleAddresses */ class checkForUnnumbered : public PolicyRuleProcessor { public: checkForUnnumbered(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; /** * this processor converts to atomic rules using all combinations * of objects in Src,Dst. It ignores Srv. */ DECLARE_POLICY_RULE_PROCESSOR(ConvertToAtomicForAddresses); /** * this processor splits rule so that each atomic rule has * exactly one Interval rule element */ DECLARE_POLICY_RULE_PROCESSOR(ConvertToAtomicForIntervals); /** * this processor converts to atomic rules */ DECLARE_POLICY_RULE_PROCESSOR(ConvertToAtomic); /** * deals with recursive groups in Src. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInSrc : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInSrc(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * deals with recursive groups in Dst. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInDst : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInDst(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * deals with recursive groups in Srv. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInSrv : public Compiler::recursiveGroupsInRE { public: recursiveGroupsInSrv(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {} }; /** * deals with empty groups in Src. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInSrc : public Compiler::emptyGroupsInRE { public: emptyGroupsInSrc(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * deals with empty groups in Dst. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInDst : public Compiler::emptyGroupsInRE { public: emptyGroupsInDst(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * deals with empty groups in Srv. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInSrv : public Compiler::emptyGroupsInRE { public: emptyGroupsInSrv(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {} }; /** * deals with empty groups in Itf. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInItf : public Compiler::emptyGroupsInRE { public: emptyGroupsInItf(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementItf::TYPENAME) {} }; /** * checks for host and network objects with address 0.0.0.0 */ class checkForZeroAddr : public PolicyRuleProcessor { libfwbuilder::Address *findHostWithNoInterfaces(libfwbuilder::RuleElement *re); libfwbuilder::Address *findZeroAddress(libfwbuilder::RuleElement *re); public: checkForZeroAddr(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; /** * this is a base class for the family of rule processors that * need to be able to find more general rule rule */ class findMoreGeneralRule : public PolicyRuleProcessor { protected: /** * this method scans tmp_queue looking for atomic rule * which is more general than atomic rule 'r'. * * it can starts scan at position defined by iterator * start_here and ends it at the position given by * iterator stop_here * * it returns iterator pointing at the rule it has found (so we * can continue search later) */ std::deque::iterator find_more_general_rule(libfwbuilder::PolicyRule *r, bool check_interface, const std::deque::iterator &start_here, const std::deque::iterator &stop_here, bool reverse=false); public: findMoreGeneralRule(const std::string &n) : PolicyRuleProcessor(n) {} }; /** * this inspector scans rules and detects those which "shade" * other rules below them */ class DetectShadowing : public findMoreGeneralRule { std::deque rules_seen_so_far; public: DetectShadowing(const std::string &n) : findMoreGeneralRule(n) {} virtual bool processNext(); }; /** * this inspector scans rules and detects those which "shade" * other rules above them. Use for non-terminating rules. */ class DetectShadowingForNonTerminatingRules : public findMoreGeneralRule { std::deque rules_seen_so_far; public: DetectShadowingForNonTerminatingRules(const std::string &n) : findMoreGeneralRule(n) {} virtual bool processNext(); }; /** * splits rule if one of the objects in Src is firewall * itself or a broadcast address for one of its interfaces or * multicast (multicast support is not implemented yet). This * is needed to properly choose direction and chain * later. Src may have multiple objects when this processor * is called. For firewall the iptables code compiler * generates should go into OUTPUT chain, while for all other * objects it should go into FORWARD chain. That is why we * need to split the rule and place firewall object in the * src of the rule of its own. */ class splitIfSrcMatchesFw : public Compiler::splitIfRuleElementMatchesFW { public: splitIfSrcMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * splits rule if one of the objects in Dst is firewall * itself. This is needed to properly choose direction and * chain later. See comment in splitIfInputChainObjectSrc. */ class splitIfDstMatchesFw : public Compiler::splitIfRuleElementMatchesFW { public: splitIfDstMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * many firewall platforms do not support filtering by MAC * addresses. Issue warning if MAC address is used in the rule * and remove it from the rule element. * * Call this processor after ExpandMultipleAddresses. */ class MACFiltering : public PolicyRuleProcessor { protected: std::string last_rule_lbl; /* return value: * true - ok * false - one or more MAC addresses have been removed, issue warning */ bool checkRuleElement(libfwbuilder::RuleElement *re); public: MACFiltering(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; /** * rule processors that replace MultiAddress objects with MultiAddressRunTime * equivalents */ class swapMultiAddressObjectsInSrc : public Compiler::swapMultiAddressObjectsInRE { public: swapMultiAddressObjectsInSrc(const std::string &n) : swapMultiAddressObjectsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class swapMultiAddressObjectsInDst : public Compiler::swapMultiAddressObjectsInRE { public: swapMultiAddressObjectsInDst(const std::string &n) : swapMultiAddressObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; class RegisterGroupsAndTablesInSrc : public RegisterGroupsAndTablesInRE { public: RegisterGroupsAndTablesInSrc(const std::string &n) : RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementSrc::TYPENAME) {} }; class RegisterGroupsAndTablesInDst : public RegisterGroupsAndTablesInRE { public: RegisterGroupsAndTablesInDst(const std::string &n) : RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementDst::TYPENAME) {} }; virtual int prolog(); }; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwcompiler/RoutingCompiler.h0000644000175000017500000002350611733011756026476 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ROUTING_COMPILER_HH__ #define __ROUTING_COMPILER_HH__ #include "fwcompiler/Compiler.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include namespace fwcompiler { using namespace std; #define DECLARE_ROUTING_RULE_PROCESSOR(_Name) \ friend class _Name; \ class _Name : public RoutingRuleProcessor { \ public: \ _Name(const std::string &n) : \ RoutingRuleProcessor(n) {}; \ virtual ~_Name() {}; \ virtual bool processNext(); \ }; class RoutingCompiler : public Compiler { public: RoutingCompiler(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : Compiler(_db, fw, ipv6_policy, _oscnf) {} /** * deals with empty groups in RDst. See description for * Compiler::emptyGroupsInRE */ class emptyGroupsInRDst : public emptyGroupsInRE { public: emptyGroupsInRDst(const std::string &n) : emptyGroupsInRE(n,libfwbuilder::RuleElementRDst::TYPENAME) {} }; /** * deals with recursive groups in RDst. See description for * Compiler::recursiveGroupsInRE */ class recursiveGroupsInRDst : public recursiveGroupsInRE { public: recursiveGroupsInRDst(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementRDst::TYPENAME) {} }; /** * creates a label with a sorted dst-id-list, to find identical destinations even if the order * of the dst objects differs within one rule */ DECLARE_ROUTING_RULE_PROCESSOR(createSortedDstIdsLabel); /** * checks if the Destination and the Interface are both empty */ DECLARE_ROUTING_RULE_PROCESSOR(emptyRDstAndRItf); /** * If the Gateway is a host or a network interface, it must lead to * only one IP adress. * e.g.: if a host has two interfaces, you must specify which interface * has to be used as gateway. If the inteface has two or more IP addresses, * only an IP Adress Object can be used as Gateway. */ DECLARE_ROUTING_RULE_PROCESSOR(singleAdressInRGtw); /** * Invalid routing destination network: * network address and netmask mismatch. */ friend class validateNetwork; class validateNetwork : public RoutingRuleProcessor { public: validateNetwork(const std::string &n) : RoutingRuleProcessor(n) {}; virtual ~validateNetwork() {}; virtual bool processNext(); bool checkValidNetwork(libfwbuilder::FWObject*); }; /** * the IP address of the gateway has to be * in the same local network as the firewall */ friend class reachableAddressInRGtw; class reachableAddressInRGtw : public RoutingRuleProcessor { public: reachableAddressInRGtw(const std::string &n) : RoutingRuleProcessor(n) {}; virtual ~reachableAddressInRGtw() {}; virtual bool processNext(); bool checkReachableIPAddress(libfwbuilder::FWObject*); }; /** * the IP address of the gateway has to be * in the same network as the interface */ DECLARE_ROUTING_RULE_PROCESSOR(contradictionRGtwAndRItf); /** * checks if the Interface (RItf) is a child of the current firewall */ DECLARE_ROUTING_RULE_PROCESSOR(rItfChildOfFw); /** * some OS (e.g. BSD) allow me to set up static route via * gateway or via interface, but not both in one rule. */ DECLARE_ROUTING_RULE_PROCESSOR(interfaceOrGateway); /** * for OS where we do not support ECMP, detect rules that * define routes for the same destination via different * gateways and abort. */ DECLARE_ROUTING_RULE_PROCESSOR(sameDestinationDifferentGateways); /** * checks for competing rules */ class PrintRule; class competingRules : public RoutingRuleProcessor { /** * 'rules_seen_so_far' is a nested map with the following structure * MAP MAP PAIR * |-Dst1 * | |-Gtw&Itf1- * | |-Gtw&Itf2- * | * |-Dst2 * |-Gtw&Itf1- * |-Gtw&Itf2- * |-Gtw&Itf3- * * dest gtw+itf metric label */ map< string, map< string, pair< string, string> > > rules_seen_so_far; map< string, map< string, pair< string, string> > >::iterator dest_it; map< string, pair< string, string> >::iterator gtwitf_it; public: competingRules(const std::string &name) : RoutingRuleProcessor(name){} virtual bool processNext(); }; friend class RoutingCompiler::competingRules; /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes * TODO: implement */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * this inspector replaces references to hosts and firewalls * in dst with references to their interfaces * * TODO: move to class Compiler because this might be useful * for PolicyCompiler, NATCompiler and also RoutingCompiler */ DECLARE_ROUTING_RULE_PROCESSOR(ExpandMultipleAddresses); /** * this processor converts to atomic rules using all objects * contained in Routing Destination */ DECLARE_ROUTING_RULE_PROCESSOR(ConvertToAtomicForDST); /** * this class expands groups in dst. It creates * references to new objects "in place" (that is, it does not * create new rules but rather uses rule elements of the old * ones) */ DECLARE_ROUTING_RULE_PROCESSOR(ExpandGroups); /** * this processor classifies routing rules into single and * multi path rules. Needs slurp(). */ class classifyRoutingRules : public RoutingRuleProcessor { map< string, map< string, pair< string, libfwbuilder::RoutingRule*> > > rules_seen_so_far; map< string, map< string, pair< string, libfwbuilder::RoutingRule*> > >::iterator dest_it; map< string, pair< string, libfwbuilder::RoutingRule*> >::iterator gtwitf_it; public: classifyRoutingRules(const std::string &name) : RoutingRuleProcessor(name) {} virtual bool processNext(); }; friend class RoutingCompiler::classifyRoutingRules; /** * Placeholders for MultiAddressRunTime objects */ class processMultiAddressObjectsInRE : public RoutingRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : RoutingRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInRDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInRDst(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementRDst::TYPENAME) {} }; /** * detects if rules r1 and r2 are identical (that is, have the * same effect, rather than use the same objects) * * returns: * * true if r1 is identical to r2 */ bool cmpRules(const libfwbuilder::RoutingRule &r1, const libfwbuilder::RoutingRule &r2); /** * deals with recursive groups in Dst. See description for * Compiler::recursiveGroupsInRE class recursiveGroupsInDst : public recursiveGroupsInRE { public: recursiveGroupsInSrc(const std::string &n) : recursiveGroupsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} };*/ virtual int prolog(); }; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/0000755000175000017500000000000011733011756023011 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/memcheck.h0000644000175000017500000003175011733011756024744 0ustar sylvestresylvestre /* ---------------------------------------------------------------- Notice that the following BSD-style license applies to this one file (memcheck.h) only. The rest of Valgrind is licensed under the terms of the GNU General Public License, version 2, unless otherwise indicated. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- This file is part of MemCheck, a heavyweight Valgrind tool for detecting memory errors. Copyright (C) 2000-2008 Julian Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------- Notice that the above BSD-style license applies to this one file (memcheck.h) only. The entire rest of Valgrind is licensed under the terms of the GNU General Public License, version 2. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- */ #ifndef __MEMCHECK_H #define __MEMCHECK_H /* This file is for inclusion into client (your!) code. You can use these macros to manipulate and query memory permissions inside your own programs. See comment near the top of valgrind.h on how to use them. */ #include "valgrind.h" /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! This enum comprises an ABI exported by Valgrind to programs which use client requests. DO NOT CHANGE THE ORDER OF THESE ENTRIES, NOR DELETE ANY -- add new ones at the end. */ typedef enum { VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'), VG_USERREQ__MAKE_MEM_UNDEFINED, VG_USERREQ__MAKE_MEM_DEFINED, VG_USERREQ__DISCARD, VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE, VG_USERREQ__CHECK_MEM_IS_DEFINED, VG_USERREQ__DO_LEAK_CHECK, VG_USERREQ__COUNT_LEAKS, VG_USERREQ__GET_VBITS, VG_USERREQ__SET_VBITS, VG_USERREQ__CREATE_BLOCK, VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, /* This is just for memcheck's internal use - don't use it */ _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR = VG_USERREQ_TOOL_BASE('M','C') + 256 } Vg_MemCheckClientRequest; /* Client-code macros to manipulate the state of memory. */ /* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_NOACCESS, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Similarly, mark memory at _qzz_addr as addressable but undefined for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_UNDEFINED, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Similarly, mark memory at _qzz_addr as addressable and defined for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_DEFINED, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is not altered: bytes which are addressable are marked as defined, but those which are not addressable are left unchanged. */ #define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Create a block-description handle. The description is an ascii string which is included in any messages pertaining to addresses within the specified memory range. Has no other effect on the properties of the memory range. */ #define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__CREATE_BLOCK, \ _qzz_addr, _qzz_len, _qzz_desc, \ 0, 0); \ _qzz_res; \ })) /* Discard a block-description-handle. Returns 1 for an invalid handle, 0 for a valid handle. */ #define VALGRIND_DISCARD(_qzz_blkindex) \ (__extension__ ({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__DISCARD, \ 0, _qzz_blkindex, 0, 0, 0); \ _qzz_res; \ })) /* Client-code macros to check the state of memory. */ /* Check that memory at _qzz_addr is addressable for _qzz_len bytes. If suitable addressibility is not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Check that memory at _qzz_addr is addressable and defined for _qzz_len bytes. If suitable addressibility and definedness are not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__CHECK_MEM_IS_DEFINED, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Use this macro to force the definedness and addressibility of an lvalue to be checked. If suitable addressibility and definedness are not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \ VALGRIND_CHECK_MEM_IS_DEFINED( \ (volatile unsigned char *)&(__lvalue), \ (unsigned long)(sizeof (__lvalue))) /* Do a memory leak check mid-execution. */ #define VALGRIND_DO_LEAK_CHECK \ {unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DO_LEAK_CHECK, \ 0, 0, 0, 0, 0); \ } /* Just display summaries of leaked memory, rather than all the details */ #define VALGRIND_DO_QUICK_LEAK_CHECK \ {unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DO_LEAK_CHECK, \ 1, 0, 0, 0, 0); \ } /* Return number of leaked, dubious, reachable and suppressed bytes found by all previous leak checks. They must be lvalues. */ #define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \ /* For safety on 64-bit platforms we assign the results to private unsigned long variables, then assign these to the lvalues the user specified, which works no matter what type 'leaked', 'dubious', etc are. We also initialise '_qzz_leaked', etc because VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as initialised. */ \ {unsigned long _qzz_res; \ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__COUNT_LEAKS, \ &_qzz_leaked, &_qzz_dubious, \ &_qzz_reachable, &_qzz_suppressed, 0); \ leaked = _qzz_leaked; \ dubious = _qzz_dubious; \ reachable = _qzz_reachable; \ suppressed = _qzz_suppressed; \ } /* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it into the provided zzvbits array. Return values: 0 if not running on valgrind 1 success 2 [previously indicated unaligned arrays; these are now allowed] 3 if any parts of zzsrc/zzvbits are not addressable. The metadata is not copied in cases 0, 2 or 3 so it should be impossible to segfault your system by using this call. */ #define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \ (__extension__({unsigned long _qzz_res; \ char* czza = (char*)zza; \ char* czzvbits = (char*)zzvbits; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__GET_VBITS, \ czza, czzvbits, zznbytes, 0, 0 ); \ _qzz_res; \ })) /* Set the validity data for addresses [zza..zza+zznbytes-1], copying it from the provided zzvbits array. Return values: 0 if not running on valgrind 1 success 2 [previously indicated unaligned arrays; these are now allowed] 3 if any parts of zza/zzvbits are not addressable. The metadata is not copied in cases 0, 2 or 3 so it should be impossible to segfault your system by using this call. */ #define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \ (__extension__({unsigned int _qzz_res; \ char* czza = (char*)zza; \ char* czzvbits = (char*)zzvbits; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__SET_VBITS, \ czza, czzvbits, zznbytes, 0, 0 ); \ _qzz_res; \ })) #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/physAddress.cpp0000644000175000017500000000446611733011756026020 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" #include //#include using namespace libfwbuilder; using namespace std; const char *physAddress::TYPENAME={"physAddress"}; physAddress::physAddress() : Address() { setPhysAddress("00:00:00:00:00:00"); } void physAddress::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char* n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address"))); assert(n!=NULL); setStr("address", n); FREEXMLBUFF(n); } xmlNodePtr physAddress::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } std::string physAddress::getPhysAddress() const { return getStr("address"); } void physAddress::setPhysAddress(const std::string &s) { setStr("address",s); } FWReference* physAddress::createRef() { // FWObjectReference *ref=new FWObjectReference(); FWObjectReference *ref = getRoot()->createFWObjectReference(); ref->setPointer(this); return ref; } bool physAddress::isAny() const { return getPhysAddress()==""; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Pool.h0000644000175000017500000000726011733011756024100 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POOL_HH_FLAG__ #define __POOL_HH_FLAG__ #include #include #include "fwbuilder/ThreadTools.h" namespace libfwbuilder { /** * General purpose Pool. * Object can be 'leased' from pool, * and 'released' back to pool. * All access is synchronized. */ template class Pool { typedef std::vector __vtp; typedef std::set __stp; typedef typename __vtp::iterator __vtp_i; typedef typename __stp::iterator __stp_i; private: size_t max; Mutex mutex ; Cond cond ; std::vector freepool; std::set usedpool; public: /** * Creates Pool with initial size and max size. * 'initial' objects are created immediately. * Later Pool can automatically grow up to 'max_'. */ Pool(size_t initial, size_t max_) { max = max_; for(size_t i=0;i $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PHYS_ADDRESS_HH_FLAG__ #define __PHYS_ADDRESS_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/Address.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class physAddress : public Address { private: public: DECLARE_FWOBJECT_SUBTYPE(physAddress); DECLARE_DISPATCH_METHODS(physAddress); physAddress(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); std::string getPhysAddress() const; void setPhysAddress(const std::string &s); virtual FWReference* createRef(); bool isAny() const; virtual bool isPrimaryObject() const { return false; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Network.h0000644000175000017500000000415111733011756024614 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NETWORK_HH_FLAG__ #define __NETWORK_HH_FLAG__ #include "fwbuilder/Address.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class Network : public Address { public: Network(); Network(Network &); Network(const std::string &); virtual ~Network(); bool isValidRoutingNet() const; virtual void fromXML (xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr xml_parent_node) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(Network); DECLARE_DISPATCH_METHODS(Network); virtual bool hasInetAddress() const { return true; } /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool) const { return 1; } virtual const Address* getAddressObject() const { return this; } const InetAddr* getFirstHostPtr() const; const InetAddr* getLastHostPtr() const; virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual void setAddressNetmask(const std::string& s); virtual bool isPrimaryObject() const { return true; } }; } #endif // __NETWORK_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ObjectMirror.cpp0000644000175000017500000000703211733011756026120 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: ObjectMirror.cpp 534 2010-02-07 23:25:06Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ==================================================================== */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ObjectMirror.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include using namespace libfwbuilder; using namespace std; Service* ObjectMirror::getMirroredService(Service *obj) { void* res = obj->dispatch(this, (void*)NULL); return Service::cast((FWObject*)(res)); } void* ObjectMirror::dispatch(IPService* obj, void*) { return obj; } void* ObjectMirror::dispatch(ICMPService* obj, void*) { ICMPService *new_obj = obj->getRoot()->createICMPService(); new_obj->setName(obj->getName() + "-mirror"); if (obj->getInt("type") == 8) { new_obj->setInt("type", 0); new_obj->setInt("code", 0); } else { new_obj->setInt("type", obj->getInt("type")); new_obj->setInt("code", obj->getInt("code")); } return new_obj; } void* ObjectMirror::dispatch(ICMP6Service* obj, void*) { ICMP6Service *new_obj = obj->getRoot()->createICMP6Service(); new_obj->setName(obj->getName() + "-mirror"); if (obj->getInt("type") == 128) { new_obj->setInt("type", 129); new_obj->setInt("code", 0); } else { new_obj->setInt("type", obj->getInt("type")); new_obj->setInt("code", obj->getInt("code")); } return new_obj; } void* ObjectMirror::dispatch(TCPService* obj, void*) { TCPService *new_obj = obj->getRoot()->createTCPService(); new_obj->duplicate(obj); // mostly to copy tcp flags new_obj->setName(obj->getName() + "-mirror"); new_obj->setSrcRangeStart(obj->getDstRangeStart()); new_obj->setSrcRangeEnd(obj->getDstRangeEnd()); new_obj->setDstRangeStart(obj->getSrcRangeStart()); new_obj->setDstRangeEnd(obj->getSrcRangeEnd()); // if original tcp service does something with flags, we can't simply // invert it by adding flag "established". Just leave as-is if (!obj->inspectFlags()) new_obj->setEstablished( ! obj->getEstablished()); return new_obj; } void* ObjectMirror::dispatch(UDPService* obj, void*) { UDPService *new_obj = obj->getRoot()->createUDPService(); new_obj->setName(obj->getName() + "-mirror"); new_obj->setSrcRangeStart(obj->getDstRangeStart()); new_obj->setSrcRangeEnd(obj->getDstRangeEnd()); new_obj->setDstRangeStart(obj->getSrcRangeStart()); new_obj->setDstRangeEnd(obj->getSrcRangeEnd()); return new_obj; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Routing.cpp0000644000175000017500000000333111733011756025144 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWObjectDatabase.h" using namespace libfwbuilder; const char *Routing::TYPENAME={"Routing"}; Routing::Routing() : RuleSet() { setName("Routing"); } Routing::~Routing() {} Rule* Routing::createRule() { FWObjectDatabase* db=getRoot(); assert(db!=NULL); return db->createRoutingRule(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ClusterGroup.cpp0000644000175000017500000001200711733011756026153 0ustar sylvestresylvestre/* * ClusterGroup.cpp - ClusterGroup class implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" using namespace std; using namespace libfwbuilder; const char *ClusterGroup::TYPENAME = {"ClusterGroup"}; ClusterGroup::ClusterGroup() : ObjectGroup() { setStr("type", ""); } void ClusterGroup::init(FWObjectDatabase *root) { FWObject *gopt = getFirstByType(ClusterGroupOptions::TYPENAME); if (gopt == NULL) { gopt = root->create(ClusterGroupOptions::TYPENAME); add(gopt); } } bool ClusterGroup::validateChild(FWObject *o) { string otype = o->getTypeName(); return (FWObject::validateChild(o) && (otype == Interface::TYPENAME || otype == ClusterGroupOptions::TYPENAME || otype == FWObjectReference::TYPENAME)); } void ClusterGroup::replaceReferenceInternal(int old_id, int new_id, int &counter) { if (old_id == new_id) return; FWObject::replaceReferenceInternal(old_id, new_id, counter); string master_iface_id = getStr("master_iface"); if (!master_iface_id.empty()) { int master_iface_id_int = FWObjectDatabase::getIntId(master_iface_id); if (master_iface_id_int == old_id) { setStr("master_iface", FWObjectDatabase::getStringId(new_id)); counter++; } } } void ClusterGroup::fromXML(xmlNodePtr parent) throw(FWException) { FWObject::fromXML(parent); const char *n; n = FROMXMLCAST(xmlGetProp(parent, TOXMLCAST("type"))); if (n != NULL) { setStr("type", n); FREEXMLBUFF(n); } n = FROMXMLCAST(xmlGetProp(parent, TOXMLCAST("master_iface"))); if (n != NULL) { setStr("master_iface", n); FREEXMLBUFF(n); } } xmlNodePtr ClusterGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); FWObject *o; for (FWObjectTypedChildIterator it = findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { o = *it; if (o) o->toXML(me); } for (FWObjectTypedChildIterator it = findByType(ClusterGroupOptions::TYPENAME); it != it.end(); ++it) { o = *it; if (o) o->toXML(me); } return me; } ClusterGroupOptions* ClusterGroup::getOptionsObject() { ClusterGroupOptions *gopt = ClusterGroupOptions::cast( getFirstByType(ClusterGroupOptions::TYPENAME)); if (gopt == NULL) { gopt = ClusterGroupOptions::cast( getRoot()->create(ClusterGroupOptions::TYPENAME)); add(gopt); } return gopt; } FWObject& ClusterGroup::duplicateForUndo(const FWObject *obj) throw(FWException) { if (ClusterGroup::constcast(obj)==NULL) return *this; setRO(false); ClusterGroupOptions *their_opts = ClusterGroupOptions::cast( obj->getFirstByType(ClusterGroupOptions::TYPENAME)); ClusterGroupOptions *mine_opts = ClusterGroupOptions::cast( getFirstByType(ClusterGroupOptions::TYPENAME)); list all_refs = getByType(FWObjectReference::TYPENAME); while (all_refs.size()) { remove(all_refs.front(), false); all_refs.pop_front(); } for(list::const_iterator m=obj->begin(); m!=obj->end(); ++m) { if (FWReference::cast(*m)) { FWObject *object = FWReference::getObject(*m); addRef(object); } } if (their_opts && mine_opts) mine_opts->duplicate(their_opts); if (their_opts && mine_opts==NULL) addCopyOf(their_opts); shallowDuplicate(obj); return *this; } Interface* ClusterGroup::getInterfaceForMemberFirewall(Firewall *fw) { #ifdef DEBUG_FOR_DMZ cerr << "ClusterGroup::getInterfaceForMemberFirewall " << fw << endl; if (fw) { cerr << " fw: " << fw->getName() << endl; } #endif for (FWObjectTypedChildIterator it = findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *other_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(other_iface); #ifdef DEBUG_FOR_DMZ cerr << " other_iface: " << other_iface->getName() << " isChildOf(fw): " << other_iface->isChildOf(fw) << endl; #endif if (other_iface->isChildOf(fw)) return other_iface; } return NULL; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Rule.cpp0000644000175000017500000007150511733011756024434 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Policy.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/TagService.h" using namespace std; using namespace libfwbuilder; const char *Rule::TYPENAME={"Rule"}; Rule::Rule() { setInt("position",0); enable(); setFallback(false); setHidden(false); setRuleGroupName(""); } void Rule::init(FWObjectDatabase*) { } FWOptions* Rule::getOptionsObject() const { return NULL; } RuleSet* Rule::getBranch() { return NULL; } void Rule::setPosition(int n) { setInt("position", n); } int Rule::getPosition() const { return getInt("position"); } void Rule::disable() { setBool("disabled",true); } void Rule::enable() { setBool("disabled",false); } bool Rule::isDisabled() const { return( getBool("disabled")); } bool Rule::isEmpty() { return false; } void Rule::setBranch(RuleSet*) {}; string Rule::getRuleGroupName() const { return getStr("group"); } void Rule::setRuleGroupName(const std::string &group_name) { setStr("group", group_name); } FWObject& Rule::shallowDuplicate(const FWObject *x, bool preserve_id) throw(FWException) { const Rule *rx=Rule::constcast(x); fallback = rx->fallback; hidden = rx->hidden; label = rx->label; unique_id = rx->unique_id; abs_rule_number = rx->abs_rule_number; compiler_message = rx->compiler_message; return FWObject::shallowDuplicate(x,preserve_id); } bool Rule::cmp(const FWObject *x, bool recursive) throw(FWException) { const Rule *rx = Rule::constcast(x); if (fallback != rx->fallback || hidden != rx->hidden || label != rx->label || unique_id != rx->unique_id) return false; return FWObject::cmp(x, recursive); } /***************************************************************************/ const char *PolicyRule::TYPENAME={"PolicyRule"}; PolicyRule::PolicyRule() { // setStr("action","Deny"); setAction(PolicyRule::Deny); src_re = NULL; dst_re = NULL; srv_re = NULL; itf_re = NULL; when_re = NULL; } void PolicyRule::init(FWObjectDatabase *root) { FWObject *re = getFirstByType(RuleElementSrc::TYPENAME); if (re == NULL) { // re = root->createRuleElementSrc(); assert(re!=NULL); add(re); src_re = RuleElementSrc::cast(re); re = root->createRuleElementDst(); assert(re!=NULL); add(re); dst_re = RuleElementDst::cast(re); re = root->createRuleElementSrv(); assert(re!=NULL); add(re); srv_re = RuleElementSrv::cast(re); re = root->createRuleElementItf(); assert(re!=NULL); add(re); itf_re = RuleElementItf::cast(re); re = root->createRuleElementInterval(); assert(re!=NULL); add(re); when_re = RuleElementInterval::cast(re); add( root->createPolicyRuleOptions() ); } } FWObject& PolicyRule::shallowDuplicate(const FWObject *x, bool preserve_id) throw(FWException) { const PolicyRule *rx=PolicyRule::constcast(x); setDirection(rx->getDirection()); setAction(rx->getAction()); setLogging(rx->getLogging()); src_re = NULL; dst_re = NULL; srv_re = NULL; itf_re = NULL; when_re = NULL; return Rule::shallowDuplicate(x, preserve_id); } bool PolicyRule::cmp(const FWObject *x, bool recursive) throw(FWException) { const PolicyRule *rx = PolicyRule::constcast(x); if (rx == NULL) return false; if (getDirection() != rx->getDirection() || getAction() != rx->getAction() || getLogging() != rx->getLogging()) return false; return Rule::cmp(x, recursive); } // RuleElementSrc* PolicyRule::getSrc() { if (src_re) return src_re; FWObject::iterator i1 = begin(); src_re = RuleElementSrc::cast(*i1); return src_re; } RuleElementDst* PolicyRule::getDst() { if (dst_re) return dst_re; FWObject::iterator i1 = begin(); i1++; dst_re = RuleElementDst::cast(*i1); return dst_re; } RuleElementSrv* PolicyRule::getSrv() { if (srv_re) return srv_re; FWObject::iterator i1 = begin(); i1++; i1++; srv_re = RuleElementSrv::cast(*i1); return srv_re; } RuleElementItf* PolicyRule::getItf() { if (itf_re) return itf_re; FWObject::iterator i1 = begin(); i1++; i1++; i1++; itf_re = RuleElementItf::cast(*i1); return itf_re; } RuleElementInterval* PolicyRule::getWhen() { if (when_re) return when_re; FWObject::iterator i1 = begin(); i1++; i1++; i1++; i1++; when_re = RuleElementInterval::cast(*i1); return when_re; } bool PolicyRule::isEmpty() { return (getSrc()->isAny() && getDst()->isAny() && getSrv()->isAny() && getItf()->isAny()); } string PolicyRule::getActionAsString() const { return getActionAsString(action); } // static method string PolicyRule::getActionAsString(int act) { switch (act) { case Accept: return "Accept"; case Deny: return "Deny"; case Reject: return "Reject"; case Scrub: return "Scrub"; case Return: return "Return"; case Skip: return "Skip"; case Continue: return "Continue"; case Accounting: return "Accounting"; case Modify: return "Modify"; case Pipe: return "Pipe"; case Custom: return "Custom"; case Branch: return "Branch"; default: return "Unknown"; } return "Deny"; } void PolicyRule::setAction(const string& act) { if (act=="Accept") { setAction(Accept); return; } if (act=="Deny") { setAction(Deny); return; } if (act=="Reject") { setAction(Reject); return; } if (act=="Scrub") { setAction(Scrub); return; } if (act=="Return") { setAction(Return); return; } if (act=="Skip") { setAction(Skip); return; } if (act=="Continue") { setAction(Continue); return; } if (act=="Accounting") { setAction(Accounting); return; } if (act=="Modify") { setAction(Modify); return; } if (act=="Pipe") { setAction(Pipe); return; } if (act=="Custom") { setAction(Custom); return; } if (act=="Branch") { setAction(Branch); return; } setAction(Deny); } string PolicyRule::getDirectionAsString() const { switch (direction) { case Inbound: return "Inbound"; case Outbound: return "Outbound"; default: return "Both"; } return "Both"; } void PolicyRule::setDirection(const string& dir) { if (dir=="Inbound") { setDirection(Inbound); return; } if (dir=="Outbound") { setDirection(Outbound); return; } setDirection(Both); } bool PolicyRule::getLogging() const { return getBool("log"); } void PolicyRule::setLogging(bool flag) { setBool("log",flag); } void PolicyRule::fromXML(xmlNodePtr root) throw(FWException) { const char* n; FWObject::fromXML(root); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("position"))); if(n) { setInt("position",atoi(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("disabled"))); if(n) { setStr("disabled",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("action"))); if(n) { setAction(string(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("log"))); if(n) { setStr("log",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("interface"))); if(n) { setStr("interface",n); FREEXMLBUFF(n); } n= FROMXMLCAST(xmlGetProp(root,TOXMLCAST("direction"))); if(n) { setDirection(string(n)); FREEXMLBUFF(n); } n= FROMXMLCAST(xmlGetProp(root,TOXMLCAST("group"))); if(n) { setStr("group",n); FREEXMLBUFF(n); } } xmlNodePtr PolicyRule::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("action"), STRTOXMLCAST(getActionAsString())); xmlNewProp(me, TOXMLCAST("direction"),STRTOXMLCAST(getDirectionAsString())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); FWObject *o; /* * Save children to XML file in just this order (src, dst, srv). * PolicyCompiler::checkForShadowing depends on it! * But after all, DTD requires this order. * */ if ( (o=getFirstByType( RuleElementSrc::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementDst::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementSrv::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementItf::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementInterval::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( PolicyRuleOptions::TYPENAME ))!=NULL ) o->toXML(me); // there should be no children Policy objects in v3 if ( (o=getFirstByType( Policy::TYPENAME ))!=NULL ) o->toXML(me); return me; } FWOptions* PolicyRule::getOptionsObject() const { return FWOptions::cast( getFirstByType(PolicyRuleOptions::TYPENAME) ); } /* * FWObjectDatabase::setPredictableIds() calls this method after it * has updated string ID of all objects, including rule sets. */ void PolicyRule::updateNonStandardObjectReferences() { if (getAction() == PolicyRule::Branch) { RuleSet *branch_ruleset = getBranch(); setBranch(branch_ruleset); } if (getTagging()) { FWObject *tag_object = getTagObject(); setTagObject(tag_object); } } RuleSet* PolicyRule::getBranch() { if (getAction() != PolicyRule::Branch) return NULL; FWObject *fw = this; while (fw && Firewall::cast(fw) == NULL) fw = fw->getParent(); assert(fw!=NULL); string branch_id = getOptionsObject()->getStr("branch_id"); if (!branch_id.empty()) { return RuleSet::cast(getRoot()->findInIndex( FWObjectDatabase::getIntId(branch_id))); } else { string branch_name = getOptionsObject()->getStr("branch_name"); if (!branch_name.empty()) { return RuleSet::cast( fw->findObjectByName(Policy::TYPENAME, branch_name)); } else return NULL; } } void PolicyRule::setBranch(RuleSet* ruleset) { string branch_id = (ruleset) ? FWObjectDatabase::getStringId(ruleset->getId()) : ""; getOptionsObject()->setStr("branch_id", branch_id); } bool PolicyRule::getRouting() const { return getOptionsObject()->getBool("routing"); } void PolicyRule::setRouting(bool f) { getOptionsObject()->setBool("routing", f); } bool PolicyRule::getClassification() const { return getOptionsObject()->getBool("classification"); } void PolicyRule::setClassification(bool f) { getOptionsObject()->setBool("classification", f); } bool PolicyRule::getTagging() const { return getOptionsObject()->getBool("tagging"); } void PolicyRule::setTagging(bool f) { getOptionsObject()->setBool("tagging", f); } void PolicyRule::setTagObject(FWObject *tag_object) { string tag_id = (tag_object) ? FWObjectDatabase::getStringId(tag_object->getId()) : ""; getOptionsObject()->setStr("tagobject_id", tag_id); setTagging(tag_object && ! tag_id.empty()); } FWObject* PolicyRule::getTagObject() { if (getTagging()) { string tagobj_id = getOptionsObject()->getStr("tagobject_id"); if (!tagobj_id.empty()) { return getRoot()->findInIndex( FWObjectDatabase::getIntId(tagobj_id)); } } return NULL; } string PolicyRule::getTagValue() { if (getTagging()) { TagService *tagobj = TagService::cast(getTagObject()); if (tagobj) return tagobj->getCode(); else return getOptionsObject()->getStr("tagvalue"); } return ""; } /** * Add reference to given object. In case of PolicyRule this only * makes sense in terms of adding reference to this object as an * argument for actions Branch and Tag. */ void PolicyRule::addRef(FWObject *obj) { if (RuleSet::cast(obj)) { setBranch(RuleSet::cast(obj)); } if (TagService::cast(obj)) { setTagObject(TagService::cast(obj)); } } /** * Removes reference to given object among children of 'this'. In case * of PolicyRule we should also clear reference to it if action is * Branch. Caveat: clear reference to it even if action is not branch * right now but was in the past and reference got stuck in options. * * Do the same for the TagService */ void PolicyRule::removeRef(FWObject *obj) { if (RuleSet::cast(obj)) { string branch_id = FWObjectDatabase::getStringId(obj->getId()); string rule_branch_id = getOptionsObject()->getStr("branch_id"); if (branch_id == rule_branch_id) getOptionsObject()->setStr("branch_id", ""); } if (TagService::cast(obj)) { string tag_id = FWObjectDatabase::getStringId(obj->getId()); string rule_tag_id = getOptionsObject()->getStr("tagobject_id"); if (tag_id == rule_tag_id) getOptionsObject()->setStr("tagobject_id", ""); } FWObject::removeRef(obj); } void PolicyRule::replaceReferenceInternal(int old_id, int new_id, int &counter) { if (old_id == new_id) return; FWObject::replaceReferenceInternal(old_id, new_id, counter); string branch_id = getOptionsObject()->getStr("branch_id"); if (!branch_id.empty()) { int branch_id_int = FWObjectDatabase::getIntId(branch_id); if (branch_id_int == old_id) { getOptionsObject()->setStr("branch_id", FWObjectDatabase::getStringId(new_id)); counter++; } } } /***************************************************************************/ const char *NATRule::TYPENAME={"NATRule"}; NATRule::NATRule() : Rule() { rule_type = Unknown; setAction(NATRule::Translate); osrc_re = NULL; odst_re = NULL; osrv_re = NULL; tsrc_re = NULL; tdst_re = NULL; tsrv_re = NULL; itf_inb_re = NULL; itf_outb_re = NULL; when_re = NULL; } void NATRule::init(FWObjectDatabase *root) { FWObject *re = getFirstByType(RuleElementOSrc::TYPENAME); if (re == NULL) { re = root->createRuleElementOSrc(); assert(re!=NULL); add(re); osrc_re = RuleElementOSrc::cast(re); re = root->createRuleElementODst(); assert(re!=NULL); add(re); odst_re = RuleElementODst::cast(re); re = root->createRuleElementOSrv(); assert(re!=NULL); add(re); osrv_re = RuleElementOSrv::cast(re); re = root->createRuleElementTSrc(); assert(re!=NULL); add(re); tsrc_re = RuleElementTSrc::cast(re); re = root->createRuleElementTDst(); assert(re!=NULL); add(re); tdst_re = RuleElementTDst::cast(re); re = root->createRuleElementTSrv(); assert(re!=NULL); add(re); tsrv_re = RuleElementTSrv::cast(re); re = root->createRuleElementItfInb(); assert(re!=NULL); add(re); itf_inb_re = RuleElementItfInb::cast(re); re = root->createRuleElementItfOutb(); assert(re!=NULL); add(re); itf_outb_re = RuleElementItfOutb::cast(re); add( root->createNATRuleOptions() ); } } /** * Add reference to given object. In case of NATRule this only * makes sense in terms of adding reference to this object as an * argument for action Branch. */ void NATRule::addRef(FWObject *obj) { if (RuleSet::cast(obj)) { setBranch(RuleSet::cast(obj)); } } /** * Removes reference to given object among children of 'this'. In case * of NATRule we should also clear reference to it if action is * Branch. Caveat: clear reference to it even if action is not branch * right now but was in the past and reference got stuck in options. */ void NATRule::removeRef(FWObject *obj) { if (RuleSet::cast(obj)) { string branch_id = FWObjectDatabase::getStringId(obj->getId()); string rule_branch_id = getOptionsObject()->getStr("branch_id"); if (branch_id == rule_branch_id) getOptionsObject()->setStr("branch_id", ""); } FWObject::removeRef(obj); } RuleElementOSrc* NATRule::getOSrc() { if (osrc_re) return osrc_re; osrc_re = RuleElementOSrc::cast(getFirstByType(RuleElementOSrc::TYPENAME)); return osrc_re; } RuleElementODst* NATRule::getODst() { if (odst_re) return odst_re; odst_re = RuleElementODst::cast(getFirstByType(RuleElementODst::TYPENAME)); return odst_re; } RuleElementOSrv* NATRule::getOSrv() { if (osrv_re) return osrv_re; osrv_re = RuleElementOSrv::cast(getFirstByType(RuleElementOSrv::TYPENAME)); return osrv_re; } RuleElementTSrc* NATRule::getTSrc() { if (tsrc_re) return tsrc_re; tsrc_re = RuleElementTSrc::cast(getFirstByType(RuleElementTSrc::TYPENAME)); return tsrc_re; } RuleElementTDst* NATRule::getTDst() { if (tdst_re) return tdst_re; tdst_re = RuleElementTDst::cast(getFirstByType(RuleElementTDst::TYPENAME)); return tdst_re; } RuleElementTSrv* NATRule::getTSrv() { if (tsrv_re) return tsrv_re; tsrv_re = RuleElementTSrv::cast(getFirstByType(RuleElementTSrv::TYPENAME)); return tsrv_re; } RuleElementInterval* NATRule::getWhen() { if (when_re) return when_re; when_re = RuleElementInterval::cast(getFirstByType(RuleElementInterval::TYPENAME)); return when_re; } RuleElementItfInb* NATRule::getItfInb() { if (itf_inb_re) return itf_inb_re; itf_inb_re = RuleElementItfInb::cast(getFirstByType(RuleElementItfInb::TYPENAME)); return itf_inb_re; } RuleElementItfOutb* NATRule::getItfOutb() { if (itf_outb_re) return itf_outb_re; itf_outb_re = RuleElementItfOutb::cast(getFirstByType(RuleElementItfOutb::TYPENAME)); return itf_outb_re; } string NATRule::getActionAsString() const { return getActionAsString(action); } // static method string NATRule::getActionAsString(int act) { if (act == Branch) return "NATBranch"; return "Translate"; } void NATRule::setAction(const string& act) { if (act=="Translate") { setAction(Translate); return; } if (act=="Branch") { setAction(Branch); return; } if (act=="NATBranch") { setAction(Branch); return; } setAction(Translate); } bool NATRule::isEmpty() { RuleElement *osrc = getOSrc(); RuleElement *odst = getODst(); RuleElement *osrv = getOSrv(); RuleElement *tsrc = getTSrc(); RuleElement *tdst = getTDst(); RuleElement *tsrv = getTSrv(); RuleElement *itf_inb = getItfInb(); RuleElement *itf_outb = getItfOutb(); return (osrc->isAny() && odst->isAny() && osrv->isAny() && tsrc->isAny() && tdst->isAny() && tsrv->isAny() && itf_inb->isAny() && itf_outb->isAny()); } void NATRule::fromXML(xmlNodePtr root) throw(FWException) { const char* n; FWObject::fromXML(root); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("action"))); if(n) { setAction(string(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("disabled"))); if(n) { setStr("disabled",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("position"))); if(n) { setStr("position",n); FREEXMLBUFF(n); } n= FROMXMLCAST(xmlGetProp(root,TOXMLCAST("group"))); if(n) { setStr("group",n); FREEXMLBUFF(n); } } xmlNodePtr NATRule::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); // xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("action"), STRTOXMLCAST(getActionAsString())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); FWObject *o; if ( (o=getFirstByType( RuleElementOSrc::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementODst::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementOSrv::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementTSrc::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementTDst::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementTSrv::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementItfInb::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementItfOutb::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementInterval::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( NATRuleOptions::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( NAT::TYPENAME ))!=NULL ) o->toXML(me); return me; } FWOptions* NATRule::getOptionsObject() const { return FWOptions::cast( getFirstByType(NATRuleOptions::TYPENAME) ); } RuleSet* NATRule::getBranch() { if (getAction() != NATRule::Branch) return NULL; FWObject *fw = getParent()->getParent(); assert(fw!=NULL); string branch_id = getOptionsObject()->getStr("branch_id"); if (!branch_id.empty()) { return RuleSet::cast(getRoot()->findInIndex( FWObjectDatabase::getIntId(branch_id))); } else { string branch_name = getOptionsObject()->getStr("branch_name"); if (!branch_name.empty()) return RuleSet::cast(fw->findObjectByName(NAT::TYPENAME, branch_name)); else return NULL; } } void NATRule::setBranch(RuleSet* ruleset) { string branch_id = (ruleset) ? FWObjectDatabase::getStringId(ruleset->getId()) : ""; getOptionsObject()->setStr("branch_id", branch_id); } NATRule::NATRuleTypes NATRule::getRuleType() const { return rule_type; } string NATRule::getRuleTypeAsString() const { switch (rule_type) { case SNAT: return("SNAT"); case DNAT: return("DNAT"); case SDNAT: return("SDNAT"); case Masq: return("Masq"); case SNetnat: return("SNetnat"); case DNetnat: return("DNetnat"); case Redirect: return("Redirect"); case Return: return("Return"); case Skip: return("Skip"); case Continue: return("Continue"); case LB: return("LB"); case NONAT: return("NONAT"); case NATBranch: return("NATBranch"); default: return("Unknown"); } } void NATRule::setRuleType(NATRuleTypes rt) { rule_type=rt; } FWObject& NATRule::shallowDuplicate(const FWObject *x, bool preserve_id) throw(FWException) { const NATRule *rx = NATRule::constcast(x); if (rx!=NULL) rule_type = rx->rule_type; setAction(rx->getAction()); osrc_re = NULL; odst_re = NULL; osrv_re = NULL; tsrc_re = NULL; tdst_re = NULL; tsrv_re = NULL; itf_inb_re = NULL; itf_outb_re = NULL; when_re = NULL; return Rule::shallowDuplicate(x, preserve_id); } bool NATRule::cmp(const FWObject *x, bool recursive) throw(FWException) { const NATRule *rx = NATRule::constcast(x); if (rx == NULL) return false; if (getAction() != rx->getAction()) return false; return Rule::cmp(x, recursive); } /***************************************************************************/ const char *RoutingRule::TYPENAME={"RoutingRule"}; RoutingRule::RoutingRule() : Rule() { rule_type=Undefined; sorted_dst_ids=""; setMetric(0); } void RoutingRule::init(FWObjectDatabase *root) { FWObject *re = getFirstByType(RuleElementRDst::TYPENAME); if (re == NULL) { re = root->createRuleElementRDst(); assert(re!=NULL); add(re); re = root->createRuleElementRGtw(); assert(re!=NULL); add(re); re = root->createRuleElementRItf(); assert(re!=NULL); add(re); add( root->createRoutingRuleOptions() ); } } RuleElementRDst* RoutingRule::getRDst() const { return RuleElementRDst::cast(getFirstByType(RuleElementRDst::TYPENAME)); } RuleElementRGtw* RoutingRule::getRGtw() const { return RuleElementRGtw::cast(getFirstByType(RuleElementRGtw::TYPENAME)); } RuleElementRItf* RoutingRule::getRItf() const { return RuleElementRItf::cast(getFirstByType(RuleElementRItf::TYPENAME)); } bool RoutingRule::isEmpty() const { RuleElement *rdst=getRDst(); RuleElement *rgtw=getRGtw(); RuleElement *ritf=getRItf(); return (rdst->isAny() && rgtw->isAny() && ritf->isAny()); } int RoutingRule::getMetric() const { return getInt("metric"); } string RoutingRule::getMetricAsString() const { stringstream s; s << getMetric(); return s.str(); } void RoutingRule::setMetric(const int metric) { setInt("metric", metric); } void RoutingRule::setMetric(string metric) { int imetric = atoi(metric.c_str()); setInt("metric", imetric); } void RoutingRule::fromXML(xmlNodePtr root) throw(FWException) { const char* n; FWObject::fromXML(root); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("disabled"))); if(n) { setStr("disabled",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("metric"))); if(n) { setStr("metric",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("position"))); if(n) { setStr("position",n); FREEXMLBUFF(n); } n= FROMXMLCAST(xmlGetProp(root,TOXMLCAST("group"))); if(n) { setStr("group",n); FREEXMLBUFF(n); } } xmlNodePtr RoutingRule::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); // xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); FWObject *o; if ( (o=getFirstByType( RuleElementRDst::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementRGtw::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RuleElementRItf::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( RoutingRuleOptions::TYPENAME ))!=NULL ) o->toXML(me); if ( (o=getFirstByType( Routing::TYPENAME ))!=NULL ) o->toXML(me); return me; } FWOptions* RoutingRule::getOptionsObject() const { return FWOptions::cast( getFirstByType(RoutingRuleOptions::TYPENAME) ); } RuleSet* RoutingRule::getBranch() { FWObject *fw = getParent()->getParent(); assert(fw!=NULL); string branch_id = getOptionsObject()->getStr("branch_id"); if (!branch_id.empty()) { return RuleSet::cast(getRoot()->findInIndex( FWObjectDatabase::getIntId(branch_id))); } else { string branch_name = getOptionsObject()->getStr("branch_name"); if (!branch_name.empty()) return RuleSet::cast(fw->findObjectByName(Routing::TYPENAME, branch_name)); else return NULL; } } RoutingRule::RoutingRuleTypes RoutingRule::getRuleType() const { return rule_type; } string RoutingRule::getRuleTypeAsString() const { switch (rule_type) { case Undefined: return("Undefined"); case SinglePath: return("Single Path"); case MultiPath: return("Multi Path"); default: return("Unknown"); } } void RoutingRule::setRuleType(RoutingRuleTypes rt) { rule_type=rt; } FWObject& RoutingRule::duplicate(const FWObject *x, bool preserve_id) throw(FWException) { Rule::duplicate(x,preserve_id); const RoutingRule *rx = RoutingRule::constcast(x); if (rx!=NULL) { rule_type = rx->rule_type; sorted_dst_ids = rx->sorted_dst_ids; } return *this; } void RoutingRule::setSortedDstIds(const string& ids) { sorted_dst_ids = ids; } string RoutingRule::getSortedDstIds() const { return sorted_dst_ids; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Tools.cpp0000644000175000017500000001363711733011756024627 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Tools.h" #include "fwbuilder/XMLTools.h" #include #include #include #include /* * this is workaround, for some reason dirent.h defines DIR as a typedef * for struct __dirstream which is not defined anywhere. 07/12/02 vk */ #ifndef __dirstream struct __dirstream {}; #endif #ifndef _WIN32 # include # include #else # include # include //# include # include #endif using namespace std; namespace libfwbuilder { char *cxx_strdup(const string &x) { char *res=new char[x.length()+1]; strcpy(res, x.c_str()); return res; } char *cxx_strdup(const char *x) { if(!x) return (char*)NULL; char *res=new char[strlen(x)+1]; strcpy(res,x); return res; } int cxx_strcasecmp(const char *s1, const char *s2) { #ifndef _WIN32 return ::strcasecmp(s1,s2); #else return _stricoll(s1,s2); #endif } void init() { #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 0 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { // Could not find usable dll cerr << "Could not initialize winsock dll v2.0"; return; } // Confirm that the WinSock DLL supports 2.0. if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) { cerr << "Could not initialize winsock dll v2.0"; WSACleanup( ); return; } #endif /* Init XML parser */ XMLTools::initXMLTools(); } /** * portable function that gets a list of files in the directory. * dir - directory * ext - file extension mask, should be just "xml" rather than "*.xml" */ list getDirList(const std::string &dir, const std::string &ext) { list res; #ifndef _WIN32 DIR *d=opendir(dir.c_str()); if (d!=NULL) { struct dirent *de; while ( (de=readdir(d))!=NULL ) { if (strcmp(de->d_name,".")==SAME || strcmp(de->d_name,"..")==SAME) continue; string pfile=de->d_name; string rfile=dir+FS_SEPARATOR+pfile; if (rfile.rfind(string(".")+ext)==rfile.size()-ext.size()-1) res.push_back(rfile); } } closedir(d); #else struct _finddata_t c_file; long hFile; string filepath=dir + FS_SEPARATOR + "*." + ext; /* Find first file in current directory */ if( (hFile = _findfirst( filepath.c_str(), &c_file )) != -1L ) { string rfile=dir+FS_SEPARATOR+c_file.name; res.push_back(rfile); /* Find the rest of the files */ while( _findnext( hFile, &c_file ) == 0 ) { string rfile=dir+FS_SEPARATOR+c_file.name; res.push_back(rfile); } } #endif return res; } unsigned int cxx_sleep(unsigned int seconds) { #ifndef _WIN32 return sleep(seconds); #else Sleep(seconds*1000); return 0; #endif } void tokenize(const string& str, vector& tokens, const string& delimiters) { // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } } string strip(const string& in, const string& identifier) { string result; vector parts; tokenize(in, parts, identifier); for (vector::iterator it = parts.begin(); it != parts.end(); ++it) { result += *it; } return result; } string stringify(const vector& parts, const string& delimiter) { string result; vector::const_iterator it = parts.begin(); while (it != parts.end()) { result += *it++; if (it != parts.end()) { result += delimiter; } } return result; } set stringToSet(const string &str) { set ret; size_t lastpos = 0; for ( ; ; ) { size_t pos = str.find(',', lastpos); if (pos == string::npos) { if (lastpos < str.size()) { ret.insert(str.substr(lastpos)); } return ret; } ret.insert(str.substr(lastpos, pos - lastpos)); lastpos = pos + 1; } } string setToString(const set &s) { string ret; set::const_iterator iter; bool first = true; for (iter = s.begin(); iter != s.end(); ++iter) { if (first) { first = false; } else { ret += ","; } ret += *iter; } return ret; } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Network.cpp0000644000175000017500000000645511733011756025160 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Network.h" #include "fwbuilder/XMLTools.h" #include using namespace libfwbuilder; using namespace std; const char *Network::TYPENAME={"Network"}; Network::Network() : Address() { setNetmask(InetAddr(AF_INET, 32)); } Network::Network(Network &o) : Address(o) { FWObject::operator=(o); setAddress(*(o.getAddressPtr())); setNetmask(*(o.getNetmaskPtr())); } Network::Network (const string &s) : Address() { setAddressNetmask(s); } Network::~Network() {} void Network::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address"))); assert(n!=NULL); setAddress(InetAddr(n)); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("netmask"))); assert(n!=NULL); setNetmask(InetAddr(n)); FREEXMLBUFF(n); } xmlNodePtr Network::toXML(xmlNodePtr xml_parent_node) throw(FWException) { if (getName().empty()) setName(getTypeName()); xmlNodePtr me = FWObject::toXML(xml_parent_node); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("address"), STRTOXMLCAST(getAddressPtr()->toString())); xmlNewProp(me, TOXMLCAST("netmask"), STRTOXMLCAST(getNetmaskPtr()->toString())); return me; } /* check if host address bits are cleared */ bool Network::isValidRoutingNet() const { return (*(getAddressPtr()) == *(getNetworkAddressPtr())); } void Network::setAddress(const InetAddr &a) { inet_addr_mask->setAddress(a); } void Network::setNetmask(const InetAddr &nm) { inet_addr_mask->setNetmask(nm); } void Network::setAddressNetmask(const std::string& s) { delete inet_addr_mask; inet_addr_mask = new InetAddrMask(s); } const InetAddr* Network::getFirstHostPtr() const { const InetAddrMask *inet_addr_mask = getInetAddrMaskObjectPtr(); if (inet_addr_mask) return inet_addr_mask->getFirstHostPtr(); return NULL; } const InetAddr* Network::getLastHostPtr() const { const InetAddrMask *inet_addr_mask = getInetAddrMaskObjectPtr(); if (inet_addr_mask) return inet_addr_mask->getLastHostPtr(); return NULL; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Rule.h0000644000175000017500000003274211733011756024101 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RULE_HH_FLAG__ #define __RULE_HH_FLAG__ #include "fwbuilder/Group.h" namespace libfwbuilder { class FWOptions; class RuleElementSrc; class RuleElementDst; class RuleElementSrv; class RuleElementItf; class RuleElementOSrc; class RuleElementODst; class RuleElementOSrv; class RuleElementTSrc; class RuleElementTDst; class RuleElementTSrv; class RuleElementItfInb; class RuleElementItfOutb; class RuleElementInterval; class RuleElementRDst; class RuleElementRGtw; class RuleElementRItf; class RuleSet; class Rule : public Group { /* these members are used only by compilers and are not stored in XML */ std::string label; bool fallback; bool hidden; std::string unique_id; int abs_rule_number; /* compilers store warnings and errors associated with this rule here. */ std::string compiler_message; public: Rule(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); DECLARE_FWOBJECT_SUBTYPE(Rule); DECLARE_DISPATCH_METHODS(Rule); void setPosition(int n); int getPosition() const; void setCompilerMessage(const std::string &msg) { compiler_message = msg; } std::string getCompilerMessage() { return compiler_message; } void disable(); void enable(); bool isDisabled() const; bool isFallback() const { return fallback; } void setFallback(bool f) { fallback=f; } bool isHidden() const { return hidden; } void setHidden(bool f) { hidden=f; } std::string getUniqueId() const { return unique_id; } void setUniqueId(const std::string &str) { unique_id=str; } std::string getLabel() const { return label; } void setLabel(const std::string &l) { label=l; } std::string getRuleGroupName() const; void setRuleGroupName(const std::string &group_name); int getAbsRuleNumber() const { return abs_rule_number; } void setAbsRuleNumber(int rn) { abs_rule_number=rn; } virtual bool isEmpty(); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual FWOptions* getOptionsObject() const; // find branch ruleset for policy rules with action Branch // We may support some kind of branching in NAT in the future, so // lets make this method virtual. virtual RuleSet* getBranch(); virtual void setBranch(RuleSet *ruleset); virtual bool isPrimaryObject() const { return false; } }; class PolicyRule : public Rule { public: /* * Supported policy rule actions: * * Accept - accept the packet, analysis terminates * * Reject - reject the packet and send ICMP 'unreachable' or * TCP RST back to sender, analysis terminates * * Deny - drop the packet, nothing is sent back to sender, * analysis terminates * * Scrub - run the packet through normalizer (see 'scrub' in * PF), continue analysis * * Return - action used internally, meaning may depend on * implementation of the policy compiler but generally * means return from the block of rules * * Skip - skip N rules down and continue analysis. Used * internally. * * Continue - do nothing, continue analysis. Used internally. * * Accounting - generate target firewall platform rule to count * the packet and continue analysis. * * Modify - edit the packet (change some header values, like * TOS bits) or mark it somehow if the kernel supports * that (e.g. target MARK in iptables) * * Branch - * * Route - * */ typedef enum { Unknown, Accept, Reject, Deny, Scrub, Return, Skip, Continue, Accounting, Modify, Pipe, Custom, Branch} Action; typedef enum { Undefined, Inbound, Outbound, Both } Direction; private: libfwbuilder::RuleElementSrc* src_re; libfwbuilder::RuleElementDst* dst_re; libfwbuilder::RuleElementSrv* srv_re; libfwbuilder::RuleElementItf* itf_re; libfwbuilder::RuleElementInterval* when_re; Action action; Direction direction; protected: virtual void updateNonStandardObjectReferences(); public: PolicyRule(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr parent) throw(FWException); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(PolicyRule); DECLARE_DISPATCH_METHODS(PolicyRule); virtual FWOptions* getOptionsObject() const; virtual RuleSet* getBranch(); virtual void setBranch(RuleSet *ruleset); virtual bool isEmpty(); /** * Removes reference to given object among * children of 'this'. */ virtual void removeRef(FWObject *obj); /** * Add reference to given object to 'this'. In case of a PolicyRule, * change action and add parameter if @obj is TagService or RuleSet. */ virtual void addRef(FWObject *obj); /** * if this object has any references as its children, replace IDs * these references point to. This overloaded method also replaces * references to branch rulesets. */ virtual void replaceReferenceInternal(int old_id, int new_id, int &counter); libfwbuilder::RuleElementSrc* getSrc() ; libfwbuilder::RuleElementDst* getDst() ; libfwbuilder::RuleElementSrv* getSrv() ; libfwbuilder::RuleElementItf* getItf() ; libfwbuilder::RuleElementInterval* getWhen() ; Action getAction() const { return action; } void setAction(Action act) { action = act; } static std::string getActionAsString(int act); std::string getActionAsString() const; void setAction(const std::string& act); Direction getDirection() const { return direction; } void setDirection(Direction dir) { direction = dir; } std::string getDirectionAsString() const; void setDirection(const std::string& dir); bool getLogging() const; void setLogging(bool flag); // return true if rule does tagging bool getTagging() const; void setTagging(bool f); // return true if rule does routing bool getRouting() const; void setRouting(bool f); // return true if rule does classification bool getClassification() const; void setClassification(bool f); // find TagService object for rules that do tagging FWObject* getTagObject(); std::string getTagValue(); void setTagObject(FWObject *tag_object); }; class NATRule : public Rule { public: typedef enum { Translate, Branch } NATAction; /* * Supported NAT rule types: * * Unknown - Uknown action * * NONAT - Exception to other nat rules * * SNAT - Source NAT - Translate Source Address * * Masq - Masquerading. * * DNAT - Destnation NAT - Translate Destination Address. * * SDNAT - Source & Destination NAT - Translate both source and * destination addresses. * * SNetNAT - Source Network Translation - Translate source * address network. * * DNetNAT - Destination Network Translation - Translate * destination address network. * * Redirect - Redirect to firewall - Translate destination to a * firewall address. * * Return - Internal use for rule chains. * * Skip - * * Continue - Internal use for nat rules with negation. * * LB - NAT Rule that does load ballencing. * * NOTE: Not all types supported on all platforms. * */ typedef enum { Unknown, NONAT, NATBranch, SNAT, Masq, DNAT, SDNAT, SNetnat, DNetnat, Redirect , Return , Skip , Continue , LB } NATRuleTypes; private: libfwbuilder::RuleElementOSrc* osrc_re; libfwbuilder::RuleElementODst* odst_re; libfwbuilder::RuleElementOSrv* osrv_re; libfwbuilder::RuleElementTSrc* tsrc_re; libfwbuilder::RuleElementTDst* tdst_re; libfwbuilder::RuleElementTSrv* tsrv_re; libfwbuilder::RuleElementItfInb* itf_inb_re; libfwbuilder::RuleElementItfOutb* itf_outb_re; libfwbuilder::RuleElementInterval* when_re; NATAction action; NATRuleTypes rule_type; public: NATRule(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr parent) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(NATRule); DECLARE_DISPATCH_METHODS(NATRule); virtual FWOptions* getOptionsObject() const; virtual RuleSet* getBranch(); virtual void setBranch(RuleSet *ruleset); virtual bool isEmpty(); /** * Removes reference to given object among * children of 'this'. */ virtual void removeRef(FWObject *obj); /** * Add reference to given object to 'this'. In case of a PolicyRule, * change action and add parameter if @obj is TagService or RuleSet. */ virtual void addRef(FWObject *obj); libfwbuilder::RuleElementOSrc* getOSrc(); libfwbuilder::RuleElementODst* getODst(); libfwbuilder::RuleElementOSrv* getOSrv(); libfwbuilder::RuleElementTSrc* getTSrc(); libfwbuilder::RuleElementTDst* getTDst(); libfwbuilder::RuleElementTSrv* getTSrv(); libfwbuilder::RuleElementItfInb* getItfInb(); libfwbuilder::RuleElementItfOutb* getItfOutb(); libfwbuilder::RuleElementInterval* getWhen(); NATAction getAction() const { return action; } void setAction(NATAction act) { action = act; } static std::string getActionAsString(int act); std::string getActionAsString() const; void setAction(const std::string& act); NATRuleTypes getRuleType() const; std::string getRuleTypeAsString() const; void setRuleType(NATRuleTypes rt); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); }; class RoutingRule : public Rule { public: typedef enum { Undefined, SinglePath, MultiPath } RoutingRuleTypes; private: RoutingRuleTypes rule_type; std::string sorted_dst_ids; int ecmp_id; public: RoutingRule(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(RoutingRule); DECLARE_DISPATCH_METHODS(RoutingRule); virtual FWOptions* getOptionsObject() const; virtual RuleSet* getBranch(); virtual bool isEmpty() const; int getMetric() const; void setMetric(int metric); void setMetric(std::string metric); std::string getMetricAsString() const; libfwbuilder::RuleElementRDst* getRDst() const; libfwbuilder::RuleElementRGtw* getRGtw() const; libfwbuilder::RuleElementRItf* getRItf() const; RoutingRuleTypes getRuleType() const; std::string getRuleTypeAsString() const; void setRuleType(RoutingRuleTypes rt); void setSortedDstIds(const std::string& ids); std::string getSortedDstIds() const; virtual FWObject& duplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); }; } #endif //__RULE_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FailoverClusterGroup.cpp0000644000175000017500000000302011733011756027636 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/FWOptions.h" using namespace std; using namespace libfwbuilder; const char *FailoverClusterGroup::TYPENAME = {"FailoverClusterGroup"}; FailoverClusterGroup::FailoverClusterGroup() : ClusterGroup() { setStr("type", ""); } void FailoverClusterGroup::fromXML(xmlNodePtr parent) throw(FWException) { ClusterGroup::fromXML(parent); // Read additional attributes here } xmlNodePtr FailoverClusterGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = ClusterGroup::toXML(parent); // Save additional attributes here return me; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Library.cpp0000644000175000017500000000366211733011756025130 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Library.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *Library::TYPENAME={"Library"}; Library::Library() {} Library::~Library() { } bool Library::validateChild(FWObject*) { return true; // anything goes } void Library::fromXML(xmlNodePtr root) throw(FWException) { const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("color"))); if(n!=NULL) // color is not a mandatory attribute { setStr("color", n); FREEXMLBUFF(n); } FWObject::fromXML(root); } xmlNodePtr Library::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWReference.h0000644000175000017500000000500011733011756025310 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWREF_HH_FLAG__ #define __FWREF_HH_FLAG__ #include "fwbuilder/FWObject.h" namespace libfwbuilder { /** * This class represents reference reference. */ class FWReference : public FWObject { private: std::string str_ref; int int_ref; protected: FWReference(); public: DECLARE_FWOBJECT_SUBTYPE(FWReference); DECLARE_DISPATCH_METHODS(FWReference); virtual ~FWReference(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual FWObject& shallowDuplicate( const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual void add(FWObject *obj); virtual FWObject *getPointer(); virtual int getPointerId(); void setPointer(FWObject *o); void setPointerId(int ref_id); virtual void dump(std::ostream &f,bool recursive,bool brief,int offset=0) const; virtual bool isPrimaryObject() const { return false; } /** * If obj is FWReference object, return pointer to the object this * reference points to. Otherwise return obj. This is a typical * operation repeated in many places where we loop over children * of some object. */ static FWObject* getObject(FWObject* obj); /** * Unlike getPointerId(), this method does not use cache when * returns reference ID. This is faster and makes it possible to * be const method but late initialization does not work when it * is used. */ int getPointerIdDirect() const { return int_ref; } }; } #endif // _FWREF_HH fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/InetAddrMask.cpp0000644000175000017500000003317311733011756026032 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/InetAddrMask.h" #include #include #include #include #include #include #ifndef _WIN32 # include # include #else # include #endif using namespace std; using namespace libfwbuilder; void InetAddrMask::setNetworkAndBroadcastAddress() { // see #2670. Per RFC3021 network with netmask /31 has no network // and direct broadcast addresses. if (netmask->isV4() && netmask->getLength() >= 31) { *network_address = *address; *broadcast_address = InetAddr(32); *last_host = *address; if (netmask->getLength() == 31) *last_host = *last_host + 1; } else { *network_address = *address & *netmask; *broadcast_address = *address | (~(*netmask)); *last_host = *broadcast_address; } } InetAddrMask::InetAddrMask(bool) { // this constructor does not create address, netmask and other // variables. This constructor should only be used by classes that // inherit InetAddrMask and create address, netmask themselves, // such as Inet6AddrMask address = NULL; netmask = NULL; broadcast_address = NULL; network_address = NULL; last_host = NULL; } InetAddrMask::InetAddrMask() { address = new InetAddr(); netmask = new InetAddr(); broadcast_address = new InetAddr(); network_address = new InetAddr(); last_host = new InetAddr(); } InetAddrMask::InetAddrMask(const InetAddr &a, const InetAddr &n) { address = new InetAddr(a & n); netmask = new InetAddr(n); broadcast_address = new InetAddr(); network_address = new InetAddr(); last_host = new InetAddr(); setNetworkAndBroadcastAddress(); } InetAddrMask::InetAddrMask(const InetAddrMask& other) { address = new InetAddr(*(other.address)); netmask = new InetAddr(*(other.netmask)); broadcast_address = new InetAddr(); network_address = new InetAddr(); last_host = new InetAddr(); setNetworkAndBroadcastAddress(); } InetAddrMask::InetAddrMask(const string &s) throw(FWException) { address = new InetAddr(); netmask = new InetAddr(); broadcast_address = new InetAddr(); network_address = new InetAddr(); last_host = new InetAddr(); if(s.find_first_not_of(".1234567890/")!=string::npos) { throw FWException(string("Invalid IP address: '")+s+"'"); } string::size_type pos=s.find("/"); if (pos==string::npos) { setAddress(InetAddr(s)); setNetmask(InetAddr(InetAddr::getAllOnes())); } else { setAddress(InetAddr(s.substr(0,pos))); string netm = s.substr(pos+1); if (netm.find(".")==string::npos) { // netmask is represented as /NN (length in bits) int d = atoi(netm.c_str()); *netmask = InetAddr(d); } else { setNetmask(InetAddr(netm)); } } setNetworkAndBroadcastAddress(); } InetAddrMask::~InetAddrMask() { if (address!=NULL) delete address; if (netmask!=NULL) delete netmask; if (network_address!=NULL) delete network_address; if (broadcast_address!=NULL) delete broadcast_address; if (last_host!=NULL) delete last_host; } bool InetAddrMask::isAny() { return (address->isAny() && netmask->isAny()); } void InetAddrMask::setAddress(const InetAddr &a) { *address = a; setNetworkAndBroadcastAddress(); } void InetAddrMask::setNetmask(const InetAddr &nm) { *netmask = nm; setNetworkAndBroadcastAddress(); } // check if address 'o' belongs to the network bool InetAddrMask::belongs(const InetAddr &o) const { return ((o & *netmask) == *network_address); } unsigned int InetAddrMask::dimension() const { /* * TODO: this code not portable 'cause it implies specific to IPv4 * maximum length of netmask */ int masklength = netmask->getLength(); int host_part = netmask->addressLengthBits() - masklength; if (host_part>=32) return INT_MAX; // can be >32 if ipv6 unsigned int u = 1; for (int i=0; igetAddressPtr()->addressFamily() != b.getAddressPtr()->addressFamily()) return false; return *(this->getAddressPtr()) < *(b.getAddressPtr()); } bool libfwbuilder::operator==(const InetAddrMask &a, const InetAddrMask &b) { if (a.getAddressPtr()->addressFamily() != b.getAddressPtr()->addressFamily()) return false; return ( *(a.getNetmaskPtr()) == *(b.getNetmaskPtr()) && *(a.getAddressPtr()) == *(b.getAddressPtr())); } bool libfwbuilder::operator<(const InetAddrMask &a, const InetAddrMask &b) { if (a.getAddressPtr()->addressFamily() != b.getAddressPtr()->addressFamily()) return false; return *(a.getAddressPtr()) < *(b.getAddressPtr()); } /* this is just a better interface to _convert_range_to_networks */ vector libfwbuilder::convertAddressRange(const InetAddr &start, const InetAddr &end) { vector res; _convert_range_to_networks(start,end,res); return res; } bool libfwbuilder::_convert_range_to_networks(const InetAddr &start, const InetAddr &end, vector &res) { if (end < start) return false; if (start == end) { res.push_back(InetAddrMask( start, InetAddr(InetAddr::getAllOnes(start.addressFamily())))); return false; } if (start.isAny() && end.isBroadcast()) { res.push_back( InetAddrMask() ); return false; } unsigned int size = start.distance(end); if (size==2) { res.push_back(InetAddrMask( start, InetAddr(InetAddr::getAllOnes(start.addressFamily())))); res.push_back(InetAddrMask( end, InetAddr(InetAddr::getAllOnes(end.addressFamily())))); return false; } /* determine closest power of 2 which is less or equal to size */ unsigned int l = size; int mask_bits = 0; while ( l!=0 ) { l>>=1; mask_bits++; } mask_bits--; mask_bits = start.addressLengthBits() - mask_bits; /* mask_bits represents number of '1'in the netmask for the new subnet */ /* test start address to see if it is a good network address for netmask */ InetAddr nm1(mask_bits); // new netmask InetAddrMask tn1(start, nm1); InetAddr nstart; InetAddr nend; InetAddr nnm; nstart = start; if (start != *(tn1.getAddressPtr())) { /* we can not use start address for the network because it shifts * beginning of the range back after netmask is applied to it. Need to * make netmask longer and then find the first address higher than * start, which matches the netmask and can be used as a network * address */ do { mask_bits++; nnm = InetAddr(mask_bits); tn1 = InetAddrMask(nstart, nnm); } while (start != *(tn1.getAddressPtr()) && mask_bits>0); nend = nstart; nend = nend | (~nnm); } else { /* find shortest netmask that yields subnet with end address within * required range. Start with very short netmask and keep making it longer * while the end of the subnet it defines is still above required end of * the range. Once the end moves inside the range, stop. */ mask_bits--; do { mask_bits++; nnm = InetAddr(mask_bits); // new netmask nend = start; nend = nend | (~nnm); } while (nend > end); } /* new range starts from nstart and ends at nend */ res.push_back( InetAddrMask(nstart, nnm) ); if (!(nstart == start)) { /* there are some addresses between start and nstart */ while (libfwbuilder::_convert_range_to_networks(start,nstart-1,res)) ; } if (!(nend == end)) { /* the remainder of the original range is nend+1 - end */ while (libfwbuilder::_convert_range_to_networks(nend+1,end,res)) ; } return false; } vector libfwbuilder::getOverlap(const InetAddrMask &n1, const InetAddrMask &n2) { const InetAddr& s1 = *(n1.getAddressPtr()); const InetAddr& s2 = *(n2.getAddressPtr()); const InetAddr& m1 = *(n1.getNetmaskPtr()); const InetAddr& m2 = *(n2.getNetmaskPtr()); InetAddr e1 = s1 | (~m1); InetAddr e2 = s2 | (~m2); /* * now both networks are represented by their first and last addresses * * we assume network 0.0.0.0/0.0.0.0 in fact represents the whole * possible range of ip addresses (for ip v4 it is 0.0.0.0 - * 255.255.255.255). Check for this condition and replace e1 or e2 * accordingly if needed. * */ if (s1.isAny() && m1.isAny()) e1 = InetAddr(InetAddr::getAllOnes(s1.addressFamily())); if (s2.isAny() && m2.isAny()) e2 = InetAddr(InetAddr::getAllOnes(s2.addressFamily())); vector res; if (e2 < s1) return res; if (e1 < s2) return res; if (s1 == s2 && e1 == e2) { // subnets are identical res.push_back(n1); return res; } if (e2 == s1) { // end of n2 == start of n1, overlap is just 1 address res.push_back(InetAddrMask(s1, InetAddr::getAllOnes(s1.addressFamily()))); return res; } if (e1 == s2) { // end of n1 == start of n2, overlap is just 1 address res.push_back(InetAddrMask(s2, InetAddr::getAllOnes(s2.addressFamily()))); return res; } if (s1 == s2 && e1 < e2) { // both subnets have the same start address, but n1 is smaller res.push_back(n1); return res; } if (s1 == s2 && e2 < e1) { // both subnets have the same start address, but n2 is smaller res.push_back(n2); return res; } if (s2 < s1 && e1 == e2) { // both subnets have the same end address, but n1 is smaller res.push_back(n1); return res; } if (s1 < s2 && e1 == e2) { // both subnets have the same end address, but n2 is smaller res.push_back(n2); return res; } if (s1 > s2 && e1 < e2) { // n1 fits inside of n2 res.push_back(n1); return res; } if (s2 > s1 && e2 < e1) { // n2 fits inside of n1 res.push_back(n2); return res; } InetAddr rs, re; // if (s1 == s2) { rs = s1; } if (s1 < s2) { rs = s2; } if (s2 < s1) { rs = s1; } // if (e1 == e2) { re = e1; } if (e1 < e2) { re = e1; } if (e2 < e1) { re = e2; } /* rb and re represent resulting address range boundaries */ libfwbuilder::_convert_range_to_networks(rs, re, res); return res; } vector libfwbuilder::substract(const InetAddrMask &n1, const InetAddrMask &n2) { const InetAddr n1s = *(n1.getAddressPtr()); const InetAddr n2s = *(n2.getAddressPtr()); const InetAddr n1m = *(n1.getNetmaskPtr()); const InetAddr n2m = *(n2.getNetmaskPtr()); InetAddr n1e = n1s; n1e = n1e | (~n1m); InetAddr n2e = n2s; n2e = n2e | (~n2m); /* * now both networks are represented by their first and last addresses * * we assume network 0.0.0.0/0.0.0.0 in fact represents the whole * possible range of ip addresses (for ip v4 it is 0.0.0.0 - * 255.255.255.255). Check for this condition and replace n1e or n2e * accordingly if needed. */ if (n1s.isAny() && n1e.isAny()) n1e=InetAddr(InetAddr::getAllOnes()); if (n2s.isAny() && n2e.isAny()) n2e=InetAddr(InetAddr::getAllOnes()); vector res; if (/* n2sn1s) { InetAddr rs=n2e + 1; InetAddr re=n1e; libfwbuilder::_convert_range_to_networks(rs,re,res); } if ( n2s>n1s && n2en1s && n2e>n1e) { InetAddr rs=n1s; InetAddr re=n2s - 1; libfwbuilder::_convert_range_to_networks(rs,re,res); } if (n2s>n1e /* && n2e>n1e */) { res.push_back(n1); } if (n2sn1e) { /* * Do nothing since in this case network n2 is bigger than n1 and n1 * is totally eclipsed by n2. Result is empty list. */ ; } return res; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectDatabase.cpp0000644000175000017500000003666211733011756026622 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include #include #include #include #include #include "fwbuilder/memcheck.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Library.h" #include "fwbuilder/Interval.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/IPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/Host.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Group.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Routing.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Management.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include #include using namespace std; using namespace libfwbuilder; // each program invocation tracks its own set of object ids (as int) // we just increment this counter to get new id. We also keep a dictionary // that maps integer ids to strings. This dictionary is populated when // objects are loaded from xml file and then used to write string ids // when objects are written back to file. Internally we operate with // integer ids all the time, string ids are only used in xml file. // "System" objects use ids < 1000. int id_seed = 1000; #ifdef _WIN32 static int cached_pid = _getpid(); # ifndef __GNUC__ #define snprintf sprintf_s # endif #else static int cached_pid = getpid(); #endif // these two dictionaries must be static to ensure uniqueness of integer // ids across multiple FWObjectDatabase objects map id_dict; map id_dict_reverse; const char* FWObjectDatabase::TYPENAME = {"FWObjectDatabase"}; const string FWObjectDatabase::DTD_FILE_NAME = "fwbuilder.dtd" ; FWObjectDatabase::FWObjectDatabase() : FWObject(false), data_file(), obj_index() { init_create_methods_table(); setRoot(this); index_hits = index_misses = 0; init_id_dict(); predictable_id_tracker = 0; ignore_read_only = false; searchId =0; lastModified = 0; setName(TYPENAME); setId( ROOT_ID ); setDirty(false); } FWObjectDatabase::FWObjectDatabase(FWObjectDatabase& d) : FWObject(false), data_file(), obj_index() { init_create_methods_table(); setRoot(this); index_hits = index_misses = 0; init_id_dict(); predictable_id_tracker = 0; ignore_read_only = false; data_file = d.data_file; setName(TYPENAME); searchId =0; busy = true; *this = d; // copies entire tree setId( ROOT_ID ); // I do not understand why do I need to reindex the whole database // after operator=. It calls FWobject::duplicate, which in turn // uses FWObject::shallowDuplicate, which calls addToIndex // This is necessary however. // addToIndexRecursive( this ); // reindex setDirty(false); busy = false; } FWObjectDatabase::~FWObjectDatabase() { busy = true; //verifyTree(); // debugging destroyChildren(); } void FWObjectDatabase::init_id_dict() { if (id_dict.size()==0) { id_dict[ROOT_ID] = "root"; id_dict[ANY_ADDRESS_ID] = "sysid0"; id_dict[ANY_SERVICE_ID] = "sysid1"; id_dict[ANY_INTERVAL_ID] = "sysid2"; id_dict[STANDARD_LIB_ID] = "syslib000"; id_dict[TEMPLATE_LIB_ID] = "syslib100"; id_dict[DELETED_OBJECTS_ID] = "sysid99"; for (map::iterator i=id_dict.begin(); i!=id_dict.end(); ++i) id_dict_reverse[i->second] = i->first; } } int FWObjectDatabase::registerStringId(const std::string &s_id) { int i_id = -1; if (id_dict_reverse.count(s_id) > 0) return id_dict_reverse[s_id]; i_id = ++id_seed; id_dict[i_id] = s_id; id_dict_reverse[s_id] = i_id; return i_id; } int FWObjectDatabase::getIntId(const std::string &s_id) { if (id_dict_reverse.count(s_id) > 0) return id_dict_reverse[s_id]; return -1; } string FWObjectDatabase::getStringId(int i_id) { if (id_dict.count(i_id) > 0) return id_dict[i_id]; // TODO: Use proper GUID algorithm here char id_buf[64]; snprintf(id_buf, sizeof(id_buf), "id%dX%d", i_id, cached_pid); id_dict[i_id] = string(id_buf); id_dict_reverse[string(id_buf)] = i_id; return id_dict[i_id]; } string FWObjectDatabase::getPredictableId(const string &prefix) { ostringstream str; str << prefix << predictable_id_tracker; string new_id = str.str(); predictable_id_tracker++; return new_id; } void FWObjectDatabase::_setPredictableStrIdsRecursively(FWObject *obj) { if (obj->getBool(".seen_this")) return; if (!obj->isReadOnly() && !FWObjectDatabase::isA(obj) && obj->getLibrary()->getId() != FWObjectDatabase::STANDARD_LIB_ID && obj->getLibrary()->getId() != FWObjectDatabase::DELETED_OBJECTS_ID && obj->getId() != -1) { string new_id = getPredictableId("id"); int int_id = obj->getId(); id_dict[int_id] = new_id; id_dict_reverse[new_id] = int_id; obj->setBool(".seen_this", true); } for (list::iterator it=obj->begin(); it!=obj->end(); ++it) { _setPredictableStrIdsRecursively(*it); } } void FWObjectDatabase::_updateNonStandardObjectReferencesRecursively( FWObject *obj) { for (list::iterator it=obj->begin(); it!=obj->end(); ++it) { (*it)->updateNonStandardObjectReferences(); _updateNonStandardObjectReferencesRecursively(*it); } } void FWObjectDatabase::setPredictableIds() { _setPredictableStrIdsRecursively(this); _updateNonStandardObjectReferencesRecursively(this); } int FWObjectDatabase::generateUniqueId() { return ++id_seed; } void FWObjectDatabase::setFileName(const string &filename) { data_file = filename; } const string &FWObjectDatabase::getFileName() { return data_file; } const string FWObjectDatabase::getFileDir() { char dir_delimiter='/'; #ifdef __MINGW32__ dir_delimiter = '\\'; #endif string::size_type i = data_file.rfind(dir_delimiter); if (i==string::npos || i==0) return ""; else return data_file.substr(0,i); } void FWObjectDatabase::load(const string &f, XMLTools::UpgradePredicate *upgrade, const std::string &template_dir) throw(FWException) { if(f=="") return; xmlDocPtr doc = XMLTools::loadFile(f, FWObjectDatabase::TYPENAME, FWObjectDatabase::DTD_FILE_NAME, upgrade, template_dir); xmlNodePtr root = xmlDocGetRootElement(doc); if(!root || !root->name || strcmp(FROMXMLCAST(root->name), FWObjectDatabase::TYPENAME)!=SAME) { xmlFreeDoc(doc); throw FWException("Data file has invalid structure: "+f); } try { busy = true; destroyChildren(); clearIndex(); fromXML(root); setDirty(false); setFileName(f); } catch (FWException &ex) { busy = false; throw(ex); } xmlFreeDoc(doc); busy = false; } void FWObjectDatabase::saveFile(const string &filename) throw(FWException) { /* need to set flag 'busy' so we ignore read-only status. Some objects * modify themselves in toXML() (e.g. Management) so if they belong to * a read-only library, we can't save them to a file. It should be * safe to ignore read-only flag but save it though. */ busy = true; xmlDocPtr doc = xmlNewDoc(TOXMLCAST("1.0")); xmlNodePtr node = xmlNewNode(NULL, STRTOXMLCAST(getName())); xmlDocSetRootElement(doc, node); xmlNewNs(node, TOXMLCAST("http://www.fwbuilder.org/1.0/"), NULL); toXML(xmlDocGetRootElement(doc)); XMLTools::saveFile(doc, filename, FWObjectDatabase::TYPENAME, FWObjectDatabase::DTD_FILE_NAME); xmlFreeDoc(doc); setDirty(false); busy = false; } void FWObjectDatabase::saveToBuffer(xmlChar **buffer, int *size) throw(FWException) { /* need to set flag 'busy' so we ignore read-only status. Some objects * modify themselves in toXML() (e.g. Management) so if they belong to a * read-only library, we can't save them to a file. It should be safe * to ignore read-only flag but save it though. */ busy = true; xmlDocPtr doc = xmlNewDoc(TOXMLCAST("1.0")); xmlNodePtr node = xmlNewDocNode(doc, NULL, STRTOXMLCAST(getName()), NULL); xmlDocSetRootElement(doc, node); xmlNewNs(node, TOXMLCAST("http://www.fwbuilder.org/1.0/"), NULL); toXML(xmlDocGetRootElement(doc)); XMLTools::dumpToMemory(doc, buffer, size, FWObjectDatabase::TYPENAME, FWObjectDatabase::DTD_FILE_NAME); xmlFreeDoc(doc); //xmlCleanupParser(); // setDirty(false); busy = false; } void FWObjectDatabase::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n = FROMXMLCAST(xmlGetProp(root, TOXMLCAST("lastModified"))); if (n!=NULL) { int i = 0; istringstream str(n); str >> i; lastModified = i; FREEXMLBUFF(n); //xmlFree((void*)n); } } xmlNodePtr FWObjectDatabase::toXML(xmlNodePtr parent) throw(FWException) { FWObject *o; //xmlNewProp(parent, NULL, NULL); xmlNewProp(parent, TOXMLCAST("version") , TOXMLCAST(FWBUILDER_XML_VERSION)); if (lastModified!=0) { ostringstream str; str << lastModified; xmlNewProp(parent, TOXMLCAST("lastModified"), TOXMLCAST(str.str().c_str())); } int rootid = getId(); //NOTUSED xmlAttrPtr pr = xmlNewProp(parent, TOXMLCAST("id") , STRTOXMLCAST(id_dict[rootid])); //xmlAddID(NULL, parent->doc, STRTOXMLCAST(id_dict[rootid]), pr); for(list::const_iterator j=begin(); j!=end(); ++j) { if ((o=(*j))!=NULL) o->toXML(parent); } return parent; } void FWObjectDatabase::setDirty(bool f) { dirty=f; if(!busy && f) lastModified=time(NULL); } void FWObjectDatabase::addToIndex(FWObject* o) { if (o) { o->setRoot( this ); if (o->getId() > -1 ) obj_index[o->getId()] = o; } } void FWObjectDatabase::removeFromIndex(int id) { obj_index.erase(id); } FWObject* FWObjectDatabase::checkIndex(int id) { if (obj_index.count(id)==0) return NULL; return obj_index[id]; } FWObject* FWObjectDatabase::findInIndex(int id) { if (id < 0) return NULL; FWObject *o = checkIndex(id); if (o!=NULL) index_hits++; else { index_misses++; // if index is incomplete or empty, update it automatically using // recursive search to find object o = getById( id , true ); if (o) addToIndex(o); } return o; } void FWObjectDatabase::buildIndex() { clearIndex(); addToIndexRecursive(this); } void FWObjectDatabase::validateIndex() { std::map::iterator it; for (it=obj_index.begin(); it!=obj_index.end(); ++it) { if (it->second->getRoot() != this) { cerr << "Object '" << it->second->getName() << "'" << " ( " << it->second << " type " << it->second->getTypeName() << ")" << " in index of db " << this << " has incorrect db root ptr " << it->second->getRoot() << endl; } } } void FWObjectDatabase::_clearReferenceCounters(FWObject *o) { o->clearRefCounter(); for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) { _clearReferenceCounters(*i); } } void FWObjectDatabase::_fixReferenceCounters(FWObject *o) { if (FWReference::cast(o)!=NULL) { FWObject *obj = findInIndex( FWReference::cast(o)->getPointerId() ); assert(obj); obj->ref(); } for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) { (*i)->ref(); _fixReferenceCounters(*i); } } void FWObjectDatabase::reIndex() { buildIndex(); _clearReferenceCounters(this); _fixReferenceCounters(this); } void FWObjectDatabase::clearIndex() { index_hits = index_misses = 0; obj_index.clear(); } void FWObjectDatabase::getIndexStats(int &index_size, int &hit_counter, int &miss_counter) { index_size = obj_index.size(); hit_counter = index_hits; miss_counter = index_misses; } void FWObjectDatabase::addToIndexRecursive(FWObject *o) { addToIndex(o); for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) addToIndexRecursive(*i); } /* * This method removes all references to child objects of obj, then * removes obj. FWObject::remove moves obj to the "DeletedObjects" * library so we want to preserve subtree structure under obj. There * is no need to delete child objects, but we must remove all * references to them. * * Note: there is no need to search for references pointing at certain * types of objects, such as references and rules/rule sets. This * dramatically speeds up deleting firewalls with large policies and * groups with lots of objects */ void FWObjectDatabase::recursivelyRemoveObjFromTree(FWObject* obj, bool remove_ref) { obj->checkReadOnly(); for (FWObject::iterator i=obj->begin(); i!=obj->end(); ++i) { if (FWReference::cast(*i)!=NULL || RuleSet::cast(*i)!=NULL) continue; recursivelyRemoveObjFromTree( *i , true); } if (remove_ref) removeAllReferences(obj); else removeAllInstances(obj); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/TagService.h0000644000175000017500000000360011733011756025215 0ustar sylvestresylvestre /* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GEN_TAGSERVICE_HH_FLAG__ #define __GEN_TAGSERVICE_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/Service.h" namespace libfwbuilder { /** * This is base class for all service objects and other objects that * can be children of RuleElementSrv (service rule element). It is * never used on it's own, only it's subclasses are used. * * TODO: we might need to derive ServiceGroup from Service, but this * requires lot more testing */ class TagService : public Service { private: public: std::string getCode() const; void setCode(const std::string &p); DECLARE_FWOBJECT_SUBTYPE(TagService); DECLARE_DISPATCH_METHODS(TagService); TagService(); ~TagService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; //virtual FWReference* createRef(); //bool isAny() const; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPv6.h0000644000175000017500000000417011733011756023750 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPV6_HH_FLAG__ #define __IPV6_HH_FLAG__ #include #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class IPv6 : public Address { public: IPv6(); virtual ~IPv6(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual unsigned int dimension() const { return 1; } DECLARE_FWOBJECT_SUBTYPE(IPv6); DECLARE_DISPATCH_METHODS(IPv6); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool hasInetAddress() const { return true; } /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool) const { return 1; } virtual const Address* getAddressObject() const { return this; } virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual void setAddressNetmask(const std::string& s); virtual void dump(std::ostream &f,bool recursive,bool brief,int offset=0) const; virtual bool isPrimaryObject() const; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/dns.h0000644000175000017500000000514611733011756023754 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DNS_HH_FLAG__ #define __DNS_HH_FLAG__ #include "fwbuilder/libfwbuilder-config.h" #ifndef _WIN32 /* do not change the order of these headers! resolv.h should be included * before netdb.h, otherwise there seems to be a problem with macro __P * which is defined in cdfes.h as '#define __P(args) args __THROW' and * gcc 3.3 does not like this */ # include # include # include # include # include # include #else # ifndef RES_TIMEOUT # define RES_TIMEOUT 1 # endif #endif // _WIN32 #include "fwbuilder/InetAddr.h" #include "fwbuilder/FWException.h" #include "fwbuilder/BackgroundOp.h" #include "fwbuilder/ThreadTools.h" #include #include #include #ifndef RES_DFLRETRY # define RES_DFLRETRY 1 #endif namespace libfwbuilder { class HostEnt { public: std::string name ; std::set aliases ; }; /** * This is abstract class */ class DNS { public: DNS() {} /** * Should be called exactly once before this class * ever used. */ static void init(); /** * Finds IP adddresses of the host with given host name. * This operation does not run in backgound. * Returned list is sorted. */ static std::list getHostByName(const std::string &name, int type=AF_INET) throw(FWException); /** * Find all host names of host with given IP. * This operation does not run in backgound. */ static HostEnt getHostByAddr(const InetAddr &addr, int type=AF_INET) throw(FWException); private: static Mutex *gethostbyname_mutex; static Mutex *gethostbyaddr_mutex; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/UDPService.cpp0000644000175000017500000000240411733011756025466 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *UDPService::TYPENAME={"UDPService"}; UDPService::UDPService() {} UDPService::~UDPService() {} string UDPService::getProtocolName() const { return "udp"; } int UDPService::getProtocolNumber() const { return 17; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/RuleSet.cpp0000644000175000017500000002241411733011756025103 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/XMLTools.h" #include using namespace std; using namespace libfwbuilder; const char *RuleSet::TYPENAME={"Ruleset"}; RuleSet::RuleSet() { setName("RuleSet"); ipv4 = false; ipv6 = false; top = false; } void RuleSet::init(FWObjectDatabase *root) { FWObject *opt = getFirstByType(RuleSetOptions::TYPENAME); if (opt == NULL) add(root->createRuleSetOptions()); } RuleSet::~RuleSet() {} void RuleSet::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; // Both ipv4_rule_set and ipv6_rule_set attributes can be set to // true, which means this is "dual" rule set When both are false, // this is ipv4-only rule set (for backwards compatibility and to // avoid having to increment DTD version number) n=FROMXMLCAST(xmlGetProp(root, TOXMLCAST("ipv4_rule_set"))); if (n!=NULL) { ipv4 = (string(n)=="True" || string(n)=="true"); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root, TOXMLCAST("ipv6_rule_set"))); if (n!=NULL) { ipv6 = (string(n)=="True" || string(n)=="true"); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("top_rule_set"))); if (n!=NULL) { top = (string(n)=="True" || string(n)=="true"); FREEXMLBUFF(n); } } xmlNodePtr RuleSet::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("ipv4_rule_set"), TOXMLCAST(((ipv4) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("ipv6_rule_set"), TOXMLCAST(((ipv6) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("top_rule_set"), TOXMLCAST(((top) ? "True" : "False"))); // First all rules, skip options for(list::const_iterator j=begin(); j!=end(); ++j) { if (FWOptions::cast(*j) == NULL) (*j)->toXML(me); } FWObject *o; if ( (o=getFirstByType( RuleSetOptions::TYPENAME ))!=NULL ) o->toXML(me); return me; } FWOptions* RuleSet::getOptionsObject() { return FWOptions::cast(getFirstByType(RuleSetOptions::TYPENAME)); } FWObject& RuleSet::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { const RuleSet *other = RuleSet::constcast(o); FWObject::shallowDuplicate(o, preserve_id); ipv4 = other->ipv4; ipv6 = other->ipv6; top = other->top; return *this; } bool RuleSet::cmp(const FWObject *obj, bool recursive) throw(FWException) { const RuleSet *other = RuleSet::constcast(obj); if (other == NULL) return false; if (ipv4 != other->ipv4 || ipv6 != other->ipv6 || top != other->top) return false; return FWObject::cmp(obj, recursive); } /** * Add new rule on top of the rule set. If hidden_rule arg is true, * force new rule position number ot be negative. Make sure it grows * backwards if there are other rules with negative position * numbers. If the topmost rule has position > 0 for whatever reason, * set hidden rule's position to -1 rather than 0. * * Hidden rules are those added by compilers automatically, such as * automatic rule to permit ssh to the firewall or rules to permit * vrrp and other protocols. These rules are constructed by compilers * rather than defined by the user in the GUI. */ Rule* RuleSet::insertRuleAtTop(bool hidden_rule) { Rule *r = createRule(); r->setHidden(hidden_rule); if (hidden_rule) r->setPosition(-1); else r->setPosition(0); insert(begin(), r); _adopt(r); renumberRules(); return(r); } Rule* RuleSet::insertRuleBefore(int rule_n) { Rule *old_rule = getRuleByNum(rule_n); Rule *r = createRule(); if (old_rule==NULL) add(r); else insert_before(old_rule, r); renumberRules(); return(r); } Rule* RuleSet::appendRuleAtBottom(bool hidden_rule) { Rule *r = createRule(); r->setHidden(hidden_rule); int last_rule_position; Rule *last_rule = Rule::cast(back()); if (last_rule != NULL) { last_rule_position = last_rule->getPosition() + 1000; } else last_rule_position = 1000; if (hidden_rule) r->setPosition(last_rule_position); add(r); // FWObject::add adds to the end of the list renumberRules(); return(r); } Rule* RuleSet::appendRuleAfter(int rule_n) { Rule *old_rule = getRuleByNum(rule_n); Rule *r = createRule(); if (old_rule==NULL) add(r); else insert_after(old_rule,r); renumberRules(); return(r); } bool RuleSet::deleteRule(int rule_n) { return deleteRule( getRuleByNum(rule_n) ); } bool RuleSet::deleteRule(Rule *r) { if (r!=NULL) { remove(r, true); // and delete the rule if ref counter == 0 renumberRules(); return(true); } return(false); } bool RuleSet::moveRuleUp(int rule_n) { if (rule_n==0) return(false); FWObject* o = getRuleByNum( rule_n ); FWObject* prev = getRuleByNum( rule_n-1 ); swapObjects(prev,o); renumberRules(); return(true); } bool RuleSet::moveRuleDown(int rule_n) { if (rule_n > (getRuleSetSize() - 1) ) return(false); FWObject* o = getRuleByNum( rule_n ); FWObject* next = getRuleByNum( rule_n+1 ); swapObjects(o,next); renumberRules(); return(true); } bool RuleSet::disableRule(int rule_n) { FWObject* o =getRuleByNum( rule_n ); if (o) { (Rule::cast(o))->disable(); return true; } return false; } bool RuleSet::enableRule(int rule_n) { FWObject* o =getRuleByNum( rule_n ); if (o) { (Rule::cast(o))->enable(); return true; } return false; } bool RuleSet::isRuleDisabled(int rule_n) { FWObject* o =getRuleByNum( rule_n ); if (o) return((Rule::cast(o))->isDisabled()); return false; } /* * Rule number src_rule_n moves right above rule number dst_rule_n */ bool RuleSet::moveRule(int src_rule_n, int dst_rule_n) { FWObject* src =getRuleByNum( src_rule_n ); FWObject* dst =getRuleByNum( dst_rule_n ); if (src!=NULL && dst!=NULL && src!=dst ) { FWObject *o; list::iterator m, m1, m2; for (m=begin(); m!=end(); ++m) { if ( (o=(*m))!=NULL ) { if ( o==src ) m1=m; if ( o==dst ) m2=m; } } if ( (*m1)!=NULL && (*m2)!=NULL ) { erase(m1); insert(m2,src); } renumberRules(); return(true); } return(false); } void RuleSet::renumberRules() { if (size() == 0) return; list::iterator m, it; int rn; // first pass: find first not hidden rule; it will become rule #0 // Even though RuleSet object an only have Rule objects as // children, I am checking for the child type everywhere in case // we ever add another type of child. it = begin(); for (; it!=end(); ++it) { Rule *rule = Rule::cast(*it); if (rule && !rule->isHidden()) break; } list::reverse_iterator rev_it(it); list::reverse_iterator rev_end(begin()); // rev_it points to the last hidden rule rn = 0; for (; it != end(); it++) { Rule *rule = Rule::cast(*it); // there can be hidden rules at the bottom of policy // Just do not change their position numbers. if (rule && !rule->isHidden()) { rule->setPosition(rn); rn++; } } rn = -1; for (; rev_it != rev_end; rev_it++) { Rule *rule = Rule::cast(*rev_it); if (rule && rule->isHidden()) { rule->setPosition(rn); rn--; } } } Rule* RuleSet::getRuleByNum(int n) { for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o; if ( (o=(*m))!=NULL ) { Rule *r = Rule::cast(o); if (r && r->getPosition()==n) return r; } } return NULL; } int RuleSet::getRuleSetSize() { return getChildrenCount() - 1; } void RuleSet::assignUniqueRuleIds() { for (FWObject::iterator it=begin(); it!=end(); ++it) { Rule *r = Rule::cast(*it); if (r != NULL && r->getUniqueId().empty()) r->setUniqueId(FWObjectDatabase::getStringId((*it)->getId()) ); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectReference.h0000644000175000017500000000250511733011756026446 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOBJECTREF_HH_FLAG__ #define __FWOBJECTREF_HH_FLAG__ #include "fwbuilder/FWReference.h" namespace libfwbuilder { class ObjectGroup; /** * This class represents object reference. */ class FWObjectReference : public FWReference { public: DECLARE_FWOBJECT_SUBTYPE(FWObjectReference); DECLARE_DISPATCH_METHODS(FWObjectReference); FWObjectReference(); void setPointer(FWObject *o); void setPointer(ObjectGroup *o); }; } #endif // _FWOBJECT_HH fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ObjectMatcher.h0000644000175000017500000000764611733011756025711 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTMATCHER_HH_FLAG__ #define __OBJECTMATCHER_HH_FLAG__ #include #include #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Dispatch.h" namespace libfwbuilder { class ObjectMatcher : public Dispatch { public: typedef enum {EXACT, PARTIAL} address_range_match; private: bool recognize_broadcasts; bool recognize_multicasts; bool ipv6; bool match_subnets; address_range_match address_range_match_mode; bool checkComplexMatchForSingleAddress(const InetAddr *addr1, FWObject *obj2); int matchRHS(const InetAddr *addr1, Address *obj2); int matchInetAddrRHS(const InetAddr *addr1, const InetAddr *rhs_obj_addr); int matchSubnetRHS(const InetAddr *addr1, const InetAddr *rhs_obj_addr, const InetAddr *rhs_obj_netm); public: ObjectMatcher() : Dispatch() { recognize_broadcasts = false; recognize_multicasts = false; ipv6 = false; match_subnets = false; address_range_match_mode = PARTIAL; } virtual ~ObjectMatcher() {} void setMatchSubnets(bool f) { match_subnets = f; } void setAddressRangeMatchMode(address_range_match f) { address_range_match_mode = f; } void setRecognizeBroadcasts(bool f) { recognize_broadcasts = f; } void setRecognizeMulticasts(bool f) { recognize_multicasts = f; } void setIPV6(bool f) { ipv6 = f; } /** * check if address obj1 matches any of the addresses of obj2. Obj1 * has to be a single address. */ bool checkComplexMatchForSingleAddress(Address *obj1, FWObject *obj2); /** * check if any of the addresses of obj2 belongs to the subnet of obj1 */ bool checkComplexMatchForSubnet(Address *obj1, FWObject *obj2); /** * This method returns true if one of the following conditions is met: * * 1. obj1 is the same as obj2 (compares ID of both objects), or * 2. obj1 is a child of obj2 on any depth, or * 3. address of obj1 matches that of any obj2's interfaces, or * 4. address of obj1 is a broadcast address of one of * the interfaces of obj2 * 5. address of obj1 is a broadcast (255.255.255.255) */ bool complexMatch(Address *obj1, Address *obj2); virtual void* dispatch(Interface*, void*); virtual void* dispatch(Network*, void*); virtual void* dispatch(NetworkIPv6*, void*); virtual void* dispatch(IPv4*, void*); virtual void* dispatch(IPv6*, void*); virtual void* dispatch(Host*, void*); virtual void* dispatch(Firewall*, void*); virtual void* dispatch(Cluster*, void*); virtual void* dispatch(AddressRange*, void*); virtual void* dispatch(physAddress*, void*); virtual void* dispatch(MultiAddressRunTime*, void*); }; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/UserService.h0000644000175000017500000000343211733011756025423 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __USERSERVICE_HH_FLAG__ #define __USERSERVICE_HH_FLAG__ #include "fwbuilder/Service.h" #include namespace libfwbuilder { class UserService : public Service { private: std::string userid; public: UserService(); virtual ~UserService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(UserService); DECLARE_DISPATCH_METHODS(UserService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; const std::string& getUserId() const { return userid; } void setUserId(const std::string& uid) { userid = uid; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/InterfaceData.h0000644000175000017500000000341711733011756025661 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INTERFACE_DATA_HH_ #define __INTERFACE_DATA_HH_ #include "fwbuilder/Interface.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/Inet6AddrMask.h" #include namespace libfwbuilder { class InterfaceData { public: std::string id; std::string name; std::list addr_mask; bool ext; int snmp_type; int ostatus; int securityLevel; bool isDyn; bool isUnnumbered; bool isBridgePort; std::string mac_addr; std::string label; std::string networkZone; std::string interface_type; int vlan_id; std::list subinterfaces; InterfaceData(); InterfaceData(const InterfaceData& other); InterfaceData(const libfwbuilder::Interface &iface); virtual ~InterfaceData(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/NetworkIPv6.h0000644000175000017500000000431411733011756025322 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NETWORKIPV6_HH_FLAG__ #define __NETWORKIPV6_HH_FLAG__ #include "fwbuilder/Address.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class NetworkIPv6 : public Address { public: NetworkIPv6(); NetworkIPv6(NetworkIPv6 &); NetworkIPv6(const std::string &); virtual ~NetworkIPv6(); bool isValidRoutingNet() const; virtual void fromXML (xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr xml_parent_node) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(NetworkIPv6); DECLARE_DISPATCH_METHODS(NetworkIPv6); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool hasInetAddress() const { return true; } /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool) const { return 1; } virtual const Address* getAddressObject() const { return this; } virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual void setAddressNetmask(const std::string& s); virtual bool isPrimaryObject() const { return true; } }; } #endif // __NETWORK_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ICMP6Service.h0000644000175000017500000000256211733011756025326 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ICMP6SERVICE_HH_FLAG__ #define __ICMP6SERVICE_HH_FLAG__ #include "fwbuilder/ICMPService.h" namespace libfwbuilder { class ICMP6Service : public ICMPService { private: public: ICMP6Service(); virtual ~ICMP6Service(); DECLARE_FWOBJECT_SUBTYPE(ICMP6Service); DECLARE_DISPATCH_METHODS(ICMP6Service); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; virtual bool isV4Only() { return false; } virtual bool isV6Only() { return true; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/fwbuilder.pro0000644000175000017500000000630411733011756025521 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib CONFIG += staticlib INCLUDEPATH += "../../../../" # SOURCES = InetAddr.cpp \ InetAddrMask.cpp \ Inet6AddrMask.cpp \ IPRoute.cpp \ Address.cpp \ AddressRange.cpp \ BackgroundOp.cpp \ Constants.cpp \ CustomService.cpp \ dns.cpp \ Firewall.cpp \ Cluster.cpp \ ClusterGroup.cpp \ FailoverClusterGroup.cpp \ StateSyncClusterGroup.cpp \ FWException.cpp \ FWIntervalReference.cpp \ FWObject.cpp \ FWObjectDatabase.cpp \ FWObjectDatabase_create_object.cpp \ FWObjectDatabase_tree_ops.cpp \ FWObjectDatabase_search.cpp \ FWObjectReference.cpp \ FWOptions.cpp \ FWReference.cpp \ FWServiceReference.cpp \ Group.cpp \ Host.cpp \ ICMPService.cpp \ ICMP6Service.cpp \ Interface.cpp \ InterfaceData.cpp \ Interval.cpp \ IntervalGroup.cpp \ IPService.cpp \ IPv4.cpp \ IPv6.cpp \ Library.cpp \ Logger.cpp \ Management.cpp \ MultiAddress.cpp \ NAT.cpp \ Network.cpp \ NetworkIPv6.cpp \ AttachedNetworks.cpp \ ObjectGroup.cpp \ DynamicGroup.cpp \ physAddress.cpp \ DNSName.cpp\ AddressTable.cpp\ Policy.cpp \ Resources.cpp \ Routing.cpp \ Rule.cpp \ RuleElement.cpp \ RuleSet.cpp \ SecuwallMgmtFile.cpp \ Service.cpp \ ServiceGroup.cpp \ snmp.cpp \ TCPService.cpp \ ThreadTools.cpp \ Tools.cpp \ TCPUDPService.cpp \ UDPService.cpp \ UserService.cpp \ TagService.cpp \ XMLTools.cpp \ ObjectMatcher.cpp \ ObjectMirror.cpp \ inet_net_ntop.c \ inet_net_pton.c \ uint128.cpp HEADERS = inet_net.h \ uint128.h \ InetAddr.h \ InetAddrMask.h \ Inet6AddrMask.h \ Dispatch.h \ IPRoute.h \ Address.h \ AddressRange.h \ BackgroundOp.h \ Constants.h \ CustomService.h \ dns.h \ Firewall.h \ Cluster.h \ ClusterGroup.h \ FailoverClusterGroup.h \ StateSyncClusterGroup.h \ FWException.h \ FWIntervalReference.h \ FWObjectDatabase.h \ FWObject.h \ FWObjectReference.h \ FWOptions.h \ FWReference.h \ FWServiceReference.h \ Group.h \ Host.h \ ICMPService.h \ ICMP6Service.h \ Interface.h \ InterfaceData.h \ IntervalGroup.h \ Interval.h \ IPService.h \ IPv4.h \ IPv6.h \ libfwbuilder-config.h \ libfwbuilder-version.h \ Library.h \ Logger.h \ Management.h \ MultiAddress.h \ NAT.h \ Network.h \ NetworkIPv6.h \ AttachedNetworks.h \ ObjectGroup.h \ DynamicGroup.h \ physAddress.h \ DNSName.h\ AddressTable.h\ Policy.h \ Pool.h \ Resources.h \ Routing.h \ RuleElement.h \ Rule.h \ RuleSet.h \ SecuwallMgmtFile.h \ ServiceGroup.h \ Service.h \ snmp.h \ SyncQueue.h \ TCPService.h \ ThreadTools.h \ Tools.h \ TCPUDPService.h \ UDPService.h \ UserService.h \ TagService.h \ ObjectMatcher.h \ ObjectMirror.h \ XMLTools.h TARGET = fwbuilder # no need to install headers #headers.files = $$HEADERS #headers.path = "$$prefix/include/fwb-4/fwbuilder" #INSTALLS += headers # and no need to install .a library INSTALLS -= target fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ServiceGroup.h0000644000175000017500000000322711733011756025603 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SERVICEGROUP_HH_FLAG__ #define __SERVICEGROUP_HH_FLAG__ #include "fwbuilder/Group.h" namespace libfwbuilder { class ServiceGroup : public Group { public: ServiceGroup(); virtual ~ServiceGroup(); DECLARE_FWOBJECT_SUBTYPE(ServiceGroup); DECLARE_DISPATCH_METHODS(ServiceGroup); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual FWReference* createRef(); /** * get the list of object type names that can be inserted into * given object group. This reflects definition of the group XML * element in DTD. */ virtual void getAllowedTypesOfChildren(std::list &types_list); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectDatabase.h0000644000175000017500000004754711733011756026273 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOBJECTDATABASE_HH_FLAG__ #define __FWOBJECTDATABASE_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/FWException.h" #include "fwbuilder/ThreadTools.h" #include "fwbuilder/XMLTools.h" #ifdef _WIN32 # include # include #else # include # include #endif #include // for time_t #define DECLARE_CREATE_OBJ_METHOD(classname) \ FWObject* create_##classname(int id=-1); #define DECLARE_CREATE_OBJ_CLASS_METHOD(classname) \ classname * create##classname(int id=-1); namespace libfwbuilder { class Group; // forward declarations for specialized create() methods class AddressRange; class AddressTable; class AttachedNetworks; class Cluster; class StateSyncClusterGroup; class FailoverClusterGroup; class ClusterGroupOptions; class CustomService; class DNSName; class DynamicGroup; class FWBDManagement; class FWIntervalReference; class FWObjectReference; class FWServiceReference; class Firewall; class FirewallOptions; class Host; class HostOptions; class ICMP6Service; class ICMPService; class IPService; class IPv4; class IPv6; class Interface; class InterfaceOptions; class Interval; class IntervalGroup; class Library; class Management; class NAT; class NATRule; class NATRuleOptions; class Network; class NetworkIPv6; class ObjectGroup; class Policy; class PolicyInstallScript; class PolicyRule; class PolicyRuleOptions; class Routing; class RoutingRule; class RoutingRuleOptions; class RuleElementDst; class RuleElementInterval; class RuleElementItf; class RuleElementItfInb; class RuleElementItfOutb; class RuleElementODst; class RuleElementOSrc; class RuleElementOSrv; class RuleElementRDst; class RuleElementRGtw; class RuleElementRItf; class RuleElementSrc; class RuleElementSrv; class RuleElementTDst; class RuleElementTSrc; class RuleElementTSrv; class RuleSetOptions; class SNMPManagement; class ServiceGroup; class TCPService; class TagService; class UDPService; class UserService; class physAddress; DECLARE_CREATE_OBJ_METHOD(AddressRange); DECLARE_CREATE_OBJ_METHOD(AddressTable); DECLARE_CREATE_OBJ_METHOD(AttachedNetworks); DECLARE_CREATE_OBJ_METHOD(Cluster); DECLARE_CREATE_OBJ_METHOD(StateSyncClusterGroup); DECLARE_CREATE_OBJ_METHOD(FailoverClusterGroup); DECLARE_CREATE_OBJ_METHOD(ClusterGroupOptions); DECLARE_CREATE_OBJ_METHOD(CustomService); DECLARE_CREATE_OBJ_METHOD(DNSName); DECLARE_CREATE_OBJ_METHOD(DynamicGroup); DECLARE_CREATE_OBJ_METHOD(FWBDManagement); DECLARE_CREATE_OBJ_METHOD(FWIntervalReference); DECLARE_CREATE_OBJ_METHOD(FWObjectReference); DECLARE_CREATE_OBJ_METHOD(FWServiceReference); DECLARE_CREATE_OBJ_METHOD(Firewall); DECLARE_CREATE_OBJ_METHOD(FirewallOptions); DECLARE_CREATE_OBJ_METHOD(Host); DECLARE_CREATE_OBJ_METHOD(HostOptions); DECLARE_CREATE_OBJ_METHOD(ICMP6Service); DECLARE_CREATE_OBJ_METHOD(ICMPService); DECLARE_CREATE_OBJ_METHOD(IPService); DECLARE_CREATE_OBJ_METHOD(IPv4); DECLARE_CREATE_OBJ_METHOD(IPv6); DECLARE_CREATE_OBJ_METHOD(Interface); DECLARE_CREATE_OBJ_METHOD(InterfaceOptions); DECLARE_CREATE_OBJ_METHOD(Interval); DECLARE_CREATE_OBJ_METHOD(IntervalGroup); DECLARE_CREATE_OBJ_METHOD(Library); DECLARE_CREATE_OBJ_METHOD(Management); DECLARE_CREATE_OBJ_METHOD(NAT); DECLARE_CREATE_OBJ_METHOD(NATRule); DECLARE_CREATE_OBJ_METHOD(NATRuleOptions); DECLARE_CREATE_OBJ_METHOD(Network); DECLARE_CREATE_OBJ_METHOD(NetworkIPv6); DECLARE_CREATE_OBJ_METHOD(ObjectGroup); DECLARE_CREATE_OBJ_METHOD(Policy); DECLARE_CREATE_OBJ_METHOD(PolicyInstallScript); DECLARE_CREATE_OBJ_METHOD(PolicyRule); DECLARE_CREATE_OBJ_METHOD(PolicyRuleOptions); DECLARE_CREATE_OBJ_METHOD(Routing); DECLARE_CREATE_OBJ_METHOD(RoutingRule); DECLARE_CREATE_OBJ_METHOD(RoutingRuleOptions); DECLARE_CREATE_OBJ_METHOD(RuleElementDst); DECLARE_CREATE_OBJ_METHOD(RuleElementInterval); DECLARE_CREATE_OBJ_METHOD(RuleElementItf); DECLARE_CREATE_OBJ_METHOD(RuleElementItfInb); DECLARE_CREATE_OBJ_METHOD(RuleElementItfOutb); DECLARE_CREATE_OBJ_METHOD(RuleElementODst); DECLARE_CREATE_OBJ_METHOD(RuleElementOSrc); DECLARE_CREATE_OBJ_METHOD(RuleElementOSrv); DECLARE_CREATE_OBJ_METHOD(RuleElementRDst); DECLARE_CREATE_OBJ_METHOD(RuleElementRGtw); DECLARE_CREATE_OBJ_METHOD(RuleElementRItf); DECLARE_CREATE_OBJ_METHOD(RuleElementSrc); DECLARE_CREATE_OBJ_METHOD(RuleElementSrv); DECLARE_CREATE_OBJ_METHOD(RuleElementTDst); DECLARE_CREATE_OBJ_METHOD(RuleElementTSrc); DECLARE_CREATE_OBJ_METHOD(RuleElementTSrv); DECLARE_CREATE_OBJ_METHOD(RuleSetOptions); DECLARE_CREATE_OBJ_METHOD(SNMPManagement); DECLARE_CREATE_OBJ_METHOD(ServiceGroup); DECLARE_CREATE_OBJ_METHOD(TCPService); DECLARE_CREATE_OBJ_METHOD(TagService); DECLARE_CREATE_OBJ_METHOD(UDPService); DECLARE_CREATE_OBJ_METHOD(UserService); DECLARE_CREATE_OBJ_METHOD(physAddress); DECLARE_CREATE_OBJ_METHOD(Group); class IDcounter { protected: long cntr; public: IDcounter(); long get() { ++cntr; return cntr; } }; class FWObjectDatabase; typedef FWObject*(*create_function_ptr)(int); /** * Database of objects. */ class FWObjectDatabase : public FWObject { private: void _clearReferenceCounters(FWObject *o); void _fixReferenceCounters(FWObject *o); bool _isInIgnoreList(FWObject *o); /* bool _findWhereUsed( */ /* libfwbuilder::FWObject *o, */ /* libfwbuilder::FWObject *p, */ /* std::set &resset); */ bool _findWhereObjectIsUsed(libfwbuilder::FWObject *o, libfwbuilder::FWObject *p, std::set &resset, int search_id); void _findObjectsInGroup( libfwbuilder::Group *g, std::set &res); Firewall* _findFirewallByNameRecursive( FWObject* db, const std::string &name) throw(FWException); FWObject* _recursively_copy_subtree(FWObject *target, FWObject *source, std::map &id_map, const std::string &dedup_attribute); void _copy_foreign_obj_aux(FWObject *target, FWObject *source, std::map &id_map, const std::string &dedup_attribute); void _setPredictableStrIdsRecursively(FWObject *obj); void _updateNonStandardObjectReferencesRecursively(FWObject *obj); protected: static const std::string DTD_FILE_NAME ; time_t lastModified; int index_hits; int index_misses; std::string data_file; std::map obj_index; int searchId; int predictable_id_tracker; bool ignore_read_only; void init_create_methods_table(); void init_id_dict(); public: DECLARE_FWOBJECT_SUBTYPE(FWObjectDatabase); DECLARE_DISPATCH_METHODS(FWObjectDatabase); enum {ROOT_ID = 0, ANY_ADDRESS_ID = 1, ANY_SERVICE_ID = 2, ANY_INTERVAL_ID = 3, STANDARD_LIB_ID = 4, USER_LIB_ID = 5, TEMPLATE_LIB_ID = 6, DELETED_OBJECTS_ID = 7 } standard_ids; static void registerObjectType(const std::string &type_name, create_function_ptr create_function); /** * this constructor initializes singleton db */ FWObjectDatabase(); /** * this constructor makes a copy of entire tree and does not * intitialize db */ FWObjectDatabase(FWObjectDatabase& d); virtual ~FWObjectDatabase(); // --- methods dealing with object index void addToIndexRecursive(FWObject *o); /** * add an object to the index */ void addToIndex(FWObject* obj); /** * remove an object from the index */ void removeFromIndex(int id); /** * check if an object is present in the index using its ID */ FWObject* checkIndex(int id); /** * find an object in the index using its ID */ FWObject* findInIndex(int id); /** * build index */ void buildIndex(); /** * clear the index */ void clearIndex(); /** * this is just like buildIndex, except it also fixes reference * counters in objects. Call this method after loading database * from XML file. This method uses private _fixReferenceCounters */ void reIndex(); /** * return index usage statistics */ void getIndexStats(int &index_size, int &hit_counter, int &miss_counter); /** * this function is intended for debugging. */ void validateIndex(); /** * Some operations, such as object tree merging, should ignore * read-only flag on individual objects. */ bool getIgnoreReadOnlyFlag() { return ignore_read_only; } void setIgnoreReadOnlyFlag(bool f) { ignore_read_only = f; } // --- XML import/export --- virtual void fromXML(xmlNodePtr xml_parent_node) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); time_t getTimeLastModified() { return lastModified; } void resetTimeLastModified(time_t t) { lastModified=t; } // --- Load/Save --- virtual void saveFile(const std::string &filename) throw(FWException); virtual void saveToBuffer(xmlChar **buffer,int *size) throw(FWException); virtual void load( const std::string &filename, XMLTools::UpgradePredicate *upgrade, const std::string &template_dir) throw(FWException); virtual void setDirty(bool f); Firewall* findFirewallByName(const std::string &name) throw(FWException); FWObjectDatabase* exportSubtree( FWObject *lib ); FWObjectDatabase* exportSubtree( const std::list &libs ); /* void findWhereUsed( */ /* libfwbuilder::FWObject *o, */ /* libfwbuilder::FWObject *p, */ /* std::set &resset); */ /** * Find reference to object in the subtree rooted at

. Do * not search for indirect usage, i.e. when an object has a * reference to a group that in turn has reference to . Search * also includes references to objects used in rule actions Tag * and Branch. */ void findWhereObjectIsUsed( libfwbuilder::FWObject *o, libfwbuilder::FWObject *p, std::set &resset); /** * find all objects used by the group 'gr'. Resolve references * recursively (that is, if a group member is another group, this * method descends into it and scans all objects that group uses) */ void findObjectsInGroup( libfwbuilder::Group *g, std::set &resset); /** * We ignore read-only flag on individual objects when whole object * tree is duplicated */ virtual FWObject& duplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); void recursivelyRemoveObjFromTree(FWObject* obj, bool remove_ref=false); /** * Copy object and all its children, recursively, into * object tree starting from . is a parent of the copy * of that will be created. * Store ID mapping in (as a dictionary old_id -> new_id) */ FWObject* recursivelyCopySubtree(FWObject *target, FWObject *source, std::map &id_map); /** * Create groups to reproduce path inside given library. If groups * with required names exist, do nothing. Return pointer to the * last object created to copy the path. Do not copy object. * This means returned object can be a parent for the copy of . */ FWObject* reproduceRelativePath(FWObject *lib, const FWObject *source); /** * fix references in children of obj according to the map_ids which * maps old IDs to the new ones. Return the number of fixed references. */ int fixReferences(FWObject *obj, const std::map &map_ids); /** * this predicate is used to hand control over to user in case * when a conflict is detected while merging trees. By default the * old object is overwritten with new one. */ class ConflictResolutionPredicate { public: virtual ~ConflictResolutionPredicate() {} virtual bool askUser(FWObject*,FWObject*) { return true; } }; void merge(FWObjectDatabase *ndb, ConflictResolutionPredicate *mp=NULL); void findDuplicateIds(FWObjectDatabase *ndb, std::set &dupids); void setFileName(const std::string &filename); const std::string& getFileName (); const std::string getFileDir (); static int generateUniqueId(); static int registerStringId(const std::string &s_id); static int getIntId(const std::string &s_id); static std::string getStringId(int i_id); /** * generate predictable ID based on given prefix by adding sequential * suffix to it. */ std::string getPredictableId(const std::string &prefix); /** * This method replaces random string object ids with * predictable ones. This does not change their int IDs, only * string IDs that appear in the XML file when objects are * saved change. * * Used in unit testing to create .fwb files that can be * compared. */ virtual void setPredictableIds(); /** * This is the main "Create" method: * it creates instance of FWObject of given type * * if parameter 'create_with_root' is true, this method will create * objects using constructor that uses pointer to this as a parameter, * otherwise empty constructor is used */ FWObject *create(const std::string &type, int id=-1, bool init=true); /** * Creates instance of FWObject using its XML representation */ virtual FWObject *createFromXML(xmlNodePtr data); /** * Specialized createClass() methods: class name is part of the method * name, e.g. createLibrary(), also these return a pointer to the * corresponding class. Note that each macro declares two methods: * Class* createClass(int,bool) and FWObject* createFWObjectClass(int,bool) */ DECLARE_CREATE_OBJ_CLASS_METHOD(AddressRange); DECLARE_CREATE_OBJ_CLASS_METHOD(AddressTable); DECLARE_CREATE_OBJ_CLASS_METHOD(AttachedNetworks); DECLARE_CREATE_OBJ_CLASS_METHOD(Cluster); DECLARE_CREATE_OBJ_CLASS_METHOD(StateSyncClusterGroup); DECLARE_CREATE_OBJ_CLASS_METHOD(FailoverClusterGroup); DECLARE_CREATE_OBJ_CLASS_METHOD(ClusterGroupOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(CustomService); DECLARE_CREATE_OBJ_CLASS_METHOD(DNSName); DECLARE_CREATE_OBJ_CLASS_METHOD(DynamicGroup); DECLARE_CREATE_OBJ_CLASS_METHOD(FWBDManagement); DECLARE_CREATE_OBJ_CLASS_METHOD(FWIntervalReference); DECLARE_CREATE_OBJ_CLASS_METHOD(FWObjectReference); DECLARE_CREATE_OBJ_CLASS_METHOD(FWServiceReference); DECLARE_CREATE_OBJ_CLASS_METHOD(Firewall); DECLARE_CREATE_OBJ_CLASS_METHOD(FirewallOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(Host); DECLARE_CREATE_OBJ_CLASS_METHOD(HostOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(ICMP6Service); DECLARE_CREATE_OBJ_CLASS_METHOD(ICMPService); DECLARE_CREATE_OBJ_CLASS_METHOD(IPService); DECLARE_CREATE_OBJ_CLASS_METHOD(IPv4); DECLARE_CREATE_OBJ_CLASS_METHOD(IPv6); DECLARE_CREATE_OBJ_CLASS_METHOD(Interface); DECLARE_CREATE_OBJ_CLASS_METHOD(InterfaceOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(Interval); DECLARE_CREATE_OBJ_CLASS_METHOD(IntervalGroup); DECLARE_CREATE_OBJ_CLASS_METHOD(Library); DECLARE_CREATE_OBJ_CLASS_METHOD(Management); DECLARE_CREATE_OBJ_CLASS_METHOD(NAT); DECLARE_CREATE_OBJ_CLASS_METHOD(NATRule); DECLARE_CREATE_OBJ_CLASS_METHOD(NATRuleOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(Network); DECLARE_CREATE_OBJ_CLASS_METHOD(NetworkIPv6); DECLARE_CREATE_OBJ_CLASS_METHOD(ObjectGroup); DECLARE_CREATE_OBJ_CLASS_METHOD(Policy); DECLARE_CREATE_OBJ_CLASS_METHOD(PolicyInstallScript); DECLARE_CREATE_OBJ_CLASS_METHOD(PolicyRule); DECLARE_CREATE_OBJ_CLASS_METHOD(PolicyRuleOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(Routing); DECLARE_CREATE_OBJ_CLASS_METHOD(RoutingRule); DECLARE_CREATE_OBJ_CLASS_METHOD(RoutingRuleOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementDst); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementInterval); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementItf); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementItfInb); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementItfOutb); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementODst); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementOSrc); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementOSrv); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementRDst); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementRGtw); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementRItf); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementSrc); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementSrv); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementTDst); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementTSrc); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementTSrv); DECLARE_CREATE_OBJ_CLASS_METHOD(RuleSetOptions); DECLARE_CREATE_OBJ_CLASS_METHOD(SNMPManagement); DECLARE_CREATE_OBJ_CLASS_METHOD(ServiceGroup); DECLARE_CREATE_OBJ_CLASS_METHOD(TCPService); DECLARE_CREATE_OBJ_CLASS_METHOD(TagService); DECLARE_CREATE_OBJ_CLASS_METHOD(UDPService); DECLARE_CREATE_OBJ_CLASS_METHOD(UserService); DECLARE_CREATE_OBJ_CLASS_METHOD(physAddress); DECLARE_CREATE_OBJ_CLASS_METHOD(Group); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWException.h0000644000175000017500000000321311733011756025354 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FW_EXCEPTION_HH_FLAG__ #define __FW_EXCEPTION_HH_FLAG__ #include #include namespace libfwbuilder { /** * Base class for all Exceptions used in FWBuilder project */ class FWException { private: protected: std::string reason; std::map properties; public: /** * Creates exception with given reason */ FWException(const std::string &reason); virtual ~FWException() {}; /** * Returns textual representation of this exception */ virtual const std::string &toString() const; std::map& getProperties(); }; class FWNotSupportedException: public FWException { public: FWNotSupportedException(const std::string &reason):FWException(reason) {}; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPService.h0000644000175000017500000000346411733011756025022 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPSERVICE_HH_FLAG__ #define __IPSERVICE_HH_FLAG__ #include "fwbuilder/Service.h" namespace libfwbuilder { class IPService : public Service { static void initNamedProtocols(); protected: static std::map named_protocols; public: IPService(); virtual ~IPService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(IPService); DECLARE_DISPATCH_METHODS(IPService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; void setProtocolNumber(int n); std::string getTOSCode() const; void setTOSCode(const std::string &c); std::string getDSCPCode() const; void setDSCPCode(const std::string &c); bool hasIpOptions() const; static void addNamedProtocol(int proto_num, const std::string &proto_name); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWIntervalReference.h0000644000175000017500000000260411733011756027024 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWINTERVALREF_HH_FLAG__ #define __FWINTERVALREF_HH_FLAG__ #include "fwbuilder/FWReference.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" namespace libfwbuilder { /** * This class represents object reference. */ class FWIntervalReference : public FWReference { public: DECLARE_FWOBJECT_SUBTYPE(FWIntervalReference); DECLARE_DISPATCH_METHODS(FWIntervalReference); FWIntervalReference(); void setPointer(Interval *o); void setPointer(IntervalGroup *o); }; } #endif // _FWOBJECT_HH fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/SyncQueue.h0000644000175000017500000001062011733011756025102 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SYNC_QUEUE_H_FLAG__ #define __SYNC_QUEUE_H_FLAG__ #include "fwbuilder/ThreadTools.h" namespace libfwbuilder { /** * This is exception thrown by SyncQueue. * * @see SyncQueue */ class SyncQueueDoneException: public FWException { public: SyncQueueDoneException(const std::string &reason):FWException(reason) {} }; /** * SyncQueue - queue with access synchronized by mutex. * * @see SyncQueueDoneException */ template class SyncQueue: protected queue<_Tp> { protected: Mutex mutex ; Cond cond ; bool down ; public: /** * Creates empty queue. */ SyncQueue() : queue<_Tp>() { down = false; } /** * Returns true if queue is currently empty * * @exception SyncQueueDoneException if queue have been already shut down */ bool empty() const throw (SyncQueueDoneException) { mutex.lock(); if(down) { mutex.ulock(); throw SyncQueueDoneException("This queue already have been shut down."); } bool res=queue<_Tp>::empty(); mutex.unlock(); return res; } /** * Returns current queue size * * @exception SyncQueueDoneException if queue have been already shut down */ size_type size() const throw (SyncQueueDoneException) { mutex.lock(); if(down) { mutex.ulock(); throw SyncQueueDoneException("This queue already have been shut down."); } size_type res=queue<_Tp>::size(); mutex.unlock(); return res; } /** * Adds element to end of queue * * @exception SyncQueueDoneException if queue have been already shut down */ void push(const queue<_Tp>::value_type& __x) throw (SyncQueueDoneException) { mutex.lock(); if(down) { mutex.ulock(); throw SyncQueueDoneException("This queue already have been shut down."); } queue<_Tp>::push_back(__x); cond.signal(); mutex.unlock(); } /** * Pops element from front of queue. It queue is empty, blocks * according to timeout_ms parameter. * * @param timeout_ms timeout in milliseconds. -1 means wait forewer. * @exception FWException if timeout occured * @exception SyncQueueDoneException if shutdown() was called */ const queue<_Tp>::value_type pop(long timeout_ms=-1) throw(SyncQueueDoneException, FWException) { mutex.lock(); if(down) { mutex.ulock(); throw SyncQueueDoneException("This queue already have been shut down."); } while(true) { if(!queue<_Tp>::empty()) break; bool wait_status=cond.wait(mutex, timeout_ms); if(down) { mutex.ulock(); throw SyncQueueDoneException("The queue have been shut down."); } if(!wait_status) { //Timeout occured mutex.unlock(); throw FWException("SyncQueue timeout in pop()"); } } queue<_Tp>::value_type res = queue<_Tp>::front(); queue<_Tp>::pop(); mutex.unlock(); } /** * Shut down this queue. All waiting threads will be released * throwing SyncQueueDoneException exception. */ void shutdown() { mutex.lock(); down = true; cond.signal(); mutex.unlock(); } }; } #endif // __SYNC_QUEUE_H_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ThreadTools.h0000644000175000017500000000650111733011756025414 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __THREAD_TOOLS_H_FLAG__ #define __THREAD_TOOLS_H_FLAG__ #include "fwbuilder/libfwbuilder-config.h" #include //for time_t definition #include #include #include #include "fwbuilder/FWException.h" namespace libfwbuilder { /** * POSIX Mutex wrapper class. */ class Mutex { friend class Cond; protected: pthread_mutex_t mutex; public: Mutex(); virtual ~Mutex(); void lock() const; void unlock() const; }; /** * POSIX Mutex wrapper class. */ class Cond { protected: pthread_cond_t cond; public: Cond(); virtual ~Cond(); bool wait(const Mutex &mutex) const; void signal () const; void broadcast() const; }; /** * This class represents boolean value, access to which * is guarded by mutex. */ class SyncFlag: public Mutex { private: bool value; public: SyncFlag(bool v=false); /** * Checks value without locking. * Use with lock/unlock() */ bool peek() const; /** * Changes value without locking. * Use with lock/unlock() */ void modify(bool v); bool get() const; void set(bool v); operator bool() const; SyncFlag& operator=(const SyncFlag &o); SyncFlag& operator=(bool v); }; #ifndef _WIN32 /** * Timeout counter. This class needs poll(2) which does not exist on Windows */ class TimeoutCounter { private: unsigned int timeout ; std::string name ; time_t finish ; public: /** * Creates counter with start time now * and end time now+timeout. String is counter * name which will be used in thrown exception * in check() method. * NB: timeout is in whole seconds. */ TimeoutCounter(unsigned int timeout, const std::string &name); /** * Starts counter with start time 'now' * and end time now+timeout. * Could be called several times to restart it. */ void start(); /** * retunrs time left before * timeout expiration (in seconds) */ unsigned int timeLeft() const; /** * Returns 'true' if timeout is expired. */ bool isExpired() const; /** * Throw exception if timeout is expired */ void check() const throw(FWException) ; /** * Reads from socket/file. * Throws FWException if timeout occured. */ ssize_t read(int fd, void *buf, size_t n) const throw(FWException); }; #endif } #endif //__THREAD_TOOLS_H_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Policy.cpp0000644000175000017500000000255711733011756024765 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; const char *Policy::TYPENAME={"Policy"}; Policy::Policy() : RuleSet() { setName("Policy"); } Policy::~Policy() {} Rule* Policy::createRule() { FWObjectDatabase* db=getRoot(); assert(db!=NULL); return db->createPolicyRule(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Routing.h0000644000175000017500000000420311733011756024610 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ROUTING_HH_FLAG__ #define __ROUTING_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/RuleSet.h" namespace libfwbuilder { class Routing : public RuleSet { public: Routing(); virtual ~Routing(); DECLARE_FWOBJECT_SUBTYPE(Routing); DECLARE_DISPATCH_METHODS(Routing); /* the following methods provide proper typization */ RoutingRule* getRuleByNum(int n) { return RoutingRule::cast(RuleSet::getRuleByNum(n)); } RoutingRule* insertRuleAtTop() { return RoutingRule::cast(RuleSet::insertRuleAtTop()); } RoutingRule* insertRuleBefore(int n){ return RoutingRule::cast(RuleSet::insertRuleBefore(n));} RoutingRule* appendRuleAfter(int n){ return RoutingRule::cast(RuleSet::appendRuleAfter(n));} RoutingRule* appendRuleAtBottom(){ return RoutingRule::cast(RuleSet::appendRuleAtBottom());} virtual Rule* createRule(); }; } #endif //__ROUTING_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/valgrind.h0000644000175000017500000070560211733011756025002 0ustar sylvestresylvestre/* -*- c -*- ---------------------------------------------------------------- Notice that the following BSD-style license applies to this one file (valgrind.h) only. The rest of Valgrind is licensed under the terms of the GNU General Public License, version 2, unless otherwise indicated. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- This file is part of Valgrind, a dynamic binary instrumentation framework. Copyright (C) 2000-2008 Julian Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------- Notice that the above BSD-style license applies to this one file (valgrind.h) only. The entire rest of Valgrind is licensed under the terms of the GNU General Public License, version 2. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- */ /* This file is for inclusion into client (your!) code. You can use these macros to manipulate and query Valgrind's execution inside your own programs. The resulting executables will still run without Valgrind, just a little bit more slowly than they otherwise would, but otherwise unchanged. When not running on valgrind, each client request consumes very few (eg. 7) instructions, so the resulting performance loss is negligible unless you plan to execute client requests millions of times per second. Nevertheless, if that is still a problem, you can compile with the NVALGRIND symbol defined (gcc -DNVALGRIND) so that client requests are not even compiled in. */ #ifndef __VALGRIND_H #define __VALGRIND_H #include /* Nb: this file might be included in a file compiled with -ansi. So we can't use C++ style "//" comments nor the "asm" keyword (instead use "__asm__"). */ /* Derive some tags indicating what the target platform is. Note that in this file we're using the compiler's CPP symbols for identifying architectures, which are different to the ones we use within the rest of Valgrind. Note, __powerpc__ is active for both 32 and 64-bit PPC, whereas __powerpc64__ is only active for the latter (on Linux, that is). */ #undef PLAT_x86_linux #undef PLAT_amd64_linux #undef PLAT_ppc32_linux #undef PLAT_ppc64_linux #undef PLAT_ppc32_aix5 #undef PLAT_ppc64_aix5 #if !defined(_AIX) && defined(__i386__) # define PLAT_x86_linux 1 #elif !defined(_AIX) && defined(__x86_64__) # define PLAT_amd64_linux 1 #elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__) # define PLAT_ppc32_linux 1 #elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__) # define PLAT_ppc64_linux 1 #elif defined(_AIX) && defined(__64BIT__) # define PLAT_ppc64_aix5 1 #elif defined(_AIX) && !defined(__64BIT__) # define PLAT_ppc32_aix5 1 #endif /* If we're not compiling for our target platform, don't generate any inline asms. */ #if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \ && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \ && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5) # if !defined(NVALGRIND) # define NVALGRIND 1 # endif #endif /* ------------------------------------------------------------------ */ /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ /* in here of use to end-users -- skip to the next section. */ /* ------------------------------------------------------------------ */ #if defined(NVALGRIND) /* Define NVALGRIND to completely remove the Valgrind magic sequence from the compiled code (analogous to NDEBUG's effects on assert()) */ #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { \ (_zzq_rlval) = (_zzq_default); \ } #else /* ! NVALGRIND */ /* The following defines the magic code sequences which the JITter spots and handles magically. Don't look too closely at them as they will rot your brain. The assembly code sequences for all architectures is in this one file. This is because this file must be stand-alone, and we don't want to have multiple files. For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default value gets put in the return slot, so that everything works when this is executed not under Valgrind. Args are passed in a memory block, and so there's no intrinsic limit to the number that could be passed, but it's currently five. The macro args are: _zzq_rlval result lvalue _zzq_default default value (result returned when running on real CPU) _zzq_request request code _zzq_arg1..5 request params The other two macros are used to support function wrapping, and are a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the guest's NRADDR pseudo-register and whatever other information is needed to safely run the call original from the wrapper: on ppc64-linux, the R2 value at the divert point is also needed. This information is abstracted into a user-visible type, OrigFn. VALGRIND_CALL_NOREDIR_* behaves the same as the following on the guest, but guarantees that the branch instruction will not be redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a complete inline asm, since it needs to be combined with more magic inline asm stuff to be useful. */ /* ------------------------- x86-linux ------------------------- */ #if defined(PLAT_x86_linux) typedef struct { unsigned int nraddr; /* where's the code? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "roll $3, %%edi ; roll $13, %%edi\n\t" \ "roll $29, %%edi ; roll $19, %%edi\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { volatile unsigned int _zzq_args[6]; \ volatile unsigned int _zzq_result; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %EDX = client_request ( %EAX ) */ \ "xchgl %%ebx,%%ebx" \ : "=d" (_zzq_result) \ : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ volatile unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %EAX = guest_NRADDR */ \ "xchgl %%ecx,%%ecx" \ : "=a" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ } #define VALGRIND_CALL_NOREDIR_EAX \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* call-noredir *%EAX */ \ "xchgl %%edx,%%edx\n\t" #endif /* PLAT_x86_linux */ /* ------------------------ amd64-linux ------------------------ */ #if defined(PLAT_amd64_linux) typedef struct { unsigned long long int nraddr; /* where's the code? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { volatile unsigned long long int _zzq_args[6]; \ volatile unsigned long long int _zzq_result; \ _zzq_args[0] = (unsigned long long int)(_zzq_request); \ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %RDX = client_request ( %RAX ) */ \ "xchgq %%rbx,%%rbx" \ : "=d" (_zzq_result) \ : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ volatile unsigned long long int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %RAX = guest_NRADDR */ \ "xchgq %%rcx,%%rcx" \ : "=a" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ } #define VALGRIND_CALL_NOREDIR_RAX \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* call-noredir *%RAX */ \ "xchgq %%rdx,%%rdx\n\t" #endif /* PLAT_amd64_linux */ /* ------------------------ ppc32-linux ------------------------ */ #if defined(PLAT_ppc32_linux) typedef struct { unsigned int nraddr; /* where's the code? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned int _zzq_args[6]; \ unsigned int _zzq_result; \ unsigned int* _zzq_ptr; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ _zzq_ptr = _zzq_args; \ __asm__ volatile("mr 3,%1\n\t" /*default*/ \ "mr 4,%2\n\t" /*ptr*/ \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1\n\t" \ "mr %0,3" /*result*/ \ : "=b" (_zzq_result) \ : "b" (_zzq_default), "b" (_zzq_ptr) \ : "cc", "memory", "r3", "r4"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "cc", "memory", "r3" \ ); \ _zzq_orig->nraddr = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc32_linux */ /* ------------------------ ppc64-linux ------------------------ */ #if defined(PLAT_ppc64_linux) typedef struct { unsigned long long int nraddr; /* where's the code? */ unsigned long long int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ "rotldi 0,0,61 ; rotldi 0,0,51\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned long long int _zzq_args[6]; \ register unsigned long long int _zzq_result __asm__("r3"); \ register unsigned long long int* _zzq_ptr __asm__("r4"); \ _zzq_args[0] = (unsigned long long int)(_zzq_request); \ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ _zzq_ptr = _zzq_args; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1" \ : "=r" (_zzq_result) \ : "0" (_zzq_default), "r" (_zzq_ptr) \ : "cc", "memory"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ register unsigned long long int __addr __asm__("r3"); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2" \ : "=r" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ "or 4,4,4" \ : "=r" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->r2 = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc64_linux */ /* ------------------------ ppc32-aix5 ------------------------- */ #if defined(PLAT_ppc32_aix5) typedef struct { unsigned int nraddr; /* where's the code? */ unsigned int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned int _zzq_args[7]; \ register unsigned int _zzq_result; \ register unsigned int* _zzq_ptr; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ _zzq_args[6] = (unsigned int)(_zzq_default); \ _zzq_ptr = _zzq_args; \ __asm__ volatile("mr 4,%1\n\t" \ "lwz 3, 24(4)\n\t" \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1\n\t" \ "mr %0,3" \ : "=b" (_zzq_result) \ : "b" (_zzq_ptr) \ : "r3", "r4", "cc", "memory"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ register unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ "or 4,4,4\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->r2 = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc32_aix5 */ /* ------------------------ ppc64-aix5 ------------------------- */ #if defined(PLAT_ppc64_aix5) typedef struct { unsigned long long int nraddr; /* where's the code? */ unsigned long long int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ "rotldi 0,0,61 ; rotldi 0,0,51\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned long long int _zzq_args[7]; \ register unsigned long long int _zzq_result; \ register unsigned long long int* _zzq_ptr; \ _zzq_args[0] = (unsigned int long long)(_zzq_request); \ _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \ _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \ _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \ _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \ _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \ _zzq_args[6] = (unsigned int long long)(_zzq_default); \ _zzq_ptr = _zzq_args; \ __asm__ volatile("mr 4,%1\n\t" \ "ld 3, 48(4)\n\t" \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1\n\t" \ "mr %0,3" \ : "=b" (_zzq_result) \ : "b" (_zzq_ptr) \ : "r3", "r4", "cc", "memory"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ register unsigned long long int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ "or 4,4,4\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->r2 = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc64_aix5 */ /* Insert assembly code for other platforms here... */ #endif /* NVALGRIND */ /* ------------------------------------------------------------------ */ /* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ /* ugly. It's the least-worst tradeoff I can think of. */ /* ------------------------------------------------------------------ */ /* This section defines magic (a.k.a appalling-hack) macros for doing guaranteed-no-redirection macros, so as to get from function wrappers to the functions they are wrapping. The whole point is to construct standard call sequences, but to do the call itself with a special no-redirect call pseudo-instruction that the JIT understands and handles specially. This section is long and repetitious, and I can't see a way to make it shorter. The naming scheme is as follows: CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} 'W' stands for "word" and 'v' for "void". Hence there are different macros for calling arity 0, 1, 2, 3, 4, etc, functions, and for each, the possibility of returning a word-typed result, or no result. */ /* Use these to write the name of your wrapper. NOTE: duplicates VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */ #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ _vgwZU_##soname##_##fnname #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ _vgwZZ_##soname##_##fnname /* Use this macro from within a wrapper function to collect the context (address and possibly other info) of the original function. Once you have that you can then use it in one of the CALL_FN_ macros. The type of the argument _lval is OrigFn. */ #define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) /* Derivatives of the main macros below, for calling functions returning void. */ #define CALL_FN_v_v(fnptr) \ do { volatile unsigned long _junk; \ CALL_FN_W_v(_junk,fnptr); } while (0) #define CALL_FN_v_W(fnptr, arg1) \ do { volatile unsigned long _junk; \ CALL_FN_W_W(_junk,fnptr,arg1); } while (0) #define CALL_FN_v_WW(fnptr, arg1,arg2) \ do { volatile unsigned long _junk; \ CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ do { volatile unsigned long _junk; \ CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) /* ------------------------- x86-linux ------------------------- */ #if defined(PLAT_x86_linux) /* These regs are trashed by the hidden call. No need to mention eax as gcc can already see that, plus causes gcc to bomb. */ #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $4, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $8, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $12, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $16, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $20, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $24, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $28, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $32, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $36, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $40, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ arg6,arg7,arg8,arg9,arg10, \ arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ "pushl 44(%%eax)\n\t" \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $44, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ arg6,arg7,arg8,arg9,arg10, \ arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ "pushl 48(%%eax)\n\t" \ "pushl 44(%%eax)\n\t" \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $48, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_x86_linux */ /* ------------------------ amd64-linux ------------------------ */ #if defined(PLAT_amd64_linux) /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ "rdi", "r8", "r9", "r10", "r11" /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned long) == 8. */ /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ macros. In order not to trash the stack redzone, we need to drop %rsp by 128 before the hidden call, and restore afterwards. The nastyness is that it is only by luck that the stack still appears to be unwindable during the hidden call - since then the behaviour of any routine using this macro does not match what the CFI data says. Sigh. Why is this important? Imagine that a wrapper has a stack allocated local, and passes to the hidden call, a pointer to it. Because gcc does not know about the hidden call, it may allocate that local in the redzone. Unfortunately the hidden call may then trash it before it comes to use it. So we must step clear of the redzone, for the duration of the hidden call, to make it safe. Probably the same problem afflicts the other redzone-style ABIs too (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is self describing (none of this CFI nonsense) so at least messing with the stack pointer doesn't give a danger of non-unwindable stack. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ "addq $128,%%rsp\n\t" \ VALGRIND_CALL_NOREDIR_RAX \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $8, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $16, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $24, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 80(%%rax)\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $32, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 88(%%rax)\n\t" \ "pushq 80(%%rax)\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $40, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 96(%%rax)\n\t" \ "pushq 88(%%rax)\n\t" \ "pushq 80(%%rax)\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $48, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_amd64_linux */ /* ------------------------ ppc32-linux ------------------------ */ #if defined(PLAT_ppc32_linux) /* This is useful for finding out about the on-stack stuff: extern int f9 ( int,int,int,int,int,int,int,int,int ); extern int f10 ( int,int,int,int,int,int,int,int,int,int ); extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); int g9 ( void ) { return f9(11,22,33,44,55,66,77,88,99); } int g10 ( void ) { return f10(11,22,33,44,55,66,77,88,99,110); } int g11 ( void ) { return f11(11,22,33,44,55,66,77,88,99,110,121); } int g12 ( void ) { return f12(11,22,33,44,55,66,77,88,99,110,121,132); } */ /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* These CALL_FN_ macros assume that on ppc32-linux, sizeof(unsigned long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-16\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,16\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ _argvec[10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-16\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,12(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,16\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ _argvec[10] = (unsigned long)arg10; \ _argvec[11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-32\n\t" \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,16(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,12(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,32\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ _argvec[10] = (unsigned long)arg10; \ _argvec[11] = (unsigned long)arg11; \ _argvec[12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-32\n\t" \ /* arg12 */ \ "lwz 3,48(11)\n\t" \ "stw 3,20(1)\n\t" \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,16(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,12(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,32\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc32_linux */ /* ------------------------ ppc64-linux ------------------------ */ #if defined(PLAT_ppc64_linux) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned long) == 8. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-128\n\t" /* expand stack frame */ \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,128" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-128\n\t" /* expand stack frame */ \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,128" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-144\n\t" /* expand stack frame */ \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,144" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-144\n\t" /* expand stack frame */ \ /* arg12 */ \ "ld 3,96(11)\n\t" \ "std 3,136(1)\n\t" \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,144" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc64_linux */ /* ------------------------ ppc32-aix5 ------------------------- */ #if defined(PLAT_ppc32_aix5) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* Expand the stack frame, copying enough info that unwinding still works. Trashes r3. */ #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ "addi 1,1,-" #_n_fr "\n\t" \ "lwz 3," #_n_fr "(1)\n\t" \ "stw 3,0(1)\n\t" #define VG_CONTRACT_FRAME_BY(_n_fr) \ "addi 1,1," #_n_fr "\n\t" /* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(64) \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(64) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(64) \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,60(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(64) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(72) \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,64(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,60(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(72) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(72) \ /* arg12 */ \ "lwz 3,48(11)\n\t" \ "stw 3,68(1)\n\t" \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,64(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,60(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(72) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc32_aix5 */ /* ------------------------ ppc64-aix5 ------------------------- */ #if defined(PLAT_ppc64_aix5) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* Expand the stack frame, copying enough info that unwinding still works. Trashes r3. */ #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ "addi 1,1,-" #_n_fr "\n\t" \ "ld 3," #_n_fr "(1)\n\t" \ "std 3,0(1)\n\t" #define VG_CONTRACT_FRAME_BY(_n_fr) \ "addi 1,1," #_n_fr "\n\t" /* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned long) == 8. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(128) \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(128) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(128) \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(128) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(144) \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(144) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(144) \ /* arg12 */ \ "ld 3,96(11)\n\t" \ "std 3,136(1)\n\t" \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(144) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc64_aix5 */ /* ------------------------------------------------------------------ */ /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ /* */ /* ------------------------------------------------------------------ */ /* Some request codes. There are many more of these, but most are not exposed to end-user view. These are the public ones, all of the form 0x1000 + small_number. Core ones are in the range 0x00000000--0x0000ffff. The non-public ones start at 0x2000. */ /* These macros are used by tools -- they must be public, but don't embed them into other programs. */ #define VG_USERREQ_TOOL_BASE(a,b) \ ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) #define VG_IS_TOOL_USERREQ(a, b, v) \ (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! This enum comprises an ABI exported by Valgrind to programs which use client requests. DO NOT CHANGE THE ORDER OF THESE ENTRIES, NOR DELETE ANY -- add new ones at the end. */ typedef enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, /* These allow any function to be called from the simulated CPU but run on the real CPU. Nb: the first arg passed to the function is always the ThreadId of the running thread! So CLIENT_CALL0 actually requires a 1 arg function, etc. */ VG_USERREQ__CLIENT_CALL0 = 0x1101, VG_USERREQ__CLIENT_CALL1 = 0x1102, VG_USERREQ__CLIENT_CALL2 = 0x1103, VG_USERREQ__CLIENT_CALL3 = 0x1104, /* Can be useful in regression testing suites -- eg. can send Valgrind's output to /dev/null and still count errors. */ VG_USERREQ__COUNT_ERRORS = 0x1201, /* These are useful and can be interpreted by any tool that tracks malloc() et al, by using vg_replace_malloc.c. */ VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, VG_USERREQ__FREELIKE_BLOCK = 0x1302, /* Memory pool support. */ VG_USERREQ__CREATE_MEMPOOL = 0x1303, VG_USERREQ__DESTROY_MEMPOOL = 0x1304, VG_USERREQ__MEMPOOL_ALLOC = 0x1305, VG_USERREQ__MEMPOOL_FREE = 0x1306, VG_USERREQ__MEMPOOL_TRIM = 0x1307, VG_USERREQ__MOVE_MEMPOOL = 0x1308, VG_USERREQ__MEMPOOL_CHANGE = 0x1309, VG_USERREQ__MEMPOOL_EXISTS = 0x130a, /* Allow printfs to valgrind log. */ VG_USERREQ__PRINTF = 0x1401, VG_USERREQ__PRINTF_BACKTRACE = 0x1402, /* Stack support. */ VG_USERREQ__STACK_REGISTER = 0x1501, VG_USERREQ__STACK_DEREGISTER = 0x1502, VG_USERREQ__STACK_CHANGE = 0x1503 } Vg_ClientRequest; #if !defined(__GNUC__) # define __extension__ /* */ #endif /* Returns the number of Valgrinds this code is running under. That is, 0 if running natively, 1 if running under Valgrind, 2 if running under Valgrind which is running under another Valgrind, etc. */ #define RUNNING_ON_VALGRIND __extension__ \ ({unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \ VG_USERREQ__RUNNING_ON_VALGRIND, \ 0, 0, 0, 0, 0); \ _qzz_res; \ }) /* Discard translation of code in the range [_qzz_addr .. _qzz_addr + _qzz_len - 1]. Useful if you are debugging a JITter or some such, since it provides a way to make sure valgrind will retranslate the invalidated area. Returns no value. */ #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DISCARD_TRANSLATIONS, \ _qzz_addr, _qzz_len, 0, 0, 0); \ } /* These requests are for getting Valgrind itself to print something. Possibly with a backtrace. This is a really ugly hack. */ #if defined(NVALGRIND) # define VALGRIND_PRINTF(...) # define VALGRIND_PRINTF_BACKTRACE(...) #else /* NVALGRIND */ /* Modern GCC will optimize the static routine out if unused, and unused attribute will shut down warnings about it. */ static int VALGRIND_PRINTF(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); static int VALGRIND_PRINTF(const char *format, ...) { unsigned long _qzz_res; va_list vargs; va_start(vargs, format); VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF, (unsigned long)format, (unsigned long)vargs, 0, 0, 0); va_end(vargs); return (int)_qzz_res; } static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) { unsigned long _qzz_res; va_list vargs; va_start(vargs, format); VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE, (unsigned long)format, (unsigned long)vargs, 0, 0, 0); va_end(vargs); return (int)_qzz_res; } #endif /* NVALGRIND */ /* These requests allow control to move from the simulated CPU to the real CPU, calling an arbitary function. Note that the current ThreadId is inserted as the first argument. So this call: VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) requires f to have this signature: Word f(Word tid, Word arg1, Word arg2) where "Word" is a word-sized type. Note that these client requests are not entirely reliable. For example, if you call a function with them that subsequently calls printf(), there's a high chance Valgrind will crash. Generally, your prospects of these working are made higher if the called function does not refer to any global variables, and does not refer to any libc or other functions (printf et al). Any kind of entanglement with libc or dynamic linking is likely to have a bad outcome, for tricky reasons which we've grappled with a lot in the past. */ #define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL0, \ _qyy_fn, \ 0, 0, 0, 0); \ _qyy_res; \ }) #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL1, \ _qyy_fn, \ _qyy_arg1, 0, 0, 0); \ _qyy_res; \ }) #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL2, \ _qyy_fn, \ _qyy_arg1, _qyy_arg2, 0, 0); \ _qyy_res; \ }) #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL3, \ _qyy_fn, \ _qyy_arg1, _qyy_arg2, \ _qyy_arg3, 0); \ _qyy_res; \ }) /* Counts the number of errors that have been recorded by a tool. Nb: the tool must record the errors with VG_(maybe_record_error)() or VG_(unique_error)() for them to be counted. */ #define VALGRIND_COUNT_ERRORS \ __extension__ \ ({unsigned int _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__COUNT_ERRORS, \ 0, 0, 0, 0, 0); \ _qyy_res; \ }) /* Mark a block of memory as having been allocated by a malloc()-like function. `addr' is the start of the usable block (ie. after any redzone) `rzB' is redzone size if the allocator can apply redzones; use '0' if not. Adding redzones makes it more likely Valgrind will spot block overruns. `is_zeroed' indicates if the memory is zeroed, as it is for calloc(). Put it immediately after the point where a block is allocated. If you're using Memcheck: If you're allocating memory via superblocks, and then handing out small chunks of each superblock, if you don't have redzones on your small blocks, it's worth marking the superblock with VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are detected. But if you can put redzones on, it's probably better to not do this, so that messages for small overruns are described in terms of the small block rather than the superblock (but if you have a big overrun that skips over a redzone, you could miss an error this way). See memcheck/tests/custom_alloc.c for an example. WARNING: if your allocator uses malloc() or 'new' to allocate superblocks, rather than mmap() or brk(), this will not work properly -- you'll likely get assertion failures during leak detection. This is because Valgrind doesn't like seeing overlapping heap blocks. Sorry. Nb: block must be freed via a free()-like function specified with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */ #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MALLOCLIKE_BLOCK, \ addr, sizeB, rzB, is_zeroed, 0); \ } /* Mark a block of memory as having been freed by a free()-like function. `rzB' is redzone size; it must match that given to VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak checker. Put it immediately after the point where the block is freed. */ #define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__FREELIKE_BLOCK, \ addr, rzB, 0, 0, 0); \ } /* Create a memory pool. */ #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__CREATE_MEMPOOL, \ pool, rzB, is_zeroed, 0, 0); \ } /* Destroy a memory pool. */ #define VALGRIND_DESTROY_MEMPOOL(pool) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DESTROY_MEMPOOL, \ pool, 0, 0, 0, 0); \ } /* Associate a piece of memory with a memory pool. */ #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_ALLOC, \ pool, addr, size, 0, 0); \ } /* Disassociate a piece of memory from a memory pool. */ #define VALGRIND_MEMPOOL_FREE(pool, addr) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_FREE, \ pool, addr, 0, 0, 0); \ } /* Disassociate any pieces outside a particular range. */ #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_TRIM, \ pool, addr, size, 0, 0); \ } /* Resize and/or move a piece associated with a memory pool. */ #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MOVE_MEMPOOL, \ poolA, poolB, 0, 0, 0); \ } /* Resize and/or move a piece associated with a memory pool. */ #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_CHANGE, \ pool, addrA, addrB, size, 0); \ } /* Return 1 if a mempool exists, else 0. */ #define VALGRIND_MEMPOOL_EXISTS(pool) \ ({unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_EXISTS, \ pool, 0, 0, 0, 0); \ _qzz_res; \ }) /* Mark a piece of memory as being a stack. Returns a stack id. */ #define VALGRIND_STACK_REGISTER(start, end) \ ({unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__STACK_REGISTER, \ start, end, 0, 0, 0); \ _qzz_res; \ }) /* Unmark the piece of memory associated with a stack id as being a stack. */ #define VALGRIND_STACK_DEREGISTER(id) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__STACK_DEREGISTER, \ id, 0, 0, 0, 0); \ } /* Change the start and end address of the stack id. */ #define VALGRIND_STACK_CHANGE(id, start, end) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__STACK_CHANGE, \ id, start, end, 0, 0); \ } #undef PLAT_x86_linux #undef PLAT_amd64_linux #undef PLAT_ppc32_linux #undef PLAT_ppc64_linux #undef PLAT_ppc32_aix5 #undef PLAT_ppc64_aix5 #endif /* __VALGRIND_H */ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/InetAddrMask.h0000644000175000017500000001104011733011756025464 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This class is a holder of a pair address / netmask. * It can act both as a container for the address/netmask configuration * data (such as for an interface) or as a network. * * TODO(vadim): need better name. InetNetwork ? InetAddrMaskPair ? */ #ifndef __INETADDRMASK_HH_FLAG__ #define __INETADDRMASK_HH_FLAG__ #include #include #ifndef _WIN32 # include # include # include # include #else # include #endif #include "fwbuilder/FWException.h" #include "fwbuilder/InetAddr.h" namespace libfwbuilder { class InetAddrMask; std::vector getOverlap(const InetAddrMask &n1, const InetAddrMask &n2); std::vector substract(const InetAddrMask &n1, const InetAddrMask &n2); std::vector convertAddressRange(const InetAddr &start, const InetAddr &end); bool _convert_range_to_networks(const InetAddr &start, const InetAddr &end, std::vector &res); class InetAddrMask { protected: InetAddr* address; InetAddr* netmask; InetAddr* broadcast_address; InetAddr* network_address; InetAddr* last_host; explicit InetAddrMask(bool no_address); public: InetAddrMask(); InetAddrMask(const InetAddr&, const InetAddr&); InetAddrMask(const std::string &s) throw(FWException); InetAddrMask(const InetAddrMask&); virtual ~InetAddrMask(); void setNetworkAndBroadcastAddress(); virtual const InetAddr* getAddressPtr() const { return address; } virtual const InetAddr* getNetmaskPtr() const { return netmask; } virtual const InetAddr* getNetworkAddressPtr() const { return network_address; } virtual const InetAddr* getBroadcastAddressPtr() const { return broadcast_address; } const InetAddr* getFirstHostPtr() const { return network_address;} const InetAddr* getLastHostPtr() const{ return last_host;} virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual unsigned int dimension() const; bool isAny(); InetAddrMask& operator=(const InetAddrMask &o); bool operator<(const InetAddrMask &b); friend bool operator==(const InetAddrMask &a, const InetAddrMask &b); friend bool operator<(const InetAddrMask &a, const InetAddrMask &b); virtual std::string toString() const { return address->toString()+"/"+netmask->toString(); } bool belongs(const InetAddr &) const; /** * calculates overlapping part of two networks n1 and * n2. Overlapping part is defined as in sets: if we think of * networks as sets of addresses, then intersection contains all * addresses that belong to both networks */ friend std::vector getOverlap(const InetAddrMask &n1, const InetAddrMask &n2); /** * substract network n2 from the network n1. The meaning of this * operation is opposite to getOverlap: it returns all addresses * that belong to n1 but do not belong to n2 */ friend std::vector substract(const InetAddrMask &n1, const InetAddrMask &n2); /** * converts address range (defined by its start and end) to a * bunch of networks */ friend std::vector convertAddressRange(const InetAddr &start, const InetAddr &end); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPv4.cpp0000644000175000017500000000773711733011756024315 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Class IPv4 serves two purposes: - it is used to describe configuration of an interface which consists of an address and netmask - it is used to describe a single standalone address object (in the tree, under Objects/Addresses) Even though class Network also has address and netmask, IPv4 objects are recognized by compilers as single addresses. */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include "fwbuilder/IPv4.h" #include "fwbuilder/Interface.h" #include "fwbuilder/XMLTools.h" using namespace std; using namespace libfwbuilder; const char *IPv4::TYPENAME={"IPv4"}; IPv4::IPv4() : Address() { } IPv4::~IPv4() { } void IPv4::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char* n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address"))); assert(n!=NULL); // strip whitespace and other non-numeric characters at the beginng and end string addr(n); string::size_type first = addr.find_first_of("0123456789"); string::size_type last = addr.find_last_of("0123456789"); try { addr = addr.substr(first, last-first+1); } catch (std::out_of_range &ex) { cerr << "Object \"" << getName() << "\": Invalid address" << n << endl; addr = "0.0.0.0"; } setAddress(InetAddr(addr)); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("netmask"))); assert(n!=NULL); string netm(n); first = netm.find_first_of("0123456789"); last = netm.find_last_of("0123456789"); try { netm = netm.substr(first, last-first+1); } catch (std::out_of_range &ex) { cerr << "Object \"" << getName() << "\": Invalid netmask" << n << endl; addr = "0.0.0.0"; } if (!netm.empty()) setNetmask(InetAddr(netm)); else setNetmask(InetAddr(0)); FREEXMLBUFF(n); } xmlNodePtr IPv4::toXML(xmlNodePtr xml_parent_node) throw(FWException) { if (getName().empty()) setName(getTypeName()); xmlNodePtr me = FWObject::toXML(xml_parent_node); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("address"), STRTOXMLCAST(inet_addr_mask->getAddressPtr()->toString())); xmlNewProp(me, TOXMLCAST("netmask"), STRTOXMLCAST(inet_addr_mask->getNetmaskPtr()->toString())); return me; } void IPv4::setAddress(const InetAddr &a) { inet_addr_mask->setAddress(a); } void IPv4::setNetmask(const InetAddr &nm) { inet_addr_mask->setNetmask(nm); } void IPv4::setAddressNetmask(const std::string& s) { delete inet_addr_mask; inet_addr_mask = new InetAddrMask(s); } void IPv4::dump(std::ostream &f,bool recursive,bool brief,int offset) const { FWObject::dump(f, recursive, brief, offset); f << inet_addr_mask->getAddressPtr()->toString() << endl; } bool IPv4::isPrimaryObject() const { return (!Interface::isA(getParent())); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ObjectGroup.h0000644000175000017500000000332711733011756025412 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTGROUP_HH_FLAG__ #define __OBJECTGROUP_HH_FLAG__ #include "fwbuilder/Group.h" namespace libfwbuilder { class ObjectGroup : public Group { public: ObjectGroup(); virtual ~ObjectGroup(); DECLARE_FWOBJECT_SUBTYPE(ObjectGroup); DECLARE_DISPATCH_METHODS(ObjectGroup); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); /** * get the list of object type names that can be inserted into * given object group. For example, if the group is ObjectGroup, * then the list will include all objects but not services. This * reflects definition of the group XML element in DTD. */ virtual void getAllowedTypesOfChildren(std::list &types_list); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ClusterGroup.h0000644000175000017500000000446711733011756025633 0ustar sylvestresylvestre/* * ClusterGroup.h - Class to group cluster interfaces * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement * * * Class ClusterGroup serves as a base class for StateSyncClusterGroup and * FailoverClusterGroup. Objects of the class ClusterGroup are never used * and can not be stored in XML file. */ #ifndef __CLUSTERGROUP_HH_ #define __CLUSTERGROUP_HH_ #include "fwbuilder/ObjectGroup.h" namespace libfwbuilder { class ClusterGroupOptions; class ClusterGroup : public ObjectGroup { protected: virtual void replaceReferenceInternal(int oldfw_id, int newfw_id, int &counter); public: ClusterGroup(); virtual ~ClusterGroup() {}; /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); DECLARE_FWOBJECT_SUBTYPE(ClusterGroup); DECLARE_DISPATCH_METHODS(ClusterGroup); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual ClusterGroupOptions* getOptionsObject(); /** * This method copies all attributes of obj plus all reference * child objects and the options object to reproduce accurate * state of this. */ virtual FWObject& duplicateForUndo(const FWObject *obj) throw(FWException); /** * If @this is cluster interface and it is correctly * configured with member interfaces, this method returns * pointer to interface that belongs to the given member * firewall. Otherwise it returns NULL. */ Interface* getInterfaceForMemberFirewall(Firewall *fw); }; } #endif /* __CLUSTERGROUP_HH_ */ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/XMLTools.h0000644000175000017500000001461711733011756024654 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This file contains assorted XML handling code */ #ifndef __XML_TOOLS_HH_FLAG__ #define __XML_TOOLS_HH_FLAG__ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Tools.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include namespace libfwbuilder { //TODO: define type cast operators for these #define FROMXMLCAST(x) ((const char *)x) #define STRTOXMLCAST(x) ((xmlChar *)x.c_str()) #define TOXMLCAST(x) ((xmlChar *)x) class XMLTools { public: static xmlNodePtr getXmlNodeByPath(xmlNodePtr r,const char *path ); static xmlNodePtr getXmlNodeByPath(xmlNodePtr r,const std::string &path ); static xmlNodePtr getXmlChildNode (xmlNodePtr r,const char *child_name ); static void initXMLTools(); static void close(); class UpgradePredicate { public: virtual ~UpgradePredicate() {} virtual bool operator()(const std::string&) const { return true; } }; static std::string readFile(const std::string &file_name) throw(FWException); /** * Loads given file, performing version conversion * if neccessary. */ static xmlDocPtr loadFile(const std::string &file_name, const std::string &type_name, const std::string &dtd_file, const UpgradePredicate *upgrade, const std::string &template_dir, const std::string ¤t_version = std::string(FWBUILDER_XML_VERSION) ) throw(FWException); static void setDTD(xmlDocPtr doc, const std::string &type_name, const std::string &dtd_file) throw(FWException); /** * Saves to file with setting DTD. */ static void saveFile(xmlDocPtr doc, const std::string &file_name, const std::string &type_name, const std::string &dtd_file) throw(FWException); /** * Saves XML document to the memory buffer */ static void dumpToMemory(xmlDocPtr doc, xmlChar **buffer, int *size, const std::string &type_name, const std::string &dtd_file) throw(FWException); static xmlExternalEntityLoader defaultLoader; /** * parses contents of the file file_name which is preloaded into * buffer, without version conversion. File name is passed for * pretty error printing. * * @return document pointer */ static xmlDocPtr parseFile(const std::string &file_name, const std::string &buffer, bool use_dtd, const std::string &template_dir ) throw(FWException); /** * Performs XSLT transformation of the document in memory * @return new document */ static xmlDocPtr transformDocument(xmlDocPtr doc, const std::string &stylesheet_file, const char **params ) throw(FWException); /** * Performs XSLT transformation of the document. Results are * stored in dst file. */ static void transformDocumentToFile(xmlDocPtr doc, const std::string &stylesheet_file, const char **params, const std::string &dst_file ) throw(FWException); /** * Performs XSLT transformation of the src file. Results are * stored in dst file. */ static void transformFileToFile(const std::string &src_file, const std::string &stylesheet_file, const char **params, const std::string &dst_file ) throw(FWException); static std::string quote_linefeeds (const std::string &s); static std::string unquote_linefeeds(const std::string &s); /** * checks all characters in str and makes sure they all conform * with UTF8 encoding. Replaces unconforming characters with '?' */ static std::string cleanForUTF8(const std::string &str); /** * checks all characters in str and makes sure they all conform * to NVT ASCII encoding. Replaces unconforming characters with '?' */ static std::string cleanForNVTASCII(const std::string &str); /** * Compares 2 product version numbers in dotted notation * @return 0 if equal, positive if v1>v2, negative if v1 #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *ICMPService::TYPENAME={"ICMPService"}; ICMPService::ICMPService() { setStr("type", "-1"); setStr("code", "-1"); } ICMPService::~ICMPService() {} string ICMPService::getProtocolName() const { return "icmp";} int ICMPService::getProtocolNumber() const { return 1; } void ICMPService::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("type"))); assert(n!=NULL); setStr("type", n); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("code"))); if(n!=NULL) { setStr("code", n); FREEXMLBUFF(n); } } xmlNodePtr ICMPService::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/RuleElement.cpp0000644000175000017500000003775711733011756025761 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Rule.h" #include "fwbuilder/IPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Interval.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Network.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/XMLTools.h" #include using namespace std; using namespace libfwbuilder; const char *RuleElement::TYPENAME={"RuleElement"}; RuleElement::RuleElement() { setNeg(false); } void RuleElement::init(FWObjectDatabase *root) { setRoot(root); /* we need to add a reference to 'any' to this new rule element. However, when objects are being loaded from XML file, ANY element may be located at its bottom so at the moment when this rule element is created, we may have not read the ANY yet. In that case we do not add the reference here because it will be added when it is read from the file anyway */ int any_id = getAnyElementId(); FWObject *any_obj = getById(any_id); if (any_obj == NULL) { any_obj = root->checkIndex( any_id ); if (any_obj) FWObject::addRef( any_obj ); } } void RuleElement::fromXML(xmlNodePtr root) throw(FWException) { const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("neg"))); if (n) { negation = (cxx_strcasecmp(n, "1")==0 || cxx_strcasecmp(n , "true")==0); FREEXMLBUFF(n); } FWObject::fromXML(root); } xmlNodePtr RuleElement::toXML(xmlNodePtr xml_parent_node) throw(FWException) { int my_id = getId(); setId(-1); // FWObject::toXML() skips id if it is == -1. RuleElement objects // have no ID as per DTD (why?) xmlNodePtr me = FWObject::toXML(xml_parent_node, false); xmlNewProp(me, TOXMLCAST("neg"), TOXMLCAST(((getNeg()) ? "True" : "False"))); setId(my_id); return me; } FWObject& RuleElement::shallowDuplicate(const FWObject *other, bool preserve_id) throw(FWException) { setNeg(RuleElement::constcast(other)->getNeg()); return FWObject::shallowDuplicate(other, preserve_id); } void RuleElement::addRef(FWObject *obj) { FWObject *o=NULL; if (isAny()) { o=(*(begin())); o=(FWReference::cast(o))->getPointer(); } FWObject::addRef(obj); if (o!=NULL) removeRef(o); } void RuleElement::removeRef(FWObject *obj) { FWObject::removeRef(obj); if (getChildrenCount()==0) { // there is nothing left obj = obj->getRoot()->findInIndex( getAnyElementId() ); if (obj) addRef(obj); } } bool RuleElement::isAny() const { if (getChildrenCount()!=1) return(false); const FWObject *o = front(); return ((FWReference::constcast(o))->getPointerIdDirect() == getAnyElementId()); } void RuleElement::setAnyElement() { int any_id = getAnyElementId(); FWObject *any = getRoot()->findInIndex( any_id ); if (any) addRef( any ); } void RuleElement::reset() { clearChildren(); setAnyElement(); setNeg(false); } int RuleElement::getAnyElementId() const { return -1; } const char *RuleElementSrc::TYPENAME={"Src"}; RuleElementSrc::RuleElementSrc() {} int RuleElementSrc::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementSrc::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementSrc::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementDst::TYPENAME={"Dst"}; RuleElementDst::RuleElementDst() {} int RuleElementDst::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementDst::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementDst::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementSrv::TYPENAME={"Srv"}; RuleElementSrv::RuleElementSrv() {} int RuleElementSrv::getAnyElementId() const { return FWObjectDatabase::ANY_SERVICE_ID; } xmlNodePtr RuleElementSrv::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementSrv::validateChild(FWObject *o) { if (FWServiceReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ServiceGroup::validateChild(o); } const char *RuleElementItf::TYPENAME={"Itf"}; RuleElementItf::RuleElementItf() {} int RuleElementItf::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementItf::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementItf::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if (o->getId() == getAnyElementId()) return true; if (Interface::cast(o)!=NULL) return true; if (ObjectGroup::cast(o)!=NULL && o->size() > 0) { bool all_intf = true; for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) { FWObject *o1 = FWReference::getObject(*i); if (!Interface::isA(o1)) { all_intf = false; break; } } return all_intf; // group is allowed if all members are interfaces } return false; } /* * this method checks if an object 'o' is a child of the same firewall * this rule element belongs to * * Note: when an object is being inserted into a rule using clipboard * (copy/paste), the object 'o' is in fact a copy of the original * object. This causes problems because the copy does not have any * parent and hence we can not simply traverse up the tree using * getParent(). We have to take its ID, find the original (clipboard * copy has the same ID as the original) and then walk up the tree * starting from it. This also means that if an object was placed into * clipboard using 'cut', it won't validate because the original has * lost its parent. * * After implementing undo(), we now run into the same problem with * the rule element object because the GUI tries to call addRef() * using a copy of the RuleElement object (the copy is a part of the * undo command) and this copy does not have any parent either. The * trick with using object Id does not work in this case though * because the copy of RuleElement stored in the command has different * ID. Will call this function from the GUI to do additional check * where appropriate, but validateChild() will accept any Interface * object. */ bool RuleElementItf::checkItfChildOfThisFw(FWObject *o) { if (Group::cast(o) != NULL) { for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) { FWObject *o1 = FWReference::getObject(*i); if (!checkItfChildOfThisFw(o1)) return false; } return true; } FWObject* o_tmp = getRoot()->findInIndex(o->getId()); FWObject* o_tmp2 = getRoot()->findInIndex(this->getId()); FWObject *fw1 = o_tmp; while (fw1 && Firewall::cast(fw1) == NULL) fw1 = fw1->getParent(); FWObject *fw2 = o_tmp2; while (fw2 && Firewall::cast(fw2) == NULL) fw2 = fw2->getParent(); return (fw1 != NULL && fw1 == fw2); } const char *RuleElementItfInb::TYPENAME={"ItfInb"}; RuleElementItfInb::RuleElementItfInb() {} const char *RuleElementItfOutb::TYPENAME={"ItfOutb"}; RuleElementItfOutb::RuleElementItfOutb() {} const char *RuleElementOSrc::TYPENAME={"OSrc"}; RuleElementOSrc::RuleElementOSrc() {} int RuleElementOSrc::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementOSrc::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementOSrc::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementODst::TYPENAME={"ODst"}; RuleElementODst::RuleElementODst() {} int RuleElementODst::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementODst::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementODst::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementOSrv::TYPENAME={"OSrv"}; RuleElementOSrv::RuleElementOSrv() {} int RuleElementOSrv::getAnyElementId() const { return FWObjectDatabase::ANY_SERVICE_ID; } xmlNodePtr RuleElementOSrv::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementOSrv::validateChild(FWObject *o) { if (FWServiceReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ServiceGroup::validateChild(o); } const char *RuleElementTSrc::TYPENAME={"TSrc"}; RuleElementTSrc::RuleElementTSrc() {} int RuleElementTSrc::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementTSrc::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementTSrc::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementTDst::TYPENAME={"TDst"}; RuleElementTDst::RuleElementTDst() {} int RuleElementTDst::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementTDst::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementTDst::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementTSrv::TYPENAME={"TSrv"}; RuleElementTSrv::RuleElementTSrv() {} int RuleElementTSrv::getAnyElementId() const { return FWObjectDatabase::ANY_SERVICE_ID; } xmlNodePtr RuleElementTSrv::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementTSrv::validateChild(FWObject *o) { if (FWServiceReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; // TagService is not allowed in translated service if (TagService::isA(o)) return false; if (ServiceGroup::cast(o)!=NULL) { for (FWObject::iterator i=o->begin(); i!=o->end(); ++i) { FWObject *o1 = FWReference::getObject(*i); if (!validateChild(o1)) return false; } } return ServiceGroup::validateChild(o); } const char *RuleElementInterval::TYPENAME={"When"}; RuleElementInterval::RuleElementInterval() {} int RuleElementInterval::getAnyElementId() const { return FWObjectDatabase::ANY_INTERVAL_ID; } xmlNodePtr RuleElementInterval::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementInterval::validateChild(FWObject *o) { if (FWIntervalReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return (Interval::cast(o)!=NULL || IntervalGroup::cast(o)!=NULL); } const char *RuleElementRDst::TYPENAME={"RDst"}; RuleElementRDst::RuleElementRDst() {} int RuleElementRDst::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementRDst::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementRDst::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if ( o->getId() == getAnyElementId()) return true; return ObjectGroup::validateChild(o); } const char *RuleElementRGtw::TYPENAME={"RGtw"}; RuleElementRGtw::RuleElementRGtw() {} int RuleElementRGtw::getAnyElementId() const { return FWObjectDatabase::ANY_ADDRESS_ID; } xmlNodePtr RuleElementRGtw::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = RuleElement::toXML(parent); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } bool RuleElementRGtw::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if( getChildrenCount() > 0 && !isAny()) return false; return checkSingleIPAdress(o); } // check if the gateway has only one interface with only one ipv4 adress bool RuleElementRGtw::checkSingleIPAdress(FWObject *o) { if( Host::cast(o) != NULL) { list obj_list = o->getByType("Interface"); if( obj_list.size() == 1) { obj_list = (obj_list.front())->getByType("IPv4"); if( obj_list.size() == 1) { return true; } else return false; } else return false; } else if( Interface::cast(o) != NULL) { list obj_list = o->getByType("IPv4"); if( obj_list.size() == 1) { return true; } else return false; } return ( o->getId() == getAnyElementId() || (FWObject::validateChild(o) && (IPv4::cast(o)!=NULL || FWObjectReference::cast(o)!=NULL))); } const char *RuleElementRItf::TYPENAME={"RItf"}; RuleElementRItf::RuleElementRItf() {} bool RuleElementRItf::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; if (getChildrenCount() > 0 && !isAny()) return false; if ( o->getId() == getAnyElementId()) return true; return (Interface::cast(o)!=NULL); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObject.h0000644000175000017500000005327211733011756024636 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOBJECT_HH_FLAG__ #define __FWOBJECT_HH_FLAG__ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include #include #include #include #include #include #include "fwbuilder/FWException.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/Dispatch.h" namespace libfwbuilder { class FWObject; class FWObjectDatabase; class FWReference; class FWObjectTypedChildIterator; class FWObjectFindPredicate; #define DECLARE_FWOBJECT_SUBTYPE(name) \ static const char *TYPENAME; \ virtual std::string getTypeName() const { return TYPENAME; } \ static bool isA(const FWObject *o) { return o && o->getTypeName()==TYPENAME; } \ static name* cast(FWObject *o) { return dynamic_cast(o); } \ static const name* constcast(const FWObject *o) { return dynamic_cast(o); } #define DECLARE_DISPATCH_METHODS(classname) \ virtual void* dispatch(Dispatch* _d, void* _a1) \ {return _d->dispatch(this, _a1); } \ virtual void* dispatch(Dispatch* _d, const void* _a1) \ {return _d->dispatch(this, _a1); } \ virtual void* dispatch(Dispatch* _d, void* _a1) const \ {return _d->dispatch(this, _a1); } \ virtual void* dispatch(Dispatch* _d, const void* _a1) const \ {return _d->dispatch(this, _a1); } \ virtual const void* const_dispatch(Dispatch* _d, void* _a1) const \ {return _d->const_dispatch(this, _a1); } \ virtual const void* const_dispatch(Dispatch* _d, const void* _a1) const \ {return _d->const_dispatch(this, _a1); } /** * This class represents base class for all * objects we are dealing with. * * FWObject can have children, that is other objects of the same class * or derived classes which are included in this one */ class FWObject : public std::list { friend class libfwbuilder::FWObjectDatabase; private: int ref_counter; FWObject *parent; /** * dbroot is a pointer to the database root. Method getRoot * returns this. We need this pointer because most of the time we * create an object first, make some manipulations with it (such * as create its children and/or add copies of children objects) * and only then put it in its place in the tree. This means the * object does not have valid parent pointer for a while, yet we * must be able to work with it. Many methods rely on being able * to reach the root of the tree (FWObjectDatabase object) for * things like setting 'dirty' flag etc. Therefore we need to * store the pointer to the root as soon as possible after we * create the object. The 'parent' pointer, on the other hand, is * stored once the object is added to the tree. * * dbroot is assigned by method FWObjectDatabase::create */ FWObjectDatabase *dbroot; int id; bool ro; std::string name; std::string comment; static std::string NOT_FOUND; time_t creation_time; std::set keywords; static std::string dataDir; protected: std::string xml_name; bool busy; bool dirty; std::map data; std::map private_data; void clearRefCounter() { ref_counter=0; } void _removeAll(FWObject *rm); void _removeAllRef(FWObject *rm); void _adopt(FWObject *obj); // increments reference void _findDependencies_internal(FWObject *obj, std::list &deps, int anti_loop_id); void setRO(bool f) { ro = f; } virtual void replaceReferenceInternal(int oldfw_id, int newfw_id, int &counter); /** * Finds direct child of this object with given name. */ FWObject* _find(const std::string& name) const; /** * Finds all references to the object 'obj' in object * tree starting from 'this' and address them to resulting * set. */ virtual void findAllReferences(const FWObject *obj, std::set &res); /** * internal method: update references to other objects this object * might keep in attributes. Example of this is reference to * branch rule set that is stored as its string ID in RuleOptions * object. Eventually we must fix these and make these references * either use FWReference child object or be normal C++ * pointers. Meanwhile, this virtual method is called from * FWObjectDatabase::_set_predictable_str_ids_recursively() when string * ids are replaced (and possibly from other places for similar reasons). */ virtual void updateNonStandardObjectReferences(); FWObject(); // special constructor used to create FWObjectDatabase objects FWObject(bool new_id); public: DECLARE_FWOBJECT_SUBTYPE(FWObject); DECLARE_DISPATCH_METHODS(FWObject); class tree_iterator { friend class libfwbuilder::FWObject; FWObject *node; public: tree_iterator() { node=NULL; } tree_iterator(FWObject *_n) { node=_n; } tree_iterator(const tree_iterator &ti) { node=ti.node; } FWObject* operator*() { return node; } tree_iterator& operator++(); tree_iterator operator++(int); tree_iterator& operator=(const tree_iterator &ti) { node=ti.node; return *this; } bool operator==(const tree_iterator& i) const; bool operator!=(const tree_iterator& i) const; }; tree_iterator tree_begin(); tree_iterator tree_end(); FWObject(const FWObject ©); /** * This method should create any standard mandatory child objects * the object might need. The function should not require that the * object be already added to the object tree but can use provided * pointer to FWObjectDatabase to create other objects it might * need to add as children. */ virtual void init(FWObjectDatabase *root); int getId() const; void setId(int i); bool haveId() { return (id != -1); } /** * getRO() simply returns value of private member ro. Note the * difference between _getRO and isReadOnly() - the latter checks * if any parent of this object is read-only in addition to * checking if this object is read-only itself. */ bool getRO() const { return ro; } virtual void fromXML(xmlNodePtr xml_parent_node) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); xmlNodePtr toXML(xmlNodePtr xml_parent_node, bool process_children) throw(FWException); /** * Rarely used feature: we can change the name of XML element * represented by the class derived from FWObject if we want to. For * example, used in all "Any" objects so we did not have to create extra * classes * */ void setXMLName (const std::string &); virtual ~FWObject(); int ref() { ++ref_counter; return(ref_counter); } int unref() { --ref_counter; return(ref_counter); } int getRefCounter() { return(ref_counter); } /** * It is same as calling duplicate(x, FALSE); */ virtual FWObject& operator=(const FWObject &) throw(FWException); /** * This method copies content of object 'x' in the object 'this'. * depending on 'preserve_id' flag, Id are either copied or new * ones are issued. All children of 'this' are destroyed and new ones * are created recursively as copies of corresponding children of obj. */ virtual FWObject& duplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); /** * This method works just like duplicate, except it does not destroy * or change children of 'this'. */ virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); /** * This method copies all attributes of obj into this, plus * FWOptions child object if it exists but no other * children. Combination of attributes of the object plus its * option child object describe all parameters of the object and * should be sufficient to properly roll back or redo any changes. * Changes done to its children should be undone or redone using * corresponding objects. */ virtual FWObject& duplicateForUndo(const FWObject *obj) throw(FWException); /** * This method creates a copy of object 'x' and adds it to 'this'. * Depending on 'preserve_id' flag, Id are either copied or new * ones are issued. */ virtual FWObject* addCopyOf(const FWObject *obj, bool preserve_id = true) throw(FWException); /** * compares objects. Ignores ID and always looks at * attributes. Returns true if objects are equal. */ virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); void Show(); void Hide(); FWObject* getParent() const; void setParent(FWObject *p); bool exists(const std::string &name) const; void remStr(const std::string &name); const std::string &getStr(const std::string& name) const; void setStr(const std::string &name, const std::string &val); int getInt(const std::string &name) const; void setInt(const std::string &name, int val); bool getBool(const std::string &name) const; void setBool(const std::string &name, bool val); void setBool(const std::string &name, const std::string &val); const std::string &getName() const; void setName(const std::string& n); const std::string &getComment() const; void setComment(const std::string& c); void storeCreationTime() { creation_time = time(NULL); } time_t getCreationTime() { return creation_time; } void setPrivateData(const std::string &key, void *data); void* getPrivateData(const std::string &key) const; std::map &getAllPrivateData(); /** * convenience method: returns the name of the library this object belongs to. * In fwbuilder2 library is an element directly under FWObjectDatabase; all * other objects are children of a Library object */ const std::string &getLibraryName() const; /** * returns a pointer to the library object 'this' is a part of. */ FWObject* getLibrary() const; /** * Returns root of the objects tree this object is part of */ FWObjectDatabase* getRoot() const; int getDistanceFromRoot() const; /* How many parents does this have? */ /** * Sets pointer to the database root */ void setRoot(const FWObjectDatabase *_dbroot) { dbroot = (FWObjectDatabase*)_dbroot; } /** * Returns a string that represents a path to the object * 'this'. Path is built using names of objects above 'this', * all the way to the root of the tree. If parameter 'relative' * is true, the path is built relative to the library 'this' is * a part of (name of the library is not included). */ std::string getPath(bool relative=false, bool detailed=false) const; void addAt(int where_id, FWObject *obj); virtual void add(FWObject *obj,bool validate=true); virtual void insert_before(FWObject *o1,FWObject *obj); virtual void insert_after(FWObject *o1,FWObject *obj); /** * call add(), but first remove() object from its old parent */ virtual void reparent(FWObject *obj,bool validate=true); /** * In direct children of 'this' swaps all references * to o1 with o2 and vice versa. */ virtual void swapObjects(FWObject *o1,FWObject *o2); /** * Finds first instance of 'obj' in children of this * object and removes if. If 'obj' reference counter * reaches 0 it is also deleted. */ virtual void remove(FWObject *obj, bool delete_if_last=true); /** * Finds and removes instances of 'obj' recursively in the * whole tree under this object */ virtual void removeAllInstances(FWObject *obj); /** * Adds reference object pointing to 'obj' as a child of 'this' */ virtual void addRef(FWObject *obj); /** * Removes reference to given object among * children of 'this'. */ virtual void removeRef(FWObject *obj); /** * check if 'this' already has reference to obj */ virtual bool hasRef(FWObject *obj); /** * Removes all references to 'obj' recursively in the whole tree * under 'this' */ virtual void removeAllReferences(FWObject *obj); /** * Finds all references to the object 'obj' in object * tree starting from 'this'. */ virtual std::set findAllReferences(const FWObject *obj); /* * Create appropriate reference object for itself. * Different object require different class of reference. e.g.: * for Host reference should be of class FWObjectReference * for Service reference should be of class FWServiceReference */ virtual FWReference* createRef(); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); /** * forcefully destroys all objects in the subtree under this, * except this. This method ignores reference counters and simply * deletes everything. */ void destroyChildren(); void clearChildren(bool recursive=true); void sortChildrenByName(bool follow_references=false); /** * Walks the tree, looking for objects that are referenced by two parents * or those with this->parent == NULL. Prints report to stderr and * returns true if such objects have been found. */ bool verifyTree(); /** * sometimes we need to move object subtree from one object * database to another. For example, this can be a useful * mechanism to maintain persistent objects between compiler * passes. However when the object and its children are added to * the new tree, "parent" and "root" pointers in obejcts still * point to the old object tree and need to be fixed. */ void fixTree(); int getChildrenCount() const; virtual void dump(bool recursive,bool brief,int offset=0) const; virtual void dump(std::ostream &f,bool recursive,bool brief,int offset=0) const; /** * returns true if this is either direct child of obj, or a child * of one of its children and so on (this method works recursively). */ bool isChildOf(FWObject *obj); bool hasChild(FWObject *obj); /** * Returns object with given ID. If recursive is 'false' * search is restricted to direct children of given object * and itslef. If it is true, method proceeds to all chidren of all * objects starting from current one. */ virtual FWObject* getById(int id, bool recursive=false); /** * Returns list of direct children of current object whose * getTypeName() is equal type_name. If not found, empty list is * returned. */ virtual std::list getByType(const std::string &type_name) const; /** * Returns list of children of current object whose getTypeName() * is equal type_name. If not found, empty list is * returned. Search recursively including all direct children of this. */ virtual std::list getByTypeDeep(const std::string &type_name) const; /** * Returns list of direct children of current object * whose getTypeName() same as given. * If not found, end() is returned. */ virtual FWObjectTypedChildIterator findByType( const std::string &type_name) const; /** * Returns first of direct children of current object * whose getTypeName() same as given or NULL if not found. */ virtual FWObject* getFirstByType(const std::string &type_name) const; /** * finds a child object of a given type with a given name */ FWObject* findObjectByName(const std::string &type, const std::string &name) throw(FWException); /** * finds a child object of a given type with an attribute attr */ FWObject* findObjectByAttribute(const std::string &attr, const std::string &val) throw(FWException); /** * Generic find function, finds all objects in the tree rooted at * that match given predicate. Fills @res_list with * pointers to the objects it finds. */ std::list findIf(FWObjectFindPredicate *pred); /** * if this object has any references as its children, replace IDs * these references point to. */ virtual int replaceRef(int oldfw_id, int newfw_id); /** * recursively find all FWReference objects that are children of * this and generate list of pointers to the objects these * references point to. */ void findDependencies(std::list &deps); virtual void setDirty(bool f); virtual bool isDirty(); /** * sets read-only flag for the object. FWObject checks all objects * up in the tree before making any change to see if the subtree * is read-only. Marking an object read-only automatically makes * the whole tree branch under it read-only. */ virtual void setReadOnly(bool f); virtual bool isReadOnly(); virtual void checkReadOnly() throw(FWException); /** * return true if this object can be copied around and put in the * tree in one of the system folders. False if it must be a child * of some other primary obejct. The latter category includes * physAddress, interface, IPv4 and IPv6 if they are children of * interface, rulesets, rule elements and rules. */ virtual bool isPrimaryObject() const; // Attributes iterator std::map::const_iterator dataBegin() { return data.begin(); } std::map::const_iterator dataEnd() { return data.end(); } const std::set &getKeywords() { return keywords; } const std::set &getAllKeywords(); void addKeyword(const std::string &keyword); void removeKeyword(const std::string &keyword); void clearKeywords(); static std::string getDataDir() { return dataDir; } static void setDataDir(const std::string &dir) { dataDir = dir; } }; class FWObjectTypedChildIterator { public: FWObjectTypedChildIterator(); FWObjectTypedChildIterator(const FWObjectTypedChildIterator &o); FWObjectTypedChildIterator(const FWObject *o, const std::string &_type_name); bool operator==(const FWObject::const_iterator& __x) const; bool operator!=(const FWObject::const_iterator& __x) const; FWObject *operator*() const; FWObjectTypedChildIterator& operator++(); FWObjectTypedChildIterator& operator--(); const FWObject::const_iterator &begin() { return _begin; } const FWObject::const_iterator & end() { return _end ; } protected: std::string type_name; FWObject::const_iterator real_iterator; FWObject::const_iterator _begin; FWObject::const_iterator _end; void init(const FWObject *o, const std::string &_type_name); }; /** * Predicate class testing object pointers for name eqivalence. * name is obtained by calling getName() method. * This class could be used in STL Algoriths find_if, and others. */ class FWObjectNameEQPredicate: public std::unary_function { std::string n; public: FWObjectNameEQPredicate(const std::string &name):n(name) {} bool operator()(const FWObject *o) const { return o->getName()==n; } }; struct FWObjectNameCmpPredicate : public std::binary_function { bool follow_references; FWObjectNameCmpPredicate(bool follow_refs=false); bool operator()(FWObject *a,FWObject *b); }; class findFWObjectIDPredicate : public std::unary_function { int _id; public: findFWObjectIDPredicate(int id):_id(id) {} bool operator()(const FWObject *o) const {return o->getId()==_id;} }; /** * Predicate class testing object pointers for type name eqivalence. * name is obtained by calling getTypeName() method. * This class could be used in STL Algoriths find_if, and others. */ class FWObjectTypeNameEQPredicate: public std::unary_function { std::string n; public: FWObjectTypeNameEQPredicate(const std::string &name):n(name) {} bool operator()(const FWObject *o) const { return o->getTypeName()==n; } }; /** * Generic predicate class testing any object parameters, used for findIf. */ class FWObjectFindPredicate { public: FWObjectFindPredicate() {} virtual ~FWObjectFindPredicate() {} virtual bool operator()(FWObject*) const { std::cerr << "#"; return false; } }; } #endif // _FWOBJECT_HH fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Inet6AddrMask.h0000644000175000017500000000323411733011756025560 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This class is a holder of a pair address / netmask. * It can act both as a container for the address/netmask configuration * data (such as for an interface) or as a network. * */ #ifndef __INET6ADDRMASK_HH_FLAG__ #define __INET6ADDRMASK_HH_FLAG__ #include #include #ifndef _WIN32 # include # include # include # include #else # include #endif #include "fwbuilder/FWException.h" #include "fwbuilder/InetAddrMask.h" namespace libfwbuilder { class Inet6AddrMask : public InetAddrMask { protected: public: Inet6AddrMask(); Inet6AddrMask(const std::string &s) throw(FWException); Inet6AddrMask(const InetAddr&, const InetAddr&); virtual ~Inet6AddrMask(); virtual std::string toString() const; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Resources.cpp0000644000175000017500000003660711733011756025503 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #ifndef _WIN32 # include # include #endif #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Host.h" #include "fwbuilder/Tools.h" using namespace libfwbuilder; using namespace std; const string Resources::PLATFORM_RES_DIR_NAME = "platform"; const string Resources::OS_RES_DIR_NAME = "os"; Resources* Resources::global_res = NULL; map Resources::platform_res; map Resources::os_res; Resources::Resources() throw(FWException) { doc=NULL; } Resources::Resources(const string &_resF) throw(FWException) { doc = NULL; resfile = _resF; if (global_res==NULL) { global_res = this; loadRes(_resF); loadSystemResources(); } else loadRes(_resF); } Resources::~Resources() { if (doc) xmlFreeDoc(doc); } void Resources::clear() { for (map::iterator it=platform_res.begin(); it!=platform_res.end(); ++it) { delete it->second; } platform_res.clear(); for (map::iterator it=os_res.begin(); it!=os_res.end(); ++it) { delete it->second; } os_res.clear(); } string Resources::getXmlNodeContent(xmlNodePtr node) { string res; char* cptr= (char*)( xmlNodeGetContent(node) ); if (cptr!=NULL) { res=cptr; FREEXMLBUFF(cptr); } return res; } string Resources::getXmlNodeProp(xmlNodePtr node,string prop) { string res; char* cptr=(char*)( xmlGetProp(node,TOXMLCAST(prop.c_str()))); if (cptr!=NULL) { res=cptr; FREEXMLBUFF(cptr); } return res; } void Resources::loadRes(const std::string &rfile ) throw(FWException) { string buffer = XMLTools::readFile(rfile); doc = xmlParseMemory(buffer.c_str(), buffer.length()); // doc = xmlParseFile(rfile.c_str()); // doc = XMLTools::loadAndParseFile(rfile); if (!doc) throw FWException("Error parsing "+rfile); root = xmlDocGetRootElement(doc); if(!root || !root->name || strcmp(FROMXMLCAST(root->name), "FWBuilderResources")!=0) { xmlFreeDoc(doc); throw FWException("Invalid resources file "+rfile); } } void Resources::loadSystemResources() throw(FWException) { /* * Find and open resources for individual firewall platforms and OS. * If corresponding directory does not exist or is empty, then no * target platform support package is installed. So be it, not my * problem */ // string resDir=Constants::getTemplateDirectory(); string::size_type n=resfile.find_last_of("/\\"); string resDir = resfile.substr(0,n); list pllist = getDirList( resDir + FS_SEPARATOR +PLATFORM_RES_DIR_NAME, "xml" ); for (list::iterator lsi1=pllist.begin(); lsi1!=pllist.end(); lsi1++) { string::size_type n=lsi1->find_last_of("/\\")+1; string platform=lsi1->substr(n, lsi1->rfind(".xml")-n); Resources *tr=new Resources(*lsi1); platform_res[platform]=tr; } list oslist = getDirList( resDir + FS_SEPARATOR +OS_RES_DIR_NAME, "xml" ); for (list::iterator lsi2=oslist.begin(); lsi2!=oslist.end(); lsi2++) { string::size_type n=lsi2->find_last_of("/\\")+1; string os=lsi2->substr(n, lsi2->rfind(".xml")-n); Resources *tr=new Resources(*lsi2); os_res[os]=tr; } #if 0 cerr << "Loaded resources for the following modules :\n"; map p=getPlatforms(); map::iterator i1; for (i1=p.begin(); i1!=p.end(); ++i1) { cerr << (*i1).first << " " << (*i1).second << endl; } p=getOS(); for (i1=p.begin(); i1!=p.end(); ++i1) { cerr << (*i1).first << " " << (*i1).second << endl; } #endif } xmlNodePtr Resources::getXmlNode(const string& path) { return XMLTools::getXmlNodeByPath(root,path); } string Resources::getIconPath(const char* icon) { string icn; icn= getResourceStr("/FWBuilderResources/Paths/Icndir"); icn += "/"; icn += getResourceStr(string("/FWBuilderResources/UI/Icons/")+icon); return icn; } string Resources::getIconPath(const string& icon) { return getIconPath(icon.c_str()); } string Resources::getResourceStr(const string& resource_path) { xmlNodePtr node=XMLTools::getXmlNodeByPath(root,resource_path.c_str()); if (node) return getXmlNodeContent(node); return ""; } int Resources::getResourceInt(const string& resource_path) { return atoi(getResourceStr(resource_path).c_str()); } bool Resources::getResourceBool(const string& resource_path) { string res=getResourceStr(resource_path); return (res=="true" || res=="True"); } /* * Adds bodies of xml elements found directly under resource_path to * the list res * * * * value1 * value2 * value3 * value4 * * * * here resorce_path="/element1/element2", returned list consists of * strings value1,value2,value3,value4 */ void Resources::getResourceStrList(const string& resource_path, list &res) { xmlNodePtr node = XMLTools::getXmlNodeByPath(root, resource_path.c_str()); if (node) { xmlNodePtr c; for(c=node->xmlChildrenNode; c; c=c->next) { if ( xmlIsBlankNode(c) ) continue; res.push_back(getXmlNodeContent(c)); } } } string Resources::getObjResourceStr(const FWObject *obj, const string& resource_name) { string objid = FWObjectDatabase::getStringId(obj->getId()); string objtype = obj->getTypeName(); string res; string resource="/FWBuilderResources/Object/"+objid+"/"+resource_name; res= getResourceStr(resource); if (res.empty()) { string resource="/FWBuilderResources/Type/"+objtype+"/"+resource_name; res= getResourceStr(resource); if (res.empty()) { resource="/FWBuilderResources/Type/DEFAULT/"+resource_name; res= getResourceStr(resource); } } if (res.empty()) cerr << "Failed to locate resource for object " << obj->getName() << " (type=" << objtype << "), " << " (id=" << obj->getId() << "), resource name: " << resource_name << endl; return res; } bool Resources::getObjResourceBool(const FWObject *obj, const string& resource_name) { string res=getObjResourceStr(obj,resource_name); return (res=="true" || res=="True"); } /* * call this using appropriate Resources object, like this: * * platform_res["iptables"]->getVersion() */ string Resources::getVersion() { xmlNodePtr pn=getXmlNode("/FWBuilderResources/"); return getXmlNodeProp(pn,"version"); } /* * call this using appropriate Resources object, like this: * * platform_res["iptables"]->getCompiler() */ string Resources::getCompiler() { return getResourceStr("/FWBuilderResources/Target/compiler"); } string Resources::getInstaller() { return getResourceStr("/FWBuilderResources/Target/installer"); } string Resources::getTransferAgent() { return getResourceStr("/FWBuilderResources/Target/transfer_agent"); } vector Resources::getListOfPlatforms() { vector vs; for (map::iterator i1=platform_res.begin(); i1!=platform_res.end(); ++i1) { vs.push_back( (*i1).first ); } return vs; } map Resources::getPlatforms() { map vs; for (map::iterator i1=platform_res.begin(); i1!=platform_res.end(); ++i1) { Resources *res = (*i1).second; if (res) { string desc = res->getResourceStr( "/FWBuilderResources/Target/description"); vs[ (*i1).first ]=desc; } } return vs; } map Resources::getOS() { map vs; for (map::iterator i1=os_res.begin(); i1!=os_res.end(); ++i1) { Resources *res = (*i1).second; if (res) { string desc = res->getResourceStr( "/FWBuilderResources/Target/description"); vs[ (*i1).first ]=desc; } } return vs; } string Resources::getRuleElementResourceStr(const string &rel, const string &resource_name) { xmlNodePtr c,d; xmlNodePtr dptr=Resources::global_res->getXmlNode("FWBuilderResources/RuleElements"); assert (dptr!=NULL); for(c=dptr->xmlChildrenNode; c; c=c->next) { if ( xmlIsBlankNode(c) ) continue; if (rel==getXmlNodeProp(c,"RuleElement")) { d=XMLTools::getXmlChildNode(c,resource_name.c_str()); if (d) { return getXmlNodeContent(d); } } } return string(""); } bool Resources::isSystem(const FWObject *o) { return global_res->getObjResourceBool(o, "system"); } string Resources::getIconFileName(const FWObject *o) { string res; res=global_res->getResourceStr("/FWBuilderResources/Paths/Icndir"); res += "/"; res += global_res->getObjResourceStr(o, "icon"); return res; } string Resources::getNegIconFileName(const FWObject *o) { string res; res=global_res->getResourceStr("/FWBuilderResources/Paths/Icndir"); res += "/"; res += global_res->getObjResourceStr(o, "icon-neg"); return res; } string Resources::getRefIconFileName(const FWObject *o) { string res; res=global_res->getResourceStr("/FWBuilderResources/Paths/Icndir"); res += "/"; res += global_res->getObjResourceStr(o, "icon-ref"); return res; } string Resources::getTreeIconFileName(const FWObject *o) { string res; res=global_res->getResourceStr("/FWBuilderResources/Paths/Icndir"); res += "/"; res += global_res->getObjResourceStr(o, "icon-tree"); return res; } void Resources::setDefaultOption(FWObject *o,const string &xml_node) { xmlNodePtr pn = XMLTools::getXmlNodeByPath(root,xml_node.c_str()); if (pn==NULL) return; string optname=FROMXMLCAST(pn->name); string optval =getXmlNodeContent(pn); o->setStr(optname , optval); } void Resources::setDefaultOptionsAll(FWObject *o,const string &xml_node) { xmlNodePtr pn = XMLTools::getXmlNodeByPath(root , xml_node.c_str() ); if (pn==NULL) return; xmlNodePtr opt; for(opt=pn->xmlChildrenNode; opt; opt=opt->next) { if ( xmlIsBlankNode(opt) ) continue; setDefaultOption(o,xml_node+"/"+FROMXMLCAST(opt->name)); } } void Resources::setDefaultTargetOptions(const string &target,Firewall *fw) throw (FWException) { FWOptions *opt=fw->getOptionsObject(); Resources *r=NULL; if (platform_res.count(target)!=0) r=platform_res[target]; if (r==NULL && os_res.count(target)!=0) r=os_res[target]; if (r==NULL) throw FWException("Support module for target '"+target+"' is not available"); r->setDefaultOptionsAll(opt,"/FWBuilderResources/Target/options/default"); } void Resources::setDefaultIfaceOptions(const string &target,Interface *iface) throw (FWException) { FWOptions *opt=iface->getOptionsObject(); /* if InterfaceOptions object does not yet exist -> create one */ if (opt == NULL) { iface->add(iface->getRoot()->create(InterfaceOptions::TYPENAME)); opt = iface->getOptionsObject(); } Resources *r=NULL; if (platform_res.count(target)!=0) r=platform_res[target]; if (r==NULL && os_res.count(target)!=0) r=os_res[target]; if (r==NULL) throw FWException("Support module for target '"+target+"' is not available"); r->setDefaultOptionsAll(opt,"/FWBuilderResources/Target/options/interface"); } void Resources::setDefaultOptions(Host *h) { FWOptions *opt=h->getOptionsObject(); global_res->setDefaultOptionsAll(opt, "/FWBuilderResources/Type/"+h->getTypeName()+"/options"); } void Resources::setDefaultProperties(FWObject *obj) { global_res->setDefaultOptionsAll(obj, "/FWBuilderResources/Type/"+obj->getTypeName()+"/properties"); } string Resources::getTargetCapabilityStr(const string &target, const string &cap_name) throw (FWException) { Resources *r=NULL; if (platform_res.count(target)!=0) r=platform_res[target]; if (r==NULL && os_res.count(target)!=0) r=os_res[target]; if (r==NULL) throw FWException("Support module for target '"+target+"' is not available"); return r->getResourceStr("/FWBuilderResources/Target/capabilities/"+cap_name); } bool Resources::getTargetCapabilityBool(const string &target, const string &cap_name) throw (FWException) { string s=getTargetCapabilityStr(target,cap_name); return (s=="true" || s=="True"); } bool Resources::isTargetActionSupported(const string &target, const string &action) { bool res=false; try { res = getTargetCapabilityBool(target, "actions/" + action + "/supported"); } catch (FWException &ex) { } return res; } string Resources::getActionEditor(const string &target, const string &action) { string res="None"; try { res = getTargetCapabilityStr(target, "actions/" + action + "/parameter"); } catch (FWException &ex) { } return res; } string Resources::getTargetOptionStr(const string &target, const string &opt_name) throw (FWException) { Resources *r=NULL; if (platform_res.count(target)!=0) r=platform_res[target]; if (r==NULL && os_res.count(target)!=0) r=os_res[target]; if (r==NULL) throw FWException("Support module for target '"+target+"' is not available"); return r->getResourceStr("/FWBuilderResources/Target/options/"+opt_name); } bool Resources::getTargetOptionBool(const string &target, const string &opt_name) throw (FWException) { string s=getTargetOptionStr(target,opt_name); return (s=="true" || s=="True"); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPService.cpp0000644000175000017500000001154311733011756025352 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/IPService.h" #include "fwbuilder/XMLTools.h" #include using namespace libfwbuilder; using namespace std; const char *IPService::TYPENAME={"IPService"}; std::map IPService::named_protocols; void IPService::initNamedProtocols() { if (IPService::named_protocols.size() == 0) { IPService::named_protocols[0] = "ip"; IPService::named_protocols[1] = "icmp"; IPService::named_protocols[6] = "tcp"; IPService::named_protocols[17] = "udp"; } } IPService::IPService() { setStr("protocol_num", ""); IPService::initNamedProtocols(); } IPService::~IPService() {} void IPService::addNamedProtocol(int proto_num, const std::string &proto_name) { // Call initialize function because we might be trying to register // named protocol before any IPService objects have been created. IPService::initNamedProtocols(); IPService::named_protocols[proto_num] = proto_name; } void IPService::setProtocolNumber(int n) { setInt("protocol_num", n); } string IPService::getProtocolName() const { int proto_num = getInt("protocol_num"); if (IPService::named_protocols.count(proto_num) > 0) return IPService::named_protocols[proto_num]; else return getStr("protocol_num"); } int IPService::getProtocolNumber() const { return getInt("protocol_num"); } void IPService::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("protocol_num"))); assert(n!=NULL); setStr("protocol_num", n); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("fragm"))); if(n!=NULL) { setStr("fragm", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("short_fragm"))); if(n!=NULL) { setStr("short_fragm", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("any_opt"))); if(n!=NULL) { setStr("any_opt", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("lsrr"))); if(n!=NULL) { setStr("lsrr", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("ssrr"))); if(n!=NULL) { setStr("ssrr", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("rr"))); if(n!=NULL) { setStr("rr", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("ts"))); if(n!=NULL) { setStr("ts", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("tos"))); if(n!=NULL) { setStr("tos", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dscp"))); if(n!=NULL) { setStr("dscp", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("rtralt"))); if(n!=NULL) { setStr("rtralt", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("rtralt_value"))); if(n!=NULL) { setStr("rtralt_value", n); FREEXMLBUFF(n); } } xmlNodePtr IPService::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } bool IPService::hasIpOptions() const { return (getBool("any_opt") || getBool("lsrr") || getBool("rr") || getBool("ssrr") || getBool("ts") || getBool("rtralt")); } string IPService::getTOSCode() const { return getStr("tos"); } void IPService::setTOSCode(const string &c) { setStr("tos", c); } string IPService::getDSCPCode() const { return getStr("dscp"); } void IPService::setDSCPCode(const string &c) { setStr("dscp", c); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/StateSyncClusterGroup.cpp0000644000175000017500000000302711733011756030013 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FWOptions.h" using namespace std; using namespace libfwbuilder; const char *StateSyncClusterGroup::TYPENAME = {"StateSyncClusterGroup"}; StateSyncClusterGroup::StateSyncClusterGroup() : ClusterGroup() { setStr("type", ""); } void StateSyncClusterGroup::fromXML(xmlNodePtr parent) throw(FWException) { ClusterGroup::fromXML(parent); // Read additional attributes here } xmlNodePtr StateSyncClusterGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = ClusterGroup::toXML(parent); // Save additional attributes here return me; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/NAT.h0000644000175000017500000000327111733011756023607 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NAT_HH_FLAG__ #define __NAT_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/RuleSet.h" namespace libfwbuilder { class NAT : public RuleSet { public: NAT(); virtual ~NAT(); DECLARE_FWOBJECT_SUBTYPE(NAT); DECLARE_DISPATCH_METHODS(NAT); /* the following methods provide proper typization */ NATRule* getRuleByNum(int n) { return NATRule::cast(RuleSet::getRuleByNum(n)); } NATRule* insertRuleAtTop() { return NATRule::cast(RuleSet::insertRuleAtTop()); } NATRule* insertRuleBefore(int n){ return NATRule::cast(RuleSet::insertRuleBefore(n));} NATRule* appendRuleAfter(int n){ return NATRule::cast(RuleSet::appendRuleAfter(n));} NATRule* appendRuleAtBottom(){ return NATRule::cast(RuleSet::appendRuleAtBottom());} virtual Rule* createRule(); }; } #endif //__NAT_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/StateSyncClusterGroup.h0000644000175000017500000000265211733011756027463 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __STATESYNCCLUSTERGROUP_HH_ #define __STATESYNCCLUSTERGROUP_HH_ #include "fwbuilder/ClusterGroup.h" namespace libfwbuilder { class StateSyncClusterGroup : public ClusterGroup { public: StateSyncClusterGroup(); virtual ~StateSyncClusterGroup() {}; DECLARE_FWOBJECT_SUBTYPE(StateSyncClusterGroup); DECLARE_DISPATCH_METHODS(StateSyncClusterGroup); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); }; } #endif /* __CLUSTERGROUP_HH_ */ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPv6.cpp0000644000175000017500000000777511733011756024321 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Class IPv6 serves two purposes: - it is used to describe configuration of an interface which consists of an address and netmask - it is used to describe a single standalone address object (in the tree, under Objects/Addresses) Even though class Network also has address and netmask, IPv6 objects are recognized by compilers as single addresses. */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include "fwbuilder/Inet6AddrMask.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/XMLTools.h" using namespace std; using namespace libfwbuilder; const char *IPv6::TYPENAME={"IPv6"}; IPv6::IPv6() : Address() { delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask(); } IPv6::~IPv6() { } FWObject& IPv6::shallowDuplicate(const FWObject *other, bool preserve_id) throw(FWException) { const IPv6* a_other = IPv6::constcast(other); assert(a_other); delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask( *(dynamic_cast(a_other->inet_addr_mask))); return FWObject::shallowDuplicate(other, preserve_id); } void IPv6::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char* n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address"))); assert(n!=NULL); setAddress(InetAddr(AF_INET6, n)); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("netmask"))); assert(n!=NULL); if (strlen(n)) { if (string(n).find(":")!=string::npos) { setNetmask(InetAddr(AF_INET6, n)); } else { istringstream str(n); int netm; str >> netm; setNetmask(InetAddr(AF_INET6, netm)); } } else setNetmask(InetAddr(AF_INET6, 0)); FREEXMLBUFF(n); } xmlNodePtr IPv6::toXML(xmlNodePtr xml_parent_node) throw(FWException) { if (getName().empty()) setName(getTypeName()); xmlNodePtr me = FWObject::toXML(xml_parent_node); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("address"), STRTOXMLCAST(inet_addr_mask->getAddressPtr()->toString())); // Save netmask as bit length ostringstream str; str << inet_addr_mask->getNetmaskPtr()->getLength(); xmlNewProp(me, TOXMLCAST("netmask"), STRTOXMLCAST(str.str())); return me; } void IPv6::setAddress(const InetAddr &a) { inet_addr_mask->setAddress(a); } void IPv6::setNetmask(const InetAddr &nm) { inet_addr_mask->setNetmask(nm); } void IPv6::setAddressNetmask(const std::string& s) { delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask(s); } void IPv6::dump(std::ostream &f,bool recursive,bool brief,int offset) const { FWObject::dump(f, recursive, brief, offset); f << inet_addr_mask->getAddressPtr()->toString() << endl; } bool IPv6::isPrimaryObject() const { return (!Interface::isA(getParent())); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Constants.cpp0000644000175000017500000000423511733011756025475 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" using namespace std; using namespace libfwbuilder; string Constants::res_dir; void Constants::init(const std::string &app_root_dir) { if (app_root_dir.empty()) res_dir = string(RES_DIR); else res_dir = app_root_dir + FS_SEPARATOR + string(RES_DIR); } const string Constants::getLibraryDescription() { return "Firewall Builder API "; } const string Constants::getLibraryVersion() { return string(VERSION); } const string Constants::getDataFormatVersion() { return string(FWBUILDER_XML_VERSION); } const string Constants::getTemplateDirectory() { return string(RES_DIR); } string Constants::getDTDDirectory() { if (res_dir.empty()) init(""); return res_dir; } string Constants::getResourcesDirectory() { if (res_dir.empty()) init(""); return res_dir; } string Constants::getResourcesFilePath() { return getResourcesDirectory() + FS_SEPARATOR + "resources.xml"; } string Constants::getStandardObjectsFilePath() { return getResourcesDirectory() + FS_SEPARATOR + "objects_init.xml"; } string Constants::getTemplatesObjectsFilePath() { return getResourcesDirectory() + FS_SEPARATOR + "templates.xml"; } string Constants::getLocaleDirectory() { return getResourcesDirectory() + "/locale"; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/DNSName.h0000644000175000017500000000321511733011756024410 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DNS_NAME_HH_FLAG__ #define __DNS_NAME_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/MultiAddress.h" namespace libfwbuilder { class DNSName : public MultiAddress { private: public: DECLARE_FWOBJECT_SUBTYPE(DNSName); DECLARE_DISPATCH_METHODS(DNSName); DNSName(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual std::string getSourceName(); virtual void setSourceName(const std::string& source_name); std::string getDNSRecordType(); void setDNSRecordType(const std::string& rectype); virtual void loadFromSource(bool ipv6, FWOptions *options, bool test_mode=false) throw(FWException); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/AddressRange.cpp0000644000175000017500000000743011733011756026063 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; const char *AddressRange::TYPENAME={"AddressRange"}; /** * Empty constructor. Make sure start and end addresses are * initialized to 0. */ AddressRange::AddressRange() : Address(), start_address(InetAddr::getAny()), end_address(InetAddr::getAny()) { Address::setNetmask(InetAddr::getAny()); } AddressRange::AddressRange(AddressRange &o) : Address() , start_address(o.getRangeStart()), end_address(o.getRangeEnd()) { FWObject::operator=(o); } const InetAddr* AddressRange::getAddressPtr() const { return &start_address; } unsigned int AddressRange::dimension() const { return start_address.distance(end_address); } void AddressRange::setAddress(const InetAddr &a) { setRangeStart(a); setRangeEnd(a); } void AddressRange::setNetmask(const InetAddr& ) {} FWObject& AddressRange::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { const AddressRange *n = dynamic_cast(o); if (n==NULL) throw(FWException( "Attempt to copy incompatible object to AddressRange: objectID="+o->getId())); start_address = n->getRangeStart(); end_address = n->getRangeEnd(); return FWObject::shallowDuplicate(o, preserve_id); } bool AddressRange::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (AddressRange::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; InetAddr o1b; InetAddr o1e; InetAddr o2b; InetAddr o2e; o1b = getRangeStart(); o1e = getRangeEnd(); o2b = AddressRange::constcast(obj)->getRangeStart(); o2e = AddressRange::constcast(obj)->getRangeEnd(); return (o1b==o2b && o1e==o2e); } void AddressRange::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("start_address"))); assert(n!=NULL); start_address = InetAddr(n); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("end_address"))); assert(n!=NULL); end_address = InetAddr(n); FREEXMLBUFF(n); } xmlNodePtr AddressRange::toXML(xmlNodePtr xml_parent_node) throw(FWException) { xmlNodePtr me = FWObject::toXML(xml_parent_node); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("start_address"), STRTOXMLCAST(start_address.toString())); xmlNewProp(me, TOXMLCAST("end_address"), STRTOXMLCAST(end_address.toString())); return me; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/libfwbuilder-config.h.in0000644000175000017500000000216711733011756027512 0ustar sylvestresylvestre #undef FWBUILDER_XML_VERSION #define FREEXMLBUFF(x) xmlFree((void*)(x)) /* * Template files directory dir * DO NOT USE THIS CONSTANT DIRECTLY - USE Constants class instead! */ #undef RES_DIR #undef HAVE_LIBSNMP #undef UCD_SNMP #undef NET_SNMP #undef HAVE_INET_NET_NTOP #undef HAVE_GOODLIBRESOLV #undef HAVE_LWRES #undef HAVE_LWRES_GETIPNODE #undef HAVE_GETOPT_H /* gethostbyname_r */ #undef HAVE_FUNC_GETHOSTBYNAME_R_6 #undef HAVE_FUNC_GETHOSTBYNAME_R_5 #undef HAVE_FUNC_GETHOSTBYNAME_R_3 /* gethostbyaddr_r */ #undef HAVE_GETHOSTBYADDR_R_5 #undef HAVE_GETHOSTBYADDR_R_7 #undef HAVE_GETHOSTBYADDR_R_8 /* first argument of gethostbyaddr_r may be char* or void* */ #undef GETHOSTBYADDR_FIRST_ARG_CHARPTR #undef GETHOSTBYADDR_FIRST_ARG_VOIDPTR /* xmlSaveFile */ #undef HAVE_XMLSAVEFORMATFILEENC #undef HAVE_LIBXSLT_XSLTCONFIG_H /* strtok_r */ #undef HAVE_STRTOK_R #undef WORDS_LITTLEENDIAN #undef WORDS_BIGENDIAN /* * newer versions of UCD-SNMP use this function. This should be preferred way, * but Mandrake 8.2 comes with ucd-snmp v.4.2.3 which does not have it. */ #undef HAVE_SNPRINT_OBJID #define FS_SEPARATOR "/" fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectDatabase_search.cpp0000644000175000017500000001671711733011756030146 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/Host.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Group.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include #include using namespace std; using namespace libfwbuilder; /* * find all objects used by the group 'gr'. Resolves references * recursively (that is, if a group member is another group, this * method descends into it and scans all objects that group uses) */ void FWObjectDatabase::findObjectsInGroup(Group *g, set &res) { searchId++; _findObjectsInGroup(g, res); } void FWObjectDatabase::_findObjectsInGroup(Group *g, set &res) { if (g->size()==0 || g->getInt(".searchId")==searchId) return; g->setInt(".searchId",searchId); FWObjectReference *ref; Group *sg; FWObject *obj; FWObject::iterator i=g->begin(); for (;i!=g->end();++i) { ref=FWObjectReference::cast(*i); if (ref==NULL) { res.insert(*i); continue; } obj=ref->getPointer(); sg=Group::cast(obj); if (sg==NULL) { res.insert(obj); continue; } _findObjectsInGroup(sg,res); } } /* *********************************************************************** */ /** * Find firewall object by name. Finds Firewall and Cluster objects. */ Firewall* FWObjectDatabase::_findFirewallByNameRecursive(FWObject* db, const string &name) throw(FWException) { // use Firewall::cast so that both Firewall and Cluster objects match if (Firewall::cast(db) && db->getName()==name && db->getParent()->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID) return static_cast(db); list::iterator j; for(j=db->begin(); j!=db->end(); ++j) { FWObject *o=*j; o = _findFirewallByNameRecursive(o, name); if(o) return static_cast(o); } if (db==this) throw FWException("Firewall object '"+name+"' not found"); return NULL; // not found } Firewall* FWObjectDatabase::findFirewallByName(const string &name) throw(FWException) { return _findFirewallByNameRecursive(this, name); } //#define DEBUG_WHERE_USED 1 bool FWObjectDatabase::_isInIgnoreList(FWObject *o) { if (FWOptions::cast(o)!=NULL) return true; if (o->getId()==FWObjectDatabase::DELETED_OBJECTS_ID) return true; return false; } /* *********************************************************************** */ /** * Finds references to object 'o' in a subtree rooted at object * 'p'. Skips 'deleted objects' library. Avoids circular group * references using temporary flags set in objects this method * visits. Results are placed in the set resset. This function * returns the following objects as the results: * * - references that point to the object (FWObjectReference, * FWServiceReference objects). Note that the reference itself is * returned rather than the parent object the reference is a child of. * This includes cases where object is a member of a user-defined * group and when it is used in a rule element. In both cases reference * is returned as part of the resset. * * - group objects which are parents of the object . */ void FWObjectDatabase::findWhereObjectIsUsed(FWObject *o, FWObject *p, std::set &resset) { searchId++; _findWhereObjectIsUsed(o, p, resset, searchId); } bool FWObjectDatabase::_findWhereObjectIsUsed(FWObject *o, FWObject *p, std::set &resset, int search_id) { bool res = false; if ( _isInIgnoreList(p)) return res; if (p->size()==0) return res; if (p->getInt(".search_id")==search_id) return p->getBool(".searchResult"); // set flags to break indefinite recursion in case we encounter circular groups p->setInt(".search_id", search_id); p->setBool(".searchResult", false); Interface *intf = Interface::cast(p); if (intf) { string netzone_id = intf->getStr("network_zone"); FWObject *netzone = findInIndex(FWObjectDatabase::getIntId(netzone_id)); if (netzone == o) { resset.insert(p); res = true; } } PolicyRule *rule = PolicyRule::cast(p); if (rule) { if (rule->getAction() == PolicyRule::Branch) { FWObject *ruleset = rule->getBranch(); if (o==ruleset) { resset.insert(p); res = true; } } if (rule->getTagging()) { FWObject *tagobj = rule->getTagObject(); if (o==tagobj) { resset.insert(p); res = true; } } } NATRule *nat_rule = NATRule::cast(p); if (nat_rule && nat_rule->getAction() == NATRule::Branch) { FWObject *ruleset = nat_rule->getBranch(); if (o==ruleset) { resset.insert(p); res = true; } } if (Firewall::isA(o) && Cluster::isA(p)) { if (Cluster::cast(p)->hasMember(Firewall::cast(o))) { resset.insert(p); res = true; } } FWObject::iterator i1 = p->begin(); for ( ; i1!=p->end(); ++i1) { FWReference *ref = FWReference::cast(*i1); if (ref!=NULL) { // child is a reference FWObject *g = ref->getPointer(); if (o->getId() == g->getId()) { resset.insert(*i1); res = true; } } else // child is a regular object, not a reference { if (o->getId() == (*i1)->getId()) { resset.insert(p); res = true; // still run search recursively, the same object could be // used in rules if it is a firewall } _findWhereObjectIsUsed(o, *i1, resset, search_id); } } p->setBool(".searchResult", res); return res; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Interval.cpp0000644000175000017500000001663311733011756025312 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Interval.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWObjectDatabase.h" #include using namespace libfwbuilder; const char *Interval::TYPENAME={"Interval"}; Interval::Interval() { setInt("from_minute", -1); setInt("from_hour", -1); setInt("from_day", -1); setInt("from_month", -1); setInt("from_year", -1); setInt("from_weekday", -1); setInt("to_minute", -1); setInt("to_hour", -1); setInt("to_day", -1); setInt("to_month", -1); setInt("to_year", -1); setInt("to_weekday", -1); setStr("days_of_week", ""); } std::string Interval::constructDaysOfWeek(int sdayofweek, int edayofweek) { std::ostringstream ostr; if (sdayofweek<0) sdayofweek=0; if (sdayofweek>6) sdayofweek=6; // if both start and end day are -1, need to // generate "sun,mon,tue,wed,thu,fri,sat" if (edayofweek<0) edayofweek=6; if (edayofweek>6) edayofweek=6; bool first=true; bool inside_interval = false; int day=0; while (1) { if (!inside_interval && day==sdayofweek) inside_interval=true; if (inside_interval) { if (!first) ostr << ","; first=false; ostr << day; // if sdayofweek==edayofweek print one day if (day==edayofweek) break; } if (++day>6) day=0; } return ostr.str(); } void Interval::setStartTime(int min,int hour,int day,int month,int year,int dayofweek) { setInt("from_minute", min); setInt("from_hour", hour); setInt("from_day", day); setInt("from_month", month); setInt("from_year", year); setInt("from_weekday", dayofweek); setStr("days_of_week", constructDaysOfWeek(dayofweek,getInt("to_weekday"))); } void Interval::setEndTime(int min,int hour,int day,int month,int year,int dayofweek) { setInt("to_minute", min); setInt("to_hour", hour); setInt("to_day", day); setInt("to_month", month); setInt("to_year", year); setInt("to_weekday", dayofweek); setStr("days_of_week", constructDaysOfWeek(getInt("from_weekday"),dayofweek)); } void Interval::setStartTime(int min,int hour,int day,int month,int year) { setInt("from_minute", min); setInt("from_hour", hour); setInt("from_day", day); setInt("from_month", month); setInt("from_year", year); } void Interval::setEndTime(int min,int hour,int day,int month,int year) { setInt("to_minute", min); setInt("to_hour", hour); setInt("to_day", day); setInt("to_month", month); setInt("to_year", year); } void Interval::setDaysOfWeek(const std::string &days_of_week) { setStr("days_of_week", days_of_week); } void Interval::getStartTime(int *min,int *hour,int *day,int *month,int *year,int *dayofweek) const { *min=getInt("from_minute"); *hour=getInt("from_hour"); *day=getInt("from_day"); *month=getInt("from_month"); *year=getInt("from_year"); *dayofweek=getInt("from_weekday"); } void Interval::getEndTime(int *min,int *hour,int *day,int *month,int *year,int *dayofweek) const { *min=getInt("to_minute"); *hour=getInt("to_hour"); *day=getInt("to_day"); *month=getInt("to_month"); *year=getInt("to_year"); *dayofweek=getInt("to_weekday"); } /** * Returns a string, a comma separated list of day numbers. Sunday is * day "0" */ std::string Interval::getDaysOfWeek() { std::string days_of_week = getStr("days_of_week"); int sdayofweek = getInt("from_weekday"); int edayofweek = getInt("to_weekday"); if (!days_of_week.empty()) return getStr("days_of_week"); if (sdayofweek!=-1 || edayofweek!=-1) // Old school representation of the days of week return constructDaysOfWeek(sdayofweek, edayofweek); return ""; } void Interval::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("from_minute"))); if (n!=NULL) { setStr("from_minute", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("from_hour"))); if (n!=NULL) { setStr("from_hour", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("from_day"))); if (n!=NULL) { setStr("from_day", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("from_month"))); if (n!=NULL) { setStr("from_month", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("from_year"))); if (n!=NULL) { setStr("from_year", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("from_weekday"))); if (n!=NULL) { setStr("from_weekday", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("to_minute"))); if (n!=NULL) { setStr("to_minute", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("to_hour"))); if (n!=NULL) { setStr("to_hour", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("to_day"))); if (n!=NULL) { setStr("to_day", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("to_month"))); if (n!=NULL) { setStr("to_month", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("to_year"))); if (n!=NULL) { setStr("to_year", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("to_weekday"))); if (n!=NULL) { setStr("to_weekday", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("days_of_week"))); if (n!=NULL) { setStr("days_of_week", n); FREEXMLBUFF(n); } else { setStr("days_of_week", constructDaysOfWeek(getInt("from_weekday"), getInt("to_weekday"))); } } xmlNodePtr Interval::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } FWReference* Interval::createRef() { // FWIntervalReference *ref=new FWIntervalReference(); FWIntervalReference *ref = getRoot()->createFWIntervalReference(); ref->setPointer(this); return ref; } bool Interval::isAny() const { return getId()==FWObjectDatabase::ANY_INTERVAL_ID; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IntervalGroup.h0000644000175000017500000000324211733011756025764 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INTERVALGROUP_HH_FLAG__ #define __INTERVALGROUP_HH_FLAG__ #include "fwbuilder/Group.h" namespace libfwbuilder { class IntervalGroup : public Group { public: IntervalGroup(); virtual ~IntervalGroup(); DECLARE_FWOBJECT_SUBTYPE(IntervalGroup); DECLARE_DISPATCH_METHODS(IntervalGroup); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual FWReference* createRef(); /** * get the list of object type names that can be inserted into * given object group. This reflects definition of the group XML * element in DTD. */ virtual void getAllowedTypesOfChildren(std::list &types_list); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/NAT.cpp0000644000175000017500000000245511733011756024145 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWObjectDatabase.h" using namespace libfwbuilder; const char *NAT::TYPENAME={"NAT"}; NAT::NAT() : RuleSet() { setName("NAT"); } NAT::~NAT() {} Rule* NAT::createRule() { FWObjectDatabase* db=getRoot(); assert(db!=NULL); return db->createNATRule(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/uint128.cpp0000644000175000017500000000036111733011756024727 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC */ #include "uint128.h" using namespace std; ostream &operator<<(ostream &o, const uint128 &n) { o << n.to_string(); return o; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/inet_net_ntop.c0000644000175000017500000003257411733011756026035 0ustar sylvestresylvestre/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include "inet_net.h" #include #include #include #define NS_IN6ADDRSZ 16 #define NS_INT16SZ 2 #ifdef SPRINTF_CHAR #define SPRINTF(x) strlen(sprintfx) #else #define SPRINTF(x) ((size_t)sprintf x) #endif static char *inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size); static char *inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size); static char *inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size); static char *inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size); /* * char * * inet_net_ntop(af, src, bits, dst, size) * convert host/network address from network to presentation format. * "src"'s size is determined from its "af". * return: * pointer to dst, or NULL if an error occurred (check errno). * note: * 192.5.5.1/28 has a nonzero host part, which means it isn't a network * as called for by inet_net_pton() but it can be a host address with * an included netmask. * author: * Paul Vixie (ISC), October 1998 */ char* inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) { switch (af) { case AF_INET: return (inet_net_ntop_ipv4(src, bits, dst, size)); case AF_INET6: return (inet_net_ntop_ipv6(src, bits, dst, size)); default: errno = EAFNOSUPPORT; return (NULL); } } /* * char * * inet_cidr_ntop(af, src, bits, dst, size) * convert network number from network to presentation format. * generates CIDR style result always. * return: * pointer to dst, or NULL if an error occurred (check errno). * author: * Paul Vixie (ISC), July 1996 */ char* inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) { switch (af) { case AF_INET: return (inet_cidr_ntop_ipv4(src, bits, dst, size)); case AF_INET6: return (inet_cidr_ntop_ipv6(src, bits, dst, size)); default: errno = EAFNOSUPPORT; return (NULL); } } /* * static char * * inet_cidr_ntop_ipv4(src, bits, dst, size) * convert IPv4 network number from network to presentation format. * generates CIDR style result always. * return: * pointer to dst, or NULL if an error occurred (check errno). * note: * network byte order assumed. this means 192.5.5.240/28 has * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), July 1996 */ static char * inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { char *odst = dst; char *t; u_int m; int b; if (bits < 0 || bits > 32) { errno = EINVAL; return (NULL); } if (bits == 0) { if (size < sizeof "0") goto emsgsize; *dst++ = '0'; size--; *dst = '\0'; } /* Format whole octets. */ for (b = bits / 8; b > 0; b--) { if (size <= sizeof "255.") goto emsgsize; t = dst; dst += SPRINTF((dst, "%u", *src++)); if (b > 1) { *dst++ = '.'; *dst = '\0'; } size -= (size_t) (dst - t); } /* Format partial octet. */ b = bits % 8; if (b > 0) { if (size <= sizeof ".255") goto emsgsize; t = dst; if (dst != odst) *dst++ = '.'; m = ((1 << b) - 1) << (8 - b); dst += SPRINTF((dst, "%u", *src & m)); size -= (size_t) (dst - t); } /* Format CIDR /width. */ if (size <= sizeof "/32") goto emsgsize; dst += SPRINTF((dst, "/%u", bits)); return (odst); emsgsize: errno = EMSGSIZE; return (NULL); } /* * static char * * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size) * convert IPv6 network number from network to presentation format. * generates CIDR style result always. Picks the shortest representation * unless the IP is really IPv4. * always prints specified number of bits (bits). * return: * pointer to dst, or NULL if an error occurred (check errno). * note: * network byte order assumed. this means 192.5.5.240/28 has * 0x11110000 in its fourth octet. * author: * Vadim Kogan (UCB), June 2001 * Original version (IPv4) by Paul Vixie (ISC), July 1996 */ static char * inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { u_int m; int b; int p; int zero_s, zero_l, tmp_zero_s, tmp_zero_l; int i; int is_ipv4 = 0; unsigned char inbuf[16]; char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; char *cp; int words; u_char *s; if (bits < 0 || bits > 128) { errno = EINVAL; return (NULL); } cp = outbuf; if (bits == 0) { *cp++ = ':'; *cp++ = ':'; *cp = '\0'; } else { /* Copy src to private buffer. Zero host part. */ p = (bits + 7) / 8; memcpy(inbuf, src, p); memset(inbuf + p, 0, 16 - p); b = bits % 8; if (b != 0) { m = ~0 << (8 - b); inbuf[p - 1] &= m; } s = inbuf; /* how many words need to be displayed in output */ words = (bits + 15) / 16; if (words == 1) words = 2; /* Find the longest substring of zero's */ zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; for (i = 0; i < (words * 2); i += 2) { if ((s[i] | s[i + 1]) == 0) { if (tmp_zero_l == 0) tmp_zero_s = i / 2; tmp_zero_l++; } else { if (tmp_zero_l && zero_l < tmp_zero_l) { zero_s = tmp_zero_s; zero_l = tmp_zero_l; tmp_zero_l = 0; } } } if (tmp_zero_l && zero_l < tmp_zero_l) { zero_s = tmp_zero_s; zero_l = tmp_zero_l; } if (zero_l != words && zero_s == 0 && ((zero_l == 6) || ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) is_ipv4 = 1; /* Format whole words. */ for (p = 0; p < words; p++) { if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) { /* Time to skip some zeros */ if (p == zero_s) *cp++ = ':'; if (p == words - 1) *cp++ = ':'; s++; s++; continue; } if (is_ipv4 && p > 5) { *cp++ = (p == 6) ? ':' : '.'; cp += SPRINTF((cp, "%u", *s++)); /* we can potentially drop the last octet */ if (p != 7 || bits > 120) { *cp++ = '.'; cp += SPRINTF((cp, "%u", *s++)); } } else { if (cp != outbuf) *cp++ = ':'; cp += SPRINTF((cp, "%x", *s * 256 + s[1])); s += 2; } } } /* Format CIDR /width. */ (void) SPRINTF((cp, "/%u", bits)); if (strlen(outbuf) + 1 > size) goto emsgsize; strcpy(dst, outbuf); return (dst); emsgsize: errno = EMSGSIZE; return (NULL); } /* * static char * * inet_net_ntop_ipv4(src, bits, dst, size) * convert IPv4 network address from network to presentation format. * "src"'s size is determined from its "af". * return: * pointer to dst, or NULL if an error occurred (check errno). * note: * network byte order assumed. this means 192.5.5.240/28 has * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), October 1998 */ static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { char *odst = dst; char *t; int len = 4; int b; if (bits < 0 || bits > 32) { errno = EINVAL; return (NULL); } /* Always format all four octets, regardless of mask length. */ for (b = len; b > 0; b--) { if (size <= sizeof ".255") goto emsgsize; t = dst; if (dst != odst) *dst++ = '.'; dst += SPRINTF((dst, "%u", *src++)); size -= (size_t) (dst - t); } /* don't print masklen if 32 bits */ if (bits != 32) { if (size <= sizeof "/32") goto emsgsize; dst += SPRINTF((dst, "/%u", bits)); } return (odst); emsgsize: errno = EMSGSIZE; return (NULL); } static int decoct(const u_char *src, int bytes, char *dst, size_t size) { char *odst = dst; char *t; int b; for (b = 1; b <= bytes; b++) { if (size <= sizeof "255.") return (0); t = dst; dst += SPRINTF((dst, "%u", *src++)); if (b != bytes) { *dst++ = '.'; *dst = '\0'; } size -= (size_t) (dst - t); } return (dst - odst); } static char * inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough to * contain a value of the specified size. On some systems, like Crays, * there is no such thing as an integer variable with 16 bits. Keep this * in mind if you think this function should have been coded to use * pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; char *tp; struct { int base, len; } best, cur; u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; if ((bits < -1) || (bits > 128)) { errno = EINVAL; return (NULL); } /* * Preprocess: Copy the input (bytewise) array into a wordwise array. Find * the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; best.len = 0; cur.len = 0; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 7 && words[7] != 0x0001) || (best.len == 5 && words[5] == 0xffff))) { int n; n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp)); if (n == 0) { errno = EMSGSIZE; return (NULL); } tp += strlen(tp); break; } tp += SPRINTF((tp, "%x", words[i])); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp = '\0'; if (bits != -1 && bits != 128) tp += SPRINTF((tp, "/%u", bits)); /* * Check for overflow, copy, and we're done. */ if ((size_t) (tp - tmp) > size) { errno = EMSGSIZE; return (NULL); } strcpy(dst, tmp); return (dst); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/BackgroundOp.cpp0000644000175000017500000001313711733011756026100 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include // #include #include #include #include #include "fwbuilder/BackgroundOp.h" using namespace std; using namespace libfwbuilder; BackgroundOp::BackgroundOp():running(false),connected(true) { error = NULL; stop_program = new SyncFlag(false); iamdead = new SyncFlag(false); pthread_attr_init(&tattr); } /* * we destroy logger in the background thread because run_impl may use * logger and we should be able to destroy object of this class even * while background thread is working. * * iamdead should not be deleted either because it is used as a flag * so that background thread would know if this object has been deleted * while run_impl was running */ BackgroundOp::~BackgroundOp() { stop_program->lock(); stop_program->modify(true); stop_program->unlock(); iamdead->lock(); iamdead->modify(true); iamdead->unlock(); pthread_attr_destroy(&tattr); } /* replaced by a macro void BackgroundOp::check_stop() { stop_program->lock(); if ( stop_program->peek() ) { stop_program->unlock(); pthread_exit(NULL); } stop_program->unlock(); } */ bool BackgroundOp::isRunning() { return running; } void BackgroundOp::setRunning() { running=true; } void BackgroundOp::clearRunning() { running=false; } bool BackgroundOp::isConnected() { return connected; } void BackgroundOp::disconnect() { connected=false; } Logger* BackgroundOp::start_operation() throw(FWException) { /* * Suppose calling program wants to stop background operation. It * calls stop_oprtation and some times immediately destroys * BackgroundOp object. If background op. was stuck in a system * call when this happened, it will check stop_program flag only * after it returns from the system call. Since BackgroundOp * object has been destroyed by then, the program crashes. To * avoid this, we create stop_program flag here so that even * BackgroundOp object is destoryed, this flag is still available * and can be properly checked. */ stop_program->lock(); stop_program->modify(false); stop_program->unlock(); running = true; Logger *logger = new QueueLogger(); void **void_pair = new void*[4]; void_pair[0] = this; void_pair[1] = logger; void_pair[2] = iamdead; void_pair[3] = stop_program; pthread_t tid; pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); int err = pthread_create(&tid, &tattr, background_thread, void_pair); switch (err) { case EAGAIN: throw FWException("Not enough system resources to create new thread"); case EINVAL: throw FWException("The value specified by attr is invalid."); } return logger; } void BackgroundOp::stop_operation() { error = new FWException("Interrupted by user"); stop_program->lock(); stop_program->modify(true); stop_program->unlock(); } namespace libfwbuilder { void *background_thread(void *args) { void **void_pair=(void**)args; BackgroundOp *bop = (BackgroundOp*)void_pair[0]; Logger *logger = (Logger *) void_pair[1]; SyncFlag *isdead = (SyncFlag*) void_pair[2]; SyncFlag *stop_program = (SyncFlag*) void_pair[3]; try { bop->run_impl(logger,stop_program); } catch (FWException &ex) { isdead->lock(); if (isdead->peek()) { isdead->unlock(); delete logger; delete isdead; delete void_pair; return(NULL); } *logger << "Exception: " << ex.toString().c_str() << '\n'; bop->error=new FWException(ex); isdead->unlock(); } *logger << "Background process has finished\n"; isdead->lock(); if (isdead->peek()) { isdead->unlock(); delete logger; delete isdead; delete void_pair; return(NULL); } /* operation completed - clear "running" flag */ bop->clearRunning(); isdead->unlock(); /* wait till the other thread reads all the lines from logger. If * widget that was reading lines from this logger has been destroyed, * it should have called BackhroundOp::disconnect to release BackgroundOp * object */ while (true) { isdead->lock(); if (isdead->peek() || !bop->isConnected()) { isdead->unlock(); break; } isdead->unlock(); libfwbuilder::cxx_sleep(1); } delete logger; delete void_pair; return(NULL); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Inet6AddrMask.cpp0000644000175000017500000000673611733011756026125 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Inet6AddrMask.h" extern "C" { #include "fwbuilder/inet_net.h" } #include #include #include #include #include #ifndef _WIN32 # include # include #else # include #endif #include #include using namespace std; using namespace libfwbuilder; Inet6AddrMask::Inet6AddrMask() : InetAddrMask() { address->address_family = AF_INET6; netmask->address_family = AF_INET6; setNetworkAndBroadcastAddress(); } Inet6AddrMask::Inet6AddrMask(const string &s) throw(FWException) : InetAddrMask(true) { struct in6_addr a_ipv6; int nbits; nbits = inet_net_pton(AF_INET6, s.c_str(), &a_ipv6, sizeof(a_ipv6)); if (nbits < 0) throw FWException(string("Invalid IP address: '") + s + "'"); address = new InetAddr(&a_ipv6); netmask = new InetAddr(AF_INET6, nbits); broadcast_address = new InetAddr(); network_address = new InetAddr(); last_host = new InetAddr(); setNetworkAndBroadcastAddress(); } Inet6AddrMask::Inet6AddrMask(const InetAddr &a, const InetAddr &n) : InetAddrMask(true) { address = new InetAddr(a & n); netmask = new InetAddr(AF_INET6, n.getLength()); broadcast_address = new InetAddr(); network_address = new InetAddr(); last_host = new InetAddr(); setNetworkAndBroadcastAddress(); } Inet6AddrMask::~Inet6AddrMask() { // destructor of InetAddrMask deletes address, netmask // and other member variables } std::string Inet6AddrMask::toString() const { char ntop_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; char *cp; cp = inet_net_ntop(AF_INET6, (const void*)(&(address->ipv6)), netmask->getLength(), ntop_buf, sizeof(ntop_buf)); if (cp==NULL) { ostringstream err; switch (errno) { case EINVAL: err << "Inet6AddrMask::toString() Invalid bit length 0"; throw FWException(err.str()); ;; case EMSGSIZE: err << "Inet6AddrMask::toString() EMSGSIZE error"; throw FWException(err.str()); ;; case EAFNOSUPPORT: err << "Inet6AddrMask::toString() EAFNOSUPPORT error"; throw FWException(err.str()); ;; default: err << "Inet6AddrMask::toString() other error: " << errno; throw FWException(err.str()); ;; } } return std::string(strdup(cp)); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/TCPService.h0000644000175000017500000000463311733011756025137 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TCPSERVICE_HH_FLAG__ #define __TCPSERVICE_HH_FLAG__ #include "fwbuilder/TCPUDPService.h" namespace libfwbuilder { class TCPService : public TCPUDPService { public: typedef enum {URG, ACK, PSH, RST, SYN, FIN } TCPFlag; private: static std::map flags; static std::map flags_masks; void _init_flags(); public: TCPService(); virtual ~TCPService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(TCPService); DECLARE_DISPATCH_METHODS(TCPService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; /** * this is a shortcut method, it returns true if TCPService object * inspects any TCP flags. This is so if it has non-empty set of TCP * flag masks. Note that configuration with non-empty set of the TCP * flags masks and empty set of TCP flags is completely legal and * sometimes desired (checking for null scans, for example). */ bool inspectFlags() const; bool getTCPFlag(TCPFlag f) const; std::set getAllTCPFlags() const; void setTCPFlag(TCPFlag f,bool v); bool getTCPFlagMask(TCPFlag f) const; std::set getAllTCPFlagMasks() const; void setTCPFlagMask(TCPFlag f,bool v); void clearAllTCPFlags(); void clearAllTCPFlagMasks(); void setAllTCPFlagMasks(); bool getEstablished(); void setEstablished(bool f); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/CustomService.h0000644000175000017500000000461611733011756025764 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CUSTOMSERVICE_HH_FLAG__ #define __CUSTOMSERVICE_HH_FLAG__ #include "fwbuilder/Service.h" #include // for AF_INET and AF_INET6 #ifndef _WIN32 # include # include # include # include #else # include # include #endif namespace libfwbuilder { class CustomService : public Service { private: std::map codes; std::string protocol; int address_family; public: CustomService(); virtual ~CustomService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual FWObject& shallowDuplicate( const FWObject *obj, bool preserve_id = true) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(CustomService); DECLARE_DISPATCH_METHODS(CustomService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; void setCodeForPlatform(const std::string& platform, const std::string& code); const std::string getCodeForPlatform(const std::string& platform) const; std::list getAllKnownPlatforms(); void setProtocol(const std::string& proto); const std::string& getProtocol(); void setAddressFamily(int af); int getAddressFamily(); virtual bool isV4Only(); virtual bool isV6Only(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/snmp.h0000644000175000017500000003373111733011756024146 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SNMP_HH_FLAG__ #define __SNMP_HH_FLAG__ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #ifdef HAVE_LIBSNMP #include #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "fwbuilder/BackgroundOp.h" #include "fwbuilder/FWException.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InterfaceData.h" #include "fwbuilder/IPRoute.h" #include "fwbuilder/dns.h" #ifdef UCD_SNMP #include #include #include #endif #ifdef NET_SNMP #include #include #endif namespace libfwbuilder { class SNMPConnection; class SNMPVariable { friend class SNMPConnection; public: virtual ~SNMPVariable() {} enum { snmp_int = ASN_INTEGER, snmp_string = ASN_OCTET_STR, snmp_bits = ASN_BIT_STR, snmp_counter64 = ASN_APP_COUNTER64, snmp_oid = ASN_OBJECT_ID, snmp_ipaddr = ASN_IPADDRESS } type; /** * Returns std::string representation of this variable */ virtual std::string toString() = 0; static std::string varList2String(std::vector &v); static long varList2Int(std::vector &v) throw(FWException); static long var2Int(SNMPVariable *var) throw(FWException); static void freeVarList(std::vector &v); protected: static SNMPVariable *create(struct variable_list *v) throw(FWException); }; class SNMPVariable_Int : public SNMPVariable { friend class SNMPVariable; public: virtual std::string toString(); long getIntValue() { return value; } protected: SNMPVariable_Int(long v) { type=snmp_int; value=v; } long value; }; class SNMPVariable_Bits : public SNMPVariable { friend class SNMPVariable; public: virtual ~SNMPVariable_Bits() { delete value; } virtual std::string toString(); protected: SNMPVariable_Bits(u_char *v, size_t l) { type = snmp_bits; if (v) { len=l; value = (uint32_t*)(new unsigned char[len]); memcpy((void*)value, v, len); } else { value = NULL ; len = 0 ; } } const uint32_t *value; size_t len; }; /** * Unfortunately SNMP does not distinguish Netmask and InetAddr * types. On our framework they are different, and thus * we have to do late type conversion. * (lord) */ class SNMPVariable_IPaddr : public SNMPVariable { friend class SNMPVariable; public: virtual std::string toString(); virtual InetAddr getInetAddrValue() throw(FWException); virtual InetAddr getNetmaskValue() throw(FWException); protected: SNMPVariable_IPaddr(u_char *v, size_t l) throw(FWException) { type = snmp_ipaddr; if(v) { len=l; value=new unsigned char[len]; memcpy((void*)value, v, len); } else { throw FWException("Invalid data for snmp_ipaddress variable."); } } const unsigned char *value; size_t len; }; class SNMPVariable_String : public SNMPVariable { friend class SNMPVariable; public: virtual std::string toString(); virtual const std::string toHexString(); protected: SNMPVariable_String(u_char *v, size_t l) { type=snmp_string; if(v) { for(u_char *p=v; l; p++,l--) { value+=*p; } } else value=""; } std::string value; }; class SNMPVariable_Counter64 : public SNMPVariable { friend class SNMPVariable; public: virtual std::string toString(); protected: SNMPVariable_Counter64(struct counter64 *v) { type=snmp_counter64; if(v) { high=v->high; low=v->low; } else { high=low=0l; } } unsigned long high; unsigned long low; }; class SNMPVariable_OID : public SNMPVariable { friend class SNMPVariable; public: virtual std::string toString(); protected: SNMPVariable_OID(oid v) { type=snmp_oid; value=v; } oid value; }; class SNMPConnection { public: SNMPConnection(const std::string &peer, const std::string &community); virtual ~SNMPConnection(); /** * Optional parameter timeout is in milliseconds. */ void connect(int retries=SNMP_DEFAULT_RETRIES, long timeout=SNMP_DEFAULT_TIMEOUT) throw(FWException); void disconnect() throw(FWException); std::vector get(const std::string &variable) throw(FWException); std::multimap walk(const std::string &variable) throw(FWException); private: std::string peer; std::string community; bool connected; struct snmp_session *session, *session_data; static bool lib_initialized; }; class SNMPQuery : public BackgroundOp { private: static const char *SNMP_INTERFACE_ASTATUS; static const char *SNMP_INTERFACE_OSTATUS; static const char *SNMP_INTERFACE_INDEX ; static const char *SNMP_INTERFACES_DESCR ; static const char *SNMP_INTERFACES_PHYSA ; static const char *SNMP_INTERFACES_TYPE ; static const char *SNMP_ADDR_INDEX_TABLE ; static const char *SNMP_NMASK_TABLE ; static const char *SNMP_ADDR_TABLE ; static const char *SNMP_BCAST_TABLE ; static const char *SNMP_AT_TABLE_NET ; static const char *SNMP_AT_TABLE_PHYS ; static const char *SNMP_ROUTE_DST_TABLE ; static const char *SNMP_ROUTE_NM_TABLE ; static const char *SNMP_ROUTE_TYPE_TABLE ; static const char *SNMP_ROUTE_IF_TABLE ; static const char *SNMP_ROUTE_GW_TABLE ; static const int SNMP_DIRECT_ROUTE ; static const char *SNMP_SYSNAME ; static const char *SNMP_SYSDESCR ; static const char *SNMP_CONTACT ; static const char *SNMP_LOCATION ; static const char *IP_MIB_PREFIX ; static const char *IP_MIB_ENTIFINDEX_PREFIX ; static const char *RFC1213_MIB_PREFIX ; static const char *RFC1213_MIB_PREFIX_IPROUTEDEST_PREFIX ; static const char* SNMP_IP_MIB_RFC4293_V4_INDEX; static const char* SNMP_IP_MIB_RFC4293_V6_INDEX; static const char* SNMP_IP_MIB_RFC4293_V6_PREFIX; std::string hostname, community; std::string descr, contact, location, sysname; std::map interfaces; std::map arptable; std::vector routes; int retries; long timeout; void walkInterfaceIndexTable(Logger *logger, SNMPConnection *c, const char* OID, std::map > &addr); void getAddressAndNetmask(Logger *logger, SNMPConnection *c, std::string adentry, InetAddr **addr, InetAddr **netmask); public: SNMPQuery() {} SNMPQuery(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT); virtual ~SNMPQuery(); void init(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT); void fetchArpTable(Logger *,SyncFlag *stop_program, SNMPConnection *connection=NULL) throw(FWException); void fetchInterfaces(Logger *,SyncFlag *stop_program, SNMPConnection *connection=NULL) throw(FWException); void fetchSysInfo(Logger *,SyncFlag *stop_program, SNMPConnection *connection=NULL) throw(FWException); void fetchAll(Logger *,SyncFlag *stop_program) throw(FWException); void fetchRoutingTable(Logger *,SyncFlag *stop_program, SNMPConnection *connection=NULL) throw(FWException); std::map* getInterfaces(); std::map* getArpTable(); std::vector* getRoutes(); const std::string& getSysname (); const std::string& getDescr (); const std::string& getContact (); const std::string& getLocation (); protected: bool isDefault(const IPRoute &) const; }; class SNMP_interface_query : public SNMPQuery { public: SNMP_interface_query() : SNMPQuery() {} SNMP_interface_query(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT) : SNMPQuery(hostname, community, retries_, timeout_) {} void init(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT) { SNMPQuery::init(hostname, community, retries_, timeout_); } virtual void run_impl(Logger *logger,SyncFlag *stop_program) throw(FWException); }; class SNMP_sysdesc_query : public SNMPQuery { public: SNMP_sysdesc_query() : SNMPQuery() {} SNMP_sysdesc_query(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT) : SNMPQuery(hostname, community, retries_, timeout_) {} void init(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT) { SNMPQuery::init(hostname, community, retries_, timeout_); } virtual void run_impl(Logger *logger,SyncFlag *stop_program) throw(FWException); }; class SNMP_discover_query : public SNMPQuery { private: bool fetch_inerfaces; public: SNMP_discover_query() : SNMPQuery() {} SNMP_discover_query(std::string hostname, std::string community, int retries_=SNMP_DEFAULT_RETRIES, long timeout_=SNMP_DEFAULT_TIMEOUT, bool _f=true):SNMPQuery(hostname, community, retries_, timeout_) { fetch_inerfaces=_f; } virtual void run_impl(Logger *logger,SyncFlag *stop_program) throw(FWException); }; class CrawlerFind: public HostEnt { public: CrawlerFind(); virtual ~CrawlerFind(); bool have_snmpd ; std::string descr, contact, location, sysname; std::map interfaces; /** * What physical address host had in ARP table when it was found. * (optional) */ std::string found_phys_addr; //set when DNS resolution succeeded. bool dns_ok ; }; class SNMPCrawler : public BackgroundOp { private: const std::vector *limit_to_networks ; static const InetAddrMask LOOPBACK_NET ; static const InetAddrMask IPV6_LOOPBACK_NET ; static const InetAddr PTP_NETMASK ; std::map queue; std::map found; std::set networks; std::string community; int snmp_retries ; long snmp_timeout ; bool recursive ; bool do_dns ; bool follow_ptp ; unsigned int dns_threads ; int dns_retries ; int dns_timeout ; static const int PTP_INTERFACE_TYPES[]; protected: bool included (const InetAddr &) const ; bool alreadyseen (const InetAddr &) const ; bool special (const InetAddrMask &) const ; bool special (const InetAddr &) const ; bool point2point (const InetAddrMask &, const InterfaceData&) const ; bool point2point (const InterfaceData&) const ; std::list guessInterface( const IPRoute &r, const std::map &intf) const; public: SNMPCrawler(); SNMPCrawler(const InetAddr &seed, const std::string &_community, bool _recursive=true, bool _do_dns=true, bool _follow_ptp=false, unsigned int _dns_threads=10, int _retries=SNMP_DEFAULT_RETRIES, long _timeout=SNMP_DEFAULT_TIMEOUT, int _dns_retries=RES_DFLRETRY, int _dns_timeout=RES_TIMEOUT, const std::vector *include=NULL); virtual ~SNMPCrawler(); void init(const InetAddr &seed, const std::string &_community, bool _recursive=true, bool _do_dns=true, bool _follow_ptp=false, unsigned int _dns_threads=10, int _snmp_retries=SNMP_DEFAULT_RETRIES, long _snmp_timeout=SNMP_DEFAULT_TIMEOUT, int _dns_retries=RES_DFLRETRY, int _dns_timeout=RES_TIMEOUT, const std::vector *include=NULL); std::map getAllIPs(); std::set getNetworks(); virtual void run_impl(Logger *logger,SyncFlag *stop_program) throw(FWException); void bacresolve_results(Logger *logger,SyncFlag *stop_program) throw(FWException); }; } #endif #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPRoute.h0000644000175000017500000000372111733011756024514 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPROUTE_HH_FLAG__ #define __IPROUTE_HH_FLAG__ #include #include #ifndef _WIN32 # include # include # include # include #else # include #endif #include "fwbuilder/FWException.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InterfaceData.h" namespace libfwbuilder { class Interface; class IPRoute { public: IPRoute(const IPRoute &); IPRoute(const InetAddr &_dst, const InetAddr &_nm, const InetAddr &_gw, const InterfaceData &_intf, bool _direct); virtual ~IPRoute(); bool isDirect() const { return direct;} const InetAddr &getNetmask () const { return nm; } const InetAddr &getDestination() const { return dst; } const InetAddr &getGateway () const { return gw; } /** * @return interface associated with this route, or * NULL if none. */ const InterfaceData& getInterface() const { return intf; } private: InetAddr nm ; InetAddr dst ; InetAddr gw ; InterfaceData intf; bool direct ; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/TagService.cpp0000644000175000017500000000404411733011756025553 0ustar sylvestresylvestre /* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/TagService.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *TagService::TYPENAME={"TagService"}; string TagService::getProtocolName() const { return "tag_service";} int TagService::getProtocolNumber() const { return 65001; } TagService::TagService() { setStr("tagcode", ""); } TagService::~TagService() {} void TagService::setCode(const string &p) { setStr("tagcode", p); } string TagService::getCode() const { return getStr("tagcode"); } void TagService::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("tagcode"))); assert(n!=NULL); setStr("tagcode", n); FREEXMLBUFF(n); } xmlNodePtr TagService::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Management.cpp0000644000175000017500000003010211733011756025565 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Management.h" #include "fwbuilder/XMLTools.h" #include using namespace std; using namespace libfwbuilder; // --- Management --- const char *Management::TYPENAME={"Management"}; Management::Management() { // This object does not have standard attributes setId(-1); } void Management::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address"))); if (!n) { throw FWException( "Missing required address attribute in Management element"); } try { addr = InetAddr(n); FREEXMLBUFF(n); } catch(FWException &ex) { // try ipv6 try { addr = InetAddr(AF_INET6, n); FREEXMLBUFF(n); } catch(FWException &ex) { FREEXMLBUFF(n); throw FWException( string("Invalid address attribute in Management element: ") + ex.toString()); } } } xmlNodePtr Management::toXML(xmlNodePtr parent) throw(FWException) { setId(-1); setStr("address", addr.toString()); xmlNodePtr me = FWObject::toXML(parent, false); // to ensure right order we convert these nodes manually // also we do not save them if they are empty SNMPManagement *sm=getSNMPManagement(); sm->toXML(me); // if(!sm->isEmpty()) sm->toXML(me); FWBDManagement *fm=getFWBDManagement(); fm->toXML(me); // if(!fm->isEmpty()) fm->toXML(me); PolicyInstallScript *pi=getPolicyInstallScript(); pi->toXML(me); // if(!pi->isEmpty()) pi->toXML(me); return me; } bool Management::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (Management::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; const Management *o2=Management::constcast(obj); return (addr==o2->addr); } bool Management::validateChild(FWObject *o) { string otype=o->getTypeName(); return (otype==SNMPManagement::TYPENAME || otype==FWBDManagement::TYPENAME || otype==PolicyInstallScript::TYPENAME ); } FWObject& Management::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { const Management *other = dynamic_cast(o); addr = other->getAddress(); FWObject::shallowDuplicate(o, preserve_id); return *this; } bool Management::isEmpty() const { const SNMPManagement *sm = dynamic_cast(getFirstByType(SNMPManagement::TYPENAME)); const FWBDManagement *fm = dynamic_cast(getFirstByType(FWBDManagement::TYPENAME)); const PolicyInstallScript *pi = dynamic_cast( getFirstByType(PolicyInstallScript::TYPENAME)); return (!pi || pi->isEmpty()) && (!sm || sm->isEmpty()) && (!fm || fm->isEmpty()) && addr.isAny(); } PolicyInstallScript *Management::getPolicyInstallScript() { PolicyInstallScript *res = dynamic_cast( getFirstByType(PolicyInstallScript::TYPENAME)); if (!res) add( res= getRoot()->createPolicyInstallScript() ); //add(res = new PolicyInstallScript()); return res; } SNMPManagement *Management::getSNMPManagement() { SNMPManagement *res = dynamic_cast( getFirstByType(SNMPManagement::TYPENAME)); if (!res) add( res = getRoot()->createSNMPManagement() ); //add(res = new SNMPManagement()); return res; } FWBDManagement *Management::getFWBDManagement() { FWBDManagement *res = dynamic_cast( getFirstByType(FWBDManagement::TYPENAME)); if (!res) add( res = getRoot()->createFWBDManagement() ); //add(res = new FWBDManagement()); return res; } // --- PolicyInstallScript --- const char *PolicyInstallScript::TYPENAME={"PolicyInstallScript"}; PolicyInstallScript::PolicyInstallScript() { // This object does not have standard attributes setId(-1); enabled = false ; } bool PolicyInstallScript::isEmpty() const { return command.empty(); } bool PolicyInstallScript::isEnabled() const { return enabled; } void PolicyInstallScript::setEnabled(bool v) { enabled = v; } void PolicyInstallScript::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("command"))); if(n) { command=n; FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("arguments"))); if(n) { arguments=n; FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("enabled"))); if(n) { enabled=(cxx_strcasecmp(n,"True")==0); FREEXMLBUFF(n); } else enabled = false; } xmlNodePtr PolicyInstallScript::toXML(xmlNodePtr parent) throw(FWException) { setId(-1); setStr("command", command ); setStr("arguments", arguments); setBool("enabled", enabled); return FWObject::toXML(parent); } bool PolicyInstallScript::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (PolicyInstallScript::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; const PolicyInstallScript *o2=PolicyInstallScript::constcast(obj); return (command==o2->command && arguments==o2->arguments && enabled==o2->enabled); } FWObject& PolicyInstallScript::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { const PolicyInstallScript *n=dynamic_cast(o); command = n->getCommand(); arguments = n->getArguments(); enabled = n->isEnabled(); FWObject::shallowDuplicate(o, preserve_id); return *this; } const string& PolicyInstallScript::getCommand() const { return command; } void PolicyInstallScript::setCommand(const string& s) { command = s; } const string& PolicyInstallScript::getArguments() const { return arguments; } void PolicyInstallScript::setArguments(const string& s) { arguments = s; } // --- SNMPManagement --- const char *SNMPManagement::TYPENAME={"SNMPManagement"}; SNMPManagement::SNMPManagement() { // This object does not have standard attributes enabled = false ; setId(-1); } bool SNMPManagement::isEmpty() const { return read_community.empty() && write_community.empty(); } bool SNMPManagement::isEnabled() const { return enabled; } void SNMPManagement::setEnabled(bool v) { enabled = v; } void SNMPManagement::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("snmp_read_community"))); if(n) { read_community=n; FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("snmp_write_community"))); if(n) { write_community=n; FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("enabled"))); if(n) { enabled=(cxx_strcasecmp(n,"True")==0); FREEXMLBUFF(n); } else enabled = false; } xmlNodePtr SNMPManagement::toXML(xmlNodePtr parent) throw(FWException) { setId(-1); setStr("snmp_read_community", read_community ); setStr("snmp_write_community", write_community); setBool("enabled", enabled); return FWObject::toXML(parent); } bool SNMPManagement::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (SNMPManagement::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; const SNMPManagement *o2=SNMPManagement::constcast(obj); return (read_community==o2->read_community && write_community==o2->write_community && enabled==o2->enabled); } FWObject& SNMPManagement::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { const SNMPManagement *n=dynamic_cast(o); read_community = n->getReadCommunity(); write_community = n->getWriteCommunity(); enabled = n->isEnabled(); FWObject::shallowDuplicate(o, preserve_id); return *this; } const string& SNMPManagement::getReadCommunity () const { return read_community; } void SNMPManagement::setReadCommunity (const string& s) { read_community = s; } const string& SNMPManagement::getWriteCommunity() const { return write_community; } void SNMPManagement::setWriteCommunity(const string& s) { write_community = s; } // --- FWBDManagement --- const char *FWBDManagement::TYPENAME={"FWBDManagement"}; FWBDManagement::FWBDManagement() { port = -1 ; enabled = false ; // This object does not have standard attributes setId(-1); } FWBDManagement::~FWBDManagement() { } bool FWBDManagement::isEmpty() const { return port==-1; } bool FWBDManagement::isEnabled() const { return enabled; } void FWBDManagement::setEnabled(bool v) { enabled = v; } void FWBDManagement::fromXML(xmlNodePtr parent) throw(FWException) { const char *n=FROMXMLCAST(xmlGetProp(parent,TOXMLCAST("identity"))); assert(n!=NULL); identity_id = n; FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(parent,TOXMLCAST("port"))); assert(n!=NULL); port = atoi(n); FREEXMLBUFF(n); enabled=false; n=FROMXMLCAST(xmlGetProp(parent,TOXMLCAST("enabled"))); if(n) { enabled=(cxx_strcasecmp(n,"True")==0); FREEXMLBUFF(n); } } xmlNodePtr FWBDManagement::toXML(xmlNodePtr parent) throw(FWException) { setId(-1); setInt("port", port); setStr("identity", identity_id); setBool("enabled", enabled); xmlNodePtr me = FWObject::toXML(parent, false); return me; } bool FWBDManagement::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (FWBDManagement::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; const FWBDManagement *o2=FWBDManagement::constcast(obj); return (port==o2->port && identity_id==o2->identity_id && enabled==o2->enabled); } FWObject& FWBDManagement::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { const FWBDManagement *n=dynamic_cast(o); #if 0 cerr << "FWBDManagement::shallowDuplicate" << endl; cerr << "this:" << endl; dump(false,false); cerr << "Port: " << port << endl; cerr << "identity_id: " << identity_id << endl; cerr << "enabled: " << enabled << endl; cerr << endl; cerr << "n:" << endl; ((FWObject*)n)->dump(false,false); cerr << "Port: " << n->port << endl; cerr << "identity_id: " << n->identity_id << endl; cerr << "enabled: " << n->enabled << endl; cerr << endl; #endif port = n->getPort(); identity_id = n->getIdentityId(); enabled = n->isEnabled(); FWObject::shallowDuplicate(o, preserve_id); return *this; } int FWBDManagement::getPort() const { return port; } void FWBDManagement::setPort(int x) { port = x; } const string &FWBDManagement::getIdentityId() const { return identity_id; } void FWBDManagement::setIdentityId(const string &s) { identity_id = s; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/UserService.cpp0000644000175000017500000000501111733011756025751 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/UserService.h" #include "fwbuilder/XMLTools.h" using namespace std; using namespace libfwbuilder; const char *UserService::TYPENAME={"UserService"}; UserService::UserService() {} UserService::~UserService() {} string UserService::getProtocolName() const { return "user_service";} int UserService::getProtocolNumber() const { return 65002; } FWObject& UserService::shallowDuplicate(const FWObject *x, bool preserve_id) throw(FWException) { const UserService *cs = dynamic_cast(x); userid = cs->userid; return FWObject::shallowDuplicate(x, preserve_id); } void UserService::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n = FROMXMLCAST(xmlGetProp(root,TOXMLCAST("userid"))); if(n) { userid = string(n); FREEXMLBUFF(n); } } xmlNodePtr UserService::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("userid"), STRTOXMLCAST(userid)); return me; } bool UserService::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (UserService::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; const UserService *user_serv = UserService::constcast(obj); return (userid == user_serv->userid); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/XMLTools.cpp0000644000175000017500000006666211733011756025216 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/ThreadTools.h" #include #include #include #include // for va_start and friends #include #include #include #include #ifndef _WIN32 # include // need this for read(2) #else # include // for access # define R_OK 4 // for access #endif #ifdef HAVE_LIBXSLT_XSLTCONFIG_H # include #endif #include #include #include #include #include #include #include #undef FW_XMLTOOLS_VERBOSE // #define FW_XMLTOOLS_VERBOSE 1 #define DTD_LOAD_BITS (1|XML_DETECT_IDS|XML_COMPLETE_ATTRS) using namespace std; using namespace libfwbuilder; #ifndef __MINGW32__ extern int xmlDoValidityCheckingDefaultValue ; extern int xmlLoadExtDtdDefaultValue ; #else extern __declspec(dllimport) int xmlDoValidityCheckingDefaultValue ; extern __declspec(dllimport) int xmlLoadExtDtdDefaultValue ; #endif /* * This mutex protects access to XML parser. * since we change DTD validation flags and error * handling function pointers, access should be * synchronized. */ Mutex xml_parser_mutex; /* * This mutex protects access to XSLT processor. * since we error handling function pointers, access should be * synchronized. */ Mutex xslt_processor_mutex; static void xslt_error_handler(void *ctx, const char *msg, ...) { char buf[4096]; va_list args; assert(ctx!=NULL); va_start(args, msg); VSNPRINTF(buf, sizeof(buf)-1, msg, args); va_end(args); #ifdef FW_XMLTOOLS_VERBOSE cerr << "XSLT ERR: " << buf << endl; #endif *((string*)ctx)+=buf; } xmlNodePtr XMLTools::getXmlChildNode(xmlNodePtr r,const char *child_name) { xmlNodePtr cur; for(cur=r->xmlChildrenNode; cur; cur=cur->next) { if ( xmlIsBlankNode(cur) ) continue; if (strcmp(child_name,FROMXMLCAST(cur->name))==SAME) return cur; } return NULL; } xmlNodePtr XMLTools::getXmlNodeByPath(xmlNodePtr r, const string &path) { return getXmlNodeByPath(r, path.c_str()); } xmlNodePtr XMLTools::getXmlNodeByPath(xmlNodePtr r, const char *path) { char *s1, *cptr; char *path_copy; xmlNodePtr cur, res; res=NULL; path_copy= cxx_strdup( path ); s1=path_copy+strlen(path_copy)-1; while (*s1=='/') { *s1='\0'; s1--; } s1=path_copy; if (*s1=='/') { res=getXmlNodeByPath(r,s1+1); delete[] path_copy; return(res); } cptr=strchr(s1,'/'); if (cptr!=NULL) { *cptr='\0'; cptr++; } if (strcmp(FROMXMLCAST(r->name), s1)==0) { if (cptr) { for(cur=r->xmlChildrenNode; cur; cur=cur->next) { if ( xmlIsBlankNode(cur) ) continue; res=getXmlNodeByPath(cur,cptr); if (res) { delete[] path_copy; return(res); } } } else res=r; } delete[] path_copy; return(res); } xmlExternalEntityLoader XMLTools::defaultLoader = NULL; /** * This is global variable used in 'fwbExternalEntityLoader' * parser callback. It is protected by 'xml_parser_mutex'. */ static char* current_template_dir=NULL; xmlParserInputPtr fwbExternalEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { xmlParserInputPtr ret; #ifdef FW_XMLTOOLS_VERBOSE cerr << "ENTITY: " << URL << " " << string((ID)?ID:"(null)") << endl; #endif string fname; fname=string(current_template_dir) + FS_SEPARATOR; string url=URL; string::size_type pos=url.find_last_of("/\\"); fname+=(pos==string::npos)?url:url.substr(pos+1); #ifdef FW_XMLTOOLS_VERBOSE cerr << "ENTITY FNAME: " << fname << endl; #endif ret = xmlNewInputFromFile(ctxt, fname.c_str()); if(ret) return(ret); else if(XMLTools::defaultLoader) return XMLTools::defaultLoader(URL, ID, ctxt); else return NULL; } void XMLTools::initXMLTools() { // xml_parser_mutex = PTHREAD_MUTEX_INITIALIZER; // xslt_processor_mutex = PTHREAD_MUTEX_INITIALIZER; xmlInitMemory(); xmlInitParser(); defaultLoader = xmlGetExternalEntityLoader(); current_template_dir=cxx_strdup(""); xmlSetExternalEntityLoader(fwbExternalEntityLoader); } void XMLTools::close() { xmlCleanupParser(); } string XMLTools::readFile(const std::string &rfile) throw(FWException) { string buf; if (rfile=="-") { string s; while (!cin.eof()) { getline(cin,s); buf += s; buf += '\n'; } return buf; } gzFile gzf = gzopen(rfile.c_str(), "rb9"); if (gzf == NULL) throw FWException("Could not read file "+rfile); int chunk_size = 65536; char *chunk = (char*)malloc(chunk_size); if (!chunk) throw FWException("Out of memory"); int n = 0; while(1) { n = gzread(gzf, chunk, chunk_size-1); if (n<=0) break; chunk[n] = '\0'; buf = buf + chunk; } int errn = errno; free(chunk); gzclose(gzf); if (n<0) { string s; s = "Error reading from file " + rfile + " : " + string(strerror(errn)); throw FWException(s); } return buf; } xmlDocPtr XMLTools::parseFile(const string &file_name, const string &buffer, bool use_dtd, const string &template_dir) throw(FWException) { xml_parser_mutex.lock(); if (current_template_dir!=NULL) delete[] current_template_dir; current_template_dir = cxx_strdup(template_dir.c_str()); xmlDoValidityCheckingDefaultValue = use_dtd ? 1 : 0; xmlLoadExtDtdDefaultValue = use_dtd ? DTD_LOAD_BITS : 0; string errors; xmlSetGenericErrorFunc(&errors, xslt_error_handler); // xmlDocPtr doc = xmlParseFile(file_name.c_str()); xmlDocPtr doc = xmlParseMemory(buffer.c_str(), buffer.length()); xmlSetGenericErrorFunc(NULL, NULL); xml_parser_mutex.unlock(); if (!doc || errors.length()) { throw FWException( "Error parsing XML from file '"+file_name+ "' "+ "(use_dtd="+ (use_dtd?string("1"):string("0"))+") "+ (errors.length() ? ( string("\nXML Parser reported:\n")+errors):string("")) ); } return doc; } xmlDocPtr XMLTools::loadFile(const string &data_file , const string &type , const string &dtd_file , const UpgradePredicate *upgrade, const string &template_dir, const string ¤t_version ) throw(FWException) { #ifdef FW_XMLTOOLS_VERBOSE cerr << "Loading file: " << data_file << endl << " type: " << type << endl << " dtd_file: " << dtd_file << endl << " template_dir: " << template_dir << endl << " current_version: " << current_version << endl; #endif int access_err = 0; if (data_file!="-" && (access_err=access(data_file.c_str() , R_OK ))!=0) { string access_err_str; switch (access_err) { case EACCES: access_err_str = "EACCES"; break; case EFAULT: access_err_str = "EFAULT"; break; case EIO: access_err_str = "EIO"; break; #ifdef ELOOP case ELOOP: access_err_str = "ELOOP"; break; #endif case ENAMETOOLONG: access_err_str = "ENAMETOOLONG"; break; case ENOENT: access_err_str = "ENOENT"; break; case ENOTDIR: access_err_str = "ENOTDIR"; break; default: access_err_str = "Unknown"; break; } throw FWException( string("Could not access data file '") + data_file + "'" + " error code " + access_err_str); } string buf = readFile(data_file); // First load without using DTD to check version xmlDocPtr doc = parseFile(data_file, buf, false, template_dir); #ifdef FW_XMLTOOLS_VERBOSE cerr << "Parsed file: " << data_file << endl; #endif // normally we load the file twice, first time to check the version and // upgrade it and the second time to generate doc that will be // used in the program. We can't do this if data_file is '-' (stdin) // 'cause we can't read stdin twice. So in this case we do not // upgrade. if (data_file=="-") return doc; xmlDocPtr newdoc = convert(doc, data_file, type, template_dir, current_version); if(newdoc) { const string upgrade_msg = "The file '" + data_file + "' was saved with\n\ an older version of Firewall Builder. Opening it in this version will\n\ cause it to be upgraded, which may prevent older versions of the program\n\ from reading it. Backup copy of your file in the old format will be made\n\ in the same directory with extension '.bak'. Are you sure you want to open it?"; if(!(*upgrade)(upgrade_msg)) { xmlFreeDoc(newdoc); //xmlCleanupParser(); throw FWException("Load operation cancelled for file: '"+data_file); } #ifdef FW_XMLTOOLS_VERBOSE cerr << "Saving updated file: " << data_file << endl; #endif // file was changed save it doc=newdoc; string backup_file = data_file+".bak"; // on windows rename fails if target file already exists unlink(backup_file.c_str()); if(rename(data_file.c_str(), backup_file.c_str())) { xmlFreeDoc(doc); //xmlCleanupParser(); throw FWException("Error making backup copy of file: '" + data_file + "' as '" + backup_file + "'"); } try { saveFile(doc, data_file, type, dtd_file); } catch(FWException &ex) { // Saving converted copy failed // let's restore backup if(rename(backup_file.c_str(), data_file.c_str())) { throw FWException(ex.toString() + "\nRestoring backup copy failed " + "your old data could be found in the file: '"+ backup_file+"'"); } else throw; } } assert(doc!=NULL); xmlFreeDoc(doc); //xmlCleanupParser(); // Now we know the version is OK, // let us load for real, checking DTD. doc = parseFile(data_file, readFile(data_file), true, template_dir); return doc; } void XMLTools::setDTD(xmlDocPtr doc, const string &type_name, const string &dtd_file) throw(FWException) { #ifdef FW_XMLTOOLS_VERBOSE cerr << "XMLTools::setDTD: type_name=" << type_name << " dtd_file=" << dtd_file << endl; #endif xmlCreateIntSubset(doc, STRTOXMLCAST(type_name), NULL, STRTOXMLCAST(dtd_file) ); xml_parser_mutex.lock(); xmlDoValidityCheckingDefaultValue = 1; xmlLoadExtDtdDefaultValue = DTD_LOAD_BITS; xmlSubstituteEntitiesDefaultValue = 1; string errors; xmlSetGenericErrorFunc (&errors, xslt_error_handler); try { /* * This broke with libxml 2.6.4. Tests seem to rule out bug inside * libxml2 (used their example program "tree2.c" and added similar * fragment for validation, it worked), so it must be something in our * code. I can't seem to find the problem though. * * We recreate the tree from the objects in the memory, so doing * validation here is mostly a double check. It should be relatively * safe to just skip validation until I figure out what's wrong with * it. xmlValidCtxt vctxt; vctxt.userData = &errors; vctxt.error = xslt_error_handler; vctxt.warning = xslt_error_handler; if(xmlValidateDocument(&vctxt, doc)!=1) throw FWException(string("DTD validation stage 2 failed with following errors:\n")+errors); */ xmlSetGenericErrorFunc (NULL, NULL); xml_parser_mutex.unlock(); } catch(...) { xmlSetGenericErrorFunc (NULL, NULL); xml_parser_mutex.unlock(); throw; } } void XMLTools::saveFile(xmlDocPtr doc, const string &file_name, const string &type_name, const string &dtd_file) throw(FWException) { #ifdef FW_XMLTOOLS_VERBOSE cerr << "SAVE: " << file_name << " " <name || type_name!=FROMXMLCAST(root->name)) { xmlFreeDoc(doc); //xmlCleanupParser(); throw FWException("XML file '"+file_name+ "' has invalid structure."); } string vers; const char *v = FROMXMLCAST(xmlGetProp(root,TOXMLCAST("version"))); if (v==NULL) { // no version. v="0.8.7"; // at this version attribute has been introduced xmlNewProp(root, TOXMLCAST("version") , TOXMLCAST(v)); res=doc; // changed vers=v; } else { vers=v; FREEXMLBUFF(v); } #ifdef FW_XMLTOOLS_VERBOSE cerr << "File reports version : " << vers << endl; #endif int c; while (!vers.empty() && (c=version_compare(current_version,vers))!=0) { if(c<0) { string err; err += string("The file '"); err += file_name; err += string("' "); err += string("was created by a newer version of " "Firewall Builder, please upgrade in order to " "open this file."); err += string("\n"); err += string("\n"); err += string("DTD version in the file: "); err += vers; err += string(" current: "); err += current_version; throw FWException(err); } string oldversion = vers; #ifdef FW_XMLTOOLS_VERBOSE cerr << "Converting from version: " << oldversion << endl; #endif string fname; fname = template_dir; fname = fname+FS_SEPARATOR+"migration"+FS_SEPARATOR+type_name+"_"+vers+".xslt"; if (access(fname.c_str() , R_OK )!=0) { xmlFreeDoc(doc); //xmlCleanupParser(); throw FWException( string("File '" + file_name + "' conversion error: no converter found for version: ") + oldversion+".\n" + string("Supposed to be a file ")+fname ); } try { res = transformDocument(doc, fname, NULL); } catch(FWException &ex) { ex.getProperties()["failed_transformation"]=fname; xmlFreeDoc(doc); //xmlCleanupParser(); throw; } xmlFreeDoc(doc); //xmlCleanupParser(); doc = res; root = xmlDocGetRootElement(doc); if (!root || !root->name || type_name!=FROMXMLCAST(root->name)) { xmlFreeDoc(doc); //xmlCleanupParser(); throw FWException("File '" + file_name + "' conversion Error: conversion produced file with invalid structure."); } v = FROMXMLCAST(xmlGetProp(root, TOXMLCAST("version"))); if (v==NULL) { xmlFreeDoc(doc); //xmlCleanupParser(); throw FWException("File '" + file_name + "' conversion error: converted to unknown version."); } vers=v; FREEXMLBUFF(v); if (version_compare(vers, oldversion) <= 0) { xmlFreeDoc(doc); //xmlCleanupParser(); throw FWException("File '" + file_name + "' conversion error: conversion did not advance version number!."); } } return res; } int XMLTools::major_number(const string &v, string &rest) { string a; string::size_type pos=v.find('.'); if(pos==string::npos) { a = v; rest = ""; } else { a = v.substr(0,pos); rest = v.substr(pos+1); } //TODO: handle conversion errors, by using 'strtol' if (a.empty()) a = "0"; return atoi(v.c_str()); } /* * Compare two version numbers. * If versions have different length (different total number of components) * consider missing components equal to zero. That is, * 1.2.3 is equal to 1.2.3.0 so, if we have to compare "1.2.3.4" to "1.2.3", then * this is equivalent to comparing "1.2.3.4" to "1.2.3.0". The opposite * is also true. */ int XMLTools::version_compare(const string &v1, const string &v2) { string rest1, rest2; int x1=major_number(v1, rest1); int x2=major_number(v2, rest2); if (rest1.empty() && rest2.empty()) return x1-x2; if (rest1.empty() && !rest2.empty()) rest1 = "0"; if (rest2.empty() && !rest1.empty()) rest2 = "0"; if (x1!=x2) return x1-x2; else return version_compare(rest1, rest2); } string XMLTools::quote_linefeeds(const string &s) { string res; for(string::size_type i=0;i127) res[i]='?'; } return res; } #undef DTD_LOAD_BITS #undef FW_XMLTOOLS_VERBOSE fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Interface.cpp0000644000175000017500000003501111733011756025415 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Host.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Resources.h" using namespace std; using namespace libfwbuilder; const char *Interface::TYPENAME={"Interface"}; Interface::Interface(const Interface &i):Address() { FWObject::operator=(i); bcast_bits = i.bcast_bits ; ostatus = i.ostatus ; snmp_type = i.snmp_type ; } Interface::Interface():Address() { setName("unknown"); setBool("dyn", false); setBool("unnum", false); setBool("unprotected", false); setBool("dedicated_failover", false); setInt("security_level",0); bcast_bits = 1 ; ostatus = true ; snmp_type = -1 ; } Interface::~Interface() {} /** * Add reference to given object. In case of an Interface this only * makes sense in terms of adding @obj as a network zone. */ void Interface::addRef(FWObject *obj) { setStr("network_zone", FWObjectDatabase::getStringId(obj->getId())); } /** * Removes reference to given object among children of 'this'. In case * of Interface we check if @obj is used as network zone. */ void Interface::removeRef(FWObject *obj) { string netzone_id = getStr("network_zone"); FWObject *netzone = getRoot()->findInIndex( FWObjectDatabase::getIntId(netzone_id)); if (obj == netzone) setStr("network_zone", ""); } FWObject& Interface::shallowDuplicate(const FWObject *o, bool preserve_id) throw(FWException) { FWObject::shallowDuplicate(o,preserve_id); if (Interface::isA(o)) { bcast_bits = Interface::constcast(o)->bcast_bits ; ostatus = Interface::constcast(o)->ostatus ; snmp_type = Interface::constcast(o)->snmp_type ; } return *this; } FWObject& Interface::duplicate(const FWObject *x, bool preserve_id) throw(FWException) { FWObject::duplicate(x, preserve_id); const Interface *rx = Interface::constcast(x); if (rx!=NULL) { bcast_bits = rx->bcast_bits; ostatus = rx->ostatus; snmp_type = rx->snmp_type; } return *this; } void Interface::duplicateWithIdMapping(const FWObject *src, map &id_mapping, bool preserve_id) { assert(src->getTypeName() == Interface::TYPENAME); checkReadOnly(); shallowDuplicate(src, preserve_id); destroyChildren(); for(list::const_iterator m=src->begin(); m!=src->end(); ++m) { FWObject *src_obj = *m; FWObject *dst_obj_copy = addCopyOf(src_obj, preserve_id); if (src_obj!=NULL && dst_obj_copy!=NULL) id_mapping[src_obj->getId()] = dst_obj_copy->getId(); } setDirty(true); } bool Interface::cmp(const FWObject *obj, bool recursive) throw(FWException) { const Interface *rx = Interface::constcast(obj); if (rx == NULL) return false; if (bcast_bits != rx->bcast_bits || ostatus != rx->ostatus || snmp_type != rx->snmp_type) return false; return FWObject::cmp(obj, recursive); } void Interface::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("security_level"))); if (n!=NULL) { setStr("security_level",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dyn"))); if (n!=NULL) { setStr("dyn",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("unnum"))); if (n!=NULL) { setStr("unnum",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("unprotected"))); if (n!=NULL) { setStr("unprotected",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dedicated_failover"))); if (n!=NULL) { setStr("dedicated_failover",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("mgmt"))); if (n!=NULL) { setStr("mgmt",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("label"))); if (n!=NULL) { setStr("label",n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("network_zone"))); if (n!=NULL) { setStr("network_zone", n); FREEXMLBUFF(n); } } /* * */ xmlNodePtr Interface::toXML(xmlNodePtr parent) throw(FWException) { // DTD prohibits empty network_zone attribute if (exists("network_zone") && getStr("network_zone").empty()) remStr("network_zone"); xmlNodePtr me = FWObject::toXML(parent, false); FWObject *o; xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); for(FWObjectTypedChildIterator j1=findByType(IPv4::TYPENAME); j1!=j1.end(); ++j1) { if ((o=(*j1))!=NULL ) o->toXML(me); } for(FWObjectTypedChildIterator j1=findByType(IPv6::TYPENAME); j1!=j1.end(); ++j1) { if ((o=(*j1))!=NULL ) o->toXML(me); } for(FWObjectTypedChildIterator j2=findByType(physAddress::TYPENAME); j2!=j2.end(); ++j2) { if ((o=(*j2))!=NULL ) o->toXML(me); } o = getFirstByType(InterfaceOptions::TYPENAME); if (o) o->toXML(me); /* * serialize sub-interfaces (only for interfaces with advanced interface * config mode enabled) */ for(FWObjectTypedChildIterator j1=findByType(Interface::TYPENAME); j1!=j1.end(); ++j1) { if((o=(*j1))!=NULL) o->toXML(me); } /* * serialize ClusterGroup members (if any) */ o = getFirstByType(FailoverClusterGroup::TYPENAME); if (o) o->toXML(me); o = getFirstByType(AttachedNetworks::TYPENAME); if (o) o->toXML(me); return me; } FWOptions* Interface::getOptionsObject() { FWOptions *iface_opt = FWOptions::cast(getFirstByType(InterfaceOptions::TYPENAME)); if (iface_opt == NULL) { iface_opt = FWOptions::cast(getRoot()->create(InterfaceOptions::TYPENAME)); add(iface_opt); // set default interface options const FWObject *parent_host = Host::getParentHost(this); if (parent_host != NULL) { const string host_OS = parent_host->getStr("host_OS"); try { Resources::setDefaultIfaceOptions(host_OS, this); } catch (FWException &ex) { // Resources::setDefaultIfaceOptions throws exception if it can't // find resources module for the given host OS. ; } } } return iface_opt; } FWOptions* Interface::getOptionsObjectConst() const { FWOptions *iface_opt = FWOptions::cast(getFirstByType(InterfaceOptions::TYPENAME)); if (iface_opt == NULL) cerr << "Interface " << getName() << " (" << getPath() << ") " << " has no options object; late initialization failure" << endl; return iface_opt; } int Interface::getSecurityLevel() const { return getInt("security_level") ; } void Interface::setSecurityLevel(int level) { setInt("security_level",level); } void Interface::setDyn(bool value) { setBool("dyn",value); } bool Interface::isDyn() const { return(getBool("dyn")); } void Interface::setUnnumbered(bool value) { setBool("unnum",value); } bool Interface::isUnnumbered() const { return getBool("unnum"); } void Interface::setUnprotected(bool value) { setBool("unprotected",value); } bool Interface::isUnprotected() const { return getBool("unprotected") || getBool("dedicated_failover"); } void Interface::setDedicatedFailover(bool value) { setBool("dedicated_failover",value); } bool Interface::isDedicatedFailover() const { return getBool("dedicated_failover"); } void Interface::setManagement(bool value) { setBool("mgmt",value); } bool Interface::isManagement() const { return (getBool("mgmt")); } void Interface::setOStatus(bool value) { ostatus=value; } void Interface::setInterfaceType(int _snmp_type) { snmp_type=_snmp_type; } void Interface::setBroadcastBits(int _val) { bcast_bits=_val; } bool Interface::validateChild(FWObject *o) { string otype=o->getTypeName(); if (otype==Interface::TYPENAME) { // Interface with subinterfaces is not allowed (DTD allows only one // level of subinterfaces) if (Interface::isA(getParent())) return false; list il = o->getByType(Interface::TYPENAME); return (il.size() == 0); } return (otype==IPv4::TYPENAME || otype==IPv6::TYPENAME || otype==physAddress::TYPENAME || otype==InterfaceOptions::TYPENAME || otype==FailoverClusterGroup::TYPENAME || otype==AttachedNetworks::TYPENAME); } /* * I get options obect directly instead of calling getOptionsObject() * because that method tries to add options object if it is missing, * which means @this can not be const. */ bool Interface::isBridgePort() const { string my_type; FWOptions *iface_opt = getOptionsObjectConst(); if (iface_opt) my_type = iface_opt->getStr("type"); Interface *parent = Interface::cast(getParent()); return ((my_type.empty() || my_type == "ethernet") && parent && parent->getOptionsObject()->getStr("type") == "bridge"); } bool Interface::isSlave() const { string my_type; FWOptions *iface_opt = getOptionsObjectConst(); if (iface_opt) my_type = iface_opt->getStr("type"); Interface *parent = Interface::cast(getParent()); return ((my_type.empty() || my_type == "ethernet") && parent && parent->getOptionsObject()->getStr("type") == "bonding"); } bool Interface::isLoopback() const { const Address *iaddr = getAddressObject(); if (iaddr) { return (iaddr && *(iaddr->getAddressPtr()) == InetAddr::getLoopbackAddr()); } /* just a little flexibility in case this is a cluster interface: it * should be considered loopback if corresponding member * interfaces are loopbacks themselves even if it has no address */ if (isFailoverInterface()) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { bool all_loopbacks = true; for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *iface = Interface::cast(FWObjectReference::getObject(*it)); assert(iface); if (!iface->isLoopback()) { all_loopbacks = false; break; } } return all_loopbacks; } } return false; } physAddress* Interface::getPhysicalAddress () const { return physAddress::cast( getFirstByType( physAddress::TYPENAME ) ); } /* * per DTD, there can be 0 or 1 physAddress */ void Interface::setPhysicalAddress(const std::string &paddr) { physAddress *pa=getPhysicalAddress(); if (pa!=NULL) { pa->setPhysAddress(paddr); } else { pa = getRoot()->createphysAddress(); pa->setPhysAddress(paddr); add(pa); } } const string& Interface::getLabel() const { return getStr("label"); } void Interface::setLabel(const string& n) { setStr("label",n); } const Address* Interface::getAddressObject() const { Address *res = Address::cast(getFirstByType(IPv4::TYPENAME)); if (res==NULL) res = Address::cast(getFirstByType(IPv6::TYPENAME)); return res; } IPv4* Interface::addIPv4() { IPv4* ipv4 = getRoot()->createIPv4(); add(ipv4); return ipv4; } IPv6* Interface::addIPv6() { IPv6* ipv6 = getRoot()->createIPv6(); add(ipv6); return ipv6; } int Interface::countInetAddresses(bool skip_loopback) const { if (skip_loopback && isLoopback()) return 0; int res = 0; for(FWObjectTypedChildIterator j=findByType(IPv4::TYPENAME); j!=j.end(); ++j) res++; for(FWObjectTypedChildIterator j=findByType(IPv6::TYPENAME); j!=j.end(); ++j) res++; return res; } bool Interface::isFailoverInterface() const { return getFirstByType(FailoverClusterGroup::TYPENAME) != NULL; } void Interface::replaceReferenceInternal(int old_id, int new_id, int &counter) { if (old_id == new_id) return; FWObject::replaceReferenceInternal(old_id, new_id, counter); string nzid = getStr("network_zone"); if (!nzid.empty()) { int nzid_int = FWObjectDatabase::getIntId(nzid); if (nzid_int == old_id) { setStr("network_zone", FWObjectDatabase::getStringId(new_id)); counter++; } } } /* * finds all interfaces of the host (or firewall, since class Firewall * inherits Host) without scanning whole tree rooted at this. This is * more efficient than calling getByTypeDeep() when firewall has lots * of rules. */ void Interface::findAllInterfaces(FWObject *obj, list &interfaces) { for (FWObjectTypedChildIterator it = obj->findByType(Interface::TYPENAME); it != it.end(); ++it) { interfaces.push_back(*it); findAllInterfaces(*it, interfaces); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Service.cpp0000644000175000017500000000324011733011756025114 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Zaliva $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Service.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWObjectDatabase.h" using namespace libfwbuilder; using namespace std; const char *Service::TYPENAME={"Service"}; string Service::getProtocolName() const { throw FWException("base class Service does not return protocol name"); } int Service::getProtocolNumber() const { throw FWException("base class Service does not return protocol number"); } FWReference* Service::createRef() { // FWServiceReference *ref=new FWServiceReference(); FWServiceReference *ref = getRoot()->createFWServiceReference(); ref->setPointer(this); return ref; } bool Service::isAny() const { return getId()==FWObjectDatabase::ANY_SERVICE_ID; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Interface.h0000644000175000017500000001677211733011756025077 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INTERFACE_HH_FLAG__ #define __INTERFACE_HH_FLAG__ #include #include "fwbuilder/Address.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/FWException.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/FWOptions.h" namespace libfwbuilder { class IPv4; class IPv6; class Interface : public Address { private: /* * @param _bcast_bits The value of the least-significant bit in the IP * broadcast address used for sending datagrams on * the (logical) interface associated with the IP * address of this entry. For example, when the * Internet standard all-ones broadcast address is * used, the value will be 1. This value applies to * both the subnet and network broadcasts addresses * used by the entity on this (logical) interface." * * @param _snmp_type type of interface, as described in RFC-1213 under * 'ifType' variable description. * @param _ostatus, interface operational status. 'true' means up. * * These attrbites are not stored in XML yet. */ int bcast_bits; bool ostatus; int snmp_type; protected: virtual void replaceReferenceInternal(int oldfw_id, int newfw_id, int &counter); public: Interface(); Interface(const Interface &i); virtual ~Interface(); /** * Removes reference to given object among * children of 'this'. In case of an Interface, we should check for * if the reference to @obj is used as a network zone. */ virtual void removeRef(FWObject *obj); /** * Add reference to given object to 'this'. In case of an Interface, * add @obj as a network zone. */ virtual void addRef(FWObject *obj); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool validateChild(FWObject *o); virtual FWOptions* getOptionsObject(); virtual FWOptions* getOptionsObjectConst() const; DECLARE_FWOBJECT_SUBTYPE(Interface); DECLARE_DISPATCH_METHODS(Interface); /** * each interface must be associated with some security level. Level * is described by interger number between 0 and 100, with 0 being * least secure and 100 most secure levels. By default class Interface * assigns value of 0 to its security level. */ int getSecurityLevel() const; void setSecurityLevel(int level); /** * set and check 'dyn' attribute - for interfaces that get their * IP address dynamically */ void setDyn(bool value); bool isDyn() const ; /** * set and check 'unnum' attribute - for unnumbered interfaces */ void setUnnumbered(bool value); bool isUnnumbered() const ; /** * Check if this is a bridge port. Bridge port is an * interfaces with type "ethernet" that is a child of an * interface with type "bridge". Type is defined in the * InterfaceOptions object. This is different from how it was * in v3.0.x where bridge port was defined by an attribute * "bridgeport" of the interface object. There is no * automatic conversion! User must conver their bridge port * interfaces manually by dragging them under the bridge * interface (typically br0) and setting the type * appropriately. * */ bool isBridgePort() const; /** * Check if this is a slave of bonding interface. Slave is an * interfaces with type "ethernet" that is a child of an * interface with type "bonding". Type is defined in the * InterfaceOptions object. */ bool isSlave() const; /** * we often need to check if this is a regular interface * Equivalent to (!isDyn() && !isUnnumbered() && !isBridgePort()) */ bool isRegular() const { return (!isDyn() && !isUnnumbered() && !isBridgePort()); } /** * set and check 'unprotected' attribute - for interfaces that * should not have any ACLs or policy rules */ void setUnprotected(bool value); bool isUnprotected() const ; void setDedicatedFailover(bool value); bool isDedicatedFailover() const; void setManagement(bool value); bool isManagement() const; bool isUp () const { return ostatus; } void setOStatus(bool value); bool isFailoverInterface() const; void setInterfaceType(int _snmp_type); int getInterfaceType() const { return snmp_type; } void setBroadcastBits(int _val); /** * returns true if interface is loopback. Should work correctly * for both ipv4 and ipv6 (some day) */ bool isLoopback() const; IPv4* addIPv4(); IPv6* addIPv6(); physAddress* getPhysicalAddress () const; void setPhysicalAddress(const std::string &pa); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual FWObject& duplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); void duplicateWithIdMapping(const FWObject *src, std::map &id_mapping, bool preserve_id); const std::string &getLabel() const; void setLabel(const std::string& n); virtual const Address* getAddressObject() const; virtual unsigned int dimension() const { return 1; } /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool skip_loopback) const; virtual bool isPrimaryObject() const { return false; } /** * finds all interfaces of the host (or firewall, since class * Firewall inherits Host) without scanning whole tree rooted * at this. This is more efficient than calling * getByTypeDeep() when firewall has lots of rules. */ static void findAllInterfaces(FWObject *obj, std::list &interfaces); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/DynamicGroup.h0000644000175000017500000000473011733011756025567 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DynamicGroup_h__ #define __DynamicGroup_h__ #include "fwbuilder/MultiAddress.h" namespace libfwbuilder { class DynamicGroup : public MultiAddress { std::list m_filter; public: DynamicGroup(); virtual ~DynamicGroup(); DECLARE_FWOBJECT_SUBTYPE(DynamicGroup); DECLARE_DISPATCH_METHODS(DynamicGroup); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); /* Each list entry is comma-separated list of matching criteria */ const std::list &getFilter() { return m_filter; } void setFilter(const std::list &filter) { m_filter = filter; } static bool splitFilter(const std::string &str, std::string &type, std::string &keyword); static bool makeFilter(std::string &filter, const std::string &type, const std::string &keyword); virtual bool cmp(const FWObject *obj, bool recursive=false) throw (FWException); virtual FWObject& shallowDuplicate(const FWObject *other, bool preserve_id) throw (FWException); virtual bool isCompileTime() const; virtual void loadFromSource(bool ipv6, FWOptions *options, bool test_mode=false) throw (FWException); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); bool isMemberOfGroup(FWObject *obj); static const char *TYPE_NONE; static const char *TYPE_ANY; static const char *KEYWORD_NONE; static const char *KEYWORD_ANY; }; } #endif /* __DynamicGroup_h__ */ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ICMP6Service.cpp0000644000175000017500000000247611733011756025665 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *ICMP6Service::TYPENAME={"ICMP6Service"}; ICMP6Service::ICMP6Service() : ICMPService() { } ICMP6Service::~ICMP6Service() {} string ICMP6Service::getProtocolName() const { return "icmp6";} int ICMP6Service::getProtocolNumber() const { return 58; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/BackgroundOp.h0000644000175000017500000000761311733011756025547 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BACKGROUNDOP_HH_FLAG__ #define __BACKGROUNDOP_HH_FLAG__ #include #include #ifdef __MINGW32__ //win32 pthread ditrib doesn't have config.h # ifdef HAVE_CONFIG_H # undef HAVE_CONFIG_H # include # define HAVE_CONFIG_H # endif #else # include #endif #include "fwbuilder/FWException.h" #include "fwbuilder/Tools.h" #include "fwbuilder/ThreadTools.h" #include "fwbuilder/Pool.h" #include "fwbuilder/Logger.h" // #include namespace libfwbuilder { void *background_thread(void *); /** * Abstract class BackgroundOp represents operatioin executed in background */ class BackgroundOp { friend void *background_thread(void *); private: SyncFlag running ; SyncFlag connected ; pthread_attr_t tattr; protected: SyncFlag *stop_program ; FWException *error ; SyncFlag *iamdead ; /** * Implementation of the actual operation. Use logger to send * output text to the GUI. The SyncFlag is a mutex flag used to * interrupt background operation. We can't keep this flag as a * member of the class BackgroundOp because object of this class * gets destroyed before actual background operation has finished * (especially if it got stuck in a system call). To avoid having * to use object of the class BackgroundOp and any of its members * or methods, we create this flag as a dynamic variable and pass * pointer to run_impl, which should destroy it when it finishes. */ virtual void run_impl(Logger *,SyncFlag *) throw(FWException) = 0; /** * sets flag "running" */ void setRunning(); /** * clears flag "running" */ void clearRunning(); /** * checks "stop" flag and terminates thread if it is set. Used * from inside run_impl to check if background operation should be * immediately interrupted */ #define CHECK_STOP_AND_RETURN { stop_program->lock();\ if ( stop_program->peek() ){ stop_program->unlock(); return; }\ stop_program->unlock(); } #define CHECK_STOP_AND_THROW_EXCEPTION { stop_program->lock();\ if ( stop_program->peek() ){ stop_program->unlock(); throw FWException("Interrupted"); }\ stop_program->unlock(); } public: BackgroundOp(); virtual ~BackgroundOp(); /** * checks whether background operation is connected to GUI */ bool isConnected(); /** * disconnects background operation from the GUI */ void disconnect(); /** * Initiates background operation */ virtual Logger* start_operation() throw(FWException); /** * Stops background operation */ virtual void stop_operation(); /** * returns flag "running" */ bool isRunning(); /** * returns last error from the background operation. The meaning of * the error is determined by the operation */ FWException *get_latest_error() { return error; } }; } #endif // __BACKGROUNDOP_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/inet_net.h0000644000175000017500000000471711733011756025000 0ustar sylvestresylvestre/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef INET_NET_H #define INET_NET_H #include "fwbuilder/libfwbuilder-config.h" #ifdef _WIN32 # include // missing errno definitions: #define EMSGSIZE 40 /* Message too long */ #define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ #else # include # include //# include # include # include #endif /* * char * * inet_net_ntop(af, src, bits, dst, size) * convert host/network address from network to presentation format. * "src"'s size is determined from its "af". * return: * pointer to dst, or NULL if an error occurred (check errno). * note: * 192.5.5.1/28 has a nonzero host part, which means it isn't a network * as called for by inet_net_pton() but it can be a host address with * an included netmask. * author: * Paul Vixie (ISC), October 1998 */ extern char* inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size); /* * int * inet_net_pton(af, src, dst, size) * convert network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not a valid network specification. * author: * Paul Vixie (ISC), June 1996 * * Changes: * I added the inet_cidr_pton function (also from Paul) and changed * the names to reflect their current use. * */ extern int inet_net_pton(int af, const char *src, void *dst, size_t size); #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/RuleSet.h0000644000175000017500000000762011733011756024552 0ustar sylvestresylvestre /* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RULESET_HH_FLAG__ #define __RULESET_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/Rule.h" #include "fwbuilder/InetAddr.h" namespace libfwbuilder { class RuleSet : public FWObject { private: bool ipv4; bool ipv6; bool top; protected: public: RuleSet(); virtual ~RuleSet(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); DECLARE_FWOBJECT_SUBTYPE(RuleSet); DECLARE_DISPATCH_METHODS(RuleSet); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual FWOptions* getOptionsObject(); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); // Both ipv4 and ipv6 variables can be set to true, which means // this is "dual" rule set. When both are false, this is ipv4-only // rule set (for backwards compatibility and to avoid having to // increment DTD version number) bool isV4() const { return (ipv4 || (!ipv4 && !ipv6)); } bool isV6() const { return (ipv6); } bool isDual() const { return (ipv4 && ipv6); } bool matchingAddressFamily(int af) { if (af == AF_INET && isV4()) return true; if (af == AF_INET6 && isV6()) return true; return false; } void setV4() { ipv4=true; ipv6=false; } void setV6() { ipv4=false; ipv6=true; } void setDual() { ipv4=true; ipv6=true; } bool isTop() const { return top; } void setTop(bool f) { top=f; } Rule* getRuleByNum(int n); Rule* insertRuleAtTop(bool hidden_rule=false); Rule* insertRuleBefore(int rule_n); Rule* appendRuleAfter(int rule_n); Rule* appendRuleAtBottom(bool hidden_rule=false); bool deleteRule(int rule_n); bool deleteRule(Rule *r); bool moveRuleUp(int rule_n); bool moveRuleDown(int rule_n); bool moveRule(int src_rule_n,int dst_rule_n); bool disableRule(int rule_n); bool enableRule(int rule_n); bool isRuleDisabled(int rule_n); int getRuleSetSize(); virtual Rule* createRule() = 0; virtual bool isPrimaryObject() const { return false; } void renumberRules(); /** * scan all rules of all rule sets and call setUniqueId() to set * unique string id for each rule. These IDs will be carried * through calls to duplicate() when firewall object and its rule * sets are cloned. These IDs are used by compilers to generate * stable labels for chains and such. */ void assignUniqueRuleIds(); struct UniqueRuleIdsSetter { void operator()(FWObject *o) { RuleSet *rs = RuleSet::cast(o); if (rs != NULL) rs->assignUniqueRuleIds(); } }; }; //__RULESET_HH_FLAG__ } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/AttachedNetworks.h0000644000175000017500000000305011733011756026432 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ATTACHEDNETWORKS_HH_ #define _ATTACHEDNETWORKS_HH_ #include "fwbuilder/MultiAddress.h" namespace libfwbuilder { class AttachedNetworks : public MultiAddress { private: void addNetworkObject(const InetAddrMask &addr_mask); public: DECLARE_FWOBJECT_SUBTYPE(AttachedNetworks); DECLARE_DISPATCH_METHODS(AttachedNetworks); AttachedNetworks(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual void loadFromSource(bool ipv6, FWOptions *options, bool test_mode=false) throw(FWException); virtual std::string getSourceName(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectDatabase_tree_ops.cpp0000644000175000017500000005651111733011756030515 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/Host.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" #include "fwbuilder/Interface.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWIntervalReference.h" #include #include using namespace std; using namespace libfwbuilder; class FWObjectTreeScanner { FWObjectDatabase *treeRoot; map srcMap; map dstMap; FWObjectDatabase::ConflictResolutionPredicate *crp; bool defaultCrp; int reference_object_id_offset; void walkTree(map &m,FWObject *root); void addRecursively(FWObject *src); public: FWObjectTreeScanner(FWObject *r, FWObjectDatabase::ConflictResolutionPredicate *_crp=NULL) { reference_object_id_offset = 1000000; treeRoot=FWObjectDatabase::cast(r); defaultCrp=false; if (_crp==NULL) { crp=new FWObjectDatabase::ConflictResolutionPredicate(); defaultCrp=true; } else crp=_crp; } ~FWObjectTreeScanner() { if (defaultCrp) delete crp; } void scanAndAdd(FWObject *dst,FWObject *source); void merge( FWObject *dst,FWObject *source); }; /* * why does FWReference not have an 'id' attribute ? Marginal savings * in the size of the data file turns into a major headache in coding * things such as tree merge. * * Here, in effect, I am artifically adding IDs to references. */ void FWObjectTreeScanner::walkTree(map &m, FWObject *root) { if (root->haveId()) m[root->getId()]=root; if (FWReference::cast(root)!=NULL) { FWReference *r=FWReference::cast(root); // need to add reference to the map, but references do not have // their own Id. Create new id using id of the object reference // points to, plus some offset. // I can not just generate new uniq id because I need to be able // to find this object later, and for that its id must be predictable. m[reference_object_id_offset+r->getPointerId()]=root; } for (FWObject::iterator i=root->begin(); i!=root->end(); i++) { walkTree(m, *i); } } void FWObjectTreeScanner::addRecursively(FWObject *src) { if (src==NULL) return; if (treeRoot->getId()==src->getId()) return ; addRecursively(src->getParent()); if (dstMap[src->getId()]==NULL) { // last arg.==false : do not call method init() of the new object to // make sure it doesn't create its children FWObject *o1 = treeRoot->create(src->getTypeName(), -1, false); FWObject *pdst = dstMap[src->getParent()->getId()]; assert(pdst!=NULL); // no validation is necessary - this copies existing tree pdst->add(o1, false); if (src->size()==0) o1->shallowDuplicate(src, false); else { if (Firewall::isA(src) || Host::isA(src) || Interface::isA(src) ) o1->duplicate(src, false); else { /* copy system groups (folders) partially, but user's * groups should be copied as a whole. There is no * definite and simple * way to tell them apart, except * that user groups contain references * while system * groups contain objects. */ if (Group::cast(src)!=NULL && FWReference::cast(src->front())!=NULL) o1->duplicate(src, false); else o1->shallowDuplicate(src, false); } } walkTree( dstMap , o1 ); // there are children objects if we did a deep copy } } /* * scans tree treeRoot and finds references to missing objects. Tries * to add an object from 'source' by adding all missing objects * between it and a tree root. Method addRecusrively climbs up from * the objects that it needs to add to the root by doing recursive * calls to itself, then while it exist invokations it adds objects to * the tree. Since added objects are appended to the end of each level * of the tree, method scanAndAdd finds them later. For example, if * 'Standard' library was added because some standard object was * referenced but missing, this library will be found in the loop in * scanAndAdd even if it wasn't there when the loop started. This * ensures that this method will pull in any objects referenced from * objects it included, recursively. * */ void FWObjectTreeScanner::scanAndAdd(FWObject *dst,FWObject *source) { if (dst==NULL) { dst=treeRoot; walkTree(dstMap,treeRoot); walkTree(srcMap, source); } for (FWObject::iterator i=dst->begin(); i!=dst->end(); i++) { FWObject *o1=*i; if (FWReference::cast(o1)!=NULL) { int pid = FWReference::cast(o1)->getPointerId(); FWObject *o2 = dstMap[pid]; if (o2==NULL) { FWObject *osrc = srcMap[ pid ]; if (osrc==NULL) cerr << "Object with ID=" << pid << " (" << FWObjectDatabase::getStringId(pid) << ") " << " disappeared" << endl; else addRecursively( osrc); } } else scanAndAdd( o1 , source ); } // TODO: do the same for the objects referenced by // rule actions Branch and Tag - find those objects and add. // Wrap operations with network_zone in methods of class Interface, // setNetworkZone(FWObject*) getNetworkZone() // (Just like Rule::getBranch Rule::setBranch) // if (Interface::isA(dst)) { string sid = dst->getStr("network_zone"); if ( !sid.empty() ) { int pid = FWObjectDatabase::getIntId(sid); FWObject *o2 = dstMap[pid]; if (o2==NULL) { FWObject *osrc = srcMap[ pid ]; addRecursively( osrc); } } } } // #define DEBUG_MERGE 1 void FWObjectTreeScanner::merge(FWObject *dst, FWObject *src) { int dobjId = FWObjectDatabase::DELETED_OBJECTS_ID; if (dst==NULL) { /* dst == NULL on the first call to this function */ dst = treeRoot; walkTree(dstMap,treeRoot); walkTree(srcMap, src); /** * find deleted objects library in src and check if any object * from it is present in dst */ FWObjectDatabase *dstroot = dst->getRoot(); /* * find deleted objects library in dst and delete objects from * it if they are present and not deleted in src */ list deletedObjects; FWObject *dstdobj = dstroot->findInIndex( dobjId ); if (dstdobj) { for (FWObject::iterator i=dstdobj->begin(); i!=dstdobj->end(); i++) { FWObject *sobj = srcMap[ (*i)->getId() ]; if(sobj!=NULL && sobj->getParent()->getId()!=dobjId) deletedObjects.push_back(*i); } for (FWObject::iterator i=deletedObjects.begin(); i!=deletedObjects.end(); i++) { dstroot->recursivelyRemoveObjFromTree( *i ); dstMap[ (*i)->getId() ] = NULL; } } } for (FWObject::iterator i=src->begin(); i!=src->end(); i++) { /* * commented 12/04/04. We now delete "deleted objects" * from libraries we are merging in before calling * FWObjectDatabase::merge. Ignoring "Deleted objects" here * caused problems; in particular, deleted objects disappeared * from a data file whenever it was opened. This happened * because we merged user's data file into standard objects * tree, so user's file was _source_ here, and deleted objects * in it were ignored. */ // if ((*i)->getId()==dobjId) continue; FWObject *dobj; FWObject *sobj; if (FWReference::cast( *i )) { FWReference *r=FWReference::cast(*i); dobj= dstMap[reference_object_id_offset + r->getPointerId()]; } else dobj= dstMap[ (*i)->getId() ]; if (dobj==NULL) { sobj = *i; FWObject *o1 = treeRoot->create( sobj->getTypeName()); FWObject *pdst = dstMap[ src->getId() ]; assert(pdst!=NULL); // no validation is necessary - this copies existing tree pdst->add(o1, false); #ifdef DEBUG_MERGE cerr << "--------------------------------" << endl; cerr << "merge: duplicate #1 " << endl; cerr << "dobj: " << endl; o1->dump(true,true); cerr << endl; cerr << "sobj: " << endl; sobj->dump(true,true); #endif o1->duplicate( sobj, false); // copy IDs as well #ifdef DEBUG_MERGE cerr << "duplicate #1 done" << endl; #endif /* there may be children objects since we did a deep copy */ walkTree( dstMap , o1 ); } else { /* need to compare objects, looking into attributes. This is different * from Compiler::operator== operators because fwcompiler assumes that * objects with the same ID are equal. Here we specifically look for a * case when objects with the same ID have different attributes. */ if (dobj->cmp(*i, true)) continue; // compare recursively /* such object exists in destination tree but is different Since we * traverse the tree from the root towards leaves, it won't help much * if we ask the user if they want to overwrite the old library or a * high-level system group only because a single object somewhere deep * down the tree is different. Need to traverse the tree further until * the actual object that differs is found. * * There still is a problem because we do want to ask the user if the * group we are looking at is user-defined as opposed to our standard * top level one. There is no reliable way to distinguish them though * because both are represented by the same class. We use simple hack: * all children of our system groups are regular objects, while * children of user-defined groups are always references. */ if (Group::cast(dobj)!=NULL) { // at one point I've got bunch of data files where // DeletedObjects library contained references for // some reason. This should not happen, but at the // same time this is valid file structure so the code // should be able to handle it. if (dobj->getId()==FWObjectDatabase::DELETED_OBJECTS_ID) merge( dobj , *i ); else { FWObject *firstChild=NULL; if (dobj->size()>0) firstChild= dobj->front(); else { if ( (*i)->size()>0 ) firstChild= (*i)->front(); } if (firstChild==NULL || FWReference::cast(firstChild)!=NULL) { if (crp!=NULL && crp->askUser( dobj, *i )) { #ifdef DEBUG_MERGE cerr << "--------------------------------" << endl; cerr << "merge: duplicate #2 " << endl; dobj->dump(true,true); cerr << endl; #endif dobj->duplicate( (*i), false ); } } else merge( dobj , *i ); } } else { if (crp!=NULL && crp->askUser( dobj, *i )) { #ifdef DEBUG_MERGE cerr << "--------------------------------" << endl; cerr << "merge: duplicate #3 " << endl; dobj->dump(true,true); cerr << endl; #endif dobj->duplicate( (*i), false ); } } } } } FWObjectDatabase* FWObjectDatabase::exportSubtree( const list &libs ) { FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->busy = true; for (list::const_iterator i=libs.begin(); i!=libs.end(); i++) { FWObject *lib = *i; FWObject *nlib = ndb->create(lib->getTypeName()); // no validation is necessary - this copies existing tree ndb->add(nlib, false); *nlib = *lib; } FWObjectTreeScanner scanner(ndb); scanner.scanAndAdd(NULL, this); ndb->busy = false; return ndb; } FWObjectDatabase* FWObjectDatabase::exportSubtree( FWObject *lib ) { FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->busy = true; FWObject *nlib = ndb->create(lib->getTypeName()); // no validation is necessary - this copies existing tree ndb->add(nlib, false); *nlib = *lib; FWObjectTreeScanner scanner(ndb); scanner.scanAndAdd(NULL, this); ndb->busy = false; return ndb; } /** * check if source and destination files have objects with the * same ID. To do this, compare keys in obj_index in this and * ndb. */ void FWObjectDatabase::findDuplicateIds(FWObjectDatabase *ndb, set &dupids) { FWObjectDatabase *db1; FWObjectDatabase *db2; if (obj_index.size() > ndb->obj_index.size()) { db1 = ndb; db2 = this; } else { db2 = ndb; db1 = this; } for (map::iterator it=db1->obj_index.begin(); it!=db1->obj_index.end(); ++it) { int id = it->first; if (db2->obj_index.count(id) != 0) { // skip standard IDs if (id <= DELETED_OBJECTS_ID) continue; FWObject *obj = db1->findInIndex(id); assert(obj); if (obj->getLibrary()->getId() == STANDARD_LIB_ID || obj->getLibrary()->getId() == DELETED_OBJECTS_ID) continue; dupids.insert(id); } } } void FWObjectDatabase::merge( FWObjectDatabase *ndb, ConflictResolutionPredicate *crp) { busy = true; setIgnoreReadOnlyFlag(true); FWObjectTreeScanner scanner(this, crp); scanner.merge(NULL, ndb); setIgnoreReadOnlyFlag(false); busy = false; } /** * Copy object and all its children, recursively, into * object tree starting from . is a parent of the copy * of that will be created. * Store ID mapping in (as a dictionary old_id -> new_id) */ FWObject* FWObjectDatabase::recursivelyCopySubtree(FWObject *target, FWObject *source, std::map &id_map) { char s[64]; snprintf(s, sizeof(s), ".copy_of_%p", source->getRoot()); string dedup_attribute = s; FWObject *nobj = _recursively_copy_subtree(target, source, id_map, dedup_attribute); fixReferences(nobj, id_map); // one more pass to fix references in other firewalls and groups // we might have copied. for (map::const_iterator i=id_map.begin(); i!=id_map.end(); ++i) { int new_id = i->second; // new id FWObject *new_obj = findInIndex(new_id); if (Firewall::cast(new_obj) || Group::cast(new_obj)) fixReferences(new_obj, id_map); } return nobj; } /* * fix references in children of obj according to the map_ids which * maps old IDs to the new ones. Return the number of fixed references. */ int FWObjectDatabase::fixReferences(FWObject *obj, const map &map_ids) { int total_counter = 0; for (map::const_iterator it=map_ids.begin(); it!=map_ids.end(); ++it) total_counter += obj->replaceRef(it->first, it->second); return total_counter; } FWObject* FWObjectDatabase::_recursively_copy_subtree( FWObject *target, FWObject *source, std::map &id_map, const string &dedup_attribute) { target->checkReadOnly(); // TODO: get rid of references in attributes, they suck. ticket #1004 if (Interface::cast(source)) { int nzid = FWObjectDatabase::getIntId(source->getStr("network_zone")); // check if we have seen old_ptr_obj already. if (nzid!= 0 && id_map.count(nzid) == 0 && findInIndex(nzid)==NULL) { FWObject *netzone = source->getRoot()->findInIndex(nzid); if (netzone) _copy_foreign_obj_aux(target, netzone, id_map, dedup_attribute); } } if (ClusterGroup::cast(source)) { int miface_id = FWObjectDatabase::getIntId(source->getStr("master_iface")); FWObject *miface = source->getRoot()->findInIndex(miface_id); if (miface) _copy_foreign_obj_aux(target, miface, id_map, dedup_attribute); } FWObject *nobj = create(source->getTypeName()); nobj->clearChildren(); nobj->shallowDuplicate(source, true); id_map[source->getId()] = nobj->getId(); nobj->setInt(dedup_attribute, source->getId()); // no validation is necessary - this copies existing tree target->add(nobj, false); // copy interfaces and options objects before rule sets for(list::iterator m=source->begin(); m!=source->end(); ++m) { FWObject *old_obj = *m; if (RuleSet::cast(old_obj)!=NULL) continue; if (FWReference::cast(old_obj)!=NULL) continue; _recursively_copy_subtree(nobj, old_obj, id_map, dedup_attribute); } for(list::iterator m=source->begin(); m!=source->end(); ++m) { FWObject *old_obj = *m; if (id_map.count(old_obj->getId()) > 0) continue; if (FWReference::cast(old_obj)) { FWReference *old_ref_obj = FWReference::cast(old_obj); FWObject *old_ptr_obj = old_ref_obj->getPointer(); FWObject *n_ptr_obj = NULL; // check if we have seen old_ptr_obj already. if (id_map.count(old_ptr_obj->getId()) > 0) { n_ptr_obj = findInIndex(id_map[old_ptr_obj->getId()]); nobj->addRef(n_ptr_obj); continue; } // search for old_ptr_obj in the index. If it is found, we do not // need to copy it and its ID is valid (perhaps standard object?) n_ptr_obj = findInIndex(old_ptr_obj->getId()); if (n_ptr_obj != NULL) { nobj->addRef(n_ptr_obj); continue; } // Check if we have already copied the same object before char s[64]; snprintf(s, sizeof(s), "%d", old_ptr_obj->getId()); n_ptr_obj = findObjectByAttribute(dedup_attribute, s); if (n_ptr_obj) { nobj->addRef(n_ptr_obj); continue; } // Need to create a copy of old_ptr_obj and put it in the // same place in the tree. // Problem: what if old_ptr_obj is interface or an address of // interface or a rule etc ? Check isPrimaryObject(). // _copy_foreign_obj_aux(nobj, old_ptr_obj, id_map, dedup_attribute); } else _recursively_copy_subtree(nobj, old_obj, id_map, dedup_attribute); } return nobj; } void FWObjectDatabase::_copy_foreign_obj_aux( FWObject *target, FWObject *source, map &id_map, const std::string &dedup_attribute) { FWObject *parent_obj = source; while (parent_obj && !parent_obj->isPrimaryObject()) parent_obj = parent_obj->getParent(); // check if this parent (which is a primary object) is // unknown. If it is known or exist in our tree, no need // to create a copy. if (parent_obj && id_map.count(parent_obj->getId()) == 0 && !Library::isA(parent_obj)) { FWObject *new_parent = reproduceRelativePath( target->getLibrary(), parent_obj); // (parent_obj at this point is either pointer // to the same obj or pointer to its parent // object that we can copy as a whole. The latter // happens if obj is an interface or address // of an interface. new_parent = _recursively_copy_subtree(new_parent, parent_obj, id_map, dedup_attribute); // we just copied old object to the target data tree. // Copy of obj is either new_parent, or one of its // children. In the process of making this copy, // its ID should have been added to id_map. assert(id_map.count(source->getId()) > 0); FWObject *n_ptr_obj = new_parent->getById(id_map[source->getId()], true); target->addRef(n_ptr_obj); } } /** * Create groups to reproduce path inside given library. If groups * with required names exist, do nothing. Return pointer to the * last object created to copy the path. Do not copy object. * This means returned object can be a parent for the copy of . */ FWObject* FWObjectDatabase::reproduceRelativePath(FWObject *lib, const FWObject *source) { list path; FWObject *p = source->getParent(); while (p && !Library::isA(p)) { path.push_front(p); p = p->getParent(); } FWObject *target = lib; FWObject *nobj; for (list::iterator p=path.begin(); p!=path.end(); ++p) { FWObject *obj = *p; nobj = target->findObjectByName(obj->getTypeName(), obj->getName()); if (nobj==NULL) { nobj = create(obj->getTypeName()); nobj->shallowDuplicate(obj, false); // no validation is necessary - this copies existing tree target->add(nobj, false); } target = nobj; } return target; } FWObject& FWObjectDatabase::duplicate(const FWObject *obj, bool preserve_id) throw(FWException) { setIgnoreReadOnlyFlag(true); FWObject &o = FWObject::duplicate(obj, preserve_id); setIgnoreReadOnlyFlag(false); return o; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Group.h0000644000175000017500000000432611733011756024263 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GROUP_HH_FLAG__ #define __GROUP_HH_FLAG__ #include #include #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectReference.h" namespace libfwbuilder { class Group : virtual public FWObject { protected: public: Group(); virtual ~Group(); DECLARE_FWOBJECT_SUBTYPE(Group); DECLARE_DISPATCH_METHODS(Group); bool hasMember(FWObject *o); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual bool isPrimaryObject() const { return true; } int getSize(); /** * This method copies all attributes of obj plus all reference * child objects to reproduce accurate state of this. In fact, it * simply calls duplicate() if this is user-defined group. For system * grops that hold actual objects, it calls shallowDuplicate() */ virtual FWObject& duplicateForUndo(const FWObject *obj) throw(FWException); /** * get the list of object type names that can be inserted into * given object group. For example, if the group is ObjectGroup, * then the list will include all objects but not services. This * reflects definition of the group XML element in DTD. */ virtual void getAllowedTypesOfChildren(std::list &types_list); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Firewall.h0000644000175000017500000000765111733011756024740 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FIREWALL_HH_FLAG__ #define __FIREWALL_HH_FLAG__ #include "fwbuilder/Host.h" #include // for time_t #include #include namespace libfwbuilder { class Interface; class Policy; class NAT; class RuleSet; class Routing; class Firewall : public Host { std::map id_mapping_for_duplicate; void duplicateInterfaces(FWObject *target, const FWObject *source, std::map &id_mapping, bool preserve_id = true); public: Firewall(); virtual ~Firewall(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr parent) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(Firewall); DECLARE_DISPATCH_METHODS(Firewall); /** * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual FWOptions* getOptionsObject(); /** * This method copies content of object 'x' in the object 'this'. * Depending on 'preserve_id' flag, Id's are either copied or new * ones are issued. Unlike FWObject::duplicate, this method also * replaces references to the old firewall in all policy and NAT * rules with references to 'this' */ virtual FWObject& duplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); /** * This method copies all attributes of obj into this, plus * FWOptions and Management child objects but no other * children. */ virtual FWObject& duplicateForUndo(const FWObject *obj) throw(FWException); /* * Return id mapping table created during latest run of duplicate() */ const std::map& getIDMappingTable() { return id_mapping_for_duplicate; } Policy *getPolicy(); NAT *getNAT(); Routing *getRouting(); /** * scan all rules of all rule sets and call setUniqueId() to set * unique string id for each rule. These IDs will be carried * through calls to duplicate() when firewall object and its rule * sets are cloned. These IDs are used by compilers to generate * stable labels for chains and such. */ void assignUniqueRuleIds(); /** * Return list of interfaces of given type. This walks all interfaces recursively, * including subinterfaces. */ std::list getInterfacesByType(const std::string &iface_type); time_t getLastModified(); time_t getLastInstalled(); time_t getLastCompiled(); void updateLastInstalledTimestamp(); void updateLastModifiedTimestamp(); void updateLastCompiledTimestamp(); bool needsInstall(); bool needsCompile(); bool getInactive(); void setInactive(bool b); }; } #endif //__FIREWALL_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/AddressRange.h0000644000175000017500000000450211733011756025525 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ADDRESSRANGE_HH_FLAG__ #define __ADDRESSRANGE_HH_FLAG__ #include "fwbuilder/Address.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class AddressRange : public Address { private: InetAddr start_address; InetAddr end_address; public: AddressRange(); AddressRange(AddressRange &); const InetAddr &getRangeStart() const { return start_address; } const InetAddr &getRangeEnd() const { return end_address; } void setRangeStart(const InetAddr &o) { start_address = o; } void setRangeEnd(const InetAddr &o) { end_address = o; } /** * virtual methods inherited from Address */ virtual bool hasInetAddress() const { return true; } virtual const InetAddr* getAddressPtr() const; virtual unsigned int dimension() const; virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual void fromXML (xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr xml_parent_node) throw(FWException); virtual bool isPrimaryObject() const { return true; } DECLARE_FWOBJECT_SUBTYPE(AddressRange); DECLARE_DISPATCH_METHODS(AddressRange); }; } #endif // __ADDRESSRANGE_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWServiceReference.h0000644000175000017500000000256511733011756026646 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWSRVREF_HH_FLAG__ #define __FWSRVREF_HH_FLAG__ #include "fwbuilder/FWReference.h" namespace libfwbuilder { class Service; class ServiceGroup; /** * This class represents object reference. */ class FWServiceReference : public FWReference { public: DECLARE_FWOBJECT_SUBTYPE(FWServiceReference); DECLARE_DISPATCH_METHODS(FWServiceReference); FWServiceReference(); void setPointer(Service *o); void setPointer(ServiceGroup *o); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObject.cpp0000644000175000017500000011744011733011756025167 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Tools.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Host.h" #include "fwbuilder/Interface.h" #include #include // #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; const char *FWObject::TYPENAME={"UNDEF"}; string FWObject::NOT_FOUND=""; string FWObject::dataDir; //#define FWB_DEBUG //#define TI_DEBUG void FWObject::fromXML(xmlNodePtr root) throw(FWException) { assert(root!=NULL); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("name"))); if(n) { setName(n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("id"))); if(n) { setId(FWObjectDatabase::registerStringId(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("comment"))); if(n) { setComment(XMLTools::unquote_linefeeds(n)); FREEXMLBUFF(n); } n = FROMXMLCAST(xmlGetProp(root, TOXMLCAST("keywords"))); if (n != 0) { keywords = stringToSet(n); dbroot->keywords.insert(keywords.begin(), keywords.end()); FREEXMLBUFF(n); } n = FROMXMLCAST(xmlGetProp(root, TOXMLCAST("subfolders"))); if (n != 0) { setStr("subfolders", n); FREEXMLBUFF(n); } n = FROMXMLCAST(xmlGetProp(root, TOXMLCAST("folder"))); if (n != 0) { setStr("folder", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("ro"))); if(n) { ro = (cxx_strcasecmp(n, "1")==0 || cxx_strcasecmp(n , "true")==0); FREEXMLBUFF(n); } // ref_counter = 0; FWObjectDatabase *dbr = getRoot(); for (xmlNodePtr cur=root->xmlChildrenNode; cur; cur=cur->next) { if (cur && !xmlIsBlankNode(cur)) { FWObject *o = dbr->createFromXML(cur); if (o!=NULL) { /* Add w/o validation. Trust XML to do that */ add(o, false); try { o->fromXML(cur); } catch(FWException &ex) { map &properties = ex.getProperties(); if (properties.find("failed_element")==properties.end()) properties["failed_element"]=o->getTypeName(); throw; } } } } setDirty(false); } xmlNodePtr FWObject::toXML(xmlNodePtr xml_parent_node) throw(FWException) { return toXML(xml_parent_node, true); } xmlNodePtr FWObject::toXML(xmlNodePtr parent, bool process_children) throw(FWException) { string s_id = FWObjectDatabase::getStringId(getId()); xmlNodePtr me = xmlNewChild( parent, NULL, xml_name.empty() ? STRTOXMLCAST(getTypeName()) : STRTOXMLCAST(xml_name), NULL); if (id!=-1) { xmlNewProp( me, TOXMLCAST("id"), STRTOXMLCAST(s_id)); } if (!keywords.empty()) { xmlNewProp(me, TOXMLCAST("keywords"), STRTOXMLCAST(setToString(keywords))); } for(map::const_iterator i=data.begin(); i!=data.end(); ++i) { const string &name = (*i).first; const string &value = (*i).second; if (name[0]=='.') continue; if (name == "folder" && value.empty()) continue; xmlNewProp(me, STRTOXMLCAST(name), STRTOXMLCAST(value)); } if (process_children) { for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); } return me; } FWObject::FWObject() { busy = false; ref_counter = 0; parent = NULL; dbroot = NULL; name = ""; comment = ""; id = -1; ro = false; // When object is created we assign it unique Id setId(FWObjectDatabase::generateUniqueId()); setDirty(false); storeCreationTime(); } FWObject::FWObject(bool new_id) { busy = false; ref_counter = 0; parent = NULL; dbroot = NULL; name = ""; comment = ""; id = -1; ro = false; // When object created we assign it unique Id if (new_id) setId(FWObjectDatabase::generateUniqueId()); setDirty(false); storeCreationTime(); } FWObject::FWObject(const FWObject &c) : list(c) { busy = false; *this = c; storeCreationTime(); } FWObject::~FWObject() { busy = true; // ignore read-only if (size() > 0) destroyChildren(); data.clear(); private_data.clear(); } void FWObject::init(FWObjectDatabase *root) { dbroot = (FWObjectDatabase*)root; } void FWObject::setPrivateData(const string &key, void *data) { private_data[key] = data; } void* FWObject::getPrivateData(const string &key) const { map::const_iterator it = private_data.find(key); if(it == private_data.end()) return NULL; else return it->second; } map &FWObject::getAllPrivateData() { return private_data; } void FWObject::updateNonStandardObjectReferences() { } FWObject* FWObject::getParent() const { return parent; } void FWObject::setParent(FWObject *p) { parent=p; } void FWObject::setXMLName(const string &n) { xml_name = n; } FWObject* FWObject::_find(const string& name) const { const_iterator i = std::find_if(begin(),end(), FWObjectNameEQPredicate(name)); return i==end()?NULL:(*i); } list FWObject::findIf(FWObjectFindPredicate *pred) { list res_list; list::iterator i1; for(i1=begin(); i1!=end(); ++i1) { if ((*pred)(*i1)) res_list.push_back(*i1); list res1 = (*i1)->findIf(pred); res_list.splice(res_list.begin(), res1); } return res_list; } FWObject* FWObject::findObjectByName(const string &type, const string &name) throw(FWException) { if (getTypeName()==type && getName()==name) return this; list::iterator j; for(j=begin(); j!=end(); ++j) { FWObject *o=*j; o=o->findObjectByName(type,name); if(o) return o; } return NULL; // not found } FWObject* FWObject::findObjectByAttribute(const std::string &attr, const std::string &val) throw(FWException) { if (getStr(attr)==val) return this; list::iterator j; for(j=begin(); j!=end(); ++j) { FWObject *o=*j; o=o->findObjectByAttribute(attr, val); if(o) return o; } return NULL; // not found } bool FWObject::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (getTypeName() != obj->getTypeName() || name != obj->name || comment != obj->comment || ro != obj->ro) return false; if (data.size() != obj->data.size()) return false; for(map::const_iterator i=data.begin(); i!=data.end(); ++i) { const string &name = (*i).first; const string &value = (*i).second; // 10/21/2008 --vk map::const_iterator j=obj->data.find(name); if (j==obj->data.end()) return false; if (j->second!=value) return false; } if (keywords.empty() != obj->keywords.empty() || keywords != obj->keywords) return false; if (recursive) { if (size()!=obj->size()) return false; /* chidren are not necessarily in the same order in two groups */ std::set matched; FWObject::const_iterator i1=begin(); for ( ; i1!=end(); ++i1) { bool found_equal_child_object=false; FWObject::const_iterator j1=obj->begin(); for ( ; j1!=obj->end(); ++j1) { if ((*i1)->cmp(*j1, recursive)) { if (matched.find(*j1) == matched.end()) { matched.insert(*j1); found_equal_child_object = true; break; } // else object matches some other object } } if (!found_equal_child_object) return false; } } return true; } FWObject& FWObject::operator=(const FWObject &x) throw(FWException) { return duplicate(&x, false); } FWObject& FWObject::duplicate(const FWObject *x, bool preserve_id) throw(FWException) { checkReadOnly(); bool xro = x->ro; shallowDuplicate(x, preserve_id); if (xro) setReadOnly(false); destroyChildren(); // does it erase index entries? for(list::const_iterator m=x->begin(); m!=x->end(); ++m) { FWObject *o = *m; addCopyOf( o, preserve_id); } setDirty(true); if (xro) setReadOnly(true); return *this; } FWObject* FWObject::addCopyOf(const FWObject *x, bool preserve_id) throw(FWException) { if (x==NULL) return NULL; FWObject *o1; FWObjectDatabase *root = getRoot(); if (root==NULL) root = x->getRoot(); // do not prepopulte children for objects that do that automatically // in their constructor o1 = root->create(x->getTypeName(), -1); if(!o1) throw FWException(string("Error creating object with type: ")+ x->getTypeName()); // This adds with validation add(o1); o1->duplicate(x, preserve_id); return o1; } /* * copying an object does not copy its read-only status; thus we can * take read-only object and make a read-write copy of it to work * with. * * 07/06/2007 -- changed that. Now copy has the same value of "ro" * attribute. Clear it in the caller if neccessary. */ FWObject& FWObject::shallowDuplicate(const FWObject *x, bool preserve_id) throw(FWException) { checkReadOnly(); int old_id = getId(); id = x->id; name = x->name; comment = x->comment; ro = x->ro; data = x->data; private_data = x->private_data; keywords = x->keywords; set::const_iterator iter; for (iter = keywords.begin(); iter != keywords.end(); ++iter) { dbroot->keywords.insert(*iter); } setReadOnly(false); if (!preserve_id) { // ref_counter = 0 ; xml_name = x->xml_name; } else { // some objects do not have ID per DTD (e.g. Src, Dst, etc.) // Those will return -1 from getId() if (id > -1) setId(old_id); } if (dbroot==NULL) setRoot(x->getRoot()); if (dbroot!=NULL) dbroot->addToIndex(this); setReadOnly(x->ro); setDirty(true); return *this; } class InheritsFWOptions: public std::unary_function { public: InheritsFWOptions() {} bool operator()(const FWObject *o) const { return FWOptions::constcast(o)!=NULL; } }; FWObject& FWObject::duplicateForUndo(const FWObject *obj) throw(FWException) { setRO(false); InheritsFWOptions pred; FWObject::const_iterator mine_opts_iter = std::find_if(begin(), end(), pred); FWObject::const_iterator their_opts_iter = std::find_if(obj->begin(), obj->end(), pred); if (their_opts_iter != obj->end()) { if (mine_opts_iter != end()) (*mine_opts_iter)->duplicate(*their_opts_iter); else addCopyOf(*their_opts_iter); } shallowDuplicate(obj); return *this; } const string &FWObject::getName() const { return name; } void FWObject::setName(const string &n) { if (name != n) { name = n; setDirty(true); } } const string& FWObject::getLibraryName() const { return getLibrary()->getName(); } FWObject* FWObject::getLibrary() const { const FWObject *p=this; while (p!=NULL && !Library::isA(p) ) p=p->getParent(); return (FWObject*)p; } FWObjectDatabase* FWObject::getRoot() const { return dbroot; } int FWObject::getDistanceFromRoot() const { int count = 0; for (FWObject *obj = getParent(); obj != 0; obj = obj->getParent()) { count++; } return count; } class pathAccumulator : public string { public: void operator()(const string &s) { append("/" + s); } }; string FWObject::getPath(bool relative, bool detailed) const { list res; const FWObject *p = this; if (p == NULL) res.push_front("(0x0)"); while (p!=NULL) { if (relative && Library::isA(p)) break; ostringstream s; s << p->getName(); if (detailed) { s << "(" << p << ")"; } res.push_front(s.str()); p = p->getParent(); } string path = std::for_each(res.begin(), res.end(), pathAccumulator()); if (relative && path[0] == '/') path.erase(0, 1); return path; } const string& FWObject::getComment() const { return comment; } void FWObject::setComment(const string &c) { if (comment != c) { comment = c; setDirty(true); } } int FWObject::getId() const { return id; } /* * need to update index because ID of the object changes */ void FWObject::setId(int c) { if (id != c) { id = c; setDirty(true); if (dbroot!=NULL) dbroot->addToIndex(this); } } bool FWObject::exists(const string &name) const { return data.count(name)!=0; } const string &FWObject::getStr(const string &name) const { map::const_iterator i=data.find(name); if (i==data.end()) return NOT_FOUND; else return (*i).second; } void FWObject::remStr(const string &name) { checkReadOnly(); map::iterator m=data.find(name); if(m != data.end()) { data.erase(m); setDirty(true); } } void FWObject::setStr(const string &name, const string &val) { if (name[0]!='.' && name != "folder") checkReadOnly(); string old_val = data[name]; if (old_val != val) { data[name] = val; // attribute with name that starts with "." is considered "hidden" // or "internal". Such attribute is not saved to the data file and // should not trigger "dirty" flag. if (name[0]!='.') setDirty(true); } } int FWObject::getInt(const string &name) const { string val = getStr(name); size_t n = val.find_first_of(" \n\r\t"); while (n != string::npos) { val = val.erase(n, 1); n = val.find_first_of(" \n\r\t"); } if (val != "") return( atol(val.c_str()) ); else return(-1); } void FWObject::setInt(const string &name, int val) { ostringstream str; str << val; setStr(name, str.str()); } bool FWObject::getBool(const string &name) const { // 10/21/2008 --vk string val = getStr(name); size_t n = val.find_first_of(" \n\r\t"); while (n != string::npos) { val = val.erase(n, 1); n = val.find_first_of(" \n\r\t"); } return (val=="1" || cxx_strcasecmp(val.c_str() , "true")==0); } void FWObject::setBool(const string &name, bool val) { setStr(name, (val)?"True":"False"); //if (name[0]!='.') setDirty(true); } void FWObject::setBool(const string &name, const string &val) { if(!name.empty()) setBool(name, (val=="1" || cxx_strcasecmp(val.c_str(),"true")==0)); } void FWObject::Show() { setBool("read",true); } void FWObject::Hide() { setBool("read",false); } void FWObject::dump(bool recursive,bool brief,int offset) const { dump(cerr,recursive,brief,offset); } void FWObject::dump(std::ostream &f,bool recursive,bool brief,int offset) const { FWObject *o; string n; if (brief) { f << string(offset,' '); f << " Obj=" << this; f << " ID=" << getId() << " (" << FWObjectDatabase::getStringId(getId()) << ")"; f << " Name=" << getName(); f << " Type=" << getTypeName(); if (this!=getRoot()) f << " Library=" << getLibrary(); f << " Root=" << getRoot(); f << " ref_counter=" << ref_counter; f << endl; if (recursive) { list::const_iterator m; for (m=begin(); m!=end(); ++m) { if ( (o=(*m))!=NULL) o->dump(f,recursive,brief,offset+2); } } } else { f << string(offset,' ') << string(16,'-') << endl; f << string(offset,' ') << "Obj: " << this << endl; f << string(offset,' ') << "ID: " << getId() << " (" << FWObjectDatabase::getStringId(getId()) << ")" << endl; f << string(offset,' ') << "Name: " << getName() << endl; f << string(offset,' ') << "Ref.ctr:" << ref_counter << endl; f << string(offset,' ') << "Type: " << getTypeName() << endl; f << string(offset,' ') << "Library:" << getLibrary() << endl; // f << string(offset,' ') << "Path: " << getPath() << endl; n=(getParent()!=NULL)?getParent()->getName():""; f << string(offset,' ') << "Parent: " << getParent() << " name=" << n << endl; f << string(offset,' ') << "Root: " << getRoot() << endl; map::const_iterator d; for (d=data.begin(); d!=data.end(); ++d) { f << string(offset,' '); f << (*d).first << ": " << (*d).second << endl; } if (recursive) { list::const_iterator m; for (m=begin(); m!=end(); ++m) { if ( (o=(*m))!=NULL) o->dump(f,recursive,brief,offset+2); } } } } void FWObject::_adopt(FWObject *obj) { obj->ref(); obj->setParent(this); /* * normally we always create objects using FWObjectDatabase::create * which sets dbroot in the object. However, if an object is created * just with 'new ...' and then added to the database using * FWObject::add, it doesn't have correct pointer to the database * root. We can easily repair this by setting dbroot here. Even if * this operation is redundant, its cost is very low and it adds * robustness. * */ obj->setRoot(getRoot()); } void FWObject::addAt(int where_id, FWObject *obj) { FWObject *p = getRoot()->findInIndex( where_id ); assert (p!=NULL); p->add(obj); } void FWObject::add(FWObject *obj, bool validate) { checkReadOnly(); FWObject *old_parent = obj->getParent(); if (old_parent != NULL) { cerr << "WARNING: object " << obj << " " << "(name: " << obj->getName() << " type: " << obj->getTypeName() << ") " << "that is a child of " << old_parent << " " << "(name: " << old_parent->getName() << " type: " << old_parent->getTypeName() << ") " << "is being added to the new parent " << this << " " << "(name: " << getName() << " type: " << getTypeName() << ") " << endl; assert(old_parent == NULL); } // do not allow to add the same object twice if (old_parent == this) { cerr << "WARNING: object " << obj << " " << "(name: " << obj->getName() << " type: " << obj->getTypeName() << ") " << "that is a child of " << old_parent << " " << "(name: " << old_parent->getName() << " type: " << old_parent->getTypeName() << ") " << "is being added to the same parent again" << endl; assert(old_parent != this); } if (!validate || validateChild(obj)) { push_back(obj); _adopt(obj); setDirty(true); } } void FWObject::reparent(FWObject *obj, bool validate) { FWObject *old_parent = obj->getParent(); if (old_parent != NULL && old_parent != this) { old_parent->remove(obj, false); add(obj, validate); obj->fixTree(); } } FWReference* FWObject::createRef() { // FWObjectReference *ref=new FWObjectReference(); FWObjectReference *ref = getRoot()->createFWObjectReference(); ref->setPointer(this); return ref; } void FWObject::addRef(FWObject *obj) { checkReadOnly(); if (validateChild(obj)) { FWReference *oref = obj->createRef(); obj->ref(); push_back(oref); _adopt(oref); setDirty(true); // see comment in FWObject::_adopt obj->setRoot(getRoot()); } } void FWObject::insert_before(FWObject *o1, FWObject *obj) { checkReadOnly(); if (obj == NULL) return; if (o1 == NULL) { insert(begin(), obj); _adopt(obj); setDirty(true); return; } list::iterator m = find(begin(), end(), o1); if (m != end()) { insert(m, obj); _adopt(obj); setDirty(true); } } void FWObject::insert_after(FWObject *o1, FWObject *obj) { checkReadOnly(); if (obj == NULL) return; list::iterator m = find(begin(), end(), o1); if (m != end()) { insert(++m, obj); _adopt(obj); setDirty(true); } } void FWObject::swapObjects(FWObject *o1, FWObject *o2) { checkReadOnly(); for(list::iterator m=begin(); m!=end(); ++m) { if(*m==o1) { *m=o2; } else if(*m==o2) { *m=o1; } } setDirty(true); } void FWObject::remove(FWObject *obj, bool delete_if_last) { FWObject::iterator fi=std::find(begin(), end(), obj); if (fi!=end()) { checkReadOnly(); erase(fi); setDirty(true); obj->unref(); if (delete_if_last && obj->ref_counter <= 0) { FWObjectDatabase *db = getRoot(); if (db) db->removeFromIndex(obj->getId()); delete obj; } obj->parent = NULL; } } void FWObject::_removeAll(FWObject *rm) { for (FWObject::iterator i=begin(); i!=end(); i++) (*i)->_removeAll(rm); remove(rm,false); } void FWObject::removeAllInstances(FWObject *rm) { checkReadOnly(); removeAllReferences(rm); _removeAll(rm); } void FWObject::removeRef(FWObject *obj) { int obj_id = obj->getId(); for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o = *m; FWReference *oref = FWReference::cast(o); if (oref && oref->getPointerId()==obj_id) { // do not delete object even if this reference was the last one (?) obj->unref(); FWObject::remove(o, false); // do not remove delete o; return; } } } bool FWObject::hasRef(FWObject *obj) { int obj_id = obj->getId(); for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o = *m; FWReference *oref = FWReference::cast(o); if (oref && oref->getPointerId()==obj_id) return true; } return false; } void FWObject::_removeAllRef(FWObject *rm) { // Do not delete references to the same object from its children // such as references to the firewall or cluster in its own rules if (this == rm || this->isChildOf(rm)) return; for (FWObject::iterator i=begin(); i!=end(); i++) (*i)->_removeAllRef(rm); removeRef(rm); } void FWObject::removeAllReferences(FWObject *rm) { _removeAllRef(rm); } void FWObject::findAllReferences(const FWObject *obj, std::set &res) { int obj_id = obj->getId(); for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o=*m; FWReference *oref = FWReference::cast(o); if(oref) { if(oref->getPointerId()==obj_id) res.insert(oref); } else { o->findAllReferences(obj, res); } } } set FWObject::findAllReferences(const FWObject *obj) { set res; findAllReferences(obj, res); return res; } bool FWObject::validateChild(FWObject*) { return true; } /* * this method deletes all children recursively regardless of their * usage counter. We call this method form destructor. */ void FWObject::destroyChildren() { #ifdef DEBUG_DESTROY_CHILDREN cerr << "destroyChildren() " << this << " name=" << name << " type=" << getTypeName() << " parent=" << getParent() << " path=" << getPath() << endl; #endif FWObjectDatabase *dbr = getRoot(); while (size() > 0) { FWObject *o = front(); #ifdef DEBUG_DESTROY_CHILDREN cerr << " " << this << " size=" << size() << " o=" << o << " o->size=" << o->size() << endl; #endif if (o) { if (o->size()) o->destroyChildren(); if (dbr && !dbr->busy) dbr->removeFromIndex( o->getId() ); #ifdef DEBUG_DESTROY_CHILDREN cerr << " " << this << " delete " << o << " " << o->name << " " << o->getTypeName() << endl; #endif delete o; } pop_front(); } //clear(); } void FWObject::sortChildrenByName(bool follow_references) { if (!follow_references) sort(FWObjectNameCmpPredicate()); } /* * Walks the tree, looking for objects that are referenced by two parents */ bool FWObject::verifyTree() { bool res = false; for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o = *m; FWObject *o_parent = o->getParent(); if (o_parent != this) { if (o_parent != NULL) { cerr << "WARNING: Object " << o << " (name: '" << o->getName() << "' type: " << o->getTypeName() << ")" << " has two parents in the tree:" << endl; cerr << " " << o_parent->getPath(false, true) << endl; cerr << " " << getPath(false, true) << endl; bool o_parent_real = false; for (FWObject::iterator k=o_parent->begin(); k!=o_parent->end(); ++k) { FWObject *o1 = *k; if (o1 == o) { o_parent_real = true; break; } } if ( ! o_parent_real) { cerr << "WARNING: Parent " << o_parent_real << " does not have child " << o << endl; } } else { cerr << "WARNING: Object " << o << " (name: '" << o->getName() << "' type: " << o->getTypeName() << ")" << " was not correctly added to its parent " << "(getParent()==NULL):" << endl; cerr << " " << getPath(false, true) << endl; } o->dump(true, false); // recursive, not brief res = true; } res |= o->verifyTree(); } return res; } void FWObject::fixTree() { getRoot()->addToIndex(this); for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o = *m; if (o->getRoot() != getRoot()) o->setRoot(getRoot()); if (o->getParent() != this) o->setParent(this); getRoot()->addToIndex(o); o->fixTree(); } } /* * even if I run this method with flag recursive=true, it does not * guarantee that there will be no objects lost in the memory. If * some children of this are referenced from somewhere else, they * won't be deleted because their reference counter is >1. This is * bad because it leads to a situation when object is not a part of * the tree anymore, but reference to it does exist. * * If this method is called with recursive=false, then it deletes * only immediate children of this, leaving their children hanging in * the memory. TODO: research whether we ever need to call it with * recursive=false * * In other words, this method leaves tree in inconsistent state. At * this time I am just using it carefully, only when I copy objects * between main tree and scratch pad, and when I create copies of * objects. In both cases children of this will be immediately * restored after call to clearChildren. * * 05/08/02 vk */ void FWObject::clearChildren(bool recursive) { #ifdef FWB_DEBUG cerr << "FWObject::clearChildren" << endl; #endif FWObjectDatabase *dbr = getRoot(); checkReadOnly(); int referenced_children = 0; int total_children = 0; for(list::iterator m=begin(); m!=end(); ++m) { FWObject *o = *m; total_children++; if (recursive) o->clearChildren(recursive); o->unref(); if(o->ref_counter==0) { if (dbr) dbr->removeFromIndex( o->getId() ); delete o; } else referenced_children++; } clear(); setDirty(true); #ifdef FWB_DEBUG cerr << "Deleted " << total_children - referenced_children << " child objects; still referenced " << referenced_children << " child objects" << endl; #endif } int FWObject::getChildrenCount() const { return(size()); } /* * returns true if this is either direct child of obj, or a child * of one of its children and so on. */ bool FWObject::isChildOf(FWObject *obj) { if (this==obj) return false; #ifdef FWB_DEBUG cerr << "FWObject::isChildOf" << endl; cerr << "this: " << endl; dump(true,true); cerr << endl; cerr << "obj: " << endl; obj->dump(true,true); cerr << endl; #endif FWObject *p=this; while (p!=NULL && p!=obj) p=p->getParent(); return (p==obj); } bool FWObject::hasChild(FWObject *obj) { int o_id = obj->getId(); for (list::iterator it=begin(); it!=end(); ++it) { if ((*it)->getId() == o_id) return true; } return false; } FWObject* FWObject::getById (int id, bool recursive) { if(id==getId()) return this; list::iterator j; for(j=begin(); j!=end(); ++j) { FWObject *o=*j; int oid = o->getId(); if(id==oid) return o; if(recursive && (o=o->getById(id, true))!=NULL ) return o; } return NULL; // not found } FWObject* FWObject::getFirstByType(const string &type_name) const { const_iterator i=find_if(begin(),end(), FWObjectTypeNameEQPredicate(type_name)); return i==end()?NULL:(*i); } list FWObject::getByType(const string &type_name) const { list res; for(const_iterator i=begin(); i!=end(); ++i) { i=find_if( i, end(), FWObjectTypeNameEQPredicate(type_name)); if (i==end()) break; res.push_back(*i); } return res; } list FWObject::getByTypeDeep(const string &type_name) const { list res = getByType(type_name); // direct children for (const_iterator i=begin(); i!=end(); ++i) { list c_res = (*i)->getByTypeDeep(type_name); res.insert(res.end(), c_res.begin(), c_res.end()); } return res; } FWObjectTypedChildIterator FWObject::findByType(const std::string &type_name) const { return FWObjectTypedChildIterator(this, type_name); } /** * this method should change 'dirty' flag in the root, i.e. in * FWObjectDatabase object */ void FWObject::setDirty(bool f) { FWObjectDatabase *dbr = getRoot(); if (dbr==NULL) return; if (dbr==this) dirty = f; else dbr->dirty = f; } bool FWObject::isDirty() { FWObjectDatabase *dbr = getRoot(); if (dbr==NULL) return false; return (dbr->dirty); } /* * can't use normal method setBool because it checks for read-only * flag */ void FWObject::setReadOnly(bool f) { ro = f; FWObjectDatabase *dbr = getRoot(); if (dbr) { bool ri = dbr->busy; dbr->busy = true; setDirty(true); dbr->busy = ri; } } /* * scan the tree up from 'this' to the root and see if any object * along the way is marked as read-only. If such object exists, it * makes the whole subtree under it read-only which blocks all * changes. * * If root of the tree has flag 'busy' set to true, we do not check * for read-only. This is used to initialize the tree. */ bool FWObject::isReadOnly() { FWObjectDatabase *dbr = getRoot(); if (dbr==NULL || dbr->busy) return false; FWObject *p=this; while (p) { if (p->ro) return true; p = p->getParent(); } return false; } void FWObject::checkReadOnly() throw(FWException) { if (isReadOnly() && ! getRoot()->getIgnoreReadOnlyFlag()) throw FWException(string("Attempt to modify read-only object ")+getName()); } FWObjectTypedChildIterator::FWObjectTypedChildIterator() : type_name(), real_iterator() { } FWObjectTypedChildIterator::FWObjectTypedChildIterator( const FWObjectTypedChildIterator &o) : type_name(o.type_name), real_iterator(o.real_iterator), _begin(o._begin), _end(o._end) { } FWObjectTypedChildIterator::FWObjectTypedChildIterator( const FWObject *o, const std::string &_type_name) { init(o, _type_name); } void FWObjectTypedChildIterator::init( const FWObject *o, const std::string &_type_name) { type_name = _type_name ; _end = o->end() ; // position to first element real_iterator = o->begin() ; while(real_iterator!=_end && (*real_iterator)->getTypeName()!=type_name) real_iterator++; _begin = real_iterator; } bool FWObjectTypedChildIterator::operator==( const FWObject::const_iterator& __x) const { return real_iterator == __x; } bool FWObjectTypedChildIterator::operator!=( const FWObject::const_iterator& __x) const { return real_iterator != __x; } FWObject *FWObjectTypedChildIterator::operator*() const { return *real_iterator; } FWObjectTypedChildIterator& FWObjectTypedChildIterator::operator++() { if(real_iterator==_end) return *this; do { real_iterator++; } while(real_iterator!=_end && (*real_iterator)->getTypeName()!=type_name); return *this; } /* * if iterator points to the first element in the list, then operator--() * should move it and make it point to end() */ FWObjectTypedChildIterator& FWObjectTypedChildIterator::operator--() { if(real_iterator==_end) return *this; do { real_iterator--; } while(real_iterator!=_end && (*real_iterator)->getTypeName()!=type_name); return *this; } /* this is a postfix operator */ FWObject::tree_iterator FWObject::tree_iterator::operator++(int ) { FWObject::tree_iterator __tmp = *this; ++*this; return __tmp; } //#define TI_DEBUG 1 /* this is a prefix operator */ FWObject::tree_iterator& FWObject::tree_iterator::operator++() { if (node == (FWObject*)(-1)) return *this; #ifdef TI_DEBUG cerr << endl; cerr << "ENTRY node=" << node << "(" << node->getTypeName() << " " << node->getName() << ")" << endl; node->dump(false, false); #endif if (node->size()!=0) { node = node->front(); #ifdef TI_DEBUG cerr << "#2 node=" << node << "(" << node->getTypeName() << " " << node->getName() << ")" << endl; #endif return *this; } FWObject *p = node; while (node->getParent()!=NULL) { p = node->getParent(); #ifdef TI_DEBUG cerr << " p=" << p << "(" << p->getTypeName() << " " << p->getName() << ")" << endl; #endif for (FWObject::iterator i=p->begin(); i!=p->end(); ++i) { #ifdef TI_DEBUG cerr << " child=" << (*i) << "(" << (*i)->getTypeName() << " " << (*i)->getName() << ")" << endl; #endif if ( node == (*i) ) { ++i; if (i==p->end()) { #ifdef TI_DEBUG cerr << " end of list" << endl; #endif node = p; break; } node = *i; #ifdef TI_DEBUG cerr << "#3 node=" << node << "(" << node->getTypeName() << " " << node->getName() << ")" << endl; #endif return *this; } } } node=(FWObject*)(-1); #ifdef TI_DEBUG cerr << "#4 END" << endl; #endif return *this; } bool FWObject::tree_iterator::operator==(const FWObject::tree_iterator& i) const { return (node==i.node); } bool FWObject::tree_iterator::operator!=(const FWObject::tree_iterator& i) const { return (node!=i.node); } FWObject::tree_iterator FWObject::tree_begin() { return FWObject::tree_iterator(this); } FWObject::tree_iterator FWObject::tree_end() { return FWObject::tree_iterator( (FWObject*)(-1) ); } /* * find all references to object with id "old_id" in objects in rs * (recursively) and replace them with references to object with id * "new_id" Use this to find all references to old firewall with * references to the new one when copying policy of the old one into * the new one. */ int FWObject::replaceRef(int old_id, int new_id) { int ref_replacement_counter = 0; replaceReferenceInternal(old_id, new_id, ref_replacement_counter); return ref_replacement_counter; } void FWObject::replaceReferenceInternal(int old_id, int new_id, int &counter) { if (old_id == new_id) return; FWReference *ref = FWReference::cast(this); if (ref==NULL) { for (FWObject::iterator j1=begin(); j1!=end(); ++j1) (*j1)->replaceReferenceInternal(old_id, new_id, counter); } else { if (ref->getPointerId()==old_id) { ref->setPointerId(new_id); counter++; } } } void FWObject::findDependencies(list &deps) { int loop_id = time(NULL); _findDependencies_internal(this, deps, loop_id); } void FWObject::_findDependencies_internal(FWObject *obj, list &deps, int anti_loop_id) { if (obj==NULL) return; if (FWOptions::cast(obj)) return; if (FWReference::cast(obj)!=NULL) { _findDependencies_internal(FWReference::cast(obj)->getPointer(), deps, anti_loop_id); } else { if (obj->getInt(".anti_loop")==anti_loop_id) return; obj->setInt(".anti_loop", anti_loop_id); if (!RuleElement::cast(obj) && !Rule::cast(obj) && !RuleSet::cast(obj)) deps.push_back(obj); if (Group::cast(obj) || RuleSet::cast(obj) || Host::cast(obj)) { for (FWObject::iterator j1=obj->begin(); j1!=obj->end(); ++j1) { FWObject *o = *j1; _findDependencies_internal(o, deps, anti_loop_id); } } } } bool FWObject::isPrimaryObject() const { return false; } const set &FWObject::getAllKeywords() { return dbroot->keywords; } void FWObject::addKeyword(const string &keyword) { keywords.insert(keyword); dbroot->keywords.insert(keyword); } void FWObject::removeKeyword(const string &keyword) { keywords.erase(keyword); } void FWObject::clearKeywords() { keywords.clear(); } FWObjectNameCmpPredicate::FWObjectNameCmpPredicate(bool follow_refs) { follow_references = follow_refs; } bool FWObjectNameCmpPredicate::operator()(FWObject *a, FWObject *b) { FWObject *o1 = (follow_references) ? FWReference::getObject(a) : a; FWObject *o2 = (follow_references) ? FWReference::getObject(b) : b; return o1->getName() < o2->getName(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPRoute.cpp0000644000175000017500000000311411733011756025043 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPRoute.h" #include #include #ifndef _WIN32 # include # include #else # include #endif using namespace std; namespace libfwbuilder { IPRoute::IPRoute(const IPRoute &o) { nm = o.nm; dst = o.dst; gw = o.gw; intf = o.intf; direct = o.direct; } IPRoute::~IPRoute() {} IPRoute::IPRoute(const InetAddr &_dst, const InetAddr &_nm, const InetAddr &_gw, const InterfaceData& _intf, bool _direct) { nm = _nm; dst = _dst; gw = _gw; intf = _intf; direct = _direct; } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp0000644000175000017500000001362311733011756026123 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include using namespace std; using namespace libfwbuilder; const char *DynamicGroup::TYPE_NONE = "none"; const char *DynamicGroup::TYPE_ANY = "any"; const char *DynamicGroup::KEYWORD_NONE = ","; const char *DynamicGroup::KEYWORD_ANY = ""; const char *DynamicGroup::TYPENAME={"DynamicGroup"}; DynamicGroup::DynamicGroup() : MultiAddress() {} DynamicGroup::~DynamicGroup() {} bool DynamicGroup::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; return FWObject::validateChild(o); } void DynamicGroup::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); for (xmlNodePtr child = root->xmlChildrenNode; child != 0; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; assert(strcmp(FROMXMLCAST(child->name), "SelectionCriteria") == 0); const char *type = FROMXMLCAST(xmlGetProp(child, TOXMLCAST("type"))); const char *keyword = FROMXMLCAST(xmlGetProp(child, TOXMLCAST("keyword"))); string filter; if (makeFilter(filter, type, keyword)) { m_filter.push_back(filter); } FREEXMLBUFF(type); FREEXMLBUFF(keyword); } } xmlNodePtr DynamicGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlRemoveProp(xmlHasProp(me, TOXMLCAST("run_time"))); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); list::const_iterator iter; for (iter = m_filter.begin(); iter != m_filter.end(); ++iter) { string filter, type, keyword; if (!splitFilter(*iter, type, keyword)) continue; if (!makeFilter(filter, type, keyword)) continue; xmlNodePtr item = xmlNewChild(me, NULL, TOXMLCAST("SelectionCriteria"), NULL); xmlNewProp(item, TOXMLCAST("type"), STRTOXMLCAST(type)); xmlNewProp(item, TOXMLCAST("keyword"), STRTOXMLCAST(keyword)); } return me; } bool DynamicGroup::splitFilter(const std::string &filter, std::string &type, std::string &keyword) { size_t pos = filter.find(','); if (pos == string::npos) return false; type = filter.substr(0, pos); keyword = filter.substr(pos + 1); return true; } bool DynamicGroup::makeFilter(string &filter, const string &type, const string &keyword) { if (type == TYPE_NONE || keyword == KEYWORD_NONE) return false; filter = type; filter.append(","); filter.append(keyword); return true; } bool DynamicGroup::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (!FWObject::cmp(obj, recursive)) return false; const DynamicGroup *group = DynamicGroup::constcast(obj); return group->m_filter == m_filter; } FWObject& DynamicGroup::shallowDuplicate(const FWObject *other, bool preserve_id) throw (FWException) { const DynamicGroup *otherObj = DynamicGroup::constcast(other); m_filter = otherObj->m_filter; return FWObject::shallowDuplicate(otherObj, preserve_id); } bool DynamicGroup::isCompileTime() const { return true; } void DynamicGroup::loadFromSource(bool ipv6, FWOptions *options, bool test_mode) throw (FWException) { FWObjectDatabase *root = getRoot(); FWObject::tree_iterator tree_iter; for (tree_iter = root->tree_begin(); tree_iter != root->tree_end(); ++tree_iter) { FWObject *elem = (*tree_iter); if (elem == root) continue; if (!isMemberOfGroup(elem)) continue; addRef(elem); } } static bool isInDeletedObjs(FWObject *obj) { FWObject *lib = obj->getLibrary(); return lib == 0 || lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID; } bool DynamicGroup::isMemberOfGroup(FWObject *obj) { if (obj == this) return false; if (ObjectGroup::cast(obj) == 0 && Address::cast(obj) == 0) return false; if (RuleElement::cast(obj) != 0) return false; if (isInDeletedObjs(obj)) return false; /* There's no way to figure out what are the "standard" object groups (like "address tables") from within the fwbuilder library, so we rely on counting how deep we are in the tree instead. */ if (ObjectGroup::cast(obj) != 0 && obj->getDistanceFromRoot() <= 3) return false; const set &keywords = obj->getKeywords(); list::const_iterator iter; for (iter = m_filter.begin(); iter != m_filter.end(); ++iter) { string type, keyword; splitFilter(*iter, type, keyword); if ((type == TYPE_ANY || obj->getTypeName() == type) && (keyword == KEYWORD_ANY || keywords.count(keyword) > 0)) { return true; } } return false; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ServiceGroup.cpp0000644000175000017500000000641411733011756026137 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Service.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/Address.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/RuleSet.h" #include using namespace std; using namespace libfwbuilder; const char *ServiceGroup::TYPENAME={"ServiceGroup"}; ServiceGroup::ServiceGroup() : Group() {} ServiceGroup::~ServiceGroup() {} bool ServiceGroup::validateChild(FWObject *o) { if (FWServiceReference::cast(o)!=NULL) return true; return (FWObject::validateChild(o) && Address::cast(o)==NULL && ObjectGroup::cast(o)==NULL && Interval::cast(o)==NULL && FWObjectReference::cast(o)==NULL && RuleSet::cast(o)==NULL); } FWReference* ServiceGroup::createRef() { // FWServiceReference *ref=new FWServiceReference(); FWServiceReference *ref = getRoot()->createFWServiceReference(); ref->setPointer(this); return ref; } xmlNodePtr ServiceGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } void ServiceGroup::getAllowedTypesOfChildren(std::list &types_list) { types_list.clear(); types_list.push_back(IPService::TYPENAME); types_list.push_back(ICMPService::TYPENAME); types_list.push_back(ICMP6Service::TYPENAME); types_list.push_back(TCPService::TYPENAME); types_list.push_back(UDPService::TYPENAME); types_list.push_back(CustomService::TYPENAME); types_list.push_back(TagService::TYPENAME); types_list.push_back(UserService::TYPENAME); types_list.push_back(FWServiceReference::TYPENAME); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/TCPService.cpp0000644000175000017500000001213011733011756025461 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *TCPService::TYPENAME={"TCPService"}; std::map TCPService::flags; std::map TCPService::flags_masks; TCPService::TCPService() { _init_flags(); clearAllTCPFlags(); clearAllTCPFlagMasks(); } TCPService::~TCPService() {} string TCPService::getProtocolName() const { return "tcp";} int TCPService::getProtocolNumber() const { return 6; } void TCPService::_init_flags() { if (flags.empty()) { flags[URG]="urg_flag"; flags[ACK]="ack_flag"; flags[PSH]="psh_flag"; flags[RST]="rst_flag"; flags[SYN]="syn_flag"; flags[FIN]="fin_flag"; } if (flags_masks.empty()) { flags_masks[URG]="urg_flag_mask"; flags_masks[ACK]="ack_flag_mask"; flags_masks[PSH]="psh_flag_mask"; flags_masks[RST]="rst_flag_mask"; flags_masks[SYN]="syn_flag_mask"; flags_masks[FIN]="fin_flag_mask"; } } void TCPService::fromXML(xmlNodePtr root) throw(FWException) { TCPUDPService::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("established"))); if(n!=NULL) { setStr("established", n); FREEXMLBUFF(n); } std::map::iterator i; for (i=flags.begin(); i!=flags.end(); ++i) { n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST( (i->second).c_str() ))); if(n!=NULL) { setStr( i->second , n); FREEXMLBUFF(n); } } for (i=flags_masks.begin(); i!=flags_masks.end(); ++i) { n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST( (i->second).c_str() ))); if(n!=NULL) { setStr( i->second , n); FREEXMLBUFF(n); } } } xmlNodePtr TCPService::toXML(xmlNodePtr xml_parent_node) throw(FWException) { xmlNodePtr me = TCPUDPService::toXML(xml_parent_node); return me; } bool TCPService::getEstablished() { return getBool("established"); } void TCPService::setEstablished(bool f) { return setBool("established", f); } bool TCPService::inspectFlags() const { return ( ! getAllTCPFlagMasks().empty() ); } bool TCPService::getTCPFlag(TCPFlag fl) const { return getBool( flags[fl] ); } std::set TCPService::getAllTCPFlags() const { std::set res; std::map::iterator i; for (i=flags.begin(); i!=flags.end(); ++i) { TCPFlag fl= i->first; if (getTCPFlag( fl )) res.insert( fl ); } return res; } void TCPService::setTCPFlag(TCPFlag fl,bool v) { setBool( flags[fl] , v ); } bool TCPService::getTCPFlagMask(TCPFlag fl) const { return getBool( flags_masks[fl] ); } std::set TCPService::getAllTCPFlagMasks() const { std::set res; std::map::iterator i; for (i=flags_masks.begin(); i!=flags_masks.end(); ++i) { TCPFlag fl= i->first; if (getTCPFlagMask( fl )) res.insert( fl ); } return res; } void TCPService::setTCPFlagMask(TCPFlag fl,bool v) { setBool( flags_masks[fl] , v ); } void TCPService::clearAllTCPFlags() { setBool( flags[URG] , false ); setBool( flags[ACK] , false ); setBool( flags[PSH] , false ); setBool( flags[RST] , false ); setBool( flags[SYN] , false ); setBool( flags[FIN] , false ); } void TCPService::clearAllTCPFlagMasks() { setBool( flags_masks[URG] , false ); setBool( flags_masks[ACK] , false ); setBool( flags_masks[PSH] , false ); setBool( flags_masks[RST] , false ); setBool( flags_masks[SYN] , false ); setBool( flags_masks[FIN] , false ); } void TCPService::setAllTCPFlagMasks() { setBool( flags_masks[URG] , true ); setBool( flags_masks[ACK] , true ); setBool( flags_masks[PSH] , true ); setBool( flags_masks[RST] , true ); setBool( flags_masks[SYN] , true ); setBool( flags_masks[FIN] , true ); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/MultiAddress.cpp0000644000175000017500000000543011733011756026117 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Network.h" #include #include #include #include using namespace libfwbuilder; using namespace std; const char *MultiAddress::TYPENAME={"MultiAddress"}; MultiAddress::MultiAddress() : FWObject() { setRunTime(false); } MultiAddress::~MultiAddress() { } string MultiAddress::getSourceName() { return ""; } void MultiAddress::setSourceName(const std::string&) { } bool MultiAddress::isCompileTime() const { return !getBool("run_time"); } bool MultiAddress::isRunTime() const { return getBool("run_time"); } void MultiAddress::setCompileTime(const bool b) { setBool("run_time",!b); } void MultiAddress::setRunTime(const bool b) { setBool("run_time",b); } bool MultiAddress::validateChild(FWObject *o) { return ObjectGroup::validateChild(o); } // ======================================================================== const char *MultiAddressRunTime::TYPENAME={"MultiAddressRunTime"}; MultiAddressRunTime::MultiAddressRunTime() { setName("UnknownMultiAddressRunTime"); source_name = "source"; run_time = false; subst_type_name = "Unknown"; } MultiAddressRunTime::MultiAddressRunTime(MultiAddress *maddr) { setName(maddr->getName()); source_name = maddr->getSourceName(); run_time = maddr->isRunTime(); subst_type_name = maddr->getTypeName(); } string MultiAddressRunTime::getSourceNameAsPath(FWOptions *options) const { string ret = source_name; size_t found = ret.find("%DATADIR%"); if (found == string::npos) return ret; string dataDir = options->getStr("data_dir"); if (dataDir.empty()) return dataDir; ret.replace(found, 9, dataDir); return ret; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Dispatch.h0000644000175000017500000002013611733011756024723 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: Dispatch.h 516 2010-01-26 03:25:44Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DISPATCH_HH_FLAG__ #define __DISPATCH_HH_FLAG__ #include #include #include #include "fwbuilder/libfwbuilder-config.h" namespace libfwbuilder { class InetAddr; class InetAddrMask; class Address; class AddressRange; class AddressTable; class Cluster; class ClusterGroup; class ClusterGroupOptions; class CustomService; class DNSName; class FWBDManagement; class FWIntervalReference; class FWObject; class FWObjectDatabase; class FWObjectReference; class FWOptions; class FWReference; class FWServiceReference; class FailoverClusterGroup; class Firewall; class FirewallOptions; class Group; class Host; class HostOptions; class ICMP6Service; class ICMPService; class IPService; class IPv4; class IPv6; class Interface; class InterfaceOptions; class Interval; class IntervalGroup; class Library; class Management; class MultiAddress; class MultiAddressRunTime; class NAT; class NATRule; class NATRuleOptions; class Network; class NetworkIPv6; class ObjectGroup; class Policy; class PolicyInstallScript; class PolicyRule; class PolicyRuleOptions; class Routing; class RoutingRule; class RoutingRuleOptions; class Rule; class RuleElement; class RuleElementDst; class RuleElementInterval; class RuleElementItf; class RuleElementODst; class RuleElementOSrc; class RuleElementOSrv; class RuleElementRDst; class RuleElementRGtw; class RuleElementRItf; class RuleElementSrc; class RuleElementSrv; class RuleElementTDst; class RuleElementTSrc; class RuleElementTSrv; class RuleSet; class RuleSetOptions; class SNMPManagement; class Service; class ServiceGroup; class StateSyncClusterGroup; class TCPService; class TCPUDPService; class TagService; class UDPService; class UserService; class physAddress; class DynamicGroup; }; /* * Keeping return NULL; after assert() to make sure the function * returns something even if compiled with -DNDEBUG that disables assert() * and to make gcc happy at compile time. */ #define __DECLARE_DISPATCH_METHODS(classname) \ virtual void* dispatch(classname*, void*) \ { assert("Call to unimplemented virtual void* Dispatch::dispatch("#classname"*, void*)"==NULL); \ return NULL; } \ virtual void* dispatch(classname*, const void*) \ { assert("Call to unimplemented virtual void* Dispatch::dispatch("#classname"*, const void*)"==NULL); \ return NULL; } \ virtual void* dispatch(const classname*, void*) \ { assert("Call to unimplemented virtual void* Dispatch::dispatch(const "#classname"*, void*)"==NULL); \ return NULL; } \ virtual void* dispatch(const classname*, const void*) \ { assert("Call to unimplemented virtual void* Dispatch::dispatch(const "#classname"*, const void*)"==NULL); \ return NULL; } \ virtual const void* const_dispatch(const classname*, void*) \ { assert("Call to unimplemented virtual const void* Dispatch::const_dispatch(const "#classname"*, void*)"==NULL); \ return NULL; } \ virtual const void* const_dispatch(const classname*, const void*) \ { assert("Call to unimplemented virtual const void* Dispatch::const_dispatch(const "#classname"*, const void*)"==NULL); \ return NULL; }\ namespace libfwbuilder { class Dispatch { public: Dispatch() {} virtual ~Dispatch() {} __DECLARE_DISPATCH_METHODS(Address); __DECLARE_DISPATCH_METHODS(AddressRange); __DECLARE_DISPATCH_METHODS(AddressTable); __DECLARE_DISPATCH_METHODS(Cluster); __DECLARE_DISPATCH_METHODS(ClusterGroup); __DECLARE_DISPATCH_METHODS(ClusterGroupOptions); __DECLARE_DISPATCH_METHODS(CustomService); __DECLARE_DISPATCH_METHODS(DNSName); __DECLARE_DISPATCH_METHODS(FWBDManagement); __DECLARE_DISPATCH_METHODS(FWIntervalReference); __DECLARE_DISPATCH_METHODS(FWObject); __DECLARE_DISPATCH_METHODS(FWObjectDatabase); __DECLARE_DISPATCH_METHODS(FWObjectReference); __DECLARE_DISPATCH_METHODS(FWOptions); __DECLARE_DISPATCH_METHODS(FWReference); __DECLARE_DISPATCH_METHODS(FWServiceReference); __DECLARE_DISPATCH_METHODS(FailoverClusterGroup); __DECLARE_DISPATCH_METHODS(Firewall); __DECLARE_DISPATCH_METHODS(FirewallOptions); __DECLARE_DISPATCH_METHODS(Group); __DECLARE_DISPATCH_METHODS(Host); __DECLARE_DISPATCH_METHODS(HostOptions); __DECLARE_DISPATCH_METHODS(ICMP6Service); __DECLARE_DISPATCH_METHODS(ICMPService); __DECLARE_DISPATCH_METHODS(IPService); __DECLARE_DISPATCH_METHODS(IPv4); __DECLARE_DISPATCH_METHODS(IPv6); __DECLARE_DISPATCH_METHODS(Interface); __DECLARE_DISPATCH_METHODS(InterfaceOptions); __DECLARE_DISPATCH_METHODS(Interval); __DECLARE_DISPATCH_METHODS(IntervalGroup); __DECLARE_DISPATCH_METHODS(Library); __DECLARE_DISPATCH_METHODS(Management); __DECLARE_DISPATCH_METHODS(MultiAddress); __DECLARE_DISPATCH_METHODS(MultiAddressRunTime); __DECLARE_DISPATCH_METHODS(NAT); __DECLARE_DISPATCH_METHODS(NATRule); __DECLARE_DISPATCH_METHODS(NATRuleOptions); __DECLARE_DISPATCH_METHODS(Network); __DECLARE_DISPATCH_METHODS(NetworkIPv6); __DECLARE_DISPATCH_METHODS(ObjectGroup); __DECLARE_DISPATCH_METHODS(Policy); __DECLARE_DISPATCH_METHODS(PolicyInstallScript); __DECLARE_DISPATCH_METHODS(PolicyRule); __DECLARE_DISPATCH_METHODS(PolicyRuleOptions); __DECLARE_DISPATCH_METHODS(Routing); __DECLARE_DISPATCH_METHODS(RoutingRule); __DECLARE_DISPATCH_METHODS(RoutingRuleOptions); __DECLARE_DISPATCH_METHODS(Rule); __DECLARE_DISPATCH_METHODS(RuleElement); __DECLARE_DISPATCH_METHODS(RuleElementDst); __DECLARE_DISPATCH_METHODS(RuleElementInterval); __DECLARE_DISPATCH_METHODS(RuleElementItf); __DECLARE_DISPATCH_METHODS(RuleElementODst); __DECLARE_DISPATCH_METHODS(RuleElementOSrc); __DECLARE_DISPATCH_METHODS(RuleElementOSrv); __DECLARE_DISPATCH_METHODS(RuleElementRDst); __DECLARE_DISPATCH_METHODS(RuleElementRGtw); __DECLARE_DISPATCH_METHODS(RuleElementRItf); __DECLARE_DISPATCH_METHODS(RuleElementSrc); __DECLARE_DISPATCH_METHODS(RuleElementSrv); __DECLARE_DISPATCH_METHODS(RuleElementTDst); __DECLARE_DISPATCH_METHODS(RuleElementTSrc); __DECLARE_DISPATCH_METHODS(RuleElementTSrv); __DECLARE_DISPATCH_METHODS(RuleSet); __DECLARE_DISPATCH_METHODS(RuleSetOptions); __DECLARE_DISPATCH_METHODS(SNMPManagement); __DECLARE_DISPATCH_METHODS(Service); __DECLARE_DISPATCH_METHODS(ServiceGroup); __DECLARE_DISPATCH_METHODS(StateSyncClusterGroup); __DECLARE_DISPATCH_METHODS(TCPService); __DECLARE_DISPATCH_METHODS(TCPUDPService); __DECLARE_DISPATCH_METHODS(TagService); __DECLARE_DISPATCH_METHODS(UDPService); __DECLARE_DISPATCH_METHODS(UserService); __DECLARE_DISPATCH_METHODS(physAddress); __DECLARE_DISPATCH_METHODS(DynamicGroup); }; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/TCPUDPService.h0000644000175000017500000000434711733011756025512 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TCPUDPSERVICE_HH_FLAG__ #define __TCPUDPSERVICE_HH_FLAG__ #include "fwbuilder/Service.h" namespace libfwbuilder { class TCPUDPService : public Service { protected: int src_range_start; int src_range_end; int dst_range_start; int dst_range_end; public: TCPUDPService(); virtual ~TCPUDPService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(TCPUDPService); DECLARE_DISPATCH_METHODS(TCPUDPService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; int getSrcRangeStart() const { return src_range_start; } int getSrcRangeEnd() const { return src_range_end; } int getDstRangeStart() const { return dst_range_start; } int getDstRangeEnd() const { return dst_range_end; } void setSrcRangeStart(int p) { src_range_start = p; } void setSrcRangeEnd(int p) { src_range_end = p; } void setDstRangeStart(int p) { dst_range_start = p; } void setDstRangeEnd(int p) { dst_range_end = p; } virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/MultiAddress.h0000644000175000017500000000655711733011756025577 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GEN_MULTIADDRESS_HH_FLAG__ #define __GEN_MULTIADDRESS_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/Address.h" #include "fwbuilder/ObjectGroup.h" #include namespace libfwbuilder { class MultiAddress : public ObjectGroup { private: public: DECLARE_FWOBJECT_SUBTYPE(MultiAddress); DECLARE_DISPATCH_METHODS(MultiAddress); MultiAddress(); virtual ~MultiAddress(); virtual std::string getSourceName(); virtual void setSourceName(const std::string& source_name); virtual void loadFromSource(bool ipv6, FWOptions *options, bool test_mode=false) throw(FWException) = 0; /* * functions isCompileTime() and isRunTime() are virtual because * some multi-address objects allow the user to set these flags, * while other object types behave as run-time or compile-time * depending on attributes of other objects (e.g. AttachedNetworks) */ virtual bool isCompileTime() const; virtual bool isRunTime() const; void setCompileTime(const bool b); void setRunTime(const bool b); virtual bool validateChild(FWObject *o); virtual bool isPrimaryObject() const { return true; } }; /* * compilers assume that object that appear in Src, Dst, OSrc, ODst * are inherited from class Address and use this in many * places. MultiAddress is derived from ObjectGroup to simplify * processing in compile-time mode, which creates lots of problems * with it when it is configured in run-time mode. To simplify things, * we'll use class MultiAddressRunTime which is derived from * Address. We'll replace MultiAddress objects with run-time mode with * objects of this class in a special rule processor * * Objects of this class are never stored in the data file and do not * appear in DTD; they are only used in compilers. */ class MultiAddressRunTime : public Address { std::string subst_type_name; std::string source_name; bool run_time; public: DECLARE_FWOBJECT_SUBTYPE(MultiAddressRunTime); DECLARE_DISPATCH_METHODS(MultiAddressRunTime); MultiAddressRunTime(); MultiAddressRunTime(MultiAddress *maddr); std::string getSourceName() const { return source_name; } std::string getSubstitutionTypeName() const { return subst_type_name; } std::string getSourceNameAsPath(FWOptions *options) const; bool isCompileTime() const { return !run_time; } bool isRunTime() const { return run_time; } virtual bool isPrimaryObject() const { return true; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWReference.cpp0000644000175000017500000001063211733011756025652 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include using namespace libfwbuilder; using namespace std; const char *FWReference::TYPENAME={"Ref"}; /* FWReference::FWReference(FWObject *p) { setPointer(p); } */ FWReference::FWReference() { setPointer(NULL); } FWReference::~FWReference() {} void FWReference::fromXML(xmlNodePtr root) throw(FWException) { assert(root!=NULL); FWObject::fromXML(root); const char *n = FROMXMLCAST(xmlGetProp(root, TOXMLCAST("ref"))); assert(n!=NULL); str_ref = n; //setInt("ref", n); // if object with id str_ref has not been loaded yet, // FWObjectDatabase::getIntId returns -1. int_ref = FWObjectDatabase::getIntId(str_ref); FREEXMLBUFF(n); } // Note that XML elements represented by FWReference have only one // attribute "ref" and no value xmlNodePtr FWReference::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = xmlNewChild( parent, NULL, xml_name.empty() ? STRTOXMLCAST(getTypeName()) : STRTOXMLCAST(xml_name), NULL); if (int_ref == -1 && !str_ref.empty()) int_ref = FWObjectDatabase::getIntId(str_ref); str_ref = FWObjectDatabase::getStringId(int_ref); xmlNewProp(me, TOXMLCAST("ref"), STRTOXMLCAST(str_ref)); //xmlAddRef(NULL, parent->doc, STRTOXMLCAST(str_ref), pr); return me; } FWObject& FWReference::shallowDuplicate(const FWObject *_other, bool) throw(FWException) { const FWReference *other = FWReference::constcast(_other); int_ref = other->int_ref; str_ref = other->str_ref; return *this; } bool FWReference::cmp(const FWObject *obj, bool /* UNUSED recursive */) throw(FWException) { const FWReference *rx = FWReference::constcast(obj); if (rx == NULL) return false; if (int_ref != rx->int_ref || str_ref != rx->str_ref) return false; return true; } void FWReference::add(FWObject*) { throw std::string("Can't add to a reference !"); } void FWReference::setPointer(FWObject *p) { if(p) setPointerId(p->getId()); else { int_ref = -1; str_ref = ""; } } void FWReference::setPointerId(int ref_id) { //setInt("ref" , ref_id ); int_ref = ref_id; // if object with id ref_id has not been loaded into database // yet, FWObjectDatabase::getStringId returns empty string. // This works as postponed initialization. // We really need string id only in toXML. str_ref = FWObjectDatabase::getStringId(int_ref); } FWObject *FWReference::getPointer() { return getRoot()->findInIndex( getPointerId() ); } int FWReference::getPointerId() { // postponed initialization happens now if (int_ref==-1 && !str_ref.empty()) int_ref = FWObjectDatabase::getIntId(str_ref); return int_ref; //return getInt("ref"); } void FWReference::dump(std::ostream &f, bool recursive, bool brief, int offset) const { FWObject::dump(f, recursive, brief, offset); FWObject* ptr = getRoot()->findInIndex(int_ref); f << string(offset,' ') << "PointerId: " << int_ref << endl; f << string(offset,' ') << "Pointer: " << ptr << endl; if (ptr) { f << string(offset,' ') << "Ptr.name: " << ptr->getName() <getId() <getPointer(); return o; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/CustomService.cpp0000644000175000017500000001404011733011756026307 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/XMLTools.h" using namespace std; using namespace libfwbuilder; const char *CustomService::TYPENAME={"CustomService"}; CustomService::CustomService() { address_family = AF_INET;} CustomService::~CustomService() {} string CustomService::getProtocolName() const { if (protocol.empty()) return "any"; return protocol; } int CustomService::getProtocolNumber() const { return 65000; } FWObject& CustomService::shallowDuplicate(const FWObject *x, bool preserve_id) throw(FWException) { const CustomService *cs = dynamic_cast(x); codes = cs->codes; protocol = cs->protocol; address_family = cs->address_family; return FWObject::shallowDuplicate(x, preserve_id); } void CustomService::fromXML(xmlNodePtr root) throw(FWException) { const char *n; const char *cont; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("name"))); if (n) { setName(n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("id"))); if (n) { setId(FWObjectDatabase::registerStringId(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("comment"))); if (n) { setComment(XMLTools::unquote_linefeeds(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("protocol"))); if (n) { setProtocol(XMLTools::unquote_linefeeds(n)); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address_family"))); if (n) { string af(XMLTools::unquote_linefeeds(n)); if (af=="ipv6") setAddressFamily(AF_INET6); else setAddressFamily(AF_INET); FREEXMLBUFF(n); } for (xmlNodePtr cur=root->xmlChildrenNode; cur; cur=cur->next) { if (cur && !xmlIsBlankNode(cur)) { n = FROMXMLCAST(xmlGetProp(cur,TOXMLCAST("platform"))); assert(n!=NULL); cont = FROMXMLCAST( xmlNodeGetContent(cur) ); if (cont) { setCodeForPlatform(n, cont ); FREEXMLBUFF(cont); } FREEXMLBUFF(n); } } } xmlNodePtr CustomService::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr opt; xmlNodePtr me = FWObject::toXML(parent); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("protocol"), STRTOXMLCAST(getProtocol())); string af; if (getAddressFamily() == AF_INET6) af ="ipv6"; else af = "ipv4"; xmlNewProp(me, TOXMLCAST("address_family"), STRTOXMLCAST(af)); map::const_iterator i; for(i=codes.begin(); i!=codes.end(); ++i) { const string &platform = (*i).first; const string &code = (*i).second; xmlChar *codebuf = xmlEncodeSpecialChars(NULL, STRTOXMLCAST(code) ); opt=xmlNewChild(me,NULL,TOXMLCAST("CustomServiceCommand"), codebuf); FREEXMLBUFF(codebuf); xmlNewProp(opt, TOXMLCAST("platform") , STRTOXMLCAST(platform)); } return me; } bool CustomService::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (CustomService::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; const CustomService *o2 = CustomService::constcast(obj); if (protocol!=o2->protocol || address_family!=o2->address_family) return false; map::const_iterator i; for (i=codes.begin(); i!=codes.end(); ++i) { const string &platform = (*i).first; const string &code = (*i).second; if (o2->codes.count(platform)==0 ) return false; map::const_iterator j=o2->codes.find(platform); if ( (*j).second!=code) return false; } return true; } void CustomService::setCodeForPlatform(const string& platform, const string& code) { codes[platform]=code; } const string CustomService::getCodeForPlatform(const string& platform) const { std::map::const_iterator it = codes.find(platform); if (it == codes.end()) return ""; return it->second; } list CustomService::getAllKnownPlatforms() { list res; map::const_iterator i; for (i=codes.begin(); i!=codes.end(); ++i) { res.push_back( (*i).first); } return res; } void CustomService::setProtocol(const string& proto) { protocol = proto; } const string& CustomService::getProtocol() { if (protocol.empty()) protocol = "any"; return protocol; } void CustomService::setAddressFamily(int af) { address_family = af; } int CustomService::getAddressFamily() { if (address_family==-1) return AF_INET; return address_family; } bool CustomService::isV4Only() { return (getAddressFamily() == AF_INET); } bool CustomService::isV6Only() { return (getAddressFamily() == AF_INET6); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/UDPService.h0000644000175000017500000000242211733011756025133 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UDPSERVICE_HH_FLAG__ #define __UDPSERVICE_HH_FLAG__ #include "fwbuilder/TCPUDPService.h" namespace libfwbuilder { class UDPService : public TCPUDPService { public: UDPService(); virtual ~UDPService(); DECLARE_FWOBJECT_SUBTYPE(UDPService); DECLARE_DISPATCH_METHODS(UDPService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/AttachedNetworks.cpp0000644000175000017500000001032011733011756026763 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include #include #include #include using namespace libfwbuilder; using namespace std; const char *AttachedNetworks::TYPENAME={"AttachedNetworks"}; AttachedNetworks::AttachedNetworks() : MultiAddress() { } void AttachedNetworks::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); } xmlNodePtr AttachedNetworks::toXML(xmlNodePtr parent) throw(FWException) { remStr("run_time"); xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } void AttachedNetworks::addNetworkObject(const InetAddrMask &addr_mask) { const InetAddr *ip_addr = addr_mask.getAddressPtr(); const InetAddr *ip_netm = addr_mask.getNetmaskPtr(); FWObject *new_obj = NULL; if (ip_addr->isV4()) { Network *net = getRoot()->createNetwork(); net->setAddress(*ip_addr); net->setNetmask(*ip_netm); ostringstream str; str << "net-" << ip_addr->toString() << "/" << ip_netm->toString(); net->setName(str.str()); new_obj = net; } if (ip_addr->isV6()) { NetworkIPv6 *net = getRoot()->createNetworkIPv6(); net->setAddress(*ip_addr); net->setNetmask(*ip_netm); ostringstream str; str << "net-" << ip_addr->toString() << "/" << ip_netm->getLength(); net->setName(str.str()); new_obj = net; } if (validateChild(new_obj)) { getRoot()->add(new_obj); addRef(new_obj); } } /* * Read addresses of the parent interface and build a group of * corresponding networks. */ void AttachedNetworks::loadFromSource(bool ipv6, FWOptions*, bool) throw(FWException) { Interface *parent_intf = Interface::cast(getParent()); assert(parent_intf); string c_type = (ipv6) ? IPv6::TYPENAME : IPv4::TYPENAME; // assemble list of address/netmask pairs to eliminate duplicates map networks; FWObjectTypedChildIterator k = parent_intf->findByType(c_type); for ( ; k!=k.end(); ++k) { Address *addr = Address::cast(*k); const InetAddr *ip_netm = addr->getNetmaskPtr(); const InetAddr *ip_net_addr = addr->getNetworkAddressPtr(); ostringstream net; if (ip_net_addr->isV6()) { net << ip_net_addr->toString() << "/" << ip_netm->getLength(); } else { net << ip_net_addr->toString() << "/" << ip_netm->toString(); } networks[net.str()] = InetAddrMask(*ip_net_addr, *ip_netm); } for (map::iterator it=networks.begin(); it!=networks.end(); ++it) { addNetworkObject(it->second); } } string AttachedNetworks::getSourceName() { Interface *parent = Interface::cast(getParent()); assert(parent!=NULL); return parent->getName(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Cluster.cpp0000644000175000017500000001764711733011756025155 0ustar sylvestresylvestre/* * Cluster.cpp - Cluster class implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Resources.h" using namespace std; using namespace libfwbuilder; const char *Cluster::TYPENAME = {"Cluster"}; Cluster::Cluster() { setStr("platform", "unknown"); setStr("host_OS", "unknown"); setInt("lastModified", 0); setInt("lastInstalled", 0); setInt("lastCompiled", 0); } void Cluster::init(FWObjectDatabase *root) { Firewall::init(root); // create one conntrack member group FWObject *state_sync_members = getFirstByType(StateSyncClusterGroup::TYPENAME); if (state_sync_members == NULL) { state_sync_members = root->create(StateSyncClusterGroup::TYPENAME); state_sync_members->setName("State Sync Group"); state_sync_members->setStr("type", "conntrack"); add(state_sync_members); } } void Cluster::fromXML(xmlNodePtr root) throw(FWException) { Firewall::fromXML(root); } xmlNodePtr Cluster::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = Firewall::toXML(parent); FWObject *o; for (FWObjectTypedChildIterator it = findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) { o = *it; if (o) { o->toXML(me); } } return me; } FWOptions* Cluster::getOptionsObject() { return FWOptions::cast(getFirstByType(FirewallOptions::TYPENAME)); } Policy* Cluster::getPolicy() { return (Policy::cast(findObjectByName(Policy::TYPENAME, "Policy"))); } NAT* Cluster::getNAT() { return (NAT::cast(findObjectByName(NAT::TYPENAME, "NAT"))); } Routing* Cluster::getRouting() { return(Routing::cast(findObjectByName(Routing::TYPENAME, "Routing"))); } ClusterGroup* Cluster::getStateSyncGroupObject() { StateSyncClusterGroup *group = StateSyncClusterGroup::cast( getFirstByType(StateSyncClusterGroup::TYPENAME)); if (group == NULL) { // create a new ClusterGroup object group = StateSyncClusterGroup::cast(getRoot()->create( StateSyncClusterGroup::TYPENAME)); add(group); } return group; } bool Cluster::validateChild(FWObject *o) { string otype = o->getTypeName(); return (FWObject::validateChild(o) && (otype == Interface::TYPENAME || otype == RuleSet::TYPENAME || otype == Policy::TYPENAME || otype == NAT::TYPENAME || otype == Routing::TYPENAME || otype == Management::TYPENAME || otype == StateSyncClusterGroup::TYPENAME || otype == FirewallOptions::TYPENAME)); } FWObject& Cluster::duplicate(const FWObject *obj, bool preserve_id) throw(FWException) { Firewall::duplicate(obj, preserve_id); FWObject *o; for (FWObjectTypedChildIterator it = obj->findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) { o = *it; if (o) { addCopyOf(o, preserve_id); } } return *this; } void Cluster::updateLastInstalledTimestamp() { setInt("lastInstalled", time(NULL)); } void Cluster::updateLastModifiedTimestamp() { setInt("lastModified", time(NULL)); } bool Cluster::needsInstall() { if (getLastInstalled() == 0 || getLastCompiled() == 0) { return true; } return !(getLastModified() <= getLastCompiled() && getLastCompiled() <= getLastInstalled()); } bool Cluster::needsCompile() { return getLastModified() > getLastCompiled() || getLastCompiled() == 0; } time_t Cluster::getLastModified() { return getInt("lastModified"); } time_t Cluster::getLastInstalled() { return getInt("lastInstalled"); } time_t Cluster::getLastCompiled() { return getInt("lastCompiled"); } void Cluster::updateLastCompiledTimestamp() { setInt("lastCompiled", time(NULL)); } bool Cluster::getInactive() { return getBool("inactive"); } void Cluster::setInactive(bool b) { setBool("inactive", b); } bool Cluster::validateMember(Firewall *fw) { string my_host_os = getStr("host_OS"); string their_host_os = fw->getStr("host_OS"); string my_platform = getStr("platform"); string their_platform = fw->getStr("platform"); if (my_host_os != their_host_os) return false; if (my_platform != their_platform) return false; if (! Resources::getTargetCapabilityBool(my_host_os, "supports_cluster")) return false; // Any other checks we should do ? return true; } /* * List members should contain each member firewall only once, but the * same member firewall can be present in several failover groups and * possibly in state synchronization group. Using set to make the * list unique. */ void Cluster::getMembersList(list &members) { set members_ids; list all_groups = getByTypeDeep(StateSyncClusterGroup::TYPENAME); list all_failover = getByTypeDeep(FailoverClusterGroup::TYPENAME); all_groups.merge(all_failover); for (list::iterator it = all_groups.begin(); it != all_groups.end(); ++it) { for (list::iterator j = (*it)->begin(); j != (*it)->end(); ++j) { FWObject *member = FWReference::getObject(*j); if (ClusterGroupOptions::isA(member)) continue; Firewall *fw = NULL; // as of 05/04 members of StateSyncClusterGroup are interfaces. See // tickets #10 and #11 if (Interface::cast(member)) fw = Firewall::cast(Host::getParentHost(member)); else fw = Firewall::cast(member); members_ids.insert(fw->getId()); } } for (set::iterator it = members_ids.begin(); it != members_ids.end(); ++it) { Firewall *fw = Firewall::cast(getRoot()->findInIndex(*it)); if (fw) members.push_back(fw); } } bool Cluster::hasMember(Firewall *fw) { list all_groups = getByTypeDeep(StateSyncClusterGroup::TYPENAME); list all_failover = getByTypeDeep(FailoverClusterGroup::TYPENAME); all_groups.merge(all_failover); for (list::iterator it = all_groups.begin(); it != all_groups.end(); ++it) { for (list::iterator j = (*it)->begin(); j != (*it)->end(); ++j) { FWObject *member = FWReference::getObject(*j); if (ClusterGroupOptions::isA(member)) continue; Firewall *member_fw = NULL; // as of 05/04/2009 members of StateSyncClusterGroup are // interfaces. See tickets #10 and #11 if (Interface::cast(member)) member_fw = Firewall::cast(Host::getParentHost(member)); else member_fw = Firewall::cast(member); if (fw == member_fw) return true; } } return false; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/SecuwallMgmtFile.h0000644000175000017500000000216211733011756026367 0ustar sylvestresylvestre/* * SecuwallMgmtFile.h - hosts(5) file format parser * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __SECUWALLMGMT_FILE_H_ #define __SECUWALLMGMT_FILE_H_ #include "FWException.h" #include #include #include namespace libfwbuilder { /** * This class is parser for file in hosts(5) format * (e.g. /etc/hosts) */ class SecuwallMgmtFile { public: void parse(const std::string &filename) throw(FWException); void parse(std::istream &from) throw(FWException); /* Return data */ std::map getData() { return data; } private: std::map data; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWOptions.cpp0000644000175000017500000000704111733011756025407 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include using namespace std; using namespace libfwbuilder; const char *FWOptions::TYPENAME={"FWOptions"}; FWOptions::FWOptions() { remStr("comment"); remStr("name" ); remStr("id" ); } void FWOptions::fromXML(xmlNodePtr root) throw(FWException) { const char *n; const char *cont; for (xmlNodePtr cur = root->xmlChildrenNode; cur; cur = cur->next) { if (cur && !xmlIsBlankNode(cur)) { n = FROMXMLCAST(xmlGetProp(cur,TOXMLCAST("name"))); assert(n!=NULL); cont = FROMXMLCAST( xmlNodeGetContent(cur) ); if (cont) { setStr(n, cont ); FREEXMLBUFF(cont); } FREEXMLBUFF(n); } } } xmlNodePtr FWOptions::toXML(xmlNodePtr root) throw(FWException) { xmlNodePtr opt; xmlNodePtr me = xmlNewChild( root, NULL, xml_name.empty() ? STRTOXMLCAST(getTypeName()) : STRTOXMLCAST(xml_name), NULL); for(map::const_iterator i=data.begin(); i!=data.end(); ++i) { const string &name = (*i).first; const string &value = (*i).second; if (name[0]=='.') continue; xmlChar *valbuf = xmlEncodeSpecialChars(root->doc, STRTOXMLCAST(value) ); // xmlChar *valbuf = xmlEncodeEntitiesReentrant(root->doc, // STRTOXMLCAST(value) ); opt = xmlNewChild(me, NULL, TOXMLCAST("Option"), valbuf); FREEXMLBUFF(valbuf); xmlNewProp(opt, TOXMLCAST("name") , STRTOXMLCAST(name)); } return me; } const char *HostOptions::TYPENAME ={"HostOptions"}; HostOptions::HostOptions() : FWOptions() {} const char *FirewallOptions::TYPENAME ={"FirewallOptions"}; FirewallOptions::FirewallOptions() : FWOptions() {} const char *InterfaceOptions::TYPENAME ={"InterfaceOptions"}; InterfaceOptions::InterfaceOptions() : FWOptions() {} const char *RuleSetOptions::TYPENAME={"RuleSetOptions"}; RuleSetOptions::RuleSetOptions() : FWOptions() {} const char *PolicyRuleOptions::TYPENAME={"PolicyRuleOptions"}; PolicyRuleOptions::PolicyRuleOptions() : FWOptions() {} const char *NATRuleOptions::TYPENAME={"NATRuleOptions"}; NATRuleOptions::NATRuleOptions() : FWOptions() {} const char *RoutingRuleOptions::TYPENAME={"RoutingRuleOptions"}; RoutingRuleOptions::RoutingRuleOptions() : FWOptions() {} const char *ClusterGroupOptions::TYPENAME={"ClusterGroupOptions"}; ClusterGroupOptions::ClusterGroupOptions() : FWOptions() {} fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectReference.cpp0000644000175000017500000000302411733011756026776 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; const char *FWObjectReference::TYPENAME={"ObjectRef"}; //FWObjectReference::FWObjectReference(FWObject *p):FWReference(p) //{ //} FWObjectReference::FWObjectReference():FWReference() { } void FWObjectReference::setPointer(FWObject *p) { //TODO: add check if it is right type. FWReference::setPointer(p); } void FWObjectReference::setPointer(ObjectGroup *p) { //TODO: add check if it is right type. FWReference::setPointer(p); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Library.h0000644000175000017500000000276511733011756024600 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id$ */ #ifndef __LIBRARY_HH_FLAG__ #define __LIBRARY_HH_FLAG__ #include "fwbuilder/Group.h" namespace libfwbuilder { class Library : public Group { protected: public: Library(); virtual ~Library(); DECLARE_FWOBJECT_SUBTYPE(Library); DECLARE_DISPATCH_METHODS(Library); virtual void fromXML (xmlNodePtr xml_parent_node) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual bool isPrimaryObject() const { return true; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ThreadTools.cpp0000644000175000017500000000676111733011756025757 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ThreadTools.h" #include #include #ifndef _WIN32 # include # include #else # include #endif # ifndef DST_NONE # define DST_NONE 0 # endif using namespace std; using namespace libfwbuilder; Mutex::Mutex() { pthread_mutexattr_t mutexattr; pthread_mutexattr_init( &mutexattr); // pthread_mutexattr_settype( &mutexattr, PTHREAD_MUTEX_FAST_NP ); pthread_mutex_init(&mutex, &mutexattr); } Mutex::~Mutex() { } void Mutex::lock() const { pthread_mutex_lock( (pthread_mutex_t*)&mutex ); } void Mutex::unlock() const { pthread_mutex_unlock( (pthread_mutex_t*)&mutex ); } Cond::Cond() { pthread_cond_init( &cond, NULL ); } Cond::~Cond() { } bool Cond::wait(const Mutex &m) const { m.lock(); pthread_cond_wait( (pthread_cond_t*)&cond, (pthread_mutex_t*)&m.mutex); return true; } void Cond::signal() const { pthread_cond_signal( (pthread_cond_t*)&cond ); } void Cond::broadcast() const { pthread_cond_broadcast( (pthread_cond_t*)&cond ); } SyncFlag::SyncFlag(bool v) { value = v; } bool SyncFlag::peek() const { return value; } bool SyncFlag::get() const { bool v; lock(); v = value; unlock(); return v; } void SyncFlag::modify(bool v) { value = v; } void SyncFlag::set(bool v) { lock(); value = v; unlock(); } SyncFlag::operator bool() const { return get(); } SyncFlag& SyncFlag::operator=(const SyncFlag &o) { set(o.get()); return *this; } SyncFlag& SyncFlag::operator=(bool v) { set(v); return *this; } #ifndef _WIN32 TimeoutCounter::TimeoutCounter(unsigned int _timeout, const string &_name) : timeout(_timeout),name(_name) { start(); } void TimeoutCounter::start() { time_t tres; finish = time(&tres) + timeout ; } unsigned int TimeoutCounter::timeLeft() const { time_t tres; int res = finish-time(&tres); return res<0?0:res; } bool TimeoutCounter::isExpired() const { time_t tres; return time(&tres) > finish ; } void TimeoutCounter::check() const throw(FWException) { if(isExpired()) { //cerr << "Expired Timeout Counter." << endl; throw FWException(name+" timeout"); } } ssize_t TimeoutCounter::read(int fd, void *buf, size_t n) const throw(FWException) { struct pollfd ufds[1]; ufds[0].fd=fd; ufds[0].events=POLLIN|POLLPRI; int retval=poll(ufds, 1, 1000*timeLeft()); if(retval==0) throw FWException("Timeout "+name); else if(retval>0) return ::read(fd, buf, n); else return -1; //error } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/SecuwallMgmtFile.cpp0000644000175000017500000000756211733011756026733 0ustar sylvestresylvestre/* * SecuwallMgmtFile.cpp - hosts(5) file format parser implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/SecuwallMgmtFile.h" #include "fwbuilder/Tools.h" #include #include #include using namespace std; using namespace libfwbuilder; void SecuwallMgmtFile::parse(const string &filename) throw(FWException) { ifstream f(filename.c_str(), ios::in); if (!f) { throw FWException("Can't open file '" + filename + "'"); } else { parse(f); } } /** * Does the actual parsing. */ void SecuwallMgmtFile::parse(istream &from) throw(FWException) { enum { s_begin, s_key, s_space, s_value, s_rest } state; state = s_begin; string key; string temp; char c; int ln = 1; while (from.get(c)) { switch (state) { case s_begin: if (c == '#') { /* Ignore commented lines */ state = s_rest; break; } else if (c != '\n' && c != ' ' && c != '\t' && c != '\"') { /* Found key entry */ state = s_key; } else break; case s_key: if (c == '=' || c == ' ' || c == '\t' || c == '\"') { /* End of key */ if (temp.empty()) { ostringstream err; cerr << "Found line without key: " << ln; throw FWException(err.str()); } key = temp; temp.clear(); state = s_space; } else { /* Processing key entry */ temp += c; } break; case s_space: if (c == '#' || c == '\n') { /* Key entry without value */ ostringstream err; cerr << "Found key without value: " << ln; throw FWException(err.str()); } else if (c == ' ' || c == '\t') { /* Ignore whitespaces */ break; } else { /* Process value */ state = s_value; } /* FALLTHROUGH */ case s_value: if (c == ' ' || c == '\t' || c == '#' || c == '\n') { /* Store data */ data.insert(make_pair(key, temp)); /* Reset processing variables */ key.clear(); temp.clear(); if (c == '\n') { /* Process next line */ ln++; state = s_begin; } else { /* Process rest of line */ state = s_rest; } break; } else if (c == '\"') { /* Ignore Quotation marks */ break; } else { temp += c; break; } case s_rest: if (c == '\n') { ln++; state = s_begin; } break; } } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/InetAddr.h0000644000175000017500000002254411733011756024663 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INETADDR_HH_FLAG__ #define __INETADDR_HH_FLAG__ #include #include #include #include #ifndef _WIN32 # include # include # include # include #else # include # include # include typedef unsigned int uint32_t; #endif #include "fwbuilder/uint128.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWException.h" namespace libfwbuilder { /** * Class InetAddr is a wrapper for struct inet_addr and in6_addr * * Why both address families are implemented as the same class ? Mostly * because I need to have a family of two-argument operators such as * operator&, operator| etc which return new object of the class that * represent the same address family as the arguments. These operators * should be "friends" of class InetAddr since they return new object * by value rather than modify "this". But how to do it if returned * type should be different depending on the types of arguments ? * */ class InetAddr { protected: friend class InetAddrMask; friend class Inet6AddrMask; int address_family; // Address in network order struct in_addr ipv4; struct in6_addr ipv6; // copy in6_addr from sa to da static inline void _copy_in6_addr(struct in6_addr* da, const struct in6_addr* sa) { ((uint32_t*)(da))[0] = ((uint32_t*)(sa))[0]; ((uint32_t*)(da))[1] = ((uint32_t*)(sa))[1]; ((uint32_t*)(da))[2] = ((uint32_t*)(sa))[2]; ((uint32_t*)(da))[3] = ((uint32_t*)(sa))[3]; } void init_from_string(const char* data); void init_from_int(unsigned int n); public: explicit InetAddr() { address_family = AF_INET; ipv4.s_addr = 0; ((uint32_t *) (&ipv6))[0] = 0; ((uint32_t *) (&ipv6))[1] = 0; ((uint32_t *) (&ipv6))[2] = 0; ((uint32_t *) (&ipv6))[3] = 0; } virtual ~InetAddr() {} inline unsigned int addressLengthBits() const { if (address_family == AF_INET) return sizeof(ipv4) * 8; return sizeof(ipv6) * 8; } bool isValidV4Netmask(); void init_from_uint128(uint128 int128a); uint128 to_uint128() const; InetAddr(const char *data) throw(FWException); InetAddr(int af, const char *data) throw(FWException); InetAddr(const struct in_addr*) throw(FWException); InetAddr(const struct in6_addr*) throw(FWException); explicit InetAddr(const std::string&) throw(FWException, FWNotSupportedException); explicit InetAddr(int af, const std::string&) throw(FWException, FWNotSupportedException); InetAddr(const InetAddr &); // creates netmask 'n' bits long explicit InetAddr(int n) throw(FWException); explicit InetAddr(int af, int n) throw(FWException); InetAddr& operator=(const InetAddr &addr); int addressFamily() const { return address_family; } bool isV4() const { return (address_family==AF_INET); } bool isV6() const { return (address_family==AF_INET6); } const struct in_addr* getV4() const { return &ipv4; } const struct in6_addr* getV6() const { return &ipv6; } static inline InetAddr getAny() { return InetAddr(); } static inline InetAddr getAllOnes(int af=AF_INET) { if (af==AF_INET) { struct in_addr allones; allones.s_addr = 0xffffffff; return InetAddr(&allones); } else { struct in6_addr a; ((uint32_t *) (&a))[0] = 0xffffffff; ((uint32_t *) (&a))[1] = 0xffffffff; ((uint32_t *) (&a))[2] = 0xffffffff; ((uint32_t *) (&a))[3] = 0xffffffff; return InetAddr(&a); } } static inline InetAddr getLoopbackAddr(int af=AF_INET) { if (af==AF_INET) { struct in_addr loopback; loopback.s_addr = htonl(INADDR_LOOPBACK); return InetAddr(&loopback); } else { struct in6_addr a; ((uint32_t *) (&a))[0] = 0; ((uint32_t *) (&a))[1] = 0; ((uint32_t *) (&a))[2] = 0; ((uint32_t *) (&a))[3] = htonl (1); return InetAddr(&a); } } std::string toString() const; /** * Broadcast : 255.255.255.255 * * there are no broadcast addresses in ipv6. However some multicast * addresses serve similar purpose. For example "link-scope * all-hosts multicast" address ff02::1 corresponds to the ipv4 * broadcast 255.255.255.255 */ inline bool isBroadcast() const { if (address_family==AF_INET) return ipv4.s_addr == INADDR_BROADCAST; else return IN6_IS_ADDR_MC_LINKLOCAL(&ipv6); } /** * Multicast : 224.0.0.0 - 239.0.0.0 */ inline bool isMulticast() const { if (address_family==AF_INET) return IN_MULTICAST(ntohl(ipv4.s_addr)); else return IN6_IS_ADDR_MULTICAST(&ipv6); } /** * INADDR_ANY: 0 */ inline bool isAny() const { if (address_family==AF_INET) return ipv4.s_addr == INADDR_ANY; else return (IN6_IS_ADDR_UNSPECIFIED(&ipv6)); } /** * calculate distance between _this_ address and address a2 and return * it as int * This method is limited, it only calculates distance that fit in 32 bit * number */ inline unsigned int distance(const InetAddr &a2) const { if (address_family==AF_INET) return ntohl(a2.ipv4.s_addr) - ntohl(ipv4.s_addr) + 1; else { uint128 d1 = to_uint128(); uint128 d2 = a2.to_uint128(); uint128 res; if (d1 < d2) { res = d2; res -= d1; } else { res = d1; res -= d2; } return res.to_integer() + 1; } } /** * returns the "length" of the netmask, that is number of bits set to '1' * counting from left to right */ int getLength() const; /** * for netmasks: return true if this is host mask, i.e. all '1' */ inline bool isHostMask() const { if (address_family==AF_INET) return ipv4.s_addr == INADDR_BROADCAST; else return (((uint32_t*)(&ipv6))[0] == 0xffffffff && ((uint32_t*)(&ipv6))[1] == 0xffffffff && ((uint32_t*)(&ipv6))[2] == 0xffffffff && ((uint32_t*)(&ipv6))[3] == 0xffffffff); } /*****************************************************************/ InetAddr opAnd(const InetAddr &mask) const; InetAddr opOr(const InetAddr &mask) const; InetAddr opPlus(int increment) const; InetAddr opMinus(int decrement) const; bool opLT(const InetAddr &other) const; bool opGT(const InetAddr &other) const; bool opEQ(const InetAddr &other) const; bool opNEQ(const InetAddr &other) const; InetAddr opCompl() const; /*****************************************************************/ inline friend InetAddr operator&(const InetAddr &addr, const InetAddr &mask) { assert (typeid(addr) == typeid(mask)); return addr.opAnd(mask); } inline friend InetAddr operator|(const InetAddr &addr, const InetAddr &mask) { assert (typeid(addr) == typeid(mask)); return addr.opOr(mask); } inline friend InetAddr operator+(const InetAddr &addr, int increment) { return addr.opPlus(increment); } inline friend InetAddr operator-(const InetAddr &addr, int decrement) { return addr.opMinus(decrement); } inline friend bool operator<(const InetAddr &a, const InetAddr &b) { assert (typeid(a) == typeid(b)); return a.opLT(b); } inline friend bool operator>(const InetAddr &a, const InetAddr &b) { assert (typeid(a) == typeid(b)); return a.opGT(b); } inline friend bool operator==(const InetAddr &a, const InetAddr &b) { assert (typeid(a) == typeid(b)); return a.opEQ(b); } inline friend bool operator!=(const InetAddr &a, const InetAddr &b) { assert (typeid(a) == typeid(b)); return a.opNEQ(b); } inline friend InetAddr operator~(const InetAddr &a) { return a.opCompl(); } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Host.cpp0000644000175000017500000001100611733011756024430 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Host.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/XMLTools.h" using namespace std; using namespace libfwbuilder; const char *Host::TYPENAME={"Host"}; Host::Host() { } void Host::init(FWObjectDatabase *root) { FWObject *opt = getFirstByType(HostOptions::TYPENAME); if (opt == NULL) add( root->createHostOptions() ); } Host::~Host() {} void Host::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); } xmlNodePtr Host::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); FWObject *o; for(FWObjectTypedChildIterator j=findByType(Interface::TYPENAME); j!=j.end(); ++j) if((o=(*j))!=NULL ) o->toXML(me); o=getFirstByType( Management::TYPENAME ); if (o) o->toXML(me); o=getFirstByType( HostOptions::TYPENAME ); if (o) o->toXML(me); return me; } bool Host::validateChild(FWObject *o) { string otype=o->getTypeName(); return (FWObject::validateChild(o) && (otype==Interface::TYPENAME || otype==Management::TYPENAME || otype==HostOptions::TYPENAME) ); } /* * TODO: Implement syntax checks for interfaces * */ bool Host::Appropriate(Interface*) { return true; } void Host::addInterface(Interface *i) { add(i); } void Host::removeInterface(Interface *i) { remove(i); } FWOptions* Host::getOptionsObject() { return FWOptions::cast( getFirstByType(HostOptions::TYPENAME) ); } Management *Host::getManagementObject() { Management *res = dynamic_cast( getFirstByType(Management::TYPENAME)); if(!res) add( res = getRoot()->createManagement() ); // add(res = new Management()); return res; } /** * returns address from management interface. If there is no * management interface or no address to be found, returns NULL. * May throw exception if interface has invalid address. */ const InetAddr* Host::getManagementAddress() throw(FWException) { list interfaces = getByTypeDeep(Interface::TYPENAME); list::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); if (iface->isManagement()) { FWObjectTypedChildIterator k = iface->findByType(IPv4::TYPENAME); if (k != k.end()) return Address::cast(*k)->getAddressPtr(); } } return NULL; } const Address* Host::getAddressObject() const { FWObjectTypedChildIterator j = findByType(Interface::TYPENAME); if (j == j.end()) return NULL; return Interface::cast(*j)->getAddressObject(); } int Host::countInetAddresses(bool skip_loopback) const { int res = 0; FWObjectTypedChildIterator j = findByType(Interface::TYPENAME); for( ; j!=j.end(); ++j) { Interface *iface = Interface::cast(*j); res += iface->countInetAddresses(skip_loopback); } return res; } /* * This function will find parent host, firewall or cluster object of * a given object. If object is not a child of host, firewall or * cluster, it returns NULL */ FWObject* Host::getParentHost(FWObject *obj) { FWObject *parent_h = obj; while (parent_h != NULL && Host::cast(parent_h) == NULL) parent_h = parent_h->getParent(); return parent_h; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ObjectGroup.cpp0000644000175000017500000000607111733011756025744 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Service.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interval.h" #include "fwbuilder/Host.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/RuleSet.h" using namespace std; using namespace libfwbuilder; const char *ObjectGroup::TYPENAME={"ObjectGroup"}; ObjectGroup::ObjectGroup() : Group() {} ObjectGroup::~ObjectGroup() {} bool ObjectGroup::validateChild(FWObject *o) { if (FWObjectReference::cast(o)!=NULL) return true; return (FWObject::validateChild(o) && Service::cast(o)==NULL && ServiceGroup::cast(o)==NULL && Interval::cast(o)==NULL && FWServiceReference::cast(o)==NULL && RuleSet::cast(o)==NULL); } xmlNodePtr ObjectGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } void ObjectGroup::getAllowedTypesOfChildren(std::list &types_list) { types_list.clear(); types_list.push_back(Host::TYPENAME); types_list.push_back(Firewall::TYPENAME); types_list.push_back(Cluster::TYPENAME); types_list.push_back(Network::TYPENAME); types_list.push_back(NetworkIPv6::TYPENAME); types_list.push_back(IPv4::TYPENAME); types_list.push_back(IPv6::TYPENAME); types_list.push_back(DNSName::TYPENAME); types_list.push_back(AddressTable::TYPENAME); types_list.push_back(AddressRange::TYPENAME); types_list.push_back(FWObjectReference::TYPENAME); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/AddressTable.h0000644000175000017500000000317111733011756025521 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GEN_ADDRESSTABLE_HH_FLAG__ #define __GEN_ADDRESSTABLE_HH_FLAG__ #include "fwbuilder/MultiAddress.h" namespace libfwbuilder { class AddressTable : public MultiAddress { private: std::string getFilename(FWOptions *options) throw(FWException); public: DECLARE_FWOBJECT_SUBTYPE(AddressTable); DECLARE_DISPATCH_METHODS(AddressTable); AddressTable(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual std::string getSourceName(); virtual void setSourceName(const std::string& source_name); virtual void loadFromSource(bool ipv6, FWOptions *options, bool test_mode=false) throw(FWException); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FailoverClusterGroup.h0000644000175000017500000000264211733011756027314 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FAILOVERCLUSTERGROUP_HH_ #define __FAILOVERCLUSTERGROUP_HH_ #include "fwbuilder/ClusterGroup.h" namespace libfwbuilder { class FailoverClusterGroup : public ClusterGroup { public: FailoverClusterGroup(); virtual ~FailoverClusterGroup() {}; DECLARE_FWOBJECT_SUBTYPE(FailoverClusterGroup); DECLARE_DISPATCH_METHODS(FailoverClusterGroup); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); }; } #endif /* __CLUSTERGROUP_HH_ */ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/inet_net_pton.c0000644000175000017500000003521211733011756026025 0ustar sylvestresylvestre/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include "inet_net.h" #include #include #include #include #include static int inet_net_pton_ipv4(const char *src, u_char *dst); static int inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size); static int inet_net_pton_ipv6(const char *src, u_char *dst); static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size); static const size_t invalid_size = -1; /* * int * inet_net_pton(af, src, dst, size) * convert network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not a valid network specification. * author: * Paul Vixie (ISC), June 1996 * * Changes: * I added the inet_cidr_pton function (also from Paul) and changed * the names to reflect their current use. * */ int inet_net_pton(int af, const char *src, void *dst, size_t size) { switch (af) { case AF_INET: return size == invalid_size ? inet_net_pton_ipv4(src, dst) : inet_cidr_pton_ipv4(src, dst, size); case AF_INET6: return size == invalid_size ? inet_net_pton_ipv6(src, dst) : inet_cidr_pton_ipv6(src, dst, size); default: errno = EAFNOSUPPORT; return (-1); } } /* * static int * inet_cidr_pton_ipv4(src, dst, size) * convert IPv4 network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not an IPv4 network specification. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), June 1996 */ static int inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) { static const char xdigits[] = "0123456789abcdef"; static const char digits[] = "0123456789"; int n, ch, tmp = 0, dirty, bits; const u_char *odst = dst; ch = *src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && isxdigit((unsigned char) src[1])) { /* Hexadecimal: Eat nybble string. */ if (size <= 0U) goto emsgsize; dirty = 0; src++; /* skip x or X. */ while ((ch = *src++) != '\0' && isxdigit((unsigned char) ch)) { if (isupper((unsigned char) ch)) ch = tolower((unsigned char) ch); n = strchr(xdigits, ch) - xdigits; assert(n >= 0 && n <= 15); if (dirty == 0) tmp = n; else tmp = (tmp << 4) | n; if (++dirty == 2) { if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) tmp; dirty = 0; } } if (dirty) { /* Odd trailing nybble? */ if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) (tmp << 4); } } else if (isdigit((unsigned char) ch)) { /* Decimal: eat dotted digit string. */ size_t size_l = 4; // vk for (;;) { tmp = 0; do { n = strchr(digits, ch) - digits; assert(n >= 0 && n <= 9); tmp *= 10; tmp += n; if (tmp > 255) goto enoent; } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch)); if (size_l-- == 0) goto emsgsize; if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) tmp; if (ch == '\0' || ch == '/') break; if (ch != '.') goto enoent; ch = *src++; if (!isdigit((unsigned char) ch)) goto enoent; } /* Extend address to four octets. -- vk */ while (size_l-- > 0) *dst++ = 0; } else goto enoent; bits = -1; if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ bits = 0; do { n = strchr(digits, ch) - digits; assert(n >= 0 && n <= 9); bits *= 10; bits += n; } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch)); if (ch != '\0') goto enoent; if (bits > 32) goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; /* If nothing was written to the destination, we found no address. */ if (dst == odst) goto enoent; /* If no CIDR spec was given, infer width from net class. */ if (bits == -1) { if (*odst >= 240) /* Class E */ bits = 32; else if (*odst >= 224) /* Class D */ bits = 8; else if (*odst >= 192) /* Class C */ bits = 24; else if (*odst >= 128) /* Class B */ bits = 16; else /* Class A */ bits = 8; /* If imputed mask is narrower than specified octets, widen. */ if (bits < ((dst - odst) * 8)) bits = (dst - odst) * 8; /* * If there are no additional bits specified for a class D address * adjust bits to 4. */ if (bits == 8 && *odst == 224) bits = 4; } /* Extend network to cover the actual mask. */ while (bits > ((dst - odst) * 8)) { if (size-- <= 0U) goto emsgsize; *dst++ = '\0'; } return (bits); enoent: errno = ENOENT; return (-1); emsgsize: errno = EMSGSIZE; return (-1); } /* * int * inet_net_pton(af, src, dst, *bits) * convert network address from presentation to network format. * accepts inet_pton()'s input for this "af" plus trailing "/CIDR". * "dst" is assumed large enough for its "af". "bits" is set to the * /CIDR prefix length, which can have defaults (like /32 for IPv4). * return: * -1 if an error occurred (inspect errno; ENOENT means bad format). * 0 if successful conversion occurred. * note: * 192.5.5.1/28 has a nonzero host part, which means it isn't a network * as called for by inet_cidr_pton() but it can be a host address with * an included netmask. * author: * Paul Vixie (ISC), October 1998 */ static int inet_net_pton_ipv4(const char *src, u_char *dst) { static const char digits[] = "0123456789"; const u_char *odst = dst; int n, ch, tmp, bits; size_t size = 4; /* Get the mantissa. */ while (ch = *src++, isdigit((unsigned char) ch)) { tmp = 0; do { n = strchr(digits, ch) - digits; assert(n >= 0 && n <= 9); tmp *= 10; tmp += n; if (tmp > 255) goto enoent; } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch)); if (size-- == 0) goto emsgsize; *dst++ = (u_char) tmp; if (ch == '\0' || ch == '/') break; if (ch != '.') goto enoent; } /* Get the prefix length if any. */ bits = -1; if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ bits = 0; do { n = strchr(digits, ch) - digits; assert(n >= 0 && n <= 9); bits *= 10; bits += n; } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch)); if (ch != '\0') goto enoent; if (bits > 32) goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; /* Prefix length can default to /32 only if all four octets spec'd. */ if (bits == -1) { if (dst - odst == 4) bits = 32; else goto enoent; } /* If nothing was written to the destination, we found no address. */ if (dst == odst) goto enoent; /* If prefix length overspecifies mantissa, life is bad. */ if ((bits / 8) > (dst - odst)) goto enoent; /* Extend address to four octets. */ while (size-- > 0) *dst++ = 0; return bits; enoent: errno = ENOENT; return (-1); emsgsize: errno = EMSGSIZE; return (-1); } static int getbits(const char *src, int *bitsp) { static const char digits[] = "0123456789"; int n; int val; char ch; val = 0; n = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr(digits, ch); if (pch != NULL) { if (n++ != 0 && val == 0) /* no leading zeros */ return (0); val *= 10; val += (pch - digits); if (val > 128) /* range */ return (0); continue; } return (0); } if (n == 0) return (0); *bitsp = val; return (1); } static int getv4(const char *src, u_char *dst, int *bitsp) { static const char digits[] = "0123456789"; u_char *odst = dst; int n; u_int val; char ch; val = 0; n = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr(digits, ch); if (pch != NULL) { if (n++ != 0 && val == 0) /* no leading zeros */ return (0); val *= 10; val += (pch - digits); if (val > 255) /* range */ return (0); continue; } if (ch == '.' || ch == '/') { if (dst - odst > 3) /* too many octets? */ return (0); *dst++ = val; if (ch == '/') return (getbits(src, bitsp)); val = 0; n = 0; continue; } return (0); } if (n == 0) return (0); if (dst - odst > 3) /* too many octets? */ return (0); *dst++ = val; return (1); } static int inet_net_pton_ipv6(const char *src, u_char *dst) { return inet_cidr_pton_ipv6(src, dst, 16); } #define NS_IN6ADDRSZ 16 #define NS_INT16SZ 2 #define NS_INADDRSZ 4 static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; u_int val; int digits; int bits; if (size < NS_IN6ADDRSZ) goto emsgsize; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') goto enoent; curtok = src; saw_xdigit = 0; val = 0; digits = 0; bits = -1; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (++digits > 4) goto enoent; saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) goto enoent; colonp = tp; continue; } else if (*src == '\0') goto enoent; if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; saw_xdigit = 0; digits = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && getv4(curtok, tp, &bits) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } if (ch == '/' && getbits(src, &bits) > 0) break; goto enoent; } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) goto enoent; *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; } if (bits == -1) bits = 128; endp = tmp + 16; if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle overlapping * regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; if (tp == endp) goto enoent; for (i = 1; i <= n; i++) { endp[-i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) goto enoent; /* * Copy out the result. */ memcpy(dst, tmp, NS_IN6ADDRSZ); return (bits); enoent: errno = ENOENT; return (-1); emsgsize: errno = EMSGSIZE; return (-1); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWObjectDatabase_create_object.cpp0000644000175000017500000003265311733011756031467 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include #include #include #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/Group.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Library.h" #include "fwbuilder/Management.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/physAddress.h" #include #include using namespace std; using namespace libfwbuilder; static std::map create_methods; #define CREATE_OBJ_METHOD(classname) \ FWObject* libfwbuilder::create_##classname(int id) \ { \ classname *nobj = new classname(); \ if (id > -1) nobj->setId(id); \ return nobj; \ } \ \ classname * FWObjectDatabase::create##classname(int id) \ { \ classname * nobj = classname::cast(create_##classname(id)); \ addToIndex(nobj); \ nobj->init(this); \ return nobj; \ } void FWObjectDatabase::registerObjectType(const std::string &type_name, create_function_ptr create_function) { create_methods[type_name] = create_function; } void FWObjectDatabase::init_create_methods_table() { if (create_methods.size()==0) { registerObjectType("AddressRange", &create_AddressRange); registerObjectType("AddressTable", &create_AddressTable); registerObjectType("AttachedNetworks", &create_AttachedNetworks); registerObjectType("Cluster", &create_Cluster); registerObjectType("StateSyncClusterGroup", &create_StateSyncClusterGroup); registerObjectType("FailoverClusterGroup", &create_FailoverClusterGroup); registerObjectType("ClusterGroupOptions", &create_ClusterGroupOptions); registerObjectType("CustomService", &create_CustomService); registerObjectType("DNSName", &create_DNSName); registerObjectType("DynamicGroup", &create_DynamicGroup); registerObjectType("FWBDManagement", &create_FWBDManagement); registerObjectType("IntervalRef", &create_FWIntervalReference); registerObjectType("ObjectRef", &create_FWObjectReference); registerObjectType("ServiceRef", &create_FWServiceReference); registerObjectType("Firewall", &create_Firewall); registerObjectType("FirewallOptions", &create_FirewallOptions); registerObjectType("Host", &create_Host); registerObjectType("HostOptions", &create_HostOptions); registerObjectType("ICMP6Service", &create_ICMP6Service); registerObjectType("ICMPService", &create_ICMPService); registerObjectType("InterfaceOptions", &create_InterfaceOptions); registerObjectType("IPService", &create_IPService); registerObjectType("IPv4", &create_IPv4); registerObjectType("IPv6", &create_IPv6); registerObjectType("Interface", &create_Interface); registerObjectType("Interval", &create_Interval); registerObjectType("IntervalGroup", &create_IntervalGroup); registerObjectType("Library", &create_Library); registerObjectType("Management", &create_Management); registerObjectType("NAT", &create_NAT); registerObjectType("NATRule", &create_NATRule); registerObjectType("NATRuleOptions", &create_NATRuleOptions); registerObjectType("Network", &create_Network); registerObjectType("NetworkIPv6", &create_NetworkIPv6); registerObjectType("ObjectGroup", &create_ObjectGroup); registerObjectType("Policy", &create_Policy); registerObjectType("PolicyInstallScript", &create_PolicyInstallScript); registerObjectType("PolicyRule", &create_PolicyRule); registerObjectType("PolicyRuleOptions", &create_PolicyRuleOptions); registerObjectType("Routing", &create_Routing); registerObjectType("RoutingRule", &create_RoutingRule); registerObjectType("RoutingRuleOptions", &create_RoutingRuleOptions); registerObjectType("RuleSetOptions", &create_RuleSetOptions); registerObjectType("Dst", &create_RuleElementDst); registerObjectType("When", &create_RuleElementInterval); registerObjectType("Itf", &create_RuleElementItf); registerObjectType("ItfInb", &create_RuleElementItfInb); registerObjectType("ItfOutb", &create_RuleElementItfOutb); registerObjectType("ODst", &create_RuleElementODst); registerObjectType("OSrc", &create_RuleElementOSrc); registerObjectType("OSrv", &create_RuleElementOSrv); registerObjectType("RDst", &create_RuleElementRDst); registerObjectType("RGtw", &create_RuleElementRGtw); registerObjectType("RItf", &create_RuleElementRItf); registerObjectType("Src", &create_RuleElementSrc); registerObjectType("Srv", &create_RuleElementSrv); registerObjectType("TDst", &create_RuleElementTDst); registerObjectType("TSrc", &create_RuleElementTSrc); registerObjectType("TSrv", &create_RuleElementTSrv); registerObjectType("SNMPManagement", &create_SNMPManagement); registerObjectType("ServiceGroup", &create_ServiceGroup); registerObjectType("TCPService", &create_TCPService); registerObjectType("TagService", &create_TagService); registerObjectType("UDPService", &create_UDPService); registerObjectType("UserService", &create_UserService); registerObjectType("physAddress", &create_physAddress); registerObjectType("Group", &create_Group); } } FWObject *FWObjectDatabase::create(const string &type_name, int id, bool init) { create_function_ptr fn = create_methods[type_name]; if (fn == NULL) { const char *type_name_cptr = type_name.c_str(); FWObject *nobj; if (strcmp("comment", type_name_cptr)==SAME) return NULL; if (strcmp("SelectionCriteria", type_name_cptr) == 0) return 0; if (strcmp("AnyNetwork", type_name_cptr)==SAME) { nobj = new Network(); if (id > -1) nobj->setId(id); nobj->setXMLName("AnyNetwork"); addToIndex(nobj); return nobj; } if (strcmp("AnyIPService", type_name_cptr)==SAME) { nobj = new IPService(); if (id > -1) nobj->setId(id); nobj->setXMLName("AnyIPService"); addToIndex(nobj); return nobj; } if (strcmp("AnyInterval", type_name_cptr)==SAME) { nobj = new Interval(); if (id > -1) nobj->setId(id); nobj->setXMLName("AnyInterval"); addToIndex(nobj); return nobj; } cerr << "Do not have method to create object of type " << type_name << endl; return NULL; } FWObject *nobj = (*fn)(id); addToIndex(nobj); if (init) nobj->init(this); return nobj; } FWObject *FWObjectDatabase::createFromXML(xmlNodePtr data) { const char *n; string typen; int id = -1; n = FROMXMLCAST(data->name); if (!n) return NULL; typen = n; n = FROMXMLCAST(xmlGetProp(data, TOXMLCAST("id"))); if (n) { id = registerStringId(n); FREEXMLBUFF(n); } // create new object but do not prepopulate objects that // automatically create children in constructor return create(typen, id, false); } CREATE_OBJ_METHOD(AddressRange); CREATE_OBJ_METHOD(AddressTable); CREATE_OBJ_METHOD(AttachedNetworks); CREATE_OBJ_METHOD(Cluster); CREATE_OBJ_METHOD(StateSyncClusterGroup); CREATE_OBJ_METHOD(FailoverClusterGroup); CREATE_OBJ_METHOD(ClusterGroupOptions); CREATE_OBJ_METHOD(CustomService); CREATE_OBJ_METHOD(DNSName); CREATE_OBJ_METHOD(DynamicGroup); CREATE_OBJ_METHOD(FWBDManagement); CREATE_OBJ_METHOD(FWIntervalReference); CREATE_OBJ_METHOD(FWObjectReference); CREATE_OBJ_METHOD(FWServiceReference); CREATE_OBJ_METHOD(Firewall); CREATE_OBJ_METHOD(FirewallOptions); CREATE_OBJ_METHOD(InterfaceOptions); CREATE_OBJ_METHOD(Host); CREATE_OBJ_METHOD(HostOptions); CREATE_OBJ_METHOD(ICMP6Service); CREATE_OBJ_METHOD(ICMPService); CREATE_OBJ_METHOD(IPService); CREATE_OBJ_METHOD(IPv4); CREATE_OBJ_METHOD(IPv6); CREATE_OBJ_METHOD(Interface); CREATE_OBJ_METHOD(Interval); CREATE_OBJ_METHOD(IntervalGroup); CREATE_OBJ_METHOD(Library); CREATE_OBJ_METHOD(Management); CREATE_OBJ_METHOD(NAT); CREATE_OBJ_METHOD(NATRule); CREATE_OBJ_METHOD(NATRuleOptions); CREATE_OBJ_METHOD(Network); CREATE_OBJ_METHOD(NetworkIPv6); CREATE_OBJ_METHOD(ObjectGroup); CREATE_OBJ_METHOD(Policy); CREATE_OBJ_METHOD(PolicyInstallScript); CREATE_OBJ_METHOD(PolicyRule); CREATE_OBJ_METHOD(PolicyRuleOptions); CREATE_OBJ_METHOD(Routing); CREATE_OBJ_METHOD(RoutingRule); CREATE_OBJ_METHOD(RoutingRuleOptions); CREATE_OBJ_METHOD(RuleElementDst); CREATE_OBJ_METHOD(RuleElementInterval); CREATE_OBJ_METHOD(RuleElementItf); CREATE_OBJ_METHOD(RuleElementItfInb); CREATE_OBJ_METHOD(RuleElementItfOutb); CREATE_OBJ_METHOD(RuleElementODst); CREATE_OBJ_METHOD(RuleElementOSrc); CREATE_OBJ_METHOD(RuleElementOSrv); CREATE_OBJ_METHOD(RuleElementRDst); CREATE_OBJ_METHOD(RuleElementRGtw); CREATE_OBJ_METHOD(RuleElementRItf); CREATE_OBJ_METHOD(RuleElementSrc); CREATE_OBJ_METHOD(RuleElementSrv); CREATE_OBJ_METHOD(RuleElementTDst); CREATE_OBJ_METHOD(RuleElementTSrc); CREATE_OBJ_METHOD(RuleElementTSrv); CREATE_OBJ_METHOD(RuleSetOptions); CREATE_OBJ_METHOD(SNMPManagement); CREATE_OBJ_METHOD(ServiceGroup); CREATE_OBJ_METHOD(TCPService); CREATE_OBJ_METHOD(TagService); CREATE_OBJ_METHOD(UDPService); CREATE_OBJ_METHOD(UserService); CREATE_OBJ_METHOD(physAddress); CREATE_OBJ_METHOD(Group); fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Management.h0000644000175000017500000001160411733011756025240 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __MANAGEMENT_HH_FLAG__ #define __MANAGEMENT_HH_FLAG__ #include "fwbuilder/InetAddr.h" #include "fwbuilder/FWObject.h" namespace libfwbuilder { class PolicyInstallScript : public FWObject { public: PolicyInstallScript(); DECLARE_FWOBJECT_SUBTYPE(PolicyInstallScript); DECLARE_DISPATCH_METHODS(PolicyInstallScript); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual FWObject& shallowDuplicate( const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); const std::string& getCommand () const; void setCommand (const std::string& ); const std::string& getArguments() const; void setArguments(const std::string& ); bool isEmpty() const; bool isEnabled() const; void setEnabled(bool v); private: bool enabled; std::string command; std::string arguments; }; class SNMPManagement : public FWObject { public: SNMPManagement(); DECLARE_FWOBJECT_SUBTYPE(SNMPManagement); DECLARE_DISPATCH_METHODS(SNMPManagement); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual FWObject& shallowDuplicate( const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); const std::string& getReadCommunity () const; void setReadCommunity (const std::string& ); const std::string& getWriteCommunity() const; void setWriteCommunity(const std::string& ); bool isEmpty() const; bool isEnabled() const; void setEnabled(bool v); private: bool enabled; std::string read_community; std::string write_community; }; class FWBDManagement : public FWObject { public: FWBDManagement(); virtual ~FWBDManagement(); DECLARE_FWOBJECT_SUBTYPE(FWBDManagement); DECLARE_DISPATCH_METHODS(FWBDManagement); virtual FWObject& shallowDuplicate( const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); int getPort() const; void setPort(int); const std::string &getIdentityId() const; void setIdentityId(const std::string &); bool isEmpty() const; bool isEnabled() const; void setEnabled(bool v); private: bool enabled ; int port ; std::string identity_id ; }; class Management : public FWObject { public: Management(); DECLARE_FWOBJECT_SUBTYPE(Management); DECLARE_DISPATCH_METHODS(Management); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual FWObject& shallowDuplicate( const FWObject *obj, bool preserve_id = true) throw(FWException); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); virtual bool validateChild(FWObject *o); const InetAddr& getAddress() const { return addr; } void setAddress(const InetAddr& a) { addr = a; } PolicyInstallScript *getPolicyInstallScript(); SNMPManagement *getSNMPManagement(); FWBDManagement *getFWBDManagement(); bool isEmpty() const; private: InetAddr addr; }; } #endif //__MANAGEMENT_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ObjectMatcher.cpp0000644000175000017500000004156711733011756026244 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ==================================================================== Algorithms implemented in this module are used to decide if an object that defines one or several addresses matches firewall, its interface or any of its addresses in the sense that packets with address equal to that of would be accepted by the firewall machine. Two match modes are defined: EXACT and PARTIAL. The difference makes sense when object is an AddressRange because the range may match subnet of an interface exactly or overlap with it only partially. This class is used in policy compilers to determine chain (for iptables) or find interface that matches addresses used in policy or nat rules. */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/Group.h" #include #include using namespace libfwbuilder; using namespace std; /** * returns true if : * 1. obj1 is the same as obj2, or * 2. any child of obj2 or * 3. its address matches that of any obj2's interfaces, or * 4. its address matches broadcast address of one of the interfaces * 5. address of obj1 is a broadcast (255.255.255.255) * 6. address of obj1 is a multicast ( added 09/15/02, --vk ) * * This used double dispatch pattern: complexMatch calls virtual * method dispatchComplexMatch method of obj1, which in turn calls * appropriate variant of ObjectMatcher::checkComplexMatch method * depending on which class obj1 is an object of. */ bool ObjectMatcher::complexMatch(Address *obj1, Address *obj2) { if (obj1->getId()==obj2->getId()) return true; if (Cluster::cast(obj1) && Firewall::cast(obj2)) { // "parent_cluster_id" is set in CompilerDriver::populateClusterElements() // which unfortunately is part of fwbuilder rather than fwcompiler int cluster_id = obj2->getInt("parent_cluster_id"); if (obj1->getId() == cluster_id) return true; } void* res = obj1->dispatch(this, obj2); return (res != NULL); } /** * Compare single InetAddr to an address defined by Address * object. The right hand side Address object should be a "primary" * address object (i.e. IPv4, IPv6, Network, NetworkIPv6, AddressRange * but not Interface or Host). This method takes into account the * hierarcy of which rhs_obj is part. That is, it treats IPv4 which is * a child of interface differently from IPv4 which is a standalone * object. This method uses flag match_subnets to decide whether it * should consider only ip address of rhs_obj or a subnet defined by * its address and netmask. */ int ObjectMatcher::matchRHS(const InetAddr *inet_addr_obj, Address *rhs_obj) { const InetAddr *addr = rhs_obj->getAddressPtr(); const InetAddr *netm = rhs_obj->getNetmaskPtr(); if (match_subnets) { return matchSubnetRHS(inet_addr_obj, addr, netm); } else { if (matchInetAddrRHS(inet_addr_obj, addr) == 0) return 0; if (recognize_broadcasts) { /* * bug #1040773: need to match network address as well as * broadcast. Packets sent to the network address (192.168.1.0 for net * 192.168.1.0/24) go in the broadcast frame and behave just like IP * broadcast packets (sent to 192.168.1.1255 for the same net) * */ InetAddrMask n(*addr, *netm); int f1 = matchInetAddrRHS(inet_addr_obj, n.getNetworkAddressPtr()); int f2 = matchInetAddrRHS(inet_addr_obj, n.getBroadcastAddressPtr()); if (f1 == 0 || f2 == 0) return 0; if (f2 > 0) return 1; } return -1; } } /** * Match inet one address against another * Returns: * 0 if first address is equal to the secnd * -1 if first address is less than the secnd * 1 if first address is greater than the secnd */ int ObjectMatcher::matchInetAddrRHS(const InetAddr *inet_addr_obj, const InetAddr *rhs_obj_addr) { if ((*inet_addr_obj) == (*rhs_obj_addr)) return 0; if ((*inet_addr_obj) < (*rhs_obj_addr)) return -1; return 1; } /** * Match inet address against subnet defined by addr/mask pair. * Returns: * 0 if inet address belongs to the subnet, * -1 if inet address is less than the beginning of the subnet * 1 if inet address is greater than the end of the subnet */ int ObjectMatcher::matchSubnetRHS(const InetAddr *inet_addr_obj, const InetAddr *rhs_obj_addr, const InetAddr *rhs_obj_netm) { InetAddrMask n(*rhs_obj_addr, *rhs_obj_netm); int f1 = matchInetAddrRHS(inet_addr_obj, n.getNetworkAddressPtr()); int f2 = matchInetAddrRHS(inet_addr_obj, n.getBroadcastAddressPtr()); if (f1 >= 0 && f2 <= 0) return 0; if (f1 < 0) return -1; if (f2 > 0) return 1; return -1; } bool ObjectMatcher::checkComplexMatchForSingleAddress(const InetAddr *obj1_addr, FWObject *obj2) { if (!obj1_addr->isAny() && ( (recognize_broadcasts && obj1_addr->isBroadcast()) || (recognize_multicasts && obj1_addr->isMulticast()) ) ) return true; // case of "old boradcast" if (recognize_broadcasts && obj1_addr->isAny()) return true; string addr_type = (ipv6) ? IPv6::TYPENAME : IPv4::TYPENAME; list all_addresses; if (Host::cast(obj2)) { /* * note that compilers add copies of rules to the same firewall object * (temp_ruleset object) which means the tree rooted at the firewall * can be large, so searching for all interfaces using getByTypeDeep() * may cause scanning very large tree. */ list all_interfaces; Interface::findAllInterfaces(obj2, all_interfaces); for (list::iterator it = all_interfaces.begin(); it != all_interfaces.end(); ++it) { list intf_addresses = (*it)->getByTypeDeep(addr_type); all_addresses.splice(all_addresses.end(), intf_addresses); } } else { all_addresses = obj2->getByTypeDeep(addr_type); } for (list::iterator it = all_addresses.begin(); it != all_addresses.end(); ++it) { Address *rhs_addr = Address::cast(*it); const InetAddr *addr = rhs_addr->getAddressPtr(); if (match_subnets) { const InetAddr *netm = rhs_addr->getNetmaskPtr(); if (matchSubnetRHS(obj1_addr, addr, netm) == 0) return true; } else { if (matchRHS(obj1_addr, rhs_addr) == 0) return true; } } return false; } bool ObjectMatcher::checkComplexMatchForSingleAddress(Address *obj1, FWObject *obj2) { const InetAddr *obj1_addr = obj1->getAddressPtr(); // obj1_addr may be NULL if obj1 does not have any real address, // one case when this happens is when obj1 is physAddress if (obj1_addr) return checkComplexMatchForSingleAddress(obj1_addr, obj2); return false; } /** * check if any of the addresses of obj2 belongs to the subnet of obj1 */ bool ObjectMatcher::checkComplexMatchForSubnet(Address *obj1, FWObject *obj2) { //cerr << "ObjectMatcher::checkComplexMatchForSubnet obj1=" << obj1->getName() // << " obj2=" << obj2->getName(); const InetAddr *addr = obj1->getAddressPtr(); const InetAddr *netm = obj1->getNetmaskPtr(); bool res = false; string addr_type = (ipv6) ? IPv6::TYPENAME : IPv4::TYPENAME; list all_addresses = obj2->getByTypeDeep(addr_type); for (list::iterator it = all_addresses.begin(); it != all_addresses.end(); ++it) { Address *obj2_addr = Address::cast(*it); const InetAddr *rhs_addr = obj2_addr->getAddressPtr(); if (matchSubnetRHS(rhs_addr, addr, netm) == 0) { res = true; break; } } //cerr << " " << res << endl; return res; } void* ObjectMatcher::dispatch(Interface* obj1, void* _obj2) { FWObject *obj2 = (FWObject*)(_obj2); if (obj1->getParent()->getId() == obj2->getId()) return obj1; if (!obj1->isRegular()) return NULL; if ((obj1->getByType(IPv4::TYPENAME)).size()>1) return NULL; if ((obj1->getByType(IPv6::TYPENAME)).size()>1) return NULL; return (checkComplexMatchForSingleAddress(obj1, obj2)) ? obj1 : NULL; } void* ObjectMatcher::dispatch(Network *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); /* * bug #1055937: "Any->all_multicasts not in INPUT Chain" * Need to check for multicast networks. We assume they always * match if obj2 is firewall */ //Network *nobj1 = Network::cast(obj1); const InetAddr *inet_addr = obj1->getAddressPtr(); if (inet_addr) { if (recognize_multicasts && inet_addr->isMulticast() && Firewall::isA(obj2)) return obj1; /* * need to check for network object with mask 255.255.255.255 * Such objects are created by the method that expands address * ranges, and some often used ranges trigger that (like * "255.255.255.255-255.255.255.255" or "0.0.0.0-0.0.0.0") */ if (!obj1->getNetmaskPtr()->isHostMask()) return NULL; } else return NULL; return checkComplexMatchForSingleAddress(obj1, obj2) ? obj1 : NULL; } void* ObjectMatcher::dispatch(NetworkIPv6 *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); const InetAddr *inet_addr = obj1->getAddressPtr(); if (inet_addr) { if (recognize_multicasts && inet_addr->isMulticast() && Firewall::isA(obj2)) return obj1; if (!obj1->getNetmaskPtr()->isHostMask()) return NULL; } else return NULL; return checkComplexMatchForSingleAddress(obj1, obj2) ? obj1 : NULL; } void* ObjectMatcher::dispatch(IPv4 *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); return checkComplexMatchForSingleAddress(obj1, obj2) ? obj1 : NULL; } void* ObjectMatcher::dispatch(IPv6 *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); return checkComplexMatchForSingleAddress(obj1, obj2) ? obj1 : NULL; } void* ObjectMatcher::dispatch(physAddress *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); list all_pa = obj2->getByTypeDeep(physAddress::TYPENAME); for (list::iterator i = all_pa.begin(); i != all_pa.end(); ++i) { physAddress *iface_pa = physAddress::cast(*i); if (obj1->getPhysAddress() == iface_pa->getPhysAddress()) return obj1; } return NULL; } void* ObjectMatcher::dispatch(AddressRange *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); const InetAddr &range_start = obj1->getRangeStart(); const InetAddr &range_end = obj1->getRangeEnd(); if (!range_start.isAny() && ( (recognize_broadcasts && range_start.isBroadcast()) || (recognize_multicasts && range_start.isMulticast()) ) ) return obj1; if (!range_end.isAny() && ( (recognize_broadcasts && range_end.isBroadcast()) || (recognize_multicasts && range_end.isMulticast()) ) ) return obj1; // case of "old boradcast" if (recognize_broadcasts && range_start == range_end && range_start.isAny()) return obj1; string addr_type = (ipv6) ? IPv6::TYPENAME : IPv4::TYPENAME; list all_addresses = obj2->getByTypeDeep(addr_type); for (list::iterator it = all_addresses.begin(); it != all_addresses.end(); ++it) { Address *rhs_addr = Address::cast(*it); const InetAddr *addr = rhs_addr->getAddressPtr(); if (match_subnets) { const InetAddr *netm = rhs_addr->getNetmaskPtr(); int f_b = matchSubnetRHS(&range_start, addr, netm); int f_e = matchSubnetRHS(&range_end, addr, netm); #if 0 cerr << "Address Range " << range_start.toString() << ":" << range_end.toString() << " rhs_addr " << rhs_addr->getName() << " " << addr->toString() << "/" << netm->toString() << " f_b=" << f_b << " f_e=" << f_e << " match_mode=" << address_range_match_mode << endl; #endif if (address_range_match_mode == EXACT) { if (f_b == 0 && f_e == 0) return obj1; } // PARTIAL match only makes sense when match_subnets is true if (address_range_match_mode == PARTIAL) { if (f_b == 0 || f_e == 0) return obj1; // one end of the range is inside subnet if (f_b == -1 && f_e == 1) return obj1; // range is wider than subnet, subnet fits inside the range completely } } else { // If we do not need to match subnets, we just look if address // @addr is inside the range int f_b = matchInetAddrRHS(&range_start, addr); int f_e = matchInetAddrRHS(&range_end, addr); #if 0 cerr << "Address Range " << range_start.toString() << ":" << range_end.toString() << " rhs_addr " << rhs_addr->getName() << " " << addr->toString() << " f_b=" << f_b << " f_e=" << f_e << " match_mode=" << address_range_match_mode << endl; #endif if (f_b <= 0 && f_e >= 0) return obj1; } } return NULL; bool f_b = checkComplexMatchForSingleAddress(&range_start, obj2); bool f_e = checkComplexMatchForSingleAddress(&range_end, obj2); if (address_range_match_mode == EXACT && f_b && f_e) return obj1; if (address_range_match_mode == PARTIAL && (f_b || f_e)) return obj1; return NULL; } /* * Special case: run-time DNSName object with source name "self" * matches firewall. */ void* ObjectMatcher::dispatch(MultiAddressRunTime *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); if (obj1->getSubstitutionTypeName() == DNSName::TYPENAME && obj1->getSourceName() == "self" && Firewall::isA(obj2)) return obj1; return NULL; // never matches in this implementation } void* ObjectMatcher::dispatch(Host *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); /* * match only if all interfaces of obj1 match obj2 */ bool res = true; list all_interfaces; Interface::findAllInterfaces(obj1, all_interfaces); for (list::iterator it = all_interfaces.begin(); it != all_interfaces.end(); ++it) { res &= checkComplexMatchForSingleAddress(Interface::cast(*it), obj2); } return res ? obj1 : NULL; } void* ObjectMatcher::dispatch(Firewall *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); if (obj1->getId() == obj2->getId()) return obj1; /* * Special case: run-time DNSName object with source name "self" * matches firewall. */ MultiAddressRunTime *mart = MultiAddressRunTime::cast(obj2); if (mart) { if (mart->getSubstitutionTypeName() == DNSName::TYPENAME && mart->getSourceName() == "self") return obj1; } /* * match only if all interfaces of obj1 match obj2 */ return dispatch(static_cast(obj1), obj2); } void* ObjectMatcher::dispatch(Cluster *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); if (obj1->getId() == obj2->getId()) return obj1; list members; obj1->getMembersList(members); list::iterator it; for (it=members.begin(); it!=members.end(); ++it) { if (dispatch(*it, obj2) != NULL) return obj1; } /* * match only if all interfaces of obj1 match obj2 */ return dispatch(static_cast(obj1), obj2); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWException.cpp0000644000175000017500000000230211733011756025705 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWException.h" using namespace std; using namespace libfwbuilder; FWException::FWException(const string &r) { reason = r; } const string &FWException::toString() const { return reason; } map& FWException::getProperties() { return properties; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Logger.cpp0000644000175000017500000000774111733011756024745 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include #ifndef _WIN32 #include #endif #include #include #include #include "fwbuilder/BackgroundOp.h" using namespace std; using namespace libfwbuilder; /* Logger &libfwbuilder::start(Logger &l) { l.line_lock.lock(); return l; } Logger &libfwbuilder::end(Logger &l) { l.line_lock.unlock(); return l; } */ void Logger::blackhole() { line_lock.lock(); blackhole_mode = true; copy_to_stderr = false; line_lock.unlock(); } Logger& NullLogger::operator<< (char ) { return *this;} Logger& NullLogger::operator<< (char*) { return *this;} Logger& NullLogger::operator<< (const char*) { return *this;} Logger& NullLogger::operator<< (const string&) { return *this;} Logger& NullLogger::operator<< (int) { return *this;} Logger& NullLogger::operator<< (long) { return *this;} Logger& NullLogger::operator<< (std::ostringstream&) { return *this;} QueueLogger::QueueLogger() {} Logger& QueueLogger::operator<< (char c) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << c; std::ostringstream str; str << c; *this << str; return *this; } Logger& QueueLogger::operator<< (char *str) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << str; line_lock.lock(); linequeue.push(str); line_lock.unlock(); return *this; } Logger& QueueLogger::operator<< (const char *str) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << str; line_lock.lock(); linequeue.push(str); line_lock.unlock(); return *this; } Logger& QueueLogger::operator<< (const string &str) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << str; line_lock.lock(); linequeue.push(str); line_lock.unlock(); return *this; } Logger& QueueLogger::operator<< (int i ) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << i; std::ostringstream str; str << i; *this << str; return *this; } Logger& QueueLogger::operator<< (long l ) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << l; std::ostringstream str; str << l; *this << str; return *this; } Logger& QueueLogger::operator<< (std::ostringstream &sstr) { if (blackhole_mode) return *this; if (copy_to_stderr) cerr << sstr.str(); line_lock.lock(); linequeue.push(sstr.str()); line_lock.unlock(); sstr.str(""); // purge stream contents return *this; } bool QueueLogger::ready() { if (blackhole_mode) return false; bool res=false; line_lock.lock(); res=(!linequeue.empty()); line_lock.unlock(); return res; } string QueueLogger::getLine() { if (blackhole_mode) return ""; string str; line_lock.lock(); if(!linequeue.empty()) { str=linequeue.front(); linequeue.pop(); } line_lock.unlock(); return str; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ObjectMirror.h0000644000175000017500000000455711733011756025576 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: ObjectMirror.h 534 2010-02-07 23:25:06Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTMIRROR_HH_FLAG__ #define __OBJECTMIRROR_HH_FLAG__ #include #include #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Dispatch.h" namespace libfwbuilder { class ObjectMirror : public Dispatch { public: ObjectMirror() : Dispatch() { } /** * Creates "mirrored" object (currently only * service). Mirroring means swapping source and destination * port ranges for tcp and udp and picking appropriate ICMP * type for some known ICMP services. The object it returns is * not added to the tree, caller must do this in order to * avoid memory leaks and to be able to use the object later. * * Note: mirroring of actual rules requires knowledge of the * firewall platform specifics, such as what set of rule * elements is supported and their semantics (e.g. is time * supported ? If yes, then what does it mean to mirror the * rule with time match?). So it is not done here to avoid * dependency on the platform. This class focuses only on * mirroring of individual objects. */ Service* getMirroredService(Service *obj); virtual void* dispatch(IPService*, void*); virtual void* dispatch(ICMPService*, void*); virtual void* dispatch(ICMP6Service*, void*); virtual void* dispatch(UDPService*, void*); virtual void* dispatch(TCPService*, void*); }; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Logger.h0000644000175000017500000000567311733011756024414 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LOGGER_HH_FLAG__ #define __LOGGER_HH_FLAG__ #include #include "fwbuilder/FWException.h" #include "fwbuilder/Tools.h" #include "fwbuilder/ThreadTools.h" namespace libfwbuilder { class Logger { protected: Mutex line_lock; bool blackhole_mode; bool copy_to_stderr; public: Logger() { blackhole_mode=false; copy_to_stderr=false; } virtual ~Logger() {}; virtual Logger& operator<< (char c) = 0; virtual Logger& operator<< (char *str) = 0; virtual Logger& operator<< (const char *str) = 0; virtual Logger& operator<< (const std::string &str) = 0; virtual Logger& operator<< (int i ) = 0; virtual Logger& operator<< (long l ) = 0; virtual Logger& operator<< (std::ostringstream &sstr) = 0; // Manipulator virtual Logger& operator<< (Logger&(*f)(Logger &l)) { return f(*this); } virtual bool ready() { return true; } virtual std::string getLine() { return std::string(""); } void blackhole(); void copyToStderr() { copy_to_stderr=true; } }; class NullLogger:public Logger { public: virtual Logger& operator<< (char c) ; virtual Logger& operator<< (char *str) ; virtual Logger& operator<< (const char *str) ; virtual Logger& operator<< (const std::string &str) ; virtual Logger& operator<< (int i ) ; virtual Logger& operator<< (long l ) ; virtual Logger& operator<< (std::ostringstream &sstr); }; class QueueLogger:public Logger { private: std::queue linequeue; public: QueueLogger(); virtual Logger& operator<< (char c) ; virtual Logger& operator<< (char *str) ; virtual Logger& operator<< (const char *str) ; virtual Logger& operator<< (const std::string &str) ; virtual Logger& operator<< (int i ) ; virtual Logger& operator<< (long l ) ; virtual Logger& operator<< (std::ostringstream &sstr); virtual bool ready(); virtual std::string getLine(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWOptions.h0000644000175000017500000000542211733011756025055 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOPTINS_HH_FLAG__ #define __FWOPTINS_HH_FLAG__ #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWObject.h" namespace libfwbuilder { class FWOptions : public FWObject { public: FWOptions(); DECLARE_FWOBJECT_SUBTYPE(FWOptions); DECLARE_DISPATCH_METHODS(FWOptions); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class HostOptions : public FWOptions { public: HostOptions(); DECLARE_FWOBJECT_SUBTYPE(HostOptions); DECLARE_DISPATCH_METHODS(HostOptions); }; class FirewallOptions : public FWOptions { public: FirewallOptions(); DECLARE_FWOBJECT_SUBTYPE(FirewallOptions); DECLARE_DISPATCH_METHODS(FirewallOptions); }; class InterfaceOptions : public FWOptions { public: InterfaceOptions(); DECLARE_FWOBJECT_SUBTYPE(InterfaceOptions); DECLARE_DISPATCH_METHODS(InterfaceOptions); }; class RuleSetOptions : public FWOptions { public: RuleSetOptions(); DECLARE_FWOBJECT_SUBTYPE(RuleSetOptions); DECLARE_DISPATCH_METHODS(RuleSetOptions); }; class PolicyRuleOptions : public FWOptions { public: PolicyRuleOptions(); DECLARE_FWOBJECT_SUBTYPE(PolicyRuleOptions); DECLARE_DISPATCH_METHODS(PolicyRuleOptions); }; class NATRuleOptions : public FWOptions { public: NATRuleOptions(); DECLARE_FWOBJECT_SUBTYPE(NATRuleOptions); DECLARE_DISPATCH_METHODS(NATRuleOptions); }; class RoutingRuleOptions : public FWOptions { public: RoutingRuleOptions(); DECLARE_FWOBJECT_SUBTYPE(RoutingRuleOptions); DECLARE_DISPATCH_METHODS(RoutingRuleOptions); }; class ClusterGroupOptions : public FWOptions { public: ClusterGroupOptions(); DECLARE_FWOBJECT_SUBTYPE(ClusterGroupOptions); DECLARE_DISPATCH_METHODS(ClusterGroupOptions); }; } #endif // __FWOPTINS_HH_FLAG fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/uint128.h0000644000175000017500000003213011733011756024373 0ustar sylvestresylvestre/* * Copyright (c) 2008 * Evan Teran * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * copyright notice and this permission notice appear in supporting * documentation, and that the same name not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. We make no representations about the * suitability this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * Commented out the line that #includes * and ran through astyle: * astyle --style=ansi --indent=spaces --convert-tabs uint128.h * * --vk 11/16/2010 */ #ifndef UINT128_20050119_H_ #define UINT128_20050119_H_ #include #include #include // #include #include #include #include #include // #define __STDC_FORMAT_MACROS #include // for sprintf formats for "long long" // convinience macro #define U128_C(s) uint128(#s) class uint128 { public: typedef uint64_t base_type; typedef uint128 Self; public: static const int size = (sizeof(base_type) + sizeof(base_type)) * CHAR_BIT; private: base_type lo; base_type hi; public: uint128(base_type _lo, base_type _hi) : lo(_lo), hi(_hi) {} // constructors for all basic types uint128() : lo(0), hi(0) {} uint128(int value) : lo(static_cast(value)), hi(0) { if (value < 0) hi = static_cast(-1); } uint128(unsigned int value) : lo(static_cast(value)), hi(0) {} uint128(float value) : lo(static_cast(value)), hi(0) {} uint128(double value) : lo(static_cast(value)), hi(0) {} uint128(const Self &value) : lo(value.lo), hi (value.hi) {} uint128(base_type value) : lo(value), hi(0) {} uint128(const uint32_t value[4]): lo((uint64_t(value[2])<<32)|value[3]),hi((uint64_t(value[0])<<32)|value[1]) {} uint128(const std::string &sz) : lo(0), hi(0) { // do we have at least one character? if (!sz.empty()) { // make some reasonable assumptions int radix = 10; bool minus = false; std::string::const_iterator i = sz.begin(); // check for minus sign, i suppose technically this should only apply // to base 10, but who says that -0x1 should be invalid? if (*i == '-') { ++i; minus = true; } // check if there is radix changing prefix (0 or 0x) if (i != sz.end()) { if (*i == '0') { radix = 8; ++i; if (i != sz.end()) { if (*i == 'x') { radix = 16; ++i; } } } while (i != sz.end()) { unsigned int n; const char ch = *i; if (ch >= 'A' && ch <= 'Z') { if (((ch - 'A') + 10) < radix) { n = (ch - 'A') + 10; } else { break; } } else if (ch >= 'a' && ch <= 'z') { if (((ch - 'a') + 10) < radix) { n = (ch - 'a') + 10; } else { break; } } else if (ch >= '0' && ch <= '9') { if ((ch - '0') < radix) { n = (ch - '0'); } else { break; } } else { /* completely invalid character */ break; } (*this) *= radix; (*this) += n; ++i; } } // if this was a negative number, do that two's compliment madness :-P if (minus) { *this = -*this; } } } Self &operator=(const Self &other) { if (&other != this) { lo = other.lo; hi = other.hi; } return *this; } public: // comparison operators bool operator==(const Self &o) const { return hi == o.hi && lo == o.lo; } bool operator!=(const Self &o) const { return hi != o.hi || lo != o.lo; } bool operator<(const Self &o) const { return (hi == o.hi) ? lo < o.lo : hi < o.hi; } bool operator>(const Self &o) const { return (hi == o.hi) ? lo > o.lo : hi > o.hi; } bool operator<=(const Self &o) const { return *this < o || *this == 0; } bool operator>=(const Self &o) const { return *this > o || *this == 0; } public: // unary operators bool operator!() const { return !(hi != 0 || lo != 0); } Self operator-() const { // standard 2's compliment negation return ~Self(*this) + 1; } Self operator~() const { Self t(*this); t.lo = ~t.lo; t.hi = ~t.hi; return t; } Self &operator++() { if (++lo == 0) { ++hi; } return *this; } Self &operator--() { if (lo-- == 0) { --hi; } return *this; } public: // basic math operators Self &operator+=(const Self &b) { const base_type old_lo = lo; lo += b.lo; hi += b.hi; if (lo < old_lo) { ++hi; } return *this; } Self &operator-=(const Self &b) { // it happens to be way easier to write it // this way instead of make a subtraction algorithm return *this += -b; } Self &operator*=(const Self &b) { // check for multiply by 0 // result is always 0 :-P if (b == 0) { hi = 0; lo = 0; } else if (b != 1) { // check we aren't multiplying by 1 Self a(*this); Self t = b; lo = 0; hi = 0; for (int i = 0; i < size; ++i) { if ((t & 1) != 0) { *this += (a << i); } t >>= 1; } } return *this; } Self &operator|=(const Self &b) { hi |= b.hi; lo |= b.lo; return *this; } Self &operator&=(const Self &b) { hi &= b.hi; lo &= b.lo; return *this; } Self &operator^=(const Self &b) { hi ^= b.hi; lo ^= b.lo; return *this; } Self &operator/=(const Self &b) { Self remainder; __do_div(*this, b, *this, remainder); return *this; } Self &operator%=(const Self &b) { Self quotient; __do_div(*this, b, quotient, *this); return *this; } Self &operator<<=(const Self& rhs) { int n = rhs.to_integer(); if (n >= size) { hi = 0; lo = 0; } else { const int halfsize = size / 2; if (n >= halfsize) { n -= halfsize; hi = lo; lo = 0; } if (n != 0) { // shift high half hi <<= n; const base_type mask(~(base_type(-1) >> n)); // and add them to high half hi |= (lo & mask) >> (halfsize - n); // and finally shift also low half lo <<= n; } } return *this; } Self &operator>>=(const Self& rhs) { int n = rhs.to_integer(); if (n >= size) { hi = 0; lo = 0; } else { const int halfsize = size / 2; if (n >= halfsize) { n -= halfsize; lo = hi; hi = 0; } if (n != 0) { // shift low half lo >>= n; // get lower N bits of high half const base_type mask(~(base_type(-1) << n)); // and add them to low qword lo |= (hi & mask) << (halfsize - n); // and finally shift also high half hi >>= n; } } return *this; } Self operator+(const int &u) { Self temp(*this); temp += u; return temp; } Self operator&(const int &u) { Self temp(*this); temp &= u; return temp; } Self operator<<(const int &u) { Self temp(*this); temp <<= u; return temp; } Self operator>>(const int &u) { Self temp(*this); temp >>= u; return temp; } public: int to_integer() const { return static_cast(lo); } base_type to_base_type() const { return lo; } std::string to_string() const { char buf[33]; if (hi) sprintf(buf, "%"PRIX64"%08"PRIX64, (unsigned long long)hi,(unsigned long long)lo); else sprintf(buf,"%"PRIX64,(unsigned long long)lo); return buf; } private: template static void __do_div(const T &numerator, const T &denominator, T "ient, T &remainder) { static const int bits = sizeof(T) * CHAR_BIT; if (denominator == 0) { throw std::domain_error("divide by zero"); } else { T n = numerator; T d = denominator; T x = 1; T answer = 0; while ((n >= d) && (((d >> (bits - 1)) & 1) == 0)) { x <<= 1; d <<= 1; } while (x != 0) { if (n >= d) { n -= d; answer |= x; } x >>= 1; d >>= 1; } quotient = answer; remainder = n; } } }; std::ostream &operator<<(std::ostream &o, const uint128 &n); typedef uint128 uint128_t; namespace std { template<> struct numeric_limits { static const bool is_specialized = true; // static uint128 min() throw() // { // return 0; // } // // static uint128 max() throw() // { // return uint128( // std::numeric_limits::max(), // std::numeric_limits::max() // ); // } static const bool is_signed = false; static const bool is_integer = true; static const bool is_exact = true; static const int digits = 128; static const int digits10 = 39; static const int radix = 2; static uint128 epsilon() throw() { return 0; } static uint128 round_error() throw() { return 0; } static const int min_exponent = 0; static const int min_exponent10 = 0; static const int max_exponent = 0; static const int max_exponent10 = 0; static const bool has_infinity = false; static const bool has_quiet_NaN = false; static const bool has_signaling_NaN = false; static const float_denorm_style has_denorm = denorm_absent; static const bool has_denorm_loss = false; static uint128 infinity() throw() { return static_cast(0); } static uint128 quiet_NaN() throw() { return static_cast(0); } static uint128 signaling_NaN() throw() { return static_cast(0); } static uint128 denorm_min() throw() { return static_cast(0); } static const bool is_iec559 = false; static const bool is_bounded = true; static const bool is_modulo = true; static const bool traps = false; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/InterfaceData.cpp0000644000175000017500000000660711733011756026220 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "InterfaceData.h" #include "fwbuilder/Resources.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include using namespace libfwbuilder; using namespace std; InterfaceData::InterfaceData() : addr_mask() { ext = false; isDyn = false; isUnnumbered = false; isBridgePort = false; securityLevel = 0; snmp_type = 0; ostatus = 0; } InterfaceData::InterfaceData(const InterfaceData& other) : addr_mask() { id = other.id; name = other.name; label = other.label; if (other.addr_mask.size()) { for (list::const_iterator i=other.addr_mask.begin(); i!=other.addr_mask.end(); ++i) { InetAddrMask *am; const InetAddr *ad = (*i)->getAddressPtr(); const InetAddr *nm = (*i)->getNetmaskPtr(); if (ad==NULL) continue; if (ad->isV6()) { am = new Inet6AddrMask(); am->setAddress(*(ad)); am->setNetmask(*(nm)); } else am = new InetAddrMask(*(*i)); addr_mask.push_back(am); } } ext = other.ext; isDyn = other.isDyn; isUnnumbered = other.isUnnumbered; isBridgePort = other.isBridgePort; securityLevel = other.securityLevel; mac_addr = other.mac_addr; snmp_type = other.snmp_type; ostatus = other.ostatus; } InterfaceData::InterfaceData(const Interface &iface) : addr_mask() { id = iface.getId(); name = iface.getName(); IPv4 *addr = IPv4::cast(iface.getFirstByType(IPv4::TYPENAME)); if (addr) { addr_mask.push_back(new InetAddrMask(*(addr->getAddressPtr()), *(addr->getNetmaskPtr()))); } IPv6 *addr6 = IPv6::cast(iface.getFirstByType(IPv6::TYPENAME)); if (addr6) { addr_mask.push_back(new Inet6AddrMask(*(addr6->getAddressPtr()), *(addr6->getNetmaskPtr()))); } securityLevel = iface.getSecurityLevel(); isDyn = iface.isDyn(); isUnnumbered = iface.isUnnumbered(); isBridgePort = iface.isBridgePort(); libfwbuilder::physAddress *pa = iface.getPhysicalAddress(); if (pa!=NULL) mac_addr = pa->getPhysAddress(); label = iface.getLabel(); networkZone = iface.getStr("network_zone"); } InterfaceData::~InterfaceData() { // TODO: memory leak! need to delete items in the list addr_mask. addr_mask.clear(); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/NetworkIPv6.cpp0000644000175000017500000000773011733011756025662 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Inet6AddrMask.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/XMLTools.h" #include #include #include using namespace libfwbuilder; using namespace std; const char *NetworkIPv6::TYPENAME={"NetworkIPv6"}; NetworkIPv6::NetworkIPv6() : Address() { delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask(); setNetmask(InetAddr(AF_INET6, 64)); } NetworkIPv6::NetworkIPv6(NetworkIPv6 &other) : Address(other) { delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask( *(dynamic_cast(other.inet_addr_mask))); FWObject::operator=(other); } NetworkIPv6::NetworkIPv6 (const string &s) : Address() { setAddressNetmask(s); } NetworkIPv6::~NetworkIPv6() {} FWObject& NetworkIPv6::shallowDuplicate(const FWObject *other, bool preserve_id) throw(FWException) { const NetworkIPv6* a_other = NetworkIPv6::constcast(other); delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask( *(dynamic_cast(a_other->inet_addr_mask))); return FWObject::shallowDuplicate(other, preserve_id); } void NetworkIPv6::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("address"))); assert(n!=NULL); setAddress(InetAddr(AF_INET6, n)); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("netmask"))); assert(n!=NULL); if (strlen(n)) { if (string(n).find(":")!=string::npos) { setNetmask(InetAddr(AF_INET6, n)); } else { istringstream str(n); int netm; str >> netm; setNetmask(InetAddr(AF_INET6, netm)); } } else setNetmask(InetAddr(AF_INET6, 0)); FREEXMLBUFF(n); } xmlNodePtr NetworkIPv6::toXML(xmlNodePtr xml_parent_node) throw(FWException) { if (getName().empty()) setName(getTypeName()); xmlNodePtr me = FWObject::toXML(xml_parent_node); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); xmlNewProp(me, TOXMLCAST("address"), STRTOXMLCAST(inet_addr_mask->getAddressPtr()->toString())); // Save netmask as bit length ostringstream str; str << inet_addr_mask->getNetmaskPtr()->getLength(); xmlNewProp(me, TOXMLCAST("netmask"), STRTOXMLCAST(str.str())); return me; } /* check if host address bits are cleared */ bool NetworkIPv6::isValidRoutingNet() const { return (*(getAddressPtr()) == *(getNetworkAddressPtr())); } void NetworkIPv6::setAddress(const InetAddr &a) { inet_addr_mask->setAddress(a); } void NetworkIPv6::setNetmask(const InetAddr &nm) { inet_addr_mask->setNetmask(nm); } void NetworkIPv6::setAddressNetmask(const std::string& s) { delete inet_addr_mask; inet_addr_mask = new Inet6AddrMask(s); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Cluster.h0000644000175000017500000000611511733011756024606 0ustar sylvestresylvestre/* * Cluster.h - Cluster class header file * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __CLUSTER_HH__ #define __CLUSTER_HH__ #include "fwbuilder/Firewall.h" namespace libfwbuilder { class Policy; class NAT; class RuleSet; class Routing; class ClusterGroup; class Cluster : public Firewall { public: Cluster(); virtual ~Cluster() {}; /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(Cluster); DECLARE_DISPATCH_METHODS(Cluster); /** * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); virtual FWOptions* getOptionsObject(); virtual FWObject& duplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); Policy* getPolicy(); NAT* getNAT(); Routing* getRouting(); /** * return attached cluster group members object that * supports state synchronization (e.g. conntrackd). * * if the object is not found, a new one is created. * * @return assigned cluster group members object */ virtual ClusterGroup* getStateSyncGroupObject(); /** * Build a list of member firewalls. This method scans all * failover groups as well as state sync groups of the * cluster. Upon return, each firewall object appears in the * list exactly once. */ virtual void getMembersList(std::list &members); /** * Check validity of a given member. This is where we * implement logic to check if host OS of the cluster and * members is the same and possibly other criteria. */ virtual bool validateMember(libfwbuilder::Firewall*); /** * check if @fw is a member of this cluster. */ bool hasMember(libfwbuilder::Firewall *fw); time_t getLastModified(); time_t getLastInstalled(); time_t getLastCompiled(); void updateLastInstalledTimestamp(); void updateLastModifiedTimestamp(); void updateLastCompiledTimestamp(); bool needsInstall(); bool needsCompile(); bool getInactive(); void setInactive(bool b); }; } #endif /* __CLUSTER_HH__ */ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Service.h0000644000175000017500000000356011733011756024566 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Zaliva $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GEN_SERVICE_HH_FLAG__ #define __GEN_SERVICE_HH_FLAG__ #include "fwbuilder/FWObject.h" namespace libfwbuilder { /** * This is base class for all service objects and other objects that * can be children of RuleElementSrv (service rule element). It is * never used on it's own, only it's subclasses are used. * * TODO: we might need to derive ServiceGroup from Service, but this * requires lot more testing */ class Service : public FWObject { private: public: DECLARE_FWOBJECT_SUBTYPE(Service); DECLARE_DISPATCH_METHODS(Service); Service() {} virtual FWReference* createRef(); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; bool isAny() const; virtual bool isPrimaryObject() const { return true; } // All service objects except for ICMPService, ICMP6Service and // CustomService can be used in both ipv4 and ipv6 contexts. virtual bool isV4Only() { return false; } virtual bool isV6Only() { return false; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/dns.cpp0000644000175000017500000001161311733011756024303 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #ifndef _WIN32 # include # include # include # include # include # include # include # include # include # include # include # include #else # include #endif #include #include #include #include #include #include "fwbuilder/dns.h" #include "fwbuilder/ThreadTools.h" using namespace std; using namespace libfwbuilder; #undef DEBUG_DNS Mutex *DNS::gethostbyname_mutex = NULL; Mutex *DNS::gethostbyaddr_mutex = NULL; // use this function for delayed initialization void DNS::init() { if (gethostbyname_mutex==NULL) gethostbyname_mutex = new Mutex(); if (gethostbyaddr_mutex==NULL) gethostbyaddr_mutex = new Mutex(); } /* * gethostbyaddr and gethostbyname return pointers to a static structure. * Since this is not thread safe, need to use mutex to protect calls to * these functions. */ HostEnt DNS::getHostByAddr(const InetAddr &addr, int type) throw(FWException) { DNS::init(); struct hostent *hp; size_t hstbuflen = 1024; char *tmphstbuf = (char *)malloc(hstbuflen); gethostbyaddr_mutex->lock(); if (type==AF_INET) { hp = gethostbyaddr((const char *)addr.getV4(), sizeof(struct in_addr), type); } else { hp = gethostbyaddr((const char *)addr.getV6(), sizeof(struct in_addr), type); } if(hp==NULL) { gethostbyaddr_mutex->unlock(); free(tmphstbuf); throw FWException(string("Hostname of address: '") + addr.toString() + "' not found"); } HostEnt v; v.name = hp->h_name; if (hp->h_aliases) for(char **p = hp->h_aliases; *p; p++) v.aliases.insert(string(*p)); free(tmphstbuf); gethostbyaddr_mutex->unlock(); return v; } list DNS::getHostByName(const string &name, int type) throw(FWException) { DNS::init(); list v; struct addrinfo *aiList = NULL; int retVal; #ifdef DEBUG_DNS cerr << "DNS::getHostByName " << name << " type=" << type << endl; #endif if ((retVal = getaddrinfo(name.c_str(), NULL, NULL, &aiList)) != 0) { std::ostringstream strerr; strerr << "Host or network '" + name + "' not found; last error: "; #ifdef _WIN32 strerr << WSAGetLastError(); #else strerr << gai_strerror(errno); #endif throw FWException(strerr.str()); } struct addrinfo *ai; try { for (ai=aiList; ai!=NULL; ai=ai->ai_next) { #ifdef DEBUG_DNS cerr << "DNS::getHostByName " << name << " returned address type=" << ai->ai_family << endl; #endif if (ai->ai_family!=type) continue; switch (ai->ai_family) { case AF_INET: { struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; InetAddr addr((struct in_addr *)(&(sa->sin_addr))); v.push_back(addr); #ifdef DEBUG_DNS cerr << "DNS::getHostByName " << name << " ipv4 address=" << addr.toString() << endl; #endif } break; case AF_INET6: { struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; InetAddr addr((struct in6_addr *)(&(sa->sin6_addr))); v.push_back(addr); #ifdef DEBUG_DNS cerr << "DNS::getHostByName " << name << " ipv6 address=" << addr.toString() << endl; #endif } break; } } } catch(const FWException &e) { freeaddrinfo(aiList); throw e; } freeaddrinfo(aiList); v.sort(); v.unique(); return v; } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Policy.h0000644000175000017500000000345511733011756024430 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICY_HH_FLAG__ #define __POLICY_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/RuleSet.h" namespace libfwbuilder { class Policy : public RuleSet { public: Policy(); virtual ~Policy(); DECLARE_FWOBJECT_SUBTYPE(Policy); DECLARE_DISPATCH_METHODS(Policy); /* the following methods provide proper typization */ PolicyRule* getRuleByNum(int n) { return PolicyRule::cast(RuleSet::getRuleByNum(n)); } PolicyRule* insertRuleAtTop() { return PolicyRule::cast(RuleSet::insertRuleAtTop()); } PolicyRule* insertRuleBefore(int n){ return PolicyRule::cast(RuleSet::insertRuleBefore(n)); } PolicyRule* appendRuleAfter(int n){ return PolicyRule::cast(RuleSet::appendRuleAfter(n)); } PolicyRule* appendRuleAtBottom(){ return PolicyRule::cast(RuleSet::appendRuleAtBottom()); } virtual Rule* createRule(); }; } #endif //__POLICY_HH_FLAG__ fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/ICMPService.h0000644000175000017500000000276111733011756025241 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ICMPSERVICE_HH_FLAG__ #define __ICMPSERVICE_HH_FLAG__ #include "fwbuilder/Service.h" namespace libfwbuilder { class ICMPService : public Service { private: public: ICMPService(); virtual ~ICMPService(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(ICMPService); DECLARE_DISPATCH_METHODS(ICMPService); virtual std::string getProtocolName() const; virtual int getProtocolNumber() const; virtual bool isV4Only() { return true; } virtual bool isV6Only() { return false; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Tools.h0000644000175000017500000000652211733011756024267 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This file contains various utility methods */ #ifndef __FW_TOOLS_HH_FLAG__ #define __FW_TOOLS_HH_FLAG__ #ifndef SAME # define SAME 0 #endif #ifndef nil # define nil NULL #endif #include "config.h" #include #include #include #include #include #ifndef _WIN32 # include #else # include #endif #include "fwbuilder/FWException.h" namespace libfwbuilder { /** * This method should be called to initialize the library * before any calls to it are made. The argument is a full path * to the executable that wants to initialize the library. Just * pass argv[0] there. This method passes substring between * the beginning of exec_path and position of the last '/' or '\' * to XMLTools::init; this information is later used to find DTD * if template directory is defined as relative path. This is especially * useful on Mac and Win32 where API is not installed in the absolute * predetermined path. */ void init(); /** * case insensitive string comparison. We reimplement it on win32 */ int cxx_strcasecmp(const char *s1, const char *s2); char *cxx_strdup(const char *x); char *cxx_strdup(const std::string &x); std::string int2string(int n); /** * portable function that gets a list of files that reside in a given * directory and have specified extension */ std::list getDirList(const std::string &dir, const std::string &ext); /** * just a portable version of sleep */ unsigned int cxx_sleep(unsigned int seconds); /** * Tokenize given string 'str' with delimiters into string vector. */ void tokenize(const std::string& str, std::vector& tokens, const std::string& delimiters = " "); /** * Concat all members of a vector together into a string * if there is more than one member, they are separated by delimiter. */ std::string stringify(const std::vector& parts, const std::string& delimiter = " "); /** * Strip identifier from string 'in' and return as string. */ std::string strip(const std::string& in, const std::string& identifier); /* Convert from string <-> set, using comma as delim */ std::set stringToSet(const std::string &str); std::string setToString(const std::set &s); } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Resources.h0000644000175000017500000001506211733011756025140 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RESOURCES_HH #define _RESOURCES_HH #include "fwbuilder/libfwbuilder-config.h" #include #include #include #include #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" namespace libfwbuilder { class Host; class Firewall; class Interface; class FWOptions; }; class Resources { xmlDocPtr doc; xmlNodePtr root; std::string resfile; static const std::string PLATFORM_RES_DIR_NAME; static const std::string OS_RES_DIR_NAME; std::string getXmlNodeContent(xmlNodePtr node); std::string getXmlNodeProp(xmlNodePtr node,std::string prop); void loadRes(const std::string &rfile ) throw(libfwbuilder::FWException); public: Resources() throw(libfwbuilder::FWException); Resources(const std::string &resF) throw(libfwbuilder::FWException); ~Resources(); void clear(); void loadSystemResources() throw(libfwbuilder::FWException); xmlNodePtr getXmlNode(const std::string& path); std::string getIconPath(const char* icon); std::string getIconPath(const std::string& icon); std::string getResourceStr(const std::string& resource_path); int getResourceInt(const std::string& resource_path); bool getResourceBool(const std::string& resource_path); void getResourceStrList(const std::string& resource_path, std::list &res); bool getObjResourceBool(const libfwbuilder::FWObject *obj, const std::string& resource_name); std::string getObjResourceStr(const libfwbuilder::FWObject *obj, const std::string& resource_name); std::string getRuleElementResourceStr(const std::string &rel, const std::string &resource); std::string getVersion(); std::string getCompiler(); std::string getInstaller(); std::string getTransferAgent(); static std::vector getListOfPlatforms(); static std::map getPlatforms(); static std::map getOS(); /** * sets value of _one_ option using default value from resources */ void setDefaultOption(libfwbuilder::FWObject *o, const std::string &xml_node); /** * sets values of _all_ options using default values from * resources */ void setDefaultOptionsAll(libfwbuilder::FWObject *o, const std::string &xml_node); /** * This method sets default values to objects's properties (or * attributes) defined in DTD. Values are found in global * resources. */ static void setDefaultProperties(libfwbuilder::FWObject *o); /** * This method sets default values to the platform-specific host * or firewall options. Values are found in global resources. Only * class Host and its descendants have child element Options, hence * limitation on the parameter type. */ static void setDefaultOptions(libfwbuilder::Host *o); /** * This method sets default values to the platform-specific * firewall or OS-specific host_OS options. */ static void setDefaultTargetOptions(const std::string &target, libfwbuilder::Firewall *o) throw (libfwbuilder::FWException); /** * This method sets default values to the platform-specific interface * or OS-specific interface options. */ static void setDefaultIfaceOptions(const std::string &target, libfwbuilder::Interface *iface) throw (libfwbuilder::FWException); /** * returns string value of target's capability * 'cap_name'. Capabilities are stored in platform-specific xml files * in subtree "/FWBuilderResources/Target/capabilities" */ static std::string getTargetCapabilityStr(const std::string &target, const std::string &cap_name) throw (libfwbuilder::FWException); static bool getTargetCapabilityBool(const std::string &target, const std::string &cap_name) throw (libfwbuilder::FWException); /** * returns string value of target's option * 'opt_name'. Options are stored in platform-specific xml files * in subtree "/FWBuilderResources/Target/options" */ static std::string getTargetOptionStr(const std::string &target, const std::string &opt_name) throw (libfwbuilder::FWException); static bool getTargetOptionBool(const std::string &target, const std::string &opt_name) throw (libfwbuilder::FWException); static bool isTargetActionSupported(const std::string &target, const std::string &action); static std::string getActionEditor (const std::string &target, const std::string &action); static bool isSystem(const libfwbuilder::FWObject *o); static std::string getIconFileName(const libfwbuilder::FWObject *o); static std::string getNegIconFileName(const libfwbuilder::FWObject *o); static std::string getRefIconFileName(const libfwbuilder::FWObject *o); static std::string getTreeIconFileName(const libfwbuilder::FWObject *o); static Resources *global_res; static std::map platform_res; static std::map os_res; }; #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/FWServiceReference.cpp0000644000175000017500000000305211733011756027171 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Service.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; const char *FWServiceReference::TYPENAME={"ServiceRef"}; FWServiceReference::FWServiceReference():FWReference(){} //FWServiceReference::FWServiceReference(Service *p):FWReference(p){} //FWServiceReference::FWServiceReference(ServiceGroup *p):FWReference(p){} void FWServiceReference::setPointer(Service *p) { FWReference::setPointer(p); } void FWServiceReference::setPointer(ServiceGroup *p) { FWReference::setPointer(p); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/InetAddr.cpp0000644000175000017500000003254411733011756025217 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" extern "C" { # include "fwbuilder/inet_net.h" } #ifndef _WIN32 # include # include # include # include # include #endif #include #include #include #include #include #include #include #ifndef _WIN32 # include # include #else # include #endif #ifdef __linux__ # ifndef _GNU_SOURCE # define _GNU_SOURCE # endif # define A6PREF __in6_u #else # define A6PREF __u6_addr #endif using namespace std; using namespace libfwbuilder; /* * if data is a string that represents integer number without '.' or ':' * in it, call init_from_int */ void InetAddr::init_from_string(const char* data) { if(!data) throw FWException("NULL IP address data.."); if (strchr(data, '.')==NULL && strchr(data, ':')==NULL) { char *invalid_chars; long r = strtol(data, &invalid_chars, 10); if (invalid_chars && *invalid_chars == '\0') init_from_int(r); else throw FWException(string("Invalid IP address: '") + string(data) + "'"); } else { if (address_family == AF_INET) { if (inet_net_pton(AF_INET, data, &ipv4, sizeof(ipv4)) < 0) throw FWException(string("Invalid IP address: '") + string(data)+"'"); } else { if (inet_net_pton(AF_INET6, data, &ipv6, sizeof(ipv6)) < 0) throw FWException(string("Invalid IPv6 address: '") + string(data)+"'"); } } } void InetAddr::init_from_int(unsigned int len) { if (address_family == AF_INET) { if (len > addressLengthBits()) { throw FWException(string("Invalid netmask length")); } unsigned long nm_bits = 0; int i = len; while (i>0) { nm_bits >>= 1; nm_bits |= 0x80000000; i--; } ipv4.s_addr = htonl(nm_bits); } else { if (len > addressLengthBits()) { throw FWException(string("Invalid netmask length")); } ((uint32_t *) (&ipv6))[0] = 0xffffffff; ((uint32_t *) (&ipv6))[1] = 0xffffffff; ((uint32_t *) (&ipv6))[2] = 0xffffffff; ((uint32_t *) (&ipv6))[3] = 0xffffffff; // bits is number of zeros counting from the right end unsigned int nbits = addressLengthBits() - len; for (int i=3; i>=0; --i) { if (nbits >= 32) { ((uint32_t*)(&ipv6))[i] = 0; nbits -= 32; continue; } uint32_t t = 0xffffffff; for (int k = nbits % 32; k; --k) { t <<= 1; t &= 0xfffffffe; } ((uint32_t*)(&ipv6))[i] = htonl(t); break; } } } /* * Netmask with "holes" is accepted by InetAddr, but we do not support * it at this time. This function returns true if InetAddr object * corresponds to an integer with a string of consequitive "1" bits * and then string of consequtive "0" bits. The function only works * for ipv4 addresses. */ bool InetAddr::isValidV4Netmask() { assert(isV4()); unsigned int n = ntohl(ipv4.s_addr); while (n & 0x80000000) { n = n<<1; } return (n == 0); } // uint128 is always in the host order void InetAddr::init_from_uint128(uint128 la) { ((uint32_t *) (&ipv6))[0] = htonl((la >> 96).to_integer() & 0xffffffff); ((uint32_t *) (&ipv6))[1] = htonl((la >> 64).to_integer() & 0xffffffff); ((uint32_t *) (&ipv6))[2] = htonl((la >> 32).to_integer() & 0xffffffff); ((uint32_t *) (&ipv6))[3] = htonl( la.to_integer() & 0xffffffff); } uint128 InetAddr::to_uint128() const { assert(isV6()); uint128 res; uint128 x = uint64_t(ntohl(((uint32_t *) (&ipv6))[0])); x <<= 96; res |= x; x = uint64_t(ntohl(((uint32_t *) (&ipv6))[1])); x <<= 64; res |= x; x = uint64_t(ntohl(((uint32_t *) (&ipv6))[2])); x <<= 32; res |= x; x = uint64_t(ntohl(((uint32_t *) (&ipv6))[3])); res |= x; return res; } InetAddr::InetAddr(const InetAddr &o) { *this = o; } InetAddr::InetAddr(const string &s) throw(FWException, FWNotSupportedException) { address_family = AF_INET; init_from_string(s.c_str()); } InetAddr::InetAddr(int af, const string &s) throw(FWException, FWNotSupportedException) { address_family = af; init_from_string(s.c_str()); } InetAddr::InetAddr(const char *data) throw(FWException) { address_family = AF_INET; init_from_string(data); } InetAddr::InetAddr(int af, const char *data) throw(FWException) { address_family = af; init_from_string(data); } InetAddr::InetAddr(const struct in_addr *na) throw(FWException) { address_family = AF_INET; ipv4.s_addr = na->s_addr; } InetAddr::InetAddr(const struct in6_addr *na) throw(FWException) { address_family = AF_INET6; _copy_in6_addr(&ipv6, na); } // Set netmask to 'n' bits InetAddr::InetAddr(int n) throw(FWException) { address_family = AF_INET; init_from_int(n); } InetAddr::InetAddr(int af, int n) throw(FWException) { address_family = af; init_from_int(n); } InetAddr& InetAddr::operator=(const InetAddr &addr) { if ((address_family = addr.address_family)==AF_INET) { ipv4.s_addr = addr.ipv4.s_addr; } else { InetAddr::_copy_in6_addr(&ipv6, &(addr.ipv6) ); } return *this; } int InetAddr::getLength() const { if (address_family==AF_INET) { if (ipv4.s_addr == INADDR_BROADCAST) return addressLengthBits(); if (ipv4.s_addr == 0) return 0; unsigned int n = ntohl(ipv4.s_addr); int i=0; while (n) { n=n<<1; i++; } return i; } else { int bits = 0; for (int i=3; i>=0; --i) { uint32_t n = ntohl(((uint32_t*)(&ipv6))[i]); if (n==0) { bits += 32; continue; } while ((n & 1) == 0) { bits++; n = n >> 1; } bits = 128 - bits; break; } return bits; } } string InetAddr::toString() const { if (address_family==AF_INET) { return std::string(inet_ntoa(ipv4)); } else { char ntop_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; /* * Our included copy of inet_net_ntop does not add /netmask if * bits==-1 (argument #3). However, the same function included * in libc on FreeBSD returns EINVAL for bits=-1. Here is a * hack: use bits=128 and then strip /128 that inet_net_ntop * adds to the generated string. Both our included * inet_net_ntop and the one shipped with FreeBSD add "/128" * consistently, so this works on all platforms. */ char *cp; cp = inet_net_ntop(AF_INET6, (const void*)(&ipv6), 128, ntop_buf, sizeof(ntop_buf)); if (cp==NULL) { ostringstream err; switch (errno) { case EINVAL: err << "InetAddr::toString() Invalid bit length 0"; throw FWException(err.str()); ;; case EMSGSIZE: err << "InetAddr::toString() EMSGSIZE error"; throw FWException(err.str()); ;; case EAFNOSUPPORT: err << "InetAddr::toString() EAFNOSUPPORT error"; throw FWException(err.str()); ;; default: err << "InetAddr::toString() other error: " << errno; throw FWException(err.str()); ;; } } char *slash_p = strchr(ntop_buf, '/'); if (slash_p!=NULL) *slash_p = '\0'; return std::string(ntop_buf); } } // note that address family of the result is dictated by the address family of // "this". Address family of mask must be the same. InetAddr InetAddr::opAnd(const InetAddr &mask) const { assert(address_family==mask.address_family); if (address_family==AF_INET) { struct in_addr res; res.s_addr = htonl(ntohl(ipv4.s_addr) & ntohl(mask.ipv4.s_addr)); return InetAddr(&res); } else { struct in6_addr res; for (int i=0; i<4; ++i) ((uint32_t*)(&res))[i] = htonl(ntohl(((uint32_t*)(&(ipv6)))[i]) & ntohl(((uint32_t*)(&(mask.ipv6)))[i])); return InetAddr(&res); } } InetAddr InetAddr::opOr(const InetAddr &mask) const { assert(address_family==mask.address_family); if (address_family==AF_INET) { struct in_addr res; res.s_addr = htonl(ntohl(ipv4.s_addr) | ntohl(mask.ipv4.s_addr)); return InetAddr(&res); } else { struct in6_addr res; for (int i=0; i<4; ++i) ((uint32_t*)(&res))[i] = htonl(ntohl(((uint32_t*)(&(ipv6)))[i]) | ntohl(((uint32_t*)(&(mask.ipv6)))[i])); return InetAddr(&res); } } InetAddr InetAddr::opPlus(int increment) const { if (address_family==AF_INET) { struct in_addr res; res.s_addr = htonl(ntohl(ipv4.s_addr) + increment); return InetAddr(&res); } else { uint128 x = to_uint128(); x += increment; InetAddr res(AF_INET6, 0); res.init_from_uint128(x); return res; // struct in6_addr res; // InetAddr::_copy_in6_addr(&res, &(ipv6) ); // ((uint32_t*)(&res))[3] = // htonl(ntohl( ((uint32_t*)(&(ipv6)))[3]) + increment); // return InetAddr(&res); } } InetAddr InetAddr::opMinus(int decrement) const { if (address_family==AF_INET) { struct in_addr res; res.s_addr = htonl(ntohl(ipv4.s_addr) - decrement); return InetAddr(&res); } else { uint128 x = to_uint128(); x -= decrement; InetAddr res(AF_INET6, 0); res.init_from_uint128(x); return res; // struct in6_addr res; // InetAddr::_copy_in6_addr(&res, &(ipv6) ); // ((uint32_t*)(&res))[3] = // htonl(ntohl( ((uint32_t*)(&(ipv6)))[3]) - decrement); // return InetAddr(&res); } } bool InetAddr::opLT(const InetAddr &other) const { if (address_family!=other.address_family) return false; if (address_family==AF_INET) { return (ntohl( ipv4.s_addr ) < ntohl( other.ipv4.s_addr )); } else { uint128 a = to_uint128(); uint128 b = other.to_uint128(); return a < b; // return (ntohl(((uint32_t*)(&(ipv6)))[3]) < // ntohl(((uint32_t*)(&(other.ipv6)))[3])); } } bool InetAddr::opGT(const InetAddr &other) const { if (address_family!=other.address_family) return false; if (address_family==AF_INET) { return (ntohl( ipv4.s_addr ) > ntohl( other.ipv4.s_addr )); } else { uint128 a = to_uint128(); uint128 b = other.to_uint128(); return a > b; // return (ntohl(((uint32_t*)(&(ipv6)))[3]) > // ntohl(((uint32_t*)(&(other.ipv6)))[3])); } } bool InetAddr::opEQ(const InetAddr &other) const { if (address_family!=other.address_family) return false; if (address_family==AF_INET) { return ipv4.s_addr == other.ipv4.s_addr; } else { return (IN6_ARE_ADDR_EQUAL(&(ipv6), &(other.ipv6))); } } bool InetAddr::opNEQ(const InetAddr &other) const { if (address_family!=other.address_family) return false; if (address_family==AF_INET) { return ipv4.s_addr != other.ipv4.s_addr; } else { return (!(IN6_ARE_ADDR_EQUAL(&(ipv6), &(other.ipv6)))); } } InetAddr InetAddr::opCompl() const { if (address_family==AF_INET) { struct in_addr res; res.s_addr = htonl(~(ntohl(ipv4.s_addr))); return InetAddr(&res); } else { struct in6_addr res; ((uint32_t *) (&res))[0] = htonl(~(ntohl(((uint32_t *) (&ipv6))[0]))); ((uint32_t *) (&res))[1] = htonl(~(ntohl(((uint32_t *) (&ipv6))[1]))); ((uint32_t *) (&res))[2] = htonl(~(ntohl(((uint32_t *) (&ipv6))[2]))); ((uint32_t *) (&res))[3] = htonl(~(ntohl(((uint32_t *) (&ipv6))[3]))); return InetAddr(&res); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Address.cpp0000644000175000017500000001066611733011756025113 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed with 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Address.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" using namespace libfwbuilder; using namespace std; const char *Address::TYPENAME={"Address"}; Address::Address() : FWObject() { inet_addr_mask = new InetAddrMask(); setName("address"); } Address::Address(const Address& other) : FWObject(other) { inet_addr_mask = new InetAddrMask(*(other.inet_addr_mask)); } Address::~Address() { delete inet_addr_mask; } FWObject& Address::shallowDuplicate(const FWObject *other, bool preserve_id) throw(FWException) { const Address* a_other = Address::constcast(other); delete inet_addr_mask; inet_addr_mask = new InetAddrMask(*(a_other->inet_addr_mask)); return FWObject::shallowDuplicate(other, preserve_id); } FWReference* Address::createRef() { FWObjectReference *ref = getRoot()->createFWObjectReference(); ref->setPointer(this); return ref; } bool Address::isAny() const { return getId()==FWObjectDatabase::ANY_ADDRESS_ID; } const Address* Address::getAddressObject() const { return NULL; } const InetAddrMask* Address::getInetAddrMaskObjectPtr() const { const Address *addr_obj = getAddressObject(); if (addr_obj) return addr_obj->inet_addr_mask; return NULL; } bool Address::hasInetAddress() const { return false; } int Address::countInetAddresses(bool ) const { return 0; } const InetAddr* Address::getAddressPtr() const { const InetAddrMask *inet_addr_mask = getInetAddrMaskObjectPtr(); if (inet_addr_mask) return inet_addr_mask->getAddressPtr(); return NULL; } const InetAddr* Address::getNetmaskPtr() const { const InetAddrMask *inet_addr_mask = getInetAddrMaskObjectPtr(); if (inet_addr_mask) return inet_addr_mask->getNetmaskPtr(); return NULL; } const InetAddr* Address::getNetworkAddressPtr() const { const InetAddrMask *inet_addr_mask = getInetAddrMaskObjectPtr(); if (inet_addr_mask) return inet_addr_mask->getNetworkAddressPtr(); return NULL; } const InetAddr* Address::getBroadcastAddressPtr() const { const InetAddrMask *inet_addr_mask = getInetAddrMaskObjectPtr(); if (inet_addr_mask) return inet_addr_mask->getBroadcastAddressPtr(); return NULL; } void Address::setAddress(const InetAddr& a) { inet_addr_mask->setAddress(a); } void Address::setNetmask(const InetAddr& nm) { inet_addr_mask->setNetmask(nm); } void Address::setAddressNetmask(const std::string&) { } /* By default dimension is 1. Compilers may rely on this behavior * assuming that every Address object represents single address unless * specific netmask is given. */ unsigned int Address::dimension() const { const InetAddrMask *addr_obj = getInetAddrMaskObjectPtr(); if (addr_obj!=NULL) return addr_obj->dimension(); return 1; } bool Address::belongs(const InetAddr &other) const { const InetAddrMask *addr_obj = getInetAddrMaskObjectPtr(); if (addr_obj!=NULL) return addr_obj->belongs(other); return false; } bool Address::cmp(const FWObject *obj, bool recursive) throw(FWException) { if (Address::constcast(obj)==NULL) return false; if (!FWObject::cmp(obj, recursive)) return false; if (hasInetAddress()!=Address::constcast(obj)->hasInetAddress()) return false; if (!hasInetAddress()) return true; // both this and obj are objects that own ip addresses return (*inet_addr_mask == *(Address::constcast(obj)->inet_addr_mask)); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IPv4.h0000644000175000017500000000374311733011756023753 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPV4_HH_FLAG__ #define __IPV4_HH_FLAG__ #include #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class IPv4 : public Address { public: IPv4(); virtual ~IPv4(); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual unsigned int dimension() const { return 1; } DECLARE_FWOBJECT_SUBTYPE(IPv4); DECLARE_DISPATCH_METHODS(IPv4); virtual bool hasInetAddress() const { return true; } /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool) const { return 1; } virtual const Address* getAddressObject() const { return this; } virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual void setAddressNetmask(const std::string& s); virtual void dump(std::ostream &f,bool recursive,bool brief,int offset=0) const; virtual bool isPrimaryObject() const; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/DNSName.cpp0000644000175000017500000001210511733011756024741 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/dns.h" #include using namespace libfwbuilder; using namespace std; const char *DNSName::TYPENAME={"DNSName"}; DNSName::DNSName() : MultiAddress() { setRunTime(false); setStr("dnsrec", ""); setStr("dnsrectype", "A"); } string DNSName::getSourceName() { return getStr("dnsrec"); } void DNSName::setSourceName(const std::string& source_name) { setStr("dnsrec", source_name); } string DNSName::getDNSRecordType() { return getStr("dnsrec"); } void DNSName::setDNSRecordType(const string& rectype) { setStr("dnsrec", rectype); } void DNSName::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dnsrec"))); assert(n!=NULL); setStr("dnsrec", n); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dnsrectype"))); if (n!=NULL) { setStr("dnsrectype", n); FREEXMLBUFF(n); } else { setStr("dnsrectype", "A"); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("run_time"))); assert(n!=NULL); setStr("run_time", n); FREEXMLBUFF(n); } xmlNodePtr DNSName::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } /* * take domain name from the "dnsrec" attribute and try to run DNS * query. If successful, create corresponding IPv4 or IPv6 object, add * it to the object database and add reference to it to @this. If * unsuccessful, create dummy object and add it to the database and * referece to it, then throw exception. * * TODO: new object should be added to some kind of special group in * the object tree, something with the name "tmp" or similar. */ void DNSName::loadFromSource(bool ipv6, FWOptions *options, bool test_mode) throw(FWException) { int af_type = (ipv6)?AF_INET6:AF_INET; try { list v = DNS::getHostByName(getSourceName(), af_type); for (list::iterator i=v.begin(); i!=v.end(); ++i) { //Address *a = Address::cast( // getRoot()->create((ipv6)?IPv6::TYPENAME:IPv4::TYPENAME)); int af = AF_INET; Address *a = NULL; if (ipv6) { a = getRoot()->createIPv6(); af = AF_INET6; } else a = getRoot()->createIPv4(); getRoot()->add(a); a->setAddress(*i); a->setNetmask(InetAddr::getAllOnes(af)); addRef(a); } } catch (const FWException &ex) { // in test mode we use dummy address but still throw exception. // Compiler should print error message but continue. ostringstream err; string af_type_name = (ipv6)?string("AF_INET6"):string("AF_INET"); err << "DNSName object \"" << getName() << "\" (compile time) can not resolve dns name \"" << getSourceName() << "\" " << "(" << af_type_name << ")" << ": " << ex.toString(); if (test_mode) { err << " Using dummy address in test mode"; int af = AF_INET; Address *a = NULL; if (ipv6) { a = getRoot()->createIPv6(); a->setAddress(InetAddr(af_type, "2001:db8::1")); af = AF_INET6; } else { a = getRoot()->createIPv4(); a->setAddress("192.0.2.1"); a->setNetmask(InetAddr::getAllOnes(af)); } getRoot()->add(a); addRef(a); a->setBool(".rule_error", true); a->setStr(".error_msg", err.str()); } throw(FWException(err.str())); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Address.h0000644000175000017500000000713111733011756024551 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GEN_ADDRESS_HH_FLAG__ #define __GEN_ADDRESS_HH_FLAG__ #include "fwbuilder/FWObject.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InetAddrMask.h" namespace libfwbuilder { /** * This is base class for all objects that can have an address and can * be a child of RuleElementSrc, RuleElementDst and other rule * elements holding addresses. It is never used on it's own, only * it's subclasses are used. * * TODO: we might need to derive ObjectGroup and AddressRange from Address, * but this requires lot more testing */ class Address : public FWObject { protected: InetAddrMask* inet_addr_mask; public: DECLARE_FWOBJECT_SUBTYPE(Address); DECLARE_DISPATCH_METHODS(Address); Address(); Address(const Address&); virtual ~Address(); // Address(const std::string& addr,const std::string& mask); // Address(const std::string &s) throw(FWException); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); const InetAddrMask* getInetAddrMaskObjectPtr() const; /** * This method returns true if object "owns" ip address. Owning * in this context means that the object itself has an address, rather * than one of its child objects. In this sense Firewall, Host, * Interface do not "own" ip address, whereas IPv4, Network, IPv6 * NetworkIPv6 do. */ virtual bool hasInetAddress() const; /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool skip_loopback) const; /** * returns const pointer to internal InetAddr object. Some objects * that inherit this class may return NULL if they do not have * their own IP address (examples: physAddress or Interface with * no child IPv4 object). Using exclusively method that returns * pointer rather than reference to the object allows us to * distinguish between when an object has address 0.0.0.0 or has no * address at all. */ virtual const InetAddr* getAddressPtr() const; virtual const InetAddr* getNetmaskPtr() const; virtual const InetAddr* getNetworkAddressPtr() const; virtual const InetAddr* getBroadcastAddressPtr() const; virtual void setAddress(const InetAddr &a); virtual void setNetmask(const InetAddr &nm); virtual void setAddressNetmask(const std::string& s); virtual const Address* getAddressObject() const; virtual unsigned int dimension() const; bool belongs(const InetAddr &) const; virtual FWReference* createRef(); virtual bool cmp(const FWObject *obj, bool recursive=false) throw(FWException); bool isAny() const; virtual bool isPrimaryObject() const { return true; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Constants.h0000644000175000017500000000457411733011756025150 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LIBFWBUILDER_CONSTANTS_HH__ #define __LIBFWBUILDER_CONSTANTS_HH__ #include namespace libfwbuilder { /** * This class represents various information * about library as well as some public * constants. */ class Constants { static std::string res_dir; public: static void init(const std::string &app_root_dir); /** * Returns library's description */ static const std::string getLibraryDescription(); /** * Returns library version number */ static const std::string getLibraryVersion(); /** * Returns data format version number */ static const std::string getDataFormatVersion(); /** * Returns directory in which library stores it's data files. */ static const std::string getTemplateDirectory(); /** * Returns directory where we install XML DTD file */ static std::string getDTDDirectory(); /** * Returns directory where we install resources */ static std::string getResourcesDirectory(); /** * Returns full path to the resources file */ static std::string getResourcesFilePath(); /** * Returns full path to the standard objects library file */ static std::string getStandardObjectsFilePath(); /** * Returns full path to the prepackaged firewall template objects file */ static std::string getTemplatesObjectsFilePath(); /** * Returns full path to the directory where we install locale files */ static std::string getLocaleDirectory(); }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Group.cpp0000644000175000017500000000656611733011756024626 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Group.h" #include "fwbuilder/XMLTools.h" #include using namespace libfwbuilder; using namespace std; const char *Group::TYPENAME={"Group"}; /* * Group should inherit a list of allowed types from its parent upon creation */ Group::Group() {} Group::~Group() { } bool Group::validateChild(FWObject *o) { return FWObject::validateChild(o); } int Group::getSize() { return getChildrenCount(); } bool Group::hasMember(FWObject *o) { // unlike FWObject::hasChild(), Group::hasMember() also checks references int o_id = o->getId(); for (list::iterator it=begin(); it!=end(); ++it) { if (FWReference::cast(*it)) { if (FWReference::cast(*it)->getPointerId() == o_id) return true; } else { if ((*it)->getId() == o_id) return true; } } return false; } /* * if this is user-defined group, it holds references to objects and * we need to copy it with all these child objects to accurately * reproduce its state for undo. If this is system group, we only copy * this object and its attributes. However we should never really need * to execute undo/redo for system groups anyway. * * Important assumption: groups never have a mix of references and * actual objects, it is either one or another. We can check the kind * of the group by looking at the first child object. * * Caveat: This breaks FWObject::tree_iterator which is used in long * operations that walk the whole tree so the iterator holds the state * that is broken when objects are added or removed from groups in the * middle of iteration. */ FWObject& Group::duplicateForUndo(const FWObject *obj) throw(FWException) { setRO(false); if ((obj->size() && FWReference::cast(obj->front())!=NULL) || (this->size() && FWReference::cast(this->front())!=NULL)) { destroyChildren(); for(list::const_iterator m=obj->begin(); m!=obj->end(); ++m) { if (FWReference::cast(*m)) { FWObject *object = FWReference::getObject(*m); addRef(object); } } } FWObject::duplicateForUndo(obj); return *this; } /* * this is virtual function. Overloaded functions in derived classes * return some meaningful list of types. */ void Group::getAllowedTypesOfChildren(std::list&) { } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/snmp.cpp0000644000175000017500000016204511733011756024502 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2001 NetCitadel, LLC Author: Vadim Zaliva lord@crocodile.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #ifdef HAVE_LIBSNMP #include #include #include #include #include "fwbuilder/physAddress.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/Inet6AddrMask.h" #include "fwbuilder/IPv4.h" /* * we do not really use getops here, but net-snmp does. On FreeBSD, if * port devel/libgnugetopt is installed, it installs file * /usr/local/include/getopt.h. Definition of getopt in this file * conflicts with that in unistd.h, so this module does not * compile. To solve this problem, I put -I/usr/include first in * INCLUDEPATH in Makefiles and #define _GETOPT_H here, so that when * it is included from /usr/local, its internal wrapper macro * _GETOPT_H will have been defined and include file won't be * processed */ #define _GETOPT_H #include "fwbuilder/snmp.h" #ifdef UCD_SNMP #include #endif #include #include #include #include #include /* #ifdef _WIN32 #define snprintf sprintf_s #endif */ /** * Define this if you need extra debug output. */ #undef SNMP_CRAWLER_DEBUG using namespace std; using namespace libfwbuilder; /* Compiled OIDs */ /* We use #define so the compiler can do string concatenation for snprintf */ #define SNMP_INTERFACE_ASTATUS ".1.3.6.1.2.1.2.2.1.7" #define SNMP_INTERFACE_OSTATUS ".1.3.6.1.2.1.2.2.1.8" #define SNMP_INTERFACE_INDEX ".1.3.6.1.2.1.2.2.1.1" #define SNMP_INTERFACES_DESCR ".1.3.6.1.2.1.2.2.1.2" #define SNMP_INTERFACES_PHYSA ".1.3.6.1.2.1.2.2.1.6" #define SNMP_INTERFACES_TYPE ".1.3.6.1.2.1.2.2.1.3" #define SNMP_ADDR_INDEX_TABLE ".1.3.6.1.2.1.4.20.1.2" #define SNMP_NMASK_TABLE ".1.3.6.1.2.1.4.20.1.3" #define SNMP_ADDR_TABLE ".1.3.6.1.2.1.4.20.1.1" #define SNMP_BCAST_TABLE ".1.3.6.1.2.1.4.20.1.4" #define SNMP_AT_TABLE_NET ".1.3.6.1.2.1.3.1.1.3" #define SNMP_AT_TABLE_PHYS ".1.3.6.1.2.1.3.1.1.2" const char *SNMPQuery::SNMP_SYSNAME = ".1.3.6.1.2.1.1.5.0"; const char *SNMPQuery::SNMP_SYSDESCR = ".1.3.6.1.2.1.1.1.0"; const char *SNMPQuery::SNMP_CONTACT = ".1.3.6.1.2.1.1.4.0"; const char *SNMPQuery::SNMP_LOCATION = ".1.3.6.1.2.1.1.6.0"; const char *SNMPQuery::SNMP_ROUTE_DST_TABLE = ".1.3.6.1.2.1.4.21.1.1"; const char *SNMPQuery::SNMP_ROUTE_NM_TABLE = ".1.3.6.1.2.1.4.21.1.11"; const char *SNMPQuery::SNMP_ROUTE_TYPE_TABLE = ".1.3.6.1.2.1.4.21.1.8"; const char *SNMPQuery::SNMP_ROUTE_IF_TABLE = ".1.3.6.1.2.1.4.21.1.2"; const char *SNMPQuery::SNMP_ROUTE_GW_TABLE = ".1.3.6.1.2.1.4.21.1.7"; const int SNMPQuery::SNMP_DIRECT_ROUTE = 3; const char* SNMPQuery::SNMP_IP_MIB_RFC4293_V6_INDEX = ".1.3.6.1.2.1.4.34.1.3.2.16"; const char* SNMPQuery::SNMP_IP_MIB_RFC4293_V6_PREFIX = ".1.3.6.1.2.1.4.34.1.5.2.16"; /** * Following interface types correspond to point-to-point interfaces. * (in ascending order!) */ const int SNMPCrawler::PTP_INTERFACE_TYPES[]={ 17, // sdlc 18, // ds1 19, // e1 20, // basicISDN 21, // primaryISDN 22, // propPointToPointSerial 23, // ppp 28, // slip 30, // ds3 32 // frameRelay. According to 'vk' it could be also broadcast // capable in some weird setup, but we assume it is p-t-p only. }; /* * temporary database object, needs this to be able to create * interfaces and then add ip addresses to them */ static FWObjectDatabase *snmp_tmp_db = NULL; #include SNMPQuery::SNMPQuery(string h,string c, int retries_, long timeout_) { hostname = h; community = c; retries = retries_; timeout = timeout_; descr = ""; contact = ""; location = ""; } void SNMPQuery::init(string h, string c, int retries_, long timeout_) { hostname = h; community = c; retries = retries_; timeout = timeout_; descr = ""; contact = ""; location = ""; char *snmp_out_opt = (char*)("n"); snmp_out_toggle_options(snmp_out_opt); if (snmp_tmp_db==NULL) snmp_tmp_db = new FWObjectDatabase(); } SNMPQuery::~SNMPQuery() { } void SNMPQuery::fetchAll(Logger *logger,SyncFlag *stop_program) throw(FWException) { if(community.empty()) throw FWException("No SNMP community specified"); if(hostname.empty()) throw FWException("No SNMP hostname specified"); SNMPConnection c(hostname, community); c.connect(retries, timeout); CHECK_STOP_AND_THROW_EXCEPTION; fetchSysInfo (logger,stop_program, &c); CHECK_STOP_AND_THROW_EXCEPTION; fetchInterfaces(logger,stop_program, &c); CHECK_STOP_AND_THROW_EXCEPTION; fetchArpTable (logger,stop_program, &c); CHECK_STOP_AND_THROW_EXCEPTION; fetchRoutingTable (logger,stop_program, &c); CHECK_STOP_AND_THROW_EXCEPTION; } void SNMPQuery::fetchArpTable(Logger *logger,SyncFlag *stop_program, SNMPConnection *connection) throw(FWException) { std::ostringstream str; *logger << "ARP table\n"; arptable.clear(); SNMPConnection *c; if(connection) { c=connection; } else { if(community.empty()) throw FWException("No SNMP community specified"); if(hostname.empty()) throw FWException("No SNMP hostname specified"); c=new SNMPConnection(hostname, community); try { c->connect(retries, timeout); } catch(...) { // If program was stopped, show this, rather // than error. throw; } } vector v; try { *logger << "Walking atNetAddress table...\n"; multimap nw=c->walk(SNMP_AT_TABLE_NET ); CHECK_STOP_AND_THROW_EXCEPTION; *logger << "Walking atPhysAddress table...\n"; multimap pw=c->walk(SNMP_AT_TABLE_PHYS ); CHECK_STOP_AND_THROW_EXCEPTION; try { // int preflen = strlen(SNMP_AT_TABLE_NET); for(multimap::iterator j = nw.begin(); j!=nw.end(); ++j) { CHECK_STOP_AND_THROW_EXCEPTION; if((*j).second->type!=SNMPVariable::snmp_ipaddr) { *logger << "unexpected result type in '" << SNMP_AT_TABLE_NET << "' table. Skipping it.\n"; continue; } InetAddr ip = dynamic_cast((*j).second)->getInetAddrValue(); str << "Learned: " << ip.toString(); for(multimap::iterator k = pw.begin(); k!=pw.end(); ++k) { string pa_oid= k->first; if ( pa_oid.find( ip.toString() )!=string::npos ) { string hwaddr=dynamic_cast(k->second)->toHexString(); arptable.insert(make_pair(ip,hwaddr)); str << " at " << hwaddr; break; } } *logger << str; // *logger << "\n"; } } catch(...) { for(multimap::iterator j = nw.begin(); j!=nw.end(); ++j) delete (*j).second; for(multimap::iterator j = pw.begin(); j!=pw.end(); ++j) delete (*j).second; throw; } for(multimap::iterator j = nw.begin(); j!=nw.end(); ++j) delete (*j).second; for(multimap::iterator j = pw.begin(); j!=pw.end(); ++j) delete (*j).second; } catch (FWException &ex) { SNMPVariable::freeVarList(v); if(!connection) delete c; // If program was stopped, show this, rather // than error. throw; } if(!connection) delete c; *logger << "Done fetching ARP table\n"; } /** * Fetches routing table. If interfaces have been already found * it will contain also reference to interface object associated * with the route. */ void SNMPQuery::fetchRoutingTable(Logger *logger,SyncFlag *stop_program, SNMPConnection *connection) throw(FWException) { std::ostringstream str; *logger << "Routing table\n"; routes.clear(); SNMPConnection *c; if(connection) { c=connection; } else { if(community.empty()) throw FWException("No SNMP community specified"); if(hostname.empty()) throw FWException("No SNMP hostname specified"); c=new SNMPConnection(hostname, community); try { c->connect(retries, timeout); } catch(...) { // If program was stopped, show this, rather // than error. throw; } } CHECK_STOP_AND_THROW_EXCEPTION; vector v; try { // Get Indices and destinations multimap w=c->walk(SNMP_ROUTE_DST_TABLE); CHECK_STOP_AND_THROW_EXCEPTION; try { for(multimap::iterator j = w.begin(); j!=w.end(); ++j) { CHECK_STOP_AND_THROW_EXCEPTION; if((*j).second->type!=SNMPVariable::snmp_ipaddr) { str << "unexpected result type in '" << SNMP_ROUTE_DST_TABLE << "' table. Skipping it.\n"; *logger << str; continue; } InetAddr dst = dynamic_cast((*j).second)->getInetAddrValue(); string rname=(*j).first.substr(strlen(SNMP_ROUTE_DST_TABLE)+1); v=c->get(string(SNMP_ROUTE_NM_TABLE)+"."+rname); if(v[0]->type!=SNMPVariable::snmp_ipaddr) { str << "unexpected result type in '" << SNMP_ROUTE_NM_TABLE << "'table. Skipping it.\n"; *logger << str; SNMPVariable::freeVarList(v); continue; } InetAddr nm = dynamic_cast(v[0])->getNetmaskValue(); SNMPVariable::freeVarList(v); v=c->get(string(SNMP_ROUTE_TYPE_TABLE)+"."+rname); long type = SNMPVariable::varList2Int(v); SNMPVariable::freeVarList(v); v=c->get(string(SNMP_ROUTE_GW_TABLE)+"."+rname); if(v[0]->type!=SNMPVariable::snmp_ipaddr) { str << "unexpected result type in '" << SNMP_ROUTE_GW_TABLE << "'table. Skipping it.\n"; *logger << str; SNMPVariable::freeVarList(v); continue; } InetAddr gw = dynamic_cast(v[0])->getInetAddrValue(); SNMPVariable::freeVarList(v); v=c->get(string(SNMP_ROUTE_IF_TABLE)+"."+rname); int ifindex = SNMPVariable::varList2Int(v); SNMPVariable::freeVarList(v); map::iterator ici = interfaces.find(ifindex); InterfaceData route_intf; if(ici==interfaces.end()) { str << "Route references non-existing interface '" << ifindex << "' in '" << string(SNMP_ROUTE_IF_TABLE)+"."+rname << "' variable. Ignoring interface reference.\n"; *logger << str; route_intf.name = "(interface not found)"; } else { #ifdef SNMP_CRAWLER_DEBUG str << "Found interface # " << ifindex << " associated with the route: " << string(SNMP_ROUTE_IF_TABLE)+"."+rname << "\n"; *logger << str; #endif route_intf = ici->second; } bool isdef= type!=SNMP_DIRECT_ROUTE && nm.getLength() == 0 && dst == InetAddr("0.0.0.0"); if (isdef) route_intf.ext = true; IPRoute rt(dst, nm, gw, route_intf, type==SNMP_DIRECT_ROUTE); routes.push_back(rt); str << "route: " << rt.getDestination().toString() << "/" << rt.getNetmask().getLength() << " gw " << rt.getGateway().toString() << " " << rt.getInterface().name << string( (rt.getInterface().ext)?"(Ext)":"") << "\n"; *logger << str; } } catch(...) { for(multimap::iterator j = w.begin(); j!=w.end(); ++j) delete (*j).second; throw; } for(multimap::iterator j = w.begin(); j!=w.end(); ++j) delete (*j).second; w.clear(); } catch (FWException &ex) { SNMPVariable::freeVarList(v); if(!connection) delete c; // If program was stopped, show this, rather // than error. throw; } if(!connection) delete c; *logger << "Done fetching routing table\n"; } bool SNMPQuery::isDefault(const IPRoute &r) const { return !r.isDirect() && r.getNetmask().getLength() == 0 && r.getDestination() == InetAddr("0.0.0.0"); } void SNMPQuery::walkInterfaceIndexTable(Logger *logger, SNMPConnection *c, const char* oid, map > &addr) { std::ostringstream str; multimap w; w = c->walk(oid); CHECK_STOP_AND_THROW_EXCEPTION; for (multimap::iterator j = w.begin(); j!=w.end(); ++j) { CHECK_STOP_AND_THROW_EXCEPTION; if ((*j).second->type != SNMPVariable::snmp_int) { str << "unexpected result type in '" << oid << "' table. Skipping it.\n"; *logger << str; continue; } long ind = SNMPVariable::var2Int((*j).second); string iname = (*j).first.substr(strlen(oid)+1); /* * Example (two interfaces, first has two addresses): * * ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.3.14.201 = 1 * ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.100.100 = 1 * ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.222.22.22.222 = 2 * * at this point iname is watever text we get after * "ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex." , ind is an index */ addr[ind].push_back(iname); str << "interface #" << ind << ": " << iname << "\n"; *logger << str; } for (multimap::iterator j = w.begin(); j!=w.end(); ++j) { delete (*j).second; } w.clear(); } void SNMPQuery::getAddressAndNetmask(Logger * /* UNUSED logger */, SNMPConnection *c, std::string adentry, InetAddr **addr, InetAddr **netmask) { std::ostringstream str; vector v; list components; istringstream iss(adentry); char item[4]; while (iss.getline(item, 4, '.')) { components.push_back(item); } if (components.size()==4) { // IPv4 address // get netmasks v = c->get(string(SNMP_NMASK_TABLE)+"."+adentry); if (v.size()!=1) throw FWException("Can't get netmask"); if (v[0]->type!=SNMPVariable::snmp_ipaddr) throw FWException("Wrong return type for netmask"); *netmask = new InetAddr(dynamic_cast( v[0])->getNetmaskValue().toString()); SNMPVariable::freeVarList(v); // get addresss v = c->get(string(SNMP_ADDR_TABLE)+"."+adentry); if(v.size()!=1) throw FWException("Can't get IP address"); if(v[0]->type!=SNMPVariable::snmp_ipaddr) throw FWException("Wrong return type for IP address"); *addr = new InetAddr(dynamic_cast( v[0])->getInetAddrValue().toString()); SNMPVariable::freeVarList(v); } else { // Assuming everything that is not IPv4 is IPv6 // get prefix string oid = string(SNMP_IP_MIB_RFC4293_V6_PREFIX) + "." + adentry; v = c->get(oid); if (v.size()!=1) throw FWException("Can't get prefix data"); string pref = v[0]->toString(); SNMPVariable::freeVarList(v); // response to this query has type OBJECT_ID. Corresponding // SNMPVariable class returns dot-separated string representation // (SNMPVariable_Bits) // We need to find the last octet, which is the prefix we need. pref = pref.substr(pref.rfind(".") + 1); *netmask = new InetAddr(AF_INET6, atoi(pref.c_str())); // to build proper ipv6 address need to convert adentry to // a ':' separated hex representation ostringstream str_addr; bool first = true; for (list::iterator i=components.begin(); i!=components.end(); ++i) { if (!first) str_addr << ":"; str_addr << hex << atoi(i->c_str()); ++i; str_addr << hex << atoi(i->c_str()); first = false; } *addr = new InetAddr(AF_INET6, str_addr.str()); } } void SNMPQuery::fetchInterfaces(Logger *logger, SyncFlag *stop_program, SNMPConnection *connection) throw(FWException) { std::ostringstream str; interfaces.clear(); SNMPConnection *c; if(connection) { c=connection; } else { if(community.empty()) throw FWException("No SNMP community specified"); if(hostname.empty()) throw FWException("No SNMP hostname specified"); c=new SNMPConnection(hostname, community); try { c->connect(retries, timeout); } catch(...) { // If program was stopped, show this, rather // than error. throw; } } CHECK_STOP_AND_THROW_EXCEPTION; multimap w; vector v; try { map > addr; *logger << "Getting IPv4 addresses."; walkInterfaceIndexTable(logger, c, SNMP_ADDR_INDEX_TABLE, addr); *logger << "Getting IPv6 addresses using IP-MIB RFC4293.\n"; *logger << "This MIB is only supported by latest versions of net-snmp\n"; walkInterfaceIndexTable(logger, c, SNMP_IP_MIB_RFC4293_V6_INDEX, addr); // **************************************************************** *logger << "Collecting full interfaces info\n"; w = c->walk(SNMP_INTERFACE_INDEX); CHECK_STOP_AND_THROW_EXCEPTION; str << w.size() << " interfaces found\n"; *logger << str; for (multimap::iterator j = w.begin(); j!=w.end(); ++j) { CHECK_STOP_AND_THROW_EXCEPTION; // Get index long ifindex = SNMPVariable::var2Int((*j).second); char oid[1024]; // Get admin status snprintf(oid, sizeof(oid), SNMP_INTERFACE_ASTATUS ".%ld", ifindex); v=c->get(oid); if(v.size()!=1) throw FWException( string("Unexpected response length for OID: ") + oid); int astatus = SNMPVariable::varList2Int(v); SNMPVariable::freeVarList(v); if (!astatus) { str << "Interface #" << ifindex << " disabled by admin - skipping.\n"; *logger << str; continue; } // Get operational status snprintf(oid, sizeof(oid), SNMP_INTERFACE_OSTATUS ".%ld", ifindex); v=c->get(oid); if(v.size()!=1) throw FWException( string("Unexpected response length for OID: ") + oid); int ostatus = SNMPVariable::varList2Int(v); SNMPVariable::freeVarList(v); /* gather all information for interface ifindex and create Interface object */ // Get desriptions snprintf(oid, sizeof(oid), SNMP_INTERFACES_DESCR ".%ld", ifindex); v=c->get(oid); string descr = SNMPVariable::varList2String(v); SNMPVariable::freeVarList(v); list &addlist = addr[ifindex]; // Get physical address snprintf(oid, sizeof(oid), SNMP_INTERFACES_PHYSA ".%ld", ifindex); v=c->get(oid); if(v.size()!=1) throw FWException(string("Unexpected response length for OID: ")+oid); if(v[0]->type!=SNMPVariable::snmp_string) throw FWException(string("Unexpected response type for: ")+oid); string physa = dynamic_cast(v[0])->toHexString(); SNMPVariable::freeVarList(v); // Get type snprintf(oid, sizeof(oid), SNMP_INTERFACES_TYPE ".%ld", ifindex); v=c->get(oid); if(v.size()!=1) throw FWException(string("Unexpected response length for OID: ")+oid); int itype = SNMPVariable::varList2Int(v); SNMPVariable::freeVarList(v); InterfaceData idata; idata.name = descr; idata.snmp_type = itype; idata.ext = false; idata.ostatus = ostatus; //snmp_tmp_db->add( &interfaces[ifindex] ); if (physa!="") idata.mac_addr = physa; str << "Adding interface #" << ifindex << " " << idata.name << " MAC: " << idata.mac_addr << endl; *logger << str; if (addlist.empty()) { str << " no IP addresses." << endl; *logger << str; } for (list::iterator ali = addlist.begin(); ali!=addlist.end(); ali++) { CHECK_STOP_AND_THROW_EXCEPTION; InetAddr *ad = NULL; InetAddr *nm = NULL; getAddressAndNetmask(logger, c, *ali, &ad, &nm); InetAddrMask *iam = NULL; if (ad->isV6()) iam = new Inet6AddrMask(); else iam = new InetAddrMask(); iam->setAddress(*ad); iam->setNetmask(*nm); idata.addr_mask.push_back(iam); str << " " << descr << " IP address" << " " << iam->toString() << "\n"; *logger << str; if (ad) delete ad; if (nm) delete nm; } interfaces[ifindex] = idata; } // index walk. for (multimap::iterator j = w.begin(); j!=w.end(); ++j) { delete (*j).second; } w.clear(); } catch (FWException &ex) { SNMPVariable::freeVarList(v); for (multimap::iterator j = w.begin(); j!=w.end(); ++j) { delete (*j).second; } w.clear(); if (!connection) delete c; // If program was stopped, show this, rather // than error. throw; } if (!connection) delete c; *logger << "Done fetching interfaces\n"; } void SNMPQuery::fetchSysInfo(Logger *logger, SyncFlag *stop_program, SNMPConnection *connection) throw(FWException) { std::ostringstream str; descr = ""; contact = ""; location = ""; sysname = ""; SNMPConnection *c; if(connection) { c=connection; } else { if(community.empty()) { throw FWException("No SNMP community specified"); } if(hostname.empty()) { throw FWException("No SNMP hostname specified"); } c=new SNMPConnection(hostname, community); try { c->connect(retries, timeout); } catch(...) { // If program was stopped, show this, rather // than error. throw; } } try { vector v; *logger << "Getting System name\n"; v=c->get(SNMP_SYSNAME); sysname = SNMPVariable::varList2String(v); SNMPVariable::freeVarList(v); CHECK_STOP_AND_THROW_EXCEPTION; *logger << "Getting Description\n"; v=c->get(SNMP_SYSDESCR); descr = SNMPVariable::varList2String(v); SNMPVariable::freeVarList(v); CHECK_STOP_AND_THROW_EXCEPTION; *logger << "Getting Location\n"; v=c->get(SNMP_LOCATION); location = SNMPVariable::varList2String(v); SNMPVariable::freeVarList(v); CHECK_STOP_AND_THROW_EXCEPTION; *logger << "Getting Contact Info\n"; v=c->get(SNMP_CONTACT); contact = SNMPVariable::varList2String(v); SNMPVariable::freeVarList(v); CHECK_STOP_AND_THROW_EXCEPTION; } catch(...) { if(!connection) delete c; // If program was stopped, show this, rather // than error. throw; } if(!connection) delete c; *logger << "Done fetching sysinfo\n"; } vector* SNMPQuery::getRoutes() { return &routes; } map* SNMPQuery::getArpTable() { return &arptable; } map* SNMPQuery::getInterfaces() { return &interfaces; } const string& SNMPQuery::getSysname() { return sysname; } const string& SNMPQuery::getDescr() { return descr; } const string& SNMPQuery::getContact() { return contact; } const string& SNMPQuery::getLocation() { return location; } // ----------------------------------------------- bool SNMPConnection::lib_initialized = false; SNMPConnection::SNMPConnection(const string &p, const string &c) { connected = false; session_data = NULL; peer = p; community = c; if(!lib_initialized) { init_snmp("fwbuilder"); lib_initialized = true; } } SNMPConnection::~SNMPConnection() { if(connected) disconnect(); } void SNMPConnection::connect(int retries, long timeout) throw(FWException) { if(connected) throw FWException("SNMPSession: already connected"); session_data = new struct snmp_session; snmp_sess_init( session_data ); session_data->version = SNMP_VERSION_1; session_data->peername = cxx_strdup(peer.c_str()); session_data->community = (unsigned char *)cxx_strdup(community.c_str()); session_data->community_len = community.length(); session_data->retries = retries; session_data->timeout = timeout; session = snmp_open(session_data); if(!session) throw FWException("SNMPSession: error while establishing connection."); connected=true; } void SNMPConnection::disconnect() throw(FWException) { if(!connected) throw FWException("SNMPSession: already disconnected"); snmp_close(session); delete session_data->peername; delete session_data->community; delete session_data; session_data = NULL; connected = false; } multimap SNMPConnection::walk(const string &variable) throw(FWException) { multimap res; oid root[MAX_OID_LEN]; size_t rootlen; rootlen = MAX_OID_LEN; // get_node(variable.c_str(), root, &rootlen); //TODO: error check read_objid(variable.c_str(), root, &rootlen); //TODO: error check oid name[MAX_OID_LEN]; size_t name_length; /* get first object to start walk */ memmove(name, root, rootlen * sizeof(oid)); name_length = rootlen; bool running=true; while(running) { /* create PDU for GETNEXT request and add object name to request */ struct snmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(pdu, name, name_length); /* do the request */ struct snmp_pdu *response = NULL; int status = snmp_synch_response(session, pdu, &response); if(status == STAT_SUCCESS) { if(response->errstat == SNMP_ERR_NOERROR) { for(struct variable_list *vars = response->variables; vars; vars = vars->next_variable ) { if ((vars->name_length < rootlen) || (memcmp(root, vars->name, rootlen * sizeof(oid))!=0)) { /* not part of this subtree */ running = false; continue; } char n[MAX_NAME_LEN]; #ifdef HAVE_SNPRINT_OBJID snprint_objid (n, sizeof(n), vars->name, vars->name_length); #else sprint_objid (n, vars->name, vars->name_length); #endif res.insert(make_pair(string(n),SNMPVariable::create(vars))); if ((vars->type != SNMP_ENDOFMIBVIEW) && (vars->type != SNMP_NOSUCHOBJECT) && (vars->type != SNMP_NOSUCHINSTANCE)){ /* not an exception value */ memmove((char *)name, (char *)vars->name, vars->name_length * sizeof(oid)); name_length = vars->name_length; } else { /* an exception value, so stop */ running = false; } } } else { /* error in response, print it */ if(response->errstat == SNMP_ERR_NOSUCHNAME) { throw FWException("SNMPSession: error: End of MIB"); } else { throw FWException(string("SNMPSession: SNMP error: ")+ snmp_errstring(response->errstat)); } } // } else if (status == STAT_TIMEOUT) // { // throw FWException("SNMPSession: SNMP timeout"); } else { // status == STAT_ERROR if (response != NULL) { throw FWException(string("SNMPSession: SNMP error: '") + string(snmp_errstring(response->errstat)) + "'"); snmp_free_pdu(response); } else { std::ostringstream str; str << "SNMPSession: SNMP error, status "; str << status; int liberr,syserr; char *errstr = (char*)(""); snmp_error(session, &liberr, &syserr, &errstr); str << " " << errstr; throw FWException(str.str()); } } } return res; } vector SNMPConnection::get(const string &variable) throw(FWException) { if(!connected) throw FWException("SNMPSession: not connected"); struct snmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_GET); oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; // get_node(variable.c_str(), anOID, &anOID_len); //TODO: error check read_objid(variable.c_str(), anOID, &anOID_len); //TODO: error check snmp_add_null_var(pdu, anOID, anOID_len); struct snmp_pdu *response; int status = snmp_synch_response(session, pdu, &response); if(status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { vector res; for(struct variable_list *vars = response->variables; vars; vars = vars->next_variable ) { try { res.push_back(SNMPVariable::create(vars)); } catch(const FWException &ex) { SNMPVariable::freeVarList(res); throw; } } if (response) snmp_free_pdu(response); return res; } else { if (response) snmp_free_pdu(response); throw FWException("SNMPSession: Error getting variable "+ variable); } } SNMPVariable *SNMPVariable::create(struct variable_list *vars) throw(FWException) { switch(vars->type) { case ASN_INTEGER: return new SNMPVariable_Int(*vars->val.integer); case ASN_OCTET_STR: return new SNMPVariable_String(vars->val.string, vars->val_len); case ASN_BIT_STR: return new SNMPVariable_Bits(vars->val.bitstring, vars->val_len); case ASN_APP_COUNTER64: return new SNMPVariable_Counter64(vars->val.counter64); case ASN_OBJECT_ID: return new SNMPVariable_Bits(vars->val.bitstring, vars->val_len); // return new SNMPVariable_OID(*vars->val.objid); case ASN_IPADDRESS: return new SNMPVariable_IPaddr(vars->val.string, vars->val_len); default: char x[32]; snprintf(x, sizeof(x), "%d", (int)vars->type); throw FWException(string("Unknown SNMP variable type: ") + x); } } string SNMPVariable_Int::toString() { char x[32]; snprintf(x, sizeof(x), "%ld", value); return x; } string SNMPVariable_Bits::toString() { string res; for (unsigned int i=0; i &v) { vector::iterator j; for(j=v.begin(); j!=v.end(); ++j) delete (*j); v.clear(); } string SNMPVariable::varList2String(vector &v) { string res; vector::iterator j; for(j=v.begin(); j!=v.end(); ++j) res+=(*j)->toString(); return res; } long SNMPVariable::var2Int(SNMPVariable *var) throw(FWException) { if(var->type != SNMPVariable::snmp_int) throw FWException("Could not extract integer from non-int SNMP variable."); return dynamic_cast(var)->getIntValue(); } long SNMPVariable::varList2Int(vector &v) throw(FWException) { if(v.size()!=1) throw FWException("Empty SNMP variable list returned. Could not extract integer"); return SNMPVariable::var2Int(v[0]); } SNMPCrawler::SNMPCrawler() {} SNMPCrawler::SNMPCrawler(const InetAddr &_seed, const string &_community, bool _recursive, bool _do_dns, bool _follow_ptp, unsigned int _dns_threads, int _snmp_retries, long _snmp_timeout, int _dns_retries, int _dns_timeout, const vector *_limit_to_networks) { init(_seed, _community, _recursive, _do_dns, _follow_ptp, _dns_threads, _snmp_retries, _snmp_timeout, _dns_retries, _dns_timeout, _limit_to_networks); } SNMPCrawler::~SNMPCrawler() { } void SNMPCrawler::init(const InetAddr &_seed, const string &_community, bool _recursive, bool _do_dns, bool _follow_ptp, unsigned int _dns_threads, int _snmp_retries, long _snmp_timeout, int _dns_retries, int _dns_timeout, const vector *_limit_to_networks) { limit_to_networks = _limit_to_networks; community = _community; snmp_retries = _snmp_retries; snmp_timeout = _snmp_timeout; recursive = _recursive; do_dns = _do_dns; follow_ptp = _follow_ptp; dns_threads = _dns_threads; dns_retries = _dns_retries; dns_timeout = _dns_timeout; queue.clear(); found.clear(); networks.clear(); queue[_seed]=""; } /** * This method attempts to guess what interface might be associated * with given route. It could be more than one. */ list SNMPCrawler::guessInterface( const IPRoute &r, const map &intf) const { list res; map::const_iterator i; for(i=intf.begin(); i!=intf.end(); ++i) { for (list::const_iterator j=i->second.addr_mask.begin(); j!=i->second.addr_mask.end(); ++j) { if ((*j)->belongs(r.getGateway())) { res.push_back((*i).second); break; } } } return res; } bool SNMPCrawler::included(const InetAddr &a) const { if (!limit_to_networks) return true; // no include list provided. All hosts are OK. // currently we allow the user to specify only ipv4 in the inlcude list if (a.isV6()) return true; for (vector::const_iterator i=limit_to_networks->begin(); i!=limit_to_networks->end(); ++i) { if ((*i).belongs(a)) return true; } return false; } bool SNMPCrawler::alreadyseen(const InetAddr &a) const { return found.find(a) != found.end(); } /** * loopback : All addresses on the net 127.0.0.0/255.0.0.0 */ const InetAddrMask SNMPCrawler::LOOPBACK_NET( InetAddr::getLoopbackAddr(), InetAddr("255.0.0.0")); const InetAddrMask SNMPCrawler::IPV6_LOOPBACK_NET( InetAddr::getLoopbackAddr(AF_INET6), InetAddr(AF_INET6, 128)); const InetAddr SNMPCrawler::PTP_NETMASK(InetAddr::getAllOnes()); bool SNMPCrawler::point2point(const InetAddrMask &n, const InterfaceData& intf) const { return *(n.getNetmaskPtr())==PTP_NETMASK || point2point(intf); } bool SNMPCrawler::point2point(const InterfaceData& intf) const { int itype = intf.snmp_type; for(unsigned int i=0;i<(sizeof(PTP_INTERFACE_TYPES)/sizeof(int));i++) { if(PTP_INTERFACE_TYPES[i]==itype) return true; else if(PTP_INTERFACE_TYPES[i]>itype) return false; } return false; } /** * Check if address one which we are ignoring. * This include hosts on loopback, special addresses * as "0.0.0.0". */ bool SNMPCrawler::special(const InetAddr &a) const { if (a.isAny()) return true; if (a.isV4()) return LOOPBACK_NET.belongs(a); if (a.isV6()) return IPV6_LOOPBACK_NET.belongs(a); return false; } bool SNMPCrawler::special(const InetAddrMask &n) const { return n==LOOPBACK_NET || n==IPV6_LOOPBACK_NET || n.getAddressPtr()->isBroadcast() || n.getAddressPtr()->isMulticast() || n.getAddressPtr()->isAny(); } //TODO: multiple threads (via pool). void SNMPCrawler::run_impl(Logger *logger, SyncFlag *stop_program) throw(FWException) { if (snmp_tmp_db==NULL) snmp_tmp_db = new FWObjectDatabase(); std::ostringstream str; time_t now=time(NULL); str << "SNMPCrawler started at " << asctime(localtime(&now)) << ". Seed host: " << (*(queue.begin())).first.toString() << "\n"; *logger << str; snmp_tmp_db->destroyChildren(); SNMP_discover_query q; do { CHECK_STOP_AND_RETURN; map::iterator i=queue.begin(); if(i==queue.end()) { break; } InetAddr task = (*i).first; string task_phys_address = (*i).second; queue.erase(i); str << "\nProcessing " << task.toString() << "\n"; *logger << str; // Now in task we have element to probe q.init(task.toString(), // fake host - IP in dotted notation community, snmp_retries, snmp_timeout ); CrawlerFind *res = new CrawlerFind(); found[task] = *res; delete res; found[task].found_phys_addr = task_phys_address; try { q.fetchArpTable(logger,stop_program); found[task].have_snmpd = true; } catch(const FWException &ex) { // fetch failed str << ex.toString() << "\n"; str << "Failed to fetch ARP table from " << task.toString(); if (!ex.toString().empty()) str << " : " << ex.toString(); str << "\n"; *logger << str; continue; } catch (std::string s) { str << s << "\n"; str << "Failed to fetch ARP table from " << task.toString(); str << " : " << s; str << "\n"; *logger << str; continue; } map* at = q.getArpTable(); str << "Got " << long(at->size()) << " entries\n"; *logger << str; int qplus=0, rplus=0, dplus=0; for(map::iterator j=at->begin();j!=at->end();++j) { CHECK_STOP_AND_RETURN; InetAddr c = (*j).first; string pa = (*j).second; if (included(c) && !alreadyseen(c) && !special(c)) { if(recursive) { qplus++; queue[c]=pa; } else { rplus++; found[c]=CrawlerFind(); found[c].found_phys_addr=pa; } } else dplus++; } if (qplus) { str << "Adding " << qplus << " hosts to queue\n"; *logger << str; } if (rplus) { str << "Adding " << rplus << " hosts to results\n"; *logger << str; } if (dplus) { str << "Skipping " << dplus << " hosts as duplicate, excluded or virtual\n"; *logger << str; } set interface_broadcasts; try { q.fetchInterfaces(logger,stop_program); found[task].have_snmpd = true; //cerr << "Copying list of interfaces" << endl; //map intf = q.getInterfaces(); //cerr << "Done" << endl; map* intf = q.getInterfaces(); map::iterator j; for (j=intf->begin(); j!=intf->end(); ++j) { // If interface is down or does not have ip address, it // will be ignored. if (!j->second.ostatus) continue; if (j->second.addr_mask.size()==0) continue; list::iterator n; for (n=j->second.addr_mask.begin(); n!=j->second.addr_mask.end(); ++n) { InetAddrMask *net = *n; const InetAddr *addr = net->getAddressPtr(); const InetAddr *netm = net->getNetmaskPtr(); if (addr==NULL) continue; //InetAddrMask net(*addr, *netm); interface_broadcasts.insert( *(net->getBroadcastAddressPtr())); if (!special(*net) && included(*(net->getAddressPtr())) && !point2point(*net, j->second)) { str << "Network " << net->toString() << "\n"; *logger << str; // NOTE: net is a pointer to InetAddrMask object // created in fetchInterfaces when we filled // map interfaces with InterfaceData objects. // This object is destroyed when all InterfaceData // objects are destroyed. Create a copy. networks.insert(*net); } } } } catch(FWException &ex) { // fetch failed str << ex.toString() << "\n"; str << "Failed to fetch list of interfaces from " << task.toString() << "\n"; *logger << str; } try { q.fetchSysInfo(logger,stop_program); found[task].have_snmpd = true; found[task].sysname = q.getSysname (); found[task].descr = q.getDescr (); found[task].contact = q.getContact (); found[task].location = q.getLocation (); } catch (const FWException &ex) { // fetch failed str << ex.toString() << "\n"; str << "Failed to fetch sysinfo from " << task.toString() << "\n"; *logger << str; } try { q.fetchRoutingTable(logger,stop_program); found[task].have_snmpd = true; vector* routes = q.getRoutes(); qplus=0; rplus=0; dplus=0; int nplus=0; for (vector::iterator j=routes->begin(); j!=routes->end(); ++j) { InterfaceData intf; bool have_intf; const InterfaceData& real_i = j->getInterface(); intf = real_i; have_intf = !intf.name.empty(); InetAddrMask net(j->getDestination(), j->getNetmask()); if (!have_intf) { // No interface reported for this route by SNMP // we can try to guess it by route information. // Since interface is used. list gi = guessInterface(*j, *(q.getInterfaces())); // From all resulting interfaces we select one // using following rules: // // 1. If all interfaces are down we select any of them // since this route will be ignored because of it. // // 2. From interfaces which are UP, we select first one // with Point-to-Point attribute enabled. // list::const_iterator k; for(k=gi.begin(); k!=gi.end(); ++k) { if(!have_intf) { // first interface ever found intf=*k; have_intf = true; } else { if ((*k).ostatus) { // Candidate is up // Store it. intf = *k; have_intf = true; } else { // Candidate is down. // We take it into account only // if everything found so far is down. if (!intf.ostatus) intf = *k; } } if(have_intf && intf.ostatus && point2point(intf)) break; } if (have_intf) str << "Guessed that network " << net.toString() << " is using interface " << intf.name << "\n"; *logger << str; } // If route is associated with an interface which is down, // ignore it. if (have_intf && !intf.ostatus) { str << "Skipping route for network " << net.toString() << " which is associated with interface which is" << " currently down."; *logger << str; continue; } if (!special(net) && included(*(net.getAddressPtr())) ) { if (point2point(net, intf)) { const InetAddr *c = net.getAddressPtr(); // For all addresses found in the routing table // we must check if they are broadcast addresses // for some of our interfaces, and if yes, ignore them. // (see task #36520). if (included(*c) && !alreadyseen(*c) && !special(*c) && !interface_broadcasts.count(*c)) { if(recursive && follow_ptp) { qplus++; queue[*c]=""; } else { rplus++; found[*c] = CrawlerFind(); } } else { dplus++; } } else { str << "Network " << net.toString() << " found (via " << string(((*j).isDirect())?"direct":"indirect") << " route).\n"; *logger << str; networks.insert( InetAddrMask(j->getDestination(), j->getNetmask())); nplus++; } } InetAddr gw((*j).getGateway()); if (included(gw) && !alreadyseen(gw) && !special(gw) && !interface_broadcasts.count(gw)) { bool isptp=point2point(net, intf); if(recursive && (!isptp || (isptp && follow_ptp))) { qplus++; queue[gw]=""; } else { rplus++; found[gw]=CrawlerFind(); } } } if (qplus) { str << "Adding " << qplus << " hosts to queue\n"; *logger << str; } if (nplus) { str << "Adding " << nplus << " networks to results\n"; *logger << str; } if (rplus) { str << "Adding " << rplus << " hosts to results\n"; *logger << str; } if (dplus) { str << "Skipping " << dplus << " hosts as duplicate, excluded or virtual\n"; *logger << str; } } catch(const FWException &ex) { // fetch failed str << ex.toString() << "\n"; str << "Failed to fetch routing table from " << task.toString() << "\n"; *logger << str; } catch (...) { *logger << "Unsupported exception\n"; } // We add interfaces _after_ fetching routing table, // since it's updates 'ext' attribute based on rounting // table. found[task].interfaces = *(q.getInterfaces()); } while(recursive); if(do_dns) bacresolve_results(logger,stop_program); snmp_tmp_db->clear(); // at this point all children have been destroyed anyway now=time(NULL); str << "SNMPCrawler - done at " << asctime(localtime(&now)) << "\n"; *logger << str; } void SNMPCrawler::bacresolve_results(Logger *logger, SyncFlag *) throw(FWException) { *logger << "Resolving names\n"; set resolv_set; for (map::iterator j=found.begin(); j!=found.end(); ++j) { HostEnt he = DNS::getHostByAddr((*j).first); found[(*j).first].dns_ok = true; found[(*j).first].name = he.name; found[(*j).first].aliases = he.aliases; *logger << ((*j).first).toString() << " : " << he.name << "\n"; } *logger << "Finished.\n"; } set SNMPCrawler::getNetworks() { return networks; } map SNMPCrawler::getAllIPs() { return found; } CrawlerFind::CrawlerFind() { have_snmpd = false; dns_ok = false; } CrawlerFind::~CrawlerFind() { } void SNMP_interface_query::run_impl(Logger *logger, SyncFlag *stop_program) throw(FWException) { fetchSysInfo(logger, stop_program); CHECK_STOP_AND_THROW_EXCEPTION; fetchInterfaces(logger, stop_program); #if 0 // See #2084 this takes forever on decides with large routing // tables. Also it is unclear if routing table data is really // used to determine external interface. Besides, we only have // concept of external/internale on platforms that support // security levels (PIX) and there we guess levels by matching // addresses against RFC1918 and let the user user set levels // manually anyway. // We try to fetch routing table, to find // which interface is "external". // We do not fail if this query does not succeed. try { fetchRoutingTable(logger, stop_program); } catch(FWException &ex) { *logger << "Error fetching routing table, external interface will not be detected.\n"; } #endif } void SNMP_sysdesc_query::run_impl(Logger *logger,SyncFlag *stop_program) throw(FWException) { fetchSysInfo(logger,stop_program); } void SNMP_discover_query::run_impl(Logger *logger,SyncFlag *stop_program) throw(FWException) { fetchArpTable(logger,stop_program); if(fetch_inerfaces) fetchInterfaces(logger,stop_program); } #undef SNMP_CRAWLER_DEBUG #else #ifndef _WIN32 # warning ucd-snmp library not found - SNMP functionality will be disabled. #endif #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/AddressTable.cpp0000644000175000017500000001615311733011756026060 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include #include #include #include using namespace libfwbuilder; using namespace std; const char *AddressTable::TYPENAME={"AddressTable"}; AddressTable::AddressTable() : MultiAddress() { setRunTime(false); setStr("filename", ""); } string AddressTable::getSourceName() { return getStr("filename"); } void AddressTable::setSourceName(const std::string& source_name) { setStr("filename", source_name); } void AddressTable::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("filename"))); assert(n!=NULL); setStr("filename", n); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("run_time"))); assert(n!=NULL); setStr("run_time", n); FREEXMLBUFF(n); } xmlNodePtr AddressTable::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); return me; } string AddressTable::getFilename(FWOptions *options) throw (FWException) { string path = getStr("filename"); size_t found = path.find("%DATADIR%"); if (found == string::npos) return path; string dataDir; if (isRunTime()) { dataDir = options->getStr("data_dir"); if (dataDir.empty()) { throw FWException("Firewall 'data directory' setting is blank"); } } else { dataDir = FWObject::getDataDir(); if (dataDir.empty()) { throw FWException("Global 'data directory' setting is blank"); } } path.replace(found, 9, dataDir); return path; } /* * read file specified by the "filename" attribute and interpret lines * as addresses. Create corresponding address or network objects, add * them to the object database and add references to them to @this. If * file does not exist and we run in test mode, create dummy object * and add it to the database and referece to it, then throw * exception. * * TODO: new objects should be added to some kind of special group in * the object tree, something with the name "tmp" or similar. */ void AddressTable::loadFromSource(bool ipv6, FWOptions *options, bool test_mode) throw(FWException) { string path = getFilename(options); ifstream fs(path.c_str()); ostringstream exmess; string buf; size_type pos; int line = 1; int cntr = 0; Address *new_addr; if(fs) { while(!fs.eof()) { getline(fs,buf); pos = buf.find_first_not_of(" \t"); if (pos!=string::npos) { buf = buf.substr(pos); pos = buf.find_first_not_of("0123456789abcdef:/."); buf = buf.substr(0,pos); } else { buf=""; } if (!buf.empty()) { new_addr = NULL; if (ipv6 && buf.find(":")!=string::npos) { try { InetAddr(AF_INET6, buf); // to test address NetworkIPv6 *net = getRoot()->createNetworkIPv6(); net->setAddressNetmask(buf); new_addr = net; } catch (FWException &ex) { exmess << "Invalid address: " << path << ":" << line << " \"" << buf << "\""; throw FWException(exmess.str()); } } if (!ipv6 && buf.find(".")!=string::npos) { try { InetAddr(AF_INET, buf); // to test address Network *net = getRoot()->createNetwork(); net->setAddressNetmask(buf); new_addr = net; } catch (FWException &ex) { exmess << "Invalid address: " << path << ":" << line << " \"" << buf << "\""; throw FWException(exmess.str()); } } if (new_addr) { new_addr->setName(buf); if (validateChild(new_addr)) { getRoot()->add(new_addr); addRef(new_addr); cntr++; } } } line++; } } else { // in test mode we use dummy address but still throw exception. // Compiler should print error message but continue. exmess << "File not found for Address Table: " << getName() << " (" << path << ")"; if (test_mode) { exmess << " Using dummy address in test mode"; if (ipv6) { NetworkIPv6 *net = getRoot()->createNetworkIPv6(); net->setAddressNetmask("2001:db8::/32"); new_addr = net; } else { Network *net = getRoot()->createNetwork(); net->setAddressNetmask("192.0.2.0/24"); new_addr = net; } new_addr->setName(buf); if (validateChild(new_addr)) { getRoot()->add(new_addr); addRef(new_addr); cntr++; } new_addr->setBool(".rule_error", true); new_addr->setStr(".error_msg", exmess.str()); } throw FWException(exmess.str()); } } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/IntervalGroup.cpp0000644000175000017500000000467011733011756026325 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Interval.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/FWObjectDatabase.h" using namespace std; using namespace libfwbuilder; const char *IntervalGroup::TYPENAME={"IntervalGroup"}; IntervalGroup::IntervalGroup() : Group() {} IntervalGroup::~IntervalGroup() {} bool IntervalGroup::validateChild(FWObject *o) { FWObject *oo = o; if (FWObjectReference::cast(o)!=NULL) oo = FWObjectReference::cast(o)->getPointer(); string otype = oo->getTypeName(); return (FWObject::validateChild(o) && (otype=="Interval" || otype=="IntervalGroup" || otype=="IntervalRef" )); } FWReference* IntervalGroup::createRef() { // FWIntervalReference *ref=new FWIntervalReference(); FWIntervalReference *ref = getRoot()->createFWIntervalReference(); ref->setPointer(this); return ref; } xmlNodePtr IntervalGroup::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); for(list::const_iterator j=begin(); j!=end(); ++j) (*j)->toXML(me); return me; } void IntervalGroup::getAllowedTypesOfChildren(std::list &types_list) { types_list.clear(); types_list.push_back(Interval::TYPENAME); types_list.push_back(FWIntervalReference::TYPENAME); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/TCPUDPService.cpp0000644000175000017500000000747111733011756026046 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/TCPUDPService.h" #include "fwbuilder/XMLTools.h" using namespace libfwbuilder; using namespace std; const char *TCPUDPService::TYPENAME={"TCPUDPService"}; TCPUDPService::TCPUDPService() { src_range_start = 0; src_range_end = 0; dst_range_start = 0; dst_range_end = 0; } TCPUDPService::~TCPUDPService() {} string TCPUDPService::getProtocolName() const { return ""; } int TCPUDPService::getProtocolNumber() const { return -1; } void TCPUDPService::fromXML(xmlNodePtr root) throw(FWException) { FWObject::fromXML(root); const char *n; n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("src_range_start"))); if(n!=NULL) { src_range_start = atol(n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("src_range_end"))); if(n!=NULL) { src_range_end = atol(n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dst_range_start"))); if(n!=NULL) { dst_range_start = atol(n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("dst_range_end"))); if(n!=NULL) { dst_range_end = atol(n); FREEXMLBUFF(n); } } xmlNodePtr TCPUDPService::toXML(xmlNodePtr xml_parent_node) throw(FWException) { xmlNodePtr me = FWObject::toXML(xml_parent_node); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); char str[128]; snprintf(str, sizeof(str), "%d", src_range_start); xmlNewProp(me, TOXMLCAST("src_range_start"), TOXMLCAST(str)); snprintf(str, sizeof(str), "%d", src_range_end); xmlNewProp(me, TOXMLCAST("src_range_end"), TOXMLCAST(str)); snprintf(str, sizeof(str), "%d", dst_range_start); xmlNewProp(me, TOXMLCAST("dst_range_start"), TOXMLCAST(str)); snprintf(str, sizeof(str), "%d", dst_range_end); xmlNewProp(me, TOXMLCAST("dst_range_end"), TOXMLCAST(str)); return me; } FWObject& TCPUDPService::shallowDuplicate(const FWObject *obj, bool preserve_id) throw(FWException) { const TCPUDPService *other = TCPUDPService::constcast(obj); src_range_start = other->src_range_start; src_range_end = other->src_range_end; dst_range_start = other->dst_range_start; dst_range_end = other->dst_range_end; return FWObject::shallowDuplicate(obj, preserve_id); } bool TCPUDPService::cmp(const FWObject *obj, bool recursive) throw(FWException) { const TCPUDPService *other = TCPUDPService::constcast(obj); if (other == NULL) return false; if (src_range_start != other->src_range_start || src_range_end != other->src_range_end || dst_range_start != other->dst_range_start || dst_range_end != other->dst_range_end) return false; return FWObject::cmp(obj, recursive); } fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/RuleElement.h0000644000175000017500000002102311733011756025401 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RULEELEMENT_HH_FLAG__ #define __RULEELEMENT_HH_FLAG__ #include "fwbuilder/Group.h" #include "fwbuilder/Address.h" #include "fwbuilder/Service.h" #include "fwbuilder/Interval.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/IntervalGroup.h" namespace libfwbuilder { class Rule; class FWReference; class RuleElement : virtual public FWObject { protected: bool negation; public: RuleElement(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); DECLARE_FWOBJECT_SUBTYPE(RuleElement); DECLARE_DISPATCH_METHODS(RuleElement); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); void setAnyElement(); void reset(); virtual int getAnyElementId() const; bool isAny() const; /** * Adds reference object pointing to 'obj' as a child of 'this'. If * RuleElement contained "any", it is removed */ virtual void addRef(FWObject *obj); /** * Removes reference to given object among children of 'this'. If * this object was the last one, appropriate "any" object is added * instead */ virtual void removeRef(FWObject *obj); bool getNeg() const { return negation; } void setNeg(bool flag) { negation = flag; } void toggleNeg() { negation = !negation; } }; class RuleElementSrc : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementSrc); DECLARE_DISPATCH_METHODS(RuleElementSrc); RuleElementSrc(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementDst : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementDst); DECLARE_DISPATCH_METHODS(RuleElementDst); RuleElementDst(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementSrv : public ServiceGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementSrv); DECLARE_DISPATCH_METHODS(RuleElementSrv); RuleElementSrv(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementItf : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementItf); DECLARE_DISPATCH_METHODS(RuleElementItf); RuleElementItf(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); bool checkItfChildOfThisFw(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementItfInb : public RuleElementItf { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementItfInb); DECLARE_DISPATCH_METHODS(RuleElementItfInb); RuleElementItfInb(); }; class RuleElementItfOutb : public RuleElementItf { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementItfOutb); DECLARE_DISPATCH_METHODS(RuleElementItfOutb); RuleElementItfOutb(); }; class RuleElementInterval : public IntervalGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementInterval); DECLARE_DISPATCH_METHODS(RuleElementInterval); RuleElementInterval(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementOSrc : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementOSrc); DECLARE_DISPATCH_METHODS(RuleElementOSrc); RuleElementOSrc(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementODst : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementODst); DECLARE_DISPATCH_METHODS(RuleElementODst); RuleElementODst(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementOSrv : public ServiceGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementOSrv); DECLARE_DISPATCH_METHODS(RuleElementOSrv); RuleElementOSrv(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementTSrc : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementTSrc); DECLARE_DISPATCH_METHODS(RuleElementTSrc); RuleElementTSrc(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementTDst : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementTDst); DECLARE_DISPATCH_METHODS(RuleElementTDst); RuleElementTDst(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementTSrv : public ServiceGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementTSrv); DECLARE_DISPATCH_METHODS(RuleElementTSrv); RuleElementTSrv(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementRDst : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementRDst); DECLARE_DISPATCH_METHODS(RuleElementRDst); RuleElementRDst(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementRGtw : public ObjectGroup, public RuleElement { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementRGtw); DECLARE_DISPATCH_METHODS(RuleElementRGtw); RuleElementRGtw(); virtual int getAnyElementId() const; virtual bool validateChild(FWObject *o); bool checkSingleIPAdress(FWObject *o); bool checkReachableIPAdress(FWObject *o); virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); virtual bool isPrimaryObject() const { return false; } }; class RuleElementRItf : public RuleElementItf { public: DECLARE_FWOBJECT_SUBTYPE(RuleElementRItf); DECLARE_DISPATCH_METHODS(RuleElementRItf); RuleElementRItf(); virtual bool validateChild(FWObject *o); virtual bool isPrimaryObject() const { return false; } }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Host.h0000644000175000017500000000561711733011756024110 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __HOST_HH_FLAG__ #define __HOST_HH_FLAG__ #include #include #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/ObjectMatcher.h" namespace libfwbuilder { class Interface; class Management; class Host : public Address { protected: public: Host(); virtual ~Host(); /** * This method should create any standard mandatory child objects * the object might need. */ virtual void init(FWObjectDatabase *root); virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML (xmlNodePtr parent) throw(FWException); DECLARE_FWOBJECT_SUBTYPE(Host); DECLARE_DISPATCH_METHODS(Host); /* * verify whether given object type is approppriate as a child */ virtual bool validateChild(FWObject *o); bool Appropriate(Interface *i); void addInterface(Interface *i); void removeInterface(Interface *i); const InetAddr* getManagementAddress() throw(FWException); /** * This method returns reference to the object representing * host's platform-specific options (class HostOptions) */ virtual FWOptions* getOptionsObject(); /** * Returns management object associated with this Host. * If none is present, new one will be created; */ Management *getManagementObject(); virtual const Address* getAddressObject() const; virtual unsigned int dimension() const { return 1; } /** * similar to hasInetAddress() but counts addresses */ virtual int countInetAddresses(bool skip_loopback) const; virtual bool isPrimaryObject() const { return true; } /** * helper-function, needed when dealing with sub-interfaces: * function returns the parent host (or firewall) of an interface * or rule set. This is just a convenience function that performs * operation we often need. */ static FWObject* getParentHost(FWObject *obj); protected: Management *mgmt; }; } #endif fwbuilder-5.1.0.3599/src/libfwbuilder/src/fwbuilder/Firewall.cpp0000644000175000017500000002645511733011756025276 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include #include using namespace std; using namespace libfwbuilder; const char *Firewall::TYPENAME={"Firewall"}; Firewall::Firewall() { setStr("platform","unknown"); setStr("host_OS" ,"unknown"); setInt("lastModified" ,0); setInt("lastInstalled" ,0); setInt("lastCompiled" ,0); } void Firewall::init(FWObjectDatabase *root) { FWObject *opt = getFirstByType(FirewallOptions::TYPENAME); if (opt == NULL) { add( root->createFirewallOptions() ); RuleSet *p; p = root->createPolicy(); p->setTop(true); add(p); p = root->createNAT(); p->setTop(true); add(p); p = root->createRouting(); p->setTop(true); add(p); } } Firewall::~Firewall() {} void Firewall::fromXML(xmlNodePtr root) throw(FWException) { const char *n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("platform"))); assert(n!=NULL); setStr("platform", n); FREEXMLBUFF(n); n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("version"))); if (n!=NULL) { setStr("version", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("host_OS"))); if (n!=NULL) { setStr("host_OS", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("lastModified"))); if(n!=NULL) { setStr("lastModified", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("lastInstalled"))); if(n!=NULL) { setStr("lastInstalled", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("lastCompiled"))); if(n!=NULL) { setStr("lastCompiled", n); FREEXMLBUFF(n); } n=FROMXMLCAST(xmlGetProp(root,TOXMLCAST("inactive"))); if(n!=NULL) { setStr("inactive", n); FREEXMLBUFF(n); } Host::fromXML(root); } xmlNodePtr Firewall::toXML(xmlNodePtr parent) throw(FWException) { xmlNodePtr me = FWObject::toXML(parent, false); xmlNewProp(me, TOXMLCAST("name"), STRTOXMLCAST(getName())); xmlNewProp(me, TOXMLCAST("comment"), STRTOXMLCAST(getComment())); xmlNewProp(me, TOXMLCAST("ro"), TOXMLCAST(((getRO()) ? "True" : "False"))); FWObject *o; for (FWObjectTypedChildIterator it = findByType(NAT::TYPENAME); it != it.end(); ++it) { o = *it; if (o) o->toXML(me); } for (FWObjectTypedChildIterator it = findByType(Policy::TYPENAME); it != it.end(); ++it) { o = *it; if (o) o->toXML(me); } for (FWObjectTypedChildIterator it = findByType(Routing::TYPENAME); it != it.end(); ++it) { o = *it; if (o) o->toXML(me); } for(FWObjectTypedChildIterator it = findByType(Interface::TYPENAME); it != it.end(); ++it) { o = *it; if (o) o->toXML(me); } o=getFirstByType( Management::TYPENAME ); if(o) o->toXML(me); o=getFirstByType( FirewallOptions::TYPENAME ); if (o) o->toXML(me); return me; } FWOptions* Firewall::getOptionsObject() { return FWOptions::cast( getFirstByType(FirewallOptions::TYPENAME) ); } Policy* Firewall::getPolicy() { return(Policy::cast(findObjectByName(Policy::TYPENAME, "Policy"))); } NAT* Firewall::getNAT() { return(NAT::cast(findObjectByName(NAT::TYPENAME, "NAT"))); } Routing* Firewall::getRouting() { return(Routing::cast(findObjectByName(Routing::TYPENAME, "Routing"))); } bool Firewall::validateChild(FWObject *o) { string otype=o->getTypeName(); if (Routing::isA(o)) { // there can be only one list routing_objects = getByType(Routing::TYPENAME); if (routing_objects.size() > 0) return false; } return (FWObject::validateChild(o) && (otype==Interface::TYPENAME || otype==RuleSet::TYPENAME || otype==Policy::TYPENAME || otype==NAT::TYPENAME || otype==Routing::TYPENAME || otype==Management::TYPENAME || otype==FirewallOptions::TYPENAME )); } void Firewall::duplicateInterfaces(FWObject *target, const FWObject *source, map &id_mapping, bool preserve_id) { for (FWObjectTypedChildIterator m = source->findByType(Interface::TYPENAME); m!=m.end(); ++m ) { FWObject *src_interface = *m; FWObject *dst_interface_copy = target->addCopyOf(src_interface, preserve_id); id_mapping[src_interface->getId()] = dst_interface_copy->getId(); Interface::cast(dst_interface_copy)->duplicateWithIdMapping( src_interface, id_mapping, preserve_id); #if 0 if (Firewall::cast(target)) { /* * duplicate FailoverClusterGroup object of all interfaces * this is actually used for Cluster object only atm. * * Do this only if @target is Firewall or Cluster, do not do * this if @target is an interface because in the latter case * this function copies subinterfaces and those don't have * failover group child objects. */ for (FWObjectTypedChildIterator k = src_interface->findByType(FailoverClusterGroup::TYPENAME); k!=k.end(); ++k ) { FWObject *src_subinterface = *k; FWObject *dst_subinterface_copy = dst_interface_copy->addCopyOf(src_subinterface, preserve_id); if (src_subinterface!=NULL && dst_subinterface_copy!=NULL) id_mapping[src_subinterface->getId()] = dst_subinterface_copy->getId(); } duplicateInterfaces(dst_interface_copy, src_interface, id_mapping, preserve_id); } #endif } } FWObject& Firewall::duplicate(const FWObject *obj, bool preserve_id) throw(FWException) { string err="Error creating object with type: "; checkReadOnly(); bool xro = obj->getRO(); //shallowDuplicate(obj, preserve_id); FWObject::shallowDuplicate(obj, preserve_id); setReadOnly(false); destroyChildren(); id_mapping_for_duplicate.clear(); duplicateInterfaces(this, obj, id_mapping_for_duplicate, preserve_id); for (FWObjectTypedChildIterator it = obj->findByType(Policy::TYPENAME); it != it.end(); ++it) { FWObject *new_ruleset = addCopyOf(*it, preserve_id); id_mapping_for_duplicate[(*it)->getId()] = new_ruleset->getId(); } for (FWObjectTypedChildIterator it = obj->findByType(NAT::TYPENAME); it != it.end(); ++it) { FWObject *new_ruleset = addCopyOf(*it, preserve_id); id_mapping_for_duplicate[(*it)->getId()] = new_ruleset->getId(); } for (FWObjectTypedChildIterator it = obj->findByType(Routing::TYPENAME); it != it.end(); ++it) { FWObject *new_ruleset = addCopyOf(*it, preserve_id); id_mapping_for_duplicate[(*it)->getId()] = new_ruleset->getId(); } // replace references to old fw (obj) with references to this fw id_mapping_for_duplicate[obj->getId()] = getId(); FWObject *o=obj->getFirstByType( Management::TYPENAME ); addCopyOf(o,preserve_id); o=obj->getFirstByType( FirewallOptions::TYPENAME ); addCopyOf(o,preserve_id); // replace references to old objects in rules map::iterator it; for (it=id_mapping_for_duplicate.begin(); it!=id_mapping_for_duplicate.end(); ++it) { int old_id = it->first; int new_id = it->second; replaceRef(old_id, new_id); } setDirty(true); if (xro) setReadOnly(true); return *this; } FWObject& Firewall::duplicateForUndo(const FWObject *obj) throw(FWException) { setRO(false); FWObject *their_mgmt = obj->getFirstByType(Management::TYPENAME); if (their_mgmt) { FWObject *my_mgmt = getManagementObject(); if (my_mgmt) my_mgmt->duplicate(their_mgmt); } FWObject::duplicateForUndo(obj); return *this; } void Firewall::updateLastInstalledTimestamp() { setInt("lastInstalled",time(NULL)); } void Firewall::updateLastModifiedTimestamp() { setInt("lastModified",time(NULL)); } bool Firewall::needsInstall() { if (getLastInstalled()==0 || getLastCompiled()==0) return true; return !(getLastModified()<=getLastCompiled() && getLastCompiled()<=getLastInstalled()); } bool Firewall::needsCompile() { return getLastModified()>getLastCompiled() || getLastCompiled()==0; } time_t Firewall::getLastModified() { return getInt("lastModified"); } time_t Firewall::getLastInstalled() { return getInt("lastInstalled"); } time_t Firewall::getLastCompiled() { return getInt("lastCompiled"); } void Firewall::updateLastCompiledTimestamp() { setInt("lastCompiled",time(NULL)); } bool Firewall::getInactive() { return getBool("inactive"); } void Firewall::setInactive(bool b) { setBool("inactive",b); } /* * There are only two levels of interfaces, i.e. a top-level interface can only * have a subinterface. Subinterfaces can not have further subinterfaces. */ list Firewall::getInterfacesByType(const string &iface_type) { list res; for (FWObjectTypedChildIterator it = findByType(Interface::TYPENAME); it != it.end(); ++it) { Interface *iface = Interface::cast(*it); if (iface->getOptionsObject()->getStr("type") == iface_type) res.push_back(iface); for (FWObjectTypedChildIterator subit = iface->findByType(Interface::TYPENAME); subit != subit.end(); ++subit) { Interface *subiface = Interface::cast(*subit); if (subiface->getOptionsObject()->getStr("type") == iface_type) res.push_back(subiface); } } return res; } void Firewall::assignUniqueRuleIds() { std::for_each(begin(), end(), RuleSet::UniqueRuleIdsSetter()); } fwbuilder-5.1.0.3599/src/libfwbuilder/migration/0000755000175000017500000000000011733011756022230 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_4.xslt0000644000175000017500000000465411733011756026470 0ustar sylvestresylvestre Policy NAT Routing 5 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.12.xslt0000644000175000017500000000153011733011756027033 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.7.xslt0000644000175000017500000000152711733011756026766 0ustar sylvestresylvestre 2.1.8 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.1.xslt0000644000175000017500000002063411733011756026760 0ustar sylvestresylvestre num. of interfaces: num. of interface policy rules: interface id= num. of preceding interface policy rules: interface policy rule pos new position False global policy rule new position False sysid0 2.1.2 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.99.xslt0000644000175000017500000000152111733011756027053 0ustar sylvestresylvestre 3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.13.xslt0000644000175000017500000000153611733011756027121 0ustar sylvestresylvestre 0.10.14 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_1.0.1.xslt0000644000175000017500000000433611733011756026757 0ustar sylvestresylvestre id3F6D115C broadcast Standard 255.255.255.255 255.255.255.255 id3F6D115D old-broadcast Standard 0.0.0.0 0.0.0.0 1.0.2 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.0.xslt0000644000175000017500000000153111733011756026751 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.1.xslt0000644000175000017500000000153111733011756026752 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.1.xslt0000644000175000017500000000366511733011756027043 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_8.xslt0000644000175000017500000000376111733011756026472 0ustar sylvestresylvestre tagobject_id 9 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.8.xslt0000644000175000017500000000152711733011756026767 0ustar sylvestresylvestre 2.1.9 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_17.xslt0000644000175000017500000000530111733011756026542 0ustar sylvestresylvestre False sysid0 False sysid0 18 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.14.xslt0000644000175000017500000000153311733011756027041 0ustar sylvestresylvestre 2.1.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_1.0.0.xslt0000644000175000017500000000152611733011756026754 0ustar sylvestresylvestre 1.0.1 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.4.xslt0000644000175000017500000000153111733011756026755 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.4.xslt0000644000175000017500000003410711733011756027041 0ustar sylvestresylvestre 33524 False False ipf False True 0.10.5 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.6.xslt0000644000175000017500000000152711733011756026765 0ustar sylvestresylvestre 2.1.7 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_15.xslt0000644000175000017500000000306111733011756026541 0ustar sylvestresylvestre sveasoft 16 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.2.xslt0000644000175000017500000000151211733011756027031 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_21.xslt0000644000175000017500000000205311733011756026536 0ustar sylvestresylvestre 22 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.8.xslt0000644000175000017500000001074111733011756027043 0ustar sylvestresylvestre -i interface-1 False 0 -i-1-addr 255.255.255.255 0.10.9 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.10.xslt0000644000175000017500000000153011733011756027031 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.12.xslt0000644000175000017500000000555211733011756027122 0ustar sylvestresylvestre False -pa (MAC) 0.10.13 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.2.xslt0000644000175000017500000000153111733011756026753 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_7.xslt0000644000175000017500000001310211733011756026457 0ustar sylvestresylvestre Automatically created for rule Tag In library "" 8 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.16.xslt0000644000175000017500000000152111733011756027040 0ustar sylvestresylvestre 3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.9.xslt0000644000175000017500000000155011733011756027042 0ustar sylvestresylvestre 0.10.10 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.3.xslt0000644000175000017500000000231511733011756027034 0ustar sylvestresylvestre 0.10.4 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.14.xslt0000644000175000017500000000153211733011756027116 0ustar sylvestresylvestre 1.0.0 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_16.xslt0000644000175000017500000000312111733011756026537 0ustar sylvestresylvestre True 17 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.11.xslt0000644000175000017500000000525211733011756027040 0ustar sylvestresylvestre 2.1.12 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.4.xslt0000644000175000017500000000162511733011756026762 0ustar sylvestresylvestre 2.1.6 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.15.xslt0000644000175000017500000000152111733011756027037 0ustar sylvestresylvestre 3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.2.xslt0000644000175000017500000000310411733011756026752 0ustar sylvestresylvestre _og_ats_1 Address Tables 2.1.3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_20.xslt0000644000175000017500000002243511733011756026543 0ustar sylvestresylvestre Accept Accept Continue taggingTrue classificationFalse routingFalse True Accept Accept Accept Continue taggingFalse classificationTrue routingFalse Continue Accept taggingFalse classificationFalse routingTrue 21 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.9.4.xslt0000644000175000017500000000123311733011756026763 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_3.xslt0000644000175000017500000000150611733011756026460 0ustar sylvestresylvestre 4 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_19.xslt0000644000175000017500000000405311733011756026547 0ustar sylvestresylvestre pf_classify_str 20 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_13.xslt0000644000175000017500000000257311733011756026546 0ustar sylvestresylvestre 14 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_10.xslt0000644000175000017500000000447311733011756026544 0ustar sylvestresylvestre _clusters Clusters 11 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.0.xslt0000644000175000017500000001246211733011756027035 0ustar sylvestresylvestre -i 0 100 -m state --state ESTABLISHED,RELATED fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.3.xslt0000644000175000017500000000310411733011756026753 0ustar sylvestresylvestre _og_tag_1 TagServices 2.1.4 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.6.xslt0000644000175000017500000000265611733011756027047 0ustar sylvestresylvestre 0.10.7 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.12.xslt0000644000175000017500000000163111733011756027036 0ustar sylvestresylvestre 2.1.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.5.xslt0000644000175000017500000000153111733011756026756 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.11.xslt0000644000175000017500000000662211733011756027120 0ustar sylvestresylvestre 1 1 1 1 1 1 False True 0.10.12 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_14.xslt0000644000175000017500000000674311733011756026552 0ustar sylvestresylvestre mangle_only_rule_set True 15 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.18.xslt0000644000175000017500000000152111733011756027042 0ustar sylvestresylvestre 3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.7.xslt0000644000175000017500000000150411733011756027037 0ustar sylvestresylvestre 0.10.8 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.13.xslt0000644000175000017500000000163111733011756027037 0ustar sylvestresylvestre 2.1.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.9.xslt0000644000175000017500000000153111733011756026763 0ustar sylvestresylvestre 2.1.10 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.0.xslt0000644000175000017500000000360411733011756026755 0ustar sylvestresylvestre -routing 2.1.1 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.9.1.xslt0000644000175000017500000000241411733011756026762 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.99.xslt0000644000175000017500000000412411733011756027054 0ustar sylvestresylvestre _og_dnsn_1 DNS Names 2.1.0 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_11.xslt0000644000175000017500000000400111733011756026530 0ustar sylvestresylvestre Clusters 12 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.5.xslt0000644000175000017500000000152511733011756026762 0ustar sylvestresylvestre 2.1.6 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.9.3.xslt0000644000175000017500000000536411733011756026773 0ustar sylvestresylvestre -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.10.xslt0000644000175000017500000000364011733011756027114 0ustar sylvestresylvestre 0.10.11 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.3.xslt0000644000175000017500000000153111733011756026754 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.17.xslt0000644000175000017500000000152111733011756027041 0ustar sylvestresylvestre 3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_12.xslt0000644000175000017500000000302111733011756026532 0ustar sylvestresylvestre Translate 13 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.7.xslt0000644000175000017500000000153111733011756026760 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.9.5.xslt0000644000175000017500000003604211733011756026772 0ustar sylvestresylvestre linux24 0.10.0 root Standard fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.19.xslt0000644000175000017500000000152111733011756027043 0ustar sylvestresylvestre 3 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.1.10.xslt0000644000175000017500000000153311733011756027035 0ustar sylvestresylvestre 2.1.11 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.8.xslt0000644000175000017500000000153211733011756026762 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.6.xslt0000644000175000017500000000153111733011756026757 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_5.xslt0000644000175000017500000000717211733011756026467 0ustar sylvestresylvestre Policy 6 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.11.xslt0000644000175000017500000000153011733011756027032 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/migration.pro0000644000175000017500000000637211733011756024753 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../qmake.inc) TEMPLATE = lib TARGET = migration win32 { CONFIG -= embed_manifest_exe } QMAKE_RUN_CC = "@echo" QMAKE_RUN_CXX = "@echo" QMAKE_LINK = "@echo" target.path = $${migration.path} target.files = FWObjectDatabase_0.9.0.xslt \ FWObjectDatabase_0.9.1.xslt \ FWObjectDatabase_0.9.2.xslt \ FWObjectDatabase_0.9.3.xslt \ FWObjectDatabase_0.9.4.xslt \ FWObjectDatabase_0.9.5.xslt \ FWObjectDatabase_0.10.0.xslt \ FWObjectDatabase_0.10.1.xslt \ FWObjectDatabase_0.10.2.xslt \ FWObjectDatabase_0.10.3.xslt \ FWObjectDatabase_0.10.4.xslt \ FWObjectDatabase_0.10.5.xslt \ FWObjectDatabase_0.10.6.xslt \ FWObjectDatabase_0.10.7.xslt \ FWObjectDatabase_0.10.8.xslt \ FWObjectDatabase_0.10.9.xslt \ FWObjectDatabase_0.10.10.xslt \ FWObjectDatabase_0.10.11.xslt \ FWObjectDatabase_0.10.12.xslt \ FWObjectDatabase_0.10.13.xslt \ FWObjectDatabase_0.10.14.xslt \ FWObjectDatabase_1.0.0.xslt \ FWObjectDatabase_1.0.1.xslt \ FWObjectDatabase_1.0.2.xslt \ FWObjectDatabase_2.0.0.xslt \ FWObjectDatabase_2.0.1.xslt \ FWObjectDatabase_2.0.2.xslt \ FWObjectDatabase_2.0.3.xslt \ FWObjectDatabase_2.0.4.xslt \ FWObjectDatabase_2.0.5.xslt \ FWObjectDatabase_2.0.6.xslt \ FWObjectDatabase_2.0.7.xslt \ FWObjectDatabase_2.0.8.xslt \ FWObjectDatabase_2.0.9.xslt \ FWObjectDatabase_2.0.10.xslt \ FWObjectDatabase_2.0.11.xslt \ FWObjectDatabase_2.0.12.xslt \ FWObjectDatabase_2.0.99.xslt \ FWObjectDatabase_2.1.0.xslt \ FWObjectDatabase_2.1.1.xslt \ FWObjectDatabase_2.1.2.xslt \ FWObjectDatabase_2.1.3.xslt \ FWObjectDatabase_2.1.4.xslt \ FWObjectDatabase_2.1.5.xslt \ FWObjectDatabase_2.1.6.xslt \ FWObjectDatabase_2.1.7.xslt \ FWObjectDatabase_2.1.8.xslt \ FWObjectDatabase_2.1.9.xslt \ FWObjectDatabase_2.1.10.xslt \ FWObjectDatabase_2.1.11.xslt \ FWObjectDatabase_2.1.12.xslt \ FWObjectDatabase_2.1.13.xslt \ FWObjectDatabase_2.1.14.xslt \ FWObjectDatabase_2.1.15.xslt \ FWObjectDatabase_2.1.16.xslt \ FWObjectDatabase_2.1.17.xslt \ FWObjectDatabase_2.1.18.xslt \ FWObjectDatabase_2.1.19.xslt \ FWObjectDatabase_2.1.99.xslt \ FWObjectDatabase_3.xslt \ FWObjectDatabase_4.xslt \ FWObjectDatabase_5.xslt \ FWObjectDatabase_6.xslt \ FWObjectDatabase_7.xslt \ FWObjectDatabase_8.xslt \ FWObjectDatabase_9.xslt \ FWObjectDatabase_10.xslt \ FWObjectDatabase_11.xslt \ FWObjectDatabase_12.xslt \ FWObjectDatabase_13.xslt \ FWObjectDatabase_14.xslt \ FWObjectDatabase_15.xslt \ FWObjectDatabase_16.xslt \ FWObjectDatabase_17.xslt \ FWObjectDatabase_18.xslt \ FWObjectDatabase_19.xslt \ FWObjectDatabase_20.xslt \ FWObjectDatabase_21.xslt \ fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.9.0.xslt0000644000175000017500000000124711733011756026764 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_18.xslt0000644000175000017500000000452211733011756026547 0ustar sylvestresylvestre False sysid0 19 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_1.0.2.xslt0000644000175000017500000001071311733011756026754 0ustar sylvestresylvestre _1 _1 2.0.0 root syslib000 Standard Standard objects #d4f8ff True syslib001 User User defined objects #d2ffd0 fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.9.2.xslt0000644000175000017500000000123311733011756026761 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_0.10.5.xslt0000644000175000017500000000265611733011756027046 0ustar sylvestresylvestre 0.10.6 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_2.0.9.xslt0000644000175000017500000000153111733011756026762 0ustar sylvestresylvestre 2.0.99 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_6.xslt0000644000175000017500000000355211733011756026466 0ustar sylvestresylvestre _userservices Users 7 root fwbuilder-5.1.0.3599/src/libfwbuilder/migration/FWObjectDatabase_9.xslt0000644000175000017500000000437111733011756026471 0ustar sylvestresylvestre True True True 10 root fwbuilder-5.1.0.3599/src/iptlib/0000755000175000017500000000000011733011756017050 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_PrintRuleIptRstEcho.cpp0000644000175000017500000000521511733011756026462 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_ipt.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Resources.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ /* * check and create new chain if needed */ string PolicyCompiler_ipt::PrintRuleIptRstEcho::_createChain(const string &chain) { string res; PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); if (!minus_n_tracker_initialized) initializeMinusNTracker(); if ( ipt_comp->minus_n_commands->count(chain)==0 ) { if ( ! compiler->inSingleRuleCompileMode()) res = "echo \":" + chain + " - [0:0]\"\n"; (*(ipt_comp->minus_n_commands))[chain] = true; } return res; } string PolicyCompiler_ipt::PrintRuleIptRstEcho::_startRuleLine() { return string("echo \"-A "); } string PolicyCompiler_ipt::PrintRuleIptRstEcho::_endRuleLine() { return string("\"\n"); } bool PolicyCompiler_ipt::PrintRuleIptRstEcho::processNext() { if (print_once_on_top) { print_once_on_top=false; } return PolicyCompiler_ipt::PrintRule::processNext(); } string PolicyCompiler_ipt::PrintRuleIptRstEcho::_declareTable() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); ostringstream res; res << "echo '*" << ipt_comp->my_table << "'" << endl; return res.str(); } string PolicyCompiler_ipt::PrintRuleIptRstEcho::_commit() { return "echo COMMIT\n"; } string PolicyCompiler_ipt::PrintRuleIptRstEcho::_quote(const string &s) { return "\\\"" + s + "\\\""; } fwbuilder-5.1.0.3599/src/iptlib/RoutingCompiler_ipt.cpp0000644000175000017500000002355111733011756023560 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "RoutingCompiler_ipt.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Network.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; static std::map tmp_chain_no; string RoutingCompiler_ipt::myPlatformName() { return "iptables"; } void RoutingCompiler_ipt::verifyPlatform() { //TODO: Routing based on the 'ip' command is independent from iptables string family = Resources::platform_res[fw->getStr("platform")]-> getResourceStr("/FWBuilderResources/Target/family"); if (family != myPlatformName()) abort("Unsupported platform " + fw->getStr("platform") + " (family " + family + ")"); } int RoutingCompiler_ipt::prolog() { int n = RoutingCompiler::prolog(); verifyPlatform(); return n; } /* * this processor eliminates duplicate routing rules, generated from the same * rule in the GUI */ bool RoutingCompiler_ipt::optimize3::processNext() { RoutingRule *rule; rule=getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } if (printRule==NULL) { printRule = new PrintRule(""); printRule->setContext(compiler); } string thisRule = rule->getLabel() + " " + printRule->RoutingRuleToString(rule); if (rules_seen_so_far.count(thisRule)!=0) return true; tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = true; return true; } /* * this processor eliminates duplicate atomic routing rules in one routing table */ bool RoutingCompiler_ipt::eliminateDuplicateRules::processNext() { RoutingRule *rule; rule = getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } if (printRule==NULL) { printRule = new PrintRule(""); printRule->setContext(compiler); } string label = rule->getLabel(); int bracepos = label.find("("); label.erase(0, bracepos); string thisRule = label + " " + printRule->RoutingRuleToString(rule); rules_it = rules_seen_so_far.find(thisRule); if (rules_it != rules_seen_so_far.end()) { string msg; msg = "Two of the sub rules created from the gui routing rules " + rules_it->second + " and " + rule->getLabel() + " are identical, skipping the second. " + "Revise them to avoid this warning"; compiler->warning(rule, msg.c_str()); return true; } tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = rule->getLabel(); return true; } bool RoutingCompiler_ipt::addressRangesInDst::processNext() { RoutingRule *rule; rule=getNext(); if (rule==NULL) return false; RuleElementRDst *dstrel = rule->getRDst(); compiler->_expandAddressRanges(rule, dstrel); tmp_queue.push_back(rule); return true; } bool RoutingCompiler_ipt::FindDefaultRoute::processNext() { RoutingCompiler_ipt *ipt_comp = dynamic_cast(compiler); RoutingRule *rule; rule=getNext(); if (rule==NULL) return false; RuleElementRDst *dstrel = rule->getRDst(); FWObject *ref = dstrel->front(); Address *dst = Address::cast(FWReference::cast(ref)->getPointer()); if (dst->isAny()) ipt_comp->have_default_route = true; tmp_queue.push_back(rule); return true; } /** *----------------------------------------------------------------------- */ void RoutingCompiler_ipt::compile() { string banner = " Compiling routing rules for " + fw->getName(); info(banner); Compiler::compile(); //bool check_for_recursive_groups=true; add(new RoutingCompiler::Begin()); add(new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new recursiveGroupsInRDst("Check for recursive Groups in RDst")); add(new emptyGroupsInRDst("Check for empty Groups in RDst")); add(new emptyRDstAndRItf("Check if RDst and RItf are both empty")); add(new singleAdressInRGtw( "Check if RGtw object has exactly one IP adress")); add(new rItfChildOfFw("Check if RItf is an Iterface of this firewall")); // unfortunately ExpandGroups also filters out objects that do not // match address family but does not issue a warning when that // happens. Since I need to show a warning when user places ipv6 // object in a routing rule, I call DropIPv6RulesWithWarning() // before expanding groups. This has limited effect though: user // gets a warning when a single ipv6 address or network object // appears in the rule but gets no warning when it appears as a // member of a group. add(new DropIPv6RulesWithWarning( "drop ipv6 rules", "Rule has been suppressed because it contains IPv6 " "objects and Firewall Builder does not support IPv6 " "routing rules at this time")); add(new ExpandGroups("Expand groups in DST")); add(new ExpandMultipleAddresses( "Expand objects with multiple addresses in DST")); add(new dropRuleWithEmptyRE("drop rules with empty rule elements")); add(new DropIPv6RulesWithWarning( "drop ipv6 rules", "Rule has been suppressed because it contains IPv6 " "objects and Firewall Builder does not support IPv6 " "routing rules at this time")); add(new validateNetwork("Validate network addresses")); add(new reachableAddressInRGtw( "Check if RGtw is reachable via local networks")); add(new contradictionRGtwAndRItf( "Check if RGtw is in a network of RItf")); add(new addressRangesInDst("process address ranges")); add(new eliminateDuplicatesInDST("Eliminate duplicates in DST")); add(new FindDefaultRoute("Find rules that install default route")); add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'competingRules'")); add(new competingRules("Check for competing rules")); add(new ConvertToAtomicForDST( "Convert to atomic rules by dst address elements")); add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'classifyRoutingRules'")); add(new classifyRoutingRules( "Classify into single path or part of a multi path rule")); add(new optimize3( "Eliminate duplicate rules generated from a single gui-rule")); add(new eliminateDuplicateRules( "Eliminate duplicate rules over the whole table")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add(new PrintRule("generate ip code")); add(new simplePrintProgress()); runRuleProcessors(); } string RoutingCompiler_ipt::debugPrintRule(Rule *r) { RoutingRule *rule=RoutingRule::cast(r); string s= RoutingCompiler::debugPrintRule(rule); return s; } void RoutingCompiler_ipt::epilog() { ///int total = ecmp_comments_buffer.size(); int nb = 0; // ecmp roules can only be generated after all the rules have been // parsed, that is the reason for putting this code in the epilog // function if (ecmp_rules_buffer.size() > 0) { output << "\n#\n# ============== EQUAL COST MULTI PATH ============\n#" << endl; output << "echo \"Activating ecmp routing rules...\"" << endl; for (map::iterator ecmp_comments_buffer_it = ecmp_comments_buffer.begin(); ecmp_comments_buffer_it != ecmp_comments_buffer.end(); ++ecmp_comments_buffer_it) { output << ecmp_comments_buffer_it->second << "#\n" << flush; output << ecmp_rules_buffer[ecmp_comments_buffer_it->first] << flush; output << " \\\n|| route_command_error " << "\"" << ++nb << "\"" << endl; //echo \"Error: The ECMP routing rule #" << ++nb <<" couldn't be activated! Please make sure your kernel is compiled with the CONFIG_IP_ROUTE_MULTIPATH option.\"" << endl; } } if (!inSingleRuleCompileMode() && defined_restore_script_output) { // function restore_script_output may not be defined if we // have no rules or all rules are disabled output << endl; output << "restore_script_output" << endl; output << "echo \"...done.\"" << endl; } } fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_PrintRule.cpp0000644000175000017500000016535711733011756024533 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Network.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Inet6AddrMask.h" #include "combinedAddress.h" #include "Configlet.h" #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ string PolicyCompiler_ipt::PrintRule::_printSingleObjectNegation( RuleElement *rel) { if (rel->getBool("single_object_negation")) return "! "; else return ""; } /* * Prints single --option with argument and negation "!" * taking into account the change that happened in iptables 1.4.3.1 * that causes warning * Using intrapositioned negation (`--option ! this`) is deprecated in favor of extrapositioned (`! --option this`). */ string PolicyCompiler_ipt::PrintRule::_printSingleOptionWithNegation( const string &option, RuleElement *rel, const string &arg) { ostringstream ostr; if (XMLTools::version_compare(version, "1.4.3")>=0) { ostr << _printSingleObjectNegation(rel); ostr << option << " "; ostr << arg << " "; } else { ostr << option << " "; ostr << _printSingleObjectNegation(rel); ostr << arg << " "; } return ostr.str(); } void PolicyCompiler_ipt::PrintRule::initializeMinusNTracker() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); for (list::const_iterator i = PolicyCompiler_ipt::getStandardChains().begin(); i != PolicyCompiler_ipt::getStandardChains().end(); ++i) { (*(ipt_comp->minus_n_commands))[*i] = true; } minus_n_tracker_initialized = true; } /* * check and create new chain if needed */ string PolicyCompiler_ipt::PrintRule::_createChain(const string &chain) { string res; PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); if (!minus_n_tracker_initialized) initializeMinusNTracker(); if ( ipt_comp->minus_n_commands->count(chain)==0 ) { res = string((ipt_comp->ipv6) ? "$IP6TABLES -N " : "$IPTABLES -N ") + chain; if (ipt_comp->my_table != "filter") res += " -t " + ipt_comp->my_table; res += "\n"; (*(ipt_comp->minus_n_commands))[chain] = true; } return res; } string PolicyCompiler_ipt::PrintRule::_startRuleLine() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); string res = (ipt_comp->ipv6) ? "$IP6TABLES " : "$IPTABLES "; if (ipt_comp->my_table != "filter") res += "-t " + ipt_comp->my_table + " "; res += "-A "; return res; } string PolicyCompiler_ipt::PrintRule::_endRuleLine() { return string("\n"); } string PolicyCompiler_ipt::PrintRule::_printRuleLabel(PolicyRule *rule) { ostringstream res; bool nocomm = Resources::os_res[compiler->fw->getStr("host_OS")]-> Resources::getResourceBool( "/FWBuilderResources/Target/options/suppress_comments"); // TODO: convert this into virtual function PolicyCompiler_ipt::printComment() string rl=rule->getLabel(); if (rl != current_rule_label) { if (!compiler->inSingleRuleCompileMode()) { if (!nocomm) { res << "# " << endl; res << "# Rule " << rl << endl; res << "# " << endl; } res << "echo " << _quote(string("Rule ")+rl) << endl; res << "# " << endl; } /* do not put comment in the script if it is intended for linksys */ if (!nocomm || compiler->inSingleRuleCompileMode()) { QStringList comm = QString(rule->getComment().c_str()).split("\n", QString::SkipEmptyParts); foreach(QString line, comm) { res << "# " << line.toStdString() << endl; } //res << "# " << endl; string err = compiler->getErrorsForRule(rule, "# "); if (!err.empty()) res << err << endl; } } current_rule_label = rl; // string err = rule->getCompilerMessage(); // if (!err.empty()) res << "# " << err << endl; return res.str(); } /** *----------------------------------------------------------------------- */ string PolicyCompiler_ipt::PrintRule::_printChain(PolicyRule *rule) { string s = rule->getStr("ipt_chain"); if (s.empty()) s = "UNKNOWN"; // check chain name length per bug report #2507239 if (s.length() > 30) { ostringstream str; str << "Chain name '" << s << "' "; str << "is longer than 30 characters. Rule " << rule->getLabel(); compiler->abort(rule, str.str()); } s= s + " "; return s; } string PolicyCompiler_ipt::PrintRule::_printModules(PolicyRule *rule) { std::ostringstream ostr; string target=rule->getStr("ipt_target"); if (target.empty()) target="UNKNOWN"; FWOptions *ruleopt =rule->getOptionsObject(); int lim = 0; /* * Here is what do we do with limits: * * Limit set globally in 'Firewall' tab of the firewall dialog * applies only to logging * * Limit set in the rule options dialog applies only to this * rule's target. * * this is so as of 1.0.11 ( 28/06/03 ) --vk */ if (target=="LOG") { FWOptions *compopt=compiler->getCachedFwOpt(); if ((lim=compopt->getInt("limit_value"))>0) { ostr << " -m limit --limit " << lim; string ls=compopt->getStr("limit_suffix"); if (!ls.empty()) ostr << ls; int lb=compopt->getInt("limit_burst"); if (lb>0) ostr << " --limit-burst " << lb; } } else { if (ruleopt!=NULL && (lim=ruleopt->getInt("limit_value"))>0) { if (ruleopt->getBool("limit_value_not")) ostr << " -m limit \\! --limit " << lim; else ostr << " -m limit --limit " << lim; string ls=ruleopt->getStr("limit_suffix"); if (!ls.empty()) ostr << ls; int lb=ruleopt->getInt("limit_burst"); if (lb>0) ostr << " --limit-burst " << lb; } } if (ruleopt!=NULL && (lim=ruleopt->getInt("connlimit_value"))>0) { if (ruleopt->getBool("connlimit_above_not")) ostr << " -m connlimit \\! --connlimit-above " << lim; else ostr << " -m connlimit --connlimit-above " << lim; int ml=ruleopt->getInt("connlimit_masklen"); if (ml>0) ostr << " --connlimit-mask " << ml; } if (ruleopt!=NULL && (lim=ruleopt->getInt("hashlimit_value"))>0) { string module_name = "hashlimit"; if (ruleopt->getBool("hashlimit_dstlimit")) module_name = "dstlimit"; ostr << " -m " << module_name << " --" << module_name << " " << lim; string ls = ruleopt->getStr("hashlimit_suffix"); if (!ls.empty()) ostr << ls; int lb=ruleopt->getInt("hashlimit_burst"); if (lb>0) ostr << " --" << module_name << "-burst " << lb; ls = ruleopt->getStr("hashlimit_mode"); if (ls.empty()) { /* syntax "--hashlimit-mode srcip,srcport " (i.e. with options separated by commas) tested with iptables 1.3.6 */ QStringList opts; bool f; f = ruleopt->getBool("hashlimit_mode_srcip"); if (f) opts.push_back("srcip"); f = ruleopt->getBool("hashlimit_mode_dstip"); if (f) opts.push_back("dstip"); f = ruleopt->getBool("hashlimit_mode_srcport"); if (f) opts.push_back("srcport"); f = ruleopt->getBool("hashlimit_mode_dstport"); if (f) opts.push_back("dstport"); if (!opts.isEmpty()) ostr << " --" << module_name << "-mode " << opts.join(",").toStdString(); } else // hashlimit_mode is v2.1 option. In v3 we have options // hashlimit_mode_srcip // hashlimit_mode_dstip // hashlimit_mode_srcport // hashlimit_mode_dstport ostr << " --" << module_name << "-mode " << ls; string hl_name = ruleopt->getStr("hashlimit_name"); if (hl_name.empty()) { std::ostringstream hn; hn << "htable_rule_" << rule->getPosition(); hl_name = hn.str(); } ostr << " --" << module_name << "-name " << hl_name; int arg = ruleopt->getInt("hashlimit_size"); if (arg>0) ostr << " --" << module_name << "-htable-size " << arg; arg = ruleopt->getInt("hashlimit_max"); if (arg>0) ostr << " --" << module_name << "-htable-max " << arg; arg = ruleopt->getInt("hashlimit_expire"); if (arg>0) ostr << " --" << module_name << "-htable-expire " << arg; arg = ruleopt->getInt("hashlimit_gcinterval"); if (arg>0) ostr << " --" << module_name << "-htable-gcinterval " << arg; } return ostr.str(); } string PolicyCompiler_ipt::PrintRule::_printTarget(PolicyRule *rule) { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); std::ostringstream ostr; string target=rule->getStr("ipt_target"); if (target.empty()) target="UNKNOWN"; FWOptions *ruleopt =rule->getOptionsObject(); if (rule->getTagging()) { ostr << " -j MARK"; ostr << " --set-mark " << rule->getTagValue(); return ostr.str(); } if (rule->getClassification()) { ostr << " -j CLASSIFY"; ostr << " --set-class " << ruleopt->getStr("classify_str"); return ostr.str(); } if (rule->getRouting()) { ostr << " -j ROUTE"; string a; a = ruleopt->getStr("ipt_iif"); if (!a.empty()) ostr << " --iif " << a; a = ruleopt->getStr("ipt_oif"); if (!a.empty()) ostr << " --oif " << a; a = ruleopt->getStr("ipt_gw"); if (!a.empty()) ostr << " --gw " << a; bool c = ruleopt->getBool("ipt_continue"); if (c) ostr << " --continue"; c = ruleopt->getBool("ipt_tee"); if (c) ostr << " --tee"; return ostr.str(); } if (target==".CUSTOM") { ostr << " " << ruleopt->getStr("custom_str"); return ostr.str(); } if (target==".CONTINUE") // not a real target ! return ostr.str(); // there is no ULOG for ip6tables yet if (!ipt_comp->ipv6 && compiler->getCachedFwOpt()->getBool("use_ULOG") && target=="LOG") target="ULOG"; ostr << " -j " << target << " "; if (target=="REJECT") ostr << _printActionOnReject(rule); if (target=="LOG" || target=="ULOG") ostr << _printLogParameters(rule); if (target=="CONNMARK") { ostr << ruleopt->getStr("CONNMARK_arg"); } return ostr.str(); } string PolicyCompiler_ipt::PrintRule::_printMultiport(PolicyRule *rule) { RuleElementSrv *srvrel=rule->getSrv(); string s; if(srvrel->size()>1 && rule->getBool("ipt_multiport")) s= " -m multiport "; return s; } string PolicyCompiler_ipt::PrintRule::_printDirectionAndInterface(PolicyRule *rule) { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); QStringList res; if (rule->getStr(".iface") == "nil") return ""; RuleElementItf *itfrel = rule->getItf(); QString iface_name; FWObject *rule_iface_obj = NULL; Interface *rule_iface = NULL; if ( ! itfrel->isAny()) { rule_iface_obj = FWObjectReference::getObject(itfrel->front()); rule_iface = Interface::cast(rule_iface_obj); iface_name = rule_iface_obj->getName().c_str(); if (iface_name.endsWith("*")) iface_name.replace("*", "+"); if (rule_iface && rule_iface->isBridgePort() && (version.empty() || XMLTools::version_compare(version, "1.3.0")>=0)) { /* http://www.netfilter.org/projects/iptables/files/changes-iptables-1.2.9.txt See SF bug #3439613 https://sourceforge.net/tracker/index.php?func=detail&aid=3439613&group_id=5314&atid=1129518# physdev module does not allow --physdev-out for non-bridged traffic anymore. We should add --physdev-is-bridged to make sure this matches only bridged packets. Also, adding "-i" / "-o" clause to match parent bridge interface. This allows us to correctly match which bridge the packet comes through in configurations using wildcard bridge port interfaces. For example, when br0 and br1 have "vnet+" bridge port interface, iptables can still correctly match which bridge the packet went through using "-o br0" or "-o br1" clause. This can be useful in installations with many bridged interfaces that get created and destroyed dynamically, e.g. with virtual machines. However add "-i br0" / "-o br0" only when there is more than one bridge interface _and_ bridge port name ends with a wild card symbol "+" */ QString parent_name = rule_iface->getParent()->getName().c_str(); if (rule->getDirection()==PolicyRule::Inbound) { if (ipt_comp->bridge_count > 1 && iface_name.endsWith("+")) res << "-i" << parent_name; res << "-m physdev --physdev-in" << iface_name; } if (rule->getDirection()==PolicyRule::Outbound) { if (ipt_comp->bridge_count > 1 && iface_name.endsWith("+")) res << "-o" << parent_name; res << "-m physdev --physdev-is-bridged --physdev-out" << iface_name; } } else { if (rule->getDirection()==PolicyRule::Inbound) res << _printSingleOptionWithNegation( "-i", itfrel, iface_name.toStdString()).c_str(); if (rule->getDirection()==PolicyRule::Outbound) res << _printSingleOptionWithNegation( "-o", itfrel, iface_name.toStdString()).c_str(); } res << ""; } return res.join(" ").toStdString(); } string PolicyCompiler_ipt::PrintRule::_printActionOnReject(PolicyRule *rule) { std::ostringstream str; PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); // RuleElementSrv *srvrel=rule->getSrv(); Service *srv = compiler->getFirstSrv(rule); assert(srv); string s = ipt_comp->getActionOnReject(rule); if (!s.empty()) { if (ipt_comp->isActionOnRejectTCPRST(rule)) str << " --reject-with tcp-reset"; if (s.find("ICMP")!=string::npos) { if (ipt_comp->ipv6) { if (s.find("unreachable")!=string::npos) { if (s.find("net")!=string::npos || s.find("host")!=string::npos) str << " --reject-with icmp6-addr-unreachable"; if (s.find("port")!=string::npos || s.find("proto")!=string::npos) str << " --reject-with icmp6-port-unreachable"; } if (s.find("prohibited")!=string::npos) { str << " --reject-with icmp6-adm-prohibited"; } } else { if (s.find("unreachable")!=string::npos) { if (s.find("net")!=string::npos) str << " --reject-with icmp-net-unreachable"; if (s.find("host")!=string::npos) str << " --reject-with icmp-host-unreachable"; if (s.find("port")!=string::npos) str << " --reject-with icmp-port-unreachable"; if (s.find("proto")!=string::npos) str << " --reject-with icmp-proto-unreachable"; } if (s.find("prohibited")!=string::npos) { if (s.find("net")!=string::npos) str << " --reject-with icmp-net-prohibited"; if (s.find("host")!=string::npos) str << " --reject-with icmp-host-prohibited"; if (XMLTools::version_compare(version, "1.2.9")>=0 && s.find("admin")!=string::npos) str << " --reject-with icmp-admin-prohibited"; } } } } str << " "; return str.str(); } string PolicyCompiler_ipt::PrintRule::_printGlobalLogParameters() { return _printLogParameters(NULL); } string PolicyCompiler_ipt::PrintRule::_printLogPrefix(const string &rule_num, const string &action, const string &interf, const string &chain, const string &ruleset, const string& , const string &prefix) { string s = prefix; /* deal with our logging macros: * %N - rule number ('2', or '2/3' for rule in a branch) * %A - action * %I - interface name * %C - chain name * %R - ruleset name */ string::size_type n; if ((n=s.find("%N"))!=string::npos ) { s.replace(n, 2, rule_num); } if ((n=s.find("%A"))!=string::npos ) { s.replace(n, 2, action); } if ((n=s.find("%I"))!=string::npos ) { s.replace(n, 2, interf); } if ((n=s.find("%C"))!=string::npos ) { s.replace(n, 2, chain); } if ((n=s.find("%R"))!=string::npos ) { s.replace(n, 2, ruleset); } if (s.length()>29) { compiler->warning( "Log prefix has been truncated to 29 characters"); s=s.substr(0,29); } return _quote( s ); } string PolicyCompiler_ipt::PrintRule::_printLogPrefix(PolicyRule *rule, const string &prefix) { FWObject *ruleset = rule->getParent(); QString action = QString(rule->getStr("stored_action").c_str()).toUpper(); RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); FWObject *rule_iface = FWObjectReference::getObject(itf_re->front()); string rule_iface_name = rule_iface->getName(); if (rule_iface_name=="") rule_iface_name = "global"; if (rule_iface_name=="Any") rule_iface_name = "global"; std::ostringstream s1; int pos = rule->getPosition(); // parent_rule_num is set by processor "Branching" for branch rules string ppos = rule->getStr("parent_rule_num"); if (ppos != "") s1 << ppos << "/"; s1 << pos; return _printLogPrefix(s1.str(), action.toStdString(), rule_iface_name, rule->getStr("ipt_chain"), ruleset->getName(), rule->getLabel(), prefix); } string PolicyCompiler_ipt::PrintRule::_printLogParameters(PolicyRule *rule) { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); std::ostringstream str; string s; FWOptions *ruleopt = (rule!=NULL) ? rule->getOptionsObject() : compiler->getCachedFwOpt(); // there is no ULOG for ip6tables yet bool use_ulog = (!ipt_comp->ipv6 && compiler->getCachedFwOpt()->getBool("use_ULOG")); if (use_ulog) { s=ruleopt->getStr("ulog_nlgroup"); if (s.empty()) s=compiler->getCachedFwOpt()->getStr("ulog_nlgroup"); if (!s.empty()) str << " --ulog-nlgroup " << s; s=ruleopt->getStr("log_prefix"); if (s.empty()) s=compiler->getCachedFwOpt()->getStr("log_prefix"); if (!s.empty()) str << " --ulog-prefix " << _printLogPrefix(rule, s); int r=compiler->getCachedFwOpt()->getInt("ulog_cprange"); if (r!=0) str << " --ulog-cprange " << r << " "; r=compiler->getCachedFwOpt()->getInt("ulog_qthreshold"); if (r!=0) str << " --ulog-qthreshold " << r << " "; } else { bool numeric_levels; numeric_levels=compiler->getCachedFwOpt()->getBool("use_numeric_log_levels"); s=ruleopt->getStr("log_level"); if (s.empty()) s=compiler->getCachedFwOpt()->getStr("log_level"); if (!s.empty()) { if ( numeric_levels ) { if (s=="alert") s="1"; if (s=="crit") s="2"; if (s=="error") s="3"; if (s=="warning") s="4"; if (s=="notice") s="5"; if (s=="info") s="6"; if (s=="debug") s="7"; } str << " --log-level " << s; } s=ruleopt->getStr("log_prefix"); if (s.empty()) s=compiler->getCachedFwOpt()->getStr("log_prefix"); if (!s.empty()) str << " --log-prefix " << _printLogPrefix(rule, s); if (ruleopt->getBool("log_tcp_seq") || compiler->getCachedFwOpt()->getBool("log_tcp_seq")) str << " --log-tcp-sequence "; if (ruleopt->getBool("log_tcp_opt") || compiler->getCachedFwOpt()->getBool("log_tcp_opt")) str << " --log-tcp-options "; if (ruleopt->getBool("log_ip_opt") || compiler->getCachedFwOpt()->getBool("log_ip_opt")) str << " --log-ip-options "; } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printLimit(libfwbuilder::PolicyRule *rule) { std::ostringstream str; string s; int l, lb; FWOptions *ruleopt =rule->getOptionsObject(); FWOptions *compopt =compiler->getCachedFwOpt(); if ( (ruleopt!=NULL && (l=ruleopt->getInt("limit_value"))>0) || (l=compopt->getInt("limit_value"))>0 ) { str << " -m limit --limit " << l; if (ruleopt!=NULL) s=ruleopt->getStr("limit_suffix"); if (s.empty()) s=compopt->getStr("limit_suffix"); if (!s.empty()) str << s; lb=-1; if (ruleopt!=NULL) lb=ruleopt->getInt("limit_burst"); if (lb<0) lb=compopt->getInt("limit_burst"); if (lb>0) str << " --limit-burst " << lb; } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printProtocol(Service *srv) { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); string s; // CustomService returns protocol name starting with v3.0.4 // However CustomService can return protocol name "any", which we should // just skip. if (CustomService::isA(srv)) { // check if the code string for this custom service already includes // "-p proto" fragment string code = CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName()); std::size_t minus_p = code.find("-p "); if (minus_p != string::npos) return ""; string pn = srv->getProtocolName(); if (pn == "any") return ""; } if (!srv->isAny() && !TagService::isA(srv) && !UserService::isA(srv)) { string pn = srv->getProtocolName(); if (pn=="ip" || pn=="any") pn = "all"; if (ipt_comp->ipv6) { if (ICMPService::isA(srv)) { compiler->abort( "Can not use ICMPService in ipv6 rule; " "use ICMP6Service object instead"); } if (ICMP6Service::isA(srv)) { s = "-p ipv6-icmp "; if (srv->getInt("type")!=-1 && (version.empty() || XMLTools::version_compare(version, "1.3.0")>=0)) s += " -m icmp6"; } else { // ip6tables issues warning for commands using "-p all" // Warning: never matched protocol: all. use exension match instead // Skip "-p all" if ipv6 if (pn!="all") s = "-p " + pn + " "; } } else { if (ICMP6Service::isA(srv)) { compiler->abort( "Can not use ICMP6Service in ipv4 rule; " "use ICMPService object instead"); } if (ICMPService::isA(srv)) { s = "-p icmp "; if (version.empty() || XMLTools::version_compare(version, "1.2.9")>=0) s += " -m icmp "; } else { s = "-p " + pn + " "; } } if (pn == "tcp") s += "-m tcp "; if (pn == "udp") s += "-m udp "; } return s; } string PolicyCompiler_ipt::PrintRule::_printPorts(int rs,int re) { std::ostringstream str; compiler->normalizePortRange(rs,re); if (rs>0 || re>0) { if (rs==re) str << rs; else if (rs==0 && re!=0) str << ":" << re; else str << rs << ":" << re; } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printSrcPorts(Service *srv) { std::ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getSrcRangeStart(); int re = TCPUDPService::cast(srv)->getSrcRangeEnd(); str << _printPorts(rs,re); } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printDstPorts(Service *srv) { std::ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getDstRangeStart(); int re = TCPUDPService::cast(srv)->getDstRangeEnd(); str << _printPorts(rs,re); } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printICMP(ICMPService *srv) { std::ostringstream str; if (ICMPService::cast(srv) && srv->getInt("type")!=-1) { str << srv->getStr("type"); if (srv->getInt("code")!=-1) str << "/" << srv->getStr("code") << " "; } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printIP(IPService *srv, PolicyRule *rule) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); std::ostringstream str; if (srv->getBool("fragm") || srv->getBool("short_fragm")) { if (ipt_comp->ipv6) str << " -m frag --fragmore"; else str << " -f "; } string tos = srv->getTOSCode(); string dscp = srv->getDSCPCode(); if (!tos.empty()) str << " -m tos --tos " << tos; else if (!dscp.empty()) { if (dscp.find("BE")==0 || dscp.find("EF")==0 || dscp.find("AF")==0 || dscp.find("CS")==0) str << " -m dscp --dscp-class " << dscp; else str << " -m dscp --dscp " << dscp; } if (srv->hasIpOptions()) { if (!ipt_comp->ipv6) { str << " -m ipv4options "; if (version.empty() || XMLTools::version_compare(version, "1.4.3")<0) { // "old" ipv4options module if (srv->getBool("any_opt")) str << " --any-opt"; else { if (srv->getBool("lsrr")) str << " --lsrr"; if (srv->getBool("ssrr")) str << " --ssrr"; if (srv->getBool("rr")) str << " --rr"; if (srv->getBool("ts")) str << " --ts"; if (srv->getBool("rtralt")) str << " --ra"; } } else { // "new" ipv4options module if (srv->getBool("any_opt")) str << " --any"; else { QStringList options; if (srv->getBool("lsrr")) options << "lsrr"; if (srv->getBool("ssrr")) options << "ssrr"; if (srv->getBool("rr")) options << "record-route"; if (srv->getBool("ts")) options << "timestamp"; if (srv->getBool("rtralt")) options << "router-alert"; if (options.size() > 0) str << " --flags " << options.join(",").toStdString(); } } } else { compiler->abort( rule, "IP options match is not supported for IPv6."); } } return str.str(); } string PolicyCompiler_ipt::PrintRule::_printTCPFlags(libfwbuilder::TCPService *srv) { string str; if (srv->inspectFlags()) { TCPService::TCPFlag f1[2]={ TCPService::SYN }; TCPService::TCPFlag f2[7]={ TCPService::URG, TCPService::ACK, TCPService::PSH, TCPService::RST, TCPService::SYN, TCPService::FIN }; std::set none; std::set syn( f1, f1+1 ); std::set all_masks( f2 , f2+6 ); if (srv->getAllTCPFlags()==syn && srv->getAllTCPFlagMasks()==all_masks) str=" --tcp-flags SYN,RST,ACK SYN "; else { str=" --tcp-flags "; bool first=true; if (srv->getAllTCPFlagMasks()==all_masks) str+="ALL"; else { if (srv->getTCPFlagMask(TCPService::URG)) { if (!first) str+=","; str+="URG"; first=false; } if (srv->getTCPFlagMask(TCPService::ACK)) { if (!first) str+=","; str+="ACK"; first=false; } if (srv->getTCPFlagMask(TCPService::PSH)) { if (!first) str+=","; str+="PSH"; first=false; } if (srv->getTCPFlagMask(TCPService::RST)) { if (!first) str+=","; str+="RST"; first=false; } if (srv->getTCPFlagMask(TCPService::SYN)) { if (!first) str+=","; str+="SYN"; first=false; } if (srv->getTCPFlagMask(TCPService::FIN)) { if (!first) str+=","; str+="FIN"; first=false; } } str+=" "; if (srv->getAllTCPFlags()==none) str+="NONE"; else { first=true; if (srv->getTCPFlag(TCPService::URG)) { if (!first) str+=","; str+="URG"; first=false; } if (srv->getTCPFlag(TCPService::ACK)) { if (!first) str+=","; str+="ACK"; first=false; } if (srv->getTCPFlag(TCPService::PSH)) { if (!first) str+=","; str+="PSH"; first=false; } if (srv->getTCPFlag(TCPService::RST)) { if (!first) str+=","; str+="RST"; first=false; } if (srv->getTCPFlag(TCPService::SYN)) { if (!first) str+=","; str+="SYN"; first=false; } if (srv->getTCPFlag(TCPService::FIN)) { if (!first) str+=","; str+="FIN"; first=false; } } } } return str; } /* * we made sure that all services in rel represent the same protocol */ string PolicyCompiler_ipt::PrintRule::_printSrcService(RuleElementSrv *rel) { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); std::ostringstream ostr; /* I do not want to use rel->getFirst because it traverses the tree to * find the object. I'd rather use a cached copy in the compiler */ FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); if (rel->size()==1) { if (UDPService::isA(srv) || TCPService::isA(srv) || TagService::isA(srv)) { string str=_printSrcPorts( srv ); if (! str.empty() ) { ostr << _printSingleOptionWithNegation(" --sport", rel, str); } } } else { /* use multiport */ string str; bool first=true; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (UDPService::isA(srv) || TCPService::isA(srv)) { if (!first) str+=","; str+= _printSrcPorts( s ); if (!str.empty()) first=false; } } if ( !str.empty() ) { if (ipt_comp->newIptables(version)) ostr << " --sports "; else ostr << " --source-port "; ostr << str << " "; } } return ostr.str(); } string PolicyCompiler_ipt::PrintRule::_printDstService(RuleElementSrv *rel) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); std::ostringstream ostr; FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); if (rel->size()==1) { if (UDPService::isA(srv) || TCPService::isA(srv)) { string str=_printDstPorts( srv ); if (! str.empty() ) { ostr << _printSingleOptionWithNegation(" --dport", rel, str); } } if (TCPService::isA(srv)) { string str=_printTCPFlags(TCPService::cast(srv)); if (!str.empty()) { ostr << _printSingleOptionWithNegation("", rel, str); } } if (ICMPService::isA(srv) || ICMP6Service::isA(srv)) { string icmp_type_str = (ipt_comp->ipv6) ? " --icmpv6-type" : " --icmp-type"; string str = _printICMP( ICMPService::cast(srv) ); if (str.empty() ) { // module icmp6 does not like "--icmp6-type any" if ((version.empty() || XMLTools::version_compare(version, "1.2.6")>0) && !ipt_comp->ipv6) ostr << icmp_type_str << " any "; } else { ostr << _printSingleOptionWithNegation(icmp_type_str, rel, str); } } if (IPService::isA(srv)) { string str = _printIP(IPService::cast(srv), PolicyRule::cast(rel->getParent())); if (! str.empty() ) { ostr << _printSingleObjectNegation(rel) << str << " "; } } if (CustomService::isA(srv)) { ostr << _printSingleObjectNegation(rel) << " " << CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ) << " "; } if (TagService::isA(srv)) { ostr << "-m mark " << _printSingleObjectNegation(rel) << "--mark " << TagService::constcast(srv)->getCode() << " "; } if (UserService::isA(srv)) { ostr << "-m owner " << _printSingleObjectNegation(rel) << "--uid-owner " << UserService::cast(srv)->getUserId() << " "; } } else { /* use multiport */ string str; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (UDPService::isA(srv) || TCPService::isA(srv)) { string str1 = _printDstPorts( s ); if (str!="" && str1!="") str+=","; str+=str1; } } if ( !str.empty() ) { if (ipt_comp->newIptables(version)) ostr << " --dports "; else ostr << " --destination-port "; ostr << str << " "; } } return ostr.str(); } string PolicyCompiler_ipt::PrintRule::_printSrcAddr(RuleElement *rel, Address *o) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); string res; if (AddressRange::cast(o)!=NULL) { AddressRange *ar = AddressRange::cast(o); const InetAddr &range_start = ar->getRangeStart(); const InetAddr &range_end = ar->getRangeEnd(); if (range_start != range_end) { if (!have_m_iprange) { res = "-m iprange "; have_m_iprange = true; } res += _printSingleObjectNegation(rel) + "--src-range "; res += range_start.toString() + "-" + range_end.toString() + " "; } else res += "-s " + range_start.toString() + " "; return res; } MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME && ipt_comp->using_ipset) { return _printIpSetMatch(o, rel); } return _printSingleOptionWithNegation(" -s", rel, _printAddr(o)); } string PolicyCompiler_ipt::PrintRule::_printDstAddr(RuleElement *rel, Address *o) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); string res; if (AddressRange::cast(o)!=NULL) { AddressRange *ar = AddressRange::cast(o); const InetAddr &range_start = ar->getRangeStart(); const InetAddr &range_end = ar->getRangeEnd(); if (range_start != range_end) { if (!have_m_iprange) { res = "-m iprange "; have_m_iprange = true; } res += _printSingleObjectNegation(rel) + "--dst-range "; res += range_start.toString() + "-" + range_end.toString() + " "; } else res += "-d " + range_start.toString() + " "; return res; } MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME && ipt_comp->using_ipset) { return _printIpSetMatch(o, rel); } return _printSingleOptionWithNegation(" -d", rel, _printAddr(o)); } string PolicyCompiler_ipt::PrintRule::_printIpSetMatch(Address *o, RuleElement *rel) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); string set_name = dynamic_cast(ipt_comp->osconfigurator)->normalizeSetName(o->getName()); string suffix = "dst"; if (RuleElementSrc::isA(rel)) suffix = "src"; if (RuleElementDst::isA(rel)) suffix = "dst"; string set_match_option; if (XMLTools::version_compare(version, "1.4.4")>=0) set_match_option = "--match-set"; else set_match_option = "--set"; string set_match = set_match_option + " " + set_name + " " + suffix; ostringstream ostr; ostr << "-m set " << _printSingleOptionWithNegation("", rel, set_match); return ostr.str(); } string PolicyCompiler_ipt::PrintRule::_printAddr(Address *o) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); std::ostringstream ostr; MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { ostr << "$" << ipt_comp->getAddressTableVarName(atrt) << " "; return ostr.str(); } if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { return atrt->getSourceName(); } if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME) { ostr << "$i_" << atrt->getSourceName() << "_network"; return ostr.str(); } // at this time we only support two types of MultiAddress // objects: AddressTable and DNSName. Both should be converted // to MultiAddressRunTime at this point. If we get some other // kind of MultiAddressRunTime object, we do not know what to do // with it so we stop. assert(atrt==NULL); } if (Interface::cast(o)!=NULL) { Interface *iface=Interface::cast(o); if (iface->isDyn()) ostr << "$" << ipt_comp->getInterfaceVarName(iface, ipt_comp->ipv6) << " "; return ostr.str(); } const InetAddr *addr = o->getAddressPtr(); const InetAddr *mask = o->getNetmaskPtr(); if (addr==NULL) { compiler->warning( string("Empty inet address in object ") + o->getName() + "(" + FWObjectDatabase::getStringId(o->getId()) + ")"); return ostr.str(); } // Note that mask can be NULL, for example if o is AddressRange. if (addr->isAny() && (mask==NULL || mask->isAny())) { ostr << "0/0 "; } else { ostr << addr->toString(); if (Interface::cast(o)==NULL && Address::cast(o)->dimension() > 1 && !mask->isHostMask()) { ostr << "/" << mask->getLength(); } ostr << " "; } return ostr.str(); } string PolicyCompiler_ipt::PrintRule::_printTimeInterval(PolicyRule *r) { std::ostringstream ostr; RuleElementInterval* ri=r->getWhen(); if (ri==NULL || ri->isAny()) return ""; std::map daysofweek; daysofweek[0]="Sun"; daysofweek[1]="Mon"; daysofweek[2]="Tue"; daysofweek[3]="Wed"; daysofweek[4]="Thu"; daysofweek[5]="Fri"; daysofweek[6]="Sat"; daysofweek[7]="Sun"; int smin, shour, sday, smonth, syear, sdayofweek; int emin, ehour, eday, emonth, eyear, edayofweek; string days_of_week; Interval *interval = compiler->getFirstWhen(r); assert(interval!=NULL); interval->getStartTime( &smin, &shour, &sday, &smonth, &syear, &sdayofweek); interval->getEndTime( &emin, &ehour, &eday, &emonth, &eyear, &edayofweek); days_of_week = interval->getDaysOfWeek(); if (shour<0) shour=0; if (smin<0) smin=0; if (ehour<0) ehour=23; if (emin<0) emin=59; ostr << "-m time "; bool use_timestart_timestop = true; if (XMLTools::version_compare(version, "1.4.0")>=0) { /* in 1.4.0 date format has changed, it is now ISO 8601 * http://www.w3.org/TR/NOTE-datetime * * --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]] * * --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]] */ if (sday>0 && smonth>0 && syear>0) { ostr << "--datestart " << setw(2) << setfill('0') << syear << "-" << setw(2) << setfill('0') << smonth << "-" << setw(2) << setfill('0') << sday << "T" << setw(2) << setfill('0') << shour << ":" << setw(2) << setfill('0') << smin << ":00 "; use_timestart_timestop = false; } if (eday>0 && emonth>0 && eyear>0) { ostr << "--datestop " << setw(2) << setfill('0') << eyear << "-" << setw(2) << setfill('0') << emonth << "-" << setw(2) << setfill('0') << eday << "T" << setw(2) << setfill('0') << ehour << ":" << setw(2) << setfill('0') << emin << ":00 "; use_timestart_timestop = false; } if (use_timestart_timestop) { ostr << " --timestart " << setw(2) << setfill('0') << shour << ":" << setw(2) << setfill('0') << smin << " "; ostr << " --timestop " << setw(2) << setfill('0') << ehour << ":" << setw(2) << setfill('0') << emin << " "; } if (!days_of_week.empty() && days_of_week != "0,1,2,3,4,5,6") { ostr << " --weekdays "; istringstream istr(days_of_week); bool first= true; while (!istr.eof()) { if (!first) ostr << ','; first = false; int d; istr >> d; ostr << daysofweek[d]; char sep; istr >> sep; } } } else { /* "old" iptables time module TIME v1.2.11 options: --timestart value --timestop value --days listofdays timestart value : HH:MM timestop value : HH:MM listofdays value: a list of days to apply -> ie. Mon,Tue,Wed,Thu,Fri. Case sensitive */ ostr << " --timestart " << setw(2) << setfill('0') << shour << ":" << setw(2) << setfill('0') << smin << " "; ostr << " --timestop " << setw(2) << setfill('0') << ehour << ":" << setw(2) << setfill('0') << emin << " "; if (!days_of_week.empty() && days_of_week != "0,1,2,3,4,5,6") { ostr << " --days "; istringstream istr(days_of_week); bool first= true; while (!istr.eof()) { if (!first) ostr << ','; first = false; int d; istr >> d; ostr << daysofweek[d]; char sep; istr >> sep; } } } return ostr.str(); } PolicyCompiler_ipt::PrintRule::PrintRule(const std::string &name) : PolicyRuleProcessor(name) { init = true; print_once_on_top = true; // use delayed initialization for ipt_comp->minus_n_commands // because it requires pointer to the compiler which has not been // initialized yet when this constructor is executed. minus_n_tracker_initialized = false; } /* * Initialize some internal variables. Need to do this in a separate * method because pointer to the compiler object is set by * RuleProcessor::setContext and is not available in constructor. */ void PolicyCompiler_ipt::PrintRule::initialize() { // retrieve and save version for _printSingleOptionWithNegation and others version = compiler->fw->getStr("version"); } bool PolicyCompiler_ipt::PrintRule::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule =getNext(); if (rule==NULL) return false; string chain = rule->getStr("ipt_chain"); if (ipt_comp->chain_usage_counter[chain] > 0) { tmp_queue.push_back(rule); compiler->output << _printRuleLabel(rule); compiler->output << _createChain(rule->getStr("ipt_chain")); string target = rule->getStr("ipt_target"); if (target[0] != '.') compiler->output << _createChain(target); compiler->output << dynamic_cast( compiler->osconfigurator)->printRunTimeWrappers( rule, PolicyRuleToString(rule), ipt_comp->ipv6); } return true; } string PolicyCompiler_ipt::PrintRule::PolicyRuleToString(PolicyRule *rule) { FWOptions *ruleopt = rule->getOptionsObject(); FWObject *ref; RuleElementSrc *srcrel=rule->getSrc(); ref=srcrel->front(); Address *src=Address::cast(FWReference::cast(ref)->getPointer()); if(src==NULL) compiler->abort(rule, string("Broken SRC in ") + rule->getLabel()); RuleElementDst *dstrel=rule->getDst(); ref=dstrel->front(); Address *dst=Address::cast(FWReference::cast(ref)->getPointer()); if(dst==NULL) compiler->abort(rule, string("Broken DST in ") + rule->getLabel()); RuleElementSrv *srvrel=rule->getSrv(); ref=srvrel->front(); Service *srv=Service::cast(FWReference::cast(ref)->getPointer()); if(srv==NULL) compiler->abort(rule, string("Broken SRV in ") + rule->getLabel()); std::ostringstream command_line; have_m_iprange = false; command_line << _startRuleLine(); command_line << _printChain(rule); command_line << _printDirectionAndInterface(rule); command_line << _printProtocol(srv); command_line << _printMultiport(rule); if (!src->isAny()) { if (physAddress::isA(src) || combinedAddress::isA(src)) { string physaddress = ""; if (physAddress::isA(src)) { physaddress = physAddress::cast(src)->getPhysAddress(); if (physaddress.empty()) { compiler->warning( rule, "Empty MAC address in rule"); physaddress = "00:00:00:00:00:00"; } } if (combinedAddress::isA(src)) physaddress = combinedAddress::cast(src)->getPhysAddress(); /* physAddress component of combinedAddress can be empty. For example * this happens when an object with both IP and MAC addresses is found * in "source" and rule is determined to go into OUTPUT chain. On the * other hand, if physAddress object has no MAC address, it is always * an error. */ if (!physaddress.empty()) { command_line << " -m mac"; command_line << _printSingleOptionWithNegation(" --mac-source", srcrel, physaddress); } /* * fool-proof: this is last resort check for situation when user * created IPv4 object for the interface but left it with empty * address ( 0.0.0.0 ). * * note that combinedAddress inherits IPv4 and therefore * combinedAddress::hasInetAddress returns true; * */ if (src->hasInetAddress() && !src->getAddressPtr()->isAny()) command_line << _printSrcAddr(srcrel, src); } else command_line << _printSrcAddr(srcrel, src); } command_line << _printSrcService(srvrel); if (!dst->isAny()) command_line << _printDstAddr(dstrel, dst); command_line << _printDstService(srvrel); /* keeping state does not apply to deny/reject however some rules need state check even if action is Deny autoupgrade transformation 2.1.11 -> 2.1.12 adds rule option 'stateless=True' for rules with action NOT 'Accept', 'Tag' or 'Route'. No need to check action here, just rely on this option and internal flag 'force_state_check' (05/07/07 --vk) */ if (!ruleopt->getBool("stateless") || rule->getBool("force_state_check") ) { /* * But not, when the line already contains a state matching */ if (command_line.str().find("-m state --state", 0) == string::npos) command_line << " -m state --state NEW "; } command_line << _printTimeInterval(rule); command_line << _printModules(rule); command_line << _printTarget(rule); command_line << _endRuleLine(); // command_line << endl; return command_line.str(); } string PolicyCompiler_ipt::PrintRule::_declareTable() { return ""; } string PolicyCompiler_ipt::PrintRule::_commit() { return ""; } string PolicyCompiler_ipt::PrintRule::_clampTcpToMssRule() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); ostringstream res; if ( compiler->getCachedFwOpt()->getBool("clamp_mss_to_mtu")) { bool ipforw; if (ipt_comp->ipv6) { string s = compiler->getCachedFwOpt()->getStr("linux24_ipv6_forward"); ipforw = (s.empty() || s=="1" || s=="On" || s=="on"); // bug #2477775: target TCPMSS is not available in ip6tables // before 1.4.0 In fact I am not sure of the minimal required // version. According to the netfilter git log, it was added in // 1.3.8 if (XMLTools::version_compare(version, "1.3.8")<0) { if (ipforw) { res << "target TCPMSS is not supported by ip6tables before v1.3.8"; compiler->warning(res.str()); return "# " + res.str() + "\n\n"; } else return ""; } } else { string s = compiler->getCachedFwOpt()->getStr("linux24_ip_forward"); ipforw = (s.empty() || s=="1" || s=="On" || s=="on"); } if (ipforw) { res << _startRuleLine() << "FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" << _endRuleLine(); res << endl; } } return res.str(); } string PolicyCompiler_ipt::PrintRule::_printOptionalGlobalRules() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); ostringstream res; bool isIPv6 = ipt_comp->ipv6; string s = compiler->getCachedFwOpt()->getStr("linux24_ip_forward"); bool ipforward= (s.empty() || s=="1" || s=="On" || s=="on"); s = compiler->getCachedFwOpt()->getStr("linux24_ipv6_forward"); bool ip6forward= (s.empty() || s=="1" || s=="On" || s=="on"); bool ipforw = ((!ipt_comp->ipv6 && ipforward) || (ipt_comp->ipv6 && ip6forward)); Configlet configlet(compiler->fw, "linux24", "automatic_rules"); configlet.removeComments(); configlet.collapseEmptyStrings(true); configlet.setVariable("begin_rule", _startRuleLine().c_str()); configlet.setVariable("end_rule", _endRuleLine().c_str()); configlet.setVariable("ipforw", ipforw); configlet.setVariable("accept_established", compiler->getCachedFwOpt()->getBool("accept_established") && ipt_comp->my_table=="filter"); list ll = compiler->fw->getByTypeDeep(Interface::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { Interface *intf = Interface::cast( *i ); if (intf->isManagement()) { configlet.setVariable("management_interface", intf->getName().c_str()); break; } } _printBackupSSHAccessRules(&configlet); configlet.setVariable( "drop_new_tcp_with_no_syn", ! compiler->getCachedFwOpt()->getBool("accept_new_tcp_with_no_syn")); configlet.setVariable( "bridging_firewall", compiler->getCachedFwOpt()->getBool("bridging_fw")); configlet.setVariable( "add_rules_for_ipv6_neighbor_discovery", isIPv6 && compiler->getCachedFwOpt()->getBool("add_rules_for_ipv6_neighbor_discovery")); configlet.setVariable("drop_invalid", compiler->getCachedFwOpt()->getBool("drop_invalid") && !compiler->getCachedFwOpt()->getBool("log_invalid")); configlet.setVariable("drop_invalid_and_log", compiler->getCachedFwOpt()->getBool("drop_invalid") && compiler->getCachedFwOpt()->getBool("log_invalid")); configlet.setVariable("create_drop_invalid_chain", _createChain("drop_invalid").c_str()); if (compiler->getCachedFwOpt()->getBool("log_invalid") && !isIPv6 && compiler->getCachedFwOpt()->getBool("use_ULOG")) { configlet.setVariable("use_ulog", 1); string s = compiler->getCachedFwOpt()->getStr("ulog_nlgroup"); configlet.setVariable("use_nlgroup", !s.empty()); configlet.setVariable("nlgroup", s.c_str()); int r = compiler->getCachedFwOpt()->getInt("ulog_cprange"); configlet.setVariable("use_cprange", r!=0); configlet.setVariable("cprange", r); r = compiler->getCachedFwOpt()->getInt("ulog_qthreshold"); configlet.setVariable("use_qthreshold", r!=0); configlet.setVariable("qthreshold", r); } else configlet.setVariable("not_use_ulog", 1); configlet.setVariable("invalid_match_log_prefix", _printLogPrefix("-1", "DENY", "global", "drop_invalid", "Policy", "BLOCK INVALID", "INVALID state -- DENY ").c_str()); return configlet.expand().toStdString(); } void PolicyCompiler_ipt::PrintRule::_printBackupSSHAccessRules(Configlet *conf) { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); bool isIPv6 = ipt_comp->ipv6; if ( compiler->getCachedFwOpt()->getBool("mgmt_ssh") && ! compiler->getCachedFwOpt()->getStr("mgmt_addr").empty() ) { string addr_str = compiler->getCachedFwOpt()->getStr("mgmt_addr"); InetAddrMask *inet_addr = NULL; bool addr_is_good = true; if (isIPv6) { // check if given address is ipv6 try { inet_addr = new Inet6AddrMask(addr_str); } catch(const FWException &ex) { // address does not parse as ipv6, skip this rule. addr_is_good = false; QString err("Backup ssh access rule could not be added " "to IPv6 policy because specified address " "'%1' is invalid"); compiler->warning(err.arg(addr_str.c_str()).toStdString()); } } else { // check if given address parses as ipv4 try { inet_addr = new InetAddrMask(addr_str); } catch(const FWException &ex) { // address does not parse addr_is_good = false; QString err("Backup ssh access rule could not be added " "to IPv4 policy because specified address " "'%1' is invalid"); compiler->warning(err.arg(addr_str.c_str()).toStdString()); } } if (addr_is_good) { conf->setVariable("begin_rule", _startRuleLine().c_str()); conf->setVariable("end_rule", _endRuleLine().c_str()); conf->setVariable("mgmt_access", 1); conf->setVariable("ssh_management_address", inet_addr->toString().c_str()); } } } string PolicyCompiler_ipt::PrintRule::_quote(const string &s) { return "\"" + s + "\""; } fwbuilder-5.1.0.3599/src/iptlib/CompilerDriver_ipt_policy.cpp0000644000175000017500000002355611733011756024750 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "CompilerDriver_ipt.h" #include "MangleTableCompiler_ipt.h" #include "PolicyCompiler_ipt.h" #include "PolicyCompiler_secuwall.h" #include "OSConfigurator_linux24.h" #include "Configlet.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Library.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; // we always first process all non-top rule sets, then all top rule // sets bool CompilerDriver_ipt::processPolicyRuleSet( Firewall *fw, FWObject *ruleset, const string &single_rule_id, ostringstream &filter_rules_stream, ostringstream &mangle_rules_stream, ostringstream &automatic_rules_stream, ostringstream &automatic_mangle_stream, OSConfigurator_linux24 *oscnf, int policy_af, std::map &minus_n_commands_filter, std::map &minus_n_commands_mangle) { int policy_rules_count = 0; int mangle_rules_count = 0; bool empty_output = true; string prolog_place = fw->getOptionsObject()->getStr("prolog_place"); string platform = fw->getStr("platform"); string host_os = fw->getStr("host_OS"); bool flush_and_set_default_policy = Resources::getTargetOptionBool( host_os, "default/flush_and_set_default_policy"); string platform_family = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/family"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); Policy *policy = Policy::cast(ruleset); assignRuleSetChain(policy); string branch_name = policy->getName(); if (!policy->matchingAddressFamily(policy_af)) return true; bool ipv6_policy = (policy_af == AF_INET6); std::auto_ptr mangle_compiler( new MangleTableCompiler_ipt(objdb , fw, ipv6_policy , oscnf, &minus_n_commands_mangle )); if (!policy->isTop()) mangle_compiler->registerRuleSetChain(branch_name); mangle_compiler->setSourceRuleSet( policy ); mangle_compiler->setRuleSetName(branch_name); mangle_compiler->setPersistentObjects(persistent_objects); mangle_compiler->setSingleRuleCompileMode(single_rule_id); mangle_compiler->setDebugLevel( dl ); if (rule_debug_on) mangle_compiler->setDebugRule( drp ); mangle_compiler->setVerbose( (bool)(verbose) ); mangle_compiler->setHaveDynamicInterfaces(have_dynamic_interfaces); if (inTestMode()) mangle_compiler->setTestMode(); if (inEmbeddedMode()) mangle_compiler->setEmbeddedMode(); if ( (mangle_rules_count = mangle_compiler->prolog()) > 0 ) { mangle_compiler->compile(); mangle_compiler->epilog(); // We need to generate automatic rules in mangle // table (-j CONNMARK --restore-mark) if CONNMARK // target is present in any ruleset, not only in // the top-level ruleset. So we keep global // boolean flags for this condition which will // become true if any ruleset has such // rules. We'll call // MangleTableCompiler_ipt::flushAndSetDefaultPolicy // later if either of these flags is true after // all rulesets have been processed. have_connmark |= mangle_compiler->haveConnMarkRules(); have_connmark_in_output |= mangle_compiler->haveConnMarkRulesInOutput(); long m_str_pos = mangle_rules_stream.tellp(); if (mangle_compiler->getCompiledScriptLength() > 0) { ostringstream tmp; tmp << mangle_compiler->getCompiledScript(); if (tmp.tellp() > 0) { if (!single_rule_compile_on) { mangle_rules_stream << "# ================ Table 'mangle', "; mangle_rules_stream << "rule set " << branch_name << "\n"; } mangle_rules_stream << tmp.str(); } } if (mangle_compiler->haveErrorsAndWarnings()) { all_errors.push_back(mangle_compiler->getErrors("").c_str()); mangle_compiler->clearErrors(); } if (m_str_pos!=mangle_rules_stream.tellp()) { //mangle_rules_stream << "\n"; empty_output = false; } } std::auto_ptr policy_compiler = createPolicyCompiler( fw, ipv6_policy, oscnf, &minus_n_commands_filter); policy_compiler->setSingleRuleCompileMode(single_rule_id); policy_compiler->setDebugLevel( dl ); if (rule_debug_on) policy_compiler->setDebugRule( drp ); policy_compiler->setVerbose( (bool)(verbose) ); policy_compiler->setHaveDynamicInterfaces(have_dynamic_interfaces); if (inTestMode()) policy_compiler->setTestMode(); if (inEmbeddedMode()) policy_compiler->setEmbeddedMode(); if (!policy->isTop()) policy_compiler->registerRuleSetChain(branch_name); policy_compiler->setSourceRuleSet( policy ); policy_compiler->setRuleSetName(branch_name); policy_compiler->setPersistentObjects(persistent_objects); if ( (policy_rules_count=policy_compiler->prolog()) > 0 ) { policy_compiler->compile(); policy_compiler->epilog(); if (policy_compiler->getCompiledScriptLength() > 0) { ostringstream tmp; tmp << policy_compiler->getCompiledScript(); if (tmp.tellp() > 0) { empty_output = false; if (!single_rule_compile_on) { filter_rules_stream << "# ================ Table 'filter', "; filter_rules_stream << "rule set " << branch_name << "\n"; } filter_rules_stream << tmp.str(); } } if (policy_compiler->haveErrorsAndWarnings()) { all_errors.push_back(policy_compiler->getErrors("").c_str()); policy_compiler->clearErrors(); } } /* bug #2550074: "Automatic rules for filter table included twice * in iptables". If user had two policy ruleset objects marked as * "top" rule set, then automaitc rules were added twice. Since we * add rules to automatic_rules_stream only in this one place, it * is sufficient to check if the stream is empty to avoid * duplication. Note that on windows tellp() seems to return -1 * if no data has ever been written to the stream. */ long auto_rules_stream_position = automatic_rules_stream.tellp(); if (policy->isTop() && auto_rules_stream_position <= 0) { ostringstream tmp; if (flush_and_set_default_policy) tmp << policy_compiler->flushAndSetDefaultPolicy(); /* * commented out for #1707 * if (!prolog_done && prolog_place == "after_flush" && !fw->getOptionsObject()->getBool("use_iptables_restore")) { tmp << "prolog_commands" << endl; prolog_done = true; } */ tmp << policy_compiler->printAutomaticRules(); // printAutomaticRules() can generate errors and warnings if (policy_compiler->haveErrorsAndWarnings()) { all_errors.push_back(policy_compiler->getErrors("").c_str()); policy_compiler->clearErrors(); } if (tmp.tellp() > 0) { empty_output = false; if (!single_rule_compile_on) { automatic_rules_stream << "# ================ Table 'filter', automatic rules" << "\n"; } automatic_rules_stream << tmp.str(); } } long auto_mangle_stream_position = automatic_mangle_stream.tellp(); if (policy->isTop() && auto_mangle_stream_position <= 0) { // Note that we process non-top rule sets first and then // deal with the top rule set. By the time we get here the // have_connmark flags reflect the state of all other rule // sets and the top one. ostringstream tmp_m; tmp_m << mangle_compiler->printAutomaticRulesForMangleTable( have_connmark, have_connmark_in_output); // printAutomaticRulesForMangleTable() can generate errors and warnings if (mangle_compiler->haveErrorsAndWarnings()) { all_errors.push_back(mangle_compiler->getErrors("").c_str()); mangle_compiler->clearErrors(); } if (tmp_m.tellp() > 0) { if (!single_rule_compile_on) { automatic_mangle_stream << "# ================ Table 'mangle', "; automatic_mangle_stream << "automatic rules"; automatic_mangle_stream << "\n"; } automatic_mangle_stream << tmp_m.str(); } } return empty_output; } fwbuilder-5.1.0.3599/src/iptlib/MangleTableCompiler_ipt.h0000644000175000017500000000413111733011756023742 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __MANGLETABLECOMPILER_IPT_HH #define __MANGLETABLECOMPILER_IPT_HH #include #include "PolicyCompiler_ipt.h" namespace fwcompiler { class MangleTableCompiler_ipt : public PolicyCompiler_ipt { protected: virtual std::string myPlatformName(); /** * this processor drops all rules except for those that require mangle table */ DECLARE_POLICY_RULE_PROCESSOR(keepMangleTableRules); friend class keepMangleTableRules; public: MangleTableCompiler_ipt(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, std::map *m_n_cmd_map ) : PolicyCompiler_ipt(_db, fw, ipv6_policy, _oscnf, m_n_cmd_map) { my_table = "mangle"; } virtual int prolog(); virtual void addRuleFilter(); virtual std::string flushAndSetDefaultPolicy(); virtual std::string printAutomaticRules(); std::string printAutomaticRulesForMangleTable( bool have_connmark, bool have_connmark_in_output); }; } #endif fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_ipt.h0000644000175000017500000012675211733011756023044 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_IPT_HH__ #define __POLICYCOMPILER_IPT_HH__ #include #include "fwcompiler/PolicyCompiler.h" #include "fwbuilder/RuleElement.h" #include "config.h" #include "Configlet.h" #include #include namespace libfwbuilder { class Interface; class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementSrc; class RuleElementDst; class RuleElementSrv; }; #define ANY_IP_OBJ_ID "__any_ip_obj__" #define ANY_ICMP_OBJ_ID "__any_icmp_obj__" #define ANY_TCP_OBJ_ID "__any_tcp_obj__" #define ANY_UDP_OBJ_ID "__any_udp_obj__" #define TCP_SYN_OBJ_ID "__tcp_syn_obj__" #define BCAST_255_OBJ_ID "__bcast_255_obj__" namespace fwcompiler { class PolicyCompiler_ipt : public PolicyCompiler { public: class PrintRule; protected: bool have_dynamic_interfaces; bool have_connmark; bool have_connmark_in_output; bool using_ipset; bool actually_used_module_set; std::string my_table; std::map tmp_chain_no; std::map rule_chain_no; std::map chain_usage_counter; std::map ipset_tables; typedef std::list chain_list; std::map chains; // number of bridge interfaces (br0 / br1 / etc) int bridge_count; // use minus_n_commands map to track creation of chains. // Using external map object for this to be able to track // new chains across different compiler runs (used to process // rules in different policy or nat objects) std::map *minus_n_commands; QMap regular_interfaces; static const std::list& getStandardChains(); void registerChain(const std::string &chain_name); void insertUpstreamChain(const std::string &chain_name, const std::string &before_chain); std::string findUpstreamChain(const std::string &chain_name); void setChain(libfwbuilder::PolicyRule *rule, const std::string &chain_name); std::string printChains(libfwbuilder::PolicyRule *rule); bool isChainDescendantOfOutput(const std::string &chain_name); bool isChainDescendantOfInput(const std::string &chain_name); std::string getInterfaceVarName(libfwbuilder::FWObject *iface, bool v6=false); std::string getAddressTableVarName(libfwbuilder::FWObject *iface); bool newIptables(const std::string &version); /** * internal: scans child objects of interface iface, both IPv4 * and physAddress, and puts them in the list ol. Since iptables * supports matching on MAC addresses, we create objects of * the class combinedAddress here from each pair of physAddress * and IPV4 */ virtual void _expand_interface(libfwbuilder::Rule *rule, libfwbuilder::Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully); /** * virtual method to let policy compiler check rules using * options specific for the given fw platform. Base class * PolicyCompiler has no visibility into platform-specific * options and can not do this. */ virtual bool checkForShadowingPlatformSpecific(libfwbuilder::PolicyRule *r1, libfwbuilder::PolicyRule *r2); /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls PolicyCompiler::_internalPrintPolicyRule and then adds * chain and target at the end of the printed line */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * trivial rule processor - just prints contents of src, dst, srv */ class printRuleElements : public PolicyRuleProcessor { std::string printRE(libfwbuilder::RuleElement *re); public: printRuleElements(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class printRuleElements; /** * this processor drops all rules that require mangle table */ DECLARE_POLICY_RULE_PROCESSOR(dropMangleTableRules); /** * this processor checks actions in mangle table. For example, * REJECT is not allowed. */ DECLARE_POLICY_RULE_PROCESSOR(checkActionInMangleTable); /** * Rule with options "Tag", "Classify" and "Route" may need to * placed in the same chain (PREROUTING or POSTROUTING since * ROUTE can go into both), but we can't process it if it also * has action Accept (or any other action that is not * "Continue"). This is because we have to split the rule * before the chain is determined and so we end up with two * user defined chains, one for CLASSIFY or MARK and another * for ROUTE, each of them ending with ACCEPT. This means one * of the chains accepts the packet and the other never sees * it. We may eventually optimize this and find a way to * generate code for rules like this in one chain, but since * this is rarely used case, we'll abort for now. */ DECLARE_POLICY_RULE_PROCESSOR(checkForUnsupportedCombinationsInMangle); /** * See #2401 Option "Route" (used to be action "Route") is * deprecated. Iptables target ROUTE is not included in major * distributions (Debian, Ubuntu, Fedora, CentOS). */ DECLARE_POLICY_RULE_PROCESSOR(deprecateOptionRoute); /** * adds few predefined (or "builtin") rules on top of the policy */ class addPredefinedRules : public PolicyRuleProcessor { bool add_once; public: addPredefinedRules(const std::string &name) : PolicyRuleProcessor(name) { add_once=true; } virtual bool processNext(); }; friend class addPredefinedRules; /** * need to duplicate original action of this rule. We use this * information later to decide whether we need to use "-m * state --state new". Also this rule processor stores a copy * of flags getRouting(), getTagging() and getClassification() * which we use in setChainPreroutingForTag() and * setChainPostroutingForTag() to place rules that do tagging in * chain PREROUTING and similar purposes. */ DECLARE_POLICY_RULE_PROCESSOR(storeAction); /** * set target and chain in case of branching */ class Branching : public PolicyRuleProcessor { public: Branching(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); void expandBranch(libfwbuilder::PolicyRule *rule, const std::string &parentRuleNum ); }; friend class Branching; /** * set target and chain in case of route rules * Deprecated beginning with 4.3.0. To be removed in future versions. */ DECLARE_POLICY_RULE_PROCESSOR(Route); /** * turns logging on if global logging override is used */ DECLARE_POLICY_RULE_PROCESSOR(Logging1); /** * splits rule if logging is required and either src or dst is * not any */ DECLARE_POLICY_RULE_PROCESSOR(Logging2); /** * splits rule if it has more than option Tag, Classify or Route */ DECLARE_POLICY_RULE_PROCESSOR(splitIfTagClassifyOrRoute); /** * clears options Tag and Classify in filter table */ DECLARE_POLICY_RULE_PROCESSOR(clearTagClassifyInFilter); /** * turns off logging in rules with options Tag, Classify or * Route in table mangle */ DECLARE_POLICY_RULE_PROCESSOR(clearLogInMangle); /** * switches action to Continue in rules with options Tag, * Classify in mangle table. We deal with other actions in * table filter. */ DECLARE_POLICY_RULE_PROCESSOR(clearActionInTagClassifyIfMangle); /** * this processor checks if the rule is associated with an * interface and uses setInterfaceId to record its id. If the * rule is associated with multiple interfaces, this processor * splits the rule accordingly. Unlike basic processor * PolicyCompiler::InterfacePolicyrules, this processor tries * to optimize rules applied to multiple interfaces using * user-defined chains */ DECLARE_POLICY_RULE_PROCESSOR(InterfacePolicyRulesWithOptimization); /** * if option "firewall is part of any" is OFF, replace all * "Any" with "!fw" before checking for rule shadowing (if fw is * not * part of "any", then "any" does not shadow the * firewall) */ DECLARE_POLICY_RULE_PROCESSOR(convertAnyToNotFWForShadowing); /** * processes rules with negation in Src if it holds only one * object. Similar to PolicyCompiler::singleObjectNegationSrc * but takes into account AddressTable objects if we compile * with support for ipset module */ class SingleRENegation : public PolicyRuleProcessor { std::string type_name; void processSingleObjectNegationInRE(libfwbuilder::FWObject *obj, libfwbuilder::RuleElement *re); public: SingleRENegation(const std::string &name, const std::string &tn) : PolicyRuleProcessor(name) { type_name = tn; } virtual bool processNext(); }; class SingleSrcNegation : public SingleRENegation { public: SingleSrcNegation(const std::string &name) : SingleRENegation(name, libfwbuilder::RuleElementSrc::TYPENAME) {} }; class SingleDstNegation : public SingleRENegation { public: SingleDstNegation(const std::string &name) : SingleRENegation(name, libfwbuilder::RuleElementDst::TYPENAME) {} }; class SingleSrvNegation : public SingleRENegation { public: SingleSrvNegation(const std::string &name) : SingleRENegation(name, libfwbuilder::RuleElementSrv::TYPENAME) {} }; /** * processes rules with negation in Src * * Argument dm defines mode of operation for this rule processor: * if it is false, processor compiles the rule * if it is true, it works in the mode of shadowing detection * * difference is that in shadowing detection mode it does not * replace objects in dst,srv and time with any so that we can * properly check shadowing later. Regular rule processor that * deals with negation in SRC replaces objects in rule * elements DST, SRV and Time with any which causes problems * because these rule elements then match those in other * rules, but they really should not match them because * originally they had specific object so only some packets * would match these rules. */ class SrcNegation : public PolicyRuleProcessor { bool shadowing_mode; public: SrcNegation(bool dm, const std::string &name) : PolicyRuleProcessor(name) { shadowing_mode = dm; } virtual bool processNext(); }; /** * processes rules with negation in Dst */ class DstNegation : public PolicyRuleProcessor { bool shadowing_mode; public: DstNegation(bool dm, const std::string &name) : PolicyRuleProcessor(name) { shadowing_mode = dm; } virtual bool processNext(); }; /** * processes rules with negation in Srv */ class SrvNegation : public PolicyRuleProcessor { bool shadowing_mode; public: SrvNegation(bool dm, const std::string &name) : PolicyRuleProcessor(name) { shadowing_mode = dm; } virtual bool processNext(); }; /** * processes rules with negation in Interval */ class TimeNegation : public PolicyRuleProcessor { bool shadowing_mode; public: TimeNegation(bool dm, const std::string &name) : PolicyRuleProcessor(name) { shadowing_mode = dm; } virtual bool processNext(); }; /** * verifies combination of interface and * direction and * fills interface and direction. After this * predicate it * is guaranteed that both interface and * direction have * some value. In certain situations interface * ID may be * set to "nil" though (e.g. global policy rules). */ DECLARE_POLICY_RULE_PROCESSOR(InterfaceAndDirection); /** * splits rule onto two if interface is defined and direction is Both */ DECLARE_POLICY_RULE_PROCESSOR(splitIfIfaceAndDirectionBoth); /** * If this is bridging firewall, broadcasts and multicasts go * to FORWARD chain unconditionally. There may be other * special conditions to be added later. */ class bridgingFw : public PolicyRuleProcessor { bool checkForMatchingBroadcastAndMulticast(libfwbuilder::Address *addr); public: bridgingFw(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * set chain if Tag rule should go into PREROUTING * DECLARE_POLICY_RULE_PROCESSOR(setChainIfTagInPrerouting); */ /** * set chain if Tag rule should go into PREROUTING */ DECLARE_POLICY_RULE_PROCESSOR(setChainPreroutingForTag); /** * set chain if Tag rule should go into POSTROUTING */ DECLARE_POLICY_RULE_PROCESSOR(setChainPostroutingForTag); /** * set chain for mangle table */ DECLARE_POLICY_RULE_PROCESSOR(setChainForMangle); /** * check if we need to do CONNMARK --restore-mark in OUTPUT chain */ DECLARE_POLICY_RULE_PROCESSOR(checkForRestoreMarkInOutput); /** * split rule if action is Tag and connmark option is activated */ DECLARE_POLICY_RULE_PROCESSOR(splitIfTagAndConnmark); /** * split rule if Src==any * * This is special case since we assume that "any" includes * also a firewall object. Packets headed to or from the * firewall must be inspected by INPUT or OUTPUT chain, while * packets crossing the firewall are inspected by FORWARD * chain. If we assume that "any" also includes firewall * itself, then we need to generate code for both FORWARD and * INPUT/OUTPUT chains from the same rule. This processor * splits the rule onto two and sets chain and direction in * the second copy appropriately. It preserves original src * and dst in both copies, it only changes chain and direction * in the second copy. */ DECLARE_POLICY_RULE_PROCESSOR(splitIfSrcAny); /** * split rule if Dst==any. See comment in splitIfSrcAny */ DECLARE_POLICY_RULE_PROCESSOR(splitIfDstAny); /** * Split rule if src has addressRange object that matches the * firewall */ DECLARE_POLICY_RULE_PROCESSOR(splitIfSrcMatchingAddressRange); /** * Split rule if dst has addressRange object that matches the * firewall */ DECLARE_POLICY_RULE_PROCESSOR(splitIfDstMatchingAddressRange); /** * If rule element RE has an AddressRange object that * represents single address, replace it with corresponding * IPv4 object */ class specialCaseAddressRangeInRE : public PolicyRuleProcessor { std::string re_type; public: specialCaseAddressRangeInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class specialCaseAddressRangeInSrc : public specialCaseAddressRangeInRE { public: specialCaseAddressRangeInSrc(const std::string &n) : specialCaseAddressRangeInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class specialCaseAddressRangeInDst : public specialCaseAddressRangeInRE { public: specialCaseAddressRangeInDst(const std::string &n) : specialCaseAddressRangeInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * split rule if Src==any * * This works just like splitIfSrcAny, except is used in the * part of compiler that detects rule shadowing. While * compiling rules, we split the rule and set chains * appropriately (one rule gets into chain OUTPUT) but leave * SRC 'any' to avoid generating lots of address matches since * setting chain to OUTPUT is sufficient. We can not do this * while detecting shadowing and need to explicitly put the * firewall object in the first of the two rules we produce. */ DECLARE_POLICY_RULE_PROCESSOR(splitIfSrcAnyForShadowing); /** * split rule if Dst==any for shadowing detection. See comment * in splitIfSrcAnyForShadowing */ DECLARE_POLICY_RULE_PROCESSOR(splitIfDstAnyForShadowing); /** * split rule if Src==network the firewall is connected to * * This is special case since we assume that network object * that firewall has interface on includes also a firewall * object. See comment in splitIfSrcAny for further explanation. * * Unlike in splitIfSrcAny, we can not assume rule element * holds a single object (since in splitIfSrcAny we are * looking for "any", we could rely on rule element containing * single object because "any" can only be there alone). * * This processor splits the rule onto two and sets chain and * direction in the second copy appropriately. It preserves * original src and dst in both copies, it only changes chain * and direction in the second copy. */ DECLARE_POLICY_RULE_PROCESSOR(splitIfSrcFWNetwork); /** * split rule if Dst==network the firewall is connected to. * See comment in splitIfSrcAny */ DECLARE_POLICY_RULE_PROCESSOR(splitIfDstFWNetwork); /** * this is a special case of splitIfSrcAny. It splits the rule * but only if SRC has negation turned on, contains two or more * objects and one of these objects is firewall. * * This processor should be called immediately before * processing negation. I tried to modify splitIfSrcAny to * split if there is negation and use it, but that lead to too * much overhead in the generated code for rules with negation * but no firewall in the rule element. */ DECLARE_POLICY_RULE_PROCESSOR(splitIfSrcNegAndFw); /** * similar to splitIfSrcNegAndFw */ DECLARE_POLICY_RULE_PROCESSOR(splitIfDstNegAndFw); /** * checks for illegal combination of src, dst and direction */ DECLARE_POLICY_RULE_PROCESSOR(checkSrcAndDst1); /** * checks for illegal combination of src, dst and direction */ DECLARE_POLICY_RULE_PROCESSOR(checkSrcAndDst2); /** * Split rule if MultiAddress object is used in RE to make * sure it is single object. */ class processMultiAddressObjectsInRE : public PolicyRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInSrc(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class processMultiAddressObjectsInDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInDst(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * splits rule if firewall is in src and dst */ DECLARE_POLICY_RULE_PROCESSOR(specialCaseWithFW1); /** * splits rule if firewall is in dst, interface is not empty, * direction is Outbound and chain is not OUTPUT (it makes * sense to check packets in OUTPUT chain with destination * address that belogns to the firewall, but it does not make * sense to do it in FORWARD chain) */ DECLARE_POLICY_RULE_PROCESSOR(specialCaseWithFWInDstAndOutbound); /** * expands src and dst if both contain fw object. Unlike * standard processor ExpandMultipleAddresses, this one * uses loopback interface as well. */ DECLARE_POLICY_RULE_PROCESSOR(specialCaseWithFW2); /** * checks for the following situations: * * 1. unnumbered interface is in source and direction is inbound * (drop interface from src since source address is * undertermined) * * 2. unnumbered interface is in source, direction is outbound * and temporary chain (drop interface from the list, this * rule has been created while processing negation. TODO: this * is kludge, need to create separate temporary chain while * doing negation in src if one of the objects is firewall) * * 3. unnumbered interface is in destination and direction is * outbound (drop interface since dest. address is undefined) * */ friend class specialCaseWithUnnumberedInterface; class specialCaseWithUnnumberedInterface : public PolicyRuleProcessor { bool dropUnnumberedInterface(libfwbuilder::RuleElement *re); public: specialCaseWithUnnumberedInterface(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class checkForDynamicInterfacesOfOtherObjects; class checkForDynamicInterfacesOfOtherObjects : public PolicyRuleProcessor { bool findDynamicInterfaces(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: checkForDynamicInterfacesOfOtherObjects(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * expand object with multiple addresses but only if it is NOT * the firewall we are working with. This processor is called * right before decideOnChain but after groups have been * expanded and splitIfSrcMatchesFw and splitIfDstMatchesFw * have been called. Latter two make sure that firewall, if it * is part of Src or Dst, will be a single object there when * this processor is called. * * 1. We need to expand objects with multiple addresses (such * as interfaces with many addresses) so that decideOnChain * would properly match when it calls * complexMatch. complexMatch does not match if its first * argument is an object with multiple addresses. * * 2. At the same time we need to keep firewall as a whole, so * that we can drop it later in removeFW, but only after * decideOnChain has determined that chain is INPUT or OUTPUT. */ DECLARE_POLICY_RULE_PROCESSOR(expandMultipleAddressesIfNotFWinSrc); DECLARE_POLICY_RULE_PROCESSOR(expandMultipleAddressesIfNotFWinDst); /** * Compiler::_expandAddr skips loopback interface, so we need * to explicitly process the case when user puts loopback * interface object in the rule */ friend class expandLoopbackInterfaceAddress; class expandLoopbackInterfaceAddress : public PolicyRuleProcessor { void replaceLoopbackWithItsAddress(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: expandLoopbackInterfaceAddress(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * decides what chain this rule should go to if Src contains * firewall object. This is a simple case and we need to set * chain before we try to split the rule if it contains * network the firewall has interface on (splitIfSrcFWNetwork * / splitIfDstFWNetwork). */ DECLARE_POLICY_RULE_PROCESSOR(decideOnChainIfSrcFW); /** * Similar to the above, except it decides what chain this * rule should go to if Dst contains firewall object. */ DECLARE_POLICY_RULE_PROCESSOR(decideOnChainIfDstFW); /** * This processor takes care of a special case where a rule * with 'any' in both src and dst is used on a loopback * interface and option 'assume firewall is part of any' is * OFF. Processor splitIfIfaceAndDirectionBoth splits * interface rule if its direction is "Both". This means that * by the time this processor is called, the original rule * "any any any accept both" on the loopback interface has * already been converted to two rules : * * any any any accept inbound * any any any accept outbound * * We do not have to split rule here, but rather just assign it to * INPUT/OUTPUT chains. * * This is mostly a patch for those who do not understand how * does "assume firewall is part of any" work. It also * eliminates useless code in the FORWARD chain that appear in * the rules on a loopback interface if the option "assume * firewall is part of any" is ON. */ DECLARE_POLICY_RULE_PROCESSOR(decideOnChainIfLoopback); /** * define chain for rules with action Classify */ DECLARE_POLICY_RULE_PROCESSOR(decideOnChainForClassify); /** * drop rules with terminating targets. Used as part of the * shadowing detection for non-terminating rules in the mangle * table. */ DECLARE_POLICY_RULE_PROCESSOR(dropTerminatingTargets); /** * decides what chain this rule should go to if it has not * been decided in decideOnChainIfFW */ DECLARE_POLICY_RULE_PROCESSOR(finalizeChain); /** * decides on "jump to" chain */ DECLARE_POLICY_RULE_PROCESSOR(decideOnTarget); /** * If chain has been determined to be INPUT or OUTPUT, we can * remove firewall object from dst or src (resp.) NB: we can * remove only reference to the whole firewall. We DO NOT * remove reference to its interface or (in the future) * address objects under interfaces. We do this only if we do * not add any virtual addresses for NAT and if original rule * did not have negation. */ DECLARE_POLICY_RULE_PROCESSOR(removeFW); /** * if rule option action_on_reject is empty, initialize it * with global setting of this option. */ DECLARE_POLICY_RULE_PROCESSOR(fillActionOnReject); /** * iptables does not permit using "--m mac --mac-source" in * the OUTPUT chain */ DECLARE_POLICY_RULE_PROCESSOR(checkMACinOUTPUTChain); /** * iptables permits using "--m owner --uid-owner" only in * the OUTPUT chain */ DECLARE_POLICY_RULE_PROCESSOR(checkUserServiceInWrongChains); /** * split a rule if action Reject is used in a rule with * Service 'any' and rule options do not specify what should * we use for Reject */ class splitRuleIfSrvAnyActionReject :public PolicyRuleProcessor { std::map seen_rules; public: splitRuleIfSrvAnyActionReject(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipt::splitRuleIfSrvAnyActionReject; /** * separate TCP/UDP services that specify source port (can * not be used in combination with destination port with * multiport) * * Call this processor after groups have been expanded in Srv */ class splitServicesIfRejectWithTCPReset :public PolicyRuleProcessor { std::map seen_rules; public: splitServicesIfRejectWithTCPReset(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipt::splitServicesIfRejectWithTCPReset; /** * Rules that match icmpv6 should not be stateful. See SF bug 3094273 * Will reset "stateful" flag and issue warning. * Call this processor after groups have been expanded in Srv */ class checkForStatefulICMP6Rules :public PolicyRuleProcessor { public: checkForStatefulICMP6Rules(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipt::checkForStatefulICMP6Rules; /** * deals with special cases with some known custom services */ DECLARE_POLICY_RULE_PROCESSOR(specialCasesWithCustomServices); /** * optimize rules in case we deal with one or few objects in * one rule element and lots of objects in the other two */ class optimize1 : public PolicyRuleProcessor { void optimizeForRuleElement(libfwbuilder::PolicyRule *rule, const std::string &re_type); public: optimize1(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipt::optimize1; /** * simple optimization: if the rule is "final" and its action * does not need protocol specification (it is _not_ -j REJECT * --reject-with tcp-reset), then make sure service is * "any". The "final" is such rule that defines the actual * built-in chain ACCEPT/DROP/REJECT and * should not be * further split or processed in any way; such rule for * example is created in Logging and negations) */ DECLARE_POLICY_RULE_PROCESSOR(optimize2); friend class PolicyCompiler_ipt::optimize2; /** * remove duplicate rules */ class optimize3 : public PolicyRuleProcessor { std::map rules_seen_so_far; PolicyCompiler_ipt::PrintRule *printRule; public: optimize3(const std::string &name) : PolicyRuleProcessor(name) { printRule = NULL; } virtual ~optimize3() { if (printRule) delete printRule; } virtual bool processNext(); }; friend class PolicyCompiler_ipt::optimize3; /** * Optimize rules by dropping "-i +" or "-o +" if chain is * INPUT or OUTPUT respectively. */ DECLARE_POLICY_RULE_PROCESSOR(optimizeForMinusIOPlus); /** * split rules so multiport module can be used */ DECLARE_POLICY_RULE_PROCESSOR(prepareForMultiport); /** * eliminates duplicate objects in SRC. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInSRC : public eliminateDuplicatesInRE { public: eliminateDuplicatesInSRC(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInDST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInDST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInSRV : public eliminateDuplicatesInRE { public: eliminateDuplicatesInSRV(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {} }; /** * process action 'Accounting' */ DECLARE_POLICY_RULE_PROCESSOR(accounting); /* * Check if interface uses in the element "interface" has address * that matches address family of the rule set. If interface does * not have ipv6 address but rule set is ipv6, this interface will * never see ipv6 packets and rule should be dropped. */ DECLARE_POLICY_RULE_PROCESSOR(checkInterfaceAgainstAddressFamily); /** * if action is Continue and logging is off, skip this rule. * We only use action Continue to log some packets without making * policy decision */ DECLARE_POLICY_RULE_PROCESSOR(SkipActionContinueWithNoLogging); /** * count how many times each user-defined chain we've created is * used. We should be able to drop unused chains. */ DECLARE_POLICY_RULE_PROCESSOR(countChainUsage); virtual std::string myPlatformName(); /** * TODO: move these two to class fwcompiler::PolicyCompiler, * then create enum for all possible actions on reject in that * class and use it instead of string. */ std::string getActionOnReject(libfwbuilder::PolicyRule *rule); bool isActionOnRejectTCPRST(libfwbuilder::PolicyRule *rule); void resetActionOnReject(libfwbuilder::PolicyRule *rule); public: PolicyCompiler_ipt(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, std::map *m_n_commands_map ) : PolicyCompiler(_db, fw, ipv6_policy, _oscnf) { have_dynamic_interfaces = false; have_connmark = false; have_connmark_in_output = false; my_table = "filter"; minus_n_commands = m_n_commands_map; bridge_count = 0; } virtual ~PolicyCompiler_ipt(); /** * Add some predefined rules controlled by checkboxes in * firewall settings dialog */ virtual void addPredefinedPolicyRules(); virtual void verifyPlatform(); virtual int prolog(); virtual void compile(); virtual void epilog(); /** * addRuleFilter() is a hook where we can add a rule processor to filter * some of the rules out before we begin actual processing */ virtual void addRuleFilter(); /** * this method registers chain used for the ruleset (most * often branch rule set). Since rules in the same ruleset do * not use this chain as target, rule processor * countChainUsage considers it unused. Registering it makes * sure its usage counter is > 0. */ void registerRuleSetChain(const std::string &chain_name); void setHaveDynamicInterfaces(bool f) { have_dynamic_interfaces=f; } virtual std::string flushAndSetDefaultPolicy(); virtual std::string printAutomaticRules(); std::string commit(); std::string getNewTmpChainName(libfwbuilder::PolicyRule *rule); std::string getNewChainName(libfwbuilder::PolicyRule *rule,libfwbuilder::Interface *rule_iface); bool haveConnMarkRules() { return have_connmark; } bool haveConnMarkRulesInOutput() { return have_connmark_in_output; } std::list getUsedChains(); PolicyCompiler_ipt::PrintRule* createPrintRuleProcessor(); /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. Negation * should also have been taken care of before this method is * called. * * This processor is not necessarily the last in the * conveyor, so it should push rules back to tmp_queue (for * example there could be progress indicator processor after * this one) */ class PrintRule : public PolicyRuleProcessor { protected: bool init; bool print_once_on_top; bool minus_n_tracker_initialized; bool have_m_iprange; std::string current_rule_label; std::string version; void initializeMinusNTracker(); /* * Prints single --option with argument and negation "!" * taking into account the change that happened in iptables 1.4.3.1 * that causes warning * Using intrapositioned negation (`--option ! this`) is deprecated in favor of extrapositioned (`! --option this`). */ virtual std::string _printSingleOptionWithNegation( const std::string &option, libfwbuilder::RuleElement *rel, const std::string &arg); virtual std::string _createChain(const std::string &chain); virtual std::string _printRuleLabel(libfwbuilder::PolicyRule *r); virtual std::string _printSrcService( libfwbuilder::RuleElementSrv *o); virtual std::string _printDstService( libfwbuilder::RuleElementSrv *o); virtual std::string _printProtocol(libfwbuilder::Service *srv); virtual std::string _printPorts(int rs,int re); virtual std::string _printSrcPorts(libfwbuilder::Service *srv); virtual std::string _printDstPorts(libfwbuilder::Service *srv); virtual std::string _printICMP(libfwbuilder::ICMPService *srv); virtual std::string _printIP(libfwbuilder::IPService *srv, libfwbuilder::PolicyRule *rule); virtual std::string _printTCPFlags(libfwbuilder::TCPService *srv); virtual std::string _printSrcAddr(libfwbuilder::RuleElement *rel, libfwbuilder::Address *o); virtual std::string _printDstAddr(libfwbuilder::RuleElement *rel, libfwbuilder::Address *o); virtual std::string _printAddr(libfwbuilder::Address *o); virtual std::string _printIpSetMatch( libfwbuilder::Address *o, libfwbuilder::RuleElement *rel); virtual std::string _printSingleObjectNegation( libfwbuilder::RuleElement *rel); virtual std::string _printChain(libfwbuilder::PolicyRule *r); virtual std::string _printTarget(libfwbuilder::PolicyRule *r); virtual std::string _printModules(libfwbuilder::PolicyRule *r); virtual std::string _printDirectionAndInterface( libfwbuilder::PolicyRule *r); virtual std::string _printMultiport(libfwbuilder::PolicyRule *r); virtual std::string _printTimeInterval(libfwbuilder::PolicyRule *r); virtual std::string _printLogParameters( libfwbuilder::PolicyRule *r); virtual std::string _printLogPrefix(const std::string &rule_n, const std::string &action, const std::string &interf, const std::string &chain, const std::string &ruleset, const std::string &rule_label, const std::string &prefix); virtual std::string _printLogPrefix(libfwbuilder::PolicyRule *r, const std::string &prefix); virtual std::string _printActionOnReject( libfwbuilder::PolicyRule *r); virtual std::string _printLimit(libfwbuilder::PolicyRule *r); public: PrintRule(const std::string &name); void initialize(); virtual std::string _printGlobalLogParameters(); virtual std::string _printOptionalGlobalRules(); virtual std::string _declareTable(); virtual std::string _clampTcpToMssRule(); virtual std::string _commit(); virtual std::string _quote(const std::string &s); virtual std::string _startRuleLine(); virtual std::string _endRuleLine(); virtual void _printBackupSSHAccessRules(Configlet *c); virtual bool processNext(); std::string PolicyRuleToString(libfwbuilder::PolicyRule *r); }; friend class PolicyCompiler_ipt::PrintRule; class PrintRuleIptRst : public PrintRule { virtual std::string _createChain(const std::string &chain); virtual std::string _startRuleLine(); virtual std::string _endRuleLine(); virtual std::string _printRuleLabel(libfwbuilder::PolicyRule *r); public: PrintRuleIptRst(const std::string &name) : PrintRule(name) {}; virtual std::string _declareTable(); virtual std::string _commit(); virtual std::string _quote(const std::string &s); virtual bool processNext(); }; friend class PolicyCompiler_ipt::PrintRuleIptRst; class PrintRuleIptRstEcho : public PrintRuleIptRst { virtual std::string _createChain(const std::string &chain); virtual std::string _startRuleLine(); virtual std::string _endRuleLine(); public: PrintRuleIptRstEcho(const std::string &name) : PrintRuleIptRst(name) {}; virtual std::string _declareTable(); virtual std::string _commit(); virtual std::string _quote(const std::string &s); virtual bool processNext(); }; friend class PolicyCompiler_ipt::PrintRuleIptRstEcho; }; } #endif fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_secuwall.h0000644000175000017500000000514111733011756024025 0ustar sylvestresylvestre/* * OSConfigurator_secuwall.h - OS configurator for secunet wall host OS * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __OSNETWORKCONFIGURATOR_SECUWALL_H_ #define __OSNETWORKCONFIGURATOR_SECUWALL_H_ #include "fwbuilder/Tools.h" #include "OSConfigurator_linux24.h" #include #include namespace fwcompiler { class OSConfigurator_secuwall : public OSConfigurator_linux24 { public: virtual ~OSConfigurator_secuwall() {}; OSConfigurator_secuwall(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy); virtual std::string myPlatformName(); virtual void processFirewallOptions(); virtual std::string printPathForAllTools(const std::string &); virtual std::map getGeneratedFiles() const; /* TODO: Merge this mapping with gui interface types mapping */ /* Value-Defintions of the different String values */ enum ifaceType { ifNotDefined, ETHERNET, ALIAS, BRIDGE, BONDING, CLUSTER, VLAN, ifEnd }; /* Map to associate the strings with the enum values */ std::map s_mapIfaceTypes; /* and vice versa for the config files */ std::map s_mapIfaceStrings; private: bool createDirStructure() const; int generateManagementFile(); int generateNetworkFile(); int generateHostsFile(); int generateDNSFile(); int generateNsswitchFile(); int generateInterfaces(); int generateInterfaceFile(libfwbuilder::Interface * iface, std::string name = "", libfwbuilder::IPv4 * ip_address = NULL, int iface_number = 0); int generateSSHKeys(); int stringToFile(const std::string data, const std::string filename, const QIODevice::OpenMode mode = QIODevice::ReadWrite|QIODevice::Truncate) const; bool containsFirewallKey(std::string in) const; std::list m_ifaces; }; }; #endif fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_ipcop.cpp0000644000175000017500000000310211733011756023646 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id: OSConfigurator_linux24.cpp 756 2009-02-06 00:58:01Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "OSConfigurator_ipcop.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_ipcop::myPlatformName() { return "ipcop"; } OSConfigurator_ipcop::OSConfigurator_ipcop(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy) : OSConfigurator_linux24(_db, fw, ipv6_policy) { } void OSConfigurator_ipcop::addVirtualAddressForNAT(const Network*) { } void OSConfigurator_ipcop::addVirtualAddressForNAT(const Address*) { } int OSConfigurator_ipcop::prolog() { return 0; } void OSConfigurator_ipcop::epilog() { } fwbuilder-5.1.0.3599/src/iptlib/CompilerDriver_ipt.h0000644000175000017500000001112611733011756023024 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_IPT_HH__ #define __COMPILER_DRIVER_IPT_HH__ #include "../compiler_lib/CompilerDriver.h" #include "PolicyCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include #include #include #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; class Address; class PolicyRule; }; namespace fwcompiler { class CompilerDriver_ipt : public CompilerDriver { // commands that pass control to branch chains should go into // POSTROUTING or PREROUTING chains depending on the targets used // inside the branch. Branches that use mixed rules (both SNAT // and DNAT) will be split so that two separate chains are created, one // for all SNAT rules and another for all DNAT rules. Rules in // the top NAT ruleset that pass control to them will be placed into // PREROUTING or POSTROUTING chain depending on the target in the branch. // The following maps targets used in the branch to the ruleset name. // By convention, the chain created for the branch rules will be named // using combination of the ruleset name and word "PREROUTING" // or "POSTROUTING" std::map > branch_ruleset_to_chain_mapping; std::auto_ptr createPolicyCompiler( libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, std::map *m_n_commands_map); bool have_connmark; bool have_connmark_in_output; public: CompilerDriver_ipt(libfwbuilder::FWObjectDatabase *db); virtual ~CompilerDriver_ipt(); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); void assignRuleSetChain(libfwbuilder::RuleSet *ruleset); void findBranchesInMangleTable(libfwbuilder::Firewall*, std::list &all_policies); std::string dumpScript(libfwbuilder::Firewall *fw, const std::string& automatic_rules_script, const std::string& automatic_mangle_script, const std::string& nat_script, const std::string& mangle_script, const std::string& filter_script, bool ipv6_policy); bool processPolicyRuleSet( libfwbuilder::Firewall *fw, libfwbuilder::FWObject *ruleset, const std::string &single_rule_id, std::ostringstream &filter_table_stream, std::ostringstream &mangle_table_stream, std::ostringstream &automatic_rules_stream, std::ostringstream &automatic_mangle_stream, fwcompiler::OSConfigurator_linux24 *oscnf, int policy_af, std::map &minus_n_commands_filter, std::map &minus_n_commands_mangle); bool processNatRuleSet( libfwbuilder::Firewall *fw, libfwbuilder::FWObject *ruleset, const std::string &single_rule_id, std::ostringstream &nat_stream, fwcompiler::OSConfigurator_linux24 *oscnf, int policy_af, std::map &minus_n_commands_nat); }; }; #endif fwbuilder-5.1.0.3599/src/iptlib/OSData.h0000644000175000017500000000341211733011756020334 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OSDATA_HH #define __OSDATA_HH #include "config.h" #include #include #include class OSData { std::string host_os; std::map variable_names; std::map attribute_names; std::list all_tools; public: OSData(const std::string &ho); typedef enum { LSMOD, MODPROBE, IPTABLES, IP6TABLES, IPTABLES_RESTORE, IP6TABLES_RESTORE, IP, IFCONFIG, VCONFIG, BRCTL, IFENSLAVE, IPSET, LOGGER } tools; std::string getVariableName(tools t) { return variable_names[t]; } const std::list& getAllTools() { return all_tools; } std::string getAttributeNameForTool(tools t) { return attribute_names[t]; } }; #endif fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_ipt_optimizer.cpp0000644000175000017500000002356411733011756025476 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_ipt.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Firewall.h" #include "combinedAddress.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* * Optimizer 1: * * splits rule, making sure we make only one parameter check at a time * That is, we only check source, or destination or service and then * pass control to a user-defined chain to check for the next * parameter. This helps avoid multiple checks for the same parameter. * * Assumtions: * * Can use this process with multiple objects in src,dst,srv * Run splitRuleIfSrvAnyActionReject before this processor to make sure * Srv contains only TCP objects if action is "Reject" and TCP RST is required */ void PolicyCompiler_ipt::optimize1::optimizeForRuleElement( PolicyRule *rule, const std::string &re_type) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *r; string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewTmpChainName(rule); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); for (FWObject::iterator i=r->begin(); i!=r->end(); ++i) { if (RuleElement::cast(*i)!=NULL) { if ((*i)->getTypeName()!=re_type && (*i)->size()!=1) { RuleElement *nre=RuleElement::cast(*i); nre->clearChildren(); nre->setAnyElement(); } else { RuleElement *re = RuleElement::cast( rule->getFirstByType((*i)->getTypeName())); /* * put "any tcp" service back in srv field if it was originally some * tcp service. This is needed because we may need to produce * --reject-with tcp-reset if the action is reject and we need to * reject with TCP RST. */ if (RuleElementSrv::isA(re) && r->getAction()==PolicyRule::Reject && ipt_comp->isActionOnRejectTCPRST(r)) { Service *srv= compiler->getFirstSrv(r); if (TCPService::isA(srv)) { re->clearChildren(); re->addRef( compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(ANY_TCP_OBJ_ID))); /* also leave a flag indicating that further optimization by service * is not needed */ rule->setBool("do_not_optimize_by_srv",true); r->setBool("do_not_optimize_by_srv",true); } else { re->reset(); } } else { re->reset(); } } } } r->setStr("ipt_target",new_chain); r->setClassification(false); r->setRouting(false); r->setTagging(false); tmp_queue.push_back(r); FWOptions *ruleopt=rule->getOptionsObject(); ruleopt->setBool("stateless",true); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); rule->setStr("ipt_chain",new_chain); rule->setBool("force_state_check",false); rule->setStr("upstream_rule_chain", this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); // if (rule->getInterfaceStr()=="") // rule->setInterfaceStr("nil"); rule->setDirection( PolicyRule::Both ); tmp_queue.push_back(rule); } bool PolicyCompiler_ipt::optimize1::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel; RuleElementDst *dstrel; RuleElementSrv *srvrel; RuleElementInterval *intrel; FWObject::iterator i1 = rule->begin(); srcrel = RuleElementSrc::cast(*i1); i1++; dstrel = RuleElementDst::cast(*i1); i1++; srvrel = RuleElementSrv::cast(*i1); i1++; i1++; intrel = RuleElementInterval::cast(*i1); bool srcany = srcrel->isAny(); bool dstany = dstrel->isAny(); bool srvany = srvrel->isAny(); bool intany = (intrel!=NULL && intrel->isAny()); int srcn = srcrel->size(); int dstn = dstrel->size(); int srvn = srvrel->size(); int intn = 1; if (intrel!=NULL) intn = intrel->size(); bool all_tcp_or_udp = true; for (FWObject::iterator i=srvrel->begin(); i!=srvrel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *service_object = Service::cast( o ); if (service_object==NULL) { compiler->abort(rule, "Broken Service rule element"); } // tcp and udp will be collapsed because we can use multiport module if ( !TCPService::isA(service_object) && !UDPService::isA(service_object)) { all_tcp_or_udp = false; break; } } if (all_tcp_or_udp) srvn = 1; // Golden rule - try to introduce minimum forward rules .... // we can't optimize 1 src, 1 dstn, 1 service and 1 time interval // we can't optimize if we've got three 'anys' .. if ((srcn <= 1 && dstn <= 1 && srvn <= 1 && intn <= 1) || (srcany && dstany && srvany) || (srcany && dstany && intany) || (srcany && srvany && intany) || (dstany && srvany && intany) ) { tmp_queue.push_back(rule); return true; } // Assume any means LOTS of rules - i.e. not good candidate for optimization if (srcany) srcn=INT_MAX; if (dstany) dstn=INT_MAX; if (srvany) srvn=INT_MAX; if (intany) intn=INT_MAX; // Now work out which is best optimization to do. // this rule is called twice so we only need to do one op on each if ( !srvany && (srvn <= dstn) && (srvn <= srcn) && (srvn <= intn) && ! rule->getBool("do_not_optimize_by_srv") ) { optimizeForRuleElement(rule,RuleElementSrv::TYPENAME); return true; } if ( !srcany && (srcn <= dstn) && (srcn <= srvn) && (srcn <= intn)) { optimizeForRuleElement(rule,RuleElementSrc::TYPENAME); return true; } if ( !dstany && (dstn <= srcn) && (dstn <= srvn) && (dstn <= intn)) { optimizeForRuleElement(rule,RuleElementDst::TYPENAME); return true; } if ( !intany && (intn <= srcn) && (intn <= dstn) && (intn <= srvn)) { optimizeForRuleElement(rule,RuleElementInterval::TYPENAME); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::optimize2::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srvrel=rule->getSrv(); if (rule->getBool("final")) { if ( rule->getAction()==PolicyRule::Reject && ipt_comp->isActionOnRejectTCPRST(rule)) { // preserve service ; } else { srvrel->clearChildren(); srvrel->setAnyElement(); } } tmp_queue.push_back(rule); return true; } /* * this processor eliminates duplicate rules _generated for the same * high level rule_ This is different from processor * PolicyCompiler_ipf::eliminateDuplicateRules, which finds and * eliminates duplicate rules throughout the whole generated script. */ bool PolicyCompiler_ipt::optimize3::processNext() { PolicyRule *rule; rule = getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } if (printRule==NULL) { printRule = new PrintRule(""); printRule->setContext(compiler); printRule->initialize(); } string thisRule = rule->getLabel() + " " + printRule->PolicyRuleToString(rule); if (rules_seen_so_far.count(thisRule)!=0) return true; tmp_queue.push_back(rule); rules_seen_so_far[thisRule]=true; return true; } bool PolicyCompiler_ipt::optimizeForMinusIOPlus::processNext() { PolicyRule *rule; rule=getNext(); if (rule==NULL) return false; RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); FWObject *rule_iface = FWObjectReference::getObject(itf_re->front()); string iface_name = rule_iface->getName(); // rule->getInterfaceStr(); if (iface_name.empty() || iface_name=="nil" ) { tmp_queue.push_back(rule); return true; } string chain = rule->getStr("ipt_chain"); if (iface_name == "*" && (chain == "INPUT" || chain == "OUTPUT")) itf_re->reset(); // rule->setInterfaceStr(""); tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/iptlib/Preprocessor_ipt.cpp0000644000175000017500000000273311733011756023123 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Preprocessor_ipt.h" #include "fwbuilder/Interface.h" #include "fwbuilder/AttachedNetworks.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; void Preprocessor_ipt::convertObject(FWObject *obj) { if ( AttachedNetworks::isA(obj)) { AttachedNetworks *att = AttachedNetworks::cast(obj); Interface *intf = Interface::cast(att->getParent()); if (intf->isRegular()) { att->setCompileTime(true); att->loadFromSource(ipv6, getCachedFwOpt(), inTestMode()); } else att->setRunTime(true); } else Preprocessor::convertObject(obj); } fwbuilder-5.1.0.3599/src/iptlib/RoutingCompiler_ipt.h0000644000175000017500000001432611733011756023225 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ROUTINGCOMPILER_IPT_HH__ #define __ROUTINGCOMPILER_IPT_HH__ #include #include "fwcompiler/RoutingCompiler.h" #include "fwbuilder/RuleElement.h" #include "config.h" namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_ipt : public RoutingCompiler { protected: /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls RoutingCompiler::debugPrintRule */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * processes rules with negation in Dst if it holds only one object */ DECLARE_ROUTING_RULE_PROCESSOR(singleDstNegation); /** * processes rules with negation in Dst */ DECLARE_ROUTING_RULE_PROCESSOR(DstNegation); /** * check if we have to install default route */ DECLARE_ROUTING_RULE_PROCESSOR(FindDefaultRoute); /** * expand address range objects in destination */ DECLARE_ROUTING_RULE_PROCESSOR(addressRangesInDst); /** * remove duplicate rules */ class PrintRule; class optimize3 : public RoutingRuleProcessor { std::map rules_seen_so_far; RoutingCompiler_ipt::PrintRule *printRule; public: optimize3(const std::string &name) : RoutingRuleProcessor(name){ printRule=NULL; } virtual bool processNext(); }; friend class RoutingCompiler_ipt::optimize3; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInDST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInDST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementRDst::TYPENAME) {} }; /** * eliminates duplicate rules */ class eliminateDuplicateRules : public RoutingRuleProcessor { std::map rules_seen_so_far; std::map::iterator rules_it; RoutingCompiler_ipt::PrintRule *printRule; public: eliminateDuplicateRules(const std::string &name) : RoutingRuleProcessor(name){ printRule=NULL; } virtual bool processNext(); }; /** * prints single policy rule, assuming all groups have been * expanded, destination holds exactly one object, and this * object is not a group. Negation should also have been taken * care of before this method is called. * * This processor is not necessarily the last in the * conveyor, so it should push rules back to tmp_queue (for * example there could be progress indicator processor after * this one) */ class PrintRule : public RoutingRuleProcessor { bool print_once_on_top; std::string current_rule_label; virtual std::string _printAddr(libfwbuilder::Address *o); public: PrintRule(const std::string &name); virtual bool processNext(); std::string RoutingRuleToString(libfwbuilder::RoutingRule *r); std::string _printRGtw(libfwbuilder::RoutingRule *r); std::string _printRItf(libfwbuilder::RoutingRule *r); std::string _printRDst(libfwbuilder::RoutingRule *r); }; friend class RoutingCompiler_ipt::PrintRule; virtual std::string myPlatformName(); // These buffers are needed to collect output generated from the single ECMP rules belonging to one destination, // because all these routes have to be activated with a single ip command. So ECMP ip commands are built up gradually // during compilation and inserted in the shell script after all rules are processed. std::map< std::string, std::string> ecmp_rules_buffer; // sortedDstId+metric-->nexthops std::map< std::string, std::string> ecmp_comments_buffer; // sortedDstId+metric-->rule's info for the fw script bool have_default_route; bool defined_restore_script_output; public: RoutingCompiler_ipt(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler(_db, fw, ipv6_policy, _oscnf) { have_default_route = false; defined_restore_script_output = false; } virtual void verifyPlatform(); virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/iptlib/combinedAddress.cpp0000644000175000017500000000336211733011756022646 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "combinedAddress.h" #include #include #include using namespace libfwbuilder; using namespace std; const char *combinedAddress::TYPENAME={"combinedAddress"}; combinedAddress::~combinedAddress() {} std::string combinedAddress::getPhysAddress() const { return physAddress; } void combinedAddress::setPhysAddress(const std::string &s) { physAddress = s; } bool combinedAddress::isAny() const { return (IPv4::isAny() && physAddress==""); } FWObject& combinedAddress::shallowDuplicate(const FWObject *other, bool preserve_id) throw(FWException) { physAddress = dynamic_cast(other)->physAddress; return IPv4::shallowDuplicate(other, preserve_id); } fwbuilder-5.1.0.3599/src/iptlib/NATCompiler_ipt.h0000644000175000017500000005124011733011756022214 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NATCOMPILER_IPT_HH__ #define __NATCOMPILER_IPT_HH__ #include #include "fwcompiler/NATCompiler.h" #include "fwbuilder/RuleElement.h" #include #include #include #include #include namespace libfwbuilder { class Host; class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementOSrc; class RuleElementODst; class RuleElementOSrv; class RuleElementTSrc; class RuleElementTDst; class RuleElementTSrv; }; namespace fwcompiler { class NATCompiler_ipt : public NATCompiler { protected: class PrintRule; NATCompiler_ipt::PrintRule *printRule; bool have_dynamic_interfaces; bool using_ipset; std::map chain_usage_counter; // use minus_n_commands map to track creation of chains. // Using external map object for this to be able to track // new chains across different compiler runs (used to process // rules in different policy or nat objects) std::map *minus_n_commands; // This map is located in CompilerDriver_ipt const std::map > *branch_ruleset_to_chain_mapping; QMap regular_interfaces; static const std::list& getStandardChains(); std::string getInterfaceVarName(libfwbuilder::FWObject *iface, bool v6=false); std::string getAddressTableVarName(libfwbuilder::FWObject *iface); /** * internal: scans child objects of interface iface, both IPv4 * and physAddress, and puts them in the list ol. Since iptables * supports matching on MAc addresses, we create objects of * the class combinedAddress here from each pair of physAddress * and IPV4 */ virtual void _expand_interface(libfwbuilder::Rule *rule, libfwbuilder::Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully); virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * convert load balancing rules into DNAT rules with address * range in TDst. If objects in TDst do not constitute a * consecutive address range, abort with an error message */ DECLARE_NAT_RULE_PROCESSOR(ConvertLoadBalancingRules); /** * this processor spits SDNAT rule onto SNAT and DNAT rules. * SDNAT rule translates both source and destination. */ DECLARE_NAT_RULE_PROCESSOR(splitSDNATRule); /** * this processor spits NAT rule with action Branch to * generate iptables commands in all chains that it needs */ DECLARE_NAT_RULE_PROCESSOR(splitNATBranchRule); /** * verifies correctness of the NAT rules */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules); /** * verifies correctness of the NAT rules - this one * specifically * checks for some inconsistencies between * OSrv and TSrv and should * only be used after * splitServices */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules2); /** * verifies correctness of the combination of interface * specification and chain. */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules3); /** * splits rule with multiple objects in ODst. This needs to be * done only * for DNAT rules. Call this processor when * negation has been dealt with already. */ DECLARE_NAT_RULE_PROCESSOR(splitOnODst); /** * splits rule with multiple service objects in OSrv onto * several rules */ DECLARE_NAT_RULE_PROCESSOR(splitOnOSrv); /** * process special case: multiple objects in osrv and * tsrv!=any. Need to convert to atomic by OSrv before * using classifyNATRule. */ DECLARE_NAT_RULE_PROCESSOR(convertToAtomicportForOSrv); /** * process special case: rule that translates dest. port but * does not change addresses (tsrc==any, tdst==any, tsrv!=any) * Need to copy odst to tdst. */ DECLARE_NAT_RULE_PROCESSOR(portTranslationRules); /** * processor portTranslationRules copies ODst into TDst * for rules that only do port translations and where TDst * is "any". In case ODst was firewall or one of its interfaces, * we should set rule type to NATRule::REDIRECT */ DECLARE_NAT_RULE_PROCESSOR(specialCaseWithRedirect); class splitRuleIfRuleElementIsDynamicInterface : public NATRuleProcessor { std::string re_type; public: splitRuleIfRuleElementIsDynamicInterface(const std::string &n,std::string _type): NATRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; /** * splits rule if one of the objects in tsrc is * interface * with dynamic address */ class splitOnDynamicInterfaceInTSrc : public splitRuleIfRuleElementIsDynamicInterface { public: splitOnDynamicInterfaceInTSrc(const std::string &n): splitRuleIfRuleElementIsDynamicInterface(n,libfwbuilder::RuleElementTSrc::TYPENAME) {} }; /** * splits rule if one of the objects in odst is * interface * with dynamic address */ class splitOnDynamicInterfaceInODst : public splitRuleIfRuleElementIsDynamicInterface { public: splitOnDynamicInterfaceInODst(const std::string &n): splitRuleIfRuleElementIsDynamicInterface(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * checks for the following situations: * * 1. an unnumbered interface is in OSrc and rule rtype is Masq * or SNAT (drop interface from src since source address is * undertermined) * * 2. an unnumbered interface is in ODst and rule type is * DNAT (drop interface since dest. address is undefined) * */ friend class specialCaseWithUnnumberedInterface; class specialCaseWithUnnumberedInterface : public NATRuleProcessor { bool dropUnnumberedInterface(libfwbuilder::RuleElement *re); public: specialCaseWithUnnumberedInterface(const std::string &name) : NATRuleProcessor(name) {} virtual bool processNext(); }; friend class checkForDynamicInterfacesOfOtherObjects; class checkForDynamicInterfacesOfOtherObjects : public NATRuleProcessor { void findDynamicInterfaces(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: checkForDynamicInterfacesOfOtherObjects(const std::string &name) : NATRuleProcessor(name) {} virtual bool processNext(); }; /** * fills translated service with the copy of original srv */ DECLARE_NAT_RULE_PROCESSOR(fillTranslatedSrv); /** * Assigns NAT rules to interfaces * * This processor works together with * ReplaceFirewallObjectsTSrc and ConvertToAtomicRules. If the * first two left interface object in TSrc, AssignInterfaces * assigns this rule to the corresponding interface. Rule * wont'be assigned to any interface if object in TSrc is not * an interface or an address of interface. */ friend class AssignInterface; class AssignInterface : public NATRuleProcessor { public: AssignInterface(const std::string &name) : NATRuleProcessor(name) {} virtual bool processNext(); }; /** * calls OSConfigurator to add virtual * address to the * firewall if it is needed for NAT rule */ DECLARE_NAT_RULE_PROCESSOR(addVirtualAddress); /** * replaces references to the firewall in odst * with * references to its external interfaces */ DECLARE_NAT_RULE_PROCESSOR(ReplaceFirewallObjectsODst); /** * replaces references to the firewall in tsrc with * references to its interfaces in SNAT rules */ DECLARE_NAT_RULE_PROCESSOR(ReplaceFirewallObjectsTSrc); /** * distinguishes SNAT from Masquerading (can do * this after * firewall objects has been replaced with its * interfaces * and basic NAT rule type has been determined) */ DECLARE_NAT_RULE_PROCESSOR(dynamicInterfaceInTSrc); /** * takes care of dynamic interfaces in ODst (if ODst contains * interface and its address is dynamic, replace it with any) */ DECLARE_NAT_RULE_PROCESSOR(dynamicInterfaceInODst); /** * splits rule element if src or dst contains * address * range. This inspector differs from the standard one * in * the base class NATCompiler */ DECLARE_NAT_RULE_PROCESSOR(ExpandAddressRanges); /** * splits rules so multiport module can be used (only works for UDP and TCP) */ DECLARE_NAT_RULE_PROCESSOR(prepareForMultiport); /** * splits rules using multiple ICMP services */ DECLARE_NAT_RULE_PROCESSOR(splitMultipleICMP); /** * deals with negation in OSrc */ DECLARE_NAT_RULE_PROCESSOR(doOSrcNegation); /** * deals with negation in ODst */ DECLARE_NAT_RULE_PROCESSOR(doODstNegation); /** * deals with negation in OSrv */ DECLARE_NAT_RULE_PROCESSOR(doOSrvNegation); /** * splits DNAT rule if "Assume firewall is part of any" is ON * and OSrc is any. Need this to take care of the case with * packets originating on the firewall in DNAT rules. */ DECLARE_NAT_RULE_PROCESSOR(splitIfOSrcAny); /** * splits NONAT rule and assigns chains to PREROUTING, * POSTROUTING and OUTPUT. Always call this processor before * decideOnChain */ DECLARE_NAT_RULE_PROCESSOR(splitNONATRule); /** * sets chain and possibly splits a NAT rule if firewall or * its interface is in OSrc. */ DECLARE_NAT_RULE_PROCESSOR(localNATRule); /** * special case of DNAT rule for packets originated on the * firewall itself * (should go to the OUTPUT chain) */ DECLARE_NAT_RULE_PROCESSOR(DNATforFW); /** * decides what chain this rule should go to. */ DECLARE_NAT_RULE_PROCESSOR(decideOnChain); /** * decides on "jump to" chain */ DECLARE_NAT_RULE_PROCESSOR(decideOnTarget); /** * split rule for efficiency where multiple srcs & dsts are present */ DECLARE_NAT_RULE_PROCESSOR(splitMultiSrcAndDst); /** * MAC address filtering is permitted only in DNAT rules (only * in PREROUTING chain) */ DECLARE_NAT_RULE_PROCESSOR(verifyRuleWithMAC); /** * eliminates duplicate objects in SRC. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRC : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRC(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInODST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInODST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRV : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRV(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrv::TYPENAME) {} }; /** * Split rule if MultiAddress object is used in RE to make * sure it is single object. */ class processMultiAddressObjectsInRE : public NATRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : NATRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInOSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInOSrc(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementOSrc::TYPENAME) {} }; class processMultiAddressObjectsInODst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInODst(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementODst::TYPENAME) {} }; class processMultiAddressObjectsInTSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInTSrc(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementTSrc::TYPENAME) {} }; class processMultiAddressObjectsInTDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInTDst(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementTDst::TYPENAME) {} }; /** * count how many times each user-defined chain we've created is * used. We should be able to drop unused chains. */ DECLARE_NAT_RULE_PROCESSOR(countChainUsage); /** * prints single policy rule, assuming all * groups have * been expanded, so source, destination and * service hold * exactly one object each, and this object is * not a * group. Negation should also have been taken care of * * before this method is called. */ class PrintRule : public NATRuleProcessor { protected: bool init; bool print_once_on_top; bool minus_n_tracker_initialized; std::string current_rule_label; std::string version; void initializeMinusNTracker(); QString getInterfaceName(libfwbuilder::RuleElement *itf_re); /* * Prints single --option with argument and negation "!" * taking into account the change that happened in iptables 1.4.3.1 * that causes warning * Using intrapositioned negation (`--option ! this`) is deprecated in favor of extrapositioned (`! --option this`). */ virtual std::string _printSingleOptionWithNegation( const std::string &option, libfwbuilder::RuleElement *rel, const std::string &arg); virtual std::string _createChain(const std::string &chain); virtual std::string _startRuleLine(); virtual std::string _endRuleLine(); virtual std::string _printRuleLabel(libfwbuilder::NATRule *r); virtual std::string _printProtocol(libfwbuilder::Service *srv); virtual std::string _printSrcService(libfwbuilder::RuleElementOSrv *o); virtual std::string _printDstService(libfwbuilder::RuleElementOSrv *o); virtual std::string _printICMP(libfwbuilder::ICMPService *srv); virtual std::string _printIP(libfwbuilder::IPService *srv); virtual std::string _printOPorts(int rs,int re); virtual std::string _printTPorts(int rs,int re); virtual std::string _printSrcPorts(libfwbuilder::Service *srv); virtual std::string _printDstPorts(libfwbuilder::Service *srv); virtual std::string _printSNATPorts(libfwbuilder::Service *srv); virtual std::string _printDNATPorts(libfwbuilder::Service *srv); virtual std::string _printMultiport(libfwbuilder::NATRule *r); virtual std::string _printAddr(libfwbuilder::Address *o, bool print_mask=true, bool print_range=false); virtual std::string _printIpSetMatch( libfwbuilder::Address *o, libfwbuilder::RuleElement *rel); virtual std::string _printChainDirectionAndInterface(libfwbuilder::NATRule *r); virtual std::string _printSingleObjectNegation(libfwbuilder::RuleElement *rel); public: PrintRule(const std::string &name); void initialize(); virtual std::string _declareTable(); virtual std::string _commit(); virtual std::string _quote(const std::string &s); virtual bool processNext(); }; friend class NATCompiler_ipt::PrintRule; class PrintRuleIptRst : public PrintRule { virtual std::string _createChain(const std::string &chain); virtual std::string _startRuleLine(); virtual std::string _endRuleLine(); virtual std::string _printRuleLabel(libfwbuilder::NATRule *r); public: PrintRuleIptRst(const std::string &name) : PrintRule(name) {}; virtual std::string _declareTable(); virtual std::string _commit(); virtual std::string _quote(const std::string &s); virtual bool processNext(); }; friend class NATCompiler_ipt::PrintRuleIptRst; class PrintRuleIptRstEcho : public PrintRuleIptRst { virtual std::string _createChain(const std::string &chain); virtual std::string _startRuleLine(); virtual std::string _endRuleLine(); public: PrintRuleIptRstEcho(const std::string &name) : PrintRuleIptRst(name) {}; virtual std::string _declareTable(); virtual std::string _commit(); virtual std::string _quote(const std::string &s); virtual bool processNext(); }; friend class NATCompiler_ipt::PrintRuleIptRstEcho; virtual std::string myPlatformName(); public: NATCompiler_ipt(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, std::map *m_n_commands_map) : NATCompiler(_db, fw, ipv6_policy, _oscnf) { have_dynamic_interfaces=false; printRule=NULL; minus_n_commands = m_n_commands_map; branch_ruleset_to_chain_mapping = NULL; } /** * this method registers chain used for the ruleset (most * often branch rule set). Since rules in the same ruleset do * not use this chain as target, rule processor * countChainUsage considers it unused. Registering it makes * sure its usage counter is > 0. */ void registerRuleSetChain(const std::string &chain_name); virtual void verifyPlatform(); virtual int prolog(); virtual void compile(); virtual void epilog(); void setHaveDynamicInterfaces(bool f) { have_dynamic_interfaces=f; } virtual std::string flushAndSetDefaultPolicy(); virtual std::string printAutomaticRules(); std::string commit(); std::list getUsedChains(); static std::string getNewTmpChainName(libfwbuilder::NATRule *rule); void setRulesetToChainMapping(const std::map > *m) { branch_ruleset_to_chain_mapping = m; } }; } #endif fwbuilder-5.1.0.3599/src/iptlib/CompilerDriver_ipt.cpp0000644000175000017500000002027311733011756023362 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "Configlet.h" #include "CompilerDriver_ipt.h" #include "PolicyCompiler_ipt.h" #include "PolicyCompiler_secuwall.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/IPService.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver_ipt::CompilerDriver_ipt(FWObjectDatabase *db) : CompilerDriver(db) { have_connmark = false; have_connmark_in_output = false; } CompilerDriver_ipt::~CompilerDriver_ipt() { } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_ipt::clone() { CompilerDriver_ipt* new_cd = new CompilerDriver_ipt(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } void CompilerDriver_ipt::assignRuleSetChain(RuleSet *ruleset) { string branch_name = ruleset->getName(); for (FWObject::iterator r=ruleset->begin(); r!=ruleset->end(); r++) { Rule *rule = Rule::cast(*r); if (rule == NULL) continue; // skip RuleSetOptions object if (rule->isDisabled()) continue; if (!ruleset->isTop()) rule->setStr("ipt_chain", branch_name); // ??? // rule->setUniqueId( FWObjectDatabase::getStringId(rule->getId()) ); } } void CompilerDriver_ipt::findBranchesInMangleTable(Firewall *fw, list &all_policies) { // special but common case: if we only have one policy, there is // no need to check if we have to do branching in mangle table // since we do not have any branching rules in that case. if (all_policies.size() > 1) { for (list::iterator i=all_policies.begin(); i!=all_policies.end(); ++i) { for (list::iterator r=(*i)->begin(); r!=(*i)->end(); ++r) { PolicyRule *rule = PolicyRule::cast(*r); if (rule == NULL) continue; // skip RuleSetOptions object FWOptions *ruleopt = rule->getOptionsObject(); if (rule->getAction() == PolicyRule::Branch && ! ruleopt->getBool("ipt_branch_in_mangle")) { RuleSet *ruleset = rule->getBranch(); if (ruleset == NULL) { abort(fw, *i, rule, "Action branch does not point to any rule set"); } for (list::iterator br=ruleset->begin(); br!=ruleset->end(); ++br) { PolicyRule *b_rule = PolicyRule::cast(*br); if (b_rule == NULL) continue; if (b_rule->getTagging() || b_rule->getClassification()) ruleopt->setBool("ipt_branch_in_mangle", true); } } } } } } /* * TODO: use configlet to define structure of generated script. Need 2 * configlets: for the shell script format and iptables-restore format * However in order to use configlets in an efficient manner, we need * to be able to use if-then-else statements there. This will help * implement logic that skips filter or mangle or nat segments if * there are no rules in them. * * Also will need either special configlets for the single-rule * compile or more if-then-else in configlet code. */ string CompilerDriver_ipt::dumpScript(Firewall *fw, const string& automatic_rules_script, const string& automatic_mangle_script, const string& nat_script, const string& mangle_script, const string& filter_script, bool ipv6_policy) { // cerr << "nat script" << endl; // cerr << "\"" << nat_script << "\"" << endl; ostringstream res; ostringstream script; string prolog_place = fw->getOptionsObject()->getStr("prolog_place"); Configlet *conf = NULL; bool have_auto = !automatic_rules_script.empty() || !automatic_mangle_script.empty(); if (single_rule_compile_on) { have_auto = false; conf = new Configlet(fw, "linux24", "script_body_single_rule"); conf->collapseEmptyStrings(true); } else { if (fw->getOptionsObject()->getBool("use_iptables_restore")) { conf = new Configlet(fw, "linux24", "script_body_iptables_restore"); } else conf = new Configlet(fw, "linux24", "script_body_iptables_shell"); } conf->setVariable("auto", have_auto); conf->setVariable("iptables_restore_format", fw->getOptionsObject()->getBool("use_iptables_restore")); conf->setVariable("filter", !filter_script.empty()); conf->setVariable("filter_or_auto", have_auto || !filter_script.empty()); conf->setVariable("filter_auto_script", automatic_rules_script.c_str()); conf->setVariable("filter_script", filter_script.c_str()); conf->setVariable("mangle", !mangle_script.empty()); conf->setVariable("mangle_or_auto", !mangle_script.empty() || !automatic_mangle_script.empty()); conf->setVariable("mangle_auto_script", automatic_mangle_script.c_str()); conf->setVariable("mangle_script", mangle_script.c_str()); conf->setVariable("nat", !nat_script.empty()); conf->setVariable("nat_script", nat_script.c_str()); bool have_script = (have_auto || !filter_script.empty() || !mangle_script.empty() || !nat_script.empty()); conf->setVariable("have_script", have_script); conf->setVariable("ipv4", !ipv6_policy); conf->setVariable("ipv6", ipv6_policy); res << conf->expand().toStdString(); delete conf; return res.str(); } std::auto_ptr CompilerDriver_ipt::createPolicyCompiler( Firewall *fw, bool ipv6_policy, OSConfigurator *oscnf, std::map *minus_n_commands_filter) { string platform = fw->getStr("platform"); string platform_family = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/family"); std::auto_ptr policy_compiler; if (fw->getStr("host_OS") == "secuwall") { policy_compiler = std::auto_ptr( new PolicyCompiler_secuwall(objdb,fw, ipv6_policy, oscnf, minus_n_commands_filter)); } else { policy_compiler = std::auto_ptr( new PolicyCompiler_ipt(objdb,fw, ipv6_policy, oscnf, minus_n_commands_filter)); } if (policy_compiler.get()==NULL) abort("Unrecognized firewall platform " + fw->getStr("platform") + " (family " + platform_family+")"); return policy_compiler; } fwbuilder-5.1.0.3599/src/iptlib/AutomaticRules_ipt.h0000644000175000017500000000346611733011756023047 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __AUTOMATICRULES_IPT_HH__ #define __AUTOMATICRULES_IPT_HH__ #include "AutomaticRules.h" namespace libfwbuilder { class Address; class Firewall; class Interface; class Service; }; namespace fwcompiler { class AutomaticRules_ipt : public AutomaticRules { public: AutomaticRules_ipt(libfwbuilder::Firewall *fw, libfwbuilder::Library *presistent_objects) : AutomaticRules(fw, presistent_objects) {} virtual libfwbuilder::PolicyRule* addMgmtRule( libfwbuilder::Address* src, libfwbuilder::Address* dst, libfwbuilder::Service* service, libfwbuilder::Interface* iface, const libfwbuilder::PolicyRule::Direction direction, const libfwbuilder::PolicyRule::Action action, const std::string &label, bool related = false); void addConntrackRule(); void addFailoverRules(); }; }; #endif fwbuilder-5.1.0.3599/src/iptlib/iptlib.pro0000644000175000017500000000343211733011756021057 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) TEMPLATE = lib SOURCES = CompilerDriver_ipt.cpp \ CompilerDriver_ipt_run.cpp \ CompilerDriver_ipt_policy.cpp \ CompilerDriver_ipt_nat.cpp \ MangleTableCompiler_ipt.cpp \ NATCompiler_PrintRule.cpp \ NATCompiler_PrintRuleIptRst.cpp \ NATCompiler_PrintRuleIptRstEcho.cpp \ NATCompiler_ipt.cpp \ OSConfigurator_ipcop.cpp \ OSConfigurator_linux24.cpp \ OSConfigurator_linux24_interfaces.cpp \ OSConfigurator_secuwall.cpp \ OSData.cpp \ PolicyCompiler_PrintRule.cpp \ PolicyCompiler_PrintRuleIptRst.cpp \ PolicyCompiler_PrintRuleIptRstEcho.cpp \ PolicyCompiler_ipt.cpp \ PolicyCompiler_ipt_optimizer.cpp \ PolicyCompiler_secuwall.cpp \ RoutingCompiler_ipt.cpp \ RoutingCompiler_ipt_writers.cpp \ Preprocessor_ipt.cpp \ combinedAddress.cpp \ AutomaticRules_ipt.cpp \ ipt_utils.cpp HEADERS = ../../config.h \ CompilerDriver_ipt.h \ MangleTableCompiler_ipt.h \ NATCompiler_ipt.h \ OSConfigurator_ipcop.h \ OSConfigurator_linux24.h \ OSConfigurator_secuwall.h \ OSData.h \ PolicyCompiler_ipt.h \ PolicyCompiler_secuwall.h \ RoutingCompiler_ipt.h \ Preprocessor_ipt.h \ combinedAddress.h \ AutomaticRules_ipt.h \ ipt_utils.h CONFIG += staticlib INCLUDEPATH += ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../compiler_lib ../libfwbuilder/src win32:PRE_TARGETDEPS = ../compiler_lib/release/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/release/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/release/libfwbuilder.a !win32:PRE_TARGETDEPS = ../compiler_lib/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/libfwbuilder.a TARGET = iptlib INSTALLS -= target fwbuilder-5.1.0.3599/src/iptlib/RoutingCompiler_ipt_writers.cpp0000644000175000017500000002601011733011756025330 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Modified: Vadim Kurland vadim@vk.crocodile.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "RoutingCompiler_ipt.h" #include "Configlet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ string RoutingCompiler_ipt::PrintRule::_printAddr(Address *o) { ostringstream ostr; if (Interface::cast(o)!=NULL) { Interface *iface=Interface::cast(o); if (iface->isDyn()) ostr << "$interface_" << iface->getName() << " "; return ostr.str(); } const InetAddr *addr; const InetAddr *mask; addr = o->getAddressPtr(); mask = o->getNetmaskPtr(); if (addr==NULL) { FWObject *obj=o; /* * check if this is object of class Address. since we want to * distinguish between Host, Interface and Address, and both Host and * Interface are inherited from Address, we can't use cast. Use isA * instead */ while (obj!=NULL && !Host::isA(obj) && !Firewall::isA(obj) && !Network::isA(obj)) obj=obj->getParent(); compiler->abort( "Problem with address or netmask in the object or " "one of its interfaces: '" + obj->getName() + "'"); } if (addr->isAny() && mask->isAny()) { ostr << "default "; } else { ostr << addr->toString(); if (Interface::cast(o)==NULL && Address::cast(o)->dimension() > 1 && !mask->isHostMask()) { ostr << "/" << mask->getLength(); } ostr << " "; } return ostr.str(); } RoutingCompiler_ipt::PrintRule::PrintRule(const std::string &name) : RoutingRuleProcessor(name) { print_once_on_top=true; } bool RoutingCompiler_ipt::PrintRule::processNext() { RoutingCompiler_ipt *ipt_comp = dynamic_cast(compiler); RoutingRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (print_once_on_top && !compiler->inSingleRuleCompileMode()) { // string os_family = Resources::os_res[compiler->fw->getStr("host_OS")]-> // getResourceStr("/FWBuilderResources/Target/family"); Configlet routing_functions(compiler->fw, "linux24", "routing_functions"); // we should delete default route if we have a new one to // install. IF user did not define any routes that look like // default (i.e. where destination is "any"), then we should // preserve default so that we won't leave machine with no // default at all. QString route_pattern = ""; if (ipt_comp->have_default_route) { // If we will install default route, delete it now route_pattern = "'proto kernel'"; } else { // do not delete default if we won't install new one route_pattern = "'\\( proto kernel \\)\\|\\(default via \\)'"; } routing_functions.setVariable("proto_filter", route_pattern); compiler->output << routing_functions.expand().toStdString(); ipt_comp->defined_restore_script_output = true; print_once_on_top = false; } // TODO: convert this into virtual function RoutingCompiler_ipt::printComment() string rl = rule->getLabel(); string comm = rule->getComment(); string::size_type c1,c2; c1=0; if (!compiler->inSingleRuleCompileMode() && rl!=current_rule_label) { compiler->output << "# " << endl; compiler->output << "# Rule " << rl << endl; //compiler->output << "# " << rule->getRuleTypeAsString() << endl; compiler->output << "# " << endl; compiler->output << "echo \"Routing rule " << rl << "\"" << endl; compiler->output << "# " << endl; } if( rule->getRuleType() != RoutingRule::MultiPath ) { if (!compiler->inSingleRuleCompileMode() && rl!=current_rule_label) { while ( (c2=comm.find('\n',c1))!=string::npos ) { compiler->output << "# " << comm.substr(c1,c2-c1) << endl; c1=c2+1; } compiler->output << "# " << comm.substr(c1) << endl; compiler->output << "# " << endl; string err = compiler->getErrorsForRule(rule, "# "); if (!err.empty()) compiler->output << err << endl; current_rule_label = rl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) compiler->output << "# " << err << endl; string command_line = RoutingRuleToString(rule); compiler->output << command_line; } else { // the ecmp_id contains the table, the rule label and the metric. These are the properties the ecmp rules are distinguished string metric = rule->getMetricAsString(); string ecmp_id = rule->getSortedDstIds() + "#" + metric; if (rl!=current_rule_label) { compiler->output << "# Some sub rules belonging to an ECMP (Equal Cost Multi Path) rule were placed in the ECMP section below." << endl; current_rule_label=rl; } map< string, string>& ecmp_rules_buffer = ((RoutingCompiler_ipt*)compiler)->ecmp_rules_buffer; map< string, string>& ecmp_comments_buffer = ((RoutingCompiler_ipt*)compiler)->ecmp_comments_buffer; map< string, string>::iterator ecmp_rules_buffer_it; ecmp_rules_buffer_it = ecmp_rules_buffer.find(ecmp_id); if( ecmp_rules_buffer_it == ecmp_rules_buffer.end() ) { // ECMP Dst not seen so far, add "ip route add x.x.x.x" // and comment's header ecmp_comments_buffer[ecmp_id] = "#\n# Multipath Rule " " derived from the following routing rules:\n#\n"; if (rule->getMetricAsString() != "0") { ecmp_rules_buffer[ecmp_id] += "$IP route add " + _printRDst(rule) + "metric " + metric; } else { ecmp_rules_buffer[ecmp_id] += "$IP route add " + _printRDst(rule); } } ecmp_comments_buffer[ecmp_id] += "# Rule " + rl + "\n"; while ( (c2=comm.find('\n',c1))!=string::npos ) { ecmp_comments_buffer[ecmp_id] += "# " + comm.substr(c1,c2-c1) + "\n"; c1=c2+1; } ecmp_comments_buffer[ecmp_id] += "# " + comm.substr(c1) + "\n"; // Collect the nexthop information for the multipath rules, indexed by the sorted dst ids ecmp_rules_buffer[ecmp_id] += " \\\nnexthop " ; ecmp_rules_buffer[ecmp_id] += _printRGtw(rule); ecmp_rules_buffer[ecmp_id] += _printRItf(rule); } return true; } string RoutingCompiler_ipt::PrintRule::RoutingRuleToString(RoutingRule *rule) { FWObject *ref; RuleElementRDst *dstrel=rule->getRDst(); ref=dstrel->front(); Address *dst=Address::cast(FWReference::cast(ref)->getPointer()); if(dst==NULL) compiler->abort(rule, "Broken DST"); ostringstream command_line; command_line << "$IP route add "; command_line << _printRDst(rule); if (rule->getMetricAsString() != "0") { command_line << " metric " << rule->getMetricAsString() << " "; } command_line << _printRGtw(rule); command_line << _printRItf(rule); // to make generated script more readable in single rule compile mode, // skip the part that rolls back in case of an error if (!compiler->inSingleRuleCompileMode()) { command_line << "\\\n|| "; FWObject *opt_dummy = rule->getFirstByType(RoutingRuleOptions::TYPENAME); RoutingRuleOptions *opt = opt_dummy ? RoutingRuleOptions::cast(opt_dummy) : 0; if ( opt && opt->getBool("no_fail") ) { command_line << "echo \"*** Warning: routing rule " << rule->getLabel() << " failed. ignored. ***\"\n"; } else { command_line << "route_command_error " << "\"" << rule->getLabel() << "\"" << endl;; } } command_line << endl; return command_line.str(); } string RoutingCompiler_ipt::PrintRule::_printRGtw(RoutingRule *rule) { FWObject *ref; RuleElementRGtw *gtwrel = rule->getRGtw(); ref = gtwrel->front(); Address *gtw = Address::cast(FWReference::cast(ref)->getPointer()); if(gtw==NULL) compiler->abort(rule, "Broken GTW"); string gateway = _printAddr(gtw); if( gateway != "default ") return "via " + gateway; else return ""; } string RoutingCompiler_ipt::PrintRule::_printRItf(RoutingRule *rule) { FWObject *ref; RuleElementRItf *itfrel=rule->getRItf(); ref=itfrel->front(); Interface *itf=Interface::cast(FWReference::cast(ref)->getPointer()); if(itf != NULL) return "dev " + itf->getName() + " "; else return ""; } string RoutingCompiler_ipt::PrintRule::_printRDst(RoutingRule *rule) { FWObject *ref; RuleElementRDst *dstrel=rule->getRDst(); ref=dstrel->front(); Address *dst=Address::cast(FWReference::cast(ref)->getPointer()); if(dst==NULL) compiler->abort(rule, "Broken DST"); return _printAddr(dst); } fwbuilder-5.1.0.3599/src/iptlib/NATCompiler_ipt.cpp0000644000175000017500000024777611733011756022574 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include "ipt_utils.h" #include "combinedAddress.h" #include "fwcompiler/OSConfigurator.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; struct subnetInfo { Interface *iface; IPv4 *ipv4; int nmlength; subnetInfo() { iface=NULL; ipv4=NULL; nmlength=0; } subnetInfo(Interface *i,IPv4 *a,int n) { iface=i; ipv4=a; nmlength=n; } }; #if 0 static int chain_no=0; #endif static std::map tmp_chain_no; static std::list standard_chains; const std::list& NATCompiler_ipt::getStandardChains() { if (standard_chains.size()==0) { standard_chains.push_back("POSTROUTING"); standard_chains.push_back("PREROUTING"); standard_chains.push_back("SNAT"); standard_chains.push_back("DNAT"); standard_chains.push_back("MASQUERADE"); standard_chains.push_back("REDIRECT"); standard_chains.push_back("NETMAP"); standard_chains.push_back("LOG"); standard_chains.push_back("MARK"); standard_chains.push_back("ACCEPT"); standard_chains.push_back("REJECT"); standard_chains.push_back("DROP"); standard_chains.push_back("RETURN"); standard_chains.push_back("OUTPUT"); } return standard_chains; } string NATCompiler_ipt::myPlatformName() { return "iptables"; } /* * this function generates acceptable shell variable name from * interface name. Note that * OSConfigurator_linux24::getInterfaceVarName() and * PolicyCompiler_ipt::getInterfaceVarName() do the same thing and * these functions should be identical. * * TODO: really need to have one function for this instead of three in * three different classes. */ string NATCompiler_ipt::getInterfaceVarName(FWObject *iface, bool v6) { ostringstream ostr; string iname=iface->getName(); string::size_type p1; while ( (p1=iname.find("."))!=string::npos) iname=iname.replace(p1,1,"_"); while ( (p1=iname.find("-"))!=string::npos) iname=iname.replace(p1,1,"_"); ostr << "i_" << iname; if (v6) ostr << "_v6"; return ostr.str(); } string NATCompiler_ipt::getAddressTableVarName(FWObject *at) { ostringstream ostr; string name=at->getName(); string::size_type p1; const char *bad_shell_chars = " !#$&*()-+=\\|{}[]?<>,.:"; for (const char *cptr=bad_shell_chars; *cptr; cptr++) { while ( (p1=name.find(*cptr))!=string::npos) name=name.replace(p1,1,"_"); } ostr << "at_" << name; return ostr.str(); } string NATCompiler_ipt::getNewTmpChainName(NATRule *rule) { std::ostringstream str; string chain_id=rule->getUniqueId(); int n=tmp_chain_no[chain_id]; str << "C" << chain_id; str << "." << setw(1) << setfill('0') << n; n++; tmp_chain_no[chain_id]=n; return str.str(); #if 0 std::ostringstream str; str << "ntmp" << setw(3) << setfill('0') << chain_no; chain_no++; return str.str(); #endif } string NATCompiler_ipt::debugPrintRule(Rule *r) { NATRule *rule = NATRule::cast(r); return NATCompiler::debugPrintRule(rule)+ " c=" + rule->getStr("ipt_chain") + " t=" + rule->getStr("ipt_target") + " (type="+rule->getRuleTypeAsString()+")"; } void NATCompiler_ipt::verifyPlatform() { string family = Resources::platform_res[fw->getStr("platform")]-> getResourceStr("/FWBuilderResources/Target/family"); if (family != myPlatformName()) abort("Unsupported platform " + fw->getStr("platform") + " (family " + family + ")"); } int NATCompiler_ipt::prolog() { verifyPlatform(); // initialize counters for the standard chains for (list::const_iterator i = NATCompiler_ipt::getStandardChains().begin(); i != NATCompiler_ipt::getStandardChains().end(); ++i) { chain_usage_counter[*i] = 1; } int n = NATCompiler::prolog(); if ( n>0 ) { list l2=fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if ( iface->isDyn()) iface->setBool("use_var_address",true); } build_interface_groups(dbcopy, persistent_objects, fw, ipv6, regular_interfaces); } string version = fw->getStr("version"); using_ipset = (XMLTools::version_compare(version, "1.4.1.1") >= 0 && fwopt->getBool("use_m_set")); return n; } void NATCompiler_ipt::_expand_interface(Rule *rule, Interface *iface, std::list &list_result, bool expand_cluster_interfaces_fully) { std::list ol1; Compiler::_expand_interface( rule, iface, ol1, expand_cluster_interfaces_fully); // see utils.cpp expand_interface_with_phys_address(this, rule, iface, ol1, list_result); } bool compare_addresses_ptr(const InetAddr* a1, const InetAddr* a2) { return (*a1 < *a2); } /* * call this processor after classifyNATRules */ bool NATCompiler_ipt::ConvertLoadBalancingRules::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()==NATRule::LB) { RuleElementTDst *tdst=rule->getTDst(); assert(tdst); list al; for(list::iterator i=tdst->begin(); i!=tdst->end(); i++) { FWObject *o= *i; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); //const InetAddrMask *a = Address::cast(obj)->getAddressObjectInetAddrMask(); const InetAddr *ip_addr = Address::cast(obj)->getAddressPtr(); al.push_back( ip_addr ); } al.sort(compare_addresses_ptr); const InetAddr* a1 = al.front(); list::iterator j=al.begin(); j++; for ( ; j!=al.end(); j++) { /* I use temporary AddressRange object here because it takes care of * big endian/little endian conversion for me */ AddressRange tar; tar.setRangeStart( *a1 ); tar.setRangeEnd( *(*j) ); if ( tar.dimension() != 2 ) { compiler->abort( rule, "Non-contiguous address range in " "Translated Destination in load balancing NAT rule"); } a1 = *j; } AddressRange *ar = compiler->dbcopy->createAddressRange(); ar->setRangeStart( *(al.front()) ); ar->setRangeEnd( *(al.back()) ); ar->setName(string("%")+al.front()->toString() +"-"+al.back()->toString()+"%" ); compiler->persistent_objects->add(ar,false); tdst->clearChildren(); tdst->addRef(ar); rule->setRuleType(NATRule::DNAT); } return true; } /* * This processor should be called after classifyNATRule. Should call * classifyNATRule after this processor again. * * This algorithm is very much specific to iptables. Platforms where * this simple algorithm for SDNAT rules is not appropriate, should * either implement equivalent of this processor using different * algorithm, or should catch SDNAT rules and abort in their own * verifyNATRule processor. */ bool NATCompiler_ipt::splitSDNATRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if ( rule->getRuleType()==NATRule::SDNAT) { // RuleElementOSrc *osrc; RuleElementODst *odst; RuleElementOSrv *osrv; RuleElementTSrc *tsrc; RuleElementTDst *tdst; RuleElementTSrv *tsrv; bool tsrv_translates_src_port = false; bool tsrv_translates_dst_port = false; Service *osrv_obj = compiler->getFirstOSrv(rule); Service *tsrv_obj = compiler->getFirstTSrv(rule); if (TCPUDPService::cast(osrv_obj) && TCPUDPService::cast(tsrv_obj)) { TCPUDPService *tu_osrv = TCPUDPService::cast(osrv_obj); TCPUDPService *tu_tsrv = TCPUDPService::cast(tsrv_obj); tsrv_translates_src_port = (tu_tsrv->getSrcRangeStart() != 0 && tu_tsrv->getDstRangeStart() == 0); tsrv_translates_dst_port = (tu_tsrv->getSrcRangeStart() == 0 && tu_tsrv->getDstRangeStart() != 0); if (tsrv_translates_dst_port && tu_osrv->getDstRangeStart() == tu_tsrv->getDstRangeStart() && tu_osrv->getDstRangeEnd() == tu_tsrv->getDstRangeEnd()) tsrv_translates_dst_port = false; // osrv and tsrv define the same ports if (tsrv_translates_src_port && tu_osrv->getSrcRangeStart() == tu_tsrv->getSrcRangeStart() && tu_osrv->getSrcRangeEnd() == tu_tsrv->getSrcRangeEnd()) tsrv_translates_src_port = false; // osrv and tsrv define the same ports } /* first rule translates destination and may translate service (depends * on the original rule). Set type to Unknown because this may become * DNAT or DNetNat - we will decide later. */ NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); r->setRuleType(NATRule::Unknown); tsrc = r->getTSrc(); tsrc->clearChildren(); tsrc->setAnyElement(); /* this rule translates destination and can't deal with source port * translation. Leave that to the second rule */ if (tsrv_translates_src_port) { tsrv = r->getTSrv(); tsrv->clearChildren(); tsrv->setAnyElement(); } tmp_queue.push_back(r); /* the second rule translates source and uses translated object in * ODst. Since the service could have been translated by the first * rule, we use TSrv in OSrv */ r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); r->setRuleType(NATRule::Unknown); /* if original rule involved negation in ODst, it should be processed * in the first of the two rules we create for SDNAT. Negation in OSrc * must be processed in both rules since the first rule does not * change OSrc */ odst = r->getODst(); odst->setNeg(false); odst->clearChildren(); for (FWObject::iterator i=rule->getTDst()->begin(); i!=rule->getTDst()->end(); i++) { FWObject *obj = FWObjectReference::getObject(*i); odst->addRef(obj); } if ( ! rule->getTSrv()->isAny()) { /* * If the first rule in the pair translated service and * changed destination port, we need to match it in the * second rule to only trsnslate source in the packets * that have been processed by the first rule. However * this only applies to the case when destination port has * been translated because the first rule uses DNAT which * can only translate dest. port. So, if TSrv has zero * dest. port range but non-zero source port range, we * should not match it here because in this case no * dest. port translation occurs. If TSrv translates both * source and destination ports, we create new TCP(UDP) * service object with only dest. port part and use it to * match. */ Service *tsrv = compiler->getFirstTSrv(rule); TCPUDPService *tu_tsrv = TCPUDPService::cast(tsrv); if (tu_tsrv && tu_tsrv->getDstRangeStart() != 0) { TCPUDPService *match_service = NULL; if (tu_tsrv->getSrcRangeStart() == 0) { // no source port tranlsation match_service = tu_tsrv; } else { // both source and dest port translation occurs match_service = TCPUDPService::cast( compiler->dbcopy->create(tsrv->getTypeName())); match_service->setName(tsrv->getName() + "_dport"); compiler->persistent_objects->add(match_service); match_service->setDstRangeStart(tu_tsrv->getDstRangeStart()); match_service->setDstRangeEnd(tu_tsrv->getDstRangeEnd()); } osrv = r->getOSrv(); osrv->clearChildren(); osrv->addRef(match_service); } } tdst = r->getTDst(); tdst->clearChildren(); tdst->setAnyElement(); if (tsrv_translates_dst_port) { tsrv = r->getTSrv(); tsrv->clearChildren(); tsrv->setAnyElement(); } tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::VerifyRules::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); if (tsrc->getNeg()) { compiler->abort( rule, "Can not use negation in translated source "); return true; } if (tdst->getNeg()) { compiler->abort( rule, "Can not use negation in translated destination."); return true; } if (tsrv->getNeg()) { compiler->abort( rule, "Can not use negation in translated service."); return true; } if (tsrv->size()!=1) { compiler->abort( rule, "Translated service should be 'Original' or should contain single object."); return true; } if ( Group::cast( compiler->getFirstTSrv(rule) )!=NULL) { compiler->abort( rule, "Can not use group in translated service."); return true; } if (rule->getRuleType()==NATRule::LB) { compiler->abort( rule, "Load balancing rules are not supported."); return true; } // Note that in -xt mode and in single rule compile compiler->abort // does not really abort processing if (rule->getRuleType()==NATRule::NATBranch) { RuleSet *branch = rule->getBranch(); if (branch == NULL) { compiler->abort( rule, "Action 'Branch' needs NAT rule set to point to"); return true; } else { if (!NAT::isA(branch)) { compiler->abort( rule, "Action 'Branch' must point to a NAT rule set " "(points to " + branch->getTypeName() + ")"); return true; } } } if (rule->getRuleType()==NATRule::SNAT ) { FWObject *o1 = FWReference::getObject(tsrc->front()); if ( ! tsrc->isAny() && Network::cast(o1)!=NULL) { compiler->abort( rule, "Can not use network object in translated source."); return true; } if (Interface::isA(o1) && Interface::cast(o1)->isUnnumbered()) { compiler->abort( rule, "Can not use unnumbered interface in " "Translated Source of a Source translation rule."); return true; } } if (rule->getRuleType()==NATRule::SNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstOSrc(rule)); Network *a2=Network::cast(compiler->getFirstTSrc(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength() != a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated source should both be networks of the same size."); return true; } } if (rule->getRuleType()==NATRule::DNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstODst(rule)); Network *a2=Network::cast(compiler->getFirstTDst(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength() != a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated destination should both be networks of the same size ."); return true; } } tmp_queue.push_back(rule); return true; } /* * this should be called only after groupServicesByProtocol, so that we have * objects of the same type in OSrv and either "any" or a single * object in TSrv */ bool NATCompiler_ipt::VerifyRules2::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if (rule->getRuleType()!= NATRule::Return) { RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); Service *s1=compiler->getFirstOSrv(rule); Service *s2=compiler->getFirstTSrv(rule); if (osrv->isAny() && ! tsrv->isAny()) { compiler->abort( rule, "Can not use service object in Translated Service if Original Service is 'Any'."); return true; } if (!tsrv->isAny() && s1->getProtocolName()!=s2->getProtocolName()) { compiler->abort( rule, "Translated Service should be either 'Original' or should contain object of the same type as Original Service."); return true; } } tmp_queue.push_back(rule); return true; } /* * make sure combination of "-i" or "-o" interface spec and chosen chain * is allowed */ bool NATCompiler_ipt::VerifyRules3::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElement *itf_i_re = rule->getItfInb(); assert(itf_i_re!=NULL); RuleElement *itf_o_re = rule->getItfOutb(); assert(itf_o_re!=NULL); if (rule->getRuleType()==NATRule::SNAT && ! itf_i_re->isAny()) { // iptables does not allow "-i" in POSTROUTING chain compiler->abort( rule, "Can not use inbound interface specification with " "rules that translate source because iptables does not " "allow \"-i\" in POSTROUTING chain"); return true; } if (rule->getRuleType()==NATRule::DNAT && ! itf_o_re->isAny()) { // iptables does not allow "-o" in PREROUTING chain compiler->abort( rule, "Can not use outbound interface specification with " "rules that translate destination because iptables does not " "allow \"-o\" in PREROUTING chain"); return true; } string chain = rule->getStr("ipt_chain"); if (chain == "OUTPUT" && ! itf_i_re->isAny()) { // iptables does not allow "-i" in POSTROUTING chain compiler->abort( rule, "Can not use inbound interface specification with " "this rule because iptables does not " "allow \"-i\" in OUTPUT chain"); return true; } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::convertToAtomicportForOSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if (rule->getOSrv()->size()>1 && ! rule->getTSrv()->isAny()) { RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); for (FWObject::iterator i1=osrv->begin(); i1!=osrv->end(); ++i1) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s = r->getOSrv(); assert(s); s->clearChildren(); s->addRef(FWReference::getObject(*i1)); tmp_queue.push_back(r); } } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::portTranslationRules::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; Address *odst=compiler->getFirstODst(rule); // Service *osrv=compiler->getFirstOSrv(rule); Address *tsrc=compiler->getFirstTSrc(rule); Address *tdst=compiler->getFirstTDst(rule); Service *tsrv=compiler->getFirstTSrv(rule); if (rule->getRuleType() == NATRule::DNAT && tsrc->isAny() && tdst->isAny() && ! tsrv->isAny() && odst->getId()==compiler->fw->getId() ) { rule->getTDst()->addRef( odst ); } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::specialCaseWithRedirect::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; Address *tdst = compiler->getFirstTDst(rule); /* we consider rule redirect only if TDst is a firewall object * */ int fw_id = compiler->fw->getId(); int cluster_id = -1; bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); Cluster *cluster = NULL; if (cluster_member) { cluster = Cluster::cast( compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id"))); cluster_id = cluster->getId(); } if (rule->getRuleType() == NATRule::DNAT && (tdst->getId() == fw_id || tdst->getId() == cluster_id)) rule->setRuleType(NATRule::Redirect); tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::splitOnODst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementODst *odst=rule->getODst(); assert(odst); if (rule->getRuleType()==NATRule::DNAT && odst->size()!=1) { for(list::iterator i=odst->begin(); i!=odst->end(); ++i) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *a=Address::cast( o ); assert(a); NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementODst *nodst=r->getODst(); nodst->clearChildren(); nodst->addRef( a ); tmp_queue.push_back( r ); } } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::splitOnOSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); if (osrv->size()!=1) { for(list::iterator i=osrv->begin(); i!=osrv->end(); ++i) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementOSrv *nosrv=r->getOSrv(); nosrv->clearChildren(); nosrv->addRef( s ); tmp_queue.push_back( r ); } } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::fillTranslatedSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); Service *osrv_o=compiler->getFirstOSrv(rule); Service *tsrv_o=compiler->getFirstTSrv(rule); if ( ! osrv_o->isAny() && tsrv_o->isAny() ) { RuleElementTSrv *tsrv=rule->getTSrv(); tsrv->addRef(osrv_o); } return true; } bool NATCompiler_ipt::addVirtualAddress::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); Cluster *cluster = NULL; if (cluster_member) cluster = Cluster::cast( compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id"))); Address *a = NULL; if (rule->getRuleType()==NATRule::SNAT || rule->getRuleType()==NATRule::DNAT) { if (rule->getRuleType()==NATRule::SNAT) a = compiler->getFirstTSrc(rule); else a = compiler->getFirstODst(rule); Interface *iface = Interface::cast(a); if (iface && ! iface->isRegular()) return true; if ( ! a->isAny() && ! compiler->complexMatch(a, compiler->fw) && ! compiler->complexMatch(a, cluster)) { if (AddressRange::cast(a)!=NULL) { compiler->warning( rule, string("Adding of virtual address for address range " "is not implemented (object ") + a->getName() + ")" ); } else compiler->osconfigurator->addVirtualAddressForNAT( a ); } return true; } if (rule->getRuleType()==NATRule::SNetnat || rule->getRuleType()==NATRule::DNetnat) { if (rule->getRuleType()==NATRule::SNetnat) a=compiler->getFirstTSrc(rule); else a=compiler->getFirstODst(rule); if ( ! a->isAny() && Network::cast(a) ) compiler->osconfigurator->addVirtualAddressForNAT( Network::constcast(a) ); return true; } return true; } bool NATCompiler_ipt::splitRuleIfRuleElementIsDynamicInterface::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re =RuleElement::cast(rule->getFirstByType(re_type)); int nre = re->size(); vector cl; for(list::iterator i=re->begin(); nre>1 && i!=re->end(); ++i) { FWObject *o= *i; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *iface=Interface::cast(obj); if (iface!=NULL && !iface->isRegular()) { cl.push_back(o); // can not remove right now because remove invalidates iterator nre--; NATRule *new_rule= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); RuleElement *new_re=RuleElement::cast(new_rule->getFirstByType(re_type)); new_re->clearChildren(); new_re->setAnyElement(); new_re->addRef( iface ); tmp_queue.push_back(new_rule); } } if (!cl.empty()) { for (vector::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->remove( (*i1) ); } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::specialCaseWithUnnumberedInterface::dropUnnumberedInterface(RuleElement *re) { if (re->isAny()) return true; list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs =Interface::cast( obj ); if (ifs!=NULL && (ifs->isUnnumbered() || ifs->isBridgePort()) ) cl.push_back(obj); } if (!cl.empty()) { for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->removeRef( (*i1) ); } return (!re->isAny()); } bool NATCompiler_ipt::specialCaseWithUnnumberedInterface::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; bool keep_rule=true; switch (rule->getRuleType()) { case NATRule::Masq: case NATRule::SNAT: keep_rule=dropUnnumberedInterface( rule->getOSrc() ); break; case NATRule::DNAT: keep_rule=dropUnnumberedInterface( rule->getODst() ); break; default: ; } if (keep_rule) tmp_queue.push_back(rule); return true; } /* * I assume that there is always only one object in ODst, TSrc and TDst * rule elements. This should have been assured by inspector VerifyRules */ bool NATCompiler_ipt::ReplaceFirewallObjectsODst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); Cluster *cluster = NULL; if (cluster_member) cluster = Cluster::cast( compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id"))); tmp_queue.push_back(rule); list cl; RuleElementODst *rel; Address *obj=NULL; switch (rule->getRuleType()) { case NATRule::Masq: // case NATRule::Redirect: return true; default: rel=rule->getODst(); assert(rel); obj=compiler->getFirstODst(rule); assert(obj!=NULL); if (obj->getId()==compiler->fw->getId() || (cluster && obj->getId()==cluster->getId())) { list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *interface_=Interface::cast(*i); if (interface_->isLoopback()) continue; if (cluster && ! interface_->getOptionsObject()->getBool("cluster_interface")) continue; cl.push_back(interface_); } if ( ! cl.empty() ) { while (rel->size()) rel->remove( rel->front() ); for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) { rel->addRef( *i1 ); } } } } return true; } /* * This processor works together with ConvertToAtomicRules and * AssignInterfaces. If firewall object is used in TSrc of SNAT rule, * it gets replaced with its interfaces. ConvertToAtomicRules slits * this rule onto atomic rules, each of which has one interface object * in TSrc. AssigInterfaces then assigns each atomic rule to * corresponding interface. * * it seems the simplest way is just to assign SNAT rule to all * interfaces if firewall is used in TSrc. This automatically takes * care of weird cases where people use address that belongs to subnet * of one interface to do translation of packets going out through * another interface. Basically, compiler does not have information * about routing, so we have no choice but assume the routing can be * anything and assign the rule to all interfaces. */ bool NATCompiler_ipt::ReplaceFirewallObjectsTSrc::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); Cluster *cluster = NULL; if (cluster_member) cluster = Cluster::cast( compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id"))); tmp_queue.push_back(rule); list cl; RuleElementTSrc *rel; Address *obj=NULL; switch (rule->getRuleType()) { case NATRule::Masq: case NATRule::Redirect: return true; default: rel=rule->getTSrc(); assert(rel); obj=compiler->getFirstTSrc(rule); assert(obj!=NULL); if (obj->getId()==compiler->fw->getId() || (cluster && obj->getId()==cluster->getId())) { RuleElementODst *odstrel = rule->getODst(); Address *osrc = compiler->getFirstOSrc(rule); Address *odst = compiler->getFirstODst(rule); rel->clearChildren(); Interface *odst_iface = NULL; if (cluster) odst_iface = compiler->findInterfaceFor(odst, cluster); else odst_iface = compiler->findInterfaceFor(odst, compiler->fw); Interface *osrc_iface = NULL; if (cluster) osrc_iface = compiler->findInterfaceFor(osrc, compiler->fw); else osrc_iface = compiler->findInterfaceFor(osrc, compiler->fw); if (!odst->isAny() && odst_iface!=NULL && !odstrel->getBool("single_object_negation")) { rel->addRef(odst_iface); } else { /* * else use all interfaces except loopback and * unnumbered ones. Skip interface connected to ODst * if single object negation was detected in ODst. For * cluster members use only copy of cluster interfaces * (ticket #1185) */ list l2 = compiler->fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->isLoopback() || iface->isUnnumbered() || iface->isBridgePort() ) continue; // Note: comparing osrc_iface and odst_iface by name // because these objects are children of cluster if (odstrel->getBool("single_object_negation") && odst_iface && odst_iface->getName()==iface->getName()) continue; if (osrc_iface && osrc_iface->getName() == iface->getName()) continue; if (cluster && ! iface->getOptionsObject()->getBool("cluster_interface")) continue; rel->addRef( *i ); } for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) rel->addRef( *i1 ); /* it is an error if rule element is empty at this point. this could have * happened if all external interfaces are unnumbered */ if (rel->size()==0) { compiler->abort( rule, "Could not find suitable interface for the NAT rule. " "Perhaps all interfaces are unnumbered?"); } } } } return true; } bool NATCompiler_ipt::splitMultiSrcAndDst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *osrv=rule->getOSrv(); RuleElementOSrc *osrc=rule->getOSrc(); RuleElementODst *odst=rule->getODst(); RuleElementOSrc *rosrc; RuleElementODst *rodst; int nosrv=osrv->size(); int nosrc=osrc->size(); int nodst=odst->size(); /* * Return if service is set - svcs my introduce complications and I'm * treading carefully here. * We don't handle anything thats redirect, MASQ yet - just NONAT,SNAT & DNAT * We also check we've got multiple rules to deal with - we can't optimize * 1 src with 1 dst ... */ if ((nosrv>1 || !(osrv->isAny())) || (nosrc<1 || osrc->isAny()) || (nodst<1 || odst->isAny()) || (nosrc==1 && nodst==1) ) { tmp_queue.push_back(rule); return true; } switch (rule->getRuleType()) { case NATRule::NONAT: case NATRule::SNAT: case NATRule::DNAT: { // get old chain name create new chain name string new_chain = NATCompiler_ipt::getNewTmpChainName(rule); // create new rule NATRule *r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); // move existing rule onto new chain rule->setStr("ipt_chain", new_chain); // we've already tested for interface .... rule->setStr(".iface_in", "nil"); rule->setStr(".iface_out", "nil"); // new rule points to new chain, continues if no match r->setStr("ipt_target", new_chain); // Now decide which way round would be best ... if (nosrc < nodst) { rodst= r->getODst(); rodst->clearChildren(); rodst->setAnyElement(); osrc->clearChildren(); osrc->setAnyElement(); } else { rosrc = r->getOSrc(); rosrc->clearChildren(); rosrc->setAnyElement(); odst->clearChildren(); odst->setAnyElement(); } tmp_queue.push_back(r); } break; default: ; } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::dynamicInterfaceInODst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementODst *odstrel=rule->getODst(); assert(odstrel); Address *odst = compiler->getFirstODst(rule); if ( ! odstrel->isAny() ) { Interface *iface = Interface::cast(odst); if (iface!=NULL && iface->isDyn() && iface->isFailoverInterface()) { Address *new_odst = compiler->correctForCluster(odst); RuleElementODst *odst_re = rule->getODst(); assert(odst_re); odst_re->removeRef(odst); odst_re->addRef(new_odst); } } return true; } bool NATCompiler_ipt::dynamicInterfaceInTSrc::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); bool use_snat = ruleopt->getBool("ipt_use_snat_instead_of_masq"); tmp_queue.push_back(rule); Address *tsrc = compiler->getFirstTSrc(rule); if (rule->getRuleType()==NATRule::SNAT && Interface::cast(tsrc)!=NULL && !Interface::cast(tsrc)->isRegular()) { Interface *iface = Interface::cast(tsrc); if (iface->isFailoverInterface()) { Address *new_tsrc = compiler->correctForCluster(tsrc); RuleElementTSrc *tsrc_re = rule->getTSrc(); assert(tsrc); tsrc_re->removeRef(tsrc); tsrc_re->addRef(new_tsrc); } if (use_snat) { // Emulate SNAT with dynamic interface //tsrc->setBool("use_var_address", true); } else { rule->setRuleType(NATRule::Masq); if (rule->getStr("ipt_target")=="" || rule->getStr("ipt_target")=="SNAT") rule->setStr("ipt_target", "MASQUERADE"); } } return true; } /** * unlike standard inspector addressRanges in the base class NATCompiler, * this one does not expand address ranges in TSrc and TDst because * iptables supports ranges in those rule elements */ bool NATCompiler_ipt::ExpandAddressRanges::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *rel; rel=rule->getOSrc(); assert(rel); compiler->_expandAddressRanges(rule,rel); rel=rule->getODst(); assert(rel); compiler->_expandAddressRanges(rule,rel); return true; } void NATCompiler_ipt::checkForDynamicInterfacesOfOtherObjects::findDynamicInterfaces( RuleElement *re, Rule *rule) { if (re->isAny()) return; bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); FWObject *cluster = NULL; if (cluster_member) cluster = compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id")); list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs =Interface::cast( obj ); if (ifs!=NULL && ifs->isDyn() && ! ifs->isChildOf(compiler->fw) && ! ifs->isChildOf(cluster)) { QString err( "Can not build rule using dynamic interface '%1' " "of the object '%2' because its address in unknown."); compiler->abort( rule, err .arg(ifs->getName().c_str()) .arg(ifs->getParent()->getName().c_str()).toStdString()); } } } bool NATCompiler_ipt::checkForDynamicInterfacesOfOtherObjects::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; findDynamicInterfaces( rule->getOSrc() , rule ); findDynamicInterfaces( rule->getODst() , rule ); findDynamicInterfaces( rule->getTSrc() , rule ); findDynamicInterfaces( rule->getTDst() , rule ); tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::prepareForMultiport::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *rel= rule->getOSrv(); Service *srv= compiler->getFirstOSrv(rule); if (rel->size()==1) { tmp_queue.push_back(rule); return true; } /* * processor groupServicesByProtocol should have been called eariler, so now all * services in Srv are of the same type */ if (TCPService::isA(srv) || UDPService::isA(srv)) { rule->setBool("ipt_multiport",true); /* make sure we have no more than 15 ports */ if (rel->size()>15) { int n=0; NATRule *r; RuleElementOSrv *nsrv=NULL; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (n==0) { r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getOSrv(); nsrv->clearChildren(); tmp_queue.push_back(r); } assert(nsrv!=NULL); nsrv->addRef( s ); if (++n>=15) n=0; } } else { tmp_queue.push_back(rule); } // tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::splitMultipleICMP::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *rel= rule->getOSrv(); Service *srv= compiler->getFirstOSrv(rule); if (rel->size()==1) { tmp_queue.push_back(rule); return true; } if (ICMPService::isA(srv)) { NATRule *r; RuleElementOSrv *nsrv; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getOSrv(); nsrv->clearChildren(); nsrv->addRef( s ); tmp_queue.push_back(r); } } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::doOSrcNegation::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrcrel=rule->getOSrc(); /* ! A B C */ if (osrcrel->getNeg()) { NATRule *r; RuleElementOSrc *nsrc; RuleElementODst *ndst; RuleElementOSrv *nsrv; RuleElementTSrc *ntsrc; RuleElementTDst *ntdst; RuleElementTSrv *ntsrv; string new_chain = NATCompiler_ipt::getNewTmpChainName(rule); osrcrel->setNeg(false); /* * negation in OSrc : * * CHAIN !A B C RULE_TYPE TARGET *----------------------------------------------- * ----- any B C SNAT/DNAT TMP_CHAIN * TMP_CHAIN A any any RETURN RETURN * TMP_CHAIN any any C SNAT/DNAT --------- */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); // ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); // ntdst=r->getTDst(); ntdst->clearChildren(); ntdst->setAnyElement(); // r->setRuleType(NATRule::Continue); r->setStr("ipt_target",new_chain); // r->setBool("rule_added_for_osrc_neg",true); tmp_queue.push_back(r); /* TMP_CHAIN A any any RETURN */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); nsrv=r->getOSrv(); nsrv->clearChildren(); nsrv->setAnyElement(); ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); ntdst=r->getTDst(); ntdst->clearChildren(); ntdst->setAnyElement(); ntsrv=r->getTSrv(); ntsrv->clearChildren(); ntsrv->setAnyElement(); ndst->setNeg(false); nsrv->setNeg(false); r->setRuleType(NATRule::Return); r->setStr("ipt_target","RETURN"); r->setStr("ipt_chain",new_chain); r->setStr(".iface_in", "nil"); r->setStr(".iface_out", "nil"); //r->setInterfaceStr("nil"); r->setBool("rule_added_for_osrc_neg",true); tmp_queue.push_back(r); /* TMP_CHAIN any any C ACTION */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); nsrv=r->getOSrv(); ndst->setNeg(false); nsrv->setNeg(false); r->setStr("ipt_chain",new_chain); r->setStr(".iface_in", "nil"); r->setStr(".iface_out", "nil"); //r->setInterfaceStr("nil"); r->setBool("rule_added_for_osrc_neg",true); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::doODstNegation::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementODst *odstrel=rule->getODst(); /* ! A B C */ if (odstrel->getNeg()) { NATRule *r; RuleElementOSrc *nsrc; RuleElementODst *ndst; RuleElementOSrv *nsrv; RuleElementTSrc *ntsrc; RuleElementTDst *ntdst; RuleElementTSrv *ntsrv; string new_chain=NATCompiler_ipt::getNewTmpChainName(rule); odstrel->setNeg(false); /* * negation in Odst : * * CHAIN A !B C RULE_TYPE TARGET *----------------------------------------------- * ----- A any C SNAT/DNAT TMP_CHAIN * TMP_CHAIN any B any RETURN RETURN * TMP_CHAIN any any C SNAT/DNAT --------- */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); // ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); // ntdst=r->getTDst(); ntdst->clearChildren(); ntdst->setAnyElement(); // r->setRuleType(NATRule::Continue); r->setStr("ipt_target",new_chain); r->setBool("rule_added_for_odst_neg",true); tmp_queue.push_back(r); /* TMP_CHAIN any B any RETURN */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); nsrv=r->getOSrv(); nsrv->clearChildren(); nsrv->setAnyElement(); ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); ntdst=r->getTDst(); ntdst->clearChildren(); ntdst->setAnyElement(); ntsrv=r->getTSrv(); ntsrv->clearChildren(); ntsrv->setAnyElement(); nsrc->setNeg(false); nsrv->setNeg(false); r->setRuleType(NATRule::Return); r->setStr("ipt_target","RETURN"); r->setStr("ipt_chain",new_chain); r->setStr(".iface_in", "nil"); r->setStr(".iface_out", "nil"); //r->setInterfaceStr("nil"); // r->setBool("rule_added_for_odst_neg",true); tmp_queue.push_back(r); /* TMP_CHAIN any any C ACTION */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); nsrv=r->getOSrv(); nsrc->setNeg(false); nsrv->setNeg(false); r->setStr("ipt_chain",new_chain); r->setStr(".iface_in", "nil"); r->setStr(".iface_out", "nil"); //r->setInterfaceStr("nil"); r->setBool("rule_added_for_odst_neg",true); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::doOSrvNegation::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *osrvrel=rule->getOSrv(); /* A B ! C */ if (osrvrel->getNeg()) { NATRule *r; RuleElementOSrc *nsrc; RuleElementODst *ndst; RuleElementOSrv *nsrv; RuleElementTSrc *ntsrc; RuleElementTDst *ntdst; string new_chain=NATCompiler_ipt::getNewTmpChainName(rule); osrvrel->setNeg(false); /* * negation in OSrv : * * CHAIN A B !C RULE_TYPE TARGET *----------------------------------------------- * ----- A B any SNAT/DNAT TMP_CHAIN * TMP_CHAIN any any C RETURN RETURN * TMP_CHAIN any any any SNAT/DNAT --------- */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getOSrv(); nsrv->clearChildren(); nsrv->setAnyElement(); // ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); // ntdst=r->getTDst(); ntdst->clearChildren(); ntdst->setAnyElement(); // r->setRuleType(NATRule::Continue); r->setStr("ipt_target",new_chain); r->setBool("rule_added_for_osrv_neg",true); tmp_queue.push_back(r); /* TMP_CHAIN any any C RETURN */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); ntdst=r->getTDst(); ntdst->clearChildren(); ntdst->setAnyElement(); nsrc->setNeg(false); ndst->setNeg(false); r->setRuleType(NATRule::Return); r->setStr("ipt_target","RETURN"); r->setStr("ipt_chain",new_chain); r->setStr(".iface_in", "nil"); r->setStr(".iface_out", "nil"); //r->setInterfaceStr("nil"); r->setBool("rule_added_for_osrv_neg",true); tmp_queue.push_back(r); /* TMP_CHAIN any any any ACTION */ r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); nsrv=r->getOSrv(); nsrv->clearChildren(); nsrv->setAnyElement(); nsrc->setNeg(false); ndst->setNeg(false); r->setStr("ipt_chain",new_chain); r->setStr(".iface_in", "nil"); r->setStr(".iface_out", "nil"); //r->setInterfaceStr("nil"); // r->setBool("rule_added_for_osrv_neg",true); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::splitNONATRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if ( rule->getStr("ipt_chain").empty() && rule->getRuleType()==NATRule::NONAT) { Address *osrc=compiler->getFirstOSrc(rule); bool osrcfw= compiler->complexMatch(osrc,compiler->fw); /* * NONAT is special if OSrc matches firewall. It is not sufficient to * only put this rule in the OUTPUT chain because packets originating * on the firewall actually cross both OUTPUT and POSTROUTING chains * (I tested this). So, we need to make sure we _do not_ translate in * both these chains because there may be other rules in POSTROUTING * chain that may accidentally match the packet and translate it. */ NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","POSTROUTING"); tmp_queue.push_back(r); if (osrcfw) { rule->setStr("ipt_chain","OUTPUT"); if (osrc->getId()==compiler->fw->getId()) { RuleElementOSrc *src; src=rule->getOSrc(); src->clearChildren(); src->setAnyElement(); } } else rule->setStr("ipt_chain","PREROUTING"); tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); return true; } /** * Branch rule in NAT rule sets should go into PREROUTING or * POSTROUTING chain depending on the target of the rules in the * branch. Iptables verifies this when a command that passes control * (the one with "-j ") is entered. If branch * ruleset has -j SNAT, the command that sends control to the branch * should be in POSTROUTING. Attempt to place it in PREROUTING ends * with an error "iptables: Invalid argument". * * Note that if branch rule set contains a mix of rules that use both * SNAT and DNAT targets, the branching rule (that should pass control * to the branch) can not be added to PREROUTING and POSTROUTING * chains, it just gives an error "iptables: Invalid argument" for both. * Tested with iptables 1.4.1.1 10/20/2009 */ bool NATCompiler_ipt::splitNATBranchRule::processNext() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; if ( rule->getRuleType()==NATRule::NATBranch) { RuleSet *branch = rule->getBranch(); if (branch) { string branch_name = branch->getName(); if (ipt_comp->branch_ruleset_to_chain_mapping) { map >::const_iterator lit = ipt_comp->branch_ruleset_to_chain_mapping->find(branch_name); if (lit!=ipt_comp->branch_ruleset_to_chain_mapping->end()) { list chains = lit->second; list::iterator it; for (it=chains.begin(); it!=chains.end(); ++it) { string branch_chain = *it; // If chain in the branch rule set does not // start with its own name plus "_", skip it // because it is one of the standard chains if (branch_chain.find(branch_name + "_") == 0) { // branch chain is + "_" + string my_chain = branch_chain.substr(branch_name.length()+1); NATRule *r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain", my_chain); r->setStr("ipt_target", *it); tmp_queue.push_back(r); } } return true; } } compiler->warning(rule, "NAT branching rule does not have information" " about targets used in the branch ruleset" " to choose proper chain in the nat table." " Will split the rule and place it in both" " PREROUTNING and POSTROUTING"); NATRule *r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain", "POSTROUTING"); r->setStr("ipt_target", branch_name); tmp_queue.push_back(r); r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain", "PREROUTING"); r->setStr("ipt_target", branch_name); tmp_queue.push_back(r); return true; } else { compiler->abort(rule, "NAT branching rule misses branch rule set."); // in case we are in the test mode and abort() does not // really abort. Both the chain and the target are bogus // and are needed only to make the compiler continue and // produce some output, which will be shown to the user // together with the error in single-rule compile mode rule->setStr("ipt_chain", "PREROUTING"); rule->setStr("ipt_target", "UNDEFINED"); tmp_queue.push_back(rule); } } else tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::localNATRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; // if ( rule->getStr("ipt_chain").empty()) // { Address *osrc = compiler->getFirstOSrc(rule); bool osrcfw = compiler->complexMatch(osrc,compiler->fw); switch( rule->getRuleType()) { case NATRule::DNAT: case NATRule::DNetnat: case NATRule::Redirect: /* it should not be necessary to do anything if rule type is NONAT * since splitNONATRule takes care of NONAT rules * * is there any need to split the rule if it is SNAT or DNAT type ? I * can't see any reason to do it. * * Can use OUTPUT chain only for DNAT rules and a like */ if (osrcfw) rule->setStr("ipt_chain", "OUTPUT"); if (osrcfw && osrc->getId()==compiler->fw->getId()) { RuleElementOSrc *src; src=rule->getOSrc(); src->clearChildren(); src->setAnyElement(); } break; default: break; } // } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::splitIfOSrcAny::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); /* do not split if user nailed inbound interface */ RuleElement *itf_re = rule->getItfInb(); assert(itf_re!=NULL); if (! itf_re->isAny()) return true; /* do not split rules added to handle negation, these rules have "any" * in OSrc but get control only after OSrc is tested by another * rule */ if (rule->getBool("rule_added_for_osrc_neg")) return true; if (rule->getBool("rule_added_for_odst_neg")) return true; if (rule->getBool("rule_added_for_osrv_neg")) return true; if (rule->getRuleType()==NATRule::DNAT) { RuleElementOSrc *osrcrel = rule->getOSrc(); Address *osrc = compiler->getFirstOSrc(rule); // split if osrc is any OR if it has a single object with negation if (osrc->isAny() || osrcrel->getBool("single_object_negation")) { NATRule *r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementOSrc *nosrcrel = r->getOSrc(); nosrcrel->addRef(compiler->fw); tmp_queue.push_back(r); } } return true; } /* * we assume that splitIfOSrcMatchesFw was called before, so that if firewall * was in OSrc, it is now a single object in that rule element */ bool NATCompiler_ipt::DNATforFW::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()==NATRule::DNAT) { Address *osrc=compiler->getFirstOSrc(rule); if ( compiler->complexMatch(osrc,compiler->fw) ) { rule->setStr("ipt_chain","OUTPUT"); if (osrc->getId()==compiler->fw->getId()) { rule->getOSrc()->clearChildren(); rule->getOSrc()->setAnyElement(); } } } return true; } bool NATCompiler_ipt::decideOnChain::processNext() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); string chain; switch (rule->getRuleType()) { case NATRule::SNAT: chain = "POSTROUTING"; break; case NATRule::SNetnat: chain = "POSTROUTING"; break; case NATRule::Masq: chain = "POSTROUTING"; break; case NATRule::DNAT: chain = "PREROUTING"; break; case NATRule::DNetnat: chain = "PREROUTING"; break; case NATRule::Redirect: chain = "PREROUTING"; break; case NATRule::NONAT: // processor splitNONATRule took care of NONAT rule break; case NATRule::NATBranch: // processor splitNATBranchRule took care of NATBranch rule break; default: ; } if (!rule->getStr("ipt_chain").empty()) { if (!compiler->getSourceRuleSet()->isTop() && ipt_comp->getRuleSetName() == rule->getStr("ipt_chain")) { // this is a NAT branch. Need to rename the chain to add // information about the chain that would have been used // if this was top ruleset string new_chain = compiler->getRuleSetName() + "_" + chain; ipt_comp->registerRuleSetChain(new_chain); rule->setStr("ipt_chain", new_chain); } return true; // already defined } if (!chain.empty()) rule->setStr("ipt_chain", chain); return true; } bool NATCompiler_ipt::decideOnTarget::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if ( ! rule->getStr("ipt_target").empty() ) return true; // already defined switch (rule->getRuleType()) { case NATRule::NONAT: rule->setStr("ipt_target","ACCEPT"); break; case NATRule::SNAT: rule->setStr("ipt_target","SNAT"); break; case NATRule::SNetnat: rule->setStr("ipt_target","NETMAP"); break; case NATRule::DNAT: rule->setStr("ipt_target","DNAT"); break; case NATRule::DNetnat: rule->setStr("ipt_target","NETMAP"); break; case NATRule::Masq: rule->setStr("ipt_target","MASQUERADE"); break; case NATRule::Redirect: rule->setStr("ipt_target","REDIRECT"); break; case NATRule::Return: rule->setStr("ipt_target","RETURN"); break; case NATRule::NATBranch: // this case has been taken care for in splitNATBranchRule() break; default: ; } return true; } /* * This rule processor chooses interfaces for the rule automatically * if user did not set them manually in "Inbound Interface" and * "Outbound Interface" columns. * * Automatic algorithm: * * this processor works together with ReplaceFirewallObjectsTSrc and * ConvertToAtomicRules. If the first two left interface object in * TSrc, AssignInterfaces assigns this rule to the corresponding * interface. Rule will be split and assigned to all interfaces here * if object in TSrc is not an interface or an address of interface. * * Summary: SNAT rules are now assigned to interfaces (using "-o * iface_name") as follows: * * - if firewall's interface or its address is in TSrc, the rule the * uses its address for "--to-source" and its name for "-o" * * - if firewall object is in TSrc, then it gets replaced with its * interfaces (except unnumbered and loopback interfaces) and rule is * processed using each interface as described above * * - if some other object is in TSrc, the rule is assigned to all * interfaces of the firewall (using notation with '+') and address of * this object is used for "--to-source". There are reasons why rule * has to be explicitly assigned to all interfaces using "-o" as * opposed to skipping "-o" all together. consider for example a * configuration with an unnumbred tunnel interface (e.g. ipsec0) used * for "road varrior" connections where IP address on the other end of * the tunnel is unknown. We can not add a "no nat" rule because we do * not know address of the net on the other side of the tunnel, but * fortunately ipsec0 is skipped in the assignment of SNAT rule * because it is unnumbered, so the firewall won't translate packets * going through this interface. * * * NOTE: this rule processor may place groups of interfaces in inbound * and outbound interface rule elements. Names of these groups were * specifically constructed to match "wildcard" interface * specifications supported by iptables, such as "eth+". Do not call * rule processors that expand groups after AssignInterface. * */ bool NATCompiler_ipt::AssignInterface::processNext() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); NATRule *rule = getNext(); if (rule==NULL) return false; RuleElement *itf_re; itf_re = rule->getItfInb(); assert(itf_re!=NULL); if ( ! itf_re->isAny()) { tmp_queue.push_back(rule); return true; } itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->isAny()) { tmp_queue.push_back(rule); return true; } switch (rule->getRuleType()) { case NATRule::SNAT: case NATRule::Masq: { Address* tsrc = compiler->getFirstTSrc(rule); Interface *iface = Interface::cast(tsrc); if (IPv4::isA(tsrc) || IPv6::isA(tsrc)) { iface = Interface::cast(tsrc->getParent()); } if (iface) { FWObject *parent_host = Host::getParentHost(iface); if (Cluster::isA(parent_host)) { if (iface->isFailoverInterface()) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( iface->getFirstByType(FailoverClusterGroup::TYPENAME)); Interface *fw_iface = failover_group->getInterfaceForMemberFirewall(compiler->fw); if (fw_iface) { // this is a bit tricky: we assign rule to the // member firewall's inteface but TSrc remains // cluster interface or its address. iface = fw_iface; RuleElementItfOutb *itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); tmp_queue.push_back(rule); return true; } } else { // parent is the cluster but there is no failover // group. This must be a copy of the member interface. RuleElementItfOutb *itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); tmp_queue.push_back(rule); return true; } } else { if (iface->isChildOf(compiler->fw)) { RuleElementItfOutb *itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); tmp_queue.push_back(rule); return true; } } } #if 0 FWObject *p = iface->getParent(); qDebug() << "Checkpoint #1" << " iface=" << iface << " " << iface->getName().c_str() << " parent=" << p << " " << p->getName().c_str() << " " << p->getTypeName().c_str(); #endif /* if we appear here, then TSrc is not an interface or address of an * interface. This processor will simply pass a rule along if firewall * has no interfaces at all. I wonder if I really have to do this, * but I do it anyway. */ int n = 0; QMap::iterator it; for (it=ipt_comp->regular_interfaces.begin(); it!=ipt_comp->regular_interfaces.end(); ++it) { FWObject *itf_group = it.value(); // group "*" holds all interfaces if (itf_group->getName() == "*") continue; NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); RuleElementItfOutb *itf_re = r->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(itf_group)) itf_re->addRef(itf_group); //r->setInterfaceStr(intf_name.toStdString()); tmp_queue.push_back(r); n++; } if (n==0) tmp_queue.push_back(rule); return true; } break; default: ; } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::verifyRuleWithMAC::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *rel = rule->getOSrc(); if (rel->isAny()) { tmp_queue.push_back(rule); return true; } string chain = rule->getStr("ipt_chain"); if (chain!="PREROUTING" && chain!="FORWARD" && chain!="INPUT" ) { /* scan all objects in OSrc, look for physAddress or combinedAddress * with pa present. Objects like that are not allowed in chain POSTROUTING. * Issue warning and remove physAddress from the list. */ list cl; FWObject *pa=NULL; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; FWObject *o1= o; if (FWReference::cast(o)!=NULL) o1=FWReference::cast(o)->getPointer(); if (physAddress::isA(o1)) { pa=o1; cl.push_back(o1); } combinedAddress *ca=combinedAddress::cast(o1); if (ca!=NULL && ca->getPhysAddress()!="" ) { /* there are two possibilities: * 1 - combinedAddress consists of the IPv4 component and MAC address component * 2 - combinedAddress consists of an empty IPv4 component and MAC address . */ pa=o1; if ( ca->isAny() ) cl.push_back(o1); else ca->setPhysAddress(""); } } if (!cl.empty()) { for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) rel->removeRef( (*i1) ); } if (pa!=NULL) { if (rel->isAny()) { QString err( "SNAT rule can not match MAC address, however " "after removing object %1 from OSrc it becomes 'Any'"); compiler->abort(rule, err.arg(pa->getName().c_str()).toStdString()); return true; } else { QString err( "SNAT rule can not match MAC address. Object %1 " "removed from the rule"); compiler->warning(rule, err.arg(pa->getName().c_str()).toStdString()); } } } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::processMultiAddressObjectsInRE::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; OSConfigurator_linux24 *osconf = dynamic_cast(compiler->osconfigurator); RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); if (re->size()==1) { FWObject *o = re->front(); if (FWReference::cast(o)!=NULL) o = FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { // we have just one object in RE and this object is MutiAddressRunTime if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { string path = atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); if (path.empty() && !atrt->getSourceName().empty()) { compiler->abort(rule, "Firewall's data directory not set for address table: " + atrt->getName()); return true; } rule->setStr("address_table_file", path); osconf->registerMultiAddressObject(atrt); } if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { // this is DNSName converted to its run-time counterpart, // we do not need to touch it at all } tmp_queue.push_back(rule); return true; } } list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) cl.push_back(atrt); } if (!cl.empty()) { RuleElement *nre; RuleElement *ore=RuleElement::cast( rule->getFirstByType(re_type) ); NATRule *r; for (list::iterator i=cl.begin(); i!=cl.end(); i++) { MultiAddressRunTime *atrt = *i; r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( atrt ); string path = atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); if (path.empty() && !atrt->getSourceName().empty()) { compiler->abort(rule, "Firewall's data directory not set for address table: " + atrt->getName()); return true; } r->setStr("address_table_file", path); osconf->registerMultiAddressObject(atrt); tmp_queue.push_back(r); ore->removeRef( *i ); } } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipt::countChainUsage::processNext() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { NATRule *rule = NATRule::cast( *k ); ipt_comp->chain_usage_counter[rule->getStr("ipt_target")] += 1; } return true; } void NATCompiler_ipt::registerRuleSetChain(const std::string &chain_name) { chain_usage_counter[chain_name] = 1; } void NATCompiler_ipt::compile() { string banner = " Compiling ruleset " + getRuleSetName() + " for 'nat' table"; if (ipv6) banner += ", IPv6"; info(banner); Compiler::compile(); add( new NATCompiler::Begin()); add( new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new expandGroupsInItfInb("expand groups in inbound Interface")); add(new replaceClusterInterfaceInItfInb( "replace cluster interfaces with member interfaces in " "the inbound Interface rule element")); add(new singleObjectNegationItfInb("process single object negation in inbound Itf")); add(new ItfInbNegation("process negation in inbound Itf")); add(new expandGroupsInItfOutb("expand groups in outbound Interface")); add(new replaceClusterInterfaceInItfOutb( "replace cluster interfaces with member interfaces in " "the outbound Interface rule element")); add(new singleObjectNegationItfOutb("process single object negation in outbound Itf")); add(new ItfOutbNegation("process negation in outbound Itf")); add( new recursiveGroupsInOSrc("check for recursive groups in OSRC")); add( new recursiveGroupsInODst("check for recursive groups in ODST")); add( new recursiveGroupsInOSrv("check for recursive groups in OSRV")); add( new recursiveGroupsInTSrc("check for recursive groups in TSRC")); add( new recursiveGroupsInTDst("check for recursive groups in TDST")); add( new recursiveGroupsInTSrv("check for recursive groups in TSRV")); add( new emptyGroupsInOSrc("check for empty groups in OSRC" )); add( new emptyGroupsInODst("check for empty groups in ODST" )); add( new emptyGroupsInOSrv("check for empty groups in OSRV" )); add( new emptyGroupsInTSrc("check for empty groups in TSRC" )); add( new emptyGroupsInTDst("check for empty groups in TDST" )); add( new emptyGroupsInTSrv("check for empty groups in TSRV")); add( new ExpandGroups("Expand groups")); // processors that expand objects with multiple addresses // check addresses against current address family using member // ipv6. If all addresses do not match, we may end up with // empty rule element. add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); if (ipv6) add( new DropIPv4Rules("drop ipv4 rules")); else add( new DropIPv6Rules("drop ipv6 rules")); add( new eliminateDuplicatesInOSRC("eliminate duplicates in OSRC")); add( new eliminateDuplicatesInODST("eliminate duplicates in ODST")); add( new eliminateDuplicatesInOSRV("eliminate duplicates in OSRV")); add( new swapMultiAddressObjectsInOSrc( " swap MultiAddress -> MultiAddressRunTime in OSrc") ); add( new swapMultiAddressObjectsInODst( " swap MultiAddress -> MultiAddressRunTime in ODst") ); add( new swapMultiAddressObjectsInTSrc( " swap MultiAddress -> MultiAddressRunTime in TSrc") ); add( new swapMultiAddressObjectsInTDst( " swap MultiAddress -> MultiAddressRunTime in TDst") ); add( new processMultiAddressObjectsInOSrc( "process MultiAddress objects in OSrc") ); add( new processMultiAddressObjectsInODst( "process MultiAddress objects in ODst") ); add( new processMultiAddressObjectsInTSrc( "process MultiAddress objects in TSrc") ); add( new processMultiAddressObjectsInTDst( "process MultiAddress objects in TDst") ); add( new doOSrvNegation( "process negation in OSrv" )); add( new convertToAtomicportForOSrv("convert to atomic rules in OSrv")); add( new classifyNATRule( "classify NAT rule" )); add( new splitSDNATRule( "split SDNAT rules" )); add( new classifyNATRule( "reclassify rules" )); add( new ConvertLoadBalancingRules( "convert load balancing rules")); add( new VerifyRules( "verify rules" )); add( new singleObjectNegationOSrc( "negation in OSrc if it holds single object")); add( new singleObjectNegationODst( "negation in ODst if it holds single object")); add( new doOSrcNegation( "process negation in OSrc" )); add( new doODstNegation( "process negation in ODst" )); /* call splitOnODst after processing negation */ add( new splitOnODst( "split on ODst" )); add( new portTranslationRules( "port translation rules" )); add( new specialCaseWithRedirect( "special case with redirecting port translation rules" ) ); if (fwopt->getBool("local_nat") ) { if ( fwopt->getBool("firewall_is_part_of_any_and_networks") ) add( new splitIfOSrcAny( "split rule if OSrc is any" )); add( new splitIfOSrcMatchesFw("split rule if OSrc matches FW" )); } add( new splitNONATRule("NAT rules that request no translation")); add( new splitNATBranchRule("Split Branch rules to use all chains")); add( new localNATRule("process local NAT rules")); // add( new DNATforFW("process DNAT rules for packets originated on the firewall")); add( new decideOnChain( "decide on chain" ) ); add( new decideOnTarget( "decide on target" ) ); // ----------- 10/18/2008 add( new splitODstForSNAT( "split rule if objects in ODst belong to different subnets") ); add( new ReplaceFirewallObjectsODst("replace firewall in ODst" ) ); add( new ReplaceFirewallObjectsTSrc("replace firewall in TSrc" ) ); add( new splitOnDynamicInterfaceInODst( "split rule if ODst is dynamic interface" ) ); add( new splitOnDynamicInterfaceInTSrc( "split rule if TSrc is dynamic interface" ) ); add( new ExpandMultipleAddresses("expand multiple addresses") ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); if (ipv6) add( new DropIPv4Rules("drop ipv4 rules")); else add( new DropIPv6Rules("drop ipv6 rules")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new specialCaseWithUnnumberedInterface( "special cases with dynamic and unnumbered interfaces" ) ); add( new checkForDynamicInterfacesOfOtherObjects( "dynamic interfaces of other hosts and firewalls" ) ); add( new verifyRuleWithMAC("verify rules using MAC address filtering")); add( new ExpandAddressRanges("expand address ranges") ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new splitMultiSrcAndDst( "split rules where multiple srcs and dsts are present" ) ); add( new groupServicesByProtocol("group services by protocol")); add( new VerifyRules2("check correctness of TSrv")); add( new separatePortRanges("separate port ranges")); add( new separateSrcPort("separate objects with src ports") ); add( new separateSrcAndDstPort("separate objects with src and dest ports")); add( new prepareForMultiport("prepare for multiport") ); add( new splitMultipleICMP("split rule with multiple ICMP services") ); add( new ConvertToAtomicForAddresses("convert to atomic rules") ); add( new addVirtualAddress("add virtual addresses") ); add( new AssignInterface("assign rules to interfaces") ); add( new VerifyRules3("check combination of interface spec and chain")); add( new dynamicInterfaceInODst("split if dynamic interface in ODst") ); add( new dynamicInterfaceInTSrc( "set target if dynamic interface in TSrc" ) ); add( new ConvertToAtomicForItfInb("convert to atomic for inbound interface") ); add( new ConvertToAtomicForItfOutb("convert to atomic for outbound interface")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new countChainUsage("Count chain usage")); if (fwopt->getBool("use_iptables_restore")) { // bug #1812295: we should use PrintRuleIptRstEcho not only // when we have dynamic interfaces, but also when we have // address tables expanded at run time. Instead of checking // for all these conditions, just always use PrintRuleIptRstEcho printRule=new PrintRuleIptRstEcho( "generate code for iptables-restore using echo"); } else printRule=new PrintRule("generate iptables shell script"); printRule->setContext(this); printRule->initialize(); add( printRule ); add( new simplePrintProgress() ); runRuleProcessors(); } void NATCompiler_ipt::epilog() { if (fwopt->getBool("use_iptables_restore") && getCompiledScriptLength()>0 && ! inSingleRuleCompileMode()) { output << "#" << endl; } } string NATCompiler_ipt::flushAndSetDefaultPolicy() { string res=""; if (fwopt->getBool("use_iptables_restore") && ! inSingleRuleCompileMode()) { res += "echo :PREROUTING ACCEPT [0:0]\n"; res += "echo :POSTROUTING ACCEPT [0:0]\n"; res += "echo :OUTPUT ACCEPT [0:0]\n"; } return res; } string NATCompiler_ipt::printAutomaticRules() { return ""; } string NATCompiler_ipt::commit() { string res=""; if(printRule!=NULL) { res += printRule->_commit(); } return res; } list NATCompiler_ipt::getUsedChains() { list res; for (map::iterator it=chain_usage_counter.begin(); it!=chain_usage_counter.end(); ++it) res.push_back(it->first); return res; } fwbuilder-5.1.0.3599/src/iptlib/NATCompiler_PrintRule.cpp0000644000175000017500000005764511733011756023716 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/XMLTools.h" #include "combinedAddress.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ /* * Prints single --option with argument and negation "!" * taking into account the change that happened in iptables 1.4.3.1 * that causes warning * Using intrapositioned negation (`--option ! this`) is deprecated in favor of extrapositioned (`! --option this`). */ string NATCompiler_ipt::PrintRule::_printSingleOptionWithNegation( const string &option, RuleElement *rel, const string &arg) { ostringstream ostr; if (XMLTools::version_compare(version, "1.4.3")>=0) { ostr << _printSingleObjectNegation(rel); ostr << option << " "; ostr << arg << " "; } else { ostr << option << " "; ostr << _printSingleObjectNegation(rel); ostr << arg << " "; } return ostr.str(); } void NATCompiler_ipt::PrintRule::initializeMinusNTracker() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); for (list::const_iterator i = NATCompiler_ipt::getStandardChains().begin(); i != NATCompiler_ipt::getStandardChains().end(); ++i) { (*(ipt_comp->minus_n_commands))[*i] = true; } minus_n_tracker_initialized = true; } /* * Initialize some internal variables. Need to do this in a separate * method because pointer to the compiler object is set by * RuleProcessor::setContext and is not available in constructor. */ void NATCompiler_ipt::PrintRule::initialize() { // retrieve and save version for _printSingleOptionWithNegation and others version = compiler->fw->getStr("version"); } /* * check and create new chain if needed */ string NATCompiler_ipt::PrintRule::_createChain(const string &chain) { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); ostringstream res; if (!minus_n_tracker_initialized) initializeMinusNTracker(); if ( ipt_comp->minus_n_commands->count(chain)==0 ) { string ipt_cmd = (ipt_comp->ipv6) ? "$IP6TABLES " : "$IPTABLES "; res << ipt_cmd << "-t nat -N " << chain << endl; (*(ipt_comp->minus_n_commands))[chain] = true; } return res.str(); } string NATCompiler_ipt::PrintRule::_startRuleLine() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); string res = (ipt_comp->ipv6) ? "$IP6TABLES " : "$IPTABLES "; return res + string("-t nat -A "); } string NATCompiler_ipt::PrintRule::_endRuleLine() { return string("\n"); } string NATCompiler_ipt::PrintRule::_printRuleLabel(NATRule *rule) { ostringstream res; bool nocomm = Resources::os_res[compiler->fw->getStr("host_OS")]->Resources::getResourceBool("/FWBuilderResources/Target/options/suppress_comments"); // TODO: convert this into virtual function NATCompiler_ipt::printComment() string rl=rule->getLabel(); if (rl != current_rule_label) { if (!compiler->inSingleRuleCompileMode() && !nocomm) { res << "# " << endl; res << "# Rule " << rl << endl; res << "# " << endl; } res << "echo " << _quote(string("Rule ")+rl) << endl; res << "# " << endl; /* do not put comment in the script if it is intended for linksys */ if (!nocomm || compiler->inSingleRuleCompileMode()) { QStringList comm = QString(rule->getComment().c_str()).split("\n", QString::SkipEmptyParts); foreach(QString line, comm) { res << "# " << line.toStdString() << endl; } //res << "# " << endl; string err = compiler->getErrorsForRule(rule, "# "); if (!err.empty()) res << err << endl; } current_rule_label=rl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) res << "# " << err << endl; return res.str(); } /* * check and create new chain if needed */ QString NATCompiler_ipt::PrintRule::getInterfaceName(RuleElement *itf_re) { if (itf_re->isAny()) return ""; FWObject *iface = FWObjectReference::getObject(itf_re->front()); QString iface_name = iface->getName().c_str(); if (iface_name.endsWith("*")) iface_name.replace("*", "+"); return iface_name; } /** *----------------------------------------------------------------------- */ string NATCompiler_ipt::PrintRule::_printChainDirectionAndInterface(NATRule *rule) { QStringList res; RuleElementItfInb *itf_in_re = rule->getItfInb(); assert(itf_in_re!=NULL); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); assert(itf_out_re!=NULL); QString iface_in_name = getInterfaceName(itf_in_re); QString iface_out_name = getInterfaceName(itf_out_re); if (rule->getStr(".iface_in") == "nil") iface_in_name = ""; if (rule->getStr(".iface_out") == "nil") iface_out_name = ""; res << rule->getStr("ipt_chain").c_str(); if ( ! iface_in_name.isEmpty()) { res << _printSingleOptionWithNegation( "-i", itf_in_re, iface_in_name.toStdString()).c_str(); } if ( ! iface_out_name.isEmpty()) { res << _printSingleOptionWithNegation( "-o", itf_out_re, iface_out_name.toStdString()).c_str(); } res << ""; return res.join(" ").toStdString(); } string NATCompiler_ipt::PrintRule::_printProtocol(Service *srv) { std::ostringstream ostr; // CustomService returns protocol name starting with v3.0.4 // However CustomService can return protocol name "any", which we should // just skip. if (CustomService::isA(srv)) { // check if the code string for this custom service already includes // "-p proto" fragment string code = CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName()); std::size_t minus_p = code.find("-p "); if (minus_p != string::npos) return ""; string pn = srv->getProtocolName(); if (pn == "any") return ""; } if (!srv->isAny() && !TagService::isA(srv) && !UserService::isA(srv)) { string pn = srv->getProtocolName(); if (pn=="ip") pn="all"; ostr << "-p " << pn << " "; if (pn == "tcp") ostr << "-m tcp "; if (pn == "udp") ostr << "-m udp "; if (pn == "icmp") ostr << "-m icmp "; } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printMultiport(NATRule *rule) { std::ostringstream ostr; if( rule->getBool("ipt_multiport")) ostr << "-m multiport "; return ostr.str(); } string NATCompiler_ipt::PrintRule::_printOPorts(int rs,int re) { std::ostringstream ostr; if (rs<0) rs=0; if (re<0) re=0; if (rs>0 || re>0) { if (rs==re) ostr << rs; else if (rs==0 && re!=0) ostr << ":" << re; else ostr << rs << ":" << re; } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printTPorts(int rs,int re) { std::ostringstream ostr; if (rs<0) rs=0; if (re<0) re=0; if (rs>0 || re>0) { if (rs==re) ostr << rs; else if (rs==0 && re!=0) ostr << "-" << re; else ostr << rs << "-" << re; } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printICMP(ICMPService *srv) { std::ostringstream ostr; if (ICMPService::isA(srv) && srv->getInt("type")!=-1) { ostr << srv->getStr("type"); if (srv->getInt("code")!=-1) ostr << "/" << srv->getStr("code") << " "; } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printIP(IPService *srv) { std::ostringstream ostr; if (IPService::isA(srv) ) { if (srv->getBool("fragm") || srv->getBool("short_fragm")) ostr << "-f "; if (srv->getBool("lsrr") || srv->getBool("ssrr") || srv->getBool("rr") || srv->getBool("ts") ) ostr << " -m ipv4options "; if (srv->getBool("lsrr")) ostr << " --lsrr"; if (srv->getBool("ssrr")) ostr << " --ssrr"; if (srv->getBool("rr")) ostr << " --rr"; if (srv->getBool("ts")) ostr << " --ts"; } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printSrcPorts(Service *srv) { std::ostringstream ostr; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getSrcRangeStart(); int re=TCPUDPService::cast(srv)->getSrcRangeEnd(); ostr << _printOPorts(rs,re); } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printDstPorts(Service *srv) { std::ostringstream ostr; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getDstRangeStart(); int re=TCPUDPService::cast(srv)->getDstRangeEnd(); ostr << _printOPorts(rs,re); } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printSNATPorts(Service *srv) { std::ostringstream ostr; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getSrcRangeStart(); int re=TCPUDPService::cast(srv)->getSrcRangeEnd(); ostr << _printTPorts(rs,re); } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printDNATPorts(Service *srv) { std::ostringstream ostr; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getDstRangeStart(); int re=TCPUDPService::cast(srv)->getDstRangeEnd(); ostr << _printTPorts(rs,re); } return ostr.str(); } /* * we made sure that all services in rel represent the same protocol */ string NATCompiler_ipt::PrintRule::_printSrcService(RuleElementOSrv *rel) { std::ostringstream ostr; /* I do not want to use rel->getFirst because it traverses the tree to * find the object. I'd rather use a cached copy in the compiler */ FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); if (rel->size()==1) { if (UDPService::isA(srv) || TCPService::isA(srv)) { string str=_printSrcPorts( srv ); if (! str.empty() ) ostr << "--sport " << str << " "; } } else { /* use multiport */ string str; bool first=true; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (UDPService::isA(srv) || TCPService::isA(srv)) { if (!first) str+=","; str+= _printSrcPorts( s ); if (!str.empty()) first=false; } } if ( !str.empty() ) { if (version.empty() || version=="ge_1.2.6" || XMLTools::version_compare(version, "1.2.6")>=0) ostr << "--sports "; else ostr << "--source-port "; ostr << str << " "; } } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printDstService(RuleElementOSrv *rel) { std::ostringstream ostr; FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); if (rel->size()==1) { if (UDPService::isA(srv) || TCPService::isA(srv)) { string str=_printDstPorts( srv ); if (! str.empty() ) ostr << "--dport " << str << " "; } if (ICMPService::isA(srv)) { string str=_printICMP( ICMPService::cast(srv) ); if (! str.empty() ) ostr << "--icmp-type " << str << " "; } if (IPService::isA(srv)) { string str=_printIP( IPService::cast(srv) ); if (! str.empty() ) ostr << str << " "; } if (CustomService::isA(srv)) { ostr << CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ) << " "; } if (TagService::isA(srv)) { ostr << "-m mark --mark " << TagService::constcast(srv)->getCode() << " "; } } else { /* use multiport */ string str; bool first=true; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (UDPService::isA(srv) || TCPService::isA(srv)) { if (!first) str+=","; str+= _printDstPorts( s ); if (!str.empty()) first=false; } } if ( !str.empty() ) { if (version.empty() || version=="ge_1.2.6" || XMLTools::version_compare(version, "1.2.6")>=0) ostr << "--dports "; else ostr << "--destination-port "; ostr << str << " "; } } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printIpSetMatch(Address *o, RuleElement *rel) { NATCompiler_ipt *ipt_comp=dynamic_cast(compiler); string set_name = dynamic_cast(ipt_comp->osconfigurator)->normalizeSetName(o->getName()); string suffix = "dst"; if (RuleElementOSrc::isA(rel)) suffix = "src"; if (RuleElementODst::isA(rel)) suffix = "dst"; string set_match_option; if (XMLTools::version_compare(version, "1.4.4")>=0) set_match_option = "--match-set"; else set_match_option = "--set"; string set_match = set_match_option + " " + set_name + " " + suffix; ostringstream ostr; ostr << "-m set " << _printSingleOptionWithNegation("", rel, set_match); return ostr.str(); } // Note print_mask is true by default, print_range is false by default. string NATCompiler_ipt::PrintRule::_printAddr(Address *o, bool , bool print_range) { NATCompiler_ipt *ipt_comp=dynamic_cast(compiler); std::ostringstream ostr; MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { ostr << "$" << ipt_comp->getAddressTableVarName(atrt) << " "; return ostr.str(); } if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { return atrt->getSourceName(); } // at this time we only support two types of MultiAddress // objects: AddressTable and DNSName. Both should be converted // to MultiAddressRunTime at this point. If we get some other // kind of MultiAddressRunTime object, we do not know what to do // with it so we stop. assert(atrt==NULL); } if (print_range && AddressRange::cast(o)!=NULL) { InetAddr a1 = AddressRange::cast(o)->getRangeStart(); InetAddr a2 = AddressRange::cast(o)->getRangeEnd(); ostr << a1.toString() << "-" << a2.toString(); } else { Interface *iface = Interface::cast(o); if (iface!=NULL && iface->isDyn() && iface->getBool("use_var_address")) { ostr << "$" << ipt_comp->getInterfaceVarName(iface, ipt_comp->ipv6) << " "; return ostr.str(); } const InetAddr* addr = o->getAddressPtr(); const InetAddr* mask = o->getNetmaskPtr(); if (addr==NULL) { compiler->warning( string("Empty inet address in object ") + FWObjectDatabase::getStringId(o->getId())); return ostr.str(); } if (addr->isAny() && mask->isAny()) { ostr << "0/0 "; } else { ostr << addr->toString(); if (Interface::cast(o)==NULL && Address::cast(o)->dimension() > 1 && !mask->isHostMask()) { ostr << "/" << mask->getLength(); } // do not add space after address because there might be // :port spec coming right after it. } } return ostr.str(); } string NATCompiler_ipt::PrintRule::_printSingleObjectNegation( RuleElement *rel) { if (rel->getBool("single_object_negation")) return "! "; else return ""; } NATCompiler_ipt::PrintRule::PrintRule(const std::string &name) : NATRuleProcessor(name) { init = true; print_once_on_top = true; minus_n_tracker_initialized = false; } bool NATCompiler_ipt::PrintRule::processNext() { NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ropt = rule->getOptionsObject(); string chain = rule->getStr("ipt_chain"); if (ipt_comp->chain_usage_counter[chain] == 0) { return true; } tmp_queue.push_back(rule); compiler->output << _printRuleLabel(rule); string s; std::ostringstream cmdout; compiler->output << _createChain(rule->getStr("ipt_chain")); compiler->output << _createChain(rule->getStr("ipt_target")); RuleElementOSrc *osrcrel = rule->getOSrc(); Address *osrc = compiler->getFirstOSrc(rule); assert(osrc); RuleElementODst *odstrel = rule->getODst(); Address *odst = compiler->getFirstODst(rule); assert(odst); RuleElementOSrv *osrvrel=rule->getOSrv(); Service *osrv = compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc = compiler->getFirstTSrc(rule); assert(tsrc); Address *tdst = compiler->getFirstTDst(rule); assert(tdst); Service *tsrv = compiler->getFirstTSrv(rule); assert(tsrv); cmdout << _startRuleLine(); cmdout << _printChainDirectionAndInterface(rule); if (! osrv->isAny() ) cmdout << _printProtocol(osrv); cmdout << _printMultiport(rule); if (!osrc->isAny()) { string physaddress=""; if (physAddress::isA(osrc)) physaddress= physAddress::cast(osrc)->getPhysAddress(); if (combinedAddress::isA(osrc)) physaddress= combinedAddress::cast(osrc)->getPhysAddress(); if ( ! physaddress.empty()) { cmdout << " -m mac --mac-source " << physaddress; } const InetAddr *osrc_addr = osrc->getAddressPtr(); if (osrc_addr==NULL || !osrc_addr->isAny()) { MultiAddressRunTime *atrt = MultiAddressRunTime::cast(osrc); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME && ipt_comp->using_ipset) { cmdout << _printIpSetMatch(osrc, osrcrel); } else { string osrc_out = _printAddr(osrc); if (!osrc_out.empty()) cmdout << _printSingleOptionWithNegation(" -s", osrcrel, osrc_out); } } // cmdout << " -s "; // cmdout << _printAddr(osrc); } if (!osrv->isAny()) { cmdout << " "; cmdout << _printSrcService(osrvrel); } if (!odst->isAny()) { MultiAddressRunTime *atrt = MultiAddressRunTime::cast(odst); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME && ipt_comp->using_ipset) { cmdout << _printIpSetMatch(odst, odstrel); } else cmdout << _printSingleOptionWithNegation(" -d", odstrel, _printAddr(odst)); } cmdout << " "; cmdout << _printDstService(osrvrel); cmdout << "-j " << rule->getStr("ipt_target") << " "; switch (rule->getRuleType()) { case NATRule::Masq: if (ropt->getBool("ipt_nat_random")) cmdout << " --random"; break; case NATRule::SNAT: if (rule->getStr("ipt_target")=="SNAT") { cmdout << "--to-source "; // if TSrc is "any" and this is SNAT rule, then this rule only // translates source port. Skip address part. // Note for #1693: _printAddr() returns string that ends with a space, // but there should be no space if the address is followed by port // spec. QString addr_part; if (!tsrc->isAny()) { addr_part = _printAddr(tsrc, false, true).c_str(); } string ports = _printSNATPorts(tsrv); if (!ports.empty()) { cmdout << addr_part.trimmed().toStdString() << ":" << ports; } else cmdout << addr_part.toStdString(); if (ropt->getBool("ipt_nat_random")) cmdout << " --random"; if (XMLTools::version_compare(version, "1.4.3")>=0) if (ropt->getBool("ipt_nat_persistent")) cmdout << " --persistent"; } break; /* * if rule type is DNAT and TDst is any, this rule only does port * translation and does not change addresses. Iptables accepts * "--to-destination :80" (no address in front of the ':') and seems * to do the right thing. */ case NATRule::DNAT: if (rule->getStr("ipt_target")=="DNAT") { cmdout << "--to-destination "; // if TDst is "any" and this is DNAT rule, then this rule only // translates source port. Skip address part. QString addr_part; if (!tdst->isAny()) addr_part = _printAddr(tdst, false, true).c_str(); string ports = _printDNATPorts(tsrv); if (!ports.empty()) { cmdout << addr_part.trimmed().toStdString() << ":" << ports; } else { cmdout << addr_part.toStdString(); } if (ropt->getBool("ipt_nat_random")) cmdout << " --random"; if (XMLTools::version_compare(version, "1.4.3")>=0) if (ropt->getBool("ipt_nat_persistent")) cmdout << " --persistent"; } break; case NATRule::SNetnat: if (rule->getStr("ipt_target")=="NETMAP") { cmdout << "--to "; cmdout << _printAddr(tsrc,true,false); } break; case NATRule::DNetnat: if (rule->getStr("ipt_target")=="NETMAP") { cmdout << "--to "; cmdout << _printAddr(tdst,true,false); } break; case NATRule::Redirect: if (rule->getStr("ipt_target")=="REDIRECT") { string ports=_printDNATPorts(tsrv); if (!ports.empty()) cmdout << "--to-ports " << ports; } break; case NATRule::NATBranch: break; default: break; } cmdout << " "; cmdout << _endRuleLine(); // cmdout << endl; compiler->output << dynamic_cast(compiler->osconfigurator)-> printRunTimeWrappers( rule, cmdout.str(), ipt_comp->ipv6); return true; } string NATCompiler_ipt::PrintRule::_declareTable() { return ""; } string NATCompiler_ipt::PrintRule::_commit() { return ""; } string NATCompiler_ipt::PrintRule::_quote(const string &s) { return "\"" + s + "\""; } fwbuilder-5.1.0.3599/src/iptlib/Preprocessor_ipt.h0000644000175000017500000000263311733011756022567 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PREPROCESSOR_IPT_HH #define __PREPROCESSOR_IPT_HH #include #include "fwcompiler/Preprocessor.h" namespace libfwbuilder { class FWObjectDatabase; }; namespace fwcompiler { class Preprocessor_ipt : public Preprocessor { public: Preprocessor_ipt(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : Preprocessor(_db, fw, ipv6_policy) { } virtual void convertObject(libfwbuilder::FWObject *obj); }; } #endif fwbuilder-5.1.0.3599/src/iptlib/ipt_utils.cpp0000644000175000017500000001463711733011756021603 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ipt_utils.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/ObjectGroup.h" #include "fwcompiler/Compiler.h" #include "combinedAddress.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; void build_interface_groups( FWObjectDatabase *dbcopy, Library *persistent_objects, Firewall *fw, bool ipv6, QMap ®ular_interfaces) { // object group that will hold all regular inetrfaces FWObject *all_itf_group = dbcopy->create(ObjectGroup::TYPENAME); persistent_objects->add(all_itf_group); all_itf_group->setName("*"); regular_interfaces["*"] = all_itf_group; list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->isLoopback() || iface->isUnnumbered() || iface->isBridgePort()) continue; FWObjectTypedChildIterator ipv4_addresses = iface->findByType(IPv4::TYPENAME); FWObjectTypedChildIterator ipv6_addresses = iface->findByType(IPv6::TYPENAME); if ((ipv6 && ipv6_addresses != ipv6_addresses.end()) || (!ipv6 && ipv4_addresses != ipv4_addresses.end()) || (ipv4_addresses == ipv4_addresses.end() && ipv6_addresses == ipv6_addresses.end())) { /* * regular_interfaces is a set of groups of * interfaces, where each group holds references to * all interfaces with "similar names". The group name * is then the base name of these interfaces with * numeric index replaced with "*". For example: * group "eth*" { eth0, eth1, eth2, ... } * * if interface name ends with '*', this is wildcard * interface. Just replace '*' with '+'. If interace * name does not end with '*', replace numeric * interface index with '+'. */ QString iname = QString(iface->getName().c_str()); iname.replace(QRegExp("[0-9]{1,}$"), "+"); iname.replace("*", "+"); if (regular_interfaces.count(iname) == 0) { FWObject *itf_group = dbcopy->create(ObjectGroup::TYPENAME); persistent_objects->add(itf_group); itf_group->setName(iname.toStdString()); regular_interfaces[iname] = itf_group; } regular_interfaces[iname]->addRef(iface); regular_interfaces["*"]->addRef(iface); } } } void expand_interface_with_phys_address(Compiler *compiler, Rule *rule, Interface *iface, std::list &ol1, std::list &list_result) { std::list lipaddr; std::list lother; physAddress *pa = NULL; for (std::list::iterator j=ol1.begin(); j!=ol1.end(); j++) { if ((*j)->getTypeName() == IPv4::TYPENAME) { lipaddr.push_back(*j); continue; } if (physAddress::cast(*j)!=NULL) { pa = physAddress::cast(*j); continue; } lother.push_back(*j); } /* * if pa==NULL then this is trivial case: there is no physical address */ if (pa==NULL) { list_result.insert(list_result.end(), ol1.begin(), ol1.end()); return; } /* At this point we have physAddress object and have to deal with it * * Compiler::_expand_interface picks all IPv4 objects and physAddress * object under Interface; it can also add interface object(s) to * the list. * * We have two possibilities now: there could be IPv4 objects or * not. In either case list ol1 may contain also interface object(s). * If there are IPv4 objects, we replace them with combinedAddress * objects which store information about IPv4 address and physAddress pa. * If there were no IPv4 objects, then we pass physAddress along. * We always copy interface objects to the output list. * * * * we use physAddress only if Host option "use_mac_addr_filter" of the * parent Host object is true */ FWObject *p = Host::getParentHost(iface); //FWObject *p = iface->getParentHost(); assert(p!=NULL); FWOptions *hopt = Host::cast(p)->getOptionsObject(); bool use_mac = (hopt!=NULL && hopt->getBool("use_mac_addr_filter") ); if (lipaddr.empty()) list_result.push_back(pa); else { std::list::iterator j=lipaddr.begin(); for ( ; j!=lipaddr.end(); j++) { const InetAddr *ip_addr = Address::cast(*j)->getAddressPtr(); const InetAddr *ip_netm = Address::cast(*j)->getNetmaskPtr(); if (use_mac) { combinedAddress *ca = new combinedAddress(); compiler->persistent_objects->add(ca); ca->setName( "CA("+iface->getName()+")" ); ca->setAddress( *ip_addr ); ca->setNetmask( *ip_netm ); ca->setPhysAddress( pa->getPhysAddress() ); list_result.push_back(ca); } else list_result.push_back(*j); } } list_result.insert(list_result.end(), lother.begin(), lother.end()); } fwbuilder-5.1.0.3599/src/iptlib/ipt_utils.h0000644000175000017500000000305111733011756021234 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; class Firewall; class Interface; class Library; class Rule; }; namespace fwcompiler { class Compiler; }; extern void build_interface_groups( libfwbuilder::FWObjectDatabase *dbcopy, libfwbuilder::Library *persistent_objects, libfwbuilder::Firewall *fw, bool ipv6, QMap ®ular_interfaces); extern void expand_interface_with_phys_address( fwcompiler::Compiler *compiler, libfwbuilder::Rule *rule, libfwbuilder::Interface *iface, std::list &list_temp, std::list &list_result); fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_secuwall.cpp0000644000175000017500000001053011733011756024404 0ustar sylvestresylvestre/* * PolicyCompiler_secuwall.cpp - secunet wall policy compiler implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include #include "PolicyCompiler_secuwall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Policy.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Network.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_secuwall::myPlatformName() { return "secuwall"; } vector PolicyCompiler_secuwall::getMgmtInterfaces() { vector interfaces; /* search Management Interfaces, note: this can be more than one */ for (FWObjectTypedChildIterator fw_ifaces = fw->findByType(Interface::TYPENAME); fw_ifaces != fw_ifaces.end(); ++fw_ifaces) { Interface *iface = Interface::cast(*fw_ifaces); /* Check if it is a management interface */ if (iface->isManagement() && iface->getAddressObject() != NULL) { interfaces.push_back(iface->getName()); } } return interfaces; } void PolicyCompiler_secuwall::verifyPlatform() { string family = Resources::platform_res[fw->getStr("platform")]-> getResourceStr("/FWBuilderResources/Target/family"); if ((family != myPlatformName()) && (fw->getStr("host_OS") != myPlatformName())) abort("Unsupported platform " + fw->getStr("platform") + " (family " + family + ")"); } std::string PolicyCompiler_secuwall::printAutomaticRules() { string res = PolicyCompiler_ipt::printAutomaticRules(); FWOptions* options = getCachedFwOpt(); if (options->getBool("secuwall_mgmt_rules_disable")) { return res; } Configlet configlet(fw, "secuwall", "management_rules"); configlet.removeComments(); configlet.collapseEmptyStrings(false); PolicyCompiler_ipt::PrintRule *print_rule = createPrintRuleProcessor(); configlet.setVariable("begin_rule", print_rule->_startRuleLine().c_str()); configlet.setVariable("end_rule", print_rule->_endRuleLine().c_str()); // export these variables to the configlet std::vector vars; vars.push_back("secuwall_mgmt_mgmtaddr"); vars.push_back("secuwall_mgmt_loggingaddr"); vars.push_back("secuwall_mgmt_ntpaddr"); vars.push_back("secuwall_mgmt_nagiosaddr"); vars.push_back("secuwall_mgmt_snmpaddr"); vars.push_back("secuwall_dns_srv1"); vars.push_back("secuwall_dns_srv2"); vars.push_back("secuwall_dns_srv3"); vars.push_back("secuwall_mgmt_confpart"); for (vector::iterator it = vars.begin(); it != vars.end(); ++it) { std::vector tmp; tokenize(options->getStr(*it), tmp, ","); if (!tmp.empty()) { configlet.setVariable(it->c_str(), stringify(tmp, " ").c_str()); configlet.setVariable((string("has_")+*it).c_str(), true); } } configlet.setVariable("secuwall_mgmt_ifaces", stringify(getMgmtInterfaces(), " ").c_str()); res += configlet.expand().toStdString(); delete print_rule; return res; } /* * An interface is considered a valid interface when it is * 1. a management interface * 2. of type "ethernet" */ bool PolicyCompiler_secuwall::isValidMgmtRuleInterface(Interface *intf) { if (intf == NULL) return false; if (Interface::isA(intf)) { FWOptions* if_opts = intf->getOptionsObject(); if (if_opts == NULL) return false; /* TODO: Extract magic value! */ string iface_type = if_opts->getStr("type"); if (intf->isManagement() && (iface_type != "cluster_member") && (intf->getAddressObject() != NULL)) { return true; } } return false; } fwbuilder-5.1.0.3599/src/iptlib/combinedAddress.h0000644000175000017500000000277411733011756022321 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMB_ADDRESS_HH_FLAG__ #define __COMB_ADDRESS_HH_FLAG__ #include #include #include namespace libfwbuilder { class combinedAddress : public IPv4 { private: std::string physAddress; public: DECLARE_FWOBJECT_SUBTYPE(combinedAddress); combinedAddress() {} virtual ~combinedAddress(); virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(FWException); std::string getPhysAddress() const; void setPhysAddress(const std::string &s); bool isAny() const; }; } #endif fwbuilder-5.1.0.3599/src/iptlib/CompilerDriver_ipt_run.cpp0000644000175000017500000007120511733011756024247 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CompilerDriver_ipt.h" #include "PolicyCompiler_ipt.h" #include "NATCompiler_ipt.h" #include "RoutingCompiler_ipt.h" #include "Preprocessor_ipt.h" #include "OSConfigurator_linux24.h" #include "OSConfigurator_secuwall.h" #include "OSConfigurator_ipcop.h" #include "combinedAddress.h" #include "AutomaticRules_ipt.h" #include "Configlet.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Resources.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Library.h" #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; extern QString user_name; FWObject* create_combinedAddress(int id) { FWObject *nobj = new combinedAddress(); if (id > -1) nobj->setId(id); return nobj; } /* * Go through paces to compile firewall which may be a member of a * cluster. Note that both firewall and cluster are defined by their * unique string IDs. This is necessary because CompilerDriver * operates with a copy of the object database which is not exposed * outside, so the caller can not provide pointers to these obejcts. */ QString CompilerDriver_ipt::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { FWObjectDatabase::registerObjectType(combinedAddress::TYPENAME, &create_combinedAddress); // see #2212 Create temporary copy of the firewall and cluster // objects and pass them to the compilers. Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); string generated_script; try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); string fw_version = fw->getStr("version"); if (fw_version.empty()) fw_version = "(any version)"; string platform = fw->getStr("platform"); string host_os = fw->getStr("host_OS"); FWOptions* options = fw->getOptionsObject(); string s; // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" && fw->getOptionsObject()->getBool("use_iptables_restore")) { abort("Prolog place \"after policy reset\" can not be used" " when policy is activated with iptables-restore"); } string firewall_dir = options->getStr("firewall_dir"); if (firewall_dir=="") firewall_dir="/etc"; bool debug=options->getBool("debug"); QString shell_dbg = (debug)?"set -x":"" ; std::auto_ptr oscnf; string platform_family = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/family"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); bool supports_prolog_epilog = Resources::getTargetCapabilityBool( platform, "supports_prolog_epilog"); if (!supports_prolog_epilog) { prolog_done = true; epilog_done = true; } string os_variant = DISTRO; /* minimal sanity checking */ if (os_family == "ipcop") { os_variant = "ipcop"; // can't use iptables-restore with ipcop fw->getOptionsObject()->setBool("use_iptables_restore", false); // ipcop has its own iptables commands that accept packets // in states ESTABLISHED,RELATED fw->getOptionsObject()->setBool("accept_established", false); oscnf = std::auto_ptr( new OSConfigurator_ipcop(objdb , fw, false)); } if (os_family == "linux24" || os_family == "openwrt" || os_family == "dd-wrt-nvram" || os_family == "dd-wrt-jffs" || os_family == "sveasoft") oscnf = std::auto_ptr( new OSConfigurator_linux24(objdb , fw, false)); if (os_family == "secuwall") oscnf = std::auto_ptr( new OSConfigurator_secuwall(objdb , fw, false)); if (oscnf.get()==NULL) { abort("Unrecognized host OS " + fw->getStr("host_OS") + " (family " + os_family+")"); return ""; } if (inTestMode()) oscnf->setTestMode(); if (inEmbeddedMode()) oscnf->setEmbeddedMode(); oscnf->validateInterfaces(); oscnf->prolog(); list all_policies = fw->getByType(Policy::TYPENAME); list all_nat = fw->getByType(NAT::TYPENAME); int routing_rules_count = 0; bool have_ipv4 = false; bool have_ipv6 = false; // track chains in each table separately. Can we have the same // chain in filter and mangle tables ? Would it be the same // chain, i.e. do we need to create it only once or do we create // it twice, in each table separately ? // Using separate trackers we track and create chain in each // table separately. std::map minus_n_commands_filter; std::map minus_n_commands_mangle; std::map minus_n_commands_nat; vector ipv4_6_runs; findImportedRuleSets(fw, all_policies); findBranchesInMangleTable(fw, all_policies); findImportedRuleSets(fw, all_nat); try { AutomaticRules_ipt auto_rules(fw, persistent_objects); auto_rules.addConntrackRule(); auto_rules.addFailoverRules(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() assignUniqueRuleIds(all_policies); assignUniqueRuleIds(all_nat); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); /* clear chain tracker map only between ipv4/ipv6 runs Don't clear it between compiler runs for different policy or nat objects for the same address family. */ minus_n_commands_filter.clear(); minus_n_commands_mangle.clear(); minus_n_commands_nat.clear(); /* We need to create and run preprocessor for this address family before nat and policy compilers, but if there are no nat / policy rules for this address family, we do not need preprocessor either. */ // Count rules for each address family int nat_count = 0; int policy_count = 0; for (list::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { NAT *nat = NAT::cast(*p); if (nat->matchingAddressFamily(policy_af)) nat_count++; } for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (nat_count || policy_count) { Preprocessor_ipt* prep = new Preprocessor_ipt( objdb , fw, ipv6_policy); prep->setSingleRuleCompileMode(single_rule_id); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); delete prep; } ostringstream automaitc_rules_stream; ostringstream automaitc_mangle_stream; ostringstream filter_rules_stream; ostringstream mangle_rules_stream; ostringstream nat_rules_stream; bool empty_output = true; // First, process branch NAT rulesets, then top NAT ruleset NAT *top_nat = NULL; for (list::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { NAT *nat = NAT::cast(*p); if (!nat->matchingAddressFamily(policy_af)) continue; if (nat->isTop()) { top_nat = nat; continue; } if (! processNatRuleSet( fw, nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; } if (top_nat && ! processNatRuleSet( fw, top_nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; // first process all non-top rule sets, then all top rule sets for (int all_top = 0; all_top < 2; ++all_top) { for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(policy_af)) continue; if (policy->isTop() && all_top == 0) continue; if (!policy->isTop() && all_top == 1) continue; if (! processPolicyRuleSet( fw, policy, single_rule_id, filter_rules_stream, mangle_rules_stream, automaitc_rules_stream, automaitc_mangle_stream, oscnf.get(), policy_af, minus_n_commands_filter, minus_n_commands_mangle)) empty_output = false; } } if (!empty_output && !single_rule_compile_on) { if (ipv6_policy) { have_ipv6 = true; generated_script += "\n\n"; generated_script += "# ================ IPv6\n"; generated_script += "\n\n"; } else { have_ipv4 = true; generated_script += "\n\n"; generated_script += "# ================ IPv4\n"; generated_script += "\n\n"; } } generated_script += dumpScript(fw, automaitc_rules_stream.str(), automaitc_mangle_stream.str(), nat_rules_stream.str(), mangle_rules_stream.str(), filter_rules_stream.str(), ipv6_policy); if (single_rule_compile_on) generated_script += "\n\n"; } std::auto_ptr routing_compiler( new RoutingCompiler_ipt(objdb, fw, false, oscnf.get())); RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); if (routing) { routing_compiler->setSourceRuleSet(routing); routing_compiler->setRuleSetName(routing->getName()); routing_compiler->setPersistentObjects(persistent_objects); routing_compiler->setSingleRuleCompileMode(single_rule_id); routing_compiler->setDebugLevel( dl ); if (rule_debug_on) routing_compiler->setDebugRule(drr); routing_compiler->setVerbose( verbose ); if (inTestMode()) routing_compiler->setTestMode(); if (inEmbeddedMode()) routing_compiler->setEmbeddedMode(); if ( (routing_rules_count=routing_compiler->prolog()) > 0 ) { routing_compiler->compile(); routing_compiler->epilog(); } if (routing_compiler->haveErrorsAndWarnings()) all_errors.push_back(routing_compiler->getErrors("").c_str()); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (getErrors("") + generated_script + routing_compiler->getCompiledScript()).c_str())); } /* * These store generated configuration internally, extract it later using * OSConfiguration::getGeneratedFiles(); */ oscnf->processFirewallOptions(); /* * now write generated scripts to files */ char *timestr = NULL; time_t tm; struct tm *stm; tm = time(NULL); stm = localtime(&tm); timestr = strdup(ctime(&tm)); timestr[strlen(timestr)-1] = '\0'; /* * assemble the script and then perhaps post-process it if it * should run on Linksys device with sveasoft firmware */ Configlet script_skeleton(fw, "linux24", "script_skeleton"); script_skeleton.removeComments(); QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); /* * text comes from the compiler in UTF-8 (because all comments * and object names are stored in UTF-8 in objects and * compilers do not decode). We have a choice: 1) apply * QString::fromUtf8() to all strings coming from the compiler * to convert to Unicode and rely on QTextStream to convert * back to UTF-8 in the generated file, or 2) leavle strings * coming from compilers as-is and tell the stream to not * covert. */ script_buffer = ""; script_skeleton.setVariable("shell_debug", shell_dbg); script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n"; script << "export PATH" << "\n"; script_skeleton.setVariable("path", script_buffer); script_buffer = ""; Configlet script_constants(fw, "linux24", "constants"); script_skeleton.setVariable("constants", script_constants.expand()); /* * print definitions for variables IPTABLES, IP, LOGGER. Some * day we may add a choice of os_variant in the GUI. Right now * paths are either default for a given os_variant, or custom * strings entered by user in the GUI and stored in firewall * options. */ script_skeleton.setVariable("tools", oscnf->printPathForAllTools(os_variant).c_str()); script_skeleton.setVariable("shell_functions", oscnf->printShellFunctions(have_ipv6).c_str()); script_skeleton.setVariable("run_time_address_tables", oscnf->printRunTimeAddressTablesCode().c_str()); script_skeleton.setVariable("using_ipset", oscnf->usingIpSetModule()); if (supports_prolog_epilog) { //script_skeleton.setVariable("prolog_epilog", // oscnf->printPrologEpilogFunctions().c_str()); script_skeleton.setVariable( "prolog_script", fw->getOptionsObject()->getStr("prolog_script").c_str()); script_skeleton.setVariable( "epilog_script", fw->getOptionsObject()->getStr("epilog_script").c_str()); } ostringstream ostr; ostr << "# Configure interfaces" << endl; if ( options->getBool("configure_bonding_interfaces") ) ostr << oscnf->printBondingInterfaceConfigurationCommands(); if ( options->getBool("configure_vlan_interfaces")) ostr << oscnf->printVlanInterfaceConfigurationCommands(); if ( options->getBool("configure_bridge_interfaces") ) ostr << oscnf->printBridgeInterfaceConfigurationCommands(); if ( options->getBool("configure_interfaces") || options->getBool("manage_virtual_addr")) { if ( options->getBool("configure_interfaces")) ostr << oscnf->printInterfaceConfigurationCommands(); else ostr << oscnf->printVirtualAddressesForNatCommands(); } ostr << oscnf->printCommandsToClearKnownInterfaces(); ostr << oscnf->printDynamicAddressesConfigurationCommands(); script_skeleton.setVariable( "configure_interfaces", indent(4, QString(ostr.str().c_str()))); // verify_interfaces checks bridge interfaces so run it // after those have been created if (options->getBool("verify_interfaces")) { list l2=fw->getByType(Interface::TYPENAME); if (l2.empty() ) script_skeleton.setVariable("verify_interfaces", QString()); else script_skeleton.setVariable("verify_interfaces", oscnf->printVerifyInterfacesCommands().c_str()); } else script_skeleton.setVariable("verify_interfaces", QString()); string prolog_place = fw->getOptionsObject()->getStr("prolog_place"); if (prolog_place == "") prolog_place="top"; /* there is no way to stick prolog commands between iptables * reset and iptables rules if we use iptables-restore to * activate policy. Therefore, if prolog needs to be ran after * iptables flush and we use iptables-restore, we run prolog * on top of the script. */ if (!prolog_done && (prolog_place == "top" || (prolog_place == "after_flush" && fw->getOptionsObject()->getBool("use_iptables_restore")))) { script_skeleton.setVariable("prolog_top", 1); script_skeleton.setVariable("prolog_after_interfaces", 0); script_skeleton.setVariable("prolog_after_flush", 0); prolog_done = true; } if (!prolog_done && prolog_place == "after_interfaces") { script_skeleton.setVariable("prolog_top", 0); script_skeleton.setVariable("prolog_after_interfaces", 1); script_skeleton.setVariable("prolog_after_flush", 0); prolog_done = true; } if (!prolog_done && prolog_place == "after_flush") { script_skeleton.setVariable("prolog_top", 0); script_skeleton.setVariable("prolog_after_interfaces", 0); script_skeleton.setVariable("prolog_after_flush", 1); prolog_done = true; } script_skeleton.setVariable("load_modules", oscnf->generateCodeForProtocolHandlers().c_str()); script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"nat":""); script_skeleton.setVariable("load_modules_with_ipv6", (have_ipv6)?"ipv6":""); script_skeleton.setVariable("ip_forward_commands", oscnf->printIPForwardingCommands().c_str()); /* * script body begins here */ script_buffer = ""; if (oscnf->haveErrorsAndWarnings()) { all_errors.push_back(oscnf->getErrors("").c_str()); } // convert from UTF8 to make sure localized comments are shown correctly // script << oscnf->getCompiledScript().c_str(); // script << generated_script.c_str(); // script << routing_compiler->getCompiledScript().c_str(); script << QString::fromUtf8(oscnf->getCompiledScript().c_str()); script << QString::fromUtf8(generated_script.c_str()); script << QString::fromUtf8(routing_compiler->getCompiledScript().c_str()); script << endl; script_skeleton.setVariable("script_body", indent(4, script_buffer)); script_skeleton.setVariable("timestamp", timestr); script_skeleton.setVariable("tz", tzname[stm->tm_isdst]); script_skeleton.setVariable("user", user_name); script_skeleton.setVariable("database", objdb->getFileName().c_str()); /* * Call reset_all function to flush and reset iptables, but only * do this if we do not use iptables_restore. Reset is done as part * of iptables-restore script in the latter case and commands are * added in PolicyCompiler_ipt::flushAndSetDefaultPolicy() */ script_skeleton.setVariable("not_using_iptables_restore", ! fw->getOptionsObject()->getBool("use_iptables_restore")); script_buffer = ""; if (have_ipv4) script << " reset_iptables_v4" << endl; if (have_ipv6) script << " reset_iptables_v6" << endl; script_skeleton.setVariable("reset_all", script_buffer); script_buffer = ""; Configlet block_action(fw, "linux24", "block_action"); block_action.collapseEmptyStrings(true); // the name of the option is historical (including the typo) if (fw->getOptionsObject()->getBool("add_mgmt_ssh_rule_when_stoped")) { std::auto_ptr policy_compiler = createPolicyCompiler(fw, false, NULL, NULL); PolicyCompiler_ipt::PrintRule* print_rule = policy_compiler->createPrintRuleProcessor(); print_rule->setContext(policy_compiler.get()); print_rule->_printBackupSSHAccessRules(&block_action); } else { block_action.setVariable("mgmt_access", 0); } script_skeleton.setVariable("block_action", block_action.expand()); Configlet stop_action(fw, "linux24", "stop_action"); stop_action.collapseEmptyStrings(true); stop_action.setVariable("have_ipv4", have_ipv4); stop_action.setVariable("have_ipv6", have_ipv6); script_skeleton.setVariable("stop_action", stop_action.expand()); Configlet status_action(fw, "linux24", "status_action"); status_action.collapseEmptyStrings(true); script_skeleton.setVariable("status_action", status_action.expand()); Configlet top_comment(fw, "linux24", "top_comment"); top_comment.setVariable("version", VERSION); top_comment.setVariable("timestamp", timestr); top_comment.setVariable("tz", tzname[stm->tm_isdst]); top_comment.setVariable("user", user_name); top_comment.setVariable("database", objdb->getFileName().c_str()); determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("script_name_on_firewall")); script_buffer = ""; script << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]); if (!remote_file_names[FW_FILE].isEmpty()) script << " " << this->escapeFileName(remote_file_names[FW_FILE]); script << "\n"; /* Add additional files to manifest if specified. Currently there * are no GUI controls to let user provide alternative names for * these on the firewall. See description of manifest format in * comments in src/gui/FirewallInstaller.cpp */ map file_list = oscnf->getGeneratedFiles(); if (!file_list.empty()) { info(" Adding additional files to manifest"); map::const_iterator c_iter = file_list.begin(); for (; c_iter != file_list.end(); ++c_iter) { string name = c_iter->first; string dest = c_iter->second; script << MANIFEST_MARKER << this->escapeFileName(name.c_str()); if (!dest.empty()) script << " " << dest; script << "\n"; } } top_comment.setVariable("manifest", script_buffer); top_comment.setVariable("platform", platform.c_str()); top_comment.setVariable("fw_version", fw_version.c_str()); top_comment.setVariable("comment", prepend("# ", fw->getComment().c_str())); script_skeleton.setVariable("top_comment", top_comment.expand()); script_skeleton.setVariable("errors_and_warnings", prepend("# ", all_errors.join("\n"))); info("Output file name: " + file_names[FW_FILE].toStdString()); QFile fw_file(file_names[FW_FILE]); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_skeleton.expand(); fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } free(timestr); } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } fwbuilder-5.1.0.3599/src/iptlib/NATCompiler_PrintRuleIptRst.cpp0000644000175000017500000000531111733011756025043 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_ipt.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Resources.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ /* * check and create new chain if needed */ string NATCompiler_ipt::PrintRuleIptRst::_createChain(const string &chain) { string res; NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); if (!minus_n_tracker_initialized) initializeMinusNTracker(); if ( ipt_comp->minus_n_commands->count(chain)==0 ) { if ( ! compiler->inSingleRuleCompileMode()) res = ":" + chain + " - [0:0]\n"; (*(ipt_comp->minus_n_commands))[chain] = true; } return res; } string NATCompiler_ipt::PrintRuleIptRst::_startRuleLine() { return string("-A "); } string NATCompiler_ipt::PrintRuleIptRst::_endRuleLine() { return string("\n"); } string NATCompiler_ipt::PrintRuleIptRst::_printRuleLabel(NATRule *rule) { bool nocomm = Resources::os_res[compiler->fw->getStr("host_OS")]->Resources::getResourceBool("/FWBuilderResources/Target/options/suppress_comments"); return compiler->printComment(rule, current_rule_label, "#", nocomm); } bool NATCompiler_ipt::PrintRuleIptRst::processNext() { if (print_once_on_top) { print_once_on_top=false; } return NATCompiler_ipt::PrintRule::processNext(); } string NATCompiler_ipt::PrintRuleIptRst::_declareTable() { ostringstream res; res << "*nat" << endl; return res.str(); } string NATCompiler_ipt::PrintRuleIptRst::_commit() { return "COMMIT\n"; } string NATCompiler_ipt::PrintRuleIptRst::_quote(const string &s) { return "\"" + s + "\""; } fwbuilder-5.1.0.3599/src/iptlib/MangleTableCompiler_ipt.cpp0000644000175000017500000001427611733011756024310 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "MangleTableCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string MangleTableCompiler_ipt::myPlatformName() { return "iptables"; } int MangleTableCompiler_ipt::prolog() { return PolicyCompiler_ipt::prolog(); } bool MangleTableCompiler_ipt::keepMangleTableRules::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); string ruleset_name = compiler->getRuleSetName(); FWOptions *rulesetopts = ipt_comp->getSourceRuleSet()->getOptionsObject(); if (rulesetopts->getBool("mangle_only_rule_set")) tmp_queue.push_back(rule); else { if (rule->getAction() == PolicyRule::Branch && ruleopt->getBool("ipt_branch_in_mangle")) { PolicyRule* r; // this is a branching rule for mangle table. Need to put it // into PREROUTING and POSTROUTING chains as well because some // targets that work with mangle table can only go into these // chains, yet we do not know what kind of rules will user // place in the branch if (rule->getDirection()==PolicyRule::Undefined || rule->getDirection()==PolicyRule::Both || rule->getDirection()==PolicyRule::Inbound) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","PREROUTING"); tmp_queue.push_back(r); } if (rule->getDirection()==PolicyRule::Undefined || rule->getDirection()==PolicyRule::Both || rule->getDirection()==PolicyRule::Outbound) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","POSTROUTING"); tmp_queue.push_back(r); } // ticket #1415 User reports that only packets that went // through the FORWARD chain can match inbound "-i" and // outbound "-o" interface at the same time. Since we do // not allow both in and out interface matches in one rule // and have to use branch to do this, need to branch in // FORWARD chain as well so that inbound interface can be // matched in the branching rule and outbound interface // can be matched in a rule in the branch // // This is ugly, this means the branch will inspect the // packet at least twice - in PREROUTING and FORWARD, or // FORWARD and POSTROUTING chains. // // I mention above that some targets can only be used in // PREROUTING or POSTROUTING chains. It would help if // these tagrets worked in FORWARD chain, in that case we // could just branch in FORWARD instead of all thress chains. // r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","FORWARD"); tmp_queue.push_back(r); // tmp_queue.push_back(rule); return true; } if (rule->getTagging() || rule->getRouting() || rule->getClassification() || ruleopt->getBool("put_in_mangle_table")) tmp_queue.push_back(rule); } return true; } void MangleTableCompiler_ipt::addRuleFilter() { add(new keepMangleTableRules("keep only rules that require mangle table")); } string MangleTableCompiler_ipt::flushAndSetDefaultPolicy() { return ""; } // mangle table compiler is special, it needs additional parameters to // generate automatic rules correctly. But virtual function // printAutomaticRules() has no parameters so we have another one // that takes parameters: printAutomaticRulesForMangleTable() string MangleTableCompiler_ipt::printAutomaticRules() { return ""; } string MangleTableCompiler_ipt::printAutomaticRulesForMangleTable( bool have_connmark, bool have_connmark_in_output) { ostringstream res; PolicyCompiler_ipt::PrintRule *prp = createPrintRuleProcessor(); // res << prp->_declareTable(); if (have_connmark) { res << prp->_startRuleLine() << "PREROUTING -j CONNMARK --restore-mark" << prp->_endRuleLine(); } if (have_connmark_in_output) { res << prp->_startRuleLine() << "OUTPUT -j CONNMARK --restore-mark" << prp->_endRuleLine(); res << endl; } // iptables accepted TCPMSS target in filter table, FORWARD chain // in the older versions, but requires it to be in mangle filter // starting somewhere 1.3.x string version = fw->getStr("version"); if (XMLTools::version_compare(version, "1.3.0")>=0) res << prp->_clampTcpToMssRule(); delete prp; return res.str(); } fwbuilder-5.1.0.3599/src/iptlib/CompilerDriver_ipt_nat.cpp0000644000175000017500000001010211733011756024212 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "CompilerDriver_ipt.h" #include "NATCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Library.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; bool CompilerDriver_ipt::processNatRuleSet( Firewall *fw, FWObject *ruleset, const std::string &single_rule_id, std::ostringstream &nat_rules_stream, fwcompiler::OSConfigurator_linux24 *oscnf, int policy_af, std::map &minus_n_commands_nat) { int nat_rules_count = 0; string host_os = fw->getStr("host_OS"); bool flush_and_set_default_policy = Resources::getTargetOptionBool( host_os, "default/flush_and_set_default_policy"); bool empty_output = true; NAT *nat = NAT::cast(ruleset); assignRuleSetChain(nat); string branch_name = nat->getName(); if (!nat->matchingAddressFamily(policy_af)) return true; bool ipv6_policy = (policy_af == AF_INET6); // compile NAT rules before policy rules because policy // compiler needs to know the number of virtual addresses // being created for NAT std::auto_ptr nat_compiler( new NATCompiler_ipt(objdb, fw, ipv6_policy, oscnf, &minus_n_commands_nat)); if (!nat->isTop()) nat_compiler->registerRuleSetChain(branch_name); nat_compiler->setSourceRuleSet( nat ); nat_compiler->setRuleSetName(branch_name); nat_compiler->setPersistentObjects(persistent_objects); nat_compiler->setSingleRuleCompileMode(single_rule_id); nat_compiler->setDebugLevel( dl ); if (rule_debug_on) nat_compiler->setDebugRule( drn ); nat_compiler->setVerbose( (bool)(verbose) ); nat_compiler->setHaveDynamicInterfaces(have_dynamic_interfaces); if (inTestMode()) nat_compiler->setTestMode(); if (inEmbeddedMode()) nat_compiler->setEmbeddedMode(); nat_compiler->setRulesetToChainMapping(&branch_ruleset_to_chain_mapping); if ( (nat_rules_count=nat_compiler->prolog()) > 0 ) { nat_compiler->compile(); nat_compiler->epilog(); } have_nat = (have_nat || (nat_rules_count > 0)); if (nat_compiler->getCompiledScriptLength() > 0) { if (!single_rule_compile_on) nat_rules_stream << "# ================ Table 'nat', " << " rule set " << branch_name << "\n"; if (nat->isTop()) { if (flush_and_set_default_policy) nat_rules_stream << nat_compiler->flushAndSetDefaultPolicy(); nat_rules_stream << nat_compiler->printAutomaticRules(); } nat_rules_stream << nat_compiler->getCompiledScript(); nat_rules_stream << "\n"; empty_output = false; branch_ruleset_to_chain_mapping[branch_name] = nat_compiler->getUsedChains(); } if (nat_compiler->haveErrorsAndWarnings()) { all_errors.push_back(nat_compiler->getErrors("").c_str()); } return empty_output; } fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_secuwall.h0000644000175000017500000000333511733011756024056 0ustar sylvestresylvestre/* * PolicyCompiler_secuwall.h - Policy compiler for secunet wall host OS * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __POLICYCOMPILER_SECUWALL_H_ #define __POLICYCOMPILER_SECUWALL_H_ #include #include #include "PolicyCompiler_ipt.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Tools.h" namespace libfwbuilder { class Address; class Service; class Interface; class Address; class InetAddr; } namespace fwcompiler { class PolicyCompiler_secuwall : public PolicyCompiler_ipt { protected: virtual std::string myPlatformName(); public: PolicyCompiler_secuwall(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, std::map *m_n_commands_map) : PolicyCompiler_ipt(_db, fw, ipv6_policy, _oscnf, m_n_commands_map) {}; /** * Add some predefined rules controlled by checkboxes in * firewall settings dialog */ virtual std::string printAutomaticRules(); virtual void verifyPlatform(); private: std::vector getMgmtInterfaces(); static bool isValidMgmtRuleInterface(libfwbuilder::Interface* intf); }; } #endif fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_linux24_interfaces.cpp0000644000175000017500000006046611733011756026264 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "OSConfigurator_linux24.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/Resources.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/FailoverClusterGroup.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "Configlet.h" #ifndef _WIN32 # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_linux24::printVerifyInterfacesCommands() { // string os_family = Resources::os_res[fw->getStr("host_OS")]-> // getResourceStr("/FWBuilderResources/Target/family"); QStringList interfaces_to_check; list interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { QString iface_name = (*i)->getName().c_str(); /* if interface name ends with '*', this is a wildcard interface. Do * not check if it exists. */ if (!iface_name.contains("*") && interfaces_to_check.indexOf(iface_name) == -1) { interfaces_to_check.push_back((*i)->getName().c_str()); } } Configlet verify_interfaces(fw, "linux24", "verify_interfaces"); verify_interfaces.setVariable("have_interfaces", interfaces_to_check.size()); verify_interfaces.setVariable("interfaces", interfaces_to_check.join(" ")); return verify_interfaces.expand().toStdString(); } /* * Generate calls to the shell function update_addresses_of_interface * to add or remove ip addresses of interfaces. The following cases * are supported, depending on the value of * @add_virtual_addresses_for_nat and @configure_interfaces * * configure_interfaces == false && add_virtual_addresses_for_nat == false: * do not generate any commands * * configure_interfaces == false && add_virtual_addresses_for_nat == true: * use only virtual_addresses_for_nat, add normal addresses of the interface * to the list of addresses we should ignore * * configure_interfaces == true && add_virtual_addresses_for_nat == false: * ignore virtual_addresses_for_nat * * configure_interfaces == true && add_virtual_addresses_for_nat == true: * use virtual_addresses_for_nat * * */ string OSConfigurator_linux24::printInterfaceConfigurationCommands() { FWOptions* options = fw->getOptionsObject(); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( fw->getStr("host_OS"))); Configlet script(fw, "linux24", "configure_interfaces"); script.removeComments(); script.collapseEmptyStrings(true); list interfaces = fw->getByTypeDeep(Interface::TYPENAME); bool need_promote_command = false; QStringList gencmd; list::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); string iface_name = iface->getName(); QStringList update_addresses; QStringList ignore_addresses; if (int_prop->manageIpAddresses(iface, update_addresses, ignore_addresses)) { if (options->getBool("manage_virtual_addr") && virtual_addresses_for_nat.count(iface_name) > 0) update_addresses.push_back( virtual_addresses_for_nat[iface_name].c_str()); // generate update_addresses calls even if interface has // no addresses in fwbuilder. This makes sure all // addresses it might have on the machine will be // removed. Say, interface was regular and had an address // and then user converted it to unnumbered. In this case // the address should be removed. gencmd.push_back( printUpdateAddressCommand(iface, update_addresses, ignore_addresses)); // update_addresses list looks like this: // ("eth0", "22.22.22.22/24", "22.22.22.23/24") // I need to add "promote" command only when there is more than 1 address. need_promote_command |= (update_addresses.size() > 2); } known_interfaces.push_back(iface_name); } script.setVariable("have_interfaces", interfaces.size() > 0); script.setVariable("need_promote_command", need_promote_command); script.setVariable("configure_interfaces_script", gencmd.join("\n")); return script.expand().toStdString() + "\n"; } /* * printVirtualAddressesForNatCommands() deals with the case when we * add virtual addresses for NAT but do not configure normal addresses * of interfaces */ string OSConfigurator_linux24::printVirtualAddressesForNatCommands() { QStringList gencmd; std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( fw->getStr("host_OS"))); list interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); string iface_name = iface->getName(); QStringList update_addresses; QStringList ignore_addresses; // Return value of InterfaceProperties::manageIpAddresses() // signals if we should manage addresses of the interface at // all, so it is useful even if we are not going to use the // lists. if (int_prop->manageIpAddresses(iface, update_addresses, ignore_addresses)) { // we should not configure normal addresses of interfaces, but // should configure virtual addresses for nat. This means we should // add normal addresses to the ignore_addresses list. ignore_addresses += update_addresses; update_addresses.clear(); if (virtual_addresses_for_nat.count(iface_name) > 0) { update_addresses.push_back( virtual_addresses_for_nat[iface_name].c_str()); gencmd.push_back( printUpdateAddressCommand(iface, update_addresses, ignore_addresses)); } } known_interfaces.push_back(iface_name); } return gencmd.join("\n").toStdString() + "\n"; } string OSConfigurator_linux24::printCommandsToClearKnownInterfaces() { if (fw->getOptionsObject()->getBool("clear_unknown_interfaces") && known_interfaces.size() > 0) { // last resort protection: if there are no interfaces with // addresses in fwbuilder configuration, we should not kill // all addresses of all interfaces on the firewall string res = "clear_addresses_except_known_interfaces "; for (list::iterator it=known_interfaces.begin(); it!=known_interfaces.end(); ++it) { res += *it + " "; } return res; } return ""; } QString OSConfigurator_linux24::printUpdateAddressCommand( Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses) { QStringList out; update_addresses.push_front(intf->getName().c_str()); out.push_back("update_addresses_of_interface"); out.push_back("\"" + update_addresses.join(" ") + "\""); out.push_back("\"" + ignore_addresses.join(" ") + "\""); return out.join(" "); } string OSConfigurator_linux24::printVlanInterfaceConfigurationCommands() { ostringstream out; // Generate code to call shell function "update_vlans" // http://www.cyberciti.biz/tips/howto-configure-linux-virtual-local-area-network-vlan.html // vconfig add eth0 5 QStringList all_vlans; FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); QStringList vlan_interfaces; QString parent_interface = iface->getName().c_str(); FWObjectTypedChildIterator si=iface->findByType(Interface::TYPENAME); for ( ; si!=si.end(); ++si ) { Interface *subinterface = Interface::cast(*si); assert(subinterface); if (subinterface->getOptionsObject()->getStr("type") == "8021q") { vlan_interfaces.push_back(subinterface->getName().c_str()); string name_type = ""; int vlan_id = subinterface->getOptionsObject()->getInt("vlan_id"); QString sintf_name = subinterface->getName().c_str(); QString vlan_name; QStringList supported_vlan_names; vlan_name.sprintf("vlan%04d", vlan_id); supported_vlan_names.append(vlan_name); if (vlan_name == sintf_name) name_type = "VLAN_PLUS_VID"; else { vlan_name.sprintf("vlan%d", vlan_id); supported_vlan_names.append(vlan_name); if (vlan_name == sintf_name) name_type = "VLAN_PLUS_VID_NO_PAD"; else { vlan_name.sprintf("%s.%04d", iface->getName().c_str(), vlan_id); supported_vlan_names.append(vlan_name); if (vlan_name == sintf_name) name_type = "DEV_PLUS_VID_PAD"; else { vlan_name.sprintf("%s.%d", iface->getName().c_str(), vlan_id); supported_vlan_names.append(vlan_name); if (vlan_name == sintf_name) name_type = "DEV_PLUS_VID_NO_PAD"; } } } if (name_type.empty()) { QString err_str( "Name of the VLAN interface '%1' " "does not match any supported naming " "type for VLAN interfaces. Possible names: %2"); abort(err_str.arg(sintf_name). arg(supported_vlan_names.join(", ")).toStdString()); } } } if (vlan_interfaces.size() > 0) { out << "update_vlans_of_interface \"" << parent_interface.toStdString() << " " << vlan_interfaces.join(" ").toStdString() << "\"" << endl; foreach(QString intf, vlan_interfaces) { all_vlans.push_back(QString("%1@%2").arg(intf).arg(parent_interface)); } } } out << "clear_vlans_except_known" << " " << all_vlans.join(" ").toStdString() << endl; return out.str(); } string OSConfigurator_linux24::printBridgeInterfaceConfigurationCommands() { /* * http://www.linuxfoundation.org/en/Net:Bridge#Manual_Configuration * # brctl addbr br12 * # brctl addif br12 eth0 * # brctl addif br12 eth1 * # ifconfig br12 up */ list all_bridges = fw->getInterfacesByType("bridge"); QStringList names; for (list::iterator it=all_bridges.begin(); it!=all_bridges.end(); ++it) names.push_back((*it)->getName().c_str()); QStringList gencmd; gencmd.push_back("sync_bridge_interfaces " + names.join(" ")); for (list::iterator it=all_bridges.begin(); it!=all_bridges.end(); ++it) { Interface *iface = Interface::cast(*it); assert(iface); QStringList out; QStringList bridge_interfaces; if (iface->getOptionsObject()->getStr("type") == "bridge") { out.push_back("update_bridge"); out.push_back(iface->getName().c_str()); FWObjectTypedChildIterator si=iface->findByType(Interface::TYPENAME); for ( ; si!=si.end(); ++si ) { Interface *subinterface = Interface::cast(*si); assert(subinterface); bridge_interfaces.push_back(subinterface->getName().c_str()); } out.push_back("\"" + bridge_interfaces.join(" ") + "\""); gencmd.push_back(out.join(" ")); out.clear(); bool enable_stp = iface->getOptionsObject()->getBool("enable_stp"); out.push_back("$BRCTL stp"); out.push_back(iface->getName().c_str()); out.push_back((enable_stp)?"on":"off"); gencmd.push_back(out.join(" ")); } } return gencmd.join("\n").toStdString() + "\n"; } string OSConfigurator_linux24::printBondingInterfaceConfigurationCommands() { /* * http://www.linuxfoundation.org/en/Net:Bonding#Configuring_Bonding_Manually * * modprobe bonding mode=balance-alb miimon=100 * modprobe e100 * ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up * ifenslave bond0 eth0 * ifenslave bond0 eth1 */ QStringList gencmd; QStringList bonding_interfaces; QString module_parameters; FWObjectTypedChildIterator i = fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); QStringList out; if (iface->getOptionsObject()->getStr("type") == "bonding") { /* * current implementation of function load_bonding_module() * in the configlet loads the module once, which means we can * only support the same parameters for all bonding interfaces. * Take parameters from the first bonding interface and use that * in the call to load_bonding_module() * * However, check if parameters for the subsequent bonding * interfaces are different and issue warning. */ QString mode = iface->getOptionsObject()->getStr("bonding_policy").c_str(); QString xmit_hash_policy = iface->getOptionsObject()->getStr("xmit_hash_policy").c_str(); QString driver_opts = iface->getOptionsObject()->getStr("bondng_driver_options").c_str(); QStringList params; if (!mode.isEmpty()) params.push_back("mode=" + mode); if (!xmit_hash_policy.isEmpty()) params.push_back("xmit_hash_policy=" + xmit_hash_policy); if (!driver_opts.isEmpty()) params.push_back(driver_opts); if (module_parameters.isEmpty()) { module_parameters = params.join(" "); } else { if (module_parameters != params.join(" ")) { warning( QString("Different protocol parameters for multiple " "bonding interfaces are not supported at " "this time. Module 'bonding' " "will be loaded with the following parameters: '%1'") .arg(module_parameters).toStdString()); } } out.push_back("update_bonding"); out.push_back(iface->getName().c_str()); bonding_interfaces.push_back(iface->getName().c_str()); QStringList bonding_interfaces; FWObjectTypedChildIterator j = iface->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *subint = Interface::cast(*j); if (subint->getOptionsObject()->getStr("type") == "" || subint->getOptionsObject()->getStr("type") == "ethernet") bonding_interfaces.push_back(subint->getName().c_str()); } out.push_back(bonding_interfaces.join(" ")); gencmd.push_back(out.join(" ")); } } if (bonding_interfaces.size()) { gencmd.push_front( QString("load_bonding_module \"%1\" max_bonds=%2 %3") .arg(bonding_interfaces.join(" ")) .arg(bonding_interfaces.size()) .arg(module_parameters)); gencmd.push_back( QString("clear_bonding_except_known %1") .arg(bonding_interfaces.join(" "))); } else gencmd.push_front("unload_bonding_module"); return gencmd.join("\n").toStdString() + "\n"; } string OSConfigurator_linux24::printDynamicAddressesConfigurationCommands() { ostringstream out; /* * get addresses of dynamic interfaces */ list interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator j; for (j=interfaces.begin(); j!=interfaces.end(); ++j ) { Interface *iface = Interface::cast(*j); if ( iface->isDyn() ) { /* if interface name ends with '*', this is a wildcard interface. Do * not get its address at this time. */ if (iface->getName().find("*")==string::npos) { out << "getaddr " << iface->getName() << " " << getInterfaceVarName(iface, false) << endl; out << "getaddr6 " << iface->getName() << " " << getInterfaceVarName(iface, true) << endl; out << "getnet " << iface->getName() << " " << getInterfaceVarName(iface, false) << "_network" << endl; out << "getnet6 " << iface->getName() << " " << getInterfaceVarName(iface, true) << "_network" << endl; } } } return out.str(); } bool OSConfigurator_linux24::validateInterfaces() { FWOptions* options = fw->getOptionsObject(); if ( options->getBool("configure_bridge_interfaces") ) { /* * Per #315: * * The test should scan all subinterfaces of each interface and * try to find inetrfaces wth the same name, then check the * type. So, for the combination br0/br1, the type of br1 * is (probably) "bridge" which is not allowed. */ FWObjectTypedChildIterator i = fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); FWObjectTypedChildIterator j = iface->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *subinterface = Interface::cast(*j); FWObject::const_iterator it = find_if( fw->begin(), fw->end(), FWObjectNameEQPredicate(subinterface->getName())); if (it != fw->end() && Interface::isA(*it)) { Interface *other_iface = Interface::cast(*it); // Have top-level interface with the same name if (other_iface->getOptionsObject()->getStr("type") == "bridge") { QString err( "Subinterface '%1' of interface '%2' has the same name as " "another bridge interface of the firewall '%3'. " "The configuration where bridge interface is " "a subinterface of another interface is not supported."); abort( err.arg(subinterface->getName().c_str()). arg(iface->getName().c_str()). arg(fw->getName().c_str()).toStdString()); return false; } } } } } if (options->getBool("configure_vlan_interfaces")) { /* * Per #324: * * Unsupported configurations: * * vlan interfaces under bridge interface (e.g. br0 = [eth1, * eth2], vlan inetrface br0.100 is not supported) * * bridge interface as part of bonding interface (e.g. bond0 = * [br0, br1]) (This is covered by the case above, including * unusual interface names) * * vlan interface as a slave of bonding interface (e.g. eth0.100, * eth1.100, bond0 = [eth0.100, eth1.100]). Only regular * interfaces can be slaves of bonding interface. If subinterface * type is "slave" but its name matches one of the vlan interface * regexes, assume this is vlan. Slave subintrfaces do not have to * be copies, one can have "eth4" only once, as a slave, so here * we rely on the subinterface type. * * Allowed configurations: * * vlans can be created under bonding interface (e.g. bond0.100), * both regular interfaces and vlans can be bridge ports. } */ FWObjectTypedChildIterator i = fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); FWObjectTypedChildIterator j = iface->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *subinterface = Interface::cast(*j); if ( options->getBool("configure_bridge_interfaces") ) { if (subinterface->getOptionsObject()->getStr("type") == "8021q" && iface->getOptionsObject()->getStr("type") == "bridge") { QString err( "Vlan subinterfaces of bridge interfaces " "are not supported. " "Interface '%1', subinterface '%2'"); abort( err.arg(iface->getName().c_str()). arg(subinterface->getName().c_str()).toStdString()); } } if ( options->getBool("configure_bonding_interfaces")) { if (subinterface->getOptionsObject()->getStr("type") != "8021q" && iface->getOptionsObject()->getStr("type") == "bonding") { QString subint_name = subinterface->getName().c_str(); QRegExp vlan1("[a-zA-Z-]+\\d{1,}\\.\\d{1,}"); QRegExp vlan2("vlan\\d{1,}"); if (vlan1.indexIn(subint_name) != -1 || vlan1.indexIn(subint_name) != -1) { QString err( "Vlan subinterfaces as slaves of bonding interfaces " "are not supported. " "Interface '%1', subinterface '%2'"); abort( err.arg(iface->getName().c_str()). arg(subinterface->getName().c_str()).toStdString()); } } } } } } return true; } fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_ipt.cpp0000644000175000017500000047771611733011756023410 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_ipt.h" #include "OSConfigurator_linux24.h" #include "ipt_utils.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/physAddress.h" #include "combinedAddress.h" #include #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; static int chain_no=0; static std::list standard_chains; const std::list& PolicyCompiler_ipt::getStandardChains() { if (standard_chains.size()==0) { standard_chains.push_back("INPUT"); standard_chains.push_back("OUTPUT"); standard_chains.push_back("FORWARD"); standard_chains.push_back("PREROUTING"); standard_chains.push_back("POSTROUTING"); standard_chains.push_back("RETURN"); standard_chains.push_back("LOG"); standard_chains.push_back("ACCEPT"); standard_chains.push_back("DROP"); standard_chains.push_back("REJECT"); standard_chains.push_back("MARK"); standard_chains.push_back("CONNMARK"); standard_chains.push_back("QUEUE"); standard_chains.push_back("CLASSIFY"); standard_chains.push_back("ROUTE"); // pseudo-targets standard_chains.push_back(".CUSTOM"); standard_chains.push_back(".CONTINUE"); } return standard_chains; } PolicyCompiler_ipt::~PolicyCompiler_ipt() { // if (printRule) delete printRule; while (chains.size() > 0) { map::iterator i = chains.begin(); chain_list *cl = i->second; chains.erase(i); delete cl; } } string PolicyCompiler_ipt::myPlatformName() { return "iptables"; } void PolicyCompiler_ipt::registerChain(const string &chain_name) { map::iterator i = chains.find(chain_name); if (i==chains.end()) { chain_list *cl = new chain_list(); cl->push_back(chain_name); chains[chain_name] = cl; } } void PolicyCompiler_ipt::insertUpstreamChain(const string &chain_name, const string &before_chain) { if (!chain_name.empty()) { map::iterator i = chains.find(before_chain); if (i==chains.end()) return; chain_list *cl = i->second; list::iterator j = std::find(cl->begin(), cl->end(), before_chain); cl->insert(j, chain_name); } } string PolicyCompiler_ipt::findUpstreamChain(const string &chain_name) { map::iterator i = chains.find(chain_name); if (i==chains.end()) return ""; return i->second->front(); } void PolicyCompiler_ipt::setChain(PolicyRule *rule, const string &chain_name) { rule->setStr("ipt_chain", chain_name); string target = rule->getStr("ipt_target"); if (!target.empty()) { registerChain(target); insertUpstreamChain(chain_name, target); } } string PolicyCompiler_ipt::printChains(PolicyRule *rule) { string chain_name = rule->getStr("ipt_chain"); map::iterator i = chains.find(chain_name); if (i==chains.end() || i->second->size()==0) return chain_name; ostringstream res; for (list::iterator j=i->second->begin(); j!=i->second->end(); ++j) { res << *j; if (*j == chain_name) res << "*"; res << "[" << chain_usage_counter[*j] << "],"; } return res.str(); } bool PolicyCompiler_ipt::isChainDescendantOfOutput(const string &chain_name) { map::iterator i = chains.find(chain_name); if (i==chains.end()) return false; for (list::iterator j=i->second->begin(); j!=i->second->end(); ++j) if (*j=="OUTPUT") return true; return false; } bool PolicyCompiler_ipt::isChainDescendantOfInput(const string &chain_name) { map::iterator i = chains.find(chain_name); if (i==chains.end()) return false; for (list::iterator j=i->second->begin(); j!=i->second->end(); ++j) if (*j=="INPUT") return true; return false; } /* * this function generates acceptable shell variable name from * interface name. Note that OSConfigurator_linux24::getInterfaceVarName() * does the same and these two functions should be identical. * * TODO: really need to have one function for this instead of two in * two different classes. */ string PolicyCompiler_ipt::getInterfaceVarName(FWObject *iface, bool v6) { ostringstream ostr; string iname = iface->getName(); string::size_type p1; while ( (p1=iname.find("."))!=string::npos) iname=iname.replace(p1,1,"_"); while ( (p1=iname.find("-"))!=string::npos) iname=iname.replace(p1,1,"_"); ostr << "i_" << iname; if (v6) ostr << "_v6"; return ostr.str(); } string PolicyCompiler_ipt::getAddressTableVarName(FWObject *at) { ostringstream ostr; string name = at->getName(); string::size_type p1; const char *bad_shell_chars = " !#$&*()-+=\\|{}[]?<>,.:"; for (const char *cptr=bad_shell_chars; *cptr; cptr++) { while ((p1 = name.find(*cptr)) != string::npos) name = name.replace(p1,1,"_"); } ostr << "at_" << name; return ostr.str(); } string PolicyCompiler_ipt::getNewTmpChainName(PolicyRule *rule) { std::ostringstream str; string chain_id = rule->getUniqueId(); int n = tmp_chain_no[chain_id]; str << "C" << chain_id; str << "." << setw(1) << setfill('0') << n; n++; tmp_chain_no[chain_id]=n; return str.str(); #if 0 std::ostringstream str; str << "ptmp" << setw(3) << setfill('0') << chain_no; chain_no++; return str.str(); #endif } string PolicyCompiler_ipt::getNewChainName(PolicyRule *rule, Interface *rule_iface) { std::ostringstream str; /* if interface name ends with '*', this is a wildcard interface. We * do not want '*' to get incorporated into the chain name, so we * replace it with '_' */ if (rule_iface) { string iface_name = rule_iface->getName(); string::size_type n=iface_name.find("*"); str << iface_name.substr(0,n) << "_"; } switch (rule->getDirection()) { case PolicyRule::Inbound: str << "In_"; break; case PolicyRule::Outbound: str << "Out_"; break; default: ; } int pos = rule->getPosition(); string ruleset_name = getRuleSetName(); if (ruleset_name != "Policy") str << ruleset_name << "_"; else str << "RULE_"; if (pos>=0) str << pos; else // special case: position == -1 str << "000"; string suffix = rule->getStr("subrule_suffix"); if (!suffix.empty()) str << "_" << suffix; string chain_name = str.str(); int n = rule_chain_no[chain_name]; n++; rule_chain_no[chain_name] = n; // if (n > 1) // { // str << "_" << n; // } string full_chain_name = str.str(); chain_no++; return full_chain_name; } void PolicyCompiler_ipt::_expand_interface(Rule *rule, Interface *iface, std::list &list_result, bool expand_cluster_interfaces_fully) { std::list ol1; Compiler::_expand_interface( rule, iface, ol1, expand_cluster_interfaces_fully); // see utils.cpp expand_interface_with_phys_address(this, rule, iface, ol1, list_result); } string PolicyCompiler_ipt::getActionOnReject(PolicyRule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); return ruleopt->getStr("action_on_reject"); } bool PolicyCompiler_ipt::isActionOnRejectTCPRST(PolicyRule *rule) { string s = getActionOnReject(rule); return ( ! s.empty() && s.find("TCP ")!=string::npos ); } /* * resets rule option "action_on_reject" so it won't be TCP RST * Algorithm: * * if global option "action_on_reject" is not empty * if global option is TCP RST * set rule option value to "none" * else * copy value from global option to rule option * else * set rule option value to "none" * * */ void PolicyCompiler_ipt::resetActionOnReject(PolicyRule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); string go = getCachedFwOpt()->getStr("action_on_reject"); if (!go.empty()) { if ( go.find("TCP ")!=string::npos ) { ruleopt->setStr("action_on_reject", "NOP"); // hack. } else { ruleopt->setStr("action_on_reject", go); } } else ruleopt->setStr("action_on_reject", "none"); // hack. } void PolicyCompiler_ipt::registerRuleSetChain(const std::string &chain_name) { chain_usage_counter[chain_name] = 1; } void PolicyCompiler_ipt::verifyPlatform() { string family = Resources::platform_res[fw->getStr("platform")]-> getResourceStr("/FWBuilderResources/Target/family"); if (family != myPlatformName()) abort("Unsupported platform " + fw->getStr("platform") + " (family " + family + ")"); } int PolicyCompiler_ipt::prolog() { verifyPlatform(); PolicyCompiler::prolog(); addPredefinedPolicyRules(); FWOptions *fwopt = getCachedFwOpt(); // initialize counters for the standard chains for (list::const_iterator i = PolicyCompiler_ipt::getStandardChains().begin(); i != PolicyCompiler_ipt::getStandardChains().end(); ++i) { chain_usage_counter[*i] = 1; } Service *anytcp, *anyudp, *anyicmp, *anyip; Address *bcast255; TCPService *tcpsyn; anytcp=dbcopy->createTCPService(); anytcp->setId(FWObjectDatabase::registerStringId(ANY_TCP_OBJ_ID)); anytcp->setName("AnyTCP"); persistent_objects->add(anytcp); tcpsyn=dbcopy->createTCPService(); tcpsyn->setId(FWObjectDatabase::registerStringId(TCP_SYN_OBJ_ID)); tcpsyn->setName("tcpSYN"); tcpsyn->setTCPFlag(TCPService::SYN,true); tcpsyn->setAllTCPFlagMasks(); persistent_objects->add(tcpsyn); anyudp=dbcopy->createUDPService(); anyudp->setId(FWObjectDatabase::registerStringId(ANY_UDP_OBJ_ID)); anyudp->setName("AnyUDP"); persistent_objects->add(anyudp); anyicmp=dbcopy->createICMPService(); anyicmp->setId(FWObjectDatabase::registerStringId(ANY_ICMP_OBJ_ID)); anyicmp->setName("AnyICMP"); persistent_objects->add(anyicmp); anyip=dbcopy->createIPService(); anyip->setId(FWObjectDatabase::registerStringId(ANY_IP_OBJ_ID)); anyip->setName("AnyIP"); persistent_objects->add(anyip); bcast255=dbcopy->createIPv4(); bcast255->setId(FWObjectDatabase::registerStringId(BCAST_255_OBJ_ID)); bcast255->setName("Broadcast_addr"); bcast255->setAddress(InetAddr::getAllOnes()); bcast255->setNetmask(InetAddr(InetAddr::getAllOnes())); persistent_objects->add(bcast255); bool global_afpa = fwopt->getBool("firewall_is_part_of_any_and_networks"); int n = 0; for(FWObject::iterator i=source_ruleset->begin(); i!=source_ruleset->end(); i++) { Rule *r = Rule::cast( *i ); if (r == NULL) continue; if (r->isDisabled()) continue; FWOptions *ruleopt = r->getOptionsObject(); string rule_afpa = ruleopt->getStr("firewall_is_part_of_any_and_networks"); // in v3.0 rule options attribute "assume fw is part of any" // used to be a checkbox and therefore stored as boolean in // the rule options. Old "on" or "True" maps to "1", old "off" // or "False" maps to "use global" (it was impossible to turn // this option off for just one rule if it was on // globally). If this attribute has value of an empty string, // then we should use global setting from the firewall options // object. if (rule_afpa.empty()) ruleopt->setInt("firewall_is_part_of_any_and_networks", global_afpa); if (rule_afpa == "True") ruleopt->setInt("firewall_is_part_of_any_and_networks", 1); if (rule_afpa == "False") ruleopt->setInt("firewall_is_part_of_any_and_networks", global_afpa); n++; } string version = fw->getStr("version"); using_ipset = (XMLTools::version_compare(version, "1.4.1.1") >= 0 && fwopt->getBool("use_m_set")); actually_used_module_set = false; build_interface_groups(dbcopy, persistent_objects, fw, ipv6, regular_interfaces); // count bridge interfaces. We need this later in // PrintRule::_printDirectionAndInterface list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); string interface_type = iface->getOptionsObject()->getStr("type"); if (interface_type == "bridge") bridge_count++; } return n; } void PolicyCompiler_ipt::addPredefinedPolicyRules() { // if (getSourceRuleSet()->isTop() && !inSingleRuleCompileMode()) // { // insertConntrackRule(); // insertFailoverRule(); // } } bool PolicyCompiler_ipt::SkipActionContinueWithNoLogging::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( ! rule->getStr("ipt_target").empty() && rule->getStr("ipt_target") == ".CONTINUE" && ! rule->getLogging() && ! rule->getTagging() && ! rule->getClassification() && ! rule->getRouting()) return true; // skip this rule tmp_queue.push_back(rule); return true; } /* * by the time this processor is called all non-terminating rules should * be processed if terminating behevior needs to be emulated. */ bool PolicyCompiler_ipt::dropTerminatingTargets::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; string tgt = rule->getStr("ipt_target"); if (tgt=="CLASSIFY" || tgt=="MARK") tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::clearTagClassifyInFilter::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; if (ipt_comp->my_table != "mangle") { rule->setClassification(false); rule->setRouting(false); rule->setTagging(false); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::clearActionInTagClassifyIfMangle::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; if (ipt_comp->my_table == "mangle" && (rule->getTagging() || rule->getClassification()) ) rule->setAction(PolicyRule::Continue); tmp_queue.push_back(rule); return true; } /* * in a rule generates some code in both filter and mangle tables and * has logging turned on, we should log only once. Will log in filter. * However if the rule belongs to mangle-only rule set, we should log * in mangle. */ bool PolicyCompiler_ipt::clearLogInMangle::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *rulesetopts = ipt_comp->getSourceRuleSet()->getOptionsObject(); if (rulesetopts->getBool("mangle_only_rule_set")) { tmp_queue.push_back(rule); return true; } if (ipt_comp->my_table == "mangle") rule->setLogging(false); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfTagClassifyOrRoute::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *r; int number_of_options = 0; if (rule->getTagging()) number_of_options++; if (rule->getClassification()) number_of_options++; if (rule->getRouting()) number_of_options++; if (ipt_comp->my_table=="mangle" && number_of_options > 0) { RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; RuleElementItf *nitfre; PolicyRule *r, *r2; string this_chain = rule->getStr("ipt_chain"); string new_chain = this_chain; nsrc = rule->getSrc(); ndst = rule->getDst(); nsrv = rule->getSrv(); nitfre = rule->getItf(); if ( (! nsrc->isAny() || ! ndst->isAny() || ! nsrv->isAny() || ! nitfre->isAny()) && number_of_options > 1 ) { new_chain = ipt_comp->getNewTmpChainName(rule); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix", "ntt"); r->setStr("ipt_target", new_chain); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setAction(PolicyRule::Continue); tmp_queue.push_back(r); nsrc = rule->getSrc(); nsrc->reset(); ndst = rule->getDst(); ndst->reset(); nsrv = rule->getSrv(); nsrv->reset(); nitfre = rule->getItf(); nitfre->reset(); ruleopt = rule->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setBool("stateless",true); rule->setLogging(false); } if (rule->getTagging()) { r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setClassification(false); r->setRouting(false); rule->setTagging(false); r->setStr("ipt_chain", new_chain); r->setStr("upstream_rule_chain", this_chain); r->setAction(PolicyRule::Continue); tmp_queue.push_back(r); } if (rule->getClassification()) { r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); rule->setClassification(false); r->setRouting(false); r->setTagging(false); r->setStr("ipt_chain", new_chain); r->setStr("upstream_rule_chain", this_chain); r->setAction(PolicyRule::Continue); tmp_queue.push_back(r); } /* * Target ROUTE is terminating unless parameter "--continue" * is present. We add "--continue" if action is Continue, * otherwise the rule does not need to be split and we carry * action Accept further. */ if (rule->getRouting() || rule->getAction() != PolicyRule::Continue) { rule->setClassification(false); rule->setTagging(false); rule->setStr("ipt_chain", new_chain); rule->setStr("upstream_rule_chain", this_chain); tmp_queue.push_back(rule); } } else tmp_queue.push_back(rule); return true; } // this version just splits rule so that each elementary rule is associated // with one interface. bool PolicyCompiler_ipt::InterfacePolicyRulesWithOptimization::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementItf *itfre = rule->getItf(); assert(itfre); // sometimes for whatever reason itf rule element appears to be broken // (it is just empty, not even "any") if (itfre->isAny() || itfre->size()==0) { //rule->setInterfaceId(-1); tmp_queue.push_back(rule); return true; } for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i) { FWObject *o = FWObjectReference::getObject(*i); PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix", "i1"); //r->setInterfaceId(o->getId()); RuleElementItf *nitfre = r->getItf(); nitfre->reset(); nitfre->addRef(o); tmp_queue.push_back(r); } return true; } /** * Deprecated beginning with 4.3.0. To be removed in future versions. */ bool PolicyCompiler_ipt::Route::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); if (rule->getRouting()) { string iif,oif,gw; iif = ruleopt->getStr("ipt_iif"); oif = ruleopt->getStr("ipt_oif"); gw = ruleopt->getStr("ipt_gw"); if (!iif.empty()) { ipt_comp->setChain(rule, "PREROUTING"); } if (!oif.empty() || !gw.empty()) { ipt_comp->setChain(rule, "POSTROUTING"); } if (ruleopt->getBool("ipt_tee")) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(rule, "PREROUTING"); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(rule, "POSTROUTING"); tmp_queue.push_back(r); return true; } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::dropMangleTableRules::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); string ruleset_name = compiler->getRuleSetName(); FWOptions *rulesetopts = ipt_comp->getSourceRuleSet()->getOptionsObject(); if (rulesetopts->getBool("mangle_only_rule_set")) return true; if ( rule->getAction() == PolicyRule::Continue && ! rule->getLogging() && (rule->getTagging() || rule->getRouting() || rule->getClassification())) return true; // Another special case (while working on #1415, although not // related directly): branching rule that has "branch in mangle table" // checkbox turned on and is branches to the "mangle only" rule set // does not need any iptables rules in the filter table FWOptions *ruleopt = rule->getOptionsObject(); if (rule->getAction() == PolicyRule::Branch && ruleopt->getBool("ipt_branch_in_mangle")) { RuleSet *ruleset = rule->getBranch(); assert(ruleset!=NULL); rulesetopts = ruleset->getOptionsObject(); if (rulesetopts->getBool("mangle_only_rule_set")) return true; } tmp_queue.push_back(rule); return true; } /* * Only call this rule processor if compiling for the mangle table */ bool PolicyCompiler_ipt::checkActionInMangleTable::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getAction() == PolicyRule::Reject) { compiler->abort( rule, "Action Reject is not allowed in mangle table"); return true; } tmp_queue.push_back(rule); return true; } /* * Rules with action Tag can only be in PREROUTING or OUTPUT chains, * rules with action Classify always go into POSTROUTING. This means * they can't conflict. But option Route can yield rules in PREROUTING * or POSTROUTING and can conflict. We'll flag combinations of Tag + * Route and Classify + Route if action is not Continue. */ bool PolicyCompiler_ipt::checkForUnsupportedCombinationsInMangle::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; if (ipt_comp->my_table=="mangle" && rule->getAction() != PolicyRule::Continue && rule->getRouting() && (rule->getTagging() || rule->getClassification())) { QString err("Can not process option Route in combination with " "options Tag or Classify and action %1"); compiler->abort( rule, err.arg(rule->getActionAsString().c_str()).toStdString()); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::deprecateOptionRoute::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getRouting()) { compiler->abort( rule, "Option Route is deprecated. You can use Custom Action " "to generate iptables command using '-j ROUTE' target " "if it is supported by your firewall OS"); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::Logging1::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( compiler->getCachedFwOpt()->getBool("log_all") ) rule->setLogging(true); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::storeAction::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; rule->setStr("stored_action", rule->getActionAsString() ); rule->setBool("originated_from_a_rule_with_tagging", rule->getTagging()); rule->setBool("originated_from_a_rule_with_classification", rule->getClassification()); rule->setBool("originated_from_a_rule_with_routing", rule->getRouting()); tmp_queue.push_back(rule); return true; } /** * splits rule if logging is required and either src or dst is * not any */ bool PolicyCompiler_ipt::Logging2::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; RuleElementInterval *nint; RuleElementItf *nitfre; if (rule->getLogging()) { /* * see #2235 Rules with action Continue translate into iptables * commands without "-j TARGET" parameter, so we dont need to create new chain * for logging. */ if (rule->getAction() == PolicyRule::Continue && ( ! rule->getTagging() && ! rule->getClassification() && ! rule->getRouting())) { rule->setStr("ipt_target", "LOG"); tmp_queue.push_back(rule); return true; } /* * chain could have been assigned if we split this rule before */ string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewChainName(rule, NULL); //rule_iface); PolicyRule *r; FWOptions *ruleopt; /* * if we are in the user-defined chain and src=dst=srv=int=any, then there is no * need to create a sub-chain. Otherwise, create new chain and handle logging * and actual original target there. */ bool need_new_chain = true; if (this_chain==new_chain && rule->getSrc()->isAny() && rule->getDst()->isAny() && rule->getSrv()->isAny() && (rule->getWhen())!=NULL && rule->getWhen()->isAny()) { need_new_chain = false; } /* * add copy of original rule, but turn off logging and set target * chain to new_chain. */ if (need_new_chain) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ruleopt =r->getOptionsObject(); r->setStr("ipt_target",new_chain); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setAction(PolicyRule::Continue); // ### // ruleopt->setInt("limit_value",-1); tmp_queue.push_back(r); } /* * need to add two rules with the same rule_label, direction=both, no * interface, no src, no srv and no dst. One of these new rules should * have target = LOG and another should inherit action and therefore * target from original rule. Both new rules go into chain new_chain. * In both rules turn off stateful inspection. * * keep interface information in the first one to be able to process * %I in log prefix * */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ruleopt =r->getOptionsObject(); nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); nsrv=r->getSrv(); nsrv->reset(); nitfre=r->getItf(); nitfre->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); r->setStr("ipt_chain",new_chain); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); r->setStr("ipt_target","LOG"); r->setAction(PolicyRule::Continue); // ### r->setDirection( PolicyRule::Both ); r->setLogging(false); r->setClassification(false); r->setRouting(false); r->setTagging(false); ruleopt->setBool("stateless",true); r->setBool("force_state_check",false); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ruleopt =r->getOptionsObject(); nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); nitfre=r->getItf(); nitfre->reset(); /* * special case: need to preserve information about service protocol in case * action_on_reject is TCP RST */ nsrv=r->getSrv(); Service *srv= compiler->getFirstSrv(r); if (TCPService::isA(srv)) { nsrv->clearChildren(); nsrv->addRef(compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(ANY_TCP_OBJ_ID))); } else { nsrv->reset(); } r->setStr("ipt_chain",new_chain); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); r->setStr(".iface", "nil"); //r->setInterfaceStr("nil"); r->setDirection( PolicyRule::Both ); r->setLogging(false); ruleopt->setBool("stateless",true); r->setBool("force_state_check",false); r->setBool("final",true); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } string PolicyCompiler_ipt::printRuleElements::printRE(RuleElement *re) { ostringstream str; if (re->size() == 0) return ""; FWObject *obj = FWReference::cast(re->front())->getPointer(); str << "id=" << obj->getId() << " name=" << obj->getName() << " type=" << obj->getTypeName(); return str.str(); } bool PolicyCompiler_ipt::printRuleElements::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel = rule->getSrc(); RuleElementDst *dstrel = rule->getDst(); RuleElementSrv *srvrel = rule->getSrv(); cerr << "rule " << rule->getLabel() << " src: " << printRE(srcrel) << " dst: " << printRE(dstrel) << " srv: " << printRE(srvrel) << endl; tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipt::SingleRENegation::processSingleObjectNegationInRE( FWObject *obj, RuleElement *rel) { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); // We call singleSrcNegation before we replace AddressTable // objects with MultiAddressRunTime objects if (AddressTable::cast(obj) && AddressTable::cast(obj)->isRunTime() && ipt_comp->using_ipset) { rel->setNeg(false); rel->setBool("single_object_negation", true); return; } Address *src = Address::cast(obj); // note: src can be NULL if object in this rule element is a group // or MultiAddress if (src!=NULL && src->countInetAddresses(true)==1 && !compiler->complexMatch(src, compiler->fw)) { rel->setNeg(false); rel->setBool("single_object_negation", true); return; } Service *srv = Service::cast(obj); // see comment in compile() where this rule processor is used for why // only some services can be processed here. if (TagService::isA(srv) || UserService::isA(srv)) { /* A B ! C ACTION */ rel->setNeg(false); rel->setBool("single_object_negation", true); } } bool PolicyCompiler_ipt::SingleRENegation::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElement *rel = RuleElement::cast(rule->getFirstByType(type_name)); /* ! A B C ACTION */ if (rel->getNeg() && rel->size()==1) { processSingleObjectNegationInRE(FWReference::getObject(rel->front()), rel); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::SrcNegation::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); string afpa = ruleopt->getStr("firewall_is_part_of_any_and_networks"); RuleElementSrc *srcrel=rule->getSrc(); /* ! A B C D ACTION */ if (srcrel->getNeg()) { PolicyRule *r; RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; RuleElementInterval *nint; RuleElementItf *nitf; FWOptions *ruleopt; /*chain could have been assigned if we split this rule before */ string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewTmpChainName(rule); srcrel->setNeg(false); rule->setBool("upstream_rule_neg",true); /* any B C D TMP_CHAIN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","1"); nsrc=r->getSrc(); nsrc->reset(); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_target",new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setStr("firewall_is_part_of_any_and_networks", afpa); tmp_queue.push_back(r); /* TMP_CHAIN A any any any RETURN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","2"); if (!shadowing_mode) { ndst=r->getDst(); ndst->reset(); nsrv=r->getSrv(); nsrv->reset(); nitf=r->getItf(); nitf->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); } r->setAction( PolicyRule::Return ); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_chain",new_chain); r->setStr("ipt_target",""); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setBool("stateless",true); // ### tmp_queue.push_back(r); /* TMP_CHAIN any any any any ACTION */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","3"); nsrc=r->getSrc(); nsrc->reset(); if (!shadowing_mode) { ndst = r->getDst(); ndst->reset(); nitf = r->getItf(); nitf->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); /* * special case: need to preserve information about service protocol in case * action_on_reject is TCP RST */ nsrv=r->getSrv(); Service *srv= compiler->getFirstSrv(r); if (TCPService::isA(srv)) { nsrv->clearChildren(); nsrv->addRef(compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(ANY_TCP_OBJ_ID))); } else { nsrv->reset(); } } r->setStr("ipt_chain",new_chain); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); if ( ! rule->getStr("ipt_target").empty() ) r->setStr("ipt_target",rule->getStr("ipt_target")); // r->setInterfaceStr("nil"); r->setBool("final",true); ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); // ### tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::DstNegation::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); string afpa = ruleopt->getStr("firewall_is_part_of_any_and_networks"); RuleElementDst *dstrel=rule->getDst(); /* A ! B C D ACTION */ if (dstrel->getNeg()) { PolicyRule *r; RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; RuleElementInterval *nint; RuleElementItf *nitf; FWOptions *ruleopt; /*chain could have been assigned if we split this rule before */ string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewTmpChainName(rule); dstrel->setNeg(false); rule->setBool("upstream_rule_neg",true); /* A any C D TMP_CHAIN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","1"); ndst=r->getDst(); ndst->reset(); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_target",new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setStr("firewall_is_part_of_any_and_networks", afpa); tmp_queue.push_back(r); /* TMP_CHAIN any B any any RETURN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","2"); if (!shadowing_mode) { nsrc=r->getSrc(); nsrc->reset(); nsrv=r->getSrv(); nsrv->reset(); nitf=r->getItf(); nitf->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); } r->setAction( PolicyRule::Return ); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_chain",new_chain); r->setStr("ipt_target",""); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setBool("stateless",true); // ### // r->setInterfaceStr("nil"); tmp_queue.push_back(r); /* TMP_CHAIN any any any any ACTION */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","3"); ndst=r->getDst(); ndst->reset(); if (!shadowing_mode) { nsrc=r->getSrc(); nsrc->reset(); nitf=r->getItf(); nitf->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); /* * special case: need to preserve information about service protocol in case * action_on_reject is TCP RST */ nsrv=r->getSrv(); Service *srv= compiler->getFirstSrv(r); if (TCPService::isA(srv)) { nsrv->clearChildren(); nsrv->addRef(compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(ANY_TCP_OBJ_ID))); } else { nsrv->reset(); } } r->setStr("ipt_chain",new_chain); r->setStr("ipt_target",""); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); if ( ! rule->getStr("ipt_target").empty() ) r->setStr("ipt_target",rule->getStr("ipt_target")); // r->setInterfaceStr("nil"); r->setBool("final",true); ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); // ### tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::SrvNegation::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srvrel=rule->getSrv(); /* A B !C D ACTION */ if (srvrel->getNeg()) { PolicyRule *r; RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; RuleElementInterval *nint; RuleElementItf *nitf; FWOptions *ruleopt; /*chain could have been assigned if we split this rule before */ string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewTmpChainName(rule); srvrel->setNeg(false); /* A B any D TMP_CHAIN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","1"); nsrv=r->getSrv(); nsrv->reset(); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_target",new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); tmp_queue.push_back(r); /* TMP_CHAIN any any C any RETURN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","2"); if (!shadowing_mode) { nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); nitf=r->getItf(); nitf->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); } r->setAction( PolicyRule::Return ); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_chain",new_chain); r->setStr("ipt_target",""); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setBool("stateless",true); // ### // r->setInterfaceStr("nil"); tmp_queue.push_back(r); /* TMP_CHAIN any any any any ACTION */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","3"); nsrv=r->getSrv(); nsrv->reset(); if (!shadowing_mode) { nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); nitf=r->getItf(); nitf->reset(); if ( (nint=r->getWhen())!=NULL ) nint->reset(); } r->setStr("ipt_chain",new_chain); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); r->setBool("upstream_rule_neg",true); if ( ! rule->getStr("ipt_target").empty() ) r->setStr("ipt_target",rule->getStr("ipt_target")); // r->setInterfaceStr("nil"); r->setBool("final",true); ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); // ### tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::TimeNegation::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); string afpa = ruleopt->getStr("firewall_is_part_of_any_and_networks"); RuleElementInterval *intrel=rule->getWhen(); /* A B C !D ACTION */ if (intrel!=NULL && intrel->getNeg()) { PolicyRule *r; RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; RuleElementInterval *nint; RuleElementItf *nitf; FWOptions *ruleopt; /*chain could have been assigned if we split this rule before */ string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewTmpChainName(rule); intrel->setNeg(false); rule->setBool("upstream_rule_neg",true); /* A B C any TMP_CHAIN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","1"); if ( (nint=r->getWhen())!=NULL ) nint->reset(); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_target",new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setStr("firewall_is_part_of_any_and_networks", afpa); tmp_queue.push_back(r); /* TMP_CHAIN any any any D RETURN */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","2"); if (!shadowing_mode) { nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); nsrv=r->getSrv(); nsrv->reset(); nitf=r->getItf(); nitf->reset(); } r->setAction( PolicyRule::Return ); r->setClassification(false); r->setRouting(false); r->setTagging(false); r->setLogging(false); r->setStr("ipt_chain",new_chain); r->setStr("ipt_target",""); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); ruleopt =r->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); ruleopt->setBool("stateless",true); // ### // r->setInterfaceStr("nil"); tmp_queue.push_back(r); /* TMP_CHAIN any any any any ACTION */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("subrule_suffix","3"); if ( (nint=r->getWhen())!=NULL ) nint->reset(); if (!shadowing_mode) { nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); nsrv=r->getSrv(); nsrv->reset(); nitf=r->getItf(); nitf->reset(); /* * special case: need to preserve information about service protocol in case * action_on_reject is TCP RST */ nsrv=r->getSrv(); Service *srv= compiler->getFirstSrv(r); if (TCPService::isA(srv)) { nsrv->clearChildren(); nsrv->addRef(compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(ANY_TCP_OBJ_ID))); } else { nsrv->reset(); } } r->setStr("ipt_chain",new_chain); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); if ( ! rule->getStr("ipt_target").empty() ) r->setStr("ipt_target",rule->getStr("ipt_target")); // r->setInterfaceStr("nil"); r->setBool("final",true); ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); // ### tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::InterfaceAndDirection::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementItf *itfre = rule->getItf(); assert(itfre); if (rule->getDirection()==PolicyRule::Undefined) rule->setDirection( PolicyRule::Both ); if (itfre->isAny() && rule->getDirection()==PolicyRule::Both) { rule->setStr(".iface", "nil"); //rule->setInterfaceStr("nil"); return true; } if (itfre->isAny() && ( rule->getDirection()==PolicyRule::Inbound || rule->getDirection()==PolicyRule::Outbound )) { itfre->addRef(ipt_comp->regular_interfaces["*"]); //rule->setInterfaceStr("*"); return true; } return true; } bool PolicyCompiler_ipt::setChainPreroutingForTag::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; /* * About setting chain for rules with action Tag * * We tag in chains OUTPUT and PREROUTING. Here is why we need * OUTPUT: packets that originate on the firewall should be marked * in OUTPUT chain rather than in POSTROUTING because NAT * rerouting happens after OUTPUT hook but before POSTROUTING * hook. See diagram at * http://www.shorewall.net/NetfilterOverview.html * * Packet that traverse the firewall will be marked in PREROUTING * giving us a chance to match them later in other chains. * * Rule is split by the normal splitIfSrcAny rule processor if src * is any or chain is set to OUTPUT if src matches fw. In case * rule is split, the second copy won't have chain set when this * rule processor is called so it will place it in PREROUTING. * * This means this processor must be called after splitIfSrcAny but * before splitIfDstAny * * Chain is set by the rule processor setChainForMangle for all * rules in the table mangle if direction is set to Inbound or * Outbound */ /* * set chain to PREROUTING if this is (was) a Tag rule, chain has * not been assigned yet, direction is Both and there is no * interface. */ RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); if ( (rule->getTagging() || rule->getBool("originated_from_a_rule_with_tagging")) && rule->getStr("ipt_chain").empty() && (rule->getDirection()==PolicyRule::Both || rule->getDirection()==PolicyRule::Inbound) && itf_re->isAny()) { ipt_comp->setChain(rule, "PREROUTING"); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::setChainPostroutingForTag::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); if ( (rule->getTagging() || rule->getBool("originated_from_a_rule_with_tagging")) && rule->getStr("ipt_chain").empty() && (rule->getDirection()==PolicyRule::Both || rule->getDirection()==PolicyRule::Outbound) && itf_re->isAny()) ipt_comp->setChain(rule, "POSTROUTING"); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::checkForRestoreMarkInOutput::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); if ( (rule->getTagging() || rule->getBool("originated_from_a_rule_with_tagging")) && ruleopt->getBool("ipt_mark_connections") && rule->getStr("ipt_chain")=="OUTPUT") ipt_comp->have_connmark_in_output = true; tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::setChainForMangle::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (ipt_comp->my_table=="mangle" && rule->getStr("ipt_chain").empty()) { if (rule->getDirection()==PolicyRule::Inbound) ipt_comp->setChain(rule, "PREROUTING"); if (rule->getDirection()==PolicyRule::Outbound) ipt_comp->setChain(rule, "POSTROUTING"); /* if direction is "Outbound", chain can never be INPUT, but could be FORWARD */ RuleElementSrc *srcrel = rule->getSrc(); Address *src = compiler->getFirstSrc(rule); assert(src); if ( rule->getDirection()!=PolicyRule::Inbound && !srcrel->isAny() && compiler->complexMatch(src,compiler->fw,true,true)) { ipt_comp->setChain(rule, "OUTPUT"); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfTagAndConnmark::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); FWOptions *ruleopt = rule->getOptionsObject(); if (rule->getTagging() && ruleopt->getBool("ipt_mark_connections")) { tmp_queue.push_back(rule); PolicyRule *r1 = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r1); r1->duplicate(rule); r1->setStr("ipt_target", "CONNMARK"); r1->setAction(PolicyRule::Continue); // ### r1->setClassification(false); r1->setRouting(false); r1->setTagging(false); r1->setLogging(false); ruleopt = r1->getOptionsObject(); ruleopt->setStr("CONNMARK_arg", "--save-mark"); tmp_queue.push_back(r1); ipt_comp->have_connmark = true; } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfIfaceAndDirectionBoth::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementItf *itfre=rule->getItf(); assert(itfre); if ( !itfre->isAny() && rule->getDirection()==PolicyRule::Both) { PolicyRule *r; // If this rule has been assigned to chain POSTROUTING, // direction 'inbound' does not make sense for it. if (rule->getStr("ipt_chain") != "POSTROUTING") { r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection( PolicyRule::Inbound ); tmp_queue.push_back(r); } // If this rule has been assigned to chain PREROUTING, // direction 'Outbound' does not make sense for it. if (rule->getStr("ipt_chain") != "PREROUTING") { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection( PolicyRule::Outbound ); tmp_queue.push_back(r); } } else tmp_queue.push_back(rule); return true; } /* * Check if ip address of the object passed as argument "addr" matches * broadcast address defined by an address/mask of one of the * interfaces of the firewall or is a broadcast or multicast address * itself, such as 255.255.255.255. */ bool PolicyCompiler_ipt::bridgingFw::checkForMatchingBroadcastAndMulticast( Address *addr) { // addr can be interface, in which case it does not own ip address // and can not match broadcast or multicast if (!addr->hasInetAddress()) return false; const InetAddr *obj1_addr = addr->getAddressPtr(); if (!obj1_addr->isAny() && (obj1_addr->isBroadcast() || obj1_addr->isMulticast()) ) return true; FWObjectTypedChildIterator j= compiler->fw->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *iface = Interface::cast(*j); if ( iface->isRegular() ) { FWObjectTypedChildIterator k = iface->findByType(IPv4::TYPENAME); for ( ; k!=k.end(); ++k ) { //const InetAddrMask *ipv4 = Address::cast(*k)->getAddressObjectInetAddrMask(); Address *addr = Address::cast(*k); const InetAddr *ip_netm = addr->getNetmaskPtr(); const InetAddr *ip_net_addr = addr->getNetworkAddressPtr(); const InetAddr *ip_bcast_addr = addr->getBroadcastAddressPtr(); /* * bug #780345: if interface has netmask 255.255.255.255, its own * address will be detected as broadcast. Of course interface address * should not be created with netmask 255.255.255.255, but even if it * is, we should not interpret its own address as a broadcast, so we * should just skip it here. Typical case when this happens is the * rule that uses firewall's interface in dst. If we compare an addres * found in dst against combination addr/netmask of the same * interface, and the netmask is 255.255.255.255, then we get positive * match because this routine interprets this address as a broadcast. */ if (ip_netm->isHostMask()) continue; /* * commented out to fix bug #637694 - "bridge enbaled / management" * Rule where firewall was in destination, and bridging option was on, * yielded code in FORWARD chain when this line was uncommented. if ( ipv4->getAddress()==obj1_addr ) return true; */ if (*ip_net_addr == *obj1_addr) return true; if (*ip_bcast_addr == *obj1_addr) return true; } } } return false; } /* * call this after splitIfSrcMatchesFw and splitIfDstMatchesFw so that * we can count on firewall or broadcast/multicast being a single * object in src and dst. */ bool PolicyCompiler_ipt::bridgingFw::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; // Address *src=compiler->getFirstSrc(rule); Address *dst = compiler->getFirstDst(rule); if ( rule->getStr("ipt_chain")=="INPUT" ) { if ( checkForMatchingBroadcastAndMulticast(dst) ) { /* bug #1101910: "Samba problem with Bridged Firewall" need to split * rule to take care of broadcasts forwarded by the bridge, as well as * broadcasts that are accepted by the firewall itself. Need to do * this only if the rule is not associated with any bridging * interfaces */ RuleElementItf *itfre = rule->getItf(); assert(itfre); RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); Interface *rule_iface = Interface::cast(FWObjectReference::getObject(itf_re->front())); // Interface *rule_iface = Interface::cast( // compiler->dbcopy->findInIndex(rule->getInterfaceId())); if (rule_iface!=NULL && (rule_iface->isUnnumbered() || rule_iface->isBridgePort() )) { ipt_comp->setChain(rule, "FORWARD"); } else { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r, "FORWARD"); tmp_queue.push_back(r); } } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfSrcNegAndFw::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( ! rule->getStr("ipt_chain").empty() ) { tmp_queue.push_back(rule); return true; } RuleElementSrc *srcrel=rule->getSrc(); RuleElementSrc *nsrc; // Address *src=compiler->getFirstSrc(rule); /* if there is negation in SRC, then we need to split the rule based on what * first rule generated as the result of processing negation would be: any B C TMP_CHAIN in this case SRC will become Any even if it is not in the original rule. That is, we should split if srcrel is 'any' OR if it has negation. To avoid extra complexity in the generated code, this processor does it only if src contains more than 1 object and one of these objects is firewall. This is the only case when we need to split before processing negation. All other "normal" cases are handled by splitIfSrcAny */ list fwLikes; list notFwLikes; if (rule->getDirection()!=PolicyRule::Inbound && srcrel->getNeg()) { for (list::iterator i1=srcrel->begin(); i1!=srcrel->end(); ++i1) { FWObject *o = *i1; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *a = Address::cast(o); if (a && compiler->complexMatch(a,compiler->fw)) fwLikes.push_back(o); else notFwLikes.push_back(o); } if (fwLikes.size() != 0) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"OUTPUT"); r->setDirection( PolicyRule::Outbound ); nsrc=r->getSrc(); nsrc->clearChildren(); for (list::iterator m=fwLikes.begin(); m!=fwLikes.end(); ++m) nsrc->addRef(*m); tmp_queue.push_back(r); // rule->setStr("ipt_chain","FORWARD"); nsrc=rule->getSrc(); nsrc->reset(); // resets negation flag for (list::iterator m=notFwLikes.begin(); m!=notFwLikes.end(); ++m) nsrc->addRef(*m); if (!nsrc->isAny()) nsrc->setNeg(true); FWOptions *ruleopt = rule->getOptionsObject(); // so we do not put this rule in OUTPUT chain later ruleopt->setBool("no_output_chain",true); tmp_queue.push_back(rule); return true; } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfDstNegAndFw::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( ! rule->getStr("ipt_chain").empty() ) { tmp_queue.push_back(rule); return true; } RuleElementDst *dstrel=rule->getDst(); RuleElementDst *ndst; // Address *dst=compiler->getFirstDst(rule); /* if there is negation in DST, then we need to split the rule based on what * first rule generated as the result of processing negation would be: A any C TMP_CHAIN in this case DST will become Any even if it is not in the original rule. That is, we should split if dstrel is 'any' OR if it has negation. To avoid extra complexity in the generated code, this processor does it only if dst contains more than 1 object and one of these objects is firewall. This is the only case when we need to split before processing negation. All other "normal" cases are handled by splitIfDstAny */ list fwLikes; list notFwLikes; if (rule->getDirection()!=PolicyRule::Outbound && dstrel->getNeg()) { for (list::iterator i1=dstrel->begin(); i1!=dstrel->end(); ++i1) { FWObject *o = *i1; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *a = Address::cast(o); if (a && compiler->complexMatch(a,compiler->fw)) fwLikes.push_back(o); else notFwLikes.push_back(o); } if (fwLikes.size() != 0) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"INPUT"); r->setDirection( PolicyRule::Inbound ); ndst=r->getDst(); ndst->clearChildren(); for (list::iterator m=fwLikes.begin(); m!=fwLikes.end(); ++m) ndst->addRef(*m); tmp_queue.push_back(r); // the second rule goes into FORWARD chain, but if source // is (or contains) firewall, we may also need OUTPUT chain // rule->setStr("ipt_chain","FORWARD"); ndst=rule->getDst(); ndst->reset(); // resets negation flag for (list::iterator m=notFwLikes.begin(); m!=notFwLikes.end(); ++m) ndst->addRef(*m); if (!ndst->isAny()) ndst->setNeg(true); FWOptions *ruleopt = rule->getOptionsObject(); // so we do not put this rule in INPUT chain later ruleopt->setBool("no_input_chain",true); tmp_queue.push_back(rule); return true; } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfSrcAny::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); FWOptions *fwopt = compiler->getCachedFwOpt(); /* commented to fix bug #1112470 * if fw is considered part of any, we should place rule in INPUT/OUTPUT * chains even if it is a bridging fw since fw itself may send or receive * packets */ if ( /* fwopt->getBool("bridging_fw") || */ ruleopt->getInt("firewall_is_part_of_any_and_networks")==0 || ruleopt->getBool("no_output_chain")) { tmp_queue.push_back(rule); return true; } /* See #2008. It appears "--physdev-out" is not allowed in OUTPUT * chain. */ RuleElementItf *itfre = rule->getItf(); assert(itfre); Interface *itf = compiler->getFirstItf(rule); if (fwopt->getBool("bridging_fw") && itf && itf->isBridgePort()) { tmp_queue.push_back(rule); return true; } if ( ! rule->getStr("ipt_chain").empty() ) { tmp_queue.push_back(rule); return true; } RuleElementSrc *srcrel = rule->getSrc(); Address *src = compiler->getFirstSrc(rule); if ( rule->getDirection()!=PolicyRule::Inbound && ( srcrel->isAny() || ( srcrel->size()==1 && src!=NULL && !compiler->complexMatch(src,compiler->fw) && srcrel->getBool("single_object_negation")) ) ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"OUTPUT"); r->setDirection( PolicyRule::Outbound ); tmp_queue.push_back(r); /* * A note about CLASSIFY target in iptables: * * CLASSIFY only works in mangle table in POSTROUTING chain. * the man page does not mention this, but module * documentation in p-o-m says so. */ if (ipt_comp->my_table=="mangle" && rule->getClassification()) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"POSTROUTING"); r->setDirection( PolicyRule::Outbound ); tmp_queue.push_back(r); } } tmp_queue.push_back(rule); // add old rule anyway return true; } bool PolicyCompiler_ipt::splitIfDstAny::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; // FWOptions *fwopt = compiler->getCachedFwOpt(); FWOptions *ruleopt = rule->getOptionsObject(); /* commented to fix bug #1112470 * if fw is considered part of any, we should place rule in INPUT/OUTPUT * chains even if it is a bridging fw since fw itself may send or receive * packets */ if ( /* fwopt->getBool("bridging_fw") || */ ruleopt->getInt("firewall_is_part_of_any_and_networks")==0 || ruleopt->getBool("no_input_chain")) { tmp_queue.push_back(rule); return true; } if ( ! rule->getStr("ipt_chain").empty() ) { tmp_queue.push_back(rule); return true; } RuleElementDst *dstrel = rule->getDst(); Address *dst = compiler->getFirstDst(rule); if ( rule->getDirection()!=PolicyRule::Outbound && ( dstrel->isAny() || ( dstrel->size()==1 && dst!=NULL && !compiler->complexMatch(dst,compiler->fw) && dstrel->getBool("single_object_negation")) ) ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"INPUT"); r->setDirection( PolicyRule::Inbound ); tmp_queue.push_back(r); // if this rule is for mangle table, need to put it into // POSTROUTING chain as well because some targets that // work with mangle table can only go into POSTROUTING chain // such as CLASSIFY if (ipt_comp->my_table=="mangle" && rule->getClassification()) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"PREROUTING"); r->setDirection( PolicyRule::Inbound ); tmp_queue.push_back(r); } } tmp_queue.push_back(rule); // add old rule in any case return true; } /** * If rule element RE (Src or Dst) has an AddressRange object that * represents single address, replace it with corresponding IPv4 * object. Call this rule processor before splitIfSrcMatchingAddressRange * * #2650 */ bool PolicyCompiler_ipt::specialCaseAddressRangeInRE::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; list new_children; RuleElement *rel = RuleElement::cast( rule->getFirstByType(re_type) ); for (list::iterator i1=rel->begin(); i1!=rel->end(); ++i1) { Address *addr_obj = Address::cast(FWReference::getObject(*i1)); if (addr_obj == NULL) continue; /* * commented out for SF bug 3468358 * Why did I need to replace cluster interface with member interface if * addresses of interfaces can not be AddressRange objects ? * Address *addr_obj = compiler->correctForCluster(Address::cast(obj)); */ if (addr_obj && !addr_obj->isAny() && AddressRange::isA(addr_obj) && addr_obj->dimension() == 1) { Address *new_addr = compiler->dbcopy->createIPv4(); new_addr->setName(addr_obj->getName() + "_addr"); new_addr->setAddress(AddressRange::cast(addr_obj)->getRangeStart()); new_addr->setNetmask(InetAddr(InetAddr::getAllOnes())); compiler->persistent_objects->add(new_addr); new_children.push_back(new_addr); } else new_children.push_back(addr_obj); } if (new_children.size() > 0) { rel->clearChildren(); for (list::iterator i1=new_children.begin(); i1!=new_children.end(); ++i1) { rel->addRef(*i1); } } tmp_queue.push_back(rule); // add old rule in any case return true; } /** * Split rule if src has addressRange object that matches the * firewall. If some addresses inside the range match the firewall, * while others dont, the rule must be placed in both OUTPUT and * FORWARD chains. * * #2650 */ bool PolicyCompiler_ipt::splitIfSrcMatchingAddressRange::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; Address *src = compiler->correctForCluster(compiler->getFirstSrc(rule)); bool b, m; b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") ); /* * directions outbound or both: if src is an address range that * matches fw, we should split the rule to make sure we match both * in OUTPUT and FORWARD */ if ( rule->getDirection() != PolicyRule::Inbound && src && !src->isAny() && AddressRange::isA(src) && ipt_comp->complexMatch(src, ipt_comp->fw, b, m)) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r, "OUTPUT"); r->setDirection( PolicyRule::Outbound ); tmp_queue.push_back(r); } tmp_queue.push_back(rule); return true; } /** * Split rule if dst has addressRange object that matches the * firewall. If some addresses inside the range match the firewall, * while others dont, the rule must be placed in both INPUT and * FORWARD chains. * * #2650 */ bool PolicyCompiler_ipt::splitIfDstMatchingAddressRange::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; Address *dst = compiler->correctForCluster(compiler->getFirstDst(rule)); bool b, m; b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") ); /* * directions inbound or both: if src is an address range that * matches fw, we should split the rule to make sure we match both * in INPUT and FORWARD */ if ( rule->getDirection() != PolicyRule::Outbound && dst && !dst->isAny() && AddressRange::isA(dst) && ipt_comp->complexMatch(dst, ipt_comp->fw, b, m)) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r, "INPUT"); r->setDirection( PolicyRule::Inbound ); tmp_queue.push_back(r); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfSrcAnyForShadowing::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getClassification()) { tmp_queue.push_back(rule); return true; } RuleElementSrc *srcrel=rule->getSrc(); FWOptions *ruleopt = rule->getOptionsObject(); if ( ruleopt->getInt("firewall_is_part_of_any_and_networks")==1 && !ruleopt->getBool("no_output_chain") && rule->getDirection()!=PolicyRule::Inbound && srcrel->isAny() ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"OUTPUT"); r->setDirection( PolicyRule::Outbound ); RuleElementSrc *nsrcrel=r->getSrc(); nsrcrel->addRef(compiler->fw); tmp_queue.push_back(r); } tmp_queue.push_back(rule); // add old rule anyway return true; } bool PolicyCompiler_ipt::splitIfDstAnyForShadowing::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getClassification()) { tmp_queue.push_back(rule); return true; } RuleElementDst *dstrel=rule->getDst(); FWOptions *ruleopt = rule->getOptionsObject(); if ( ruleopt->getInt("firewall_is_part_of_any_and_networks")==1 && !ruleopt->getBool("no_input_chain") && rule->getDirection()!=PolicyRule::Outbound && dstrel->isAny() ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"INPUT"); r->setDirection( PolicyRule::Inbound ); RuleElementDst *ndstrel=r->getDst(); ndstrel->addRef(compiler->fw); tmp_queue.push_back(r); } tmp_queue.push_back(rule); // add old rule anyway return true; } bool PolicyCompiler_ipt::splitIfSrcFWNetwork::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getClassification()) { tmp_queue.push_back(rule); return true; } RuleElementSrc *srcrel=rule->getSrc(); FWOptions *fwopt = compiler->getCachedFwOpt(); FWOptions *ruleopt = rule->getOptionsObject(); if ( fwopt->getBool("bridging_fw") || ruleopt->getInt("firewall_is_part_of_any_and_networks")==0 || ruleopt->getBool("no_output_chain")) { tmp_queue.push_back(rule); return true; } if ( ! rule->getStr("ipt_chain").empty() || srcrel->isAny() ) { tmp_queue.push_back(rule); return true; } if (rule->getDirection()!=PolicyRule::Inbound) { std::map obj_subst; for (list::iterator i1=srcrel->begin(); i1!=srcrel->end(); ++i1) { FWObject *o = *i1; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *a = Address::cast(o); FWObject *na; if ((Network::isA(o) || NetworkIPv6::isA(o)) && (na=compiler->findAddressFor(a, compiler->fw ))!=NULL) { obj_subst[a]=na; } } if ( ! obj_subst.empty() ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"OUTPUT"); r->setDirection( PolicyRule::Outbound ); #if 0 /* I can't decide right now if I should replace network objects with firewall's addresses. I am going not to replace them for now */ RuleElementSrc *nsrcrel=r->getSrc(); for (std::map::iterator i=obj_subst.begin(); i!=obj_subst.end(); i++) { nsrcrel->removeRef( i->first ); nsrcrel->addRef( i->second ); } #endif tmp_queue.push_back(r); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitIfDstFWNetwork::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getClassification()) { tmp_queue.push_back(rule); return true; } RuleElementDst *dstrel=rule->getDst(); FWOptions *fwopt = compiler->getCachedFwOpt(); FWOptions *ruleopt = rule->getOptionsObject(); if ( fwopt->getBool("bridging_fw") || ruleopt->getInt("firewall_is_part_of_any_and_networks")==0 || ruleopt->getBool("no_input_chain")) { tmp_queue.push_back(rule); return true; } if ( ! rule->getStr("ipt_chain").empty() || dstrel->isAny() ) { tmp_queue.push_back(rule); return true; } if (rule->getDirection()!=PolicyRule::Outbound) { std::map obj_subst; for (list::iterator i1=dstrel->begin(); i1!=dstrel->end(); ++i1) { FWObject *o = *i1; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *a = Address::cast(o); FWObject *na; if ((Network::isA(a) || NetworkIPv6::isA(a)) && (na=compiler->findAddressFor(a, compiler->fw))!=NULL) { obj_subst[a]=na; } } if ( ! obj_subst.empty() ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"INPUT"); r->setDirection( PolicyRule::Inbound ); #if 0 /* I can't decide right now if I should replace network objects with firewall's addresses. I am going not to replace them for now */ RuleElementDst *ndstrel=r->getDst(); for (std::map::iterator i=obj_subst.begin(); i!=obj_subst.end(); i++) { ndstrel->removeRef( i->first ); ndstrel->addRef( i->second ); } #endif tmp_queue.push_back(r); } } tmp_queue.push_back(rule); return true; } /* * predicates that run before guarantee that when we call this one, * firewall object, if it is in src or dst, is single object there */ bool PolicyCompiler_ipt::checkSrcAndDst1::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; Address *src = compiler->getFirstSrc(rule); assert(src); Address *dst = compiler->getFirstDst(rule); assert(dst); if (!compiler->isFirewallOrCluster(src) && compiler->isFirewallOrCluster(dst) && rule->getDirection()==PolicyRule::Outbound ) { compiler->abort( rule, "direction can not be outbound when destination is firewall"); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::checkSrcAndDst2::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; Address *src = compiler->getFirstSrc(rule); assert(src); Address *dst = compiler->getFirstDst(rule); assert(dst); if (compiler->isFirewallOrCluster(src) && !compiler->isFirewallOrCluster(dst) && rule->getDirection()==PolicyRule::Inbound ) { compiler->abort( rule, "direction can not be inbound when source is firewall"); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::specialCaseWithFW1::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getClassification()) { tmp_queue.push_back(rule); return true; } // RuleElementSrc *srcrel=rule->getSrc(); Address *src = compiler->getFirstSrc(rule); if(src==NULL) compiler->abort(rule, "Broken SRC "); // RuleElementDst *dstrel=rule->getDst(); Address *dst = compiler->getFirstDst(rule); if(dst==NULL) compiler->abort(rule, "Broken DST"); if (!src->isAny() && !dst->isAny() && compiler->complexMatch(src,compiler->fw) && compiler->complexMatch(dst,compiler->fw) && rule->getDirection()== PolicyRule::Both ) { PolicyRule *r; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection( PolicyRule::Inbound ); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection( PolicyRule::Outbound ); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::specialCaseWithFWInDstAndOutbound::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; Interface *itf = compiler->getFirstItf(rule); // note: itf can be NULL if object in this rule element is a group RuleElementSrc *srcrel = rule->getSrc(); Address *src =compiler->getFirstSrc(rule); Address *dst =compiler->getFirstDst(rule); string chain = rule->getStr("ipt_chain"); if (rule->getDirection()== PolicyRule::Outbound && itf!=NULL && itf->isChildOf(compiler->fw) && chain!="OUTPUT") { // If dst is broadcast, drop the rule if this is not bridging // fw. Bridging fw can forward broadcasts, so a rule with // this address in destination, direction Outbound and // non-empty interface is legit FWOptions *fwopt = compiler->getCachedFwOpt(); const InetAddr *dst_addr = dst->getAddressPtr(); if (dst_addr && (dst_addr->isBroadcast() || dst_addr->isMulticast()) && fwopt->getBool("bridging_fw")) { tmp_queue.push_back(rule); return true; } // if src does not match fw and dst matches firewall, skip the // rule. The idea is that if src does not match fw, such // packet can only be forwarded by the firewall. If dst // matches firewall, it would go into INPUT chain and would // not be forwarded, so it can't cross interface in outbound // direction and the rule would never see this packet. If src // matches the firewall, the packet might be generated by it // and can cross interface in outbound direction, so the rule // must be preserved. // Also, if src is negated, the rule must be preserved too. if (srcrel->getNeg() || srcrel->getBool("single_object_negation")) { tmp_queue.push_back(rule); return true; } FWOptions *ruleopt = rule->getOptionsObject(); bool rule_afpa = ruleopt->getBool("firewall_is_part_of_any_and_networks"); bool src_matches = compiler->complexMatch(src, compiler->fw); bool dst_matches = compiler->complexMatch(dst, compiler->fw); // if "assume fw is part of any and networks" is turned off, // do not consider network objects matching. Except when such // network has netmask 255.255.255.255 and defines just a // single address if ((src->isAny() || Network::isA(src) || NetworkIPv6::isA(src)) && !rule_afpa && ! src->getNetmaskPtr()->isHostMask()) src_matches = false; if ((dst->isAny() || Network::isA(dst) || NetworkIPv6::isA(dst)) && !rule_afpa && ! dst->getNetmaskPtr()->isHostMask()) dst_matches = false; // there is still one case that this rule processor catches // and drop the rule, but I am not sure if it is right thing // to do. This is when src=some address on the subnet fw // intrface is on, but not the address of the firewall, // dst=broadcast or multicast, "assume fw is part of any" is // turned on, the firewall is not a bridge. A rule like this // passes all checks above and gets dropped by this rule // processor. It is hard ot say what should we really do in // this case. if (!src_matches && dst_matches) { // src does not match, dst matches: skipping the rule return true; } tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } /* * this is basically the same as ExpandMultipleAddresses except it * does not skip loopback */ bool PolicyCompiler_ipt::specialCaseWithFW2::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); Address *src =compiler->getFirstSrc(rule); RuleElementDst *dstrel=rule->getDst(); Address *dst =compiler->getFirstDst(rule); if (src->getId()==compiler->fw->getId() && dst->getId()==compiler->fw->getId() ) { srcrel->reset(); dstrel->reset(); list all_addresses; FWObjectTypedChildIterator i=compiler->fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface=Interface::cast(*i); if ( iface->isUnnumbered() || iface->isBridgePort() ) continue; FWObjectTypedChildIterator j=iface->findByType(IPv4::TYPENAME); for ( ; j!=j.end(); ++j ) all_addresses.push_back( *j); } for (list::iterator i=all_addresses.begin(); i!=all_addresses.end(); ++i) { srcrel->addRef(*i); dstrel->addRef(*i); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::specialCaseWithUnnumberedInterface::dropUnnumberedInterface(RuleElement *re) { if (re->isAny()) return true; list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs =Interface::cast( obj ); if (ifs!=NULL && (ifs->isUnnumbered() || ifs->isBridgePort())) cl.push_back(obj); } if (!cl.empty()) { for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->removeRef( (*i1) ); } return (!re->isAny() ); } /** * checks for the following situations: * * 1. unnumbered interface is in source and direction is inbound * (drop interface from src since source address is * undertermined) * * 2. unnumbered interface is in source, direction is outbound * and chain is temporary (drop interface from the list, this * rule has been created while processing negation. TODO: this * is kludge, need to create separate temporary chain while * doing negation in src if one of the objects is firewall) * * 3. unnumbered interface is in destination and chain is "OUTPUT" * (drop interface since dest. address is undefined) * * */ bool PolicyCompiler_ipt::specialCaseWithUnnumberedInterface::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; bool keep_rule=true; switch ( rule->getDirection() ) { case PolicyRule::Inbound: keep_rule=dropUnnumberedInterface( rule->getSrc() ); break; case PolicyRule::Outbound: if ( rule->getStr("ipt_chain")=="OUTPUT" ) keep_rule=dropUnnumberedInterface( rule->getDst() ); else keep_rule=dropUnnumberedInterface( rule->getSrc() ); break; default: ; } if (keep_rule) tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::checkForDynamicInterfacesOfOtherObjects::findDynamicInterfaces( RuleElement *re, Rule *rule) { if (re->isAny()) return true; list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs = Interface::cast( obj ); if (ifs != NULL && ifs->isDyn()) { if ( ! ifs->isChildOf(compiler->fw)) { // If this is dynamic failover interface, look at // corresponding member interface. If we can find one, // it is ok. Otherwise it is probably failover // interface of a cluster this firewall is not a // member of. if (ifs->isFailoverInterface()) { FailoverClusterGroup *fg = FailoverClusterGroup::cast( ifs->getFirstByType(FailoverClusterGroup::TYPENAME)); if (fg && fg->getInterfaceForMemberFirewall(compiler->fw)!=NULL) continue; } QString err( "Can not build rule using dynamic interface '%1' " "of the object '%2' because its address in unknown."); compiler->abort( rule, err .arg(ifs->getName().c_str()) .arg(ifs->getParent()->getName().c_str()).toStdString()); return false; } } } return true; } bool PolicyCompiler_ipt::checkForDynamicInterfacesOfOtherObjects::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (findDynamicInterfaces( rule->getSrc() , rule ) && findDynamicInterfaces( rule->getDst() , rule )) tmp_queue.push_back(rule); return true; } /* * remember, behavior of this processor has been changed in virtual * method _expand_interface */ bool PolicyCompiler_ipt::expandMultipleAddressesIfNotFWinSrc::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel = rule->getSrc(); Address *src =compiler->getFirstSrc(rule); assert(src); if (Firewall::cast(src)==NULL) compiler->_expand_addr(rule, srcrel, true); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::expandMultipleAddressesIfNotFWinDst::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementDst *dstrel=rule->getDst(); Address *dst =compiler->getFirstDst(rule); assert(dst); if (Firewall::cast(dst)==NULL) compiler->_expand_addr(rule, dstrel, true); tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipt::expandLoopbackInterfaceAddress::replaceLoopbackWithItsAddress( RuleElement *rel, Rule *rule) { if (rel->isAny()) return; list cl; for (list::iterator i1=rel->begin(); i1!=rel->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); if (Interface::cast(obj)!=NULL && Interface::cast(obj)->isLoopback()) { FWObject *addr = obj->getFirstByType(IPv4::TYPENAME); if (addr==NULL) compiler->abort( rule, "Loopback interface of the firewall object does not " "have IP address but is used in the rule"); rel->removeRef(obj); rel->addRef(addr); break; // I guess there can be only one loopback object in the rule, right ? } } } bool PolicyCompiler_ipt::expandLoopbackInterfaceAddress::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); replaceLoopbackWithItsAddress(srcrel,rule); replaceLoopbackWithItsAddress(dstrel,rule); tmp_queue.push_back(rule); return true; } /* * This processor sets chain only if it is INPUT or OUTPUT. We will * look at the rule if it goes into FORWARD chain in * splitIfSrcFWNetwork / splitIfDstFWNetwork and possibly split it. We will * set chain to FORWARD after that in decideOnChain */ bool PolicyCompiler_ipt::decideOnChainIfSrcFW::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( ! rule->getStr("ipt_chain").empty() || rule->getClassification()) { tmp_queue.push_back(rule); return true; } #ifdef DEBUG_FOR_DMZ cerr << endl; cerr << "PolicyCompiler_ipt::decideOnChainIfSrcFW " << " rule " << rule->getLabel() << endl; #endif Address *src = compiler->correctForCluster(compiler->getFirstSrc(rule)); assert(src); /* Bug 811860: "IPTables Compiler Firewall IP to Input Chain". * on a bridging firewall rules not associated with interfaces should * go into INPUT/OUTPUT chain on interfaces that do routing and into * FORWARD chain on bridging interfaces. Sometimes bridging interfaces * are not created in the GUI, so to play it safe we will split the * rule and put it into both FORWARD and INPUT/OUTPUT chain. * * Bug #934949: "duplicate rules". Split the rule only if firewall is * in src or dst. Otherwise compiler produces duplicates. * */ if ( compiler->getCachedFwOpt()->getBool("bridging_fw") && compiler->complexMatch(src, compiler->fw, false, false) ) { /* Correction for bug #1231 : as of fwbuilder v4.0 (and * really, probably as of 3.0), bridge ports must be created * in the GUI for the compiler to process policy of the * bridging firewall correctly. Will split the rule if it is * not associated with any particular interface or associated * with an interface which is a bridge port. */ Interface *rule_iface = compiler->getFirstItf(rule); if (rule_iface == NULL || rule_iface->isBridgePort()) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"FORWARD"); tmp_queue.push_back(r); } } bool b,m; /* * do not check for broadcasts and multicasts in bridging firewall because * they should go to FORWARD chain * * b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") ); * * * Commented out the line above while working on the bug #811860: * "IPTables Compiler Firewall IP to Input Chain". No need to do it * anymore since we now split the rule if we work with a bridging fw * and the rule _always_ goes into FORWARD chain --vk 09/28/03 */ b=m=true; switch ( rule->getDirection() ) { case PolicyRule::Outbound: /* if direction is "Outbound", chain can never be INPUT, but could be FORWARD */ if (! src->isAny() && ! AddressRange::isA(src) && // #2650 compiler->complexMatch(src, compiler->fw, b, m)) ipt_comp->setChain(rule,"OUTPUT"); break; case PolicyRule::Both: /* direction == Both */ if (! src->isAny() && ! AddressRange::isA(src) && // #2650 compiler->complexMatch(src, compiler->fw, b, m)) { ipt_comp->setChain(rule,"OUTPUT"); rule->setDirection( PolicyRule::Outbound ); } break; default: break; } tmp_queue.push_back(rule); return true; } /* * Call this processor before InterfacePolicyRulesWithOptimization */ bool PolicyCompiler_ipt::decideOnChainIfDstFW::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( ! rule->getStr("ipt_chain").empty() || rule->getClassification()) { tmp_queue.push_back(rule); return true; } Address *dst = compiler->correctForCluster(compiler->getFirstDst(rule)); assert(dst); /* * Note: dst can be cluster object but not necessarily the same cluster * that is being compiled. Check if compiler->fw is a member of this cluster. */ list cluster_members; if (Cluster::isA(dst)) Cluster::cast(dst)->getMembersList(cluster_members); /* Bug 811860: "IPTables Compiler Firewall IP to Input Chain". * on a bridging firewall rules not associated with interfaces should * go into INPUT/OUTPUT chain on interfaces that do routing and into * FORWARD chain on bridging interfaces. Sometimes bridging interfaces * are not created in the GUI, so to play it safe we will split the * rule and put it into both FORWARD and INPUT/OUTPUT chain. * * Bug #934949: "duplicate rules". Split the rule only if firewall is * in src or dst. Otherwise compiler produces duplicates. */ if ( compiler->getCachedFwOpt()->getBool("bridging_fw") && compiler->complexMatch(dst,compiler->fw,false,false) ) { /* Correction for bug #1231 : as of fwbuilder v4.0 (and * really, probably as of 3.0), bridge ports must be created * in the GUI for the compiler to process policy of the * bridging firewall correctly. Will split the rule if it is * not associated with any particular interface or associated * with an interface which is a bridge port. */ Interface *rule_iface = compiler->getFirstItf(rule); if (rule_iface == NULL || rule_iface->isBridgePort()) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ipt_comp->setChain(r,"FORWARD"); tmp_queue.push_back(r); } } bool b,m; /* * do not check for broadcasts and multicasts in bridging firewall because * they should go to FORWARD chain * * b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") ); * * * Commented out the line above while working on the bug #811860: * "IPTables Compiler Firewall IP to Input Chain". No need to do it * anymore since we now split the rule if we work with a bridging fw * and the rule _always_ goes into FORWARD chain --vk 09/28/03 */ b=m=true; switch ( rule->getDirection() ) { case PolicyRule::Inbound: /* if direction is "Inbound", chain can never be OUTPUT, but could be FORWARD */ if (! dst->isAny() && ! AddressRange::isA(dst) && // #2650 (compiler->complexMatch(dst,compiler->fw,b,m) || std::find(cluster_members.begin(), cluster_members.end(), compiler->fw) != cluster_members.end()) ) ipt_comp->setChain(rule,"INPUT"); break; case PolicyRule::Both: /* direction == Both */ if (! dst->isAny() && ! AddressRange::isA(dst) && // #2650 (compiler->complexMatch(dst,compiler->fw,b,m) || std::find(cluster_members.begin(), cluster_members.end(), compiler->fw) != cluster_members.end()) ) { ipt_comp->setChain(rule,"INPUT"); rule->setDirection(PolicyRule::Inbound); } break; default: break; } tmp_queue.push_back(rule); return true; } /* * processor splitIfIfaceAndDirectionBoth splits interface rule if its * direction is "Both". This means that by the time when this * processor is called, original rule "any any any accept both" on the * loopback interface has already been converted to two rules : * * any any any accept inbound * any any any accept outbound * * We do not have to split rule here, but rather just assign it to * INPUT/OUTPUT chains. * * We now call this rule processor after InterfacePolicyRulesWithOptimization * which means there is no more than one object in rule element 'Interface' */ bool PolicyCompiler_ipt::decideOnChainIfLoopback::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementItf *itfre=rule->getItf(); assert(itfre); assert(itfre->size()<=1); // sometimes for whatever reason itf rule element appears to be broken // (it is just empty, not even "any") if (itfre->size()==0) { tmp_queue.push_back(rule); return true; } Interface *rule_iface = compiler->getFirstItf(rule); RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); if (srcrel->isAny() && dstrel->isAny() && rule->getStr("ipt_chain").empty() && rule_iface!=NULL && rule_iface->isLoopback() ) { switch (rule->getDirection()) { case PolicyRule::Inbound: ipt_comp->setChain(rule,"INPUT"); break; case PolicyRule::Outbound: ipt_comp->setChain(rule,"OUTPUT"); break; default: ; } } tmp_queue.push_back(rule); return true; } /** * target CLASSIFY is only valid in mangle table, chain POSTROUTING. * However if the same rule also has tagging option, it should be * split because we want to tag in PREROUTING */ bool PolicyCompiler_ipt::decideOnChainForClassify::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( ! rule->getClassification()) { tmp_queue.push_back(rule); return true; } if (rule->getStr("ipt_chain").empty()) { if (rule->getTagging()) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setClassification(false); r->setRouting(false); r->setAction(PolicyRule::Continue); tmp_queue.push_back(r); rule->setTagging(false); } ipt_comp->setChain(rule, "POSTROUTING"); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::finalizeChain::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; // tmp_queue.push_back(rule); if ( ! rule->getStr("ipt_chain").empty() ) { tmp_queue.push_back(rule); return true; } ipt_comp->setChain(rule, "FORWARD"); if (ipt_comp->my_table=="mangle") { switch ( rule->getDirection() ) { case PolicyRule::Inbound: ipt_comp->setChain(rule,"PREROUTING"); break; case PolicyRule::Outbound: ipt_comp->setChain(rule,"POSTROUTING"); break; default: ipt_comp->setChain(rule,"FORWARD"); break; } if (rule->getAction() == PolicyRule::Accept) ipt_comp->setChain(rule,"PREROUTING"); } else { Address *src = compiler->correctForCluster(compiler->getFirstSrc(rule)); Address *dst = compiler->correctForCluster(compiler->getFirstDst(rule)); /* * Note that we deal with address ranges in splitIfSrcMatchingAddressRange and * splitIfDstMatchingAddressRange. At this point we treat ranges as always * not matching the firewall (so the go into FORWARD chain), except for ranges * that consist of 1 address. These should be treated as a single address. This * is for #2650 */ bool b,m; /* * do not check for broadcasts and multicasts in bridging firewall because * they should go to FORWARD chain */ b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") ); switch ( rule->getDirection() ) { case PolicyRule::Inbound: /* if direction is "Inbound", chain can never be OUTPUT, but could be FORWARD */ if (dst && !dst->isAny() && ! AddressRange::isA(dst) && // #2650 ipt_comp->complexMatch(dst, ipt_comp->fw, b, m)) { ipt_comp->setChain(rule,"INPUT"); } break; case PolicyRule::Outbound: /* if direction is "Outbound", chain can never be INPUT, but could be FORWARD */ if (src && !src->isAny() && ! AddressRange::isA(src) && // #2650 ipt_comp->complexMatch(src, ipt_comp->fw, b, m)) { ipt_comp->setChain(rule,"OUTPUT"); } break; default: /* direction == Both */ if (dst && !dst->isAny() && ! AddressRange::isA(dst) && // #2650 ipt_comp->complexMatch(dst, ipt_comp->fw, b, m)) { ipt_comp->setChain(rule,"INPUT"); break; } if (src && !src->isAny() && ! AddressRange::isA(src) && // #2650 ipt_comp->complexMatch(src, ipt_comp->fw, b, m)) { ipt_comp->setChain(rule,"OUTPUT"); break; } } } /* * bug #1040599: "unnecessary FORWARD rules". * If we haven't decided on INPUT/OUTPUT chain, it stays FORWARD. * However, if ip forwarding is turned off, we do not want any rules * in FORWARD chain, so we just drop it. * * If ip forwarding is set to "no change", assume it is on. */ bool ipforw = true; string ip_forward_option; if (ipt_comp->ipv6) ip_forward_option = compiler->getCachedFwOpt()->getStr("linux24_ipv6_forward"); else ip_forward_option = compiler->getCachedFwOpt()->getStr("linux24_ip_forward"); if (!ip_forward_option.empty() && (ip_forward_option=="0" || ip_forward_option=="Off" || ip_forward_option=="off")) ipforw = false; if (rule->getStr("ipt_chain")=="FORWARD" && !ipforw) return true; tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::decideOnTarget::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if ( ! rule->getStr("ipt_target").empty() ) return true; // already defined // note that we use pseudo-target for action Continue switch (rule->getAction()) { case PolicyRule::Accept: rule->setStr("ipt_target", "ACCEPT"); break; case PolicyRule::Deny: rule->setStr("ipt_target", "DROP"); break; case PolicyRule::Reject: rule->setStr("ipt_target", "REJECT"); break; case PolicyRule::Return: rule->setStr("ipt_target", "RETURN"); break; // case PolicyRule::Tag: rule->setStr("ipt_target", "MARK"); break; case PolicyRule::Pipe: rule->setStr("ipt_target", "QUEUE"); break; // case PolicyRule::Classify: rule->setStr("ipt_target", "CLASSIFY"); break; // case PolicyRule::Route: rule->setStr("ipt_target", "ROUTE"); break; case PolicyRule::Continue: rule->setStr("ipt_target", ".CONTINUE"); break; case PolicyRule::Custom: rule->setStr("ipt_target", ".CUSTOM"); break; case PolicyRule::Branch: { RuleSet *ruleset = rule->getBranch(); if (ruleset==NULL) compiler->abort( rule, string("Branching rule ") + rule->getLabel() + " refers ruleset that does not exist"); else rule->setStr("ipt_target", ruleset->getName()); break; } default: ; } return true; } /* * remove fw object from src or dst to simplify rules but only if: * * original rule did not have negation and * we do not add any virtual addresses for NAT. * * After removal the rule collapses to a simple command like this: * iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT * * this works fine except if we have added virtual addresses for * NAT. It is assumed that firewall object in rules represents * combination of addresses configured in its interfaces in the * GUI. Virtual addresses added for NAT are considered to be a side * effect and connections should not be implicitly permitted to them * by a rule with fw object in destination. The same applies to fw * object in source. See bug #685947 * * To avoid inadvertently opening holes in the firewall by a rule like * that, we remove fw object only when it is safe to do so. */ bool PolicyCompiler_ipt::removeFW::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (compiler->osconfigurator->getNumOfVirtualAddressesForNat()==0 && ! rule->getBool("upstream_rule_neg") ) { RuleElementSrc *srcrel = rule->getSrc(); Address *src = compiler->getFirstSrc(rule); if (src==NULL) { compiler->abort( rule, "removeFW: Empty Source rule element in rule"); return true; } RuleElementDst *dstrel = rule->getDst(); Address *dst = compiler->getFirstDst(rule); if (dst==NULL) { compiler->abort( rule, "removeFW: Empty Destination rule element in rule"); return true; } string chain = rule->getStr("ipt_chain"); if (( chain=="INPUT" || ipt_comp->isChainDescendantOfInput(chain)) && compiler->isFirewallOrCluster(dst)) { dstrel->reset(); } if (( chain=="OUTPUT" || ipt_comp->isChainDescendantOfOutput(chain)) && compiler->isFirewallOrCluster(src)) { srcrel->reset(); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::checkMACinOUTPUTChain::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( rule->getStr("ipt_chain")=="OUTPUT" ) { // RuleElementSrc *srcrel=rule->getSrc(); Address *src = compiler->getFirstSrc(rule); assert(src); if (physAddress::isA(src)) { compiler->abort( rule, "Can not match MAC address of the firewall"); return true; } if (combinedAddress::isA(src)) { compiler->warning( rule, "Can not match MAC address of the firewall " "(chain OUTPUT) "); combinedAddress::cast(src)->setPhysAddress(""); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::checkUserServiceInWrongChains::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; Service *srv = compiler->getFirstSrv(rule); assert(srv); string chain = rule->getStr("ipt_chain"); if (UserService::cast(srv) != NULL && chain != "OUTPUT" && !ipt_comp->isChainDescendantOfOutput(chain)) { compiler->warning( rule, "Iptables does not support module 'owner' in a chain " "other than OUTPUT"); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::fillActionOnReject::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); string s=ruleopt->getStr("action_on_reject"); if (s.empty()) ruleopt->setStr("action_on_reject", ipt_comp->getCachedFwOpt()->getStr("action_on_reject")); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::splitRuleIfSrvAnyActionReject::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv= rule->getSrv(); string s=ipt_comp->getActionOnReject(rule); if ( rule->getAction()==PolicyRule::Reject && s.empty() && srv->isAny() ) { PolicyRule *r; RuleElementSrv *nsrv; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->addRef(compiler->dbcopy->findInIndex( FWObjectDatabase::getIntId(ANY_TCP_OBJ_ID))); FWOptions *ruleopt =r->getOptionsObject(); ruleopt->setStr("action_on_reject","TCP RST"); tmp_queue.push_back(r); } tmp_queue.push_back(rule); return true; } /** * objects in Srv must be of the same type by the time when we call * this rule processor */ bool PolicyCompiler_ipt::checkForStatefulICMP6Rules::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); RuleElementSrv *srv = rule->getSrv(); if (!srv->isAny()) { Service *s = Service::cast(FWReference::getObject(srv->front())); assert(s); if (ICMP6Service::isA(s) && ! ruleopt->getBool("stateless")) { compiler->warning( rule, "Making rule stateless because it matches ICMPv6"); ruleopt->setBool("stateless",true); } } tmp_queue.push_back(rule); return true; } /* * I am adding subrule suffix here, which I then use to generate * unique new chain name for this rule. The idea is to generate * meaningful chain name, which is associated with rule number (like * RULE_5), however since this processor runs very early and may split * the rule, subsequent processors that create new chains end up * creating chains with the same names. Need this suffix to create * different, yet meaningful chain names. * * TODO: add methods addRuleSuffix and getRuleSuffix to class Rule. * Define suffix automatically in a tree-like manner, so that when * original rule is split, its parts will get suffixes ".1" and * ".2". When these parts are split again, suffixes should become * ".1.1" and ".1.2" and so on. */ bool PolicyCompiler_ipt::splitServicesIfRejectWithTCPReset::processNext() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv= rule->getSrv(); if ( rule->getAction()==PolicyRule::Reject && ipt_comp->isActionOnRejectTCPRST(rule)) { list tcp; list other; for (FWObject::iterator i=srv->begin(); i!=srv->end(); ++i) { Service *s1 = Service::cast(FWReference::getObject(*i)); assert(s1); // Protocol name is more reliable reference because CustomService // allows user to set protocol name if (s1->getProtocolName()=="tcp") tcp.push_back(s1); else other.push_back(s1); } if ( !other.empty() && tcp.empty() ) { if (seen_rules[rule->getPosition()]==false) compiler->warning( rule, "Rule action 'Reject' with TCP RST can be used " "only with TCP services."); ipt_comp->resetActionOnReject(rule); tmp_queue.push_back(rule); seen_rules[rule->getPosition()]=true; return true; } if ( other.empty() && !tcp.empty() ) { tmp_queue.push_back(rule); return true; } /* if both are not empty */ PolicyRule *r; RuleElementSrv *nsrv; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); for (list::iterator j=other.begin(); j!=other.end(); j++) nsrv->addRef( (*j) ); r->getOptionsObject()->setStr("action_on_reject",""); r->setStr("subrule_suffix","1"); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); for (list::iterator j=tcp.begin(); j!=tcp.end(); j++) nsrv->addRef( (*j) ); r->setStr("subrule_suffix","2"); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } /* * processor groupServicesByProtocol should have been called eariler, so now all * services in Srv are of the same type */ bool PolicyCompiler_ipt::prepareForMultiport::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *rel= rule->getSrv(); Service *srv= compiler->getFirstSrv(rule); if (rel->size()==1) { tmp_queue.push_back(rule); return true; } if (IPService::isA(srv) || ICMPService::isA(srv) || ICMP6Service::isA(srv) || CustomService::isA(srv) || TagService::isA(srv)) { /* multiport does not support ip and icmp services, split the rule */ for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef( s ); tmp_queue.push_back(r); } return true; } if (TCPService::isA(srv) || UDPService::isA(srv)) { rule->setBool("ipt_multiport",true); /* make sure we have no more than 15 ports */ if (rel->size()>15) { int n=0; PolicyRule *r; RuleElementSrv *nsrv = NULL; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (n==0) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); tmp_queue.push_back(r); } assert(nsrv!=NULL); nsrv->addRef( s ); if (++n>=15) n=0; } } else tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } /* * processor groupServicesByProtocol should have been called before, it makes sure * all objects in Service are of the same type. * * One special case is custom service "ESTABLISHED". This processor * splits rule if it finds this service and turns off stateful * inspection on the rule. * */ bool PolicyCompiler_ipt::specialCasesWithCustomServices::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv= rule->getSrv(); if (srv->isAny()) { tmp_queue.push_back(rule); return true; } stack cl; for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); assert(o!=NULL); if (CustomService::isA(o)) { string code=CustomService::cast(o)->getCodeForPlatform(compiler->myPlatformName()); if (code.find("ESTABLISHED")!=string::npos || code.find("RELATED")!=string::npos) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(o); r->getOptionsObject()->setBool("stateless",true); tmp_queue.push_back(r); cl.push(o); } } } while (!cl.empty()) { srv->removeRef( cl.top() ); cl.pop(); } /* * if srv is 'any' at this point, then it had only single object at * the beginning and that object was CustomService which we've split * into a new rule. There is nothing left in the original srv so we * can simply drop the old rule. */ if (!srv->isAny()) tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::convertAnyToNotFWForShadowing::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); PolicyRule *r; if ( ruleopt->getInt("firewall_is_part_of_any_and_networks")==0 ) { RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); if (srcrel->isAny()) { // srcrel->addRef(compiler->fw); // srcrel->setNeg(true); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction( PolicyRule::Return ); RuleElementSrc *nsrc=r->getSrc(); nsrc->clearChildren(); nsrc->addRef( compiler->fw ); tmp_queue.push_back(r); } if (dstrel->isAny()) { // dstrel->addRef(compiler->fw); // dstrel->setNeg(true); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction( PolicyRule::Return ); RuleElementDst *ndst=r->getDst(); ndst->clearChildren(); ndst->addRef( compiler->fw ); tmp_queue.push_back(r); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::processMultiAddressObjectsInRE::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; OSConfigurator_linux24 *osconf = dynamic_cast(compiler->osconfigurator); RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) ); if (re->size()==1) { FWObject *o = re->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { // we have just one object in RE and this object is MutiAddressRunTime if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { string path = atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); if (path.empty() && !atrt->getSourceName().empty()) { compiler->abort(rule, "Firewall's data directory not set for address table: " + atrt->getName()); return true; } rule->setStr("address_table_file", path); osconf->registerMultiAddressObject(atrt); } if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { // this is DNSName converted to its run-time counterpart, // we do not need to touch it at all } } tmp_queue.push_back(rule); return true; } list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) cl.push_back(atrt); } if (cl.empty()) { tmp_queue.push_back(rule); return true; } RuleElement *nre; RuleElement *ore = re; PolicyRule *r; for (list::iterator i=cl.begin(); i!=cl.end(); i++) { MultiAddressRunTime *atrt = *i; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( atrt ); string path = atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); if (path.empty() && !atrt->getSourceName().empty()) { compiler->abort(rule, "Firewall's data directory not set for address table: " + atrt->getName()); return true; } r->setStr("address_table_file", path); osconf->registerMultiAddressObject(atrt); tmp_queue.push_back(r); ore->removeRef( *i ); } // if rule element contained only run-time address tables, it should // be empty by now. There is no need to continue with this rule then. if ( ! re->isAny()) tmp_queue.push_back(rule); return true; } /* * iptables does not have target that would do nothing and would not * terminate processing of the packet (like NOP), so we create a new * user chain with target RETURN. */ bool PolicyCompiler_ipt::accounting::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementItf *itf_re = rule->getItf(); assert(itf_re!=NULL); Interface *rule_iface = Interface::cast(FWObjectReference::getObject(itf_re->front())); FWOptions *ruleopt = rule->getOptionsObject(); if (rule->getAction()==PolicyRule::Accounting && rule->getStr("ipt_target").empty()) { string this_chain = rule->getStr("ipt_chain"); string new_chain = ipt_comp->getNewChainName(rule, rule_iface); string rule_name_accounting = ruleopt->getStr("rule_name_accounting"); if (!rule_name_accounting.empty()) new_chain = rule_name_accounting; if (new_chain==this_chain) { rule->setStr("ipt_target", "RETURN"); rule->setAction(PolicyRule::Continue); } else { PolicyRule *r; FWOptions *ruleopt; RuleElementSrc *nsrc; RuleElementDst *ndst; RuleElementSrv *nsrv; /* * add copy of original rule, but turn off logging and set target * chain to new_chain. */ r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getSrc(); nsrc->reset(); ndst=r->getDst(); ndst->reset(); nsrv=r->getSrv(); nsrv->reset(); r->setStr("ipt_chain",new_chain); r->setStr("upstream_rule_chain",this_chain); ipt_comp->registerChain(new_chain); ipt_comp->insertUpstreamChain(this_chain, new_chain); r->setStr("ipt_target", "RETURN"); r->setLogging(false); r->setAction(PolicyRule::Continue); tmp_queue.push_back(r); rule->setStr("ipt_target", new_chain); rule->setLogging(false); ruleopt = rule->getOptionsObject(); ruleopt->setInt("limit_value",-1); ruleopt->setInt("connlimit_value",-1); ruleopt->setInt("hashlimit_value",-1); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipt::countChainUsage::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { PolicyRule *rule = PolicyRule::cast( *k ); ipt_comp->chain_usage_counter[rule->getStr("ipt_target")] += 1; } // second pass: if chain the rule belongs to has never been used as a target // then the target chain of the rule will never be used as well for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { PolicyRule *rule = PolicyRule::cast( *k ); if (ipt_comp->chain_usage_counter[rule->getStr("ipt_chain")] == 0) ipt_comp->chain_usage_counter[rule->getStr("ipt_target")] = 0; } return true; } bool PolicyCompiler_ipt::checkInterfaceAgainstAddressFamily::processNext() { PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; /* * If interface is "regular", compiler expects its addresses to * match addresses on real firewall. If it does not have any * addresses that match address family of the rule set, drop the * rule. If interface is not "Regular", i.e. dynamic, unnumbered * or bridge port, then compiler assumes it gets its address(es) * at run time and therefore can have address that matches address * family of the rule set. Therefore we can not drop the rule. */ Interface *rule_iface = compiler->getFirstItf(rule); if (rule_iface==NULL || !rule_iface->isRegular()) { tmp_queue.push_back(rule); return true; } string addr_type = IPv4::TYPENAME; if (ipt_comp->ipv6) addr_type = IPv6::TYPENAME; list addr_list = rule_iface->getByType(addr_type); if (addr_list.size() != 0) { tmp_queue.push_back(rule); return true; } if (rule_iface->isFailoverInterface()) { /* * for ticket #1172 : this is cluster interface that has no * address, check properties of the corresponding member */ FailoverClusterGroup *fg = FailoverClusterGroup::cast( rule_iface->getFirstByType(FailoverClusterGroup::TYPENAME)); Interface *other_iface = fg->getInterfaceForMemberFirewall(compiler->fw); if (other_iface == NULL) { // if we get here, this cluster interface does not have // any corresponding interface of the firewall we are // compiling right now. What is the right thing to do in // this case? I suppose we can't check if this interface // matches address family. Dropping the rule. QString err("Cluster interface '%1' does not map onto any " "interface of the firewall '%2' but is used " "in the 'Interface' rule element. " "The rule will be dropped because it can " "not be associated with this interface."); compiler->warning(rule, err.arg(rule_iface->getName().c_str()) .arg(compiler->fw->getName().c_str()).toStdString()); return true; } if (other_iface->getByType(addr_type).size() != 0) { tmp_queue.push_back(rule); return true; } else { // member interface also has no addresses return true; } } // interface has no addresses and is not cluster failover interface // drop the rule return true; } bool PolicyCompiler_ipt::addPredefinedRules::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipt::addRuleFilter() { add( new dropMangleTableRules(" remove rules that require mangle table") ); } /** *----------------------------------------------------------------------- */ void PolicyCompiler_ipt::compile() { string version = fw->getStr("version"); string banner = " Compiling ruleset " + getRuleSetName() + " for '" + my_table + "' table"; if (ipv6) banner += ", IPv6"; info(banner); Compiler::compile(); bool check_for_recursive_groups=true; if ( fw->getOptionsObject()->getBool ("check_shading") && ! inSingleRuleCompileMode()) { add( new Begin("Detecting rule shadowing")); addRuleFilter(); add( new printTotalNumberOfRules()); // use full negation rule processor in shadowing detection. // This rule processor replaces inetrface(s) object(s) with a // complimentary set of "other" interfaces of the firewall. // add( new ItfNegation("process negation in Itf")); add( new InterfacePolicyRules( "process interface policy rules and store interface ids")); add( new convertAnyToNotFWForShadowing("convert 'any' to '!fw'")); #if 0 add( new splitIfSrcAnyForShadowing("split rule if src is any")); add( new splitIfDstAnyForShadowing("split rule if dst is any")); add( new SrcNegation(true, "process negation in Src")); add( new DstNegation(true, "process negation in Dst")); #endif add( new recursiveGroupsInSrc("check for recursive groups in SRC")); add( new recursiveGroupsInDst("check for recursive groups in DST")); add( new recursiveGroupsInSrv("check for recursive groups in SRV")); check_for_recursive_groups=false; add( new ExpandGroups("expand groups")); add( new dropRuleWithEmptyRE( "drop rules with empty rule elements")); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC")); add( new eliminateDuplicatesInDST("eliminate duplicates in DST")); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV")); add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src")); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst")); /* behavior of processors ExpandMultiple... has been changed in * virtual method _expand_interface */ add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC")); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST")); add( new dropRuleWithEmptyRE( "drop rules with empty rule elements")); add( new ConvertToAtomic("convert to atomic rules")); /* * This assumes that all rules that go into the mangle table are * non-terminating. This is not necessarily correct because * non-termination is really an attribute of the target. However * targets that we support that go into mangle table (CLASSIFY and * MARK) are indeed non-terminating. */ add( new SkipActionContinueWithNoLogging( "drop rules with action Continue") ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); // #2367 // if (my_table=="mangle" && // !fw->getOptionsObject()->getBool("classify_mark_terminating") // ) // { // add( new dropTerminatingTargets( // "Drop rules with terminating targets") ); // add( new DetectShadowingForNonTerminatingRules( // "Detect shadowing for non-terminating rules" ) ); // } else add( new DetectShadowing("Detect shadowing" ) ); add( new simplePrintProgress() ); runRuleProcessors(); deleteRuleProcessors(); } add( new PolicyCompiler::Begin()); add( new addPredefinedRules("Add some predefined rules")); addRuleFilter(); add( new printTotalNumberOfRules()); add( new singleRuleFilter()); add( new deprecateOptionRoute("Deprecate option Route")); add( new checkForUnsupportedCombinationsInMangle( "Check for unsupported Tag+Route and Classify+Route combinations")); add( new clearTagClassifyInFilter( "Clear Tag and Classify options in filter table")); add( new clearLogInMangle("clear logging in rules in mangle table")); add( new clearActionInTagClassifyIfMangle( "clear action in rules with Tag and Classify in mangle")); add( new storeAction("store original action of this rule")); add( new Logging1("check global logging override option")); add( new emptyGroupsInItf("check for empty groups in Itf")); add( new expandGroupsInItf("expand groups in Interface" )); add( new replaceClusterInterfaceInItf( "replace cluster interfaces with member interfaces in the Interface rule element")); add( new singleObjectNegationItf( "negation in Itf if it holds single object")); add( new ItfNegation("process negation in Itf")); add( new decideOnChainForClassify("set chain for action is Classify")); add( new InterfaceAndDirection("fill in interface and direction")); // if an action requires chain POSTROUTING (e.g. Classify), set chain // BEFORE calling splitIfIfaceAndDirectionBoth add( new splitIfIfaceAndDirectionBoth( "split interface rule with direction 'both'")); if (check_for_recursive_groups) { add( new recursiveGroupsInSrc("check for recursive groups in SRC")); add( new recursiveGroupsInDst("check for recursive groups in DST")); add( new recursiveGroupsInSrv("check for recursive groups in SRV")); } add( new emptyGroupsInSrc("check for empty groups in SRC")); add( new emptyGroupsInDst("check for empty groups in DST")); add( new emptyGroupsInSrv("check for empty groups in SRV")); /* * commented out to fix bug #727324. "-p tcp --destination-port ! 25" * means "all TCP with port != 25", which is not the same as "all * protocols except TCP port 25". We just can't use "!" with negation * in service even if there is only single object in that rule * element. * * Further correction: we CAN use single object negatiob with some types * of service objects, such as e.g. TagService or UserService */ add( new SingleSrvNegation("negation in Srv if it holds 1 object")); add( new splitRuleIfSrvAnyActionReject( "split rule if action is reject and srv is any" ) ); add( new SrvNegation( false, "process negation in Srv") ); add( new expandGroupsInSrv("expand groups in Srv" )); add( new CheckForTCPEstablished("TCPService with \"established\"") ); // add( new splitRuleIfSrvAnyActionReject( // "split rule if action is reject and srv is any" ) ); add( new fillActionOnReject("fill in action_on_reject" ) ); add( new splitServicesIfRejectWithTCPReset( "split if action on reject is TCP reset")); add( new fillActionOnReject("fill in action_on_reject 2" ) ); add( new splitServicesIfRejectWithTCPReset( "split if action on reject is TCP reset 2")); add( new SingleSrcNegation("negation in Src if it holds single object")); add( new SingleDstNegation("negation in Dst if it holds single object")); add( new splitIfSrcNegAndFw("split rule if src has negation and fw")); add( new splitIfDstNegAndFw("split rule if dst has negation and fw")); add( new SrcNegation(false, "process negation in Src" )); add( new DstNegation(false, "process negation in Dst" )); add( new TimeNegation(false, "process negation in Time" )); add( new Logging2("process logging")); // #2367 #2397 add( new splitIfTagClassifyOrRoute( "Split rule if it uses tagging, classification or routing options")); add( new splitIfTagAndConnmark("Tag+CONNMARK combo")); add( new Route("process route rules")); /* * this is just a patch for those who do not understand how does * "assume firewall is part of any" work. It also eliminates redundant * and useless rules in the FORWARD chain for rules assigned to a * loopback interface. */ // add( new decideOnChainIfLoopback("any-any rule on loopback" ) ); add( new ExpandGroups("expand all groups")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC" )); add( new eliminateDuplicatesInDST("eliminate duplicates in DST" )); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV" )); add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src")); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst")); add( new accounting("Accounting") ); add( new splitIfSrcAny("split rule if src is any") ); if (my_table == "mangle") add( new checkActionInMangleTable("check allowed actions in mangle table")); add( new setChainForMangle("set chain for other rules in mangle")); add( new setChainPreroutingForTag("chain PREROUTING for Tag")); add( new splitIfDstAny("split rule if dst is any") ); add( new setChainPostroutingForTag("chain POSTROUTING for Tag")); add( new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src")); add( new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst")); if (XMLTools::version_compare(version, "1.2.11") < 0) { /* Use module iprange for iptables v1.2.11 and later. * should expand address range before splitIfSrcMatchesFw because some * addresses in the range may match firewall */ add( new addressRanges("process address ranges")); } else { add( new specialCaseAddressRangeInSrc( "replace single address range in Src")); add( new specialCaseAddressRangeInDst( "replace single address range in Dst")); add( new splitIfSrcMatchingAddressRange( "split rule if Src contains matching address range object")); add( new splitIfDstMatchingAddressRange( "split rule if Dst contains matching address range object")); } add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new splitIfSrcMatchesFw("split rule if src matches FW")); add( new splitIfDstMatchesFw("split rule if dst matches FW")); add( new specialCaseWithFW1( "special case with firewall" ) ); add( new decideOnChainIfDstFW( "decide on chain if Dst has fw" ) ); add( new splitIfSrcFWNetwork( "split rule if src has a net fw has interface on" ) ); add( new decideOnChainIfSrcFW( "decide on chain if Src has fw" ) ); add( new splitIfDstFWNetwork( "split rule if dst has a net fw has interface on" ) ); add( new specialCaseWithFW2( "replace fw with its interfaces if src==dst==fw" ) ); /* behavior of processors ExpandMultiple... has been changed in * the virtual method expandInterface */ add( new expandMultipleAddressesIfNotFWinSrc( "expand multiple addresses if not FW in Src") ); add( new expandMultipleAddressesIfNotFWinDst( "expand multiple addresses if not FW in Dst") ); add( new expandLoopbackInterfaceAddress( "check for loopback interface in the rule objects") ); // processors that expand objects with multiple addresses // check addresses against current address family using member // ipv6. If all addresses do not match, we may end up with // empty rule element. add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); // trying process rules with multiple interfaces as late as possible add( new InterfacePolicyRulesWithOptimization( "process interface policy rules and store interface ids") ); add( new checkInterfaceAgainstAddressFamily( "check if interface matches address family") ); /* this is just a patch for those who do not understand how does * "assume firewall is part of any" work. It also eliminates * redundant and useless rules in the FORWARD chain for rules * assigned to a loopback interface. */ add( new decideOnChainIfLoopback("any-any rule on loopback" ) ); // add( new decideOnChainForClassify("set chain if action is Classify")); add( new finalizeChain( "decide on chain" ) ); /*****************************************************************/ /* at this point in all rules where firewall is in either src or * dst, firewall is a single object in that rule element. Other * rule elements may contain multiple objects yet */ add( new specialCaseWithFWInDstAndOutbound( "Drop rules in FORWARD chain with non-empty interface and dir Outbound")); add( new decideOnTarget( "decide on target" ) ); add( new checkForRestoreMarkInOutput( "check if we need -A OUTPUT -j CONNMARK --restore-mark")); /* * removed call to processor removeFW to make changes for bug * #685947: "Rules with firewall object allow too much. " */ add( new removeFW("remove fw") ); add( new ExpandMultipleAddresses("expand multiple addresses" ) ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); if (ipv6) add( new DropIPv4Rules("drop ipv4 rules")); else add( new DropIPv6Rules("drop ipv6 rules")); //add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new checkForUnnumbered("check for unnumbered interfaces" ) ); add( new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls")); if ( fwopt->getBool("bridging_fw") ) add( new bridgingFw("handle bridging firewall cases")); add( new specialCaseWithUnnumberedInterface( "check for a special cases with unnumbered interface")); // add( new groupServicesByProtocol("split on services")); // add( new prepareForMultiport("prepare for multiport")); add( new optimize1("optimization 1, pass 1")); add( new optimize1("optimization 1, pass 2")); add( new optimize1("optimization 1, pass 3")); add( new groupServicesByProtocol("split on services")); add( new separateTCPWithFlags("split on TCP services with flags")); add( new verifyCustomServices("verify custom services")); add( new specialCasesWithCustomServices( "scpecial cases with some custom services")); add( new separatePortRanges("separate port ranges")); add( new separateUserServices("separate user services")); add( new separateSrcPort("split on TCP and UDP with source ports")); add( new checkForStatefulICMP6Rules( "Make sure rules that match icmpv6 are stateless")); add( new optimize2("optimization 2") ); add( new prepareForMultiport("prepare for multiport") ); add( new ConvertToAtomicForAddresses( "convert to atomic rules by address elements") ); add( new checkForZeroAddr("check for zero addresses") ); add( new checkMACinOUTPUTChain("check for MAC in OUTPUT chain") ); add( new checkUserServiceInWrongChains( "Check for UserSErvice ojects in chains other than OUTPUT")); add( new ConvertToAtomicForIntervals( "convert to atomic rules by interval element") ); // see #2235. ACtion Continue should generate iptables command // w/o "-j TARGET" parameter // // add( new SkipActionContinueWithNoLogging( // "drop rules with action Continue") ); add( new optimize3("optimization 3") ); add( new optimizeForMinusIOPlus("optimize for '-i +' / '-o +'") ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new countChainUsage("Count chain usage")); add( createPrintRuleProcessor() ); add( new simplePrintProgress()); runRuleProcessors(); deleteRuleProcessors(); } string PolicyCompiler_ipt::debugPrintRule(Rule *r) { PolicyRule *rule=PolicyRule::cast(r); FWOptions *ruleopt =rule->getOptionsObject(); RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); RuleElementSrv *srvrel=rule->getSrv(); RuleElementInterval *intrel=rule->getWhen(); RuleElementItf *itfrel=rule->getItf(); ostringstream str; // str << setw(70) << setfill('-') << "-"; int no=0; FWObject::iterator i1=srcrel->begin(); FWObject::iterator i2=dstrel->begin(); FWObject::iterator i3=srvrel->begin(); FWObject::iterator i4=intrel->begin(); FWObject::iterator i5=itfrel->begin(); while ( i1!=srcrel->end() || i2!=dstrel->end() || i3!=srvrel->end() || i4!=intrel->end() || i5!=itfrel->end()) { str << endl; ostringstream src; ostringstream dst; string srv=" "; string time=" "; ostringstream itf; if (srcrel->getNeg()) src << "!"; if (dstrel->getNeg()) dst << "!"; if (srvrel->getNeg()) srv = "!"; if (intrel->getNeg()) time = "!"; if (itfrel->getNeg()) itf << "!"; if (i1!=srcrel->end()) { FWObject *o = FWReference::getObject(*i1); src << o->getName(); if (Group::cast(o)!=NULL) src << "[" << o->size() << "]"; if ( MultiAddress::cast(o)!=NULL) src << string((MultiAddress::cast(o)->isRunTime()) ? "(r)" : "(c)"); } if (i2!=dstrel->end()) { FWObject *o = FWReference::getObject(*i2); dst << o->getName(); if (Group::cast(o)!=NULL) dst << "[" << o->size() << "]"; if ( MultiAddress::cast(o)!=NULL) dst << string((MultiAddress::cast(o)->isRunTime()) ? "(r)" : "(c)"); } if (i3!=srvrel->end()) { FWObject *o = FWReference::getObject(*i3); srv += o->getName(); } if (i4!=intrel->end()) { FWObject *o = FWReference::getObject(*i4); time += o->getName(); } if (i5!=itfrel->end()) { FWObject *o = FWReference::getObject(*i5); Interface *iface = Interface::cast(o); itf << o->getName() << "(" << o->getId() << ")"; if (iface) { if (iface->isDyn()) itf << "D"; if (iface->isUnnumbered()) itf << "U"; if (iface->isFailoverInterface()) itf << "F"; } } int w=0; if (no==0) { str << rule->getLabel(); w = rule->getLabel().length(); } str << setw(15-w) << setfill(' ') << " "; str << setw(18) << setfill(' ') << src.str(); str << setw(18) << setfill(' ') << dst.str(); str << setw(12) << setfill(' ') << srv.c_str(); str << setw(10) << setfill(' ') << time.c_str(); str << setw(8) << setfill(' ') << itf.str(); if (no==0) { str << setw(9) << setfill(' ') << rule->getActionAsString().c_str(); str << setw(9) << setfill(' ') << rule->getDirectionAsString().c_str(); if (rule->getLogging()) str << " LOG"; } else str << setw(18) << setfill(' ') << " "; ++no; if ( i1!=srcrel->end() ) ++i1; if ( i2!=dstrel->end() ) ++i2; if ( i3!=srvrel->end() ) ++i3; if ( i4!=intrel->end() ) ++i4; if ( i5!=itfrel->end() ) ++i5; } str << " pos=" << rule->getPosition(); str << " u=" << rule->getUniqueId(); str << " c=" << printChains(rule); str << " t=" << rule->getStr("ipt_target"); if ( ! rule->getStr(".iface").empty()) str << " .iface=" << rule->getStr(".iface"); if (rule->getTagging()) str << " (tag)"; if (rule->getClassification()) str << " (class)"; if (rule->getRouting()) str << " (route)"; if (rule->getAction()==PolicyRule::Reject) str << " " + ruleopt->getStr("action_on_reject"); if (ruleopt!=NULL && ruleopt->getInt("limit_value")>0) str << " limit"; if (ruleopt!=NULL && ruleopt->getInt("connlimit_value")>0) str << " connlimit"; if (ruleopt!=NULL && ruleopt->getInt("hashlimit_value")>0) str << " hashlimit"; if (ruleopt!=NULL && ruleopt->getBool("no_input_chain")) str << " no_input"; if (ruleopt!=NULL && ruleopt->getBool("no_output_chain")) str << " no_output"; //ruleopt->dump(str, false, false); return str.str(); } void PolicyCompiler_ipt::epilog() { if (fwopt->getBool("use_iptables_restore") && getCompiledScriptLength()>0 && ! inSingleRuleCompileMode()) { output << "#" << endl; } } PolicyCompiler_ipt::PrintRule* PolicyCompiler_ipt::createPrintRuleProcessor() { PolicyCompiler_ipt::PrintRule* print_rule = NULL; if (fw->getOptionsObject()->getBool("use_iptables_restore")) { // bug #1812295: we should use PrintRuleIptRstEcho not only // when we have dynamic interfaces, but also when we have // address tables expanded at run time. Instead of checking // for all these conditions, just always use PrintRuleIptRstEcho print_rule = new PrintRuleIptRstEcho( "generate code for iptables-restore using echo"); } else { print_rule = new PrintRule("generate shell script"); } print_rule->setContext(this); print_rule->initialize(); return print_rule; } string PolicyCompiler_ipt::flushAndSetDefaultPolicy() { string res = ""; if (!inSingleRuleCompileMode() && fwopt->getBool("use_iptables_restore")) { res += "echo :INPUT DROP [0:0]\n"; res += "echo :FORWARD DROP [0:0]\n"; res += "echo :OUTPUT DROP [0:0]\n"; } return res; } std::string PolicyCompiler_ipt::printAutomaticRules() { string res=""; if (!inSingleRuleCompileMode()) { PolicyCompiler_ipt::PrintRule* print_rule = createPrintRuleProcessor(); // iptables accepted TCPMSS target in filter table, FORWARD chain // in the older versions, but requires it to be in mangle filter // starting somewhere 1.3.x string version = fw->getStr("version"); if (XMLTools::version_compare(version, "1.3.0")<0) res += print_rule->_clampTcpToMssRule(); res += print_rule->_printOptionalGlobalRules(); delete print_rule; } return res; } string PolicyCompiler_ipt::commit() { return createPrintRuleProcessor()->_commit(); } bool PolicyCompiler_ipt::newIptables(const string &version) { return (version.empty() || version=="ge_1.2.6" || XMLTools::version_compare(version, "1.2.6")>0); } list PolicyCompiler_ipt::getUsedChains() { list res; for (map::iterator it=chain_usage_counter.begin(); it!=chain_usage_counter.end(); ++it) res.push_back(it->first); return res; } /* * see #1417 To policy rules with different module limit settings but * otherwise identical should not shadow each other. * * For all limit modules: * rule with rate "-1" (i.e. no rate limiting at all) shadows rule with * rate > 0 * OR * rule with greater rate shadows rule with lower rate * * From man iptables: "A rule using this extension will match until * this limit is reached " * * consider for example two rules: rule 1 that matches 50 pkts/sec and * rule 2 that matches 30 pkts/sec * * rule 1 matches rates between 0 and 49 and rule 2 rates between 0 * and 29. This means rule 2 will never match any rate and rule with * greater limit value shadows the one with lower limit value * * we should return true if candidate_rule_2 shadows candidate_rule_1 */ bool PolicyCompiler_ipt::checkForShadowingPlatformSpecific(PolicyRule *candidate_r1, PolicyRule *candidate_r2) { FWOptions *opt_1 = candidate_r1->getOptionsObject(); FWOptions *opt_2 = candidate_r2->getOptionsObject(); if (opt_1->getInt("limit_value")>0 || opt_2->getInt("limit_value")>0) { int rate_1 = opt_1->getInt("limit_value"); if (rate_1 == -1) rate_1 = INT_MAX; int rate_2 = opt_2->getInt("limit_value"); if (rate_2 == -1) rate_2 = INT_MAX; if (rate_1 > rate_2) return false; if (opt_1->getStr("limit_value_not") != opt_2->getStr("limit_value_not")) return false; if (opt_1->getStr("limit_suffix") != opt_2->getStr("limit_suffix")) return false; } if (opt_1->getInt("connlimit_value")>0 || opt_2->getInt("connlimit_value")>0) { int rate_1 = opt_1->getInt("connlimit_value"); if (rate_1 == -1) rate_1 = INT_MAX; int rate_2 = opt_2->getInt("connlimit_value"); if (rate_2 == -1) rate_2 = INT_MAX; if (rate_1 > rate_2) return false; if (opt_1->getStr("connlimit_value_not") != opt_2->getStr("connlimit_value_not")) return false; if (opt_1->getStr("connlimit_suffix") != opt_2->getStr("connlimit_suffix")) return false; } if (opt_1->getInt("hashlimit_value")>0 || opt_2->getInt("hashlimit_value")>0) { int rate_1 = opt_1->getInt("hashlimit_value"); if (rate_1 == -1) rate_1 = INT_MAX; int rate_2 = opt_2->getInt("hashlimit_value"); if (rate_2 == -1) rate_2 = INT_MAX; if (rate_1 > rate_2) return false; if (opt_1->getStr("hashlimit_suffix") != opt_2->getStr("hashlimit_suffix")) return false; if (opt_1->getStr("hashlimit_mode") != opt_2->getStr("hashlimit_mode")) return false; if (opt_1->getStr("hashlimit_name") != opt_2->getStr("hashlimit_name")) return false; } return true; } fwbuilder-5.1.0.3599/src/iptlib/NATCompiler_PrintRuleIptRstEcho.cpp0000644000175000017500000000467211733011756025653 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_ipt.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Resources.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ /* * check and create new chain if needed */ string NATCompiler_ipt::PrintRuleIptRstEcho::_createChain(const string &chain) { string res; NATCompiler_ipt *ipt_comp = dynamic_cast(compiler); if (!minus_n_tracker_initialized) initializeMinusNTracker(); if ( ipt_comp->minus_n_commands->count(chain)==0 ) { if ( ! compiler->inSingleRuleCompileMode()) res = "echo \":" + chain + " - [0:0]\"\n"; (*(ipt_comp->minus_n_commands))[chain] = true; } return res; } string NATCompiler_ipt::PrintRuleIptRstEcho::_startRuleLine() { return string("echo \"-A "); } string NATCompiler_ipt::PrintRuleIptRstEcho::_endRuleLine() { return string("\"\n"); } bool NATCompiler_ipt::PrintRuleIptRstEcho::processNext() { if (print_once_on_top) { print_once_on_top=false; } return NATCompiler_ipt::PrintRuleIptRst::processNext(); } string NATCompiler_ipt::PrintRuleIptRstEcho::_declareTable() { ostringstream res; res << "echo '*nat'" << endl; return res.str(); } string NATCompiler_ipt::PrintRuleIptRstEcho::_commit() { return "echo COMMIT\n"; } string NATCompiler_ipt::PrintRuleIptRstEcho::_quote(const string &s) { return "\\\"" + s + "\\\""; } fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_secuwall.cpp0000644000175000017500000007271611733011756024374 0ustar sylvestresylvestre/* * OSConfigurator_secuwall.cpp - secunet wall OS configurator implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "config.h" #include "OSConfigurator_secuwall.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/Resources.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Tools.h" #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; static string sysconfig_dir = "sysconfig"; static string ssh_dir = "ssh"; static string networkscripts_dir = sysconfig_dir + "/network-scripts"; static string hosts_filename = "hosts"; static string dns_filename = "resolv.conf"; static string nsswitch_filename = "nsswitch.conf"; static string mgmt_filename = sysconfig_dir + "/management"; static string network_filename = sysconfig_dir + "/network"; static string iface_prefix = "ifcfg-"; static string iface_filename = networkscripts_dir+"/"+iface_prefix; static string fwadmin_ssh_key = "/.ssh/id_rsa.pub"; static string fwadmin_known_hosts = "/.ssh/known_hosts2"; string OSConfigurator_secuwall::myPlatformName() { return "Secuwall"; } OSConfigurator_secuwall::OSConfigurator_secuwall(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy) : OSConfigurator_linux24(_db, fw, ipv6_policy) { s_mapIfaceTypes["ethernet"] = ETHERNET; s_mapIfaceTypes["bridge"] = BRIDGE; s_mapIfaceTypes["bonding"] = BONDING; s_mapIfaceTypes["vrrp"] = CLUSTER; s_mapIfaceTypes["8021q"] = VLAN; s_mapIfaceStrings[ETHERNET] = "ethernet"; s_mapIfaceStrings[ALIAS] = "alias"; s_mapIfaceStrings[BRIDGE] = "bridge"; s_mapIfaceStrings[BONDING] = "bonding"; s_mapIfaceStrings[CLUSTER] = "vrrp"; s_mapIfaceStrings[VLAN] = "8021q"; /* search all interfaces, this means here: IP endpoints in stack! */ list fw_ifaces = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator it = fw_ifaces.begin(); it != fw_ifaces.end(); it++) { Interface *iface = Interface::cast(*it); assert(NULL != iface); /* Check if it is a management interface */ if (!iface->getName().empty() && (NULL != iface->getAddressObject())) { m_ifaces.push_back(iface); } } } /* * in addition to kernel parameters and other standard things * OSConfigurator_linux24 does, this class also creates configuration * directories, generates ssh keys and files for sysconfig-style * configuration. This method is called from CompilerDriver_ipt::run() * and does not run in single rule compile mode. */ void OSConfigurator_secuwall::processFirewallOptions() { OSConfigurator_linux24::processFirewallOptions(); if (!createDirStructure()) abort("Unable to create directory structure"); FWOptions* options = fw->getOptionsObject(); assert(options != NULL); /* Do ssh key generation if not disabled. */ if (!options->getBool("secuwall_no_ssh_key_generation")) { generateSSHKeys(); } generateHostsFile(); generateDNSFile(); generateNsswitchFile(); generateManagementFile(); generateNetworkFile(); generateInterfaces(); } bool OSConfigurator_secuwall::createDirStructure() const { QDir directory; list dir_names; dir_names.push_back (QString (fw->getName().c_str())); QString tmp_name = fw->getName().c_str(); tmp_name.append("/"); tmp_name.append(ssh_dir.c_str()); dir_names.push_back(tmp_name); tmp_name = fw->getName().c_str(); tmp_name.append("/"); tmp_name.append(sysconfig_dir.c_str()); dir_names.push_back(tmp_name); tmp_name = fw->getName().c_str(); tmp_name.append("/"); tmp_name.append(networkscripts_dir.c_str()); dir_names.push_back(tmp_name); list::const_iterator c_iter = dir_names.begin(); for (; c_iter != dir_names.end(); c_iter++) { if (!directory.mkdir(*c_iter)) { /* Check if directory already exists */ if (!directory.exists()) { cerr << "Error[" << errno << "]: " << strerror(errno); cerr << " '" << c_iter->toStdString() << "'"<< endl; return false; } } } cout << " created directory structure successfully" << endl << flush; return true; } int OSConfigurator_secuwall::generateManagementFile() { FWOptions* options = fw->getOptionsObject(); assert(options != NULL); QString s, mgm_ip, vrrp_secret, stream_string, snmp_ip; bool vrrp_master = false; vector tmp_v, mgm_iface; /* Temporary storage for management file content */ QTextStream stream (&stream_string); /* search Management Interfaces, note: this can be more than one */ for (list::iterator it = m_ifaces.begin(); it != m_ifaces.end(); it++) { /* Check if it is a management interface */ if ((*it)->isManagement()) { mgm_iface.push_back((*it)->getName()); } } stream << "MGM_DEV=\""; stream << stringify(mgm_iface, " ").c_str(); stream << "\"" << endl; /* lookup Management IP address */ mgm_ip = options->getStr("secuwall_mgmt_mgmtaddr").c_str(); if (mgm_ip.isEmpty()) { /* This is only a warning, if the system is not managed online */ cout << " Warning: no Management IP address specified!" << endl; } else { if (mgm_iface.empty()) { abort("At least one management interface is needed for Online Management!"); } else { stream << "MGM_IP=\""; tmp_v.clear(); tokenize(mgm_ip.toStdString(), tmp_v, ","); stream << stringify(tmp_v, " ").c_str(); stream << s << "\"" << endl; } } /* Log-Server IP address */ stream << "LOG_IP=\""; tmp_v.clear(); tokenize(options->getStr("secuwall_mgmt_loggingaddr"), tmp_v, ","); stream << stringify(tmp_v, " ").c_str(); stream << "\"" << endl; /* SNMP-Server IP address */ snmp_ip = options->getStr("secuwall_mgmt_snmpaddr").c_str(); if (!snmp_ip.isEmpty()) { if (mgm_iface.empty()) { abort("At least one management interface is needed for SNMP!"); } else { stream << "SNMP_IP=\""; tmp_v.clear(); tokenize(options->getStr("secuwall_mgmt_snmpaddr"), tmp_v, ","); stream << stringify(tmp_v, " ").c_str(); stream << "\"" << endl; /* SNMP Community string */ stream << "SNMP_COM=\""; stream << options->getStr("secuwall_mgmt_rosnmp").c_str(); stream << "\"" << endl; } } /* NTP-Server IP address */ stream << "NTP_IP=\""; tmp_v.clear(); tokenize(options->getStr("secuwall_mgmt_ntpaddr"), tmp_v, ","); stream << stringify(tmp_v, " ").c_str(); stream << "\"" << endl; /* /var partition */ stream << "VARPART=\""; stream << options->getStr("secuwall_mgmt_varpart").c_str(); stream << "\"" << endl; /* Configuration partition */ stream << "CFGPART=\""; stream << options->getStr("secuwall_mgmt_confpart").c_str(); stream << "\"" << endl; /* Activate Nagios */ stream << "NRPE="; s.clear(); s = options->getStr("secuwall_mgmt_nagiosaddr").c_str(); if (!s.isEmpty()) { stream << "yes" << endl; /* Nagios-Server IP-Address */ stream << "NRPE_IP=\""; tmp_v.clear(); tokenize(s.toStdString(), tmp_v, ","); stream << stringify(tmp_v, " ").c_str(); stream << "\"" << endl; } else { stream << "no" << endl; } /* VRRP interfaces */ for (FWObjectTypedChildIterator fw_ifaces = fw->findByType(Interface::TYPENAME); fw_ifaces != fw_ifaces.end(); ++fw_ifaces) { Interface *iface = Interface::cast(*fw_ifaces); /* Check if it is a VRRP interface */ FWObject *failover_group = iface->getFirstByType(FailoverClusterGroup::TYPENAME); if (failover_group) { FWOptions *failover_opts = FailoverClusterGroup::cast(failover_group)->getOptionsObject(); if (failover_group->getStr("type") == "vrrp" && failover_opts != NULL) { vrrp_secret = failover_opts->getStr("vrrp_secret").c_str(); vrrp_master = iface->getOptionsObject()->getBool("failover_master");; } } } /* Activate VRRP */ stream << "VRRPD="; if (options->getBool("cluster_member")) { stream << "yes" << endl; /* VRRP secret */ stream << "VRRPSECRET=\""; stream << vrrp_secret; stream << "\"" << endl; /* VRRP Master/Slave */ stream << "MASTER="; stream << (vrrp_master ? "yes" : "no"); stream << endl; } else { stream << "no" << endl; } /* conntrackd */ s.clear(); s = options->getStr("state_sync_interface").c_str(); stream << "CONNTRACKD="; if (!s.isEmpty()) { stream << "yes" << endl; /* conntrack device */ stream << "CONN_DEV=\""; stream << s; stream << "\"" << endl; } else { stream << "no" << endl; } /* Write actual management file */ string filename = fw->getName() + "/" + mgmt_filename; stringToFile(stream.string()->toStdString(), filename); cout << " wrote " << mgmt_filename << " successfully" << endl << flush; return 0; } /* Routes are expected to be verified & valid since this step is executed after Route policy compilation */ int OSConfigurator_secuwall::generateNetworkFile() { FWOptions* options = fw->getOptionsObject(); assert(options != NULL); FWObject *routes = fw->getFirstByType(Routing::TYPENAME); assert(routes); QString s, ifName, gwAddress, stream_string; /* Temporary storage for file content */ QTextStream stream (&stream_string); /* Default route */ RoutingRule* defaultRoute = NULL; /* Prepend static content */ stream << "NETWORKING=yes" << endl; /* Find default route */ FWObjectTypedChildIterator routing_rules = routes->findByType(RoutingRule::TYPENAME); for (; routing_rules != routing_rules.end(); ++routing_rules) { RoutingRule* route = RoutingRule::cast(*routing_rules); if (!route->isEmpty() && !route->isDisabled() && route->getRDst()->isAny()) { defaultRoute = route; /* There can only be one default route, so we are done */ break; } } if (defaultRoute != NULL) { RuleElementRItf* itfrel = defaultRoute->getRItf(); RuleElementRGtw* gtwrel = defaultRoute->getRGtw(); FWObject *oRGtw = FWReference::cast(gtwrel->front())->getPointer(); assert(oRGtw != NULL); FWObject *oRItf = FWReference::cast(itfrel->front())->getPointer(); assert(oRItf != NULL); /* Extract Gateway IP address */ if (Host::cast(oRGtw) != NULL) { Host *host=Host::cast(oRGtw); gwAddress = host->getAddressPtr()->toString().c_str(); } else if (Interface::cast(oRGtw) != NULL) { Interface *intf=Interface::cast(oRGtw); gwAddress = intf->getAddressPtr()->toString().c_str(); } else if (Address::cast(oRGtw)->dimension()==1) { Address *ipv4 = Address::cast(oRGtw); gwAddress = ipv4->getAddressPtr()->toString().c_str(); } /* Extract Interface name */ ifName = oRItf->getName().c_str(); } /* XXX: not setting gateway since default route will be set by routing rules */ /* Default Gateway */ stream << "GATEWAY=\""; s = gwAddress; { // stream << s; } stream << "\"" << endl; /* Gateway interface */ stream << "GATEWAYDEV=\""; s = ifName; { // stream << s; } stream << "\"" << endl; /* Hostname */ stream << "HOSTNAME=\""; stream << fw->getName().c_str(); stream << "\"" << endl; /* Routing */ stream << "FORWARD_IPV4=\""; if (options->getBool("linux24_ip_forward")) { stream << "yes"; } else { stream << "no"; } stream << "\"" << endl; /* Write actual network file */ string filename = fw->getName() + "/" + network_filename; stringToFile(stream.string()->toStdString(), filename); cout << " wrote " << network_filename << " successfully" << endl << flush; return 0; } int OSConfigurator_secuwall::generateHostsFile() { FWOptions* options = fw->getOptionsObject(); assert(options != NULL); QString s, stream_string; /* Temporary storage for file content */ QTextStream stream (&stream_string); /* Prepend static content */ stream << "127.0.0.1\tlocalhost\n\n# Secuwall hosts" << endl; /* TODO: Should entries of every fw interface address be appended? */ stream << options->getStr("secuwall_dns_hosts").c_str(); stream << endl; /* Write actual hosts file */ string filename = fw->getName() + "/" + hosts_filename; stringToFile(stream.string()->toStdString(), filename); cout << " wrote " << hosts_filename << " successfully" << endl << flush; return 0; } int OSConfigurator_secuwall::generateDNSFile() { FWOptions* options = fw->getOptionsObject(); assert(options != NULL); QString s, stream_string; /* Temporary storage for file content */ QTextStream stream (&stream_string); /* Search domains */ s = options->getStr("secuwall_dns_domains").c_str(); if (!s.isEmpty()) { /* Replace \n with " " */ s.replace(QString("\n"), QString(" ")); stream << "search\t\t" << s << endl; } /* DNS-Server entries */ s = options->getStr("secuwall_dns_srv1").c_str(); if (!s.isEmpty()) stream << "nameserver\t" << s << endl; s = options->getStr("secuwall_dns_srv2").c_str(); if (!s.isEmpty()) stream << "nameserver\t" << s << endl; s = options->getStr("secuwall_dns_srv3").c_str(); if (!s.isEmpty()) stream << "nameserver\t" << s << endl; /* Write actual DNS file */ string filename = fw->getName() + "/" + dns_filename; stringToFile(stream.string()->toStdString(), filename); cout << " wrote " << dns_filename << " successfully" << endl << flush; return 0; } int OSConfigurator_secuwall::generateNsswitchFile() { FWOptions* options = fw->getOptionsObject(); assert(options != NULL); QString s, stream_string; /* Temporary storage for file content */ QTextStream stream(&stream_string); /* Prepend static content */ stream << "passwd:\t\tfiles\nshadow:\t\tfiles\ngroup:\t\tfiles\n" << endl; /* hosts entries */ stream << "hosts:\t\t"; s = options->getStr("secuwall_dns_reso1").c_str(); if (!s.isEmpty() && s != "none") { stream << s; } s = options->getStr("secuwall_dns_reso2").c_str(); if (!s.isEmpty() && s != "none") { stream << " " << s; } s = options->getStr("secuwall_dns_reso3").c_str(); if (!s.isEmpty() && s != "none") { stream << " " << s; } s = options->getStr("secuwall_dns_reso4").c_str(); if (!s.isEmpty() && s != "none") { stream << " " << s; } s = options->getStr("secuwall_dns_reso5").c_str(); if (!s.isEmpty() && s != "none") { stream << " " << s << endl; } stream << endl; /* Append static content */ stream << "ethers:\t\tfiles\nnetmasks:\tfiles\nnetworks:\tfiles\nprotocols:\tfiles\nrpc:\t\tfiles\nservices:\tfiles\n"; /* Write actual nsswitch file */ string filename = fw->getName() + "/" + nsswitch_filename; stringToFile(stream.string()->toStdString(), filename); cout << " wrote " << nsswitch_filename << " successfully" << endl << flush; return 0; } int OSConfigurator_secuwall::generateInterfaceFile (Interface * iface, string name, IPv4 * ip_address, int iface_number) { FWOptions* options = NULL; ifaceType itype = ifNotDefined; QString s; /* Temporary storage for file content */ QString stream_string; QTextStream stream(&stream_string); assert(iface != NULL); /* fallback for name of the interface */ if (name.empty()) name = iface->getName(); if (name.empty()) abort("cannot get name for interface"); /* determine the type of the interface */ if (iface->getName().find("*") == string::npos) options = iface->getOptionsObject(); if (iface_number > 0) { itype = ALIAS; } else if (options == NULL || options->getStr("type").empty()) { itype = ETHERNET; } else { itype = s_mapIfaceTypes[options->getStr("type")]; } /* shortcut: unconfigured ethernet devices just exist, they don't need a config file */ if ((itype == ETHERNET) && (ip_address == NULL) && (iface->getAddressObject() == NULL)) return 0; /* Interface name */ stream << "DEVICE=\""; stream << name.c_str(); if (iface_number > 0) stream << ":" << iface_number; stream << "\"" << endl; /* Boot-Protocol */ stream << "BOOTPROTO=\""; if (iface->isDyn()) { stream << "dhcp"; } else { stream << "none"; } stream << "\"" << endl; /* Address object contains host, network and broadcast address plus netmask */ const Address* ipAddr; if (ip_address != NULL) ipAddr = ip_address->getAddressObject(); if (ipAddr != NULL) { /* Interface IP Address */ stream << "IPADDR=\""; stream << ipAddr->getAddressPtr()->toString().c_str(); stream << "\"" << endl; /* Netmask */ stream << "NETMASK=\""; stream << ipAddr->getNetmaskPtr()->toString().c_str(); stream << "\"" << endl; /* Network IP Address */ stream << "NETWORK=\""; stream << ipAddr->getNetworkAddressPtr()->toString().c_str(); stream << "\"" << endl; /* Broadcast IP Address */ stream << "BROADCAST=\""; stream << ipAddr->getBroadcastAddressPtr()->toString().c_str(); stream << "\"" << endl; } /* Activate on bootup */ stream << "ONBOOT=\""; if (options != NULL && options->getBool("iface_disableboot")) { stream << "no"; } else { stream << "yes"; } stream << "\"" << endl; /* Link */ stream << "LINK=\""; if (options != NULL) { stream << options->getStr("iface_options").c_str(); } stream << "\"" << endl; /* MAC-Address */ stream << "MACADDR=\""; physAddress* macAddr = iface->getPhysicalAddress(); if (macAddr != NULL) { stream << macAddr->getPhysAddress().c_str(); } stream << "\"" << endl; /* MTU */ s.clear(); stream << "MTU=\""; if (options == NULL || (s = options->getStr("iface_mtu").c_str()).isEmpty()) { /* TODO: Extract magic value */ /* Set to "sane" default: "1500" */ s = "1500"; } stream << s; stream << "\"" << endl; /* Activate ARP */ stream << "ARP=\""; if (options != NULL && options->getBool("iface_disablearp")) { stream << "no"; } else { stream << "yes"; } stream << "\"" << endl; /* Interface type */ stream << "TYPE=\""; stream << s_mapIfaceStrings[itype].c_str(); stream << "\"" << endl; /* get all direct children of type interface */ list basedevs = iface->getByType(Interface::TYPENAME); /* Type-specific parameter handling */ switch (itype) { case BRIDGE: /* Fall-through */ case BONDING: /* Iterate over all child interfaces */ if (basedevs.empty()) { abort("No base device specified for " + name); } else { vector devs; for (list::iterator it = basedevs.begin(); it != basedevs.end(); it++) { Interface *iface = Interface::cast(*it); assert(NULL != iface); if (!(iface->getName().empty())) { devs.push_back(iface->getName()); generateInterfaceFile(iface); } } /* Base Device */ stream << "BASEDEV=\""; stream << stringify(devs," ").c_str(); stream << "\"" << endl; } break; case VLAN: if (options == NULL || options->getStr("vlan_id").empty()) { abort("No VLAN id specified for " + name); } stream << "VLANID=\""; stream << options->getStr("vlan_id").c_str(); stream << "\"" << endl; if (iface->getParent() == NULL || iface->getParent()->getName().empty()) { /* No base device provided */ abort("No base device specified for " + name); } stream << "BASEDEV=\""; stream << iface->getParent()->getName().c_str(); stream << "\"" << endl; generateInterfaceFile(Interface::cast(iface->getParent())); break; case CLUSTER: if (options->getStr("base_device").empty()) { /* No base device provided */ abort("No base device specified for " + name); } stream << "BASEDEV=\""; stream << options->getStr("base_device").c_str(); stream << "\"" << endl; break; case ALIAS: /* Base Device for secondary interfaces*/ stream << "BASEDEV=\""; stream << name.c_str(); stream << "\"" << endl; break; default: /* Don't define BASEDEV */ break; } /* Write actual interface file */ string filename = fw->getName() + "/" + iface_filename + name; if (iface_number > 0) { stringstream tmp; tmp << ":" << iface_number; filename += tmp.str(); } stringToFile(stream.string()->toStdString(), filename); cout << " wrote " << filename << " successfully" << endl << flush; return 0; } template inline std::string toString (const T& t) { std::stringstream ss; ss << t; return ss.str(); } int OSConfigurator_secuwall::generateInterfaces() { /* clean up possibly stale interface files */ string nwdir = fw->getName() + "/" + networkscripts_dir; QDir d(nwdir.c_str()); QStringList entries = d.entryList(); for (QStringList::ConstIterator entry=entries.begin(); entry!=entries.end(); ++entry) { if (*entry != "." && *entry != "..") { d.remove(*entry); } } int vrrp_count = 0; /* Iterate over all top-level interfaces */ for (list::iterator it = m_ifaces.begin(); it != m_ifaces.end(); it++) { string ifname = (*it)->getName(); FWOptions *options = (*it)->getOptionsObject(); /* rename handling for our vrrp "devices" */ if ((options != NULL) && options->getBool("cluster_interface")) { ifname = "vrrp" + ::toString(vrrp_count++); } /* Iterate over all addresses */ FWObjectTypedChildIterator j = (*it)->findByType(IPv4::TYPENAME); int count = 0; for (; j != j.end(); ++j, ++count) { IPv4 *address = IPv4::cast(*j); generateInterfaceFile (*it, ifname, address, count); } } return 0; } int OSConfigurator_secuwall::stringToFile(const std::string data, const std::string filename, const QIODevice::OpenMode mode) const { QFile file (QString (filename.c_str())); if (!file.open (mode)) { cerr << "Unable to open file " << filename << endl; } qint64 byte_count = file.write (data.c_str()); if (byte_count == -1) { cerr << "Unable to write data to file " << filename << endl; } if (data.length() != (unsigned int) byte_count) { cerr << "Unable to write all data (" << byte_count << " of " << data.length() << " bytes) to file " << filename << endl; } file.close(); file.setPermissions (QFile::ReadOwner|QFile::WriteOwner|QFile::ReadGroup|QFile::ReadOther); return 0; } int OSConfigurator_secuwall::generateSSHKeys() { int i; string cmd; QString pwd = QDir::currentPath(); string filename; string hostKey_file; string fwadmin_keyfilename; QFile file (filename.c_str()); /* TODO: Rewrite with popen for error handling */ /* Generate RSA Keys */ filename = fw->getName() + "/" + ssh_dir + "/ssh_host_rsa_key"; if (!QFile::exists(filename.c_str())) { cmd = "ssh-keygen -t rsa -b 2048 -f " + pwd.toStdString() + "/" + filename + " -C root@" + fw->getName() + " -P \"\" 2>&1"; i = system(cmd.c_str()); } else { cout << " Found existing RSA key: skipping key generation." << endl; } /* Generate DSA Keys */ filename = fw->getName() + "/" + ssh_dir + "/ssh_host_dsa_key"; if (!QFile::exists(filename.c_str())) { cmd = "ssh-keygen -t dsa -f " + pwd.toStdString() + "/" + filename + " -C root@" + fw->getName() + " -P \"\" 2>&1"; i = system(cmd.c_str()); } else { cout << " Found existing DSA key: skipping key generation." << endl; } /* Add RSA pub key of fwadmin to the firewall's known hosts file */ fwadmin_keyfilename = getenv("HOME"); fwadmin_keyfilename += fwadmin_ssh_key; QFile fwadmin_ssh_keyfile(fwadmin_keyfilename.c_str()); filename = pwd.toStdString() + "/" + fw->getName() + "/" + ssh_dir + "/authorized_keys2"; if (!QFile::exists(filename.c_str())) { if (fwadmin_ssh_keyfile.open(QIODevice::ReadOnly)) { /* Temporary storage for file content */ QString stream_string; QTextStream stream(&stream_string); stream << fwadmin_ssh_keyfile.readAll(); fwadmin_ssh_keyfile.close(); /* Write actual authorized_keys2 file */ stringToFile(stream.string()->toStdString(), fw->getName() + "/" + ssh_dir + "/authorized_keys2"); QFile::setPermissions (filename.c_str(), QFile::ReadOwner|QFile::ReadGroup); } else { cout << " Unable to open " << fwadmin_keyfilename << endl; } } else { cout << " Found existing key authorization file: skipping addition of management key." << endl; } /* Add RSA host key of firewall to the fwadmin's known hosts file */ string hostKey_filename = getenv("HOME"); hostKey_filename += fwadmin_known_hosts; QFile host_key_file(hostKey_filename.c_str()); bool keyPresent = false; /* Check if hosts key file exists */ if (host_key_file.exists()) { /* Check if key entry is present */ host_key_file.open(QIODevice::ReadOnly); QTextStream known_hosts(&host_key_file); QString tmp; while(!known_hosts.atEnd()) { known_hosts >> tmp; if (containsFirewallKey(tmp.toStdString())) keyPresent = true; } host_key_file.close(); } if (!keyPresent) { filename = pwd.toStdString() + "/" + fw->getName() + "/" + ssh_dir + "/ssh_host_rsa_key.pub"; QFile ssh_keyfile(filename.c_str()); if (ssh_keyfile.open(QIODevice::ReadOnly)) { /* Temporary storage for file content */ QString stream_string; QTextStream stream(&stream_string); stream << fw->getName().c_str() << " "; stream << ssh_keyfile.readAll(); ssh_keyfile.close(); /* Append entry to authorized_keys2 file */ stringToFile(stream.string()->toStdString(), hostKey_filename, QIODevice::Append); } else { cout << " Unable to open firewall public key" << endl; } } else { cout << " Found existing authorization entry: skipping addition of firewall key." << endl; } cout << " generated SSH keys successfully" << endl << flush; return 0; } /* TODO: Put in utility library */ bool OSConfigurator_secuwall::containsFirewallKey(string in) const { string match = "root@"+fw->getName(); if (match == in) return true; else return false; } string OSConfigurator_secuwall::printPathForAllTools(const string &) { return OSConfigurator_linux24::printPathForAllTools("secuwall"); } map OSConfigurator_secuwall::getGeneratedFiles() const { map files; return files; } fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_linux24.h0000644000175000017500000001121711733011756023514 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCONFIGURATOR_LINUX24_HH #define _OSCONFIGURATOR_LINUX24_HH #include "config.h" #include "fwcompiler/OSConfigurator.h" #include "OSData.h" class QString; class QStringList; namespace libfwbuilder { class FWObject; class MultiAddressRunTime; }; class Configlet; namespace fwcompiler { class OSConfigurator_linux24 : public OSConfigurator { OSData os_data; Configlet *command_wrappers; bool using_ipset; std::map address_table_objects; // this vector is used to avoid duplication of virtual addresses for nat std::vector virtual_addresses; // map of virt. addresses for nat for each interface std::map virtual_addresses_for_nat; std::list known_interfaces; std::string getInterfaceVarName(libfwbuilder::FWObject *iface, bool v6=false); std::string getPathForATool(const std::string &os_variant, OSData::tools tool_name); void setConfigletMacroForOptionStr(const std::string &opt, Configlet *c, const char *option_name); void setConfigletMacroForOptionInt(int opt, Configlet *c, const char *option_name); virtual QString addressTableWrapper(libfwbuilder::FWObject *rule, const QString &command, bool ipv6=false); virtual QString printUpdateAddressCommand( libfwbuilder::Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses); public: virtual ~OSConfigurator_linux24(); OSConfigurator_linux24(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy); virtual std::string myPlatformName(); virtual int prolog(); virtual void epilog(); bool usingIpSetModule() { return using_ipset; } /* * Try to find conflicts in subinterface types and unsupported * interface configurations. */ virtual bool validateInterfaces(); virtual void processFirewallOptions(); virtual std::string generateCodeForProtocolHandlers(); virtual void addVirtualAddressForNAT(const libfwbuilder::Address *addr); virtual void addVirtualAddressForNAT(const libfwbuilder::Network *nw); virtual void registerMultiAddressObject(libfwbuilder::MultiAddressRunTime *at); virtual std::string printShellFunctions(bool have_ipv6); virtual std::string printPathForAllTools(const std::string &os); virtual std::string printIPForwardingCommands(); virtual std::string printRunTimeWrappers(libfwbuilder::FWObject *rule, const std::string &command, bool ipv6=false); virtual std::string printVerifyInterfacesCommands(); virtual std::string printVirtualAddressesForNatCommands(); virtual std::string printInterfaceConfigurationCommands(); virtual std::string printCommandsToClearKnownInterfaces(); virtual std::string printVlanInterfaceConfigurationCommands(); virtual std::string printBridgeInterfaceConfigurationCommands(); virtual std::string printBondingInterfaceConfigurationCommands(); virtual std::string printDynamicAddressesConfigurationCommands(); virtual std::string printRunTimeAddressTablesCode(); virtual std::map getGeneratedFiles() const; std::string normalizeSetName(const std::string &txt); }; }; #endif fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_linux24.cpp0000644000175000017500000005432311733011756024054 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "OSConfigurator_linux24.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/Resources.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "Configlet.h" #ifndef _WIN32 # include #endif #include #include #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_linux24::myPlatformName() { return "Linux24"; } OSConfigurator_linux24::OSConfigurator_linux24(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy) : OSConfigurator(_db, fw, ipv6_policy) , os_data(fw->getStr("host_OS")) { command_wrappers = new Configlet(fw, "linux24", "run_time_wrappers"); FWOptions* fwopt = fw->getOptionsObject(); string version = fw->getStr("version"); using_ipset = (XMLTools::version_compare(version, "1.4.1.1") >= 0 && fwopt->getBool("use_m_set")); } OSConfigurator_linux24::~OSConfigurator_linux24() { delete command_wrappers; } /* * this function generates acceptable shell variable name from * interface name. Note that PolicyCompiler_ipt::getInterfaceVarName() * and NATCompiler_ipt::getInterfaceVarName do the same thing and * these functions should be identical. * * TODO: really need to have one function for this instead of three in * three different classes. */ string OSConfigurator_linux24::getInterfaceVarName(FWObject *iface, bool v6) { ostringstream ostr; string iname=iface->getName(); string::size_type p1; while ( (p1=iname.find("."))!=string::npos) iname=iname.replace(p1,1,"_"); while ( (p1=iname.find("-"))!=string::npos) iname=iname.replace(p1,1,"_"); ostr << "i_" << iname; if (v6) ostr << "_v6"; return ostr.str(); } void OSConfigurator_linux24::setConfigletMacroForOptionStr( const string &s, Configlet *c, const char *option_name) { // "" means no change, do not include the command in the script if (!s.empty()) { c->setVariable(QString("if_") + option_name, 1); c->setVariable(option_name, s.c_str()); } else { c->setVariable(QString("if_") + option_name, 0); c->setVariable(option_name, s.c_str()); } } void OSConfigurator_linux24::setConfigletMacroForOptionInt( int val, Configlet *c, const char *option_name) { // -1 means no change, do not include the command in the script if (val >= 0) { c->setVariable(QString("if_") + option_name, 1); c->setVariable(option_name, val); } else { c->setVariable(QString("if_") + option_name, 0); c->setVariable(option_name, 0); } } void OSConfigurator_linux24::processFirewallOptions() { Configlet kernel_vars(fw, "linux24", "kernel_vars"); kernel_vars.removeComments(); kernel_vars.collapseEmptyStrings(true); FWOptions* options = fw->getOptionsObject(); setConfigletMacroForOptionStr(options->getStr("linux24_ip_dynaddr"), &kernel_vars, "linux24_ip_dynaddr"); setConfigletMacroForOptionStr(options->getStr("linux24_rp_filter"), &kernel_vars, "linux24_rp_filter"); setConfigletMacroForOptionStr(options->getStr("linux24_accept_source_route"), &kernel_vars, "linux24_accept_source_route"); setConfigletMacroForOptionStr(options->getStr("linux24_accept_redirects"), &kernel_vars, "linux24_accept_redirects"); setConfigletMacroForOptionStr(options->getStr("linux24_log_martians"), &kernel_vars, "linux24_log_martians"); setConfigletMacroForOptionStr(options->getStr("linux24_icmp_echo_ignore_broadcasts"), &kernel_vars, "linux24_icmp_echo_ignore_broadcasts"); setConfigletMacroForOptionStr(options->getStr("linux24_icmp_echo_ignore_all"), &kernel_vars, "linux24_icmp_echo_ignore_all"); setConfigletMacroForOptionStr(options->getStr("linux24_icmp_ignore_bogus_error_responses"), &kernel_vars, "linux24_icmp_ignore_bogus_error_responses"); setConfigletMacroForOptionStr(options->getStr("linux24_tcp_window_scaling"), &kernel_vars, "linux24_tcp_window_scaling"); setConfigletMacroForOptionStr(options->getStr("linux24_tcp_sack"), &kernel_vars, "linux24_tcp_sack"); setConfigletMacroForOptionStr(options->getStr("linux24_tcp_fack"), &kernel_vars, "linux24_tcp_fack"); setConfigletMacroForOptionStr(options->getStr("linux24_tcp_syncookies"), &kernel_vars, "linux24_tcp_syncookies"); setConfigletMacroForOptionStr(options->getStr("linux24_tcp_ecn"), &kernel_vars, "linux24_tcp_ecn"); setConfigletMacroForOptionStr(options->getStr("linux24_tcp_timestamps"), &kernel_vars, "linux24_tcp_timestamps"); int opt = options->getInt("linux24_tcp_fin_timeout"); setConfigletMacroForOptionInt((opt==0)?-1:opt, &kernel_vars, "linux24_tcp_fin_timeout"); opt = options->getInt("linux24_tcp_keepalive_interval"); setConfigletMacroForOptionInt((opt==0)?-1:opt, &kernel_vars, "linux24_tcp_keepalive_interval"); Configlet conntrack_vars(fw, "linux24", "conntrack"); conntrack_vars.removeComments(); conntrack_vars.collapseEmptyStrings(true); string version = fw->getStr("version"); bool version_ge_1_4 = XMLTools::version_compare(version, "1.4.0") >= 0; conntrack_vars.setVariable("iptables_version_ge_1_4", version_ge_1_4); conntrack_vars.setVariable("iptables_version_lt_1_4", !version_ge_1_4); // if conntrack_max and conntrack_hashsize are equal to 0, we do // not add commands from the configlet (so the kernel defaults are // used). Options above assume -1 is the default. Need to pass -1 // instead of 0 for the conntrack vars opt = options->getInt("linux24_conntrack_max"); setConfigletMacroForOptionInt( (opt==0)?-1:opt, &conntrack_vars, "conntrack_max"); opt = options->getInt("linux24_conntrack_hashsize"); setConfigletMacroForOptionInt( (opt==0)?-1:opt, &conntrack_vars, "conntrack_hashsize"); // This option uses three-state control and assumes empty string is the default setConfigletMacroForOptionStr( options->getStr("linux24_conntrack_tcp_be_liberal"), &conntrack_vars, "conntrack_tcp_be_liberal"); output << kernel_vars.expand().toStdString(); output << endl; output << conntrack_vars.expand().toStdString(); } void OSConfigurator_linux24::addVirtualAddressForNAT(const Network *nw) { FWOptions* options=fw->getOptionsObject(); if (options->getBool("manage_virtual_addr")) { if (virtual_addresses.empty() || find(virtual_addresses.begin(),virtual_addresses.end(), *(nw->getAddressPtr())) == virtual_addresses.end()) { Interface *iface = findInterfaceFor( nw, fw ); if (iface!=NULL) { const InetAddr *addr = nw->getAddressPtr(); InetAddr first, last; InetAddr a; first = *addr; last = *(nw->getBroadcastAddressPtr()); QStringList addresses; for (a=first; agetName()) > 0) addresses.push_front(virtual_addresses_for_nat[iface->getName()].c_str()); virtual_addresses_for_nat[iface->getName()] = addresses.join(" ").toStdString(); virtual_addresses.push_back( *(nw->getAddressPtr()) ); registerVirtualAddressForNat(); } else warning("Can not add virtual address " + nw->getAddressPtr()->toString() + " (object " + nw->getName() + ")" ); } } } void OSConfigurator_linux24::addVirtualAddressForNAT(const Address *addr) { FWOptions* options=fw->getOptionsObject(); if ( options->getBool("manage_virtual_addr") ) { const InetAddr *addr_addr = addr->getAddressPtr(); if (virtual_addresses.empty() || find(virtual_addresses.begin(), virtual_addresses.end(), *addr_addr) == virtual_addresses.end()) { FWObject *vaddr = findAddressFor(addr, fw ); if (vaddr!=NULL) { Interface *iface = Interface::cast(vaddr->getParent()); assert(iface!=NULL); QStringList addresses; const InetAddr *vaddr_netm = Address::cast(vaddr)->getNetmaskPtr(); addresses.push_back(QString("%1/%2"). arg(addr_addr->toString().c_str()). arg(vaddr_netm->getLength())); if (virtual_addresses_for_nat.count(iface->getName()) > 0) addresses.push_front(virtual_addresses_for_nat[iface->getName()].c_str()); virtual_addresses_for_nat[iface->getName()] = addresses.join(" ").toStdString(); virtual_addresses.push_back(*(addr_addr)); registerVirtualAddressForNat(); } else warning("Can not add virtual address for object " + addr->getName()); } return; } } string OSConfigurator_linux24::normalizeSetName(const string &txt) { QString table_name = txt.c_str(); table_name.replace(QRegExp("[ +*!#|]"), "_"); return table_name.toStdString(); } void OSConfigurator_linux24::registerMultiAddressObject(MultiAddressRunTime *at) { // std::map address_table_objects[normalizeSetName(at->getName())] = at->getSourceName(); } int OSConfigurator_linux24::prolog() { return 0; } /** * Print shell functions used by the script. If argument (boolean) is true, * do not add comments. */ string OSConfigurator_linux24::printShellFunctions(bool have_ipv6) { QStringList output; FWOptions* options = fw->getOptionsObject(); // string host_os = fw->getStr("host_OS"); // string os_family = Resources::os_res[host_os]-> // getResourceStr("/FWBuilderResources/Target/family"); Configlet shell_functions(fw, "linux24", "shell_functions"); output.push_back(shell_functions.expand()); /* check if package iproute2 is installed, but do this only if * we really need /usr/sbin/ip */ Configlet configlet(fw, "linux24", "check_utilities"); configlet.removeComments(); configlet.collapseEmptyStrings(true); configlet.setVariable("load_modules", options->getBool("load_modules")); if (options->getBool("load_modules") || options->getBool("configure_vlan_interfaces") || options->getBool("configure_bonding_interfaces")) { configlet.setVariable("need_modprobe", true); } if (options->getBool("verify_interfaces") || options->getBool("manage_virtual_addr") || options->getBool("configure_interfaces") ) { configlet.setVariable("need_vconfig", options->getBool("configure_vlan_interfaces")); configlet.setVariable("need_brctl", options->getBool("configure_bridge_interfaces")); configlet.setVariable("need_ifenslave", options->getBool("configure_bonding_interfaces")); } configlet.setVariable("need_ipset", using_ipset); configlet.setVariable("need_iptables_restore", options->getBool("use_iptables_restore")); configlet.setVariable("need_ip6tables_restore", have_ipv6 && options->getBool("use_iptables_restore")); output.push_back(configlet.expand()); /* * Generate commands to reset all tables and chains and set * default policy */ Configlet reset_iptables(fw, "linux24", "reset_iptables"); output.push_back(reset_iptables.expand()); Configlet addr_conf(fw, "linux24", "update_addresses"); output.push_back(addr_conf.expand()); if (options->getBool("configure_vlan_interfaces")) { Configlet conf(fw, "linux24", "update_vlans"); output.push_back(conf.expand()); } if (options->getBool("configure_bridge_interfaces")) { Configlet conf(fw, "linux24", "update_bridge"); output.push_back(conf.expand()); } if (options->getBool("configure_bonding_interfaces")) { Configlet conf(fw, "linux24", "update_bonding"); output.push_back(conf.expand()); } return output.join("\n").toStdString(); } string OSConfigurator_linux24::printRunTimeAddressTablesCode() { Configlet conf(fw, "linux24", "run_time_address_tables"); conf.setVariable("using_ipset", using_ipset); ostringstream check_ostr; ostringstream load_ostr; map::iterator i; for (i=address_table_objects.begin(); i!=address_table_objects.end(); ++i) { string at_name = i->first; string at_file = i->second; // If the file name is empty, this run-time table is // completely controlled by the user outside fwbuilder so we // do not need to add commands to check if the file exits and // load it if (!at_file.empty()) { check_ostr << "check_file \"" + at_name + "\" \"" + at_file + "\"" << endl; load_ostr << "reload_address_table \"" + at_name + "\" \"" + at_file + "\"" << endl; } } conf.setVariable("check_files_commands", check_ostr.str().c_str()); conf.setVariable("load_files_commands", load_ostr.str().c_str()); return conf.expand().toStdString(); } string OSConfigurator_linux24::getPathForATool(const std::string &os_variant, OSData::tools tool_name) { FWOptions* options = fw->getOptionsObject(); string attr = os_data.getAttributeNameForTool(tool_name); string s = options->getStr("linux24_" + attr); if (!s.empty()) return s; string host_os = fw->getStr("host_OS"); string r = "/FWBuilderResources/Target/tools/" + os_variant + "/" + attr; if (Resources::os_res[host_os]->getResourceStr(r).empty()) r = "/FWBuilderResources/Target/tools/Unknown/" + attr; return Resources::os_res[host_os]->getResourceStr(r); } string OSConfigurator_linux24::printPathForAllTools(const string &os) { ostringstream res; list::const_iterator i; const list &all_tools = os_data.getAllTools(); for (i=all_tools.begin(); i!=all_tools.end(); ++i) res << os_data.getVariableName(OSData::tools(*i)) << "=\"" << getPathForATool(os, OSData::tools(*i)) << "\"" << endl; return res.str(); } string OSConfigurator_linux24::generateCodeForProtocolHandlers() { FWOptions* options = fw->getOptionsObject(); bool nomod = Resources::os_res[fw->getStr("host_OS")]-> Resources::getResourceBool("/FWBuilderResources/Target/options/suppress_modules"); // string host_os = fw->getStr("host_OS"); // string os_family = Resources::os_res[host_os]-> // getResourceStr("/FWBuilderResources/Target/family"); Configlet load_modules(fw, "linux24", "load_modules"); load_modules.removeComments(); // See ticket #2 string modules_dir = Resources::os_res[fw->getStr("host_OS")]-> Resources::getResourceStr("/FWBuilderResources/Target/options/default/modules_dir"); /* there is no need to load modules on some platforms */ load_modules.setVariable("load_modules", options->getBool("load_modules") && !nomod); load_modules.setVariable("modules_dir", modules_dir.c_str()); return load_modules.expand().toStdString(); } QString OSConfigurator_linux24::addressTableWrapper(FWObject *rule, const QString &command, bool ipv6) { QString combined_command = command; QRegExp address_table_re("\\$at_(\\S+)"); int pos = address_table_re.indexIn(command); if (pos > -1) { QStringList command_lines = QString(command).split("\n", QString::SkipEmptyParts); if (command_lines.size() > 1) { command_lines.push_front("{"); command_lines.push_back("}"); } combined_command = command_lines.join("\n"); command_wrappers->clear(); command_wrappers->removeComments(); command_wrappers->collapseEmptyStrings(true); command_wrappers->setVariable("ipv6", ipv6); QString at_var = address_table_re.cap(1); QString at_file = rule->getStr("address_table_file").c_str(); command_wrappers->setVariable("address_table_file", at_file); command_wrappers->setVariable("address_table_var", at_var); command_wrappers->setVariable("command", combined_command); command_wrappers->setVariable("address_table", true); command_wrappers->setVariable("wildcard_interface", false); command_wrappers->setVariable("no_dyn_addr", false); command_wrappers->setVariable("one_dyn_addr", false); command_wrappers->setVariable("two_dyn_addr", false); combined_command = command_wrappers->expand(); } return combined_command; } string OSConfigurator_linux24::printRunTimeWrappers(FWObject *rule, const string &command, bool ipv6) { /* if anywhere in command_line we used variable holding an address of * dynamic interface (named $i_something) then we need to add this * command with a check for the value of this variable. We execute * iptables command only if the value is a non-empty string. * * bug #1851166: there could be two dynamic interfaces in the same * rule. */ bool wildcard_interface = false; QString combined_command; if (using_ipset) combined_command = command.c_str(); else combined_command = addressTableWrapper(rule, command.c_str(), ipv6); command_wrappers->clear(); command_wrappers->removeComments(); command_wrappers->collapseEmptyStrings(true); command_wrappers->setVariable("ipv6", ipv6); command_wrappers->setVariable("address_table", false); QRegExp intf_re("\\$i_([^ :]+)"); QStringList iface_names; QStringList iface_vars; int pos = -1; while ((pos = intf_re.indexIn(combined_command, pos + 1)) > -1) { QString name = intf_re.cap(1); int match_len = intf_re.matchedLength(); iface_names.push_back(name); iface_vars.push_back("$i_" + name); if (name.contains("*")) { wildcard_interface = true; QString intf_family = name.section('*', 0, 0); command_wrappers->setVariable("interface_family_name", intf_family); // replace $i_ppp* with $addr. This must match shell code // in the configlet run_time_wrappers combined_command.replace(pos, match_len, "$addr"); break; } } bool no_wrapper = !wildcard_interface && iface_names.size() == 0; if (!no_wrapper) { QStringList command_lines = QString(combined_command).split("\n", QString::SkipEmptyParts); if (command_lines.size() > 1) { command_lines.push_front("{"); command_lines.push_back("}"); } combined_command = command_lines.join("\n"); } command_wrappers->setVariable("no_wrapper", no_wrapper); command_wrappers->setVariable("wildcard_interface", wildcard_interface); command_wrappers->setVariable("one_dyn_addr", !wildcard_interface && iface_names.size() == 1); command_wrappers->setVariable("two_dyn_addr", !wildcard_interface && iface_names.size() > 1); for (int idx=0; idxsetVariable(QString("intf_%1_var_name").arg(idx+1), intf_name); } command_wrappers->setVariable("command", combined_command); return command_wrappers->expand().toStdString() + "\n"; } string OSConfigurator_linux24::printIPForwardingCommands() { /* Turn on packet forwarding if we have to */ // string os_family = Resources::os_res[fw->getStr("host_OS")]-> // getResourceStr("/FWBuilderResources/Target/family"); FWOptions* options = fw->getOptionsObject(); Configlet ip_forwarding(fw, "linux24", "ip_forwarding"); ip_forwarding.removeComments(); ip_forwarding.collapseEmptyStrings(true); string s = options->getStr("linux24_ip_forward"); ip_forwarding.setVariable("ipv4", !s.empty()); ip_forwarding.setVariable("ipv4_forw", (s=="1" || s=="On" || s=="on")?1:0); s = options->getStr("linux24_ipv6_forward"); ip_forwarding.setVariable("ipv6", !s.empty()); ip_forwarding.setVariable("ipv6_forw", (s=="1" || s=="On" || s=="on")?1:0); return ip_forwarding.expand().toStdString(); } void OSConfigurator_linux24::epilog() { } map OSConfigurator_linux24::getGeneratedFiles() const { map files; return files; } fwbuilder-5.1.0.3599/src/iptlib/AutomaticRules_ipt.cpp0000644000175000017500000004562511733011756023405 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AutomaticRules_ipt.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Policy.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/IPService.h" #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; PolicyRule* AutomaticRules_ipt::addMgmtRule( Address* src, Address* dst, Service* service, Interface* iface, const PolicyRule::Direction direction, const PolicyRule::Action action, const string &label, bool related) { PolicyRule *rule = AutomaticRules::addMgmtRule(src, dst, service, iface, direction, action, label); FWOptions *ruleopt = rule->getOptionsObject(); assert(ruleopt!=NULL); if (related) { ruleopt->setBool("stateless", false); ruleopt->setBool("accept_established", true); } else { ruleopt->setBool("stateless", true); } ruleopt->setBool("firewall_is_part_of_any_and_networks", true); return rule; } void AutomaticRules_ipt::addConntrackRule() { if (ruleset == NULL) return; FWOptions* options = fw->getOptionsObject(); string conntrack_iface_name = options->getStr("state_sync_interface"); if (conntrack_iface_name.empty()) { /* CONNTRACK not active, nothing left to do */ return; } string conntrack_group_id = options->getStr("state_sync_group_id"); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast( ruleset->getRoot()->findInIndex( FWObjectDatabase::getIntId(conntrack_group_id))); Resources *os_res = Resources::os_res[fw->getStr("host_OS")]; assert(os_res != NULL); string default_address = os_res->getResourceStr("/FWBuilderResources/Target/protocols/conntrack/default_address"); string default_port = os_res->getResourceStr("/FWBuilderResources/Target/protocols/conntrack/default_port"); bool ucast = state_sync_group->getOptionsObject()->getBool("conntrack_unicast"); string addr = state_sync_group->getOptionsObject()->getStr("conntrack_address"); if (addr.empty()) addr = default_address; try { InetAddr(addr); } catch (FWException &ex) { try { InetAddr(AF_INET6, addr); } catch (FWException &ex) { throw FWException(string("Invalid IP address for conntrack: ") + addr); } } string port = state_sync_group->getOptionsObject()->getStr("conntrack_port"); if (port.empty()) port = default_port; /* Add CONNTRACK-Address to database */ Address *conntrack_dst = Address::cast(ruleset->getRoot()->create(IPv4::TYPENAME)); conntrack_dst->setName("CONNTRACK-Address"); conntrack_dst->setAddress(InetAddr(addr)); // Why the whole multicast adress range ? //conntrack_dst->setNetmask(InetAddr("240.0.0.0")); conntrack_dst->setComment("CONNTRACK Multicast Address"); persistent_objects->add(conntrack_dst); UDPService *conntrack_srv = UDPService::cast(ruleset->getRoot()->create(UDPService::TYPENAME)); conntrack_srv->setName("CONNTRACK-UDP"); conntrack_srv->setDstRangeStart(atoi(port.c_str())); conntrack_srv->setDstRangeEnd(atoi(port.c_str())); conntrack_srv->setComment("CONNTRACK UDP port"); persistent_objects->add(conntrack_srv); /* Find conntrack interface */ Interface* conntrack_iface = Interface::cast(fw->findObjectByName(Interface::TYPENAME, conntrack_iface_name)); if (conntrack_iface == NULL) { throw FWException( "Unable to get CONNTRACK interface ("+ conntrack_iface_name +")"); } /* Add automatic rules for CONNTRACK */ if (ucast) { Interface *fw_iface = NULL; list other_interfaces; for (FWObjectTypedChildIterator it = state_sync_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *iface = Interface::cast(FWObjectReference::getObject(*it)); assert(iface); if (iface->isChildOf(fw)) { fw_iface = iface; } else { other_interfaces.push_back(iface); } } for (list::iterator it=other_interfaces.begin(); it!=other_interfaces.end(); ++it) { Interface *other_iface = *it; addMgmtRule(other_iface, fw, conntrack_srv, fw_iface, PolicyRule::Inbound, PolicyRule::Accept, "CONNTRACK"); addMgmtRule(fw, other_iface, conntrack_srv, fw_iface, PolicyRule::Outbound, PolicyRule::Accept, "CONNTRACK"); } } else { addMgmtRule(NULL, conntrack_dst, conntrack_srv, conntrack_iface, PolicyRule::Inbound, PolicyRule::Accept, "CONNTRACK"); addMgmtRule(fw, conntrack_dst, conntrack_srv, conntrack_iface, PolicyRule::Outbound, PolicyRule::Accept, "CONNTRACK"); } } void AutomaticRules_ipt::addFailoverRules() { if (ruleset == NULL) return; Resources *os_res = Resources::os_res[fw->getStr("host_OS")]; assert(os_res != NULL); string default_heartbeat_port = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/heartbeat/default_port"); string default_heartbeat_address = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/heartbeat/default_address"); string default_openais_port = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/openais/default_port"); string default_openais_address = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/openais/default_address"); list interfaces = fw->getByTypeDeep(Interface::TYPENAME); interfaces.sort(FWObjectNameCmpPredicate()); list::iterator iface_i; for (iface_i=interfaces.begin(); iface_i != interfaces.end(); ++iface_i) { Interface *iface = Interface::cast(*iface_i); /* We add copies of cluster interface objects to fw objects so each interface appears twice, the original interface of the firewall, plus a copy of the cluster interface. To deduplicate will use only copies of cluster interfaces because these include VRRP interfaces. */ if (iface->isFailoverInterface() && iface->getOptionsObject()->getBool("cluster_interface")) { FWObject *failover_group = iface->getFirstByType(FailoverClusterGroup::TYPENAME); PolicyRule *rule = NULL; string fw_iface_id = iface->getOptionsObject()->getStr("base_interface_id"); Interface *fw_iface = Interface::cast( ruleset->getRoot()->findInIndex(FWObjectDatabase::getIntId(fw_iface_id))); if (fw_iface == NULL) { throw FWException( QString("Can not find interface of the firewall " "for the cluster failover group %1. ") .arg(failover_group->getName().c_str()).toStdString()); } if (failover_group->getStr("type") == "vrrp") { /* Add VRRP-Address to database */ Address *vrrp_dst = Address::cast( ruleset->getRoot()->create(IPv4::TYPENAME)); vrrp_dst->setName("VRRP-Address"); vrrp_dst->setAddress(InetAddr("224.0.0.18")); vrrp_dst->setNetmask(InetAddr(InetAddr::getAllOnes())); vrrp_dst->setComment("VRRP Multicast Address"); persistent_objects->add(vrrp_dst); bool use_ipsec_ah = false; FWOptions *failover_opts = FailoverClusterGroup::cast(failover_group)->getOptionsObject(); if (failover_opts) { use_ipsec_ah = failover_opts->getBool("vrrp_over_ipsec_ah"); } /* Add VRRP-Service to database */ IPService* vrrp_srv = IPService::cast( ruleset->getRoot()->create(IPService::TYPENAME)); vrrp_srv->setComment("VRRP service"); vrrp_srv->setProtocolNumber(112); persistent_objects->add(vrrp_srv); /* * Add AH-Service to database. * According to RFC 2338 section 5.3.6.3, VRRP can use * IPsec AH. */ IPService* ah_srv = IPService::cast( ruleset->getRoot()->create(IPService::TYPENAME)); ah_srv->setComment("IPSEC-AH"); ah_srv->setProtocolNumber(51); persistent_objects->add(ah_srv); for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *other_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(other_iface); if (other_iface->getId() == fw_iface->getId()) continue; // if interface is dynamic, we can't use it in the rule // (because it belongs to another machine, not the fw // we compile for so we can't use script). NULL means "any" // in the call to addMgmtRule() if (other_iface->isDyn()) other_iface = NULL; if (!use_ipsec_ah) { addMgmtRule(other_iface, vrrp_dst, vrrp_srv, iface, PolicyRule::Inbound, PolicyRule::Accept, "VRRP"); } else { addMgmtRule(other_iface, vrrp_dst, ah_srv, iface, PolicyRule::Inbound, PolicyRule::Accept, "VRRP (with IPSEC-AH)"); } } // outbound rule does not use other_interface and // should be created outside the loop to avoid // duplicates. Duplicates happen when cluster has 3 or // more members. if (!use_ipsec_ah) { addMgmtRule(fw, vrrp_dst, vrrp_srv, iface, PolicyRule::Outbound, PolicyRule::Accept, "VRRP"); } else { addMgmtRule(fw, vrrp_dst, ah_srv, iface, PolicyRule::Outbound, PolicyRule::Accept, "VRRP (with IPSEC-AH)"); } } if (failover_group->getStr("type") == "heartbeat") { /* * Note that iface is a copy of the cluster inetrface. * Find interface of the member firewall fw that corresponds * to the cluster interface iface */ bool ucast = FailoverClusterGroup::cast(failover_group)-> getOptionsObject()->getBool("heartbeat_unicast"); string addr = FailoverClusterGroup::cast(failover_group)-> getOptionsObject()->getStr("heartbeat_address"); if (addr.empty()) addr = default_heartbeat_address; string port = FailoverClusterGroup::cast(failover_group)-> getOptionsObject()->getStr("heartbeat_port"); if (port.empty()) port = default_heartbeat_port; UDPService *heartbeat_srv = UDPService::cast( ruleset->getRoot()->create(UDPService::TYPENAME)); /* Add heartbeat-Address to database */ Address *heartbeat_dst = Address::cast(ruleset->getRoot()->create( IPv4::TYPENAME)); heartbeat_dst->setName("HEARTBEAT-Address"); heartbeat_dst->setAddress(InetAddr(addr)); heartbeat_dst->setNetmask(InetAddr(InetAddr::getAllOnes())); heartbeat_dst->setComment("HEARTBEAT Multicast Address"); persistent_objects->add(heartbeat_dst); heartbeat_srv->setName("HEARTBEAT-UDP"); heartbeat_srv->setDstRangeStart(atoi(port.c_str())); heartbeat_srv->setDstRangeEnd(atoi(port.c_str())); heartbeat_srv->setComment("HEARTBEAT UDP port"); persistent_objects->add(heartbeat_srv); // Heartbeat can use either multicast or unicast for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *other_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(other_iface); if (other_iface->getId() == fw_iface->getId()) continue; // if interface is dynamic, we can't use it in the rule // (because it belongs to another machine, not the fw // we compile for so we can't use script). NULL means "any" // in the call to addMgmtRule() if (other_iface->isDyn()) other_iface = NULL; if (ucast) { addMgmtRule(other_iface, fw, heartbeat_srv, fw_iface, PolicyRule::Inbound, PolicyRule::Accept, "heartbeat"); addMgmtRule(fw, other_iface, heartbeat_srv, fw_iface, PolicyRule::Outbound, PolicyRule::Accept, "heartbeat"); } else { addMgmtRule(other_iface, heartbeat_dst, heartbeat_srv, fw_iface, PolicyRule::Inbound, PolicyRule::Accept, "heartbeat"); addMgmtRule(fw, heartbeat_dst, heartbeat_srv, fw_iface, PolicyRule::Outbound, PolicyRule::Accept, "heartbeat"); } } } if (failover_group->getStr("type") == "openais") { string addr = FailoverClusterGroup::cast(failover_group)-> getOptionsObject()->getStr("openais_address"); if (addr.empty()) addr = default_openais_address; string port = FailoverClusterGroup::cast(failover_group)-> getOptionsObject()->getStr("openais_port"); if (port.empty()) port = default_openais_port; /* Add OPENAIS-Address to database */ Address *openais_dst = Address::cast(ruleset->getRoot()->create( IPv4::TYPENAME)); openais_dst->setName("OPENAIS-Address"); openais_dst->setAddress(InetAddr(addr)); openais_dst->setNetmask(InetAddr(InetAddr::getAllOnes())); openais_dst->setComment("OPENAIS Multicast Address"); persistent_objects->add(openais_dst); UDPService *openais_srv = UDPService::cast( ruleset->getRoot()->create(UDPService::TYPENAME)); openais_srv->setName("OPENAIS-UDP"); openais_srv->setDstRangeStart(atoi(port.c_str())); openais_srv->setDstRangeEnd(atoi(port.c_str())); openais_srv->setComment("OPENAIS UDP port"); persistent_objects->add(openais_srv); for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *other_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(other_iface); if (other_iface->getId() == fw_iface->getId()) continue; // if interface is dynamic, we can't use it in the rule // (because it belongs to another machine, not the fw // we compile for so we can't use script). NULL means "any" // in the call to addMgmtRule() if (other_iface->isDyn()) other_iface = NULL; addMgmtRule(other_iface, openais_dst, openais_srv, iface, PolicyRule::Inbound, PolicyRule::Accept, "openais"); addMgmtRule(fw, openais_dst, openais_srv, iface, PolicyRule::Outbound, PolicyRule::Accept, "openais"); } } if (rule) { FWOptions *ruleopt = rule->getOptionsObject(); assert(ruleopt!=NULL); ruleopt->setInt("firewall_is_part_of_any_and_networks", 1); } } } } fwbuilder-5.1.0.3599/src/iptlib/OSData.cpp0000644000175000017500000000507511733011756020676 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSData.h" using namespace std; OSData::OSData(const std::string &ho) { host_os = ho; attribute_names[LSMOD] = "path_lsmod"; attribute_names[MODPROBE] = "path_modprobe"; attribute_names[IPTABLES] = "path_iptables"; attribute_names[IP6TABLES] = "path_ip6tables"; attribute_names[IPTABLES_RESTORE] = "path_iptables_restore"; attribute_names[IP6TABLES_RESTORE] = "path_ip6tables_restore"; attribute_names[IP] = "path_ip"; attribute_names[IFCONFIG] = "path_ifconfig"; attribute_names[VCONFIG] = "path_vconfig"; attribute_names[BRCTL] = "path_brctl"; attribute_names[IFENSLAVE] = "path_ifenslave"; attribute_names[IPSET] = "path_ipset"; attribute_names[LOGGER] = "path_logger"; variable_names[LSMOD] = "LSMOD"; variable_names[MODPROBE] = "MODPROBE"; variable_names[IPTABLES] = "IPTABLES"; variable_names[IP6TABLES] = "IP6TABLES"; variable_names[IPTABLES_RESTORE] = "IPTABLES_RESTORE"; variable_names[IP6TABLES_RESTORE] = "IP6TABLES_RESTORE"; variable_names[IP] = "IP"; variable_names[IFCONFIG] = "IFCONFIG"; variable_names[VCONFIG] = "VCONFIG"; variable_names[BRCTL] = "BRCTL"; variable_names[IFENSLAVE] = "IFENSLAVE"; variable_names[IPSET] = "IPSET"; variable_names[LOGGER] = "LOGGER"; all_tools.push_back(LSMOD); all_tools.push_back(MODPROBE); all_tools.push_back(IPTABLES); all_tools.push_back(IP6TABLES); all_tools.push_back(IPTABLES_RESTORE); all_tools.push_back(IP6TABLES_RESTORE); all_tools.push_back(IP); all_tools.push_back(IFCONFIG); all_tools.push_back(VCONFIG); all_tools.push_back(BRCTL); all_tools.push_back(IFENSLAVE); all_tools.push_back(IPSET); all_tools.push_back(LOGGER); } fwbuilder-5.1.0.3599/src/iptlib/PolicyCompiler_PrintRuleIptRst.cpp0000644000175000017500000000721711733011756025667 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_ipt.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ /* * check and create new chain if needed */ string PolicyCompiler_ipt::PrintRuleIptRst::_createChain(const string &chain) { string res; PolicyCompiler_ipt *ipt_comp = dynamic_cast(compiler); if (!minus_n_tracker_initialized) initializeMinusNTracker(); if ( ipt_comp->minus_n_commands->count(chain)==0 ) { if ( ! compiler->inSingleRuleCompileMode()) res = ":" + chain + " - [0:0]\n"; (*(ipt_comp->minus_n_commands))[chain] = true; } return res; } string PolicyCompiler_ipt::PrintRuleIptRst::_startRuleLine() { return string("-A "); } string PolicyCompiler_ipt::PrintRuleIptRst::_endRuleLine() { return string("\n"); } string PolicyCompiler_ipt::PrintRuleIptRst::_printRuleLabel(PolicyRule *rule) { bool nocomm = Resources::os_res[compiler->fw->getStr("host_OS")]->Resources::getResourceBool("/FWBuilderResources/Target/options/suppress_comments"); return compiler->printComment(rule, current_rule_label, "#", nocomm); #if 0 ostringstream res; string rl=rule->getLabel(); if (rl!=current_rule_label) { if (!compiler->inSingleRuleCompileMode() && !nocomm) { res << "# " << endl; res << "# Rule " << rl << endl; res << "# " << endl; } /* do not put comment in the script if it is intended for linksys */ if (!nocomm || compiler->inSingleRuleCompileMode()) { QStringList comm = QString(rule->getComment().c_str()).split("\n"); foreach(QString line, comm) { res << "# " << line.toStdString() << endl; } //res << "# " << endl; } current_rule_label=rl; } return res.str(); #endif } bool PolicyCompiler_ipt::PrintRuleIptRst::processNext() { if (print_once_on_top) { print_once_on_top=false; } return PolicyCompiler_ipt::PrintRule::processNext(); } string PolicyCompiler_ipt::PrintRuleIptRst::_declareTable() { PolicyCompiler_ipt *ipt_comp=dynamic_cast(compiler); ostringstream res; res << "*" << ipt_comp->my_table << endl; return res.str(); } string PolicyCompiler_ipt::PrintRuleIptRst::_commit() { return "COMMIT\n"; } string PolicyCompiler_ipt::PrintRuleIptRst::_quote(const string &s) { return "\"" + s + "\""; } fwbuilder-5.1.0.3599/src/iptlib/OSConfigurator_ipcop.h0000644000175000017500000000311611733011756023320 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id: OSConfigurator_linux24.h 752 2009-01-30 04:54:03Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSNETWORKCONFIGURATOR_IPCOP_HH #define _OSNETWORKCONFIGURATOR_IPCOP_HH #include "config.h" #include "OSConfigurator_linux24.h" #include "OSData.h" namespace fwcompiler { class OSConfigurator_ipcop : public OSConfigurator_linux24 { public: virtual ~OSConfigurator_ipcop() {}; OSConfigurator_ipcop(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy); virtual std::string myPlatformName(); virtual int prolog(); virtual void epilog(); virtual void addVirtualAddressForNAT(const libfwbuilder::Address *addr); virtual void addVirtualAddressForNAT(const libfwbuilder::Network *nw); }; } #endif fwbuilder-5.1.0.3599/src/res/0000755000175000017500000000000011733011756016356 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/templates.xml0000644000175000017500000077016311733011756021114 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/res/platform/0000755000175000017500000000000011733011756020202 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/platform/fwsm.xml0000644000175000017500000004010411733011756021677 0ustar sylvestresylvestre Cisco FWSM active Cisco fwb_pix

pix fwb_inst_pix fwb_pix_diff fwsm_os 2.3,3.2,4.x true true true true true true true info 300 false false false true true true true true true true true true info 300 true true true false false true false true true clear access-list clear object-group clear icmp clear telnet clear ssh clear ntp clear snmp-server clear xlate clear static clear global clear nat ip address %il %a %n ip address %il dhcp setroute retry 10 nameif %in %il security%sl 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup true false false true true true true true true false true info 300 true true true false false true true true false clear config access-list clear config object-group clear config icmp clear config telnet clear config ssh clear xlate clear config static clear config global clear config nat clear ntp clear snmp-server ip address %il %a %n ip address %il dhcp setroute retry 10 nameif %in %il security%sl 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup false true true true true true true true true false true info 300 true true true false false true true true false clear config access-list clear config object-group clear config icmp clear config telnet clear config ssh clear xlate clear config static clear config global clear config nat clear ntp clear snmp-server ip address %il %a %n ip address %il dhcp setroute retry 10 nameif %in %il security%sl 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup false true true False False False True True True False True True False False True True False True True True True Accept None True Deny None False Reject Reject False Accounting None False Tag None False Pipe None False Classify None False Custom None False Branch None False Route None True Translate None False Branch None fwbuilder-5.1.0.3599/src/res/platform/pf.xml0000644000175000017500000001055311733011756021335 0ustar sylvestresylvestre PF active Open Source Firewalls fwb_pf pf openbsd,freebsd /etc true RULE %N -- %A true true true false 1460 10 30 5000 10000 True True True True True True True False True False True False False True True True False True Accept None True Deny None True Reject Reject True Accounting None False Tag TagPF False Pipe None False Classify ClassifyPF False Custom None True Branch BranchAnchor False Route RoutePF True Continue None True Translate None True Branch NATBranch fwbuilder-5.1.0.3599/src/res/platform/iptables.xml0000644000175000017500000001140511733011756022530 0ustar sylvestresylvestre iptables active Open Source Firewalls fwb_ipt iptables linux24,openwrt,sveasoft,ipcop,endian,oneshield,secuwall,dd-wrt-nvram,dd-wrt-jffs iptables true true true true true true true info RULE %N -- %A 1 0 true true false True True True True True True True True True True True False False False True True False True Accept None True Deny None True Reject Reject True Accounting AccountingStr False Tag TagIptables True Queue None False Classify ClassifyIptables True Custom CustomStr True Branch BranchChain False Routing RouteIPT True Continue None True Translate None True Branch NATBranch fwbuilder-5.1.0.3599/src/res/platform/pix.xml0000644000175000017500000007375611733011756021546 0ustar sylvestresylvestre Cisco ASA / Cisco PIX active Cisco fwb_pix pix fwb_inst_pix fwb_pix_diff pix_os 6.1,6.2,6.3,7.0,8.0,8.2,8.3 true true true true true true true info 300 false false false true true true true true true true true true true info 300 false false false true true false false false true False clear access-list clear object-group clear icmp clear telnet clear ssh clear xlate clear static clear global clear nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ftp_fixup,http_fixup,h323_h225_fixup,h323_ras_fixup,rsh_fixup,rtsp_fixup,sip_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup true false false true true true true true true true info 300 false false false true true false false true true False clear access-list clear object-group clear icmp clear telnet clear ssh clear xlate clear static clear global clear nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ftp_fixup,http_fixup,h323_h225_fixup,h323_ras_fixup,ils_fixup,rsh_fixup,rtsp_fixup,sip_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup true false false true true true true true true true info 300 true true true false false false false true true False clear access-list clear object-group clear icmp clear telnet clear ssh clear xlate clear static clear global clear nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ctiqbe_fixup,dns_fixup,espike_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,pptp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup true false false true true true true true true false true info 300 true true true false false true true true true False clear config access-list clear config object-group clear config object clear config icmp clear config telnet clear config ssh clear xlate clear config static clear config global clear config nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ctiqbe_fixup,dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup false true false true true true true true true false true info 300 true true true false false true true true true True clear config access-list clear config object-group clear config object clear config icmp clear config telnet clear config ssh clear xlate clear config static clear config global clear config nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ctiqbe_fixup,dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup false true true true true true true true true false true info 300 true true true false false true true true true True clear config access-list clear config object-group clear config object clear config icmp clear config telnet clear config ssh clear xlate clear config static clear config global clear config nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ctiqbe_fixup,dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup,ip_options_eool_fixup,ip_options_nop_fixup,ip_options_rtralt_fixup false true true true true true true true true false true info 300 true true true false false true true true true True clear config access-list clear config object-group clear config object clear config icmp clear config telnet clear config ssh clear xlate clear config object clear config nat 3 0 0 1 0 0 0 2 0 0 10 0 0 5 0 0 30 0 0 2 0 0 10 0 2 0 0 True False 5 5 ctiqbe_fixup,dns_fixup,ftp_fixup,h323_h225_fixup,h323_ras_fixup,http_fixup,icmp_error_fixup,ils_fixup,mgcp_fixup,rsh_fixup,rtsp_fixup,sip_fixup,sip_udp_fixup,skinny_fixup,smtp_fixup,sqlnet_fixup,tftp_fixup,ip_options_eool_fixup,ip_options_nop_fixup,ip_options_rtralt_fixup false true true False False False True True True False True True False False True True True True True True True Accept None True Deny None False Reject Reject False Accounting None False Tag None False Pipe None False Classify None False Custom None False Branch None False Route None True Translate None False NATBranch None fwbuilder-5.1.0.3599/src/res/platform/unknown.xml0000644000175000017500000000677011733011756022435 0ustar sylvestresylvestre Unknown active Unknown unknown unknown False False False False False False False False False False False False False False False False True Accept None True Deny None True Reject Reject True Accounting None False Tag None False Pipe None False Classify None False Custom None False Branch None False Route None False Translate None False Branch None fwbuilder-5.1.0.3599/src/res/platform/iosacl.xml0000644000175000017500000001561511733011756022206 0ustar sylvestresylvestre Cisco Router IOS ACL active Cisco fwb_iosacl iosacl fwb_inst_iosacl fwb_iosacl_diff ios 12.1,12.2,12.3,12.4 true true true true true true False no access-list no ip access-list extended no ipv6 access-list interface %in ip address %a %n interface %in ip address dhcp true true true False no access-list no ip access-list extended no ipv6 access-list interface %in ip address %a %n interface %in ip address dhcp true true true False no access-list no ip access-list extended no ipv6 access-list interface %in ip address %a %n interface %in ip address dhcp true true true False no access-list no ip access-list extended no ipv6 access-list interface %in ip address %a %n interface %in ip address dhcp False False False True True False False False False False False False False True True False False True Accept None True Deny None False Reject Reject False Accounting None False Tag None False Pipe None False Classify None False Custom None False Branch None False Route None False Translate None False Branch None fwbuilder-5.1.0.3599/src/res/platform/ipf.xml0000644000175000017500000001006011733011756021477 0ustar sylvestresylvestre ipfilter active Open Source Firewalls fwb_ipf ipf freebsd,solaris /etc true true true RULE %N -- %A true true true false True True False True True True False False False False True False False False True False False True Accept None True Deny None True Reject Reject True Count None False Tag None False Pipe None False Classify None True Custom CustomStr False Branch None False Route RouteIPF True Translate None False Branch None fwbuilder-5.1.0.3599/src/res/platform/procurve_acl.xml0000644000175000017500000001114111733011756023406 0ustar sylvestresylvestre HP ProCurve ACL active procurve_acl fwb_procurve_acl procurveacl procurve K.13 true true true true true true no access-list no ip access-list extended no ipv6 access-list interface %in ip address %a %n interface %in ip address dhcp False False False True True False False False False False False False False True True False False True Accept None True Deny None False Reject Reject False Accounting None False Tag None False Pipe None False Classify None False Custom None False Branch None False Route None False Translate None False Branch None fwbuilder-5.1.0.3599/src/res/platform/ipfw.xml0000644000175000017500000000774511733011756021706 0ustar sylvestresylvestre ipfw active Open Source Firewalls fwb_ipfw ipfw freebsd,macosx /etc true true true RULE %N -- %A true true True True False True True False False False False False True False False False True False False True Accept None True Deny None True Reject Reject True Count None False Tag None True Pipe PipeArgsIPFW False Classify ClassifyArgsIPFW True Custom CustomStr False Branch None False Route None False Translate None False Branch None fwbuilder-5.1.0.3599/src/res/templates.xml.in0000644000175000017500000077021011733011756021512 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/res/resources.xml0000644000175000017500000001157411733011756021122 0ustar sylvestresylvestre false Network Objects Library Of Objects Host Attached Networks Network Network IPv6 Address Range Firewall Firewall Cluster Group of Cluster members Group of Cluster members Group of Objects Dynamic Group of Objects Group of Services Group of time intervals Interface Physical address IPv4 address IPv6 address DNS Name Address Table Management true Management true Management true IP ICMP ICMP6 TCP UDP Tag Custom User NAT Policy Routing Policy Rule Element true Rule true Rule true Rule true Reference true Reference true Reference true Time Host Options true Firewall Options true Interface Options true Rule Set Options true Policy Rule Options true NAT Rule Options true Cluster Group Options true Temporary Objects true fwbuilder-5.1.0.3599/src/res/fwbuilder.desktop0000644000175000017500000000031011733011756021726 0ustar sylvestresylvestre[Desktop Entry] Name=Firewall Builder Comment=Design and Manage Firewall Rules Icon=fwbuilder Categories=System;Settings;Security;Qt; Exec=fwbuilder Type=Application StartupNotify=true Terminal=false fwbuilder-5.1.0.3599/src/res/objects_init.xml0000644000175000017500000022153711733011756021566 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/res/Icons/0000755000175000017500000000000011733011756017431 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/72x72/0000755000175000017500000000000011733011756020222 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/72x72/fwbuilder.png0000644000175000017500000002604211733011756022717 0ustar sylvestresylvestre‰PNG  IHDRHHUэГG pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХF!MIDATxкь|ipdх•хykО—/ї””)ЉД—ЊЄZ „ЪХ`жam‡gк Э8КУv4сqДлvO t‡н]І—љгv7ї€—і avА ЖБ уZUUWi­’”JЅrЯ|ћіЭхїœЊ…* tдЩˆŒRIЉЗœя~чм{ю}b!јџЏГПx0MѓœМїо{9ЯѓіјОПЧї§mОяg !НОяУї§”яћC„јОBdY.^yх• уууW_~љхЦrq’$]эѕмsЯ§§ввRџ‰'.’eyЇчyhпїAџпббI’@ъююv†††т‘HdыйРЙѕж[Џp€чќ№Щ'ŸД/и:лkvvіШВŒ‰‰ „УapзtЧSU•Џзы‚яћ!I’ iЊе*JЅJЅ<Я:;;ЁЊъiрмyчBШ—8Žћ(!„B*Зоzыз<єф“OЊ,@_§ъW#їо{opЕZ ЕZ љ|ž~+:>>~тž{юЬd2ТРРтё8LгФъъ*VVVЧБИИxЦ&‰у<ЯwTЋUДmЩ”яћїB>|лmЗ]їФOП ’eљ‰o|у{=Я{йї§WMг„iš№}?јLГй<чAmлЦЩ“'ЯјГчŸ^{{{aлі†-лтДgяИуŽсЧќ‚(.Šт$!$BЙої§ысћ>4MУддЧAЕZ=Їьеj5X–uжŸ?~яџћ5œ$IBЃбр …–——Ч‡2™ЬЙХєzНЎvuuЅкWеї}ˆЂˆ;vраЁCЈT*чˆђбй^„pGЧ‘t]G4E&“СоН{ЁiZљŽ;юИ rО§эoЧ?іБiууутккš`YV л;vьРŽэлёќѓЯ‹ч:hЉTТъъ*р _јBЄ•ьё<якЛюК+677‡••F„ тшЫї}і‚%iпїёШ#(щtљШGьббQNг4NQђЪЫ/2Я?ї,|„Ю(Ч™L›7o†a@†i(Š"ˆЂиlOBЁ.Кш"pЇФуqдj5 Аь:.Ь-ѓ У@г4|ч;пGFFpЫ-ЗрыџєЬЪЪвњіЉW6|6‰`ЧŽˆFЃэdЫјОgёxžчA–e„Уaxžг4Q(pша!ЬЭЭЁЃЃ ГŽK6›Н№ѓ BЧA­VУЩ“'QЉќžOТayxrr‚ р†nРuз]QсК.<ЯƒчyˆХbpFОяcaaљ|SSSX[[УккZА(ŠјŠrAGCr]–e&ѓёXёxpфШШВ žчaš&lл†iš0 уД-Ы‚mлАm У •$Тѓ<”ЫхрЖmћ$@Ÿќф'Сq\фдH:Řэшь ј‚о(§њyљОJЅЄыК|!(F6›лКs†a‚їщdм…l6‹l6‹ЎЎЎЗ}ОяЃЏЏсpІiТѓ<щс‡–/Иj%gЎ$Чq‚ ‚€ЎЎ xžnЎбhМ­ „рЮ;я„(ŠXYYA.—ѓ|№Ayф‘w€t*vкїnџРŸа‡?ќa|эk_SAˆЗЋ”aрx;ЖŽcзФn„BПЗ <Я{лЕЪwvvЖ&ŠbУ0ATONNОЃ`=2u“ч“OyžЗs] ˜\ЕІЮјОџ џ`6ŠхЮJв„Ў–eСВ, УРезмИ444$+Šвбўyзuџ`юi_„gŸ}–ЯfГЉT ŽуМјN‚ђњk?сyў‡lЧнэyоЉЂдХ0Ь„Ђ„я >1:Дxэ5я;+@ЎыўЧqћˆt‹™І MгњNž<‰P(фВ,ЛтyžщКn‰уИ*Яѓєvo‚ЊІmлvГйќЫЗsЌ 32€ы=ЯЛЃZkќgгДЧv`ЗQУ0H%“№|ЊЊavvКЎЫ,ЫfЯШA’$сРјжЗО5uЯ=їм&Šтw|пгƒqA …x–eћЧчy[LгЯѓp]їmфК.Lг4*•ЪŸ~іГŸ§н‘#GовяПјтЏЦЧљДiZЄыFdIB8,C’Bˆ$c’$cyyЊІсрЁC0M3и)T™Я™(~ѓ›п|њK_њв!У0ЎvŽуI яћ`Y6у8ќЁž6M!!ˆD"PхЅћюЛяџœяяџьљŸўн0ўFзŒKЭfтLŸ§P5•JЃ›‡№Ъo\;ЧqX&неех ФbБYŠЖ A‚G йГдBЛMKA8† P™L‰DЂvЎ‹}ъЉ'ю6tу#бhdLQ”.%FDQ DТа4F–ecxx„ kxщЅпРq№<ЁСОГ[Иžїшy”L&Y–1:: ЫВ Њ*Ње*TUE,Яѓp'Иq]зс8NIг7№<†a IX–ЯѓˆХbˆХbˆЧуˆХbe„гЎх{п{\4MѓЏдІњСbЉД]з3.yoO†‡‡qХ—ущЇŸХ /ќОяƒчy№<жHсy‰D ŠСіэ;дЭ›7џХ‰…™sфћ~<#›Э"лЪu]†Mг;CзѕгЂCEˆЂDЫВшээEН^РRŠЂкЖ€Чћп};Ж_c˜жY+Ќ]Н’Я‹ХтщоR6“Сјјtн@ЅZХ~јClкдщщixžVP8ŽC*•D"‘@gg:;;‘JЅNЇ§ѓоbЖmGщ dYF4…Ђ(E„Р–e†a@зuИЎD­Л!Аm шыыC.—ƒeYі?BUU'>ѓ™O——sЯ<ѓcФc1teКщъФЮлС2,фpЭІŠЕЕ5TЋ5ќ№_Žу‚HyГTЂЃЃ‹K+иЕkВй,вщ4тё8dY† `Y–иЖ}v€к“Вя~їЛбP(Дkш‰hШ&“ыЋ`лvPи:Žl/Z ъКŽp8Д…(ёћОa”ЫхєсУПWЏFЃЅхelнКМ ЂT*уЯўєПbпОПGamэœ Ќsi'вЉ’Љ4КЛЛ!I‡!Š"8Ž;gwкxрЌЎЎ&{{{7€C­ JКЇ*™(ŠTŽž˜ВЁИЅ[‘n=QQ.—‘Ых Њы •mлЖЁЗЇšЎceeO<ё$8ŽУŸм§ЧчЌывЉzzz‘JЇ‘ЩdL&‹Х ( Lг „‡^!ѕz•J…пДiгЙŠD"иВe 333ƒ'Ÿ|—]vЦЦЦ Ыr…eYЬЮЮbpppCAСa& fQ …‚МЉбh X,"—ЫAlлЖ‹EЦ0 ,,,рШ‘#ч-ЧшлД ље"FЗlХM7нЧq IRё4u]ЧСqфr9‹E$“I 1чAЫЫЫŒу8ьž={000€rЙŒщщi;v ™Lйl‰DFЗп~;жж 0 з]wюПџ~0 UUЁiLг„ЎыаuхrЭfkkkh6›HЇгHЇгAФ”ЫeчрСƒтЙЗРvщHcpp§§§шыыG:F"‘Ръъ*†‡‡—r]мrЙŒzНA iЎИт ъ"ИgкnЇ”NЇБВВТZ–Mгалл‹x<Žh4Š••dГYhš†Ѕх“xшсЯУ4M4ъ <єаџФ§їпЛяО–eЁйl"•J†‡‡!Š"’Щ$FFFАДД„bБИ!b†?WTЉTБeы(њpѓЭ7ƒ‚ŽŽDЃQPЮЌT*7QpJЅ}єQМјт‹ˆD"xєбGСВ,Nœ8A=tZІœ У‡‹єЦЈ|лЖ MгРВ,8ŽƒЊЊHЅјж7џѕzщt=ќі§нƒиКu+,ЫТтт"’Щ$t]‡eYp]еjхr9pкљi’Nšh4Š‹vюФра TЭФ 7м„щщiьйГ•J‚ мзИmлЈеjXXXРО}ћ044ˆ}Ÿџ,FF†Б’_BG:ˆхЭѓкb–euг ‚г4Сq"‘HАWWW‘ЩІPЏ7жеfi wџЩ‡рy^ jT!шгФ’уИ`Е)рєч’$С4MD#lо<‚-[ЧАmл6ttt N#‹! ЁP(€vDк­[ZзŸ‡яћˆD"шяяп9ЛЎ‹zНŽL6…FЃєячїѕЭшяPХЂЅхЊvЧŽCЙ\ЦФФQ…™œœФтт"nЙхDЃQH’QAћhэV/m‡—JЅ ЅЄ( ŠХ"–——БДД„П§ЛПЦcў jЕ4Mƒ Ќ EБXФмм.ОјbŒŽŽњ'OЬž Z­Ц\rЩ%…B˜ŸŸGЁP@?ЈьгrЂ}Иnк2В,kƒьгTу8†У0р8Ъх2!РииŽ=ъ ѓууу0 X–ЕAAŽ;лЖ!Ы2.НєRT*•@ X– XŽуP.—ЁЊj0[P.—ёžїМФ№№0jЕšwО}Б”išH$˜œœD>ŸGwwwАbѓѓѓA›Цuз[;4ё<Ђ(ЂZ­BгД лQЏзЁы:*• dYFoo/`ddFžчСВ,D"H’Y–^ =~Žу‚ЌМбh`jj —\rIРwЅR ЊЊ‚‚d2I§Ѕѕы&@Н^GГй ЎЕЋЋ Эf3 №<љР?tZсЭŸС"HваЇ5Ugg'Тс0xžGЃб@Й\ЦkЏНњ<ъЕ:ццч!ЫnЛэ6№<Ј^<m_s‡ххх 5M xЃНѓzjхЙ\ѓѓѓр8ѓѓѓxщЅ— Š"Оќх/op!Avoл6t]_чЈVДЋЊ(œчyрy>8_ЕZхЮ+‚<ЯлD JQ\oУг§Я0 dYFww7<ˆ§Пћ\зE8,ур7pљх—Y5ЧqА,k/бѓ}?(9h§cY У`hйтК.~ђ“Ÿ@г4\|ёХа4 ?ў8††ёйЯн‘‘aзЪˆDт'Б,‹rЙ ]з‰Dагг"Š>№СлpгM7 АZB($Уї}†W^yйl–=/€:;;‡чццРѓ<ККК Bp“<ЯC–e ‹aћіэЈT*ЈVЋB"‘ؘrUТіЃ‰`(‚чyX^^Ц‰'аззЧ?~GХииіьйƒH$У0№•Џ|хŒjTЋЊА, •JšІaxx###ЈеjШхrИўњыB№щЯќ%tЭРjОY–QЉд Š"ЎКъ*јОзuэѓ•љќФФVVV№мsЯA’$ЄR)tuuЁЛЛсpŠЂ ™LЂeВ#—ЫЁЇЇ'иїЎыn hj•аюЋЎыh6›AЙбггƒK/НdqэЕз" ]ЊR~яGOSЃ™™єєє`ddЫЫЫрyЋЋЋ „@Q\qХ8~|ЁPсp$XјX,†rЙ MгЈšž_ЉFQбппёёq‚€jЕБ Са&Е6(7йЖєуMгDЕZ 8Ј\.ƒeY(Š‚X,†d2 žчЁЊjРkБXŒ‚Рдj5ЄRЉ 3 #рБSеhЯž=С0]JМЎыЂЃЃІi"NCг4lйВљ|>˜ Ni(bЯд!>  X,&‚€!I†††Zю[ŠЂРї}‹EЄгi†Qсy^№5Н™d2‰d2‰W_}з]w4Mƒmл(ЊЊnр)Яѓ˜S­к–™ЖNиgP#ъKQžЃІœЊЊр8™L###ЈVЋЈVЋeL‘чyиЖBЁp~$­(Š@Й&xд8ЃVš‡Ус ‰!†a*‡QЉT@'aЉћШq\Авд\ѓ}—J%9rЭfs=ћ>‹б!‰fГ‰fГ‰p8ŒЁЁ!0 ƒFЃ\.ЗЁС@Фu],--A’$єєєœпгu=Fƒ) jjQcЋняЁ вСMкI QAѓЯѓ‚•Ѓ5%ljAа З, oМёšЭ&pэЕзbqqЯ<ѓL FЗп~+nИё?bnюtm=iUU===HЇгAВHyeй {Ї5ЁЎы0MЛvэBЅVСбкlП/жwфяKo ЧqнПўѕЏБyѓцРуyў4W‘J$šЬЕЫЗ ХХХыGGGЗ.,,рwПћ]pуэ&;ЕDY–ХБcЧ_з4MX–DeYAћ:бbš&JЅŠХ"ІІІ …АsчN8ŽУ0˜-[ЖlЈА†A2™ФБcгШхђpщt{їюE, B ˆ СЙшv—e###№Žуаl6КЎујёуAh‡B!Фb1lоМ–eaзЎ]КЎЛЁBЇљЭЋvяофFдSђŒЅЅЅv*Aq­„Rzс\xАс‚ ЙаЯКХЂэОL&“A__"‘–––066†zНŽхх“xј l0ЬОјХ/тSŸњT ћ™L&Ш;EСјј8Mы7ЈUЫp8LЃ(ˆФљљyШВŒЩЩIФb1˜І‰Z­EQ`л6Ђб(\зEГй ЖЏыКкЉаŸ7Ќ^^њ9цЊ А;uЌœа ђ!0.ЃЎƒси‹ЯЪAѕz=IŠЎfЛЕюьUHЦ№ЭЧ6f|ўa(ŠTвЉT ЖmœUЉT6јCTв)љГ, лЖ1??щщiŒŒŒръЋЏЂ‡nkЊtќЦu]hš†T*…ссaфѓyфrЙ@Љэbл6VWWё#ђЯКV…Zl ЇЛ‰X FM‡Ь(ЉЅф№GЄНѓ_7_f8ьѕћюЛхr9FЎvYЄ*`л6ђљ§боЂ‹рyrЙfffЈ^ЏžbЭЂZ­ЂVЋabb’$!ŸЯczz’$­ЅіЧЕђљ<!ШWр8`$ŽщТ%И[Зрy.‘^7žьи0ЃНННѓŠХ"žzъ)?~ЎыВ}ъ`чЉ†НžчƒЈhџ<ЭGкыГjЕŠŸџќчh4иН{w$ЖG.х˜ЃGbuu“““иЙs'*• –––‚ЯщКјч†a@–ed2T*‹EМj§€K3AˆТx p6дBR(!*Рѓ=„dёЮг"Јel‰›7oЦ–-[Ых№иcaгІMиКu+Aj­3fэъCA ЩЃaШчѓСХцѓy„УaLLL ЛЛЅR ЕZmпyž‡ееUаGЇnОљf”J%œ8qbCуц_ЖmC’$d2p‡RЉєрђk+0•bFfQG4Ыѓ№ЯѓЁH d)™C‹•фxxhг‡Ќ№€^yх•оббQ†Jh&“СФФnЙх–`‚ЃйlЂVЋЁZ-сС‡іЁ^k†й5з\ƒпўіЗЈеj(•J˜™™AБXD4У0‡У`я}я{!*•JаžІђЬВl`Ч:t;vьРЎ]ЛАџ~,..NMXi^Ѕ( Вй,xžЧЪЪJ`ЕRIЯ5IЩЩњ”‰((0* h5Ф!0*:tvv"‰&5РЊеjPišЌ8э~PЎЃлцЦoD4КЮsЫЫЫђЕЗІi"™LbttЕZ ЖmЃX,n К•e;юЏMYNjЄ’Ѓ <ЏЫѕ`6b—œj9\Jy9јЭšeд–єoW~эќЭ†-‹Х>Ї(J‚жUAнjЅаАЇЩтUW]…­[ЗЂ^Џcuu}}§ˆЧу „ Z­7A‹Qъ-SžЂђOk3Њtд™ГŽ@nФeСЖЃбUЏз‘L&ZYY œOКЈTХ\з5Ž=§єг/j^Єv ]c‘‹x™‹Tђњrљљ”ЙшЯѕnЛт/:urЬ3Шq5ПZEq[8ѕbкѓžіgЧhй100€ююn†ХХEєєєv%Vњ0^ћsTeкw iХЬЬ lbСлYХьЎyИ%сХ,† (‹А, щЎ&&&‚Ї„(шєјДутКЎqєшбWё‹_|'—Ы`H~aПX9PюдЩ€:в8ъњXOŸ›Tю†Z^^NP‡pjj “““ˆFЃСЩiБ}rƒчyH’„H$Y–0ЈsHЗУ0›•c5  Ь­LуDeC+™‡$ј)?RФ!цYtј›БЊёoсeЬч‡Ё‘:DKЦNсНрА^Ж,uffцх^xс[еjѕ0€•>@Фi€б‚Z­Є5HONЋцЧЧЧ9ЯѓvЭЭЭattБX GŽСддЎЙцЌ­­ЁГГsCk‡Ў\{aJgƒЈмЖІaрhПЌVЋamm Хb…BEi ђѕ&†ЗёyЌЯ€qFdрЖиа3(.ЉˆiTcЋ$ кXУыU`+ЗЊЊ6>|р™gžљGлЖЇф[лФnЛiЇфœЈ|+?йЦ0Œьћ>–——‘NЇбппI’0;;‹W_}šІAEd2 #•J}Ћўў~шКXЌд"-‹Аm;hшЉЊŠќђ—ы3„сp‚$ ќAБM2№рРq,|зƒыњр<œЧu$…8TНН)#йЃZXsо˜yуW?§щOџР\ ˜Ц)Рр­€r@ УьiЯt=ЯCЕZE2™D<Чрр``ЕRŸžž"фрСƒAОA —Ъ:§Œ$I…B8qт2™ JЅЪх2АЩ@X$р гАс<УСб]x:Ф…ЁU j‰$\ЫBЭ4 зC`uЖдјЭ Ч> зŠч­‚p>ДчLІ>mсp|MkЋЮЮЮР5ф8В,ox&ЌX,O?7 ”JЅ`цк/СS~|ЦƒНЬƒ‰,сЁk\ЫGXШМР‡­Ћ04^wnˆ€5Я!А\М"Є{nSЫџз~§&hїюнмХ_|@эdмўx  щ|ЛŒЗѓ§š~ŸЖŽЭŠШЄ%‚QфaЉ,ф8ЛnС!.ˆEрšb8„x2 OїQ*Ь!б…hGІiAЏX№B,8™/ѓ€§Ž€sZы9‘Ht0 ГѓlгЁgŠЌ7ГљAЧuр4ьMC `]dQ@TŽРа-№О†И"ƒуИj,ЯCIEР„XИєВ!$Тp-:uЅqАvШњўЛіМ˜$I;|пчкŸ<ѕКvкСy+ ­З›mИŽЯvA„—Q-Waз8Ќ­U $eРfЁ5 ˜ЅИ9œFuЕ зС3ФЫjzХ)ыWцŠџзvйзп5€*•J#™L–Y–MЗ'‡oв['Щ#рD!…яиа5<сaW,$]Pј„‡jЉ„z­У" X† Q`4,Dbз/ГNcЪ}РZ+ywЩДm{muuѕйЖнloŸ д;БХ|ЩAlœCyЁŽтBž XU $DDзaж4јІ_їсЊ.р3` ЃfРw|А< п'`EVтcŒC3оwѓ‘ЬЕjЕњЫВЬўўўџ …Ў ИіdЏН^zЋ[Œšf^І‰d2ЯДЁ&TГЏКў,—!Љ№Ž/@kXP‹<ЦGИ‹…я3 РГАu–fЃ>gМь6ШlЋ4xW2ЬъКЎ;vьhЁPи;::њžP(4)Ыr‡ MJ&щŒ•эі7­‰кпС$~нGyЁ Я№@D@ŠKА9…Е:lтA ЌWwс–хТcLАтzџЬslЈ%jбЊд8џ`Ёy'•kƒPэпПА{їn@@'€nEQњ†††.ŸюI&“IQЛiyAЂбAѓ*ыЇЪ>эЉЛ™šѕ8%т`;ъ­AtЏKУ<8№"ЫqЁ6l‹№$ФˆлkКV}Ъў[k‘ќЈія}эоН› ˆаЗ(ŠЉl6лL&3йlvДйlJсpИУq&•J%Z…"РА,‹Зm[p]—˜Іщ4 еu]Ї^ЏW У Жmћс>І7q‘ИјlS_q~ЉN{пѓ 2КœŸ#м_жKю3цВџc.ЪИ| №™|ЦВђоЋі*9 иЧЇsŸ7шА˜жcт!r ИЁхgѓ­яё­ЗиК`JžЋMe$IБV­ДжЊ*­ъši_iзlН)А­c9мєЭ)?ырншMЇлїяпOZ7ъЖVыLбЦЗnŒmнTЛmрЕ~—^л‰ўс€еw‡ф |—пскžс{ыУ—Ф'`8\ˆЗ<ЧƒяЗХќћќyУџ7”5ŒСУ1]VIENDЎB`‚fwbuilder-5.1.0.3599/src/res/Icons/16x16/0000755000175000017500000000000011733011756020216 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/16x16/fwbuilder.png0000644000175000017500000000633611733011756022717 0ustar sylvestresylvestre‰PNG  IHDRѓџa pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХF IDATxкЄ’ПkaЧПЯyІŠ6'&ёr ДRЈ R+m)нš%tэд­K‡ ЅИ2”ў вЁS—RшдЅ‹P0XГUбE=Iд\=ЃЭїыэФbщxп—ч§ђ}><ФУ™RЉ”‹Х Šт†,ЫšЂ(h4УZ­Ж 5ЦиАRЉ„0%џЉ D$ШВЌMпAац6јWб4( ,—ЫA’$‹EpEQащtFљ|~ёЪсpјќœЕse~іЁ^ЏУ0 dГYИŽƒrЙŒnЗ ЫВЛО|уюrQЯ’§ѕbSТ­еhЕZhЗлp]њкжЗ AйћєїЛРЃё3 РтР™[ќOоgєр$КиџЖR}PU§~ƒСX?ТЩс5АЊџmcе-Б-‰1†•{ороX|œ‡‹#ыХшЛѓczж•ћ|Ъычw˜KKр)4юNялЧuKтmLяЮ'IENDЎB`‚fwbuilder-5.1.0.3599/src/res/Icons/128x128/0000755000175000017500000000000011733011756020366 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/128x128/fwbuilder.png0000644000175000017500000006102111733011756023057 0ustar sylvestresylvestre‰PNG  IHDR€€У>aЫ pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХFW?мщ7/DРVWMНy3н=Зя9ПОѓsИ №ЗџzтПљ7џцІzž№}kkk№<ЧmћНчy№}Ўы"xž‡ рћ>§Ž њОЏzžз 7‚~пїгRAФ‚ @b=Ap йЙЯuнКЊЊЫЊЊ>Р Ѕх8’$Сu]ИЎЫЎЧї}м­bѓ<ПэГН  Ы8v Ђ(B”$Œ €чydГИЎ A 8ŽЯѓŽуv§Œ‡уxр8@№УД!Š[Яw]žчC‘%шКzЃ~ЧЯ&ОCŸQ0С,€]Чэт8n€ižчгЧЩAШОяѓ<ЯЃ#x&$Rњž”ЯВ,ШВŒћяПпўР>pс№сУ?рyž)€$I8yђ$ўнПћwј[Kі6-РžрyЧЯѓьgЎыЦ|п?рŽуŽx@„ažч•Аpwњђ}ŸPњ7Ќ! 9rФyєбGѕббQХqœЩХХEŸ4šчyшКŽџјџ#ГP;(СсŽ%Yј[QПM†Іiaсќ=AўЉeYУеjUжuІiТqfЊшAю€LД P‚ l™BQЧqа4 Ђ(2с+Š‚ћюЛЯŸœœфkЕZЊP(@3,`EQ№ъЋЏЂ^ЏCQцЖшВќЏ>Р№ €oј€љПћ]*ЯѓˆХbP…§ŒуИ{UU”eГГГE1№}Ÿ3Mѕzйlеj†a ‰ ЏЏCCCˆХbˆFЃˆЧуLиAР4M€išhЗлeЎыbrrRИvэ8ŽЛЩё<jЕŠK—.A’ЄmОРпс8юз8Ž›Y—uОўyGўРїџVќwaЧmлpA€у8“nЌ $‰‹FЃШd2˜™™СбЃGСq,ЫBЕZEЉTB>ŸЧккšЭ& У€ ЫВ`кэ6ъѕ:Ње*šЭ&TUХяўюяЂбhАч†‚ рєщгШчѓ$ Ч Ђ(ц8юзAјXЗK ХБ žц8юЇƒ ј џ€+Ћwx‚Яѓ ы:)СЖ\ЋеАККк‰veH’„ћяПџфŸќЌЎЎ"‹ЁЏЏ}}}HЇгˆХb$i[lРqA@EŽу VЋэЈ№№Ууcћ‚ €mл}ЏМђЪЗ*•JoБXмv}A xRІрЇ‚ xР/v\Уп*@ч!qїПAР8рTЋВ,ыКЎЃйlкЗKlл†mл(‹ьЧуqhšY–!xžЯѓ№}Ÿ™xњЂШ0 TЋUц.ТR–BЁ@С ўЪ+ЏpГГØ™™СњњњŽf8гш| A№g> р‡яn*јU€Nи“‚ ќЁ›dAАСщx<ўКeYZ­УШBt+у8,Ш{;]зQЉT ЫђMПSЯ=ї^}ѕUD"pЈЊъ]Нz?ќ0&&&Эfбrює@ѓ<яŸA№1ŽуМwу&{ž‡d2ўжьЧЊšІuџь )гё}:‚iQjxxžчС4MшК]зQ(ЖЙлЖYpїv дыuдjЕ€В‰оо^f шFŸЂ(J|uuэv<ЯЃеjС4Mцž(m•eВ,#bll В,у‹_ќbЄX,;œoїaš&Ž> Q`yоЋ›‚@Qƒ7оxCr]7ђЬ3ЯННН‘\.'8ŽУД8ЌсаСƒёс_јТПBЕZ ЖфЩнёЄаы 5 ‚ЕZ ХbЂ(Тї}ˆЂ|ъSŸт&''5]з<ШqмОя(‰ь{ќёЧбh40??ЯRгpбˆ0 г4rЙ"‘ˆP.—yUUп1ѓьyІЇЇ1Л{–ЙЭї ( NŸ>­fГY<ѓЬ3оƒ>шеj5.—Ыq–eqatŽ лнЛwУЖM|э/џ ѓз0Л{п?<§>•JAЖЊa‰D‚ЛwяF,ƒЊЊHЅR‰™™™g]зaчypzŸL&ƒоо^шКЮЊ•ЖmУѓМ›L0›тё8dYцvBпnќ‰DpябУ[јI(–z_A‘HХbПџћП/МќђЫxъЉЇќ}ћіyЎыђљ|žЋVЋœу8E*•ФЫ?|пњц_С0кАmЭfЃŸпvъ=ЯC,УШШвщ4+‘ p]’$…1е4ЭuЌzwaЩї}ЈЊЪ D™L˜eŸвX,ЦВ*ЛўЈ~_QЬнsDIzЯŸў;"TАЙrх VWWљЙЙ9ўЁ‡ іэл‡ЩЩЩРЖmюЦѕЋј“?ўїX\\€Ђ(ьц7Э›ЂоNŒQ155…ссaPрvЛъ!)R=$“ы˜4MƒІiр8ІibccЭfѓ&NCЋеЧq,ƒјQРВlьо=ссЁŽђя(˜у8(ŠY–Q(№ќѓЯs—.]ТсУ‡Ё("О№ќK›оyЧЎЗ"†„6<<Œ ‘Hl“nuѓ $ы Š";БЂ("#<ЯsP.—БББѓчЯc~~ЅR Оя#“Щ@Uеm%чvЛЭH%?Њ №}§шяялRrIФћс!ОѓF ‹iš(KPА Ќ |Щd2№|ŸS…‘H’$сcћ>јС"Хгї”rњОžчйЉŒD",§Ѓ:хћFЅR чЮу–––0??JЅг4™Ѕ‘ey[жаm:РїvA+ђћ[qа.†>ўQ ъ6пžч1ЌпЖmD"кM7Эл:mœэH&“8с#E"Гц 8ŽУNЛmл№}эvІiЂбh \.#ŸЯЃVЋЁнnЃеjС0 †ђ…­У6@Іњ„ƒзVЋЧqж№v€вр‘‘afЉxџ/CК‘РАЧFрGvz6A@TVЖ§дq,--A’$†С~Я7плa)›iš Э sщ{ВсXЁћк)/7 c›дыuшКЮ‚ЪЗЊA№№С<‚fЋУ0!М„Gш6eaJ—яћnqSdIDD!ќm&WUUЦмм]ZMd9Шœ‡eЇчоюsљнЇЙЗЗ7ИїОуœЂhЖaшМЂ(‚Ђ(ЧqЯѓb8ЏЂBЮ‹gYkKы.=;ŽѓŸv2t­§}hЕл№}я]ЛvŽуbqlїq?žєІєPзѕ-ЫњъГЯ>ћ#НїO?§ж_ѓ•Пјџ4žчŸr]ї1ЫvžrgŒФб)nоЄpaЁ‹ЂˆhTC,Чm5ЫЎЌЌ \.CзuЬLOњЂ("№ƒЗyžїяMг<ЎЊъп _РN– S|с;Чyž— мнu]йqœ”ыК~‡ S—бKшєw`х ]зџСГЯ>ћ7™ўЮoџЫQAŸьщIVUѕ#НН=3Жы\ гВ`š,Ыо>{ЁœЩВŒX,Šx<Žкmѓѓ ЈVЋаu}MўnЌе­Впuнh†#ТчEЙkгзех#№aYі”яћBXљoхЯЉЧбггƒt:нщ(ayy{їю†c;X]]C4КеcљNX@œНхЭL&“H$$Щ<ўRbЙ\f>NnX1vтњ`Ь`Ть)4M333Шхrл\ EЦ; >$|јО“јЪWў\“Dси'OЦuнOЭЯЯы†гД <lбmЁТJЌi††1>>d2 г4БЖЖ†ГgЯ"ŸЯуSŸxb'€#Tђn„ўfPНu_4M…ІjˆЦbа4Х7с8ЇT*addфQпїЧ1ŸJЇ™Ёлw=‰+Щ†СZЖКŸіхнA§kYt]Чааа6ѓšYY–™аuR\вQh >ѓ™Oёџ”э8~ ПЏo*“NsO=ѕА, ­f ѕzЙ|…B хr †avЦ.8ˆХbСдд4bБ CЧвв2666ЖЫ’$A|‹)­JDa#vЂбшЖЁ[tњ#‘s%ЅR‰ЕйНеbаMс8N’N0њƒtгУЇƒN5 ЖP(`bbŠЂА^=š"Bh—mл;BЕс–/пїajЕQЋе!м8B§$ј0у8дыѕ§=іСo•Ы•уЖm'lлЦйГч˜ђhš†ўў>єїїa` 33г8rф$QDЉTFГеF!_„Ќ(H&“hЕZИvэ:љђА{К[є3ЯЈЊŠСжж7алл‹§ћїC–х…N.lUю†‚wGш'A‚Ђ“FЬ jЗІ›ю Ї@щtЩd’)@иПгs)Š'7ЖaИІiHЅRлzУVЃ; Ч#ЧЁбhЬ\П>?УqлГЋУжыullltt‹088ˆ={ц0>6†ЃGЂ<\ЦњГ/ЁT*ЁйlnkB +ннFяAрu9ёxЩdЩdЉT ЅR УУ#˜˜˜`Šб-єюxз8Р У Dпїуa4­ћtR'OјФ‘ж“BЄR)єєє0V™њp3H8№ыv#єE]8бwлfЇL‚рб7›MНЉрt][МП4ЦЧЧ111Y–QЉT№ЕЏџ\зiYИpсRЉ"‘{пЗZЙЎлhЩD=щ4‰bБ"‘‰‰dYЦШШXгlxижNЉё]зЊеъ.T&@Ѕ{ІяN7ИЛќ €Ѕd4Ž” <Ц…nліЖщЂдбCжЇ[ыo•f†KЯЄD Ѕ`”^O~*•Тшш(ЦЧЧ‰DP­VqђфIфr9ж]DнDфњюVрсkЅG===H&“ЬЇЋЊŠh4Šh4 Q‘H$`š&›Дf‹НКSe:ˆd У0o;A^XXшйииРфф$ У`fŽ^†3ЩфвџУ•)ъ[’n“MZН.nџЂяУЪ@œоЋŽ.—Ы8wюђљ>ЄR)МќђЫИvэ:„}ћіappѕсэ4F†jжаl6рћ[.AU5hб(ьЮр$R†pŽKуЯЛп“юК.TUeZž=H GРЕZ kkkШfГУ‰'№ьГЯbppЉTŠ”ЙpсъѕњЖ–32яoUшdНTUE_o/њ AТЁC‡P(Аkз.цвHшд9>еa ŽiшДgГY\П~йl‘H{іьу8јєЇ?}g(‹wќ0‘H„{ф‘GpєшQ\О|ЏПў:Юœ9ƒЩЩIькЕ SSSeC˜”Ё‰оеJПіOџXІ€GІЗњ№H&“нg[&@7žrxžчYіЁЊъ›LЧа”АVЋ…Z­†fГ лЖбзз‡Я|ц3HЇгиммD,ЖUƒП~§:t]g+tђоj@іщВ,ЃПП[J–LnЫйщP Cзѕm)3НWин†­uН^Чњњ:жжж`л6ІЇЇqьи1єііТu]œ:uŠнŸл*РнАt}пчWVV0<<ŒŸј‰Ÿ€(Š(—ЫШfГX[[C.—ыЄN§C4eСЬЩ“Џ!глƒ_јХ_dTьЫ—.т‹ќу;пўўёџ?aff|ид‡…NYš+\,QЏзйP)ђ‘‘HуууУеЋW144„ЁЁ!lllРѓШВзѕоjЕАООŽХХE”Ыe9r—.]КГмЎfм9I‰ЋWЏЂ^ЏушбЃˆХbhЕZ`Р‹$Ilп‰ŒЫЮѓpм-z3=пЖэ­>;р8Р|&tQй.@Ъыi(UиœSк(Ы2Z­dYf–€ŠJЎРZ­Nž<‰FЃžžјОЉЉ)LMMapp§§§h4›HЅRƒыКЌЊІ]гЄ“pЅ’f†-‘$I,s*‹№<CCC8vьњћћсК. …666иgWпљЮw0==‰Ÿј‰'№Ѕ/§*• ›l‘E8ŽxЂЗЅь‹‹‹Иrх JЅіяпG}+++ј™Ÿљ™;+@4Ньž8q xх•WЯч188Žу088ˆd2ЩFЖЅгщmОдї<цїMУ€икVрhМi’y!Lж@Лн†(ŠPU•™OBНlлfпS€N?H№Є˜Жmу7о€eYФƒ>ЌЌЌј›ТШш(ўшш(zzzH$аззг4ЗMњ&ы†ЙУ™H$ТЦдцr9фѓy”ЫeЄгiьнЛЃЃЃLa—––˜Л[Сx№66ВимиЯѓ[СoЛ -"AD†ызр>z{{Б{їnœ>}=єs41§Ж аYЩvлч сбG…aX\\Фњњ:ŠХ"бггƒССALOOo+ЩВl S2 ЃуˆЂR<ŠЖ ; ERбh<Я#2 )=tгУ“FЉ`SЉTи0EQ022‚щщiŒQzХkРЊЏЏfШэPс‹O 4ЩB„ЕZ чЮC.—ƒ(Š0MŸ§ьg‘H$`жззсК.УТЬ R6:Ђ$ЂнnCзu№<ПEPiЕJDŽƒeлшыяУБcЧ‰DP.—СqšЭцŽШс-…{Ќбї}lnnbtt=іЧСЅK—RЏзБЙЙ‰ўў~ЄгiЌ­­mŠ‹F˜š‚ѕFКОй{ЎЫщт–yІ2(нtг4100Q‘Ых€BVAзuжG[Чh ЊЊЧСƒFйы666G)T8Њ)Ј:I.…`А4Mc&Оеjс…^Рљѓч166†'žx===јЦ7ОСFэіїїS/"; щt†aА˜хЭ 5ЎуЂнжСѓo.сА­ћ–щЭ 7# T*AEДZ-цŽ›Э&Тю(\:™З$–ou2рЅX,ВU-ггг8qтЪх2г<Тр5UCЋнРФф~ічžйђƒЅŒЖлveЫѓ|˜†‰l6‹ССAИЎЫЦЗ‚€+WЎ ‰ ›Эn[UCi(љFUUqрР lЯѓЬP0ий3Р8–emу0а@‰zНЮš0Т…ЯѓАДД„ЋWЏЂT*attŸњдЇ033У2™••†@&“Iдыu6™дЖэmLrWДdƒчx€lЧFЛн mBбсКИŽKрАх:›Э&KУщoо5p;FPчFЈсSGMг:Ј˜Mг088ШЖqp‡ZНIЁыmdњdњњ1зщ­EЖž31}$YFГйd7…|9™>Яѓ033УСžžeЇгiМђЪ+e“““lгˆЎыŒ‚FС•eY,ЕЄз=}œ‚Kr)Фi4 •JWЎ\СккEС§їпgžy<Яccc—.]B<g€ЅЧ•Je[і@АJЅMгњ™H$P(АЖО†™]Spl‡ХCІiЂбм‚ШЙнjЕXЁT*Бд—LџнPўХл­2щPТћi0Ѕ9’$БЩ›фЃ ˆ hYD:&]…moэ. l.ЯsX]]Уg>ѓSшыыeкMшy У`AІ,ЫьD1дВ,ЌЏЏЃZ­bjjj›u сw@TcфwЩ/г=Qэv—.]ТљѓчQ.—qша!<§єгиГgЎ^НŠ_џѕпРЫ/џ@€d*…Я~ц3ИџўcLб-ЫBЉTB:†išH&“E‘q IБЖЫall šЊ`;6&xžCјРишШ–ъ(1ШtџlлЦъъ*4MУ‹/ОјЃ!S‘ЄРŽ мЎУ‡OАІi2…ФVГ А`Чu]ЄR=иЕkLгd>ŸЂh`kп­ž)—ЫˆD",$Ѕ$0Ъ4MцgУ‘9eaГHJA ™eњ|ІiтТ… xљх—‘Эf144„{яНЏНі~с~еjПњЋПŠЏ~ѕЋx№ј1ќϐۘœœ‚$‰X]]gŒмpМаh4˜ѕЄйЧЙ\ŽЕлэоН###[жЏѓљ]з…$Š˜˜ХФФ<€ƒ‡"ЂF‘Ы1<4ТвпVЋ…zНŽo}ы[{іьщ ы ~$ HЮчѓгA “ЩА€‰ в№Œ]фcIYxžgц‘NњЫ/ПŒУ‡3tжЪЄIBЇh?ќ \œъїЄpєђБ#—-3хг4 ‰D‚m.ЋT*(‹eЃЃЃ˜ššB*•bƒА+• Z­&l+ƒнГЛ№s?їS8p`?†† Ы rйVзrЊЊЈVЋX^^FЉTТддvяо\Лv <№РлoэœnЁZ­ЊчЯŸGЅRС§їпD"СJЎDœ f 2aњTи/ЩВЬNzxBЗ(nхЕ1гк—x<Ю,ЁzD)'^ЅTќ)o!n}}—/_Цњњ:ццц˜›xѕеWБЖЖЫВpј№a<§єг˜žžfS@Љў.ўєOџЇNФПџ€ZЕ/}щЫ,ѕдлMЬхQЃ0 “…B­V љ|НННИїо{144„ P(P(˜ ˆFЃ˜›лƒˆ*avї,в™ ZЭ6цч—aвщ4vЭьB­VУыЏПŽ 0>>ŽуЧГЙT*ик№#eОя{===ц'?љIœ>}Я?џ<Ў^НŠC‡ЁеjБ†BяˆќI{†ЉЃ‡L№+fT8",<інї}Fи Œ€ќ\xЅ EжžчБXЎУЖmДZ-dГYмИqыыыС'?љI4 <џќѓАmcccxф‘G№аC!“ЩРЖmцzТмМbБˆЏ~ѕЋјЅ_њ‡№§Я=ї]ГЛP,qхЪ4 vэšІ1 Fї€”€I U>ŸGOOFFF077ЧшpKKKŒbF™‘$I[ѕ‚ЎИ‰p‘Vун6 ‚€“eYІАйlТ4ЭŽŸšcЇN:љfТР‹Х"cХ„‡IMkЯž=X__gcN‚ Рњњ:; [лЧЖ@ŽfГЩрP&!xФЋяыыcŒI’…ŒˆЁсАг!I’Щd(Дг„ѓp?5išІEƒА:йKЖз vыѕ:–——™ђ$“IкTЪ\ БH‰Ш} ЖXk||‚ рѕз_GН^G.—c`еU( яV Њ*YжzНŽЏ}эk7СзЗЏЊЊ@ Ыd2‰l6 MгаззЧЬNИЁ!мюUЏзЗoDQd'UE‹E4›MЈЊЪЈPduZ­4MYЊh4ŠSЇNсиБcшыыc–‚ [bеPi:мТia7/”‘‚зp?]збnЗYьЁы\wKэЮжRЊJвM'l}}!–ёвюžžFЙЇЮъZ­ЦЬ<6:P4,‘HАt˜OИeYјэпўmМњъЋ7Л€юєЊЋЬЙЎ+JHA™”Z5›M’i#єM|х+_СЧ?ўqЖаВЖЂY‚@ …УЏA@Н^gmPДšLЃыКXZZТммS"Zдыu c…zТНŠсчtЏ  s DQDГйФќќ<+ї`šГЖmУ0Ж n€ъt"М„н­Kїb”‘‘–V*\ЛvmЧЎЂpП5щ„ЛVЋaqqФwПћ]œ:u ЫЫЫX]]н9ЈзыЗ+ЋЊЊJtЃ’Щ$SBшhQ#eЁщ›лВ!}ФdЅр12@CQ‹EVк s)k4Ќ—Ш"tcЩ…{УЭЊaА(<ќ№УиП?‹K;Ї“”йGoccиПo/кёёIдM,/Ў!‘LВЪf.—C$СбЃG166пїqљђe6N'ГJ%AРš…;†ШКбТ ъ‚њшG?ŠX,†FЃЕЅuфэ5|wѓ/џ*:-ьi/zWоV- еO|ы[пт?єЁ1ГCЄCти…i`„KwGає{К`2БЕZХaоukЕZ,n 0†В€0кG>Њ”4ž .dъ‰шБББххeDЃQ”J%œ>}ŠЂршбЃјєЇ?vЃ‹Х"ћ;[Ќ] ’$т3?љ d2LЯL#–H V­уЬ™ №М У‰XСкк*z{{qьи1ŒЁнn#ŸЯГƒ”L&бnЗNAёЙ‹0ЉеЖm,//cqqšІсаЁCH&“xўљч!IVVVр™.7NулЦŸТŠшON==T?Э§Š^3rVЩ+ЖцН›ІЂŠ333Зƒ‚лŽур+_љ ‚ Р#<ТІo…oz˜]жи0— NJс(А‹D"ьдRъжггУPAMгXУ&Y‹ЮьBVjЗльдƒ†Ў%2…)—ЫИqу …vяоl6‹sчЮсРч>ї9$ шКŽЭЭЭmС")[$СЁC‡!ˆ">№иQ­жБКšEЉt‘}юvЛfГнЛwcяоНЌФ{іьY$“Iї„[о(eЃ;4Ъ–Њеj'а4№шЃ2ЋT(оŒ_l RЏс”№}Ш ‡ч>KoŒЎЯ\џѓZЅтu'{§ЋOыСЙm p;Дˆчyїјёу˜žžЦыЏПŽ^xЋЋЋ8x№ ццц066ЦЬV7;ЖлчSmЇš2ІiВ}šІСВ,$ иЖBЁРJя('%ЄekNС‚бjЕŠl6‹ххe”Ыe ууџ8ыХЇRm­VC>ŸgщYВp<Чё‘|/Н№ .\Иˆ'N —ЫГвu*•ТёуЧ177ЧJж+++ЬЩђжЄŠ7ШЧ“EЄX‹ЌmЋе‚$I˜˜˜Ршш(|пGЁPРњњ:Щ|‹PsЃvgЭсдбDбгЇЂВaТkЛНˆ ЇДбб9ПyуšŸ†чЎbЯѓЂ­V УУУxњщЇБООŽгЇOулпў6Оџ§яcffЛvэТфф$FFFЩd˜й‡ QпiwxbсšІaccƒхЏѕzЕ†еыuєїї#›Э"•Jm‹–)ЈVЋЌРВЙЙ‰ѕѕuжHљф“O"•JСu]цJЈЋ‰0RrgсВГ(Šшээe$жЭЭMT*$ <ќ№У8pрЧСхЫ—aYc АndMгиl#Тџ#‘УKg‹?™H$p№рAЄгiДZ-ЌЎЎВо Т|п‡яњX)/т/kПз„каŠGP­—бvки5„ъzZ"†ђJm@Ћ‰Зы ‚@%Кs˜››УСƒбnЗБККŠххeмИq‹‹‹ˆЧуФШШвщ4zzz‹ХXŒ‹ХаггƒrЅЙЃщфJbБVФ tžCcU‰;пnЗБООЮИКЎЃVЋБ›+Iqьи1\Иp§§§иН{7жжжXtžЊMеJ‚SУИЭёm4X]]Хцц&›$ђЬ3ЯрЕз^ƒeY˜ŸŸgюB’$Vw š•Ћ5MCЋеbA*•‚)њЧєє4ƒ‘)Г V„q8ŽНj аyєїŽc`hхlЅ|з—!ЩЦvЃВ^FЂ7Љеm;}яЈє‡Љ*G@ЦбЃGqьи1†ŠQ^N$‡jЕЪ:cЇЇЇ№Эo|†ЁУѓ|Фт ЬЮюF<ž`PВЂ(иммФаа4MУввƒMгdН‡ЭfйlѓѓѓьDyž‡L&ƒ]Лv!NГ›LОџъеЋьФPЯ<Б”’5O3 ЋoМёВй,њћћёшЃbпО}№}Хbйl{іьСрр …ЫŠ"‘Ђб(rЙcAЯЯЯcxxžчЁT*assбhЛwяЦФФЎ^Н EQАММŒbБИ­й„Uрpžор9>Ъэ"zFbаЂ<ЮПњ*T-ŠБЉ1Hš„™}ГЈoЖАx~‰оXJNђQЛтп]kЧqліда)!JбБЊЊшяяGxщЅ—pтФ‰­Чq1Пpэv CУ№М­>ПЅЅ%|уы_ХСУїсСуГˆЛ^Џ##ŸЯ3"e­VC<G?‹ћћћo“FСTЛн†eYЌnаQS0Ъ@ NёxŽурЪ•+ИvэLгФž={№Ь3Я`ppІibyyy[wЁp–e1аŒј|ƒƒƒЈT*pУУУЌN"Ы2>ŒL&]зБИИˆ\.‡d2ййMЈnЃГA€РšFW3p kњ‹ЇQЊф-kа*јXЙОЎМv …•"дX>яХЂв}vХКqЧљІбIђ<U—шдаMЅш3б[&рјЙ\ЇNƒ(JТСCїтшНїтїО№ЏHФёё'?Й-ЋˆЧушээeEН{їЂT*1кVјъѕњ6ZWŒ"ЎB8CЁIE“№яEAЃбРйГgБММŒx<ŽћяП„ЊЊpЫЫЫ,ƒ!І];Х24ГбhАXЃеjЁПП?ў8тё8jЕЎ_ПЮмe0Д5Џ­FЕz UћЌJ—aMШIьc@…ЩЕ‘юЯ "I0књ†&Бvх*в§1ˆ’ Нepbїј3ІЗbt‚Ÿ˜чyˆЧу,( ŸІюQёс6lЂˆЏ­ЎрХ^ъšp ŸўЩЇ№Г?ї9ќщџїЬэУЬЬ Z­тё8cаPeCT“'6-|"Є†GХ…7ƒuO #„‘fee 0M“““јьg?‹‰‰ X–…jЕŠRЉФмхыoюLtУ,jЖдAUUдj5жю=;;‹™™$“I\П~™ћ0НЎћОвЯ\лE-зФыЭчQ^ХDbЃЮbuс"В ЋАЭ:МР…iдс›2в™^$2zz{ рZDCiАњQˆш…‹вmGФtLŒptђЇсSг=њl{<ССqmT+•лЮ@ ŸЫabbb Ц MУ"CДtŠшћ0Ђv˜^пНЙŒЊqgЯžEБXФ‘#G055…={і0n?) a№с9}сє–jнšАљББ1X–ХвQVр0C™ж4MД[:ŠѕЎДN#7x™TёЈ„LK\(rОРmћ№ŒЂcН$…\–mCŠ№Ш  ]o#=–˜XC5 tрVCЂ:дЂaЪХУ§wФѓ§ТЭрWЯƒгiђмq>@GЭV“ЅŽФkЃ‰‘“bRHЅцx<ЮZТRƒ8є|КЖАЉЅЖБƒтСD"‘`гУšО Зr…\вћ™І‰љљy†ССAШВŒ'Ÿ|ЅR чЮлV# ФЛКїІin`ЎYVА žЧљоя!&E4ЂHФ9ll,ЃgМя@–4”s%Р P+W‘ш‰Ѓ]iТn™и{џ~,^Dја2 9в_ߘ›ўэ›C%I’Ў_П>^­Vё№Уo#FаM!LН{x$Чq@РGžУ­чЕёпœЅG Dо гO, ВТХrі›™RвыУЕ}xэЕзАДД„нЛw#‹!ŸЯ3l@г4цƒУ№4™fВdc+Š‚—_~бhSSS8zє(<ЯУ /М€zНŽ7nАљ„ tї4†•luu•еў{{{Сљєy ЪˆŠ™ЙУАtmгA1З‚ъFУSƒМ(Ђm4!Щі>Аg^x‰t‹qуд:†wѕ ’e)Щ ™›€H; €оєПўыПFЁPРO<={і0 їџпjЋРі‘-dвУб/ a Т#љ`*эRTO1љц№аpЛv.—У+ЏМ‚\.‡уЧуфЩ“lБtxШe˜Y*У0P,БЙЙ‰H$‚{яНћіэЌЌЌАED†UU• ЖшЎ~жB8A__‰—]ЯС’п5ŒТц"ђЋEьНїZ53CœХЫ_y,ŒЭMbpї0 У‚Ђ*PуQБ#}ˆ( е:—˜Tяm^i}Ф\.w+РЅR)ўщЇŸЦ‹/Оˆ?ќУ?Фмм{ь1ЬЬЬ ‹mƒщTnГиZ€xЫљСжГv”Дг м0FЇ3Lу"ЅВІї"ОџЙsч066†Яўѓ,Г ї _љdŠ7ˆ bЎ]Л†bБˆўў~<ђШ#˜žžFЋеТТТУ5КЩЎ4Iо“Ў›f%“IŒŽŽВžФХХEДš-(š‚ГюpЭ9 ѓ&fїяТўћahf WРё<ЮНtМ$z2(lцPЌфIШ‡у{№J\A,‘@9[CъžШЯхОпўWž”nЧ›Эf\Q|њгŸFН^Ч_џѕ_уџ№бппЃGВz@OO3ilˆЯšиn9!Ў@W§>ЌHс›Ff?< "Œ­FnrЙVWW1??FЃббQ|юsŸУ№№0ыЮЁзэДрŠ”ŒFоoll VЋaffŸњдЇ000€fГ‰‹/В5$‡З „Ї‚бпІд4q•˜ПЄШŽэЂhфpКѕ]ŒЭM@UФ{%Э6.Мќ:ЦFG Ъ ”ˆ†ZЎQфQ[l UЖАыўiДЪu(1}У И†‚ /^< |ФŒrЛл7‚в-›Cƒ hэv›››Ч/§в/ЁP(рњѕыИxё".\И€d2‰ёёqЬЮЮb``€Uўоь9фn= ъP”о=o˜ъіt*У) aч”nхr9lnn2—AдяЩЩIєїїoM.эЬж 7„ œIмИqЋЋЋ‚ЉT ?ѓ3?MгX­R?2яєh˜eбћwhh§§§№<QлТШqиІl{ VЃ…ѕ3W %cиœСд єїCMКpE œрc|nљЅ ДИŠx4†ък:інџx>“ЯŸСъхDт†ІЁыm^Ž Лл№_o5MВgF(в­зыЌї'ђ'‰DаjЕ№рƒb}}йl–Uг~№ƒ •ъAЊ'žу099Жу|€А ЁxDх2 ƒQЅh6ЁišЈеjЈT*(•JЌ7žjГГГD:F:f•ЕJЅТn0?с§Єl­V gЯžХњњ:вщ4}єQ слпў6,ЫТттт6ЗGЇ?\8Ђю`г4Y‡ŽЊЊ˜˜˜@oo/K3ЉБeЇeлrP3ŠHІz №<8ŽG2‘СхЋW CФр§)Шб(Z-з_YТтЅyD" ік‡д№ДX–@o6127€Щ§3(­зАqНм0 ў2N\__Пеж ittTЃ\•N[ЋеbKFFFpп}їaпО}ЬєRП%LуS“јйŸћY ”J[EЧЖЁD"P;ЇzaaбЮpˆ0Ѓ—hнЏНікЖ=К49ЄЏЏћїяЧЕkзH$pтФ fv[fn>Ÿg‚ЁŠtRЛGЯWЋUфr9ќйŸ§ЦЦЦ№йЯ~ЃЃЃl 7ЁФpЧ tЪЉшcš&Z­ЮŸ?ЯІˆбЦЕХХEV`ыNŸщ}Чщш(‹›а’@o2 ЯъоnсЩ_xW^;ЩaxŽŠОќ XF уїŒ@ф$шuМр!3’BЃоТЁяC-WУЦ|+WVQ}йў-cнПу Ш вЊЊўПЧЅШ—QšЊPзыuН*ŠТђwтъ-.-РЕ}ФтILЭЬ0ОЯёЈV+Hїіcзь,іяпЯ|њNЫ)эЂ.LRQ…†.mnnnуј„M?Ѓд•„nY*• ыO8qтxрЄгiЖкLrx‡сєА…VЋлЖ100€щщ­]B Аm›‘]ЃбшЖAсўGFWxєЕ&0ПЖ]№aы5Д+:ЎНxc{ЇРsь …ƒО­jѕB nй†ж#Ђžmсњы6 ыE4›z†3Ђ ьюѕ+ўŸn!/ю0ЈXŠХb‰D> K'б†ЫЈaZ5!p”v РїlnnЂ\ЎvnЮ–пммФ>ј!ЬЭЭБ™Лt=4ƒxдиAn ŒћS˜‚ј‰wxž‡X,†fГЩ"q (ЩD?~=і’‰$LгТЕЋзр>SЂ0у9<ўоŸ ZA`ll 333lvЯцц&t]G:f-ё#ТЈ&)†alkяt9ЏОњъ_}ѕе/ЏЎЎО з–йСг"n…jнo.ЕŸ“э~ЇсчМ–дД:ТхH€зЖгљзрпr\<ЯѓBН^?B­[ЖmЃT*a``€aтa7~ИЙ2\)МUŠ6пaх Л‚p+=К(˜І‰vЛL&ƒrЙМmкИaЌо[oы—.^ТыoМE‰`ђ№(PрсњэSPpз КАPЦBь‡ЈО>{GЃйФцZюн‡yх4Њмд|ЭZ Ў`AšPн8dQя&с“щ'Eo4жЙsч~№кkЏ}9ŸЯП  Мtn2Чq. @@еmћыnAЧ[ч[xskxњКs_Чqƒ­Vkіњѕы8rфFGG‘Яч‘Ых ы:†‡‡ЗMР oњ 3tУ“ЖК9З[3ЦпIHа”)Їп“y7 ƒm07ejHiYЎ”Хjn›љ Db њ‹@x  Лт!аbh6uДлр}nЂ†ь‘“А§Є!жЋт ^Уfb+жeLЩ‡ J1,6ЮЁlm"cс ѕ’r>Мmфъ-(‹њХ‹ПwњєщПЈT*ЏwJГdžН Ы„AрА8Žs:Я#”Эя(J7œынѕкИ.NрAт+++РддЊе*ŠХ"цччй\ђeсн=Ÿ?М§+м|I ЯNAfxQtИcˆИђєкfГЩ эv›Э *—ЫŒNMЪеnЗББЖЅЪ ”Ѕ,јОџ@@*ЅТзlФciD$•к&šy=Б4ж*ЋAЛж€ж…ѕчзО }5€Г0Ќ B”8Hs&JЅLЃ еSаŠфёbс/pЄ§єjƒИ7­]БXl}ѓ›п|юЬ™3_i6›Ї;ьм63ї.WјЁпyђУнNщ*Т$M][[CЛнЦ=їмƒ‰‰ єїї3фэфЩ“lонтт""‘[*н †Ѓцp!'мЖM­д4ў=Œ9P†@M4Е3œƒ&@˜DxiTЕZEЙT†Ўр7‘>ю#&Ч!КрUО`mc’ 'ЎA–9№œƒёБ1$Д­šzЋЖ5swbї0мq+W–QЬWЁ ‚ў!@Ђ›D#[EВ/ЫsX-_C‚ы$ХbБ~іьйя\П~§ЋэvћL'ПkСП›БkІўЁ№і.]зqщв%T*LOOcxxуууЌ[хфЩ“ЈеjЌnнзз‡x<Žёёqж#@н?;­_! |xc(e"4Œ’Р%Ђ^“"p‡ўў~\Мx—.]кж#Џ( FGС 8(ž8Ьlxp>рњRЉ“\ЯСfn У}HХRX[\@Ож‚$‰юEamОaРiј№‹ Ъ›:дL —`ъ:Ђ="&їŒЃQla`fvбФЦцFхвЕ пО|љђГЖmŸ оњq ~Ї@сp8‡'kP­VqљђeфѓyŒŒŒ`ppУУУ IЋзы(‹X]]eа-EуД2–€ˆШDзj5ЌЌЌАŽcЪџiІ>ATЏзыаuс д жзз‡……(Š‚mу^Ze›C—Є ИzvЇмkЛ&Ъх!Šсоь™й‡jЙˆЅљreЬLOƒDM"/ šЏЃД``xh/bb љьъ•"d!Šбй)4+&ЎПБŒёУШ7~№хГПцxЮЉŽрѕЮ‰ї№zˆЁ“9ТqмtwъF戆fГY4›M$“IЄгid2ЬЬЬррСƒЌЕЩ0Œm&˜цф†ЧДиЖЩЩI|§ы_Ч7X f…>‡ЧГЫВЬ–GGЃQЦ"z№Сa™Jх­!PХbѕЪV ЗДЗ„„Р#\ЎСS ј<,з@>_…kћЖ`sЕ…dД†Ё>мИвЦьўYМќЕ№ЁЯ‡Ї[ˆФ“ˆ ьХх3‘‰bёь"LЫФРl?|–щјЮkВh§ЎГ‹рyўЧq‘юfн[Ј(А ЏwЋеjа45BhšЦJФДс‹ ф№ŽрnТi8 Я 3eЩ%PЯ@ЅRСцц&JЅJЅк6ЬЖ.рё]Gk(jp–hCЦЧa‹6JХ2D(˜юУтвЋI"JQ-‚B6ЄкСщQœњсYDжЏЏ"Љѕ`ўy$UHВ(!–JA•Lˆ2р˜”ДtOrМЇ~й^Ф{ј!^Нz<Яcїюн‡ТФФnHwЇŸ…ыщ4Ю…„•'ЬЯ#вqўЉ‹&<Ц…puRТ№ЉћˆhVTі<žыУ—pїеСU%Kќ˜…рў*lзCћК…ўб z'4Xѕlп‡щИ†!AoкPг.l XZ]РЬь$QФвђ Іћ16а‡y ѕІm@‚4ЂAw-ј<‡vЙ%*`№`?‚€CГиЧWфј.щcѕЫі_НЇ Фш=|З/ъциw/v žоМ^ OЇ?Œђ…SС№*љ0BHAЄ,Ы№\–oСKкіЕЁФ†Œh†v)ŽхзЪ3 Юч рš"cзD‹‹KИrёкvгFO:…™Љ~Е <™ЧНэУЩo…$(h– D"*’2ЬVЕЭ6тi О)ї4ВЎœ<ЯuьWЁєѓї€G>ЬїЌtL{ŠчљУw{ђяЄ;§,<Ь!lAТЬœ№ЪјpЩ5ќoїž№нЖj@~DЧаФ8• ЊЭ""š€с‰,Њ!НW‚ї!CCЅX„эљšC`0ЄЂ)И^€fеF"E<$тНШ.ЖББX‡х1y4‰Ь`Ьj zЉ ЧlЂnй+uT7]ЌПі†їf0wќ6ЫXЮ­%9žS?xЯ*п™ЪНG’Є‘;M–ю^Ј|7 –wBќощ‡чy№с€ыuа74€Йƒћ G$№Žб3@4ЂЁ'–„,ѓP•\нЦЅзЯCьš…"Кœ6$С€Ре!Щ \;РбЧFВO/ѓ0Z.6 № BL…šŒЃ]sэ‹"’рАџб}˜88•Ћ9м8ЙъhќAрњ{крeYОчyщvГКн­сШН[ия–р™Ћё]ˆУ'Q-•Q+Uё№cРђќ"Рё5В b`hmГ\6 QŽ`|ržэРЊU‘ŠH8tрШеRљЭ*fЄQЬ^Ar fЙ­GƒЌH№|М ТЕђJбLeТu5x‚г2аМ`ўООрџч.џžU€ˆ,ЫGпŠџ/Ѕ2[Œтg"ПоФјє ’ЩЌЖ QPбЈ6 іˆѕЈ(мШТѓмwєA NтќK—Бxy ’dЂwИ—x Ђ(C”xBХЕjХєК‹є`ђk Я #З”‡еА‘HЧa6mDгъй66Ўl"VЕ жŸ7OћџЖSЄqоы љО/оЭІщ‚П,СMz—Nџ›>€6e•Эы˜о5ьвL—GІЏЕ\…Х +€"Gpсћѓ8m]Ррl?њЦR0Z-TЫ Д›:8СЦа=CX:Н ЯёJСs$КЦf ‘ˆŽXЃт€ ЂŒvХ„–Ž pВqНєZљKn_Pь(€џ^V@аjЕЮ„— н­мЩппŠ №Ž[рbЩ4‰ƒ027YхБreFUGuЅ…žО^dЦ2hж h5+Ј– ˆїFMІ E’ˆієBV€Ћ ЂIр АXByН…žЁ~єŽЦаЬШ^ЋСГЃa"šжэQс.МwС­тЅNйV/оЫ р7›ЭяUЋеоŽкЕг,н;eяњЩxќЈ…иСE@"–€чиШЏn@№yшM‘И†xJUm`ѕеE$” vяЛimx}Л?„cO|.ƒжКƒъЊ…ўБ1ДЫ&є†ŽЗАr~Єњ“X;еТшОqєOїcѓrэrЂЌ@HНЁН‡їСCш\]зDQмЋ(ЪPxч=7’$mcц†ћкiў^ї–ю0_ {–@їъеЗђюМqLЮPк!РoШ/цР ^@5пDnEG<ЎapА§Ciфп(blЯ.ьz`/8‡CDUPЩ­#;П‚Е‹Ы˜82Œќѕu(Šл№И€ ё0&’}"Г]ƒgйDбоJЋ8Ж пƒо^pПе1џњэˆя%№ЗVПбjЕЮATeVŽоhA‚ягэV€0Ы'\лЧРѕ`йј9щёbZ ’СЅQЫже4Ј1B›ƒНж€гАpшЉ{эIтТў!ъХl\ПŒzA‡ЌŠрpB€vЕл№аЗЋžчBыI@Џ8Ш]ЭЁžkB‰E`5(š€ЬDьЖзёQ?ч|Э.yЏ„ˆ—я  ‰AГнnŸjЗлЫ<ЯgdY ™N~З№УЃWwт О[ `›ŒhТ\c3#Gрё№]Cг#pLFЭФЦљ:bjНу=XЛД^Ж!ХD(щMEt0ьѕ<єŠ…Рц`V}ˆ Iхрš&кН3}АкmИŽ -ЁЂ&[w Hъљ&Њ—ГsЮшЪ7€ї‹ АикŽу,TЋеW›Эц‚чyŠ(Š}В,KtвЩ%„•`'›џ0њPЯѓ`›.ьž*аoBt}–ГИіУkU’*Т|дJMŒž†mиаЫ 8І)'№ˆ%П\€ ЅјђжIж ˜ЕJЫ-ˆ1 žУaхЕ*вГ1xŽЯВ!+ƒ oTрК>Ьšз,Н`|!pp [„ЮЦ{=њпI˜%ш˜ЏКeYзЪхђsЙмЕZ­рyЯѓ|L…&v„kнbИл7<џцВЎчРЌЙ0‚ЈЃв†лоšЅЃІTДЊьІ лВPЩWQЭщpvЫ†Ђ*p zЭ€’ж`4u№B€ЦZv“ƒмЋ‚зд–]єЮ&`4MHšŒРœЖЋщРЈ[аы&ЊЏ[ф”ƒчBЇпЦћфБгка c ЬN гp]w­^ЏПБККњтќќќ йlіjЁPЈtJЕQžч%R„pыTИИг-Мк­0;}žяяz.<+€Е!Рr,4Н2&žэ 8dЦ{с9.Ы‡š‰Ђн4>б2,>№|Tз›ЈЏ–сщд˜„дTžРqˆ2H*Q`6lXuбў(J7j0лԘˆжuяy§†їG6БХъ}_ј~–Снхs2€кљ7Цq\$ъээHЅRCуууЃщtzHQ”Є$I2> 2э$\Њ№…ІЛRHпЉЄSatMг4ZЭvЅiжыќTKЫм#E{4ХЕ}ЄЧ2р#Њљ*ъ%ЭEћХк)ћџсф@z(њїДД№ ž5ˆ#кЇЁ]j#94ѓЮZ5з2#9ЪK|&№Ё(izQ‡кЋ‚—€ЦFЫїмЫЭSюП<\А­–+яЃї6žЯwD€дQЙѓЅHI’д#BМЏЏЏ?‹ѕЪВм#BL„x,‹I’ЄH’ЄR§чy ‚jЇ ШtЧђ}Ÿ3MгpЧ2 CЗ,ЋщКnЫuнКу8eУ0 Žу4ƒ pƒ Р##їpуНGе‡гъA%&ЫыЏ–_ИF`r7ЊЬЏ6–:–-ЉNтПщ™Sў./`*9–р[EГY]hПnЌ_ѕн Р‰рј(7!ЦЙ}7pј‚gЙЈ‰]ѕжНZpЙ“ђ•Беœaу}ірозѓ!ЅBЪ!v§L YRaЋRЬK!wtJКгљВё&ЕЪэњїŒH‚CЏм‹))!*њВ{:№PPщœаvчu<‘“1-ѕрXŒ—uыС<<ф;ЯЅHžЎЅЭыb{ЛU№_›мb„ПџŸлс Ё›ш‡ўя‡ўЅяНаїд #ˆˆu„хtžgt„iwgH9ЅRxГгЦ =ЏЛл]з№О|pяёПџvnЌа$ hН;Єe|Wйж{? ѕ§ЄŸыП AОнЧџ?ѓLH1”@(IENDЎB`‚fwbuilder-5.1.0.3599/src/res/Icons/512x512/0000755000175000017500000000000011733011756020360 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/512x512/fwbuilder.png0000644000175000017500000051574311733011756023070 0ustar sylvestresylvestre‰PNG  IHDRєxдњ pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХF‘IDATxкьНw|diu&ќмЪIUЅœЅ–ZнRužž„g†acЦš4Рkя:ь:,ЛkУЗЛŸгz1о]л˜С֘!36іјHУЄю™ŽгнRЗrЌRЉJ•ѓї‡t.Ї^НЗЊЄ–дъж{~?§$UЎ{пћžч<чœчhХbЪ”)SІL™Вe&u”)SІL™2”)SІL™2e (SІL™2eЪPІL™2eЪ”нfйЈJЅRъhns{Ч;осаЯo+‹§<тcŠCзzћŠ…ŒЗНђф“OцеYйўцp8дAPІь64mЃКи|{Я{ог kхœэр\љйПr[€Fц{д•sв7rл ™Э˜bџO­мЏШˆVрAeЪ”m#@йњэ§яWБXl\‰Ю=ХbqpХБ`.‹G@г4аяnХbQЭЕоЖолЫXЫЪйqЩc.јEхќ•)SІL€[Т~цg~†Ђє#+NО @пŠгяЅшр7Тс9хѕ>Я(p RээхЌОО.—+биијч?ћГ?ћХжжж%`ЁL™2e lћйŸ§йF§ХbqџJєо_,ћ5MkЏфШ7Ущ—{§ kaжј}.— иГgЯ™ћюЛяŸl6лнЉTъ]юTЮ_™2eЪИ)і П№ ]фм ЎќєkšV':лrŽ}-NПвc7@ЌЧљЏ'=`БXА{їnєїїŽ9ђЅЮЮЮŽT*ѕ›ЁPШ™L&Ч;::Іе TІL™26е~ёБЫЙhrіGьз4ЭЙчО^pГœќfY%– ЅЅƒƒƒ™={і|ыаЁC™t:§ўp8ьŽЧу( jA*SІL™›cПђ+Пr7€Л‹ХтIw›LІ.#‡.:ДJŽГ@РFВ7ЋИаэvушбЃшыыЛ<888nБX^Ч=бh™LF-LeЪ”)S`уь?§ЇџдВтьяp7€Л5M3oДГ7z­›Ж*ЊЏжЬf3:„У‡‡{{{Џљ|О=љ|~`ii ёxjP•2eЪ”)pУіЋПњЋN‹ХћŸЯd2™мщtС`‰DЂв)Пчž{КoqЧo№›+?№-п№д“O>yi;~f%ЄL™лќцoўІsХс?Z,п€М­tј78lи`6›qп}їсЁ‡Ъеддф-‹=ŸЯ#`aaЁZbќЧ~ьЧnYpъдЉќ99ffГОрЩ'Ÿ|ђk (SІL€2і[Пѕ[No(‹я№,+щ•udЗ›уп А‘QџоН{ёшЃ[ZZ VЋе\(‡199‰t:Н–г=ўРмrрдЉSўРћж№Да ј€ЏнЬTЪ”)Аm€?ћГ?{Хbљf2™ КнnГзыѕдддX“Щ$–––‡БДД„l6ЛЉМК‘ЮўfІ Њ>Ÿ>њ(Nœ8Q4›ЭZБXD*•ТШШBЁаzNѕјы^їК[ œ:uъ—ќ.п МL„ЇЖ ( L™лИЏ^НњІ@ №YЏз “Щ„BЁ€|>\.ЧуёИЖДД„H$Ђџ№‚Г–*0™Lшьь”вяVЋmmmЋn/їš™LSSSzдџц7ПvЛ…BšІabbcccШчзэПЦ~јс[œ:uъ€Ч!Ÿip#№Iѕф“OŽ( L™ВЭ<ѕдSwe2™КнnИ\.И\.X­Vнё фѓy‹EФb1DЃQ,.."‰  •ˆЮlЇtBЅЧ9N466Bг4tvvZZZ`ГйPWWЧЗл†††M=ХbХb…B…BХbЯ?џ<тёјОєјOќФOlkpъд)ЯJФџЫX):нDћ€ПТrЭРІ &( LйэiЗEрЬЬLєлl6ИнnИнnX,X­Vиl6hšMгPSSƒжжжe4Дr[4E(ТТТ‚С цччѕћХЖМjк7ъohnnFcc#šššаммŒііvдееСыѕn›ѓA  ББХbKKKЗ§ХєжЗОѕэšІ§)€v#аЖСірЪOрдЉSŸ№ž|ђЩqЕ­)SІlЧ™Ll*•B*•*‡.— ^ЏfГ&“ &“ fГfГ555шшш€йl†Іi0™L˜™™Сьь,цччW9ъв АX,hiiAkk+t‡пооОсЧmrrrЃQ,‘Щd011QЭWњлfГЁЗЗ…BЇOŸЦŸ§йŸс…^€Ё§ЗННэmoы№П5M{Dцјз3qжрзќ—SЇN}Р?љф“чеіІL™ВлTЛЁ&“I$“ЩPрrЙPSSŸЯŸЯ‡ккZX,tvvbзЎ]а4 fГЙ\ГГØœœФЬЬ &''ѕз]KtOyјЮЮNtuuЁЋЋkн}2™Фќќ<ŠХ"&''ЁiцццЭfБИИˆX,†D"`0XтМЉf‚~‹?B-EI…џЭ_ƒшr€ЗЃИЯ;оё[БXќ/šІ§?œе:ўMf,wМядЉS_№a”)SЖу€j-‹!‹affFПЭыѕЂЎЎѕѕѕњ9kJиэvькЕ ===њ†žL&1==‰‰ LOOc||KKK%ПЩdBooЏўгнн “ЩTѕчœœФьь,fff033ƒ‰‰ „УaФb1ЭрЌ}о›išІнv Р;пљЮћќЙІiћEgОж)ˆхІ#о€Н Р›N:ѕ… 0ЌЖ;eЪ”)PСТс0Тс0Ў_ПЎ;А†††:ОЎЎnеЦэrЙазз‡ОО>жХb˜œœD$Acc#zzz*:ќt:kзЎсњѕы˜ššТЬЬ ІЇЇ1::Њз1X,Ѕ ПЗЃб1К]€G}ДРŸhšіОqђ[Ш< рдЉSЇ>рЗŸ|ђЩ˜кі”)SІРlnnsssњџVЋhnnFSSсїћW9ПššьлЗЯ№uѓљ<^yхœ={.\Р… 0==]тшљпЗЊн РЛоѕЎŸз4эјЊ‚Д–Щˆkk6,зМядЉSПјф“O>ЉЖ>eЪ”нрf8—|>‰‰ LLLшЗ9455ЁЅЅEџэёxJž—Щd№ƒќЯ>ћ,~јУт•W^Y>+Žž~nЛ€їМч=ƒХbёуšІнН–ч­u,ђZ…uВ-О|ъдЉ/јХ'Ÿ|2 Ж@eЪP РX"‘Ршш(FGGѕлмn7ZZZ№ц7ПаддЄkу…П]щћХbё–=і˜'‰ќ“ЯчЛ›пгП•,Слм}ъдЉw=љф“пWл 2e (А FFK˜ƒЕ§н.v+MгоюrЙюЋЋЋ3g2ФbБUРfГ§АэОsъдЉ_ђЩ'џ—к •)Sр–ДлЙЧќV7r8З"јЬg>ѓЙ|р|їнw7И\.LLLрђхЫX\\м0g“YsБXќ“SЇNѕјO7sр2eЪИэeЗ.рЮcЧŽйтё8Ђб(мn7юПџ~ЬЯЯуќљѓ%ЬN•ŒBEжрFшBјeo}ы[ћђ—ПЌ@€2e (@йŽпћУ?ќУШсУ‡НwмqьvЛ|№A\Лv ЏОњj‰рw№•&И`ФH€ТЃХb1 рgдjUІL€uлу?ў›>р…bБxР ^јЙŸћЙаfМŸbи,KЇгХ^xЇOŸЦО}ћpьи1dГYDЃQДЕЕЁЙЙ/ОјbI}РvЖ @сЇпіЖЗ]љ‡ј‡?P+V™2жl§з§ЈЩdњ§•MхMšІН‰6˜Ч|ИX,О@€ X,О№ѓ?џѓ7Оп Р&„Й%Ю­.”Ячu†ССAœŸїнw^yхЬЬЬTdжњџVАТmПћіЗП§…/}щKпRлЃ2e TmŸњдЇъ4Mћsq#cїišжW,пCЗ?ўјуЏ‹Х2–рвэvЊб  лiРљѓчqэк5м{яНиЕkRЉ> ЛнŽБББMЃўЗШЬХbёуoћл|щK_ЪЈЌL™U™ІiџCгДКj&оБЈјˆІiGŠХтXa bŒ%8НТŒ+pkZЁPИ-‡% |упРСƒqЧw8€L&ƒййYУЕП™Qџ2}X. TэЪ”)Pй>§щOћ4MћщJŽпhуc{4M{АX,>ШX‚YIъ ТŒ2n†]Иp xшЁ‡`БX088ˆh4ŠD"!‚уЊўЭ  јР;пљЮ}ё‹_TшZ™2Ъ›ЩdzOБXєTкаЊтуZVj оDї}тŸИр4€fggЗѕоЉ5…B&“щЖ033ƒo~ѓ›x§ы_Чƒžž\КtiCўMА.o№”к&•)S Ќišірz}%РЇp_БXь№ПпŸЯ‡d2ЉџЄR)ЄгщmхwЂeГYX,–лxёХсvЛббб+WЎшьЧzЎƒe6PмЏ€2e TNЎeгк(€РџvЛнpЙ\њѓђљ<‰’ЩЄў;›Э*` -ŸЯпж)nЏОњ*vэк…ііvј|>„УсMЛЖШŽЋ-R™2Њ-kD6ˆџ[,ддд ІІFwРйl‰DЂфg+Š …ТŽщt…BaG`Й&рФ‰p80™LКжз ж $oQ[Є2e T4ГйМ.EДЭтп6› 6› ~П_ЉT ёxёxС`pSѕNФИь099‰\.Џз‹@ Аng^С1ЏЫщЏ иl6 ”)SІ@%sЙ\‹ёxМy=‘ЦF„ ѕe7aЇг Їг‰††D"$“ЩM;Б Nпv:е€Зл­ЏЩZЇ›Q;PЮіяп…2eЪЈdvЛ}:‘H4Wыє7 нWэ&ьїћ7EжuЇ€l6ЛcjРуё —ЫЁЎЎ@6›E2™D4E2™д SЋ­kЉ,l@ИыЎЛT  2e TЖ|>Ÿ(—ѓ\Ћ“пъœ)§нббЉЉЉ wXЙ\nGЊБи) czz Ј­­Х‰'єѓO@ˆІ Rъiqq‹‹‹RpА,A5зšЫхBKK‹Um‘Ъ”)Pб.\И`;tшPviiiK6ЭVЋ===И|љђ†~о|>П#ЅSv №ћ§ˆЧуАлэШd2Айl0›Э0™L0›Э0›ЭАX,( њэVЋ&“ љ|‘HѓѓѓˆD"‡У˜ŸŸЧьь,Вйь–‚€|0>66нГgк%•)S М={іјC=єR<?Y­ЃлЬоцй;::‹Х066І€ `v…BxъЉЇ№ОїН0:: ЛнЇг —ЫЅџ6™LАX,0›ЭАZ­АX,АZ­Ј­­ХюнЛЁi, 4MƒйlF4E8Цфф$ 1??_ТVm@№љ|x§ы_Ÿџнп§]лC=ЄvIeЪ(oЃЃЃІЋWЏ[[[“@Рi0sќІБkШd2˜œœмЯV(vфЬ‚l6‹L&ГЃŠЙ---Iзžлэжu+<ќ~?jkkaЗлѕЧаoMгрѓљрѓљАkзЎUk5caaггг˜E(B0дьZЛољЮwЦcБ˜івK/EдЉL™-Nу™gžЙу~сОЧЕаЗЪЩoTEДйlЦ‘#GPSSƒ .мp _.—ЛЉ"D7Ы’ЩфŽ*”?#` vЛЕЕЕ№љ|№zН№zНhll”ЫiПпнЛwыїгяP(„……ЬЭЭajj …B˜œœ”‚€зОіЕ8rфHёёЧЏ) ;SПZ™2жn—/_6}я{плћрƒž>Ю^ЕгШn&`нзззПп—^zщ†КђљќŽd2™ ЬfѓŽДЎзšі!)ы@ Аъ>М^/jjjрѓљVН/Y}}=ъыыБwя^§Гаˆцљљy„B!LNNТd2сmo{[jnnЮўдSJX™2ж`БX /М№BGCCУьў§ћЏŽŽюОе6~hllФУ?ŒK—.сеW_]W.?“ЩьH@•э мИ…Уa]^X4^Џ>Ÿ ЈЉЉгщдc2™J@ss3šššапп“Щ”-‹Х\.gљф'?iQ#Ж•)S`MžІiЦЙsчNxНояэкЕЫ;>>о˜Щdж2‹|KЃўjў–e…:„žžœ?###kJ ьT`Їщ№5d2™ЖЌ№snnsssЋn'еЫ†† ј§~дззызlБX„ХbЩf2л?џѓ?[^zщ%њќ”)SІ@ЕV,ё§яч>›ЭіьЎ]ЛLѕЉTjKœџfГ^Џїо{/:„ѓчЯcxxИЊM~'ѕТ‹ @БXмqрЧd2m)0ВT*…ййYШЦe{<ј|>ј§~8މ@ аџйЯ~VэŠЪ”)АvЧON<—Ыслпў6ьvћ=йlіl___vjjЊ%ЏЩљo%PX++PSSƒ{юЙЧŽУЕkзpэк5iо–l'ЯИ€џўпџ{WБXќщ7ОёЭ@зЎ]C(Z рЗ]-‰р‘GAБXФ/ўт/іг%f@™2e ЌЫтё8ž~њi˜ЭцУЙ\nlppp(ь™™™)‰ŠnдљЏ$мшhUzОгщФСƒq№рAD"\НzCCCˆFЃŠ`рV`~ћЗЛРЃоЃiкk4Mг‹ш …0<<Œ‘‘d2™ŠыУd2mћЮцццUзrўЪ”)pУ‹Х№/џђ/xупиЩdbЧ?чѕzї[тёИtГ‘Е9mFфПL‚ЯчУwмццf|упа рv2ШчѓШfГліЛџоя§žГX,>р}&“щ‘bБhцыё8qтЦЧЧ1<<Œ™™C@гД[Bќ‰"~~=( L™7l‰DџјџˆзНюu‹ХrЈГГѓкў§ћ§sssѕгггzdhфј7‹%И‘Ј_ќпd2aїюнhnnЦгO?я|члHЅ’рmдлй n6рПЗƒ§ўяџўxІijšцзIЙП- zzzаггƒD"ЁЁ! k_P Р­Р|(Ъ_™26ЭrЙОўѕЏ#рс‡о‰DR}}}MMMm“““цљљyУ(§fВеXcc#:Їг‰d2‰ŸќЩGабо‚џѕб?ХтbЄфьФ.€эўшўш$9ќbБј“ЩT•У/'­KuЛн8rфŽ9‚щщi cll _њв—рvЛёрƒn{чop•)SІР†йЫ/ПŒёёqМуяp˜LІЮЦЦЦХН{їЂНННіњѕыЋzœЋuќ7ƒ%p88tшZZZЩdЭfА ряПјYœ9ѓ’+S№v:(‹[*ƒќПўзџr‹Х“^УОчFœ|ЕЗЗЗЃ­­ щt###˜ššКхЮ9е.]gЪ”)S`]Ž‚С >ўёуо{яХ# P( ŸЫст…ѓјлП§$ІЇ&…яXкћОSknH ЅЅ‡uuuhmm­ћпџћ?  пd2еm„3ЏжБпШћp D?лаgЇ"FeЪ”)АЁ› §N&“јќч?gžyя{пћДУ‡Лгщ4ъъъ2ЭЭЭцh4jО~§КaЅѕZX‚Йнсp`џў§шьь\‰ц /.тoўцЏ№м`rФРNєєгO#›Э–‹ІІ&˜ЭfдееСnЗЃІІNЇ>ŸVЋ %QѓЪпwWыЈзњїfrЊФфr9фrЙmЧ 5 (SІРцкЬЬ ўјџ'OžФЛоѕ.иэv[>Ÿ‡ЧуЩ=zT0ŒŒ`rrr]QєzYMгаггƒX,нБ?ѕ/џˆ/~сsHЅ’eYюєRЉд-‘ЈЏЏG{{;’ЩЄЕђпЩdVЋЕф6њлщtТэvыЧ’ŽgЁP@}}=l6›ЬЉKџп‡МQo4€(‹АйlАйlШfГл‚ хћ•)S`УЭHtDг4МєвK8sц Nœ8ЗМх-4 8Žтапп™™mbb‹‹‹хmzЕЕЕ8tш>i­X,теKёёџLNŒWё=KЉ^ŠјЖЋйэvьоНRg\ЮQЏхqВ‘Ж›бпLf кз# P(Щdnка(’-VЕЪ”)pSэЬ™38{і,њњњ№–ЗМЏyЭk4ъПюъъBww7тё8&''1>>>gрFЭfгщ~ВpxŸўлOтЛпљVеЏ)2™Lf[Mгаее…ЎЎ.УПкЪkqшщјЗ p# Сl6УсpРсp —Ы!•JщsЖjˆ?д  L™26uу‘йШШ>іБс _јоќц7у€Ус@БX„лэF?њћћ 199‰™™™rВЛvэТРРЌVЋюФПњЏџŒЯю3H$тkz­Т -NЖ•kkkбллЋŒ]ы„Фѕ„Е>ЎgП€aЌV+ЌV+<’Щ$‚С ЌVы–EцŠPІL€mЁќЭпќ ž|ђIмuз]ИяОћаззЇ?ІЁЁ 8x№ fff0??_uбЯчУсУ‡uКЎ\yŸјјџХШШѕu}nА]Šэv;zzzP__Пю1Щыы[сь7’X˜pЙ\шююF[[ІІІ№Т /`ttБX mmm›‘ѓЈŸW…”)S`k>mŠЂC‰ХbјЮwОƒяџћhkkУНїо‹{юЙGwм‹­­­hmmАм‚6??ййYФbБUяeЕZБoп>twwыЗ--E№щП§k|ћ[пИЁяQ,Wемьі/MгаооŽЮЮЮ q&ы›‘RиˆєРV0"АpЛншььD{{;ѕ‚Jj9=ў<ОёoшE™› ј4@Х(SІРЖdцччёдSOсщЇŸЦў§ћqтФ Ÿпt@МіPІL€mo”.HЇгИtщ†††`6›ѕ‰mЛwя.Щя“ХbQ|ця>…o|§Ћ›№™VЗn%0™LшююЦЎ]Л6Ÿ/Y{ЃЃЃИ~§:Ў^НŠссaЄгщВПлl Дџ)SІL€эЧ”ћЁ ˜6KГйМ2В7Пjѓнt 0›EсЖЖЖтФ‰КЕ@kЋЃњ­еоg6›uкочѓСяїУяїУэv—Ќ'ЊвOЅRњњ"–) bxxCCCИvэЦЦЦ6$ѓ5Н™@\ЌPУ€”)S`K7yЃшОZPРGЎвІ)›ЩОщ@ЈишНдэvуЮ;яDWWзš9чПе,СFГВзђzНpЙ\ЈЉЉAMM œN'М^/jjjV 'Ђѓ%@ЂЧФb1\Лv ЏОњЊNщЫє%n„ “­еЭdФу)ВpЪ”)SрІEќеВ"§Я€l#лlКГЁЁ`HWџлЈ"@“Щ„#GŽршбЃz›X90U-P-KP­ѓпŠтB‡УЇг —Ы‡УЗл ›ЭŸЯ‡Уššš5­/К=NcddУУУСшш(FGG‡Ѕ)ЈЭrШє‰ХкLРSTЈ€2e l‰Ѓ‹жВaѓv)ф\x4З•)Ÿп‡#GŽ`ffSSSUНŸйl†Эfƒйl†нn‡йl†Хbб7уЎЎ.мџ§№ћ§p8hoo‡Хbбe†5MУвв’ўz4PЦшИn ИF€žgГйєŽ…bБЧЃkплl6=НQ[[ЋГ\РiН–Щd066ІџŒŽŽbdd333ЋŠN7кс–;циђuМVсuPІL€эУШ"rў" пВъћЭ&MƒеjEWWккк№ё>ŸАйlАZ­Алэа4MЦSЩЦЧЧёЙЯ}o}ы[ё†7М.—KWŽЃоqЃЪBЁPШтёј*–Bt|ХbБXL?Ž4™‘3ІїЗйlp:%zѓ>ŸO6TИШ?ѓFQаSSSƒ˜™™‘ž˜˜Рдд”NпбюлЩ6Ћƒ„зЧЈ€2e lЊU§‹GŒжХџ+оx3M3Сd*ъ№фЩ“7ќš===xјс‡uqёЛ‹ЮД˜L№ћ§Ћ(fЏз[БЈ’G ќ~Ї1Ђ#1›ЭКгЯfГњџќѓЎХё„Уa„B!,--annбhуууX\\ФєєtйДбvИхОїf‘і/‹%BEЪ”)SрІnŒFLєљпДYЧг%qqsk–7д ЦЦЦ№™Я|8qтš››a6›сёxрt:a2™tЩ_“ЩЧГJ ЈfElЅфЮ_,ŒЋ†*'чBЮŸ˜ К-™LbaaA??@‰DАДД„`0И~§: …цччF+v…мNЖY€RG2гF/`eЪ”эlPЎ:нШ9•Ћ EџмYQq“ИЩm:`в`к„j:Цьь,BЁbБ˜юL 9l“Щ„ККК’лхQШVЋЕЂ3ѕћ§АZ­њы%“ID"‘U•ѓ"“S,‘H$‰DJЮеEШ‡бmќілеŒŽсf3Ъ”)Sр–и eЙjБрƒiNsГkL&hšiг^{=фќќќЊу7;;[•ЦBЕŽЙкл”•_уМCb3@:–l•џWІL€Œ%еЯkЉ"щ]Šђeї—Ѓ…7л™4Šл(Л5A.В›œx @RB@Ъ”)pS6@ЃMQL1rєbРътВЭf4@3+ ь†ЏƒЭœ˜JЅVuŽ№Т@eЪ”)Аa‘ЅNЎЅ k­Х`›Эhš šikEЉпњŽžЗ­ŠЗиT€_Ѓj-)SІРЖŽˆжТˆїo`‚ЩЌe7 Ш6‹H$ЋКd”€2e lšѓц›L9ЦРh ˜ X 3АU €Щd*+е{#f6›UЄv8xОжљoDЭ…6*”ЭYP@™2Ж§FZN+рfйfХь<АА™ €Иž˜ѓW@™26/*W p# УЭ6ЎЪЗY \БЄВ[УdL–ыЕ=ћд ‹ќ L™З\ДTн}›_ e’ѓљќІR\”W”)S ъHF6бЏкhtНQkЙZ›Щlv @ЅcЈX€[пљ‹Уœ6д( L™Ъ ьfЊи ЧеVІL€пМn„AЈ6Ђ5ЪyЫtЖ2 Й €ВлЧсѓѕЫ^mДeГй5wш(SІLeŠPЖE `Г@*•Rщ"eЪИёj-šў›eтћoхР'm6Сbй|Х_—sЅфvћ9њНY)€t:]іњQІL™Ъ ь&ƒЭ4N›:PІL€maF›бZ6ЊЕv&lW jnП(ПмЌ rў›rЙ\Щћ rР (SІ€В5M1Ъ6Ю6ГА `Vћƒ2e Ќ-Rпш\єZ‡”ˆуMхбжц7* l#˜ZЏ›dЏIзŒХbiTgB™2nЫu3Эl6oZ bfwоšн,ЯчЫ­сZuє•)S`л9XЃЈПR$ЕUŸЯdвЖ?AgчЎMџjаЮГssscщ/хз•)SЖM€еЏхё2Ж€?fЃщsЗлƒСCЧаЛ{Я–:eЗЇiЌЬЯЯуњѕыHЇгe#ЏўчяOПџъЏўJ˜mj?џѓ?Џ‚2ХTkерp8pш№qьйЛoЫ#rХь#ЇМ022‚ббQЄгiX,–5ЏUPЊL™75 ЇјUЂ.ХћŒдoД…ЮfГсРС#иПЋѕІv  iL&SйѓžЩd044„‘‘фѓyНh_G2нёzQЮџжВЬЮ8іBЁ№С|О№H>Ÿo)Гй”4iк‚f2MjЎhšіMMгО‘LІч6у3дзyзѕМЗН§] м [Џ йbСў§ƒ8tјьі›;%U€Ч1‘H—.]Тшш(ŠХ",ЫЊЧЅЊe(PЖœў}…BсCљ|сЮD"х_НПч:V~ю№o–їL­`2™b&M›вLкeMгЮišі\2™ўšb60jЏvГЉ&Ђ_/U_Ў†`­ƒt4MCџР?q\.зЖ8iЊ`ч8~~ЮщМчr9\Нz/^D а[N­Vы*Ї]эZчзХz_C™ВMrњя- ?—ЫхяJ$RЖѕМF>_4хѓ//€}NБk+i2i &M›дLšЮ$ЉЙл§иn8И‘ˆc+l-)€Н§ћpќФ]№љќлъ;(`ч“Щ„щщiœ?УУУШfГzДЯСїNŠ”Н†RžTЖ•цv;mХBёзѓ…ќ;Вйќx<ЙЉOЁP(ЧФЭ&гЄfв.›VXƒx"uлА ž,‹ЇnдљѓШПмFfЄ`љѓ nх†ЏнНЋwоu/šЖхI€ŠаnoчЏi>ё‰O ‹щЕ2(:n1‚—]WМтŸ+цѓљh6›§SЕО”m…yмЮЮBЁј\>џh<žl/‹7=‚\a jВЫŒA k`Б˜“&“i!ŽNj&эŠi™5јЎЧуšиЉр Ж;`$мвк†ћБбвкЖ­Ošbvž---IЉ9щ­w­кыХbЙ\юєg?ћй/) lѓœОыPОџЕ|Ў№p4–hК•>{6›“ВёDВ`6™у&ГiвФj М5юmЩl$јюZвх*’ЋeФлXYП­ББwп{zzvп‹O€eќš’§Эџ—хэ˜€ рџЃлюОћnu”mˆ;ћЪђ…ќЏцrљ;ЃБxЭэі§ˆ5@Ж”5ˆЧ“(ђa“I{ынwпћэлМќђЫГЧ?],oW€“f‚п_‹{юНћмR‹L€ xд/ЫљSдO[ gяёїъh+л{х•3џ1ŸЯП;“ЩШчѓ;ІѓLг4 y„#,.†сp8ќ>_MђЖdV6ŽЯЈmTCKV "Œ"§rЏuрр!?qђ–”Eх”яvNЗl%ЈЛiъrЙћr  Ts|шyљ|ўъOѓ™Я„оїОї}ЉX,ОЏрF#ПrЕВџХ)‚љ|бh‰Dѓѓѓ0›ЭEЇгYt:&vЛ}лFНЪpУmoЗћБрEЙе\…B!•ЫхўќтХ‹ъ€*+k/ŸyщЎ\О№_sЙмНщtІ~'}w“IC6›Хќм<Šњњњppp%[\\Фѕыз122‚P(„]ЛКbЗ-АВќžІiяб4Э\ 5Пœ)“ZеВйЌ–ЯчЧ a6›г6›-gГйœ‡Уфp8рrЙnъwR €2vНСd2ЁP(”DQD_I4ŠGџ…BЩdђo>ќс‡е‘U&ГгЇ_|k.—џхl6{g&“uэЄяn2iHЇг˜ŸŸ‡ню@oo/Ž?Пп_ђИљљyŒahhбht[ћР O<ёФ•їОїНŸд4эчЩБЎ'O-‹фз[АžїfНжі\.gЯчѓHЅRњk™LІ˜ХbIйl6ЭnЗзлэі-S $wХм8‹В]йYўŸџ-‹ьЋeEdЏ•Яч‘ЫхЂ™LцCju(уів‹/ќF.Ÿ{G:•9œлAE|фє“Щ$цццсѓљаггƒ{я} <žR&jj cccИvэтёј-Г7oЪЩ,‹П](е4ЭW-ѕИнЮЌмю) žT*U ,˜LІ˜йl.иэіœеjЕкlЖVЇгiпЈяo6›a2™дlїhх ўЪ‰Ы#ВWЂџ?RбПВгЇ_ЌЫчѓПžЭdMЅ3н…BaGm2&“†D"‰ЙЙ9455ЁЗЗ<№к’ЏX,b||ЃЃЃA*•К%ПыІ€'žxbъНя}яЏ …ЧYФМ&РAУzœœ,2Њ†iX/@`џз‹ХzJ#p@иl6ЬfsвjЕšGШfГэrЛнI§<•Јi]c^•U%oзЯЬћЪщˆЗ‰‚@ќБ…Bйlіj.—ћЕ2vj”џќ@.Ÿџ`&“}$•JЗьДК“IC<Чќ|mmmшыыУы_џz8?ќ–Ых099‰ЁЁ!Œ!›Эn˜Й­|ц3Ÿљф{пћоЗkšіёнЎQ+O9ˆпweУ­)‹5љ|О“R ‘H„W`gѓљќЙeo`vЛнсbБXєљ|‹‹ЅНЖЖ6˜ЯчыM&г[)їЋL™АuppЯч3ёxќ]љШGrъюъ …Т^ŠЦо’LІъvкїз4 ‹# ЁЃЃЂЛЛV6ц=“Щ`ll УУУG>ŸП­ќиІцs …ТћМ  ЈnŠз#7Њђ—UіWКOМ­м­ ќ{RT_(ЌfГљаЪF}АX,"ЃP(`qqQпРEFEUСя\'oЄјg4ЩG§є“H$~§#љШЫъШюЇЫъtoа_WчG]йl™L™LЉTщL™LЙ\ўЖsњ‘HБXннн8vьКЛЛK|S2™ФШШЎ_ПŽББ1щў}ЛиІ€Я~іГЧ{ьЭ…BсYNžCпj›[сФЩъ%8Э_NоU™2 ˆŠœ-т=џња‡>ІŽкmы№Э^р‘Чп.{œеjеjл]z{>_@&“A2•B&A:“A:E&“ЙEўђžКИИˆtzЙGџюЛ ЛЛЛфqБX зЎ]УШШ&&&vcНщžxт‰W{ьБwј23EНта 1*_kŽVV-Нб a-]7ъ˜•cWЦзQ1­б Q˜њ?“Щ|/—Ы§Ќ:ЪЗ—=їмГЙ\ю.—ѓ.ЗЫuШnЗ­[sпl6СщtРщtЌК/™L!Ю NЏƒ ’Щ›_ З,С[РBhХ"АgЯ=zээЅиgii WЎ\Сшш(fffvdAѕ–Дt<ёФ_yьБЧ~РЇѓљМtSЛй F™Вл1тчЂWмrЙмKйlі‘јУ*яиŸ§СЁl.ћkщTњ ‰dЊAмW]N'ьь6ьv;ь\Nч НЇ0HЇг+Р ƒT:d"…t&Гj nєžЯч …`6›бппЛяЙg•0O0ФЕkз0<<Œ`0Иуїў-ыщ|т‰'ўюБЧГišіИёЫFWЊў_K.-'ЙвР^…}#›u5Q~9=wХlOлh}jtdы‹б …Т…h4њая§ояХдЛuэпц ™lцWSЉєЩdЊl”‹Ч[щJтfЗлрАлaЗлсpисt9`ЗлaЉЂ^ЫШь+Џ'Z6›C:F*•F2™Bjхo^MП#5ОPh.— {їюХ<€ККвzЦййY\П~—/_Цвв’ јnXŸ|ьБЧbХbёгlЂ3WNM™ВЕILЪђ§ќКЪхrЯФуёŸјƒ?јƒИ:ŠЗž}я{пљйLінёDтD&“Нс§;™LIi{‹ХВ ЫQОУa_qьЖuПеxќјя]5Чe||зЏ_ЧааbБиšA6|с=яyЯЌІiџРCcK9(W§_mw@ЙHZМ}-uы‰ўзщW*РД=ѓV0Fы—Їˆe?i2™ољ№ŠіПeЂќяyВЙмгщЬЛуёD_.—лёЬJРвRtе:vЙœЫ Рn‡cхЗЫЕўt‚Щd‚Ых”ОF"‘D,Ча№5,,„аккŠ}ћіЁЏЏnVБX,122‚ссa ыТ<Ъщo3Ÿ§ьgПћиc№Oљ|~??QВъї[iѓП‘ЇКВѕZ>Ÿ_•яЇѕd2™ љ|ўwчw~чПЉ#Е§э™gОЛ;›Эўчd2u*OДn7%Оh4†htuіh™)pРщXn— ‡fГiЭЏ_SГЌ‡цvЛаааЗЧ‹нЛwЏцСеЋWq§њѕ’ЮхјЗ1Xa†{ьБ;<рQMгt}{Šne9LЃю€Еt TвIп `”ппˆяАэvЙ зЩЏї|‰zЂ ПN0Ч“ЩLЇгяџУ?ќУЏЊэnћкwПѓэЛ2™ЬMІRїЦbё[rВ^<ž@<žXuЛЭf[N'8№ИнzJСfћQ:!\Рдє ЦЦЦhxїЛоЗЇ‡ &“ MЭm– Џ]Л†ЋWЏbddЙ\ЗТа9ф р]?§г?§t>Ÿџ3ЌЄDэ§m­”Ибз•->БpKE§Ъ6вdЙ~JЉ€йlўn6›}їџёЯЈЃЕ§ьлпњц[гщЬ/Чу‰ЛЩЄѓv§žЩdЩd‹‹ЅЗ/Я3ђљіюн‹7Оёєєє”ѓфѓy\МxQwњ[­!ЃР&лЇ>ѕЉПyџћпџЃiк§мљSTcјmFNиhѓЌцОJЏ_mdПг§­ЈНП›Ќ @&чЫc2™ђЩdђЗџт/ўтЗеЗНьпxњ72щЬ;–ЂБУ™LЦВІiˆ.-!_(,Зын}zzzJ“ЯчЧHФ‘J&№еЏ~UEљЗ+€Oњг#јйŸ§й_ШчѓЄišW Ђ xхвыuBFЏ'ŠЎT+8TЮёUp+  Ќœё”_;М^Цd2ЁІІfш‡?ќс'дЛљі­o}Гy%Ÿџh4ыЮхr;жƒ---Сd2сРиЛw/:::Jю‡УИxё"FFF№š{яT‹g'ВЧќу?љ“?љююю/фѓљВhˆР€Јv&‹оЋ‰ЪeЯ-Ч0Meл …@ЖoГUчЧhmse?Mг`ЕZщЇ@-œ›dџп7П>Щd?˜H&YZŠЖьм]E„УИнn `џў§hjj*yФќќ<._ОŒ+WЎ @Щ0e; РьььтёуЧџХщtž˜››C.—+a8#@Q§MЙЃJЮПP`$Д":џrР`-5Ъй+3ZЇFt?9~ЇгЉ3d&“ЩЁFEo­}уOп—JЅ>”ˆ'я\ŠF§; y„УдееaяоН8x№р*aЉ{ётE„УaUФЇРjГлэNЇг‰њњz$ D"щd?}S”Ш l”sхЏQЮљНпfwмЬHxЇ:шЭŽіiM‹`хлэ†йlжПйl†йlЖhšІаф&лзОњЏ?“LЅў]t)zG"™ДэФcАм}’C8A{{;іьйƒЎц!QžK—.)aЊј`‹ X!ьp8pљђeиэv444 ІІFъhХZГй\–ж_ЫИ`Ћ­ЭgЏІхяv)šSЖ60![wуїx<АX,њzЇГй ЋеъT Р&Dљ_џš-“Эўz2™zG$9NgЬ;ё8hкВo4Eww7АoпОažBЁ€ссaоO$*вW њ=бfГY- ЬfГNѓGЃQDЃQx<ьнЛЗ$5 ‹JiЄЮЌwЃЎљЅЊ o5ЇЛ•ЭЮё—…мсгпšІСсpРэvУjЕrКП№Ў€'T Р†иг_ћзЮt&ѓx<ёh$ВдОS‹ј4MC&ГЌспее…ССAєїї—ѓdГY уТ… F:V_€ѕ3&“ ‹EwтфШcБššš`6›СkdєЉ˜3хb)ВhЋP.ч/~йgR‘ОŠєeыBtјєc6›сt:сvЛK"}1ђ~Ќ ЌпFG†ZœŠХтя4™Lї S6“EБXРN*шг4 ЉT Й\ЛvэТЁC‡Аwяо’"НT*…ЋWЏтќљѓИ~§:ВйЌŠєИёНвjЕКW€@ ­O kY]j9"ЪfГ(‹К*wЊ‹EJс‹гЙCЏФ=жшљ7Rh”ТPЖ9‘>яЕ/WФY-C ы 1њсЮпсpРЕ"ЅЪS[мљ“rІџ‡ХbБyН^ЕћЎЭщїx;€Gм {іь.y\&“E"‘@8A<‘@"ž@,G$Вt[\—šІ!™LBг4єѕѕсрСƒиЛwo sЧqщв%\О|CCCkъ‚RІ@UРbБи‹ХтЊ<'m‹VЋUПŸoЂЙ\Ў$*FUМ}J2#ч_ 3`фаЫ *ћEљ\ок,ZqСуёшЮЫcѓџ9b``Р­ЮFEЇ?€7x@O5ЯБйЌАй|№ћ}ЋюK$’ˆ'ˆEcˆ,-!O ‘HЌЈГ~<‡ЭfУО}ћАoп>ьйГЇф1KKK8wюЎ\Й‚ызЏ—8|хји р, Айlzюž/4Л}YKšђЁфдЙsOЇгњ44юќyЋ ЌТZVXШїzМЂњЗoфП–bLЮTrњ•вJД–ьv;œN'ьvЛОЮe?нй§аѓъъъьЉЇўй“NЇ?‹Х3›Э55ЛЧэ†пяƒЫх,ЩgЏЧhЂ]cУj)џЅЅ(тё8тё"KKˆFcˆЧуH$’7i§/нqЛн8tшіэл‡ююю’Ч„B!МђЪ+xѕеW199ЉО[јС,+M5уmœ6›MёsчЯџOЇгШfГШхrp8%`R јmМ‹€6`ŠфФbBЃбпž~ЅZr5&ЂгЕ-ФПŒъ7rќєлэvзЈГќѓWўqw*•ўЯKбшЉХХpkЙ">Гй Ÿз ЏЏnЗЗ>ПоšНiНцѕжРы­‘ЎЇХpБhёxБx‹Ё0bёxЩtЛВx<ŽккZљw%’ЩџЦю]XU=YЏP( ИА€рТТЊћ–[/нЈ­ѕЃЦулГ ъъjo˜‰ЊЋ­E]эъзYnЕ‹aqqФcq,EЃ‡#U#‹E$ ДДД```ЧŽC}}щ!УХ‹qіьY,ЎLьQћзЦšнnЯљ}оч5MQ ŠukБXœ|В™XhЗлѕ*,шЇЧ$Ыљ9ЋеЊ:Ю6 ŸЯы@€ўЮчѓњцKэ‰”R ˜_@k)2TvsС€Q%~9P)Ыэ3KwњTЋ"FљЂг7rютm2&€зиэvзN:‡џ№џжD"ёЫ‹‹сЛ—–Ђ~hЂ] \uŸЧу†ЧуAЧƒк:?<юхџeџZЬjЕЂЎЎV 2‰фJёa‘ШЎ\*йч‰vэк…}ћісШ‘#№љJkЎ^НŠ‹/тТ… %"kjкHЇoCMM Ьfsц-o9eW Рк€ƒгъ"@ЋЭfг1mТbЄFЏ!>†,“Щ Ncii‰Ђ'ИнnиэvфѓyНuР@Й Zє™9тAI9JYйц8y1j—9txВЕ%ЃіЉ0•и)Y„OkBтmbŸб§ВзZђОѕ­oеОќх/пЖ щ ŸџмoФ‰w,,,N$’7m/‹D–‰,IяЋ­ѕУуёРуqУя[.єxмpЙn ŸQНAScвщ ЮЛ€t:нЛwcppƒƒƒ№x<њуѓљ<Ў\Й‚ѓчЯутХ‹ˆЧуЪсo‚йЌVx}^˜L&dГ9фry˜Lцќv§Мл˜L&w˜х€ІiШхr%їбГљ|^паeNЙP(ЌыФuк–оЫщtъ €бцЬХ‡шЕЫ]d"•ЧAЙЩ‡ЪЪ;w™Г– ьˆџѓu"в§b”O)"ЋеZ–жчkB&оSю6Ѓ5&ООŠХтm7рўся›гщє^ZŠ>КАъЮd2ло{-,„ААZuЛЩdBm­>Ÿ5<5дзеЁІІ6›ё0œL&‹‰‰ ьонЋя/ЕЕuxЫ[о‚}ћіСщtъMЇгИrх ^~љeМњъЋ%Т<ЪёoœY­Vј|^X-dВ9€хVuГй ›mћЊDoћ.~СШtЌVыЊј}МРO&Е*‹ШГй,2™ –––x~6› NЇS тf/‹ќЊеЈ4JXќЭСNЅQУЗКS7ŠТКxne @d…ФџЉоƒи&ŠєщœŠtОЬсЫЖ,к/'№# т{г3›Эюl6Ћсњв—О8L&?‰,=o›Щz…B@PšRАлэЈЉё ЁОžь6+Тс%LMMadt ‡†л]ЇгMгадМ\Ь—L&qётEМќђЫИrхŠцй$3›Э№ћ}АZ­Шхђ(\О Зсr№О2S€ЕьџfГй%вЅ"`Гйє6AžŸч˜G§ДЉЫ˜ЃПe…`T? …`2™t@@є/~б•ЛјФт}2н‘! Э”•*е7њЇ….sоFбКьu*9uШНXАGŸ_аќ\rgЫОP)ђ7Ђљ0dS2ѓљМ“Кhn5ћт>w_,џP8Й3\№я4чBћЫммќJдŸЭfУ№†Ÿx#іэлWв…”ЯчёмsЯсмЙsИ|љВцй4Їo‚пч‡ЭnC6›[Q–-шiaц№Ёiš~ЛнnW`=)Y4ENЗђ‰iЂqvКHљŠNСhюКЬQK цƒ9DTБб`ЂJЋЈbXэ,r’ФыFК •œxЕЮОœЏЪ=VFёГс9%QЖx>d ’2–Ч(: ќ*ђ‰Т>FL‚QбщЪ§о[Щ<ёФп§\<џ7СрТKKQлNw6™L.— ‡Црр JюЯчsˆЧЂH$тHЅ’јмч>Ї"§MАх‹_Џ–>еƒ@Ь пOш17кBКуРлпўvЛІi#z“ђ.6›MЇєE%?к№ХœПЌ6@жоUЎЕKLpЇЫo'`H$єЧаЂ @‹ŒўЖLe oK”™\­QŠ Z``T!/+Ј+жСW тЙЃsO‘oђI‘хР”й€rЙx#Ъп(кЇ5"{žЬёгm’TŸЮЖньяПјy[2•њѕX4іŽљ@№@"‘0яtg“NЇсѓљpьи1>|==Ѕт„@/Нє^}ѕUМѕдO)яМ‰V[ы‡Ус@>O>ЂГйRBягuJ{ М`мbБ(`-жккъц›(пhЙ#хH‹GUхŠЛ*EГ"X0r.ЂГчЙIйпЂcтПEњXЮхQы-,Q‡ вЄAБбˆ}(ЪІ­ жЪ”ЃхХлeМХbA0D6›бпїо{/œN'ЦЦЦЭfWžJщёoЃМЛЌЯШбЫДќщБ<Ђ(ЇРo3Іrжддр?ќ‡џ §Х_ќХЖи€>џЙ':“ЩдУсG`ћ­PФЗNПЕЕƒƒƒ8qткккJюŸššТ™3gpцЬЬЬЬш-аЪ6о|>/\.зЪžГьє…)›%ПЩС“Учк1P РZЬхrеѓ]dЈ-q'"‹юd­€ќё2Р`t›ШШю—™#j&“A2™длаа€BЁ Ї8`рПe`9& \š`-uFЉ“j@ь3‰б­˜ї–9mЊЉЉЫх*)•9{йэеЃп0Œ@иПЯs0,~ЩдKOmm-М^яЭІіЧbёп‡УЏ››oищ-tmгHнЛюКk•0ЯЕkзpіьYМ№Т …BЊjЭы]V}ЄeY,&“Й$%HsчЮМьv!P Рš>”Хт3ŠzШ(џяp8Эf+:@юмhk™œoЕ"1хœП §ІЧЛ!ћ_0bкƒgŠ„ЕŒШtˆЧšЗЭЩXrL<в•1–Kanв:Блэ%9;йѓd€б(ї/ыщМЌК_8А‘е Шш~йчрwхw]]~ѓ7sЫ7ŸПћєпО!ўъB(tg0ИАу%‰i.ЩоН{qј№aмqЧЋ„y.]К„W^yЇOŸЦвв’є+лsЛн№zkє"ОbЋИ8x™X^єGбПXќЧoчvмэЪMј8Э-лјyёЖОJХZфЈФўњrдИlО@Й(иˆі/—ސН&wјфШxWƒЌвŸ$ЙS Уйžцр ”‹пШв2рСБEЋв(]zЭJ)rКе“t3—Œ™ёћ‰`@œюhєSˆOЙZ1в—uˆ,„Ќ6D8Цю­ЌјыO~т?FcёwЯЮЮˆFЃ–юdŠХ …"њћћqќјq;v ќ|фr9\Мx/НєЮŸ?h4ЊŠј6—UF­пЭDћƒM3СfГЌŠіХœОŒв—EћтыˆЬоm Ž?ОЎчЩћ‡?ќaOЙmє2J”GJтЦIЯук§Ђ•+ю“хЃљcЙj\9PЭэ4фˆ>?Э…ЇЭCŒZЉи‘ŠлdЧW6.™Ы‹ E<.тw E@ФПџr2Щ"ЕЭП“QэЏф Я| 9єžbЕПьsз­Zwb„/з+vЕŠыWtіВЂ?‹Q,нvЛНјЕЏ}MWЕ OШŒХbАZ­ја‡>8}њєšЎлб‘!лтbј-g^~хƒ—.Нz<™L™vК“ЁЮ’м}їн8x№`‰т_*•ТХ‹ёмsЯстХ‹H&“ŠопDs8ЈЋ­…йbF>_@Ё˜иˆybЫQјт}аыTъф1™L*АV@5ђS,ќ1<_ЪŒŒ’‘ѕЭ‹ЮС(…Ря“1хђсb_:§&бњLЈ{@ŒЖi‚dјw ЯРЃdйИc™:ЁШШX#@d\d DцдЪшнЮ'8в&рt:K™ГЏfД,"/Wљ/2FЂ?"(GћW[ИX,‡ёxVЋUЏƒ˜žžF"‘@CCC‰Tl•NПРМРыkk§žз=ј^їр˜›ŸЧBpѓ ‚ ‚G";Тщлэv‰рЬ™3xщЅ—pётХ’ыS9ў7›ЭŠКК:иэvфrДпЂ$BлѕŒ(~Yў_цшEP`фјЗ;УГ-@БXєPŸЛ‘ё –ъd›-9)ёФˆ@VIo4*жЈ[@Цу#‡+ы——ѕИ/ї цѕЧSЧз8рnЂ "§pњ]І‹ ЖBђZЎSРЃвrРшиёЯ)cd›Ѕ‘Р‘€xjˆŽ#EП”њЈдњ(K5№Я#^иВM€ЏQYН€Q-ЪŒ:ŒX*fожжVиэvЬЮЮЂP(  !ЃЉЉ uuu†i>ё‰П5џb[kkggGGSSуКђ˜‹mm­hk+9ŸH$0?@ Ф| €™™YA=ЕЕ-—ЫСяїуФ‰8~ќ8іяп_r(ТsЯ=‡3gЮрђхЫЪсoВбЄDЇУ‚Оє5]Ž;nщгџbд/2bA Ќ3GVЌЫ}Olзю—mўђ/џ“““юХ\(?Рœђ•m†ќФђMYV=.:юHЪQаFsуeМ*п(тІƒњйЩ‘­HМ–€ ™є/хєѓљМ>$‰*Tш~‚шЙВˆ™ ёЕФDЃcT%4м< 7щ{ашfžЄеЮP12! ”ŠtПь~qѓ Е,+њ“§6bAVж‰ЃЉЉ sssXXXаSDЫcjНˆХb%ƒcўќЯџЯo,-Eп1==}8Yрьйѓњ§uuЕhjjBccš›бии€ІІІu]у.— ЛvucзЎю’лУс0ццƒ˜Ÿ›G ФььмMuњMMM8yђ$юИуєіі–м?;;‹ў№‡xщЅ—022Ђœў&›йlFcC=œNђ4ЉГˆUEЗхŠіЪё‰}ў"‹WŽт7кЖЛm;рѕzQ,нхЂ21вхб’ЌBZveб&?a<в5Ъ_QихФ‚Ф–:™VНŒђw:њчЩfГЋ&ЪЂorўDёЯЩўнШб‹™и.)‚ў[,д+з! sЖFQИш№E&€+-€гщдЪПЪцBШ::ЪQяFŒ@5t Qд_ю{—K}€$ЕЩ:NНe‰tžњ—Џ4'’Щџќ;ПztvvЖ;™L•ѕZСр‚С…UЗЗД4ЃЙЙ h^ЕЕўu]ћ~П~П§§{G;‡љР2c077@ ˆP(ДiNПЃЃwмqюЙчžUТ<ЃЃЃxёХёќѓЯcjjJ9ќMЖBЁ€Љщьп7ЇЫ`0АќФ УСхrљїЪхrњФ;б‰ѓќ3Џ%0ј)ЙЫђёВѓ-Fь2РEЉ \(џoЕZѕcQNЭ#FI\“FећтZ2FбНLџBfiG,Ccc#:::ЫхpіьЫc|љх3?555нДУ‚ІЇg0==#аГ477ЃЅЅ-Э?nЗk]ябвВќZмВйІЇg0;7ЗœN˜ ‹­ЫщяйГЧŽУͿ††’c~љђeœ9s?јС UЄП655бБqLNN#›Это{я•FїFQНQѕОdic#ч/‚uОЯм'( 1ЪOњ|>цP’X ,nˆтPБ/SЌр›ЖиЎ&цeEа :AnЂ н&RэфœЉjwPС#§ІчЪœЏQ­њщ§ХH”ПП-ѓуФ?ƒxЌŒTЫQз"(ŒФ—јљЅЉ‘д(ъџЫR6х„‰Dp ;џЂHЬЉWВJJ‡•RєЧkЏ_>G> яœžžёoХ5Ng0>>ёё‰’лнn7š››аддˆ–цfДЕЗЂЉББhVŸ–зФуёхТУЙyЬЮЭaffssѓ:ћУЏƒƒтФ‰ИѓЮ;Q[[[ђ:gЯžХK/Н„чž{‘•nх№7зъыыPSS@УwПї§šЂьfГYџЭЃњJ”ОQЄ/kЧхmт№ыйH—Уˆ!T)€2vљђe$“IькЕ ~ПщtХbБ†чџЋzdє­ бЩ(]оJŽОмРйІ^ЎПGЅbОш ѓљМ^№GЏIŠSVЋUџœDгѓHБ€Žх€љ+в зw№СŠп“з$”‹аŽMЙtOЙз’‰4б…Я”D@Ч\Ц^Ш”ХEЙ Р(šЏєёs”K?”+ВфŸїћпfvjjкК]6›h4Šh4Šссk%Ззжж.ЇšбмвŒцІ&ДЖЖЌы=мn7zzмшщйUrћЏ§њ‡`БX088ˆ;яМ'Nœ(‘I^fHЮтЙчžУ‹/Оˆx *ŽЃуЭ0O№зтЮLL]№tDЙњˆrs D‡[iVџсњ”JЁMƒƒJsxЇм-ЃщЫБEВaNх”)ХКЃу%ћсpФК4џf[0Им"xAB§ЗЖД ЉЙ ­+ЕЂnО,%qсТE<ќ№C+ЧжЇг…_њЅ_ТБcЧєZ`yржЙsч№Ня}ЏМђ RЉ”ЂїЗР|>/j§~˜-Д—YV9bЊцЇл<ЌV+ЂбшЊˆŸъdŽоhа–QЗNЅH_Ќ73Z+хІŒ*РЌЕЕ‰D™L555ZБXtsg%;РВ<ЎЈЗЮ ?Dе:Ѓ–,БИƒ;<™(‹ЌV€/б1ђ*zrœфЌљw#%@z}*фт“ю80рЗQDУ‚ЭfC>ŸзŸЯ[Yј њЎЙ\nUЫ$}6~ŒФBF-_.5`TЬgфљЙх …Эfгы)x„LF™&#њ^Мјe`@цД+mх*m0Fя!Ъ"пj&Ћ/0›ЭhmmAGGЛЮ$’IŒ\С‹/Цтb 8ѕжSpЙмp:]а4 wћы ibБЮœ9ƒў№‡8wюœцй"ЋЉё ОО&г ;Ч‚.1ŸЯExшzЂNЮцЩЄ{ХОџrcЕзщW eЯU ŒeГYDЃQ8x<ƒA/mвВIgЂ“+ўљтр‘ЕЌр;{‘ў–бсЫдтФаAr€AŽšn#LїSN• і!}8,ЫЊБИЂ“еEЇЫЏ)ЈF,ЩˆЦ—е2ˆsdtПŒрч™Šџh]\+џ.t}†Jtžш|љ90Ъг‹Я“‰У”г йЎj˜€[ШЌP(ЌЊ/ іЦ;ю8‰ЃGтшбЃ%Кћљ|_џњзёвK/смЙsJ˜g‹ЬхrЁБЁЋљќrЄOь#Ян‹Ъ{\њœўЏЉЉХbгщ,є1и3ЂїХz'ЃNœjrњхtOnлE€SSSАZ­ЈЏЏGcc#€6gQѓ_цшјЦ/*ЂQДK…FЂBŸЌ^4qЄkЙщlЂ“фє“8B˜;/ZРbžИЁS зmђтЅ.9u/#Y#K:nb”)›(ћпШ@cbн?6ќ3‹кD…H™ќ0‘œ1*ь,ЗŒœ—lГ1jƒ,ЪЉ!оЮ€OПп;яМЧŽУРР@Щ&ŸЫe‘LФ‘L&J%ё‰O|B9ќ-qњN4Ўvцry ХNTкуэ|шаoКЯсpРjЕъ Љ2gЯїP‘т)}ЃNYWЮFњл мtH$‡Wf25ЋеЊp№6 #њГмmЖЂУ‘г1Z(хŠ?x”/•Шя8У Zа|xиК’Эf‘ЩdJž#ЃДD C Šeъ|ВуСEˆш;p‰aЃ™ UНŠ Gь"[ Ж\в@пEЌ S-\1Qwю^~љeМ№Т К0rќ[р ,цeЇяѕX Ьf˜…j{•ѓ=OХQŸk‘№НQd<љљхСŽШHŠLžlO4šЏaД†6j]uё(Аb™LІЄ@dhhШяrЙ4юИyd\ю`ѕdWћ*ЃXEЙE"(Ф7pю$y„ЯЉ\Zає˜L&§ёqЗ„ВљEР+фХH˜"ŽžeуˆХя&:XўБ P,d” /—"GЫЂgфЩ$œљЙуl‡јњF}ј2kDУЕЪRЂ№’Ќ№Гтq”1'ВсPлX,8pwоy'Ž9ЧУŠјr8wю^|ёEœ9sБXLUюo!+лккВТДUN\ œxDЯЧ…Зˆрz$<њЛ—Шˆр)QгEЖoWZ3›]ХПнSp7‹E,.."•JЁОО^р“ЕЮ‰'[Б9ё„‹Й§JQ]ЙA@х EgA‹–а1БЄРЛdbF+мiа{pн{^$У Яё‹QЇŒnчNLdTФt‹˜—Uг—‹јeˆ]–’0jэ7 й:)‘WМ#ЫСЫ!RbхВ‘h}OkтЊ•х”yŠf;™нnЧў§ћqЯ=їраЁC:ЕK,е… №ьГЯтьйГHЇгЪсoЁЕЖЖ ж_ 3sаЂЎŠбtKNщs Жчёы˜ы№Th.—[5~š4Ђ.П(ш&cћDЙїЭˆіo%ЧПm€гщD @2™$‡д ЫхsJ‰;(*€“E_В П\UџzNАH3Щшm1bцЮPTь3s+ж(№ ƒЇDК™;bY%М ˆэ{еєЃs‡,~gYП‘ЫRnж‚ŠЏц<Ы6 й˜фJŸQ^оˆЊ;Œ1}"[Ѓк ‘AИ™цvЛuн§ССС’ЖЬX,†ГgЯт…^РЙsчJКR”уп|kjjD}]=ЌLyOьЂсJ{В>{юшљ}\…SqчЯ%МХyЂЈxглЁhоhhHлГgЯЖC7ј§~,.."›ЭиЫ'З‰NLtpЂ€ŽЬ9‹шАх/лмХM^ѓзsоД8y!GЅВЩQ"-/Ы{‰: "ЪцВО(ЩкбDFƒЗнЩrjbў]F‹UљkЅнФЯШЃ`ў9Ые…”ы­7в–)ЪLdPdэ‚"Xс›Јl­‰РIŒ€*щ*аkd2™›Цx<9r‡ТСƒK$X#‘Юœ9ƒ—_~чЯŸWЮ~Ћ~c#`Зйж-Хз%Ѕ)ѕШ™Iйh]YюŸT89;IыQ|MЮZЩœЛŠQЎ˜&o—НІLЏRЋŽбм~ЌdD9цУЈhАœ.€LLЦˆя%nЬтY‚ЙЙ9МђЪ+[ЎRцѓљpфШ ЂЗЗЗœƒAœ9sчЮУеЋW7•~U& Д|Јѕћбп?ЛУЁЗLђ BЫЂо}ЪЛЕёqчЯS" Џ^œЫЯ_ƒQz]Vыc4Ђ}+#~ёšKЇгš˜вP€YssГŽ6SЉдЎљљyŒŒŒ`ff{їюEkkЋTі—ЕЌq™Wѕ+nАхЦїVБЪ(\Ѓ\Ви3Я/1Т/7‡ž;Y”*+удП Фixеˆв”Ћ­ѕZЂќjЫ7gQdЉЃш^іоМz˜"2оq!;ц2ё(й:’mPе‚ ЄЅˆNŸœœ444l:ааа€ƒbppэээ% еммЮž=‹ГgЯb||\Qћ[l>ŸЕЕЕ+ьj ‘Ѕ(œ.—!eЯ%yЙjЈЈЁТљˆ%А  ё@…Г@2жTьˆ’ Юг b1ЕLЬЇšйё‹СЩии^}ѕULOOзмџ§ ШЬсpРэv#›ЭТfГiuuuДС'“I\Иp“““К“—`оCO9n#ч.nцFCŒ&ЛQАВШŸп&Ъг/зП*Rљ2‡"т#Ч‰ ˆ,PŽК—Qя2zНм”Пj€wіВMCЫ }Ф(Z–ŸчяЧС€бDНЕDзFЕт9(ЗQ .%“I\ЙrзЎ]+љЌ”FлhkiiСž={pша!дззыЮЂX,bbbЏОњ*Юž=‹љљyхьoЃкййЁЗэ]П~НФљвP1‡УQBсѓhh{NѕѓРіx!ŸЌл†<>Ж\цЈХ@N–ч— 7ъ Zk ГРїЁ`0ˆЁЁ!\НzЩdRŸытt:5Њ@Ж`­V+"‘х,}тИоp8\"l#:w>N—Gд2z[VL&sфВ|z%Эh•™Д-_Шм)аїЫщаWNУž?NLеЇ‘GБ ЯЈЈPІ~WЎOЦЌШЮ­ьќ‰Д;}_Бƒ1йw_ЃкMЅ’˜Œ-0š€ЩY8ЦеЋW1>>Оj"#€US&oФ:::аггƒ}ћіСяї—lфИzѕ*.\И€p8ЌЂќ-ЖL&‹ўН{рѕљ`2•N?Чпв4=ЎЉЯ‡e‰j{FЃдyD.ŠYѕ‹/ДОIžм(X2š+лešx§mФ:MЅRИzѕ*Ў\Й‚……щ5ŸH$ 3›Э†BЁ€H$‚t:L&у6 Ы7њчŸ=єPI ŠЪUжЫ6fЃMкHшЧhё№4…Xщn4ТUЬЩ‹Љ‘ЦМЌK›s%цAІ_ЩљsЇ^."{Мƒ +@,їОЂ#6zБv‚оƒdХћel,е!N”);1Š7b3dЉ„bБˆ@ €+WЎ`vvЖl„ŸЩdжݘL&ДЗЗЃЇЇЛwя†лэ.щ"С№№0†††‹Х”гпbЫхrCYŠЂЎОЁ$ї.ŽеЅsчёx`БXєѓЩ#~’чB=МшOМVEE>оЯЯSgb€XЃ%г‘еЮШв^Ві>#Ў\Ÿ…BcccИrх ЦЧЧЫ2‚&“I[ZZRРhcK&“XZZB(вњћћѓ.—KпTŒўщŸў O?§4:;;Б{їntttЌR€2*˜тЈT9ŠЮYVф&s\Ђ3ч”НЬiШ(~Y_ЙЬyˆшК*6bŒоЯHžWіЗLдGІЕ-Љ‘‚Qк \mф<щя\.ЗЊSD&“Ы7*ЃЙFšт9з™Ь‘9ўT*…ёёqŒ!Vе088ˆЫ—/ЏЩщSЄпееЅгФ4obttУУУе•%•гп:Глэшьь@CC=žсL €‡ъЇг ЋеЊЇxЮŸьё§‘XОЫLљћѓˆ]|МQФС‡р&Уй;YюfЮЯЯcxxзЏ_G*•ЊxжддрФ‰љ`0Ј€бGЙЉbБˆіііќ/§в/сйgŸХsЯ=ЇGj2—L&uъХыѕb``ƒƒƒ№zНЋTэdщqŠУodt9Ї*Ћќ7Z„F ты‰Œ†H‹ ВЯVNsо`TЪU‘kZd…˜2 тrэšFЬ E1D#R+\6›•ž;rоFšFвОх’JЯ)70HЄљ|333˜œœЌэsыыыУ[ођджжтЩ'Ÿд'FЪЬjЕЂ­­ ===шьь,qЉT гггИ~§:&''ѕуЈœўnа :;;амд ЛУQ™Ух§њФ™ЭfxН^X,8ЮaнЯ•Fi]ˆћŸЂ)Šў№рGџtЭ‰лpTы;Œ”rldЕЉ;Nпcxx‘HЄЂ6ˆеjХО}ћpќјqєѕѕЁX,цџђ/џr[^4лx<ДЕЕ­’Ћ­­Хk_ћZ?~пњжЗpщвЅU'VtšБX gЮœС+ЏМ‚ююnьоН}}}КМЈиN%Fм•ФdduВЧ–ЃƒEЫ[aјŒўфШЩЉ,u vDШ.”jЈj1—fdF3dƒvјљуHОR?ПјD b*nт‘y&“A:–ЖHвч™YБЉЌА’?П2Њyрlm’С`ГГØžž.ыМEЋЋЋУ›оє&8p@ЯЭЫв‡эээшююF[[[ЩљIЅR˜œœФјј8ІІІЄ­šЪ6зЬf3:;;адд‡УY•ѓhZŒИ‰‚чэ—\t‰Ѓ6>‘т—)jЪдIХЕ, ЕubБa2ЕN ЛdѕFхXдJ Ÿ‰‰ czzКЂг€žž=zћїя‡УсX"˜гщ„гщдЋЏ/\И`YXXРО}ћ000€їОїН˜˜˜Р7ПљM\ЙrХбё899‰щщi<ћьГhiiAoo/њћћQ___БPKVРWŽšхmcВЙгМOV”Цб._Р$џšЭf‘ЫхtYдT*UВРI9зA рЈн(UQЭИлr…|хшn‘9лК5ФЂ;Y§€qSB}Ы4‰ŽwрbЄ!gт›q%Y`ўyФMГ3В‚G:‡ЁP@ zЪЂкˆпчѓсўћяЧ]wн‹Х‚P(„ЁЁ!DЃQj­…ЫхBWW:::аккК*711ЉЉ)LOOЏiѓTЖqжее‰цІfИнnhТД;QyOVН/€bБX2=Яl6УэvУbБРсpЌ*4кЧŒFi‹Т`тшpq ‰`W–f•ГrЫхrЋZЅe5V•XЃЕM-шЃЃЃШfГ_ЏЖЖ‡ЦБcЧєV|oJ$ˆХbЃNЂjkkѕзэvCг4gБXФ•+W 188ˆ]Лvсч~юч033ƒя~їЛ8sцŒ^db„,Щццц qњєiј§~ьнЛннншшшX5%Ў’#,G›s$,"cYQ›8ФGЪ“ЩdЩdpсќY\О| ѓsЫТЃ#зK€Ус@Kkкк:Pпа€оо>ьэпЏз[2_›ыШФ{ŒО›Q…ПЌ ^d/dТLдV'ЫЉMхп“Ы…rФ/›™ ўˆ&хЗ+Э—‰;•гр<—1хщЋ……,,,ш#mЋ‰2ИЕЖЖтРбЃGѕш§еW_Хмм\ЩpЉ––<єаCЋ4ЦЦЦ099 žŸTNk­ЃЃ­­­pЛ=?ržBd/Fќ2gЯ[эјО&VщSфЯŸ+*SŠПХЪ}Yє.ше-ЙbЈXpЫ#s–т •жАQэV<Чшш(FGG‹ХЄЉJn6› ћїяЧ‘#GАkзЎUŸ1•J!‹щђі TCЁ€`sssњbpЙ\šЩdrа‚XZZТщгЇ199‰ўў~tttр}я{yф|ы[пТГЯ>[2  ’L4ХйГgqсТX­VtvvЂЃЃmmmhkk“.6Б&@Ь]‰TŒt9…F–Gеф”hсgГYФуqќУ—>3/Н€X,ZіјЅR)ŒŽ\ЧшШѕ’лqєи ;q‡б/.Н)•&в+zyЎOц0Йулыd‚Obšƒ;8К@S>Ÿз‹Ÿ(ЂtŠX™,’н&2В4‰ б}™LБX ‹‹‹zЫыZ>йюнЛёрƒbяоНњЧьььЊЭгfГannЉT ЉT ccc˜ššвA‡rњ[o---шшh‡зы…І™VхєE‡ONœпЮ…wDV€Њ№Їb[эv{Щ5Р‹‰e@@ЦЮЩZlО.eZFуШeз’ЌžЋв,dГYLOOc||ѓѓѓU]‹ЛwяЦ‘#GаппбЁgГYФb1DЃбUЕ2šІСnЗЋ™9sЕЕЕЈЋЋCCC4MsˆbЄюѕzбггƒІІ&МэmoУO§дOсмЙsxс…pѕъеВ9'ёЖBЁ€ЉЉ)ЬЮЮТjЕТсp ЕЕmmmhmmEssГ4gmЄЬ–Эfue*БИЬfГщ+П јЌl6‹t:Щ‰qќЯ?ў1=5yCЧ5 р_џ*ОёѕЏТ_[‹‡^џ<јрУ№дд”l2š^ЄтФ9 \0‡ЂgўZdјq"чЫ#ўр€A6MаfГщKЇг( АлэzŽ-N#‘H X,Тхrщщ%bвщєЊЭNќўр1?ВЙ№ ЖЖХbсp“““…B%›˜ь@"чЏlkг›НН=Јѕзъ9}БвžSё2ЧЯ єшz%šŸЎ[юєХ‚Uвёчњ8XгaЂ‰l€8’[v­–С-KШtI*jfЕ% LNNbbbBЏЁЊt]?~\—З–БЎбhtM…}лtпtАџ~ЄR)ЬЬЬPЮФ,NВушœЭ•+W066†ЖЖ6ttt ББo~ѓ›qъд)МњъЋ8sц .\И€X,f˜хqљКАА€p8ЌЫiZ­VдееЁООuuu№ћ§№ћ§ЋTїxћ Н–(ŒСЋќ3™ ‚јиŸў‘юќ{{wc№ШatvvТыѕЁЃГSџЬ С тё8‚AƒALNLрк№P ­+Гd2‰/}ёГјСїП‹ŸџїП‚ЮЮЎ%@™~Зx‘QЪ…KІгiФуqЫЪŽ6›­ФA‹UїМ@†ќy7q2žнn/щёЇо›:RЉ”ОсЙ\.=%@ŸЇш|ёїYt:T*Ѕ;њx<Ў;特љwыыыУѕызЅNћ•W^бu8!Tђ€В­3ŸЯ‹нНН№љќ0 mq<чЉAйt=r№мбsР.R§bJ‹;kY1Ё,ЭUЉ%NІб/ыx’9fОNЙŒяZъАdљ~ё6њNЇ177‡ййY„Ус5_—?ё?QђxNё‹ѕg2a"бђљfz џяя|?ћѓП„C‡– е/HЮ^№HŸ"O:?тш`^ GчS тЌЏЗI ‹•ОєXњNЇ“4ЗѕуšЫхJЅt'(n|bq#џмщtKKKˆХbH$%L•‘6УzЭхraяоНФюнЛaГй№ћПџћR ЖŠКъЂхvЅo'ѓx<иНЛMMMАйь%­ЉbЯЃ~юаХ?Еъёa<"S ц№ХН-ŸЯЏJ7№‚T™МoЅa_хЂ~~m‹i#Б4QРˆ‰™H‘) з_\\Фєє4цччKdƒЌББ{їюХ3Я<#НŸіёZЌT|.о/Ж*`Х†††єцrЙ‰DLœfтгІИhП(КЅ|h]]ъъъаииˆžžєѕѕсдЉSX\\Ф™3g0<<Œ‘‘‘Uљ\ЃB0QKіо|аEnГйрѓљє‚ЇгЉƒо{>??‡g№=МѓняЦЏ}pнЧВЎЎЏ}ны№кзНгSSјц7ОŽž{Nš[ЫfГxќЏў/ўнЯ§">ЊoœНрЋ(ЙL;Єg@8бъЂƒЖйl(‹z.œчф=ўє™`q “Щ —Ы•DѓщtZзS њвв’Nч%“I8PсJк kБњњzьлЗ{іьСюнЛKђŠС`P/$2к€ЫEhќG1›cnЗ ===ЈЏЏ‡Усдз?пSxЅ>пGЈU•ъ‚D^ф'ц№yПН8RWŒЮeЪ~Ђу—э}ВkтZ4šsТЁШPёєЈбь™ж†Dйюx<ЎGћT\[ЎžРхraџў§@KK RЉ”! mИЉІ3Œюѓљ| PЂeW ЛL…BAšП ЏŒц?G"D"ŒУчѓЁООЈЏЏЧУ?Œ‡~йl###˜˜˜РииXЩИRY•)П€ш1мбЩZж(7L$}Gќ_њ_ёящ—АџРС ;ЎmээxџOџ z§УјмŸ‘2йlŸќФŸучў§Џ`пОњє8йPr‚фPШљчrЙ’БЁЉTJяехѕvЛНФq‹9Fž Ћ†ХˆƒŠ 9 ЯСѕъѓљМО1LOO#‰ •Jщ yСb%5D#Ф_ 8ыээХоН{бггƒšš§8ЄR)ЬЭЭannЁPhUкфFr‰Šи8s8шээAsSlv‡~|Й“цA‚,ЗO •Rh"3 >Ÿ;oxˆ‘3яюЧ”ѓkHЌхѓЫIыЪжЂl†F9!ж­е_˜L&d2§š‰Чу)~ГйŒžž8p===ыях”V4UxН—€йlЦЕkзЈ%Pgј$<О№y‰*,e”Щdв+4чццрrЙPWWЏз Зл={і`яоНzJZы“““˜››+Щэѓ*V|‹m-ВХ@QЄЫгщ4њњzЅЮvv#зG099ƒT*……eчааи‹йŒo Z[[ажк‚ц–&C №ЋПўјзљgќЫWО"їЗу?§—џJ]ЋjxЫ}_š*Ц/`žWЇДЭfƒнnзЯЅгщдzФ^y~|јБх]>ŸG4E&“A2™дѕИ‰ &†6ХПџћП/a0ј†)5хХтF~AWQЊЏЏGwwЗсћ|О’((‹affѓѓѓњи\NѕVk•&6nзўу[Хl6::к188ˆ––VŒŒŒ”TдгоCы‹Ђwњ…BAя2SМ€ЮЯљ‹ЌOБq†MœтЧkgDG,вьќšX И”)№UаF“SХXFV(tСЌP(TU ЎЙЙYіЉ –я%KKK%QўzMЖ'№ uaa ѕ>DлЕk2™ BЁFFFъ8ЬОL№…ŸH#н}ОЈSЉfgg i<jjjtZОЇЇ===њ&8p~П[‹Х‡uб1нЦ?s%yђJЧŒўƒшплЋ€hvЛЉT >Ÿ‹Ѕ‘їХѓ…ЯекјА qђM\ЌЌ)ўh4Šd2Y<М^/l6кккамм\Bу\+хЃбЈT KTк#Х чђљ<ыKОУммОћэo#›Щ"АF*•YЅВ%ЋUШd2ХшшZZšqђЮhoo-yэЃЧ#—Ясo|еyxљЬ‹hямŸЯЏG6b_2m8дуNטr™ЉTJыL}Ъ”KOЅRz[1<OЧƒїѓP 4WЄsЪY!œFх›Š,тч ВЙœ( zKh[[КККаее…КК:§ћаћ-..bnnNзš №ШС пdxбXЕб}gNѕŠkd-lТN6“Щ„ооtttРсpтєщгˆЧ%эЁ$ЄCЧ•;ojЙsЙ\zšŒДїэv{‰wаДјyу“чјХ5LŸŠ‘щZ# јЋдmфмŒTўDgg4ОWдрEПМ…зH №ќљѓeОХbб%пIO”фЅnБy-^vLŒŠџИPГ*ф)}>L&S#пœy„G›ЄЈоfФOІУ.цЂbБ˜оюСgЅgЕZбккŠііv§Нџѕ_џUК2ЭPw\эS}™Lf…4УуqыŸ1Jс™я~йLБxёxвPЫ@†ъ ЈЬЬЬт+џєNž<Žу'Ž–‡;Nо‰щЩ)<§ЕЏЎ:fCW^ХЁ#Ч+цЙУ–Ѕ`ши™ЭfНя–#{žг*є?Œt:Н <№і)~ž TrG-Cь‡ѕѕѕшььDss3Q[[‹ЎЎЎ’ЂBњ‰Хb˜žžЦЬЬ ‚С цццJкOhAЃ‘ЩхfЌ%њW @eыэ]}ьїз–ˆr‰эs.— fГ.—Ћ„еЃufЗлсp8рvЛѕ6SjWЅ'ОŽEE?Q€KТ#ŠuбmД?q0, ‘Щ˜%qџ“Щщ–f4йTІb4ВWVл‰DАИИXѕљkooЧоН{БgЯxбыЃ u0‘Й,7ЈЈœs7zœQЪ…ЯпP€Y*•вY &‰`? b[‹Ф SюЈxAG™ВiZ4ƒ"WrrT™K=Я-ЫЃXљЌэx<Žd2ЉЂЕѓљ<|~OЩБИtё’ЎАŽЎК€eШЕ\чТ /œЦBhЏ§kKя#ozЮœ9Рќ|ЩћЯLObпCЋŽН˜;чдЙ8еŽ‹•аqЃЈŸв)&t$Іwxk wдд=@+m||ъх[Х\+EHt>щБ њOcc#Z[[uС'Nеђк„ЅЅ%,..baaAЇє—––JD…Фˆœж˜QŸЕьxЫœПl7NЂkF€ежне…Ўю.дззУbБЎбВ$œХРD…=Нт^"щ‰ћlxфЯйъ^с‘>1Ј8€хBEЦЉэJSљd2+Qў2zПu5ш9KKKƒˆD"UЕюЙнn=ЏяѕzWБaTNzt|ХїЎ”Ъ• КUпF ышбЃХl&Ё€lQqFЁPЈ#2ЕYnоМб с‚/туХўs~9šЄTпдХ rё‚ 2R§[XX@,і#Є›Ых04t•QFIщЛЕВУCзрqЛqЯНw–Dѕя}џПСGџч—жD‘Щdt5<žk'№УЃk2$Ж#ЊђЭ‘˜о ЖXђcЭE~xфЯ•ќxЛ%Пащ˜8NджжъEŸNЇnЗѕѕѕz„&Ъ7S}Q†ЁPЁPГГГЋфHEMœŠвТFбƒXХ]Щњ­eрBаож†žо466ТlЖHu№щјѓЎrр555%ctyОЭfг)wюаЙучEЭќ§ФЂ>1хЦз51k|Яр*›ќZ‹lEЃћdSћ*хГђў•XОоГй, …Є#ЋХЯaЕZблл‹}n ЛKKK…B:Х/7F] е “љŽJУшј§vЛ HŒЊcWЂВ:^д'.N™“ЧЎŠ(P4п`љD8Б(%N—ŒЫЄŠuКpЙGЖ"ђO$% Žз2d2hЖvцчц‘Э,#і‚0 AvжТМђЪ9ДЕЗ`зЎ эйЛ˜œ˜(YИЉT‡Ѓф8qХ.~<шšќФP„.о‰B$"“е№u@ нnGKK …‚юШэv;jk—5жН^/œN'ъыыK.BœЩdєДеpP~p~~‹‹‹H$њћs'OЕ ЂўПЌ№бHœE<‡ЂТЁ(ыjфјerЋFРbЇZ<žР| ˆљљюКћюU;b{ЏsЇшQWœЄЈ’г№b$,"‹)ъЦгѕСЛ4MгїIJ8Э" ›ЭІ—Rњвh qinšEgoє[гѕjvIЦ: !‹UtК”RэыыCOO ˆйШd2˜™™A&“)бˆ‹y9 AЌEOьPе^e,œи‚ЩеааZ[mzz‹ГГГOЅЉNхтФyж|щ6О№Ei^rHb~JtbFT.GяT”F "™L.‹ЮЄJбрТB­>ЌB­\9k=lРŸ}нн]%Ÿћ5їн‡Я?ёФЊ~D Q.ьcTь#Fф$m6ъыыuJОЫСƒa6›QWW‡t:L&ƒКК:НЈЊЛЛ[gŠЈQмРDgLЧšKгј(ђ œ€mІb_;мёЫŽƒЌ@JЖŽХ ‚ПOЙ Дš|фNfъъъpрР~Мјв+H&“%E|`‰н-bjKœДчѕzKj[ˆ9ЂcЬ__L›q6OЏ4šDЩйњМфЬim‹щ2Y]‚ЌКЏ Yс^Йж:Бкh@˜ћFЃ:›fЄoСОЯчг[ДЉ›†˜Йl6‹P(„ХХEНf‹Kт€!Бš_цœ+ЕŠЏ]iBЊьzQ@f/^„ІiTU^++Є•ŸxŽ•є‰ДGЄЂoуЙkк(OL3ЏxчhPцlE-'›ЯeK€ХатЊ…':§a‚СŒŽŽЁЇg—ў(ћіэG{{;|>_I‹$WњЃc#јq ›рŸјЂбЈО!оџ§pЙ\К#цŸнсpш5ЩdсpX/ŒFЃzЮ“ЊmуёИ>(‡OЁш!›ЭТщtъLн&n~2Эt‘jщ\Оіdšш2Е>™ЮEЙЈо(_)Л'љ|>ьл7€–цf8]nНЖˆGфмљѓk"r^p'2TР;^јА)ю ш5D,КFI”˜3ЂьЙТЅи*Hk‹Š‹iм5зHЇгњчцѕ6FF{šH“MН4ы-ŠбўDiЮP(Tіsаkкl6єііЂЏЏMMMњ5D ќљчŸЧ?§г?сх—_ж mЃб(š››Q[[‹xo|уK‚%ёмШjј:0ыЂV["ў5Ы1;ŒŽŽъ€кr EЄЅE*›3Э‘-зйц&=Žш#Ђ‰ Yђh@<щd…ˆ2ХТљEюџ ‡Kю-—X/pѕъЕPWWЛн^"cœЩЄ‘L&сt:WQ№„еjеAЩѕr ЦѓŸ”ЖЁЭƒЈбаFРЃ~Yњ„ž/FВ‚"^3Сœ8ЎTdЋDКп(Ÿj4Aб№TЭэf^ožv­8}Y„/Sт“Щ‰s@Ю›;ЊюwЛнzPР[ћИРА\|iЗлѕѕN•GЬ2‘)N§ѓО~ZЯДо)ˆ!@, Ъ9^Ѓ’Ќ@ РD0KЗQ^ЙО)VБі КККазз‡ЎЎЎ’я™ЯчёЭo~ŸљЬg№§яС`Pњ:Єxљђe|ўѓŸЧG>ђ}ŒŒЉ5iЋфwdE•jјs‹ фЂl6jjjFти\1‚сЮOь‹х…92GбibK˜(ЕIб!_$$A+*o ё ВмF-і‰r"sњыaІЇf*RФГГsШх–["#‘–––є дХЯчuV€DPHTƒ&ю‚ЇЊкИш|RU3?ŽfГС`сpxUчЈГN‚Їx›Ÿ˜П'p"›.Ў'qЬ0mnМеа(ђ.W•Я‹§dˆLžе(uPŽрЏy;1.— §§hяhGMw{"нu@шКчZ 2q(Nчгk“Гїx<%Œ9ZюyџПУс(qjЫѕ?ZЩм YM‡иUBsЙ\њgтNŽЫx‹*€2Y6q1*t#j“Щ„ХХEƒA,--U5ЭЏЎЎNWШЄ@ƒ~ўъЏў Ÿћмч0>>ОІѕ‡ё‘|Пї{П‡={і”A^М\mБ­иŠЮ5\Œ$“n?x№ ˜лэц}В^YЅQЊ(Š!ІxoŒ+ ZCCƒ>ЖЕP(ИЫ9Щh)qƒ•ѕa=L›!щШ›Эfдддшƒjвщeњ›6оРлрxе/bXœі+qКЙМtс‰NыFй€Њ†_HhФt:]т$љ˜RžлЄяGљMšІЧ‡ёі>~Lвщ4œNЇžrсu2‡ШЅp№BяЧй Š”-OqаѓiCЧСПшE XЬ?ЪfEp 'Ћњ—U”—›ЛЮ7&ZNЇѓ†Іо ГZ­иЛwz{zPуѕ­rЦ"шЕ№ХџљoјD-~^э-црЙ3Ё>|žїцХwМ#€жuж№Ж=QЮšƒD‹ы„3BtMq^Щ)sСЏ #K Zb‰БЌдKпее…ўў~тчСE4Хфф$ўђ/џŸўєЇKєAŒжХёуЧpтФ1?q §њ}щt##ЃјкWŸЦ?ўу?уЛп§.^ѓšз”ˆ0Q]oцiуЦEшŒЦ(Ы‚МЛ\.ХШЌНН‘HSSSа4ЭeДФўzБW–Wэ—›кGމœšлэ.Щ=%“ЩGЯ‹оxЎ_імйѓ PVyZz1ц…њ9Аl@5&Vѓg2™Um€ќћё(|&]X4 …Ф•јШ#!њЮДŠƒwИЃучГМ№ЇgDБЭPlй/:w™ЬАˆўХ4ƒ,${?ю€dQ‡˜S:ќ6вйЈДЙоєШbСоН{аггƒккКUEz2qйsчo4O,ь“{:І"шрЃ{Хjr^WDзмiqКŸ>БДІљч3-+™LьG–#GЭ{ь+э# шяяG___‰:_ЁP@*•B Рьь,~№ƒрЃ§(ІЇЇЫОоЩ“'№жЗО'яМC—bЭnЗc` §xпћп‹џхуH&—ЯЂа^Эїn##|Бp2лˆCЗ%ЈЏЏGБXФфф$8FUŠ”?_Ј"ѕЪ-QlВёТ|ˆwт|c!v€rw2Ъ•_<<ї-xEт9qKџм7ЪTKyёџХb=rюЂrЂŒyс*i<fTŒ$FЬВЭNFпёЪ{>‹]І›o”?Љ|БэO6ЁPЌЅр›ПИё‹§Т"m-ЫУЪж›Q—,е@ьЫv§{БЋЇgE˜Щ"m=ЃcёИQЮ^§ЫŠEЦ…GўтЙЕ#утY|Ђ ŸЂАИИX\UВЗП§эЈЋЋ+ЙОјlŒ`0ˆd2‰П§лПХО№УзБлэјЉ7=‚wПћQДЕЕЎбЇдс—х?`|l ™LFџЎœХ! F­…х€˜цс{AЅaAt~†††рѓКхo2™ ьv;bБ˜SЖЙЫЈQŽжyяЖ(МA Џсm<љ|ОdЄ,ЏЌхcoЙsч”_L<Ђх „69WƒаЙ3“9ќѕВ@БА*‚ѓй"еN› mr<=Р7AО‘Š›1ббЪ"p ФкЃ\ІBчN^œ) ‹а"mй\vYД/і€‹ЂRF=ЦbJ„пV.MF ЬvJьщыCooъu`Ю7[QЇƒGЦ2ч.Rџ2ЧЯSFВм-Їь9c(Ат€PЄцЩi‹BXє?жe}уќМёыŒnЃ‚CОnXˆЊх:@„pЉєBЁ€……нIWb e‘0wўБXLŸОJЧ$уќџгЇOОц;оёVќєЯМ~ПнkЬы­A[{3fІ%УЭ8ЄдЃŒч№ЮБƒCж.,ІZЎ\Й‚“wU@F§йэvИнn,,,XŒЄzEЪЪhNНx2Q‹гы(ЯL0ŸЯУщtТыѕъQ?ЮаsˆюЃ—гKВ–OЋМW1ХTУˆщ Ў€(цМisK&“ШfГzЧV"І…SІМЇšoюМКŸо›3*$Dє)ЏьцŸ›;sйd<Б6ƒ6\q* Їљf){™ЌБH;V3ЭHPE8т&lDЯ {3­ЛЛ {ієЁЙЙVЋMšЮћіE.цєeЙ~БЂ_,t“щ№‹Lžи%ТoЃѓЮ[ђxQЊX B‘=§№ŽёќђЯ-ЖŠэЅВBДt:­3=тXa™Ѓ% …‡БДДTUКАЙЙ§§§шььФg?ћYщ:>wюœоDзH(Т‡>є! I_ЗЋЛ џэП§іяп'Н?Jcdd “XX!ТхДЁЎЎ]шя€еfe`Є‹‹KzНЅУ8@Я—x-гIчXwхФР8h7jcмё`ii БXŒ6)›QUv‚xЎŽ5wМ$щKЃjSЉ”юœ8’#nокУЪ№лy›хЋeO+ќiчЋrФе:ќЕАеІD”K[ŒLxю.>‰*“y/’л>ХЈJL‰­Rќ1|мВИбђMQL+ˆSe5ЂЈ‘Q; /4"K цtEЧnMщ№ззM[mэшпЛmээ%CwФB>Y1ŸбoQЇ_Ц&‰4ПLsŸQЄЪHJ<ќ6^аJ @Ќрщ3‘ т›wрˆСŽX (ћОє™ЪЕ€...b~~ UQќnЗ@MMžъ0rœЂРмм>јСbjjJ FоџўїтпўЛГЊkЅX,тЪ•! ]Н†ББё’cZ,ЦЫfZXРєд4|шu%пЛОо‰ё=еЫ[ОeХzт5Mћ{b7€ИЧˆ‘шхј ˜ЭЮЮ’Z”РnDеЪZќш SŽ™œ4ŽAЗSIљ9šYяѓ-W/--щp*•в‘№щЂцЙoBљ|УхP& T"РfЕISе:ќЕВхL,|увyЯ=-:іTHIЬ iяSž”o†ф щМˆh\Є":^О1ђhIŒўщ6žŽ0вычеЂЬ*џŒœyu№МОЈыРZgœЉр…•6Ѓ™œeл*khЈGKK > ЛнБЊ0—SњЂѓћѓХм>/ј‡цˆщQѓ_tтFьЂQ1(џДy„-Vеѓ"QЃЪqQpŠ‚Іy}}bx0Bз8O_ЪьљчŸЧЅK—F+FњVЋ}}}иГg:::Vн/j—ˆэtm$ ќжo§–дљ{Н^ќЩŸќ!:ўг/НŒp8Rr ˆИ"б8ъkНЬЯум+gqьФё’T0]"ŒD .ЕkЪRt.вщДоЁФЛŸ8Ш+џe’СБXЬДkз.M‰…B!$“IЪї˜ЫE§FmRМrœЃYŠ6iƒ%€œ7йвЩ%tKC8ИМ-/"PС7ž7т‘n52`-ПP­ём(пTKŠWъ№ЯK)aД‰‰4Їl"wd2-u.ь#*r@&Ѓ? P$ Fv"ƒ#ъЌ‹4Бј}Ф"Ь7БpQќŒ|њ›­hЄ(rnPWW‡ЖЖж•ЁJ!LLLтўћа%jХЖ;>R[(­УЉ~ўПX(Fѕтz-WtЪ[ћxžбѕТї:Ю0ђыElу™'YНB|-ёЂd>жšъ‘xAЄуїУўАт(мŽŽєїїcїюнЋ"ђt:­Ъ K9GћРG?њQ\П~}еcёБ?ћ“uR›РїŸyсpd•г—€D"…њZ/рЪхЫ8p№ь+їВzЃ ЉTF?<еdЗлЫ2ќМђРNЌѓтСэ§зЏ_ЧеЋWБААр~§ы_\6Љ€hЙ\.—KkmmХХ‹Эхцž‹9\~№yGj4Ў–6ђl6 ЛнПпЏыС }ШхГEyNБ`Зв$*~сѓ"9YnЛ|V-ЎbЊuќbБ/d"ЇЮЛ˜6рЮ”в0\“Ÿoќt!ŠѓИг$бЁНˆ’щƒ$љЫг ФбчЃс(<С;8k$ ‰Ъ‚<вуЙZОys№ Ёёs"ЖГŠЉ Бл…~ФѓiфќщЛot ЯчХСабй ЛнЏ|х+%зЅЯчƒХbA(’їq*_,юу€ƒ,БMŽŸ+ЮЕИ‰i1ёv#vЅœм8Џ'ьё@@,ц“хŽeщ%Б†…N—*ѕбыE"ЬЬЬЌЁhЮ‹}ћіaџў§zk4g#ƒС Ђбh —­?ZЃщt_ћкз№o|Cšњ?џчOбмв\ђ]јь 8{і|EЇ/ўцЏ11>ОН{єльv‰TЩЙфbM2Эq:п#h&1.ќњ\XXРѕыз166І'VЋ­­­˜ПЎ€ь@ЏшlkKKKZSSSХh_Єњј…'вѓ‘R=—ъДZ­%уlЉXшjjй!ЧХ7yjЯЁОv1ВѓчДШ*ЁoBb `#й€j€биZ^НЮ#^ЎМЧгмбђjZО‘Ыє№E‘]pщS1:“1‰CUdub€вѓХhŒ?_,ФЃ R<ЎтЌБŽ+Bђˆ™kBШв5Влщ3E"‘5Г?FVSSƒіЃГГ55оВЧ”„Дh“5*ъLGL№c!Nі“хљE‡+“90ЃыTцєФt’шЪMЂумб‹ч›Ыœ !ОW2™Фмм€оЖ\юмлl6єїїЃППmmmЋюЇ)~ѓѓѓ:sFз=EїВшŸіЧP(„ПћЛП[ѕК§гџYтќуёўѕЉЇ1?Ј*ъ—ЅнШ@ АкЌ:§OЕbNЇSLdз}7^'Ц‹?ЩЇPАwэк5 щŠ„тк№zНЊ н0??ЏЅR)tttЌд!ju‹=Д”‡ІAМ*—4Д)ETиhЊ њ§~Н#€вВў\Z(ЂвПРEa›Uyn“V1АQl@e€UЃ–щјRŸ1 "њŒŽ1mАDџ˜‡ђpЧЬ №QУThšVвЏЫ#B>Ÿ],RS‹G?оТ)TyбчІяС{†EњOЌWOU№‚/>Ї@vi}‰ŒŒ(E++ŽсЪ•+7”p9иЗ:;;сѓљWЕч‰ VT‹$Р=яУ&Ї"Jіђы›Гтэ<­b$И#гГ—9dzЌ,"фѕ!"№ єxфЯІi:ƒХƒ^,,ъjачф gvŠХ"fgg155ЅWёW|===@ooяЊњъ ‡УњК'gЯ…ИдАxшZљђ—П,•ѕ§ўл‡бббЮ€K _љЪП"ДZSд/Імxayi-ƒщtК„mЄѕ)2тљры“w;™Эf,,,`bbeЧ(›L&­Йф jjj`2™L&RѕшааZZZаккКЊ(ЧЈт•чуХ6 ‡УЊТфє5mTЫ4ЎƒZ F)NѓNz}~бЪ €*l-–MмPmўŸвё ’34&•3"tмhУШd2ЋњЈiCфНШxБwшœОЇчRzИ$8mЫЉYY18йЋŠub]ЇчХ™юЂў?/итЧ[|ЎXœF›RВ6ЊЋЙ|љ2Ђб(ŠХ"ъыызtM:v  ЛЛ^ЏЏФБёaZFГэM&jjj`6›‘L&KZfХB9ў§Ф4šŒўЛ%ФaYпœХB@hЩuѓШPœ9С ЖМЃE”œkG8у'іšѓм3Е3G"„BЁUГ%dV__oHёчr9ЬЯЯcvvбhДD&—ЫгžЧЛ1ЪEџ_џњзW}ŽwПћQќинЋџŸЭfёдП| С…5G§F @\ш@ чЭї:ЉTЊdЊЌV„|E>ŸG8Цьь,fffH$Ъп@kk+Nœ8‘KЇгЊPfЕЕЕH&“Z"‘иУ7мљљyD"ДЗЗЃЉЉi•м%_ˆДP СršŒХ№с6„Тнn7’ЩЄ>›ОЉЉ GŸb'ія‹šаМр†žC:`#вjXNWnPЩ4muлп˜ye?ЭR0›ЭњХР/иs8pЛнњ†LеЗtLјCвСдОIХNМЅdЅїт: oсЮšыЄ'“IНј‡œ?GјbA˜˜їЇЈˆ;vq0‹ЈРg а†O@Fд>х…ХbWоRЦ)рЫ—/c~~ОЄˆГРbБ П/vэкЇf•ў=wФbёžHЉ0ф38ИУ—uШRA\ƒ‚_g" –E_ВЧ№ш_д{ gЦAЎQЪRtLЂю€Ј“Сы?ˆ ”u5qF‘5?V‘Hв‰tЋœћіэУамм,-РžE0\Uр*Ў-^OCзЇЌeЂџќрЋŠыъыы№s?џoKnћСїŸУЬЬьКЂ~#@tштњу СЩв#єИd2‰™™LNNbaaЁЂгw8ФёуЧбкк #эƒ<-ДVqФn&“СааfggБ{їnДДД”ДеˆвРтИF‘жх#wЎД y'_`”  œ;Š€ХV,YбQЙШBЖбЩпP”ŽB–хњ2™ тёxIŽ—шNNЫ:N‘ƒцгћx †ЗhђHŒ 8Йк9qžыхE;ќМњ'pСг"Р7Ѓ9FХdhђЧŠQ-ѕ*VгgцE—ВОaІгi\Лv “““%яЭS(2'a2™апПmmmАйь%…˜<ђфб9}>Б;CЬПЛнnX,ˆ•ё"­Я 39K&J%‹…sтoй€0Q•QŒАљћUКFљzуџ‹ЮŸуб?g ФˆWІ4˜Ых(=Z•PІiиН{7:„]Лv­ъBI&“XXXРмм’ЩфЊvYКЖИ”9п'yъЏq1=*SњћЗџюЇKДќ''ЇpўќХuG§F qѓ"c^Ј(“6™L˜››УииІІІє‚ОrЖkз.œЉ‹љ№\$mR”Іh1™LBг4x<Єгi,,,РbБ ІІFф„(‡L)*vЂзрsРљ‚‘ЮX- -6’щљпPЩx‡MGЄуKט6яљ'Ї‡ѕуDLJ"‘@,C8ж#ѓX,†d2Y2ЩŒ*§IК™Žщ<аёЅкetxmˆ˜Gч䭘žсQ0M$$ж‰Ѓ†щq<џЮЕФљ<яKk3\ЬŠœЂlN<Нg4ХШШfff …d)ЇООнhkk[љ,L&ГtаsЊO р+Ц‘ѕК0фRПќМ№КО>щvЮ€‰55мŠД>?ЏВБЖЂ<Г(A]ЎС‰ЮŸы`P’Ўъ@ЁНNl1хLЗ.,,`jj ‹‹‹UЗДДррСƒиЗoпЊЩsйlVOаѕЬыxэ _ЗŸ‡Эfг#rž"…Ь/tQQЭЈІƒŸ‹єОДІD†AЬсЪ*УEХBQ$†X‘r‘,.ќВИИˆЁЁ! ZFwЗЖЖтиБcКŠІІFhНw&`Б˜KњђЩсгoњсЬЇTЉCBtђNЇГdЎБтŸSјќ3ˆ5тd<1rk'Dmйё5ŠЄЫ]'2™`Ѓ‘еœ§ЁЕ#8ђяBкљгггz^ЮёЛнnŸ˜+ šзы…Ус@0tџјџ8zzz№еЏ~UWЊ’CЭхrИrх ЦЦЦажж†оо^j%,ЁЂИу'J’ž‹ХЭfсёxє*sЊр•ьД™ђSИ<џL9k>4‘HшїѓЭМP€ŒюМ6 Айl№xЅЅ%}Пт{\ww7ѓг ШК\.—іђЫ/Їѓљ<њћћбее…чŸЯ?џќЊќŒHЮЭЭ! ЁЖЖ]]]hkkг7ожgГйє(“ ијч]TmKХ$bЅ,‹Nїq,оЗM.GкЫ‹Б (€eЊIЩ№Э†Я8чэkМˆWЂcCUћщtZяЛЅz Ће ЏзЋ?JБpE3крщМЩt dє0$EN•љsЦ‚;оŽE› jФ„иЦHЮ€ŸŠ”y˜О'/у“щљ§з­qh wЎ&“ ]]]xэk_‹њњz$ \О|%+žюЬyџ=H!O…М ”ў'"ђЅiХ6?оY#кŠыRЦІpV€YŠš œkˆФ:ŽrCtd 6љ5B ‹Ÿ[ZЧЙ\гг㘘˜Рмм\U­{8|ј0іэлW’G'6, ! щ-p<е ж?ˆДНQ—/хO<%iМ=чгЉпызGзщ—sўkšІann“““zБlЙ}бbБ```@/ЄќшG?*- Нzѕj  СŸпяW]Fxзœ9sЁPЧŽУ§исрСƒјіЗПkзЎщ‘Mћ†Љjxx555№ћ§КЁХJ›pmm-\.—~1QU:Е’SтоДљpё ўyФEьM/7wZцˆХaХTzпT*…D"Qт$ш8PT‹Хt оэvЃЖЖVЏзH&“:[@рˆєЗЉѓЂЎЎ6› ‘HDŸН@б,WФГйlpЙ\Кl33ю˜ЙŽ:яГцЮ”+§ёyщtК„†чбu<ањрm‹мЉѓЈJь7ЇуFы„6,$т MгАИИˆD"QR? Ў!оoOї{Н^мџ§шээEЁPРЬЬ ЦЧЧ‘ЫхЬє9DM YЮŸжВ8яžиюќEAqŠ"wDb4.ЫбѓˆœГ)мA‹рAь™чљuрEgР?ѕзгњЈxЭЁuЧA9шL&ƒ`0ˆљљyЬЯЯ—тьшБcЧ088ИЊ•ГP(`zz“““H$№zНњДAЊС :‘\.Wв†ЩЛФю$ž–™1БhSŒєE–сGi^gI'J:Цтbј†ЃўjSаЦЧЧqўќљU­л2kkkУ‘#GаппЏя-2fˆРЕOђZ.№T‰Uкб]‘HФ”ЯчНšІa~~Я<ѓ :;;бггƒG}ѓѓѓxюЙч0<<\вžТѓЈД@- –––0??\.‡ккZДЗЗcїюн:EoЗлѕ:‰|ь,НЇIљкЈЈhMЌєІ ‹oЌМшЋP(@3UЎ0Ъ1оP-№р™GФ\~—œGюЄИр‹QСЯ7sЦ†„ё1Ф<ЭР…sˆ.ч­„МЊ^ќ>и8cCб:ёxŠC’85-Ж|qpЪч!№”w€фBЁ~L9Р;'8ЁЕU[[‹“'OтРх(kaaЃЃЃzњЉX,ši№(Џц'ЪŸŠXљzІк @tМEСОFEp Žеч t3я‰ч Et№<ŠU8Хz ‘К—uч№”N%@ќ~b%<Їџ—––є *Р+чјm6іэл‡ЃGbїюнЋюFЃ˜™™Сдд”оІlГйJОю‰rЙœ~ўИ яŽс{‘9рпK<М~@6\‡[<7tъkqўkI\НzЕd ЬЈm’ъЫhП'АFii3%c/9Слоў.dy•ЉЉ)‹E/]fГУУӘŸŸЧсУ‡бггƒнЛwczzЯ<ѓ ЮŸ?Џ#kО иэvИ\.иэvx<юG(вY††]HtŒœЂЅќ§ON$ŸЯы]bЯ6x.)ЬЃ Кшlів РjГ"›Щъ9žзСАеЎЁ@]8nˆYсjМШ†"*^O i‰RЉТсА’шТ\ьБЌ'@ЗQФJЅJ>Uы' Єгi§ГК\.нщѓ 1кщ\!”в!'O ‘P<ЯсŠC€ИЮ8нЯŽјzK&“‡У‡УƒњЮ‹фDЇ"Ž—mjjТНїо‹ƒ’˜ЦЦЦФ"23}.bfduШPЧ=†oœМ7D‰Œ$˜ PёыJtдє]шјгёJ&“zы'ЅЇф‰Ъ‚b„Юл№ФИЈ +ъ”^Сќјия‰‰ Œ#TtњРВ:пбЃGq№рС’КZџгггzWБh 0›ЭШd2%‘ОХbбnxс1FbZЪˆБсь“l(—ШЊŠШ‹(I›Ў7ъ/—uЪћ]ЛvсРшщщ)бnЁ‚>ъžz].Яз6нщв%эфЩ“ ˆ‡‘H$4“ЩфцШŒ r.]К„……twwЃЅЅя|ч;ёаCсйgŸХщгЇѕ Yмˆ)КЄ žш§t:ЙЙ9\Иp~П~ПMMMhmm-Ёl(=рvЛKFCвтр§кЩfГЁОО~0уыЗАJДDДХХEU`DЭаl6›“ŠТФŠZ*pЉ­­Eoo/ёШ#рР•+WpётEЬЬЬ” T. BjNДЁ“rQi###ЈЏЏ‡пя‡йlF}}=КЛЛQSSS‚ˆљŒЦЦFeЁбЌВт9Ж™eкїмљsЕ=‘ЁЯC9ЯчŠNV6€"f^ЯщRZSМе‘6Sžђр9ižz 5'ЖZђ”џЌ<Юг2FГ:D@з4EчcccИvэRЉTUб>З|Афџ……ŒыUќєž<ЕDcИi2ŸЌ…“‹6бКу,q<-У;axБiv№ToыХЉЊ)ЪЛбЈ-)њоННН8|ј0іьйS2ТjЕъщ•p8 ‡УЁƒv›Э†šššUХ—є=DUNБ5ЙX,ЂЁЁAеШ, Тяїk&“ЩI‹[г4ЂчеЇKKKИrх œN'š››баа€“'Oто{яE,УЙsчpњєiФbБ’‚™ИЏ>ІJєљљyФуqŒŽŽbxxэээЈЏЏзСЅФШŒ;QО€ѕQ ŠгщD2•­КП(X+PЩ ‚„­xьˆVЄш6А Р‰mUдKб;Ї ynкыѕъs”›—Љ„ХMŽ‚ЗсёsР yЩ/TЎШ‹icфQ8уSSЉbБЂбЈЎњХ­gО)‹”?яBЁJoo/њћћбббЁ;ьT*…ЉЉ)}ђЇƒgёЊv.кTю:ЩчѓH$СФФBЁа*€.Гoу* ХЬЬ š››бввПп{юЙЧЧааЎ\Й‚‰‰ dГY§Ёi\ДPЅ,]д„ Эf3RЉ&'' uI[ЛнŽккZИнn§BуŠƒ9rйOоЫ…e’Љhй+Š!mP‰‚5D+SU|БX„Яч+)(Ђz^ŒIX2™D</Ђ1ЪМянсpРыѕ"‰ш$urА sI ŠгБМVƒЂ1:wtЎРˆњђ\š˜t#јˆhъ яH•пБXL>Й ЕeѓѓAŸђЩМкјкллбййYBчкl6ŒщuДpэrю( ˆГРi^|ш3ђЯЭ‡ўˆcБeУˆD@Ѓы˜ГJ\‚;tžVтВЛМРЈЈ”ЏuYы(g|ˆсЁbFZKœээмЙsјЮwОƒЉЉЉUзЬšššpђфIœ\ъ}u8№љ|№x<шъъвsњ И|љrЩt:r bkЁCr\<š1™L‡УX\\,‰yБмєєД~БQ4я ј‘hŠё1БZ-xјЁћ14t#cUЇЊa*вd Йв…E‰hvк˜‡нг†Aє6п xuЕЈ—Nt?’VЇвчсъs бk№^T“ф‘2Ÿ`$DВИИˆH$‚H$‚x<Žp8ЌггЁёёдт†Ф7‡е:?Šмvэк…ОО>ьнЛWпtRЉєїчX№оr^a/FБ”Z TŠбPОЮЙУ'їmК|-r–ƒЏ{DхЦёr‘оŽШ ž6тїѓ1Р?Ї8№Š&–хŒџЫљ/%уvЎ'—Ы…'NрфЩ“шъъЊzL$zъLd_Ф‘ЯМы…ЗфёaWБXLWфР™MоРY1 ЮˆжnkwєkIXmVщЛ&“IƒA]+Ad”ž….ДХгŒ2Х@оУл}Х:Ўl6ЋЃ"Р• ШЪпФј/nV„`ЩI‘s'gваа€ііv\Лvm•Ь/IгFљYЂ`i‘ѓJYNЁ‰H€ЎM‹Уыѕ‚Ї62™Ь šжVЪaфјюнЛБ{їnd2ЬЯЯcl|ууSXŠFoˆ Јd"эЪ+‘i2m$„ЈyсзвчbФХuК /юЂтAŠРЙиŽ8 †GДтœvю@И"d2™длю(ВŠFЃˆD"Шхr%гi3Є:ZwFЃeљБч3сЙ“khhРЎ]Лє!Wёx\/С`АdJЏeхŒyЯэr…ОџŸН?В,?ЏУРsялзмГі}ЏъZКЋїFѕ@ ЄЩ‘5Є-‰Д5”ЦВ­ [c‡УА-лЃ™"Fжx‚ ‰Ч#QЄ”И И КнUнЕWVUю{О}яЮ™чЧѓОМ/ГК е7"ЃЋ_О|я.ПпЗœя|чГмў^…А”MЏЕa"ьТа’€Л­/Ыg`ЊъŒ:J•џєођў+w„меIаkRm{,e{жyOТЦУ‹ХзИ)ts/М№.^М:€guu333;•аe­œrУќ\і§ГїНбh8о@ЕZukB%™щw№~*RРясћ53АВОšAбxrг aџў§8tш<ˆl6ыюА)†BXq}}н‰ЃЈtЎэЏƒйИи–DгЬ}Ѕ ъ!h‹™:QЂUVЯпBіƒP,[ р>QБm“UфMŸ•=7ЎEесўДJŠЦЉУрs]^^Ц§ћї] >l~€ ф^zщ%МќђЫ8pрР6GУЈУЏвтƒъдЊ1 =х*HC$Тr9h[xјœи>ЫР\Щ|˜18цZтњa)-д  ЌЈе‡=ОYџ“"фšцНе2-ЫфTsСuШ„eP€СrU*•к&ХЁ\!ЧШШтёИAT‰'6Šз,G ˜ељІёPGЂT‘пїQо‚дGFFАoп>Єгiœ?™LЦ) .,,`iiЩmKіP‡cg аp’Mњ'›Вџ>dГYМјђKИxљюпЛ‡Ч…*O=щ‰D>’ѓяѕ‚>AТнМ6mПc/П…ЛЕgОVЋСѓМ>v­жYћМyѓ&ђљ<–——I‹Еxпш,cБжзз‘Щd\KFѕЪКЗŠeЪрgАЄŒx"7šсZQ%­ЇгiьнЛ“““˜œœФž={Sžпзl6БВВв'цЂbG 5 бщˆ …k)Jєx-vтжКѕYYФB5ыI”Tqm‹д€',дЯ$Y0ЉBђЪKр9кй\{4жкЈЏlŠj{ƒАwп}|№жжжv­ыGЃQ<§єг}ЂKz”J%ЬЭЭavv­VЋфžАлy?›ŽŸуА ™ь4щѕzNXЫЄR2Ыqtт<7 UыŸN‹л уЬ|дуЃ–Тў§$чСФ…ы0lдД~'я}$„FfЄ_ йVї–чyоNъ’џFьНр+tЂ"0vо4 Т˜Кˆ-IY­\р…BFхrй! tрУУУС‰'œcc›WЃб@ЕZэ“рдВЌе1ћbDЭХ њ&“Сх+WpљЪ”Ыe,.,`ue“ИвщДQи(ќk}kkkю\iДШ‚Хbu#•i[­JЅ’#MZIe:•d2‰ссadГY—эбqы[пrѕ9№Д“WДЖ’8ШLG‡ГшФ=;ДЧ–Tv8ЌЖ?66†‘‘ьпПGŽСБcЧ066цЎ—ІT*ЁX,bccхrй!?D(XТbD%DY{ ›bЇаЎŠљhЋœ•ЛUdG я:о:yfоќ.%№щ§ 3Œ |д!’ЃRЧŠАhvЊAІ …л’юk\ЄїŒзqџў}мЛw333OдЏђфIМєвKxёХdЌџьь,>|шzХ­lИŠч№wƒ2эY›&ѓ\Џ“ї“vИающl’\.‡\.чі`Н^пжх Фk&Q  3™Œ[џьFа@№Ѓ–€р‰JfHаЎŽNJNŠиqАœЉ%uшдA4 ЇџЂ{™ћ`iiщуР …Пuг<л_ЭШU!,Т\кКЁF[ЃT­k2ƒHЅRHЇгЎЇŸ›GЃtжU№‚Ц…QБж/Щ# ЁчFЁƒSш›€™щyLLŽ!“IМ7мРЇNŸюЯ8ЖXщkЋЋшСІШLoѓz ыыˆmеЯ;[уtŸєШ і!)vм.я1Щ€4ЬdВk—YЉTrFFH™ѓм$,hЋŽжЋЙJgРeG7ыЦГdЌ$ЊжЉљ“H$_ƒїр/џхПŒ“'OіЭа–2Jњr+—ЖqЭ2@Ѕsв6>ЎY еZйa‹d1АTЖМ Ъ#а Р]енPх8;?^б…Ак(%с~u6X№3HjЏг9 uгћЅя ‚333xяНїpяоН>УNˆфЕkзpэкЕmАm( XYYСвв’K”ЕЏ(‹v&ьіНкYЂYhC ЩJVU/m§k4иииpe&rД,ЂNRe™љ<2™ŒCh#w*i|/KƒВўиn,–ёx ,s~†–b”ˆ<(аЕгэищZ­іq0Ј5#N{бhдSRЛншvьІnUŸГѕy2д )Z7![­ЊеЊЫ№Idћ“ь}#SsЙœ›0Шњ6•к–––аnЗнk6›[ФЏ6?šC*•Рш膆žЎЯ !?4„}ћїoA4†бё}щkgaЦЧ{Ѓ5u:1f Ь\ˆd2™m„.­чђ>хr9W*а)‚ 눋яхЈa…Л•Мi‰zъZ­ЦЧЧ1>>ŽН{їтР8pрFFFJЅ№_џзџ5VWWБиЛwЏ›eРњ§њњК›џMУ­Ј…qй…РѓUи^kпЊ:ЈumЫdзїкЁ<–uЏcrМ(—EџFйукЂ‡[a№ІјД4ЁЙђ)шьдxЊ˜№ уЎNЅP(рњѕыИqужззЗM, KBž{ю9МікkИxёbh бжА,ЁV#ЮyЇi J(f@mэЙ7„Д5@Ьd2ŽlЌmœЬд™ЅšНР2K<ѕzНЯВ~ЎшлnC>JР‡ЩњŸМрѕ•ИДnЏх%^›х@э„tp]…qnДTЧ’фЧ@Шцћђ—ПМ_[Уд0ЉAГYUєSб жА5#ек*лšH$В0Ќж9yNvёЋ€7)!#ерЦтЯјј8‚ pƒ&*х*JХ рШЄSљпŽƒ1О‘HЬ ь!cŸ‹XЫ)44 к‡­Ђ@ж$ќ­u1n<"t€jRЭz‚bPH(д У‘P—NЇ‘ЫхЯч199‰ссa axxИЯ*Y“]:g‚Яќk_ћš;G{ОtкЖ•R‰nVЁNз.ыэЪ/ањН йhа т<іѓ5˜PgjkэvŒ/ГQэ2аЁO<[VА†Q{ЧУШŒaLnЭфUbZ9?Тяt:И}ћ6nнК…Ч?ФўќyМікkxюЙчNЇћ‚ІfГ‰ЙЙ9,,,Ив’’ёДуТ–ŠЌ"!Й.Л‘5Сб2Ї~Ÿ5 s)’Ђƒ4“%Ё–Rкv}qw:TЋU0I`Pbчhш155…oћлпuР“d§† 2дкцЫ`XЇŒъ˜g[Ъ #L3р"Љ\Ы###ƒ8ЕZmDчŽ+РFдЊy­фZ:~эMч†aK uД9зž‹„чЁЦO#C5Є:Ÿп­вАЪ^Іq'œ–ЩdмџG"TЋе-Ђиbё(2щђC9 хџЕнџT*ƒX,цD”XтАYя%Щ.в:'[юh4;ЇсДЇ*Э1SбšЉ…ž mrsэпПп mЪd28pр€s№Z—З•ЈО*• *• Ње*JЅ’+чh=W[В”46tёв–+лїЎ,vbЙ%ЊтІkеЖЫj№ЊŸЉї^˜:НїJАЃcД|€0vД•Dн‰ИЅSIŽЪћбR " sssИuы–ў$ъ|ЏНі^§uLNNnSl[]]ХввVVVњ‚m‘уГжz?„vџЈSи 2'њiлŠе‰Г?ŸпAG­IЫЃ`qz V%aвљщšfРNсхˆXвЕ=оyч'*;~/Вў' <)KЉD<Ÿ‘M&$L€ИпЙі:wDЫS*Ф666іq0ˆ­ощtЦuСZ6А’ƒt8эj{›­œіsЃhGш›пMXлМбEЌбЗBЬ„P•EOx“А!3T­OqŒqЕZEЕRУђђкж5E‘Ln)Љ4ыю›џŸЫeБЫДVЋЁVлЬ‚^€bЉˆZЕю†\o@ЈJ'йžlЭКшD5Ђs%|ШlУъь;х5ђ ђљМƒ'&&OcrrВЏцЮЬ‡ПЇ#ДP\Й\FЕZuN:y7[WWЃЮ€УNыГ:њЪ(ІЃжZЌЎй; ˆŠДh]б:m‹ŠЉ1еї)Ћ[Я7ЬAъїЈІƒjшы (Ю—п‰дІМ ­Л†e§VЇпВВ•˜H-ќызЏуцЭ›ЈT*OЄЮїТ /рЭ7пФљѓчћЎ;ЌЏЏ;ЇOcЯs[]]Хњњ:?~ьHЌGuˆ"пGt„Ям’.wЋSѓм’˜Fђ1 Bnf`fэ>ƒuў-?Ÿы]ЇTЊ˜ m­’БљLйъћНъјАYџ“а‡єZŽyMЊЏ N\‚=З0ўїa*‚pJWcЬžU‹\k\tšZ[UD@!cЋяNУEƒK–*•B6›эSІЃ“f‹–%й(лпŠР0вЇјяћ(•JлВ%ttЌЙЉbНPЌіХЏЎlєщгЋІЗ#ЪЂІБ&ЄIЇsтФ Œahh###ШfГ}ПuPZfфмnЗћю=H4u3ЈВG";1Q,…ч›JЅњ%о[r3шXЫхr_№С@ЂRЉlƒ™…йMЊLrОNOуKљ:ЅP š…вгщtпкБpБ‹„˜Еаv2+ъТРTыђ4TММE[YгпйѕЬ€Eg;X8_яНЭŒ4Б­ˆŠYBЃ%$rM=x№wяо}bџхЫ—ёц›oтХ_ь ФИNиГЯеM‘­ М§ілјц7П‰їо{o`6{хЪќєOџ4.^Миз‹OиXеU•oЇŒ˜і*зб1r_Ј}ЁэЮжЉqНk Џ˜*€Х@5wк0E‚ъѕ:*•JЈ.ўG%~дЌџЩЇ}ЯФњ-ыѕукзЎЂАuЮ@UEцЌ†EЛнЦђђ2Ў^Нњq`-У7lћ-•Ўи€>(Нщt$м№ъЈ˜…&“Iљ њl Dtq†Mгв.[WV9c%tЉЊ.2ЖjBtBa]3Њ„Іhа0+eщƒc‹їяпярrTЎWч[ЋaWbІ:&’%U\DkjЬ4ЈeNcCШcs9>˜u~Ў :vGЪћMЂ“:y5z6ы ƒУ•MчЋcžЉ=Рsg€Р6!;SнЮКЗ№TOBЁ%-Ya}Ÿ:НF;CУѓ,ЂЃ›†PћwЪ]3Œv/ы~ +A„јЧ;џ“Ащ8€O~ђ“x§ѕз166ЖM.™ ўRЉфОЋбhр+_љ ў№џпљЮwžШnНћюЛxїнwёs?їsјЬg>Г­—žїЏiPНSFЬЮ цљyFУНf.—sнEtшJжгЁSњœTГCTОGm*ˆ(“Н›ьѓ№№№Ўy'рIГўMIэ1Мќтs§х”h,4р Пб`[ƒp;-”‰%‘П0вЃ•БVЎ›ФŠХb€РућЬЭЭaпО}žяћC*rТ`[ЁшHД†cI\Ьі-!‡йВfужX+|Ќ„:euккИf,„ЫXG#ќЃZљ х1SЄЁеQ ŒJЫхВ .2™ вщДћ|e“Ќа!Џ‘й{ˆ‰іьйƒl6ыАNQЃ˜#b­;ГУж>ђє§Dhј§д[ уЬчѓŠdЖЂїXƒBў;ŸЯ;'Oй_ Њьh_;сЇvšи@Oy6kЖЮNБ:ouь qѓџiˆu]3xуШW’35лБњofŽЊСkдЯБ$[ЭUTKИ(;e_жXлБД*хXYYС7pуЦ —яфјГй,Ў]Л†7оxgЯžнж Q(077‡ЅЅЅО6Жљљyќюяў.ОєЅ/}d8ћќƒ€L&ƒ—_~ЙЏ$ЃH !јJ&ЬЎi+вщ4ђљМSІгњ5K“йl###ˆFЃYуЂTLы^bYŒяб1ьРІРGяцєуёИгФи•ьŽь–ѕчrY,#а кE7hИŽf:Ъ’ЗвЗ\| p–R#Їгіј^0AƒA#Яћдэv]ЩsЏЩ*f™ЁP(ИжЦt:={і ™LЂP(8иЫТўЬАУК0,œN'ЎЄJЭИбˆnЈR›8Ц`ˆШџпЪШЊКЮ&P–Н­ёkW‰FёЖюЭN б€23RQI}*XЅAPиКг ТvПX(\Ёj@Уx/ъhT–йЮрuXфK‘$ЭduhЄй,ЏMUжДЎ§њu,,,<Фуoќ М№Т }ЄE`Sjyii kkkЎМФk˜™™СЏџњЏу+_љЪѕЗ­єbЫu;!МjйEЩk:‹ŠмВЁd)€dCU)l4(•J.аощd2œ;wgЯžuнU ”лэ6ццц>`ЇЌrrO?‹ЃGУG,ћОЃЧуљžпцЈ5hв Zї—m@˜яaВіН…BїяпЧУ‡C;=<Яѓ>юРLѕ‚ Ш‡M<Г§Щa“бТHEк`•Ъlm[Ё5eЛЊўЙТУaFƒVЉ+•Jѕ1viuК7 ’mЃЌhFГЊmР Ž„e :tЮ" sЄЃЄ@‘ž3Џ™ƒ2Ѓ-”ЫЖG%М(IM$^*4Љэn|&кБС’я›f6Ь)єЭЏЯ^л™дс)Q*LЬХ*jћ:dЋ^жїoy#6›а пЮМз’†$]›vйv%х(7@Џ_ч$ кk;)БYфL__\\Ф;яМƒїо{ЯСЫ;9ў|>7оx/М№~ўч>”…}чЮЌ­­ѕ!J˜Пїо{јћџяceee =:vь(~ьЧŸ§ь#›Э<‘ ћ3Ÿљ^{§ўЮпљЛASо EБТТŠp2из1ГмCьЭЇѓх}р^скй=О]wСЗ–vrќОяушбЃ8ў<<иИ›т7oоФН{їАММќD]Лe§ёx GЦщS'0>>и уъsЯbпўэwЪЅ ІNo›@Mэr =гGI”aмЏ§кЏсіэллИDv&‰€эюŽ9тљО?ФХЋТ%„ХД6ЅЄ=Јlh5‚t0ЌХ%рЦ дЅ™’8XѓVЅ9ЭšјЉTj[0Ё{БXtRЖКШ5ZЯfГ}­9м(Ж6Ћ$?u D4#f)Н­ЬH2TИŸS7€ >UЁ~5ю™щ“єЄ– ф0{ф3T! о‹|>я2B•|ўtє*УQŸ|† ЖTЮSЩ@щtк•{tЬ3‘жп,eГYзБ зЃkСN‰фw2рупi–ІЯXKј*У[леЋŒЖBХЪпP‚ЈšЃнВƒЏ”aЮ€mсуy•ЫeмИqяНї–——ŸhЯеЋWёц›oтЙчžC4uYfЛООо7‰$ИBЁ€_ўх_Ц—ОєЅvшќљsј?§мП‡_|с#™џњ_џ1ѕр1’ЩT_ЭYIЂ;1ч‰piэЙлэnЕяж%N;в.ЫƒыQВ09%ЬHЙЦЈOТ™a%M=ЦЦЦpіьYœ9sf[ Ѓ^Џczz=Тъъ*ŠХтЋ†eџA тћ8tј Ž9ŒƒїяˆDф‡†pцм9œ>}*4Нџ!–NЅDћzИTк\їВ*‘j n;wю <ПH$‚sчЮсъеЋ?јƒ?ј‰ьН-J‚7Zыј }Њc”ІЂ% [кA/‚ДйЌ.F]šкЬ_ЛtaW т(c\ Š* Ѓ5&ž#пЇ@4лwT­Ž —„рa–ЎС•Эu­)jPРыс=фГPй[ŒьTGBБ TъT…OX/mЕZ(‹nN€ьАuSэ\аКМ‡QоY§4–ќn>Kыр­,ЎLЅыQЛ tИˆ ЪЅPЃЅш‡rUдБйLnPgƒЂiаEelэ9jg‰ bЉ(V˜б'ZsчЮМћюЛИwяоŽш'NрЭ7пФ+ЏМ‚\.з—Й’вUDGЏwnnџхљ_bmm-єя9Œџј?ўkxх•—vДSхrѕzЫЫЫнtТУC†ˆ˜СјФжV‹}2Э:‰pЇƒ з%c#ЎkммвL–ї‰ћ€cёищФуqœ:u чЯŸЧффф6ЧНЖЖ†‡biiЩ) к@7 кР‘с!ьнЛ{їLbпО=ЁPЛГБrљ<Юœ=‹'Ž‡ОЇАQФмFЇгu‰ŽхZЉ№’жv’$з^ЁPРуЧŸШЏ сйgŸХгO?Mф5ј˜0 pћіmonnюфШШFGGЗБeЙєAYЅ-…!5гS:›Э:vfЋйlжMІcНЂ5,Јš …a иЋŒ(љЛT*хњсЭгHБ‡Ю…YДіыьнˆT5TmxТќууу}гщДюЋЂ4Ъ1АsлЕ?žНјќ<":еNav…еUЬEЇoёњyЏ(ŒDcHш“уOuр-ž+лљ<љЊдЈ§Й6иTх/Ў%kjОJѓsшЕЖIє‚‚EЪјз A”~Ўj9XxVћъ|m6Ч{U­Vqыж-:tЈЏнTЧ&ЋSб`HћјеёЋLp˜3љ‡џ№тЋ_§jŸRн Ї3<<Œ7оxŸќф'qрРmфZ’вжззC3Iк-YмО}ѓoўЭPBZ"‘РЯќь_РПѓяќдРКќєє,=|Œ{їюЃVЋ#ё‘ˆG‘Ll>Ћу'OрвхЫI€§ћїЁXЈИР“/K;9ЦёёёО€›{ˆЈ”">дТачO;@E;ЮœXYYСъъъњ8€sчЮсфЩ“лZKЅfggQ.—MмГgOпјhЕC;žчуЬщХž=OЄ“ŸJgpш№!\К|i ™ВеjуцЗБВВ†l6‹ЁЁЌCЛ,‘Щ “ ’“Е‹Јнncqq?vmЃ;'OžФѓЯ?3gЮє)L~єЉ‰џ;JЅІІІМfГ™}єш‘‹žHHR‘ еоЖlNKˆR'­5MЭmЯЕжƒ~UЧЫMФЯWх;Fлtњ§,9„MWгщ\V5M[Бѕш0ДC'Ђщ§дkVЩ{daA;*T =§|о fкЖ—Y‰v ц}аћJD†m‹*ZТћІйЖ")Šфш8hЫЄЇбN BткI@ЃЁ-~tоtъV"U x–46х/L!Oлэg[УnkЋ•JяНїЪх2Ž9вїљњ_э|aЭк~О–„Тєєјќч?ПыžчŸЏОњ*Ў^НкЗ(Џ­­a}}НOQ1,ћЗцwОѓќэП§ЗCkюЧŽХџџ›8vьh пРwоywюм§еLљќfГ…z=‚‘с,юпН‡хХ%|ц‡qqHЃЃCXXXщг%бZќNФCE ИŸэ“”І<%к;P‰’т,aэёЇR)œ?чЮлІWпэvБООŽ™™,,, ‰`ttд•Юt3?_лX:HЯ<}yWџ'0<:ŠK—/bЯž=;ђ юп›Т­[wн€1%Ћзѕ†SДьбЃG˜žžvїt``’JсвЅKИzѕ*FGGћžaЛнFЁPРЦЦFSлAЂбЈ799™^XXpRœGэcАЎбРƒ‚6cБЦ[E€TNОRЉє)№YmvŠжh†Џœ–+2™LŸ$(ЇыЅгiФbБ>ђ˜Ыу+тЁ­nЬˆuШ‡ŒшPиЬš.Yэф*и a…•єG‰afМПjЄ(еЫыбЙ кЪФьЗ\.Лћ‰DЯчЗЕЭ)мKr#:2^ѓ С•њ$ С€…Я˜uTu> ”hє”‹ЁЄCž#ЯЯXчкЋЁ`рШчb‡TЉУжьB‘­ѕіz=ЬЭЭсбЃG}}Э4мЌhчї…жћ5xб™эvЗoпЦЛяОћФ{ўТ… Иvэ^|ёEЧЉPфiccУЕюi:hь0з%Яч§їпЧпњ[+4ыzэѕWёпќ7?П-ƒlдxы­ярж­;}шWНош ^"“IЂT*сц7qх™Їџ$СƒћЦŽГЄЕ VЋѕ‘WYvaЗб>fњкгоыѕАВВВ9XlЋєИ“џјёу8ў<Ž;Жэ}…B…BхrѕzнiЈž9MCCCЮNЊ|ћG=bё8FFGёдХЇЖcЖGЛнЦƒёшс4ц6q,[ЊвВ—UEфtЯййYЌЌЌь*1|рР\НzчЯŸпVbфШhvtХbБрєщг—ьбщtЯч=пї}:П ,//cпО}8~ќx_–+Kƒ­Йi_9Г;­џ+ŒЏNQЁ-]Tк"GјZыАJ$a+™fƒъ(zеНžЛeЪлЁvЎіmѓ‡Ѓˆѕ§іГlІgQеL`ІЯр„§Ы$ыiYDлк‰RyP‡­(бQkvКqес)TJ'@RЇэ k=т§ЅƒdFE†4 ”D@iл :cEЁЌТЄfіўkљФ*QZЅ?ЦВYcЗлХђђ2юоНыГ$kљ)ЌƒF ИбКF>|ˆЗоz |№#IэфlFGGёЩO~oОљ&іюнЛ Щ`я8›>k…Ђm`,­­­сјў‡PчџУ?ќќп~ўП0ћЊ‡ЗО§Ў_пezaNпўЛTЉ"“й„­ямОsЮЛ§П9ћ"х:M`ТДфеZўз}ю3жкMiя………'юІИxё".\ИрJъL06›Mчи­І‘=m &?*™&№<бXу8с<іюаrЩЃRЉтонћxєhf+РJ!OИ$ŠйП&v0’nЗ‹ЧcaaЁoоС дъќљѓxц™gАgЯžmг(9HЁž&E?Јe€яkЧНёёq/‚( >3ѕGayy/^Ф‘#GЖЭDчБж€ш Й5Жƒ№=мШœэnХ[ИщД• GЧЈ rlзaлџЦ2М™ныя4ѓжЖB…оЕЎЏ9EДќaЙ š-(мЌzьzOУDšxO‰p№5­Г1ЃЅЎƒ:т^:afи:УœйКЋ˜)в9ёЛ4›жКЙa nјм™нSiЌsЂA4,FеjЕoh Ѓ­§1S^ƒ–xTIKF*ъЂх:Ђ+TuћрƒАМММm Џељз@S‘'ЋvШыЊT*ИsчnмИBЁАtFj{щЅ—№ц›oтТ… }cЛ=Яs™%Лp,3\ —мXтŸJуўнПћwQ,ЗЫOќФуџњŸ§'†иWЦќў—БИИДЃЦ|и;zAыЙ/ЬЯушБc}„РRi“8H…O%РbŒUдѕh€ЙЙ9w/Ј^ИS№FqђфI\КtЉЏ}Чкк–——]Щ€rумW6!a`›NЇQЏзоngкщ№#Є2:tч/œw|…ŽFЃ‰Љqїо}Ќ­Ў#›Э"ŸЯ#›Э:дŠі1Nї)ЉкV:kЂЮjё3ž~њi\ИpСsЊAR,Q(КЉК2мГпљЮw№щOњу@-‡чY•4.ќVЋ…їо{sss8{і,іэлЗ­жoЁ… 5SЕГШеIЊ.;П›57+{ЊucТПaйЊ:Jž kр$jцkUМдљђ;” #F књЖещзыWcІ X5€ќnUМ SЄSі?Х~тёИk}тяHфу%a’-šъ5+TЦЈVІˆвчЌ‚QŠi{'&пЋС”fї бСkЫџЋSьДЅШбŠ;wюрСƒлд љм5€В§ўкh‡'нО}7oоФьььЖжФАуЪ•+xу7№ьГЯК FГЬ lllєЦьИ`[вdœ5Шњпја–ЌЯ§шgЗ9џщЧ3ј§пџ’ ИwЫќУў‹ ЖЎmiiЉ/ˆ'bno…йmh Ubдв^ЉTТЬЬŒS˜л-лпГg.]К„ГgЯ†ЖяБЎЯЕeЩЭК‡дVX$“ы—ШIŸ,ы…Гфѓј‰Ÿќ‰'BˆЇІсіэЛX^ZqDZжјА2i ѓ'iZэmэђђ2цчч9w'dтьйГИrх >МmАфЂ2JZЗŠІaжу€ ”J%яГŸ§lї _ј‚ПДДфъА*иR(№ѕЏљ|чЮУёуЧЗ ўб”АЉO4ш*тЂF„5zЭ љ^›лОoЫ,%Ї@ Ѕj ЈчпЈјЖї)|ЋQ,?›зЎГ­Е}H[вЌ„ЌŽхЂWЇС{` …т9 ^Џї‰)9Я&“Щє‘š8ULГuы„- ­ŽЯ–>•PxŸџUѕ;>›Л~d!$rD+GЋО€jфѓМmЙAƒЋPIegИ[Љ\%Хђ}И{ї.цццњъѕV8‘HрGєGQ*•АККкЧ‘АК­V sss˜ššТддTпРЂъЁoМё>ѕЉOattt™БRЉ8]yыаУ„‹ЌфЕ}MџОеjazzПљ›ПЙэМN>…џє?§ПєНішб4О№Пў~hњnŠtƒЪ‹ЅbЇAr+ИхдnШdtФDлэ6JЅQ.—w-Е$“I\Иp/^мжОзэvБААр!1[еч % Е›фУ№§Jъ#љr_§•ПђW№Х/~wяо§>Ё€™™Y,/­`aaбеі‰цѓy'{n‡_Y-]”…оm~E.—У•+WœДГ" F…BСЕ&k—“эJббч›C‹Ц?Жзr*žяћ~"‘№ўэћпЦWПњUМїо{л˜ЯЬІŠХ"оyчMљJЅ‚‡bnnыыыЁNпЪљ>ѓЬ3јф'?‰—^zЉo ЕN­,•J}UЖTcљ/aС‹rlЈz~~Пѕ[ПЕЭЎќŸџƒП‚УGїЧўзЯџў6Yы BlmŸkHŸy˜SеƒВеее'š€ШуЏўеПКmќnЋеТТТ–——dЯƒх,й2› ДЙпЕLІЄD~>mEГјЗ'OžtіЕ\Ў`eeЋ+Ћx№р!–––yјеW_E>ŸЧјјx_€Т@;—ЫЙЖ>Ђ‰*ИФчZЏз1??ххх>t.ЬљГ…явЅKъ[Эf‹‹‹X[[ы+ЫЈЭд_X›ЁюЯУ‡„АRНјЗoпŽМћюЛ8~ќ8Nœ8ЃGтџјёж[oѕEyšEвHLOOczz™L'OžФ™3gмƒВМUQгО§А)sv–{AOYыё‰OрЕз^УФФDŸT0'Pnll8бн76ѓв`ТкЛeiХщѕzјпјm РџјіНіх/еСЖOьшiъ4вЭ5йіўAЮќСƒxћэЗёўћяЄaHъќWWW155…ЅЅ%72œЌIЕМ–н‚IEUљT1эЮБМЋ №ыПў[ЈVЊю;8З!—Ы!bbb‰Dхry›н&oˆAG<wmжмK•JNйъW˜ЄЯ<ѓŒѓŠŠ‹E,--ЙббZ*г`6l>ˆjІ(obы™zц˜œœDЗлMD"€›ІtцЬМњъЋИtщОђ•Џ`jjЊ‰JЇЋЏеj5МћюЛјЮwОƒC‡сФ‰8yђЄƒlи­Еs5д$ŸЉК›mС 3JfЂ1ЇAвїЉа пЃ:ќКэt6жъ йѓЧBџ:WЩxžгжAkќУШW<B^ыкїТFЭjрN'EчЃћJГ(кЉчoƒxE;,яIХЬt~ ™љ*A­Rчм/ЃЃЃЎєЦНЬRh*BnvL9kЇрxtt—/_Ц… bРыЁМqБXь nUаKm mЫж ƒa6Й<ЯУђђђЧ@˜ЭYZZšаХРE8?? иЖŒ]О|Я<ѓ †††ЩdмпR%MER,LV:ВмElЩЦ–6Тj§ZS4ЦNќЁўLпu.,,buuэC“ќvЪўwг„зыh4XXXРњњњŽЯ@Ы-Я>ћЌsX …–ЬЪ§ЩЩ|l7ж2bXїŒ}&ЊЗЁ{ГJXvдn%эРЁ]bE;Ш@‡ПE" #bxxИoЊ*Ч•S•pcccл}АAЄчy8}њ4Ў\Йтц_ЈXYYСввЪхrYš?чЉh–ЏШх №^ъєE-Oš_№otаh4МzН>ТhO76 іЃGАББс -ШSO=хрMнrЖjg<ўб?њG8zє(&''qєшQфѓљmЪwъ<ЕmK'РЉTЉFнм м<м|Œ4uуи–E…†Уи0ЪWa!ž‹Žсе:Н’Пъѕz_пc#WЛЙіуwЅR)SѓY№Zаš9a_ХбїЊƒБe }ОъУTыдёЊ`Œ lЙF…•Д…‘§ЧѕzНiс}Ѓ1Qј›йXЃбРЪЪ VVVœqр>K ­д ЗeЪ‘HGХkЏН†“'OКߘ››УььЌ3мжёк +•JсмЙsИpс8а'rЅчлjЕœ”­: ЄьyъЖгЮK`YЩТЊZCUXшaGњNM=њЎсўнH€aGЁАсь“ж‘УŽL&ƒЇŸ~WЏ^uэ{Њ+СQЛeгm`Џ­9Д!v"hс”Я”іСЪ~3Єˆ- М‰Ј20ІmW5Cžї KЕЩdв $Ў­­9тЋ’њЌ]Яd2Иtщ.^Мш”љЛZ­†ййYWлчѓАЮ4аеЮ \§хоеd",0оГgЯЧ€=JЅzН^N”aКшхrйБЩйjівK/с3Ÿљ >|ˆ7nрсУ‡}›S№ шw~~KKKxј№!FGG199щzMGFFњкЖЌQUxWыђкJІэ5:ФrдСй o\ˆapЊBz*hcўVMN•U ЧJЋђ;ДЈ†’ˆ"а(‰OњJ$T&m‘Гƒo4Гї&LДHџоТХXш“hя…*вTœШ–вЁЁ!'№Єњ§нnхrЫЫЫX]]э Tщ<-IQ_ГN.ŸЯуйgŸХѓЯ?‰‰ t:‹EЬЬЬ`yyy[m:ЬiњОршбЃ8tшS6ф3nЕZ} ~ўоЅіWqЈАяCXь3БD9-S)‰7ькд^МxЁяЕЧІПkИџЃ >„чљ;NК;{і,Ў^НŠsчЮmы\тјйЙЙ9WІм‰'РВR6›u**‹­лСыRž’ЂВкqжjЊЩ ч(lЯяЁу~вНЭLŸнLNхry›<ЏЭі‰š\О|йIЧыЙ­ЏЏЛвš" ЖуDП‡Цf;iж] .žЃолIa4[Мƒ~иЃнn{БXl„$2…бUНŒФЭќ8ЮїќљѓИrх жжж№ілoу[пњVŸЈЖZYЦ.~ЃбшЋkв1ŽурСƒNлNоSЮ‡mЁt Б…E бkIУf“ъ\5sЖЕ)›-kнM[•ЈЂэmЖDЁ›- й`FIпgEДЄжњhћфmЭ[ Й­…+QЩжx50А„2ЫоUEC5Œ:ќ‰|Ž)і}…BЫЫЫnˆŠT4zzMК^TmMяƒчyNЦѕЬ™3юй ЬЬЬ`eeЅЯyZЉїРѓ<ŒŒŒр№сУ}ѓ4”\Ъѓвa[ЖЖЙ“"Ё}&6 ЋЅкр@‘‚ВJ•aьюt:Е j]]]ћЎсўаяbлZ­v(ь;<<ŒчŸЯ?џ<ђљќЖі=rA …‚s8L!,аsџi ЅіФNЇ Ъ”@ЋмE&Шгёyщ@-UTUQ‰„\sЅRЩэŸАdKŸy2™Ф™3gpљђe ѕ§Оеjavvѓѓѓ}Ѕ ЌmЉPэЗю њ лQ&a­їXЯ7~lћђhдKЅR#ьядК !dAЕZu}южR*•022‚L&ƒW^y/Ој"ІІІpчЮмПЕZ­LBr—›Ъ…Fэў P,нфbШхrС№№0†††044дГ)|–-(iЭŠGX­5ёxэм Ъ]PЇЂ™0[яД Сс@Z.А§Ъ tвFН*ЦAHа iаРkQх.і'ыцд{Ѓ”эщЕфFлwn; ," пЧЬої}з‡ЭkgF•L&БББееUЬЯЯЃVЋѕ!7:­MГ[šPУLсfk4lЇOŸЦ‰'њИЋЋЋЎ„`ѕ ,aа^ЇхV4›M7Sž De4KГkI{ДУŒЋЉmuТdmЇФXЭўУаŸнэЂј0йџЎ€љъx,>А1‰рђхЫxёХqіьйmNmqqбЩќZ‰нA‹ЭˆšІЭфкхоз’Ѓž›vЅ lщFЕїЕЋРЎ7 ЂmЋЌ‘_ќт1;;ЛmНи{ЙgЯ\ИpЇOŸю ^ˆ(/..biiЉЯF*ЇЦ n,rЌЩ!яU-+ZjKyjЫ—––>ь‘NЇНd29”Щd\ИТЫ$bMЪеnЗ]џјкк …‚ЋгfГY9rGŽСg>ѓЬЯЯЛњhЁPp‹XџИIИ`9ВWUосnll8R!Z6›ХааrЙ†‡‡нРжМ”НЎ‘bK] rжйiћšfГŠЈСГушœ-[}а”5л яГn$ъp+яС5*“Љœ {жЊ3W4…Ш†5”ƒZЫј7к+ЬИ"tЪNПіkП†JЅтИ–†††Эfћ š%)YeE}NџєщгЮщsн7›M—n•ЫЖѕ•лЯ у ЈёЋT*}АКf•Ж,1ЈZ;tкR[ичZ2Ї šPrЋ"naŽa'hќЛ…ћŸЄ 0ь˜˜˜pI Yю<ъѕ:=z„Ч;Ий–ƒl]yЇяe‚ТћЩ€–№Жъ†(’iŸЙ:zоsWuˆ”ЂDŒxŽДуV$Mm%CВд1 QФщгЇqўќљmЧэv‹‹‹X\\ь;?" N4hе–=§&GЊžJ‰x‹кjљT9aƒє\JЅвЧ€=RЉ”Ч“:v’7Y‡хАѕŒmhh“““Шd2.#b–ЖББсXшЉT {їюХсУ‡‘H$P,qуЦ ,,, X,К ƒ ‡ЈBЗлХффЄ›ќІQk<ьFшѕz(‹(‹˜u™-ЏCЇЩq‚•’ўдYЉЬЎ’ђl0гІЃЗТ4œNp>Ÿw•ИбйуšmњbVЪ…Э{ ЮŸУNИСВй,FFFCž‘Fм:Щ.,CеЄmЕбЌао?…‰m}Y [;ЉOЏЊu|]UОЖкxњЪ4ЊПРюЁњŒШ рНЄsХсУ‡Бoп>9rФ•Иъѕ:–——Q.—БООоЗіmmлЖТВC[ fЫоBіŠRhЭТ№ьЉzeXЛŸjJ"$фD#­гŸ4ћW$шЛqќс€ПџЯџљ?ГgЯbhhШ%/A`yysss˜ŸŸwы.ьY*_EяЭ XœЈNЅRqЪyь с%єЎAЕ–1•Шkebd•4У$oy^*‡ЭкПЮЉеjЁњіТSO=…гЇOЛ§Ёй>ее6s2ATN™ZЪdйUЧЇїM~”ёЫƒ‚”АзЕдњБа ‰dTkžэeк&f.Ј FЪ”œ-•JHЇгF"‘Рии^~љeg,9snn?vА‘ъѓл FЁ§Б= dŸrŠ: (JšI&“ŽtІйnrn`ŽлЕ™‘M*rУ(=NїMАS8_3iСЋМBТt(„’=ЯУаа VДЄcЇ%кqЦa-`š)кЬж’эрŽs.—Ы–Ї1ркаПЅКX&“щ›СЎ§Рќ| Ј:*•Š{ˆЯЦ4ŸЯушбЃ8wюŽ;†t:эNжJ766œcPЈ]34…3iœьфC{У_жй00PС ТТ ѕ RиNh„=/-УXЄ@•ЖŒ~˜уУfџп+@3еjЕŠ™™™Оa4*ЂckёZ‡W™й0N…:*fњ:"]' †ЭщА]MЊb;44V;ЇчoџŽ(їœ sЄœmАgЯ|ѕЋ_Х7ПљMwОЇNТЬЬŒ КЕsЬюЕvЖЊUкn,M0дЮ„Э$ ЬТ:а|пџ8АG"‘№zН^Žф1BШкcЊНП:РFЏ2™Œsкzу•XШŒYГЖ\.‡У‡у™gžСввІЇЇQ,]С…ЂaгВДUP‡QиZ—FжќНFУі3Јu@чЭХЩ‚=ј €иNЃDD2™ ђљМ›мWЏзQ­Vн§с§ЇгЃС!AЁ$ž‹2†•­Эњ9IЛнveU!Ѓќ.3Э"ДgYРН^ЯMFЋзы( }§Йф‰ПAУ`GCk†bgw–зрƒ*g 8№†эY Б&“IŒуиБc8pр8€\.ча2ј———БООŽjЕŠt:нЗє{m0ІнD”+&АУЯх>аяс^ГЯз:ЉАQРVvеЊў…СЪњ,•ЈЕi;^љУ:ў')|7hРЖМˆП yXXXРН{їњј5ДIъЄ4Ажв_з2ˆ=,!YƒPкЂЉЖKFЙ5КЦД\hлUШЬ:Vоo%ВЗ )NЛЖTЖ№ЕZ-мМysлфV YеOž—]kК6эsTyoЛЗьшsиdЇВђ™щTSiuіv"pўдыuЏнnЇьd7filmбљёœ9НООюВakCОІ?„’›ЭІг.зс‘HћїяЧБcЧdEшЖX,b~~ХbБялQІЖ5ЪыЌQиал›NЃm{р•HЃЮrЧэ2ЫхАž7!K/Zт ёаŒƒЏѓw\ш$О)“ž›P ЏŸЈkk…BСЁ.4@ М€M]nŠ?1ЫжL‰cz}пwŽYЛ(д†AЬбаБвЬЂt~2˜uƒ“ АgЯ=zGŽA.—ыCИŽжззБММь†mPШзJŒк9лbgХŽЌQу­&ŠДЈ„Г]гКfЖSїГ=пkkйЖЭЊў)Њfл?J№Н‚ў!6xyы­ЗNЇ‘ЭfгWЇЎVнџJ@гu6dF#’€‰(Z.+ERlіЋkAas;ŸB‡џш`,ЎсjЕъJkЛ!пћїяЧљѓчqьиБmk?еkaBЉгYiWˆ>гІYо”EМј:б;Šhm•R>FьБВВт5›ЭT4E*•rЮŽuгT*…ссaЧђgŸ9ЇЗUЋUїЌФ.kODTG_!єххeg|шєSЉ2™ ЦЦЦЫхњ&ТБnЬsX__…ЂУВ/лŠІ5+Ћ+`лЊ4Га^^­“’мІ-њяbБи7Я>“Щ`vvжцe?ПжЧl ‘nЙ\v| fЧCCCЎџЖгщИёЃV“\afы™бЋ™_Яї[Э•Aе(оЖХ‰™€Ў:zN™L“““УФФDW„вщЧщ‹WЋеО JЅ~•{ЁнšI в2 Т˜ДЄd0uМ_фй0u>‘ ыѓз@+ЌV† ЈЁд_|ю–ŒEХЬ№Уaƒ[Ошп;|gЇгнІњgхУ­3З#­•фЉsюgЧq˜}’ зў|-K*П‡Ж–і€ЈƒxM„јьиЛг юхгЇOумЙsйжЕAR_­VлvDxџ§їћрv%;+2 ЖVэ+.њ :m"ЃМ~§\эdЂ]Е\хPtЭѓ‰sь1ЏеjЮ‘Ћ>И Mh=—Aџ–uN.B]ЪˆfжLвG$СШШіяпяœ!iFQˆьйAщТŒІm Д„ Еg5Ью:$IH;hluА‘­i;я %л' зЊШZЖ2‚m?wX›Ѕ`эFГƒОhfiЁЭр8ЅlЯž=s-r“““NА„”ЊчБXYYq}м„+‰ЮЈІ€BЎ 0•Ы`лImЛЃI Sўг–%U\ гЁаћЯ{Њэ}v˜“Тї;еE-ъb[н4 “ѓжђЧїЂ№Н( ь& ЬёАвŒеБœ…0ЅбъчД}аЁгgЩR(+9– Јƒ'9XЏЅP(`ccеjuG’А9дшТ… 8qтD_GЌ­­annліgи&+і§ae:%ќ1ёфЫЗЖеP9v‹PbЂД…P~Œи#—ЫyБX,С (™L:ƒЋ‹ДнncccыыыŽЭЪВK ˜ЙvЃqЅ2Йjљs‘”GЧоjЕœ‚” хѓyAр Т|j<ЙЙШ) TOUCKœ ыПU&Ж2йUЋžЮ•DBн<_:K…Y7цїБkяS k˜53VtFљф8h€Ч ŸQЖEИiШœVCѕИЕvЧРУŽoVHн 'Рјј8†‡‡199йWЋ'Ч„ќ •>fэŸў_JжuЃбpЄHuДtќD&дР)baЌ­Укйъј5ˆV‚–:aЎS Х+Jƒi>;EЊД6:Шј† ъ№U!RЛDx™‰ђ<ДНь_№$Т“’=Џ?PхD}ЦЖжЌuy"{ЊЩA2q˜ƒFГйtЮXз­Vйy CvИŽt@•F•ЏУ§Y,ёјёуУЅД‹ушбЃИpс&''ћж#Ч]ЯЭЭ9фGЈAїYQ<)в€GЧЉл’‡vУЄгiwпИ—uЂ'uJ№<ЕPK@ЪХ "КeЃ>Bк<ќT*•Vт Пе ЇШ л­tШ ;?YЕZu!-frZхы,XЂ‹F{$.*ДЏm$4ФЙ\ЎЏO\ЩM„lUиHкFњбЖпZ™ц*чЋм%oБЖЅ†—А–Ж…ёМ‚з{дl6‘L&ђ˜Z4ФћKЧGЧЃTYэк1 ˆљ Z>АѓXїT‡ЪКoп>ŒŽŽ"—ЫaпО}˜œœФФФЦЧЧћ‚(’ пWЋUЌЌЌИЄеjЙЕсћ>*• *• †S=у№e$ѓšУz†mщЧ’Ь,СiPoПЭ–•&€bЕпУ†їа hћЇ%ГъеіОAF;ьќ5уT&Кж -!№{IќааџЮ{vъЈtŒЎк;нsКOДдeяŸЖпU*”JЅОA:фi–oE%Iл!R ыѕzпL‚A™w>ŸЧйГgqіьYGšхQЉT0;;‹ХХE‡zЉфњ ЅЧА5ЅыЧЖ4лk+]ёžГЭ”їI…%ыЈc-aкnm9T‚ѓЧ€[0}œuvЊг1[з…ЏuЭHГ РžХkмѓ<фr97ZВбhИПgДHƒDD@!g—а:Љ:d. DфAсЇL&гG\уuнО}ЛO†rddФХzНю>ѓи•`DХ@"мИ„ф‰0Pa œSпДMNŸ>7ТоzЩdCCCHЇг}jŠд`ІЧЉs|ц:Џœ™’j-аЩ8pщtк чI&“иЗo’Щ$>џљЯЛL)ќєOџ4&&&њj™ *й-РkЈVЋ}UЛ!: …‚#•f2ФуqЧrfэг:…mш*ФЪkдЁBƒДvъ9ky sъ в˜Y+{[GЎj„%кLпžCиыdZeGЭКlн\ЁьяІ рЛ…ў?ЌŠ–%-ЩN;1t:Ѕжш9‡ˆ0H;Чу!ПG;(WЭћШ{ЊRЖ<ХuЩзЉЫжeЂќ‘#GpіьY:thлyЎЌЌ`~~О/€Аzv-:4`Вe5(А &‡$›ѓѓRЉ”ЋнS6›Э:ђДнWGГDЬbaaсуР…BС‹D"1fuЦь'gfIшЮ\с3iиUрŽ =0ƒдс4–”fkж*Ё‹(Ј@%г)š6нX’eДeNеТШFO&“ЈVЋШчѓnёЕлmG b€ э„­V еjеБ_Е­LЅF‰’(њРРСЖs1ъgєЭf‘JЅœPQ*•ТФФтёИыXшt:иЛwЏ{F{їюE.—ƒчyюzЂб(ђљМ+o(г\яЅf”+++e!б‡ї†ЏIТШШˆгUЇє.5šЭІCu4€вчIєCЫ( ОHdЕШ€vw(ы>, “?VЖ§ Вžэ0АЅ 4HиIŠvБж~+‰ІыР ЯЈNfћА%€§яlш@]Cфi&KЄLvm%FQ­V‹нђ—”ї‘H$pюм9œ;wйlЖяќ–––œОEX‹ЊЎsЕ‡;!-Šbкj]ѓ6№ф{ЩA`‚ШЕЎіšћT“+юDquмЛ_* ˜››‹ЎЏЏ\АЧН{їМ^Џчb$ “H$pрРФb1 ПF"GЖ#\ЃUФФ:#Њђщ|i:J~6Em˜)г j\сv…Бm›’ТјКp”Щo‰&–ЅЋѕkfФš%“ЎP)‡ОŒ9ЮAЗлE6›uˆ‡nf&$0j™Eлр˜х' їљ[з(•J}50,ъvЛHЇгuˆ…2p‰]Lt‡Ю’?:HˆнњфZся˜qпО}лmfJБэ–4‚<ЗJЅтP`SиЉ\.ЃRЉИѕ”Эfћє4и ›юШчЊѕWuЖaŠxa=L‘/ьGЗ ЫЈCR6ЕЪ3+г[Я!ь5ЋZgЕ, гЖ Њо‚ŽkUфщK`ЇџюtСŸАў™…3 Vо@уŠйkV­‹А љвР_K€ŠЄZ!0ьЇBh6РгRфО}ћ\ Ÿ VWWБАА€еееО SХ{BЗК;ЖD`‰Ъ>@:>юjmМЏ$=*мHЦ-YЗ|NЬШUxˆ7ЎB™ ”ЧЁBАZ2Аг)ќЃНРœCСЬ4™LКkЇСK$ŽДJ˜пNtДт+–8HДШ2™m€Љ†U1з€-)ш{5ѓЗЅ  ФMЋe`UбТˆ‹šѕjЛч EAжСянЛ‡лЗocnnю‰‡ё„‘+Пй;2М­ѓnЕZ(‹шѕzШхrŠчНPm~Žбk™dЉNћ_–Yc№JЅЖ![„КЫх2 …BŸјж Ї;66†3gЮрфЩ“}х=NеrmmЭй%У*пDЫЇˆš^9ШёлЄФЖњъОfY˜e>~7Ёzv№01ЁЬpXђU­Vн^aNЇБИИˆлЗoЛ~н›Оя{EУтїРбЃG§ћїяЧи:Ѕ­t\АЊЪзщtœбзŒ_2ЖŠЅhOГFJtгРJѓЊsUЭaƒ=ДэФN$АbkЕzmjl[Œ~7u&“q(3W5єZ†аКЋ*Ц1Гр}U˜z˜T-Гw;\ћнЕ>ЎFB!3л9Ёт(ъ,l—/жqi –э{ZkVcb'’фCєˆN] ^JІR8S9кŸЏшУ њ}˜уЋcлlбЊђ)_B;VlšЖб…1ўУt§ѕ5л"hМ5№КПШлИ~§:nоМЙMњ{Эј0џнUРыG0X'Ж:DžИFUЎмЎWВkЮI5к :?эs'ЦЖ‰ZЇыћ>Nœ8сІ№щя:VVV033уЪЖZжА-ФaШ)“э@ВгR—Yњ?Ч*YjћЇv5Y…RнЖg*ЕЫ‰Ђ™™мЛwЏ #,f2™{фrЙh$‰шЂY[[sУ{89 и”іeЫОыL&уиум@ќ7I0 .lЫœ:0fНф шрuРъ,У 9Ё*!бNБГ"A–ФЅu*э~kЭR=Э ѕsЕПм–0ьо…ўiPЂбЈf"Л_'ѕ6'ЩВ!4mЗd5ўљ9ЬАu,ГЪFѓОrcВE‰§ћ,IPЩQЯЅЎfaїЋ^Џ;еУббQ§Г Тр‰Ј№fЩw KZ4 sъaх‚А6/КDcK,Q5мZVhыmG€E4їТ8<‡лЗoуцЭ›nDЌ%…AсxИџЃ”ќцѓљОй&:LŠыEGx+Kі‡,|ЈыŠы‰mЉ\йlж9žjЕŠRЉфЪdƒHЧA ŸЯуќљѓ8wюœуО№(•Jxќј1VWWrA$ƒ(цд^i@6Qа"Eƒлng b5TA&–ƒyn Ta“Ѕ_хR‘ƒєјёc‡xьДЮœ9ƒgŸ}ЖѓЅ/}щуР<aД•ЩdњFЬВvЬЮZ 3А‘‘ЄгiЌЎЎ:ˆ‹™#­‰q2–fСъ•єЇ<шІаe˜R›’™l?Ћ.H5”vš џЋЦжBЕќН~ІFзƒTШ4(аЖУ0]ykЌiИH|Ѓ"`ЁPшыѕOЇг}ЁtЮlЗбz47"Ѓ/BžtЄ|ОЊ'PЉT\™ЧNд€E™КRзL_Џ’ЕћBek•XЄњ ƒD•(ЕS'mwм†loSУŽmUac‚эZф:&zF$Фžл –0хИ„ЁVКцччёўћяуоН{}Яsаqњєi9rяОћюЎРw ї‡§люm†uk +…Џѓ~rŸ`vЩ’˜ŽZжБхaю•Т&ВU,ŸH—џаЁCИxёЂkсг@•УвЈЯЏœ…іеЎ(ЁQmЂ–ьšЄ}{’.+ѓkU$-Ђ УЎ49ГeхУh7LЙ\ЦЬЬ JЅвށ`"‘РХ‹ёЬ3Я`ddН^/HЇг?э9_€™™™:кёёёmЕr…oYka@ѕНX,ж7њжFщšЕы 28™љ1гdжK•?EДц&жЁйUи@e?лХ­„БнаЫ”U'F(N[‚ЌФo˜АFЃP?#yжш§ЃјЯ№№0тёИєC6- Ÿ/бе!gпl,C.—C*•rш9ќ^fћЌЩqю:Ѕ‰щдokm[Гі6ѓЛј,ˆ0Рр4Хl6ыдўъѕК“TVr‘ “hKЂBŒaП…Ъ-ЄVѓДБ­sвy X˜СšVд-lН^ŸMaz>:п@ƒйzНŽ>ј|№666vЭLЧЧЧёмsЯсщЇŸ,..>1№aВџў§'СМ,Ѓ‘m]МFЎ/:uEДTLГPЎOEђTC"ь9‹РJЅ‚еееМЧЉT gЮœСљѓч]Ы­ю……ЬЮЮ:;<44фjсОя;;L—ЮrађЈЕЭЖ<`a фУ˜кf ,Ђ зO”‚з=џŸф>"{ЕZ ыыы˜ХьььЎDОёёq<§єг8wюœKЌXњeтђ1 GЕZЭ3гчТU‡Oe+.|eЖЋЭоДNЏƒИHЌѓЕm*к>bаapЄ}Ÿ5tZїƒ>•oЁуj_: дўНf>м0tTVаEОщИвЖAE&“q5ЦJЅт"Њ'JXbЋe6›эы Г$Ё“яeЦM].—БББбз“OE@ЮNЇуФ;TХBУ nl=bJЗлu! §йёеƒВu{?l 6Јі†иžчА+ДcQ:zma “їUTC?ЧNtОКч=z„7nрсУ‡лˆ‚aЌѓЋWЏтŸјNŸ>э‚/“yRрIГџн€'-hћ™ъCАП\б+Bх\?Š$1sЕњљzаA CzєиЛw/ЮŸ?уЧ;'ШчАЖЖцћиР„ЈœюеАnЋSfsУXKъ{’Œ6ЌЫЮрЙr_ ЖN ` …‚#юѓ?~/Ој"Ž9вЧ1jЕZ˜››CБXl„У8)UASyWЭРHJ#Ємl6БВВ‚l6ЛЦMЂв•š ГчŸ‹вЖ€)KмBѕ6bе@3?…сеИаШъће!Yђ`XŸЋЭМla[^lЛ›ЪбZЎ ккТЬ‚Qm­VsѕD")дЈеj…ШчѓлƒЧ“рЩh›Япg;!xN|ўl!Д}§Jњ ‚Р)іБ}д’”ЂHЫŠ (hkЙhjыSуоЮдцeГ§0)Z X„Ш vdЊЖGZфЪЂUv€Š5фvMкя.‹И~§:оџ}ЧбЄ(‡ЦЋЏОŠ—^z йlЖHлjЕыњУ"іззFF†ё‰W^мб{њќ\Wœ Ч’!gВЩHjp`;†,вRЉT№ўћяЃP(lƒзэsЧу8uъЮŸ?яКs  KKKXZZrћŠі€<^|ЪQm EI™дйТvО(zКЊЅ?S˜дИн‡ юU+ІнnуСƒXZZrS^C,УSO=…ЋWЏbllЌ/!k4˜ŸŸЧьь,*• 2™LаjЕМ­`зQRџ;~с~‹‹‹^>ŸЯвiЋ’ЃauŽŒЬHB#EhYЧZЊбфтеV.xЂ ъќе (дЏйo“йfBЊ–ЇS УTО!АFдЪXЊ‚aXtЏЌ`mфFбйфV:SсFFёЪ‘ qЂр•#‘ˆ кэ6Вй,ђљ<2™LŸ Я‡ЅыЕƒ№$K?„§I&Єњ`:v*‡ЪОзeиНЕAf)DžД”ЂУThHpдЂжў-œП“’^XOџ њН]a| +Ќ4Ую‰LФРЮ*Ј1Гu§0тVЇгСнЛwёюЛяbvv6дщk›L&ёвK/скЕk8zєшЖ „™щђђВSŽќ($Р'!љйџЯхВИtёЮ=Нэ;FFF":…OG kvЊƒ˜ИЗэsв U_ўх_оv_­MЧSO=…гЇOїйGпїБККŠййY WRЅ.ŠЂ'Ж=”уJ`Дзe3ћ0ђпN{cЇ@“:э(вФ*Œpm•BЙОчччБМММkЗЩШШž~њiœ={ЖЫС’жњњ:жззЌ8яi^ŸHџхќдыu/‹EтёxжЮ”ЖЦŒ M ˜­ч 2Оњ@ЈŠ“ŽЖ$’0 UћКеXщПiЌ3Зй›U€ +7„СЧ”Xѕ@­ГЉ ’–Nд№и$FыD ˜Хѓ~І'cŸ›‡FŒkћnЕХO‘fГ‰bБшž7Г#;аˆukі№Њd/;4зR†Э€Ž%yŠ\Х–LВ$Р!S4€ЖнЎKі #ѓ ‚oУВвAгсlYJƒ.‹dё9Ј††Ф`šчmЧ kpБММŒ7nрцЭ›}уcgЯžХЋЏОŠЋWЏіЕі2KcŸ9kц\OBЊ +|˜Ќdx/^РЉ“ЧC?џФЩ“xю…ч’.іЇ]Pс*Kr*ьЏ ЅЊrЉСeXmŸћїдЉSИpсіэлЗ­дDRпъъjпHp;­Oy#њ\Ќ˜zžVˆKбе0‡&i8k0amЄ&aЖѓ„їЗ^ЏceeЫЫЫЛ~псУ‡ёмsЯсфЩ“}(1ХЈЛТ{Ёвь[ШІР7?0A№oDАEцђЃбhF'`iДЯˆ™Žš‹‘dU—г…oГpuŽќ:!+еjыѓ–мЇ‹кŽF +ЈА.> tЌ2˜жmkžЭN,Й›HГyЂ"|M%VѕѓlOkqtžЬР™S‹\Ђ3š5SЂ—Ÿ›:$­й‡)мYдD  шШSЎ#:6%Ф)dЉфP0i‹(K:OBЅ“5ЫQ…C+гkoеўэы;qТІУYB•ЊDъ^гРuNЛЂqaЅЌFЃ›7oтЦXYYй‘аlN‹ћФ'>з_“““}ЯЙлэКёп,ёiї‡бјPт>ђџуИјдy;z8єsSЉ.?§4Nœ<БэwэvЧ фbн™х[DЃбm\KМЧЕZ ‹‹‹nя B‘XvЛxё"žzъ)Фb1|ѕЋ_ХнЛwн}=~ќ8–——нš4Т–…lЂЃ\aЪ=Rлh'$Z›­‰л“HЋ–‰-‹ZлШыY__ЧЬЬ 666v„љЃб(.\И€Ы—/їЉr=.,,`ffЦI…ѓœu”5нEЃQ@dЫЩѓЧ“€wцoЄпї6‰ЄA€ Гu/ƒ<ј‘hОяСѓ}Мџџ(§щ Жn–зыѕвšiщT*m'QCУ­pОmЭГ0|иТD№Г„іG[™ЪAЃ6mV[lєЖИm_Ќэ ыПжШ–d"оk…ИUbY{тЕOey•йЫ{ štЄ:I‹‹fГ‰ЕЕ5дj57ЬIЕш йыuВo™cЁ™ѕ0X`‡†v( _mди(1Щjс‡щ.(E%=Љ HuCEї)‹;ЌцoFv[ a™RX‡€…сэњБmŠŠОЉШ‘fqJЪЕНн№№сC|№СИwя^Ј6…EЮЎ\Й‚з^{ WЎ\йІШœПР{egЏлвФ‡хьєя§ћїтђХ иЗoя@g{№аaМ№т H$ЗЛV–Wqыж=wŸ{Нžы!вЄЊ‘ЊЦЉ„?ЯѓАААрFR‚љљяЃGтђхЫ8vьXЂіСєнџd2йЇ‰AЋRЕl Ўћ^&mЙEэ„Ђ aС†•що-xДгўЌЂІŠ.s>yaƒŽ|>Ы—/уТ… ŽыРR(ЛиDЛУ@U9L ЖlgФНŒ?ИѓwjоЙџ<xрМxДЏ^ал МnяO'044фe2ouu5AU%B%*йЫa3уmOЉБjйЪJц ы А*}T„1ž-дjб улЖƒaт›^ Е‹žкзШ[7ЉЖ6’cЁDFждЕvЩРKkМ$“бqиR3kжї9]Lчp#' фѓљ>Z­VнцуyБХˆ-›ќ^:+л†Їc5›eFiЕјYуdцІŽ(†– Ќ\ЎЎЉнUйsP=4Œ\ЇAŒўшyёЙёžыфBўА%ЪЊ[Zў eЅoмИызЏЃT*m+‹йcпО}xэЕз№кkЏ!—Ыmу&lll`mm­'cЛj”Mўa€н€ёБQ=rЧE:шtі<ˆЫ—/cdt$Ддpћж=ЌЎЎїэ):X§tp]j§<ЬЯЯЛ>›hшљЄгi\ИpWЎ\A>ŸяГ?ѕzSSSльУ™3gаnЗёэo;ёГЈ”fамчД-jWН-ВqЖмk;‘vк3–Љ$h§=“ЎЏнжЮч>ї9œ>}Кo­u:,--ammЭљL^дЉє;QеХв<ъA%ђхжo^:ѕsЃїя§ƒѕ™-чяo§ЗgPмњ†#=O§CAЗгEЗлƒзн$›ўЉ ђљ<ЦЧЧНЗп~ћќњЎ…Ÿ-Б‰pr­Vsф0ea+Ь­Е$]Ј 0˜с…ѕd3ЉчІ—AО6[БŠp–ДІ†Ѕ3aeјлiX|FHыbм aUяƒдХяЇ#сМ:nžЏЊв№1›oЗлX__wх…ќ™Pʘm…ЅRЉЏŸ_љ$ †Б‹ЕBю%4Yq-ЃŠеЖQЫцg–хЋЈŠЖl–]…ЕfZ'ЄPПђ:l†Ь}cйз+++лJg эѓ3 +}їю]мО}=к5KK$xс…pэк5œ={v['л8ЉaƒиАђ‡инjЖЛ““уи39‰'Ž"П”„^G2‰‘‘Q\yц ЦЦЦBпГММ‚їоћ6Ibм{­MоŠ’)е.A€bБˆЅЅ%Ї†V’qФСƒИrх NŸ>НmУТТюпПRЉдзЪЬПнЗoрњѕы}нSJ˜Гk’ŸЃH&ї0ПлњQ:HЄЪL­sпIРА–с_­VБОООЋh=Юœ9уl@ЃбРммœS=$1–ЅPEM5I€nЏƒoОŽефc#‘•`і3љёŸОђпьљіЛџев/‰ѓЗA@Т€р§ПUь[ ЇџЃt№Ї2ШхrоШШˆ_(-,,ртХ‹}‘”ЩPчKr•ТнђЕНђv2š% jЙ@KкNbГx] Лё,‰Q?гжnУ О0єС:šІн„Ђэ„A;‘LЯ[%wuуъXмFЃRЉ„x<ю$Oйюфћ>†‡‡144фф4Щрз9lСБ‚=:РDK ”№Ѕh~Їъqг!ЊЃд*ЇїY о?fЧ:%Ц“[Зˆˆ(#Z‡Ciц‰†ЉЃi †<ЉЕY‘ж3WVVАЖЖ†ƒnS*Д“їІ\.уюнЛИ{їЎkљк);;~ќ8о|ѓMМ№Т .№учSJy}}НO–x& †ж=ў$Fї-“IcЯфіял‹§ћїіЕ2†eћ™lЧŽУSŸxНѕz7Ў€ХХхОЕ@} Bў„U#ƒ*ЃїюнУќќќЖŽыИуёИЫіїьйгїоVЋ…™™мИq…B™LууулЦыZ™mmЛЖ"aЖдЉŽžћЫj„„ЌЖу)l/†•aУ:\єаі?EрŠХ"VWWw…љ3™ .\И€o~ѓ›ЁHлƒАЖЖцкЯЩЫаСB:6^їwЕSТчKџ‹x„ rH4S‘ЖW#№‚l$ƒ?џє?љЪнИёVЕы"№l`pїџ]ѓО[трї%`’NЇЧ№ѕЏ—.]rlUЖьЉЁдa „a5[T†2ЄТjšѓѓ ‘\hпЯьY3К0BZыT™Ъ\ КШ-4fБ-?(‚ FRы`Ќэk+ЅЮЊІHсCђ)єkDЎ§ЫlёЃЁ‹Чу(•JXYYAЃбРШШ2™Œ3ЌRшЇ^Џїe“J&ЬхrNхБX,і‰ #ЇЕв0ЁыЌ­ёдї&€&Gныѕ№рС з=aee5ˆl6›˜››УУ‡БВВвЗmйlЏОњ*^§u>|Ияsi”YлЗзж*ЉArX™ьУђ\{хELLŽ#љB,Бx#ЃcxіЙЋй1ЈИsћnнКлЇСu@)qОFэ "hЕZ SSSXXXшK ТўББ1<ѓЬ3ИtщRŸ4:Q”ЕЕ5ЬЮЮ:&:92zNaУuш’ФЇš6и–Ь­T‹’gm‹БЎЩАa@–{Ѓ];ЈЗZ-7p7˜яоНИ|љ2Юž=‹fГЙ-р9.//;ЂБ–$iTЮ[ƒ˜™кќNёџ‡FЄМduбhW|є‚Унv'єz?qќ/eіЭўfэпнxЏUан% Тƒ?@$AЕZѕ‚ HвЉџб§ž~њi<ѓЬ3л %UЃВфЭXЕ%NkзšU)Єna|y ы˜`­­‡е_wj7’žиИ` x§J,ГџЏ‚"dЯlV‰UкVЈ­8:ML7zН^я“%ЩХЖDђпь`э_Uї‚ pвТ$іёšјдˆ`п7пЋ­yѕz•JХн ;€I…UДцiU5SсПtЄRЉ>2ЅБ3ЬэT5%KYѕЦАВб ЫЦжЌ*Ќйh4№рСƒ>ю 3-Хb1”ЫхО‘ЛЛMdЛxё"о|ѓM<їмsЮa№\Ње*жжж\[giб"ZvЊcXFlU6w;:АуяЩ†G†qсЉЇџєИuѓ6ОѓnэЊ˜2ћ)@Ѕн ЋЋЋ˜ššъœіМ#‘ЮŸ?ЋWЏ:ДFuEfff055…vЛн'пЫФ&›Э:%Nл­kDч„hйЯŽŽІГеФЖ`ыОзвЉ и4)ВСС“Дђ\ЃбЈ[c…BaGnˆчy8{іЌCOž„xЋœэтѓдNўџ;•ЏрЊПh<‚tr“,мiuаl7аыtВ­Z>?ъ#žJМtъ/Œ§цу\ёЇ–ОV[и[ЁїнпЏ6@o}}нЋеj1’М|пЧ;яМƒ••МњъЋ˜˜˜pа*#/эЋT•@:ТYJ>Si_5в)j6I#Љ [ЛИ!ьцБYŠ" –`чН+20ˆ ЈЇŠ i=дŽЕНВыЉnлUO3IоефХb˜œœt†€“•qOхРЕЕ5T*з‚™ЭfћИ ќ;Ђ:‘KЫЃЃЃˆЧу}Ѕыјyt>„’&myE‡–А|Ё ѕ=” ЋS‡ЕpщїZ­‡АЎkшlэZ9–№ЄYwЇгСьь,цццмзяЄбъvЛX[[УќќМSшГ5zŒŒŒрЕз^У'?љIїьЕЛemm Nѕ. ън)ИбkДъ˜au§rdВY рфщS8x№РЎяяt:ИsћnмјѕzУiњГtХЕBd’8џ–­А–HlŸ{>ŸЧГЯ>‹ЋWЏКnўM­VУввюпПЕЕ54 ЭтyёмTпФ$щjrЃC„Д•W9Uм‡vXŽЂЇVrлŽ”Жˆв‡™Жищtpџў}мПпнгAяOЅRИxё"._Ом7#$T*ЬЯЯ  щHeѕ vЛ]|Ѕњ[xЗёUФqФу›mzНnнV эzэz z™|йс bЩ"бШХ3>ё/2ћ‹џодџВqЯнУ?™йп)їЪѓПW_3Сv)ќ` иии№Z­VTЧВРЬЬ ўй?ћgxс…pўќљ>(]ѕшmV­™]˜ББmO:?кіh[CЋN@ЃX­Л†е­Тйl'Lo@сxr #ЊQДcf$ 7ЎVсjmеQx“e:;1‘ЅВхЩ:nЗл}†‘FŒb'ХbбIJЄd@О†…%!+Vcљx(4Љ„<НяzOL№\Tї\;Fh8uF;Q+[7ЕЊŽ xдxкі%[т kџ S7уZa&oЧ+Ћ‘]^^ЦЪЪ жззЗe‡aˆн•+W№њыЏутХ‹ŽуРЃ\.cuuењlpVЯЗПГmЧƒєљ0‡яћШ ahxч/œЧшшш§ньь<юп€Ййy›uxЛЂуз,‘k:caa>ьы’Аї™џ>uъ”"cŸзуЧ1==эJhžтњ#EkеЊP9ˆ :Ъъз YЩЩVU[k-gШ’ќТfЂX4'  \ўЇџщъD ;&&&pщв%œ={vlii ѓѓѓЎИJЭђ яЕЋSRъƒњјNэ+ˆЦЃˆF"ˆx>М^€^Џ @,E=јн‰$rCyDb[vЫk9x _9ŸќѕЪ|ыї[•V12МIуЧ|/8эGт}.ѕ{Ѕ›эџhњ7Ъ [A‚gаŒ|_€ћїяЃVЋсГŸ§lљW~хWRtд ѕупРѕызёЬ3ЯрфЩ“}њє [fcЭžСхa­СрbW8<ЌзUт„щM[ЅAЫjUj•ЖЇЭИИaшxУІgбйh n`uиМ'УУУH&“Ў­ŽЦ‚ЮV#]fђVБK‰wЌ…ёYћd†ЎHГvФb1 Лщ}ёxмешйOЋ­{М—­V ыыы.a сћОƒšulЏvPылЖ‹ђЉ•Jœj6ЇeeќkЩФ4›Ѕ[УЉ%&}žJ*U”Фђ46­еjИwя–——цƒ ”_zщ%ЧцпЩаВ^њмsЯс•W^Сшшh_ЦI4ђ tЦ„ЫvnЛ­ЕъпXдKбЕAу]w;žКt ЇЯœA*•|"лДООлЗятЮ{hЗкЎІЮ@ZПž7“Š……,,,lыgЗ?щtЯ<ѓ žўyŒŽŽі­—jЕŠ;wюрж­[ЎЅКюЉЧOtї”-ЗƒЪJamwzЯэdPETY5 љ CjДT–ѕыšбВйvтe}рГ;yђ$Ў\Й‚§ћїї}6ч,..іqЄv*#Q/E|щ=гђнцWK$Œ'€ @ГвB,‘D*™B~п0ђ##(­l`m~~ЬCЗйКрћшЖ=/–ЬХ~*v"ђSV­fя]/€чїўLіЄї…ЩзŸYўrs @G2_P?%€љљyјО§ћї{?ћГ?‹_џѕ_GЉTкЖ(JЅОђ•ЏрСƒ}=щJDa&eЛtёи™рV WБfj6S$$6Эfєa'+ЬВлФ80шЖЅb>ЌЃ,—ЫЮ™jgƒf0jHљ{UЃБc§нї}дj5ч$5Аві;пїRЭfQЏзГ–NOYєdзВ=“™ ‡ БЮЏэ}\МFЖхq Ћ"Vuвr7”щЯ`A;7,I‰Ѕ)"кЂ\;є9ъР(;Х"Gš‘iэŸА,с~х9шО€—_~/М№юпП?Po€Ч_ўЫЇNr‡чWЉTšcїY˜а‘Ђa­\Ъ“ SНДяК?cБŽ;цІ †—Џ\ое•ЫeLM=Ц§{АВВъа\.чі‰КџКн. …VVVPЉTЖё&Ќу?tш^~љeœ?оэ^яЦЦ=zфxšЅ3и$ВFn чb4›MœјОRЉфЪ~ сОАd<-kъГбй,Јэа2œэВkйЎЋЌЪVЛBЁАыГK&“8wю.^Мˆ\.зЗЇKЅfggБВВтіšЖ я6KТŽTWЧOЛ[юАŸG*žF2‘DЇоBЕUA<E2™УфоC8xђVччDбЌзбj6о†паt Р‡x,Š^7@/ш!шA/@Гб>–<о§ŸЗМi.Е­ €|яЃ–О/@ЏзC:ЦуЧkЧЧЯќЬЯрŸўгŠ8ЧХ‰DАККъ7‡н`\А:дж>.§ŽАцЉZYaлЮb3UД­2К ЌЎy˜Ёг#q§<TTN”Ar,Иш^gцЭЭO4€зJЧЊќжзT5Єœ••tЛ]зРMЊR™нnзuаˆВ]Š"5фАŸКX,Кџз@œкF‘ЫхЭf]‰ƒзey xiЋЇŠВYтC{Ў„(§ gmЛFТH›aЃuйж‡ZЕЬ <~ќЫЫЫЁVD]<ЯУЇ>ѕ)œ9sѓѓѓŽч І…с<шœBЇгСТТ‚“ЖЕ%KnЕм:vu<–VCЖмUЃћБћ1,..тњѕыO4ˆЮъёуiЬЮЬannFг9Юl6ыж3ЎS%{r"сЪЪŠ{ц )мL&qщв%МђЪ+Ў_GcOOOуў§ћЎ„6::ъ^щtљ|ЉTЪИЎVЋNk€ФМt:эЎKНяЪїсОЖvвNˆ$Т@TIGл*ŽвэєjyСrЌNЏзCЉTBЉTкUчatt/^Ф™3gЖщЦ,--ajj ыыыnџkBІъ}ƒКѓ™Я “Щ`qqЫЫЫЎ4H$pќјqœ:u ŸџќчЗеnЩЩQ"(3` Ђ4ГВIKрВѕт0ѕL§ЗхфшОтїцr9\Кti Є[ЉTёшбclwQТАN“zЯ‰ КуVгc7‘LeJn­•H>‡C‡с_ќ‹сœ3N:пўэпЦWОђ7Ќ§ЧZ›з,Ok]*о F†PВFЅ\h]\Еб­…`ЩKЛM$:ЁГT\ІнnЃT*9-jжЉДCN9›Э:>G(3€` Rž ‘г‘_.—нѓHЇгNЦЕнnї вж>ьSf–ЂЄ;u\ЬvFGGбl6БВВтT'&&0>>пїБЖЖж7К“Q;D"съ …BхrйкЂATXЦФЎ ЎEЭVеЊИ‘fšvЬВ“м*yбŠ;бHъŒq"t>  xORЉ^zщ%Мљц››эkЗnauuеeЙЯ>ћ,іяпп'ЅlЩˆнnеjеё'hШЙ&\џМŒЪБ„]pйЙ6Аг)•ŒЦ}’JЅњWЃбРђв –WVБМДŒ/љАЖЖюЮхgіg1::Š\.чжЫcŠ<*УПзыaaaГГГЎ†lЩžЄ]Кt /НєN:ЕэžЮЬЬрСƒ}ВвЬЂ‰TёZbБВйЌЛЧ:4ˆh”хUЋUdГYŒЃгщє1н­вЄJW3 ƒГCЌ˜ѕѓљRG„Ј,з6Гdл"ЋeOо;Е);9§x<Ž3gЮрЉЇžТааPŸ§ЌT*˜ХђђrчDч~pэ№њЌ†хpё‰~№^iАпl6q/і6:™’ёМHAа†чw‘hН xuD"m$’dђ9дk%TKT‹” EдЊUнщ$щЂ‰Ђё|ЯG/‚Ў@2•€MЂйlЁхЗ~ўШO%я=ўеЦч… ш§Љ!BѓЈ7l ђ\Ер}ЄW`ћњmЋы їZћ`Й:ЖЄІ5ŸЋеТЏќ“џЅяй EчX}пЧјј8тёИы ув€ŸСkЕZХЃGАИИшОSэ‡ТїъЋЏтљчŸwКќќa—ФттЂыК )—HkЎA&< ЊЋеЊSŸ#.NЛvZ>OfЇМцA@Їгqт^60Г„d-—’KЈ_[У8Pіћй~L[Вг‘ЯчqсТœ9sЦ­]ўЌЎЎтбЃGю~Zнo Ггaн*Y"ЖЎхNЇƒ‡Б˜лsёX бр{=A ‚ nЇ‚nЏЯkТˆ%Ђ(л(ЎЌЁ\(ЂВQB/ш №h,Šh,Яѓс‘ЭI€р{"~‰tБt^Б‚vЋAЊ§7|qЋ+Рџ(йџї-(‹Иyѓf|bbТgL=lЯѓАgЯ|іГŸХГЯ>‹пљпС|а)YХ3Т?KKKјƒ?ј;v gЯžХ™3gЭfћjўВЗЕ/›Љ+уZ!3;ж7ЬљЋƒ Ќbйс џZх@НVNЭ#ЩŽ§ѓ$чqАFHШ=“Щє‰т№oЕ}IЃeFїЬ~ З’юyЦЧЧ‘NЇљаї}W‹ЇѓЇБСž={ЧLЧыa&кщtP*•\'BЇгq†Ю  Xu2ђвщ4RЉ”›2GEC]K:ЭOЇ 2H"Ћњ D1иа‘ЮЖФЖE1ћжuДЖЖ†ЅЅ%ЬЬЬИЖ/•еŒЊцэнЛŸўєЇqњєiДлmЬЯЯczzКzз †AT˜!Ж2л:™чЬЯуѕi6ЉЦ2lИŒ чиLVЊ9,Pсї’ФВ–№кэvŸѓD"E"‘pЬ{-iёяWWWБДД„RЉДЯaN:…W_}/^мжЭАККŠћїяcvvЖ.'‘Vл)ЙІˆ^%“I4›M‡^•J%збУ§ЩыЩчѓ}%@юяАБуЊNШ ƒЯ‚$Zžqхd2Ї-Т9cЉУЊUЖлmѓя–эпП—.]ТЁC‡њЮŸˆ‘mQд.LhHKЋ–'І%C–;hлн6жz‹Ј{e=`Ёѓѓ‰hd Hј D}п‡яy›ФОNVˆfнGЇ^GЛUFЛйDЃQBqu г3шu{ˆxЂБ(рћh7[ЈjКМHfRHц’ˆ%ЃHЄ‹Ч‰G€nЋ‹^ЏwbфšwfуЋСMƒќр#[0NŽЮ… Ž}ЎгггШчѓ˜˜˜РЯ§мЯсбЃGјтПˆ;wю„нБ№%…">џљЯу№сУŽ%Jсkp­‘ [@Ъ/Ћыћэ/[WЖЂ'zV‡ЬEЉСŒNЉЃ!&ƒ˜™ВіБлыЖr”љЋ#Mщy3`˜˜˜@<ЧњњњІШЪC™$&ЊЂёўi№ЁY•–=ч3SЦ№№0zН–——Q(к@Q"ŠБЈФВ%?iрЅ0ЗЖYю&ђ@‘kTсж4аmFo9ŠDдыu7[|iiЉЏu.lj=НлэbhhзЎ]У‹/ОˆL&ƒJЅ‚‡і –Бт%KKK.kЇГК№|>–Ÿ0ˆD†Ў)oFїк љZnбыЅУВzZЮbfЫ}AG>44фZћ)ъt:˜››УТТBшА.}žйl/М№^§u7 ˆПk6›И{ї.VWW$ЯЉ–ЪДзўy:ZžГу$п1PЩd2nЮ€ЖzВ<FКЋы(kх iyh­Ђ_ 6”tIŽŒ’{9P‡#Сw:bБNž<‰ѓчЯcxxИЯNзj5LOOcaaЁ} оІhЂ-НZљuЫ§aɘYЃWУz{3н˘bЕ7‡ жC4 Ф§Фж4ОMІ~/шЁзэЂзюЁлэЁз €ž‡NЇ…fН‚zН†zЕ„zЕ„ZЅ‚D"†x>ЗYџxh7ZhжZшЕЛ@З?E"“Є`РНа аmvбыіЭт€л[€їQЪп—рдЉSЈзыYBЧ„Ќ ъЋеj˜˜˜РЩ“'qњєiLOOу _јОѕ­oѕ)п…СэмиsssX^^Ц7Оё ŒсмЙs8~ќ8Ž;Жу, l;˜эkЖтtlжиhж=­ +™Šй Ѓ{% ё^•J%ЧŽD"X[[CA4usь|ї0xUG]вA№3и499‰|>яДЭйŠФM_­V‰D0>>ŽЁЁ!,//;:кссaї •' dГYФb1фѓy7KзДММŒfГщ2fЃ„Fu41Џ™чFD@Й$мь ђ™ёP­ YmY  м”` ˜žžЦттЂыЗ™ВfеŠ№}уууxёХёдSO9tdjj хrЙУЁФ%qК пh4\@ЩчСвХgЌј‹eђ+!Q9VNйЮба G[+•Ћп­AїdvућО7Э€‚Šp `mйGїэбЃGqэк5<џќѓ}ZљP(АММŒ‡:Ї­єˆЦБЕ•67ђxНDюˆРэнЛзЭ)рч”Ыe јО‰‰ ЄгiїЬЉ.цѓљОz=ƒ\–x/Iж-—ЫŽ Яр™Ш˜ЊLв~ГОП›рN6›ХљѓчqњєщОrLX[[УєєДыєQЧoyvъc™[3|к8+еj5бэі=дМ2{1п}„BoНx‘рE|шЂгnA€N+иT§ыєр{>"~БT Cc№у ”ЫUT eз‹№qь?yёD ‰TэvV žЗеЙе @<G,‡ѕhеšhTшvКК=ј>{C@‘2Р‡жјОЃЃЃXZZЪhл”ж•h177чHa{їюХ_ќ‹?ђ#?‚љ/џ%Оѕ­om{аam8|РыыыјЦ7Оo}ы[H$8zє(>ŒC‡c‰5ыKЖъ‚ЛеAе …AqaэV,EbДюnЅzUcžQ>ЁsлЎcЏS{-сŠŒ_BуA8Ї 5sf;$ f2ЧАњмФеjеA—*RФ@`xxбhдAўD#‰rЙ2™ :Ž##ЊCбN о%ю)_@Џ[’fЗt> ы !KЬг,ЅRЉ82фттЂ+(" ›fКЖ…ёјёуИvэŽ;цјГГГЮPZ–Н:2}іVXШЎ_Œ(ьЏœ ,ь„Bu‚aZaS0­кЁў^еfЈ•J?Цммœk› лћt€Я=ї>ё‰Oрјёу}ззjЕ№шб#|ˆjЕъж˜е…АукУDпТДUй]ОЇбn нjЃбm иYЧRwЫн9tЃ-Ф"ќˆП)ѓ‹к:.tр{оfњэ{№ЂDc Ф3ix~­vѕFеj ‰dљБaФQDbд*5T‹%ФгqН"~‘h Оя!РцїyО‡vГnЇ `“cаѓ=јq …dџžбиБфћl-’ŒФЃт6 Я’ѕЧ122‚‰‰ ќ…П№№г?§гИ~§:ўеПњWИuыж6 ]8V‘ЌгщрсУ‡˜žžю#O9r‡ЦоН{З}Ц чь42uPmTYNujJ$cš5pВнщДy?rЙœc“EЎ0)‰(4Ј#y•D]ђnЗ‹ББ1gŒZ­–ˆ!1‹ьмvЛббQАǘNŸ†LГKBЃфx4 Œ;…Cжh•ФDЇЎƒ‡ђљшѕzЈVЋnУБчš0#чУѓќX`FЬЯбОb•.ж.%>1sKЅRЎ„Р‘Фv€в б†ЈКк›­A@БXDЙ\v$EЖТRŠ"9Š\йЖUерГљы§Џ#›Э:­џ••‹ХОL‘ш„S`uТjёaЦš$S,Ќ7[TBEмЌsчч†i_иN;ЄЪъzŸЂzЅ`ІЌЯъНїошє#‘ž~њi\Лv яОћ.цччёПё№}?ѕS?…‡тоН{Ž?Сu­ ц„иq_еыuЧъ'Щг:YТћ„кGFF\ћkЉTrФЧl6‹ЁЁ!ŒŽŽЂX,іі;!Tм ЮЄ •Тх>gbБККŠѕѕѕ]aўT*…ѓчЯуьйГЮ~q=‹E<~ќиuZшѓГйƒt3ТxMƒ89іsmџГн@­QEНQCЗзE$G4ч{ˆDcˆFcшљ h#6ƒЇT6ƒсЩq4Њ5t{EtƒMл—ШfсG#яˆNt$$š‘K‹Х0::ŠX,†ѕѕu'mŸЪfГИ|љ2Ў\ЙтШЉ?џѓ?я UлёТђ„fйVћ!ЌЅNuьaѓ*јљtZ%L­т9йVHйI›ƒff ›k9 яA€ћїяуцЭ›XYY э€ауьйГx§ѕзqѕъеО’Lииоgžy№ж[o…Юђаљ№œ# AнЪЪ кэ6ђљМЫц‰fjЋЇТгJмd№Х€‹ЏБœGц>ХЖиюјрСƒPLGom‰ЉЂыŠœ;9}Ÿћмч011бgыšЭ&=z„ЙЙЙО>ЕaіP2Ѕш‘}aк,ќ>;“ЃЯц@а рwЃˆuRHів№{Qtа’[BЩ4R™4’Љ:6š‚ ‡fЃ‰NЋx@ј"hT›ш4зQ\п@Е\мdљbБ(Ђ‰8"рGx2D&X<x:­6еš••Й4’™-Н‹fžWGo8„№ƒЏИїfєsk[Ёo[*АНС­V ЋЋЋииишsШЧЧ‰'№?ёX[[У[oН…{їюсСƒ #іѕА6%]Œtž…BСБмy-CCC}{вУ„\4ѓБLѓА1Чš0“UyKŠuvдV?:@2Ž™Iг)ЊЊЇ 2 !Д^*•уќРШfГ.CЯчѓPђ!axВЫIžВн|mmm нn“““nъћЛЩ|зAQь† “цїU*•ОяfЗBЙ\FН^ЧњњКƒWub˜:>гvЛэєєUDIЁlql%H`rrgЯžuz„cYцRХЛ0Ї†*)iд–Nј9:kAevэA#Ip%…2xR)gKИВ[иP%лЎe‡ ЉЮ€ЪJ3Рh4Иyѓ&ІІІЖЭ7#ПНђЪ+xѓЭ7БgЯžОћI]ў[Зnms4gЯž…чyxы­Зњњч‰ 2А&ф?44ф ќbБˆ ДZ-$“IŒ9ХвQЛню“№цўч ’ыић?11X,†RЉ„BЁ€T*хJn вЉb9Ј @е#-_‚hƒыZ eџt€mƒВЃЃ•{Ђэ\Ќ‘Zё K`KЇг8~ќ8&''‘Щd099щњБ -fРТѓу§'МЋmЌ6;VI&[лЕ:Lи "ŒЃkR•јІћ‘A€ЖXjрiхАAБ:Хаžчтт"nнК…щщщаНcсчW_}зЎ]У№№pп …JЅ‚щщiЛ910ŸE4CФїQюЈ–Ћh7КhT;@аA4бFЗРѓ7Й[Hд7аџ‡.|пЄ€ …BЦ>`k uah` †Я’ƒТъЅƒ˜ў•JХAЬ„Џљ“H$p№рAРуGS€…љЙО7O`bbуШч‡q№аa>|‰­оbлкEУФ€YƒШўe-s||м FЁ’_­VC*•Тў§ћq№рAФуq,..Ђнn;хСZ­ц&’фФы#п€Ц’ufЭо Б30P oeЇ+ ЯпйЌ’™iии__бь˜… 1hœ˜˜Рў§ћqрРьнЛз)ъє0*ДQЅYЖД)ёkЇRWи  0j‰iЖ&ЪРpЇN{ojЕšeвв”HвЩr*lЄЊŠњџŠ(шы:МZ­bjj wюмqAћNŽџЪ•+Иvэ.\Иаw_Лн.–––0==zНО­эR‹Dl`“?C>„ЌZђb+*Q0 ‘бЏАјаа[C:Г‚mДЭfгэD"сжƒЩH$т8F@Є@˜c ‚KKK;ђ&Ј&zщв%œјрЊA"ЏwttЃЃЃЧФФ<ˆН{ї"•JЙ2!LЖ^)ч€э‚,(\Ю{Dh\kЯZ fэњыFD’В zлBЈКЊ@ЦQQЖ?˜vЇияБђБ*tЖџlPїрСмЛwЫЫЫл:mь5ž:u ЏНіž}ійmdЩееUщ3TБ"хpН)j4(ЃЅЂЃ*•R‡ƒˆГ•кО™ЯчFŠШї2 'с•5 Мy~*гH$Яч]‰эЙ•JХѕзлуWѕWw Јтё8Юœ9ƒ .`hhЈяњKЅюпПЙЙЙ>iэA5w›`ЉVX jЫžƒШЉaA@X ]0vp•&яmД‚ОsѓmмZМŽJzэlкZ‚NЭjОE&•B.›EФ еъ ^ЉЁбЊЃДPmT03їБTc{їЂQm`unч!‰"?1‚‘бQдŠeTжKиhЌЃМVFЇеAЛбFЕМ)!N!}(‹TЮG:ч#№тCо_§ЈDРяKАѕP2ЖviЁИAВƒ !ћ5вм ŠWfэ ,€YЌƒУ4CCC}IЃшjЕŠJЅтиђзЏП‹ЏѕKјЋэЏaЯ–q(ѓv|cуу8,H{ђпћЮw№ЮлoсС§ћюѕJЅŒЏѕЫјі/Мє Мјв'њHmVŽVkœЎQ–=Щ‚Ќ§GЃQŒŽŽТѓ<'>ТЖІЁЁ!Gš"dšH$мgЉМ,Гi ѕи–2ЭZ™ё3 GAзE<G>ŸwŽ~Яž=Ў-“Y˜ъкгЙQD‰ѓД(КРю;.:Ь Zƒ7шїv?XПЭfТˆ{JДГe5;MO[FУ1mEd`ХkƒXmчx5ЬњkЕЎ_ПŽЛwяіŽa§џщtЯ=їЎ]Л†}ћіm“S^XXpZlЩу5Z.ŒvOhВі,lэœ‰EБtn<Л&ˆ№qь9ЫѓЁx‘п!йUbоCU$Т@T@GёjчЯ“–e/]К„3gЮєeєA`qqїяпwK –GГ“}ЕRМжn[лОлlˆАНЂіB}J(w Ј›ЃˆH!dEЙБƒJdЭhЋЫГЈE ЈGŠhu*@­ЏA€^Ї‡T*ƒTnЉФ&' QoЂньэ:zн.<шД;Ич&fЇ#›BiЕŒh<†дPQ/†t6ƒVЕŽfЃ…nГƒ нC^t[m$R>В“1$3]Dc@$‡яљhTZК@алJю :ьџL|ФћЧ­ ‰?т` ЬРжл&ЄЦ3l*п ŒPдhыЃЛЕѓ…AJa*ƒЪ zшјO­СђD`uuџш?љч~ GшS†#DЎŽ˜А*•Q€ЮРfQD4;'йoddФЉђЙ?~МoA4uУN8ш”шAБXDЅRqВР І4sцРЁbБшЮKY]]uй!kАžчЙRG˜ZЊd€3 b†Ч,OIEVЮV?gPІdѓ–ќgГыАV) *tђІ§ЌAЏ"dЉщАзЁЮпvр№;иТїўћя;žФ §‰D№ьГЯт7оРЩ“'Зщ P‡^хju„2;mme0ЃZ$ащЃ0‡ІZŠђ)Ч„k€h3vђžАP‡ŸYД%шRиŠA ‘љ^vЇА]puuгггЮёКПБX gЯžХЅK—мha>ЃZ­†{їюсоН{}“9m7‡O;!&DУPмAї8 EдвgЧKkMПк)с •џ СВ^ ЄрУGНWУmяŒжт`ї"Н*Š‘UTќ5t=tкMДЛ@Ћ Д›>Z­.ќ(Ь>К@ДкMд xFŒЄ/ п‹ тGаЈдбЎЗЧ‘Ш&‘Юe‘HЅP/TQ/еаmm:?ц!ѕбёZhЗ›№ќо–VbўfЖН^€jНЏAФt7яM,Йрw%ћ'А+№} ЖŒmJ™ЩjєЌPIXіbuЦеˆZ”@7ЋхXЙаAF4L`тЃ}э&[QўЬь#Lю™міоХХE<œzˆйй4MЌ­m’Ч'ЦDЫчАoп^ьпЗ{іN ўгџь?Ччїw№ЛП§лТУhуŸџњЏсЏўЕПŽ+WžA.—s”N›mBѕЉT*ЮˆІгiчtu–@ЃбpЂ6бhд)В6JхПпћНпs5кvЛ+WЎ —ЫѕнguВќ!ѓ™ ьс&AЋX,іIЇV*—m1сtDfU,u№љhннj(ЉбhД/@в1оKuŒЊfg_З§б–$ЉЊжаѕя,‘–чЉх Tv[бР@ћђmMжжfёXXXР7055Еk пииЎ]Л†O|тШхr}ѕz X[[ыуV„ЕеiЧйчнn™LЦНFДF™ъZ6sDtкŠphCA[љМљЬ)чЋЪtц\ЧlЗеŒ›ƒеd2‰X,†ххe,--ЁбhьJ˜Мtщ.^МиWЦ ‚ЫЫЫxќј1 …‚Л/J:UDKЛИ.ЁЉJќ ыууЗиЄMЙ\aП%іvЛ],ЖЇё…ъ?E#ZA2•D/ш к*ЁлюЂнiЁtА}€ЪdK'PGѕоц„ЦX&†t,‰бXэFz z№у=D“>Мx€h2‚ЎзB<G4’@Ь‹Сlжљ}?‚ЈЩT ‰T™\щ|•hх5ј`8—C/иёлЊ@аAЗнEЗнE4A$…РјhекhжZh6z drУˆЦ|РѓOсPl!~ˆ.РVАеz’Ыєmы3,ЫPЗЦШ.н€Ж>i3ЭІvƒžRv+'„edнnхJi+Hћ“ЃX(р_}§_amu… ЭVМЛВМпїБММ‚Љ]ІsшаA<§є%ьнЗgлљќШŸ§іэл_ўЅ_tNЛнТпџџќ]ќЕџш?СsЯПи7БNЅ`щи3у  ’NidfУ>x­Kл,š­LЊOŸVЋхШOэvлетuј ƒ:7Яѓ\fЩ`B u˜ШˆUIД†]3 ‚4“&WBѕиЭ ЯŸ0HГоNЪГУ[lцF„х3UEIоПАA,ъаЌWвцN’Њ­V їюнУ­[ЗАЖЖЖk пхЫ—ёъЋЏтќљѓ}ЅОnЗ‹ѕѕu,--9ОN„дЙ\O,OЕ`ЖO(оvNЈа“жмwH^њ>—­іЩЖ­ВNOGЮѓеŽ^\mЄQ<GЃбРккжззЗ9W{8pWЎ\С‰'ЖёA=z„[ЗnЙС]J^UТЏЖввОrэюXh~аш^‹аšŽ:Шљ+‘љFујFч ˆ&"H'7[К;­:экн&Ецfšѕб*b5w…:Н-Ф#C:ŸFnhэfjНv]tбДаё›шE:ш~ ‘XЩxбh‘hОчУ 6Л’Љ RЙ,в™adrУ№…žзC4тЁлы лiЃTаmДєє€˜E<™D,C4EЅSAЛдBФ‹ tP­Ldс{D“бУ[О\ƒ›cљA nнКх8p ЫЫЎу5~TУeЧЉZ&ЉЭ@ТˆG–Ц`жšjито‰ЅМ|Ѕ‹З\ки§б—О„vЋ•ЕV(iЬ"!›J†№шбcьнЛЯП№,изїйO_НŠNЗƒ_ўХ_ьsHПєCУЃиЛwoŸо:ЕШ”fжAЃJCПББ™™T*•>с Вў ЏЊаPЉTrЎfВ…BСЩ›’јЅ7’ ЉUЮl…†›•іѓkџ=ƒ эjА dкюІžŸEфJGСВ; Ь бiк/a-~"ВZч–lhГ,хLX'ЎŽлJЩ†Вth %…œТВ:ўЌ­­сƒ>РнЛwwехЯхrxѕеWёъЋЏb||МЯ1ЗZ-Ќ­­aqqБo6ыс,;iЏэ•:ЧA•ž3Г`е и- чКRыТѓ<ЇFI f№,5)Б’|JЋ\6K pHœŸŸw­Ъ–#х {4ŠsчЮсђхЫяГuЕZЭ‰!iMљ *зЭвƒ @…%`6€Дќлjmh˜ѓп‰ьЇЮŸЯуkѕпСћo žˆ#Рї=єК]t[-ДыMДы-tъdђid‡3ˆ%cˆD#№г,оЏ­.ќРG2C:•D7Р єКItКд;]xўfvёќMШ>К)щ^ааC4кC<с#Ђб.’Щ2Й‹ББё>ВыцtЊnЮЙŠЉа\$6Љa#" ›šпЉЕBІj-jck“\Gl3д`DяЋЖI‘НЭRљ :qбТыЄк5–ЏЄ4МЂАŽйЕыP;2ЌгзРRз?ЁhO"zaЩTaA­’ЊДѕSјоџ}мО}{зњs"‘РK/Н„7оxЃO]“YчккZ1Sї<PЂ(”Бе`žЕy-;ё>Љ#у:с: ’ aЖ:ЄЭНЛЩCБs"” ЪѓЄ}#ЩTK\#\чŠ№t:Ї-0(срк8pрЎ^НŠ3gЮє9ЮnЗ‹рwоСђђrс•ы@ЕьњБѕ~ лBMЌту ЕЕSтd‰АaА?БbБˆoџБLЩx4+-ФIЄ’)фї #?2‚вЪжц—сЧ€n=єрѕ?цСыН€n€ гCзяЁзо”єј=ј~^аFЃZAayНn€ˆяб­2KГƒJЙє6G'3)$sIФ“1`8x*Žh2ЏPCЛжFЏ лщ!{Цћя oу'З|z{+јСфјОŸБ†Zkі SЊaЕ—–ьiыа™5XЉЯAСх|XЙпAU~ЛнR^їюн˜Ў*oќaб€ћї ›ЩрхW^шƒџнПј—№џњ;Л/уўЦзПŠO§™vSлЗБЮre&ЁŽG3>BШ$_ Ѕгч9ЊгQE=~Ї–!ЌSTч6БM3@-7бс‡e [|+ &=­Ž-ЌОiЧѓвсщЙ’ЯЖpўNЈ™qYl; ТжSSSИ{ї.ІЇЇЮ‘`ЏПў:^|ёХОА$–...іqtА•–ъl‡Š-LGІSєєykVЖW4н‰ЁЎђl есV,{Q(Š­€tќ*LФuЮр–ћІ^ЏcqqбЩŒКП‘HчЮУ•+WАџўmЃ>|ˆЉЉ) T*i_(PКяДo_ї‹%‹ВwaСУ“”Еќiаl6БОООY6ьP=КT<d"‰NН…jЋ‚x,Šd2‡ЩН‡p№ф ЌЮЯ#‰ЂYЏЃеlНMяtД7™ѕш№с#‹Ђз а 6ыђA/@НжDуq'Fсћ=tЛ@ађаё}D<н^НvVНN/ŠMN@/@аkЂлiЁгj нЊЃYk žˆ!О5$Шѓ=TлUДъэ­ !@$E*“B<G,‡йzЦнкЕzр^ O_‹МИњею}Рї%чЦЅсе1Жкпj™Жa§г4О§ЋфЊ*лiЖe[Ђt`ŠЂA№УКˆ[­fпп//-ЃН5шЁgЦЖ†Е~4рнwЏcџН8zєO„ƒN>ƒ‡avцO$„oн|з^{гeTTcжGˆ‘ЕHŠ"iDЎ™Ћ’œTuГ3оџT4Du(’B]~Пі|s=0ˆсп+\Љ2ЅTјЃb#‰ŒЊtЦCnјзŠЎ-Ћ8hщ"эQз65ŽЈN‹ѕofЌЖ:ЌsРЪлъšж2K˜AЖСLЗлХ§ћїqџў§ОљЁF%ХГЯ>‹O~ђ“8}њєЖR kћфyX‰bэЗ-”ъ€љœЮжћHbПƒшv˜в(Л<кЩіSљaЛбГдїз€ŽС$…БШФєшQ(—DŸG:ЦгO?gŸ}ж•64ЈZ^^Цњњ:†#ыЊючА\Aйnž*–ЌjэŠЇ тJ…ЁЋƒьЈ hУjўѕzн usуДs3ШЄ3H$RH&RhG깂rљQ #=4ŽDrщLЙсrУЭОћnN Ѕѕ"JЋmt[-tmDcD‰-О‡fЙ…FЅ/№бmЖА1[ЦФ‰мц3€vЋƒf4Šng“Хя{>|/‚D:…с‰1Фг)4­Э•*bЩ$і8„x<†D*ŽNЗƒVГ /т#lVюс!!žŒУEр{к6ZѕЭЩ€ші‰‘Ј/ю#sиПЖŠюз”B‘€яKPЏзЧД§O№ ˆ’F@ }иннФ#,Ы’ wbўяDю{’Р@ЏГйъo5Z[[•7"ДmцЛAОёЏО…#Gїї'^}Пі+П"m‡ѓNєУ:PEXˆЧу*зђ 9йђt\іY~WЙNвQxŸЦ”Y$ МОЌ(‘]KvиOX?ОЮ зqЛ6…zP%Џi›‘kўџ8IРДПQJЁ*'%:їїіŒWлњѕƒЂ;;ЛИuы6юПџвј=žxђ*€џeт˜ћНоxМкxšseCŸ6‘“nxŒ1ДZ­ёп)ЅЧё8a0NfДrtAјЂ5"'ц5šЭц„ьЋ!RDˆŠЌаs˜ІщX5Žxй*fг6"Btnœ&tЩх2g •и7EПЬчЁ":†“`‹ўPъЅA[t ‚"г`з7п|яПџ>vww!іу‰'žРО№\НzѕP›noo[[[c“—4,гq nб1QлоиTЋ4и›QAЪ zДucЮ'MŽŽJъЭyЬВlœDPu>SеS’jЗлOԘcYYY™€љЇё{ь1<џќѓ8Oќ@LВ|эк5МћюЛуфt8ŽечччЧ-ЯѓЦОІЊwєбЕOy)ЖiE†fUѕгќ\ф>ћ<›ы1аяїЧвпєјЊЊТцвuшv?ˆР„„жeMТ с•P:X !J„‘@ГгFšє1ъ1ъu1шіŒFаR!Œ#„q^шУ |pЦыvМЌЅwЃFцEШѓЃэ " " ЦРццБАМYVШг•*біа™ŸG{ayQя <"сМаƒъ  G(FЪЌ@Ѓй„пˆ~xАVяУФѓ!4jbДP•ЅV'Ѓ€јc“ќЫљ/БЛЛ‹(Šš6ќho‚Жк˜й<ЈЇљQђ‘v5ф"ѓбОвДБ”iU§Н(ZšPђаь?…fЕ>(№о{з'€ХХE„a8!|’љ„М'эёк•Ж5UОйM•cцžэљy›QlH„fДЯХŽЇ•;5 2IŠЉ№LрЃCЯнь( еєїMUD!~*#K7?к2Ђ•“эma'…Ж.еIЇkмЎШmdШ&ŠвыdыђS„Фюхк ыЫ/П|H1ЎыVЋ…Я|ц3јТО€'NLќ.Яsьююb{{ћ3# мі}o#”сoѓqLТEs>LЛ‰"54№а к^ b73јK ІХe ЃnI[Дх˜eйXг`Vрo4xійgёЇўдŸkZŒ“єSž•••‰РIЕіїї'”ЉЂн šЦyВ9?гцёт<Йўдї&йяїћVš”e‰Ю5ь_М‰ ЈЧ№8SаК„fТД.!Ћ!ЄJРX.4ќаУ WЂЗН‹AЗ‡с~JWа№Xјь`–_i Юу~€ѕ†(‹ §ЛC,?И p Э4‚ИЙЫШ#HЉQI…бhˆЈеѓВA ­Цyг ўG&k „Рљѓчй­[Зк4Швъ†оМ.&3…,mxžnђvt™PиьbWЅmCdГnоуЧ7†žlБЋЛ ќ(а€^ЏwєqZ#cfSЅЮЁЦe†c>­ІэіНNt4ЫV~Єф9JьЃыЧ 6ђbW€цuŒб =пT~•і|M@“ кkЗ?ЫЖ l&ДЏ=m#žІсO Вvѕo~ОЗЗ‡~ПH&лЎк‚ РгO?Я|ц3Иtщв^/Ыџс?ќdY6іЖс… ЙЎ3ЙЗ‘Y&G4 аd’ўН=)dж/Ё№6хžЬkГe˜ЭёSЭ У™B`0`cc;;;3Ip№шЃт“Ÿќ$._ОБАtU•œ!Or”eU;ќŒ#хЈВ}єіі1ъѕ *#ф!pЦР=РCDq?№СPц%ђД@>Ь‘s4[ˆZзЈ*UhЮ я ЧPk`њOJЉЙi вмˆ”АcЊ3›K+{;+ЅcYД‚7ЋэNfo6њœ&Еъ:ŠDјGП'ŸН’S3lW№џ hРqІь>5­|ЈН)E єHЇLдМПQ4‰„ЉpM5nдhЕk^ч(‘zлвеТАћ“411 EЇlјнpЬ3ЅiP‚ ]%QˆгU§ЛкічŸ5KƒЈ§З4I–RЂлэ єБАА€gŸ}Я>ћ,цччЧЊŒЦ#|ІU`оџ…^8Аm˜п^ЏЎЖ MЌьEƒ”йьЉsŸ›Фž*к™ё<ГwPIjšxЛ.A3њgкN{{{cзПЃŠ†ŸњЉŸТЇ>ѕ),--MЮС`€ызЏуЮ;FH’dќ~Ѕ0ь}ŠZкЄI“мвфеxz˜ЯAQ"J‚uн?ЎПЃ“vрЇ?7“?д дДHЭgЪіƒMŒТ=:…цU='4$ЊВДFUшZѕЏ:ес~ЃЙЅрAˆС`„aw€о^< pіСѓuоQ–ЊЂc<ЅЁ5„ќ ї84€"Щ‘2ШJBKЮ-ыоМч1 “†н^н6рfŒFЃ, ЄйUUР *UЉ‘Ї9Вa /№„>ќ Ќї“ВB%Є;ФpoС„/D‚8‚ЌJpOyP\Cjј<ŸKVдРbџџё@677йэлЗQХœYДЖЉi ИfЂ]S6ЭйBСt2р(Впq§4)рIВЫd Ї pдC*yШ`УжѓІаЕ ьІŠВ7 КIгkhHK&  юgTEЯе\-SйкcpЖЯИXэ`NgШЉЂœЫ˜‡ ЖиоЕбл-mиВНt^нюmЛŒЋь lš…0=oІzД9t§\ИpO>љ$._О<ЁL'ЅФююю^vѕ}єQpЮqыж-Їбж4WJ0Ѕъ…ЂІŸЩѕк.=ѓУ€ЇЏG+КO\ “XloocooяH6?}ќьЯўьФ^rчЮМћюЛилл›XƒцМPAzќіš0KЩК4q ­4šШКаQQд•L+`\œ*ЧэZ•Њћкa3Р|Ї…­2Сц`%Ыр .X-ѓ …В*PUаUЭТъŠо№ќA3уŠВBšх„Q€Юв<‚аƒ№’a‚QЏ  •ЊЎчƒs .8g(ѓђ `Ћ9Š3”EV›њ0 O3ьяюУ=Dq-Ю5ƒY–Bj z/! ЯїDТFˆ№`дYI ШK іњhДbДцZѕq€БтЏ' "L)(%žтЫЩŠКыќ?љ1РЛwяЂ( vћіэO<њшЃ˜››;tгк й–ЕƒhэЭоnиІf3Єzэvр˜Ж яЕ0-aЈlиQOBh.ƒŠ™jšVЋ.ЖДщ­†a8ЎжЭЕ2§|CТЃyY–a4MT]TЫŸ&nІГјЖeДНйR$‰ŽcбпS‰YлЈˆM МKЁcZEй }кŸЖ“QЪкЇH­цiьJh\›З]qбѕќњыЏOЌЫ0 qџ§їуСФТТТXбh.ьююЂ(Š1ђ1Mюєщгрœуіэл‡итt’ФuoИ$x)ŒOQjКdǘЬЕ1S–хxо:;R€iQдСцЪPѕJѓоН^wяоХооо‘0џ<€7n8ї„wоyяОћ.ƒСЁ}ژk’*ѕџ0еГIФЭ:7ЩyЋе€БT7§,=АGБЇ)Ђк{є4с$q2?3 ŠГ”R˜_œЧввД'ёЃ єГ.*”~ Х СС ЄFYUJ> Й— ЋyVЂЌJ ћ]Дчаž_@–`Л0юƒ{˜чAR–HCIŽ2+бˆcQ/№ы^|UЁ*jЕHЯˆZЄ •Т зХікDрЁЛЛ‹ооZ ФэDШ6}d)ƒЊJС7mBx№AрЃбŠбl75ˆ›1ђ$JЕш5Ёз›Ž‘Шќn–)љ,;;;ИsчzНоL…Л0 ёьГЯт3Ÿљ ццц№OўЩ?qОюјУ rІK@ЪД LbLGOЉ"Ѕq­4ї =tвЪ–ЄvЙ–Ю‚ѕg™їачšћfšЭ2MъOŸ>“'OЂд9Fйнбi– Ш‹:ј‹крGx><Я‡т Kh]Џ­FЋ‰љ“ЫШF ЄъAъzŒ0lЕРНК=^UМЈg4S<YŽ,I!‹EQС‹|aЯї'Z•р№Ba3€f!ВЄФh8лфуƒ^щ(їщНиž‰šŸР8 „‡ ˆ„š­&šs­ƒЏ6<Я‡Я9z{ й0E•+фУ %ТИ†dQе-ЅСР}\I0”№;тОZ Ў`xјX€+WЎѕхЕЕ5|ы[пТK/Н46фO™ЮT–’Ж ІБumГлЬХF\0ѓД`э‚ѕXцЁЁšшg$ЫЈо;Т(FЃ#ŠCTU‰LѕывЈ0ŸƒŽ-вз4ЯЃŸЧˆ4Qa+sž]’н.r~зžgІyŽГN:…ѓчЯ#|уп˜xн<ЯЧBRуQKЉ *Vq0Х!˜(Д;s(Ч~Э4†’`ЋY^Г№}QBД9qЃ&ц)”–№ч+ЁЁрљ>ќЈ ŽFчаUНЯєїh4"ФэЬ`Œз ;мДšц—P”4$4S˜[\ФЩsgЁ™FYдI[Пл‡јˆ= аZь ЬkЭYЄа•{їITрCћD„“їЭ#Œ=!GžхШњy}n”ЎЕ8ƒ†’€†>г8Ы›щšJ#ƒfm№Ъ+Џљ7ЦЙщЯџљ?ŸоИqЃЙНН=СМ~ѕеWБЕЕ…O}ъScі*нМщтЃ•и42 K€Ђ 4АPЗЫьƒn<ЖIЬ Аг8Фž§Ја€’PвmЋL œІЏkУед9ЬжЇ‰uЛЃ.Žє:лОыt”Щ8…u6z)‚D b.ђ Д7oЗŽC~›–ЈкЮЎъЉи]елIK2Y)…з_пќц7СжŒ1ќѕПўзёЅ/}ij›ЪNІnšh9ИПьљr:ІGe]m„‰ЮтЛФ“ьФ„NP^•†6 ЉваUY–И}ћ6nпО}ЄZпхЫ—ёт‹/тЉЇž:ФЙqу֘ЭOЕ3Ій.›Ÿб‰ГіщоVUеx$3ŠЂ1ŠaжВэC`žoј1.)НЯmХЦY$OƒмPЧУЉІчсьйГуРo’{н2Ц077wˆрЉ”‚дS`>CдjbёФ E0@WиИЛZKї2†§twїаžkЁбŠрAьC$ЌžfЂSCщ~Pkы7ZЭи>BЃйD‘eH“i’€сро`Ќvт+%В4GUШКMP* №=ЉrUQыањрœq сљТР‡,%†н>ђ$ƒVКі№9М ?dмƒFk>@аdhД#4к ˆ~Ui”e§­=Ty‰2/ЁСсd О№œўdњ_вџцќ?Y€щ… ќнПћwё/ўХП‹‘˜пЏЌЌ`ccWЏ^Х'>ё‰CеФq˜ў.(ло­_ўбžЈУ-€ ИзЩ—‹+hаkEЙtѓЗЩZ6#œ>ЯЗЁD?[оŸ-mjУжTpЦж&0pЎнЃЖƒ­нЗІAг5j:+I ЈvOœЊSк0Йk$е|­ЎЎты_џ:ЖЗЗS ПќЫПŒGyџюп§Л™ТUГ‡Ѓžчв$pЁг*кћvЕшџ]sџE1ћŽ‘ЈІUєіі6юмЙƒэээ™l~!ž}іYМјт‹ИtщвЁбЖkзЎсњѕыcВ€ЁШжЌ}бE5kУ$ЁдзТ>^кюЂ †ЫзУNІЕF]EmCЬђ28ўќx,”оЛЛЛЮ}лVѕЌd‰LЅ`™?"‰ЈЃйŽсх@Y… Fилн­ƒЙ пэ!Žаˆ0†К' 0а`LƒТ D†ˆ;M4;-ДцкhЮЕр ‚sєїd˜д,ќQ† ~TB)]ыXЗƒ1(Љрy!ќШCQ2HUяAeQBj‰"Э •‚xˆТ8†№TQRзўž?ЦЂFс 0Ё6ŸС Т(DUTЂy’!ЯВƒщ с јQ@#\аŸв/сА# сŒљЛАR oП§Ж~с…№ЗўжпТЏџњЏхHЭS–%^yх\П~/Нє}єб йJД™жЖЁэякФ(њЗЎўўЌЊљƒЪzЮŽl|ThР˜–и=|z]lяz›„7- R~€эLf^Чєoi%iЯ›пЙ” iЫ2є +žŽ3кRЏ.Л7n#D6фjKJЂДћњЧ РŒ1 |ћлпЦЕkз@ѓzё/ўEМєвKxћэЗЇŠЙ^пўоц+иhEl(rDЫ–RvСаtтСVДс}Њэ@yfа{|uuЗnнТ`0˜yЗZ-М№Т јмч>‡VЋ5‘РюььрЦX[[ЗЅЬ{™Љ%кІšІ:­MBQHzž(‚bа Ъr!,fяЃН—щЙsЁFЌkšћm‹œ?'Ož<„Цlmmasss‚Ї@ЏБ™Z0ч/W9њzУpU<š$/‘$Œ†#ьяv1&H 8ѓ <Њ(бh‡BŒi@$FJz…,QfЪЌ@Т$IŠQ„,ЩPцХ‹_‰­•lомТЮvVG˜[ЊPI‰F3„Еb`РЫ+Y‰ИcnЙƒ,O&!8ушююжЩУ^ fKЫKhД›ˆтТ ƒˆт­q ? ј€,JфiЮХ‘И8иsu}-CЉ0иС‹‹/ŠћŸdЊmO€CЃ€kpАuY–ўїПџ}|ђ“ŸФЏќЪЏр_§Ћх”%эvЛј/џхПр•W^СЇ>ѕ)\О|йЩкwmd.y_зм)ݘЇ1^я5€%dџь0ЃZЯl|4р^кПД`УГємКFэsс  ./ЪH7ьpЊlfлJЛІ=hЅCз’-И3m-йЊYнЎpІ]|•i k—PS’$јб~„Зп~{І–§ЯџќЯуч~ючp§њutЛн™3§ЎV…љМдZyoФeCЏ/эПлU*MвmtЯеzs!uєИжУлoПлЗo[Dг‚йХ‹ёт‹/тйgŸ(’RтЮ;xчwа;АЮ6BU.uG:Ы?Mшˆю6зЦ%zdы?PєШжGАЧIщ9u]/ћ˜ŒЬїQ'Nрќљѓ‡`ќ<ЯБЙЙ‰Cы–ўkП”E•Ѓ”†Њ‹ПƒЌйƒjeа•Ю0ю#ІHFЪЂ‚’ šUPJBp†8n n5Ч1‚АцPhT•DYд9чЕTpеЏTE‰В(r$НызЖАњовЁB1ТXЁ‘№МZл?h„…яAŽt0Фт™yp)РД@’fHз6P–9ђ$G‘sџ1кsmDЭќF„ЊЌаШ x_[7"xa€ FFy…,ЩpшЃЃ…„/z Œsx H9„Я/ўљрџtїпчП†Ic …ŸЄщэ…išт•W^СѓЯ?јџ!ўѕПўзИvэкЁVVVpыж-œж`iiI/,,0  6МјсˆgŸ}яя§=ќЇџєŸ№ћПџћ‡*.€666№џуФзОі5ќдO§ž{юЙCН|WE@%Vщ eГЙЌEэПћАџqŸ?ѕaб€уVџгЊСЃЦЇUdЎ/—–О§^ГцФэknїјi`ЁI€ЋOm„Rь*ЮЅHG'\‚MtГ=JdŠ’ЇЉ/к#ЎјсˆеееCm{ГНpс~ѕW'OžФъъ*VWW ѕгcqMC\Šq6ЪfйIж4D[|ЪNмЭ~qћіэ ˜пuЬqуSŸњ>џљЯcnnnт3юььр§їпЧЦЦЦ89ЁЩ m1QЋlГ>LЕэћƒ&”jn“дв=‹Ž=кc—ЎvЫДѓjL‘Ž ќAрмЙsИяОћ{&џh4:TШЙж)uш,Ъ{rCеE† ћиР@я`Tє P•˜†– qЋ…жм"šЭц;ШѓЩ ?H$*Ь--рфЙћЎAŽЊ”шяїсћ>s‚0D{Бƒ*ЯP–ВМ‚ЎTЭЊз€’„ЯаZŽpђО9ј‘€яYš#эч€Ўc)c ` ;k;(Ъ†ƒНН QK#žc˜—qа@†h-Ц`œAŠМ’ZЈŠEV &ЕŠaYA–муЕєБЧ” %˜рР11eшm ЯХˆч&‚иƒ7№иры8l ќ“с\Кt oНѕж> 4р^Žп•8и„ћ&ЗешŽ2YЁJxдСМПQЉГ•яЦD!вЛЇ*t6Sœђш{аФР<зEpЂœлvкљЃ–Тєœб$ХeФbЗM„шїћјўїПЏ|х+ипп?„,Иd€?џљЯу/ќ…ПЯѓ№о{яMTctdѓЈi†ЃІ\ˆ™Миф?Гщг6%cКќц]kžгКsчnнК5dtнгз<{і,>їЙЯсŸјФXZзМїккоџ}ЌЏЏ‰ьvНFFЄЬМŽAЄlrч4RЅ­ŽIљ4љЃ‰€=]cHzє>ЄЦ\гl{MпыДНЎйlтТ… 8}њє!џ€нннёќОkЯv9YRЃ,K$йЛr ћz ЙЪ1R=$хƒa…BZC *$= ПUтФy(j№ƒZІ(Š Z*ЯU­5РТ0‚ ПТpП‡|tРТЕ'€№<п 4Zѓ>‚X jEˆXoˆЊTЈЪeЗ@‘е#yZВаh6"@аˆ;>„чcаэc~qЮ<ђ$УЈ;‚д Z+ˆа‡ј@Xsš Ырya#BGЂAжvФRaдaИ3€,HК9‚/Ц4Рќа‡п,?Hqp8>ж нnCJйІ•ЖR išтеW_ХC=4жјэпўmќЮяќЮФ‚І7c I’р•W^СЋЏОŠљљy<ћьГxюЙч0??ЈЁ"!Ж н{tUГЎЭч8§§šиjqp/€] КІ)lRх4уЅYэТтВЕЋ-— ­žhKЧ&Rј™VŸ6\?Эqв•ЄЅšцšdqЙхЙZOџќŸџѓCfXгЌЈyфќЕПізpњєi$I‚Зп~{ьa@ŸчJŽ"кзј8kлuiл‡&B.;ШЛј#§~ЗnнТњњњ‘ЃlWЏ^Хч>їЙ1Йиќ­М~§њФјœљЌf/ВЧ@ЉБmй"d.(м&чйB=Ў кqЁZЎVŽ iKгY–ЭД„jсž‹/byyyт}ЪВїї)‰г…"й$Z[еВ( tг}lЩUьВu(!QШ …Š Ш ŽВ6Є(QА sK%Дђр‡‚i…ВШкsU­˜д,|дкqУВЌ uн№‚ @а6ТКкцЊfф{~р!ˆY€ &)ђДnK@k0ЮQЄ ЭљтvBФэЪњшX~˜ТЉ6ёЯdіTыоЅmWЎ?.! =eЪсЃBŽJN\&36Ь:+абЪмhЇUqЎрKS­иcœt-„ZоfCЇ•ЛщћлšЖѓž‹e%WЫhкЈ›}mŸ Z+ЅАББ1 іє„­АHœ……ќТ/ќžyц(ЅАЙЙ‰лЗoтиэ‡YzV`9J§в&…К‚‚=§0!экoЗйъkkkИuыКнЎѓиЭёDQ„ŸњЉŸТK/Н„ХХХ‰dl0`eekkkF0v=Є•85œЂуЎіt‚AL’eўЦД‰г8#vлХN–M0Ж[ іп˜з1Ž|ГZzFИчтХ‹hЗлŸ?Mгqрw‰ M['6A‘~_њХ>†К‡D Р…€h tц#, ”…Džр\ƒ ОчСѓ9NœYFgБF3Fіš˜шюь"MS$ƒс˜…Ч1––Е›ˆтaаЋYјa€Ј!j7а8№хЌž*ШВМRUYœAј|Љ …у` љHВ„sјž†і9 CШLcИзC™`Z#jFhtbh]ЂRŠ,EžeТёbŒжТ<цц‘є іі2$НqЋ‰жBE’AРC{)gѓhДc„Б|”е> eMŽl\Р“ƒЗА)škp џ8oпL4ЛпййС`0РХ‹qўќyќПѓwpэк5ќчџќŸёњыЏ;Yу6Єэк5мО}П§лПѓчЯуЁ‡Т#<‚ХХEg/qVЅoWGўYЬш{ЩІ% ј c€.‚е4ћДчЙШlGщ6˜б ЛчnOPр4;\Ляl'86YrЉlкЄЧ4ЎƒЋїKЯs–eX]]ХэлЗБЕЕ5F:\IŽЈ9ч˜ŸŸЧПјE|ц3ŸчyшѕzИ}ћіXчпх‹aZГzу.Јњ8–ы3вщ—nEЋ\–ДєљEQŒЯзQІ<'OžФч?џy<їмscвЃйk666АВВ‚ННН‰1a;јвq>ЛoOЕ+(‰еДœ *0M=‘rœ\э[зРЅœhЗ\h+ХГqф;ЪЫРѓ<œ;w—.] ї˜їэїћиии@ПпwюЁv‚чкЋmУ,ѓ}QиJз0”=”К@Dˆ;!ZѓЬ-, ЌВ$ƒV`BpxGk!Fpј>‡zuхЎ’a‚$MPdym›CЭVŒVЇЈ#hDcymЫлlдb=A? рGa=ŽhXјКžљзZƒГн­Ёƒ№<€+ ws„…€рТHL€УC•) їzХaфЃ=пB2 ы ѓ ВHсЕ"ДцšшЬЕбžŸG6,0ъ%иЛЛ‡нЕ}Дчкш,eрМж5Бмї˜Ў ЄDUxh жаOpйЧžШ‘.ИВBлцїіэлиллУ<€GyџрќЌЌЌрЗ~ыЗ№Эo~гЩЪЗџЬСњњ:^~љe,..тЪ•+ИџўћqўќљCАБ§ZгdVguWђPG…љQЁї:ЮшкЌІ§ЮжjЗћй.УкgЇjnцyFХі№ фЪ9' ЮЄj!lж™щѕлГчЖлЁЋ?TлФ%d'нnwюмСкккxŽœВрэsKЧ tюм9|ё‹_ФsЯ= ж†џ§їЧЭе2 _.…ЭipБ+‘;J-nZ+Щ^Я.љYWb2 pыж­‰ѓ5 СzьБЧ№ЙЯ}O>љф!ДeuuwюмЯъS= ГЈзƒ ŒЙ1эŠNйше™А;щЄІUЎbУМ†Й(o€rJьѓ/ЅD’$‡ћE.]К„sчЮMШBk­БГГƒѕѕѕБg„€иI‹mзn'аvвc€нd•ЬЁ•г ž/аlF˜[nCI Я5: UхЊ@‘БГ™A+@J…юі{›_#ˆFГ…fkЭИŸ 4тZjфIZЫъА№гЄ@šdаRBV йО@-г{РТP•U^i@žH‡gаZaД—"p@1„мGЁ ШВЈ{ц)_CЉщpАЂбn бnLдС?Сpw€aw€d0Džфшэ |Ю/PрBA+   фЌщт> №?џ‰"§~ZыyђЄl{ЪиЯВ яНїЖЗЗqўќy\МxПњЋПŠПђWў ~ыЗ~ _љЪW&Цolhо^œ†pјня~žчQ†‹/тТ… GЮ5ЯкœŽS нKлРхFјQ Чy_—-н k|dП­юl6П-щL> d”Пa›ЫPђ“]%ЛЌim‹й{Iъь„С%яK_Џпяcmm ЋЋЋX__G’$‡аКyл,}нGy?ћГ?‹Ч|,МЖЖ6nLгХА“J sЕdf%9GM•PЛMšДб —9 %ЭmllрцЭ›иннyя…aˆчŸ/Ој"–——'жйh4ТЭ›7БЖЖ60аЊž^3š0ИЦVЭН@GI)?ХF>Lv9в`ш"ьQ1$›Pk#pцѓP˜ж§йщtpщв%œ>}z|}Ь{эьь`ssyžJ€щ}cпtЊ…&”УCб“lŒю /Sh]BЋАŽVLCC‚ яРњšЃdTЁQ вQ‰,Щ‘2tЗRьmЅbИУАА| Ўь›qœе,ќ<ЋЦ,|h@VŠ,G6L‘ SHYB•5у^ј5Ÿ{Јъ~=ДF‘Hћ)ќаМж*D ЌуЃбвЄBЅ+ˆ€CЕфЏдЩa–ˆZ!Ђf / ЁД@вЯбMrьot1и $(ђЊЪ d\0x‡rјЄ„” qЛ(ŽСЏU}\žV§ь РС˜ЇА§Дъ„Ž~Пwп}NgЮœСЩ“'ё7ўЦпР/ўт/т;пљОњеЏтэЗп>”ифzs)ЅpчЮЌЌЌр{пћ.\И0o17ФЌБ™rРќ?’—„>4ЫћQЁЧMь›}Єi“ИЈЈ‡=7Эh†*б?ѕЊЇjgtікlD”mрN*8уЊ№]§mаžnp­Š&0Ц0БЛЛ‹ѕѕulll зыYсєИшш–Эь6<)%:>ѕЉOс…^РйГgЧяqчЮ iU›Єiіш=6‹рJ]“гЊ›}nѓl2ЇMеZуцЭ›И~§:’$™yя---сЅ—^Т'?љIDQ4q|[[[ИsчЮXРіГ U9эщSщiлђй\кЦДхФщњœжJЁ’&#є:˜зА8s 6‘s8"ЫВCчд>w'NœРЅK—АММ<ёкY–amm ЛЛЛ‡Zgv{Я&jšdhš“б" ,KьgлPВжз—y‰dˆrXboeRВR"~Ф!Bр`п; ъi4ч8РБ@ЃщAјњН>цч1ЗМ€<Щ0мBJЅМШ;Аў8g,| .GдЈХy‚(„чзjŽВ’шяє1иэCJ<ЉР…‡Рcˆлвa ІKy?с#Š=јбqaЃV{Qc‚ЁЫœ5E (GРpo{wи]щЃЊ(•AVќ€A1%Є‰Ј @J€3 @јЂvyZжIB_ФЄрФ(рЧš,†ІkcЂ ‡іh"0qѓцMlnnтєщгX^^ЦK/Н„ЯўѓиккТзОі5|эk_CПп?ФдЕEhьЃ,KмКu ЋЋЋуjёЬ™38}њ4N:…“'OŽUЎfЭШкPф‡iИ€‹љО–рШЌЙ|ZХ™Ÿг:{Žн%•kЛ2RЈд$6YЬ–і<Q{М”@GзньЭFoЭЊ|ЇЫ4MБООŽ­­-ььь`{{{ТŸнхЂhГК] yЮ9ž}іY<џќѓcё+ƒd­­­ЁзыMT„.[рiыЪžЃ?n‚ы’}ž…˜Йњ§Г”Э=ОКК:г”Gk‡~/Ој"Ў^Н:qўЪВsЈ/=6[•ŽŽЂк  M^ЃнnИию.RЉн:Г‘лЪUŒаc1§§YэIЮ9Ю;‡‹/ЂйlNМџp8ФнЛwБНН=СБнЇЩxO#к‰ОIœьЖLUUHЪQ”ƒ*$в^‚a>@‘KhЅЁ56|Ф^A4BqˆАд B)рy ­Ž@иŒ5#фI]еЫ–„рЊPШ‡94Ћ5§сз,|ЯА№Ѓš…5"4ZќШŠkЖ=у UЎєRp&jU0Юб^hд(в~?фht|№ FЇИйF3ю jЗр‡1ќ  Яo‚ЁU†ьанъbѓж66oю lŽW“ї5ƒŒ{чр\@kЈƒGІр‡!‚ЈірœC œjœгэtUV№Џз­}бОџ§яџи€_џѕ_Чпўл{С•EКњFviО/ŠbмлŸŸŸЧђђ2N:…Пќ—џ2ўъ_§Ћx§ѕзёня~?јСЦЩРД>ў,єіі6ііі№о{яЋбSЇNayy‹‹‹у„р8HРНN ИџGм+ *ЗлX ёк•хЕНьуЅU8ЃЂœгч7Џgќl]›hF_лTнДђЖЏ‰+aq%Ёнn§~Н^o<ћLIQt“ДG)a“ЭyBрбGХеЋWёдSOЃ=ПЕЕ…бhфLBm}зFM.iкЃѓ>гžkЯ­гJŸžwŠ !АЕЕ…їп›››3“пїёмsЯсХ_Ф™3g&о'ЯsмКu +++уж -Й<œHЧ]†CІH DQ3% „ля?"ЇRиЖ† њ.4dк(iY–H’фPhŸЗ pџ§їуђхЫ‡LКzНжззЧkиЅ›@Щlށал…ˆЖиIE“`р `Zзczโф ТЏ KdЋBšЅрž?єkБ№|дcuЪѓРрqŽ*UюєPd˜ЂиА№+”В@‘зц:~`n!Fk~Х9$ƒУ§!FНУюQм@мl"`šЃб Б ›Оh`ўь2ќ ‡Q/У`7ЏЧѓBР 8Бб™CЃнD†`ˆš,Ÿ9ƒa?Сц=єvіАПЕU•X8бИ Qd yЊаœїаœа^lЃЕаcZE’!K2Q%585В ­GиЅtЕиЕƒџЧо8X<›рfЗ lэ TUіііаыѕE–––АДД„Їžz O?§4cxяНї№кkЏсwїwŒYdЅiVЇfќХdќц_пї1??ееUЬЭЭ‰58*)ИW4рйŠ31rщБOЋЬ\•ЪЌd‹V_Ц5і ]Œ|Jжr%-vйцИк#4С уЕеэvбыѕАЕЕuHwРжАЏƒН9к~RJ4›M\НzЯ=ї}єбёц^vvvАЛЛ;VГsћњuэ52 ˜V­о‹ §Z&˜˜JлЬнeЪ3??Я|ц3иииc пјЦ7РУ_њK ЛЛЛc˜п†ЪiOоuўьБDжv9ʘяцyt‚У6№™ЦА[\6yд>г*3ФОiЩ}ГйФ<0VьЃ}kk wяоOQLØЖЙ:.Э ћЅ‰зДжЎ­љPUЋ 8SЕУДчžpС x­‡Ы8‡NdъЁPЉ,СEAC lyL"є5 Иц™ТPѕŽпА№›H†CdщpЬТ[!šsMt ПФЈ;ТюкvзЛhЖc4;s$ЊВ€р@ЃэзНЙF<з@Ѓ!А‰.’~-Ч7@шћa\ЯѕkY8­љ†нН­і6КипмCs.@{!‚” eЁСXTGqŒљхЯ.`сд4ъЩ„СоƒнЪ\"ц•ї<4–ФE јЖР?‰ IgRgq\а•іЅ 6Ы2lll`ggэvѓѓѓшt:xјс‡ёшЃтлпўіXAЭоцї<Я=ї>џљЯуќљѓЮФмќџТ… PJсѕз_ŸIжuйVгНЧ5šlюк>Вз.эћлМг2p L™cuЉZк L’$ШѓќШVт}їн‡xѓѓѓз*IмН{[[[Ю‡N ик4Џћo\м%—ЮЧ4ыьНj‚№д‡я x€№—№|пѓЦ1тvхeЬ8…юF;>Gž бп–(“ eЅEЭŽ(j€‡Ђц6щ ^Шр>МРƒz€жШгa3@#Žс…4F§eRА№‡Ш†)ŠЌ€Ќ2(Ѕ!8ƒ№ИWЗЄдѕј`’Ё5п†’Ћа˜‹бZъ€ Ё ­kЦ~UTЈђE–@ымг>ƒ8зЕDqУCX8=‡ЅГ'Я5бhЧаšЁЪ€tPbд/1ьцHњ9†ћв~†цзЃнnуЅ—^Тч>їЙ‰ ІЕЦюю.Ў]Лvш9чЮƒжЏПўњФɘ&Kљ*іZt)Ÿ&a}Ђ&@цs›Jzз˜+m/к–йyž;Ѕащѓ|пЧХ‹ёрƒ"іѕz=мН{{{{‡Ц-эѕLї[еХAАQ ;AЅc€tк$oѓ§z~UЎ!т“Еš_#$н>TІQTLPyЊфЈr‰сўЩ Ю Дx>Œ*%Š$ч!ˆ‚pЎfѕ7hЗчХsbUр­&ТhХHcИзХўнvV{ЈЊДfс—МРмыаЩS ШътWРpgˆе7яТ‹8šэ6ќFПЩ ВВAЭx ы{<`ž~Ь/D›тV„ЈUK ЯXРм‰ШRbиO1и П› OJф™D‘$Ш3 Ц8‚8ЈM‡*ЕЕѕефяT‰ЊH№з?б@)еВaxЛŠwADЎMжЮLэўАыuэŠЉпя# C4 <њшЃxьБЧЦsїю]мН{иммDЗл§H‚Л›Ё+”‡~nœЗЮ;‡Я|КОБіїЛиппЧюо>в4У(IаячХ‘hРНŽ0šЫРšАЋ1“˜^Ѓ WU…сp86ЁаМR ЏОњ*т8Ц{яН7ў}ПпПЎQШsё\…Ћ;ЫбХИЖƒ,…ќщ:›ŸŸЧхЫ—qџ§ї7у………ёп–e‰С`€ээmььь`ooo гБJ;љЅF/vХjo ЧЌВзKthж9ЎАб№xџ§їqуЦ#ечюПџўБZŸ­уБББызЏcп ЁЯ"=Кј6OdVЫЯ^3Дdа'[PЩМЇYчQ3їЫ˜ WбчЮвFнUY ЬsD-ЈГˆСоl{Ц4вa/ф›>„пЊYј­6тИИе„яЧ№ќš…ЯCЫЃніwКиКЙƒЭ›;@<чеpПb№МZнŒCƒ P•9wхN…MБ…љ3sX8;ЦdЅk=@Швžяћ^MŒ<„Б0їЁб‚љˆš!тNЃžrˆ4ц[№тйЮ§§!ЖWїАГК‡ЊаPUэ+РYэђ+|ЅT9|Џќ?їп)vIѕџ“G4fѕўg™L ў.ˆл&ЂLлрЬЦ"„@Чh4h4jћFxЭт/Šbœ ьяяЃпя;)pщ“гЧŸў3?ƒ7_зUŽ]Ё///ayy ЭnЕ MДZэ{К87oоDЗлEЛнFЃбГџЮОщšЙ}cJ{–†ХOgоЭfiШK”ХУoџіoOlцяiвoПчэ#iєаiД7CˆPBыe^‚ёЭљi_"йWр‡і’§yоCМЂЕaљТI,Ÿ?‰Xyч6њ; л9€žЏс QьCˆэ&ќ0чqГgЯ`иKАu}Н}ьoэAЪ '#€Љ?bс' ёœ@ЃуеRТaˆВTЈВй(‡ъ3hЭє2ˆ†y№УžЧб>бF0_ЗтЕЌ Y=Жч…ЭЙ&ќF€xЉUе6СЊЊ ЪњўvGHG9z[}Є§†н!{фЃф@Ж@рР•ЕMАBБЅџ/[П @|ЉƒЏ‰Dр'AŒ ўг<Ш]„$Л/ibЬЊњьЭ?IЄi:оL"`|AрТ… ИpсТФkŒF# ƒqŸйМŽБЦœжЇЕсЯŸњєЇ№Ф“OрњЕыИ}ыƒС>ЯBˆ{ўvUрВduѕњmu2{гtqІ—uЈKZwVšЦ—8юЃйlŽ“sLџш§#<§єг‡TйЬКщїћcЎAЏзC’$у$ШЃчв&šЏЂ( Е›вP#+Zqв*Э&ЪК‚}.}пwVшЧеCАџєŸўг™žЭf/НєО№…/ гщLМvПпЧЪЪ 666AШ%™umЇѕаэЂР†РщZЕ•mў‰ЋMхJь(‰’@эЧ›oО‰Зоzkœ ЮjЋ4›M,..bwwwЬ}0šыыыRŽЕ0l зоiї§эЩ![І{љ“Ў]!жNЦэѓЕ^Gˆт~(™ЁвЊbа№#]xаmІР9’^НЭ!МРCp_„ХГ'pщъƒ№Eš@–ЛюT€d`К+SО@G`†…ˆчльЇшnѕБПY'q+@g1‚T%Š\ƒiЮ‚Јж\„xЎ‰ ЁH Є^Ž2“h4Z`аВB™•Ш‡9d0OЁб р Ѕ*)ЁЄ„’ Š10Сj ‚ С’СƒНВ4G6Ь dMЯ“y’ЃЪ‹ZДH`ДbЈ4(ШўэЭџZў€jJ№'?  ˜ЦіŸV…И€ЃPл_`T9kьЯєрЬмЕёЇ7БФ[­Z­–3іћ§ 2эљК­vO=ѓ4žzцi Ь7vЖwаяїQU%КћныХБ7 Ъ:З7@[-ЯfSщ^лAЭќп5veЯPЛДшgIжкНЋЏ”Т}їн‡SЇNсєщг8sц ЮŸ?3gЮ нnуW~хWАЙЙ9^o/^ч§~L"мппЧўў>’$Vƒ˜ВХi%eЮ­ЈhKРД> :e[Ž˜ўмХоЖћ|yžчLfщeаћуИ .р _ј>љЩOŽ!ksœЦбЏпящ}л\”i#zv€ЃСоnйC40Й8*v Р %АџЕЕЈЋ%НgОѓя8ЭќџвЅKИ|љ2ОўѕЏc4сіэл€|pь`hЮ“A%(зХ HyžO?U<Д'lЩ|O[ ЖР•эŸ`ŸWыJ]`зПЊ(‘$Ъ‘P!є‚РР  љ“ЇqщъyT…DžцˆV<€Uш,4бlЖ18 БxђєеQЃ‰( аœа9еD№BAрƒљ J( …,"Œ ЋОЯ з@U5 пц–›уЭХq'у”вPU‰2UhˆЇ>YIфЃ ^Фсљ J–it˜#І№Bю3dЃњћ<-‘х9ТVŒЦ\|S’~‚Є;B‘а•‚V€fžчƒХŒ Qˆ<+PdŠЄD™K0ЉЏэџžњŸњЩ•# P?БРЯќЬЯœZZZ:eцфЇѕѓ\Œ\›-~`ЋXег<Й‰*nб›лм|4и™Э~nnn<…`њ{išbkkУaПжЖžђhw:hw:xшс‡'~ояѕ0АЛГu@іЉ €юо|—хФˆдН&цѓ˜ › №Иl†)JeJSИBљ. bW Х5-2эšЖлm,--aaasss8{іьXеёОћю;ДЦшX˜9vъ ЕЦwОѓБК}•ёЕ7sЋzš •yО!3№ЉнП5gж’Ё§c SлМR AL ^г8єgнn7oоФнЛwgо[Œ1|тŸРПјE\Йreтz•e‰ЛwятцЭ›cщZ0lэ;Pлзлѓœ–0КZ>гi|J Є’РЖВ%­Š Qжї§Ch€]ŒјО|>њ(ЦФЈрxшїбnЗ'жE)ь@KБшўdWђЖЎm1Pп Ђ5|щК&уЯСЗ!ЪB–ШГ ЋР˜ЕBŸ>„/а:йЦщGO!ць Ї в~ŒfЛ?№kЗНэJЅy”I -K„­š -00@œ{€Ў}ЊJЂ,jОвИЏъqCУТзТѓ6|Ьш`юФМ(ER HrфI‰2­pюО3X87"Щ0ъq@I@KTe‰2-Q 3ЄУр7|ЄЃНэ>FƒЩ C<Ѓ™uр{И№ R$нZф‰yBГКрчѓ<€1pСЁЄ‚,Ъ:A(еhјšўGrˆсAPZ-§kќ™?ѓg>зh4~GXbГdAщыbŽк €KЋњ(\WХшЎ9 b6}m*ЧIo4њjти"„№бээЃ,sСё/EgnЙ9œ9{і#ПNœOsќгЊЇYU6u,ЃoУ†.№i"MBˆq№ŽуЫЫЫУgЯžEЧ8uъšЭ&Nžт8Ц‹/ОˆŸљ™ŸСвввDђ7qћіэ у"гтАѓyiyкНщš›wMИМ\§v—ЈQЕлTЖ‡ƒAfДжHгƒСрp@[­жи­”JёКHЏїнw”RxћэЗ'ˆИє=шz2$Fј‡Ж(zс‰В]5)ЂDЇ lO:й`s1ЬЃЂЌЩ$ ]€{>Т–€ pЯCsЁƒЮтš -”E‚с^Л+;ШF)­˜`Шћ9VоИ›?МƒFлCдіС= йiC„0h0Ё!% KhАš…/8xРы1=ЎрG ёb„0аh…ˆš!Тfˆж|qЛ…4I1ъ%шя 0мO'9чцЗ"Ÿе-€ЂЈэxK YUЈЪ щ0AoЫC№"ƒН!њ;}фi"ЏPІz[(]‹ qсСЂvŒxЎ.< EZ Or”Јr‰ЊЌн зЊXСџ˜пТmХ руoќьЯўьџБбhќ_9чl–ЭQŠQГzL.ЦѓЌР4FЗ Г7˜іwІz ^$ cˆ“{х іv{SˆуN?‰Чтђ)xž?h•iУɘђіцg~g”iЅНММ<і7ј™3gЦЧsђфI4 РљѓчDЪYЈ!)цyŽ<Я‘$ ’$Сh4Тp8œкvЁ:эaNC'h`АIh&Аƒ“§^д€ЦЈHвQ0ГЁRGD—I %йД§ЯѓАККŠ……… a ZYпЙswяоEQSƒ>œ={_ќтёТ /ŒMyЬcsssL0ЅIхQ-[jvgš Э4Ž„mШcыИ&šШи­—nЩh4›@йзюU‹‹‹xьБЧpсТ…Cъ•+++XYY9ДоьбNt ‚D Г>Э8ЉYї4алчХž€ їЖ]н›Яm л9”NВŒЯ'кXB‰ MжС~"—CxЭ:<)0pцУ cTy…§э]ьннУц­эњоє|ШМBVІшnбн Йи@чd sЇц0КЦ=ШRAžЧЁU=ї/|LppŸУ‹|Б(їб„ˆ}Dq€ИСпCаŒР|e.€šˆЧЧќ…ЄЌPŒr$У i7ЊJ(­РxН.‹LbИ?‚—фРh„с^YI(­gŠМ&>–…Dм‰ЯЗkФ 5Œ1@kY)TЅ‚’ Jj”њџ>ќў€œ$%I( №ёЕўьŸ§ГПбjЕўЂ‹: –ŸЦVЕ!ЏiуPцїЎРY­pЏˆР4тЭЬЉ„pУ§~Л;ћШѓ›ЭfŒљ…9,,ЬџxЧ2т&ž|ъИpс–––АММŒЅЅЅqћЂйlŽ1Эъ]T1ЭеТЁЩХД1ДYdIЅд˜0U–х˜%n*wу}nњђЧс•Ь’}ЕЋ$ƒђи­ž(ЙЯV7ЄэъQUе8›sdГЎM[ЦХДže6у22ЏБППЂ(ЦШIšІX]]ХЮЮЮL‡@xт‰'№ЇџєŸЫoгž№ЪЪ VWWЧзƒЖЭЬT—ГMЁЬyq­š P$„ЖNh0sy?ИЦ)КaCжі8 WU5і‹pYLгї8wюЎ\Й‚'NLл,ЫpѓцMмО}{Њс%ЂR”‡Š™qAЪK1мV№ЄŸЯжЁАяuњО Гmmё0зН‹”Ї1,"@ˆс*ЊбаЊRagиХюQm Ь* vsєЗвZ[ПщС|Q)‚VЅс~ ц{`‡№8И`h/ЕЮwъы&+HІ ˜‚ Дц›bЭЅ&”TЈ*Y–ЅDžduGѕjЦ§Ј7Фh?A:JP•%šˆАgƒи‡yHzFлCp"ЦrŒЦbї<0ЎPі 0­ %P’юВ’5РtЅP–dQAЋšPюупяў~ѕ$ј›Џj ќ?жјБ&?џѓ?џ•fГљгtѓЕ-HЇѕom5Бi›­j;ЎЭ"N єw.Л’и*aЦдЦОС<ЯУh4Тh4ТњњnмИ}Рюѕбj5СCЇг†ч{hЗ[аZcaa~цy€С †ЛЅЌ 5аыі0J<єШ“XXЌƒ}Eу/ШiEo\z3O›‘6ˆ‡љ2іЅfг0}E”ЈjЂ™‡6“voгE&6)2ЫnкVqГз§мJЉ1„њХ›€| вEzЅ6ЧІТ7›5Е 6•ŸlPћхit}QBša›sМОО>VгЄСк~„aˆ^x_ќтqп}їMœ#CVлииЏ‘ YпвqPjЦCПMЛЏш§d KЙ|1\=~—г!MžьЕG‹Ђ(аыѕ0%[ЖАе<€Ч|Ќi^o0ŒMЮІY л-Г^lО‡Эг™ІйoяvТk>ЇAьѓHїъътŸŒл‹\Рч!š‚! BpхcPІŒ*фШЏ„Ъ ”C­%РJd‰F2ЂК:ЈВббlХ5ф~@ŒK9зр\Ёб !„ЙЧ$T%ЁdХъЯФТVЦ8Р€Qo„сюI?E:H v‰|”#OŠкЈЈаКrP ˜rС}Ž")‘ѕ ј‘cšœ#ъDШ‡ŠД„,+ШJЂHKTyЎР8ѓ <šеŽƒЅD6ЬPd˜`рŒC3VBъЌШЊЂ*J]іеkлџ-ћџœ$еQеџјљŸџљџмщt~šV‡Г7Gђ ˜5 0KшcV№A*ўY9ДЏЎЕУпЖќnˆЂišŽѕП‹Ђ@П_Ћо­ЏoŽЋLл4Чмќ”ДCпŸ Њ!pџ§їЃгщLˆж’[žчу„ бhLэ]И A0і0UК @4YБ+ЏYкѓг6вpдˆЃ=bHЋ}Ъ}pY!ЛЊS ё›йz›nоЧTМ4xOoЂ<“HйНqšиш‹‹ЃAб3sЌц9Y–™уЎkДДД„ŸўщŸЦg>ѓЬЭЭMœЃээmмН{ЛЛЛзeРdW‰&2Ÿ…BЪДКŸvOЋ<эћбж  •Б=рЊ~)ŠaD77711ущW†Иrх Ў\Й2>ПцЕЖЗЗБККZ“yIвC?ЃщнЛ ОhRH+n›ЈH?Џ-0eЏ{КЏšћ–ЂVДЕdЏ;[Тк%ЗlЮгxп>^kbXњ:эg’E•Ч5‡з№ќ"ˆа”РœМАжєїЂ~шЃЙаBsБ…Ќ_`дM <пgy‰Ќ(dЃТG:ЪRфY‰<Ы4ˆ:ЭZ G0Є§Ѓ§!ŠQU@э•8ї<пƒЪРЄв*c‘№8‹кТ†<№Рƒ‡рТ‡№$8g(*…"-ы*О’PКvѓU„'р˜`аОBUJАъР;†КBПЪѕ†,Ћž.иэѕџя№_ЋR'2ќ?KрЧЧјЙŸћЙџaaaсПЗћєЧ™%vёi€­ў7­Ч7ы}\яiЃГP€у&vŸмЎЊЬЭ`wЂ(BГйDšІ(Šbм ІB:ІЊІpЇ9ЯfŽмў<ДњcŒM“ЬŒvГйУ†tCГ‘ЎЇЊhДvнќGщдЛ,FяeЭиkУ%jcOие2%х™ke‚Л јє:›ѓoЮэЇла)Ђ†&Щ&РгБIZЕб1AзЬПЭАЩ]цѓг‘<:озщtЦе,PЋѕН№Т xц™gЦQц3ХLSRШйцD˜JпГэщрBёŽ"ђК\]<ƒiЯЦEАЁqdGЃКню„FПЋЧ?77‡Ч<№Р!ЇѕѕuмН{I’8?3M:Іљ5иФO;x$С$™&бr%B4йЂВд.]ЪYqнлєX\dkГ-..Ž‘О ˆдЪћыkыњжž_Й‚і}ЯѓBљ­К'o"ч№jфЭ=ДOЮЁszЩnЦUJЈЊBU–ѕЌў0GвK4k~6Jалюa4H‘ R4:MД–2OТCвM0ъŽP•­М‚КRgЈКjЇьaEљšAш9юы%ецc<ЁЏ€yU^ЁЬKy*/Pf9ЄвааPRJЉ4˜`œ ЮИрZЪЌ€*UБ•–ЋTЅwЋT_—#§ОJѕъюїВЏW#5А*џуАџ|SџјџуO,//џ{ѓq‰НИЗGЭјлŽ]ГќЮэ@дЬЛР?p+V{c‰ЂhЂк1@Qh4у›ХќK!u R•-SEЙк*Д7КИИˆNЇ)%т8ы˜/кзЗЇьй~*|b‚д4п;Иг$Яl\гьegё,h?ж$KДтpmhq%5цgцкаq(ГЁбy~кGЅ=iЛ"ВI–цк”e9‘pИњњДZ5AзюЃЯЏ5 ‹kd6ЯsДZ-\О|ŸљЬgpцЬ4ёпЅiŠ[ЗnсюнЛу€k|"(ЪEUƒ–PQŸ0 ЩvгНУЎng‘yiKЩЎZэѓoЋFкUВ=ЎiоЃпяcџbŸНFOž<‰'žxb,F[6wяоХъъъxbШЕ?аЕE ;q1ŽљЌT›Ÿ*jв1?šˆИкj.{`[АЪш6ркг)њ`8 A ЯsљЃ§шЮWПњеяє†ћ[ЭЫь4ёМMсыЖдЪЁ‡јDŒВЊ5я8‚fˆ(n ŠCpЦ *‰2ЫQРэU^Ё**ЄƒНэќQнЋьблŒYјХhНэДдRёZю7ŒqTлы–dЅ Yєп,ПЊK]p_3p~ZDšiQ6 ˜­{>‘@™иІШ‡Y-шЃ$ДR`žї…V%ЫeЅ5ДtЅ„’Z)Љu‘•МH‹zyJ$Œѓ> і~езoЄwхЋУkХM™щ!ЉќѓьџЉAщ#Oкэіџъћ>ЗƒЏ GЛєЈ]ЌгуЖ\Сў8ќЈз<ъufСўгPћІUЇЯMЂh"шгрOсsЃг^МЋEb6dsЫЫЫhЕZШѓ|LF4 €љз&ЌЙњ№єF7z…А[l•2[јЧЅЬцb~Л*{—„§~ЎM›кёкljЈc­`Юы,бЛ/MХ[lяu:ЮхД‰•fн˜ЄХmЎƒ-№b>‹ыQU>ѕЉOсФ‰уŸuЛ]мИq§~B„ˆ^_ЛBgаM‚d’“L\4=ЫбвF m‹яiЮ†іˆфДћж‹}r4єšпџ§xт‰'АММ<ё:I’рЮ;иммœјLцѕlїФY=tкVЅ €+‘АьQFћиJ‘і=D[cє|лdSњїд™~ц,ЫВ/}щKoїЛп§Юооо]­ЕР‹.Єˆ5у!WКв'XK-–eхWRœ1!+(­„/  e^†Є—`Д;‚Ь‹ƒё8€qŽ"/1ьŽ žЯ1ъ&ю~^ ЬJe‰*“hДc„эИр^-Џ[З$я_^—?т ”кS@IVqxˆНВb•T"ЯJ/я'ЂШ VІИ`рœ)&xС Н_ІzWU(сЃ hП‚.ЏTUVЂЪЅRZ—КФ.gb[%ќ­фVѕкшfyзъљлС&ёяЧ–ќкЏ§к/Ÿ9sц’kФЦЕАщBžFt?l~СЅ№a'\AЪ617Ї!Ыб ж|йА?UпВEIьЪп@—І2jя№8Ž1!„˜€џiEaWœ6ДMЭ€Є”уО?­Ищšp)жй§тiкщєsг Эўм.дХUQйŠmfУ3š­Ўf'6”nˆ‚ЖфЌyаV!с™`msfhяпlєQ_лШM]€(Š ЅD’$Я5ЏkO'иЩ•-Ѕ§Ѕ/} Пј‹Пˆнн]ььь ЊЊё)ЫrBP†&N†ЇAн4ЄD“АP‘к#žvЯкHС4йp{rХNК\fQEQ`ƒСраl<§ ‚?ќ0ž|ђIДZ­‰уьvЛXYYСюююдiЪŸ6њьв1АЯПY'.8пn3йї§>vвNлJ6oХ^З.m„Біџp8њюwПћƒя}я{пF›*]Ÿt€UCХЎ.x r=Чі8Wg†;йœЌv–И@S’ЉBAцvˆц|мї И‡сЮНМЃБ#^Šk”nTI€!eШGEMЎѓjТžfа€‚” eQ!щ'Шгт`:@Ђш•wЗ_NОЌ+”Њ„‡ЪvUХ|”LАLФ|йkА…|(yŸ'-U•Э2Я;R*Os€љLˆLIЖW еЭЂЇWT…дkѓ%&X(K™j hЎ$Џd!гr$7ЋЎКžЏъ2бƒƒ`o3ўšћЧиjЕў{зU@ +xZ[РЖ­<ЮDС‡A> РЕqйЏC78[…2Ѕэ/[љkZЂDYР­VkДжX\\H узмИtDnVЎоЖЋzЗНhЕaЋЈбѓ`Ÿkњ>Ж9ŽmмBчм]‚‹UmяLр`Œ9ЖжОљŒЖp‹-eьъЉвж‰Rj,зj$\MПж)юБqеgНftDњ7P8˜Ў•ikz}}пњжЗЦшyoЪ>ЇЏm’Tк>В?ЏЋ]г4АPќЈћ˜VЗ4QІ|#хMJК3Ÿ…zzЬъя7›M<ўјуИrхЪ„@Žж;;;X]]лRл ЃнfДZ‰Лˆ­”bЋвфЩU€й>.wТiу‡tэЛИЖй}э~Пп§оїОїн—_~љв4нPJU$HБƒ/^ ѕP•КЇJьWslNЇьlбЪOцIqЩ є н’Йв2‘(†ŠQЦ…р‚1ŽtP"нЯрE!ѓаaЛr”#/кЅD‘ЈВ <`Ђvщcрмƒі YHЈJЌNцUЅЊ—ѓЃ ьPPZчлВЇKНЇKБуЯaIЗАPŠRНjA{rBWѓ`№u •Z/SuЗибялzUцHУeoоkА JUZ%j%S5({ЊWіtZVР7Aп0ўEњћБ%ПіkПvъмЙs—]І.ЖІћЌD€’ЎІyuл3ЬЧ­њ?Ћ–>Р‡ 7$%ЭаРj‚‹ЭцЅY6…§]•5j6›§ѕNЇ3ц˜sJ{„іыЮ‚YщfE…H(TюZіkи›с4Л_Л3•7•;Ейн6еŒ<ЯЧу™ІЯO‰—išNЇ˜љuшЬkбdЮ6ЂŸЩ &ЖЗМy8ŽЧўюЃбшWl†П9gнnлллоЎЏххe<іиcx№С'’мЊЊАЙЙ‰ЕЕЕ EаYш…MІ=Ў M\lŸ Ъ ™І…сJ(|o#.Б :l{ а$koooїћпџў~х+_љВжz[JY*ЅJ Њ6 €€щAБЏ“j$їTІЛўпfBHнaм ™fJдšU•ŠИ` .‹š‚ ЎЋzпƒпˆР…&$CЭШ ”EUђфЈнї€И_Рg#ЅЅ<шйJkЄ7фџkј~љ–hыћvЄГlK%еHo1oкMtМ&ќ;ЯqJCВTНrЄWdŸ­цлњNйCOх:/ідš*uЉ MyEОJ№KL §T$јЄ €яћƒndгь{] nv…4­пѕq}WешJŽJ fё ья]юmT]ЬЎ*iЦюšš ƒ‘Я5›“жNaŽƒŒЋjЇА1эКк”-Og§m|W…`УŽ.чš€ймІiAйn“хKBЏ›-УkЋqКд щ=@Ї\\ћ JАhКЖэ${sssу?јС7^~љхЏEБЅ”Ъ-–К19PІњ ­рЩT ™ъ ьЉ§`я0†\KžЪ†>­*Ѕt.ИіДRKŒБSрЊУ}Ц„WГ№EB ŽЊ(QfЪЂЌƒšC}H)ЕRуЊ†ћLsCfЊц( ­$зеџsџлх7Ќ€;>Њд<п“У|ьр3pЏХЂ`ŽЗЂ3тЎпf'5˜W%К[ьщѕ|Go•ћz№G[›Р-ЩПвJ*+шO3ћбГ‚ў+xжжЗG“Ій“R §ЙяfСъГ юЕbŸІ?џaЄ€geѓЎЦ&хиЌh›йon@[4‰ҘЊ”O˜з3sўfsЖ]Э(i‹BЙІЖ‘ š@и7­P\RЁіш˜yo:їNЉ­InKљRq E›ўОЉј Б&˜ічуBˆБœАщ§RQ#:Ўщ‚НЭMЌŒNЧупчyŽС`ЅZ­ж„uЅЄL{УЙ0чОŸ9VЪ№ЇZGЩ^›ctѕ№ЭџG.6—Џca AвDФhаNбЬчсq"ЄыдFCh…~TЛЯХЛ0sїхЁŠxf]lll`ggчPBCџяy|№A<љф“XXX˜И“$Сњњ:ЖЗЗЇЊIК\ЇќhЏў8шmЫQuQ[SУХ}0‰ƒЫЙЯN6mm[ђ;”RX___§іЗП§ћпџўїПUUеЎRЊPJe˜TЈЃAT“€Ф%ѓх№Ы‘*“ЕŠЩ’e"b+К^Оу:P'јExZTЊŒрkЅqжœ@™чиЛ;B>Ъ‘ 2(yРмуZVШ•дJЋ*T€р’+&˜.В’ЫRVU_М)3Н­юXЧЎHтrьТpdЊг\ЊLБЗuЉ+™ыBІКАЖќiрBЄјЭyt§Б$žчнg'faвЫюЛ”ЇЬЦ?MќХхе=Ыcр^+ўiСњ(г уЖ ŽУ]˜ЦАсBЪВЅЪuДb%j‡Ю3 LvхdK*л#>іЦgЃі(ЈшбъУеcД])dK+wZЭаб/ Хк‰ІЭС ЯЗЈЭ/0 =.šl™1>“\™€msŒЅЎљН‘\.ЫišN$(цuѓ<WџІЊ5ŽнТБ­—щ4ƒi/ѕ0фВC„LЃЛ|›gпGo~ \ хЃ*%r‘C щKHVЁS.С“о}0г/Жˆ‘нЖБЧ[]mJ~ГХxЬЯ ŸЂпяуіэликкrЖ‘Ьk7 \ЙrO>љфXЫЌ‘§§}мН{Н^oІLВmlы•5Љ0ЫЊœЖМlрimSз˜ŸнЮ™6Mх*Дьн7ЎїЛп§ƒў№‡п•Rю}УR/ЇЬЉг7FЌ аŠt]eeэѓ u РЩ t%ћJъЪя0Щ9цРбфEХЄ”"O ‘ѕSЏL Vfe­(˜g ьWЉо–%kkЈ@fђ–тzО_нNoЫї‹]НGŽŸVрšД˜ќ9Ў%˜L5“щјм*ђМу|Щ)Щ€œQѕ;јЄ @QЮР–ˆЌЊjBošЗЫjZ@3hš |P5ПY0§Qў‡iKLг18ЪЇЂ+6tю2сp#Nѓ[ŸF№Б m6\h_{ЛbБG“І1і]І.ІzvЅoЗJЬsLА6е MDM  N{†ЅžeЪВœ‘ЬВl\Љ7›ЭБ„ВЭ:її  uХ2hV ~ №"єƒm”EQкBQУŒБC№П9/†˜jЮ-uLз$Ня)П€ЖШvvvАВВ‚§§§ЉжЧFИч™gžСУ?х№Њ–Sy5аЛ^ЬкѓšlоkbСы№sqZхjPє­В[­ф[XЩЗдЎ–у„ЄВоoщNќ-ЌфХU§3+(лUЛšђџЃўДъџqД>‘Іщ!сZэдмœчЯŸŸј{;ИTІѕЖ\Ф›Yj`f„ЯХАƒзЌЖРGi4tTKф8я7ДdWг “lђоД„СNШ\ъmvŸжFpЉ?вž(mи–Хі˜˜-^c6гбh4юСhйˆ3Q†=х[аЖFcл`њ>TЃоF!ЈK$UЄо&а§t#Aмh4ё((L№џ(€ч]ЪgД‚Ї.qY–a4ЁйlN<ЧЎфlFКэ№ggзгnЬуэўщQPќ4рЧ1šx*рB\ГЛ.uМi„>› H™ыЎў=ѕŸ5ЏoOPВ(§KЅŒ" 0}OJќ3 ЖY тцјЪžћїїїЧ}yпїЧ*oT'MгБ№љ™ \f$/ŠЂ1o€Њ RЉ^sL†Нn’#$cžO[RJ dY†FЃ1Fl'Й<ЯЧНsЮп|ѓMgѕ?О_8 Ю,оБп@…!ќиƒр ЌО‡0с‰E‘#M†Јd upŸћІrUЂR%488И/Р| `|ївџОѕУљCФH:HЧэ5_–%юмЙƒз^{m<ЎшB3cˆуЯ=їž~њщCїФюю.nпО=VьЃB\ц{“МйфRзшЌНїИ[;ž–јКP›ЗAЋ{Šњаc7ш‘ы§\ћкAт™НњъЋЏ|ѓ›пќннн›JЉ„0њg~;pJG%  H`тЊƒ˜e8v" Ш—‰N“Ёмw№фŒ$РўWЭ`мУJ^pŒЧі8ЦП*№ф€Щ˜gAеf“Rbggg<^eїЈэдiзЮVg1їѓАo2WBp\=€Ѓ*іъqЉтYm;пV ›еJqѕьYa{.кN8шпPйQ›…l mJЎs‰й‰‹E{ЏЖЫŸ >”єHUі 1 РИЇcк? њ&љШВlŒ˜ё?“D˜gЯxлФђ ђC'ŒБOœxЌЏЏутХ‹ldзˆuлккТЉSЇЧёдўЎЋїlІiЧё jZG§ bŸХ ј8гˆЧ ќгИ гЦ’\</ёnђўooќр[1.ŒЎ е\ .ŒЏ-#ГЩЏ6—РNp)Х•ИмPmєђ(DoкШГYїЎ$Ю…DИL’ЬїћћћЛ?јСОѓo|уwЕж[dŒ/ƒ[ƒў^ПrГЫ=B6,Біџ–Ь ™PВ €%ТCўu1№њв3їzF_Ÿ9~ЯюБŠџXƒЦGбј„љЯэлЗqўќљC}йYA(Ы2Ќ­­ЁгщрФ‰‡ЦаlЧ6›<ц7ГХkŽлGЇЯЁЧ?mФЯ…•H|JўИэƒу$ѕЛЃр~ЛЇo?B§vЅAMwшІъЊŒ dn*[Ъ0KŸKE`\–Їцw& &ў5щ˜\G­zЭММЉBMЯŸy3ў—чљЁQA3=`&Lp3kЫќЬvBЄ$С4MЧB?Ц$Ш|žFЃ1–ЖѕLв2pѓцMмЙsчаИцЁœЙКˆСdWЂлэBABCъ>g№=ЁРižРтF„Р”.сЅ*)Эс Эаj”J5аѓЁЋ]л˜†ф +ї§#єpюіе1’3АННнннCїн'Т0ФеЋWёЬ3ЯŒбœЕќ&і“lзаѕwqmюћ˜\D{ї,|№С чJћ:QЁ,ъЅ@пзVПЄПГGb]ѓјЎ1лYе>}PђЃ-БэšаБ6ГоЖЖЖЖ_{эЕo~ы[пњ­ѕ6€Œји0с`ЦЛ„iєQќйG{ИјW…О§o 6Ѕ*fVЕЭSЎ9|ќ>kФю(6ўФБ§ЫО^ћїх ђ?б џQ#Я›šІ)юмЙƒЫ—/к|gщнgY†~ПсpˆЫ—/ЪКiPwКаŸлЂ8Г’€iЎЖ‚K№c–DЇйЌlЦючЧЌ$`š@вД$Ф%ˆbЋљйЄ<{d ч˜kAGJщƒТоб1›7 І@?­аM№7=~“€˜і%гQ>‚yžM†ЄЦ3ЫѓќаfL ыž€8ЈRЃ!.Rпˆ,ЫАЙЙ‰wп}Н^яPrсъ›ŸxКЙK1ŠНJ_b/п:XGЂє34Т~шз(žфЩZUPRУœ pССР р‰мc|JTзRаа` рœA0Э8іЮо@.†Xxѕloь пяr8Є{KЛнЦŸzў9<њјЃр‚Ѓ*+ в$“ИБћ>nэП>КаPшоУћжБ;GŸФ­[З „ ў%Нš6LъѕБУжА_m"`p Ыђѓ­]j№EŸ\џДўП+щuЁ’.ВЌ y Я[___џўїПџЕз^{э›RЪmLŽёйЃ|…ƒбџЁПy\џŸзпЬJf%.6…hwЏџPхќЂќ7nмРЉSЇаjЕBћ&Ё›ДЉžnмИ“'OЂнnЪ`mU;[ Хм(vв0­2ЖЁC=pСnі1LC ІСх.ВЁР>Hu?-їyГ‚џДЯfУˆг’ ;бЂ0Ўˆh№І:ZmйІDЖо€љоі  zцї”™o’ѓМ<Я‘$ЩиѕЏнnУї§1дNЏээ„С|™п5q 7H€н*0г цѓх?C63c|ІWN?]—UUamm oНѕжи(шЈрпљћањяF(Ъ*FЛ{ 94/СZ%TЌр5ˆ›тИЩJ$L#/2ш`–ч(Š В’`LБАƒv– ВЊ-Yj/vЮД.])`ИД‰§ЇЗQ}iL…‡ю­5NŸ>Їžz >њ($Ћа/іPъЈ6w6БЖН‚] icс јЬВ’(yŽпяџЏјaі‡8Y^Цљќ‘C”П‡u\ЏaƒпЌфдAМа 1oу)ѕг8ЁЮO$ЇгЮБшКF ЭzЇЯ™–иm zo™uDЭ”юмЙГњъЋЏ~эЭ7пќCЅдюAАЯІєїЇў G г|˜рЈЇш\Є;Jd3ˆxGз+шуc•ќв/§вœт›TђкkЏсSŸњдDхEaДiVЅBфyŽЕЕ5pЮqљђeчŒ*­ЎhжK{b.=€Yе…ипьщпа`0M|Z@fЩj zЬ рГ’Ы#А!џYDKщiš–€ ŸRssЮM€ЄК6фщJВheEѕт |J5њЉ•Ўy~–eH’фаЕЕ“PУтЇ’П&Ё5эѓ>ё2I„mжd>ЗI0ш8ЁYп&Y)ŠRK(}€h(€i†Сp€е•UlmmђсА56Ьї—/_Fјй ћK{УY• :№љтt,СtЃ„ф%$Ћ ДД„R%ђЊD%М(PUU%СД‚Ќ4˜ц`аКєZЊƒQJЁЧСИ>H @0xЇ5ф_ы!џNѕУіИžМtщž}іYœ;wn пЊ>юfЗБ1XE–ф(dŽŠpI4‚Иц|”ЂLJ№0@"†иzј’` kЇА”žE„68чВFМ‹•Ц[иckаJƒƒsјМіnг@ЎS|џЇЫЫxZџ4BD‡ј2”dgЛškJї*J’=ъўЅ‰/EFl‰wоyчЦыЏПўЕызЏЗЊЊ=ИUћьПэ3џуќГ’Л’gŽ1%јЛxГијџ› јiР{о†єZbєЕз^УгO?}Ш9ЪЎўЉ0ЁQ=ЯCQИqут8Цљѓч'ц[m(д6XБсАЃn ›\шj'PCзgЖХ`І™g|Q"пU аФф^_„яњ§[—’­§oЃ-іЯЉx эU›~6€ [[а)УŸТЎєh+СєшЁŽљž^s;@ˆнЬ{YsЎЭё˜ЯІщФœ==&z§Œ€–9oдdˆТШЖѓЂR ѕў[ЩЙ.аняЂП?Рfw,д`sЂ'&ж}?zž‡GyњЉіŸОU* д@Чƒ<ЩыноWq‰мƒP‰„ЧPЪЊо%9?ЈюЂ•„ЌrШJЃ,U`Џ!g@hhјрœСѓkb з!|Яƒ фy†ўg‡ЈžHБАv ЯЭ}ч/sŽ4MЁ”Тp8ФЭ­kИSМAА ю3јэW№УAўбоЂ=hХ5ˆт&šэтЙ6Кс6VіпДчЌц=@ЃHrј‰€,%d)сyТїjфBpI‰<)АRН‹nОƒOG?‡иkЇTшВЅy]dНYŽЊєaО]ја=Ћ,Kѕілo_ѓЭ7ПrћіэWЕжћ„бŸп#ЙяуќГW{РњьdсЗAџЃl|bк/ЖЗЗёЦoрЉЇž:дїВГy›/‹GДkзЎгЅкрЎљяу&4hЛњжv№ЗI‰v0І7А+рлAќ^кїZЙлНРЃцљierкЯv™эаї 0ќ,4РЎŠ(LOGБшЙДџ–Т›tmбЯ`њКІšі},ЮcЊoj?LѕДoNЙдVйџP ~ЊЬfГО]чв|*&DЧ вХj—НŠиэЂп`meeZAДБ4.+ш Bu-@uЭЧd№ŸŸŸЧЉOv0|њ]чК5Њ­T[<-р1€B!+T\"S)tžУЯЯ Д†Re!QЊJA+~D5ЄЪQцI*!˜bŽ0рžWяаJCCƒAsyЃЭžя!/ ˆ… йт*ОЎўФљ"тВ^ј‰BVfPв`€ФB{ a@1ќШCњ№ЃТѓ 8d]НGqqЇ…И5fk˜S№ƒTЄ,1вCШЌ  рsAС|xО‡a5Dй/ ˜@;јƒќ7№ЇфЯ`Qœ:$Cls\#ЖІШ9jП0ыЩ$ŠєЋЊJОѓЮ;з^{эЕпнииxC)ЕяЈіsИХ{ьџqџЧ4›ш{$м§я*№dРЌŠvccJ)<ѓЬ3‡zXдIŽЖ|пGžчуРќ;ёілo#Š"<єаC‡˜шTŒ…’юŽJь@eE—&‹$hsfнРv56Ћ рR›•(LГ5О—iˆYЯІUрRўs‘”Ј^;=ЏЖzm]kЗ ЈEЎэ3O{ь4 ощ”dhєѓ)O ‹F“Пбh йlŽз'•]5pН-l“ щёQ…LЊ шЊ ‚Q*VЁ›ьЂWьcs{ВPа№"~ЬрХьŒBуЇRx-žz@Я“ lЁBеО=ѓ^šCыz РчQ"єНJK@•˜ Щ ‚s0p…Фю^‚ЊTh!ТРGраЁD–'рШPV94ќ @z№ИOxPJзI@%|еДRаŠA№qЃщK0hy‰AБ‹]Н† %|ЏHuрыЊвзрМBСSѓ P”fрLТї<ЁСY…Рчˆ›$˜ж(ѓe‘ЁL dЃUV€s†0Š58ќР‡јрŒŒеэ Х…!x+FžјVўŸё€~ђgб!’Ї$вбT?fZ›LжXѕњыЏПїњыЏџюююю[z–%ЏЋтЏŽј?АньЧРQѕьѓє‚Ь@ОїНяс™gž ў˜ХOэ+mР@ЊЦ?РT@yžу7о@xјс‡Eб fћВе wyиDія\пьЎо§qўq—ХЈ§3›pxЫзЃњљгxГјГќ\c›4A4}{“мшп5vE9(&Иšџ›O{ьfЃ5kЫTьF‹пж€УpŒdРlР&ИSѓšааI“авШ@ёu П9†SаO{шхћиJжЁЂЌ№’хЌр РkЂЁР#/тBA;€_ЭQ(J O†[!у‚ ~ЭА(Œр{>Д–№K žыW`@)kЈ?Щ dY С<4ЂтFяЁЊ (UЂ№sјр Э8Fмˆр h Ь ШJƒkІєRЋu$*ШЊцШВ„*$ 5 tUЁЊJTВЌI†cЂa4-СXЗ ЙЌЇ$8$ +ЎPДR9FЃ щ0E6ешчОЯї!И;р™ip]З.Ђ8DиŽ0шT#М•~ЗЋw№…ЅП„ZуЎДmHѕ ь}šєћ}pЮёФOLм—Њ”хoМёжoМёх^Џї–Rjр іхpєиіМЖмэЗРџ'§C№ЫПќЫЇ9чŽ"ЇЕСЦЗОѕ-<ѕдSX^^>д;ЇЛс˜­Љ|Œ:eWПёЦBрФ‰Иxёт`6^R›†И76ьO{mЎРOGл\ŽeДMpTѕmCјЎ`l'.муЊкЎx6Щв– ЕЩG.•@aвkВпЫЌГ1š@iWЦtžŸЂH”DH-PЭ{šŸgY6б’0 ‚нR МCF4аЎyž!ќ™і‚y_jkк.ЃšќfY6aMl>cЗлEЏзУцц&†eЌЅ 4D‹ƒљ(82 xФР@xТг№ЙF <ОаСCшеЧbЖL…Z 'є"~„(hРгPК‚№|Уї(YBk‰$-бэ&( …(єаiЭсєђ)„ОВ*1•В„R%_ЃбБ4П€Ий‚яљHгнlZ)О€Ѓ,TUЁ,rpЮЅQ9’A‚0#h№"Ќ› LJЈBcПкСіў+ОАє—ЧЈ—ЭwrЕGэ§…"U:Pэ+_~љхзпyчпO’фm­ѕа1Уяrц+qx”Oтhс›? АUІЂѕџ'ž?ЊТЃЂ(№Ъ+ЏртХ‹xф‘G&HW6л›о$Іњ3юj&! _ыыыикк‚>њ('‚E\Јй„ЉЩ‹-ьуNБљгћ.‹Ю{­іgc›mьBŽУ…˜Vёл?ЗaI[хЬѕЊ4зš’чЈј…Я)tO9tЄN—(ЖƒьY}УДІчнМž=ЦE!~ЪюЇ Œ™рoƒц5Э8!Е#Nгtœьš`Ogџ{НіїїБББQГў•„7№Ж†Xвѓ  Hyx€˜г№š€{№|!88cрdМђ`ѕB+ Љѓ<€3)K”Њ.=ЯGЬЊтШ‹9dЅР4!:­­f Ц€4!ЯkQ†V3Ц\gsѓ hD1Д”№„Њ”ЈЄd­РР EЩUU(Š eQ@+ пѓЧћ@.Š2E™Wuu_еj„J)ш’Ѓdd.‘sД›M(Ѕ!+С5ДЈ\BцЪ,G™Ѕ(Вй0Cљт„'Р9УЈЁHKЈВД†№<4š Q? РХСО ЪЄ‚ЊР€ѕє6ЖђUЬсФЁ„ђeш§сo5ћкkЏ!MгєНїо{ї›пќцяєћ§ЗЕж#ИY§хф>[њVџIрџр#ƒџ];wю`{{WЎ\С™3g&6Oъюf*?š˜„€&єћЊЊ№кkЏ!4›M<ђШ#X\\œ9 oMХF{жгfЇi`ЊBащыК,=ѓpНЦ4`кПЧ!к€kš†Ик 6С‰іпЦ:%УйГџ4)ЄшэЛлоРхЎcЇзЬv•Ѓ-;щ3ŸЯ І e>­ьЭš5ыбˆ ™члФIЃрg„hЬї;;;шѕzиии˜аB@Ђ)СкbžЭ+№FНГL9c@cС‡П QB3yаЗWр Њ–ёт Ёb JVЋPI)K хe™#ЭF‚!n„ќКooт†'кэ8A~  Q!M3ььnЁзя#KsФQŒЅХ“XX\DЇ=_k,d Дќ D‘•ѕвRТPР“€Ќ*ŒвQ­є№Н&‚Р‡Ч8у…FеVЦ)x/EUŒihЦjзU!&ЅF’~†fмЌЯc;@Г=!$У Щ(СА?„ч‡8}џ9„Ё0!u…ЂЈР‡№ФС8"ЋyQю pЦPf%ŠД€,$ „„ЧСŽЕђ:цќzєО  ~šXкœэээб›oОљцЛяОћ;JЉыUUДжгX§%&zў$№џЩуЃKŽ"ЮzфyŽз^{ Иrх šЭц!n€!xбб*[0ХўєћС`€oћлУ­V =іNœ8OњгˆЂsss7šнпІA‚ЮKг LЭT\Sг ЛE`Ы‚N#§йЩЪq€у Жa+№Лџіш­іщsщ8”aкл$PwjДSТ”IŒž;eЮSK`z]h+С3ЄBš„RЈžzЇ:*Юc*|*4DЇЈЊM‹ЂЫ looуџЧоПХЪšЇщаяќqX‡Нwž*ЛВЫнэnлcfРэFцТ!k@x„Œdq3mw„Ф ’ЙB #љ.Fš #№ @Hиж`ЗofЦгmЛ=vЙiWз)Г2sж!пщфтБ*vфZ;wfUVюrЧ+…vЌБcE|ёНяћМЯћ<]зНє™Й{žJ"–љ8!ž"ђ<Ёfeџ_F0IaEкLj<йFЛщxJјрPR‘„ Єнч*'|№ЮGbЪ8нШ0іT•FЈ9BTdvя- !AˆќšЬфь†-§а3M=)ŒВдUCн4X[!Ѕ xЧvЛe‡‚Hh Rьог2rAs цXпHŒбдU6­bGBl–ыы уv Lž=1gd‚Сe|J„PP„y{FЮ#rИ!0uža3RЯ+–—иЦ`kУи ˆэ†œ*DІј  )@Yвš6€Œ6”D‰Ј$+žПє8tœмѓU7@ЩЉ)%ž={Ж§ЮwОѓЯОѓяќq?Ѕдѓ№џёŒџ”јOёц ‡ёќљsnnnјЅ_њ%>јрƒ;иwТ3Ц|FYэpVЛП~˜ќяЛЌV+ЎЏЏ1Ц№чџќŸчбЃGїК|BЩЧ?ЋљЯЯІ’'~H<шPBє>э§уYџ}’ЦїI‚Оъ>Ч ў>ŽФЁ@аCncЧ†(‡ЄЙ§m{‚пс{ЙO№ћQбсБоЧžrШи OІ‡ЏЩ9w—ьнїњњ‡ЧуP<ш0iуxхТЙ‡ЩџА0иЇУЯяvЛЅя{nnnю<ш ’у™0&#eИ„|–Ы„^dдŒ’aQ#%)аVu#j‡ДAYлЫEЌЧЧ@Ž‘”39CЮŠР‡Dˆ‘”JjHŠ˜ЩШћ4иt$H1рќDЧ–”"ЦhЮ ДЊБЦTaГС;Ч8 \_Н њDг4иZГИhˆ!”ч#S№J'r&ЙФшFтЈg3Ю.Дѓc+šy‹­+Ж7kЖз+мДЁ-г6Оˆ ЉD’7NмоЌX^žБœЯ™ІPюFHƒTi41nш6ОwјЩгЮf˜КЦV S•ЯL k ІВДчy'р#CкRxiЯџАH=fќяЯm}єбъї~яїўщїПџ§П+„ј^ŒБпЭј?oя”јOёещ/§ЅoI)ŸМЮьџu ю?јƒ?рУ?фƒ>рƒ>ИГJ=Fія~>КŸ›^іЩуА8L:эЏ§ЕЛПнЖ-]зёюЛяђkПіkwЯчx|И’Е?9ЋЯ=”МW™пМj№Єюч!Џ‹џŸ‡œЪŽъ1p'сАѓ9$б §Bтћ$КЗщн3ч5јї№њ!ЋпUŽGLїљf‡EсK‚;p/ №>wЪCБЁУуњњšллл;2пБˆбqВ?L wqщр@~ь §XЂц Qƒж%2—™МT d™_#2BўиP-ІaџyPЅБЛу3M{;о93gbЪ„‘.М/3pЅS$Хђ|ЕВXmwЋ‚ЖHЉ1вѓ™Fœ™Ц‰i˜ŠКо0ж`Œ*2С!}9ЎЕ­H13љ™A!1RЁеŽ8) 2Pе geёH ЄD™Šj6C’pнDФVŠ˜У0SUЬЮЮSТ!3ЪЊ]žДŒУФд D_8J”ŠІТTšш“ї#Б­ЅЭ Jyмp“'ФX8 љЧ[&‡JћŸЧWпџўїoПџ§яџ—пћоїўо8ŽПc<„љ‚њвъOЇФŠŸ6№ЇО№ht№ј{пY}я{пуЃ>т›пќ&пњжЗ>ƒH)ЉыšЖmяджЦq| 8„nЧ1FVЋеKПK)ёУўјџ!ѓљœГГ3Оѕ­oёЋПњЋŸйХ>д8~^эЛ“’нCчЧє}b;їЁї1їе_—kp_ApŒмЇdv_‘p\Ањі‚O‡ЩЧ;Жє8Дџн'сCщо”}ппйою ƒ§}Ч;{辘ыqИ=pь|Ич#ЋУБУ!‚Вя№зы5WWWwЇўaQy,uпw+Н;ЂпVˆ'Бф…GU SkŒБ…<Зыц•(!Rм=оЎˆ)Ё•GJ…QFYД*Ђ;›~M?єŒгШ4Y_R`&мTЦwФ\H…hfMMSЯЙ\žГ˜/hъ$ьW/CЛ‡\П›&rLДm‹wŽnГE*ЩЌcŒBh– Ћ rЇcFэ€‹хr7zL›оwŒЛЕНnНeКэёc$gm#F т˜ж™ˆHBe|М&y0К†єœЭэšыЋkД†ѕsMеъyСЇЂ_PW4mДŠ#гЖŽqеЃЌЂžЗH•‹fСИfм^C$|Цc`пhь €нzѓ‹>њшŸ|ђЩ'џјsnˆ1|ўџ)ёџФ›Тќџ‰ !ФŸљЊžPŒ‘ў№‡|ќёЧМџўћќТ/ќГйь3'Ц=ќ{~~~'гКOЧмq1p5v…г4ёЩ'Ÿ№бGё[Пѕ[Ьf3fГoП§6пњжЗюV сњCя1~ш1~lz8+?NјЧ#cШџА€И јI €}Wr\twѓ‡ЯхX‹џИИьtј^2œMn‰ЧЧoпmя‹ЧНєю}‡нјaБИп 8цўУїbмE‡жы5зззwЬjЕzЩНяРxЌ3ёЊ “}‘вЖ-Ы‹›?ёЦfƒ_Drэ‘˜ZS›k+™Щ хљj‰КьМП$*B… вEhЇв%5ОіTЦтš &МѓLЎ ШZ+Bpx"!ВOЉДbж6œ//X,ЮŠ.GˆlѓІxx›~rx7сЦБXЯцŒHж~p+0MEеX сGGNЉ„b„DЪ„Ш7$мрЖn чIc„ЈЩ }dк8B70Ž§е€”EFšђОѕщGaŠtнšюf"!uЦTšЊЕ(-QlUQ55Ц„?yІС1uгvbv9Їžз™‹"=a‚,Yњ{х}wŸГќ/ўХПИњсј;?јС~ЋыКфœї0џxьїј|Žзљђ)ёŸтЋDўŸФѓў!уšу„єбGёёЧsyyЩћяПЯ[oНuЏ—љИИИИ“оnЗw'сCЦјЋP‚§m‡зoooЙООцŸџѓРl6cБX№ілoѓЮ;я№kПіk/AР‡sўccЂCіњ}3џу=ўcФрX_џ>>Р}ЛћЏS…ћ)м'|мщЃ‡…аёБ>TО;м•пПGћcЖ7Эй ?эНоїђНZkЦqМC ŽIћЯЧ!ра`g_$ьŸУў§юћў%)ъћ>ЏBжы5Яž={iEЏяћЯЌюЙ ї%љ—цњpЏФєbБ`Й\вЖ-cЕсжА i30Ѓ ZWXгs$EOЪ ЕƒџsЪЄМл”и-ўe2фL”u< Є€Q†іќ-Ќ2(mЩ)уC(]pщЦ Зы[њ~‹їУЮ‚% %дuCe+rJєCЧЭЭлЭŠЁяё“#ХHN™œЕ­Љ›)жhb,F@uг№фэG7/ЎћR&NcП--№4ЂЅ&>сЧ„…Xщ–JeVSЧЭѕ CЗ1BТ;X&у}@7ŠлёSR DŸф2ђ№‰&І~Фд 0Ж*п;) њUGwН-ŸЃАЕЦЖ51xЄVhk0Е&ЩLЬ™ш=Vд‡њщлпўіГЇOŸўg777џyсч\—sxѕ:п)ёŸты+~ѓ7SI)уg ›мооВнnљюwПЫЛяОЫ{яНЧ|>ПїфЙ/=zTЊќОЇы:КЎћЬЮэБ ЫqQp_БрНчХ‹<{іŒп§нпхoўЭПyЇg­хНїоуЩ“'|упx 18,Žбƒ§s?Nж‡b6ЧГў‡,vяw<:xРqp˜ьђ 8„ОїЏmпivп‡ЌџУ.~ŸИїЩ{П?ПGiіЦ;ћЄ-„Иу §Яњї{ˆЮТў‡zћз3 яНїЗЗЗќхПќ—9??чђђ€п§нпхйГg/YЗюЗŽ ]ї§юxtЖПОG›цѓ9mл~ІРк5“ю‰к‘•QI‘3eŽ.)ƒ@эtъ$dAЮeцR€|HL3 'Ыё1каV LSƒДВs1ђZѕОЪB˜Ж} ( С;њn‹ŽэvУf}Cзmp“#†)—^(„иmZƒ1JFЌБ;†иYЛeHq‡ „i(ПЯ™(-9)ЂЫL}@‰IЁ0 2WXUуИЩх’>u"M…@DаЪа4НЛFј„D"EœJiДЉА•ХV J‹В90y67kšYЫќ|^64Б{ЯЕBе‘)Eœ1ЙbšІєя|чщЇŸ~њŸОxёт?ЛЙЙљ0$ќ‡,yя“ы=%ўSќl !Ф/ !ц_tіџр>Dри.іpvћбGёЩ'Ÿ#“ЗпцЩ“'дu}/„К'‘эЕЦqМ+6›ЭgŒYК~\0пОˆЧ‘ллл—ыѓљœЊЊX.—<~ќ˜>ј€_њЅ_њЬъу}‰џxHьч№О‡EХ1мўyРёъо}$Пу"сОЭуcЖƒь‘CŸ}З}Ј‰X эњ!гйsЦq|IјчxШ;и?ж>1_]]БZ­иl6w‚=КАџLўт/ў"oП§інkДжОDRНЏГ?ў,ўў№y, цѓ9Гйь%~Щ1r“sfг\11ру@t’L…С*CŒЬЎЗOˆМыѓѓ~Х/0љœraє)Цi`лoŠ8NŒЈньНm,лKfэœк6()Ш9"ЄЂЉZкЊХV18Жн яњш?†сЗsЮЯЇiкн$їЅ{:HєЇФŠЏt№gŽOf_Gl6КЎу‡?ќ!ччч<~ќ˜ЧІ8< Ячs–Ых]bшКю!иnЗw]ы}—УЄќћCЃућэaюеjХ~№~ћЗћжоЃћ"fO|ќ•_љ•—^ы1pŸнё>ЉоЗЫXМЪсpД№Pp˜ ХvЙ { цуЎ{ЯtоЯпэOї‰ќp}n і<C6ѕсп:~Я7› лэ–Ўыюол=WdН^†БџП‡ ўЏќ•ПђS{GšІљ ф_т?ќnдu}зхЯfГЛТчx}ѓј§‰1ВZпђє—~@`™ŠЙЭнfEи!& Ш„ряВ‚Лч–љ…S$ЧHŒ˜ŠІ&#‘t}OзѕДѕœYнbM‘@Ъ™кж4Ж!jƒї78жл‚л‘7c"њ@Jхпw‘ х„P’КnЛбOˆ‘ЁоЁuщœ Ѕ-6KД6hmQЪЃ„nŒŒы‰Ё‹ЈTQ)K}Vqўј лj™э­AШ‘a“IqDЄŒнщ %ZiМ*~Еlю„Ф,Ÿ,X<>Ѓj+ъJГнtLнHг6 ёTГл‘шvЧ2%Pi 2EžoђOўщѓoOЃяћЋ]вяv3ўc’пБ;_фГфОSт?Хз†ќЉћд№^Зѓџ<Р1љъ!KйУћь‹?ќхrЩЃGxќјёKцCЧ'fc wш€‚aю’ЦfГa†ЯxCГЧ?пvZpШz†чЯŸ“sО+іфЏІiюTтЌЕgьSЖ И~Т…RšЦьЌЦЙ€ЖŠрЪЙФ\ШG1Ц}ђп#Чнџ)ёŸтЭ-~ѓ7гJ)џф—§;јЯˆœ<Р8цМNиЧ4M<ўœыыkЄ”,—KЮЮЮюжї%ƒУ"ЁЎkъК~ цняxo66› ыѕšѕz}ЧrПЏ{ОORїОbсU |їщлп'пЛч#ьЏуШ‹/^:fпўіЗљ‹ё/оЩ!ќѕПўзyіьйgŽѕ}Чј!лрWн~_т{шstќћ§нaЁ№Pї§PЂе}^ѕ8‡ŸйЖmя.Mга4ЭKPўёћtпcюoыћžЇOŸоЉaКV)%фЛeU™OkV %Х]WŠPheHdF?ЂУyOŠяЫ>ў8 Œ“Ч…ВЁАl-FяЖNВ„Мяьh„B кzЮХйc–ѓ9­1J(ЃЅбЛђ\”Ск Ѓ+ДTИфњ‘Ў›њˆ›ŠTБ9oИxєЫeѓŽЁяймЎ!fЊІС9Яэѕ†ь3ЕmhЋ–Хт’˜#CзГНн№ь‡ЗloaЬT•тьВсЩћ—|у—оg~О@*ЫіЊчщїŸБњtMггЮjољж[\МcЩYpѓЩ З/ЎIоi оgRŠd“Y\^–-€БguЕfђN@Љ_їЄ™_ЖМ§GЬЯ4ѓsBbи)0LЅPF’wХ’ащ­ƒФ88LўŸ—јгgПvЇмŠŸQ „ј“RЪцыžџПjdpœ ЃыК;Ш]kЭrЙМc^Ячѓ—єџ* Є”\^^ђшбЃ—P„§ъaпїЌVЋ;ВсvЛНw­ю'Й~иUoЧТўОѕЏўеЛ9;ЗЦ=1ёЁdўЊФџy'Ђ‡:рћ’§}ГљуФџаќўЁл^ѕи‡cOЭfw„П}в?<ІЧEкCwџ:ї‚@WWWМxё‚Оя_:Џњ.х'уnХO‘D,ѓ}дЙвHЉЊ|-!vяwЪeжŸ СЯ(HQ ‘ф˜I"#w(@о ћgх#] рІn0КAJKJЂGЉ„” !Ы|оhƒe?>PаƒqrLSРЛLŠ Єwˆ–Ѓя6ŒCO˜мn\Ё™њРњzРMp63Ьчtƒ‘,4Ю%ж7Ћчa„Гѓ–Ыw,‹‹%—я^аЬkњЭDˆcЗЁ_пвЏ{lu‰Uд‹3ЋF1lzІq l(ОRTuЭ8М x?1ѕЉвЉ‹ЧoНF57T•,$рѕDЉ”2eЩ2E@ёШœ ќm>„§G>+ш“Ž’џН‰џ”КNёuŒўдCГј/Z <ФИp_Тy•№Ьы$Ѓ”ыѕšЭfsЗ*ж4Э]10›ЭЈыњ•СсќxЙ\В\.я#ЏVЋ;–љЭЭ лэ–išИККњŒšоёЯЧХУНћЧМНН}щі}Gћаё{Шwр‹ !‡Иу$§:П{(Й?„.еu1†ХbQДш­Н›ећАп—ш•П Ю9^МxСѓчЯЙККтњњњ%WПћŽС!Йѓ%c$ЎэaH„рQB Є@ƒ1–ЊЎJТЁўHQЬj(СZЮM­м%ёD #yOа”e,ЕFŠ’Ш•RhiЦ‘nы‡ВтРbж№і[O˜ЭŒЉаЦkB L~dє#о'rEІlЦeњЁуЃ|xgdfЙl9?ПрђбcШk†Э›еH=эY`№ ­!‰Rф(#ћГ–hm gЦэШИИ}vЭњХšр:ЌMpІ™_VД–Г'gœПŽn$§jЭэЇя'„’иж Ђ xOПщ ќ2кjŒQ˜YйZ#efvfБ3AГЈh—-jг“BA\nž]&Ÿ<Y<<ђђзгЏ=§;уGGџtдљŸџ)оXр7о„ЎџЇХ8ў§оc`?ƒ5ЦмБЖїАяО(xе,љИ8и“яыєіЩxš&6› у8оІiтццц3 }ї)О*љ?$Эћy#•ЯKњ_vpŒ_ІЈмпwБXм{”R,‹;5Н}GџPQu_7ŸЫусџЧ‘›››;SŸчЯŸто+Ж-^чњ]<Єы 6“ы@0Ё*DBŒd!JёHЅЈA*ЎjRŒxч ІЛV- !x†œ/ВМЄ=Т%бЄh%I)3і}иl<оР‘b`6oA€’ђnз?яQ2­0FЫо”‹”Џ7M\Пp”щEцтМЌA^>~Фх“Зш{в–'BŒ“cНк LЂяzœїHU-!flЅаІ<Я~=B ПэˆS Ў "цRхРАй`ZCГlЉf†Х“nъXп:Єh+Y“$Щ>!…D›Ви,кeЉ5ТdъЙн§?EUWАЕeъGІq$ч‚(Ѓ0udšЗвŸ€ёoёА˜ЯaїJќЇxу€пxе ј!вдO‚Кфб“З˜ŸПЭђ2sўЄ%ц‰КЖЄьИzў1б{Кы[ЦM6™љЙЁi2ѓЙBW’›ѕ…Т˜–ъЂEjХАкђlxЦњjЭаЬ/žГ||BP/ ѓЗg„TШ€J+ЄдЃhgsbœP“ЄZTДч-ГЫ"јcЗ5RkђЮAщ‚Lј)ѓ%kБьЬЇv ŒULlЎ:ЬRўYY‰џ]šr8Jј%џSт?Х›QќцoўfЃ”њу_юџW!ю{8џњњњ%жy]зwIЋЎыЛBсЁbщuишћŸїР7ПљЭ{Ёѕc[о§jу~ч}џћчЯŸПДІЗ^Џ_šIП %Й/Н I8ќїЩ“'/%мљ|ў’ яОcхx!ђОM„c+тћŽыёkœІ‰лл[^МxqG№МООО+АŸЧCЏѓ>тъыP9gєŸ ќ9n;1ЌJ Ђ—cБC…š,‚H6,!*‡Ш”„,‘B ЅF+SўHr‚aœJшz"ЮEœ+Ѓ[iЌ64ЖёО'ј‘фШ‰ЪhŒUЬк"Ч‚c‹Ю?9Ђ•DR‚ZiъЪRеС„Х­PынVƒˆ;ЅNЧfеу?yЮЭбV`ЬŒ˜›еŠqлгпєФб#…@(0ЕDкL ž~ггЏЌЉhы]зTЕeиLL]dsН%ЇЬцХ†юzK5ЗˆЊњ KњM1•ЎBƒV–„­*Lm1ЖиcБUХиGЦ~BHY )•q‡2Šт­ЌRЂ › eхяќїэПѓёп˜ўWџIЙяo~АлџW‡]ьы@э_T'рЫBњЏsћыў‡gЏ:ЙOгTœвю‰§К]]зwsgcЬK,ќЯ+юK^ЏšƒJцvЧ9gоџ§W&ђW%ѓ‡F ЏКм'NєaёОЮ§ИР9оŸ(Щ?єйиeЕZн%љыыы;тЯ“Z~4ыUХгg~&гќЙ-ђƒаRAјЁшф‹˜1 HoJ#В’X]Qл†ЪдЁШ)‚’Xc‹}БŒг@?t„‰>\"L~‡fЭhšMcq~`Н˜І)ѓ™.uеPW5)'Іq ј FЄ(f99EњMOŠХpШVšК•иЈh[CUk*k >А]ѕ\=_1uРкg4э[7œ]œqљі[(]Б^нђёїWt›žюf"N %0V ЄcЛю wLƒЇВ =aО”Фй^9Ў?™и^O(“qCРUI’’ФT4„ШQF‘Є g‹б–”ao§г*ŽХœюЛўP'§ЊБСqМxёчOŸ>Х9ЧГgЯюцє{nХчq%^О%„џЃ—ƒŒўoо П•Y“Ÿ^ЦШф2žД)Џˆ…Aˆ„”Ћ-Vi‚9NHPкS™g“2nr8ч‹‘ŽЯx—к„РиŠйќ ы,уи‘b@Š!$Ц”Ъeь")9Ш)"BHЄ77ЗЄ wˆCг*„аЬч5ucЉlЕГ л‘ч›ЎвЃjНѓ˜oўк7™-[B™3e‹! Cb.#Š >$H‰q˜ШБќ]Ё$“7lжлЕЃяѕ DˆфЮ‘;ˆI•@jQЌ“S&Ц †М…fд‚р>&br„0‘E,ЕBkUl‘ЕкY ЫђnцЬиЌžmhЯZкГR$иVЃЗ ѓHќ[РoQ№Ž SpŠ7јћцгЧ'МŸt<№Pч§:§y‰№u6~ЈХaФяfіщљЇ”X,h­‘Rrqq™§ˆсЩ“'wЦ4чччџJ|8ї›)%ЎЎЎ†OŸ>}i‹#чЬГgЯюД^U ќ$гKзEFЬ#ˆL^ЉзŸ|цљцѕ‹Ž4aŠŒ+‡пzdŠЈ ЩCи&ќ&Ё•FР$Є-Ы^% 2 ‚ѓф4•ЯŽH%ЩY ВРъ*‰žIybіЄ№9уB@(Эйй%J<ЂЊZnnžqsћ”~шwX=dY " А;^†Ш‚ЎшЖ~LЄ‘Й ГЖaБ\P7Ѕ4жЄ9ГGЖ](*|Кч7"ћФэЇ[6зkp‰y[1Џ4aЪ §„=Сybm5вHP …ЦGGъ2l3ыMЧ#й‚^€ЎKv &WШ”Vƒ!‘"Ф‚0ИqТЊк”`21—5@]Kl­h ѕЂЁšеTMUF)б­:Ж/6DЗЁПА;H!ŠГЉ fцџх.сяџ=%џSМбРoœзWu›ыѕњЎ“ўєгO_)tYяQ„Улпzы­—ŠЂНэьщєП №Ѓ§шЅпяItћŸ‡aИ[ќЂЈТW!ˆђJЮƒЬфy@|0 п™HЗ’єšќƒ’xхХнs&“ўдsЬ/Nфh@@œ2У:0u A Ш’иGЦg™ЪVXЃ0ZЁ4TВtўХy.R*н, Ђ"#v:?c*„TdЇˆ \Hd.x†qЂF*&—™œd`!ИнgMb”ТZƒV„„ о†оГоNИ!’4жR™k uSяд!ЇH;k.с&"bЌ@з™iь№cЯњйзOдЪ0;ЋЪ0ѕО\1тЦЂ]$Сж)m12І$\-ЉЃНДԘi/ІкYїeD*E5“HYє rŒф^ЙЛb@Ш2зJЁdХьЌІ=oЉч5еЌFƒPc-жHŠa=Ђt‘Y–jч9@&'W$­ў#‹?/7пOw€dgпp*NёFПўыП.ўићcgжк_~h_ћЋŽћ р/#Fє“vь!_љјЂЌё/у8ОT0J бDўeѓз™Фš…РKЯ=ЇBЦЫ iђ[ёЫtџЅ%ў~ƒxV?ќ­'ўЦSФcG Š,4J|Œ›i“1Z”єJЇЬњщH;гЬц3fUE–IFюŒ~Ъ—ZЁЬ.9#pо3LУNa†TšŒ$‘wТч=W7зŒгDђ‰ѕzЫv;аwрБ&aТ‹55uU!„"ХФф&њЮ3MrщЌSиKE’/>1ьм Cб&X,gиЪ"ЄФД‘aмЎp[лїПхb‰i+аšщщ6фБs5’JЁ­-іШжPЗ5эYЫтbЮњjM’‰iшi–c%№CЄэ=Z)ъy…=нѕ–i;тІˆЈ#жЊт#0–ЕРzЗяПx|ЮХлИiЂ_uєл‰a;0[Ь™_.q§ˆBГxд"Х9ЭЂЅj S7тG_L’bЂљ&rѓmžtџт”ŽNёFПўыП.”RПёe“ю)NёѓŒФ<Иэ@&‹*€(pЖT+џ• ~Еcz‘ШпmWбЊˆќх§ЭM&yEђ #>Dќ”H^иО0Ь BШј)\$E(”д$"9ЇD)ВH#еЎѓhщ‘RQйЊьХ„Q†lKЇЋЕ&xЧъfb<ыеn§Я%Дб”6UIQиэЂB)ƒ$ЄRBлJb„h2zЗ6›rТ бљ7DB"А•ЁЗЈJ ЊФИИЙъЛ@QUEўИВDYrd‰р"~*<€юЦс]9'5gгZf—soŸЁkЩцц†ЉгдГЊŒ ј~d”B*ЊЖxF8Ћ F#Є]3Н# O’Ѕ*šYЭ|>c6_\ [ѕм<Нхњг[–ч –Ћ)!БV 7H­9”uIч‰Ё˜‰&џkРп?'$р__АOўћ_З{ўiЬХ?ЏџIžЧыHа~]pџOыОЇјj’џK‚AВьс#<Ш€–Ѓ5Jœ`#ZŽјѓ{ЄЋАжbl д„б3lFКaФŽ !M)ЖRHЃШIр}"љˆ4iDщАsФOЦ“EI*RH”В(ЉаhЄдd2ЊвX[!ЅТ˜ &Іa@eАЊЌ Жэ Rbш{#’„ A† )IМЯф ;ДnЕФXR“Eupg,В ћ@˜&rNt› 9—ю_JбŠv1ЇЯI9АyqEПюngэ\А‚б{\ŸˆdКmЧА6žq“Vнѕ І‘д3СЃїЯ9{k2­$К2ЬЮZДU4ГЁ4)@іBO S›„ˆT’Њ­Fƒ’„ф№гˆЊІеиІЂj*2‚Бѓt7не–ээ†~ГХ ЋЋMQ*” mBЊ„@SЪJ @ЮHУ/Рџђ„œт)’П(Йёч_№ЇјВХРсЬ>“Щ:’ЋuDдeR Š|К‘R#rЕœЪЖ‡жc-u]AЮ8ыB’<ŒЩуЖž@з%ёч\TєЂЫшЙІ>7,7TK ВЌ%v.}Ѕ ZY”PфбGRNH­ЈL™W+­@Ѕ 1Ш $bJф˜YbДЂвЛбBЪФ9e|Фр!D/АUIшJš"QЌTБLжŠф<#рЇ‰б5A-В­Šеuл’cd"9rŒ„”Щ!ьd‹w&I"бoGЦС\"%ˆ.тЇ”uc‘2#ЩЄЩГНй'Р2ы)zІІеФд9H‘Х]П-”DKAJŸYГН™˜К"ШS75ІЉЈfEи(&HcбGШ9с„Ѓ’ H–ф5урКžлЗ\}rC54ч ! Q[Jƒ,Ч gi'№'ІЊАuUŠ?)‰ŠЗ›їѓbј(ЙЃѓю)NёЕŸIў€4ЦќзяSŸћiŸЧјМлюЛ§Ыўюu§щП"№*™‡~џy›ЏkС{Š/ѕіЯЙЌžщHj=Дн є\"5Є(ŒUХ/B”.<ИБьЌU#ЙxЧ‹ y'$SЭk†)q.рУ€`ЄОдˆ,аF!Е F‡Ш`lKлVинњ™V–SБЅ;†О'D ФPˆh$Jё!BШBŒ|"јLGЄ№$Rэ Œл*’MИЉќHQ™’EѕЯЛ„BPЯчЬf ЮЮ "}ЗТпzжыrЪЬлЭlЩ|БФжsBШloЖ|ђнЇм>ПfиxЪ6AЮЛ*ЫhС7Р$I@;k8{tЦђб‚ХEC№‘Эѓ5уІ# Уnѕ1ІH˜ŸC{І8{ЋfёxЦьб‚шЊъщЎЗxчvŸgоžbфц“ уабu[ГЫa"Gќ˜˜ІФь\ГИА,.Ь/—!Щ\?2і#ЖЎŠ-ВTkРќWХ/ЙЋSђ?Хз]м›ќ%Ѕ<)~ єЋŠ…Sќlп$Y'˜xфбO2ЖбиЅBЭY`^YєрC№јб1!6(Ђ5иœбJ“B‘є­ДйiЫ[ЊкSз–­ЫН4•ТЬvвл)“ЂУyWˆ{ВЬќ•дЪcІ >ьXђŽ#‰Њ я : ’$ІBPSJЁЅВ‘#ьё’ HЉСJДTЦ’L‚С1ЅRђ_№‘”ђŽ№FБСе’ЊmЧЊŒ@ЄТд-MЛ jцh]Н _O<џј†е‹[žŠ9Qкйуф Ae4ЖVˆ\lЋЦP- ІVdYЦ0ˆŒ2’z^C.k‚Сƒi4Ш„­3ѕB”еM[<ДQЄ`qƒFм&Ш…Э!4dнmGЗнвmVДч†љeM–ХиH ‘BRЗ-чц\ОwСХ;юH‘›ы-›Ћ~ŠŒл‰2RkT‚ц‘њм?:%џSМI#€Лфh)хŸ>LLo*№ѓ<ряѓК<€Ÿжѓњi*аН.вpŠŸЌшz™ќ—Ш"“lD.#і-EнLcАЕFY]МxђЮ(jЛЁпє89уŒ nl1ŒQ‰кйœЪдиЊІž9кЙЅЎ5гЪƒ‘XЅ@•НМ#щ)B@Š?9rˆхJQў@љ…DчЧ‰ЪЕZыr›RФI1cMХb!ЉЋ–рЩYнЭЊ'Х@Œ‚”$Rжˆ\XьRIъІЬ§Ее‡ш}ПШШlaЉZУl9ч|<#GС|Ж В A‘$ј)3l'ЦэˆRigЅ 9B р5T>C#Јš јЩ‚c}u‹ыЊYƒ6YГ[‚"іjM№c—‹"ŸЬŒ]‡P ­ФTЉA[4™8FrЬtн 26HUŠ;ј1аo”UСйуЭrЮх;KЮо]0[ЮЈf ~L УФД lЎњеРАаж–QвH“–Їoп)Ою`ŸэЅ)ею6#„јзO‡щg“|NёцН7хВSV”‰TyD rF‘…mjfM‹Б!2vНЦо•N6Цˆw T$5ЕУиrNИСэЦcbЖЌh—5нM ЧЂгOH-w…ШЮM2vH1}|)ЫB@Юх>Fœˆ"С•ЄcFwB ™˜)И])‰Ў-T­" ‚ A)AJ31ю$xоСм™˜")xb %NeЦAЂЋUSF#U]“#H-wЏ_’бmЈлЫ‹ ЂѓxП%ИН _бапзу9fRЪА`Š.2n§fЄЊкхŒљйb7лoШ91u#в*ъs‹ДyGјsИо1nGњz YД5шЊliФрH13И-­(яЋ”хЙ ‘KсЄ5uc9ВфёћO˜]ЮhЯf€$ 0l=нкГНшзл›‘a=2;икНј/>њlўc>ыxŠSќЬ€У"рЎxџ§їџЈтб›иљпЧќш9О*Щ>Є№г=њY&їcSS|љїы3@ЪDюc`BIЌ­Š§ѓй’ІmБF1›ЭЩ$”‚ЕОЁпІ"ю“!ŠyŒ)т>нfЫиOХ9fъyХќЂa}50ЌллФcЩ*•Ю>—B9Л2m Аг'ˆ‰,•ЉШЕ@ЂqЮБНнВКо”Џїю.4HJJ”диЊЂifTg ѓљ‚Ю9мшqгШ89Іa"ІLП™ сmOtc5UU#tс‰Ссœ&ON‰“л"W;Ѓ],бUƒЉjž}xЦ'пџ67З8"J *-бV"• јHл—Т@fќ”ЗЁ7Š0%Ќ­бж’™“g{ГЦ#BjЊ™$ шnHј њ•C`ЉЯkД­Љg3b’Lн„Žl ‰OYA5ГTKCЛЌhЮkfч чя\pіЮ9gЖЋЭЭ–ЭUЯ4xІ1тњži,†IЖЕ)ˆ!={іїћ7є)$џгї_k ЛџКЎџзIАЇ8ХПЊEF@иЉб‘ „*fn1rJ(mЉкšѓЫKBpјi њИKŽ ЅЫЪмОžКˆD"ЕFгŒ(-ЫeЗ.HHЉPJ …BKIUŒ5hЃ1І sЪ„ ‰-eЊЊРѕBCъМxI9—фЏІж шLжAТmbˆєƒ {Oя\!5ц„Ь™Š"aДД­ТZAнjъJЁ(ЙГеF’Г*RРn„hЈLТE3›1?7Ь „ˆм<џˆэ-R t+бЊшъ{—> иZ“eƒ &2eп> )КDПщY}К&ХHеhTU4 RR’„1уšLRiьЌ%DШQр№ #кH„Ўа­ІYVД— ѕYMГЈЈ-ЊЎn;ж7[^|tЭ‹]\&…ВІ)EЪHRJ~ћћўОў=wuа§Ÿ’џ)ОЖ𘼯wkŒљгoТ“мЯёПЌюџeёU…ЮWI№;uў?нїцјz rЧ­UTж`Д!ХШfН"‡h#™-gLюŒэњч&Є–XcЈjM=ЋYœ-ЩI2XEз?…ФvеЁMGS)ЮЯv]ЕЅ”%V[ъЖBIJњЗ•!‹Œє‚DФљD–лt]”№ІqbьFB*.†BuТтV'Q@œ&`ЅBцŒJ‰œбyH™Ж-Z1ф2тH‰К6,ЮZfѓТgакйсКbжЖИ)≉8ма#gъ"aMежTuE][n—-J”ёFN€(Sє’яу6ЁD[…ЊиљA5oаЕ!гаГЙкp§Щ–œ"ѓЫ†vQ![‹c+ЂˆХЩ0AєЉ$ЖЉ ‹ЂMАQАlЯQF ЌD™R˜Єщn:мфймtL}OПщи\o™Ж}ЩшYчDQќœюYўЋЯўПг?тюВЃ:ž S|Н€8Lў€UJ§бSзŠ?,‰џ> чLVЊ„l2UcЉЉ*Д–Yио}WсЌ-кѕZ.=ІmgФaЇ˜sbFЄАkбІТXS„}bФ0•Н{лhŒжhЅбЛ@"бЦPеRIbš@dbі„qЮ1N#У0’ЩXЁ‘RЁ gYcё Jэ.rзDNЄрёу@Š ?Ndя‘@[цЫk-dIŒ яUmX\ЬЉ+ƒD2Ѕ8˜ОŸЁˆ ITсR’н*ДЭHH9"uFi…ЖfЇ`XhI9CLЛЬНџjж Д$šCYЄ|5H n;U>EЮrgЅ­ РХУs9fƒCъ]yБВ"хЬДЉgOА­СЖ–”=ЮMјЩ3 c?"ЕФ9‡Ÿ~,†HЅ“ф$ 7љo=§ћП„’џЉ8ХзRьЁџ§Х(ЅZ)хG|ЈГ?ќн›RДnМЊCџ<]€SЇџГ‡џ_zTB,"цBRŸ*Ћ0VярwMЮаmЖ|ђќ#’GO.Yœ-xђЮ;hЃЩ)1t[V7зtыŽѕѕ†ЊšqёшmŒ)šnt ›Ža;сњ€Yэ•љ “‰)рC"Їˆ­ЪLYWя'6ы У0аnpLCІ6()я4ŠdЮ(­бж Є(вП;a"%ЫО}эz=СЙbЇ[išyУљуsкљ mLqœ&ДVДГ9)E†M‡Fмф‰ЉчіХЅ,ЖЎh[EіŠjfh–Њ!;Млвo{œл`лŠйй 5њн˜Ё№’m ‹Ы–zов.krL ›œ2кjЊЦbы"w,•B)ƒ­*rлXrŒL§ФдOŒ;НИб1ѕгTшJBЇ*#ЁO?љoНѓф„п‰,…X\§P‚,2Zd­Ja› 79мшpНЧOѓwnў?щ ј]p\Єг7№_'p—ќѓЮ;яМ+„˜•ј)NёF†€,9ь ‘#і‰]X”ˆнžwХ…Я‡@п3жZЊЊB_œг6…} GAŠСN„GbЪФ˜&GeNШŒH [D"’и%ТHNъ’dšY*уWŽэІgГкрмDt‰$1†!MaŸЯrWFcТ… 2hЕ!хЂпяCyљFЁДeжЖДuУlжвЮg3§Ж!ЉлšрqpDˆ*у'Яаw(=!EB*EЛhh—3lЃIйГ]нрЇ‘эКЃлЌ‘FQЭВ”јi"њТў*c*A=7дs”bК“пн0Ѓп™ e0FQЯ,)цђzф)эl‰]y}!$Ђ/лІЖ„: ЋRр їWŸХOШ"щ_Wо QeєT4ЪШ™ мCD(IJЅLIЊ“gьFІnD#!g|?сЧ€D3?_PU B@˜&мш™Ц‰LB­‰L}i;cŸ"5œ0Z2ŸЯxчoSЕ ]ЗaЛкв­Gњѕ2Ё”Є­-)eмшё>#(Sб.ДГ„`ъGІmI ыТшOЁЌjYцсІЊŠбO–HmˆS$M=зeEP(rJ2J(šХ Sзјщ6)­˜ЦРіІЃ]Д,.,Ю—HЅш6=лыњmЯаŒ#'б– #фTL”Ќ‚]—Lјqd%aOУT  г PZ‘3„б3nІRьL„hЋKAv\ƒ\оїрC!m!%BЪн,nnoи<пЂkЉ ѕyCед˜Ц"M)ДМѓ„ь S јт|(dNюCўЪє}~ИW Ї"р_ы@\ŒжњŸЯ)ўа$§УТKиџNУfr›Ш6’ˆЈМSч‹ЙxЧяѕšyKpОЬанDŽ‘œv;эШтИгеO1g͘pУD ­ ЭЂfўЈAЗ…5ЎdQл‚В (ЪBt/nђ‹NОдиІыYMNр†€їГхŒ‹GRаo:ІЮ3ЎЦhфLЂ’Рe–B@U–кV(m ”-пOŒR1жB€лŽЄTяH ?erJХxH[‚ШИбaЋ€­,Zkм0бo:ž}є)УЖ'‘‰ЎˆЩ9#t‘+Ю€”‚<.LИ>icкjŒе;Љф€Ÿ<оE|чж2˜Jп]”бeУТ)Bиy%ф\ь…@ЄŒr'DPЖ@„еGkЊ™Ѕ>kа­,;";­ˆшSq+ŒХ3Сšџкіхџ˜ PЂЇ8ХзVBёЦHП.њ№КN€ЏR<М~Ј№U&Ÿ/’ЄNёећМ/D.ЃЩС1M!3uг ^U ”2R+цЫ~шж+Rє)QZ“sкїZBьЦ9 Œ-ѓi7:2[7,ЮйAl‡т+`F*Ш‘"эќяѕпE[…аŠqhmХМmY\.™ŸЭiцэнz`‘. €ZIn^мђєй3Ў>]г­fЫ†‹Gхy›‰ЉяЩ9B„X$ХˆЧЛ€'ІЩяL†`иіС6ХСАЬЧSљ›ZЃ”ХT™рvpx7Œt›-ЗЯЎyњƒO !в.цԘYпtјЩџX|G•uKЅЫКŸя'І!рњ„вŠйВfv6gёј ­ ~ŒєЋžюfCw30ЌR)fK‹5Ж6H­‘КlФP›]ЊжЂ­он S ПєL•эW™Œi в АѕЄDŠрЏљП^§н№$џ§%<џŸ4NёЕ{€6ЦhрOžЯ)ўаЂщЧh@J†ФДqюІ(љYk‹‚œ1hSvЬ{ нzUдѕД*[>э ѕТd/E"Є"ЧX<яГ жЬ\сR …@Œ-ІЖˆ Р'ТрщЎЏЫЬЙ­ZR™Šf>уќќ‚йYKе4…gmyJKпЩqVtз#ычгБ2“}щВ]яЗrDЂˆmDQмђœѓ…чаїLуH мA№эЌуv,>RЁЋ;SЅSК<ўфH)т&Wˆxc1,вЛ•J7FІо!cvVH}І2qƒ'КH˜b!в m4Jk’˜С‡2њ˜Š’”Ѕ“R–"HLmˆО8Ъ)’rB…­ Ж­б•!ИРА.‚@З†p›>1ѕŽЊ/BE$ŒоGЃЯ~“~їљпџЛф?сд§ŸтM*Ž%€еЃG~%чмvС?эnјЋfы™Чџ<Я€Ÿuз|п“ѓЯqЪ‚м­s :pЋDL=оMTuЭ|1gІ—4Г–КmбJ@L()”Є&‘L“cGмфvh@YЌъšЉwЄЩ)bl@iЭzrЬLн„ˆ ц-ѓГSWф.0 ™iq!ЧH=Ћi— ;УH ^R@lЄЂь78мк1о8м:’<ЄЙ$Lc" RТ‹„Ÿ2Erи9Чдј1€H>у]ФVІ@ёJюШŠr$Ц‰рBч@r1жбЖ ЕБ,.ЮбF3П8cиLмъžб;†СQ5ŠКХ>x>+ЋwНЧЩ€P vЧ9њЬАu2Sяpƒ/К­Ёj,къyMея‚"ІЎmЊ2NqЅЖ­h– эyK№гX†ѕРАIГ„ИSIQ”з˜Х&žхnГ?јєooџ§фsŒїРџЏв8}СOёЕ$ і €_Uђ?Х)оlD”Š) “‚&oQGbšЁЬ‹•1ДГ4 eбЈ›ІРћ93#››5}з“(НSяГ–ЊЎ ?UU8:ƒL пyrШ(!h5BCŒE€'ИB‚‹B"DФV™0Ц­УѕbЖЉ ЖЖиЪьіъ‹юUWдU…‘%n ?vт {žˆY:В”W~іƒ#Ї"Ь3 ™КЭд3‹иСыЈМ{ž‘iькPЕСAŽqЗЫ_!ЅЂnklU1[ДHaXœ$аc*0UЕ…Œ˜bYVJQœGЪLХ‰PŽr!1цтŒeќЁDЊшј"nT,† Щ&L(# idY‰4 et!ЦRш„)€Ь9љ„Ш‚œR^D7aЪ?ШcўNrљУлпuџ єЉуЧПчѕиџЇфŠЏЅxI а{?юDЏњљЋьдП(ŸрЇ|^wџІР јi’јёП“„^#Gƒˆ ч=СOHUєяЅ6(!QЪ2_,1Z‚g&ЎŸНР…H=_Rеu!Т[ˆkB’Ю2ЖjимЎiлнfЫАлУзЦuCTži3тњч}с(pS`uЛeеz ‡ЬиMяI)аž5ˆ…ˆˆс%йGтДCf†jбј)вoF†UЂl8ш`PК •5HЕыБ лЄЉxЫ&САZ“EТдКє ЫЅ/f;уZЇDUL0UиЦ§€РŽ(HA`m,bIйу])b„˜КB)…Rš”9Dм8!nA™Т0Ё-n;вHœRAd$Ѓаr+Ђј~ьѓяЯт?> \оь:џуюџ˜§њтžтk/юrкўвuнwЮЯЯ?ƒœ€ŸQў9%єЏxщтє F…ЬmЪy=нzƒŠр#ОŸPZ"ЅBСИЛŽ~ЛС‡LКјЬп§в‰Zk ЙšІЎ‰cРIOŽ?F†ѕˆгŠi;zOє%ЪZ„ лiє„vG@ы'†эРАэЈЎ ~єјŠg€ШT­e~бb OЮ‘DFW(_t‚вa‹\x І№ ЪkHx[иљiЧ™Л;]S|R,Р,БuЂj JC*JcдЮ0HBŽhѕмцП檘o&њѕ€ыa„ш@ Aє‚0eІЮasЧєЏZK№Пš№"}B%3A zOEз!ІDB9ІnЂj+ьЌОsKJsœќ6пЂ№dVRцЋ4‰пŸžЦџrzvўю(љŸˆЇx# €УЌ.КЎЛ>\њ*’џ—eЕ?4лH №ѓ„Ÿeџ<НљзљЇјz@‰б–Њ•xяћ‘aгу†‰nНЂЭ™Яg4mZвЛ-cЗ-€)0L‘j;0?[PеU!jВЊ0ш‡ ?ЅК•б] †iыЙЈЪХ)ЇD3Г,/ЯH11|rMєžЊnЈšŠКЎ‘Z3ŽŽБѓ\}rMпм<пю˜№rТЬ*ЅœЎЬn Ђhђ‡Щ“Id2вhЋwJЗeBK`d$„LŠ г(ЊЪ—‰MЛС=››žf–Љк!~ђDя˜Цр&LЅpSфљopcРTЖШ- MП™xёƒ†э„r)wfIТFыFЊy`ёЈХд†ѓwЮQКУm)$rЪchц3bŒtZб­:КU‡‹Ѓ`є™рЫіЉЭYM{ц‘Кx3в"RЯrЮCtљyъгї§-пЭ>_ѓ2йяИыhяџ”ќOёЕ‡РьНcŒпBќ‘ћѕ јъЛ§Sв3Ђ|жs1ЯQc%КH•‰~ПB–ШСнHŒ­лBŒKл6,/Яш{Ч8FbЪ у„їrІnjцgKRШL§HЗюшnКЂBg2JТ№q„T6тEЮHЅАMMЛœ—5То{І~2І2e}1%Мї„g§fЄ=o˜_ЬЈšцl†T;—УбЧн’‚РMŽэЭ–0љЂХ/wb<9c%АMY‡4•Ц4ЅRHЄ–HЅаZ•bТ^‚ж ЅЪŠ] 0œ…U?%Ђ ИЮ3Ќ#эЙцbYc+AJЗ$OщФEFIPB"…*л}YП3ЕЂ‘‚ЊЎ0Uђc [yЄ˜Ъ хNњиhЄ*H!чТe,БїxpуT”§3К••ЛђП6_“йu§ўрz<(в)љŸтM-іФЛЇsю_*Ѕ^*•љ~в"рѓXњ‡ѓuћ^ч~ЏЃрї*tсЋ‚єПlч*~ša3ЊЩ˜Z= "FrVХlGkДе4ЕЂ™U4Г)KwМŒчtл‘лЋ-ур‰10ѕ~hg3ЊЊ!чLПэX_ЏИ}КAkУќМќ~ммж!В Yъ™Ѕj+цч šEU•РЏ'VЮЁДDW яЪ<;хX\іrЦM3 P–іlЦх7ЮiЯZ”1L뉛OWLC!дe!бжу]ТЛ ˆФ”юФ‹ЂЅ 0Е-^™BœќnRbmЂn%UЋБЦO‰5J–ьк4œПеу–§оsЂїМџЧ,.—„1Г~БСc7­ФO7DКЋЎf‹€)%Ц.0ЌЖlž,Ў6дsST­сќэѓ"рутЮUАЪ*тnkЂьі—ШTs+w7М,ъГ_ёѓGz(љџёџй[љлџоГг—ь_kpјЁмHуfГљћu]џ›9ч2›мЬі‰№Ф8ХšАХ H.cсz)Ё”@P’IеTXk™Ÿ/˜/чшЊ*k„R …@W5кZ†n`ьGЖ7kК› ™EqЬ‚ш|щŠ}бЗOЉ‚$H;ы]#uS3[4дГŠf^Q5eО]4чо‘’ЧMEWЊ"ыЋj‰оЭБ•)ъv)'Ju#ШHb—№C(д‡!}†(Ј„"ХL˜Ja$хЮePh@]о=v&Йˆ”k4ЙJ(-юИЙЋАŠ?‚Ъ$r*ЂCбЇМВЂš[Юп^ UІ_ 2я&”ЁvЏ%eBpSТ‘ш!К„2S |„р"Уv(rЩFЃ+Ў  SDHаІhH!˜†‰0љТнЃVcŸ„ЗКяФzьяля?^ѕћŒхoŠсєн:Х~H#_МxёЯ...>дZџТ>љпЗ“ўU_Єѓнn§ОЧ|чџЊзљe…Џ E8ХWuD,ЙqL|WЌѕDЮикPз5ѓХ‚љљ’йrF3›0#94ŠйТ0[6x7вЏ7<ЯŽЭгŒŠ ŽVEђжhMн(@bмщ (dki ПyA;kH)bŒFiE3Ћyќо%ЭВ"ФБhќ=a№DЪ*ъYƒЊ ч@(I ‰ѕЇІM@]V'ЯА.т<)цТpХыРV3„H)q8Ђ.Ц;ОOєi$Y\єD.:Z’’ТTБ)ыzdŠŸ”ф"pчј7v1Žt+Яиy–OѓKsr*\…6еH8R,кЪD‚K˜ЖчCёCІj uлаЮ$"ЫBŸ+DЦq1NХЊ9†PЦ VrЃ+AЪH„В ~D?aМ}OТhжџЮvУtњnт@в=dПйlўячччџю€BОљY_Uœ‹SМЊШК#Р’Р$hњ!•,Ћ‰FЃЄР(AUБœњlŽ4EЙpъњЭ€G\— :‚‰H-w’К­4znBсЇВ|DЈXішwz P:р]d{л‘T­СT0ѕC‘AоU )9fгЎm5фтxш'˜6 Џ298ђ…dqYб.ЊжЙŒDb)FЂпidШ)DР*вNP(ч„д­ŠlpNlВямгэчW$§Я$?њг—ю_{я)<р?§єгП?›ЭўЛ֘?КGіу€ЏВxШ№U]џчm|Z№eа†зщжO;ћov!˜Rz нzщ§Q™Ќ"ЂЮЈF`[К[)1FS7ЅŠИNПоАzvEедœНu‰БКHвNžБАжАМ8Ѓ[ ќ№џї1З/V„iBIXнЎhC`~vЦrО _œгнlЙyњ‚Z)ъZcъ^џКчъ/˜њ mЊ6шFЁMIŠОИd,ЖЉЉЬœљќ‚jQЃ­ЁПюи žскm§ЉШц.ЭЙќе',Ÿ, ЁЯ„ЁžЭhKЄQјq`}НЦичˆoHќ)“tFлŒдЅ+ъYбе—V3v#1”YzrХ+ ИDœb9‡T™!Чђ~HeШ)1mЧ‚HЄЬИи^Џ‰>љуYE˘!№H]јw9”ЕР>D$‘КШ Ыьb‰Љ%С;ЦэФpггЏzњѕHŽЉhДію|6u#ЪhьвЂыЊ1c&чdƒIУНЩџѓШ}?ьšЊSœтM(врїьйГџгЛяОћПЊ=№Г(NqŠЏИГ6‘мxdP :3и дngм‰VЊьРчтLчНC]дД„И3ЧY_нblUШ~QbtEнДeХO‚6zЇA_QЭДВИС‘2e…M—‘C‘i=р{ЯДщW§NЎж0{дRЗ5R[’з(tU1Д Y4ˆ\‘FCJB…J ЕUдF2K‰"Ыw<љц78{kmtыбe Fз„‹ЇA„4%’K…#Ъj„Х oˆИ8O=7иЊFЛ[”ф)&ЂKWH‚BjДMиЦю\ўС9КлŽ —7#нm‡T‚љy…жХ§08Qо—,ЪcАфбч2†Q лXЊ™EHЩИ™.1Ќ&R иж”s™;‚2ŠЃ39Ї?ћŽxќ^~СЫќ)xивWpbќŸт ,Jў0n6›яЮчѓџѓrЙќŽR*RЈ‡…РOkўeчMяЌяCњїОЄtŠЏ б?„дШLЎ<œд2бОciЮ$ЪВHХ„FBЮœ%R€бŠd-ЭМaqБD lиЌJчš*ШI2?kyџ—-ле–еЭ !lmЉк[W˜Нъ?F\H2Ђˆpы bЦI]Y†aBN5*•‹Ќ,ГZб^,Йќц#Т”ЙњС SП.ЗRQ5\О3чќн'дЫaРЮ,ѕВСT !#ˆH?9Ж7k6WVЯЎЙњш9ЯјŒa5ITѓšйyCњлžq=]132VAL­‘ДЖ2Юд!ЦˆВS*Ѓ‘Z3MŽргрШ§„#у62m=SЉZMеXШ!%Вфi?–.іР…Аш†РИ1•І>Ћ16ЂTс!бƒдЇ|!6ътU‚рCБ;ŽЛ‘Ž/уuЦ7€t”№wЌЪЯtћїх3r"žтЭьY­fWиO>љфocОе4Эk_ь“џa!pR <ХЯs!АПžd$Э\ŒЈG ЯЫŒ}ь<ШˆVХцWfIЬ|!ГБ‹бхv­ F•ЮXь„Ж…;гшQ‘"Ф ˆќ˜‰~dь=ЩУњљпrtAŒ5ЃаJЁЮ$CэШуЊtІ}$DGШe\б, um™ŸЭ™:@BЁ%U;cv~ЦљЛИјц;ЬЮg( 1ЦО'GJŒ6[VŸмrѓё5зПрњуkn?]HЬЮšyEГД;‘ЂВў—МТжŠшУЎi0eƒ"Bœ"cяpc Хтв'F…д1fЂЄЊИ'FчёcБ6ж`Њ лд˜ЪтM!ыI#аІœаT-а( R‡=СЩ;пzQQЯnHY]B'Д)MŠЉœ CЦueK2z.~с ЇяЏШƒыт Иїdјƒџ`<} OёFљPЛ"`кнЎ§с‡ўћ|№СeUUџњ~pœќя›Ѕ~™BрЫь§ПЮѕУŸ?oKрЋv+ќВ]§ јщїУЯndВ Фz"ЫDю&вВw Ёj4MSЃ—оynЏ6ФфБ•Ђi‚ѓEсO+leig5Ъ*„Šј<сЦ‰Оыиој)SЭЪDХF7‡ФАlc˜/j.о:уќ­%ѓЫFk’KЌ?]‘ЧDџbЫt;АzТ$АГšјФQзšщЩ! ‹‹–йљŒzйАxtСќЩšГЖЉVE пЌИњ№#њэ–œЈŒ6ša3pѓЃkn?ЙціуыB`эyУљлgЬЯ03SœћBnдЖ-ВШЊx*H)Ы*оTvы‡ЭHt!$RьЦ.впt ›žрvfYzйвœUЬ/f\ўТ%oџЪл\|ѓ-foП…Њ,1:|зуж[†›knОї1§vdкŒ;зР2!l"&O№ОёjW s+™ПЕ Нlщo;ЎДІj ЭМЦЮ*rJh+0ЖЅьЛžќq.ЖКBЋфyƒm&ВЯ yР;Op?Э§Њ­ЊЬоs†юz!ЩYа.[цчsšГm5aєИбГНъ˜zOŽeRЫђB _ Иоq+aЬL[ЯьМFhХќВЅНh ТT\ƒ+т}jЗЮh‹ЊH!чr№S"њ$л_Hяuпѕkю_ѕ;.NЈР)ош`Ќ9В јшЃўУЗп~ћщйййП-„PЧћЁrрБ’рЁСа 8ХзЌмзѕџxї?ƒI˜™Ф^Юh—5‹‹sЌ5яq§Hr89rL29fтЎƒUbBЋ5ЖШ”M€Šї|і™ьA$’EW™Œб‰К6,—Ы =RеІH7nШS$ŽŽaегчHеБўxE3д‹эХ’йх’Х“9gяžqёо’ъЌ-+mл?tŒы уѕšЭГЋOWєЋ-уv*ZJbэ“ЪJD‚L$M +m •ЎЪѓ“‚эЭ€Љ4Кб[d‡…m%С•Нњi;1ЎкZъe™злж"uACB($@R&L# vnбЕЦ aw)h‚ДЅ‹Cє‘~еяd’'†uя=9х2Ё•‹ПB718ˆc1њIЁј1ЋjІБ K5ЋЈцa*|…фH6ХŠXH‰Œy‡6”SЅHмКыјœћЕ§OZџЇјЙ)рх5О8К~OŸ>§Oœs/?~ќ—Ѕ”еЁXа}Iіо“эktЛЏЃоїКћў_Є(јК ƒзq<Ё?bр0љ'‘ ЙœqёAЫ|9Ѓ]Д`м t11) *#HUъц"›ш§„])Ѕ$кdc1ЖBыЂ`gkM]$‘ifА8ЋY>Z2Ё1RтƒcКоаžИ1Vc з{2™fi8џЦ[|ѓ_ћЮо}„šYЄЬЄ8бнnшЎ?e§щ-ыЏ˜Ж=9юД К‰р<)EЄQшЪ k‹ЉК6$ЋяО§В’˜Ж"яŠ{Ѕ‹TЎ;)^вN/?ЁЌBэ]я7Ц–НМj^“sBYIНЌˆб—џG.М‰FгЬыbЌч­_z‹ЗџшcъГоeње†ЭГ[VŸ^Гњј†ѕгkЖOoI1`ZД ] tЅIB!Д@YI&1uСeЄV…Їw3№‰9бŸБxь;w'a\O„1ь^ЏйY№†"ЇЋгŽ7I)‚ЉСдšjQ‘cBШ‚ ЪV€P e U[Юcчq›‰~=W>ЋFо˜ВŠ^JЂЮФ)ЬiЉГЧЭR‹пјcDm5Ж.Ћ…)epr!Cfˆ)ІD˜"гMјЇЋьў >+ЁўЊbрЇxcGтžQ@| љ~ИSпї?јюwПћП~чwўмrЙќЕ”’уƒ kїŸзеwхї§|мэџДчъ‡Ѓ‹‡Ж^еЙ›)§$ё&,n;ўуЯJ0ї0sL>rѕЃ‰@‰BH#g„RЃАu­ЪЎљ…<џhУЭ'3l{HX Є@’/DЕљљœvйP/Zцч79Мsфй^_3ЌЦ›žитЦG]ЊЊbvQcjKшЗO7ЬЯ|ѓПњ—я]ЂфФц“ŽлOж\џш–›Џи<_3Ќ;bєH“ЉЯ+fjš‹–jYЃД$ЄˆуvЄПqЌОwE†zб`ч–jІ‘&тЖя#уv`мŒ0RЅWЎєЗeжžГТXK‘мr†zaYМ=У.,18b,\ )эE ;ѓ ШLл‘”!8”ŠіQ‹Д‚Б.•B$–&CЙ\жџ”YО)г$S™ВЪЗ(E\МˆижА|k†m™ŒЎѕЎPй›"з{ЦmиЁ?EН‹„>LЋпNџЏЏџъўOёЦ#‡Н<<˜ќ9ўєгOџжjЕњ'яОћюџЈЊЊ?qИpМZwпЯ{2сЯxшo|™П}’§§9.ШЄкч#Љ СЬeВXоЖѕМaЖh™ЕTЕ)JqbЮ ›DUiТXDhєNŸ?‡Dž>э*щbЂ‡i-R H0n‹Œm ™ўj {жуo&p‘ЊждUEN Єf6Џ •СO лT$—и^mI“c\tW=нUЯДщˆо!DЦ4Л4дч–ъЌЂОЈЈ—-R |ФœHы„їЅУG bЮФ”‡ К"йы]Биn7+ї‰ўЊ'Уz*№Об-Ш23їS lЃаVR$ЙXШvB`+В(֘Ш)ФI *‰к'LЅбЕ&ј>FО*„ПR›ЅkbF[0UQ§“І((њaФT ]Д)В(ўхМc@ЛH˜"б{рр#9a!!9f†ђџ3мфGЩ?ё"рЇxЃGт(Щп—ќ3ŸЕNћ/С0 сЛп§юџўэЗпўГ———џC)e{п–РCЩёАИO[р>јіЫvћЏКпё уOSмш!Tф‹DA@mсIH+PY‘В$ёCљ?кz„€цМ)|%H!ЁLIќ)•dэЦHp™фFbkKГЈбЕФїŽ0yмˆ~K5ЋhЮZЄxЪњaЬ„БЌцPШ‚ьDŠ„(ўiпщџYњ-ќRv—§ЯїйŸŠ€Sќ\ ‡Ѓю)ŽYЎ‰Яz_G <}њєя]__џЮ;яМѓo.‹?'„Јяƒю€упя ‡з)ОlТќ*З> xБЧ)~FЃI6š‰\šКЎiч-ѓѓЫGsЮ/YŸџY zNpŸќЧї!Чѕ:3љ/кM їщЪџ$Щ§_ЅТрM*tŽЧLQFrэЩMЄ^VœcСх“GœПuСт|NНP˜ZЁај!Вўф†Бёnd'œжBdкEХХЛ—\М}NНhA€<уvdъЇ"4ŒИidЦтl‡ eAЂݘ™„FRе˘!ДРoF†СгoЂЬD$aђTѓŠzЎ™=jhЕЈж’ЁtЖЁ$Ыьцу I– D!О™™ЁЙœQ_ЮШY T]6Дfиa"_цт]1ябЕ)—Ц`ŒFJ‰REТwъ§uЧи9ТX”ѓ„’фЈ˜ж ЉB*ШЅЃ;єA*0­A(IЪр'я3еЂ$™Й&Ѕ€вcd\јб—5L2К.[ І8щQвЦзeЄЊ хkcy/b‚ЊqдRbъ"ђ„Є ‘Й‰§)e $†Цџ—{?9Hјюшт9qNёs^№лП§лљз§зŸПлšFЧЄ8чœџўїПџеu§Ÿ|упјЗцѓљŸЁј м›Dя#ЬэЗ іРЁ ё}мз9ёПЊ#|xUт’№аxтЁQР)ОzрЅŸu‚™G%ЊЅЂjlYуb*аrEbv{еqѕУ ыcяШ2bg7 фЂјЮЧ‹šžV(+ЉцDaСЛi]ћДSБ+uP -Ь FъЪ2_дФЩ3­'|ˆ$ >њ•gиN J7[Э*tmZ3DЗыјЇq Й“Љ—{_‚‹^IDLH!@ˆ %ІЊ@HДЉQІBз5PКrЉTёbЗ-P:ьœRYЏ[MјБpˆUЃJr#Сgb(Л7ё)<"1хт‰аgМф QЊFj…i4) Ђѓ?&§•7гЮБP!„"9ПгўЛ‹Amn(яiђ‘Б›V"wХKйiмuў;`ЏLКќ/WПўо‰п=€œрџSќќGEРМьu}L G(Рq•\у8§СќСаЖэп|яНїўм|>џ3Bˆі8y'ќУxˆxZE rа# 9≄T !д‰s„и№f’@Ї Ж0№ж‚™aKrщ!ЅBЕ4№6ЪыЎr№P‰„З@UZчAѕXdвФˆёxFs ™*­Qхс~@€)@Љ<ЊТ@8‚B:™`яb bƒХН Ћ{Ъг '?AРЩDУѓЄ„а1‘x#@( Лb 6e$c†ЮЌb`+`!5HјЊ„7БњBg:г€qќ/3˜Зф›љ{ќg-oП ўыч]z 6иЫE:д€ѕ Mш. ”=J@HЄЊЛwя~чюнЛяЧуУз^{эьяяџ4M/tu$"8чЮхA7СZJљTRaзXуѕk)eЏфпЅHєЬsx§CuРЯб R HЦіЖЄJ­[њМp6 !†PБЎ}БpШіFѓу§1Вйщ$ o Te…ђД€€€2ђГ”Б=m’І !ёфо NуА!ЫБvо<Мw A@:вЦс:67рвЁЬ-В*є$"ѕу€РЖpыvНžР™ЦјТЃ‰dК‡щёL!Цц [Ш”b™рa ›ЋхI…еW8TЋˆ}剋гћСT SxЈ™Фштй†šD ОZP‘ќH™i$““K1саV6З(KdГ *гHЦUЪ“ЎŠŽЉXЋ/=H2‰tšЦ&C\хP<)`‹ий}T bћсHШBaы<‚w‹й?r'ќАќmЯПџo‚џ`ƒ§ђ€žРZ шJєЕ"аL\“]ƒ~ћљlљЮ;yчЮјїЏНікWџцССС7Джуu›с.9П В!„ЇbћRFЃьлжTvUЮг h№є1 п|MN@фр8w@e ЧвМA(Рq€+*xуa gb!bšЫ}LЖЋ=gWЉГxЕJHиЪТreQ­LєЌЕ‚ (%A  ^9ТосюxЋ‡ЇБS-Ц2иZРоyЈqT*Ќё`ыыТ]‚(’xР‹ъTœ…œqШŸ”p…]ѕFуЃ ЩLТ;g*€H ˜`—L@т‰€w Г4pUМ Kј*zже*РеѓtєTBІБ|Ph‰р-Мѓ№†AuLž‘юш‘‚žHLЧЈVЪEY'у1dШ$Ж&і6€=Чpƒ"Ф €”€ёXyЯ `KГ2‘дw,!,Ђ’§јѕ$˜{ўПххОз!§7Ÿ›™џCщп`Пќ` @у„oЊымU_0ЊEšЄуuђс‡Оћс‡~W‘нИqузП5ŸЯП"„З5Е ўо{Ј:ъН‡жЬ|&ћЏU…ЕьB8 ЌЛŸ5 C{A;TАM шSvY7†'ЭГ„А lЮ%И”0 _ш9 ЇёTvЅYZT [2ˆc8@eБДN)‚ЖхЂ‡ц?'EЈ––Or,ю/` &F2ŠшМђ`‡Žeg$ .\ПˆЃ+‡x№б}фЇy=ŽЗОЈ‚GЙ0gѕёсc•)HЃbу!Р>6Њ–вЖtШчАEŒыgsЁтхj‹‚+‘Ž B*HMБмN ШD"iи‘‚/ЄŠ­IА ЈN\ї™„ШDьРФ {)%0рь*`uЇ„YyЄ{ у i$"SЫћЂ”oєXAЊњZTщ^!WХуЧŽсr‡тI я>E0№qл…”ЎЇр%**Y`”Ы˜щюr )вНi’@Ž4dІ R‚Y9ИТС;х§Sшг˜›Рс НcЧ -Р> kL/Œ@—Цˆƒєbђ ЗvQС­2јв‰2‚ ІВЦСWьzЊ1Й8L4ђG%dBHч2“gЅе"Ž`&)` •Лz|ql+,SPэсРDАЅGЕ4к"ЧоBF‚$зџj‚NБм/Р|Œ?vёQ№7cўэВ?МџС^IpN"аь Ъ@-2А‰ЈЧЏо}їн{ў'ѕеЏ~ѕызЏх№№№Эљ|ўZ§ЙgРЁй,Ш{џ” А~яlJ ќзпm+›ТНijEbhЋ›Рncѓ›—Ьw}Д“@ЛіН}Œ;GL‡H`%PмУLђ`С1cнЧrМ~vЕЂ$ "ЉЯ|&АYђQPRb<‹IЩX%Ж‘ˆ$бƒЄ19/Xћл[ ‚€Ш­іЇXЎ`r8V*€!8ЮЧЁ6!ЪцСХо4J 3вВюr‡рЌ;пљЪЁ\DХ@ЇBЪˆl>Цщ…p‚ CDнАЮЁGЈb_—[Р3X2иRн$ШРWф9ŽIж2‰ў’YРјB1™љ*Ю]ˆњbFfЩ4ЖFНэ Цџшlџ (&Ш €ЈЛJQ“Џz Ё pOјWрџt€йAкžџўƒНк` xъžо4CЂОАD‹єЉjAPяНїоЛяНїоwзпчwо|§ѕзѕшшшЭљ|~=ЫВYГ_@;Lаь&иєўЛHРІP@ŸgкEк нlwмTЖ€ЎжШ}jУyAіѓxДC#эФЭОяœчїлЏз6ј7п[Ÿ­\ и#ЄK‚L Šž?P—і1l;ЪІ’ RЊ“гС9qКр(СX d“ ЃљЩH…€+-ђгœБ:fЦ Б Б тУTlUХz|"јxУFJŸXуA  А №U€J$Цћ#dFЧ€cœ~В@ЙЈр}оƒ€˜,ЗА3„QMШTєœ ‘ŒьмЊ)q:ŸГхc‡хн vт `D№рЌ GйL#™Ѕ IАЋьЃЃ Сx˜E `ri 1ЫР N laaх‰сHSќuCJ„–P) ъ;›!VPT Љ 2QuЙСйWxИЅПSќџx‹ьпїj§Р"|:XЈY9аЬ‡Ћ[ЖСЎЄ`§™5!7oоќўЭ›7oЎПћЦo\ЙqуЦлWЎ\Йqxxјкd29Zƒb3LањfП€ОI†myЙ]jиќ\˜жыЗ‘„vnA№Л@НM>OалѕowіЎяu}Іяsэcиїљѕы6љh‡ €K?V№Т@Œ ѕd:$‹z4­€7"ЦА5ЧiuŽ&(EаЉB:K1кcr4 obV|№бл&Њ“MЅ€Жpp1O 0#O|p`WёЩ§?3џfњ7Ф;ЃkєлRтHˆZ™ HD&Ѓф/ЦyKƒтqх‹uШТЮЎP/„ ‰BН№eT#HB­4иТСWоАcTOк |™€в*Nм 1ѓО uЋbПYxыA2Ю*p6д1{ŠЭyŒC№ђT€ƒC?!b&Ч)…оФHЄeЬ А.Ю.XїE`ŽФЅђ6?ќ[ЖXЕ<ўВБмюљ?xџƒ рŸ_нллЛФЬдџіtТІчП-Fп™.j‚цІпиЖмG6хœчбѕmо\џ"žў6аЅ(4Ÿлпo*Я/OK–*жЮ „ Ш4fГЇ™Fš%‰„wХвР–БнЏb$С pжЃ щ4C2ЪРСУЎˆ3ыБ лвzрJќФBъИ­щ$L”ѓ^”оqс лгј?p+ўфЩwќэ“ПФŸЮCќНщ—хящ‘8ЄŒ R‘8(rЛˆлg+[xА‹u”HЇ „–1'AF9T7BЬр‡ˆt„$) 2‚j Ї.NДЬжњP•Ц8С†…аЁЃїюŒ‹з‘ˆaWyИ2юoЕАX=Ќbлт,VP €LbR_T/<Мѓа]71аГ,€рMœ}Є%ЁŒ—B}—Y—ў•?ѕ`яѓ;Шў§у~№ьЅ4ъьЯ§6TцvДЂё,d Й,7(rIш" ВE.љЭo~ѓ­/љЫo\О|љKѓљќЪl6ЛЄ”Jк^џZ5и4IАKтпГюRкŸm'nRњђv <p^iО­ŒДЗaЎщѓшћr*КШ@XПvЮ}њЗ8 CH-xbiy''LI&))ЁRЩ*vњ#gІД0Й… •Њ8^ $“ й|„t’@5œё(N ”‹еЊŠЊ“’№!ц'Ы'%˜‰ ] Ш‡ЎmaŸЙП8}Я}Пэ™Ъ1щЃП­wtYўSЪ™N5”’BРWцДŠёњВ Dub’"™$P™)QХc )H‰Hу>f6…Ў№Ѕ+Ca gЋТ5^уЕЄ’Б 2$Є ${–оС‰˜р=УWBK$3Ы(ЧrWХI=вHі4в§Є.$˜•Eё(GpБ Г3veA ауиљ08 ќа§ўђўДРПЈ @бЁДIЗ”ЭsчЗ 6и+GЮIDkЙMЈEКHш{йCdы;Я7п|ѓђыЏП~эјјјкбббейlvy4h­ГN ЙЧля“Ќл озˆh[€]кo#Лџ&ао…lўчUњBЭџCs€T“Ќ—1їЌЕ'Ц™SЫUю…-indr(G—дЅlOэщБ F R#%гYFЬ@Е4рР*О‘:Жм•ZF/”ЖВЈђ о‡x‚з-ƒСQV/W%ђ'LхР,‚ИЯ•ј WєSћˆpђ}Гг№LЯBmщqpјЗдПTњ5l tУˆS§Œ B’iЄГй~=ŠёџрЖЌх}ысL= 0Фу* 9–рmщsЛtMюЖ№ЙЕ^zя8#‚"Aт8: a EИ™™H•ЬbBЄ7BвЇ9uШ%јX™QVБЂ„dЊ1Й”AO5Є’А…Eў ‡-\=‘ыФB@jе'ќ‡ЋїќџjХ§ЫŽGќнg%§`АWžl ЭƒЛ‚>•@l rЫCt)П/&oП§іѕЋWЏ^ŸЭf‡“Щфp>Ÿ_‘RfI’Ь7yЛыхf"ZѓЙЋгр. K!8"аѕў&RАЉзС‹Јч§n‘iWxяЕіОsюБ1цЄЊЊeYоЋЊjQХВq.­IЂcŒв тptE^еsqAhLЩУЉ”’б<OЧ™jэŠXžF‚ E”В…*Nљ3•EqjИ\”!f•*ЄMЩ$!HСС3лЂтќЄЖВо•ў~ШљЏэ)}п>фЎnљŸ <“œжŒПГwФo$ЧќЏРxC B:бHF J p|н&WAO4Ц‡#Є{)єXЫ]щсJћъоФфE*НЗсФ•ў‘9ё?syxфLXr`Ї,8% &Š™00РРX$bœŒ•’Š’рƒ†„RФВПuGCЂЈ`, lюсЫ™Id‡ вi‚ŒCyZС•БЧA№БЩ œгŸяѓ№K~RЏ6ш tћ}aщ ƒ `wU /Tа$}Є@twп{]ЄAэ@(КHѓA7nм8žЭfГkзЎ}Y)•Ючѓу$IІI’ьeYvDDiˆnЫ%ицёoRЖхœ‡ Д ЭgEЮ›А~mŒЙB(ЊЊКыœ[c•eyЯ9WЭ=сжљ&zТM‚R5ІQz$Žф”˜Т„=l:{“KЩХЩеб•t/™ !ЮJ‰R ]ЯІЗБ‹пђAnїsУ!иdЂhДŸъt6BIЧЬЮУхЂ*mi—Орм‚TўдП›р?рpж”Іъ&бyi’H'_У?S3њ:ЁTgщHCHЛ(ЛЛТCj‰l?Уш Хш`•ХT!g=lлъV ч!TС‡œ–От;Ў wэ"|фJ~ $˜ HC!! I‚|$Г,Iб„$fЄq` ‰=A”AbN3С1y2Жќy ьо2\щ`sA$дXBe ŒИ/!–@ц~Х?ДУwь]ўЎ?С}<нžМkвпЎ‰/їР`xБ0Сњ&‡–2pR 6€wŸšАm]зomкŽ3eуk_ћкыЬLЧЧЧз‰HfYЖ—ІщfГйu"‚жzЎ”šэ*ћїyў›€ПєЗ„ОFзїњР&ђB№жкŸеђќ#я}юН7eYо€Ђ(юYkѓхrљ ,Ы%žYн\zbИЭѓЈMњЮТE2ЅLŽ1eт„=љtŸВcyutYН‘ьЉ‹z$g$„`&)Ѕ*•B% *­“OЊ|yЇxДИ“?ђ62%$3=NІ‰’Ърй0ГЗ…; 6<єKќеъ'ю;ен№ іR-ž-Mу‰iWФ$й—№+Ѓ7щ_ыTМЃ“:сБнЎ]9Ф*“10OIз2|№ЬЎr0+LnйЮИвUЎт‡С†ОР‡>Ч]ЗфCЩ'С"'@‚ ’  IBЄ MSJ0‡Р‚‰0ƒТ’И‹`ЮHP O7}Ž›~…ИТв„‡ю„Oф ћb‚Ф$$‰‰`Ылю6ž[ю[ MкРпчљ`А|СШэЈ<A;ЎЃ>пѕwЛћТRJѕж[o]@Zk}ttt…™Љˆљ|~m§š™1™LЎ­W23в4Н$„HЮгLЈMЖyёЭu֘Ло{Л~П,ЫоћВ^ЯUU=6Ц,зџXcЬ"ЯѓGЬЬЫхђбjЕZ { 5w€{и‡žяДG]їЉg€4I$ (f5Ёqz(.ш xMЭpUхE!)JLd"GzЌF:‹Cq˜Њ'ц“ХЧх‹OЪ}$‰д„Іj$ˆ@9XфЬСйSџБЙЯmюё=іЯФЅлБin] ВE4€„ВНoˆЂїщŸK-ОЄT0рЋ‚gЎ+HЅ’d"IjРС‡`MАОrЮšА&,|ХŸ„ wќ †м’яГC ‚Э `x˜HЄЄI#‘cšRJs‘т‚„ЦeRЖќФ>ЦЬGќ“жuŽјђ–хі|’ЎqхЖч˜КЦїžџ§(љЩїЯ}/Р`јlЩРy AWХУcпumzБeКЖЙы5mйtмH7…[žВууу‹Y–ж7ЏO>љфck­яЙ)wyGлnиЁчЦЭ/ќ}ЫшјZŠR›є•JJf4вpQясВкЃK$)“#БЏЦb_х‘ЉЉд2ЧЇц‰ћёъgі§ќ#ћŸѓ AސT†œOC‰•/yХю)ЉпДЋЏ=ѕ—gpЭП)79”ПGŠ_gЫŽ}=@‘ЌЫ§<†лр8їžЫ`јQАќ8јШИчO№3_№Ic{7ѕЬo•И­Yх“=зЖ}пКѕпѕ$Рu€ўЦ)ПЅЬxќ_н/є8ˆС^Y№„ :иF ЖyцлРЛШЯ јb‰AЧMRьHv&Ло“v\ц-окЎрпGЖю ых>ѕЈ]!ђLЏ PrŒЉc*G4ŠДž‹}=“ѕL\‘#Й/…`щ}тџЊј™§`uлў4”\Б‡с№Xк/Ељ№ч.`žЎ”iwа|j чф-ёvzIќ&4ОЪ%3kH(–§”PВУ‚ђ`№-žИSўФ-јAШyСс)рпuhm ѕ€Mч6œ;ОƒДŸ›^џSЧішw4ХфЩ‡Z `А_№ ьuIсB…‡х];џинїyЈZдLл@5Ді=fаДœв4ЛFП&Чx‡PБЧ’-NCОФiXёЉ/9gwV‚шzЖеяH6‘cl!и‘4Us›|Яё|ъ=њЧŠIШиР(ўЄР`ј% }%ˆb‡pBhcР П№ћЖЉы§m€O€ч9Gv•џЗнИЗIЛЛ(и@ИCіяыщоіЄЛ*tKboЎ'‘B‹„RDрPЁє%іOyяО\ЯsћѓэуCр*7і\3BЃfДч\ДЮ—MqѕЖŒоGЧц`ду§c рї=w)BmР=ч рш)ˆ@Рƒ?€С^^SЏр>ѓŽяЗglеч! Л~ŽЖџЎЫиряѕЯMяё†јЎ^н6u-рпFкПM[Ж}оtW+щvЮHиф‰n[ЧшЏа€эыsа$1].] @ш!)}’њ6АФђŽчж6Х‰б_кЧч<Ч`АМтФ`›‡н—€п$я^чТyТ›vИIѓŽŸлє§./ГЮщЋhwl'6gW…ТЖJоўиrl#}},Кёšйѕ}ŠFWЅo!ЭиСћпѕќЮ‚:/СР`l+9РАЫ{лHФІїЮј/z^№ŽыЯCЮыѕёsў=єx›лVЕCѕ•Џ›Ы7%/n ]l:ю›HчЮMЊz€>BУ;€џ&НЫЙКmпЯŠzek ƒ `АЯфxяR›Пiнyтіє 8vёЌvНaПшКѓмшw™\йзгЁЯkоЅЌq[(уy$ъ]ˆРѓ&тm*ПмІTœ7ѕy›_р<Р`ь ѓ?y‘ј§сџ~ЉѕydYўџ/ЛЬІи4wMLф</В/}‰xЛдмmsщ9її•@Ц 6€Сш њ[ќ§­Яƒл3збšчѕюљчИ/8ЧО`Гыігќ<Р`p 6иpэєшy@ѓчјчн—MЫиВэ/m\} ƒ `АС{оkh >o.Фсž№<^љ€Pl ƒ 6\O/1PвKО§lАіE=œ@ƒ 6и`ƒ іъ™С`ƒ 6и`ƒ `АСlАС{ьџхаƒДVу&IENDЎB`‚fwbuilder-5.1.0.3599/src/res/Icons/48x48/0000755000175000017500000000000011733011756020230 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/48x48/fwbuilder.png0000644000175000017500000001657511733011756022737 0ustar sylvestresylvestre‰PNG  IHDR00Wљ‡ pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХFЈIDATxкдšiŒdзUЧo­WѕjэкzКЋЇ{КЇ{Цг™xЦЮŒ'и1ŠƒŒA&B )F$ !E( п%ˆП@Є( ”8A >a‚‘ХvŒиЯxѓЖЗЗI’„8Žџмї§Лlлžp]w*“ЩT$I§8Ž)•J?~œ§ћї Žу№шЃВББС_ˆ(Š‚№Ч1Зоz”ƒ †‚ˆ ŠHЂˆЌШ$ щs]зe8ЄЯ”_Пбž={‚рЏ …љ|žЕЕ5vvvаuAшvЛ\О|™лnЛ €гЇOу8еjЧqО0?v§P№ЗРУI’X?б€$с „дEQˆЂЯѓшvЛ\ЙrMгиооцёЧчиБcДZ-†У!/^dii QгпlmmбяїџАйlbYAЂ(њЄЊЊŸ|ьБЧ„_fи|њгљš‡G‹BЁ …Є^Џ'ћїяЇZ­rэк5жззб4L&ƒ,ЫH’„ЊЊ\Йr…_|‘ГgЯтК.ЇOŸцЙчžcbb‚ћяПŸ{яН—#GŽ№ЉO}JxЛr 5рљчŸgll,Љеjфѓy>ЬћоwŽc“$ I’E‚ Эfйии`mmFЃёаТТТ§ќрП}їнwK–eБББeY4 yф‘фmOтЇŸ~šѕѕuсHіьй#\ЙМФїŸљ.э­Э4šЭ&Мћня& C2™Ьп'IB>Ÿgff†жжжшvЛЈЊњ‡BЊЊВББСу?.мsЯн<ѕнoвяїЩ ШJ†уЧsз]wсyŽуЧ1AаыѕиййС0 :—/_Цu]4MCQt]чОћюОёo$oЋ’$Ч †a Ы2Ђ(277‚DМќђЫ˜І‰a†С`0 пя3 АmпїQI’X]]E–eŽ9‚ЎыoПFу5ШˆЃˆfЃIЁX"›Э†!Aa’$ Ђ(ЂЊ*Q!Š"I’ ЅR‰~П€ІiМэIМ{xQ ƒЧБ)KЬ/`nnŽ|>OЧ‚Ю7QЁы:ŸјФ'xшЁ‡FЯ§…QшЫ_ўRіgѕ@Ш‚ рљ>wмyѓ “|О€ ЩђђВ`ліO=ˆ(ŠxžЧSO=…ЊЊ”Ыхџњв—Оџ<‡ўТч?WLр§IТЏCђ+ŸџмчTQЯI’Д†сs‚ |іG˜иѓМЩхr–e™0 Љ7і$`YVE‘EQVхЇm.žчqсТfffМ љiПyјсПUUЉVЧn‹Тш#ЎчMъQ_—‚ ДЖЗwиккња;/~v„ŒЉŽуќЎыCзu?ЧёIQ%г4‹ЎыђГDТˆ/’$С0ŒпџњзПўф›}яЋ_§Špњ•3Чxe;ПСэЫЫЋr&“ЁP(е2Ј•­­6[[э4ЗvїˆљюНїо0ŠЂнммќјˆŒ’$Aг4‚ Žу”аF3ŽcЂ(Jg†ЈЊЪииѕzzНОєњCџёЧ?ІYЖ}‡(Š–JХwEQ|,“Щˆz•саРЖ–ћ§­жŽутК.ЊЊ"Ыђѕsj'!I~јaAРВЌћЂ(zbqqг4 ‚€(Š0 зu У0хЯѓ‚ЯѓвАQ…Z­FН^'ŸЯcšЦнЎыМ8?ПџŽS'_љНNчžvЛНЧВl!ŸЯS(аu]зQd‰ЫWЎA ХssГAˆ LNNвjЕА,‹ййYс†$6Ms”ЕJЅТммКЎЃЊ*qГННmлxž‡išИЎ‹яћDQ„eYˆЂШцц&QQ,)‹(ŠЪ /ќ№ЏOŸ~u&—ЫU:ћіЭp`ažЭ­6››[t:–——‰Ђˆ……yЧA’$dYІT*‘Эц8th­V‹zНNЁPрЉЇžb~~ўFъѕz#43™ ‚ Ых(‹зCЂŠЊ*DQЬ`аЧ0†˜І…eYlooEУсУ0№}зuщvЛœ;wўhЛнІVЋaл6››mrЙ,яxЧ!^xсEt=‡ЊЊˆЂ„ Рии­V‹™™іюн‹Іi4›MŠХ"Ђ(bYЛЊќмЙs7ж#ЭRЉTє0 yђЩ'9zє(333”Ы––ЮsтЅВoпя8|UЭ Ы^ZЌŒЪВ,zН–e166–2Аmл8ŽC†дЊUцччH’Y–i4ЬЯЯГА0OЃбdџў§ЈЊŠЂ( ‡УДiЗлфѓљ‘ўКбƒС`”Акмм“““d2жззq]—^ј/Ÿ8Щъъ*gЯžхиmwвоеџИЎ‹чyDQDЅR!t]gzzšSЇNaŽу ŠЛœ)ˆšІqфШnП§vцччi6›d2Œ #Т0ФЖmЮ;ЧM7нDЙ\f||œ .аl6o4Рѓ<т8F’Є=I’ ( йl]зoВВВЪ+ЇЯ чS(И”J%п'—ЫЖm“ЫхXYYС4MdYNeЦZ'''9x№ Змr $BІЇї’Щd$ пї1M‹dYцвЅKœxљ% cHН^ЅZmр8нnїF*• ‚ р8NЃлэ233sЫw7wl›••цfї1оlр\Oш(ŠRˆ]зг mmm 8vь‹‡qѓ‘#ЬЯЯS,ЩfГЌЎЎІЊлэ’$Лo?I$Iтх—_Т C’$цкЕkDбЎ„Iљд€\.G’$ EзuЮŸ?Яфф$SSSфѓ9UСЖm†ЦюУ\зУВ,EСu]ЧIумЖw  |>ЯЭ7пЬьь,ћіэcTc sзuSЎ)—Ыd2™ДDэїћˆЂШЅK—1MQ(‹„aцз †AЧŒЉууу†СоН{)•ЪX–Эƒў6GХї†Cзu‚зu ‚ %МЉЉ)JЅRкiАm›L&“ТёккZъЙ­­-ІІІh6›hš†iš„a˜riš\Иx‘B>‡$IhZ–NЧ`eeхFЎЧЌт8ЮИЂ(#FЅR Z­2;;OЗлEQLг$—ЫЅю У~ПOE)G zНЕZ . Š"ЅR г4йjoвяѕ€rЙ„,+ЉчrЙм.D pпћяennз АЌN:Ѓ\H Ию%I§•W^AзuvvvP…RЉ„ІiИЎ›†кH^ŒєQ);;ŽCЛнN якЕkмqЧДZ- …_љЪ—)t67лфѓ:ћі„a„Ђ(фѓyA Š"оyјљМŽ,+”ŠeDQDQƒ“““hš† ЛTЋU UUхаЁCиЖЭкк–eQ.— ‚ %*лЖ‡8ŽƒištЛ]DQDгД4I]зхмЙs4›M‚ рК.QбщєXZКФxГЦXЕŠ(HX–•ц‘,ЫLOOS,‘e9}1#Х`YO<ёУсpзEQEQЪd2J’$Œ111AЉT"—ЫЅ!ГЋoЬф266†ыК4›ЭTЖлmЧIн|„0мeс‘jЂˆZ­F†)Ыцr9,ЫтєщгŒQ(˜ššBUU:žчсћ>ŽуЄё?jA€чјДћ|_њ–еKxлХV)б'„_dръеЋФqœžžVЦЧЧ‰ЂлЖб48Ž8ѓъž}іynП§–i0>>žЪлL&“ КQ3вSЖmEŽуPЏзSТRЫВЕь+• šІЅ(”$ Ђ в7z|г§'фй˜šVag#Dб5ВjkЏ3'ч;уЏ—гъХ‹ё}ŸХХEІІІ$ I–q‡ееUЖЗg˜›AU3(ŠТˆє‚ @гД”ШvvvX^^Ц4MЊе*’$aлvŠH‚ Є ;’тллл)ж+ŠBФ\ьŸЦЈЖ)Фз&№гE‘$"%Щi5yNшt:ˆЂ(ЯЮЮRЉTxњщЇЙљц›i4Фq„ІeCЫ4ёМзXv$AzНН^пїё}ЯѓhЕZ<ћьГИЎЫњњ:Й\Q™žž&Š"vvvˆу8mэ т8f0рš>'{ObћDGЁP-Бuy›`лЅ8SЧ =Є‚АkРЪЪ йlіCЕZщщi&&&8pрхrIљЭпz§ѓѓзc6ЄпяЅєŽЎыLMM!Š"Оя“$ §~Ÿ~ПO1[І^iЂхUЧЁлэІеU.—ЃP(0вdЃМŠтx †‚ ЪХ=:іІWY;ПFчЄћпƒWƒџ”‚ 8кjЕўФѓ<†У!Оя†!йЌ†ЎымњЎуЬэ_`}m-Н+p]—8Ž1M3ЭI’v1ћz- $"­.{п[Ѕ3v•b{‚Р‰д˜$ЈеЊ2щKEY–YZZКіэo}чяN9љrѕЈќ;ƒ›Мїі6м лЯ;џИЊeЯˆЖB“gˆй’ЏЧпёХХEТ0d8Eб BM’$Ц*H‚ `0`YVЊУ0ФВЌыI3йомсдв Є.ЦэY:э92чIДŠГ\й>Ә3AFЮЧ1gЯž]ўоїОїЇNњ"ААѕ\јЬжsnиПї&­EпїЯž=Ытт"ƒС€ѓчЯcYЉˆ%ЂeY ‡ClлЦuнДcKKK}“Ћѕ“d~зb~ЎˆoК”Н*о5мъ:—V-6jБЫ=šз‘—+Oœ~щбW_}ѕQ`ѓ =0ыњќёНQY–ƒчЯŸчРLNNтК.kkklllEОяЇŒЛЕЕ…чy7є‰EС1]ж.mbdwаяГ‹оаЇЈXЛЖI^)b\Ccэду‡МК}тљWОЖўHКПp{]Х[F†С`@БXЄT*Ёы:Ђ(bлvN#Е8R‡N‡С`РАg0л ˜6А”•+{kьt кУ99‡Бc3шИh%Ё/И R3Ў!%6б[ИЁ>jЬJ’”Ьˆ”LгL/1FЗ,+Жх04фh.ф\Шъ"nл!1|ђb=­›юЈ}дЂ†k€Бmco‡m"’ЗtС1ъŒŒx}wДuЬFJuД‰=AпwЩPC‘#мЖ…Іkd#‰0Дй<(–ё=‰ю†IУі:Ї6ž6МЗtС17%IBХtОж Nnј|ѓ›jѓ bтbДи]б9&ІуіœnФ`н"іdGDжDŒUїћ‘Пњ–oh.^МxџеЋWПešІ/BJч’$Ѕ†ќ8ЯФQB<9 \.Г~rsХ&›ЈJ›чVpлц†˜(„v€šЯˆbkЭщ­^1 ЏыЛgTUНmjjъИѕж[o=вjЕj™LЯѓв9j†iš˜†IП7`;Y&йЗ…ZQI22Гk|К,ЈЙlЮъ8t6‡hу9Рw\ЖžБОh_Šўє'AфЯkРыGF’ЄVЉTš) -UUыŠЂ”5M+‰Ђ˜‹ЂHq]зqЧЖ,Ћ~з5§nЄЙек-й_ ЌdЙwЮ§gA (ЭK&Š’8Иќ›Ј …$&yq/ь'п$й%ЋЗ4~Щџn#к.…ы ƒЗeќяW#мыfBwIENDЎB`‚fwbuilder-5.1.0.3599/src/res/Icons/24x24/0000755000175000017500000000000011733011756020214 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/24x24/fwbuilder.png0000644000175000017500000000714511733011756022714 0ustar sylvestresylvestre‰PNG  IHDRрw=ј pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХFIDATxкД•ЯOcUХ?їЕв(3PZ&•Ёƒ4,ˆ‚bЂNbТvЬФ8њш’нФРФ•Xш F6&f5.не@:!$BD† !ЖЕвїкїЛяѕЙ‚Œ…2иФ“мЭЭНпsя9ч~Џ‚€N,,,ƒƒƒЬЮЮВОО.VWWBЕ^ЏszzJ>Ÿ333‰ ­X,sТм™L†H$ТUКџ3^IАЖЖфr9ѕхЙ••• ‘HЈ7!ИR"г4P…X,F8Ц4Mъѕ:ЕZFЃaДлmкэvЈшІщццfДT*™щtI’ˆD"шКŽЊЊFБ, г4‡666šнъ\gђэЅЅ%Вй,–e166†ЊЊT*ъѕ:SSShš†ыКC@Г’Ÿ|ќсжнш'''o(Š‚ІiLOOS.—БLƒ­­-іііЮ#ћZ;џ™ •JЩЊЊ2??Я№№0Жm‚ххeЊе*еj•§§}RЉTЄЇ˜ !’Ц}љезWzе“DЅRiЊЏЏээmrЙОяP(Pг4‘$‰JЅ2еСффЄИ{ї.X–Хјј8бh”‘‘ђљ/=u6Юы^xIŠЅёxтэИ–у"Ањ(ЧўфDyбѕ›ДЂЩ{ƒШФЅ~„•ямO~3ђŽчЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХFі\IDATxкь§y˜œgy&ŠпЕя{UWяъERoZZжf[Вlйl˜@АЭ'$œЬE2pТ/™L’Ю•$“L&™ф LТ’™Уa и€ё^d[ВжVЋїНЛЊКі}Џњ§ЁО_ПѕЉЕЫЖŒћЛЎО$uЗКЋОя}ЖћЙŸћQеыul\зЦѕіМдЗ`укИоО—іR_, o‹›№аC9ъѕњfў[™IџєбG3?яїУh4nXЦлфR]ЊxЋ8€јУ›ыѕКРіЕї4\Џз5њъѕКuэ[ЗЏ}Oƒ‘_ЯпзЎ<€бЕП'œ№йG}tjУl\oй рfКў§ПџїƒѕzНoЭ ћжŒй S­V7ІђЯЋљšJЅКЊПЏ]ІzНОлnЗcїюнЧ<ЈКх–[‚ЧkукШЎђњиЧ>Ж[aш}ѕz}јb|Н^щз.ѕuН^mлЖяЛяОsgK&“БoлЖЭБQl\Р%Ўпњ­пвдыѕƒѕz§ €ƒѕz§ FЃБжыѕuђѕrз’№ЯОООђ;оёŽёююnw:>FYl\з†Џп§нп5ЩЦЎVЋа_ЮШЏзмШЌ€Ž ЙЙя{пћ‚›7o6d2™mС`odKѕ§я7€‡М рљG}ДДqœ7Ў›Ўјф'?щЋзыя№ўzНўŽ5`юŠ ћjљF:‹§i2™№‹Пј‹йлoП]›Щd @ЅвЖ—МуŽ;œЏ“сы|rэУДіщ€'| Рc>њhlЃиИn №єгOФbБQЛнQЋеъd2ЉFЃіd2‰x<ŽJЅrЭ‘џF:Џз ‹ХrIуomm­?јрƒuН^Џž™™A,vQ;KоsЯ=ЮзСјя№Oњ.ёmе5g№пК–Ь`Уl8€цОќх/wщѕњY‹ХГй ‹ХЃбˆZ­†Z­†\.‡d2YŽЧуКx<ŽP(ДЎSИZaГйрѓљамм ЛнЇг ƒСПпшььМЊїQЏзQ,ЁVЋёьГЯЂZ­^ъл“їпџ s>ј Рпеыѕ_QОІЫ\Б5G№…G}ttУl\o8Ячkљ|ЩфkȘZ­†ХbЭfƒнnGggЇnЧŽащtаыѕHЇг…BXYYСттЂ08ЅБЋеjtuuЁЋЋ .— mmmhnnОрgГYDЃQTЋU,--ayyЅR еjеj•J•JЩdѓѓѓhnn†^ЏGЅRAЕZХ‘#G№ƒќљ|ў {@јР>ЎVЋџЊ^Џ;” ЄJЅК?С рЗќіћпџўoјєЃ>zfуиo\o˜ЈT*ы~ОT*!‹ыt:И\.xН^455ЁЗЗ{іьJЅ‚Z­F0Фтт"–––NЇббб––єѕѕ<€ХХE,//уфЩ“XZZB0D<G>Ÿ‡^Џ‡VЋ…Z­†SЋе„б—J%”J%‹EёqцЬёљRЉ„JЅ•J…bБјК?˜}шCУѕz§_дjѕюыр'ШРCkŽрw}єб…уПqНю \._ёїхr9,//‹Я™L&455ЁЙЙMMMФО}ћёx/М№Оёo`ll ууутџ№Уh4Т`0Р`0мАїЃVЋ_W№KПєKVЁVЋ?!ІWbќыeЪ,РCѕz§ОїПџ§ рПot6Р›’\Щ•NЇ‘NЇ1==->gЕZёБ} ащt0 0туuMTЊз ѕ+Пђ+›5Эq•JeЋеjзХOИTf RЉЌѕz§ЏмїР|р;пљNxУ6Р›š\щ%— oЦUЏз_7№•Џ|%іЙЯ}No6›1;;[›™™QЫŽ`=gp­Ž`эяwжыѕc>јр§пўіЗG7ЬaУ\єњќч?пYЏзпрШЧ>іБ“o–ИЎз‘"ћтПXмГga``@Нoп>LNN"п0Jѓ:Ž Р=єаžo}ы[™Р†И№њ—љНFЃљNН^п]Џзё…/|ЁTЏз_№ џќиЧ>6Лоџ]‡$sCЂ№Яc‰DЂў“ŸќGŽСАsчNƒAЬЯЯп№yЩtЊTЊpз†Il8€ .FѓжыѕнввK~Ќ9…˜ьъѕњ+џјЧУ?o@ЕZ}C†ЄВй,~ќуcqqїнwЊе*VVV^Яy‡;?јСоїo|у‡fБс.ЕZ§+Wp˜мѕz§ОzН~ŸфfЛККFТс0 … …Т ‰оЕZэMЛaхrљ ’8NtvvтрСƒPЉTЂЭЗММŒX,†ееU1`‰DФ€VН^Ч<АђГŸ§Ьwј№с ЋиpзФФ„oeeх˜пяw&“IлхРЕ:ЛнŽУ‡удЉS єпu2’7э†ЅRЉ7M-YЅR5р™L™LЁPSSS пчѕzEiхp8рїћБuыVшѕzqЯKЅ‚С RЉTФh4џіoџ6Зaр‚Ћ^ЏупјЦžџјџу+‡cG:6^ŒzzНЮС`0`яоНшээХщгЇБААpSeщtњMsцŠа@ €@рТ’оd2СсpРыѕТхrСfГСэv—џєOџДЅ^Џo8€ АОˆХbјќч?Пяз§з'Z[[›‚С “ЕхЅЦPЏ&+џюѕzqїнw#NcbbSSS"e}ГЛ7к§љŸџЙf?ё+яџћm333˜ššК Кp)–NЇБДДјпљ<јрƒ-oц=нИnrРkyyŸџќчЗ~јУіѕѕ-,,,t2ПмкЕf vЛя~їЛёќѓЯущЇŸBЙ\AБX|г@РBЁpCР_џѕ_[з˜”ябh4\лqЇг‰]ЛvaзЎ]X^^Цєє4цццPЋе бhnИѓ!V cз†ИdjљйЯ~ЖљР;пљЮhЅRБ,..e‚Ъе:‚‹9‡У­[ЗТfГaa~FwМ™@Й\ОІљ†џўпџЛC–@зh4/зщшш@GG …ІЇЇё­o} їнwп wђŸз†Иь•ЯчёЕЏ} SSSž~№ƒЕ={іфcБ˜vvvV—Ых.)Lq%j6Z­===иКu+Nž<ŽП§›П@0x^}З\.ПЉ@ЕZНЄАZ­pЛнкЯ|ц3ПБЦЌыЋзы}ІљjuљwГйŒmлЖaлЖmЈеjBТьF]jЕЕZmУ l8€Ћ‹GХШШˆњНя}ЏщЁ‡ЊнqЧ•@ P™œœ42J_­”U[[P(№™ќ;yёљ Ђяхк„зrЙ\.ЁG˜NЇ…ГБйlЈзыЈT*ЈеjСіэлбккŠzНŸЯ­V ‡У“ЩDЃЕдыѕЯ_ЏьљzWЋеаjЕЈзыт5оˆњ}­и№рЪ.ШBЁ€я|ч;xц™gдП№ П ~я{пЋ9|јp-‹%—––\ЁPхrЙ!К(3FЮ­[ЗЂЕЕ}я;јзo>‚BЁ1еЏT*(—ЫШfГ7ŒАb4бееЏз{У–мЈЯ]ю{Љ‚T­V‘ЯчQ(ЎiPJЃб VЋ mХkУ\u ™NЇёЭo~?ўИъяx‡ъ]яz—kзЎ]Јзыѕp8\\YY1ƒAAухџгjЕшююЎoйВE566Šџі7ЅХѕѕ*щn VЋбооŽЖЖ6ЈеъNqОкЏ]ЯзЕZ-ККК …022Гй|Mїc#иp7${ђЩ'ёмsЯaѓцЭ8tшjїюнЦссaдыu„УсвЪЪŠ> ТуёдћњЖЊjЕšъ|іяёгgŸОL§}^Сїz€лэFww7ŒF#n4ГёѕЪ”_зыѕ№x<№ћ§№ћ§0 X]]ХЪЪ RЉдUgr)Жqm8€k. фЬ`eeпћої№ф“Obhh}}}иВe‹~xxPЋеTO<ўoјњ#_E.wљКОRОО Рd2aЫ–-№x<зЬOИбЛЏєs:Ўйg6›Q.—199‰gŸ}ЃЃЃШd2аh4№x<з”h4š АсЎ>§—ыzYЂšуОЕZ гггXYYСK/НПп|ŸўГ?Т™г'ЎјїUж–w”ЫхЋТ4 6oоŒююnQч^/?сFўЙоўAВєЬf3 4 …тё8Nœ8‘‘LLL T*AЃб@Ѓб@ЏзЃVЋ]U›’ЫUјчЦЕсЎ9ъѓQЩ–rыџ\[ЁљљЙЋњ}ЕкљізеД[[[qЫ-З4дХзЫOИ‘ЮСjЕТхrСэvзGйjЕъѕzНXN2>>ŽййYЬЭЭazzZ0јфўНв™\ЭИ4GВпLХычPћжrД€Z§ъk­F[ЌVЋ†zН~йзmГйpЧw ЃЃу‚зw­ќ„Ћu\NbГй еjсvЛЁRЉ`ГйФчљНхrY5>>Ў?zє(ІІІ§љjю={љз’h4š `У\ЛбЫFХШЯш/”ЫeсЎ6ъє  FGGaГй„aq&^ЋеBЋеТbБрж[oХwо —ЫШхrащtb‘вXkЕZУxЌ2ЊЊT*Б=˜ˆЙJЅ‚нn‡FЃAЉTuКVЋПWyХуqDЃQœ8qбhЫЫЫЧЬЬLCжtЙ{Ѓэфз{5€ыЮ6xрšъeД$g]ŽќмСЇбh еjqЅ~•=kV‹ііv‹EHМиЇеj‘NЇa0`6›aЕZсёx гщ [Ц)фз+Nй[зщtТйhЕZh4,..BЅR!“Щ`~~еjЋЋЋHЅRXYYi=уЯ–їѕ8`er5 T* €ŽyукpWt№”CyyИ+• ДZэug­ъњхƒT>ŸЧГЯ> 0 BЯ]ЏзЁзы…6Ёви/іoйhcБвщєпwЙŸёz]rіu5 P(ˆ @­Vodръ2€ѕкrt•ІlpЕА“VЋ ОŠяНєСЯхrјХŒyНПпlй|WувщєЦ4р†Иzу_ЏНиЧz‘tэ?]ЅаAЅК2РTџэp)яїеtdАqm8€ЋўжЫ ж+ фг\m гiЁVk7РeЪАЋЩbБ˜p—Ыš6Ў pЩЈ4і‹•в7]u бhЏ№{Еы:­ŸggР?Џ&`чcc`У\Жо—[}—3ЎѕњызkŒчбwн;€ѕ2ŸчL€<€ЋqсpX~Ў`У\>Ъ\ЬA\ъ{з#з\НаBЇг_бїОнZZз›lррЊ џJВ†K§§j/НNНСpEпћvdЕё9]@AРы}6злИ'p#˜NЇƒ^ЏПІп§ѓlєЪїz5 —Ы‰џЏVЋ&Бс.jP7В†ЎзыРUще8€ЗыEљВ+Ни1X#™7юр†Иae€‰•eРЕitz= WXМРП‹НялnЛMЬ„BЁKОйYЈTЊ .№†И1ЕўхОїZTmЏ&И™zЏwРї|яНї6|=#‹!" ‰ ‹!•JЁZ­ŠŽ‰JЅЊn˜Ф†ИсѕПŒ0ѓЯkYё}5рFЪfП•œчф‹ВaЪЋ\.У`0`tt”?#Лaр†Ш‹eзЂэЕрэКюъJя‘FЃСќќМLи*m˜Ф†ИюШ1У—Г€kqzНюŠ1€JЅђЖt\АzЙ+NcvvеjuchУМОзz‹ЋФЎфrЛНи1М^oгu§ЮЗ‹ИTP,155…L&sб{і…/|aУ2о"зoќЦoммрb\€+YБэtКБsзnДЗoкxвWXr]Ќ с‡Ус xџРF№КПђя—*Ќ6;†‡wcѓ–ўы2ˆЗ›а%€< ‹Хpюм9„УaЁЬњ_љзћћЦum—ЩdИЕVЋ§?еjэ@ЅRѕh4ъ’JЅJЉеЊ•J}Z­RQЉ№|._<}г;*с\ ГяRktхe4™АgЯ­ш‚Z­Йncx;^МЧcccC,ƒС`втыЉ +цл­ƒrЃ.ГйјсZЕіыхJu_&“k`UVЋU=якЧцѓвhд9ЕZНЂVЋцT*еY•JuLЅR}3›Э—n№|Н^?xЅ%ŽЂZ­ mНо€н{іaћŽ[nиПаx›9•J…Я~іГЈеjЂk" Ў7ВЭЋP(|іяпПaЭWx:uтЋекЪхЪP&“ЛІЈU­VЭ6Џ}ФёF]QЋеIЕZTЋU'д*ѕI• /lп1ќвэ~PЋе*l.g\—Ъъѕ:Д:vнŠ}ћoПbtџ*nъліP‹EhЕZaјЪ(Б‘юJЅђШ†I_жр§ЕZэw*•ъЫхЪІZ­іК'еjU РГі1рУjЕ Я<ѓtНR)ЗМуя НQр[ЕZэ/ъѕКцrЬП‹e ЪЯМуž|SS“‰ъК74ЕЙIдmо,`MV_’eйж3ўZ­†rЙ<ћШ#й0ё Џ“'^нQ­ж~П\ЉМГT*7Н‘Y%СйjЅ›нŽііvИ\.еKG^4НaРЩ“'ЇnЙх–Јеъїj4š+6ђK}}zzzНоT,Ёгщ гщ FЃ1g45‹ХСЅзzн,zot r1WfJХІ|>џљ Sэ:ўъбћ*•ъя–Ъх§ЅRйіF • @НЋнююnиl6,..тєщгXZZBG{kѕuwFЃЏОњ*г‘п­T*їЉеj§•D5™єs…YƒБZ­ …Ъх2чд‹jЕ:ЊеjГzН&“ ІЫd2](ащt7Н&РЮdЃVЎgЛдЖсBЁ0].—џюьйГokЃ?zєх_ЏT*)KћЪхЪ**ЉVЋ€њyщ{›ЭŽ-[ЖР`0`~~ЏМђ .ЊХљКg№Пџїџžњ№‡?ќ—•JхЯДZэUзЕˆ‚ЈT*€жjЕŠBЁ Иk;[ЋеVыѕz@FЇг…u:Ыl6Џъt:—VЋѕшtКэ7ѓ{НВЅЁ+хУYd2™пўЃ?њЃЗmrnvRЧ~ЛP(ќZЁPьЋTЋъ7жшеЮ37].76oо •J…™™ќьg?УТТТКs47ДTОJPтЏмЉRЉю~э \:њ_Ъ \ЇREЅRuѓ@—J%TЋU„Ус†Cўvš \fУŸмP”Щdўюџ№№62z7€ћ<р>ŸлZЉTP,–P,•P(Q,–P*•P.W^7Ѓ7™L№љšалл‹JЅ‚ЩЩIќ№‡?D xCIYWхyф‘вУ?ќ@Й\~NЅRmЇ‘]-рFЅЦ—TоИ.pеjFp0 …Т7џѓўЯПїѓ~ŽМјќюRЙђЉZ­ЖЯhаЗщ z˜LF ЈеjiЇЄљьЄP,"Ÿ/œw…ЂpW‹GЉе*FДЕЕЃЛЛЙ\јюwП+„Yп РјЊЁђGy$љ№Упр‰zНО]Љ'1‹їыљЦžœТЕ(2­З Ѕ\.ЃRЉ \. РџљѓjєЯ=їгЪЅђ'ђ…Тў|ОpQЅ#Н^ƒAЃбГй“бЃб–Йf“ fг…€{.—GЁXDБPN"Ÿ/ˆgt~ Ж‹шююF4Хєє4^zщ%$‰›‚~}MНВGydљс‡ОР—U*ећ/ЖZњJд‚з‹о—‹шoЧh/Пч+uЪmAkkЭ2ЕZэЗ?§щOџЏŸЗ{єЬ3O§AЉTў@6›нY*•ЏшlW*•uг4 L&#ЬцѓРh<Пкh<ЯW1›M0›MryМЖ%К‚Ѕх6mк„žž,--azzЯ>ћьM)РzЭЭђGy$р_§е_§3•Jѕ)•JЅс–йѕРЈЫъ‹‘S”rт7ƒёПяRяѕjŒ­ЧЯБпS*•ъƒџѕПўзёŸƒійЇ§•rхwђ…ќ3™мІJЅrУLЙ\FЁP@<žИрЙX,f˜M&ш zTЪ%$SiИ\И§6MfhuLNNтG?њВйьM=luнl™/љЫђяџ§ПџvЉTњВJЅкЩl@Б.vˆзcЊ]Ъ \ЊўЃ№€7Т ]Яяя_ЇгъѕњўПџћП/О•ўщЇžь/•ЫП—Ыхп“NЇ›kЕ7> фr9TЪ4љ§к6€ІІ&ЬЮЮ"“Iau5ˆ§з}ЫLWоКмџњ_џыєG>ђ‘нg&ŸЯwžpа@Їг]д@/е—^Ќ";+нNєvЎћй§аh400™LХПќЫП|Kџ“OўшPЁPјЯЙl~*vОЏAЏгСl1УяoЦРРьv;fff№Т /`nnхrПє№оrїі†ёeџПџяџЋўУ?ќC<‘HtЮЮЮТяї7д;ЪU][!ЮьсrбќŠіoІПšїІЄ§ЊT*˜ЭfX,hЕZшѕњЗдЖдЧџўЏ …ЄRщНЙ\ўMб‚зыѕp8ьhnnСЖmл зы199‰'Ÿ|ГГГbл[YKс†цЕZ­оd2!•J!‘HрЖлnC>Ÿœ-C­V+FS/—Ц_,к_ю{оJщўЕ:9к“дsОFЕУзщtдИЉ*ЬЭNjЊеъЛ&&Ї?ЙВИ-›ЭНсУ*• zn„Z­ЦйГgёиcaffІСрTnшMжыѕКZ­FƒZ­†––„Уa”J%фr9дj5A@‘ECu:нE)ЋJуИ\wр­V ШY XІ|Ў‡‰ЯН^ЛнNКДшmKк/љЫк_§е_­мDFя№№FушпŠў­(•JШцrHФ“ШцrШfsШfВH$“7єЋеj x<lоМ§§§(—Ы8uъyф,..ў\+&нP`4M$Vдj5X­VdГYшѕzЁв›ЭfQ.—8ХБ]ƒС ЏЈjР.ОYРыiќJІЂlќJЇ(Їјѕz:‹&“ zНОдЂќXgЂoц{ўоїнЯчџ ЮЎеj—ЫЉВЎe,6ЛN‡jЕzНzН.Їs].“Э"Ъ ‘L"›Э"“Щ!•J]бkаЈе0hjjТРРњњњL&qцЬ|ё‹_D(zлШЄнP`0 zНZ­еj6›M<# >—Ы!ŸЯУ`0РfГСjЕ z.Ћ ƒ>‹EХЗк%gAЪˆNC—Ѓ=Ы'=г{й№§ЯЏRэЯЕћцy3РЗП§ЏфrЙO$Љ§‰dВ”G.ј~ГйЋХ‡У‡УЋеЋе ЇгБіu3Ьf3š|О ўo2™B&“A&“E"‘D*•BhѕМšйlFss3†††азз‡@ €ббQ<ўјуˆЧу7НбЋеjиэЖКЭj§G•JКщ€бhд‡асp “ЩžОЬG—B"‘@*•‚Щd‚Щd‚йl†бhМр0Ћеj‘№!]lЦ§fu ђ@Ž\ЛЫg™DмDЏзУh4BЏз ƒ—гќѓЌГзўЭћХЯёџшt:гѕ>Пўѕџ§[Й\ўсH$ВчjыљdВŒd2…х•Р_;яЌАйЌpЛ]АлlАкЌАY­ты‡Й\}}[ Vk№ђ+Џbhh§§§˜ššТшш(Оѕ­o bЮЭщNŒЊЕ:ДZmсняљwџёfХŒїЙЯН%"Ннfƒйb†Juўьjз2994 7ЇxьБЧœvЛНЁn7›Э"‚3њгe#‘KхП/іwљџѓsЩdЕZ NЇ•JхP‘†ЯЫ?OŽцJАMŽфЪЯ+ыvЙЖЇQРтт"Ње*юОћn,,,ˆŸБй‰FK–ГІї‹іЪЌAv,зћœПње/пšЭdџŸX<~hu5ь|ГŒEЏзЁЉЉ [ЗіaяоНp8Су?ŽббQT*ќСџ§ŸnzШfЕТjЕBНіЌј< ‚в№зŒzНўцtѕzн)G-іЃ­V+*•Š8ьќЃ…lpŒўЪШЛž ?јГkЕ …Ње*ЌV+ђљ|ˆЦa 9b—ЫeadФ$”ˆFЃ‹Lх"ѓ”,Eй љ3i˜>ŸЋЋЋтu_ ьЁс+ы};Ы!eФ—‡эж0ѓЕ<л/§ПџыУщtњзWУ‘}ёxмјf‹С`@{{;њћћБoп>шѕzœ”Эe]бX сpјM0z=zzzБmл6ьйГЕZ GХПќЫП`llь-CЬ1™ŒpЛнаjДЈ_ФшeУЇЄћ:€юыvяо}ЩЏѓІъSŸВ*Љ‘r+oDЙ5˜QYNхl`Н2@ЎХхˆžЫхP­Vсt:a0D=.—4|ЕZJЅ" šNЅ\.‹пЯВEЮ`ж#ъШпПžіОь\.,‹Ш8”п/‹Ќ(?%вЏŒјrк/?‰`d~ійgQЏзqќјqќўяџ>vэкјФ'ўЏ‹Хќ№@џ›Эz'‡NЇУіэCиО}шЕЖ]$‚H8‚ее0Т‘("сТ‘Ш 5‹Х‚оо^ cїюнШчѓxс…№їџїАёnцы<СШ ƒС€Z­. žЦ­4|љыtіВЃЇsПY3€&ЉьШђ“/ОA9к)€ВпП^§MƒЮЯuчѓyT*8шѕњ„Ц•Ячa6›ЁбhВ 9SPЋе(—Ы =zљчЌGPRжџЪю’зы…йlFЉTj>•Pr*Ћ4ўKE}хЖEр˜žžF:Fww7Ој…ЯэHЅгПЦоЙВhЊVЋјС~ЛнŸЯŸЯ Sš›§№ћ› бhрѓzсѓz10а/нз:‚С BЋЋ‡#‡У…ТH&“W…zїіnЦў§ћ1<<ŒееUМќђЫјєЇ?ЅЅЅЗDj…Bэkƒp5НœоЫ‘_iєЪі­œUЋTЊњ”ЙЛn№Ня}fГ?ўёЪšXюeЫ‡YюыгXdВ2š*гY%Ÿ€QоnЗЃZ­Тчѓ!›ЭŠ9йШЭfГ0pў?f&ЪR*З/хЬрbдeeл‘T]ЕZ ЇгйаY/Ы‘я<;Ёl ЪFЁlk­W†TЋU[Й\МЏPШџю /<П? ­+w‹Х‹Х1>>б№yЏз‹І&š§MhjђЁЉЩПпЕZ…жжДЖЖ4|ЉTТъj@@Ћс0VWУШfГЧƒООѓ оЎ]Л0;;‹ЃGтЋ_§jƒLжЭnє:MM^<ѓЬЯ†pша!D"Faш4zЙІ—3ЙѕZЗJЧ.usn№эo;wюDН^Зб d0KnЏЩˆЖ T)‚I•ŸcДЇбАX.—yШb9_ъкэvфѓy‘~3Н/‹Тщ‹ET*ёzŠХтэBАфћPvжуШe 1›ЭЖ–жDЂцQЖ/ѕoe)ВоО?~ЬЭЭ§і‹/Ој;зњЌN)>пож†&Zš§тOЇг Н^іі6ДЗЗ!ŽРчѓBЃбрпОџCьнЛЛwяЦщгЇqьи1|ё‹_|KАё„сhЕhђљ`Б˜ЁRŸ7кљљy˜L&x<Бš4m9НП_уbFЏ,Йo000€ёёqX­VgЁPИ ž•o˜С`hаTrзљ•‚‡™‚–FЃQќьJЅ‚RЉ$„р\узыuб…`ч™ёЃбирX84Gc”[‚rыNљЁŒтЪv%Г ›Эж0!{tЅAЫэЫѕєжгMXЯј%%`ѕыбЋŸ›ŸЧмќќрЫх‚NЋ…ZЃA__?>ђ‘_…С`РЎ]Л№Т /р3ŸљЬ[†Чѓъї7СjЕP]бm6дj5ššš„рї(^ЮфЎЦшo:№Ъ+ЏРуё Z­КыѕzаGУ‘Иш€у›UFQFq%‹?SЏз‹tФДоd2‰ŸoЕZЁVЋѓ‹б–)—С`б^™V1[Pv$”Џѕb<…ѕDМ/L ‰1№’1ЅA+ ^~­2ШЇф;(ЫЙ§њz^.— Лvн‚Н{їЂЙЙYsТЋ9ќе_§е[ЦшU*ќў&иlЖЕзЊ‚бhКД3АZ­аh4№zНШхr"бШЅ›‚ЁyХїуFЫм_ЗАлэШfГАX,N%ћŽ–(КМŸ^ЗфНі2њ­ЖјяRЉ$jjГй,іpГ03 ў|e]Ь4оh4ЂX,ŠNDЉTF*уr;RЮж#)џM ’ПC> |Ь~јoeЂtPы•3~љuwxНRтЮЮN уж[o…ЭfУщгЇё­o} ###(—ЫјŸ§МU.ПП NЇЖЁƒE™єtŽFX,ѓ„УaСђ\Ÿq1ЃПœhшM—˜Эf czzк^.—‘Ых„Б+{лDд•їbm,ŒcЙPЉT`6›…a1жщtТИ\.ЄR)T*С7`›аl6‹nЃ1#< QоœУЈЉ$(ЩК4f›L{цЯdљТlHN§”…ѕв|љО)KЅуz%пгЬДZ-Жlй‚;wbџў§аыѕxѕеWёЅ/} ### ЗТX­Яч…лх†v-m'`Э€b2™ФЖнno˜WQЉTтЌYзи}Ьˆ•ЕНВыu5Ц}Ѓ‡мЎлЄгiœ9s&“Щ.ƒ|ђДпz§Kєz}eЁ4’Z­FЁP‘•ЮCж$рпKЅŒF#*•Š@eхШ,7 VNћe’П&Ї\"Ќо)Чš•ЈНв№Нвбё{XЂЈеjБ@Uо‚ФLFжdTŽ_тНuыVмrЫ-иГgT*^~љeќѓ?џ3Ю;ї–SЬёz=№zН0MтЙгрЩ_ЁШŠ^ЏЅ%бв3™Lт чwjЪeЏ\я+лШWcмћoЊpЙ\ˆЧуH&“›dЖпk}б‚эh(ЪIОѕkFR~ЏœОЪлmˆ №€3uЇрƒфџ%?@Іђђ{иVTіт9н(crM&ЇрJЗвРљuљЕЫm@ОWйИљ{”Ÿ—&ЙђpU6›Хђђђ59“ЩˆююьоН;vь@ЉTТЋЏОŠП§лПХќќќMЇuЙЫщt ЋЋ Z­NœІъfГY€z4dљƒYГN:f~ЏLњbчGiмзТgxНЦлЏлlкД [ЖlС /Ма|фШДЗЗ7№ъiЌL••` œіЫ=wy`G vS`§U.—EД“#Ў,5FNП< УшЏ|8Ъп/—2sБMЧ|mђчјЛј;”р_ПЬXyЈdM*ЉШJ< —ЫсьйØžž†ЩdКb`ЕZбооŽ;wbpp‰DчЮУјУЗЄbŽУaG{[в™ ŠХЖnэУъъЊшХsћ4 ZЏзУfГ‰2’јTН^оoF{>K*1W*qхѓ-†‹Х011щщiл?јС›Чј§~ŒAЇгщT*BЁ8Єёx\?ы$с‘Щ@ы”ВL(•Jтgёчѓа3 +•J i˜œ)ШY…мъЃё+гwЅ1*Е •-8ўш“q:!ІїыЖRYйPvфїCЎУии&''ЈЬ—rVЋmmmшыыCoo/"‘fff№ју †З’DVБTBx5‚§ћї 0/žHТd2СыѕЂT*5tф>=3#;KFfђЄ%яЗ|~ф!59(ЯЫЅюgЁPРддЦЧЧ‡yОU7UP*•ААА€mлЖ•3™Œ. ŠУћ'ђ'шшш@?њњњ„сЩЉМœгhжkcБGЯžZ­&|2ћфРпCЃ—іzДcЅŸœтЫFУЌE6*%fЁФ.XrT* 1(%Зœ!ШЕž<Ч t8ЪЮ@Н~ž’ЛИИˆ•••†Й‡У{юЙџјџЈштиажжŽM›6ЁНН@ГГГјЩO~‚\.ї–Kя- 6mъ„лэЦЋЏžZ“PГŠ~НеzўяMMM(‹ }zfЃFЃБсьЪ+ŸCY—‘RvђѓЁƒg`“ƒнЅJ€zНŽХХELLL`~~ОХКyѓfьоНЛzS9“Щ„[nЙБXЌњсЋЋЋxђЩ' ЁRЉАИИˆххe9rНННшыыУ–-[D EШ‘Зь”ф!жђ|Hьйгkr,˜Ф9CPЖ*/wИхЬDюH'ц LйјоиmАйl(—ЫHЇг Р$šr H.].†“аЧуqФb1ƒAAцз­V+юНї^ cnnЕZ ‡шшш€ЫхB0Фддžyц‘]Н•Œоh4Ђkг&x}^ ЏIЩЩ RЉTУР ŸЉ\ЊЪ“ЌЬ0e@šŸЃЃ–чJdЎЄ‘+СX,†щщiЬЮЮŠNZН^‡зыХ№№0vэкEfk% о<РbБРхrallLѓќѓЯcЫ–-јФ'>ёёq<ёФˆХbЂw?55…љљy<џќѓшююQЇЕЕѕRІФXшiЋеЊa­ћмЯžХ+/Пˆx,ŠHфќшЊЭf‡лэAя–­Фо}З‰У х_Iќ‘ABF2Ё( DЪ->ƒДŽšИХљ…’Ѕ†V‘œ%Щzђc*•B2™D,DЮ\Ьf3>ŒН{їbyyЏОњ*ŠХ"ьv;ољЮw"рьйГXYYiР7о*Fo0аеЕ MM>ц†Оf ф{(3cf ђ§•ЯyБXФммцччЧХЯ2™LТŽ;аббRЉ„t:……дjЕвM•<ёФшяя‡Z­ж „B!$“ItttрўрААА€ЃGbttДЁЕИИˆ`0ˆ“'OТd2Ё­­ mmmhmmEsss|~жѕfГYDxН^H$ŒџњWŽ‘3ЇжiSІNЇ0??‹Їђ#ŸУю=ћ№ў<oУd"Nй бхr9h4С.dQЃбˆНФT*’Щ$ЌV+bБ’Щ$|>Ьf3ВйЌH …‚h1q.A):’JЅЫхЭf‘JЅ. )Џ}шCD0Ф+ЏМвррjЕОљЭo^щфfЛt:-6mк„––f˜ЭVaє2хV6ўѕv$Ш™ГPх šЬЏ3FyJTЮ(‹Хтїп+ѓTјЬТс0ZЯ[ЖlСіэлбззШfГƒ"ЃU‚Ы7…иЕk^zщ%шѕz5Ѓ_.—Умм‚С :;;ёаCСjЕb||###˜œœl№„ЕZ ‘Hщt333PЋеpЙ\hoo‡ЧуžкхrС`0 P(ˆr!ŸЯуѓџќYЈеРЧ~ѓ№zНhmkD#,..biq'OЧЪђ2 …<^xўЇxѕиЫјрУПŠлм!€Й5ШіЅ^ЏG4…ЫхjXoЦ ‚u6AБXй ї"p0ІX,"ŸЯУbБР`0 ŸЯ L€Ž!‘H T*!“Щ —Ы!N_@7VД­[ЗbЫ–-xт‰'P(А}ћvœ8qBdrgЏћ­ri4twwЁЕЕFЃщ‚I:FyЖшdv?/Gv~NЩвSr6”ЪNђŸЬьШ)сЙQт12hœL&EаЃJіyђ‘ЁPH8юl6‹h4кPМž oЎлœ:u VЋЙ\N­зыQ(`БXФƒbєГлэpЛнxшЁ‡рt:155…ЙЙ9ЌЎЎ^ €S*•ЧХCдыѕbа‡Ю   ЕНПtј—/xmЏЏУЛvспͿ͘žšТcп}“( јђ—Оˆl6‹Cw†бhLТbБƒС€D"rЙ ‡Уl6 ­V‹t: ЛнŽD"!"RЉT \.‹ˆ^,aГйFБИИˆpјќHlБXD4E&“xAЁPh]яjiiAOOкллбггƒT*…h4К.ВЌ<и7љ†0qѕtwЁЙЅvћy%ffFЃQИмГчзdСbE2А,ѓѓeqY9КЪэTYЏx€,лЮд_ОЏ2.ААА€P(„l6лтїїїc``~ПџхПќёщ ”НЙ,љ—љёљЯўѓoЎИџўћёФO \.Ћи+eЪLАƒtлX,†t:}^ЭхТО}ћ`ЕZa2™ААА€h4Šp8ŒH$"Œ‰^šuyЉTЦЅеjБ0?ЛпrЙŒЏЧфд,‚Сдj М^|>/кллАek/z7oЦяќояу‡џ}їЛЈзыxєлп€ЫэСРР`ƒ‡зh4АлэЂ (‹Шd20"mЇЉJЅB:F2™„Z­iz"‘мf <ђˆp™LFDŠ„ШN‡žž—tvv"N# "™LтХ_eЪЅі#аЙоЬ@{{lV<€ххX,Aн6™Lp8ЈеjpЛнтНаˆeЪ7#29"0“ЩerJЮ”jO<{ЪЩLг, ŠХз/смЙsˆХb lиююn ЂЋЋKьӘ—І(/ххгцКn гщЧ; u:0Nо$ЙХGЧ‘JЅDЋХыѕbыж­‚^ЏG.—C2™ФЉSЇ RЉрvЛEЭкЎX,b`pЕZ Я<ѕ&&І‘LeзœFсpбh ““г8rфьнw †‡wрОwПЕZ пь1TЋ|џБG'Фn=œX,&RЩЅЅ%!6šL&aГйЁ‰i?Їm6вщДHћyˆ]Ш5%ГhkkCSгљ!Як‚JПпЙЙ9ЌЌЌ`nnЏМђJCћŠQˆ”`хЅьћпl@[[+zКЛсpКpьи1T* x<^dГ9їpЦžлІ ƒ0NІќ2аЪГСрa4‹Х„уPЮb(…X”TюШ(ћњМŸВ^тгO?-xSSњћћБuыV‘UЮЬЬˆѓЁью(_‡R%j=ЎЬ›юдju“RаCž€bъТкz=я\ЉTH$D РќЛvэ‚еjEЁP@ЉTBЉTТJ` Z­ cуX ­"KhЄлђчѓy<џмd398x+ю{ї{pњд),ЬЯ#МD&“l<” šL&X,‘!$“Щ H>Œр™LFьFTЉTHЅR00шшшЮТщtЂЕЕ>Ÿёx‰D‘HбhЧŽC 8НПLGцЁWК2­х}М@KK3zКЛбфoK ьМКNbБ˜ЈзNЇpЂFЃQtSdAW’Эи ц@˜ХbA>Ÿ‡Ус@4]—МЅЄsЫ†ЈфІШLжJЅ‚x<.рЪ˜ОО>єѕѕСщtŠК>™L –,ЁВ\“5!хPžkЙЉРš‘јф›&зRЪ‚RЄIв“ІгiИ\. фѓy1tСя#јW­VE`6›P*ЌЌЩ‚Hr:Hc8~ќ$к;ZБiS'ю{ї{№…ў'T*eБАTV(вщtH$ ЕХœN'"‘ˆШNќi4lоМY,юДлэLdкЇгщ F‘ЯчqєшQЌЎЎЂ\. PXqfTЪv"X~ЩJn)ђАпшrЅ—зыСммТ‘(КS€LФ!хЖЉЉ +++BчŽT.)хв“x4Зл •JЛнорH\.WУ§)‹тkr+O6<™Юѓ‹Х‹Х„ДГƒЎЎ.єііЂЃЃЙ\бhуууPцМŽdў Žыѕз€RЎKљA‡!_ќ~’}иRЊVЋАлэьcєЩfГтћѓљМш(SUEXжШ#ХѕzНxtrХњ’Ц"ƒ{ќyВюТХhУ2z}#/ЋеŠСС~ДЗwРnw4,1Q.О?фвEVШe†@Y-Ће*АЂbБЧ#иЅRIt xЏ™fЫJШ)Ѓ-иЕ*‹‚Z-ЯBшt:twwЃЏЏЭЭЭ( ˜™™С_ўх_тпј†pЖVЋяyЯ§ИѕЖ§иЕkXHЯ=ёФ№ђЫ/cяоНаыѕH$АX, р-A>Њ[Щ­Шз+ ИюгаппББ1Ћ’ЁDcЇк#e&“i OФуqQCмЩd2 йНБьБ/ь‘з/p—ЪжC{Yыг ' иlЖ†1Oжѕt<2Я›s ќ946<ЙU% І№{d 2ЃЂмКbЋIж$X)Гзd­хИ№*L&Ж ЂЃsгšt–ІaДіRЫ/”BАœс™сџЏVЋ(‹"Ыхr0™LШхrАZ­b5vБXd:Хd258Oљ=0ЭOЇг…BHЅRык‡?ќaЈеjD"ŒŒŒрШ‘#јГ?ћ3ЌЌЌќЭ~<ќ№ёоїОG№dкђ/ўт{166ŽT*%vfъѕzёћx)GGМ@^‚ћz‚ЎлFЈT*_ 21M–W„E"ј§~бK/‹шюю„Іg…BA<<Йѕb4nœœ_lЉшz:ўЪџKА‡•5c,ƒЫх‡/™LŠШFЃ’“i~:‘KЅR‰ЌA–AЃ#‘ЇЫ˜аШк‰JmyђQˆУ(ЋЎ4 ш_УI< Q^ЩСgъЭЫBю13”лrЌУ™Љ1‚“љi4‘ЩdpfALЃ‰№ѕEЃQx<ž J€••СзрНsЙ\иВe њћћёЕЏ}MdЏМђ *• Ž=ŠO~ђ“т|<№Р/тџПУd2!“ЩbddK‹ЫX^^V  bїžншяяУ™гЃˆD"№zНŽ<—&“I”JQ››NєеW_жЖЮ*7м2ђЛ\.h{Ноггƒh4ŠBЁа0ED˜#—RКKY?]J­їbtZ9%ЄXЈQt:’Щ$ ƒ џј|>9hЌt)5 ђљМxЙ\ND,йЉ JЇг"§у€ЌюУ{УУЭЖ*;%ыŸВњбU­нн]аыѕИ§іТp•‘^YпаSю5”љtxrыWю–yœ•лЭFЃЙ\Nt‰ДZ-l6[УЬ…нnoШОіЕЏ! Ѓ7 иВe‹`чхѓy$‰у, XXXРЇ>ѕ)Сyљѓ?џмyзЁЕaД122*ЈОчЯDкБ1иl6єєУсД#I ТnЗ78%FƒH$Зл-Pr­X,b||\S9€Ешх•IђF"ž$pаŠХ"Жlй‚t:-fГСй2Љеj‚,ЄгщЭfХZ-y|s=p1НўK•LЛY V*d2‘вГfdTч!]Ы‚P,…:,ЩDфpJŒэE–E|lƒЪeЃ $ђx*A#хЮљ}_Љ"Z­Ц@?6oю…зз„я|ч;PЋеhooG*•‘U^]MƒgЄ—`”›ф{.ЯWШ еš9sOš8ЫfLrЋNЋеТnЗ7d…‰DB№ˆnWWанн}~~$ХЉSЇP,КlUџсў!Вй,t:ўцП§мzы~Ќ,№Ѓ?…t*н !/Џ”[^\Dџ@?ЌV V–CbVDЂy~љ~гщ4ЌV+ццц055…••шt:УMW …­sssшшш€Хbi@|Ых2Вй, ƒnZZZ8№KKKЈT*шээ}sŽК–ЫeX,‘"ѓ ЩTa6d‘ŽЫiї_ŒёU*•P(„w–S<У9Дa*#њ\v!;Ю№3Ъ$“I‘эфr9ј|>‹Х†м–ь_%gїBоy@`KОгггˆ\b‘чР@?zzzрv{Фk’—}t:@ІіrД—5іј|фe/2HЬCПом‘y‡.,kэbБ(И!ђ3Шd2‡Уƒ j<^Џƒƒƒшяя‡йlF4ХФФ„0z:9YмЅRЉр‰'žднџ№>Š[oнh4†ћЗ'ЂЕђ€(YkAАЙЙfГЙBЬЌцччХд МpЧчѓayyљцqnЗ^Џз677‡™™D"єїїУjЕЂVЋ‰vG,Л€еUЋеаммŒ‰‰ ›Э"N‹ƒЫ”ВZ­6HR)ћЙ2ИрЗ^6Ао%ѓТ …’Щ$ккк‡6ЁVЋ…Ј„йlШНJЅ‚ЧуA,ЏWЇгСjЕ"“Щ P(РщtŠRЈX,"N УˆD" щНNЇC>ŸТж3ў^"ЖY32Z& LNN 'лммм8tггЎЎ.xНчХ4ˆЙPOžšѓљ| E7dvЂЌЋЧЯЩkсјoj4Ъ6ыa2еjU ќLЛe'ФhЫN ЁŠD.ŠJЅ‚ХbСрр …ѓ ƒ‚i)—4кІІ&LOO‹nУ“O> шм䉇щƒ( xќ?[І.і!ЗЊѕН({ђљ<вщtCц5==ееU$‰†Еr;wюФЮ;бжжVўу?ўу›Чиl6иэі:AЇd2‰уЧЃЉЉ лЗoQ‰šўˆХbШd2№ћ§˜œœD[[Вй,bБZZZАiг&LOOЃRЉPm=~ЛМдъЎ‹9–%LЭIО!=yqqэээЂ4bl3ŸЯ#›ЭŠнv~П_LџЩУ*м^DJ(gH ІZ”йlmIвЅ)oNU,ƒЩd‚ЭfЉ?U€GGGБИИиРVѓx<идй‰іŽvєhзœŸЅ[qr яvЛ‘ЯчE*/гЅЙQюмШ)Й,ŽЁ\C Еp$e\Ће"›ЭЂRЉˆy ’Ч˜ Цb1,,,ˆчE‡ГyѓfьмЙННН(—Ыƒ"Х—й”хrYр/$ьШш;mрУПќ0дj5N<ƒp8rСЫЮKо+IG)3`х’ьўс„Ь=Џ|CCC‚ŸВММ|s ‚єєє ™LёЬ3Я  ђЬѓЯ?ŽŽ Рсpz$€Тс0\.JЅњњњФHЋЬа€L&ƒ|>­V+†.жЋу•)яЅВѕfмnЗHй‡F!Mxqq…B­­­Тљ{- œN'–——‹ХDЋ=iю(ŒХb0›Э"}'@†#*—Ы‰%(L™=а)дыu1ЊœЩd`БXNЇёo|ЫЫЫ‚NLvнО}ћаббQœ™™1TЋ5ЈзdАI[Жйl‚ЄФQ[‹Х"еj›qЪБЂƒЂЮМ‰ЯьJЦищQr3јœhрќ‚ЫH™E(jа`liiСЮ;144ЃбˆD"ёёq‘кЫгЄr@рsgХєœ@$Ям‡ЮŒŒŠŽУх€ђНщѕzƒA,--‰Я—J%˜Эf сЅ—^lпОсpXœ{“ЩTПЉ€ЧуСБcЧапп‡zЋЋЋ8vьfff`БXH$pђфII:;;aБX‹Хапп/ъИp8,ŒœшљъъjУ^Н^Ч•JешШ(ўХаoe6 МэН^Џ˜ъ PЋеB!зbБˆіЄЭfCWW—аpcёx<АлэЂngDD""uЮfГ"НŽЧу ЉX,‡У!€.‚ІtF=&6R*•L&EЩЂеj133#xKK nЛэ6єііbii  М .ОАZ­"ъ9NСЅ—;8•3В!г9Щ#-•sdY7ОGх4#W•J…D"!В’x<ŽёёqЌЎЎ6ь™ДлэИх–[АsчNБ~rr‘H‡ЉT nЗЫЫЫЇтыfа!5Л^ЏУщtŠR“˜/~-МОЌёЏ—­RŒe uЗмr КККP(„(•J˜››ЯчІ^РєйlGŽСŽ;№‘|cccјщOŠH$""FЃСддbБœN'тё8мnЗјšХbзы(nжц”иbtНRp%D L2Я8]ЦHУHЬЩНp8ŒееUиэvшt:ЌЎЎŠЕа333pЙ\№љ|X]]…йl†лэ)f&“N~{<G&“ЌУ|>Лн.…E™ ‹E,//#"•J‰є€ЄNЇУсУ‡Бџ~ЌЎЎbzzщtѕz]c0`Зл€нn‡Хbн ъсЫ§qж­ќˆЙ№uЅR)И\.СтЃА ‹sŒРВЬлz†BRŒVЋХТТ–––‹Х8лЗoЧЎ]Лазз'юЩшш(Ђб(кллсrЙААА—Ы…d2)27Y<•šr&#зяыЩЉЫ{з3zхЯЏd2 ‡У‡У!^ЛУс@:Цьььd-т*tx_јТ№Пё7‡…Эfгrрbyyсp===јјЧ?Ž@ €ЩЩILOO Ѓb4=sц *• :;;QЉTАsчNX­V8NБhё5ŠЅЙ\™LF dВq)­ТEзwЏ— ЌчШdJj:F"‘u8SђZ­&<2гgRUIP!o ЃЃ‘HDЄ•4,yЏ ‡‹‰„`Ї1"ВЙИИˆZ­&ЦJ-KУ$нnG*•Boo/:;;100€t:‰‰ e[J+Я1иl6ё>–‘}Ї\`IО‚^Џ­KОg*Aб9‘вLа–‹7˜Щдоѕxњpњєi„B!ЌЌЌ4Єј›6mиЦ‡>є!ЌЎЎтЅ—^B"‘™MKK оЃЌ П~–UМOT{"ш)з№ц,шХ—ŠўЪїUЏзбйй‰`ЧŽ":qт ІЇЇ144дPжЪƒ_7p­южQН\.УfГaaaсpmmmИћюЛqрРLLL ‹! !‰МX,ЋеŠcЧŽСэvУjЕТэv ŒеjХттЂьЪfГшшш@8"SешьhУќТв%РЅ2ІXЩdЙ\ННН(•JЂƒсrЙ‡‘L&боо.ˆ"~Псp˜žž  м›O$pЛн@Єб1’Z,†rˆŽ‰$Гй,2ƒh4*SЖoпŽІІ&Q2$ СMDт<ЄМЯtL,[фНцичkg'CоХЎЫ;оwQ3‰ЧуbЎB.)О§эoуЇ?§Љˆx\7~ћэЗcпО}pЛнјƒ?јƒGAІ_{{;rЙœx6дtljjKRќ~П(OVWW…МŸ:;;/PњН`љ*РЅ\2UЋU1№ъЋЏrГЖ)hhѓ)ї?VЋе›k1Шђђ2 ƒЦсpˆдSц|ƒAФb1Fј|>tuuс‰'ž@ЅRi[8‚ rЯ›}нZ­†ёёqБљ—уžV›ЁapцнїПSЬk‚!ƒ!dsфѓ‘_lЂŠбHЅR!‰ˆC—Яч‘ЯчсїћEъF^л”t.GLђ'`DbMžЭfХ`бдд’ЩЄ8ˆDђ•рЁЬВ$ЉЊЕЕ~П===XZZBЙ\ЦЙsчР$KVё5АІf›аbБO~?щtКЂЋ\&БHЬЊVЋЂC@щ6–%ЉTJ”Qœє4 ‚­WЋе„bŸxт б1йН{7nНѕVlнК…BAЅШзъъ*L&ЬfГPкѕx<Јзы…BЂD!ШЦЎ Г1ŽЂЇгiQN]Щ5™ёw)GjЭkУ]ЧGww7ќ~ПpКхrYp4drw4mp7hiiСттЂŠ“pnЗЛЕХжљ™LFxнССAиэvxН^ŒЁX," бЉРnЗ‹дЌЉЉЉ\ДКК Ћ­№Žћо…б‘DТфѓyxН^xН^lп6tХяƒ‘š АзœЭf DЎПХbBŸd-Цb1‹ELOOcгІM(‹X]]ž>™L >;КT*СjЕ @1ŸЯУfГЁЙЙЭЭЭhjj“hKKKЈVЋG<?Oжc”Й *•J,'‘gЭйОх{tЛн “)иЪ1nR™Йp‡§zтj‘РHh …B8~ќ8@ƒ#Ф­ЗоŠнЛwCЋе")4Ћеz†д_ЖZЉJMVЋE<gыZќNЖeYіFцХ.оЗ‹Eџu1€њљжЙУс€еj…ЭfУввš››БВВЃбПпЏdк :§M9|фШ5I)”Птд•}p1bR”BzН^Џ›7oМk2х(ЙфvЛ‘ЩdRŸЫхa6ŸпѓvшЎЛDF^ #‘ˆЃT,"“ЮˆшЅœе~-Эв ‘HˆYаєє4ŒFЃј§хrcccЈT*"K…BxєбGбвв‚ЅЅ%QВфѓyб ƒЂЖцAЄcЃ!’wP­VqЧwРсp!аP(„ЅЅ%ЌЎЎbeeEtAHNВX, УR4^Y@ƒ”fy]5k_›Э&вѓBЁГй ‹Х"ЄЩхˆЧ-жЎ$%‘м’ЭfсrЙHOЬ6`eeЇNТддTУ‚иццf:t‡r^333˜ššxVЋmTљђљ|p:X]]Љ{ €Ус€гщDБXD*•ЅU™˜ё0уtЛн <†|>Пюа™L<Лœё+@} дЋзы"$ ЮэФr‡‹ЌPJЫпt]€/}щKЗл-P| |фѓy‘цЩd–RЉЛн.оyџЌЏM&|>Ÿ ž677ЃЅЅEђЅЅ%8ЁК$ЁеЉa2ЁзыФ‚‘+žp3YсѓЕˆбLъџ‡Уaёњмn7тё8š››ХƒЫхr№xŸ‡йl†ЯчC €еjmрЦŸgмрrЙ`6›сїћбееЛнŽпћНпC*•Т§їп‘‘,,,рШ‘#АлэˆЧу‚ЌТЌ€zђ, œИ‚МиB–#V##№,7ˆо“ЁфYШЫYKЅ’8Шл9Y>dГYœŸ`КuvvŠо;‰ќ~А Х!ЮчѓШхr8~ќИ˜>#O`zzZDiFQ‚ьЉѓP0­ЇA’Ш“JЅ ГX,ŠЏГЏ-“sXївВ-(“ЅLЪ“щ,˜йPЭiffчЮУТТBƒї-Зм‚У‡cїюнPЋеƒxѕеW…ŒіЬЬ М^ЏЫfГBˆEЇг‰€ NІR)фѓyX8YЩhJL€lIО"ЮC(пЇœn?їмs—Ф.іq1ЮI:ФЋp8,œ3CЙМ‘‡бшЄoІ.@‡LдЁ`І ‘]ЦЈDЄšгPLЗьv;\.—рusD”žЖЙЙKKK"eЭd2№x<Т!RЋRЉ‡Б_E&“р{№fГгггащt8pрќ~?ќ~ПˆжŒ8ŸHЕ ‚2ТВ}шѕz™ŒCyї ‡œЈgЧ–Є\2Н'с$™LŠЈ+Fљg+u ‹Х"VVV022‚щщiAЗeыюЮ;яФ=їмЇг)–a†УaМђЪ+xњщЇqьиБ†aЅ]ЛvсЗ~ыЗФѓцНU–|оЌѕљ<’Щ$œNgУр–ЌўLМˆJЬt”„#ѓP™ )1€ѕŒžњ|ž 0юhdЉKœ‚Ж#ЯК ЄSЧу7]рхпЃбЈЈqYџГ?.+тrА‡Ьh4 Yl‚bDВe ‡L3Y:š!5у8]ШŒƒ†™H$аввв &d6›1<<,:sЙœHУHр)‹ƒbфwrr*• ™L‡CD`.QЉTX^^Нn‚tВр%ѕ(&ТњTj§4ьЅ“ :фС_!ƒŠDdБqžЂZ­ŠrBV(bЏžYбgy|—Ž„щ?#8ЦЋЏОŠsчЮ!7uюПџ~м{яНиВe rЙbБNž<‰\.‡џјЧјоїОwADпВu 4j5цёЇњЇј‹Пј !’ЫхаддtБ†ŸЇгц>ŽŽDЃQБQŠЅ3Ь••AЙŽХbИфНѕћ§"Cќф'?yQ OžяBИ1Мs:;к.—{Э[wЄЬ2Ће*š››ёхˆвСqж!˜n*PЋеьВwtЛн‚єAD–‘‹C†oМFЃЮ 3ж›\ŒЉгщрѕzN5нііvБ@бd2 Ц\БXD,шp4EGGVVVрёxАММ ЋеŠююnLNNŠжы>F7Ъ•“цЫvQooякbвз"V"‘@SSТс0Z[[бдд$œ йŽфЃ[,Ap!OžC I!ПосpˆЈ,ЏЬbŠШ”–iК<\(ФНЄ!зOъ-ЉБNЇѓ‚]‚фyp ыдЉSСььlУZЗ}ћі‰VнG?њQƒAœ8qBЬz9rŸћмчDzЎVЋqя;юЦНїоƒ}ћі4ДСž{юœ:u ;vьhlQ–stЈЬВXЪХb1СЧ`+šАЩdR Щћ&M&њњњапп—Ы…ХХE=zt]Œьkmёchh­-Э"sшйМ{іюY ’чЯ$лбЬ5hьPРБcЧ№ќѓЯ ™<Н^гeNжBЌIT!i…u&AevАДД$8i€LСЙ„д_жПccc‚2ЬRЂЉЉ еjU€(L;y›ššААА€ЮЮN1ХШ”›‡‡ˆєдZ­†ЖЖ6,//‹ЈBт 8гeN‡ццf1{žNЇЗЁЃЃC,!rOB I5‹ЏМђŠ  OMM \…=n–Uф0••yъ4xЖџШгgJ•БmGњЏЬк#qHNG Тž>}ZtChјНННИыЎЛpша!Инn|рЦ=77'0˜Пљ›ПСЯ~і3ёZxр}xјсТпь—њњa˜ЭччюИуЦЦ&YШщt" 6œA–Z­+++ШхrhkkƒнnЧЪЪŠ‰DB` +++тНб№7mк„ўўѓšхrsssХьььК: хrZ­э­шьhG[[‹p˜*• mИ§Рm"л9‡D<Џз+ЦЋ тZ,ИнndГй†nеOѓ™ЯмTD =œЕ–W^3—ЧIМpЙ\‚єуїћHH`„HГМ_ —Ы!У`0 ЗЗС`PˆhKЯ™{zPЖєz=l6z{{Хр _[T…BApСN'BЁшm“AGА“‹K™ŠГ‹СоwssГ=%gСчѓ‰H,/ЙЄcрњ№p8,^K<ЦHƒЄƒха я3(Y˜џМZ­ >НЧуŽ€7ф ащ0RёњЭпќЭ†EЎnЗwнuюОћntvv э|іѕ ОUЋUD"|њгŸЦшшшZЏђ'ŸBчІNT*UŒŒŒbvf33ГPЋUА[MшщэСmnGџVœ8~Fш,(5 КЛЛЎСр“ЯчБИИ("k:†FЃСђђrУ=БлэТрр `'?~МAаЄX, €ZJЬёŽ{я‚ЯыipVЛ[ЖnСР@ПјќФФffцсrКФЮ‚ЉХbЭЭЭШхr˜ŸŸЧќќ<тёз(юvЛ{їюХЎ]Л8RНЉ2€іііЭsss8uъ:::агг#€?оDŠzP›Œ,R_M&"‘<˜ЄўYc•Jmmm%g?—Љ+Ž7–KH›ššL&ЁбhFEЋŽЂLхu`t`д“чєQ}nѕUЉTЂ•ДВВЋеŠііv/ŸˆD"bg Г%ŽГFwЙ\‚`D6їцr9б LЅ\Й—ЯяcmI .7tknnnрlф€яЧOњSœ9sF<ыPшМ”еž={pЯ=ї`xxX€Км€Уaй$“Iќб§‘`ћ§т/ОПџџ'Јеjœ9}ЧŸD2™jЈЁЯg9ѓ№јЮЋї˜Ьa,J@Ž`GЕNЇhС–J%,--‰Ž ™[ЗnХрр :;;Q(АИИ(hпБX ­­­ƒЂ%x!q №yЯOІЭftuucxзNс0+• І&gАИИŒt:#:1œс ѓЏT*8vь‚С (ѓ`ѓцЭиГg6oо,РеH$ЃбXОЉ€VЋЕ|тКЋ;wŠUMNЇSаEYџ3эЮыџГЪ:‡u•sHcЅс‹Eо дjЕiqЖ 9}ЧњŠœuYКŠ\w:Ж vБбjЕ№ћ§ШхrbЗННMMM жРбU4ЖФИjœ™йq4~b$Hйl6D"‘†Zž`"ХC˜hфMrИ[ёдЉS˜››$q>–ilЇŽcjjJ“*• }}}ИћюЛq№рA˜L&Єгi,--‰зGж eпˆ`W*|љЫ_ЦџС>„џј;П…l6‡gžљfgц.бФG­†Рв2сёИ1>6-•r ”йqЃЙЙз~.™М^/vюм‰ўў~шѕz„B!ŒŒŒуЃМ9е‡эv;ІІІажж&FУi zНЛіьСрр@Уk™™™Умьюєє4fggE*Ю’ьРшщщСsЯ=‡Z­†‰‰ D"Q"Qtdџў§Ичž{Аџ~!ѓ633#К3ro\f­qHHžОќмч>'2˜?ў“OA­VущЇ~Š` tQM~д”жЂНЩdЌQЙ ААА€^xA U)•‡?ё‰O ^Џ =:}–i 6|ЭФ‹Јc@~€VЋХЎ]ЛрѕzqтФi„W#˜œœDБXТНїо‹z§М&d[[›˜6фГ …B˜™™A4б^Їгahh;wю„ЫхB:މg†0‡Јж‚ЫMзАMMMЁЇЇ?ќ0–––№ьГЯ"ŸЯCЏз## сХ_ФІM›044$8здаcš58'јœNЇˆцЄžВV——fА‹L&E‹†>0}Ѕ2­ЃsbЊХХЄюRщ—)ЅЕЙИ“ЛШѕ–E:™Pв›бR^ЦNyіьIsи…“{ё%РI †љљyЄRЉ†Э@fГя|ч;БcЧLOOуєщгШчѓ8rфˆЙЈwша!мzы­тљLMM‰ћШОПМЏјЛђ–Я>ћ,р}Пј №љ|˜žšСФФдХг~yŠЎŽQFWЙ3ёљЯ^D{ЛнŽ]ЛvaїюнјџуˆH}єшQ,..ЂЕЕUœ+‚е“oЈ‹РћCGOvh.[@ЕZƒн~О‹488(№–ЖМš››kаљѓx<F__Ÿ˜%™™™,DRВЩU`ЩРa1% њMwљ|оЬYъббQq“ыѕ:кллХbER<ЩБзh48zє(ZZZ`ЕZ…Ž>Епил%#—Ы‰ёU>y’ސ oX$еj…Хbif$эВЏЏOдхr[‹)ИзыХммœ˜Q`ŠI<<|yГЏ,I•_О>Y€R)‘H$PЏзбммŒљљyиl6ЬЯЯ Aы0ZАХ&3 щl<ˆнЛwcyyЧŽ=~bvЛУУУиГg:;;№Jщsnе‘зМ1‚ё>ё}Ш Р2Щ^џ§їПK тšQ:ѓЃ3Џ4sкђфЩ“‚+ VЋбзз‡={і ЏЏхrљ‚u[ьб.&s•™„ЅVЋ‡ЇТjЕТjЕ E(о_Љ]]]‚v ЧЄьЗnнJU_Єгi,.."™LЁœUрY'АKfg*•j 3п4@­Vыфєл`0рCњвщ4Ž?Ž“'OŠZ›7цеW_…С`РйГgсp8`ЗлБyѓfAФсa•#…<Ы.ЗjxИ™Кёџг№9PСЌ‚щџ)Ўd КнnЁkРqWжtT6ВX,‚*,oКхи31 F(Й-FЖ ПGоLA”P(„ііvЬЬЬ–къъjУј2/Šƒ aii 'NœFЪ{Ђеjqз]wЁЃЃCдІЄFћ|>Qж !Џ%#ЦСчHбN gВУУgјVдЗV2NЏы”Ÿ[oъB+6› >Ÿ{іьСоН{‹яеW_$хеддд@А"еœYГ‘ЅоЉЙшѕzбййй@cg&I*ХmфоааЖoп.Вс‘‘DЃQЁщШэR*• ёx---тYsŠЅеыБк§К€зы5бSкэvX­VtvvbeeEм C‡сЮ;яФЬЬ fffNЇХˆ-љтŒ€фt›L&ј§~8Nx<№ђћх’AочNф{uuеjUДЧшM‰шѕz‘N’„DУфdёЮ'pФ™кљЌЩi| œ ZLN3 жstFd3ВŸџф“Obyy“““тч‡УaQWвшYЙнn‡!ѓэиБc [ŠщtЋеЊХdœAA™ь$;ОL Іт}”•€хaоŠ\*ѕчпзƒЛЗoпŽ{яНCCCШf؟ŸЧТТ‚(ЭdБОцt: ƒС ИьЦ0{TЎXc*n4сrЙЫх9LЂ"pјЏџњЏ"ЈT*ttt`лЖmшююF>ŸG$A(Ђ2г”KN)KRN–ЛФVjЕкЭ…иэv=kyєзсp ЇЇgЮœ=r—Ы…{яНWДWВй,–——БИИˆййYьмЙSЖњHЅeЪЪжœЫх[„XыRIЧ`0%и|>/€ЖbБˆЖЖ6АчСфkчMЯчѓ"•ТдтЇ*//ŽЂвшP2 ,—Ы…BТpшd||МСQ<ѕдSB~‹mФ––qOьv;Жmл†ццfбf››Уии˜p`ԘuШL‘‹ъ=Œш”^“хгф­=|/tОђz..BЙ”„мЅЂ~cТ‰РЏќЪЏ`ыж­аjЕ8qт„XvBƒ—7/ЩŽŠrєœ  єџ7SJо\Ll‰х ]vœфёщqN­VЋц=u:тLВsE№дjЕŠ-Zr`“3АѕЁn†i@cЁP@sssУƒOЅRBъ‹ ™МВЋЋ С`{їю§фRЉŸЯ‡ЙЙ9сё˜*ёA’РNВlЕr-SєbБŸЯ‡d2‰‰‰ twwЃЇЇGДјЈNьt:‘ЭfEL,тќшp zН^ДI0сd7љ„дjЕHЅRH&“ЂќрЯ“G{й‡Џзы№zНт}RaaazННННиМy3š››a% azzZ№ d€2dtVђ€ Dтœ$Ю"w.„ЄеZж%gђзфtZY_j‚юR€†ЦО9Ѓ9UЇhМ$s1UІЩB,$ЈёїЩщ571ЩЊмnХUЬ,yљ§~ `Ы–-ЈVЋјќч?zНŽУ‡#ŠпCPї$.ЙTd–AS&kQ8•Jн\@&“бЕДД #›ЭbxxXH`БНХ(C Єx<.ъЩББ11šкооŽццfькЕKD#ВIыeЋ†ˆ=‡Ž42ђБ%&Г YoЭЭЭ!™LТnЗ вh4*"6гd2сьйГbXijjJŒо2Z3ѕ#ˆDp‰Р"#-ЫІЊп4tЃŠp>ŸЧІM›рёxаккŠP(„l6‹ЙЙ9œ;wNH‡“ƒL&…’@)йЭVžМ?%$q ВRTUV’AN–=2]–eЪЅdДЎ$ P^|FВц$ћэђкvyГеj€$Ÿ'[ŠђvaвШ™1ЈT*ЌЌЌ ™LŠŸЇеjБeЫ Суё ‘H`bbЂAЩghh?ўИ˜юcyЩѓEn KŽ••Сщ яР;`ВФоMу ƒЖT*a``Ч‡NЇУЬЬŒ˜ф )•t G,Єр`D>ŸЧффЄhщPЕ&Sw.DюЙ­UЎЙM˜cТВ|6Їы(Ež~2™lЫuЙ\ЂЎf]ЯЕЮVЋЋЋЋ ЃМMMMB@˜$гЎX,ТяїУ`0 ГГ>ŸfГ[Зn…бhФйГgХlƒУсРјј8^zщ%ДЖЖŠюЇЪkЧSЉTxЕ^?œ’ŒфLѓйЪcЦT(рvЛ/0~Й6–ХUйб “SY­W\‰Œжz€ЮœРqpёНФbБ†6ЌпяЧйГgЁVЋEožž”l–ŒЪ”„уЯхТ”ССAlйВEоОєвK@TŠЮ0;aKœВщЕЩ^+ЬЉg@n [–‰ЙХјІqMMMZоtwи>"Ч?›ЭŠд†Њ7еjэээBЏŽ­)ЊўжыuDЃб†ЮGЧСУо;йˆœ рД‰DѓѓѓтАxН^1 (Џ^тk4X]]ХќќМ˜^ьююFL&Бiг&С‘ЗX,Ђ•ЦХ""~ц3ŸA4ХG?њQQ^Фуq„Уa<ѕдSаjЕbdx~~^HЂ‹E1дB4Š€А)“ЁHt’S`Y]^ЗЦZS№Єƒ`š‚Ь?aЦњYжX —сRРхjџ‹9jR‚Љ1ѕ#™5ВЄтћ]]]дl—Ы%Ю'gBJЅТс04 тёxУNЕZžž ЂЅЅ…BѓѓѓЂзАЫхŒ ЩjMdХђЬ†УaQ~QNПГГ‡‰DBJ‡/--н\%@Й\ж1НнП?цццаоо.јЮЌЛјeН……ttt‰&Жќ~Уt>™јCŠX0Нf@№†YˆбhФоН{ БsчЮŠrss3клл~@…ЁM›6avvVLьЩј%Н”ЉYc‰DBlš@^ЏЧ /Ма@ј`Кg0АВВПпББ1Фb1ttt4Ш“ЫЦ(oM& ’%ЦzЫPхЌ€Љ29ќdѕ˜’Е˜†˜bє•A,JˆБikkУммм9€‹2•Л8жкЙФ„XzШe гev@иJЅR‚ˆE˜?“3ђ$Ће*Ж FС?…B‚E‡УŒSЮИјГљѓ8[Тн‰|tЄ$t‘pФщLv …Ю;‡@ `МЉ€бhд/..bяоН,.. Іы/ а8ЙЦaІc4vІs2BФ•ѓ№ЌЅ”ЃУFЃQ їly•ЫeA#‡УHЇг№x<Т+sށ`%Ћ КЛЛБВВ‚L&ƒССA,--‰§ѓфЂѓ§---A­V вС‡У!ВFoІЏœ3 дh4hkks§ЫЫЫbС)дЬЊф}Ќэy№ePДу}%ТLв”ЌФз*‚2"M ŠЅєФФ&&&F‚зУ.цdЮ‡ђЊзыB™`38В=Й‚ž‚jRœдd”gлЯ†кйй‰ўў~tuu EчH$‚L&ƒD"!~>Щgы”Ш‚ЫBСRЛcБ|>Ÿ˜Uf-фВН€T№…/|ђŸзrеыѕыsџєOџdБйlЊ|>……ј§~1„Т•_ѓѓѓШчѓЂЖrЛнb гVЇг)дtф!yBю АN@GžncŠkЗлEJVЋеёF^єHF!SVNr($ ™2’‹ДZ-–——Q­VEІB rђљМHй™ЖЎЎЎ mЖ‚ижY]]яXФъъ*ККК„&<—ЋШv•iКœђ“!Гѓ8‹Q*•акк*юGk].WƒRыйѕzћѕzС`уу󘘘hреwww‹lчr:zыщщAСАX,hnn$bB Ф.Œ)#‘H`ee‡C8 тмQ188Їг‰H$‚W^yEdy---0dgMЏМЧJМƒЂVЋ Š:9ђŠsтSzНsss…B8}њД8ыœШмН{wѕГŸ§ьЭ‘ФуqеjEПЈ…И=ЇRЉщ-‚WђЪhЖž’Щ$мn7мn7ьv;вщДHбxуфQXЙэ'Oя‘…ЧТz˜иЫхi!A@т фjГOяp8рѓљI#ŸЯЃЛЛ‹‹‹XZZl:~/ &2Ус0šššАДД„D"žžA(QЪfЇR)с4H;nnnМ^Џ(oxhхееrп›u8_ЩлgEnK1+ђљ|";c*ЭŸ+;~-ŸЯc||gЯž™ СлЛяОЗмr дj5ОњеЏ^ж(ѕє.ЖОš ›Щd2ЂЯЮl“й–’Рy>ЉT*ј|>lпОННН€H$"r˜‘677‹.ƒŠLт"№ЧС"9Куї‘I ‹\ŽЙЏЎЎтдЉS‡Ут^FьмЙУУУ 7 HН^w“]G=О……1Д055%"#ћАбh~П_Ќбт œЂВž’лQьёвгЪb™ђ jІrђD.r фZš§xrПй­ /Ÿsњ4ЂђDљй рAFЃˆFЃ"R1г!՘­Dж…ќ~Xy Œ[meЭe TYџЫѓ№МGЌUЉ@ ‡‘ŸьGdйЙЬЬЬрЬ™3˜™™ПOЃб`чЮИѓЮ;Бkз.дыuŒŒŒ\VGOѕkЕм.'nнПЇaИ†ŽN^:C-–”tђ~„'Ÿ|Вg0АuыVlлЖMpCІЇЇ‘ЩdФkc7ˆš‚,aPиE‘5%œ”:ђ ‡,ЄЪr–‹U?Žd2)юЧуСЎ]ЛА}ћvшt:Фуqœ9sБXьцqfГйУ– kJJ{‘—O:0A*ітi8Dќe=zVfжХrКO/Џœf (OъЩNь—рь[|‡CLqƒБХb(-љп:NhђЌЌЌP! •JГГГЈзыhkk”[–t>l’dФhLаЧяї‹ D~’—pђ’_ЙUNл‰dГYAšb”Ё22я?%ЖљњFGGqњєi1%ЉVЋбдд„ЛюК "% H$H$ыЖ™Ќѕ›|^ь””tЭ ю<|—xMœе !Iюр0уф€пїФФTЊѓЃКЅƒ8}њ4VVVТNч+ы№“%JОƒМЄDОчф}(&eœЧ­љ^RЉ–——ІЗlй‚ссaєєє “Щˆ JTдZ[zCДБЎјѓuFЃбЬi;N,ЙнnСМЃьД\GВ&ЂD–|xYћ3R3е'BЭTŸkЖ”оV‰t+%Ќ9ьAqNъяQ)—кxЬ.иБр–Ÿt:ЩЩI8Nј§~!‚ ЭЭЭ0‚]H~ƒеj‘š GФ3фшVЋБX mmmт№ѓђц]ОGЙ~—ž™<Ё'яцЃ3ц}!c“NRЃб`rrЇOŸjBœcиП?юМѓNєїї p5GЪ2a= †E еjАiSњћЖ йп$ЮIWOіюл+ЪЄгЇF…кRWW—иёчѕz зыБАА FЬЩЂыыыУŽ;аббd2‰Џ~ѕЋаh4ИћюЛХ”<СIчLyжђяt,OejД|БLlюЦЄгтГпН{7Жmл—Ы…`0(ЪЧ`0(В40Z шyиэžy$–P[ћИf'p]`aaaЕщ|>ŸˆмЕZM ѕPИ“Ц-Ћд2н–gьuˆъЫNэЄG•pXШrbЌeйjсд"гjFFY@гh4ŠёOzrЂАmmm(•J˜žžЦGЎ~,Увв’‡˜юѓћXjиl6ADbЪ*oиa”гh4№xЩЩЩ†н}]]]ИыЎЛpћэЗ 2вффЄWљ}ЬОщзsFƒ--~ДЕЖ ННUдШЋ ›К6aліmї9sfѓs‹b=œŒЦЋеj,//c~~^ЬqpRoїюниЙs'ŒF#žzъ)aЌjЕлЖmУќќМ`ђž1К TAVЅ яЋr‡‚М№…eE$ЌOЪхqz№№сУ8~ќИ8ззбщt(”ђx"јudТ Нc‡іЫЗьl9wќ“?P‘в д_WрvЛЗМќђЫшщщпя‡нn}bюЪcџUVтс№еn8фC–”,14ТД}ffFєsхі!_?D’юЬ2ЪjЕ |[}…euYхVоШT—V,‘H$АММ,вe–XXYYA4ївnЗуŽ;юРНїо+FaЉ Єф#а Ы†Бо,Рƒяџ˜LЏЕЫŒ&М>vУщtЌ9ќ:Nœ8…sЃАX,ЂНжее…ХХEAк9{іЌ8*• НННиЕk—шXXX@*•Тии˜X";+fVt1›Э"sр}Ѓъѕ”бŸј[|Ъ ‹A4:ФЎЎ. ЃГГџэП§7qПfgg…Г!UЙZ­"–р›СBB‚ЭaзшЂšћS‘ф§[ў“ЉcщkххC•"€ЊфjWZ\—( оp8Œd2‰P(„wНы]" фRЏз…к/Н9л4Nў]’ №"ЃбЌџi8rћ‹7—ЗМЂšо–mHv*8ЌУQXv4 VWWсvЛ100€X,&Ц€KЅfff`6›бмм,А Зл-ДШыƒ"Zат{”…C9iЦˆ,ЗŽhєм]@„ŒЉШVжф§ H566&ŒЧэvcuu‘HDPg‰Е таЁCИуŽ;ФJэГgЯ6Œ9ЫTaў]nђ9*/“ЩƒбЇЫў>ЁЂ|О-›ХььЦЮM X<ЯшуФ'KKіаЩ- vю쉧ћїУэv# bll ###H&“шээ…С`@SS“8OќˆХbҘeЭЏз+ЪDfЬb™5В“РрСgРыйgŸЛш,Жmл†;v­‡‰‰‰‡%†<ф–ШЦёџ†ўUc›ЅlйHљh }{{>аёЇшŽЦўЎ\.хaЈюUЉё!}ќI$I@ЋОеоjќзjE‹bО€RЙŒŽї›я§Лф/1Л”И.‰D<№~№ƒˆ5ж@‰D…BAPyPxЩ{шэш]хбR>ўˆ=СEv ш‰eYa˜†lЕZБИИ(tkkЋЧфЧ.eЩ+’›zzz зыБyѓf!ЩMюхЩащt№ћ§˜œœ{ чччХkЇs+ ТQёž‘PEƒЦLVcЁP…}}вzYZР™3gАИИ("“^Џ‡ЯчУ022"Жс,--юОћnдj5ŒŒŒ4ь&d6!;^ЙФuщˆh`ŸјФ'ФšАЕВГГsШхђ8vє8JЅВhЗЗЗ iюl6‹@ FЋЩ№Мх–[pлmЗЁННбhgЮœСьь,š››…QHЦщtтєщг‚Ž.S“™ѕQЧQ–‚уіg*41;“—ŒвYШJЮr ­­ лЗoGWW …цццФш6ѕфЩ>vЧ‡Р Ъ•2Іѕ#№7ЗУnwAW7Ѓ{hьЮ.ДmюGŸЧˆt2Šб—N ЩТсwAo1`i<№ОŽ_бўчХЏTў‹фnМ0›Экp8Œ{яН›7oЦ /М€ЉЉ)ссџќЯџУУУFooЏXЁх4UоРя! (oАх“[aќ:EA9fffФnBJˆmйВгггЈзыbVŸбљ`0(ДкBЁ˜e`ŠyіьYzR€ƒrZ/Пќ2:::АuыVœ>}Z.* …BBѕ…ЎХЎеjАлэтп<Иœ№#с…Œ4  hЕZ„B!Ё0ФєЕ^ЏуЮ;яФіэлХdмЛп§nx<<ђШ#т9&rЭN†_“x>k›oц>|>юИуьнЛWаМіГŸ  Žњ|œы(•J˜››УЖmл№œL&бпп#GŽ\РЯgЭЭзЯэж^ЏWш)pдWV<ЂvKjџmлЖ ‘HЇNуяЬ.+•Š ƒЩ+ У2€-> 4Ё7ЊP)ХaЖзQ.Џ@Џ/ ЙГ3gOcntPЋа9А PiЯЁЉЊсэtJ§ЫЉWцПVјё& ZЯ \—HЇгf—Ы…d2)њ—чЮУO~ђAV9sц FFF`0АeЫЁ.Oђ1кЩ@ЁЌвЫд–-"NŒі<2HШ}€ћИ:lyyYдxTфёxŸ+++тgбYлр ёО_в„›ššАКК*D&љ>8i)s/ €јр0ŽЬрЛџўћБoп>ЬЭЭсјёуbњќќ!&Ћqt•3щмШgBpQ;aд’K&ЎRcFЦ2Šѕ0љ ---xъЉЇ‰DDW…ƒ6‡ТсУ‡aГйАММŒ‰‰ БжŒ(”‹cKR­VУуёРnЗУчѓaѓцЭbЧТєєДXд!гšIѓeE6фђђВЊс@;2ЙЩяїcpp]]](•J˜ХъъЊ(K9TЅ$>Бd%O Z­"M![Oс•ђБX‡бЊ‡^ЏB:D&‘G1Ÿ‡нюТІЁ!,ЮЏ`~jЗ>pŒf=ЂЁtz Tu ЊЕLv –Ї–QЏW[ж‚|љuЩjЕšQЎC …‚`fѕѕѕс№сӘššjи1GРjjj sssbъЌЇЇэээ№ћ§Т!№P1’а“В,ы}Y%ˆ‘‰tл––Бœž+—t:œNЇрм§OЇгC_пy5лббQx<œ;wVЋCCCXYYСШШˆШ:8Ѕ799)4Y;ђ0p; ?'ѓѓM&“ˆHJcБ˜@ОƒС ‚С`bЭN‚мzћа‡>„-[Ж ™Lb~~^№+d"ОL_eлŠ|zЛн.жГ;!Fg,гЎ fR‚NC­VУчѓ 4Х_џѕ_ GЁVЋ188Fƒ}ћіaпО}˜œœФии˜hGВќЩхrИ§іл111……ьлЗO V1иF;v лЖmƒпяЧФФfgg–‡№ћˆ_›‘ЗKq<‰i,uЈРLђЬ™3b,3%fI<ГВ^чиЭЊеjHЄуЄ1Ÿ‚ЋгЕF•HЅ’ЈеŠИэ№XšœЧТм vмО S!ЈѕFш­F„Ў ˜) }ѓ-zФCQLXнF+PаЎ1UЏЧ8А…Ф‚*DЈkЕšаaџЕ_ћ5hЕZœ;w'NœРииXzZЏзE—uИлэFkkЋ8ˆ‡Clн‘ыP™т*З 9,’JЅFсёxXЧNCЙ\?]\\Фдд”а‚›žž†Ус@,C0„гщDkk+цччE?мяїУbБ  ТfГ ІšлэF"‘@–пяФ'Ъ•QЩ‡C!д ‡У‚PХџOgABSШ]ЛvЁЇЇпћоїP*•088ˆщщщн?: ж iUВзиb+—ЫˆЧуАZ­№xzєЈєИкэРИїо{сїћё›Пљ›˜œœ„VЋХттЂp*YБŒуŒОJЅvU*…ЖB[[››хV$ѓђђВ(%РЪ„ЉГgЯ68Шссa AЏз#ршбЃ"›ф}фй—)Чt”,љИ8– x­VCЅTE%WƒНм„ppNЗлvпНQ…D4ŒBЎ ­о„|Ж‚б—F0;zѓgыАЛэPЉjhйв НId$‰аlvЏ™dЮ.9€пдh4бiN„ёІtЃзыбее…;wBЋеbrrRH:А’Џl6‹ХХEБœŸНaЖг88ФЏ“­ХˆЦˆФhЯ)ЌJЅ"ві……QŸ3с Щ‹/ОˆЛюК хrYдцЙ\N€„[ЗniЏнnЧјј8Жoп.Œ‡XC(‚ЧуСии&''‹ХDtˆFЃbaŠЌщGО‚rй‰УсР№№0Z[[бнн-цжхl‰JЬDIue:+ЇP”5ŸЯ •чzНŽX,жРK ЃŽmA:b­ч=Y^^Ц3Я<#ŒSЃб`гІMИћюЛqлmЗAЅR!уЙчžЮќрСƒјЪWО"І5 8pЩdуууИх–[Аџ~ЬЮЮ ]}Fƒ`0ˆsчЮ‰{tцЬСљ`ЯL”гЇ2]<N7” \йЗмr fff066&ЪE‚ЁЄO“~.o –YЋђL_GЕZEЕTƒЅт€Ѕт@оdF[G'N§)юyпПƒF[Ч‰чТb3ЃГЇЫГs0кtШХѓ˜Ÿƒгч‚ГЩ‹J1…ЉSS№4ЛaВ›ЁеkRєПё€JЅ23*Eg– #ќ{6›щOKK‹ш  ,..byyС`А˜RъвБЮfГbЪKЮ ж(Ъ"=&ƒu™<*Ъe—ќОееU!ЯЬmЖлЖmC(‚лэТйl^Џ•J‘HzН^Д> …žxт 455сшбЃ б.™LтK_њRЦюAЉbБ(6 гhіюн Н^M›6ЁНН]дЬЙ\чЮŽ—†Э&Џњf -/n‘‰B2hШ{‰D`0oiЋ|ШйЮ”ї9’ŒУЙ|"єћіэУНїо+]FFFD!GлІІ&ёŒЈ'С)гŒ ч›JЅ099)Z‰Знvцччqюм9T*œ={эээ дo‡У" ƒ ““Lѓ›››ё?џчџчёєщгТС’%S9Ъ2UЉŸЈdJЪ йRUmvЛ ;wР`UуШSOСd2cn|;ь„нkТЬй,<~Кмhйдo‡“+s3˜8vЕz‰` ЕjеЛц^Ÿ €Eж`——k2ЫK ф‘дL&#”Nщ‡††DЋ'•J! сх—_ћхж‰’s]ЉTpьшЫxхх HФзD$ЌАйьшмд…ЖіNєєn†NЇ>›Э‚Œ\.‡оо^Б6кщtтілoЧммœPeZ{юм9ёoŸЯ'ЖьЄ’AEy0FV(тˆ2'йA ОТцЭ›EщBA‘™™бz$вЮˆ,“„d‰0>Жэ˜)>И€ЄЃЃЃAћ]ў<Ю7Ш‚Z­gЯžХјјИ@в jоyчИэЖл„.О,Є)џ ІЈ,‰DtznЗёx]]]Алэ˜™™СцЭ›‘ЭfБВВ"„Z- VVVЧ'€”lŠ˜TЋUl˜Йєѕѕ‰‚ХХE‘™АнL=Ж хkљўЫ“™ЪUЉгXЋе+f1U? mW Z›‹‹˜<;ƒјJ ZНю&;PЊBєfЂ‘"Т‹!t ѕbu&ˆ#žФъ\ §ЗU`їЙ`ВYЬіСЄ;5ZNKY@§FъXxXЏЩ &dRŠЌ1ЯˆЫHХёS\ИЈЁЅЅEdwп}З(38HУŒ"™Lр‰ЧCWw>№Сџ­чG&DЮ‹x,.тф‰уxххЁзаЛy+пѓ.ДЖЖ ЦK‡ЅЅ%!QЋе077'кzœгЎзы‚™ЦˆH"wТ€\YY-?N‡––aьм=иммŒжжVDЃQ!њ ‘NЇ…>; ‹jЕZрŒОdTвh•‹%Шeчї№=Ы‚!4‚—Z9дХЈЦƒЬ}}###˜‡\Ѓб`xxwоy'Жmл&Д&&&‹Х„ђ UrЉЋ E1x/ш\- bБš››122›Э†BЁ›Э†;v`yyY№шыѕ:Жnн NЏзлPгѓ›пYЅзыХŽ;АyѓfёЬЇІІ.рїЫЦЬВSfAЪйЊ<Р&Ћ1@ЙVB­^*чэ ЃŠуЛ/~KжГ@> ]]‹Г+Ыhiп‚Э[6уЬ‰г(”ѓа™ЈA‹3GЮРлюЧžУЗсф“/!2еR ажАџЭ0šдH…гАzpэан™-эѕ*Œ2^ŽDœP*ЪШ%|˜јwйY(‡+Ј-@EЏз‹RЉ„ЧОї-МїпwСыѓxН№xНоЕ џюНяХєдћюЃ87zгSxЯ/М[ћ‰шXЈЉЯV gГ<ˆbБˆююnё`›šš„ K“Щ„x<ŽzН.ЅШJфb‰DуууЂL†$[SGМв)P!Г(хu™т*ы+ШSƒrЪ-яњ#%›Е7ыWт-хrѓѓѓиѕюМѓNмuз]‚О|іьYЌЎЎŠ} В(58‘'gмРd6›aЗлсёxлчѓсмЙs ЊХ,‰ЈќЫКrлЃЃЃ =єєє`ЧŽhkkC<ЧёуЧ…ў"_ƒrьœ&vnd хœ„,KV­VQЎ–ёу№7‘е$ЁЊЉa,к`+ЕbС6‚В>‡D:‰РLЅрэеauj[nй ЛгjЅ†№RS'ЧсєК`6šБtvеbjЃu}M[­HЅƒ(–Эаˆ.‡ЁВт_ Y›ЌпH`хšeFY™–щ=ыRЙЯЯяgщ п49}R^В7=_ЋЁgs/Ъх2NМz“SГCPЋ5№z=№љМhooУ–­НшнМПѓ{П>ў<інятЛпљ&ў§2оћОФСц45цИЛНЗЗ bпе†Ус0оѕЎw‰1]ŠœВŽf|jjJЬP($дwђљМрЏUзщtЂї/Џцц6$Ft’ЈHaЅCрч˜–ЪЄNЌVkƒъ’ьd–&Г ЖШЦЦЦpnч=x№ іюн‹Z­&zя|Ь№Ш*ŒХbhjjBЁPŒ;х:1n№!ЂnЗлштшИU7ŸЯ#ŠvKK‹а`ŽХ`0`hhЛvэ№ѓЯ?/КdŸђžЩРЯ$ABй‰ЪCQђНdл4QŒсћ‰/!iX…ЭaG*šD*•„Ыи†œ1b!_gЖhEh1‚Ђ: ЈkашTpлНаЬPЋ4ажWрjn†гл‚ам4КwіЂZ.!0ЕˆR6Їз НUе™04#Lу Ї_sЊš$“IЋУсh˜цrЙоЄЫѓхВЌ—L1хЭ˘ŠЉŒ9‹”Ъч э™ЇžТФФ4’ЉьZDЏ#Ž arrGŽМ‚НћnС№№мїюї VЋсћ=†o}ѓДЖЖcSWЗP]с+•J…B8vь˜Јѓ———aЗл‘L&Ezsss‚CJЅЩdаоо.zљ™LFD”ЕbК/ыШг`$иАМхвd5[–ZќriРCOЧЬ€šNоЙ@Љ6v FGG1??/ž•ХbССƒqша!L.,,ЧХ4Ÿ„Ё\.—ЫеАPоd$k’ТœЭfЫO4S—FЃQhrjЮ’Юbxx§§§BкьХ_*ЖБm6›и@Х2PЙд„Я‹џo=,E^=–Ъ'№х№Eн\К`ЂЏsЏ šŒ…й4дъ:ђй4L&-ъuLN=Tj5Lєњ*ЪЙ"ь.=Œ†ZкМ0hеX›Хъ|•НPkЕ(JP•д05щYŽЕМ*G1RЯЎ КзьўёџбСZдщt"—Ы‰VЄ,е--rњЏьŸЪ=еЫL†&ЦЦБZE4– К`­#эѓЯA6“УƒЗтОwПЇOТТќ<~јФїёЁ_њU˜L&иl6бІЄУс:yЁ‡œКrА‰_ч^?ЖЬ(DIB я›МIисp  Й4v#фMНђШ.‰+”:c†%SK‰F3Еg”FEБљ№ђyХуq,//уьйГ 2`Ичž{Аџ~шt:AЯeFРE%,Uиy‘Зё8NёuўиlЖ „CRЉTƒz.ХX,DЃQбІJ/‰BВЁЩž={аннd2‰гЇO >хм™YШГФАdфž.Я­RМT™і …ѓќ‡ЬгаИеА]dЂOЃеСеьE>—G"GЉ\†VЇ‡Zч€ЪPFНЂVoBЙ^F5_EUW†бX†ЊšУєёx[šЁ3ыБxn ѕbэC№vљ зkœ ЉЗЋ~;єX§Ѕ2рњ3€\.g#™„лr*•ŠиЪТУKЃЇз'#ކ]fѓЩ|)ЯŸOг•ЕVJБ”‘uьщ Ž?‰іŽVlкд‰ћо§|сŸџ 3гH$т@3…, "њ2[ЁV[~?Iьс:hПп/і%ђwSрkтіŸP(„ЅЅ%˜ЭfAцю Њв‘QЁ–и Б–фк+Еўe 1Й Tэ ‡УX^^ЦТТ‚Hѕz=іэл‡wНы]шщщšP($Rt™§GC"§—ƒK;%ZЎћЉŒ#ЯˆжFсp8DZЮн ьfфr9ёzyЖoпŽ}ћіСсpˆЉAr+ИМ…сд$ЧŸY–ЌЈ$+§Ъ™зzZŒФ/"‘RщЂ]‹№З\ѕD’+ hЛЭˆ†ЫˆTu(eѓАйшйБ Бp Ё•Uь{я0[Œˆ#0шѕPЋ5€ pš X™\Ъ5]šwЕOЏ9Е4"|э T*9ЩЃfJIcfБX,Т[ЪћъH­d J/п`љІ+K€зИѓ^:5ЈхЪdНl`фЬ(6mъФРкP7{Н^сЈ(zIЯ2ь'лl6МєвKBЁ–AЖH$"ШCљ|^.ђ8fJQJ•J%"­йlF8Zt,r;Nюп?рВюO”ы^FHf+,Idыы_џ:тёИ(нќ~?юЙчмyчb>рьйГТЉ1ѓPŠ_rђ‘†РgHљ8Nчб1А+;wій‰„ ыp­dž1Чƒ}ћіaxx xщЅ—Ф–І[nЙE,fI$ *KlKВЎ—7ЫяMАх ГПин˜wŒ@ы­AoЌ\ѕDŸІЊG!ЁGБZ€JUФ­їмЅ‰Y,/,`чэЗby& НйЃнˆШЋgPLбБЕ6—ЉXfЛЭ›эHgЪ В.pЭ@ЋеКф 4$ајЙД“BT§с—4лOœ˜“wбЫHЕќїZ­†ккс•Ž”ЊИыe33sB"њ55šѓ„"јL ЋеЊа hmmEБXВYђDeТ™Z3њ1т‘,%4ѓОё~а˜(ЄAу‘WpЩ’V”0у=fй@аNNmх5ZdѕЉеъцъъ*ДZ-pј№aьлЗ?ћйЯ№јуЃЋЋk]Й1:ЎнbћЏOца3цЦbІј˜RЎ“ёl6 Їг)˜ЃьСЋеjtwwcџў§шяяG&“СщгЇБММŒrЙ,~ŽгщФии˜0ZЖќјšHб•RчOV1–EWKЅВйЌB[-/cЮ8ŠЄ+€‚!q]}ЕŒћоy™TљL Н љl#/ŸСьш9Ь­Ссr@­ЎЃukєfтЋI„ЇC№є6ЁRЏ В4k ЛЁ T*Й•C\.їЂy д№†В")˜ЎЪкvЪњЊaћM§Е‰Њz§5 м‹ЇќXPDj,‡VиБр€9ђFЃQШKqG)#ЋR<ƒxЌ,+#Q}–Œ;2ѕXNQRœ“e,sdŒ@^ъ)ЇїьШ›“h”йlVD|Н^;vрілoGww7ъѕ:FGGёѕЏŸњдЇФžЯRN›Й„ƒ-\Ўл–ы}Ѓб(v&дj5!H"?kJG"œ;wюхчO|тhjjТЪЪ ^~љeЬЯЯ#•J‰Въ/ѕ ШмdНЯY?QnK+Я ПЮ’ЖX,žЮ•"jЦ2fЬ'0[< Ѓ^wн}ЩXлAh nœ~љUXЌtіі`in›љD spx]pњн(S˜=1 џІ&иŸ‚Z­V0їH,’A$f$таа˜9BрјЇЦфх td^’](Зi№2ቛнnGOOњћћпрєщгp8 хСж­[ёЪ+ЏˆШюМЉIЎ RЙˆ0&“ ЋЋЋBМ…JGЪ•c&“ @ ТRЧраЁCјсЯ ‹xН^|џћпG2™їЗ­­M0 IяІtНзыл‚9'ТgOЇЏd$*3ОLчѕzНА:ЭXШЮ`цмэо2бчєYqєйŸТьДbnr;oп g“3чВ№6{at :АЭlХвь ІŽЁVU!4Г‚BЖЩ S{ySzJFр5;€ЖЖЖž—_~‡†гщ­@Tоpe4’S_9“gЅхEЪє_й T"ЧJpБl`=q%hАМg@ж$`­Ь䑇ˆЫ”Е;‰$д<0yS/ЫЖ“фЌBоњC.#3# 6l&“СП§лПЁЛЛ[”;;v80 jМ|oЬdј,)†СчЫ%: Ž;SюŒмЧ#jkоSyЅјsЯ=‡gŸ}VtH4 КЛЛq№рAьиБљ|^8r-И”§|Š{ƒqЛнXZZъCtž<3Ъ.”\†ђнљyэоНћ<;tqЋ‹aX n„ƒs7dЂ/И”ЧђЬ V=<ЭN V4*Ќ&ФVˆЃˆ,‡аНm VЇƒxс_#8]ТЖ;+hъєУюЕ#›ЪAoWЗ№Ј_МњъЋW"кyЕZ­5—ЫсЩ'ŸФоН{БuыVБ›]Nљ­d§8Й](ыуЩ;щ”,5хУXЯˆeУP:e6Ао%?xЙЧЫzž УђŽCYЋ@Ў­ QьƒМ: FffGђvжЎŒ2Lџe)pyw‚М‰н~Ѓ>Сьь,~ќу7ьффŸМUWжUgлi0|frWA–j“ЕшєЉЁШїЋзыд˜y=ђШ#CиГg>ŒЖЖ6„УaМєвKb ЕМ3‚ЌKЋеŠ––ЁЦУ–-q(Ѕьzє]9§—ЫPЮшt:tvvŠ­=д_ŒЧуPЅu0—э(˜ЬhыьФщck}КЕ‰>ыеMєщѕz8|БX uU w?јdR)œyљ4|~ьЛїNќшާш*Ѕ*ЊЈр№GЖУdЉ#Йš†лf…ЮЄE]WэVLžЯT*Uƒhу•^ƒƒƒЁххeŒŽŽт•W^A Рў§ћсёxDKu`љ01тѓ2ЪcЌЪzKY‹ЩŸSŽX^Ьр•йРE˜‚eЧш/Џ'gњ'+фR УbБˆ^;)ЉTесіcRaхх’МЌC ь1‹Pюј“kTО_!SjyEп{БXФ+ЏМ‚SЇN‰'CCCiѕedфяPfWt(В1Ÿ3Б ~:ёоŸd2)RяH$‚••„B!‘iY­V>|€бhФЪЪ {ь1(Wž' ‘•ЄR)TЋU8N„8КЭЏЫF”•?ЯrJюX­VtttРчѓЁZ­bjjJ<#РЙrU] v‡ ƒУ;aДi№вгOСdВ`n|;ь„ЃЩŒ™б 'њЌf+–}Хl™H 6Ћби jPЁ\­УъВСbЕ 0Е Лз ЛлЈ›O‹ІŽ”ЫsXCЅT†Щeи”UЪбрk.Ю;—~№С…КЯќќ<Бmл6С0e$хЭWІ`W IАц0G[зKџзkнЌђШУ.rЊHšЎ ФЩB^nBД›CAVЋUtdPЇг!“ЩъЋЬ$“Г ™-'yЃ˜B3ТёЕхr9!ТB ЋЉЉ Пљ›П‰ЇŸ~њъЊUхУOЌAЎ•хh.ƒ›ЪvЩPlr)'гќM›6саЁC"ЅC0D*•Xї5*Љу!йЁњЫ RЂ VГ”aсНЅа*џ­RЉрrЙайй —Ы…l6‹ййYDЃбjpЉTBЎ˜Х’aІіjv––'0unБ•(єzМ­Ј(щn5"N Š!ВМŠюmНЭётЗO4Lє™Vxќ.tt#АфТфШ9aаща?д‡пЕJO[<ЭЈЕЌЮ-ЃЎв@g2РъЊЁ^ЋУh3эO*ѕF~V:%gзьЊеЊёЬ™3јшG?Šў№‡BiхЬ™38yђ$іьйƒ;яМ--- ` 'хЎ<>,U(S~Й АŽљ^P\*ȘёЫ›jхE”ЬT`ЎЗ|TюbШ”'Т.A=fЌgхўq”ЙГГ‹E lq/„|^ŠХ""ХbѕU4c(хbаЋt=Ж‚ЖЎ>ьКmљ(Ъх ?№ndвщЕОћю9€у?zЧ~t~ЂЏŠ ><ОŠd0Ћз‘W^С™WŸЧєXžv`чоƒшъCЙPТЪєjufFІpќЩ—‘OeЁжhЁбi‹g`А˜Б2‚Эg7ИŒŸŒќЌє+2шzfьЕZ 'OžФнwп]Лvслпў6–——QЏзqќјqœ>}b]“,N!‹€Ъ‘_†PћхВepЉlрb%€ёuх,€†*С<Ђ0ŠАЎ'Fв •xиж3™L‚ЮєЕЅм‡ц=“л‹T;ЂЊVЋјъWПŠгЇO7 еNЇяyЯ{АsчNЬЬЬˆnВ––gк•’ї™ _ЏŒ;Ш *w"at‹ElrЛнxц™gАДД$hзђЈЖнn2мvЛН! #X)ЗEхЌS.ۘСаqцr9ёLљклллбйй ЭџŸН? ’,?Яћапйrп3kпЛzпІЇЇgР`@а’(/Д­ ‡mъƒ—ИКп+бсАУWЁˆ+_+,GаŠ`($й’EJ€E‚р€Ыьгг=НWWWUз^YЙя™'ѓlїCз?ч_9е=н3=$†ьqЂЊЋЊs9yочнžїy5bБШъъjBT&‰ШЌоЌsе~•Ž^ЇT-БЙиЄз„иl^—/ўћПH4'ЗН‰‡‚mЛD1"‘йхu šIOEAѓˆЅ т™1z5Jй"ЊщщGN…HŒЧйXYсЙ^dљНEз&=3ŒЊ'№<—™г3 MŒ ‡PЋЏМGiГEf*ƒ›ДA*~ЛсuХdрGлЖ#Т х7ѓ7ЙuыпљЮwиммФЖmXZZ"sіьYNž<Щєє4ЁPЈЬВŽќ КЯ&EƒKFЂ Я/ГH Zy–МЂLnя‰~Иx\Ё(nLсЕMfУЩ…6Йу!ЇЂe*4 …BџgWЎ\щG Щd’Џ§ы\ИpЁЏд#^“0T™д"Gr ‹[ŠЯIД8…h‡<‡Ыхњ’]т3ššт _јЯ<ѓ КЎГББСЕkз( }‰МxCА$E˜-w DБR<ЏМСGоН(К ЂлялK†8tшccc}=БщypФW5ыyrњнv‡ЁCУ<ѕхѓфwJрYcAІц'H[LАtsьк&CчиЉ$†гЈhЄЦ‡HfP4љЕmGAїУъх6ЫoUЩЬˆЦДavжаP˜;}˜|v›ja—™“G™;y‚Ы?КФтХŽœ=†Я№ѓєWfPЕ ЕB5?Џ.§дЙВx'ˆ яhл6хr™ЋWЏ255Хпћ{K—.ёЭo~“rЙм7žЫ—/їUuчцц˜œœdjjŠ™™™}ЊAђњІСhрAР їee=(8(^\љDxQ€7а+ИФ DЁPшяE‹K4MычЉТ ƒBЙ2-я, §=ЛЛЛћвAЕџ3Ÿљ йl–›7oю:™O0HГ>ЈЫ"зFA<ІHS„жЃИ6ЊЊrіьY^zщ%Ž;voнїžбЫ+<И ŒЕZ­}’фэШ2 b—ЈШ3'тѓДcётНЧуqfffњ E„Ѕ,ы%wЋ„зРныѕиЎ­бЎзq­‘ИŸйЄЧ’и=—Ju›[—^ЇД[сЮ{в“pіЙ8zњ8–йe{eзƒе›wyя‡1-]Gех&Њjаi4iхz”w шѓХйнй"9Х{”rYR“Ic)Š[ ВKл”Гy^[Ы ы„НNP4ѓžЎ‹BрЧ‰ЂђEЈ˜Ыхњ ЌПѕ[ПХЕkзxѕеWЙqуЦОŠщввRЃn(bff†‰‰ ІІІлGгєњїћРУфшС4Э~YŒШіzН~IоП'ŒZa<яЖˆЅ‚,$n&Q#—›Ш CEZБЙЙI.—ЃX,ії ъА№˜Ђ;qфШž}іYЮœ9CЉTтъеЋ}#”…(хA—ћЕ]ЏНМЄEдФы­зыlooГЕЕеПўС`_|‘—^zЉПїўѕз_яЋ ‹k.ЈЬ29LOE@€‹\Ј”ѕdКѓ`—ЂзыэKБ4Mcdd„йййОоУТТBŸР%{zљ~^_8=ьдж0k=Aымўёm,FfbD&S$†c„c.ЧЮ‰ Хй\ОЫГ/|žЅЫ‹И8ЄІ‡P5Яu˜95MfrM5шЖКмxѕ­jбЙ•B“Z)OtШ`lbŽDbˆxrЋЙH"u”ыЏмхЕo]bьpˆPЬРЖ,ьЎM­`cј šŽQ2ъ3вPаGЯѓBтBШ§rХb‘JЅB:ц7~у7№ћ§§QLYšI\№l6KЉTbqqПпO&“щ/н№љ|§uZїіМ§pаа‡MŠGЎіЫTRВ‹z€Щž^Lя‰МSДЄрШ“{В!ѕЧ›їи…•J…RЉDЕZнЇY'ѓжХџї< .pъд)Nœ8бWКuыж—dіAюУAДзСCf6 .‡ р •cUUЧчѓqсТ^zщ%Вй,WЏ^н'њ!ou-LсO-ЯTD1а$ƒИјПƒн$1R,jMOO3??O("ŸЯsэк5šЭfpEJ!ƒžјИї„сїŸУЎ ъhЊ‡йъJxЈ*˜Э ПWCї‰IMˆ„јЕ!vnЏЃ+ S'QШюP-ь2}ђ(s'ѓо+—YМИЬфЁi4е`ьP‚/ќЪ—ЙќУ7Йљк6№6бT€Ё“gСе9ёќ3\ќ“KЌо\фш3х:…M‹ŸцШГЧшuv—Гtš=ќQџ4Дћ|€ХE•+чr˜$Td„ЦоЬЬ чЮуяўнПKЏзух—_&ŸЯГГГѓЎбhАООо'§шG?ъGф–йћ2•щЉ ж7ЖЦщЋ>ŸЏ_<d•См_žеdб†’ѓQ‘.фrЙўšЊFЃAЕZэkџЫ[c'eV`:цЉЇžbnnŽЃGт8ЛЛЛЌЌЌєѓgy[№”тІF/“Б‹}їScђћ§t:Ў_ПЮккк>e SЇNёх/™ЃGђЗџіпfgg‡ББ1юоНћіІ(оЩДbq-…юЁИ†ЂЯŸL&ї13хЙ‘f Д`AН>tшsssћЄУepЅгeFр§ Щ":Аm›ЎЏE0ЄБг"іу(DS~2Г‡љЅџќ<7z“Зўф5Šk4 ќљэ-тЃQŒ0”vwIM'HŒЅ(m7Щ.nSо-Rи,т Јш†‚йpљвј2ЩєE&NNскZаЂ–ЏRЮnˆЈЈxфжŠФ2Оє=УјБ EggЙHaЃJaЋB<Џ=€у8ay:J.ВЩ` кdbЇZЋеъч†§Џџѕ~ЛББСжжVћЭ§МДёЧ!™ŠьЫCПўK_Сu]Ъх2йнЛЛ9Zm“NЧмGМ9шБE›K| …њеzЁ,#r|БCOD"o:tйlЖЏ‹/T’…TVG7œ\l”#*Б unnŽљљyNŸ>Эќќ<ЕZBЁ@ЋеbyyЙя1Eј," Y“QЎь‹5уƒЙ {H–J%VWWY__пЗв§Ѕ—^т‹_ќ"cccфr9оxуўћ:vьЫЫЫXю*Ц}хз'ЯOˆvБH<ЯЃX,~@}W€Ў p"ВŠD"9r„йййОЋа0м™”%†Н„Чc_eкАу8l•WhY&'>s†єh‚›?НB3Џ`5Жщж,*Л9&ХШmдЉ– L1œ#‘ШHN`Еn“HхЦ+wy§џО|/„шX–нsщЖсџјЛО0Ум…<7€юw)m50ТєŽbt:’fт№Љ‰!ЦчgXЙМФЭWБLАёўЋ[пnќЃЧЂфКЎџ~DqadЩ/љgrˆЙГГгgY={–чŸПпп_І!д‚E ш .Р—^ўnпОMЙx/?Юd2d2Юœ>ѕаяGЌаZ__'•Jѕ)ЕbСЇ<Ё&дmDхћЗћЗїE‘№§IEoпŽ=QGTя^љЋ_§*“““Œ333CН^Ї^Џ“ЯчyѕеWћЦ)Иѕ"=Е б­cД"mЁѓ ‘ч д`MхќƒРттbџљFGGyљх—љмч>зgы§єЇ?эƒž\[‘U‰do+я2ї;ˆПЃМЂЇ/К ђЖтлЗoїЃ'QHV…ёёqžўy:N?Пџ_ЄxЂў";QЫѕС‡5ёЙ‹kSЖsј' І'Žр3ZдЫ Fч“Ќ_jс ^э Oџ•уќЪџћ?цџЗoqхG›‚;DRA†NOчФg.№юŸ\bѕцŽžЯP/з)emІOЧ‰ЅTVhС;ЋEДX€`N~с$ЭJ EГŸehvUзШ­eйКНEvq‡jЎJЃ\Aг TUЉе.ZПйЋКІ, і‘рk_ћšo||<(гBeУч`kы q# "†~ї "яАZ­Цnn EбБ1FЧюЭ:lnlP,я}рн.ЭFГян„1<Ј­(П^Џя“+“‡˜DД жЫl@™‰'Гы„‡™ŸŸЧ0 ЦЧЧcdd„‘‘&''љ›ѓoRЋејЕ_ћ5) §5jbzNЬˆњƒИYETМHˆql2.хЩССЙŠЭЭЭўЕЙuыšІqђфIОіЕЏqцЬ™ўоћ­­­}›žхBš8ёzd’—М,C Qv:~d#ЎЉfЏїg?ћYџ}LOOsќјq~ђ“Ÿє#В+WЎє9N‡p8LН^яВфК,Џ&ЂMШ<ЙkTёmcY=vЗpЭ:Љ‘VлхпџŸўЙхк˜ Ž`ЈqОќЏMМСФёIœž‡АЈjTvЖ DUХ#З^$’єsс+Ч DƒTruR‰$‡_55…чy  ‰ЧуЄгщўBёЕбhPЋеXXXрвЅK§дЃлэіг qуЪМ{Й­%n~БЪL„еН^p8мddšЌ№„Ђр&w\:›››фѓљ}‹GОјХ/ђ‹Пј‹LNNR,yяНїњТ("ТSђ`0rQ_aКЬ•HYIJD6Т”JЅ~ф#дŽŽ9ТбЃGћJJВоП\з" ѕ˜`ЏO†Тсp?bœqHЎ?zQМ5?-ЏХФщ |s_}šfНРэ7/‘šЪPо(ѓ[ПўПpшйifЮNу:~ ПKyЇ‰ђЁ…4НЫ№с4Ѓs"Љ8Ёh”•ЫЫДvœўь |~эz^Ћ‡ныБ~s“`мЯжэК]‹wўэ›Д›]FfЧ™~j•мњ.ЭZ‡іZяwЎѓ:аКВ<ј#РзПўѕgbБи›ЊЊђE)Є2Шю§@žћџ0РС­*їР LЃбb7›ЃбЌЃ(рѓшКFРяЧѕ<2щ4КЁjR*–Ш qќФŽ9Т‰'˜žžюыі Џ-wrя^Ь5pсЂи! ‘пЏМj[Д…ЇМСЇžJDAэvЛ_A— xbŽПбhє%ЊDKM\?Qx@& LМўщщiОќх/ѓТ /їЖшŠ{йѓ ‡УДZ­>­YnЃ‰ЯM€’x В†мZ‘‰bБи7JJЇNb~~ž^ЏЧњњ:Й\ЎпОЌDёмr !šтzШвщ"Я—UЌDФ"ъ)тп2ћ0‰АиEЃк Ж#иЖ‰ЭЬ0yоC7ќјУfŸ?Фже,žеЃК]ЁšЋNYНЙJ~ЃШфщ ŸŸќZЫДАLЗЉдѕ€бЖ{47˜yz|šЎRЯзА{6ЭB_РGt6JГвЄmЖ1+ж%ЛЌќИ№ГЮѕ=0kМGJтёј[ЁP( OР ‘TфпФ0“ЋКЃ$ƒ€пя'ї—XІRЉОžМЈ NМ0D‘3[–ХбЃGћkКЃб(ЁPhщDмьBюJ6ryŠLtd6у`qMUе~mADТPЯAќ?БyVДD…t˜ьйФЎ:a,bЊPЪXpyџТ ОХЏўъЏrј№a4Mcaa|>пwЉ‘ЫH$§МY<Юр@ˆŒ“OШЏ‰’LЈзыћvя ~ўSO=ХииЭf“………ў uaИТˆхeтН‹ы!ЄЪХXДхЉBбщ+кЊђ а^kе+•J;ЏОњъыkљх|ѕХФДя˜хи‰ЇЇшT[8.dІ†0tƒvЅ†Y3щuіBјЈŸ­лл˜]‹‹п~›VЃKj,C|4IЗйЈ~ж§7FŸ?­}Љ^1',лжцžKБјж-љ:šЁиš/”Зm+j–ЛvЗcЋ­rЛэЖЙеМЦ?ыdэu Ж-)ќД"рпџћџ7ЦЦЦЦ‹yrю.З§фяeУ?(Ф?(xиC64‡Ус}:mтЋ ŠєСВ,>мЇ7ЙмNЁЃшK Уо[nЏЩяW€МSOŸщЈ‚г/sд…ЇIˆ„ЧVUЕП_PШ{‰n€ПпOЅRщз!ђљ|?=‘ЗШ!ю•+Wњ8‚ь#фаХg*ЎЃ(Ў‰Хr+Už'TiнˆIIyРHD!Ђ]*ы№сУœ9s†L&CЅRсъеЋдыѕЬ(o?HтЙ{ЇгщЇЅŸђцрA’’ˆДайЖm/..о~ѓЭ7џфюнЛ+{Ќ:Н~УkzІЕІіŸКіУы‡Л•6э‚ХШЁ.ЛЗJ$&‚Ьс8х2•­*R‡@2„чъ(žMЇйЁГlR~Її-3чм0sИŠо)‡g“ўЈЯ.f[ЕцАЋаrZњхњ•ЮлcG­7;fЋ[bГНnпѕlЊ{†п8РјM0‰ќ?dOqїœ”књАž‡‰ю7, Eы/_Ў@Ыф$ЁуoYsss}EZёee]ё8b–œГЪbВXІі”Ѓй‹ЫЫSUUЅX,F‰ХblooїЉФbIШ Я_Ў† УыѕzŒŽŽіе}уёxП> €KМ'QhеtљК.//399йяpє7т`Ё›:=иWа•™srt!ў‚ˆ#МОHŸ„ЬИlјтяХњЎ“'O‡ЩчѓМћюЛ§Т ‚Я  Ќ\Hs>ŸЏB"§9НЌh$†ЄфaЉлcнИqуЪ~єЃonll,э•ЗGЌ tЖНB7g-Yхцrђiп/iЊпg„ЏgMЃ:3ч‡ё|>tПESiцЋи]›FБ…fФFќДЋ-кыю7kW­я…ы^}бЮwЖнkzX &Ьй№”~в,йѕ[нKН2•к-лСЃЗ—пwіr}‘ѓЗї^чОаџ‘  Nя&kЈфХ'ыюЧКЛ_h?ЈtPФpАШmŸчж­[ћ†ŠюЗ#т~3"ЂЫ!kхн‰В.Р РЉшVЋеНyѓцлЏМђЪЗЖЗЗWіŒЋЕgpюžљ€kЉ\ЗjнЊCQќўИ:ЄŸзўjЗл™ъѕlmюй–оОMНPGг[19ЇgЧЬ’Ещ4ДЋѕлНзКлокž!їіРEЗšЎn5]­“уnэКѓcзђЌ=ЃЖёАїОЗіŒНГ—яwЅЖпŒџЁрпј†іљЯ>"@žЅэЃƒxфВgЙпоA†=hќїK >ЌV ‹?я Тй@ Ащ%“ˆт˜МџM{eі™јНь„чеed ЋЖEўоWˆХњљj­V#™LтѓљИ{ї.щtšt:M6›эWї…0†HFGGяmЂйгкŠ5"Ь—=œiš4~Ф1ЈАдье)ЮhЯвіењ‚tъ]Њj#щЇgЕh•вЄУУ}у…B§q2=WD‚М#hИђBббQЮŸ?ЯЁC‡њyДфBтA-у}2ёjЧqњ3BœTsŸЛјŒфзМч(ЬызЏПњ§яџп–JЅѕНpКБg`сЁї†kќ@pЯу†л›^М`7шЙNhZ?Ћ‡ФЮRaЎ]o ЛаД›ъЛ•+цїЌŠWДn,сБ[{oя€&щњЋЎхy{П†mKЇй№нƒŒџЁ@Q”УЎыъDѕДRЉ0>>ўѕžA>шБњ№Cег 8hЬu№’‰1r+oя-@ž—CEyе—Ј„‹ТЃˆ ФюDсmD{Nюяw:вщt?чі<ббQJЅ‰D‚ёёqvvvњо]ž Ў"'їћ§§EІ}:ВFЃМћюЛ}ƒа‹|!CуK+t‡ЊЈ>”–Рu,туqZFF%‹i•йJмтxэ3d”IЪх2БXŒFЃAН^п'ѓ-j looї+њЊЊrша!ž{ю9FFF(‹,..і—­Ъ„%Йћ0x?ШQц j”}бm[|"-’I[тЏVЋ………WјУў^Н^п–Њш-ЩЛZМПgOлћ™8;{`Bе›ж[­uч–VУѕas\ jF{Чо4ГVжsњžК#…яЂ_яь€КїК$ш) л‘NWW:9Шј>+_Ёу/ŽŒŒ| џ’eР~0Œ“sџƒ<џƒZ‚sШЏMўАo2љqх G2ЅW.€ŠМW–• чК"J…D!ˆ*^ƒ№Œ>ŸЏOОIЇг§ѕcхr™p8мпА+Z 0Њеj§ xЋе"—ЫЧћsє$‰О(Іmльььаh4x§ѕзїбgѕИТPp”њj# 9&ˆqыі%ЂсёtœЂUІжВˆФЂмљ!ЉЫЧuїхИ5Mыw"<Яу;пљ/^ь__ПпЯ™3gxс…њоWАE‡@tDбS№>ЬQ JЄ‰TDxx"<*•Jѕж­[?ўюwПћэ^Џ—“Њч-)—ю фгьЈ№РННПž<­І[ГšЎоЩqW2RёЗт4ЅŸY{ЦЋHjОЊЛ?їdјчђљ<Щd’H$вПљЧЁRЉєG~х ..ю qч T@ЎЂЫ’ЬђNСG‰ю7жzПq`љЙзTЫДTЙЈ'WђyѓЂИ$Т–сpИ?ш"tъDЩdиййщѓФŒСЦЦ@€BЁаяЗ‹4Тuн>я_Q–——IЅRћ$УФыj4ћјЛЛЛ\Мxq_>ЌD\Ž=“WБz*Бу!з#Шpьа ВЛїˆV†C­нЃk—™˜Їra}QCЯНoМbрр7ошч§O=ѕўу.NNэoшыхХН%Zy‚'Wљ#‚ƒRОƒжtЫКђч* …Й\Ўtыж­ўр?ј ДцбdУ—M‘ŒЮ‘ТpSђшўН^xpWњЛžЖ[Rd!{яЈљJЯян'МЈ–кCEЛЛЛ=zДCЫсXЕZe}}ЙЙЙ}э9T–хЉ?LSюШ`p‹№a ‹[|,`ЪбŠx_Ђ`$jТ3‰Т ˜щ—г™+ЏэmE!V!„G„ЦŸШхEQPHŒ lёИB[@8;љ|ОяёcБX_Uз0 –––И~§њ>‚ РЬ‹У$Д›7ВИŸс'KА[enzз5iЗz„в1F2&Žэсz*ЎЅА3u‹І["yћЫЫЫ}%€d2Щ…g/pxў0MЏЪ?]ќŸйЕжI—Їљgў ъЅz_;aŸ†ŸZЧіl‚fД?ШЃN‹ЯP.иЪ"Ћтš‰ЯЊP(Ў_ПўнŸ§ьgTЄП-…њЬЅќFФ[њ'MМЏlмн=;гїТxЄ~0wЅШТ}yŽ:дЇHаЇыњзuЙqуЯ>ћlŸ%WMkЕЋЋЋ$‰ОfКЌ+Зъ›$ ОЬ “ qR zNС§ј ВкЎ Nђz,Qd™_/oЩX„Йbш)NїЇїVWWI&“§qYВЦуqjЕZЛЏh-ŠХЂ‚ѓPЋењ$"1ЩшИ6эV‡BЁРЭ›7ћ`$ kўйiмgwй]]С:жE6IŒІIЇ“”ъY–—nгщvшš6 >t]УЖ:ДmТ‘0uЗEedlgw=a˜˜˜р™gžavn–хцMо\љ ыeЌL‡„—‚”Щ?йјџ0ЭIžN|ЛЇаSLюr•UыmЏ†cйФнžеОJвњ€Vс d—ЬёчDt&RЛЭЭЭызЏџсХ‹_‘ _ЮёЛ[D“ŒŸћD–ЄРЃJчJурЩ?ВQ?6PхŒЂ(СНќˆ7npюмЙ~$ ZWBлОбhPЉTњnВ•ѓхƒŒOFt™j,{оƒV…дŽ”НјA;юЇ 8 ŽЦ C–…#u ‘HаqХјА№ˆнnЗOGХb§:‰Ђ(}‚‹( Šњ@Й\&P­VїЕ9ћаu]bБЭfГЏ™зэvqqЉй%vvВlЎoЁ9„ixYЃпџž§м(нЏlажGI аVК,–ЏблЦХE7|ДЫfЇCnЇDЃ ЉДGРч'  љ „SЄ†И=ЕТDїуО(Es‹ХWXБnа3кDЃ bбў`Mз)КYдQѕЁeђыw Х§8V–MмВE"“РqљёЪяpN§EІGіЕ{хTGQwŽH:WWW7oпО§‡WЏ^§‰dј­ћО§€№њУМБ'…њŠTЭ”žŸxFїwwwЙvэgЮœйЗ§зчѓѕЩэv›RЉD>Ÿgzzšббб}§еAЇъd’‘ЌwаšІСА,N9јѕ 1Юƒд€e>ПШ)Œ,.ŠyТИEN/ˆ/ђј{СдзЃбhьгPU•x:Б˜wžп4MFGGХєžЗВВВzчЮпП}ћі›{дићхјЮ[юух`T№XCї?+xn№gЙ\г49wюБXЌЏи"–ƒ ВIЋе"›ЭВЕЕE,ујёу nЪњAœ™э%wЗѕ qпœ$МЉ<бv ШЏGpл…G…ЌRЉДЏЯ,иf2IHєцыѕ:Ўывh4њ!Йи(" ЙUX­VћЯ+EХšВbБизшлннe+Л‰:гУ?ясu4”†Š‡`$HШo<&щNƒЇ`ЛёP’p0ŽукЃї>УfЋзз™Ъ№ьйg)wййЎ“J(Ÿ?I(ткЅK$’ šU‡fЋ†тТіЪ:Vз&OвЈhї,ДŠ‡ЂкXэуу#їfš=Ѕ‹ЎvЁзbљђ †ЦF1Т>6Ж№К“ЇІЩЬсѓi,.НGи‰3я{Њ?ј#WџХчЗДю;яМГѓэoћwVWWп>Р№;Ÿсџ\њЧŠfГЩ›oОЩддЧŽыsн2 і9љ‚rётХ}лV:д/ЮШћффB™L)•[y"bxPQp0мˆZ…,ћ4XФ”OЁV#*ж"ДWQѓшя‹л[T)wGф—ІXЬгiЕYИq™щCЬСl™ЋЛŒŽŽбЬUшLN<{ŒФpŠX:ЬЪ{З Љ1ќё!Жя”ˆdќ(];ыœyсйЕ"КФQиКAЏйeъи<бd„zЙA(bєpŒ^Їзяч‹YˆН”sћіэЛ7nмј|>џžTб9ОљЩ№?ё@Q”gЄЖХ}+юВитбЃGяGЂ +dМDЅКзыё§яПџ§oМбOФжкD"бя›Єђ+ыЧ жW=ЫF~аz0б›?чјХЯd]~г4ћТЁ™LІЯ2“wЅRЉ_зыѕњ:єbХЗЈ‡ˆЉ5Ё€“ЯчћУ;хryŸЦ‚а%ЇaІUкOЕpFЯЭ›7љюwПлЏ7„B!†††%‹133C,лзЖ“гyHч " ˜ь“@Њ”'ф„зн™S.в1‡/Zx" кккъ‹`Длэ>H^РЏќЪЏ№Ъ+ЏP.—ё<d2љi5yЊ/ элZгjЕиђ/бj14‡` €щoЁ тьЕXKе"_€žm’+d1Л]ќ†Ÿ™БЃŒM щ #C“<}ъ9Vзoѓжл?Ђc6P‰Dƒ}n€ќž+• хr™JЅBKЏЂ}БЫp4Ђyt:ЭНнѕM|ОCЩQtЭРBЗ…ЁДЭ6зЎqѓж5‚>…T"лывnЗЈ6ѓ<}ьyn/.pwen fgЦаu…Бб1E%ІZШ2}ш­Z EQЈц:фжыhŠСмГs M cЗ;œ|с—џш*ŽZ 2ЅгВше=šѕ:ѕJГkђ^ЖФ[p…нЛ=NСfxz„X&FЋоfЃЛєcЫВnE :аЧbјОёoФ}>псЋ<DЬ9ˆ-Bоl6лoWХуqтё8БXŒX,ж7@!ˆнsЭfГЪRQ2( љф >азГлйййGIN$”J%оzы­~r?]ТСйƒк•ƒKM XдСП …B„B!ќ~?ТуЋђћВm›|>OЁPшЏ_“лЂњS]‚БбPУЇс8.ў`„FЛNЕQЁбЌQЎ”Јжan"ІXXhш„C:чN>ЧhrˆЎеХvzt: b‘$КЊВЛSЄ\]ЇŸ}ž­5жя’ЮdXМЙЦФаsŸ=Эх7_уеЛ@Џ^žц—ўгЏвlиќ№Ÿў˜ьОђŸ}…3_Syя{яЁЋ mЫEз\ЮŒ(Дkh˜ьJžлo_ХаšL‹‘ž‰2§м‹Жv)юь’<”ЄUq(Ќхpm—h&Jj"ŽъƒШЮШє–ЕЦЦ­5ьžExФ?–мзя=1ќЧ Я<шf~”^ф§ЖЮо„BŒЎы§WN("‹ѕAйы @њ@!rbKь ёV*•}ЊС2ШlC‘B v&Ф’PQНЊ| /!~Q%‰>Гя~аыѕШfГx^yЕЗ ЁzЅRщѓ”ћЩЄ{ž‡pPІLМК‚Зэћ`d‚ƒu.GјЄGЇЂRZ­уЗ<Ќ]А&m1‘`œˆjаЊV(t:h†/q•ŠжЄаЉSo7љмgПH4’ткЕзикмРюA$Ќ“IХql‡Нўšг“&ЭbЈŽerѓRŽЕ;ЛœyЙЮЕ?~ИюgјГŠ[UJй:Ѓ‡тh>?•z™|1GO…‘iАmЈюxФF<ЌЎ…ч5Ј[~2‡3јУZP!=9ЭШь8сXUбЙњЪ{”6[dІ2ИIћKzTёй Яф§ М'ЧЧ€_џѕ_ѓљ|ЊМѓЈ@№aiХA’^*Ю іѕEсOˆSШ4п-5НпyP=с ŸєћG=њЎй0_C›А ЉбЛЁcoщ(?nФФ;UСwш6tЩI wЫ$’‘ЈŸђŠЩьё)<Е І… $Ђ)\`sg‹ёё)UЧѕ\ЪЕ пњ§пekГLЋa16ЌO$H$†шДLЖ7з „:nлФБ\кбX’gПcфH„?ИŒ]“чN`љ7/чсQ ЉЉsчцА}п'>CгšЛu’iV/­в(t8tv„nЋйЌ3їє иФЛ0н"ІЮ†Ре9њЬQ#qюМЖ€YЋ‚Ѓ[ЙS0q6ХјёiЖoeYНК…йm3>ˆ…зVинйdўlŠvГIaУтФ УyіНЎУюr–NГ‡?ъŸ†ЖЪ|Rјˆ П_UеГу?J ёQ#ŒOЋз?Ј№чК.ЎЯB™7IKcј ЦfЦшš-n^КNЛnбЌ7ІQnrфФ)ЂёcгQVоЉŠqЛ†EЇнЦ6яб—UECEcs)O0ЃЂБqHЅ†ˆG2˜M“е;›tЭ:ЉLMqI% …УВyv6WP5“ЉљfЭ‘NŽ кlЧЃАQ&vёшЖ зq™NвЈ4XОКHr$Ejfˆ#Ÿ;IЋоФД8]‡ьн-‚сЄнpЈз‹(]УЇ К…ѕ2Бб_ќеѓLœ˜DQuv–‹6ЊЖ*ФЃёк“№џёЄ*`LNNžR%§Иnъ? Ѓ˜ЂрЇіЕѕlЎл"ЛГЩсcטš;D8Фuю.мЂVЖPt•x&Ъът сp”™“cd—ъXm еѓ№ЉvлdxzзБщu-вБ4šычЮеeLгCA Ђ †˜š™х3/ S)–йZпЂбhSм­тК‹CjtлmR+ћёPЈ4Жб”(ѓчŽѓkч?ч{џъ_аЌ˜Є†tvVВљѕ…Е g_>OqЇЦіт‘LUWиККMіN•Щ3sЄ&F)nVˆ\УuылєФы|о?Ю}œ‚мУЖL›}ўУшЛ?я†/Оі‹ЖC$&šˆaј}мЙu“ЙЃsЬ?LvkУшŠ˜>4KaГХШиwЖp€H4B@ѓаЄ†4›eCqš­6љ­щё‰б(…ЎтŒ„Р…f1OhdЭqш4[LNФБMГлcіШ8БhЧQ#Пй ЗКЭЬW4™БTЇmтКˆшд=Š[ІOfž Ё(*ў˜мЪwоЪ2u*Efb˜h2‰‚BЗmNЃљќЈm…Cѓ‡ …hЕыь.э’_ЭQ+еh”+hКЊ*ЕкEы7{UзdПў“у#€ЦННfAПпіq?СУњуф|;§OqёЦ;ŒMŽЃhрКЮќЋпуфЙ3ќТ/ЯЕИёю{Мћу‹œ}ўZ­6Хэšj И ŽcS)ч D тC –o/R*–iеmЂ‰љХ“є:]|!?~н`эі"]ГЫєh’љгЧIЄTŠ%щ ›З—ЉUЌ-f™;6ƒл04Сv6Шnь2|h‚jЅNЋjb›Ї_œ#žI[н%  †™<6I$С ‘]мЂМSEЁQiŠŒ‡ЉЫ(лŽ— Z,уррИ*сx”Щ#>JйŠ[Миў;+l№ОИЧx VUѕд'хѕ? т|œЮУЇюP=<нСХ!q.ˆЎшѕ:T U#KQЩ—hця­ЮjV:9}šnЋCН\Gг5FOб<эZ™h"ШgОјYVWWиXЮ )ŒNЄШo—щšpтk'pl‡Е[KЄ :&СŸЉй)шЊДs5&ЧЦi95МЎЭиь4щ ›л—VXПЙЮ™—žТщЙМўЧ?ЃQmˆЦ š]|†Šы:8n›ѕ…fЛƒцKГНВЈдЗышh#ьЧщ:xžKiЃj#`АЖКFїэ.™Й!fž™Сw 4ЋкkНмЙЮыМ?§g?1ўЧšІEyњqф§ѓу0фћ к~ўЏИx†MНQEйэ12>†Њ)˜=‹CЧfйИН€єу‘ЬŒАГЙC,šЄQk’Nу„zу%ŠgZќо?ўз$FSЬLMrјЬQ2у‚‘ šnаЎ6ј§ђЧTr ŽЬ‡Y]YAёlвё4VзЁR(нлJœЏKФ)чKш†дФ;wЗqm—ХworхЧя1sђ0+ЗVuќA_(HaЋDЃ`3}j„щг‡Јхšмyы6хc‡уŒЧђS*VСƒєtУoPЩеQƒT5:u“Е+k!Oѕl3g§qщћwx_эGzКOLљу€‘L&{žy\•ўП4žћqжl№T{ЪF‘ZЅТјЬ‡ŽЧ04жnо"Š’_[ЃеhOЅˆЦ’ф6ѓиЖCЛо&яd9rzkлЄК^ЃPЯ3wђ0>/H}Г>Њc+RƒЪjЧ1hе]z зДi•:8†FyЗLnЃHЇхrшДŠлs0;]:,бTŒЭ…uбѓЇ3:;СЦ­йх Чž"31AГbЂ @'П^ЂQhˆј™>!šJ ‘LŒH*FЋв"”Œ0vtœаZн;9єДЛлЅS1ЉmлзмКђ“в[цЗyP,ш|2єŠ€ZЗлЕхЏgрЃќьaъї–љдE ЎЖ Ж†š<ЊQ(ём-Тс8ЃуЬ>LЕXтжЅыŒ;N8& 257IЛйХlєЈэж(&ЋTЖ и–ЊX^XgwЋLaНHЛYчм—Ю№д—ЮёйПrŽЛWзЩ/oЁЈ=лЂоl ЁуЙрїыTЗz˜.УЧЧЈ—;м}w•!g нP№ƒh:Фг_~žЪцžЯ‡ы‚еа(ЎA,н" ŽRмЈ`Е{„УЪх2Эz‹ФP’x&AЛб"7K0!š‰ВГVьZmЛЅИ,wVјWнВГШ=ёЁўг}’џ? бh]зmИЎ}и §‡з§ zќq ?Ёь†G8СдЩmюrхЗfjf’эхUКf‡лWn21=A $бЎ˜x]›`0B~ЅDЏicЕmž~юяўш2Бdš™ЇцЙўгk\љщ юоЮ24• 9Тs\ЂуSh>ТFХч1<;уZ зшvКи–Ыиь8йХVЏg9ћв1jљ •BžpдЧ{пПNzz‚H&ШЯўЏїˆЇ#CЊcѕв‡žчФ‹ЧИјћWp•й3ѓl/oБve ЋэбmC(#G‡СUщ5ЌUs…ŸY5їЖчВЭўН}Вё?9>&єї˜ѕzНыЊЊ~npyЧЧЉо?юTрQ~ъ”˜E8U+~Џ`шdЦScЧЇYМЖAЕоЂЖp—Ї_ќ …]6nчIfЂдЖ›ŒЭ&™<7Ић“JЅАx?ˆ №Љ­„,ТЧ=ŠЛлрihКBzd”ёЙi’щ8ХнСh„ЯўтYrыМr{ђV @4Њуєl†gcœћ…S4 u4CчЬ/œЦьTЩнн ѓ“ЦаШејЩ?Чіhз:8–‡Bjj ХѓшњЁЖйsнаDФ‡†АкЛ4+ @УlЗ(э”й\МУ™_fge‹сУ1л  њ;˜-“н‹N)Ядё ?eа(жРѓш6zXСЈŸzЁN  ”дще+о_Џн‘rў' ьНjЊY,пˆХb—іvєAрЯЂ јqтгlєћj†ƒ’В№%tBё$ŠЇN`ЖšМ§НŸrфм1ЌЎMn;Чсc‡јўяМ‰ЯяpїіІŽfющуdя гiЕИђнЋ\§г+ЄчSQwuвsУŒM&rљђЛ”ВEšе_ћЏПJb4Ž?dhbŽFЃФЕ\aщE9L#5‘bt>B5_Уъир€Yя‰ƒныЂћУз X=›л›$Чc MВsЃгВШ-˜$2*‡/Ьbѕ:Ќ_о`уъсtUQЈцЊŒ˜@Qф”rR ЂИОб?бєџ„@Ќ0nѕпšššњ‡@ъQ‹qŸdѕџQќг2(ƒ€3в vFeъШэv<^Ћ…ЁыФгQІЮБЙВСюъGOŸсЋуeЎн"іЃЈ:НЖMuЇƒЯUXкЎ2:“fїZ‘аtMїsфЙгœ|љ,?ўэWёL;ЫЏќП^"˜рКЎлСvЋмНВРЗnБ№ъMBЩG>w”ѕ+›ЌОНТ‰/%‰aј‚TВ5,Ы#’‰3їДђN­…5ŠыmкUˆІЃ~уо-цB$ЦlѕЈlз;>†ЂnбЊ‚юяRЩVёGƒД*mЌnЛka 1кн`хЃbќzLг\Ыхrџ`ddфПѓ!€Žє;ЗзыЙkkkџг№№№зRЉд„„ЁЪ :З|X!ƒ$Кf'СЇЙјљХС8вЃZЊђіwЖQlнoKŠ˜:q˜o§џ~‚тДа*ЕнšЇ0~tœјP’rЎТнwn’ПВKи0Hd’ MЯБ№ЪэПџ+4Жюr§{‹,ўt‰zЉJцXœ‰s#Œœ гiБ}3ЫХoОGњШ8Љщѕн6хl C…мbŽТjž@4BЏн%3уOPЫщuL&ЯL`ЖLђЫyЫ`ђЉq~pЗЕнСXеPБкCГiRq†™LžЃлъб(Ж1~Ъ›5jйŽх ш:Е›цЗьeіoє}ŸˆУйЫБИЂ>ЯчП]Џз/§H$ђEQTйИХz/Бšы ыGЩуFКћЯѓx\s }б˜IБЙ†Га# 1їєaNНxŠЉЃг˜M“хЋ+ OЉ OгЎ6)e›ЌниЂYoЂ+:z›Ъ‚EЗЩГAJ+eЦfSœќkЇјGх'=сушOђйпИ€еэaЖк4ЫMЖЏi5[l/d9євЂqюОs‡ъZ…P"B0f§ѕz]‹ЁуŒDњfЋнСд)ЏЗ † Т ЖkПгЦЌЕ;3†О”#ѓcЖLjйVS%ў™8Сx€эkkЌ_мdќє$­b›^ЧТЕСюЙh†гVк ќ”їл€r №I№qРЛяОыэЩ‚йRО%Ђ‚`šІйY]]§_Ѓбш‘ббб7‹]4ZyянУШ^? >Ьћ?шq>i€xп<;е$2хЬ‹g™?wšPмТЌtyчїЏаЈ•шXТQ?Ї_<Щш‘ šехѕ*ХЭЅlEѓЃ'! ЁДВK>WФВtF 1zr5ьЃV­гЉtP4O3PTƒЉЇgIJс:!†Nгэth—|ё0СtˆєL$РвЯ–iКD†#”—[dŽЇ0 еЗюbла­Ь<7ƒуuq­•­ Њц1v"Aљn•ЦЮ.šžТѓБs­@(S#1–РS льЂj–щЖЋoZџчžс P‡'ƒ?Ÿl№юЛяz.\IЖT0VЃбh6•D"q|ttє+ёxќр—ѓјСх—тпbsюƒRyAn->ˆѓџi џ…€1ъžOQЩyуіїIщЖлМѕћwи]€ѓџAзѕ[ымН~—№P\rЅLГг%’L267Эшј$(6ЙХM2G†јщoПƒ?l`›=ьnгДА-ЯU$`yф—vY~}…Pl‚бГGЈЎZDЂTZЙ6VаЄYЌcж(hTЖ;l/T+Ęy~”‘АAa9ЧяЕё'|œќkаkXД+|!Е*šЁˆ+„Ч§DFƒшFЖNuГŠЊщh~ зёp,—ц’ѕ{Vйлс§ЁŸжоН'р шJЂw чВі@ Гї4ЊеjНZ­.ј§ўЁ™™™—SЉд‹Ра`~;˜*ˆN‚ эт{˜сУўЯЯKИџa``VК,ОК™‡`ЦOІ9єќ_јOЮБu}EГщЕjЙ:Е\Х€иP еаАЭ…еzЃŠbS[/бišЌННУЬgfЩ/эВЛT"Rы‹сљiз:уA"щ;W6hʘЅ NЯЁSщL‡ЉЌPu—шpвЊЩ№‰8ўX˜ЛoяіpЉlеQmC3у№r‹хŸeYњЩ"щљЊb`DuьЎІыlп№ˆЄќ~ГaG)oБЬ]"™Žчa7”kлоyŸїпр@юџ_и™?/WЊXМЯhэ}8сnЗ[ЙsчЮ№ћ###ЧЦЦЦ>322ђМЂ(Qyw|~иЇiZуэAыАў,?єOќЙ<ЖЂDG &>ЋN(–Gy­LЏхрt їБ˘#=bць,‰ёНŽEn5‡Я№Я„ба)Ў)m– —_Л‹к…ЙчGhlUi[ŒyЦ”†гА0ѓm|СЎЂ2~v”Фь jƒFЉU}zˆ7жYњAГцбиьa6Ћ˜ўw†1т>ђ‹yT'„ЂщŒœЮp›ќЭ ‰‰б‰Йы9TCAе bSБс8ŽхRИSDеT|бЎэRЯ7СU+ѕw{џЧžзo№dьїЯRWњDM Л ИзхrЙR.—ЛќЫЙЙЙГcccOЅгщУ‰DbVСA{ѓdpаu}пКыAваAџ“Ž>ЩbЂЊЈhЅ0VЩ œыа;трqЈЏW(ЏЕP•`R#9 SщА}s# SЩUйМ‘E7 бэ™Дj’Ѓ)№dвЋѕ0Ы6К•]HЯjу~TCУ L9<ŠуКф–ГИ.4J-zm—X&IЋRѓZеЖcзН_д;Ў:НКЭфЙІЯOrћOю`[ЊЊPлh`tЂуQ|A ES@‡VЩdїН&Nд”‚хyЄg|ЄŽЃzmhgыLМ4C}ЛNcЋAўf‰БѓУ„GТt›]Ъ+%p4P,lЧ"˜тйЭЮњлЮџŒK(%ю 4їЬНџЇН%ќчўњ€і˜ƒ{Ї ƒ  €ср‰DbЇN:<999ŸNЇ'‰Фp8N \<”#ЙЖ№ кїѓТƒ€? >l9шряW‡&28ŽCЏзЛїГPeЊхЊсžЂiž’ŽЫ„и^.cж:D‡ЂјB>ЦNŽ“œISИ›#˘Cѓы4Ы-r+Mc!SS;•ѕязoиo)CŸёџ{Ё”ёхфx\ „|l]мЁ•ыЂћRSqє гsРup0ќО„=тЃ]ъyН–гЊфъJЋж $Ї"EUДnН‡Ysш5zD'ca•њVзq‰MG БM‡ђJ…P:HyНNl<@Џсх*ЏvџОгdЈHgcЯјхмŸ'№s Кt>Фї†ќurrrшШ‘#s###S™Lf2„Ус4рыOа —мFt]їƒ  ђcFђsп/АmћО+СХяlлvКнnо4ЭМišхNЇSы˜КчГЕиqѕXђxшАЁЉŠЎyсЬёНЖUЧh>UU1;Zе6zРРѕгm[TЖЪN'oПanЈп6зн…НpкМи эh`ŠПуѕœ“ЉЉ(šЂв)šb~†Že№E}4 mЬšIЇвХq\ќщ mVКыЭlwЕлЕА=7Ё xЎэъžKЦƒtr.ъГMKїE TŸŠЂ*T–kєкУч’Ѓ wŠиеQпn/xџТЎzл{aЈIЙџCЕ§žРЯ< ”AD њРзƒОё3§щЇŸ>ТЉTjФяї'ќ~\зѕАa €P(4цyž*_dЙё уПмюїЗІiц\зЕmлnZ–UqЇešfб4Э’eYЕjЕКщ8NOњ,4ѕАŒiЖik™3ўѓ™S‰#КЯЇX_@Gъ”VЊХн;хfxШŠЧ:ŽуšэBgЉrЉїЛfжYч}]kя9|@ xŠ_ gј/cЃс зsiьtHLEЩOЃtš…6ѕІз,ušvлЛг-Йяі*юTl5H@е5[1М R'бнI&4ПrдБАсѓнЦUГЎуbVzžTёE|8Жчй ћЎЙщ\v*dЅЖrSЊњ уЗІъџ~Юр>`0@P%PаЅšТ Pш€!ŸƒџW“_KЇгёt:Яѓ”x<žђћ§бН‹ЏьƒСДЎысћEЖmїšЭцЎEИ{^О[Џзs€ыyžзэv›•J%/LХ)ИЖдQ_ХbKm 2 ŠД)2ЇOЮ3FXбCкx0ˆ†‘+]k~ПЖfnЊa"Њ­nК&ЅnЮн№м~AMPi d@а?ЂN…ёСДяkvЧж­Жƒюгt=hиЎэvz-ЛмkЙKvйЛhхЙэіЈ!щё+ŠтS|ZˆЈ$хyvб+ИнўsЩЌRљћƒ ЩтuЪŒ?ячо€žРGЙЈоД"‡ђџSЄŸ žђѓ*М–ўuŸбоWљ&<]щЋЬќ~ м0W.Њі A-LL *‘ШМ~ЬŸжЇь •ЫнwьЖ+кe}ЦІtЪ}tEКž`BzDIgечПї4š7ƒЃ4\SYvл^ЖWfУЎЛ%М}в\нм|№3Rр ыdK ал;­G1ўПЧЯќ/ŸАнД7<м|8 оьъ@*аo­ŠєGQQQp=Ї/iIF$@Р”ŒK6VфчHѕ!/шр=щ1{вcОfU`p< хОўRѕћŸРG†ƒў­оЧ›Ћ0ђћ}?xђ§ƒ"ƒ}я <ž*ЅFОh@Є@Ъ€ЕО—ж ™њоцЗLљњШЉ•OЊПhЪ0љqнЯjhЙЯЕт> щё—щї>оk~cОпяњї}?ЏєA №0 Р™џ&у5 жўewиДa6Ц)uЂŒƒŒjАksPJ…dЌЮРsИїyЬСkюЄpАЖп_J–пјГ}Ъ‡МwхCŒџA?їђяіu\пP jю}Мщ‡Нх€(iа‹{љиЪ#\Г'Чxr<"(ї ЏнћD&'хz {r<€'ЧŸC$ѓ8#Ž'Ч_Vx2O§фxrќх=ўџŠHО• ЄЬIENDЎB`‚fwbuilder-5.1.0.3599/src/res/Icons/32x32/0000755000175000017500000000000011733011756020212 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/Icons/32x32/fwbuilder.png0000644000175000017500000001232411733011756022705 0ustar sylvestresylvestre‰PNG  IHDR szzє pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХF џIDATxкЌ—[lчy†Ÿ9я —ЛЫгђ(žu"Sq%ЫjMdФ@UР.RјТ‚э›кh„6Hс ЃшMQЙhЗ…{S Нh/фqrРвhкЬX’[ЫЂЭхaIŠЛфЮюЮЮюЮьџ^P"’є"Nм˜›™ОїџОgоyщ­Зотж­[мКuЫpч;Р„Тt!„’ІiebbтЏп|ѓЭoёџДОљЭ?G’$T!ФЩЭщщщЏЬЮЮ~Хѓ<ХЖmrЙЭf“ЩЩЩйVЋuјжЭ›7П—ІщѕzН~W’ЄП“eљŸо}їнфWЂъК.ПўњыkЭfsЖзы ŽбjЕX[[увЅKloocл6šІ !n!˜››ЛтКюY–eр~UђэлЗхZ­Ж|уЦСчž{ŽгЇOS­V У(ŠА,‹нн]оxупт‰'žрЪ•+!ўўѓŒB­еjRН^пд4}щњѕ/Г[.qpА‡ЎЌЌЌP,щѕzЈЊšЪВќ_гггьяяѓо{яЁыњчfAUUY–)•6ШхВl—>fxh˜бБI†‡‡q]Чqh6›rЕZЅRЉрК.AАККЪ‹/ОјK^YY: I€ЌЊ*qГАИРЬЬ<ЕZ ЧqАm›zНNЃб лэ"„`ddMг>wф(ŠR!D,Ы2B.?}U<ѓЬГтьйГBQdYFUе“K–eв4e``€ѓчЯџТзЎ]5Я;ѓ;љ|ўžešuг4їgggО.I’$!w:ЄнnџiЧ-EQ™_8‡ІiТѓМрQ‡~VЕ,ГННЭцццн4MŸљљчѓѓsCУCC00PX[[ћ Y*mН#Сj.7ипп?ЙГSў+щј“BО|љ2ЅRщлХbё;žчё№сОT­VхzНЎ…aH’$$IBЧФqLšІЈЊJБXdxxф/dYў7MSg CџЫО>ы“rЙ|иtœПщtКу81$IBеTіїї9::@’хc–——8sцŒЖИИˆЊЊDQ„яћ'Лз4BЁ€Ўы$IТрр ЇNЂбЈŸѓМюk~пmwžУPz,4›эУѓ|lлЦВњА,“ХХEЮœ9ѓЈKѓ!Ppg`hhˆЅЅ% …Н^0 9<<ФЖmšЭ&•J…jЕЪ#Cтюн{rяо=yzzšbq„l6Ыњњ:Оя399AБ8ЪйГg9ў<333ЬЯЯc:|pч`5Š"в45766А,‹ХХEўћУЛ4чЮ-cYFƒ8މЂˆFЃAН^ЇзыЩaВЕЕХњњ:_јТ2B.\ИРХ‹ПЦмм ‹dГYzНН^яdiš pEQЌ™™rЙ<N›oПѓнn‡0ŒŸ˜"Š"ђљŸЇлэђ№сCЇIБ8Ъшш(’$быѕhЛ.їяпчњѕ/‘Ячшtк'€Ћйl–$I2ОячTUezzš‰‰ ^{эkTЋZ-—NЇУаааIKлэ6ѕzлЖ)—ЫLMMбl6Йџ#„HИ|љ †a ы:ІiR,Ž№Т ПЫииОяŸ@ЌЊ*ъРР’$)†aшКЎГЗЗGšІdГY‚ Фѓће „}КЎkЫЫЫTЫмО}›nЗЫ+ЏМТььќIјhЗлt:Z­{{{,..R,шvGQ(PЯѓаƒњЧќ(ї]ќ\“ОИu@‘­эЌišj<ŽЭЈŸэmмv›0 тиЙс№№НН=т8&—ЫEЖmЃ( Й\ю>I’ŽчяGмэќ;^ЁƒЊъ„^D&Їг7ЃџК211чy_^\\| —Ы‘Яч"%“Щ0ZEVŽŽŽNўКЎ3>>Ži™”>йd(7 ’@QмVЯїqЬNa7ымЉ§+fAЇзlП…Л?ЌџЃZ.—еЅЅЅ7\зЅP(0>>Юјј$ЏОі5іэ2MSLгЄеj ы:NУaЃ‚“9фшмЧdзOЁћ:Іeajy„xžЧжжж§џјсОЕYн>љЂљUg/ИзЋ…ЅИ—Vт?V]зВm{nllŒzНЮЮЮiš’Ых0 пї9::ТѓМЧйЧvљфр>ељћ ўЖТQі#ЊщIC';laюŽФЂ”§pэЮћћщЇŸў3аш~?ќюџ ЅBˆЅZ­–)—Ыфr9>|HГйD’$„ФqLН^Чu]ŽуАWйЅ}z—Сg№ iHDr@Лэт):нюоњЗwЏо/LХЎы^!Žc‚ рqlЕZ8ŽCЛнЦqœcы­жiXВ_эЂtфŠIнv(ŒаrD&ЁчFј~€Є‰Яp^RII’PUEQ$щ„ј0 ‚р$œЄ‰€ОўQЩˆЊЬ 6@яШ#РїSтІя—оn|C$DŸщ\P­VџЬ0ŒСсссg5MS3™ЬЯШO'bш;ѕБ-œЬбn%4"U&:• Е’жX~yMг|jaaс7WVV.MNNЮЫВ<ЧБщћОцКЎh4Ё]ЋЛ5v\s9œ=гVК•›ВЎ5іН=ЩRДШ§кќ?JКтћПД€Ÿ[:аЏ(Š)ЫВ!„H“$щ !К@(ывœˆ…-RjВСй4рˆфГ€їгыхЯ>†——qIENDЎB`‚fwbuilder-5.1.0.3599/src/res/os/0000755000175000017500000000000011733011756016777 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/os/ipcop.xml0000644000175000017500000000621611733011756020640 0ustar sylvestresylvestre IPCOP Firewall Appliance active ipcop ipcop false 1 lo /etc/rc.d/ rc.firewall.local root /etc/rc.d/rc.firewall restart False /lib/modules/`uname -r`/kernel/net/ /etc/rc.d {{$fwdir}}/tmp False True True True True False ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/os/pix_os.xml0000644000175000017500000000444611733011756021032 0ustar sylvestresylvestre Cisco ASA / Cisco PIX active fwb_pix pix_os pix_os pix_os basic true flash: flash: True True True True True True pix_failover,PIX failover protocol none, pix_state_sync,PIX state synchronization none, True True True pix_state_sync True True True True True True ethernet,Ethernet 8021q,VLAN unknown,Unknown fwbuilder-5.1.0.3599/src/res/os/fwsm_os.xml0000644000175000017500000000224111733011756021175 0ustar sylvestresylvestre Cisco FWSM active fwb_pix fwsm_os pix_os false disk: disk: True True True False ethernet,Ethernet 8021q,VLAN unknown,Unknown fwbuilder-5.1.0.3599/src/res/os/openbsd.xml0000644000175000017500000000536711733011756021166 0ustar sylvestresylvestre OpenBSD active openbsd openbsd bsd basic true false 1 lo0 /etc/fw {{$fwdir}}/tmp True False False True True True carp,CARP none,None pfsync,pfsync False True pfsync True True carp False True False carp,CARP ethernet,Ethernet bridge,Bridge 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/ifconfig /sbin/pfctl /sbin/sysctl /usr/bin/logger /usr/bin/expect fwbuilder-5.1.0.3599/src/res/os/endian.xml0000644000175000017500000000622311733011756020762 0ustar sylvestresylvestre Endian Firewall Appliance disabled ipcop ipcop false 1 lo /etc/rc.d/ rc.firewall.local root /etc/rc.d/rc.firewall restart False /lib/modules/`uname -r`/kernel/net/ /etc/rc.d {{$fwdir}}/tmp False True True True True False ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/os/unknown_os.xml0000644000175000017500000000354111733011756021724 0ustar sylvestresylvestre Unknown active unknown unknown true /etc/fw {{$fwdir}}/tmp False False False False ethernet,Ethernet unknown,Unknown /sbin/ifconfig /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ipfw /sbin/ipf /sbin/ipnat /sbin/sysctl /sbin/ifconfig /sbin/vconfig /sbin/brctl fwbuilder-5.1.0.3599/src/res/os/dd-wrt-jffs.xml0000644000175000017500000001144511733011756021655 0ustar sylvestresylvestre DD-WRT (jffs) active dd-wrt-jffs linux24 linux24 basic true 1 lo True /lib/modules/`uname -r`/kernel /jffs/firewall firewall.fw root /jffs/firewall/ /tmp False True True True True True True True vrrp,VRRP heartbeat,heartbeat openais,OpenAIS none,None conntrack,conntrack True 224.0.10.100 694 False heartbeat True False 226.94.1.1 5405 False openais False 225.0.0.50 3780 conntrack True False False False True False vrrp,VRRP heartbeat,heartbeat ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /sbin/insmod /usr/sbin/iptables /usr/sbin/ip6tables /usr/sbin/iptables-restore /usr/sbin/ip6tables-restore /usr/sbin/ip /usr/bin/logger /sbin/ifconfig /sbin/vconfig /usr/sbin/brctl /usr/sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/os/ios.xml0000644000175000017500000000317211733011756020316 0ustar sylvestresylvestre Cisco IOS active fwb_iosacl ios ios basic true nvram: nvram: True True True False True none,None none,None False True True ethernet,Ethernet 8021q,VLAN unknown,Unknown fwbuilder-5.1.0.3599/src/res/os/macosx.xml0000644000175000017500000000274011733011756021016 0ustar sylvestresylvestre Mac OS X active macosx macosx true 1 lo0 /etc/fw {{$fwdir}}/tmp False False False False ethernet,Ethernet unknown,Unknown /sbin/ifconfig /sbin/ipfw /usr/sbin/sysctl /usr/bin/logger /sw/bin/expect fwbuilder-5.1.0.3599/src/res/os/sveasoft.xml0000644000175000017500000000545111733011756021360 0ustar sylvestresylvestre Sveasoft active sveasoft sveasoft false 1 lo /tmp root True $ # /tmp /tmp True True True True True False ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown lsmod modprobe iptables ip6tables iptables-restore ip6tables-restore ip logger ifconfig vconfig brctl ifenslave ipset fwbuilder-5.1.0.3599/src/res/os/solaris.xml0000644000175000017500000000264511733011756021204 0ustar sylvestresylvestre Solaris active solaris solaris true 1 lo0 /etc/fw {{$fwdir}}/tmp False False False False ethernet,Ethernet unknown,Unknown /sbin/ipf /sbin/ipnat /usr/bin/logger /usr/bin/expect fwbuilder-5.1.0.3599/src/res/os/oneshield.xml0000644000175000017500000000621611733011756021500 0ustar sylvestresylvestre OneShield Firewall Appliance disabled ipcop ipcop false 1 lo /etc/rc.d/ rc.firewall.local root /etc/rc.d/rc.firewall restart False /lib/modules/`uname -r`/kernel/net/ /etc/rc.d /tmp False True True True True False ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/os/openwrt.xml0000644000175000017500000001140511733011756021220 0ustar sylvestresylvestre OpenWRT active openwrt linux24 linux24 basic true 1 lo True /lib/modules/`uname -r`/ /etc/init.d fwbuilder.fw root /etc/ /tmp False False True True True True True True vrrp,VRRP heartbeat,heartbeat openais,OpenAIS none,None conntrack,conntrack True 224.0.10.100 694 False heartbeat True False 226.94.1.1 5405 False openais False 225.0.0.50 3780 conntrack True False False False True False vrrp,VRRP heartbeat,heartbeat ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /usr/sbin/iptables /usr/sbin/ip6tables /usr/sbin/iptables-restore /usr/sbin/ip6tables-restore /usr/sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /usr/sbin/brctl /sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/os/procurve.xml0000644000175000017500000000245311733011756021372 0ustar sylvestresylvestre HP ProCurve active fwb_procurve procurve procurve vlan_only false nvram: nvram: True True True False True False ethernet,Ethernet 8021q,VLAN unknown,Unknown fwbuilder-5.1.0.3599/src/res/os/dd-wrt-nvram.xml0000644000175000017500000001133711733011756022050 0ustar sylvestresylvestre DD-WRT (nvram) active dd-wrt-nvram linux24 linux24 basic false 1 lo /tmp root True $ # /tmp /tmp True True True True True True True True vrrp,VRRP heartbeat,heartbeat openais,OpenAIS none,None conntrack,conntrack True 224.0.10.100 694 False heartbeat True False 226.94.1.1 5405 False openais False 225.0.0.50 3780 conntrack True False False False True False vrrp,VRRP heartbeat,heartbeat ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /sbin/insmod /usr/sbin/iptables /usr/sbin/ip6tables /usr/sbin/iptables-restore /usr/sbin/ip6tables-restore /usr/sbin/ip /usr/bin/logger /sbin/ifconfig /sbin/vconfig /usr/sbin/brctl /usr/sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/os/linux24.xml0000644000175000017500000002005211733011756021025 0ustar sylvestresylvestre Linux 2.4/2.6 active linux24 linux24 linux24 basic true 1 lo True /lib/modules/`uname -r`/kernel/net/ /etc/fw {{$fwdir}}/tmp False False True True True True True True vrrp,VRRP heartbeat,heartbeat openais,OpenAIS none,None conntrack,conntrack False True 224.0.10.100 694 False heartbeat False True 226.94.1.1 5405 False openais False 225.0.0.50 3780 False conntrack False True False True False False vrrp,VRRP heartbeat,heartbeat ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset /sbin/lsmod /sbin/modprobe /usr/sbin/iptables /usr/sbin/ip6tables /usr/sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset /sbin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset lsmod modprobe iptables ip6tables iptables-restore ip6tables-restore ip logger /usr/bin/expect ifconfig vconfig brctl ifenslave ipset fwbuilder-5.1.0.3599/src/res/os/freebsd.xml0000644000175000017500000000556511733011756021146 0ustar sylvestresylvestre FreeBSD active freebsd freebsd bsd basic true true 1 lo0 /etc/fw {{$fwdir}}/tmp True False False True True True carp,CARP none,None pfsync,pfsync False True pfsync True True carp False True False carp,CARP ethernet,Ethernet bridge,Bridge 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /sbin/ifconfig /sbin/ipfw /sbin/ipf /sbin/ipnat /sbin/pfctl /sbin/sysctl /usr/bin/logger /usr/bin/expect fwbuilder-5.1.0.3599/src/res/os/secuwall.xml0000644000175000017500000001024611733011756021343 0ustar sylvestresylvestre secunet wall active secuwall secuwall basic secuwall transfer_secuwall False False /opt/secuwall/templates/default files 1 lo True /lib/modules/`uname -r`/kernel/net/ False False False RULE=%N ACTION=%A 1500 ethernet /etc/sysconfig /tmp False True True True True True True True vrrp,VRRP none,None conntrack,conntrack True 225.0.0.50 3780 conntrack True True vrrp vrrp,VRRP ethernet,Ethernet bridge,Bridge bonding,Bonding 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown ethernet,Ethernet 8021q,VLAN unknown,Unknown /bin/lsmod /sbin/modprobe /sbin/iptables /sbin/ip6tables /sbin/iptables-restore /sbin/ip6tables-restore /sbin/ip /usr/bin/logger /usr/bin/expect /sbin/ifconfig /sbin/vconfig /sbin/brctl /sbin/ifenslave /usr/sbin/ipset fwbuilder-5.1.0.3599/src/res/fwbuilder_preferences.dtd.in0000644000175000017500000000532511733011756024031 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/res/objects_init.xml.in0000644000175000017500000022156411733011756022173 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/res/res.pro0000644000175000017500000000366611733011756017704 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) TEMPLATE = app win32 { CONFIG -= embed_manifest_exe CONFIG -= debug QMAKE_RUN_CC = echo QMAKE_RUN_CXX = echo QMAKE_LINK = echo } !win32 { QMAKE_RUN_CC = @echo > /dev/null QMAKE_RUN_CXX = @echo > /dev/null QMAKE_LINK = @echo > /dev/null } TARGET = res win32:target.path = $$PREFIX/ unix:target.path = $$PREFIX/share/fwbuilder/ macx:target.path = $$PREFIX/ res.files = objects_init.xml templates.xml resources.xml res_os.files = os/*.xml res_platform.files = platform/*.xml res_help_en_US.files = help/en_US/*.html help/en_US/*.png help/en_US/*.jpg res_configlets.files = configlets/* INSTALLS -= target INSTALLS += res INSTALLS += res_os INSTALLS += res_platform INSTALLS += res_help_en_US INSTALLS += res_configlets unix { !macx { res_desktop.files = fwbuilder.desktop INSTALLS += res_desktop !isEmpty(ICONSDIR) { app_icon_16x16.files = Icons/16x16/fwbuilder.png app_icon_16x16.path = $$ICONSDIR/16x16/apps INSTALLS += app_icon_16x16 app_icon_24x24.files = Icons/24x24/fwbuilder.png app_icon_24x24.path = $$ICONSDIR/24x24/apps INSTALLS += app_icon_24x24 app_icon_32x32.files = Icons/32x32/fwbuilder.png app_icon_32x32.path = $$ICONSDIR/32x32/apps INSTALLS += app_icon_32x32 app_icon_48x48.files = Icons/48x48/fwbuilder.png app_icon_48x48.path = $$ICONSDIR/48x48/apps INSTALLS += app_icon_48x48 app_icon_72x72.files = Icons/72x72/fwbuilder.png app_icon_72x72.path = $$ICONSDIR/72x72/apps INSTALLS += app_icon_72x72 app_icon_128x128.files = Icons/128x128/fwbuilder.png app_icon_128x128.path = $$ICONSDIR/128x128/apps INSTALLS += app_icon_128x128 app_icon_256x256.files = Icons/256x256/fwbuilder.png app_icon_256x256.path = $$ICONSDIR/256x256/apps INSTALLS += app_icon_256x256 app_icon_512x512.files = Icons/512x512/fwbuilder.png app_icon_512x512.path = $$ICONSDIR/512x512/apps INSTALLS += app_icon_512x512 } } } fwbuilder-5.1.0.3599/src/res/fwbuilder_prefs.xml.in0000644000175000017500000000311411733011756022666 0ustar sylvestresylvestre 10 1 10 1 lpr null.xsl false true false true false 0 0 0 0 0 0 0 0 0 0 0 0 0 Split false false true true false popup 2 fwbuilder-5.1.0.3599/src/res/help/0000755000175000017500000000000011733011756017306 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/help/en_US/0000755000175000017500000000000011733011756020317 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.2.1.html0000644000175000017500000023133611733011756024567 0ustar sylvestresylvestre

Firewall Builder 4.2.1 Release Notes

v4.2.1 is a minor bug-fix release

SourceForge: Tickets for V4

GUI Updates

  • Fix for SF bug 3169045 "Batch installer lists IPv4 address as management address". Built-in installer wanted to use management interface address in batch mode even when alternative address or putty session name was provided. This happens only in batch mode install.

  • fixes #2370, #2371 "broken signals in network discovery wizard". Network discovery wizard was not correctly initializased and did not work.

  • fixes #2368 and SF bug 3294457 "External install script". External install script name and arguments weren't saved for IOS firewall objects.

  • fixes #2360 "Sometimes fwbuilder opens with object tree scroll bar centered so folders are not visible"

  • fixes #2385 "PF action Classify uses wrong parameter". This change fixes a bug introduced in 4.2.0 that affects rules with action Classify in PF firewalls. The bug causes the following problems:

    For users who built their rules before v4.2.0:

    • rules compile normally, both in the single rule compile and when the whole firewall is compiled
    • if they opened the action of one of such rules in the action editor, the classification string would look empty
    • if they entered new classification string in the editor, compiler kept using the old one (which they can not see or change in the editor)

    For users who tried to build rules with action Classify with v4.2.0:

    • no matter what classification string they enter in the action dialog, generated code does not use it

Firewall Builder 4.2.0 Release Notes

SourceForge: Tickets for V4

Summary

This release brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10.

This release adds interfaces to the NAT rule model. There are two interfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded. Inbound and outbound interfaces in NAT rules are supported for iptables, ASA/PIX/FWSM and PF, but in the case of PF GUI exposes only one interface to the user since PF commands can not match two interfaces simultaneously.

This release adds support for ASA 8.0 - 8.3 configuration generation, including named objects and "new" style nat commands in ASA 8.3

This release comes with numerous improvemends in support for FWSM 2.x, 3.x and 4.x configuration generation.

This release implements import of PIX, ASA and FWSM configurations. Host name, version, interface configuration, object groups, named objects, access lists as well as commands "global", "nat" and "static" can be imported. There is no support for import of the "new" ASA 8.3 "nat" commands just yet. Also there is no support for import of standby configuration, which means PIX clusters can not be created automatically by importing existing configuration.

This release adds ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their IPv4 and IPv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF.

This release adds ability to automatically detect firewall platform from the format of the imported configuration file. Import is supported for iptables, Cisco IOS or Cisco ASA/PIX/FWSM. The program detects firewall platform, version and host name (if possible) from the contents of the configuration and shows platform-specific warning to explain what parts of the config can and can not be imported. Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved.

Starting with this release the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import.

Deduplication algorithm is as follows:

  • ASA/PIX/FWSM configuration import:

    ASA configuration language supports named objects and object groups. On import, fwbuilder creates objects and groups with the same names and uses them in rules. Objects created from in-line address/netmask and port specifications found inside object-group, access-list, filter or nat commands are condidered "anonymous" objects. These get automatically generated names and are deduplicated using only their relevant attributes but not names. Objects created from PIX named object ("object network foo", "object service bar") statements are considered "named" objects. They get the name matching the name in corresponding PIX config line and are deduplicated using both relevant attributes and the name.

  • iptables:

    Fwbuilder can only import iptables configuration saved with "iptables-save" command. This format does not support variables or named objects, therefor all objects created from address and port specifications are "anonymous" and get automatically generated names. They are deduplicated using their address, netmask, port numbers and other relevant attributes but not their names.

TCP and UDP service objects in fwbuilder that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

GUI Updates

  • fixed #1872: "vlan interface does not appear in the list of interfaces for route-to action for PF".

  • context menu item that opens object in the editor should be named "Inspect" when the object is read-only because the editor would not allow the user to change it.

  • fixed #1926 "Crash when moving object in Standard library". Context menu item "Move" should be disabled when the object is located in the read-only library.

  • see #1976 "Crash when deleting firewall object from rule after export / import library" Crash occurred as the result of the following sequence of actions in the GUI: 1) use context menu item "Cut" to delete an object in the tree, 2) open object group or rule and use context menu item "Paste" to add it, 3) export library to an external file, 4) import this library into different data file, 5) save the data file. Saved data file is invalid XML since it has unsatisfied reference and some operations on it cause crash. The problem is that since it is a reference to the object that is being added in case of both groups and rules, we end up with a group or rule with a reference to an object that is located in Deleted Objects library. Deleted Objects library is not included when a library file is merged into data file and this leads to a dangling reference. The fix is to not allow Paste if object in the clipboard has been deleted.

  • see #1980 "Objects from Deleted Objects should not be allowed to be used in rules". Added checks to not allow drag-and-drop of an object from Deleted Objects library into rules and groups.

  • see #1994 "Crash when compiling a firewall in an imported Library". To prevent crash, added check to make sure firewall object is not read-only before an attempt to update its "last compiled" or "last installed" timestamp.

  • fixes #1993 "V4.2 on Windows - export Library shows the file type as Firewall Builder 2"

  • fixes #1992 " V4.2 on Windows - installer error can't find Secure Shell utility"

  • fixed #1989 "variables respath and librespath are redundant and copy Constants::getTemplateDirectory()". Got rid of global variables sysfname, tempfname, librespath, respath and localepath; will now use class Constants to keep this information.

  • fixes #1998 "Crash after running find-and-replace then closing file". Specific sequence of actions and only on Mac OSX caused GUI to crash. To fix, I clear editor panel when user closes project window using MDI window title menu item "Close" or "Close" button.

  • see #1996 "Crash when finding and replacing a large number of objects". When "find and replace" function was used to replace large number of objects in a rule set, it generated stream of calls to updateLastModifiedTimestampForAllFirewalls() which caused corresponding stream of events to update various parts of the GUI, both in the tree and rule set views. This caused weird corruption and crash on Windows. Trying to resolve the issue by optimizing the part that updated "last modified" timestamp on the firewall since all parts of the rule set updated in one call to "find and replace" function belong to the same firewall.

  • fixes #2000 "New dialog window in New Firewall wizard for ASA / PIX - Network Zone explanation". Added page to the new firewall wizard to let the user configure network zones of interfaces when chosen firewall platform supports network zones (only PIX/ASA right now).

  • fixes #1983 "ASA multiple interfaces have the same security level". Using table widget with spin-boxes to let the user edit security levels of interfaces conveniently.

  • see #2006 "Crash when closing editor panel with find-and-replace". The GUI crashed if user tried to close editor panel at the bottom after closing objects+rules panel and while some object was still displayed in the editor.

  • See #2015 "Add support for setting names of generated .fw and .conf files separately for PF". Added second input field in the "advanced settings" dialog, tab "Compiler" for the firewall platform "PF". Now user can set the name for both the generated .fw initialization script and .conf PF configuration file, as well as names for both files on the firewall. Support for this is generic and the same functions work for other platforms if corresponding input field in the dialog exists. The name of the initialization script is set as follows: 1) if user provided -o command line switch to the compiler, its argument is used. 2) if -o switch was not present but the name was configured in the firewall settings dialog, it is used. 3) if none of them were present, the name is constructed from the name of the firewall object with suffix .fw. The name of the .conf PF configuration file is taken from the settings dialog, but if it is blank, then it is constructed from the name of the initialization script but with suffix .conf.

  • fixes #1914 "Address table object file name is not created properly if user clicks outside Editor panel"

  • fixes #1915 "tooltip shown when mouse is over rule number should be added to the list of suppressed tooltips when 'Advanced user mode' is in effect"

  • fixes #2064 "CARP interfaces are not properly installed on FreeBSD cluster". I need to populate failover group objects with some reasonable defaults when they are created.

  • fixes #2067 "Add way to show interface label in object tree". The tree now shows interface name and label if the label is not empty.

  • fixes #1979 "New firewall created with Cisco c36xx template results in network object in interface column in Policy"

  • fixes #1895 "Add context menu option to expand all child nodes in object tree". Added menu item "Expand" to the context menu associated with all objects in the object tree. This item recursively expands all tree nodes under the given object and automatically changes to "Collapse" if the item is expanded. Also changed behavior of the double click on the object in tree: before, double click opened object in the editor and expanded or collapsed subtree. Now it only opens object in the editor but does not expand/collapse subtree.

  • see #2103 "complex vlan/bridge configurations are not supported by the interface validation code". Added checkbox to let the user turn off interface name validation functions in the GUI. Checkbox is located in the global Preferences dialog, tab Objects, subtab Interface. For backwards compatibility, the checkbox is turned on by default. When it is off, the GUI does not validate the name of interfaces and subinterfaces and turns off checks that enforced interface name patterns for VLAN, bridge and bodning interfaces. It also turns off check for the validity of vlan ID derived from vlan interface name and turns off automatic configuration of interface type and vlan ID. These checks sometimes were in the way of building complex configurations that involved multiple vlan interfaces with names not matching their IDs. This also fixes SF bug #3066714 "please dont stop me from creating a new interface" where user wanted to create interface "veth201.0" on Linux but the GUI blocked this operation because the name seemed to match vlan interface pattern.

  • fixes #2099 "Object list scrolls up to the last edited object". Object tree used to scroll spontaneously when user started dragging an object from it to a rule.

  • fixes #1971 "Address range can be created with end address lower than start address". Address Range object dialog should not let the user enter range end address which is lower than range start address. Dialog behavior is now similar to the behavior of the tcp and udp service dialog where user can not enter port range end number lower than port range start number.

  • fixes #1678 "When creating a firewall from template it appears that a default template is selected". When user arrives at the page where they choose template to create new firewall object from, the first template should be automatically selected.

  • fixes #2135 "Editing table objects". Dialog of the AddressTable object now offers button "Edit" that lets the user edit address table file. This only works if the file is located on the same machine where the GUI is running, so it is probably most useful for compile time objects.

  • fixes #2139 "Provide "Cancel" button if Address Table file is read-only". If the file configured with Address Table object is read-only, the GUI shows warning when user clicks "Edit" button and offers a choice: open it for viewing read-only or cancel.

  • see #2140 "Attempting to create new Address Table file results in read-only error". Implemented support for the workflow when user wants to create the file used to feed addresses to the Address Table object.

  • see #2047 "Inspect generated files button shows different path information". Do not pass full path to the output file as an argument of the "-o" option when the GUI launches policy compiler. Since the "-d" option passes directory path where files sould be saved, actual file names do not need to be absolute path, except if the user entered absolute path for the output file name in the firewall settings dialog.

  • see #2153 "Add Network Zone explanation and selection dialog to ASA/PIX import". Wizard shows additional page when user imports PIX/ASA config. This page explains concept of network zones and offers UI to let them choose network objects or groups as a network zone of each interface.

  • fixes #2156 "After import the firewall should be opened in object tree".

  • see #2163 code that imports addresses from a file in /etc/hosts format moved to its own wizard; using QWizard and QWizardPage classes with correct implementation of page sequencing and validation; old discovery druid has been disabled. SNMP discovery and ios/PIX/iptables configuration import will move to their own wizards later.

  • fixes #2203 "Crash when attempting to add an object to a locked group".

  • fixes #2201 "Some fields of locked object are editable". Some input fields of the Custom Service object dialog were editable even when object was locked read-only.

  • fixed SF bug 3238026: build failure on systems without net-snmp development libraries.

  • see #2226 fixed GUI crash that happened when user tried to delete or cut an object from locked library.

  • fixes #2307 "GUI switches to another file after editor panel is closed"

  • see #2286 "Crash when closing file". The GUI crashed if user imported iptables or PIX configuration, then deleted a rule and tried to close project window.

  • see #2171 "Undoing delete of rule ends up with rules being created with duplicate rule numbers". Also see #2172 "Crash when deleting rule - related to #2171". When user deleted the last rule in a rule set, then used Undo to restore it, the program lost track of rules in the rule set and became unstable.

  • see #2335 "GUI switches between data files upon closing editor panel". If user opened two data files in the GUI and was in the process of editing objects in one of them, the GUI would flip to the other file under certin circumstances.

  • see SF bug 3211769 "Member interfaces not sorted". Sorting interfaces by name in the dialog where user adds them to the cluster member group.

  • fixed #2287 "Show text description in rule columns" does not persist across sessions

  • see #2229 "Multiple new objects with the same name". The GUI should automatically choose unique object names for new objects.

Changes in command line tool fwbedit

  • see #2328 "Add ability to run firewall import from the command line". This has been implemented as a new function "import" in fwbedit. See man page fwbedit(1) and "fwbedit -h" for more details.

  • Starting with v4.2.0, fwbedit.exe is now part of the Windows package

Changes in policy importer for all supported platforms

Changes that affect import for all platforms

  • see #1931 "Update failed import behavior". Added meaningful error messages for when policy importer fails to create firewall object or does not create interface objects or any rules.

  • see #2161 "import workflow and automatic detection of firewall platform from the config file". When user imports existing firewall configuration, the GUI automatically detects firewall platform from the format of the config file and shows platform-specific warning to explain what parts of the config can and can not be imported. It also detects firewall host name where possible (currently Cisco IOS and ASA/PIX). Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved.

  • see #2162 menu item "File / Import Policy" renamed to "File / Import Firewall". This menu item launches wizard that imports existing iptables, Cisco router IOS or Cisco PIX/ASA config.

  • see #2183 "count errors and warnings generated by the importer and show the numbers in the progress page of the wizard". Configuration import wizard now shows counters of warnings and errors generated by the importer.

  • see #2189 Policy importer warnings and errors now include line numbers to help find relevant lines in the original configuration file.

  • see #2189 Program adds the file name and the line number to comments of policy and nat rules it creates during import.

  • fixed #1548 "Object de-duplication during import process". Also SourceForge 3030072 "remove duplicates during any import". Now the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import.

  • see #2253 "importer should not creates objects while still in the middle of the wizard". Importer wizard creates new objects in the object tree only when user clicks Finish and abandons results if they click Cancel.

Fixes and improvements in import of iptables configurations

  • see #2190 "support for import of branches in NAT rules for iptables". Implemented import of NAT rules in user-defined chains for iptables, these translate into branching NAT rules in fwbuilder.

  • see #2196 "iptables nat rules with target REDIRECT not imported". Iptables NAT rules with target REDIRECT where not imported correctly.

  • fixes #2195 "incorrect iptables import of nat rule with NETMAP target"

  • see #2194 "iptables import problem with SNAT rule translating to an address range". NAT rules translating into address range with "-j SNAT --to-source 192.168.1.1-192.168.1.10" did not import correctly

  • see #2197 "iptables nat rules in chain OUTPUT not imported correctly"

  • see #2202 importer for iptables creates Custom Service object to match combination of states it does not recognize. This includes "NEW,ESTABLISHED".

  • see #2336 Importer for iptables recognizes version stored in the top comment by iptables-save and sets version in the firewall object it creates.

  • see #2206 iptables commands with no "-j TARGET" parameter should be imported using action "Continue".

  • see #2338 "Empty Mangle Policy object created on import". iptables rules in the table 'mangle' will be imported in the dedicated Policy rule set with name "Mangle". Rules that use chains FORWARD and POSTROUTING in table 'mangle' can not be reproduced and will be marked as "bad" (color red and corresponding comment).

  • see #2275 Importer for iptables now correctly handles both "intrapositioned" ("-s ! address") and "extrapositioned" ("! -s address") negation.

  • see #2245 fixed bug in parser for iptables that prevented correct import of iptables rules using module "multiport" with port range matches.

Fixes and improvements in import of Cisco IOS configurations

  • see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group.

Fixes and improvements in import of Cisco ASA/FWSM configurations

  • see #2161 policy import wizard shows the page where user can set up network zones of interfaces if firewall platform was determined to be PIX.

  • see #2152 "ASA Import - shutdown interfaces". Importer recognizes and skips ASA interfaces in "shutdown" mode.

  • see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group.

  • see #2268 updated list of named TCP and UDP ports recognized by the importer for Cisco ASA.

  • see #2277 "Create policy objects for ASA access-lists that are not applied in an access-group". Policy rule set will be created and populated with rules found in the corresponding access-list even if this access-list is not applied to an interface with access-group command.

  • see #2164 fixed import of "ssh" commands and added import of "http" commands for ASA/PIX/FWSM

Changes in the built-in policy installer

  • see #2039 "Installer reports success even if pfctl can't load config file". Added more pfctl error messages to the list to make code more robust.

  • fixes #2049 "Installer reports success even if there was an error while creating static routes". Added our own error message generated when command used to add static route fails to the list of error messages recognized by the installer.

  • fixes #2037 "If there is an error when compiling firewall then installer should be aborted". Compile/install wizard should disable "Next" button after compile phase is done if all firewalls failed to compile with no errors.

  • fixes #2061 "Installer shows success for failed installed on FreeBSD due to corrupt script file". Added bunch of common shell error messages to make sure installer recognizes them and mark install as a failure even if ssh fails to pass termination code.

  • fixed SF bug 3169045: "Batch installer lists IPv4 address as management address". The "summary" display in the installer progress log output will now show putty session name if it is used instead of the management address.

  • see #2073 "Add additional information or workflow when no management inferface configured". The error message shown to the user when no interfaces has been marked as "management" is now more verbose and provides instructions how to do this. Also, if user provided alternative address to be used to communicate with the firewall, the check for the management interface is not performed since it is not needed.

  • see #2088 "Installer caches putty session". Need to initialize putty_session properly and clear it in clear().

  • fixes #2129 'deprecate "test install" function'. We have decided to deprecate test install because it is rather heavy-handed on Linux and PIX where it reboots the firewall and plain does not work on *BSD.

  • see #2239 Added variable "firewall_name" to configlets that define commands installer runs on the firewall to activate new policy (all platforms).

  • updated filesystem path on FWSM where fwbuilder built-in installer should place generated configuration when it is installed using scp. Currently using path "disk:".

  • see SF bug 3212988 "external script makes getopt difficult". User-defined parameters for the external script moved to the end of the command line.

Changes and improvements in the API library libfwbuilder

  • see #1972 Separated object creation and initialization. Some complex objects need to create a set of standard child objects. Previously this was done in a special type of constructor which required pointer to the object tree root (FWObjectDatabase*). This created problems with implementation of the method to register functions that create objects of new types outside of the API. Now all objects have just a basic set of constructors, plus method init() that can initialize them.

  • see #1972 implemented mechanism that allows me to register new object types created and used outside of libfwbuilder API. This means FWObjectDatabase can then copy and manipulate object trees that use these new object types.

  • fixes #1937 "RES_DIR macro is defined twice". Got rid of duplicate definition of this macro.

  • see #1985 added virtual function updateNonStandardObjectReferences() that is supposed to update any references to objects stored as attributes.

  • fixes #1997 "add removeRef and addRef methods to class NATRule". Now undo and redo correctly remove and restore references to NAT rule sets in NAT rules with action Branch.

  • fixes #1991 "Undo does not restore object as a parameter of policy rule action Branch or Tag after it was deleted deleted". Now Undo restores references to rule sets and tag services as arguments of corresponding policy rules, as well as references to objects configured as interface network zones.

  • fixes #1987 "Deleting object that is used as Network Zone for ASA/PIX interface results in inconsistent behavior". When an object that is used as a network zone of an interface is deleted, it should be removed from the interface configuration as well.

  • fixes #1995 "Crash when compiling a cluster with identical firewalls". Method Cluster::init() must call base class method Firewall::init() to get child Policy, NAT and Routing objects created.

  • See #2084 "snmp discovery takes forever on devices with large routing tables". This takes very long time on decides with large routing tables. This code was implemented long time ago and apparently routing data was intended to be used to discover "external" interfaces, but it is unclear if this is still done. The concept of external/internal currently exists only for platforms that support security levels (PIX) and there we guess levels by matching addresses against RFC1918 and let the user user adjust levels manually anyway.

  • see #133 Added interfaces to the NAT rule model. There will be two interfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded.

  • see #2126 Using snmp sysDescr OID to guess version of the new firewall when it is created using snmp polling.

  • fixes #2209 "do not allow the same object to be child of different objects in the tree". Method FWObject::add() enforces this. Subsequent clean-up and fixes in many places to follow this logic. This makes code much cleaner, better organized and more reliable.

Changes and improvements in the library of standard objects

  • #2083 Added new services to the Standard Objects Library: rtmp, xmpp-client, xmpp-server, nrpe

common changes that affect policy compilers for all platforms

  • fixes #1920 "Setting host interface to unnumbered after it has been assigned IP address doesn't have desired effect". Compiler still used IP addresses that belonged to the interface even if it switchd to "unnumbered". These children address objects should be ignored.

  • fixes #2124 "some error messages get multiplied when compiler splits rules". Under certain circumstances error messages could appear multiple times in the generated script.

  • see #2204 "Shadowing detected for rule with action Continue". Policy rules with action "Continue" should not shadow other rules and can not be shadowed.

  • see #2207 fixed memory leak in policy compilers. The impact of this leak was especially severe on Windows with very large object databases.

  • see #2212 "Performance improvement in compilers". This change brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10.

  • sorting objects in rule element after cluster interfaces have been replaced, this helps ensure stable ordering of objects in generated configuration.

  • sorting objects in the rule element by name after group is expanded, this helps ensure stable ordering of objects in generated configuration.

Changes in support for iptables

  • fixed #1879 "gui crash". Both GUI and fwb_ipt crashed trying to compile a rule with action Branch that was not configured to point to any rule set.

  • fixed SF bug #3102044 "Colon in (runtime) Address Table name". Variable used to process addresses in the run-time address table should not use character ":" even if it appears in the Address Table object name.

  • fixes #1999 "log() does not work" Using built-in utitlity "command" to verify that all the tools generated script needs to function properly are available and can be accessed either via direct full path or are in the PATH variable. This includes the check for the logger tool that is used to make log record when firewall is activated.

  • see #2097 #133 "support for inbound and outbound interface columns in iptables NAT rules". This also addresses SF feature requests 1954286 "DNAT with interface as condition not possible" and 621023 "manipulating interface in NAT rule".

  • fixes #2008 "option "--physdev-out" is not allowed in OUTPUT chain". After this change, compiler avoids INPUT/OUTPUT chain if interface in the rule column "Interface" is a bridge port and firewall is bridging firewall (which means we are going to use --physdev-in or --physdev-out option for this rule).

  • see #2170 "Compiler should generate error for invalid iptables NAT configs". Now that we allow the user to specify inbound and outbound interfaces in iptables NAT rules, compiler should verify that combination of requested "-i" and "-o" interfaces is in fact valid. For example iptables does not allow "-o" interface spec with rules that go into PREROUTING chain (DNAT rules) or "-i" interface spec with rules in POSTROUTING chain (SNAT rules).

  • see #2181 "Update iptables importer to detect inbound & outbound interfaces in NAT rules". Importer can now import nat rules with "-i" or "-o" interface spec.

  • see #2230 the GUI should allow limit-burst values of up to 10000

  • SF bug 3178186 "Add ND/NS allow rules for the FORWARD chain". Rules that are added automatically to IPv6 Linux firewall to permit neighbor discovery packets should be also added to the FORWARD chain if the firewall is a bridge.

  • see #2324 "NAT + MAC-matching rules not generated properly". iptables NAT rules matching a group of host objects with both IP and MAC addresses each in "Original Source" were not generated properly.

  • see #2235 "Modified rule action for Continue". Rules with action "Continue" should translate into iptables commands without "-j TARGET" parameter. If such rule also has logging enabled, it should use target "-j LOG" instead of generating additional chain.

  • see #2359 "Crash when compiling single rule with IPv6 destination and IPv4 gateway or interface". Routing compiler for iptables does not support ipv6 at this time and will issue a warning when user tries to place ipv6 address or network in a routing rule. The warning does not appear when ipv6 address is a member of a group used in the rule. Also see #1575.

Changes in support for PF (FreeBSD, OpenBSD)

  • see #1890 "Add support for configuring static routes on BSD". Implemented support for simple static routing rules. ECMP and routing via interface (routing to directly reachable subnets) are not supported. Generated script preserves static routing entries that existed before and attempts to recover in case of error.

  • see #1888 "Add option to generate rc.conf.local file for BSD systems". Added ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their IPv4 and IPv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF.

  • fixes #2026 Compiler can now generate static routing configuration in rc.conf format for FreeBSD.

  • fixes #2032 "support for DHCP interfaces in rc.conf mode". Include dynamic interfaces inin the list of interfaces generated script manages when the script is in rc.conf format. This addds lines similar to 'ifconfig_em0="DHCP"'.

  • fixes #2038 "pfctl error when firewall settings include scrub option for reassembly". Command "scrub all reassemble tcp" does not allow direction. Tested and verified on OpenBSD 4.2 and FreeBSD 8.1

  • see #1889, #2043 Added support for bridge interface configuration in BSD.

  • fixes #2054 "Add support for load anchor PF command". Instead of loading anchors using "pfctl -a anchor -f file" command in the .fw initialization script, now generated PF configuration uses "load anchor" commands in the pf.conf file. This way, we can load anchors correctly when PF configuration is activated from the generated rc.conf.local file where only one pf.conf file can be referenced.

  • fixes #2042 "add configlet and shell functions to manage bridge interfaces via shell script on OpenBSD and FreeBSD". Bridge interfaces are managed incrementally, that is, the script creates and destroys them as needed, then adds or removes bridge ports, to bring bridge configuration in sync with what is defined in fwbuilder GUI.

  • fixes #2065 "activation commands on FreeBSD and OpenBSD lose script exit status". Sequence of commands ran by the built-in installer on *BSD firewalls were losing exit status of the script which meant installer always declared installation a "success" even when there were errors.

  • fixes #2066 "Existing VLAN interfaces are not properly removed from FreeBSD and install script fails"

  • fixes #2069 "PF: allow multiple objects in ODst of redirecting nat rule". This fixes SF bug 3162862 "NAT - more than one object in original destination"

  • fixes #2071 "vlandev missing in the vlan definition (when using rc.conf.local )"

  • fixes #2058 "Ability to configure mtu and metric of regular interfaces". "Advanced settings" dialog of the interface object provides controls to configure MTU and possibly add any additional ifconfig parameters. This is available for OpenBSD and FreeBSD.

  • see #2078 added verbose error message in a situation when "ifconfig carp0 create" command fails to create CARP interface.

  • see #1867 "PF: rule with non-terminating action Tag shadows other rules below it". Since action Tag is non-terminating, rules with this action should not shadow other rules.

  • see #2074 On FreeBSD ifconfig does not understand parameter carpdev

  • fixes #1866 "support for pf option set state-policy", #1868 "support for pf option set block-policy", #1869 "support for pf option set debug".

  • fixes #2092 option "stp" should be optional in the ifconfig command that builds bridge interface for FreeBSD. The dialog provides checkbox "Enable STP", parameter "stp" will be added to the ifconfig command only when the checkbox is turned on.

  • fixes #2091 "ethernet interface options a used twice if the interface is a bridge port". When an interface appeared twice in the firewall configuration, such as when it is used as a bridge port and vlan parent interface, options configured for it in its settings dialog were added twice to the generated configuration.

  • see #1871 "PF Actions Tag and Classify can be terminating or non-terminating". Added checkbox to the action properties dialog for actions Tag and Classify for PF that lets the user choose if these actions should be terminating or not. Old behavior (Tag was non-terminating and Classify was terminating) is reflected in default settings of the checkboxes. Terminating rules generate "pass quick" commands, while non-terminating rules generate "pass" commands (no "quick" option).

  • see #1807, #2104: arrange interface configuration commands in the generated script in such order that bridge and carp interfaces are configured after all other interfaces are done.

  • see #2105: generated script now supports vlan interfaces with names that do not match vlan IDs (OpenBSD, FreeBSD, shell script format).

  • Making sure we print "ifconfig" commands for mtu and other parameters for all interfaces, including those with no ip addresses and bridge ports (unnumbered interfaces used to be skipped before)

  • fixes #2100 carp password should be optional parameter

  • fixes #2096 added support for negation in Interface column for PF NAT rules. Sets of interfaces are converted to complementary sets using complete list of interfaces of the firewall.

  • fixes #2095 added support for groups and multiple objects in column "Interface" for PF NAT rules. These translate into { em0 em1 em2 } groups in generated pf.conf lines.

  • fixes #2101 "CARP interfaces are set with same advskew". When new PF cluster is created, master advskew paramerer will be set to 10 and backup to 20 to make it deterministic.

  • fixes #2116 "When CARP interface IP address can't be assigned error or warning should appear". The problem actually affects any type of interface. Generated script should abort with an error termination code when ifconfig fails to assign IP address to an interface.

  • fixes #2117 "CARP interfaces in cluster that use VLAN interaces have no interface set to MASTER". When PF cluster configuration was built using vlan interfaces of member firewalls, CARP interfaces were not properly configured with master/slave choice user makes on the first page of the new cluster wizard.

  • see #2143 "installer should run /etc/rc.d/pf script to reload PF rules on FreeBSD when generated script is in rc.conf format"

  • see #2224 "FreeBSD - Bridge interfaces with the name vlan don't show as Bridge Port Interfaces". This actually applies to all OS where we support vlan and bridge interfaces. Fwbuilder GUI should allow the user to set subinterface type to both "ethernet" and "vlan" when its parent interface has type "bridge". Setting subinterface type to "ethernet" makes it bridge port, while setting the type to "vlan" signals policy compiler that it should generate code to configure real vlan interface. If the name of the subinterface does not include the name of the parent, such as "vlan101", or when the name does not match vlan ID, such as "vlan8101", global preferences option "Verify interface names and autoconfigure their parameters..." should turned off. The option is located in the Preferences dialog, tab "Objects".

Changes in support for ipfilter

  • There are no changes in the support for ipfilter in this release

Changes in support for ipfw

  • There are no changes in the support for ipfw in this release

Changes in support for for Cisco IOS ACL

  • fixes #1966 "IOSACL: object-group can get name that consists of only suffix". Compiler generated object-group statements with names such as ".src.net.0" in some cases.

  • see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

  • see #2330 "Crash when creating a cluster of IOS router firewalls". Added support for basic IOS router clusters. No failover protocol support at this time, but the cluster can be configured with protocol "None" and fwbuilder will do address substitutions at compile time.

Changes in support for for Cisco ASA and FWSM

  • FWSM v4.x does not have "fixup" command, instead, we should use policy-map and class commands.

  • refs #1893 fixes #1883 "inspect IP options in PIX8". Added support for "policy-map type inspect ip-options" command in PIX v8.2 and later. At this time, of all possible types of "policy-map type inspect" command only "ip-options" is implemented.

  • refs #1882 "Mixed service groups in PIX8". Added PIX versions 8.0 and 8.3; added support for mixed servcie groups in PIX 8.0 and later.

  • fixed #1892 "move rule processor class separateServiceObject to PolicyCompiler". This rule processor used to be implemented only in the compiler for PF, but since it has very general meaning, the same function was duplicated in other compilers as well. Moved the class to libfwbuilder and reimplemented several other rule processors to inherit from this class to avoid further duplication for code.

  • fixed #1891 "problems with TCP and UDP services with source ports". Policy compiler for PIX did not generate correct PIX ACL lines when one Policy rule tried to match several TCP and/or UDP objects matching source ports.

  • fixes #1901 "add destructor to NATCompiler_pix and NATCompiler_asa8". This eliminates memory leak.

  • refs #1885 "named network and service objects in PIX8". So far, these objects are only used for nat configuration.

  • fixes #1903 "correct order of clear commands for ASA 8.3"

  • refs #1886 "new nat configuration in PIX 8.3". Initial support for new style nat configuation.

  • fixed #1862 "fwb_pix crash". Compiler fwb_pix crashed when DNS Name run-time object was used in a rule, but worked fine and issued an error when used in single-rule compile mode.

  • fixed #1906 "ASA NAT - Address objects are not properly identified by network zone and have the wrong real interface". The problem should have affected both "old" (PIX 6 and 7) and "new" (ASA 8.3) configuration. When an Address object was used in Original Source of a NAT rule, compiler used wrong interface in the (interface1,interface2) pair in "nat" command.

  • fixed #1905 "fwbuilder crash when compiling a rule with hosts folder as destination". Compiler issues a warning when an empty group object is used in a rule, but GUI crashed when user tried to compile this rule using single-rule compile function. The change actually affects all policy compilers and makes sure the GUI catches exception and does not crash, and prints any errors generated by the compiler in the compiler output panel when single-rule compile function is used.

  • refs #1908 "ASA NAT - cannot configure static NAT translations with (inside,outside)". Added NAT rule option to make source nat rules "static". The option is presented to the user as three radio buttons in the NAT rule options dialog which is only enabled when platform is "PIX" and version >= 8.3. Policy compiler generates "twice nat" rules with keyword "static" in the following cases: when TSrc is "original", so the rule translates destination and not source or when numbers of ip addresses represented by OSrc and TSrc are equal. If TSrc is not "original" and represents different number of IP addresses than OSrc, compiler looks at the new rule option. User can use or override automatic algorithm using radio buttons in the NAT rule options dialog.

  • refs #1902 "Add NAT rule option "translate dns" for PIX". The option is only available for ASA 8.3 or later.

  • fixed #1909 "ASA NAT - static nat port translation where service is the same for original service and translated service not generated correctly"

  • fixed #1913 "ASA/PIX rules with logging enabled don't have log set unless user modifies Firewall Settings". Added default log level setting to the resource xml file for platform "PIX", set to "informational". ACL lines now get "log " keyword followed by the log level taken from the rule options, or if that was not configured, from the firewall object settings, or if that is not configured, the default.

  • refs #1907 "ASA NAT - fwbuilder doesn't support multiple translated sources in a single NAT rule". Compiler uses object-group to translate NAT rules that have multiple objects in Translated Source.

  • refs #1885 Compiler uses named objects and objects groups to build configurations that use address ranges in TSrc in NAT rules. (only ASA 8.3 and later)

  • fixed #1917 "Duplicate objects are not detected". Compiler should detect duplicate objects that may be created in a rule element when user combines Address Table object with other address or network objects there.

  • fixes #1934 "libfwbuilder::getOverlap() incorrectly calculates overlap between IPv4 networks". This should also fix SF bug 3156376 "Can not find interface with network zone that includes address range".

  • fixes #1932 "Add description field to generated NAT rules for ASA". NAT rules generated for ASA 8.3 and later will have "description" keyword added, with rule label as an argument. Rule label includes word "NAT" and rule number.

  • Added support for CustomService objects in policy and nat rules for ASA 8.3 using named objects and object-groups. -- see #1942 "ASA NAT - if custom service is included in service group incorrect config generated" -- see #1929 "move map named_objects inside class NamedObjectManager" -- see #1946 "restrict generation of the named objects by PolicyCompiler_pix to ASA 8" -- see #1885 "named network and service objects in PIX8" Note: this has been rolled back. There is no support for CustomService objects in NAT rules.

  • see #1941 "ASA NAT - compiler complains about range in original destination". NAT rules translating destination allow Address Range objects in ODst or TDst for ASA 8.3

  • see #1940 "ASA NAT - fwbuilder host objects interface IP is reserved keyword". Added list of reserved words used in IOS and ASA software to make sure generated named objects do not conflict. Will maintain single super-set of reserved words instead of separate set for each version of IOS and ASA.

  • fixed #1938 "icmp" commands were not generated for ASA 8.x policy rules.

  • See #1927. Added check for NAT rules that request translation of destination address but have ODst "any". This only applies to ASA 8.3; these rules are prohibited.

  • fixes #1916 "nat rule must be "static" when subnet is present in TSrc"

  • see #1942 improved support for CustomService objects for ASA 8.3. Generate separate named object and object-group for these objects, then split policy and nat rules so that only one custom service object is left in each rule and then use object-group to match it. Note: this has been rolled back. There is no support for CustomService objects in NAT rules.

  • fixes #1948 "incorrect configuration created when a CustomService object is used in a policy rule for PIX/ASA versions prior to 8.3". Since we do not support custom service objects in policy and nat rules for versions older than 8.3, added check to generate fatal error when such object is used.

  • fixes #1945 "object-group names include ever-growing suffix". Object-groups created by the compiler for PIX/ASA had numerical suffix that was constantly increasing when user used single-rule compile function in the GUI.

  • fixed #1944 "ASA Policy - duplicate network object groups created for mixed service group with TCP dst and TCP src port range objects". Need to convert address range objects to subnets early, before the rule is split for any reason, to make sure object groups created later match and are reused.

  • See #1943 "ASA Policy - mixed service group with TCP destination port range and standard TCP object generates invalid config". Protocol word "tcp" was missing after "deny" in the generated rule.

  • see #1949 "ASA NAT - split objects if OSrc contains objects that are in more than one network zone".

  • ASA 8.3 see #1942, #1943 fixed generation of the "object-group" statements by adding protocol keyword at the end so that the group can be used in access-list commands. It looks like mixed service groups that have no protocol keyword at the end of the line that defines them cause error "specified object group has wrong type; expecting service type". I am going to avoid using mixed service groups because of this.

  • see #1953 "ASA NAT - two host objects in the same rule result in incorrect config". Objects that represent addresses of interfaces of a host object created using template will be automatically renamed to follow standard naming convention "host_name:interface_name:ip" to avoid creating duplicate names.

  • see #1960 add support for CustomService for PIX policy rules. Note that CustomService objects are only supported in Policy rules since nat commands in ASA 8.3 require use of named objects and it is difficult to implement correct named objects and object-groups with protocol parameter and custom services.

  • See #1959 "ASA Policy - ranges are broken into composite network instead of using range command." Added support for address ranges using named network object with parameter "range" for ASA 8.3 and later. NOTE: if a network or IP address object is used in a nat rule for ASA 8.3, a named object has to be created for it since ASA 8.3 does not accept IP addresses or subnets in "nat" commands. In the situation like this, if the same address or network object is used in any Policy rule, the same named object will be used in the generated access-lists command.

  • see #1959 Moved generation of the code that defines named objects to class NamedObjectManager. This allows me to put all named object commands on top of the generated policy, nat and routing configurations and make sure each object is defined only once. Still need to do #1963 - move code that generates commands to define object-groups to class NamedObjectManager.

  • see #1954 "ASA NAT - generate warning if nat rule is split and one of the resulting nat rules have the same real interface and mapped interface". Compiler issues warning when objects used in OSrc and TSrc of a NAT rule make it use the same interface as both real and mapped interface in the generated nat command. This check is only done for ASA 8.3 NAT rules.

  • see #1963 "move printing of object-group definitions to NamedObjectManager::getNamedObjectsDefinitions()". Consolidated code that works with named objects and object groups in the class NamedObjectManager. This class manages all the objects and in the end generates commands.

  • Refactored parts that generate "clear" commands to make sure they are printed in the right order at the top of the generated configuration. Previously compiler placed "clear global", "clear static" and "clear nat" commands above the NAT section but below policy section. Since ASA8.3 nat commands can use named objects and object groups, and since I have added support for object groups in ASA 8.3 policy rules, I now need to clear objects and object groups at the very beginning of the generated config. However in order to be able to clear objects and object-groups, I need to clear access-lists and nat commands that might be using them first. So, all clear commands are now grouped at the beginning of the generated configuration. This affects PIX/ASA, iosacl and procurve_acl platforms.

  • See #1965 "ASA Policy - PIX 6.1 configurations use object groups". Policy compiler for PIX is now aware that object-group statement was introduced in PIX v6.2 and avoids using object-groups when firewall object version is set to 6.1

  • made names automatically assigned to object-groups in generated PIX configuration shorter by removing interface label prefix.

  • see #1968, #1972 Class NamedObjectsManager maintains its own copy of object tree that holds object group objects it creates during compiler passes. This allows me to maitain one common set of object groups for both policy and nat compilers and avoid creating duplicate and redundant object-group statements.

  • see #1968, #1972 class NamedObjectsManager (and derived classes for IOS and PIX) generate "clear" commands. This way, I can generate correct set of "clear" commands that take into account any named objects and object-groups that could be created during both policy and nat compiler passes.

  • See #1958 "consistently use "exit" to get out of nested context in PIX config". Using "exit" to exit from nested context while adding network or service object in generated PIX/ASA configuraton.

  • see #1970 "ASA Policy - single IPv6 icmp object allowed in rules". Since we do not support IPv6 for PIX/ASA at this time, policy compiler should drop the rule if IPv6 address or icmpv6 service is used and issue a warning.

  • see #1981 "ASA / FWSM Policy - Generate warning message if rule will not generate config data"

  • fixes #1986 "Cisco ASA remarks should be truncated to 100 characters or less". Trimming all lines used for access list remarks to than 100 characters. Remarks can only be less than 101 characters on PIX/ASA and less than 100 characters on IOS.

  • fixes #1994 "Crash when compiling a firewall in an imported Library". Compilers should reset any read-only flags in the copy of object tree they work with before they make any modifications.

  • fixes #2060 "Existing configuration objects are not cleared in PIX 6.3". Commands used to clear object groups and objects have different syntax in PIX 6.3 and PIX 7 and later.

  • see #2098 Added support for user-configurable inbound and outbound interfaces in Cisco PIX/ASA NAT rules. Two new columns appear in the rule set view: "Inbound Interface" and "Outbound Interface". If user leaves one or both columns blank, the GUI shows "Auto" in there and policy compiler picks corresponding interface automatically. Leaving both columns blank ("Auto") triggers backwards-compatible automatic behavior where both interfaces are picked automatically. Multiple interface objects and groups of interfaces are allowed in these columns.

  • fixes #2113 "ASA/PIX SNMP discovery - assign default labels based on interface description". Added pattern to match Cisco ASA interface description which is different from Cisco PIX interface descriptions as returned via snmp.

  • see #1990 "Change default value for Cisco ASA/PIX 7+ to generate outbound ACLs". Newly created PIX/ASA firewall objects will now have "generate outbound acl" option turned on by default.

  • see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

  • see #2263 looks like "object-group service" that includes named objects defined as "service-object" can not be used in access-list commands and therefore is useless. Unless I misunderstood and there is a way to use it, I should not generate ASA configuration like this:

            object-group service id5102X14531.srv.tcp.0 tcp
              service-object object http.0
              service-object object https.0
        

    Object-group with "tcp" or "udp" type-suffix in the end does not allow "service-object" statements at all, so this configuration is incorrect anyway. However even without "tcp" in the end to make "service-object" references acceptable, the group can be built but can not be used in access-list statements.

    Instead, the group should use port-object statements:

    	object-group service id5102X14531.srv.tcp.0 tcp
    	  port-object eq 80
    	  port-object eq 443
        
  • see SF bug 3213019 "FWSM Network zone and IPv6". Currently we do not support IPv6 with PIX/ASA and FWSM. If user creates a group to be used as network zone object and places IPv6 address in it, this address should be ignored while compiling the policy but this should not be an error.

  • see #2308 "ASA rules with service set to "http" and destination set to ASA firewall object should generate different command syntax". Policy rules that have firewall object in Destination and http object in Service now generate "http" commands. This is similar to how fwbuilder generates "ssh", "telnet" and "icmp" commands to permit corresponding services to the firewall itself.

  • see #2344 "FWSM install errors for clear commands". Using correct syntax for "clear" commands for FWSM v4.x

  • see #2343 "Interface nameif error when installing generated config for FWSM". Use correct "nameif" command sytax in FWSM 2.x and 4.x.

  • see #2345 More fixes for FWSM 4.x: "service resetoutbound", "timeout xlate", "timeout sunrpc"

  • see #2344 fwbuilder should not generate any "ntp" commands for FWSM because NTP can not be configured on FWSM.

  • see #2322 If this is FWSM and if manual commit mode is used, need to commit after clearing ACLs before we clear object groups.

  • see #2347 "FWSM move up the "access-list mode auto-commit" command". Command that configures access list commit mode should be issued before any commands that clear and configure access lists. Also in this change moving commands that set up temporary access list to the top of the script.

  • see #2348: "Accounting action is not valid for FWSM platform". Actions "Accounting" and "Reject" should not appear in the drop-down list of actions in the GUI if platform is PIX or fwsm.

  • see #2295 Added FWSM version "3.2". According to Cisco documentation, FWSM version 3.2 matches PIX 7.

  • see #2351 Security levels of ASA and FWSM interfaces do not have to be unique. Removed check that enforced this.

Changes in support for HP ProCurve

  • There are no changes in the support for HP ProCurve in this release

Changes in packaging

  • This version is the first one to merge libfwbuilder and fwbuilder packages. The libfwbuilder library is now in the src/libfwbuilder subtree inside fwbuilder code tree.

  • RPM .spec files and DEB .control files are now located in the directory "packaging" inside fwbuilder code tree.

  • Changes in the versioning format: build number is going to be used as part of the long version number, composing complete version as "4.2.0.3425". The "-n" suffix in rpm and deb package names will be used for package release number and most of the time will be "-1". This suffix should reflect minor differences in the package that do not affect the code.

  • We have stopped making builds on Ubuntu Hardy. Old Qt (4.4.1) means more and more parts of the code do not compile and require workarounds, sometimes with loss of functionality in the GUI. v4.1.3 will be the last officially released version of fwbuilder to work on Hardy.

fwbuilder-5.1.0.3599/src/res/help/en_US/pf_Route.html0000644000175000017500000000052311733011756022770 0ustar sylvestresylvestre

Rule Action "Route"

This action makes the firewall to route the packet that matches the rule through an interface or a gateway specified in the parameters of the action. This action is translated 'route' clause for PF and ipfilter. Compilers for PF and ipfilter support fastroute, route-to, reply-to and dup-to options.

fwbuilder-5.1.0.3599/src/res/help/en_US/pix-statesync-group-1.png0000644000175000017500000014323611733011756025141 0ustar sylvestresylvestre‰PNG  IHDR&УЖик^РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь]€Uеў^пЗНїždг7Нї„$‰‘о›JE) т/ˆˆHЕ ЈЅ(R `$„’@BzлlяНї}ћкџ™нЗ›Mп„s“ЗoоЬ[ЮЙчЛЇ]УцЭ›На“N:t ша) Sр €ЁЋЋK&ЇР@шMа) S@Ї€N:sSS“N:t ша) S@ЇР)AГС`8%Ђ7BЇ€NуЇ€зЋ @ПŒїZ­л™R|ПWЧWТЉа–!mЧи •ЮЧG™žqт€щ\рx)Љп?”0ЛнюЁ,O/KЇ€NУP@˜д d2FrЗлглŠ!eŠ,U)o3ыэ“Т4“ЩФ|nxњšблžЁ>8\џ F#=tmQыУAЧА—=Uђ Н„6шvДДш-‹аФы=p"їЋ}PћsњUCK2&‹Х Зг O?ы.љ!ыV•aШ1ГЊ @ZрУаe|J#љЏн.,V‹К ц}f3Щ˜ЎОEˆŒTІЄTсп6JЎiчЕ|’CMв~ <ЌЧнлЌ6 ћф‚Сh‚ЩрE[[Œ+Ь‚ Є/МYe„ћ$$zQ;ЫМL=}ек ]S/II§“‰э1xмp cRЋ‡гй Ѓй “ќPЉr@[zћйзШƒЖХjЕБ\КЛj)Ж7ѕаЧEњHYLBR–U›јх‚KhЬ;{.+yД>Ыm|ЕўїЖзŒ&3љрaYFИ8ІоЊPЗyЬЋн7X9ƒ‘Яˆ.Ž™‘ RЦРЩc-ЩН§яыBл'їhuiїып:އ†ттbѕэ9žRє{u ш84„ ‘ЉРб†Нћђ‘4r,Тќ 'd*ќo4ђ™–‡ьЦJ†сюю†гэ%ѓPЊЫХk '3)ЬоI`#ЬLn–<Т(e5^™ЛыїwтМѓ`uu(ЬК4{/ё‘Љ)ТTљУЇ|2v4QŠj"35Т GwГ’КLFіэо‡”QHЖЩјxЛБуѓOБЏЄ†MВcвДIЈЮЭFиИй˜šŠ.G7YЉQiЗ€Kc—њМdˆFжхuKпMАYL Œa&€3ВOnін ™РЂ›tбК0HГйŒвь=шєЧШф0оK№Х{ €ђv6bѕыЋ6їŒNFWWЗ›р ЄJ_Ё‹} %хyXŸ—Ki л.pЮЬњМЩгэ@ЮЖШЊwbоЂ…хАБhАCіюЭFDкhDћ[•ЖдэУ†Mлаa‰ЦтE nc™F6“…уnфЗ ЄcщЇ€HЁ“2VkЙdbлšЋ‹Бё“ Јwй0}с—ŠЮ.‡B3EeB#л. гIZIлH)eђЗа_Рзб„Я?ў%ѕmЄ‡?fЬ™‹сЉбФ'lЫњ­6жOкt“МIœB3ГйD‰{@@Ѓд%yј<‰pLžH=щ8^ ˜='CжzМ­дяз)№Ї€ЪDцК|Д5—›@Љƒ‹R†ЌzэEДFЬФЙ‹&РфlFVI-Ђ“RdCMI*›К‘’–Œв]яcе.]ОёŠšФdшFav6š&Œ“AІк…’Š ьпЛў6;’“cсшhA—5†РЇЙYљ0F!)>W' xo™\АЁЏОўц-џ6ЦЇGЂКЌ† Є%Х*LM„СD†к\†6|УЦ0JP$’§ёјыG-Иэћ+сmЊ…СьEMm ь”4еTУa€эЌэє <иUьScЗRb§Аўѕ +}Юš> ІЎZьЋh@ћbѓЂВЊmFaс‘pЕд ІХƒдД$и­&EВCnЩ>ЕbгЇ!эєKyьQСOз–цЃЂЁq1ЁЈЉiB™rcmœц иМhщ2 "ФŠЂм\іŸtŠБтЭW_†пАгpЮœ 8лЊй–f$ІЇТпрBMC#ZйўшЈ(‰NМНaЦЮœ‹а@ТсўН†:ъ*№скm8якБ H0x[ёЪKЏaиiav’?R-оzі5И“ц`оє‘hЉ.G›лТ~%ЃzяGXЕЎЫЏИ‰сv”эЯг†фј(EЂaуј}ўС3(‹ZŽ•™qѓV”–v!<2 оіFдЖ;`еео‚Ж. !) /ŠѓіЁОеф”$кatwaУЊgБК>7žwš** НhmЌGC]=мVФE† $w: ЦЖy;аТg,<иŠъК ЃЕ эЌЋгcCRbl&в_А•˜Пт/Ќоќ/•К*чK%П^љ7…Вт5SнPšНЩcjЅ4ТС“н](оЙ œќЯ˜‰uяЎAs—э–Xœ{њh<§л?cТy—#1б…–Ъ\<ББ KNClИПbKВsн*|šOмM…X::uWa[`;ію*РпЛŽ\К -ˆЧŽѕŸтЃ]5dђ8этЋ`­њџДЇЭžЗЉЋŸјc/ФЖЯЖрХ5ЅИњђЪЪXVСЂтБ’Щх!0)Q~fЎЊ]-XџA6ЎЙђ&d$DЁ32Ѓ[Zl&/ЖќяM˜&­Рsомн‰ХcќёаCЏсЂ›ЎA™gўЖ?Ђо0ѓв‹А~н;hr™бЕ=пY”ЧП#2p/&„уеџ‡…—\Ž$Ўд=”вˆ ЈpšЫ‹аdˆХ№ш@E2#’žš‚Mxфbжœ9АћS"a‚]иђЮЋsЂZvbMžѓ“лёшгыpЩ пE\gr6Н‹_&цдYёі›PD)Ъžбјж”8лИоИL$Zсl­С†е;pС?ЦмIЩЈ*м‡й—,ХдёусЉpaTx1ZšZрєPВТžxМЂhCIi R†/$#ІД‡т~1*uКLŠДBдM"E1šDEу%У&ˆ  РNѕŒХьGнI;Cb0?3 uеѕА ‘SЎDФs`kнЕїт[+ЮF}‡mmHПрZ,_2жњŒƒЦцZt8“a3ЋРФbuЂДЄ‰)A,оAећжПƒЩgž ЯšƒюšR|бйЩ•< &+ЌT‡Xhћb Д*(: “ЧЃКОу†Ѕ }жхЗpЬ-ыёдоrќпSPя0ЂГ­)ЫяТ%gЯC€AЅЈ“МЊЏHi’ФfУне’œbЄŒ “‡Ж>ЂђZ0яь ѓ žМџA\qЫ ˜0ѓ"„Э›ŽФh?д”љ!>6ѕ^DФ%рћw]„‰УЃёТŸџчјeˆ Ч-*ЊкœŒšЙ 7…(=rЏ§!цЬœ€оy[QЭЬ=s Ж5рмs/_ўZф4TaУЮm8ћœЋpЦЬt444)Њ0iЏЫIK‘–sw}ИжФбT_йpчЎТДд@<єњ|ч–‡‘иž‹ŸZЈХё UT7ў6+яяFPдD\xёЅpFтщ-љX8c,2цŠšЊяёзt -t‰ЩбRLЯЏSрh)@&fръО•іЎ,ˆАУACCYљ“зРР•uvN.&N ТЌ№„D&bBfmŒ=mЪŸЛ яЦFaVLђїэCем‘ДOЁ-ќъм=лсо„ŽHЊќLШкБ…ГSUж€ДŒxЫTЏ"51љL˜>aAvTЇb+ѓ†љЙ`qvРнZŠТТ"$FФbЩœ1\џ!=ёбŠE{S#ŠЫн˜73œ ЫAfI^oБcіМ8ќљŸЏуіk–УаVЏЩТў9h„ыІКЈЙ9{(и€W&Мf;f-˜‡чЙQq‚™FГ{і --‰Б‘ьG&gFТнQ„.вЧуq Уу‡‹цтљП<€ю пт‚щ)ш&см­()(САi`$pˆ…в‹˜Œqј`ћNьIGАХ‰v‚81ѕz[А7k/ћ>Jms[fˆ<іјя§Kј{8ЙHLФ|кWDФУФФ8tUьG‡рРщщF~a~ЫЊУМ rЃQGg[-ŠšMXAAX—цŒЎfьЭЇjnјDЬJZ‡ъš:т#'J*Ы€КR<ђпJ\9ЫеTy‘E9(Ћ_€ФЬqиcђУИщKЌи нШЯЮC`є0,™7ЛіесКЅS№вЄEH|ф_H Гau8$)к(s щ1иВc+%jјлЉ‚ „- ГІ;ёї7пЧѕпž‰-џљ'’/ў ТКI?>—nИ№ `ьйЖ ­ю§№K‰E нИ=лPŠUŸV`ЦR:;Ћ‘Cz9hS’ #AŽb€L›=щ8 ˜nМёЦ{§ыњ3pbžѕ[-фьќuіd‹Ѕm‰Къі, DE^>ЂгЦ`ЪШXЊ`vЃСiED ЛЩ`I31Œ*:$Цњ"tš‚L‰„ Д!ЉкПћ+]X|ж|Ф‡в† Ћ……NˆЙSF pлД ЧŠкŠВ‘W\ЈјDdŒƒкМШ*nFъА4ЄФ™QNћЗЛƒ@Љ ™gœ‹1Щ1фЛdX4tЌ.м‚§-ў˜>qМŠ*Ѕ"4оHHGЄЇ;vьAIu+ТЃуE€E`фeчТCудiу3hлŒ-[ї!nк9˜4†+$…{ ;"™iьћ.Дx§M•PˆŸбббh' лОm/bF/ЦŒqi№Ѓ№FŒ1лыKАnG5ІЮœ ?рŠ Б BЃ’рпY…э{ђGЛp„GХ œ /{O,I˜”™S{ vьЬСШi‹й–ˆЄБj~n RGeb"ЅЛwэc[Фо" !rQaŠ}FAVUY›‘пŒR)QёFъFоО]иАa ќGLУЬЩ™lGr KIЗ‘Ш$€3къ‡„є27ЂкˆЩSЇСU‹œтJі!žЯˆR'ЊKіQ ѓœі$œОh*‚Pѓ*0mщR$‡ћБџDFЦаWpW4эŽFЃЕtіфз!Žv Сў‚+#тiœы­-ФŽ]Y0ЅMЦŽ?јR‘аp$А_;З Ќн†%ѓg#!"эДлЉэ№bђœЩHŠА`їцЯPMћ'W`<цޘB[1 vtbо#}~њцаеАkз.оДгяе)p ƒВRН‘Зw QУNбН“Fš‘ ‘ъ3Wмтi#Šэ UЇТШ•:љ­Ђ2‘I_Є еkl—‹ЯЁєеKКЪXinхbЋcІ’єз+Ял#ЯžCђ; №Скн˜sЮйѕ#ќRьm„Rzв)pќ0lпО]šŽŸŽz :JaрТl…‘ЈnП='…1 UИŸЦш(I^QѕЂфU™™фРзW)х’uЂ“Ж“+kzдz}R_ЩrВџ/эЗжFa№rЗxђѕžыiПв.^W:ъSОvЈЕЉЏіОКњŽДмъЗr^к+єёI}u“9ѓВДG€фгЎЩ-ZW{iжSЦРЖ Zџ€“ЪOЈI#Д&I}ZB:TЄŸТдхooђmTяIЩТ<НхoЙm`ъ­лїŸ@! B ”ћ•е“Ui{ЯБДU’а@ЊUЏ U­­}§Q2ђLhїЉЖ5j~ЩЋбAНOџЋSри) П;эє;u ыš/ф ЉяЂТXšЏчЙ‡ЌБ§ќƒљW]йЋМЇЏ­ˆўgњџъЧX{Vлк}ПНЪЊ~рYŸпТ }~њ–нџ|_ІƒWsP’а—ѕ€#a Z:€fкт“UЛХЗyЪЙСђє+—є9T{дB+…Wњ5ЖЏ ‡=ЂфФ@А+˜Г7љ–еsђ ЕRЃнЅхаОЕѓђ}р97§‚5 вОЗщЧ:Ž‘”ЭщIЇ€NЏ+DьЏЄСVс_зN“њ5`ЬЎы€фdRћ›Uзqэ.Ќ?˜пЌ‡Eя­N:t ш8б0'$$sbЉ/†dzв) S@Ї€N:t  ЭЭЭ* dб/ЖЖЖв—НSб5С-z:t ша) S@ЇР!)`V6;d–/Š”ЄІІyyyJ|љ­ЋuЄ“~FЇ€N:t ш8: ˜5їБЃЛ oм€$nrДЗъљu ша) S@Ї€NƒRр˜МrD:тЯ=>BCCЄ‡СœqOД6§ЄN:t ша) Sр8fЫU$К ч”е/ща) S@Ї€NGMc&š”фXUAGнR§:t ша) SрkOc&: љк?zu ша) S@ЇРIЇР1““оRНB:t ша) SрkOc2~ЊhЊœSŠBТ3+QИЕЭБNЉ†ъб) S@Ї€N:ЃР1“С ћ2Я P’-уMВнhO’sЪЦi=^Cъ—КчЇ’EE.ZіSђ[30>%р)I1НQ:t ша)№UІР1“SЩЦD˜Ж™^Bэuшlj„СФ7ЙХМЭn‡_`LVЋ2Fм ›ћdr{pЁ0р­ђ_ўS№л>юJ$^Œ‹[‡šЭfEJu*б§„@Џ@Ї€N:Оq8f`r*QЪъgGCi>zђ!Ўyб1А›>QчСУАљ`Ь+B#"—ГеOйЬл$RЋ ’сT“JH{”ЄЅЅ)ф>екw*=z[t ша) SрыAЏ<01RuSДу Мї›Ђ|]fN5aZ`5э@NV оњм ŠpГ­{ц2ў ‚еl‚ню‡јЬЩ>g ЌіРS œ(’ I‰ьKЄ':t ша)№uЇРW˜(L›ъ›}€7ЮП1‰РMKc0жПГEЗЉfLMѕу1ЛImУ ф7е +kМнРч%РОF 8 ˆўз:D гyJmJЈIItЮз§UдћЇS@Ї€NBЏ,0‘Ц‹ FЩо,E%cOЊж\ ‚ џ0‰њЦlhё ltŒИ2&Œі&сШiЇД$РŒ+миыЊ‡›РEБ…Uю<ѕў@бСЩЉ7.z‹t ша) S`h)№•&‚<ќA­ кКЛ№N`"КаsФІ5ˆ=Ь$!ё№ЗЩа 'Х%эР’?$XЛнiЇБ,oфu=ща) S@Ї€N_ОкР„tГz=(qЁV#bBM№№Xˆ›NИјЩю0 ЛЭЫпrо‹ЊtGёv:МСKѕ џ)И„hFУ'"q9Ех(в>6_˜žt шјR( K2ПВы•~)№•&KVEZт50– U7&<ц9љЦ№˜˜^ДђР@ " ]Ўy]№КJ =wфœ\ђђ†^˜"€ХHyŠЎшK~8dR4™иY=ща)№ЅPРэv+sƒPОђы•~ )№•&к˜hЅїwЯ B" œ˜ XќЬ‚P’"€ЄэАЁКЪЮџНŽжњ:X‚Ј ЂŠ(8QБJ 8Œо#=dHб^J^М”ж(i hQE-ъЕјW&Bq'nkk;ЕшEыа)p0 Шb%44T‰3$ят‘‚пEЮСЪжЯыјКRрpяЩW˜єƒЂв‘?ќЏ1 !пrN’LФ цЭN/же”аˆжњТ“иѓЗ'сІOmgэ“F#"sЬўФ$&D%%#fФ?кЃсGcЕћ+H07“т $Е hЁЄE-Ъ™Ёџ#§II{{ЛђЁ€”ЁЏI/QЇ€NС( я_SS“]кЮ`ŽЮ#єш“IY—rFQ§мзТЗфљWјАЈ0’Ž˜HСЇBъ`пКи–nэE–ЊVъoќЈсАhв ž4S}уG@"чш.ќi!tе™ЦUOJ0U;Vtв8ЅВ“eеfСљЯ,x(Œpб&eяwІ~бАи1vBв2hгb„=$ с‰ЩАиьœpŒŠŽ‡-8L('šF2ссс gˆ”ХSIO:t œX Ш{'рB"2M’IYŒH9х]=мЪёhЪ>Uђ mОŽ§:њžJ}?•ктK;й&FоР@zЅ$н[uBОЌгќЩ‡Ѓљm&qT8мržFЎ”X@сЋЯ—DЕ9ё' БS•#@#ЇdРДpUЭгюT' ?ŠWвx@ \1ў+&TљT7u!ЪлˆXCVœk‹бRдеААЫXоъЖЌL{шߘКь|8нŽў‚Ъ "dy‡L8zв)pЂ) я›МwђЮ)8‘{dBюььDWWќќќ”ћO$з˜“і}Ђщ"хKe‘4TIк.щDвiЈк:д}?жv ­јх8k[оgГйамм хYбЦз7п1“Sх!Бt„АGў6!ДЁёЋФ$oЭpUЋ58<шpРPR"{хXhJ:МЈ*ГYљэE„еЫ(*yLaлQЮ<–™`BАЭŸЧl–я Є„"жŒ^{ГžT7t ГДюn"У1“зwŒ{Ќ=„_зиa  gа)p’) НsЧ2Ъ=29KŠŠŠR29ƒH?UІЌd>к? sтќЦЙPдЯ^щm!Gž_њ%ŒPд[‘‘‘=ui§’%Ђ6#Y™ЊЇЄК9Ћ,<нЮуЁЦ‘UzŒЙДЖЪоf"С–ЙXSY%sБ+v‹ЂоW*V‹'Ќ/Rwww7$ZИ<_ЪFЖB{6хXžзc$ЩЗiэъшшP@љ`€DЛщфpN­Ж№эћžQSЃи|XёЇdФ$/&O dp!)=ƒЦЇƒše TДАtmдSTЮИѕђ[Р‡fs)п^Дѓ…ѓяф*‡RЉЦТтl|YфX>n‚nžK ц}ЎИК:abић“•›иNVнz=:t 9„9у Cb"CVŸРфЂxиЬ­7м”ю˜ŽRэt,Э&(’ЄЁь—лбŽ–.bbNо|z,}—{d\“““ѕі!ЛOкQ^^Ž„„„!+s( ’gcџў§=`щр%~х q‚О–8‚=d!ЦЎ‚н DTU5ИˆЄDд9ФЪ‡ИVЎ( FЪX'ъЧ‹­ ДYс9 вжNЄввэEAK+?R‡аJт!‚­DЙa`Д7б!‹ЌzEЪз“N:њ( ЋG—Ы‰nЮpЗaћ[PRQC` Ц$Grю2!}єHˆ XЩыЄЈзdE$bd+ъЇK1ЬЇђšё™8‡qRЩˆиЙyИјъj*РыwbёЂ…јєПы0љ[ч -„*oЎЖd?”Id!FJxœь“0Ÿ.GWч&8ZЫБ5Ї'N@#1xE фuSВBUЛ,й—вГВwY7UcЂ„0e4rGѕЖr<їЬ“Ј˜‚Ў\ЦyжЬђ$“}7№КеjanЊ№ ї@3'ьnG7ЂВ к>Œ^вwMb"§яш C‚йЪ№X јфуэHу^liёQhЋЩУ'ЛЊ0cњTD…и ŠŒЅФж2гFP“+ IDATЄB.іKсHtЈ0PТх"SГIŸ9ў.ђ Qš8Ц‹4 П0ŽЪ8№zбRЖ)ЏЛНж}„Ђš6LY|&&Hтj]ТaŸ2СBWUQРI_ф™Sy&OЊржЩёт3h1ѓйsаTAFъШhЌЕЫб%УXЧ€v+'}ў|х kуWja”ѓт ,}6‘фјв)Ђ‡†2P"Ry‡ Щ'Dђ0JНb kf!Л›Мˆё3`ƒБЩ5jƒ”рlн(ЮFЮЄs ѓВ +QRЇ\@Є<ќв“Byї0ъЄв)p*R@“FuлTщч)W^{ѓп˜pњї1;ƒЊŽz”6И‘деІ†:4wRКc{*œHJŠEWK+УУрhЌƒЧ€@›ѕtwЕЁЁБQ i3vЁИЊšN”—aU!n€L†К7œї HфbJПШ`M:š ёШы_рБдa\№5ЃЎЉ–Р(DћЕу•<‡Ј9чaQцH8[JPRлф”‚1Њы›аЭп› >ЧЎlЎНu*šJѓ‘здЁа":" žЮVц” гcЧ№a‰шЈ)EeЃ)щЩ”l‹-!CЯœ?єНМDы`FЏЃ?;{)–ќ§ќцЪ%иЛіE,Л4йEЃаY‡кv’`AmY)*ъ:‘’‡=WaSM.[>A†vd•дp<“I~mm Zк;aѓCLd€2–§њHжу5Љmqgс8ьYѓ<6VЇрВГpДсЃзџ†§Юx|ћД9ЕЈЊoGtB*Неxњ…З0aсJLJ ЄЅэ3ЃОІAс‘p6V ЌВС1єR `Y\ЅїkРрtvш1ЊвДCЉpДЛ˜h…kпZ'ѓ[žЙ"„"~‡гФШЎВj€@Є!ЦЎ:ф!•МZ$№š€Х'JpШ5љ–МrЬgЋGт"X\ЅЛЌ\‚yЏ‡Ј_ЙO22Ÿлyѓі`K'‘>ЯnrЌЄD=iнГ|ОЬчEk‹ў­Sрh( ђЪ$ ]‡ЌhM\y††…г6ЃнА{[Ÿп‚Q#№ЫЫЏFъЗcёИz|Оz \F ТccбоV…Й+.РЎ—ƒ†фkА4ЕК‘9<{7ОуCЛёЮ{џC ƒRgсєqјЩќpю?A™pSMšкh0LГkп|œˆ_пvіЏyoрŒ38яжрПoo h #чуЪeГЈ‡чЪёH˜цбvєљ=”rЈ}Ї‚+йГЏ[Œ-[w ќДьоS† ~‰Žж&T•цbгцб=jЎš‹ЧoНiчоŒЈШ ”я[;wРв)qXПх7КаaŠУ5ž…UПЙ _„/Ц/Z‰ШP%TJM ЄЙŒƒ LDzDћШј‘ЈZНЙг&`Af >zіПxЁqцN‹ЮЊ"ьйКљЮX\pњЌ}юNјЅOƒS vwФ%г#№Ъ3ЋpўїWт­g‡ІЈљXvZ4Т)тX)хљкI:"`тЫLЄ№ƒ§–ѓr§d%Ссœ/вљm ` MЃ4б^D•ŠЈ€DlJ˜Z ŒF(AМВ­vо/Fд22Дˆ‰HSМXјr№\ ?ѕь_3Вb)[PŒЈ‹zљл„ЎzJUќB`іѓчyЙђЭNђLX­VфххaїюнŠ^]^=щ8е) тьŽі‡cіьй УЪ6kРФЬUЇ›^:…%('ГwПvбsЇсЇ_„+Я;%?Ww;qуYQpšƒ0,е†5ЏПgЋ?к+Жрнj`тќ%4Ж „[­{KZамE•е&Т Duт$ъюІH†В#=eЩм/ ЄЗ_œўdХ.*‡Ѓ ‰KVрŠ‹aнѓ/riЧЬх?ТиГfЃkЯЋxw%Ю]4 uTY4RW>ызw`љЂХpьe‹alZ$ŠwW ’ЋіPSЊ‹ѓБfU n|ф!ŒKРњзЧjЪќўФx”7ЕгѓЉ‹sљ‰5іэGB!(ћЋ‚1в5Ђ“1Іт&ГШЛŸќуѓ>f4ДЃ‹урFсьЋkЄWg:2gO@ys мцБˆЩ˜‚GЧ-B”Ѕ яОЕ‹/О5N4ЕДС9?ИьBŒ‰БЁЯШ`ьVž[uЬеБяЂњ$~ТbмњУ<§ф§(?ѓ{H›0зE-ФА„0dеš v‘ЕП–АЬОќ7X4gМљх№ИИЈЇZЩF)LЗЧŒдaуёyq К::љ<љ)§эG‡Cќакuˆ,Н—Ž˜c‘‡Nc(ТlЄ „ШomUЁˆБјћd%1BUМrЭЄH)иNV/ #—тбЕЦpO1bл‘&к‰Twz]šші1–‰UЉЭr‚љ-‘œTбfфuіч ц[ЭxjwpЯYЬ;…yЉbŽ%uIщ8ˆ~G…+РDєЅN=VЯ@а(C4иC}АћчМд-Ј/^LƘ!ŸрЇmњН:F™уФЕЗЈЈЈwю;Xоc9/sƒb3@ ќ2€e+О…#ТPИe:E–ѓ,ХП&ЮП!!1TŒдIs`g–{^~oŸќЗД_†mmјѕ]ПХщW]†Ў†r8Шœлeb?к[‰ ЦЬе™(†кЦDњЏЭuRЖв/JkŒu”zИX‚Йс*'мЊsŒД›p:jW\™ёѓЯFТАЉ˜ŸЦђ/hЋg‡…}oщnC;уJ9лЫёw?…‹o^ O}м–ŒсСЖнћЊnТ’‘ъ)Р№‰319(XБХ1ž$ЏHпБЈМаB~фD­;K'ЦaЦMсуMЫQјщŽяЛј€ЛШž™‡К}•ш4X0§Ќхxѓ…птЅOу0/(Йћsс–„ЄtЊW"Fрќ)Q cГл›=К8›Ф‡ѕљ&7KфљUЧСƒЊ‚|˜УвqСwсoЛJ˜фAQy-jŠ xњћАшЛ7Рй”ЅьчnЊBYE b ЈJ ѓБн˜‹ї6еbщеFŒšВЅЯтO9№шзТB[лаПО-R}лuреЯ˜‘х#/fccЃ"в:+‚‚ƒƒ•еАїП|KІPG(@F1V9„g є$aДтa#ъђbЙ c!ЩH@B ˆф‘[л(Y›ёвi#`i GNa+[ TкPђуdЇв—оmФ№#~WУj̘втХЅЬ7—f^ ЕРP'+”И№9i\_Кu˜ЄО,тгЎJ*DЭФgіЄŒ‘д-Ѕ<#тFtъ[ж†œњхoPзжжі“Eїе‰кЄoCpжЂ3 ЦЃnЦ УдiNюœХг'СЬїvиЄИžѓгіMŸ#}дTЬ>џyѕ-dŽoи­xо›ŽЈј0œwщ…Јnїbв˜бДUсќ4c:BЁzЮт9ˆ А’™1ЪuOЪЁш‡oПƒVХ(•@( $Ю @|l(І›Ќп’yI`›ЎРк]ћ`YЖЗ\hРЦэŸЃл; 1#1зи-VДe‰щг\№ŒЧ-?ќ6cJЙ1yЮЦ™ С9зм‚wЉžXзкoО7:э4"оŒЄQг‘C™…wžм$€РТ§жЬДы@P,fѕ qфHьоћ4b"B`jЭD( aэA[асБ`ЩX3кЋlЅЩ#ЯУЬcgLФФМPэšŒя^{-ж~М ;œc1kђ,Z< avРв‹УJ)†№ИIxД№_љ–yW™ƒiќњўGысВ„учŸ†JcJоќ 5]iИєњQ@uбФБуhcУЪsNУцЌlŒœ= Sђ>B~Е Wмx ниВmкУЦрzкІјѓYђˆЊт“ДGžћ#I†њњњƒц”‚ЖnнŠКК: >МWЯ*RAcвqЭ'_м€ЊЊЊАdЩхќ‘6тH:0”mЖљ!ыљП ъжŸУoI2F9^U@"j›н E-3!\bˆъFГ/QŒфћтOаPJ€ђз&rn; ^‘dBDУб3\loц;rДgЩё‹Иш4{p #a4vc*BзaиСœKЎЄ!šˆк{tXЦ&„IIIŠOКoYJџIЙ.n‡2eЬњ%жяQЌџнАћћQЌJpFнЋ‹Vќ6ZДћŽ‘Z>P>O„4_ћ­еЏнућ[;юW7hэ”Щ=–Кq‰o00 ,яhЏ+љйH/лŸкЂLxn`щ‡ў-mЌo;швєЋ_ hу+дrrr [> LђЮiЂ”э!xџ|n’2eЮliiЁчm!љ2%%Y1в”wб--!тљ kWZ8Љоo НN<”<ˆ`X Xm6‹т­к˜(™шц9Щ/яЋ‰рУЩптЁЃИ +žbїсг !>”їDxCYYRSS•w_дiƒТ(ХЦРMIћJѕ’§№ вЁ‹В•‡в& ѓ z7J•=yx]ЄтЅ"зDн.}F,Y|Щ ЈиГ qџŽЄ8YФ‹ЛАxЮؘYeќ~Љ. —m &ƒ"jgћйо9†БNdёЌЙxI?ЮрьЃ,№zњЈияМ5ђ ŠЄЏККiiiвŽ|šŒ€•jхQšТК:.*`ћLЦFJК8 ]хœВВŸщЇŸ~К— ’Ї—рОЕб1ŸOŠњм -"M!!дor™`52ц‰n6u№ёРЦіЙЈkЎ&о(‰иB`Y)Чь ›oВРмёvŒЖbbѕЫ6ъ~б‰6З0rѕкИТФША#XІBќшќl-ЫЋrcdТ(рOЬгSƒzг—єWЦбТqЌ+пћ"Оћ?GfJ(у6`э>рЛ—/&XSнім4Œ“‰PJ‘(Щ !n}bйnЅиU чфчхй0№С•чAtЉт>&Іъ4xg}ŸƒцЊBlпM]y0&NžHз9ъؘї4TЖ[FJЛGћ–иШE“Ц‰фGВѓЩLїКnьпЙEе­ˆL†Iу‡3рžzMђШaoъ­C-Ch%I"њ–bхЗдэe№М[ЖвыFLЛ—‰”шаўэ`љZџхх>Ѕ<9fY|o„vj#њкЂеЅTЌџ9e( =sкїP7L{жЬFЮQТtфнГбШ­яšјr1eЕбVDо >џdђ’ШлцЋ0a\ђіЬцђМ)’ay‘™Tf(п\ЩЋЇ”ѓCљGк,|@Ѓ—№9'™:хš$‘ЄШ95ІŠєNUћШЙя‚еfыЅ…E€‹’[}/Ѕ/<т?ѕ§(H2ѓї ъЊRў`Є’Єяв_љ-g„љJ5š’d€$)йХ5зЇЅJnЁ‘єII ф Ї‡GЉSъ–ЙYЦBъжhOt"ФSЪ‘’хHЛ&yХtA­“ќнѓј0ЃИЃKћеіhЭ—~iвкЅй юОA‰м$ – тRSSабжжЊєI˜‚VИK‡ф#„UУєщгр"чNt"X†УпŽЈtmт@лИВАаmтъ&)>ДКpƒЙ ˆ˜eТфaVј!РХн…мЈЯР—ƒ]qyeЕсЁ-ЅDTмШР‘вЊ1)mt‹k€c?§!1 }—O|я†К|ќŸgб2fžМѕ2Zк‘y2ПККэNТТ#hЃQSу|ЖRlF( o*Ъъшš‰ Р]М—Ў‡Ђу‰‰фoiРe †Х—кЫ9Аu2ёЪ Žjќёёћ€фЙ0жlBTњHГu`гžzЬ9RНMž)ŸJїэA“-у‡ЉЋVэe’,j}ъф”Gнќ-й„ цІcW^&˜H=ЪЄч[ЈOR†іkеjчМн-xцž[№ŸКH\їэљиљЮ‹ЈГ§ˆРdbяK­о#ЋМО Дћ•6ђдЏ$%к^ѕ„ўї›Fy6Dв,sІ…s&уѓЬs9м(€BŠю{žf‘>HђЭ#ЧТDЅŸŸŸп;hy–!П…uЫ{#‹Yјє{`V^PЪщi“oНj9lЫw љiƒжпї]ЋHЦДААPћЉ|K~пі*їѓŠяЙ~7ч)WxєРqшiŒв~=ЩЇЕСЗZџ†šžR—HдDУ"B‹CЅƒэ& є­NUаЂuJG;–{&šбЪЊoЕ“NL=c)’џ—С@EtGэІ˜hг:Д”Ђ“ЋїчяЁjЏC‘ЈxаB BУT~ќЇRэтƒdъЬъщ'ŽјNŒ5ЁnЋ •-H Ж!0УBƒЊЦ1‰ЂчO4RЬ™z(EшрПw=ъ;kPзйˆкœ:дх’9WЧqфНбЁдуЁ›Hц/=ЯпїS\LešХШДVaЭћŸРAзУ"w2юќбЈЩY›ю{ ГІЄЂЁйДє$дьй€КдsёшЭg#ы“зБŽ j1eљЅX4&Ћџ§2Іœ{9FХУб}­пљ&ˆˆкн˜‹Нu&ќюžkDлIŸџчЏ˜wыЌ~щ6Lн›7Ё†њєб“ч`lRўїьcxЕ1оq5&І…bЫЦPжbСЌ…ѓl󘣺ЎЬZ‡щg_kЮЁ”[UœE } ІLWgvэ-ЁZ, UŒэ@п§ŠV#fЬš‹И0j‹їтѓэй\ю„`ЫіWWe;оЦїЖњQћ;$бњлgŸЃ”нйZ‡ЌьBК>V#iъ<Єz№ёњбиiСЄ™s0,>…ЛЗУ3œ Ц‚›З#jфTјЗ•ЂАŠю •h7DaСТ рG№ФROЅgFщЄўч„P@˜З“Œ nЪуcMкмь{П0ёљž?šc­мƒЗ­o•пЇ~QkаxяНZykƒзгВђRЊ@RШ?Јnц"f`X†фбT НМIЮЩ‹4ФЉiїѕ[ЉbњЄО}я•љфењт›яPMц’Ч*ЧзЂZѓ-JŒЂ.’“lЃЈЏGTrЄэ;АіƒŸ‘О (йГgO/(,wЯ2nАK}чЄ“Zђ=–sŠ^_РIO†у})ДzŽф[^ ПаHЄMƒбs`ЬќгАј†;БќWObйнaљSяbХъЗ№­wпРЄ˜Ля€ыЖ ›§ьуjМѓAОЈ$ …+ƒв•Т8н(мм‚НЏ•`пЖ=Ш­кJg.Zluш6ЗЃеЏUmЙи_Ж ћзmУgЏяЦЮOЪQCџuы,J2јQуqо#!ЩydМ\нDL9яОњ+<їьsШЎn†тІ€ˆЬ;™cF  , mbЏп…ФЙпСэ?НЩ~uNƒ;юљ ŸnCYIжќыaФŽI[рBzЌGЛ%+.ПЩсм№+žЯGoƒи‰hŠ…oІскwndФRхВFyѓFGТ?€~љнАЧ д[‚›Іw’CЉ6‰g0Љ@Њл>}у Мл SУnќўџЄ'OЕ3ц\†џw%ўяOЏ*яќ:+ёгћF-Ѓjћ*ќuc>cдс†Щ“АЙЌ Л_§=ољt;кšѓqћ7 ЪуА`?EяЊЕ{зчљјгеч) DёйяЙаY_†kЇMЧЇ%АИZёЏЧюУЖ:#=Ръ№Гў€Jв2ћэПaWwzD^xтиЯрX5;оХф+ўM.3ж§§Q<ћж&ЕD™}єєЁ€6OЪD}ЌŸ6_лњп—Бљ_Уgќь|я ЦЮшTЫућvЄхЪ;Ћ}ф'ƒДе7PbЪc9Џ•гwl СfЊkXВћ%$эљnlmDy]%Ъk ЎšСгЊ”OU]5ъ›xЎІ~Мž‹Kк№vп{ЕуЮЖfTUVвМ еuT;H„[еѓФыlФ–эЛ"BДћ|ћ%чўю[Xќ­QЙД7зЁ€RЎbz­ИФіТЇ.9иwЅгЕ55 Тй—ЗвѕЦжvх^­=ЊC‚šЇї\Oйb'$эTывЦЊЏ<-Пo[фмРЖ(Фн…ВтфхЁ™ЊiEuуqЂБЁ‘N BSыыаЦkОх еБДI{і•фЯa%&к}вQ)PAШ=“Јќ–ю+Dш!„FэО§эЅэƒгMнПЬыlƒй <мRoA‹в,Ж3uвLЉoѓI7œwЁтчnЂєЃыэс-ч?bK…#ИоБ,ˆРЂ­š^:›кPВ*…SВ=9сЉмЄog+кЗз` [ єд ЂхyšКС_PE"–9ХxŒш'[šЛ1nж \Иџ—ИќВЋ№Ргo"oЯЇxх§ œГ$šžЂUŒƒOЯHF:b{,R™аnig,J&ˆЎн]єФЂЪfЬВbf07Ћ"§§BB;ЭЦBh?0)Я…_бoщВ[ƒ1“пТOП3 ЗМО “гєgaцMЬ€ЋЅyмщЙБгŒhЊЯ,TХ%ЄMФ“ц #5oўј^˜–>wЕrSЃŽUUŸВRŠ> џќh5ў§—pСK№я‡ЎУ…#џ‡ЯжoBеЇћqщХ?AЈНЃo|7]|>ђ‚Њ№v+Ѓlю/BЫЪркяœЅuIл5{ -њzI<{§›hJœŒaмvіMOрЮы.€Бi'ЎќЏея/C4U‰[жо‰Н{ —†nEkClЪxТQхЩ8Яп7V.)єsvеИЯЉЈ!•Jє?:ސYыоСч_…а$ ˜ŸЏвЋЫљЮаfЋg>>dQ2Oёб8gWчэЦП>lТm7/UЏq%-†œZОš}№Рнч +є—јЯпna7a6§Ћ$Ї`бb\щЦЋ›^cћж!`І*ШŽ] ехЌGЋБš^zfL™ŠdЯ$eЫiЏТWzкЯЊЙЪ6Џz?|р5,œ—gвbмw§yh­ЏAЪАT=uјУ+џХ}П Ч‹кЅо2Д6k ь§-Ib=ълЭуžNєЯуE1]fC’‡sБд‚WО Х#Q№ё:,Ощ^\u6Хя;/EqBужцЪ,L™€О(СђЉ(OўrчЙh_№ ќтЂХН4•І№.~TрЁќфgg Уdd Ѕё=Фа†VЃ“o{iJoћМЕјћуwуŠ0LlЧџВ№зЧяХШрмwы3Иу‰ЛPљ ~xп*мїћTV6`\ЕvЫЗжо#ЙїАmиёUO>ћ`к=6к%„1кj-оyћCюмЋ%•Ÿд$–М4=hX€ŠXЁ{јЫm *$z?K9)BЂЕ"вG!qьDЄO™”q39њДI G€…ВzJ­йcŒOУЁyVьЏЗтГзАі™||іnіPGžiCT2їj#!}Ь§ЙЂч„pФPя$PЉg(d_…Вš&ИhgsњљпУRV]кф@ W1{ыZббмŽw^}Tq8HЋzў–ав-Uhэ`ф@оПeu>#у0{ХrЊ0*щGQ?Иaсџњ'Ъъ)9 qдСЦ_Ю 0t3hT-УFO^t>юџэхxaг~Д3Ten[fэSућ1jєX43 Вu ѕVёШHšЯ@@d–]v3~ѕ“я2ьЖа‘Ћ ŽA#У5[#Sqэmw#ВъlЏ6b%_ў‹gт=GІ0*f7mЅ TeЩdджвЄ€{pЪЗэe€#ЂrpwhЊ5ƒДЬйуё№ў]ЅtЛb*Xџ6цV(+Eу$дђБЬTЬpиЬуЉEnu жœ-4g”ЧіъlмАY™„dВЊЉЊWЪ*.ЩG{HДJjшŽ–>K!Щд>Ž ЫЌ4xЧЛоyYkпСЎоСЮїWЁ|яvђ3ЂїС_‚іцFJ!*QНYљe kŒH†•Ы&3ь}3 єM$”Л2ІE1Кшщ–67мѕЬаоSp/wWk|CN[8/N'XКvю2œn c,“ †ZХАШ1˜’>—бN#їZ_ллмžrл:LјЩoŸРяŸј;žјйшЎиƒ\ѓ >йQŒЖv7FФ… ’1йћіЁ‘s–”хьhТžэлWZЃ%A•”КхesјF4дQ_[…ЌН{QЦw–7БZŠВї`Чоі"vЩJ˜о6UиОu;Jk[”>vR%N*9Y wЁJœ|ы—cU|@pїўЫјуЎ<љ $Vf IDATшoёГ{ХЦетЏМ‹VкLFDЂЃ:џц\|Ы-HЅ7Њ $–vьПпƒwX6*ШWA„œ>ЭДЧј№нcххЗр'wў I1|№?Gmт2œбc-~zNоi*=ЕiпZхaDЕ!@ХЬ[бI’ Aўўю т}Œз"VЕŒqтт WЊЈ "|кE4oЃїЯ|3WЮЊ†`0q^Б0’lh@АR†Lx~`нZNцЗ0AqЫ ‰Ž_ў8ёК` MСУл6ЂйŠФа‰И+tœ6к‰ ч?ѓ!Б=ŒF}ЪД}СkА№єЧqї.Тцзў…Ыў№ 2Mexfu=юЙa&žКљЬОчэиŒ‡пяФЃw_?ЮЩёБ0{DОz˜Фљ@œKЪЩТГŠsPD @]Ї %mpmј˜сžэeŸPњIчŠCe1{ŸЕ ;]ˆ#pъюЌУŽ7вЛ/ УbгсЩY‡П•6!КcЬ3~ˆћ.‹—Ÿ~-ŒЙQѓљ X~ћ/0в^ƒ+тG#сіптŽ.ФЮ~Kƒ1'С‰--qxъСЛPЙњяx+ŸЊo4т‹тoaХ8J6o„;b:–L†.Ц%2I"3ЙCММтО“H\ЊE5xšЛ(БŠLŸˆл‘ˆКЊ‡.‹EэJ@ьЯџFфNƒ‘№А‰=u>НrpёхTгyѕ2pžyi н‹‹_:†v QЖ P€3ньц^xЦP?кХ@Lt =ЊDjЪPžpЎ›6LiXеFwн:AigЦYW#§ЅІчќ№^ЬЎ­‡зТБьq_VЫЕbюЪ0qQ-ъš;Аььo#4ˆоI|JюњY*c4ЈГв„E—"}Bƒ&1ю 7@;|ојѓИгaДрЧŒb)q(6TTсКыnР+gШYЈ cП/w|ФОйgЕ1‘яS5m-(Ч‡4‘‹ѕ ЋЃжЎ"иЧ$"$ nEPUjЌtk—Н:’єШЛщ‘ŸуЧ7ŸƒМй1Ићэ­Иw)A CŽлЂpягOсЛу†cЯйїтOмЅьД.E‰ZfХƒ%~т…QА;ŸгцJ*ЙPYТ6фЗw!‹”юl/v;>С(ћЮ'=ЧCџm@E^.VS’ЛђўЇQQє8>ЯЙ Љ™!H:џ—јн§?EЄХ/Ыё§ыў+ІтWПћ*+ ёњЋoТСеuTтВЛпХ•лnЦйW_ƒ1g\JP"KЖОџo<§ЉПје…тŸI:|Q!;HЇЌќўтW„7ЎCkŽїнїkђ™v›†KШDQў^Дэ}UэїР мЊВDФХ3H.fNХю• '"чНg№ожќxЮ|МћзЫБїі›1ЬkСMwџїўє mM<8 шY4‡Јвf+š^JРdлГГ oМ”Ы@jфa=щP§вђœЈяУUў  %мСnђм3щŽ›DЏ—љ1цŸzІ3о…жщЮW!ѕДSОШEќh FpиХЉTћ-љњ‘yЙШ€DХ'‰?CAьBЎ“{(Т(Ђ”PСТgўОž|Т€ &PXўTŒazI3T} –HHH}Щ%ЁБкšwа.Ч!‘цz’фs0ЎвСК-з•ФoM=@лљј&Ћ0"фНg ыMЮXiЩтФеЁOйž:LV;Ђт’ДlЪw7Сиe\EІ…pА˜LЇ…c(ЩH  ,д_Ÿ­Одлvž тЇяšhє­ОIvпєi/б‰{OјІ”ЉKтуа—гЗпМњё—GmLФшO;ўђZs`Эт ъЂJѓж‚МїоЄЭЃжО€ŒБёd6н I)iхч|w‰^”$ѓйРЗ” +F№–фс"#€’OyOЕx В'Š)EМœџх~5™DŒ)ЉUг`EѓJCс ‡K\†ж~€Œ™X“ѓтЧE#Ї(wЙS­Љ`ŠТр{J;рЋУaТ™^ƒ Б1LэЕyhi ъTКУ‰й?>š‘Ш)!ЎpТ’$ рœ‚ˆш|џ…ŒЖšGх^„ЮhрМ‡БЉ<ІШˆ“ї“ѓ—™Юk‹=HQы/8ѓћ(^@Љ­‹ЖёЅАуƒтЉЗš№шc” K9‡[Tp~5ћЧbС™Ѓ1jТ<ќЦg8-Й–{Q@ƒќ'жTрŠ9#‘šA0HњІЭ[‰gŸ™ˆ'ќн№ЮШАrюnPКiцт+ˆ‹Бј”Qј]^bгc‘Пab’’еѕ№AкЂ б!СБјя‡лp%"BЖЌO?„72œ )ДјŸ†­л†ч~ў-И ШЮ•NОЧ;Ељ[:“іXQ•вFу\d}њ&оЭjGD€§ў/Ияпkqѓ9szЪјрQб_n&>sтGТИaі0Д:i!Ѓ)‰пђ>{\Ј˜(I‰‘ЊЗ+Ž`шш`оk‘8ј8…ŸRIРE_ƒ|'ZŸг}zŽњхыэSџВ$ЋoО…h+NQIФKёa—UдсюXŽяom5ц{ЎяX${} Щ= ѓb ŒœлЂ@њђ§бЁы=ВђBгЧбˆЮKcdЦвё”#Л]Яu)  DлjCžqэY>‰M8hUJ{Иџt§z<ќѓŸbщeW!Rkу(J3ъ+€ќЇЏ…\ѓSгoЛ?w,}уЮ_#-тzlzуe\}яsАЕюGЅym ЅИїЖGё“7ШїНŒKoyЋžЙцЊ,МњЪKx{ЭFјП0­XТ§{ьƒJўФыЃ­Г ы>Z‹м|#~ќ“sСуdŒ,Ђ=)јdх:…;№Юж5Šz§`ЖвГэЉПў н•уасЄWпщ“ЙШ[xъ9Иўєx˜h?"в`3эiЪ*š3b>Ю^9}ДЮ”@zкGsƒ†*ꕉ`†ущтœаСЖˆЄ•[ь‰Иєђ•xш­HфŽО]ўHL˜‚8o;ž{ё_ўнгёо—cWєЏёкSСF­ч/_ЬЕhџ9Ї_lJ›:Й7Эќубћ1aЪ8X*ВбкD шBU~Jв,xƒ6~KюШFsk!Jhд˜@ѕ8уp(e§ўvМ=kޘ}&цв;ђГM;‘ЬрŸ^кцШвмижЏЪў?8*УŒ…+nТцŸџї§Е г#;№№_>ФЏўєФ2дAжЖ2\љГыpџ“ЯаXwќwnУвЬx}ѓд !щхєЃz";;›m2`тФ‰40ЂЁ#ЯЫ5ёC–•h@ r>[…7iн{лЕчPoцGн/‰0ЧŒsв­ѕˆ#ћ%СвќЙ‡ФПпx7цп€]В6—?Š› нИ‹/S7A5U9|nЉЩ@W•ѕ[мˆZРЩ~Њ:ЧЬ§ BЙђ5IСЉDЦќћ§Їё=л#ИњМ+бIIТЁ˜і‘ДєИCвI%'8а@3@VмгŽГОЃ*CщЈŽЖŒƒ5љhЫQѓKi}LтhЫЌ-CQ†”;хœ*e EЄ/Њ‹r)ЯђБ„Є—wZмCхxв•W\‰ея­ЦmЗнŠЉSЇ)Цм чЯЇ”Ђе4 ьЎ,AђШбˆЅjдїySш"Ђ}.66Пѓ2^й\wсdxm!ШHŠЁ'H+w&6(ъy1~—@ŠŒЪˆŠв*„%$ТиNUI]3ZЙšЇє4.1jьўk\эаћвЯ#FрмsЯХИqуИ‹э~хœ‡bі%Ї-ЁИ Я=џw\xсе т2ш3иом€њЦfEjуёš‘˜wk5 Ћ;‘šžˆnюЮ•s;]qˆŽЂš‚›sѓ 8—3žуˆa%khь@dДЈZ=hЂъжNc\/ъъiАN)Ўь,_MINY}B"у‘ž‹ю–z”T :9›жЕЃ™›ŠZм›эХвЄПмДџˆ:iLпдкM_Š[EфNЩ‹Ѓ­‘Ю#„Q[œУи6єЄDоe C w”-ІЬ‡aЉ‰А0*pUQ]VŒž OG#іч“'й6j8C8ажххЎЫ}иў-Piу!Сй9ЙF&ЊъG".œЖt”ееЗPRЗ^iЊЉ@‡СqЄaп,5XЉЧvNРў^Ы†ЎђIлІўOгРЋќнл0Й™/“D ЭсfK…ЕмФ/$еєІи\”Є†+фўSў”а„‚‘€јћ†ћ3jW(}Кkрф‹ыbП]­ъGњтnЃб,%%&КМйИбNTPэ$ТјbrчLОЈбЖ”SОЫ'ЛђрI@)=щј*R@@„€“S-‰§‚‘сУ†+A'#6‘ЙШ'.9эаЭэ™иХ€|іLю\<s<ввв”эJFв№}бТ…ЪэJDhГз^sй‹*йl1@!Ÿ~)<уДSм7MI~ЪёфvŠZЦшё§n‰ŽжЄG\TіЈn…Dв+E’ЧЄf№#ПдфЧОŽЇѕ7€v–кљ–;zЙЄяхX<’ЂФ[S’ЂтGДљгZ‘:rЌzЭчяИIОЫіФЪuіЩш†qT\хЊдФ;ќpIhЊЬУ4W7qZov9g0Y­і_ДЁбёŠлѕсњж[Ш 88,0щGt!,ufЅ{ПРЧмЖ9’‚vЗюКrќe‡МЏjbгЉОSŒ ChэˆES;Qmc7ђZЉЯЧ–§ЇБPƒю|IЕH[,BќBљ !0Б!РLФ?ИйЦW•:CвnyєЄSрЋHSѕй§ѓ“OrнЏ№+Њ1œ”6H%ў&P˜{3ŒбkчFNŸ‹ДЁгњЈ—з•g{ц>Юћr,ч”IPЉFљ#€­7Кiпщо|В‡кю]ЛеHдЁИШ?dѓ6-iЖ]]”в[yŸveР7ы–жєе/’,ЅAJ№1-wП~АСЬб“T‰Љ\зЪPђВBЉR;Џїо%4dyWoлдћењEнwшфK7i kшi—”ЃЕwа2|к&зШ/з}ЪД Ÿ“ЬЎаLГѕS#ьЊэяыПo{…_N:`вг0щ*Т=œuээ8ЭA5 .lTљHуЕ8љня!К<+Є‚HLи XvЖХТR_Ээt*aщаIЗМц,zя$HФ=žsб{…86Є#~Ё†ЈлPгєЫЮ“OEНF:О „„ЃЖ ЎЎtДкaKLЅQОКž0РУЭEВ  ;˜Waš=]‘щ^cЂъ)aр}l^bD‰Х|˜0ТИ}HOё*ЊJlі:л›Ањ§pжЫсOЦ$ЕМЪЗ„pџJ;U&нЫ`ЙWUm3ТЂ8s.яэЕtЂЇ_jњ˜Л0y`ЈejЧОujч/‰%†ѓšАя=їš^њJн=Е:МЏяŒoпc%‡OY}w vЄŽЏр(eCV’пкГыЃJяўtёб6ŒЌД}юАРЄsr€eРe›щЂнŸсOO<‰§-˜}ц…Иъвя06DŸ›б‰nє”ЯўШ ›ХХ†v$-дЖДRФF—Tzй ž7pkЃŽP$™TЩ)ЏЅxтјQ…ƒс!‰є .[]ъe;ш— ]}щ†Єz!:t ш„ЛпŸ™2АZM6эючWН^G71ŠдXп 7rЪ7EжfМББ7\KWw)Gц~~ЉyмјшПЧЊshФъТŠknФ’IУ”<Ьp@ЩbЫїцgo"Пb7;p0–§јџŸНыŒЃИкпщюд{яВ%KВ,ЫН7м)ІЗа!@0Н&HHјIЁ=IЈ›bšС`м1.ror‘,KВz—NК;§плеЪ'YеUЖgьгнЮЮNљfvц›7oоpqœЫфvkЁэ ŽКђlл„WHД™ >С[sОуВЕCЂЦтС›.сБ6nЏхQЌ ћ№млѓpЫmwбж‡фWbб4ЪхJv ?#­–k>"К^ ƒЈЉЂ> u_м5јєѕПaiN=cMИќЦ[1ž; \у6ть]пњиMM?nuўў5o­ysљ*m:nЙц\јл‹hoi>ЮНс**$чрЙ?І“[‘&Ї;ыјыђt%‡javRefъ д—чу•п=…ŒYзсёП>ŠdЫ>М№ж7Дx@$tЌ бгєЄš„TжT"Гp-0XТ~џЭьWiMЈbcФ—Л3aƒЮЦнїм[/› gYžјѓ[Ш)хЖ_š0pRrc+пuœHJG­ХхЄBpъš Иv–Е‘ч ‰…k1~жФgыЈ л(&lљœ<&;O+EcVтi*Улџ§'–eб2,ч›ЉcЯТЏxз Х{}Фу\ѕgк)К‘ѕуў­‘ ц"‹Uf\ћo\}зУxфЁ{P5ч^М4w‰нкљДr[їџіь‰ЃбЄD*Д“*9ЊхъRbЂзŽфAjIџђKБcЦёŒ“pє Ж`Ч[aqзеyДЦйT ї§•—L˜М;•~.™z њ„ѕСћЫпЧœŸWРm,0==‘v2b!‡Ыљ;ќPN l7Э€œЯэwЪ ю6д˜KЉ%э@yv6e-wX‘^ЃЎЉ™tя}%?~9’J4АEД+'ZJ‹wm&Ца2[aVЛы'Ѕ’АЎЯvцw$гж:ЄЄн^W4К[юіТuVюігvMЙѓCЮ–zЗыЁ§ќДƒХЁцGЃ%?в7‰([к]wcЉ Q,іBфч яTpћЌJјbу"k~{6­Sь“€Вќ=H<ћzœёаS№ЂтЈы;bX~нЙj^zћ+„„Zй‡ессП§•жS‹ЙН‰сMxє7сЊ'ŸGпњuxь­Lќц›аЏ_š†FUm ‚эЛЕЭ&С#­Ы“ŠЉВШгƒчlбцБЉвЦLИ#FbOЩFžJ.6“:vf> уё !4œhЕИ#‹68yќиТC№Ћ‹† Ќz ž{’жЋїgaмЕуЊ)ЉXўѕћXИn+лзмv‚ъv“Ь<Чгц§№Ы[o@щЯпaеО2юй ПГ№рэ—ЃzѓМѓх"T7Z1'ІїГfуЕ[яCтm6Dџсvє2\Ыd-DЛёво/gKзиEV­˜ЧѓpЧшDБз†ћžz Гп\†Н‘’м„O?xсуЎ‹Ч5П#­ћ†ŽkчШпщ19ЈЌ;yxњв\їJ\~яƒИzdіэЪФжъ<њx)юНk6яsџ;CO'/jzŸt Єm‰Г&ž…Ќ=;№С‚џсНзпЅœk†Œ †‚?МЙѓІо“$Д†Ш5P'—nJ ъАko&жoЌЈ {qм%ИѓŒ308e0Bi LЏjлё/LŒЌUњmˆAЋ{GјBвЗаSUUvq+œСЦ5_VGЪOŠа6 УOF%‘šюhІ-х1тзОrкFZЎ8хnЯяЈcбL*ŽGкmБў9/ŸЧKдЩЎNNZHŠK=i-ƒ7ъЋœ<$ 2"ЉCзћ† мт2ЌсNА…цбљ4‰j€AА—№H†РНШ"Ÿ*ођ3O Ўеˆ‰бо]П+KKPмд>t6|ѓ^јx)юы‡ŸVцрZ'ўеь3№д§ГсE‹п—оx‚($WБoўђЛgёРO#‚:x|™[кЙ љд{Q~,УЯлЗbGн6ьѓХЖЂ|ŒіŒЂ§UXЗ+"=ЂteVз‡]~{Yэ˜ѓкпАkM fёрТFрцЋў‚›ЎО}ќѓЕЛWўv6ЂЋзсйY8+БЏ>ћ4.ћгыXћиЬ%ЁИrh~~g?ўВіOх‰З^|ж)/уO7]ŒGž§vѓЌА<Ч4љV uЌУј+пFэвq§3 uЦ/‘"'tвэ^…п§u.Ў}ь™#~аK‘ьOЈџиЗoИЏш єI‚Ѕf —Њъa)ўЗ>В‹Зp‰Œэˆњ нгЁ9Вй4bы’˜ИvрlyќOfої,м; aўHыл‰9Й№‹ŒуЎ+ЪЅФ'“ЃЖХ…†#|h8†йЙПТšѕkё№Зџ‡šТ=Р8 –CНБzг.€Ј;.}<ž})І @ZŸZEši}M4флvФ’ЦёrВUЗЅf&ЄУ(9лцX8‘’дбњфКЬuФsuттрУŽЋ%вΘ!СN~iyеђиЮlŽEО? y_єђ~\ФЩFЈc*шžКN$ ?mЏт1дЧ е^ACC„•dHђЄ-ЪnСК А џ~g Ўf QДнd?а3ŒВй`K­ S,р{•‰Р„,ј№ПHйљ эtєG•й†њJ*ѓjGAt”]G“ЃN›nb­ЋЅkХЪi Ѕ:I<eo_€з/{OЄEiб)yх…—qСЃoblЂьз%^ЭяЎ‘ŽбоФІ•gюђ:Vo\СQXPє9f№ЧŽќxдљ8ЮŒхнТ%уёƒОыhЧуš{џˆ+NOбюе—ьцжй@„‡2ŸNxІ F:ѕ=LлВTЭ%œZИё„ђКкŒИёKž.п-oЛёЬ3І™HŒЮ7ўС6aAЫЋ Шk№EdU-R†cСГQl'nмќР-ПЭ[‹‹wЏЦ3O|Ž^iQ$*”М;‹ЪtoђрИ$Ч‹ь–Уiљ•ЏЪsvЃмг оОд%‰Кx'^{єa„<ѓ в"яQ]}ЈаІС_žрЪ“ sk1ёТЁHŒ @щюuXЛЧ‰_§т")я†lОМ†Д7еKGy1:ƒ ˜IМвћ$с€g`ѓЎЭјjбWxыћЗ€œ]o C&`њuгAr&ІеЉ&ФdЭВ‘тnк~ѕŽR<іўeЅЅк96f+lинЫ>”niЎyаo›3›$Ыu еЗ}ІэЕ<+Ф(++‹Ђf?єKюЧŽ_пЮЈ "[wq2 Ш`n8}Ћžˆрѕp†= -oв1ьќh ?-*-B}Аi~D`к<ЏЧЉg хyyЖ9S­§ZЇн~~є4ѕŽKгжЕ#ю0m>"щхзЮiЈгќ4Ї%ЉЖ<ЫNTзblƒY‡e<<,DaRУŽ_Z=Ш_ ЮЖXИ"С G:?ЭXШr‚Ж28sYQoOЂз МZ%і жv‹ˆŽ‚М#!qс4#?.нJbBKЭИ7Gw\П$Я1бД7AsђлyЂЎ•@ЭВнv5ЯЮ‰иŠ D.ёгXX‰–дЛцwН&š=hЩ„љџ§Q.hД IDATNьХoПsЯ{œ‡ЕюЧо*Їr ~ёсGё‹я~Ц[пХЏџў)ў~чщxч‰Щx06lТE52ьњ5Zб:v!yN$ФїЁВЅЖ§Мc=ZxП8ј7Fр•гiЪŒнћђ[НЧFўŒo{m –,]‚єЈjд6X‘эЫšЗ1џч3pFЅяЇWnАЄиЭЛЫ}5‰ЪшTд:М1,%œЇЛёќŸFьм^9QУ—ђяЊœЅ9z4 {_6йj,Ю™2_–ђ|›ФZgf@skЬЫТ‚Х+0шœ4ќѓоXї"ЮлЙKїcдˆ эH–ЖИљ>ўпЌ­џђФЄгgуН[‡yХР žИыИтЗЏЃOˆЫОЫУпюМ)С•pСЭXџё‹ШрЁњГmkѕш—ЊKbЂeA ЦMeЗZ,јє-<јз0lб"ѓ ЄЙ јПЇŸх,TтŽщTДрG?яG4­3dŒвEыAŽIУ&сŠ—г8P!ЅBTˆ>suZЖg<пЋH‰tЄс}ђіП№гNJzЪЪрС5кZОxWRymЪ@ZLЄ>3ЗОЩИ/щЈх 9Gпš8КXЉ?dfЇ.[эTГˆ†DЌ;NP‘˜јљљA,AФФlqЃ•Х,ьШоGх3Z"XЗНsWBBМА'ЛщC3x&“ХйлSы…Щqмжэhž[щП–Щ7 Ёw’ V7IЙфм в"­{6юЫ€#ЏžіњЩт 7ŠгыU~kw]^TнЯˆCТiђ9yVtЎ*иЁ}ЕxЮ=Ÿ'›y$бту}эi>#ЎUє3ؘv“!-ьдKsv`/­иЬшЧЂ f8)ЗdЙ,Xв&–ЙЖ,›ГЋљlЄЄЌхсfr)e•8š§В€ДфO’дВмvNПa„гЎzЎѕѓЭj‰qvзЏЃДХ_кpyu•й9KфLXь8xxzaы†LМџЯПуо?ў ><‹DЮЁЁЬŽї)ў–#Би‰9€K xхqsЂxПpсB<ћьГИјЂ сF8yFоyMЩ—`їжL4de"cЬTGХiљдлrы,ЫgЁбСШоББгюУ™cSаPш…[Џ‰gФ~7“GxOСыw Х№пoЦЃёјЭз#щЦ'pоhЩrjФviІоŠ•ЪКЂїьиRцƒг†ђTd’(3їщЫ€&цЃ­ж&*'Џ@Sи ‹їgy43.KNзфёфXђJоЄ‹”GHšьZh Х  ьХ…ppHг^t)—„‘Ў‘;œвNмйNxWвоЛaю}f-^љVyRC‰љ–г›ЕИ9HЪršXыдžсЕCв ФQˆЂHЗ4ћ iQЙ™?buЖgž'gsˆФIЦІЭ8(Ъvg‡/Џƒy”ьцяй€­хў˜>* …TЬўlM9.8c2ќ)љ%dy^ь1бД ќ'RЩ“7ск#i˜’Zšк—ŽЫЂчCї“Щkat„ NзьЧ‡E‚Ђћ5умЇLB іјIч*ЯэЇЇiЫqWŸ­gЛ љt1)v˜jЋ+№ђŸюФЂЏчтЮG^ФДѓЏжˆГ,чл–[…ZšЯОхъў$ˆКxлШяё6I?nOuїіЦwоЩЅˆpфр‚ѓЯзВ'“GЃM#^дм7Вмђm(ПЎњj.VVЧужKtЅЮ–Ў?Dт"ЊNЋKVP 2ёЅсЗnИ—]v™жіХяЬГЮЄЎO=З {№нЋCqq!­ЏЦВ 6Kq]ввл”‹G‡?Т>$яЏжвĘ\žъ0цŽoогЧ{фяДIыќы“S#эжї пУ§>"&щѕ.XЯŠЬtНТкп U”›йРФ-YЕѕ№ѕцЬ‚N В8Wв!Rуeз{НЛМ&k-ДАѓЅц~DD8~|ћ>ьŽ=w_2‹>|Л‚&cˆ[юњЫ\pі ,_ДПyўiФ;ітŸя.B4…DUо§qѓ•ГНњkфХймRhзH‚1мД„р&И4Шššj]"#ƒ›5 \{ЫИvZмЏž…ѕЙcЕK=ƒbqЭo^Упњ›УQšv nШˆG Пsp„ГфfmРкu›ЉtqЃрЧЯџ…ZёХз!СЯ†UЋжСцц‹acЦ"ЪЛџр‰ Eq—ус›. В]=–/^ŠZЯšфЮ“Ѕ­кRœ VN[56Ќ]…=ћ+8`,•љ№ю›Ž~œюЩ\ŽRЎСћ˜ъxрV5Jп Kp"ЦO{5V.ќ ;s‹0tbЉЧэ[ХѓчЂ„;†„X?'VnмJбs1O:ˆБTШ[Вˆіoьш—>Cгћ`яЦ5(ЈЌCUYЪэ˜€{n„y_,CцЪЏАл†фиPќyози]в€Œ)—`*I‚НЭЬКГќ v:9Бq9Ї†ГЅ:~зQкб€ЌMk№§з_`eё $zSYЏ’‡mU"6c NнŠюXƒKЯ?kФ$Фu$8 hЈЭУпŸј2‹šтO; \’Ђ‰о‰ЁО€Ј,Џ€/э1иГПХЫŸ/FEК ˆ@D ­Њ)ФЛЯ=5&ЌџЯ‘xеrINь86ьмМЇпјэ9DёЈВx<љ+sdwCо{э5V…?М‰щНƒZ{-ў§ЯчБ!Ї+чНПќѓ[pЙЬ‡k‰ф!ћЕGАЁ й?~€9п,Eym%^?s>х6FSОќїKјzc b#ЌxщЉџУrЎnќ3Oџ5ђjlXєёёУ–|l]‰Oцќˆz‘є№и/{1.Пђj,пQˆžоZчА"6мЯ<і&Жь.†Пo0ЦђФWwžыTBуVЯЮ[FRВoўхї(фI^ЖmxјхwА— žkоН ї§ч;Ж‘2Мјц4œXХКЅ)тQЫz’СOџдђ[ќфЛйaФOџш~ѕ]љБхyзpвфSпг?#fџівnЯЏнќдsљ'ЗюЁўФо2;vеЁФюƒ”q№OŸ„Ё< ж‰ЖёмR;ђЈcPF"cЂdЮЈ:kуЧњорСƒ1†фRYOщIRR’–cаж!e;ЮН—_ BuSіš„Nb`x­ŸkюѓєHѕўOП-жЏ›?Ф-ae7оШ‘#1jд(-Ÿ&L@TT”6@Ж јBК6ŒўзHWJ$~zl|kž-dСИo|ѓ m№•|‰k)Џќ–Иt_эљЯHGBШ3FN$RЂЭ(ЇVPЬшяЊ*х“ђOwАŒЏГмpVхЦэТ“ЏКЃъхtawœ5&ЫиёJЅ+з;6ІНh$–В4'Šsa}‡сЂА/№‡G—s›сЕ4Ју\.G„Гг№ѓѕІиnы7q‡‘ЏП7‚Й­zёŸ'!ZŒ2ѓИCžzy cщКмви…˜ШЗюєУы§Ћ|CkЛqїSї ЦГŸQК ЫhЌЅršш№TЂЄМ}‚Т8р‹X™Н˜›Юœu&>[ВЙIёHцI›IщЩу‹A§“xИdjxЌ@#НЊЃЭŸ@JњF сБ№Ї!& џxinxjя1.g1­PВхtAa‘)јнeЫ‘Йžыю}њaм”ѓёг[_aщВFTіЧЈсЩ\šоИыf\29Žв"дUюУЊu9ИўЦ›1kR_.ћpЖН§gј^ёG\uЩх( ЎСG{Ыx8$2Иє^мјЋыаЧ+ќ_џсFLާлv`sцŒ шћбgфs3оДљмЮ'ЪЪ>œ {‡RТ“п\ˆћўіn›c?Юурa—QEpd0F‰nЦЪW›фЄЌЈЙћri Ћ–dP7AЗиЭˆTАу€@}9uCD KТaцVЛQгІтГЙ_aТ№<ю›ВХџљ&>ќh.>|я œ~іDdŒ˜ l^‚в2фэЇu@vc;–ЭС›ВaІhЖЫЉЫ)]ŸALde|Ќь№ыЈ"?уЂqуе—cPПh’jЫзё &Г ?|uГёеЛgттпП†J=МИѓ@–qШL6ц мѓЋ™јхЅїaћžэˆ№эљхpk*Чџљі5ёTа”x”д:ЉПH§(_^ЬЃг­ž7м„аиT\=ћnмrљ4ИГgбЗшiX}Bqѕmw#У?3џ‰FЪFD5рЂ‹ЏFџ)3Х]ЕДqсKн 9ББ’::nAшjAц–­(ЉЈЄž1—œHrмЈ—`&цѕ””4r;ˆœ-ваРїHnš§P‰}%%ЈЊ(Ѓ—ŒŠа”[Н,дeЁфЇšK_T:ЁТ/u?h]йќцМўоЩФЕчŒ!NfdgЎФ ЏЮGП .'••ѓјt.Wpщ1;ПXд_5›eДъщM…РИЂMиЯ%ЈŠТНи\oFѕУЋь№qЇб@Jг*xЬНЎЛУsPЄЎXGF}‰вГЫЖ~э…kyЦЈo>kј™Yђ[ШЇ'ЏЭдojхзN:эЅ-yэ*?Z:Эљ№ЄqD.лљђ;Рз fg-О|ѕAМtзtlX№|i"нї§x_v­љPE,^їF'я”ычfЙB`Ž")м\ѓ(П)ŸНБTžŽ]JLŒ™–Жр&*Tmјў|Й­ЁžœaеріЛC-їЃмК'{ФЌЮŠ&+ІнўмЙ%В‘–"ЭмщAывИюWПЧ€Ф8Йы ЎбŒбSЦ!"4Wпџ$R"8№…тўп†bWvМУbрЮŽ%,i(•ЙЕRTњЛSэœnЪ "ыЭ2HHЧ$’†aсpњqыlъpRRу‹!УИЧ~2kуpэU3O)ЪгыХЂU;pеŒСд ёšŠўfю(фvПО 11№ЎтžŸў†…cB1jђйXМv9жбЮAtЩl/œŠaёфы/cLъУИџйG№іG_ЁlbŒHХљgO дЪ­ KіЎЧЧ_Ќ!бёЦѓзŽ‚'єгІŒ>ЈС„С§xф€Ё Щ\RёЄтЈ'b##суŽбWў;ž}ЏМК‘Љу05-i‰ЁšтДH тЬСTіѓBп”hm&юс…яљў;чCМД†qЅLуЎˆTь]И!Д’ie…„ХС“+яІPФїqЂ;lОџqы)_~№BћŽЦЄŒT O_ŽЅ —#"еŽŸ7хрьє!№§љqќИ6 CˆMпšO‚по;ўћ јиЫqЭь_аўN8ВУЈDщIZ'њЦrЇ—€ИыУiв•l7Dъ­­”Ќ#?yЦ5Ќ1ŠŸФеQ:ЎёuŽmхё"йрbIЅfЈФ?vЦX5џ]Œ™z6‚ќIEŸLп2ьянs5п†VN! 86єpWEœNЖЌ_‡мЂrxћ‡"5­? ­yjћў§ќќЙ+g-wхTŸЛrŽMtžЪсяЪ9ПHФШŽOЗ|џйЛ(ŸŒ Ц'БуoТвyѓP˜ŽKІЇSj†тdЛАHDИЦ‘;9мhЪпЛE)чƒшр— йTЌ”эТ1119Ђ"NФМ2kœfрŠ$Ё‰Ї—Zi­Bu!њюyNТˆђžнfc[Ћ…ЮьХйjЋ`Ѓэ?/wTVVгR/зžh[ЦЩЅ й"ZХГ3Ьž>№ур[_YN1>—$iТ“ЛZ 'Ъ}5мYц`К<Є‘;zО{у1,iŠЎ?‡ЫIѕЭ[’ѕйІ”Af‚2{—“^Х6‚ел‡Жdy€Уя‰ЄQ+' ˜Ж#Ђ77J l”ИдpЙISRІФЈQvж№ОœюЉŸТ* '№Y$IБЕ!z_омй`Ѓž‰YzЅ+’=Ѕ46Ї™ŠщžZ<ВSHжХЋЪhз†ЛщFъбNХ7ƒ8e1Ў]ўЃх'ИщiИњЩoУпw(~В•|о7д˜мyоI#БpЫzЅR{wnAП#ЕК‘эцкЎрœЂj˜‹Вё‹ $Šю­š“ЖXAelйуууЃэ@‘vа‘“М‹THоi)OjjjGA•ПBрЄEрˆьЪбас eЂ8йQНяНњ>ZКa!>hЈ.‡WќHќцžйHŽ hВыъЄEМ—Ќ‘3AvёœhRˆ;ЊFNЛкq {J 2UŒ+И!N:OўчЖR›W4'~vJЭФƒ…vбСщŒEJ"кјв‘гъbœI<пЊQ'Ю&юЪЁŽДз—ssH(†j„№$ƒCG!а+шr)G^\ОТДgсріЪїБЄ"ЯНњžЎЫКБп}ј^§hўrыyНHщh•ыД&Ф9Ыk1цХzГzP„Яo™хЛКжЯuИ>/П…,_ОœЖS‚œœмюРоіЙn›v{azЮxОЛёъс=1њ8†ышйŽќчкћnћŒNТк yќкFЮыCр@G #Ч/Š0n›ЎЇфФ“фЄu+—+YЊ’>LђgBQ^)эЧ|‘1\тsз%YЧ/ы*e…Р)ƒ@—ФDh‰ЬВФВkq^5nПщž:щ‹тЂRxFрЬ oРЎќШэ–ѓшхNФx˜VЗЭY–хУ*ъ‘*… МВ]966ФЧЌ‘™žP$–Ѓ•6tЕмP*žЃŽ€АjўqА.лBНruRЂWБ uT`˜ƒAƒGQ‘Yо х c@—ФD›S 7qsЇ˜К ‹зlЁБІTŽу,‚ыў;ЖЌAXrчZ­r' ВGo-К щщщHLLD)Яю9ЁHЩ V­*Л# Н” M(вq0ЁјP'Ъ?0њ9,=wіˆКЇPК$&ђгx6u <ЈƒpОМяWИіЛ)˜9" ЅY?уѕ/ ёњПŸ(днAƒн‘ЩЈŠхФG@ŒМ‰ѕGQ€UN!p<ш’ИdJ–9ХЮ‰r …РБE Kbb,х8ИC#(. П{ўlиВ‹;;ИЕ0.ГЎMFjb4ЧјSџN‰;mžHЉ‰ј\$%BP”SєvZющэVљSœ$tILŒrЪK*‡ЁљгцСXкdНўВл‚к“кжEй*)NW3žRп ƒPўС˜(…€B@! аш’˜Zко’9БВŽ‡БЩЌWlZж I‰ZЩQMK! P( CE чЋdЎ&†еьїPЁWЯ) …€B@!а.‰‰ОIR3d"zЦЎ ƒ˜зmPз …€B@! P(К‹@—ФЄ%Ђ”Gк’Жз-ЯЋ …€B@! P(К@ Kb"gkˆЌФŒИ~ЫoзЄeмя"]u[! P( …РAtЉќ*40$‘†ШЧИ6Hˆё-Б‹!-зыƒRT …€B@! P(:@ KbRЪ“H‹KJД“3…t1БёTWй‘#fХх#;sD!VќФЊЇœЖЉœB@! P( ž"а%1 EDx8rЏi‘˜ШБХВ]X‰ALф[ŽЕeј*ЏœB@! P( ž"аЅŽ‰œ4+fœ SЮ†rЋБЌc$hјзъ[! P( …@Oш’˜жP“жIХа+QЅ5>ъJ! P( ю#а%1щ(*ƒˆДНп‘лpъZ! P( …@[™˜’EDкBЊЎ …€B@! 8TК$&Y~uMPШ‰AT\§еo…€B@! P(=A KbвЂcвlУD"7Hˆ|[ˆ Щ‰qЏ'™Pa …€B@! P]nж`т–“Щ Vw šhЫD Ќ 1ь—˜нœЃcЏB@! P( ž"а%1‘Ѕ‰‡ГБЋ–ЌDaНГъkkШVФИšс‰щ˜ЋЅM!Šr …€B@! P( .—rИnЃEмфthV] ѓwу/Фђ-{QU]†9И_Ќп˜­‡”ѕB@! P( .%&В„гфl‚›Л/f^r9Њ ВАmmnКўz$Gћbв ОxхуНhhД3Nw~”ШФW}+ …€B@!а3К$&Ztš ‰і†FИY<фќяЮ‰РДЁёXѓѕЧиmƒЎE/=ۘ ­P( …РЉ‡@7јDГ„ЪЎNG#м§Уpхнї#в^€eK–У9Кq:МЌz8Ѕќzъ5"Ub…€B@! P)К”˜ДZ˜бШ‰^~a1vr76{Ї!=кхEш7§ \:9ДНVTцдCT•X! P( CF KbтГ,г8ь6”6ЅсілюР 88œДgbœM ъЅй7q}F§V( …€B@!а]К$&Lвƒ†еdщ&)Ы№зW§pѕ„TиЊЋ5`$FІ'iiЊЅœюBЏТ) …€B@!а.‰‰ыbре 3†\…; БkчNдUVР-z€˜†mЊ–r\1SП …€B@! ш>]CЧD_Цi€гь‰3.Са)šIzГ™ж_i -K9нO\…T( …€B@!рŠ@—ФD79i:Эн„Е‹ПЦЖъ0˜wЯЧ_џЗCУ‘ПyЮјѕГје9уДx›š Щ‰k2ъЗB@! P( Ўш’˜hgхkиэя\K IDATMˆъ3ўM@тeјЧШѓ5ЅWб)ё ‚ЉI,Пв)^Ђу ў* …€B@!аcК$&ЃhX2/g#Ъ§3069ЅЗ!21 СМ!Ъ'"VЁSМDƒA§Q( …€BршвђЋF4ШLмЈмZ]Й5MxИе`о_ЃšП-7}‹Аb$‡ПzD! P( WК%1бhтв‹,€gž7rЖяЦŠХ ‘ej@`Ÿ’’ Sл…]сUП …€B@! ш ]YЦ‘ѕ‡‹шгgs1ПРq‘БиДєTbфE‘œкЇ'щЊА …€B@! P(B Kb"+4bЂ„ #!mўњмDдззЃЁЁAл.lЁђ‰йЭuЛАFeJHy( …€B@! ш .‰I‹:Ћ‰ћsИNгишфЇ‘Лtє]8тзDr"EwJйЄ+ае}…€B@! P(кG KхзіckЪ) …€B@! 8вtILœ•г>’"‘œ(ЇP( …€Bрpш’˜&щ;JD[Ъ!)1Є(Š t„”ђW( …€B + ХУirб#‰ˆ|3ЄГљЛйKѓ“пЪ) …€B@! 8К &Д]B™Š‰Лn<јChI““ ФъЦ3†љ1›`ІПEОЭz6,bV9…€B@! P(‡€@'ФDHˆEеШ+ЉFiy Д:ow:Q[kCНЭЮƒ§,ќXсnu‡ЛЇ с‘4[Я№~ŠœBUЈG …€B@! ш˜˜p{АнnAЃУЕN ъЌЈчсGrJЌR Тќ=рэ@_w„PŠвШи h-PV}Ж …€B@! P(zˆ@‡ФD_i‚З—>žёsТFыЏ\Ъip˜QKSАA$$~$&~ќ№u"€Ы9>f4е+ZвУzPС …€B@!  ƒZ8ID\ОБsЧNb"ŸFў–ј9(A1>brMc[ŒВ)ˆ …€B@! PєЗ ЗVaх•і_l–шБkпђGўэ–0hMrЂ‚* …€B@!pЪ#а!19QЃg хрЁ škё4<дЗB@! P( ž#аbвNфbЯ„ЄDx‰т&эрЃМ …€B@! шъ˜‹N=DJbXƒcчр№ЪG! P( …@ЯшФDшˆБxуЄ„D—“Д˜ЄяYК*ДB@! P(Ї=9ЎІћФ„k6&ГЖъBЌўn1ь a5wXh\Эlю~4ЇHЈb* 0&xмVо “у<Ню­K9К‰й6Lжќ ћМ#сŸ [%_ВАPјћ{t'=F! Pœт4С§Ј8'M1(Ї8Upуё6тŒяŽЪнbТЅJMмЬ‰Гт/<„Тa‰Шћё?ћШИцвqЅЁќ …€B щ”ЫЪЪАiг&ELTЋ8%hllьДмн'&&2Ї&Ћ7R.ў;юU “aЗў!pу=№h?х …€Bр`D”э ХlX,§Фіƒƒ)…РI€ŸŸŸ&5щHяЄћФ„PЩж`7ž&мPВпПћмuNѓЎН‘‘ў'=˜Њ€ …€Bрp‚тээ}ИбЈч'4-cvŸ˜hЫ8Vд–хaй?_EтД{1:#+пЧ'sч#ёЎ‹Е=;1 A•y…€B@!pшЌS>‚ЩЈЈ'$=иNУ]9\ЕлЊQhЫ@RrТbш;p nИы8т!д№:эBє<f-DЋNЁЋФе§Sщxe&ZRR‚хЫ—#..&L@xxИFNŽm„V/gЯкАЯМkсšЏW^;KWЫЗфГГ@ъ^ЇHWVVbчЮXМx1RRRаПte ЊгHЛИ)iJнЩЛ!’ФVэЏ‹gеm…@ЏG€’єJBј{"ь1‘ЮŽя ЪЫKс7cNЦЖr+Т<руa†ƒ3`‡гЂuтН(•СcŽ€tО"))//Ч—_~‰™3g"##CЫЧём6)эк, леqЩвСк3љЭ_n&J Эšі‚ѕОСƒ/О9хYVЭйt-‘њн]Xя!!! EBB>јр,$''kффHзЛМЦВQQQjjj”%июж• wB яŒє§кGŠ|Кz—КGLјТZ­&фm§л*Ѓ`йЗOџk)FЇ…cџ’/0х‰яqeм5[;!šЪБЯЄ4Bщ„WЌXЁЭB“’’PWWЇљuе@Vn9O…ХфРžЌиА#ŸДžњоa=v­дЇЂЬўыёеТнИђњYиБќgX"“‘–‚ŠїYœV/—”ЯещхIKГ/18pЁћI“БЁтИ_ы ХСЧФЏ%-yШl…ЙЁЬ[‚‘“ЯArЈ•љ“YИKк-YpyVѓcњэ„k.‰i­%Н–-|_{FžsТЉaфZ&IOЎ PŠPЛпжїш_ щдѓ$y“tЄ“&†\ЈIѕќ§§{4уыNžEЯjпО}XЗnFPbccЕяю<ЋТєЄНшяjяЩSЏШIѓЛ.Ч/HЦ!CрххехЛд-b"IcCтгOGXcђ’’ёр€фыП^F@ ЭЫrvIЙJЏРCeЂї /­0fщ€ыыы!ЄЄЊЊJГ|)ЂkЙяъŒыCХЛ‡у'БИ>пD)ˆ6Ќџў5\Е,ЯOщ ‡—l'ЬžX-V8ъ*1џ•eИфК3QœWџ dT—ьРЗkqжЄс05жPК"Б’0М…ЇlkпбЃ‰ёXE‡Fоž Сƒл,^ГЬšюЩаВљK=x RЂНPksТƒƒщuу ~‚pwЇ˜Ÿ‘8yьƒФcц‰о’Vг-0ЏйД)ЃЯрјJ &ЫрЦћRI[ђфД7’А8єгРI†Фй'—Дј.‘iї›4)“х“YНФ#u#Љ7Шэ<я‚Iёyž0ЮћR&3uЭВ6­Р^gІŠƒЭfгюKŠцСNq”Ф''’Kyьv'ѓЄK[ѕћЕ“gZЗŽжuШлš;ЌpRА6NЄx"Н№з–eigшаЁŽm‚вЅ`(lнКUгЕ:§єгЃН'‡ЁzH!аЫїi§њѕ˜7oЄНwEєЛALШйQйm•Xњб;иSSкњFьЏqƒПH5gDЅi/ЧGeя#`Ь$DбUєI<==5‚"тГџ~ќ6L›wЎfJѓЗnСІЌT•Тс‡гgއГt7VfnEYБуgN‚gн>ќАx ъ­ў˜8m&"ћ№їoGШЕЗр†+ЯGRА_-Xˆ}Uvє0c‡ІТ­О‹—.Ц–мrФ$ЅуД CѓгXЙa'ЌС‘˜4y*Ђ<4bд`ЋEuЕ6’{e!ж­п›НЛsЪ0hТ OФце?bеК0ћ‡aьФгn­РO?gЂ`-R…Gcяя€WP4&ž6ЈРъ5[аиTƒmЙѕ3rŠwmРž ЬjѕёФџо|/чѕЧ~sD{bХп!пцq”@$†Йc5ёнЕЗ^~ 1,ыVќ„‚J2ЦOGzЌ(œŠЈWЏyз:ŸŽк@{с$МЋћэBї5кЉДAi›B,…€EGGk:'r-[юŽ3HInn.–-[†+ЏМ")=!q‡џсфэh?Ћ‰№IЮ…ФŠФRЄjvD“Ќ3qНьКTЭ5/тoдјkси@ŒњlёуЖс\Џ%œ8'ыW8OWбк‡LД|0oZЛczZў\рsЎљпrBДŒ‹yХ5ˆˆŒ„‡Ѕ„ZЙДdкЭ'=%“Z€іЪЁ?y2ќеjT+ˆд‡‡;Fމкк:,XАГfЭъє}ъ†ˆƒ K7к/щ?љ Œ3 Ж ™>C'ЯBTPrsіБЂO0UŽв!ЩKж<[ж{”™НмГѓ#п2SmЂќ_>ЮцoуК3ПЖaхКS?І+iЩЧlёТџћ:ž{њI,X•ƒђьuxњх!2%!^ иЧоЬ%Ÿч|†ѕЛ*X†H ’„Шкю‘МS:СхМ+pй ѓBн„я=†oWnBEх^\~ХЃАFDСYБ§сxФD‚Gž~ў?(vИcРєбш—˜ˆŸF|ёŸ—№н.3†gФсЃ?=‚5;sАfсЧxєНuHЅNNtD0ђ7-ЦуЏО„!#`оЗћ[д9HюœvMRЂuКь*‹ёжas™QО6\~џ((­†егЇ!{й'˜џгŠ1Ъ№а%W пюР/ОЧžШ>џљ,нœ{C-ў}сX™п„ШІ,œvћЃЈД2sА$k?Ж-ŸWчЌFBМ/nНї%ьк_>‰)˜˜дс~&|§ж‹XUdB@Sn~ђsAV~ћ&^]˜ƒ„Ф`ЌYќfДC#ˆ’*i zн\‡Езvb„ыД ДД3НHћглЂ,гщR>й1&3;= 1ioыщћ"dGHHff&†___M:#~ZћgкNљhmј@;5кы‰јЭ! Х№Ožџ-^§п8)-3S’ИѓЇo№‡gоBQ=—U9љu#оМеRџ:Ж&]9^У„в4r2ЁЁž, BWЅЎ Iž†Ч,3‰Є K-˜Щ8ЦїdёЛOс/Џ~†z>jІДpџіUxфџў†нђЎK ]ЇLŸзšггаШcucФК­b'žўЯg(o0Уљ2ђ$ѕgnжљ’є™}=Ц-r­п'-j.GK>O‚k‘ц Vђ‘їЪfkа–я““ћi“S‘BJщxъиИўэ†ФЄ™)КYзo ќ(%Б{e &1 1}BhК}Фехв<єАЎ ЈпЇ6в™Ы 'пвqШЌS~л„tіђцъ:-~FŸР;к†Я Iж~KXў3ТJ—9Tз~R %K9$Ь&›Œ)#ћ 8*{iЃЇџГqЮДЩШ vУŠЅѓIЪ9h‡#а? !}1v|$†KCм,pЇФФфс‰По;чŸ= §,YјЧЮ§HіФ=/<_\p:Š–П г˜гpЦŒiЉУї›_Cа/ЉуЦЃ_P9ў]Xˆ‹oНнQy§JЌнВy[qхЭПЦщ“’рtkТ‚зОИгЮУ“' 8а‰ѕЯПƒ"ћ0ј{zpIФЊ?ИЙ3_& Ихa\ХEД‘@|z?*kсэЈEЮОB4Z#шхСzhРˆп?‹k.Пбž5XН? 9{+` №C#O7Б|)7мŽыЏМІ-nИз4—\|BšіЂдYнyйШЋpCMy„QžmпєTŒN…ўqОxўчЭ‘ˆjГƒќЅB›р; ^zF GЈЅЗnњKWmХTЊї`ьœy\Џк˜$•ЇЕ§Gs[hiЭ}а!Е‹Mк’>˜ШрЂxr}ИNт5–5%>‘ЦШВІ}ЙLzPqlŸвЮхжЏЗФƒољI8 ЮњSА}?эљ6с:єc­&=L[{YїАеcџъ—pпМFЬœСЖсgУ’Џ^ЦпжЄуцй ЈЅЄВЄЊюžо№ѕёБљ—4m6Zїѕ•Ђ[Ujjm№№і!nЄ<”цзWЂšR|Y’ДpљR–CсЌCёўJXН§сыЩeYЦGэp’ОF”ю^Чћg;уb=А~й\<§д&\vлmLжŠв’"4ТBЂюKL™О,ЉRRЧеп @8)™Ќ­wАOA#—'MlЏмт^гw_>ЩЄиЗ”Wа Љќ§МсhЌ%щц< б7/Иѓ]ЎЌЈф:Ј'ЧTomrг\н|ЖuЖ[пэеC{~ДУn+]Д щ‹[оaРЩ œ,х I‘нnYYYшлЗЏfЯЪhчŒВХu‹˜ШK ЮЮЦeѕ FЦШr<ўд}Иh\:ЖЬћFнѕ:;gЉ:VˆR§QшHЃB"3Юj.‰НALŽNв]Š(—ЂињјЦ„#99vЮrJНмБsћVьЩЫЧŽЕKАІŒњ”љкИFЪw‹:ВX“ЕuœБбsЦ2‘pё“Н3eЩијгFЄ Я ”АmltР= [V|…ќЂRиŠw#{ŸЁ^XГorїС‘Є‘†Элs0šв˜Ь%‹бїŠsс]Й?­ХљƒД+(. чoТўŠjфхlХ>k"BНЬЈЈЉеH„ |N!]дCЉЬЯB^~ ъkГА18ЋЎ/N:ч.[‹Ф­ы˜З:m'O9ыХIRWА?їnј5$†lPMFfАЖ;,ь ЋъЊ8pарlЈš[Ј/њ„„"ШПЃЇœOТfЃ‚›/і­.Чžт8Ьq€кАxœ{оE˜Qы€ЎЈa<˜EGХ#0ГяКя=}?^љРПџlЮЌъ[:Еcб>Z:ац‘AкЌALDoFШƒДз#хdKВьќB"щдГМšDFfсвƒr€‘z28˜PПЊЖюqчsоЧіЗ Цџњ#/™JaJ—+?ТЯ{ыPДg7ЮЙљ~ŒˆВуѕg_РŽzЊ Аї?ч.мxf*|:{ KАЃРnЙёnйxђЩ7рŸѕ?,Ф”ыТеgРќwоЧжв*О О8џВЫфО†А6БQћі#Дп`УКЭшч?8яrю.Еa—I?XАŠc™NКgr)їЃзџŽ%й №ЊЉ@фРA№ЊЭУ‚%йјеCФiIT­‡ПяЯF ћ Wп‰kЮŠе4:њу†=э8уŠбƒ'џќ,ьЁIИnіх(X6Šмгo(Юš:О|/ьДњ?*žeапЋжв? Ф>МOВЌ#KћBVк:ѓoћлGкzЪЕ(эюЏ€НЩ‚АЋъьЈЋ­с,ЪоqЃ)VŽЃ˜3ƒf\‰ŒifХћqНЙ ЏŽSl/ЪtЦKп^ЪЏk„eЪіDЩRЩr_:8љн“}т]Ї|фBH#”ЮНДДёёё\oфьžЈјЏХЌюTдЌ`ž-ЪDўЮuXМ.ƒЧN@Hу6|јЭO(ЄЭ•C‡`тиtхц!АO*’cC‘ће{(v ‹TxpqїА $ožyљ3XmљШЊKР5— їК|”7њcDџP$ЩГ_ЮџkжяХY—^‹qщ}(Е)Ц{_.AвАI7( K?Ÿƒеы7Т.š5§И4”Пь3|Лb=*Œ:ž%[№Х‚ЅXŸS‰knИiьЪ-CЪ€Сїс\ƒЄЄЉЖ K>YUР†5ы0§ъЋ0‘KD QXЛЙ€eчlЕЉёa0;н>`‚МЭh фcћЎНАЦЁœЄЌJ4gЌш?j8,uХ(iєУАє~(+ШгП?ІгўеXœЙ ›7х OZ:Ђ(mY№цk№M‰г'bЫЂ/Б~чьоWЯmт (+*Fh\њE{c[цb|ђХ24љФbц™га'’Kdœ2Ыv!яŽ|ЄMП%ђ{я^’Pю ыгЇЯA}™мз”{)х‘6ВгYgм“­Сооо9‘rЖMWtњŒ|œ№п‚#wމЂј–u{1хЌЁШ­ї‚'—9эiƒт„Сьу"ТЩ%ЯтЌyи0ЃћzснПРЌkяСЌQ‰јяЧY˜uњPmgGLtV/XиCPМт}%ЬР}7]ьнŽrk,wІ•тЂпЮХMзž‡п^МАK1.9J“@Yh`лк-?} іеYрзPŠ2Џ8 މGJB(Оxщ Xвg ŸWЎљнVмuуP,_ј-LЛП8=—]њ{хHѓ.ЧЊЌŒ†/яХ wм‹ &ФрнПAП~Пђ”ЪшzГyН–ЌW{s—Kь№‰<Зп~ |)їђІЄƒГ№Koљ=g*кu}НОc&-m8… œ­™уqнRDбЙ—'•ы`сUПЛгѕЮ#у м(цgеЄ3>CIЫUЗ?ЈOXНрхС7бc№тлЬ>о^Иясџу2R=ѓя­­У_xЩ Z^E5|вЙHV 7+1сI 2™‘]QЧЫв! B ]Yjiofw(љ”їAHŒtо“п'Ѕ“—‡“Š)r7cєФГёљгwтЦЉјћЮУїЫ7PъX†љѓО€WB<ЃгрэуЫvТ™uJњЇ&С/П}‚P_VŒo?ј/BFNцNаh.­zb_~5’'Ц!˜К@оМЖАо(оЄ$"R9wœёЫ/™ЃA+Ы\„_ўпHиr3Бнs.кмсжР pІ‹*ЈЋ(%Y˜йSЮDщњџaхŽ™˜uцLмџЬSиПmњ3Юљѕљ‹ТTїQGЃŸ§BН5 c™`s *o'uABqкŒБ8ЫfBzџH|:7 Ѓg\ŠѓgЧJ"OKC%ЅВL[YОŸ*№SѓdѕwХšЦ†кrV„h[с?ћУЃ5$ ^ЛТщ›AЅцAи1?%мi–E5RxъИdg—iKЇѕ$0›ЗэCтРtќяžЛP{як„C[Ш9ЎЕЃиЕrљШЛ$ЫњBі;r&šguЕvђyQМДa}5—=’‘„ТЪZЌњсm|ИИ“0gюW7ыИэ[†šј3qыѕ3‘ЌYЙ 5ш—6€њNЧv­Иu)NŽ+щ Eк K!Ў—д‘Мlr?((H›y ээ3/Б†IЄ)HIDATнАpсBЭђkZZЕuЦуW[КDФH_Әиx)DЊcмеП{qF}ШЅt`тєьР3вѕёЖЯŠдA‹Ž‰H8уО$j<зт'ФBѓ<ч–<ИІ#R†TvВ#ъ@^хBђd8уyуњ@ZКŽ™1Жњn'?ZЁєt]уl›žDcмoя^ЋdŽђ…д]^^ЖoпŽŸ~њIk›уЧяPAOˆЅˆЄeYFDвbЋЁГїOЪ)ЯШБ K—.ХфЩ“5X)Зјхo‹‡\ї :ђ“ћЎaлЦееѓЎЯJиŽвi/œД‘­VZЖЅj$рTўмОy"’p2Ы-эv+|ЌеXŸUHœ“PМ}%жхж"6ФеД™•6xЪЈч•8ЕиЖЗ–" лж­Рю§ND…{ЂФц‹ё#RЗc#*(i[єйŽМ7Ÿ?…й[Аbх:д›Н>rR"љnЪ:voоŸ˜~ѕЕ К–Цє|иИu7"ћІ#дZ‹Ÿ—.ЁŽT BcR1ad"veэB`l6#s[†KCYі6”4x!Йo жЎZ‡Ъšjд6x`ф„q,ƒ/jKrБ|йO(ЎЁВчЈ ˆїnB6Ѕ;3’Љ—[ЬхK[鈄”С”šР|Fлl щzRнЊ—їSOAџ{ИщiэЮˆ[Ўх§’ћkжЌбо3yЗЄнЗ +Яt‹˜ЄJB~YВЗ­Т7ѓОG%рЊиАмMT$Ђ2`кДЫ0eB т"Е?ЏE<З†)bbTЩс}ŸlФDf!wŸЌ^НZkœвЉ СjЏqrЧіiЩПtФb­W8цGЖv6PіŠ|іВLдRIStЖd+oпО};ь8%лвЉі„˜ИUЌ ЫГ^xЁІC&їД6Ф:;љœіfА-ђнvЩъЄYtiД‚ ›jПиTК–trW№1>#pqюZМђж|њ4aw™;fsщ2•ЄE“>јm ŠтЅПВ ПEщ”uЉхMŽ рђšKVД%NЙЧ\ѓmвђ!d_l˜ˆ3та.Д?2“ б<рйђKЖѓ“УSЄ'Г“:3ъMЖ ђЩ')IdGz‘OJL66KL„˜фжhŠАВІОЗЄЛJ\зЃТ+з…§(Ѕѕїw :вŒLELŽh;йˆ‰€#ƒt2ЂT(’ YoWN!pМv)KŽ"§В,†ДгŽмЁщЄEКљэЗпjQŸ{юЙˆЄ.х ЂМНЈЈkB\"ылc‡­zъ" ФPN”Ÿ;w.F­IЬ;{ЗКЕ kМšюДг$vЕєЙЗЛjЈ_вhqчьь–BEuR#`Ь јI]XUИ щ,х#щбrПl“œ>}Кv~д‹/ОЈ™Є6l˜Ж•ВГћhхщDW”бнЙЫOЬUьЭкFв6pNд2Lљ–Ж,;лDB.ядФ‰iš!ЙSТ/хя”˜Шz!уе4іЕoљMЖ/Є…‡№†мћ5тєЛŠЖъhЈП!`”ЮТЈ{ “щАeЩh2ѕLD<'gЏv–ˆHR1щIsI†K'2ЩnИ^Г”к“"œФaE )ц.FЅщJŠ%хюєћ­ІЅВMдBжзЋE*"Ыar—˜м•o;я‰aYЇгИ 3ЂœB@! PtŽ€A@ЂЂЂ ™QvЇгю]l[оˆ‰Iг!‰‰ ІЉрMДіш†юЎЎoBэTg5pЋ–*xэыЩ3ъhЂкюьœ|mX‹Рє‹i(щш­бЖ-ФЉ~mЬМNuTљЧ ЃУ=щ;$.ѕ. DUН з6оМЕKL( бЖ<љђ`‹ѓЮKЦМ/Жгdw.Ьu Nи4 ФMС9ѕд:*ѕхщ›ж„иwсТsЮЄU>й3ЎЬбwЇ7Œtd2Ы’ˆЬфЃœB@!pє0о9E&Ž>ж*…S vЗ pЬуЖ9БyOћ8\Ї1ЖuђљДŽщЏ ˆЦ^oбŽvЃ™ЛЃЉбnфэTљюhЛА”_Hˆ&ѕ"Є!–zSN! 8:H(dDо?Б{"Ї‹"kWжŽNnTЌ “v%&F1хДkлЏФ&Œ4-,ЄD^J9žкƒPќСбˆC}=„ЪIr€˜`/т2љVN! 8vШЁ”bbЛЇтъc—C•’BрФB Sb"Er"N№8шЩА'П лЖ/cлkэaѕчЈ X 44 rrTS‘*э" †ХЉОЏ]x”ЇB ЧtILк‹бxх[>j–оJЧЮЯ &’ЂЊ‹c‡ЛJI! P(Ž<‡DL$99ђYъ~ŒН}ю uMR! P(ЧC&&Ч+ыBFNЄн'-y/ќTК …€B@! шЭœpФDзН б€яэЛD1XДѕ%Я‡“зо.ъЭ \хM! P(N,Nbb,‹@ЖаŠ&М ќGУ 0в;дјхy!P  BXX˜UOI†Ф#ФFЪzИy:дВЈч …€B@!pЌ8!ˆ‰ ШВ$Вkз.xpklJJŠv4ЙеЪ#%‚“Ѕ"W…вCIBˆ!йЩЮЮжь$&&іHYXЪ-ФFˆ˜иKыž›CЩЛzF! P(Ч N Ќu–)‘\ШIК“Ѓk;Cd!%2(8Pг1‘Ѕ‘ž вh9YЛцН8јЈЊЎƒЏ,ШДК dЗ~I‚@лДi“fo$!!ЁGљ–2 Iвѓл­dU …€B@! PœАєz‰‰H/ЪЫЫ5‰HJ„ИъkШ€­ЭоJ‹б•– 1‘8ы+Аrх$ŠЈ O”dсЇЭ˜0vМ,BVhнV(‹Щ uX№ЭL:k*"ќ-hД‹В­ž†ЄЃЅ'БЛ0–?ёBaЈИИ8ьмЙUUUЁыŽDFв“%+YЪбЪиR*ѕC! P(''Нž˜Ш^ZZŠрр`иl6m Т"Nьvmёч}ЁŽЦфь.@ќ@Ї&mБ7ж`SV>FŽo"PWWƒ&šвEU'‰O#—O„PPE„п<БС-пšIPФ_H‡ц rb\ыОšU:SsО$o†Щxб5‘Вјљљ!;§–tъыы; Ѓn* …€BрdB W˜EOC>BLФБOѓn]ж…ЩйФ“Žэu”ЊŠ ”XPQYKI„&g#rГЖbэЖ}”n˜‘>r4ЂНœ$4&šFькИ kЖТвд€zs0ІL‹`2;ЩJ7’жђ&ФЪ N>>>(..жЪг])ˆAРК,Ј  P( “^­OOOM?Ciљa1H‰і[ЎлљH§а[њЉОЋW/ЧЂХKАjѕFИЙ{Р^S†UЫ—Р'І›Š№гъ hpуy@”rШђM я7јDcЪŒщˆТ^Ќч ЫMfо—8лIЯШƒЄk8#Яђ-gкШЇ;Ы8Цѓъ[! P(Ї‡,11ЄЧ,CJвBJ4f м YП„™пт$_ЎПнHJ„}™М#0nмФ…zЃ0w#О^SХ%Jcъp6дТ/2ƒCcHJœ0SыUг+сЁ… I§В„0ЌЎmdм$F$ВLdЄ#щŠ30љзђm|)бБR …€B@!а‡LLк‹ьhј ‘-ГBN щƒЄг–Д—Жэr–šjЌюžмfЬS‘­&””еТ' QБЁ(wИ#>)v“f“еUды q'ЃйЙqЖ{UbMf1RЇ†•;uьNJnš‰P{щКњ„DќЄ Ђo"yRN! P( ƒ8dbвbppr=ѓ‘A]t1d)GvГˆђЈ8иЛ›О&с№єС№1№зєCœ№ˆЦЬБў№є РШгNЧК [Бys9"ћ&#”К,ЃЦ„Џ'wТhК&ѕШн—ЄёS‘ж'’Л–Їю–DЪ RЩЏ”AЪr,ЖXw7*œB@! P(zНоŽ‰аХŽ‰(‹ˆˆhYщњо+EЂDыЄ2ЌwрX,&Mza’пfT#-УvЛƒK9VXM XОdlaУ0%=š;sЉєЪm:неzmЮœ)Уў§ћЕ2$%%iЦсд’NїjO…R( S C–˜+˜dїѕѕEdd$Жn§џію`ЕAŽуxZm;ёаR<ј;ьОї†Ёчі/›ѓ—.рnQ0DћFнъš?-фGŒёУŽ>”eiG-|GMTЋF.‡у_йšѓa†‰Ј'=cїu)pпя†П%іи~2Џoяц'y1пC˜бМ’cЂу§7ЕЉг7ЗлЭДmkъК6Y–1љеŸ#@žL њ`ЂЯCМю5Ѓ Ђ^Ѓ' *EQиб=ПФЖз§iњЮ|}N{}еЉ@Ѕ…с4RЂ}…’ЫхbпЫЕђš €lA`СФA+œh|­ЂћЧhYќЅBЩЃM’Че>ЎпG…­кzН^Эљ|ЖћЫжъ[Ч!€ ЏРЊ‚‰:vuіUUй@Ђг$Бn &n’Ўъ&”ФњIQ €@LЋ &‚wђъјcоЦЕЦ\'Е!€ ‹@м={,Jд €A&A˜i@|&>Jƒ €Af7™г=Љ–F@@`гГ'ПjтЉжча’ё„“MGxs €Hч„ ] ›чЙщКюпU2СЊІ!@иЄРnИЭДeM§ИЛўnR†7… €СвІif7ъЪьр@@‘@zПпGПNлshZ  €Я$№ |Рџн:ƒIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/tip09.html0000644000175000017500000000043611733011756022155 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Firewall Builder GUI has built-in Revision Control System that helps you keep track of the changes in objects and rules. Read more about it here.

fwbuilder-5.1.0.3599/src/res/help/en_US/ipcoposAdvancedDialog.html0000644000175000017500000001231411733011756025430 0ustar sylvestresylvestre

Linux 2.4/2.6 kernel settings

All of these parameters are controlled either with sysctl command line tool or via /proc file system. See file ip-sysctl.txt for description of these parameters, and more. The file can be found online for example here

IPv6 related kernel settings are documented here:


Tab Options

IPv4 Packet Forwarding

Enable IPv4 forwarding between all interfaces

IPv6 Packet Forwarding

Enable IPv6 forwarding between all interfaces

Kernel anti-spoofing protection

/proc/sys/net/ipv4/conf/all/rp_filter

  • 1 - do source validation by reversed path, as specified in RFC1812 Recommended option for single homed hosts and stub network routers. Could cause troubles for complicated (not loop free) networks running a slow unreliable protocol (sort of RIP), or using static routes.
  • 0 - No source validation.

Ignore broadcast pings

/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

If set to true, then the kernel will ignore ICMP echo requests sent to broadcast/multicast addresses.

Accept source route

Accept packets with SRR option.

Accept ICMP redirects

Accept ICMP Redirects.

Ignore bogus ICMP errors

/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

Some routers violate RFC 1122 by sending bogus responses to broadcast frames. Such violations are normally logged via a kernel warning. If this is set to TRUE, the kernel will not give such warnings, which will avoid log file clutter.

Allow dynamic addresses

/proc/sys/net/ipv4/ip_dynaddr

If set, enables support for dynamic addresses.

Log martians

Log and drop "Martian" packets. A "Martian" packet is one for which the host does not have a route back to the source IP address (it apparently dropped in from Mars).


Tab TCP

TCP FIN timeout

/proc/sys/net/ipv4/tcp_fin_timeout

Time to hold socket in state FIN-WAIT-2, if it was closed by our side. Peer can be broken and never close its side, or even died unexpectedly. Default value is 60sec. Usual value used in 2.2 was 180 seconds, you may restore it, but remember that if your machine is even underloaded WEB server, you risk to overflow memory with kilotons of dead sockets, FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1, because they eat maximum 1.5K of memory, but they tend to live longer.

TCP keepalive time

/proc/sys/net/ipv4/tcp_keepalive_intvl

How often TCP sends out keepalive messages when keepalive is enabled. Default: 2hours.

TCP window scaling

/proc/sys/net/ipv4/tcp_window_scaling

Enable window scaling as defined in RFC1323.

TCP sack

/proc/sys/net/ipv4/tcp_sack

Enable select acknowledgments (SACKS).

TCP fack

/proc/sys/net/ipv4/tcp_fack

Enable FACK congestion avoidance and fast retransmission. The value is not used, if tcp_sack is not enabled.

TCP ECN

/proc/sys/net/ipv4/tcp_ecn

Enable Explicit Congestion Notification in TCP.

TCP SYN cookies

/proc/sys/net/ipv4/tcp_syncookies

Only valid when the kernel was compiled with CONFIG_SYNCOOKIES Send out syncookies when the syn backlog queue of a socket overflows. This is to prevent against the common 'syn flood attack' Default: FALSE

Note, that syncookies is fallback facility. It MUST NOT be used to help highly loaded servers to stand against legal connection rate. If you see synflood warnings in your logs, but investigation shows that they occur because of overload with legal connections, you should tune another parameters until this warning disappear. See: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.

syncookies seriously violate TCP protocol, do not allow to use TCP extensions, can result in serious degradation of some services (f.e. SMTP relaying), visible not by you, but your clients and relays, contacting you. While you see synflood warnings in logs not being really flooded, your server is seriously misconfigured.

TCP timestamps

/proc/sys/net/ipv4/tcp_timestamps

Enable timestamps as defined in RFC1323.


Tab Path

In this tab you can set path to the system command line tools used by generated iptables script. Use these if tools you expect to use are located in non-standard directories (such as "/usr/local/bin", "/use/local/sbin" etc.) Leave these blank if tools you expect to use are in standard system directories. fwbuilder-5.1.0.3599/src/res/help/en_US/ipfw_Classify.html0000644000175000017500000000037411733011756024013 0ustar sylvestresylvestre

Rule Action "Classify"

This action allows the firewall to define QoS class for the packet that matches the rule. Compiler for ipfw uses pipe, queue or divert depending on how the action is configured by the administrator in the GUI.

fwbuilder-5.1.0.3599/src/res/help/en_US/pf_Tag.html0000644000175000017500000000044011733011756022403 0ustar sylvestresylvestre

Rule Action "Tag"

This action associates internal tag with the packet. For PF this action is translates into the 'tag' clause. To use this action create TagService object with tag string you want to use, then drag and drop it into the well in the action dialog.

fwbuilder-5.1.0.3599/src/res/help/en_US/pix-failover-groups-mapping.png0000644000175000017500000032526411733011756026414 0ustar sylvestresylvestre‰PNG  IHDRDъхQYРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ IDATxь] @Tењџ 3УАƒ( !ИєDCEŸ;š)Y‘ Y.jJYšf.НЄ^Z&йsyiiЉМDЫФЫДП)Іiю)TЈИ†Š‚‚В 3џям™;3р€Ь€ Ю9:sя=ЫwЮ§ sцЛп*)Ї^8ŽG€#Рри0v6|яќж9ŽG€#Ррp†ˆџ!p8ŽG€#`ѓp†Шцџ8ŽG€#Ррp†ˆџ p8ŽG€#`ѓp†Шцџ8ŽG€#Ррp†ˆџ p8ŽG€#`ѓp†Шцџ8ŽG€#Ррp†ˆџ p8ŽG€#`ѓp†Шцџ8ŽG€#Ррp†ˆџ p8ŽG€#`ѓШlG€#p_рйƒю+ќ|rŽ@ƒF@"‘дйњ9CTgPrBŽ@MЈЬБkБN<2ZІч5ЅЭћq8ц˜;;‚‹эbЛxДію9Cd-r|G€#`1І ;gЏВВ2ŽxыYЅi‹'у8 ‘ b7%žW>В6k#Ю1єxсpю:"s#2<Œb/v-ž‹зbёxзЧ'рpъ-ŒС_"ФЎЅRЉРБ:ЖWА:гvKoˆ3D–"Цћs8V# 28ŒёбjЕ#”››‹џ§яИuы–АЉ‰}ФЃе“ёŽРctX™"ёшцц†шшhxzz˜#ЖЗ0ІHc œ!В-о—#РА ЦмАТŽ"3ЄбhІhхЪ•xяНїЌЂЫq8ЖлO&NœЙ\.0ELj$ю3ЂДЈІq†ЈІHё~Ž@­%>L2Ԙ!іRЋеИyѓІ@ЗOŸ>шлЗo­црƒ9л@`їюнјх—_„§ЃДДєЖ›fŒ‘Ѕ…3D–"Цћs8V!РžфФc†и&VRR"0FŒ`ЛОm1є§!VбnШƒ”W2qMэŽЗ†||э{†@{tРћяП/0DьЁJЅR s‹Њ4v4Е+ЊщТ8CTSЄx?ŽGРjD•™ЉКLмШиб–‹“osи2ќо9Е@€=\1†ˆ1AІFжlЏс*ГZЫ‡r8wQЏЯTfŒ b"Ж‘й:Ctїч”9>lџ`’fЦќШd2сШ#Ў2{№?{~‡‡€h;dЊ.Ufї“!J]А6m\U '…JniQъb‡2M9š„И58Ќљ‚9Ж†€(!bFеьœ1EьЁ‹1DlЯБ„1тЙЬlэЏ‡п/Gр>"Р6(Ц ‰†еьщŽпrњЋup*,ES™.$nwtЅ˜&Z_ЁйПМwK*ЩEц™Ldeыь ,™XU`љKшѓОњŽ€јpХŽl/a{ +Ђšо’ѕs†ШДx_ŽGРjDI‘Иi‰j3Ж‘UUЪДdˆ}‡WUcяTЏKаЉЉ#ќнэся,G3… ЪТ2ј9’ћЎЖъТТ;‘Ј“іЂу[08№iLљтTшeл‡ѕёџХЄ~ЁxВчфзhяФx0`ћ лKи>Т^Ђ$кšЛхFеж ЦЧp8V!И"Жa™2Eт]e‚ЌўшкcP+Ћf˜<2ЌcхЁ5К.е–уаU%ьH:фloіtШТ%•–•ЃQ^1ЮM| *{'”:ЛФ”9З{b’М{ќ^!СŽDєuQ­ћрЫсаЂф”јѕƒиŽ68œR П9ј&^иx—Ж—Tf†Ќ‘1€И„ш§3с7ЦЈ_0G”БsгMЬмJ™‘d‹ю-Ь5ъZіВо?Ћ—<Ѕp#ћЁь"5В еp”Ip‹˜Ÿ"y9.;‹ПІAѓыaЈїХЕ псвІ8њъќ_Џ~†5мёЄф<–EМ‚™яlУЁЄх–tDˆфЌйž) еоИˆŸ>_пўИAз*ьxg2Ц„ХЊэYB{жіDJ&cїYІsBдцНX‘єžфлЗ€Гmи^">`БЃИЧˆGKас ‘%hёОŽ@­7ЉЪЬQUDНZ5{3ѓёyš6†‡Џ{UCяX/Ѕl­мhэЉ€'ЉЫZ’ъlаУЎимН<анЧ PZЂdGb˜ђыJ”хiрJŒšTyGђЦъќЕх(ЖЮ‰qQ;№фШ.Dї0ц…?нWшщЖ8IпяЦŸ—KhŒ=^ь‹УЛ`Ix<і‘zlQјbh^ŒЖRiГОМp8тУ;В"ю-ж УЅ­ж ЦЧp8V#И"VиБ&›WЫžј§ЛДгЇ”’ŠЫП›ПБТŠГ?Џ“Ћ.-E TЄ>Ы/•а“&рэ$ƒЏЃ фКKъДсх ƒŒЮSѓJp‰ьЪ4‚“fЭ‘жч€Сј"ћC„xO7{Џ~|{і_A—жяд> ѓR==ЏvJЦ}5яqb•LJнhыLђSŽ@УDРt?Я­НЮY‹ЧрдЪЛЎ\W1GwG4i†Ь#— ]} '{УЕ5'н}QNLжВ#ђw•[$С •W”j!;"ЦЖблЏЁ)1GŒA*!ЦщV ЉћXЃ…ЅЩ3ЁhCЬ+О­Н…уХs”ЖЄCФB&ŽGиє=H!.А§Ђ‘n$tчoŽ€Ф+г=ХємЬГU\ef^Щрд%тц$Eк•ЏХњЪGп>PИщd$ЮMœёPЛІ•ЛX|Э$DWЩnˆUћ’—Yg/G<Г%№€ѓКђfŽGрў!РЂћ‡=Ÿ™#РА №ie}Dm›€ˆп$G  РЂz№!№%p8ŸŽZUЃzkЕСZЈF§y'ŽGрю!РЂЛ‡-ЇЬри ŒJXНАFw=ъMpІЈFPёNЛŽ@2D5)rзяŠOРрд |‡ЋИ>Б…0nKЬ9ŒэtћV+ц^ВŠИƒ49щј!щzМв^З/Ч Š|GрСB ж_‹ЪLЛыФ#ƒЬєќС‚п G a#`Žщa™цYaп[Б]<6ьЛНЋ7Ц,к{Y WrЗwвнЖn1%јРё$A—OxОшMФNьъќзT™Пу§з6тыQФQ(ЇєE‘xcХ0$ЇFqcoы> >ъCРj†Ш”Сaчь%>ёˆGБžafкџУпGр@@d‚иЭˆч•Ќ3F …;—•‘gрh/!fC‚ujрІ;ФFжNюІС ŠR=aл&DЫpfїfŒ1hБ гžёЉzar9EЧі€˜жwpт{yqfЈjФx‹!`C$27"УУ іbзтЙx-і6†/П]Ž@НG€18тKd€иЕT*#VЧОПЌЮДНопи}^ршЄG„l‰>‡aоОеВ=вкR@]М›Тгз ЁУŸBиˆU8uХ{Г;~1&NOHў`>ІЬ|мЌŠ,џјn$ ЦЃ!”'ŽzgюJЦќЩГ‘ЂЄ=;u gН…ГЯ~„Иш@ в0гmž_‚О-j#цв‘уяњ„РэпвЎNdpи—ZЋе ŒPnn.ўїПџсEyлM5$ЭЛq8їЦшА"2EтбЭЭ ббб№єє40GьћЮ˜"qЬ=\fУЪD$ЊЬœы‚—ывКfэњMH;ЙыC8єNІЮm‡OnCGљY|<у.-@вВ>ЗсWr=~п%QаШck1И<КЬќ76l цьп=ф‡‚юРв˜эx…"&{Ъќў[ьALсЬаmxђŠ†€Х cpXaG‘вh4SДrхJМїо{ ~Ž€€ћŽOœ8rRЗ0‰{‰п}QZФЁ2РŠЁgШVH–yЉЬ˜э+КTwnэЛ+ \:щuьL9Š#(Cа›ѓ1ЌУUЬь–ƒgжOУ’њ€X˜wіФЂoяDќ9ПZ™™L"‘CFЖH‡WЏ„;^УЧE€вЋўЭ…окЁуQ0}*~=6Q!*ќ8b:ЏYЇыc†Џт4d,fˆиЭŠR&bЬ{ЉеjмМЩDЖ@Ї>аЅogсœПq8 УЛрш/G…яt)ewЏ\cФKѕŒй№ˆаy™еЕЪŒю=hžz;oЕCлV€’t0UZЯжюТМьMсЁЫ§&Џ– +BЮ‰ИD4КЭžHк*гл;!)щ$К_Уч№ЧЪ№}~ТxАŠ!bOт‹1ClУ,))#c†^{џе:Чiзрg Йž WZЕZSŽ›wъŒKељ\œ GР–XњўчCФtT*–ЋЂJЭдЎШ–qВцопаЂЖ*3Цј„†їGі&К7Еn5Y—‹bbXбЊuЬЌКZ3nМP§VŽ„ЩЛzЧ=‡OЂцbю‹ї :яХ GрAD@ч[kС‰*3Su™ИiВун,ЅЙ7 зjаиоЮє’))YтЩП Оqътb”@SR|7—Рisl іРУ"іаУЮ™TXT™йVм,ѓ2ћfјYa*ГЯj№+ЙнзYQыU=WDŽtУ†щп #GmоyЌŽY ЏОб‚щиЊ, „Œ…ыi 1wё!ф(‘•–†Œ+:њЭDœХж”RDŽ \6X%МЁ#`•„Hмйцؘ ЖYВMѓn3DNNŽао*ХеB5J4dм)!'Rе-і"ШШR/o_ќіžшЙicџhјђ9їіfв_&’ЩdТQД%КџЋЋп+0x™™Q™eж†1’Сль­;сЩЅЋpmдKъНRшбЄя,й)Ф'"ЙЙн3‹&БИ@жи^Иpы: ыж`иˆqи:Iз>+u?}щмЕžŸдG=ƒ~!еE:щђ#G a"`C$к™ЊЫD•йН`ˆм(І‡ТYŽBЕ%к2ДЇ/Г“Ќy7 ‘кA›› ‰F хЭм:љ4rьFЪёbДnкz[UЬ_m‰™ѕkYе-™З5@D 3ЊfчŒ)bBŒ)bћЗ%ЊњCmВј‚а8šоGVuVёqљ1ѓф\Гy/†“”‡>%8ЙUjЮэЃpЄ<Ъ0.0v!ЖЧŠ—RДўRŸ%эЏRGгН%ЇvЂѓƒO3q?r4Ќў9e›!cDУjі$ЩЮY)/#4bXXБ#FЅЎŠК\‚•y%Z8J%јЛPC pS]OЛ2„xисt>K§ъЂ\?˜ˆ9oСфŽ=ˆ!ЊOF™иБv'~лЖIЩ‡1љшФ№'ЖКјЈ9*xи‘}ПйїžінчХ<,7ЫQV“rЗђ˜)\u6D5YC…> 8™dmЙЛБ0­_=ЇETaПр<8XХ‰’"qƒеflгdхвБЫ8№е!8x8 dXGЋањiH4™“ˆžЄBхZЈЄr(‹ŠaO1S2 щФepІеgSфA’ЃІœКUFuз‘’[Іh*Ќн^'UЖъ>и эйŸ1ь‘Љ№ћb=З~SQfФ[KO`pуУКuYН">#P3иwœ}Пйw›НDщpЭFлnЏЛХшмDк?‹ф3#рu?fчsrюV‹oSФ6GSІH|z—пВ—ѕю™…gр)бр!’јКа#‹œV*Ё9™йЖлуqС7й5BŽФJm9ьшѕQw +Шж]XPTWвАjќdK: ЏШЩ?CYy|Щy,~6 “Ф6К^fzM§3w%afП(јЕчЩі<>%fш4ЕЇ,}‘§ц#Ѓ„з"#)cєsŽ•€ѓЬu„Šъфߘдс,^і3’пy…ш§ щдц‰д 0юЅСКŽќ#p—`пяЪЬ—нeаыy'Џц`n§МppЌ’1ЦG”Бsг SФЋI`cxјуaˆѕ5=:Rж6^ЮBњBHїш%œIMЦlfZFAур@љзŸ(Й– хЁп >Žs9Wс#-М‰y“CГsчЅašп(Šє „Эœ†AЅ8rкœЗ\ Ю&g %ьІЮ5U]‚ПLЏ)стќўsˆЮ`|Мs&œ2Žр<“,9xрovFP@W яК‡Ќ- 04*AуІaqŸBLБhFв'Wй›>џ0Rb™$(Aa­!QІ’s UёТИ+˜>є0цHќо‹ЧЛ2i'њщЈUнСƒ$MВшЦygŽ@=CР*†ˆнƒИ!VfŽX›1.ўнќйЉеEEvHћ.W„Є+"Џ2Ц_4‘–уZм œЃDЅ gОsћі(Ш+†KPМ^‡<њЯ›‘ќ­Р uљ`9Э Ц=YХhA+OІDhФ TИ&ЉP—"ИЂяјqшЋЇ3pќS˜A ‘_xF*3%жЏLZ‡Œ€^эJ0!l)–$ІрмвЧ)є™ОDМ‰Ÿ’ЂсcѕЇ$тGŽ€uˆ<ьШŠј}ЗŽšэŒJXНАF7[S[Ѓу8Z!PЋŸZЦБТŽІЅЛŸ;NЕ3МщючŒ2 ОXJЦйЧЎ)б”ЌЇ5Ф$Љэх(ОqЗJЪаФ‰в;№MŠOЄЙ•х•+Ш=tЁЋП†Gыж5F/mЙЧšѕЇ^:KЉJаЙaТЂHDOJТьўQ˜M§&$oТјg " ]1†=б™зmцщ[lA%(^†…їрЬ?оLПутљ}YHœєфkКєU-НЭвЬЊšx=G€#pАи†ЈђІШЎ+зЙx™ЦКАюЎўИЎТхТRh‰>sTkнШ=}аНБњћ* ')дCф BZЙЧфE‚1ЕWKJUШM§У‚IuжBю ‘iЉzЈhWФYЕ—/"ƒu%Џ6]ЁрfпХяЙпcёЂ‘Bе’ˆХ‚эШхfƒF–ъЧM?‚дђЃј]MЏђ/l@Med ФYиQdХьхF—Zгv~ЮЈKФ‡гяЙщy]Юѕ бjћљ%˜{еъ>I=џЄ˜­ЃЉі\™Ж§;Ќ­hџXŽ’DНГO0?цЅ“ЈNД™Ќ|џW­–Чs*тokз/n„тQXсКМоэ‰сЩ+бряќR(Шkьреb ФP€jИШ%($ZAЉСФ=тl‡sфL+9Щ+љŠ‹4sl9шYЊMСсщЃяНC:9"# ш;<ЄRo™NE–МЫтsqbњRСPZˆxЦz’ёєšOŽЂmTДю)z’5† žœђAu9З;њКЂы?бyl$M›„yуцЃб‚рœcџ—…юoGBчлVizКдфрм…›Иp1[h<єЮЫ}аДMsнкnТk8ЕB Тїк„’XЯŽfфЧ‹YT‡Ё<_‰ВТ"”хЂœ2–”сЪ…лѓУ™%`ЖRƒ”›ьєТЉHxzЦї3КiS+ШJйŠ)љЋ§м$œxЛB˜mДCоЛМ3д2(ф…иФќѕў6 ›ˆ§ЗъEbУлтx:VЉ2v`hЇxC‡Ф˜qДо.X—џ%кšJ– =ј G€#p?P„n7;}њЋЭЬжзДRT№ЏшПНѓчаїпSš‡mяn@—q#QО|-~и–‰сL'…ЇЏ~*gИ6‘ТЭЧ^^FЦЊІыр§8uЦе5(йбгT!I}ЪБы’ьаТХЎL$ADs9IƒЪ!ЃW1ё?(aтУЮŒ)Ђ@bЄ2 xŽI~jVМКF`QљSPц‘>JEweЁŒc?D*НФ:mПšOЂggŠK=&F‹MФ0b.ЉОо/PiК(вЋЁЕž\№%њ Fe Єb?Љcо@>IЗdŽU–‚Ђ Ѕ=Йз—“ЉRq NѕУ+еђKŽG О"Pzf8эcДЏ)q.1НЮ–Щ”яГv.Сљў“№nмјnAЪx]‘Мъф! bТО7PŒэ˜ѕёNМ><\ўS'~ХЈЗ б эпC•wчЮскCИq" Y9йЄ6Ђ”eЌ#‘Г7cєVH@$С†([UN*ЕrИЖm-оŸGbHн9ЕТЕК>$еЂБFFЈтєfЃЧцЦC|TŠ_qЮ~КЇТ0{"Б”/Я,? !Ы|;#vI‰{OТз/ьЧKюЬUУЈŠ;ёѕBДЗ!є€Ї№Ў/{O>ˆ6‚Ќх“ђzЫ)<<Р^n-рзПŸсcP“д(ї?‘ЛŠЯ_РЩ ч‘–“ƒ^ю\&†ШчЙЁhђь3†ўќ„#РрмЦІв’3МмьруAšѓF$N&g7 ьеyЕ^RЉR З^/уу‘kIхПўь iАž,Soœ›ƒLlFМгa2q< 4Ќљ: u­ѕмœGрAD о2DU-wqAгn]…Wх>+W˜\чў•ŽЋПў†+лЖУ‘b1•X1Ѕ^+wvE‹gSАЧчLzѓSŽG€#P;іMЉ^9U{ЛKц…JюџЄФXŒ}М >}пЭŒЉFL_ѓьKIjдхQ4ї^‰%sПEњЬа*lŽjwП|4G Ё#ар"k?ђЏ8œ= WВ9Rd™ђУЂ„’Т’гJo\ч ‘ЕРђqŽ€YКЯПAъ]рЭ$Dф ыC"?’бK^zгьЋ*НBёя5Яa№ˆ$иЙГиpљиѕюFД™їЂ†З3’р†_NРї)WбібЈкиЬЯ8ЖŽ€Э0DjВEzД‘ЎіRЊЫ  §lђ`ѓ$ц(Ÿв№Трpъ§SWKЮz ‘ оDйžyПъKѓс0ыЛŸ№е- Tgїa^š‹GVВЅєzŒдkјlХ!МўLDХP,'/GРfО,Ъu %uІT ,Oš'Ѕ9›Ї‚‚ŒАKд(јmdљA­еРNHoOICЪ‰qђl™Ћх>эЊМ Y&є3w%c’~n–ћ(™ж_Ёh2БŠ˜!Œœ‹9{Р‹WJI]чщлЁЯаЕРzГyў…5лїa1ЃEy—ђ‰ˆіJ–px…кЯHŸO˜ƒ™ ЦыЕѓ1fђ/N*vO§цcї–$К7.ё iЦœM†Qќ„#Ррp8е#`3Ђx;Ђ%B;{“ь[(GZkт‚rH*Є$OГ„@ьP)f'ўїТ 2В>†НУєьЖo…БЛ ЋGбЄеыБОЄ ZЗкvЧШ/–#v|ЈюЬ)0ГЧbжђЎјќЙљ7S@s-шї:’ЕC^Ъ2DЧ|‰AУClІ/Ы•6ЏХh\œGв—mојadЯєЧя z! Kpm…о Ф[1/"ѕЗi˜;g(Н(њvЋжhЉXАю4zLkOнѓё“I­6fЕА>ѕЕЬю‚.ЬEТЖlGУT(%QM—y+БbZ]+1+8л^&†ШЧVЧSнkјјЃxБIќ›ГїŠ…ЄlЌxzTb”4JJMB‘Ф)• 3-gѓ„}ё тЦыlВ”Фl%!‰Ћ‡#йЎGŽСЧK1ƒ"ќŽъAєЊ\ШОЫPˆЏВПD([X?L_Б›~ЛФ">ќф^#№b†V›и№UГ€—GН‰ЉЋcЊщС›8{…€ЭЈЬЎ“T(OU†€(—^[.aЫХb|wƒ$FTпHќqўO$­MAЪbЧšПp1=ДђХЅЋз,ћ<"fѕzќДч]br’0rи&b1@^W:I“Юœ›Ёœ4,юз9vХшgт4\ ѓTю ЙГа6ЋS8њzРЋгЩl9ий„10 Ѕ'„RžДпГПСи0`AјЪк>§,Е%т@Z>в7,"ўЮО:ИвФO„w&–ЦтIrNаy„'yшUSєy”ЮŸПUЁ“2u3zzОŒ?‰)b…Экн_wСох,н€єќKб6œ}ОH№Rc]*#FКzИ:ˆ=dАЇuЛ;й%Б…9ї J7m(Я)Р^Uђe­Њ‰зs8ї›aˆь[Ђ”lz(xŠhЧbлiа@3A|эр‹Q1§0|єф]+Р€№ъШnаЭeфЎoMёщ‰OVб{Ъ\c>шŠ ?М2 _љ§ЛЫ#щЉЄˆa’9ƒ НЁ.Ђы@$фЇЏњзъJБD*Ž€дЋ-&~9—j3№ч9ЭјvС,КЬž4ГІg`Т[Н+w—Њo[$UР+ч Ћ`Pє“Кz &.ќ Є4щm 1EІѓЈѕіY†ћ&лЎc)@cˆБ6ЇU,•%+*\>ЩкtWКwJŒkrM WE–ЬЄŸrю!CxўЅH<5j Н@{•„„x{{C"б1BфвaљŠШqтI'ƒэaGВI\Lі‡•Ќњ,ЇkfDaкZt”PВщš[ ˜ЁТЋ8 ›aˆžиИіт™=ЛаcйR<ќв(HўбЙЄ*c[SбBЈђеа–J}?ЪdPгSF6ШeЬ †%k{2’wešˆВочЧюЭєˆІь—]Aвд ИH1zДєЉрdO kѓphёrU?Œ?ўb•T*єЅnэКmRЂg$!3O e^2в2[н§;йфќ˜А™lRWЅю=*45gђ'єC кV’FEт‰VogЃc,§&­{!ц.>DБ”ШJKCЦЃqЖnfМИб^ˆqd}>Gзž›Ѓc*%тж/–VаžСӘПxђ5Zфћ?,[NšГзК a-nвЏdaїьз1‘i"(‚‘uKС7hŽЭкѕfЇУТќ єљ Gр^#Р6U&ziьpјyљтpоA<сЦ EGG#;;›інžЂc‹,]Ё7ш1nТЖMи}љ{,љЂ+О"ѕќІЪŽ–’Ѕў‚wыГл ћŠK@Vюќў)ЌDљŽ@AРf"ёѓrЁ§Г:М=a_ЏФдvРN&ƒ–т]ЬЬCњчщщ И–[€ф.ž{KkиМDеKЎТЌўQшщж]<‡`СљH$$~м[>ё"ШŠУМЛуыƒє|—х3бп- ЫЮ7УX&НщєвIНTБ/1IŒmж™%Мœ\ї=ЛЃ›ч tаŒG•?ХLР`šу19vЧ$arђ&єаЋЦМњ>Nk`іB0б,1ХUхтЇ^ыжuж­ƒ­“ЦЁЏ[w …у7DХŸq”з 7Аuл4Иг#МЛ OАћ/Ѕ­…ќqЌчmѓЭе'GIŠ5}zЪ;ЁЇ™$УёЉ‘:;%џАчHэH˜љ…cтЅ0Ьў  Q‘WPІ.'ŒиŸТ ЌZчкыžЦй|Мpю5LцssЃ _Й‡ђw@оX†ЌЄ\мм ТЊUЋ ‘]эЖ^Іvёn*xqі3˜О#Дi$Џљи?Ч Aš9ћgфшŸ T'З!2јП8Џї UЅ“Їf‡љфИ@–ƒzOиLђ„эЊї„U]=…Ÿ+ŒWbыМQY ДHЩcТм‹%`fбf‹х…#а0љIlЋНKKtvvBNv~йwЕthmmГЮbчсГIuv65™> њCќўТПPTЌ‚F#…Л—›СыJъŠEъƒP’HAб›ЅˆFjёѓфщІ€ЙЉCѓ<Цjшœ=ЙVьЫцvjеsЫbVЉЯY?3Ж Ф8Б9ђI’У4MЮорdђ)kЏ]ЩЌАxX;FR_(Zэ‰утYєку&бkЩЎgјH}n­U ЉЃЙє›t79m>h8V”Eю•|hЩј[Q!Ruхyt=CТiL?( ˆЩ’Гћ2тэд>Iъ>‚aЖfУСL­YбЉТ0їрДTчCEvVІcuНј;Gро" В:Љ9вАЇ‚^ž–#МФ‰Њ3ёКІGWЁ#q)’.Џи@пrx ёЮД8єNІЮm‡OnCGљY|<у.-@вВ>аЊ q.-LdKћŒV“пSOЁ˜ЎбyТЮ#OиOєžАъKW№ыюTк—t+г\;ZЕ7ъЕB@и‘kVтѓŽјПwcёѕюМXг›т§8ї*~жюѓЊюёє/ хЋ—Ё}P0:ЗщŽПьAzzў:ѕь$vвћ9‹VФтЙ1{%sE֘“ъ'0@ЌJFчІŸHхОТ0)œ‘ЮЈКBум(onгˆi)щуT2Ц~ЁўFІЃ:Rкˆ3ЌЕBCх ШЋrхЎ+сbк›pqЛэ^ЈmюЄЃ6s)K‘b:†Ÿsюezю‡ЉХ2ОЬAy%DІNc$V,аЦWИf67ЏSoЬгзЮ:š‚ўє/IЧšЙ9xf§4 ёЁVМГ'}{'тЯљ}№ˆОП\X#SищŒї„kGwЋsАбЖш’иЎXš_†ЮІоЈэ?3zЃЎ[‰ІДЗМ> ЉЁ§Л`oџ_ыљЧUлхI)ha@m‰дŸёаЦœшЈў,‘ЏФv`оdLJ”““ %“zХ MДž№rѓDyŸ1IQ„ѓЋV$иљљRриq”С~оя4џШŸƒЖzjY—I­ЎЗЅгъ=9еІЬœI‡(<+9=и™„ћаЏіPСKда“>?9n§–IЊlC„2у/ќn:ЇЁ/?сдOl’!bQdkRxNЂš Фћp8а1Ь›L,хeхPStБ(gВОFnB“(MћYtЄ|‹ЬхђЩХџARтXܘкп‘PфH7Ь›ў Т;GKйЌŽY ЏОSбB/IеWчљПВрRД"а/%G‡0уДфнZ”Њѓ„ ђЊ™Z8CN?ЋџЬž#G/З Ь˜”(а6ЊчŒг№3Ž@}DРц"Ц е4Š,ЫXЭ™ЂњјgЫзФЈПшsMš4y§њuсxюГkТб'Ъ[ПћIА#zyд$+nDoгQB№ar FЬDТПtЎQNЦЁо+…^MњŽС’‘Кˆіm{br_'Ь ЏŒšўХHŠЈй@yЗvA,yТ&bђ=xžx"S ѓеG3Œёд{Xxіƒ ыэёп%пcЅ{,&г)с)Ј ™2Œт'њ‡€Э1DтGp}’NчО%ZБn‡ЁЌЬŠ€i"q+ŽšьtќАёzŒэЋO„j>„#РИяшфC€ШБ1—{Б˜UKˆнАИ'щЧхЧ* ѓy†М@Ыпазy!fѓ^ 'OSђ %'oT™bRіbyЊ2GЦЫŒo$Ѕѓ„§ЭФ6 GЪЃєШK4uПБ3Y EэњеФ•’d?Х‘бBŸЬ-ѓ)<†7(K/Рэœ@ƒXv].R Qм{Y+Єp2й?,ž‰E‘uŒђŽщЦbфЂ7KрЋѓ S]њqЏnDтHbˆ(~cњЂH [1 ПЅFUŸ2УтђŽРнD`Ъъ0щ2+Œ9bVЬ–ШNњYчзCэ,'с[ЋЃЉѕю…kU*Џ;xЊšѕnНѓЕ)9t‹Љzf0ќ.ќ„”T "зЌGРƒу“rgx€Э2D+‡Њрh/!fC‚ujШMој9ŠOxЦKЮXYHTА gvoЦи€л0эц[ErvszљŽCB//Ю UЏцдglQе.ѕя…ŸвПAж•\—FрѕрGш[mФњќђЕй VШk ”FoPрХoH#NЂaЪоJ†^~Rtl,E ‹б…еšЛeбqФ(ВЁУŸLO]ИIЕUG­‚ЌЎЭќЛ^дr њќŠ&нма{жHЬ‹š‹ЙШ–hм"tр›M№сЇŠ”iяNУNjН%џј ‚*N^Х•rEEEUДšЉUelіЯOє2cъ-Qeцц`bPT)KЏ…(В& ‘Ћ?†ŽfLџ–"ШŽгG%UXиЛ†ВцЇP d4Й№._ˆЙ‹лсэ˜@uс, ‘бЂЭ$ЃэDlM!эйќЧL2™ЇЦk9ЖŠ“њ]{ jхэ"&жQМДњИyНn(љ=JfBžсœ4ж=НA­ВФ‚yВ–S.Гѕˆ і€JЭюЧžФ№dЎƒия:aуцpЛyЏкМWяk, vŒ„]с+1wИN‚Г}9bЇaщљƒшй,kDbт„$QЄэкЙДT€˜_p,BРњG!‹ІЉE/3ІКg*Г'ЩЫЌЇоЫЌvЋ­Eж@Ь O.н„Щ+(‚lW<ц9KСК њВB?Цž‰…ЮГИАœПы(Ќ[3['C_Зюў>єjmZ2HBfђLt•Da}šRшЭ"M_лџ3fHB/еј„tйRvМ3YЈя,™ŒiЂъN‰cџ…5лїaq‡Ўшпa-љШ*БuќdЌп›†фёQҘ1у“Х—'тД–H“9ї›•5YЄл€FжЃы2*5E‘[~мќ'ш@d› ым>Š"Э'c"5V$#Eлс‰іЙqPЊ)іЌЃ“aVзšгЛHаєХ TхH$Ф›FРЋUdŸЬЦ­KтПŽ&ссkЬolЉн™( Љ\ЫОŠќќ[XїэwРГb­eGІ§JпЉJ'h Щ)ф‘ №‘PЬˆyЫЛт“ƒбВ1—XЊLьŸ‚щЩ+1шфL‰љžКm]ЫШѓѕМ?ї)ЌЛќ ’>ТФрХxD§.ш—A}u/ц…oEфѓёI—ж‚ ЃцкQЬюM?˜‹„myˆŸƒэЃŸ@LWч*iљ…E`d№ь ž†&w€Ÿ<пЇУофоЕj9™Цщ JДmSU@IЫ0тН9–"`s  ˜&F‘НXw+ИZеdяА"œLHВоЙЛБ јъ9fhФ G€#p'Zі Ряп‘Ї‚‰9‘доўнќя4ДFэLMЖyЦ…ОЂЪL”БЪ-mЖ`ћЖŸPRBтІ FФM:mŒ]„эЫ!I;‹р5GъЈрfpnЮ]л *3%1DЌЬ>К$Aж#нњOКЪ’гX37Пш&5лЃg_’Н‡#щSаžЉќ2zањqулъњS+ЋыкЇШъ2пК…‡ž.рдЌ%:“r/ЗuІЁ3?см%lŽ!b8о-Fч.}Fе’uhџ,’ЯŒD€WЕнx#G€# GРбнЭ‰qШ<ЂчЈўса‡ЁpвЉЈы(Ц LP‚ŽšЉ”h#Vнj7 S™НšˆІŽTЇ|YaЂƒФ5ЈNЎRWєяwЄ1?ЦŽFŠAMzвыeэ^‘Idu§УлP'}ibДКЈš––ЄT4ЏJoЛхрvPфЌV'зVžOУb’^t7БЛчрGŽР=BР&Ђ{„э=™ЦЩЋ9g†ю в|’ п>Ш>UО ЮMœёPЛІuv{QЧ^AЏю=AIу+”R J%\%{Ё “ёЧ {„v•КeкщзЬюЈŒ1IŒЊь4BŒO6Š\П q‘•ю:ћЃRС`ЛТmР\cЂюDЫHХ Э#БЗФШœIЩшлžмCZјq†Шˆ?ЛзиCєщЈUaќ I“,Кqо™#№# •IбВg Єo;…–Н б'^­э-_\–s.Ђ˜ ‡эээсффggИ8гЫе2šзYс„ыWЎƒѕeЅ•Мj2ЌЖЄ0Ђыч/"ЧЭ%фХŒЌЁpAQъ\ЬQ"ШыЖ8ЎAxщMOLŠGяд8ќ3PмŒ‹а4 Bs Тw+П-’,хgeSЬЁ ИQђиnG`Fџси1є јecY№Дxs!ZV2 Ао—#P[lŽ!b€%Ќ^X#мjjkT#bМG€#PЏhDПњmСеЫдЛгњ%юнpHќzи$мКu‹˜ R‘„2н‹Ѕœ8ђѓ p§Ц ьнЎы?§й8 "SRъ/b…H˜Ž“ЩNшЅ'^ЄˆDБцˆЩі`ёDЬЫL,RЙНЩЕ}?љГ0“ŒЉУФ.˜•К_`ˆ˜Б2›fЎЮSС~FЊЃх„Юq/bvд$є§X/ЉпЫјjо_ћHWa^!бммхо№)№“ћ€M2D ш“ЏUэЂЭвš‰ЃяЧ‡ЦчфpъOЯК!dBхГ”E&Ww>U‘qЕZ­7мЙswR}"Ўќ(тЬі Х"ѕoP“АШUA FŽ˜xЏ*кDаu„qЄЬ  ОТ H•GЕЬсCмЃˆ1ЊXœPБŽЎw§J3шK5Д"пРяХc(YЕшЂ@шД…8“‡"š‘GЊAфЧћ‰€Э2D єЖŸ—™Х>§UЃЁ йеU QdЩ…žђ—­Y№И.8ѕWІ­EЗ‘pњФpйщ˜щі"2f.СКєOG”тc’у‹BBXsгt™ї yxˆ^цz№:ŽG !!№ї… `LQRI91šХjЯW3sTEKърdмћєуœМнVg†$Џтмlš!R Gy~Ъ(RlЫ QV ФСћСZќYYрєТЉHxzЦї3qџ"їxг’•В•ВгS™›„oї@гл;сНЫл0C-ƒB^ˆф№!X0xvNn ЙЄЪмъў‰жtMќœ#РИЗl<љнНЯЦр˜EРІ"Eш6Г дJBDE а’ў б;џC €fnš$!ђѓ НфЅ7ыnQ^ЁxM$H‚ю[“]dLDюѓQУMО„мА`љЪ…ЖЯˆFеuЗ N‰#РЈ[Ъ(ШтбЕЧ Ў&!Љƒ‡B†uЌѕФ›зыHˆЩbй•iТXv-цK+$ЏYЕJХЊjX˜gl9&l[Ј`Ј„t№$†'sэФ~з 7‡ыBˆШхибtИE…ЃaWјJЬЅ„ЖЌфl_ŽищEXJвіžЭrБf@$&N@вВ>†ИJІ жПи9і 8$П…SІ 5 ЅЁ O.Т0lм~|uкžВВёђ  `§ЃKGрадЦи5VoŸ—cС@9І…Ъ0"HŠўоvшнЌzщQѕЗ.{ІГЇьбbi>|fБXh$ХVн‡yЉРы#ƒФfнбы1RЏ‰+QщJEˆ[ЉŽ_r8ї;;;ДшоЂк5ДьЅћСЎЖг3дќу7рїъS`чŒ™!Ц§1џŽ~”Š%ЮkJЅ$uV[˜%‹ѕЄдžО^№ёїЁW#hг’…ЙЬф™ш*‰Тњ4нЮФ"__лџ3fHB,щˆј„tйRvМ3YЈя,™ŒiДщ EIIdџ…5лїaq‡Ўшпa-m‡Jl?ыїІ!y|”0fЬј$dB2™Ї•‘№ оJЬУжCаM2щ”&eќwxtбєlAъ+™"?ŸŒ‹фН{к@KП §СЇ_8žд ­У+6PшШ;бRј‡"*њqtщˆ2ю S П†}iГ S‰UїВњcЅ(ВsЫ#ЊНш|Я(5BдцуHн‰F­Т‘Jэ}}+ыЌIНЖšњlŽ0Иэ3•[дЎуX1>аъх№ŽРнCРЋUИ73Џ0iиО$~ЎуҘ ёХH_ЫОŠПџО€ЕkжZ=г~Ѕя?‚дƒЧplч!d\TТщ‘PЬHьЯH,9№I^tЖ2Ѕ6vbџЉhŸќЯŒocўƒгЬŠ[‹CяМ€їчЖФКЫ;А”vЯ ^ŒѓЬz€Šњъ^Ь Ÿ€›Џ}ˆOVѕ‚3еiЎХьоЃАЅйh$l›†УЫч`ћ ЦDUMЫ/,#ƒэё№ШwБќш0јЩГq*Ѕ˜’У‹V-‡‡qњТm—ЦN4G)K­bZ45ЇЅaIsyy 0Š1ЈлЊўfxŽВъёс­Ž@Эhй3Пw”ИЬPЄіv№яцoИЎЭ S“mžё_„Ј2%DЌrK›-иОэ'”АhзЯZ?гЦиE8бО’ДГ^ГqЄŽ iчршмЕ­ 2S^вбŸMyг"Bм  :LџIWYrkцц ѓ=а„$ф=ћ’ ш=IŸ‚€і”-П a_|ƒИёЂЉ€RЈытMљЩЪ…x@ЬaЕœЄGТQPеыЮЩ&[_glзе1u>%Z•RЈRќD{НКї%БЏPJ™ЫИŠ’В’На†Щју…=BЛJ]Š2 mˆt„Mйž SUИ(cЊ"Ц9H*дƒŸlЊ‰\П q‘:ЦФиAЇК* ЖЕьЬ\]MhЉИЁy„#іоb‘ЪЩŽ“З~2DфљRsZ.тtќј€ `“ бЇЃVABџh$С–HwХji3Ђv6eu4ёТрpЊG`сG*\Я6Бѕл]эJѕДXЋХC“JИИь Ю5Кˆb2ЖЗЗ‡““#œ](Ѕ3Н\]!“IсЌpТѕ+зЉ/cG€VђЈY8 Г!К~ў"rм‚ъХ*вмD!qЊŒNNžмЙQлh9ЙyEШЮЮDIj.._ЩCSW7ИЙVЖ ­с ѓnѕ›cˆўCЬPТъ…5њ^ѕ&ІЎŽЉQ_о‰#РА]Кt—cлfۘЊаjъc‡б№/ЯuB—зУ&сж­[ФЙˆ瘼H_ЪIЄ”Ÿ_€ы7n`яіCBэєgу,dˆdhL€+"^„iТЩd'єв/RDЂX ѓNФф{0Œx"цe&ЉмофZŠОŸ|ƒY˜‰‰СabЬJн/0DLX!suž‚WmuДœа9юEЬŽš„Оыу%ѕ{_Эћ cщ*Ь+Ф!šлУрrѓќId”п4xУ[= У&ж­qї$ щgшyZЪєЭшЏПП3ъЗдL,#}3?4(lŽ!")ЕЁШŸcђ 4Mk ЭєEgr#^8Ž@ѕtъ*УO[HUe~+Љ~АIk@ ^яG'уоѓY ЙkYPTd\­VWJžXнxђŒ+?Š8Г}BБH§(є‘YŠ()'ƒ&}QД‰ kSD_d^ˆX№}@Њ<ЊRИ:˜’(bŒ*ђЂ­PЧМjЅєЅZ‘oрїт1ф$Џ (гЌПЁгт@ I~hFO/7УМ‚ЗюцНFКдЛэФ/‘:Q?Яm‡ъhЕіУЩSxјmЃxEУGРhСж№яХЂ;ЕCЬK#№ТЈЇсњsрээMZ4нfTfъ6RSъ,ъ+Хц`ё9tЏ(,^f&ЖPMщUгЏ(m-Э‰Tю§Y JМ‰#pїpuЗCыGkЇ2 ‘aьы™!kVўї… ИvѕЊ5CЭ!•KOaЩн1FШЩ„2OИfЕUб’:а•Rn8y5‚WfЈfs˜ыU—ДЬбчuѕ›cˆи KI2єъиhјyљ`_оhQ Ц EGG“^8[А)b•ёЭ’ŽE}E}н„н—ПЧч_tХWБуАIдЬJ•ћВЈБСЯnЃЇ"]qCТЮй№ž*їцзŽРНD ДYђZYzі“cјdrыvгi7žќ[/l1­тчŽ@ А9†ˆIДЕЫБфЫU8”П%ИHY5дЪАjе*ABФ"ажІ0‹wSŠњк=Ц F#f№ЎШЧюxblєЄ™ГFŽо{Tur";ќчѕбUU'֘ѓ‘AзJ}дXPди.њЈБЊЋЇ0{r…ё ЖкЈЏРљ- ˆдЯЛxqfі#кЬп–ŽG Vфо(УхL-ѓбАИ ~ЮOG* ’i‹ X0рТ…rМІХ–dGй §4xqЙЇ,Ч‹O”aё;d]1к(Y@šwх4xjїЫпo_Мa{Љ=rЄрHс4ФDЎ111‚„ˆх(bETYz›:“CтR4y8ДbNo $І‹ОкЇпРЇGЗagъ n*њOјEаЗkеE8šŠНњ_ЋЮЦсдS(ІkЇ@]дXPдиЯѕQc5ХWА{7ѕз3Tъk)UD}ЅЌ!з""b!BзЌФЮ п ёс…иšrdР G€#`r=?qDŸ#>N‰ŸЗЊMэяHQJœУG+аћqfZ|oЪІUЎˆŽ РЗЋt;сs#§1цЕ–?Ё%ЦM|YyM1ѕu;ь§EПЉм›eёY8ѕ4Њж=§”•k‘іe4ЏУдRFъ4 IX1qцАшУbЮЉѓ:ѕЦ<§ЈYGS0РŸЂ’tŠОЪтtLУ€ЇУ3їМ†­Нёчќ>xDпп(xзm”ТЕƒ5&Qc‹.щzЧK)т}гЈЏф !D}эъŒcп’WD№Лx}xˆdФ—п`Wтє3ђG€#PSЎ$ш№oќ~Hb+Ны(ъ 3žnIљяeёmЊР#ўŽ9Б]CƒрЖ.PЉбдG‰у™Щьроѕa|БјzѕбI‘юхњј\ћ‰€Э1DЂч˜*Щјd7„b~03тƒ^?ьКl“.‘5л#™ QПТ04Š9В7=ІNыйкн@Vсс)œ‹LЁNŒЃtЕцЂЦšі/%уЅ~ІQ_‹­EШЁЬќАР щjmюЃСрGŽ€Х(•LЄСС_еШКdњe†S›UЃurї`єыxшЖ|†fhеu­K*•РNЏкЫЂtЧŽоФлям„пЃeИЉrСёk>(tc;R§bˆДДГж‘ЁЖ6;?lЪFї1}рUЗB')_Sй[Юњ?†њ~ПжпYнŽ5HuKЕPcоd^^^ТJ2:Чz |\0Мм<1цЅс=g=4‚ ‘Ÿ/#Ч ьgwšG™i*Н*,ыr‘!-E•eЅ‚“Ќž;ЪЯЩЅcЬЁуоЬF}%—T?xрo QІ+ЪŒП(ѕ!/Ž@U0UњйS|ГЊЮ(ТцoUе2C~лсйa DDU­{ШзІ9оfˆnєjЎ9Eх$зqlћЯЊq2W‚Ѕ_–у­ЩqфЌ;фђrhѓEзЊаБО>}Q$^Oюё5(šьˆџ/&uшŒ.n“№g56ЬЮRДЭУ’ {žщlЊKПуНиЯUяlT8џ&Кx†ЁПwo K@ІёйнєЛRё>ХcУЛп Зtп/ъ!o|З1б=1o2БЈЫДPЫ pЎ(d§^Oб^yэтЉй†т†'ЏФ†Фб6Е'/ыƒЁ#гПExЇqh)Л‚е1ЄЪ {-XЈXЁЦљПВрRДƒћ/Ѕš0}=(j,Rk5V?ъ–pT SЬk@џ9˜=[Ž^ю˜1)‘ZТ`N2ЅЪ›D /—Є&)Wњ>5ђrЋѕ:NБуБ.r„і”˜–Вc[r)J+ё-Ѕx)жŽŽzёЬ}@їРў[ј ž(SъЄ?YљZИЕєР_yАH{ЛrdюўKW1)инYЇяр8ФїђВнп дюcр˜и7IIћћ<ЊZW)эйX˜ОСdЊ"G™“;IХUи1jv…ЏФ\JX+Йœњzѓwчм­кГл№ЯG~Хѕ‡дџчl_ŽищEXzў z6ЫХš‘˜8!IєлQYcРТ\6ЄћН[8ж%]ыХ uЙŠ{HKT„5iвь%–уŸiqf5 w,Gђw? žhVХ!Ђ$ƒо"Qvl‚9Щc€х3‘АНO.н„Щ+0дЛ+ѓ‚%Ч`н†Hbhsmл“УˆaъŽСНїaњФ=™”–56 ‰5Ж;О>HCB1JЬ=—њ Q_Yєе1иАўM(S~РЪ] ,о6FV”Lщ)ђGРж`вЉЧ4XёпbЬ›ЅФџ}_Z%3Ф<Щ‚кJ7љЭuЦ3Я+ ЬУMA9ОXL!гвЁ“ cоИПЬАкёхЮєІпљнхИu!Г_П†ї_Й„yўЦъџ•Тн­*ІУєЎЊ:Wb+ѓxнuЋТК R›ШQk‘ЉїžЭ?О IЇ„№!љ“0Tђ ~LїГ|ђ–Т :т2<9>ŸxŒl=™ьнЄ1п†тЧ“JC%crќё"_/јјћР  Ÿр­Ф|ф]”`+fvъ„ШёлH’ЅТўјя№шЂ)шй‚lNщо#?ŸŒ‹Ыqšaз@юз№a4Р“Šпкx–.Yќš_П~н0TC.їbБ'[ЂвКo.iкХъš)ъымђуњћ<ѓE6}C_ч…˜ЭЧ1œєсZтљYР3CЁ/@ЬЎЃFyrЄ”‡ё2#ЦZ!ѕeQcVˆ›jˆKQ^O˜ЮЫЂОЏѕсgЃБ(2Z ˜Йe>НсzŸŒwЦЯ8їЌK:щcяl эйD‚Nнфшв]wъї–Ъу^ГвЋПЬЕоZЏеКDFBіCŽ.RH#Ђr8‘­аѕ5мЊаЫX9ЙцкQЬюŸ‚Ш/!aњM|ўoLnтu z фz*ўќО J>p?‰1#?УћСѓH’—Э‹ЗМVЯЄТЬ*bXo/h>ЎмВВ‚ТёŸЁ˜$w%pФ#џl ПАŒ о‚=Сг№бф№гKшJ‘‚‰ДЦщЩ+1шфL‰љžКmх0ЏХ+И8o1vnѓЦ#^Цф™КЕk•y8œ’ˆпSК`іЫммкЋйHIMD 9ЧLЎ1­Юxі‹!и{ЃФQžИ&PhВq*ЅіЯяTЋ–“щћaœО Dл р~]Х_Xу=4Є3›cˆІЌŽA4х(c…}t+DЖтf5мљMФPЛL.У[ЋЃЉЧн),њЊљBL%ЌВQcЋl­ВA{1]ZLEPФ`јпJ_`ђv[Г<Јc•˜ё†б@њЉФЎd†Ьн­ŒўбQ&0A­Ш#Lм'Ьѕ5­kбJ я‡$шкSŽž§ЬЩnM{пУsI9ф2#saWFŒееu)=ЇСШфm˜і ѓІf~Б/Чў†+ŸєЎ%9ЩвYqТ“юФ(Œьt ХЉG0счД­ЩЋCsФ,{[ "О•!ёгцтaR­eІЕЦџђч ­ZSи“S=;ф.Pш*Ъ”fSОЖˆ7hƒЮгвЕ§ѕ’шquіу-!Ѕп №G‘Иц"й<ѕаЏ™МˆЯ|†­tГJ}P№YD+ЪZ­ћДЁGю‹ъоmй>L Ыє‹дК…‡x;pjжЉWюџГw%pQUпџ "ŠЂ*И`bŠ… ц’тОThТпм~iІRšf–Kхnšўњ§LiюZЁ-j.iZšИЄ‰ TЈЈЈЈ(((ШАЬ ѓ?їНyГ13Ь Т яњqцНћю=яоѓ†їЮ;ї|ПGNзЉ ЬW;№*КёдDь:M&Ѓшi+Nў№kђwDК–…ќЂŒn@_sFйгІqОOКИщ‹ф :ЎФ_g•а$t7;m ЭМsB‰гЧЫ §(SЕ7cˆЭЅV 5КОШ#[йўKaF‘пЌВœŠ‹Гn)KMœ юdЌјx„=ю yFОŠкЮUни5 ћ’z ЂЅсЫљцј.хкD87“$#B%ћ&‚\ЌМ>k BŒl3цY2еЯT'в’,JРЫт˜ SuдpУQ ЪŠy(™Б`d€ Чmљ.гщІњ™ЊГe,ікжО^_ьPKЛяУЊ‰ŒKH,ЂD T Hяп]z€єаЗ\a*@К*Ьз–1&%Ње.ћш я1БЖЮ–ѓИ4rТ73ОCJІђ[Iи:ђ(ќц<яB61‡ƒ'уuў3І> ўTјЬИr2Гq+5ы™u5Y™šl‚флМЉй:Я‹!К“’ŽєkщHЛœ†Дk™| єнbфЄgЗOщмJВцmб—1{кVЄeгјГ3‘’˜ІЭ!Yb *,Щ’=уOžЋXœ8NВЙqIбnТP$N‚§—ЩP-HУЊр%x/и’Z˜/SEVќ1ŠЯдjЅД}mC;и ЂR.‚„8ŠŠu{)­ХУЂD T–X€єЎ 1z6­-РХd•YЖy нуeLџTFш/7&‘hМ•5 8ям15ЈjMcљGМwШк:›†—Ѓ&"аДэбЮo8FМ%SB5"ЊAR‹Ћb0ѓЉЋaс!„Д•ЂЧвЕˆФЏ˜>љwо)И‚uКQкЁu\pёлA=е}78“Јр.ў;t ŽЇ /ђfЄ`Bpє Єn“W0 `.цКЁЭЬСИ№йDtqŽFЂ†ЫˆѓЮhFффьТ{kи>cfІќЭW/@?/ПWŒŸЧVtXПŸІ{‰:mKВ|›cЦ0O,щі њЖўPf ќж.ъ‚ЩMТьі ~ю2Kvр!їUaО4‡;–`еM`•ћ‚эслжж­~мГІJZ|WЋ/??rЙЙЙЙx№рюнЛ‡uыжaЧŽˆž5яЬ~лцЇCШРДлЖlЬ™‡‹—R0uУ$[КYеV•IlЉ?=AlЉЪBШ•Ш\uЎrAЅ3ЏЊ ЇЄlЈ;ЁГј]сX1ћ+ЌœГŠD=z4МММрщщ ИЛЛC*•rџœJ4ЖіОёіЌhМ=;кІЙVD€ДMВѓЦЬ;фё|C8КJёрФyl9сЮy‹ЌЉГ~jrl юlŠХа ђ№RНІс˜ѕВЪЏЅЊ€лЅ&яOІЯBї$BќТѕ1УcКŸЉZѓВ sЩ0ЅshRИЮrђŠж^оеM№™’_ВЎrч[r<хYг­0{іlЬ™3Ї\юQТиь*†ЈXeёСэшTvЇVѓБЖПЪШ‘—GжЦсE(§в19kЌ%_фІХŒшэˆBєёFЧє{Wќ6cK†ЗІЦђЇ{~њf~-™q{ёеТѕиК3m—~‡u‚є†lY–*3 п,ј{Оиƒ‹‹§#Н)ŠEд€y 0ыrH›Mе:ђй&7LšЪ :hdSњО kыl™iQ’ЙrzаKЊ“1dKЯЧзжЩUІ—КШšѓ”‚јЕF„ЖyYR}ъM{™wMЧЊ=‘vЃrчЋF•к0ѓˆЋј9А ѓg6ЧCСр…fŠk W„ zоЬQыЋwlхнЕ§#W+pmЃсŒџ˜љ№a1ЮђЎeыЮ Ф=j8nяDзриRЩ /2xв6ЯGП[удŽ>єžB…мД "БЪdK%шБИ†‹ыv-‹+scП5ѕ!ОК‡~Ф–к“мЯФ–zv•)ЖTZк&{БMєxИюœH8УRš,Ѕ<еZ…cа˜=˜—тЂErJїD €ˆm %щ:iQ‡@уЦŽœWˆзХMюЫк:ыѕ'ХЫ—~ š3­e}?БЅЈЪе@йн-хуpџЯБqC'./тN,цН4ЛъН‰”šудъљи—РТЭЫтY\йА>AЬ™A№sflЉФ KUBalЉаАЅ u%Пз‡Qс˜W­“Ѕ4Іх7%ю>]аоМЎАдщžЏ<}вц~"2жœfФzQ–5`7KfТ0uЄЅ™4в|­“‹#ќлљ Mщ›-“э˜>‹“!,™ "VЙЋй.ьлћ+ ШЕвПьЇк§ƒЉb ‚7mЧLJ*R@›А nЩL~ƒ—oŠ-Бi!Ѕ_]йЕ‰-ЕFЧ.дxN'П†-)­й9с+ПУЬБBМŽœЋkЛh=жM ЁЖrЬ^Œ}q71ВХ7š‘е’БИmWŽ-%иRл’DŽ-•О­.ЪŠP('YVŸTlXU5 *vСŸ‡8IœAж2H‡RF60HWUyѓеx IDATни2nk‹ЖФЖЂtА;ƒШЭг ѕЩpH;­БhЌ B@*уу~tC/ћ3„8#h#?}!^ˆIќ ѓve—ЭzВ%ГЉ”лfhKС ФЫМ † pњlЉ|;с“E5э‰~БњР Љ,ёœ!ДНЁ‘ШъКіi&t'6нІyYЯŽРтЪБЅЂ[ъ)ѕКЖTнYŒЖЪS–‘hqїЩаХGЃиЅZu›‰wЛ!эЫёzƒєѓФ ]™Yу+Bћ 0uлЮі~ШL<Шх€щЖuДЂЕ*ƒБлEdЌŠєћ @‰+‹KƒVќrЊFЛ3ˆ˜к|[љ уb& s сюэŽgšз-7mFХЯBЇі}#ƒЄ1Шx!%\-VaлЖјыѕяЙs)ŠPlc ?XCГЧќШ|bFŽЋQ ЊЫ ЊШ-{13вЧш TЄаЌŸщ5UЧф—&K'‚БЅћЕБG |>ьhYиRm‘ХХђДh ;З$ЊБ:ЕўОdМ“mdВШ(6ї; ~мШXџБuLъФReйБЏsљЛЙ,%ФFSШиg1‹Бпи%2v*AqSЈлх=Ќп_2v!c/™AЦš“E ”Б}1yЕ.р1rхzLТeŠпURvi9IœаЈc’ї^ ЄЖ6ЁbiWрŸUj\Љy љФћртт™Ь юемQxUЊПŠ„Юы.•сю­Л`mYiтœ XmKaі{ЉзYН 4I“<§ъR:’xзˆНЕЉ7ѓйX(MСrаNˆZŒ—gтХ@)ВRЎAYЏ)ълc}РNQš,њл>E›s”MQ’ЧЖ›№ІuŒ§уаУ/ƒиRя-чйRi)nџЄ‰иэ6 ‹tцnŒc(OyŸѓŒ19™й~Еe4kЅЩЂБ)хШ"ЎŒŒЄ›,мМ•Кт[—…_F•=ЄP#Ž€Oe!9Е@c™Мu †ŒР '.ŸXѓ`'њлЄ ;+ŠŒнТOО”N iГu;ДUc`ШX…ЭШXЕYdl4!cв"c‰„аБН Ло=5+Rу(>“Б="1Б[-"cп%dьd“ШXKВъ Xˆ=ŸЕЂћАЉЛVЮ›шіЪt№5§[6ИHтŽ]kР. "ІБšєдoжЋ)<МЫЧsПэ,w!Ц‡Oфˆ$ЋЙW#VS2z˜Я^Sд§Я!БЛD2Пo?­џL(l2ˆ$мJекˆСX+ІяI” љ_=“Ÿe е‰СЄG0ˆГ‰tѓsт№їТОКќ{?цс#b^еСЗf$ч "Ж€hlІ™Њѓ“ВKlI– mfŒЂ&ЂуB _Ч–šŒЗˆ-•+Œ‡H`KЅŠћЉЇˆpўe-sы•oЇ`аDЖЈF%v"К r<цUѓВфЩ;а…\\IС@П&ои4‡ХЏ*ЉЫiyјэјm:uѓ-{Nƒt›щПž5ь ѓQBї26хРЅЧ„ŠrAЦ’1TџГwQ|-;Окжy:CˆA{[œ@aQ!nоМqyCЙ8…^m†у№Ђ—6/_ЋZ. cЩwцА'~~дŽБ03dьзнІрК‹л№&в2dь\ƒФr9И&ЮA– (C(ишO‘нП/юM};1лњу(ЁeхУо„KЬ\ЬXMСќЅ‘№с†aZŒ%Ф @ьаHlШљџˆч–ЎFЧІ@ШиЏ&с?A„Œ]кй(б+f-ыC”#Šp7#ƒˆ!c-Щ’"ЈЗn)ГaЇ04Хz\Єпx_г€ ўŒтgUа€нDLy^ў^хЎУ/c—к$Г‚Ћ3Зе…QЕЋЯaІЩЁXЊˆQя€‘q9I}Ђ:RлRк,‚і#Дћx#bЩєžKKyT+ѕiYKЃЮщкq[2жбўСsаОPZе0ђ]œЭЅaqeТЄВ'FšbK%Й;єфRы  k8„‰KВYЫ!4ч!&њ‰UUYЙФ'vјT&~ћѓ.]ЯГ<Е7S"$д“цє/7Ах“–ЯQ†ŒЭ8Ÿ7JЦь<.dЌр fРБ99№Уї?–Bя.<2V.ƒђЁMZ А Œ]Д: џ>б2–Й,џж„nБ˜JШиочЗс}BЦО2p5‚<Š ћ:f/|™Б!wыz™[†&ŠOаž4ŠлG Л‘+?ЧПл>Ы!c•wЮ26mч.$dl6Fє!dь›=12ЬнЌ,Л GˆШuСЄV2ічи|Иш`2VЉAЦ5уо<uщ}ГјIн 1w€CЦZ/+~Э\EДkЮ4(–ЊЎЛ6ˆьAЙзЏ^хgх5Z’’йјЗУ Ёђ*цd™b5-ЖTaмх)K)~л—ƒtТ…ф КƒcчюAЁ4zи з‡оw}ђpтїuHќ§Gtш]ЅŒ!a:Ж c‹)1"9sШ‹cє]Hћфђ-вћЎсв†Nql™lЧДџqЇ–Ьє—ЫЪ ћSєR$ДTУ!щ2!cв"cнƒmAЦfЂ2Vn€Œ-6Œ-F}dlЫ/ѕБІeёШX). c‹K cл/ЋlШXыdЅlў#ІžТд#Бd кп’Ў№ћП­з€h•ЂЋmчщ­K,ЂD ˜е@FV!'шЗ?3РЖ-•j2'„6—с…@Ш$)bтдЦ‹П–$ип1†ŒНQмзѓ ”с%§wІ—˜Иe”їБHЮ#:Њ’8“jш„Х_ФЦ/У0Cˆ3‚6ђЭѕНD?б’ЭЃ"cй’й‡V"c]hсПis~\…DœЉ_мhчsШXЪ8_Kuнє‘БЕuЫЄцei<;ШXI dьiZЮ\&dlщВ—MТА‰БјьL,њ†идЉЏ,qлю4 DvwIФ‰А Ащ“пУ™8G^!НPМƒgвЯ?ы‰ЎmkЂE#)yBђ5IЁK4­ВвюHKаХп€Yє@.Kyі9' уŠ˜?дГ:ЂтG[FЦRМаЖŸ2іwКТЧŒŒ-f№ fЙyEЌ@ГšBСšЊГы†Ѓ:уŒ!c™срЧbŠl) kYVцСеœ1єŸKgаЃБHm‹vэН­hU№b,В7oоФиЅШ,QULiwŠpђŸ\'євЄŸЉэŠ/жAїvоЈQЭ‰‹ХЫЯЯч–†ЊиДKn‡p)ŽfБRFFBЉ= Дxо CFЙТЩ‰—smU†еШXж–•Ц„ŒЕ B@Tъwз 26/бzdьПоѓТˆŒхќ…„ŒЕ(‹ uз‘OF+ ИіsAv– ›ћ)ˆ6j@4ˆlTиЃ6YdUƒbџŠж@ТЇ/Ј‘˜šƒ›™–Qb.ЮŽш№B-є$C(ИЉ'Фb‹”њ‰Š{EЏvGZF’рт?–ѕciаПguiы wЗЇѓЖвЁ‹s™ Ђv$шџКдdPyХ cЯX@ЦўЉ‡ŒТi54i CЦž.Œ]kK”!†…Ћu ћ‡2жД,гШи/, cъфв JGЦš‘х„ЯдёјЬp"тоЂЇѓЮUNЏљXлнуљGѓ‘—Ч\ыZTHŠš…‡†WЊAЄЪLТ7 ОЧž/ір"С`џHЂ Еq~ЉX6kљ~§V~‹…c[šЂЬФўџ~н›ж!6QУЄм+EVfм^|Еp=БдяЩвяАn‚Юєщ*ЖVs]OTЮuЭЮ*Ц™?•ИyoB_ЮGј …ёp— kЈ7zuЈ‹_їŠU“ž­ACG0VmЙо/uwFПзЌ{Аfк ЫшBЪ­ˆШиrSЅ(ШО5 Dхp}vlхѓЌ Щb™H§„Бl_Ш—ЦXd‹lb‘eНЭВˆpћ ба#ЦзэZЦW[…)‰TЉZЋp ГѓR\PЖT!~MЦP№ќžїѓа.h8šЧbl'SBяx6@ЏQ§ˆR.ГˆvрЅЫRвЋMєxbЉhDЪІRЙСt])ЁoE%Шў@Ќ-d]:ЏвHы–EєЧС^ZКsqA^№†ЋдйЄWCПЯ“О}ћ– Ч)GПK(ۘ^zєsAwњ_žх'[žъe=EаaŸЂI—чT™1фПpќЂG€m3Cˆ§g‹0ЏѕЩЧйі]ˆлЃ1v$„сЃSЎ№)J…Dmšl<>е­$Ќ>СЯsџЇoL1n‚дѓЁ_ŸJЃ&&ВEVTHоК‘šўСУwo,Р3ОRйЁHю|$sШЦ;IsЎIиOЉјBLГФ*Лiп1,kEуhЕьˆд?Q#КЃMH8х+б4О R0з!ПœggcХДlе­г˜C qЇє€7Е’5ыŽsБќ?ФРЫѕ3њј яиєъЩ–- ёЂWЌ‘ХXjћіn‡giШЦ%яќN Œи ў%ŸЭyЖЧІсМюGЭ;FЫzЩXЬt@њœ>я0Ї^Žщљq,Н6ШaЧ"ЪЕЁ?ŽШс›‘ІїТŸКkЃіZ.^•Є]ШтЏљfь\ЬЎпh$вѕ”_>†Й]y9СkЎ1?к[i*ьќБѓЇчaѓњBЄ$ ЦБVˆ9žьЃоaЎX8ЮSоh€ƒ)}ƒфщН}0>ЁЄГJЌњ"Kцч#юлЁ~Џ•П1TђЪж\НЊЦыс*ькЩ/ОоU‰С=žоKС=‹БlЙ#вoщаZ†НХ=QOЖ*ю5єЩжЃvvЬT“^У3jЁKjЊеї€kЫAyї BN\F#й9ЄЙјiл—КAЫ?Ÿњ 'ђќH|E9Э(2‘NЙ„ŒKANR jЋ•Йpъ /gPH Ў`eд Хўъp 1ГdЯјК1СŸ †1ОКЉˆ6œhїGi™fп"Ійгь=ZІйІYс„J#У„ЏwE§1a№$юf”™“]їі5:оAѕtA‰uъЉйќј…“}šx/ДZу2)Y$O„Еже+юФrLК§–.ХкˆTМ5g‚вЌІд,G№жШ/1`|g„ж4??ŽЅзj9фj,GŒОKБ1њ>–ї™…~Е§qvIфХoІмI_`о‰Ÿъќоm=пЗ=BеЁЬЭЦЉ/bp*т=Ќ=†zn…86{ЖњЭСЏЁШLJG5ђ?ЌРЉуJмJ3ГІ™ОŠbЌœ‹.сеЎўhбФ5jИСУущОeф=Tуф1ў<ЂРƒьВŒ†€Х Еыdшлд§ъпжі э…o6\УЋDŠџк0Šзs†„Pmj цўэ\>>бшдљщОжя*ˆ’эUт/ўЏ [&л1}'EX2›ВЧMфpЌчgП†pёt‚њ~.œЊWƒwŽc[Qю+‹ќŸ?Щц%ˆЭXœA}њЧŠрuсvшЃЄ‘Ф˜8ј Ь›+гnЂа+Ёўš bџІxЖ™"ZЦзdlZHyэѕ˜faР4ЫŽ}‡™c­ŒЙq­‘Ћ>фX`^v?BЊА"бћ5ц?ИA5l_‚{DYв&]0… Ё‘,|У,H‰hый<ЛхgL‰ЄЋPPmGЦрoB_…Кн,]wжШЁ„‘фDФА{1хUnгVТРш?qыпэpљлХ@№;h^п•Ќ4СKдbћ79ƒˆџMМƒпwŒрˆžЩ‹Ј'Mz 'mj7fq1CyuдPЂИѓK]IЧ§У?р~к(NMКК|оœѕ †Жvxм>ЭЙЄ…жvbэєb@\ƒ№ЩЮwШГ№zбУО%Aœ=!”Ј/‰РјJ͘f9ІYZ3fšegВƘ—Э|5ї)E н€=xcЭyˆШ‡cсйcњДDJWnВииœ[kшкѓКcъhHt]\№\+'6ћV1._04(œшЇЭ8†˜СTi…œZŒуHƒьGzN1тЯмЧ‡н‡пsХИ_X чюјрauf0ŽПвЦЌ9БyDЉэ#Se$cїі Део•x9ЬМ0;9J'xyWзцЏ4зжšz{ŸЏ5sЈˆ6vјSЈˆi—п9Ђтg•`‘u§nd.uQћѕо(Hљ wюCaѓЦь4ЎкЇ—uƒр№БИzG…@СГcЂ'Л ЯeО>KИщк– _ƒDХыˆY#Ч ]Я8D4гц7шЅ6ƒЖ"ЗьХЬHо;ЁkС{ЄLВЪrє 0]'н–%ййЭ(ct Rв ъЭЬ G?Иmц‹ЦЯ§ЈjYУВЩ22f:ГŒ3dѕіЕ§,ЭOуЭГJŽF ‹ГvvМ5EО)wd‘Ѓ ј„–C#-ъF—д7яЖ 8xЩ:ѓV4 rB›іЮhьD:Њ rЩHˆ;ЊФ‰Ѓ к& ТLq&›с…P кмоЧOяzQћ " Е§БO?ћ\хоrog)™GМPdьБrќВWГАb)WQ\Ыn5еPх˜Œоуњ<ъG2eГwн ьLŒв3оЭHе"JПЦбФА1g ‚=LЗ•'эDЛрY}К|‚эБ‘м‹žўBŠб›Нп !ƒШŒ<§іЗ]ˆ“‹Їт­Љ‡ИSr|JћG О‰ŸЭ“1пŠгЌ5gzzЃ"­бN)mўYЅЦ•Kз№лЏПуPьQœŒ;ПџN&”Ž *z›Wхм% *8фP, н`ЗЏBѕ “жъ­WЛЌy[є#)“'~‹ф[9ШЙ•ŠФЄЬ#уй3R›tš7О &”nˆЋ/HЧБ}ЩШRКЃIыч ћ’фдmЦјЪМ3M1ќ=`+1ЭJЂ1Ш‘ž”ŒДl oŠJ9В23‘‘qƒ<YИy‹оlr5эщfvlѓ~ ЂQX’]ѓ9Œ,šЛlf9ё;ё6вxцХЂ…ŸK‡0Сс-НрlЦ1”[Љщм\ВЎfв4СпЅШbилWVцЮKЧцž™Ѓ оVв›уў]Щк}юж|XšŸ5§ѕкАЂE3ОCJІr Јп2’ŒУЙЯг2˜BоЄ ;Ћ6'C^PШ§’/gыѕжп$NЃ]ЧрXв n-СєOexsМ‚C$Ђ1DjЛžЊТw А№c9ія)2k yеv ˜М >^шށC (ad Б+Df /оРtЁё(вseCl\'Ž?РКЃ…(–ѓЃщ9*ToTџdћТс_ИHvш:Vl(љ›a§ЫЃјі›‰Х;–n q'ЅН8Hgуьє*Ђ6X–М‡nюЧЏWї"цЧОd 14m8ІoNеЕ&kж‘Т ˜Q[YEuy/B шТнЄљQdю[шЉyX‘G/А{1k0aмa3ОКЊ5пЪвГ-чЕўЩl‹дЇ mќЖГ`џ/_ОŒѓ/рJ**џMБqP%?+yЮ!џк8=ќ3Ш˘љљsАј7mЌ;з@ЬH^Š№_`пKшш7Kc™Ёeрјkфe‰Ё6}0сF8цЭeб.,ЩЕ|ˆн}Ѓ‹[kt žŽЖг?G8DŒЏ3F 'ЂЃs4Ё’гь~Ь{я!Ч4лж­=zЦ‰ќлЂА4Ф‰д|Ш“w Kx{f еАЅœpLкp‘?Zpџњ!ŽЇВE KВЅшБb;оJ]Œn„мъиšbWˆ‡ш_a|IeўТidЫ5w ŸQ'œ–з‘мSx;ЈКtп­A{Y–Хvхл)4цXBv›{7ЏЩИРbmЈоˆУфˆ8 .У9K4 ‘Кз5цу!ђ–цЧЂЙє‹%9дŽlЛІHРР:эбŽъc"ІрзC9еУF`л–wАvш`Дs у~+№ПnAЏ–ў^…д-у0­wGмЛqFHПЁ‚Guб#Ф(тујп"9–џ;Ÿ‹2cиЬ oDЛтУй2Мднn2ѓњclг/ОфLm€бнР’ЕкEЁ;ОГ;}hюќnžЮxp5ѓЦпСьб7Аhмu|ћu<щЗ!Ч†ЊpC“ƒ4hк]8BФБ 84-oШ!hŒSwЎGяѓл№ўШџт•Ћф|‹FукЂeј}oьњ&MчЧЎ’’36gcлbо/Ћ\п*ђ2Ч&Ц іЅLВZVє_9?E'`ј’™hъ]Re.ФцУЅПnІ*…3yљOстU9‚ЊР|=ЬП$шfeП[ЂAєЎMођУpП} ъЕs“|ЙѓWдE*ќщв ГоСv›ЯыD† _cЖ+еkš;ъі№4Uœ\e%жиЭЕ5епж:ѓВЅЈюMO r)х)ЫЖ™ŸŸurœ˜1Ф ]—ъz дљJЭ'Б›Пж-СЎЏ?=_Т:Є{№мЋ@›‰мГjпФ gky/ѕ’Š ’ўћ,Ќ еЎу€іФє#5ЮъnљкЃ2wbЎж=ЌЕ*sУAMќQ:уТБ˜~TWоЅшŠв)9}х!ђЎ1ЄdюT‚їZ†Оk6рЏ˜( k}љ‰Ї1ю@,‚ЌyАъЃX5(ІXФХSЂЙсг’žХз9ѓФЁiЅИ  iЉ­€бwц"ˆВBеє Ё§ЪIс‘Н*Ьыоˆ^@%hкч9ФlКFмd:дыЂK_RІ{ў^%ПЭŸ|ЩŠВAжГ›б‹ё54mпAьяœ<@7‰ўй€М@њ”еk„6д*‹yЧЋР|ЕЏЂЂAє˜.\о3єњф[H~ЇФ#Pе @бkу,•aћгIEБЂ,h [œ>AАq g… њ­=_./#”—koŸŠ"5Ю\žБIЇп4oБ ѓgŸsт‚ЄYАЙЋxТЪџОvDBђuјvр №І7рк\ѓƒ(ЧЙВErcЄd‡”љmŒŠkCŒмв1Q[Qяе9бЭь[QЧ’Л|sr o`h34-ЭWMЫЙ œђђЫђ(gr/Q™бКїЭ> {YKТњеѓ3ќ›au-l”ЅМ^ь›нЎ5аœЮrђъ}:Ѓwnyj qІЇсљИƒєawѓVEПEƒш1_ИТЎЏьПaЕŽ IDATXD TВЊзpD—Ю8№‹юxєwyB\PЭš7ђJП­ЇЯКЧ/‹1"Х|С%`Bˆ+=Ё™'ˆy„jyлЖ,fBœ]WеЊЁFз™ЙТ——Тјј@aП<Пѕ‘’jтЏpч’ŒУЈgфЋ(оg~cз,ьKъˆ–†оl2OљNЮхgЄr1I‚1Ђ?$EљdБ>k BŒl3і32еЯT'в’,ЪѓТт˜ SuдpУбЧЮ‰B™Б`d€щзкэ2бжљZ;;mїdџѕ—ƒвw/о‡UY№ЎXD T} tъцТ% fRDЯУпv?О‡ЂpžŠќОt^‰ЏWцcёL9я7o еѕqФbŒўx;^‰”>ёЦЛI‰*DЕЫуў:Ш/ŸZ[gЫ5tiф„oє’[G…4.„›УС“ё‡:џS ŸJ)fЃРЂTХЊЫbˆюЄЄ#§Z:в.Ї!эZ&(}З9щ4­ёŒіВЗ7.cіД­„А%Єgv&RгИ pЃІЅюZ’%{ЦŸфr9rssёрСмЛwыж­УŽ;=k,о™§ЖЕb+Є]ШРЪtž!ѓpёR Іn˜TІў–:Љ(IшюŸž ЖTЪ}%WJ г рєчn‰yU•›ƒФR-q­Žъz8§ўтvљi@ЉTуѓ9rdпг§щЗxо УЧшЂ;VЬў +чЌЂQF ///xzzR.3ИЛЛC*%Д#§w"њхвbmЌНoМ=+oЯŽЖiЂw3ŠёчaNџЉ Іsѓ]w[B}1(|MЏЇї=y‡<žoG"ˆ}pт<ЖœpчМEжд™зЎё96w6ХbhyxДШWуvЛЏ"дf!CйšИ?™‰ŠМCФжюЦњ˜Žс1нЯT­yY…„ўeчаЂЌЗœxжђШ zІъЪЏ)”_]KДТьйГ1gЮœrЙG #ГЋЂbUщoЉŽNeП™5kћ› ќˆyy6Є0`\nQ\ў1AЩ,qiŒ †еТДØAlЉ1vЩ–:иRcљ)„П‡=П™fKe 2уітЋ…ыБug к.§ы&щІNЗ “‹ЭЩ"wљи0L^­kЙr=ІŽ Ёл–X—#uпRlZЋГ ў:ЇТk*дГР†ўИЦcЋ\f`]ј‡r‹Qє…Пy‚As2|ы9rAвЯЗ• ŸэџцфVењЯ6ЙaкаTnјA#›вїMX[gЫœ‹’”Ш•гƒ^B/9Fq8ЖШ)ЯЖІаД–хВЗ&tmЙ5GЭЫ’z”МлЩМk–@ўZs§6•;_§‘TmЛ1ˆŠ {fs<љž КжpEШ чMБ­jЧVо]+$ceНЙ\dzbXжzV>ЬCQ!яZж;la“–шшИН[\…\šWx=|кцљшїckœкб‡рsyЪ*—-•ˆХ5 ћlЧТ! Йy17і[SтЋЋqшр—…M=Щ§<Ў!ЮЎъЬЛnfЏ${БMєxИюœH8УRšЌzVcЯg­PŸ’šІюZAжў›шіЪt |Zby|hљ‚|ы;dМпГНcпгy‰пйЫ&Й _Эy‚X’е{™:я–Б4Fпт хsF@cёwЄЏŸЦ9Џ_w“ћВЖN_Žхm)^ОєP‡GkYn+5`?(ЛЛЅœчрHwБ€іЅ6ъФ?А-6*х 3†ќЮ_єАmf Ц3‚ўљќ<Ю.HРrwо;RTD FЭQзš9Ыwххз@Ы–ъу_*ЪГгoшV`'1E;DaK’{сйRЇCs0§зgKВБџЃI\}АУ$ьзВЙЪ‰Эѕclкw ЫZQПV›‰м˜е;ьб$ь$ІW&kди­Hз:LЫтY\)Ёыадg>32ЖдuhJlЉќщЭ…БЅЎјиRMЬйЇkєэнЯ†,M–AНCЩboHNhи)Œš)'[š 9уSŠћVi€-sѕРПЎ\TQь h+дйУїєblџОŸ~”‡ŸЗ™5†RЎ[gLŸ/УPJЂ*C•uѕœрнИ!хбЪКтyЫІЛ1ˆи№Нз†g=г.ЪкЕPУзГlГДа‹AТжьNЦm\П~›7mЖаЫђ!–Ю!љјi$ЦХ#žшыSЎЩ! ХМ1tdО:1ы nRЦ–њZУщВE§ClЉЙ4*œќ(“6Т”—gэRЪgМ Љšч•тЮ,ъ3їпљ7tтђ)юФbоKУБЋо›иИw N­ž} ,Ч—yY~сЬ†ѕ bЮ ‚Ÿ3cK%YЊ cKe)2[ЊљТИ>Œ ЧМjНЌј5kp‘ Іэ4|FвФнrж@“f4kaјањuWšїО”ѓЬŠcc`Цйšeљјя<9БJ+ЩSkКy}G zCЪхfыљ VН@U*"’Е*]-qЌOВьfЩLPrЃŽД4ѓc#{а'GјЗѓзю?Ъ[&л1}'BX2ŽЋ'ЪЌh иAФрлЪ3Q˜Swow<гМnЙщ%*~:Еяш$НˆAЦ хPЋАmлNќѕњїм9‹Д„`c ?XCГЧќШ|bFŽЋQ ЊЫ ЊШ-{13вЧш ПtUФl2UЧф—&K'…БЅћЕБGнУVЬЪФ–ZКЌЬƒЋ9cш?—ЮPn ё–ЈЛЗеНŸ —кBЅq =ШVУСНљc[ЛœюŒ"ЏAшјрЁоoЮјф мžМA-ž—дПьhБЧdѕ[ЧxшЅю— Щњ:!Yuї–ТaЃ)$ыГ˜EHжoь ЩJ$ƒћџћ=voњG_09іR'65PЮАKƒˆ%Зlд1Щ{/€R—Цsb­NўYЅЦ•šзOУ..Фи+sƒ{5wT#^•jФЏ"ЁѓКSЎБЛЗю‚ЕeЅ‰s.X`Е-…ХнKН†Ьъ5P@МMЌxње'"R:’xз(Ѓ{SoцГБP<šbј{Р„ЈХx)q&^ ”"+х”ѕšRВ…~F‡А§вd‘gщelЮQ6EuJкnТ;˜жm0іŒCП bK] МЗœgKЅЅИ§“&bЗл0,^а™[њcCyЪћœџ‹ЩЩЬі#Ј-ЃY+E–2К­ C]Хu$Чг‘ŒЗкЭƒ( гh"тюcгухщде™ђš1Ыœ/фЯСYњx.BЎ\…Їђq,IMаlњ›`&Š„ ёчл№ЫbОѕнXЎP$ы~B§ЃtK똭먭њ#ј?d†dUиŒdU›EВF’ѕ'-’е™HэЩк›ЌыЕHVЂ]†ТГzъ…cхpfЙЦ„єZwD Tœьв bгЏIO§fНšТУлєЭвVХo;Ыu>‘#’Ќц^Т”ш8M„Ђ&шБˆн%’Щј}|ћi§gBa“A$[ЉZ1kСє=‰2!џЋч`ђГŒС :1˜tтq6‘n~NЮЬ#ь;ЁЫПїc>"цU|kFтqЮ b ˆЦfšЉ:?)ЛФ–dЩаfЦ( j":.д№%qlЉЩx‹иRЙТxˆЖTЊИŸzŠч_жОŸ^љv Md‹jTb'Ђ› ‡žЇ<ѓЊYљ„Ѓc%У‚bИ-і1ѕЬq )Х`дЖ7ЪC{КрФQ"7ЬчЅЉе.hвцMкЙZт9—вфи}8'-Щe*0#Й†—G JDŠ,c|yЩšrр’Y‘х‚d%cЈўgяЂјZ*v|Е­ѓt†3‚іЖ8BŠПyѓЦх х^И6zЁюТ‹^ВМ|uЎeЙ€d%пQ˜Уz|œј5њQ;Цš|чј|нm ~ЁЛоА пaђˆ ЭCŸЮ%№F,—3kaтєhЩ€-„Zўй§ћтодїББ=Ё?ŽКU>ьMИФЬХŒеФ;6цЬ_ nІeёHVвAЬФФ†œ)Nа}ЧF@u^Oˆ™Z,ЂьAvk1хxљ{•ЛŽОŒ]j“ЬB ЎfЬмVFеЎ>‡™&;„bЉ"rzш02.'"ЉOTGj[J›Eа~„voD,Yƒоsi)jЅzыьQ чtэИ- ыhџр9h_P-Шjљ.ЮцвАИ2aR„NY‚#MБЅ’мzrЉuа„5HœР ТФ‡YAXHКЂxoБTВd2tяы‚нлtfv§ч" ОЛс‘FІPујЛи{ ЏхY”хъ|џ72AСNpt,?CHџЄ Щšq>n”Œйy\HVС$Œƒ!Ysrр‡я,3pƒљю8$Ћ\хC%<šД@`ЩКhuў}Ђ1$ы ітФЌБ˜JHжочЗс}BВО2p5%Х„d}ГОLHжЛuН|-CХ'hHOХэЃ„dнƒШ•ŸупmŸхЌЪ;gЩ‹Жs’5#њ’ѕЭžцnVdн…#СSА`R+јQњЁd™*ХoQ•ЄЛ6ˆ*I'ЇН~ѕ*83Ј}„Z’’йИС Ёђ*цd™b5-ЖTaмх)K)~—ЏX^ЏЃ`1DЌ89Й@U§Ѕ2$ыA~9z{џИьѓ/'5ŠspјчЯ1|Bo<ї|t™ЮgKЇЧŽdЅЗгўЧ IX2г_.+/$ыOбK‘а’тН’.’ѕ'-’е=и$k&кш!YхHжbHжbДбGВЖќRЩjZd•т‚€dЕхb‰mE T DƒЈeo;Ooqb5№h€ЅЖшгппoаўЛ6#єW.х2ГNџ\ЮСЎCщ8vіtЫбЦНky:Ђu š–я#ц›x˜}еИЩ#ячГu!§g^E‘ўЗ3 k6ЄЌшй4FЈдŽЈ^п їЈiљЊкSЮFr”•ш4 tТЫ)h),fqFаF~њ^ЂŸАў‘‘ЌlЩьC+‘Ќ.ДPпTУэeь‘aМфϘCВR†јHVЊыІd­­Cњ™—ХЌє[ЌМJФOQvЇб ВЛK"Hд@хi qћњUЦGФbД>žь†ІцЧTЄ(Цсг™œ!tЙ–ёр&юxщќы(hй(‡’B›7šЬŸбК#Ч)зйo?ы– {Йг.ћЏ)ЗиЗyO;к2D‚~Џ•n EХЖŒdЅxЁm?1$ы&–вћ<^$k1ƒ;‘WнRwbšnmT<’•;;їAЉљ1ЯœN)тVЅi@4ˆ*XѕŒ•іцЭ›Л”™Х"jРЮ4Р<}(ЅЧ†х: |к]g\КЉFkOУСffbпБLќzьrђ4˜}У&мžeяZН^єBjjШхrфцšooBD™ЊB;Hp`cо.SwƒNmлK№кiЉžЁkЋ2ЌFВВЖЌ4&$ЋmР ŽRПЛfЌy‰ж#Yџѕž>xD$+gr’еЂ,ђ,хЄ HV†T!'“ тдtІd]ЭDV-)—нЋ?D T‚DƒЈ‚•.ВвVАТХгйЌfЯIръr EОкОБчд тН9џ\ЩУ“ЗpњяАА*†њЯИсхЮ>d yУYТ–ЌШЯзРиД’п†GuGДЄ$Џ gЭјъH”l™Ќ4њЃлNr“БЩztп~j™ЌXGHжuzъЌm‰dMЩЪPfBqЂ„вК}†>§30§‘Ќ^Z$Ћ9Y„d9ѓЩкх3 _’ѓЬЈ3ˆТНykѕэ №І ыэ CР0nb5P Ђ2j=dр eъ9#drЪ…•Ж‰[їAйО7B| MRщE9НѕЫ=WіТоГ ”T‡—№ЕtIцYn-ЩЂБfчG-šxз$L=ћИЎ5мЯ"НаGkмЮ~ј]Žє{yИ™i~i‰VикТ Џ†ћр…f|њ5Q[(5|\­щ;;?’AдƒH+qЅ-ЅbЌg, YџдCВFсДšš4…!YO—@ВЎ5d%ŠУBSƒ:†d§УЩjZVI$k –Њу Х‹{Ђ*YЂAє љXЃ5y+dхЭG^^ž-KkЂBRд,<ќ3МR "UfОY№=і|Бщ яВОсЄbYиЌMфчнoхЗX8ЖЅi%hYnз!6QУЄмГ Ћ№ђa m2‘’Ш Ѕ-Ѕ YlG)C4зѕDх^WЉsnЅќПІНEсєysё8Фž%sBЯіuёђK>xІЖŽGлЙ’66qТ3~ŽИ}гіuГW"]аБЋmЦPYІЩЌŒоЃмJBВ–лœEAЂЪAЂATJмБ•Пi Щb™H§„Бl_Ш—ЦXi‹lbЅeНЭВˆpћJ!і#йэz ВЖ‰SЉRЕVс4fцЅИ l?ЈBќ2šŒЁр9ј=!юч ]аp4ХиN<›ЏсЈ–л~ФЩXnѕ‹eY7/Œџ} B_jDЙтr№ЫИpLЙЫjШщŸКМЖƒщКRBпЪ*ЬЃ“Oо!ЉŒ<<ŒИ”Й}Ь”_^щтƒЎД,&uyt6i3Ї)SuaёqJфхкf Бщ*Eлі†ПЌ2 ТŠN?‰HV+Д$65№ј5 УL>ўs=‘g`ЦџТ9№‹ЖЭ !іŸ=^ы“ГэЛWHcьHУGЇ\сS” ‰ZkЖF)Њ[IX5|4‚žчўOп˜RЂ[ъЦљаЏOЅьёЃ&&ВEVTHоК‘šўСУw-Р3ШRйЁHю|$3,/qGяџh’ц\“АŸX…љBЬЕФRЛiп1,kEуhЕ™Ь ЂpєEдˆюhNљJ4M…Џ‚ЬuˆФ/чљмkцdЋnЦДbЈžBqдWжЌ;6Ю ФђџЃЏ Kџ[ТГміъЩ–-Y*]])M–“oKtщЅiЄ&ZОHуNМGЉGxyчwb`ФN№><6чIиr4›†ѓК5я-ы%c1гщsњМУœјо–tgНfуQЊ §љsDпŒ4=BъЎкkЙxU’–1œПц›Бs1Л~Ѓ‘HзS~љцvхх;|ЌЙЦ:}щo1тиЁ"|>GŽŒнQЛ^“ЦCœЗkщ‰‚АќучбЇу3ve нI/Ція 0zvќP[VЈшg1є-з 3†єѕojћъU5^WaзNFЭJ –Л*1ИG1їRcpЯb,[юˆє[ЉgjLbЈ'U•їњ„j”y‚jвУkxF-tI @Ењpmљ/(я^AШ‰Ыh$;‡4?ыgOЫ?Ÿњ '2ўH|E9Э(2‘NЙ‰ŒK‘лЅ дV+s/рдA_Ю \СЪЈ$Ъўес\КЮ’y<ƒьVФ‚ŽAVElГсDу?JЫ\ћ1зю˜kяьб2зnд0з 'T&|Н+ъ ƒ'-Ї0ЃЬœьКЗЏбёЖЊ'ФСЃN= 5›ПЖжpЃаD(KЁMВвёЫ’XJЅж^šП‰Фa­uчQм‰х˜yћ-]JщXRёVд8tœI]6ЌІд,G№жШ/1`|g„ж4??Žѕзj9фj,G СKБ1њ>–ї™…~Е§qvIфХoFDФ˜wтg„:џ…w[ЧїmPЊ“ъPцfуд18ёж C=ЗB›=[§црзŒPd&ЅЃЖ ЇGцb?Ќ Œї ђ^ъцnnЋK›xћџ •кOє•JЅЦп *œ8ЂРх‹Мё`nќцъYцœсc]ёlsћЙ-nпрб^јfУ5МJ$іЏ ѓЇј:gH(С­š,гпЮхуƒёЗ=QNэgмцt,ж‹Аg ˆAxuи2йŽщГ8)Т’й”=.hъ$‡c=w8ћ5„‹ЇдїsсTНМsфлЪzЄќŸ?Щц%ˆЭиЈ>§cE№Кp;єQвHЂGЋf ‹7WІнDЁW8B§™BХП)ž­EІˆР [ŒM )ЏНs- ˜kйБя0slпПДOзњЙъCО•й§љТŠDя瘟реtА} ЮjYйивП–'Fbл}Дев&]0… Ё‘,|У,Hљ(ый<ЛхgL‰ЄЋPPmGЦряд„Кн,]wжШЉ)91lч^Lyе‡ЦД•‡00њOмњw;\ўv1ќšзwЅ17СKдbћ79ƒˆџMМƒпwŒрrœKs@žФža Аrй 2ˆ,_ЧJžŠxzQvЏНGнеnШ !.fh#ЏЮ€Jw~ В+щИјмЏSХЉ)PWї€Я›“ ^BСажЮ†{Р‡Ѓy€­дЎAјdч;фYјНшaпoщjЬžJTЦ KEA–љhі˜cЎЅ%1cцZkЇСк™—ЭFqŸRЄа нƒ Й1NГ’ХК[WˆфЎTYЪtЌjMЦоСЮœ1hЈmt–"6чж †iеY‘\сGЧ›s–цG3БA›w=щФƒяВѓѓ™@›‰+0аo7ібOћг _UА—н нVаRЉпŒhВˆx?ЎŒDў$OJж]ѓ™LИuёдЬФас§Аљp <диё ЅпэMЧф7,(N;КЧГ‘zI…?ЩЋ•t–ўжŠЭŸУЃКB;JаЎЃ3~јІ—Ю—4(Я3FНыПњіe qГЂKфDо ЖLЩJzN1тЯмЧ‡н‡пsХИ_X чюјрauf0•œзЉ’>Ь#@m*#ЛЗg §ЈЮ№ЖгЇVyЮзv ‰=ЪCvњг*ЉUŒŒЈјY%Xi]П™K]д~Н7 RўТƒћPиМ1; €ƒЋіщeнЙ|,ЎоQ!P№ь˜шЩ.фХBСѓD™ДЯЧЕ:h[6|u Џ#>f5FŒƒv=убL{˜п %Ј кВ•Й–яЌg€‰хv-ЩЮn†ІHAJZ!BН™йDуH ёїгznИJЃэу‹= 4EжА4YH>ŽCяQЗрIz›ў.RшЬ2ЮелзіА4?7Я*9.ЮкйёжљІ|<м‘EŽ*P~№S#-ъF—д7”’ ŸСлёБ˜?%ыg?$n`ЭгUhЄїЭ ˆАNЮ8bіўО`C о?џЉ3 ŽЦg#ЊЇ ыUœQФbœЮžRr^-'dЉ4vD{‚мЗ "fPАвžrЕDž50zЂМыъ<`–фVєБлY dцm- ВrќВWГАb)WQ\Ыn5еPхXБжYЦС'S6ћwз ТЮФ(=cлŒ0-єkM|l›E IDATsж иЬODžДэ‚gђщђ ЖЧFr/Oњ )ІnVєv|3„ "3ђєлWиЖ ѓ}˜ДƒТ7Й[\ЪэВТЦ/žШ@іy0Ђ§юќГJ+—ЎсЗ_ЧЁиЃ8wџLЎyTє6ЏЪЙKƒWС!‡baш†ЅИ}Њ™ДіoНкeЭлЂI™<ё[$пЪAЮ­T$&e–P їШžyкЄуаМё˜№5!†3ЎО€rKэKF–вMZ?gиїpъ6ceо™ІўА•˜k%ᘠˆw&)iйо<•rdef"#уy.ВpѓV6ё,iкгЭтиц§ DЃА$Лцs; X4wиЬrтwтmџЄёЬ‹EЌK‡0Сс-НрlЦ1”[њ,ЗФzЫ•вdп‡ЩЋi™phC<<Ÿ‚фјd$Sl0C%Н‰юп•l:˜›?ƒщOKѓ3нУl-‹!Z4у;ЄdЪ!Ї€њ-#Щ8œћ<-ƒ9!фMК@БѓБjs2ф…мя!љrЖYФiДыR3 ЁЊзРюfЁ 1xЄг?•qя89щEq“єрF@šКп-#d\ПуК™ѓ–ouЦэbьњБŸ~”‡эпТœ1фB?–АNLњФ oO–ЁUg­1ФFьЯš:cА–ЗЕГ_cˆљФёXwДХrўšžЃBѕF5№OЖ/žё…‹д i‡ЎcХЫ"“Uжтлo&oьXК1Ф@@€іт Y3ГЅˆкbYђ~КЙП^н‹˜ћ’1ФаЏс˜О9Uз“М),€ХyUVQ]о‹P&Єp7UaжЯЗZУpЌџ}.ќэ‡•B˜„ј­б€ю'ЊФ& Фo; іџђхЫ8ёЎЄ’ЁђїпјѓDдєДШЯЪ@о…sШПvъb<усМ‹IŸ?GС 6œЪ53’—"|чфї:њ РвXfhСnюўyYbЈMLИŽysYД _r-bwŸСштжšоPІЃэєЯЮХ#ƒьŒQРТ‰шшMЈ$Ц\Лѓо{Ш1зЖuk^Сƒqтџі), q"5ђфшRЇоž™B5l)'“6\фмХ‡~ˆуЉlШ’l)zЌиŽЗRЃ!З:ЖІ bт!њWYtT”љpЇ‘-зм‰(H|FpZ\GGOБмvщО[ƒіВ,KХ2}В^S'""( ƒZЦ aБT_7т09"‚9`8g‰†ѓWчXe/z”сљЖ†„ўˆYJ—;№о;Ё>>љ’RЛхњЭbœў:ЇФšeљјЯ\9Ёпd ›>Eg№j” >YшŽзЛт_=яš^6‡vф§bх_GМ§ОjжВѓ[ Яй>4УtѓtЦƒЋй˜7ўfОEуЎулЏ‹рIžНВ9і04хС“иоžCOъ#sЮТЦ­И—„œИ­HЦ_ДшSЂЎ…Ййп?=(—CЏх?9дщ@Н6­№kт /_oјјћР›<Ф<њ5›CПЖуаЏќ “1lп9~гBИ1.}‘)МOШЯаc/М|ЃК~ާ[7sЧ6Фч€q‘Mlѕ9ŽЕAЗ4љ„ю {0НukDŽнЫћ}m˜oсэ и8я͘2uXжЙОкФэŠг€юЮ^qч|ЂЮdŠ•жqм.8мП…œ›ссяЯ@Rт•QdнCіХфЊйлŽѕEжЌ3БКž!&шB89K!ЅмPЌќ_"Wš"kй[Щ;CŽЁšьС5Jс U ЉџlъЏ"Ÿ‹LЇУ–dѕFФ’5І™ktчгH†Ќх$Њ‡Л†пе‚АM­зGb^6<bBBFWD)‘0UЛЗŒ shgCI*Ы­ž\УГ’7ЪМ,YЫH’iмCЛя2‚Ž ЛФФЋ?gуѓRl–С8,ЬЯ9Џ§vQŒ€ъT3bŠ\ъT#–ХнIIGњЕtЄ]NCкЕL>Pš~9щєЋёŒіЗ7.cіД­„ˆ%dfv&RгlGŠ’\KВdЯј“ч*–$›ЁrЙbл|5И/ыuЎпKм~œ ЂRД+!њdК—‹EдРЃЖєTУKчђWбН}яТš‰Ож­.х/гн>Њ5iŒхёо!kыlвRyыє#оЇ`љPˆjдтшЬ}Ћ1uu#,<0„X=бЙt-%њг'џЮ Д‡Uj Q”CNб N™hђоЄЂЕzєAП&Џ`@Р\ЬuC›™ƒqсГ‰шТЁ_љapоЭˆœШ}Јн'АУЬ”џЁљъшчEШLЏ?1N‹@гЖгєe_Цuк}KВ|›cЦ0O,щі њЖўkВiОFчЕЈsНСŠ›ІЇfЩ,dр eRъŒy„цбpм”I‚љN*JКћ'‘}еМ†Ф#Crљї‰pСwtЫ/‰ёJtОІB= фŸњcЉIhЇн}БљДур-МкХ5ЋЛ љJ~>|Фпе’ ъїЖн\ŠQ”u~Z„‘ D`3+гТž‚o'JДчшJЁИ—t“ЕЖNзУђVydF/§ CЗ’ЧC‹TхћF}бќЖ{яwЏџ‚HёDSдЇuТ9$fМn_‹CžежШŒбЃк#Дљ.Юц"#‹PБ,€ЙeNЋЃД-ЄЭ"h_‡<•5щ№џь] @TењџБяВ(*"тŠKЅтОЁЙ •šђЌдї,+ЭzšѕвЌФLЫДўЏєНЪJЫž[ІцR†e‰ћ†+–ЈЈˆИ‚ь00ѓџО{чЮЦ Ь ъ=:мsЯ=ч;ч|3їмп§ЮЗр]тs‹Iщ‰лшЗ€-к1o‹ВrчЖh!q+vсёЯшОЁ>„˜ЏEПём0Q9SЃЈU€ЈL[ЙиойХјVъ(ЇкMtќSБ[тbКЩьMьkУ+Nˆ?fl•V<Ж*3Žcy_]YkНЏ.#ѓTыc7ЮMЮнhпЩUPЎОvХxЯmнЈТDВРВ7 ‹iˆ­Лo‚ЅCœ”Њ2Ь_z–FjqёJХїLxC<мВ |ѓБќ›Н(-f—œrВфРЋМ№Ц˜4ЁИэ3tМ {Ы,iUtЎ:ЅAЁ‚єЎuьЖ^Ќˆ^u\Гf§Z1]ВФ •Ў+ЎgЯUлД<ќьзЗЋЈЇкШѓŠЦ{?\Ћ5€ЈŒ]} jЩљžю{xЂУш‡Ќ\qЌhгzQќ+cхжB,22ЕžSQQ1E7ОI›TБ‘е€œ?уЅ„uˆ‹ = оїїDY dЌž‡ЁпwDв&}0Q!Nй_ы}•cфЖ vФnФќЇ›щч$y_ŠФЉ НБЈщЪХw%œ(кщ'мБtБблсEŠ:YCў}ь[МШKђиGУ№щwd­OœЗ-Mu'ЩTЗЈ:шео оJфчч#›o9йф@ ВЎ[wPДЂb0ФЩо2›DЫ]№РЃчз’+rЉŸrф‚jч€Ьѓjgi5ЌКИЅ:7%сLžжšvojZT.пМ—єР.wЩюCсѓч tвxpž†ўш ŽПŸњ$ 4U* 0ЪJ$ŽwкФр}5$<ZŠл3tЬz`3yŠvŠУКS’.…ш}u&yhŽЂЉїU лпœ&”G9MУvƒwXy‡} ЋЖэУтідЎ§jrnЬeфmvЯ)l&ЯБLkТФѕИnxоYЇ%z…Ѕ€ЎcFP›yЄIƒ7ёОJа™ЫUя&Д"‡†­0ЗокЖYEжcІ{"жgФuSx—§'*G4ъ{bТˆ&ј*ўA<7<a Ь•К­ї —ж\мЂХ3џ-д\џїcO2ЯkуЗ^k3'ИE=ј7Ж.ђЌзЊ.љW;I&~3ѓ._О„еЋVWЙ/2ЬDЪў#H>t ЧШ~jКо­:cю ­шЪX|~№]є$.bbяЋџТƒф1uё‚ЁXIоWЯ .^Д8ќf ^›пk)ЮЯвEЯ,j1вDCЈonХ‚и—7љ#кrш%ФRпLФмоуАЅёГXž0I_ЮУЖ“ќЦn›VhЬ0ŒтaН•GG#дdЧ„НЫщоцы‘АШ8NXв~§ЬPjЬRL­-ЛnсЅљЇ1яЋs8~&пxб$Ч4ЛDaоЫэ№eќУЄ[д>^іIžLШмYй’ѕОјšхIоЈu+TѓžЭpќћ“ь<Т\Шš%МkИсќv2МMЖiцl„Дe&IˆИpK›-и–№ JKIД2Мъ=­'EФdЩЉˆZЕёДеЁ1EЩlŠN]к yŠ+"}kоWQzЋцS”ё%=PМЏєьK•gуHЪЋhIа чФ,Yƒј‰’ЊB(‹^№5–Mя@u˜Ел]Х3эa“V\dZзЅ`Ї&^aХQЩя„4vAЇnЎf h;љ% p7—\ЭвсчУХ8y>—$І•sІe˜/fП(ў6uКЪ%N•SМwkШ–Ќїюw+Яьют@­D^ў^#рqDˆŸM:7‡wѕ‰й hЙ8}I_ˆПК0шz{_"o2Э X9c"%)HOЃп~2ž˜z_5я—]mє,ѕТUНд†ќІQsШe§bл‰а‘’mZь–’…WXЉ|Мї9№EЗ?žЄFџл*ЬзСйЇœ]мЁѕzkїјт™ ЗЩŒ& Нpљ†ол#еJН\„}ЧГбуa“ЁЭжїЦ…^#%3uЧцѓj‡xфп)KжLВdнXK-Y5Jп …Ё т/:Ц7ЙЖЬъц@­D<СFэCy. Ъ%|‚}аА]ƒj›wмБйшеН'` 2ˆКŠnN…R-љCйАa3ўxђ;ЁO•št*д!k{lO€р?ˆ<-jPY&Z—€јQ!E§#• Аm~ЩZгЏŒ–9ёЬ # ‹_9нЛtFяўnиБMˆhЊљХ‘шї-аz0В>ww7gєщTO0ЕoAЁw—Єр`rŽЁђџ~LGзіAp6й’3\ќ‹2wк’5|b}‡gV5Kж'Щ’еИЦpŒхж,YЏЧlВd§_-ГdЭXџ†Ц­4№*dи+XВb<šљŠфŒЬч@­DмВyЯІHI8 VЄf‹˜ъHЇПасb`:J(ъЛЛЛ;EЛі‚Џ|}шучWъз‡bнКv \—SKЗBАbЕ#‰uˆВгв‘U'ЅQУ?4  ‡ ’/!"КGГЬІ‚фqЏSтЂwr<КЕђ@Nj:4#XA;‹K‚†GeДHВ”D  4Ј#eяЋ4‡ыЕœKYШЉKoqСжѕЛ,К”OяBє$@Д/Q ЃAЅ мјїj%5rУ юСм3ўd‚,нŸџx<‡Nх@к!Ы ‰бЖН70ЄWC+TjОЈF-Yз‰ѓgœgЦђ\у хТЦ‹72[ВЊŒ7Ћc§„-Yu6-Y'‘%ыKV7rBX,Y“%ызKVЯАnX~~кЗ„ђвaЬl6 ŸlшƒEу›YŸВ\*s 8P+Я;žњmEР/ињЂь(oŽm8.4y9fЊ`юыыуKjJzЄе›ЎъШєП€М’н"[рcлФњo ‡к!@ф о$X:ь),5ф4ŠЌќїOQHС0КўJL;ИЃLdœŸ‹‹bЄsє§p;цтMђфc 4+yПˆxбІY+ ѕрЏИ"Zош4k7=чы}Й]ФЌњqфЄ^L/Ж@КOгБї${Ї•гНФт"щЉqpЗ)В>УЖMн№HчtŽЌ OOOxП-cн№Fо”`лО›†Т5вЃ_—`Ижѓ Щ’5ѕЗѓ†ёYflYВВU] fK:еsBEb7 ћрŸ(KOУІЯBЧb#b”№рAђйЄФеЋW№Rёс…Kэ КD/YAŒЂe…dЩJВЃ.N_у­фo1”ъБц›ћУЗ§ЇуgZѕЦ~ГЏoKЋ'Ж>}—Œ7…рЉѓ“ч`@$пхdЕ:щ=ф‚ьЏb3ІbуЩсиCж­ŠБЯТ}х˘ѕe*Ђ_xѓBˆ0 ыДDKVтСЪH3 пМ…Ж]zТ‚x7m~1>ј>SЖhОљЯ_ЦZ ˆ˜#AсAеޘџ&.rˆІ’”ЋедЯюФЎпu'oЕAg,R‚‚T-иЙ— 9НOж2дdяЋЩ&оWсŒa…СявVеђ№ѓж/b„_Nž0Д3оetОу /Јаjfщ–%.Ђ9Шщох@Ц%-ьRуфQв…˜ж'Ћг’E5zFy!<д~~^‰ЕO УŽУYPЉEЋˆœ|~јэў6аrлзZы;_VnѕВ‘AFZЈщЃвˆGW?михA Ї%Х:(ќ(шШ H †;м з‘$I‚Є6lЩZPЕп}_eУ оY,YоаiрзђAДj)ZВ.јВ ><8Эй’ѕ П8Б%k"f%ыр3№*YВ>6ђKДѕ+#Kж'ёЮќGЩ’ѕMЎŸ^ОЃЅњm4Ѓ'ƒњЦВdнŠQK>Т‡б­KVЭЭЃdЩšˆшwч“%k.ЦЧ’%ыГёL›ДDKж-иM/UяOkO–ЌцхЉm˜•XˆчІз“X$eќ%Је€ш/сˆEЇ—/]-Ю,ЪЋ|J „ою“3ЊЎd‹–у^aЋkD2šт€š"…Ÿ<ЂС~BW/›˜qV4'кОn @€Џ}ПСzxЂ#|ЗžФњєУяз0И{=ŽvPЃщШA5’іЉЩ8Zќ…ZяŸБ“‹{Рo“mzу?Bв–™щvYuYВў0iNFърtъYВў`Аdѕ‰rФ’5 L,Yf–ЌeV,YЫаЩд’5ђП&–Ќжi‰–Ќ8kХ’U™О/FЭAы™Ÿbтркš­џ8фвћ2 Њф[оp†отф$sр.ц@6ХЉт-1оуm[Щ•vlЂiZмМ!ъаqн})^hзТVЋђх#„bыž(,СE …ђX“pЯЗDЪ“Ј–’№f.Xї?GМЬлю–СPЬ ћ%C „Д\Єi*%њ_пЖ%+o™НnЇ%+эФЭn%bгФnЧ~ЖeЩJП›r–ЌTжпд’Еžq/д6-ЖdЅ~-,YgаЕэLФ,њŸOщ,Ц3œœ—9PУQ 3\юNц@Mp€u^ЮІm1BgџдšЊЪ•ыžubКіrCtw7xћ8сbЊ_|l4ЁП‘ыŠ”tКF•kjЕ€0ކ%ыв з=…ЁНъЁŽ}‚&CЛлЩ7pІ0$.Ž„7œЋž=юŠ;і|Х–ЌЄ/ДсЖdн- Jy‡-YЫин!Oѓ­*{ЌO­Y­Z+Г‡–й7P˜‚™mп$P‹ ОдЬjШ'2jœ2 Њa–ГWкЋWЏbт"Rd–“Ьjцo Jв{дШЙe. 0эŠ 79lGЗоnТQВу:Э[ЙРЫ§2JTM MOш§ mz†ŠњL,Y–ёVYfŽ(ЁбhuXЙѕ&ЧеЌХYŸюˆŒрЮrœ•3ъ7и~ЩPњ™v[Вr]N-Ш’е1У €wнoйАd-NЖп’ѕяЏс_ЗiЩ*w%k…ДHВTp]Вd%ЉуќYЄйT†Y­ШgеБ&\ыЖ@Ћ№DЬїх?2Œ‘‘5’“Нвж›яЛNЎЄ‹в ь`бЖ I€@žЉн dВнaЩА@пуPм …“Гh‹”MОˆўЁФр–5­ŸЛ‘Yй3УУБрыs† ’ѓл= pah\ХLг.hвЬ—гьд™2щЧQ0ДgУaЁЕН–Ќ{Ж‰ѕgTЩ’е ЫШ’u™Щx%KжhrВfjЩЪVfRrЁ€вЦsЖ>]ƒY˜y[–ЌAKV[ДШ’5ў)Ь%KжОАПЄEИuZƒsћ?% ‘ V`еєHУЙœ‘9PгQ9оaфУUj9ЋУ\T‹WZ%’зoƒІћ`thTУкЊVgЎ…ЂPC уЗ;–ъЂcuU.дf‘Чпj—Ч_ +I“•[‹eЄWќРoю,€ іЄ#фFQч+KnЎШHљM0ЦЏйžTŠОбe З]vЅоыaнЏWqёJБЁўwПdbъ“5gMЄRща ‘у€hрcŽI† ЄLЭXВ­Р’ѕ€‰%kŽшHЁIŸи’ѕH9KжЅж-YЩХ‡y"ЫUГ2ЖdнkaЩj–Й%Ћ Ђ6эЦ0sтђ™ЬПœ2 КЏ нФЪ,–фKі” Ииј€АМnџЙЇтfЃш@Ь_ ˆДYЇ№ПїПУжOЖтмmј*Њ.:іѓЯБšЪŒу˜EWжП9йЄ$M[blAЅЈрЇфJwwћŽЎшжЧ aMEI#Г>ф4i;„йˆ[FE%:l;P@њAі™Iђ6мГ#šтэџќiшіtšЇЮ— iѕ9Ÿ7а6ЭъА‹Qc IDATЇJаЁЊˆGІmЄ<ƒЁўБіo“IэЊzdKVvяQmIЖd­6VЪ„ю/Ш€ЈОяMыХХS Ы$MЦђЙ/НвЊђJЫ­m$’.“УэлHJlз…<Шn4xu”˜†œ*љЖСшЖbnЊ;ЊњƒЊ.:ŽŽпюњДе€Пау/He%i6™ЏLI:АЎQIкЧзqа.ёDЉШ†KQДuŒћdП'’rД <ь“vh€ŽэpєtžDwцaъпь3Zй—ЩКY†=ПЋpє`Х[‡ЖЈе4тqќ [Вкњ:фr™5ЪЃЭdv{яtЦ`(|ў„NЮ3тП?[‚унћ’ЏиtВ оLђDˆ* Ў:ЧLЕзNс‹qЯ#Ъщ!с3syj9І-ŸгђДеaТД]{в"e§—Ѕo5n3љЁ%eЦхтЕ•@vЬЂ;)lЫ+xЎІяkЖŸ’Y‘чZђRЛjл>,nOуhП|Х#М3тЦ?‚Nb(^ З7IЅЉxзi~>#йzГ'[kДЃ#Юm=v~ё‘8Юі!%+ћцъiїћRr–Ei[–цО№‹S†PŽвa/тiПЎЧ=.7вRІУBц ]5n52є/ќЪ ПaBПА}§jск7ЧˆkЅзБyšФ‡‡№Ў•яSтЂšЎ^V‚wЇуыOKqцлc­лЙ`ќ‹ž˜>Ч[№—s;`HъпЙ8‰Ќлq*кІ[ї›Јџ!еЉьШ!=Lге,5ŽЄXњY7­сx>\|ћE ўœ˜к{ї€ЁЪfzщ’OЦhБeГј{~ВŸO (УSƒtxj`ъŒызьWvЏЌ?љКЬћ™2 ЊцoŸ%A=ЉРТ~^x+­-ХIѓCPїП# ytШѓХяhфNfАіІв4М:ŸЎ ЧчЩ?bыбЏ1"* \ыв‚“HЭ4jгj Я"iЧU•^Ф’ИЯаŠ\іяМДK_h'6бƒ,‘ћ6VMdЕфm6†мј7'ЯЕлБ”œzПFžkгєdе7З’чк—7љ#,џІ—рЙVˆ†M{Ы%O„Наўо +І-5­œ )ЬEв'ѓ0em,?ј)F‘?–бѕc№т9Rи<ИC—с›/ $ Ž­ЦАaŸ`мСёЫбљ83џлC! ш;ZаєYœѓ)~ПКCЏ.Фа™ћрЅUф!)q%^‹KФм„/б7Ь9ћФЌOŠ№љљэТїљ(щкиJџ]XJzBЄWeckЬЫшEqШ=ћВкFКVVТV?ЖЪtjtimОГћX>Ўм4/ГеžЫ[аœc:›ЯёзУЅ`ЫГлIьZрЯ“|і‘Ÿ}X‚г'­ƒEцQЬ 7!€­­ўПяxт!)‘Aк™ы§цррŠa№&ОЄаеќРжтиŠ…‡m2к…Qь-ДDoОЖї*Цtу5йG‡ Љ–f~…ЮСtв/3–mХЦW0кч”ј=в.nЎˆ ЌJG1zЖџяќ1 …ИЭ”%Рд$\JЭCЇСєпЇО ‹У-кВ–B›ˆJвьHбЭНълbжh[–ЕmЌЂ˜ФоШ$ˆbјП?]У;“§-Ћк<:6{Žf@P^QЅ8ЁMˆЭ&6/АЧэc‡4иЕ]…ь,л *0Ш =њЙЁK7И{8уЖэ'ПLЕ9щCнёШлк{6'XgаЏ6м ЎочPƒЈЖОŽеhЂР‰ šYѓљwi‚%‹Џ WЃTД‡ “’9pпp@Dе№U3t†–‹ьl AYŸо№ОxyЛж"Џ~=”ЅЅBWЧ!ЯNƒюcR†ЖЗ_Aw%эšкЇГa$k4Е…g[МНy2IJў…AёРPђ ћŽр–=ШR2ё ЫаdЋ-ЯЕД%fщЙжи_хЙŠhWокДq/*H/ЁЂ9Р':Ж!1ЙгюјЈ.FжI*Kў #C?3j`ЅНtЄІ№3Фвt…;IOњЮнD}˜YcЅŠ$u{д†FЂqЈЁSї~М’Œ7bуАб˜{№} ЃЈжRУPg\1Б coвЯОф‰5wы:“pт‘ŽNј~Ї|;S€?Ю }kћlшыyPдћ`lй™i˜цў?uhJN!эM hX™|_ЂŠРэV {“д,ŠЪMƒАђbЇnЎфЕл(MРЂZ›ˆх..LVЯІыe8v4ЏП™‡аЪЇєХ‰›!(ЊУ€Љv"m!НȘФ_Мk3ЩЪscэВђ4ЬGЃDAЎRf ”V!УU9sq@о2ЛЭ/+юиl,імŽЭ“6>ž:wдqo€њO>ƒz}њA{§J)іA“Ї&ТХгј`ДЋkђb кЊЙtГтХŽч”’ф‰"iŸIш-ЅfП€dѕnкъ‹­S_РЖ3Vє˜шЭ™WЃж%Pй†O\уMnеK­а‰ “:5=кA[Ќ^ SšІyPg,іA09~CЬлH2™ЯќŠ$\VщH}сЪё ЄD1Ÿѓъbњг ЫsŒјэп˜vгV{ЄЎщєh#0цОS/cgRљпЂ­qљyЛтё>&(*ўyйƒю?ЋM._вbхвR|јŽBАЎS›‚J} ‹КИbкл^˜@:T-лT,9ЋьŒкЛ@ˆЅCЕ=мŸe{”(Sˆїдѕ-ъ4РщмFpjиˆЖ]Бѓ2>ћцЮфFCуБpyO3Aл|г@эпƒ& @Кq 3›IEuZaqЪvь$Х_.%`хїCHвЫжЏ1˜Й:Эив.Љас/Kк шьєRFx†uУђѓ‰8N/\гОD›Э‹ёЩ“q›ŒжЗY Оў§]„Wў`вJЮж$ь2зфЈю‚ОŽm8ў\ИpgЮХХ4*ў‰AGЪž%9™(>{%щgсЄ+CC??Ÿ;Х™Є„сР=[aVЪ"ФlўЃC{Ѓgш,Jd E;5&dТcž@HЙ84SЎФ`юЛќ uгoлсЇиЇазЋ#zFЭDєЬ#ш#‘йY€љSбгm’ йsэvЬ}ЅH№\эEo]X‚SЧ4VуАyвCЅї#nxcЎ7FџУ iˆйШŒы‰Л УЇкЭ‡ўшWj/7ф_ЪХм—oтчЏ`СK—Бт[ќыиПѕXž- l8 ыvЦ71нЫYJœи‰хыЯ ПраzŒtz?ЌO Шњ4Юh)щ‚!‡aаР‡)0‡…(DА:ibuЪг @hЫ`5 FHx‚ƒНѕжЏЙ‚ѕkWСњU\0йУіЭ§Пс ЇТ.O1мcЂ•gчrcЗfхЉМА‹$XaпhБqKЫЗQŠ­˜йБ#FML$YС]z C‹@СHХЛi{є‹ёС­L§М-цЋМqЫчўF/Іќ TЬѓђп‘\RЈјuЊ&Fp—їaЭ+­ѓK[р”w WЯС/<\@ЄlЋЮЩFюЙTъјmЧўфнІщŽ’'h%)эzРУS\ќџ–LрJŸМ#cБ^н‡Є3$іБŸ6z‚Ѕі|jџЕз’jБЗЩЩмƒ, Ц0кЮLцЫќNъaЂwвиŸО[xG>M[kOKЇцGпЖи@oN†D[EЖh;BЇеФ‘ŽGDp=ZIЭ“ђд6ЬJ,Фsгыщ/˜ЯW]r {w&у9§WWЯ2яC>ЛГбрoёЇЛрsу‚—~KD[?;О“rжЂ )R*NŸ&і2NЕЦЗѓаVА~ѕРYЩњ•FРvЅœцЅd!ЊИЬјE(-qŘ+YyЦ>€•Vž LЌ<7„f˜EДт еКOz‘MGDїHДЕИэ”щћ№bдДžљ)&yHћiF+[ъвI/г—dлё<ЬО[IœˆќЗк8 ГНкXiNЈИaKрэ№иё\’wCл )TOМŒ(olќЗy]љLц@eрјcь+gУ*ЅЁъ‘в/*Cpƒ–ѕ­‡нЧѓQЊMAБп(zvDSУи*Ъ8ъћА'Оћ]zЬб手ŠYN њŠhw.Uџљж'S.ЃQХD\g;+ЪT1мŽk,{ nьoЈщъW—$6g‘KJЬІvBЯfxfнpЌŒ[ЦЯСјў6пТ єle\ЩЪђ‡ПВl§JѓЕ0pp'kЭˆvт ‡™ЪŠ•g+OngjхЩcсВЄЅ•Є^|4‘N*Ю$ kл™ˆ!ынЯы][Г5/ЏˆчaжеъЬ ШgеЮћs•Љv6к&Јьї$љЌЁœdм&иdœ}ямЪŽЄnƒm›•їBЙGжmіTqs_WАХиšR зЇ-Дmіxпд ДмHjˆЧДЋЅјqї-ђTmCц5Оc“yV&oдјўо<Ј CПnЦ­во]Œ€и’oЗ{ююfфЕN•MJдбЁsž%aвљu3œа"уk{еlк“aп7bП* 1ђэ–t›ƒ8–’‡w–Є"~Щ%$VXU”цЦl:?у]o<ѕŒч}†˜Ї’ЕˆыZ,|vю•Oь-уіі&їц.јпЌ5HЭ"+I Дў™=ѓeВ›: ЛЂ^У^н!ќп uё^д{іGщlU[@atЎЅ‰`9чRYЁŠžсajuЊынLНŽыщз‘q!щY‚ю"n•ЁрКоњЕ’IА•ч`\Р;ІVžЩЖ­<+"W-я†с$ЙJФС§D›ѕџhЄћцЯЂ’2єlEV—ЧRrьRгѕ`пЪ|MћЖŸчІ­фќф€ ˆ*сЎ+… /“юѕJъЪ—eмiD>ьŠЦсцЗmТfЃсNї/бїpw&п“aвЉpмq8 iWIЉ\Ÿдš2ќv0“чРœ%чШ‘Ѓ…е‘Tбфx+Г ОЗe1eBьШОћB)М›„СЗe |њІ(ВЗЬЁщшШŠь$Fж'+I ДcиЋјxzg= ђПUWмвЬкі%f|йѓ{šМzx`РЂЅ…_0ѓЕп+4P˜ Yѕћ“иeфђ# /Ж€ИG~т’v6YNз[2iwA‡h Y\j‹Ё-УˆІяу\Ё:Х?…ГLE_СњU† бШ…жЮЩh$>ѕ?hїхћ+Я—MЌ< ѕєmљ`Yf8ЏˆVЃv˜5жї C:Ў%Н&%nЮЈЮэџFv| Ѓ;ŽУ;k/ˆ=•›ЏEПђ\$!џ­Yм7[fF>\%ЮЮъ0—Ќ“єo8UЂ`Л‘6‹МЏў {_ЕЭ!љŠ5ФwЧW‹84‰˜.œетмiMыйp|ВM‰зqYя-З№Ооx oLh„Н7АiЧuффлkСчЌЯдЫIмЎЩЙЅƒhAg]ЇHšѓ§tt "лžЄŠ{о8k{ЫŒ-*ЮЉH"ѓќЂ0f=Ix –Њb›V“>СЖIbоg№?qЬє‘є‰Іыމ XЄ;f<7Э VЇЧ %о‘УШs˜см,3ъŸ8^2 [lв•Ш8бХЊxДFчЦЖо-{р]тЫYyšЗcоДЪлЂ…@Ф­и…Ч?#`J–Є,ЋЖ‰”М ЃВШXЬзЧЂпŠxnAI>­!д*@Tf‡?gѓЗcGјдnЂ–Л(.6ОѕZ\.ЪО'Мт„иVЦ‹бXY№Ђ,х”Ч1kвFЌ|К‚-Ўлж|ŽНЏ[iьxи+иМb<šеЂ1wџхZЖvEЋЖ.HM1n•mлЂЪœ$7Ь5РкТ›@ŠдГ?ушqb:z:cоHoЁйJ­›x?,в T ;[‰$кjањt4TgKбннрЉ7З6\И3ЌђТcв„™З}&‚ŽWao™#ьR‘яЇB=ш]ымЖ5І#§VTзšѕkEѕВђЌ˜]Еm1ъсgОm]))j#Яm ѕО)Ў5€ЈŒ›]} j…ИOnэ№ №D‡бYЛфPйІѕтлЇŒ• БШLЈpдzNEEХP)Qdд ›кН”Аq•^Љцљx"ˆРDЦjrмї}G$mŠ}XqЪўZяЋdЪA^aЛ`GьFЬКOYя}uк“У1eњaЬlњy_%_HуХыB%љЯ_ЪСУм у\Н\†фЃ2K—ŒzkfxDЫ&>8O^ЋЅd vBWКbЛ ~@ ‘Ÿ/Жp):Ѕ[[ИК‹ŠЙ "•ј‹ БУЋчС#ыn<ЖhсŒuЩIЎ э-г7ВурGЯЏъK§ибDЎr›y~› М#ЭЋ.nЉцс8“iIгюM+ЄкМзэ? …ЯŸƒаIуСyBbtњЃ38ўўI|ъ“(ŒEЅR‘'^у›x…д_dM‰ а&яЋ!саRмžЁcж›ЩSДSжв+ощНЏЮtуљ˜z_rБ§Эiњx?гАнрVAоaпТЊmћАИ=ЕkПšішЙŒМЭю9…Эф9–уM˜Из ;+жiЅ.џЏ‘0hы˜дf)G’љ­ЉїеpіОJяЅ’їU{ зЙуhмФEАФ2эшŠѓЅеšюg˜^­ўќ‰Гљxћ?š!Ы^<=œыГ/тлуеqЭаД‘Й–h9••рТёfMї%’ЯЅ<лR&ГЪђЩmrРС-š‘”кhev›хц•r@цyЅ,ВГBuJХk тЙЗЈџЦжлеkUќэd‘§еInu3ѓ._О„еЋVлOФЂ&jHйЩ‡ŽсЙУgЋяV1ї…Vte,>?ј.z6–о~йћъП№ yL]М`(V’їеsJи‚с№›1xm~sЌЅ8?KQ<ГЈХHг ад7ЗbAьKШ›ќlэ%ФRпLФмоуАЅёГXž0IJbлIжВMKє ЫУz+Ž&ЏАмЗ1‰оW)LB”ф}еxMЮ§Еє)–šмСйY:$эГ-a­ŽбjЩТ`п‰|ќыпgџ)Н<œб‹y,ˆГDhьа0|ћ^4&Ц5CƒКх7‘Гєфupq6JМ8n<9Щ9 s 2/VъвкRY[гыЕfЫLTѓžЭpќћ“ь<Т\ШЂ%МkИсќv2МMЖiцl„Дe&IˆИpK›-и–№ J9`д№ЊїДž“ЃЈ}r*ЂVmDŠтёЗ_ЄаbЭЯx~dSвBХG^Ијутт"ЙBЪЎгhпэ8nСh8qц-О}_г^W IDATk'ќмѓељЧ)юu№†ŸЕM?Vп№ЮЦъьNІ%s@ц@5q`EнЙsЇ@Эt‘‘Дж8к]­D.Ў.hоГ)RЮ‚ЉЋ:9KfœўB‡‹щ(ЁЈяюююєР№‚Џ|}шучWъз‡bнКv \—SKЗBАbЕ#‰uˆВгв‘U'€отФэ џа0Š JW’/!МСFГЬІ‚фqЏSтЂwr<КЕђ@Nj:4#XA;‹KТb_-’,%QшMъа/bпќxђО Ь"•'іОJђrЬж­Т+ГEпђiЭp я@wкЋF‰^OŸ;ЩJkШ{Є цcМpVƒ]ПЉq=ч1466šжrЇа1‚0r@c„6№1мŸu|н№фр0,лxЩP§ЇнвЃ!‚E‰пЫ–€Шз—яrЛv ŸЎ#>G`CкжЇ§gМppу4щT>Ъ9 sРРz~Гe~Й’ж–Њb†Z ˆxІєдo3(~Стbi˜}3Ч6ZО3•Ь}ѓ љ’šі&ЇO:2§/ ЏdЗВГql›XџсёP;ˆ\С;UK‡=…Ѕa:NЃШЪјb№Fз_‰iwcД€/ŒѓsqsЃšвЙ њ~Иsё&ІDХ(ЭJо/"~МXТ4keЁќWDЫfMтІЂч|і—ДˆМЏІ §БїU)E,Xѕг)Љ\>ўѕ№ђІ`ЉŠ6ћvЊЩK*KeЄ№sъ˜„и|пVђ%П@1ъ`HЏњГЬхзcЯlѓЮkИ•+ŽECњ8Ы7_Цыу[ ‹•Д`ё›/bnє›8p ”фк"//O8–яЅ!k D—~уQš-о“ЖЦ'—Ы9pяqРrЭж ^0x№`a-с5ХTBФэFNЄ№hD•№’ЋjHтЁ&’’( Н?‘|rА–eЫ–aгІM˜4{"&Пѓb%дюŽЫгOG>-д_ќВzЬ[sЄŠСЮНЌoD”яFYH[yTьсчmw›ђTФ[ДДЅьˆžНТк;*[=Шхд*ЬІћ‘tˆЄд™ЎGŽБм‹•Ў VъpxП{W#7ЧиЮXCЬљћhбуAWєzиAuРodМёGz+3mГуP&>њVеRљЧІ›†x€‡зўАУг‚‚с…_R8_TT$Ќ+fЕAžЊЁдn(D—ZрlгPYЮШ9pЯp€A Џ3 „xЭёђђЂнoАdйvvќ§§…чЙŒЏyzz Л@ќТХmэMЕVBdяюtНЫ—.‰gее‘+?Чˆ1ЊЎd‹–у^aЋkD2ър[• ъŽVˆ9 Ёˆёe`k4гT˜_– мcмf3Н.хsoœBАћŒвuыСЭ•”†ьH}ЃƒБсЗЋзLђЕ|Г)яNn-МСёТ&Нхёж5/^,!въuѕxkЅЛ†ЄkЌ;(іЉ†Tž"и#нŽШUdШИ8 Iy$@Фы…ŠёGz9c№Уы зх$-r„2 Њ„[Ю|_I љВЬкСNн\Бћ7•СJ‹v€БmГcŸKeо(Ў;ЌVTm+7pzCл(dЇoEТчѓ(Hч0’Ъє-WЏЂgвЖцoџїДЁZђЙљ3э#| o{вKœ Io‚МшyyЉYšєЃџЋ›Ѕ-бЊЁ‚ќйож3t(gdШИ'8 ­ (bФ/Q †XZЭ!^3јУkJU€Ф(Iœ2юrИИ8aауXЕ”|hщгЉуZкЇBJВ)ЇxуеzЂuD№_дћwAЂєй;Yж+кYкЁ] :Ж Ч6“вŠŸЎ §Ћm €ˆ0Bт…ŒЫxБcC†hw%Ў$•‘хЇ(сRiнqЃД9"Mћ%кђQц€Ь{‹ „Є$I}L%Ы ˆ$`Ф ID’tЈ*РHDЧkшјгТmИzѕ*&.šPC=ЪнмOˆ|иЁMœaЊ§У*ЃВЕ%/М)|UЗоnшоз,- eНЊœ?3М)ŽЅœ0и-Є_/СЮЃЙшл‘уїЙуr’оyБc Ф#жUєїз cK5Ÿ3*oЇоD lыэ!ыUх;‘лШИл8Рыƒ ш№кСр‡’ДШнŽ”HD5ќыр/‹НјЪIцРр‡МhвЬYы'ЈžzѕwCЇnМИT/’њkои§ЛдЧo3Ѕ"ЌIИŠž ЂmS@Ф /p’б†$9ъзЉ Є“#BНj”Zы„“щўке\/Ъаœ‘9 sрžт€$)’@?C™# IзИдЮfШ€Шn™дэ0ђa“3ћГГ:ЬEA!ЧЋЙ”up;іe6ХЃЗ‚ќ…зпkВЇЂBіяRсР.58ZМ­юŒомёрCЌtxg€iпуm‚]GВ &ѓ{N9љjќИ+“œ96ођxб’Фс †јУ@‰§ш3Јk 6ю2zЩ>qаХСі[˜ŽIЮЫ9pwq€з DвG>|фƒ#^G8/еЉ (’ŸЗёЛh7бёJЩбмиюnKSёЎWж›5`A_!ЪІЕšЋœКЃшРnLьZЗ}јWž@ŒЎќЭшШ'w;neŠŠвBјŠвв!+4ЖDЋЩфс§aнЏW нnLМС=‚сы-:RcФ‹™†ё‡н|№g@ь=yYyтщ~=ЌЦЄ‘šrFц€Ь{—И1FМf0ј‘@єbХe\Џ*IDUсšE›MыХ‡Œ,–/›Œхs)^ZQQ1љ1šFѓЕŠ“йTсЅ„uˆ‹  xRќP№DM0ФдмбћРзаДЭѕ]=шСI&‰|INї.]а cЇIYк–'1^LЏHRЃЌ-"U[,ЊЪИИ‘Аї&Š" ))еbэ/з11ЎЉ|xc‰/lІ@HDмя“ƒр?пAеёs%фMл-УD КЊŽMn's@цРнС ёh%)~$pФчœLы vў‘Ÿ‘v2ЪV5Cсѓч@“ž†MK–ус"‘Ѕ,Ь[‚YљБp.Ь@йIoVФU.ыDBТњ†6AP#Ѓr)'kЯzМб{’„СХ`юСx ыHg*œYЛъ‰mа,АќWœБc=ощЏo3KП™ŒЮ–#mѕ<МОЋ#ўїE,D(ЅРцqџРйaџЦєQОиўцЛxm~"бСџ%ЯС€Ш:”Wрч‰я!wФdЯx‰МsOЇЗљЇСWLSк–хx}и'8G…Я-zз7нТГ›џ…VьвV„yI№xHfЭ(Є_žТвЩятгЭьр/3оԘСЭ’iЫчсKŒЦќё[„’и>Ÿ}м‡\KђxоBёшЇP4я|LУ;ѕ4Тlћ(шді?ьQš­Хv‘i}њEлІч^єхuЅXfmШ™т’—@б­L’іkаЅ'{DЏЙфKяŸ†/зЇ:нЖ/УbBь),nМ I`ˆ+1’—їъP?яЭС…+Ц­ГЕПf‘o#ё7 е•2dм[Є=– G:—@‘TOEUсBљЇeUЈШm `IP Y=ЫЌ‹ОiMсцЯШПCsы":М€цо'сjЈoO†ƒydЇ]Фѕ:ОааѓРГA}Š хЂ›* NXƒЂ<БЮЬšйvŒРLця[Ё7Ѓљ‚cЋ1ДџBŒ§цk|00Phї\гЋX[№1Т#лрм˜™8>{ z4r6ЪЪT,žз‡пьL`hж^}…ыпЧsQ‹БY§6šб/H}s+ФnХЈ%aytkс’Y*8Дšќй|‚БЋОЦч=М№ылж$1Oщki s‘єЩJ$ {KwwAcЇ4М:ы‡MЧ†Ћ йПЃcG hw"&і DiСIЄ–Ž4єЁ)<‹ЄШг6yѓІњf"ціOЄё,Тђщyј4v6†ж Чё{мЖЇoCЇ5˜QЋuBDћ=П} Yы>0Ш =ћЙЁsR”іЅ@бн]qxŸq/эЗ­*tшТ{ю5+%кЛ!6'^УЭlёe@Kрnљ–Ыxыљ6ТTєX.dІ ˆ+=KОоњOŠaъ)iХ8qN.‘ќ '™2юHР‡ч*х%ptЛѓ—бmrЗЩ6Эœ-P‘ЖЬІouG„‹Юdeук юў.ахТ…MpлпrэщžЅ5ІБбЂ­СВ)mбlдг`™‰VЃ@= f-С i-N­XDНЉу;рaбкђхS8xКmЛєСs˜‡яМˆ[смц•$ šƒЮ .`ц|Ъ.щznЎшй—hЯЦ‘”Wб,’фQЄ#Гd т'ЖЕкчБяФ>_~КƒжЦ|Е;VўлЄ.{4žŒп7G0хкжЃVЎxZ aд|0ь3МёЛ1Ўз0ЊaMw„œrщ)’c7'`њу!BЩKvbфЄИіa„I•єukћса^6ЎQЄ<жЦЫfіНqCTV(4:Ќ7tь++‹- (ДЧОDЕћЬ­;Uццъ 6Уџ`йYCћOфрьЅ"ДnъkCІ HZьЄэ[ њС$§‘'aХшDЮЭчmЈ gdШИч8`К6˜цowЂwйусvЇ{gк3t†–‹ьl@–2}zУћтuфэZ‹МњѕP–– ]?„<; Кg л`іŽ†сТ ;ІƒљFдuкњz[ПѕСФb*ЃXŒk'ЉЮа&j“™6K іКŠgКДEь’ћ3С?NMТs яˆЙ%™­“žEт$“>Ј-')9uю.ž”ћ[Œ,}Ÿ ьФdљГ+"d”,ЙБNљЊ‘Њ“\Їm,MюГbe†‹”‘тŠeьu'ИБQ}мебтYф%н]•ЖnА †ZЗsЁаnhбк’ŸЦ)њSpз1nиЕ]џeбЅПЊа…ЖдМ(XkMІ^ъbУv_Є^Ія[Ÿ–§†…ЏF [d’Ž\Х4Ячc‡6<^K;j—o”р—}70Ј{}О,'™2юAX=’D™зщКtЌ* lЏЄUЅxŸЕ‹;6НКїL€‚чš№vo€zOFiъИЙc”эZ UЏpђ4зВ‡]ЦЧ‡Iэв …ЏкˆeO7CЦђiњБЩuЋYŠJ^7l/СKќ t~X ЄйъБс4—ЉX:џ Vb(6є%™њ2ЉйЈu ˆ%J]ŒфЎ(”НЅЦœдчeвющ,+EъiНо“Б–YN­w$h@DZœ?–дэ!HxФч”’”M‰ЋgФkІ4мнLLВБ‘RШ]†x>NVмэtьъ*H„вЖІ=Љя@wкЋFЉže%є•эќE…исŽџэщЯV^ЌžŽ™‹ў4TљѓB!іЫBзЈ@A‡ˆ/№'!щ(5 vCLЇ ьHЪ‘Š№љ6ъё?<мЌ0ЫPKЮШ9pЗs@A<)oyфkUF2 bюU1ўB‡‹щ()T >UМН)ЖŠЏы(AI1ДЗˆ2Хh*Ш…В ъ—р ^ОŠнŠЭ DEV*6>C  Њ=ђI„B:Ќ6’zfа6ЖъŒG;њуфВхHЄэЉ1mєzЦ,к•šПя~VЌˆьqЏSтЂwr<КЕђ@Nj:4#ІofЃC*і@Чg&SŸѓ0wЎzљЇтЉ+Љ<ЦDdок›ісЂБ-о‡_э eђЏјтKd]@%H‰тw eBn.‹Ч”OЈ=Y’Й7ЃёЯZƒЮ_§ Ёъ XЧМyї)a;ЮМЇк6рQwќИNѕУe‰Н`ˆ›xћ8 [dл6щ№ЖгЉу_s ‚СMT„?:?ˆУф˜џ?кіzЈЕ…qеЋ%P$ •)ѓxŸ@ь9žkєmT ЦF &;Ќo=гjr^ц€Ь{„ pЄ€јмдКŒз .3Нюшєm>:%tПе?ЖсИ0х—cІ"??О>О Я)‚ѓ@ +P’“‰тГЅацчРIW††~~(>w ЎўATЧnЙТъf€_8ž|%Џ}]03>С R”>Иc€6Œ?кRЊ+Кюї–/ЩЧјЎБ˜% Ѓfэў YyGHuаѓYM›—aтгшЫ\аїУэ˜‹71%ЪИ/7+yПˆ˜ВБ/}“CPП иАЮџ§ь'|]' ‹ІcJl"Œ›8<>ƒ8ŒФ‡GчуѕŽ/Ёч ‘ааŸт_ЃТ„“№˜'™JРъ…щ˜ћ.0ыЈ‰[і{Yч$FжgЄD‰”ГyНØПЫўіŒu€LCq$lTсЙ)Ž™›3јaTX ўјиЃ5+X?ё4#оšKМh§§ё0кіЪ5xlПšYŠ™я}omŠA:$!>ZK~К‘ƒ6†K?ќ~'і| ЇŠ~‰†ъrFц€ЬЛˆ t8I H:жЉSуЧGPщъ§IRGІщD ŽѕЧ ЎЪЮг8жPII   @eЫ–aгІM˜4{"&ПѓЂ їG‘ЯK}рRNХE№ GС‰dјwކ:'ХзoЯдpўrWЕ0CЩ^ЏНъРƒ ­ВіBШцšѓ•%mЉ‚|.~TПВЪ&зЙ-{P;ћ6lИБJ‹a\[>ТаaЙи\ђšUјвvo•ё‹—Ѓ[fіНŠй1bGP˜фЌVQ‘Ž›VCњСЮ№Ё+…ѕVž9 uі-ЈIЇIEњLЩЖи*ЙPцРнЫЫРЌ—ЪpъИd[gпМј>.*иK-RSДДgNuоз Šx‘b@ФouЮN Œ6з`;BЁEВnСš4F[Ч‡:Й"ЄБљ2і3)ЫЉ*_&‚§юМДА*ЃЛ7лШ<Пня•з’ввRaлŒѓRшЊа5_Iь `Й@JчвбUЎТfэЄgŽEjdЉhAuF€2‡(nеЁ'FтшKџФюACБwФUюCn(s Жr qИ‹ркt|П§ЬŽE ‹iyEљвIjоЪќЁЧR"[‰яmЫћлђмV[.чёI`ˆ/XќQЉThпB—В|CsКŒ­?%>† 62<Ž!яќ-ЮвvЂœdШИї9 Iˆ$0Ф/\ќсЕ†?ŽЄ*"гб4яHчŽж­ую„†>фa—А‘^$™’7ѓv‚{~6J@ˆЧfя§o:*ыёB(-†R^:o€†‚в“iGе‘LШДJІЗеR; ‰‘Oї5V&ƒ›Ш–ЦS9's 6q Вмљ~?”eжо'ŒŽr(žW$ЉY(OLJЛ~tТші"О‡9™олМ/нуRGŽМ@I`ˆПбБ”ШЙ4Йи№AЙŸIJєвtћяcI—(5ХЈt~tЄ8†[ЧЎ&ў­ дЭ3ч–ЎE€‡ ‚М(ц M'к2вЈщ-ГЈ ™™WО“gќ2vЅ˜Œ#ы#ЄОљVЂѕnЕPф ”№АЇ_`•ЌF­г•Keм=`$I‡UE2$ЭЖJ€HZљШ‹$$e&&ЬцpЌ.'™2ЊŸЅо:&_KlUE‰ўsцRдї•m…B;ў”hXIЗ}D‘SХ›2ѓ+{]юa&azoK€HКџљКЃ‰/Xв›/d|~цРЇш6тsЙЫЄuђЈэ;Š€ІL[Бш;$д wv5“–Б‚v{R"gхыŠ’]яиР eT  ”e8šЋFS/7фiUPСЭ—œ‡осT|b †vћЬљжФGUи›ђТoˆnљ/Г:Ѓ}‰S:;фWЬŒ€|"sр.ф€$m6CU‘ёдЋˆИ!/Š–€ШWПhАoўШIц€Ь;УvН^Cјƒ# ФSЎaЩъЩа•9Ж}і`пkћ˜ЮщыѕА{ѕ?QF@€;atuu58`”@‘Ё>’”ˆѓМ€I‹XоS№і xwЪ&ŠьkщС‡\iбсшъcP+lЯЭ3РЛ F!Б9ўОj €kЎDnш@ŸQiu8|CA:‰N‚БУLТmP•щH/N™ ЅЛ7TфЬ|к= Єњ=К!ИУУpvЋ\ eйЇЕsж}№еЯ­реЌЉЕЫfeќѕМєЩGшїш№U\ФWcІa§даЂч~ mПdЭŒЈ|"sр.ф€щ ƒ#i‘ŽŽLЉJ€Ш ё‚щF‹ТРѓ7v”ФfpќіЧЄщ@ \Wц€Ьђp.=BрчQ ў*>ŒНќЂлР—ЩzbљЪ”И(СF:О аoјtИA@@,"B’ю>:šЄEЪ1@Ÿ(U7!‰‘H•Hи­‡/iкН)R;oГЛцНš! ž3КїuУžпAa)ˆmчЄwHК†ЖRЛ`O•’& ыdАС`ШЫе љ ~<‘, M‚}\Ё#Lv3хO”(J‘БrœIЏq№С=ЖH›——Іс‹бяувO`D‡ <їН‘Rј„xŒmv:~љ|ќНЂкx`ћ›oрЛ…Оf.ž‚ыл–уŸБ'ёђљаЗэ#˜иV"‚ИчК к‰ьLVP—‘Фљxяs@zЙт#'imЉЪЬo ё‚Ш[e тx"У‡GAAŠш ŠC{˜šУI Ј*•лШ9`Ю[к Шг;5Ї[в6—“§ Щ|g—Ѕ!Ga юн№ &%Ѓ pИ~й‘ЄD(2TЎB†A'>š.^nЎшвгMAй *t"= рѕy&љW(TEЊзЊ.љ Ѕ1ƒм‘ДЭpХJ%ЭfЧ6†>a['‡ќUЂ…П> CЮ§=œб.аSиdЅєзa[FЁ‚а™VLн-Ъh[­…“)UˆsБ’ѕSu)No9ŠФ-IH €ЪCЦFуч•IXћBЏEtIжџИ}ћOЄішёT_М66Nю\ˆˆЃЃ№cьbhž_ˆn-,цB:XыІŠ ЌeЋ ы}ЫЅ2юQ˜Ў'RОЊSu™ОђТШ‹Є†мннПXл IDATсщщ)H†јpbАФ‹ЉЄ№d ˆnwрUАмNцРНТЏВЋШЯkEjбТJ /”КGЂЁзEЛІ(нЯ~Nз‘Ћ9Д:q9P—Йтbv„†h 1ЫLA‘Є/ШээM–ї;Ÿ[–1-ЖЂ;zˆ”­ѕFžIЊШЃšїl†упŸЄW@cЏ.ф,МkИЁРЧз 1ƒнaъF`?m›qpл€@QчЪPYŸљѓV)œ зPT6(iћЌ@х$lЛеїvE#/rўJ з.4зuНьIkх“sKq…ѕŸ4іƒOŽИЬк_žŠ%™яЁT~Ќёѓxёƒ$ьо б­ЭGц9 Ы$bќŒDМи1QhЗtС#:BYXѕфГXOёЧЎлˆ!–`ЩœЄ|&sрžф€єbeКІ˜цэДC€Ш”(/†’tˆAz”ЖЧЄk ’МММ €HД)9/s@ц@е9Pф|i9ЁYЪцhнЈЎЮ&ЈСpЕ|FКW[:eсlfˆЁТйыўше^ ooo№}ЬОЯЋ*!’'щ(udyЮa;њtЧЏcMJ{wЈб­ќМжЁ12Ž\‘.ЁIч&№№6зъAлfће(ШЅ7ЄЊжG§2!Е’К7ђЁmCрщ…ћ‘[њ—­дтšB#ДЦTx;mлЕb4 pФЉ”€S~)щA‰]XЁjЛЈоуб†РЇF­ы Чє‹y€ т ІLDЬŒнH$Йh,Ђ…ъто‚ыђ>M.ХŒп0ІŸёћ3Љ%geмгА\CЄЩJх|ДїхЭa@Ф„yQфˆxБdщЄы\Ц#6Ћ•ЎI€HЈ4pљ(s@ц@е8№P%Ўф“йЉV”ЉЫмpГЄ9"УŒцєж(›.|i‘žЋ%‘ŽFы„#чН0*ЬKxй‘‘$Њ*0В‹ЕЕ W?к6лЅFaˆ6H#šП§нк‡ ѓ\”JјдѓAУv ,IТєzRЬЖѕ+ѕb&ЊСОšz?ЂEHЈ8?гF,! rw”Њ‘ŸГPoк"$с—ЋГЮф*‘’ЇDњоИTЈBЁК YЄoTBњEѕH‚фяb]ъdJп2Џ-Pыez@n†шJЄ}Л98cYЉпmР_85u%’ЧН'‚"Mwy_'7СтKпЁ/9э”“Ь™ЗЧ‡wЧ‹)/Œ pX”ЮGгr~“d $m•I–$ *ЫdШЈtlЉТСГМ#ІдЬ@t{Рžю•‹/ЄОŸ{“9`Њˆ˜Д$!тМ) тrI ‚Є-4IwHЊЧmф$s@ц@ѕp їУ:œМЄ=…Єж8с+ўиЉrщ…$)тћЖзУЮ8~A…œBHё{NТСМєЗ 3Хjn#ЕЋž”ЇвЉ2oˆca@Гѕа†ЂЭ јлі фL †Нq/џ\Џ]M]œ;-ЦlkaОь ќa­Ш72Щ9ѕnьньф?pŠb'*5љаЉДјцB.ъИК t–BШ?QyЫ/&I‘‚”АMlYvѕуЩ,К˜–№ot&Ъ9P pI}JШєœˆ$$!C2 ’И%eT/щъƒ'ШZЌHДzR“№aч -љЗЭб+ъM7|ьнб;Ž– уІQЉљЛ_2?1@ИЗYбЏъ5k€f+šў?{WUЕџПУЬ0ь›‚‚"И/%**˜["š %V№ЬдвLЅ,—WџЌог,+гz•ОVKх•кт’˜Š†Šћ‚;”ЈЈ€Ј(ШР03№?gЖ{я03ьаљљюНчžѓ;ч|/ољђ;Пѓћ-4MhLѕCIе—sDёf€­Bп–SД%aМ‚j>Іє[UF ѕRЄkђ&КИЛXеœUf0ъ"ў ‘ њ’ЄФ‡ЉEˆњ!F†ъїA2эohŽШPжФъз]€ЃI№Th[ДvЋўЫ_OŠ(Š“ЧњрЃuщєT#ч/сRКнм4зќКК*ѕvKт}Й‚#4Зn”уќ)IгQ§œш :t# P‚ЄГкх)ZFwœѕюGЃoWЖбћѕ&Юн№Се-(…шѓbТ`4-jDˆшєЄˆ)љб#zд“!ZO„h9†C ~ѕHl?”‡œ|­u‡ќm‚пrёЪ3~f;фџ?жŸѕЖCЏNїpё: Є“~ЯФ'ЏЙ–Щѕхѕ}ьр/жф#ЃVНh !9КЬ3оžЇIЕ•ѓюqА-h^‡Ud№юмБѕ1U †@]"PcBDЁRЫ^(щс_гr>)взcG†C n ОИSїХЇ?^3(>|6“Т;РЧЫt CEн‰ўџєД ~xугП З/Ѕ=Р‰Є| юлЪPжP'”а$ŸуM>ЩQFƒ-%Œ?dn<­Нl0h˜ЧШV~Наи‘BfgЉвЗГіјŸЉы,jђкг-ЊЧ*1ѕ‡@­‘~Xњ—(НІ"*Œi``? ŠРˆ /ќњЧmмМЋ]fЂзяМ‰З^4ѕЯЬШшџч‡ЛИс‘>8~‹gєУярAўрЉ_a<ЌVž$G Ьx„[д MЧ1ppе9Ъєuщ‘FР>}Ђrь1у5[КјUыьœ’Ё˜?ЗHпДЉѓСH‘EPБJ zC€3эдqєЅЪ> і;аАП(№љёТ%В#чr‘~[nёџG§ЋрЙ'ќH§p#Ћ{Oh rЅ s62œzхњЂ9Ъі+ЅтфlS)ы=M[XPџЫјїцњƒ~жžгZЯЉџБtuUO•“‚m_@З YWЊ™†@ГF оQГF… ž!аŒмзƒl“КэЦФfX=#?ŒЄM-ЁoМaч _ЌўI„О?§QŸЃLM4šu> `Љ •ТЩ™cx4vќЫI•Ѕ§˜ЏGЬu:9|KѓЙj\бэ д—[u$I]пѕG€ЈЏцгW…ЋŽЂrњ[ЁVEц9,yљ dщB4ЅЌŒФЈ€M(VcW ПŒ§э9›pKG€ZхІE­DЇўЬЧ•є"ЋЇ>y\ѓ2uиоq(Ыj=uб€ц(suу ЭQЖ;жrBC#`~\шwtъй ЧrRU“yЌМŠŸžЅ~]"ќђ— qз8г 7›šhV!—dZ›їмњЋ7 Чњys№Эіjž œkCvКщїщљŒ[Œ1CйЮЗš<жІE!РQ‹zœl2 -rGwa$чџmЗоJфх!УуУ…ICй}ђRюKНЁ0Ї9ЪЈƒ5_шќл™киKќrsчKак‹Ѓ!4vм6.EˆЙvЕ)asLки™8V’ МГУHNЕО­ФшъФЅJЉI”т:yЕ‡/‚ž}!„ъ\N'‰b‰шРŠї жЃЗ–ю5ЛDVxўb6_жФFЂcШм‹y}кЦ&пР† Qx/†DћдKQ2оНˆщѕ‹О;vd4Œ5ЪЌ†@# №М‘•шмЅœПDП,­“‰aэaOr{щЅАX…-ёЗє— zь$AлvТз жhЉаиCс„Žд“дHПf9ЉВДЏJѕ8§’Yjm–ЬєHЕЯ&kџqM"иЁСm‘јv^_˜‹џœ‰УОЄ/PБј ЬšsІfYz/ §~›ФG"4ъьFŒ }Ц-Т–єпёЫО/бЋm;єLт7Mп Нэ)ѓїŸq}№ПK§и‘!аОYšу и˜ “єэю†~=ЕСѕж kХеIŠЇGЗ4ћmџmм'йпZшЗqO ­DW/Љq™,EY*ї• ƒП№еЗыЗњГtЌyZЛdFљ]2лЅ[2у<Š,yхzЮЄшЋyЏрQ Ц„Ў@ЗљŸ`bŸ;иА,у7Нбо№ь=oŠFЦъѕјЫЬЊЉH$…„аЅГ?Ў…+^ЦGF ЋŸ/zŽ‚Ўž$дгГQ„58r–xГ#Л&ЧcР†ЧARА1aД„o…3-6†C€"0eœЏˆ‹зŠp2™лJ/ИYХХ“#}@‰‘^JхјiWІўВAнzIаЅgБЂякVF/ZN1hlОd\/зФ:т—еељŒ-к%3::Кd6VЗdжЏ–Ьш‡‡=‰Лў‹_Ў&`ѓgЃ4i_)ящйKл"sгц~“вu;ГRŒœ ЅpŠpЏфO$ю„…НАyѓ%^;Џс‡чУ;šеФn0š#Œ5ЧЇЦЦЬАž\4БƒјещN1kХоNŒIc…ф*юШ]мЙЧe“ЗVgmъ5ВнЙUŽ3',Зuь"FЏ!ЉкГ]ARUEj3тЪmщ.Гк.™Qтѓpx(†„AЯЮюкNtсšВnqћЦдJ­5OIЛЭ‹ ž]eP\/Fe$]0|ёSИМl–Э|gН‚>КюЬыcwЭ FˆšзѓbЃeXРd#+беХ8tцžеzТ‡ЖA›VœeEEШУП[OЎЌюиDƒvОb’ЯLW6~g `9Ё ‹ т,хм­РЉЃ•Љ€‰ю­*вя2у/™!люыL”FЫ}Ю~ˆœт‚- Bj!yљiјqњ*xŽКЦfVd|a*ю%ŽeЋ‘W$GVr2RokѕћŽƒGq ;Ъ9Л„tвЌRvƒ!аl`„Јй<*6P†@Эшьы„GД4ІV"k–˜hcЉФЯ=бA чрщЄё,‚›ѕ|1ц [ˆyœЈ П4иЂЅвЦл†DЛц) їю*C™ТrReI_њ]fTЋ~ЩlЈn—™%эЭз‘@%J_гcПZ‡i7сiЏ`єѓxПxLЦч[#сЂЋbўD'HZi§В\‚Їт— 3Аsо,ŒpŒ1S5ё’4Эœ{сѓZС302PЏIп';2š?Œ5џgШfРЈgЩr?уFць;i}дщGxТŸlд нЖ^“ њіЕ9КЗВMФ—ƒ”Ёјх„fє8[А<)*ЌРЁН–“*CУ*NZЏJ§МаЯ†аrСЇГCUKXU(ЅЗьКтЃŠГ˜lŠœ8wФєm‡qЊ№NžФў„WбSЗФхи; Ї+>GO'ъ§9v'Dшќ†ФшљьЋH*9IкУ)хyDп!­тђў№MМu%ьРhIџўuЕuixЋAH˜-NS‚Іђ RJ\šі+ЯјpK{к;ІКИй`‰`Н7G‚ю-У сТЈжІ[W]Js“бe–H}х1“9ыЩŒ%ЃреБ“С—*…оЩлПŸ'—рћЇКђ*ВS†@ЫA€Ђ–ѓ,йLU"№L˜/іШZЗ‹:DЧЙƒЧЕюя§ ошейtЧš^жmKЧ'Џш/ьш@,,Ё$ЯйŽ-\€‡•2RŠV­-3€?:кД\чƒ\F\fіЄ ЯXFЊЊšl}ЊњЌЏ{vН' іъtєЌЏ˜^†@у"`йЃqЧШzg0ъЖ­э0vx[І_імЌQnВщќz.^'лљ“ђe uёБцИ{pV.5ёWоMЖс[*vі"Œ+ŒmtђˆЙ9ѕ›вУвё5•zžОшЈпЩжTХЦСЈC˜…ЈСdЊM<жЛ‰UHЉвњйфо/УіƒYxzT;Ћ†ўPgѕvGbrОЁѕ%јА;ЩфЮ‘УЭz<‘HE‹АХOыДЛЁhWIgUžЎ†ЏПe{Ё‚‡Iq$A‰М{Z\ˆЋтHžД)/­Y1џL]gEm %Y“Ќš8ЋЬh"0BдDC !hх&CDˆ6ѓRolўуЦ k ;^zKЦB}‰ЈџuЌІ’‘%ЧўФŒdzя“ЖV§ќь3@‚ƒФњv&gейIЂOG/АЬ‡F"!ЄŠфIлИ–#UЩ„TeZAЊLЭ,цЧЯMW*ГдзЈRCVР`дlЩЌЮ dŠЭš†УNЦ§з/x Фж}З­МП#qЪ:”ЌпqƒXŸ8RbЕв6‰HJЇ„Ы^iЉхȘdy\Ё€ўДыРсB‡ВЫŠšйYЈ„]1Z8ŒЕ№ЬІЧ0…€ЃНџг^pыwт\]PФХумЌт‚nчч/С>PaЫо[UДЈП[m}Ф№ˆа52~‰>]ІstВ ы№ BRu7ЫКмЛr{У—ЅхЃru–VкЅіёIЊ ЙВМWѓ5G?n ‰qєщxЫ‰žw{1ѓЄReMž4уб•]}ŠѓP”—к>ЦѕЌН.! эћ‘иƒ/>Є]3šЊтв M@Х9ŸМŠГЗгЪвС>ъ'Ю2SЂPƒ.5†И’шгУIєiОашгŠ,wіMђЄIИщ р~Žь7bќЊ9ПіŸCИўэ\_Џ№Эї'ЊІi•З5Ё1} ња,Є~>?œ”Cц t.П№УчшС‹дhн№CВ…кY5†РпFˆў>ЯšЭ”!P ЉдSЦu”ЧЯMыa­Pчj/ЮяDЅЎн†пЂ‰>MЗђ%ёЈ 9w-ЗбЪ€п'<‚f€ьC  "РQ|(lH †D€fЛ~МШ<ƒ$ђДЕB5њysfХšІєh Ёѓ ‹р,Vt /Ј‘~ЭђtйЬЭ#UjbŒйНн:+бБз[aџ‹2ќќ)>гYˆ& QЈБЕїЈ4x‘жЖRЮйЩїй9XсŒђзŽbyВ/Nщ.ьУГŸfyэРšDaЌ"ZKЦщ6bW –#D-џГ2ЊE`X`kt№жoт†&ЧџЖ[Odh3šвƒ/‰$НGJšЦ§—_м ч’ЯLјšлERzX*R’'m IщС—ѓЇT$EˆхЄЊ‚АТЊ>|нVлuХGgе›# €;ЂЖЦž„HИwGRХyŒ Ё„т€Б?РЎиp-ЕџжЬю*ЌЪЎ#иŸЃ‡ЭІЪ0‡€žШМїЭ%C•уђp-ѓ:ћ:Ъ,9 №@ЯNЮHЙЮ‘ ЖgтН—чЫvмS2|ѓ)н Ў•ŒыхH>ЇBя~–НўњдцIЛs‹[*Ѓ)=^œЫHНnу#ЫQfŒЛf4],{#4нёГ‘1u„Р €VшвСWo4Ўл–ї_}ШpmщЩє ~xуг? е/^€3 аЋЃакbЈP'ЛˆбЋXГ\ІяfwЌНФ Ыjе %‹4ік/8GѓдKjЄ^RЁkѓЏP–НО:dй}†@гB@hKnZccЃa0щќ=žMЙO,=…‚2K.ютЁЛ ЊnŒЛmq^1AУ:И'ОDќ”їВ+pђˆхq…Кї’ 3ёћсЫЎ­ešЅ0~;g0š/цџМiОsb#g0jˆ@ПnшейЏqЫ]џл~ЭиjгЦћсє_љ$к8#ЋЧ“ бЏ›0hЂеŠkаР‹lq*СЩУ\^ГН;•ш,…ЬЎz+эrьSЖјяGмвлэ›х ўD§‚ЬЯч?SзADўЏ,аu2з^бRт[DюаГў8œ1a0Fˆ}ж7C  "№$Иpš#U{ШŽГоФq["ЉLЊ>%d(цЧЯЭЉ”??u>^џqК Œ]0 ‹[2kXМYo &@яЎЎаЫM0Юk`q*‰K$&>8zЩЙЏФСsє— ztvЕ`Э—Ућ”(,рœЅљїLгgbоЪY~^Ž4НєЦзъFЛщЧœи+†C q`„ЈqёgН3š$Ц/Ї?РБѓжЇ™ Чk#˜уЎЃP(щbQУ ЭqцфЬ‘%с2ќny\ЁV­m0hИp‰lџю2””˜Ÿлг2ќуЙH<>u мŸбnt‰‰——ёkвŽЅ|њd!.ЅЉxOдЂОšO_QV}k"Ж…ъЊЊі y#њŠ"‘д8\ЖЊЁБ{ :C€Ђ:ƒ’)bДКљ;cH_aZ‰ ;oдШ‰xbX{ШlЙWM‘œDh>ЯэиjHдЈПашЧ…VЂгЧUИ›e9! З%~GмЈхdSо=•I1Е =їтГhчщƒSљ'б6Т” M›6 ййй<9ŠЦщ­ўL…\т…4'ю7Иѕ;Оќ&пGЯТo$cm%sућ7!њˆMNCАvп{№уЭЛЖ}Аі І†ї–jj#cуa0Щћ vfЅн’уРщ{VЩнХ!BПЁgK!W˜ЗЊXн‰ –РГ GAЈЃГ5СDё˜TIPЂрОTбЋћ[јсЛH,Œ‡Д•Y›ѓp‹ыж­гXˆlljї ІЎяN^mрсу‹!3ЦЁ]zSъ}œ q`Хћ в[Kї"GwKq)‘џEšŽ—*RіbFŸOJЎхЩБ7y32cпB0Б:m"Kqч2bHћѓIлƒHQ?ЭНU+c№VбЭљщъБ†@SB GщZ IDATvџ›вLиX :EРпЧ!Ф)š/wf‚ц:ГVžщ 'ЮљFA–ЊŽ$[ЏЧк~MеЇБ‡Ц>)єчЙєЇзI~1KeшH)œ]9RЅ2БєІЙŠH9т\иКљыІ<}њt…Јœ&X#Ђ_:ГД}=gЭ a)Њ|$Ўй‚+ЄЏVtnj$О…зцт?gтА/щ T,~Гц$wШ]х\ONB‘Ю§I­ЪЦЙЄЫ(!з]‚АtVW8a О<ё†Ж—AYrGњ:BЅК{K‡OХіі/ &ю œZ§>v_а†g(<БŸ#hУьKџ ­NЏCќ[річщGЯŽ І…€ўџlг C€!а$˜4ж|#Ц­ьь=žmѕиьФx:Th%:}(*iœWPЏ ќ; ћоIRzа–ˆ­­-Н9ЁТлЉ*зБЊ3ѕЛ\џя]jО“Е…н кг +{yџс†рХшЭXt&Ѓ§!*Н‚ Ыr0~гш ЯоCёіЁhdЌ^Пx–ЉžЁAыЅЙЖїF@`{8јc@pOxЛ‹‰нI_;„ВТr XОk…#0l‘є!GNо"7е8ћЫZД ј7^y6ž~=1љЛoаМNЕ*иO†@“C@јFhrУcb0v^і3Xш§S\&Y•.Y2ЦА!­бЪ•‹єЁ&*Џ4žSЪXЃ]_73ЪqсŒЮbС„–О‹]Ћ>С €w4dЫ”eЪД&VЪh!jмYЏ f…Р?Ц­ѓRюu‘_ЈФіYVЯZU&Œ},ЗыЗ6ж'ЕКs Z{YWШXёв[&YzK:Ћ"ЋcZKSыж­A?zЙўХ]мќ16і6иљыЭRZт,йщ•вЃ{ >ˆŽДеo!fw1Ц~Ег:nТг^Сшчё$~ё˜ŒЯЗFТ…Tuш9 F8рЭўсxrјQ,ќf _:=6 БНу‡“ZgiОIИЧNлдCІ%К#g%Мљ(ої;жю—aqК.'KpЫ” 7vСhpЊ5ёАQ0MКu~ТHPЫ^ЖФпТИсmс`gнkЄo7th#ЦЛœ…Љл hЂі/Нъ=вИBgN(ЁаmЇq…HАEуhцE—ою+ЦŸчЙљьŽUќrюнуBа-їzЁKet[>БЁX-v]ёQХYA3яёЏ"ЉтU]™'Іo;Œg‹Ј•G gођžФгcb~1ФЮ. \fђlN•и'+•Ч!'NJ2вNŒ(œЎˆвUp@Tв1Ў2ёŠк„дрЄУ„iX9MSЙ§ usжњes•иC ‰!`н›Ќ‰ ž ‡!Рh8žхƒэГPRЊ§т/,VaЫол щ9Ќ•qƒэёѕoкх"кЖ•O?—(пZ5uRŸFЎІq…Јџ^Ž’ИBƒ•ТЭУ2Ђ!УХ$9tЛш‘›SqЩQF….žQ7tКуЬFz‚уۘNю‹ЅМіу4rЗ~DцЌŽ]Y;!Iюд^dF$2BЂЬмЋЂX‘€ўЏЃлјqh—О I*Dnи„Žч?_Хhй-†‡#DьŒ!РЈgG)ЂFЗУПп0дкЖџ6&„xƒоГF:ЧлЮ>РЕл\ЋћХ}5„ЁІ1y8MжŸ #q…hNВТэ2—Šl6лCRzL|оВoqЯ66"С‰Ум.ЕН;•Xјн4еZИƒЫњб5ЏbПaи“ђВnчЁЄ,Џ<„Ў$І†@SGРВ?šњ,иј A`М†ќpGQkбЏ{hќыed?JИ]e*A&yы5жМ…”ЦzBшs.Q…л7ЙeАъДg )OEёƒ мЫYјэ`ЊFЪчЦG§œЫрнЃ'GСА F†ъdІЕ`„Ј@e*-ъ/є ЩMЦ—d-Пає?Пžёy[Кxыі‡ыnRЋŒZЭ‘$у6ѕyнmМЙW"+Ды7ЫчхьbƒGG -e‡і*QTРХl*+ЋРОИ2,_LтѕмхЪщМvЌиoч­ЉЯ)2н †@pџћЋЈФn1 =cЩ|wю‹_Ё,ЧOЛ2ѕЗ­:w#^Лœ†n{O<Т-;YЅЌ–•щИБOёLv9$`ЃЕтъXy’ й^bAЁ–”ЦIаЙэ™ŽZ‰,MщA§…’o&њ‰C ,ˆNХж rѓzџг•іtсSRRŠ‚"эw‚:ИPgЇ ілƒ†фЎu ВNU(ђѓIЌІB‹cеiчLC@‡#DьW!РАЧH:АQ/4Кѓњ7є—V%Žš„B+i8МOИ”ІПWWЧr’7Фм'<‚Г~бўВn–уьIЫ­DwJv@хШХh‰ФА“јTКчУ]р7лЫ№‘—ШQ\Lіќ[*ЅЉxOдпЭ>@дЂ™HЂсЋDqѓо‰ўYЬF5ыRФѓ1а#Ё^УƒLЫЁnЌAГ~[(œwd  ›C€!Pїа4SШvћOH5(пw2IG’џЬ•Ы‘žє+КєоаьP|.…ƒ#ЗќdИYЫšaўЬЦГPЪЭѓv№ђУlnЯ9]ц ш/T—ъЂЊ!и‰лA--&БwЊееVШМпiюšŠCЉАЦЪІB.qJŸЗ QnPhRiиСƒ ;sућˆўЕ?Жn '1Ќ‰HЅ$в‘=4Ђ(?5 ћУзbйГ5уШйНб ‹ёUкI mŸ‡ Ѓ#1wNGlўіQћˆ C a`Ђ†Х›ѕЦh1„y‚&е СУп’Џ/Зф˜v~#‰ЯУ‘R$q? ŽXbCruјіЏRѕИ8@Ьc4їѓ+@cU%дyzыЦRєkЕВћ]ЊЊЊЙчпЊ?Ю|˜„/7hЎЫЪЪ TsўTе* Ј1ШЃ/<|<сэчM>юP'ЧbмфЭШŒ} СЂ(lJжfЃ‘Іял‹7EЋвŠ˜оU>тп^ ) Z€јd§вЛЂџ… ЛbUŸ`„ійˆB’Ѕlчьиt8БГЃ4mfЬоŒ,]`KРДЎд˜ёкњ|ьœќ$‰о'9з8ЖтW<ДђŸъOh љѕdЌ^+]– Ръ0ъFˆъGІ…!№ЗC@LœŸпA0яУgя!§ЖЫ>КжЊВbИ:ў)аEунЯюФTЈХ…gчжpmo:(aыЎ­рпЫU˜‘пEТž2Ш‹9 §=EiўиЁРђwфФqZКDf‰м/TуzZ:6nиhIu“uЈ +хиi$<‹Гћ‘š!‡C— ,е•аŸ)јђФ{ФђЂ]к,Cц†ОŽоБпcеђqјyњЇИBСZ”јі3XВЌ~ЙЏV‹V!Mg@Sо9Œхсspџх№ёКa …TwЯ`щ№ЉиоўФдЇVПн(‰2ЏЋ]HІиЂУ”cѕ™‰h'ЭЦх„№ниеJ)hŽЕ+щZG2a4Œ5дЌ#†@ЫC`HПVшиŽ‹„LЗЊџ/ЖfОDЮі—съЦ-‘брˆ{wж•ˆ>‰NCЩВбPlkПA~š52Ьvœ ЅФџ†n™7%‰'tхЂКdђЦЗЭ^S*ВјнЯqќј Гu,ЙБ5z%ољ!>5?Н и{# А=ќ1 И'Мн9‚ЖєЬ!LˆaућqЊKЏ`УВ јfZ“ЈйОCGаfœNб’’ВТr„|ѓЯ…Р@_ЭR-А|-ж, G`и,ъэ€#'oUшr№ы†ю­dh3Д_W’S­ЗHќююў\n;‡і0€<”М*–3ЙГ3†@н"`є:Ј[хLC€!аВ QЅЇEh „~І'“ѓШ_ј&<{ѕЬmDх С љrњИ йwъЧJdяj_Bјв!Јdк1Pџ%JŠјB­Vyї„уqrЖСьљіš|fќК–œЋІ‹PО<з’Њ&ыP”џ/i=Ж$mЦцŠsXЌѓЭQ‘dЊTј pЖAЗ^ZЋ˜Т(($х} б/ЧцŒщџŽІ-ЩЦЊ‘22п СТgLЫBУ{h+аŸ­ЙЏѓКд ћѕ…Юєdч†^Фгъrњ}ƒyZ2N’доUkе2м`' @€ћ-n€ЮX †@ЫC`рУфЏ|'СФbЖgЎ-Н№ˆžm8+Е8эйЮљYЊЧвz>}М!sб~љ:ЖvDл^mM‡Œ љЬмЙёPŸнБ•­D4вѕфэ0,д:ЏхіGњSSЙ•>DкЦ|кcPWщ„fœ‡вT"Ф'›œDnŠ#‰aЯ>QœхЏLуА-TiЊŒ’ЈъtqZ\рaO’ъ’‡Ќ17џvŒщ1aЧ†C€Ђ†УšѕФhБEEEdй­2й2еN_F}ˆюЅe '# ™з25ŸBъ,sBqR:2rhІћjФЙž›яэQ+p 9Ÿ9В’S™_mKbЭШЋгE,K…Yй(TQн2 š;I ŸEќ5BzK3ёmРg№Ÿ‰N–ЅєЯ.ЕE€Ђк"Шк3шлУ }КЛ јaћ СЕЅНћ??сЋiї6ыˆ‚Ѕ}бzюОюш1Іœ=…V.НŽ~AјДŽgчVѓуйДў_˜ўВ#*ЪЭзбыVзчУ[5ŸRВЕЮ:B$A+ˆА&bB§У1ЎЫšЯ–‹…шєи$ ФFLєŒNjwŒб]fz“ЄkмЕ#>ў ‹цan@к֘€I8qSk™вA­Se2К-Џ*]Аx.4#ЄбšxI#ŸЧїЫGрЕ.САП˜ƒЯ– a[юѕŠоЦвэ—uЦ`Д0І’ИD.'fѕзЕBœњ3вЦй1мАр$|‚-VЏфі^_ЛBRh\T˜њyeyјy˜Еб”пЏтЦsŒ'%Y…žНM‡–Я}л1_• ЂSwтнЙ—ЁHA ‘Въ­§†ЪєФЎ+WœСbAЁў"+•Ч!'Žр2g!Q8]ЅП YraИ†ФŸ}АїД%™3 ; Л•tŒЋЇ9s€АŒ\я?BzаIК:FОŠs%3  ж!H† 7>Ч‰щљ(&=zxКњеЋcG†@C! ќГЇЁze§0-^]д[H~жяШЌб<;w— kO§WВVEёнБ4…F:­ЂQзBЦŒЦCЌV4G™9iпAŒ9oи ЦзНŸWaHf{#=wям1ЎRѓk !2dЙ J„xdШђ–•kšг%Ж#}и Бt№t‡'#C•Ad% Š#D 7ыŒ!аВ V"ОЄоx€#$6QM$їn/F`Аp<ьЈ>­НН3^БнAgJrЖё›ЊУЪ њG€ЂњЧ˜ѕРј[!№ьX_%хЩ(z№LЭbэŒy‚8џђоRЙ98uДjЋL}‚§„ЧkŠ ,KD+‹5еЃZНшXss„qъjќ;VьЦЗѓжд•:І‡!атрНjZќ\й @ ƒЗBƒН=§МћV,;­Нl0p­{wUo•t^‡nю6:RkшРex IQ}GЃЦкbтѓФЩ™З‚–›]?/ anUИ8U?XVƒ!№7C@јІљ›MžM—!РЈЈ•(!1jн7ђ{ ьKЬХАО4–uBIФй*ВKлЎЈАGі++E‘ЖNkЭkc‹ФЃJ’зLЋЃŒьNЇ)F&<#ŒŸdЎ‡Р`ьб?Ќ.A ЩŽqЏ бАЇƒЬЉЊВќŸ‹QPЄнr_eХмTgЇ`Чoй<уQx6СoE~>‰udХЎ5•r•Є’Г7…Іz]jШ‹Tі@Щš4!˜…Ј = 6†@KA mk;„ F}оВї”*ы—‡\\+[eЦ“DЋђњБЌTї ЈOPhИpщыф%ВГT$вtЙй_oЇnbМќКм[‰,Z2ѓ›эk?rТЖŠ‹uЌпЙЙѓвTМ'ъЏЩ^ ъЋ9Šfjт7Qм<‡wЂПY mbЂ@тŠљшBв GXH 2ЋXaЭ9‡ї&D"@ŒWW_1šKеКд9ЩXЗр_ˆ РCЗ ~ЈЇбиeН"РQНТЫ”3ўОL kЉ„‹ќœ[ Фо“\о*kytД-ьЙLšDЋHіљЦ’AУЅ№hЭЭюлИъ.N|Ÿhђs~sRЅЁzЕЕС+d[О“3ЩgfскжЖM§№%3&ќўоƒХP*ЌI{ЂB.Щ56'nЌї{вуШЎЗшNТagn|у&Ф‘јA:‘JI`G7C#ŠёSC№жЦ4УrvЏFєТb|•vIЪ8LУw˜;ч йhн*ТDПŠ)$ЇšБTЇKE‚<9ѕ СФYnxп2cьКй!РQГ{dlР ц@k7žс-ьŽУЙP”Yo%ВwaФcBЋЬбJмЗ^—`@5МЂf ЋРyХ4Еieщ4ЌcхBRBУЮxХžФW2y[PH‰яGЏЂнKkH‘žбJОгмёч'—qцУ$|щИAгЎŒЄQZ™&‹ѕhч Oxћy“;дЩБ7y32cпBА( ›’Щ:щњюБНxSЈБ&­ˆIс|ФПН@S>@ДёЩzћ‰ЛЂџ… ЛbUŸ`„ійH,+rьœН›'#vv”ІЭŒй›‘eˆƒiZWjЬЧxm}>vN~ƒDя#ЅHc+~ХC+џ‰ЁўdљRтШЏ cѕz\1шв н№У{d8Ц† BїучVН.™_ЂІТ€РО(Я3Јd'ЭFˆšёУcCg4uЂFЗ‡Œ{ЭЋБя§кЕ^hЂUWЮ*Ѓ">EдwЇБ$ АrŠ‘ПnЗ­4œж][СЭG˜ж„_‰&†ЅЛаЌJ‚єкіnімИ‘Ž6ZЋЪPŸцFK9vI'ЯтьОDЄfШса%Kgu%єg О<ё†ЖзњJ•!sC_GяияБjљ8ќ<§S\б8—Ћ‘јі3XВЌ~!–ІЏV‹V!MЗtЅМsЫУчрўЫруuУ@НЪTwЯ`щ№ЉиоўФФНSЋпЧю ”D™зе.$SlбaЪПБњЬDД“fуrB IЫ‰Z)… Їp%]KтИ;ќ35HШO~хКT4i.“їІjгa“`0šЎЮR<9вG0ЄјФ"”(ŒО€5L_Pт0jџыšРˆ9wЧJЄIщёЄа‘:OюˆЌJ+Д"ЖЕп ?§e­ŽHnŒЬ7џ‹[_я=ЇЂЗбуіэлёцТЗqќј эЭўмНяЮќŽšŸŽоьНиŽўмоюмЙЅgaђј@ пы­є 6,ЫС€o† Е”ЦЁ#ˆ h3NЇhIIYa9BОљ ‹gB` Џ&U-А|-ж, G`и,ъэ€#'o‘„Џцu9јuCїV2Дк‡ŒЏ+\PŠ[(Gw7УXкwТbЫЪ“WсHdЈЭ;QеЁ.žZvкД`ЫžMћљАб1š=!к~ Х%кьщђвr8WŠС=­Ÿ nxhoющЖЊSп=л˜2гxЩУzн5iAЃ{і“Мf\fј‹YmбЦЅ6Фшг!ЈdBW“~єm4ЄˆФhKЈ…H/[БЄПЊй‘кюў/i=&ї=Н„›%ˆ%&„Є3qбtЄP .}ЛЂ_@B4oК]‚e$eа`!IЄeЁс=ИЪ­ЙПеЭывYv:Вcч†^Ф“'1њЉi—jхiЩ8MHв$Wс|ИŽЬœеЅ.3]АтІ‡#DMя™А1ZN<ъwм4Ьы№…Rєэh§2]Z3^† пsN!ЩчдИ™ЁF{?ЮraшЈNТ'ШpщOЙСшB†Œ\<мCЖН„;эj3œЈГ31l№P€O2ˆТ2Кe\A’ВЁ-[cёч3‡4н(”$зš•>Dкёёiљ—гЅ"J„ьŒž#!>йЄYфІ8,ŽњиŠЈ”)+[lL•С]…š.№АЧсRŽœ‰ЅZтцпЮJBDьM–ыrт†РЮš5 oжг`ƒg0š2o'юяЏ2ђEwфOю‹ЫšБїю'FЛТWMќкXвЦ›ЬЭŽуђ]/ДюH"v‘…2улl\Пš?іьУ„УH‡ЇІјaЦЫ0{N'ЬšлYљm№њ+68|АёШeCрРњ`№рН•јХьœ!Р`д6d—Xи a ХЖF@Ёф‚ Zг3^-!ёfєRXPšчЌБфсО‰Г™ЧНFДљД‘Ё‹Ÿ=$Zрz:СƒфUыкЙrI Š‰П—kp|ГJHюЬЭ…•3ZŒЕ„ЇШцРhf<мI onаtШ§тО\gЎn6 yЮјrр2”ШоJDЅЦ—!ћNѕ}ыЃmѓЧн`чdxдšEЃiSЩ"Љ3яУїЁlŒ ЫBpЯ8КлBь"ФU[Л‘~’]n…dїX^~UyЩЌ›:;БпDN5„б8I99…†0жЭŽеЖFˆЌEŒеg0j%@!§„V”’ВvШИ.\VВДЃclaЧ3:•яLJŠJhhГ'•јј]’Э§З2”‘И€еIcњнЩS"Ї˜„Cа9 ЛІФЅ<ОњЎЏ§KŠгз\!•V@]hСDЊ›Ј™ћ)+#1*`й_Нdnўв` ѕ СС3!ifrЫ“c ъ+јŒ йЌ‹‘-ьKqѓо‰ўY$œ@гWЬЧ@„z GXH 2ЭЖЩбW‰$–cЖжЂZCШ05A Гmн…oљ=лkFbDё˜0gиб% ъпO‡&—]ЕЌПќOћyе[†єXфBRЯ[яѕ}O+РšУ ”ЫЕ4ЋP —NnȘяQ[и’@š™nрЋuѕ‡ŸЯИХX3T“эоx|ЦзvО цjЮUœЧ‰ДешЛ ŸoI3ЎІЛ.#A"ЛbUJ<мŠЧžє8Ќџu,HДЂјЉ!xk#ЏTJъКђgFUЋЏХ!Hє/Єђў+фь^ш…Хј*э$’”q˜†я0wЮA“–"ЇŽ!XЛя=јiЂq7Р€[pŒЕр‡ЫІЦhъwўiNiФщšШ)œ]8Ћ“’ИQыњ–Vž"јwц‚ZкнVп[яЭŽ…МљЅŽф‡юРоUŠ‚є|,}х.–ЬМ‰хsnрЧџ•С•‡ЇY]foШБsіlкŸˆu!ƒ5›ШЉ‘Љ 0^xўb6_жЄЪ(<ЙO‹fbWrЁN[!vЭŽТ{1ЉškЯр!ььЎ Вшрп#CI‚_IЄ4я‰žЦЎKмR%9эКxТУЧо~о$&‘Rc>ЦkыѓБsђ“$z)EZђJ#lп=ЖoŠ5c\“b ŠŒГXб'ЈвизіbЦШOПyЃцоКГ$хЧЕƒ˜зч=l…Ўв4|ахп(ХNМеП?"gЧK–ЧVќŠ‡VўC§‰—Ф‘_/@ЦъѕИBБ3šЏтЮeФ,н‹<Э›Њ17ћЈи ŒБ_†C бhзJ‘‚ї;Щ5ДйкŠ@Ќљrъ˜Š|qжŸ•ƒіeCq"&Ъ№xЄ-‰ˆЫяНњѓЦZ6џ!{'СWчDф@|…дЅJИ:ЈрdWГeKSГUн=ƒЅЁГљЬ2ФФН —ѕŸ`С[G5„Ѓє^ўњ§6!€K№Xܘ’Š%Ы5–’ЌЭЋАxu{D=нЅ’ZEђn,J(Bp€>ШЇ|g ‚Ћ=GJЫqчїžEвсГH<œЂ! эB"0%РІќЋЯLD;{эУ*Cц†ОŽоБпcеђqјyњЇИBЩ!+Ы§gтђфЯАяж&ŒЛљ…aьjy>N%ЌЧТЈ,нѕ-Fј:B-ЯFBвzМ4ќutЗT—&|ѓЄЦЂ5ѕГBHћBІЪЦх„MЧфеJ)T8…+щ”є чЋ,Й#’PЄћ;Ђ*Ьѕњиб4Œ™Ц…•2 „€ЄшЈ ЇщхȘT3+MВJ-6z!)ОАчїњЗбў†ДХдYvV-Пд7YгуPщ(Њ€TЂЕа{6хoRVзRv]…)Б$ы§ьGЗОyЗ??ŽлКЧ+IЁ šр€Бп­C$і`Jџ1&j3fю]ŒžЮмГЄcSdХKяЂћ[_bv˜ЗvИvΘўэџaˆЗ#ЎЉXёЦ2М;чCМ2|=ю–TРСЏКЗ’ЁЭа>ь ^Д†Ѕ$_лфё6ОŸљХуиLЈлјQ –КЁ[јCШпŸ!№yZ~ѕ D„ЃЃ'GЦ]г-ж%CїG{h–эК юžНН!V•тЩVзнпЭ0‡і0€дЪ“рŒц+‚vНOПъWцЅьЄМ_‰JїXC€!РЈwl”wpчњAДэєЈЁЏ?v”‘/ЫsщвS4XуЦЕœ3pвFŒVЃ]юKK_ПЎѕ‘ њŸіXїu)VO0kы§џgƒ )7р3D;Цn7aзЋюCP*ъйž Ф)qnE,B—‘OVJy>№кЧ`зг7MРzB†кгB…aф—т0Јч[YЙ_Я "йЫЬ‹„ЄЂ§!ё;єјеЈIRY2_…lл"нzЙh”)ј>]RGMйЂўс†Ž:Ly\Gрh’кДo'-{иJ]j}ŸєHЂУЮ НH/‰щїIПZв'OKЦiB’&Й ћ3 ŒwRцО$i-ѓ0 ‘ylи†C H=Е†єФˆЌ›х DІ&а__сЋ-.ЖaЌDtМ4ЅШ+oиЃЗp ІцвX[я[ЙU`ф#eшб];ЊсС ѕЏŸЅE[)GD+Ъr‰ѕ@x›њb&О1_G§ІаЭэя`w2ч„ЂМеѓ_љц'ЌЌ† ™ТЙЊВr_$=)сWTk–ВbђЮ#‰8sгЯŽ#ˆsЖVLЕ3UІЉ]•.тьF§˜ е[У\рaE)їџALЬ?”lљ0ўpљчcЮoФЮЩs`Т`0yзс(KŒ"ž8DгDЈж нвoœј55Ek—kFАЌэŸжwїАСЫЏлЃkŽ ˜в“[ЯўMІњЄeЩIjD *ж|ьзтbi™9ІЪm;‰ёУЂŸš#‡ќv26O?Œvяі…gЅЪdиМh x G*Nт?ГZсƒ€tŽЯj]Жˆxњ”chW ѕl RЮCG˜T98К1iљмѓЅ>DwSГ•‘…Ьk™ШЬШб:Jп+GaV6 UећI9єˆ0\У’77#“Ф>’чч 5)Sу^iјеTЅЫЁ­Б\%рФ1Ђ[3.ЭŒЄ…Я"ўБt–fтл€Яр??ЈХЫФ|љн[Ž9П;Ї0BФ~ &€›c’Р)9чnЮœрОфЌdЗ^tъ&$#qлЮJDЧjGœvЇЯБѕk2'їgы§{ГJсаСN]:уЫЗЕЫ‹––™›‹ЩrВlЈР<э5ƒкMХўˆтГ7‚tU iЅu‚ЇлЬЎю„e{Ÿ… Y Нђ{?б[Џэ#эИw1[гfiш$<н&іŸŠ%П\гъ)Н‡O'ПciњчkKЈS*ц„cŒ8ЦuyOњHЅэ1`ё$\ўhFHЃ‘Є‹cЄБЮшF$–’мxдZCХЎ+ЇўНVˆq$іб бxeоIУ4C=mmЭOу2УuUК|zaбW|њЦіџE/Щcфѓј~љМж%іOрїs№йВ!š]vЈ4_њEЎ3E•˜ѓЫN+! "ХЌџЌ’VР`0L#@_1*• JВ4PRBRCШх(**BAArssБfЭlлЖ /Н Я.г@w†щХнC„џ{зAUY_fщёFК_ЎnыŸ2гНћ™'(–ъЖЖ^Тž2ь6ГlїЯE$З›ЫkжіYU}jrюл6v2œИ„M'5ж"KЪЊв+М'Ч†€QР†LюЉF!! .юњ'aЭ†МR—вэ28и Гљ1Ј‰uˆ„ДЇmЊїс1Џ‡о1ЏKQDˆ)щCЦћѕ”“ШмХ„yxКhЩPеЪЩнІ‰yЕУЖВBoєС’%K№юЛя"""3gЮ„‡‡\]]сьь GGGШdKђ‹-їEd"+ЋЮ`дЁcIКоїT> txђHЭœ};ј‹ёp_ž22ь=лI0Т,УеvЦ!$’іГ3d№Оьє:cы§GьQt>MC†zNяІŠЅeњq[r,KV!WNОш%M‚ б1‹эЌ CšppwЉ2TЕ.™Г бкžю$†’ЅdˆЖš"цк‘5§Ÿ&ў{6§AГ2-ъ{3h˜Tœuџn%>"…”ФВVЦŒ—сЏ rшэрtюєq‚†ш7)[ЋБцѕћє—ТЭнџћ†$OхЅYhŒ­ї;лhЌBкймв,-Г›щъ/€—vЗ–хэXЭš#Р0Џ9vЬ‡Ј6иБЖ †@= 2†_)"йыЌ™•ШЋ­ <"ќЛFЏVšкUTs1VщGœŒчМс€ж^Йk Bd<ЎњЙУГsGx: ­tѕггЊE€a^›пЖdVєX[†C Юpv%йыIОаD­ќmШќ{егшеќЅ*ъШ|ь@ЭVu}YrПUk )ъиUћњН—S?nœ;VьЦЗѓh8& †€%0Bd JЌC€!а <:к2^P=9ёi=МЏf$†.S !$XдЩЙ„D/n,ЁЩh_|е§‚$ЈЏ­їТС]ЊБ e§2j€а–\kuLC€!РЈ=Ž" ЕEЄ—УћЪ0˜XŽ(™АVЈSs"qЮ.е%-!!lЋSXDmw Y;ЎОD"Т3гьАwW™&ыНФ˜ЋCЯ†=­пІ.,ЏюъŸ‹QPЄO–Z]mыюЋГSАуЗl žё(<›рЗˆ"?ŸФВbw–JЙJbвйК*]j‚oAЉ;ИАЅAы~‰š`э&јЋмQbCb0Ё#ЉsuЈuˆ %3tщlьыI %X>fKv™qыH‚Cˆхˆ.беVЪееGyЖ›юgйYWјЭіЊЎJЅћђCrыРЋtзDЭЂnџŒ&—ў.MSјŒ"K+nžУ;бПс‡g !2КЇoл8GW,Ф‹ hКo3b>жЦOƒЏ™oКœ“qјzйlŽНЁ+ТšЙ=yУЎJ $9{,^[kЈљЭZ,œXeJCevв$0ѓkв$ЧЪХ`ќ  GГы7ŽФPпŸa„(9˘&UС3”X—Ž’іњcJЂvo\ž|†З6W•3їЪIй3ЯBIoš;7;NьkцЎхХл6iыNˆткdЦфsфЬwš6иƒХP*ДAЬ^-ђ$}ЪœИMˆ pƒBIчcBx27Ош_ћcыЖpэ>ёzЗ›РљнЌкzЛAHЩд0ь_‹eЯvдєBWжПUšЯмиH fŽРрG)љс–Ш(‰Ёл№k"Ж2F… ­1‰G ШЉоКSU666№ь_UtІ§ТЎВR57)ђ§шUД{щqаsJ„єdˆ’ ??ЙŒ3&сKЧ Meed7Књќni№fvО№№ё„ЗŸ7љИC‹q“IњŠиЗ,ŠТ&]Ž1љюБНxSˆQ_ЌˆI1DqђџіMљбФ'ы—юфи§/lи}Ћњ#ДЯF’`‚;g/РІУЩˆЅi3cіfdщ–7ЭщJљЏ­ЯЧЮЩObш}’цCc+~ХC+џ‰ЁўФŠ(ёFфз Бz=ЎtёgKRЇŽ ЧиАAшbœjЖ:]2є "dˆZ+Хш8,н Т•L+,rТЁАЋ&€#DMр!А!0І Б‡BH дx?Џf$&hЈ­9‚EŒ;иѓ;g2=ŠъK=;З†k{mЦtук­ЛЖ‚›—ёнј~MЏ) вЈŽЛйwpуF:6nиXS• Ћ_)ЧN#щфYœн—ЈЩца%Kgu%єg О<ёБМh—,iў­ЙЁЏЃwьїXЕ|~žў)IAееH|ћ,Yж ПмŠЧW+EЋІ3 )яЦђ№9Иџђјxн0’ь•ЄчК{K‡OХіі/ &ю œZ§>v_ $ЪМЎv!˜`‹Sўеg&Ђ4—JHTNдJ)T8…+щФiЬЌЈI.1#{•uКЮ~їв1ƒz5ЉѕCГ3f7L#Р‘i\X)C€!аD8D7’ТC/jђХJ‘k"bБcžрeNЋp;г:KŠЉО; %V Ѓ7Њиж~ƒќLUЗКŒ.“eОљ_мњzєKfz+=nпОo.|ЧŸАZ7ПСжш•xwц‡јpдlќtє.I'с€Ріp №Ч€рž№vч–„–ž9„Щу1l|?NEщlX–ƒп AkЉОCGаfœNб’’ВТrMжњХГG!0аWГ”EЫ,_‹5‹Т6‹z;рШЩ[ФqЬМ.ПnшоJ†6Cћёu%9аJq‹d1ыюяf‹CћN@J^Ы™†Ъќ•хКR7~‚i OaСЁХшщЬ§žђеБѓцѓ!jЯ‰’!№ЗE€юЦMb mњ‘ѓ‡ЁI_GzнfъJZЕSц%рЃ3 Јѕн2Ћ“нhђ0Bдф C€!,t/[ЛДA—Ктw”aв ж;D‹D"„Gиbэ—œcЩ•‹j\ПЂFЇnœѕЃ&ЈћєёFі•( plэˆЖНкдDЩ6QggbирЁŸdšetЫИB5ёкВ5>sHг^AЎЪ­є!вvЬЇ=&‡Ђ),Ї$‰!;#Ћ!>47}фІ8,ŽдN‹ЮJЄqицJщY™‰2JЂЊгХiqo„=—jGhЙX В„џvV"boЊNWЮўе2єŸЋg0Кsэ~oИ9АГЦD€Ѓс9 ж7C€!РЈ{\hiЙpF…;З-ћђ6Vн§! є‘ЂѕїтЖq(}™ЕGБDŒNC§AќkбixGPђU’ёm6Ў_ЭР{іс@Тa$ž<ПўJAFњ Ш!"1wmqяі=аКєSTT%qЌЖFЈЬНД фdd!ѓZІцSHyЃЬ ХIщШШ!ФЋ:…Юн№м|lZЩљ$ТИYЩ)ШЬЏЖЅ@Гfфещ"–ЅТЌlsˆъ–aамЩHZј,тЏ‘gYš‰o>ƒџќHtв№f9тЬФМЗ’lїZЁ1†ђrютA…VON~Ёю^5КTiXКZуWеFy)gSr"9дФЦЄй"Р,DЭібБ3ў^є—`џ%юмв.uб„­д!њљй5[ъ 'ёŒОњИФтєrќu^…‡њrЏEš.ф.B6]ЖГDм}нбcL78{:YRНк:‡З$jъМ2prt"‹@dђњŒЕфn1™с^n.яжж_8aБ•„H‚V„Щ­‰˜„5МQ- ~BЯ=6‰D$ŠЦDЏѕXpт&:Pw)n~bЉ-яZŒџ„Ex sB š%#ЛВЈХ†Xƒ ЅкSe2њЊвх€‹'aiд<ŒјH/iфѓј~љEМи%XЃX‡hйУ–ћћi—Zqп@ъЎџј&Ю;ЅФyЃзC˜ЁGUКJJ‘GžТЌЧ”žыЕэЩЯ…gŽar ‡IГD@TAЄYŽœ š!РhаWŒJЅ" U•$]F фrЙЦzAПмsЩјš5kАmл6МєN4^ZbДd4У‹I*’-ž[ъЂЗ_]hі~5[ВјпЗ%ИxГ\xЕaСП@—фNR’-ўešЬєїcъЌš/Ѓ)4ихќА7Pxџ>жžX]7}вЅ9ТeЮ2СЈNБЂHkQ’9;XмЦœNsКдФЅ ж!;юw@ž“bвЃ‡ЇK­ћ­K]ццЦЪ­C 7њ`Щ’%xїнwIќЇЬœ9puu…ГГ3!“Щ4БXlБЅ–ћSШКёАк †C Сш@v-љй 3Ck%ЂиMЂOгМ`5‘Аё2Є$Щ Ц–ь;иКQдKjВЕŸћ[1їw^“~ЃЭєtВ\%$Е‡„+w•S"TWbN—иЮЦН8xКW*Ћщ8ъRWMЧРк5 Ь‡ЈapfН0u„@qˆцKjŠiW9+џ^uчmМmа№яТSЧT2Duф_•ц&[/§Šщл›лАйx†#D=ы˜!РЈ ]zHаЉ+З’Х?ЌJ‰Ч[ёи“‡ѕПŽ%л№ˆŸ‚З6ђкIЅЄЎ!fT5@БњZ‚DџB*№фь^ш…Хј*э$’”q˜†я0wЮA3–Ђц5п€ДЦ]0BTcшXC†C Б лцћ ­=ё;ЫH^/ѓV"§˜CУmѕœ 6О›уж{§\+ЩœЅŽф‡nюіЎRЄчcщ+wБdцM,Ÿs?ўЏ Ў.<ЖYIIurьœН›і'b]Ш`Х&rъFdъB#ž?€˜Э—5Љ2 OnЦгЂ™и•\ЈSZˆ]ГЃ№^LЊцк3x;Лk‚,:јїСШџoя\рЂЊі=ў˜a†сЅ žDŸ(vМ`Bj%™љЊАЋ\3ёœ<~TМu5Г4* Ѓ2Э“GЫRЪЄк)ЈД“ЂG‹45Ѕ‚ | & *:0РР]kяйѓр9Уsџъ3ьйkЏѕ_k}ЧіќцПж^џpзN 8‹ђМ$›†н'M> .rzђ†Ї7zљѕ‚ЗЗ9‰ЏciRvЭzaВ—‘]*ўс;n_>МЯЪ‚…>ЎIЬ6 ]nжЌгwнщ§˜{яZьKй.\лšСB~œў‹ƒжтPК ЖЪЯт•A/ Л‚щ R™'K‡Уk>СэыŸТ˜~l —МІПГЙ IјГы$уmъ_‡=^ЗђV`]Ї>"@€ћXH sQsЕАЧП3ћЙнЄa Ьy\Х<"2\т566зДћ)!c^2gіФœЬАˆHЭж щЫ+сЁЎ‚ЋЪКЇюЌMехˆ7yЌBbъJИ'­Х’˜C‚р(П’‰_ў}‘‰Р=t2цFх NГZ№”фЇlРŠ„EhЖš IDAT>ˆœ6ЈN3КЌ=ˆM+EЈІ‡сš ОѓУрсlš>­ЦuќИ?™щ8–žkьŸCя№Diœа7ъ$œ˜оЮЂиЋ@{;пУ†еS№Џ9oр7.–˜XYнoNЭZ‡ЏўHЦ” oћЎзсћД$,LCќюЭыыНЖi™IXxїгb­-•ІnzX№hЭ^—Шщp(Ћ p*­Lq" ^_Љ@ОЧoчИшыу•:оЩŽ–?­:YчЉЛD€ЏИƒ­ :šnA_ЅV $TЙЂi‡€ —:у§х,PjУž%ЮуzQ <НšЖiїŸŠЌ ЙiЌеŒЫkэTqІ Q;SБьЁ^‚щ˜MёзшяpёѕбТЙLЦѕоЉ1љн­ј9)Q!—Q–yяOC€›%k]ю!,дЌФ˜X0QД •/цl~ЦЂыеШСšeЋа—Х|ЫЫ‚J^F€Ÿ?†x)qjL4Сƒ…ђ’O)žХk‹v‡оџ HЖWМіыwHaв-ўОpTШс?щv$mЫekžFњ Ќў§-щ^TгкKbb™­Hl Йg(DЙ№ˆ„–y€ў`qв†єы&dе}`+uMЫ>ЇN0^cЧ;йDьЃю"P—Ÿў:СМB,dšŠ™p9ђm%Ц„[юj]ЗІ˜угЧ?уŒ­LёuH Ѕ"ішНЇWчwЌПљ~Ъ>ŸбЂ їПеАЪ††нь|ФеЛ‡БОмЭ‹y„NЁˆ-bЎlEеs’Ї")2}Z‰ЧЦБHАfI{2a1_Ÿ€wdбЫNrŠіУcяŠУXLЯVБёъLТ™_rB8ќ‡Й Ѕt•fЂPс"фХ†LŽќOпЈŒbˆзыглВ<яЯ6квKmђЃŠ @U7 c­;wЕ(Š>эй,g"iІ‡e{RЧьnМRЧ:й‘Q'ћРЈЛD€д%рбЭaw+№эг—zкžJі4™NN–^†КЕХœюž‚Їˆ|=›SП(т1ЭiШBчЩїъVƒ{я4ХœП;TзfwR˜ІВj*ЎВEдw ‹‰ЦПю-ѓŒМљЙuс‹Б'k<" QЪJГ№<Т7}„ѕ ,ЊЕє„ЧЌ‡$FЬUоІВоП–Œ`Km&<БV_Нњђ“йbAљ:&Н™ю№pFzЙIœ9ВEп\lѕЋ%РЬЛkэћfѕ‘ЏЏ^}yжіУЫuўŸ:іH•њDˆ@ЛŸрdБш[r(Э$ЌщГZ&Š ЉџЗ"п­њVHY™zD†н^ˆkѓlПгG|ћr Еа^ЬBЪœtє^9оuŒА'РGуkЭR|[sŸя…W4Џ>ыqhU,[щS1lІ+'#йYШЩ5LxUтаі}8[dђќ№5D—sђ‘Ÿ›Мгy,pЁИPšyјJђ PRеє:)ѕА;0Їїl ђиоGкЂBфdц ‹РыtП‰ŒЦlЉoѓcžЋ49Ьl §R"lб,d.ћN3ЁZž‡Эšuшїфt рSj`МЧЕŒC8˜Qh$гдЙБ`О!Aд№Љi"@Z€+[o2&мђљщЏїU ЌЬєKлšжфrfўM‰ЛяГДХыvЦЈїѕљЅљхPїѕ…ы ијœшВ6Џ>{ ц•д0ёІѕ…АоГq т)Ќ[6вPмr/qJ“?fОyоћWМЗz,– …ЦљAќ{ьуXЗjД№”:УxЫћзaѓ.УТ*+ЮЭ0vи[лЙеЖЛE‡u•&D 3рǘ*ЖИЇ’M ”•БаZ-JKKQ\\ŒЋWЏbЫ–-иБcО…qб-b™ЖЏХоDЙйF{у&)иžCѕЏНhЊБC+№яdЖђФp—єэч€'–ІqšЊlЧзЙwШmx8Ј”(>rЩG\o‘5yжK‹mšћ€mi˜ G  юн;žОœ?иЎ„ZešЪk|LzцbлG:ѓ:ЭћwdВпА-])ІЌ Ѕ™sRЫvцОЩdЇЗЛ(†L†Ќ~зБуЕК›6 DтттАrхJDDD`оМy№єє„‡‡мммрттЅ’Бd/GGі4ЅљfeДDЂFра%"@:>хuЯxЫ…дщl]Qs#еы„йѓTьi5‘У­В9уkлœQњуYA Ьёgmž-џ"*ВЊpUЫОшхjЛCМяŽ*Е bHЈuwїVCлRКYŠ!^ZэнэЁд|1$ДиЁух=ш<ЩL‹vžNSO‰  =–/ЎЎ`"H,QСОгіVрiЭћuћp9ц?щŒФЗYагl ˆ-vUђЇ:q8аA№ ‰CјC8X›g§А•xрїžтгZжзЃ’D c‡ЈcИSЋD€Д.VТ'Zz‰ОћІ%ХЭ_эзŸ?–Џ†gЎн" ЋлП™YGxьo7kЇІЬЊв["аHutj’Ж%v—ю&/N{иŒoжи’дЃЇƒАW‘ТјxtKЌе­ћхš=иМxKн ”Cˆ@Л Aд.˜Љ"@к“-у&[z‰О?TеbяŽЋ›И0j‹$—ЫQMИДZВIЌ"@kˆЌТD…ˆшlю%ь^Z­g[Яьg_џч/|3—ЖKwM“+З­Ї‚W ИT nj[нІJы Вёхч5їxлщ]__ЪіrS7ћiЊІаu"а;§_ЃЉnгu"@ˆ@уYгё,№ыЧˆћь№вGЋ>Ё^R\аFL886пфЗ g#–ыПЄ§F‹›7йунж&ѕмљ!о–T…‡pH,yЖДyв]ј/FŽe‚Јж5ѓrэўžm2ИясЫm =ѓПъэ{Лї‰ьВHuйžNn}Уя O˜\чЂј~B{ПаaˆъTђ@™ $U7‚g oрЊѕй;’ХВS#Muђ‹L'ьяcb\ˆ7nЂRgo…ъ=aДГи\Ї&#Rг КJ><™рЩлў2Ђ? Сg;&‰1П Жс`7АC&Жѕь‰80щ}ЌzДПЁl*О˜0w-жBСcСДіЋ;KMwAЭџ дaб‰ш\du6eЬњAѕ щ Йўё ИЋёыѕзВЬхbШїЕџCя…€ПчBHC\§МіNМš‰.л„ŠЈфѓz6$ОйВgo_xњxЃ—_/іъ}жNL™ХТMьŒAЈ,ЩYl*Š%ОkђхУћёЌ,йpЌIЬ6юК aпsK„ќВ%и—%MнiБ;њylлs‚B1.h;Jи^ЪЛ,Arzv.ˆъЬ]‚ќrЁіЇ~[9‰ЏciRvЭzaВ—ХАђ^˜М юџ/1V–d‚ŽD  ъшд$ эGрЯУсуkyЋ;іƒ}ФчЕ{вcАКљ˜"ДзОомs.‚ЄЗqЙрЮŸ?‡элЖ7з$јьWісуШ<šŒЏŽ ёНдƒF"~ў`&ЂАёШKгGм‰ЧЫZ4юiю|VOСПцМСТYpŒЧž{qЋру?ісэѕ@ЌfЮh•—вБzвуИўПЏрѕ­wБрЌ,œжхˆП{6Ошѓ7$І.Уї /cЯO\D5lЋwxЂ4N,bќ H81НMž ‹(ѓЬ %"аhЪЌ#ЈS›D€ДОmџ„‡œАuЃб…“?ы1њЎ~РХLЦл˜рцgMЖуй7в”™ф!т™_ §{RїЂМœѕkjѓ[њ,z=~ Ќ,ы44л>У 6Ѕ юM?Œ ІЬДDћё'ОADА;єўg€х{ХЬђпАmU!Fl 9КЫ|@/тxіSшT”T QцWЃЬk…МЋпЧ–eСЬ†БoaЯб?0'ˆEъhРVd ?†x)qjLыпрц˜j6"@‚ЈР’Y"@ь‡Ралх№р€м3&ѕs№€ “ЦєAоqƒZ`нэ;В/”jЫЧѕ[2 .„”(Z‘ж ёГЯ№>&ц7ї/Ÿ2{&3 Г-wсЎ‚ИMЗљœТс?LєŠеіШ83;ЛЃџ†4ѓPrlя&ž*X„ј‘Ѓ,E"Я7iЈX€џэaђР5lKЯЂК3”ЎсЕ[&ƒєŽД?DэЯœZ$D p/QТ?L^ЂгЇє(пJїBшJtpщс‚놧Љеz™1w˜‹ fНЂJ­N =[/єщg;ёѓ#пmъ*+Pmу"БГцВЇсюWs‘TЩIэА#Lј№Xђг“SБbzЏZФѕGТ‚mЫKѕхС [–VФ3~S|гF›^жз&хкLВОі:'D€мBњЫ1hЈe‰}ЛЊ0`L?сСІwїЗ:*vSXr7рЬяЙјЯоЏp0-ЧŽЧ/Пd#їмy”k!Ћr„‹“Ў\М^–ПJKKQЩVл’јЂ+gsQ˜›МгyТЋ„k>Ѕ+nfžCn!^MtѓЧ_žєФ‘kp0ЋˆХjг"?+yEMжДА,єМ)[ЬГT’_€’*ЩЖ%,ЂћХГљ‚­kч q­PZаmažNˆ@› Q›#ІˆАмKєћЩ2cwЮŸ­ЦЅыn:СnоЎЦ|ўцвE=nѓБP8Iџє˜pх‰№Х(..†Ћ‹+[ІФ<3ќ™CЊЉfТ ЄWЎ^EњБќђЉ+lDrx1ЯЪ–ˆ™и"fЧ%lа_юŸЩv$ŠЦŒžIXrфЬP‹O™IХNТSgтЙ#ЦОўbƒEšpЉb3У—эР'kЫДњђ<•ќыЄ1[jŒX1ё‘‹1і5У~IŠ3ˆэ9ƒ-їЇ2Œ‡Зf>џщQдПфни=zCZ ЂVGJ‰АW}ћ9" айY’‡јЯП+А(Fм ˆїћЬozьa{н`O`-[ЩŸЉj^z+=ЎeCвБХе••†…;ждS ЦŠšXQoй‘X_љДLћ)н”LІDтxi3$хаvaЊ)їFФКї0ё%бЃЄ4л1:’ #ЫЄ†e;?№-kСБењџс‡ВЙаБЅоjaУ№СX_“!еЄ#шP$ˆ:?5Nˆ@{˜№ D&/бХ ер{uѓ”с?_T чЄ(–йнБ†yuјSjэ‘ЮŸ;ЧІЋLkœZмІœ‰>ЇfCтBЈЕRCЖUjД^+­е[ВCDєЏ€.E WG…Шёг ггNЩџ,GE­MЂѕьriI м=кG}vђ“.ѕ9а`‰€Н Eеіі‰PˆhsуА|ДОЖ’:PtЭДюGЪыˆуЙs5x$\/vŠоЋGю­ТЬёе˜9Ё3яЏЦ†ШПh}э>д&h ф!j ŠdƒNC шZ5ўЇі2сњЛ•ѕыoћТъњ­5?їѓ­nx,кnЭХClщЯGљСГЛrРЖ†…'љЯexњ‰Kˆ^\‰ЛюЁлzѓISЭЎL€ўЯщЪŸ>t!ЅХе8АЇGП­d{Y7№ыvт!ђљ“ƒќœ!WѓшЌUаИB{ГъЅХy2м”;Р#Д/6mИР‘•ƒГ•"]†M™u™šJК.єЏ*Аz…‡ПЖ^ qZEWэdŠuУ‘yƒ˜3HHљ,œFкБы№ННS&ц#4 .нршЮ“$Ж%пcшZ‘ИЙckєJ_›ПFЁiљWk˜mUњR+і~jеЩXk AдZ$Щ vKрісrxtЗ}q4Ÿ^Г‡tщZ% oж J/ ДУЇ+qђš oП[ƒЅЯ+pќДŠшйŽлm•ВзOЧ}šdмДЂМ”Еа(B1Іg8ЦzŽТ„Љ‰8ЫуŒд“ДY;Ё‘ ЗxMOaвъ&н…№bє[Ш7=$XЗPGфTbпš7Б8hюp_Œ_+якЌэ.›ŽL1КJGє–кl€ ЂРP6 ЗO/ќягjјіГэ–g/SfGcKКеZq:,ПDїн№k‘dЗљРIщˆМƒчёіжЖp>SV`Mт!к}Sџ2TОw"ёї4ќPѓ#ŽœMРа№OЯ6P­‚m9ВїсрћАї\*’>™ЬЭзaпьpФl7ЋЇPАВ혼kРT;dыOЇbЄьyфXxЉЊPщбцN6МT№8HЎ§УёўW/СOи‡ЉB”н!lЛ;tHЉQ"@ˆ@Ы ИИЪ0Б3† Г~‘ДНxˆиЗ,.ьсŽэьЁ@ёЙ"Ф?qqѓ.`ѕучёЯ*рсnЛЬDV‹] – љР1l %xlІЯоŽ<УжH%?DbЪ)&S€’Ѓ)˜&›‡нYR˜ь^‰—ssоЁЃ<А;лPї ТНс.ИR`p‰”чр%й4ь>iђq‘г{7<}МбЫЏМНеШI|K“ŠАkжУ“НŒlЖQ&OpХхУћёЌ,XшуšФlcx]nжЌгwнщ§˜{яZьKй.\лšQнщЏ™Gg-Ѕл`Ћќ,^єЪБ 1!!˜О UєdЩ{aђ‚LИџПиžлЕ\?ЕЦЋЛt ‰ёћqMT3Lк ЂvCM "абœ”2ќuЁ !Ёж=OЂcb Lл№Џ§іŒ­rve!P ‹ˆдl­ОМъ*ИЊZouехˆ7yЌBbъJИ'­Х’˜C‚р(П’‰_ў}‘‰Р=t2цFх NГZ№”фЇlРŠ„>ˆœ6Ј]жФІ•"TгУpMпљa№p6 гj\Чћ3™žcщй‚Xш(њFН€„3алY{,аЧЂqO#pч{иАz ў5ч ќЦХ+ЋћЭУЉYы№е٘rс-cпѕк"|Ÿ–„х‘iˆпНc}] з -3 я~CЌЕЅђСдM3Q6Гз%2A:œэЙmJ:<ЗNВoeйE|{0ЅScЬы˜ЂŒ6%`н]ЁMЛ@Ц‰ эG€/NўŸПЊрцЁcп7*ƒ{‰œеІ/яіыЉYKВ(фІ/[‡jіmЪђZ;UœЉBдЮT,{HŒzГщ ў§.О>ZhJ&cњ я䘝юVќœ‰ЈЫ(Ы<ŽЧїЇ!РЭвCЅЫ=„…š•Г &Š6ЁђХœЭЯXtН9XГlњВЉІМЌ!ј фeјљcˆ—ЇЦAŸбЂ їПеАІХœ­фЛ3yїё0V“Лy1а)БEЬЮЦ\УUЬIžŠЄШєyh%gŠЧKhOІ", сы№ЮЂ‘ž”кІф,э‡Чо­%0є,Ј,ЏЮрJ1TrB8ќ‡‰Ё_-<2 1ю\lШ$ЃљОQХЏзЇЗЙ?‡Ў ЧŸmДЅ—М@ќЈВ€Ц†mxгs_CЏиа,­‡ Ђz P ]ƒР˜p'ИБu7'ъм›ШжyuЋСНwš6“М;”Џфi›фЄ0yУj*ЎВEдw ћbО^Л9Ж6цШЯ…м _Мˆ=YуhˆRVš˜€чОщ#Ќ_PЛf‹Ю…5:ѕ‰‘Ъ›ТTжћз’lЉЭ„u>ѕеЋ/Oш\cЖX^ОŽ ŠКbˆMjŠcЋчZcƒnˆycuшZы 5D­Я”,"а‰…(№З'TP60§aOšeeъvSx< zLЌЭГхЃpрˆc?BNЁк‹YH™“Žо+‡УЛŽіитh|­YŠokŽтяѓН№ŠцУТg=­Še+}Њ1†Эtхdd#;# 9Й† /іˆњЁэћpЖШфљсkˆ.чф#?7yЇѓ—[(.”ОR’ќ”T5НNJ=ьLФiФ=›‚<Жї‘ЖЈ9™yТ"№:нo"Ѓ1[ъ띘ч* G3лЦ~щ…=—.žЭ,_;Wˆk…†чѕŒзМyы™›зЂїmA€Q[P%›D€t*ƒ†ШНФЎѕ<ЅeёЬ^š_u__ИˆЯ‰о!kѓlњ X0[~ТДžЃж{6D<…uЫFLИBю%Ц€+м“€х АjџЃpg“aузП‡щи‹˜Ѕ_Бњ:\љЕ@Ј?n&І…ЬФŒйˆћјДhЇќ о˜Е ‡ЯJ/'&rАH3 њMТ”Aтс~ЏВ…вЮБb&NНЖcбШ4ьэ#xg =rT8‰о~ЎŒ9obXТЋ˜Ті> ѓ'5>f^ЯPнTзa,г˜-ŸaˆђРКqbrШЧтSfхgлs""ЖА}ФПЧТ€ёˆМяK’ЈЮxХ'хЄ> QцЦRєІШjXj‡vЈ "@К(~‹ЉЊbћДАЉ†ВВ2hЕZ”––ЂИИWЏ^Х–-[АcЧ,|1 уЂ;”в5ц‘xяЭ2\-4н}§№ФrУTPѕŽ{‡м†ї‡ƒJ‰т#'‘|ФE№Y“g}—ЕиІЙи–†YЬуСˆ{їŽ7яЛО\Ы$–j•i*Џё1щ™wˆmщЬыXЎjМ^}WЖЅ+eТ”ЕЁlбТћd^ {Ъ DтттАrхJ&B#0oоіrtd™ВКг›ѕ‡ЛжЏiњдњЖЩ" D Sр8>Ц6p 6lрh ЋлЄ#Мі‡З›ЕSSmпЃ[ПbnOŸ1 "{њ4Ј/D€и aЧП(qЯxкубћ/зьСцХ[ьfќд"аеа”YWћФiМD€XM€/ЦœќАКrг"kЋ+лXP.—ЃКэ›ББWTœt$ˆКЮgM#%D ™”6ьH|з4щ1uл{*xŠKЅ`ЉЖеmЊДО _~^€QsяЗНнѕЋt(aћUЩ•№ДƒЇкšbIзo]ііПЦ­KšFFˆ€нЈжW7йЧцЏ(№[аГIћЕ hПбтцMіИИЕ‰GQw~Dˆп%Uс!0Kо…ІVШн…№bєчј№Q&ˆj]“ъvФ1/e-ІD&›юё$6§ѓ1єЗЃ>;Gony$ˆnљ˜Hˆ€9ъъjœиžJ­iЇdѓыќНЊ=cxэl›Яw$‹UІFšЊц%™Nи;пЧФ87nмDЅЮ–ьyыыёдdDjКAWЩЧЃ‚'yл_Fє'!јlЧ$1†˜BС6!ьЦž”ГhКOиюжГ'тРЄїБъбўBл*п;‘јћ\ ьнЙcˆщ|zж?&^oчRs]œ@ѓuqp4|"@:'єеЏбЮИЋх_Ш\ љОішН№№ї\Ibˆ‹ ŸзžТ‰W3Ббe›а—ŠŠ Tъ›QaоqОyГgo_xњxЃ—_/іъ}жNL™ХТWьŒAЈ,ЩYbШ О ѓхУћёЌ,йpЌIЬ6ют aпsK„ќВ%и—%MнiБ;њylлs‚B1.h;л}Y‹] – 9= ;D uц.HA~ЙдГњmх$ОŽЅIEи5ыa„Щ^Т|x‡ŽF0CќЙ6uП мю‚+7$Ct$эJ€QЛтІЦˆАо{РЃ1Нvz іB7SФїкз›{ЮEєт6.\ТљѓчА}ліцšŸYЪ>|™G3ёе1!^˜zаHФЯЬфO6y cњˆЛ5ѓј[‹Ц=РяaУъ)јзœ7Xx ОŠ[cЯ=‚ИU№ёћ№іz VГg ДЪKщX=щq\џпW№њжЛXАW ъђ Фп=_єљS—сћ„—Бч'.ЂЖе;<Q'єz 'f ЗГхюСКЌ=ˆM+EЈІГC‰Д?š2kцд" v@`Иўјс“ŸРi“Ѓ“ќТќŒч-yУЇЩv<ћІ`Bš2“Ућ@˜˜пмП|Ъь™Ь$Ь ДŒйUqкЩ|Ю с№&zХtlчmѓфЬNvGџ iцЁф*Х,ОлШQ–"‘ч›4дd‚…<‘RУЖє,J§l'~~фЁM]eЊm\C$vж\і4м§j.’ИЊН…><6§єфTЌ˜^л;#Ў?Њl[кЎ/VиВАRš˜€чдzЃЪЂv#@‚ЈнPSCD€иGЙ#Œщ‡ьдSpwЋЃb75ŽмЭ8г=e,"К““дjgИИКР•EсveбИхЌ]ЅW.^/Ыг@E)*йТj[_Ctхl. нЛЁМJєМxАEжPКтfц9фjсянDФz7ќхIO<ЙwgЎРƒ•И–“‹Њ>ў№€ГЊKBЯ›ВХX[Іе—чЉф_'йRcФŠ™ˆ\ŒБЏё§’жуЪЏB{ёуfл \§Ol[Ц/Q"эL@VУR;ЗIЭ"а…№[Lѓ^TVVЂЌЌ Z­ЅЅЅ‚XИЪС–-[АcЧ,|1 уjЭ/u!NON\†’ызёў‘„ж5Ÿš+cЮ"7Ѕ№XЛ5FuЅl*TКЉ­Ўгн†lщЫЕаБ•Bj‘mˆх7N Aˆ‹‹УЪ•+yѓцСггpcXц‰U*•ТЫбббjЯ/yˆчNW‰ эBрќЙs,fšq3Ÿ–ЗЩBaЈљœš ‰ ЁжJ йrTЉбz­ДVoЩHбП"@ˆ€јьф'vа ъшКHuнЯžFNˆ@'!pю\ žSGŸŠpФ#їVAЦc­9АЭ й”фrD>ЌG/ЫЭ;Щ№Ј›DР. В‹:Aˆh˜Рч[н№XД'>мšЫ№пQ~,2МrGj˜(њЯexњ‰Kˆ^\‰ЛюЁлzУ$щ h˜€i7­†Ыа"@ˆш@>RbŸ3фj…а M€+ тъ€Сй"uynЪрк›6Xnаи]ІІ‰@Ї#@‚Јг}dдa"@Кі,А#ѓё2žђY8Дcзс{{ІLЬGh@1\К;Сб]LbЉўЫžr+),ТЕ"qsЧжшО ;7BЫЭЎ[УtЫmДСx[о)В` DЖаЂВD€ pщZ% oВэ єт.)‡OWтф5о~ЗKŸWрјi(5аГЗл*eЏŸŽћ4ЩИiEy)kЁQ„bLЯpŒѕ… Sq–ЧЉ'iГvB#nёšžТ"ЄеMК ?рХшЗЯЖАЇdЫxodmЧpйtdŠбUьi]О/$ˆКќ?@ˆ€Н8rИ[вuЈжђ]‚И‡Hїн№k‘dЗљРIщˆМƒчёіVГHЕ­<(Ÿ)+А&qŒэО)г*п;‘ј{~ЈљGЮ&`шЮ јЧЇgЈVС6‰Œ йћp№}и{.IŸLfцыАov8bЖ›еS(XйnLќ5`ЊВѕЇS1Rіiђq‘г{7<}МбЫЏМYИ‘œФзБ4ЉЛf=Œ0йЫШ.Нc|ЧэЫ‡їуYYАаЧ5‰йТf’Мa]nжЌгwнщ§˜{яZьKй.\лšQнщЏБ8h-Ѕл`Ћќ,^єЪБ 1!!˜О U№dй2^нЅSHŒпk‚ jœЙ.к‰ ЂvMЭ"@šK@Цж9ЛВw ‹ˆдl­ОМъ*ИЊDЏQsm›зЋК|ёуц#я‘UHL] їЄЕXsHхW2ёЫП/21И‡NЦмЈФiV ž’ќ” X‘а‘г™›оыВі 6­Ёš†k*јЮƒ‡ГiЇъj\Чћ3™žcщй‚Xш(њFН€„3алY{,њйЂqO#pч{иАz ў5ч ќЦХ+ЋћЭУЉYы№е٘rс-cпѕк"|Ÿ–„х‘iˆпНc}] з -3 я~CЌЕЅђСдM ­йы™ ЮімЖLMЗВь"О=˜‰Rƒ‡Љ1ц––щЌ­ аѓ™mM˜ь"@ZJ@V…\єpSеьл”хЕvЊ8S…ЈЉXіѕ>fгAќ5њ;\|}Да”LЦѕоЉ1љн­ј9)Q!—Q–yяOC€›Ѕ‡J—{ 5+1$f#LmBх‹9›ŸБшz5rАfй*єe1пђВ†рƒ’—рч!^JœM0‹ўЪ’фSŠgёк"‚нЁї?,п+^ћѕ;Є0щп8*ф№Ÿt;’ЖхВ5OЃ;Џў§-Œ(Jэ%Ёb™­Hl Йg(DЙ№ˆ€Zг^жŒWqОOšѕkŒЙ/}C‹R;§%мэšš!D€4—Р›8рЇьѓ№-Š pџ P ЋlЎЙыё Ўо}<Œзхn^Ь#t ElГГ1з№Fеs’Ї")2}Z‰ЧЦuЗ(Ё=™ŠА€„ЏOР;‹FжёЄ˜–ГPД{З–РаГ ВlМ:ГХ:Ќ’Тс?Ь]ЈЎЋ4… !/6d’бtпЈŒbˆзыглвŸУѓўlЃ-Нд&?ЊLа–ё;Шо4ЦмзЦа+цvщНэHйЮŒj"@к•€WЗм{Ї)цќнЁ|%Oл$'…i*ЋІт*[D}zБ/цыЕ›ckо‰ќ\ШН№Х‹и“5†(eЅйˆ xс›>ТњЕkЖшМl-R-1"ЌМ)LeН-С–кL№,еWЏОМ&mБ Х|&1„ŽЗ!ц-E•m&@kˆlFFˆ эK +SША›Тырбcbmž-=uрˆc?BNЁк‹YH™“Žо+‡УЛŽіитh|­YŠokŽтяѓН№ŠцУТg=­Še+}Њ1†Эtхdd#;# 9Й† ЏЊBкОg‹LžО†шrN>ђsѓ‘w:yЙ…тBщ+е(Щ/@IUгыЄдУюРDœFмГ)Шc{i‹ ‘“™',Џг§&2ГЅОЭyuвpф0Г-єЫіёš7o=sѓZєО- j Њd“"аŠ^š_u__ИˆЯ‰о!kѓlъFI ?aZЯQы="žТКe# &\!їrоюIРђ„XЕџQИГЩАёыпУtьEЬвЏX}ЎќZ ”‹7гBfbFШlФ}|ZДS~oЬZ†Уg%—“N9XЄ™„ §&aЪ ёpПWйBigŒX1Ї^[ŒБŠhdі1М3†9*œDo ?W ЦŠœ71,сULa{…yŽЧ‹Ÿ@3ЏgЈnЊkШ0–iЬ–Я0ФFy`нИ19фcц}ВuМќaAцa’RЃЬЅBtlВ–кЃ!jƒЎI€пbЊЊЊPЩІЪЪXЈ ­ЅЅЅ(..ЦеЋWБeЫьиБ _ŒЦТИшЎ Љ‰Qsял№ўpP)Q|ф$’Ио"kђš0mvY‹mšћ€mi˜ G  юн S`fЅкћ­ОœK%д*гT^у}а3ял>в™зБ\3дxНњЎ6lKWЪ„)kCйЂ…'іЩМ>і”ˆ ФХХaхЪ•ˆˆˆРМyѓрщщ ИЙЙСХХJ%ћlиЫб‘=)3›оld ф!j]"D€изЖ9ЃєЧГ‚ ˜у/tЩк<[њ_‘U…ЋZіE/Wл…т}wTЉmCB ЈЛЛЗ‚jм–в­Ѕbˆлg‹ЊэЙиГЎїЗEкЖысЂ"аšЌ§хжšmvF[:^!БяkѓЌЏќў1аS|ZЫњzTВљˆyѓй‰5[ѓB‚ЈЅŸе'D IЕoZвЙtlвhŽ№иПкЁ&LˆЙ‰EѓпёћHэ{IэskЌ“ В†•!D EЄ›“tфЦЬпѓѓžјјкJD€–ю/вб{Д†ШJT†V!РoNв Jz/ЗJd„.EРќ>трр`МП4yˆšCъ"`3Iј№#Пqё„y:x№ №фˆЭ†Љ ]ŽП_№d~ся%$\Дё "Qq"@šO@КYё—t#suїdљњыЏС_”ˆ жриЫхrууѕ’(ВЖОy9Dц4ш= mF Жт71…BћяП:зЏ_Ž|П"ўвыѕТ‹яcDлЅЕйЧB†‰€]0ї(ѓ{†tпр{ uыж 'NђЄYв}F:к28DЖаЂВD€4›€tƒтG>U&ниј†jSЇNEII nмИ!lмX^^ŽŠŠ Ѓ0"AдlьT‘tjцї .‚œЁVЋС=Ы|FО#џaХя'в<ЏгœD‚Ј9дЈ V0BќWœљЏ<'''ЈT*С3Ф=B<ё›ПСq/псšчK‚H:Zн8$D гюв(~ПDFќХЯљЫ\5W‘ ъДџTЈуD ѓ0џЕЧ…П‘Iгcв5~гу7:IUWWQч1ѕ˜–ю ’(тї ў#Šп#јњ!ю-тї ўтїZCдкT—6'РojвПtcу70itчё›Ÿ.“ЎI‚ˆМCmў1QDРn№{‚”ј=CКopOПOpA$ #.’$AФЫIїs’­ЦŽф!jŒ]#D е№›ПYqУojќШ“”ЯнIы†јTё2’ jЕŽ!"@: ~рG:’ тGЩ[d.ˆZт%"AдiўYPG‰@ч' нијHЬЯч78.‚Є)4iэTЎѓžF@ˆ€­$/tяр‚‡‹#saФНCќ\КЦыHѕli‘-ДЈ, Э" §Ъут†пиxт71žЯonќeютbˆ—х/š*krЊDnв§ƒп;јK>ќШ_\ ё{/•сuјЫ–D‚ШZT–d„Ÿs!$ "IIBˆ‹!D-:ЎI@7ќ( ~ЯФ?ђs)—kN’Б›MMs*R"@ˆ€­$#%d>=&]“ŽЖЖAх‰ИѕHЂˆLEќШѓ%!ФЯy2/+dXљ‡‘• Ј ­C€ žИтI>’WHЪ.В?R9щœŽD€t’ЗЇЖШ‘Ю%Q$•“DQs‘ j5ЊCˆ@‹ HТˆЊOє˜_oqcd€[‚€$|ј`Єї’8jщIЕ” е'D еj5”dˆмВ$!дкЄEе­M”ь"аlmuЃkv‡Ј" ]†€ИЉЫ —Jˆ D€КHеeB9D€"@ˆ@#@‚Ј‹}р4\"@ˆ D .Du™P D€"аХ ъb8 —"@ˆЈK€Q]&”Cˆ D€t1$ˆКиNУ%D€"@ъ AT— х"@ˆ ]Œ Ђ.ігp‰ D€Кў cѕYр[g,IENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/ipcopAdvancedDialog.html0000644000175000017500000003331711733011756025074 0ustar sylvestresylvestre

iptables settings

Most of the iptables options can be found in the man page iptables(1) or online on the project web site at http://www.netfilter.org

Tab Compiler

Compiler

Full path to the policy compiler executable. Use this if you do not want to use standard Firewall Builder policy compiler that comes with the package or if you want to wrap compiler in a script.

Command line options for the compiler

Additional command line options for the policy compiler.

Output file name

Specify the name of the generated iptables script. If left blank, the file name is constructed from the firewall object name and extension ".fw".

Assume firewall is part of 'any'

On some firewall platforms there is a difference in the configuration command used to control access through the firewall versus the command that controls access to the firewall itself. For example, in iptables, packets headed for the firewall machine should be inspected in the INPUT chain, while packets going through the firewall are inspected in the FORWARD chain. If this option is ON, the compiler generates code for both FORWARD and INPUT chains if it sees т€™anyт€™ as the destination of the policy rule. In other words, it assumes that the firewall is part of т€™anyт€™, and packets may either go to or through the firewall. If this option is off, the compiler only generates code for the FORWARD chain. Compiler treats т€™anyт€™ in the source of the rule in a similar way, generating code either for the OUTPUT and FORWARD, or only for the FORWARD chain.

Accept TCP sessions opened prior to firewall restart

If this option is ON, the firewall will accept TCP sessions opened before the firewall software has been activated. These sessions are special because the firewall never saw their initiation phase. If this option is on, the firewall creates an entry in the state table when it sees a packet that apparently belongs to the unknown TCP session.

Accept ESTABLISHED and RELATED packets before the first rule

This option generates an implicit rule to accept ESTABLISHED and RELATED packets before the very first rule specified in the GUI. This helps to reduce the size of the policy script generated by the policy compiler. ESTABLISHED packets are basically reply packets coming back from the server to the client. Iptables keeps state information about each TCP session opened through the firewall and thus can detect and permit these kind of packets automatically. RELATED packets belong to another stream somehow associated with the initial stream opened through the firewall. FTP protocol is a good example of this situation. FTP uses two TCP sessions: command channel and data channel. You do not need to add a special rule for the data channel to your policy because iptables т€™understandsт€™ when it needs to permit packets that belong to the data channel that has been created per request sent via a known command channel. This option is ON by default. If for some reason you do not want to have an implicit rule to permit these types of packets on top of all the rules defined in the GUI, you should uncheck this option. Remember that in this case you need to add a rule to permit these types of packets yourself. You can use the Custom Service object named т€™ESTABLISHEDт€™ in this rule. This service object can be found in the т€™Standardт€™ object tree.

Drop packets that are associated with no known connection

Add rule on top of the policy to match packets in state "INVALID" and drop them. This is implemented using iptables module state with option "--state INVALID". Additional checkbox makes generated script drop and log such packets.

Bridging firewall

This option changes algorithms used by the policy compiler and makes it generate script for a bridging firewall. A bridging firewall treats broadcast packets differently, never uses INPUT and OUTPUT chains, and has some other differences.

Detect shadowing in policy rules

Rule shadowing happens when a certain rule is a super set of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. For example, if rule #1 uses the network object for the source and rule #2 uses the host object located on that network for the source, rule #1 т€™shadowsт€™ rule #2 because any packet matched by #1 will never be matched by #2. This may be important if, say, rule #1 permits and #2 denies access to the same destination. If rule #1 т€™shadowsт€™ rule #2, then rule #2 will never fire. This situation is most often an error; the compiler can detect it and abort processing of the policy with an appropriate error message.

Ignore empty groups in rules

Compiler supports special case when empty group is used in the policy rule and there are no other objects in the same rule element. Depending on the state of this option, it generates iptables commands as follows:

  • OFF: Compiler treats such case as an error and stops processing. This is because group with no objects is equivalent to an empty rule element ("source" or "destination"), but empty rule element is normally considered to be equal to "any". To avoid errors this may cause, compiler considers this situation an error.
  • ON: A group with no objects in it never matches any packets, thus rendering the rule useless. When this option is turned on, compiler just throws such rule away.

This is useful when one needs to control access to/from a group of hosts which may change and sometimes becomes empty. When this option is turned on, compiler will automatically disable the rule if the group becomes empty. Group contents can be managed manually or by a script using fwbedit command line tool.

Enable support for NAT of locally originated connections

By default sessions initiated by the firewall are not considered subject to NAT and NAT rules are not placed in the OUTPUT chain. However if this option is checked, compiler finds NAT rules that can match sessions initiated by the firewall and places them in the OUTPUT chain as well.

Clamp MSS to MTU

This adds a rule on top of the policy with iptables target TCPMSS and option --clamp-mss-to-pmtu which automatically clamps MSS value to (path_MTU - 40). This iptables rule is added only if IP forwarding is turned on in the host settings dialog. since IP forwarding for ipv4 and ipv6 can be configured separately, rules with target TCPMSS for iptables and ip6tables are also added separately if corresponding IP forwarding setting is enabled. Finally, this target is only available in ip6tables starting with version 1.3.8 and compiler will not add it to the generated script if version is set to less than "1.4.x" in the firewall object dialog.

Make Tag and Classify actions terminating

Normally, iptables targets MARK and CLASSIFY are not terminating. This means iptables sets mark on the packet but does not stop inspection process and other rules still inspect the same packet. Fwbuilder policy compiler can emulate terminating behavior for these rules if this checkbox is checked.

Default action on "Reject"

This defines what kind of ICMP message will be send back to the sender if packet matches rule with action "Reject".

Always permit ssh access from the management station with given address

When this option is checked, compiler adds rules to permit ssh access to the firewall from the specified address block. Rules are placed at the very beginning of the policy to make sure ssh access is permitted even if there is an error in the policy which otherwise would block it. Added rules permit packets that match both NEW and ESTABLISHED states to avoid breaking ssh sessions that were already established.


Tab Installer

Directory on the firewall where script should be installed

Installer will try to put generated script in /etc on the firewall, unless this option specify different location

User name used to authenticate to the firewall

This can be root or any regular user name. See "How to use built-in policy installer" on the web site at http://www.fwbuilder.org/guides/firewall_builder_howtos.html

Alternative name or address used to communicate with the firewall

Normally installer uses address of the interface marked as "management" to communicate with the firewall. Note that installer uses IP address rather than run DNS query for its name. You can specify different IP address in this option if necessary.

Command that installer should execute on the firewall to activate the policy

If this option is blank, installer copies script produces by the policy compiler to the firewall and executes it there. If this option defines different command, installer copies generated script and then runs this command.

Additional command line parameters to ssh

This can be useful if you want to use alternative port for the ssh session to the firewall. Just put "-p PORT" here and this option will be appended to the ssh command line.

External policy install script

Put the full path to your own installer script here if you have one.

Command line options for the script

Command line options to the external installer script go here.


Tab Prolog/Epilog

Prolog section

Add commands that you want compiler to insert into generated script here. Prolog section is added at the beginning of the script, before generated iptables commands. Note that generated iptables script is just a shell script, so commands you place in the Prolog and Epilog sections should be valid Bourne shell commands.

Epilog section

Epilog commands are added at the bottom of generated script, after iptables commands.


Tab Logging

use LOG

Use target LOG for logging

log TCP seq. numbers

Available if target LOG is used for logging. Log TCP sequence numbers. This is a security risk if the log is readable by users.

log TCP options

Available if target LOG is used for logging. Log options from the TCP packet header.

log IP options

Available if target LOG is used for logging. Log options from the IP packet header.

Use numeric syslog levels

Available if target LOG is used for logging. Use numeric log levels instead of the names "debug", "info" etc. This option was added long time ago because of a bug in iptables and probably is not relevant any more.

Log level

Available if target LOG is used for logging. This option refers to the syslog log level and is used with firewalls that support logging via the syslog protocol. Here is the list of the standard log levels: т€™debugт€™, т€™infoт€™, т€™noticeт€™, т€™warningт€™, т€™error т€™, т€™critт€™ and т€™alert'

queue threshold

Available if target ULOG is used for logging Number of packet to queue inside kernel. Setting this value to, e.g. 10 accumulates ten packets inside the kernel and transmits them as one netlink multipart message to userspace. Default is 1 (for backwards compatibility).

netlink group

Available if target ULOG is used for logging This specifies the netlink group (1-32) to which the packet is sent. Default value is 1.

Log prefix

Log records will be prefixed with a string you enter in this option. Firewall Builder supports the following macros in the log prefix that are expanded at the compile time:

  • %N rule number in the GUI.
  • %A rule action
  • %I interface the rule is associated with
  • %C (iptables only) iptables chain that this rule generated code for.

Logging limit

Generated iptables rules use module "limit" to limit amount of log data they produce. You can limit logging to a given number of log records per unit of time.

Activate logging in all rules

This makes all rules log, regardless of whether a rule requested logging or not. This may be useful for debugging but produces a lot of syslog data and should be used carefully.


Tab Script Options

Verify interfaces before loading firewall policy

this option makes compiler add commands to check if all interfaces defined in the firewall object in the GUI really exist on the firewall machine. Generated policy is probably going to be incorrect and won't load because of iptables errors if it was generated for an interface that does not really exist.

Turn debugging on in generated script

This option makes the generated firewall script print all commands when it is executed. To do this, compiler adds "-x" to the shell command line at the top of the script.


Tab IPv6

Order in which IPv4 and IPv6 rules should be generated

Compiler can place ipv6 policies before or after ipv4 rules. This option controls the order. fwbuilder-5.1.0.3599/src/res/help/en_US/iptables_Classify.html0000644000175000017500000000031411733011756024643 0ustar sylvestresylvestre

Rule Action "Classify"

This action allows the firewall to define QoS class for the packet that matches the rule. It is translated into CLASSIFY for iptables with parameter --set-class.

fwbuilder-5.1.0.3599/src/res/help/en_US/iptables_rule_options.html0000644000175000017500000001055711733011756025622 0ustar sylvestresylvestre

Rule options for iptables policy rules

Tab General

Assume firewall is part of 'any'

This option overrides global setting of the option with the same name in the firewall object "advanced" settings dialog.

On some firewall platforms there is a difference in the configuration command used to control access through the firewall versus the command that controls access to the firewall itself. For example, in iptables, packets headed for the firewall machine should be inspected in the INPUT chain, while packets going through the firewall are inspected in the FORWARD chain. If this option is ON, the compiler generates code for both FORWARD and INPUT chains if it sees т€™anyт€™ as the destination of the policy rule. In other words, it assumes that the firewall is part of т€™anyт€™, and packets may either go to or through the firewall. If this option is off, the compiler only generates code for the FORWARD chain. Compiler treats т€™anyт€™ in the source of the rule in a similar way, generating code either for the OUTPUT and FORWARD, or only for the FORWARD chain.

Stateless rule

Firewall Builder always uses stateful packet inspection if it is available in the target firewall. In case of iptables, this means it always uses module "state" by adding the following parameters to the generated rules: "-m state --state NEW". It also adds a rule to match states "ESTABLISHED,RELATED" on top of the policy. However, sometimes it might be desirable to create a rule without state matching. Checking this checkbox on makes the rule stateless, which means parameters "-m state --state NEW" will not be added.

Rules with action Deny are always stateless by default and do not get the "-m state --state NEW" parameters, although you can make them stateful by checking this checkbox.


Tab Logging

Options in this tab override the same options configured globally in the firewall object "advanced" settings dialog.

Log prefix

Log records will be prefixed with a string you enter in this option. Firewall Builder supports the following macros in the log prefix that are expanded at the compile time:

  • %N rule number in the GUI.
  • %A rule action
  • %I interface the rule is associated with
  • %C (iptables only) iptables chain that this rule generated code for.

Log level

Choose one of the standard syslog log levels for the "--log-level" option of the LOG iptables target.

Netlink group

This specifies the netlink group (1-32) to which the packet is sent. Used to add "--ulog-nlgroup" parameter if ULOG logging is chosen in the firewall settings dialog, tab "Logging".


Tab limit

Options in this tab are used to configure parameters for the module "limit".

Rate, burst

These translate into " --limit rate" and "--limit-burst number" options for the module "limit". If rate is set to 0 (the default), parameter "-m limit --limit rate" is not added to the generated iptables command.


Tab connlimit

Options in this tab are used to configure parameters for the module "connlimit".

Number of allowed connections per client host

If this option is set to non-zero value, it adds the following clause to the generated iptables command: "-m connlimit --connlimit-above ".

...per network with netmask of ...

If this option is set to non-zero value, it adds the following to the generated iptables command: " --connlimit-mask mask".

Note that conntrack module must be compiled into the kernel and iptables in order for these options to work on the firewall.


Tab hashlimit

Options in this tab are used to configure parameters for the module "hashlimit". Please see man page for iptables, section "hashlimit" for the explanation of all parameters it accepts. Note that on some older Linux systems this module used to be called "dstlimit". Checking corresponding checkbox in this dialog causes compiler to generate parameter as "-m dstlimit" instead of "-m hashlimit".

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.1.2.html0000644000175000017500000003446711733011756024575 0ustar sylvestresylvestre

Firewall Builder 4.1.2 Release Notes

SourceForge: Tickets for V4

What's new in V4.1.2 ?

v4.1.2 has been tested, and we believe it to be ready for production use, but if you do find a bug or issue please let us know.

GUI Updates

  • fixed #1703 "importing iptables line with module pkttype causes parser error". We do not have any object with the behavior closely resembling that of iptables module "pkttype" so the importer creates CustomService object with the code taken from the original iptables rule. SF bug 3065435

  • fixed SF bug 3049665 "Firewall Settings -> Output file name misses .fw extension"

  • fixed how we append suffix ".fw" to the name of generated script when it is preconfigured in the firewall settings dialog and already includes ".fw" suffix (it was added twice).

  • Fixed #1699 installation session status was reset from "failure" to "success" in a configuration where fwbuilder gui was running on Windows and talked to Cisco router using pscp.exe and plink.exe and ssh session failed because of authentication failure. This happened because plink.exe terminated with return status "success" even in case of authentication failure.

  • fixed #1724 . There was a problem with pscp.exe and putty sessions. Plink.exe accepts session name in place of the host name on the command line, but pscp.exe does not. We ask user to enter session name in the "alternative name or address to use to communicate with the firewall" input field in the "Installer" tab of the firewall settings dialog and then use it in place of the host name in the command line for pscp.exe and plink.exe. This works with plink.exe but breaks pscp.exe which interprets it as a host name and fails with an error 'ssh_init: Host does not exist'. The fix checks if what user entered in the "alternative host or address field" is a session name and uses different command line with pscp.exe

  • fixed #1715 "automatically expand new firewall and new host objects in the tree once they are created"

  • fixed #1732 "Double clicking on object with child objects should auto expand them". Double clicking on objects and folders in the tree expands and collapses them, as well as opens object in the editor.

  • fixed #1729 "double clicking a folder in the tree should expand it rather than open it in the editor".

  • fixed #1738 "Enable tooltips by default"

  • refs #1731 Change double-clicking on "Any" object behavior. Tooltip shown for the object "any" in rules says "to modify the rule drag and drop an object from the tree here" instead of atributes of the object "any". Double click on "any" in a rule does not try to open object "any" in the tree and editor panel.

  • fixed #1739 "remove 'tooltip delay' input form preferences dialog". Qt4 does not allow for changing tooltip delay.

  • fixed #1728 "Update Library drop down menu". Library drop down list shows an item "Object libraries:" at the top that can not be selected and that always stays on top as libraries are added, removed and renamed. The list always stays sorted in ascending order. Library names are indented by 2 spaces to make them visually distinguishable from the prompt item at the top. Implementation uses class ListOfLibrariesModel that inherits QStringListModel.

  • fixed #1740 "Deleted library remains in the drop-down list". If option "Show deleted objects" was turned off in the Preferences dialog and user deleted a library, it remained in the drop-down list of libraries and its object tree was still displayed in the object tree panel.

  • fixed #1741 "there is no way to undelete a library object".

  • fixed #1730 "Add background help text and images to empty policy window". Showing tooltip in the empty space in the rule set view, this tooltip provides hints on how to edit rules which should be useful for the beginners.

  • fixed #1743 "change default for the option 'Show text descriptions for direction and action'". The option should be on by default.

  • fixed #1744 "Add tooltip to the rule number". The column in the RuleSetView? where rule number is shown now has a tooltip to remind the user that they can click right mouse button to the the context menu and use keyboard shortcut "x" to compile the rule

  • Added text to the tooltips shown for the "Direction" and "Action" rule elements to remind user that to change these rule parameters they need to click right mouse button to open list of possible settings

  • system folders in the tree now have tooltips that explain what kind of objects belong there.

  • refs #1737 Added "Quick Start Guide" tutorial that demonstrates basic features and key concepts of Firewall Builder. The tutorial is accessible via Help / Tutorials menu and is shown to the first-time user on the GUI startup instead of the "tip of the day" dialog.

  • refs #1748 "Add dialog about Standard Library when user creates first Service object". First time users will see an informational dialog reminding them about the Standard objects library when they create their first service object.

  • fixed #1745 "Remove path data from text above rules window that shows firewall name".

  • fixed #1746 "Force user to change interface name in New Firewall wizard". When user creates interfaces for the new firewall or host using manual method and clicks on the "+" button to add a tab for the new interface in the wizard page, the interface tab is created with blank name. Wizard later checks the name when user clicks Finish to create new firewall or host object and does not let them do this while interface name is still blank. Error dialog reminds that the name of the interface must match the name of the interface on the machine.

  • fixed #1733 "Add button for video tutorial link". Shortcut button "Watch Getting Started Tutorial" opens page with video tutorials in the standard browser.

  • added "placeholder" text to the interface name and label input fields. This text is displayed in greyed-out small font inside the imput field but is cleared as soon as user starts their input. The text gives user a prompt as of what is expected in each input field and actual list of example interface names depends on the host OS chosen in the first page of the wizard.. The "placeholder" text support is available only in Qt 4.7 and later so the code is conditional on the version of Qt.

  • fixed #1718 "Inspect generated files" dialog says "Multiple firewalls" even when there is only one

  • fixed #1751 "Don't allow interface names to be blank". The GUI should not allow the name of any object to be blank.

  • fixed #1759 "Use default template library" button seems to do nothing. This button should only be enabled if user switched to their own library of template objects. The button should be disabled if they switched back to the standard template library or never switched to their own one.

  • fixed #1757 Allow searching by attributes even after an object is dropped into the drop area in search panel.

  • fixed #1760 'Search by attribute "name" should search by name or label'. The first item in the list of attribute types available for search now reads "Name or label". Searching using this option matches the name or the label of object instead of just the name. Label is only defined for Interface objects.

  • fixed #1755 "hitting enter after editing search attribute in the Find panel should trigger search"

  • fixed #1753 "Set interface name hint based on firewall platform and host OS". The placeholder text in the interface name and label input fields in the new firewall wizard will depend on the host OS chosen in the first page of the wizard.

  • fixed #1761 "blank interface name is possible in new host wizard"

  • fixed #1763 Implemented basic facility for A/B testing within the GUI

  • fixed #1765, #1779 Move quick start guide to the web site. The "Quick Start Guide" is now part of the web site and the GUI only shows a dialog-invitation to watch it.

  • fixed #1776 once new firewall is created, automatically open its Policy

  • fixed #1767 improved UI in the new firewall and new host dialogs where user chooses file for the custom template library or uses standard template library.

  • fixed #1791 "Add preference flag to enable / disable the Custom templates button on the New Firewall Wizard". Use of the custom template library to create new firewall object is now optional, controlled by a checkbox in the "Object" tab of the gobal preferenes dialog. New users will have this option turned off by default, however existing users will see it enabled for backwards compatibility.

  • fixed #1777 "scroll new fw object to the top of the tree view panel once its created". This has side effect in that some other operations that open an object in the tree will also scroll the tree to position this object at the top.

  • fixed #1778 "main menu Rules should have the same items that context RuleSetView menu when no rules are selected"

  • fixed SF bug 3039681 "context-menu items inconsistent for Single/Multiple rules". When several rules are selected in rule set, some context menu itmes should turn to plural.

Changes in support for iptables

  • fixed SF bug #3071667 "Compilation segfault with DNS address in NAT rule". Added rule processors to replace Run-time DNSName and Address Table objects in TSrc and TDst.

  • fixed #1705 "iptables (v >= 1.4.4) --set option deprecated ..." (SF bug 3059893) Option '--set' has been deprecated and renamed '--match-set' in iptales 1.4.4

  • fixed SF bug 3057503 "DNAT rule with dynamic IP has a white space, causing error".

  • fixed SF bug 3060325 "Address table object and prolog script conflict". Generated script should run prolog before checking and loading run-time address tables.

  • fixed #1707 "call function "prolog_commands" from the main iptables script part instead of function "script_body" when prolog should be executed after iptables reset"

  • fixed SF bug #3071667 "Compilation segfault with DNS address in NAT rule". Added rule processors to replace Run-time DNSName and Address Table objects in TSrc and TDst.

  • fixed #1714 "make checking for MODPROBE conditional". There is no need to check if modprobe utility exists on the firewall machine if it is not used by the script.

  • fixed SF bug 3077132 "no PREROUTING rule with *-Interface". Rules matching addresses of a wildcard interface (e.g. "ppp*") were not properly generated.

Support for PF

  • fixed SF bug 3061034 "ifconfig definition missing". Script generated for the ipfw firewall on Mac OS X missed definition of variable IFCONFIG.

Support for ipfilter

  • fixed #1702 "Wrong path in the activation script for ipfilter". Activation command embedded in the generated .fw script used local path to the generated .conf file on the machine where fwbuilder compiler was running.

Changes in support for for Cisco IOS ACL

  • No changes in support for IOS ACL in this release

Changes in support for for Cisco ASA (PIX)

  • fixed #1783 "PIX routing entries require interface, but PIX config will compile without interface in Routing rule". Policy compiler for PIX now checks that both "interface" and "gateway" rule elements are not empty.

  • Collection of template firewall objects now includes an object for PIX 50X (501 and 506)

  • using command "terminal width 256" to turn off ANSI commands in the PIX command echo.

Support for HP ProCurve

  • No changes in support for HP ProCurve in this release

fwbuilder-5.1.0.3599/src/res/help/en_US/cluster_interfaces.png0000644000175000017500000037537611733011756024736 0ustar sylvestresylvestre‰PNG  IHDRHF/vэˆhiCCPICC Profilex­—gTSMЗЧч$$єŠ  tAz/‚є.щUщMJ])‚є.HGP”Ђ€вщEQЄ "HAъ=шЫѓЌћс]їЫЕВц—}ўГgrіdіl(ћlq8wРУгo ЁЬjfnСJј # М@мжоЇ„Х^€%џЅ§њ ЃGУGОh—НŸzrфL „ŠЖИ†ў—AЧf <яршc?>šїВƒНЬ 0ЏzxxСў)ќѓиу№№XЪЛ0sНИ‡[ №Z Щm&М<`ГѕЏэL!tiДbџЕmќyW§k'1б?ю 2ePŸ7ИсЕСњ§дУУнтУУ§uŽзN”LІŠ˜ђ™vњlљХpFwVkNѕЋтМм‚є7ёEсяќK<Ыœ?NЏ0­2Ќб­c6Ј~Rl’§"о"мFџFя wQ{Ј}‚Ф!txЧŸм†ЁˆbdС]д(!?Q 5iЙХ.еc žVŒnѓD-Ѓ sы)§гClВь‰}œ?Й1gиyјyEЯJѓЩ№K HŠ ѓˆpŠВˆб‰“J‰ ЩYЉaщv™*йьsсrЎђиѓ ЬŠŠ?”Ц”{UъUяЈ%Јhиhjj jгjoщŒ]hжЭзЛЎo‡еМ(jРjHiИoДdyиYY]•[[јшЪc›ZГ:§zЭ'ŠOЅ„Й›XšiZˆ[žmД.ДM<jяъxвYо•гаs­зЃЯЊџТРЙМ/O  ЎПš~§zЈуMУлšсяюП/ў?’5šњ1n,rkvhkGши^зeднд{Ћ_MОˆ705”7т0&2^6‚їР-s cKq+jЋы——*.Члрl-эtьЯ9:В:aœ‘Ю._\‡мž])wЯ№ИюyХЫЇэ­ˆ—ѕ‘єѓё р <Ф~•%јDе5тPњ > &Т_F4F–оH‰ ŽvИЉ#Ы‡ˆ›™P“˜‘l‘"ŸЪš†H›MяЩ(Л“щ’Ѕq›;•=›г‘[”’oV QH]ИZ4tЇЖ8Ћ$о :ЅТїщюя”M•wV”>ˆ}xЅRЏJИšЖzЇfіб›ЧЕѕuхѕљORŸF6ј7К4Y4ыДШ=уoen#kл}Од>йёЊѓyзЃю;=iН}о§Жи /Y^‘ПкН:Д№fцэЬ№мЛ…їKVFжG7?nэL">ЁЇШЇ?ѓб˜q™MšЋџ:Й€ў&Аhќ=tЉ|yt…zеz­yCьчГ_F[+ПwЯюѕиХџoю;Ъ hIю.`*€6œЃ зрЮ€&,9F2њA   5}Чљƒ№` мA$Ш5 Lƒmˆ т…”!+(Jƒ*ЁhA€р@(#ь7ЅˆФ*’Љ€tCf!{‘;Тю VQ2Јhдњ,:=F(I˜AИIdFдJЬMœB|@тEђ…дœєйEВ7фЦфN”TдTEд"д3Ь*M-э žž‰Оч„УcъIѕ“;LUЬv,Œ,УЇRN_dЅegЛЫюЭЁФIУ9ЯеФЦŒ‡ЮcgЃљLјyљFы„в„ё"ЦЂ2bЬbћту ’R8i}!YŒьіЙ)Й~љ'чя*d*Ц)…+_SЙІЎЃžЎQЄYЃеЉ=ІГЁKЉ'ЈХњ^Ь3ш1м0ц0167ы4пЗ”ЕКjнz™РFз6лnСAж1бщГ‹Иk”лwЯaœ w<~бWзяQc`DаJАUHЈиѕœАƒЛШž(ш[1PЌgмT‚Ab_ВbJsšLzг­ѓ™=З/fOхzчЃ ђŠ$я —ряб–6–йT?ЈЋМTЎy№XЏv­>уЉlУLSRЫЙgплђл :‰Кк{‚ћФњПНШдyѕ{Јь­щ;тї-#Имc“™ŸАгфŸ_ЬФЮiЮ.є.Ц.щўРЌŒЎl8lђ§њЙнЖ“АgyРџчќРРЗAE` Ышчnљ IDATxь]`EїпvН_zя=Є%@шEšЈA{СоаOСЯі 6TPD@ŠŠ`GzO( о“Л\ПнлнџлЛT!|Bм!$[ІўvfоЬ›WP–e>№№№№№єАžвО<<<<<Р#Р#Р#Р#аЃр [њœ|cxxxxxТЦї…OиzдчфУ#Р#Р#Р#Р6О№№№№є(xТжЃ>'пžАё}€G€G€G€G G!РЖѕ9љЦ№№№№№„я<<<<= žАѕЈЯЩ7†G€G€G€G€'l|рррршQ№„­G}NО1<<<<:0"А›€\>‹А,ƒ0,‚РкђA0 Хр–<HЮЮУ9;rЎЪАњЛ„Эѕ5€Њ=№Ъ5YхQ&уЖэыDъ-)Жоl“Й‘НчŒAЄ2 t( ФR\&§п:…kx§oiљTџfVНџ-ЖžРиcŽxЕкh*-=ўСвњ=ћ… %ФP›•$ХbЁZzћmQїм}ЕJqхы} Ђ, ѓђ$“›\ЄіъV‚ЯэЪјєеЯ€А]yКNR\ТжIЦWщŠЂ2Љ˜6P5fЪц`D(ІjЊЩЙѓ.D@ ­НЂRьылуњ+,лщR6вС bЉшКЏ]Ѓ}мЪ•<џЌеЕ5Пўщ)#d"мc.ІэŒЃЎ^_xЪйњ FŒџ90M%e%чЊХЁОќRљА У8ьЄнjБкQБ\ЁT.•~г!pѕ кйl +ЈюCƒ"mВš‚ЩЈPJHкС0Jg­zcЈIч ВККћ9ЗЦДъўzїЫlCиьџо$n}мн h#ќАNЦJwгpё€УP6Леl1›эЈTыу)Й’ф|\ –& ЗЛ(р8.UuЋcЂ– ТЕb˜ [ч šь6O™З™lеUИDъR(Šумр 1ІІЮŠlWзT‘0n0r‘ПЉ’е?ОxЅз“ѓцНpoоЕЕLAм-\ГЄс|Nюо_ќБy_™Gђ§/п7u WЛМљЫ›ЋLиšj›œ;‘ AA1LхЁМ№igї0ї[jjX§~Ћ•bŒвDбJVcq bІw.ЧŠЭЌ‘И`­зYІ\VА1kо*1ˆƒЖš+џиДЋrЬдзИјЮЗpрHPB{ЂХб0xб€’A NVН^gdДўžRм•Š‹рfмmЫ‚ё†СЕГ~@Њ†Жжn]ПћаŽœНчШсЏ.^|gXчехŸђм(Ац&ЫoKkЊ18A[Е€Њі zЯЖG]^)њhЦЁˆ@)š…у6E ŽцœzфAR e$b\$!ќ€ЄЙЇ%kcуФ^ž—ЮeДХ`І1B$DЬ M$*–)e ЅE3ЦЬLIљЩЛIgГSА!KЅ"–”&;"ЩbFWЙ§‡іВЈU-Феp†Я‡„Ре$lАВћkљЖ†ВЦ‹ёё‰єїш˜‹Ÿ_ќФaЖlНc:Zн€уАЌBВˆЧ*ЙЗБtЅ‰Tˆ›-732ЅКУId(cЃОIпdБЂ„PютŽтˆP‰Ђ•Р!›ъšHDЌѕ†ŒвDЫ!еh•2ЦnжеtFХЅj7_ЙЙЄшЛо\ЙЭrџšЗFФЛ{xHYЪвPЃгщlИXцц­Q*DŽІHƒЮDbBPЦњ&Zюс)59њуїAО61ŽћJyжЧХпŸrЃ!€J’Д i{WяЃt[хPDщІHН%ЕэI—WRЉлHЦю`ЊЭ$Ђ*ЮтХА†SчЌD#Т`,[ѓdvГНlљJmпДŒ_\:KFwўфo|y˜ шуиѓй†уца>3o]№тф`7дpюTЮІcЪYZI§юпџБS—Uƒf™ьI%ЄaМа Fщ.!"ШсДоaЁй$-^ca ŽйСЉ+ L)„qzй`ØKKŠъr§™œœcAЄLлЕvЕVœјылп LОоn…Пм—ја`'pdhИЄŒƒВлэFлЕCњvYё—7WŸАAg M v|I^iXя0џHП+4‹œi$%(#p‹(ЉвМxHPaЁЕ",\йŽа QФ„3ІВВ.F4~ABknб{ня#cЌvVЎhзlŽnr4Њ8_tЮTК{ЫцЃ0юœ” z<) щЗlkVYіоЏ'>ѕг‘П6я™’6Ž€S†f-:ƒе—PљI…ЅAƒo}уѓ;У5Š4›Œ6.€А:8ђзЌAwДИњp G$џ1T Иьy‚+3ў7Р?Š€P*~ЬБ­yН†Ф_б †Z ммU#Цкt „Х\иЈg›trЃU†в3#'XƒФШ ƒš-ЗbgЌ(ŒНnДеTy~зgЏуЕ†Ѓпo•%ЄЧ бšž0њHSѕю•ыллаgС“}ˆвяўoѕŽoзkЇNN’иkэ:–НѓpюсbНОqз7ыч““ЄDƒ(%n~кЭ№WЏ1ащSЧЅX –”бIW:`Іc$Щ–I?ЛД #K;Ož;Ы:шИb~X+ П1Bв• шЧ„dŸдчижќ ЯЮЉ›сйlЩ=мG…аvN.ŸEpЁЪЃWЌvЯйcоїК–>_UЋтЦЗЏs˜*ђП˜Й ч!З6јXXFЂ;!ДzG#Лj~јя2cжш‘C†OLШлОїыЇю8е7йг\"•qї.$ašdYa›њKš+ђџИ6Лєфk}mЮъ5+ЫУ#2G NmeЙzп€Я‰Gрj#Gk^Až“њH•аЛЛCxкj  щПјmTvЛ^_Tд˜Ÿo,)Г5щБ]SC§Џƒиb‘R5mЧио!вЫfЯэшj•[˜З-oo™ яЈ)SЇNHїAЛм?(vPК2вiЈЉ%…‰wп:iжаp…NЏРЩЕћэеч­ >ДљмЩћі*}cдlн‰c9bЕBBt[•љЋ›kBи‡$$AГфJЄE)JЪаb† ’ Bэ1ХfзSin0+Ъ, E#2‚[гС–ЮZ[з%ќ„< іБЏ„Иl[ЖБ№аI…Ÿз ‹€рe ЌHR0Б{`жGXђ #'/š/>ѕ§–sЩ1Jа^#„*5Лgџс3,*‹3gЦє1ЉnBк–>їщЉЅkѓM gr,3Ыx`нТ e›wч”d7BЏ№oxЊДУ† hŒSk€Ћ#0< ЕљљчqмcР`oŠЌ:™‹Ћ’л‰Pwйў%Р?ŽЊ=ўс Хb‚њc"‘{\/Иd'ž%эMЦВ2CiЉЕЊЦP^YеPOиl~2Lо+ЁыЦВ4BйхюYѓпy$4тLB•p.Aƒn[0hƒ€М#{ЯЫ§0асAьФ{Ъм‡ІЯ}ŒBHИЅ‘Ш™OОxЯ“m œщлюЁыrљЗ7mпѕъVЄEДW" йV:Aи s45сFуБ†z‘ЉЩuˆF@#^Z)EсN{ГLˆъ)‡­ОЁ-mЇW(*ѕю5}ёВiˆ•A@;NШ" ёБ№ƒqˆУŠиD5xЪВС“I"ЈЩ:ЇЋaф~qїnY1,зŸ"AzѕЪ|ъ‡!$BСY™Ё%AiГї™…‡F—чВЅР^З.N%Иk85р&ж&ŽœљэШ9­е„MБCA­Oј ю ‚]Ђ!pzОY#шœ&ТcG@Џ†{ЄЎu-кœ:šЭ•СƒDЎбе*њШ ФВ])ЛЉeШЕ{Ю_ђќkёчjЏнUDŽ~хљЁ„ЬЬ!pg |рhCрЖЖBЎьŠ“Р)е"ЅFч\ЧЁ@HCЃ­ЖŽ4#3Й‹и * †G@Зn-СЕю=–ЖGэнP 7эžЕ&hЛшbltўъЂ ;жVХ#Р#pu@…ЉЇTумл5g –э0/€OЩsјЏа7i.7 a$BpDR ЌЈ#unœІ ЧЌR‡Р D`‘ЖMˆэZъjuљ…G ЮP#†А”JЏєtM|lKVќ_›˜ кЭЭЭЉ8]UœWтс’ќ7[ш<„њvЉkыфБРДщ4„ЂaJVJрОmyшЈ-8™›]XcfkIгvБwpRП”p9ЪrџœŽЎјaыЧ їLš”xЕq€ЪТЊН•p3XУЩƒ_~ќsIICЬјЉwLMwS .ео–ё/D G6 >›]ЊЋ$ lр&ЇЪJ+ %С`ј9\­uА 8Хf&ќRаšne—c€ftЇЖОџіŠьSŒHЃЭКџўлЦEd@0,Ž\’"@ўРыGЄK.„М“{!-%9›WДёx1Ѓ 1жш!!Wїл ˜R7œ;АwУЪПŽЈBPOTlцэ™™‘Z)аS>№\u82bZ00; p–оН.Ў7шwю№HчДKчуЖyЎwўс65pС 3ƒ›уС{h'ХЕ=bŽgџЙn‡Nх%sP6БCjv˜*Ы+ыmr_?_Peэ–j}НЮ~В:ЋОЋє‹›uAфNЃ]№Асє‰*JцЁpКћ0Ÿ=№ё– ‚ћЇјЌ[ВДŒyќЙYЩ*оHлчыжUїzVЗВњч#НRKV ЎmЬч ƒtА ЋЊЏЫњpПСиЬ6ЇPP•‘ѓяk/m”Ž!kNg?zчћeЪ№Љ#kO_БЊ`ќИ”ВWф%AбЊKД™Е› 5чЪIE@XАтqк=v˜Nьнўв“пXМ"GQ—œ)пАщьаЋLиPКЉxУчп}§С.Y@xъ№"K§ё?ўњ‹ |ByТжюc№—W‹бv`у LњЗP"Ш˜`КЪ3д3!+О;…СИЋPї4Pоs ?ЏІ—'qnШFL—-dŽi'в"к>Др ^|;ИзщЌЦn{љЇO˜8&Q ѓЈPІвHЋПњy]nSФмщгRVˆ`JDЌ!D`ѕШ†q|KŽ+Ш8+ЂРEдгРУфЈ*F›A œЈBUрќ Г\d;ї ЋАGёЂД4}іЭU_…z№Ю!НќV@žмИўЈ%hі33FЄjCTяўїЃЭ…У#RУ4œyM>tEи@А$P%ƒ•*г™)py“ф.ЁРТъЮžЊ12žœћ50ЗƒQФv2пZY‘ўсћ—Т l^YJ‹ЪЋMOЌxnT„аnh*з[Љ5Кї-ЯНѕ]Dшœ:ЕпDbPуђІ@1 њиN”n[јхщ'_z/XN!Ў9p% єF­ˆЭiЕВЙd№иT|жŽˆћП'3pS“QgIBФх Znмžь” œв0„p^0 ЃєlI;ь#!‰і“œN к­(эчпКљonЉУf={WZМЃэГЋьЈЬM+„ЌЮЗ*.B0;^‡yIИ])ŒJЛГE0,ay ,йfж%˜Њ†e-(9Р@†ч ЎЧpLNw*УкЊ;еK!Я?я) @Рф*yўбэшз8ЅЛ"МOј4“EBъбЇ*ќг‡Ћ/9Cџq№-0Qb‡в{Hј<Џ—эŒЅˆШоOюЗS$8†МlЮRЙвз?08Ш†-АuE‡џиЗћї_kѓцWя—5{ @!Р3№ЉнŸў˜ГoЏ1aмШIw ё’bЄqџŠ%ы7ŸЋoђГ`жЈ‘‘J)[јѓšДŸJŸћзЯЕУžžЉ->\* ђЦ*6Џн[V)ёШŒ1ЃЂд2!fmиПђЃіimy[WЮЫљНцЃЭ“чЯš0жяаЮЪ >CтЂ§D2Iж­C–МїVA‰ЁWšрљ‘—§Јэ"є(Т"’gm0kФ8xА8 ХhDЈ7dт‚Œ$ЛF|šж™ЬYV‚(,4žiХ…—А”з3`џ[%’xH•vЉТг›БZšђ~ўъНьSжљ/нї&ўктq‰Ш/_Џљфѓ,Ђ NvЯ›“bЄ†§Ќћbлa4яЩG“нМјєИ ­сьЮ5ЏНЕyŸ( %ѓџЛ7Сhх‚E†ДЎIнх2Ѕ\х‹иыЮчьXЛ“щ7eЪ 0Ж‰дŸмЛso…2&59WPl–jy?џўчNCЦДIwЬт$Ч^šНулОпГϘA#Цо?uъCiъ#ЃЏиuЈ H›2mоэ§г§EАœDЄŠX8<*O•ј3їЌNj>Лqmй˜—>а'wУ—Ÿ}ВЕДв0ціћLАAўЧWЏ*ЧіыЉ5§mЭtшИ”ˆ –BеЩ †ЫХЌЦWЋ)/+лŸkфЭ\џКЬ6?uѕ 'OŽ”жСFLух&•+Q*ЙР"BtGvo;昘UbэЏJEРї‡žџњћЖїЛх–фŠ‚-я~-бЬ:РЏўшЮ п—д+$%СгS^ЛyчКŸJы=“ Љ0ўђуЋПzІЇŠї=БdY9л>mК—›ŸDю?<<<Ъm*ЯoД„ј(И3œ’`žў18yюl™с'…“q>tж#ЫnЇИ#ТŽ-H-Š7‚phEбžbМвь8iІоїЦцЉ‘uіbяQФ‰Ні8_ЗпэіОКœA­˜^5Е‹'Ю^Мbox§O6 8V, нwи§ЗGIэыC~ћ <№TUнцхЯфк%ROПhЕrчдYƒQKqUc“ЉЂpу‘ќ вВ>Qi‰ЪрŒ^gLа7DŽ;ЌЭ’/ЮЙ‰РT(ZSmЇнlЭ…@ЯZАˆСцƒtрЦŒ@ЦkСBSBа‹(Šiт#У 9FEqд@хй“єСЪДODŸ.:&аFѕ}nїџ­{џЋЏю}dћG1ѓ>x{R?G|rF_Qо€ЬЁwЋCфЃ™-‘HєчіжќЙіЗŠ“h†_Bljпњ!ƒ†L `эMGvоnІЇL18EфfЋ>ёўСг– ЈѓЭ„,d№ˆg6IV/]ѓёЬћЖ ژїњ YбОSПyчРЎу“o 4х5ШТ3cЂ” 'i‹[ФQ3яН+M5в IDATpf{SЩяеЕХК tw~nMZъ/Ь”цA€'^Йhб"Әэ< Ч†= csXМтŸxіžсЩ~Ђк#ž8њФНwЬЯ tGгBЮ]} ?9"6 4Œw. ;I)OРЕУBšњN|ўЁ)CМёщНl“_лЗЋ$=5JщгвР.@ц_ѕtРi”OЄЏЌ_й‰r s`@9Мw„ТCЩэЌЎ$XEшодQsUљ!ДЂ\$V št.Vќ3ўЁ%ШŒŠДЎWwВљfm\Т„QЗg%ЩTэщAр8&d%8x `ЗФА$т781мWнX-! . wmq8rзёќІo-Џk@,B8„JKюшЁ3ˆЕ"AzїKїTK)ЉмTApsеФ0gWuH‹y—a˜˜AЙ0—"XбbЮOзАўЮ"оо2œwІгяк.N"l0OW›HХ, cУбПЪ-аыЮi“R0$3ќШЂќ3')еPg78>оъ3–ІvP\|‰bB‰пЬљс1CЇяXѕм›пїЈbгВ4Аp,Є˜Pf'[}ѕжхЋо§ПИ@.“Вb/Naт˜„;`ТxЎ(у(9UИtђДЯ0ФAГQ}СУoЛђPBІŠ>zABт№пYћц—Ÿ=KK—Пš˜ЅњsЧЂcщOЁuMЂєa‰ž"ДžDМТCb3тмфК!† ) †l,"іV{њkХœйш‹жТАрЃA$”Ѕ[ d§ЯKОЭoTмђјpМца+дG#‘ ДёI‹їчЮоL*”Б.ЏUАZщЊ7Ёw(…ЛƒAрЁ’‰ЏЃ эVкбsŽv№—74ѕЕŽќ\ЛT†IЅ˜D†ТoЉ •HaДяЦ—j*– "ћDе•ж;ьЏPя„ ЙВР"Z“я†ЁБ‘gal˜œЁШ@ж6дя­мV‘~ЎЧPŽ6‡—(zЌP­ђ‰ ‹ŠуЬ<Р(Ѓz@$СЭЗыМšKЧТ!3.?:@ф` ШЩaЂ(э€Ÿўѓю™0:СMФPЈіїV;9?b№иЭ 'Еf1œѓƒz<с†'† іѕp†Й8-$БRрР„KIxљѕRШ*ЫŒ& э!Уѕ%ЧdLVчн|ИzaуЬ’xњšjk€–HX‡b18€РёЩЁЕuM›мб?9&,HМЪэ{jКЦ ‹Ц(Ѓ№№N3NЁfІOYqќ”.-™…Е›‰ТXšВ§uу7›N=ўУЇ)r§•Ћжtњт!gŒ.CwфF 8ђі‰Нoй›О`6‡х™B#nW4Ї€сИЪ7ЈпД) UЕ№ѕ§ЇЮ™“{…ІOLўѓwоћoА4Ў_jš7Xz…ќ ЇˆьЫ\у$Џ(Nћ€лMqCШ)ж2ЦœХрb1.–ь;P•tЄ:nL0P9рЊb&Ђч…а РЇL/@ш„Љ4кl`U“Ы‡m@ч ƒw@иDŠСъЗ4фгЂ0Ю“ЩDСЊС|ЋMpлžъŒФџК‰KАoО4p§Ѓc›т@э$R~{ъ]JAgЄ|ыzi#ћF”ŸЈˆю)\™Ъ3є;КVZКYиЈАŠjъ„bB,‘H%bЉI.ЛAЧУmJ§Ёg‹Є(ЭјZ-@м:VГ“;ЛБЉІЂьМЇ™#jЁаЪ1aћhЕ(<%еoвWŸv; ‚ўмWY№W,–J)‰Ћ3юЛЃЌњХ5Яоџ)ђ5щЭEЗMˆCPр7ЖвX$ЖнтBБT.gТИдgЪЧcяМн1mjф˜ёš_WМ;gоЙ7MŸ˜3ѓžЛЊ>Xљќ_›(KSв‚ 3#§[Чё•"їяпЃєrЁ дВЯ –њћћ ЫBl]еžEs€и”—жедш`—SVcЈlа…њ‚ KW„ Xрdї…^v2ИЉJ9чƒ%У"Aрв=iЦєЗІ~0;ёћ‡6|•к;=jхo њLі ѕю77Гј“ппцѓњšЌ˜[2Пxќѕ‡џvџ—K†gzјWгч пžБўI‰~ѓa+acmІЂэ[^~wПГ к34lжлџщ „ЌgtєРЧ{ŸмNfІ‡4‹ћrœX r5ЧРс0.†пИHеoСLVmљђЃџLћ GйР‰OЮїRaƒTар[U{|ЗxхзЗЭZ @`’ŠAѓgСb|Xq‹Sч(@%ў3V>Ы>ћњ’‘kZк7уЅѓ ”тDќ]ух|љќUь БЗŽM1œ•sІ:!РFвKї§c Оzаl!Щё‹_7є Ђb:!lа>˜ЯЇLWŒКЅ§ ЉГfЃЈL%•(Є`ќцJƒH №іїvѓŽ‰†ЭАDк\шИАБЖ RЃЬŸДлm@ъК,B>qц‹C&йZЩ4.”Њф2 6їџLyТˆ+еZрN™ља†Ъ +Uь€љї†0p‰{Lyы§ЁuMV++Šе^n2‰0ухз“1‘LцbУˆлпz šўі/ЉJ*VFxќEiq$iФ[R Mv™ЗNгPŸaO=пыŽj…Qzјјј+@ЌЫц№/;A G6gћšчgрьqЮз` "“ˆ…ЂŠЪЦC9љСBURz~пёX€uIЫ#BЎъ§Ш+{f?Љ3Y@ГKъІUJDмВL$‹<я`У4 …ƒ:оВhяPЋйA_cь/[(BЊвˆМю[АџЮћьЌ@Ў‘Ђ<ьЖџєїДЩ ъ ШдвZ‚и;pєЫo Y`nВXa‘(sƒЃ.Ёk§GZыѕe•nЊ{#§@Ї ‚ fц§Q3Р4їсдIYOЏ D‹ГІЂё№иKЉsŸАYiB"’rМAgŠ–_(.ђMЮ|xuя9MF“™Т ЁX!•Ъ%N›љ@д Ngж|&$Ь§цЋi 8j”*ЄBЉШu"ш=hтђ§У-f‡X.З}Р–$)39юŽYГћЫAУT3„ yЅлR6џїІE М”:šm;’m/9:ЩЅ Лџ1uT,ч9цђˆв•S5Ш†4,чpІvПД9NC”1š ѕ Њ ьє.!‘Љ%(1GX )ммфnpъЦT&ьцйD(VК‰q *Qj%J —ў9уˆеpДавЖП…3I7 Єтrъ4-BЕ~>?ЎPWЪ•ў1 xЖY\ [о№Л‹@ЧЩЏЛЉnІx2‰|Xппoў!62.68)чШбТ‚3чJЯЋ$ЪёYЃЛl Š „­~:FJ"h4-М6\$SˆИ…РŸœыŠЄZаГvŽq"ЪдЮ`ѓГЖ?@tФ2јi{Т]8хщУ'жžv›ё~†Ќeб$­uv€‰‚h“r„YdP”ВK™C1”KU№гБ X45зsАО#Д&:X+‹х q‡ ‹сШЧ‹"’i<.hAЧєќнM‚‹` ЯФнњФ2šw?Bta0рšъЙ–РюОЧдЊVeЩkпКЫЮђуg=mЄPфZvUЁЮВjЃLВc„Ю_ЕЦiНpйёі2i]ЄБ}]Йф.šщ$‡э_ёзнD ч6…T~џ”4Щom|ЃЊЊJ.UжееMЩšђр]‹Ѓ›0§#бXTœўъ’ОбW|,q+,ˆ}уС…ИGИл цuфf-ЪdЁічжяЬЎmЭ‹,*(„†а*5–"JNЧ%Š6mec№ЛЫ…буeЗNSИЅ\On„п@в.ІjРЗоlшрd’С)А+€й+оA‹лxёЁG!аѓ 0 ФbёАБCG K!W'vъ&s:зV7жЇХ„RЯшxЯшК’А єKMѕунVнX}ч jSUgн}ЄvWNmЮ‰FКљаTdm*IяЏGxhА•›ч} o@и$tюƒъфоnшЏ ШыЕБ]Л†­ЉfЇMGrs‘яж‚0ˆАAЁш№ЁHZ ЃqcШ]пJ§§вœЌаПŸMЭсп@иИO \ДД~DngБУ)‘DqCЯ™юЖ ‹a>мlž71л•SsЊишЊ;LюЩ1šAiž+?}юпП{р‘У";Ич"—(œ9Gхщ}3Эgђ…\mТШyњФXЅbКфDРMLQ§УЯ†ЃG ЗMaТУџ.as Ug.—ЩЊы˜љ‹ѓdq™цeњuюz­5МИbP“Ў[wнЊz3uаю€ТiIv#X –ŸпћУLяZ<Ѓышй№)›[ZSdќНЕ}ЕОК туь^ПЕУ]‡rљ"nF(sфd#0wцдд66ћv‘ŠёО‰ю™ЉžS=• 0 п~bшДuАu{тљfйŠN#м˜хR<а[2 ~тІX=„RЉќ4ž6`’@хЩ2<ћˆ.<Мэь№k…Уd!с[ІКЪ€ІHŠЂlfVЌ‹„N}дŽбf‹ф&ч\Cb™DТ oСшn!$Lйžƒ•ЊАфxёš%ыXTЗюк•ЫХЇ-ІшЖВBЙJЉm‰ 7ŽT“‘iАbб­ьЏUЄEи@”ПДКДEЇВ+Ш(3% PКk!-Žd™ѕ`Ѕ >Ў“j€‰~Љ ̘КNvCЕжз9THE&ЅEpšз4Д+—+‡ЁШІњF}“M$“ƒР˜”г{§ЛуѓšжŸЯќAР`ЂіЋƒ§йоЃu[Г0ˆЇVд?ХіgщНмРJЦ?RБыS(ЈЎrкврЋEšЌlюYk`pcя>6 &40ZЋ;V ѕї*cЯ§ђѓЂфё“г=[ЄЪ.Ю‘Ею;tќР‘н›єcп=83ф"OˆіМU+7чT:Рw†кЌzПЁwнu[Œt0ьmqф‚<:їЕ%Sž^6Рї6 В$.’€Уg[‹саЊOПМ#эЁц>љњ­раЎ#qЖю[МјPќЌGІE]Ђ{1Р­On ТжqoдZCюТIU:<щєЦl1›3б8_К>Eы<п~§vјъ‡‚6˜š™0цХкєUПНќЮo5/)јSЏЁŽи[ИывjЃQ‘Dу5ž<ГхсЯОњњђkLиœk=@рІ!–ВлГ§Г7зьмWф•|Ы#wOЙ5йS &DјР#Р!PQkй}ИіgG tœя&g ъэћГИ№ ec]zоoЩqЎЮQgd”4RЎЇз!Їы‰9B-Ч”„Г€[т+h5Ќqa2qЎu9Б“ц‰uTWе*bРg. ъs{ЭБSР57\лЊV|А>яаЩЦка,p]еИЈ\юоPp(ЗТ­џШ@­˜В[ф~rА4Yєн‡ЕЉуГB%d…}‘^jNЇh6—sKИєА™r– жŒœгљу"И* qQРаk—iAХтдъѕ‡§о14и)gЪ–§єХ‚~›ЖtЩ”h§УЗОќфBѕЗKЦhd@DИЅГ(URRфВBЫеЅ­шfЌšыъЊмЕћ}Ѓ6иl5”5:ЛР…ƒXZ?БК№е…ї("в 1ѓ9ьТА’_Ќхœє‚1№I'j4 іЕБ"Е"І­›еzaя’lЬЯ>чsטЬ@ lАюѓє—8ŒІм/зІм2›s(CaФН&ЕсdцЁџ€?6%vђ ]J0Лъ:—V)lвЁяЂФ&$‚ющдЙЃ)—LЫ6:zЈШргlЋ* Яечя[їс:ƒ_њ‡лŸ-јaнкЯзs`жФШŽ ЈŽэсяz:0•œ3ьtž•‚=p.€вoZœ63Эspo/Ю=єП+W’[В-B`c…q(&P‰Z"e”Bж\cHЯ0Ž~€FЃДSaблh&)Lхэ A.Hyў…8`шШРЄ‘ЕБLЧШUw0U‚в6c]ЙMтЉR€]vIрыk>Bkїо;e“sд7—ы0щЋMЈV+“U‰0xвьб>.х‡ЙЉъР‹+–EЙб‘Сn0вˆ‰EЌКктbГyzЋUN5nšдWU44-t ђQC‰(b­Ћ1c2ЁЃЉЁё їEuѕVЁBܘъjMšp ђU+všдU”5С4Ка=ФO-Ч)}Эž'—}~ЗgoOЪ=4иMiоњёFйнoЭ›' WЎ<7|фњмg‡ !XC}ЉYшЃ тЬЯ>щCШ%N5$KU•EЄQ†š:ІЙћhN*xxџQoТлЧю5Лы‹ZEА\ +зA AУякЭіqk%’P‡p:ДŽЕ>[]@ЁД­н*–{тс’^рєV9L_kЋАX,РьОLЖ`mR.ۘtћєл‚‹/АiЎ8’НххU{юь-ЌSG„q~“hФтАе—ХjР(%јGю†ЕБЊш|M#Œ#m`t BФRр>ІNG ЅЌЎZg—„yPzZ&G u%e&‰вЭџiХ]СлжюЌДˆ5dА{ ъЬОcx№Р™SћЇњЄy9L5ЋЯю?R5"" Uхэ2mу_їHŠЩЮof#Д}ѓс™LBd$Къэ9 ХŒ:ѕœж^aK€ЄIdœН| р†˜&ЩоБњё#mBињpжWС_nїUђчOпьЌVтu9л ЪЯ:вgO›ћјИЈ ёсwпќSкЦЬСtбЗs—UDІнљф-Б!ђ’?~ZњJщрEг†’‘Е’`ѓИC‰uћ7ПєЇhомЁ}#9-QЋСl0šš‚ ФAЭЮЭСФъ lв%ОЖhоє(X,ЅЙПёЧІu‡KЩс/Мђш#щж˜Нoљ’џл}”27Ш‡<}џМљ<еєСЗ_ў…Iє6йі'њьЯ --к%M”|П>ЇБŒГшЭЧJ’ 醧Л>}чЭ§Ч ЋN6ђ•ЧчЯэЃпКqƒDПZ§жњкФЗп›?ЬЖ'—Йх L‰!iXМћєФ)]П iеo+юйѓн;#=%дŽЧўЋя“џ™нK"Дя[јЬЯЊЬp:я‡ѕ…жб˜7Ÿxdў`хuзЛA*§nЭиЖbeя@lфyŸЩщzСхnЄђў…ђ§ЧЄЧrВjА д˜e,•0VЛ&ь'ЃЩИ'oчЛШC,ъ†zˆгXЏkДЊсc‚ 4ЮXJќёЛйB|ОъУпщ>oО9кСЌњЊ[–ўzjлЏErY№m‹_˜95˜nЈЩ]ПўЋе?œ­P*”Суž›wћ­б–ѓ'6ПЕє0%Ў-4bНцН0јФ{чЛЇШъNlћѓŒ\rЉДЃЂ›В‹ ЯЏ1МRJMЬ3и3<-єфžТжMиУˆ­vWкYїлJaШrdNЎЙЊ8'†іыCйЪ9с]НЏnџ™гЇЗћ™мнќhЪšїыiw0"ѓЫ71<|аЈлvœфчЇ‡ Ѕ ЖЌФfЈЫ§=WѓР]пKя|ыг??н7zВgSіžeџн%сƒяnгь§rХђw—ХfОB‘КS9fЩа']0,„Ў-иU’Пk/;јСЛ>~АЋД?,SoіyрЎQ}§„цѓ:ЋРC"фО *–ј‰Хyцњ3t]VDнХwѕ(Ћ6;%ѕk‚эгцќЃ‚@Ь2гМЂCЎЙгеoвЕЬбн єu€PЁFHpЪK*­А]qСрЇMrћќWœ(CвUGVЮ>й 7pЛ>ШFs‡LрА?PјвЂЯ^ќX'ўшЂлњјК‰Z>T'%jcћо њH@lрUNvЎЌБW)+‘`eЦ№hЅ›_`2Ё№іѕђsWр4b‘lв#ŸН51ШMXzv€pХ)™Вž=ЙУA&Л›Юџ•MАЈ'fЊЉЅ*Ц‚Шю\Аќ™1оj‚FР›"›м–џЈ бФј•џ“Ё‡x =ˆа_мPQcФЇbyžўС~R!jЊфьЙPЭ~Pъ€CBЪ’uˆgяс3z36Ї=•‹єГеŒШyeуS§qўтУ™/mл~ ъпEи2№Х?$ОьT…ЉЮФ­ PФ=Ш-Њ_дQ5ШЧ*@žьoв}џye#ђі D’Яp’ВFBПвэУММљђiЭДDІtkdм<}|неv ›8RqŽп„#@јяКэdь№nnрŸ(jкХ ƒдœЏh6џzЦiБZ`6Jѓђrу4тaУ‘ФTЃЭТzИБf‹ЩmтЁЅQ‰pжЭЩ6€#sрžИўwž‘ы)Š„ШDnЂщg‹œч5.!ДцЧщўiщrМЂ fRVА‡gћOу”"bš…) дХAК*РЩг#С3яxpіи`KкЬœЃ8ЋGq Ю]ъL`ЕŸЏDDƒ8i5ВЌTРду<нДЅф/8oУХБƒ"дм!кКaа!g-/L+чvГЮД9~8+mF\е{TДЏE9іIƒ‹: ЄИPЉuУ0‹ЃyMРZЭz‰ђN/ Ž;jn~+№$F)БЂЄСi;„№КљпЙQvl |Аœ4,aпњ0IƒŸ‹ф‘Iч6Г Ј–žsЩП€-tГРІ˜яoqЏћS˜rСЄЌчm6†v m&K5‘ДйЗmTq$сrdоc„2§Х'–L &‹и­ˆЭˆ8р{Уђ з8hАТEс пcЇ’ВйQpŒУЩ CSоі]% ЈHШb‡Ž s"е˜іїфј‡И!нLыЅРt t1Nо(=lбdb№ХѕzЎ;бœc_™‡ЪУЗжxЩОq3ОА‘tіё89љЦЦІцУ …Œш—фћГўЩpv3ЖыzжМ3кL=ј Еa~Œ›Š-+gOВZ7д?єœ‘ђ2ІЎ–usG}§QЩхжМ mh,­ЉЏГЛ lU•vжнS*цœ’cЮIХR•ПцЕявЈдОšПV§т5.3L.тиТ Pv0 СPкnЃ„N5кдЄГ 2Tф< %M&ЕБоjсђ‡"А%‹6žj0™i­œп№˜6SэVББA ‘A„Э{юс9}ќхBk1`QХ SmmЙГДБŽЇ<єŸЧ5ЮЅ~ IDATюJєтk6АІЗBЙ 'ыЭ6ю9)B§зїЙг<ќdLщЎ­ЧEОЗk€вMѕ6ЦГYєŸ›Vs6œщN—7ш"§нКѓч0I\Рuš nЌQ|№рФр’Мвв“eЁ)!оЁоWDеMвЪжч“tSS’’‰ №€‹9ј@рešrP&ГyХІEi›$Є#|iТRуrіB6 PŒСЉ™ Ћ-Ў СюЈцhН§Ў(ТдsњnЮ-Й33Ž“;БHт4њБEѓ&…Ы k!3ШUУ;№з,!й§ДVЦІЧPS•I_nЃгqBщ™ъsђЇъМУU‰~Сж3'NЏFƒЃНЕМСЦЫ}б›с}c“}Я‘:иŸШ­З“Э|x_ шPУў ьƒ€ї›Ё7D N0Ы–БГБЄDіоЙДHŒtМE?_Ц€З ЬМ{бє>NuщŠƒшDХцm?cHu?Яъ§?IќяуЁŸeqзwЂ еППџсn]ь§<дзЗђ­пи№Щ:oЭЌŒ$jЬћ5Ї№Ш^]cХ‘_З“ЅхЗєђзшrЗ§ИO<фЖŒ№`1Pк†ќC|kЩS•s ъИБSb=’Bџќc/fјmУ#§aЅŒЗђRС+й€шО04mюрдї}№‰~x|”вV_ч?b|j”Д}dhVћ[WZЬ…їyphъџ=§_Aу˜и`‰ЉЖ6hм”Дp™wZhэтя7єЖgMюэ1fёФ­s7Ў‰t$x˜З-ў+zвГiСа­ЋмЛqeNФCOї—s>`+в)rіЫыЕ†˜8YўšЯš2ЦоžиђђкўНБД#АЄб‰?8ўЪЈьеbЬ QРSЮЩЭ)./–JЅ"‘P$CАЧЦ€Ае–зЅФBь(0%0ЇBXWУЭb9БqЭgхžр­С yPЦФ nžбžgП^О<К*kђ(8Єlиtрђсv@,VЊ Mь7кя№/ЯМмpМЇœAEвФЩуНкG†шэoЛL›9}’2азэпій ­т–О QЃ3boШўт+ћ™ уСУ%К ‘Г3}ќ|зеїМСпWš\’ЧOыЙeЏ3Ф„*AЯ"‚7x§oЬъиO/’zєђ(Њдчk’аўЦ`^‘ЬН—{QЕ.яЈсВ„уВєїЗ•јcХAJ$Йѕљй{HqЦ#!9QъЃd}й9sРдзІ&ХЋ ч§ЯпѓХЇП5дш­”ЏЕm?}Ђ6(Уйќ=…КРдаebMz„%ъxЅ&GWœнНџŒ‹NК wлCƒŽ•џг/ў}вC}<Мг3R‚н„NЩ yHЏў#Mоj`(*†}НPДь­5?nџaK“ŽaYЂ}dP§h i3ט<8?ІВб^~јкšŸ~?akбТЉЃІ€ЏЎ„OЮћ2gЭ&ПєўЁ^"ПїОјКэЃх?Е#Ваћ_{wАFтьІlSm=х\­О§ЄEЈ? XЅЊБa†;зn'В№—V?ЅќЛš№ньc7aЩ­ЗЖяЄtЉ0kмнkD$yџёH;љХ;Ыr…H$rВ 9Šacm`јЪLYtЯГk_šѓ*x ь2cp4#=8ёHг™c:.&!г IЙ[ђнeVm<Л;'~јpo7и­ЁмЄnc‚њЬдzЊ„&.ўЖoQ~љЭŽCйчРRp\T2†IкE†_ћлЎгbю•4hрLл[Ž””ФЅФz†Ѕмђ ‰}ѓыСпaв˜Qї9ТqЏ В.лЯПМРс1`6‚™Ћв*'ї мюhяx7`6IsW_|ј„„b!tХЄT#J7‘FIuИUP!tй.ŠюР№ИЬr4ЂђиСї=8.ЦvTpЌEТБЌy“юyК7žHЦ­пТЅChФ‡p BjRF,\6ЮXЗ~3п[|ЇКъ Д Э:F:`оk;—?§щдщэїуv3bg‘Є7—Пчє2ЧTѕ]№ц@”p9С ŒлпЮ'аї†”ю]’y/ф‰‰…˜)„m*мўв.Э@- ‚€ш‡*ысO‡> Ip "&# оS?\“ …Ѕ;ЗfGя|ўгi&3qБi6c8vсc)“ѓ`dр AЬN!Яaъ™_О/R8LHHш"з-\ГП7aуZŠ"*е•R5DФ‚ˆљ/Ьs&П r‹8Щƒ8Ъpюt‘Bлѕ*НВžyoЄ+kю7аHиž9d‰ƒп_›z pЫ б#J€H!ŒPхећі @ЩЁсrП”Љ ћLu^ƒs БЕ ЛSe`wг’\Zп[цЬ?uъzУў‘ѕJ4їэAs8-oNнЛUМ­ОќеŠ€ец8˜зЬFјi26ЋИЈф86zж/Щ]"О!ЧцŠgѕЪL  y`o­g˜2!]тЭЖПuwї˜=У•‰щА†шZK}TJ‰тѓ sW€бg’у ”ЅНuс(Sѓ„Ж#цж›–‡0X›Х8цck>­яс‚:(Я5+RHKсдМmЭzј\tLr žR'Ўєэ#Cэo!m;лK@СF(Єe€DЙвТйŽБ]ЙЮфfv,4ЉЭ›+[ЖфBЃN Q.=ІtWI j–!ƒZАrх}mп ƒчЃj­PйлzRыГ*­rСЃВУгNn X:(ж9у€0$tg?ƒ{ˆгќЁкœЄTK>фvоаW-™0­‘Й”`юёJвКж;-хBŸВЪ‘jЇŽјѕь6--фџ^!ѕzћlЬЉ=tМДЊ]Љ§НЄ@Ьр')š;ŠПТ,љш—A@,BЦŒL-„e(‰€lс…ЗуF &ŽРhРfбСKfIјNђЈwз@nзyФЕ2Ї/YЙ–нй’ЂэяХi/| я^ЫE)=%іœќv[ зхъ%lзКэb‰8kд`›М ьЂ&нўVньеIк ЪНўІгŠђЛ@р\Й Фєas–ІЩ ;ё*Ай–C§/ђJоE^ќЋK#K<фФ`ц…_-С9ЬaЄЗ=§Hћ[;Чbq…ЫЏ*dZw…ж”<ЯПпKџu№рTкПtмЋќц_JищЫюъК@ZˆР^ћ;DБ‹ЬљW=P+jЇ0HMEM3ƒK$Рzїrƒ“3otSѓ"ЌWљSыk›ъJдо*їPПљ{SlуL_€ЫryYъ вќ[oA?яŸjњП”А§ИэћоД}ШЬAWš —еcNЊ…WЇui˜tўa`-6Чўcѕ@Я@^п'ёЮ Q С`#ьЯРѓYГЮгUm{ЯЮŒл‡‘нї­-Ј?ј[vф€ˆЫ6ŽoЧsdЁ˜;а0жЂз-ДD­RЪ`{]T‡3НвРяьPЋыZ›К0žА5>№жЄ@Кe‹ШфА€БfƒЕхИє О? .›‘ZЉОьёоф{ЉЈ TцR ѕТ.p2Tз4Э&Ит0 Б;н\гв.ШœmЌЋ`…ЪMњSе6к@‡ш#ІZђ‘Й${EЊ›­S\PkўЖ•-]§‘kХтъУ—šэC0ЋІ/ГЇrдžЬЭ>ч1–ЅiRь”и/9м_4ŽШqЙг•?ўѕУБІ№9“&%^cл† АЅwк нXQ^vњмС?=<:дч‡g­бј‹Ўр [3:Ењк™oмBE— 2L6\=кNЕАх/› -гtЌ`УѓЋK}dёИРЖЧнИšr•W($Тк›ъ+ЮœЪй^& ‰ь?!I}m—žЌЙЖДјdсž_Њ“g эеЫ›3щz§™3uсŠ1s–ЬOѕtКО>%Ÿ)1юЪЉapу*fЉ„(50СЬUяuВГp}{хЅpddЋ:пEƒmžюM?:ƒ~їЩэю}8Qq—AЊfъЙ;IœГЎ‘…і7ЧлЩЎЧ&л—§чw;єкШH/™ƒВŠ)YˆйaЊ,ЏЊЗЫ}}ž}X›ЉJWЇГZPТХ+Beэєyћ‡FЛрaущ“•”*8ЌХƒ­ъ“W?Юй_S5#+ИйyЭ•cџяNбНžѕ/Рˆ$ЉуЅЙЃИСcrйЄ-DkЗЙЪGS*ЫйLаѕўPЁQ+‰W–fqИnчРЊŠЋjl ЏЫйќiЭ”Ќ[ћбŠ/ойlЗљŽ_pOњјжзцТZќтМХ‡vœ$эqЯdѕ‰‹П6Ѕ\2Wж**XэзсPŸІйFН& щОœкЬщOяuеŒ}м€й?jeЛsЩ џ+^XŒЖCпД™I8Џjп`Арю?$Ж§УK]УZAЌFНЂбp>Ћ@XЌpЌˆЅ@аžjФtG8Ž P‰PЫЈR(СЪbЖа`RБЫЦ„Ф^ў}&N“ЈK@`<Д^ЫПњiэQ}јЌ)З'8XЎR!-!bQJoЃl,. d8иг‚fа&Š4Я#T!с–oЌ нЁ(уpXXL)РiЮУ&x MуР58щцR^œ–Бл ўЛre@ПћІˆ V Є*gн1ЅwŸрEЯœ+’PыВQќЫі№„­ єэQ…*Ж#oќЦ4*ачF Р›p˜бъ-bАjdGh\ŠxГVд˜k%э]Џ ЙlСиЗ\Мsњ˜ лH‚"$*@JDZgЮУ6Ѓ’$ёCŸЧ0дj.œz\CBH–!эœњ$RЗvЧъМІЈЧюЙЧ t'б™ Х\XC Ф Ь ШР›@1dъдшФИ-_+^\…œСY+Ш4€sVХ@Ф™[e‚VBЧ,ь@MXD hжНџѓпrNШь GЈEюs^~zњœCo=дi~ХUTH(хЂqОяpgЮ Э*BРш hЇ‚VЉ@Ъ]Ѓ$Xzmf–ТBB*rъг@лR ю ”ЎтjD!ЛzR)"(ФкЂ ЪЊрСjZЈЇ8d6СК+иWХ%3ƒФ\|6NД§ВЛЙ!V sќ˜§hŽ-яЈнjIіŠLG1n*сlLѓLях&тОк#€‚Е'ЙVqўh~й]NQUе?Њ}дЫ\ГHPК Ь/mш№њт3ф_оdPжюЁ‘фсѓН^Жг–BєРAђ I‘—wG…"™ТУЧЯЯŸ“1sтњsGwdяпўkэЉќЂІqƒюb•˜ЭXПћ‹My9‡ бYYf ї—1&нюЏ—ўК­МQЏtяЃGЧj•ШЉ_жчк=M…ћvш‡>1US”}ѕё$ъўќ)ЛЂ Яœ7mм-БџЯоqFQlwїzяЩЅїо •PC‡а‹€ EЄˆЈ ˆbХ†{AQQ@К€QЊє^$!@щхRюrНюs—r ! *|”Œ˜л™ySvfоЬЋ>нR]z|У чВжЋGЗ^ЪИ|АђЇ#ЛcЇO2 ŽEТфОЩ–гЧ‹Гл“ŽзwФжdl$lщIЬь)њ[7ˆm{gЈ)  {џаdr†2 з—Y/S3LЅЅЦ­­Ё#0Kmб•UџМvKšе&ы:ўѕѕ#аЮWЗФ­Њ[зЮn=lю:zpВЬXSrщР‘гкˆйгЂ­*kЧЖ­Ы2л|bЃŸњіƒ(VХЖSпYvvзсь‘)УLI ЅfяњіЇO~=Ÿ#ъ1mтДљCќddўё§чЏrэ•пЯВ“†L~~˜—ПOц,ЅгN­КvrэŸЗXЁ1IцЌ W СƒRЛ„ uјœmпю-ї27ччJЅuќвЗ& b1i4Rёлkѓ–o,S›§чўќцаnrЭ|цГOЎљѕhЕ RUХБšѓ?ОёэђГЕпйk^неЇрtВbЫ‚™пnK A Ж.'Т УЩЯоKїtcЭGЫѕoŸјТЛњјВqKWыlbўіѕƒb%Ш,К=TWZ/^0\j№уMwI1)ђ\2їА2іъZ?ošKO^5rЩqIРФ_ S Lкњ ІБЖъњЙ•~ƒУЭЬ .НrщrЉ 9ЭPšvzЫв}вy >Nрk•6 ‡Bcqƒ]ф‘ЁЬрq§Sz„yИX/~ЖсћЭYтёѓ_vQю[wxнwд ъJrN|ЕцНSЯЁ§RE;ЬОЅЅЮЕM§ѓq.4:‡Цфрdююѓ•я№—Кёuх_}ЛW0ш *“ІКzzЧЊyQІLъRxшєŽеNбƒЇwќ бO›œpzЯЎЗ^bpп•+@,5dсЙй‚Д‘tlЧ‘ЊМгЋПџБІЫˆy/NОёх7KŒежФLћxВѕд—›žџ5&жЏs ЖНлг_ЩžћОqaпWГ–ˆ~}Їk8ЛцъЁеliЕ “ЦУВ>zћDŸБЯП<ЛjЫъ/ЦOцэли'ћ%zњ—СооаUwxчGc_ћ$о ЋJлЗцп4ƒЦНДИ“œSОЊч’тсП?6@}ЃDтЪЄ–г —ГKч ЗъD–…„б;Х3:Ч3їm:xtѕ*^ŸyX­~ZЕќ уУr"{†нp‚Д$(„а]”HЅнуŽ\‘э3sс“?§|ЂYgˆ*‘|ЏгT›x.^ИTСЩ—ФЗ‹Љ‰г1лчomQxj1QPп cєіŠ№еёB‡іяйEFPЌ9`EJшпoјХ3nRо:PZZЈT0Я\Щ`љtъм)Ffaпњэ[e]’м,Z“о;іб™R|ј›3ie‘ЃfŽKMёU*г^ОUZЃв”дь̘ХJэ\616Кs$ЏXйuм€Po.ј!‚u`Д–'гнЄv Ж&ЃUС&ŸJЌќъЭLггCЭR6я(% 7В<ЅtO?КPhгйиlVE)oД(г„=bг*ѓВЯ•H&|ўђјоnT ‚5*жxj…l@‡З™сˆiр!РjЕPРдВй +ЉP›LTߘwг8/ “{ˆ‰’в=!IjЋЮйž{Uыщ:ІkЇN.Ељ'.н(Ш-­1в 6Ѓwќш 3žЮuDяl!№Ѓ‡љF‚MpBm’ŸЩИ‘vН(ЮGqЉЌ ЌoLАDDЛЁБшGНѕвФ”9“f)ж6ъ,њ~“>xfLї)>.Дvит3'ŠКu ИХБ… Kь?+Ї1РќйЂЕшRІ.{lД'я–%§ШBьНOvwБu1ќzр”кhб]ПИ2ПДчcIC‚˜ž†_ПX|ѕfU|0гЌ+Ÿ­uY X.ѓЬъ—Sƒ=xЖTї›Ooп_O~WP‘КА{T€!N‘јrfžВÇЍ2ыЮ^ѓЩш ›АмT)TЋ lЏаЄ.БЅ ыSSЪ@Šд <Њ№Yt,“ЫНӘЖаяџTRiБхїэ \#o]іП n ”hАu С)5ќЅгёюНй№ЗYЯ *юшююUQЏиvP|OЪЏЃ\4Ы}чЈF9юBЩбеЇaЅ !ЙЦ<,ЪCиjЕK-Щ1уŠші˜Хћ@Ђ№ˆˆAућtт-\(“RSЧ&(,‚Ц бЦЕ‰_ьяб=:РMX]ЪІвЈРFƒЋp№rvmљшшnaЎVaL&ƒР2ВWЇ˜јPo)Ÿ vЊHце%.)>РUШВАи,E(k2ЊH[СЮ&eЉt етƒТ€z‘…ŽІЁљX6}лЛѓt Ж&cЬЎlБyhЂЂh'CSBs'№`ƒв)– N…ŽoХDрЪщ&јDw5†иГГЮ`m мŠSHMъ)†u‚Rб–ш|aCi0oыЇ.8А›Ÿ XžqI“ŸЛіхЂEУОѕ‰œ8эЭEƒН„`#СЛ…%РыЗmЫмѕ,*‹™нэ‰:Уц.ї–‡y‰и­ /рT*˜!DKHф’ш~}Kбй39кЋW|‡E‡…Щ˜Рђ&Б Ј 1Йч>јmQ7/>“NУИ• žюœ\CЁ~9‚ŽxlŽ  ""ќd|Ц`Yё.!" ?šи"8кCep`…ѓТЮчŸџ}!єЬfаKЛRQАЭ‚0Œ(Џ—›ИќTŒЯOЌЕF+”еш­O>ЙžРyЮu(œŠэЃЛDћJи48tPќgo}ЎtФgгЗ|Gэ§иЏNt`ЕИ$fЯ>Ќа 8ЁwЙR.]0шДЭ7о†Qas№ЇžнŽеьp&‡œЄ(P˜ѕfy м;выnЩЗ€ŠJзоЪЧќƒ­ЎроŠ{…T>ˆ‰˜ fceuебв§…qgЭ%6‹Эўvжтр!К€яф&…‰cC“Y}д­c}a`2ƒ$Z)рРз1СaJ’T›-nм„У:ЛђР_Cш Ш UZx]GЏА!š аyеБаIЋA’qуmZЁ<­жЖё Ў_PЛ‘Ъ+Ш"„†}ЂХўt$о6ˆ­ЩАЭ‚ЙЯuމХf НŒЊSА.тШ…‰t9щ•чO“A>ё@њ o]W.h#њSяLЋI5 иmк#Э†eЭeŒ—Г™!–їœџ\мc“вЖl_іщК%~>Ыg‡УЄQ$4‚r›mfS┉3^~"м6]œBЇбш$№ša)ЁефŸЂž@%З_6pF@—dя}[Я}ѓУЕЯ Cф. r‰Ў* ж…№[}hс’Кћ Р‰4„СО ‘јЪV"щxй!| œd‘m‡†ЊЌ`ВœДM]Зђбo н‚hјЂPœNыЕесйоŒУРlр­‘$gmп?jіzs`?а} §ыU#Vќ9=!œ[[Tlt Aч‚˜ЁфШoљо]У]‚ќЃH[š<ŠsщЌ)їКљи!}Я>-“X›@јЏG@УАW‹Н ЇЯ] j“HЫф0ƒ‚dоБћэЕEР‰aЁЋ?\U|­xз—ПыLjˆƒ‹Lаx‡3`5ЋYYЃђuї{эѕWЯю:xѓёЖДaЊpЌЗЎќОјН}Œ’Ncž?41Щ?ўкo›>1SЧO˜;Š`€z+ЭюѓŒ ГБEФЂ2…‰гЦŒ)}gз'ol|ŸBждЗп•Je‹XlFƒОs”ЪтK\ХlРXlљˆž&ОњЂiй˜рдсn‡зЎ~х•Jѓk э,%;_ћќРщ,фѕ IDATгВzс[ы)a/яX zшЉѓЁ=OЗэ5э)є_Ьу.s;ѓЫЙъђšїžј@ЋеАиl *HMw†EWQB7瘎+aл—вщškщ•оток808УГgїЇшО_єсѓ]7aИ ДышwwБ€рFgРЉ pп NУу~}sёуkмН†іljI68-Тlъkй[Ч.9Y8в !^R*„gboŸфыОzЉ\;yж+3“=Nјё‡Oоzє'Tgї™SgО2•WК4 € Lе‡?џсћw–ЂГуC?oБ№‰™Џ Ё”\мЗљŠ at`ИŒN… ‰‹МœІ є№pЏ3ХK— •К3bГ(Ц§ Л_uУžФљјЁ§C `Џ/^5eёo'ЏiH,їйг?`Ё/m{uPп`ѕЕн+WŠžtw—ЪvPp—CqŠ€с*ЈЅРЅa0АIa4щД Ый‹žўlвcяи™˜svlpяхJа@j­ аM zБ{к“_˜&’|ъзu)!РчЯОБš3oЦ›ЉЛnцџЙгGЪ€єF,nL›їъ+*Л‡а!ЯM iІ№—ЁмВО66ёсe­С—Й‘c:sBі„A­†[GѓаЃ7kђ PцjЧuЧ9‹чЬЙЛ УЫеS.–‡„У$БЯЬњЃ мЋа?’B%ј"~у ЈbXAЄАЕ@ѓKП лPpz_wЇЂа9|.‡EL~§•ЁsеTОP іk†O˜9иJc#iAh—iŸt&Љ 8љQфž#оўАg•JЏ'ilІP&с0щ /.ŽZЧс9сuщ>іэЭ–€ М8"0ќЖВ,ВЯ[+ЃUj#зM.bƒћ)љи 3Y‘ 4Є‹мјэржzќ№Н‚S§љKѓЭ7пzы­'Я~ъЭ9 РWˆАгь`Б@Ы№šrцћг ŸЂ­eJЄњ[З8ссцъ*ey•Š&х|ДБ­жу fђ ˆ'pфBTB0iˆЈіФ}L&‹•`!ЎšШ€Mэ?ИЩ`Ж8э™Q=@ќ4-pYA ћFJvfЃбLЁТТ‡™0‘ўЈcЅл†NДvRG3б`‡вС"1@†ѕьд„_бЊr@i5zіЩ]в‘Гf№р$tЫЁ:‡r"8 Xе^`4 AШ|dю {•7ЁСb:dГ4F3ЮфВ)ˆuиЎ‚6Г•@l‹Vc$€<№ъЈW,6єioˆ>ŠY.вHi@TrщлUWЏ˜zѕeO%Ј‡TїЛі‹uKч4oоМЯ?џМйЋџ@4uHъЁc“^њАИTVЉЈc Л{P9\ќњЕ:ы—№Б™Ф4Ќю0tzэ8ймЉ.јp;~њэзяЖ˜>lєьQwЪfOw^(СО Oh6жЭH˜tшЙ.f_q +­ћДlў€`йчМ#ƒ#жzYШю\o}q{ѕЈr№Г—гЁKVЁˆHьЪJюЮђёЇц›ПX Љ ?ћY!Ј=мчNзЃ™;V;xвР~cњ€dуsдНhЖRЉuxЋ.RПэбfЏъfЬэњЬЭц›sДВ0п‚чл,бQQЧпvŽ@bkc РБ“Ю'ікй”мЫЯ KПI=1zod,Ѓmу#m@џїНІ…ќє[ИиW‚№ю;ИyPхќБCЛцЧкз–H8(џН^kt–УчЪw+ Юh—ЅИZLšАpлˆ ОЁ o‹JQ№ђЁyxQuZˆŠxћЖ‰<…юы_ 03hf:Ѓ@hдiа™‹УСM&RWo Jwи$XBЬКŽ№п‡Б9ШЮ рЮ_жF2(ІуЩьDА_ж˜Ю€Ы#ЂмyЄюъѓп…aЃЙЇŽыoх™язѕи.хпб€˜-Ж“—{Ž•‚T‡;oр­vы,K;КђаяпЭœљixTHГюŒЧѓЂ EЮ”ƒfYўЯблWtU%Оe^^a{ф2+џu3Ž.їщщ‰wяAЦuЖКИэbўŸ{жЌz8€tруfcв}HШа)A,иЦ—ёЃ'0фzЇ€Јф щ EzуЦхпžЮ`Ї –}Rѓы&u|2“Яp7єі5Ае/fзь9^rрt™Z‹ф,`њЦ†‹wwы—,чВiЉ‡^#muМДf`A”ІYЪƒН™MR„jТ”ЅŒ хsЦ 9lЄvНЬКkП:=Нvьh[HШwћzh_ўˆAо&ОAЈјс(k •:р8зy;L‹б`ХApЪЗСЙьНxnOћooѓНhI+0џkˆ ьџЖвл†W:ЕnЯћ5FэД&5$Жјрˆp -˜F@ўvfУ@d2ФbiGЪџCtЩ.šaoХCƒY[ќLї.1.‘ кl™—›зЊŸx TхџХсFш{O”–WейЭ ђс ъю6ЈЛЛ‹јп‡Бкљ%и,ŠЇLbƒфЄXLгHhŽžd™ЏkЖяZ!хтeeHˆ3WЌ€Г‘ЦЅЄx ZƒRЇѓћКgаX5ѕm­…+Аиmч|ЄQЉвЬШ;p|mG$€ѕ„ ыБ…5џрЩBihRŒ+ыолнvЊкIštzЃСЈQZEоbYЛ Џ’zEЅ. nяšs7яљsЛаР=oХ?TшЏdх]2Y›СЊГ‚tAЖЌpZ_Y а(Д 8.d$K( Сjšiv GъЪЫГŽf#“К‡7—Ћ‡ѓO§‚(ЬoћyЯФ$ažеVы),Ž@ЪЕЋмќSuuРiIгљЏ/Pœ8‚tк‚Bџ}R$Ѕ §О“Ѕ€вr 5Ž^ЙЫXКЙЅіpїѓМЏbczŸр(jБ‚stЛQщЩЫyF/яšИ@Cˆ‰QckUT ђё7ƒ)sѕЊSŒИсc|•ƒ;›>ѓиЩŒSi'wЋ‡П7=ЅЇЛ9 Р”ЙaэЮsхВЯzC[яЧІŒ ##ЮтpІЙЭ™ѓ—~1fбкщНFl&•dхxМњ3ЛMsцЗW/gйf~ўЯWbм›Гйћl8ћсGЇЃŸџh0гaqщ#qЏ“ ФцГПНУpd@—пv^7сщI˜‹§Šя@$ѓЂŽl˜€&œыёДZSЗЮып5ћGe{п\ђG…РƒG‡›™З„™3u˜—ASkХй.ŒЉЙ–ЗoбOyoоcФFZL“бFЛ рл ЉПvіќ‰пŽІ­ 4hтТ~.џ}yŽfш>E]хдд‘м[4kR-ў@к LqŸЊџЋеЈ4рнЅHŽ@xtР№h}“фƒ{Иw §UЈџОrеЕ–eVE­Mр†+­YUd^5§d:Ykс\‚G7№XwУ1ЏS‚§ иЩДN*UЕ|“нš (ё Џ ФFиёAЗpЬXБuЭо+чВJђнњƒЫІњ€68№Ёm_жъkВЊ\{t ї–0ЭF=з[@!l9›vœwIе7€ўДq’…ђ)рUЪžч d$‚§pYь›ecУъ˜$ЈС rк3:ŒЊ4dCš–…ndЏй|оЇЯФОрvеЁ/^ўйЏzЅ"яz`НMTЮЉ§YЉЈ5R{PT—ѓXйыF…юmx@8h'KђJ[”H;Ё.~€ЌкР“˜{Йч‹.Б™Љј9ђF2я†Rф€ЦLš №Ф%ЧИzLs@o ГVƒЭdR]Э(ђ4ЖП7|№$!ѓсZTъKпЎЫL3'Х‹ФŒ„“v!hl PСвHU€5Й.vg2 `Zь‰0ЙAЇ ”0aтУ_Ш "hі(XJЈuй QЗ—­:yсф Е{ЏžнƒxVDЅP_>›ЙgчЙj[огм€И[эPЧЫП8CFpOец[ьж ђ@K‘LжуЛ—œИЈ€efа №єЦфN`эїЁ›)…хІН—tАƒћи›XС@‡ЫчГe4№љ^—ЌщнЛ§ГH…еU:ЭjЈЎЊ5 ЁЇ›\ЮЇSЉ‘sŸђЃp|†ЭЈ-ЫQX"W7и‰5k”ЅЙЎЗT dPXžЏЏј/?>{ьNtОЎцZEО’puхѓMЬ?БлЩCн&oЌкЊ‚SяЌYйŸФећFЩС гY­jE‘ЂRm$щro) э#&НЂ0OQeЕZ.^R ь*kŠђk)<†IYЎАzFњтŠ-MРФ4ЅХ*Г…*ђ•‰ˆeвUмЪ­Ј$Ф”‡xKD KUёБWWЎšф'PЛ„…ШЅL‚№у‘u”Ђ]Н:џVпvєkЊ.ЩЉe…њЈ=ёНw#йRЂD’ъ‚›Еt!Ы\[\Z юЭ]ƒ}фb8}пмі€ 6АфkMлVzЕ 8G‚РS;:`„ы]L{Л&ЂЪЄZ\›мŒ[ xѕI†Ш‡ЧIСК‹"зpEЏг™ѓЫV`J;1uф˜q~і|$Ј/8}tЫ’MsTI]туy Ma!Е:UnњйkйеlЉ<4!TЖHЋЁІ,/=Ѓ ‚рŠ]C“ТЄ<ТЄUUфы<ВЂЈRЯѓд–˜јЌК('GЩ–И„мЁ,пZyqћ ‡*ЫЬє>оtќМЙуЇ\ўжЏ pЋйюх€к‰ѓПјАfћfuRЗ‘eЕ‘ч3Ћі/=xІLg@W0й%F ,До‰Ў`Xё^Я nиL#c:рO–€гjчpхˆ\}ь˜ЛY<–‚ƒЌ:XТЃЉВЮ\/Щ5FŽёјs#Т8—–}ОŸг}тcНМБ[лўpг+rќќ‘QьМнлјЄЂЯлzїётPiL:Љ7ƒ™ц&#Vu~пв?гя“„ЮL:ЅЖІFYЭ‚c7ƒ#`(ЮќЙлЈ'wь^}tSд+oL›ЇsтцЅ=Ћњ=Ѓ*Wнѕ™Wц/ь*сcх'ŽЎњў‡ДRWAK˜5mЦм7Бэќ—яэ4FЪЭйчNPžлВHће{hБЬђ{.Wхiz.|ч…т9 kщсƒ+ОћюrУЈ %?;sжмžКЛwY-ДЭ;О;PѕіOŒ bPщ,†MчtзttЃьаЦŽ…Ўљ ПŒe>ўЪ‹КМ№ієhнxњн7~уt РЏи}]WŽїxyЮ3Я ”В›ь№MтŸ‹< г;S‰УWжл9ZuФ1Ё‹0vHчЛъ/г‚НzžУ§x #=уљыїJЬ‡ кк[єпЗ*•ђhњсє… LЏІѓЋЅj@0ЄЂДЂЌ†w$‚ТdвMeйчвŒ|яŸ;sёNЏѕ‘`ИЎ*џЮVdžО…[„.š>3Ш\^|fеІ_VkјTL4}тЄЩqцТkћоћќ$Т7–Qxбq—>њ"#0•fžk­ьШ$,ЇМ <_AЌпОOе}€ЬC"рУ1 ш“`ŽcнЙвв№}F шкgИпоМ9гž›.@-љ7ѕZu^aiшм Ь1љшлУkЯŒ˜тЁМprэђГ’зП;LxfэšU?ЌмЩпlЎ)И™CК{nюдюž†В+еeЙ—В%ЉPіщжЪіM}ГKDp™ж5lідС]<9uжLZžgэъ[GІЛ‰SљW.+Юœ4tŽјџ‹G–iс~"!…eu”|м8‘Oy‡сцЦЏытŠј K’T‚БЉ& )фџu-L№гЦ=}ёмсQо,ŽwnхщѓWЋUрžУИ8’Щ†‚WяGцЬОђклЋоўО†›њмЃмФ`яŽAš0(8РТ0я„[ЂШ?}Ѕ–_ŽљИіlу‹н<;QyЎnоХ†щAйœ;ьЩЯ?щ#І$vЁ§x ъo]=f1G jЎ8Ч$-RЊБЊJgЕ mzŒћшг_?7X.ЄZ1-1Й#ц4”ЅPЏ)СЦ{qж!›Е—А:§г+юF3”WjiсоБФ%™‡—;‹ъюиYlŸGbmFЬЎ:‚apтvДm:Œїф+kžяJe`~ gw}qЯбsebCпœŠ…'‡_-Ў.ЊFT“ћЛЦЖ2 -Ю{7Ю :њKIі}ЦЬЄЪQF3ЅvƒњлЋЗЎт"ђЮrKMAк9]B•ЙЖВЃjIЙ sНRзpJЙиUю"ї–х$F‘xЦ™ЕhVgSyюѕkiЅZЅЋЊ(ОnжШГOџVA–нЈІ‘ЅЪГŠ"іŽ9ыхбсVЬ\QŽQЄ^qcл.ЋЗ1>\QЙU$sq•№`Lк)PгД?БП5RъА1М_7ЊЏх…ЫўoСњЋ…Ћ”ЦЇЪ€…vх†ЪC" їяŠDі#яЕ\ю_mєџЕАа"Ѓдz)“ i/э‹‰VЄЇgПУС>ƒьЙћ$Иo8DzD;њEoРЋ)јvИYѕ˜зИQsЇ sК€Q‡СНбLЭ&+xqdвbЩrŒ=у&Н†$YT蘣thХ•GЋ. /УЂИ>!ž|tЭТБwAE™Q+›—хаРАДНlњю?ЫOB ŠМgjЈœЃ3šVp%Wg­5ИЎ§uVhQћ­Є ьƒршЊŽshzмФFж_ €ќAнёц^џ}PnlіAР™|ftяЈ“›O™ fŽˆг/”У`Фю"€I ЉюtКЗkѕ1FЯRŒТД‰СИ[,6№"ЈIiJŸ|[ œйюDhЌ ВP(мшЇЇП6бО‰™ ˜бvфMЄб “ Xѓp>УXК‡\Щ[m&‹ єИ™0W`жZ †тыЙ–20Л/L‘(Ѕc%‹Ius,А*@TІнeх<Ђвf3š­fа*Џ“БAS І*Њ ~€uŒ&RGИЗ#0hчФ]y)Ч5xдН­Љ)t`l>WБчXЩ™єJЧuƒУЂєJpмн=!JьДІй;b#`2’ЕеЖђ2›^Mјњк<ђцMђђ%R&У}ќяяќ›ЖВ2Rъ‚ћњтœЖЈЬ€џTЗЪЪ‹U^\_\Ј0r9—ЖР!иwР‘Е7-нС‘D$ї’п| изuxя`]чŒz“V­ЕZ-НQЃбSСS/ЗдVWiq„ЧВSŽMЕрбНLФ†у7ˆ аи\ŒФVeWдЈ BFд’ЄГ8œŸЂEяBЄГ=™ ї O=ѕx/Уjеъ˜:ј2„Ца5ГIYЄЖN 9о zш”ччM‰qaбЬV­žобT6Ѕ2ЃМFmdаX€МЁ&ƒЦ б*ЫdzTІ2зTThщrOC-б‘PЁэXUvAy9ШБаЋЎоЈЂёуМлoAјЫсBlаяКЪJeЦСЬЮ;Щ|Рq–}„кн?Š…QВŸбЧв+8 ˆюAe лqLF%иПсX\Ѓг~П§ћŒРrІ•ъЃеxЃФэjэkUyё­2:ˆˆ@ RУqš-oSFЩ8o™]xuV8ждƒ€‰dЃГЄRЏЮLЉ0tјМWКШ(6EcfЂњрєc…ГWCці•Х™D ‹R{­<џLQu'ИѕйFIUЁвiєšAЉPБLч~ˆълџА§‚эЅЧІ >YRэ1Щh=uЏЛЧБгщ•Л•9_nД;­…}А{'й n=у\ї^?ї^w№>РЯЪД­јžМp™n›ё„МЙ9GСДф+Ш Љ‘ж™3l]КЖБ%Тf]Оџј*^–$Љ8ЛПXф71%T&dоРiv:€ЅJї/_qA5ы“й nЅ_ЬџdзЪ_=dгКХz00uцчВ/žЎU•]оФTPдudВŸЗЈ&ѓШіЌО$њБ:M™}срF]&в&ВbтЈaу"фqAšwїэŠАі88Ь‹юrэз#tš!ЈT“ .ЗОБгћ'-ћъ‡šœа@ОБЊв{ШЈ„ЎsfиbЃue ŒсŸ0gP—/пћlЙКАKЇPјšШіH Q.йЙ#Ю2.5ФIБ(ЯЌ;’›{ Tп№{Оа­Я)ЎšтєŽеgƒŸ]д \Bмn\д~аЂВАќЛЖIеAaЌЋПЎ6Ѕ тyО8TбЦWМ?pЎ„—Т’BрОыэ{ЗXХ`ОџТћfхРЇ–W•O5№FHЅQi*љx'5-јъZ<т}C­ёиw'ЈрЮНе7! \њю“—wqб5‰ЪwћњтшнЏЏxgцљGп}%|McuJЛpuЂвшt Мz'tєЉТѕ[о_pЮ“M'…>оЃ_ЮЯ)3Њй)кzйя/t ”К]кЗќCЋmТШЩЉBЭљ ПяXѕЧ•B……–^t9­яфсУ&'‹DуД­ŽђПэeD4УER^QхzГ6ьЕNФщз”@oЊЃJS'ЕЪg`ѕЊoВ\Р§ї)‰пЃjиДsжь[lq˜,ЗМцJІЦж9 лBVG.ЙYЁЪЬPuщкH`…qКzлjђOmЫ2г„c_šм­Г'‹b“Ч&ФБМј,ŠЅІЌФ8ў1бa*MіФТiДŸўд(ерў Ю]ЪКЊ KђД–нМ\d ьуэ%Т №RХАпЊybBTеѕЂ‹ХކxИѕ‰‡Œ~Вoж†МуЧRzyH<КіLђvAŽА€БчлЙзp­œчmnЏх‹]ОиВыќС‹ZR}‡тsЮм, eћŽвкOчœ~k3О[њЫюSЇPYЏapіІ„O˜з?kmжОУ~)Нƒф€иД9‡O_еу)C§iieЖРј‰=]9 gгиve@ŠwЏ>]BE‚еˆ RƒMйџH3бйЏќєlЯЮˆkcŒџзЈ?6‹оLcбяБСxА0(qœ?u9’ЄPбХ&2К#эC„ЄP(БIЋ*Њ_ђEџpл’;"8K3”^8{Нд К(AcЪ‚Лѕt5*ЪЮIз[hƒRфuiЮ-‹Gh€ юP•y…E5ьА.^р2аЊЉКqёbNЎж†QEžЎa]bљ6UCfh™ЉVйmНlЇюq\BŸŸu§к•"o@Hч`гT’™—{­Ф ўpэГанУУн‘œŽpG`Хв-ЧNЧRhЌЏ^‰‘њАЖмBѕоуЅ{N”‚Йи/.№Я@j_.m/kјoЖќБэўcїВпПъ‘куo‚zŠ<`йА•Z^ЫЅ–GG›D<“sTЬ3­пB+Wƒ"ЊmТ(УиQі•~Чv[2—}џu™ЯТЇ†„КСў™- ‹*‹ ZK\ЋiLŒnC< Дk\щ IkRаŽ–(ьќ ;jЗ,&f3aШ.РЁ#нж†`вaF8:ƒ8]†ЊƒZ9TЬ`ЈƒЯ`aИйhT "Р„;н‚щLщœnlЮQИЊБ1\йЕCPЛ] c˜08O; љr‚‰|;| ƒ­!Xє Щ‚X“fж"v Рчв0iш~MќЫЄЏ7>GЁƒЂ-є@kЮЭУпл_Уj0b0а0ЬёнуZDŠpТЁ‡т Ÿ„Gl˜$ оУ€7kƒ‹š[XЄ`,ћœЃp]"z ‰шФ‚>|cf€Яр7Fл,kУ8Aт‚;Хƒv6Ђvb,ЏшПшXћЅš,phC#‘ГБеOџє0Ц’Ќu^13–ў”Еёую >№7kу`ѕ Xh9љj(W г!тxПиГ lёю=AЖпrўtЅдЯ№qЕ5‰Киpв|ўt•ЬbнyтNнaѓнЅFŽ•ЂЗЫbJsИШщхиƒYяЄWjУ3еЉaiбˆщnз1ё:СVДK4РЉgџ1iэ uЧЖfFXЇ.­їУ) Џ€вdmЈд93ьЮQ(ыd{ 0+Ь=(kх€RЇzЁ§:”ЇyaЫz8_]п6\ьоIЪЧuИ–ƒQm˜К~ЌšПёŽщшd‹hЉ§§‡ГOы™СЫпНLЃЗй}˜ЏЗЉ#"|дjG“PфiЈА 8ЕЉ ЭŒN.0W7>Hл" ™ŽsДЭВ0iакЉЏ@C]ѕГЈОвŽпћ39лƒуЦ–a?яЬ›1Цщ№s7еЋЕцƒgЪф˜–Um'+`<Ќ^ ъс&В н ИŽМ-ƒŽ шOMэOгCpЛ‚y[”oIЬ ћ˜Јj FCеmhЏЙzB,ё§ћЙQCЄЁ%­<Д?чэ@n/{{ЪэЅZLaФ|6?ˆ)Эћ>V­ХњЧAЈ$Ёмъ-4Ђ™Л­Ѕнѓњ/Я hQ eл]янvЈ#џ]ŒXв рgeV'­к–ж„н]юBu „ФЇU€ќuPЙсЮз#ЮeP7ЗnБ2Z‡5ыЛјMВ"Љ} ­CдБ†ы9хRn‹‰ХZЧj([$сŠ€ цM­+жёгтH|ЄШУkуШǘэ^$ЖyeЙ•ўџaкчz§dОћцрfьQк­б‹яjG‰й5 ЭБћxщЧЋВ?}1ЎЭжƒyZИ™С§ lk”eЇP'FIьVЏРкCКл7Шраj3ЇВLU~ЋBф.tё•Е™Й‰ЕМякYѓшвмЯЈ, $™6ЋјkœЊlс\ћз`ў_J[…џKНPiЧZjљІИ1Нй“Ak8ЕщМСЂ4k@ГWmEaœ%№лр`йVоч{GЗZо)юu +№cuЏЋiџйЩЁр~њиХбѓ=уяhЊћъЭZАzŽа*kъ8,Ё~|АВ? Ћ\*z-O6щфџ;Њ›f-XŒoЛХY%i.‡tlБЂ3вЯqШ€ыњж ЂоЮНЃRЋЈЌЊ5s]Ѕbо}•A…Ж™ufЋiЉQСЛ ППsКэaўфш@lѕ цЗС‰~QŸмТЏ–P•зжъ[`ЂЖЙi’YЇЉ,Vр7ЙЫ§иЮr;ј@…&XЧЎ{Ќ’мЎ:јіe Xї1Uy744ю§4`/2цŒ†л'ЋВЃ%ЬІŠeХ:q„+к­т:П‡+kP7wаBѓuџя;BћЇО~^qю—kПЫПD’;Щъј‘|›аVЋU[*ВггN_U@†(eFІм7І[\;‹@ IzYKvк~Й6pњшQ1тVЁ§н—Шœр.и{#™ŽьиsёЊRЇЗDŽ3dDЂЋЉЮўнjВђˆ­юƒWдT<љцlЧЉаq4МгTтRИУХc †9ІіO›2§ъжWц?ївGЃМл_ І;’МЕ]М6ЕПœMUQrѓђ•s‡Š…aб}пSмfХЪгў\њж†œхсУўдр@_єЙ_Сtnъ[? ™ѓЭг ЎМЛЃПпМБНw*КžЏ^Й-oЮј ЈЌ5э?UWДєЅОˆOя—,+!QСџ#“ПЫэ†€m,:‹CпІI)Р  c ђэЪZеЩkGd]PVœ‡˜ЭCп–ˆpqў‡‹ cЊIŠ6вdjЫ@Vg^<Му˜JцЦŘ LŠHЋЗЊ‹ Ъ |__o&6шЪkJƒ*pLbЧо€кPŸ‚ъGqьдjB‰QћлжЪV]ЩШЗ‰ƒ‚нPO2]џ~GF-сб9’Мq~чЇпVXxOOŒтwЉэуиў?эšXэїяЭiБZђЋoњ@=pXёTR7Ѓб Њ B˜њ+z Јjм} щFBPЭП{™|хЭ7Kt"П_Жlў4ДЪTЙуЇ+?пЅзК ™ябЋЁ ўб‡кЬƒяПИмбwцhЮ/пnзJ{}СР`ћv/ГЏ ‘ЭbЗ,іvЌ-` ‹њвс3о8ѓѓŽ\№y.ГњєхJp"хР rЏф-)Zr?я‘m5љўНggЗ5jѕ‹ U CVі]н"SТлгРLюŒдPІ\Ѕ№,+ƒЬ hoЎ!jвѕ&ЮЂ‰lќX3эКYЇгGŽжС‚Ю(Cц–0rxjД.Ю`qyєтеЧ6_RMѓ]Fх’>ЦS@—жЌд› 8\Юp(`O vЋЦhбƒъ(NаЈ,„amz{†cЇеЂЕ| NЁИЭЄБи,ЊB‹@і!hVжf4^ћlуяnГЧq#}љ`ТЪoќиЩЙП”ЈэFN~jЧЮє #B€џz_k­пПсmbkќJ`-‰%ФЅ:ќУ#Д*іb/DжЗjёвнL Nр$Nхи\St=ЎSkк:кС‚г>IšэJииŠ>FАРN Ќћ9t aБРG€х…ЮЕ8NЗŸѕL`о к'NqВtгЁѕjТцM›&fЭ€`I ФЅиt8#GЈHV Ќ™Р*ƒBtС i“SтЗ|{д:* ˜ А№€КMЇК`k б^@љmЦxЉBЪ9ˆ]…dХи@ЩМC`#0&hћAiCкЦЭљђžЯЭе%\!ЗМўњЩєСбžђ@6тЖ“jДWaя b!ж>l а [tшBio ЄРиCГРЋнќъ)ту“шЁх‚С֘0”F$щJ’рL™ЌЈГBЇ@‹ЕWaГЎ эcя#њˆ“ZЄŠN3\АWSW~к Ћ $A<]YEхњЯз\ƒќ€ъКu–у˜^ёЎЬ‡ZaЌУroІнrКм o" ‚’ƒллЦ $цS…?_ф‘вЏ2џКща™ЅР€JАNнfЙОaВщЏсЇЯ˜ЮšЬ&0ХаXАХ'аˆц№dnž^ˆЬˆdэЭ‹GЮž<Д[‘“~C5ДKЯ)ƒ@D0ЈЫ2ާј[Цљ3ЊАО}†MэшЩ!55ЧVГчPQ•Jд{ЦјƒУ@6gї–tƒŒ[›}ђˆЊпѓу…7Ючсn2JХпЮ—нg>:dHИ„OЗV—빓sYлЕ#П^ЬИєgеЪCЛcЇ?–:*оНW<ь`‡–`љyвЌљ`В­юДиЧ‡;ББ5љўR-іхyI№мY†W?мЙkЂЦ#ёЁIјš$B_iЪТвЕ…љцйКx7 ƒ"3э—/~йЖ?ЧЄ!Ic^н0mн€&PА)o^;БюCЪф1`ЪЄКфмяћŽЉcžŸлSV]XЗiх{лoсИgTФSЫ?ŒbWќ‘vт№Ўђ+GЯо‘2lСcq^–KлжЌ§~wFЎ ~ьЈ)Яѓfфл{"­tqrЅ‹КŸђќ0™›\HЉцqЊњZЁbUЮ™ећђиa“-'вД!C†ѕь,d˜Ос›?k‚GKTэ^sЪр%Q^јc›bдвgd7^6;EЏМLzЙЏэњх\A{№Ђ“&uqeW\8­Šшы% г~cиД?r *5zuкЖЗŽаЇNь‘РI_ёэ)fDюмђoNTW{Япј| цЬ[/oЉЌTІООdцд>‡fSфnyяе ЛЊеZїЩ_П465˜УДœљш§‹юн[-ˆюйЄЁ№шђныз^ЌQЩ[івФЁС УDVмXџЦ‚ { FЃчŒŸонЯ›N5јфЭГ.§ŠЖ~џГхэŸC—M_~йhВXЩgwl'iЪЕк$јhe8BS6шЄbиˆ>žO?,фпW‰ћŒzџа™ДрфрВ›eU…е эcА>1>Aю )эy`›q#“№ѓфеTњYIAЄ”@ 6)”3ƒХС…йвn­Ј m 4m*ŠЌєL‚сL™ЇœЧсЙ№y^ю–€”ир„`—ЊЅaЪЬ3Чs Л†DUfnнЯњzЮёЯ]ПѓЇЦ.ЉЃKЎэ]Жž+еЇ—GеЅ#лw–д†&єŽ‰p‘rЫЗйЖЋTэйЙ{З0vэЎ]ьpOŠcyuйЯe„sйDБ›с)v яттЪ„*2Г€&smоЅ_в(n`SНЅ^tЄЕ2ˆ­йр€‡mwУ4xє`№вЃЋХЩUnR/OКМ—Й<‡SZцУЬњгм*…4;ўУЈ3ƒžYБ4DŒi tАuуЌMmждd]RDŽXЮЄЉЬЛzНШЎ$e—Яюјњ˜ћ+o,ь)6дXD|*ХђєОб‰ыљдиHїм?3іЏk]ћKEвШ'ЮeœлГўѓw8вwFv2giЕЁ.™9' Б,ŠN-)ЈвъЬ\І8С*eТ§ˆд”dlљaЋЉпИEЮЫљьЃЯЦLЗснŸ^іДѕфЧ?МЙН[џАиѓІО V‡ z}C qё%ѓ?’ћ}˜У­-8ЗхЋƒ­Œ bQИXжђЏг‡LZєqПъmЋ~xbІhп–!m?'Ь]гmТGПѕ4нђЦ”7нO-ыъЋВNm§ь1fЪы_vђц—џ0ё3ХЄyŸN 5ц—s<љіlГ‰б--БфјEІў˜^хžОЇ^}јgаёo7н:ф‚ЉЁЙю'ИfsХœN§Ђn8.;`0(4 7Io‹mb чСЛ.ВНg+˜ДђЧ<“іћpŒiђаAёъЕЪ•ьхWЎdUБ Ѕс"ч"wzFTŠ‚‚ЬЭЛg ˜аПћАЁ=ЛzE{„ыy!#іJr'/9pŸ—$3эбкѕУЕ…ћJJ • ЦЉЬtŠ(РзЭ],3R9u§VYR’›Ek2t™:gBџXO.‡Ќ MиqOOдЭGЙ_uqбЭвj•ІЄz[кJDчВ q1Ѓy%ЂЈn„zёЈhЭт˜A_qюЇ7жщЃF>?;Ф2;л>хв;[“‘Љd‘Я$U~ќб'„mA/ГРˆЯ=NёgY™nšд•ЪУ-•z‹хOЕŠсrwч`гЉђѓ.Ÿѕr›ўй УЛH€жA‚шХZйДaГ6њD:ŸpAъЇMЇ7*ЌЌPџ>‹ >9^б.>К_lчШ‰U‘}Жш–NиN*‘0м%DaEБBiЂIk`—ё“fЭ‚№ШVп?b _8"ьЉ-ђ№“gѓ._Л•ш[~IY=2:X, YР=aїёяО<О[ЈŒF1хъo‹™ОtоЈФ@1ФЗєєЋ—Ю•uѓaСв ŠZ<Š’TЉєf‹U—2%љ/–?@ЖІЮќ~ЩЈ 9'ДцФЎшяьŸ!ЖEеЌм|TgВъЏ_кXU“œф'ХiŒˆp7ѓя7 •н"8MЁZ‹#'>џѓЂо2оS’Йuжю#Х=щE?зЈњwZ"&JЎџэzAm_EmЕŽ˜Зqщpw0хCkГђ Ћu1‘]уЙїьБ enVаишp Ђ ‘X`ˆ—ЛˆKЗГЃZˆJEb.ј‘kЌШ0Рi 60  KT5i‚5щх)`Бh $ ПЎA$х/у1Ја№•ряд*n@ьGЄS {( xџƒ#ЮЂеъ1ЫF­hЋ НV,ТU lvdA–nя‡•„gИћХ‡ЫEвЪ ’pЈ$н)HТ‚ЬА­јЮиўbѕИ/оЌ єо7Гz…‹˜ѕzэТYУщуњьLФs…РbсB^ёс_О||BЪќЩ#Q’=HŠ$bкЋЇжџ~kX/?Яћ&8Sп‚є„3h€Ьљ•zЕо-ин#дУ>Mкл\vpЯL/–vеNєѓѕГђЈ@›ЃаqLеЄˆБЂВъЯТ=7…g ЕVКХ nЄZ Љ\ŽФЧн,c О4*-0GuЕ&­ Ќ #ŸЃ0C`qС$‡З`аФўщaн,œLю?fB’Ї„Ю=yЎ2О]s<…РJЈѓŠl—ŒРФFoф?-l(Kf.ПyYАє€Љ+t#вQ€[bеХуЫо_G‰2czё†луўДѕ?|o;[у7‡ѓ]Х•џBlЇXьQф—ІЏ`ўљ"Wш%Lш­ЫNWœ9f іJ`ЫнŽMЎБtѓ' nЃ-ЕхZ3PЩиЃq*lЖфтШ ГdЎрhh2еVg`‚ў№†ТЦLžБlќИŒ_Ж}њцжO#Уz:–š^gЏ;VXd6еFЦѓјыГу9 aЫ†ТV›]жЃЎ1гf… RnррFaз‡БZЭV+ШZSЈ4яФЎ~ž_От<]8ђѕ 1ЌQЄAŒ#—ЦЖ:GaKGЋрVyйаЬVœЫЁАНМ{HјiWЪUz ‡Ѕ/Иvб`Mђq˜T›Х цљРyУb9ŽœŠеCЎEHб9и,6FјьЫiЃУ„ t‡/­„5Ље‚(Xф4‚П_›•KZ5z3IКЭЦШ–ъМїжD†nqА XH~DŸїnєS]9ѕvЗ_јІгбOћЪЫИh EwftщЮŠ‰cnњцЯп*.уxJ€њŸ№Сш~^[ї~јSжђ7ы“і_8юˆнХСIA%9%СIp7ЙЋс09ОМь WQЋФЫJ˜L˜Фc˜Lм-вpЅТhШЂ3АkР`0€ы6сыЪJЎ:s\ЩGШˆЮї іЄKјц[щ;NDљѕ№ѓТ% P Ќ;(ј 'K КХ„EџіjNИ'/к…4Њ4T&›Ы…ЬрЎБсВи4ŠЪіЂШƒћF‡l;вЌ,Ÿя)­љўт™hwоШ8O‘ўФ‡[ВчФЧїМqђЬu@А\П}ќ9p@lГKœFрюf˜SСџк#"$lїš§ЬkЖмъJ8(eБ˜bЊб‹Д˜4JKТf1рЕEc0–ц‡ЭkeŽа?8>ЙњШ–ч–ГоцЧУДz<Аg4:З5Vq]љвЁг'Ц…Эk6Ÿ ‡=НБ&?їќ‘2yŒ;I0̘3 Ю’p Yч37ŸК”туъ›~eЩЩ-”]ЖY1`>лЬxzйЇОгќ'MеEЗвrЪJ+Ек’ЌSWMўЎrЉЉ0чт…RЖ_xЇX9гг/>Dznг~EзЁQ!nvЗЉЈЮ]kЅВБмvяч АС>ЅзŸгpFѕs‘љіžгѕиkЧЫ(]Й>[oЄtŽ№чГхЅуG3iё}Ѓ<м`q6BF—;ћег^ŠС3(iŠЏчђ9ЋdијФhЎВ‚ь<†6 BY ПњЩ–НюЬn]$йы–]FМ5 ˆяу9УgеђIЫ]жNˆ тд–—2ТТмЁВF€˜ЁшрЊtI|А„NѕІs<Љв•_ЉrВЭ:-кд kh№Y|“ n=к OMўѓtй…+е ЧTЪЖВ?,я, ЄћIМФ—vБСœЧ%Р'рГE—о,?Иђ ЪЌ4р 8ZtJƒ9g7•R9ђ™сЇwž;tуцœ‹пўЬvqрЎьјѕЦя№AIL9hЪаО"R їќ}пЪ№Љƒ˜bWЖNWpІс=C|-^B“3~ؘڏўќ}У™эpT#ћ.xЦЫ3ˆыюяЦ0щŽщ;G"y`ŒE"dвивЏ=AЌZйДЌФПџаАsлNl\Ыr—Єі›dПNaEЇЯm9{Ем{hto@lЗїЂ#Ѕ•ш@luƒ#—ИX~ ІRљЩsŸбt4ЩRkЕ–ZXЗЉ(ешЋm'Й4šўzP лВЋA“''ЭќуYЦ›Ÿ|3ћ‰ C‡Мм=†Igђхr<aЁ_Pќ#)>јљН“nОƒG?]vе‚є …%Їоќь$TР‘xф…P{|Jи€’ЭыVЌт+'?їXчg'Э Ф~ўђчХ`ѓХ“'OxьЙёtОP,ЃpМЇšеiЖЎ§vo%ˆН“W—=3pюc“чїЃдф]:uЇїˆŽ•SAHjbRnЎЮ'PQРYR шqщuФИfQФN Gб/ўќу‘х…2цНзєђчб0оАЉЯT}ѓхВЯЖПЏЇRћ,X=.>RгЫPšvpŸа#:Шн мŠЛКˆрўŠ …ыхТЃйЅ ЫУЯ‡EЃтбИƒŸБоYју{‹з^!(г^ waЫ=к(жNи}фщK?оj0X(ДЇ7.OіƒК8[Ю~эй/ОМТЌ>тЩ­kBм8wOW!гŽLЁЧXСЗ+ПVjŒ$NKщ^щqЉ0/jrVR7–HŒvЗv>—іЬЄw–g‚шїX— uу†уl>“ЩŽq;В1F—ЫмЅBџ?t‚љуDNА“ћ0 •р yt*MSлІ*Э+eшЌИоFPЖqTBай|6›IŒžџTпЉ:*'1)§‡>šBRYШ/0vь+‘фПpŠЬmР‚—’ЊеzFeбљR‡Ayђй‚Щf;Da›D% C|me X@'|ƒn+K`Ё]Ÿџ$ДVcцИJAsа; z#с\h›НuTxp:…5KЧS+#№€:mЅХїєL :ЖaJЁY…Ћ*ЉЫцрЁАМ„)т Šй!AІъš …К “x~ЙОѕЦлˆB›рЫнюI4­Ћ™эї€зDJ‹Х†3(Л^•МсP ЃXI#а/€g zYі n0ЮHэ R Ф3s№8ју€“%ЈЩuгю5ъЂ6:-–9д ‡Y* йmА€ВЪ„ЂР”ƒho№2D@ r5‡BгЈёа“svИ~fцр#ш>ˆ­(žш@ж„ХfR(Аї э|2gbFўы)Ш#ЪN˜ес,šФТ(&Ьh?iƒ>јiСрЉГH э?TPQГ7О•‚@ьqtH‡8L58\/BУ |S­й:l+†Ьƒ;G pѓы(Ё0Ж H‡ЙTњ’їJ3.›М}Љ‹?:ю‘ЈsMУк/ж-џбМyѓ>џќѓІoP HR Џ fG& іY0э^yйОНо*хu4кфž}[oaОэпќчžѕ{ћы7шбЗНwNhzeGЋ&;:чиg2њуЈЋЛдНВПDЏ`љв+ыSъЊhu€Нcйлъu\ћZ‹жQCфП§№:m6ˆџэqkЛw0ƒР-` 3кFЭ&Pїђzыи…fЏHmЮЦdЊK*kЉт4зžпЉ#к’zмbvД^Fбњ1#ј”\ƒ‚Ÿ@АПУЖX `‚IlШB”ієO† b v5ае>бстћ0h>$ОO'ц(Nx– “љ0tќОЃ@Ћ@зЭе :{д`ЌЧjbЕ;џu4ёЖ(NSJk И–4‚TŽјTЌ† Y1СІqx /ƒИшŽv€• C=ЎЕCЎЫNѕ•‚+^V80D ŒyТ„„8^ёGЏяPЄ2cмCИї:?ПhДc5;@}=VC M(hжzјb IDATурžqі|‘@HмВ;и†ЯI(йbtЖHр^ёЫž|0ЕеbžŽФП00ѓ[љ{ яёіЊХ}FѕО8 -јСў“ЪОbь’#vЌo(Ф1maк9cчgxхрМAb ЎюС^CC†К˜}С:ž^5–Н­^хќЏЎ=uх;~к7ЄШжЧ ŽeF{ўФєЫћ№[Y67KЗQ]1z †щрПvчiнRv˜т-†гoOМ=ЅEhџT"=tЩ“Џa|7IЫŽлъlћ›ёзћu‡6Д А.›M<:ПќsхцuЕ|ўнгЮ0,и—?nЯЦнљќxeХ[IwКљЕ8:rЖgшРB:Ў5Ў*ŸR”ЃЃœ‹+ЎVЃg@–KФ$—GЪГЇwќљOŒРУ‹иŸКS\ЋпФ|hŠJЦј{WебЕя]w—ШЦн’рюZМДPwwљњз]П–ZZ @qЇИkтюОYїнћŸЛ›„!йфЃТЮи+3sgЮ•3sцœїХЗ!Ћkњіnkщ/'ХСnvБЋ_ŽўвЕŽ~ LЁ?ЄП’i\ПZНєЩ>Т?<+hџЩКЌХŽ#5‡Ш:*wmќЃшЌвjЈ'lпBlhАNœbЋЌ ьмўРxXЅP‚FЧXтЂ-^>эю[Ц‚їЯЅoњ(нЃІHˆыlЌhn(mМЉ`К8@Ў0EoјЮŸtЧvч#]”ьO‡pћjЛІ?ѕыКОЬAzрюŸwшCЗ‘gт$пќVЎ}ЈСUф–H І”, ˜Dni1!,ˆ=}ЌЧмЩвћІHН|D‡ЮАзn оŠїзЈP3UС"ьЭsB-Wи$ЛШiTЉžТmn‰|zU M8R— УЋТOtбц^]хЯмпСF @ŒVOfЅљШ/ЧwџМЏ[ тЯ „DуuкР­gЭЦн6ЎMр[lдъ!ОђкУЗeк€№‡7Ь5|Л•2—HI“ІГЁЦ5Ы•8’|ŸИћЧ‡ Iђ‡u…}ЊРUшH€N#К‰h| 8l2›EфёMю>КРРђd–ЩyЙџЛсЪІЊЎЊЎQ№hЫn’MЏR6UUž/ki……ф“MU[]ž_Zš‡џeUеjл]$;Д…ЅlыўНgjє=\ыЦЪ{фZ-ЅkЈ-ƒТ-cЮœЩЁDu“ŠШ |ђZ >[Ж|тЋ)ёЬ˜;B[_ЇІ№%`:…ыšђљcнё ŠББž›2vў ѓ“C=і^/ћэ‰и‡_˜B#їeqК“(ўЇЭ;DБйПкажU_№чбЙ‰Ѕо ђЇЩОј#lПИЩЌ­NЈС>CЦЏ`Cx$оRюуj­ІЋ v`ЦУŸ|МM)аa~ъa“š7žЊkj1Px">xрcкђЪу_mЈ|+іVlЈIЋбъ,&›‰П жКЃ'З­мpЎZЅSъ |їдХѓЇO$@“\щжHhŒ.х~єNЫЎ-šфTК›G_^kю8п_З—}Д<ї—џKи­[г8W-NK YaЮЉ6ЫUЯЉWZ‹H•’|БЁСp)Ы u5wКI§`ŠУПVИIЗЂ$ЄJІ’iВ…Чий@—`ўеrьк 6'ЗЈЮžЮ/ЙTRRТ4@4J{ТЭ{Д 9P@vЮЎдzю#Є *УанЬљЋ7їЩ˜?кŸУЁA„9ёfH@?e4-‰@vИПрf1лqНPРѓГћФ xИ:д ˆE№ яžƒGBфўuьШvcYјрх§МюXјј‡Чњ@|=‘`U^h›ѓє“~КЫџѓшWпБЃЂ>Jчdрw’„А`­XhшŒ=‘…bfГЊЂ@”–1Цд"р1 ицVхљ/зd›ћЬP/Œh#pAЈ€сУB˜ЪйсRсrpQ їRч PАpc0iqдGРиз‚X{ш=И иnVГ6;w4_х5jш`дa‘›=У‡ xs˜/Љnы—Пь§uŸФгіXoчЦ]ЫЯuє: ‡QЅ;ЄƒфKo Џ;ыфю’{Oдц–(ЗЌš6влЩRЎlЗJuЭцљј˜‡л`ХРJ&2јtw™BFєrE„Ÿ.йЮЭэмх0]}MU+`—ЋыЋZ5:‚{X€ПП‚ЛН'ŒKф‹9d›AQtЊТ*–јIX4ЂОЅЎ№ВRю-ugЈюO}ј Vќс™;ьёmз46Ug5 ўўR! зAВЈ„!SF‡КуCjSWчўvѓ†Z€Ѕ. 9Сп—Š‡М˜ŒMe…yПi!ћХEњћp ШАз+ЏdW4˜-fЊw\„Џ7›LФфљйУTWY…‰BЪ фt1S5DПФP’№хб*ЪГ2+š@сб|#}НX†ътŸџЙqЂ4ЮVх1p@€'}§g#?ОgВ)3W~џAf…жjќoCMёщfvJДтnƒЭёмk:и’uЙюЦ15Зк0šпРШзоџ|КC *Н№DAUn Žп)С(8)иYХ†ЯЪЂUE~]лbP| -9`&X Јт,E@IхŒХ(ВwCЎёЂ^Ї7ѕНЯ•A:rЬ”ЈnˆйЂ)?ўї–oЗ]n№ˆjИЇІ @oY0V^|Ё2+Л…)іŠ.хQба\Ÿў|Y‘-ёˆ#хŒjE}iЙŽЪGъKыuМШ?}Y…/&6UdхЪйBЯШ›”хY2wкќwГГ‘<,Ф?.Ьод`іB юУ†Э/ЫЊЏk5#оИГГ+н: ЬœЯЙ|о˜Ÿc:yT7(Н{ОЎЏЪ ‘ž[іЪ——ПџЃhX’›‹Њ­k1§cGa&DЁрK_T2нсŠI# d˜њР’t>YjNўНrg)mk.kl.RHSRц=;+.œŸГfљ>Fњќ…C}IMЇ–­Э&{Nzjzb(3gЫжѕП›ЦМ5C |n@ёЧє0ŸƒQnЇЄШ;НіeСќ  РдЭŠ†Кz.FмX˜Љ,М|Сb$Ÿ=АюT=@А{z €%їєRxЙМ5ЗкoЪ3/ќgЈ”‹•lпћлж *КЁоф1tєƒ/Lє• Y+Пн$”0›*ѓFЩZ~ўvЗ1Ь‹gШЫ*—чUЭ~ѕеїRЙTsбцПlлЉаѓєЕzЏ1yi"–wўfЁŸ<НЛJFїѓ•№Й=в<шš‹[ BopCƒ›.ьџўd`Tи0*б|і“іЇМќF3(Ц‹п}Ж ‹їхЪ /зЋKUўїM{њей2оэP:ЗуюрM7ЩRќ„uГFЇю‹"|)?nLЬM‹uu‚fAžПФd}z5ыЪу+*wHp№ ^М)8џЙяЇ •ђШЅƒ9Œ‹р €Ў*ИцL%ыъšъхL<šHЃг--%WЎ˜MЄ“gЩ‰11щ|г5—эйКќАВ4Г гввŸ|ѕЁЧ‚M5U'WЎл|6Ыbр"fFn•~сƒЩ–šТŸ|~ ц J?Š'5_њфЫsє(&/ЭщЎьŒ Zys]K]uзс“ˆ‘юэ/с<‡§93kjšДr"+‚oЖЛІљЎџU,aжіŠ”ызЈЃуiА뇇'Л%E ЯdЕ|ЛЖрЭGЃњPƒЋHŸ%@$atО6Ж9@т!‘ШІmИjС‘гz™lFUсх<ЩЄy-Ёў§еkьŽŠєђJ2)›­F`•ЇˆCЧ=QњЦЯлVб‰ф}ЋВќч-Œ‰ŒЏQhэ—fxGЭBєа@K4QнхœЃлА2>[gФ‰тгF{Ќ8XцёЦлlњцъгПџЕ­)фОчc88iТJ~œЭgтЋmЈQ^н qшmдЌЊЪЪЁpžxшЃjvЎxёсOџ9ђЩ№EўЧS_овЂQ0š{Š‚’№@{№№єP nj?рдЏ™ˆlї3ЊŽœl,Ьлa 1а<­D.ж˜i=rъ№К ќЕkГSй3С},мБwуO7ўМfзоR„JїM٘шЯdў“?П9,AЖNƒA[] ” žљоm:БўLГA[yљдк•И“^њПU/MžР?Оj]^“еf6+ЊЋЫъmўsyъ™"ВЙЕЉ"яŠ\2Д‡В*žџ€ШРAicо{zбsг‚Нp\GxKlMсУЛўЎa†Ч'ЦЙЛ RПГЮчLЭ`ВZmƒmчK]—ѓХХс`,кvИ&ЛPqн)зю?*oo4:Фhђ№@иTS€‡^$МfD пœЮŸю+эьб3Ÿ[2&9*0vкиxwIM‰B­ХУ98Xlв”q‹HЊк§ззЯўа>dьиX ИНЏM.Щѕœ.хгё–ЎжdЈkm­ЉmU˜a!ŒЬ“И…b‘дУMФІEд \qу̾ꪘ€€ш2ЅEkАшkЪЮYЭ2Ќ>sћсЫљJ˜дjLАvАuМЉїПћРаˆPOж0о„…e‰ФzоfЈ.9…Y§Бкѓ›ўЮ,жŠЈJe$ёммУ*Vтц (–@/д)+ŠvЏљsэњТє'_<Ъз(+ˆH3<1}bЕCŸYѕўуŸ<8І™IKчФ"ШљЌІkЅ№Oэн)36шмб№ŒЈжUEfш9А‰ƒ2`@ szе{љ4ЮtЂ`{ЭiфД7‘~”HїР)'ДХкз›„КгO2‰Dії‰–!U,$ˆЁHLЌˆ$XtБ4(АШ{№§=П X__"ѕѓДж*t*Cks]^kНсЗџГ Q+•6В›N‹уXQФоƒg=ємDРгjЌГя.юЙЌЅВe,N­…'‹8I#ХиPБ{ЭЦНЧ‚FNš<#%а{'Ћ^ і^ЮМ` ї­šd+-ƒкцТЩў+7—|М"gѕ‡ƒHаїВHo[п““€@­Nƒ‰…`†д гQгjаС'uƒo1fZL Šj*|xzhŠИƒ{" РmFХЉ€ёRяžЭlЄ<ш<ЖЎQхРЂ0pHоіšЏЦхи/…PРПё+ƒ2p;rё’1aюрˆkВCХТЂ fдw= ЙкЇ"zФ;ZD#У2Сbаah; w‚щ(RSDW6PˆЄ1#|Иј„ EМ%l œFК,ЫŸ‚НleV>­™ 8ЯQSf„{2 ѓŒ:ƒ<МqЦњВm?Ќи|С2чН—fgјй€нžl6“ОН§p CpA A‡™нՍ噈fі7PG Зќџ;HБС ІPIQУ"K›є=_Ъ Kыё1Л^" _Œ<МlЖoT‹<цФd 42C2XM­ъ|У…š˜Г6Чтœ)AЉžiIЃ'јCѓрi$I‘BАŒУ\#pИ`„€3А€%Ќр Ф gLŒ”€G…ыю,ЃZŠ№sl0EуFD<ТвЩВ~R9f3š1xАиЋЊfїяw‘ЇЬПoк˜X›dќШžоЪыХхкwNюЄёSXл6iVџЌ|чc`ЇьKZ<еїБк‚rѕЦН•ГЧњєЅ W™оK@ЋХЊЫЌеU˜Фfѓ‘м\[e%ццNZ$/зV]$НHh8пЉ@}+ ЪЋ ы%TЎ"ПЮB”ЩјL: >ч№:уў{jУЧЄС§BЮю9ВпGТ-‚uwФІ‘k” ­f“Q-W6з+D"0э[ъъZboЧЂomЊЋ­fXaЙQщB1…ЪІ4gUджFАhBдZ №!phЛ|žќ`.“–2сСЅЉ>ЊйЌЕYˆJЋБ#3ЎuЎ)‹гu І ŒЫЅM}dЩw6ЩdдXј jЂr(Ъъ‚dю<*Q“НќзяО§{ўš_*Ћ*"ЧУ› 3HC]EЅ’с*Ў\p {г`Ќа|Б ЂдЫлв˜™йФ ш#ŽOooћЅирц wAXzHжўЌЈa‘,.Єд‹.СИТDЋмEЩРDt€K#уДjрUYS‚ЛЂжЄ;sВЄМ†NЗ‘НuZ„а“›/ў˜Z”5ѕ€DЬК t•рЉi+џуrэo `ФC-fr˜•ЁЕАaГQ7ПPнйІ"fмќСb’UkQЗСђ‚q‡,nOЮ•…мD:Q__yКВ5žЯ! 7ю;єѕNЪˆQaСBemE Ъ |мLяJџ„ЦOe>ЁЏ­Жьнб-wњЭЏMЃ_И?ьљO/ўw}бˆ7!ЯхшssaнК3WВl+V ЙE” ѓƒ‹Ќd*кy—BA—џ‚ц’ƒ§Ь.ЖІщс“k`M.ZCЌ‹ц7gS{…OШrЉDƒЬ№дЌЌ9№ыŸЬИХo/Œ‘ДЌxѓыЃwњŠ'xгPѕ•]GГ/г[Ўќ}ФPV“>'=аOЈ*<Еы(cфь”@™Хаeeк ЭТ'76D7cAЌGrŒхНSЛжк,‹ІDљбI4D8 ~*Эc d”*‹Z8mјЯ›7ЎЕ–љЩ˜&Е"hЦ}ЩЁьЮ™с лyЪr , ЁИХ.5тПыWЏЖњJЉzekиМћ“™^iёІџкђЋqфќщ‘ю-Ч—ŸЂгщgї§q&ц–ња рR"ЯмГўdшгoЄqhРЋСІ/§3DЄ!5ŽэrзЪ|i%ћ6Г&ޘ8Шэжниюjъс.vWєŸ9‡баС ŸHŸоi5Ёгш_Нѕ…IcоіоЮ†цz&“ Ё@пD"3p’aJЅкjД|Кр ˆ§:№ѕ!’C-нМ#Р[m3™.ѓб3ы!(ІWtaќМї?Š ›жђкВ7цžџЩ;рКйЧV№дрзЂR!Д’ТєLJ]№BЭok?zrь*рiјњЬzџeџN™сВ`ŸpВьЃ_О.Œ–x]кѓУћгœ RkЋZєЭ|zё2к&Œ™њШЬY3ƒюИ;zsёо]gШdtсюgџ'пЖQЎи}Iщ‰’Дxёё‹M_џšџŸ'{че—ыЙЪ HAЎЕМŽСѕV5+‹‹4€Kt§n-ƒч'ЌnVЉв‡є 2`‚`'rЈІšœr #hжуР;шF#`žЩƒh~рAaSiЌ‚„йsF‡qH$сœ'вџR]и€@йX<тŒ<ѕ‘)5—)ѕаNFјМIЈСdа Žј`XБ' ›Эb2ьж5’џЈ‰CХŽх6Ћс‰bkšѓ.Щ^ƒŸkБ8сѕ р[s7ўў/5НѓЮ;яОћю#o?ќи;ў/ѕ\WжbАiфо*6Ј„ ФZVknf.‰ …Р\Р)ё‚'ˆˆ oil}sсл:хуПоПювvajelЮЩ*kАрЈ60!Јџ„DQо’y6Wo"‡ M4Mх5I€З„ ІцжЊњz%= жN@ЌZEEю•ђ  D!q=DБ,›К#34ЫЌQuьv_6H&“УcУ‚#‚њu/]ћG$>ŒЮe+(tA…:Иo  />eўГИQо1Xя[eїP)pwз+ 7ћ3jL7S{0№д#к1ЪьМ _\`i‡Г0SЛ™VыЌыш\žDТ†;xЩНЏ]хЩМЄ"њmУ‡ьмЬžЇ,sїЇэЮГŸоі …7!@"эJїž )ФПрЬЅФzwNБ2"А/˜§ƒbХУ’ЄŸiјruў‡ЯBшЊ+ѕ ЋЩ*ЏTЪkT8†/>‹вІЋк|Ш4’{˜<у{ЈШ~КЭoпЦ§нЛIрОo… 4pBУПа у№ьЎ7П‰uœ‚…›KPWŸŒŽжИ6К—8э_љїЖe;ЛЯжЇГіЧ^œыqшSЃяСB,ІЖО`,H|јѓ{`a_d№ьТP•xрt§™ЌцО”ПЧЪШы•йKщ^fВЦМH-$b3m@сЁfвUьтЫ•NHГшѕЊFEK}ЋМNЁlб™Л#6УTU5…™Ѕu­Ај€™ЕzmЋw%sЅ;[їюŒэњћC>чlB6ІWКю)opх„ся‚Уf#L№0Т}ЇКHpi юDА ,k  ˆРгЫ м‘\щЮ•@]юяО‘ Ъ‘ѕЛ+цŽїэCCнDєЅгО§Н№г•y|–JО–иЊія"zASЏ–‘M[ПVЃі№ЌџщpLчK$0< ž4nrqNБB€ъЬгЧršLd*fElЏ˜шШX?цяlrlЏЧкx№ФЖKЪ gNrВЮg–ътЧeИё]1ˆэК#]Š­эЖ4ШОМа™5G6‰3K:_пƒb`ђcПmЫ–Ѓ`*”ЩŠ3mTЪ VeUщйЭЧ 'L$Tfцnzjyй+Џ=УїŽ|`\j“€ЭjєчфцЕ&ўИО0ŽЅТОDЖFм~ЄІМF „mL p З €1H"š Цšђ:ЅЮГ^Н5 IDATФЄЫ/Џѓіѓ5f8˜Ы$мZh'тьІћ)LY˜}іа9НWЄ/Z_’]М{_СЄGgODН„ЖOŒDщ˜баЌRДšь|з†ššŠ|uш№6у%DzqвЎёќvМЋЋ†JћY8ЎtЛ%рRlmЗкl­ІFПщјт›С 3-<•vЫўtТSLDF“ў’^г—›QоPphя)юрёбИFв8 aWЩм"/=tЂY6b"L№шЊЗFъ˜цu•йuьЮ‘€€жьX'ћє—мЯ^ˆяCУH$ТK„?іо9Р›цс.vMг{Ђšщ•§"Ц–ˆY>S—М$2М|ЅМ)fГœ§Е TЁ8dєШ‘AhоЎѕЌЪ/НPЉH2h *ЦLb2йn\6џ<Ђl„Х!РXTФq >f‡}Ѓ\!oP›№205є:JcёЉp[!ƒYЅTыЌŠFа5WКНp)ЖЋђ†…†ЪДшЇG™Эtы ƒѕИ•­нE#С)MЅ[н'ШІWkЬй}‚H}.?љОЙ‹ЧЫь•аOl#ХС›ƒC™A0&ATќ‚U_`4œФFŒ`Ў$Ж)6ртЕš @Xa€#њЊФR” МY8W/Pй†)psXMГЩ:”@!УB:`Ий,f;хpсZБjИЊZ1ЈЩ №6М4>ю$тя#С У`м Бщ62š‡BƒaЬЅx 4Шu VЃбŠЂ ЌЇУU "Œ„wХ~кj/#UќOэDXнЫъЎ= YАBvф\у‘ѓ ‰в>єc@Єpд ї}'ы>[•їљ‹}бŽ}Ишн[„iЈ /^ЎЧ\їџЙ Ађ $ЖpЮ\gћ…" SъсщЪЇдDх5`›ЁОЖќШ‰ƒ‡ГjфZšи=zШ№ЁУ"нЅ8c>эТЋЖЊы*KŠuќ@?Ј-.:Еы№СS%Z„…Ьyw!{яй&й˜йщў2бfЪпїз‰FяQSјz0ЏОwЮ6б•я’€KБ]#>Б§њЌШїХЧМ >оАyš…DД!B22-™ј€:…hlбчbYкВRKЙщ™LТ7€”ОдV ЂЉЋо§эВoWž$иш’€дОx`TŠXY–whх6ЭШХ ‡Йuj `kЋЯњ§ѓпwŸЊф…E[:ЪјPљб­Я(C'NžяœЅєаі§gZ‚FŽ‚žћsѕo+і^)х%N™М№ХЉQAŒŠƒ;Ÿ­а#–ВcЙтŒ)‹_œ$nsУЬ­uчж§Вvхўœ*яид„ўрєфQюђoŽjмyЊЌ}л[f}ётpъЩЌ^wКБY-NsџГs'zїЧхО9У8qъ@/ НљфцЏїЇп?46˜™љУ7Gю"SщюПЮV•гGОјр§KвeрушŸЏЖX@{tv0ш$X')ЄњDягГ CŽ_lм({HЇ{К…'jШє|/ZзAјћf1шŠ s.ф\,.+SрV{тšєйоЫўzd шфяЏ_TŽ€N][œ[*wФиДW€kN]6ђ‹ѕ№oЌxlœрФыЫV}žM№ф—ŠNяШl1ƒёДjпЮ й&Б;щЬWП.ћЉоїЉOОџѓVуХ?я­е`ЦжšЬ?џXsАA0kёŒљƒX_]›ъьЗП-ЉH2ьЕіН”сmЪўэxCГlЎКкМCпўАЂдsЪЛˆЁэћіOŸ)'ПђоЪC_Nрх~=iйбЃЕ0SWцхдДЈэhЮ&EeifƒN…GЉыZђ}џуOмщџїЦЫЯ†\ўя›w^hб^лЕі.іп™ЃНУќ9 -†ŸўtЦsЁ‹N‹јД‡gс!•`в4vаE‘{іšщ}.ъ•трЙŸщП:jцОЩaSYDхtG-E~Ссе+ўћщЗOд{Lœ’ТЩЭ/RyydтЈЉcІ,э-Sцц]ЈSt`/рЕƒ…„hњФR_М/Ћ€9|иє&š6bьм?O~Р  1ЋёдбЂІ}хСЃ9MвШXпЉ№ЇлюЪш”:>uNхюї™šиSš?њъ‹F{iИEиJxьй›‘(”Ч'R№MEa2Мщ„щМv™›,ŠUѕ‰O?Юњрг<#'=јсчЉ,wЯјI•ZзкJ ’4FsYГсррoиuЋ+6­КЂДрrЄчѓ?ЭŠ  DJgUќ˜гpF/я}ђDХхМ’$П†Ы EФрє_ZѓъЦ“;+8ДQšKЌU44+M#†…e,КџбЅc§:пisSэ…†ZЦТгŸ.%‡МFЌ1oZaќеbФ‘‹>}mіР@žЉшшnЕ&э‹)#ІFJ˜DйKe}–]^šЈn Hьл—`aЊЧIxёi}§ьдx_6:вЃє`iжЅІ–QFДк?„7НЖ4bбkЇжэЊ7и#июgЏгЌ1олUЩъ­ЅЭtсмT€,]e\ю‡*qbЖhЩІ?€чF!ЛyzФFE,YxџM‹]{№~0‰@:`рр0›ях"ЊŽXI\7O_XЖЅ)ГLЋ5š№'Лs‚wўЌ&“Ъf ѓŠY"#ТД ­су†yќИюrўaѕъГм„Б!!nє›ЌЌwЎгЕ}Ы%pн]Лхѕпe0‚žФ{f$Е~'Д ˆ6f+aР@JCЋђТ•€Е4Qd~‚фaЖMПw?eƒ—‡ц<ѓ™Я^ъЏTeС M%ЙПXѕЧ–R.“ЫdаP.ŽЂкu" "Brp ЌoQЕPІћа$пќ5ygŽ\”—хc\nТд Ё>Џ‡sё@" Daъ‚ЁжнЄГzkйИСž276ИR@1 ОpKДЏёњ‡/yі7.žФ. tu2ђƒТcђп?єЛѕ7еЂЊЧx"пp?№uМІэ!‰eЩay[ўўЦg[‹NgfхI9ДkЇ"Џ№ёЁ?o>ДG@J№С.Ўй`ЖХЦ‡јs2™[~сЪщ§Ь+5‡ЖЌЏЉ'8ь’D:RіѓžНt†q”Ќюя —LМ™aСuvжіvєЃ_рP~ё№—>Пєня…CJE}"}r^№сs '/7:л0t`_|,ћ‘Doш @+=M№"шY(‰*xИP‘Д&ŠЉpк‹.чWзUE„E'вєюZ›З#œ'БBFdL!“ЯŸ+’зЪ^№рQRГHDaXьšЮн т Žm>‹„R˜ їOЧ$ЌѓЙђжІVСƒ NеP‘ыGЇўх›ž!“2œјF\з6зю­‘€KБЕЩQТ—юњj—ЂEёХk_™Щf№dW™е6 ќщMеj]ІSƒЩ‚MЅъ‹sІруКН(‰Ю”јаyW—ŽI,AxкАЁGВ7Нї4P6фНЙYЫŽoџќјЃoњI§\Ш‰—jлF)юSZn]ѓжwŸ/йB№ˆїє#ГgDБСvˆАƒЧЅЄUзшНТ"„vеE~ќОGƒ kПлње“лрuOš7sN ?](ё№Ђѓ˜7ЌЋЃЬИGцђ‚l<оDKœјф їэ—ё0;хxљA nK„З]4сЧ—‰}ОсЋЯЗЉQJ№АЧ–ЯM‰yєїEПѕыЮO—Ёg?эsЁDЦ†Ѕ <ЁЧqŠvn:ПA Р3о{eDš8­tЉ_ЛрнwT‘ƒDєЫеyя?нјG—њи}С@gѓљЊМ”nн}RјЧZЬ2Dќ' K І YE1amB&I'ївYtю7 ми Ђ4>yH4FДŽ„ЂTО8jьш€ДСFЃHЁ18t wh”$$БЉ№zлАDхЈnžюЛ/LЅ*ЏaђшА €i›NœЏ „$%DzAH@GѕЎл,—bk8Œн4ˆ†,$Пѓг›0ђƒ1ЎИT-Шђ<Ъж—SЙ<ќѓlахЪКfM5&ъv‰Ÿ NМяЃAФiь%PФщЯќ>ќФ @h{т~0ŠBAјЧm9…С‰sкЗaЫ=qєЛЦ[#ФЖС\Јэ#RŒ:шё/†ТXИхcT+Тља#о‚Пb&Ф„NX: Рчх:ЭbSV(Эdй№чaZ4ЙлVЉ,f>•@јм‡ƒpv‡sž cИOњЯ7“ўcВ @H‚у@;Вт†ЇЖ1 <Ц(СŠ— Ре4‰K#*4юйЅƒмaД œ‡РbwМЭЯѕПt9ˆЖ>Ÿs|пЩњ‰Cš“cD}hХє‘^рE’_ІZОЉј‰Й!}ЈЁПсŠй!щО…gЫёWm0”в>ИФVƒœ)dD8г}Pi$x6э‹љСRBІ1И4:,лыХ— ‘№Ь]lC6 ƒ%`0љ“?‹ЎUA ЩXъяwуТvЧЅ\џИ\ŠэУгЉыЬШa#ЯЎ 7XwЌВT\!аšf•ы•Ыік]ŠОqMбыw€ќЩи‰>Эq8Ÿ@9СЬkЃьƒW&9T ŠOЁs)‚“B~;KяUх•к‹8 Т[ њЯюVuЏЈе›8к[jvьYЕіИ<"ШSWYQXя5~vА/lЂyэ5удˆИН\љ;q0Т›ƒљPgoF;9#JБx˜Ќ$-ўL(qЕХэ­ьпПђаЬРo~+јhEЮњЯвЈН‡œЧ“W–„пџњщЕ;Ъ' ёєѕш9\В‹ДЃw€х/єф$Œ я8rн ШФі'џК“зяv™­§`›s”i?ˆяuоюД{5?J]4ƒхщnїљrTрњџ_€KБu/tщudС;д+‡аъ|›ФЯš4! !Ї# šКї‹МiЭ^ЋЏФMsп№:u“г~Ъ™:)ўNlhByQЃк’2!(8,Ь“IНщEЇwОјЂ„ПЛє5Œ#€/ЫНІдк$3gœЯЎЃ5Х•š›J›мY^NnGђІ—§uАњ“Й?М9аЩRїD6JЅп`Wядѓ§Љ#2~‘<;x^ћlВSѓ\›ЗM§WБсAY7O0Аs:Х€љMqЃАИqј6nŽУMswsТ( žodB`$ С+ Ÿ2:Гьоc—…>b;ox/флcЅwUpмmiфož^ГНlь`?Y_І\Я ЊЖsWфЕ€[w•ўЉЦЊZ4љЧKэЖƒЎ/œ,XъњЏ:нРК‚S@Ь]wСuєVI *6Ьl+К\q3ћy@”— ‚Џz—Œ`тЛy Ј­[Uzѓ’џЪˆЋЇў›*ћо"0Ѕойїм%Ѓ‚yгFxпџ‡Ыs~z{ D\ѕЖQ\хЩy!џїг•/зфЇЦ‰СхВЗ5єПќЊ&MўБђДДŽX”:ˆ6Ы•Ж:g>БУЭ И–^`мц~ѕf9ŽСQЧ!иНбFЭwШЮЅnh˜ыРП ~јТ€OpсйŠЊc( w^4R‚}7щС?xЄIxє˜œЌ'yлu•ЭюзяP[ОeчюэВ Эj1щŒ `иР)mыСwВЫŠ\я~ <1wмП”зКэpЭфЁ=>i]txвPЯ-W])R.ћГ(IЛШq‚WШчM i=БђКб(КиЗ>,§XоI'ЄbU”•—Ъ9~~";0ˆ­ЕЄИІйТ є—‰кш‡,ЊцтЌтV„эTmfЌЯ-))j0ТZf X<рœЃtˆgbЄПЏРюAщФХ]Yn‹њЁb3-{<ОbѕGXСN+‰Q#NЛ|dш3€О‡џLFвРAoМљёу?іŒањЅZИ`‘ˆTЖTьц.РзЇЛH˜ЖКцм_ЇдƒGNN˜ЕЊЦђ›XС]фuъя`3ЩЯ- }у›Ќo+ШH№8јЋW ц /?Бше“@d:qˆg 7ЛWХћkfKkeЮЦїџ*jŸWйчP,lој!шИ чzmkЪ9ЛwепФ„IГіsЃ“eѓ…s‡/ЉƒgЛЕ+6[sЮ™=?lЪDbg<9kLŠ3ЕVUхžЬбIІкœт"ЊW”W@5ЋЬг[цХw)6ч„›rѕCХ’Ѓ2(˜Q'џbЖ–эГvшоЗgЮІвёЉC ЭгMœ”4ˆjDщI֘QеxфГЯЖЉ<ƒy˜ЂЖф“2gк”tЎтS0]Uѕйх[*%''№”х…ОZЏžјє“њ2ZяЉaЎѓwFЇzl;Ts6ЛхЋ_ѓпy<К-ѕуLх§чоJˆl[іNRjш—EH,7в bX0“0G“‰N2ЕЙш;зaЋFо˜s!/—"•љfGCЌЉY-omVjьlЂPfhЭ=uљєЁЬ|Ф˜›/RhюсaiwИRЫёŠSYŒ!‰I‘|X щ.ч$лrѕOХтƒЫМШlt›У>§‰T№вGosP8 m*“ђХЬmuБ6tTЦ0vЩб}{7­П\ФLлГXJB Vр.У‡бf#тqo6Т‹ѓ'ˆЅ2y^ЁAЊvФ?0СЃV" WС ёhdQУ(mє4?уА–‡>л^нЊГ mŠ‚ —s‹Z›X–*Ѓ;,ѓVG06JŠ‚FІZvH Žjn*И\FMЁ <bSљЭЙeї№ˆ@.v­UV”((>1‘ТоМžЮvТ•яп’€—ѓЉў?n(ўpyюŸІтhЛНL€'§дќwОЯўfmAЦ ьіВ‚ў–^@вgRШ§oQ˜•хr­Ž^s^ИЅЪ шKi­9~ш/Ÿ щШі lЛИlњв“9ХuФиГмЋNэоU}В<2(‚ŽЃЭсЫА˜ЃP№НТ‰Јњ›€ћIœюВ“-КaЇpц5ЕЂхЧ7њхГзL&Юdа{ЙшЋФ6`š6h›ъ+ŽЃTšMSБuЮыя>КПЊYЇЈШ^ѓд_Пw^}Эnюа]~ОіdФЫЏdў6чѕ_Y›W!зШ[ъ*[›ыOЏљљ›wЖеснњЊѓЧ–Нќп eњЛLФЎц:!…“§}<˜ЕZрЃq"{YЦЇ{>В\iњa]QЇяБCРЯтя‹сЭ‰х-HŽŽ•Bиd*й]н Ж @хaЪBгNХЏиzјјпEzР oџšхеYrѕNxzt|bА„мxхRvu+Рьt$зјГCwшFПБ™IЬ]щщ ž@ќм—ыљ<кШёЩ,у€`ѓ;— ЏеЊЙќнђO.) ЯišЅГпl+Й№л™тAў№Шdm=пєхЏ6 { ‡Џ&@ѕЗZє€#bгЋЫЎœо]ЌH}э•ХѓтИtЬЈ70MУРˆ?“йібђмОu\"яч–ЏWфРЊRп*щЅЕиoйжuЙШяЙШ9иСRЕсќlv#Ёѓ}„Ё'†Q|RRЦЯ #дžоГуReЋмFЮĘyОЁ>­RGрј†yб›+ѓЮЕюiЩ;/л;!gП§˜lцРŠ=:–З)@щша4|ЁјЕПА{gŠ$щSЦOŸ@Іа™TВХЄhР @‘ЁгX11 ˜,8hЂ=ц†ћ яхэ>"˜Э„ПI8H$Cћј №хђeПиdЅЈpщєPŠ=dє†:\њƒžžrьB#xHю9^;&ЭЃ]Z:#pя‰:kлњwѕ”с^}ЈЁA1ЩjŒopДјm`}7у„‡Р9xЭШВ‡ЮB№0ТrK?zdmvхъ•geУTe…йYJvдш™KFИSС?5ењXОиT|1ЛЈ*Vўgј[ oБ§Ї‡ыИNџ[шЗ363‰ЕuФЮ#щП№„взоѕПьњ`йКб†eŒй+Yƒѓ"—ЬdГ™4* oF"s<ќƒЭšUkNжЉѕšКтѓ[№yQўnt\‰u щкЗ‰4Ід3аЇJОѕƒ­WЪ›•M-•%•J3Bˆ§Єј6ю?\B2&^рŠЎдo%qlO/РЁњID оНO>тгО7ЅЦдћ њI *™ P‡[Yо‘ƒgMЭ/•№˜TD^Vkec†%…‡xКћzzњxјФ LЪˆdидu5JЧJ:‘С{ГЉ.VЇ~ћ3ілЩІПђІ‰сv”њхк/_'q†ч5"сЪ ›{+‹Л=б, Яmw!љћ`ЦїпОџиVЃ‘Н-~sŽ/‡ ‡щ˜ц@нСЇfŽmУ')эЗЊWќєгK71ˆlЯ№ŒчW,тщn!aCf„]&Ž˜:XжnџНw]ёvJ`тйіУ5рИџэя…Џ-шУЅ4rЫС*ќnmсыGіЁ†ЛЛ†ŒFВY;?IƒH<ТЦ>i‚б$l ityГТ9;-Q7h„…ы‰Џw™šћ€г_фзЋЉ2…5z^И0Ь‹ Ћyбxq#Ч2д\oЖУi„š1w>СЯƒщиuфr§GI *6›,„ EcЊ—•њнЧŽЙ™B•L-Р$ш`zясV tЁlт7ŸрuЖќ $&7zСœЗтуЋы єу IDAT6UшыЧCП 8fц'oZY dlл(E ‰]КшеŒєšzBbђЅnRС!ІЗ’4ю’ЉCcЙ=4ФuК_Hре%s_:ёзЊ бСќ>єщЅУчМpb n” @jИ{‹@„Ј5_)(ђєя‚ІЮjГfцх0МЏVїН$№B…А*Њ t"†PЙ!†тФOD%ƒCŽSŽzќ№A!РkhБчG^ЁƒН Ач:`Џю/ъ:{[%а…NžіђЈџћЯЗЗNmћф63<Х›џмOcSfМ<Ц 1Ѓ2EŽЛFт/Ре„RX` №FЌ03#тdiј™С’‚Ч„Ж`ЗЁ$‰Юї‰xЧ@D)Юсй6“І8;їЯKь/gH{1…Мкзж]'@њяџ•›K>X–ѓлЧƒ€ З]zЖљ§Vm)?”еЄy[okИ{ѓѓФьјQ!`>БtfLьдЁˆ-ѕs* є,АuJижn’щJ]]эУѓu*ькМ%а%ИІ=zS""‘(ђф]Е.v{[р™юъМ}p‡ŸfЮЖd_VkГ^tоЦ3ЕN№‘`{nT$ XєьтуdНўМЕ_бѕ{зIтЕїžЈ-ЉвќОЃ”\кџрД€нЧjb{гўЊ™ЃНћPУ]Z„СЁ…ЇуРУ7I№вAаД“яѕMъpю'ш‡Š П3("ѕts‹ўѕЇXхнЃтЧ‡ЁDœ Р•ю Їі+F<љСљe‹GrЦэоіœF%Оpи‹Ÿ_њa]с№dЉ€ыŒё­ЗЙCѓ FyНвŸvаp;Jл…FсЛЙ Ђяа{w››е/†щaftё№zБvz=Хѕgnг>J ’ЩО Єч6]дu™;@Щ1"pQ€6ўђх„>ДhШ@щ XбЩЫЭпќVа7xх>\є_/ЌѕХ-5WС$C&‘l6›љZƒ"ƒKЃ "гає€ЮŠcMЖ%мћ–кwћў‹т`“јJФ-ЈЋя­p•Ф%а@{Ќ|q‰дMз0:‡>џ?џѕGоЈН Ўм~ ЃЭЩЫMЧ/6Рё№dЗ>4рХХсГ_8№Ъг€[}ЈсЎ+ЂhR—žЊпЂ‘Ÿ.8-d ’C’эНh›БЩUЪŠœšаA=xmк–ж–КVН VЦaЙœ)tВиT@mэ­Lь0 PЪЁЩlЪђ*%ЪЛГiDIoey‹ѓwѓѕПХWКmеЫ/fB?јрЬ PŒ7$•+єŸѕг 'n<€?Џ6ЃC€‹ Gлq<СpмRˆW%‡й,V;)$')эZрNв–:,&№Ечi?чњН'% фQ‰@>_•И>dЫм‹&ћ§МБАH~§Ј/~(wрujƒЂNы7Ыѓд‰# Gм(БЌˆѓѓѓ Џ—п‘œr'њemКraџžKM(›ЁQщ-$iZj깘 )У‰Взdб+ф ™ЩЃлс­-Ѕ;ЖœЂЧM˜”шх§П&ЏkчЖJръчљЖ^іОh!ХZјJ ўZя%p"cKМ9vЈЉžZ• ‡П_‘ХL{єё 6NЙ„ ЧП§Е1eСмрж ГЈ[rїьл}JЖdо pŠ™ ВЖГЗ–JЅТ<„С’BД™O6ьЩQnНˆ$эЉ…ЎѓwЋІ№кqЄDўЛЎш…Хa}шЦЂЩўЛŽжWj6ьЉœ;оЗ5м]EрmV7­9КъDхЊˆpEsњыЭs[яч›%%%Z­жЫЫ,ŒЮ$mUiIQ)j7й’wьќЅjIшю7к—d7QЇ ИЈ€У8єлW4рЪј<ПРuЖС›aфZПуа N№ШŒ.   :$‡!‚": NА‰С‡ЊЯjGшД‘ ВФiЊрд-1„:гё{'OџTlј§УњVѕ}л‰іЧЩюЅˆ`РЖщAgЩи ЋQ_{dѓжЬ|П€&zС Ш5ћœ“NoЇпЦUџєљКŸB~TBи ј§гB?7 %#ŠšќƒчЕ˜К$”lAЈƒ OВ+Й$6єЕЅ‘ ^9љчоŠёaўНŽe?0H>ѓё…Ÿ6ф&тџЛ‹ЦЗуžjкТњ:MщюЮm­ЎVеы++xМ^[b1Ћ™СЄІŒ ЂxГT ыЊšђ[MЃќ(ЈUS[UYкPЏЃJнbƒdlbеждД(­LO7—lV6_Љ0ШќD$Uе‘?іlЃV"ххQiqс"^hH(EШЄ‚ДЪѓ UdUeVЉ44џ”P__.№06dŸЭЯmбшљ~бBЋ‘( v].dЗјљщПŠ A‰&ў№пx~ЩДъГ?іжZьжvGI жзŠэj№{xђд1ƒ“К“ЫNд›{QЯ-pхшз гH/=]„•ЖFyWОN=u"с drA№€Ѕџc<ЁвЯ[42ІЖЕ~ѕСелВЖm<”н /ž“яЬы,*EmAцСM{”ZЧЅ&Х‰Q-ЬЌš,СОƒgЅФЅФЇKѕ™Ы+ šеАаfьз6ЗIŒ`ГР ЁŠ<|ќшЂ@Яа”и@BZmдlј=ƒXr`ьиiC‡JIJ EЭ­*­оаR{ОJэ31-mє€ИСБCчЅpФwЛFН==цН>пo› !TeGWžиPyщЈЊ€6уXи}'BŸ?яп+!A=VVр№g>ˆЇж=ёKaЋОFГє5Ї–‹hЃH­l^јBХ“YJ'пЎ^5У•ЙПJ =Q2d€DgА‚‡dпњ [>юЬђэкх}Ћс.*EУh>яфїЇо_ЏЋњютGЋw9иЏЇVэМАгЩŽР€•ющ7`ђибcт$CcMЃ^‡ЁV“бjЅ‰XBLщ|>ƒG1[fp‹d> ˆE„ЋЦЗртL„etь Dt%Ўž`оa D"q€ŸŸЏ˜CЇ’)dJ№=3щ­Ј@Цх0id"‹ЦчjМ„“Эves^§жЉGа~g1i|*х ђцTРРxЄоR~`ЈЩЦ’E?ўѓЬЇ]ѓг—Ќ`В№БщZkOЎпlаэјrХYЂЂўJAУлО3{Bм`—ХмљGа•ѓ…Хс@еії™†угт%НјšПј@ияŸ_ОЉHКнDНF3щэџ•ќŽЯ?ŠЁ$™A`ИёЅУh Ћ1[­f2_)зЎоГъ‰ЉЯ8г6а1T&з=8|Ш`7|эСƒлі{q&цђЉHvE}A…в+’ЅЌ,’W*XžQL: oj•IЉб)Ћ /;пb:€AБЕ^iV)Э6OЦѕк X`EŸхЇ)'A;ЂзdШнy!гƒ-Е”лЕЏОІщ§vvсЬНј‡ђє[Хf3щЊVЭ†aМwQћCnЖDLцсОuуІ^HгЮIH а|R'=?gћыŸќšХN˜ fHckсх]чeГП{z ”b‚`6е sk–оuьЪ’”D~+и^ˆЮ•е9 H…ДGf}Б:џ“•y‰BЭrЎме\IбЂЩnNзу•<wѕDПкТu8u˜,&Ће ЪЩЈЖ5—˜ф„9_%е‡ MuВЛ8вЋє ЪђHŸ6ЄЎќЗу+wY3Т“‹ў<ЛџППTp[K š1ЯфдX)›в$–‚›убU4yЃuеzГШ“M‡‡шwžлђ_ГqЩЄИ0@)ƒ5исдл&#pX9Ь7аr Ž$БЯИЉƒЗэЫџ{M“ЅRVЩ& РћЙlЉЕи))йЂйў!q„ƒžјhЦЖчўlВ!&ФЄQхю8l;ez†;їСŒ-tcуЗ=V?;†сЃ4<ьХ•\ш^ГЦјŒHA™ 0$Ÿšз-KїХсьГ‹BO\j:tЖ0MХŠ{ЬзeР]РЌV“ ЉŠЪ„ВЧ†<ƒQz}uvѓЉ)Q3тƒВ*Џ8б/T@е{HщЮх8f‘{DNEhУгЇRIчЮЕ€c$'8mDbjF“D"$$ Љг_Ъi0гНb'јћ(„юB˜Н†ŒЄЎQЃг€#ШвFЄвљLјЈzџыЇѕм`@я^ƒљJ4№БќњЗ‚OWц­џ\H!ї7KРљѓ2/цћz‡ˆФмѓ%Iœ xbЪеeŠ Г‡@}]“{€3†\Ђ4!ih FЂт‘'dшpяd шЄЈБcRгРія>“Э бq\†‡_Ц‚вљВqяџОС8Ј2$"й=nвъ­3-ˆж€`s–­$!:эU^Ђ 8aщїi(bа#Иs$Mш5tСУ#‹cЗsеЎm—Ў“@xhhFТкVМ—“’ы2єИ{п8@3Nœе[K—Юь1џн•/хФLi(iІ‚иa‚ шBO€‚р}PYd@gІЊ(‘JЃSqŸ Ј”ФДБiŽmаstќсІ–Ж#іD‡Mчр кPЄујА|œ‡лžL gэu"фNл ьиЧqЋ•Ќk*ЌЋЊ$` %zцC#гУ§ЙЎoЛoйo?TlрЛф.]ЛѕІ i`Ш№‰№pF„ЋcBTsZСАр!qŒˆЊmЫБ ИSЗяСЃ ХѕНuVщ(юкИз$№шь`p!Щ.RЫіД‘НцZ\ xјнГЋЗ”ŽKї№”єќ№Ž8Š2Й4пЯ›6ЦАœюtrh GіЮл]qdшќ7йn<е^?бsdњЄZƒжтPЯ ’~7Зvtџп§П*62•<чљён‹ž3cЛ~ъ>ЇыЌKЗM, Иж^љђђw7MИжтУ`ЩмuЌіГ_ђњЦ‰sл:л— СnМ‹…Ы—ВЙ=‡ТŸўЙв­—@џ4юЃJЙљŸKЋнњgЩUуџГwрUTi{fюЬэ%ЗІїžJ„^Ѕ7ADPФВЛўжUзОжЕЌЎ]Q‘" HяНїаB Є’žммоцЮЬџЭ RPHТ9Я}rЇœя”w’yѓѓ•?ШbгЋ‹Юjї‚}cЫš{zj<Є €œ8;—ЖЌ$ѕ—"Р[Пј bЕПчvЈБXœ‡;Йџ<,†ћі)p№эї!xym\(&vbеџ:lQЫ– №вŒЄIЯяоАЇxЬ€`Ауonч‰ЩБЯ9ѓПŸЯ‚x‹sƒй,іЊŠЊці~НњюŠЪќ ›ЭЇOƒ‡3Wx<4#‘R™я^Aћ]O ]ПЃp9Z|ЇAˆк!БM№™НMЧРcIжO{aŸы2ЋС!tžХГуКG4ˆH‹ ŠуЌ€Ј^8О„ш3ЇNђЭЌB№Y+PAдG Ш гЏž‡„mП~‼зПпјй„Ёa+Ж^:Ÿg§iйХ'&Ч5.PПFЕ&ёв§/зПќзœ}БсЏiЕzG#а‰ RШoљщРѓ>ЉАTl8ОV*’шtX$І}žЖУюzупџmБaŒЧU|ъL‰nУIRЂЅ.‡іoњя ЯdЂpОЅ_еT|Б5DEЕЯ M‡еlFEЌлUіs–gƒяvƒunpœ^~4yЦћчЏЬн?8,АжpяBWnНћюЛЇOŸ† gW.Ё#„Р-A <<ќ‰'žИљЎк!Б(”„*З”?ё§у—Мy cэ8ЕѓпомЛkявЅK!р;яМ'7… бhЩцЗп\ЬtюŒ_XsРзщщЇџ}ЏЯљК9и{lжвЌ|—6<6 \тXЫХГџ3Чxпk/нлlЫЗцt‹ъЖUР'ј•G“}ѓюяTэIйŒщЄФљМr[!GўњЕnЭФАдддмммf‰ ЪV…@ћ4qИэЭ|Ф.3ѕюоЭTБЄlі‹ѓ^ˆ‰‰5jдАaУ| I ŠУrn[@Ÿ!“žœ2§I‘хЧї.>уИќqмMv‚p8]уsФaMр>Ÿ7Ј…{qRxsœ§LЮжЗч/:eЦЁ2C("b?ѓши>Ÿ›j/Nа8Д†; ШЮ[] L8стЛРќ]hэђ єu а)A}ї /У}0;Гeг}jJМRF8QЙy_IЫZ@R6Š@ћди„Єp|њ=Ÿn}_ЭTb…RГaDяYYYkжЌ­OяОM}Zh”„†%ІФDЈŠжўtђd•“Сфы)Ып<щъ­9"ОујёуGvVKМжтќ“а‡іыЌІ-хgї>юˆО{€ъјЎu‹6dђОјДЛ>ѕw pT\rћEc!"[qўЉ {M!ёdіОe+rb;{v|ЇH9ИРUdн№у/ЛOIuAI‰]uўбБщƒтdЭоpiъ\QНж†РSФя8\v4гnзАЂимсљ)…џ7%юƒйЇ?›w,-ЅтіљЧо\XP§;іЉБQъююуГђ.цcgЄr[)пыžФ„ФI“&;–WжjTЌЦŸ1ш[`|b†Ф„™‡2Є’ю! ‚q–ф,ŸєЮп“‡єM У}њЭWЏяЗАœГЂјфЦ ЛsxmЏн”spїіM—0’”ЩЄўRaHbxXjœRN:Ъ ЎXБуМ Д9—БјшЂйŸП<ѓз=ŽШxiщŽ?|˜aЧшЪу‹Ї}ЛjН$хЎд0iщŠЗяп“oЏб6ЊбіPЪЉgL€y|>џЌЩкGаљ  I™б§Уял>hІ"а^џ‰cLр’ž]эЂ="№эЈK.ўњѕc3VїхИ7ЁєЧ2цЃМў№оіDtзДW_я&b<—ЮўхдЅСŸН>уўЌт‚A№гœKNvˆ†Tƒєх№[|Ж куuЄ\к)%НыгисcЦ‡сЂъ4$ВpО%GˆNт$Ii|Џ/Š—oі|ГќdFЙ9Љтќбm&яШџ>sџ(К0Ћ0лH{\е9 5Кп~oыел/:eќjСЙ7ў‘вм‰AИр—Mzше} зцŽвьНКціˆъ#ZэPcѓэDсrБ|гЛз§cуOSц›JGО3bЦWгЫˆKг?ШюnjmšŒутƒGŒэP•UZг=дЫыіXЄa=FDAІ@Љ& Иc ЭTXМ>К/ЧF?L\ЪŸу„@"Є”%ŠDB!Щ{ю—зYLЂаv3ИORАL*—ШфрuЧz—euсi}ƒ%Ѕ №зЧhxУЪж№+ƒЦpkћFŠФWn/І ЛeюЋѓ‡”~ іъР… тH!ацh‡Фйiр1ˆХтwо{чљŸ‡cNР)#XЋњв–’•*,ѓь™f<'žc‘JпcЦƒJ—Міжі\Z“шЕџгЎB‹Ѓф\ЦСЅл4ъдЈ ыeЭ%žѓgsВOY3ыыŸV8|ФYŸжnЫљ5Ѓіы€ } tЎŒMy/g$„{ќM‰дћ§_/[<жKO­л˜UMиWЄабƒРCуЂТe9…іyЋrZ0iиЋƒ8[ јХќГ6GѓђЖ ;$‚ИэДCbЋЦдщt>їмsрj KЄUvюaЮ:ЎиžwўDівw—V“_ушѓѕ$<г@VїШ Џ=™dЪћrЦJwhЗЇ>›ІY§юЃн'ߘ2k?7№бџLސ“Š аиQg?zчг?[VжЃOЈ„џOШТbЅ^иёйkў{oЎ“пфФ—Ч~vф…тЩ”=R(’Ш„%5ВGпЇО}8^šГuЩa{даЮiСо”зQЙѓ€фjАUѓўiщХKЅ5ў&ЭСŒ*;ЦћUš=п-†џPAДsкЁёПЬШяГfЭЉіаW‡!ЃLQUс#?ЮXњв1#Х›Ь —шУЦїэHЅ?4 YG§S‡ОБ5ХN+ќ•Š {'Мн-НЌЬ‰ ЅърC€‚ЭЮ?dи /&пWNcBeNAв.†OбDЈњ>њдœЛ&1I`АT†ЇоџхћЌќиMbъ§ŸWc"}иРч^LsQ:!Ф9бФ їdџў.ч2х|ђ”* €o •;ЎД‰fэЮ"и*ћъеЎЭХўgzљ‘фЉ/эљmC8nЧE@Ц1TэvHlB‰pтУпўїЇ˜ є †aљLђрпЬxг+‡ў№щЏЕјОзG6с‘‚еЉ Ћ иVу*’вEF‚%Bрv!а‰ 8Lт7юеA€)O,u ЫВ„€ћI/ЏжЙлр!oгQчœжЌњЋ~ћPБКй‘šoпѕ+'|Jвšfъћиš(тbzП5I|бшtаБџірЈб~ˆзъ<Š;юP­ТVй{ГN}6їLя.:ЙД)aсъЁєјФи{KNœ7­к^8v`HН{ш!аŽh‡ФЦ?SioфВгDVЛ}ЉеЩЃFЦ{–х@qЄD$8дЅЦл76дѓmCVWmПtќœ bџƒ@sЧ‰LŸ{0ўѕ/O|ѕЫЙнќСЈЄЙ- њ6Р_i<Тx1ЇГоЧы3xП%РuнрsK†p“€-%)”ˆФ2БPLђЉnВ=$оі€еˆWK№e› Ne™Z0ЁaНƒв’5&+§Э"HXˆ B }"№зGmћMёЪ(Хыc/^%\§цД6№сїЇZaQq у…6пŠcэq+*в‚@tЈbк˜Hј‹yмк˜–ИЕA"S Цх[ 2/‚s$*vˆРŸГЙхї­g.еƒ‡ё ВOўq„ŒІјк IDAT!јТ9ЬŽUи;ЋЋOЏќ$&4ŠЎ\i-GО N'Ї8‚rљХ!n-Oшv#ч|Юэъњ}dBєІНХYyж_зцMйм‘D†ШЇŒŠ€Tm§xzЮ{=!@Ns[@ѕ­›%ЖnнКI}жщ,ј44еІE:8Rа,К†hНРЊ`zzњmŸX(јз#IЯ|pdжoюъ kvКкЧ&DoмSœyбzл„!aЗeЈS„Р_‡Юнє2роН{/]ЊЏЎ§uуE-#Zўўў§ћїПcyхГŒЭћKњЅўїЏд cЫў’—?ЫPШШeŸїƒ7-h‰ Z-БЕкЙЁ!к1UЎ{Ÿлmwz?~ОЫ€ю| ц–Їо? ^qcЗ o@sћBѕЗПЮxфVЮѕ…ИуаЉХOм гўxNІУе’/>œX7рјЙЊ;>4сv"Жv§xбфк5ї ЋЮ#кВ7рСБQ€Ф"a *і‚"Жіђ$б<ю<Р ёеЧ“СЊqёКМГ9–0}|T^–CВтH!а:@Фж:Ÿ B IФG('ŒuыƒйЇ HM“dъTЫчЇ'Т…я_Ј0ёЉ(PAДБЕƒ‡ˆІpG#№ЗI1ўZ1июџО)П@єыjш›І#Шжжq$‚h… bk… !а ЄbЬ@@`цЂѓ`*й ЩšЊ/LOQФњнХG25за7B  #€ˆ­ ?<4t„@5§Лљƒтew2Ÿќм­+Ш }x|4ѕп3[І =„@ЋB[Ћzh0"J›X$Зы=ЧЪ[аФДБQЁвьK6Hижq$‚hU эVѕ8а`-Gр—е9ŸЯ?VŽ‹?эV!ЭmhЫоМ—П8#ГџнAч‡b‘4?TџOC@"‘ШdВ›iлЭ ‡d­№E{№хНчѓЌ‹|rJ|ГFЖjѕЊ &„ІНЈ эk,и•Ня§f‰ЃЪ?ƒСАmлЖЄЄЄЗyГA[м1D ў\>ЗЖ‡_пП`uюˆОAрІщэЯў~6эЁ+/Ьї ъмцЌшыЌ:йtqTѓF@@^О№U v6Ш„ŒЪѕp9\eeeK–,yы­ЗЎWЇбыˆи…U@Д’cќ& §}cСГOЯ~;‡6ЇМћу VџћBkъШ7о§DO’ЭПNWз6вlЛыДŒ.ЗCfОѕэwoЯКЩ‰!󑛉#ZџwœV%<~ЮДbkKrn % &K‹™u+m791HaЯИмДЭFлЌ^›•ЖZс€ЖлX}“-#q„Р@лёAwm Й”њчєФзО8ўе/чС @нЬ”4 ЅM}DљпwŒЋ—йzі•шє-ExmіѓѓЃX7Ih7KS$%—1nЬŸ +Ч2†ФўWчX лъUAТw†”Ч?ћAДŠіnє[а*ˆ@4ЁН{tвYьєчѓZтж–,Jя-Іilс l]ѕiњX@WЫ]А„9y”:w†;ЦyёЌщф‰Ъƒћ+ѓ5A.љl<е|šоіU59ЗХ’wрxN^Љ›Нъж•SЏл^U\”—yёќёЌœ E•UNк‹xэ >эщЈхџŽЕ'а\э —IšќќюЕЛŠFюжAлмйM|@~ќˆ+уˆ{піЊф”zo ’HTMЫйЭВИУЁƒnФтс эZ% YSЙЛЄ”‹@УjУ 'pB(‡]Ÿ—|s№!ЯFpК(`ОŸЌэbіцўypТНAphўИЫ3ЏЇatёЕЫZ}$‡РЏз+ŠLя9ю‘‘SЈk7}ТшGлE оЏlл9B!PщŒ бпўšѕсЇ}мGH5km† ™Єˆ’ЃgќX50љЄHФW`Љ/(.ЈлиДК}н№˜+Дx€[8цb8†e ж‹Ÿ?›їщGДPТQbB$Ђ ŽЈbU‘бb§ѕ[уX/уАиœ 1‡бьЦФ2ЅLЎ.ђзЧNЮ$Ц‘ŒлfsЙ=˜DЮP"ЮэДYн˜P,“ Xвž60tx œЉ:єыЦ}‹ЧЅўQ“ТфЭчњDwZ ˆиZЭЃ@AќЉ<8&r§ЎЂœBћЯd?>1ІYmS"AП~ТsmvќфM„2ЛZ\Ў‘Х4Б)’Рƒ”BЦЫyYЎвI“8Ў 8‚рь–В{!ЃŽЄh…< „”Xг55х­зЏп8k-Юйњгђ3ДbИїдЪI#y``B ХАnЋЙмcђ:+ ŽЏиЖїˆ)~hџC“ьЧlмxСа­ї№QЩAЛытЛ’R№]7 .]<О;ЃИ вbїbrф~}длцDlmѓЙЁQ#C€$‰WK~ќ­ƒ?џqqXяР№ І‡rРIŠŒюбыиёM‡dжШY‰„rR"2ЂKd`TPc=_ЙdІNЧюaд"AiЮXЖ“Ž›Њb6c€Е9Žv”^БfуŽ‚Ш1‡QЅйОuбaaЪQ}§Яь>ЖУi­ЫйИuIюЗ‹шлwш§ЃДh›эКpЗбˆикшƒCУF4WKКџ…=dkLџрN ъІK (AHBшЄћKПџлИЦо1UД}ЃуР^Wяў’F‰MЈTu|ц_,јŒyьцœlЫ… ювbГеЦ™,ГљˆЧ*ЂнЏSЦаА шЁёІ%к!DЄ€r—л}ЩnH2lєє ‰ эЙхАдЮŽHgЎ(.sњі6mLМД‚•6яЩ5цчYhƒŸVŸи)Y…$e/)Аs,рq№ОtЈД;БЕЛGŠ&„Иˆ љєЛЃ~XzёƒN/јА,р]SЅс рн,”’нњŸЙhоЙељё;FжчBŸлјЊ&.HУС7mJаН'ы#/m7;Š ХЅюЪ SiЉбbx<~"\оБcУƒЈЙ у‘jгю}ъA?Ќ"”јщuZ­LGAёУ_|‰•Њe*nаД§b•A)ЈЧќубўї:D…J.SŽйы.~м5БіХZ…Rе4>­њn bk !pГ<<>zУžт‹6Hj$зœц№‹=ЮѓŒPЭjpPt 1Ўб№џЕ‘DR!)те#Ž TFEБ.K{YЭ2^œСРNR k$  AIх!с2mppx$U„oŒџрршэ„Sm˜ nАќ1ЉєзљљГBVhPЫ кК \‡jЭеm bkЯ !p“@№ˆГѕфџ№ћ…!Н‚ вІ4H{ИЙГЭ{w:ЏЊЬ0<З…E4cw Xxˆo‘ˆ…ЄxЮwтћЊўQK„uЎеђшЛўѕlOJЇА`™rЙЕšћ,цЛЦ_НТUp|љЊЏ>Ј|5ебw{F Љ+э47„Р@zGн№>nš§я™Mœ1%Фу“„dCќUзјjф zёiQМ"UїsƒњpK$SDЄuIюv•Е40№љ}Џі :@ bCП;чLPШШН›їёFќM)}J_}GЇб^§ЎhЪ6[Sкor>Э€ˆд_fr˜Їwœ>Гџ\“лЙnE>$3Ÿm•6zŠmўЂ šŽ€F%zrJ<дџпм36‡З‰‚Qд›ъ;д‹Љ˜ŸлTё&іRЗš#Є˜єк“ТЇюuЮ†eМx!#ЇЎјЕЧ8jЇPXѓЁ0 ]wЛ—№@Рd“Х ^uЗМР№D˜ц%Ц(Є{о<ќѕџљЙљіP „@ыF`ќр5; Oœ7ЭќѕќПf$5qА %ёќkšЅ‹ЌыVкЋEnr)ђЦ§ц—ќБсЖ д)І%JЛšР!Ќж S•—›sІ ЪЩл”0ŒGЄ ˆюь/ѓбиФРцSМqЯі,GшиуT7hыцoС&#ЈА)шлr‚Ѕœ…ч~]И=ПРеgР Ёе~шЭ|S0#јn >$Œhs€л5Gžњвоп7цъœгд—8Є9›ј€2"šњiІйэцvЎЂмл`Šm‚OSг@ЃŽ&šo”Ы–э[ЂJФѓР‡ Ћѕ(X+Ќ}iСюœ3xCz:GП]§]ЙФVœ8ДюЗнх’ P?‘—vIC•!aЁгdђˆ5Е ”QЮV˜}ёD•ЈoЏ+rЭ‘Ѕ(пф‘шUb wŸYєйœ§…T„†]>{AЖ§ўящфЯ •"Pћ;вBy$†@Д9bТSFGЬ_™ѓСьSs?шеhєсКьжCB~ѓIUI1S{-Бq.ЛчєЖгь5ЁЊpючЏŠщ]ЗЕы{YЦ…[tQx€Щ)БuЩ„уh3a9EyНЌ›ѓPJLг˜§ь9ЁЈ!ћ–:­ЛЋЪ к5}`Ђ$v#šƒФИyлКs–ˆIуFЉD^ЬЫI<И”!1Ё 0ЎРЧЇЬŒ‚еKЦy1ЃСС€уЬ[ОЯ4њ"ƒSœТx'AИBCƒќ`OPHё*Kcnš7ЫФ g-[кэСёНЂE/цМИnйЖГ\џ†шЄ:ќл’?~лб=%Dз5№Ц\]grш№jБ]:Gм <~o иœЫЕ.^—7eTDГІBНёОю‡™&АщвэšРZSдюЪЩШе№JГyЗ§‚qСЎ­’@a4ўP…aPZZiљ%ђи™ХNœqт^ ž6Zѓ0KЙЫUgлїИ\.Т[ЇЏкVъpЌLЅNюа)MƘ`#т(ОАqЫ–?6—‡ЪЊšš6ЎŒ—0ЮЂ“ЫОYr4У•0Аgџб J 0wб‘M[џи{ОPбapПQЛH„ом][ѓ‰?ѓй]л*КMІ*ЛX) бcE[W+Љ”ѕ~phzзЉˆ"1л™UK6lЮЏДщ>2Ж{з зЙ}K7эоьШѓnомљО1§њŽl<ЋˆкНWrTˆL{wЯ5kЫ.эо%@вАо[wVшИaБ5Œ КŠhпР"иПf$>їббяg юбдмЁЕ˜HЄФ“ЯЋГГАјŠЉЈДЈтЌb{•ЃЖ>)$uЁк иРк+M9а9№f•ўююђcTП“gVЦ1Ќr БрhП‘кeЅыГŠ8 ФXf –HЃ šŽbcee8ЄJЙ@›\^!ЦЩд2J%ЅŒ 0[цСyЮшhШšНsN%AjЧN .XЙuщВнх]АПї№кѕ†„€ю]tХћз/йZ^ЉѓХ…xёСѕЫіЭŠа№™;gг’IЭ‡wЇ$‹3>ž?їDО|˜š-ZњхќХћтE,D`‘R„Ф $%BКъRF9Јw€оO ™{T‘QQ”Ћ0ПœІ!вй}Њ W@V‘ у‚Ў"к=}R ƒв§nц“9MukЋ‹ (dбqзюсАЇ б&єŠч=ВyЭ‹џШЕђиєX‰Ђ‘и"uл‡уB9З\]ю\Б>/ћдš4/ЅсЙ”ѕC;hХœГs2}|ЧQSЧŸ”Ў`ч3sLЦв§{їfšШдa#ЧLщ"Љ:}ц’Эхu•—ч{ ОgЦˆи0?ЦQžkЄтњє?уžБу+Яeц›lЅ—Џлсд'є;bьН№œ# Ыb:%("Л%їš2&==\‚9Œ/ьџ6ЦEB5U[!* ?5TZ„виZBД ^˜žИџxХіCej"тЯ›NŠШа”АТѓХ Зџ HADчpШюVwmВ)нUIИХСU'ВŽфfВЧє 'С„сќыО”МИTј™1йD ] Lб”І v–28( {ŸžЩ&ё ‹T“b‰L#Vш%ЊAЏФp6аT‘ббCzuяjУГeR‚ІнŒЫQfГœ;|СёŸђэbOСЙв^щ^Œ+iNп)m`яŽ Q*Рy8}зnяJKŠѕ+Н`рч=sЬaЮЕйѓзЏ§ўєn=“Uфєт…Ÿ”(њƒЮOт1цˆSBПЌeРІ.—SMЩN甉п™uБн™ЯЭ!Р# зˆŸ˜їЩЯgЬT_B№§Ÿ ˜\#Kъ“PyЉвыёЊќ•Q]"(иЋjVС1ЅWпй2<"1<ЬыI`„˜ъ %ЉЧыЁ-VЫqюpE|&f”Г,ЫеFБМN@lC@BяДо]5Z’ a™Я ›4N0А ЩS.†‰T­­1ТЮЧnЦqgiт6І$ šxWˆgY2Ђ{‚JЬГR)WA L~' sЅFхЇрOЋUeР'Žeїщп#ZIrЃІ‹"AVB€‰‡p@e8NъќЃE"“бх‚Ф=2‚ЕWц0}€’jФЮѓ:ѓD—} bCП;‰УТжь,<“u˜іч‘§ }Є>І{LжЌЄ>‰2u“єЊкР–™Ѓ„+о$Ъєx Z% РюQ‚‰Хv1)Ђp!Wъ-=tььХBFуЁ NЇ”ЙЦ†ЅЖ­ъl=Nгсrѓ^8ŸF•5*ГИ№pБ=U+ѕН Ѓ0ŽџQ]@=$TКhЅўШйJЇеаilМ wлq10TР}“5uy&фŽ/p1ЪжE$лЗл.оS9Ќ.!Шb” +нpОdDЏШ@ЉHвhфь•OїL ъЁ<Гtyž#МGl0ЬвзњбБЕ5$ƒh7Р–иЋ%O{yьнЦЊKоМp‘T”м/бOЏ яН4ЋхЄшФљя/,>_МўЫM—ДE H№лPќР/SYYЉ‘јЯ~baYvљкЏ6)iљлЫЪ[Жl8ђ 0аІ.ѕоЇ&ьвUxrЩ;/”•N}р‰Л!^В—ц@ћƒІј­Bœ„Ÿ„Lпџ“Yсм?ПВў;ЙgFОѕЦ„б‰@ŽА VkДRї”р>HB€Њ№Љ_=#љєЋ9џмљ&„\ЈЃоysТшЮБ#FЋ~}oЪЎ яП9qLчюOA|у_+<Ѕ\U BWgБzБ§љdu:у ЭgЙИwх.PTнЪpVУxP›ПtUПgоTДЮPРh5 e[шА\…v Z@"„@{@РTИ7$ицtr‹цZка|@# Š дзгЦ€`УŒёњ2gГАsvљУ_iеюauЙВ =„V7TЄБЕКG‚„И]tяVVV.?Изеg€ЛCЇъ зЗk,MяЗŽ^U#d6aЫ—rххи=А'Б?ўРјC УТ;wd•рЗ†ўЋЏЋ§}Ѓgлўž)šB …ШхоqyЛќљ?šiЯ•нЌ6wћФ.œ’.cWž:G‡)FЙwXшНУCќ_%›;ЫЯџSfз$‹_гМќЙ"ЕЎZрМRпчЊїЇŒљJ›M?jtќMoъждDФvkpFН кCGЩBТШђRfе2[лqCЃQ‚а‰N#т8"Р Š GE`Ё’УЕЪŒѕсЃuwИjЂ зМNЗЫХ›ќп .K{sU…бXnДйнРOзVіКмЛУaх?v‹ЭхЌnГ.kВХž8[сОqЖъі ƒХYЧTQх?ф+hhќvЇг kржЕ“Н5WаRф­Сѕ‚hјƒЉоЃrнJ[>т FвСДкY |Аоhїpgђ]ЁaІN]]6‚Њb4lм ўЇПЩн6їщs ; •|]›LІ`ћІхѓ–ь?iДš=‰ую™ђФј1ZˆŸU7Oця‹6e”вœ€ФqлЊK>nL'Н2”АZ‡Ѓ3žњяЌбO~џЯєХЭdъ4мЂCжэЎг/ЦК'—.x§НuэŠ=§щзЦDъDѕ“;ќя“ŒФIолzœЪ‘ЦжЂ‡„э˜8aџЛЄ ƒЭћСвF§\-v&П’1:Рн ЛdbO”rлŽГц Vm“T˜IБР#ІšœЛцћтР"X’ЯPѓвФййљEV‡Я7v№jЎƒАQѕЉ'wўNZпыбOоxщqхлз~3sgnQuвh ЊAсЊŽэнЖSЈќC !A*5„ѕЧsзЌ_Л'ТЄTзС"Эюђъ#єЃ‚O-[њzчЧP}ЊЇpU5~ зШf/_Йj_УT +н<яеWўшљє3џ™љЗМ5s^ћhЇеYј<Њ;Ф™™Ъh№UЈnа7ЏЋ‡ФOєЄБнBАQW6‚РФ)Šc‡\чЯxvowіўZmЌф•xжsР‹6(ŒЭM‘ИHIˆЅ w-=гlƒ7cFДнцєР›žsYэv'Іђз)AP)O?IШеZыqšKl˜BЁR !V чqKBB*“tћфеюB‘HFaоXgЦО™'/”{G‡Ш0ЛЕšRI$Ц1žАЎНG?pW|€”ЗуoЦДщэЙsOTВЁQС~~аˆG€Л­UyХъ‚ѕ2$/vфЌeFЌQ 5С…Œ_buЫнЄ”ђX&VІУ­fZ(qŽђ2ЫQъ ]­ЌЅ$ЯhUD‘.д “^KйžW~˜;YеICkBƒеJЧЖ™П9G<ћјЄ…р‹џх?№иoЇžьг#ŒФЌІ7Ј“В=>њАƒЬ_Ь;ЊcЮŠ2єхЕ–W8йтЇ" IDAT!U:XЏџеrn3`П™Њˆиn=$‹hŸHeФф‡”пiZВРв9MЌPжбFкТŒљPWА NpˆKD0ДЗK‚yh…ГУ (–”4§UKl_Пyg–U,.;uђt†-uЪФi‰ Ÿ§uю.iїёу{ВйKžžWпѕОџ*-мЙvжН_ЙЛя€0™A=ёЮйХBИd ЬV^ћЮ6бєi§КFKсЕЁМ i&„еQ‹I”юкЙДИДjСђ™kчwzэѕiїFБ ЯlљeїкЅЧL…ьрџѕи#U2в”q`бЗ_эШ FйРч`JšVЩљбfЎƒСzlћійХ/Йч|ОO–Aф­XvдT\OvючŸь:ExLђЁЏ?9ur'гŽ‹ЫŒЖŸ~ћl…Бул<8РЙѓ€}ш#‰r%IDhjšдЙјдESЗIщЖOьŽѓю@­и{єЫOvwљћѓї%ˆ)ЯСооЌъс9Оnѕ{…hаЋ=њ`?љ­&š6іћкўІаэН%I)BЛnk‹ѓ!)‚ёі)> ЄѕЊхДBц+9ЊЌЦOнm)9Гuуњ sа=гž{uHжВŸWn>UiїZђ.\(4C˜.Ё>~р䘀M ~_ДыфпИж›ŸЄ—]~ŸCtKїЅ};?РwMдЫТHMшрЄР9ъдЎќЬSЛжямМ|эцѕ'ЪNeBЇqьИгfОаhѕа€/ўќЧ2ƒ->Q~aѕм’˜юї ПИЭНЖёkњзЬЕŠ@4ŽьЎѕю/Жљ?˜_x][-`ЕА­йTrџfп1)щЏ9vЮœ|д ямъгŒsцWБ6Jl %QЁ2]Вoa–™e‡=ѓPпє9…щ’’$rp‹ЋЬЯ,U ћч=={…ЉХ?kќyўю’"Ѓ3RЋŠ‹ьш8ђђф№њV Јkџј@уЎ(*T:x“ \п19В(чЬж]gypq,ˆ‹K‹Iœ№XзcKџБЪаЅS˜ПЦПKj‡h хK IHdеƒЫЅ9ѓeђЧ/7ьн˜ЙЯ36­ЫЩъV†ыž^%ЫЭќxу†5ЧXZ$&єЦqђї?йэиЏЛ.зvI з‹"Ч=іtщwП.[~ŒсЊ‰Џ|<ТŸч5œqчфћCˆPвКvK‰RU'р5Q–Ў/нЙ§фVЏ“?њХSЉaЗС]%mќе@Д{ЦŽЛjеЊ/W~1`Lџk' 4іъse`!љјS~н{‰Зmt,ћењбзЙќЪBйЕRЗёЪš•єќХ"#-‡ЁS'8UВыŸоыœ2љЦ#ЅO}§нТ§U‰гЙ;Eюхp™Ÿ\(ц'Юкh/XёK`{‹ЅЭ^BN‘еы“†Жxq9)с x˜7РАК'њQЄuбŒРŽлрЖЂ|jыр]eЕ1ЌLЅЄФ8gЁН$ іœP8Ззkс- \[Œеmw:hb"БF$œХS[™gгЋe-n›гюх!.’hФА'‡3mДXNЁQ‘B~‘ГyL&“‹УЅ"ЕRЫЈќfы№x]ЅцOYГЧK‘ŸфмЕДћ…>=%ЃhHЈЇаŠ!ž дozA‰F›ŽЊ‰@ДPЮ&MUЮљЮќЫѓњUЖќ\>lG^6мБ•šJіщOКмє‘КErЊ$"€ЛС)xп\(в)•B™NЂєїƒšе]p@Ш…ЂъХA6ЛШкы˜ъ.ŸRъЋ К̘Hˆ…qЭБ\(зТхыBJSгЎ]ю T0%д_Ё@!V*.чY­CнЪќ8o ЋЋ”ѕd1.дћb^;\.вШ М!LЭJ(пІT$’жŒ_U;6\.UњIФў2XЗдiЄюєnС1ZŠМ Ѓ.mЎ=DЫ—&#kЗ]F•лŠ‰MЅТЦ&F!pЪCŠx‹†ы ЩМ N0Мп„t"TVћЎЏyœ—пьpZџжѕЎзШёпWъд?ОRчzm^UП~ЕjёКпЈЏ†dЏšK­xSкЅ|№T .TD‚mKzeBЗюл­Уѕ„hЃ9шZ8Ч ЌVwќ Бе=Н]ЧАVA9 wАфЈ3œ”`oŽcцЭюЏwъ{ћоx­ W*!„IцбaУрiauђv/Q#bkјљ Ћ„@5'3\3?­КъпuИ[k€ШVeЫкw‘”‘њ']5žЋHыЦЇ ы  ŠFэfWM{ЅєvПЉk†вкПqŸyЫm%"Жлўа­”Ютч^б|џU•ЭZoqЉЂœБйиПШ~”01ж$џ'‡н™“‘O*з[]X Ђ} јЋ УAі§_oF.‡ехdD2ЉX|Ћ_Œ ’рЫЦыžZЃўКуGЧЭBрV?Пf UF Z:‰оњP?ѓГЊь ѕДДПЮ~$ЛштмeѓЙК‹‹зBС*CœЦттмќ{ŒБУгbЂ!dHЭ єн"БЕ6$„ИУаш/П­§užeы†ъtbќќѓr6ŒнЖОЎAˆ9Шђ1›/•U•ŽЏжtЦX0!‡S&іЩe^ѓв‚еQ O˜Цy7ИpнАQЖтФСu wTHУ"u/э’„cўБqzQiЅб-ещЕ>лE‡1П(ЏJc… m1х_ЈєШCд’jеа]јѕ[ГŽю:]Yђ 1QкП6—ш_;ЙVбzЭяHЋ B!аz€($SgЈbу…sf™=n^йhh›sкмGWc`ЉЏ~$2к`mRП„њ—>ЮТ…Y,nА`dАљjьзЮ„чш*Тx”b<œ“u 嘡+&Ўrл/:DТF2}{­&LЊJ6tHŠЂvЙ>@j\ОnyІ9zњ}їЊEЬ‹ЫJyDL šœЃ=эSц XіSн– ]˜‡ЗFшЪМЪEQюС d#„e„ShЬч%ƒ+а O!ƒ5Fˆ|LЯy0ˆЂC№‚Я~]йћяS$ˆ О Иѓ€aЁЪпцгржŒЪM#€ˆэІ!D ю$ АVh8љЭЇІтBoƒ†‘|4 Я>˜жŠW ‡Щ§фС СWЎ4zD`‘ќ‰Ђ о§z•хЛŽЯrрŒ в}т{GLёж‹Л d'vзЙн.sc :уЄ MxL|bј†"ШYrOnиОyХњђ н'‹FІїy`0\Ї^[ўс9[Žюйgя2ъЎ“Лњ‰HЬ•Зgљъ[NхЉRЧ ›<НЗTDgm\}RWиДІИЯ“uХgKeсўxСъE{/•Ъ‡=5Ё_ŸHЙhЯšБшЫV^,ГŒzсўНТЇЖ.мy`чЪ|њх]ž<|LgŸКЯˆ~о|ЭтrgЃР  "€ˆ­QˆP„B A!дяkže>ИзeЗБВњёG„b*>=Жј\‘­в^+F‰Ј€XCH|ѓв—h\x›B•кYФ2=22~Ia@uТE\@˜ЌЗЎWIIёљS'1%?ўrЌ§кў:0кЌ9ХE—ŠœKЪ§„D(Ѓ(­Bи12 .P,И…˜љшЎ]'*“:†ЈJЬ]#ћOšžГhѕ/ПэГ'&Ї9ЯlмАЇcxŸюўЅ‡6.Y]P’”ЇP‰ЪVo\ИБЈТ/ЎsЇПќ­ПОЅв=1­ГєРЋп|оп+= штВч‘o<œЂ”€7ЖЮ  юЁіѓхL $мIA†ЦЎ5DlЭЧ I юxФbтяЯЈcуэ—ђщјzЉкpАWTЩ§“ї-;P аRшхёН…вцmхЈИяu…OќД0‡2Яэу…еFуО…œгюѕђЭ‡.ebЃšє0`‰а}ђфцг3/„91uьћ& œа!$ЩЎH?Мz€H&Ш&0ЇXŸаgадКЩrw-јпюМьœЊ jїсCɘъžб#ЛЬžЂљgЯvъЈѕTYKб#юПgdїƒш зZJžlАЄ†ѕа.э1›L‡ЭЛKКУ*Tт™ЯbvУ™".ЂsRjWHaЉ3С•NьС чУєђ:д e2ˆЁЯыOР^P‘Ѓi–ІЃєїа˜pT$bејц(eзЅ”ХЄJ‰T њ*$х ВЌЫЭВLњєЩУњ&@lœЦGЋ%8иеИ`Q•З(ёѕЫћ†У јІРСйї}­Cќ Ї‡nжG бзњебB!€h~ARЂIь@ )ƒ:HЭЫ]Мy#Пnyх$ ЉCeWЎЃЃі„"Жіє4б\w  №”Щ„-^Ф••cїн‡ЫР~[ IДy](2>OMe•*DoэљW[{~Кhn;s'…2VIy=ЇŽ[’bŒWЩРѓŒРs*˜%+ЭGYюН МeЫ~—ЉЗЦpЅ%Я”NЏП|й’vюDlwШƒFгDмAШФ‚А@Б‹ы "@/d‚EbЉл#№^tтTъD єА%<ВЮe‹Аa\B ›ыr$ыeqjыoЮџ[ё|JАИnЮ_уЮ=яp4щПOŒCbŸжQБЕŽч€F@ќy˜эL~…зhc• vЩФž(хВЪЛŽRFZ‚Ы)!n š‘іЬgс:Я–>еЌ:~юЮЮЮWE:љ–р:|jуzёеРl…Хм9?lхТGўыљnтм§_§gљœсЕW‡'„B|џъІx 6Ÿмw0[‘о-%D#іxьr%EтйЌ:Ўю<Вo„”t‚Q]Б2иМ јЁј4<b8o"У—к‹pЅvДМцєВFU[ DЎ•НАdiF`Џ{њ‡QфjиsпќчЗ6cUEy†lmџ 2 \С™™<еЊщЋzvW†T+vkБнœQ/„Р­C ЗШНђЂEАˆѕ(ЂHБ)dєBм^nюзн6bh3CлэNXt$0Зеjsb*ƒNЉ€EaъыЏ'у"ЉLФвNs‰ —+•*ИNpДЋЊФAЉхRЙЄїЯџŠ#шh]Ѓ:ДћЫŒЌRcпX 6‡ЕмЉT ф,`™˜žЦ?44žwу8цu7М1чЧсEkБАШ`??оЮIрnЋЉ ФNcbmV&ƒр›Рœ­ЌРhfXLЈ ж+ C*†9Ћ*н E[ŒUЌ6L‡cЙP*bV†ЊЏШZKђŒVр+‘.T/^sйžg§0M›ъЯjB‚е~$.ўiїbЂpэˆ^ы}dy7Fт"uRїŸ§]К<еyЦ…>\B™˜Б–U8 У:†фcљfр§'TEФі'€ˆš@ Z№ОЇФМЇ"уёtM4ь†@ Bа,ч3’lк˜щМЭ+7n;g‘ŠKŽ?~д’>cкŒ'†G‡ŠŽћх6YI“њ3<ќci‡žSŸ&+мЖђЫчєysвр!с2Yѕ;ˆѓpк_\ КlпŠз7‹™1ЈGЌ HЫэєКНЯЫ~нЄ@P~pЫт*Ѓѕч%Ÿ-ехїfLŽZ%/ојѓжПЊ,dGќћпџx<еONšэŸћХЧ[ИUЪ!Џ>9czw’9јП77у цƒ›7АЯЏќЗ{ії)г#БьЅПЊ,bъЪЮўшнmGqЗY9њНޘ–ZЙхї_,6її >XTощПŸўэо8%RЋ1W№eЕZxГK~|dgТТ†ш%єž7^йбэЉWІ&K(їо7_кЄэх8њЧђsж ёШwŸўлŒОjљ­&žcQA э X #)‚фƒRAв 8ТbI…Œb9DCЉїŽntтДНтмŽЭы3œ1<ѕочs–§И|Уё c/ЩЫ/Е9Мœ0 УшgRЪЖЮ]4ч‰лОyg59Ќc—TџjRу—ћїЅ=лэa‚Л'фР"CЬИЎa*?DЫ=}bћš­–ЎкА6Ѓмшдtъ>J#I˜:њџ~џп=#cЅb!УВ-^r"рййяќѓAjгћ›s*Д+џЧўГ–˜єіК9ŸЯВху/vž1КЬY|aзь…ыЉ/Ьy!)LE[.lћт‡…Ї§Ÿ§сэЋdзћ=іљЮyŸ}гoщ+яяЩvш{ыGХ=|Я3+>П{0ЌF^ъZ{NIHЪєž!r>œnЭ?wЁ‚і-EтŽЪsлg§ВF8рНп?yѕйЈѕoОёЧЁ’Fўг+мj"§г'€D W! QуAў^PР_ ЖгДrЗLЪ›Š№+zЭ/Ќ‡t0uъу ЦАИcГ6dœ(Џщ†5D0!E "jФДф^јр‹oпјЮŒѕxјЩ=‚ е%ыДœпГхћЗ–Й;njЯpŸЅ‰&ЉЧИDŒ€А›aтѓЙ'\Ƙ†1Tu–п3„Љ"6VєиЋПМиТ“aIпёХОнJв|дoJлMС‡„VˆР]CАŽЉVЗ аr6ЇUuЈу`3 оНM~‚ЮКFэi#SР1НBтЏ–p@b ЌnжaG^сђI“ЂИ>=Ф?ž<—mЛ{HBhˆ’­ё<ъЕeЌZњйWлЃЧоџщд!b`шїхbQ8fXј}pxьБЌ–ВИ 4 ’аAe_ћœ ‹KWЋ!e&іЅРСrхдšеEл!q2ЖgT  КH\T  RјВёpvŸЌ_ВЧџXžПl@pYчAбA0`YЗ_˜ЬЗкї &Њ й7~AтЋС.%ЈI Ют,QэпИЩmDl ЌЈQ„Bр6"ЌA2^“‰Ћ"=kа`%Ѕь‘cœZCр‰ГхќЉ X7.МйH•е\jЁНмfЋt3ZX,фЭ4Њ ,6КЫЯќўёr8*ЅГlћ’Э“BGє‘lёц5_МЗ$ъЁggLы­W`n7 щХСšФыƒN$ѓЦ‡8Ц0^ј“‹hо”’хCKтVyоьІkv‹€&н`–Ш“J5зёGЁЧcЇ?џфДю2аž<.1F’.ОŽVО _Ў/›єЗзžžœЂ му–@b є[qжфaЕ š‡e€@ А„уjbїZ-6†TЈDѕ< ‰Y.›IСBвR\TЩ’!Е-UцVќDФv+PF} Зsg™ŸтіФ;wbf<Œ ХиѕNžwIНBQ ’ АЊŒ“лП‹KтН…GЯїѕMаЋE̘з яzŒЖ”Ќџъ‹ЭЙг?љ{z`б'Я}КшЋEzйДюIицOWœ.вfо0Ї”1N?l|ЇрЙёј–•ФЦw‹ џіЮ>ЊbkрЗэнО›ьfг{я@zGŠ Xр{EŸнчSŸНыГЃbQŠtЅ‰ -єNЈ щНnЖяmпЙЛI@ …(3? ЗL§Яюœ=3gЮШ@UоЛсgћ1­8L6р†8ЏФРŠї[‘Ь8,Ъ4)ŒУGD\€>‡бaНfіKžѓімљIQZkM•џаQ=ЂфчGЦЮП=/эЧ/|ЌБ Qš*ЪƒFпд3\юTњсЏПІ9сM\нЎ…ЛsOэbœe[~ўНPчгZ?ƒ‚*Я\њѓўˆћŸьЃ’ŠљГ 2#XЮм_—x™bу•Ї—}WеяОЁa-Rэд‡HАu*^”9"€\™лЙ=ЧЪ}Vnн§&=­нмWYС‚GЎ­cJЗЭ;nФˆёЯ=8ИOˆ‚М’т>px›Ѓ2џD…nТKSвzћhЄ>;§›Џџ,)ЉДFt)qНe]NоЎ3Й"?Eњ№x_ŒgЋЫJ5VT№ю‘^x*ыПŽЙQљ‹IŽЛѕОкЗt…wjPƒOЏоIažюГп”Сёщ#L„ 5ЃxQђећЫзЏ9Ж )rbњAP5 JTѓл втŸМОtнЪN1эДaуРЎ&щЮЧњ˜З}ўCЯоЁ=с4э_ќлQ+г{ˆсфк 'Аш˜ёщ`фЯ3eљ…ў.)ЄozFJ„дPЈ>ДG34 ќЏ 6АЉє›Чz^ 4ъў(ЁПˆРuM sНfHзќЦЮ_Hз8U$яœ>йЁU1­но9й~ћДKз“9іщœ_іж'пїрфАсЅpи03|N№0ХУТЬЯЃ9оЅћсь8}Šу)З0…'ЗВE№Ё{~ђDЈ:\=w9Ћѓъƒлy8а "€ќН€§ )Zяc`ЩбЌц8c›8МЙu˜Ым6Kxё%ЎђёV{ут4 —!€{'Фћрт~ƒk`ЛЖќQщˆ"а.ІѓщэgH™2"ЉЅŒ.b/uыіммGpC†н`ЄnЉiнђьЂыѕB‚­tЊ"€œO”09ж&k:›Х–wЄ€PЗ&иђW‹ц2‚Э `№…Y,з Я5ФБ[ъmv^ЊPШх]:0ТІ;Ѓ)—“~sІ§чWь|6шюђКДџ._@ Ы.:ѓЭ’o…ЫЎa˜г†ГQЂ,ИTр*NŸ8q0ЛвЬAЧ9ЅоСIщ)срЖм{€П*P3итeW5…O7>ЩѓR™ЕћH20BaБл“Кќул]БsO‰…‘ЄNКeєИ4lhCЁ`k<”@Z"њhEНЇрНщвЈ!QM]эІ#ыѕрРь jё˜ЬН‚Ч‘5 Z ‘XЬ‡ іЕИДnЫІUk+ќЖ*ИБЯYcРD"SоЮЏпГ5гмыцQуяшр)Ѕ0{ожХЫО_$O›6qќŒћ)ЄьЉ5ЫO‘њъkW– yтvCЩБUX^Аlо–Т2Эи'ЇЉ–М­п7џ­…ПžЎ4ћнєьЌƒУЌ‡џ˜ЗcпŽU…Ž_Іо=cмЄ^#2‚сф80эдХіŠVЎЯЌЗлaПu :я%л‡^ž#€4Жs,а"€ДŸ€T.‰щ]’]bЊ47х&‘Iуу›žДхТгŽЇY4ŠžЩ>NgЦСѓ’‚HЉрЄHгї.+)9zhц юС7яхmё*Ц3…Й &jO-Ѕ”iхR_*ЌoBhJ˜JAкiЌnп_›їU$єѓ+мїУяrYРmї„dЯ[9б.{Яєбж#Ўлж#t`?пђ}ЏШ-IчЉ—UќОё—п Ъ=т32‚}Ы7.|Qч7ЧЋwЊ|ћ“џ›sЦšџ>[nќzCБXеV)dpFn_ЅўmЯю}%ŠSј„6хHаsь№†#Е'§Э˜.fєЗ›”`гЦL;ЌЗDŠe˜M0)6Б—ИЦц:эг nŸœ8ЮЙ§„‡‡Є@…‚šŠ'‰ч„тЫ€l‹5lтнЗ„ЉСЇэЂSˆ •œ .ЊЄт ЩЅ4-ЩsPёи2оa‡ЃЬ>|їиСёЂ?%ѓ ‚Д`цouY1В€‘\Mж[џљВвЗп§їŒщч'ЇСmrЃЪKЗ Нm…ђг є@ЎžbЬУп3qP<%Ѕ’†'H•mкmнT Ш!cОГ”7у+šlEvЁ“š•кŸgT‘ЪЧеэ&~/dџЦX-–mюOЋ)›ѓ.œvЋБОІКЎЎККВККкju2мИЏ o[Ё‰w5эŽоА\'.кСжBчЏѓчў,;s€ HLˆK№‡7сє11Ў(L›­э‰—ю[ё/THг_Ў>>7ЛЮІ‹NMŒŽєtЅХ$*МdёбТ<“]i†ШC‹_{ЌЌbЦŒMСщ-Q ІP 6њNШ=ћ=8‘Ь]4џЩ)_ШIПщзІNHр˜S гюV Эo бР‘$`Ч€ЪЪOрoП7ї‘™Ÿ1ДР1о}cъ„^бcЧIW}џъЄ­“о{эіНЯœ-3Y‹ўѓо [„р›пўцЖєУ•BЛРџ№Иш<ЖxЃц!m!а9чБЙvd;9 мE]E`ۘГЖВD(€neШ5w'NТъ!!Н|є9GЯ~ђєчЯ|ёDы…“бXYkq6ъT”ТУKЋQуЦђЪЊВzZo№ є"-u&Ok=дrиW`­­Ж`RˆІ$Ю^_W]ZmЌwТ6†а@O­ЬQQf&дž їсŸжђвІ[жlЌЌtЊ|Д*ѓЌЙКЂВдhœ•2] ?ЄХЖђ‚вк:‡gXˆС“6WšmNdЄ[Є5>Zl“Л.:эКьvдhDрoCд$И:ЉmKAэшsЉцт˜нnЫЯЩ—iDkЩKZ­5ЈД†f1Dп(И ѓїї№ѓM\гxшДЎ3˜”)tўŠ†œ”itўO?Q№€'>–{ћКкrl~KЊДОJБўЂЪEP*/?…ZїЎRрЁTс&6LЬ ѓ ђЛРЎ*ƒB{\Ї? кƒ ЅE6hї}Й тzХўrh>ю2тhНV.IбBVЂАM8мС-ŠšюšžУ—Hj.oš_7МoJ(о7оИоЙ&'›=їЭmiЮ/їМxшцЊ СvUиP"Dш`йMЎjС2t+ё˜Ж„zŠџ‹A7ЭEŽы!њѓЯ#€л?ЏOQ‹ы@m­№г|ЌМœŸ>иЛOјљ'0ЕХLˆŒ"ЦвzcZ ’pџф lџфоEmCЎOЇKu”жB8ŽЊOMдzЬєP)р\"ЛŒYИмИoЏqъ!,ќяДй іеЎйкŒъѕйЫ—h5l—€ƒ^!ˆРп’€ZIћЫ 8=1{{I_Z&Зл ЇЃŽT„h’!{aс—йг}й–sN'ЋI`ЙЌељM0пdь6'ћНq‰L*•Сю #sN'+КЛ „?d ПЯ‹ЦэйWЉ Mˆё’J.L~йzЖ'ЯТ!?V8уЄар E Šя…рьv–„ЭщPу _ЕЇшіЄE‚­=єPZDшŽЗЂ‰*NM8˜m ЏЩшgceД злыiŠu­‚ЭqpЮœ]t›&І{ЗАШчтТхoјmСЇs7эЉ0ЉгяКяЙЉ)‘њœН Фrњсћпі–8yp†Œ;lѕо§'LЛ5ЭWKKЊAZ8їM{щƒiЯ,~~€ПЖsЯiуLГrЙS‹ц}ѕПЙЛNrŒе1јйf?sSААk.Рlл^~eOТŒйЗХШ$нХипIяŽ_ T'Dш~Œf.Џ’ЉД№,‡еrG*„ѕ;Љ7>ЄXІ*Ў†дœ4yЎ=\S€Ђ:џ‰š эХyЙEх›ИЭ§Ж „xыКqц|љ‡$~ъл.ќaёПl™ЋпwSNЁХѕъ\’њЌн ъеAСбЩQБ=уƒ‚62ˆоѓіых§oŸ>$;љэ”ЏЫSмѕьј˜UёŸЫо*{№[wм0&L RO,|-;ыY™ђУЪЗўњфzщУїпа7FЏэf›йj1УšИzІЉђkXЭŽЙ?Н9ПЂч[я=43„]œЕіЋЕ‹ОЯЌ.$&М§њЃѕіP‘ѕw}ћі+kvиЬ5ž7Нід=їfxiИo>Пяэ_Зcѕ*юХMo8ОxcЛЖvњчwTŸ—і‹—Ÿ[ПЗзyNњ№…ћfЅVЏY№ўљw/~Sмѓу/gп'“0W§СћJƒIД ЩФћТе_NлЗђуБоrfуCїmЪxъПГ’фДcыГЏгДэZєЫqS•тцžyєўAžЪЎ4ZЕXUDј' BRКŒС`?"кaрOсc6 IгfЉ&врЕ9л6Ў?ъHzђЅЏЙЇ`йœ_?XiцэU%ХF0œdНЇОœQћзїѓќыШЎMџћЯ*хДŒŒОj(RЬ€Р9{біѓџb‚њ&љЈa%J?}`L˜ЇLTgььб#›W§ЙnбЪuЋUT[НвпъЅH|`к ;~œ15A)#I%vrоМŸ†МВђЫзџЅкјк†МJ+у(˜sѓЫЋ•їv№ї_VLмјю{[ВЊ@8:+ѓw}=oтЦЗзОб3\ЧлѓЗќoЮќСЏЌО0эš€ччŸYїѓЏc}њЅm9пaуoѓФЭžёпН юМ)BвX‚ГцќОќГš!“S=iё\TExкП†‡ЋСЗ%†[Ыђђы\l:MЙлПњ~ЕђЦ9™?|јzтК?§ыЎ2‘Aз†ЎЄ]л:T"€\t:!Р‡;C“Œ^ЋўŠЏœяФЈ>c˜љаНќ,bфЧkі­Њ1:0SУYjтp>tдŒ'fŸ~щ­OŸљЄŽ:ћ­Љ§МЄnЉ&иыOn[џљsKœiЗ<8Ѓ_ˆAUа'іП%”98сЦNJ1ХЩГMЕ9к ,hldjЄwИohuип?($ШKMr˜  хŸјў§[‚ѕвТм!єМ“5Ц–}ьOж™юkЭлМŽїсыJЫЭ,ыСй0љЌчМ8жЯgЕ€ЫNљ­OƘvАПхдКн+ j KЭTlpxqд70$4ќ\rтBАжю_ГфЭ‡—=јќѓгbмf™Оcў/ƒЗ‹gˆ‚YыZ[ƒkЮ‚)ž|wн3§ Q)/ЬўѓНлw•о;<№ЪЉЗ+lэТ‡#ˆ@7$0f4о;нdЗc>:ЁоlвТ§МёLOзI4№t&а5šn/гѓ‘SžrвŽ$тр№7’jpФ9ИQс(П9zК:.ЪЯ_ jИѕŒ5XЖ№э7'оqя+3‡zы(s‹XЮ)–/fРZБАYw>rзqО0-Щи0;H2ЛІLY8˜kŠa,Ж_€LЪБуАšA)Г(qпГxЩ‰ •RŠШQўZqІЧbƒѕ„„eм‹[­ЇЭœПр(pС(eЪ бОJgьNVюrŽ1Ц­п|ёяіоўљGГoN(x%ж]ѕ‡K14q€‰žrЮШРž…q,€кчŽг•‘`ыJкЈ,Dш тiжTХ,юыKє|iЉ›ЫыtИŸx Lq)_UщО%hњr#/ИZЎ5е–з;YOТT_хрѕz™Œ>gкЖ…іЪЌŸ^њ ЇТ’{*~›Л6&ЬїЦ~! Š+^ПђƒW—$=ќяІїбШГƒ%4иЄЦиЬ6&SI%0ƒјАYыѕuЂАЅ`UЇ fмfwУЙnEЁ)^‘ДУуу‰YўJ (FСŽу6xУй›"‹љЗ–6хЙžšžф%•Т:СAр6(ЗђD­ƒ#Ф ‚#oсЯ=ПlЦвїєБ1&žЅh™hДҘf–вheчэ\€ЂHЌ6ЛДЮ@І’’*ž єmm/„Ћ)ѓ ЖЮсŠrEkGрФqў›Џ„;Б^ЉТ}їqRжњ-п+эœˆjБЪ$ею?МЉќIq<[Мя8ю;chМЗN– Њ #КaъKз|№СŸ%1}9Л@ЩїНёгG Њ™}А яўVvЊмяиЖхŸŸСсј6ЯИ1“zљЉjlX‘)zkпШPШЈђƒЛз§d=ЌЅрDL>hLМ!9АтЭхЫйс“†Gƒ1АЏ A3‚ žУiDњНR>zњНO*G'ХzиЊ+ќ†пи;Zq~dьќлѓвОuџЫTХј„0ЅЉМRдЭ#Уœkѓл в’О№уВх{эt>}иݘ@ЅЬ|Жџ9[ОY я™ц! бЗŸХžНqч)q^УТЇLчAАёleAa ИŒ‰‘~}њєˆвŠЮ8acyŒ ЋмДіћеBхѓєќЇ“§Ф5Х.ш б.ŽŠŸ-<п IDATCК#Ю9hєšЕtэяьO‹ш*ЛŠи;'л‘š” E„ŸЙЕлф X‚aќЭіV*ъy•xЗh(ИА6^3VА+i <цА`Ўн_р/ Г6\5ОuџЫc6ЗИm–OѓH 6DїюљGF”: жвЬз #@1$ЎЃ‰еCѓШAѓл в:`лǘ–З4І…‰Uи оX.иWB„‡Y_NЬдИHЈдБr)фfQa‰{ПЏI8__“* BDшP2)>aœdђ8šЧО­о‚Ќ‚З—,œ ˜4bц ŒBЏiZуКdќ|щžšlK†myqnЇНјЩХЉZ|Bїšћ|ЌмG.!КœеyѕA‚э<ш@К0РЃ`ЎЎ•Іч`РqёKP@‡hДGхжЅo/ЮЁй\Ѕ7hє8Xо_+§ЃYeКљ%юКЃkмЕЌjЋŸ˜kY)T6"€ тb^SdмДxWk0МѕCІdД(лZKв–ч`ОяŠцоp“<,Ёа|KП3к’Аcу СжБнжF‚ TЉР[~LOƒž+?q`-kaaXсоЭKцўЖчP™grкј{Ї KЄaиЊ7˜ЋѓІВТќ|ЛЗRч­ц,>˜љПз~*(6 xЏ>OŸмr†N92ХWћс№’ЬЅkŽiпи#,ќўЃpЭ СvЭаЃ‚D -іъ˜ГЋЫmѕ&|фоMЋ#т’§яЛr іёlKђІ8И„’аrц(п•WВлв›,ќyЩвз6з$&ŽўПћv-|xNеCџ7yVPS˜ŠЌ>~pлc|`BB0}ќЛЅѓоZfаЬ LDыЉrкѓзvвЫпш€`…ГxщGKŠb' чџЭВ@—]O ЖЎgŽJD+ PІOћ}Т1‰\Ѕ№њdэq_ƒЂg‰Љсч6OE‚#уЊэ™?<ЙœЎ9}‹4nа`эОekЪУo{qњРžjѓ  /_§eпЭНЧOk^9cq†…]lLUўЖ{ѓУbŸz~f|ИZ€‡š#‡Sп|ОхPNrŠПљш_ЛNxŽšщэu М#6Џ3КF‚ }D [№0ŸъПяГWънЬEяЮ&˜ŒДй,ІО}2^yщ•6VзzMBњ€8Џ›ŽŒM№Ё‹ї/UyE‡FЦщрPhЯ PBЋйСxћяО0ѓ)Аœ…уЁоО~Z)E ”f+щ^7TЬћђXIFdЩЧ[Јфў qў*ЄАЕБW:-l†eŒ A@ъЈ.ЩЌ$6КўфСLШ2.%ѕƒяњщ@gkk€г` ссбЗLИ%ЭS’$I0ЅyщФxHАu"\”5"€ДŸ@™ЁЯŠIEpВgŒ\§эЖbЅ ѓі†GшЅ,V—гVЋHЈ“ š–Iib ПHo„ЮАѕ3kЗцмшWДuэщ­…~#‡љыЅ•-Ušђ Lє и§йюu7ŒМitˆНЂL№єід*ы‰IМDЉj™P…FMјя>PcВp•0•š…+ііЛžМ•—(`Їйь—„џї гЋрє3ЉRЃїеЪE9†3цc<›>09мG`Ѓа  nш€Њ€ -Œёa'№=№ВxК'‡%ЎІˆМРћFш'>}Cг“ж/p‰Bў&]“ЭcR•‡oЄжW\3У›”9ZЉІХщJ14П†CЄiЅ6(Vб]ЫrbО2ыНя+žœАœu‰ ` Jл5ЧР№_є*‰B7"pM?нˆЊ "€t;ХgЪ—НГQЉ7Œ-–cuASў=Кхзчž6ЬТBZуГss‰ЭТЫ bž‹ж˜АспѓS]№н^cHА]у@Х#ˆР%DF†>їм}МЉЪmЪq.&’>]TЗ`щвs[ПтN‡ƒ%ЅR™Дaаƒ' 8}mЃ xЯrи,0%СНjж(œјВƒЧNŸbzLНMaЫ:r№Xжa#ќai)Їe36жicХУВ™Ц$WP:ŠкХ`ыbрЈ8DИ2А•–рqђ™оИец,Ў*иz"Їcy,ЛїosNМѓKvчКтЫ,ќ}OŒŸЗZ\Cœ5G6Ÿ(ф4cІп˜xˆ,YЛnћіѓ’4EiКhLƒўэЦ`ыЦƒЊ† f%Д‡ъЂЬ7ТВ-ѕЬ&МzR€бњjт^К>–іN›''_йічЂ­C#ьdу:™9чФ‘œ“ђРD†…ыМz›Oф<ž—>0Jƒк•0ю.q‘`ы.=ъ -8У‡>ЦМЎRJuJмKћDaР=Ѕ| і =’pЌР)гn5Ж wхŽЕІ\A ‚‹ГйГЗ(ЇЈJЅ[ѓѕ/rsaIyM~eС=щ‰В+АPiБњшс5 €л5€ŽŠDЖ`ЋЯVЏ~ЖŽ"*H\BbАMBa БЅїLyі_OЕ=Ю…3Џ Qc& (9іхЏ+*|ЧD %0І:џРоJ6lдЬ{Ц„ЊpŽ"­ЇџZ6gK˜ŒŽ‰дŸ›ŽlОп эхЂ˜]O ЖЎgŽJD+ @ыC‚ЦНЄTЪ<И^вцЅТ4R>Xѓ†mЮ$якhmH5v’1/k^)Fт<_vјh~5rјА‘щZpё*\ЌGюБ╇Ž;>0b ˜@Р иM"У‘6ПІ‘`ЛІјQсˆ"p92KaєйСКЄŠ‰Чъ1,РАфф”иYї].Ећ=Ё я)и‚ Ђ~S$мzУMД\уЏ'•TЬž‘Ѓb”ИгНЉ зјєжЏŽ,уDy ƒЩHк#0:SDjаФdл€_уXHА]у@Х#ˆ@ЋЬXWяtтoПїхХqX–=uќŒРƒшЙl C‡NŒїŸ9q>QРUюyxЦ;0Ї1-ёF‚_5d%`tФ ŸК„ј—ЙП:2эЮШ cнЗ—-EИЖ`ЛЖќQщˆ"а*ЅVЎVЎоКОЕ$I„$ЖіЖљsГ‹ћбЮЮY ЗqgмyA9зќXcьчE@7нšlнК{Pхы™€—ПчфG/s@6ЎŠБFЗXз3,діf`k]"ˆ@w"BЫ)8qЖ`ўl8мЁŠ .Ш Ѓ;uY7Љ lнЄ#P5Dр"fЎВхЭЉц:9Ftqх’i`М(€ Sj•‘ЩС‚žЁ€œ#€л9ш @Къ’куыЯіˆNЉF`иEђЂ}‡[uƒšтЕ•uлWш?ЉчхЋ –ўЌ˜Юq8xŒ;Т‹1+ \Ѓ—я€.:ЄKqЃТD э,F[MЉЯЌžsОЗтЭи€ИчnљЗT"{H†a@‰ЫЫ-кОxwђјсНЇ*-р S|ЂRТC ’Ћ˜Ц@0bBƒе?svѓц"85-\ЏЙB7(mЇ€b^9$иЎœJ ]B@мMbћsіНМфEГДІД ]Ь?4ђЁы7Ў^Н:,,ьЎЛюЃРЩхƒP}dя‹ЖзщТueљЙйјАБw<М|ХQŒЋ"€лUaC‰D KdлВxЅg "Ь/vkсњХŸ›Vд=4фQƒСрсс>љК-ђуэVЉЗoк„ C,\ЖуhЮсЮ^оRXНу0Т‰ N‚@ МK‹5Ѕq)Ч рчЫVnћВZї№C0A"MКя/кш%8Cт ЭС\Ї‡SAЦ‹ЩEJ8ю$VœHХAЏ…OТ7ъ|]ёњ+ ЖыЏЯQ‹П@}PzJќцX ЊzОвŸI•2vзЎ] Б…‡‡п}W=ˆJ™R­ђ NHгKРПёжнLБ•с1kЮл•Йќч?ŸЌєˆI~Ч„a}Т4[Мg[VžнЏOпФ0•Е0ыЏ]ХВјњЊ™[іnf?_Г<ѕžу'%ЯžЮЁy/_•Œ?ЕbбI:и/љmёŽ‚"йЈйЗуЁЄ1[хЮs–џ–WQ1lrИЙNкoЪ€И(/к­Ф§}њтoTS$иўF…ЊŠ\wtj]ЯЄWзфK%rš&хvЯЉ# М УBУф ЙЈѕFDrrМУјЫJВT њШpf;5љќwЖ›’“Fо–RypЯЪgПЋНчЮЩw…ГГіь­‹ш ‚Э^•wxЫQuЊ_кJ/Е*0\?"2,ЪG*СJЖnјCMD&GxkЉЪУ›—Ќ*Њ6$^Лfй+ыƒƒ}вSe™O}ќЭЏЅ13є”ŸZАzы ЕwzRd„œТƒB'@‚­“РЂlD C$NВеєЩ_9†Ё§|9'яЌф*–œ^ќюŒїђs‹Х-mm0XЗџЯЏў:Кf=Тћ</ОоЃсѓrћ;ПБJR+m уžnwbR:wсѓ2?/Н™D^КУкљ ЖvDЩD ГјEиём+џ§ь6Р?Ј9Ш: Кv„иz~єц\C˜юІЧ†ЖЅx‰RM+!bУŽi’•ИŽ ŸLущЇё№—Фš"€bGk}}5№D–­ё)ё єr%„G—\<Э[ ђfз р rxХйЖЯ|слz:І4Еy{f~єну"УtрЖ…Ю#€[чБE9#ˆ@Л’ф?эquы‚“~рЩƒ I™’nуlфљГ`Mв“7,Ž5=vЧ‡П$l~ Ыjё!кЙk—HsП‘ЧН8cк3%&6eф§ГR{ЇEщtШБdЖNЙ@‚­SАЂLD Cр$.зРD_ЋЁQ,ЕсšПа'Ім—ШЙЄ˜Y’А…N&€['Fй#{Ц81бО1РЄE‹џЁаЂ+g‚Bvzm@еaQ`ы0”(#DряNрЛзП_=wѕ…­рyмTK+Я='H^ы%Ј=Я=AWˆ@Ш9uЖ§9!Сж~†(DрoO`а AрVјаžCmnI~›cЂˆˆР• (ЊoпОW–цќи`jд|)єќ—ш@Ў›6m2›ЭзMsQCЛ/€€€^НzЕЇ~HАЕ‡J‹ ˆ"аэ Эnз%ЈBˆ"€ э!€[{шЁДˆ"€ нŽlнЎKP…D@кC ЖіаCiD@К$иК]—  !ˆ"€Д‡lэЁ‡в"ˆ"€t;HАuЛ.ABDh$икCЅEDшv`ыv]‚*„ ˆ"аHАЕ‡J‹ ˆ"аэ СжэКU@D =`k=”@D л@‚­лu Њ"€ ˆ@{ Сжz(-"€ ˆ@З#€[ЗыT!D@і@‚­=єPZD@nG Жnз%ЈBˆ"€ э!€[{шЁДˆ"€ нŽlнЎKP…D@кC ЖіаCiD@К$иК]—  !ˆ"€Д‡lэЁ‡в"ˆ"€t;Tћk”ŸŸпўLPˆ"€ з9!€4ЖСˆ2ADш.`ы.=ъ ˆ"а!`ыŒ(D@юB ЖювЈˆ"€ B ŒGмѕр8ŽчљЉЪИЎ‚ ‘H‚€‹Ж4ОhкЙ-Ђ8ˆР5!рўфу8осЅwŒ`ƒяdEE…гщ„яg‡WeˆќГ 0 Ѓзыu:Ус‰uщЦТ(`ГйъъърЇdgŒ—.НE:Š|zAdSTЧˆЁцыАAі&$$hЕкЫ~3›Ўыœ|НЋЊЊ@V]‘ІVЋe2й?рЛЭПЂ†џ?-]йЦЎ,Ћ}Aгteee'ѕ~‡ 6h$|ЭŠ‹‹Y–mgƒQrDрК"`БX@JСдЦVCLPз@BBꘌ{FГZ­RЉ”$ЩюYНЉДК киі.ОъrЭfГBЁ€)ДЋЮЁkТфдКО“ŠыHСU ]аyФe‹t=јО\Х0ПsaP ьњ:w`‰ЧŽƒЩ(FгyvЗЌ ООО0е|}ЅmйГgOjjjgLю]iM.цвЫЅуДчmwьэiJ‹ќГ tв4ŽЭmХв6c–Ћ†мСg‚“Fm2ПЙъ_UBЈДєЊ’^q"јHР’э'ыђ гЙ{ЌБu9T "pp —№Чe)ч R4РЙк<НйЂР3ѕѕVЉBС9Ќё=У ;-шЖ‚p­FhLeHž 9`‚cmЇўuшdЕ ѕъ7t@ AE8|lдёЦT"^z\з)ЛP= vc:ў_$и:ž)Ъш0BСцt2ŽКЂ5п~ђуђmX LЦˆсR№в3^‘Н о^ €рšŸƒС*“u d‚8ˆСТB§єзџp%№œХTЕёЭ†ФшлЗЋу˜˜ШP9)Њо(…]ƒОfЯ+9•ље‡Knјз CzЧQ8ќœ' КPЈЕЎЂ З40>Q ђ ЧHх]ІjP%Bд%aр'gіlи~$qиД/ЅРБœšK™…і`Ж!цЎ1]РIH€„uFЃ. фn#ЬМЙмIЬw IDAT„7Eу•?<={ЉЧ€u?НЄ”Xqї]ŸмёбтчЧE‹•щэъ-PiQчжV{ќаЉ№ДОj bИњQ|маƒЂШohŠржеІhŒƒ“–’}яН№ŸBвЫnR)‚#”œ4яLITя^rЪ­К0`˜ЉД0їleTяTбјйЁ‰Л*ЁбцЉ!оvH€6Б;:- СжihQЦˆ@g€q2†q:œ,­ѓžј№г“яšЌъъЊЫŠB%juюб“ѕжк:ŽŒŒT:k8ъщТœхД!P/ŽхTќќМ$LЕЙоTS™[PТŠЄžЉz𑄐<хKа˜–g8§}РэїfЈkœЩ5k=^Pl7§‘ё|f0Ы‰‹“`Lюx€к к I ЫР|яЌй№УЊœŠššъSЕвјћ˜bЬ>–WUdњkgZ”bЯђw(ХЄЩ“Г5•ЧПŸѓ[юМёюћДЙй{wэ9JFІxЇeЎ]ЙџиIЃЊї+џ}TчЬ›ѓёЇ'ŒvOŸA‘=#Ві­XВhCЉбœ2Єќю™“tJ Ј;пАf96o#ŽS иврщAnкtrlˆ~ѓ^KjŒС!8ВіlZВ2ГДЪиoђ3ЯMO˜џѕЛ›Oлzі‰MN*:Б3зZЗnУ–ŒXCжšя6ю>ЫIДьь'cŸН№mЁŠя;щЎˆ@_! 6ЗЩAr<­єђ`Wќќsј„1CМeЮ‚3{sы+зmмžEќЕnхЮуy5dЬ+/н“—s ЗЖlУІIQ+>н3ѓ‹Ї|*~јqљћяOмЙђ‡ЏVdЊuўžБ}Мх0м1Ќ zау икПЌиŒєy—Hc;КAў.рч3 š`|SnœЭvіDсf•Ц‘šЈ—1ЕЕFКоЃЊ4[0xжЄ‰~ЬБїзmю7ёЫЖuGŸ S'Ž—ЊйcdсЮ’ЂСGeІz›ДЯаIЗм2qЭтхЙХее&˜АЇФ`^’o(Ѕ346w`€ƒf€ф„`йІйъЪВ*љ”ў=aсзЪЫј˜ФR“щлgOWџОxћБЧўѓТЮї_п™•гWR–[PtляŽюS…н\ч5єž;Т5‚ЯЬЇo1{ќЉп‹ЪЪŽю\Qш—ёі‡w+ šЋљ№Ї_4щюа;—-§-їІ1Z™ЊГŒнюBh#\CШу&тlп‘H—їйK›[nccњM|Ѓяи ^О=Ћ~ЂaїŽœ‘П3mpЂšТтЭH§ЭђшѓD›ЗЮ^њчSяrфУџlмЙЯЏЏ&'7{ђG_пв7ŒР`DќфR7O˜žєJ|л |ѓУgѓjю™>.БяНmxњщY‘JЛъџžšФ>pџ9•|BПiНNэ|ў_3‚Й’Ђ$-QщƒњMшm<\CВŠ’39ЌЦл;"&J–Гќд^J™–VXX„Ћ-Ё У+ цžАUZhoJ R„Ы}%IQЄDJKiFЂo ŒѕP{ђ`M"Ё`ЩŒ„Е~“'ŒN‰UџЎЪ‘J4-б@ЙмVSM9е9ЧŽ:"Н§}„ъВф^НіŠв(ф&ЅTЊ“Шd жRА+s+IСF№Ќ­ŠэЄS(%RЎЊgІтВNЉЎWš‡BFS4,QuBЫЮЁr7к$Сх ”ЅАдžёЦ3‹О§2х^EЩйZœШ>ОЃАЪYZуаJ0JўЃ‡Э_ОИЖДhЦД2‰–›f),Ѕ9}обuq‘сЁQ2f`М‚„ѕ*БwФH‚€нŸqвwъs_њФ/xэй7DЦёЂЕЄD.•ёЮђнлў хrB dRJ.‘hсƒ$—в&шxŒ’б2…„–<­š4zТџVf~§х#fм6&ЪЗЃHA%ќ=‡ЉЃЏ`ыhЂ(?D KР(Ѓ6NBIфВАИШAУЫйМcѕ0d0Е‡ћ˜œ ЕЮSІђJ4Ќw”V­ъrі/^p@‘>рІщЙsžІ™~ЉE?їgъшёQ!ОHАžƒ` &%Eƒшџ&0ќƒ*уn‚8ЬСЊЫ*’€TђЃ д„7<–PRА1[Љї–{„єш;zЦ$­ЦCsjsŽљAE!Іh ‚cMцюњэл…yoН>9Рѓ„‚–k ЪГе%f'ЧYZ)—*} бSЧЄj• ЕFeЕзФўr}эФЁ›РЙ ˜УP`Р)№о1IўA?НЛ\wуQцВ$Sєљg?ѕПї_IбІ‚j–РхЃž§OРšяžќ`iBњА|”`ШЪžжЫ Qњ'Іš>aВ\ыaЬо‰cА{2w“@YpэF ѕВ™ъ”jФФЛђ—­>m,У А '@VXћём§ћD€v/p'I)<‚R (—еk?ОѓА™єРxRWЯЅDкI~ъЦФФDGЛ,пк™Wcr0ŠAр`а„ŸР0jт @ћ‘ШIR?СIŒ–RRŠєˆ0y\жO+~иМ”э;aњд)a ‘ul@R\J]јМ?ј!ўСБбЊ]ЛзЎ–ЉБrGeXœ'Ю2Z"ѕ ~ЛwšЦ&ŽЉP]ЗЦF`pЅ (™T*' (SД„№”Pi`D\ чВ7?Z№ТƒУЧі;ўеoi(~тcЯтЄœР!rRˆbо[шaмљУТ еіуKЖф?sѓјэ|љЏћзz{g<ѓц§їм3ь§я–ОЖk™_TтУГPu˜ADcЗ\ј/t„Fa?hЮIЯ QS'2Н"vТ•JmЌFП}ЩќlEnБ§№Ё]kџZWSцяяяэщх•ТОўњ/єџфECѓiЉ”n\(tѓ„сŠ#)КxЧ/Эн‚сœбюћР єЯК`эw/Ољньa>ѕ•пЯgтЯ,^{ш§щ‰~ђљ/М=џѕћвНВ_|р‰ КодTRdтСС†КтЃЅ˜_l€Gй‘§‡rЫ5z­—E†‡рЕVяшSQЁвzћщiЊSf  №ѕ uЙдlЕхЙЙ%осСЦМju€Ÿо“<™SЁёєђѓ$ OоU эŸ*1ќ•ЙЧdУz (aЋЪmЁI0ЅhЋ*.Љ2Т"eіЊЬПЖUQž~ k-92#ќдЁнGO•j"‡Œьу-БnйВэlQ…ж/t@џ^*б‚ОS›C‡y{{У($юcУЌY{В}cдЧђ№ы(Ы?iU…bgїэ=Sj „х⹘иьЌ§Ѕ•џ№˜С§38“stЧЎГxПA} Xйк?Ж™ьB|пСqоВТ“Uсё`есn”•™™™œœ,—ЫЁЈњТƒыЗЌ3БОёщƒћ&yріу3”*‡Є‡фdn+”aМœ й',џшЮ•šQъЮьм{Т‘i%єƒ’ ‡іff.Є•њС#Fјid… Ff8 gЅRщссbИЉ BBBšЎлsёOl0”——Cg‡……СрвL(-"pе`ј.,,„O Œngrе‚ „ЈС`С9ИВmЊ З0‰ЯиЏСЋ ‡юЄMчUЏёi‹вњМ˜W{г$и@ЈCжМЁvЂ)оЅ~Къз˜ЖБIUjl„ыўМ›&6Q;ч_ЈисУ‡§`[…——Ћ’ 5msiTњЂtЭКВоЕkWƒ`kтйтrљДqcИ^5+чЂЈWјъ ~§Ož< И“л?y*z~ ЈT*OOЯь•+ьD§z'+I БZжс @XBш№lЛ,Cр €xћ[ЗтВИ@Aёš —мЮРJщў<Ё’Pеv6іЩџЩ‚Энlї‡ЉS!^‚/z…tЦpŸg˜З„%ф’’’П/aюAоƒЃwXniC+šƒ5+ж†bлХd2ежж6Ÿpkw–­f`4СЊ 3>r­yU/рглЉ@кђyКЊŠ_”HмmУ `pхžV§нˆs.ŠкU FАт?КЊРПA9А ц,Кџуo€ВгЊђ&иaVрџюS№§os@˜ПDиMЃX`ќmОЖWвЦі~hКВЌvжњ~™Е3“ж’w‘`#(в˜tё†ЌС7Mˆ1(0Š<ѓЧтУBфMƒSР ]k•ыдчАД$ч”Sю+ЮяwhЛнjg•uЧ.КsЌгnsДT.=Змк5ч9ЖІ$ПšU†‡јJ:}жЄ+~=f я0Ч~е-ч'ќИјСл ШIRrоŠЪUчл‰ aЗљhж‰рРOOXЏКв(LђАтў’юD6УЌЏєдј+jbW 6RbЏЭ_5їУbY№ З KЯЪНЎУ№бƒz€IќЪpџа..УGOмЗ!ўыжы\G.И.ХЦЙ^ˆЋтАК ўjsEПЂV‹‘YЛ§_лqыПчNJjKbŽHиЗxЙШB}uaцц?ЖgšfМєPДG‡pЬ8ŒYћ2Зm?’6њЦaq—­ЧхъйТ{жd:ќезsЅЩ?s‡wgmлBЙшQ€пGeЧїз—ф <ЫуЄЦ;Р'&YЁе]ЕlПУЇ“ЄeбУp ~39ьž `№%цHьŒнЩ‚џ.зЏ]мЎќ •рЌЯ:~R!“kЕ^.WЦФ8lv‡гЕY6lIU y“cэр|ВPЎSK;kކgjjъ,ЇвшT Кћh”ЋБЎоЪ ИTЅеЉх"UŽRД\ ПМЮiЖ:фЪў~aп\tяь/zкAКHАAmС cЌјѕу7ъЎђрq+x…?v‚ к.ѓ<.`‹ xжaР*Dw2,.—ƒST‡еСвДЖoŠoДјиТ7DDУs”RWќ)0Юч—#šЫб„{…‡іфIC']:.œPБmЫЪЇŸџŸХ™:щЙ.љ о luйБйO§ЛЂ†ИпПOЫƒЧdзrTgDцэЄќ[.=эZ0W‘П{гўоgЪВ1ŽЏg1MxТ ‡^JN‡}pWWkeюж-{§zŽ ]<ЈЮ‚г‡ўњcaH9ЊŸNйb)NЦЙыTцОм§рнf(AdEї‰_R­RЎ—)jъСu?гŠгBсЬ–•ЋіgƒЌfьF]ќ wŒ •‚+8OcŠЯ~ћŸџ%М№ъ-)ŠŽњUCУС&5—ЄфkrіџћѕŽхжŽЛяпїо<@ЏъАЕ-тjуC›ХИiё‡Ÿ§єg• Пqњ;о зX+Nџў{fЪј;ЂМЅeЧЗ,љ#чЦщџaeо?#tе‡bP8Ѕ”sЦПоYЙжppR<—>tŽъмŸ|`кmгю~№У§&ЉлГ№“…kжЭ}џ_S&?Иnпёѕ?2uЪ­ЬџЭ>3yЧБsя›qч]їНВ'зђЎzaЩА7jK—8mІВвтттвšZ+ш} Ёvй)1V“йъњШ3Цz +š 6c]IqQiY™ОXVго>}ћЯЌЊŠ*о М мн—MvёsРГsНХ\WY^СaTjП?yї)š…ЏЄ+8эІjp~РиŒ&83Ы•‚Бз›-`/g3з›Эf0~Е9VёкдpmЏЫЫJЫ+jDс‹žобЏМўцд1щ&›ннXžsж˜ _јюC ъm–z8iБВЊžс˜ЊŠВвВr›S<І^›kЫJŠKЋkMP8ŒkV“бbГ@”ђŠ:†cыkЋJKЫЭv'ќ`'•”JJ8mU%ЅЅuА_FЌ,ќД0——–”–UкЁё‚MfK}m%dЧ?е”–•””жыZ+&AЁћ“9sY>]•Cз— fpž\j)ЮeЬuУ€^џСЯ8шх+j[Wёџь]`Gї_Й=їЛ\м8IАтюкb-PЄ”вЏЅBНџКЛЈQМhБ"Х] žwЗsлНџл; 4 Х’ЄГ_?ВЛЗ;ћц7ђ›yѓцН‹ЧцUдZЋДЅьГЏ>ћ“ЏŸЩ4›o:™vа5†:ТЁѓжe”Ÿ™3ЋАьlь|–r‰{8“wДDN“f6ЈYуТсХЇџиt,Mk4й ^кiЛQwцшсМ*- УXмФ%0^WОMuXjJœ8[Vg‚Fݘ*?џьЃ|ЎџАё‹ќvя…"ГНщОtЇ;hУЮЮwGhІъZДшНWПY[iДвU%Gwn)ал­ЦЂ%oП|рŒ]СYяє+­№НЎšKH‹жиsh'ќь–еŸймѕ`BЧДѕњ„ћ†їmўі§?іщёeЗђ л>;БЇћјЩ§ќWП3on@шШ‡ЦЧ,_ЙБџРоЙ{Пљъ@—йQчw/њцзШ/žчтМ@SЗ›V"ЋЎfџњEя.\gАKz™џС‹=Ё с-кf9Г~сIq9Ѓ’L…g>\wqЦєё>d§†Япљjѓ1‘‡з?oз_њ!ѕ№сC/ŸŒ{њ‹o=-О?g§)Gп ЯП8g(ЅЭ^Лl™–tоWќтЂятн§%У„мЃЎоІžўі]yјЫ‘UKщfЮxШƒoЩNнГ>M{џ€Ф›—фcвєУч'<5Ї&e{#ОxјтЄЇfWй^$љ}ŽїђGЏѕђр T’2S—Б6/РІЖк‚sooН8yЬЈp[жяkЗHxVяyіyт‰о‹?y?ЛТђј[‹ш\[pўзЏцЏ:jъи}ђлoЮŠ6/]R)ѓ<А~u-їЪыї^Йh[Jю”љŸNэщъЫ/ўќСБЭrњ>№фГ —3ЦГћ–Нўбйсйїо+?Пэ—E&7ЅFжѓб1ЁŸ=ћњšъ;bмГOЭ•ЕдHЉЙЊщ ]h*0‚Ію) —чpЬP]“vЫхЉгšŠрЫ7/_и(6“ŒэžбB Є2‰Hь;љ)ОBУ‡aЕ•/AjŒеЄзгB‰€C)ъХ0яU…ЄРiБеhЊьM’тJLкx7Е;І>Qž™C№-&ЦF1|1Ц‘€6(Іs,кx'ьАшC;œ9ЙПRФ%ЙbЊќђo, xщЅ1Tˆ˜ФH gшЪŠ2.AЩTrЛЌ@ыj+uFZ QШ%BhS& цhƒб&•J@ЧKrѕѕ:асЩUr>ЋЖГikЊ`М'’)d"ОіlкзПџЌЈ/7Я:qДJ<ёёYcт„XеџЅœ8з/Ъ‹/7ZїђаŸYїщвЮупџј ŸЁЌГ?]qbЬаЎ$DЌƒёБ=uУЗ›‹Ј—О#ЕЋЕ‡–#6X.Г =‡M™іРsП|Л}–'Eй@bWј† TxaікЂš“Y&Ќ‡ЩŒЙї›њњЌ К]…ЯU=§іьЮЪМЭПSЏ­ЉЬNЩц№ ЕZгwŸ:[k`ќуњM$nъ?€Б[вЗЎњПЗw}єљСqЄРШСХ… n.ЯNq=’TjkЇСуюЇцUЎ}ъЕMт!oОјх{?Ќ‰ Н?мp|эЂmš1ѓ&Lђ–:Ћ2cФkЮх#…">ПўРВЭћюэ‡эйЗ+“I h]Ъя‹68zЬ™9гO`йОvсfВзуГІљ [6.м.ш5cмдŠэKОўфн˜E_ЙSla€ёjК0 ц‰„2fЊ.;АцЇу>ЃІŒzђ—/ч>rdјшоВ•+nы=ёw?оdKzёЅЈ]ЋЖЌо™4!‰:ОщћЭXЯ)уFхЎјzідS]Л –˜Н~СЦa}ž!1kкŸš5}ЌїoЫоXф6Ьг№љ[›žx5Аф№ТЯОъАшХЊŒƒ‹=ы3іџз?bчw‹lБУ^ž$ЉШыђ|UHєЗе!Ф рРЮ*ЌЮЬРьž]’2hгж.$7//VvœВс„*АCЇiЯxХvІљgђЌп•ЇЏ/NнНџœ_ч ЯЬьЧЉ<ќч~ПnC}…?Г3ўў НЛG”§sеІЪсГ‡Х„Л‡‡Gdћ{–—§лР‡™‰;lVСG-‡ЂДa ЯFбTœ(й›ђВкkъ ‚(лpoPеp‚/Je2Йи”“ВmѓЦгЧx3І—Ь}щбС>fЫOYЗцэ%uЯНџЮаЮtUњЂц­;\<ьщцŽ•гљызnаZъїЎ~dоЄВS)„œЗbХz=љТ{Џѕ‹їЖ–Є}љўѓœ4їœјќГ3ћ=ЕхиЎCЧџ,}ыУ$,лMхъпŽŒєљ-7ЛЦj“cќЦјŸ˜6ЯœsGіq|LьЅb—аКOšБrќБ‹9IQ8Ючъ‹Ž}ўыs?ьэбДfnЭ“›лHЕ‰ Ч hЙдЃлЃџыѕъЦ_#:›p (#IcххзўяНьb3уъh+дX‚фЦFЧљJEY‚юЏтZk8\dAтYЉџїдl`#MP_ŠtP<Ёє&l4­;vё Јп”ЇчLіAu–™џjДуRo€G0XШГš‹jъ”*КcGЕ6 Љ:&jЪƒЛєщ‘l­LY›•‘№рД`o'Џ&;ЇРт/3ˆ=}bўЬ"˜y:gTWKж-BЛŽђe о”BЂ,й•–оIШЭI-OšдI(0˜DОНЧЭllœБшДIтлwќгГЧФrSLърAОќј@П,oњџо§#Ѓмъюѓї.†р(МУІ?‹ё…vЛ[РЌ'ž™Nё3RЌњС/<92ч0vьчЊzsЭ™A=„њ]rЃrѓrѕБсЉ10ѓпU™šŸš№ж“ь—=vН}ЮZK%ы=ёЋЇѓe*ЫŽŸ8pрœoBэYŒ˜,3[Жфз90ЉИoќOЯ№wдŸЎЏ+$h7џЈЅ№пz­Ћp ПїЇCa.IёСг0І’ƒя|ТF›Въъaў†MGQЋ+ЩЃ#%6Cх…5‹з›;о?qмШ]k—nˆє-NϘ‚…w ї}џћжпЄВ!Л]o‰%UH[|\ažo’y0|䉄—ђЮkыђ„‚2­БиQЮЅљМ}”І€LSY}НбnПвVMыlцЙу'ХR*:6вн+"NЃ ypжаAЄв[IцВ%ЂЩSoўщЗEЧz„+ЗЬk‡Ќп+oј/њtецф˜qсцГ›~]Чщђиф}•јЖ?~оlJœ6a\цšЅП§x"љн^+žzїXШш—ž'|ПxO—А@їрШЪОуЧѕI ШйёЛCь&РЂЧGхFЏЉ3БнЬэЏў7š­;Лщаыы%nС>"—Mз#Є‡ŸЧЙЫ…LŒRkЩћьЉ—н|dx'ёЭmтюL€{іV №2’‚оу& :0mбjKђlбЎ[їв{сЛЃі|ітvЋ&жХu†n‚С,` х<рueБ†Фtћр§w<6p—ЊрX-А.рРaБэп!+ ИЧіp“KЁ-C|Ь УПœ5Laж8эр†і>kдБOцŽ_о}кO>!gЋъ ŠcuаZ›yнgЯэY@Yэќ9j ю0ЉеnБ!опЙчъhт‹`QоnQ?мCѓоžcчxвšzjR—ŽщЌBщц.сsM\­R{EF@"АЈ’H§ќ%BОH*‡wС"„ƒєЎ&щ”•У•ˆЙЛК›FРы  IDATˆ„/Љ’!“ 9‡ЈЧILkжя]№цБe<‚MNšEa4XK‡uˆ№›HсЏ’цёрцT-АЪщуэЇ’ru& _hГ@D ћх‹Чžž> Rћw‘IDGDхУ5їсCOО=cъ‘с<ћъ”о‚fї–ЮfwƒGQ­ўB Iыp0S4сИ?СШH\ ГХ„’Т2ъэu8(Sn5лjД ’Ч=7cFЯp•qёxfUЕIаv’qѕЈЉSŽ=џб гWиBЦ~40бЖїмк] ѕк"ƒЙ€ыэ ,сVђЫЋt5j™ЌДЂЄ8ЛЂJ’Eъ”6›хЏ!щпSц№0нЎэпgng4_~ёеЄ€ш8Зˆ^тB}Щъj­H=ёС'‘tT›ЖшTЖI—ОЉ$/Ду(яo^}AQЉб‡W'pdжгzХq+j…ъщsžœе?bKQЪяХьSНЕВ(~ `ˆи\•WЎэья[žдЗoИП< BЂAѓqЮ$9јџ4YЬз”+—ВЏ ыЫ—pх Иb’g4вEђ*Šг ЌC№ыѕНЪеGліпk9n‰l“@8<™OТ§cfo>ёЙжqAOЏЋ&d,Я9ЕыМ->о`pšJКЊ?]Q9@са/G%Јјх№БЌн5ѕее”XfЫ=‘Z.ып+ъЊ#аe„с‚ DбlВq ЅЎ/KјŠg-0*Ы/АJи!УЛOzѕгћЦьїШ{яnАt|8ШR_osPг‹(ўЬЗПŸ; œnЊХRkў1ў­њъЗС ЮYГ.Vn0yБ 28\чw4ж1у‡oъ<ФAН#еC./RЎf Š`\g"№ЈѕР:Ж8@$c0Г8~ьцi8Hі/ЛЌGlvV‡€c№Мѓ]иР HБ4Я> К›MТMyё§gЦu† ЬŠЬхчЁљС,—}>gq>ь”DЛS($›Іh+˜Šˆ…H6:Йї— О –BЬ ŸcлЯ`lНЙ5ХѕIіѕЊ KЏYПњDПф^ОтЋ  П­ЊšкЕЇВёаžPЕРЂяВХz6ћˆПБˆ*šqусZ›У ˜э&Ј`7ЪCЦгO% Œ€н ‘IЏŒКUHR`‡€?ŽІŒ™™цЏCчk‡ГŽ_ЛjxR^V~hнa‚"ЌVО€’Јъѕš:‰6)кЭ-ž‘ —5|эКkЛыњФPppУ‘АО}Ђ9`xуbсвфАЮ ^XўSb‡сБ*Э‰ d;зШЮ=w:uп>ыњяхерђ™ЊМK'/ж‡И‡’м:ЬUpЁ’—БrЧ™ЩЩŠшбjяХŸЌяѓИЏІхnћЎC[SsцЬE­Ж>§ЬyЕХ?Шз­№ЬоДZŸQЂdЁїu'о^~‰~ёБ!<0œqIьт–‰œеIзfЄ_њyuOYЇ[6р!#<)ЛUŸ{щbNAq­!џ|VaH7]™{№Daм}ЩзџEёАW а yџќн–~IСAbЛUЈT1ЎžЦѕmзг•XДlчWnќ391Œ›~ИФ0|rчhuYPС–-›вnвЫ§|`VЦ2"њZ]к‘Œ/аШ”І‚Йэ=Г]Д P™у;&vэкьfuкzT™ЗМЦ-Гд‡МЮцЈД`|(лкА“l\$X ƒ}-`zџкТ‘:+K\LUцщ‚s…"Оrч‰Гуvї”њАЊЈ0 чЦ0XkAЬўЌ’*K€ФS–ƒЙ…K њЮM„mюŸqOп0Cйž§чKЛ 9L]vZJQўh_Їкjуt§‚_н‰OоyЬлkѕаx_ш›[ KП…ˆЭnБИ'Ž|5ށxП6›њ|М` јaУJHї‡ЏС<Б€ћ№ @ІЄ $xf‹ЩНгД_:bЬfЁ|>њњy.Ÿ fШI#ŸZкыa˜эё%1iХњЮћЌ уKW?}#рŠ5zъќЫ‡>x{юЏ”ДЯˆљ_Н$VhфКŠтХŒЯћп[OМv,nаФ.ЕJPyъѓ/§№ЬIŽ*nм‚Сs1fа fё /Пd^АhСд>Њzaк#їџСŠfА`RIЉX' ‰ьЖsЛW=ёЪзѕ6цНЇgї1яЋw'—^оБњLяQЂ)ЁЧ9ƒ2ізът-–пЄJ0рbы?Ь~ ˜MТ9ь…РdLкЩ5SјZьјњ—) І&џќЧO=wАВУO^едfџОуИ2<.J6#С*обЇoPЧ$љ7лvўqH–dпБэRЬє‡UМ{l99ѕ0Џџo?ѕ…ПрБHЁізЏ>Шє›јA|NнA,c б˜ІžўЩЋЯ…§В в]бn˜ %зу?+Ъ-мiЕёи@v№= Ёž‚‚‚\љTАЛ€&)‰H1бэVp…ё аˆъЕZ MJЄ`ђ‹AlEœБѕЃйnБј|ЇЋиЌІеšRЁ”}ˆХl„Э\$W ‰`ИjГкH.ЯеVAГjБ]йЌѕ`з9иdкhˆЉШ#ич`ЁСs2˜ƒе4Bм_6ЏыОйЫ.§ьнїНŸX<Ћe!`XЬ*54xUp4L6Р {Ь­vЏVлжЋиmVƒ`И Џ„/9ИьžwАЛ6УЎ8G ‘ˆ(К 6“>Кь0І€и‡ ЇЕBФJЪnняь•бтHЄЎSfкjаъ@3)‚’†Ћ…6Œ]n„fібƒЂ.‹Фт[pЫr ѕЉн=nнsssСл/Dшјgц (o7l|„4СWфЙд‚XNoМёЦйГgСa.Dц O№u‹`x]]]цЈ)Х,:ЁЛ_є#ozwъOђЌЄ.yюХЧъѓkѕvs—fЮŸ;гУœНbљъЁГ§щ‹Ÿ.о6fцS}"OЏћђћэgЇ=љbЯHбOМДњр‰Z;Ус†НўХЛ#ћФСЄЇ0Q{ы­З BУ ОЃD*QЙi`kPPPр˜1ЃmіъO>§nЬшQ ё] lxƒзсђш‚9Я/:Xi`WЄqпж,z<џатз>[5xо{s{z­^№e‡)яѕ‰r?ју;KS=?xwВS№Х›Г—э+7ZёG>ќёСH|йOП&OЇ[И‡9чР‚…K;ЯzЗ[ЈxЫчяќQіСkˆŒ?zэыз˜lјМЏWNы№Щ+Я­н~lж‡ПЮъŸЛgс+ќ˜^jL|ђ›/ђqЗžp˜*3тЉУЇГ`4у’№бW_w ѕ0\оџе7?і~цћnЂŠ3цO5њй…ѓ&tЖ ‰бh„€>zщzoШ(л?ku#w[#OДТ[ДНьЬЩї^ќJ§ўзЏ%Њ[Ё€HЄлB Е˜0yТ fžПњ*ЋнжЫ7~ѓѓѓ=фў§ћSRRРЗ\П~§Ў{œеЧ …` 3ЇVкrЏ“оKк3ББ+Q8кHVC‚„Р=BUAVГюбї~VЃбЌ\ЙВснлЙV„7‡ŠжWVЏ^}cA€Ь`:њLдœo њХ‰@{&6#ƒВŽж3XFЕюП‰€@Рš`ДВzxХт-‘жЊКј{m‚UЏз BŠХšД§tuэ™и ›­Ќ+Йxtњ_B ЕеC00ыtv‹бInр •Я‰С@јnЪђ ’Єd7ВСЖQЮ•ЕИЦ„DЎулЯ€›н‘ЃG";DљzAШа?Г—Ў№ЎР]ђѕђ0ркиФ@ЭшфŠ]М„ Рrхѕ_nDЮ–НЈ8эxиuУk"АЩехЩPƒэL­еЮ‰­eыњB - рpдфg]кЖZ_pќЅAlCЙhЬАIJџшјю,6CmaQ™иЭOЅhdƒšЁВфRњ™‚rOюо!&жз œН5B4C—ж—зW€™ь’†ЃY~FdШЙЌck~QЁŸŸ?Ьн%ЖЊ‚єœr­30И…Џ Œђ‚-8а}C*–ъ’эыwљяЇl:'ЃcMё‘gjtџ‰qa>tѕЮРlкЗ ZVnњщѓХšј…u” (›О&;ЗШ=(R.ЂtyY…к Шy;rіŠˆ­ikJ !акў(8u0{гŽЪ"0ЭЏ42тРPяиdЙ—?qЭљФmЮ8ŒхйЛжm ъ?ЉKBИјvјљџ\К~mfE]?pЪГЦ №V€GЁ†˜иН|тTі!ЅМРъxd ИFЧЬ6‡уа*‰ФWъЩЅ5@u7PC:.n_ђХў|ЅbmЋЦ<Ўъы0дёеž2!з^SМkљВ„˜ОQ>MFlДQ_\mPЈер) ГщmћэНХл­FН*nј[Я?ыЇОчЎGР;PіЙƒ_њѕЉ-e7ы%!ѓŸfdя{ЩХ5 —ѕžџIЪpxэ‚ѕgЅ/М*6R( Љ\Ѓeи6RPHL„@!о­pЛIСuHФ<˜ Іо”Эh.+в–цщЪ ЕхХкŠbS]5xКбС œiYL=јњePЁZэ.ёСГХ .Uй-k‚У лў!TFнmиџОјю‡‰;ЗьК”W„њЯb2adT2@.-ч& ЉŠ d ЎД^FŽŸ‘Ѓ6рVvŸ“ИЉфRНШыО^} ~_B8ЉЏиКxХ‘ЬRxšPО’r˜zНСь’dДš zЮь Щ :90Ёџ FЃ Т”Т9ќc„FѓU ыъ@@~]юЅeЋЖЅU,ДЙr№ёз~4ck?e‰r‚И џЏНv ЗAŒ&6;ьКъМ]ПUgŸчpр3МhЫМќК ”yњ5ЊœЌ+LЯ­1›ѕU…E•ЯˆфŽQr•G|Я"ЪЁ/MIЩq №еш В/х˜CBbfЬŒwJfяЕ-ЇPo2kF—КрsŒЖBэAN•EйЇ­VФ…ЄЏЬЧW <Ы•…МЦˆьIHNx\ЏƒњЋС7Aю_Лцзеž>5jHG5Dt€Gћ] КUиЉWяPo9ЃЏ8}rOV‰Eа%Љƒ€ЎЛœžnА[JJ­ёIt%E —Мœ‘cСф{tђ”йыKN?˜_aї KъъађпіW€зХБƒЇЬŠиzХ‰АsЧХ кAqb~ЃЙМ•RjšgЪгюк“u?дŽDlэЈ0QVЗ€МТR€;4ЛCoЃЅЌ_zЛ.э@СсНр.ƒ&“љ„фj‘Ъ| џ3Щ‚#ОнuС@rLХ%&м}іsѓЛЙ6ЌX>rv‚ЪДsщМNCЧъvvУoГмfјyЉ•ью`кnЪ(з3b™HшђЋк0aчКcфр†J Г*†ж‚у:ž–KsЃЈdoЋo‰щ;WК:{jјОѓКМЌАА _'‘xhм*Ћr*ьzыОgBТЃКЋSѕЁmы5Ѕg‹‡VЫž›й%{ыњяЗn4˜p ‘Ъ}§™xqйњяо;‹ЫHкKІ ї§ђ}ЁРПЂ8Л$K;vоgON‰;ЗaхwЛіZДv‡ьМшЕЧ+kѓЕЅ;ЗІЧХjЪŠ•r…ЇbLRJwUmNi­йюсм аЈœ-sГ(?ЃШ/Њ[RЧЩАn =ю‹#ЯЇчйН( f<Дю‡й’W?šч+hWг5РЉ"[І‚ЁЏ Z `Ї5Y >y\ЎFФ ’ёТT”\JzЫ‰p9Ч‘Ц›ЁŒќт?e—)’ЦМіоћQœТНGг*jДC­ЩF‹§у ПxlѓŠ_П_u0/zPЂŸц Ё,ЮHйRу“шчЎКъгуoЩƒE$Ј +qъHiйцЫщ' –}y^I>X”Xjь•щкЂќтšКzšqyL§лЛЎ ˆ>˜uъшњuЫWlи–WЉˆьк'мoђkя=tЅ„oдж=}ю­щ§нNќyF_WКфћХ5ў“п|чuaхщ§ЇsŒkY~vЂѓc/Юяр-Ў(ЪШГљ<ѓц;c…'іžбжф§єнJ&nц[o>Ig8šYвБcЇф|<ЊwЃЙЦJ]жW $L­IoОъDЌI[цhi„'_]”ф*"%šъђZ†Cкъr–~Ли7ahз щН_ lj<Б55Ђ(Нџl7v џЕ*HL&гёМŠ‹м€ѓЂАEф)QиЃ и–†˜IЉљ˜”ТРЏ7Ќ™xЃ’г6мџОqs†іJJHN ‹еек ;JАQ ИЩƒ'x`Е?~њEO\їФ0Ѕ€uБ]’snХЪ5˜&jк№оювF—s :CС…mЁ-]ЏJГ‡dѓѕFэАиpЫљВгћ3Зыr‘СdЃRСM˜ŒjРЮФlА1р4у+фjО›ЦC.@ьB‡вwњмщ=т‚‚B–Б_риЈђд­›vУ<н‘`5уСsп)дKРиаЙO<м5.>0(чъhsЩ%ЎЫ;ўЧŸ' H!„ЈžbwЕ›X(Ђ(+–sГЌЯAœЖжР`Z Б ‚NЬ6­мЕГћ:$ADrИЙьд…МJЋsMдљD;љЇ§Ћ"aШ6YчбN eЃu FАўНQшці Ђ%ьj"ГRшє†ƒ#`јдњ:нa'ИЙ{–иЫЯЊ8Ѓ+ƒљ„Юциmzјn\lSvM|лm\DђМиЯ13x2OЂ€HJ ‰CŸiЉ.XПтз”jбыцх lбHТрŸЅ.Џ.>0БІК†ф‘vœОфйНv3SlШБxUzx‘5МxэcХТ†=№мУ§  o,Ъ7YэlL ирF;Є\Ё‚ЅС,т ƒЭ?ХƒUЗвв мш—4 kL(—Ш– XO”PZuЙ@ …иОž}6pјДЃЌЄј2- щ649д‹c,0™эь‚ЁWK5ЄоЈ+‡­ЊЎJЎQШ„зіŒ]АЅO$bЙYЋЯ.бAX3еœЋЎђёWV Ѕ tђЬ_>НрgЗчŸšгСKеиŒ–ИЉОзЮ‰ЭХjEEEрtш­ЉPCщ  пДXёъj\Н7N[lw‡ёИ„$Р_ЦчCађЦMZL№ Юђ/]КT\\ьыя_чІvгё‚ј˜JBдL‹Г’ ;ХЙС@ž АЪЬœЌЬ|Й“[ЋзЪEЮмAŽi›6mзІ:ЃbшЁGЮл›уйЏcёЮk~ппgЮЋЬœ—[фхэ.rџ9iС:D[џRЇККк;Р ЏvH #bВ№ LH•п­ќЧЙЋэ˜сL}yAA~О^L9H‘g›Œйщљu№k )PЎB!8ЛиG-‰+Lq#цLыЁb<ЙQ˜гA8іЪЦл`Вуь4`c- ”QПѓјG&&JИŒ@ЉvфёДe9y‰>Qaбдъ ЉЉ9*+чxъ%eФdПщіЫн Л7Лћ…wŽ–oZЛyW€ ЗŠKЇэ\wžvЛПc—LуUUXПysЇЭuсbwЯчfOдHлЙ;'6p…PkЩ2™ ,‰oVая[E†ЗF3SPnЋеq(жs§ѕЄ6tŸ(ЌЬef‹‰„UЌVуCЧ… €?ЂутƒЁЪ/І–Љятуп~ћ™Юr­ё#ІuA|<Я8 Я;‹ bкШФеF0aHПЏЗќђ‹9Я˜’Ч?жнУWЮhwЏ]ќtї„ћТџ8Иayё!Ы™lХŒ“хќЦбћKмц?S%=ћШШW—lјA›ыС5J9бщў';‡њљYиЕFcCŸy$5ћЫ• vя>ЌS(Фhl~ЁZт -GlИлiц,|<…gdd@ФЉјјxЁPиЬl‰Cпh%РfЊ:ƒ5Авlf>D‡Н6sV2vЏ•гНSuЕёшбœgЋЄR^ ŸєкSї0 КђШЩЩ7ЊЁЁЁ~>>^юБЁОŽе`Ќ*­+ЪЦ uoЗАЮuёYЎиnaфQЁRЃЗ ‡<0Є{\Аа,Jъ9Pу:ЎТАnУЛіˆRЊ=&N|Py*[Р!‚yРнЏBЋЇAuЫу;=\Ÿо•s№GN§AП‚A›ѕѕѕ]Ў›F&œО>О#ЛY-е№і:A5оџњw:РpОŒн–†рRE щћаЃUў4[Ь„XгeрhOœž%ѕуЦ™МŽЮ˜уfй~ЌЌNGP8СWљv8в_-†)8Oхз­џH%шЉШћ†:Ђ4B ЧsŒž їœЎЌЃIиВЧW†нџш„GޘmVFр3~жDлЊ-™DŸёSzХ{ЕŠˆlЄ ћИ9ГЕдЩѓYљ4зgТ# е9&ЅСЃ}eŽѓ†?іЊ_NийѕšvдLf‘ IDATуГ…"hdV‹k а ќŸ„ Ю+qЉєwp Оtљђe˜Ў 4fl0ы$Š^A8€‘•Юž^n† ъgм9=cУiжзTBL/9шЉœs6XЗЯЪ­=›rЙK˜p`пvP-[8‚6Јxр>Ÿ?`ИAЌj˜%'%XMmEЉнЈ“ЪхЕ78‘lДДO|ђќ"cШМщїЧј*}рЮnB Qˆ€*‘H *ˆPљ0eуѓ=<м­жњ={їЧDЧx{6ъRыЮОл”o90v‹^+ZQН’9а,Cќз{Пшwжm>а(4]‹^тР~#—‡[ VХQv“#АcЇpo~­Тuмс)p't ИW=` vЃр„w˜:zэП ЩЌvZoЁѕ4aw.FЅHeYёщƒ;DybЯA‘nƒ?(ƒSiЅЊЕ60Л3’{Ју ьЧSЉ@ЫЧЕ$PšK*Ў@ЄіЙЉ„ŠРФ“RШobн>ДPˆ\ФІT*е@0o//•:EЂљ|1,н97)н{G o|уyуЗрнV:h6ZB ФfEй—гыxbэЅ­‡3}FŒŽБжXEЁq‘VЖlюиљ0ћ.\Š0ftf.СO77ТТ/ћ3uўt:РgeоЫh3ь<&B€!pГеО” `љлСўлfI;qxЧк%RЕЛHхп…q0F›ЃЦЬhm„Твv^+Ј‡њ™gžЈй0WƒжДсюючЗŒџ№‘а Slт5$7ў| Ћ 0œ_ ШЌѕM…Ў ‡ўЖ*Z‚舄јщёуiŽ {ы…ƒеQcЧŽv˜­8IзщЭr!ь~СЌ†:#Э—№Н…с0ІЊ:OЈаЈe0.fь†ŠвJƒыцсЖT m)зYT2щП;Ћqб№$аT@•'­ z$LлF€РэvЦ6„Дƒ"aQ[]]V\„‘\N•—x‡Хs(>˜›[l bkпŒ [h :uК›ry‚Цu”w“(бБ…;wўз4PўWxаWh bƒ™‡ЂМќIз Q фю`a ьЕЩчiМžŽэТСЌЉ;VЄKћіЏ^Гџ"—Ѓ=rє’T§ПggЉy'w-лВНJЋш1nђЈ>ёц’ѓ?(ž6ЂŸ7XєоlZњБСqг‡Џb‚ў"nŽC€Й?m0cѕ4‡f-а;) э2д+ъ>ЈsRЅFgСHк^oВы, h ˆˆнќƒш „BрVhbу\иЩю!A;^^р_ 8жђMПo1ќОKўКеЛ#žcЋ?НљЗT‘#“ЃnмИnOь#}|~ўlYuЯQ=| 7.]—эхРЅ„K‘}еЂkŠм`Рb›ыфVAЯ!ў0Ў3е:N‘™PЌENpIY(WѕЭЁЃщкZичl)йЮрАjЯzgDB!аДБ§3+†Mю­ћёл#ы…њ§—*}gЦzбЉ&Н{иc'Œ‰+j./;š1  vWNйиЩС~|Л~эКќ*Sˆw№ФўОrЌ™§3е†w`КцВAzШ†а ыЛCРЅР9ƒ6KZДеf­ЏЇэа—qxBŠ/‚—АЬ6ы$ИЈ"nшъюAo# И‡ФЦ(XіЏ;€™kК V ЪmДO@hч`_‰ŒёєєЖцX,f№ЦЊMйєkiцЉƒФ\‚ф м5bчќЏaf\CзФц:€о\ зрt‰И3РЄœŠx\‰ЫoEЉЏЋЭKлQš~’фђ;і ŒяћРL›йFГvжЭЙГхЮВ€оBДWюБ]™i1Ёл№1У_zыЭTe№3tQŒэ…Хх写=ЏАDэоI&–zЂЄў3&їѓЅ­ДXЩБuЕ:Ћ\%sњИIЙИШ Іk`= –Э7y§ŒИe€Ї ЎЁЄ8Жc‚mˆ€ђЈI/Ѕ Ѕ*XЌ+./n:“Э9ck­ъЗœeє B ­ авФ†aќŠЯFN†Цt §x2 C\ˆЦ8H>Ї*3mн/?_№1КPд{Цc>тQƒЮюнМ—Aл™.C'ѓ щыvНˆFЦЙЉїG 4р6Ћ ‚ЖR*HЮжј—И"!WŒƒуж2.ф‡Цvб–f $В€ШX‰˜5'pНЩЦуJYєЕўREЖZ”и`ЫšмПгроИ3T h %n*/IчИŽО*hСеЈШOCZkГѓŒС]‡єя&–рїЯ›ЮљcwцЅ,‘BХZьƒn‘A~Ё+‹[gs­ЋСЈ(M,НЕ“BCйhБС+‰˜'Є\Юпі‚а`5фq=|=@џUšЫGъvЯ!Є`Б q[+(9$Т–%6ˆzзaРŒP№ЯЭZ~SVšsО^0&!NL2А fЏЕвЊШсгЇЛSVОXц&цzEwŸьЁелЙ"‘RBpDcGЫDЄkѕўFeЌ<Ž[И\.pВŠМVшў РЮи0\,ЦЅ<œКъаз!ШР AВ- fq<ЧЄ'д<НœВqZл‘;Ш)z!ацhQbЋJ V !Š•sІх`ъk Š˜ОI1юRЬЅy"ЏрБЇЗЇп›ТѕЩSj|nЌW№>т jЅ=Йи0Ечр€.??М-РОд›Н~Gм\Ь!’рR№ ШZјГ/В32œћ—НЎУЁЏЗ8tЙJКЬ]ЊZџ>ЛoЃG#аВФЭŸ=Ўˆ+djПиЦxI pУŠc6ITт4‹’`Yыкcpцr uхЭЋ—7Юд_ПР>(!OŸ>]QQˆэ/\аYS `fАJ;fї€рQЋбЬ БЅЋЋ§Uw7%ŒЬ} нD š–&ЖыЅ‡О@цюЋС! =а˜ƒfј*MД…Э_Ќv§ ЗdўЫГГГСЧ?ИŽМ§а"†\АtfНс#>›ыыЁ K д%:–@р^ф]‹p:?vх6Дr8MЦjlњ8ЎVЋССЋNЇЏZ-(њBр*P§Рd єс0РХјелш/B!аМмcbƒЬ5˜œ5ИМЫмЛ”?`9Ч_:аЛLНŽИЅнZшY„@ pя‰­ 2qГ$\єцњїfЯЂп„B m#€д#mЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ mDlmЛќє„B!аDl A—„B!аЖ@ФжЖЫI@  @Фжt‰@ ЭŽŽуЭї Nѓ%RF š­Vk6››/}”2B Йh>nCФжмe‡вG41ашѕњњњњцыšXb”B 1ьv{3еaDlсю!Z+‡C pЙ\8iІNЁЕfЩео€:L’dsф [s ŠвD4#РgЭд4Ѓа(i„@c4гр [c`Ѓ{ж@3u­;гH:„Р­"€Ќ"o)єB!€@Д ў36афBaXœУ0mЂ`m˜Q+aE!Еa›.J$|[D §АXEчхх?~МВВвd2ЕХrB2З-€и„BЁЇЇgtttHHœЗ-љ‘Д6@ћ'6ЃбИџўœœœnнКuьиu1mКОЖ!сыъъЮœ9sъдЉввв.]КШхr—ц  e‰ŠhЃДsbГйlЈ­­9sІПП?ŸЯosхФš мыбiЊpЏ…hk%ЇT*}||‚ƒƒ:”ššкЉS'‘H„@lkХˆфm“ДsbЫЭЭЭЪЪš4iАЌyX­жV[JA„гЧŒƒЁi†]d ЭaЕкЙ<.A’ИжЗ[6 ƒнj#Й\’Zілmћkь>ГараšššгЇOC=Е$TТЖ'$=B - аn‰ КcXZЛ|љ2Ќpx{{'а4 мcЭш ьЮKмaЋ*.ЈЈГ2N ўоE8ŒБОpЯоs‡ еšј2ЅJJBЦœŒwћпsœ}л™Т­НX1жњВ3чSe!§Ђ<љЖцgV (#Ї”m˜EcзA;h__ПььlPHТшJ&“нђш)„BрЮhЗФ”;~}ћBHŽУсДZ“HS}сO/љќ ЧCЅPЧ>АшƒG§|œ`ъj ўuIpЏž—Оћ6ЛCпћЧє0еTZLкь.ѓNиs`$IРŒШb€y<šfя™уьŒУjЈЎ6nj‚БcЩ1m‡_№ЩсР5уМ†щ#› ƒvиmњšЬ?-і—ѕˆё l6€u~бѕ]Mлс†ѓ`ПТ"ьќ:K‰Ўd V0іpИ~сIp›с:aavNWAf‹ХXWQ+tїs ЦУ4#4)cь…ГЊg83 в:ИѓњпŒo‚5Ј{Ѕ——(ЪЪЪ€и |рЇfќ0J!№ŸG нє)рOЧуЩф2ш\иsАНцRXЋœБY­6†0рƒї 1š0ŸЎ-ЫЫЯЯЏЎ/uЃЁїŸ8IЩ—gљьЫЪЄisЧw• љьтmЉ.ЏgKYi•мгплCEЕЕ5њzГNЂђвˆЩЂммЃе3 L#bЎ§|QŠuжCsЛ'xZыŠГs*0О2$Ь(ФjЈ/ЬЬЉcHOП`ЕАЎ<'ЋАRЌє№ѕА3(`Ьf зfЇ k+khЦ^^RJЪ”СK]Q~ЁжъP{њx(Ѕ6ЃЁЎNkАZDrЧP]TЅуЩм|=љИMЇ7†ЊzƒDЁ‘њђ НЪ;Р]!Дъы ђ -ŸŸWљ™э >_6љщБ}|І$?ЗжJyњК 0mMСB[-v…‡кT]\RcUЙљњљ*АжЗ…У91f@ѕ Œ7 ЬиРŽ ЊeZџГ“[ЈаЭщ%§?пC"šhЭ’юеDл'БЙFФАo Lб$ ю\ЛВкlVјмМšѕжєзdВZ\]U'рˆeМњњНЫОYМ§O-Љ5Ф[кє}›ђTQоdюж­ћ%g ў~šQн‚I‡нT›їѓ[?WHЩє“)ŠјоЯЭ›…хžќeсЖБЕя§Ч“Yп§ДЙМЮаБзи)у:Їœ6uhuъUПаyˆzїDeь[Ж-ч1ѓЉ'КЈє›6m?S–•›чцуЎ;šR5tц“;йБfхЪэfЙзаб#eх>Ÿvzщb!Ÿ‹g,YЖ<гЊьwџдбI>‡–~ЌˆK4Ч^Йќl5р№Љ3Іѕ эжV7]Њs‰X˜Lь< Z‚ззІ"6HRлKА‚Њом=Ekj.H–6Œx:•JЅ*pѓЉ.к'БAБC_ Аh с’ѕЋеj…Kїlљк)ТFkэкlJшуMgяиU6§›5ЊМўE*Fрц’tЃ(8Ќsч‡єVєž?Ё_ИУЦ*ѓЌ˜­5ЖтиЖcд‹яOїSr1Ю‰xЋ; бТ:`(`а€EЎыВI…4!l ,нeddTWWCU‡Ф›$e”B ™€J tШ0Ь‹‹‹ышŸ›i@жn‰ЭеЮatь‚’х4ч—ЭTlw“,‡ЂО8(К{поA”LQ~ЁІЦ'К_Ќ?Vи!œ›A’ЬТЁј\БHЃЛЫ$ЎбAK“\ОT1}њ ™­ŸкЃвB3^ЇNЩƒzЧšЮьАTxŒ˜ЈkЛє]|БbDŒXЉР$\Ю%Нбяч^ЇMъ$йъb.пнЗS”B"5ужšтѓCž QЋ}†ЉЖ§ ъ?F’рq(gpЇ!xlъ№и№`{P”ЁмЎезц]:™‘Yц`СсJхнюKюе9œЈЮ--М|юRЖ–С`=р№н=ztэчSž9t˜0yB8™щCфйA;YmЮЯЪ4H8X`АˆЯWђJБФеž1Uг…—љZ‰™„ќ{ЙљŽю%'ƒВуЋVЏГ м;1œЋ­ЌWw фR<ТМ ъд>И„уnъ‰ы]ЈУРj)))QQQ“'OVЉTwŸ,J!а€‚сиБcћіэ+-)0p №\sДоvKlаC ~F5Р.› СЛЎ аM9œ#&„q1ЩЩCЬ.ƒЄЬ#qЕ•ZА“Є(<:-Шd‡р x<ЋХ FŽ\шя1‡еFP8^a3bЊ) ЃKсЅЫYЉђpthYХяR$ŸaцGRBр@ŒF8$Х Є!IнЧŒюЮч’uљgЁѓ'y\>WрЩ—Кwю3ep7ž€kЏЬ;@"ХЁDСё}оyХcеЏ W-_всЃ9f;™VyАЖИ`>уTBКъс]Š е,ЁЮž= Л #_Јчljmм~—љlУЏГцЧ`–uO6чДrи ЂzxxŒ9,„з­[л`’““›CціLl џ1  Ѕq™ЂЗСб л?Ь!Й`ОaЊ8Б}нЪz “z{yX7.\№Ѓg}Ъ9­LџIТЦИPЂsEiћvœя<.X­‚E`<ЦpnЧЦ5jћ1R<9д—_žйьŠЋpїˆџўыЗD”рФyzФыбŠњтМќу;їet sџsэO?,gJNдЛwъп5.їŠK6eЧј‡Ц†'a>й§ѓ cЭй?5]†id4FeR4иЋˆім#ЛзлkƒR3r‚zu•TЄ5МвЂŒМк’єМЪp;лй…%ˆЕ„›ЙXuIF^^Ёіbmd2fЄqš"и 4“ fЄЦз/4ŒsсЬ!oоЫЯУS"W шЃ‡i:G ;”zіЈ†яющх'‚ўТ:eТa+Щ:sђB.O ёQ0фr9`7йЭуnв„šДdр6˜Д h#–ЛIгѕ.Lд aЎ щCЪ№ян'лъSРaC'Юи-Nг\АЪхRкfЕГжЗMl†ƒт"Џ%ЮЁx €Ё$ЛrzГOA1› FС№ѓПP*З[m Q€о"2ВCпОЕлЖm tssƒ›З›ЮП?OОёЦџўФMuEђГCpЕ ИI”-7§ш­<г50јWЋе Ј’cч=­ђM#Iа5e—.žЩЃИ я9lˆЛTЗїAЦ3"<0Ж_П(вPХ ˆŽ цлЋЇь—†&Чy~ЯfЊ9АnЗ–ЌO=Wиkмь :FƒЧtы KМ=”y{зяНP=aЮдБОИјдЩЬllфєб*Gѕк[ы0љмЇ_J pїSиБѕьЅ|пнюыкQbM]љћAНЊлL‰аP:Гй#0СWЩ‡m6“щфж]цъгчГ5сїЭ™>б0ЅŸ9T`АE†ЊэЏŽЁ^RЉ2Мc˜˜ЧЉЏЪM;›Ї№‰”pшИ‰”ыш)'ь6‡{@”ЗШa2“ћv зHNйєд9;OоЙ[.^ПџtЎ,ЂЫ юсe'іn:žІuˆbуЃ”Ešф#!ŠвЌ\З9П–пЕяЄўн‚Й@’­ЌdР\ѓ3 h` +aPЁРюњк Ри ž‡* јя-†Zžž­,&&ЦхІ‹ЙbЇЏЖуЖЮ~ІСF‚CвьапNТи•cККєТ›гП›њу‡” (dяТV0›сђœіŒнle7x“§ Д#f XŸу!Ј->ьЋищo™Ьfј8 NaЌjЗša\ уVшma?›нfУIжѓ(Xj+J>џп‡БГg щŠD>[с 1зў5ŒрPk~O$„Еб І|№k$H`vи§/c`%HУи˜}аb…§tАŽ#иќeЖ1lЯ 0H–\ьБƒTрu˜Бfє ЄхР&Ž&˜нuён0hЦА}эФ‰`ы,р6€њЇk/Р%ш@ щ75n„‡!ЕДД4ЙL НМњ˜Gс <цгчЧ/_QˆѓŽќ2хйЅЃ_§ђЩСбB!ъ&mƒ* N(pвуќ—БX-Дƒрі› hЛ *#lи„І;6й]žv;l_a'g<Št8vNћa.X’ЖzиЬ/ЯќрѕйнХ„~йыг^~ѓэwбоRДB№Zжlu…%V9AG už‚В4f­Zўев^'fw PІ M€УjУŠћ@Aб‚с`ms‰ћ:Ё6Пѓƒk•ю^ž@хVІ0™Ь'Ož<уЦsWЃe“зnU‘€cѓЮ< ЗnbУ)ž€т]WІаќИ]УЯЎq>А—€УНњNёeQНbdBъšsgVEУЛкзƒС†рК"Ц‰kо2!ёПЅOBЁшjВ‡Ыџы#,л§ѕE.ж-вK#‰ЎxЌ‡щ_xнWРЄХ™А&ХуџЭ`ёъdzз#—Эt.зЫIR\P1К._pэлЦuјOа*-!Џ}ншзrrr`Смп@…„_ЎgЕыМЅSxfl {+ф@rа;qТдАuзэ[ЪкЭ"РY€ХІ+Iнv*g†w4vvыv­MЯXэкђмƒ'RJѕŽјЮ‚4ІЊьZ+Qrљ\ЧЃ{bДŒ0]Ѓ•Pэ@{ j ›ЭT_~jїоВё J[оŸ;Я9Tё@“f]љщ}ћ‹qMrRœЛˆЈЉ*3єYY9<Пш ‘%5-УЋC\\ ЬЮЃ,њќ?Жфк0їЮнЂ5r~й…‡ЯH§bЛХтІвмbƒЙЎWћЋш”}ЧДBUЗn]5ъПА,.ЌАёŠЕуe|}}СЌЊ1ИQНYИНпџжноЋ­ўihэРџаР%ј}HLL ƒ)HЋќж$ЄrПщЯЬКžЂn§х;{R$SMxl&эой|,ў( IDATыџЗ@9цјчЮƒ“€€??ПЛЌ{РdаРTvС\ Rƒ;WЕ—pкОЁ%hЦ"E L;~?гCЉк”%NN 2:Е%y…•5е…—і_Ьі№TЫЁПј#?!1:џ2н“/і цUдkKvnо;хЭз…‡з-=|18*({ыnUђШYуb|љU–2Џм–W;іо]e|›Х†kBЃHўЅ3љ•О•;*;Ъa‚UПуг…g( Їnћхђ~ћv>ЖќУэ…‚ёБ/W(м#ƒМK–ЏЭљПWЧ8АтЉiѕДхщ5GЮN|ИWщћr|EЊМД :lJїЬМW–$ѕœ5ЛкmЪд‰О2PаУ:Фп М^Aг€j UєЯ0Jc—vСЂ sлn‰ 0rq †‘А8Ж$Адzф&Ќ@(ЉF€V ‚q3}]г7њ№mн„”]иeœттЖлJЁm> л9`Qг1КЎpЩЧпcуžяMфщљМ’cЋ–žЕЦЛ х2v &Ftъш­)”qbЊ>§јЦЇе<`ЭЗ—0вИ•BЁvѓ(Ќр2C9L’ ќКп?)(Y%Р:Л Уxпћ‚™п6|RC‡Овл'=/›0K8X7пЗыА š8їЂ\ящЎ і•‘]Ун4љ|~1‡Ф‘*:*>ШУЭъDёŽ—Z§$n2ЉGAccтН(ЊT–д-м‹K’ƒцНVЕєo^~чСg^эзе“-кП–_лfAнLj6‹NnƒўzcЈРpЧЭоЛНпл3Б€€JXl'..лИs{ ЁЇЗ‰T<˜TAХуŽ&œQA/|C]фКЮџ3ФFr`їУЈУ"=<СšNљŒЦЇВl‡ьGзь2GMIŽЕ+LCиъ)aC,‘ајЩЮŸо™ы№еЉCс2.%sфN>}>ађч†хT—9R•WЌЃђ‹п/\љ€СўИ Їky“У­ќ–1I-b`ЛЅђL I™Gд˜I$Ич6WТ&А]В`сtШібьЖ02VhkпXўќТŠіf‹њ‰tƒЎњBЁ;0А9Ё•‘У^z5ќЭgп Я,ЫQ&'б Xфbn13Я/ШЗx§кЇђrљквмїЮ{hLеЊuoН•ІЦф‘.s Ÿ>iрТ_оѕ'hиcЏLщЏѓ€Ё(ЪЁ˜К<2їiUз^ъњTЬbц‰НfЬzрыoо™Ж„вєњкџЗwFЁmUaO—ЕK;­Д›ЖЬlЃ3ДЕ…ЎЪт&њф“ ‚ ј >љА=њ "ш“Ђј&Оћ^ЈRUьXGЩ V]&c]KKгЮЌKвeЌџ›4‰Ъj{’“{ѓЫУ–^nЮ§ОпЙїўя§ЮwОѓкˆO…T’'Ьч6TУ@ЕВ­ї›ѕжчЛ{слOојёѓT*ќъЙž9™јъгп}Г)а§ж{яДј6ќ[A&Ќ~ѓіч——юфЯ k дио(ЙрзŠ:ъЃˆК>J€аwEщŸРџЪ<о•КMї ;лБАб,_Јкsчщў2RG”HІ8чрр ‚6чбпћХ^2WІЎю?бтз˜ŒАyљце‘ŽћK“SГљ}эmeFzЛїoЌљ{ž:м~ызKЙЎуўЬХЩKЗšщjнЬљ9š^™ПОšŽ7Кв2tі—BЙещ S7nч:ћž‰ѕ Г)›Z˜Н‘Švцв™рpўЮЪвќтc'њCїж/џєЫЕдFћёЁX_їzђњVлбюƒСХ™iџ‘ЁЎPfњЗлНЧКвЩ…ФяЌ§•jn{ђЙ3'•юИ|uђтх›Y_ћp,жг–‰џЙљьг=џн+?ќ<ЛМъxтЬщSЖ*'гћY|]“ž)Љj||\'ПRжЫ#аІв§NиМтрЁЋќ_aSшFТІбтЭбЎFЇnљ)S\™eѓœЂUŠ:“Ш”vЁэNІОØЎГвŸ&mn*уDџ+rЛНХз4ўЫЯОў~m-ЛАЙяьЧ_МыUЄ&Дi[aТвHГЁЊмTўд,kН.ыЮЮš Ї˜paЁСТЁ*ЧrцbЖ;o%NнgЊ› –1ZїP’Љ—lIДОwLw&(њйO'хЎsц­ы4гВђЪ(?œ™6я‡"+,љїа ІФiЕšЙЙ9%§Ћ*ТЮпню§?UMОH ЪS( Pёm;A"Wи&-Љ$BwD_xхѕЮTњоУ‡"Ї‡#*VЇ}yќЏЊH‘JЂц4ЂДRЋšCYойQеТЇ|ЌЂ\iЛф­М›г€Т›• •ˆcsQїŠ­4вПz2›˜˜PКПВ O †Gи Ѕ9T›€j”D" лшшh4ж ЂкѕFћсЧћ_ьŒ*р'Ѕ)Ќ я Змф…bщZ˜"ыБLѕN5­Of››Ю l…€h\MS$i‰DBхЕДˆ;еИ;x’v ЃэvКWм?з№АN`уѓВЫ.!le|€k( ЉrzuK&“*Џ\\ХТ5жchЃPдQ'­ЫŠ5GЊ„,ЂEиѕУo—аx{8V$GCnХфi—;„љо' %SМС™њWхd„Эћ'z˜€nх{С5wД7\+ХЋю ТVuФЕ!PГЛFmмс(и5эtе]џžB€ъŠТVWн1€ АW&…M‘‚!{э~п`ИdЌУqЗŒБi{ff†ЋДЦ1МE@Га”ЛЯЕу­^Х›Ь›ЊБiqътЪї6Нсиp-ѕѕu;w­љ:"` ryƒ)€ а№LŽБ5Р@0Ha3“І @Р>„Э~` $€А„IS€ `ŸТfПА€ @и ТЄ)@АOaГпX@ laв и'€Айя,€ ƒ6ƒ0i €ь@иьї@€€A›A˜4@і lіћ @Р „Э Lš‚ ћ6ћ}€€ `Тf&MA€€}›§>Р@0Ha3“І @Р>П34—Ё^™ЈIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/pix-failover-group-1.png0000644000175000017500000015234011733011756024727 0ustar sylvestresylvestre‰PNG  IHDR&Т}„ ћРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь}€]еЙюw|ЮИЛK2“L’‰ƒ$AŠ+J‘азлоЪЋ=ЈнлТ­RzЁBKЁ”($Фнg’qwїуч}џоГ3“ƒL„vЏфЬйgяЅп’џ_ПЌmјС~рПѕж[сp8`4ЁK…€955“&MТрр Ю˜\Њ^аЫеаааааP0  ЛЛ[aL ƒ‹Ž€Ž€Ž€Ž€Ž€Ž€ŽР%CР<Вd1‰†~­# "рїћ•‹‹=?F–;ђњRїЫхT—Б№Cэ*.ФKmї9цЭŠШЈ1saлu"†ЇјЅДхлЭVKŒNЛOQ—З.пq8Ђ’њхЧBРьѓљрѓђУo­Ѓ?VNz"K…РЈ7Т ЖW~™#кГQ^|OQe.’КŠ SЎЅFў№rЎ^№pŠњŒ,SˆŽўQЋ Ы“V)љŽ,hшZ]—FFЅ~ йWbŒ$‚b'чїy•ќN‘еЧПЅ”)uОQЩq/E‘9§ŒxЉДK[[Gжude>дЦ‘y=кэ:[}Ž/m‘v)m:БнЮcaN˜ДѕУqŽч|оЪxЭqxо5в3-ЦФЫ‰ьѕz•4Zыљш\ќ0š,0‘wpЛ=Ч‹Ђрѓ‘ hq”ХSІ,lМєё†\Ъ"Ќ>#яЛHЬ0K! F“\”ђД…—g"д”\˜†FЪS ”/Й‹%)”Ыh>БўлbБ’p^’b[Ьf8ћсђ6ЋEЩOk—RofЌvІ;ЙMZйZ|ЉПЉƒR­гжЧЯіБРЁ љШGЄзу†Чg€Эf&0Œё‡ЪТTЪ‘K?™;)љфx&Г6Г‘хЙи^ЋсrГХ#Бp1eі…еЂ {§>к’€љИм0OЃДыxљjžъясўзЪPП%ОдqЈ|ўањIi7ћмФ<‰ћХУѕrИžвVŽ ЅўЌЃA‰KI№2јріx`Жк`fzЗЫЅŒЗ‘eKNЖQ*Єz(щхsbЛ<ААя™ƒќ‘vœXgЅ}вйdЊ‘ШТAв[mVцх‡‹xI“ЅЌSсe0š`f–~ƒЪœЌŸє›Х%йиLŒЫyсѓ“‰–ўђxйw#тЈБц'ж[ЉфаŸс>’–KМaцF‹'йHџњ8eˆZ­ъXNЋЦ<1­Š™ шpпjyъп—ІХ‹?>aТ.—R3e2АчѕoƒЫ} Шb(LBw} ŠЋЛAЂЩR-8 ‰—їјт(еУuЩШ…Ь ЎŸ ІФLТЏьВy­хicYл >ЖЏzƒСiШH%AњZjpЄДб1QLk:NTD‚`"‘ВqЁ”EбЧђŒ\иeхЊ­rn4IƒRуwе—Ѓˆѕ‹ Їє’‹9+W{l?VОЛ‡B[ПЖС:lк[1Й0‘ ёВэІЁz Ё†E%VТЄЩЬАНЌ iЋ‡8VТфHu„аШ3ЈlJ„ hѕщЌ+УБкФF‡ЋИKI+ИйЌ&Tэ}j\ШЩNІиФ#tPСAъ.DZpj'}РЮPК0V[€BdUœHшYaі:j ёЮъ №†&"6дІдG#Љ™”ЏЖф0jњ€˜А …Ј ДUbн{qшрAдѕњЃєезЕЏП‹№Ќqˆ Pж4‰ЗEњ›д#ŒЋZжOѓ@4ђ`"§/ѕR)ћдЧ:^,pє4`н›ЏcћБZФ$І 4РЄ0J’ОЋЖяМГ ˆJ@txм}mиМъ Ќп[‰ЈјDD… Жhо]Е‰‰ В*уRi# 1ГЧ* їЃлcCDЈ]щ+)[2ЋеЃЃkо\дD№Й[OТї ЦjЋcоЏŒ Ч-;…}f“9 }D"/умФ{&ƒ GїlСšхHJJ„нJF‚эPч€0œћL!иЙ{[АўниДЏq)ЩlЗ™эі*цђ§xчН]ˆIfНl№ t`уš•иАѓ(ТRид—ьХЛяя†=6vvё7‘!Uњ_А”ЕБ }$cгFFNъ ŒЪЦ€§Щ6™9ОkŠЗb{ЭЦЩ„QaRИЙfўVЮ™T-­Д[$]2Ѕm2fЅЏ•ўеiнeIыMW_}ЕҘИнТ9ГЋфПоY:—ѕEE%|.ЊћоЕЦdфЅD(‹MkљќъЉWBЂŒЦŠRдДє $<Є0(+)FG?ЩЗГЯўё8lёHˆ–Џ,а}-8Zt }^3ТI(ŠvlAЇЯя@'ќі0˜ЈnюCrj"z[kQR^ “=С\ДлЋQT\Эzxq№§зАnWR2’съnЦб’*Ihь–!ѕ)‰ŠХƒ[VЁБШM‰f шЋ=€'~ѓ"fоt;ІŒIbl№ѕ6ЂАо‡ќь(ДЕw# РŠŽцјЭ6ТV•С` @cЩќю•эHLNAdPQ\LЦЦ‹№А@єДЕ ОЁ нlЛЩл‡тЃ%p1я {РqDъs`ѓЛh0%(ѕqsG-ФЌЏхУiрuS1š‚š„ЖŽиmДЖДТ€оЖz—VСˆЃ[VтХеEШ“ŠГЅ…GбчГ иnEgk3ъъс Џ`5Й№ЮK+`ؘ€q‰с*af_ШЮлтР†wп€%)Щ‘Ф•ŒLљVМИ­з]{вcь(оі6^л^ŽФшT<cp(Кhаo E€бЊ2жЗлАА8Клбиа€іо^–уAW{ ЊЋысЗБџ,hЉ)GY}"ТƒQИmўДІcвуБwЭыш ЫЧФШ.ЌмлŒ yY0ћмJн}иРОі$LТісЮЯЃв’щРЋk‹1Й юЎzЌ§Ч‹Hœ|%Ѓ‚U)л(ФвчъЦ;+V#:w*bƒ(yЁ4Цl№ЂЉКХUŒтFёžУH?Ўо.xйgоўtx`5“Љ)>†ц'-.ЌјУoQоkERj<њЩ@—T6Т“{-Mhjj‚10-UјЧ‹`ъ•ГХqR]UOq\0ЌрИ8†ЗQd,ЖОѕк#Їa\h'жьЈХЄ 9 a—Й2ил†W_X…˜‰г16>лVџeОLЬLѕсэŽbТФ`єў8ѕрjF" g+Жю.ЦД93bVњЮ†"<ђрклСгroНН•;жншЕФ Џxž}ы &G€Ћxцwˆ?cIPLT ЙЛъАќ…ча‚яО‡рDJ(:aMa\MEиYьDfŒЫzЩјŸЏ ЖЉGъћ‘4ˆŸћ3\AЩˆ 6ЃтрћиReТЄœ(Мњ‹'аžЬфXrйХRMI‡fлЖУ(ИbТ dB иНn5ŒYѓqѓТIм§">!=”Њд!-А oЎ-ФФ iX§їз`с.}чЫПРСОXŒЯNBgхN|уЅУИуšЩЈ/к‚UлŽсШŽ]А%e rэѓјŸ U˜ž‹эЏ=…ТОHŒЩL"cBЦGЉ^29лЖaЪЌ™Г {EЩ@gž§гѓш2„"&* Цq›Ѓaѓ–cхЁnLJЕуЭпA\R(V<ћ$кƒВ“…Њƒ№дњvмМ(LкJь=R§;і!69 {—џ^=тЦЄБ™HNO‡йн‡С€hd c"’  #wЦ}dќvыУь+ІТцЇ„ŒЩ ћhпс2E Š„Ќ…Ьи3;ZqЭфБh,нŒеЈкЕЎ№ xjwуэї |Я6XbвсmиŒ+ПЕŸ"ЖeлVсoЋїТй~ ˆГvтхЗVЃОцЊњЈ6щ(ЦїЗЕтг“уБŸЬьЄљŸТ˜h;–џ}ІЮЮG…T.ъТcЂ@І Чƒ1ёA”nlAюМыP‚]/Џ@ъЌYШL‰…АІЈ,Ф“ Vк(lЧ@wуЕZ0їŠq№:\TћQyh3žљыzD%Х) os];2r“ёўъ7˜6Žcяc–Ž=јеK;0Ё`<Т}X§єWбŸВqЖЌ\ў.šЊ QвbBvt?ўпЗƒ7:™YYH‰&уR‡иœqˆdКCћ aŽAсњхиqИ ‡vюCd|<ЪЗюEСе7b\‚›ЗoEЦЄ+l№РХщ“?Ч‚).Ё>lo%ЦЬП ™axgѓNЄч ;-ю2­1)ШŒ AЭБ#ш№‡ТаА?љеK”іИ№впп‚›RœЭ+7# _ёІиSZ={#)=ыўњkьmvЃlћ[и]б…–Ѓла`GrД/<ћBCНxwнVЄeЅсРЫБПВлїEњи1ињЇсЅR эXїТoPoNFыd'c"вЅSЏ-њš{ЉqQ_йAК‰Т—щ> PС­*wшVДVзЁЧK11™ к(Д#82їпw'fNЬРІп@…+Wg…Р@uetц8Œ-к€цЮNЄdFcњЕї`юŒиNx˜oCE Ъ}љјЏeЗс˜§il)<„8Ф`й-зafB7žљЭ;hщš@‚тGwтЛіЖbщmгСЭіnпАЌЅјьmKрu;аЖ; Ÿ7y\0ыfOEYw#КЙЅШоOF@DЬm шВАў”ЬИNX(MрF~ц/j(™—ВГWvw2O)E dТЌˆщ)Ы7Y1vњ\Tж3o7Т“в№љЯф ?-~х x“nBjАH{сВ&сKw/Х”м`8gЂЁВ‹’'bB(>ЇъТЬнЗдЇ; с!v8ƒ0йQypМqyИїо[ш Aфo“H4ќ юЂО ShД†`ќŒйигдŒwЂтЦт‹З%“‘3уЉW6aвВЉ ш†з9W@>Оpл2d%)э–vŠИ^Œ,…I эZЪ—@тl€sЖ$(‚‹) R PŠцƒ‘œœˆЯо8ЙY иыБуЮ{ю€Ї№”RJБчш и2iЃИпI[ ?žњцч0›ЛљЗ) [zѓнИ"ОoБ‹їЂБ˜96Ц"Cгё­ыR163kWѕ‘ˆБ?hгЂєы)§чр˜ђxŒ№№лL†SЌPМb(-qйЅџиoЂVpQB5‘ЈфОX:˜,^TЋDxтxи($om!Ц‡vЏBС_СЭsЧa љ(v:ŠњЮШі‹*ClDЏ‘4†вŠj4Дv#;!ЙїaмUSahм‚ЗŠмјЪЉpаЮe€hNYx –нАˆхxстXѕŽиЭx§f\1яJ2Nuјэ›Л0ўк%ˆшЁ$‡e ѓ,эБШtbZ#ъK—Sд!Д5тГб“I›ЩЌШИ–ЖЩЗЈУd,KлE}цvК:n ЧŒ Ч6`цт[qы’lД6 —’щГП‰Цšjl_ГЩKoDH@еqDeугwожЭ&д…]™i]X}Д§ƒ,ИcюZ6!{;vюGѓО§Hœ§)J"ДЫ„/|Кю&LHєЃ™’CmшщuPšHf\*Ќ‡ЫЃtŽ $љж?:Ÿˆ1Р…ЮCЦФрuЂЂї„ЬTOŠБцю˜ЯКЙSЌЊkЃк?fв'ЯENz іЬž=O§ёyTtвЃЛe5T)peњрˆHvcџ‘Bь=д„фиD Ћ†ъ™b.Єˆ;$– І… Іaмa&&Y’˜‡ЩЙИ‹Їкhv(Ђј˜ЛФ еХЈmяCц”йsьУжьƒл?dУР…ЛБќт’SLІРХyш$с7%ћз§іQбX…УGJ(ŠvЂЗŸ2p††Ц ьйЕ Ы7СХzGeMDNx žZБ §О ДF}{?’г&Уъ1)тњŒј`tѕі‰Љ њИ0ЧdMFvP~єЧЕ Н'бхю‘Кї†Вcˆg}‚Lм“№ І)™шЎ-Уо]PгиŒA˜A‘SэTE5Тž›ёюжV!uќ „ДюЅ g? JŠ бжуХЄЩЩ0лC0uў|к#XайCе1Љœ0“T дU•ЁВЂ ]}§ У#ž‚^ЗхЧъ‘Фњ˜ШTx†ж(ЗГŸj6Ѕ7с$vd6|(-ЅDЉЉ юAкŒ9шыщР 7iЩ $R&фЮšд„pєwіРDzфaоН$\&›‰ O?К BLjыdFJж$LЯI„‘B­т#‡бмхEfX8Šі *`?вЎ ƒЃkWn@ПлGэ`ы_ŠrжПГзБYС(=r…ХGсЂz&œ*ОЊ#ЊKŠPYз€Ю>Ї‚З‡јљ;Pйа‰ьŒXq2 ЄфvRBj>UIлqˆj•ЦЖnbдGO MO'Žо5ЋзЂCњ sgOФoОџ,Ъ›zтР‘2Њ­‘(ˆє :Л“'!cкЗƒ’–сёИаооŒВУEЈklT˜–Ъв2tК0eB<е’!(Иr.ттЂŸfУСЃE”P•Т3С§ЕXћоt3ЏЊ'ЋЪJQUQ‰^Џ‰q3А ї!ЃшкпАœšrЦЉЌ!Vn2šЕЈnъRьTммDxШќ :IШфtvv1Fц„$2њQ˜1s"-єv:иgdЎeќћй_Ншwpќ‘;pр(JŽBI} ЦфЄ!†Rƒ5 fOCЄе‡ЎA'Ua~2#NŽЭ+ы(ЅЊsь9џ>ынП!m6-\И№ёёуЧыЦЏм]jё•^ў9і'ЊЂ›wірƒѕЛ‘=… N Qй‘ †‹ qб^дД“ N'a№Дс№Б:„FF*КўЂвV\uеJqwнэ8@†i,Нт™?Ѓ)AОTwaцС]5ГP˜qJLi›d'‘ђˆG…ZyЖƒ…J§EњЁŠнх\YxХ[‰žЪ}С‡iЄЌИRЖ ƒm8(xžTЉ”ИГJyВУTнTI@Y€ˆшE%!nJXLŠч„4SФўtKe9BŒХгBдRž_ХэXъТJЭNSОH ­Ž’ŸTKЫGЉ‹vsˆ™9;-ОV'-?э›9/mјžTTmЇRW!hC в 91ЎZ/Ÿš­ќWЎ%œ*ЎR–0j%Юp…Б %ч0єXЩGўœœПšЗДK—ЅўйчCЭв%ёдќHё%1Ÿ)щјKЩwD\ЙR7ѓЮpЎѓЪDkїШДj?GЫI‹{<ПгдсјsЅЦjЭNN;2ŽvО‹”3|_iВв.ђ5glŸV?§ћв!`іQ?ЋщйДСuщЊЃ—Ќ#№б№ЩЮч4ЋЈ,JZy§с{Œ7U}<”vd:1~4˜@)ёК­ЩйгŸышшшшшœ ž<єё‚03R†DЄ#b(+†Џzааааааа->2cЂЌЋn4$єoбBрc3&ЃU= 1баПuttttt.9:crЩЛ@Џ€Ž€Ž€Ž€Ž€Ž€Ž€†€nНЊ!1 пђт(yГЅіŠ(кŸwcc кЋНЯ;C=Ы19яЮ‘ЃљХKЩЧѓ\Мќ–k 3Тс7Ÿ~|ˆХѓI^ Їыœ№–ЬѓЎЖžŽ€Ž€Ž€Ž€ŽРeˆ€™orзУy! Œˆ—Ь‰ƒЇрі2'7:ЩHfЄЅfУщ4ёоGcЋx=‰ДФсp ..‘‘‘ЬЫЩ|:ƒr^§Ѕ'жаааИœ0‚X=Њ є№ё0›§pЙqфh3\.^}c & ХWП’EЦ‚lЩGчKІDj$Ь‰0#rвюGЂБА] IDAT}бтЧo‘žRG@G@G@G@Gрв `6e’jњ.Mсџ*ЅŠ*ЧКЛкс TЃЕЅ“CIЪЧmуЩчФh Šfsђqѓегщшшшш\ЮP/p9WяьuB}щ>Ц!‰†дС‡Књz”••cук#Д1‘7..И'3+gGGЁ# # # # #№ЩBру[f^&эєx=ŠЭYƒ‹\#a:xќц,E­\хЧEњ#ЬО8^$АѕbtNBРKiЉttFГЗŒлў9Ѓ—сХЮЩh’&} БсqБ‡РФsDDХу#3тђ8 №бХхs’AqQКт"Oц&Ут†[е1ќч3№c”— ?ђmЂu0Я'ё›ш,оП&2<ђЭГKЌ3r"ЂmВЃnЇѓ’0ннн№x<—Єь‹нпzy:—В‰ŠŠRЊ$ ЪЙnt чхд‹z].6g›'fšH|ЂƒЈR!( VГUYŒdBœ^?""SŠЖюFДwзё9ЕW>2cd* bт ™J@DуЉ™F"SB†„L‰0'_љ-щШ”јЧ м#У"Ь‹ФНШA:зэv+gЄЄЄарімЦ‹\UН8)„Б0s-immUжQ+Ÿыц@ц­Фз™“Љ!Ё7цё/'™ŸiќЂmL“…\“№ pЊrьJƒН7Œ–LI›†Ћ СЂ+*[[Ѓp v/‘ІёyЂо!CЂ0%dQдƒ]дoХ†•— ˆќЁќ„ќ\+GаkIЄB9HН‚‚‚`Зл!’}СЛШ їo‡€,Ќ2яф#зZy­н;љ[тШЁ‰§§§Ъ\еђR”“#ŸчяUSs’ѕъ<ѓ<}r edЄQkсе–ѕі_?œ Ч‹бъS•+€‹ЧЉZўљс?œПl CCCyRКE™CЇjн'о+GY (ъѕи“Иyа™—ЇЎ.ЩžŽБ]е@еa ЛvrhЫЦ 1cцcљЁА™ ŠъЦ#Ь е7nЗ}ДCёјЈъІХР$юŠB‡9;y ŽjБ"6Ž—ЫЅ|„1бƒŽ€ŽР…E@АьњDbЉЌAчPœЄ‘љ)‡%jLЬлsMEœEнHiLТ…+gИXЭоm4эnќФYЈуХЈџpK.э•Œ“ГI.D Еэ…x7›Œy‘2Ъœ‘УBm6лiЅŒŸxЦDы7Ѕ$>2ƒn'Ц$gbь]vЫVСяк‹р3їТth?ІNџ96ЇЁЙЗˆ‹„ь…ќSЅžA.Ёю •9Ћ,6УЙ/!–Mы(–зfP|юх&k8ћQП2qэщ%г%Ь–МFC˜m-њјm1РbЕВВyЄJ}ф<ъ-И<2”5МЅЅАYmЧ5Єё*ŽТѓћtдррР0™MhooЇнЄ!!!ŠFAњO+ѓМС*ЃГГѓЌ@ђ“ЁžcW™ЅЙ‘‰@ё;4^%ѓа]AUЦˆ<јlNЛЪ19*/TB„ЭJF†R24nJJDНNєl~єЖЈ,‹аxёшс_~†Њ}”Уг{”SiӘшm!ИDХыХъќ[ pОѓLˆwTt”BР/`ŠёПŸ„ЦФїlyИCЕ\АЂДŒm|йЈЈЉbccЕ[ч§нйкЬ5<б1ttј7 ƒЪиЉТХ ТLŠY@xxј+Ж‹ŒЩй(ф'Ÿ1‚ЯЭCЮм^œ—Њn`у{Њ`ЩЪO 7?62+t‘іј0Вгх­РF2$šРCDrBХ-"PU’BХŽт‚lє[Йу ч‹Rq95ŸЋ1GіЃ01z8ћV№:лШ<9Бў[Gр"# ;EmЬŽvбВ+–—rК=^8ћ№ўкЭшьw & љ №к"‘››Љис3*м.7L”PРO/C/ЅНЂЖіРL=НkŸŸљ&‘šR k”ьІk‹7cc ѓ’№іК"мqзЕ1а‘:щQлi#sZ$@b?ЃЊ•EХхEmљ~TєEсЊ)9єz‹‘0ы+k'ы!^.Šі-<ъAкцpr§f>"}13n]с{јщ3ятцЛяЧ’Y<–AйDвƒ’I3ёg9e[0Qˆ8Ÿ;Щєїю~Д;ќѓSp4QнСўц„В.іk>Xћ>ьЩљ˜1i,мUXЕљ&MП йIсЪЛJЧ’Œ %ђ[§єUЋ˜-PZfуF\‰GЌ$ž™ћ)‰rђЗlК-f БS=K],_^H[YИ7б.3<зпt=bьмˆs?ѓ31#Kq(R9ЉЋ…уRцŒаJv$%vЄ tBБRђЃФeН†L4ЯˆШП c"—4кхРЁ–*dЇ_уі_Сu !№pт†Yб…ME(|ŠпBІƒ.Рf‚ч…птŸ#џdъвйсО8Ь М ёIь@'Їч Ÿ‹šЇЗПхЕЅ№LЂT&Eщл3‚§яўP.=ш|вPZ‘rЕФG[6W_ўКv7Оіш#ШŠЖЃЗЉнƒ. іuЁЙЎ=^вв’а]Vˆ.o0вУбг5€иФ(4UеSЪГЇН./њ:ла5рGЮи\ЎQƒhуAд.ч šкхHБЇ†@ШішВ&ЧзLЅM"І„ЦтG}Х.ЌjЮУФДtwД НЃ‰™9pзlЧГЏoУЭŸ§ ’BQV|=ХИlЖГЙэн0PвНе*ЄŸ…БЉ‘8Мw'z=|k{F&ЂТьhЋЋ@Yu"уг‘™Œ#GР‹Ќєxю/ћKњЬdt`§ѓЗсйипЁњЗcбtјмvЫчАѕP-l§еЈlDrZЂCб^WNšдДьL4ЎЧѓ[{ёШ}ЫтХЁ}•#ViqЁhЎ­GGw?ЬіHdЄDБ,йtЋъ>ЙІбзгŒзŸњ1&?ќ4ЦE™а_/ќ§ШЛс!ЬЮŽF]U%| №иœt”ь|/ьітбЛЏA НTУЃalAПз†Јp;JŽB—Я†œœ2ZЂ…8EуGмњШ”B&щхм””8ШэYП=•‡Х 3улпьмmаm ‹Аэ˜лі 3-Žœ=Я1!џF~O9ЫDŸ™œ&Я4сщђшuж!Ѓ?)aщˆЇЮдCЮоGѕŸœМ(љ\}0tPL} '•œ&ЙS=œ7НЪq§Ї~ЎпеИqk•9?ЃЙі‰4FФц"]p{ˆ 6 ДЄ‘іБptеЁОпј м”џe|oЭб]{ [ЖІб>—&кУ-ЛižјќCXіУ?ТVЛ‘ушТЎ5Џawѕ-X:б‹o@‘ЪXјt1:tQb"DчB!Іт2-Фд-R !А†@$…™pdћ›xђхB\[пСё˜™уУъеяaСЭŸAQнFМБЗ^ОЕщц{`Љк€џ~Б=ў zЛh7huЁЏЇ­mѕиМ~=Ќ“юТГƒёЬo~‰шЩ7cVp0пOЖ[ŽtРежŠ…ї|ѓЦХQ"%R› бв ›ЇрЈbI-€аžЛ•1эaФm)BeХ1TWуЦ;ОFцk­]­8Жw^мžян5џоЃ0Ю{Щщ)шiЎРяїірОjБъНе(э1ЃЅѕ}<јЅАџЯџзћвёэћюRшš0’BйeLŠЄE˜Y7ѓ*Ќјчˆф>ФXZАэѕп"dЦmш‹7ЃЉЉ{6ЌDщв‡пе‚пяlЧ§Ÿš€ї6ЎЧЌe_€ёрКs13Г_§й[јъЃ_TЄ+ъ<:sЧœ3crЖIЉ‰=%žj,sa;яфм]ч™=NN:ю@;№—ob~жtLIПaF4;Mxg])ж—lA\D$њКEТЂкЅ К1р Шkђ <О!И‹ЬŠЃэоVєG  пM?‡ Іž6˜›jс CЋ= ‡J*б6Ійў`}trЕўэЫxIIWW6nмЈF%“N:—;Ђvќ„„L›6Ma"FsmгˆТID}\‡сv:р%ArКpћ3?ХMWрЕ_~•žL\“nAXђXи[Ъ№кKk5m6ія^Ы­Unœ‡ž†J„'ІЃDkаЭsФh”ыœЈнn2Ar$“3“…з3c"э‚*œ‰ЂN $лiђрŽ>‡ыг№ъЪ2DFDѓїg1m| жќззсˆОyYс0Pђ=Шњ}щуЊ щ№%#=sтТЭЈ-5!)1R“Aя+С`и||сГЗТ@;Т§u9Lyw"'<ˆN•сЃŠт“Ш˜~*†ЊОи_є4ЕФцр?oЕтOўуfЯТMѓz1ал­ЈЛBТуaЋ„УgХЌ›–acy9к& <9пН#щ”Т§эѕПbмg~ˆ[?œмu{Bђ№•лnЧЄЬєqЬiє[+лХ1(ѓяxё;Wуч?њ•љЎуxŒЮё‘ŒIYчzzzPWWїЁ1{Žйœ1š‘GˆЧ W-ДйЂ0џкЅeРЮђїA­ŒL цШ>Ѕї`zЦ<тBцДЙˆІ˜мT‡Люџ;vьљ^§щА=М-{ёЃПэС‹ГqЄЖŽli‹!ž9н}Nz]аў€ъjЄ\ЦD№в>В!9 _4€>7щ“Р@Б‡qЂgР k` jKЁКЉЉ АЃвЉ“Ї">![‹ћИ iђQRвњЅ0ю6<ЖМ_›€еЭX|mАўUlо1бfф›… —3ЬE`0JЖ-uэ9c'\†5њjІ­ˆи‚ШyŸЭ=.,œ7[ўњ"Rяyўc;аTВЫтЪ+gЁЃ†jОA'ЧЭ@jУѓxvЭ^|aFЪіяGзєE;sћ Ўœ€Ш Ж0ЎЩЪтX0s\Ш2­–ЋвvЋ-Nb_tЌ‰й“Prm4 vїеЃМІm‡_УŠŠ`ЬMВЁЊОi&Qrј0šЏN%cи‹#ћwЁђэ7yх#w˜uеl<ћшwЉ†{љ)—btњpFЦD&Ї 0С—••)\А0bdЄ1)В†Dт‰Ћ‘і•žžЎИЗoТсТЃ0‡ЭСЄi‹с уnFюЌыИшЦашr.О{=згЎŠ@pцмŸImdжnИэ>lнАћ”QК5SЁQbXќIcвЧaцŽŒЄ jŒРќ+ц"1e,~ј—fnžЭ<44=5MН>мЖtЬЄeu•АФ\‰‡gЮBFИ wOiAcŸЗіџрƒv А˜€љK"$œя–#Sbf•AњNa†ј­Иh“ЮЛ:*БъH/rfнˆWMB-§Hзж!іјTшQ2;fL4†!.) їЯ"пцСв%З`чўRф^ћЦŽЭ‚g %UИщ‰'157™ч…5œЕ_ O§њ)џŸ€ Х9ТZВЫ•УІM›h|•Іјм pšШNQЁ\‹ОTт&&&bђфЩ #s!†™ ќjљ/ёГТŸуСБ(ўзbИЃxжpXЫ?)_Мїћ§фдЛЉŽЁŒjНrL!ф)кєѓн8ЧJjиAv/юхНЋ‘еуCd‡Aєи А!,86к РпЯm)‡ёZсp ГЧ(Dъ ЭЧў}GpїƒИћ+ЂЧCDOФuФЇНд&Кј|‹ы–р+‡вŒ”TIлT xѕмщЋ‘ЯЕЬ^ъhmAС4HS-Жћщ`чoW)БЈ–МДО’ВOF>—(jйиЉёЕч'Ї•:ЩЁR2V222”ј#уjŒЄXтKNgCыlх,_­ч№I;Вьс'CW|ю,F<™fфЕE­рЇнТф љ Ч+59ˆJŒЪЬДŒзУљ! ѕГŒлŠŠ Х§Uж=-ШsYШ;::ѕЄŒqёВ9ги’42dNЫМ•wь$R5Ёx-а;ХCU‹в$тСрѕЩ‚ЦЋT‹DКТђDŠ"ыiЎBДDe"›ъ~ЈЂЁ”@(СЯємsFyh`k6㋇6uъLеZ1КпкцTжЉффde§7ѓL ЉeШdˆhПРКEъBѕ•Ќitя x„Ј›81ІG‚ˆZ(§І^˜B^ћ”§pлD§%DUH–рсeBTcём/”Oj1RYYЉИ r#'‡}Z)нGЧ™ŒC‘~БЁЪomй‘sjŒ2їйЩ~СZpхИR7 ђё˜!œT—‰ч“кЩ[вЫИўЋЏЏG]Оel †т5%хЩ98Ә Рn:Ю/ˆm‘ŠП2GИюЩ+a$ЈоWтa%.#ќЭВKЫЪ•gB焉=еœ1“йщC­uJi˜:‰ ‘ŸŸ‰“&ТIёrŒ;јЊk“S&Ѕ|„!&eљђх˜0a‚rOт\Œ Њ ^6\хšу нШ uЕ§Ю> ИDJ2Hяž’ъ`чВzхјТxD.O§Бп‰МvВ™— ћ„„‡ŠЈ‹љћ(2‘ќ§ЊoЙ™iƒ СNŽ‚;ЯFтk@G ЂgR]ДсЯh/лЬOЫМњОJ/ЦŠ4 dТ^yђ;X№%мw§L8ЛЫ№ь/VтЎЏ=€ьј@e“фтdчHW™2юdЗ0'ДЩcЁюPš›Ў}ŽPY|”E‡ ЩЩушtM"*Н$уІdЫj4˜RБpЮХ fшЬF`fЧЎ,6ќЁ`a†НrOЦЊ:^хўЩёхw[}9U eь4ŒIPђSъ%ёyЁц/eЉхЩ+ эи€C姘Е`ВтИ{*_ђѓв&ЉЄpъz0ћŠЩ|G“0юк„§e˜vе"ф&SДFЬ:шaqрHвЧMІч@фIeЋmdDўSыТ cЄLlЙ>ўLкІжUЉћˆ?‚ЅИ‰vTФІƒЭИсжЅ4z$Ов>~д9(h+ бf S5_‰+=Ју@pИxHžВ€KПˆ:ЧРѕF Q?pZ)„CY’y-SRтШQэ6до‘nrЙT5G MЅя8;нT›hAzRVE)OцБЬiЙw!‚к•!жЎen Y#wчRGЕNJэ”ъˆ#‚ДI Ф†ЕVЉИЗЪЕ–N ЖIž‰ЦK УmW›дю’О5ьЯŠ+ы0[ЉŽuмv*.Œ ŒœˆŸWq§Uo cЌўE LяуxР3ЪXT]}Е:˜ЗVЎ0~ZЙZ‰'ЭВ‡ёg=”‚д5G—Cƒ@ЦФЙГПSVџSG• @Т§*жуЧ9qжH›Xђ-…IЅХ‡]˜yЁœpB G|ъЌG§ЎЈprІд™uІ„ЄO$$Ў>ОаЎО„Kv“њs›Щ):ш’'‹ByX>ЯЗ п2иОh˜юХDgЧ#21‹фЪBЉŠЈ ˜VИTeЊqСЇŸЖМбO[ГБ‰Р Bј>[C;jњZаѓў:DNК…noL+НHŒ.M0Тъ­Ч7я}3 џ‰1TЛuЩ"ЧдFcЙšц^гх0)эЅЈЅƒ–ќ<1ЗŸ–џЩЉqhЋ(сЙ aь[YqaiЎ)C[Ÿ—–пщ4,6ЃГЅsнТ‚•qqЖ6ЪX,44К+ЃЪТ3fцaсј• ‹ба•Фе~№V§Б#ЈС\Њд$Ш#э9Л_Йж~гXЛжОƒћј~НfЅЪ˜АdйWІŽ’П’•ђчш{ЏсщееИ~f~јгЇё‹Ÿ} 1кЮСˆжКJМўћŸрћЕГб№ђ$…1ЉоЗџ§їBмЕ Oўјчјў/† +=Р6,ЧЂЯќo}А~ˆ1BЃЕ\kу0вѕЉв^kПењoзpu9еЄЃЋЧізт–[љpˆЩVгheч32Џ‘з#Вж/GСYжOQiŠdЁœ†ŠJБ‹ч$I#Aэ7щ[ВАЪ­sQŸ(QЯщ’З0M2G8NЕrДФZйк}YћЕkyІб­]’N{Ўх1ђ[oY“еsYT†DжгЁц)э“єкGв*'кžЂn#ѓНз6Уf…т ѕ›ЬSi џБЪЉЌФC‚д]e4TLGb(Н%›эžФзpljjRhыщ№“ь5œ$н™ТЙŒ)WЁуbО1ВмaќGДс„q"ŒЖк7*RЙвFЅHe ‘ )˜ bЏЉЅ:ELЉЌђ‘B ѕž•ѓ=‡Я5&edЃ”DјHrк]эшvvQUгжAъ/ЊДBяЌ„р!пCjуБŽ$`А‚*Љ a КЈ Ђњ`-Z[œKr!zlЬ‘*8ŽщЙ{6RBРиŠХеM“V8šыаYQЎšz Жє(–&ўЎ&R2nЪ•ќ/MCtL‰ѓА№Šw№——оСЗяНŠЇNТO в‘#;QпчЧŽїзуюяќ“B›ёЃ‡AШ”ЋaІ~б’†є AММЅЯўіћˆюп‡пЏ<‚,ъплžŽGКtWk‹œ„kgчСщ8ƒ^whљйG›YобšnLš3N12учСіѕ›0vю„;kАnOцЬ›ƒСкиАѕМ‘cpгќЩиљіsИѕAЌћѕзhЙŸˆн›зсUisЎY‚\8ttп”W7P_…9ѓчсКћП‚MAшPDWь~оуViѓgФЖukqЌЎг^‹ ixы§]ИщоясКIQш*НJZpGAтајї#.sўѓ‰?`рёх 2˜МXџчхИыŸрњЉiш*љ6l:‚ŒkѓБрюoс‡ НCЂe#лИwУDOœƒhuБ%pє4ЂЯž„‚ЌhьпОi3p§‚)№ѕ6aнšѕhї‡aстЅŠ+шžэ{xКё —ЗcцЬщрй*XійO# ˆRЧКaЎ@UЭн|=rbУаNWгѕwP'…%KЏDР@+Жю:ˆКЙgЯš‡8S/6mмWh&ЎПцJ„йU‘яаtП4ƒі_ИT!ођ3йРN\]›G'П‹›K_o3КЈjNKЫОИыЅ]JJJN`zNU ГŸtѕLcZc04ІD2б8VЈП‡ѕЮХћыЇфCЋ^g/&Х :0†юOTлєгэ—bD…Sk/П|ѓ#Џ…:ЛВІRМбВ_šђuЄїuУ_§gФ'Ч#9С‰v2эm-hЈnA3ВЂЦх#lЬX„ЄfТЦу–йx'§Ићk+а~№ њъkhќ аf‹ k@EЇ}ˆ˜]<<>\JJz‘јЦO~ Яџ oo †еN§Ќ%yІ!АО%сNдЕїЃ œчГd-ТW§ :П‚НmТЯЛіЖџ‡ЦКjдYgРxžытЧsџѓnИ} І\s Н’ф 'Чžn$ю WшЧК>gvY№\ŒША@4SЕцЇфО~ЌџŸ_!nк<яmЅ§ IDATѕTрЇЏЎУ‹SІ`е7'Ѓэ†7qg~пaFhlюН"ˆpь^љ ^oŠУЕ)ќєOсйч~€Џџ ПЌˆХяПџ€rаЏ p‡ƒ/wbŒdPШŽаЦZЩћУ_іwO Ц?ќ=~љѓOУЯsBB)СaЌ№Œ­ؘЈsAtA™v;Д,ч/^;аlЭСxЛЄЁ™ЅG]-МЪW~{hгtМlо!ЏJѕ—нехXДј~МБю/Јzѕx=шJ<Д8 џќп_"кяАя…ЇQlНЬ;ёФr+ўћŽYX§љшКчŸИ:ЊЗнїEќјёяРнј:^п}юI РсѕAъ5Я#м}пўЭJќ§[‹№ќя~ŒјkО„–ЗŸЦŠ€0,›ŽЧ]ƒkџњfRєђWЇЃgбп№щIc`>KТщКQ}Њџ=dŽhыъydƒ†’"”l\ЅœЈъфz”7у\ЫёЉu"s—1к9)‡жFх[н w47РmA\ЯсњЊHјј\–ZЙіђш„Ц†эHŒ%3|† ^’ѕ­ѕpЫюšiMЬGМLh2ЂH‚tЌ(BO‡ Щ4 8„аЩщNHЁЦc‡їРз N 5ЬˆрDlСŒбQшуiччrœtnž"™ƒОќфЭY†™ўЎя,!!зпЙ щАг>HФpq1 @ ѕвY™щ4јхšyˆШеMЏ ;2&NЧs[ˆXБM“уАeЕ9SрcХKЩлMBПї~љEЬOБ CїЇbС™ˆд ОкШ[`ЦФУbГcсW_С3oяТСЄdPЕ“8Wиг٘ФbУ†U0хмŠЖO? ХЧЅ/$O|їГ˜>.– ћ€ѕЖаFФˆ|Кc;Z‚Чу–EЙчъњ.ЦЗЪPчњPјоۘyэ§јёsы№Ÿї_ЭѕŸlОњP’+AМфйеп…_Нџ ф8›к]‹ТJН4x­CЃЙгЧ!НwЎМCK:ќ=дV=)ŸљњC(.@”Бsяј:ТшIYлmФјœ8Д7ьУЫEщИ’Œ +О~м˜ISЮ„З”Є,Ж@t”юХІrХО3шНeBсЦ•Ј6чржЋ ”pЦ GћЁ‡u#M0ЙЭЈЃ#1"ЕЕеЈЎЊVЌ‹e@*ъ%ŽWХј‹ЃP{Ї„Э@"hЅЏv"8r„ў БЄѕњ`/эO|Аћ‘dЕ#>Т‡ю~#кKЊаИЗŠ.H,Ьˆd"Л•ФЪТ˜оЯИr*~H!ђ—6hхћ}v?USЦЯЦKOмЛ_n…ї3>Д5зЃЁБu{пFoТbL 'У…ƒ†Ќ>.~Э]ЅOћл›ЩџY1mщxѓЉUЈЪL€ŒKdJŠо_ЮАё˜7+—FХ$фкLйxBTЗСdGTHіьм‡%™W(xР%^QДђcu{jwЂ‘GRw”юЦ+е=јuž ЏС7RЧрžєЄ4uСN/ЊЂУG;&бЧ>ХСёXВl)ЎсСJQfJ2шqфVusЬ’“бьnы@Wp—R## ™ъ›EЩKк˜ lщŽЦТOнŠEФ'*:Щ2І–aNb іЎк„y™Ї(жЂЁз€мьd%>z@ЕаеБ‹.тБtƒž8ІxиоЬ<;Ъ*АsїнJм?&ЏA77Y]”луr0!;й“‘fЁ Ађs’ym3*›tџLCоТ;Бёu?wЩx=3 ’57šіiWG#wмМTД5‘б0ѕcFкBЄё\)3№єлгЊ`нёKёгЧПŽДH‰чХ;ППйcТџўјs№YТщыЄ7ф>КЏк1~BчmбЪŽ Є–ыњЄЩHŽ B;ЦlыьЅKЖ—’ёd:єа“Њ эnŒŸ˜Hn*{[kq АŒЄ\фs;АэmЬјSі§ьы0—lDГižќцC8Мцxvљ6L§*_y2Ф”ьЁИіСтХЎ_7Bэo/ЧЏ_oХŸ^y‘-[ё№яоФтE“›ŒGžјмOО}‚4ѕД\ь;Ъ:юhФ“п~ §єјЬUcсНuОž‰MwЖ"ŽюпБсVZџМэ˜?м’#’!љШ!vWTЫЃrщ!EІ‹œhъ˜щИыš|іkfMЯ…9 ѓ—м…,J(Bјfц9Ц"ŒR‘№ш ЬЭO\XжДщ4ŽEt|OkLS ‡ЃуMл›Р PDFG(ёJyRЧJ=UЋ{?_хƒЬЬ\Ў~ ы(…rлBИ p‡gЅˆ0+‹Ь ^zsкЛ;0yќЬ—‰mЏў [Kъsѕ2ЬŸ3qмцяЄ Ї'a*-Z€Њ-kАчp1j;ХКwжд"<-)БŒшsтƒЏbХЏэ|‡’%11&МіЯз`ŽЩУŒY“QCœ=‡JPY]‡ф‰(ШIХŽ•Чкі!iжgqЫмБ8И~ЖРŒ)йhЏ)СkџxНмљ5ѓрЊЬ츘4);зОЕk?@фДpытЉАаxћЊ—ББ„GmзеРkFNzЖўѓ“rТ]_3UЉ3 2јŽ‹˜Ц =!„gT ‰6>гѓВАћн(*+A“7/ьŠ!#йŒєщW Шл‰ZО=|J~.zкыؘЄ"/ЦŒћзЃЈЊ;ї•сгоќьt$ЅФс•PNмЫБDЕ\;ІЮЮчHv`ѕ‹СŽвj$/Z†…sg"Dдj ЪТtR_ўЛ§”ѕCм{х|&YOF™ŸbРШУТДЙx6Ь$x4Ъœ ЃоїуЮ'yёhы>CџќpDЖ!н:€kjŸYк—о€wЭыићПIШГ(E1Ъ™JRІ• ]Оћєујвs;1.ж‡_џќiф_НепТžЮLNЄDю˘АxЖПєs”кђ1-;Žk‘}TŸTt`к”1j †ђUhЗЈBЅкgsеfћkбгдˆ=ЮьыiЃ„Гw%Щ}9(*=„фр Θ;2Й– —N'ЖОўк)эыщьсš†ъТЭxџ`7ЎœЫSHб…o>јkЄч†уХ?О‚Є‚ЋбН=џ’B}xёЙѕИђњЙ8МтO˜zѕw1я–ЅˆA'ўяф|дeMAёК_Ѓд>q&<§јc0‘iyѓ+;6оІ#јгkХИkЩd§зб.WЄёде^l^О‹–ЭQэ ­HY­”V•гЫа>v&RщЭзJfцG–Э+рё РЊѕ{‘“;‰Qмћ№оЛЛ1eС,D‘~АХg?шТмбъ2иpЫыЭИџЮлFe€1 1SBё^y т јэwxМНЁџѓн/"’/Ш=Љœw&Aц€h5Nеf3ЭЮd(ЫGD]VrIWнњ —кyќl%UN\{лчOБ•И›к†ЕГf: ЄQЗ/Иѓyr ј{зTђ ѕŠЪAˆИ")с„ёq‹ъI‚ЪЈ№05о7qВZЩTxyЪ‰6*ŠQ,Џ!ЖЂŸсбЧzлв[м­|бШі—L˜Ÿ"Nƒ0&ыЫ›Œ§СєтaZC/Љ†ё.y`Ѕ fФѓМqЅ–s^ŒД3HЇлЌ0hqщЙHфюBtЩвЧТМE№0:‘`XшЉJ†ЬMĘЄdіПИћјЎŽ$ІqAтъ&оZ‰)мqЮ4кТwЊfk0„Dљ?}’’AlQиЄ.–’fо_СŒO rcЈt‡мЛўўG)H`H(U+Мa‡Ÿ<§<=­ ьwљіїаУRАпЌlы ŸЛW’)СШc“чоxЎZv `ŽЩРˆћњЂС‚‡Пљ]žзУs^ш=eхI›†ј\<њяq'I A 3nОъ~<* ўчwЉ‘3ahьK5–ЩžGџуыhя#ѓЊЮГ3–оƒ™7(pЌŠ‚сš‡VО ёSёHŽмcўЗ?Є^№яm|]%!ё­ц*m—3gфЭЗ§џЈёЇуѓŸV/ЧЯМуy)jЪЧї<_ЩР#Ї z q<ђ~оЬыёи”…Є‹|0пВ-тљџј†$–ЇСИхЁGаз?РƒОТш]&н:Д[тгз a }_.8HЩ tpЭ‘ t/ИvОbЃ™Lњ{іР4›‡™ёљR‘СB2ЖЬлSJR xт;wс†йЉ|љZ6nчeоA&уЅ@rNОїчuјЩ’‰Ъ’uЯЇИžAЪ1T`/‰Т]EЈуЦЅЏ…ЇksTЦmЂ$†›‹ЃлсЄІ’ВН™БWŸКŠCwe‰uRВ#’JcP%гАЬƒ+Иq)нЗ‹Пѕu|љЁыШГdz),,§€ЧВ‹-—Gщзаћ5n@CёћWŸУз\Ю"П?№=|ы‘ЯЃП4џЛЛ х­јіSнxч+ЪVМ‰В›?ыfЭРЃЅўіО0ЎтZћле6ѕjЩ’,лВlЫНwcšiЁHH„вљг эёв )$^ЪЫ#№ хх…NтаC5ЖСНї"лВlѕВ’VћпмНвJ^5ll'žБW{wю”3п;sцЬ™spv/0O„L™‚lЇhь3Џ41_ц<ЊpŒqЧКnЏ&bл`кЃОŒёМЫ24жr"2Ягz ўб.Iˆ nзжn ФП‘VвеЉ(C§ 4№„+вЙ[ Иу|4УсдзKaNEќЋ ž"Е Н7.:џBdlкСыtфд/ Щšњ0RЙO&NќD1&ѓІЯSЗ0–ўž‰>‡ЕжQщ(еH$esЂ#I‰HkІBJAbF??aЎв3%!Q№“-Lсd”–Ы=E2 \ќЈ6qVЙвYаJ„ ™Д\цlё„ ЈA‡ф$+?‚У@шъ…‘‘Њ$˜kIvЬЄ™zС$Q:c€‡ёК6NЙ„4яЧчб=cG!–ЎЏж*mgрKšžЎЮз3xШ:JЄю-Yfd˜7УтЫЂ}]7$!#S[p‰ѕDќ|> ”ЙCiїН\Џ9%с$rўњШЄфъ˜w‚ §=~WwDзž@ WsКr‚кkŒ_щЇњbgМ{‹H№хB•Јэ ’›(wˆ ’Ac/ŽХ9п~n1Jpз=8ЯУУС6ОŸмаэ9Й‘ЇйЗ‹?NСЖзж7`*р3O=ХЃшуЦaщgЎФя.Pџ6†ИUШюлБ›YŒљИов0їšV%qk1SˆЊЅ”9k8OыUkТtњшŽИtў<ДUэA5‡Эь€S‚ј{-јz .CwЄЊ_}чзݘ"CuЩ|Ї–зOGan!žнёwTN^‚ђ†3ИиыурМSяы.†sНЈаX_‹šj‡Iшръ:'пyџ›Щ˜ds\NЁx"%3„)ѓ/Фoџq> вƒиЦEUZŽ3цШТwNV Ѕ-рж''йЄtJ0|˜7-Х#Їр7K—аЈfъі=OЭ\Д2 ЭіaїЋ›x5Эе{š<!jWQ)4г,„p—n#­M ›„#o<Њ*ђСzлЅЄfїМd№hщг(›ˆSшлORrЉOЙz)V­й…ЂY#ИKr§еmXєбZН~ѓ1,БW\w#ћпŸЁ,ЧqvщО?oЕIОЄRѕАgЇXGmтW—<‚ŠІ›vПŽџ|`)žлД#ђеœЃfёўRjћBA/I˜“ЌЖ :’еПЈбG $IћšdАŒa#Žў”y LхФ@SlUAcbH&cA+Џh:РцИэqПU(K•%$™ sBЅQrFф™GŸP:Дп˜фЇоР)Кuв/\КХ;QІy=яХЇ‹Пю™.VФQ_Ъ#+šrŠІчuВƒ;pіE‡Нu_Ёg9ЩгWyіоЉƒ€Ц ѕY1ъЇZЈm›6тѕW^Ц­пљnр)К‰‹.сСЖнh8ќ"BGі"y%'ЦЫGƒˆЂџшЎьEz wп§дmesёэEуБњ/#Н {W.Сo^lС_|ЛыSИѓBмњб‹АэѕПтОG—№дa r spХ;цSR™!‰ыŸфЩЁuызб$њsИфтЫ8tњQ™Z‹ѓF^Ы§ o,…FЋ X/6ПЛџѓN[1bъy˜3v46нђi<У#љХфР‚1Љ”б9`к;оƒaKТ­еч(ŒтМЋЏ4VqeYЩХ…ц2ъDвоU”[Aѓ№џўМф”вїЫиYgcO EПџ;{4о}Ю˜ДіNмљГŸуаЎјјM? ІејоЗО†‹џэ{8{BO?t?[О™Рџїcю”јТEЯр?§ |{qщeF WTвY{ьїс•7_FъУ#ёn• ЯЄ„scŽ yл>3ЖЅ—т[пИ_ќсзp№ЪЫp№%Ј;у‡xчЄ"Ќyі546Ѕ`в™яУ/>ЖŸИљvмчWPLOйЧкЯ/žџЯшg|˜жQЕmбеЛD”:џ‹ь”ѓцqп9=нHnP†X$u (žxџЫ_!cюеxЯЂ1ŒJТ#<‚™3gН•ѓvеЁ` эQ<єиc˜FKЕ:­УіhpI"cЂ“RR§š–%M1ЧžйфvЖsyЭ]§-Œљ№ШЉГPєœД†ЂЊ MиVѕvJ]єНvC їщ§tс@~YЂ=nуаsИ)ЩЯ825™hfЧлёїѕШМё>2)фЫ)Ѕшw–‹Jmвjќx˜Є+іЄ]Њ=юікI#ТVl$ъЗ5^Фї§ЌIzНг•Д#§’сУ‡Ч9 k— 999ИњъЋёЎ+ЏDѕНќ\,Э™;—zHphЧfј8І Ÿ2ЉХЃXЖЦсјё]УQюљіїсŸy.œUcЙЉtГбDЋоtх1wPg"…врHЗHш§8#; ЭTЖnтpІ =в‘D…ёЌNi лГ{зЎ]kЌ€іГŸХ%—qbМЄжђиœ•‘…qуЫБcћ*lоК ^№N7{їo2ѕuДOEЫгмѕбc.•YЋyЌЙ™’Ž!”ŒPЉмжmІў="™л­tAВЇт›РЃЯE<ЁG} ™œnqvА=ЭЇrkSЧŸхS.'Aѕћy4Йžz‡-рюDЕ‡іЃЖ•ЇўŠ‡Rф^‹Э;ібоU) Г%/‰аYЁTš ЅgъODЙябС-sЩЪриЯэ››З!Т-ўQУЈƒШ\ma*здg…эдwLЃ!Яd 8ECcM%vэЋD:j#KxКtЖвC+Згu‚SвъУGx?‡rNЂIЖ0OїДR_…qRcA§`SX,A" 1ЏЃЙћ6ЌЂ žaўє!CQ0z<'FiЮ9cvџХ:“o|jy9ŽrK^žŠ;'wgБDэм†hhjсB,žз%jш=h L~ЫЂб$š%рЂŽЖЁšЙ yYB!НЭn -Ѕ*œПјв^ тт‘К„ђ’Ќ<^.$CЌзa$hГ‡v5ћQZь06GMeБ9ЩiB<ЂтœFЙeЙm!ЮТRъbr„0ЧsŽџЕЕ<С—– OŠžЮМb.XI˜эгМшzљV\•u#^JfшЊ^Uš<ФЅ™і–‚œb‚Ѕ^кђЂ…Žhr‹ЋЎЁ ^*бЇЇhыFк šѓ) 7‡ xТЋ)Ь“‘!ƒIp 8 їдСG{ˆДBЉЋФcПџ%>ѕ•лЈ04џіEZЛЛєLфАЦžsп…О wžŽы3˜ ч%sвЦ}OЕ3Ь}ПіVZPAжŸŒф’RњсУЉпЯS:„ Ѕ$СМб<пNЧ…4уLOхдV>„pеAњЂi ъ…ƒЁШІЕX,Н рЬjцФм+џѓŸиќЙЏ#Ѕи`QP IDATО˜pуЕИњЧП5Еўцx?DНђјƒ8> яН`‚3)qŒьДЂJ Ў?џСАЗ)‰Із›ёхяоŠЩХ]оЗ]Њ5юiL>\wПxњчHnЊ†F,kr3QMkЪ<Њ@ŸOaг—SЈ6Г’ЯvГv}Лmm­У§пљ*^8@sєЋsсѕЗр§g1FѓВSQБэyќz}~єЁГЬиЬYЈkђ•цеН†9шЊЭŒеŠ‹Ч"J[D‡ъкOКyўэ=xјЙ7i€m&О№ХP”Fћ#œ?tТ3к\‡ЇўєS|ё[ёРoˆЉeЮжЧfiЛѓ'Ј3„JЪŸЦќq…ДЖПЅЂшƒ•ёлл?"Nž.fq$дK—žЦƒqЧїП‹#ЉУpxл.\єБ›ёўѓІ`ЫвЇ№ќžм№ОyXішЯё|гD|скГ‰ŸfвxпŒ~=&З  ’7žyЏєр™зW#ўMње}x†–ьЎЛ`’КФрЉ8N9zvДK~иДЏЃjЂ• qЂп!{сbdsп5˜CŽ$Ъ}V_!и†yЄM†ab kS“J­бд\nлЄвˆї ЉџЪѓTДœZ–§ipm˜QКn6t!№VžSWn{e81шНuчSуРk‘ ћhS=ВЧq_:žКnPCпK[_ќ;B™Й\Щ:stnёЄцRџ-a {кб‰F)њш%“ЪЏcgЮУˆ ЅРѕ\‡ёЈ>}ОhћО.RhOчвыiЕ(Џ<ђCмёш2мїЉѓДVK4ДбУї%мс]X‚ї­Тъ JРWD7 …<к>ўHSЭКoЋШТgПќ)Œ/фjЧђ—џѕa<О#пќм;Йє#Gd=™Я,+;SBo„9ЊmЁQШЁєэтAXі}(БбС ѕh<”Рtp\Џoю "q–Qю "ьСЪУeф";=„_Р­OФm7~эыŸЦc+šё“_џЫюПџѕ—eјжеѓ;л.w­Ѓg]ˆk'эЇс=! ЕЛqћЗТчюљВї?o=№L§ючyА$„—МЋю{ƒ ЄŽfflfIˆу‰ŒI‚Ђѕјез>‰№ќ›q]дl|žЎ>ІbrU#МTmhІХоƒФш–џйˆŸнїof@г]o§a эшЃ7Фсє:Б(Њ4™"МёЧЂДДŒЖЂ˜=o" [ŠџL‚јЌЇњ5ŒВcFMAцwEЫњ8јї[Q§к3Шš6™cцвЧ ЧШ;ŸlšШс0Y| i‡О^кЊбД­u[—Ёnу*„ЗRБіІhЬŒvb'„Nu(оnњДя,ІФЕ#ѓvзgЫЗєD@іk4t­ŸЬЏИdю K…OneшЃУ—фИєё]Ъх‰Z’паxу†ц §ШRМzѕE џw5ИаХмч|ъ+”ўrцŽ›1мЫgј)~ѕнђQ‰ѕ5Cpз]_Ую5ЏЃ2—†лВvтНџБџїЧ[БэёЛ№Jt>ОpѕUЂ‹Ѓ_іŒЭk џƒšЗoцБмЦO€rЛуњ1ŸA~{^Ћzm™}HКљЬ4Э -’p{ Вƒ<хВщ|џЛ1—Ж5Ъ3г№{яBћкQXЕ;Š[П+&%яХOѓ0Зпi1;­ŸћФ;БrЩяёщЏоkПє9\<З И§6Д•ЧКчžТ5пЙWЯ†ЧяЙл#Д%лœO|ь*o{ї}ѕQІЇƒKZ–ž‰*)ѕMЁKјq3б~ЮЛбМъЈ\њ =ѕ;А_#{тBškOцЊ‚и|@Iв№ц^g#}А4lмКMo |ˆ/ы˜!tцG‘ѕџ")ƒ&њгŸЬ Ю’(”ЈмDqbJdsFGХЄЈЌпёtЙДє',Й{›L~FХKьZцёNЇі[zœ^듉߳дЃ-щИw†XПщЂеЙS[еŠyѓ‹щGЅЋlmgtц8iъѕ"Ѓ‹76QBB{_щЉadЊAё„tДOE™€qйщXNЇqMеGŒЅQӘ$ њpЅяОŸxзмѓЃ/т//mF9Н„я­ЈEў‚spлGЖтКѓЯЦŒЫ?Ž/~jAg Ыўќќц•n§і|ч2: ba*ОЎиД›|ДиКЏ[RуѕдН<ж\Мѓ№8яъ†71yFWй=Ыа‚7Йi+ўDW…tїё‰O}f_„[ЫЯœŽ­+FкфK№•oоyvяІшћР#xѕpnКЈзŸs9.ОІ-ѕ­Ир7сsОЕ_І7ѕnОуfx.‡пlм…щћёЙO.ЧKП€лц’™˜<W\xЎџСx\Оx^§уFьЄџ*…*ыF[yXи ъ;цйа|ОєFш-Эмh­=Ф#У3oЪ|jЄ™^щuЄYЮ hmЙ…G…н1яш^Бжhuњ™Œg–ŽЪЇUlъгШV эПфŽ™‚ƒыŽPт•„_ўф{˜ё™ŸуKУsL^7_gAoёЂ_ЦDН1‰х…OЧiщ(щьџїп˜0aŒ1щ~ўŽ иеРќЙ“Эљц^цСЗHт ЪFцФœлчKрR„єѓЏAкТw eч hЁХмЁ#§Шš@z|cPНsЊ7ЌЅыz>РТ‘ћ3Є*GbUPL'АŒ)hю?žд@:d}TЯM/€гqј PёJ&щнgћvвЈ—VЧГWЎ\‰<95eЪ”ЎъxЯ}!E_ч KбWœ’8эб7ѓšБТ­ejFqг™<ƒЌg0yUОкcш6?тыfIІАјИXкЗFUяв~ђщ-Ю“>бј8˜ѓЙПМЙžО€h)šŠ‹nЯSŸЃ,— z[ѕЪъ$ЦўƒuИї7ЏуcL;~тPsъPiO…p„шМ3ЯУ;_џ4–б{є#ёдз>†)щ­ШOЯF5uє#мС‰Vя7n(4аЛ}СаošAГ ў,њЈ)cTйTž­h›“•иŒ[4ЌOНє а9]ž<у1Ќј ЖmKТOюќ*В8ИяЈЙћуЦUвіХЧЫџ['Щи›[ (ьŸеё}š СЃ{~‹7 шo&kЄЬєhљЕ9g6ОєхAgО&lЅIў Ѕб 2ё>RћJ2B<™” ?Ђš0†№~rn)ўИ| FІА3Ф”‰ЭvƒЦО‰dnFѓє>ZmЭ`žVъ“DЪѓi6>З,]Ž‘cGЁНюu„шЫKgMгш`ГfџSЇŸz2­tа%/Rя&ЈtЖ)›ZAєdHЩŽНє+Фљœ**uш№Ess’ђ0г†BA“66T™ы“§Чэх!bГqйZ:mЂсСІчAййпЇ^ц>|џзA™g>ѓн{ёЫo]dcБёѕXкрєД>Jи†HVІ—ЗЕЙVЏФэЫх"ЦuяпKЇi30kj9ьrпЎђNщ[ЩщѕJ+VdHCЪЄ9ШКцsШћсrјЎМ ‡ъЏ@лђ-єV;Mх7#ѓцЧ‘їѕП#у‚w#X>“Й) `^•a8Ь“м`9–ЊЁбŸ-[Ж`зЎниГ{—БyА‹+.gЋVѓљv}bv^4’ХюЛ/zsœ“жљбї_•)ЭќњЏУ3й3PœЄ&R“%F]ыcьЫ(>.ЮН—(Ny;ѓs‰•чЦщxbЯИјzмt§Х%ЊЛЗИј2{ж­-žq§е_^B|ИŠQ‰шQојќ=ыNH1sы‰ЯлW\ЗКcЯ [œyždќп=z†}еˆЦnu‹ѓN4еE-_эn)TѓSGщЩк&lоНзьЇŒЋ ѓ^˜FЏђГ1цŒ1XЙІ‚cŸ;TїнпOд]1HY< y`я,yќqlЅудфяZ}ФИ Щ;ДйДщуiŠ„Ђѓ*г•ƒчюр~МђПт‰%kБxBЊ4†Шъv/Уч№lмОiЏоŒ_,YУ‰zоqщGаD-џчљ^ZЗз,&ЖчшжЫ„'Зnй„žy {іюBЦі|ЄWфaqђUјгœGpqо'бФБЁзРЖжЏzќљ1,љЫcx}Э6dв!щ?ў16V5P‡ЅSП„ЁŽ^’ыјŒЇ->ŸіЖібpЧš0гp!жJмUGъM:yц>Hяр‚Ё†7ЁEйв™ИёМ::Ч skG]=}v2ёч_оK' {1юьsо§ ž~ёe<єїуЪ\NЦЄw|ч›М_У’ТXѓк“xт/у/}ліU#oє|М'Дўљi<є›?Ђlм™››„њ˜yюЏуw=‚ПН№ŽДHŠь,X 'ћ в4d ОvЭ\|щkЗb)=—?њппЧЯжMРћ–#ЬC0‡hљѕНѓš~Oоі{дpкs—ЧвЯнwпНўњыЭЄПаф!ЫЏ/Нј’Бќ*лђXspОvљ ќfе\љžщtцГ…sЏФчoјЦQ(<с–_€Оѓђбшˆ9qi]{ИпЁgЬ№Юэ<Љ“‹@Q)'Wо'.кoх>•~yНОЋŒнўЧjљUeЩ‘/{юYќіЁ‡m8ŒЪЦJјœF/z>јЎsŒмЪЙќ<:8p‹љT[5Ы?Nу|AtŸ paкЊёђD’яI‰Ь]їж(ЗэйГћїяЧТ… MЛ”>ОПѕ– ёЊЇgyЧ7аz{Kw,u'Ъл[=OTцБФ ДоовKн ѓВЂОXнгЋњиъdа“ЋЌЄъ} аHдKO=GџpОѕу{ЉЯЮэƒ”,nо`ѕ–*ЄюпŒїПw*'ЛZ#є~ž,ЫЏbєГГГ1gЮ\J‹Њch/$Ÿ:'ЧЧaš>ЏЂž›ч№>Œ]| fœбExьŠфѓ}щРя~№}ьЃxСФd•cЪЈЁ8Иg"Ё\žЂ9€:n]ŒžКЪниuЈ•РѓА“VZЉмйЪXюШ (/–ŸЦ=1ƒKжЏ_‰”Rа‹НљШкgm`ЩЫˆс#А№ŒXПіUМБzЎЛі#GбЉˆ(АэмИ•Д<ЁЄ#-{&Ž‚ЕЫ^C{оXŒтЧсЦ$ŒтqсŠлЙЗU`s'•rкŒuыЖ#Џx НžGА~еJ4бD~„лжЙCGb4Н‰‡ысх^A8Нg,˜mŒЙ5еV›-м|rŒѕЂtм$ aПьŽbB8N`ЄKM›W/У†Ј\€щ3gАЏхн#ЭI(c#є+ЗrѕV Ÿ8нДЃ/"bљЕ_ЦфE2&ѓчЭE­лIG@oнСнЈЈ‹b5Г%ЁђSlЄZ9“š‡~ј„šЄя „уsHЯHLŠ— ›VeF*тФъ-wЏŽЫЗ;№“єђ(œD†qуSПЧв}йј№Gп#t(еТšnkiТСU4‹œFгЯд^ЏE]8 ЅёцRZ]Й›ЗяЃQM*AKЭ~ьЏ`ХМIВQаG‹нvькЕ 0LЎ^‡‰f=skœˆ9оeЯђDпБЖбв#ƒЃ‡ћ|œ+ё№Њ6dаЬЇŸЁ}dАЋюУwўпЅиЖe+Оxл=8ѓтї‡ŸbbИ§76FюЁ­єe2‘ЬŠЛ!Тv’—!КщІ›pйe—qВЏ3fщчЭc1v7и`ЧЋDA=HЌзƒПМ…g]Ž…уy‘AэъЩр›‹ьЯїœвтoЛŒ‰Жoe_ъ‡?ќ!-Z„M›6™яQЃИMТ1TК>azv—є.•')8м–)"юђЈ"ЛЕ1>aќѕQЙqд}ГЧŽI Wc .юVЗњууy}|g‘ИТпђхбЯVEiЋг•"КЧЅн*чpяТш ƒ>Mвw%яэJрЧ‡(}мe!T_СНГ=д–Інг ”eA~= Ц'§—Йfwq{ŒіЁe}MŒШqfFо.И’ИВ бˆŸ[*кк qUи^ЕЗќъ9ќшЇЗ#ВѕoјбSuјьХ№Э3cђ7П‡іMЯ Д№уИ~qюНы>”LM§+ЎњєW0Ќi^^qя^ёшOjЂv9{јуM…Œ*ЎСъЈ нEm/ $.ё€šhш-NЯв}ФЂУЁ‡qё‘lЉЅGш$ЦЧŒЇаѓŠяSzŽbLъИc GДzРwСУ"!|ј›Пу5}jqЏт>$У2цХгиK<Я(8э>йнїCfаЕђtƒ%%УЬOЇ“‘`›єVuыТБ Nœ—|рНмяqtт%ЅŽŽ@,™љ6*S}ŸB3)ЙїEK“Їo7nєшбиАaƒ‘.iЫQžттb“дш+’Т`0Ыј@ЯпѓZ“Ÿкbы”DWЯ)ў­Uёя­cЭ‰гxcР mjOмu|лMМk›ъюМV|,Јс(&ЬЕѓOЇЙOBн~шd‹сХrDПzއnќЩџvzŠй0—У”ИэrБ5Яƒ8;9ŽђФьt\™‚о_‘ŽеНкНёлŸџѕщУбМ{9ю{ОЯПњ'хv=ќИ"ўЕ.йеIџ™‚^аuгЪєІмвŠтђщ˜”ё7ЌYЕ KпФg_‹ьДfф\ѓm|ц†р92Йѕ˜ЖЏnЦ$23‡vПŒuдЄŸ4w6Ў-ц6э HмнW0ƒ@,$%œЄk’ФС^0КЏІ:ЙщiёqЪЇјx›ДНФ‰šne2н€тT{|н}агyф4жЎЗ…žDtEЃШ™Lbʘ>0‰ъNwЪгує3Aшйђg]шЕxш0ђZё јщюžG7uOяЩюъ&~kвpњQuPД…лйЉтp>™—z—ЄЏ•(tН/н'юDi“i—Ф НMшЪяоq&sН юJйљ•јЏЪŽiii7nмQ‰КоЇPся–TbF$šИѕі ёД‹YPшŒ‹OЯыЮмМŽoЛ‰Kk&оXEeХ~ыK‹.7$Ђ3Q56§n9Їкw—дЇЕ.\EьqnOПŒI7€ј #д+Ш.›ŽoНKНAo#fќтПЈ`йЯшо љt+Хў8сЈ3ёуМqd)х ЅЫ.žЏ}v!RЗOЄ{яНЏѓtВ‘ЊДqLЁy}n%г1aоˆёјї[яC 7…iЗrn?лєrjO^/БћQоЎnоURЂИЎЛ§_%Ъ"тzЃьDдЈKOТ‡j#4ГN])юЈыzyOFЗш9Uі6ф,N“ЄVњNЅh…=WЙЭ§SщVъёAяXїIАџ^!A“Jџ)уkиЕhQљІŽИ,zџЛгiHˆKa/OwњYœз1іRВ“i+ юІ—НA#bє “™ž„Е[Р?Œ ;ЂV6œz№бP‰ŒŽДЬ`F_@”\ŒœЖЃiЬ6gъ\б8NХ>?нѓ%м71MžТ…о€щѓF`ёв;x$q9JЈM>’GK­Ц#+унW\†”H ѕ?АЉoˆ1‰gNм+­cSY=Тc-ѓXЪГє8OЗЗgpЂ№cЁ98™ŒFв† uLЄwu„N:яџЦеиЗe5>№•_aоХзRЧD'œг…)tхэЫ*ЉгМ“ђ7~ЅўV аsy;ƒЪЛыx;щЗeŸњeLDVЏС+JI:šАeЭ*4вщЛр0†Я= чЭnьbШэЖ Ї$9џв#rЏuВІ­Љ žЉ—тТЙchЄУ8ЪJПњ›8kюtЭЃkršrцљўїнє%3о‹іЄ†вXP(НŸA€кђ§ ‹FA4HЗDŒ‰ФаюЊ)бЄ/єтунэxХЉ|•_^_qКŸіdгO‹KїёЄб-3Q=;щ‘„!5™zpЃB1чЅ™ЃЫqхЧОŠпнѕ-,8я ЄбA™NЃiЅэЯЌ” ;гЮ„ИšЗwd6X,D _ЦDяЂГ{B11‹ђˆ]щјIЈoэ@Щш‹0c2 ‹yd3‚GŒ9рлpъ!  %DГњrŒ.лRЋ;Rђk?ЪуvŒщх2%gŸ3•{зх4?мn\‘Зrѕш e`ь„)ьT Єтo2y$Ьc 7ЉW $h2S"цDˆdл$ž9}ю„я–чN‚‰т{‹KTцБФЙДш;НХЛiЅюцэFЃ–šC{М‡'Mш '›СAо›žQЙ@ЯД!ъ˜(”E^Œ)Гga(OЈEhмЇƒ§3Bg3њdІЖђ]p%MCь‹€EрmG _ЦФЁРƒњ)жмєђŸёяџ~F№XZ-(ўхўЛ1ьМOр‹ŸИ 2дчЯž†‘Ѕ4FiЃeJz"e[оњeLДžе:[ЋлPz.l[ŠWœ9e9Ц(QMХVќѕщч1њŠYdJДQ,]ИR™ЁОєвKQ__oь™ЈЇX>Ж '{ѕі# БЬщw§їМ”дTЈЅmO,‡€вЩў—rzфЭїНчR|ђ’Iёў/cв/ўђпЗaўgяЧbžЪiЅЅ|хи`H„€$'bRdtЩЎ>!dуоnњgGК(аёzаБ}Е {e8ј’ЪИ~шnЇЇ[Нz‘„ЩtОЬœ №‡PQЩ­оЙ№яУ0š&OЃь…ўод‹@м^ Š SѕWЗЯžъДZњ,џJј<)lN?Ы‡ер_nеДЕGщ5‘ŒHжўдq;ЊРreб./Д<•cƒE ?ь`пBіОEР"`8}Нх>C'SЂTZAˆ9ЁЎš%Gго.kžєж)7т6X,‹€EР"`8|(.щђA4 ЂŒЃ"Гeуˆ:эюЭ€`Г‰,‹€EР"`шoЧA2&vєВ#§§KьqЯDЈи8‹€EР"`АXо*^OЬgDя[:Б-nсИџ1$nœћ§V Вљ,‹€EР"`8}шпŽ љ’Є8Wѕb<єq=[ълља Ї Ќй}гЗ7й–[,‹€Eр№Eлbл4њJ П*УjЭTt•Ж0Яє‹)бqO)ПъZёrШІя(э8+НkЏтiГй-‹€EР"`8Э№y ЩШŽIІDв1uuu† ѓ4Ž˜1MMMцкeJєŒїXYJД’“гЌ'йцZ,‹€Eр8 рC+KIР”Јl1!~ПљHKOЃeз.‰‰IJ\Љ‰ќЁ(}(ц Э$А,‹€EР"`А _G%їpԘєВ•уlнДЃƒ’IOœп#5бЕ$#ЎtDї-иіа‰АЩ,‹€EР"`АЏ7Ÿ\I/L‰эp)ЕЦ[]FФ§6щzмSœ ‹€EР"`АXƒ€ђЙзЏ€Ѓ—НžСдdгZ,‹€EР"`шoGЙY~э…9qЂ{ЙйOсіЖEР"`АX,С рѕјcв^…"qv_ЉSЂ н’јoѓУўБX,‹€EР"pŒєы%Чш˜єЈФе-qПuлЪTz€dZ,‹€EР"0hњЕќъ”Hq 9Џ7‰?yaЎžFіKŒхзAWm3X,‹€EР"`шŽ@ПŒ‰$!ВшšфOBХЖuјћ’чMЯDGk3-СЖѕ”ЄДl,8ї€кГ IDAT"Lъмцщ^§eАX,‹€E њнЪ1т•CХJЦˆ Јп…Ї—М‰ЂВq6$ˆ'ј6ЖС›4€тњЇЩІАX,‹€Eр4E _‰‰cЧФ‹H{;В †у‚QхxЅЉ S.˜‡‹Ÿ !кЋБ{sМ“‹(19M‘ДЭЖX,‹€Eр˜ш—1щЌд:"эhljA~ЩPlќљз№“hJ|еИѕgЧэї_†hЄQЃ‡в™Ы^X,‹€EР"`0§юН8чЏзKЇ~tаW8~О~лQš D‚Ичww`ё”"„лЈsГ;` lB‹€EР"`АX,1њeL”Юнб6ЧыE[c=ъ[’™ƒМм,4жTbпсf$ёžkуФ"lАX,‹€E`АєЫ˜ШюšєLФtјƒ>lуyмјЙ_`oеьпЛ›Зя@c[ФuЅcвк?‹€EР"`АX‹€/к>№,†AЁд$ЩФYяЙя}яUHїEсѕ%ЁƒЪБmд1ёЙ–d^ЌMiАX,‹€EР рKEiHGяhhЇг(Н'ŠіˆyyxхЋWaлО˜2Ф‹КЖМыƒзcіЈ<Л•г;”іŽEР"`АX,§ рѓd2EŒ‰ђЧ6rxх…›?ўЬИљБ‡аŽPй•йНAd†’:uQ”Ч‹€EР"`АX,ƒEРmd‡ѓH˜Зы–6rкqИЊIЩY(Ÿ0™ќŒ~šЄOђљœ@GG”z&]9h#-‹€EР"`Ає‚€Џc+7kЮъхn|Д‡>q"ЕxъяOЁ АOќчЇёє‘2”ъБОq(юЙчgXуьІ,в/‘ž ш/ЇУ›† Ю@jV6ЪМ7QB"3є’˜ЄІЇQљ5‚ ЯпGiі–EР"`АX,ошїИАsX˜Ќ‰Ч oGžzv })шhйѕ#3oВ33Ђђ‰5Gп;аіŽEР"`АX,§#а/cтhŒшЏ>QДё“œ’‚pУ^ЌЏ8Œ@(„Ѕ$В kƒEР"`АX,cA`рОr(ёRбЕvЧ мyћHЎZ‰хG’‘ДoZл“pсЛЎСŒве19–ЇaѓZ,‹€Eр4G _ЦФб1‘– uL<Љ8ћм+Б~лx‡žƒQžДЗЕЂн›Тг9Vbršї%л|‹€EР"`А3§2&ŽŽ‰˜ŽDЂ!Ь;чЬ?hll4вПп-ПFЉјкn-ПѓБX,‹€EрtF _ЦФ‘ƒш/э˜ађk8м‚™ццfƒ[Н '%љ %ЩШ9ћ’mЛEР"`АXށ~Їs`˜jЏbN^тOЃСЇ{тУi.>jЖigьіOтgи ŸЮgШДЯed&Z;Аoў№Hо;ы0оѓžT /Щ@[{jjjL?;vЌБeц2$ъЗээъ˜*Њ‹й>pрZ[[MœЙйЫŸ~ЋЪєQG4§†xЗѓ"b>zцБћŒя`ябГАС"`АX# ёдчѓ!--Э0&JЅп ‡FFF%+>т-XП~~ёыМV?зh(ЮžŸ4nћ9kтеnP;'Э%кBsФPКš5‰‘ЭaZІгфЦ(гyШ ˜tfg2MоМaz1 тO4IБSІOГё#Ю|Р4Њ›љTЗ)“I”NIЭМЌЙAuЧhsЁtкžті€*х‘jцVЌ8г–Оhd™J/ђUŽљfСšќ;iŒЋћxт#;id}jO>l1щзМЈgOЃƒSb SјЖруш Cу№Q:бкBЕ беІЄch юЙяRђšq§еdfІВн^ьнЛзєзђђr>‡$aЅTЏЉ ЙЙЙ†С–ЄФ•Є‡­і’nT:ќ#ПДл МˆПvЃэЗEР"`А$F@ЕoYЮCЂНЎЎЯ>ћ,vьиЯ|ц3œдкQYyoЌмОLš•Ž:ЄмИi”T(Ѕ–4"ЬIRŒ‰;A'БlM,šЌ9EsrаЄOЯ№LЇјљ6гсѓv Иш“Ѓ UЎE”NŒŒЄу^nрlяOъ0yLyLЈ WщLн*‹щTІ?VǘЅбwk,аа ЏЁQyiŒ™”уh“bъж„ЯКы8UЗ&M&T;Х<%Б^ЕЧ0;j3ыеЧдЭњyлIУGe З=mФp јДХ№aЌЯСЧЁБ|X—‡hbіЧhtё.ŽšLM[IЃŸeЛzEТGЯP ‘ві‹Oм34јФžсQјАюГ‰ЧGL/I@skФш”6„лqЄУƒ‰ѓгёр>.;вŒ‚ќ,ІI‚ЖrіьйcЄbF$ЙѓЮ;qбEaіьйfЛRР––c1оeRдz §KLфTЧŽюяN%ўІНЖX,N4!‰бЗDсЩЩЩиЙs'~§ы_уСФЧ?ўq444QxЄНM-@[a:rŠ’бю b§(2SНH&sBЕ?ДPдосшЫђ‚dVФthЂ№[[šРл4‘SєокЎЩї8ђќd^˜Mщ§œ5лX†У”xЭdеЦеО{AnеЋœиƒМЇіЊL?‹Qш •Ї6|ˆкмою1ƒКSІC#ЫdљbtœЩ^mю‰vдоžј„bјАZCЃ˜7ОУБgHЕNƒ‰С1FЃ‹Oе,ZЉЊg8|BЄпД—јxˆgcи‹ЦцŽдЗГ^ П(„­d‹šZjLА#IOJЬˆ$#bЎхЎfзЎ]јьg?‹+ЎИз]wДmЉ>­~Џ ОпWxKŒ ŸЏў;!vЁЏЮ8їž§ЖX,ЃаЊQКh­$Ѕ8wю\ьоНл8Hе яЅЈ"99•†0 yт1''…ЉШЫЮ@F24QaHр*Z#p3ЄЦ~Ю/Žd‚пb^м-ЅежKГ™a"bД&XЅQZmхЈ<}Дj“Ё2 šЕАNMИbpФ$HbУb:ыAзiF’nъf:MОJЇI[4jзЪeФєИ4Š6е+щ…+1fвчЕђ/pвšoЇnУДФЅг„-4(Œb[ЛъvёQ[•GхIJа­ю>Ё8|$сщ†OŒFP5ј‘P УЃКYgB|јP ƒgкхрг•Юiї`№ LК№QЛЕefЪ$У-Уи3tлнa-ЦPС<ѕ–MО Mс(“vЄз5ЁО拆ІVŒki$v”ДљФй9]&_yъУ’ŒHЗЄЖЖsцЬСдЉS™жgњИлчЕег_`SФeJgПиг _’ЭaАXN\1ЖОCЁЬ5žfffbФˆFєН~§zsOЋKyn^œ†мэл‘ž:y9YШЯѕѓ:J‰‰3ЉЖq­еЌ†ф€'p"ефЃ‰HЃДa84A3;iЈЛсHJœtš 5Љ™Д’JА<1=’˜P`bЪ4Џ5ёj%ю02д)`Z‡b™БIм­лMЇ•|˜Œ‚tLDcg:вЩЊcLŽЪ$b(8БŠFУфЈ-ќhR7ŒI\нjъђЛeЦкmh4mvЪьSІS7/MнјЈnв­ііФЧдkMц.>ІээGуcвБL\U'ѓlzУЧaАXьvтУКUоQјшљБnI” >Бч­tњэвшЖЇ•R г„9Ы”DЭ0&-”š4р R2ТN9tхСƒШЯЩ ѓ >IЃй’9rЄщГz“Х˜|рР‚ 0tшPѓ[[–bZє-щJе6PмзкФТйrЏпpќRŠFй0Ыž L›о"`8ЭpЗr$1s"ЦФeXЄ@8zєшNDtЌr%)gЎ|{vЅЁ=џLNyHMї MІ8ёhТ№Ѓ‰„ѓGl"rО5йшp„&?I8Z8'pЬIЦ™HЭЄЦ‰JŒ‰N†j"S:•ЉkГхЃ‰ŸЮ‰WjŒyаw ЫcŒKЇєšкUЫгЃК5ёšКYŸ[Ішж}3Aѓ[uk"ˆFо“ЅoщКФKLФРˆса}бщЖХLМЄбД›хшЛ…iћУGuŠF~Už[f<>JЇЙUэJˆу†4ˆЦ€‹žкУIйeѕUЗ0sёqг|X†С‡eї|†Чо№aЙТ'ўйшYi'ХаЃUјЈnџ3ЊО“DсwбШmГ#•hЏ\ƒГKjQ\\nˆ­у‰11еъГъЋb>rrrpеUW™~-ЩŸЄ)bВu­>ЏЃђ§’<№ Ц$ёIь_ў –ЎKХТwœ…@"IžvЫ–98 6ЅEР"p"рŸƒт~\ЦDЋM1*ŠwУШ‘ЅИўк+№є3Я`ЯkБaУpЙ•У1ž=uF8љhЋD3‰&3M(”Feh2чюƒ™Œ”NETогЄ'i€ОM:Іе}MОR\•т$… цО[ІVлb^˜Ь03цTŽЖFXFЏu3НЉ› 4‘šВb4*˜"бЈк#]ЃДйЃюNYЗв™/,Lв—>}ЛДБZг.е-ŒUwЏ42г€ёQнЄQв?Зўx|\ЅЏст#ZEƒ‚ћlєэœЪ>м@!­I|0lNтgШxг/тŸ!ыѓЁžБСќЩ"эпwВX‰ШВq‹€EР" •Ѓ гў˜ьA1&кІёQ]wЯЊЅик6ўїk04Е ЫўpVЏм†ЩcЦ“/БœЩщкйlЛ-!апР<АRl*‹РП&ƒ`LКђ•ёŸЯ0ЗђH—|:HyЦ‹€EР"`АX,Ч‚Р GМіKJfœ‰бKПџОѓ5Œєn‚wь5јФєrъ˜IЁ<,‹€EР"`АМјЈx‡щ№xS1цТЏb(mтgЄgb­Рљ:ТдВM~+4и<Ї!eЛЧ$E™ъ4„Ю6љmD@§RJyњЖ§ђmкmшС1&zYi(цРъЇБb•3Я_Œ!™~lц^Д–œƒбc&™Књь­г—!‘ђŸLыЃ8,Їъ—ВЦЊoй\АС"`8ё ˜1бф‘D#+kqяЏХѓЄuуk—"ZЗGђЮУWnЙЮип?ёMА5ўГ `њ|–кППёB)3Ц6XN$!3"‰‰МЁfeeѕyЄёxбlѓу…Є-чTE`АвЧ3&RnаqFСDм№Ф‹˜О/ˆЌТBd„<ШЩ‚nЇŸЕcrЊі“J—Ы”466bЧŽZP`œ–Щ#ЅЖtNЭ ЗшTѕ–hџд$А“*a(kŒVјд Щ /дG%С“Љ;wšя’’’З•9QђО* Э`яA7аfАœдЧežоЕњ:ܘP­žH-Жlо@zќ­АgыфЄ%ЁjЯ6DgЬF^Ўе1шЇcMœєЗnн іУ‡7О:Ќ:nЯ AZёюЗюїИнћёy{s 8ЊL.“ жФ<ьN&D~:XIДЃ™о­‚эћх„„ёЦ7‡hc:“&VyЯ6ИДКёц7ѓЧЗTqnМъ*гmC|оЃт Е1LШ455СJ5ЎтU‡'V—г*Ї\sЭјЎр(ДїЌЇыОSўQu' бЭ#ѓшTѕwтWЇкыжчцщњюЂgPX$ Ч­Ч§VюЕОѕ,Л!Ё8ѕS™йжvЮš5kŒ2yHэЫ”Щ8Ш?Т@uЩСйЁC‡Аoп>cSХєŽЯ +БЩ-'НgњЄІІš1_†%-H cтМФ^O;Žм‡фœ6к№2v„гG“єэШ@бФщSѕОл`8 uаŠŠ ЄЅб…;Э‡Уt[™ (Кœ5y№г3NйЇLb&œ_&О=8Мg=^ys+}Axщj=„щ bX&З—И‚mЎ=ˆП=њЮЛцRдnZCШУЌ‰ХdZhс8oœ„ТЅЧ™оT•ќЁ8mQœъtк"яXМ–.†ЖVтрѕбЈ,!:qJ?ъrо-ƒ ЫaNj,„ŒЗЁЏ.]Š“ЁМ Dзіф b82ЉЉŸє˜в/КTˆ$,Ю]~184Њh‡y0П&ЏЪŒЇЋѓšёbю §ќŽа™}€nM]ЮНпежlšр<_ƒi$j-њџМD3ƒƒ›‹eџ}ХСМїtNЁ]хЉMb–%СѓМ{їncЉUŒŠЪ:AхЈ| вЫ–-3~FЪЪЪ0fЬ<ъ8хЪ`› ѓЭ‡{”§ЯєЧEp'Бї€ѕК§\§{АСщC=иМЇCzѕqНC/Нє=cђфЩБqІяwi`Œ }U{8˜†[3n2š#^ŒО№п0Œ~БГв“‘™ž†œьd3ŽМ…g{:<ŸгКZjEпЬS\EEEf@vчјAЩyЩcPЉ#ѕœњŠS?wЧ•ОвХŠWђ$JKъ*w`wГчOнmІ№ИЛшhЇПђV~šjышКМЩйШA яУs+і`юм9ШЪ)Ћеыa;;фВ“„hrA№а•Ј#…‘GW2?mTіх}9Хт/Ќym’ŠЦ`Jй3љ‹†Vњ7їЩчЛкЯТYљmч5mЩ›iЛ”†љлЯђUgsИ‰žQЉa>dBxЯc&ц%Њ[э/b оѓ‰FnЯŠnнp&1KtДЅэЦGYžž‘‡їУ,ЧИ6ДяВbь wСњuO“mРХЖ-oт@Дѓ'”ДЃls[сЇkзhT:,m2[ПŒ‹ДЗЏЎIlKg`І§БчeОХХпяя:Q~Е-–Яр#Œј‘tO.кХH9rФ ЊŠ?Aяƒ˜Ÿ%K–˜эЬK.Йф_—!9€й2ўЉ5j”ёDќјууХ_ФЂE‹Ь;жWЃؘУчRНw3ќнбцoХІu;2zRšЖc§С|ў‡`фpЎŽЯЛлЭіо?!’Hl­С^Ѓ8щОі5YєьJЧз2•­Щ–Іw—_€ЂaХ№ёЗ/Љ[жМŽе[вн{ћœœлаXWƒ_;іoХЊхk CВ`о4Єx)’зЛБ–НЙ……v ЖЩƒљg…!tз№вKЫQпРД93‘вv+VoE;'ІсхГ0Оа‡-Wт№–НЄbFeЏПК ѕ$ЮŸ2 цOG(R‡хЏМ‚ШЩ†йГ&`ЯšхиДЗšЬƒхSb\Ё&q2ЄГ­-‰’2+‡ёцђ7аDЄКЊyЃЇтŒщeиЗi 6эЄ‡кˆхгцЃ4Л/ПД‡щ—kW3Сі*lнSЩ‰3 Sч-Ра`Џ/]0лYUцD: Э‡+АПЖѓЮ]Œ’ф6Ќ|c9жЗ!Џd&—f`н›+Б­~3вч 8НЋVЎAc‡ef`мАЌzэUlнW‹ТтБ(‘ŒЕkЖ ƒLMщФY•Ÿf˜ЅžЯЋЏпЧГ_ЈѕO1!b’Ф˜HчФ0s}1ˆ{bр–RТЅwaсТ…ІьV2oGuјA”y*'ƒ,cœ‡Њы‘‘•‡дXmЋЋаьIFnV*љт13-ўлyЂёs‰ЫАЦ3‡§ЅS~Ѕ1Х вmmЦЁ#5HЭЬCz2e2ЬM5UhŒ—Ё—(Ц +пбt88‹yѕ"HСъŽMkQыŠЩ#ѓ Г)ІSAt:}Ш‘ѕЄлмg:БХє™œџ„лf}kь?яМѓ№Ї?§ 7nФФ‰ ѓя`|t›ŽяcVфŒыОќ-œ1{ђ&]їE\ўщяуМЩуиЩj…2ƒ†|,нPч”ЂЋeНМњєь”њэ~œзoХKœо~Зlѓ#Я›фЧОoрoO<‚WVяF}е~Ќxs&/\„Y“Ч#РеМ—+љъƒАїP…%УP8Ђ 'CJ’ФгЮжG[kvзt`ЪмE˜Xа7VЏC#ѓю>а€‰sц  Й/МВ Ѕ3ЯТЙsЦaувp€ШaХ#ШЬф„ŽUЏџѕщe8ям3‘\Л‰Ьб.l'm›ыгpцйgcЦ”rдяо€›`юЙчaFщ,}ёUдЕrсРwTБ‚&1SлЗ"ЃxЮ\0л—.УС#MШ+Ž)S'!5ZэЛЋ˜Ж ;*Ž tђTŒ‘ЌМbL>о#лБНтЗVЂЈиКЉХ1Џ<ЫWoТШ)Г1"7‚НdxvlX‰5{Т[6џјЫ38дшХЈБ#1rќTŒ.JХыЯ>‡цd2~QќљЏЏЃЅ=‚ЊУ•”aцŒRьпЙ+л1eк eЅp’6Г‰б§yѕё;QкDq‰њƒXз_ѕSѕЗŠyrЊХKPйъџв)бЖцДiгŒ^‰92ЯvыўПкG<Ўjyšs>X:OЎиOтy"јнЗ>ˆ?љ:М#‰ …‚FЊf˜@O’СнЯДA#=ГІ †Юg$…ъм2ф3 2]€“Ÿ$qвѓљHfyLfžш№Ž–C;№йвR<ќђ:ЦмЭxјGŸЦ­ПŠV2zюкЖ“tЯaF)Yфѓ—ЄP[“вI ћIоl^ЛOmЌ24Ј‡fЄЃь+I>?’“C\шЈ~-ьЙ]KšDЃІHCŸњ–Йя0ТџJЯ^иХЗG SХMŸeДqŠIDAT>нш644є)%˜ФDo#W“IФSCЩ7ˆšКZД†›с њцjЎъ WpоЂcyomоaдI] ‰Ы”ИŒ‚š­ћ } ўJгѓў[SuЂC+Єaуfрќ9Т%PѕЎЕмF)РЈіх#dћ7(~ф’5иЅzœž<*H8ЈqkЖ„Ф”)ЧШ#г: з6pы3Š!ЃFЃtD МV );‡J`Х(т@œ7d%Й;&Sg‹GSCtNЯн#Ц–Ђ /Ѕc БКЎR–™ƒт‚!ЄиМЙЪ™Х()*@ИЃY”в4pр p„S{Д§Т7•8E‘–=“Ч•!ггˆс™+јОЖЂrпVTДјаFcˆЉЩF%Нp8F‰єЄzlйЛu2ˆ}ЧеDFо(L&]‘Н•U^ŽВвahЈШB‹7‚zщ qkІЅ%Š9ѓЇ"'=„ЖdžиK‚Œ”$дДt Н…iВ3БhV&ЗЁH]z6Ц–a§i?y>с]ƒ—Щ`Mš5х%Й\yj;ьшО0аgm2'јг[ўЮЄт;œnиmPUОудїьйcŽ#‹Qз­mM~]};Ц ЈRVmШв7 "Юd‰ЯЋ5g€qтХКЕ~uЋ aGў[вD~§ќrœ;ГšјХ=‡ЫўšъŽ`ыŽ8мРcк…ХV”‹–#•ЈnhсмR‡p4ˆЃFРOff§Жhр{3tиpфчf!к\ ;vЁХуC2пЅќЁ…ШJѕ‘a^‡Šъ0†ƒМєЗ3‰1З1›ЈЬžJ:nf)оБ`2’oТюxcюўyGŽьЦ–э<}Z‚в’|4зТ‘:nCsОkЇaбaХ™<єБўœ”—цвЇm ZЋїcйв0<Щ™Сq#D†eпž-иЕŸRС‘cP”Т}•мЮn6[šE%…8Мi'*kУZRŠТмдN)ЁС,ўйИрЧЧ‘ўA=C%Я?иgи#ЏЊяЏџpYaњ3{2YgkTЬ‰ЋX~рРHЏЪL™qޘbШFЂ6u>&,ћў№ѓ•(єV"Љd1.œ1Z‡ИКŒoE\MіђДF@ƒЎЋ№Њ д0DФŒнIЃЏIРMф[Žc7•N:ЈШ}№ Ž‚jОАOW`З|UАЅЊ ‘^щtДP?Ты ЁКb7*˜ЇЌ0› АГЄеа-›АЃ4ЛWlC~ё4d$GЩР7r{Ѕщ™CрЋ]‰ 6ЁоЋ<˜•›ŽнэuдЩи„ #ЇQ”œ‹u+ж (iVНЙ#ЮœŒ<шoОєжet1ђ#Gєы7-У†ЭлбКwъRG"?й‡дсЁЪЋС•В(Ж-РA}жnиŠ|ovyГ0™њ3/ПH7\hеNьЉ<„щeœšсШежP…•Ћж`кY—Ђm[+%ѕh/d9 Эfi#удмD] 4ЭuhL bOЌlиЕЙEЅœlЉ—С д7йЕs ъИе;†ŒЦОЈ#ЫЦRЧ(?%;сцF2mкDkGmCŠЫЦЁЊтilкZ‰IЅІќјgь^єYЛщ{~ї–п7}аHž\Щ)ф„ІmGЅщЋoіЌ+бo•ЁXяAЫKМ­8ILTK‡“WCК†їAЭA&}|н‰цЕc‰SйЪпs”я-Ю,h™КЅЅ#.ƒ—Ÿ {>x.ъзЏEХа|ЄqОЈЋЊР›Ћж!кV‡ŸоЛЗ|чјі.УЄ…_ФЭЗ|+_xз|љœ[С›міѓ6oУЗ?ї|хJ,{єNќqK6.(kЧ 7§^Xљ2жсЇџГs&‡№и +pУGЏEЖ'lЖ8[ZšQpхB$Н№wьўФ;нЖ› ’1?йЯїzўяg?Bъ”9X§‡'№ўO~%бu˜8ѓcјђ7?‰ы_G[оŒЯjСї_HТыїп„ ‡o§шОМћy|ћ‘ŸЁ,xЗпљЬšWˆ?=љ>љщ`щН?РЧoл‚ћ§:яX†{я]‚ѓЎНI)ЙШMїѓљ;К\Чђlхьѓ№sэбмКе;œ^Ћšљ‹уЃћб˜/i”lЉ?˜ї§?QcТс.FЙ§ф!У1§]пFaeВ2гФЫ=ЁаK=‰ъЖqЇ ъ€ЩЩЩƒВФу„]цфdР@’Ф!wиLnЊРС}{ЈРЩmˆqpц9g`5ХЇeХ…•"DmС№Qд'ЩB05 gN)E%™“a…yHЁо‰Л=•ФСo7ЗO<х˜3m­yŠg BLутќ ЮТ2 лЂ~œyС…(HOApњ дrАнWнNŽsсЁ~ЦКЕ[шj1&Ž,Fr4gSрАkлdp›eЪœНА7K‰‹ЮЇž їКЫЧNDnqЅЈYJНQNА~ШшƒьІThёЙ (eЩРм ЯХЖŠ§Ш.ѕQ[C˜Ы2S8Г‹qЦќљЈиП9“ц!Ѕ™:+dд&ЮЁЎ ѕY‚ЙУ1‘ух1(1M4Ў БЈ-Š-ыVSч% гrђШ„LССCЫБЇЊгЯОўхЫБjеjЄfЁАhiхVЗmЄШы‰Д`уІэШ> 3Ц5“ž№ь>IŸиЂўъˆёa$ъЛъЋŠ?– 6‰1‘tDeКR’“ноciSПy‰™Ж-$™5у2L(№сйППŒ2фЗ}яЋ8ФЙ#-g(&+ЧўŠэ”в‘qЇ”-?рХХ_И7нјќ#ы—иWYЬйЃ0ЁМ{wж!‡‹ŠšxэЉНјЦ/ПБЉMXџШNJUZА{у?АгWˆwЄzёчЇVтъkЎAaэlQт/НВтёчуЦ Bxющз0Ќу nўоашРŠ јъЦџ>˜}6]p%FN рВПŽЯпј><ѕРїБчтsяŸ‚O~œ\;и‡Піх/рsя‹9ХMxz}ЧeюРЪі.LOЧыoОˆwз^GЅБBмћФ xягАщ…G(9‚ѕ\JŠrЈ„ЮўЮSџЊA,ЖЄ&zЇє‘ЄPŒИћŽ%jїРНмѓѓPtќт3cЮЛnDSхJь>’ђ)“ёця~‚џU˜4~и1ПМ‰ˆДqџмh@ЇЌ)1і„ :•`OfЫд­sŠЪqо№ёїNb"єDѕф Јl’™ŒФhыDLъшq”GPY–У)ѓЯ6/•sкЦaLЂ<нR0vЮ:kEЦ:eBeО`fMЂ$‚/ЁŽѕц8‡ГІр–†$)йEЃqaёhоgzж0kЫf:ёвЮ•:х$˜8ћ Lр m&6–U2v JЦL6Œ•|б4™:"Є]ћыbL"мЪё…ђ0чŒ3‘MeCО‰АŒQ“ц l")рDЋг<Œ"ƒ5ЬœŒ‰ „ёгчa<)™ O{+ŠІž;џ{2ўєЃ›№_л?Œ/^%ќ”фtpАI,?ш нS7^яP<#я2%bЬЕ}щJ угФЗf`Œ‰ЩСŠ!˜’)$EлjЉнLЛŒpЯ=(Х'‰IgџXтP”Ё*X[ЗnЦtЎ(д‰OV]кš ъОZХ;СЁIЗ§нщмT|уœЉ~n&Om[№‡&›‚’IXЬI›C $…ЙЎŸ {*Э} ’“Шœщ›ѓвhеФІjs —W>ъrI™OБцHЏ‰Ѓђœ‚‹щe1MTИ3дЋўlJ2оqRE0+єrђгЩ:S],Џ1.#гgh”иUe›LЗКям”^L—JиUЗ'ЦLhrƒY)Чкч2~№"в$N9Б MyюЕ[Ъ‰ћvŸ…Oй^иО}Лй—„ЯНwЌдЈЏH‘RƒГњНЄ&.ƒт–­Ктіјk7Э`т„Зг‹œмЪЋпІ„qъќŸNљSǘw—2iMM#†•ЧН?љ&r›2XѓФЉГH šёtч†\ьyц^ЌОєZЬЪd?ik1L‡Ll™‚uEvэ\­јŸп>ЋЎ> яџвGёН[ОŽ‰х…hŸ[J§Џ!˜Йш=xђ™ћА|eВYЭ9у\d†иі9?™†къ–С7~~JMGVй5@йј…јќћžФѓKп@Y–ЃІЬGQШO#‹ВkУу§TfomwžYИ’œэ)™ќкїюBqуYXђdџўг™ю+СьGюРВEШJ ‘n1ЏёPJЫŸў+6дД€bB”фщб{I \хlч•бћх„„Я&б3<Я+іОvЋ{§ЧЅз-C§G1'zЗd§;??пŒ›њн3НђyюОћюшѕз_olLФ'}jOўuf/š„6_*ъіуžлnТR*ОЅЕq‚9†™“J№ъы[ё•_ўяX˜Ge (–=є0.œ7лјжщйЉ]bэwп7 ZеееЦg‡8LйбРц=/­Оєбžu]]]ЗћnКSх[єjП~чЮЦЈ”,ŠY‘XћŸ=ш$ Ч(#8%кBЌ",_ќЎ!ю” ь”%BЇl–TVVšAt„™Љфœh sпOЅ—С@Н—в‰C5TщTўЫ/ПŒ .ИРиѕљџэЫo[ЧЦј’D‘ЉЗdНь8Jъ8Nр}pbЩТyЮЂ№Ђ›ўнtзu—њttS hW­YДйєЖ@ъИЈн$vj)’[/‹–dQ"%іћ†›&)‰z“ђ7Цѕя;3їw/я§xцЬУэ[[ЉМкп†ЛпUФй™Дb Z `ЉуН™ЁŸR6dЉјgMŒк"тЕFmЗNX2ЫkxіХmqюКLрЌнLпЅq D №Щ Чс6owчluё+ћљЏўmПќХЯьЙЎ0оХіIkJuкБоМй ž‡S-лAїv}ЎdЂћШЌН- ЋGкЦЧЦ0М#ц0/ж˜Зє"FЄ&cЖžУ"ФэŠ…lvCŽ1—‡AЇaБyGѕжЎ>чИŽ1\Ш ПЎБЛŒЅ\wgvЯfDfNД4т|f]Єп|sЪСYП5`(єПjџ’nГ…оZТ{ќцЭ›юоПpс‚ћaЪ}•в“Ÿ7•іњmјтР6‚1{ѓƒŸкШtкОNь цZ D^Ϙ¨Ў8д~IF jмЊЕx|˜S`?0Ј&бщSљ ђїCј0]bПч“—;Ўпг ?ЌKЎдп]њєБ…OѓуciYХљйоЭіѓо*MХe—ю; ŸiѕgЗ(E CвŒŒ8ЖйЙm-LpAЉЙ@z Ц–c8р Ь–YєЗ-‡р4hB?wтЅфъoVГі=гМс—’]VJ"P (FќНЙ_эaДЬœ?УЧџk}є‘ћМ€1ьжм/AД_чshхђЅ„Ў˜0ŸpœцP•z к)Џ˜ОTŒєЪћšЁшi-ч3Ћ{|Ы7 сМмТB]СtЫу‚э\№Л‹(MА[IЊ&АеMZuAЪ(uB€ї<Л5_yrёАž™™qaщ/VЭƒЛNNs_›Щї GweрXЪ7?s80d(оП>бџъвЅKЎЛ’#3)њЋyоo)LX+тPУU|™и]УЩЗrnј!†џСk‡sMSœ@ё гZD@D œа\8-<чфЎъЁ]^’Жˆ@m№"›‚d;–ШM„IСqŽб\'0сV"2v SšЃєЅбŸ–b%5’E%FžМ3Š(šw&0ЬыћЮ’R›Ид*Ј ўWdё/Экh™Z!Л'@ёНн{{aТ(…kікЗћэзПљ%GРг8ni„•žxБлс$П’fDшK"єdkЌ“emўѓOь ЬЯ@ПDmЗAЛЧ№l–р9ћѕГIAg-G€пЕНњОэU9wіЊIЊ#А“{{Ca‚яœГ„tї$ьЧ?:mWЏ~m+O\ЪY†{}+О†IЧV2@3!Ь‡ЭLкрw†lј"YbшNTнЉ*W1Љё ЗWг‡W|МўиЦхЁХЃвh‹•ЈЃD@6&DCqВ‚ЩЖ::cіЮЛ/Л/ CN3RсќТМЭcИ[У>нджшх {б}УАгG!.Eэп ~D ЇRп(Š^эŸ‰Z(ѕE и<ЭtZUи› VAЋ‡ѓ!сь‡nЬ œ[!Br*œ[ЅсЈбтмЮыD–’НЙ6U•ТыгззчTф_шЊU&] 8ЁЅ„?ё.ŠгЁ" ыЖ&ЬGЫ‰%…nŽЧ*,nџФgўЭœJK€š”D@€КrНj>zЊ&ХЇ-П‘bЕёЗŠЕqд ниЖ0й}•{SBСrГ7eэw)sћMXх‹€ˆ€u'L|ПnщTсЕxAиV.ьƒц"R‹WImЈ%u'L8 …№щtк–––м‹П­'!ьbЁЧ~kkЋ ?ЭQ3;I^рьфX#" " ѕD Ў„ _єїяпwѓJФуq7;-@5–/^|оТg[~ЙJѓ–чиz Ы •„ŽЉЪЫЉЮЙpлv­CdоJфлЗнr”_D@D@j@нŠ’ёёq[\\Д—NВцht[Ax<5чќa рeoœ№ЉТŒOЅyн;јЂЗЗз8УтѕызЅчиБc.оHЕХБ-6&’X-5хЈWu!Lh)рЫyvvжЮœ9c˜Ѕ/щ,ДŠp_ё:ЛМdйЕ E›!PV!pY мŒњСѕй“9цЙ `“˜ыg9Го” W]0­ј2yС§п~]zјэьЮс”ц7nмА(U2™мвrТcЈŽн@‘HdУs-­SŸE@D@D ž дМ0с š"„Т„жџ™ы’,yXDђљ 7эЋЋзьіRво>wк‚kьŸљ“5 |ЯЮщ5DжЗI.›У? 6ёХчv?2hУ.Z‹З pюŸ5 žѕŠŸдуЙ”5ЧяgћiёшююvчСnЈЭкя bњЅјЈ’О<П_k8jъB˜ЬЯЯЛnNЮ—4§4hE)~ЙПДЙнц:€љYDЎ]…H `Vd ЮŠМ”YqљвSпиЬУŒ%;ЛЌ3…."ˆ ••Ѕ›}0y˜hЭк:;­лyЌЋыRIRм&о,ЌŸ– њœА;*‘Hli5ё7›Bќ{Z‹€ˆ€u5/LxјbfwH8v‚€Тd жЖT _Д<|HrYи8ђіро˜]ПД,&“3 6дДє77эЛnэ­1ћзе/ьэwЯCLРв‚B2 їэїП§ƒ%њ[vцžE^ЖЗоxB'gyˆo9)ЎЯџ],ŒИmdћ›жЛЁ|Оjж›_5Ч+ˆ€ˆ€д @Н4ДББбY:hэр @`ЌЏљтцТЯХЛМAŸПС–чlzfЪfІЇmq9kaX?юўяKK/­Z"йbгЃ7ljqйBNёИМ…ЛOиЙ эƒїЮйтд-›ZXГHuЏзчъXo“ЏлЗХЕ–т<єQЈL .,&Д>,//?|бЇbлEСгЉ XжрGвwђU{ѓ њ˜ЬлЃ…‡˜„0oС† …!к{†э§ЫУАœDэЫUtEPŠ „a­iВP†B%_v!aDKYMeu?i‰ГђРвУЎ(њ›(‰€ˆ€ˆ€”Ј‹7$§Iќ(o} *($хЇЦ-№Сш`Яю™ххјz`УZЮВ+Ы­lшдiћtєЯvчЮ}kЪч,кец†gsА–Dš-3ё…§уЏQЫM[{џ)ыmХ8Гa‰)&•лP№3с>ŠžлЃ$" " "PN ц… ­%tœœtё@:с€ЪфЛMЪOЉd У•РaфФЫЏY?† (VQtЯМc ЁЈ5ЦšьяХьодЌ1|И%Б‘ГпЕчБoueм"=ƒ644hБчOXGOX~ЖŸ ­$юL™X,цЖ•ДTE@D@Dр™'PТ$ БаооnЃЃЃЦ‘9mmmЮњ@ _њ[&d‰&Z­ЂФYL /’Љ(ŒUtчЌYKВгFкЛс[AcШ„X˜‰ирР?qвЁœ-ЏРщ••wUnAБЏЩЬЬŒйРР€s‚eл•D@D@D@ž&PѓТ„Эe7 УЙгЯфкЕkvќјqЃх„СЪЊюЁх/оис ќKBa–П.nр#BlpЃnэУіжыƒ№-С( иZ"pРнNЂu„ѓљакsћіmыыыГT*Uѕ0сэдЅМ" " "pд…0ё ЮЃsFa9Йuы–{ЩяgTTп]”ЇeЦ7ЂЪ5Ѕš››s‘[)ІhщQи˜@] ž-%Д:0ш•б™tПвcKЪ*рБьvъъъr>%є1йMy;h‚К#PwТ„/wОфi} пI-Пьi5aћќRww‡," " L ю„ љшEРw‰Њ"№tЄВЊTеˆ€ˆ€ˆ€ˆ@%&•Јh›ˆ€ˆ€ˆРЁ09ьЊTD@D@D  “JTДMD@D@DрPьH˜аљ”#c8ъduГу)‰€ˆ€ˆ€ˆРљ. ‘^:kяFхѓ˜p8ьцАёГўr›’ˆ€ˆ€ˆ€ь†@ˆƒбT)LhЉ61oSS“;NЂЄZjЪ'" " "АаgŸ}fWЎ\qсгЗ#L|Ё;9ЦЋЕˆ€ˆ€ˆ€ј?ї[Ч*+OуЊIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/create_and_add_to_group.png0000644000175000017500000017554411733011756025660 0ustar sylvestresylvestre‰PNG  IHDRў!eUˆViCCPICC Profilex­—gPЭжЧ{vй%gDа% JЮIЩY`%gЩIТВdA$’Г ’ƒ( ‚JFrPХ@D$Š ёєтSя‡Їю—лUS§›žŸю™ггЇ”Н68œрюсƒзSSԘ˜šaG0ZРDmьМq XьXђ/хч{>т;Дѕ/ЂkІРУёТ:Ї?,ШЖир§}p>АЦљэœmьa†™o ЇsЬNИюmџpя!ћй9іMуaятс"ЬчэМэрЧ‡у^ВїЖs‡9цwwOи>хЁ}n;юKY3ЧсwkИR ЯšјЇЭˆ€{h6џi;РБTZАџД­ы§ўV§+oGспц 2EPжЙрЙСњН”ƒƒЂƒƒНbуц~tџђѓсm/S_:П6|Ѓ2$ё–чѓ{ŠрУъ№єШаhЧXЭxёDкЧ№Iя)ЧOцŸѕЇЕg4f•ПШЯЩЮK~]ќЦЛШ§cщд2г УъБ5šuЊd?‰7 ЗаПалшд.j`qРўчЗ ~ш=Ђ™JP‚&ф%КMBMZAЎFБCѕˆO'rlуx Ѓ; sЫIнSƒЌвl ьН?ИhNГqѓђŸ‘<+Х+Щ'Ц/"Р/Ш-Ф!Ь"rL”T ˆ­‹ЯH IЖIUIgЩ„ЩКœУž“c–'_RUьQzЌ\ЈЏъЏf­ЎЎСЏIЇЙЉ5zЁQ;WчšЎ-V§ЂАFŸRЯ`бpдЈЧИЦ$Я4кЬЫмдBЮ’ЫŠТjѓвŒѕ{›л^Л.ћ‡6ЧЇчЧ.еЎх—‹мВмSёz‰2ЩtЉig]Y‰s'ЮэŸŸ–ы•ЏRШP QrTжQS=ЁКЇіIН]ЃH3\ЫцТ9mFэ 7КеиЄ‹x=c§sь†D†пс5pгдЯЬа\д‚кbйђ…UХЅ8kœЙ­–Œ=ПЦ‘Ц щДюќйeаЕљrЙ[Кћ5ЫžІ8M/yМДЗИˆЏПџй€гlWX‚ŽS]%!?сн`<ьEx}DщѕфШ (ћкбb1LБˆиЙИёв§“Ь’ЯЅ`RЉ3iнщe7Ѓ3œ3еnqeЁВfnЗgфчšф‰хSчЏ жe‡РkAЋT№юБЛлe“хЅїbю_ЎдЉЌІЋо~0ѓ№ѕЃіšЧЕхsŸЄ<ЈѓЋwn0kдj’mцman%kнyЖи6бўВуYчУЎТюдž№^Џ>›~ьsЙќ,/Щ_юНZœ=§fzhіэќЛХїЫж†7FЖFwЧі'б“фSŒŸx?ЋM;Я$Ю>ў21ўЪЗ`ј-dБќћ№2ѕŠхjуКШцŸ›ЫПvЮьіьлњџOь;Œ hqJ0@ŽQљkpe@–)-бhœ@ ŸРQќ м@7ВРа ІРDё@АфЅB•P?4‡ @А#ЖˆыˆRD?bI”CК"3‘=ШmA7‚ћ+()Tъњ : =J(N˜NИAdBдBЬEœLМOтIђ™д”є-йEВзф†фуŽы”сTдTдBд4&4+ДёtgщŽсщ™шЛћ2p3Œ3ІœP=БЭTХlЫТШ2t2љдE fŒЕ„Э‹]ƒ–cŽГ+юД 7;ЧъЯD5тхс=рцЏHФ  K‰0‹ь‰Ž‰е‰ЇKр$uЅЄiЄЗd&eћЮ=9_"—!ЋІxUщЊr˜JДjšZњЭQ­umJ~],жчbŽ^ЗўК!Л‘ЁqœI‡щžЙДХЫ–Kжк6YЖѓів ŽŸœE]"]пЛqЛ{ сјНт№ >кО§Т—ƒ,‚ћBDЎннЗшŽф‹К ХxФNЦы%є&Щ'7ІJЅ5м<Ÿб}ыbжdЖW.*/Ї@МpЈ‡ЎДОЬК‚ј^mЅU5њСНG:5ЋгŸJзM7$6Щ4kЭmгы ъlыъщћњ3Ћ>G8пГГЈНDГ<МšЗnПqіч­жэј]ѓ}опћ |”ЦРD‚PžƒА ƒ Ш nCO !hA‰@ш"МiˆЇˆq$yi„Œ@>BЮ0dŒЂиQ^Ј4кнOШMCИHЄGдHЬIœF‚$ё'љNъD:Cц@6OюIОMMЩHYEЅL5FэCCNSFЋJ;GwLји}мqйуk ŒŽ'8NL31[ГААŒЬ9u У‰Ybm`‹aЗрц$хќТеq:Ÿ;{†ѓЬжйоbО`~qСу‚лBSТ}"ЕЂbёт~–’ Rœв$в+2УВэчЊЯчЪ%Щ‡+(z)Й)_VёPѕU UO‚їЏЇZЏ.,шщrcЕ.тєВє; VиŒ MтL;ЭЙТЌzЌЉl,mялР'—ћЮ„.іЎmnЬю>§8VЏќ~пDПхƒРЦ Юр”pЭ+t*\'Ђ>’5*цЦZŒEl_МDBYSrJ*QZxњAFHцAVx6QNJs~EЁtб@‰ннЛ™хЂяюTБTwkщыZa/ЖщmКUЏ˜Š›…˜їYв[9^ЊГ!ЗuА{цpЪ1дiЦEгЕже=Х…ЛтЕŸSпљЉјзr^ЙLy5њAhD8*"6’:*;š+І:N4О6Q Љ<…-5/љfn&цжлќйuЙЊyя œ wŠ“яp–6–щ—П[ЩSеџРу]MгcЧЇдu- nMєЭ­fЯ~ДЧuВvеїшї.ѕЧНрш}хњšьMѕ[ьЛoЎŽ GЃЧ &B>nNy}Zœv™™ћт07§еzaxQэ{щвцŠєЊЧZцzу‘Mъ-о_ъл;сЛ{­ћ“‡ўџ“/Ц€rбЖsЇџmqwѓ=ВI[&ѓАеб…k"јšЧљ`ѓРпьэЇЏrФŽ.ЊGloЃЌuФWœ•tŽиЏЊwФЎ6šи#v№0д?bœляќі?c)ўе;xЋќе\q60>ву}ѕ јВЇж_ННƒђпЙyИщ\8вИјhќ?pкРи§Щ3a@S“pHmЕ]‡еџ+>p €’'.ятфьƒQ€Гl^Œ†‡?/FXPP ќЖђ6юЯ Ц pHYs  šœ IDATxь]`EоzНхrщН $єЎT”&№[QЄ (R *HЅ**вЄ(EjшНCшЄїž\юr}owџЗ9B@AwФЫоодowП™}ѓц4;;сР ьПдXО­<<џPХ0 >џ%эЉѕf№д_ыѓђ№<РјEхццкэі'ЫщП›šЇўџюЕч[Ю#№<"МŒфШ‘;vмО}›eйчБЯМЮФ3Џ_Њ#дo0LfsЇЮХ"У08ŽW=9гЪOѓђЗРѓ…аНNЇsqqЕлЉчЋцuЇЖМСЇю\ О&<<UB&xеj'р}окS%М*‹ФSeЈ№чxxъ6 ?ясѓиW‰ЇўЧ†ŽOШ#Р#Р#№М"РSџѓzхјzѓ№№<6<ѕ?6t|B"І~ЕебЉ?№д_._ZC€EЁˆРю<ј8)L–тITЧEђN>eєŽ …"pЕ”Š!sюЄнFбLЉЧ=Š‰Х‚ВЈеj+†“фNV8AJ%PŽX,>^†•”mˆМzdˆ“ЉTRЭD•ўЌNUЏЕЯЊ–|Й<<5‚.$Ўmџ§zV!ŽqBБчvюЛ™/‘ŠЂ7œП‘„сA $QТЊ(A’ŽcˆŠУOхњШч*—OфФь;6,1bфЈЯŒЭЗ‰PлЮО?žAЩХBHˆXВ~[qдD#8№Ѕ€,щШO р\ЮP, pg=‡ЃБAо>{ьи1Рˆ–|ѕШЈQ#GŽѕэ/hШƒЋ1: (ЦeM’\ЭQ rƒП5|uT~„Њ:2)Ћ|…@Щ[ЛзФ$eB JN”4Z^в^ЈС5ГG>P@вйнS&ЮО™i†њ—ЄzЮ>žЫJ?gѓехЈ# ˜Ю_Ж'•BFг%п>u6E' SЯМš’‰Бд­ГїžОaeP‚`у.;xі6‹F]AzZьХЋ‰ЌУŠљиѓ~кJЃ\>@'З-њщ@мАQукК$ѓбїZ;Ізъв“ЎG;•gІqwrў$ђ/я;|С`C KЩJМКwяО”|нЎ5s‡К8-ПиŸВ?:њz†Ў„Б9Ш}ќвЕsЉ(М3`„Р”~~ђœХњ0ьaўЈЭ”—Ÿ{ѓъйД| СZЮ‰>~ю2ƒ“ŒYŸ•W/ ™&;c(*ШHО}фdŽ‘&p4§Ц™НO˜h ѓ’Ы‚‰Ђх{’єtxмЛГё1'9;›fь…yЗЏŸKЮ*6ъ 3’oDхђЖ‡>2#'%1ншшQJВzž>јеМЯгетыЪ#№$`™}ѕœ[#W5УкРОƒ!P|„BЁXšxlйЇыnішўvлц‚+ћч/:\фBniG6*јcСўФ~Ц6 DXšЫчЪYЗHЯ'БуŒю№Ю3Ч-kнШ­Iшдыч>8›b”ш‹FoMЦuПNXєAѓ#‡гјюїчA„>”hў AќWпŸ‹hW_щœуцQqю ф[fЇ ;єї/™&n/жf_k6рЈЭНХщƒ{}›і}ЏoЦN8Nхоњbк$2 ѕа^[ўўўDЎЇЊ0іFжћ}ƒ :eљ|HзНЫП‹;/qнзћ2Єукc пНюѓщТх[МжˆA€љЁџУёќи+ЊPUЈŸ'‡ )ˆй5wсоќ(7С†Жo—}МрЫQ&зШwџ7тђп_H“К kн\4хнАf-šоFŒ%љ<ЩUyFiљQџ3ž/–G ж 0ътu­Ÿi<ѕ?)‚|zч”6rВ/јЕˆТЈ§Ёт›б'22“і%аR…Rтоxъ„aGWЬ;t­ 0ЪYЃQ}љ_ЪЦКЊœ(Ъ!“‰вЦтьœ‹~Э#Й|X†%TmлЏ§yqzсфю%W М›;i Œ)ёiзЏ]Бњ`b!f!M€кнSѕвШ1ЃЛ{зWЦн:s+..ЛА˜ ХКфДL=еЅяˆіц%s—˜P˜хaц9эЬ6MЧц2„†W;…FЕosl§ю37r/mйЗПbеJ')bЙHMПrхкЙ›r'(.+9эк…{ngР žВА‰\MLžvЁЪ{м‡бWvmи}&рТБv*3щЄoыЦХБ9Ы м§eGїюћgз†+z”`i…\Ѕ4@g‘‘˜~укГ7"“НЖ  /З пH1ЫбsrмЉ&ўёЧ?_5цkЫ#Р#№8`xqЮѕm[sОеЇэ@ІА жУ? №Цю_7ьtoбљW;eœўsщo{ШЦнћwkе4*ыдњПv_АЋызїР0e`ЈЋ„sкС]іЕэлђОе$4Ё&O`Ѓ–ЄѓП­пt1[>jъGѕ]E…љgіEʘћжшЭ=эЎ}cТЊќуk7яO1kщЋПВmэж#ЄoT›pПўд+”Б{?ЧДycXЋ Ы BBЗjЩБztѕPK€’Y†–ИFИр+љѕј•јˆ–/v‰ вл˜PПЙ\ф'лђгŠs…Ђ‘Ѓ‡yj’іo?–PаЌYƒШ&-RЏорќ…+YƒFŽ Ц—§А"[ZЏЯ зМфСЌEБЎO№жK$Уu0,6i’}эxІЮЪъ-КНl5™ƒќƒ”іъЅ\€|~№~г`ѕйэЋŽоHЬЬIа„4 tq‰ŸЋРЫЗ=W—‹Џ,Ру"ЖŒќјгЧве§;лэЬl`ТV@в4N2”ЭŠ‘"Ы kЕйv Р#“a; ц–Ввœ!ђЩ‹;}"гЙфCqі. ЈА sž ЄoЇ˜D(dRќ“/ШBњЬќd€ˆїei Хр |nГ3ЈPLвV;ŠУЏ,˜hЌ ў4ˆ){Ы‘ФN/Жt’РYG1мф*8Ѓ‚Eцd­6Л€Рmœ’єGœo˜Б(Ј&ƒРФ5з#Ёc-^НfžМнФ7У•‹еЮ@{ Д$šсь;КфѓћуХ§Лдg чDd]й7oгn“Ж( љРIяі ДcЈ5kч+^јш Ш‡Ђ№‘X€иЁЪмXяTѓ9јУSџsp‘ј*ђд мЌ&XцKyД4S˜V…QuщЗ*ќ}@>аp„[.@Ю4eЬЪбiм\ЁWЙїЧrё*=,)…яп“%D­^}ЁKƒe B˜ЯЈЌШІ:ЪcТи-yy4.vwsССž_šъсљ”Цznўђдџм\*ОЂ<Я'р] sƒзVkюыY0Wcx#ЉаGV?ŸGє #№ЮЯ|Оhџїqh-7Књ}Nх5Ў~>ЕмаjЧ{јT .>2РПjŒњСРспаhО <<<џmЊJ§@њFЃбfзW>№№№№<пT‰њїѓђђ’’’јQџѓ}Ељкѓ№№” P%ъя* ~www™LЦуЦ#Р#Р#Р#№М#P%ъ‡FŠХb'''m}оЬзŸG€G€G€G Њ>АЎЏTЬšG€G€G€GрљF Њдџ|З’Џ=@9xъ/Ш#Р#Р#№п@€ЇўџЦuц[Щ#Р#Р#PžњЫСђ№№ќ7ЈЊЧЮ§ъyџ |*o%Ќoр—8T –G€Gрy@ Њдџ<2†Сюk(Т;5 NоЯ#&5ˆŸРѓ‹@UЉПNДИ–У†šАi„cае WХ",OkПlwUcЁ~ХRмЦD5@а"88˜Ўй.ЅfЊЦчТ#Р#Р#№hžъ‡qЖ bM:ЫО}ЎЈуЬйСIдFш’]FKZ ŒO(l)TPФlоR|ќЂљь5k€б:RдЕЕЄE„~…WшžP~–ЖС*‡ТТB~­УЃo1>@нC Њ[ЕdffЊTЊкf:ц ФЌХ`O:oЛМгvљF_{О!r%щ.lѓюŽ{дC;BлDBTo`Џ'иЖ4Н`Ю/bиšG$Алэ6ГU)fн\ˆў]ЄQѕ„‘ЁмЦsV+lё8*Ѕеj jЧЉ/Ÿ†G€G€G "u’њ\ !lбЩЕжГmзбё'0QJ•ƒКа„и­ъь& ŠBї5ѕиИG{ђ’хќu Й”JPR›sТNЫˆнЦиlTБњ‰iеHдИ og™BZВOELёЇўGФџЬ#Р#PчЈ{дO Љэ‰gmWvлЮma :‰QЈDЮ B€УЎœ%ˆВАW4ЂЗаY…шйќ tЗhЊж€рbЁЬYB:)`ЗMи’™І9ЛЄ€нж`ЃиГЕSVmБЁРШXlB!њсЪЗ_‘йЋ9 ЬSПЋљ ђ№<:fыGqы‘•дхьЩчp†VЙ*œ‚§Ѕr1NbSbжу>ЌcИŠdcsТЧЦNehD,Eœ"\TrЅ‚c ŒѕiіT† ‚sѕqt;ъTXhбfѕ ЙыwКЕЛ8с7xxxў;д5ъGlЧ~Ѕв0!тфуффу*qwG„J„!ИСsдtNp–мndМ)SШкl5&ф 6+ю%SЋм”˜ZŒH Фp€‰BŠЌHN>•ЌЯKб2є”•6шYГ…х7ћямю|Kyxд1ъGС\<„@жiк‚Ќb‰:WSЯ_цJ8Л "— (дйŽ0FЄ8…І-‘И[ UPЄЯз'фчм”КеS7tђїid˜†ђђmЉщ–И ЙщГжЖЁJЊаˆŒйљ5Оу$˜ƒ №З@G€yшЋ.зёЫїфеЋsдCz‰RІv•Xђѕ…–тТЂФУ—DЊXч№Pyp˜ФПBˆЉм }мMKмЕд[О„р Љ’Р…ЄI ФL­/6š’ŽЄІŸЫroьЂё”RF{ъ•|}†^`тWЈ…ПšФQЛ9Ї†9иЦV{=љ…сsрxЊHЅв‡lПї0мЩ0IіTы№яЬœЛФsъѕ{ВB)"U‰(к f|UИйDхъ,9'.e_И&quЦHвœWhз•0§+№…ЛS&Уa ыv ”pТЌrжjЃ†”cй)(w0‚Ф%NЈ@ˆ HT€ %˜\‰Г4Sуї5ŒЄдjѕCžЈчрŽрЋјп@РbБ€пsЅm…gАфWСD%ыkќAЉДиЩIcYЦZїSUъвEPе@‚E…bDЎF,рПIbTŽЃrБнjFѕ&{~f6Х .DІAф$UЁ…ЈTŠ …ˆСТРъZŽщYœХD!Р$ Z—ƒŠфЈPS( }†‘ЈD†;ЉpЃБšž=Uh<3ж’P…И|g‰РУŸhАYЂq-QЊхљ,лPїЪцМ -ІІaъК?№Џ*ѕЉеЮА$W€HœЉЁLмЄ.ИhВt.–EйыЁ€‘<† Ž;ќ„JQДа€[)шnZ8‰BTfƒЙ[˜у}8$`Jˆ1ЙW(p˜†!DИ?+ЧyјЩЩЩЩЭЭэс><х‹xаqF№Р™ѕЁЄѓИжк&l[EDtєђѕУ1Œa(šЂ`" њ5р>Цn‡c–В@O D№Ав6KIWё ьŸзѓРт7Nьаf%ЃЮ2ДDсмАc?R(žd"U›ЭjБбЈ)уТИзЧšC”8Я@пЄ/(щ$Œ”ШЄRFmerєŒ,>œ}шЮ- vЮО/Р1Ш;` ІRс*.уr.ъчРSFЧёŒŒ њіѕѕ:vte4]Оp`љ˜˜—ђžp|іьY…B!—Ы!В#Йу |Z8vtƒ!66ЖoпО0тЌЁZ_сA,2вЌ†e№y™БЩ+чЈƒ7ŠЭИйЎ?Йсц™гЊрŽ/tЬ>{РЈKЩЫ(єk™tіЈ{›їB‚4Б›цчщйˆž(в'яЊUэZˆ |MК„ъbo”0 #ѓm\ЬHG=@й˜е=НЦД…љ„oƒEЫgЬzsЬ–m=иєKЙyCпYxjн/qiёЪФ7_ЮŽ9yёFмЙ“Чєќц+/ФоОjѓОv}‡іhцЕуЏƒ1љY-[†,7n§ЮчяѕtUјY y›—->“Zќо‡НШќoџL)§GŽЅТСЫЅzMЏ{дѕЧСмO"b%"sA,њЛњЬ8Ъb мƒ"~!*JэHArъ:E@”‹:<Чh1XaЄagсnЅaє2Э№ }'* 1C~XЛ+—bR)fГС‡ѓWяvсc?@ЪЎЎЎЁoрn x DS—QЙ#чИИИћ{ш<р}ПRdR>>|…˜џёъY>P?ИN ЅmИwџpOлщПWЈФИе.sŠєˆТЎь<Јlа8)z :PЁˆ;НыlƒfaYчї˜3˜”ŒB'‰§ќОm{'ъђйўŽQ S’jŸтœ$‘B#іnTdВ—Ќ6хќ eVЮЬдІg]jь’я~д*B=eЉ?џИgФwŸ#)ЧОјщаЇпŽ=МjХКmЪ@нЉ??љњђ9‹ќ=KОџБ[ŸО›чы;џгЕЫVt˜іmTЈ‹—o`XїЎBCцё „№ъ–+I­НЅ+]л)˜>qS?§ЋкlЁ@КЌzlV7ЉІpaZVРљёXђЁ+…ўŒЖбV3Hя”ЙБ’x…џЌНЄПъXь­+Ооžэ]<п”ˆЃ(Г^Ѕ“Йd‹0Рб,t0њ е Б §RL!Х( <€еыпpзђmxF€Л$xЪ—бwЦ‡J9H"8К„ еLHHHРЄРGкђ98ип‘ k#ц“|ТГ! 4 1k‰p6Ђїшkп‰ kзь…фу*ƒšЈЅ2ЕBX ЉкЏ—э:m6ћ6ˆdЎ™N!њ"‰и'ЈE&ѓu–ТxMќ$еЈ›iaр7j}ѓHZ@xKww0ю;ъ д/5€A^ˆв˜†›щкА§Л^а]9аЙGю›Їю:&"[tnнЮzqз‰мЛФy`пŽ/ПмъТт_ѓ rMЛoXПQaЮ""8ЂэРз^tІѓ4Exƒj§9xџгчф“Ÿ/4—yЕђSk™ѓ9mъ‹r[ЩьBесЊ“дсѕƒ˜ƒЬ™18S……V6Q"’ Щ,жЖVgп”nŽ6кэ$+єBp9n6ЄоH]‹Цџ)ј‰ЩўбTфє"ЬъквЕИ\B8УЂ^JBаjжЊ@0Ъ„Иf‰љР#P[Рs Zсeдџ b+х}ˆ +А ”Ѕrєe_ЫРˆІќзЧ?FA+WЈQЩYЛQР2*M@—з?]9i‰гц[IИЬнnO/Ю+„E5JБа*Хp)ЈЇ "їmўRоЖm­‡‹KАF%CAcы_`„­kШgљG4CяXjmi^Б]'‚О’Ц "sїєПю˜%цЊЅE &цзИ“ЋzЦ7sйфГYНЦ‘][Зcчj]жс‹Ю^ГлЖПДoЯ•Ћ НХА@•’@џ"ЊBМф§Е§–n8‹6щєвпЇжЄІцдєЮЮK3"Б6ƒвbт1ЦЛЋH§k#мЉ0 €яЇрђ†лŽ$ЩВЏе(­*QЁpйФQšbьfŒВIZ$WJэJqšЩњ“ЭАеФФйMЈ Чх •€7LжЂŒcLŒ%7Q[81‹–ЦrEO„gR(‘ˆ|4ЈЇ &ØЭn*Ђ‹ aТœkxjxj€”K&nВрЪ-{ІЧŽ“їзž8ш9чiЫrЈА“ЫЅbœ;Н_ž№‘\#КѕљKCЉЋwиєЏ3su/tщТŠ|eу&Šнu_ЏІ№VМшвHщсыЉёЬЭЪQ{{iдrNxёпX——`œžинA$zP“V(’р ыкцѓЙAЮ`mFЩАV]ъгXsфнјћ9ГŸНкЉуЋэš…l?/ Љк ьЕ!эBЈџЈnC@зY н`Щ ”д.С0ˆG}›ƒ%Вƒ 5ЮЄ pы)<n>*јtiзК!ЬЗqЯ'x[У^џТPТїмœJљжСPІ|@'DBцсьhЙLэn+Ž ё }Э'дqьеD#nг$РёUютѓjЧБЊьЮ{p/ї`Ч1|ж‹lU/ђЮЗО}BJЯWћUЏъ‡лшмЙspїИИИт%kІ€њ ’Р9ћ|p­{тŽ;^}ѕUp<€юЁДј'ћ‹сŒ6E™мSЬХš&„*oLюД/УкїрM„Fd~˜_ИаеW Уx1+bм>Н4,8aЁ_…UКрЪФ(ƒ2TˆЙ H›™\œ~ бЭsїЋ­8V/ZЛ.зœvS›tUлЇЕШг•Wl~ВЋЦЇЎj†gЪ ,їпЙvq‘WЯwКZJ^есЇ;D^Y†0ф‚QџрTH§ГћpHЫnѕCoЪЗдѓ'ЦїЗi"‚ŽЌŠЉіЏ _тП я;К$H2уѓ 3NкЖ;џ‡P?7њЗ7‡юi№МЬЭЖQ0—(„нЈ@AўpP#дt/‘жЋж%€aиы5RжЫCtъІ%­ˆБуијV’Ј@P\чCнB "ѕУнS\\ žХ0ФNU‘PXLСњ4–Р ‡ xzz‚ћj З,V>п(AЋAіицSыsŽХфšЕˆ„t‰™}mц4{QЊU›œ—xNа<7ип'Р'а™tЅQ{F~F|ZRьхЬь V—1VЦ IDATMИ„Ф‰œJw+?+ЅЄЌўф…aџ1o7\у„ƒТfљS З…ЯŽGр>рљ*уwxI­К™Ую ЩсЉ„ёЮpЏт№Џумњк’ls pўОbkщј˜dg‹Вa+њйХф-†C7-Q0Kqз ўшкАж‡јDЖї…Љ.АБ—ŽXUС МЫЅЅ Вsэ„ЬMуˆSю—:uШкВвsХN.*й=§KгвЕ.>^т{]Ь-†Тм|›ЇПћНW‘ехч[ //чърј0 юЭџA1ЫНЏСMі X5sоЮЙrbR'A“Wс™~?і~iƒL(УU&Td"}0[kЫЅЏьШО-Эq ‹s ”щГmYёХE9f Дк4Јм™Њ.*'ЊˆЩeАЄœ­НZG)›…УL"дР&-5Sa>* Žƒš№bу\‹ФС8‚rУvˆ?=шљ‚Wm№№7ЇEˆс5@&‡щ6…еb‹ wОфй„i^XеU…е|P/Шв3оNЈ‰f/чБЬi "ЦУ<€dЊI(§ЫЂeНЇж+Ѕ~є№Ž љ~}ЫSџя+f/^ИЖїШ…гGuЎљ–дXŽц/ІŽлМ9ц›п7іiы_–+eJњі{ЎJЗœмдРљ. ЇФўўD›АУіНГЫwhGЂзL›27Єѕи_П_–Щм-ѕ 3Њсфœ†{ &ƒZ вё‹kхb)М#[) # …Ў(ЉТ…оИ%IЙQ”Sj Bpи') лyСs% "Й‘ДHlѕЗnANB њn№Џ†ЋЪgЧ#P€ ІСK<ЬlпЁХ‘О#onOћ DФj‹N>ЄOEЖ№гpSnˆVъдd\Ј)†   ‹.#N$=Ж•АEˆш!e06уЩЧђѕlЃm=b8wј@%Зc$шя"Ь­ѓ{ngJДЙˆTY ЙzЃ6%QвЄы+o›ѓu‰fšЈЫ6bЂБp~Бщ .вLџтГ ­Ѓ:h”5РХ+тыOЧL_tљ^’b6ы6ўƒД?ЯЋй…–e\ЩAц…сvsмp\ђ,К’кмŠЕ[Ъ УЉмgх r№јЧXŒDp)"ёХœОдcЄf{9MOј‘‰Ф*‰тУHH­„I Фlх4—јР#№Lp№rй'Аtш7ќеvоV+З† дЪёYiѕJ˜Пь„IдЏМе/ЬGъ`№Ў@’мL@йЯЩЇвЬkъЄ€$фJX"I-ƒХczЈке ю5hT(Ћ(3щєЙ+зOџ1vј|#KЏ?ўЫЅ;/юлsсј-™“ффтoЧўыЕѓЧўљу€HЁ,МОГпюŸ­лЇ3Qžо~žxйЉaћJњњЛ9)ЪQ(WA “„…+$d…ѓ‰2<Ьd%яmЊvr ђu‡1C Жюn‡SiІ№b™—xщРщœзоxYŠ)чLІ^дѓЋUЅ)kє$<bR(&$Z[Ёгщѓ&чв LЮB рчс< }Ўc YXGЇ”( ЋаХ0; Œ_зя…‹ЯЌ"tь0јРг`t oŠr’Œ |… C„ DPж ј цоРПѓnTиАeчЦmИ„”Э ЂК‡OшЪжђСБc‡Eщ†"=fƒM^@zщєШ Ј<§7ŠHМ’”™p*33quLђ”?іНш]?бЅџВџШ€ЩП {бп‰бкlfЪ`”GіўuСL‡фqЕ0YЉšР ŸV’#ЗdЊвг•OkЬ›ІДЬ‡Q?чGPœњщД)‡LGЮя2y7ЮЧОјіg †VšМЖў‚l€` …EjАщA’–+ƒЇЅфљ9у)G§,N "ЁШYъ$IEBHwg!Lmе•/‡G €”СёгvЊТј ЮT’˜*фЦѕeдбрисФ у3AЉfœ‡˜•цP '=4јЕW8фяэšš‚АЁ=\Й%jЅиЕvія˜A‘!b‰žФAe–;`c2Y-аBXwо% ~Ќ3ƒb%b˜ŸПКД}B˜ш.]цViцuуЄPKЃDмhVq˜,”H,‚)„Тыš@ТЇэ6 ХJФB ”;!КclMY-lG.фњrа2aдlQ)Š•f n=ЈЈ]Ћ–ЈЇЙu‹fЈЭмЖу[]Лu‚a0qЅ)žоIИ!ф$М:Z ж|ЧђwHђУуяУі\ щ)Р”ˆщ,ŠЅРўqхггЋ+Ÿ3Р})sƒ§RеЖВпс<ЇУAйљ eЃ~ˆY!Zљ3№МTH[k_a"њасу›6џUП~(! ™ўKС№^rГ…YЕ[пЅЉЄK‹ђ3—w*EчъВL)’BCќучѕэъЙ3К›vшbкH™л+­Mћ|R\Єџк­>ю ъ}bш ЇЛНmх†э‰ж ПЙ оиЙ&IБ&ёВEЏYЙ§Р!y:х)пв-чЭVЯZКИžЌhѕ‚ч.^4sЮиGKЗL\›ГўЇ)–ЌИХsVФ\Œ›љнЊqуп9ГьЃ­Жn+&їNŽ9БxеЦ‹з™ХПњкЛFD‘F§ п€ˆ˜шђ".С№Fб6c1#иМMMтVš<рћ ;чš3mŒ…3ј@р:Йђуxц >0вw–:ƒЁ_,+ХJ‘р™= Ѕечџђ€пас X8ИлAй№YОKpюЧ‹S№)ѓ№ЙЗ‡Ј@§АмђўфЕsfЯž= QзЈQЃ/wй~*owкЗˆжэ{тowЊKe•xхнo”AЇq{—зоВˆм^ŸПЈEєQ*tШБ›ЇњХIпКEэ/f<†Ž!VИЈ‰ўSBa†œ jпЁу?УZ(wЏu+De-ЉќцёщЌ9`иsWIE.ѕ?Ÿ2ЪGцi2ЄIЧŸWvБY…piиuњXŒІ‘ЌеЫoДщ[ЌBC[іщЧИBЦ2•KпЁ^‡­GчвМЪЫЋњй‡Q?фїЈ6+~хвХХАЂЫІл{њжзЋЖNtЯVU/ьёcrB бBQN*‰Ъ`зГмЎ]ь~L›РшАAŠIс-ŠђkdЮр *J " Л ёGр™"ЯбэлЗСчL4о‡ъ”ЇlЧ1№О^ЏПŸ§!шјЫd2ˆі№v@ц ЙRуvс‡Zіk~~ОŸŸoЛvmaЧ"oљ;т0!E W У<]*З2зN={—х/їюSю+ётЫЏ–ћ* Qнљцби/Ђм/uєhиІ}УrukЅ,љ&kнѕЅrЇ%Kк%vђшќr9vѕа”Dвј…ОфZ.~ >‚њaM—K@ГŸзЌƒ;N*`}7з …ažA#> эа]dn…ц|ГNgЮ‡ЅЦ`>ƒnЌeЌ]Я0FDЈЉ\œХ.rа|*uЄ оГŸI…ŸF|‘u nט§‘†ј&Mš8џЫš~њmлЖеЌВ>ЃьЇJ {y•qЋД”JOnмИБ Ш6k0МљVD€ŸД”r $†+ЯŸ|†<‚њ7‹ѓ’ЖўЕгŒ’АЉXТйSRI(Ш7едKGе[ЮЙюРЮЛ”@nvjНI(ГbЮў /#" &vG1 W`J•йCbvƒБG"-б т™Пъ0ѓ1kрbАдWиvё!ХTГCr•J{.>$I…Ÿ I…L*DxJ_ыеЋїуп‡УЩk–„CEœC7qc^Шс)!ўй>ТJFEЛY—pуF\Bт­›7ѕ:Мљzwм^ВKт”ZЄ(,wЄІИиXm0P"T лВx‡Љф^„PХ:Ь9№B ’ЃЮžђР//?ЉD š>…љzјgЇэœ;ЋN=јИ<€ƒ‹ŽЋю/RСЋCеФП?“Z8cГ1EіBu%Œщф–=|цЊ9ќb­'эNе—ж„_MJ/§Ъ§ЭNОv№Ры їœ,Ё.ƒRТѕ3JЭ+КSЛщФ‘CWbгЪWeЉјЋЇ!ZzўЮyЪxќ№ЁkёїDclБWNzшрФЌ{Ђбж[—Oк#F§pЉ§"пљЮž]G‹QqЛ—{жїu'bX3U L9”н›uлІGNoKЎзиюЂQJUZn+іАщa;Цbœфю*pш …Юb'ЅD‰KVd(F‹‹ЬкЄТ”bsq5яЛZh_РПrXБhiяЉaОЭNA…ЌЉ7цLœj Œ9{сЏV ыXУv№šК6iблf-_+s—›ПdбOП7ёAч>vВнTЈќЩœюЈу%эўkцЏ›.Ђ/XОxйЊHOћwŸŽ;–Ž ЕC>їnћ`G}тwlšЙv›\NХ,’/[Ж"мХђЭдБgr]Оіƒ/ОГu€#Zьж пmк-›ОZтВ|йOaNХ_|2.ІHX˜W4fЦ‚AЭ}бAсркЏK>1uЬ(ЌiмќЩюo>wLзЦ5ЭУѓ \Pќ~ЅIЏќтМгqЇ§}н-@миХнЧ‰'JК ДЭ ƒz‚Ÿ6А\WФАЙ9й9ЉкИЋY)‰ЙК|Ќ‘kшуVAGџ•G –€Iш2!‰Qє˜VТ–r8žЏgЕlшЮ 9œ?rАР&+'фА76K\T"ф`3фшMк”™w§iЫўаИЉЖ}§њЂ?їжYъwiоin‹N*бєmvMЌgЭо~“љm§я–c?XВтЭŽѓe% їV/ЭoћЊ“’ќЄo›=RtёЛˆѕыWфE/œАј—СэОsјЇ{ЖыўCЇў*9=Ўз {cв=м.GЇIЗЌ_–ИmўДEЋДўксЫшнс•Л VЪ,#КwŒО–х$=~$OН}нТ+f}Ншз~ЋПpјН<‚њС]2'=Yжs§в9юbќрп§}ьђRГZЛЅрЕ#и=xюѓг гNн>ЙёєЦѓ›/рЊTз ЉІО€aЄcЙ}0YšДЕљ ІТD дмй6ЌнФСнš6…зэZЋ0_РR!и;Oа*йсб^р фpъмe›іђŠ_Noмўљі ўШDкљЊ@ШaX‰УŒWк7oДчƒ—НWBЮvkжћлЩнР'Цv<БиНО_\ьфФљр3ЯoxЉo\нщPпG„0‘-dкIZКЁš›6•ЈИ-ЖŠS/ †{ЉЎЦ\є jр)@T‘-Хy3“ѕl}%зEHЙн^ЈМ1Х’ŽюЪЫ—.„DИрˆ ЊЙdAš .йСSъЬэcЭОuе$ыэ.ЛpєRHН†*iаИ9Жђч т_rYA§ шюъ‘v}щте›кљHEЧhхaЧŽnвЂ'‹S+ипl3Л)мДиЃqЯ[™Зж[s*іфЉГ)*?DШеӘc/ЮДм6Щ0Ycя&Џ5o1Јѕ gЌъ’иь6~Ш_+Š/фПŽРБcGJ…аЊ 94mд(сj2'фBIw„8!‡• ф0ЅDШО+фАъ‡Yр-kбOs>ПHД_9Њg]Цн˜—8cк4MЇ1ƒ[zEЏжлIg˜_EAuеFИ-zюxЬgЧ~9э3Ÿžњ7qпqAG €ЋС˜AЙhwˆК(уцЄ гТњNzЕ‘fѓQН]рm‡ѕ"+DƒmbюЬнІ]§xќчQƒІО\_НfЇž&ЙRЄ@lЅЬ Œ,тЈћдFЈŠђvПАџя!I,"ьц |Т_„5VЕ‰8ьЦџ`-sЄod‹wZФхФŸ‹?НцикЋ‡ЏйЭ–‚KИЏкїнЎЏЗiщŒoЅРеŸ…>Ѓ6+Щ—Х#№_Fршбƒƒ_}І+9!‡”Њ 9Ќ›ѓћyz CШЋ(ф@• 9˜ю 9€€K›ч|:іšИеЮЃ§fёь. ­K0nŒgїўxЛ3дТЯ3ШЖ/fН™‚„|™дW#0›LАГ:ЊK7юУр>Sц~Ђљ{YNф€/)?AЋ{;у\4Б˜-L3nBЛїfшЮ™м=Э—ѓaBП87^ЇRxЉИ%BБФžw{дИI]FЭ{Џ+З№!и3pћб|8(Ъ3ЈUює9ќ1œ- рSœ трр‹›|‚№Š ‚›Дc`пž={vыжЅMЛ—њїыу*'ту lиRЫюА#ESNRЇŸ†§[ѕoмЪЮкGН4jЦы_З mуЃі…щˆР-єz:мЋaС$8лСN5UtЕ~:сsхx*Р]mГй`e™FуXQTеR`cздДŒ›6ыuZ­ещ\Fxˆž“OЭлP иН*YWэш†зђ]XУй}—|ZП$з^љ~ЫЁ”cЧџ>ћњяzЧ~Бjkо•‹Пў}Ќmї!DќСћЋZ^=4|Ш'ъŸыЧЦ(šG”пТЅЊЕ­…xџX4eжђ€PЏ#{“n š7‰йБvїхфЋЖ„МђQŸцТIяНO6юЁпБlъœ•Сž‡wyFДŒ К№їћЎЅќГђЏˆў“{E"†TД|%oуŸ/XуэЃоПчИдЛQЫЈРг›~?p;mЧЪmџ7Е{˜eм{c]кїNћcюŒe}М”бЛO(§"[DњŸи№ы‘„ДэЋvЖxsjзHOGУQ њђРЛУхЫ—С––X, sl;ђЯк'r‡ я'Уь—vnКbіљђГ`к!::ИЏYГfЯdёHYaБЎ‚Uў•|Њ№`Рѕї/М|ЊEѓ™ѓдp‡УV}0 ?§jзЉS'rhиАaЯю]ЗŸЬНJќoХP19|Иж<Ќ=9ЖOщЦфх2Ѕ ЙЧŽœЦœнд4eљF5ˆ>"T…yИŠнМ}еbысhNШЁA˜›XЉQК4тч ѓН—/\+˜ASэеЈe#ЏrYжЁC]vЪ•лЩFHa‘-=хmъЎ=Чe§о=ŒхцеыЎ!‘Є.=&6Ѕ$š ~TK™Й iчоS„sxЏn‘ИнtуњMїа(\› бLfXT+lаЄЅŸ›д˜—АsпБkЃž]#0ЪpуzЌg§(6/љJ|ЊЩ ž’ˆІ-|\%†œИћЯЪмїшм ЬVѓ0ъЗкьД6Оoя^ЧГЈ–uNОV4сЋoto;ЫеъЏ§ыЬSэcЮ—X›<6ѕщћћћѕяп_­v:vтт w&зѓRv66еB^Ў•k9дfгјВЪx˜­tђЉч‚Ÿ~Нi#AЦSЂP;Iэ…?;uРВЊѓ<<u M›6нr`ш7п єŸˆRŽѓBuъ29*ѓ0ъ‡(!I{6ЌйФpњ‚ ыаыэбЏulZ[RGЊ#І:RО<Bр)Й;sB[  ых!:y§ŽУ„nт(^ШсAWтйѕƒƒ@ЂlжІЕ іŠАх}ўу†^(YЛО=ЯœЧ)цЧ @m! ‹aV”!jЖ@NШAk‡M `;m–с„&o1Кi‰ SOѕ‡DД%=5пЩгC*Муљ кВ”љXє џі|хw Эnбgf=§<юnЩи ђ ЅjбнSЪВцЮГЖьє<‘“F%уfЙkёЩSч•A УИUЕEЙI1зЅ.^ЭV˜VЁѓ2sP˜пp*ёеGЬлчoІы=ƒ#ъћq2ЮY7.пЬ.mвТ[uwђМ0;>цzЊвнЇIxШН Ачdф2ЕГђЎдџ]ЄюzчŒ$*Џ^}ћУ\.б іcзЏи4чv•ТCўЂЂ"WWз т‹•FцOђ<Р14@нцrkі%ЕЂУ "ЦУ<€dЊЯћім‘У‡Gя7­;ЖЅ…_%{МtŒI#%?М~ jеўЙdо+ њя šzaиА‹lMџ9ќc™юkШ]6у›ЎгЖє|яемu19uмцЭ1_џОБO[Ф”їЭGя_ЕЊ3“гЛOœџYЯŸGKє MНtЌэ >дЖД\zй_,џyыЯVŽЃ%œ<ИyсGПьящœЫš3хигM§zН/vsjХšХ~Jn}Ў-7eёШqYa‰NvџшЇёНЪ4ЈяgMўэзуц­yЏw™€Дљ`^tю›/цсb№ІMНpГЯчs0XЫ›5JЏR…П Ъыьь\u‰н ЩљЏ<OЇч–vƒQсrАц,†мЄјD8љЕiŽтŠ&OЫЬXhВXDЮXtг‹љ PѓХ#б9”Gз.Эгm}{юоiгFvm ііИ.'7hб&аMЉr 1}вдйћ9!;1Іп.6ёVП6dˆЇ3aехчЌEщЗг ŠNšqћ">­@ 1СP№}Б‰[`”tfџљ,ЏпЖ.IпНpФOKЧt_4ьћїk;ьїП& j{g„ НМ_œЃг9™6ZЗfсњOцэмBЩРІžrzї?~]о[0Ё}ПŽCSђM~Jn\х>bсoЎ>Ўчж|6q§ŽБН—О+Ёо­Ы1щЦВVкГŽ?‚њС7^эићѕСХ *ITz6lЦr4о}Ы(ЫŽ?p Ѓ*АљдьxŠЧ–G І€ћГІВЊЯ=B!Urао>№жиЏ•mК!',Pж ђСbЏоœБњ@ЛPUpXˆ“ќЮNє”6uыоЋ FznљtђVГиЃ(ћvўА6HЎ%3хжелm›гY1_ЭўБ‰(uщЯЇжoЁЩ#У„шМs!'іьЮ$M“>!kљсЕYы}ЎўнoЪПvньЇŸMœєйћ§KYВBƒžќ+щчтІV8&WЬV#!WР4П€ vWЖЋчуe\ŒЭ’ље+GЉ˜З—ŸЗ›s|Щт$]fj!-M;8kшУРПмкПmЇжПOœ№~\KMѓVQ^wіBРBр}IНŸЃhWN“™№ё ђд8ЪщйœY5Л\„ћ›‰т(UМkѓК•П§ќгї жmнŸЇƒ€(—У§iј3<<џQJ„%б_ЖЅœЌ ДйФЕ]8kіјw; н;/]ў[зVMгѓJввeT#p˜ёС@‰5cйў ЉЛRb:~ќ,ЌjzБЧ #&ѓP zЁћg,Ÿ§•=ЫШЭaаАMLihёъЇЏЗcl”нb€Q3e2*›їљэЛй?Ьuhл‘xЏxŠжмY^дМ•/unђдйsП§ 5X`zАгќН|Ц/Ї™яІ ­0 gР;Њ$˜yg“2н#^ѕfдŒiуR,vcІNш”tљlzц“Нм„ c^Л`к†ыВ™нћ&™нЩЫвžНр7нУЈ_Hа›~›7nЭЩі=1МuљхА7žH!Щ •tдџфрјO#Р 9tteŠЎњЫ mйg`я8Ъюƒ()изЯM€йИkh8В„˜МCK0jЧ"n4 њэƒЎ ЮЂrЙКyЯwПџ–б,мؘfTr—pWќЮ l} I„BNŽb”лѕƒЫC1јAб@ЕЋЖКХH”q/MоWЧ'<ѕР‰’V#ќОe`ЇцЭ:7ѓ TЁ;~šБъЂmѓк%Э=8cеbЖ–R9TŒr“Њr•gѓРа6]Z7якЯ‡ДцчхЌZёїЛKЖю?yж#эЬЯ{oиmГЭŽ0іѕ?Nџ;UёзšсЮk1УiGџ‡ ЁЅљ…—v]n=№a$N$П”И|ЩЯ|ЭH%ƒUГіьп=АујЛѓФO ŸœG€Gрп‚ь|шШёM›џjP?—‡L_Y0ќЙйТќКGпЙ‰ЄK‹вIиrэ…ХC ‹ќDлЋtkŠ‚ё:ŠА†Э‹žМpŠў~О`єш(чœ…kbF4њХП>ъдЬ,R6єЯ;}tЮы?}Џ#m3SvŽђ­6шPsAЪЯs]Оtaж7?њ№=іц_лnЙŽy=ˆВYсe@(&N§ёЫ )щмж—њЯxšKЭlбkVn?pH‘aї”Œ}1RНхЯ?єv_ЅA0ЄёТ_ћ-В=1 IDATKP”GНи{еK§,B‚ЃТ€Јvr "tѓХ<%’­Ејvэд,"ЄYыяКvlћ4Щ s Ÿ6s6kЇмœd!ђёі‰Я4џіћVсўЌЭ№УбЃЙ&tvM Ьді> еpbœjOџбSОBYZІж ИlјЗ‹v*ЄdC?yYNoЯXъw`Іžž5џЭШ MNп‘A˜ъD.=|8пbK…›/МіМ1zВаƒ›KајOјт[шUмдŒ!§dОз Ш‡ 9А”~щФсбyn#GvW scЯ,\ККуШяЧhяMМУ§>0Е[XX"?Е?Эћє<7*{fљsuЊh)Т4/шnЙИИ<ШЙnнЧг№!__п8;;=qiрЩѕ§…Аx 6е Bž.Ž=Bž=nЩЛЖ,MЭЉлjЯO &[QњёSšПєъУF§6DђжфЏЕГЇOљxМLD й^Ѓ& э 5Œї№yJWцqГ…Ч5//щкяrЗЪ|КšG§Ž@Ш|л„BЁеfтТк(#!M‚СТnЄTZъОXѓMЏFŽОн_›YnrД)ŸџЈ•wЇюœащУЈŸЅэ„ГЯGsV NM1Zэ*иM.ЦaJ…}иф№ѓЮsй`ќгЇOƒк6,,ЈаО3ЈШПрkЅJ ЙЙЙНzѕ‚•К•ўZ ­.Sњ}љ‹зтзJaptІ vcj$hйЊU-Tу‘E`0ы[ё)ydЂ[„GЋБi†‘($,K’(М(b~%o]М рM^ЗЃЂЂюЇўКX]ОN5t№—.]‚!џГт}hЎЈ’Д fLz*G ы{“ѓm:{;?ygQЭю›Фцфк ЉЋГcі˜‰9wЦШJZЕˆ„‘ЉХ˜эђU3.oбЂ™№о‘jБ6OoB=Н4П>ѓж…[™r7џЈ я`ЪN={#С9ЈQC?n›УВ`1hѓ ­žОюїЎ`.9iЈ[6nPГтKegфŠUх]!‡ JЯР†Ё`ŽGŠ@`љjЂ„rЛ7!9фЂbE™C9dpBѕ|K…r Ё›—rЏžЂМ\EzzоЃЭZѕЧN]pѓoцяVVЪ#Јп”|р~zАƒVYnќСУ€ЅбрКцp7ЦpЮS­ЬuїaЩЊќЈВРˆЇў*іo‹––gлЄ‹1з,‰Db7щЬ NIмR )-) $мЭЅЏnѕДЉёљЄkˆLџV ЋW|ЗhскоЃNйц„w,žєгб ‘­ˆh§ўњЩ§Ж:e‡E@Ѕ]^ењ§ХS‡JK ћєбMŸ|<гЛбА5ПŒъOОМћŸќа(2мnwёЭ'*У#?SјЙпŒљnкПuŽєp”štћиУ?fЄЖюšugїН}Хз?юЙ-Ѕ‘ЏђѕџкUЌ"їнќхДq›7УІ>m§`л­o?~џŠй)3ЅTШaдиDŸдKЧ+rxчГ•Vr8[&фАЮлПѕ§]!(ьРюп>›Ж МУФ_МУюж‚/>љ№’VЈЭ+;у‡ЭЙidЈX•Јп‘џљ$Р L_el(_—›iЊРuЁf;TО~’kєМЇ}цWŸСEgrUƒdš›:чxŠ‘ UИ1+Жхчхм0'ф`Д™ђSng0/tj)'1›.1њ№Uпˆ6 •>ЖAеьЧ§#УяѕУa;ї|ۘW”dтФ Ј‚иuыc>нДЋzщХ_Ф эѕвG3^ѕіЄтіtxgqь№7Л:f˜йАF>“ВjПБ$7jЫ‚Й^ŸїЭ{M`ЫGšХnо“Ъд?ќУЌХ‡_И‘^F§Ўо Пš6ђЫЅзЫзп–scѕ_'ІџВЛЉѕxї‘Ы3ћЕѓЌЄч%†Ÿ`Ш!и8I:}.г“rиЕpФЯr@z xOŸ­г™ю9Ќ]И~вМ=џ!˜ЬЛ#ф№~!ђGЕь>њндзŠЫз3хєЮУ9Nлз/ŠY?ѓ›ХЋњўў`BїО •OСз(АžтъЮ…~<9Г‰'~џaУЉdь1&ТP](рњ` – Р"ЁH($с“WtюQL ‹DТх$–Ыз”„’IŸЛ{ѓП­ое|рxRPФ&”п0ˆ/й<чih]NHі?тK+!Зкњ!!СїчЏН}№эWЛ}МlгŠЏGЯњс„-џжфї&НyэЫISЮФefe™cЏХЅх”Ў +ЫѕђєёїruЌЃ)ГУхRРЭ[BшЎ$цЋ|>йЂёе”љдIхR/Р“[жС^›Ž9л†ПћЮђ?ЯСIџfмГV=тX.гЛу]ŽTЊЁMP,._єФ-сщEШ§ј0йЗвя!мвŠ’~х„,Fв!фBI ф>ГDШСП\Ч{{љћИ;;ZBД4§рwCп}>тƒCЬš‰я]^Ш<юеюAОю`Z(-ћ{сЪхњ`—ї№&-АŒk%V7rрG§хQzšЧ(†ГХЇќ3kuПe“{S”œy1„Оrцјэ”\€ЈVMuщ‰Х –|ћ:- jж@ЖэрЙ FЭ"‚|P{бЩ=rэ]:ЗгњSБйЁ Лч ?Vнcc/,^ЖЬ"ыіЦл]+>Р]._<ŸСшДEŒЧPЅP&Т3Вs(жZ5ŒŒКЏмMПf?Ь›Йnкм#чoХЊ6ЦЄLыжуBмК іЎэыЁžCМм:ѓЦщѕ[‚0KŠ^0Д™Ÿ ђ(ѓdЙїxA:їЃ)сX^\Ќй…_oќыу…>§zžєž.L^ТЏ\ sбЅЬ,gIЃёук=бЕСжіX6*ЎŸ›t3+ЗHoŽМыT^’BАZСe х,IюФ ХfNfЎф— ї9јќКaЪдйŠєѓeB[—Зт4ѓ§вw+pq™5и!фа7ЂW‡&7ЦOћАою-Ц,P˜xљŒ(!䕆2LJO Ћ‘&ЙR ЖRfpЂs~јMWЁИВјќA#Џ”т—_ыrљя/vwj Cxx:(“юіЕ[Є`Щ—Љ–џa>И|вц›-[7O;0чgЗVaОљыў<Дxѕœƒп~{LрцЁ;–RDъUяєйЫž~Jў |К0eЩмigвН#ы{ЗюнПЁ<уяƒgSу[wыkNК”ZTpьHќ€Б“tlеЌћЊйс3Яеxkљ џƒЕ9_irф№!№юП|љJЏSѕоД_ыкЄыƒа`llpHˆ—OЖУќАѕТVл2ЅњЃЙK7ѓПxЪd0qbsb™S`PЗ!r’оё4ю№:СфяћWЫуGђŠѓŽžМфzыШКQѓЖЬYўK3_NГЄl,.rfIb$w€H›zzЕyЙGƒњтf~пчlћmБjШЬѕяЖј}JпйKўо8ыЋwrш'DоЩAy e…ЮŒpqrжю-Є…=7e=ИоЈВPQШсјбѓ™Ш%Sj‰Уз+/Г[ж.q•p9РюX сЧї 9Д еї™З „VƒУOG„Xо{Б99|кЋђBŽЬE$ш?8jB0„xn?Ъ™кŠrу j•Ї )КИыRыїє‡ŽќчSB€В0 ^іaЇІ f,вЂ, MH‰2ИA(СŠ(УэДТbЋ… ь0hюєЉэ[6l§ъy3ПT 9Щ›ЮŸ"B”б_‰Йj–z}ГŸЇŒИGЉЌЦ(\Pћ’‰NŽœњIП+›џgцБйЌ5;пPVўрП†€X,9tєфњM[џоБvLW{Кјћи`=.ЭбwЅeэРPм8œaСƒ<И~Ч~nвѓ’bЯІщŒ^!СЛцЮй}щЖ“oXŸ%ЁпЋA DПДћЪ?wмОцїMi„=НsХщИј6m ~uxЄ3§ЫŸФХноЖrСЄoVQШбUгFЭў RЅп8їуЯы.кѓУђП ЈцѕAЭW~9vё_ХќлеˆxБyмЦЙ?-_z бкЙKГдkпњx!,(ЪŒ;џ—˜ ‡Пѓ[•йГxт„E{5ѕкОжR=cвWгЧ~хо|h=чJ‡б ф№39lќeбЁѓ ЅнМqu\њ­ [Яє9КDШс›тМјEпL›ѕs4ŒЦ—NЖ<:ъщrиГщЗ ;N*ќ›to)јъЃщГЇuGШЁ 9L^Оt 9tˆф„&.йЉ’.[іћцѓЧџљљнb™;qШкщ­{іwЯ=5yцќщг7vz}Ќeь‰вГUЅе…Lј№4`ŒvаЄiпmюjгˆ>JИАmжOЛ‡ ъЋ”ј  ,…ИЙ‘Œ‘ˆ4Ў*šЖЃœПK˜кХюEg нbg˜-л)qс7žвгƒПбаэЕaнтсСГв­_ћ`Ц€Nж”3ЎІЈМ5Ыі'хiœИm7aуЭЇб\>Яџ!p2юіRЗиДл?ž˜ьтЉєbšB(˜иКrјдз ?4ю3fNGRЂёœЙ§—§ћЯšвCJzї™МD­(б>ЋжЩЭ{ШиЉ8ЪˆфЎ зцъ еfwyыЃn[РшgФкПЛkuVЋ{ P$ЊЧ0•ѓw”(œКеы-”AU0ДюјўчтР]ёйдЬЅуУ\DШЯцюЛš\8dТЬЮ­#ЭъOGв@‘‘ЌеKoДю…[­0 ‡Жъ;"€НxиWsМџй[„М№Щ++iWcЬ= СдoПcщ2!ЏИ Ы‡п|п:ТŸБ/8z$зdлЏд9€rxџ#дхŽУЈЩ_aЌ]цьЬ 9Ь\фПыіЎУП§2єєЬљoFkrњŒD=Ё0ЉЪЅџ{ ЦYLрŠ"ТџўDрЁA”тя–}їOє9йдљ=;‡3†T‡O§мѕЉJUvФN(ќЧљќраэ6e(kAЪ+Эљк“ћЮЗ%hX9|Xћ^b‘dэ6†•ћmпnнЁhWДГёRZVЏ=иk№ O% ќяЏ8œ`цНkЖћѕR§ОvWЇ ЏБ,-„хy—Фэ™ё‰Eтr!CјhDр`ZЌ+§Ќb‹M)‚g„<Ќ'SOћіэСПГ ?п5вY.R‚ѕyяЭ=ю ї–ў­яЯZЈtу6A”ю~JnЪ!eАи–ѓyw„.н_-=МчЏУ&ў яž lд%АQйW"ИiѓрВoРјОсGwЕwp7яђПˆ[uў?{зEБўЗ\oЩЅїJ„„о{Gš€ŠэayЖgЧgEХЇXбП<л ЂЂв{ЏвC !=ЙДЛЫѕл§џf7 !ЄЁPv{ЛГ3п|ѓлнoњo&зYf&Oя?&НuLЕtarПЦ/lиuФЖVЛиД@сŒQњž|KoƒПВŽ}дQ“ъ5dRmrŒBпЉџ€Кбbкw/лuюQWKFЕ›Fœxѓэ‰тЙлУŒ>ЂkL­,kI'—гйѕІ'лЫ}mUіаЎ#Оћщ'ЕoHАaТ/G•8х“n˜RbтcЃO ѕv7{у=БZL›ёв#СeђѓгуьЮ.v†ЧG)д>C†їїQЃЃП5БT€b•/ЬћрџоћdХf_ƒПЮУ{Zџ№ bжA{ыtфМ5эa†;sн/u VgэўcцмЏ*Ъм<єкЬ SKЦПT%Џ"АxёbP‰`yv§MH~04*Tшъ!cR VZ кB/mА9\ZЎ1щ0Ъњ h™•Рyx&6. ЅСšдЉo2ъо<‹{”‘т0! (4‚фЉиИs{ф i§iј‘8‰ qјmШђSbЛsЖюwХІЅаYЛжЎiёСЩg ХПЋТщUuyхлџЕзb‰єёФtўн/#_ЇаYt=)Л”””‹*Ov :|.!ИѕDƒЃЦ^ѓЕ›фEБ^0\ТВ‹žАєфcau‚U{Š!Ю=ЂуЦфпm{KьЦЇч|9$љьJHehт}?Ћe„UBЬ{_ѓ{Ў8щъŠB ЭbUYЩ‘п—И+J0lЋ0ЇŽКQу+є˜\ХyыўЬ0Јћй‰ћ %tцш6м%)cХyХ2бЯЇ­6сьYЛќ]ŽеЇУЁн™qiБХйЉ™ ЉџWќИЊ’УХЩБ ѕF 0І^juћћъa&$гџWН урГЧ VAA†™АјnL Jђ|QQЁиРТЄvmя,+:…Ьe˜#IЅ&8^/.И1 †Г%}б/б­“ы:єіУ*–ЪЗ№”N™жу’š~лщНѓПXзiHїГгяЪиžѕЫЗк;УєЯ{§™Я?_§ШмЏюpvX Ё—ЬЯ•7ыщ cЎѓQБ™[–О§щщw>њїЅHŒЁœЏОёьїН;ЙKD]љЇ]єMЖіљGn€Їdњы"sŸУDDD€2Ў^6кМ2XOщђя#pОщ‡ЬааP№8§}сYУyА@+дiЇƒsкŽ.§ИєHWŽa9ž6‡GїŒ­УЯ^QxbуŽЃ`Lы›Ы9Ћ ŠLn›щЯЬŠ§d”ГxнšэЌв€žIЮJSЙƒЋ(ШШ*S м•ж0‘AŠ3ћЖя*tє<аOM—eпВџ˜1<ЊwЗЮЈKgZЛ?“)2cХ<™нУmџЊ(ЈВмчЋq)|•Ів*gEю‰3§АЁнЪŽэЯЗ{Ї$&ЅЇFЮЛcіА;_5ду–ЋQЂЊ,Уж]мoHw_ж]PPBSUЛœщ‚!єЊќ Ц/&ФШЛЋNž1EХD‹›PжD~ЕЯJyўЃЯЦ~ђ"Y•PэМП8ahНшб”щЧ”?ЅR†>gT'ёЊ)иc’ei` ’—й/™*Йk|m›{ƒJЎЂ9ЛлЌтеВЊпlXДРGEU8)y`№ѕѓNNЏЇaсЎпЛ~д„ю9Ÿ~ВiєЬЇn5ЬКkќ‰ФБ‰EG>_Вќуї^ќbкДЌЈііCп>ёR_nы”iя„іTЕsSюєESЛщ3Зќ№‚›‹ШмНјЗ~ѓfќsцН+IЋђєшжљфŠџM{gqЯ~}Ж.ќЅз“ƒ‘nddЛ№ ЃЅС ѕдКH—E{—M™ў~DŸ‘ќЎ ЛГžW^œЙcћЎД8ъŒХsы иЦвЩмГmї‘гyлп\НmЦ;3:ЮНoиnџIоc —žzjRХЌo+–|ѓњЉ5_ЯљЕќЃЗŸi 8ЅЈДЁS ž8mх“Iяqœ9'П8чК;ЊASЦТR‘ѕйgпЛБы™[ZК0Ч\ЉRѕ2ЖOчГѓ‡DЁвQB@B@B`§‘ЌУž є8j”2›Л2FAi5žNўŒЩцЩtй?ЅћbЧ~—Р\#ЮЈЇСЅМtлЋє]'|>їхЪ oŸГсоOъ>рФн=l,ј1[ЂЄ o§zљzВП’R;т†;ЛDUїзХuъжбЂрNи7мсєvЈPњ?:§еqŠmзнЕ(Мп ї›S7ьЩ?Мh]з1гuе&мНцыЏvž)B'Џ>2хЮ)uJ}Х›U\•ЌЏ&-Ш=ЅFО§ы/Ћœй{–Нav–Ж{БkК[šк5иГыщКД”I1)ѕU№rж’lЛўtбЉТмУі? ѕИ]nВ&“Gз;†ђ†NМmц#я|!ђlG>лqШˆКkЧrЗЏЩŒъ•XгШ[ж§QyЫ[gгjЪєЃпсtъѕКcП,}+аN/§vQтфY„Д`Ћ‡t-! !pY#PKф0lиаВRгА smeХЧђљ™iссi XЈя"{§тџ‚6э=нѓй†ѕIvоЎŠNь= “ŸЂуcУ†ћj”џ^М`Уъ ХV>ЪЈŸђL*jвдр;ŸюBљ)є‡Kš ‹ЪЈУFŽђЁЋКѕL?cѓЬŸ: NУЦMyфыРЄГяїн-S‘R' "ўёЏаœЧ7јN9­›CWЅ3rи.кuщљъШЁ§iэЕ—‹”aъыф[GЬќъѓ~Џ=iŸgLeЦйoЕaз‰и;o}Њиз/ќ‘oъ)ЕЊпћЕЧ€ЕSхєщџјЈžuгЊ{Ю;‹ч/иzЧƒЯЖ#СY3w M{:LX9-ј4eњдэ>5чЖЯЏЫмG‡ѕОыў[†г  Чžф$$$ъ P—Ш!уd…d<ў";vЏЄгФ7&V— к'2zа№IЃЃkjЋ”ЬрЈIЕбЩT* 2>@№ъжН–зКžcЦ5‡ДЂЯPRйЏuIн{'е^ДЪ‰Bв1~ь„ёеЉЩ4ШђтMс“СR(ЩjГ*о!Gcdъѕ‘BgNu5=„јЪŒiщ$џ‡ŽхtК§оnБЕ7фf]чqЩЇО0=Ё]t­ЇƒїyьЃ|ыpЕ4cњД2кРДы'‡rЌ;Š˜+ŠB}Ѓj%J'" rРмb‘Ш$nEtвŒ7ŸНj#GL˜3Ќfg}8dэ;Ÿэ~ЉГЩыД7ЅidZЈQЎ7&ы…BВFN@Bї!5чтo3ІћFYїь/Ftщ…Ёd0 гј%ЧХœ+DК’ ў>‘&”ƒNџЊ{э]ŠЩ№ .ИPаš1§Зл­AщƒfНљzЄC№ 6ё‚€В­g_h>Ѕ№—Њ2г‘п{*JМ­0Е‘УЁќ›%rи.9Фцdь;™[”&v]j<tяšeПяю

ѕћїїоэ˜XVEї;ybŸПиNi ЩKB@BрjAрфњхч9єМфDŸЏы4ИY"‡e;ИqюТзfЬQDя>”;§э/ЦЄ‰<Ч­ Н+w&ˆЎMˆЖ.}ћП—Шс•зŸЙёўw'wўЋD<'uЦISЇ˜мЌЧуХЄ™pоˆtыт'Ѕ&! !p9""Егёk‰>*=в ћ qˆ"ЂЛjАЇЂЂ0cгЮ#ўqi}"‡Тb“ЋЪt(ГВ{џ‘CЩК5лdI§{T9T‚ШЁ\5hP5‘CЮОЛ }Ј&r8pЬнЛ[' žf^{€9(eZ.Жу+Ÿ|эЈџЁ_-п>&­сm..Ќ‘ƒЋ"яxŽХ0tHW9иМS’RвSЃцнёЪа;g7MфРЫBњю"‡Т‚ DsКіыЇЖхWа-#r˜_ŸШсї9iЄ6‡в{лП‰аuЅT)A",k€6тт‚&I“ИТ‘іНP"‡ЧяŸ9Ё[Ю?й(9ЬМГ–Шaˆ>ŸіxVd{ћся žxЙ/ЗeЪя†v(9ќC rxоэ ?Йgбя§чНpїЌћWє’f‘C'9<ёЮт}{o§њч^џыя1ођžшўuі]Й”э]>eњ{ rр‘УsуbЫŠ@фАugZ,uЦьОuPѕlŸѓUˆNШaеVBф№†@фш=К№ћLBф№]Х’ЏAф№Эœ_Ы.„Ш!7Џ…DrЏхW?№KыАiйyеОЧ IDATg%^ЅšЁJЌЬЄ‡ž~lRЛэœЏНф#! !pM!АсHж!9АŒFuDЊj"‡љ5D1ГgЬрzђ jˆ†ф"‡Ѓ rP$ Њ&r8rјfBфаoоьзлЛAф№мбТ›Ќv›FnHЏ!rшsяЬчo‘ƒsП›pHИЭ…oМјŒ%щ–goіЏИєЯЦmЗъЛŽџќй•;AфАў‘ШсqШA]Mф№ЭO@ф@)4ѕˆв, >уЛMD"ПњD{AфАЖ.‘УкЏПкqІˆ‘CTЪ75Oфад0Џ‡VПsВ\яг!6„—a•5УSlhtЌзэ9пЅЧMJAB@BрJBрД@фАnнКЈИvлОzO—ёkДžЎ&r › r Ь 2ˆlD"Ÿ?9ž#хˆ|Цнћ\Rч>мО/R’kˆd"‘ƒ_ЈЫTШE"‡їОљя_}|лэџќыG„ШAEь›йneА›ЉлќќџrЇпОь‘Щ­жc-9c/D3КК"rPjŒ1ББиВƒ–Ћы9Иb'ФшлЋЌ"‘C!rШ­&rјзИєйџК]iŒџЂ‘C`hx,K–piƒ"ЯљDЫЉСwдЎhЪєГѓЪх?v™јPЧXПЕл+‡J“г4Ј;БЇд•є>JКJHД  rиИfе’яОKjŸ*9DА\E5‘л$‘ƒІјјšŸj‰^{ъѕn›<НїаУГОлЗѕ€Ž9$ж!rрœ4_Mф ‰ЦD‹AфРА„ШЁЇHфЖtщњ)ЯL<Г~йŸ.3-сЙЇіЄ ћЧ­#[cЎ ˆv|§п—UЎь=ЫЊ‰0d*9U9LŽ=O“zDЧЯ98"‡aзп6ыГŸ?—Шadн•ч9XAфps ‰РїŸsъT{ŠvœљlСЉQК U§Vфџd“D ‘УћУњЄˆDНЄЉg‰V­/ВR‘„ШсІgRIНs№ЯtЁ"‡яПЊ,**у; 5в‡ЖuыбёŒн;jBфpѓ# ƒ’ ЭОwм{—BыЈlїУкЕЛу™№иVšм "‡ˆЁƒ:З;Kф0ЛšШaв­#f5Eф№П Л2"‡"cјУ/М$9ЬO!Dj‘ШЁюJцs`5‘УПъ9l?вr"ZFЛ –ўјХ)њDa^сЗ UN+нЉЯроЯЎ>'AщBB@BрF ИИ8**Њ?Жбh‘CTМ?"‡Ј{ъ‚’иѓІФjў…"‡ыЮ!r=Й6|5‘CT ‘CКуŽКžcЧз%rш{‘ƒoПСЁЕrZч„9ЄХЛО"‡ЄСSgјžhœШЁуѕ‘B%>EфцЌ&rHяDжшў)9tmšШсљщ g ѕ…9x]ЯниНg‡ЧнЉ›|ћцЭUжŸо‡mрЄT$$Ў -Zba‘Ш!5UДYІў5FфаўТаЉ >рІNШAиГЕFF“4zYЭ„ћ_œp/gЖX{ПБ2VŽб—Л59Џku•N$$.gкЗџ‹ЖЌ6S‘C-Mœ4И<Ђ‰№ оjj˜8/ЖCРС‹y§ŒРFС2mО \ƒ‘<%$$$ZŠРеУ”двKс$$$Ўy$гЭПз’щПіžЙ”c  kЩє_ѓЏ€€„€„РЕ‡€dњЏНg.хXB@BрšG > w–a@Ж šbБ;–M3RGE“А6xVўиб’Wпн—>А]j—Tї9/яЎѓ­ђ4 Л/s˜4юRаЃкU!•;aЯœКЙ+ЋсщuЛPnvмwwчКjЖЕvRњ—5 ˜ўЫZп+X9кхtНЕр€2)<81Фd&TгjЦL`OTімˆт5qўL˜Ъь.м›eжœ2 . сeU5жŸF#!wчO{wюф)]TZџі=КЫioГ<„гЄCИй€_lЫg>А~[–mؘQ,м1”Їђд‘С i:ЕќœЁN"XИИ 3Ч,у.оИќ›з=рЇQ6"™–1мбѕ_z‚zЅvшшѕКБ =яРy6cї~У97šЌT؈@_ЙoЭŽ\ЯбУо…=–МьЌТШ”Ю Ж{ыP qЈ(”qƒПћс@Чдœ}cœ.o€ЅS †Јплаp(Щїo# —г›ЗŸ9jІш@ŸЬ[ЅнkwSяtWџ”аоу;ф™Сz—ТЈU…GНн[T'ьF цсЉƒ?ПНpўЇЪі6cЯњ 'уцJщсхNуa4^Fщ"2iьД&ЯК9Yіі5Gr,-wК)7Eќн^К6iЇaфJхeT.ЇтЪ\ИХЫЙ‡c. в\žкИДБ„TœкZyЊ їД›‡*Œ9ж‡—[ПТYърщшрekВl6Ї0yрoПЏ’€ЋЉжпJO“ЃЖ(ц§|,N.ЛдQVхј9KЊМЈ~тРч–WnŒ JHŒ;TАџ0ъч!GИЬ…›-йN;ЉG#œ§фšŸWХ^џFLTЮуцИтЂмЃлэf“Wе!ъфš….:.aјMJЊтф†oЌU'GФЖ|љVЉoJЯЗ†&ФцmџOQŽ;ВпmaAh  nы*§ГМИиY–QZш‰v›ЏQ[~ьЛгћ“Ц„D(ЫŠЊ‚;єАfЌ6s!QЩqХЧvЪќS|§}PSЇ9kоЮ‹ss|лэдлbЇмітЕпНRQBЗ~Ћ–QЧ”X=UŽќ3[?5Љb‡мn 2: wgl§Хэђ‰zSёŸьЭВ Ÿйy:Q(šЕžйtrћjZ;xВ^e7мяіX‹ŽŸŠш{[PT˜ГhЫ‰ШеЁЇК Ьх I4хЉ:Нщ›J“Щ7aLtчЮŒГ(kѓЇfs НТІ7ЪO—чo§8?›ЃyЋл7*ГаJЁ—ЬSИsсМELб№)с:яћ:7у˜6v@|—,ZQh‹pХЛП~'› /ЙюN­GцВЎ[ђfEзnјmFЃŠШ/s№цŒгы—VqtќА 5iSЁЧй Ж/(ЬSљFFЂ;ћш]%g2E™к„бОЊЪ—{•!Бnѓ1АЅG6Ъ#ћъ•жмŒЬ ЄюЎ3ЋЭvwEЦNк–0p4&де6в№Œ,EЇ3ж}…iaтћŠœв7Ќгp›ЭaЖ{NфГџPIiЙ5$иx6f+НнR2WЭзњбТ‰лЎМЬ]6ƒрѕVКh:?drыс(ГƒCнпь№цК3O;•rІC{Пм\wVЁžЃ”F5ЇЂ^Ky•“3# I•—лЕA~бёх•жr‹ГТюЕTUќiЮž“6кWПхгЙх>НміŒЋV–Y=tPWCДaЯЂO Ь2™^ЇIх}ќŽџўЩўуЌ62xЧ’Š,œХщ5˘ВТCЮ9]щc+оЖыз­…Ї6o\БM™<№јкЯO;АwЭвтВђ}KооЖќЛSоЁѕ K ‹ƒГzНП{§Рі2CJя“+?иГљ€Vл”ы‰№TйќнћЅ–Ъƒ~/ЊАя_4їHa:HЙэћЙGзНѓRЅ*EŸийFЩ<*Н> žї 7;мю Їя8ЦYБjчO›ЭŽђ}?ОВџЈ…Їrv.YVZžНщџоЗ{ѓЌЫZT‚ ЏˆL…ЙŠѓэр›{№‡s‹,ћП™{ьŒQQ–yвMГ'з~ОsЋI—дЕќT†гЭY^’KNыt>С)М_HцКЯЖџrP›2Дpч7лџиlі0DЌSFщt† Џ.АŠу їџ‘c6Xђ6юZЙНЂќЬўmkЫ\мŸKп?iђKlїаЂ&V/bеїlЊа'uШ\§эБCY•ЅЇЗ~їŸSі Ї-{нЛџqј”)*з}ќnБХyrЧвьb‡еœpУкR+ŸГїЛ +Wx‚г і}ЙkѓГГZІ йу”rВ2їЏY"ўнЙжЃЊДЁEХЫdŒJЮъu З\уp\Fc?—Эї')вЭењiкЌ˜ЃtС Ф–МZŒчхJZЫАZ•L!cАе1jќТо•'яžР*и Е§dЯO2љЉžЌЛRкб=owk]Q\АdUюELžWЋфzŒCЅ›a9/­Jыp§ƒЁŠЬ•gДЧзRUЙъјtN•›ЗпR”С{ЫUџРш@[bϘШР›В\&gGAx›eѕ*–bх1 HŸаwќ]EЋГOф˜(;c3g—ьћУQYЊ щЌйQvd…,*ЦшrйХ(КEGљ1—ŒВ”[Э NъаŽ­8˜UvXх+ H›мoдЭЎџѕ_.fy^ЉPXgЖ5ЧхtVxh.ŒЏЬp…Зы2ъv5уDвВˆ0Г1>6)CжР€x5|жж5Ўr3e,UБэДaR&= ЬљКЄ(ƒЉЪqЃћН^Gež*VЩh2Šddъќ’УхYœЗBс1U8эЧпвЎ]€зt’у­Uyб&'їъЃїцeq:Е§EŒ" 0*Pо;6&lЯЖмˆ‘SК02йћPЩ‡ЩdZсШїŒ‰3•ЏёOŸдgмy+Of—h”ё…L+WFuщ_јћ/YZuЇшN‚&”ŒuЌ,ŠwwJЎj{VгАМБӘОcЇ:N|ыjпiј8Й=ёЬБgyWЇ’kеJƒNЃ’kДJ…]ЁKђЯюЛžvž:š_€Йд”Зf ˆЂєš СїМОъ§™ OЫUкџ|-2Й @ƒхЧ€ƒлb]”e€\ъшoё7ymlІжЯ0lй™п§Б[ЎPТfЉ№r_л€§хмгŒПЮЅЄМZ•\јцёй+p‚?”vŽ?^Ця-Ї<”Wщ5))‡Œwи r3ГМ:@Џ’!–VЩјFыЉЪЃ{6+Ujf­P.cд0C FЋRъxulЯЉ#ўpрјq%л?4{4=†LTRи1I.УШBЙYЋUыYЙ1Ќ_џЉЏŒ}ьЅ ЋQЪДjЙšЅ5jЕNA)h/ЖPеA”Ж]ЇqџОўљSвкuкЙшГРіЗЅФшџќё­аОЃ*^• Ж[L&­Тэ)ЩжjќЕ†Љ,•1]U1>zЅŒaTjЕ’ЦŽ|їызнџdЏŽ))q[Ьж­”Q*9ч,­а( ZЕJG—јх§Ј>зЧGtdY™N%S)ZЅL…Q ZЎз*9[БЧesВ–Uh5JРЂзЊЬGО+.wіuГ†еЋ!…ЗZЭeŒ=Џјдq•FЋ•ЃэTЌ№–—œиA’ќБ Ъщ*ЋD. JЪZRЈVвœ)SЉєгk6љ“ 4jЅZFk4Р‡Vа№б*БoПCЛNџя7дПиsаWЇB˜qƒ‚Ў8vР–Л%gпfdK­ 5JЙFAД*ОЂЖТ™Улх §N,ЫЙђЖY&­VЉf9КВL-ѓКЭ&Нф НZ[ЙZN…EЗыЫгrЅ&mиmЩн‡ЊeXjƒїGA-W1l€кйУ(@џђK*EМv`Ÿ|ђЩКЙEуёшбb7­ŠM qИ0{€ЁЬљПН=cџўу%[vЎ]ч6D&ЖѓWЋЉ’ЌSZ;4, „ўu%\ѕчшНq8FЃбnЗуМn~q OмB€ѓn1Nkбб\З_HОX•RЎTШr™R[BU9m‡NЙl~†Gж№€Н•Л+<њЊq{ŒSњ8”$ŽК ЈИА“+?;Бw}ію_Kђ<э:Ї”fь IрЈхЏ_˜wbGюЊ?ЕхЗŠВ"кRщaЃbS|v-§RŸа#ЕcЗТ_dй[’{2Кг`ƒšU*”\љё’J>БS/Gюоr{@ыЎчГVоБ>яШFпv}Ђ#§ВџЬщ2сс`MiюwŸляа+X…œ•+4Сў™ыdьYSщŽ0ёNћєЁЕ+MG6gн~гѓIбКЃлїDv–œufыЇя/+ЮKъЋoебн|{цРПјюЁ!К=?|ф5„Ц$ЖWЩ)РRujCцС=˜dЩ* NJД™ЮDvЃЖeфd9гGOф ю]НЈќŒйKkлтЋ“+0бе[–ЙѕчвТ\™гbw‡ЅѕJмБьуЂ#9nŽ O”м>~пЏ Вїp:9ПшЎэRл)4GrЪВы‡/”‘S;ѕЪпђХбЋ Kф§&о€>9tеЎЅŸЋЃкЉЌ&3“”оЭ–НЛв‘мо˜І0ЁGПТ•юкВЪюѕI>1,Ш€XЈ‡ЧUYS€сKЉ&Ђg\8SPhn—жл7 B^vxяЊEЇіяяџ@jЇ[Сс}k–”Z,М":НЯчЉŸnоQxdmY•Зя xAФчŽG?™œЅƒ"л)5К.#nEyŽG€ї['ЁџPЦВжђЊmqяЮQ Tаštј`сДZ­ЫхЊї–Šёр‰[шц hЅ=l›дWКyI  ы VЉdK—Њb|Mчf˜KO­ќyU‰C†Ъ&R'іо­Kd€?ud§ъ@‡­KЗnи’­Ў„ЋўFyyyllliiiНQм*++У-ЈїQсвTRєЩЛ\СНCЃ‚№“Йз^fЉ(чQŸ6 Ц{i™œєЩЇЙФщ№*ѕО0\Г‰—ЁТЪy0™FЇqTšhЅAЉбpЎЪЊJ ‹JЊыѓ‡оŽB-›ч<їE‰DёЎЊђRž–Ћ ОаŽѓz`е(ѓ “†­™)eXЗ­ЬfuЈ|‚”JжыrzМnЏУЪ+4оSў‰пзЌн?љЉBƒTюЊ2›ЙJІб#Q†ёV•™Aоћў8­Ѕ˜сЃжъШŒ{ e{ь6‹UЁїёкЌЌJ‡хх *ш`+№r(m(ЮeЋ(cе~r a…’'”гRцЅQ `-Ѕѕбл+KМ2Œ”ЂWЩm-Хм$С—ч9ш,fБцR  ­ЮыЈЈ2#бКƒМœЙР”J9&Ц2РЧыAџ&Ъ" #CƒХfЧžЅjЕcМфб2ж–y(3?_ЋАэљљ§v?эо%Ъщt#ЎаУJ8VЃ3њQD”ЧVY.гehбhдћц§#;љо‘н(ЅAЅRТ:‹zж=’Ќ ”$3vёЯfѓфк5І#гЗWWQљКБъ{ЌЫц5јTшжkDЭR^Ќо:зљљ‡`ш…ШnЈЯо6DвDє7F eё e.ЋУјЏкхlќк3…ЏQрщЈŽ"њ+‰IЌЫ'фlŠ”B(ЭќY9]d:\f2Ояп‰ё>(}(]P@АЄнЧ'ъl,cxЕ†е‰ЋŒFЂ*mЈQИV+œ(ўXE~žђЦp"X2’{#‘/ЊŠw˜і e‘ Ђ'‘ˆ+c”рƒA!С$fнќж qˆръВš\‰—šЌ‹–Ы&ољчб*‡=§њ—КH–у)SъjБДЪзЯ ЌИEBrё№Šэ„СЗ…ЄDФ…“rИЎDз:NШ„xMВKГАћх™л:˜:ЅіG# ЌA:•hfL?j8Ют#пЮzЄ\a乇ж~cњ#†тƒ‘\‹ПУšЏ‘މŽщa2экЛˆЋL Žвљ№щŠ&*,L0/мЅXћк"U/n ˆ]"КwAЋˆуЪЮZл‹›F]i0ˆФ ?А‡т –ќВ,*ѕB]C@ŽЕw…(їРѕŽыз •rF†Vžf3УiЕЩо4‘FUŸ§Ї!œгf+ЩЮ+>v0šЉ: NoЈyгjЅJ' #аЌщЇ‹3kЂ'Ž{њ‘` uъЇїnZ1pшC “|ЯEпЁј)Š'jЕzђ 7)3Ym•о]ў ЖИЯ#]§ˆ™—Ыe‹—,йyьИNЇь>ёМjGfаgPЋЛE†vь8TЋг‰/л_KŠr "аŒщЧ—ЂвЫ­YыOюц цŽЌлЉш|ІpHЎYDs`тщt:бџž˜˜(“Щ ‘ј]hк7+I pСˆ ТЪпћ­›6mЮЪъRVДќеЧ –{9E@SFЅRcДVЉRЁu%й§Ыщс\К4cњ9'0eTЯAkV|јаVЅ yЯ h2[rM! ~‡u­?Цж‚‚‚`їЯОЛ”}M)xMмC€YАгвŠ‹‹a"Х<Уъ‹ƒѓЂљП €Ј}ЭЎ‚МHYh5š1§˜†т,+1vzтŸЃУеЌ\Ы—лJrPэЖцџЖjWЯсcƒtMѕ“ВЂ…Ј“—ЫсДјЕ•}Љёt9<I‡ЖB IгЯq2пиGоњё`ŽWЃ“3>JЏІ.ƒ=*к Ў KœhzPыФy‹тѓ\™еН=гŽEМ/_iѓцWИŠ*=6—Зg;mpѕІ!˜Пэќљ§‡N§ўќвІё•ЫП§ЪПћШL4'm„Г%Guу€аQVWюiоНaЩ)‘}лiМ–ќџНџepЏQСњГг„„и2Јuр‡ХЇ\ŸrХйР№Qєb ррВDgС’Ю$Ў7§и~ЗќђЩbu\тСЭ?9dуpГЧп1jHт5ƒЯg–Etˆ‰JбЕМж‘_ЙœѕёбРRcMчЕ1Œ Ќcƒ|•ЎђкЭЁh­A§ЧТwпœ4jz…RCЖzчЌE_-˜Гю5uк4CоКВрA#:љїё7ёЃoюPЙрЧ?oœ2к‡ЬчeZF&ю I0лЁмU+Ојфћ-ћcЛzќŸ7шЪяо}яїCCnyрж‰Ь{{+ПЬўЬC7эƒ|]0.mј‹ру„Œ5c0b.pйvЊI)KД›~˜J. 4њ…Х{œr-a†b§}4 ­0oГ \Ю ‹e€hњ[^ыЧ4PM{•ъJWшсЌ,ч@GX_5ЃVЫ­Ї˜eЏгЁ0ћE§вžЛр•ŒU)Н g>ї+гѕБ[єoЯљЯ-#uKзЛћ†ЅЭzф‰лОщbєлЕ9ƒКC ЧJН*sЩџўћAV”С\r2лэ1Ји-џ{kСЫЬwžќэнWојияоЖљœœѕŸчтƒ‚Е6=>Tгa|яnIW’еТSјтSЛћ/чwFвMB uhмєѓр-qоe­Lшܘ]jЅBoањщ›пЕutП\SЋ“Ђ­СvGtЂГZcхW шЮI…шЈ(– вPЌCЅ|}Јœг9иТiЬ-Џ{п9ћ§љ‘z™мэкS^xњЬ ђTеЁЯФU|јэВЃУП§дбЉЊћ IDAT5пи+F ќ‡ƒ0о<ЏQъzuын3Ю`/ѕ]З!—ђ8ў,(юџЏлЛЖяЈМyфЬ•Л|’яѕУмйsozшщЛТкG&њК:ІЧ„ GЭfсВ PћPС‡щ'е~АџАр7–z~.Ћ%)гЊ4jњЩ–Pцмe_НяЌ,9x$'8ЕЋkЯкМmфыПм1ЕgЋъx&Vkхq":XœД$+ХІrїЦ=} ˜А %ЃYЙCF9`ВљЌWv^A­Злх`|љЉ‰}G/‹Кю9%Х(Ь)cп|y Ы{ѕZ6жїдЃЏьлѕЩЋS†­аЇ-zl\‚а„UДямЃ[‚ЮS"зѓ?КYˆŠйДыАm\—ућvњ*ЛЩ4šЧоš|щћwНљщФ!oyміЬƒgМЃRЎФў|ёAˆшс@-’≄РЕ†@ЃІ$$† дч/ЩоОьЫs>іHАœкћХ+E&Rm”\sˆ†UNœДМж№7мpCQQ F ~§ueЉЩфуы3vь8аC‚q1­c*ЉwЃdfda‘‘ZЦ­щћЪ›ЏЭњљ4Я+˜>ћ?ЏЮzроUсэRfЮžешФXMЛАшы ёч†ФјА|Рє Pј‡DЈА!"…d‰ё‘  }Ч_šyчэП3њ„Y/нтЬм7ыљw хЗо "Зєс“о§їОэxћ Ю-ŸCкH­qПЖжrT|x"­‘А”†„РeŒ@3ЄЭ.Z–Пыћїч|ŸіаЌш@њРw/иCЧ?јЬ?|%вц†I›Сфm2™D‹v\8АŸƒЦ9!!DФp7щФй‡ˆОpсТ-[ЖТ`ЁфhзЎнƒў ,эˆZ+є\“Y§ }&м№NМVГMŽaьќ+LюЉё?q‹Ь%šPЄH ?‹ХІжРеXа ѓДVЃ%И6#wќD>@Nœ8‘‘‘M@Єn8@ ‡[pз`нƒоx'%вfђю_УЎбZП€ ™”:В[џuП№\Ю+єЩw>|ЃPYМ†1k.ыbЅGXLE'ž7•мGHёиПџСƒЃ†J&ё{<АSт­Z!Е—чžаZ}5“—X0дЪЌˆbыЋ]M(R0:Н^Pœм“Јd§5њАиЎŠdІ&ођ ‘ё)ˆч@RММBr Љ)!pёhмєc/XЏuпІэ~‰};н:зoˆеЧWчШ;Xzђ(пљт+rЕH„MЉ›бФРєРеѕoіц)&&ІnА–[Ћz:двьyНИч\žsбЌЄЫ%ДёЧ œЈ–XйЧх5XыП\ŒЄG›"а 'у­мёѓ7Й&оrфГ_>њQэЋЕd?s$›0ЬKЎ9j­Œx‚Ѓxв\МГїEƒU{Машg]ѓg"tЕтЄіќšЧFрE ёZ?Сp эv9эŒнjё№›Ю,vЋ–\ЫMLэБe‘Њ;юыОаCнИ­s^=r@憑™H­“hЫSЉ}тIЫ#^у!Х™QM7Œ„ё<ёЫюЁ_“ЯЎzвІ6›§ІL?Яhttб'/п vU”›ѓџНоS\8№ОЊЉš•-8иs=ИТgf6gb8В ‰beёэ Aa Хq…Бс-HЁ:Q|БЕЩC-М2Ѓ€сЛ\Ір)ЫУ“ Я/'зt—“~—Ћ.˜›АfЭ•А€h§ыЊpЩWTTfчкѓKxЇ[ ГdљIƒNиГбљДт—QmИŠп\tђ7§o ' 5&З [фыЭiоМ№&Г&~М”‡ЃМУSиН4&JщяЇЖџ#Вs›~žт§ˆоя\n+ДђNF#Ї• yx\ 'ёѕ7чпіЧчД§Ћw~§–Vcvs•UЮЬpЯгтWёеšŒќZ~YќCTП #|]•ызяьCЂх›NVнOіъnцЈј№ЙџtўхіGVНЖГђЕ'oUЂњлPHкМi˜…'œдО~˜…LєСDЁmліўїлœm'}‚уCЂcrŒ:ŽЇ1А%Ќ`1w Ф0x{БИЅю]”x“ВЉ2f” N‰eзX1ŠшDІ__ВŽЄAY/К(pkНТфL‹Ћ@„нМ!сx5/@7Ђ9„C+ђщн„њUЕn‚Z8ˆš“Є/HјХЩ86Kч]nоЩYJЧŽыЫяЛAл%еŸa›Њ„5nњ‘š ˆnяЩЫЫМъ*ZЏaСнІQЗЖ}'ЏђдЅ…С сlnоэЖfь)иПХC1r^e№ѕ ‰Р—‡/єm|2эШя…?}і,c)\ЙtQHпёZсuЏƒцЖ3<Щ‡7qI5smќљЋВŽЗѕ 3Њ :оQ^aЕСПЖ)@Тд‚гzrъофyЗйr”s1nЎРZiЦ-щЉ‹Яz.šG___œ xБР‡YЫиєdбt`џО/ОЯXy8"А}№Є›bТ• L Цлрх=в•БЄ5Š9Ц2LЉ"я$ёАо^яСk $…Лx5Щ‹IЪT^yДaД!ŒaiЫT_]мu Т!ўфHfш’їб!IЃŒWE DHaрIѕ№†т*ŠAь6ХC.E’a"ŽD7љ^d„сJјрDЭНШ)­DнBHЎDсBъ;уDИЈ[wAsяvqњн†_ЩљфЗЊ9б\\4vЌїŸ}›2§ХaА—ѓКС|H{нrrM$gхJg­ЂФK•W:ёЂЙmкНцЧа‹ТћтAЦї6dкф=Ѕ(бgЫѓчм0њЅ^JЅ†‘ЫhOyЮ?~mг!њіЧІѓз–з#№ѓЗ?MКўЎоeя->8uъxBпЦsj]РјІŠ CіЅЛ||М2šкБтгmЙцrџш}7}џйЋбџx|šOоšвcЛљ>яг”IџьсoњpйБQНТпїЉByг§гЎяы+Ьі'› “Yџ’Л*€­ЗлэшіСОЈьуdѕъеЫ–-›1cF@@шFію?Д-з‡Š№—ЊM6^VСaLМZдX`Б72ЫУ.УОЫЌ8ЁI&OЙ=)МXЉNL?,;‚ЩX2D›‹ .EЌ3шЄ."Їy9ЌБн0GŽћˆ%XvVЮrEXšHБСЁњ‹шЄМ tРBиObсЂn2X$`Є˜!ТБМК ХьОXЈ(A8‰KдУnаШ " -9C4 @\ZЭfœфКWаМŒd B…Œ И5–qЇ‡wКЙЏˆХшU0f9гS”ДLеиЫиŒщo,šфщ@ E+Їн<хЃbт 2НœпYhcœМй’_щ(;$юыKyN]TПзfћћтГўћšZ.S*<_N~­ЊЯ“wычЬ}ћу§—l^5(*}Ю3ЯпоЧпИkžьњ6oUС‚Й/l ˜8ѕncСЁ•[ЪЎ5№№кoЇ-xщБo_yvГОџwiчЬwћXув-ЋDЄОіЬ SЃњ лїхЉoPwИїБщ9ы^ќ№?пŒьїhcМ—%IђЅFПЌЌLЏз~§ѕз;vь€ ЕX,ЈўлэЖ sU…&ЦЂ1шеG љ|3ЏгРШRи^цѕzK)Ыpr†VrЦЕf,Феe…6”Ч+Љ€E/ЄEыщ$ьД№ЄQ›AБХ‰2уrги}/OЂs„ЫхАнD8NМ‚pDЧ]‡щ<†œф2жТQХwyМеw=Є˜QШНZИ\Ц ŠСv КqФІ+ У‰R.ƒС%E‚ДЫ‹z4XeЪ:КђЃ\Ц'Оcп‰ЋVО§Х’CуЇпњ№o_9ЊFŒјg-}ЋаІuыг#&$HЧ:БdU#8u№НїMыг.єЋ*гщПЮ?ЃбњДKы3aеoѓОјўЯ ЯпŸљчЏ_йЋFНзUuцУwрЭ…&”| 6+/(’˜VGІ_­VЃ^UU…#z~pYYY fY\jди>ЃСЁїз†‚‚ќŒZЅNMъvt;#ЮaУ TŸašaиrTЬ)bм9˜Hв2€ЇH›€м…Y!ѕ}Ё?бQMG ’м…‰gбёBЃД і—#Т!A)#Э\1 Œ@8lДгУ!њj \Јд#:ЉЁЃŒю”+ЦA8Ђ#$Уˆгиƒ†›шцц QDнаБн`єШ]bм‰pBt#YCљ2Œ&š MфKЬ8б­щŒ ƒтатФCдэЏdœ–|•ЭЃЕи,•2‹ЅŠчмОJЗ\^ƒзњб, вmмkВиМUnоюцЪl\™u:Pnb›@7i†)*ЈТмМАА V!Џў­ДЊвЭшdœ/ЫћЈју•оЮОЈXPU˜<Уаz|$е€гNщ|сЩ5}F.9CЩЦВjKђЈЙГoaМ.ƒNч—ѓдІ?ї-xeђрп юy!o-‰ж+­Jя=xp‚WЇI…OcЦMёу+хКЙ/пŒn>ƒNы›§ЬмвC{?™5iря~н{)rСєiБCžшWb˜љ}ikЃћ–T @SJфHюъ@Ж=ћшu1 <№–—џју№ƒѕ Š‘ŸvЋ: PњъдЄgЦюlO*цЄr-#GиPb‰……gQЏ'х)ЫŽ*(ЉYS.bпQѕ&sfPjюDt‰щ'…‡ Е~˜]HЃЃПˆюB‚›…иzЈŽoFАЮ”лВB Ёu#•w ]ЂpЂ€§ЌnаŸє‰jуH4GmИVsDG1ƒˆD7ђќхŒ К§…Œ#ПаЊЪ&“—ЃЂ'ЋЪIf*2*гиЋXПжяvyЛїˆ8|Мє›Я6кќBьыХpˆLІРўHRЮњвВŠУђТќЈ^н1кг˜hЩџ/ €/ЊЧнЯЅNОЏ4їє™] ђOQХйцЫьы5k\vЌГЈЫ(bл%dnePЯзоћ•™hу>№тыяН1ѓ{VG$ЖёЅ™ƒFмr—Nu§˜БсоAбТљCОNŠ ‹I@щ"ŠRњЦDЈс™ б+аIћ№Ќ9яЭuџ=Ћ"“R_|iЦ ‘ЗмхЋ‹%rЦэЅ†j”C{ѓѓyЖЩQJЫІ-ЇЂ’кы•”B9šкЂщ/d_Šrљ €Z?ъŒ "=d(•юбЃGZZЮс gя^Н8ЖгДЃTјќ(Ѓ/ЉY8`Тœ*Ч*Й`њ#‹nkЁж/w7ZЄО ћKЬ7Žrb^‰х%j™ЯP*ЁЬ Е~˜~VИы&жщЂ\Ž[(THЙR#\,аћ№ФИCдыeФXзыЌŒОI­Т9"f”D…г"e›фнIJQ7! –ИТ_,ZšЮИЫEAЗK‘qˆUTQ.šБVP*[VїРœЮЩ}хŠГћюџ^еЇoCРЗe[іщ‹‹У.t2ШЊьU:ƒ^FzdJЦedЫ’тЃѕŸЦ:’ЮOщЊёС7.Жии†щл0ЗpDЁ(ђda| ДnIII)))0юMCжi]ыщDЇjўsIЙЄPщЎ Œˆъ>L€]H†ЏШhdГ.Ф]+WрZєGŠЕ'ЕI!.|Фk‚_бЇ 9ˆŽНЏаžЧ”:LЧ ~a,ŠЬ‰цРе&гж'аѓшбЃЧїїї}›Шр†Ўj8м][ыикщуЕФ й,}оTіƒƒƒE”№кCQk?y8|јаŠŸWž*Ж3†P•уСфDэ}#x-ёvр…Јў#„€То/™†ЮР(ЃЇ0“GxуIЬФ!3дI‚Њ7ќIЩћ%ј“i”ЄкNю ‰ќсˆ%оE,М’т-съ Ч( 'j„“5б—D'sоЊ“†b( ўъ ц•ŠЮЯИЈЙ(МEЇ]`Ц’vЛhкiAпя ^’’SаhkтнЊ_ыGPфn№€ИЁhЃatз<•——‹Ю>LТ"—јТй(4эk_‚&Ижn1ŒŒY­жZг/2wЂУŸаh4ŒшзMЎRЧ'уЏж’…ѓГk|„7m‹,|еЂЮЈ‘RзЇVP­Їшг„„Dё@Ždю5‚‹ ЃyMRmќ и>*Атƒ@ИЎщ-ZЋиКЩ&њjuХbдmЂ€ŒŒŒšrуфœ3YцЪrЌA$ІІБЦ ЖDИРYwЭ/ёЏ ў7И+†ЋЙQѓ[З‘Л—Г№‹Ў0ъxЕu†Ј€Р _Ѓ?’Р-s ˜~1ЈЭ›jG іp,ў№X‰žŠЩ‡ъAЁЁЁ8b- Ќ!О8ЁвяТї†*'b\А­AКXз$з" - T#Б‰п&хдмЌљmBNлнь>‚#uў:МЭx™ХЎŒЖS­mRFхн8x3›Hрˆ#ʘФйD00$<НЗ№8ФБXŒ_‘'tАžз3tžа:BŒГзXБmЕкT*ѕЙcЬgTŸA-щU8ЩCBрŠC@шЛoжbuЉЅ Б. )Zƒ>РGog”‘FчўUы_ИuУŒлЖ~0ƒ< ќyЬ?|ёсž,ТЛ+ѓW,Z\\етѓўЭпќцmЗнvЫїОљс’Š’Ђџ<§ђўJВрО‰ еьЬ“œ„€„РŽ@Kk§—4›—CЙr™дeEос=Х'*dВт“Vzxх–ЩXь—рЃ TX8ˆ„Фaޘ{У—гїџ^њЫз/Ъ­Хkў1zшС:8ЧvУR жМzъЅаY„&‚{сь‡п\х|{о3jKжоc&чpИВ(7™)€№†ње6IŠАјєњ ђЛŽЛЕKЙ žФеЎ>ќЄƒ„€„Рe@л›~ЬВРqБxыл_Jи8ЌNФ VЭ ХЖ|`аgятџЫ]ОUўbЧЋє)ƒЧRЅ D?уу2)mXa]K™ЭыіџБ`іВ‘s”:ЌО E'ч4gћњц‡Ї­)ycпрљЏ~аaЪƒ§ƒMsПйя=7јЪigёЯзŸžЛр‡сi „ывo$х6РЪ=Й’Эпѓлš§?Цін№ѓWжА!#’иљГ^п’wн=Oнм3єЃџћјЈb­lжгзїћшн[s“юyќІсёЫџћоО"‹\“ќдДЉrЉ]а–o”Ж„@‹h{гŸŸŸ_TT„š#ŒoНk‹r№їЁАAСƒтKW‚‚.€—ЊŠЎ^њ5о ќж йи%–ащ ZаЛэ›рKжчWйЎ№4Yьp}›6ЂяœWCў7ћ…QЏƒQєm_ЬxqЋvр3шgП§Ю7†-]Оzd\њ;Г_Л5ah яюŒR• ъБЈНЪЂ H‰‡нЏ^Р%Ъ­%ї№Ж“A0§Y‡w[МН ЪЗ|ћЇuоћoЦјШtlпд˜„ї В|оєMжЎЯ=фћтsћіўpЧЏ їwšію”ыАюЃБ|ЕЁЃŽW*&%-!аVД™щЧЇsьи1дЕ;tш€ѕb˜QЯПj№Аeдt@`Ь§РфeЌљФR,,ИE# Y ˜ЎƒYЯhЉН"чЈŒL‰ŽЬяœ8ЏЫ+ФVEГТ§52+K[ўj™^ц9Ир%/ЭЊє>•Љвyg*вƒ8Їгнcќ,њд=ГцОЂ“Лм‡эхžŸЏ KNя3vеŠ9ѓИщхЧOXёЙУ9bќП@E…>ŒT™•Žв’њЄ—ЇZ$YЎЇЧТy9ШАb‹ ы3fbвЖчЇ=3цўЇз5 ZKЧЦUђ“–ЂьЇ?,вEЖcмNuXъ3wMMS\†$>€рлl6ёqˆыЙpФГн9ЯOКИ6h3гЫ•‘‘Лuя&—Щq м4цbБ ж*…sо­cТ€YАќDЁ3hфѕж@5-FOзЎ]їюн{ђфЩФФФІУCеыќ5–Пzr'ь>ђ%Zq eГХ[•‡39МœLЎ`iBAЅRacЄn:ћ~—ЇЄрTйЉ#Ку5лngЏОwњŒM}‡ќ’гяe,]эWмэеwяІ]6пЄPгSѓь'Э~y\Ÿu>]ЇѕŒж„Іі ѕ>:{оџ=}—ПЗєDVIBœ?Яy –їP™Й…‡w,ћтзЕcŸў—ЧЭнјЬьž?Ю№ГeїыЪЙьћWяїєKвЧFМњЮНДлІоАЁМhё@ѓљШ]*РЎгщР<,ЎчТQДў5–Ÿ4ƒ$'!p­!а6ІfЫl6ƒ '== же1роДMD]ќрж-|hjЇ8?Г|УЦ=ёћFћЋШъqСфЯЭ[нбw$ыi[ј aСR<ЦФФ9r+зa&DŸЦ„@Uє5xЗD PСPыМ кЅ‚ѓpv{€Џ,HЩXниЊ‹ U3ЧЭX44rж ВNтРQЂLщи)@щ‘љІМјСлs> z№;fЭБП5ыБˆLъ№ТЌŽИ§1?U„_№ЄЇФР`kDњ6žVЬœїсмYsg<і FŽу:Ž{Іclb‡t5Х‡їi\ўк+KL]†нЄЗхыЅљХJŸЇ|TХѓН'оБhцg?эJž№ш …sžyќСТк?ѓдЃэкw2’ %ђйТИA|кФГжЪуqрGёф‚žK›h.%*!p‰h€О­С”а#O8|D"‡C\ˆ'Œ#Њќ8FGG ”*ђъ9ъ Сž ›њ•oзkpjЈЧQјэвѕщ§FvŒ2 RэryРQ‡mЖќђЋ7ЊлРŽС нF'6ЈНQуК2ъЬG9/ бFЃnŽшЬ™3а*>>ОiгžŒГѕj§ЕU~аЗ%''7Kп†дГіnЩйЛй”yИъд!ЦVцАZR4?ж[hчђ|тCouЛх!Ёl0Va‰ЯЇ ›"жW˜—ƒK„€f,bUЋ*юuЛx†ь“ќ"щsfє€„АIll#‡Чf­uЊ‰[S W'q9ќ ушЪCПЂDпv9<I‡ЫЖЉѕУС&‚;&—PE Ў \Ь}œгn)-Sx\DIМЭ\В}ѓіR›Cm ялЛ 1тМзZVАyУ6;#Г™ЭA щНв“Сыз„d(C" pН€tчФЖ…ƒ&Б]ћсЯƒЭсpкЊŠя+9К7З0+аkЦюзIЃІ Œ tЎЎb‹ЪOС Ъ‹>!fтlёš$2#wЕœjБ€ЬлЌ­М“ФHЁ x9ф—$њй„ЊUЊ‘.§JH\оДщ‡Н@§§­рxEЅ —pЭЂ„Юmlд“{lЗ=OУ{mЇlнyЇžЊdћwэАsћŽSЅЩиN=Gи/ЄМТžиwHИКќЗѕцEХФЂ[ЌІИZ`ћаŒЎ8 ~ЩНE3™–jB­7ƒC“\W›*l,Ьnэeƒ'5eCƒ7Яёl$d}ЌЮ1ьu.‰~Nв…„€„Рeˆ@˜~}XXXок  S‚Z?O+уR;їJ №ИL?§В•S2КШйrr‹‚#т‚tЪlдCб‘‹ 3u~б‘aFК2ŽТш#•КТuRGЂpт n‘РuЌ[нР­y„Ю›њiжVРыпЎ%$$ZŒ@KMџEД†Ђ…ЉEнF_tИ„kBmbС}†5ZcСFХ#7њ…ЉНЇ"кЕзГnЕJŽиЖ§ўМЕјфЉ,Ѓ;›Q*ƒ шёЦІ9ш#Њ„#TjV“Цф\,"ŠЪЩЩ9x№@А?™Gфp8ьvisjv№рСPѕb%wqх!вt™Њwq3+I“ИrhЉщoк._hўaнР ‹§L0ј&ЮАnV>ьaD|;>PGкr]‡іЩўeˆoЇўvя‰cXЅ&Е{xєmХюQeижцz ЌУђRЎ‰юbјI›СLЬўwЄЛа]Ќ№Р!;;л\YЉV)Odd„„ЧTш’н^/zЗД ЊНоЛsэJ„ТЄ…#№@<З IDATэˆ§я„О­ЖяПкˆŒаЙ$Ш9/2y"B2-V1l3ХЊ4j™dќ[Ž›RB ѕhЉщПИšСЌ`ОPnn.FaoБлЇй$RКїРоn˜Э)Sјіюп3чQЩOьв7Љ3йЂѓИщЎнaЎЌEUŒ6tр№бўjЛ"Мhцš#XRR‚Ъu@@@!/ѕ- s`џўШи3mАzх:'џж!є[QaОt˜‘КNСx=‘ЌЌЛђлO?‰6ЕOBˆГwБ *H  6D mj§b†§ќќ`20•6umpЈ Цх" ­ф+ЫK["•}№1`B'zљбўРфЮ–ФКЄaащ„aLАd8ЇBЎщOљjXKVRсF6гVНп&Z*† уы?ŸЙhи[#ƒ•ZklgПћб{Nа“x<ЬД*7pЬэƒBпzюЭє;џ=8Єш•/ї=ња­Ошќтym@pС†ЅЯ|:ђ‹ћњ‚њM!gнхљП?sуAл МЙ+џСЧџеl8”3ЙgЅKџ§Зn§lоvoЪє{}ѓхч1нЧqЛ~њр— Ќ1фю{ЇэЂYќўЛŠьў!УеZЕFmкїЫ[‹Ž>ємЃ† \Y}I‘•„KHд а–І: леtћ`ХS^^^V­ї‹ ,ц˜ }œД^ТЇdГй§L„?%ЏTЌ\О4ŸўъŠіŸшUrЅœџуЋЗў(h7ч…гŸ|ЃпOЦіM рХ11…џ|фƒcћ~§хЇЛ=oЖcуvƒПяќзЮ]ВРЛяЫiЯϘʺѕ=~-2ѓЩл‡mxomо‘eгн7lкЫ>‰gуYК#!аІДБщGоapСš‰х]Тc€І €6HИ‘$‹K+t'ЖN№ bi‹V{њєщЪВђо}zЗKHPЋT(BTGЙœЎƒ~риЁзо~-&"PсёdЛЋN§{зХб…oяіњqєо{A,и[bБ%&БDcŒ‰%њЧФšиcM4БїНФŽЂbA,€ E:мqЗWіў7ЛwšФ ‚BœсиЖпм}3ћцЭ›+~},ї ЋесшSoH2oтнЎЇшVНКУˆŸY@ш(ЕGФ'cПHžЛpВ›ЌЃAŸЅ.IП›ДxIВƒ_И…Tъ(ВЖГГrqqбЏќuОKЇЮmJJ­кТuят$*EF„КYsdmШu' J)K—€Ю]пu”“|RБйЯо­>якЮо-ўсq0F#№†xѓдРШ&{п05 x€ЂCЧiЉiК’œsёёEхххлиXkДš§ љєSw77Ж„ mЕF]Њуcйp|Co`ГЧ нэГё'wЕXsвљ?РЪеSd;fЪ)ЁВsЫђ .ŸLhыгД}ЇКuЛ/_Йћ€{ц–ЧўКтТЗЅЧJЎŒНї˜О№Wыc/чыaЃ цŸIЕ’ќpђ 푉#'ђ~œ<Нdр |Џp0Я Р;vь3A{ FЭ`ўГFŽџЖžo<˜Žu@аЌƒщfp`7ц3XлЯЏ$˜ѕєє8{іlq~ќ}||ZtI“>˜8pЬŽ€.,JФЏзфхљ…Gй[й‡…ћг’жЭš7މ*}И{ХЦ?“х4nйЪ†Oкљ7шм:RЊ-БїыоО‰д %цш rВ`05 L§5ЌA˜ъАt\п5Вўћ‘­_ВўыMТђўппћзаŠœ]бџ—„ЏTЪ_rУŒРыD€yЉЏ\јЇ^9œЊ,–qф'ЦUYО8#ŒFр­G ВЃ~Xo•`гј­Gь_€!9ы`8ѕГт~8џKbцЖYŒЦ|Ў_Пют`УxdОMMQ:Z ЕkзЎ’YUІИЊƒfЪQU›їKцЭС6HЈ €Žm Р™u/™/N†ЈЭT–њaХЌ2…ŸPm~изQwf€ŽPи3Gіђ_+ё№сC0п&•ˆ’“яЛyњхJ‚5z=˜ё‘ 9Ёr§…ућЬ9sˆ ц|‘ $чЏЌЋЭЭў5-"ЪJжИB™ЅEОдB ;Р<хŒEАSгЦ;Я–‰Њ›-РЌЕiЎтЉ,^ст™†€œ Фь^!cœ#P[Ј,ѕУѓСРПЖ>хkЌ7;Ђ„ЃyШ§%ЈчУБ2лВсоКyгг/Иˆg­рd*(§Я7 !ŸѓmЮ扈Ck5ˆ”сЃ-Zџг"CZ…Иj эмq$Іп`W™q‚їЙO ‰е;—Ю5ьѓnЄ?­ЪлБigј{ƒ§mСмfyпЕЉ  љмЌ*оDѕ:8§ћфvŸOъцлЬY„Оє5›ЛёP\_Иv‡VO№mН{}д?иЖћ5ц‰яФœПxeЁŠlїсџ†u‹ЌCХR^иАУjmpАxќЌcэХBgƒњь0o/№Н7’АчхЈфЗ‹Ыбgгv/й§qOf|фŽcО­ДЬPЈ0ЈŒцл@9_mяТ/GЬyЂхpU…ёgORH іЏб ]с`r0кe+ApюžX9bшдХz.­N8w4[‰t OшЄPlЕqђЬ}ї рE]šraЯl–Z ШŸи"иДлAš'е3jEН™ж9zэ­ GГT•}чіЊmл˜G'–L›П хfЪYwѕ›1‹ ˜Нfй‚!ЮUХћьуО\{сTџ0/@§ьЏЋЌўОЯ!9>hщЭiхУѕБцКЫx^Vќтb…БZюф–ŸМkъІ#‘H(ѓmœ’ћ SЦ јАп Ећ.žи4sѕС„>Цˆ‘‡nцъѓЏ7} ˜љ„єƒФо™Ъ9>aхя:и(SBТЦ”Tnкм‰C>ъџЩ‚ѕ'ђЦoиБcљиo6Ў[іуЯыдqxщЌЩKіењ•‹тnІџuAџўŸ|4tјўИ ‚Ѓм<яы/ЦœЛlЋN(JDYvŽЗ Kaь HО-EƒŽФе+АEЫŽ§bкЄяй:wеŸаБЄ\šёЫЪkgo8Fдg]I,єѓwE•Ф#€Ј60ѕWД/›qY™Z""Н8ŽжТ3'ЫеkяІ}чVыЁйўгЉЯьƒœйŒС|›ШЉбТŸПЙ>{кёыyR!_Hj—Я–,jљнWяюќu‰J*>КџHnъеUkVЦ&мОvњИšрЫI ќi-W8oйЬМUѓwŸN“‰вpdЫOЇђƒ&7фФњљYтРn1СЇLПkдхиc3R`eяž=ЛЄоKИpН4эьќ-gќКfjпАyгІц(t‰—Nы‚п§lP/‘AŸzѕЗIгіЖшўЋœƒ&# Ь™/м?ѕчw“‡Эйœ5ќЛOуіmЙ’GлЛЋDчЊ'ŠЮ_ИxёrТŸЋЇŸЙžbп5^Cœ#€x>/ ы~FјnU!№$ПPx§x;k[ЁWяUDьGДGБЂXs;џњm›гЙ…9Н9Н™В ЅhійШA7fЭћогЫ] г?ІеiзЎЪГ ŽŒŽˆjutћ„ЙЋЏѕѓє„„k(Ђcџ^ае3$ цлTЮЁ§О{wъ‚oНџr”цQxЯЏVцQŸИ aшoъ9ўšС`^<ъ№Њ!) “ЛvэbgcЩгЉ.;Ѓ.Ѕš:З•d;ифуіСеФ=‚њАХ‚ўŠR—hЙНПœsїШх"ž˜пиЦеSVoЬФ)Ÿъ`чшшЎ\ДЊЌoя’‹ћ/ІфF5p7‘)˜~ѓmњ6ŸŒknШоw: і‡иyy’УЦN=т} W]XxцРЙ2ЁmЇ№?іЉѓAoы]Ы6ДюгкУкIyув‘їюX/р:ZђЕЊ2 ™oуЈМЇЌnЎп?bьљj4mРдж Ѕд КЃгPю.ZЖwЛіЙ1wLВwЋzNB qVт‰+IуЎ:ZћЫ‘Šц}<|РT•5пV Eџ7Г4Я ™U}РУšoуk`Ёс_ЌМЗу'N”–(okndЉгЛіJ-L9ŸyКЕW‡0АъМHыЅ џаH9˜` ЁHyLtTЃ–MЕYGжlоћ Ћ qLs{Бд-Дa‡Іс–|kР{-z0t |L+Š =C8ZZFDEЈ IГш&u6’Qчзlк•x?НQѓvnћіюp‰h^зЯ[ ДьмЋ‹З-loў^Я&6.u5WЏЙYъёЭЄq>6М‚‚"ЏаFіRžЂ л2АхЧ}zЄœ?BИ„z; ЇтŠ ‹<ы6Жс*K8Ё!$дƒ фvЁВэ{Н}­DvžОYkWoКѕиbєфЏн­„fYбП"іœаїРV` ЬЗVkОЕр†DJŒ{Nr| #№_E ВцлўЋЯ_хЯefќg”;€ќќќЪХпџ\6ь]ѓ№aЪЙД3љкќmщЋЪœŸ Б™˜uщЊјHC}ЇmюA™mЁ*xСЯшЬ36]A 6.Šjtх‰>”Щ‹т@LуTЋЩg>Ѓ\žŠj,ЕМ&ІЈLхPnltcpy5LЙА!І+ІјђЊЂЫ—v'ТЛџ>tКXЙѓЅaФ џ{`YMlSиМЌ~§žgћеmSZЮН}stыq7_пvечЋvЃ5.gP3УТ†2ЭBrVˆЫІ.(їГ)Ol†8›qІ3лс˜oKEзцмЪЃV&˜Щ в"і7gСтF#P`ъЏT_5O–§Т]"рcЮ+Ъ;>pљямј4яšsЈœч•WЎˆŒѕяіIё ŒFрРдџ`НЖЈŒ(Ч4њ*FЂ—Ъ,г}mФa0ЕL§5Б§Ж.ШЪЅ…Z,њ-G$т…јŠпo!її›ф7еZчg„.ŒЦЋrœ9FрЕ#€•;_;фџV ˜јЬ-Ёя=жIddЇжяutH,цX–›љ„БоS!9А2CЬ(ШьЉpџ_МLъђи\ КВЌЌlёMƒ hMvVІJGЃь0џ АхH˜™ АЇj@№šдe*їН‘Ыx2ьЏx?“ r$ъz ŠТ‚R d“ƒ,uE+gŽ;t- *Ћ-H]ЗxI†‚щ˜Ъ›т§уbх&юћњлщї Lц˜JвЅ)“&MЬзТ—‚­sбь)уnd1СфВDe˜Гf 4]2ц[5ФУтОчиa0 $ЅE+qžvІ‰>гљщЛјъy•;Aыы7ьзhЕ№[ЯKiК†nŽ\-ЃДtnЉ>>›КЏДдРmфbpsT”Л€ВќэcЫцэ/=qb™#U|уЪй§FИ[phRЁ6XЪezŽЫуAЎА—#5XBжiuьIndmнюu+,Žsю:ЊkCъtII)WЃS(ЌY=!ei ‡ ”e6z6ƒ“Ъ*E™H&хhЫŠЫєrK Фї})˜т‘hпs.ЁU—)еБD*рзY"РЮт†­ xLCгz.\3Ю<>cо"ШО П рƒž9Т.мhлWЦљwц G€МЬСд!˜ЮoZ•{T„€Hs€bІAРMџv"шѕ+ЫЪž“ аВZM'?.ЅFІU—Nшk kkЅ<ŸЇQ()cZ`rM)ЯвAqюї1KZЎьЈ3€НN*ыrмŒe‹RѓZіцSzьОMЗQяКџoшwGNяф’1~UТФqCЌy4‡фkвуw^ткЏэŽ_ыз:ШŠЃјsбдUg: -гђЄ::nгЂY;OиHмn' рŽЏњv]|ЩЕ=ЄЯ–•3юdаѕкєїY‡нsІэИzпй/hт㉔Г3&џ”Cа?лЗuЄ^їцwwJ$—Ў]8kКЅ•ы@ЧЧќqИш­мsкпТќ‡ е`NX ЖЭ@cCр(Ж@є…ј‹с~†ѕб 3ЛŠ~s і08™`PњЇ t­•&8–r‚фqaм,"tnr.‰lЎаAWЬЬЗ ЬјЙщOcfэї%‘B.ЕdсьTЛNc>—N™ЛєЫсQБ‡і пВ}ЛЎхЩW БЋЅЄuˆ=О[ы_чыс1їuњс—QЊ3‹ўМџѓŸл-“ї ™rR•}}ЦВ§Ÿ­јНЙ4Йя‡?щ9†œ{7юQ[g ?<џыxuНЉЃBОПДKч:ћіœЊ3zњэълIш‹NЧJ–.žфцяkћ§`<РЇh="}єЅО7а@ќЃTы Vx#ш­Ž0HEмЛ=™p \э уАќЦŠš=oЄт5ЖPГ. <4爇F›DЮЯЉ;€+r—|с ІяхRоЄVR)OЇ7РG жћ JУє (+BЃQћ48vФЕ9s№єѕДO8š'wcЗ”й6lеЖATГЃлЦЭX~mьв™ч/o]­сwд—ЯЅЕьф№n?fѓЎ„ќёІ]чƒ[”Š}§\Є"aˆ•нui>хшрl+Ђ=­Р!АxЗУЛ>6’"]Y~кХ[г#ZЖЗЗѕњnЮИљП,ъs(lщќ‰ { ‘:wЪˆс ŽŸкЗ ˜ЏxЮ“ОІ[РэFЩ;фqГU№?;цЧџздȘš…‰Оџ эУ+0Cы0PцbŽ№6tХtь г Р3Gс—хПkKЖG„#ъи#‚ КиJћb]N(оuЌ`м@’Gє™дЗ“mгњђ‰?Ѕ{‹†їsтѓAf:e•ZUЂ!њ~9сиЖVлЏШЙ"IsgяЌ"ћ!#?&Д*+{Ÿ OЭи5ТгњпZ>џЂМЩЌ>ДŽтё…Oў_в|Щкщv|Ђs#ЧСГж<‰Zђ№књ]‡—v^ORXиКŠ‹-лК+X™p$.љs>_ЏQЉ•*‡_Я%р]аиp1GEjr t6#G9t~bN‰0+ЄkџOЈe?П<Ёo3иsцяzaHЮHкƒЉџ р‹Ќ№<ъ…›#NšЫб›pљдм4F‚@ж™ЮЦK|2СТ@…†хІjw0lйЖYLxачяo БšЂ?œ”šPlС))‰НZzрјqZ)п [t„Оr[б3ЦТЦц{Ёgбk4ZП:ѕl-эы6 &$vM##ЗlB”œйВ§hjniУf-drЏZ5Љg+&МъєˆiфFыh.Ÿѓ(ёКSt‡Жѕ§СЌƒЛЁф‰gT—(/он‡lн›6j\ЇqГцс>жGv§Ёжiб*2""DЄWЪ=C},НТ#eКј-ло{œз(:2~ѓкпc"{ ъпЎ^QђЕ5Ыз&гЖЃF єБ—˜F oђk/рѓoмКuт\œH,6Q?л@РtЦ#ўњbо2š~в iž щјР љM:№Т?ќ|‘и_ВёŠНРЧrX`рЭ›аhўœ6ЭїнGНz?šђзƒхПчl8\4ИŸKaТвЬЦбvУ;ZŒžїˆg)ўuŒ‹ I~ ƒ E`v_gрЄ@,р)U*шФ…" — с[Ќ*Srљ"!i(SQ|‘”фhU*-ъ ОPDrєj 3 KpХb‘V­ц’|˜`€цGš<*x9IžDU хЃV1W[2ъЁыˆФЬьЁVЉ1›8Тr5Хх EHБЖˆЄ4Аyc p0ЭЛqћЖ sgYZZ!’‡Б?Ё9гC#k@5q0Џ эaК ЪEП`wvЌ Kx’€;Ь„s…Аќb›|ЏЛЪ5М<Жk„#ы aэба ŠJUІ‰a}œ†ОяˆŠУ9Б\Žвr8;чћъ@њьœ 4Ѕ ЪUЏг(ŒГЊШjAё„^K•!zG:—Ь™Љ, аЈЫ'a ДŠU:вh=_ЖоЄšЊ…DЦKe, B4j•9ІZY^l_†’€3Ѕb.о№Оиˆ№§VЃN˜њпpГртп,hšIіЗ€f%™q>œ0аРє! §1§C9їПйzзмвйЮ‘єH>Ѓn•Ыƒ#ZCX?п1ѓЃ4 уЪ=&F§ї˜сљ…ќгнg2цВbЊŠЗ*њ!Ю3—SНV?њўњ>_upL7€†§ЈQPMkJU_+.ИАЗfšо‚aЁАСШFn Q!ЕOд РE‚7#hІГёŸXH TŒušш Ф8€heYh Rв-Ќ<ŸЫчqy:К|ЄиUЄЧ„˜њ+‹ŽїŸG€Ё~р&xP†o@а‹X^ Љњ€ЄНАД‰aЖџ<./џ€,>pd=Hu№cЄЬj%ј”Qжœ]Ÿ‘—о,ЈйЧцŠEkЏ|юŽV`TЛCуc}љ"1s zи]Бк; gЛЮ*+ ‡!> nрЅ‹ѕ@1HтG§U†1ЮЈ6"Р |@˜џш€8ŸЁ-цˆ(Ъ>хk`‚кЇ %€ оŸh`4m@5ˆn @нчsЅS—P…щŠt+‰Х{сэ­lжн]<єшўяђДѕ`пи @œкŸh16\C‰/(Л€*ЁzЂўндœШ\›25НРйн mŽ їєTFz–ЕГ›„D6!^Т™ы…а4ЬIѓ„B>XR€Щяr(.,8(..ЁЙЄD,fІ6^ЂЈПIТŽРч‚Ь‡ѕ#5[ќ3­*№‚ §M8#P (ѕГПCєC…ёKp„Ÿ'\ЄLЈ™&jсгОŽ*ГаЁЙqФї=Œ1џРHUТA$ЉX,•ˆ(Bq=;сS—!Ž!Зѕ‹ЈB/ŽЬщЂ< kmСВi];щн,Є4ѓЮњuЛ; уm‰ц›ƒрт0ЄŽЊaђ˜YДqВ.§6eнеQ“Ї†94h˜у}­И9yвМ9+жЙAЙ‡щŸЬž:Оџф%MНэaY,” 9@†Ц"иšАљ3w™[PЌq*šЫ#‹я]\yшЮаƒ“ЖЯ_qцTS*m7bpo'аb• ^Б|ёЌН'oqХі_OžйВŽƒF[ek vь0 ќс‚ў#§™њУ;ŒР놉†?h\ЯАќЊјqГ?cц„†ќ,ч›z„KpoZ•y^4ТAЫЅ š"ДJ-щB=-Эй›МSCkrTMуД;^9W"*noнЧзЦVѕšЊ€шіAмЦљеqнДŠЛЗт›h >Ÿ,-|RЈ0и;йыеe\>˜l @S‡ЫНMабд>3щ@ˆHjз†ѕ›зœ hе+Мo#‚†8šœЌ\Š>ŽPs’Oчde %Ѕu0а<0ШцЮЊC IDATХ ;;Н2?ЏXkяш@Тp&/7Ÿ#Z[[У+HYQaq™кТЪZ"Ђo —Ћ+ЭНs/IKЙїЏ§:Ё§zЬ 7п№a]ыLgшСн зюSnйПЫVёDХkЫХMІЧ}•33ціgўІБ?ІўWСЇ­ѕ Q?KуЬ§Z™>3NDї˜1$г+=ѕИLї№TОMј0s% b!У2hРY)ЉkR…Є€#Є$Ћu]кŠx4)ф AO…вУu0§nщц'Йxlтв-k? ŠIОЬОxь‡•KГrxбя ђWOЖъ1Ў›чиўcš|3Џ‹ЫЃБ+І}їЙXƒFƒё G“lGы}hЭюЁнZгЪпgNиp5Ы™”>ЩЗуqgVЬ›ЛџЌНФ5щND&‰л4uљХl™Ф}д€юVЮIЩс5э5сЋ.ПЯœДчіcз€  SЇбwN§0љч"!ЏѓрЏ{ЗjЌŽ˜GЁBя|oПЦm<#Ќ~;њгTjќИšљ}aМжлъЬ§–эZ$юкLк7hпЦK+…Tх"ЁЂСAЧб`ŸѕЃPtЏrйрXџˆњбHIuрСуЃKfФЪє ь УњИХХюo”tDZfjA1# ŸЯ5а\{Й=ШЃЄ@ЦБнyёk9WfМ37!уъъKЫОi=)вН!Ш^@‰žo1cq›#ю˜& „ѕЫ/ лДџЊГtкТеЃGЖИИяxZАнGr; vМ{UfэervFў'эвљ}60ц\ЏЏŽпеœŠ]z,{љО–їїќюА:ыкNŽZћGSirя~ѓa’7/ѕоۘХг?ћsіˆыšА‰Уƒ'OXqї§ШЧ/›јх;бУЅ„‹JЄ?-šцэ в|гУ–‹\ёУНmT‰4zШЧіѓЗoќИ“їўZŒlsj_ўХф‹a5<Аш›Ge“†ukЂcзќ-Т/_gжŠє›*`Г’ПЙ}^,S#Pл€%]№ЫцGš(ШЧ<й‹ЦќЦ^С$юab<ŸНj;(UTЖWEЂtњw=†Я_о~KUц wn§љОО„Зjё)зФ'WяXХўpBu`Р)НжTСB-Е[НЦ}ѕ‡Їz Єuљmо§‹вŽ-ощк QЃ#[FO]’№эђy'Oo^Ѕѕі ЫМ8\Zwј№BкъЗн‡Vy[wœ oЇ{zzк „ДЗЬJЄViэœ=m,ю6ЮШ|_ж>Њ­ЋŒ_ЂSЅ'ќБЗ щ;=m='Э›ИpёŠїœXўѓї { —ЕhжШu>7ћ“–zvдozhищЫЅIЧб=ZzјјYhRэ;ОpСŠ<кЅMу[KХЭz}ШЁй8UQ98Œ@mB€чh„љ ѓKr(нAŽ‰СžQќљG˜$NЎHіF4T‹ШЦЁAАsКѕм’1*ќ*­ъЗkыГ9щЭ]кмЭЛ}­ф|Јm§Fб4d0ЈSё ГВАЊ+ЖrŒŠЈйЊЉHПуЯSйЅTd“fŽ–6AQ›5 ЕЗљеэс њАsWцНЛюЭк7ЏуХЖЎ^ТГё;Эќ%Їr hнДyнњЃъ:Ц:РЗjаЎCу№А@ WgэUЧЫAюi+ИЕsїБДќвЦб oюкічХ[Q юзКnЩУ;[7lI8љr€‡-l"† НЮ Д рjUrї G9’VxіЎіVЮvНzvz—ањRЭепwЦкзэќйРŽ|ГŒрЙ=@ѓ]>Ÿѓ^RьеK"‘1>’љАGFьc’ћуя3FрmC€h;r0Ђ(і:-ѓX~Зц+ЦџlfŽљьЗњёќЁQ?ГёhнысЃ/..ž0tDп.нЪTШNeАTnin‹• лќQюп_~|>ЮpЈИлц>Pz5|SЭцлxЄ@Тч)еЌљ61šTхpT*а№ y0Ќf4пІ6NŸ’‚ЇЭЗ‰DZ ™oуѓ`/XШm6пF2—œПšoуC$l(ІˆD№2лXѓmb™oгjЫЭЗ\Іy!ž@Т3h(“ж&„‹…А8ФвМ@ъќ0;bPЋа+BU9X%АuяŸ3V,БДД„э*ayš‘њбpњЋ fœOэC€јРO ‘CЬм.њY32~Фјkп“НЉ#ъ‡кљUН8!YR,aЎ|Н`M˜Ьnuїm)љ)НєIЭы~њ^Їюс=Д4k<­м|hXўХ|*чYѓmІВŸ5пІbLАЙMS8ыДј”ШXЁгЈЬЊЉpТЫЪ OxоО•LN/y@Џg>>L№Вдd>ˆћсKŽŽиaо>хNФOь?н#?ps@'жЁЁ,v/„€їЬч…’3‘іџV­ƒк”QЊ ЇрpЗ0•–ЊИ їХГ|+S<гЯ\О•р‡~Ы0MѓЂС=ЃТoЊ,№ћ` Bƒз їРxЦ и0xb(^Ÿ˜/TЦёР†$@н0r:š@†t@ЂзT26->В€l‡пУбќaЦћL(F #№"’Y`uФ2HЛаС8ЦgЩчяоˆ+Gb(ЋЗзF:“TѕљќQ%ЇйййEEEАН rѓ @k5ZŠЂdnnnlЧPБ‡ЈшџЧм+м€јІ+s/ƒфІ ИЭt>ІxІp&бSёЬILљеЈ3fЌЙ4†”уPЃъ+ƒЈ^`д џŠЄddіTёFѕVцП•; ‡Fћˆl9§ын'$$XлиŠe–b‰в1§0Ј№+UН€ЧЛr%оУУƒйёfSiPбЃhРЫ:ŽK’Ц†ћзb(90Д K|ис]‡LЊqx|ьССJaАГЖсј<Ž&7З€УZYЪЭ™ыQY|4›С–ЫeПE•(ѕ EaРglK ?ИJ7ЫЊ7.#PmРЈпш˜>РшgњЭ7XюL€TђŒŸэUMЧЪ%D{*ЪН–_(ЩJмŠ10[Ќж“ЙїЮчj-{Ж Ж-3r–ЖpЩФ1.]Цд&Ќ4уіЊ•лпљbМЏлю€Дщ&* жQ|fаіЬ#Tц~—+k”Х‹їћ як6№сЙэsЗœћ§L?бХM Юqыљ^Нy3'>wWЭЕœ8ччwТ) Ж}v.—$o9iXoBПiС|По_З№ЕаBСЈ\(йwƒg5— Џ2ШМ(S˜`EлAАsр•ЄjbЁ1АRёX5р\0Е v5o…пђ+„НьOчЏс8ф@фbtˆ ™ЫˆњT0˜3†aЗRYZtuKЯїКk5++Ы­ЉYУ{дwїpмИљЗQcиЌ щё;джПАЭWЇLЙCЉ#р% 0;-ЇˆуюхІ/+… u$ДхЃ~уГ2уЕЇž›щ ž Се‰0Lъђ„|џраЄфЩЩЩЖЖЖщYm;М[ЏnиО‡˜‘;,•в[Йк=97iёКƒ DhѕŒипЏ]]˜O†Пг?DsђЖМЧ„ž^#њŒˆ™єswздБЫЎЭž<ТŠ‡2%žо!Ёіўѓ’/ѕŒНpПЋН ЈAРЙгїhg# аqШœђГNЧ^мНˆ •|є!ДrёїНџУТYЭ Бƒх‰’Ь{ цќ”.uыБфЇ!G~ћ{:JOЪммЌ.яjиmкЬqнvќј§іФtBg3ъћЩQіКзХўей\8oŒ@­D€е|(БОЇ…5суЋ#№Ќј+%Zš(2ˆѓђ dR)HKВВВœœœ.]КtіТyЅR q 1(б“6aгЯЯ]ГфїИ‡2 _ШQџВbq–ИёРbŽnZ+№H8yьСн G/žЙ”xым‰ГіN.ж"в(Йƒg@НzŠУ“{иЙ4­RWПпW3њ4œѕхМАГЩбJнЭ™>nЯ/оые7ёQ ы€‘ –чк~6{i@тбХ›ЮI-„0G Еѓ<|дšм>Й+­TŸ›•ІvйИv>•іШГщЧ—LЙu)1ѕСљ9ПщќСPсЃЯИvќ=$Uњъm‡sРќЗјћŸK.Uё›{‹ѓ€ёБq‘эOЫП8ЯЌЪ{ #“јР*йˆz0Jщјѕkзу/ЧK%2Д‰БтkЅœCо›№эЅяцMu Њ3˜Ѓ/хш‹н8uйэїћD6Ќtу—“~О>qљ‚#‡6­бJ?1&…ЕЌќЭш y<ЁО$ѓ~Š:вVЪеTJВЧˆщЧ/wѓ›Њб'm В~зGлД?ДыЌuЛжOўŒаS№L`ћ“' ž:ї‹ўОЕtp/$я\оџ§Šc~ЖbB"‡ўA(ЖjзЄЉD#Џ VчХiJ­д—]<~дТЁ^‡&a0 WQщ9 МТ-дЌXЇМЪЏYп+d“bj+O§ЕѕijНС˜48ИmЕ…Dфяы ц@G&“999jД і-3…‹ЌЛ1цлш.ƒП=ЕѕјŠkьРˆŒXU›ЮљНlюјё—­–,њх§„…гЯYФ4Ž№аыРŒвnWgнџ‡ц&ядж?J]ZѕlЛwwБš$­мјпиІЭћћіцп‰н|ђ^ЈПГFршсlЯ!3QJQ*E…tєйЮƒУЛ3‰рмО|”caз$РъШ–ЋII™Z-,ђЅ8zКЌLЗ:’ІLЁВrю`щbчб U„\dEТДoэo.ќкŠЯЏidm­{ Џ7,ŽvƒЦЎNѓz‘uќб­v ‚ kкЌYT“ІvvЖёёWJKK(JнЄSЇŽсaa 4`4;ƒЙ6іЮО>>RЁ<ЂUS?џ P?ŸК-šЛлхПx›т CBыКЛљЕшаЌn —ЏПOУЈn!ОVЌj LеЪЄтвТЂ‚beН=Gюo Ц{HБ‡ЇЏЋ­Е{Pxу№КuBн­љЗЏнО—т]П§а>hѓGФз2K[П[Љ$ЄIгР№р `UveыеБUmАˆhъщэg/—Y:8њКЪФ"{'їрКuc:…?Jʘє0Че/Шно€љg$ЊцŸфпК7юкЃљ6vEZи…ѕW Ъ8—ZˆбqмАZXэš[eDg,й#эxНйncЬЗ};`XяN]ЪдџnО X ЖI\ЙrUaa!,ю…a>,№њєгOaО—ђЃч'PЄЇThЇsR цѓ gаЋ{jЌzПJЅѓmžAЅж№… иђЁђнЏb1кxц ДZ,Іqбц`aT ъ bБˆЃгP4:џ % ŽRЋЬ ™GЇжшС,5)ђеp‹Ы]"”3@$˜ьЁєБˆыа`W0‘ЇRiИ<ˆйБ іŒ„&уъ=HDтпю™ЕnЙЅ••б|›qЇFL§е‹<ЮН†#€>5Б яkУ_}ѕ%Ьё‚X ŽАhЋœїЁжƒ†щE`ЮЬЗ)DŠЭЖеР|›Ša{гЙќa5РФхWШ™PLLR€v&{SYna @GШ ŽP.˜`3FаkЫи’ŒБPm t*(Р WЉ*' ’ŸяјP ь0jESЕТћ’™ƒ(^`—+X_ Ўњх"/YOœ #€ЈЅ [ыие(РЂАR…Є,% }~‘ЎTЉ'y`dОFеW#€ЈнрQЭj?X|{ш\бš=yЃњ9|П:G,"„RQћ†–}Z[ZY€V Њ-lТVMT‚$ˆЙ`…BlxЅ30'"`GуL2 C—hвтegdЁ $bВg*љ”jєiаЉСl[<шС5Ќgf/ё#€Ј&0ѕWА/™-ŸЯ9rОиЪFє0Kч`;Јѕі=&[u8мжRF‚ЂЇЃ“гьйГ‘х5˜žЅtBиw™ФЁaћ+XЮ‹XіЈкk"aЙD‰€yоЂФћ~С!BД. єЊ;wю9љ[‚eЁШй•V+Д0uAђa‚Vgˆ%Ё€э `бrazкcАŽЗ#šврrЫђВюхЈB‚МIvЫ s6иƒРT)XŽPЅpVEfBW фŠ„„ROчhщќЛЋц кИ~йќ р“––†њ@ЪКЂХу?йx2Q jѓ,='Е”УlBХ#AB$GLWiцЬŽАU„22ЮmјpШЈыYjxе€PHР‡СeщгІЭ*аЂдhпGЎbоŒяofЂЅМкKtИPiЮќЮц 1ЬЗPDКhы/ѓЇЭšёѕАcЧM6yкоИ$ž@Р$•"aЪЁ­ѓvЦЁ}$!Ё@PrњвпЫ@AєOбsА{MVЌ8ŒF xд_ŒšсебФ™ћкuE„”Пэ†ІDуМmыЮУGO#%­жЮЮŽ‘‰а`3;qџќƒКњ—џЁUщwЫtjЮЃЄGЙ†€`Н"Ÿ#’KМтт"ОиBТЇѓѓ• 6ђ&И"BЙ}уŽƒ{.FМћIУObZ o^KpŠ Ў;,&ЙъЄл7AнгРuч|•ВXCгљ9.~~д“ћГ(ŸР@ !R%=HхJхо^^B’ѓ$ѕAfQЉГЇНЅ ­AцЪ{ ўМ+M­™;•ж{PgožPў$уaVNЁЕЃЇЗЇзšpзqS’n* y OТТрlM№ а вян(дЪНИШ‚4vŒ@U"€ЉП*бЌ’М@Ю­Q —Piѕ#[ˆZDи—Хrv|||XO0пfщтQ˜0ѕЇ•›? a MІл§УЦMЪR~`ЫїывБ‰ВS{ћŒ}HЋiЫ{И<јпђѓІ~eХЕ{2?щ\lКЫ”ЏZНћ‹^ЭmѕEЋ'Žн“N9гмœ\Й€Џ?8к/ч’\%ЗѓФ2ЩйуœЭqsоГеъ5‹‹”‡рЖгОщН~ъ„“йe>_Oœ”Ÿppтдх\{‹}ѕ~‹0іУсvЮЎBЎжкЦštruwѓR)žЌјeщЅ‡)Йй– 7,}џKGзЅ\ЕЮЙ“ѕХќХQЄц3@8tqѓђ…GOщKD1}†яг\џZTIѓсL0Е,№ЉYЭФчlOz;ђdЎ­ир(Ч>)‹;wюмО}ћ6mкlлЖу€љ6žUiK—nYЙљФЉ„5Њ_з.ЫжыеЕс‰­›$~aЗNЛ{;.юNТхФФ3Ч/ИЛ{Бцл@’{ј7—GїЮѕ™інЪЬК}tSЂfщ–mѓf ЖВф+3ЎўМяњФ%л—џ2кЫUJІ…й™ќ w~š7ётЁ5Зе~Н{ЖОМwѓНœм7’Ѓ;љьsG'їaђ-Пћрб…ТЦ/,В`м šŽ€Еm‡”ЖяƒіœŒП›ЯKxFџВtУŒс-6Ќо]ЄAЋЪšНjЃmHзЖ ЌwoкTLѓСhvŒ@"€ЉП СЌ‚ЌTjzDO‡UCэbТd“пБё IО(ієЉжoкДqЫцMАА‹Ѕ~кhЉ2[џwgЬъќЫЬџЮЂE}GЧехЊdУПйИQkwейсгзЯXЗ4ћдЏK%ЕŠiЦCfxx:EЦўУgЅєс3Wн<ѕl>RЂб эЌ­Х‘•_ШгЊz ™Ѓˆ”ЩD$ЬѓHIгˆKв вiИ`ђ-Ÿўlь8{їV,ђЯЛдoрзq)E‘=/нmяќЩ#–ьн„џ —УЫ}pvђЌY IE\‰' *K4'"8дI"АДqтъйэ\И­FЭЃuХ9„]шЈQŸ‰iЭKы§Е8#€0ѕзЌЏьБxёzЩ‡п<˜З.“g Лusз•ˆ!ŸO|вdmldУfН–ўКЉїё jJЅ t1НFНчe{=Ља uЏз„L+Жsu—‰T\™{h хљЫ­[ttЭМŸU,Њт pАзpћшжaЇЙ3&}>bЬмSГЮџ–Хq'ВяL›ЗtТ”Х7яШ§]ˆтЉГLŸК№иХ4шtT™ ЖbсZ„5—e”X8ИЪe:•2ыьЉkžuъШѓr‹ЕњG7тS)q]л\шžV6в€щ9fуА’œiNжЄ&57ёJ’–Ѓ=Б|эЦM›Vlљ#К]ŒœЇS••,œ{„•І•ИyЙёI%ГCLЭj&\Œ@mG›oЋЖ|)ѓmb!oЮЊŒщЂŒЬ2g zљImЖJдКЎнжѓbЕ•o‹:ЖэšКkДŒ,…Ыstёєёђ Єс­š‡ж ііiодз]}уf !–{xЕ}ЗYЗЛHptГ.žrdОуЬšэкТŒ*AШНм=ъ6щх—“њ8<К[з.QОўAMЃB‹гКЖў o;/gАѕяхуog!t Ј`И™x_Я—††ж)ОwчvfiЧAŸvЈчЁ))Кyѕšж-tфЇ=m%А#Œ[алДKsОž6RОЅƒ—5?фBŸМ'аpƒдѓђu)Ю~ьй~рћD‘‹‡ЋЃKƒЭ-yщЗ’Г-ь§ННxШHѕЫ8lОэePУiоАљЖ*ndЄy џр^Ъ|hgІdЈf­zь`ѕeWыk2ђДм ƒ]NЩ?tY1j€[”Ÿ€b^Р|›@ЈзЈѕЎ№С,šJ­Fцл„"аеж;<\>XdуЈ) `q2њсСŒАAOБsЇ э#ъ(5С№I.Сp ”ZЏУ–ŠztЩбP—/твАy;\|иš‹y]„Хe|‘$;`ЬGEiй$_ Ћ ž^–k8z- $ИB˜лe–q /0 •ФЖ˜‚Й’€ЧЅ4XI&  жКмK76півас„џmА†OЭj_w{Й‰зЯє‡с9Ѕ5Ьўк шO­Ё?щю0И'кнШћPk0пF—ѕвхжг Ам.›^Ћa'[йЌЯ<ЎYе49XЦkЃ)F’d зы`лЎrKŸДЦX\б№Е)#0Ї-ЋФш Œ—КbTUДћІзkfа›MШUЬћ1*AS•РX•™€HІ ŒjТ_ }&gL)#kЪиa0Њ@SU X•y ˜бхё$„HІ/|ТuЎr;ГTe!8/ŒFрэFSЭjе—˜ЏКП“'t—4\;ƒЃбYѕZХwЋ Вђgъ Ыzб”ѓ2њ№Аxі™џr‰жьБ 1џjО іŠб™чl+ФЌЄй„`ЂBё‹K%AУб0е‹VюЌ^|_4w cъIŠ,"˜І 49D~Ў< BWZ`вхЏŸ.))е#kЬ–)ЅЅ/ЬЋДЎДDёдћСЅЉТјјЫАkbkшшВkёч Tк—~щ€yˆЂ‚М'ЙO*­€ќeџ „НŒРkBSџkК’ХД:ЫцJЏёнšШЃЛ(.Ѕёlл‰мCЃђТз-џбк#  вЃЭ{ˆЬЗ• ѓm`ѕ vsD–л`Y,Ѓ\lЎ1DиЬYРV‰igжєєхеL•й|X‚уЊЯžН ™oC ;bRљгм9wВŠ‘С5ЦjфgиDŒЫC<№У]&gАјV~ BИ$ЉЬИіЭиЏ&Œџnр'ŸmН–eБЩ!?ˆЕDA*09ЧdСо…:C8ŠкK|~Хš3Б№#€x%ЪЙр•ВС‰Ћƒ^ЫїŠж>p~Ќ’Kј `IDAT№§О'‹чZИзqь3K$w‚ЗžXЬ‹,™Ђ€39љw6х<˜офP9YдzPїфхЄ$ФХ]UhщвмЬт2 шyц>ЩVP4—ЃЫЬЬ3Nƒ†%ЇxлЦ=БЧїя=qХР€ХMƒ6яТ™и;ryЄ'˜oуq”7.JИ‘Цсy€љ6EQnAAЮэ‰АСnaњ3g.•С2<Њ8їт™и+7ni аевoп8ћ8ЏијšBpuЅЙZ™Ы˜fЕДЯмАт(‡OfІ$‰Kz˜K\JQT\R’|3съЭT=Ж…HE^r\ь…”GYЙљ%аљаeйЮœIЭ,†Ю Š0Цй`0,ыЏa_‚а–) vяqЫЩ-ИБ/цљЩп…bIGЙGъŠЕ–žЎŽDbЈ4­еYћ4ˆ4<˜2cюжџѕM}иš§Цж3w‘wŠŒ’_НФыђуЧў_tќ У‚MН\“Ц­ОћЫД1BУььычЯфx-ќОщ†_ЖgѕmсЈЭžџљШ;ж^…9гa‹uЭцџ§яЯТ_L&ЦЇI,Єgз˜|<ЇI“фЄќВѕ'[ыMЛуцLМlьИTk@oŸа№Ь3л&/кэюнДqЕЗaпTPб ­m­`ѕ˜X"3PХGwяL-ЩНv.gкšMЂ[ПXИЧеп/ћJвчs7ЕtHљjР‹ІЭ”W.qыНПxRлЙc'8К=Iй6jњд†ожx—і}ХеЉ­рQ k9иеDРw0 ЋIsпо=юІнIЯЫxЂS?>qVќгЂŒoЧ+Вr@І•†їŽдkмь%†Cl8r]*у шВu{wЎu=.оgдјбЅгЗoЦн.ЪИžt3іфЕ`Ÿ@K!fZy„сЬёmД›CTЃHКєшоФЧYIЇчK~ќyс3>sp*вЏnLШџуЏsц Дгъt%…%1§чNњ">ю4Е]§0џлБгђJ2Гr8>эЛіДSџEљї еAЭоѓ7šo3px"aюе§ŸМлvхcщ“{p8Ђfэ;5‰l@–Фп~”Џб*9,XдГЉЫѕ[wŽŸкohжчз…г‡ёЎВV ŸоŸй В,хТЙФTVTУ W#P+Рд_уš &nІЭŠ8+швuсSПщ5ІŸ"MWфш(­+ВД„•ТLЅС|›JюйzжмїVџ8ўxК^Dш5ŸЃг‰мОž№ПЦ‘1юдЙa?lšЙfй““П,;q'ІydОрщJгіНтaУ?}љ–Ÿ/ЯцУ%:šД”ЩBH$ $bk >ˆ`ИhO-Xf+n"!h ˆЄЪ =yЂЇНыд‹ю}2pєЉ…ѕЛX>БмŠйУю2šoCЊЊ”KdЗ… циЊяЦпЪ(H‰›8ыЧдZ ё„-Щ8Z"Ђ~˜oCв`Ÿ §H,Х­P+И<^KСЎ-Ѕ%Њо_NшмШЖЉЏq­…+„Ј`ъЏ‰эf Ћ:НFЋV&Ÿ/Šлц8hДћњйЖ†pЙЅ`м*ЬЗiдJ6ЊЧW§B=юмлЦНЃк№<ц…”*Ы s ЖOМэоЂY[ЯМЧJЋњ!ŽШ|_xhЫc‹ЮsЇMјќ‹1?Юќ!їђЖ,ТS˜ŸќнїѓО™ИфNJБм9аKX6~ђД‰œКђ™oгЈT*X‘+lйV––Mq*WЁШ<њч)‰ЃЋЕBA уЯ&Є+іPG™g]/ЯFšзQф6jеГgЗhO/ПІMъщ r|ТкќQG_w'7/??_k‰Р1Є^Н0IъУ,…m  MNzj‘ЖѓрС­C]ѕ*Uк§<пˆКY‰`Э<'Д№єѕwБГѓ ‰ tvі kфTЄГш9ЈЗŒУiм РзЧоЪТЦХ;0ШЬЦ…EњкКи“ЉODa§пяаЄCX~ЦC…– Љc#Вя;OЁєм lОэЙ№р›o/и|[З=’Ц уm/iОэЉкѕfnыЧГрpхmєŠTž(KW`i7d; ’aмЯ ‘М€BЄЯSЋ‘:>J=I(ŸRЋACLЙQ-ьрХуш)Щ|_—F   уѓmŠ-JVoP ![l`ЮЙ <‚rСиc”/БE€Y7’5пІзЉ5(‰Š`oŸвU9Ц!эL’ЋEf(ИBБђ;q e яaащ`тжшаЛШ–2ЯџaХvkgqъУŒЁS–Фј[щ9ЄБяЦфљ‚kж8lОэЉoОР˜Р>&$jр$ь–іђŽsuХybпtYБ:#Iж<D(LeУВЕІѕ:к кцФМъLАЭЗГQ™ЃйЌs…: ф6ЇЫš:­ЊтЕЖмт[Х"@ФdТd№LцЬїjŒFфРpSЎ< D1жP‹JЗЉ§§LПќbЕƒ‹ЇЕ”ЋE†BЕOйw3†=ŒР+ €ЉџРЋtRVџХЭ№Р ž+є\ачсЩd.uяYОвХзІˆ<{[0/лёО№џ9jl‚чФРЗ0o˜њЋБЕAЅФ2,уƒјCРзcНH™kНЅyvMя‹фSKтТnѓUЉЦ€ь&йj c{д8p51е„ІўjЖ<[ 0Р,рѓ/^ПкЁi ˜x„й€ђлиWmЫ—Љдo$јІ.Ик Уcj˜њЋ­ЙXїЃБXМџЬIJM щѓ!lTЫ’?ъp/PЕ-€Fѕ єЬxХЖЭЧ/ŸГЖГe^ПL#~ЖiЊЖ\œF V!€ЉПŠ› lз 2‡Aѓо,пP‚АДЖŠН2ў<­Q6ь<ЛВК@4ЋTХUy›ВxЁ‹EцЁб>`kьФХ >РЮо5тС\ ?ŠŠ;Зщ[‚ŸЕ˜њ+€Q•^рfђЃ@Эtь+yј ;ŒРлŒІўъk}†№љДg ё;Ќ]E[аа €FЫnA?TOјОJ[ ˜ƒ}Ѓи‡etLOРДDBЄ‰џU Цiџ `ъЏЦVdћ@9hEphл)škрТJ-†їAЪƒBіЧФџJ Сђ9` +УѕnЃ‡щ и^1яПв8ёL§Uп@/0€gE>ˆhр‡16}мЙ>’эC€іTG‚~LќUа ,в8Ѓцƒ@кœ’ѕЃrLƒпЊ PœF v"€ЉПZл ˆ†ј у@9hL "А=СЊu‚B ШtD>ь^[цШр]Ё`Џщ#оЧвžЇј"€ЉПкIёб †ќ,Пƒд:aŒЯp?Цћhд]U €АfШ‘žRї„Œ‘ЌŸqЬhпдWE‰8Œ@-ESѕ6ЂІФIlРLї"a?шЃ›ˆЌ0љПz; ‘c:[ц„:цŸэ—‚ЗL§еђ ЦAДŽˆŸі3ќŽ4{˜P–єYЦgќ˜ќ_Ѕ%Œ”ЮR;sСtp@}.у7YњgC^ЅDœ#PЋј?ч Њ{ыrѕIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/tip03.html0000644000175000017500000000034011733011756022141 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Lists of bug fixes and new features for every new version are always in the Release Notes

fwbuilder-5.1.0.3599/src/res/help/en_US/pfAdvancedDialog.html0000644000175000017500000005173111733011756024367 0ustar sylvestresylvestre

pf settings

Most of the pf options can be found in the man page pf.conf(5) or online http://www.openbsd.org/cgi-bin/man.cgi?query=pf.conf

Tab Compiler

Compiler

Full path to the policy compiler executable. Use this if you do not want to use standard Firewall Builder policy compiler that comes with the package or if you want to wrap compiler in a script.

Command line options for the compiler

Additional command line options for the policy compiler.

Output file name

Specify the name of the generated iptables script. If left blank, the file name is constructed from the firewall object name and extension ".fw".

Script name on the firewall

Generated script will be copied to the firewall using this name. Can be full absolute path as well.

Installation process is controlled by several variables that the user can change in the "advanced" dialog for the firewall platform:

Tab "Compiler":

  • output file name
  • script name on the firewall
  • .conf file name on the firewall

Tab "Installer":

  • directory on the firewall where script should be installed
  • command that installer should execute on the firewall

These variables have default values if input fields are left blank in the dialog:

Output file name: the name of the firewall object, plus extension ".fw".

Script name on the firewall: the same as the output file name

directory on the firewall: "/etc" (tab "Installer")

command that installer executes to activate policy: installer runs script <firewall>.fw

If user enters alternative name in the "script name on the firewall", it is used when generated script is copied to the firewall. There are two input fields in the dialogs for PF and ipf where user can enter alternative name for the .fw script and .conf file. The name can be relative or absolute path. If it is a relative path or just a file name, it is treated as a file name in the directory specified by the "directory on the firewall" input field in the "Installer" tab. If the name is an absolute path, the directory entered in "directory on the firewall..." input field is ignored. If user entered alternative name for the script on the firewall, the command that installer should execute to activate it must be entered as well. If the alternative name was entered as an absolute path, activation command should take this into account and use the same absolute path. The command can start with "sudo " if user account used to copy and activate policy is not root.

Accept TCP sessions opened prior to firewall restart

If this option is ON, the firewall will accept TCP sessions opened before the firewall software has been activated. These sessions are special because the firewall never saw their initiation phase. If this option is on, the firewall creates an entry in the state table when it sees a packet that apparently belongs to the unknown TCP session.

For PF 4.x this option adds "flags any" parameters to rules that match TCP services. PF 4.x by default behaves as if "flags S/SA" parameter was added to all rules matching TCP services. Adding "flags any" makes rule match not only TCP packets with SYN flag set and ACK flag cleared, which is the packet that initiates the session, but also packets with any other combination of flags, including just ACK flag set. Firewall will see packets like that when session opened before firewall software was restarted and session table cleared hit it.

for PF 3.x the behavior of the policy compiler is opposite: when this option is not set, it adds "flags S/SA" to all rules that match any TCP services; if this option is set, "flags" parameter is not added to these rules at all, which makes them match TCP packets with any combination of flags.

Modulate state for all stateful rules

This adds "modulate state" parameter to rules that match any TCP services. Quoting man pf.conf(5), section STATE MODULATION:

Much of the security derived from TCP is attributable to how well the initial sequence numbers (ISNs) are chosen. Some popular stack implementations choose very poor ISNs and thus are normally susceptible to ISN prediction exploits. By applying a modulate state rule to a TCP connection, pf(4) will create a high quality random sequence number for each connection endpoint.

The modulate state directive implicitly keeps state on the rule and is only applicable to TCP connections.

For instance:

           block all
           pass out proto tcp from any to any modulate state
           pass in  proto tcp from any to any port 25 flags S/SFRA modulate state
       

Note that modulated connections will not recover when the state table is lost (firewall reboot, flushing the state table, etc...). pf(4) will not be able to infer a connection again after the state table flushes the connection's modulator. When the state is lost, the connection may be left dangling until the respective endpoints time out the connection. It is possible on a fast local network for the endpoints to start an ACK storm while trying to resynchronize after the loss of the modulator. The default flags settings (or a more strict equivalent) should be used on modulate state rules to prevent ACK storms.

Detect shadowing in policy rules

Rule shadowing happens when a certain rule is a super-set of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. For example, if rule #1 uses the network object for the source and rule #2 uses the host object located on that network for the source, rule #1 т€™shadowsт€™ rule #2 because any packet matched by #1 will never be matched by #2. This may be important if, say, rule #1 permits and #2 denies access to the same destination. If rule #1 т€™shadowsт€™ rule #2, then rule #2 will never fire. This situation is most often an error; the compiler can detect it and abort processing of the policy with an appropriate error message.

Ignore empty groups in rules

Compiler supports special case when empty group is used in the policy rule and there are no other objects in the same rule element. Depending on the state of this option, it generates iptables commands as follows:

  • OFF: Compiler treats such case as an error and stops processing. This is because group with no objects is equivalent to an empty rule element ("source" or "destination"), but empty rule element is normally considered to be equal to "any". To avoid errors this may cause, compiler considers this situation an error.
  • ON: A group with no objects in it never matches any packets, thus rendering the rule useless. When this option is turned on, compiler just throws such rule away.

This is useful when one needs to control access to/from a group of hosts which may change and sometimes becomes empty. When this option is turned on, compiler will automatically disable the rule if the group becomes empty. Group contents can be managed manually or by a script using fwbedit command line tool.

Always permit ssh access from the management station with given address

When this option is checked, compiler adds rules to permit ssh access to the firewall from the specified address block. Rules are placed at the very beginning of the policy to make sure ssh access is permitted even if there is an error in the policy which otherwise would block it. Added rules permit packets that match both NEW and ESTABLISHED states to avoid breaking ssh sessions that were already established.


Tab Scrub rule options

Compiler adds rules "scrub in all [options]" and "scrub out all [options]" at the top of generated pf.conf file. This dialog tab controls options added to this rule.

Clear DF bit

Translates into "scrub out all no-df"

From man pf.conf(5):

Clears the dont-fragment bit from a matching IP packet. Some operating systems are known to generate fragmented packets with the dont-fragment bit set. This is particularly true with NFS. Scrub will drop such fragmented dont-fragment packets unless no-df is specified.

Unfortunately some operating systems also generate their dont- fragment packets with a zero IP identification field. Clearing the dont-fragment bit on packets with a zero IP ID may cause deleterious results if an upstream router later fragments the packet. Using the random-id modifier (see below) is recommended in combination with the no-df modifier to ensure unique IP identifiers.

This option is only used with scrub out all rule and therefore applies to all packets sent or forwarded by the firewall.

Use random ID

Translates into "scrub out all random-id"

From man pf.conf(5):

Replaces the IP identification field with random values to compensate for predictable values generated by many hosts. This option only applies to packets that are not fragmented after the optional fragment reassembly.

This option is only used with scrub out all rule and therefore applies to all packets sent or forwarded by the firewall.

Enforce Minimum TTL

Translates into "scrub out all min-ttl"

From man pf.conf(5):

Enforces a minimum TTL for matching IP packets.

This option is only used with scrub out all rule and therefore applies to all packets sent or forwarded by the firewall.

Enforce Maximum MSS

Translates into "scrub out all max-mss"

From man pf.conf(5):

Enforces a maximum MSS for matching TCP packets.

This option is only used with scrub out all rule and therefore applies to all packets sent or forwarded by the firewall.

Reassemble fragments

Enables the following three options that control fragment reassembly options.

Buffer and reassemble fragments

Translates into "scrub in all fragment reassemble"

From man pf.conf(5):

Using scrub rules, fragments can be reassembled by normalization. In this case, fragments are buffered until they form a complete packet, and only the completed packet is passed on to the filter. The advantage is that filter rules have to deal only with complete packets, and can ignore fragments. The drawback of caching fragments is the additional memory cost. But the full reassembly method is the only method that currently works with NAT. This is the default behavior of a scrub rule if no fragmentation modifier is supplied.

This option is only used with scrub in all rule.

Drop duplicate fragments, do not buffer and reassemble

Translates into "scrub in all fragment crop"

From man pf.conf(5):

The default fragment reassembly method is expensive, hence the option to crop is provided. In this case, pf(4) will track the fragments and cache a small range descriptor. Duplicate fragments are dropped and overlaps are cropped. Thus data will only occur once on the wire with ambiguities resolving to the first occurrence. Unlike the fragment reassemble modifier, fragments are not buffered, they are passed as soon as they are received. The fragment crop reassembly mechanism does not yet work with NAT.

This option is only used with scrub in all rule.

Drop duplicate and subsequent fragments

Translates into "scrub in all fragment drop-ovl"

From man pf.conf(5):

This option is similar to the fragment crop modifier except that all overlapping or duplicate fragments will be dropped, and all further corresponding fragments will be dropped as well.

This option is only used with scrub in all rule.


Tab Limits

Compiler adds rule "set limit [options]" at the top of generated pf.conf file. This dialog tab controls options added to this rule.

Reassembly pool

Translates into "set limit frags NNN"

From man pf.conf(5):

Sets the maximum number of entries in the memory pool used for fragment reassembly (generated by scrub rules)

State table size

Translates into "set limit states"

From man pf.conf(5):

Sets the maximum number of entries in the memory pool used by state table entries (generated by pass rules which do not specify no state).

Src-nodes

Translates into "set limit src-nodes"

From man pf.conf(5):

Sets the maximum number of entries in the memory pool used for tracking source IP addresses (generated by the sticky-address and src.track options)

Tables

Translates into "set limit tables"

From man pf.conf(5):

Sets limits on the memory pools used by tables. "set limit tables" sets the number of tables that can exist.

Table-entries

Translates into "set limit table-entries"

From man pf.conf(5):

Sets limits on the memory pools used by tables. "set limit tables-entries" sets the number of addresses that can be stored in tables.


Tab Timeouts

Compiler adds rule "set timeout [options]" at the top of generated pf.conf file. This dialog tab controls options added to this rule. See man pf.conf(5) for explanation.


Tab Installer

Directory on the firewall where script should be installed

Installer will try to put generated script in /etc on the firewall, unless this option specify different location

User name used to authenticate to the firewall

This can be root or any regular user name. See "How to use built-in policy installer" on the web site at http://www.fwbuilder.org/guides/firewall_builder_howtos.html

Alternative name or address used to communicate with the firewall

Normally installer uses address of the interface marked as "management" to communicate with the firewall. Note that installer uses IP address rather than run DNS query for its name. You can specify different IP address in this option if necessary.

Command that installer should execute on the firewall to activate the policy

If this option is blank, installer copies script produces by the policy compiler to the firewall and executes it there. If this option defines different command, installer copies generated script and then runs this command.

Additional command line parameters to ssh

This can be useful if you want to use alternative port for the ssh session to the firewall. Just put "-p PORT" here and this option will be appended to the ssh command line.

External policy install script

Put the full path to your own installer script here if you have one.

Command line options for the script

Command line options to the external installer script go here.


Tab Prolog/Epilog

Insert prolog script ...

you can control where exactly commands specified in Prolog and Epilog sections will be placed:

  • in the activation shell script: commands will be placed at the very beginning of the activation shell script firewall.fw
  • in the pf rule file, at the very top: commands will be added at the top of the generated .conf file
  • in the pf rule file, after set commands:commands will be added at the top of the generated .conf file after "set limit", "set timeout" commands but before "scrub" commands.
  • in the pf rule file, after scrub commands:commands will be added at the top of the generated .conf file after "scrub" commands but before table definitions
  • in the pf rule file, after scrub commands:commands will be added at the top of the generated .conf file after "table definitions" commands but before the first policy rule.

Prolog section

Add commands that you want compiler to insert into generated script here. Prolog section is added at the beginning of the script, before generated iptables commands. Note that generated iptables script is just a shell script, so commands you place in the Prolog and Epilog sections should be valid Bourne shell commands.

Epilog section

Epilog commands are added at the bottom of generated script, after iptables commands.


Tab Logging

Log Prefix:

this translates into "label " option in pf rules that request logging.

Fallback "deny all" rule should log blocked packets

Compiler adds policy rule at the bottom of the pf rule set that just denies all packets in and out. This is just a fallback rule that follows best practices in firewall policy design. Normally this rule blocks but does not log packets. This option makes it log.


Tab Script Options

Turn debugging on in generated script

This option makes the generated firewall script print all commands when it is executed. To do this, compiler adds "-x" to the shell command line at the top of the script. Command pfctlc/ used to load PF rules into the kernel will also be given command line flag "-v".

Configure interfaces of the firewall machine

This option makes compiler add commands to configure IP addresses of the interfaces of the firewall according to the "Address" objects added to interfaces in the Firewall Builder GUI.

Add virtual addresses for NAT

The compiler can generate commands to add a virtual address to one of the interfaces of the firewall machine if this option is turned on. This is needed if a NAT rule uses an IP address that does not belong to any interface of the firewall. The firewall either needs the static т€™publishedт€™ ARP entry for this address, or it should be added to one of the interfaces as an т€™aliasт€™ or virtual address. The policy compiler adds code to add an т€™aliasт€™ address to the interface on top of the firewall activation script.

Flush pf states after reloading rules

Compiler can add command "pfctl -F states" after command "pfctl -f file.conf" to flush states that existed in memory from sessions opened prior to the policy reload. The reason is that some of these sessions might be denied by the new policy, but if state is not flushed, they will still work after the policy has been reloaded. This is optional and is off by default.

Note that ssh session used by the built-in installer to upload new pf configuration and activate it on the firewall is also subject to the state tracking and can hang if state is flushed. However, command added by the policy compiler when option "Always permit ssh access from the management station with given address" is used is immune to this. This command is written in a such way that firewall will automatically restore the state used to track ssh session opened by the installer so it will never hang. This option is located in the tab "Compiler" of the same dialog.


Tab IPv6

Order in which IPv4 and IPv6 rules should be generated

Compiler can place ipv6 policies before or after ipv4 rules. This option controls the order. fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.0.1.html0000644000175000017500000002162611733011756024564 0ustar sylvestresylvestre

Firewall Builder 4.0.1 Release Notes

This release comes with fixes several minor bugs in the GUI and other components, improves policy importer for iptables and introduces support for HP ProCurve ACLs.

Changes in the GUI

  • fixed #1443 GUI crashes compiling file opened read-only. If a file that was added to RCS was opened read-only and then any firewall object in it compiled, the GUI crashed trying to update "last_compiled" timestamp.

  • fixed #1444 compile error on FreeBSD-Current Compiler issues error "/usr/include/utmp.h:2:2: error: #error <utmp.h> has been replaced by <utmpx.h>"

  • fixes #1447: context menu item "Edit" associated with rule set object in the tree opens it in the rule set view and the editor panel. Menu item "Open" only opens it in the rule set view. This eliminates strange behavior where it would open in the rule set view on first click on "Edit" and then in the editor in the second click on "Edit". Double click used to work the same, the first double click opened in rule set view, the second in the editor. Now double click always opens in rule set view and the editor which is more consistent with the behavior for other object types.

  • fixed #1339 "Logging" icon appears looking the same as "Rule options" icon on Mac

  • fixed #1460 "when "show icons in rules" is turned off, there is no way to tell when logging is turned on and non-default options are present in a rule".

  • fixed #1464, SourceForge bug 3004274: "Branch rule set object displays improperly". Branch rule set attribute was not loaded properly into Branch action dialog for rules of PF firewalls.

  • fixed #1462 "if you do a bulk install, and then want to do a single install, bulk mode is selected"

  • fixed #1461 Need obvious button to add new rule to the empty rule set. Added button with a "+" icon right above the rule set view, this button adds new rule to the set.

  • fixes #1457 "tooltips for rule options seem to be broken". Tooltip always includes the line telling of the rule is "stateful" or "stateless", the function almost never returns empty string now. Added missing hashlimit parameters to the rule options tooltip. Some of the more rarely used hashlimit parameters are still not included in the tooltip. Improved tooltip formatting using html table.

  • fixed #1463 Always show branch rule set name with action "Branch"

  • fixed #1469 some actions should always display argument, even when text labels for actions and directions is off

  • applied patch by Vadim Jukov <persgray@gmail.com>, maintainer of OpenBSD port. Patch fixes compile issues on OpenBSD

  • fixed #1468 Open new object in the editor after it has been created.

  • see #1466 Implemented instrumentation that should help us improve user experience. Will track few things that new users do (or don't do) and report as a combination of boolean flags at the end of the GUI session. Reporting things such as if user ever looked at the "Getting Started" tutorial, if they created their first firewall object, modified any rules, tried to compile, install or import existing rule set. Information passed in the report is strictly a set of boolean flags, it is not identifiable and does not reveal what firewall platform they are using or anything about their objects and rules. List of flags is listed in the module UserWorkflow.h

  • fixed #1478 always use included antlr run-time library. Because of the fixes I've made in CircularQueue?.hpp in 2008 for 64 bit systems, we should always link with antlr run-time that is included with fwbuilder code tree rather than attempt to use the one that might be installed with the OS.

  • fixed #1481 when user changes platform in the firewall object, its version should change too.

  • added mechanism for one-time announcements that can be pulled from the web site when version check server says there is one. Announcement is shown only once. To do this, I store time stamp when it was shown in settings using hash of the announcement url.

  • refs #1483 If program detects change in CustomService object and the change just adds code string for a platform that was not in the object in the user's data file, the change is accepted without showing the dialog.

  • fixes #1484 "paste below" function pastes rules out of order

Changes in the policy importer

  • See #1450 and SourceForge ticket 3000809: iptables parser can now import "mark" module matches with hexadecimal parameters and "length" module matches. Also added check in the importer for broken iptables-save files where rules for any table are not terminated with "COMMIT".

  • fixes #1453 "iptables importer should parse multiport module parameter --ports". Module multuport with parameter "--ports" matches either source or destination port numbers. Importer creates two tcp (or udp) service objects to implement this match.

  • see #1451 "policy importer should support some popular iptables modules". Added support for module "recent" and rules that match standard ip/icmp/udp/tcp protocols and at the same time module "mark", "length", "limit" or "recent". Rules like these are translated into a combination of a branching rule and additional rule in a branch rule set that implements module match.

Changes in the Standard Objects library

  • fixed #1483 "missing code in the custom service object ESTABLISHED for ProCurve"

Changes in libfwbuilder library

  • fixed #1485 "dns name object is recognized as an empty group when it appears in shared rule set"

Support for HP ProCurve

  • Added experimental support for HP ProCurve "intelligent" switches (L3). Code is based on the policy compiler for Cisco IOS extended access lists. Differences include ';' character for comments, different naming convention for Vlan interfaces ("VLAN 2", with a space), requirement to unbind an ACL from interface before it can be cleared, different syntax for vlan ACLs and ACLs bound to switch ports.

  • At the time of the release of v4.0.1, we were able to test code generation for ProCurve ACL but policy installer remains untested for the lack of hardware. We are going to work on the installer over the next few months to make sure it works in the next point version release of fwbuilder.

Changes in support for iptables

  • fixed #1455 Function update_addresses() (host OS linux24 and derivatives) uses both ip and ifconfig. Should stick with /sbin/ip so the script works on systems where ifconfig is not installed.

  • fixed #1458 Should permit interface name "br-lan" for bridge interface on Linux. Bridge interfaces on Linux can have any name, including those with "-". OpenWRT creates bridge interface with the name "br-lan" by default.

Changes in support for DD-WRT

  • fixes #1448 "need to commit nvram changes on DD-WRT".

Changes in support for for Cisco IOS ACL

  • Compiler uses new configlet "safety_net" to add temporary ACL for the "safety net" install method.

  • restored function of the "comment the code" in the "Script options" of the firewall settings dialog for Cisco IOS ACL and ProCurve ACL. When this checkbox is off, comments are not added to generated script.

fwbuilder-5.1.0.3599/src/res/help/en_US/tip10.html0000644000175000017500000000034211733011756022141 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Did you know that Firewall Builder can run on Windows and Mac OS X ? Download Windows or Mac OS X packages here

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.2.2.html0000644000175000017500000023270211733011756024566 0ustar sylvestresylvestre

Firewall Builder 4.2.2 Release Notes

v4.2.2 is a minor bug-fix release

SourceForge: Tickets for V4

GUI Updates

  • fixes #2395 "Crash when setting installer directory location" and fixes #2396 "Crash when changing firewall name". These two bug reports where the manifestation of the same problem that was introduced by the fix for #2380. When user hitsOK in the newFirewallDialog and new firewall object was added to the object tree, any editing of the parameters of this new object would cause GUI to crash.

Firewall Builder 4.2.1 Release Notes

v4.2.1 is a minor bug-fix release

SourceForge: Tickets for V4

GUI Updates

  • Fix for SF bug 3169045 "Batch installer lists IPv4 address as management address". Built-in installer wanted to use management interface address in batch mode even when alternative address or putty session name was provided. This happens only in batch mode install.

  • fixes #2370, #2371 "broken signals in network discovery wizard". Network discovery wizard was not correctly initializased and did not work.

  • fixes #2368 and SF bug 3294457 "External install script". External install script name and arguments weren't saved for IOS firewall objects.

  • fixes #2360 "Sometimes fwbuilder opens with object tree scroll bar centered so folders are not visible"

  • fixes #2385 "PF action Classify uses wrong parameter". This change fixes a bug introduced in 4.2.0 that affects rules with action Classify in PF firewalls. The bug causes the following problems:

    For users who built their rules before v4.2.0:

    • rules compile normally, both in the single rule compile and when the whole firewall is compiled
    • if they opened the action of one of such rules in the action editor, the classification string would look empty
    • if they entered new classification string in the editor, compiler kept using the old one (which they can not see or change in the editor)

    For users who tried to build rules with action Classify with v4.2.0:

    • no matter what classification string they enter in the action dialog, generated code does not use it

Firewall Builder 4.2.0 Release Notes

SourceForge: Tickets for V4

Summary

This release brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10.

This release adds interfaces to the NAT rule model. There are two interfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded. Inbound and outbound interfaces in NAT rules are supported for iptables, ASA/PIX/FWSM and PF, but in the case of PF GUI exposes only one interface to the user since PF commands can not match two interfaces simultaneously.

This release adds support for ASA 8.0 - 8.3 configuration generation, including named objects and "new" style nat commands in ASA 8.3

This release comes with numerous improvemends in support for FWSM 2.x, 3.x and 4.x configuration generation.

This release implements import of PIX, ASA and FWSM configurations. Host name, version, interface configuration, object groups, named objects, access lists as well as commands "global", "nat" and "static" can be imported. There is no support for import of the "new" ASA 8.3 "nat" commands just yet. Also there is no support for import of standby configuration, which means PIX clusters can not be created automatically by importing existing configuration.

This release adds ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their IPv4 and IPv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF.

This release adds ability to automatically detect firewall platform from the format of the imported configuration file. Import is supported for iptables, Cisco IOS or Cisco ASA/PIX/FWSM. The program detects firewall platform, version and host name (if possible) from the contents of the configuration and shows platform-specific warning to explain what parts of the config can and can not be imported. Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved.

Starting with this release the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import.

Deduplication algorithm is as follows:

  • ASA/PIX/FWSM configuration import:

    ASA configuration language supports named objects and object groups. On import, fwbuilder creates objects and groups with the same names and uses them in rules. Objects created from in-line address/netmask and port specifications found inside object-group, access-list, filter or nat commands are condidered "anonymous" objects. These get automatically generated names and are deduplicated using only their relevant attributes but not names. Objects created from PIX named object ("object network foo", "object service bar") statements are considered "named" objects. They get the name matching the name in corresponding PIX config line and are deduplicated using both relevant attributes and the name.

  • iptables:

    Fwbuilder can only import iptables configuration saved with "iptables-save" command. This format does not support variables or named objects, therefor all objects created from address and port specifications are "anonymous" and get automatically generated names. They are deduplicated using their address, netmask, port numbers and other relevant attributes but not their names.

TCP and UDP service objects in fwbuilder that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

GUI Updates

  • fixed #1872: "vlan interface does not appear in the list of interfaces for route-to action for PF".

  • context menu item that opens object in the editor should be named "Inspect" when the object is read-only because the editor would not allow the user to change it.

  • fixed #1926 "Crash when moving object in Standard library". Context menu item "Move" should be disabled when the object is located in the read-only library.

  • see #1976 "Crash when deleting firewall object from rule after export / import library" Crash occurred as the result of the following sequence of actions in the GUI: 1) use context menu item "Cut" to delete an object in the tree, 2) open object group or rule and use context menu item "Paste" to add it, 3) export library to an external file, 4) import this library into different data file, 5) save the data file. Saved data file is invalid XML since it has unsatisfied reference and some operations on it cause crash. The problem is that since it is a reference to the object that is being added in case of both groups and rules, we end up with a group or rule with a reference to an object that is located in Deleted Objects library. Deleted Objects library is not included when a library file is merged into data file and this leads to a dangling reference. The fix is to not allow Paste if object in the clipboard has been deleted.

  • see #1980 "Objects from Deleted Objects should not be allowed to be used in rules". Added checks to not allow drag-and-drop of an object from Deleted Objects library into rules and groups.

  • see #1994 "Crash when compiling a firewall in an imported Library". To prevent crash, added check to make sure firewall object is not read-only before an attempt to update its "last compiled" or "last installed" timestamp.

  • fixes #1993 "V4.2 on Windows - export Library shows the file type as Firewall Builder 2"

  • fixes #1992 " V4.2 on Windows - installer error can't find Secure Shell utility"

  • fixed #1989 "variables respath and librespath are redundant and copy Constants::getTemplateDirectory()". Got rid of global variables sysfname, tempfname, librespath, respath and localepath; will now use class Constants to keep this information.

  • fixes #1998 "Crash after running find-and-replace then closing file". Specific sequence of actions and only on Mac OSX caused GUI to crash. To fix, I clear editor panel when user closes project window using MDI window title menu item "Close" or "Close" button.

  • see #1996 "Crash when finding and replacing a large number of objects". When "find and replace" function was used to replace large number of objects in a rule set, it generated stream of calls to updateLastModifiedTimestampForAllFirewalls() which caused corresponding stream of events to update various parts of the GUI, both in the tree and rule set views. This caused weird corruption and crash on Windows. Trying to resolve the issue by optimizing the part that updated "last modified" timestamp on the firewall since all parts of the rule set updated in one call to "find and replace" function belong to the same firewall.

  • fixes #2000 "New dialog window in New Firewall wizard for ASA / PIX - Network Zone explanation". Added page to the new firewall wizard to let the user configure network zones of interfaces when chosen firewall platform supports network zones (only PIX/ASA right now).

  • fixes #1983 "ASA multiple interfaces have the same security level". Using table widget with spin-boxes to let the user edit security levels of interfaces conveniently.

  • see #2006 "Crash when closing editor panel with find-and-replace". The GUI crashed if user tried to close editor panel at the bottom after closing objects+rules panel and while some object was still displayed in the editor.

  • See #2015 "Add support for setting names of generated .fw and .conf files separately for PF". Added second input field in the "advanced settings" dialog, tab "Compiler" for the firewall platform "PF". Now user can set the name for both the generated .fw initialization script and .conf PF configuration file, as well as names for both files on the firewall. Support for this is generic and the same functions work for other platforms if corresponding input field in the dialog exists. The name of the initialization script is set as follows: 1) if user provided -o command line switch to the compiler, its argument is used. 2) if -o switch was not present but the name was configured in the firewall settings dialog, it is used. 3) if none of them were present, the name is constructed from the name of the firewall object with suffix .fw. The name of the .conf PF configuration file is taken from the settings dialog, but if it is blank, then it is constructed from the name of the initialization script but with suffix .conf.

  • fixes #1914 "Address table object file name is not created properly if user clicks outside Editor panel"

  • fixes #1915 "tooltip shown when mouse is over rule number should be added to the list of suppressed tooltips when 'Advanced user mode' is in effect"

  • fixes #2064 "CARP interfaces are not properly installed on FreeBSD cluster". I need to populate failover group objects with some reasonable defaults when they are created.

  • fixes #2067 "Add way to show interface label in object tree". The tree now shows interface name and label if the label is not empty.

  • fixes #1979 "New firewall created with Cisco c36xx template results in network object in interface column in Policy"

  • fixes #1895 "Add context menu option to expand all child nodes in object tree". Added menu item "Expand" to the context menu associated with all objects in the object tree. This item recursively expands all tree nodes under the given object and automatically changes to "Collapse" if the item is expanded. Also changed behavior of the double click on the object in tree: before, double click opened object in the editor and expanded or collapsed subtree. Now it only opens object in the editor but does not expand/collapse subtree.

  • see #2103 "complex vlan/bridge configurations are not supported by the interface validation code". Added checkbox to let the user turn off interface name validation functions in the GUI. Checkbox is located in the global Preferences dialog, tab Objects, subtab Interface. For backwards compatibility, the checkbox is turned on by default. When it is off, the GUI does not validate the name of interfaces and subinterfaces and turns off checks that enforced interface name patterns for VLAN, bridge and bodning interfaces. It also turns off check for the validity of vlan ID derived from vlan interface name and turns off automatic configuration of interface type and vlan ID. These checks sometimes were in the way of building complex configurations that involved multiple vlan interfaces with names not matching their IDs. This also fixes SF bug #3066714 "please dont stop me from creating a new interface" where user wanted to create interface "veth201.0" on Linux but the GUI blocked this operation because the name seemed to match vlan interface pattern.

  • fixes #2099 "Object list scrolls up to the last edited object". Object tree used to scroll spontaneously when user started dragging an object from it to a rule.

  • fixes #1971 "Address range can be created with end address lower than start address". Address Range object dialog should not let the user enter range end address which is lower than range start address. Dialog behavior is now similar to the behavior of the tcp and udp service dialog where user can not enter port range end number lower than port range start number.

  • fixes #1678 "When creating a firewall from template it appears that a default template is selected". When user arrives at the page where they choose template to create new firewall object from, the first template should be automatically selected.

  • fixes #2135 "Editing table objects". Dialog of the AddressTable object now offers button "Edit" that lets the user edit address table file. This only works if the file is located on the same machine where the GUI is running, so it is probably most useful for compile time objects.

  • fixes #2139 "Provide "Cancel" button if Address Table file is read-only". If the file configured with Address Table object is read-only, the GUI shows warning when user clicks "Edit" button and offers a choice: open it for viewing read-only or cancel.

  • see #2140 "Attempting to create new Address Table file results in read-only error". Implemented support for the workflow when user wants to create the file used to feed addresses to the Address Table object.

  • see #2047 "Inspect generated files button shows different path information". Do not pass full path to the output file as an argument of the "-o" option when the GUI launches policy compiler. Since the "-d" option passes directory path where files sould be saved, actual file names do not need to be absolute path, except if the user entered absolute path for the output file name in the firewall settings dialog.

  • see #2153 "Add Network Zone explanation and selection dialog to ASA/PIX import". Wizard shows additional page when user imports PIX/ASA config. This page explains concept of network zones and offers UI to let them choose network objects or groups as a network zone of each interface.

  • fixes #2156 "After import the firewall should be opened in object tree".

  • see #2163 code that imports addresses from a file in /etc/hosts format moved to its own wizard; using QWizard and QWizardPage classes with correct implementation of page sequencing and validation; old discovery druid has been disabled. SNMP discovery and ios/PIX/iptables configuration import will move to their own wizards later.

  • fixes #2203 "Crash when attempting to add an object to a locked group".

  • fixes #2201 "Some fields of locked object are editable". Some input fields of the Custom Service object dialog were editable even when object was locked read-only.

  • fixed SF bug 3238026: build failure on systems without net-snmp development libraries.

  • see #2226 fixed GUI crash that happened when user tried to delete or cut an object from locked library.

  • fixes #2307 "GUI switches to another file after editor panel is closed"

  • see #2286 "Crash when closing file". The GUI crashed if user imported iptables or PIX configuration, then deleted a rule and tried to close project window.

  • see #2171 "Undoing delete of rule ends up with rules being created with duplicate rule numbers". Also see #2172 "Crash when deleting rule - related to #2171". When user deleted the last rule in a rule set, then used Undo to restore it, the program lost track of rules in the rule set and became unstable.

  • see #2335 "GUI switches between data files upon closing editor panel". If user opened two data files in the GUI and was in the process of editing objects in one of them, the GUI would flip to the other file under certin circumstances.

  • see SF bug 3211769 "Member interfaces not sorted". Sorting interfaces by name in the dialog where user adds them to the cluster member group.

  • fixed #2287 "Show text description in rule columns" does not persist across sessions

  • see #2229 "Multiple new objects with the same name". The GUI should automatically choose unique object names for new objects.

Changes in command line tool fwbedit

  • see #2328 "Add ability to run firewall import from the command line". This has been implemented as a new function "import" in fwbedit. See man page fwbedit(1) and "fwbedit -h" for more details.

  • Starting with v4.2.0, fwbedit.exe is now part of the Windows package

Changes in policy importer for all supported platforms

Changes that affect import for all platforms

  • see #1931 "Update failed import behavior". Added meaningful error messages for when policy importer fails to create firewall object or does not create interface objects or any rules.

  • see #2161 "import workflow and automatic detection of firewall platform from the config file". When user imports existing firewall configuration, the GUI automatically detects firewall platform from the format of the config file and shows platform-specific warning to explain what parts of the config can and can not be imported. It also detects firewall host name where possible (currently Cisco IOS and ASA/PIX). Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved.

  • see #2162 menu item "File / Import Policy" renamed to "File / Import Firewall". This menu item launches wizard that imports existing iptables, Cisco router IOS or Cisco PIX/ASA config.

  • see #2183 "count errors and warnings generated by the importer and show the numbers in the progress page of the wizard". Configuration import wizard now shows counters of warnings and errors generated by the importer.

  • see #2189 Policy importer warnings and errors now include line numbers to help find relevant lines in the original configuration file.

  • see #2189 Program adds the file name and the line number to comments of policy and nat rules it creates during import.

  • fixed #1548 "Object de-duplication during import process". Also SourceForge 3030072 "remove duplicates during any import". Now the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import.

  • see #2253 "importer should not creates objects while still in the middle of the wizard". Importer wizard creates new objects in the object tree only when user clicks Finish and abandons results if they click Cancel.

Fixes and improvements in import of iptables configurations

  • see #2190 "support for import of branches in NAT rules for iptables". Implemented import of NAT rules in user-defined chains for iptables, these translate into branching NAT rules in fwbuilder.

  • see #2196 "iptables nat rules with target REDIRECT not imported". Iptables NAT rules with target REDIRECT where not imported correctly.

  • fixes #2195 "incorrect iptables import of nat rule with NETMAP target"

  • see #2194 "iptables import problem with SNAT rule translating to an address range". NAT rules translating into address range with "-j SNAT --to-source 192.168.1.1-192.168.1.10" did not import correctly

  • see #2197 "iptables nat rules in chain OUTPUT not imported correctly"

  • see #2202 importer for iptables creates Custom Service object to match combination of states it does not recognize. This includes "NEW,ESTABLISHED".

  • see #2336 Importer for iptables recognizes version stored in the top comment by iptables-save and sets version in the firewall object it creates.

  • see #2206 iptables commands with no "-j TARGET" parameter should be imported using action "Continue".

  • see #2338 "Empty Mangle Policy object created on import". iptables rules in the table 'mangle' will be imported in the dedicated Policy rule set with name "Mangle". Rules that use chains FORWARD and POSTROUTING in table 'mangle' can not be reproduced and will be marked as "bad" (color red and corresponding comment).

  • see #2275 Importer for iptables now correctly handles both "intrapositioned" ("-s ! address") and "extrapositioned" ("! -s address") negation.

  • see #2245 fixed bug in parser for iptables that prevented correct import of iptables rules using module "multiport" with port range matches.

Fixes and improvements in import of Cisco IOS configurations

  • see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group.

Fixes and improvements in import of Cisco ASA/FWSM configurations

  • see #2161 policy import wizard shows the page where user can set up network zones of interfaces if firewall platform was determined to be PIX.

  • see #2152 "ASA Import - shutdown interfaces". Importer recognizes and skips ASA interfaces in "shutdown" mode.

  • see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group.

  • see #2268 updated list of named TCP and UDP ports recognized by the importer for Cisco ASA.

  • see #2277 "Create policy objects for ASA access-lists that are not applied in an access-group". Policy rule set will be created and populated with rules found in the corresponding access-list even if this access-list is not applied to an interface with access-group command.

  • see #2164 fixed import of "ssh" commands and added import of "http" commands for ASA/PIX/FWSM

Changes in the built-in policy installer

  • see #2039 "Installer reports success even if pfctl can't load config file". Added more pfctl error messages to the list to make code more robust.

  • fixes #2049 "Installer reports success even if there was an error while creating static routes". Added our own error message generated when command used to add static route fails to the list of error messages recognized by the installer.

  • fixes #2037 "If there is an error when compiling firewall then installer should be aborted". Compile/install wizard should disable "Next" button after compile phase is done if all firewalls failed to compile with no errors.

  • fixes #2061 "Installer shows success for failed installed on FreeBSD due to corrupt script file". Added bunch of common shell error messages to make sure installer recognizes them and mark install as a failure even if ssh fails to pass termination code.

  • fixed SF bug 3169045: "Batch installer lists IPv4 address as management address". The "summary" display in the installer progress log output will now show putty session name if it is used instead of the management address.

  • see #2073 "Add additional information or workflow when no management inferface configured". The error message shown to the user when no interfaces has been marked as "management" is now more verbose and provides instructions how to do this. Also, if user provided alternative address to be used to communicate with the firewall, the check for the management interface is not performed since it is not needed.

  • see #2088 "Installer caches putty session". Need to initialize putty_session properly and clear it in clear().

  • fixes #2129 'deprecate "test install" function'. We have decided to deprecate test install because it is rather heavy-handed on Linux and PIX where it reboots the firewall and plain does not work on *BSD.

  • see #2239 Added variable "firewall_name" to configlets that define commands installer runs on the firewall to activate new policy (all platforms).

  • updated filesystem path on FWSM where fwbuilder built-in installer should place generated configuration when it is installed using scp. Currently using path "disk:".

  • see SF bug 3212988 "external script makes getopt difficult". User-defined parameters for the external script moved to the end of the command line.

Changes and improvements in the API library libfwbuilder

  • see #1972 Separated object creation and initialization. Some complex objects need to create a set of standard child objects. Previously this was done in a special type of constructor which required pointer to the object tree root (FWObjectDatabase*). This created problems with implementation of the method to register functions that create objects of new types outside of the API. Now all objects have just a basic set of constructors, plus method init() that can initialize them.

  • see #1972 implemented mechanism that allows me to register new object types created and used outside of libfwbuilder API. This means FWObjectDatabase can then copy and manipulate object trees that use these new object types.

  • fixes #1937 "RES_DIR macro is defined twice". Got rid of duplicate definition of this macro.

  • see #1985 added virtual function updateNonStandardObjectReferences() that is supposed to update any references to objects stored as attributes.

  • fixes #1997 "add removeRef and addRef methods to class NATRule". Now undo and redo correctly remove and restore references to NAT rule sets in NAT rules with action Branch.

  • fixes #1991 "Undo does not restore object as a parameter of policy rule action Branch or Tag after it was deleted deleted". Now Undo restores references to rule sets and tag services as arguments of corresponding policy rules, as well as references to objects configured as interface network zones.

  • fixes #1987 "Deleting object that is used as Network Zone for ASA/PIX interface results in inconsistent behavior". When an object that is used as a network zone of an interface is deleted, it should be removed from the interface configuration as well.

  • fixes #1995 "Crash when compiling a cluster with identical firewalls". Method Cluster::init() must call base class method Firewall::init() to get child Policy, NAT and Routing objects created.

  • See #2084 "snmp discovery takes forever on devices with large routing tables". This takes very long time on decides with large routing tables. This code was implemented long time ago and apparently routing data was intended to be used to discover "external" interfaces, but it is unclear if this is still done. The concept of external/internal currently exists only for platforms that support security levels (PIX) and there we guess levels by matching addresses against RFC1918 and let the user user adjust levels manually anyway.

  • see #133 Added interfaces to the NAT rule model. There will be two interfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded.

  • see #2126 Using snmp sysDescr OID to guess version of the new firewall when it is created using snmp polling.

  • fixes #2209 "do not allow the same object to be child of different objects in the tree". Method FWObject::add() enforces this. Subsequent clean-up and fixes in many places to follow this logic. This makes code much cleaner, better organized and more reliable.

Changes and improvements in the library of standard objects

  • #2083 Added new services to the Standard Objects Library: rtmp, xmpp-client, xmpp-server, nrpe

common changes that affect policy compilers for all platforms

  • fixes #1920 "Setting host interface to unnumbered after it has been assigned IP address doesn't have desired effect". Compiler still used IP addresses that belonged to the interface even if it switchd to "unnumbered". These children address objects should be ignored.

  • fixes #2124 "some error messages get multiplied when compiler splits rules". Under certain circumstances error messages could appear multiple times in the generated script.

  • see #2204 "Shadowing detected for rule with action Continue". Policy rules with action "Continue" should not shadow other rules and can not be shadowed.

  • see #2207 fixed memory leak in policy compilers. The impact of this leak was especially severe on Windows with very large object databases.

  • see #2212 "Performance improvement in compilers". This change brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10.

  • sorting objects in rule element after cluster interfaces have been replaced, this helps ensure stable ordering of objects in generated configuration.

  • sorting objects in the rule element by name after group is expanded, this helps ensure stable ordering of objects in generated configuration.

Changes in support for iptables

  • fixed #1879 "gui crash". Both GUI and fwb_ipt crashed trying to compile a rule with action Branch that was not configured to point to any rule set.

  • fixed SF bug #3102044 "Colon in (runtime) Address Table name". Variable used to process addresses in the run-time address table should not use character ":" even if it appears in the Address Table object name.

  • fixes #1999 "log() does not work" Using built-in utitlity "command" to verify that all the tools generated script needs to function properly are available and can be accessed either via direct full path or are in the PATH variable. This includes the check for the logger tool that is used to make log record when firewall is activated.

  • see #2097 #133 "support for inbound and outbound interface columns in iptables NAT rules". This also addresses SF feature requests 1954286 "DNAT with interface as condition not possible" and 621023 "manipulating interface in NAT rule".

  • fixes #2008 "option "--physdev-out" is not allowed in OUTPUT chain". After this change, compiler avoids INPUT/OUTPUT chain if interface in the rule column "Interface" is a bridge port and firewall is bridging firewall (which means we are going to use --physdev-in or --physdev-out option for this rule).

  • see #2170 "Compiler should generate error for invalid iptables NAT configs". Now that we allow the user to specify inbound and outbound interfaces in iptables NAT rules, compiler should verify that combination of requested "-i" and "-o" interfaces is in fact valid. For example iptables does not allow "-o" interface spec with rules that go into PREROUTING chain (DNAT rules) or "-i" interface spec with rules in POSTROUTING chain (SNAT rules).

  • see #2181 "Update iptables importer to detect inbound & outbound interfaces in NAT rules". Importer can now import nat rules with "-i" or "-o" interface spec.

  • see #2230 the GUI should allow limit-burst values of up to 10000

  • SF bug 3178186 "Add ND/NS allow rules for the FORWARD chain". Rules that are added automatically to IPv6 Linux firewall to permit neighbor discovery packets should be also added to the FORWARD chain if the firewall is a bridge.

  • see #2324 "NAT + MAC-matching rules not generated properly". iptables NAT rules matching a group of host objects with both IP and MAC addresses each in "Original Source" were not generated properly.

  • see #2235 "Modified rule action for Continue". Rules with action "Continue" should translate into iptables commands without "-j TARGET" parameter. If such rule also has logging enabled, it should use target "-j LOG" instead of generating additional chain.

  • see #2359 "Crash when compiling single rule with IPv6 destination and IPv4 gateway or interface". Routing compiler for iptables does not support ipv6 at this time and will issue a warning when user tries to place ipv6 address or network in a routing rule. The warning does not appear when ipv6 address is a member of a group used in the rule. Also see #1575.

Changes in support for PF (FreeBSD, OpenBSD)

  • see #1890 "Add support for configuring static routes on BSD". Implemented support for simple static routing rules. ECMP and routing via interface (routing to directly reachable subnets) are not supported. Generated script preserves static routing entries that existed before and attempts to recover in case of error.

  • see #1888 "Add option to generate rc.conf.local file for BSD systems". Added ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their IPv4 and IPv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF.

  • fixes #2026 Compiler can now generate static routing configuration in rc.conf format for FreeBSD.

  • fixes #2032 "support for DHCP interfaces in rc.conf mode". Include dynamic interfaces inin the list of interfaces generated script manages when the script is in rc.conf format. This addds lines similar to 'ifconfig_em0="DHCP"'.

  • fixes #2038 "pfctl error when firewall settings include scrub option for reassembly". Command "scrub all reassemble tcp" does not allow direction. Tested and verified on OpenBSD 4.2 and FreeBSD 8.1

  • see #1889, #2043 Added support for bridge interface configuration in BSD.

  • fixes #2054 "Add support for load anchor PF command". Instead of loading anchors using "pfctl -a anchor -f file" command in the .fw initialization script, now generated PF configuration uses "load anchor" commands in the pf.conf file. This way, we can load anchors correctly when PF configuration is activated from the generated rc.conf.local file where only one pf.conf file can be referenced.

  • fixes #2042 "add configlet and shell functions to manage bridge interfaces via shell script on OpenBSD and FreeBSD". Bridge interfaces are managed incrementally, that is, the script creates and destroys them as needed, then adds or removes bridge ports, to bring bridge configuration in sync with what is defined in fwbuilder GUI.

  • fixes #2065 "activation commands on FreeBSD and OpenBSD lose script exit status". Sequence of commands ran by the built-in installer on *BSD firewalls were losing exit status of the script which meant installer always declared installation a "success" even when there were errors.

  • fixes #2066 "Existing VLAN interfaces are not properly removed from FreeBSD and install script fails"

  • fixes #2069 "PF: allow multiple objects in ODst of redirecting nat rule". This fixes SF bug 3162862 "NAT - more than one object in original destination"

  • fixes #2071 "vlandev missing in the vlan definition (when using rc.conf.local )"

  • fixes #2058 "Ability to configure mtu and metric of regular interfaces". "Advanced settings" dialog of the interface object provides controls to configure MTU and possibly add any additional ifconfig parameters. This is available for OpenBSD and FreeBSD.

  • see #2078 added verbose error message in a situation when "ifconfig carp0 create" command fails to create CARP interface.

  • see #1867 "PF: rule with non-terminating action Tag shadows other rules below it". Since action Tag is non-terminating, rules with this action should not shadow other rules.

  • see #2074 On FreeBSD ifconfig does not understand parameter carpdev

  • fixes #1866 "support for pf option set state-policy", #1868 "support for pf option set block-policy", #1869 "support for pf option set debug".

  • fixes #2092 option "stp" should be optional in the ifconfig command that builds bridge interface for FreeBSD. The dialog provides checkbox "Enable STP", parameter "stp" will be added to the ifconfig command only when the checkbox is turned on.

  • fixes #2091 "ethernet interface options a used twice if the interface is a bridge port". When an interface appeared twice in the firewall configuration, such as when it is used as a bridge port and vlan parent interface, options configured for it in its settings dialog were added twice to the generated configuration.

  • see #1871 "PF Actions Tag and Classify can be terminating or non-terminating". Added checkbox to the action properties dialog for actions Tag and Classify for PF that lets the user choose if these actions should be terminating or not. Old behavior (Tag was non-terminating and Classify was terminating) is reflected in default settings of the checkboxes. Terminating rules generate "pass quick" commands, while non-terminating rules generate "pass" commands (no "quick" option).

  • see #1807, #2104: arrange interface configuration commands in the generated script in such order that bridge and carp interfaces are configured after all other interfaces are done.

  • see #2105: generated script now supports vlan interfaces with names that do not match vlan IDs (OpenBSD, FreeBSD, shell script format).

  • Making sure we print "ifconfig" commands for mtu and other parameters for all interfaces, including those with no ip addresses and bridge ports (unnumbered interfaces used to be skipped before)

  • fixes #2100 carp password should be optional parameter

  • fixes #2096 added support for negation in Interface column for PF NAT rules. Sets of interfaces are converted to complementary sets using complete list of interfaces of the firewall.

  • fixes #2095 added support for groups and multiple objects in column "Interface" for PF NAT rules. These translate into { em0 em1 em2 } groups in generated pf.conf lines.

  • fixes #2101 "CARP interfaces are set with same advskew". When new PF cluster is created, master advskew paramerer will be set to 10 and backup to 20 to make it deterministic.

  • fixes #2116 "When CARP interface IP address can't be assigned error or warning should appear". The problem actually affects any type of interface. Generated script should abort with an error termination code when ifconfig fails to assign IP address to an interface.

  • fixes #2117 "CARP interfaces in cluster that use VLAN interaces have no interface set to MASTER". When PF cluster configuration was built using vlan interfaces of member firewalls, CARP interfaces were not properly configured with master/slave choice user makes on the first page of the new cluster wizard.

  • see #2143 "installer should run /etc/rc.d/pf script to reload PF rules on FreeBSD when generated script is in rc.conf format"

  • see #2224 "FreeBSD - Bridge interfaces with the name vlan don't show as Bridge Port Interfaces". This actually applies to all OS where we support vlan and bridge interfaces. Fwbuilder GUI should allow the user to set subinterface type to both "ethernet" and "vlan" when its parent interface has type "bridge". Setting subinterface type to "ethernet" makes it bridge port, while setting the type to "vlan" signals policy compiler that it should generate code to configure real vlan interface. If the name of the subinterface does not include the name of the parent, such as "vlan101", or when the name does not match vlan ID, such as "vlan8101", global preferences option "Verify interface names and autoconfigure their parameters..." should turned off. The option is located in the Preferences dialog, tab "Objects".

Changes in support for ipfilter

  • There are no changes in the support for ipfilter in this release

Changes in support for ipfw

  • There are no changes in the support for ipfw in this release

Changes in support for for Cisco IOS ACL

  • fixes #1966 "IOSACL: object-group can get name that consists of only suffix". Compiler generated object-group statements with names such as ".src.net.0" in some cases.

  • see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

  • see #2330 "Crash when creating a cluster of IOS router firewalls". Added support for basic IOS router clusters. No failover protocol support at this time, but the cluster can be configured with protocol "None" and fwbuilder will do address substitutions at compile time.

Changes in support for for Cisco ASA and FWSM

  • FWSM v4.x does not have "fixup" command, instead, we should use policy-map and class commands.

  • refs #1893 fixes #1883 "inspect IP options in PIX8". Added support for "policy-map type inspect ip-options" command in PIX v8.2 and later. At this time, of all possible types of "policy-map type inspect" command only "ip-options" is implemented.

  • refs #1882 "Mixed service groups in PIX8". Added PIX versions 8.0 and 8.3; added support for mixed servcie groups in PIX 8.0 and later.

  • fixed #1892 "move rule processor class separateServiceObject to PolicyCompiler". This rule processor used to be implemented only in the compiler for PF, but since it has very general meaning, the same function was duplicated in other compilers as well. Moved the class to libfwbuilder and reimplemented several other rule processors to inherit from this class to avoid further duplication for code.

  • fixed #1891 "problems with TCP and UDP services with source ports". Policy compiler for PIX did not generate correct PIX ACL lines when one Policy rule tried to match several TCP and/or UDP objects matching source ports.

  • fixes #1901 "add destructor to NATCompiler_pix and NATCompiler_asa8". This eliminates memory leak.

  • refs #1885 "named network and service objects in PIX8". So far, these objects are only used for nat configuration.

  • fixes #1903 "correct order of clear commands for ASA 8.3"

  • refs #1886 "new nat configuration in PIX 8.3". Initial support for new style nat configuation.

  • fixed #1862 "fwb_pix crash". Compiler fwb_pix crashed when DNS Name run-time object was used in a rule, but worked fine and issued an error when used in single-rule compile mode.

  • fixed #1906 "ASA NAT - Address objects are not properly identified by network zone and have the wrong real interface". The problem should have affected both "old" (PIX 6 and 7) and "new" (ASA 8.3) configuration. When an Address object was used in Original Source of a NAT rule, compiler used wrong interface in the (interface1,interface2) pair in "nat" command.

  • fixed #1905 "fwbuilder crash when compiling a rule with hosts folder as destination". Compiler issues a warning when an empty group object is used in a rule, but GUI crashed when user tried to compile this rule using single-rule compile function. The change actually affects all policy compilers and makes sure the GUI catches exception and does not crash, and prints any errors generated by the compiler in the compiler output panel when single-rule compile function is used.

  • refs #1908 "ASA NAT - cannot configure static NAT translations with (inside,outside)". Added NAT rule option to make source nat rules "static". The option is presented to the user as three radio buttons in the NAT rule options dialog which is only enabled when platform is "PIX" and version >= 8.3. Policy compiler generates "twice nat" rules with keyword "static" in the following cases: when TSrc is "original", so the rule translates destination and not source or when numbers of ip addresses represented by OSrc and TSrc are equal. If TSrc is not "original" and represents different number of IP addresses than OSrc, compiler looks at the new rule option. User can use or override automatic algorithm using radio buttons in the NAT rule options dialog.

  • refs #1902 "Add NAT rule option "translate dns" for PIX". The option is only available for ASA 8.3 or later.

  • fixed #1909 "ASA NAT - static nat port translation where service is the same for original service and translated service not generated correctly"

  • fixed #1913 "ASA/PIX rules with logging enabled don't have log set unless user modifies Firewall Settings". Added default log level setting to the resource xml file for platform "PIX", set to "informational". ACL lines now get "log " keyword followed by the log level taken from the rule options, or if that was not configured, from the firewall object settings, or if that is not configured, the default.

  • refs #1907 "ASA NAT - fwbuilder doesn't support multiple translated sources in a single NAT rule". Compiler uses object-group to translate NAT rules that have multiple objects in Translated Source.

  • refs #1885 Compiler uses named objects and objects groups to build configurations that use address ranges in TSrc in NAT rules. (only ASA 8.3 and later)

  • fixed #1917 "Duplicate objects are not detected". Compiler should detect duplicate objects that may be created in a rule element when user combines Address Table object with other address or network objects there.

  • fixes #1934 "libfwbuilder::getOverlap() incorrectly calculates overlap between IPv4 networks". This should also fix SF bug 3156376 "Can not find interface with network zone that includes address range".

  • fixes #1932 "Add description field to generated NAT rules for ASA". NAT rules generated for ASA 8.3 and later will have "description" keyword added, with rule label as an argument. Rule label includes word "NAT" and rule number.

  • Added support for CustomService objects in policy and nat rules for ASA 8.3 using named objects and object-groups. -- see #1942 "ASA NAT - if custom service is included in service group incorrect config generated" -- see #1929 "move map named_objects inside class NamedObjectManager" -- see #1946 "restrict generation of the named objects by PolicyCompiler_pix to ASA 8" -- see #1885 "named network and service objects in PIX8" Note: this has been rolled back. There is no support for CustomService objects in NAT rules.

  • see #1941 "ASA NAT - compiler complains about range in original destination". NAT rules translating destination allow Address Range objects in ODst or TDst for ASA 8.3

  • see #1940 "ASA NAT - fwbuilder host objects interface IP is reserved keyword". Added list of reserved words used in IOS and ASA software to make sure generated named objects do not conflict. Will maintain single super-set of reserved words instead of separate set for each version of IOS and ASA.

  • fixed #1938 "icmp" commands were not generated for ASA 8.x policy rules.

  • See #1927. Added check for NAT rules that request translation of destination address but have ODst "any". This only applies to ASA 8.3; these rules are prohibited.

  • fixes #1916 "nat rule must be "static" when subnet is present in TSrc"

  • see #1942 improved support for CustomService objects for ASA 8.3. Generate separate named object and object-group for these objects, then split policy and nat rules so that only one custom service object is left in each rule and then use object-group to match it. Note: this has been rolled back. There is no support for CustomService objects in NAT rules.

  • fixes #1948 "incorrect configuration created when a CustomService object is used in a policy rule for PIX/ASA versions prior to 8.3". Since we do not support custom service objects in policy and nat rules for versions older than 8.3, added check to generate fatal error when such object is used.

  • fixes #1945 "object-group names include ever-growing suffix". Object-groups created by the compiler for PIX/ASA had numerical suffix that was constantly increasing when user used single-rule compile function in the GUI.

  • fixed #1944 "ASA Policy - duplicate network object groups created for mixed service group with TCP dst and TCP src port range objects". Need to convert address range objects to subnets early, before the rule is split for any reason, to make sure object groups created later match and are reused.

  • See #1943 "ASA Policy - mixed service group with TCP destination port range and standard TCP object generates invalid config". Protocol word "tcp" was missing after "deny" in the generated rule.

  • see #1949 "ASA NAT - split objects if OSrc contains objects that are in more than one network zone".

  • ASA 8.3 see #1942, #1943 fixed generation of the "object-group" statements by adding protocol keyword at the end so that the group can be used in access-list commands. It looks like mixed service groups that have no protocol keyword at the end of the line that defines them cause error "specified object group has wrong type; expecting service type". I am going to avoid using mixed service groups because of this.

  • see #1953 "ASA NAT - two host objects in the same rule result in incorrect config". Objects that represent addresses of interfaces of a host object created using template will be automatically renamed to follow standard naming convention "host_name:interface_name:ip" to avoid creating duplicate names.

  • see #1960 add support for CustomService for PIX policy rules. Note that CustomService objects are only supported in Policy rules since nat commands in ASA 8.3 require use of named objects and it is difficult to implement correct named objects and object-groups with protocol parameter and custom services.

  • See #1959 "ASA Policy - ranges are broken into composite network instead of using range command." Added support for address ranges using named network object with parameter "range" for ASA 8.3 and later. NOTE: if a network or IP address object is used in a nat rule for ASA 8.3, a named object has to be created for it since ASA 8.3 does not accept IP addresses or subnets in "nat" commands. In the situation like this, if the same address or network object is used in any Policy rule, the same named object will be used in the generated access-lists command.

  • see #1959 Moved generation of the code that defines named objects to class NamedObjectManager. This allows me to put all named object commands on top of the generated policy, nat and routing configurations and make sure each object is defined only once. Still need to do #1963 - move code that generates commands to define object-groups to class NamedObjectManager.

  • see #1954 "ASA NAT - generate warning if nat rule is split and one of the resulting nat rules have the same real interface and mapped interface". Compiler issues warning when objects used in OSrc and TSrc of a NAT rule make it use the same interface as both real and mapped interface in the generated nat command. This check is only done for ASA 8.3 NAT rules.

  • see #1963 "move printing of object-group definitions to NamedObjectManager::getNamedObjectsDefinitions()". Consolidated code that works with named objects and object groups in the class NamedObjectManager. This class manages all the objects and in the end generates commands.

  • Refactored parts that generate "clear" commands to make sure they are printed in the right order at the top of the generated configuration. Previously compiler placed "clear global", "clear static" and "clear nat" commands above the NAT section but below policy section. Since ASA8.3 nat commands can use named objects and object groups, and since I have added support for object groups in ASA 8.3 policy rules, I now need to clear objects and object groups at the very beginning of the generated config. However in order to be able to clear objects and object-groups, I need to clear access-lists and nat commands that might be using them first. So, all clear commands are now grouped at the beginning of the generated configuration. This affects PIX/ASA, iosacl and procurve_acl platforms.

  • See #1965 "ASA Policy - PIX 6.1 configurations use object groups". Policy compiler for PIX is now aware that object-group statement was introduced in PIX v6.2 and avoids using object-groups when firewall object version is set to 6.1

  • made names automatically assigned to object-groups in generated PIX configuration shorter by removing interface label prefix.

  • see #1968, #1972 Class NamedObjectsManager maintains its own copy of object tree that holds object group objects it creates during compiler passes. This allows me to maitain one common set of object groups for both policy and nat compilers and avoid creating duplicate and redundant object-group statements.

  • see #1968, #1972 class NamedObjectsManager (and derived classes for IOS and PIX) generate "clear" commands. This way, I can generate correct set of "clear" commands that take into account any named objects and object-groups that could be created during both policy and nat compiler passes.

  • See #1958 "consistently use "exit" to get out of nested context in PIX config". Using "exit" to exit from nested context while adding network or service object in generated PIX/ASA configuraton.

  • see #1970 "ASA Policy - single IPv6 icmp object allowed in rules". Since we do not support IPv6 for PIX/ASA at this time, policy compiler should drop the rule if IPv6 address or icmpv6 service is used and issue a warning.

  • see #1981 "ASA / FWSM Policy - Generate warning message if rule will not generate config data"

  • fixes #1986 "Cisco ASA remarks should be truncated to 100 characters or less". Trimming all lines used for access list remarks to than 100 characters. Remarks can only be less than 101 characters on PIX/ASA and less than 100 characters on IOS.

  • fixes #1994 "Crash when compiling a firewall in an imported Library". Compilers should reset any read-only flags in the copy of object tree they work with before they make any modifications.

  • fixes #2060 "Existing configuration objects are not cleared in PIX 6.3". Commands used to clear object groups and objects have different syntax in PIX 6.3 and PIX 7 and later.

  • see #2098 Added support for user-configurable inbound and outbound interfaces in Cisco PIX/ASA NAT rules. Two new columns appear in the rule set view: "Inbound Interface" and "Outbound Interface". If user leaves one or both columns blank, the GUI shows "Auto" in there and policy compiler picks corresponding interface automatically. Leaving both columns blank ("Auto") triggers backwards-compatible automatic behavior where both interfaces are picked automatically. Multiple interface objects and groups of interfaces are allowed in these columns.

  • fixes #2113 "ASA/PIX SNMP discovery - assign default labels based on interface description". Added pattern to match Cisco ASA interface description which is different from Cisco PIX interface descriptions as returned via snmp.

  • see #1990 "Change default value for Cisco ASA/PIX 7+ to generate outbound ACLs". Newly created PIX/ASA firewall objects will now have "generate outbound acl" option turned on by default.

  • see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

  • see #2263 looks like "object-group service" that includes named objects defined as "service-object" can not be used in access-list commands and therefore is useless. Unless I misunderstood and there is a way to use it, I should not generate ASA configuration like this:

            object-group service id5102X14531.srv.tcp.0 tcp
              service-object object http.0
              service-object object https.0
        

    Object-group with "tcp" or "udp" type-suffix in the end does not allow "service-object" statements at all, so this configuration is incorrect anyway. However even without "tcp" in the end to make "service-object" references acceptable, the group can be built but can not be used in access-list statements.

    Instead, the group should use port-object statements:

    	object-group service id5102X14531.srv.tcp.0 tcp
    	  port-object eq 80
    	  port-object eq 443
        
  • see SF bug 3213019 "FWSM Network zone and IPv6". Currently we do not support IPv6 with PIX/ASA and FWSM. If user creates a group to be used as network zone object and places IPv6 address in it, this address should be ignored while compiling the policy but this should not be an error.

  • see #2308 "ASA rules with service set to "http" and destination set to ASA firewall object should generate different command syntax". Policy rules that have firewall object in Destination and http object in Service now generate "http" commands. This is similar to how fwbuilder generates "ssh", "telnet" and "icmp" commands to permit corresponding services to the firewall itself.

  • see #2344 "FWSM install errors for clear commands". Using correct syntax for "clear" commands for FWSM v4.x

  • see #2343 "Interface nameif error when installing generated config for FWSM". Use correct "nameif" command sytax in FWSM 2.x and 4.x.

  • see #2345 More fixes for FWSM 4.x: "service resetoutbound", "timeout xlate", "timeout sunrpc"

  • see #2344 fwbuilder should not generate any "ntp" commands for FWSM because NTP can not be configured on FWSM.

  • see #2322 If this is FWSM and if manual commit mode is used, need to commit after clearing ACLs before we clear object groups.

  • see #2347 "FWSM move up the "access-list mode auto-commit" command". Command that configures access list commit mode should be issued before any commands that clear and configure access lists. Also in this change moving commands that set up temporary access list to the top of the script.

  • see #2348: "Accounting action is not valid for FWSM platform". Actions "Accounting" and "Reject" should not appear in the drop-down list of actions in the GUI if platform is PIX or fwsm.

  • see #2295 Added FWSM version "3.2". According to Cisco documentation, FWSM version 3.2 matches PIX 7.

  • see #2351 Security levels of ASA and FWSM interfaces do not have to be unique. Removed check that enforced this.

Changes in support for HP ProCurve

  • There are no changes in the support for HP ProCurve in this release

Changes in packaging

  • This version is the first one to merge libfwbuilder and fwbuilder packages. The libfwbuilder library is now in the src/libfwbuilder subtree inside fwbuilder code tree.

  • RPM .spec files and DEB .control files are now located in the directory "packaging" inside fwbuilder code tree.

  • Changes in the versioning format: build number is going to be used as part of the long version number, composing complete version as "4.2.0.3425". The "-n" suffix in rpm and deb package names will be used for package release number and most of the time will be "-1". This suffix should reflect minor differences in the package that do not affect the code.

  • We have stopped making builds on Ubuntu Hardy. Old Qt (4.4.1) means more and more parts of the code do not compile and require workarounds, sometimes with loss of functionality in the GUI. v4.1.3 will be the last officially released version of fwbuilder to work on Hardy.

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.1.0.html0000644000175000017500000005700511733011756024564 0ustar sylvestresylvestre

Firewall Builder 4.1.0 Release Notes

This is the first official release for V4.1. It has been tested and we believe it to be stable, but you should test it prior to using it in production. If you find a bug please open a ticket in our SourceForge project:

SourceForge: Tickets for V4

What's new in V4.1?

There are several new features in this version including:

  • Support for Address Table objects that use the iptables ipset module
  • Integrated SSH tools (plink.exe and pscp.exe) in Windows installer package
  • New toolbar shortcut to view complete generated firewall configuration files in the GUI
  • Shortcut buttons in the main window to help new users get started more easily
  • Updated many dialog window sizes to work better for users with smaller displays (1024x768)
  • Added a new mode for stopping the firewall script called 'block'

In addition to providing new functionality one of the goals of this release is to make Firewall Builder easier for new users to learn. There are new buttons in the main window that are shortcuts to common functions that new users need to get started like adding a new firewall and importing policies from existing devices.

The iptables ipset module support provides an efficient way to build iptables rules that match large sets of ip addresses and update these addresses without reloading iptables rules. Please not this function requires that your firewall has the ipset module loaded. You can find more information about how to setup and use Firewall Builder to manage iptables IP sets in the Users Guide section for Address Table objects.

UsersGuide: Address Table Objects

GUI Updates

  • fixed #1505 move "Clip comments in rules" checkbox to "Appearance" tab.

  • fixed #1504 Added (optional) text to the toolbar buttons. Text is turned on by default but can be turned off in the global Preferences dialog.

  • using separate settings object and file in the .ini format to store instance uuid to ensure uuid persistence on windows across upgrades done with complete deinstall. Fixes #1497

  • fixed #1489 removed unnecessary debugging messages.

  • fixed #1490 compile problem with Qt 4.7

  • fixed #1501 call qsrand(seed) to seed random generator before generating new UUID

  • applied patch from slif@bellsouth.net to fix compiler warnings. Patch applied partially since not all fixes were appropriate. fixes #1510

  • fixed SF bug #3013532 "file chooser dialog for import policy does not show all files".

  • fixed SF bug #3013855 "various fixes for run_tests". Applied patch suggested by Michael J. Slifcak (with changes).

  • fixed SF bug #3013735 "invalid pixmap properties during make". Fixed uic warnings.

  • fixed #1499 "GroupObjectDialogTest.cpp does not compile with gcc 3.4.6" and SF bug 3015307. There is no reason to make method insertObject() protected which caused problems (and hacky workaround) in the unit test.

  • added user work flow progress flags for an attempted install and first successful install. Both flags are Boolean true/false indicating that the even occurred. We do not track and do not report any information about the firewall, platform, rules etc. These flags will be used to determine how many users abandon the program before even trying to run install for real because it is too complicated or the UI is not good enough. Fixes #1495

  • added user work flow flag indicating that ssh/scp have been configured in the Preferences dialog. The flag is Boolean and registers only the fact that something was entered in ssh and scp fields. Actual path and programs used are not registered and reported. Fixes #1496

  • fixed bug 3016720 "import policy disabled after file close". Menu items "File/Import Library" and "File/Import policy" became disabled after user closed data file using "File/Close" and never became enabled again.

  • fixed #1521 "GUI crashes upon exit on CentOS 5". This fixes SourceForge bug reports 3016482 "segfault with RHEL5 pre-built packages on CentOS 5.5" and 3015979 "fwbuilder not exiting in centos 5.5"

  • fixed #1493 "workflow icons in the big empty space". The GUI shows big buttons in the empty space in the right hand side of the main window when no firewall policy is not opened yet. These buttons provide simple shortcuts to the workflow functions useful for the novice users. Currently this includes "Create new firewall", "Import configuration of existing firewall" and "Watch Getting Started Tutorial".

  • fixed SF bug 3016680 "Vertical scrollbar issue" rules with a lot of objects did not scroll properly vertically.

  • fixed #1520 ("Comment field display clips comment text"

  • fixed #1526 "Make sure GUI unit tests work in the environment where user turned off tip of the day dialog". Unit tests now use alternative settings file with all default values and do not depend on user's preferences.

  • See #1346. Viewer panel that can be used to inspect generated firewall configuration files from within the GUI. The panel can be opened using a button in the mini-toolbar above firewall rules or as a page in the compile and install wizard.

  • SF bugs 3020381 and 3027284: "Line failure should abort remote firewall install". If network connection is lost during firewall policy activation, policy installer should detect this, disconnect and declare installation session a failure. Prior to this version, installer detected network failures during policy copy (done with scp) or when it could not connect to the firewall at all, but hang if connection was lost in the middle of ssh session used to activate firewall policy. Now using ssh parameter "ServerAliveInterval" to make it detect connection failure. Added an input field that defines inactivity timeout value in seconds to the "Installer" tab of the global preferences dialog. The same timeout value is used to set up ServerAliveInterval parameter for ssh, ConnectTimeout parameter for scp and registry entries required by plink and pscp on Windows using putty session "fwb_session_with_keepalive". Default value defines 30 sec timeout.

  • All instllation commands should be on the single line in the configlet so they are sent to the firewall as one line. When these commands were on separate lines, linefeed characters between them appeared on the standard input of command "sudo -S" and broke installation process. This only happened in my tests when I ran GUI installer on Windows and looked like some sort of a race. When all commands are on the one line the problem disappeared. Changed only configlets that used sudo as part of installation script.

  • fixed SourceForge bug 3020761 "printing from command line causes Segmentation fault". Fixes #1533

  • fixed source forge bug #3028740 "inspect/install does not like spaces in Firewall object name". compiling firewall objects with name that contains white space produces files with spaces in the name which confused "inspect generated files" function and built-in policy installer. Names with spaces are now supported.

  • sorting of filewall and cluster items in compile/install dialog is now case insensitive.

  • hiding "Select all" and "Select none" buttons in the first page of the compile/install wizard when there is only one firewall in list.

  • renamed buttons "All" to "Select all" and "None" to "Select none" in the first page of the compile/install wizard.

  • fixed SourceForge bug #3027272: "default values taken from unexpected sources". When new firewall object was created using "Import Policy" function, parts of its configuration were taken from default settings of an unexpected host OS.

  • fixed wrong display of non-ascii symbols in cluster member compilation warning.

  • firewall names are now resolved to IP address in the SNMP discovery. Added new input element for firewall IP address to use for SNMP interface discovery when firewall object name does not match DNS record..

  • Added "Cancell All" button to the installer options dialog to stop all firewalls installations and renamed OK button to "Install". The new "Cancel All" button lets user interrupt installation process when they are in the middle of pushing configuration to many firewalls.

  • fixed #1582 'tree is not refreshed after address substitutions in "new firewall" wizard'

  • Most dialogs were adjusted to make sure they fit on the screen 1024x768

  • fixed #1612 "File/Open should create new project panel". If user has some unsaved changes in the default project panel (the one with no associated file) and then uses File/Open menu to open another data file, the file should open in a new project panel.

  • fixed #1611 "File/New should create new project panel". Like #1612, open new data file in a new project panel if current project panel has no data file associated with it but has unsaved changes.

  • fixed #1622 "Crash when configuring cluster". The GUI used to crash if user created a cluster copying rules of one of the cluster members while that rule set was opened in the rule set view.

  • fixed #1632 "dependencies created by branching rule sets should be processed recursively". In the case of multi-level branches the GUI should trace all references to find all firewalls affected by a change of an object used in the rule. This fixes SourceForge bug 3033462 "nested shared branch rules between servers not working".

  • fixed SF bug 3035426 "canceled save writes .fwb ". The program created file with name ".fwb" if user started with an empty project paje, created some objects, then hit "Compile" but then clicked "Cancel" when offered a chance to save objects into a new data file.

Changes in the policy importer

  • fixed #1511, SF bug 3012953: iptables import parse error icmp_type any

  • fixed sourceforge bug 3012953 name of UDP and TCP objects created during import should follow the same pattern and not include "0-0" for the source ports if they are equal to zero.

  • policy importer for iptables can now parse numerical log levels.

  • bug 3012953: iptables importer sometimes does not recognize rule with " ESTABLISHED,RELATED ". Parser properly processed iptables rules with state "RELATED,ESTABLISHED" but not when states were in the opposite order.

  • fixed #1513 iptables importer should check default policy in standard chains. Importer creates rules at the bottom of the policy rule set to reproduce default policies in the built-in chains INPUT,OUTPUT,FORWARD. These rules are added only when default policy in these chains is set to ACCEPT because generated iptables script always sets default policies to DROP. Support for this in the mangle table is limited so far, only default policies in PREROUTING, OUTPUT and POSTROUTING can be implemented. Rules created for the commands that set default policy in chains FORWARD and INPUT will generate commands in PREROUTING chain instead. We will try to address this in the future if there is sufficient demand.

  • fixed #1516 policy importer for iptables should not use automatic ESTABLISHED rule. (See also SF bug 3012953). Policy importer for iptables always creates explicit rule to match ESTABLISHED,RELATED to make sure it goes into the same chain as the original rule. Also in the same fix, importer creates branch for iptables rules that match both regular service and state ESTABLISHED,RELATED. The service is matched in the main policy rule set, while ESTABLISHED,RELATED state is matched in the branch.

  • fixed SF bug 3015641 "imported REJECT rule changed during compile". Importer of iptables rules did not handle properly parameters of the REJECT target.

  • Fixed SF bug 3016779: Policy importer for iptables should understand module iprange

  • policy importer for iptables replaces --sport and --dport parameters of module multiport with --source-ports and --destination-ports to remove grammar ambiguity that arises from the use of the same parameters --sport and --dport by different iptables modules with different argument syntax.

  • fixed SF bug 3017084 "compiler adds extra quote characters to log-prefix string".

  • fixed #1544 "fwbuilder crashes during import of file with rtf formatting data". The fix should prevent crashes in other cases when import was unsuccessful.

Changes in libfwbuilder library

  • Added framework for creating data files with predictable and repeatable object IDs and references. This is used in unit tests so we can create data files that can be compared.

  • fixed missing class variable initialization in class CustomService

Changes common for all policy compilers

  • fixed #1631 "Process branch rule sets recursively". Policy compilers used to look only one level deep while processing branching rules. They should allow for arbitrary nesting and correctly avoid infinite loops if user creates looped branches. Compiler issues a warning when it detects looped bracnhing. This fixes SF bug 3033462 "nested shared branch rules between servers not working".

Changes in support for iptables

  • fixed #1506 SF bug #3011516: generated iptables script tries to update ip addresses of unnumbered interface.

  • fixed #1523 "outbound ipv6 rule matching multicast ipv6 destination is not generated". The rule with network object fe80::/10 in source and ipv6 muticast ff00::/8 in destination did not produce correspondign ip6tables command. The change affects other cases with rules using broadcast or multicast objects that should be considered matching the firewall object.

  • fixed bug 3001228 "v4.0.0 iptables: NAT not creating interface addresses". Iptables script generated by fwbuilder used to include commands to configure virtual ip addresses for NAT only if option "configure interfaces" was turned on. Expected behavior is to generate these commands when option "Add virtual addresses for NAT" is turned on regardless of the setting of the option "configure interfaces".

  • Added support for iptables module "set" used to generate iptables command for rules with run-time AddressTable objects. This module is only available in iptables 1.4.1.1 and later, however some embedded platforms do not have it even though they ship later versions of iptables (e.g. OpenWRT). Use of this module is controlled by a checkbox in the iptables "advanced" settings dialog which is off by default. This checkbox becomes disabled when iptables version is set to < 1.4.1.1. Supporting shell functions are generated by the configlet run_time_address_tables. This includes shell function that checks if data files used by run time address tables objects are available, a function that loads these files if user activated use of the ipset module using checkbox, a function that checks if command line utility ipset is present and can communicate with the kernel module. This configlet is included in the script generated for all linux-based host os, even though most of them do not support module ipset. If ipset is not supported because iptables version is too old or the module is simply not available for the platform, user can just uncheck the checkbox in the firewall settings dialog and code generated by the configlet will support method of loading addresses from the file at run time based on script variables and a "while" loop.

  • Implemented support for mixed address lists for run-time address table objects using ipset module. Normally, one ipset set can either contain individual ip addresses or subnets. We create a "setlist" type set that includes two sub-sets, one for ip addresses and the other for subnets. Function reload_address_table in the configlet run_time_address_tables takes care of managing these three sets automatically. Address list file has the same format as for all other supported types of Address Table object: one address per line, subnets are defined using '/bitlength' or '/netmask' syntax, comments start with '#' or ';' character.

  • fixed #1640 "default policy when the script is stopped should be optional". The "stop" command used to be interpreted by the iptables script generated by fwbuilder in a way that it blocked all connections going to, from and through the firewall. Luc Paulin pointed out that this behavior is incompatible with other firewall management scripts, such as /etc/rc.d/init.d/iptables on Fedora Linux or ufw on Ubuntu, where "stop" means disabling the firewall. In v4.1 the "stop" command flushed all chains in all tables and sets default policy to ACCEPT. New command "block" does what "stop" used to do before, that is, flushes all chains in all tables and sets default policy to "DROP". The option to add a rule to permit ssh access from the management workstation when firewall is stopped now adds this rule when firewall script is run with "block" command instead.

  • fixed SF bug 3034628 "iptables does not allow target REJECT in mangle table". Iptables does not support target REJECT in mangle table. Added check to the policy compiler to make it detect this situation and issue an error.

  • fixed #1654 "Support for run-time Address Tables with empty file in iptables". This is an implementation of the same feature we already have for PF. If the file name in the configuration of the run-time Address Table object is blank, policy compiler generates firewall configuration that uses ipset with the name the same as the name of the object but does not generate code to load addresses from a file into it. All control of the ipset is left for the user.

  • fixed #1652 "support for adding single address to address table in the generated script". Generated iptables script now provides functions "add_to_address_table", "remove_from_address_table" and "test_address_table" that let administrator add or remove single ip address to a given address table. Functions take three arguments: set name, file name and address. Functions add and remove the address both from the set in memory and from the given file so that when firewall reboots and the script reloads the set, it is restored to the desired state. Another new function "test_address_table" is a wrapper around "ipset -T" command and tests if given address belongs to the set. All these functios take the name of the run-time Address Table object used to create sets as an argument and perform actual add, remove and test operations on the subsets created for ip addresses and subnets.

  • fixed SF bug #3038636 "@v4.1b, 'iptables v1.4.8: unknown option `--ra'"'. Ipv4options module has changed in iptables 1.4.3 and now accepts different set of parameters. Policy compiler generates new parameters if user set version in the firewall object dialog to "1.4.3 or later".

Support for PF

  • No changes for PF.

Changes in support for for Cisco IOS ACL

  • No changes for Cisco IOS ACL.

Changes in support for for Cisco ASA (PIX)

  • fixed #1491 fwb_pix crashes trying to compile simple rule. Compiler should check validity of the object used as network zone of an interface.

  • do not verify network zones of unprotected interfaces. Compiler does not allow the same obejct to be used as network zone of two different interfaces, which caused problems when a vlan parent interface has zone "Any". Vlan parent interface can not have ACLs attached to it and does not need any meaningful network zone, so "Any" is reasonable fill-in choice. However it coinsides with network zone of the "outside" interface which triggered this check.

Support for HP ProCurve

  • No changes for HP ProCurve.

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_5.1.0.html0000644000175000017500000000675411733011756024572 0ustar sylvestresylvestre

Firewall Builder 5.1.0 Release Notes

SourceForge: Tickets

Summary

Starting with 5.1.0, packages for Windows and Mac OS X are released under the terms of GPL. The source code tree includes all files necessary to build on Linux, *BSD, Windows and Mac OS X.


GUI Updates

  • fixes #2685 "Clicking "Manage Members" in a vlan subinterface of a cluster causes crash".

Changes in support for iptables

  • fixed SF bug #3468358 "change in rule-compilation between 5.0.0 and 5.0.1". Rule with cluster interface in "Destination" should compile into matching ip addresses assigned to the cluster interface object and corresponding member firewall's interface object, but in v5.0.1 it only matched member interface address. This bug triggered when iptables version was set to 1.2.11 or greater. This was a regression from v5.0.0

  • fixes #2686 "automatic rules for heartbeat are not generated for vlan subinterfaces"

  • fixes #2684 "fix address deletion in configlet update_addresses". This only applies to Linux firewalls and configurations where an interface has two or more ip addresses. If user deleted one of the addresses that happens to be the "primary" address of the interface in the GUI, generated script deleted both addresses on the firewall machine instead of just one and left interface with no addresses at all. The fix is to use /proc variable /proc/sys/net/ipv4/conf/all/promote_secondaries that makes the kernel "promote" secondary address to a "primary" status when primary address is deleted. Default behavior in Linux kernel is to delete all addresses when primary address is deleted.

  • using mktemp to create temporary directory in the generated script. If mktemp is not available, fall back onto less secure but guaranteed to work method where I generate randomized the name of the temporary directory using process ID.

  • fixes SF bug 3489096 "dd-wrt-jffs: all routes are deleted if there is an error". The problem affects all supported Linux-like systems. Shell code that restores old static routing table entries in case of an error with commands adding new routing entries was broken and left the machine with no routes at all.

Other changes

  • fix for SF bug #3468802. Need to define macro __STDC_FORMAT_MACROS. This still needs to be tested on all build machines.

  • running autoconf, configure as part of windows build. Merged qmake .pro and .inc files for Windows, Mac and Linux builds. Moved files needed for Windows and Mac packaging to the "packaging" directory.

fwbuilder-5.1.0.3599/src/res/help/en_US/iptables_Tag.html0000644000175000017500000000225311733011756023605 0ustar sylvestresylvestre

Rule Action "Tag"

This action associates internal tag with the packet. Tag can later be inspected using service object TagService. This action is translated into MARK target with corresponding --set-mark parameter and optionally additional rule with CONNMARK --save-mark target for iptables. If option that activates CONNMARK target is used, compiler also adds a rule at the very top of the policy to restore the mark. Rules are placed in INPUT,OUTPUT and FORWARD chain of the "mangle" table, this ensures that DNAT happens before rules placed in the mangle table see the packet. PREROUTING chain in mangle table is executed before PREROUTING chain in the nat table, so placing tagging rules in the PREROUTING chain would make them fire before DNAT. POSTROUTING chain of the mangle table, as well as its FORWARD and OUTPUT chains, work before corresponding chains of the nat table. In all cases the goal is to make sure DNAT rules process the packet before, and SNAT rules process it after filtering and tagging rules.

To use this action create TagService object with tag code you want to use, then drag and drop it into the well in the action dialog.

fwbuilder-5.1.0.3599/src/res/help/en_US/tip07.html0000644000175000017500000000020211733011756022142 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Here is how to contact us

fwbuilder-5.1.0.3599/src/res/help/en_US/state_sync_configuration.png0000644000175000017500000037355111733011756026146 0ustar sylvestresylvestre‰PNG  IHDRHF/vэˆhiCCPICC Profilex­—gTSMЗЧч$$єŠ  tAz/‚є.щUщMJ])‚є.HGP”Ђ€вщEQЄ "HAъ=шЫѓЌћс]їЫЕВц—}ўГgrіdіl(ћlq8wРУгo ЁЬjfnСJј # М@мжоЇ„Х^€%џЅ§њ ЃGУGОh—НŸzrфL „ŠЖИ†ў—AЧf <яршc?>šїВƒНЬ 0ЏzxxСў)ќѓиу№№XЪЛ0sНИ‡[ №Z Щm&М<`ГѕЏэL!tiДbџЕmќyW§k'1б?ю 2ePŸ7ИсЕСњ§дУУнтУУ§uŽзN”LІŠ˜ђ™vњlљХpFwVkNѕЋтМм‚є7ёEсяќK<Ыœ?NЏ0­2Ќб­c6Ј~Rl’§"о"мFџFя wQ{Ј}‚Ф!txЧŸм†ЁˆbdС]д(!?Q 5iЙХ.еc žVŒnѓD-Ѓ sы)§гClВь‰}œ?Й1gиyјyEЯJѓЩ№K HŠ ѓˆpŠВˆб‰“J‰ ЩYЉaщv™*йьsсrЎђиѓ ЬŠŠ?”Ц”{UъUяЈ%Јhиhjj jгjoщŒ]hжЭзЛЎo‡еМ(jРjHiИoДdyиYY]•[[јшЪc›ZГ:§zЭ'ŠOЅ„Й›XšiZˆ[žmД.ДM<jяъxвYо•гаs­зЃЯЊџТРЙМ/O  ЎПš~§zЈуMУлšсяюП/ў?’5šњ1n,rkvhkGши^зeднд{Ћ_MОˆ705”7т0&2^6‚їР-s cKq+jЋы——*.Члрl-эtьЯ9:В:aœ‘Ю._\‡мž])wЯ№ИюyХЫЇэ­ˆ—ѕ‘єѓё р <Ф~•%јDе5тPњ > &Т_F4F–оH‰ ŽvИЉ#Ы‡ˆ›™P“˜‘l‘"ŸЪš†H›MяЩ(Л“щ’Ѕq›;•=›г‘[”’oV QH]ИZ4tЇЖ8Ћ$о :ЅТїщюя”M•wV”>ˆ}xЅRЏJИšЖzЇfіб›ЧЕѕuхѕљORŸF6ј7К4Y4ыДШ=уoen#kл}Од>йёЊѓyзЃю;=iН}о§Жи /Y^‘ПкН:Д№fцэЬ№мЛ…їKVFжG7?nэL">ЁЇШЇ?ѓб˜q™MšЋџ:Й€ў&Аhќ=tЉ|yt…zеz­yCьчГ_F[+ПwЯюѕиХџoю;Ъ hIю.`*€6œЃ зрЮ€&,9F2њA   5}Чљƒ№` мA$Ш5 Lƒmˆ т…”!+(Jƒ*ЁhA€р@(#ь7ЅˆФ*’Љ€tCf!{‘;Тю VQ2Јhдњ,:=F(I˜AИIdFдJЬMœB|@тEђ…дœєйEВ7фЦфN”TдTEд"д3Ь*M-э žž‰Оч„УcъIѕ“;LUЬv,Œ,УЇRN_dЅegЛЫюЭЁФIУ9ЯеФЦŒ‡ЮcgЃљLјyљFы„в„ё"ЦЂ2bЬbћту ’R8i}!YŒьіЙ)Й~љ'чя*d*Ц)…+_SЙІЎЃžЎQЄYЃеЉ=ІГЁKЉ'ЈХњ^Ь3ш1м0ц0167ы4пЗ”ЕКjнz™РFз6лnСAж1бщГ‹Иk”лwЯaœ w<~бWзяQc`DаJАUHЈиѕœАƒЛШž(ш[1PЌgмT‚Ab_ВbJsšLzг­ѓ™=З/fOхzчЃ ђŠ$я —ряб–6–йT?ЈЋМTЎy№XЏv­>уЉlУLSRЫЙgплђл :‰Кк{‚ћФњПНШдyѕ{Јь­щ;тї-#Имc“™ŸАгфŸ_ЬФЮiЮ.є.Ц.щўРЌŒЎl8lђ§њЙнЖ“АgyРџчќРРЗAE` Ышчnљ IDATxь]`EїпvН_zя=Є“:ЁiRDAьБ+њ)ј‰њЗWPD@Š‚ щН„’ %ЄїvЩѕлНн§ПН#!Д)рЫeЫдпЮь›yѓ ЪВ,Т{ь^iпžАё§€G€G€G€GрžB€'lїдыфУ#Р#Р#Р#Р6О№№№№мS№„эžz|cxxxxxТЦї{ žАнSЏ“o Oиј>Р#Р#Р#Р#pO!РЖ{ъuђсрррр пxxxxю)xТvOНNО1<<<<0ntХц\Ћ%їJюм;хVрЪdбЪеЌХ,ФšAl.ѓѕѓияV”ХчЩ#аNВfяп|р^eT8л5dт`џ0џvвžh,У ‹ p MП‚a(—|р@2wЭм™yS†е6члЊіФлЗd–G лwЌQЈЇ\h иZ“UцBvž6‘Ъ€аЁ&Kq™єŸu ч№њgiљTџf~ўt)Ж{Ё“†євуfЕ‘ll<њюМкН„ %ФPЋ…$ХbЁZЗŽ#№нЛ €Аu<н5RмТvŒoв-EeR1­ЇЊL”еЮˆPLеX•љрCˆ€@5Z[YЙилЛлšU,[щRVвЮ bЉшЖЯЃ}мЬ•<џ(ЃЉjупю2B&Тэ8†сbкЦиkjЮœuДўŠ‘cуІБЈЄ(ПRьччь-СЏ—, ЛДYЬ*–+” СѕЂђїя:n>aCЏѕЕ†TћЁA‘KВš‚ЩЈPJшIкЮ0aJg- zЧPЃЮN1deeћsnŽiгзlћxс}Шдџ> nОноh#ЌƒБво4\<eЕYLf“Щ†JЕ^ю’Ž$чуђќ`n4sѓАЋŽуRUЛњ0 ЕLЊУчСЮА5vЊбfu— qЋбZYKЄŽ!…Ђ8Ю .Ё#ргt­"[дСљЉH7ЙШŽ_ЊhйŸпЯ[т1{ЦŒз‘рWmMŸ юЮYR_™ЕяЏƒ[жя/qK|ќ­ЧЦї№h‘7zw#p“ [cuЃc%r%((†Љм”WоНж5|ћЭUUЌ‚ў‡нlБPŒСL)Z)РЊЬvCL4т*`CхXЁ‰5WЬѕЎ•)—,Ьœ]œe;m1•oYЗЛ|ШјwЙјŽЇpп9 „–D Rqw P2ˆФЩва 30Z_w)юLХEp 3юВiСxУрмQ? е C[jѓЮl]Еч№ЮЬ}љdџwцЭ{0фкехяђм)АІFѓІ/75VщƒрRЕ€ЊљwђяћHŸKЗZ=3Pєё*3ŒCR4 лmvŠЯ<ћЬ“Є@ЪHФИHBјњIsMIдFЧˆ=мЏŸЫиiГоDc„Hˆ˜ъIT,SЪJ1Šќ& ™œ”$ђ #6ЃЮjЃ`A&–JE L)6D ’)ФŒЎ|Чя8УЂЕWУ>ю!n&aƒ™нЖEлыJъЏЦЧ+мkиГCЎОѕЛЩМѕ‰heŽ#РА`Щ"SЈфžBFФвхFRI .BДдФШp”j'‘Ё ѕ  f JхžAЎ(Ž•(ZŽŒВБІ‘DФZOؘ!ѕ@ДьRV)уРal&]­^Wo@P\Њvqѓ–›Šђ~}}ў’эцЧ—0 жеЭMЪRцК*NgХХ2OR!‚t4EъuFТ€2д6вr7wЉЉ№иёЕПхx[Х8ю-хYWПўЮ†*UHRFЄь[ЖŸЖг—*‡"JEђ}Щ—юДz&Рбp­иJ26;Si" U‰pЧ(†еŸЭЗиƒБlЩ–йLЖ’EKД]Rвџp§,]AЮяя/№мёрюъупЩЏрxaseax†u зКЋAвБљf+'РЧЉf7 nЕЃ6wуСJeq„­–Š2kmr чf›Дчp9оц ŠБrwШ”ФDІ#ў}уЮ…?FG>1=кTq.wћ~WMмР1§RSќnиВъkK}СiSЮ‰ UЇС=Ѓ]ХPiЦ†X)вl#ЉVЊЭ?КKИ™„ № є э’Лї }4#н3ЪХCлЮЉD"ТE&†ЩЁa+,6)ŽЪE˜wLИ<,ЬRXHжжYѓЮNŸ4иЬО!ZЅЖ5‰d–ЖUŸмѕŸaog+}у_јЯлннtч‹Uт–l–6Jvч–јлГ4еXZpЎИ ж |PCeюЗ3О=эюњєВozј’чГebд[Ею*4цAнМ ўўыНЉпR]во[ї|ХњЅ_}ЕиЈ ž7#ЊўќўЬLсЙАРаAН3Ђн0„ЅЋ6Э9xю ›SyЁЪЂЗ@Ѕa ЋѕгFv‹hџ ІYЖXo+Д3$Ф љ*ьšЛˆ0Ч–”тXДucv?k`ЪHЄikьКСїE€у‰]пXѓiwkf_cЃ~lЬ/o$Ѓq !@‰Њ‰"‡пX6wХкџ;ЄHєшcЃв#лKŒЏ[6џрŽGр&6шш уKsKu&рШУ~›ж[л'Ж§ЂРЮж[`ЗŠbYЛcY# l%яОeЄQD*g 0"мZ­—†+Ц<˜1AЎ;чЂ­–Тн[‹AУžX4g„XАФГ4V_z3(Ъ;d ",PwSЮf”Р%~СЎЧkl'Жіš˜‘ь.“‰Щ]К#'NHКо? ‹‡aэКƒч”šраФb!Х.жњВВУХцЁЮчз)ѕхЅ‰r!в†8[sЉhўŒGрЎ@цЉJelя˜Ь Ч`YЂ”Фїˆцэф6[!РаN."Щ”Ho)З1оhГ—э9ѕ,p#A@lgЅ]!DЄ  РАfQЗ™#A#•$yћА[!QЊCтТјНШёjSˆJ pЪFж˜)/Дф!ѕG0&ЋЁКњфб,сЕkrтѕр‡\H‹#0W)А$ƒЎ{e†]lŽsŠВ˜'HФfЎ…+G'фОБ“=Wєжъ‚?~yѕЫoe=GМѓѕ3еЄтh6IкhрЏаЂЏЏќѓї…gдBBи%#1,Jл4К” yЇpЙ17еЦ "œЃЄœ– DфY’Mи№я``,'•œ.Љ.Ќ™ЏPЯіS5hPЏ%ЄaМа Fщ*!ТШс\ƒнLГ ZМЪܘьЌЩЮэЉ+ L)„qкfАšMХEy5 yУљЬЬAИLЫЕЕ”оіЫцм\ЃЗЇЫ™Пmˆ‰їЊЗ— ‡и2Д‚ЮЭРЙВйlFлѕВє-ВтOя&n>aƒЮœ ьјЂьтЮ!Ос>4‹œЏ'%(#p“(ЉвМxHPfІЕ",Tйьіƒа QФˆ3Ц’’VF4>BKVо–Н‡ ‰ѕ’1+WДh6G79šG•фх‹їlXЦƒВA'eA]lЭ(9ВяЇ‘/ўqlлњНcR†АЋРаЌYЇЗx*ŸЉА8 ї§яџ`ЈFB‘&ЃСЪХрV;Gў.jУmЎ>ьAВ,m'AђC‚6їœ™ёП<џS„R!№cNlЭюд'ЖCƒjIЅЊC­К:Тl:SпР6ъф‹ Ѕѕ&FNА"‰’#5[jСЮ[P{эhЋБМ`їwo cЕњуПm•ХЅFѕв*šž0њHcхž%Ћ6эЋK›5;(ўѕџ–эќee@ vќш‰­њФюGvЭ:ZиаPПћчU†‚ФФюI‘ JЩ‡Л_ј›зшєЩУ’Ьzsвр„Ž˜ЇiФIВЅвGFР*­ЬРƒvž;г:шИbжBУ/FHZSЃ§˜ ŒсЃвNl=Ењ•i•Cг}1Ћ5ёЉЇгTmуфђYЊм:Ekї^8ёХcяiщ‚Šj7&ИuнXvъ‡ЩKё^1nrKс†…ЄЧЛB‹gd ВЛъїџ.0d иЇџШИьћ~zёГ]нMЅ Rѓш—Ѓ$А[NВЌ№’њKšЪВЎ]qЄ8ч˜ЅЖ:sйђ%ЅЁa=єNneЙyя€Я‰Gрf#[kющЃвЄJшнэ!<—j RiКЭћ•Эжа—Wъ”ЁЈФки€ещыj7ъѕbГYJ™еД gXЗIлЬž[б д*—OkіОA—AcЦ‘ъ…"6Йo@tЏTeИRWUM уОд”ОЁ ]ƒ'WАUцз[тМhS~Ющ§ћ/•оQjЖцє‰LБк7..ђR•љГЛ[Bи›$$AГЄЃвЂ%eh1УHP!ƒі˜•bдR).0+JЬ E#2‚›гС’ЮR]г*ќ„м/њЙ5o‡~Б`ћУ™У9 ^СЫшQ– `bWџŒЏž:§Щ6†ž;S|іЗ љ‰QJа^#„*_5ЛїРбѓ,* 2mвФ!Щ.Bкš:§ЅёХ+NыЮgš'?—ўФЪ9 жяЩ,Щ=RG=B§ Б[ƒˆ"zYа{4‰ BЕ#=ћŽС)ФbCЙOЬЃЯрFK РѕЇHС…zОј{Ё`ЏЬŽа’€”)ѓвІ Рa„б%РЙl)ФПг§ѓ’ юv И€‰Её'џ2pZs5aQgGlPPѓў„GрG §‚`зig ˜џЮЇ@ч4Ёšа(‡‘ЮьмчX§09 ЬыЫ4!Ёўr‘еb5Iр›@“M4 ŒЅ››3!нTL,­ˆЅ…82}љхuЪсoпм*ТhќГ@ˆХiўзn0˜+ЋЮžг›ŒFqeхОš*™е з5Œ]С"uVTцЃэ–о&ђ`j’cЬ€ŠЉS„цІfaJ!-œ8Œ$ ATѓ} <6єjИG@ъšчrЁе‘Ё§ЂЙr xШ9КšEЙBXЖ Ѕb36 ЙїљS- ў|™кkћ€@•~сƒп~­/!ssмžx.!p лЅB:vЦIрŠ”j‘RЃ qЬуP FЄОоZ]CєvН„™\El€• CУ [7—рœїЫЅ[э: 7-ю5'ИtвЪиИіЃЋ2МvДK%№g<<7T(‘њFpJ5ŽЕнХLСВ†Рц№)yџЭњ.Эх$l€$PŽAj‚rЄЮ…гTс˜@ъИ€,riQbЛцšjнЉ3ѕЧ ЮP#†А”JдTMltSVќ_Лј@Дј>\lNйЙŠТь"Я0 јРlЁc ђрЕqnШџMђ;“А]Gъ@ŠЄхƒЫ.h›эфЧŸеfŸD+*д"dL@Ї›I yљп{ЇeZўœG€GрnAL’ЃdЛдЫŒхІ ™ȘhƒА1(ь_ @!1ЖаЛ{M7жЄЋ3˜ьZ)Лн6]QCl, 8‡БъцJё'эFрn!lэjkЗзmнцŽQ 9Ў1РгFƒ™PT}NЎCYэ2RшXЖнg0D(сє `z;dЫ?йhOхQN!"GA ФЂ+ЭЋеі$oW˜„‚ei!˜ЙфУЙН ŠлPД_†KЛrт#ём>Ю—ф}ѕЫ—ЮЅ“sФгцš! QВPПцгІ›іъмœЌ#gЊL,p-iк&і Lшšъ+GYюŸƒТбeПo§§„>ь‘QЃтoБ6PY˜Е7nЋЫ9Д№ы?‹ŠъЂ†`|Њ‹JpНі6Еˆџ{%їaтcЗкЄZБJ"Тnr*,Д’`Q †чуj­eР)03с Є 5 мЪVЧЭшЮn§ьУХGЮ2"6уёЧЧ Ш€<`XЙ.E€ќз" H—\ љ5ЎQ„4eЎ_іеš“…ŒЪ/hРЬ)ƒћнмwƒ"`J]Ÿpпъ%лNœЎ@PWDtЯq=г{†kЅ@OљР#pгрШˆiСРМF€Нєіuё}Уž3;нR9эRЦё‡q{ё[яјУ-jр„A$&7Х‚їаkwщ[wђШп+wъДс2;eл•С&ЛБМДМж*їіёvеXжfЎlЈеYСOжЕЊя,§ъf]љšбЎИYwюtЅqS8м}˜.ќњ? ђн’МV~ђe ѓќЋSUМ'KЏЏ]gэыYэЪъ ш•Z*АиYpmcЂ8Є­gXUmЭЉ—^їŒеdEq  Q6ѓQБіњFщВъм‘gќЌD:~ ѕЙ“‹—ц†RЖВмlƒ$ 2Lu6Г6“О*П”Tј…*ЎЇХmЛёєОoЮўйь>ИКш|щъuњоdТ†в…ЋПџѕЇЯwЫќB“ћї™kOnйЖ Мт‚yТжтe№Ї7ГСzpЭA Lњ7Q"Ш˜`КЪ=и=.#Ж=…СИЋPз(дП}ф^ І%pnШzLwDШ0гNЄEДiДр<^|/sЏs­›Yьс›:bфx-lЬЃB™J#­ќёЯ•Yaг'NPHY!‚)Б†е#+Цё-9Ў уpЎˆ_uPkTL“ЃЊm1ppЂ U№ƒЬr‘mмm0ЌТ œХЋввє…љK юѕфƒ}:љ Ќ€ЬYГъИ9`ъЫ“$kƒTџїЋѕgњ‡%‡h8ѓš|h7їaС•P VЊLgЂРхM‚Ћ„[pЋЛpЖЪРИsюзРмb@kЮ)KyYъŸ]+Аye.Ю+­4ОАјеAaB›ОБД€мJЕс№Ѓmxѕƒ_Уќ@чдЁ§&ƒ —7Šq`аЧzКxћœ…чfПљi œBЬ$\sр4J шZЋУjхХ’Сџacс"~юџfїєУM$E—'hЙqkJАS.pHУиТqТ€BŒ>аА"$э\АŽ„$XOr:=VPHh1ЃДlоz`б&—ф~S^y(%V‹бЖњЉ6TцЂBVч[!˜ ЏУwIИU)ŒJ›ЃE0,az ,й‹ЌK0U гZPr€ їA]с˜œюP†ЕiРыСЪпџ!€“ЋфЇŽŸnAзИі+]ЁiЁ@‚E‚jбЫ|SћїЋ-:Oo9є˜(БС щм't†Ч[6ЦœG9@АQ$8†l3gЉ\щэыр УиКМЃ[іяйМБ:ћаЉЪс]3І(x>ЛчлЕ™ћїт† ѕpЏ )F,ўdењќкFї!ГІ Ў”Вgў\~šіQ5dmћГКпK“Е…G‹EžXйњћJЪ%ž™4dP„Z&Ф,u–|е2­5{ыВЃй™›ЋОZП&qц”C}я*Hыщ#’I2юяѓЩЇфщ;Ј žйцKmсž"l "yЁо п`Яf;cІѕ$0НLœ›ž`гˆЯб:S)УBgЮЮœoХ•Ї0•з3`џ[%’ИI•6ЉТн“Б˜Гџќёг#g-3п|l>њюМaёШ_?-џцћ],Ђ LьїШќQQR§-+и~Эž§lЂKї7^–Ўе_иЕќнжяљ%ѕ|тџѓ!šy `‘„!Э†ЋERWЙL)Wy#Жš‚Ь+v1]ЧŒщЦ6‘кœ}Лі•)Ѓ’УќмB“T+ШўsѓпЛєщF=0Гo+[ё‘П|ѕло… 6єёёуŸJQ7Б™†Вн‡sѓДIfŒы–ъ+‚щ$"UDУцPyЊјрпYtRг…5+J†Мѕtџ^YЋ~їЭжтrЃпqЭы'ƒќO.[zFн­OДЛFT|гђƒhпaIa~ИZрiЬ^ЙtI•vФ›н?4R)vўэХ‚Шю•љUК ]3"‰а?.Р/вЗљN{Nф$a•‘Ё*CC4…Њ) —‹YЗ8ZUZRr ЫРmš9џЕš#,~jjыrЮž —жРBLус"•+мUr/{pп”ШД•\`!Кc{ЖŸЈOŒЈ=НbЃRсїруС?§іХŸЖЎїн—X–ЛсуŸ$š™}ЛћдпЕњЗЂj`…$ХЙЛЫЋзяZљGq­{BЏ^Qa†ПжОГ9ап=5YМџ…O”В-гІzИјH„~Ё>Б§CC#<бЦвSѕц /s†]Ьн7 'ѓ/д‘щ>RичCЛhоВlwŠ;8"ЌидЂXp#›Vэ.ЦЫMіѕ™'6CЌДz!ŽяДз^џžЕ`MЄићj%pЕ‚Ђ:UUЯ9uот}uрѕ<< ZПРhБ0dp—~ к8ж‡|мыO<ёb7UЭњE/gй$Rw/ŸHЕ5wТ3_Ќ>оl DˆЃИЁрФњO6–к0”1ZЛэРžѓИRj)ЫйўщћЏОДђ’бStvХЦЭП\А –“пќђЩ№џ;]­ѓЪЃОв/.YЙ4кf1˜­žбО‘ё>&Д@и8p3VcqЮЎO>|emНп€^AС‚НќчНщGќК~ъI^чжЮМјPf-,уjŽэоyВАЮЬQdsYіўMgkkР’[ŸЛ{ЭЫЏЮ^U0xPЯУos^YП#Л,К№с_јВkdБ}bšWl ІЊєPFv 'РDOGТy ѓ‘gqхзпЩоѓew 1ѕG…ЕћDgзWЎќѕГ/О8tјp;ѓC…}&gз‡?|<ћэпџiof…Рн72Ю7:е?aдŒI> ' F'UGŒzтХ)ЇђїЄ+Ъ‹uеeћOeЉ#уЛїъоo\OK^^^ЙбJл6“_ЪCOLžўЬˆШ Žк киБON˜ўЬƒуЇєFЭ…ѕЦВ3kŽК"-ы‘Џ LядcвШю]‚фИнrQђХёm"0ŠVUР)B;›ЦGs"poЭXDoЕƒA:pcF cЕ`!‹)"шЙХŠ4Бс!ЙіLƒЂ0Ђ‡ђB}ЈМM KkЅ#`mD—WїќпЪЯ~ќёбgv|5уѓGuеИХ&Іwewяйї@`Е`ˆ|а3S%ICўОЊПWl*ЫЉGг}тЂ“ЛьlшгЋЯH?жжxlЯб&zЬШН“D.жЪгŸ:Wfˆh2пLШ‚zxydй—ЫПžќиі^щ3о{=#в;ЌGђЯм}rє§ўЦьуzYhЯЈe]mv ы3hђЃЅЮяh,к\Y4щn† IDAT]Ј+CїœЪЊJI~№ѕ™НRм№Фв+WMZФ`Г…'риpЃФ`ЌvГGь Џ<в?бGT}ь‹гч‚_xє™ўЎhJрйщЫžJ ‹NG уKФ‚СNR лpn7“Ц.#_{jLŸ8O|b'ышwїя.JMŽPz]l г4|уZ›tЏ"NЃМТНƒѓ@ЪЁУnJneе‘`Ё[<ЉуІŠвУhYЉHЌ@4Љ\VЌ№Oќ s€ !hMЇіd ђЭк˜ИƒЦe$ШTэюFр8&d%8x `ЕФА$тг;>д[]_)! . wmЖлГV§№кК_€-ЏЋCќ,Bи„HIьэяІ3ˆ•Е н;wM uWK)ЉмTApsеШ0–^–ђ.У01!‚rс[Bˆ`F‹ѓ:˜ЄCыя,тщ)Уyg:эyЏ-тмS„ Ог•FG13УXqt[Љz]О1*}z†;˜wъќiDJеешС Ž—ЇњМЙБWŸЂ˜PтлЅчЬаЈОw.}uўз=ЋXЗ ,KС)&‚йIЦZ[Йuбвџo'.ЫЄЌиƒSG…8&с6„0€+Ъи‹Юžљrє„я0ФNГn]РУo‹ђPBІ ы?xV\|џЭ­˜П№ЛWhщЂwƒут3Tяœ{"ѕEДІQ”к/о]„ж’ˆGhPtzŒŸ‹\W$Фp$…Са‚•EФžjw_­˜3}е\&|4ˆ„Вt3”Ќ§ѓ“_Nе+ю{ўи^sєыьЅ‘‹Ш:к„xЅФњr{oІ ЪXЇз*˜t­tжХРЛ”Т]С   їsSЩФРзQ…6 moкча™ѕOlx\нŒъг'ЈГFТЊ|јW!€Še‚ш1хч*ь6ЛGАgP\@‡'9,Ђ5zїЉ›nїEqЦ&‹ЩŠБ‚ du]эОђэeЉ‡ш*p eПфPу:0CЊU^с!1œ™Х`TˆЄfће\:6™qјб"S@NEi;нf<2bpœ‹ˆЁPэыЉvp~ФрБ› jЭ bичѕ8ИУ 9h.Ш•8У\’X(p`ТЅ$<|:)dх%Ѓ™v“сікЂ 2$@+€§n>t{ŠАqfIмНеU@Kє$ ЌC1Šшэ@`ˆиФ`ЗъšЦѕkwvKŒ ЏrЧоЊжБBСЂ1Ъ(м<у‡ SЈ™‰cŸ<ЋKIф|ш(ŒЅ)ѓёk~^wіљпПM’7\Вtе!‡/^rfРш2tGnд€#oЏишЧЬOїГЩ8LЯq‹Ђ9н ЧUо]'ŒЉЊ9я8›oJьœ:2ёя>њєПв˜ЎЩ)ž`щђƒ,"RА.sŽ#МЂ8эn5Х !‡Zгsƒ‹ХИXВџ`EТБژ!@х€ЋŠH7)„N&Ш8exB'LЙСjЋš\> h:<Т&"P fИЙю- с<йA`‘LDмІ|o`Ж Žb›ЁB˜\€,M­<Еeѕщ­)об§Bв:y„ё 8vџŠ№­ЋіP„w +=]й-\ щ˜Ъ3є;КZZМ^XЏАˆЊj„bB,‘H%bЉQ.Л@ЧУ­Ъ†У;/фIQšёЖ˜ИЕ ЋЭаXUVRрnтˆF(ДrLFN”\јћ|MМJ МŽ(С”:5ј…й#‚j}:yn_˜[ŸеЫ‡1еš)RFs’‘Ђ32sЧЇ‹i9+ŸШ^ZЗЕ‹ЎH+i„•KГђz%љИљ+$>§ЦFЮћzЧСФ`пžŠ­|cаіO w^‹#+ўЇНмS„Щњ­^ќВQ_*ЇjџкГgъА—DlBСъƒчЅ№™1$8dkъˆз‚Ыn5—ьл}–эвеWj7–?ѓІр@-ŠU„хќ‡{ Чљ{bДЉІвbЕЋф„ЙрТў/0)^р‰W.ИнљGЪ†xyˆA3-.ъдЎUЏэ‰ўi˜ПšiЈkЈJ<•СЗ5д9^) MJіФ*s ЄТЯW%P3Ё Љ‰•ыv—L™жй_ л1b/Џ6,ЦP7џDwџЬіЎTЫguUR+.вњzЪ›Vn˜:pш№дт‹VўїKТ>uФ€P‰ед`4›б–n94Dў]%ве?ю єяŽќўћšЯсў~ )p^имВЂТЂRуІeОŸuЮ=иIи2фмWіxљЙŽ ЉијыЮRЊяc!ЎмЗ 2ЁdFђшя2W 04g—‚УCІэ’ж+0E%nYg ўїDpGt wѓwsёuыhѓbУcVОЊфLЩoЎ­Љ­KЄР(€‰ 2і ЅLгККz?Wп9sп8М!sїЊНm)hƒ1ыР’M™+œ\;?№ќƒЃЛІљЦўэЫзtц'?7Aюр* ўŠХR)%рbuњc”TОБќ•ЧП#@ОFЭŸ;vь ПБ™іР$ёв%.KхRp&ŒKНЦ|§<іб‡—ЇM2\ГqёЧгfфЯŸ;qdrдфGЊј|Щk/ќdЄЬ ГVOїmЧEюпџž"lаЫ…*Žг%TЋЅОО>§2€‡]SБwю4 6ЅХ5UU:Xх”TщЫыtСо Твaж8й}§ѕЗ nFЊRNћќ“~с pщš0iту?ŸџлSЋLюœБdгЌДбоСž]Її,ќfѓМБ^я-ЯˆКЏчЯПїdџM/ќЄЯ^Oo4~?чУ‰aŸƒТ7!ўйŸПh&lЌе˜ЗcУ[pDЛ‡Lљ№?нaƒuŒьё|чœdЯд ‹тОgц‚\Э1p8Œ‹сЉКЮšЬЊЭ ПњЯ„яp”ѕ9{њŒ7/6XIєОяYЕлЏѓ–ќ4vЪ—0і(Љш5s LС‡79uŒTт;iЩ+ь+я}2pХ B{Ї?ёхЬ^=ќЅ8ћаpљ3 _ыГ”э5єўЁIњ rЮT'XHzш~{nжOšЬ$9|о;УњGЊ5гzЅl/8|ОЎ8#(еUІо‘ЄЪTП,{уЏЇЖЄњФє щув—џ{Џ"€ЪTR‰B Цo:D‘ŸЇЏЇ‹gTl$,ў€%вrфBЧ……А•х)qŽЭfRзjТа‘“пш3ЪкleJUr™›ўўЦМ`Р•j-№ЧL~jCHe•*КћЬЏ;УИФ=§Ц|№YпšF‹…HХj™D˜ўж{‰˜H&sВaФ-/=zMќ№/ЛT%+#4іЊД8’0рƒеIњF›ЬЫSЛiЈWП_ыє@ЅЮЬ(нММ| Hжjsј‡з@рž"lŽі]ќ>gsОK™D,••зЮ<шя/ „СaEХћOСь4н"фЊЮЯМНwъlб š]R­R"тІe"Yєш‡ъ&˜)дqєОЙћњZLvј"c{ЫLR•FфёиЌ>fcrХиР~cџгmиKF ЈƒJ #PKk bOџСoНпg–ЉбlIЂЬЖК„ЮљiЉm()wQ=ю:mQ“˜ІБИЇNШxieo Zœ5WїчоLžў‚еB‘”у :R4§ ИШ;БчгЫ:Ok4MNХ ЉT.€pкф'"&q:ГŽИр3!nњЯ?Nа›СQЃT!JEЮAЯ^#шo6йХrЉИ ш#Ж$I™№aL™влWІ"јB.Юt/– sыG’FНКѕѓ…™ѓ< ›mY•чЖ^8xЌтЬ’l8МЎ§‚Лє L–ƒўюU€(uœЊ0Єa:‡ 0ЕыѕЭ)pЂŒСЈЏQ]`ЇЗ‰L-ЙŒUФ&h Й ьКq•ЩA'ћтзD(VКˆq *Qj%J —ў9тˆеАЕp12Єmy‰Id.HХхtЭД!дњxi|ИBA(WњF)риfq&lzТџm/—ќк›ъnŠ'“Шћu№лњпЃУcЂ2?“{>ПИ@%QЯмjKPL ”hЕp\ (‰@Ђб\фЕ^ГL!т&v\rЮ\(’j›ПгуD •Љ@g„П@tФ28Zм‚SЇK—5Mк€Є5рCA\’r„ЏШ (eз3‡9b(!–ЊрИМ ˜\$jЮћ`} F2hM\`Ў,–+ЎцкOсyс Iˆ4nWДрRњ@їРаЎ›Юя[xєїЗ3OєŠ„ЃомИ-џ№Ž‚#†кŸГ6Ќ8Й)ЭЏSџ.Ў—Rђg<MДљ•>uир …"ч,А)йЕў^+ЋK” R\скšу4Ÿ8‹КќВДNвиВŽ\r'ЭtУ–јѓv"pя6…Tўј˜'у4‰ЌyПЂЂB.UжддŒЩѓфCO‹Ѓ0§OЂБЈ00.ѕOКDІwx[т6VX§ў“spЗP—6Ргџ@qж™кТ]™Н‚R †ZЉjllџћЃћТв pАŒл[t_Ѕ˜єH‚§ЙлиОЈЛ iWS5р[яt! 2ЩриРья ‹Х-МјpO!pя6`ˆХт~Cћ:ІBЮNьаMцt/Ÿ[нYЏJн#cн#яшJТ2а'9йЇnЋЄBЩф„a_ZЛk}bрв 7ь™ЄјDУQcвmЯ? ЛqЅњЊџбв§тћ‡Є…КјпY/†ЏЭ]…@}=Кb9[UЩN˜ˆde!ПЎa;a‚бў}‘”$FуТ‘ЛЋк•uАBяЖJпЖњў&0pбв +7‰3л`—HЂИ’сжчN8Й“щn3>Аџб|оњIї€DX™СЂmљЩM$К"В›Lѓ@Їcbњe–чќw№TuоЎТL8д^Аi%wі ћŠц№—wчO 5Икˆ‘ЇГтЃ•Љj71yєяъзУ„†о(asUG.mdеzЬЋ‡ќеy2v;ƒ‚ИЬХiњmЦЙЙ†WW jвzыn[U/‰ЎнЖ"oiA %йžУІЗmјhЫЊїзДYXсЕ8Ў1ЏIƒ:rыrXmѓO#pVОИУЉЛіOsЙщ€žtижќCКВk }iОош=уг!/нб v/‹*ћ§БѕsПЯ\sНTзЬŠПЩ#ШЅИПЇШЭEт'.Z—›агrё232JтЏЬЉа9іdZ.зЪ3&ВMгW4EкЬцЦ“•tŠ_ž иё1™:ЃAg„_}}Ѓ,о:$XУq†0%{ЩЎВнKу-ЪхЊJ›5e5еЅе `э‚ГJм™3P02xхнІЇЗэя=ЕbQўтЪт&Ъж0ЄL”@,@щж;4gйдVКрх:о/˜ш—ЊР‹ЉƒŸщмf-Е5чŸЁТRТnЙMхr­c(ВБЖОЁб*’ЩA`LЪщНўЯ{TkАУ3?•ч№юЮю^xtэЛ}Ÿ™šы%№”ЛLŠђ@ьа{лzсPNM>HšРЌё…ИЎў bЂmыeЮпџї ЊЋœЖДcізhaГ.Xќы;ЇYݘPЯh-zьXAЙ1@lY П?(J>:еп§њУЌхЬўУ'лГЎaшМ‡{ї КЪЂ-{щ’ѕ™хv№нЁVKƒOп‡%н#L {[мp!Oї“1/-щюнA{›m#PYIРaŠ#%cж^КјЅЗжcЄ-xФєйянэЦ"š3ЖьŸ7яpь”g&Dˆoqнš‹МцЩDи_эkVђтђікЯZм5™MУІ G4Ž[ЮWбќoљ§;ќѕSOы†ЉЏ>e­ ›оњhS•ФC ў”РkЈ=њў'КЯ—ДXiT$‘Рx` 9ч7<§ѕ…wо[t‹ ЬѕРц%.€Р­ГYЪšПwЧwѓ—якŸч‘xп3Й?б] &DюєptП}EЧѓъ‹aG дД[Џ.@Ур(ззlЭ?ИЋ№hОЎtAfщЯ'6єLъœцЏіj=ўщПбž_cЏ10J)m Oж чj‰]™B=-Ч”„3ƒ[т@Zј˜8цКœиЩХ jЏЌЈVD]\Х@дчї˜›ƒkn8ЗV,ў|Uісœњър p]еИЈ\юZŸ{8ЋЬЅ[Зp­˜В™х>rА4™їыкЃкфсС ŽВТ.H'5ЇS4›ЫЙЉ\zр 9JkFŽРщќqœ†›Ž‚И(`шЕеДАХpvйЊЃО=шш3eKўјaжы›&|љЩ˜Ш†Їяkіѕ/Ÿ бШ€ˆpdе@ЉЂЂђЇZЎ.—ŠОˆеХК:+wы~яТ‹­К’zGИВБ`Kыу$VW>КђED4j&‡]HVђ Еœ“^0†> aGfСО"vAЄФИеlЕXЎЬсђk†$ыOЩїz`HO l0яsї•и ЦЌ…+Я$н7•s(CaФ5 Hкp2ѓаРќBNР'„nТmћEef0(њ–аї€1i­чЖœ:w\ДыЅeы?œЇїъЖUачjOэ_љХJНOъ;^Щ§}хŠяW хЊ)#У/Ÿ@]оž;у ЖЪJИяГƒЫ8љ~пNэд]ѓVКAЊё,9 uчъŠЖф€#м%p]ќт€гtgДЏХ…@a9Йсˆ4Ÿ§ƒ ŒC1Jд)ЃВІ*}jКa`џT˜4є  “оzIa*O7P"pAвkЏЧCG&,ѕ%:FЎвИ‚Љ”ЖjJ­w•ьВKќп[ўZНяб1ыЃўbЙvcCЅеje2АЪ€"сн{š: вЫЉ|ы/&огtlћпш+Ю15wЗ45DPєлЊЬњrШмљЯ?• Вuvћбќ' ‹N6№эчgNOkиКfЅD\іСЊъј?йЯК7‹Йяe_ L‰!viHЌћієY]зiХІХьŽњѕЃюjчѓOoы2ћ?S;I„Ж§s^ўSе3”Юў}еKhШќž™й[y[ФѕюТ† ФDзћгЗ/оIй.#6r/—]/э ШЦ#…gЮŸЌвП]Lь=lFŸќЂЉB$ГsЋF™FиXSYUkѓЛhзЇ­†§ЏŸOKљвцOРМVпрд­_GЋ{uS“FLŒМП8 hф…њ’чїТх"”ЉОБрO ЃyђёяI€clТ†‚ќ0LР#!Xэ‡СпЧцZpиmКы72ƒšЕ`š<ћЯч-ќ-ТwњфЮV]y9eЕвЌШ'aЬыiѓfџМ|‰|dёЏѓ6+Ц>м9Э ЖцьРЋs•јDOьNi83tРЩ)8yjчМPM"ŠшОCЃ=К хБrЯ€1ГІuvѕv…ёJ‘sПЎЎ,ЂзК3;РЩм~OAИnды?Т>Сс(д•џ}срОтуЙ5p(ŽKС@eпр4O…ыѕSѓOўИКЂўоvPaеЈ NyЈQЅТ)iјOš~к$уfОѓфˆX’Њ:Жєш‘œК=ЗъS œUpи&№я7щщ'ЮМ9їЛ7Ож‰ћ?;wlšЗ‹ШБѓuэЕб]ю‹}$ V№*'Ы/9Уи*”хH 2НЄвХЧ?‘PxzћјИ*pБ‹H6ъ™я>р",Оа]ИјЌЮDY.фьД“‰ЎЦ‚mGuЧŒUерЁT՘йƒГН<ФSMаx3@dЃ/ЅХПЪ­72>Ѕ'џfш>n†3!ДРз—UQ~ЩXЖЛЏ TˆЫ9Y-ЊYў›ЖУ&!eЩ:ФНsџIЋCˆžЪIњ€йjBфЯМНцХnИ }ущžonпqАтпEи2№Хл'Жфl™БЦШЭ PФ5Р%ЂkD‡Јфc ГЛuП}_^|и ‘œB чaч1 K\ОШЮЮЦЄШѕх–.ыyРЛР1Z’_~іh5BдhƒwOяМЦелзгƒEьUр:Ц- uд ѓŸKЁЊЮF‡юк]Ёo0U—žg-§ЪГЖ.CЫŠŒ"вPSo э˜6mжќc„ЊЊN:КэД&ZЂ QКд3.ю^оЎj#‚)(7tюsЃў;//kФ{1*:coбБ|]0„ІпHEСdзŒ”б“у‡ю->Й6”Џ?ЛŽXї0ВœтsЩйУЇН шз‰O6XЭЌ› Вє.§7-ТHtzy‚П№mцфИ;Юџ­ЕE‚d"№TAСwœДƒГEЮѓ—аБЏюH ›ёО)ЉrЗьМ2fTF ›{ЫЙцEх3јЖРсHuБ“Ю pђєHрфžœ:4Ъ и’Vч(ЮbЃРQEƒ3GЮ%"ф)МЋЗDDƒ8i1АЌTРдЦ*r|н†ЂmАЃ{…ћЉЙM6иДѓwС CŽZ^™VЮ­fi3Wџ~AЊъИЊѓ Ho9Šrь3’u@IqЁRы‚aMкрDЮдР"БnРщЅРq›@ŽЦЗРюD)%”” 8mЃ€о6џ;wЪŠ 7жњХэ_u>вb™8q`СЙЭleЎsЪц?€-t3џЦЈпюs­љ[˜”ƒ`Rж}Ќ•Ёэ$C›ШbM8mђЎDыUIh‹ РsŒPІОёТ'уƒIР"6 b5 vxп0Н‚Э5ЮЬ€p‘(иNХ’ВкPpŒУЩ f}cіŽнE ЈHШЂћ q"•˜іuчј‡И!эLыЁРt t1Nо(=,бdb№ХѕzЎ;бœc_™›ЪЭѕКж›!КsN@^џсЄџЗoЩЏ'7wёэЄМк eы*ˆ€ŒСœIXР—ђTѕ8T"9Ќъ2}–Њ_ IDAT‚SнeЗƒ вСZѓбo-рбf`jСЉѓѓa\TlI){ю ЋuA}§@Я)-ajЊYWдл•Д5чЮ‚ЁИЊЖЦш*АV”злXWwЉ˜SрОшЮŠЙтдђwH#’ЛhЖ-нф1Ќgˆ\Фб$;(˜†`(;mГRB g`œ66ъЬЈL#9фŸHаaГдзZЬ\žрсPЖdбњГuF­•Грлnг&ЊХ,–[€Ђ„Шƒ BfМњєД4_ЙаЮšMXTБ@­hKЫШзJ+{сxвSџyюЁxw!NБ&#sz ”[—SkВ2@pп№QaъmПeLqѓ‘1ХЛЗžyпЈJH7жзZї‹ЂџмgеёЭ†= нЙв:]ИЏ‹@WPP‡Ibќnгъ"lŽ—ˆЦeч”'y{vˆЊšЄ…­Э&FщЦ'%$щрsў№‚РЫ4eЇŒ&гтu‹ѓRжIH{0јв„ЉF[жBV PŒоa4 f[\‚еQеёZлC"ФpњnŽ%Й#3Ž“ ;БHф0јЙЙ3F…Ъ k!fШUТ3№DёbhgZ cmРPc…БЁдJЇт„в=.и+чЪьЃё>–ѓЇЯTЂ‘žк6 66{ЇќлZёžс`%riі_OЄŽЛYе‚M;8Šв% њ’&kswЌЫнчd/й+Њ…їЌ›U&ŸЯŠ@юifСіа,!ž}t:-#—_Ђп/`Тг8fЦЃhjšƒD]П) :QЖ~ћŸRйеНђРŸyп{EЙiФXмЙ_Bы+7іХ]єуŸ?еХЛќƒ'п_§ЭJOЭ”є_jШо˜yци>]}йБ;Штвєћ:јjtYлзюї›(J[wъ№–_ЬйJ rvD3tLД[BP§М?зvbњэю 3eМ™— ^щ`ЫDї…С)г{'6їѓoњЧF(­Е5О†'GH[F†fЕМtІЩlQhк“}“џяЅџ ъ‡DJŒееУЦЄ„Ъt\†гУ[ћїЮ"lаVŒРЧлэtlяиŽQ5XЋФ^ƒ€Їœ™•YXZ(•JE"ЁH †`aЋ.­IŠ„иP`J`…Аж†5šй|zЭђяJнС[)‚ђ€є‘#\м#н/ќДhQdEЦшAАHYЪюшем„ ˆ%УJ•Сё]ћ§ыхЗъNІЙЫT$=мЃedшd-/[Mлsт(ЅПЎ;А§ЛХZХ}]ву"ЇGŸ\}ф‡mч ‡ŽщNэщЅј';U­!pыŸMM1{ѓЧЛ ‚ЩЭЕыц(…uƒуlm!h€žPP84eFьЬЅКJ[sƒrы›Ю—p;8x€>™'uыф–WоuЂHBЫKƒйy2зNЎy•Кьуњ6 Чeщцk-9Нeё!J$ЙџЕЉ=:ћIqЦ-.1^ъЅdmIОЩoќЛуbе„Р§ёзљслMuU Ъ[„šѓvkrЖ‚-’їћ?s+жR@/с˜’0|wбQи+7дЌЩйі[юіDЯШўЁ]`ЩјЯDWn>|)7ˆ@P0фGз˜J5Ђti”дe— *ШŸЎ1СEБТm {=*ю§и“УЂМ`EлZ$l+Рœ7с‘—:#р9€d\КЮљВXaŽAHMв€9 †й‹увgђЇѓсTWЖ" YЧHЛЯxЗ;cуВBb'О”<м6› ББHТќEŸ:МЬq;U]fЭя€.'Ис–>юУtPq}oШAй§бOz> yb"DD!& a[F† ЗМ„Д_ІЃfFA@єC•ёєЗ}Ÿ†$И“ˆяŠўЩ_,O–( SwnЮŽЦ?јкЗŒ$fтb;buВМќ‡Юљa(etlŒєx§‹>ˆЩЬЉQ d>Іž<ђ­Ч’q!…#Р„„„NrнмК[urЧ6ЎЁ(ЂrSu”Њ92#fD„Ь|}†#љ}”›DРNФбSњќsy -GЎPЁв#ухO^Š4–gvY|яЯVd€^\2HфРЇтр%R#Tyt7)(Й-4\ю“4~NкxЧ98Ч kЫША:UњЗ7-ЩЅѕОoкєсгP‡Ў7ЌYИ^г?ь5гђцдН›uР/еї.9йHNqcХІМ}CТ{мЂZƒ&8dGNu>ьРЅЎcЙpИHеАXьдVrЗЈh>лџ!={(CмWэЂŒK•yВ-/лфЁН&їPe|*HyДЎ€ŠЅ^*ЅФŽё€я sg€бg’у”Й…Нuс(гХ'mCLЭM7с3bfgh‘Oг-ю/ uPžѓЋH!†fЅ(Є4^ŠШA‚lлд‰ѓvЫШAЫKHлТіаEН#-$Ъ™іv -Ъu$7Ё8АcЁI—МЙ‚АeS> 4ъхвcJзX•1Ѓ&B0ˆО +gоЗіїŽ$lMяя7нvЉ'];•V9ыѓчQyэЧ—юB?07їЁцл нпбЯрФЙјŽЁлq’RMё Щ­МЁŸй›2aš#s)СмcGв:ч;MхТф‡3ƒ ЄкЁ#~;ЛMS oв_!!x8qј‡{ZuzkWПЕЄѕ Ч–э ‡оjмYxt[ўЁ*cнЪS[VŸоšт &От<ТšNnД$>§€€X„ ,1XгPйТ+/‡ Œ,€б2€EЏ[mТ{dŸgЭИЋrЛЭ#fеэ эyu†WЇНђ4М}5%}ѕb„и]LpђлW—tKямЁ„э–Ж2KФƒzиd[$А•šДћ]ЕГ\ГЈkЄНЂмлпiЎYбМ™ь tж€+эЇЛLИСмк“„0‡GіК/Ђ'јЧўdfйiXУС’“ jpЊ–вlO5ј87˜тЁ '_^јi Ža#§вXДМДq,g€IcAІuUhaNyїёќлhи-xьцЦЉ \Bўrэ,џЅ„ nsUwmРw…ЌХБ!Š­dўЏ}І ГЊЮэ+>tVTЗXœuђƒЃСbиQpь2W›ъ—ŸмИђє–TŸЁŒqЙ=5сKЙqЊkŠыдž*W?PПЙБР)ЖqІ‹ЏРeqn,]qŸПМаЯЛњцэЙѓ/%l7ЎЭlлЗі IлњLюеб|`˜8­sR-|ИwЙvTTp[;РГр˜эђчm\9ЌKУGч ќOPеФ&З]8tД"ї@I6^rWрOі LЯpmд€|kржad qŠы—R[{hг‘№юam6ŽoСsdЁј^FУXsCƒСLKд*Ѕ fБЗ5@u8гћ ­ќЮЫju[ЋqWЦЖ‹ЏМ5)vЩэf0жЌЗ4m—vр§ГemЌ7DjЅКЭэНф{НЈп„Д^ИнN†ъ– йХabsИ)шpiрYг”ъЋў<Зј„IЯжз”1ˆBх"бŽ$М,.ˆG&zEТQonм^px{ў‘ cэвЌ?С8/9‘nA—%р/n=y%y_.ћЪ9cqісыНр $DСЊщ6жTіъ39YGЮ‚ХyŒѓLŠ=тЛ&†њЪaЦ9.wК|эЖпO4†N5*ў+ѕ3АМгfщњВв’sљ‡ўЎыѕєр`Џ+ž5GуOZC€'lбЉnЈžќўC TдfaВўъС6Њ‰-пf‚K˜ЦЙЋ_[Vќь3ѓ†љ_КнŽ3  WйA!жжX[vўlцŽiPxЗ ъ[;ѕdMеХ…9gіўU™8ЉoЇNžœIзА\<-iФw/щџюў ZЉЊн™уч,2э“™Щюђ›аN(zLLџбQ}Uœ8XЦэ-:x/9р1Ђнћ7GфШШV]{ ЖyкїљбщіфьpMуDХЉ.RШнAтХpЅˆЬДЏ)жFЖ>6йКь#џКГAю!ГS1% 2йхЅЕ6ЙЗЗ—Xa­Ц ]ЮbЖC NjкђE:)ы5яЗМyЭhWмЌ?—SNЉCмфRGПЕV|ѓЮз™{NUELЪМшМІeсќyлДЏgЕЯ]ƒ$Љ“ХY~ƒИСcrйЄMDkБИЪGS*ѓ…ž ы§кLЃ/#ЬPH‡ЋЏ(ЌЈВ*М|Н<кВљгœ1YГтЋХ?|Доfѕ>ы‘дсЭnЭ‰Ѕ№ѓяЬ!m1/gЄХФўУRт=#РIлЁв“KNЌЎыƒэЮ…ЕˆŠлЭндЅКŸh8jL:и~ƒM8XMўxќЬѕ~,ІAоКhxЛы~яF4Ќ‡;d5‘А_еВ•`С+д+ЖOtЫ›з;‡XzDЂЁ:|JЎАPa_ >wЊгр8.@%B-ЃJЂч)ГЩLƒIХV{јІ=$^ –€РxhН–ўјЧŠу ЁSЦŒK pА\ЅB$ZBФЂTƒ•ВВИL(с`O šA)в n.C­еFё["РЖ&4PаЗG>Ји†МП‰ЉW џЯоsDqtН{Ню8Ъб;HЗcWь%jl1ж$ІгŒ‰щеS41ЦDНХо{GTP@Єw8кСѕЖџ›Ѓx &_ќe\Йнщ;3яЭЋoЦ6aRухаFСЬd&ЁЇhё†›ZƒО}Ќ ЦОщртщc‚nЃ!q*Fхalа:Г2л(•4€?Ьy2†њAЭЉР=d„l`Rд'1Хж3›S”О gЯvнI єAЁ4J1”BЬ@Ь€аBz ( шЈм~“'ћ…XŸVМPƒЌСк*(4€rGqFX&x`Ѕ‚ЗA PT:Д„РЈд&н;№ё~oQ8ЁPАƒ,PгХГоsЪЌФeK’­цWkƒбX(ђ}GЖ– кЌt ŒО€v*h•RYш7€Ѕз&b)ivиЄe™ ХЉЗ+В§М`@(8ИƒZкЫH`\*иеcБ0:Œ‚г6kƒ‚В*xp„–€ЊЦ*2)`пћJ ИЄЖ`TЊ ŸЉ‘кЂнЈ#ЖpR№ AnD(SЫяњЩБќqGŸŸф9|„[6єЃ+ДЌ=qьИyЩi­dw‘ЂЊРЗЇoлфэФ Ь­_Tф9`PUўУЩ„/-8ЁїаXЗ^^ѓоз›5Зё„+†+ЃЁcwT8Цds%ŽЮЮ2$cцФыr“Я\Н|њpefZЖrDїО3†‚X%IзPžv~Эо”k‰ѕ~§ћ~ЖŸ—ŒmQеž_Пт№Љтš:ЛОѓ& `ЧУ2эИЉ—p•З/Љ№кdaіембžЂ8ОяjIЙЯмЇGŒ ёhІšВ [жиц5п>ЗыFъЭSUПŸ=>kњ№БіAїнM…†ЏпЯhg<К^Е?]€­ејˆTиВыЂаљ3ДљйЄнGч4Aіўн‰9u1ИЖм|“’j(+г—Њ-  3епZїѕw&™-vў=&-н<ЖNи3­ЛІY™Ÿ™ИыŒБЧИaн%њкв'Ю&ЈчЯ &Љ•щ{wџКxSКбтђТЯ_3+w_>up_yт3cтFН6#Ц’qрчпПљѓZ–АїЬ)3—Kˆ‚ ЧЏe‚rѕ­ƒ‰Ќ˜сгtёpsфjЏJЏГйЉ•™—6žЬgњ…ЦгЏпжљ ѕEъ№YЛ>Z!>*ЂсЬю›˜\\uqЧЦ’Q_,–$о!лDsя0фRе­ы.ф—йMјјЅIу‚„АЦЩ чь*XьTл1­МИэ“ ДЉ{FЪYikзЄC|”ч–-;Ћд,йџ†ЏђмЋЯџQUgžДьУЉЃ‚™ *•P\ўєu A‰—}saЧ#^cв‰+ЫПЩ”їn7#ђHŒcЕз~{ячU‰ѕ:їљ–Žыс€“qQЙѓЕЙ?яK оЏэњth„'щ.-џ,ХmАwі†ЏVi?КјНkЭ…•—]ЈбXШЄ…{6 !Гшїgг$\Ћ~ќmgТQЧxЏLeоGI+ОNY3мЕпDЯјЁї=™žш4еЇЛOy^EuauЫ@аYtї0WgoЇ–'ЙaqWƒфъФ­VШ BŒXi$Сs {йyVоЎGвџк->m•Bq+%Mч2œ!‘IyЎŸ оm<ћGљEћ№95ЋKНr.Kбг/иЏ&mїё3vюВч=r6э§§„ЙЧ№јАђЬ#+6sХѓєuЎОynяоRЅд€№  ЇbяЙнћK\Тћє`Ћ\vмЫл)&‚~vЩŠ?*ЈЖycœэdlК‹sа_O_†её4B:С[фЊн.uНl=ьЮ­?ў1ЊwWSЈ2GBYыi уu"i\ЕАx‹qЅйЧЙіiЧ ™ЉG5эу›ЦВЫ ыЦ|zAф9хЫwќь(:&­-‰D__}чъХ*љАap2г5”нКqГЬž˜Љ+KJиЙь˜ј•зОŽтЉы,"6™ЪфјиKƒќ>ХѕіwЖ7'/пВzGКнЄ…oлзлtfг/”9Џ б”f]ќqУYZXŸу‡†Р‘PZš\л4=0gOЅБЉ 6NфОVЅs xЋ'OSёуЯGљCgSTхэ„Ныжфž1cL€Ÿ}бщ„НыmЂЇіўб!ЯЮœ•pфР‡oб9ŸŒч#–В№мfAZšЪCЖуenТњеПеЦŽ~хЭщй?ќєщр ъка™_O7_ўaлЂ?CУхнМА==_ќQѕЪK=”яЉЇе§|щј‹}до>Нў‹эfdPЙXњW]ь?aблѓЋwЎџ~вtюБ­§Аэ!Г~№ќб–š3ћОš№Ўнљo"]АъЄc>оЏ:ё­їУЄьŠu}>-ѕьч<ВKEœћЕцсГўВЭєЪЭY“† Y8f{ЮЁЋŠ”Й‡с zУn˜k‹bыЉЄUо'*є8Ž€дЧџќжKыСžD& œјоQ^ъУ9юШZ–‹žћ§;dеЊа@”)ˆIp‡ЊмЦн’|§F%Л@й)ЩUœ†YВГЏхяTШд˜а{Рф ƒћ9{:ћiИ~#ѕ‰•Шц,А"%p‹8jіДHzощКќeeEu Ц•[ЉLЗАnaЁѓТЎŸГѓЫccMjƒж5ќщЙ“уЃмxl‹3Ј%AcчNŒso№ЊKz;ПЌVЉ*­н—œЮь>Ю6otxHЗ n‰]P‰ƒ§\9Ћ‰Х.ˆіїзH`k5†•,т…шЊ?јRС0М8Т(Ж`Џœ#ћуzІLL“ЩiEcaБ˜оІ:Л€ЛeZaXдuЙ‰чDЂЩпН=ЉŸ#(†`g‚нХZ!ас-F@1­Ќќ›Э&2˜Z6ъ4Ѕ• EхФЇ€cЮѕ sђ5А}уzEХˆ-5Y{rnЋeу{„…йз\М‘]˜SVЋЇъ,zзШq“ч<7&€ъўˆоyŸРѓ щ6СI ‘Я•дьЄ;ХnŠх…ўB}DBjЖЪЄћс[SтBЅ ЊЉDн:Њ1iN§тЅёНХјDПњ‘я_ЙXм36€яtZœ$zаМœJѓwF“кЄ‰{fхчBdм|SЪй7АїŽ>з+воЋћѓФхНIs'ymAYŸi1~ОbAєЙ зЫъУ `хГНŒ .kЫEу_ZџvМ3зя”чѕтžу…‘Dб/…•ёoє і”“ьтЄ_О–[зЭ™oT5CцoјfœЗ„E2х)ЪфjЫХ/&6мЄЉћœжю3’$wƒ+ЏОh{юЁНљЧoеоyякw_оX=в­?р|їЩі„="Qp/'y7yЮеш:‹ЯђŽєцŠyM”‹N†ŽJО`OЮвд—$ae ‡9D€<,Њгињћz‚mФ!1‹і„C'ѕc-\ S€SЧ"‘™$*JCз$~;Р^!žŽ‚š2…J6Ѕ€ƒ—u`чWчSIЦš:’?ƒГ,#Л„…FњЙŠy АSEш0—иˆ˜HOгФd!ѓЇз W–Т}­ђRh@ЋХIt2ъE:Z‡ЮЭУжyКbhК[ЋyЬЎ ;уˆhEё>КЊ”ъDТ}јtrX8œ ]и… С•SјDw;žtdŸе]RЋь6мŒ“ &U,Гƒu‚ž#0c{`CЯ`о6O]pў~!S3§еЬ/љГ[а”™,ц6шЉо•Ш$ ™L0А™М{wк§АЈLFVЯй4›ЛдUъяэ"dйˆЛ B[œBaPЌЧ*Ёk\ДгХ‰WВдЗoЙ ёї—0€хM`оСоžЮvlфžјрїD]ьy уАщ xКГq еЊ.ˆhˆЧжИbЁЈРЈ@Й„GЇQщL3ыых%ђЃ%д*„№…}‹|zfБ›Ця%uщŽ2Т0ЂТн]EРхЇ`<xb­з›Ё№иѕмs{сœiFVŒФЋБиw‹ HйcўЎWЫF/ŸЕѓJПi?Ўœцк!QЇƒœчђVиќ…СЯ+:П-ч`ruњжœp…Šќс7Dж›Ьж'7р 65 —iVЉQk”zI]ƒ\ftбР(тз9єЋ›цсуevЬƒі )<1шŒњЊšъseЧ‹"Ѕp,4ПнірЯs№–{ћƒƒuˆС$GVЕzГNпœ˜Ь ЩV 8№mœр0% ŠХ1qђш‘нИр/„.№Bе‡^7б+,ШЃ&‰E!|ЕqЁf  "&>н:/yjЕ lупm4И~A@*Џ џ‰tZі‰і;жѕЖyК[ѓHXYFўшœWЛ…†csаОFб(XЇГ%^‚шСšЌ”Њk D З[ф`~Тлз•šIў€иI;v[іЃЎЖЎі&ЦƒйLЗ“іYјjФДЉI;їЌќvгЇrЗUѓ`выЭVЁ”кh1bfL™ѓіь?СЩ4*•FЏ–ZM6р)ъ TrяЇ{Цvw=ЖыъOП^ЗPњП>\j"—HЬФК|kmЃ \вt„rA" ЄЦ`]V|ЉљIsMПЄMg-ЪW&‹l;ДTe“х„х™MkŸŽsвmОснs+@DфРm?ccщ@Gi4ы=šиl:fo1oЯŽЩ1v€€Џ` шДMБRЦPbœ$ы7ўЇВЁхЉ?‹џє…oНŽ}б Рџ!Lщ>Ўle>€З}'oVgРѕEђЊQюсчЩs}Ш"“ф0ь< Ч'жЛ4ЃдЗЛЄ”&PHTІVRuŠWEба**h ƒNgВ”z›!рт$Г’оDQ”IX:2EЋЕТ’*аежegЅ3f’™B!…KзЄ—dЙUmЯG жo3ŒD“ўуBЧ`7ЯгЋ3Šƒх=ЄM­R­esшњ!#ж‰m§EбІiђТ.@qђ‰“9яоо&/ƒ)b)6ЄЄї”кy и€gЋŠj+ГŠAчЕ<Ћ8зbpіВќыыЉƒn>БЏzѕ>Ц#EЈЩw69м"ЕТ@ƒs‹)Ђшх„ЩЂU[t €ŽaѕЕњБЙКќˆЂєYˆФИ{„uЛutнќ_…ПL№тYjЋЕіЁЖ’a2зkRЎІн’d]Xѕ§ъЃD№l€9’ЂŒTЕ<\цьъ$7™Ћ‘" ј з'fпцп* ю. П–ш IDATЛG;Шo|žД—хoїz4S5X(ћ{m™еЕ*E^YmMНšh(Ы.ЃHy\лPœ›‘Ё`:{јHXrя(Й№кцу•=†ПтяФщФђЁВБЌћN‹ЅМБeG6ž+&†Нф%СЉЬX[V_•[Ігъj ЋJsR™Х еЇ_OЮ%ФxлKю™lЭћ@ЫЄbњЦNfВжMн,п3Гg”ЋЈюяw(їи•gzЅЭyїžŒP•ƒЅ~АщД\0 ЏфжšяЮ]>тЭѓršA[БnєZЯ“ГЂ8ѕХ%zOДiЉншJЯю/pэ`яэLX’ŒwётЛПО`QШьУEчЖчH­Щкxg\т ‰žУЫzвШэЉ[Еэq‰ЭЭ;Ъ[т*ВsКwЂvаI/Пѕ_Ў+Щ,9№УAЁтРр"“h ќ’Ьfc]­внIўювw\;ГуBG к0Uицќ[пџьXЃGFQиј'ˆŽёˆЬмПэ#eвфcIt№QoІZ}ž‘hLОШЮ$dR‚ш™уЧ—}|р›їЖ~N&цјояGa ™,:ДЈБ'ЖQ “'rАcФbIGѕ"щЧя[ч ѕ‰хxfуњ%KЊŒя>5Ђ›˜Єиїюw'вЉ гњ7>мLі{ясžB@`ЛBчGрžНІѓYЏ”NЧ+лЏжTд~6ћ ЕZХdБ€ЊР'TНш&Me)ЭXkЌЉ‚m_LЃЉ2SHZ rvџaРщВ>Н^8ЁYНјЫE=Жa8пЏЧИOіz3рFЃVпн;lTФŸМџь'—ƒІ=SšN‹0KCfЦЎ Ÿž‡$lБї№ЩKЧƒ” IнЯ­{іІпЊPOŸЗdnЬтgižП§њЭ‡OџŽъя5ї™ЙKž!+]*P@а 5gОћuѕзћЪюxтєЛFП1{ю’сфвфc;nёЃЦyHhdЁџ№ˆ ›Ij/gg'+-*.Љс4г& qЙю№вwЖМІвиS_ИW]olGNЭSФіqЇя?јрƒ?ќ№ЙїчП№СѓЮєЏNHВвь`Б@+ёк ЦчГHBY]Я‰Ељљь€cMu]EЕ’*fЕЕЃžр„™аy Ф@Й•L"Њ}#`‹>ƒЩLb"ЎšШM­?ИAЇЖ8 жФЈ ~ѕ&8,‚ ‚ @~7ѕz#™ f>”‰єGW:zмх4j”ZcжРZ>z~ЗX” €a3{ЕСWДЊKiеŸ~љЙт1ѓцvчуtЋQuЎЉКЛPеšЪ„вЕn>ж’яђ!0итБЇБр&ДXL‡˜t*Нgp€зeIWф}xz•Dљzш"рћїЯh1šIС6ЉUz‡ Мц€ д6шLdєiбW€'6-AХЈеъL—ЫА`sЮќnјnуWЏ~НpсТхЫ—? IлЧjЃі`сiЁЬЈЫn|c6Щ3ОПsшZлдџЏёјсё‡^y№ЧоёНџ_вЖђF”Јэгц8|ИНПяџѓ—нЃg7lѓућўкЎ ”РК`! йи<эб"kZЇh Xѓ+Д^ЌГЈэ Jeѓ cэч…фЖѕ6gGл5 =Ёщіqџљхуе+пћiщвЅ}єбпьыПkE§ЭЮќOВУікR!Дз~qY”jйўЃЉ88ж й9:ћ,%xћmђї-щxC€Ў5ƒгh+­РЉО›(*tt:АЮнІщ‹~HА‚Ќ‰mC"S˜Ж' Т*вј oГ8БЉЌЉZыЦ}wЉXЃ­RсЎЛ-Dkл6Šcw˜ИY œp+2k“ЊCŒђ6Ё‚ТsHpЗтVVв[ Ъ ЩШ рЁР-ъ—ПDоЧ=т\ўu0љёVяgсЁM-w3’ЌмJPтfr€.zwмš d66Зщ+Дn њ(d& ѓnaS™Рfƒ+Е&РлЁТ3W*oР%Ђ ЦЩ‡L№&уHQчЛТƒG Ь<0ХАЉCŽя’LбєЂЭJi|кЗš"­РI›WMГ цvsт6ѓЭ6кAоxйд44џQv›•вђІыІГ#аи:)pьЄq С_ў‰šИœsг$ѓ6 œкЃѕCЦ2:6>вAщџНзд€Џ_ќЗs=R1П)!УЎ–мJ.Л Ѓœџ{Уfгт`;_Ио ЗПр$(я(ѓННmЭээ=ЅсРыыCљ д:›ђŸф[ 0гщhfк‚@hдЈЮХfуЁiЖ…GЁ‚;l,!f]WxМFрЩld л№р/k!шdCяIDяЩVЂиЏkLOfРЅСNˆdкtєy4Ѓ `p' Y›Мїф§Ё>рqћбдћЯеТЅБЇx‚+Й*}{ЮС#Eч.”_‡KТА›р1tМЧ0G–фŸЋ§1.љо]]…ям†WTZžzŠHЯРџмЃУ=‰Щ№^Н‰ˆnf{{‚ђпуbС‰Ў ?p"?Ё€ dhъ@,иТ“p86m_€!зD%BHїЅ7>h\ў‡ЯyЦ‚ тќКв?3NNњ?,љџЗЈnтИw{noў €py Х?Їoў%ckiа-{;FЬСџo џыЕчeаdAЩ‘^фЧcOАYH5ьNЙљРё†””њ у,ОО^мыПuљ#y‡№^р‡ЃЄїЉДБл:я-гЄз™qм†ќї)С6я?qп™іплцЂ%э”љИ­Аџл™Ыд`:ђ§ё?ПйзЮа4ОВК4™t*ЏеКwЋL`2Фd4˜ўqgg­*m‰@ѓЌm{ќ‰) я:;b t|цЙВ†Њ–x~OшkkыР€-љ>=UКVYYX­жДшQкІ#єuuехUUeееeеŠ’ŠК:Cџ1н‘gsСЉK—o–ыкз‘Е-ѕoм[OРѕB)„AЃQед•чUƒЄUЫS›т ­BQЋ4кђmо>КлПџE][;Ќ єWвso™ЌУ`ж˜A:ƒDДяvY P)*$wој І@b' 5Jњ5J|h**вЯЅъƒbztоyX‡ Мo„К[gwгŒ1IƒF[_Ѓ%3й|1ЧЊrsпŒЩCo‘[hpГ6iЯ’Оs“^ЕюF”}\ЕzхюМc;rЊЪ~LћуЇ[ћ9u‡\‡№5ŒжљКbЭ5™С9 :н(ЕФЭ\Н‹km„—Юз@Џ5йЉ•2ђё7ƒ!m§КЫєˆQуЃм•ƒ‹6эќЅдЫI—7ŒњlV\9ЫV e2ЄmйИяjF•\ЋЋuь7mЦxа9вуL6Їб4З1mсВяЧ/ош+f" џ`0(ы@VŽЫm&дZTWіŸИ}3ѕьnуЂ“KBZ ГYлЁKќђЋ„g>эУhДИєЖЎНЂџE€­QЮўоЦЪ`Хю}гі‰FЋ™ќтTЬоzФo@цmЫሂуS œ_lPЉкб*Ž:Ы~№щЁJО3—'3#n џќ3#]tЊz3Юbs`єUfюБХПч~фѕ6Тdає и]пNmfтЕ‹ћЯ%Ћѕ:tЪэЉ›і“ˆ*E-Ј‘Zл€в КlЧЪZ7ЪєЯ† `эDinй}%РfН€U'xГУ§g#ї|!Ѕ#П%CоHц]W†а #Ј 1ЅxˆTаъ@УЌн`1”ЗS‹нЇNф _ќ…”`ОЪK‰`Е)4ъоМе—Ў_ЪnpълЇ—7з sадp31эШОЋ5 –ДБpЗлЁџќK=%xиЏзџќуЦ0G?hЪ?ОЖЌюсpUщjџЬ=В#їHБК|yъя?І­ ы V(cьCпоџЯzVTa8zC;ИЛЇ ‰ $А9<KBŸяѕнU§њuО. жTk,TГЎІК^Џ' dŽR)FЁ-xANfѓyt‹^]žЅ0ѓ…Ž\АkTе•хЈ8ЎbО€NfЪ–ЎљЏИ00AюR–ŒѕŠ‚:’ƒ‹lЊ`б=‡OтчиhUмЌЎ.Мќё†Еƒшо­{ ЗдLЅcГЙAQЌЈjа4Љ‡ЋН˜‰іƒVQ”ЋЈ6›Эt{/Бˆ v•UХѕd.нPWЁ0Ы‚мqEЉšЪg`ЊВЅбD‘zЛKьшHед ЉЬЯЉЌ ФњКŠ„tSuЩљwжЎ›ъСoАїї•Š$Жчog7‘‹єэЖпvШ 5ЅYѕL?7>…D‹ўь“ –˜ŽLК …yѕ4гX_RVюЭ|мЄv€}? иі/l`Щзœt8ЉьvyЫъАЖНСS'Т 0’ыWB§Ј6Ак |ПОр‚7ы№šKtЁ-‚‡гM4{EŽю–VЃ1 ч—э€”\Vtќ˜ёхжtЈ/L8ЗѓгmзЇ9)Хі‘‘\І0j2'%13Ѓ†%–њEљIРVaже–чІЄV’8v~1ўb.Щ VV”hщ\ЂВИJЫѓ‹i‹J <VSœ•UЧйћ> /Я\•МчФ–гU^хFZ/з@/_<щ•“žВъУ?рVѓ‰ §<ЂNц&цжяМu|Zш№'Ёпb†p^Ргsќ'],O+”gЫЎ-:—Чш“cм шМ'aўZСвƒIТ‘1№'KlЕ[@ншС:*}Ќ˜‡Y<ІТS‡ж*хR•щWю”цшƒ&Œ~іебžь+П;Юю5eZ_W,ЯПцЙMZ8&и‹•{xЯЏпTіџhrПў.l •A#ДF0гмЊ+езŽ-;IŸѕlџodшDSЇ†] аn:›OW\9yXЏ%і^n[№’їfNіьœ”wуШњ3ЇІVч4єxiЩТ7zˆxXХХsыVџš”Eh*ЉQѓfЮYчhgЙіУgћєARcЦе‹фWw.Vџјй jИ'ЃтФ‘›еЙЊ>o|ќњы‘lКЙьЬЉ5Пќr3—ЎWPЛПš‹‡˜Mд{9QќбГ'xг)4&нЂБ9k6vЃќєжзЯћmјb„iМАфЭБЏ4+„Iг'|ђо~vOOќЮ‰Уw4xяЗŸщЅ!bжиpА3=*њLЭ­•ЃеєйqL`/о­е,ш(Т0aя\csОžAOI]ДfѓQ“~ˆбЏŸ№љЯJeнЙ”3йД7L я,ctР~xeYey-ЮH$2ƒA3”g\Mвы№Ѓ'їхрaKМћ‹0\S]p|пoЇ*гђq“`Ш‹gЭѕ6V”\YЗmћщ„‚ёcfM™:=ТX”yьГя.‘|yњr27d ?тЦWп'qCљ†ВДЋэхƒeUV(H›їSі,qёy€f}Ь‘`ЬG1W:ЉGѕЄgGŒ}їФŠУYтф‘2žУЃЊљџЙшxoЧHИ*4U;ѓŽьЪ=R *љъцЏпЅЎ"ы:p’ џч&ў+Ћ'ЙW" NЁ‚?8 Xр(дВП ˆjвеЅ;C1mсŠg™iGОћhг>Й§Œh]]Y™ |`tч1oѕXіжКXš^Œ]пžO˜щцИЌ\•ћŒг9№щоЙЫкY˜–zюV 0`М СЃ‚ьcћВпtv№ш—gEŠ$`Œgb9ћ7ФOkндšMя|њ§щБЯvу‘kf~u~рsпююKНu№ХgVє#дW&/vœ§ќЛ›КyК Яы ЏlЫЯ9у­ѕS яЛŸќ|Ј—Б`хФЯЎLygЭЯнѕWvЮšМ,tXdџCЦŠўИ8ѕЉзž с‚Ш "К6’лvуН€&с"&?ЎЉ*(nhмXq}}~т‘†к V_”ПmХoОэв#zNя‡6кЖОNФџ-,РІ$2БgŒW“рЕщ@„єяэЧ6й0ьDwP0ИxдMЏЙ˜X“sчL€й~А–уmЂл›Ћг,ч.žнЖkлЎ};:Y|I‹Y›qшшЮе;vЎйpшHЦ`yіш?JЮzyцЋ›>)юVн{ЃŒћды_І9ЛёJЕ^Sx§вЦU‰мЇоџўЯ'Ž“œўucF•йb4жцeх58NZ№ЦgO‹ЈЦšђœ‰ХьžфmyХњєь4ќЋ7g/ž> ­]Иџ<ыdяўЛЩ<эd=cЬ„хїы{ўЛНјЫ-w`‰N;>|§Š^є–FЃ–…Їgœ~}д‘yГідкчџхjџЋэpO7“ЛГI,ТXƒГH/р!>”• єа?mЌqГ>}uBџџюЯ<егХ1џvмГcGnР€ЁрвяЉччGхnYїбŒЯ <ŽхhЖё„~QC‡…9‰йАся„SЊ(HИ•zщBj†BkДаьeaЎƒЃГЋГ“HŽ8(›sF>їнзScƒ§ƒЂcЉєJ0tЊЭП}оd цзfžИš]jSєее3ИмбbœЇ_\ёъˆШ`7˜9В`œбЯїUS^2ЅЈlМчЅŸЖ˜Ѓ5)‡В+qGЊЎЂJMЕsv 'Б%Ю.nNŽ0u ­Л„їjT г њ `мI-Œћм’ ‹†ЙЙКѕ{c~ ;wЕќўEќЏŸў[H‘Ј_, Л_Щэ’šтD5Р1Љ‡ƒWЄзУZ92БO"tЪsлK‹Бе1#ЌЋ@ХЩѕ[~О–[B)я+ЇK 4жWеb5!Ер`ЎWlя@ЎАsк‹СНe‘EВˆёѓЯыfЈШЙущf.ЋjPjЊ+KюUвŒ„§•Dyv •ае)ѕ0ЋШvЎcцН=.РŒ++0Ви%bBЧyЕп#Ќ0 %і".ŒI'jюіхёК›<$Ё85]‘{Ё Й—лУщ‘ “Ш§œbс*UWьЬ=В+яhN}сч7V}›њћ0—ОР љ==§›НZPpƒVCHD„VЇРьј€b"2dшVї4HцИQФЃ§њpЬ€ йlФL„С`ДXhШѕЪгКЬf‹8 „%JЩ-Ћэонt рU3X]7t‹v8є‹о€WS№'м(рfжb.Ч.˜5мпШ’z oДz#Ё7ЬрiЄ1‘ѓь.eвРи3nаЊ‚I‰BƒVм:qЎњ:ђ2,Œшя+у!XƒcžNB%F­l›—MУвжМ)‡OV\‚diŸx?) '™єFLoд›С•\“ЕrдрІі7i>Ёі› ЋNBѓ) 5ѓaSЕИ…ЌПъјƒ(zѓЛії_и`М—ШЫ#nо $мMžфБ‚нlVkdYЖ(]KbдЬVy­Отp:л•Nѓ›Бш•ЁіLЊбЌж2Щd\Oa‘ЋR+jєt*€7дЄSщT*Ѕ`™LЋjUЉŒЕ••jšTЦoT @­A ‚Жcе… ЧBЋО]MхEИvо *с/‡`ƒ>€фxз­ЋЊK=•жmH˜Ф gYGЈг§#›шЅЧщ§M}}<НiЮ:ВЧ W§{ŽХUѕъ=ЋSН*fŠ›ZEрw%nTƒХlRV”ф—г@Dв‘њŽS-ЙлRK'КJЌz(РЋ3Zг\L$ )Лtcˆ~Ѓ^Y+![T&•‘ъьЧ ИWKтЮхХЄZ&Й>ГЂрJqM˜мzƒЧlНЦ "„JЋЃъъJ&ŸСd?*ŒЈЙ§џП}н#@Ї-ЋК`{кбgКњlЩПЁjА09Hж Ў"U(Р\І2яуЄ_пќuИ[П‰УэlнўšќˆкžfYГšИ~“`™3л омlЃ`Zђз5ФѕdJP yюKlЖDиЌ+Ž_8BСЫcD•‰ЧK„ђ)q~#ЇZ=ъ”*;ОjЭuM№МoцG9–}П№›kџt–ЬьюLЧв]ЭHNЈW–п<~жPXмcLwЙЋА6эьž‹ЬOuї’3I4j]ЦѕS[5iH›ШŒйœ(№V}rь@ yР”aў.4p—k=Й!<–DЁаpЙMwŸ5(fхПЎQeљyёєеUЎУЧFљrl#4јоМ$Œюѕќаи>[ОЊa SЃPxŒхХrŽі­ћtпо]мФx_GйTweгйœœы$rЭ…- ާgЧ9АЉŠ„Ны}^^м“\Bœжx†ЖQ˜XСжЛХ оўЬлЎ7Ф'{4_НƒЏјha[ /љЧјТyWтўАPIg|ўњчF•щФЗ'+ЊЫСЇx#ЄP)T2…Œ|М*•|uН?њs]Нўќ/)рЮНн'! мјх›Зpа1‰ТВы6aщћ!Оƒ{*–ЎљxюЕЇ?YтОІБ&Ёs8:QЈ4“ ^ ]Ѓz=§BбцŸПvUЦЂ7зqK_•л$F5лDлЯ;чѓ7ь‚ФŽ7Ž­њвl™†ŒфCI+pЩя/{sБŽэŽ'_ўK§Б™ДF*“іА€ /оЫ IDATњЬԘ ФqэђuфH’LA#˜Шж“:h‚$$™LщV]YѓЮŒїhLк—Л?}№HГ4]йѕФ;eFаEЩHT†$8єŠђФГ)Z5phœ”мP–•orіѓtdТЊ*ЗЈИ–хы.ЭЊъьффЌЕЃeўБс<‹В%1ДЬP_зm?oXЏI[~'ѓV1пнгЗ›a(MЫЭЩ,5‚†?ћL4'OЏЇџ…ЬЩПяЭњф}‡я\єЛая9+MіQ4ё/јc{ЭК_yѕE;@ф<џИваяй'Тљ €К~џ№ЏѕЧvџцvєєд г–]”ŠzdzzœAШ5иFэИ†Э;Љ  ˆj™X0‘g$Hœoж5Gџ €Xж9Gциіи"Ц„>ќнФ0[шМЛбѓZ0ЖwX„OX$hg#j'Цt •‡„#д`Cю9Ÿ>іŸ tЉшffUўйќы §џиїїa;(чЙМ6я•р™ЧŠЮƒ—œЄЊ[[sР*ђ/оC]њ0(9{ВWэ7]KЈЫЙ!‘t7KЋЈН'ŒзЊ%№ЮВАЗX<'Бžm&k­Ввф4ЭgЃжFЏд‚dB2“жLsЏŽˆ‡hšSи”гќ§дV†zуЖfDPЇ)mіУO@&^ЅЩмRЉmbи%lЃзF‚ + >з ЊБt*Pйд g0 Jг6˜1us9P~Csлp;Ї01зрj6FБ` Эcе6ћ?џз‘";y_Адљўюг~bОˆџі/oSivцы=ъˆžС5[С$дiZЊшNmš$3"ЬцJ‹dА-в’ЪБv˜& Z;ЭѕBбPWѓ,jЎєIћeб˜гCGЌИВusЪ!pеЦІuVтѕ‰(:™6в}\йЪ|АбЕЏрфЭъ ИОМёЫ(їp€ѓфЙ>ЎBЇaƒQтQСєœЎ`AоЅТ[3ТО&ЊкŠуˆО Д$;!ˆя?ЪeЅ;ЕлИц—OйœуюяНyя}r7uЛwєах Нб|фcе(<кnыЫ— Tе3"4ъoY$ъєМўЫ3Цў>y;]яcљщюг)ї/лѕzѕжд#їyнѕШfМјюKТ_8=rгЧQ‹РпiНQЕёЮP€›qъѕЇ @ј/dœzа‚ZZћыži@ЂQM8К'JР[8ЉuеPq,ЁHц$d “Q]ЁƒЙ{КJйэ(РuџoМ~B?ur€ ўз†7т$§:tmФўщ\ГТЧ€aŽ9Wђj›˜юџtџщђ™Ц8љр­Пп9h%ЈА(ЬыUio]љВпўi`ЪФfтўe„э:s)Ыы3ЏнЉ,RtІљp4kМюŸ8ѓ&я  ВXyїЯє?yjггџIyџo… З їŽр#iNзю|w˜[&zћ7zЕює†ѓ‡жџ…Уu•Є‡TЭЛлТџ]{;Х?йzОtИOoи‡~ЛОЛQVшŸЌэё)л_шљ~ФKgFn~?тeWЁ~]цЎвБ„лвШlS)Ј~Жщ*№27м8№ˆGT7uѕZ­ВуЋ$Н4qпѕќД‚6ЭnEg“кhPѕp5` Ѓ-ošP+ЊŠrЫjTїmScчЃа6CНNЋаh*5­еCч3wЅl™LЭ ћ_*бu §п4j’ВЂО^{&j‡ƒdдЈЊJ8пQjџ(DЎ5у8ьN`Иўщ`&!Щ-рЊƒo_:ђ€ѕЧ”ŸЅ&eз‰d0ИѕЋўЯWХІ2ЭWZMЈxяЮ:Ъе%%ьЯŠ“G №ˆЖчи5vђDNТљ‚d њ>5Ьo<šžч–фќАqXў…а(Tї |\Nxё,Т{сqыvš*3R’n+t Cˆ™Эz†д=Дg„З‹1@PCF’^цвЇїмЌїš5nlhSп[ђ?‹!s"p…Б„C)F(вЎŸн{$љvFk 3~јшhR§ŸеїdдиšОsemхsЬoфh5’4•8dЮ(Л :]‹SчgŠЅ.хіЎ7зМњжWcŠWGViv№кєе)+KѓnоКzКDрвџщHЛЖ™БŠЄ“Ы>м’•]0ђщY/ ѓrч#ЛЉ(Rg}V3qEz 8m1В .Н#ЈaџЅj‚ь|рКњщБDэ­РЙ15њ†НЗOУтр3Ш+жGфšP” §9_Є6hvŸFЃД?ЅабЮЄ_ЫїPє‚€Ž)HШw"де+/ež•ФЂЄ 8˜ЭCы–ˆpqў§ŽŒ1В:Ш`hџ˜EдЄ%Ÿй{^)ёѕwф˜Œ:YЈжšŠ +ts•>pРмqьэ?яљФL]њкч‡3`§W*nЪC˜Ф Aƒƒs Gfuюц”УѓЃ&ќвžшЌ$#^{ЌшщWоtˆv=ž“Pœ’R‘“B7‚Џ5€‹ЉOЯ­yГзЬіХPСYGтюDНZп 7ЬDАВярха™(Сруі>Иg-yЦmZ!зДжл‚іЦZRmВОРР™TЁ…nЄо1j4№Шб~Б 3J—8F" ‹г™.­d§љ7ъМЇŠ&Ёp2cк‘A—жXЇ5ъp2Иœa“Сž@9ГJoв‚ъ(NсS)La-Z{ДгlR[H<* 8`ЁИХ Ђ'™" SР"uкфЕшѕ™ЫЗnpэ9"'Ш&Ќф“&LйK=ФЄњžФєіюK™<к—УB–ѓЛBчG  Ан+ g pБџђ,Еš‰НйСbf5^v,[ДУ)l‹CМžІХ5 ЊŽАBkБР~ж„бŠPRШ$ЄЂ‘˜`ЇV‡ЯHX,№`y!МЧiV\Яцнлд>q0pŠeлNoО^ыџЪЬ™vLАYх@Б„о+N'‘h€#GЈHУ Ќ™Р*ƒL4ўа™гЃу"wў|Ю:*-СмьсšNuСж˜еL@“!S№R…”s ъx (™ˆB,$Œк~PД.iыŽiŸWчŒ JMK—^J"“zБЗ •р-"[ЉжBЫСc0ж>l а [tћGи1O`ьЁY`ˆеj~ѕi_шцў1 c(OyјМfхщМЋ§мЃ}$.MjЬа)T ŒХZЋаYWаіБі‘}Ф 5в@Eи ье4Е~žфр#vƒы™n#Ях'ЬЙRвPi;Рoћ№єЊ%}ц˜2ˆдс8yIљ6‡єMјОwwлв:И'0Зj|QБsTмРЊ‚;†гW–™n(СТzyЮsxЯ`бfт W ‰ЃL1tPhDГЙG™Г "3т$Ђ>/љlтЅг‡Y)йЪБ}f u’ЎЁ<ѕќoћSЏ]Qњш?ђ™~^26ЁЊ=ПўЇ#Ї‹Ћ•Т~s& цкАY‡wІш$œњŒKg•Md_ЫХ%фЪћЏ•“zЭ}zј№fЎ);ПхwлМ–ЬГ&Їо8YНієс№YгтЧF:ѕ„§ьа’˜roе\F!;ъNН}_wЖV_]ЌЦ~И&ђY0O—}ћЫ}Іш€`\ƒЯVХДU†t,E]T`,д HпN0ЃSЄ%mџ~ћюу8&іџЮ–1hыn:9Yъђ2/n:Є‹›>L™д”^=xь|CшЂнАКъы›Ж­§lO>ŽЫ‚_Xѕe0ЋђPвХ3*nKЬ7ђЕi.ІЛ7l\}85‡9aьŒEЃќ]щч^L*]œœг)Т^Ѓf,)q” Ш5\]й\+дЏЬКВўX.ЫП[wSъХ$Ея№‘}К‰Іlљщd­Яи‰бЪУ.ы\DuзэVŒ]і’$ћдMЃMєжЉ›„‹Н>ѓРіЋ…ХЌa‹чLыРЊМž  ьхюТЇбшђnЁ,ъЁœТ*•жЃ!iї‡giЯLщхЩNYѓѓeF ЗцъЊŸ.ждИ.мКШKuхУЗwVUеХ/§tю3Q<6еЂШйљй;[д4ЈІЏxkBМ›aКђечЩNНкЭˆЮй„Ў(sУaCY9ЙЏфыг[ПНˆI'•й›п{mЫQ^/›ѓћ{уКв(†‹п|h?ШГxзъ?L]ќњИrжЊ›zƒЩLММwЫАQ—8wЫф{гё>НмŽŸYнђАёІPYўоЉŸ–є#хˆкМjŒвTŸю>хyхеE5- ш,К[Ј›ГЗSЫ“ЮмАŒИ›žA’ЫИЕUr3С2Ущ‘Ф"R†OaQae†ŠАZ+jDяW4 6U EzJš‰Із%2)—ЭЕчq]œLžqс>Q>|EMХъвЎ\Швuысш]•Жы8Oр.{о#gѓОпOшc󇄔f]Й™#žзПЏsѕГ{і•жћEѕ Дs*іœн} ЌAж­WOV§_їєtЉ Ÿ}gхх$лМбЮvЮ,КЬЮ1` Џмз*2Г€&s}юэIdЧС^|АЉ~П^t=kgК[›Сл8Ю `T*xtЌsQ‘ЦеиuЏvЛШhвОЦŠ,vYЙ#§ЄБ]* a(9сзБ_ІљDНДf™ЏІжбРж­6ЕQU[˜~C4q< hUUюэ;Хnp$)П™ИwХyЇ%яНбЧNWkђ(T&/XцšЦѓ™>j@OOG)xХнјлоїЙя~ъTЛя—глeЬ}{ЄЎ2џк†M МюC&<5|HВЁ №ь.yПЉЇ8•у%Б<‘Uv9ЁЦтв_Ј.]ѕ{‚lB0“M+ЩK=ОqGEдЈy‹тУƒœrNІпд:Кq{eܘчоX@ПzdѓwГХ 3ІЋе~"™9'Hv’`ЅДАZ­1rvQN1ЮG„Њ4uчЏЛ '.ўђ•Ќх_-?Ы‚їzqх‹цK_џњСžžƒќУ=лМЖоwшв-qЄфCŸ.ќJ*џ2.”S_xuчЇкЩсЭ$sАєU+R†O}}lПн5‡ъ™е+.œ\и7фЈzNўjнЙяЭјРщђЪИ2§ђЎх—Iуg,§!Ь•Wёы”хŠЉЏ|ћŒŸО ‚-уYOАm&Ц“UŠћAЅКцН“?НгwЖ›р>€ Žй;vиРѓл.РР˜_Ђ’СИЙow№Жи!В­ёŽађ™Ѕpъкпr ъер&Sх"DёvfеZжЊ[ЗвЋ™EтЁm–н#*EaaкŽУњD&№ш5rDŸ2яч-зwєО1ірф% Юѓ"ЯюCЦЯ|:”zчL}бБввЂ:§rZ Yшщюшd'бSЖ_О“_уhRŒžБЯжoj0›GПВuй('.d(€жІчеhBƒzDrИд.РжzžbEuхWŠ‘иШ}CН^ѕСщ_оьѕŒПФуо@ћЫ<ТхЗ/f"BЏэщСr ЊAБf*-C ZЉg•ЇВjВ$|6цF€aX№†–JœЈт+LB5^xfїЖЁЭ кѓ}|т' у€eGОHŒ20X$АaNЇ’€Bf~ЎЎAQ~n~MLЁ ’МбЄ3Ы“/э)Э ‚Л2ОƒШŽь/№?хрьхlЧeX0№m…9v vё˜:†е{7феыUKeыМ4™ юEСЌJЇaУMњ;OЎY}Œ=шЭЉ§Cф‚FƒТmКаmК[›ёСЋщь9}(eц§|p уЦб‘Т#Љх5u‰6нRQJsrЦ ТіooВYYr8•Ьв ўо7Р9Ž8Р7"РД)Є#1œЃКЯxЗhе;?ЮпКI6tТ’ЅcƒœЉ`оxgРlƒ=зџq,ујёe—/СLXxнgє`гH`*ебQ,w‘Wю~u5.xФы‚Ж@ч;ѕ‹qЩмœ“x>Е.'н{Bˆo€ёЫЬЫзХIШЁYйQї‰Š…v№#жXЁЭа ф4Š Р%Њš0BMИШјL&G+`]Y{HИt ДYt$OpEWoІ™ŒрFъ%5=†)ЖШЭЩеSlхKRi‚9ЊЉ7Ј•`Mљ…‹ &9TšкVp ыŽФФI^нŸ#бСЙ'зAТГjю€ЇX ˆС.ADqМ‘џDДА!/˜ЙМЖyqђlЈдшєHgN‰еЩV~О‰1|ЮЌўnт wЦ§iSЯК~šF  Ан €/б”мБЏ‡‡…cO#ЏИTm%уф›‹ ЊŸ&#EqхМ%РЧ%jА,ww„’q EoЊЏPJF‚=GKОИ4жi%54ъЋ KJR1ў xCf BЇЯY9ibъінп~Аыл €п_ ‚ЅІе˜РыŽ™ХBБ‘уЦ?Лt~„ЛбA‰dЩ€Ьf‹UжЃЉSвb† RnррpдhБыч-ЃP€ЂmА˜,LŒМќ‡™уќl2t‡/­$А…Ў‚лЫˆ€EN=јћЕ˜9„YЅхmЩ㉔ žwјЛПЬŒwEо{› D†nqА и^`џЯВ*o]ўЈч›Џџvюл\ Gw…цpтJœЙіТ#ГБJSWѓЫІпўб`ќЅЭУЦ( ;\з'ЦЛ4Ћд'Ц Ю&їMі ‡lлˆнт(ъы№ђRƒ&ёLCСw‹TœIЎдывit,а\ЫзщtрРњAEЕ<з”—f^ОrЁŽ‡€'ѓ‘бDB|wŸm“—Ч“‰kW'_ qтމ ЕПм™q!+2ВOіЅ+w`89ђо§=и€ Ж4НыІ#№p3ЌўW“)BФrЊ=ЮШДфдT)СA)“ЩАЃш]“AUgЊUXL:\е`RщєeЙрDѓкщ*‰-№№‰ь^svчЋЋ˜Ÿ”s1Еїъ‚№ЖЛШ*ЎЉ5о8p‘DПОcУŽ‹4џiАбыk rЎ-—†:$К ƒmdАС™"Ж.§ZкŽЫwМуммЛ{мњєвNђЫМP0ŸmdђН\ЌSпfў†šтЪќЄЌђВ*ЕК4§ђmƒ‡ƒдMl(ЪJО^Ц’„…K2yЄЏјъЖуŠ#‚}­nSQmЛж&Jaa9П>ЮхcУмЪNmОЊbээo/qяї|ѓя^8э#!їр\_ОYЯышСc’ъn\8—Fьь‹ѓnЩшpg=zZыB1ИaxЧЬp—­z~›ТзTUв|C}œ€ЧаAFШKцрЗПйyд‰б3V”Бiх-ЃчpЇо‰eg]Ÿ и5m•§†ЩсоьњŠ2z@”ПTvЗ@LW|j]Š(вGDЃИвиЫцэH<бї^"з6R‘-УИЙ‘уСuЫ“{oР)Ђ<\.rБулwŠ f[‚Ї›чђХ_—хUœZ{JiЌгсt lкЉ–sp7e]]PPа˜—F%ьЛz:ћ, sЖйяНgй;№ёыЗіў™}V1 ƒ†Ю1 ,*0ЎшјЉƒЧі’G=3”aч`яЬтv„Ж@цыnrамаIУЧW§xђр–+{U#Мі’‹Ь›уфсШц3h{nЅ Ѕ^Ё&‘€Ae‰П;›ДnmыМ"A#ќЏюОИu#гIпзЮ ЩУќ‹ЎюLМŽZю:"$жлННшzвЮtЖІС‘ŠNЌ:Q[UїЭЋЫЉ*“`жщыеІz‹(e*mEЅЄр‡JеоIŠaGv5Јвю1sНLџр›Ÿц_&0oє№З{…2h žTJEY їŽ|*юФ|vЩб}иИчBЪo›^ЎЈєђЫ/Al‰ЯшЇ^эе9EЦљ.нБiЭ:^нєWЇu{yъ/ьўx2рƒxїщ“ЇН:‰ЦиIШьяЉЦ†Є-Л6ў|ДŠ є”лЫЮ]В`кє…ЩЕЙ7.grЕЮ!сR2‰я““Ѓqѓ’‚Ч@pІ(zZ1ЎMБhСДф?~;ЛJЅ#“ЧіюрО\*ЦљЬKе?§АrљžЯЕJџзжOŒ Сєв•%:&pёvrЗтіB8П"РAцИШ|ЙTЋє!‰Ъt–Л1Љœ,œxj9ѓу7~ћь§jИ&Яњc•Їдž%uю #X;a9;ї—І,ћz—Ng"S_мКjhЄ$џXjЅCMќ‡е›о|{X}Єчvm№udГdFށc…?Џ]QЇв85fЬѓ"A–в:Oњ•^sЛ*?]‘dЦмсŒvš9`[Gƒ…Гx 8Ц%Мч=J“JœФ{O9Т†`ўиЌф>ŒL!q\PWеwЈŠCu‰1/ЂŸ”mы"бX<‹AЗ№…Яh(\._Ш ёtAa"g\Џ№ K‚0 Шсd‰урзоŠЉiаъРC4'ВщДач^і%1€2k-ЏUT5ќЕfŸ p’Лї=yI˜_EпјеЋŒl1Hc§јЕ~H8кfm… žК0­{&EўЅŽF;hѕ?і& Ѓ[ хhVсЪ*ЪЪ…$№PXQЪђt…%,_oCMmЅЂЁЩ~им~C€mD&H&‹рЫнjs”жЊ­ї€зDJ“Щ‚г‡єЊLр ‡Й0В™а§xжzфЦИТв…… O  ˆ%ŽQeў8Г59а(ЕКDЭ‡К(wЫъdЬEjiњ?іЎ<ŠЋkЯЌЛKмнB wзRЄЅЅо~mПКў•ЏюnаRZквZhёт$!юЎ›ЭКяЮf7 BВhићvфкœ‘sяЙчМ/Ыс™№]X”ƒн.n`™# ЇšУг…ЛЦ§їоЗХcўCwM ”•Šй(y IDATˆ‚н_V‡šˆ8žшРз„Ю ‰№эС??РUHХ™}Р‰чЏ'тdŒx~ 9Є"VY"t‰ŽMˆб>в†x6рiЧXSЇcў§!AˆšНѓ§cуB`y%TNНxІЉјэ#ыѓїЃiџe‘9tУŠ“NчH„еќ.K(Ш– ЧЁE‰bРЙ"Hџ"ЂбЎф’гэzљТЧ—•щk‚ІGЩmъžѓ Oz–йd`OЕBOžЁоИ`ž}Ic№МэљmяЮŸvMZkƒ{ŽsьO2ўŸЃ­.эвuЪ~?Џ#"JрЦЪю#]M\ИыЈіВe/iз1эыщ-ўѕьŒь‘O4zНюdџv>A'AЅп‡ъКLзБ wQВBЄ ZЬ` @вЫш—c"0Шp>=КP‚№%2{ъ]т+]] Јx{њ"‚А0ф ]EЏ;'|њ.^™&;a ЌТDбQ]‚Gx’GФщІЂuyл}ЋБ›FвbWoнu‚lЁ/M ф&Нeг}~Єџ6ыкOЗŸЫi?џWЋ,D€ј‚VT w„8 L*є}|зћрмяFЌ[Ш=Щ‹єўЉzЏБрќФgЭЮ3y4и.IŽIМ'і јuМ2н?xў^г@ќtW{Mr<нчUŽ]/žoђТнЪ^вnЯЋsОBзж`%р2Eі/1Ъ0ъ^} iфНIФuЪы;a…J(qњ&ыЅЩёxнDn_НT 7і‘YЁ™kN7ЊкЖ—ž6іЦюьЕьЌŠ•)kpeж–ZVаiTідЮЇrEQIbј‹ хљ_ЮSП'?lЄzЧdљ%:ќW{ПСЗЋШ OC4UU(Ѓ#иДi|G9-iДэ?Љ-*Q-˜cŽŽюыхд…F…HSМШ€UсqvЧЅОrтšrлžяв:*Е… ёАЖоW н…‡тg_ЕїVњ/эот ф0ьЊsЄ)6y1АМ JУСяŽhŒšлп\~љмИКТCЂё ЛџЗЭ…Яј› FŒб5­њ^Отkubk\xј6ў^]ЋŠGX=0D_•0їCk7эMѓ‰2x#ь{_А‘+*NЗс33рХV›Я HшBPfЩтшDqtзЗw)gЖћ ОvІмuЮCЇнD4Е–mQ›Ьfй\•gЊеXžЬъ:BQigtєUЎlйT J[,fг(АФ{ЙdгЋдЅJоbЙѓРCјтŒ6USS‡  ОёV‹…&ђєЖ?шЬ­iЉоВЇШ;aJЊ7sЈнw/дRКжІњъ…Xљј сZ/єшБuVV)™ю>n ЛяѓХ—7lћ#JБѕЬбœЃЮ|нtŸ ўЗжЩЌcGEЬИpGpьЖЛЏ—”:4žЃ!]Sг™mЇtЃЧNRBBh з]нэb&­К­ЊІЁО(AИnю~a~B}иpУі ^mCрь0к+њDУЙѕЙ?:ІŸбЬе6t]Ъ›ЌІ‚Юr|Zж^pЖЃPg9яkуСТД,YЪЬ—нœуuщ№p6 $6Fœ{_хz,ЏжшсЎŽtг‰…4О†Њ’VС…cе+щœЙtуЯGiЩsі“т}'ЋцдЎ§љ'ЯžоoYєЮъqYўŽШб^™ЭЅ›~§§ЌœЮ`–С pЫZКtNQнЎ"ВХ•М–вwП^3ы™дЁVlк–f5…/г)Дk*љюч_ŽфДi(ЦЖnъДх/*ИЃЧ˜ћЩ'Gуюy|y(|‰жюuCНyƒ(6ћWкњК\ќytn.Є7шzщaВў;Ц ИOЎЃNЈЁg†oCx$о]мдZM_ і`ЖoПЕU)аa~ъсsю^6ƒЊkя0Px">8_aкšК#ўZїbм+6дЄеhu “ЭФпkѓЁc[П§ѕTƒJЇдјюiЋ–/˜?ЦKа‡?XЯѕмфрђpЖЙ0ѓ[ЪbмBўэва[ y%рЪ> yХ&x<Л“/Ы3Y$ŠN’ФИ3Фн‡oв_™Т\и`–Ћ0ž;вЂД–+z%љLCƒс R"–A"ъхл;ЧџZСчЧй.+ЄJІ’СhƒЗa6མƒЕЛ6ˆЭСMwUі‰’ЪГ•••LDЃt'‚6! ШЮчъД>у“#|…4 AeК›ЙфћMG|Г–O рph!DŽB|XаOM6Ю$;м_№Of1лqНPРѓГћФ xИ:д “,ј…„чр‘€9„{В]Z>xХпќr8bЦ=г|Љt ‘`UцД†/}јЁ,]юоWюћ№Svtє›™РшўЎ р!DеЅ0 Ђ яŒЃi• …~›эєQl0щЖждЌЛяuз/мjx`|ЂМ/:ої.ŠPЙhи@FвыQ ;щe91#К:|ј€пIТ‚Еb=ЂљGgˆ,3›UЕЅЪрєЌЉО IШ6w*OАўмј[чm."ˆ'u0aXS*;\*4їЕq/xЎЫ+CАqЋ`ьРkA,ˆ=є–УчєЖЫ•ХЌm‡O*QyO76„uXфfЯˆёЩ/Œї#5oљрЛ]?ь–x,™цум oљьЃ`\9iCўіяЮlygЪЃyFќ+Ў]cжž•л•Y~М {КФёM–Ф$СВ™$FD4КGO=#oЃYf>Zb€yhˆЭA—d"ƒOw‘)dD/WDњыFvўЂ1]Kc}'`—Ћ[ъ;5:‚{x`@€‚Л}fNŸFф‹9d›AQ~Мж*–јKX4ЂОЃЙ,W)Œ№‘К3HTїџМё4жrфžEУзЈЇUc{C~+ Вpф8vю”0wrAmъ†’Ÿlў5•hiрGХC^LЦіъВтZ™оBі №хФOЇЌ+8WлjƘЉ>ё‘~>l2“—œk#ˆІцКZ,ll4R]*Ї‹9˜ЊЂМЭh$њ'Х€’„/VQ“ŸWл ц—хчЭ24TќѓоoПЯ’Цлъ=R’}9™пјЙ№=ѓšЛшлЯ^ЯЋеZm№ahЌ8!cЇЦH!ю6фЖe"ž`-РvфчЖвн8ІЖђŠNFѓO‰ єbук{шг ЂиPPщeGKы‹qј^ F@!ЃBœUlјЌ !ъ‘ЩѕфчєqХыкЪЬЋUdS”4Ю4Œb!ћДЯшuzг@а;№\Qєиq“ІЮ „Кс†˜-šš#ћўќdknЋGt‡Р=-MzЫ‚щДђŠœКќsLБwLF„”GtFƒЌЅфєщъf"[т+хŒjEKUŽЪGZЊZtМЈT}u­/&ЖзцЩйBЯЈЫ”хY[ѓЖяпМO 3’Ч‡Ф‡,›Ћ\ƒћјёй%ељ-ЭfФwvvЅЫH`ZHњъг ЕЕєрќˆ —ЩucVеgdoЦbEeO”4И{€#И2ТšY‚(šGНлчu9Уп˜ Qhј’Р•L#Bw„‡bі$І>№Aя uЊg–ЦcћОнVEcлdеmВr…45uйЃ‹у#ј…ызьfd._9Юд~ќы чШžГџГ )ŒYјч–?™ІОИPKeРЄMСє0ŸƒQnЏЄ(>Бс eХђ, gyTЫ­Э-\ŒИБ1SY–›c1’ГOяm>оьž>(`):ёЗ)Ы­щ,j№ŸћШуЏŒ“rБЪПv§Иe[ЋŠnh1yŒ›rчуГќ$HўЗŸl’I˜эu%ŒћЂН:Ољd‡1м›g(ЮЏ‘7/yц™WгИTsљцmпmнІаѓєMzяЉГю}rV|њfЁ;БЃ^Nїїѓрs{ (ћЖЗUt„>р<†ЗчьљьXPtјx*бœ§іы{RŸњп1 ŠёЬЇяnТќИђВмu•*р–љ?ГФ‹7Jg8кшu/ЛIІf&ЊeКWи.Š№ЅќјЉБ—-жз šyь,“ѕЮ-дќ‚жж§ nD„—` IчПчїŽBЅћѓŽш(oяQ&e›ЬjVyŠ8lњУYUЯГuM‘DоН.?`йЪи81РqСј…ж}[>бKЧ}4аMдœ[xh+V-аСgkжТxQBњЕЦO[Н:Q"вЉ€H„дЪcz/{фЃх?Н№т‡Gыў3Z€6}џФзгя~љЅ JљюџЎZŸ=+ЭC(4w4з!їЌ~ќСH/OіccюЅaбђG>ЦЫ>ёжў•Ob*О~№ГђлŸyїБQ–Г[юЛѕЫЄХуЇ$юіеЁEГя[Э№I€(ЖйєВ†?§БЕ=є–Чb98iТ§›ЯФWлPЃМЁUуалЈYUŸ_HсˆбЧШЃuЙыЮny"§ічъ{р?`ЭЌр?К…@ކСД &gqТ ‰щ>уњuJ>>hŒЮ KKƒj єА‰„ŒhёI‡г/,eВЇ,њяъЉQоL$Šš№Що3• Е_р№lX№€—Rš:§Ж;ђŸyс6ШФ‹Ÿ|`Zœ„мо&GЋіcм€шŒЄТJŒжJИZ“ЁЙГSп бАFцIмТ‰ БHъс&dƒBж[+nЦŠŸщЭ'зЦФ’)UZƒEпX}ЪjЦZђў:@F”0Ље˜`э`ыxѓnљŽqCДGФ›ЙВЇ,‘XЁбл ЪЪу˜5k:НijгŠЈJe$ёмм#*Vтц)Ѕƒ wRА)kЫїnњ{ћІЪЬ‡X5йbW ‚ШбS#YЈЫ0Юъv”ДъўђоОs4‰ŠzнЕ4юžпNчЗ#7•bƒћ w4"+КГUU›W zlт`„ LТ:˜d""яФ›Ž–ўеx9сCЄ"в=pox-AёЙіЙvF!™@ЧзПœJ$9 $4ZX†TБ†ќЁHBlˆ$!˜1ZXф“qћ§­бЗTJ§=­M Ъа)k.юl1ќјх+›ЕRi#ЛщД8:#Eь“БјюџЮ €чИ­йОЛjрВf”Ъіbqš,<БX,РIA(ЦжкыпuЄ5xвь9 SƒмYqpВrJ#.гђи€!™гT О$ёюaзёњњџˆ†ƒ+#LЮЂa@v;љoozє($0HЋг`b!˜!ЕТL”УДt0УIнрC™Ѕ€š žЎEмСˆ `x ‡ @л„Qq*`МTЯЛg3):­kSyВ( №ŸРšэ5;МіёMћ(„к Žјeр>mвЊеSУнСЖlВCХТЂ fд­Ацс№Ѓг#>АJ†e‚Х У0рz'˜Ž" …хte+…H :+в—‹OЈPФGТ&@ГлWy..ЫŸ‚Нl]~ MЦœчшЙ #<‚ѓŒ:ƒpWМsЦ–ъ­ŸЏнœcYњъ“KВќm@nO6›Iпн8а#hа—Bаaf@w1k@vEG‘ЁўџF™БйЏЅPIбу#лЊкѕ=_Ъ Я №1ЛX@ _Œ<Ёz‰_tА/‹<цФd 42C2XM­ъtkNclЖMСБ8gŠDPЊgњЈ)3рљƒЇ$aDС:0:8 аFрpС0˜мf`K>XРˆ-&-œ%( зн3Ф‹j)ЧЯБСn№PG'Ыњ H5˜ЭhЦLрСbtЌЊЦ?§О§Єї/№"‰œ8ЬjУIј›!хк>•Z-жPmmЈЧ$n„ˆp›˜йъъ07wBDа ХEЖ†z щEТ"ќŒг€рЊ(­Љ/k‘PКк’f бЫ‹ЯЄ“рsЏ3ўgЕЖџѕѓУвџАжьїјJИScDАюŽи4rВЕгl2ЊхJY‹B$bгЎБЃЙЙƒ іq,Б!њЮіцІ†ІцРˆJŠ)T6E–_лдЩЂ i|Pk5ЇШAьnh№yb№CИLZъЬ;яJѓPЭf­Ш@TŠX=™q­sAYœЎ!0с\І(}оНЋ“нй$“QcсC š‰ЪЁДхT7З{ЙѓЈDЭЙ5?|њЩОхыПЫ$еез"Dއж. ЭЕuJF@˜И:p 8ОPP-‘)­­ђіqЃДххЕ3Ec‡)„є†RlpsЛ <34O~єј(— RФSу ­n;% бu. аPМ—JnСЉ С]Qkв:-во|љ№ЧдЂlkЌm$z&y ЋOM[ЭЯЙMK}$ŽKаb&‡Yz 6•!qѓгeЗ—3у—gˆIV­EнКЦ;|qWЋЮ•…ЬD:Q]вRwЂЎ3Я!Ы~пНџЃm”‰“УC„ЪІк•+јИ™о•”Р” д§еЇъ•-[Šїƒ’0џеdИЖ№Wг“›ГlAОmэZДЈœ`Оѓ6+™ŠіоЅPа5пЁ…eфѓЋЌ™cј$ТX{NюўѕФцО,яАк;bfVЈK%в4`†' feу??ќVЫŒ_ѕ+c%k_јшаял‚ќФ‰>4T]А§аЙГЇtЦŽ‚} е™K3ƒќ…ЊВул1&-I `Y ]ўЙ§ПjѓёЩ Ч/\ч1:жђъёэl–лцFћY " ?•Юц1P2JѕŠ^9Т7›п`­іїbšдŠр…ЗŒcїЮ _иоЛP–eIХ-юЎХПиј§ї–2?)UЏь _vћш Іwz‚щ•§ў`œД|A”{Ч‘5Чщtz[іюŸOСфУмвю~0\Jфy;7 {јљt x5иtрЅГ†ˆ4ЄёŸУлнЕ^~ДЪн›YГЮу6<сwqx:бЛ”ˆ†Ѕ„€\|Ѓ|Їе„NЃјтћ&yыЋлZe-L&B+РyŒDўfр$У”JЕеhygХћћѕЯGћI—ўїю <@ c2х~ќц#!(ІWtaТВзоŒ›–оёьзЯ/;Бќэ—"СuГ­ ?о• Ё•ІчЈД7ўИсЭ‡І­ž&Ÿятзž ш•šћ„“eяћр9iTŒФћьЮЯ_3˜–.\‘ждажкЁ—э=јЮ™\A„Бѓю]ДxQ№ wG/щ ВМВw&Ь}iџ—[Kfј%КБРЊ|-гаС\Ы^оu•Ykš\aНLYQЎДž‹w›<aƒLU^ЎЪ;€P€ ‚=*ˆC55жXС‹оA7ѓ5†ц6•Ц*H\ВtJX0‡D.}h%§ЗуГйЪdQ7ЕЋДмє)БГE^+зk-јw…С`‚‘Ї!zŽЩJГTЗt*хі1= ™mhрЬUГkџjЊЏShLЦђ›0-УннСkЪ J™qЋо'dЄќя~Jќї;їЗVœУШj>S іЮ ѕїо…ВsVшн™№Э ŽyяrвšЪZ(‡GœBцн;ЗіYEЕR§dD,›LСрˆ†%{ЂАй,&Уn]#Lž56H БpЦЊEјSЃйYё#й;уБWљ‚оО6ЇqуяедєвK/НќђЫїўп=їПtпедsQY‹Аа`Љsа}ЃБ–еZ”WD"CDЁ0W P? œ­V „DЦFtДuОАђџ(tЪ[МvQгНvaje”цWЗZpт?ИSU˜$0Ъ;ђВ‹є&rшИбb‚ІНІб" є‘PСдмYп‪ЦЙб p_ЕE5Еz+Bтzˆ‚т"Y6uOfш–YЃъйэПlDbƒ`h,Џ­*ofyњFzГfSMЛЎЌ§(|я`oXИu%g%№EіЏkrтмBŸЮМУй2і|}ђБ™Ќц‚ЮВџ1}Цєлw|Жэ“ŒщƒЫ™љиЫo›Iѕ2:†-škqŒНwХгЦЭФFJУЯ5Эž~_Щ%Wd)ќlЭЇmон;-䈓A%˜aБ ОD`ФЙ=‘LœGчДѓ’Р+ФОKЄ #m_‘УЋ- „а"P€WТZ шэЋaŽЦЭ@uBP›н‡лэl‚@W€(BD’§”ƒЫcЁWА4†’В1иЙ aќо•В_Tœа DїA‚ВРzET„ЁП`a‚U{hк…у=,ЦŽО™єvЖHЬ)`ž‚k‡њ б`Рѕ—сЯQГ~YёСOw'(@3 н*ФўФ;ђљиЎLЋАq65"™y9ЅѓwШЃЗhыыx‚ўCP"™ц—юуИ‰іџЄ_LЁ{ц4ИuАъьиоQ"Иё№Џ$0и FёgЂP‚’Ч…$уzкЕт7ў|f8FaпАЌ aјEDљGDA87б$ щѕhаіїмєКз&.[cІŸj,Ьm)Эn(HёŠКЁИр?Ў@hУ\$yєY rofL<йS˜Нv…V Ы=wVСЗŸХ?!§%”хцчOцШРF , 0€PyП:’<>zъАѓі„e`ЏpІžLˆБ­W=чOCCzЛЏ‰уГж›]4hЏС_`ёЙS•cяЬаЯоЛPЖЈ ”XQ(kхhX‹uікьмЫV#žЁДРнѕ@§кnH‚8&-XB1Ђœ92ћ(:T‡nPУехд’“b€qSџ9ybоы?НBТнˆH@žй§МžЯ №=Њ§™юižoЧ ЯŒЛ™рНdшЩ zя\МЗzъъRb=вИВ .uKєT ГG“tфWo6ЖQе’[‚OFеŒўcAoј`Ў8хЛр?Ўьv8SЪБАtЙœ}~7Шd$=46fQ0ЃТ_ЯоЛ№ЅЅ‘Вв`RcS˜~ѕoђ J'ŽYe$№ИрО?œjИbчmkЮчМT—–НєШЅЅњиВх‡ЧРŽ^ЏOпcЧ*pМ‚…>RіVeCXл=Щ эЪЌЊЈНЊY-ыЉŒL  Н#Фaт€ЁЯЏŸўzьЇ?ФЬpiЕ ѕ†МEynoeV|ЂnГij"Gеб њ ш‚Ёi:A2Q*rы"3‚ъ fб jDЂ9‘BІБid№Pя;aЊњЦІЧЯлSH1k &“ЪЁ;ѓћ.с:zHРЅиКoМ"= ИнЧњќЕщ0Нв аѕOyƒъ0XˆsјХт† №0Т}ЇњHаД w"X–ЕжкVDрщэюHЎ4hбtxsм њ\kљƒПбг$,Й… }УФўст€`їП‘  чZFР†^cаДhcМШІ-)„б;љ+6~ѕ18Іѓ%PJaЁ!ГЇЯЉ(ЌpтJ!€:яФсТv™ŠYQл;6&*Ю€љћLZлінzV|чЂљBnkўщМ*]Тє,7О иЬ I_П,.Хж%ћVyыЪЇV:@gњПlgБtЙ~ХР 5‡мzNŽ‚eЈ P&+zъќЩЉ—€Z•ѕUй›RfЮ#TцmњЯšъЇŸћhЁ_џнpН 4ЈZafг2А4vъU=UСЇ Јк"%AbО'„Лѕœrm\_ €1H"š ЦЦšfЅЮГвЄ+Љiіё˜8˜{IИЕаNФ9P?1eйЙь§ЇєоQ~hKхЙŠЛKgпЗdўД ъ…ES{q‰: в1ЃAІRtš И˜ЁББЖD6ЁЫx ‘^`œДЋC<ПяъМЁв~ŽУŸ+ З\Š­KтV›­гдцП_<Уaѓ!Єы ‡8CќЩФџСSLDF“ўЌ^3—›QоZКзqnЦŒ‰ \#щ œ„АЏdюWэ?*ѓš8 ZЁ[Ј>ЉЫй— ЎцD1ЮЈБЂЖЊbYЕкxоq™Me†‹ќУФ~ћЊ€ЗЕе‹#–u5mЙЪдLя̘'0ЖDЬђЗњI‘сэ'…рM1›х|шЏЭh  ХЁS&M F‹Зoќy]IUNvRЩ QДЊt3‰ЩdЛqйlќѓˆВ‡S`QЧ'fљšE\Кіr…МUmТCШРдHаыL(ХЇ’ьЌвf•R­А*Bз\ix%рRlчх #> ѕвЂяbЪшжЧ3є`›ДjбІэ4œаTКе}ІŒazЕЦ !§'ˆдчђGпrыЊ^іŒ€Jш'6‹€трM€С!Ь џЎ :aХКї1 ВСˆЬ•Ф.Х†/ ˜ @Xa€#њЊФR” МY8W/Pй†)psXMГ /… щ€сfØэ”sР…kЦЈсМjХ &3Тл№вјИ“ˆП+tƒq/ФІлШLш †m0—т5а дZF+ ˆ.Аž­@E ПћqшЋН8ŒTIt№?Еaѕ/ЋЁ9kЕYСнзdэе%Вj„Кv'> ЋeАf.іїтJ‡УDўЯ§ѓщЮђЃуќ“{v—p§о`š#*жЈФБсžпОЌМ‰„ФE„Џ\zЋГ]D‹)ѕ№ уSЃёZ1ƒЭавTs№шољr-Mь3vТИёQюR|ЭŸvсU[еЭu•:~?ЌВi+Ъo?АїxЅжсEЁK_žL8З+Лнkъ’Ь/бf*й§Чб6ŸЩs“§<˜чп;gЛшЪwUp)Ж Ф'жЃe‹ќžИпЇДє­_7ЯЗˆ6DHFц&оЁN%;єEXОЖКЪRЃCp=д‚№ ЧЅcŸяЁб47ьјфыOО=FАб>хŽїя˜œ*VVяџvЋfвЊ•унzU˜Чк†SЧzяЇЧыxс1гяZ>wF˜ќа–Н'•aГцOяœЅjџ_{NvOš16=ѕлї?ЎнUPХKš;gхѓЂƒЕ{џ>]ЋG,凋ФYsW=1[мх2†™;›O§ђн†oїжћФЅ… $ьЬ;ŒN­љјЦЇЪп§WЧтїŸA=Жічя9б&S‹гЇоўш­IžlЊ)їѓO2RfЭKё–аeЧ6Д“Иріqq!ЬМЯ?>dt™Њvќ‘]_CŸєФЗЏЮє’аэюdН.nШ6-VK…МоюЪX]кQcДœˆќpILЮ@™ЙБE—v!@р5)hєюŠуйітИ{.Эр:rн%@АYЉF5ХЈ+ˆ^Ћ‘КЙ-Нї0Ez ЙЮї Ќ‡fVV[WEЉЫл]*kІХ‰(е[Зџ§Э9JZђ”Ѕyъи—›ДrtЩ=‘НЊХ”UЅgO)‚&scШіОЙvKvЇяьŒєXЉEM9š.ћзнЂˆ7)›ЎЌмў§acцb"'“vЅa–€KБ] pАA`ъc0Т\ЧЬХќЧъќ•„…Т0PљzPмЦZZŠ(y оєГƒы?Y њжŠВТГ№Lf№%ў0лЛ‡zwзцХ%LhъwoЫ)аzŒq'ќpнšП["ўћі}žђп>иіћ7 с‹syП§|B9gљЊ…“ТY=wлІЪўфЧЕя”ћоџьЫtТ^7ˆЬez E‹Њсш;oх№ižQГя|уН4–ЛgТlŽJ­ыь$PIЃЙZІC88јv‘ЄMЋЎ­*Эђ|ьЋХБ”(щЂђк/ [OъЅ3n”_Щњт“ЯШЋK0.7q^0‹абЃЅ||&(‘PЂ0mХ8kJnRžЇ„{ЩmUФgбy,ЯЌVXŠ;Џ‚мјL*Ј)"ї$,ЕсJ‹Heрdˆ№ZC‚5|ЫБYlњМ­1ˆЧbи­ЏP#\vрЋНиU§w1ќдnOАЮŒИ2ƒ53‘? њy)г/bк` јkСюлуg_EMЎЂз^y„‹ _И%кзxBCV?њИ—9PЄѕљЮР(ˆчсš5v\Всщ6ЕЁ4д ‘Ыл;ѕОlšA%г+ѕpЅЁч_Œѓг‰K Јjф*…QТЂaF‹ шќєф™џќ}§__UWзиодгŽзЅWQзцpHр’/оp4zƒЖvBЂŒ=ЛюБЄ„Dt|‘ d}uяY,~b–Ў4Пэи~[xЈЯЈЩНБыћоџЅ€+и4ЛС!-yсоПwц(п>ёkVПэ­Я9‡Я4№яsз'кОсиЦзч ˆЁЁК^!`э:•†BŸВgЪшРэUGП^{š&Ž1=ЪŸƒuЂ€‚’2gСЊчяO fq4dЋh.Њ€[ўаЮŒnи˜Нё/r8Ъъђ…(§–4/ЙˆЋЭ˜cрTвА ~§dЈЅѓЧmќ}ыкжв€ YEНbRT˜„•6oмЁ7fЬО/9о—]щ:HРЅиК„N&‘ќСцЃдBMqk[+•F– !ЩрYLj9июЌz ЊжXсЋ]WcEРѓјvш |ФТЌ);|TбZ|р—"ЋЛЖTЮ’АШ S)ћ6Сѕ ЧNџђщ&оЪXйЁ?+ ај)оB*•ш—&=ЙqOgZXЬ„xИiJ|ЧDФ–МЖџ'ыЊлbYЈу‰ќ"ќСзё‚tw†$і^ќчоŸžџ<;ЈГќD^~БtŒCЛі*BёŽ˜јЭц§;ЄD_ьЬњ_ЭЖИ„аƒ@&skr Nьa4юџscc“8бa—$в‘ъovюЂ3Œ“Нšї§zжФ[”.\dgэюЧ@ПOюњАNйм“ы"ј'1‹{Š;ПЪljPкŽђ#ksўxyќ} ъœ/ыЪ9Tшq`ЅЇЂ‰о= %0QЅ"*’VУD1N{бчќъЂс1I4НЛ„жхэчIЌа‰YsЩфгЇЪхMr„’199-#„E" Уу’i:w70Jл| Ѕ0o_€IXЇ‹фэ$‚œЊЁ"з?žN§У/3+вKЪpтqQп\ЛзF.Хж%G _К§УэŠХћЯ~h&›С“]eVлt*№Ї7Ж7Јuэ˜N & 6•ЊЏ(g€ыї $:SHч_:&БщуЧ<ЗщеЅA^c_Н5џы#НwфОќЅ .фФKumЃї”дЛзXзПјщ{Ћџ$xФNјо% Ѓй`;Dи!гSгѕос‰‘BЛъЂЧE|ѓН_?|oЋЅ„ŒПЭ­Љёb #Йу–˜иіЮзhжЌ%ћцTzБaiEGшёœђm›NџЊ`‡…Џ>=1нœVњдЏ§ ?ЉО'@K"QЇ…ЄЧHƒож0`Љk’aQдЄcѕЙ`У|UWаŒн4ˆ†,$Пєе 0ђƒ1ЎИTШšbЪжWUPЙ<ќѓlахЪf™Іїз A’tЫ›c ˆги8J ˆ#3љiТ#ˆш8аірэ`„‚ˆЗКr C’–voУ—{в”чЗЯА"FˆmƒЙP кGЄ?lЬяƒБ*pЫ9ЦЈV„:щюз'н М9ХLˆ Й"l&,€ЯЫEšХІЌUšЩ^ў{/гЂ)кКNe1{x№ЉjЪпƒГ{8ШzlУ}і+Я~Хކ4„ЧvdХШ|їїt№ƒЄ +B\Wа$,mЈtЬєGяšьЃUр<ЛыdВКьЙ7&=єќоЯкДrˆ­^9˜ЎЖЭ•БГ>9љѓ†ќIž‘,ЪU­л WЏGr;\1;4гЏ,Л5ёзC)нƒK щ4Ш™BF`d 3"•F‚gгОа“,%dƒKЃУ‚БН^|‰ ЯмЧ6dЃ0Xг‘п1љГш:ФаЌiў—.lї4хкr Ил"†ЇSз› УF]Ko/ЕўНЮR[@ 342•ы]ФіоQ…>Aб‹w€ќЩи‹>Эq8Ÿ@9СЬыЂьƒW&9TнхЁz—В!8i!фЗГєžWNPЙЁЛHwУАpр`б…:Žз дъ…1нyKуп;зm8" ідее–ЕxЯXтЧ›hoB{nœЗї€+/FXbs0ъьншІA)“•ЄEДV0яuч{мгђ`684жгwє>аўЛэЖxРfО”цЗЗъ$ИўџrnчъФљУзАЋЅО$XўBONтєˆОNтЧё€D&v?љ—ЫеuМЯlнЛд˜#kїA|ЏїvЏнѓљQКhкm YžюvŸ/GЎџЏƒ\Š­ЁУhLЏ“ +^ЂьGJlыЈ™Ѓr&Ъ.У'лpЖзыqў•шЇTЏќ§фъ9хL”€;м?.БІМMmIю б@—[ ИL.mˆёђ]Яb‰|YЎRЉu]ŽGќXкЪз­/wЖhrPjЯuУЦ sŸк§соЪьёў)О= -КšшO”JПФЎоЋРЕzъzU9ИM"SрХГƒчuЯ&W+їЕ‘РШUlxPжх ьœN`ё`~Sќd,~:О›уpгмП9aЯ/*1( Œ{р†O/Їеu™Bп@Б7|ђЈIР=I ?Яојнй-b&?о=l зь<kMЩјЋєрк3ўoТ./’k&йСWЄъа”ЉВлњ. œWˆд3Ќ ­яLC}жœbъ~мьѕLХ†™mхЙЕ—ЛЗр~эmƒрЋС%#˜ј._jыW•^Офu9quрдCх•їLЉзDA^дƒLП„6mЧя…џ|x|У+уяѓхy\”aшvDL8Z— 1р`–œ8zшrемПTэš’У5щщЩŽX”K2Ѓ2ЙЂЮжьŒbУ'vИЙgэJЫ /0nsя9Y№cpдqv/ЕQ@qp‡ь]ЊЛFзяѕ”РTlр\–][И %сЮK€FJАoр&@ј4  и›’]Wйь~§Ес[vюо>ЫйЌ“Юˆ PІA€ ‘в@eиg^зСAK`aф$ N;R{іЭУпН6сAcи€ƒnЌW™К2n&(дŸЯэх TНNК6‡O№т љќiщЁGПНhєŠ….іk Я<\|Ь‰YеUUrŽ`ПШ bыЌЌh”YxA^Ђ.Ќ‹JV‘_ቹƒb€Њ СŒ-E••х­FXыУl€‹ќ€s”ёLŠ №и=(hм•eX$0›йhйѕх‘ЕпП‰•nГ’тємƒЛAŸє=ќЯ`2FЅŒyў…Зјђж% ањmЅUmZИ`‘ˆTЖTьц.РзЇћH˜ЖЁёдЧе“ц$ ЬZU[MЋMьС}фuК" м›ДPІUNџ[GО{yм} rЎЈšAэ]• 4Є?хяŠэA—wИvАtжўўкхнFћЪƒ…-›1žх\;ЖіТь]ыіg/Y5ХпN–ВœSЮЊC–Иu+6›Ќ№фЮЯ7х!q Z<5еˆ™:ыы‹Žjˆ$SSaE9е;к›+ šUцщухЭw)6ч„?LЙF bЩQЬЈ“ППDЫін0nзџ-ZBЅ3вЦB šЇ›xдЈ1T{$Ъ@2ЦŒЊЖƒяОЛUхТУM­$џидЅѓчfzєŸ‚щъВзќY'I™“ШSж”§ѓсFѕЌ‡œ=рМp ^ИЮwK8ЌO[ N’ЕŠf˜B=™~;ŒžЛOэяЊ„9Oьњ`ѕЉё)СBŸЁmЬU{П Бм(7ˆaСLf РM&:ЩдхЂпoСž“VМ­0ЇИˆ"ѕђ,‰XSГZо)SjьlЂ 3tЯ=Б?Џ1%ХN )4їˆ№tŽ;ДvƒуљŒБIЃЂ"љА:! в]ў=ТН16FІbйBŒeqд6К€ЭaMXp‡D*xђЭџу pкT'…™-к† mифЌёьЪCЛwmк˜[ЮLпЙJJB Vр.У‡бf#тqo6Т‹ѓ'ˆЅ2yоaС*ЗЎр'мNo%zLЁF0ЬcVАh8Ќј`ЗЬEЂЫr9РШЇ2яxсŸOs[JС—АЏ(pN{АХГCГў(оX$ЏOzшеъЊц %€;hМJії нtOсœЉЇ<Є’фХЅЛЖ№Œё˜Уя0XЏшqћаж•œUмbCm†šœТЊкA[ру+єёƒњ>LOV`|dl’и>ЦНЌ;Б3qх Œ\Х†’к„щD:“LЁ…'eP‰Жѕ­ЅS!—}ыЌщЮŠАшдˆ1щSцћЧ'{Xю~їЏ†NMhS”цф•w6БWbbl˜нa™З:‚БQЊP<)ЭъАCq”ЌН4ЗŒšЃ!№ŒKуЫŠЊ-ю‘A\<ьZЋl(­TP|cЃ„ƒy=Нˆ–Я%|<§ЖџјfOх )K834sx.pnјИУЕg€Йл†ЇEW+—J^@вgRШ§oQ˜•5r­Ž^s~ђPЊмРА?Jgу‘§јK'ueлДщЋŽV4уV,vЏ?Оc{щЙc5QС‘tm_†€Хt…‚яx`с#SWКё$рќУpуѕНп‘-КёЧяI>љЌZбёх wїюs &“Ng2шƒ\є‚Ub0MДэ-ЕGP*ЭІЉнВєЙ—ялS/г)jЯ­џЯыНzZ}СnюаэoМЗсX;‚˜хy?.}ю­Ї7зЪ5ђŽцКЖNYЫ‰ѕп|ќвжf€пЗъыOўњЉ/rЊqј(WrF€z|ЪbШЙ!o;Фn;Sфъѓ4хэёs @§7ўхсW/ŽыT0СГ8Т[byKуx+’„SтЄ6йŠJv4ћ“Г Py˜^a™+LŠцзn9pd_Й0УЛП…fyC~N‘žУ‰ШŒIH ‘л ЮžkшФщЛ“kќй-‰ѕwФЮиЬ$ціЬŸЩtO ўяљ<кЄЃYЦ*Рцw.A^ЋU“ћщšЗЯ*ЪNiZeв%Џfи*s~јсŸ_ЧпУч њ[-z`hВщее'vT(вž}zеВx.3ъЭLгšљл—GЭžщЃ*?œSm ]™ŽƒPЙ’“Hѕ‰mгvў|nЧ''~ўПqїŒЄ“Џ&[’gDœ[(XA‹9ЭWSЋьK ѕјоД’\DdгP5 ­t”AЖš§=UЇХŠ2НтG-ДU”ўqlл?F?…S2XZАДц•–•щ)Q-gѓѕђ&3ЋЃВЌ$ПЈ# нНЏХѕA5ыЪheLVѓлGжЕk;UіŠ3ƒ  4вєаљИЏИWСЫI M‹§xЮњKђSђs!ЖЗЪFFm8?›нHxЙR—‡Ё'†Q|SSg, '4иљїйКN;+Иd—v˜y~aО­RGрј…{гeuХйхмщJџ Œи)СfЊнЉcљ˜ѕgэђт_н IDATMУŠŸ}ыC{pІH‘9wЦ‚Хd I%[LŠVЬ:“€йЩ‚ƒ&кƒa.Йс№€Qою#‚йLј›„ƒDт0dБЏџиЉЌљњ;›W*МkAБsЅСI`uт/=Р ˆШzЉ&м§o„HcJ=ƒ|ыly}‹яы“МYˆRЁуњysт€фTПз_лsР~ы= ^з \бљK9‰тЧ,qп Њжї§јLцpdЈЏkvXжіМƒˆЛЮ6ˆiЈ{u“дO%М •L##L BЃ L*J%йшрNтtТ—щD(‡?*,ŸЈŒХѓjšЭ,“ŠШЋ›Ќ aьјQЁž‡0›”<*ЋДщ˜КЙQi ц@"ƒ/іaP]Ќ4N |ј3ŽXХFВщ ^01мQ?и№СsD"Ю№М^$ќізЭ8‰“ w{ЂY,@ŸлэB ѓƒ’я}сgŸМvџЃ‘}ЦЌzaЉ‡ ‡щ˜ц@нСЇfŽmУwTњ/6Ќ§ъЋ'gmbйžY­НCІЛ…†]^žKœ8/Xжœь‘+лE€YкSЋžпћ)Ьлжфќ1 д"9Rщ~JX[щ-kзwˆщТ‹Кфк `ˆСh$›ЕЫG `Ю„Gии'M0‚„M!.—)Рћп‰І‰вј1}-\ODШдм““<СoQSƒМXJє”eТpo2Ќ"8ъЂёт'McЊЙ>l‡г/,ыжхІcз‰]Y†[#SБйЌ`љ#піF zsYiŸОхxрЩЊ”`ъ&AгћвFщBЏYП7‘зл1%1Й1+–О˜ааbА‘ЈтР ?њ!Б‹о~С*p‡Ж^л(E ‰ЛыЖgВ2‰Щ—КIˆ˜оJвИKц‹&tЈ.ї_{‘ŸL_ѕђў/!€ZТЬ‹?д—"1rTй­œщ[Й_П›њЬP7чЊ$Ђfд\PZюzЉ@Ќ6k^q!УЧёj]zОї/0LЋ К@b•š’†ё“F‹Усу”Ѓ1&x -іќУ;,У{.іън„kћ:K`*6 <џЉЩџ{х„ˆ['ˆЖнr—™žтЭПэЁБ) Ÿšъ„рQ™"ŽР]#ёр|B),пјФ 33"N–†o,iјCh ж{J’ш|пXO,D”тќёžm3i*Ю§v–=ёЉ,щ Ічћркъ-@зCЃ—Оє‡Л`lŒOlяГCБнњ} /бmG§СEгGI†МЙЁИ„W<1;ar(˜O,Н{]ƒPФ–њ;5{НuaИЖu›dњRWA{у№|Нкumо€Š x–нƒDуяu9q‰D‘'яМuёrљьЧс™юыМ}p‡ŸfЮЎd_VыВ^єоЦ3uN№‘`wnTфxлЃЋ’Ї{XЯдnЩ ЯoВgфŠИыsџў"ћW!ƒ БnCкЎYfhUјДџ/чгЭSОWЩ!mЮU9ƒC‹H С‡/“рЅƒ i'пыЫдс:сЛ=ћeᆙОумтЁkЫU3АvДTt4ДI†L"йl6ѓ…E—FCІs^fьVkВ+со'А|аН{хП(6‰ЏD\ƒКЎМЎ’ИF bhoŸиD"ѕsiC_ўЪЌыўРuнћ0Т:xџЄ.ћП§_РЛGз?ŸЕ8†юЧИ%LёЮмUшЭГ_~˜іТа5фЊYбЎЎ:^ŸаЁ‘Ÿ(=!d F‡:x_Лflr•ВЖА1lLР@ВВi;:;š;ѕ&X‡хrІаMШbSЕu ‚ŸЗУ0@)‡&Г)kъ•([ьЮІQ†<цфтЎИі/”РОѓ64|{рђ‹™аз_Гу% Eх §{~uЩ‰KрЯЋЭhСрbУбvO0З”^_KЬfБТи‘H!98Ihзjw’Ўдc1ЗЈ;Oї9зяHxкžJ_ѕмоOЙэЫгП?8ъ–!hф|•OХо}И9{OубЃ-9in‰чOИЖЎЉtjƒЂYыПиѓјбƒ9†ƒn8VdJPJIIIii™@ №ѓі?XXуD›жі‚œ=;ЯЖЃl†FЅЗЄщiщbƒЅƒžмыrƒ…ЬфбЩ@ˆ…XЊўўѓ8=~ць$oшП]qe" Œ@Х’-Ф XЫžв_шН.‰l‰чў55L1ЃВѕРgkѓ™щї=ХЦ)—0ЃЂѕШ'?ДЅЎИu"ИѕCТ,ъŽЂЛwWЇЏ^6&‚…bІЖвќП>оеDЅRa Тр I!кЬƒч5ўЁ…бnƒˆ$Ј‡Ўѓ}KјЕŸЮXлРИ ‹Ѓ&їяZ•2DїGЎx7я›џљlЫ”/)D—“ыЕы%uР;+SЗЏ?ДюhнAЊˆP 9ёбQй­ЗѓЭ‚ЪЪJ­VыээFg’ЖОЊВМž=Ц‡l)>|њlƒ$tїŸтGВ›(г\TРс њэ+а2>dЯ/p„mp„ЧfЙЖќНџ('dRVЄPPP €УA 'иФрУUgЕ#єњH††ьqš*8uM ЁЮ\јЭ“gd*6ќўaHKЇњ–ПˆіЧЩюЅˆ`РЖщNgЩи ЋQпtpѓ–МЃ|џР;fyУ ШЛџ9%]аMП)ъKї}ѕо/…ОeќшФ№14№ћЇ3„ўnJF%{їw&Я[FЖ TA†'镆CО<АIŒфцЂНn,QІ_ТаЕКZїюЯщ‹GйDьrЦ`}­Ет№іVџчюžйбђйЉc_]А8РУeoєs8„–ХNoгЪєЭУпўoТ [šєxЬъ§'4Ÿ<аtrЌЧeё†Іё›ЄVдCрqGњНЭVЃЏ­jЉњ~яїmк–ТЖs­žьPчє>ФДЈВвМЮуM5VЯiїЇŠЃšЊВ†vKˆ_Цтд?šЩ‹˜ЊЂІЎTІNХ2Р~эr›Ф6 Ь№ЊШУзŸ.тz†ЅЦy2 D#аjЃ6`ѓРяФ"ƒтІЭ—‘ш.ЗцmоRЉвъ Вгѕjп[вгЇ${pVлц}ћ0МfWКЦБ36BЈ5zњЖьшЏugЉJ‰с ‡пr4ьБгƒ!дceMxфѕ с—П+ыдwУˆc6ƒОёјоmJВдЪцEЌєшPќs,_щфл5ЈnИ2_Б ь #ј^ оо9њ=№З]qU§гџ‰Z yо8ћLнњЯь:{e a4_ƒO29хіДл[tѕŸžysoУ6"ћсјКm9лœЌЌtOџф9гІLM mmz†ZMFЋ•&b D А-гљ|bЖЭр Ш|‹V0Ђ ё`–бmdАƒIDЛВuf‘Hшяя'цаЉd E|ЯLz+*№тr˜42‘Ec‚s5^ТЩnЛВ9/;cгЃŒ{i?Б˜4> •rP ya.*``<в`П8jВБМbјfбю[џеЌВ№Бщ:›Žmмlаџ§СкlЂЂЅ д с§ЕэмЬј —ХмљGprRI”'3nўŸOЫ;ъ>?Йёсдe ?э. šЕЙzWЉВлВ+ЙЁhхцЌгqУP %™Ш У/EF[xЃйj5“љJЙіћыœїˆ3ТCerнC"ЦfИiфіюнКЧ›3+ƒЫЇ"чj[Jk•оQ,e]ЙМNСђŒfвQˆxSЋLJNY_vц№щГа Š­Г@ІRšmžŒ‹Ÿ'` €y|–œІИq\% ,Ў;ЩPД-'Яƒ-ЕTŸкОЛЅ –*FььТ™{1DyFЌbГ™tѕы–Р0‹ оЛЈ§!7["цхсОхїMƒІ“@ЁљІЭ~lщ_ЯН§C>O8s˜!eЙлO{-љєс)ХСlЊ1ЇжЏ9А§pСъд$+иAˆюFЪЪЃБŸЮИу…}ŸŸh8'ЮпіЩЁшŒоŸO|pХОЧж–ќ6ЧoЂЫc(ZЙYыФu8u˜,&Ће ЪЩЈЖЩ*MrBЃœЏ’ъУЦ„Ѕ9)˜БYЬ oP–O`цќБЭ5?љіo!kaФшЄђпВї|ё]C ЗГЊT†yŽN‹“В)эb)И9ZїsЛк\к 7‹ь1йDqDЈ~лЉ?П0WЯŽ”ВХ|Тx/`лd+‡љzŽ‚С‘$і>/cыю’}ыл™,•В^n4QоЯ‘ЩЩЮЛВ9#ћ§%PСЫПcqш0c“А—0r<Ц'ѕ ;#§&šэ0$ЮџГw№Q]|х\s–ЛИ#мн)квBBЉ+-VЃBЏёQ(P(ю^ И‚ˆЛ_Юяvї{{—@А8’п•ЬЮОy3ѓпыО{3OІ}3rл;ђHФ‚Xtк„џYњ бХЇ­C(sпœ{`жсЃЧ’#žѓЇ†бПвhЗІ< ИKеяt˜јЭб?Ж_?a${ј=–cАeш0я^›“їyaЩђЮ_< os уЈк\ўuWИOэњХAВщqљ'‡†l%яp95О‹EхA-"ЙFW5‚sЙДhнї“єH!сљїш<ŒЫ:{6Б #%ЭЂ{Жюи%PШba‘‘]ГŒЏфXљ-њz+\ЋїшкП_Ц‘Ќ\AB sюй‘ч/ТKsƒ:зпIDП`Х>-њLtёї–r8ВЖ/Ž–†ЦнМ‹Й{ вvЧ]Еpy,:хSъF+и(‹^~rќА*%› 2Lрї“‹‹kчпWTCТsoŽ{9Ь pžЦтъЗ’f є6ƒAЫыџЩ5n)•\Ёwxдшn))Х:h7]Œ+Rљ‡ЉeŒhЋр*Lэ?%r8Xџџqa dqkЁiі8†|ЇХфƒ'cВЯэOщх§8†h‚00чV>,8ш€ЈР^~О‘^яƒ+bЛњW'5Šsy|.mГ|@O›˜чЈƒœуKрCoЕ”Еи)pDЬ—аДЁЫ[`?"’Ыш<мі‚ E№sжЮaWЈƒАsэС6фнШJKХЈтbN‹QЏєът+e~ј–CXoЁ`л%Зѕп[y^Ёе:ќ€А:D[l6іГЃХŒhЫjхМЭˆ”–_СWКkjЌrЇ;SyL@„­l]ўЩДЫп[ёeiNќњЯu2кЏџЦЄ= E7—%ЌyЛХKi!M‹-Š Ѕ<яpЗGЎ6(с8НкХ!фыmqTќЗВo•ѓЧнzuмFo2УY*r’I!P ­ћ1Ѕžh„‚Эe}w@х8СїЬ\.Ÿ*Їdю6>р85ъЙCЩ‚”љ1+fw{ Ь&ыw™рc№YФєБgЌМБiЈw/‰G§ђoЂмр€о|† G*S‹Ѕ9‡ТOlZ§cJ§#а8,˜38UіaЄZ§—ž%Žр@є^є jЁ<Љ(cсЉЕ$ЎЖžK EрhпўVв6яТтzfЭА{– ­_ь…‘jя16B РЂ,TмЉАnїVBСЗпŽ`йо8‡Ы nэKтѕџ.{|Я‰с\яHИТ;ПєйСХч2ўŠн1ЉерzbFи‹{гЮнzЄŸg—zчџXъДњЂќЂњl­’6o/Йr<œСИТbБ\.K Twьрк­s}Т№yІ0‚1C=•F(иР&јъ‰[Х— Чи,6h§Vœs•I5Ј`у5єvГ(яЊ0„Ў(Jт˜cуф%D€˜9UuЋъ>Э#qu@g­`Ъ“CРUЌzЏуѓ_љ}OтqpшP]GЈjNй‰+~ЗХфЯЯ§єэЅ_;ЛD й`#ў иG…Y~8іЃ†˜ыЯ{bfŒg‡:RЧљ6BС)фўyњїПОЯзцяНДKРі ЮуђЌіxєІЯ>џЖ‚ !,ІЌјЋйdЪbI4Ўžю vYhџъ#OK2„ Q(ћжЏЅД8ыVщьыуњlМщЊПдgŽ2Xхћz›Q‹NЏ[Л]%”GКзя†ћєйp{w\сѕХWV}ађ•њeў˜ИЭ;7>>2œ=&ў [G!рхх5uъдGн­~{#lАx6ŸЇЭ›њы+щЖаБŽФ§|ФЌЧNlмИRЮћ‡Wщ‰FГЬ™ѕбВГzsчщBпfсoОљљHЛѓuѕ1†]iNbЊIср .qЄіжЕ}_Ў(|югGzж„ CћXˆіj•Ѓ+иpeџ/Їж€!‰ьбvw5~~~9mєў7W'nюгл_ъ]s н#"""99ЙЁGeЦcЈ?ЇёˆСЌyЩdНАИcT›kўњмпоџы=џєщгЧŽ^Е6)‚ЄЬ:MtЏбгЦMњlДOоЅџ\5”ЁЂf гc˜C­х‘)ГbЈнч ЈPŠZa“в_M:4gекјˆ LьаcЦ”Сэь>7Ž.6ГЂР 5bзQ L8fЂ‡@ є]рVvƒљSпŒэйЩ+ТlГ|{lEЁИ~й‡ШЦњ$(rюљEѕЫ™сЦ Р №PЇЦЦaq†ЕОраW"?ЂЩ”8їыи/11qчЮ БEwьєP,в‰FYИЦУ38Ьп[#Эмѕg\\‘‘@DiЩM=АjуŽCI\ЙЊХАaУњЗ”ёmЅYЉqћN[[іюмRfец];yю’СohWщЅcЛзю?CЄќМ Jёњ‹­5†ќДtГ“тЮеeЅЦя=QьШК}rгж$M@Ы!o ї \~т…Нќ/PК†ЗVЊ§кvo&dœ9ђœъЁщеж#@Є%фнžlХœюSљln=0-g1Нљ {вŽžЯп–|`АwЯђfц/ƒƒРcA qjllœ=4jXbЪ­TфЊ@„“ќa†=z№рСДВVЎbU *ш[`|R‰ ЮЦ јQюbŒ0f'm=їЅ…ЁН:…xЂg,^8ѓ”–ЄŒљYqћіЦ$б>к6}qв™˜џіЇ#,–P(P 8юС^žЭ$"–!7уТж­Gnш@›3f]XћлO-Ywмр(Ш9Вeѕ7БzФZp)іŸ‰KЗяс‡ѕŒ№фl§ЯЉуЉњr]Аъi35D€…Гощ8ЬIRKВ:Й‚эжAeфŽшН№—тћKП—Z˜ГЋЪАbю1дЦЉБРs м$ИЖУdЕpA~XMИ_kнЂ——KЭeqoЊТФI”\јzц‹+hлnЯ‰ŸЬlУ%,щзЯ§ŸоуЧ™/ѕFђo:уЎиЗўJFs?H5h- ПEgЋАZlFŒ%’z„‡Еm}МxpпAУšлЩПN]ДщŸUЫ?œО{_ЂC`пэХдэџi<КGм<ђуЇЯ~"йHRМВ9€ŸiMha Ъ‹Ух 9%еЇ]ЇщK_ $ZNялЛeЄЄ7Ѕ5DІ4ƒƒКtїВЖocўinъkL![№ЁнM{AмŸ%–Л‰ ъ‹?У‡A€Ah„Ц#є6#}6†-_ОЧqЙ@qvс9Ш„Y”1љ—6~И“GаjГBљ*ЯaЫ–і—Ј%dUGєўьP˜о*VKФЎ#GЬiг67зˆp27ГFЬЭNэочНїCŸЫГ"‰ЋRЬВš:E&гtš2}EЯбЮwqбˆБП|EJР “GŒ§ЩQGИ*ЯnoПib+9чDоЌїi]ʘ,”Љ8щзИxЉFCѓbJC!09bhООшrN"8Ьэ>UШЉŸ01§=ЛnИЕыLохŸ.Џ˜ењЭ†Z 3ƒ@B  6Ÿ3ъГОs>_‰й@"’Ю$ўЭ„­mAяпЌуЫxЯЭЄ7šЊ*`ѕС’zxеЋб ‹­єёKф$[ іtі/“ДVKЈrT9—ŸсС_Р bЪ”ЭdJZ/Ѓ)yr7wА‡„^ѓ№NХй"ggHF!–Мsў}ѕ—SлGЋmЗїэЪqяеЇK€ œoU3gюз8†ПеaТЌCKгJВœXѕqчЩ,Ќ~МgFNОїuЕ5ТЗosyГz˜+У‚A€A PА SК; љЄ;,“,V‹cј'a8&r”эVИћа*mгQс\–як%жНќаСЖМKљ_{ћн ЋхHЩmч\Бn—vаŠ‹›љwœ=šwЋаhАŒzѕљ]§МЙVсQ4DUРцб]ЩНѕлЙMЏGЊ—Q§$ž/џук†yч­эљ“#шpНpf˜00PАбЯEЄ ˆЪјШRMЉіШў§Ъ•ЩBєД$IтШцВРq Ђh|ьS`А# 8}=iЮсeG’ЯЉEђс!=ъ˜зBЦяH9_tЖ%ŸѓX/<&  ЇёaCŒЦ{>6ЛС{ƒ`ЂЋ’OƒLЁŽƒ€-%‹Учђ„<EЇЈ#?І{m№•ЛOo7ЌжЧя;ž[[6їєАxЕz š~Žџ_‘|9˜Т Р Po<>bоРлё‚—K@А.Ѓ,}&ЌёЖѓi41 Oї[‰#ЭC$ЌsœЈЈЈ:NбKьіRрШхWзЮЛАh}Я…`‡YG†Lw@­{hŸ'NЄЇпЋЎ1а24R,ˆuВ+)№cЛџ;x ЏЋkЁЩfДч•LCЮЧ­^Ÿ0Є‘ТЦ,‹A AЈСж ѓecxвф Ц˜‘mЬрйѕлvе}:‡3OM‹™-b vіћCЩ“е!УA ‰#№8­"›8ДЬђ)Ю|Х’Ns,ўЮдџ~Žћ_нWйЭЕ]—(е№нЅпъЮсР Р Р6ц;Р Pc|Дџrаќzu]Н„3ўЄеTЦо‘rш|^}цЈёТ˜ |іьйb!Ь"/БЋœчt$ыЬбЌ3ЊцюBM]†‡лpк $у oŒђэЯФ"Љ ˜L_FccО ЕDр9П/ŽДQФŒуsoiSkЩЅМлф Qž"—›к”U‰[Ъл˜П  ЕA€lЕAщУ р@рн“{Йu,Еъ_?іYЉИ.А€%lH‡%WVƒ}J]X1}š8Œ`kт_fљuB"nгіƒ0y`†>ч˜Y`Л_v\кєtыhАчЧ.Џ І/ƒ@G€lMќ Р,ПЎ№XмХбsм„ъИТыўЖŽŽЁЖ|•‡sїЄ=•S?A)ыК<І?ƒР3ˆ#иžС‡ЦLљ)C@СsZкiž˜-мŸqќћЫПзevЎBчзBЦ‡/.,В’ЖКАbњ24Yэ&ћш™…з3 cНzєSА%љйгFg4Ж&№™%6,рjНАуЌБпКZ|ѓ§“_/ŒžUЛY†nJкwK›ђЧЕ Џ‡ŽoиEдУh6ўЦЊе…g/ВI3 У­fвЪfБE"—^нН‡ Њ‡юaA‘… VйouиD@м:v1ћЃ<оƒbcЙЈь[аXжШЌƒA ЁpтJ–uњBЪџ—uњ›‹Ыj7<ƒЯ#ЇAппЎ§“ЎЫЎ“ZїgA~ЊЯtЕфеы‰И ьыWЉWЗЎЧ].8sЊрмE; Eш=NйЇњМяЃЄЬZmЪщKI)9fђО[w/mf}QVfJТ­—“nf­6FЎнХЇ1е­1=Mf-O%є60nќћц6‘ЫФfУj1ЙжЊАA^=ЖЇќњтвХцд‚CэК$i(684›ћ8АX8_ЪПЏёс—$‰До шF$JaЋо`•т,В8ЯœƒёИ ahC1 *-‡ƒГиђhЙdУ.iiаН@ГџKъnн>№ЮФѓ#FО<Œ‹МtH,Иы0е€Kkжщ]›џмq> C›ЭЦѕiл~Шфў-У4lЌLi\0‚­q=Of5O‘Њц_ЖyчƒгѓчЧўъ&дtwk_‹йН>хpцIаќeœЌ‡šJ™є–S[ЮшђJiUЊB­>зfЎmGVhЋМJeh- [p1A’iCo\KY0пЪсSlЦхВ) —H}ќxъJ|(вFДzeq9ˆЁАФŒ№РŒS$хaЪUЋЦѕ%‚›БГNg2[ОœЁИ”йЈ+5#žP„“,gЏШn}]DDбйuћNЎ]УS дОЃ=EЬЦUхёйЛЫЖgя™13~†ре-]Ÿ§KќЪN}ГВлїЁђ€šNrjOoўhlпФ.ы Ž€^5хP z6зјЈ/^Ы"lDХю"Йа5АК zXъ*с6ЪFRF+ EЅœТ0JЏЭ=rТˆ`B6FБиVБќч8lžМuDиь™‡ЛЗN–f%њsѓUЋ:иЫПэШ-ƒ&Є_їAуЛЙА в\Z’g)Ж в.m=|т|q`я.]{‡ш/оЗяІs›Ž}„КЖˆRЖf 88RŒЇпК›•V елчо˜ЋgцЇЪ3џ™<хМ2vЈw/#až3+ЫW‹йŽѕфф q–!Џi-КзМ ЪbГ|ТН]@†С!Н[H8|Жw+_зъ3a&ус >‹‡c*>ж\С “ГBԘ'$L1i”ZJyщЌмl*3Хœš\9g‹Ж хші=+жoп|‘”Лр7/n[ўЯЊ?ЮЪЊ-HŠљ/ёJ*qV;‘%—ўГ|ЫЦ?ЖўЛrwlВоЩ])dЁl_Ќ ИXirR\BJ>лггУO!bќі*G§™МЫЖgђБ1“~Ж˜нzF[ч№|S!dЗбYѕ5<Žс3#h+’?Џџ›RšYгюЕ ЇО”м1ˆ/т•WЁˆ“‹,А}3МкGR$Eх‰ЌRKrБйl#J,dЎбІЕР†$ХТŽy А0',в ѓa|6ŠУбXЅЅФb:iО5§ЕO_3Ѓ'™”rћX|xCVR_b1иpŽ8Дwя}ЂXзЮnўщЏ˜ыTxяюQЭYіWi5f$\јgёц˜гЙэ&єэ?ЊГ ŠA+sѓ)E€lOщƒaІе˜`cЌŸ:|ц+іH,I~ћФ—6ђž§НъЌД•2d˜Oo+i§ђТтъазУ1ЅЇЪ/Ъ…ѓ1„>В ъаL,9Ќ2ЊУGQ“ѓ0Ij„l7кЈLѕRѕjЁŒюo”зЕЖ4ЉЗV8~Ћ†ˆAБDб*ВkЈ[€›W˜ЏAP иљCЁ­їэІ"<ЅGXЛ~nЌ‚Œ‘FкЪл‰ aж'=ёз/]!лПіЦ”wЧ†њЪYеД:‹ehž*СіT=f2 GДЌѓ<9Wz"чDюЏХ:п {IТЯ9П/=Інkо…о{ ˆє“ЛЩaв5ае#Фу>[’Ъy‚єЮ3‘ZФ…&EЁсRўbм_‚ qєГЎхBJ-”™@Рtv +ghПKXЬњМЌBmAnњѕФ  “ киОІмф„—ѓ‹ЕЪЉ .1іЬѕRЖŒГ'зџєзŽS%~н;ѕщФГ™Š шйнщШT ŒёHЃy”ЬBžvР0rqємIџНПсіnwЁЫ”рб5šБœчєVиЄЙЭПИ ", XМuЏ1lH ЂаЮAWcЎEВy5;ŽBЙ\NћNЖтЎйœЅ-Ъзщ&#A V’‹Rr QŠ(6ШLЩБ`™ зVc’њМŒ3џ.SIJb7%ќќGЈ8ˆŽBрLQVCоЙ­;їIѓ4Њ;gппџZЛХгS2 “њjЬХS{Џ[•Iћ­O>mжQо:ѕлЭWQГuUc’ ЩF€lOј0У7)Z(чЗ§р­_ќї'8ЗѕёшTЃхђыП1iя•ЂФe ПгbrњжŽgуnGс"Џ)ŽDкbЦ$јŒYє%IЗЕ7ošsВJJuTБжPRrоRЪЕšљ6ЃАТ†ЂХŠтеуВpЖ9ћbLКо9ДWŸ“FƒЖg‰н#Z|”TI~VЎбЙSЇ> ђI>~рxrajŠжъьЄP‡‡JŒХжgЇщ)бX Д/SŒ`kt”Yаг@/їшїТ_ўўвon[#P†+‚Ћ?_№cў,rкиo­МОiЈwo_‰GѕћжŽŒ"9–‹П›уЄ­FLPxo к”ШЫKеž4‰ЭЊ/1dfВrЬљХ99…Z-nБ8qQQ‹•ѓŽАф.‘#Ї?яЄеƒ'œ“JЉP€џ)v ьћў‡Є@&”Rн'ОдчI%\\6шѕ)]FИrБT$” тгЁ'˜Ї<ж>O!–HЋ'O+Ÿsї)C€lOйaІгx1pDЊ.s§­oФЬ^зуgwQu=У›0y шmаъўь:ПAаBqv™idM‡ЛIpX@ДzDQ.__вd!­6вd% J `'‰ Ћh‚Б"wo/ЁZсццхCGqD 8z;љИƒ„ƒ@$ O!м щ:KЂV:ЉAВ1Щq– 4hВš.ŠЁњ`лгџŒ˜6BfЖššЉЯŽЩ>џкБ™їјЂJV‘3šOк—vьtюЅ]ЉџѕїьZ§ŽЕІЌЮйW•ЬэБЏьœ  Ут9<Э+ Ÿ•ˆLфюзѓƒЗкГ•2мaWzЯМHЄЬжД"Ј—ЕвѓЃUО*чЩ4ЋШF№™%<{€kк‚іŸ6“њ$•ІЯ8>ЯJкЊП'Ўј]ћлЗБПъ­†ъw|Њ(эZ­HUќT>CЎPьй*Д…'иUо) qЛОwЇ…Љ00‚љ0<„lСвNsU<љйМЫГЮ§TЃI€OЮх™ ]YUЃŽЯ21igСчžEJŒWŽ\Йzъњ=­ЕК C2гй˜ђЬ#Р<Хgў2 xvаT лј8wkђ%WўЎўBРџГˆi`KђwтVpњЎ~Чg…G0"x№УG№ЉиNщФ3ЗnЦ&UО4aБЇќУFи:љО.˜\Ќ5ƒW]ƒ˜сУКxЛ‚:крѓh,оћуЇБЌŠYƒРГ‚@АЬџћіŸL?>gё•Uр0ШЋ{5g,ѓƒ’gюљEЋК_Э^Я YjNк–Н[ЊГAЫГђ%z†Vždœ(JINКšVdЄmJТТUhќšИЉ…vёF’Дq ‘Еяј‰С]Л5“>V рT 8tЂл˜q}нšџRгŠ}ЃЛvянBцФМ™ыєјъг™A юtumћQЫзОКИфГГ \ЊHUX5yBдџ=iG/фЧƒТ7ФЛg5{5FЇЉyHЫjšoфцn:Й^Œ(bƒI с8є(и+Мѓв‚г9тlsooўvяn™љью 1y|W'ЎЭjxKм=хcqБ…'—ЫЄрŸвeмОuЙˆлЉУн~ЇІЭL-Ж№U.RІšГЎЎ§qХЉ ЖЗœмќлълњБЯWгSbJ-ИѓЉeІƒƒ@н08M—Й*q Јnkzќф-ЫѕЊ‹˜#„lmŸљў‡KПwwm—Uїyьt.З+‡Џ„ЊO8'Ед?ЪЏ:S€pš&TЋєE5d`™)Av‡b\„В–`кxЖЭFš) [‚Ш›#x‰“>ЩРсV=Ф\”k 0жmЛ;Ab7L,wwц8МћКж{єRЎ БQ| * X‡‹№p…ји•9 GиА{‰#” БX+8аaœiЫГ˜}‚С%ЪFш_аb†єRсLУІU4вŠ˜­ДY&šБ|гF6ЯырЧХmˆёжюM‡ЏQ]Цїэ.=Зa§– GЂТм•­]*—ееБЩв0‚­Щ>zfсOД|2ЗЮ<@ЖЩИек ьнsУэ= Д§џПO#оx*–9EѕІЄиd8М; МлNЎUИ`пЁ‡ž :<­ш љЮн##s ЕЭХЋџQТˆкДhPЄч@љ‹$лœ'НvNмd2aЖ cнсRБB‘BЉТ/ДyxЄl1СFФusпСƒ[фЙŸM,ш9ЄЬ—ЦЬИM‹з_ˆ5ukпe`ИГ˜9ѓќўC[NмШ7ябyРЈV|Ž-љиЁTLуTrэисќ6ћHsoнUHцЁэГ „ŸянЖЕЛ€Ыf!КЋлзя=Z Sv›<8ЊЕЋщњЩћcRlД|nPчЮЮчї]7ые!дз]Јк~чЎЕзoчDЕв№ЎїV\S8ŒёШУqaZАљЎнG!2џT]溘9ЂђCЃЛГћіЛUПЎO4Љд2AЮЦ_жC_ JBу;KX|ŽЕ(=6­ФеGЃrтAцЉЏ/л”‘šgЕVтвWхZ›:#иšњ7€Yџгƒфу\=зE КX№Щ™ЊѓВ†ЩHН' %)ЌHЊйхq.Х0TщЎъH{dгš§)Dmјт*b‹м7Б ЕY–gмК'хvќЮH’йЅ7XY1–“‡N§ћзжиуёt—Њ…-ДLWЏўyхТYѓ.X{тbKщфмв=|hŸшо-5 …#zJЈ l1`ТaЃлŠЩТ IХ…9ЇNœH(fEєщ?h\w~б•Ћщ:“Э”——jЗшоcјK§<C^r!ЛYt‡a/ <$ИрzBJVБ.чжцнGŒЊ .ƒћ пM:})gџ№ БO›ауЕmыХG …œb§6FЙ†d•BT–ћа`.ЋГY}ЌJЧŽ€Š/_кiојƒяьN;т.дМетХъ љFшˆBrЙ№кІЄН#|ћVЇЫуЄAY\–G˜gЦЌЌФ,иФYИwK/ШюVqoВ:(тSџИ]N<Ÿœ@^TсxбЏћж­œ C‹­“ЉVаˆ%qsеDEЗe#|'O‹ЧЪyb_ЊQ:Ћ$j…4ЉŸ_ЏQ-=tшmЁГZЭщ;WЇН~юІсЫМџx–Ды9кк0ЎДRЊ№Шn[љJqмŒX(Uы6нzF†8хмtЦб›2”$ыєЉ{v§zх4-Нš˜чjДЁ|Б“3‹/Ћм•N|K1hŽ(›Л8ДCE"vuВгUУІIУЖІљм™U?Н€іc‡OсЄэЗkџxŠ\‡ћіЉrЎры§aЫWп;ѕѕ‚ЫіpыЁIЊьђX @€‰фТш ‚є›Х&UK|[yГсЌЊFE$6UKm_я`/O'Є=†`<ŠЃ„”Є›ХЊ-е^ЂЮх& …"’}Е §пYд1Вck9„–ФX8ЦbE1v!i‘‹‚aŸ/Щсh ггБ›Q”BIЋт6Л„uег]лˆ,яЈ )–B‰H 10щ“0ЬE$rЉ“˜Оt(Ња—Ÿ8’ънЅŸ„E ˜ФѕО| H,N(CQ–RэЧхšLИGˆ‘њ‚$ТЂвHиUиyжЪ&GЬlE6ЙGЮ,јщG Ѓ&ђГˆщ0Я9ч9•sБ:ючйЅ­sxБEћSмŸеЁЬ4йSљЈќЃќa“-$:X(Ћ™Ќ…#3C6•Еч\UЁЗeR‹Г+хцƒјћщУ›“Zq:йкX.Šnэ&RYF#ATхUMЃХh1LfƒОTЇ-1-ЈQ YчВє6Ft…Pє?Žв“*§$*ю5ГБд9М{ttЏV28 Г“Ѓv‹ЩrZZ:иїF!А3ТvіlХцХш…Ъ Ж§:wшbя‹А…HЮойi:3‰bBї.Н}’ЗЙ’g#JЏlмœb№ђ pуBVІдFcЋ-rL?Ч‰Р(П~iњЬ?Ўm˜qbопнє—zU9кЬˆiУіОіяэ=А IЊЄЬ(WР эьЄ’x…{УС[† ё ^ѕеšЌY{~йŸЎШE t*њ ƒPТFШљъпІЎЩНЗkс~‰UT9АБ,8}№роѓ Xt0deФШщcњЗj-s‰[?їНмœ уЇ…xЩ6+ЃаЪ}TˆВр_LЈъђњ’Гrыџ>оГL„ЃDџйŸ .tp vчPГт%к §ƒIдkТТќ WМstТ\ЈцЮ1Аe@Пўиіu_Œ;6тЋYЃЕŒš:%ЗdйЊщгЕЅйnУцОд9ЪГZщФ+_sО IkЋq№к„b–Ю №Є€џ7п=љеоєc.чu=VђdUЮфЧЫў~m}Ј,шякTй М}ћі_Ж§мuP—ъаW†~ЛXЭVШSZ=њŠTАЙH™–ТЌиЬлUЉђл(H&ШыЦbу*wе­ИЄEя/uїw}Щ;хўЅLEљљY…z№@sАb хj…\Šfфdg–œе/g\[XbАёJЉ€Etљ9Ѕ_ЄT‹YЄеPT˜“™[Ђ%p6[нЬ[.х›2гKp‰R)}KкЙ;=эЮЅЕЄ03Ы,u“KФ\Ьf.ЮЮЮЩ.6Ž€­ђѕ’KЈ|С3 ‹,ЪЕJФBI}Nnъ­Ќb)цМšЙ:IрŒ­f?\ѓ3кВdівes–Яš5kіьйЕ^ЃБе:І#ƒРуEЬ.Оnћ~Ж1џRСе7ŽЭZйэ;ЌДМ2nGЪ!HБНўжЎ1ў+Ѕm€›АЊVR цFЋL|!зХЯХў‚Пѓ–ПћCŽВрэoŘ3вг…J^хысЪ”nReEкЭЅTžrw8/Й‚pіЁpPэ- OЫрg Ю^r%ШZšT1Кy`ЃВl^hХKЖTц)ѕђњЩ IDATзm;'Wъц)qqЃЗЁ'8Р$јb 7z‘И.TЋ`Cс8ЈzŽQ+N–Љз цŒ­fx1д  ‰ч,ъ8 Ь#у‹n|pzОc—Ќ’ XМZН?Ч§ЏаT\ eCнК#j7 Cр€ˆИS ^іqџ0ПŸw.xчЛЗ*€bх§Ъ*vЭ "tсД,ЁЗJЫHьЂ ˜С_ћИОа УY,А9Ћ|X=ћЪ%л=—4u9šдоњвц"4gјLEa\Zій/„Эт€щ NOЕвЕ07ЋF€lUcФP0]Лw%ХШЪџQ?|OнКImйBН4™šђ22хUtЮшб ю>нтэоХ0W5G€l5ЧŒщС арD9‡ЯiMяЖ}yqЩБЌГ•я%v4 hц_~T•7ЪЛ7ЏpX&%Ё—Ф_F§<ХЛКьу1ВЏ‡FэђяvсЪПЈддЛguu@ Z l-–5д‚GюCк]ѕъeЮšCeэUЮПВЮOт#иžъܘ 5GгL ЧlяœќђZёэЪМєœ›P}Н$iэЭэ•S6ЪЛ\6юЁс+х\ŠТ4Ю\/žЏ7тсmС%ЊФ&ЩЮ]ЈЁЗјУ`ВЭsLўvГЌДкŒк’ЂќТТМBо ђщAbэZg0”вНVg2:xV”šdж™ —Џх›"ЮVХqaВ(iБчйчљ 6Нбh†…=фжƒ‹m˜Ц*ВapfFaЈоh>1UŸv—d]Ÿе‚{–*і“Зz}ZЬь…Wўъуб"uUМлъ`„Ag`ˆоB]M5yx‡З6щ0v!ПЉƒфn№›ОŽЇmц+ЋWžу4я; Тэ‘6™Dкћ7џЕўT\ai‰%xШ№qS‡5їW@ќЌ Р’№як§Б9V gЁЈХ\ЊŒь;dPИJ XlŽC‡ГЦNџvљРiПОгV#Ў…яD…бЊЊ’fs…qвlŒлИzцЛЋЩwрЄ7?фЃфкM`ю02žўсћирбS†<=NхŒЦvчё0gy­пŽT6Я5Lљ\o5V2уnЎэККДеY п_њ­ВFyKЋ'R ˆBИЛ!щХфхъ№ElљJ|ћa~~ ‹‡[xl[ѕnпˆЃ!!Њ˜ы—П4QуэлЉ™ЅЛo˜W–ЗcFŽKKђЊЃVU‡)пісgCђўлЕxЩбфLƒ}hкBв.пЈЂ‹'N]ЫAФRЕЛГЦнU*уƒmdђЮ=ЛŽЇ˜ЬI ё)qŒpeИG0в–іЯiižДC#TKИŒžш}ooоЖ§d&A8ц†фјы“ЗДsЦ—K^MйЙтгљGKŽФпрЙр5$$мЬЕ‚Џ‚ƒЁ}]їOЩОф†ћ‡биkf$К#РСйПtœ5юр[А С!С‡wШ# (m's/юH=<вЗ_чъцB{ГgЉ9%лВћЂ^ДЎž$hlf6 хJ0.!‘ЂЦBmћH]5XŽUЏ3ZрMO™Jѕz#"U+%b6†БУоœсƒ‰d .i1–dыБX*х€чe1f8rБ@Шoѓ§'Q.WШFlЦи“Kтnцvєs"њвl`%хѓйEX<[w8Оg F@лq‚Ч7QМЮЪ•=&љHH_7'' ФˆGЭЅE)Y+ТQКЉ„BH^ в‘*ЭM+,†=JŽмЭY,ЄП ЦТ<3KРЖ”“rO%ZZbхˆИ”!/WGRl™ЋђN_mvJЁvЙJg!ГisќћЪ1вpЙUюс&“/й`ьїж+ЃлЩХјЯ?ЄŽyCќДшvž,ЄД8ЭЬrQ йvѓПi.TѓhGuԘŸk‚БlЅyљFHU sS‰vйZМы”lѕ"У‚A !€ЧЫ:Я{р­ЃYgОŽ]6ѓбљEнEšW‚Ч,Œџkо…Х›z/Ё]›FЁC]С^$э‡†р\ŒАкZ•єюbaЃ$› q6ЩтпQoЊDФšіпžGKyМмјИ+БКˆqЃ&ОвЫзwmнЪc‚ЈaУкЛЗзПљWN`ычошлЬCqtзђЏг:~<ДSWOЁГFЂГ16 с’ЙДЯ ™nзмУмI;Зі€цЁМ iТнQ"§ч;К1+Їhѕц%ЛV…:sтH_lxЦеƒЧькxБ8ƒьёў/On)ВŠcOЏ]К№HЌеP(ьію+уЧE*$ф…%ѓPЭK/ўw|ыŸЭ+~:)Œ№ЦRЖnКPœuOп•?},Г‹zЯœ6aLxё‘­џфъўм№ужТsО~ОЋёшi}яЩС" ca‘у?ёЗŠлИѓsЏžАb^7Яvс—яcZНіюsA<ЖхЬзsH;x[.эоqSŸЯэўЩЫSžv5Д Љ =Wљ|ЇˆњП(z6cƒmШЪы›*™дK#=E.ЗД)ЋnlЎ„ЌёнbЧ—ДЯІ3Р@*P›Ld m< ХЎTЃ1kГЏкЗ'ЖФuјФЗ?щ•ИщлФшmк”›73J LGиm‚цўеџЎ=wњШЏпьВЕ  Q Ыочнвœ~ђшПЇ ЗжA.*ˆ0–мЃGˆ‹FD‡:Е+5!ўиžЃ6я:Ачr^ЁQоUЮ вmт’zwѓсШG’ўнИщ’lв3&ѕЗюћіPržбjN[5хћж>3~Ÿ?s^Л§?,85"I6—7{ш‚Ѓ5­{ЙuмŸq|ўЅ_ДџфЁ4ЌБk7$АЙЮjF\•”оЂкuWlЛHЗ>xУ ~дCХqYхђRБ›ZТхуСс`8 –v[ \+ Œ/ юд–НђЪЕјќ~г‚ННЄ№ЮЇw mКин[—,=ъкu№cКљx‹qZ‚0cсєy]'MˆЧр/ŒыЈц"`)# LЬ†SєцБ]ћ єˆ_d€ЋFРbЃi…]KАнРшЎШ­CћзœKE’яхЅƒ)(№єkцх ж—ім7”с‘}їэZ‰HЇ]Мх|ЎтИ‘$`ћћPдd.A_o9ИФ М–џH AА‹8К™ЛF*cЁ8ЦРб"B@Vж/Œ`kpШ™ъ8BKгeAть7bf­эё“ЋP§PоЖz-&ћмоДЃ'}ћЖWG<”І15rйЄПЮгSZцьL8Ым26–r’cЮЫˆde‘…љєЅJƒrЊВŸ‡їК­DWšWj!hii!ќQ№И JЪ иšѓЏo[В‡-№ œйqьl„wo8‰b‘Y‡ї.§fƒzј”‰:Л+и6Ћ…‚$Ї яŒzЃс ЙК„dЙaIйl9bЂ@vn}()КЉ5[яŽ‚гNp4­]Єк$œЋ@PяЁ/П:О•‹€KЂ6Ъ‰Чe™ЇГ|п-ъы?jкдчBlY)'Ž™`мТ%}wшя):Е#aT[šOfœ=)ћћ9AF›NЋ#иbЩНž …Yˆ19ЇШъЦa•feP,7ZsmшТЖ†FœA ~˜љfІ>їTюХзŽ}ўwїbŽ№Aў.еk!уŒћѓ‹ K6ї^ І•в4І–ФФъUдљѓhX1~<Ъх!pyЮ~9сОЫ hxKP‹*+№В.К|хЈv3?Џ‘uљ:ю<Ђc€в‰wЫЩKiicецXКјр-ЭЈЙ“#5™П|њыњ%яmˆўeзэ‹ЉЂШ+Gў)ІE˜4 Ч 0WЕА(юП]gЙбƒZћx‚9’{љм, 2­‰МлїЛц-кЕЃ%вeHg?œА"А|ДЫ4ZеЄ(E8^су:4џыз [9!RSaОs—-§їCИGі§}С_›9Н=њМ\—оZys•ЭнВ—nккжкЁ_'_gѕР™}c>§wm3[ИЪxјыню}ІДђ†<;Hіщ­.јМјf”ˆKѓ1ъ˜ШУ[џлВЩY,КЙceЖд‹Н*їёмcлуС•сЪ аP€­уOfŽ?єXˆМ}ђ‹eОxЈѕу УЗ$яK*Mџп ч5дьžЬ8ЇŽ'/ XjљХы%ЁJсыИŒН^вќОЫѓЅU 6а’иТbkіЩ5‰%$йgЦ кz‹иˆ2$4ˆЏ[\AjBŽИЯ;Улw№”ёМ_yЋ№ЋbВ3 > i3Ÿfм’z>%жЗ\И­ЛКЈ…„9?3Cb M.PU‹PŸЬЄЋ‡Ž]ЃбBWЊYЄ№ˆ—[_\nЫvчVсžjЙКUDs?9›E+pї ШюЅ*p9`‹ћ/љˆѕЧ/{OьK8LчРMRТŠФРАтх}}Љ%пэлЛѓ[‹иˆЮ}(Jд|ьД6зХЌйЌhсЅтњ yљЭœeы6mОHPИtдЧпѕSгr %ŒYIЉj‘JšІu›0_Љ#Ј‰ТЖЊœЃџХВйб”ŸЇGxBzŸ†.LЂб†FœAрq ЉЯs`FЙxИOŸymо~шЇrb'љˆ‡sЗї§ЭUш\‘цё$­8BƒжwnГЎњ‡[hAŽа #ŒRсЃ/GЧU!х­ё‹–­9Uo‘ж&bГћ“ТЊЕЁ"ЮE №0n 0ш]DЧ9NЮ%MVТˆрp"uдс(ЪNp‡EЌEЅ:‚J%lJi­6 ь9ЁPf›MKa Ш8и"JЭzЃСJЂ„Ы“CІ#ŒвZюгѓЌpy_­Ygдл(ŒƒrљrœЩЁe-д–”X.eqш3DJg)..6QЈ€+“Ј`•>L# › cЫшKВФbcГиt’sгЦЈ^kF,јm\0ТЖBB=Б‚ёT€Оњ…I4Z}ЌJFŽœЎ-ю4gвсрМЭCфђPЌКe?.ЛгŽ|Ль—ŽŸ7bDЂЛАLfыљгљJoqhп[CUr ^Х•BrИJ‰„#Tђ%j' ttAqИŽЭA ЛXwк‹Ѓ,ЛdЫюЫ [Ж™ˆё88ЏМ.трЂŠS(kч(Ѕ ЭС•pЫЦŒЫцЈЪкAтbžD\–gѕAbzž•є•№Є’{њ"8ЪQ9)ЪЧ…юЈˆ+9г†0х;Ё4O—+(ŸПєЮмP‘(@тФчЉ…BАnЉРъ Y˜­Ш†D›‹Aр1"&ќЖн‡3ŽЯ;IOЁK_Я.іAЫWŽdїHаЩЅЭƒЃE*E† ФіТPЖВŽУ!йЃ.ёВЗz%ыЦ5};hk{яŠЎ2ђВ7;\н{ыQэGЙKНЫ•ЕŠфy§НC;8мЧАтeХњ}C”ўCG—{:о;‡;ЗИa_OwQzpY`лђа5нГРЧwqзфцёСpf`hzИux?ќeыу3п?4›3_1-t"|ya‰…OЌgОР^ гѓћ~ЃЃ[„ч„r…$Ка<ъЏh<јP4P‰›‹ˆЗкЉ*ыЩ‡іnZЈKdЫ0o8o{ТЫ~ву?сх3У346РHdŒп@ i…аўЉКЬ—7>`ˆПФ р~ПЖсСЛЯ\‹ЎHwnз…и#—œ94‡GЖужC/AцнщVћцјюѕ†Bр}ћйв6ІђPPpЃƒШaP}(йуndлуF˜сЯ аа|въѕNš6ХэыЧ>/Б”о7<иL~9 ЛК|рюЛћ”\BdD!"ЊЮеcIБЉI—S*Ÿ9žЯ9><Т.NЗŸЩPZTPl4е №џнЮuЋAHKЧє`V‘Ќucо{пЇП7A˜%346 оџэ?yў№ЛрЭуsыќе}Žk‘ЊАС^=ЖЅќътвЅц>…ыПykхІUT5DŒ˜”И[<­–ЪI‰М›7n\NЪзй’" зй=$ВЙЗ+„mDС!кnВhЫмzxw‚ЮgLп~ЁД‘Шу+(Нw ‹s„WЄЧ1fe%Ї^>^а7впB†<ОС›gFА5‰ЧЬ,ВЉ! dѓ—DЯspЦЙМИЯЮ§8Пэї!№nј”C™'!?РЁŒнн:мwЗŽ— oСбзLш˜ƒ$ГЉъRPTАївyK„rˆ0E!<{?PgрHЭQРb„ƒкт)7ЎJ™’љ—Яь^s$_рщЃфлЌ&ОЂhІтцšJ•ТnЛh(LЭL)’—>іЃЧтд›Ё‹ЛŒЯГ/ЦœБhіђ ЧЎфКПфяэЋ`Nѓ*}šUп,џŽTMЩP00щЋ‹KООИМƒ:Вт­Ке)ЃЮ|aЧE‚И_€A…›"ЄsPuјƒЬB9aъЌEЦЧ’Љ2d]KL€Rж"Ќ№›АPFвЬ‘!ЪжЏШЌПeрrЊˆЅb+-Fва>Н{…Щ!jЦЉ4‚ТЭЛ7'”јMznЄŒkAlЈ` !—@“Г!V bЕ+s„ ,ћaї$ЉХ„XршŽб•i•‹ЭFP !!,#\B@c:/ДCЛ] ”ZtjІkЧЮђ2“Бc—–PТщ>бНЧЉпВЁІ4сх#…ЛЭfNTЎБС`”@,їђ п0P)mrмоџlн“ч—йПmєјаЮЦmКдs+^8~Rпj@Я~cЂ\œИ,Ф”r|ѓŽеуSЄCњŒ™дQРЕ&юлqs•]оП3+zк(eжЕЁ—MлБіDzŽЈЯєЃ}D<{ЅБkиДэVЎV3рНё]:xт­9zњшЖTы–Э­^гwPKЅ“,К_g[КѓŸ<ко…)uF ЪoCG`00<9:ЛD- ŒџљЙŸЮцоc:Gq+’зџЕˆыэ}ЪсБлˆ•BиvМѓasиšgї@з!!7ЁэtbiDKwGЛbJh“EXнЬaGŸМ`c<НсIэИуIѕш uЅIY™щ™щщ9кR#Цчйl…˜явТGгЬ…ЙХ8HЩ…ckn;›‰kЄйЇWю<И%Х‚˜зюXёCLВ<4ЂНтъОНЧ/Є *чьОѕŸЭ›Г>‘puKЙЙчї­™9чгяbŒ g'ѓЉuГ\НVL"њгŸ,^И1_дІm‹`лІяў‚О6МБ•ЮRЗ6*7'˜уѓqЂx<хM-рР9И{ˆ›ч5їД„tpџbБYО­|eЎw­&ЯЕХ]{ЮzЙ‘LрbDn­ІЛў/ћL‡А(1R-Жp8&oжЬЏЫАN-ИGЄіPГйŽ”У“ВRБD z-”‘ћњ7ыж&,РEЋ“qy8Qы-ІГ1сШщмФИПXЖќЌв^CA?„”l­";FxЙ‰!geЄмлЕщд1дЧ]”ЅrBбl"›uЙfЫЭПWЬоЗЇ щ7uj …ђј)ЮѓDr‰bу3{еќ6д„Œl5A‹Ёex6€Фm "IЦн˜v|ЮŠЎѓ!VЎc)2ЎtFи‹sЯ/дМd…з}=Љ ЄKHnJžеdurqђ‰№ЦЋ0\М`и—“[5ђGњ5їЕИ‚Q>l,9iБšLVKIqёЙ’˜ьж‘|)ЄxІГ˜UZР"“+WzЗ ‰h )Ь u&Ф|Ђƒ[PŒяk‡Ю4ŽP1єi§ ЄRV+iЕњuэ8ф…A^b dЙШ №1Ќ‘лЎхJ)‰$|єUHJOњ’&3Im'щг)HF&Ч%аOЦGСЎЦDЇЅ=™щAhf˜ЭŠvpІџVckЕвѕ6ё›Ь[џ0Ыo*№Y<ˆ’ь"pОTpnU<”хл›ВМѓЖ›ѕН!Љp—w bq№АюЭљтšх.9ЄMЃ’З"–+xqœЭ–ƒpЕ\БIЁ(ђ№Б5aEњкškЯqжЗїXzЭvПцƒ Б˜ЅК’ЂRmQQaaa‘С`ЦxЈіbzъёДR8”Š–4E &гЩ5HL~ъUЬЗU‹О,ˆЕяPГhaъ Огуn_˜леП_tsMš‘tkъjя #’Н9!=IkoК&НЙИX 2дЄ5ъŠ VтЎ‹›€љЇf0[Э№bЈž]РФYЇЙЙ RiЛ еяĘьX шЪ3xz_ыe[RК6Ч]R/{’(›ЫіoыЯѓ\\@ЉQ іZ§ЭЊЬйћШTф№yАБФ1(№JкШќТ|%WѕчћЋroчя]rPjГVЮКž>|hџХuє™…(#FОё\џ–‘ ЯЫчXP2aмыCIкРŸ"ьЪJыM Da_оaЪ(Жrлк™/§%Т)Ђяь™#C MCeщ5С€ЅТ%L’N‰Ѓ˜Шmдг‘‹WП?}Т! kџ9ŸивЏw?жЖЕѓŸ?uуыЯG lЉФВVНіѓўуng2оОВV4uљєž|Р€)ЕC€ЩЧV;м˜^ Я*'s.Мzt&lпЭi=cЄo?Ч2 лYч›ђоž!*пЯЛНZOkЃїг Стдт4­RZ-ж’ќАоЌЇ‘ж–€-ESІ’нŠKZјўb7?З–МѓшiS–RmIЁжHя>кЉpžD! QmnAAž–#SЈ\ИAЋ7“lБr‡’fcqЁх№% 3ГV[[PZjEйЅ—›TЬЕфчщqЁDТчи“ѓrя\кєкќЋX)и „ѕљyE#Т№фnш‹ZЙiЙ%ZГдгC)уГPЂ(#_“IF/Ž-wSœІ)з˜|lў3w@{uФЌШ7СњЮе\ъšaюКDзоў yЗЇФvєjљˆо5jІЯŠj%е`Z–qИ•ЋВlk№о‘QG+Š˜MЦдЄTОSщg@\ЉФZj”8Я‚4™‹кЩ4Tћ•XТ–”э-b\ОLi=эrХЙR'DЊБŸК!MУSЊј$OХKwx˜лYa,ЪйCЁ‚aщ%99Џ'тŒ>NƒТ’ЙбЉо ^6С ’М|ОЬп РœБе,†”A q 0ТЗяЫC^F” IDATAЯвіж‰/K’‹"ѕЖvь@ЈЏКДУh5згJ+МћkЧб. @мїЁ…€w`ЋfФќњЩв*eo)ДdЙ[ьн+Шј8dN™ƒ\@)_б;ЁvQDMїИ3 ћѕKК‹C€йбcиKй(–nw8аїш%–{GцŸZ#РЖZCЧtdx†˜6ЉЏGgНЭ№њБЯђŒ…Ž•тюЭ^ХІвѕёћž•Е/ЬйI,п7aPЮшУ2ћЦ%I€u~йЇЂвv_цВб P‹НяFГvf! Mа ОŠz/л[pѕ˜Y$NяAуфШЁэџeяЭн|Z{:Й< 94Ћ{fZ\ŒќГ–ЪЭCž{Й‹lј’hгz”кЗAJЄАи{К0 FckLO“Y ƒ@ WЖEбГ=„.WŠsЂmŽ2/'з>ўР/ь [*Кд€яS@z=Ž#$Ul›4ў ?ЬcЪhЯ)cМ|}мжoўў•š\сДэБOиОЩшРЗЖcџ˜`жЖw“ыЧЖ&їШ™3мAМГ—už'хˆ ”z"}Рeth/)Ot=?љhђyGЫ3їЏ‡{К№”rœdiT7ЎЇ;Љё0“ПпUz9MvњXфзЕ&‹ХLЧЉЌ„i#LДAf1Є05,N„йbв›Œ№бЅГ b–мЧ“Ь8sіђЕ<3$h№B$a2ыKLФ§Г*› a0™-pяО97јD+ ШЖ `0UІ‡€Зи§—ŽГ Kšb€wœ-pјZаџОМKo1>‹аo`i8иz Zu9й”Ѓ/є ЮiZфюJpФ\p3ЋѓКЬ—VќОтЏSљГцQ…L=Ић—'o=lhГОїћ…›љ–ћ/ѓх5Ћ~њ№Лo?јqСG?}ѓіЮ<ŠЃуkЗч9ЫХн=мRŠЗ@ЖдЉЛ{KнiZJqwŠ[Бт !$!!nчw+пЛwI@ ! эЬУsY§эБџ›™wоyюУ_чюЯ/Ж‡цŠZиџ™ќбKž.Б4Žk˜КЊ зЏ.&)Э'7o^єэЯіњђDЎ­Жe№–=ќѓ’sЭ"Кu5ЄсOЗЎœбuDИ;ДеЧ{ьz0{Їчžƒ.AIбњр ›iсЩwGЎЎeЙ‰Э*bJŒа_Т.•qЧѓљЭ‡Шo~-Z'Э/бИMLо‚BжŠxй> сŸ+рЖ Вђ+œZуКU] aьбЭ–1s+8№хyпўУФђыО§zЧ…“3žЧ5ЭW~тяJ$юžAсA‘С^žn" ПАbѕЪVkхbQ‚5\N =PgjЮVе jXjж.UB•„феб\ǡɘЖhщВ]й,SY7Ьtёчўп7ЋН|u rsх„[NŸN/ЉдыЊВjЉgUэšт/2i ЪЈ D …Pf'sЮzŒ ћvпŸяіx,Xу;9щоW6}ћWкОСЩpкТыMѕ.цкV4ƒЗŸ Ю ОХ"JЂІhVOуІТђЎэŒњ^“тFЇ“ЩbgсEn3ŒLхсюІєц›БИX&sKyžWИЙЉр:С;ЌЅyf‘F!SH;Э™ж:Ž4З y№рюяŽžЯ/щюЏРЬ†B3ІRIЅАgЧ†Ѕtі`пHaљЯ“c-йјжьY§ еaСОjЕА€ЮBр6CYvžЩIt>:Йœo‚ќ№Ц‚ь’r–Уh­Џ^ ;Єb˜ЅДиFJEŽŠ’RNрŽСТrZ&ц,EE–Ї5оWвђ2K аПЛћых‚)/иѓв/3Чы’<9­ŸЏFMсŠаџэ^HфЌаqCѕ*;(‚…šX)ow…KКЭ˜оž†•ъ‚”CVZ.a Ef k| J 5ХєFЈыЖЦ"‰ђAюnEKг;эvŽЩ™Жkі‡НŸђWy яДімЎYџ,џ з“`0y5*+’@яFЈ5%&YЛНmtљР^6pBУH ЩѓN#ЩњЕШ‘ЙyеІmg+d’МУЧŽЎh?yќф'њ‡њ‹§ќн6y‡QЃ:ћВiLš•—2юЙ‘ђœmЋО{;Ѓѓ;Ѓzѕ ”Ы]яXС­1Œ,тАэ›гtСп+пм,~hrЯсrxэл,Œ^vXзM‘dс- KK s}Нє—жя8yL8Ш*uщдІ9[WЮ;XœУ xћэЧЇ$ЉTљ‘}П}ћљ–§VsЉ[ŸзŸš<Бж=№х;›ёVх6oф^XѕЖmЦДПнкc–.8XœЫжL;уГЖЦmхnƒ?|~ђјЄт-KцUmПўёЩќТФi_=:"B,k4˜5єђЊ/РЅГкѕчg}єRЧžЗ^л‘ќєkуbЅ"лоw^љKз%Ф|xХђГ†"ЩРІ>:Й‹FбдBSеЋЎпFБDр_L ›(\j•Z ŸэškДGЦібHнвJВЗeМЛZ Sl”ˆ ЇTАiŽАЌмbЩh–qММЁ\ѕŽОiгІЂГ;6o8j {шщП™БlжђЧŠŒЌ)/3+пhfxк+n№3ё[›?wчё§л~| е/Ёu’ЇKд„б9жviЯЖљ{XпvбО P БGиаЖA*БPEЛxъјіЕ[7.]НqнбТ‹6Бн ­4jмр'—|yпРpl‚*ЧЮЯ_ИшИзГ3о~‚шЏ7g™жЌY|ДŽѕоњйпќвgЫчпюЁk‡ЄЖ];иЅRЃУ’qzsЙ!Цн‘wрLIЄЖфцU0рQЦФб#žјщЅЁ]:Dъ`Ќ“хDЇ|їe-iлx0™{NйЄ:ЫхЌ<ƒHж†pѓ  дЫ*~еЦЫ#Йя„‰Rиѕ[ИЫСžррФS82rтG^ŸїЪ6­тОўX Яэоп Тжд=DЁщ( ˆ@K%  eЏt™єц–ц§п‘ЗЙoЫ…' вцŸи0Ѕэ№–ZыkыеЛ–dАY1/oДTН1ow&Грн v}№ }&јQ_}zmњkЮqLЏ”zjЄ<ˆ Ѓ›•§!КЮ(qDч’Y'Ю^0ол'ЪпЯ ^љ‚Ž2ЦЃЋ—~§§іа{Ц~5Ў‡ŸЗЪХ{БAR8цЬXршсS&є‚96‚‡бRЗBˆ…Mш В3оˆEДдhрЗЯк-<&qn=€ƒ ЬЩЕkrЗУ{œ O ёV B’ˆo9lEрм‡79гЊkI{lХђЌ #oе3дCN,,(ЈYЎГ‰N?bPgAш\UvжŸЌ4lЉЩ.E{i()ЮссZ/мnъ€„­Љ‰ЃђNРSЁ{Йѓƒяoћusњ~/…;X‘МДщы­є NгД№ЪЛЊЊAБLY_JžzЮC‹ххsџс5ZТЫ '(,ї2WT(œzzуtх–ЋuЖL0)5”чW8-n4лXЛDB fЎƒЖТ3K>_NJBт[ЩЗ/км*Ц@?)Х]оМіл…<јьфёєJЬfsРіт`MТ˜С …+$"Jp—ЬВŒ]ФиХиЖу@A0\„Ÿ+З9Ње@&m`–:Гu‚ж G$­Уё№‰/<5ОЗ\ФуvЋЃ(aљogЎЌЏЏ;mЬЃoLЏЃIЗлЄА1Ъ-J-ГГЄаЏtXTЧБ  •ƒВтЦ*Œ,ЅT‰Џ2В„HV‘vЙЬуKS—s‹9ЪЯЛ:ЇЊяќ_$lwž1*Ил„ыŸl?њ›ПчЭ;ЖN/з ŽшК2uј"љЈїSТвАЮІВsўЧя;€ЗJd'OТi VзщЄЩxыЄ+UkЫVzєФі’%’МH&чp*с5КK”^#Nc0†w=цЈШл№§З›/MќтБіоЙ_<їеќячыхулХ`›ПZ“}*WwўаЦй9ауU‘§†%њz)JŽmYЕ_в}XrH дЊриСMZOЊDЯbЪрЮ}Ѓнуќ ОXГ"ыq_ЯpшIaи|TP3‚Lv?n3БcТєOgўfЫŒW™KŠ|zєk.Н:2vѕщUiП}у[7ЫРш@ЙЁ пПџ=­CЄ‰ў—ПZВ$йжuHPš`Ыі-иŸqvŸУžЗуЯЕйZЯNc:ъeTўоЅўњш b!џtj.FЪАє™KЛЂbфч–§/7Му”СЎJ7х'ЖІЄЪBюќЦKцŸXџУўЏuyhwж‘ŒвшУѕ K6РЗBSiЈжЏeЖgяnіРI™Fц ›Зй 3Яh‡О=*Й­Ї›иїёWЦЯјuKnnЁ9LЏMŒnCШЫв/ю;Ÿ!Ађ–Еыуу…qLqоe7Г ЊFxДŠЩ>{ъЏэ']4НzFЖ‹ˆљXЪ‘?-]с‘д*ШSяйІm|АЦЕї›< І]oƒоMDn§чМ%њх‹хзмDy_Лю<ЏЈ:Q5OЏI‹їсв +л…ДczЛšјqЯt<ќћюЙ‹ѕ­лщu„н№ЯЂ5'ЬŽЖнѕЉы7С""‡Д#Ю‘—™э.R лшеЎ}bЈtCЁњpС­‡oўіM‡71<Љ{zЦ3­ќšЁЧ†6u}•а'"№Ÿ&Ў^НњЛUпvв­&ˆ_-…AH•X1"ЖЯЌУЫe"Щфжїž*L?pщdџјGZъЌлК5Ьмt‰]Arіё#l*…ЃЎгq#ЌїЉйты'ПŸ>џ`EТ”ЧGДrc1и|”ТaСЬ9йaT&о`|ŽАЭrЮОЮТŠ3шOБ…󆹄 =4X€Ц8Шэ<†|РU'DЈІБЌ3Ч‰Є `8nƒ­У9VфŒСЄ W8чЄP4Әa U1&Хс"‰]ъyуДX'иЏр2*ЁЄХaц9‘L0'ЊltZˆРЁP8Я*„ір’`8V*\Т­$AqЌ`EcYжЖЯМБ?Ь›”€га*™Hlœu†xѕ hЃбњqBБDрv <”to‘Љєxўљ i{т=ТNЄ§p`+Г‹e—o7з;žЎ[V…эџЛР#XŸ, ітnp ЏуVЇХ …˜R№”B˜Цђœ xч9щoS<Щё2з ž—ВWnИЎ9?yŠхЋЦЫ„|j™чƒ "и>е5ўШ‹kф#ЈHu^<'f БФSш@AИ*ђ5ЇЕЄ•жL ж+ЌќJЙЇЈЅМˆeСЧxIuнЙ2RЉ YЏ ЁЃVYŸЪxMјч ž&,… w’ Ÿэ8юэ-?]ЊШ‡БЧš•†%–o-qЪM.ЧюBн;€т F1аЉы”Ї5Uл1щsOїБнь /ЅKcj‹s‡ЎU*h=rЏЬы3Л>эѕWЎOUыКѕwЯ)§%"0ЧМЕŽZ­йніХ–јЅМэЦ „ˆ"ашЄ”ИЃ"dk#СС2ЙЦТšчlє(АФЎљŽsЦI0чXМaы<…ЪЭъ+<=‚У§нUЕєЊn–іПvїˆ‰ „ЅТf3$lЭмJ,х0YkE3K›4вPb<Аъа?›дZCДЋЏ_zх Xэ_у#И2-Ž “O(䇈s]}"об8зќЬЙЃeЁЬDр.#k(ќdЧ,АЌЕоЫr;ЖЊѕV/’ЌЃЊ—5ХdЙx<‹P’‰НуoP(ИZЄ0Ї„ u`Я+ГРѕџUн5ЋЉТbхФ2™TкЄ/FXtGc4хєЛЯ`vСАџъŠн ]шV­šєљеZt@Z,™ІxЇeЇЗ˜ЕXXdо1ћ‘ДKчg,žХ_5іY;$І aТ-ИQ` Ю9s$­аШ‚AЫкХёэCќРm#ИїU pLЮВЭЋOBЦЏЙQf ОJF( Vi{R–yzї’Ш59DIУ‡ѕœЌ‡m(4€ЖРCI;ŠЄEvщмvХ™­ЮяupWmcvБ4ЇVапrКЇИц&8еяM7V Ъ$Ауєжуum0–РЌает0‰Ћd+Ќ~i"1˜Ї#РЫтыєPuMq5OЙЂcћзЯлQЈ гЫЛEDљFGy‹ŠmrwНЛN0 4—_*Ь)ѕ0жCNkц}ыЧЅ™чŠ­ я­LшZŽН;cG)Ћ‡%ж™ЧW|ѓsЎ›8К­ЇMщн:йЊеп‘Њ ш/"€ Wгвѕ ыћŽюЪМ2›Ua7•Y jЉВFtоlАZyˆНЎ куючз3ІFфКqž’ГnбИg6щ wQ‡ЭmKРfeіЂd?Э8x+gЅu˜{{LVژвLbбMd€5(>iа~ ZpEJфZНЂxсЊ%ЇЪУКŒNbЧBЩг*RLHЅlkFА˜У3BgФo-шfйm˜ œ+Rр­c8L$Т;^ЌD„pJвТl?cƒEч6R„IФ‚вs |tРPhжДyП…v}j|Я)aУи бУЧыєо!„1[ёвћзюо-вCЃЛ2ћW7'tЇVHиjХ‚."ˆРЕмхš'лбuоёu'ђЯЛnУ4[+idЭЈАš˜–ˆNџ“&x<Ќ<Іа(Њ/мќЧBJ№ЉЙ>{w+ЪО€mўчЩYqЮЕю2бу;aЩ’й\ИЪbЗ‘ЎЅб7ЬTЎд‡GFh#Iœ-K;КaЧжUы МwЭдЁћЄ` IУХП]{`ч^c›{ћ y “ЏFLaж‹;-›НёјEUђ}C&Lщ*3gз-?KњщŠЏ_™з§љћѕЙ'sСОxжВпwdчЙ |atЯnaJ шmХЁЙŸ,XrЎаш}Я+“zw 6ћыї=‡іЌЪЖ-Yєа„СУлјѕn;ЧСтnmT›љЦНV+ЌЗОжюх†C7Џ"€„э*ш@nL HуѓFЗ‡хsdеeCбйЂ‹­МЏ6БTй1"7 ьNŒеY‰$"Пh_Пш[sСЅБтЩ&7YыOЛН§‘УП'8š'ХМЇП,Yз6/7їФб˜œa€oоЋЬ@ЊЫ­yPX^~>;+CoТxBЉQQr‰J*ів*‚Sbƒƒ2вJce‡Жo;Tл6$и;ћаœЕR‰яи‡г~_9wс>kыv]"ЬЧЗlие*ЈKGЏќC›­ШШ Lь­бI жnžП6+_гО}€WўцoiНЇЛЗM’ю~с›щчЭ Н{…цœ]:mŽXњPЂNЁ# /ї№!~!юДœ2Л~PЄщТњУfжлOэ&­ёЃ f#аqН aЋ& @jHєŠќВџ [вїƒЖеМн JН2ОGмю…{Ћ—o+=”‘#EаљЙ•ІсОГe=ѓуь4iљЏнƒэCчЅжUЪ5іЪ•Х‡ж+G‚Ц'm:^šъcФД‘§Чн?АT‚ЌEyпРžfОsУt7ЮФu&ЧtQБQНFtK”bД\чыCQ”H!Ђ”T.•Щ@/э`„щеГMtGyЉ’“,ЫqЛбa;ЕeузGїџDВeХж­†СМXRДi“’;bѓ˜З`лuщхчЉИЌVрЩК‘vKБУq~жЯ/.љтэy9жћœ‰iAЫh™R&“€ѕ#x|Єьп}љ‡L"lъGїuO RŠoВс@}šќ_Žƒ„эПќєQл;BДGЊ”Фu‹ЩПяА:4Оšж.Кѕ/œWш>] Ч„&„йРіЖ(уHkglv‡­ИИdбЮЫэb0 ›F; 5ъЮ,2i­Ю/>*Ў0ЧцмэгnŸь8ЮК6§„‹‡Є  “ƒТЮcТ>Ё8Я8@лЂћѕМяЁaСJиУ“і дЪ„•Ж'…•лТ ‡IХ4-ц9*#l[ЦйЌА•Y—'и-F0рЇ$ž!ўЬќ­‚+2!2‘lЩЉOоќЙаЋуЃhэ-ЅСmr•ЪК[„юм€ZO8ш"€мdLэЃ‰ыC‰Љј^БbyНV[W:TžЩЇ/хŒ'ЙТ#Ы%+_‚‰rU‰ЇЏ=<œH тЂЫі“'fѓikf“‰aЎZ‡POЭЛе\^QR\VV\\X\\l6л ^~(ытЎlWУГVхt0iK­OŒж‡н’wў0уыњaї1!gALkЬэ ‡ЎSс*$ђь$Užž™VfбF$ХE„iœi1‘Я]t"ћЂС*ь1ZВ§…_Ў<ЃwЃ­y™2ђMЖ›7Š@Ё.ЈЧVt@B‡ЕаvЁbЅФ'ЬWшгмJˆˆ]ін’ь3—V~Оі’{ŽT"K'H№Bˆ,Уын<НП$/-езыn&lАЏ VДgг†{“Т(Й'y~ќ=’ѕaG}№L^С„ ЯтМн&XЂ@MЁlєaМUЊщјј‡hцТЙ/ŒњIJђм=Ÿ}0zh,kУьbntЕŠЏyJŽр>#>Ѓ~zџєѓ™OMќСAѓЌcшДFm1pАxеьї‡яўљїђ8!Я`В-|ѓѓ" – №ї~:clЛD§­BЛРџђИh?ЖљFЭCъC Ў§иъ“Жю8Юйv–wQЗxX2f/-,‰€ Ћ3фЛ aі‹‘юžКєО{щGпPп—zОюBx›ЁММАдdЏъSQ2ЕЛЪM‰—чхUа:НЇŸ;i*3X8ZЅVJa]ЙД脉!šœфYkEYёхтђ ;ьaЃђгЈ$Ж‚<#ЁTkdЎЭ?Эљ—ЋOcyaЁ]сЉRШhœcŒХ…—ЫMГ\ЂѕѓДИн’ŸuЙДЬІ дkhCNЁбbg@#]AкЭгW%ƒerџЩ€іcћO>vдhDрЎ!н$žИ=Uƒ6‚Ѕ „ієѓМQsqЬjЕdІgJмkЩZЉв+Tњ1п(8ЏѕёQ{ћ8m91мM­U9'Ь`R"гњШ*OpRтІѕqгx Т8сВдУЫ9бV™cЭSRЁђ’ ѕК\Ѕpї–щ pСyQ,ѓ &d†iќНЏБЋinчј50н‡џбwчУBЕFю: NЛYбmЂц‹;8ъІуTŠZВФF0сp—ъTŸU_‡+NIЊЉ75+яW'ЮЋNœїœƒ“5ЎР§šЖ4W—{UЙ-ІrC зЬЯшŽ„эŽтE™#ˆ@38{LЌЅT&ТvќhERœJ=Q­СОDZžcСђђCЫGтƒCюІХNАЎњšuЈ6т–]$Ж–§|PэDрж (хd€ФцЇ'Fw‘У‹–H­VТn+#eЊ“йdрСђр›ЌщОiБЌнЦТЮj"˜.Ћs|Ь7V‹ныНq‘D,–Рюk#Гv;#ИЛ „В„…пWEу.8TЈŠt‹ЎM~гz6$ЧР&?fиуЄар E пk+РZ­ ‹гЁЦзоjHб I‹„­!єPZDh‰Њ–Ђ ]œ2 $ЭRвОЃ…‘а\g­ )Кk 6л‘щгїб­юЙЏ]€G-“|N.loнгѕ IDATцІ5ѓОŸЙѕ@AyЙ=iќф)ЏŽN ггWьU –эшœйkцк9p†Œл,†Ž™ьЅЂР% UЉіCcоўrЬЫ‹^ыьЃКЩ= |œнQЃ\іьТпљfцОTжaЖu{хЉ/п v5ЬВыїФN˜:6R"j)žРюІЮxJŽ џхFіbЁЃаФ1,vЉ”=^Рoќ›њш+zЮ2EN1ь fЇЩ[pэсК#№OаЌ„ˆл/f\Ъ7Y„hЎЛеt…Sч‰=§чПD1Ѓ?нВ`ЮЂч,{W1mkzЖЩyыJ’ŠSћgU(§"ТЃZЧјћkh–ОtХђ-fС7‰ФБжj-x•О’аyJ‚‹ЎыЎ pХЧЕ0Сu З\•‡[WТuiЙsѓ-й–Э0Ўh–So.еŒў`оЩe3gO:ќЭДwОјЧ Лб Ё2s8Аž9“QЪИжЊз(њЊ*])ВIŽP­I0ЃBD  \ШБ-пoІHм7€3;xVJГbŘц|hм_о+Ѕb`џ[ЈУ ыЇ9чэ&“ЩТЛщuJ%tКшіŸ~жEяА–ц%AzœЇ‘F.“ЫzЌš>@шђxЂџcoŸЖ?Ѓ дЈР-†"3иАHС 2HDTЗ>Ѓ&їђ‚нjР–“Б˜‹жП:sњ'#Нˆ€ o•Šя^ ЗЫ@JС˜ЮS'—УЮT˜[b'_"ЕЗ^ S‰n)+Ж‘R‘УXVЦjќє˜БœЁх4g).6В­FZcСЅ3­ѕеЫ%8c(оѓЬO??ьбЮгњzЋUŠa›РР;4GLxтХ•‹ппyКмбV.&9Ј‰•ђжЩH\вgб‚ТPЄ ј–т"+,Dgakr ‹5о:…TЈв-рnŒЈHиƒ"Ъ@Z’Фф2X<&x, nDьэcJ‡і… зxмc8єзœSZѕЉД#c§ђu›S+d’мƒ‡ЈшђФ#=;0ЬŸ>№щ‡›ЅюпнM5ъзќФЮ“_ЈШйВь‹гК}ђ@пСJP=Ё№ЕlЏ`84єУђw.yaЃјЩGћІD*рЖеh1šMF˜ГWЯ4•Пg§<Гб6ѓчДўфѓ'&Fƒјб9ЇжџВ~сьНХйФаO?|њ‰ЖjYqdпЌOп[ЗЧb,бмѓС‹?вон§ћузжуm}ЪіЌ^ХОЕѕ#лOэVu ХЮ§љлžтœЋвўєЮЋтж2Э№Џо˜2)ЉxнМ9Аmјџ{kFNыožњ@ДDфА9ыоWЪ˜HJ&œgЏўyЬЖш•пє:6?1ekћп/Ѕm;_yvƒЎW˜eпТљЇ EВ{П|љщGЛjфM-4UНjЁЊ( ˆ"№o „ЄњR№ћСg9 ч9Г`8(MНUM СкJгwmоxТџТлПЮ8kйє%k9kQnN9N№пЖЃпi_К}імпЖпЗѕ›7WЩЧДoŸтЋ„"… œЕ^кНyюv‡JМПЇfЂ$О1уЛDk$Bw†Р.œ8Оmе– WnX}Д иьžмmЄЛ,юБ1oьљmТшXЙ„$хXъяПџy"№Н•?јœbѓ›.šЖЌщїОГZўшGжЮ_qпцiŸя8Uтh/Ьмїыяыdƒ>]џQы-gЭмёЭєЙgо[}mкuОЏЭ=ПсЯ%—МєіЎt“WЯ!cеЂшЉо=8oм=ЁЂЊњЌ9}эђіИu‘ЄЁ…}Qe!ЩЯѕ Q‚oK 7ч]ЬЌЈtБi7dьўeіjљ щ{ч|ѕaм†з_ZВ/O`аДЁЉ…Дi[‡JCџ"­–їѕdРЮаЭ WШЊќп:ЮŽQ>6ё‰G:{;Аа>пЎ;pЂЈЄм†˜іRж€sA§&Ёc ^UаХu9исЦJŠ1Yъ…#†вtUц?0,)Ь#Ф+(™:цуушяЎ$YЬ“…вћžŸ§ХА8;Ѓ;§{j‰ЩaI;Й…БЗѓ2_мvЖїфЪ.чFЭZ0щЄWчН5а[›ГšРeЇtф ЕІэцc:Лa?СH|љ’ьЫF** Є=qТЫ/0Шќ\ВТ‚7—ўГnёЧO.ѕќЕзЦDКЬ2НкxА=gі0„Yхœ[ƒcж„Щ^˜ЖсхŽаЈФ7Іnљќянћ.?вЫяжЉ7(ЖсC‰D аoлЮ`ЕbžZОТhаѕУНнyaOOчN4№ }&шkTŸоЄ 8ц)Ѕ4RвŠБАљIU:т‚\УЈ.х3NœЫfFїі‘CЗFXzЦ/[№щWлтxфН‰=<Д‹Й$–Е х 0f,xвИЇ&Šі‚aI‡Г‚’Yэ0dЪРЦlЌPS 3aQ}%b–С6Гчх"иы€^р->ГzЅ”,ЌsИJщФБЈ!bЎЩ­Кгю;яpС(ybп/9Ž;Ќv+WЙ Чх;gќєњ—яџёыЉїЦѓмъ ЮњУЁЊ9@Š8д‚;$`Ят9цЁлчŠг”ŸHиš’6* @š‚€Аaš1qƒ{y‘zwљ2Ÿ‘СiЕИЇЗАЁLЮeЎЈаuJаєЭоМрjЙдPš_ag4„ЁЂШЦщt }ХДl ­…Їўxћœ Nh-[3s}dАз Ž2ŠЭйИђЫїЧ?љњcу;ИIF+ ShАHЭa1Zl˜D!С;фУbЎАW” bЅ`EчЪAf*lмfVУ9OбŽHZ‡с1Я~єќЄі>rtўЪy+Ž[рk­Ž,ф_WкФWП~q|МЛHш–ё6З@Й…gJm,!Ќ`рmЬyѕЕe–Ў˜вЧгт0p EKЃ‡БмШPn*ЩU+ (+MЛ\fŽёЅ CnnGљyеЕТй”;ѓ„эЮpEЙ"ˆ@ѓ8sš›ё ПчoЌM?e +–`uŸrm’ЏHT­U&iЌєŸc[ѓч‹rb˜œCЇqЏ =b<Д’4шк8— ŽŠЫыОќrKnф?Oэф›ћб”ўјzž^11%л4mMой|я“Л–џx‡эл4б†ЗіїV”оДbЏЄЧШ”А hTў‘§ў0SQА#І щ: FŸрW№ёђeqLЏсН"|Iж9`]AeЯ8чХЁэщœјѕKŸWи?>Jm).№ю5Јm„ьъШиеЇWЅ§фбwЈ‚!БСrC~ОпРaЩЁ2Я$џЫ/Xджк§žžašмOЯЗ[%жЬ>D#“mЦMj%ЃЩќ ?ўдЫ!Ц}uЩБѓ?ЭŸЏ.‹—Z8#'МѓS}BjЅzG/"aЛЃxQцˆ"а іьdЇЪ=нЯх”>XкSчщЁђ› МВ%škСЮ™'Kбˆwžяж>PFВюё qR/Ѕ„Дdœ*ђ§Щ§I JфљдлLџnunN‘)мгЃ]BВL]tіТžSiBЧаGžв;жЯу™вЫљJ‹ ЊFx&%„fž<ОnѓQ—8јє‰nsџ3ŽЮмџч"}ыжA^^ЩЩ AZ—IН"0Ж]oЃ‡JŒуn§~(љщУпЏ9Кƒ}яFЗыУѓЪš‘aЬЕцщ5iЩЏојmйђƒV 6:пѓ^ŒЇ'Овщ№є3цщZ'ЋE~НS:šЌi›џ>+ŒЋbXАпЈёЧfeћ г˜щнЁCЋp•рŒ6p˜z`pсжѕГWл…чKs_J№ц›8 F›8*h‰юЬFЃЭжвѕk™?вEVХ3уFXд Ч NЧŽЎьеQ]ЧЩяЇЯ?djѓєгcлjYСTB˜штРо“Š„Љ&;k 0šХl0?y˜XЉ Цy‹`'ю+YУšmъ0Љу`nАО€|ФАуіеqРY—ж> G„ЩU­Wш63_‹’zJED“ГКЊ>HиЎТND E< Цъъ`zзп„Žє!ЊьбнКёщѕ9дИ‚+tz7–їЭеџЈQ™~ˆ{„EBпбЙЎ9ЋZч7І9+…ЪFD@˜ЌТK.•o]ДЏ.~КюЃкзЊmu%ЉЯu0пwFs-8ƒС@ІPЈЎЖпѕIиИqА5.O”"€4Тœв3›/єNю [с^љХ`њPX–ЩЩЯлЕќPЪАVUзъќK`Ye …a•4WЙPњњ$МХTn1s…\ cj8žћ‡ця…\_QtЅ.Hиъ"ƒЎ#ˆ@30•›‹/Vt(БџѕОAНеmјЪ/о=ØL0 ?~ќCЛэЏ‡А1љЉЇNўsЎРШ€3aЅЗOTR„ПŸ–Њ}t‘НДpгђухс“†о›ЈЮ?u4э’Mц+ofЈјz@ТVoT(""€4-№[E‰HЎДРКэЯRпn|;ўљчќР№шIЯП-ЅБ`W„zTŠ/:Жo§; нѕцЬ‹щE\Bпž1ЄГomo@оbЬ-Щ/5™`’ЫпНkУžђИGƒ‘АеƒsK‰Rлcm)uCѕ@D+дЕо4d7)S…Щќ>]ИЧЧЫ-ЅKxн…TVjZ=qГиг'хžсН‚G—Я_2яЉэ ]лћyˆDbŒVрќа†йР$Xˆ*ЬMC(…хgTШрaЛ2r_ЕГ №KжФ0љчtъ&)–В N!‰Сіj‚#ŽfЗžЈ'–k4$lџж'‹к…ќK(ЬYёЉŸ™ДqлеcV§ђ)Яи>./бiзЖЭЫ/МTпF‚*р-?ВЕ^ЧцŸ9Мž11А,ћрЖХ3з8šЇIHђШЈžэќhXЖъ•цъœ!/;3гъ!зzИ†йsŽь§цƒ?ВrЪyМЭcп ЁSwœЇcћєIєвСz8§ПЅПВЬиЙг€ООŽ‘JЃА[37ўъюугЃs€ЬžГєыХ—Ђ†wчџ5В@‡MO [г3G%"ˆР-Шг%ЏzR$•‡ЫмП[кK/kн*PAbJиЧЙоC‘рШИhїо?ŽЄ.ЇKЮЦТЛюкMuhйКМИБoявZiьъџѓћѓожvؘš•уYw0АŠЭQ”Йы№СЬрЈ_›ЂфсЂˆfЩ^дŒwMOHє1žиОяŒІп„0їf№ŽXГЮш њ ˆ@‹& 6žэtш)Ѓ{в:эФ…гІ FZ,&CJ‡іяН§^=ЋЮыFк-Ж]чhї{Ÿ ‹J ѕЄsўYЊp ‹жТІаџ ЕЏ:лlД9јkМ§ƒw_љфжФrВ /o•˜"yJЃ•t`›{ЛШ~џљdnћАмowP bЃ}ЈУVЯЇrЧЂ!aЛchQЦˆ"аФЖŠ€мН…МШBWЄй YF'&}9{Зњlѕ АŒ>$$bиаaЩz’$IТqљ"ч(vˆŒрыFaqŽ оъaЯГk„­В ЮСГіJ7Ш‚`а;Ž'нF Xђзв_ЇЇя+ю§YЌ?š]Ћя3ЙƒёАнAИ(kDh8<}‡У/СЮž‘RхЌ]9r цЁ‡„ъФ V–^_ЋHЈ“2š–ˆiP1а/RыЊеяќыќњОƒМ/э\ngЖwŸž>:qam•Ім§тм}їџАCп>їєДфёJІnлЅЇvеТ•{ѓлŠ PKkИщЏ-t­  akШЈDИ}к’У§7 /ѓLYшўќЯ/pюяТЗщасЗEЫы)Я90Ћ™ƒН:ЋѓтbїnŽ6;f.|тŠ‘љЅŒКдЃнмХxОƒЗYx‡г7$єг\Ч8­щќфўыWMњ‰Ѕ8&ъхХЏєы*ЂН{=бySNnвНmCдЕїіъ]QБQ akŒ(Dh|А;5cgЄСmB?<Ьt,ЁxaаW1"­•тgœъQА(ъўIЯчDrEШ„"(|шЛovyЌФ`bE %tРJ:\QїO~a$'’СJ9ВЦ1.ё щѕњБу‹`ї3БмMчЅ’ :†;Œ'9І]—„=lB €C xЈ ˆ"PПHOf(їФcяЛ{‚€№LqUGфxЮ+TwпK}ЋЏд}€‹d №7щ„Ќ‹+д^a*/aЮ ЏюЬбr%- W Ёц1l"MЫUўQnн9-'Dс O}>Л@3ВodŒіДv&BЭL [3?T<"€дE€ Щ DŸI_ Ћ;AУ.жѕ еКU3zѕХъИ[зq[•ВWXLvџГOyДŠѓѓ@Vў5б6ч1ЖцЄЪFр —(РмЃх‘{p—aAа“ФQw­Х<%$l-цQ Š ˆРе8–ЗУtж $tкšѕ=†џ‚WIZf§BД Ј*ˆ"атфœЯ_ійfЙм0ж–бњЋGНоПілWЎVŽТDZеЕ+c‰5.ТЭkb^‰V•АђяеЉЎЙ‰N›™Жf~ЈxDИАА W_ТŠ\ІWb‚АєЙKeѓ–.НrБю#жfЗйR,–ˆ+_zpХNF`][е[Мgй,6ЎЩХ”`ЄТ;,6ЋХЮ ƒŒЮy7ч`#ЌѕЩЅ1‰ЦыцнЬwЊi3W ˆ@эЬщŸћЌ{ЁE0ъЈb lе <ГњЪ ˜Ќнз­?ыбЕп€ўёJњmLж–{O›Bшук’3gžZћћ† |ш€‰‚х8WqjнжЭk–‹D$cgaP”Ђ) х(Х’гГkˆZRнџЛaсшf“@ТжфШQˆ"pKpьœziуYСсЌ›цйxwьч6WLџošŸЕ0ѓьšyЛЮXД^ž=’=aRЬ’•yўXтЈLЫ[гџоЖmўќ=XgIDTTPЌЉќ|Т“­fŒДЄ§Нc}І,Дc—˜ ѓѕ”гh%іMЁ7_$lЭЧ•Œ ѕ#ЁќkLgД№&3kД`3n0е/ie,С‘1YџїКашРаЁс:“aR%&ЉzВ%™Gїчe\v“cY—іŸЪЊ•‡ЖябО3dQrLS`9э–0рЧb!‹1 Ў5:ЗTљŽЈzЊwМ T"€ ЗIрDšёеyЧ0№Dbg”ФНАŸИ…мРББHЋвy™їялцГ>ьБQБЎYГ*qтђŽœ|Р№ЮЙ'^ВЂРk@hsg>XШї›ј№€ ЮRЄљміeгwd IџШ0н•сШšы ъ_.ŠйєА5=sT""€мZш?јmЙ\Ђ‘с:%6wц&цД0nXяРу ArЮ…жњф~‡—_<ѕћeŒФ9.яи‰Ь,6МOЏž}кЉРХ?tсЂд'/Џ№ф}ƒлx@‚ыГ>šЦмKKˆ PНB&‚х—V­ZяжЧ?2 ІАеš[­o^qуЖ aЛ-l("€4 SY'w,ZЉё“{GэЬо8/чGУŠВ'К?­зыеjзЮзѕб#ŒГšХ^ЩC‡vїЕ™З`йžщЧ:ллxˆaіŽХ;ЮГ8Aђ<ЭsЮnXЌрАЉ)Х SyNp8ч8—ЗrзЯХк'ЧuѓХx‘8~ЪcюДоЯ] 0p‰CoЦ:m8Œ˜ђNH.PТq;A0Т@*§:ш№‰ИЊ>_“@ќя‚„эПїЬQ‹Л‡€ŸЮП]bЬœУгЭzEWшуHш—8pпО}аc yhr==2ЙRсу›Ќућ9f‡IуХ}{—џЙхXjЁ:2ЁзC{v–бLЮ]Ї.ZН;ЄФ+ЬйЇЖяЫ‘ЦДвmоЛур6цЧuЫ“ž0dxBљ…sщ4чюЅVHИГ+ІвоxюšE{В.IњMНППHЕœЦ,…Я›О|ЭХ‚Ваž#BŒeтŽЃ:G‡ЛгЎNмнѓ,юЂš"aЛ‹Њ*"№Ÿ# Uj[ЦПП.S,’в4)Еjz'ѕЮrЯ –ЪЄBЌ7ъ ’хl6‡1/їдс‚KМ.,D-С,gч.ŸћйnCB|ŸБ‰…GЌ|хЅ19И<эдƒe1Ё­AиЌEэ8ЁLђN$wW*ќBЄ1НУ‚У=Х",wчІП”DXBЈ‡Š*<ЖmёЊKХњ„Ю]"BJз-{oc@€gЛ$ЩоПБфrфФЮm§Єgч­оyFщб.>,дvсAс@Тv‡РЂlD Q№$N2Хtъжс ННX;g/d Ÿ[4mТч™9Т’Жz,ћgЫ/лO,„BuH‡'‡„•fэ>z,?:hьЋc;Зr3žѕўў‚УGwЕ+іхYя`РрQШ›gX+Ч9pБ‡TМ_›oзё§"§"ЪЮБ6’ƒK!€Г’ uє}ваSцг IDAT+Ф№—љф/—sK—ўsЦ{тФбS{ыБЫЁќЉіѓlMЏ&ЮФшЃQ akTœ(3Dh<NСР[…ЖкљщNžхœ;№вя/vГЛDFЋ<ЅOЭxъЉЎЯжOз@›0Y@tЗЄђјўП2 ЙЗ—›„+r˜XЉ6<04RGS˜Ц/@хы–e2Z<ьUC k „€у4Nа№'IRN‘J І™"X4 Tњ].aу-X@—v:DxiЄЌ\FLЊБ&{9Ћэв>аS/бИoЂŸDuтЛ’8ГGO вjЕё3F9"ˆ"аPТћ?§lњ‹“_œћ§мш€(ReГЕ:ЏŽgc""rи SZO…‘щ}b{єјмˆю>Ѕ{Ўк{Њcœ+Зй VЛрH’clcwn‚HAP$˜–XЫr-ŽЫ˜` =8duоПЖq&QKШyŽ… aЌIX’/-/5л­nХ.УФ],ХCЃзТkмsдck\ž(7Dh4.љџўЧяe2YІё"ив^ЖlУщВЂ7к/'7ѓЎoqЮ­ж(ЄŽїŽМ№ы7ЫVўІ№˜к'мгsяЦДѕ[ЮКїѕШйКщТСџ>МДЂ|+~љb }ютЩ’­+ZЕхbриўPNЩЈЫЫŽЇuoуЇїWRчДrtua3AёЊN0ФMфкA+_§ЮяЂвKюхлж­8u>-Ф™ }мAЈЧvсЂЌD сRSS'MšєйgŸЩЪгц‰svђй%љrЦ 3jэ;]W(ˆlэ…>%Ž8pШ=./нПnСЅј #FѕzgъиVуžyынcЬ}“;К‹%>э[ћЩЪW=ѓђ3юЬѕˆNŒж‹OЫ”OR;цФз“ЇЬ^|АШ—ЄЮ-Hс LJqМђJˆФ2Й”Ђ RцsџЯ0(sу†Ѓ†ш~cћљHЁЫ‡Т$€zlw.Ъ@B@pХqЁЁa , iZсІ<іэ1Ш№`кџњ~жSПх”WM„нИ:bФИ's"…тQJЏnO?›4ЮF)•J•hРЋ/u˜Tj0Г”\ЉѕP+•bP'm|ЛЧО YlТe •Z kиH‰^—TPтЇ П++ЗЊќ|д2IЪлЖ&Є %ь_ŠwxыУV•Ч˜Wїћ?[УШЕr ЬДљЦ~)Ј—еŽ‰щŒЏIМ=нuJdyужРЛHи%G;EР;LЯ aп{їkАл?ўаЭ!@ы0ишкhi§ѕЧ3ѕСк{žщQŸтEr%-‡ˆ•+ІA$ѕ a :|7З›кK˜ЋŽ;ZхххWAВ„hUЗH‘{€ŸЛ3!\iнЅТnоBж8гKсgй=ёYtdЇњдЖн{3#ЌЗ%(м9Hию[”3"€4ˆI‘ё>cоfЗЎ 0шž<’”ШщzŽF^=њж$•Ё*yхфXѕeW|јМ&aЭS˜VЋŠбЎ;%ЭuG§ж„1‡Яч˜Ф>NJj›Ўе"Ч’еиюШЖ;‚eŠ B'qЉ єеЊdЉЮЭ~C—и7:ŽuЊ˜Y’АŒ…;L лŒВGюz<цАc‚|U€A;ŠўЁP‚+g‚Bvzѕ@еhQА5J”"pЗ˜ѕсџVЯ\sm+87”х…WЎ$Їrч•к+Wа"аH`йbУsBТжp†(DрЎ'аЕkWp+|ь€`sXПYПh("pЫ(ŠJIIЙхd5€ЉQЭЉаwа!"€ќ—lнКеh4ў—ZŒккB јњњЖiгІ!•CТжz(-"€ ˆ@‹#€f4[м#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDh$l Ё‡в"ˆ"€Д8HиZм#ABDhЊ!‰’633w††d‚в"w5žч9Žƒџwu+PхКжuыŽ^o6aƒџЬ‡Уd2нбцЁЬ–L€Ђ(­VkГйъSI‚@у+ѕс„т4)јeжЄхеЏАц6P5‰DЂVЋыWU јЗШЮЮvss+((ИiЇ њvљљљ№љoC€кs7€/ЄFЃ‹Х-э›йlТцzš№s ыv7?\TwDрvИФЌžoˆџMрџ‹еj­g’лЉгIуъkЖЬŸіЗнтІo|a P–eoЛЮ›є О№Е„ƒЦЭЙсЙ5ГАСwž“нnoxKPˆРнEоSЗ$Q"‘ЈИИRIЅвЛЋЅ06џЭ ХнUэзЖММžŒ9н8Z#о…їdEE…NЇkФaТž$ЏЕЅМнA*žБ9pZS)]—mƒjŒa0zfЗ; ЗсЌ6BЭyŽхnmО’YЫ ѓЫl>оkойFgЃ M•Т ’žЯВа@œ$3Ÿл}Еѓ†ž:нџlЇ@ЅŒт,FЋГУPцА[,fR"—‹)cYЉ'еj%cЕ‘4 ‹“ˆI ^Љ,gǘь ІTы”Дщјњc]Ц›RЗŸДytАЦйИF5ц‚Юы ѕfž`r~~џНс<Ѕ (BЙIтцІ”у›f|yžŒ~o/„Ј(-uр”JЅФX†уx‹е,vsЯјkuЖUёиШЁzмpщ’Ѓh•›˜рŒНДМ‚ЧХnj4ВЌЄ„IдJ9)яи#avAЃx 7цŸy§БЛ>ћ›g&ВћпzцAѕƒПЇDhKKЪyъЉ„ўkЗ–LR%д›ѓкѓLЋ{ящнЮM‚—C…ХjЅ„$аl1‹$№єЎ]к …трЧ”ШђV~тЅ—tŸ4в3йцжЮњыИmдCшi‡ЁТШтЄJ­сŒщ?Мљ}ћgоI ”CоЄˆ‚.%ќ QЦ:ЪЪ+DRЙ\˜#МN lPЈеcм Œ‘А5JŒ4%*aГœSkтR:u R)ДђVффIшlrз/Ÿ-J™|с§8іь—ŸN/рD<џ\юњщђбŸu3ЎћХ‰Г?Эšѓ~Њ>6gзњущ—"ћ<ѓод5­vиь Ъd1ЋеТ9ѓ—ИKирu С)lR&ЇАђЙя~—jАdŸй-M~№§G[­^єнŠ }™HеKŸљЫ J)љ#ЯНЋ.ћю§?ЮSЦ?YБїŸн›гщјЮ“#Š?ћr^Б{фЕi“Ts>љhѕўtЙG—ЯzцђЎ3fЎА(tП№FлHŸ;7@чъБС'4 „ЭjУфъэ[fŒЪЯйЖ—&zњќЁuѕ[Оєа;ѕqџьэ7O^Внћд[ƒƒ*ц/››Кќ#ўE’јфЏ?-6+tOОќЖЗ=cњзЫв)гјgпэю*WѓЋeЙЄ”уIжhВ™ЫLкsX%VђУGŸ~Ей~W>о]іеч3В‹}&а[Мь—…ѓ—ŸП:zчЬНЃІMЅRзГšќєѕ”й_ОЗъ@Nїa>4b ˜‡СэšEеыи%lѕŠк‘АURoБ?=šу[ЪlLе#Q Яо&№В†Гl˜ХКiљRГПOЏб§‹ђ.чŠеQš’ГiiЏ/ZиVk|яЅЯ­a“йЌ9‹ЖочЙvС?ЄmŸ({эОїя8bѕDRп„ФS7~4koўу)Nџ'0щ3DBц№б№ЊVчЭ‡jWеœчa\ЬљЭ:ГХœјфЗ ?rsХSэSSНК<езїС‘ЙwЙ?ЁјфœЅk^zідГѓu зœ:пКШЛї”)„Йєѕз|–Ь[ИcOj€%{жnёЊežУUd<9э‹ФO'6ЯYЕ9њ…‰bж~‡fрuQн(hХŠХЄŒ Аgюљk­9яlЯЧю?Ы2ža)ЏМъНvётЋіlпvзку#Пž=ИM˜Rъш“дЖџ‹“SфУяћ4aФ“Ф‰-П­ођH;ёйє o,ј3VGкс'@5AчЋDсёА0`k'5б|4тЋ?]јчвiгоmлmм)ѓв#їИйŠž{ще=W,XИmТЌЛЦИїНЗc•is/dУьk2І"qЎtч’!М9~P7kanЋgыjўеulAgHи*X$УЃjAOUхпB,Тa2ІQф КАfH,–IЅ§‡ŒьцІvWžЃD4-тIЗˆ˜.‰‘оdС ЦЄд‡Зm“’Ђ ђУ/­™љхЊїŒ™6ч“i­ћїf.э~kѕЉI#;ШŠd2)IРP%M‘B.;G\БJhјC€dџЙ g’фЁ(‚Р)1‰‹ЃюнЭCY@K”RБDD ™R!цX›Ÿ^и>ЅuwЯPЉх|pxч6qО4ЧP 1mA„П~sQхущMJDŒХЊQFyЋ)‹УbААі w_мШ) п9&тkфЁсЭqхEРи'зŽ žђхДИ6Ѓп]HЗmXј§qs@”—w!І ъ№Ыœ/ўёгБћ†­ўdХу2Й›”В VC…UE‘ћ#c:'„{’†rіК3tз\%’$tЉёјоЬJщџудgVќЕwˆ7-гjщ_ПўВ9[н%ШпWb”He"ŒpSЉe"єїJ…бj&E*RќХœ_џј}ЮШW/LџxjЄ ~м2'x №­n,žžЯuќН„Л!Cxщ,\И^@5 Њ+Ž:sе(аС д*]eee;wm˜’ЙAкzо‘€7ЉXL“ХZ,*?? A3АjуqI1&' …{`‡^­чJ- ‘{jXПˆoхёlщƒїєoћЫŸy?њ†8aжМЄМ Л$§є…rТСP` 6)!–H8Ђ1&Рџ)xз6Š3[H(ЮB:Xœ" 3сРХђ@_я%;6яьлЕwрўѓg}тоМˆЂ&ьџФа6ށЮ$EXsŽe—љHАМ#йщЃw‘`|ѕ>XэйX‡Ў]=Ož>"RИ џМ`Šr'Т5ТFSИЁд7l\фђ3QУюз1ГьŒ9їxV‰ТГX“—–Чf_8Пџ’96JžzЈ„%Q‹vЌ;иjbЗо' ТŠ`-‰Ъa&ph3-Оў'6М…„я”R‘XbЙœњЧтљJ­ЊљyљщјђХЫ—n;Tq*ГФ(/ж–Ѕч_.0ЫCдьК5"‹БуѓfЮЮ\Д <ђ кZИч|^PЄЏьЯbжDŠНФ‚)Ю-x с5]є[["кˆѕgBЅЅЅ^^^аГn”џѓ Љ<Є3gЮДnнК%?Њ†4Ѕm№2ЪЪЪ‚ЏЗŸŸ|ЯЏЉм…^ббб………7§ё_QXmБXТУУѕzž3кДг+Ѕ—ŸК:иЅгЉFRэЉцвџЯоUРEЕtёЛuЗwiюlЛЛ}ЯійнŠннOБADХ@PQ Ѕ;—эњЮ‚њЌЩ{‚oюЯŸмНїЬцЮ™sцЬ9/Š][К‘`ЃСŸ–ЯsnкЮлJ;)6ЫХЯ,JRт3ФT''лœИћoEйXѓxФVmZcy1чЏнЅrћ щЈ!Ю9v:0ПTьюлЙ™Ћ50ЖŸЁќ eЁQIIIpŽ f0ш/?.:ЫЃ­ЇДЈчj‰Вb’ЄЦтЬРє­­•‘‹уƒл7*DЄV{ИYђs^œ Šаrэиг?zќ,œa№№ыьЊ‹ПN*qmсFњlЈ%0BрHxrrrУ† ]ЫЫ2/\И№:‡ЏiщмЗGGЎВькЅРtЊs7ќr№mŽЙ5.,Зmд‰[uс~A‡žЩaз"‹\}œЄИQ[gъЉГ—3ѓљž-к4uwћЬ/ДT]ДњсУ‡рO  Њ]еAй_х16UЧA'СЗчууƒ›КqŒžџpŒЗААPOOЦи'5ќceаЎsюUСE>ќЊ9юиkъч›7o`Bџ7]oРv а†ѕwM5с'ыкрщДv2Жк+KТEЅСJЊєПUЧ\ЊN~ќdЈ+ЎnбЁ.?zŽјО*}K%UyЊV`<я‹€1vJ_пјкOГnLУAњiB5ПпšЇЛБOш§˜{5Ф|щЌW***@§RІг>Ђђƒ$uЯ?ШЂК…wK-аuНCы‡g­o|щћw}rя§хšЖOHњ№gmel`t$* КiрйЦйD4#)їЏeвl›ЙТ™Чšд“|ˆКGдf@™iii џћ'№сЗRЩ_a6ƒЋЊ‚я;…М§s™ѕ3Д$ˆNЇmС4сГд/gfI˜ŠдЈu+З(ЌМНl "7OлњŠйЃБ§“€мj1АKНwьџ§Kkф–Y БUSTWсЏ2tЊA ЎI?љeK Z}Іmn)/^БфЦ•#<#85kгЎe3g;утДY|™B$ТZЏ˜ЛxіЄЎR‘ѕŒе –Ь™/(.ф—хŽз2ppАwЄDЦ$gkкћњэЬiъ(ЋLhа Ѓ0фpѓ^cƒЃ’р–Ёys§Жy:ђJyЭ; ^4ЇgJрВЫw Э-<, льbЧ9=yьšћ:ѓNйЙшDDђЛ7а[{wŠнПА§ихQ/Г17'>tчЩ›Pэ§Р#Ё2йLйЅэSЧoПялНEJрі‹с™…OЏ m7Œ]ПѓдЉ9кАпв•хтжЖ^.ЊИЌя/~FЬтг.Ъšyj­ыиѓд}э™ѓ&"vўљЧЉ’|8фud~љрв•›Ас,Пsdўд­мКрІŸZАnwХћкпзˆn~G@"њT:Ї3ЩpЧЪ&\8№ъњЉ—Ёч_„žЫx!“TЏPHEХ……МЂЌш‡_Н)x86оѓgŒДт*Ыs33s*ЊЫMЮ,цС18вШ ‹LШ—Рщ3ЕЇщЬЭџtѕВ+ЫТ(T,Х(К†Ў6ƒŒƒ^цнЪ№“:r%д}ЬтЅ+зn\ъoЫЎи7fЪЄЃз’RГЄ$Ч”ƒKŠbЂЃ^МЩ[NZє$ђA\BКъЇBZR\X^œѕ<>WС+)уUЅ?Œzœ[њжњCPјрўƒЄ4еІQFш…36\К“_.v7wяСУўЫЗ.hЋwђФuuЇ‰qYqёЙugѓT[`ЪЧgІšN QdІО„šу_цT}pтВќЧ<|є˜'ХЄМь-У'Я:}3%-OEd%СБЯ?&8юЙ№џлjЊ\U—BЖ~т–ћаПїmZw0`v“zыF,O‡œЪr8­]”|sђ†ѓCVЬёа§ї"ЦН#эзџ­ЭЊHчEn3kэФЁs6ьЯЅuDR№NZ)VфЈ#ЧpоŒЈmmYд<Вœэ`mЎЧЇ1)pžS.SˆЅ)QEt{поnFр œСФР}ИzдUœ­žw—ЃAš+–ЏпНёЂcЗxИКyj5№ыd[6ыHXLм­И—^њfїкхI1e%ѕі^<уЁUДoщьS‰eŠ2вЄ5{zБїMяyKЊЯТ­f їоНщoОІVцг{\Г'f“SЯY<#•OSH зюYŸ–™§фсщЕBжЪMыW‰hЪОœЎЅVTШz6FyWNЦMv.Пx*нЪжNЁKy6,”UœћZОlџёvюиі)BђХLmюŽS69‘ЗгS%‡Ж2'Oшюvdем“/KхЅЄIk7іђть›бу–Ф€ІЈЗёрѓЯТ •ОŽ#юX0šЉZPЎœ3,<Ёмš…чfE­^х1fїажРўК}7UжО&УЗ!–Щ„rЉM“>sЛ7Н}я@BХ*2Я_ щ5vмGY^aIЙќŸIERpф щЄ<8 2щ€шO †n3К6›ш9cёŠЙSћшqЉќь—wуaзьЫшm l›n;rХџ/п‡O хB LР"фЇwЯнќиЪоГžž™Ѕхbiх™}%јnа6ВЖsђXЖџиˆ6.я^ЁВJГёъ|:јFяІzkŽнpjжнYљtтЈaw†=л[Ш+Ф Ж>‡) ­рU,`0‚|ЏПЋрн_&[;5%ыю е’жХзЗ­HЬ‡ s- иЉ€U!Q&ћИ“Ы„JЙЪАZХѓUj+q~с S•Ф&“ *ўwЇR”клљ@,Кj ј(2K*вyŠR Ф‰!ъаЩЮкTS.ХRƒфg@tгРˆeyЂВ’jпG ^хч9w›q%фЦФ–ЌЕ;ЎTХХ… бОыА! ЦЕяаoьbї Ѓ›йkVе њПx xЩпEyKу_^фѓRŠcŸ&?-хЧ bn<ЫШЬр јеWj/AСЩ%ѓFэБіј=ЖMЋ?›Yѕ^АiоФОTY>_Єяй?№ЪY_ЃТА/žо?Оъв›Ѕ[іщЄpКDB„“g­ЦяйНк/LЩk:Ф?єЬіЂшы/Г nxDhЙяnЬ€рЧоЭкЗювzщБЃ\Ћ‰ђ№ПW,y\oбДоъDЉPdбІї№ЎžWпLЛЛ=Г§а§ќј‚ Ў5vўКcGvњ> Ољ\Z‘xѕIЫЉ+N pзХ4œл inбoхži#:Хпњ{хХз@№иЮњGUЇН~ЃпjмО›ЬhЊяї“ БhБЉo‰H6NTnrz]“tgчк3љcДW#љ~RгoјГЯm$КЃ>ƒ(”р-ўœѕGп–šTŒm1К—пљѕ ЦeДint ”flkmЄ сpЖЙЃ›!%"R5эm ֘Эы}єУ&:~к‚ф™Д8.(ќ‰Œ%еєЃjŸC)ПsrыкGƒƒЮ=|šбФн –ЪхGжяN+*/ЭIKLiсыœ—Љ1їžЪйZ’7)ЖЭс1ўєiU™'"KR3KЪЋо ю^НѕащрРѓЏВЪ›И˜cdƒ1m<Ѓя‡ cDV‰Т žDХl•bЁ˜'SКИw№Ьz:cцњ“ЧŽ†FО|ombцбuUŸz3†пp!єкйЧщe*јЯѓјдtшkcДnщђKAЇWЏ=иа}А!„”OўНeе„g’ХШDe,\y9шєІН7щджф‡ЭыдˆзNРeЩЈ4ТрUЏНGђКЬ;Њй.4[’^!+•(ГЪpŽ‹)ЅЅеAУєmњ4weвYVж‚2ЌфРл#˜жєФд˜;Q9ЄС}МŸJ цІъЊЖКЪ‡—ї_v(u“ЄXj}оИsЅlKSѓВђвНЉKchWd8ЌЬдVШ),§бўЋwь8=kШ—d"є4и ˆeš6КћjА€RD‰H%ќє“‡К‘фцъF–‰8њН§šiт…@ ;§ZX0ЈL:'HФЅ˜зЦhѓ…ЭЋ6Мrкmˆчћю!P5&Ў9ЁГamPа‰ћJЂЙo/ ] ЖWwF…OШИo'mэ’SЧ/i7žЕ|Z?јNКM[ПэиSRЫЭ››ŠXF ЪсКZRай MŸ3GvP“@з–~­ tша!]]:.ЫИbEWZs ]U†іT ЪЋglDœ,ЮЭI|Qа 1§щ‹$ssO*ьu+A№Sщ6,иоМЧˆ’Тk„oж †+и+Š„"а@li№М[эsqv?nќЉ“ЇЪЪЫ{ЭБ­Сl’RžPƒ]ЭL%yXbюиЂtФімЫиœU‰Šˆ ;яф2Ђƒі-їmQ ' bЋіЃBњєъиjхеў-Ц{KМд˜LЌU=.•eя~GpEІЊ-*‚ЋЗ+сš6єд”­оМЇЩЊПИDўбk#–[œЕ__•4gk3КKЋIs™лW/а§n{Ѓїxзе›ї3gэk|rвw;ЕЊSюoзГОЙ ~ЊЮ‰IеђщМQЁT€&Rеx$U€‹oPMVў|—AM[сs…:=;њЛѓЈГ4hеї`ЋО•OŒжэ}ЫДz R=№э>ўUenоoiѓ~UЗяў'3; гaшЛŸЊПтэЧТЬКѓЉЇВ &szœR™Ью<ќэKѕ;n>аБђсЧџ‘ЙfЏ№с3ƒжУœпў&ВMЦ,л?цƒTsvћЕћџaaйkmЏ-ў+ЂЕџЃђ_Иљ*"""$$фщгЇpЌиЪЪЊCЫAEХo„ќBRYŽ‚TAІs lоЄџ2IцњqƒkW`ЌzЛ–uІeо„“ТTЂ2ќф†HF“€cЫ”/B: Ÿ~ксм@уƒѓІю )р‘;tШи~|Ѓƒ–jœr_ЈбЃGGFF‚…ЇЗЗ7Žг<"hЮчѕкjnnr№юžrў[Ч'1"…Ž•ьгя›"WшLZЕНiпСѓњO^bЛaJ;ˆšЉ ЯI 18К@ЖcЋЫGМšаЕSƒцн{єьAОŒЊ Њ,:­rAHІВй:2"Ѓћјe‰“Еm~ƒMSєЗuTѓfфэуtлљд‹Ыa’ оЊПzЌ–ЩЭšЮ8БЁМфѓ ъдтр MУЉЛЮћ*-иT"…IЁ0мДЈЗwЎŸ_g]ƒ‡Ž†ћ0.Ю™Ÿ@Ї№Œ›-n ˜“М:vнhTЧžГяZ9єПf@ђуY>якяzRлœ ƒЏШFпГяjХїg–Ф=ŒхZ;™kџГЇ[Њ#Lў":ЗtГвўя­пЊƒупyNС;иєЋЖьChВшА&QЈD‚Д5т€YZ˜/445СЋX~)/ЇrХ+WBJTFІPTt*DyEr"USKƒJ!Cœт2О†ž>I~ ф2ЉT%чQш,FѕŸР"ƒрPч;КЁ@ d№Ы‹*ФDmMfiQ9K“ЋT”V@0TНВ*ЅМДЈЃihА€ћ|H0,)$UПЋВšП Љ +;WŠQєы2qеєЅrCŽ*ШЊ{9Р%'0еэбUSйї=’Щd р_З:AЎХлїќSЙaЁУF999е:AVЃPљБ7ŒЌ,• ~^о[;щЋхЧJщZXРG”—_(КjJ‰џЃjAT‚§-`i5:„>zХЗќр8УћѕызЁЁЁ~~~d2…­ЅЫіnѕхШЌz w3гхъiОT@‚WN ржч}Y8HPuOcЊІч/_pfd>ЇИИ8,,Ќwяоž*Э|х%ялЇџЛћjў’Љtжя…\m§Њ|МJ:$@TЙw%‰:ЊCЫ•зЛ  ъ!уU­!@ w™‰4нzFяђb:[Ÿ^ЉлРЉфwYоЇ~~АЈт,|p“ЋњХфМ]ЦъшУЁi У5o mT? $ RuЃКЊ'И*­кџ‰†‰™х‡IрŒщ=Н$ъЛŽљ0Чр16U'УМcjj ЎгkГ[ЯџРhќ ›GГA:љ\\ћ7›Њ­­dЈМŠ+^^^FFџŸСПL nh5Ю2Q|9лwЅ^Йr|"Ct1(!5ргћ 8Мш#і№AКE|+ˆБНE –ŸЏИПE”! ’`\§кЁ4€іO _y vM л}%гw&C:5%@— чёJр„6‹Љ­&zŒј:ˆБНХшзN=_я(”Ѓn"PKЦьх&<U”rTUZІж=Ук‡ЈЪЖ1*:šL&ЖhоўЛШSШХyЙ…\z ф(юЛ€ћM3#Ці›v,jBрbЯ|Мw1C!чLхr’ЧР‰­ЦљўЗхЉб{ƒњ §УŒѓоNтmq^кѓѕЫf„%ђ˜:&KЖьє1§`'щƒ7мIИsуY(›D†ƒ˜2*.QТAN8nЦКš‚ Ьйащƒьм*чЗЏ Я’qIJ1Ю:jšЃU)‡э-Ђ,;eщаэŸьfђ~ƒщƒ‚пy ћРЭ2xі‚ѓ iw.ЎйО!>[jкА§ђ%ѓ,85,П~'ie—IЫ‚ЖЎ?xU"Ѓ48qб˜žZ8)>pЯ}’ћ˜Ў^Š’„ѕыNyў9ХЯЎњŽјЈЎпыGMЊЮ/dPkП pTK•ЌY‘ЫVŠˆр ИP˜ž(у—ЫФ"ЉD Ж‚рЕчл›JTХи *Ћ3C/KJхšwйshokУт1ГЖ—Нї/№qэх"Nф7Sфњ “u%ЩY”єщГW”шWмˆ ­Е”LRУ<фт˜А3ЉcїњnNN\6§ёžу*нё%dnƒP\ ˆ'=пА7АА’qч<|си~кЁ}›1“з]ќЄ>nѕ?№KzЪф9WF/иЖcбјчЫЧ ›t6хG‡%dbrўЖi§У“hnжџ9ЎP#‰эoЈJ„@mBФ…,RјbeЙ$#,уоеѓcлQЈ4™ т’†‘YЃ‘sЙ†цŸS-)ЩЙ*Ч%'O†Лu[ьџ…ЃaeY‹+^ŸNтŒ™и‘Ё(кяЦщОZw™жZU‡vп.ћчE‰”\№ђйE"Q”МB K+]мтUфe‘‘™D г щз7w`“№ЅАњsнЊz4ЖNћЎієRyрЇоБ|ѕcƒ0оЈЁC:кт8!%њєё™g5э:,š?ŒKС2Ÿђ_w†ЄпhљЊщњ”’а‹JбƒШќ?Gty•˜…KгžОгnрŒ‘=!ьVРќэRМћјЯьw;pЇџъћБЗBGјЏ№›9ЧЇВ Ѓл9L‰Mf]3ЬГВЮŸљBt­>ўhкЖKлЙ`XƒƒћђZйіpХ0 ‹ЄЃIК~|ЭБB“Чgшќ'mqФі3C •Eд`_ Б1%“(гЅШZт YBьEdљЃ[ФЧз+"Џ'_љG+ьяО•O=Йџ.ˆБЉ№A \ХЦЦ‚У!=НЏDМ§w;Н­–"ІCшф™ЏF,ъ:lяЮ,ГІ:ЙUгЄЯљЯ?Ё›ЕX6Ќс‚љЃLfЯА$х­]Заe~#ќ†_P"єЛdщЋsњ6Н=АЙѕmЃ­і26pHГУџ‡ј;V*ЋVяѓџ\?v~ЂЃЃ6lhkk~H~Ќ’кV lзРhьн>DБЖYwщTIS“ѓ^PKK‹ 4ѕѕСk Œ"\‹еАћмБQБйЭМMФ•‚Х/i/hзЯœ9pp8FЛѓ„u4Qi^avYъsbyОŽЖžЉ{уjiSHLsнвтg‡9ѕ?КЃ‹,CжЉ­Џ.ЎLM+ъГ`Qf.˜ћвмŠUЉ9ХЖ#GŽ,Kzz;QI1ф шYm•иН{їЮž= œ He2  ь6 ТЦУ ъеЫ_]VЁЦс™бЄ}ь˜шЫW`авshйfЬЪІЏ7мŽznлЮЕUз~ЊVГю)vzšі[—-_|g,жЌзPЧFЭЛіЗя§˜аФЕskC6Dюх˜іжпˆAvь3~3ЅdћЉƒЗ ф>“mММ[Œ™бѓft`њ`_ЃVэG0MRмJRb†bћЊoд/xJ  ˜П“fДѓФБ=rŒдbШ‚‰#{3ѕщкžb \КЯћ[(›—њ$VіпclПl!љe'ШD)єXР‹в2œH (1Ф]чcMzії4у~5ŒсїŽ0јьСљѓч;tш‹YpZUœd=pcЊr– Њ™f.еV86%Ћ>Eиh€hU юСi—jљ-|Б „ЊŽ``:*фсњ^jП1?P”™”Єд21гaќрj@E94юkl@—UЖВђUгО‘Ш: јйёш2}mnc#‘Ш) OЮь[7lЦ*}c3ˆA!‘)rxђ8ЩwЗƒ-œOк япq‚œ——Ш?ўјЃkзЎ/^ьоГ—Бa= G$рЫDBFT#Б юБ|tшЕVеKtŸДщ›~Bx20yђd№‡’––#ф6№ЈЫb1!ЮwrЪ ™bffџMuЁLПфљGАЇВщ,‘џђBРmк№1m€ЗАXtœ qGс@&‘ŠурЬ|(РœŠƒS…L BЈ{№‡Ч`Pa+~BД6œB…pž‚Ъи_ vз{СJі­ЏH˜ЉХХGж.‰ц1(Хѕt6ЈЭЃ=ј-ўђ* Yqщѕ”…ѓ=єШ 7vмG ЈЂiT C†ƒЈтЊИ@\6Ш!0 ЉQ•^в•ЪП8ЌxAКTQ”’Œ$ЪJЦ Z\™ t’ iV!ЊjРa"UŒЈdQUдКЪ#ј•‹D"†žECЙ“C>№[I$U.T!$•Jh•ТWЯЖььАdБ7UЂiщв@Ђ'—I`яŒqH•КPа5ЉЄ[’*А0•˜ u~W~<@kэ/hN…H.”€ч~•\[^ЦЋпВ›Ѓw[ЃДŒGgВbEf‰LЖЄ2€Ш/l„†Йuыж@fiz5kєceе•:yђЄКЄwьѓ?!єЋЅќ,Е”БAГфrФt!J!'CД\*˜|[дxз„7сзїzАl›wј9чШ-{4Д~~yѓ.MЦФЖ6Ы'o`ѕшЧIИГfНbѓЊБќ‚нћšr Іi`l№RаIЊ„6d …qІ­s;+ЫˆГ7 вђРЖ[QQRYоŽЬи IDATв{тК3Ый ,§{ћ•цUZtУќ&}x>рxшC“3aсZ§МАэч/T=мX7oy“WЊkц;czџдАN]ŽNM8mЖН(;“/-)3Єr/Ÿ8z)*‘eъоџЊЄ\Q,€•O$ўтsѕG~іуEхъЈ1ѕBѕезрS"НqЧ.щOЎ&$нНp[гЙ‡Б”ZoФ„y+цޘ:КWTјгGOя‡цщˆ4š256ЊPHlоyШˆVжр6шЋ„€*R%MTЪpЃZe‹љёQЁінŽФmŒ)р“ЎRВїмгWчку}§Чк21YЅ‡!X˜ rтwml:vŽџфqК4"лРкл\ПeОM\ єŸcУжЫVЮв-8{ёjŠžЃЕAћЁ#›{YФ]:АхКtђЂ‚ЧG.нХ R"4Ќ”Ьш€ЈТСГMд‡!•%‡œ.%вГbУЮ_}ЅWћ<ќрњ!>нћ•нПx-QX–Иpи\К}›9ѓgwko [ёJIah`˜}л~ŽФИ{я’Єјр{Ў=o9p`ХЃ +6оj7tюДОѕїL]|ыyБR”udч–а|У}=/яH-S№3ž^” –­Zw0fl[ю•Ћз % };єБЬ˜јЩЁаћ&6 ЌMКŒщnW/?><єINУ—ћЛ*ž2ЯпO+}ўиѕ9RJIЪЭ5›і–љvvЉиП!ˆЏ’_ыќ5•0ї'Ш8lVЅ=‹|‘žЋ1№4 ЂHмDМ’Б!Юіе/e@дЕWbћЄ ѕВuoбеіќЦХsKоHЇёХ„љУT› f2NЇD`7IЄ’e2‘І•їT_7MDА…3XЊп$zїš*ЦџCќи”J†X\ё2&B ЅѓзЎЕZ[ў}EoЁ3b^aEA*”‹K/юыeN–Ш*э( T#лц-OoYŸоiрф~Ž\- +GЖиЩГО­ПЂ$њnШй ЩљХB/ћ“/ЏОH)"Т–žІхрСѓ†Е6<Вѕ‚uŸюН;5ж’[:œ z‘—уЁA0nйkнмБzyс{ЙOE‰MХЙTиОdш:ydE YћАЩєm3ћ6СЪГ.\8:9;НœWŸ б7З4Згpђ№Ж5ІчрЮ!ˆю—ЪКЮдИОЋwНПGЬNчa8™кrиЌc{>?›x&ЖHNf2)’:­‰MƒM’’ipV1A~fuњГЖоэЛLлC=Ыхb•*„§ЏРw§E ~кЮиР4Q –‡p)хDЎI{?п€™+ымкиˆ*уE™зŽY*l.^ Бo0вйAпC|Š€[љЕЊW  rљЫЈљИc‹&АєeЌ ь!dя›\Jai Зl€Г–‚HŠЫЩ`ї†г8,кё}[Ÿ+mь4звію':КhŠT!c˜MоДЃ§ЃАйг6Ў5АоллЉbEƒЫŒИА~pтт93C6f*it&їГJ0DcQh ЉЁmу‘kбˆZ&м€бa}OЕђи|xп“;ІЏZiщ|lD§†}кияY5Y$злКЅNр1Щ8[ƒ{z Ž3˜,)‘'€0їl] УDJ'Qt5ЙИj_MA&с„ІаLˆ#Ь Шxх|ƒЫ”f‹љb:“C%St48,Ќ:p œ тФf0йФЂИ…S—=џм9ЙЇ6Ц;АoSLЙўДБ#-ЫЁŸЇ D")‡€šP0Ђар™‚WR!cs5+rЪdb‹Э„===-.М”ЌDЫЉЎ366“$'гUЊH гр˜јtV–—жЈы0]}и›„=Ы ‘”ByЎюшEОќ‘ T„@A V36АИЃщ84iњvB*%;x;š˜эм˜$“KaізІч&GЌZv™cж`Юэ 9фeћЇЎпОsЮu‚ЅGЃщ“ьѓГž?'šјњ€СТ—:XpA˜lЙ\n•Ф&—в›ЩSLОXNa1•ЮЮy0/0чЁ€žЪзWлњЯ^чyu‹)W!WyЯoЛШЕеа"Гt5ŘlM=іц5›Кz.Є‘тТЬ„'wвт3Ъ(1eCъkPdЖ9o™жБЭ€KgW…„л:bкrJc7’ЬI™qwNХjБdњ4ŽІчъuыкoя‘Aь ML40БL!с+‰8ƒЭ‚№Ьb9Щв­§­Н+fЭэфg‹г,‡ŒhGђх…ЬФ7)‘С† %|9‰JekДhб§РЙMЋ7i˜VD—ЪtїvЇ'<ўDcB.ЊH #14’ #t4ˆЦЬ=ѓрљижМЃлЗpL<Щayvz|єнмз™‚л1УZњрe7яА\7‹Š#WткцУ[ћЭ=Жg'–ёњжQkЧMЌuУe"БœШf2щd‚@ˆQсNIЉыŒMK“Ђ аЊ Џ]ћщыы87mЇ2ф&Вp0ѓ)Ш.bЊŠЌ!ОєЂ4„@Э":З_Ѓ%љђ9Жї$(42&KA$ЂQ W,оzƒѕїЮ™уО<{с qžЛЮŽДgЃ)„šЊ4їЧ)pШ fІ}$JK…bи{_e57344длллХХЅ*bНRЪu_ЧХ瘎2ж3Щ—Тф–M9™wŸ+Ќк7Д‚ZјyIo'Еhпкˆƒˆr~aиёs/x"=Ї&=ќаЩXIіЋР 3яіЭЌ9ЗЎ\L*!6іrŒ}оЊwgМтеЅkwыЗыыc­ŸїъцЅx’ьеК“ƒЙЪ‘@рчЄ\Мž'QX7jзСлжќ’єkm|§ЇОкЭCWЉ$<ЧЌš9аRb"KЈ œъЩ+вЯeђvMЛДЋŸy]lвиХˆџ0Й\ЛeГ„{7IжЭєщ@|іГ№ ›qb’VЋНœ ™ќœWOВ„žn4aў[Џъћ5Ё$<-$7qГИў&Ћ@Ф‡H^лШЛГ7ѓJрѕ šІЇ­ё“ЈТюУ;%GпИ§ИеРбКO^ŠЕ}\mIщгАsсреРЕGЯжz4,3іV6УжЫжА Дu‰ђmмъzРrPп(”4АџAИ9 UЌ Œђѓd/я†ЕЕУмнœ>зРrъп9ЧіњаB ц{ъ„„А†гъјˆ™™YЭН№;jЊэŒэƒІ€q|дƒ M[o;cPQ*ЅТ‡aїtН›;ша$#ƒьдОa?yђ:ЩззŽВЊЪˆTM.V†ЋЂЇ1€E*H4œ(ˆ ььпс Yчч*ѓ€EA‡=АЫŠФ№LЅ—УС 8&%PiT0Ь3Oјx‰aS)d h$хЊ­;*™ЬS.…#aoEKАяЇСљ< D!ŠЄdŠђк‘лю3џо8S —‚с$NЃ=АOСGˆp˜L"k*UхГO а% $ШDpL4Ј"${_ˆЇPщ`к7Њ—JхPЮŠсмЄ5\,*I8NТDb)NЏTxЊ`€ШBЉ’ŠУЉBqс˜\AQ2I"*ЩT8СEЊа%ЉЪКS,–Щ!…NVHER€FУ BJYZЇ/Рю~‰L huЭ€!(ЊЅ>ŽЧ SКuiЯbq>ˆБU‡zVgЈЭŒ­VЋ"?юa№ŒŠ;yЗУ8ЇI иIЖ…s5Hљ|љИІЯ~Суъъ џaaa|>~~–х—?P xфfVЄ“З! Л_о_'@u€‹Є†m|™ЬjИкзk@9E 16UЋ\7НoЌЪbM\Р с2ш!С“о[ч#5Qm зќіЛYv “€ЊћF Ѓ@EjmИыKЁl„@ PЧ[ДY]%Р&НЉŒGа…Ј jjсUД :џ!cћЈГбтњ#8а„B!P@'lъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ „@D1Ж:иiˆd„B!€PblъБA)„B!P@Œ­v"!€@ д#€›zlP B!€@дAcЋƒ†HF ѕ ЦІ”‚@ uФиъ`Ї!’„B@=ˆБЉЧЅ jЁ–Q„Шљя"P›G#љПл-Јх:…Ь#2™L,з)ЊБП- …Ђжђ6Фи~лa‡і;!PХе^НzЅT*ЇvЁЖд]`LJ$--­ZиФиjaЇ ’Ÿ"“ˆЌ‘?M@ПП– Ѕ.ЖcћuƒН!№=Р ѓШї”@yџ8ЕЋA›cћЧ;Н!PSдЮIЄІZ‡ъAдШ*ВІDѕ „@­@IlеwвљT zњ  Йъ@BYџ ˆБ§\`fpI+/АЋўКC|D"‘L&SЉTNШму{Cy5ƒbloq„Щ˜йЫ—/cccy<bl53Оў{ЕTЎŽРеЬЭЭнммєєєфrљдb„РЏD16њU‚ZxxxFF†ЏЏЏ‡‡‹Хњ•н‚о]—)----$$фмЙsmлЖЕВВBМ­.ї'ЂНю!€›ЊЯ`&  …гІMуp80 е‰ 6lˆ$ щ•Pіў€.#(0%hН2œoњЗ,Сс§DѕoНЏю}Ufff6lшАШ‡‘—.]ъгЇ‘‘тmuБЭuФиTтZrr2,БџќуO`|>žдžю$I%9ё/_f– %J–aу,œD ВSнy’зГgЧмћ‘œњк ™(ˆЄпK9™Ъ (ЅBЩЗ$’ёТјsз -6wQ*џСѓТ‰FЇJ…‚џsђяmл/ЪL.L‰йл;$&&>x№ sчЮp ­FШС‰Де’Ј’F†7,§kѓўёБС4нѓфЩ“њnѕщtzqI1JіV{xЮР™?єšxЈoC"лойб’NІгpr^ZrащшNнл&=|dnчQёььЅt‹ =œ„oyL!aJ‰D”ЫЄ2Й‚D&U­RТЄ ЙLAЂМ оMіамU*•‘)Р31xy€сS(8‘€U'S QЉЫ„‚Фргэњ6ЖЏйDxџƒф –7X9ѓBA TЏЩ’ F ™„‰BI Ћю<№('’ШDL!‘H••Г6д&DyЇ6Ÿѕ9бœ.–A5_!" BФфRQеL&•ЪяхиўZkЌ |і€ 8u‰DАЭvѕъеЌЌ, ЗћЙ к z…ˆˆа™ ‚ŸЋ •Fќ№uУЮБЇЇЇОО~­хmџuЦ Ќ>ЬЬЭ@ ’Тм “.ме™ W*|ЬНyз‰ућP0%о?Н{лБR ‘Т№Ъ+X$A~ќвE‹.Н›ЛЅŠ]vmHХфH@2AшЩ“#ч/›o3gюRŸf'ž^;’`нЭќоїЖ ЛOМkЧШНгgю6YзжХ!ЫІхф ›нh№юiіѓF БгЮ йџмЈљІEtж“ѓЋЯФswэн~eнд9{ЌVИ`ƒ­%%ŽђЛ+пД~ѕуO^ЕгйsЬ”yЯ#.ьлмЅiяћXƒќДkŒёђg.s о<ёLd7Ÿє“GљŽŸ7ЖщСЖ­оИ&yёЖgЩ~wЖ=ЧыѕlI9ВдСњqžŽ1='Œ­'Oš2gWЫХKВЭйtЇY—фчЎЫn^kR>іTщЪ§s›иƒDXЋz Ж!a8U­gЗСƒ=6]?<2 u`Џћ№сУоН{ЛКК“ћсЊPA„РO"аАaCŸ“'N€iB—.]`pж6о†>•хЬA0яT16˜}jе‰г€UЌћ мХт$F<*1kивнёU~УШЈx2NЅРЉ)*[OG›embЄЇ!сK”АgŠЎaƒЉЃ;›b9Оф§хJŒТВš>u Н хф#Iяе~цЦmК8l|^аR—e 46c+#xœ1­›Y›її0И—˜HЬ ДвЮоЦ$ˆфhћолL,Л^й/ёm-,кAbЃвR‚юИaЭ›xњф›š'ˆ$)ёсAїГ,ЕЕѕB"ŽыЛŸиЫ/ПxфОмеЦд HЅсŽeЗёкЩюЯШkАІЅЎђБзЄёЭЬeэgŽЯ9ЙsUjч‘ѕhF9ѕ'Пз*^ѕ‘УИ‚AКYNАZњЩ/????44t№рСЮЮЮЊ“–2ЉJСћл] бІ‰ ‡V€кVЅгУЈж3П{…TЅНўіWˆ AўЋ Б­1ЬтП№пб Щp6В_џўŒ‹‹swwџŽђџJVФи0иZƒ9”EРи`! Œ .шЙџЏПЧq|лхeBЁ@Ш“ъшшsВƒo?ŒN>Ÿ,wcPЩА9{f ]~Bz~…P—Ц…%‘ˆcќgw<ѕФnгhНД™"ŽJЧJжroІцЃчz70Ље4n*5іyFN…o{CХАHwf^Р‹вО}МJJcƒo^ihб‘ЭеЕqisтTШs/іЭ[ }h`зa7 SЉ"q›Zі8ВqЭKyFь'W/х’ZћК Yb9І”h`ЊОв #СѕfѕрŠs‹ђciЉJъŠ`’†§9™DBfjš;YХНЦНЗfаp.CШQŠRпЄ{ZкvЄsйКyАъщ<–ч–‘(иMlмqГ|ѕс{бC{јiPkб„у\Рƒ`hаіУ2VS|єш‘™Љ™ЎŽnEЛŒА­љл16и0M НцівНЋkЩŠŸГФ{вš1Э-`‹˜ЛГАk €бЄ2ž‚=Wј м‰BЁ/ў'VщЂ‰*ЄZEШa[Aы9œ{Э(›У*m )эс‰aЋЎnиМнЧZC’?bтДцv №1'qШ)•ˆЁ˜ a‚j6˜••ЙPYyњџљ%Ч/ŽЄarБі•А' edјЊФа-АU ЫM WEžОЙЏуu+Gеи†ѕ.Ќn4h№ьй38U{цLР16 &h6›››kggнSЩз~\eTуc>b‹&-іоYъaVK6Ю>"uчв%FNюЭZИАш,??=ХМeЯІЧчŸ v4А Ж et*‘ј(xOPjсЈ•Л\Д8 Z64жfSHxЏљ;rЯœ>=ШЕЧфЩЌБє)ѕooкu(vсюЕk',˜ђ@аlа‚оMœt“ч.є_№ зШ%;ЂЇ‚"u №)mТЄс[F^Э7­o  ImдШ[˜ћw˜ГhHIЫa;ZvnKˆПWІнЫУџ@ˆ›ŽоУю‚ё’‚6ЌЙQдЏ[wЭтн‡У\лћ6nжкнT,ˆ~“юyп %ІЛw:‰kзЎйV^яг?Мўќзю‘ФІ‚ьVa~ЫО’IDAT‰ŒŒ„йЧЩЩ И­ўЉQЌж_ЁћOеўaНФžу&Ъ(ЬЁ{XЬцхх……… p5а РD№УАРъфcXrСјЦ*/И~ИЖZ[дк29ЅQћўцOТЮœVhжЗhРauъFMЏЎн]"e‰лwијЄ1 'OŽжАіZ1}“іX8 ^юopŠœI&PРЗOy|рєЁїв’%}'Ќюаš0~цф)T=яЕKўЄQЩА~!Qг#Ю­кuЖHJlдн‰NЄ(a+КЖ§sєМчjА‹‹-аIР,ЖрљЯU\“Ѕ5Еjэ=ЂUнЃкєˆБНЧн|АHzЯ{О№ЕУ`ћЦ=6ёёёАтъбЃHРф ьїPTgђJ„БŒРfгЋ(ѓK%d6‹(NNzCцhe|ŽюџкЛƒž&‚0Œу ЅŠ­F1` jЌ‡&MRрТЖiгYїeћї‚йmп§Эvпн™ййы“эƒшt"rXЋжтgЫ? ХнHђrЌV‹\™*}ўДRй+Н~ѓёљЛ—o%ЊХk›f’ѓK7ЏM5п6ы{;ѕёфЅуMьoџnM'4КИКЙОVмŠ&’wч›ћ;c–;qИ[.Чц’эFuЇIЦЧŠ[ЕjЉкžЛoQЗЬ•/_MЬ\]^КбjжZbГБHНВ§эћz3П{{y*„їеџjFGЕNš}Pэъжа]{yъAѕБ‘иМѓa=qxя-K xўТЯnЁЯФжљЂ^ЅЄёM<’Ых˜sф,fgIс§Ћo?4Zуž<{њјQћ!Лэљ_ЎФ–Ячѕ›ЦмiŽяnл'Бu“a9с(Б‰@—ЦЪmz*NЏUJЇгšЉ+œ.Cь•žnPS<зv И,БuvƒЫnЋ“h €ŒŠф@•@`Гћ‡J‘A0#Р›™Њ   €.Hl.‰ `F€ФfІ*( €€ › Eb €˜ Б™Љ ‚ рB€ФцB‘ €fHlfЊ‚‚ €И БЙP$ €€›™Њ   €.Hl.‰ `F€ФfІ*( €€ › Eb €˜ Б™Љ ‚ рB€ФцB‘ €fHlfЊ‚‚ €И БЙP$ €€›™Њ   €.Hl.‰ `F€ФfІ*( €€ ПŽОѓкТkдIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/pf_Classify.html0000644000175000017500000000026311733011756023450 0ustar sylvestresylvestre

Rule Action "Classify"

This action allows the firewall to define QoS class for the packet that matches the rule. For PF it is translated into a 'queue' clause.

fwbuilder-5.1.0.3599/src/res/help/en_US/tip02.html0000644000175000017500000000051511733011756022144 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Answers to frequently asked questions and solutions for typical tasks and problems can be found in Firewall Builder HOWTOs and FAQ

fwbuilder-5.1.0.3599/src/res/help/en_US/tip04.html0000644000175000017500000000026511733011756022150 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Project updates, news and comments are regularly posted to the Firewall Builder Blog.

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_5.0.0.html0000644000175000017500000004566311733011756024573 0ustar sylvestresylvestre

Firewall Builder 5.0.0 Release Notes

SourceForge: Tickets

Summary

In addition to bug fixes and minor enhancements, v 5.0 includes the following new features:

  • User defined system folders
  • Keywords for tagging objects
  • Dynamic Group Objects with Smart Filters
  • Multiple operations per filter Rule
  • New Attached Networks Object
  • Improved GUI layout and behavior
  • Import of PF configurations

User Defined System Folders

Users can now create their own subfolders in the object tree. To add a subfolder right-click on a system folder, for example Firewalls, and select "New Subfolder". You can move objects into the subfolder by dragging-and-dropping them from the parent folder in the object tree to the subfolder. You can only delete empty subfolders, so if you want to delete a subfolder first move all the objects in that subfolder to the parent folder and then you can delete the subfolder.

Keywords for Tagging Objects

This feature gives users the ability to apply keywords to objects and then use the filter box to search for objects that match a keyword.

Dynamic Groups with Smart Filters

A new type of group, called a Dynamic Group, has been added to the Group object in the object tree. Right-click the Group object and select "New Dynamic Group" to create a new group. You can use both Keywords and Object Type to create filters of objects that should be included in the Dynamic Group. There is a preview window that displays all the objects that match the filter.

You can use Dynamic groups in rules just like you would use a regular Group object. When Firewall Builder compiles a rule that includes a Dynamic Group it will expand the group into all its member objects.

Multiple Operations per Filter Rule

The actions for Tag, Classify and Route have been moved to the rule Options. This allows a user to define a primary action, like Accept, and then define additional actions that should be taken on traffic that matches the rule.

This is only supported for iptables and PF platforms. For PF setting multiple actions will result in a single rule with multiple actions defined. For iptables this will result in multiple rules ordered so that all actions are performed correctly.

New Attached Networks Object

There is a new child object for interfaces that represents all the networks that are "attached" to the interface. This means that for each IP address that is configured on an interface the associated network for that IP address will be included in the Attached Networks object.

Improved GUI layout and behavior

There are a number of changes that have been made to make the mouse click behavior more consistent and the layout of the GUI has been updated to make things simplier.

Import of PF configurations

Firewall Builder can now import PF configurations in pf.conf format. To import a pf.conf configuration go to File -> Import Firewall and follow the prompts.


GUI Updates

  • "Crash when selecting New Firewall and existing firewall has interface that is locked". Fixed GUI crash that happened on some operations if an object in the tree was locked. For example, if the user locked an interface of one of the firewall objects that then proceeded to create new firewall object, the GUI would crash. The problem was not limited to locking specifically interface objects.

  • part of the GUI usability improvements, its behavior when user double clicks on "any" in a rule has changed. Now the program opens object "any" in the editor and shows prompt text that explains its behavior. The editor stays read-only and should appear grayed-out if palette is set up for that.

  • when user double clicks on a firewall object to open it in the editor, rule set view panel switches to the rule set of that firewall. To decide which rule set to show, the program scans history of the objects the user opened before in the same GUI session and shows that firewall's rule set they opened last. If user never opened any rule sets of this firewall, then the first Policy object is shown.

  • fixed several GUI crashes that happened when user performed various operations on the object tree that contained locked objects.

  • implementation of keywords associated with objects in the GUI; ability to filter by keywords, dialog layout changes to add GUI controls for keywords.

  • Removed obsolete localization files (Russian and Japanese). These were incomplete and have never been updated for v4.

  • Removed transfer agent code. This eliminates dependency on DBus framework.

  • Added support for creating user-defined subfolders. The subfolders exist purely in the display and are not reflected in the FWObject tree, in order to keep changes in the back-end to a minimum. New attribute "subfolders" on a system folder tells the gui what additional child elements to display in the tree, and attribute "folder" on any FWObject tells gui which child tree element to put it in.

  • Added feature : directory location caching. Use FWBSettings::{get|set}OpenFileDir() any time we use QFileDialog so that the directory you navigated to last time shows up in the next file dialog. This behavior is overridden by setting a working directory. If the directory no longer exists, gracefully fall back to something sensible.

  • "Add context menu to move an interface to be a child of another interface". New context menu (submenu) allows user to move an interface in the tree to make it a subinterface of another interface.

  • Implemented support for address table alternate paths. There's a "data directory" setting under user preferences. If the user selects an address table file using "choose file" and that file is "inside" the data directory, then the appropriate part of the path is replaced with %DATADIR% as a variable. If the address table is marked "run-time" then the path is taken from the firewall data directory option.

  • Fixed bug: save the expanded/collapsed state of the tree when the user starts typing something into the quick filter. When the quick filter is cleared, re-expand any items that started off expanded (so we get the union of expanded items displayed by quick filter plus what the user started with expanded).

  • "Attempting to copy-and-paste a tag service results in an error". Pasting of a TagService object to the "Tag Services" group did not work.

  • "Enhance Find to include searching for IP addresses in ranges". Function "find" now finds ip addresses inside address ranges.

  • "Expanded set of options the user can change to pre-set parameters in the new policy rules they create". Now user can set default values for action ("Deny" or "Accept"), direction, the "stateless" flag and logging.

  • fixes bug "If file doesn't exist when clicking 'edit file', then you have to hit save button twice". The bug affected "edit file" function in the Address Table object dialog.

  • "Remove Back and Forward buttons". We have decided behavior of the GUI was too complicated since user can both act on objects directly and navigate backwards and forwards to the objects found in their browsing history. Navigation using browsing history was broken when quick filter was in use, too. All in all, it feels the value of "back" and "forward" buttons was relatively low.

Changes in policy importer for all supported platforms

Changes that affect import of PF configurations

  • This version implements import of pf.conf configuration with the following limitations:

    • anchors are not imported. Anchor rules are imported but rules inside anchors are not.
    • only pf.conf configurations designed with the use of keyword "quick" can be imported.
    • Macros are expanded during import and are not recreated as objects. Tables are imported as run-time AddressTable obejcts configured with the file name, or object groups.
    • User has to specify host OS and PF version number during import process because interpretation of rules with default settings of some parameters is version-dependent.
    • Import of IPv6 addresses and ICMPv6 matches in pf.conf is not supported at this time.
    • Import of TCP flag matches for flags 'E' and 'W' is not supported.
    • Import of "include" clause is not supported
    • Import of "user" and "group" matches is not supported
    • as of v4.2 we can not generate optional parameters for the "source-hash" pooltype. "sticky-address" is not supported either. This options are not imported.
    • Interface group names are not recognized
    • commands "set ruleset-optimization", "set loginterface", "set block-policy", "set state-defaults", "set require-order", "set fingerprints", "set reassemble", "set hostid" are not supported.

Fixes and improvements in import of iptables configurations

  • Implemented import of iptables rules with target CLASSIFY.

Changes and improvements in the API library libfwbuilder

  • New object type "Attached Networks": network object that automatically matches subnets an interface is attached to. The object can be a child of an interface. The object is optional and is not created automatically for all interfaces; user can add it using context menu associated with an interface. Dialog for this object allows editing of the name and comment. List of network addresses represented by this object is always generated automatically. Compiler for PF translates this object to "en0:network" construct that is supported by PF. Compiler for iptables expands it to the list of ipv4 and ipv6 networks defined by the addresses of the parent interface if interface has static addresses. If interface is confgiured as "dynamic" and has no address in fwbuilder, then compiler treats AttachedNetworks object as run-time and uses shell function to determine network addresses during activation of the firewall script. Compilers for other firewall platforms always treat this object as compile-time and abort if it is used with dynamic interface.

  • New object type "Dynamic Group". Dynamic group automatically expands to a set of objects using matching rules that at this time can match object types and keywords.

  • Updated error message that appears when user tries to open .fwb file created by the future version of fwbuilder.

common changes that affect policy compilers for all platforms

  • fixed bug "Compile fails if firewall has locked interface that is set to dynamic".

Changes in support for iptables

  • 'Mixing Actions "Accept" and "Classify" results in incorrect rules', and 'Mixing Actions "Accept" and "Tag" results in incorrect ruleset'. After we made Tag, Classify and Route rule options instead of actions, rules that mix these options with actions "Accept" and others, except for "Continue", should be treated differently. The action are now implemented using iptables rules in the table "filter" and additional rules in table "mangle" is used to implement only tagging, classification or routing. Generated script does not change default action in table "mangle" and assumes it is "ACCEPT" so adding rules with target ACCEPT in mangle table should not be necessary. Another change because of this affects branching rules that use option "create branch in mangle table in addition to the filter table". These rules used to duplicate the same action and logging rules in mangle. Now they dont do this and only create rules in mangle if branch rule set performs tagging, classification or routing.

  • "Deprecating Route option for iptables". This target is not included in any of the popular Linux distributions (checked in Ubuntu, Fedora and CentOS). The GUI dialog and all support in the compiler will be removed in future version of fwbuilder. Beginning with 4.3.0, compiler aborts with an error when it encounters a rule using this option. In older versions of fwbuilder (4.2.x and before) this option was presented as an action "Route".

  • "Tag action should be done in PREROUTING so it can be acted on later". If a rule has both tagging and classification options, the rule should be split so that iptables command doing tagging goes in PREROUTING and rule doing classification goes into POSTROUTING chain.

  • "Tag and classify actions dont work properly with branches". When branching rule points to a rule set that has rules with Tag and Classify options, branching should occur in mangle table even when checkbox "create branch in mangle table" is not checked. The fix in this change is tentative as it creates branch in chains PREROUTING, POSTROUTING and OUTPUT. Since target CLASSIFY is only allowed in POSTROUTING, this may create conflict. Need to test more.

  • Added support for single object negation in "Inbound Interface" and "Outbound Interface" columns in compiler for iptables.

  • fixed SF bug 3371301 "Error compiling with VLAN and masquerade". Iptables NAT rules with vlan interface configured as "dynamic" and no ip address in Translated Source caused compiler crash.

Changes in support for PF (FreeBSD, OpenBSD)

  • "PF compiler should use 'self' keyword where appropriate". Compiler for PF now uses keyword 'self' in rules where firewall object is used in Source or Destination.

  • Added support for single object negation in "Interface" rule element of PF NAT rules. Now compiler can produce PF commands such as "nat on ! em0 ... " (for PF <4.7) or "match on ! em0 ..." (for PF >= 4.7)

  • NAT Compiler for PF should use "(interface)" syntax to the right of "->" in NAT rules. This now works for all interfaces, including those that have ip addresses in fwbuilder configuration, when interface object appears in "Translated Source" in a nat rule. When firewall object appears in "Translated Source", it gets replaced with a set of its interfaces which also get translated into "-> (interface)".

  • fixed bug "PF compiler crashes when ipv4+ipv6 NAT rule uses only ipv4 address". This has been reported as SF bug 3305234.

  • 'avoid " {tcp udp icmp} " in place of protocol'. NAT compiler for PF does not need to generate protocol match "proto {tcp udp icmp}" when service object used in the NAT rule is "any". The reason this was done this way is lost in the mist of time; it's been like this since very early versions of fwbuilder.

  • "Update generated route-to configuration for PF versions 4.7 and later", SF bug 3348931. The "route-to" parameter moved to the end of pass rules in PF 4.7

  • "Crash when compiling a route with table object". Compiler for PF crashed when run-time AddressTable object was used in RDst of a routing rule.

  • "Group and Address Table name persistence in generated config". Compiler for PF can now preserve names of object groups, dynamic groups, compile-time AddressTable and compile-time DNSName objects in the generated pf.conf file. This is optional and is controlled by a checkbox in the firewall settings dialog.

  • fixes bug "Run-time dns name or address table in routing policy -> crash". Compiler for PF crashed if user placed run-time DNSName object in "destination" of a routing rule.

  • fixes bug "PF: NAT compiler fails when run-time address table object is used in a rule"

Other changes

  • applied patch to provide configure command line option to specify path to ccache. Thanks to user "a. k. huettel " on SourceForge.

  • applied two patches by Vadim Zhukov persgray@gmail.com to replace calls to sprintf with safer calls to snprintf and fix some compiler warnings.

fwbuilder-5.1.0.3599/src/res/help/en_US/new_bridge_interfaces.png0000644000175000017500000003453011733011756025342 0ustar sylvestresylvestre‰PNG  IHDRœ+К#ЁhiCCPICC Profilex­—gTSMЗЧч$$єŠ  tAz/‚є.щUщMJ])‚є.HGP”Ђ€вщEQЄ "HAъ=шЫѓЌћс]їЫЕВц—}ўГgrіdіl(ћlq8wРУгo ЁЬjfnСJј # М@мжоЇ„Х^€%џЅ§њ ЃGУGОh—НŸzrфL „ŠЖИ†ў—AЧf <яршc?>šїВƒНЬ 0ЏzxxСў)ќѓиу№№XЪЛ0sНИ‡[ №Z Щm&М<`ГѕЏэL!tiДbџЕmќyW§k'1б?ю 2ePŸ7ИсЕСњ§дУУнтУУ§uŽзN”LІŠ˜ђ™vњlљХpFwVkNѕЋтМм‚є7ёEсяќK<Ыœ?NЏ0­2Ќб­c6Ј~Rl’§"о"мFџFя wQ{Ј}‚Ф!txЧŸм†ЁˆbdС]д(!?Q 5iЙХ.еc žVŒnѓD-Ѓ sы)§гClВь‰}œ?Й1gиyјyEЯJѓЩ№K HŠ ѓˆpŠВˆб‰“J‰ ЩYЉaщv™*йьsсrЎђиѓ ЬŠŠ?”Ц”{UъUяЈ%Јhиhjj jгjoщŒ]hжЭзЛЎo‡еМ(jРjHiИoДdyиYY]•[[јшЪc›ZГ:§zЭ'ŠOЅ„Й›XšiZˆ[žmД.ДM<jяъxвYо•гаs­зЃЯЊџТРЙМ/O  ЎПš~§zЈуMУлšсяюП/ў?’5šњ1n,rkvhkGши^зeднд{Ћ_MОˆ705”7т0&2^6‚їР-s cKq+jЋы——*.Члрl-эtьЯ9:В:aœ‘Ю._\‡мž])wЯ№ИюyХЫЇэ­ˆ—ѕ‘єѓё р <Ф~•%јDе5тPњ > &Т_F4F–оH‰ ŽvИЉ#Ы‡ˆ›™P“˜‘l‘"ŸЪš†H›MяЩ(Л“щ’Ѕq›;•=›г‘[”’oV QH]ИZ4tЇЖ8Ћ$о :ЅТїщюя”M•wV”>ˆ}xЅRЏJИšЖzЇfіб›ЧЕѕuхѕљORŸF6ј7К4Y4ыДШ=уoen#kл}Од>йёЊѓyзЃю;=iН}о§Жи /Y^‘ПкН:Д№fцэЬ№мЛ…їKVFжG7?nэL">ЁЇШЇ?ѓб˜q™MšЋџ:Й€ў&Аhќ=tЉ|yt…zеz­yCьчГ_F[+ПwЯюѕиХџoю;Ъ hIю.`*€6œЃ зрЮ€&,9F2њA   5}Чљƒ№` мA$Ш5 Lƒmˆ т…”!+(Jƒ*ЁhA€р@(#ь7ЅˆФ*’Љ€tCf!{‘;Тю VQ2Јhдњ,:=F(I˜AИIdFдJЬMœB|@тEђ…дœєйEВ7фЦфN”TдTEд"д3Ь*M-э žž‰Оч„УcъIѕ“;LUЬv,Œ,УЇRN_dЅegЛЫюЭЁФIУ9ЯеФЦŒ‡ЮcgЃљLјyљFы„в„ё"ЦЂ2bЬbћту ’R8i}!YŒьіЙ)Й~љ'чя*d*Ц)…+_SЙІЎЃžЎQЄYЃеЉ=ІГЁKЉ'ЈХњ^Ь3ш1м0ц0167ы4пЗ”ЕКjнz™РFз6лnСAж1бщГ‹Иk”лwЯaœ w<~бWзяQc`DаJАUHЈиѕœАƒЛШž(ш[1PЌgмT‚Ab_ВbJsšLzг­ѓ™=З/fOхzчЃ ђŠ$я —ряб–6–йT?ЈЋМTЎy№XЏv­>уЉlУLSRЫЙgплђл :‰Кк{‚ћФњПНШдyѕ{Јь­щ;тї-#Имc“™ŸАгфŸ_ЬФЮiЮ.є.Ц.щўРЌŒЎl8lђ§њЙнЖ“АgyРџчќРРЗAE` Ышчnљ pHYs  šœ IDATxэ] \SGК$ ŠЈˆ U[#BTЊ]Ћ”UД…Ћ(оUAАкŠьZ№m‹єZYZ_ V ъ­Tз%ЛЪК”vЉF­X”+еАJ%VЄЈЈЈ`Р@0;чœXДёSБoL|ИggХv˜Oіеф;П'ђ ћ;ЬˆX>ŒHJ…’k–5]”^8‹Wњ#н]ЧНrdїз`П^*эeьwŸj/Ј|Е"a>]-№€‘ђ&[ЌMOn>hTP%7Y˜M0xƒmCˆ#ћMVдg0ЄH­­­џиqBіЌЉ}ы 0яЃЙэУщBлkЂlАЌѕ—7ДhB4žў§­џЖџŠц∇П`i\œ9СДЯ2mрЄ 9„@/ `hГЁ_П~ќ0>eЅоѕЇ guiР0GЭЧq0Ч–Э‚Ћfх†"фzƒьЄѓєрŒxnYaТŠфчђ"xVтъ$цљ№Ќр'"їЧZ Ј94/bЏАO,?Л1!|‰№)~!-†OЯЌQ(KЄсщa–пœ!RвжЌњŒ0Ž}ђЪdДщP„х"`H‘`ЋGђ<мЧеkў(?OЗбCє;}ЉhR(ы[@Г~Z[ZЪyір^uUMѕЏееUuФь“<з’U–WЦo‘ЭЯ:Ÿ<ЬЎfЏsDКуцМG…Y_Nм>uех:чaƒ%Y—А[ОЁтФQEЮqё}(ъOJ…зЋЎ,ЙєїѓтЇяи[ВsЦiBЭЈыІЈЬ˜‘vІŸ~Tpќtцј!lъd(дЂш@‘`л§чёћБДЩњлйј§оЯT˜(eŠVјiQЖЖДСќёs&’ћsAХŽuЁ#CBЧЬ [а>O‹€иХљOg[^”@Lиk20|r 7\П-їY DЧiв’ŸDX‘’ЫЁВм>‘ –OВœрФи™#ИЮƒ\80ік]8Ќб966–”IЫьЧMїїraКtЄ“‡Тћ"Z ЁЋ=їю„щЏkb'…Lт8fšАNyZAыѓ­ЭŠ69дЂVЈKЭЕVЬžkA=ся9їБЯЕE” #ОяLАЖСЖВ""gŒœ9‹ЗЎx9sX.“‚ј@RrЕКєx†ра‘ЌdЏœТе—ŠD 4иЪ“]ЦІv~|ЛшПœС„Јv0o;gыѕЧтOј9ЛŒœЪ›ОO|_о. А| m6hZщvieУу†AУyъ,ё5iŒђДЕЖЕЕ(•-­mђж6ЈErЅB*яgеЏЙ‰bТ(ЩкФъE”R†XIW..і%4‹H2vnиђA2ƒЯ7Nx§З™`jќЧХР{CІ' HKOЦЌЬй.>6[}xSшВ–=.aйmПЏ-­ї[ѕgžxз4m5ях@ у тwКсю‚|/ю@t™6шр\S!eы ЈNЪ–њ&iіyђЌ§4­‹ЅOРNП/ŠЪje въВ2I-48ОQс@\Р*Рy§M>œž‰С‚Hlь•з?п-ѕЯžўZzhY> Д@suсбЂъZ9згc"VYFџ›А„ШYLЕbЈїащЫ‚_6Јыm‡s9В–ЇќП''юŒŸхЖцiюъ0сћМ™мЉЁМ%W`:Yр €`Яxс4PDП5Е\јП€эSчY>јЫЕ|PуОЃZo›ІSЙцŸЏuЬwŽШт…g­}CŽ~_"zтd| ;sлЈm э…ВЕЙU)WДЪMwZ[A}§ѓY3Lа(“U6mэшlчњGо •+XіNfЛJYнskG.›” вч€Эu4Д'oСЙ$з‰<{ь\5QЎ>‰@ЭC ?љТsŸгчEЄ,]єВЁV!ТšуЄкХ€ъDЙŸAЦvф#œœљ-ž‘,'д„€A˜Ў‘ A‘—VыЕ>Сцјџ2ђеwnЈkЪžПˆEQnE ‡жH]oƒэ№ёnu(uwБ'ZЭ]YvMvН$!аiњŒ"СВе'*Ќћs›яЛ Ті­СУчA›ЩўuG”ё%G Я({ ъ–-зі™ншWš%˜&ЙЕpkюб>тiзЛђЂЃ™ЂћƒИШГу]6eЄтБ‚хсэХен2ЏЙ,Ьўї/ЃX4М]] AС_?_?pрФ Ѕ- ъИŽ]) х5нЈHJЅЮƒWr­­uoLrпнgЪ‹fеЃ[[ьqM?+Їgѕ`eT-ž#ф†žšFGDАВF”-,„­Zd0љќћˆШнМxUчtѕЗŠ„Bд{‹‚ˆaœЄц‡/bS„x ѕТЂЊ5F*вх}БЗ—_йb4ИŒkˆв!а]ŠI'NœhjЂ"0wю\К б…wvl|ЁebЩ[8uи=#ћлЋњЛЊŒ‹ОVyh~lАfь^ћ Ь=ƒЅvУл Жі˜&у’hŠщLАђz1д"А*33жпЩ(вВУS6D ей›"Єoя]7ЭЭ( (qшЎэoŒШчSVЮппŸ2мp Ћ]?ЌЖ№~FqY№уфкCДZdX„6–ѓшњЙ”Ÿˆ)G+Uуœь‡}›VlЪМ\†GmЪ“ХЃ%ŠovymщО„Xž„Дoў•ЏЯцеЈЂ|вŽнЗ)aХО*‰ЪКђЃi 0Ь—rјЄwаЙЪ‚]ы0=…_%ЏX‘vіфО+„ЅuXД,-aEBZž]^”ЙiEк:Ћь zнн˜QтЕ|ж[,r=ˆ@wHА C‡НŸ|žxzzв™НGMчЊPу Ь3•‹нacqzƒ]l:єЎОQэ3є›П<_Ю—K„ЉѓŸи_м‡˜њлљ%"Pu„яХЗыy~5зrђE‚…„К"IžЙ‹‰J\0ђЩК’tYyrН9jФгјm0ŽЯЧN<YљVA$ЬЕjЧчы9)ЛуЋњћjб8Rf­зa№HИ Ч”aМ‰ќAƒн‡з•”d—x„†ћўЎцђї9"xОЖ><:$ˆs[˜‘ЃА1QэИУ‡мKЮѕЁТњWYЂŽAП=„@7*l”N:ЇyDklllќќќ:зВтœНƒн='љ[љ94eЎ&‹‚ъдœЕ,џгљ1lXпhŸvы6'Џ |уУ-ŽTPїьOї*l TЄЪЪЪ†††AƒyyQмЃLкKœZpsамЧX&ђŒŽC˜MэTы х§[№Ў„ŽМ}Nљ2–=ЎџќAјОƒђQЭ#ЂDјm;прЛ…uW."Бx[ћAизЊТмXЬg”cODavъК pP;ЖpсЯ…йЉ9лА‹Е[бN‚QPі@тnW$Иг wNŸ>`R`ћщœ^шhзЧT™|8sЁзЅН№Ж |оxэ(BљŸ)AIj|Z#ПЙ0Cз2*7мЊШ‘”ьЌИЦ/С–2ч9э=Š$Sњ/}‡žVџT\їоGKщaНафФ=.ј (ХuQ„ђСnь*(hДnBtећtзЎЙepЫ!88ŽHфР^ѕ ЂьŠb—ЌЦnваФSM#=xiЏRXˆЕлДмДhш)ЩЩШЈšš-Ръї# уњgчю …c-мЉˆў$mm( SmypЦ}Vx0ZрU"мНzљђеыЖх“G?<Пі пTWIХBЙcgсхDЭѓ…#сш€Yxвш€Qэ+Љ‚|Н‚€ееЋцnжEoFgІŽШjsЫeЯЫ5тІTЪerЙТšЋЧk’—_Оюр5Ц•cdЗ3c#В% :Н№У эl/ Аиі6дYLŒоJЩкšЭЦЂыЋtћдЮ$РшЭпрZˆБъ?0QМАйЋJУhj‡UŠЭбг‡ŽkjЭцPбїф—b—УZЧ_Је"ЎS–ьFдф%кЉ!‘mе‘ЋБДЏЏ!а7‰еЖќq ]t…sп=uЬѓ?їжЕ€ўУЦѓ'ћ{ц8оz<–НsUг=єЉ]ї4IE˜V?ќRІ‰d!^>zbзЮќQ§vчw№§їц_OTCГE)ѓЎQV—––џŠež Ѕ|9шл› †ћˆ˜2ŸЯ ‹Тcхч§–ямyDœиёіšD˜љ^vzUА!mћџќŽђpƒQ’>ƒ€™*’I,ТNиu.‘IWШ™$‚`€oл1bЕпaZ~шр’беaSз-ЗЫnёgVJеWшјЖшљ–™аR ЭЅ‘D§SoўгmК“­ukГ’b6;0п}ЦУєœEЧђ•ў;5ФюйДдзј~Ÿ'™і•x­?8‹зѓhЂ{ŠЛЊGЪ5Tˆi-~ИJSX[›ŠаЁ 1кг\ѕэЦ“lќ&YEњЎЯЎk АцоˆšяMœSpШ‡g‡Ъ$ЊcВF‡2єЬQ‘ t&Дј8>ЈЌеzЩН)ФЇц N>UG1љ…ЮJ’ж­"8\|0) ь ™ѓэ/˜† zxžрѓt@Д<—ћЯ/™ШGiњ.ц8Е#а„–ѓвNЕ*TcHч,ТІoZЌlœМЧ(BЛŠЧ#bwоeє4 3И!]ќ?ёЧwbђхœШПџЛъБj!№@ƒЌь:ŒmyЁ9К€y=fDм%*ƒОћ"цЋH„ЅРkџАvЮR Н` Ц—cСЅ4„џаŒQ\Ÿ†]ОvŽ(‚Щ7ѕjŠd аЪщЯQ‹S#^ѕ~…‰p”Ія" юoГlAз-ЖYйXЕbЪЃД‚/Imm€"YvчЁж™fњ@ж|B5A0A)’!”њХ-БŽ‹2”Х!pадŽіF`/[и?СП~mж#\ћЛ9ek[[k€“лЎ­ЕЕПm'GлЁГЕuй(t(•Щ—!H{Й_д"˜Ђпwƒщ:Œь*)PYW]њЃ)О>§ЅєлУyп ‹Њыє^ f -]m…б}= H†zJ0Z~шЏ†1Š“}c5™)P&кјЉи7&>;AvВвУ~ЛsЄWMBЧ•хђЖР[$šхќb_†ћ‹ [UМ#j#mKЩ­юC~ пўюbO˜B…TU`H lzrѓaIЏъ˜4О^`g/ЋDџ`эй3K}RЬАLЈД-эlЃz7R$CјѓЌАSстЖk„‡œєг чls%‡0№ch$rІ}–hЃ3>Рє№ЈлT:„зв–эxищкЮИ[С„кHбвЮдХlђ 5R'ЛbгЧ3O}ђШИЬ’d'ЇgмP‰­+?0Я’yV _џѓ­Me-mР№C{їEOпWIМ'ГNЂШ§Б–Ўn’У)a+E@œВиЪ'9ћтЁy{…CQ~vcBјсS<ЇДT>=ГF*nчХ<зˆыАєдF’(rKe…q+’œƒŒIМQЦЄІШ>рAŠdD'СЁIѓй .1ЯЬ„8Ьиƒ7TЃOэчШєЪшУхyчпОš„›ХФЪЋIwLЯ п_^_z5>ЛDtЛ#kдьuŽHwмœїЈ0ыЫ‰лЇЎКLЃJюo/иВОѓ?*ЁјHdАїАС’ЌŒK?БЁтФQEЮqё}И§ ,=RсѕЊ+ s5~1uaв дFВ(RKьa‰pe|{Ц$жм>тадЎ‡:Š )в5Е‘—K щPДяXы–*~Юч}ceeEY0ќЪƒ`8€с›a8œїс1aЏ9Ш€эф@o М~[ъOuJ‰3дыБУoфр‘Ї ЂСŒуП4„)љ 2>р6Сх‹OƒУыOd‚„тI№Lю№й‹gЋъХЄЈdQ*‰јиqф4fюGŠdDщ­”р2 #–I’ЩUСїЄНМ†Їћi‹jзHuИЪ^'4Hb№љЦ Џџ6LџИxoШєЄМ;:jE'ЉtbhIo&Ek$#аз, Чи-;)№RМЙю,N ќ/ŒHы8žcљZ›њїђ_kФТЬрЉ„Тpx№ЬвЮРјC‡ѓіЮѓ‰Z™Oˆр№10мя‹ЂВZYƒДКЌLRЋЫ8Є/Ъ7*ˆK ёuРy§MXn‰,ˆ|ШQ[\xRXЎР/ЕЇ6Š ЕБJ*ЩдFВ(ru‰%g0??хџѓЋfпЏCR ЖЁNО)ЇgЭH]“ ­s~–Лj}D9Ыžј4з=љ№™]9Ў‹гВц]Yvлk`Й­yšЫ^ё>OЕ-БE|бЫE+OзчHі‡NР5•ћž)XrЇбp€*Щ‹~ кyЧнуKЖfП;3|МWЖ‚ŽкHЅ[ؘl<аcR?‹9]Ѓ“ †zCя9ˆ Ѕ6g)P+ЉY&mRАЙк‰мPkжЖDхйП5gжžНІ}Д*oР,к;qЌЁiР†vІmиl[ VЏЖDƒ>ЃZјк(Ы>љЛЙйqЃЄuЯ;dLЌ`ЏEЂЩєЭбx Ѕ6g)P+Щ–УUщŒ&LњWЛЉ;Ё1aFОФфЭ"PРДŽHлpc1wI…&сI>"овёЛЫѕ2i.jsjc‹”Ь†ЯТЌЙNлšвЭйƒF$sюъКе–]ОxёжƒG€эЬŸћЖяXК›O)­•*XЊV@Y …’eЫх:v~DЂЎPWC•’яDм§‚&8uURяхGŠд{иЃ’-ДkgA‰šв{ Eъ*іШк_WДˆќH‘ЬЇM@›“озЃщuUІЩ …]„[vŸщгБ.dlvЄHдˆAk ?дљ;ŠY\№ї*ЪЌ'‡ŸŒі‰пј|M%Ѕ{њcц[юЙЯuт Щ$%„4ЛM{„•Є•W^yzщдˆ[ эcz'фVіLўіво)л`Љhћ›гZћЃ*F)љчП$NўяLq#bщhsLxr YђЩдŒеЇ ѕЖ№шdъе‡–fgRBЁ^ЁЬ.uPzme&p]ž;яb„њy13!нž )-Фн`эOЏ,ХеАmлїг(Œ~№Q(•Z‹€Lxr@МО‹|еЖщ”g0™ц@(дk?ГK”Ќ]ќГ6€˜Ј“3Ў™з‹ бдЮPošвк_;жф№ŸЗУТуЗ†[љЄUMЋ4п/:А‰‡[ќцL VЙ&е'“JЂђцŸЬjж!Џ{ …єМН†Ъoт2ŸOxмбJеRЧbў—њ(љХэтд+U OjaшVR$C№j,)СD]ГіGСКsМ€їкЈ­ХGц†EрДЙјїй_œ™&й9уфцЩю00иP—VюУДo .Г+ƒнM(ЄсэерЮп™щБ_\№}y:Џ85Œ‹r1Ј+1žпйќЌѓЩ>oыЃd=иUРнцЅHhjзўоS…-)uбк5ы.рЕ‰Pх9žљЊаЩ0‹ha›Яž ‡ЫаyЁЛђJjbЧрq†MЪ*ЫJ€Wмp  gNЧЪ ,/ћъB!e‚eзг †"ЖкqKЪй,фЅœ/\ьЫТвЧю(>€Y@„5вE Я8Z КzoY€оzKн[)-ђ&ДіGУКSbš‚^ )р/˜HLЯrxs;@Вž1<9HеЃ8ўCЧ™гX$CаM„ТіuАцш0Y\еЉnэP x,ЯXL’ЋоЋ~ЄHД№›ак ыžя-бдBmљOР„'ЩKо@"Љ–ћЛP J@{tыюіV5eažn"ЖЋމфўР™‹Š&нWLшт ƒ’Ђљ>>иdи|R$кО0ЁЕ?œu— Yw#Хq“FВŸмЉjтэхbmя*’ђЫ—yŒrтhя4RpЂ€NcцѓРЏЗŸ€vєXgЮА•AR‰Bсы ^ќ|** с’h…-‡~пpr[V #Т!ЁА}гTа С”uр8лТ%ті-їљjž;Иw|} Є]Mgkкy&ž]%љН["Рі6ЃyЌ'R$ЂЏѕПMlэšuЧ ќ`3ШIYрš“P|~Y€N_Аиии‚ПˆкЮьа їэ]б3f|йДЫK—vСŠЇm7 )x{žIw‚ЙЫпsMХJчEeнљаSЗђx­иz(}ЗbиЩ3Г“тшєЗівѓ™жк!œФКS—†QїЮУS‡аќvФ““}ЛdђzЮžŸL#Џ“ŒЂтiKюЁP+їцэ)euЯ€ХuЂš”j$ЉQzєЯДYauyMŸRЉœ&u/xtў іBљf\Єi­§ еВю4 Ї юiтt<ёф8я:ѕ|ЧMxDˆ<щ1ŠŠЇ-ЂVŒ …Z)*ŸAоž5‡ ™O]ŸЦЦЁћЉЎvЅіl‘zяО\cBЁ^#-ЗЇзЄі—H‘кc‚BF#€N6 Ъ€hRЄі˜‚ˆ}ЦсeЁЉ‘"™OЧv•„[‚ˆ}НеH‘Ј‘gШъƒЩЈѓw&д O^yЉ(Zp™˜RNЯБCФОЮ nЂ НфAS;ZрЭ„ичтH[CM"іi ш-R$ZфЭ„иG[?ŠDьЃЅg‚"бтl&Ф>M§TgК!ЏДCФОvєtR$ZФЭ…и‡UP^[%}\‰НTшЁЄf —хьсЂCCФ>кnьЁЄHд@›Б4TЌЙкІ„n /~Žє+žЮк ћЈћБЧBбщoZЈЭиG[QU"іu„PwЦЃ‰]s#ібVTˆ}!дёhDъNt-K6"ішOЄHРAQІ “ L‘BщА№5х†тЖЋz!ш!`,–?"ЕtЦтХ8НЂКДДќ|‰5r/>"С>ДВВЂыIЈb0ъм_~œіСК4Єpййэ_|иaAЖУпфЯ^8Эт…†DŽh~oчЮЏХ‰<јъPбЦOХО1ёсž$iШkQМд#’Б=Y+цKРрažчьZ?kЁаРˆc о`ЋЮѓакУ3Ж(НЙ"`љŠG$:з‰Nс/XЗхУ=зЮo Џш=ё›$œ3эГЬаpDBФђМ–ЏH–HщN••юјЗ ыГLЈЭЮ‘eЫN:OЮИЁ jЈЬMH ,+ѓЌR$ЭЕЙK"тS/уіT`ххд„ш„sцeF‹мфЇBРђ‰MЉ‚q ŠIDATn8‚сT€t†U•Ех'VŠ№xХ‘жьYvšЇЈйЫП}їнЄ‚cпп9‘U№і@–ЫЋќЂЄЏЎес9jЏЄ&‰&ЮЏs&•, љЭЫW$ŽHИy’бг}&ЙFцСођ(ћв"Ей97ЗБAаьgФДK'™X”@LAЦтйум<<§gћЛА/|)%Й˜йђcЧ*@јœпщXн2Ы;UJДkЇ‡с м$уќх ё‰œіx+LЄcc оyUmfфыЫXО"Е‘ˆў‚gнЄNNј:†iЖм‚/гЇ—ЎоВ;ўыwEЫІЈзJ*5л/vODœwхЪьœ•п­‰ѓRM™–€вѕU,џ9дКO':­ K;Ш`здєj0v‘кI/‰рДn{B n‡рЁ№ь3ЅД ?u&єk!XўˆФ­#8мŒ"дpМ8њІDЯ ЩNKѕѓwзЄ–_:˜ /ŽЌџѓЕСрIБњwљyЁ/Х P“y,ЫWЄЮhKGны6;іѓиь?%m€ѓCё ЊікL Hо<м@YЫ ›аРёзЅя>ymы4_уЕЕЃђQМй!`љŠdкщ™Њй3гŽ…fFцУKќ}?’ќ<ИЭАumИЦў—lXbz^ъП *}ЁїBšн}oђ НМkЄ{cЦtMwЎњ_уИ Х‰P{ЏPэ…]љоЩ‘-ТТ}gЎцспЎШДХ8€Aк фГ$,ќє7“ГvІ іYв-квдџ_;“Зфб#іѕcѕkUДТzЛzяж§>аTХ>‚€…HН_œпЙWCRШBA–ПFвяjЄEњˆ k №ђ)’ @C"њXјщ Ÿ-nqєjv|њ/|ш7сcŸВUVњ&јљ ЪЎЈBєBзМ#д" ЈE„gBŒJˆЫЇїбЖ4ƒ›%ЁGРТG$ У•.Mрgр<єЩ=rЕŸlБ Sфlќ=?jИћVшK1"iДШ?KM}Іэ&8Љc8ЏгXьЋЪюZЖ:јЃsтD(%џЬћіЧM =? }зcсŠUˆаЂ;Ђ“ДКдЉN#,іeЗ&A;cg*е'†Œ’ЅИЖm§Яѕъ<:іќЄїkžBМB*)-—еtJQе‚бo"`сŠ‘„ы"biЄб%МpPТЧ%8Чг[2Т_ѕ}Wxю[м КЂ6к'+Œ[‘zГz]Е0-<Ў’ўѓvxП5мЪ%лѓ“ Kлр7ѕ=П%QМ‹]‚ІЭЬѓСэќ%кЛ/zњОJтхИpєеыXИ"iv.Чаќs'Эё˜tЦ3 €$зšвўš@,Я[#бэЋ—”\~ЌКп›ŸмЌ(Цю‚w WЩ{mджт#ѓƒБзHиЬ6;РЎЂYtfqлХ§Щ^;~К 5щЎ‘щyсћЫ ђ‹CЏЦg—ˆn7М€сШ™ &X,›KSЈъЁƒkYƒ[Лю`ЙI&йOxrDoReЂ ƒћ*т—№тБоkг.рls™жh$ЬКAЃ}B^ЪёТХОЖt„a/}рxМ6QЊ<ЧѓˆНDвЁVh: RзІБЦ.ц\]НИWзн)Ъ щЪƒЦbEЄŠ7ѓyплшHFНŒ€…Hdt]Ш—а%ј‰ ћƒjІ—@яохоЩщЇoЅC†l…ьёOШГШЬФhŸƒZšВѓa Ѕу{:ЋЗD0УFЇ"ˆ2/ ь-,\‘XПeСИ #†@‚™гчH8ЛŒњЌ`ШмАao”Ќ5к‡ЃhЊе)7о S=Њ‘9ЯŒZсМ€г8ЩjœљРЭs? QKваEo!`сŠЄѕ%6ƒ1ЃƒZDФ2з"4—йб{зz‰т—|sЉŽоhŸЂх (Йp­ВЊКpуТїw zгŠЕН;ЈHЪ/Џ•щšџгˆзё@т№Ђ q=0ўасМНѓ|ЂVb|BфЬ  W$wЗp™фЂРоNм^—` ЁEЯЦKЗо‘Хƒ7wz%РŒі…WІОч:9а5bWeTж<Б—нqЇn_rRТFЮљSuш–d>PН …јСfrИN>zХалQXlИ"тиРikxтгмЄЕЎvхдLNЫ:еЊэ5˜•"Y8*„ЛЪЦ“˜реŒк•Š№Я\ЏК‰ -Ђнжcк]дFћ”ЭВчM€ыUBз5ЫЄMРо‰Ѓ^щЦЖЛR6kе›(•gќжœY{ікRчvЩP@o!`сЛvЌ/*яс>bh‚^И.‚Зv'&uє§DmДЯк–У%ПŠU“Ÿ.\“@Ч#§Ћнд‚аG0#_ bђf!-вAЈЗ/,|DъmxMV~mйх‹o=xдиЮќЙoћŽ5ъЭ–&ЋD‡R$:dP8BРњЦдХ М-.6а2d/Ь8(ЊЛшŠQАїжhз‰d8ўђМlМыaу8фE…ќFрџЋ—о^‰fиIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/iptAdvancedDialog.html0000644000175000017500000005375411733011756024565 0ustar sylvestresylvestre

iptables settings

Most of the iptables options can be found in the man page iptables(1) or online on the project web site at http://www.netfilter.org

Tab Compiler

Compiler

Full path to the policy compiler executable. Use this if you do not want to use standard Firewall Builder policy compiler that comes with the package or if you want to wrap compiler in a script.

Command line options for the compiler

Additional command line options for the policy compiler.

Output file name

Specify the name of the generated iptables script. If left blank, the file name is constructed from the firewall object name and extension ".fw".

Script name on the firewall

Generated script will be copied to the firewall using this name. Can be full absolute path as well.

Installation process is controlled by several variables that the user can change in the "advanced" dialog for the firewall platform:

Tab "Compiler":

  • output file name
  • script name on the firewall

Tab "Installer":

  • directory on the firewall where script should be installed
  • command that installer should execute on the firewall

These variables have default values if input fields are left blank in the dialog:

Output file name: the name of the firewall object, plus extension ".fw".

Script name on the firewall: the same as the output file name

directory on the firewall: "/etc" (tab "Installer")

command that installer executes to activate policy: installer runs script <firewall>.fw

If user enters alternative name in the "script name on the firewall", it is used when generated script is copied to the firewall. There are two input fields in the dialogs for PF and ipf where user can enter alternative name for the .fw script and .conf file. The name can be relative or absolute path. If it is a relative path or just a file name, it is treated as a file name in the directory specified by the "directory on the firewall" input field in the "Installer" tab. If the name is an absolute path, the directory entered in "directory on the firewall..." input field is ignored. If user entered alternative name for the script on the firewall, the command that installer should execute to activate it must be entered as well. If the alternative name was entered as an absolute path, activation command should take this into account and use the same absolute path. The command can start with "sudo " if user account used to copy and activate policy is not root.

Assume firewall is part of 'any'

On some firewall platforms there is a difference in the configuration command used to control access through the firewall versus the command that controls access to the firewall itself. For example, in iptables, packets headed for the firewall machine should be inspected in the INPUT chain, while packets going through the firewall are inspected in the FORWARD chain. If this option is ON, the compiler generates code for both FORWARD and INPUT chains if it sees "any" as the destination of the policy rule. In other words, it assumes that the firewall is part of "any", and packets may either go to or through the firewall. If this option is off, the compiler only generates code for the FORWARD chain. Compiler treats "any" in the source of the rule in a similar way, generating code either for the OUTPUT and FORWARD, or only for the FORWARD chain.

Accept TCP sessions opened prior to firewall restart

If this option is ON, the firewall will accept TCP sessions opened before the firewall software has been activated. These sessions are special because the firewall never saw their initiation phase. If this option is on, the firewall creates an entry in the state table when it sees a packet that apparently belongs to the unknown TCP session.

Accept ESTABLISHED and RELATED packets before the first rule

This option generates an implicit rule to accept ESTABLISHED and RELATED packets before the very first rule specified in the GUI. This helps to reduce the size of the policy script generated by the policy compiler. ESTABLISHED packets are basically reply packets coming back from the server to the client. Iptables keeps state information about each TCP session opened through the firewall and thus can detect and permit these kind of packets automatically. RELATED packets belong to another stream somehow associated with the initial stream opened through the firewall. FTP protocol is a good example of this situation. FTP uses two TCP sessions: command channel and data channel. You do not need to add a special rule for the data channel to your policy because iptables "understands" when it needs to permit packets that belong to the data channel that has been created per request sent via a known command channel. This option is ON by default. If for some reason you do not want to have an implicit rule to permit these types of packets on top of all the rules defined in the GUI, you should uncheck this option. Remember that in this case you need to add a rule to permit these types of packets yourself. You can use the Custom Service object named "ESTABLISHED" in this rule. This service object can be found in the "Standard" object tree.

Drop packets that are associated with no known connection

Add rule on top of the policy to match packets in state "INVALID" and drop them. This is implemented using iptables module state with option "--state INVALID". Additional checkbox makes generated script drop and log such packets.

Bridging firewall

This option changes algorithms used by the policy compiler and makes it generate script for a bridging firewall. A bridging firewall treats broadcast packets differently, never uses INPUT and OUTPUT chains, and has some other differences.

Detect shadowing in policy rules

Rule shadowing happens when a certain rule is a super set of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. For example, if rule #1 uses the network object for the source and rule #2 uses the host object located on that network for the source, rule #1 "shadows" rule #2 because any packet matched by #1 will never be matched by #2. This may be important if, say, rule #1 permits and #2 denies access to the same destination. If rule #1 "shadows" rule #2, then rule #2 will never fire. This situation is most often an error; the compiler can detect it and abort processing of the policy with an appropriate error message.

Ignore empty groups in rules

Compiler supports special case when empty group is used in the policy rule and there are no other objects in the same rule element. Depending on the state of this option, it generates iptables commands as follows:

  • OFF: Compiler treats such case as an error and stops processing. This is because group with no objects is equivalent to an empty rule element ("source" or "destination"), but empty rule element is normally considered to be equal to "any". To avoid errors this may cause, compiler considers this situation an error.
  • ON: A group with no objects in it never matches any packets, thus rendering the rule useless. When this option is turned on, compiler just throws such rule away.

This is useful when one needs to control access to/from a group of hosts which may change and sometimes becomes empty. When this option is turned on, compiler will automatically disable the rule if the group becomes empty. Group contents can be managed manually or by a script using fwbedit command line tool.

Enable support for NAT of locally originated connections

By default sessions initiated by the firewall are not considered subject to NAT and NAT rules are not placed in the OUTPUT chain. However if this option is checked, compiler finds NAT rules that can match sessions initiated by the firewall and places them in the OUTPUT chain as well.

Clamp MSS to MTU

This adds a rule on top of the policy with iptables target TCPMSS and option --clamp-mss-to-pmtu which automatically clamps MSS value to (path_MTU - 40). This iptables rule is added only if IP forwarding is turned on in the host settings dialog. since IP forwarding for ipv4 and ipv6 can be configured separately, rules with target TCPMSS for iptables and ip6tables are also added separately if corresponding IP forwarding setting is enabled. Finally, this target is only available in ip6tables starting with version 1.3.8 and compiler will not add it to the generated script if version is set to less than "1.4.x" in the firewall object dialog.

Add rules to accept IPv6 Neighbor Discovery packets to IPv6 policies

When this option is on, compiler will automatically add rules on top of the generated IPv6 script to permit ICMP6 types router-solicitation, router-advertisement, neighbour-solicitation, neighbour-advertisement (both INPUT and OUTPUT).

Default action on "Reject"

This defines what kind of ICMP message will be send back to the sender if packet matches rule with action "Reject".

Always permit ssh access from the management station with given address

When this option is checked, compiler adds rules to permit ssh access to the firewall from the specified address block. Rules are placed at the very beginning of the policy to make sure ssh access is permitted even if there is an error in the policy which otherwise would block it. Added rules permit packets that match both NEW and ESTABLISHED states to avoid breaking ssh sessions that were already established.

Install the rule for ssh access from the management workstation when the firewall is stopped

Generated script recognizes command line arguments "start" and "stop". Running with argument "start" causes it to flush all iptables tables and rules and install rules defined in fwbuilder GUI. Running with argument "stop" causes the script to flush all tables and rules and set default policy for all chains to "DROP". This effectively shuts down the firewall for all kinds of traffic. When this option is on, compiler adds rules to permit ssh access from the address defined in the previous option even when the firewall is stopped.


Tab Installer

Directory on the firewall where script should be installed

Installer will try to put generated script in /etc on the firewall, unless this option specify different location

User name used to authenticate to the firewall

This can be root or any regular user name. See "How to use built-in policy installer" on the web site at http://www.fwbuilder.org/guides/firewall_builder_howtos.html

Alternative name or address used to communicate with the firewall

Normally installer uses address of the interface marked as "management" to communicate with the firewall. Note that installer uses IP address rather than run DNS query for its name. You can specify different IP address in this option if necessary.

Command that installer should execute on the firewall to activate the policy

If this option is blank, installer copies script produces by the policy compiler to the firewall and executes it there. If this option defines different command, installer copies generated script and then runs this command.

Additional command line parameters to ssh

This can be useful if you want to use alternative port for the ssh session to the firewall. Just put "-p PORT" here and this option will be appended to the ssh command line.

External policy install script

Put the full path to your own installer script here if you have one.

Command line options for the script

Command line options to the external installer script go here.


Tab Prolog/Epilog

Prolog section

Add commands that you want compiler to insert into generated script here. Prolog section is added at the beginning of the script, before generated iptables commands. Note that generated iptables script is just a shell script, so commands you place in the Prolog and Epilog sections should be valid Bourne shell commands.

Insert prolog script ...

you can control where exactly commands specified in the Prolog section will be placed:

  • on top of the script: commands will be placed at the very beginning, before anything else is done.
  • After interface configuration: commands will be added after interface configuration is done but before any iptables commands.
  • After policy reset: Policy is reset by setting default iptables targets to DROP in all tables and all chains and by purging all existing chains. If this option is chosen, prolog section goes after policy reset but before the first iptables commands.

Epilog section

Epilog commands are added at the bottom of generated script, after iptables commands.


Tab Logging

use LOG

Use target LOG for logging

log TCP seq. numbers

Available if target LOG is used for logging. Log TCP sequence numbers. This is a security risk if the log is readable by users.

log TCP options

Available if target LOG is used for logging. Log options from the TCP packet header.

log IP options

Available if target LOG is used for logging. Log options from the IP packet header.

Use numeric syslog levels

Available if target LOG is used for logging. Use numeric log levels instead of the names "debug", "info" etc. This option was added long time ago because of a bug in iptables and probably is not relevant any more.

Log level

Available if target LOG is used for logging. This option refers to the syslog log level and is used with firewalls that support logging via the syslog protocol. Here is the list of the standard log levels: "debug", "info", "notice", "warning", "error ", "crit" and "alert"

queue threshold

Available if target ULOG is used for logging Number of packet to queue inside kernel. Setting this value to, e.g. 10 accumulates ten packets inside the kernel and transmits them as one netlink multipart message to userspace. Default is 1 (for backwards compatibility).

netlink group

Available if target ULOG is used for logging This specifies the netlink group (1-32) to which the packet is sent. Default value is 1.

Log prefix

Log records will be prefixed with a string you enter in this option. Firewall Builder supports the following macros in the log prefix that are expanded at the compile time:

  • %N rule number in the GUI.
  • %A rule action
  • %I interface the rule is associated with
  • %C (iptables only) iptables chain that this rule generated code for.

Logging limit

Generated iptables rules use module "limit" to limit amount of log data they produce. You can limit logging to a given number of log records per unit of time.

Activate logging in all rules

This makes all rules log, regardless of whether a rule requested logging or not. This may be useful for debugging but produces a lot of syslog data and should be used carefully.


Tab Script Options

Load Modules

Compiler adds commands to load all available iptables modules into kernel memory.

Turn debugging on in generated script

This option makes the generated firewall script print all commands when it is executed. To do this, compiler adds "-x" to the shell command line at the top of the script.

Verify interfaces before loading firewall policy

this option makes compiler add commands to check if all interfaces defined in the firewall object in the GUI really exist on the firewall machine. Generated policy is probably going to be incorrect and won't load because of iptables errors if it was generated for an interface that does not really exist.

Configure interfaces of the firewall machine

This option makes compiler add commands to configure IP addresses of the interfaces of the firewall according to the "Address" objects added to interfaces in the Firewall Builder GUI.

The script generated by fwbuilder v4.0 does not rely on special labels of the addresses as it did in previous versions. Also, in the past it purged all addresses and then added those defined in fwbuilder back. Script created by fwbuilder v4.0 does not purge addresses, instead it manages them incrementally. First, it obtains the list of IP addresses of each interface and compares it with addresses defined in fwbuilder. Then, it adds missing addresses to the interface and deletes addresses that are not configured in fwbuilder.

Clear IP addresses and bring down interfaces not configured in fwbuilder

If this option is on, generated script will clear IP addresses and bring down interfaces of the firewall that have not been configured in the fwbuilder GUI. This can be used to ensure that the configuration of the firewall machine is perfectly synchronized with objects defined in fwbuilder. This function does nothing to interfaces configured in fwbuilder, regardless of their type ("regular", "dynamic" or "unnumbered"). Be careful using this option, especially in the early stages of building fwbuilder objects for the new firewall. If you forget to add an interface that is supposed to pass traffic to fwbuilder configuration, generated script will shut it down when this option is turned on. However when configuration has been debugged and is known to be correct, it may be useful to turn this option on to make fwbuilder completely take over management of firewall interfaces.

Configure VLAN interfaces

When this option is on, generated script will use vconfig commands to configure vlan interfaces defined in the fwbuilder GUI. The script tries to do this incrementally, that is, it compares requested set of vlans with existing vlan interfaces on the machine, then it creates those that are missing and deletes those that are not defined in fwbuilder.

Configure bridge interfaces

When this option is on, generated script will use brctl command to manage bridge and bridge ports. This is also done incrementally, by adding bridges and ports that are configured in fwbuilder but are missing on the machine and deleting those that exist on the machine but have not been defined in fwbuilder.

Configure bonding interfaces

When this option is on, generated script will use ifenslave command to manage bonding interfaces. The script can manage bonding interface slaves incrementally as well.

Unfortunately since bonding interfaces are created by the kernel module which is difficult to unload and load back reliably, the script can not change bonding parameters (arguments for the module) incrementally. However, the script includes commands that load "bonding" module with parameters defined in the fwbuilder GUI. The module will be loaded into the kernel with these parameters if the script runs after reboot. Bonding interface parameters are defined in the "Advanced Interface Settings" dialog of the bonding interface object.

Add virtual addresses for NAT

The compiler can generate commands to add a virtual address to one of the interfaces of the firewall machine if this option is turned on. This is needed if a NAT rule uses an IP address that does not belong to any interface of the firewall. The firewall either needs the static "published" ARP entry for this address, or it should be added to one of the interfaces as an "alias" or virtual address. The policy compiler adds code to add an "alias" address to the interface on top of the firewall activation script.

Use iptables-restore to activate policy

If this option is turned on, compiler generates firewall script in different format and uses iptables-restore script to load it. Both all iptables commands and the call to iptables-restore to load them are parts of the generated script, you just need to execute this script on the firewall. The advantage of this method is that operation of loading policy using iptables-restore is atomic, that is, either the whole the new policy loads into kernel memory, or none of it does. If new policy has syntax errors, it will not load. If generated script does not use iptables-restore to activate the policy, it may load partially if there is an error in one of the rules somewhere in the middle. Using iptables-restore helps avoid this problem.


Tab IPv6

Order in which IPv4 and IPv6 rules should be generated

Compiler can place ipv6 policies before or after ipv4 rules. This option controls the order.

fwbuilder-5.1.0.3599/src/res/help/en_US/tip06.html0000644000175000017500000000054011733011756022146 0ustar sylvestresylvestre

Welcome to Firewall Builder!

You can meet other users of Firewall Builder on our online discussion forum. Several hundreds of users subscribe Firewall Builder mailing list.

fwbuilder-5.1.0.3599/src/res/help/en_US/tip01.html0000644000175000017500000000076611733011756022153 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Firewall Builder Getting Started Guide

Examples, advice on troubleshooting, tips and tricks, iptables and pf configuration examples from numerous online guides, tutorials and books reproduced in Firewall Builder - all this and more can be found in the Firewall Builder Cookbook

fwbuilder-5.1.0.3599/src/res/help/en_US/vlan_interfaces.png0000644000175000017500000002711011733011756024171 0ustar sylvestresylvestre‰PNG  IHDRАžsOhiCCPICC Profilex­—gTSMЗЧч$$єŠ  tAz/‚є.щUщMJ])‚є.HGP”Ђ€вщEQЄ "HAъ=шЫѓЌћс]їЫЕВц—}ўГgrіdіl(ћlq8wРУгo ЁЬjfnСJј # М@мжоЇ„Х^€%џЅ§њ ЃGУGОh—НŸzrфL „ŠЖИ†ў—AЧf <яршc?>šїВƒНЬ 0ЏzxxСў)ќѓиу№№XЪЛ0sНИ‡[ №Z Щm&М<`ГѕЏэL!tiДbџЕmќyW§k'1б?ю 2ePŸ7ИсЕСњ§дУУнтУУ§uŽзN”LІŠ˜ђ™vњlљХpFwVkNѕЋтМм‚є7ёEсяќK<Ыœ?NЏ0­2Ќб­c6Ј~Rl’§"о"мFџFя wQ{Ј}‚Ф!txЧŸм†ЁˆbdС]д(!?Q 5iЙХ.еc žVŒnѓD-Ѓ sы)§гClВь‰}œ?Й1gиyјyEЯJѓЩ№K HŠ ѓˆpŠВˆб‰“J‰ ЩYЉaщv™*йьsсrЎђиѓ ЬŠŠ?”Ц”{UъUяЈ%Јhиhjj jгjoщŒ]hжЭзЛЎo‡еМ(jРjHiИoДdyиYY]•[[јшЪc›ZГ:§zЭ'ŠOЅ„Й›XšiZˆ[žmД.ДM<jяъxвYо•гаs­зЃЯЊџТРЙМ/O  ЎПš~§zЈуMУлšсяюП/ў?’5šњ1n,rkvhkGши^зeднд{Ћ_MОˆ705”7т0&2^6‚їР-s cKq+jЋы——*.Члрl-эtьЯ9:В:aœ‘Ю._\‡мž])wЯ№ИюyХЫЇэ­ˆ—ѕ‘єѓё р <Ф~•%јDе5тPњ > &Т_F4F–оH‰ ŽvИЉ#Ы‡ˆ›™P“˜‘l‘"ŸЪš†H›MяЩ(Л“щ’Ѕq›;•=›г‘[”’oV QH]ИZ4tЇЖ8Ћ$о :ЅТїщюя”M•wV”>ˆ}xЅRЏJИšЖzЇfіб›ЧЕѕuхѕљORŸF6ј7К4Y4ыДШ=уoen#kл}Од>йёЊѓyзЃю;=iН}о§Жи /Y^‘ПкН:Д№fцэЬ№мЛ…їKVFжG7?nэL">ЁЇШЇ?ѓб˜q™MšЋџ:Й€ў&Аhќ=tЉ|yt…zеz­yCьчГ_F[+ПwЯюѕиХџoю;Ъ hIю.`*€6œЃ зрЮ€&,9F2њA   5}Чљƒ№` мA$Ш5 Lƒmˆ т…”!+(Jƒ*ЁhA€р@(#ь7ЅˆФ*’Љ€tCf!{‘;Тю VQ2Јhдњ,:=F(I˜AИIdFдJЬMœB|@тEђ…дœєйEВ7фЦфN”TдTEд"д3Ь*M-э žž‰Оч„УcъIѕ“;LUЬv,Œ,УЇRN_dЅegЛЫюЭЁФIУ9ЯеФЦŒ‡ЮcgЃљLјyљFы„в„ё"ЦЂ2bЬbћту ’R8i}!YŒьіЙ)Й~љ'чя*d*Ц)…+_SЙІЎЃžЎQЄYЃеЉ=ІГЁKЉ'ЈХњ^Ь3ш1м0ц0167ы4пЗ”ЕКjнz™РFз6лnСAж1бщГ‹Иk”лwЯaœ w<~бWзяQc`DаJАUHЈиѕœАƒЛШž(ш[1PЌgмT‚Ab_ВbJsšLzг­ѓ™=З/fOхzчЃ ђŠ$я —ряб–6–йT?ЈЋМTЎy№XЏv­>уЉlУLSRЫЙgплђл :‰Кк{‚ћФњПНШдyѕ{Јь­щ;тї-#Имc“™ŸАгфŸ_ЬФЮiЮ.є.Ц.щўРЌŒЎl8lђ§њЙнЖ“АgyРџчќРРЗAE` Ышчnљ pHYs  šœ†IDATxэ} \Uћџ3ьr[Xб”МхЊ(Hš&V*њ&Ј˜Z`Ђj%R&VЂџд^“Ь[ЁyїMдJ4)/)^ћ#&*d(Јˆ—P—‹,ИАЫ^~чЬь.АьeXиYіРgіЬ™s}ЮwЮyЮœяe™ ЬЇcZЋ%„<сХж*лRЎ JРЪыdЉR+J …fкkEVwJ +ьЌˆj)ШЙLнкЩ§;ЫZБё–ЂJ …qƒЯrД&Ижr9P%Љ WЪVШ4BzУл?WћC@шМH`‹!g-дДLэСЄo k'JрщА?ІeJЅJб‰ŒаV!ЖнЕaAw{§WеHn—‰мэ‘мЊF*ГfiЫОУЙрљиTB0јРшїqUюЌ…ђЉв˜ясE7 ˆйро­EŠЌ-D drXU2Њ\ЦЉMЁєyАŸv8Ѕ<гѓ+‘ЩѓЫЊ ьЌ „/ ‰ OзБЄrBJ ‰ƒpВ•ЁРŽ\pчШ­єш6‘ŠЃІ‡žш)[§2НДRUВ›pщp*AЈ 1ЊЧ^@hИДЮЅЕ$™ыšѕCИй?–6L<‘{Еa Ж.ЮЖU5rфJЋ%6,B({Жќбs+‘DоЮš…†!A5 ‹wJeЁОЕЂ!Яџ„Ž.8|Ь98Лgƒчb; \ёѕ№4ьŸЋHХл C‡€# п‡mA0ВAZETm?эРЋ/ž>аhQ3fќіЅpё:4ЖUц@RЦ gМ7XЅА3ŸŽ9ННрŸЕpr ? М@ќў7 „НaкџР]{_…bM%ЂІ9“сО†_@a tu…Ы‹сЯ4шА ІО UW`Чt€оБlЎСŽйšri|˜ž;eЬГ+ђБyЌVТ@лТюЖЅj:N­€№t`{qmИ6VЌnЖмm}]m}]Ќбр З"XQ#Е’ШЌьYв9ud…/•>PDЈ,„ЧЗСy1„Пб{J%аyМНGАžЃGa4ф‚KЁВ ЊЅХAКк{‚Г9}8К€cw=ЄРbƒѓ> ЇЗvУйЛ*Ђ9x€ИїњЙяP2œjкvZнрсЭh@љ”*E]ўŠюТSи8ТЫ“pƒо{;p ž№-Qq‡7ЋгT\(ї:joY{BќюпUу~yѕ’ЊŠ…хевт*щ=ЄL$EC— Vсыdа5Ђ#ЛЗ3сР6—tЛ?џ СБЏaX(Ž^ѕ7œ_WГБпs>Zлс#rGШџ vŒХїЎZZ*‚ЁЧмDј~м-УщœШ^Wз7ыžЇС/‡pLз дФУСЏёЉFїчŠІeХТ/гскYЫљeАоШБС'^ŽНз~ХЧfuДб-ЩЙЅ*7ис—%VвёјvАяэb‹bКsиЎЖЌŠщ]фвSёй"1R/Ў”JГJ%yхвЪљs)!еЏЊ*7*иqщЖіјhџ2D…зАŸE*=ТЕsŸvсGсУадO‹/ъ*сєZ=i$ѕЏ}Њ@ >ПЂў5ЕГњеІ’šЌМ>2№ј>ާтtшгр>феvŠZ.>Ѕ”ћHЧќЌ фщТ. Д/0ДМћqYЕщ“ЎvV=œиƒ:иМъaнн‰ecE hЯvЕ4^<Ъх,Bю„u{zNBА"rИоoК+ўзŽUЄ?6 жЯ„‹ёЉ}wIN%д5*­"ž? kЈa“Kг`шDЊ8Њ\бєџЂ2dиrU0 Я-Ш'Aаw(RX э;—•‹dжVайžдž5ТьЩzЅН•‹ Сж7cT(f0ПЏ `œ?Œ duЧ#ФЏ`Ь~ьAcчcˆJ‡WF@ёХ8,рЋЇmPеF”SjL;1пуЛЙжУTЄVУЉŸp˜ zШБЌіЂ^_Ю_Š(Uџ@ё!(ЊVœоHе›ДєЌ2ъциЫ–й.ЃГMcуc{cЄF ХUP$А*ЊЅ"ђёдE{68В,ќ§ыsЗрR&žмРkШ ?q!$ œ{Уаоdк"EЮ/Р`дЄ+Э„S;АЏ^Z2„Š ~ЌЋhђSѓ‚ЂЖ{!g6є}\ЛCщUvƒЮ. "'ж1ЫЭiзжBжМЃ ыtшѕ“ж_­љХG j"ЮсжИ‚ЗrЁѓ<_ф*Ђ^э&Зцц–X шйDITŠˆВjЈЁ…tтX9ZУРЎu;@[ {C‡Ž М Т'ŠЮЏa%ПnКр<ЌдбВ Ї-k'ѕмkдfЈ~Mп9g™Šщt•8wQЯЎ)EЋчеШѓжD#ЋмŒЩœ—A”rќPeћјGиѓЅъЬXžV,Zg“ ˜2tцУЬ‹х?ССKyћЛЩэmХЂuжНm:Eг6/ZSmГпЕЖšюВSkІtсHТБ-1:V ІTWS­‹Y‚ЭfЃэY}Nњ ++їŽ@_Д6zншJ%кс$№Žwуп$ДьІхт§V*єіДшмР™ЋWяЩ^дWoІљЩ['Mо„Ђ}ЖfХпhАBе›ѓ"R‰є№7П žайЧЋ)ВщM RТsТчЯŸы-Ш&ќэє7œ Ѓ!lзЮˆюB†/œiП59žм(б[“#ш—K[WYRyjћщњvёёwlча”м'л фЁaŠ}ЕТнф™cзh*+Ÿ‹E"zEр†#М›Хвœ@p"aDmјb† ќŽЇфй–Н Рьпџi!т~ЮƒУ )ŸЙ!•Њ=˜ем CКЎњвkЮ фAP а€p№Яš›Wџ{=б!%‹ХšљW§ќ§ж“wЃЖ!„'cп_ОхlJьd19ЛшбщtŸа‹‚‹{?€Ы9љvцэZHˆRБєЪ‘Ќ#ыRŸ(Ÿ47VДд?ЪрЩгЧїяплЗw§ЬlœрrмТХ%AЛ3vЦ…УКрЗŽоФ=-,Иœ<'&^8aћЙхэŸмИ рэNБ—€хб)ря›M­9§JЖVLЃOj {іИќиІЏЯ ъьлYэ’юS4Sў oRS†jОјЭчЗciЧЋЋЋdЩшЮ„К*Fzчg‰йџŠN§њ-ЯLšv№DсXŸЎ8*рд‹kN'F„c{Ч&>‡Ш:xIќУ ˜ђђr„тцЂзПH‡^*ŠKJВŽс8‹C—жажx№S`№'d&qчв†vвАіф-JXq'jnЗ!dЌ№ŸKп1џёНclћMRIі­Cь˜EхЯžэЬиЊ;ЖДZvЖ, ЪDlЎ“JOа˜J№/џ9А];‘a1Ь+аш#DŸ[$эћїюсх†>ЧВЃF~['НьдЩ­-<БVЩЬш#„Њ$‹‡hЙSŒ‡Ѕ’@X0POf AІ^п6ъФЌA CGNm—DcєUёыŽгмнЅQWu‘hЬ›5c\@`ТЧbkxЄ%.4/AFS)вќпŽфЛŒцI]еFЂ1{жŒ!“Щ­њUXNНИ_Џœ=œC?_/ˆЦ bB XЭDQ+Or-dйŠ ћU€@—Ыб‹їШ!†E-‰ЦќY3Fд!ЌЌЌKJM№дщр‰sбš S–П%Д?@џ“œчЃ*хяўfњ‰YFєOиW@UвЙњп‹[Ор‘$šНЇЩ—E+ЬŸ5cD@ БvуuѕђщDЩWu|q ЗgїŽЊгFxšF)кш:9‘Л$хщЩэ?є[1|^&М‚Ц†єZО4cЯ„xkž$бФЬ§ЙуцŒ­Б!љЋ_џGxЯќY3Fœ2ЈžѕOYѓ;6'F:{ыџHљ :6AF˜sq;Рь—…`7$А$пИ+ќRП (єюУм“Ќ•я™†,9s8 mhu З.хrQETђšyГfŒЇN}GО|§D6е§‚pИшеіЦИf!ШАЌБiэ“‘Н'ЪѕŒРЛ[RŒ’Ѕ€џ”~ді&т] ЪJжX3F’/ФнЌ‚ŠтŠі]кї ЄnA…ищџ4AF*Ф<§И+ОыWKкFГ ,WлS’eT•l Ќуъ”(б 3i‘ ђв4UђЅяС™л…'ŽŸ:“~>ѓв_7nфоЛ_Q.$$,k.EAq**єd8М йЋЎН˜УVфффѓ5†хрyqЉЙ|a(Њ‰It$k&Бf …PQ`–Ќ™–!$;ѕъ42rD‡Юэщƒ@Г™ 2lЯљЅl#'Ях%SEФgџйгјсHZ9Х=)6у\фрzbaлтБ„œjmЪЬY3fЕ§M“ Cс@T!Iи.œкdеBAд QЁВОЧŒY3ѕn…њ­fоM‚ е0[Ў“:CвŽуdGЋеfЬš1Ћ‚VgZ"щ”@cT<Z.2[@0ЛџšНі@(Dj!зP‚АB Й†„IЏ2šўNЩ5Ђ‚Ke_ЪњmGљТ K|•ІаQoi#цh W нРг„iZŸб$оf%зTм ќ€,йЈuкˆ9кТkSш3щ)ƒВ>“ўП3•Я№DSЂSPќ*ЪфuЄB Б>ЃVLЎY|ѕYнаZrMmh-ЙЦ{XШё”№МЅлВёїъ;ЎЯЉЇ—.d/СЖяkЖДкТkSъ3i@P1-ы3F'зpммj_MWtЇ6bŽЖpCQP'>jk2жgZ‡\Ѓ˜Ѓ-МNџь5]ЂaSZнњLы’kДsД…7 &Ђе­ЯДЙF1‡e§ѕqѓšЙa LФњL‹‘kА˜л…6bŽЖp*UуŽ а!ѕ™аE!/xЉqЖˆLž\ƒЭ!†EЇaЮv"~!џn&y?Щ/**Фь­Ф#vLz„09ы3Ц!з sˆy‚б ШUф-юq™єЮчј' Ж!kЉкˆ9кТЩ s0щэяІ?ЉЄ/FkДsД…гoО*ІI&h}†\k‘kДsД…ЋК™ОЧЄGњЭАФl. 0@ЉlЎІZђЁ# шHЉ ХБBбй‚ % €Аd(A˜є*ЃщЫЮ6@бJЈQ нРг„… SЗ+ЕaДjъІ5ШoвS†… ЃьKэDЭ„e:УMTs,аE„бDЈ1Њ ЊЋ… ƒv7Zц{OІЋCЈ0ЋђX2JQрЏМщ{OL„… Ѓ„1ПїФ @X2уt~яIPЃHѓЫТBбJС=Ў‰Pг$(☺a!Шш%Шh#д4&Н§нє'•єхТh‚ §fъiв#„… ЃжЭH„QЫYujв#„Њ–O‹I€Je‹ЩТR’€д“€ qX2” ,€PТBЁaвЋ E_5сЧм 2ШVЩЯпЧ'Є“ІхУ6lX0џЕ&~vжЬАФАЯ3i!Мh!Ш<П’ЫW§ќs'ПэžSћ7ЬїmТдf”J3Е у4EpiC|АЏOЯ‹тт‚ §№UASраFVŒњ<“&Т‹v‚ ‡ЋВЯlыиФй‚DR›S*™јy&:–bD7ЯЧЇ€ш€&ЂТќu„{ѓј<“K1Т›Lї]с_Ўkšdе&AaйœƒнИНh@GфСJЄМДŽІfA†ЊtбБнЃƒзлАuяќеќAЋ=š"Е @0юѓLj„–b„9) с~_жESџfў:„9[‘<иЮ[†њМЗЧГьѓYYш?ЋHыЗ”щaУЬGF|žЉёd$•иє@ќ№Ewѓe\ЇюзхсД,лп QY2” Ь|„ }c#>Яd!ШаяPKЬц‘€љ+•Э#Ї6“‹mІЋщ5”I:ФЗЛt4ъ“=‘:ЎZ.б”cаА{Яz­šБР˜<ШЪЎtъслЃ‰[:*nZ—JlХ1ј!оo3jfЌWs™LF[ЎТ3+жі8]—WќЧL}ЭSыї[ХчЮ\НњЧьE<єСјєЯПЪі›цMЛ,цEdЈ!Ї$}ў‘єZ‰4ЏвАЇsќєфд|№шь\’‘Д.2fєдdы0ШVa…œ$ѕмнjцuВ!5ЎwŸ’Аuтюœ$ВЗ!€јљ†DѕYfТ№КјO™нтпK‰Ÿtё^EВ'­ЯqоЮОіЖОHLПЮАbцAлiћm@S^bwgѓbѕoЯъщЈи 2 3DиФ€SŸWбЗЮ8xЈ(и§>шўУЂї4ќOFЯ^О/ŸLˆуˆЅтѓˆ•љеќ“c2•ƒ•43!vVьYlЫžQŽa€PШV9&PSFОSЮ„ќЌ•”ŸћыœtДо[ДХiТъ­]7gЇЯMфe$„8m-Ђ0SЇ;ЫђўКЮ'C%E&ЌXџ0.mџё{ПnOеŽэжлП]zмЖыedў•„Иє~Ѓћ4}?КNљ-сe vLэŸ&Fx@SЦб;Иoк„!ВВq‚Ыs>Ÿ5ВџїiIД17м!ыb"@м•‡іѕєє—Д`гщl Њ…3Y0;};РьДMяŽёѕьъ0&Р МА—Є (ЙћїчAи[oИR/“ˆЫ0bж!|ЫЁUš2ъЪЯUˆQGGM˜9Ѕыk^№сuсАAtM=ЛuTмЯl'}iэ€JчКдПџ; њ:П{іг‰ь1щўі{зЋcнњšЎŸUЎ/LДЪpЈп/ѕЏk>ѓїѓ:ВЇъљэЄќK$а Ћ#’*Оъ’fO ўŽЈјЙRaPDВ}ѕУE”№хд‹щаsѓД&бс5—kќP†Mh•QwЪИ№H­Kh LЁT*тsњМА"ў`>_(фчя[М lH­Ѓ8М й‰Џ/?zщ€ЯЯ>YDЎFу№є”Ы=Hп(CЛЎ-‘a#Ze ёЈMQ*е„lчwo'ŒŸ9Щ=_с…oПї‘ЗжЇUˆŠъ9џщ~˜2mq вI‘ њY@>нђ|kзИэ‘ЉqбC ЖШœZћР‚L‹<К– ЫžK€эфB—s$,HиЖ\[хТWz1vрмѕѓNЩЃ˜9@cюгпм’žа-&ьРяK›‰ђкђу“бђв1ДDбПЙчЮ”іŸ8дMЧtchІ-пˆ–•ЗЩ—ЦАU†ЩЫ“ёdЬ*CЗAѕƒјŒя`CР@ †щ%ШкxKќ†` PэoЮSЎяъ7Хg§'Tˆ ѓеqŠCЙИžљќЋ[sЂЧwQх*ШJ[ЕќТАЅqc§ШЧS’Л"Шуи“Д@*#E‹ЈzЃП§tDw†>tP5ЗжУ0@ ŠћnV'GхЮ5Lт_IMMIѕь—6М'% ~jъЩvсбуUr]XїYj Єr_}}O0йлlз^=СљŸЄoJJїŸНмљEpЂ0ЂJЪpѓ!Ъ – žЫ*ŸЫЯх••В сПїžд 6dьэ! #ы̘ір\wЁШџkg)щаѕЕСшл3$ў#Њ”‚.ЙЩ%CЃуУЬgXЈ#>Ую­: [ЭkfїЦ9NшЧщ7Йѓ:Ч•\9*=|щY3MўЁф<4Їќ0 mgџzHЩˆQ#U"ЏЦ„Ъ( ўe ЄЗпЉЙ"К№&š)ЈCХ/~A?$ЎˆXѓуyDhQгKŠ0k&*trtX8@ъœcE†РфјЬDоЗ?нођћнНЇи‘>A§к•а)dЭN€uУ`vƒв .ЅЃщbE,В$т9yкнq:KSFнм~ІCМзГи‘ырцdхй:ЙIБDGgТFLбж щQ5p§VІЭМcMТР/UZбЅxУsЯтoЎ{@IF2ђЏоsuЊпkjУˆ*™yˆЬ]5vњВ†ЦpнžcЂОкёIмgh;шU2.џњ–­Д|ЩпvBqѕИР>;&Ў?|}щk~.К33“Ћ DРšЧvŽюh„pOТЋбБa-6l•КЎ\б}ЖoЎй?nыДTtJђЃѓSS:ЙtA-+_иyQbJТ‘ДПwМЭЄЯu6ƒa€Ш\и^cs !Мœ” чњ~–Б(50ƒyиќ ыR{-пZї Žп›№ЙВ№oхƒ,Gа\ UcX cv;[„ УАЮ3Fu•7Š1ђnю<быМЭЅ%?u 0f„PЏИхм8`оsуШС’ЋB@X POLв!^IzO?щIљ?‚@ся™QЏe–“FI€1€XЋЯ‚Ь{ ZЌ 5 u1*„ѕD ’CЊEsЌ№рAЧеЕ ]^ ък b0ћ2 г!Ќ'YENwjФ[мЉxCjїюнюююд€e mшPY)мšМ.ђƒŸjоз–\ŽОw•rє|эVЈyи—a PEY‰ЙГgxЙy^,;тR…Р1cЦŒЇOŸR)iŽTwb 2ёэŸDŸ%‚гЪ'йЪОІѕ+ЙВlёUеSsl_цр"FОр[ЗЙŒК§Ѕ‡ф‰лve NкЕ' “Ёц lзЎ]h„АВ2МŠ—}нмб>gv…тLГd8ц§„}”д$Џ ‹NCплШп§Э Г4ŒшO^­k_†LВ;ѓтЦ/H3“їžV $ШDЩ–PlЄ†GФюкјнЌ‘п˜˜Э*УEYN-шЇ*jУВсГюй;ЁЅооŒŒŒD#eТ /Ч—ƒЌ(ыŸ’­ž;ж!Д‘y–9ГXбoе%Зђ2№nЛWаXФ•шЕ |iЦž #dп],\Ж-в08жh‚`wYTz nћ…uIECжlп…рQib:%s † GзЛ4?З™Hˆ‘J0#"і“=3ъtvуМšШHЋ…ЯЋ@ƒe™jЁ  \84)Ивj`)о’ž‰8џє‚3зghІ‰6ЎњMNХ$>ѕ8š9№mnдњ§Шйжьљ;#š, cg иK _4nvPзЂфMЉй0;ЅіuBc—M3&‚f“L9?'ѓЯ?o?~Z ЖЎўуGљљ(єгЉГІг&QЦ(•&!­6P Уі}­гБлћu]БˆЦG‹ЧGз Бј-џЉѕ­hђѓѕIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/tip05.html0000644000175000017500000000030611733011756022145 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Found a bug ? Please open bug report using our bug tracking system

fwbuilder-5.1.0.3599/src/res/help/en_US/iptables_Branch.html0000644000175000017500000000063411733011756024270 0ustar sylvestresylvestre

Rule Action "Branch"

This action is used to create a branch in the rule set. For iptables this action is translated into "-j" command line option with an argument that points to a user-defined chain. To use this action, create new Policy rule set object, then drag and drop it into a well in the dialog of this action. Note that you can use policy rule set object of another firewall as well.

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_5.0.1.html0000644000175000017500000003434711733011756024571 0ustar sylvestresylvestre

Firewall Builder 5.0.1 Release Notes

SourceForge: Tickets

Summary

v 5.0.1 is a minor bug fix release.


GUI Updates

  • moved "batch install" button from the main installer wizard to the dialog where user enters their password. Now user can start in a non-batch install mode but continue in batch install mode at any time if all their firewalls authenticate with the same user name and password.

  • see #2628 fixed crash that happened if user create new firewall object from a template and changed one of the ip addresses, while another firewall object created from the same template already existed in the tree.

  • see #2635 Object type AttachedNetworks is not allowed in the "interface" rule element.

  • The drop-down list of interfaces for the "route-through" rule option for PF and iptables should include not only cluster interfaces, but also interfaces of all members. This way, we can make compiler generate configuration "pass in quick on em0 route-to { ( em0 10.1.1.2 ) } ... " for a rule of a PF cluster. Here "em0" is an interface of a member, not the cluster.

  • fixes #2642 "GUI crashes if user cancels newFirewall dialog".

  • fixes #2641 "newFirewall dialog does not accept ipv6 addresses with long prefixes". The dialog did not allow ipv6 addresses of inetrfaces with netmask > 64 bit.

  • fixes #2643 "GUI crashes when user cuts a rule, then right-mouse click in any rule element of another"

  • added check to make sure user does not enter netmask with zeroes in the middle for the IPv4 network object. Netmasks like that are not supported by fwbuilder.

  • fixes #2648 "right mouse click on firewall object in "Deleted objects" library causes GUI crash"

  • fixes SF bug 3388055 Adding a "DNS Name" with a trailing space causes failure.

  • fixes SF bug 3302121 "cosmetic mis-format in fwb Linux paths dialog"

  • fixes SF bug 3247094 "Nomenclature of IP address edit dialog". Network ipv6 dialog says "Prefix length".

  • see #2654 fixes GUI crash that occured if user copied a rule from file A to file B, then closed file B, opened file C and tried to copy the same rule from A to C'

  • see #2655 Interface names are not allowed to have dash "-" even with interface verification off. We should allow "-" in the interface name for Cisco IOS

  • see #2657 snmp network discovery crashed if option "Confine scan to network" was used.

  • fixes #2658 "snmp network discovery creates duplicate address and network objects"

  • enable fwbuilder to take advantage of GSSAPIAuthentication with openssh using suggestion by Matthias Witte witte@netzquadrat.de

  • fixed a bug (no number): if the file name user entered in "Output file name" field in the "advanced settings" dialog of a firewall object ended with a white space, policy installer failed with an error "No such file or directory"

  • fixed SF bug #3433587 "Manual edit of new service Destination Port END value fails". This bug made it impossible to edit the value of the end of the port range because as soon as the value became less than the value of the beginning the range, the GUI would reset it to be equal to the value of the beginning of the range. This affected both TCP and UDP service object dialogs.

  • fixes #2665 "Adding text to comment causes rule to go from 2 rows to 1 row". Under certain circumstances, editing rule comment caused the GUI to collapse corresponding row in the rule set view so that only the first object of each rule element that contained several objects was visible.

  • fixes #2669 "Cant inspect custom Service object in Standard objects library".

Changes in policy importer for all supported platforms

Changes that affect import of PIX configurations

  • changed token name from "ESP" to "ESP_WORD" to avoid conflict with macro "ESP" that happened during build on OpenSolaris

  • see #2662 "Crash when compiling ASA rule with IP range". Need to split address range if it is used in "source" of a rule that controls telnet, ssh or http to the firewall itself and firewall's version is >= 8.3. Commands "ssh", "telnet" and "http" (those that control access on the corresponding protocols to the firewall itself) accept only ip address of a host or a network as their argument. They do not accept address range, named object or object group. This is so at least as of ASA 8.3. Since we expand address ranges only for versions < 8.3 and use named object for 8.3 and later, we need to make this additional check and still expand address ranges in rules that will later convert to "ssh", "telnet" or "http" command. Compiler still generates redundant object-group statement with CIDR blocks generated from the address range but does not use this group in the rule. This does not break generated configuration but the object-group is redundant since it is never used. This will be rectified in future versions.

  • fixes #2668 Remove "static routes" from the explanation text in ASA/PIX import dialog. We can not import PIX/ASA routing configuration at this time.

  • fixes #2677 Policy importer for PIX/ASA could not parse command "nat (inside) 1 0 0"

  • fixes #2679 Policy importer for PIX/ASA could not import "nat exemption" rule (for example: "nat (inside) 0 access-list EXEMPT")

  • fixes #2678 Policy importer for PIX/ASA could not parse nat command with parameter "outside"

Changes and improvements in the API library libfwbuilder

  • function InetAddr::isValidV4Netmask() checks that netmask represented by the object consists of a sequence of "1" bits, followed by the sequence of "0" bits and therefore does not have zeroes in the middle.

  • fixed bug #2670. Per RFC3021 network with netmask /31 has no network and direct broadcast addresses. When interface of the firewall is configured with netmask /31, policy compilers should not treat the second address of this "subnet" as a broadcast.

Changes in support for iptables

  • see #2639 "support for vlan subinterfaces of bridge interfaces (e.g. br0.5)". Currently fwbuilder can not generate script to configure vlan subinterfaces of bridge interfaces, however if user did not request this configuration script to be generated, compiler should not abort when it encounters this combination.

  • fixes #2650 "rules with address range that includes firewall address in Src are placed in OUTPUT chain even though addresses that do not match the firewall should go in FORWARD"

  • fixes SF bug #3414382 "Segfault in fwb_ipt dealing with empty groups". Compiler for iptables used to crash when an empty group was used in the "Interface" column of a policy rule.

  • see SF bug #3416900 "Replace `command` with `which`". Generated script (Linux/iptables) used to use "command -v" to check if command line tools it needs are present on the system. This was used to find iptables, lsmod, modprobe, ifconfig, vconfig, logger and others. Some embedded Linux distributions, notably TomatoUSB, come without support for "command". Switching to "which" that is more ubuquitous and should be available pretty much everywhere.

  • fixed #2663 "Rule with "old-broadcast" object results in invalid iptables INPUT chain". Compiler was choosing chain INPUT with direction "outbound" for rules that had old broadcast address in "Source", this lead to invalid iptables configuration with chain INPUT and "-o eth0" interface match clause.

  • fixed bug in the rule processor that replaces AddressRange object that represents single address with an IPv4 object. Also eliminated code redundancy.

  • fixes #2664 Update error message when "which" command fails. Generated iptables script uses "which" to check if all utilities it uses exist on the machine. We should also check if "which" itself exists and issue meaningful error message if not.

  • SF bug #3439613. physdev module does not allow --physdev-out for non-bridged traffic anymore. We should add --physdev-is-bridged to make sure this matches only bridged packets. Also adding "-i" / "-o" clause to match parent bridge interface. This allows us to correctly match which bridge the packet comes through in configurations using wildcard bridge port interfaces. For example, when br0 and br1 have "vnet+" bridge port interface, iptables can still correctly match which bridge the packet went through using "-o br0" or "-o br1" clause. This can be useful in installations with many bridged interfaces that get created and destroyed dynamically, e.g. with virtual machines. Note that the "-i br0" / "-o br0" clause is only added when there is more than one bridge interface and bridge port name ends with a wild card symbol "+"

  • fixed SF bug #3443609 Return of ID: 3059893": iptables "--set" option deprecated". Need to use --match-set instead of --set if iptables version is >= 1.4.4. The fix done for #3059893 was only in the policy compiler but needs to be done in both policy and nat compilers.

Changes in support for PF (FreeBSD, OpenBSD)

  • see #2636 "carp : Incorrect output in rc.conf.local format". Should use create_args_carp0 instead of ifconfig_carp0 to set up CARP interface vhid, pass and adskew parameters.

  • see #2638 "When CARP password is empty the advskew value is not read". Should skip "pass " parameter of the ifconfig command that creates carp interface if user did not set up any password.

  • fixed SF bug #3429377 "PF: IPv6 rules are not added in IPv4/IPv6 ruleset (anchor)". Compiler for PF did not inlcude rules generated for IPv6 in generated PF anchor configuration files.

  • fixed SF bug 3428992: "PF: rules order problem with IPv4 and IPv6". Compiler for PF should group ipv4 and ipv6 NAT rules together, before it generates ipv4 and ipv6 policy rules.

  • Several fixes in the algorithms used to process rules when option "preserve group and addresses table object names" is in effect

  • fixes #2674 NAT compiler for PF crashed when AttachedNetworks object was used in Translated Source of a NAT rule.

Changes in support for Cisco IOS ACL

  • fixes #2660 "compiler for IOSACL crashed when address range appears in a rule AND object-group option is turned ON"

  • fixed SF bug 3435004: "Empty lines in comment result in "Incomplete Command" in IOS".

Changes in support for ipfw

  • fixed SF bug #3426843 "ipfw doesn't work for self-reference, in 5.0.0.3568 version".

Changes in support for Cisco ASA (PIX, FWSM)

  • see #2656 "Generated Cisco ASA access-list has duplicate entry". Under certain circumstances policy compiler fwb_pix generated duplicate access-list lines.

Other changes

  • see #2646 and SF bug 3395658: Added few ipv4 and ipv6 network objects to the Standard objects library: TEST-NET-2, TEST-NET-3 (RFC 5735, RFC 5737), translated-ipv4, mapped-ipv4, Teredo, unique-local and few others.

fwbuilder-5.1.0.3599/src/res/help/en_US/pf_rule_options.html0000644000175000017500000001223611733011756024420 0ustar sylvestresylvestre

Rule options for PF policy rules

Tab General

Stateless rule

Firewall Builder always uses stateful packet inspection if it is available in the target firewall. In case of PF, this means using "keep state" option for PF 3.x. In PF 4.x, combination "flags S/SA keep state" is the default so fwbuilder does not add it explicitly to the generated pf configuration. However, sometimes it might be desirable to create a rule without state matching. Checking this checkbox on makes the rule stateless and forces compiler to add "no state" clause to the generated pf configuration line.

Add 'keep state'

In PF 4.x, "flags S/SA keep state" is the default. Compiler will omit these flags while generating code for stateful rules matching TCP services. However, according to the PF FAQ, care should be taken while dealing with states and interface enc0. To avoid leaking unencrypted traffic out, the FAQ recommends setting 'keep state' explicitly in all rules on the enc0 interface. This option applies only if version is set to 4.x.


Tab Logging

Log prefix

This option translates into "label " in the generated pf configuration. Firewall Builder supports the following macros in the log prefix that are expanded at the compile time:

  • %N rule number in the GUI.
  • %A rule action
  • %I interface the rule is associated with
  • %C (iptables only) iptables chain that this rule generated code for.


Tab Tracking

Activate source tracking

This checkbox enables using max-src-nodes and max-src-states options that can be configured using other elements in this page of the dialog.

Maximum number of source addresses...

This option translates into max-src-nodes parameter. It limits the maximum number of source addresses which can simultaneously have state table entries.

Maximum number of simultaneous state entries...

This option translates into max-src-states parameter. It limits the maximum number of simultaneous state entries that a single source address can create with this rule.


Tab Limits

Maximum number of concurrent states...

This parameter translates into "max <number>". It limits the number of concurrent states the rule may create. When this limit is reached, further packets that would create state will not match this rule until existing states time out.

Maximum number of simultaneous TCP connections...

This parameter translates into "max-src-conn <number>". It limits the maximum number of simultaneous TCP connections which have completed the 3-way handshake that a single host can make.

The limit of new connections over a time interval ... / ... sec

These parameters translate into "max-src-conn-rate <number> / <seconds>". They limit the rate of new connections over a time interval. The connection rate is an approximation calculated as a moving average.

Overload table

this parameter translates into "overload" in the generated pf configuration and can be used to create a table with given name. Source IP addresses which hit either of the limits on established connections will be added to the named table. This table can be used in the ruleset to block further activity from the offending host, redirect it to a tarpit process, or restrict its bandwidth.

To use this table in the rules, create Address Table object with the same name and leave the file name in that object blank. Then use this object in policy rules of the firewall as usual.


Tab TCP

Modulate state

When this checkbox is checked, it makes compiler add "modulate state" clause to generated pf configuration.

This option makes pf randomize TCP initial sequence numbers (ISN) of the TCP sessions opened through the firewall, thus improving protection against ISN guessing attacks. See man page for pf.conf for more details.

synproxy

This parameter translates to the "synproxy" option in generated pf configuration. The synproxy state option can be used to cause pf itself to complete the handshake with the active endpoint, perform a handshake with the passive endpoint, and then forward packets between the endpoints. See man page for pf.conf for more details.

Use sloppy TCP state tracker for this rule

This parameter translates into "sloppy" parameter in generated pf configuration. From pf.conf man page:

This makes pf use sloppy TCP connection tracker that does not check sequence numbers at all, which makes insertion and ICMP teardown attacks way easier. This is intended to be used in situations where one does not see all packets of a connection, e.g. in asymmetric routing situations. Cannot be used with modulate or synproxy state.

fwbuilder-5.1.0.3599/src/res/help/en_US/tip08.html0000644000175000017500000000046411733011756022155 0ustar sylvestresylvestre

Welcome to Firewall Builder!

Firewall Builder can copy generated script or configuration file to the firewall and activate it there. This article explains how to use built-in policy installer.

fwbuilder-5.1.0.3599/src/res/help/en_US/main.html0000644000175000017500000000365411733011756022141 0ustar sylvestresylvestre

Where to Find Help: Firewall Builder Online

External links open in your regular web browser. This page can also be opened using main menu item "Help/Firewall Builder Help.".

Firewall Builder documentation can be found on the project web site at http://www.fwbuilder.org.

You may want to start with Firewall Builder Documentation. You can find several Getting Started Guides on this page.

Examples of policy and NAT rules, advice on troubleshooting, solutions for typical tasks and problems, tips and tricks, iptables and pf configuration examples from numerous online guides, tutorials and books reproduced in Firewall Builder - all this and more can be found in the Firewall Builder Cookbook

Answers to frequently asked questions can be found in Firewall Builder FAQ

Lists of bug fixes and new features for every new version are always in the Release Notes

Project updates, news and comments are regularly posted in the Firewall Builder Blog.

Open bug reports and feature requests using our SourceForge bug tracking system

We have online discussion forum and mailing list

More information about how to get support for Firewall Builder is available on our Support Page

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.1.1.html0000644000175000017500000001110211733011756024551 0ustar sylvestresylvestre

Firewall Builder 4.1.1 Release Notes

SourceForge: Tickets for V4

What's new in V4.1.1 ?

This release includes fixes for a number of minor bugs as well being the first release to officially support HP ProCurve ACL configuration. Thanks to a generous donation of several switches from Hewlett Packard we were able to test and finalize the ProCurve support. This release also fixes a critical bug in V4.1 related to Cisco IOS ACL configurations. Some configurations would cause Firewall Builder to incorrectly generate and error with the message "Can not find interface with network zone that includes address A.B.C.D.".

v4.1.1 has been tested, and we believe it to be ready for production use, but if you do find a bug or issue please let us know.

GUI Updates

  • Built-in policy installer now works with HP Procurve switches. Currently installer can only execute generated configurarion lines one-by-one on the switch; installation method using scp that is available for Cisco routers is not supported yet. This has been tested with Procurve firmware K14.31 on ProCurve J9470A Switch 3500-24. Caveat: manager access should not be configured with user name (that is, no "password manager user-name foo")

  • fixed #1683 When user creates new firewall using snmp scan, fwbuilder will now guess and assign the type to interfaces that look like vlans for the given platform and host OS.

  • fixed #1683 class procurveInterfaces interprets interface "DEFAULT_VLAN" as vlan interface with vlan id 1.

Changes in support for iptables

  • fixed #1693 SF bug 3048516 "NAT rule with 'Use SNAT instead MASQ' doesn't work". NAT rule using combination of the option "Use SNAT instead of MASQ", dynamic address of an interface and source port translation produced iptables command with incorrect syntax.

  • see #1685 "iptables redirecting NAT rules in the OUTPUT chain". This fix makes it possible to create iptables NAT rule with target REDIRECT in the OUTPUT chain. The rule should have firewall object in OSrc and TDst rule elements.

  • fixed #1685 "iptables redirecting NAT rules in the OUTPUT chain". NAT rules should be allowed to translate from CustomService to TCP or UDP service, provided CustomService object is configured with matching protocol.

  • fixed #1686 "can not generate basic NAT branching rule". NAT branching rules were not generated in single rule compile mode because compiler needs information about targets used in the branch rule set rules to decide which chain the branching rule should be placed in. Now it will use PREROUTING and POSTROUTING in single compile mode but issue a warning.

Support for PF

  • No changes support for PF in this release

Changes in support for for Cisco IOS ACL

  • fixed #1690 "IOS ACL and Procurve ACL compilers fail because interfaces are not assumed to have network zone any anymore". Compilers for Cisco IOS ACL and Procurve ACL always assumed all interfaces have network zone "any". Recent changes made in 4.1.0 changed that and compilers stopped working for some rule configurations. This bug caused compiler to fail with error message "Can not find interface with network zone that includes address A.B.C.D"

Changes in support for for Cisco ASA (PIX)

  • No changes in support for PIX in this release

Support for HP ProCurve

  • fixed #1688 "Procurve ACL remarks should be in quotes if they include space"

  • fixed #1687 "temporary access list commands syntax is incorrect". Temporary ACL generated for the Procurve platform was incorrect.

  • Built-in installer has been tested and now works with ProCurve switches.

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.2.0.html0000644000175000017500000022517611733011756024573 0ustar sylvestresylvestre

Firewall Builder 4.2.0 Release Notes

SourceForge: Tickets for V4

Summary

This release brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10.

This release adds interfaces to the NAT rule model. There are two interfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded. Inbound and outbound interfaces in NAT rules are supported for iptables, ASA/PIX/FWSM and PF, but in the case of PF GUI exposes only one interface to the user since PF commands can not match two interfaces simultaneously.

This release adds support for ASA 8.0 - 8.3 configuration generation, including named objects and "new" style nat commands in ASA 8.3

This release comes with numerous improvemends in support for FWSM 2.x, 3.x and 4.x configuration generation.

This release implements import of PIX, ASA and FWSM configurations. Host name, version, interface configuration, object groups, named objects, access lists as well as commands "global", "nat" and "static" can be imported. There is no support for import of the "new" ASA 8.3 "nat" commands just yet. Also there is no support for import of standby configuration, which means PIX clusters can not be created automatically by importing existing configuration.

This release adds ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their IPv4 and IPv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF.

This release adds ability to automatically detect firewall platform from the format of the imported configuration file. Import is supported for iptables, Cisco IOS or Cisco ASA/PIX/FWSM. The program detects firewall platform, version and host name (if possible) from the contents of the configuration and shows platform-specific warning to explain what parts of the config can and can not be imported. Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved.

Starting with this release the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import.

Deduplication algorithm is as follows:

  • ASA/PIX/FWSM configuration import:

    ASA configuration language supports named objects and object groups. On import, fwbuilder creates objects and groups with the same names and uses them in rules. Objects created from in-line address/netmask and port specifications found inside object-group, access-list, filter or nat commands are condidered "anonymous" objects. These get automatically generated names and are deduplicated using only their relevant attributes but not names. Objects created from PIX named object ("object network foo", "object service bar") statements are considered "named" objects. They get the name matching the name in corresponding PIX config line and are deduplicated using both relevant attributes and the name.

  • iptables:

    Fwbuilder can only import iptables configuration saved with "iptables-save" command. This format does not support variables or named objects, therefor all objects created from address and port specifications are "anonymous" and get automatically generated names. They are deduplicated using their address, netmask, port numbers and other relevant attributes but not their names.

TCP and UDP service objects in fwbuilder that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

GUI Updates

  • fixed #1872: "vlan interface does not appear in the list of interfaces for route-to action for PF".

  • context menu item that opens object in the editor should be named "Inspect" when the object is read-only because the editor would not allow the user to change it.

  • fixed #1926 "Crash when moving object in Standard library". Context menu item "Move" should be disabled when the object is located in the read-only library.

  • see #1976 "Crash when deleting firewall object from rule after export / import library" Crash occurred as the result of the following sequence of actions in the GUI: 1) use context menu item "Cut" to delete an object in the tree, 2) open object group or rule and use context menu item "Paste" to add it, 3) export library to an external file, 4) import this library into different data file, 5) save the data file. Saved data file is invalid XML since it has unsatisfied reference and some operations on it cause crash. The problem is that since it is a reference to the object that is being added in case of both groups and rules, we end up with a group or rule with a reference to an object that is located in Deleted Objects library. Deleted Objects library is not included when a library file is merged into data file and this leads to a dangling reference. The fix is to not allow Paste if object in the clipboard has been deleted.

  • see #1980 "Objects from Deleted Objects should not be allowed to be used in rules". Added checks to not allow drag-and-drop of an object from Deleted Objects library into rules and groups.

  • see #1994 "Crash when compiling a firewall in an imported Library". To prevent crash, added check to make sure firewall object is not read-only before an attempt to update its "last compiled" or "last installed" timestamp.

  • fixes #1993 "V4.2 on Windows - export Library shows the file type as Firewall Builder 2"

  • fixes #1992 " V4.2 on Windows - installer error can't find Secure Shell utility"

  • fixed #1989 "variables respath and librespath are redundant and copy Constants::getTemplateDirectory()". Got rid of global variables sysfname, tempfname, librespath, respath and localepath; will now use class Constants to keep this information.

  • fixes #1998 "Crash after running find-and-replace then closing file". Specific sequence of actions and only on Mac OSX caused GUI to crash. To fix, I clear editor panel when user closes project window using MDI window title menu item "Close" or "Close" button.

  • see #1996 "Crash when finding and replacing a large number of objects". When "find and replace" function was used to replace large number of objects in a rule set, it generated stream of calls to updateLastModifiedTimestampForAllFirewalls() which caused corresponding stream of events to update various parts of the GUI, both in the tree and rule set views. This caused weird corruption and crash on Windows. Trying to resolve the issue by optimizing the part that updated "last modified" timestamp on the firewall since all parts of the rule set updated in one call to "find and replace" function belong to the same firewall.

  • fixes #2000 "New dialog window in New Firewall wizard for ASA / PIX - Network Zone explanation". Added page to the new firewall wizard to let the user configure network zones of interfaces when chosen firewall platform supports network zones (only PIX/ASA right now).

  • fixes #1983 "ASA multiple interfaces have the same security level". Using table widget with spin-boxes to let the user edit security levels of interfaces conveniently.

  • see #2006 "Crash when closing editor panel with find-and-replace". The GUI crashed if user tried to close editor panel at the bottom after closing objects+rules panel and while some object was still displayed in the editor.

  • See #2015 "Add support for setting names of generated .fw and .conf files separately for PF". Added second input field in the "advanced settings" dialog, tab "Compiler" for the firewall platform "PF". Now user can set the name for both the generated .fw initialization script and .conf PF configuration file, as well as names for both files on the firewall. Support for this is generic and the same functions work for other platforms if corresponding input field in the dialog exists. The name of the initialization script is set as follows: 1) if user provided -o command line switch to the compiler, its argument is used. 2) if -o switch was not present but the name was configured in the firewall settings dialog, it is used. 3) if none of them were present, the name is constructed from the name of the firewall object with suffix .fw. The name of the .conf PF configuration file is taken from the settings dialog, but if it is blank, then it is constructed from the name of the initialization script but with suffix .conf.

  • fixes #1914 "Address table object file name is not created properly if user clicks outside Editor panel"

  • fixes #1915 "tooltip shown when mouse is over rule number should be added to the list of suppressed tooltips when 'Advanced user mode' is in effect"

  • fixes #2064 "CARP interfaces are not properly installed on FreeBSD cluster". I need to populate failover group objects with some reasonable defaults when they are created.

  • fixes #2067 "Add way to show interface label in object tree". The tree now shows interface name and label if the label is not empty.

  • fixes #1979 "New firewall created with Cisco c36xx template results in network object in interface column in Policy"

  • fixes #1895 "Add context menu option to expand all child nodes in object tree". Added menu item "Expand" to the context menu associated with all objects in the object tree. This item recursively expands all tree nodes under the given object and automatically changes to "Collapse" if the item is expanded. Also changed behavior of the double click on the object in tree: before, double click opened object in the editor and expanded or collapsed subtree. Now it only opens object in the editor but does not expand/collapse subtree.

  • see #2103 "complex vlan/bridge configurations are not supported by the interface validation code". Added checkbox to let the user turn off interface name validation functions in the GUI. Checkbox is located in the global Preferences dialog, tab Objects, subtab Interface. For backwards compatibility, the checkbox is turned on by default. When it is off, the GUI does not validate the name of interfaces and subinterfaces and turns off checks that enforced interface name patterns for VLAN, bridge and bodning interfaces. It also turns off check for the validity of vlan ID derived from vlan interface name and turns off automatic configuration of interface type and vlan ID. These checks sometimes were in the way of building complex configurations that involved multiple vlan interfaces with names not matching their IDs. This also fixes SF bug #3066714 "please dont stop me from creating a new interface" where user wanted to create interface "veth201.0" on Linux but the GUI blocked this operation because the name seemed to match vlan interface pattern.

  • fixes #2099 "Object list scrolls up to the last edited object". Object tree used to scroll spontaneously when user started dragging an object from it to a rule.

  • fixes #1971 "Address range can be created with end address lower than start address". Address Range object dialog should not let the user enter range end address which is lower than range start address. Dialog behavior is now similar to the behavior of the tcp and udp service dialog where user can not enter port range end number lower than port range start number.

  • fixes #1678 "When creating a firewall from template it appears that a default template is selected". When user arrives at the page where they choose template to create new firewall object from, the first template should be automatically selected.

  • fixes #2135 "Editing table objects". Dialog of the AddressTable object now offers button "Edit" that lets the user edit address table file. This only works if the file is located on the same machine where the GUI is running, so it is probably most useful for compile time objects.

  • fixes #2139 "Provide "Cancel" button if Address Table file is read-only". If the file configured with Address Table object is read-only, the GUI shows warning when user clicks "Edit" button and offers a choice: open it for viewing read-only or cancel.

  • see #2140 "Attempting to create new Address Table file results in read-only error". Implemented support for the workflow when user wants to create the file used to feed addresses to the Address Table object.

  • see #2047 "Inspect generated files button shows different path information". Do not pass full path to the output file as an argument of the "-o" option when the GUI launches policy compiler. Since the "-d" option passes directory path where files sould be saved, actual file names do not need to be absolute path, except if the user entered absolute path for the output file name in the firewall settings dialog.

  • see #2153 "Add Network Zone explanation and selection dialog to ASA/PIX import". Wizard shows additional page when user imports PIX/ASA config. This page explains concept of network zones and offers UI to let them choose network objects or groups as a network zone of each interface.

  • fixes #2156 "After import the firewall should be opened in object tree".

  • see #2163 code that imports addresses from a file in /etc/hosts format moved to its own wizard; using QWizard and QWizardPage classes with correct implementation of page sequencing and validation; old discovery druid has been disabled. SNMP discovery and ios/PIX/iptables configuration import will move to their own wizards later.

  • fixes #2203 "Crash when attempting to add an object to a locked group".

  • fixes #2201 "Some fields of locked object are editable". Some input fields of the Custom Service object dialog were editable even when object was locked read-only.

  • fixed SF bug 3238026: build failure on systems without net-snmp development libraries.

  • see #2226 fixed GUI crash that happened when user tried to delete or cut an object from locked library.

  • fixes #2307 "GUI switches to another file after editor panel is closed"

  • see #2286 "Crash when closing file". The GUI crashed if user imported iptables or PIX configuration, then deleted a rule and tried to close project window.

  • see #2171 "Undoing delete of rule ends up with rules being created with duplicate rule numbers". Also see #2172 "Crash when deleting rule - related to #2171". When user deleted the last rule in a rule set, then used Undo to restore it, the program lost track of rules in the rule set and became unstable.

  • see #2335 "GUI switches between data files upon closing editor panel". If user opened two data files in the GUI and was in the process of editing objects in one of them, the GUI would flip to the other file under certin circumstances.

  • see SF bug 3211769 "Member interfaces not sorted". Sorting interfaces by name in the dialog where user adds them to the cluster member group.

  • fixed #2287 "Show text description in rule columns" does not persist across sessions

  • see #2229 "Multiple new objects with the same name". The GUI should automatically choose unique object names for new objects.

Changes in command line tool fwbedit

  • see #2328 "Add ability to run firewall import from the command line". This has been implemented as a new function "import" in fwbedit. See man page fwbedit(1) and "fwbedit -h" for more details.

  • Starting with v4.2.0, fwbedit.exe is now part of the Windows package

Changes in policy importer for all supported platforms

Changes that affect import for all platforms

  • see #1931 "Update failed import behavior". Added meaningful error messages for when policy importer fails to create firewall object or does not create interface objects or any rules.

  • see #2161 "import workflow and automatic detection of firewall platform from the config file". When user imports existing firewall configuration, the GUI automatically detects firewall platform from the format of the config file and shows platform-specific warning to explain what parts of the config can and can not be imported. It also detects firewall host name where possible (currently Cisco IOS and ASA/PIX). Importer wizard has been reimplemented using QWizard and QWizardPage classes and its workflow significantly improved.

  • see #2162 menu item "File / Import Policy" renamed to "File / Import Firewall". This menu item launches wizard that imports existing iptables, Cisco router IOS or Cisco PIX/ASA config.

  • see #2183 "count errors and warnings generated by the importer and show the numbers in the progress page of the wizard". Configuration import wizard now shows counters of warnings and errors generated by the importer.

  • see #2189 Policy importer warnings and errors now include line numbers to help find relevant lines in the original configuration file.

  • see #2189 Program adds the file name and the line number to comments of policy and nat rules it creates during import.

  • fixed #1548 "Object de-duplication during import process". Also SourceForge 3030072 "remove duplicates during any import". Now the program can optionally re-use existing objects from both Standard Objects and user-defined libraries when it imports existing firewall configuration. This works for any firewall platform for which we support policy import. Objects are matched by attributes such as address, netmask, port etc. Object name and comment are not taken into account. Importing the same configuration file twice creates two firewall objects with the same interfaces and rules but re-uses address and service objects created on the first import.

  • see #2253 "importer should not creates objects while still in the middle of the wizard". Importer wizard creates new objects in the object tree only when user clicks Finish and abandons results if they click Cancel.

Fixes and improvements in import of iptables configurations

  • see #2190 "support for import of branches in NAT rules for iptables". Implemented import of NAT rules in user-defined chains for iptables, these translate into branching NAT rules in fwbuilder.

  • see #2196 "iptables nat rules with target REDIRECT not imported". Iptables NAT rules with target REDIRECT where not imported correctly.

  • fixes #2195 "incorrect iptables import of nat rule with NETMAP target"

  • see #2194 "iptables import problem with SNAT rule translating to an address range". NAT rules translating into address range with "-j SNAT --to-source 192.168.1.1-192.168.1.10" did not import correctly

  • see #2197 "iptables nat rules in chain OUTPUT not imported correctly"

  • see #2202 importer for iptables creates Custom Service object to match combination of states it does not recognize. This includes "NEW,ESTABLISHED".

  • see #2336 Importer for iptables recognizes version stored in the top comment by iptables-save and sets version in the firewall object it creates.

  • see #2206 iptables commands with no "-j TARGET" parameter should be imported using action "Continue".

  • see #2338 "Empty Mangle Policy object created on import". iptables rules in the table 'mangle' will be imported in the dedicated Policy rule set with name "Mangle". Rules that use chains FORWARD and POSTROUTING in table 'mangle' can not be reproduced and will be marked as "bad" (color red and corresponding comment).

  • see #2275 Importer for iptables now correctly handles both "intrapositioned" ("-s ! address") and "extrapositioned" ("! -s address") negation.

  • see #2245 fixed bug in parser for iptables that prevented correct import of iptables rules using module "multiport" with port range matches.

Fixes and improvements in import of Cisco IOS configurations

  • see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group.

Fixes and improvements in import of Cisco ASA/FWSM configurations

  • see #2161 policy import wizard shows the page where user can set up network zones of interfaces if firewall platform was determined to be PIX.

  • see #2152 "ASA Import - shutdown interfaces". Importer recognizes and skips ASA interfaces in "shutdown" mode.

  • see #2248 implemented import of Cisco IOS and PIX/ASA service configurations using port operation "neq". Since object model in fwbuilder does not provide direct support for "port not equal to" expression, this configuration is conveted into two tcp or udp service objects with port range extending below and above specified port and these two service objects are then placed in a group.

  • see #2268 updated list of named TCP and UDP ports recognized by the importer for Cisco ASA.

  • see #2277 "Create policy objects for ASA access-lists that are not applied in an access-group". Policy rule set will be created and populated with rules found in the corresponding access-list even if this access-list is not applied to an interface with access-group command.

  • see #2164 fixed import of "ssh" commands and added import of "http" commands for ASA/PIX/FWSM

Changes in the built-in policy installer

  • see #2039 "Installer reports success even if pfctl can't load config file". Added more pfctl error messages to the list to make code more robust.

  • fixes #2049 "Installer reports success even if there was an error while creating static routes". Added our own error message generated when command used to add static route fails to the list of error messages recognized by the installer.

  • fixes #2037 "If there is an error when compiling firewall then installer should be aborted". Compile/install wizard should disable "Next" button after compile phase is done if all firewalls failed to compile with no errors.

  • fixes #2061 "Installer shows success for failed installed on FreeBSD due to corrupt script file". Added bunch of common shell error messages to make sure installer recognizes them and mark install as a failure even if ssh fails to pass termination code.

  • fixed SF bug 3169045: "Batch installer lists IPv4 address as management address". The "summary" display in the installer progress log output will now show putty session name if it is used instead of the management address.

  • see #2073 "Add additional information or workflow when no management inferface configured". The error message shown to the user when no interfaces has been marked as "management" is now more verbose and provides instructions how to do this. Also, if user provided alternative address to be used to communicate with the firewall, the check for the management interface is not performed since it is not needed.

  • see #2088 "Installer caches putty session". Need to initialize putty_session properly and clear it in clear().

  • fixes #2129 'deprecate "test install" function'. We have decided to deprecate test install because it is rather heavy-handed on Linux and PIX where it reboots the firewall and plain does not work on *BSD.

  • see #2239 Added variable "firewall_name" to configlets that define commands installer runs on the firewall to activate new policy (all platforms).

  • updated filesystem path on FWSM where fwbuilder built-in installer should place generated configuration when it is installed using scp. Currently using path "disk:".

  • see SF bug 3212988 "external script makes getopt difficult". User-defined parameters for the external script moved to the end of the command line.

Changes and improvements in the API library libfwbuilder

  • see #1972 Separated object creation and initialization. Some complex objects need to create a set of standard child objects. Previously this was done in a special type of constructor which required pointer to the object tree root (FWObjectDatabase*). This created problems with implementation of the method to register functions that create objects of new types outside of the API. Now all objects have just a basic set of constructors, plus method init() that can initialize them.

  • see #1972 implemented mechanism that allows me to register new object types created and used outside of libfwbuilder API. This means FWObjectDatabase can then copy and manipulate object trees that use these new object types.

  • fixes #1937 "RES_DIR macro is defined twice". Got rid of duplicate definition of this macro.

  • see #1985 added virtual function updateNonStandardObjectReferences() that is supposed to update any references to objects stored as attributes.

  • fixes #1997 "add removeRef and addRef methods to class NATRule". Now undo and redo correctly remove and restore references to NAT rule sets in NAT rules with action Branch.

  • fixes #1991 "Undo does not restore object as a parameter of policy rule action Branch or Tag after it was deleted deleted". Now Undo restores references to rule sets and tag services as arguments of corresponding policy rules, as well as references to objects configured as interface network zones.

  • fixes #1987 "Deleting object that is used as Network Zone for ASA/PIX interface results in inconsistent behavior". When an object that is used as a network zone of an interface is deleted, it should be removed from the interface configuration as well.

  • fixes #1995 "Crash when compiling a cluster with identical firewalls". Method Cluster::init() must call base class method Firewall::init() to get child Policy, NAT and Routing objects created.

  • See #2084 "snmp discovery takes forever on devices with large routing tables". This takes very long time on decides with large routing tables. This code was implemented long time ago and apparently routing data was intended to be used to discover "external" interfaces, but it is unclear if this is still done. The concept of external/internal currently exists only for platforms that support security levels (PIX) and there we guess levels by matching addresses against RFC1918 and let the user user adjust levels manually anyway.

  • see #133 Added interfaces to the NAT rule model. There will be two interfaces per NAT rule: "inbound interface" and "outbound interface". DTD version changes to "18", old data files need to be upgraded.

  • see #2126 Using snmp sysDescr OID to guess version of the new firewall when it is created using snmp polling.

  • fixes #2209 "do not allow the same object to be child of different objects in the tree". Method FWObject::add() enforces this. Subsequent clean-up and fixes in many places to follow this logic. This makes code much cleaner, better organized and more reliable.

Changes and improvements in the library of standard objects

  • #2083 Added new services to the Standard Objects Library: rtmp, xmpp-client, xmpp-server, nrpe

common changes that affect policy compilers for all platforms

  • fixes #1920 "Setting host interface to unnumbered after it has been assigned IP address doesn't have desired effect". Compiler still used IP addresses that belonged to the interface even if it switchd to "unnumbered". These children address objects should be ignored.

  • fixes #2124 "some error messages get multiplied when compiler splits rules". Under certain circumstances error messages could appear multiple times in the generated script.

  • see #2204 "Shadowing detected for rule with action Continue". Policy rules with action "Continue" should not shadow other rules and can not be shadowed.

  • see #2207 fixed memory leak in policy compilers. The impact of this leak was especially severe on Windows with very large object databases.

  • see #2212 "Performance improvement in compilers". This change brings significant improvement in compile time on large object trees. The speed-up is especially noticeable in single rule compile where the time before generated firewall configuration appears in the GUI shrank by up to a factor of 10.

  • sorting objects in rule element after cluster interfaces have been replaced, this helps ensure stable ordering of objects in generated configuration.

  • sorting objects in the rule element by name after group is expanded, this helps ensure stable ordering of objects in generated configuration.

Changes in support for iptables

  • fixed #1879 "gui crash". Both GUI and fwb_ipt crashed trying to compile a rule with action Branch that was not configured to point to any rule set.

  • fixed SF bug #3102044 "Colon in (runtime) Address Table name". Variable used to process addresses in the run-time address table should not use character ":" even if it appears in the Address Table object name.

  • fixes #1999 "log() does not work" Using built-in utitlity "command" to verify that all the tools generated script needs to function properly are available and can be accessed either via direct full path or are in the PATH variable. This includes the check for the logger tool that is used to make log record when firewall is activated.

  • see #2097 #133 "support for inbound and outbound interface columns in iptables NAT rules". This also addresses SF feature requests 1954286 "DNAT with interface as condition not possible" and 621023 "manipulating interface in NAT rule".

  • fixes #2008 "option "--physdev-out" is not allowed in OUTPUT chain". After this change, compiler avoids INPUT/OUTPUT chain if interface in the rule column "Interface" is a bridge port and firewall is bridging firewall (which means we are going to use --physdev-in or --physdev-out option for this rule).

  • see #2170 "Compiler should generate error for invalid iptables NAT configs". Now that we allow the user to specify inbound and outbound interfaces in iptables NAT rules, compiler should verify that combination of requested "-i" and "-o" interfaces is in fact valid. For example iptables does not allow "-o" interface spec with rules that go into PREROUTING chain (DNAT rules) or "-i" interface spec with rules in POSTROUTING chain (SNAT rules).

  • see #2181 "Update iptables importer to detect inbound & outbound interfaces in NAT rules". Importer can now import nat rules with "-i" or "-o" interface spec.

  • see #2230 the GUI should allow limit-burst values of up to 10000

  • SF bug 3178186 "Add ND/NS allow rules for the FORWARD chain". Rules that are added automatically to IPv6 Linux firewall to permit neighbor discovery packets should be also added to the FORWARD chain if the firewall is a bridge.

  • see #2324 "NAT + MAC-matching rules not generated properly". iptables NAT rules matching a group of host objects with both IP and MAC addresses each in "Original Source" were not generated properly.

  • see #2235 "Modified rule action for Continue". Rules with action "Continue" should translate into iptables commands without "-j TARGET" parameter. If such rule also has logging enabled, it should use target "-j LOG" instead of generating additional chain.

  • see #2359 "Crash when compiling single rule with IPv6 destination and IPv4 gateway or interface". Routing compiler for iptables does not support ipv6 at this time and will issue a warning when user tries to place ipv6 address or network in a routing rule. The warning does not appear when ipv6 address is a member of a group used in the rule. Also see #1575.

Changes in support for PF (FreeBSD, OpenBSD)

  • see #1890 "Add support for configuring static routes on BSD". Implemented support for simple static routing rules. ECMP and routing via interface (routing to directly reachable subnets) are not supported. Generated script preserves static routing entries that existed before and attempts to recover in case of error.

  • see #1888 "Add option to generate rc.conf.local file for BSD systems". Added ability to generate initialization script in rc.conf fromat for FreeBSD. Only FreeBSD is currently supported (not OpenBSD). Generated script includes variables to configure interfaces and their IPv4 and IPv6 addresses, vlans, CARP and pfsync interfaces, as well as variables that initialize PF.

  • fixes #2026 Compiler can now generate static routing configuration in rc.conf format for FreeBSD.

  • fixes #2032 "support for DHCP interfaces in rc.conf mode". Include dynamic interfaces inin the list of interfaces generated script manages when the script is in rc.conf format. This addds lines similar to 'ifconfig_em0="DHCP"'.

  • fixes #2038 "pfctl error when firewall settings include scrub option for reassembly". Command "scrub all reassemble tcp" does not allow direction. Tested and verified on OpenBSD 4.2 and FreeBSD 8.1

  • see #1889, #2043 Added support for bridge interface configuration in BSD.

  • fixes #2054 "Add support for load anchor PF command". Instead of loading anchors using "pfctl -a anchor -f file" command in the .fw initialization script, now generated PF configuration uses "load anchor" commands in the pf.conf file. This way, we can load anchors correctly when PF configuration is activated from the generated rc.conf.local file where only one pf.conf file can be referenced.

  • fixes #2042 "add configlet and shell functions to manage bridge interfaces via shell script on OpenBSD and FreeBSD". Bridge interfaces are managed incrementally, that is, the script creates and destroys them as needed, then adds or removes bridge ports, to bring bridge configuration in sync with what is defined in fwbuilder GUI.

  • fixes #2065 "activation commands on FreeBSD and OpenBSD lose script exit status". Sequence of commands ran by the built-in installer on *BSD firewalls were losing exit status of the script which meant installer always declared installation a "success" even when there were errors.

  • fixes #2066 "Existing VLAN interfaces are not properly removed from FreeBSD and install script fails"

  • fixes #2069 "PF: allow multiple objects in ODst of redirecting nat rule". This fixes SF bug 3162862 "NAT - more than one object in original destination"

  • fixes #2071 "vlandev missing in the vlan definition (when using rc.conf.local )"

  • fixes #2058 "Ability to configure mtu and metric of regular interfaces". "Advanced settings" dialog of the interface object provides controls to configure MTU and possibly add any additional ifconfig parameters. This is available for OpenBSD and FreeBSD.

  • see #2078 added verbose error message in a situation when "ifconfig carp0 create" command fails to create CARP interface.

  • see #1867 "PF: rule with non-terminating action Tag shadows other rules below it". Since action Tag is non-terminating, rules with this action should not shadow other rules.

  • see #2074 On FreeBSD ifconfig does not understand parameter carpdev

  • fixes #1866 "support for pf option set state-policy", #1868 "support for pf option set block-policy", #1869 "support for pf option set debug".

  • fixes #2092 option "stp" should be optional in the ifconfig command that builds bridge interface for FreeBSD. The dialog provides checkbox "Enable STP", parameter "stp" will be added to the ifconfig command only when the checkbox is turned on.

  • fixes #2091 "ethernet interface options a used twice if the interface is a bridge port". When an interface appeared twice in the firewall configuration, such as when it is used as a bridge port and vlan parent interface, options configured for it in its settings dialog were added twice to the generated configuration.

  • see #1871 "PF Actions Tag and Classify can be terminating or non-terminating". Added checkbox to the action properties dialog for actions Tag and Classify for PF that lets the user choose if these actions should be terminating or not. Old behavior (Tag was non-terminating and Classify was terminating) is reflected in default settings of the checkboxes. Terminating rules generate "pass quick" commands, while non-terminating rules generate "pass" commands (no "quick" option).

  • see #1807, #2104: arrange interface configuration commands in the generated script in such order that bridge and carp interfaces are configured after all other interfaces are done.

  • see #2105: generated script now supports vlan interfaces with names that do not match vlan IDs (OpenBSD, FreeBSD, shell script format).

  • Making sure we print "ifconfig" commands for mtu and other parameters for all interfaces, including those with no ip addresses and bridge ports (unnumbered interfaces used to be skipped before)

  • fixes #2100 carp password should be optional parameter

  • fixes #2096 added support for negation in Interface column for PF NAT rules. Sets of interfaces are converted to complementary sets using complete list of interfaces of the firewall.

  • fixes #2095 added support for groups and multiple objects in column "Interface" for PF NAT rules. These translate into { em0 em1 em2 } groups in generated pf.conf lines.

  • fixes #2101 "CARP interfaces are set with same advskew". When new PF cluster is created, master advskew paramerer will be set to 10 and backup to 20 to make it deterministic.

  • fixes #2116 "When CARP interface IP address can't be assigned error or warning should appear". The problem actually affects any type of interface. Generated script should abort with an error termination code when ifconfig fails to assign IP address to an interface.

  • fixes #2117 "CARP interfaces in cluster that use VLAN interaces have no interface set to MASTER". When PF cluster configuration was built using vlan interfaces of member firewalls, CARP interfaces were not properly configured with master/slave choice user makes on the first page of the new cluster wizard.

  • see #2143 "installer should run /etc/rc.d/pf script to reload PF rules on FreeBSD when generated script is in rc.conf format"

  • see #2224 "FreeBSD - Bridge interfaces with the name vlan don't show as Bridge Port Interfaces". This actually applies to all OS where we support vlan and bridge interfaces. Fwbuilder GUI should allow the user to set subinterface type to both "ethernet" and "vlan" when its parent interface has type "bridge". Setting subinterface type to "ethernet" makes it bridge port, while setting the type to "vlan" signals policy compiler that it should generate code to configure real vlan interface. If the name of the subinterface does not include the name of the parent, such as "vlan101", or when the name does not match vlan ID, such as "vlan8101", global preferences option "Verify interface names and autoconfigure their parameters..." should turned off. The option is located in the Preferences dialog, tab "Objects".

Changes in support for ipfilter

  • There are no changes in the support for ipfilter in this release

Changes in support for ipfw

  • There are no changes in the support for ipfw in this release

Changes in support for for Cisco IOS ACL

  • fixes #1966 "IOSACL: object-group can get name that consists of only suffix". Compiler generated object-group statements with names such as ".src.net.0" in some cases.

  • see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

  • see #2330 "Crash when creating a cluster of IOS router firewalls". Added support for basic IOS router clusters. No failover protocol support at this time, but the cluster can be configured with protocol "None" and fwbuilder will do address substitutions at compile time.

Changes in support for for Cisco ASA and FWSM

  • FWSM v4.x does not have "fixup" command, instead, we should use policy-map and class commands.

  • refs #1893 fixes #1883 "inspect IP options in PIX8". Added support for "policy-map type inspect ip-options" command in PIX v8.2 and later. At this time, of all possible types of "policy-map type inspect" command only "ip-options" is implemented.

  • refs #1882 "Mixed service groups in PIX8". Added PIX versions 8.0 and 8.3; added support for mixed servcie groups in PIX 8.0 and later.

  • fixed #1892 "move rule processor class separateServiceObject to PolicyCompiler". This rule processor used to be implemented only in the compiler for PF, but since it has very general meaning, the same function was duplicated in other compilers as well. Moved the class to libfwbuilder and reimplemented several other rule processors to inherit from this class to avoid further duplication for code.

  • fixed #1891 "problems with TCP and UDP services with source ports". Policy compiler for PIX did not generate correct PIX ACL lines when one Policy rule tried to match several TCP and/or UDP objects matching source ports.

  • fixes #1901 "add destructor to NATCompiler_pix and NATCompiler_asa8". This eliminates memory leak.

  • refs #1885 "named network and service objects in PIX8". So far, these objects are only used for nat configuration.

  • fixes #1903 "correct order of clear commands for ASA 8.3"

  • refs #1886 "new nat configuration in PIX 8.3". Initial support for new style nat configuation.

  • fixed #1862 "fwb_pix crash". Compiler fwb_pix crashed when DNS Name run-time object was used in a rule, but worked fine and issued an error when used in single-rule compile mode.

  • fixed #1906 "ASA NAT - Address objects are not properly identified by network zone and have the wrong real interface". The problem should have affected both "old" (PIX 6 and 7) and "new" (ASA 8.3) configuration. When an Address object was used in Original Source of a NAT rule, compiler used wrong interface in the (interface1,interface2) pair in "nat" command.

  • fixed #1905 "fwbuilder crash when compiling a rule with hosts folder as destination". Compiler issues a warning when an empty group object is used in a rule, but GUI crashed when user tried to compile this rule using single-rule compile function. The change actually affects all policy compilers and makes sure the GUI catches exception and does not crash, and prints any errors generated by the compiler in the compiler output panel when single-rule compile function is used.

  • refs #1908 "ASA NAT - cannot configure static NAT translations with (inside,outside)". Added NAT rule option to make source nat rules "static". The option is presented to the user as three radio buttons in the NAT rule options dialog which is only enabled when platform is "PIX" and version >= 8.3. Policy compiler generates "twice nat" rules with keyword "static" in the following cases: when TSrc is "original", so the rule translates destination and not source or when numbers of ip addresses represented by OSrc and TSrc are equal. If TSrc is not "original" and represents different number of IP addresses than OSrc, compiler looks at the new rule option. User can use or override automatic algorithm using radio buttons in the NAT rule options dialog.

  • refs #1902 "Add NAT rule option "translate dns" for PIX". The option is only available for ASA 8.3 or later.

  • fixed #1909 "ASA NAT - static nat port translation where service is the same for original service and translated service not generated correctly"

  • fixed #1913 "ASA/PIX rules with logging enabled don't have log set unless user modifies Firewall Settings". Added default log level setting to the resource xml file for platform "PIX", set to "informational". ACL lines now get "log " keyword followed by the log level taken from the rule options, or if that was not configured, from the firewall object settings, or if that is not configured, the default.

  • refs #1907 "ASA NAT - fwbuilder doesn't support multiple translated sources in a single NAT rule". Compiler uses object-group to translate NAT rules that have multiple objects in Translated Source.

  • refs #1885 Compiler uses named objects and objects groups to build configurations that use address ranges in TSrc in NAT rules. (only ASA 8.3 and later)

  • fixed #1917 "Duplicate objects are not detected". Compiler should detect duplicate objects that may be created in a rule element when user combines Address Table object with other address or network objects there.

  • fixes #1934 "libfwbuilder::getOverlap() incorrectly calculates overlap between IPv4 networks". This should also fix SF bug 3156376 "Can not find interface with network zone that includes address range".

  • fixes #1932 "Add description field to generated NAT rules for ASA". NAT rules generated for ASA 8.3 and later will have "description" keyword added, with rule label as an argument. Rule label includes word "NAT" and rule number.

  • Added support for CustomService objects in policy and nat rules for ASA 8.3 using named objects and object-groups. -- see #1942 "ASA NAT - if custom service is included in service group incorrect config generated" -- see #1929 "move map named_objects inside class NamedObjectManager" -- see #1946 "restrict generation of the named objects by PolicyCompiler_pix to ASA 8" -- see #1885 "named network and service objects in PIX8" Note: this has been rolled back. There is no support for CustomService objects in NAT rules.

  • see #1941 "ASA NAT - compiler complains about range in original destination". NAT rules translating destination allow Address Range objects in ODst or TDst for ASA 8.3

  • see #1940 "ASA NAT - fwbuilder host objects interface IP is reserved keyword". Added list of reserved words used in IOS and ASA software to make sure generated named objects do not conflict. Will maintain single super-set of reserved words instead of separate set for each version of IOS and ASA.

  • fixed #1938 "icmp" commands were not generated for ASA 8.x policy rules.

  • See #1927. Added check for NAT rules that request translation of destination address but have ODst "any". This only applies to ASA 8.3; these rules are prohibited.

  • fixes #1916 "nat rule must be "static" when subnet is present in TSrc"

  • see #1942 improved support for CustomService objects for ASA 8.3. Generate separate named object and object-group for these objects, then split policy and nat rules so that only one custom service object is left in each rule and then use object-group to match it. Note: this has been rolled back. There is no support for CustomService objects in NAT rules.

  • fixes #1948 "incorrect configuration created when a CustomService object is used in a policy rule for PIX/ASA versions prior to 8.3". Since we do not support custom service objects in policy and nat rules for versions older than 8.3, added check to generate fatal error when such object is used.

  • fixes #1945 "object-group names include ever-growing suffix". Object-groups created by the compiler for PIX/ASA had numerical suffix that was constantly increasing when user used single-rule compile function in the GUI.

  • fixed #1944 "ASA Policy - duplicate network object groups created for mixed service group with TCP dst and TCP src port range objects". Need to convert address range objects to subnets early, before the rule is split for any reason, to make sure object groups created later match and are reused.

  • See #1943 "ASA Policy - mixed service group with TCP destination port range and standard TCP object generates invalid config". Protocol word "tcp" was missing after "deny" in the generated rule.

  • see #1949 "ASA NAT - split objects if OSrc contains objects that are in more than one network zone".

  • ASA 8.3 see #1942, #1943 fixed generation of the "object-group" statements by adding protocol keyword at the end so that the group can be used in access-list commands. It looks like mixed service groups that have no protocol keyword at the end of the line that defines them cause error "specified object group has wrong type; expecting service type". I am going to avoid using mixed service groups because of this.

  • see #1953 "ASA NAT - two host objects in the same rule result in incorrect config". Objects that represent addresses of interfaces of a host object created using template will be automatically renamed to follow standard naming convention "host_name:interface_name:ip" to avoid creating duplicate names.

  • see #1960 add support for CustomService for PIX policy rules. Note that CustomService objects are only supported in Policy rules since nat commands in ASA 8.3 require use of named objects and it is difficult to implement correct named objects and object-groups with protocol parameter and custom services.

  • See #1959 "ASA Policy - ranges are broken into composite network instead of using range command." Added support for address ranges using named network object with parameter "range" for ASA 8.3 and later. NOTE: if a network or IP address object is used in a nat rule for ASA 8.3, a named object has to be created for it since ASA 8.3 does not accept IP addresses or subnets in "nat" commands. In the situation like this, if the same address or network object is used in any Policy rule, the same named object will be used in the generated access-lists command.

  • see #1959 Moved generation of the code that defines named objects to class NamedObjectManager. This allows me to put all named object commands on top of the generated policy, nat and routing configurations and make sure each object is defined only once. Still need to do #1963 - move code that generates commands to define object-groups to class NamedObjectManager.

  • see #1954 "ASA NAT - generate warning if nat rule is split and one of the resulting nat rules have the same real interface and mapped interface". Compiler issues warning when objects used in OSrc and TSrc of a NAT rule make it use the same interface as both real and mapped interface in the generated nat command. This check is only done for ASA 8.3 NAT rules.

  • see #1963 "move printing of object-group definitions to NamedObjectManager::getNamedObjectsDefinitions()". Consolidated code that works with named objects and object groups in the class NamedObjectManager. This class manages all the objects and in the end generates commands.

  • Refactored parts that generate "clear" commands to make sure they are printed in the right order at the top of the generated configuration. Previously compiler placed "clear global", "clear static" and "clear nat" commands above the NAT section but below policy section. Since ASA8.3 nat commands can use named objects and object groups, and since I have added support for object groups in ASA 8.3 policy rules, I now need to clear objects and object groups at the very beginning of the generated config. However in order to be able to clear objects and object-groups, I need to clear access-lists and nat commands that might be using them first. So, all clear commands are now grouped at the beginning of the generated configuration. This affects PIX/ASA, iosacl and procurve_acl platforms.

  • See #1965 "ASA Policy - PIX 6.1 configurations use object groups". Policy compiler for PIX is now aware that object-group statement was introduced in PIX v6.2 and avoids using object-groups when firewall object version is set to 6.1

  • made names automatically assigned to object-groups in generated PIX configuration shorter by removing interface label prefix.

  • see #1968, #1972 Class NamedObjectsManager maintains its own copy of object tree that holds object group objects it creates during compiler passes. This allows me to maitain one common set of object groups for both policy and nat compilers and avoid creating duplicate and redundant object-group statements.

  • see #1968, #1972 class NamedObjectsManager (and derived classes for IOS and PIX) generate "clear" commands. This way, I can generate correct set of "clear" commands that take into account any named objects and object-groups that could be created during both policy and nat compiler passes.

  • See #1958 "consistently use "exit" to get out of nested context in PIX config". Using "exit" to exit from nested context while adding network or service object in generated PIX/ASA configuraton.

  • see #1970 "ASA Policy - single IPv6 icmp object allowed in rules". Since we do not support IPv6 for PIX/ASA at this time, policy compiler should drop the rule if IPv6 address or icmpv6 service is used and issue a warning.

  • see #1981 "ASA / FWSM Policy - Generate warning message if rule will not generate config data"

  • fixes #1986 "Cisco ASA remarks should be truncated to 100 characters or less". Trimming all lines used for access list remarks to than 100 characters. Remarks can only be less than 101 characters on PIX/ASA and less than 100 characters on IOS.

  • fixes #1994 "Crash when compiling a firewall in an imported Library". Compilers should reset any read-only flags in the copy of object tree they work with before they make any modifications.

  • fixes #2060 "Existing configuration objects are not cleared in PIX 6.3". Commands used to clear object groups and objects have different syntax in PIX 6.3 and PIX 7 and later.

  • see #2098 Added support for user-configurable inbound and outbound interfaces in Cisco PIX/ASA NAT rules. Two new columns appear in the rule set view: "Inbound Interface" and "Outbound Interface". If user leaves one or both columns blank, the GUI shows "Auto" in there and policy compiler picks corresponding interface automatically. Leaving both columns blank ("Auto") triggers backwards-compatible automatic behavior where both interfaces are picked automatically. Multiple interface objects and groups of interfaces are allowed in these columns.

  • fixes #2113 "ASA/PIX SNMP discovery - assign default labels based on interface description". Added pattern to match Cisco ASA interface description which is different from Cisco PIX interface descriptions as returned via snmp.

  • see #1990 "Change default value for Cisco ASA/PIX 7+ to generate outbound ACLs". Newly created PIX/ASA firewall objects will now have "generate outbound acl" option turned on by default.

  • see #2252 TCP and UDP service objects that define port ranges assume port ranges are inclusive, that is, range boundaries are included in the match. This is the behavior of port range matches in iptables and PF, however policy compilers for Cisco IOS ACL and PIX used to convert these objects into ios and PIX access list configurations that excluded port range boundaries from the match. This behavior made TCP and UDP service objects with port ranges incompatible between firewall platforms, that is, the same object could not be used in rules of firewall objects of different platforms because generated configurations would behave differently. This change makes port ranges inclusive in generated IOS and PIX configurations. Users should verify their configurations and adjust port range boundaries in TCP and UDP service objects if necessary.

  • see #2263 looks like "object-group service" that includes named objects defined as "service-object" can not be used in access-list commands and therefore is useless. Unless I misunderstood and there is a way to use it, I should not generate ASA configuration like this:

            object-group service id5102X14531.srv.tcp.0 tcp
              service-object object http.0
              service-object object https.0
        

    Object-group with "tcp" or "udp" type-suffix in the end does not allow "service-object" statements at all, so this configuration is incorrect anyway. However even without "tcp" in the end to make "service-object" references acceptable, the group can be built but can not be used in access-list statements.

    Instead, the group should use port-object statements:

    	object-group service id5102X14531.srv.tcp.0 tcp
    	  port-object eq 80
    	  port-object eq 443
        
  • see SF bug 3213019 "FWSM Network zone and IPv6". Currently we do not support IPv6 with PIX/ASA and FWSM. If user creates a group to be used as network zone object and places IPv6 address in it, this address should be ignored while compiling the policy but this should not be an error.

  • see #2308 "ASA rules with service set to "http" and destination set to ASA firewall object should generate different command syntax". Policy rules that have firewall object in Destination and http object in Service now generate "http" commands. This is similar to how fwbuilder generates "ssh", "telnet" and "icmp" commands to permit corresponding services to the firewall itself.

  • see #2344 "FWSM install errors for clear commands". Using correct syntax for "clear" commands for FWSM v4.x

  • see #2343 "Interface nameif error when installing generated config for FWSM". Use correct "nameif" command sytax in FWSM 2.x and 4.x.

  • see #2345 More fixes for FWSM 4.x: "service resetoutbound", "timeout xlate", "timeout sunrpc"

  • see #2344 fwbuilder should not generate any "ntp" commands for FWSM because NTP can not be configured on FWSM.

  • see #2322 If this is FWSM and if manual commit mode is used, need to commit after clearing ACLs before we clear object groups.

  • see #2347 "FWSM move up the "access-list mode auto-commit" command". Command that configures access list commit mode should be issued before any commands that clear and configure access lists. Also in this change moving commands that set up temporary access list to the top of the script.

  • see #2348: "Accounting action is not valid for FWSM platform". Actions "Accounting" and "Reject" should not appear in the drop-down list of actions in the GUI if platform is PIX or fwsm.

  • see #2295 Added FWSM version "3.2". According to Cisco documentation, FWSM version 3.2 matches PIX 7.

  • see #2351 Security levels of ASA and FWSM interfaces do not have to be unique. Removed check that enforced this.

Changes in support for HP ProCurve

  • There are no changes in the support for HP ProCurve in this release

Changes in packaging

  • This version is the first one to merge libfwbuilder and fwbuilder packages. The libfwbuilder library is now in the src/libfwbuilder subtree inside fwbuilder code tree.

  • RPM .spec files and DEB .control files are now located in the directory "packaging" inside fwbuilder code tree.

  • Changes in the versioning format: build number is going to be used as part of the long version number, composing complete version as "4.2.0.3425". The "-n" suffix in rpm and deb package names will be used for package release number and most of the time will be "-1". This suffix should reflect minor differences in the package that do not affect the code.

  • We have stopped making builds on Ubuntu Hardy. Old Qt (4.4.1) means more and more parts of the code do not compile and require workarounds, sometimes with loss of functionality in the GUI. v4.1.3 will be the last officially released version of fwbuilder to work on Hardy.

fwbuilder-5.1.0.3599/src/res/help/en_US/pix-statesync-group-mapping.png0000644000175000017500000031515411733011756026434 0ustar sylvestresylvestre‰PNG  IHDRDъхQYРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ IDATxь] @Tењџ ћІ €„hрЈ(шsG35{a Y.%jjZ.e.§гzщЫ4{.яii.Мм2q-гž)ІЙсR‚‰ŠŠŠŠ‚‚В 3џям™; :чгсо{ю9п9ї73wОћ­’"pтp8ŽG€#`СXY№ЕѓKчp8ŽG€# Р"ўAрp8ŽGРтр‘Х8ŽG€#Ррpˆ8ŽG€#РАxИ@dёG€#Ррp8\ тŸŽG€#Ррp,.YќG€Ррp8Žˆјg€#Ррp8‹G€ Dџрp8ŽG€#Р"ўрp8ŽGРтZ<ŽG Vреƒj~>9Gр‰F@"‘TлњЙ@TmPrFŽ€Љ”‚иБи&n/У}Syѓ~ŽРг…@YB••ЦРХютyqkюеsШ\фј8ŽG в 8lŸНŠ‹‹>тVlg†§+=РрL3Ф„!іR*•ИџОРЗ{їюшбЃG•црƒ9Ы@рРјэЗп„ћGQQбCЭЃЪˆ*‹яЯр˜…{’_Lb7БТТBA0b [іhŸОbя'yќVю(]ряђ$__;GрБ!ŒжјєгOˆ=T) anб”ЦЖ†~EІ.Œ DІ"Хћq8f# šЬ ЭeтŒm-™|ќ`Щ№kчTіpХ"&:YГ{ 7™UX>”#РЈ9DЛ>3™1!ˆiˆиЬвЂšCœsц<§Аћг43сG*• [&q“йгџоѓ+фџЯшјwМџЭ“јЅŸ>ŒЭѓџ‰=Уёb—-Ш1iяФx:`їv/aїі5бц\-wЊ65>†#Р0 &Б–ЁP$>б•fШкOm8 ЅМ|ЩЮЭЁƒк”jвq‘К ЗхА"эЃ­иг!K—TT\їь\™0 [9:$”9Жl I^џЯаЖА"}uЌYw|ћs ь›РNŽп?›Ž=hŽёE№ДП‰›яђд"Рю%Ѕ…!sДC Ў!zj?&ќТ8u &рˆZ"Жox+kЅЬIВqЇЦeвЕ5щj~|VKO;xи[У…ќ‡2ђ•HЯSТ^*С~ђmJpуt*Ў§žея' к„И‘ДAЈфmЌп“& UпЛ†_ОоŒЃgябБ{?šŒ‘ЃАfOКp>}O,Ђ$“qр239 zћ!ЌŠћ/ђлЗ€џcйА{‰ј€ХЖт=FмV.U-о—#РЈтMЊДpTSЯІѕскЈьќ<ѕыСЭЧЕМЁlЗІjM]ehц!ƒ™ЫšщЌя3Юшуч„ЎшфэЈ-qВ"5LЩ]9ŠГUp&AЭZўHіњЪBœлy ЛцЮРшшНxqhё=y§ўŽЗшщЖ q?Р_7 iŒ пшNbiПљ8LцБХ§–@ѕvќ­ЉLЯГ€ѕхФрˆWlЫHМǘƒ зЖšƒУр˜ŠБ­)7Џ&]№ЧgшNЇŸвšL\ў§ѕ fь§u—Bui)ж@AцГœ" =i^RјиKQOFЁЛdNы\ЯžvRHi?1Л7Ш_ЁXU GpВЌйгњьапdќЁžРпНwО8ƒGn!Ќ™ёт‚#;/УЇХуvёТИ•ѓž'QЩ€ЊЧZgРяržL я'тОЙWТ"s‘уу8“(}ЃbЧЅлЪcfяjПаFH;yCзх™№g sАе›ГгЩЧ%$d$?"g‹$ИЇPу–\‰“фGФФ6к`Я­|4 сˆ H…$8=($s;YIЊџr8š“0ФШЇ™—АНv…Ъ–”ˆи‰а c1э тI ^<!юBwў‡#Р(ёСЪ№žbИ_Ц2›ИЩЌLXx#G€#Pˆ7'q+ђ.},Ж—оњДі†ЬEЃ#qЌяˆ†-”юRщcІ!КM~CЬЉк‡ЂЬк{куE2—E7qE[в й[[с'xлY#ŸТёЯ?(BђlШжVŸ„ЃЪ’:GIк( eЇe;­C–Щ&хћ-‚0ФN&M\GšЉRн(зŠH"Oё˜o9–„@yїБ]мš‚‰ў[eJoо‡#РрT#ІоЌЌ)WP“.‘Мћšt вєWu*?\Лy *I1ŽeЪ!+‘Р‚ŸI‘mvV4s–ЁН˜ЙŒўуZЎY Жћ‰ I?0‹cŸСпŸЙ„Яg$—ш@tlG*ЃлЦ —ХИ8DЬ[ŒWk1aж.ЬšM+4fГЌЫЉИwы.‘Kёр6ўJJЛ‹/еBs0fФ8J!РЂJСХ;s8Е…€ЛŸ;šї ‚Г'…СWНАu“Р…хЪJ:‹лПСНФГHЪК…ъJŠдXs9.$ŒЙ“Я’7х'rГБB~ЁreхmfR„сцТq”ЈI#0yїПNђPО( Аll5 ѕBЦaњдю№V=ƒЁГЂБюл)ˆ{CBЅиїі0ЬŽзцH:А УCV!xоZЌŸ\ ЈpЫE€ D–ћоѓ+чXЋѓ2Љ?яФрд\ Њ9l9gŽGР`ТPькE&]љ№a“Р…"“ т85Ž@Е DІцЉёЋтp8е‚€„%псdw'4ЦэŒЙ‚QэОеŠЕ—ЬbnЦ Uf2~ŠЛƒЮoї€чУЫ1ƒ#ТxКЈђзЂДФŽХ6qЫ 3мК фWУxВ(Kшa•цБя­x^м>йW[Ћзч,:tS g Зwа$н6o1…)јЬўuФASO%xМxЦNшŒŠтзiргq[ён0ˆ(•Sђт(МЗjv$Fsgoѓо >ъ)CРlШPРaћь%>ёˆ[Бafиџ)У_GрЉ@@‚иХˆћЅЗьŒ ІеQ—`o+!aC‚MЉрЂЭ;ФFVMяІТ=ЪR=~ї6D‡HqщРvŒ2hМS_і.a66”л b]XŸўГ0ПЋ'†ЪGŒŸБ0ЬˆDсFx˜Ф^ьXмХ>тжТ№х—ЫЈѓ0G|‰;ЖЖЖ#жЦОПЌЭ№|ПАZ^рˆИg…ь~ƒZ=|ЋeїHs)—:y5€‡ТП„ˆ!kpс*Š%ёцРќ%˜0-N`нџГxЦѓešШrў<€иг!hJuтЈwкўX0y6тЕ™Дg'юDоЬpyРч˜5ЉKбЃqUд\vќ/G .!№№ЗдФе‰ћRЋеjAЪЪЪТџћ_< ,ЏтyУ­‰Ќy7ŽGр1"РFЂP$n]\\0|јpxxxш„#і}gB‘8ц1.ѓЩЪ@$šЬЋC–Аб”uMпT(;ЙCC$|)s[тЋSЛбЦц2О ™€б7"nyї‡№+М›ˆП~ЌТЯ)iфщ шпk>Тfќ[v†Buљ:Є }‘л XГo“@ФtOi?~ƒhїЙ0єžМсЩG вpБ­( ЉT*A(ZНz5>љф“'~Ž€€ћŽO˜06dna#іПћЂЖˆCU6Ћ^"_! Xх5f2cОCŒ4wPЭОЙiрВ‰яb_ќ)œD1‚&-Р жЗ1Ѓc&^о<НIыa>:8=К­У_ КЃi“I$6’/в‰ЕЋсŠqјтѓHPy5РпOш­8ЙгІрїг#ЊРЯCіЂ§њMš>e№уM'J DьbE­г 1aˆН”J%юпg*[ ]їvыб^ич8'NтдoЇ„яtUw/ML0тT1#З<+t`Qfеm2cŒЛѕ}/}8ЕD‹Ію@a2˜)­K3Wa^іGцІЉ§fSЁ–Ь3…pŠtШŸШКi8І; .ю<њИоСз№Чъ~:ў|‡#№4!`–@ФžХ†и ГААPŒ8Lїщ;еŽгўў/Cu7ЮДjЅЊї%Rдkз—.ЎіЙ8CŽ€%#АьгЏˆ=ш(Ќ—БIЭаЏШ’q2чкџМЇFUMfL№ яз ƒ loJЭjвoц$Ф0R+5ТЌВB7n<ePЭ‡JУТрЏ КЭz_FЯХмcз0њKД&й‹GрiD@[[‰+Mf†ц2ёІЩЖ5IEYї`ЃVЁž­щ%•SБФѓч МwЪ‚хцBUXP“KрМ9…{рa{шaћL+,šЬ, 3.–E™m|YE˜ЩьчЫ*ќNaїеFJ ЊучьЈЁ.и2m#R2PgЇbmЬxішƒЦЬЦV.Щ:bю&-Тм% ШЪ•#=) )З4ќ§њєAw\ЦЎј"Di Ў,H~т GР, ‘xCd7G&Б›%ЛiжД@фр`ѕƒ"мЮSЂPEЮ "U<РёAo€œ`эщ…‚kзaыс†.лЖ>сo _>G і`пiІ§e!ЉT*lE_Ђк_]н^.ЪЌ “YJ^U#)МЪМtМИl ю {НV =ъї‰Ѕ[Ѓ„ќDЄ7ЂА{цб$’Єѕl…—УАi}. ]5чg&A э;ЗФkысфт—б3ДЂLG"_Ох<™TJ }‡ ЭeЂЩьqD.”гCцhƒ<Ѕ…ъbг—йAZ‚”ь{X[A•‰J љ§Ќjy72@ќŸ~Е7ZxU Њj™П"&ъB9TRШъжВ*Z2?ї" jˆ˜S5лgB{bBЛp_ЂђпдњKЎ 'Gап„UЕ‘] О(9]6;чФl?„СЄхЁw Юz“šcp4N–DыЦŽ]„=cХCkДќ_ 9н_­э я-9ИА?эПщ+Dš‰#ј–#№Д!`іЯ)Л2ItЌfO’lŸQI1E ‘РТШŠ•ъ"e‰… %В еАЗ–рzžŠ"рОВVХuГТХ ‹њUн=Оs&Фф6I ЊOFЙiиЛaŽю>ŒИ'0љдAФ№'ЖъxЋ9rxи–}Пйїžћюs*V›Œе(3…jЊŽ™ЬYуCdЪŒњиЩр`@’ЫкП‹’ АђUm."Ѓќ€#№є `–@$jŠФЄh6c7MF7NпФБ• АsГCш 6fЁѕЫ+бPЅ]'=i…JдPXл@ž_[Ъ™"“JШ&.…#­>„"7в5А“рТƒbj“  šŒмRYaэЖ­ВYзСЉ/џŠAЯNя7›БxŒљ7yЪq|Аь њз;ЁY—й+т9І!РОуьћЭОль%j‡MmЙНjJаЉ Dэ‚`ЧЅЁ№ЌйљœЧ‡€йъ&Б›ЃЁP$>=ŠЫoвеќ№ЬМ”K№Ја4ОNєШbC+•аœЬmлхљ>Иъ„sVюШ”иAЎ.=АЖr• žŒ|иA%Hq+ kЦLFˆЄ№Ššќ+фЅЧІbЩ€hLЯбёrУcъŸЖ?3zFыјЬпJЁАЉјŠ„Ё‹t>~йGˆъЙ)…ŒЙ)qБЉsфАXЄВа"Хљ_1БѕлXВќWьјшmтїHІsЁQH<ГЃпьЏщШџrjі§.- qэP ƒ^Чи;xњ!€…ѕsт<х˜Ѕ!b‚Ј%bћ†7LЏњѕрцЃЯ‡!Ж›КЕЇ,ЌЭ=…ђ…,‘юЉ[r8’™ŒљЬ4‰zѕBžƒќм_(М“yТQ(/&уJцmx[ТІ~й.‡eЮ„ЉОУ(г+1c*њсфХВЂх qyG т#юkBS•…8gxLєšC|њу‹}3рrЉLГdч†ч&…‹N ( ^щзNt щ;b`є:žŠ%нѓ0aШ"DЂ%H{žBeяSњќˆЫ4AŠhЉX€ˆZTЅ‚KЈ‰G F0|шaТ‘јНЗ52щЮєЋak*uO“6ЉRЮ;sъf DьФbiсˆГ"СХПЃ?л5›ф‡tјf.EEH`GfА|Š*cђE}ым™5W(Q‘ЬQряŒмь8…ТѓбxЎеs&Я›Ву{A ћlЯ ЦНXЮhС*OЎDh$ “€”'ŒЫ@>œбcЬhєађщ3ц%L'ШЗ_$†&396Џ^'œ}eDotmYˆёЫАt]<Ў,{žRŸi)r~‰oГп%‘пrЬC@|рa[Fтїн2иЊ!EC„’UЎ­MОрLэIЮе’"ВЯVbRЗЋLZЪ*њБ@VѕЭkHa])ЊMC”мlТЧј#ыG,YЄж№<пчT'тУŽсїмpП:чzкxЕјњЪzUщ:Щ<џ™Є˜ЏЃЁѕ\žДНZo0іЬMЦtI(Ђ?:,ИѓR‰‰д&њL–оŽœЎJЫуƒ9O*тoЋЩыo„тVht\ QяЖ$№dЊp=Ї2Š;~Л€1” N6ф‘ -ЗH‚ˆžuДТ•\ &…• 9IэKХŠ‹,cлЄяjЧ‰i#0пk)^ig”$ ЧраRНЅйŽMX>? gІ-Ѕ…ŒgЌ'9OЏџђZDwFГ.b$Y=и‘тЩЁЁ7‚ЈЫ‰Y[АЗ‡3:ќ-эGEбДq˜7zмОŽЧœў_::}Ml[ЉщщP›‰+WяуъЕ сdъЉ3HЕёFƒц~šЕ=<„ЗpЊ„€бїк€“иЮЖцфЧЉL }Q’#Gq^>ŠsђPB ‹s‹qыъУѕсЪdPfЃ їЈ6йХESћїНгSўЅN4П ?SёWлЙq8ѓag„2пhЛ |rsІ+Ѕйфa{пСинџ ,{П%TrЪ5хтaЬ„q,J Dхс"о Ы;_йv2‡Щ­q1Ћн}э…мFїIcr_ЁFb– ОVH/(ЦїзШЗЁ' 2 KрFТ’Кшбкq=жўнБяи?0Їу'X3ыи‰ˆqЬ@ ВБ!˜ьšр•yи5-+ЇЅ`штIpšИH№?в№RсьЌ9˜7Kф†ЩЛпBCиЇ%FcѕєEЛ№AЗ‹X—Г!ƒ?DlЎ†]‡щНviEaЫ‡тxк–R)Rіb`ЛљКыbFгzУА)ч[Д0д,щz№ŽG 6…я)sњфw•йnjЃhр_еkКхЬЁяYBi6vМaЃ‡ЂdХќД; Ёƒ™Я>окЉс\п.о^№єд VІЎƒїуu!NМ“CЊgGЪK=& O‘РˆЙdњњ4Wfщ’ЙSІWнYwМИ№[єњLЬЫN‰mЬ$Ž|9Єн’кSVYJŠ&P0…з—Љ9„ІіСЅZљ!G€#PW(К4˜юct_Щ—уЪКфj[&3ОЯмЗЉН&туY/р‡…нЉтЕ1{ХљcBBХиУяЁ{0ѓ‹}xw№pp§1Nќˆ# "PgЂО{~„"ћ>rЏ\Сc Иw& щ™d6Ђ’Х*l"•Г%cє’I@ $С‡(CQB&Е8Зh&^_%Ж$И?:ЕЬЙЂ>ЄеЂ БzAШxњ2ГЧ’цТS|Х8O —П:ht%ЬŸHЄ’eт^хЗBЪ2Ÿі{ДФн&тЛзрMWЊЁ7ХљnšŽ^ŒPzРSwW|‚Cч_Cds!>Жђ“ђЇ:+ЩммР^.слЋЇюmP’ж(ыь_Ш:rЉWqўj*’23беU…›$yП:ѕМЌыЯw8Ž@m 0*0‘сщbo7ВœЛKАn2ƒИH`ЋЬЎђ’ŠфjИt} _ н@&џehѕЋЌCДlЩ™zымLЄa;ц;œ ЧcТ‰ѕп%!ђѓUž›3р<дYЈ<Аmœœа cсUКO›в ЧYч’qћїЃИЕ{ь)‡3‰PщЕGg4~Й?%{|е 7пхp8UCр№ћЇЊюwЩЂPЉТ§Пц#nнXŒzОо=>ЭœЉEwL[џl‹Hkж ~^ЋБtюїHž^ŽЯQеЎ—ц<щеTћ1}§№їo"h=П "ПЫ ˜—|е’†)PDЊšАyЋБjj(Ы13d>іПI‘#NЏOmу№Хч‘№d“јћБПЦDZ6FnЅ%•œJ“P&q*eТ\Ый<пlФЌ1Ÿ,9 [qФКЕƒШ|зЃFт‹Шe˜N~‡uЄ7z•&ђяв5beЦЗg ыщiЋvaлб•ˆ~8ПВЎЃKЃжˆx†aР‰#`џ"a(v­_lо6 SжЦTаƒŸтpc2ЛKZЁlE1юQЂ,zэМšз №У=вQ{ЏWZуlъ_ˆлјŸџТоѕчp-9Я6ѕСлw*ї~И"fэfќr№crт0tа61@QWM“Ц›ЁЬ$,щйmэ;`ФЫ‹pNКyJї…ЃpnfЛ~шсеяL#ЗхGС@7”vNuвўШиˆQРТ~я#!hёїtnŽ%х yЫr ђhяЃ‰€+КGђD?’ЮDЊ'юф#ѓ эGzP„^Є­Ѓ”šњРЈ“"6ыO*№Њ}­-•KФxЌ=[`ТЗsЉ5]!еŒOf’вeіФy˜9-у?шfфм]Є|h‘4VЯ@кЄц•# h'uvCkк]Зш!PGж <$ЮЃдњgщЎ›|ЛNЧѕ4Z &к\TАR–ŒИyžгiў:Qa\ƒcИŒE2ƒsхьІdЇйyљwьНJ''Ž@p(УkoFсЅa}рў:н{ˆbccсхх‰D#QHGхg Р‰Я$эtО‡mШ'q љ–ђъЋ<п2Fф%m@ ›6нk  .М‰#№d `1б [7!ђи!М|p?:/_†gоЩsmEІ2vkЪП—EŽъ"kСоb)”t‡)&фbц`"ЅяйћSШLDUяГSq`;§€GЂћe—‘v#ё*ЎQŽ5§cц#8иRСкl$,YOЁъ'pіk$2ъKнZ†‘oR †OCZЖђьLЄ$Ѕ О4šкПф“ѓsьaЄБ9Ш\•xш”p"ШщwаcьHаv‘6* /ќ­b?`!CшˆIДюE˜Л$rЩ‘ž”„”[zчlЭЬоxc7уНЃЩ!;5Ss>+S#•*Ф­],­( ˜СXАф0rTjdžў–Џ ЫйИBšAD›ЕЩЗвq`іЛ˜Р,”С@/КХc#%šccгїџ€й‰Р Svк7д˜я ћnОА;/§nиФї9&!РnЊL+єцЈС№ѕєС‰ьуhщ & >tбмS4b‘Il :ЉpуЦяо†7Фвo:`%™чЗ•t0aъЎн:`ЗюОтећ>ƒПN k*'о#№ф!`1‘јжЕаўж­?|п­Ц”ŸіТJ*…šђ]KЫFђйTzzюdхb…‹g=Pыn^"ŠЖ…З0ГW4КИt@˜Ч+X˜…иu}…ї&/МђтС ЏNјюИ ]>&AcХ єr‰РђдFХД7э>@2™—Œћ’DЩиf^ZŠў+(tпЃ:zєЦР‰ЧЫˆЈRс—˜ёшOsДЕ!Чю˜8LоБ ЕІ1ЯЯг˜ПP$ ,KЬpUš|Ейk]: УІѕ#Бkтhєpщ„>!У№ч=б№Їхйї=ьк=ЎДЦHЏТlŸ^ЫЈC3Ё~ыља<фsѕх)вbM.6эаЋн ’уј”(Ÿ’ФЋdv$Ь|ћaТЬў,ŒИи™ —ЦіщEщжЌХЋСšЇq6Ÿ)дЫП=ьЌZ~ЂŒПqH хФЈLчsЋп}Л 9{aSOŠєИ,мпЂРš5k ‘•UеnНЬэфе@ˆть<В?}GшІЅгМцрРќ9: вŒйП"SћЁ8ПQ!џFЊ6‚T‘L‘š­Pрyj#aг(Жƒ6Vqћbi|–0^Ž]ˆFe9аЂ$m…Й—,ŽХŒтЭЫ‰#№ `№“јЌЖ†–шшш€ЬŒ\ќvј$к‡6Д­‚qљъeь;qRkk“gўOќёњџ!П@•ЪЎž.КЈ+kŸp,V‡œ,@2ЪоlсH,x"нdp 0uЈ^У(эГЇ1gуОlM;cnЩ)ЬЬ&ѓ™=ыW†o NlŽвф0K“Ѓ—; оeѕ›`?ёKЕd,ЕDйjЯќ)а–eЏ§г {-љѕ ~‰ЏŽІЕЊamя@!§н v§њЦЊ’ШК•59ЫŒ2U—žG3а#Дщ y. Y6ьКєx;їCœВЛр˜эBŽйР`0WkFAц_ˆ&Ъ(ШЯЪpЌІзЃџZгSWПжešЩўw5*†Дь+­™убyKF@u$жdZпƒ-ЅєьђJLLŒ№ёMgтБЉ[gЁ#I)*в.ЏкBпx љЮдHј(SцЖФWЇvЃЭe|2Ѓo,DмђюP+ѓp%)ЙLeKїЕ*$^@;<Ћ‰„G‘А_j#a•7nсї‰t_вЌLuчTљбЈЧ6 a‡Ў_Џ;луХwBё†ЉХћqjr~жjyUyњзћСŠЕЫ‚іЭ;aпo‘œœ‚sЮб ^щіjЅVФђЙ0ЅВHЪ„ƒдO€X“”і п‘в}…aжpp'›QEDу\ЈnВˆЉЉшуrЦўсўzЁЃ"VFчHг­ешDщ–ШГtу#ŽKсbи›pqyшZЈнмЩF'мЬ­Y‰У1•мяш§\™csшЦЊŠ0"ј%0с‰G "ŠЕв3‹Ѕ|›‰’R>ˆЬœЦ4HŒ*a7š’ЙЭЭkз ѓД­3OХЃЗ?}ч “Б~n&^о<НCНщЌ7>:8=К­У_ КуYmaЬ`ЇqоŽэ5б­Ž!њHиќтyЭРЂœbД7ŒF ў>uгj4 {ЫЛƒC…ятoПСўu_igфŽ@нGР№чЗюЏЖ†V8jР(Дu ХЋ&cхњoщGпIЩIшйўy|:qdЖOНЭЇлАЫХЇJТC Н •fыа2;’{ЁЁ€Yi.š~.^”œГЎчм)“У‰лЩPЈ‹0ІѕиXѓЏM™ ёF1rь~œFшanЏhЃЭШuшЭ1C…ућлЂтЈвШБ0цCд3я' Œ^EGњfЁъвЬUЧSцц!ьk„ ]ГАc]*ЪэЁшVую(КKЙ†бЈѕХZїў~їў=)?Ќу№O,НAжVжя†CН~ЏуoWU—gMI ЊЪЄюŒЗsG@ѓВTGц-Б“OА‘@ФДƒХTрWЄФЬЫXrz3ЦЗ;щУ>Gb?Ох0X4гeffBBХЄƒоіD}Е<]<MбgLSщјŽY` >DО>”8v4UАп‚OлЭУs9sаBЫ-§&™еЕОtjm$ЇвPјБaк!JЯJAVщ>ДУ+мE‰ъz’РчkƒGгШ”­ ˆЇœУ†sъњђŽ@нDР""–Eжт5‰LAщщщцн,КL­‚˜0фFб~їњ˜c–МqсIЪˆню58к<=šУЇч]Ќ WЂ6X4™H%Х%P’Pt-?—вПC˜[Gс”ЈMћUjKѕYШх‹Kў…ИuЃ0}Jќ@~BQC]0oкFєk7MЄЗА6f <{LAc­&UEQЉчвс”˜2а/Ѓ@‡§ДєyЯOдDТyšf„ж$ЮЁeЧOя5Гчи ЋK ІO\'№ж›чєг№=Ž@]DРт"& ™šE–UЌцBQ]ќижЬšœm(ЃјГ”ађЂn‚цўBТЦ›y”йRKЉвБ a&ЗY…щ*Х!|kAh sѕызЎњюнЛТіЪ4цXяhьњсСш­aЭ@F /УQюЁјчŽє‰œиWіbЬВ5ИC5z­zея1KЗFi2кЗш‚Щ=0М2Ahк7C)ЃўM7н†Б Л“Фk$j˜^T›9L7ЦCaсбs$ЖlЖХП—ўˆеЎ­Б„"Nпя#Э”nпсд=,N п‚Л56їУ•еюaŠ‹ѕІqLMnUЩјiыtеC[Е&gуМЫC “oА‘@”xї2ўб™~PўиŠЋ$‰ФЄљ ыI(zѕьсф.т[‹@@ЃDAˆ]4 ЙЩаЉZBтFЅ‰"IП(9m4ЬћeŠ-yOлц‰˜э‡0˜"M)&”‚8 ЂQЅоˆ‰?„AЉЪ˜,3dŒž•&іЈA$l4N–Dk;P”hт}gђŠоџЛA4*Щ0KЂ† }вv. є^ *Iœ8OKOФВЋs‘фхЈЅC7еBƒћ‡xЮф-Ы"k-дгŒ ФаХ“0–*РWєГЉИёfНГы†’@Dљ“GaаЊA8š]qЩ “Ц;š‚@ЋњpВБGž’Й­RhПВГв№> >џ9‡‹Y­3фй$­Ю5pд8Ўš2яѓt#№ўк0э2#&БG+цK$Іmр81tžе$ќ`эp:[3$s.ЯфѕˆHе2Ѓ[НFѕ5*нx ‚^юпЋП >Q…Јѕ›Р-ЫїЈXЌ@Дz іЖ6$иє—ŠТфѕя‡ј„ЇoЉЬЫ"Ћ‰‰‘твэ5d<аx7ІОЬТ`Ы!Ёf‡ОІ—OџYˆэъЩ…ЁrрЊЉf)9иwєi%д6ч8r+ ЬПh"љ }ѓчv$‘жHЄьТ\­Іh92Ф.|kXЂЉнкП+~Iоˆє[Y((ŠФЛ!­шУMЪјёb/й }э{­F БE†76’EœDƒZIбЏЉ]}­бІž5є!ЌFƒL<`.Иbй№С/ .‹ЎоЇжђ3Ш–fѓчФЦ]аЅаOлП[ЗбeŸн‘tыDуГи§ам$ЬМзєъy§IОg*}ž3ъš|я*ЮТэпiћ к7lnt>ЗH.ј]ЙЏїХ0ъР8€ оЭ[ ДggtюЮ…!‹xЯŸЎ‹ДXHї6Јƒ˜ЩŒ•ЄHЩЃŒЩU%P•ОџЈКK‡†”AЖ&LЛ'dн—И˜5НЦџVFљ ЪЏv7~К–a?чєŠљy§џ-WФІ}KбВЁ/Ztтbі@єlIћё{ьBZБmœЬF€х#ђ3аіАZvLKФˆiF…МŒ.О!Fќх”ЭzсЩM8яšQ;?р< ŸцяСђ‰,—'ŽG 6АXhеЋ l|ЃHАё3“йЯ—5ЙщѕEцП-ф„yпХHIєщ5A“`Pыл”A–Š–j3ШzwЦŒƒуЈ–eeIEЪ$VГKгkчгйqјтѓHњћЁ=zZЃѕР1дО ПŸ–г6?й…ˆѕ/СГL^МБ20чjC:vы/н!ѓyѓЙ~xо?LзЦvj%–œкŒ?3 ДvF=јGрaЄTK‘Ђђ9q8ЕŒ€ХњмЊбЂА(3f2+MU2ыпїUМ4u8ІЖD‹І”<Rъ3SZйdKЯnxЬ2РвqЄЧCўDжMУ1ГуЮЃы,E bћцћf"жP““ˆi‡нЪЛ‹дћЗрцЃујZѓžYл`з}фЊDM~FлѓмKшргRз—я<§tnжEО: rЉ€s šEЏnЫ@Ї‘ныdєЊ";9TѓбУ цc РРYrLBрaIРЄaOo'f2sЌЂХ‰ >с§zЂsА#VL‘Јь Вšseџ•С3ЮЫƒЖОЂA7t›9ѓЂчbю1вJŒ^Œже—Ий`Ылeљ…XN"CmЯб[g"†Jd`W!Aу”аQ$&D­Nњ…jКћЕ›љЖ PЌ~t: +kѓчўc*яX/?(G~~Ощш‘ЌЏS$ЋоД/ЅьAБ9п"D›|QdЦЂW?Л п &Јд9БOэlH˜? ЃІІoаcVя?ў‹T;oŸU@Рb?~b”3o1“™3E™Йи8Uѕ"d‘5ˆœ§1p(0}кї”AvД6ƒ,™Т">жe-{JBGPяŠE˜ЛЄ%>ŒyŠЋ—‘W/ˆœe№ыг‡œЖзaW<0mA[ƒŠFesу­І#РЬf†ЋgіZѓ^‚‘!—ч‡Q)жўЕ[W›Šщ•жŸћŠШŒжЛБyšУ9ј~е`ZпSNC)јбBфnчf‡аAmФCГЗл7k†RмƒŽвbГuћlЧoИцщ%//JEe!X$k е2лŒш7(”ьzьрAOк†9ћC;lноТн‡ЂW­@бЋЕš HНУњbПе˜;XЃСЮмГcЇхcYъqti”…ѕНЃ0a|т–wчї0ЃO ?xœ˜џ(є8WYs‰Qfь‡‹™Ь^Є(Г.к(ГЊMW*‹ЌŽ™^\Ж “VQйhыё –ж‰M[Дd…~L<‰іыQ‘K‡aиД~$vM.а'd˜рќ-œtn‰з„”'#б3ДЂLGBoўЇ#Э‹FC]DqЎzMA№Ž•X2Џ?Ољ.цВGA5EООŽOч6СІ›{Бl103d RЕ 4хэC˜зo<юћ'О\CІaЁКs ГЛ УЮF#KЅ9NЌ˜ƒ=g˜U>/пˆH БХ3C?ЦŠSƒрk“ ёT:DOjЅ ЙœРХЋ!N†яqЦwюЧ7o­ЭФІ‰YdЕˆšJЎV~йGЌШNƒ’ЌwжўuX˜Ќ|•9qЊn˜йlпѕS:ЖчюЅ 9‰ЪЋaьй” ПFSVы-uІЏњ§4 UEx‹ЂгЌJi‘tЬљЮcA I—ќёУM iэŒжЖV№яш_-ѓ33йіщџx‰&3QCФw6п‰=ЛAa!ЉC˜?хжБ‹q&И’ЄЫYПГШкŽ!бОC Сd&ПЁс?ћдADвCš:ш йжб4^ЄШзLДџІ3ъSжlЗ.=Hє N&П€`ЊY–SLZ1kL э"хB[ћyЋБjj(ЕЩ13ј?иsќ&bZ“‰И^бСAhVO† ]Zгњш>E>P7)wГЦnZО€CЃ&hOЦНЌ Ь™КЮ|‡#PCXœ@ФpЌ)AЇ†оЃ йкРŽKCрYa7~вLќ('‘S}!ЪŒБ`гЬЙКO@‡r96ѓx„НŽХЇ~3Г‰ФЦ1!‰х1bк'NЕƒ€НЋ=ќHpH;Љ•hЯ„?™ƒЁЮЂjkc‚ ХjјˆўBьh+V5эцўe&ГзaˆaрЕЉ„XVІЏб+тдRЃS(™fHOіДћѓиˆЋoЃjЌн-Fx'c!‘Еѕъg˜ДОоШP>/5„ЅyZе“ZRB‘!Y­FЏ-OMТI’оp5№Л4Xпх<,R zР>Ў9<§И0TУ`Г$Œ†Qd,'QE[NcWo|> OlТƒЂ|н OпЙ(hXЦkВЯЉv№iэŒ‹™Pф(рXп [6ЈЖ…DŸ~];u7Ђ"Jо)WPСUђкВuЮОЎё-S(‹P\I" cCБЧh*Ѓƒb&$1AЈtа >д3jѓnЬŠ*mp瘡Їm#v(Ћ QтЅчтПH{*д gьЋРЗЦО\ вуФї7'}5lMЅ0~šДI•КpоY‡ЋcЦœЃKД1dЌв=Ћ|Я„žŠШЧЩvBBбїИW(:ЋЬьЖјфxЏ]ь):гуGРZj&]#yї4щ %лЌКЖ<WмЏЁ€‡mmmср`G'G89вЫйRšзQц€ЛЗю‚ѕeдд&JrЌЎ 1ЂЛЉзщтFІXцХ•œЌ!sB~тU\Ы”#ШгЁb–ЮAxs’ІDЯGЗФYј[  Y)з j?­ocХ 4g…•?Ši–rв3(чP\ш3пqТLя5{Goп ,YˆЦ“ЁI)—Sцч}8е…€Х D ИиЕ‹LТЯT_#“˜ёNO,Ўє#BОAg2/щЎ™П%БЮ^ю˜кa(•ѕјЗѓГtу/нПЏNl Ц:л>т‡K7ŠяT'юєЋпМOœ= Ѓ;ЭŸса–a№ЛёрС‚œШDZ2ГŠTB99ЙИ{яэбєŸ6`V%")ъQާU‘oPžz=M&?Ё7_xƒ2Х Џu˜|ь бGЫŠмЌEВЖБ58ЖF/7b&f`BH„и33 –гЪjѓБŸ‘Šx9 §Ќ70;z"z|ЁЭ—дѓ-ЌœwЃžе˜ž…іa™g=iлNѕ€А†^єЅЩHыщЮpЫCДІл™йЬЮнMEn‘‘ЮЯ№t™ћ,ВьНа(Дё2Юѕ@‘'˜ЯЎ=ЈFMA™+рŽG€#P-Љ/ †ђЯH(~яфwЌtЏВ€ЊLћ‰œЙo)х‹н…AГ~г˜УJЙ(Ю*Ž_№FŒтцэCеEБЪЌ’ї­,ў. сэHЊ–д%Х8FЮе•%–ƒhl›шX* 63У1Gы”lQ8Ў,gоŸ#ќ4–O4tЗцЈp8І `ббХЏОЧЅх?тЪњ}V†ўDІ€W^Vэ>э1ір8`бD|w\ўPвЗ3пЭЊг‡’­ПуЛџсаљЪiЪ›ŸЗзЌf™!ЅœDцЫVм=ќк /ЄФ,$џЏЛ”Q˜GР ЄR)%5c ТАp,6Ъь­РЛ”Фž.V№І ђ>юЌ›,ACW l‹D‡ѓ?Er5\КО…/†.УєŽЫаjŸ ў–’3ѕЖЙŒїvЬw8BЊјЬhэwgљyИАЯџдMТШ(юТ]NЂ5v-ч6˜іЈВФrп nљ%hД%џ0Эg€ё(*V ЩYFыv ›U–-яџ” аu yї‚їCgсAnN  ЮHЦOл2аidwxжС_Ev6х:ЊDдK–Љ’>фьЭР{4/5фЙ*СНFРцL;u№#§x0HxпЃТ‰J r‡TиБм“,YUИџз lY7ЃzбaФЧBo3ufЎ„/Ъєж ~ VcсмHžŽ<Л\Tkћ„х$bgI™—uK9zѓЌY‘Ш``ГBлЖ”пФ&0sмŠ3;№–КJћ.щ:ёZG X]ќШ5XY›ЏˆїуѕHўЅ;ШЪ‘ŸŸ_КЙќckџ:тєБЎTXC›/ЈдНHqу|2vОLQЉsхO№8Ю(0FM; L&ф5к;~хќТeпЏчЎBмŽK[МЋ&Д0XdХМд™IјюѓяБkбЯШљлЮ †‹СhОћф"PЮЧхЩН SWОрœмœрХ4DЎ€7iˆ|нHCD/›Ђj і ЧЇыЃаH4пšь'gъ y=ирKил WŒЧёщhёrХMНFоЏfшфl$И­ЩIdmeў_П&…Ќе’џЇ[4ЫŒ{іgЁ(lOџvКvОS7(І$‹Ї6œ†В‚‚ЄvnvдІЪ оОYУB,ЫŽ ЦВcБ^Z^^>” k2‘Xdl ЦяоŒш7(„rv№ 'mУŒ§ЁЖnя'‹… %vtc›Z$іы‹§§Vc.Дe”ЙgЦNЫЧ2вЖwi”…ѕНЃ0a|т–wзхU2\АŠфХіcпƒнŽpС№„ МT”фЩЉu>‚•mIxфєД `ўќ G aJ=ь%УїЏй`aL —bH5zyYЁ[ЃŠЕG_Кь™Ю–ЊG‹ф7xŒy‰РЛCƒФгš­g[2ЏыV'ч*bg…LАЦнљQэ!тедЈф‹4K4ШbmюЪz<г#‚_‚UЉ2пŸџ?_9j.[>Ў†А"ИqЇЦroвUѓƒ]aЇGœdТпяСї—Рі™ $ CL:ЛрN}žˆЅŽыNEЄuVVВ6 †ѕ в>šhVowЈ“vri;f ƒ$›“ф–љњЮ‘_1]*фK››l [ЪЦо& ээ%“Б7‰nzЩЉˆьџa§žУXвКzQNЖКгэ3›%aטhaЬШ1qHзеC.›WJь—ј`]6v y%s(’W#ѓ@ЋХяЃKcŠТ•z#ъыЩИЖb.ъxi—Ёнxїь‡ћvDГ{у”=юQМdўсˆў<к‡ЖA1„)…п“}hБ3‰Uє2ћmЅ,ВsKўDtА|Я8Й#zћŸHмїІ§Hч{ј'(ЬkkЉЯіH2Д‰Ф2Сў‰UcŒCДХГ|[;”™“шfRЕ,ІЃO+Œi=R‰ёчc{ЪAђ]ŠЏ–98“ъCРГi}И6*л`R?Ам|H§\ЭФ„ ёХXпЩИызЏbУњ fЯФЌ_ЩGN"ёјiœо—€”kr8<ŽйЃIќŠЅЧ>#Э DE”&dBЏ)оБKцѕЧї1џТХ\цХ­FТGЏугЙMАщц^,Ѓ„н3C– •y)oТМ~уqм?ёхšЎpЄ6еS˜нmv6инSqbХь9У„ЈђyљFDbhˆ-žњ1Vœ_› \ˆ/ тАzR+m Т \МЊтєg їдt-ЅМЯUІѓRБЂЙœž*єjŒЇъВ*О^ЃЌb|јйG#РќzЄ§Ёыx–ЂТђŠH•n[њ‰SзХфЖ ‚№.~]іЧVЉѕљўw5A0Ÿ1GьвZ$“™ѓŽеŽ@“.ју‡3 Тe:ВЖЕ‚GнqUv˜™lћє ,D“™Ј!b;›яФžнП J€`€љ3mЛg‚K IКŒѕ[1‹ЬQ!Ёрвэ;ДLfђўГЉnZdЈ дA 9эMcсEЌŸ›‰іпtF}вЛuщA: Op2љ}“ •SŒˆo6bжбU@.ДЕŸЗЋІ†9fџ{ŽпDLk”Ы+:8ЭъЩpЁKkZ=,’дMПYcŠŽб’CЃ&hOЦНЌ Ь™b_Ѓ­ЊАњx1цO'ёъѕOТЧВюЏ‘vmшшЁ+и*ц$zОqXЕ,ОeН֘дю5ќћt (FЄƒ7ў ЭyЎ?ЊтГ$ђулЊ#`яj?вNjЅbљLј3ЅкЈЪLL„ X б_ˆmХj ЃІнмПЬdіaт: жhD>Ђ„е9ЩjЉбŠ)”Ці8№ѓиˆ+іІ­VІ/ЂŠїсŒ…DжжЋ_s}чњzЃEљМДš…Vѕdч†–фЩ“p•љ~z МфЉI8IBвЎЦзЃŸЈœНъфUЮМЙю"`qQн}+јЪž4:ћ†`ЫХКeЃœDе%1ІЯК7Т”А7АŠТВЄ"%ЄŸƒBU„бm"СЬwœjŸжоШȘ EŽŽѕбАeƒj[TєщЗбЕSP{#*b!у *ЪJўB[ЖюРйз чЪ"Wв‡HУиPь1šЪш ˜™Š˜ d'1jg‚OЕDmоYQСDпAcК*Жѕ­lЏЌ6SxщЙИР/в‡ ѕТ%„'ZћVR ЂШгy9щ—Рїž ,ђnњеА5а?0ћ19А2_"ЭkeБ=дLџо_;œі8qЪF œrm%HМ _ЯНƒ4Њ`ячR}?†ŒздC№Џ›p_Сžу5t†œИ—œкŒёmТNjш=!ірлЧ‰€ЕдMК4Fђю hв-€n+Ѕ„3smyЎИ_C9лккТССŽNŽprЄ—Г3Є4ЏЃЬwoныЫЈЉM.”,G%ˆљнMН†L72Ыj4/Ўфd J3‘Ÿxз2хђд{7–Щк9oNђР”шљш–8  ”!+хT‚рч^цˆ2…•?Ši–rв3(чP\Ј˜mЧ C0Нз`ьxН}3АvƒH&bQf"Yли[ЃЧ—130!$Bь‚™‰Gˆ‰эЅХДВк<„ЈкŠx9 §Ќ70;z"z|ЁЭ—дѓ-ЌœwЃžэ Ь+ф!šлYr?ѕмГ<^жv4‡Б™ЪСгžFТаУќLmЉN^ІЮЩће.'Б Ж&Эа;Ѓ†Узг‡ГBƒШ0iј№сdЮ|Šилbž~ˆe}e}н†7ФзпtРЪБЃБM›дŒё5—XжиЛщЉHCŽˆн7ўмZb.ЄUgc-ѓ%2Є#е”“ШЇИяHa§я‡НŽ wђя0  yЖ нЩч™т `БШн­чРЎЋ;-ђкљEsЊ‚€Х DЬ8ІоZ‚ЅпЎABЮ^ие“рZMl)Цš5k Ы@[b 'Џ”ѕеGіGcІ‹ЎШСљ$иhЕH3fџŠL#чw#ЊѕП‘ЊЭЎЊ  Х#[/@ ЫЕYcAYcУДYcЗ/ vі^d у)l…Y_дБˆвЮЛdI,fє$оz?нЊ\ВEэфѓœбѕГ:gљ”“ЈІШŽžи'RHўsфПdHY…9‚PФ Юrт”…РеЋ%x=B;˜A xНЇ oєІ№є>%xу…b,Yj…є[zЅВx№6ŽРгŠ@е~љŸ@TФ ЖЅ у™жWaOщ4ФBЎ111‚†ˆе(bdnЄˆЦхЄU6VmСEтхE‰Ф4йWЛaТД{јъдnьK\ Ьš‚^уьэje>.&&"WkўW+3p"ё ши!P“5”5іkmжXUС-8@§Е•ђN|9Y_ЉjШё ˆŒ\„№ѕЋБяъFд;БЛтoЂц~Ж‚–An>№rа‡б9‰вџЊб‹gšЉqm_EЛЭцaeD$lР•ћЗŒкљG€!Аm3† Рїk4wТW‡њcфИ&3О FOxщй 0х]+њM{SсАq,Q>А˜KЂ4шj‹KдHњ6IџVy IЩœ&’A0‡иdв–10Џ]7„иD`ди8Ь<оў$ ™\YžŽЉшъ Ярޘqp@5wў2адP -Б @8ЖѓВЦB›5жлйЮ5=ХўEфBЦВОЮь‡аО(m>№;e}e‚ищяч!унСЁ№єo!пnЄшю|Ф№­ъвˆР6 š4›‰гH­Ќёvы—Сђ!’œђг,ЄˆДѓїЎ6ѓ}Ž|Ш№ЌП=ЄšЛFH '*тj…РІK /Е‚k‡g№ЭіЧ‰#`YXœ@$FŽ)тT(иЌ„’Ьg,’•љYН"СИб#„-ћ˜Ћ8f)ؘб–Э#ЕŸ&НуAZ4sеЖSl„›&*Ejt'hG?JгZVжXУўEфМдг0ыk=ёl>2ЉВњ?cP'Эт E0jdлќˆєЂ4e&Ге-rvЎib%<оzЎžїoo4•‚J~,9Нg2.Еѓ G€ныЌщ^Ї§АІS9ј„ћ№k•ў}гбЁХ8КлТкЅЌ;RэbЇЮеDЎUЧ*дЩиБќ7ЛBu№ЌN,ORffŽ.M@Uyзѕы­ъѕUзx‹ˆDрX4™ЇЇЇp(“Jб~ЌњЇ‹FО9вWЭ‡F№!ђѕA`дhЁ‚§ьvѓЈ"3MЅ5…ЅпЬ—5e•ed$ЋНхdfбNшdТŸ2ГОRHЊ›/ >vR”iHžrŽJrЊ.мэ\аВ~€Лпo$зфСkЭ{Ё“NFSЈŠејњЯ­`Љ8qЗГ”ШЬ/J­yм;rY‰ѓY,ћЖќŸ N^v…M д”qЛІ(yqžйLсё&*{чџ[ЗG˜ЫD#MzщбЬЯRєЭЗ}"тtї<УўŠр“БџAzѓP aў$„yD —W7єˆEZ9жЫЇуz п•кп7џWПізnц 4F,š,3SѓЏЄЅ4W БђќПPP’GкЁJ8fјЬ_Щщ”ь†"У‹KV“ijMЁш0g  Ќœі=R2PgЇbm ™В"њ 1K+а ЄžKGкЁ8єъЕLlдl)ь‰šЌБ—Hугe=ehCІЙј9˜={~^ВC>Ё3NZЃ[Y#y[eшфl4„ "Х” їqQd`WD7ыљџь] \Uћ~ИпESTМŠ%*Ј˜šŠfо*4сoоJѓS)M%П4+яЅI~™Іц5э ­SLS?SМфTHQ QP…–§Пgfgwvй…]мУo™™3чМчœwvgоyЯћg0wYOЂд†Xc§JЌБ=ёпHsFхAт#ŽDhз…c}eьЋ“h o$№Уq+Ќ94‡Ю>QїLЉW5ЈNн`MСњBЪ)ЄЕŒлТaЕlЖъ†w^ЌfЪ3_@шѕ#8B7YczЮ5@w| ;њЇИѓл8Z ;) KЇЇaбфЛX1э~њБŽOё2H>™ƒ ёzќЖљѕфМ6уw"EžЭЙrлУnrє!9‘ai2Ф їГBЫbЩіxўB™7ХаЉўєZŠѕдˆyф8пFтхEeFŽ‹›3!|бд•т4iЙ‘јэ_cvhށ&_ЗžїŽ1ЦэДГтoЎ!лу”STвфh„tъ^ЊявBў:їhу€ыŒmб9&œ$жJœ9m€Ќ‚D|щі9 шeyžІ"­Iq6d^\§zЗЂ.{РїСHІг[LwЕdМЪ‹Q wžЛ@сgў№сCхх*&ШН,)–Ј№7ў—K3эBЖў[b}].Woњц‡ФlњЁB†3&юЛ‚1м|ИGxІN?€‰ЧЃ0ŠжЩ1ЃЕq˜-3vЊђ,Ьš1жиH5жи%k,ББ^ЗЫX_ЏЈБГЖ>Ћ&pSіЏЄmcи?У7$еШъЦž%­(Щ8‰иŠєBbСеЬPЊЮдЛy'X‘aіCь0Ф›иBД,ЖшMЗоB–qћœiР„т‡lъ™С„ "’У–b…СбVфІЈЇEaщ€lXэscэХnфŠ_WѕBСУ\ћН –И‡bвИЕXфЕюE_ЂоО5XАЉ9~ZЉў›‘ВХdK%kĘвŽ6ЊhЫ<Ц•?Ѓ‘O\ЛАлЫžpёѓЧ8Џ§8х5Ы‚;СХ† "3ЈsУРр{№бФo№ЦШM№ДHТŠV“‘Мb ŽjŒcпE№<Оя2тћКŠЫнАє№jaйƒtDФ„"Ђ-oЂЗЌЎОa~ КŠёЋа:q`UœŽ›љАЎЈЌШХмp+IЯVЕ`МіТV5†кДїмD§4h2–иЅуlqWХbŒcьfa"7З0ЧьŸ&P‰ЊIŒ}U{"#‰д™8жXguž%G [ЋУУ\в˜аn;vЃЕ‘дQЇЮ*rЂЇЫKjЧITTPэkukъIЕ%6\й K$Є g ЁўŒЂ˜#с;/œ3nŸ ˜ШaaЎ2.LKШЂМЪN…З‹1.ќцМЩЏz?oУ МtїПюХ5ebbAОt–l1”8сў Ф8Ÿ4фЧ\ТД?#рЉЯƒеК&nќ˜“"ќ+AxŸU=~' tЬІжLM*реГ}cБšЇя~4ХеИ;hж‹7‚ќ<юТКƒЄЃR:ЭОmЮЭUhZsћ†фБЙ‰, bЖбlСК5&юŽаР04s1& Pqzi-яиœ"6џ{a3o`( ЫhQYЏTн fIј—O5”Й—(ЭЇа!ЕїКвbѕšЛЈгАМ— ”%М^lkMЏчжѕбZЙє˜šх IIb,.‘‘4кQН=Ё_5nМBЧjщіЙ4ˆjщЕzЪn[Ёi{Oњ<Ѕcѕr5РxіЦŸT–;{?і™DЌэœZrK}ЌŽкХy†„NБЉМ‚тBќЫы 0>#cz>4аАО§_VЧ}|јЃj’Ѕ…ъ{%'N;2Všx„=юеyFОмЫeннП‡cТПЃњЫMђёU,[5;рb’cD,‚rYpі™Лс­a›1Я’Жzкђ8‘eЩЂxY”cr@ œ.PyьhЬиjЅa€‰ЛЋя~…њhшxѕэL -g|=,чТ9Œ3З–SЪxкЈ•49‰юфЄ!UДBНЊdѕьЕvlЪ- ы`ЩПљ ­FЇнФКЫ{PHqEЦє|h 6F†РyмчФqоcЂož!Вlc†џЮџ™аДHш… lтiИ,ю чRB63'Нfу/y$ў3Ѕ!ОєњRјЬHes2Вp?1•Ћ™™”LтчсAђЯь<ŠФ,•ч‡ХЅХЇ"5™К )HIЮрЅ– '59ХЊщуR]Qdиvш†СHРЂOТ’E§ЯЪ@|LŠr I]ѕДх—%ЫіWђ\EрќY’ЭѕЫ =fŒEЬм18š@†jA 6z­BЋYhУІдjСx™2ЃЯрD4ржч˜•Љ)Щh•s%Ь‰ЃЈDeА—SкxкЈBєбz0ž [ЉЉтL.јЊжŽ{gЬщ>NФ—$Nз&тлKЛOьжЦTї5АdJl[Ж@=ЗЖXї)ЭѕЭ3H;9r2 ЎšЖ'zИŒЧqџАjNwІ–П< IDAT…ˆz0oШЃ1Ь|юІ6XўчBкZaръ-РЬ›}Œ7@ nc~уДьаV.Иј}Я|ѕ8“Јр!О;g—%yoт1УkЕ"ЄЎлбjnхк ы‚бИљеLєГB у„ЃФygј]ŠВT0fAќwшАi†9QџbњЬH%M\OQ]UW‘Ё,S–Ќf0œ#V xC}~%”CП‹-+њaЖ›/МlоРя§Іaеђ^BЧ+Вэ0е†~$љфхбBпФqEtц8*ЖT/тйоJФbЄ)—1ПЦВЅ+йRЛєзЭ–ЪЦ“yK†вкmОјpг-ёiŸ1Џъ–%ЫˆХЖрЯ`тƒНї№o~jуaЇЦює]ш{Жє ў&oЬГNŒQ{ŽяX4ЗoЌж6­їѕ…x\ x}V;k<Ј+јj‡ rЏ$rЦчDnXњцЂƒТиb<’аƒомЖFCЌяfжЖC\ ёћєЦPйВЌш%Pl БвЖЮ ˆCIЯQVAKzЖуевЁZUcќl…љЈб(b№BЩКО5МGuжqVџь}aМЛvx€рj’ЗЋПСИN`LЂ.|’‡BЉ!г t# zгэF W}H‹иxЌiE eчЖЫї ЁїJфІ‰=KЖTfАя‹уCіbљ˜жЌW`nьЭ}‚я“"iсаLьxмЯгZуђЦОZ=EХd/v šы№™„#QOхЩ*–фЃ^'?ŒšrKу-•Hu)ЕяШŠЂ!є§ЏЛW•gЬ љѕЌ“НЅ-ўнm4О‹CТу{ЪюЄц=BEu}[™gмЉ[hлж”ѓ ёЃтЏНОyњkТ Џџѓ+бœЉЧЌщ_пXвЈgЃу!255EЋž­ЪдB›Wјv™…Ъ9ЩŒ!зх‹с4lŸB‚1ФŒ ы+oрђВЋXgСI*,,ЄuЪФ7ЫјT\Z*йR›К6€Œжй66 Ÿ‡n&иЫ\lљ Ц–:XO™GIЬ– dсшЇС oS0Ž*й\%Фцњv>ƒ5Ј^ЇфYayФ{:сФєЪdMš†T;Ќ.Y<‹+8W/ŽХ•БЅn…БЅіr%ГБЅЎџœ˜ЖlЉт*і›і‚Ёƒ{ ŸцЩђeYЙvGр„Wбе›*3KВЅžЭ^RMLЦ?jH/Е“е|`kaMSdџO'WЕ–цgsFQaпy5!Цƒч\fpnлЮіЅЇЮŸsХ‡_У5Pc "І'чЖри\=шSа_#ї†ЈпLХk!ф?э–AТ‡ЩJK€;w’АsЧЮ ‹& %тЮ^BLd4Ђ‰О>>Y[їюX:ХЮŒУїч— wsaNšБЅў/УщšУJlЉЗИY .|ъ‡йЫлрWZ—gЫjтOђZƒD…­(э V ™†ЧЌФіmЏpыЅE`iŸёипќ=lЇЅ9.nњ‡ЏВ№CнВxWж­Я5 .Œ-•d)KHŒ- ЖT!Џє–q}h$ŽyU?YХšДќЂjуЁ[ƒцpЖQ‘Ќ1‚ФШДа*#nœю€Ю4Н'Niz/ўEњЮК5gїk‰ŒШиZrЁŒнЌqЈQгN›офвш•™Ѕ)\{ЈПЩVT“lš,yоBмлАТ”™р%bл§ћїу“ЙŸтмЙѓm‚Ћє-–LYŽeІрч3i4kж”XR›^­ае—ј€Јоž[ъи7НёЪ›]TmмТŽхДюы†^hDlЉ-zїЃsaИЧ{– ЩЮёл№3L}оо-ИЉ,–зmХи:МЧ|/рЏШ{пд-Ы–cqЅz WЂOЃЅиRЛQЧ–J[НSq%ЪвЛбšUАWsКЂtюЃЭD]сv-LЭ1Егp0Њq’бŠчVєGс ?Fq!у~д€[#/‹БSЕ@5&†Hа•Ѓ ZсrщЎ…–н[ТЪ–ћQf>ХgБ˜Ёэќ№™‡HHПс  ‡pTБ-›2›KkлŒэ(xx9‚D}2BЬ–Њо‹j:є"ФРe ёœЁ{Ou#‘хѕв^%ЄЁjWЗ,…gG`qхиRQŠ-ѕ"‰z[[ЊЊНЪ”Ѕ!КЖ2Cc_ќ)ew“rрХъМ`'К8ЪГЯfЧŒІЋпыј:ЌiY˜“ш/$s;KdН.G‚I*œшߘЊWЏŒь^Ё?ђ^€ь\цЎќ$K'dь^#2VFњЭ.Сœ@ ЦЉСЪџЂ=#‰5Ю bzhжЉ)вoe@š#…Г^шаЄвдНЏєь ˆ ’^Ш уR d4­БgO8ў~ћЎЭТЂBBОЉ›0њuFп:d>1#ЧZC*хЅSVРюCXаTуЄТKФlЋŸ*д’Чф—'K%…БЅG•БG„Ю`3fbK5D›hЌ{ЉЁ#Ї—™Ќм™ЛБйЎŸђИ&ь0шќиЏСš…=BСєЪD,КПЪOРЊШ ЏРG™mмс5РPБх%SГŠ{й\Ї6.O|Љѓ’S@ЦкМЭ­п%cKBlЯй /ƒˆ“єюe, к‹џŽ!ЊsтrеПЯаЌs r‚kКIПYјсшДаё„cШия—oEXј?шЖњglс)ъrYВ„2u(foЂЗOE и№цNѕц2BІq[+5Pё_jзЬмŒІЮZqЋЏВ@ъђxNєэЪѕrмў'џ;r '"NуBф%\Л‡фЄ;ШЭ–Р„8wь,ьё№ўCАВьУx–X`Е!‰=к%&#C`K%Цдf` b’Lь­хšKі`kа††рDlЄФЁ‘GЬЉхжTыj6;*O§Ж/вŠЭ<‹+cK§ЗцŽБЅ†[*o žŒ™Ÿžф‰гH<уЪЬHуЂ€˜œŒЌХЙђdQхb еЭ@zњ]вM&юн'юЃ\УЦШ†X“SO—Žjн‹LНFdŸrЕМšrР Есю}дКSbR‚ѓуLоUЕќч§@@ЦžпrК>WТb*EMћvь#N)лГ ўч2ЖШ`dЌœCЦž xХ#I‡p0)эШрсБУ)ы kZ#Б~˜З3Q2‡Œ š›‡ѕ‰‘ˆ):„ иŒгNъМЯђШи)ЂГДХФБeЩj>b9fR;ђ(„‡OByё/нЏ[ї,ЅbŸГiБkа EДф{чЪёDяЙ іIHHР[7q;11зЎсмљH=v{ї…cзЎ0Ќ[З‰dR(_PP€"ƒ "sАЩ-ўЃ1@С–ЪSї\ЯA›зF“Ÿ%ЃˆНѕП‘‚K[5>3/›ЁпзGБtжb^ѕC7›žф5чяђк&ЕхЙpeЩВEзљ“€х3б[СтЪГЅR@З‚-u‹п,иRil/"тњcхЭціOsаЏёЌŠ “$g€гlмЬЅ}JхЩ’ФэЃКёў‚x*Н#]ќМM“ЫˆUkџБ eУ ZОіVзЎЁih›—сrлbЮV9-ŽљCця8œyІ†іКњЛUmШX2„Z|ѕ!\о3Š#ˆИХ„ј{хMD-‹!dьN ьЎШ@Џ6ћЙ:ЙДаŠŒM!dЌЏЫX˜2ія2‘Б]M4БA2жШиƒz"cХВxdl‡ŒэЁDЦюТ‹„ŒэнJŒ§>Щz!cm8Љў1dlYВЌр9И;Z4`сfh§Š/~BЉ2dЕј—ѓ'б[ cdeЌа}Ю*œŸЈ-•фюЩЅвž36#f†ацЖ,YD@жq yŒfЅ:uЬа\]_№Ф™{*oСй{Ѓc р$вЅhч4KœмЗйPgjЂ,іУƒ§™Щ1Оѕ›ЪМчy‡!cгoЄ#ћЎ№‚ЃвFU!c™$N ›““_й ŸбŸœA<2Vb‹т'ХАw{ юn<2vХ&_|}~к0d,9rйњ[3D`.!cпиƒћЦШM№Д/!dьлXДќuBЦ~ŠмАeє2ЗnEŸЃ5=iŠœ&dьAlX‰ЏЛЕуБХiQ„Œ@З%Ы ›… Cћоk˜шkЇSŒнS^sА,И‡Œ§="–ЂБ3dlБыйоV‡"XќЄ†Ї–CЦъ/+zѓf$Ёzt`4ІкЎmехоIJѓUZЂРU[;ЬЊЌЄKЧjЊбcK­Ќ–+S–F7kХ!›6D<'‘ЖьMГfІ‡Ч’ргбЙƒlРІЭ„єуНп‘O’лВžы-CЦ^оEг‰*ЁR‘БєVГя“я8!<—˜—HHћляЧсCGјћ”Ш(ЮыЛ§-h5Ўv”У$6^;~У"jeШX;/ЫОЉ2ˆXbШXoШ<Шг9їŸЩЁY3аUŒ­пЛMА/$dьGhн‘ Љœ2Vˆз‘py]2vŽ7Щ`~ЧЕ8LШи‰hххкevє@Л†VИЉ@Ц‚VИGЪoзЊ>пњoлМ Квф^ХБњЩŠпЙц^ФмSd Њ^”0юд:  Ђr.йžєжeLF <ЅмъЛ€X?"тC–ŠJш§ѕСuєmбх)%WmuыD†•єУnГS›Џ СЂ&wн;BХ"|мa"ЬLTUл›š)НZБdqFаv^b/бoјсЉ‘БlЪьc=‘Б–4ёябСыˆДHнУТ& ўа…ŒЅчK!c)o€лHХЁ[–ТГЃ†Œ5/…ŒНDFвш !cЫ—Г&уfFрЋЈ ѕVїиёWШјП6jРhеЦЋfьs­гєvёBј?Ї•}gKyдtƒˆuЖМ)‚l§Б%џђх| ЫПwљВzЋцІЯЗQЄ†ŒmTйШиЩe#c)^hЯo {Š]Z.Јj‘Б% >С !k ЏˆhVm(Xmy†#cmpК@eœБ=fИЕr1дЫБeЫЪ8О‰3†ўѓOЖ}ОПїмЎ§S™уuhP5y(Fйš|uЊЖošф‡‰йЉHЫЫЌкF+IzkѓfјИёx8˜йЉIќпƒГјєЪЗ(,1 ЮNMBн8PCЦіЉMŠю .:qчуЁ‘дoѓѓ; Ѓ‡ЈšЏН‘EЖš^ƒškd[эœZтfцeЏЮ—ш-ОЪуšМуjљЗ ТwЖрQ?ѕЧњ{:# ГЃBвe6lЬ5 Еjђˆ*Зo•Œ=НчзСщ~3‘zvѕhˆМ "Ъ9-Š““Ы!cOцЫЯОР@ƒˆ!cMА•Б[E* І8ЁwлHлF5E№љSEA… e&$3Z ZuЬаЌ?c>цqШXЁЬќ˜Г„Ъb­žДх9)‘БКd2vСh, œ‰~_)ј’њП‹-+Ўу_„Œe‰у!RCЦо@М\;jцEО3'fb ‡,CЋCV~2щ*§ŸucНI9ЦTЋ5`4ˆ*xљМGV,іcОїRтй)H1МRФ„FqЯС№nfЈ[и№жЪЏ!ƒ$ǘЦŸІ/2фddЂимNЌUVs‰ЄR„ОSеаC#у,6'd]ѕЙНYpЕи bœDŒїЧ”ІдјTгЎЋJЃlЯХЊ1ОіќŸнZK g(O^ЪМ†—–уŸ9АЗPї") =;ЕU2іœˆKrEd7]O†ŒНT ЛE;2– #ѕDˆUЕ<†Œ§KЋ]–vdьЗe cOЋфR'ЪGЦъeя‰ЏфбјJ} ЦЃ:Ђу”йS\ШSM`ш'П yyyOбЊPU†иР…ИxGг!œЉЮ­,#л‚?C€‰zєоƒ ›z‰XгЩН‰“ЈŸ“/цmŒе=Œт  љ3;uF‡™ИІщЎ.GcЉ]Bp/ _|Ищ–юvЊрL—ЦАqeф"юQЂЈ%ХuMyЖзUдЁRЛMЌт[‚<ЗВsQ;їwv<>ИИ™R•їH­€ё Z4РБiT^[2–б„шŸšеVы‹Šў2„’КdqШX—†fuvv0ЈЏB;šлЪ”Ѕ)лx\35`4ˆ*сКь Гћˆ“xСXЖ/$Ц"[h‹ЌPSЫ– Ќ–ъЭj)TVбаяЌЦјZVimчЉTЉ^'?ŒšBgZjс}еVK3OŠ?&РЏХ8FNчуVвnуБёД ZЌ^ЃEŽ-1hв0ЪЎх!+UО,žЅv:ETВц8‰кЋ5Ь8‰д’]W‹šэМmhYk}>E{‡жj]џ'ї‚.,FZў#Е|уAѕiр7BЦLк_} [2j ŽhРh=х…d†ыђХp šРE‚!ФоІо’Ы=ћЗG[ьЛъ‹O/ZЃia"ЬEH}š—нХЦё“9VX/2`ЖЧ—Њ–И§ ЕќDтؘ,,Џ!C\и&ђтtцeŒ'Ц€g|ЅdЧŽ ќ/ЧyZВpєг`E[LГSІY’У1Э’ЫмЕ;'МŠЎо~Д^‰FЗˆd‰IўИСЏНh—-Л Ÿаtќм9сL"lлПŠэKмБю?чUKˆE›7ХаЉўє›Ж$Ф‹(щ#Ћiџ!:ИкQ—5SоpŒєяУ“рŽI7;ШpdКŸДє MыХ!„МSмЕXzRфг>>ЦЏ"–Гyє*Еf#“c1їЫcJ9ЬЦ-Є5ЃЖ члП)"*ЌФ§л•з2„KєЄ@H{8ѕ|ѕлxУћq= ДН‚f–ъё2Л@г?_КŒЧКPW|ѓ;F§€^*2ЁnAЮUФЇЋxbŠsoттё{МAQpзУ}лЯ8‘Д[Іtр\Ъ<у+Iї9BЃFСХFFьАДdЧђ6Ф4{[VГ‰i6Q!Ж(э 1ЭNУуVbћЖW8ІYЁ§b У„ЯЗF‹)ОpДeцЁnйвЩtО<›ЋFЏŽ-аТлнН™E3•6’ЎƒŸxсЭ•є2œк ћ+ДЖUЗueŒЏdŠ(_Šo;,­kЏ`šmALГДМ,1ЭђžBzюњmј ІО oяхЯг[ЗРФдя–дЧbЋC6!UX2ЭхgпЅЁџмi§ў=Ѕ,+З~˜Г ŸвиуЦМm7–Яш‹юУ}Щl#ћqїя˜3Ё;КПэOЧёИ–HŠ)k|TG,ЧwxXў~EЉѕРzМV–BŠЦ…"=ї…ї`|В\YпžУ§bЂ М>@‡жАzС }ЈќоПю)$БыєŽэ›@зиNЄЯ"цѕ‹Йƒд;xѕї†ГЕЂh%nЌЭ,ё5!Ьњ7с>‚шЬТlLЃ˜Ђый B–qћŒ5аЌ‰м\m`nЫ[Ц^žѕрdo їЖљ˜S|ЃЙ)}[bУv‡0&Ѓž/  ЂJИоЬъђФТtY+rˆ”єэ+)ŸќЉ'ЦУˆЩаєН`8ІФщп*ї€їCЖhЁAI…Е'>џ€МџЦ Ь[sAсyQxIЦW’Я|4Ф4; Бљ,ф[Txb iJL“iж.щ”MDrДd,-= Lў6ЬCD>ƒпS+SыГ"x˜:УДъТЌH.ёНуЭ9=t'’cs :ДEЫбSaf­|zщз2ї€@RZйЗц\Й%ЫЇ kC)Ћ+wЌšuЇХ†Ѓp,j%К…ЏЧЧл 0Ц•Rєл151ХЇ/NС(зСjђeRЬЙњ Ю=bжœ1=K <Ш,BFžХ2ВŒ(M(ТLЌп,ЧьЯ,p)СrШrДм*ЉуqЋ№ЊзnEœ^9B•ˆвЎшІ Q*Њ.‰ WФ> 1s1Ш/Œ‹—уvЅЃЗ0ˆЈ#„[Іfgv,Х…YшцфG/Ѕ}0иo;RДмnXїъЦxŸ™ЂЕ6l4ˆДЊEПЬыхZYdхrdє6/ЫyH‚d0ЩЁXКС=H‚,;rS§еnлЁ–jіЬŸw?9ї›QЊƒмofСq*“ŠKЇcЦЗT„–тђ Rqцp2‹эрцѓЂz]ђ€\| `|ЕїРјY4IfгlБ™HOЇ)Ў˜LмЛŸEФ%pALjВјт4к‰R8uh‡ю”Љђ;i)^ Yl‰’YэпСФ6#дЄ1&ы…qыq23J-пxPН86KQ"сЃЉ928ДЉыYЭ`ђB3XZ™!хФЌпVRek6lBЖїy2ЫjJ@”т -1ЅЮTHeмБ&ю(NP ф‘$Š›л5”Мо MыЇŽІЕА ВѕЩјг)ЌЪOШЁ;тЙ›4п\ЦсMš›‡ѕ‰‘є{А3Ідс)Њ]у­r…VBњ?™+ЁБК$"zЯeАOBBnмК‰л‰dЈ\Л†sч#!/‘#?3y7Џ ?љ&Lˆў{{фнŠ…фЦbš5@жю˜З~спb”KZkVG0C jpsWПЗШЫJe†`Ц]?,]ТЂ],1DOp`ШhєГ!žЏyш6o%ќк3O1ОЮŸ,Ÿ‰оA„JbLГGБtжŽiЖ›MO ђѓwљЗEajˆЕ-$Iм>єk<я/ˆЇ,6•у‡рmЗјгXћЭиqcдЦ= IDAT6‘M•%л зяХПC0€\НiЊnи†Ÿ№Ž/П€d1-ˆz—%Qм9(H|>Mщљћo%ЙёО'MНz@в*[ыиэŸцPŸG`йlьœfуІb*Iz7Г§#!€КдЧlЮM™QДУ%цу!ђeEC‰/Ї‘%qбT“Є%Oˆ“(…,BаЕМŠ‘{Ђд‡њЯС‘™9C6Ўяьй§ЖŒ6ОмїaУŸќї›аk(ОУЫИ{ќIN›7АЮkfŽіšЋвэї@Ьh7V­ Н(ЌМ§#ўЬŠTЫ7TЃшŽoaGџw~G d'eaщє4,š|+ІнСO?ТбA1ЇVЁЎIpЁ3_Р6ПžœзFŒ”ЬЙrлУnr/9‘aIˆШ?b/4єхџcj –HZЂ”[CMмХ:RєЂФ†U.nЮpjцŒІЎM‰“ШVІЭтаД=84-f лigџФ'&о\CЖЧ) ir4!IЛ—ъЛ4сOLъПGУvrчЖ Ašp’8бVтЬid1АŒлчtŸ9ˆy>>˜zˆrюн‚НЋ+gYY˜Ѓ(ѓВnХ#WЮоNєOЖэћb5M{HrЅ0ГА‚•‚ŒьџbШИR$лŽCVд—М3єаlРЂuЦР_8IFеrЊПˆъЫШчbkЏšŽ)Эјъ џU›Е3Э^UЕ'ˆЖэ8†ІжЦ‡ълzžиCS;ЪdЎ[6ь[cЦеHL ЏHБЙ­SЕ]GjC9ZTвє!’Ћl@БS†,VЂ,–Z;я д– ˜sХcжl—bГдњQЦјtЩ)‰msїџФйћё˜јП(šг5* ‡\њќѕT{›ў|—ѓФ1в:nЅ:э>ubІЊЪ1ƒзџЇ+x}3нjiJ•U]yqЙЊйнjlЭlАтњVzр•ЪЖ›RУуњ9шнS}Uг#ЃTŠВЉg.ˆH[ŠzXPDHP‘›ЂдTœ…Ѕ"А’scэХnфŠ_WѕBСУ\ћН –‘Чвw(&[‹E^+р^є%ъэ[ƒ›šуЇ•njН)”Ђ|†bэGеЗК„bЏќ|;њљРn/{‚GгюЧ)"]м‰аДМБWˆЬ >Ю џƒoьСGПС#7Сг" +ZMFђŠ58vЈ1Œ}СѓјОЫ$„фŒХхˆnXњЧFxЕАƒŒМЬ1ЁˆшCЫ›ш-Ћ+†oп‚ЎbќЊ№pnЋтtмŒШ‡хpеeEфхПˆ[IxЖЊуЕCZ5юgЕg4ˆЊ@ѓyыNТюС?oYŒœИ›Ь…€œПc!/”сœe{,<ž†НЗkЦ1П–Y ‡КJ˜qDmg9ЦWьсYUIЗl+883ЯUeЄЪ”eXtЏДЖ”‡и К’v E^#У…nђжt=uЁТˆ=XїЕVo‡gєUЯЋЎ#џ§acf%ц!вЎЧтБeEFЉ?ј„ѓЦmiРD s•qaZB†хUv*М]Ь!%чМй”=oУ МDHЩЏ{qЧ&&‚їкC7oУпЁч“†ќ˜K˜іg<ѕyА*PЌтО—P,bШœхhI†wJl;ќ˜ѓ<94­n*аДЌМDQi)­зцяэ™Ё>чсrydЏ K_mC/ ц№ђ"Bw$SЬS/ЅoxХ?kiЅ{ў^EД[\šOВ еЎo{z1N†GЯŽ№dПsђнЃuвкЕЊЯ ЄџЖЭл +•ЪdоёZ0^eЧkщŽб ЊЂ —Gh|ўЌŽџØS5i…ТЗІУЫЪ{ПЉЂFbk<Д€“Е2 ј)ƒBz@]|pЏ4яTыЦЂЋУ›ОLˆK Ь§Er•'т…№и4[с;вUл˜_™јюGS\ЛƒfНx#ШЯу.Ќ;ћА’›$зDJpHIBjЖeнwGh`šПЙш|ЋгЌYъиœLьџ^иЬЪГ MKуЁiй)KјСЃ?-ЏцRЌХ7пgˆRBЫqЏ+!VЏЙ‹њ‹Ы{Щ@Y2СыХЖжфYБЎдЪ…ЄЧд.oHJc)X€ˆ3ел:VуЦ+tЌ–nQ_8iџЗі1&ЃДh€!3/бb”вй{БuЪ bуъйЈ3Оzi>ЛЖ%ьqЩЇ f7aгтžТ…уЖ*5аАО§_VщПЏДЪš#%хФ_aЧ!%С†F"ЯШїМЯќюў…8;ўе=д4ЩЧWВЈМ).&I0FФ]"Њœ§CцnxkиfЬГЄ­žЖƒб /ЬЇђŽ…r5ak4ˆЪЙ цDŸ\"ќ6Ы)kXєў3œИо#ЛˆѕоŸяНЗў‰ЧмmСzзбЗ Œ =№[:zNъ ч8yЩјzrŠЭрфь :ЉX IБ9l(8БЪ’%ЫЭA6БT›S,ƒ'Ў_зїЯмСз)‡йtБЌOи”кГHы} ‹7вƒШ“'O†““aOєvvvАВ"Д#}ЬЬh2Ѓœ>jЛoќ“™ŒЏг~B–\:›†zРš‚ЦЉђ5РМCі[У”bГЯпРюѓvœЗHŸ<§{#СЏWыI%ђU UQRFЈM)CйjЙ?ioOFоЁ< zbužіћЈ[–”аПЌ -Ъњ"!žЕ<Кыъ}яе2€g;^-ЊФЌŽш„E‹aётХ•rКVЃЕ3К8є!^ ?єІeE–lŒЎkZЃбZwш§B;Xˆ8‰Qѕ 2ъjjbс„щv#с$ЗWb|ж]ќчт/xRXу(„ењY[Окaƒм+‰œ1ф9‘чЄв7Я1Цу‘„єђU=Ш9•Y–G[Њ њхЫ&do‡J0†XKКeYйЋCЌД­sтPвѓE”Uа’žэxЕtЈdеПDII ЂvFЃH пгЂ<ыњж№еYЫУВі…ёюZa1VV›­C&Nlеz–ž<ЩCЁ”w-‹ЯыоЇœvh7iUz)ЗЬƒ5- ЄьќУvљртО!єžB‰[ЇьйВЅє‚X\}q|Ш^,гšscџkю|Ÿ‰^.™иёЙŸЇЕЦх}ЕzŠŠЩ^ь4жс3 GЂžЪ“е|Ф&ќЊZ40Gтўѕdэг:joDЁW3Cn\ъmжЦ#ђˆј4i‡ѓЉз”нgСеž [)ыкNS{МS<kГУPмHѕn–œѓ__и‰рnЃPпJ5­QзЦџ,ЦгЖ­)чтлОЧmєЭгППVx§Ÿ_ЦъгЂњз7–4jрйh@uz6э+[5Ѕх,ZѕlЅ<жЖгцў­эœОyЬr]О.AРі…YY}f]_y——]Х:ЛNda!-0*SёЇшг[яЪЩЅЅ’-ЕЉkШhacУMCLб&иЫ\Œ]˜БЅЮуƒ5Шеi'ёЛВ“FЄ[MсхMH"ЏVшъы‰І T7Ц–:іMoМђІ(№›њмБœ6па ˆ-ЕEя~дŸ0\Šу’BВsќ6ќŒS_…Зw n*‹хu[ёЖЮяСУ1п ј+’мтeШВхX\Љž‚ХеяЉF)Ждn”ЧБЅвVяTЌПЌј+1aюEЬ=Е€XjѕnЁN4eœDЭдНDlкьyH%RкЦйЁ“Г›кpKŸаєймЩЁпPMF$kНАЦaе: д˜"As6Ž6hA†CЪЅЛBZvo +[>юG™љ;œQФb†ЖѓУт…˜Шп№h‘ЅЇJlЪl.­m3ЖЃртХsыЋ38‰йRХљl%*šЪ zAЂ|*™xЮаНЇК‘ШђњiЏ*мPЕЋ[–ТГ#АИrlЉ(Х–z‘DН­ƒ-UеŠЦžžВbжcмЬ|ЁšLh"ыњaf/трэГЪaўѓј.'Q#лњЪМККc*7С”Ю#АэяƒИz]9Ь'Eљh§3‡>sг 'PЊ;ЏŒь^Ё^|фНй„ДЌŠ$K'$ыоš‹dec–хвK^5ЏГWК6ЪЌ§ЈqSiГNM‘~+в)ьœэ№B‡&•ІщРш…xЅgo@ldєB—J +‘aЯžpќ§і/\›…E…„|S7aєыŒОuШ|bFŽЕ†TЪKЇЌ€н‡А  ЉЦI…—ˆ иV?UЈ%Щ/O–J cKŽ*c(К‡Э˜Uˆ-Е|YЧ7qЦаў‰ЂЕT^3UžЏН&vNpЋпЬвйћБxгэсАNoЭ(–№НŽЏУкЬЇю^QŽ5Ÿ~Ÿп^њяwy /6Њx,!CБ–—LЭ4\дхUwкXtЄпЎфTЌ6o“ПXuaK8lЯй / яЊєюe, к‹џŽ!jsњѕЎŠJЩрбo~С?тtL­}ЏЂ–bаЉi™бJпmzЗBмЁ›`дхёœшЦ‰ыхИн љФћ`ii [[иеГC=тUЉGќ*цдЎ­5і№ўCАВ,ЙYф‚V’X бЃФdd8дЇ X>шЧбЅ‘в™˜$$гŠюЮЬgSFВїРјYРŒРє‰Y€—н­ŸŒтц„\F=S\HjyВШГt‘VlЮ)і€ЁzЬјŸ Ѓ##1а%иRC€YыxЖT о><lЦ!dY_-Ч8†ђŠsў/&'#Ы…e4kхШ*NФЖыЉЧуаЄштЂЩ #у­QЯšuѓжаiUіtyIЭ :wџоhлЛв~UнџЇ•ЯІЧН8 yw„ŽBbыМ­У”Nўшв„…п–ЊЩК›яБQ(SЪі,х>лi1џ!3$k‘СHVЙN$k!YS"Y-(Ё& Y’ѕ%’•h—Qфиƒ& Т™™Xp+к™ЈщЧx`д@uk тЏBUмгєдo?ШіЮЬМxњНч2и'!!7nнФэФDФ\Л†sч#qєиqьнŽ]ЛТАnн<$’IЁ|AAŠ 2ˆЬСfЊЖјЦ[*cLнs=m^M~–PŒjмџ\фЊё™Y0WŒpl†~_ХвYOˆyенlzbзhœПЫSh›@д–чТБ}•%Ы]чO–ЯDo‹+Я–Jн Жд-~ГpP`KЅ>NМˆˆы•яЇЗšCЊ ЩJЦP‹Џ>„ЫћЏcэ3CH0†˜єїЪ›ˆZCHжми W‘^hіѓrЂ—,ЇfЮhък”>*$k !Y}EHVЦšЬЌŸ˜xsшS]HжЎšHж Щъ‹ $ыA=‘ЌbY<’5‹CВі0љ‚_–ƒаЋCЇњcаk]јЕС ОšЦ F TОjЄ‡HІ“Ћ“А[iлЕЋ ’%e1sыUЛќ h­аЋ‹"!!Ю9FЦeF$ѕ1ђeIЋіўtLѓUB2w†џЊЭМ„Іђ(ЯJ4ЯxU5РЗ…zПх jВZ|ˆЫљ“,ЎLšКЯY…ѓЕБЅ’м}"ЙTкsЦfФЬр{QњВь=БœtEБуЦ$в€­…чЧбАiГі еcЦDUъьюАЖ=9Oб/7ўTŽQNоgT +„_KoeО>; Щš~#йw…U­ЊBВ ž Ё%†dЭЩЩЦЏПь† Й†mйь‡d•иЂјI1ьн^‚Лd]БЩ_Ÿ†6 ЩJ3ЏlНЌ"0—ЌƒoьСG„d}cф&/”’ѕm,Zў:!Y?Enи2zљZЗЂЯбšž EN’ѕ 6ЌФзнкqHжтД(BВF л’х„dЭТ„!„d}я5LєЕг)‹GВюЧ)Џ9Xм .6*Oк*ѓ†ЉРXкЈJз@6ˆ*}Дx') ЬKTi‰Іl œЫg†Pe%]В8VSF[jeЕ\™В4КY''‘и Кœv RЯBЂїзцЌ“*PЊПЋ-хa‰џ>DІ?•ЭNўw,Жhh›—•eѕйaHжЫЛЎВeЫ•ЉR‘ЌєВя“я8йТ”™р!b™ћляЧсCGјћJ "&чЗ еИкQ“иxэј ˆX•!YэМx$+ƒtHШ b‰!Y§Н ѓИMˆ#|&‡>Э@W’Е~я~4!ОЌЁuG2ЄrJHVOО<ey]’u3D%˜пq-’ub'ZЉcЙvY=аЎЁn*Ќ aЦQ5NFƒЈœKВчНХ“QеЌіNЎK3ƒГ$%NЂЈД›а$oЌцn=ГциИ™QДљъ~Аi3!э‹?ХE#=њ YхnЋЩJFgmчЛ#і§†žЩЪІЬ>жЩjIѕ n/MŒ ЩљC’•Vˆ/…dЅМb$Ћˆa\З,†d%CV@Вђ*1ў7j ЦiРhеИKbьQDХХ8‰Шјуі9Ѕ:'бѓj1%xгв&гiсзя/џ`-Є#‰‘ЃїZ ]_†’ЕQe#Y'—dЅxЁ=П1$ы)nв*FВ–0ИC$жЊЉ*Ўa=аЇкPЋкђ CВ WŽёг+њdЁб7UуžQеІT]mЈц†ŒЌДеЌ№Zму$Ї[Y)xєœ/eС ї3ЛŽттŠФК9I %џ{€h3Tо#ёyЭ}ЩЪžЧmњT’5yc:nџ“Œџ9†Їq!ђЎ]‹CrвфfK`RLHVK{ЩЪЪВOnnЎР ЂэЁ=dHжфTЄ$ЄpŸ6ГOHжМЩЊхkŽ^qLшгwf9a?!YOФfAJЋСЇЦЦ!%Ћмšj9 nyВШГ”“ЪЌ‚lrhEїћ‰ЉœЌЬЄ df”ŽыRkШx`д@kРш!ЊbkŠ7ВвjjФxЌK/и5Dлњ.Hx|OY„y‰оp#­ч8Й9уGноЦъKЛРH…IdŽljqrЇ7еPzТyЭme#YOяЙР51нo&ВГГ‰ЮЃ…)‘gFЎŠ{’“С–““Ы!YOцЫЯОР@ƒˆ!YMА•Ќ[Eƒ І8ЁwЩкHжF5E№љSEA€ e&$3ZPZuЬаЇ?c>цqHVЁЬќ˜ГЕ‹Vг$б–чЄDВъ’EHжЃБ4p&њ}ЅрKВИљGQИ7oРОOо=g Ко{u Д/о$єЮИ5j ъ4`4ˆ*Ј[я‘]*TsОїRфT +­1a‡Qмs0М›Б№ЩgdфSРјгє…Н5fЂимNм‚ЏхI7ЫmYВЈЏY94Э"ўlРq)•пRu•PПЎ=›НЄfgœDЯЙAФЎ„ЋУ јИћЌ"ВF!ЮŠх_ЁqзF…с"pд'Ні"YЃЪ@Вž!YqIЎФš‚!Y/•BВnбŽd%УH=ТT-!Yџв@Вj—UЩъŽеђhuёЦ#ЃžБŒSfOq:L5ЁŸќ‚|фхх=EЋBUbттž—HШ­ю­,#л‚?C€‰zєоƒ ;Н БІ“z7ˆ~NΘЗ1VїPЫmШw˜йЉ3К8ЬФ5a*NeШ’&œфћъфGмIФяd2DѓlHbЯn_q]SјыъѓB{˜›ЊМй‚ЇЯ#'‘ЖыбД^#Ьщ>lеNЧe&улЈ]U":T­…Ъ=`HжД*O(‡deДњ'†>Ебzш_ГtI]В8$ЋЕ!Н*-л˜cд@UjРhU‚vї…Y‚}ФIМ`,лcЅ-4ˆ•VЈЉeKаX"м~Š$Хбё1ogb…eЉRНN~5…D4ДDХ\ŽRќ1yЖx-Ц1т%:З’жpЇu*Ыэ0jДБмŠSйВЬmœ0§иnœ/ŠBL­Ÿ6х">™xЈт†œИщЪкЇEy--xMкZXЃKc5Щlкܘx А5оцјŽCSš^'6ЭИ’ж?Ы-Ќљ$ŸП’ѕ`в~qїћF 5№ 4`4ˆžRщЬr]О.A8ЃH0„и{а[CђqЙg?т i‹}W}ёщEk4-L„Йм0ЏŽŒHљ6ŽŸЬБЬz™Г=ОTЏЗЁ–ŸHЋЧO >Id‹,ЩЖ‰<#yуУ‰AрdiйБ#(Ÿ1ШВВY8њiАЂ­`|>ќ1U`Ў%9s-ХpКvGр„Wбелж+aѕEЉ KL№Ч сЁЄ]Жьў%|Jє(s(Ž€ЊлЖл—ИcнЮ+њ/’ЩvE,ЗP,˜+”(O–­&пЏП;li™˜7@Ч—Љп1hщ^BоpŒєяУccЦюгбиA†#г§ЄЅghZ/!фтЎХв“"cJћј_‹!r˜[HkPmЮЗqlЧCaxм6ъо5Xћpэ‡'MSхЏљN„‡Аы71t=% gАЄ?/ЧЫф3Х5VWыъS ёЧф)bгhтt77!‘;U |‡ХgkЧ~R’oћЩА?œПЪoї/Цш%=HŽбЏ•`Э:SЄоWХ(еŽQ{iд@Эд€б Њфыт:A‚ЮoKвпŸ%zR`Ѕ=œzОƒњmМс§Ик^A3Kž[FЏІiњчK—ёXъŠяc~ЧСЈ0ТЋ~ЉЊ9WŸЎ‚"чоФХуїxƒЂр66Ў‡ћЖŸq"i7ЖLщРЙгyY5юs„F"YБЭв2ЫлsэQl!RяйФ\›Ј[”v˜kЇсё+Б}л+s­а‘b У„ЯЗF‹)ОpДeцЁnйвЩtО<›Ћr˜ƒœˆ~sоlЪѕс“ѕ'0k_\оVѕ+г$ V/єDЪкћз=Œ%bў;ёŽэ›Рyкˆ EЬы—xЉ9~№юя­PїиbА3}ўп_й‹kI‰Š”IЂ ;Lp}{цƒдž$ERАeSjRjжФ nЎ60Зe–l1М<ыA’W„&M%И’b‚МЁЧHзX*Є)1MцZўŒ~џuЪ&b:Z2––2Pнаm˜‡ˆzg№{Џ>ВŠSБ‘тž–&~€№œЯсЮH]t$nЬ>.ќYъ гЊ Г"ЙФїN№нш•5Dг†ss•—ЪмО!KтZўнЩMХkоХЪpW~5Шѓшх$ђмYaРzš*йŠ n}р5|™T‡“Ѕ™ІuЩ‘8Ї™S˜‡Џ/юDbvЊ8[ЙŸDљKЯўР<*3kТŽœШ ЭLˆЈ“яL*-qс1Z̘ŽaƒSсы™ Л–єВUѓ\ ЊњE?2eщqпxпžЎ]CjWцx iзXЖђ4`4ˆžR—б БЦњ(ТƒТ•kЙ%,› ёлбЈoШRяЃ C[Д=fжЪЇ—~-sј$Ѕ•}kaЮ•[RСѓ$ХНфЌjЂѕ›S(ˆјMuб4ЯЬ)8|CЫd>щT%`ї!ZdіŠђшЭѕ|вЪRЫ`BaёЖ йЖ­лУёˆW ЋXЕєЋдЏЦJЯX”АЏ№sAU]О, $ŸFž!ЬТБЋSаК cHhG‰н‰ЮSc@ФФ3лsиИб zŠ‹~}Ѓ\++­\.ƒ,?nRIК &9 C7ЌЂIeg@nЊПкm;tУRЭžљтюч ч~"bb3Jѕš{D/8NeRqbщtЬј–Šа, —_Š3‡уYl7Ÿеы’зчтƒЌНЦЯТ aЎ-–УlвгiŠ+&їюgЯ’ТxЃ›Х™G)ˆzQ–ь/bъ8`Х’}`#Ы‰Чћдџрщн9ƒHњЯ Ь0љ—(8Л –лђdн8Œй›hšplk<ЙИш8ФХІ*пd‹щMєшўИ2c—дЈ8*k|Z+шЮd1D+цџŒј $PП{"‡K:Ѓ-х!Ngя§Э}тtХЧЇбў3HЬТЉC;tЇЪ*П“XRнл751ХЛ/Aџ–>jƒ“Ъ 9у'&#ЫO—daеХ_‘Ї€шџ/‰МЇDюXSвљГйиzZŠ џ›JЭ‘СЁM}\Яj“šСвЪ )'ю`§6§К+2ЎfУ d{o‘чБ,)tGi!ZŒЗt­B*уŽ5ДHя ŠY<’DqnЛ†в‚в §ъЇŽ~ЕА ВѕЩј+-ЅКrd ‡а€ ёмMUhUџёжkэ‡Ž-ЋЕPзИ­iаџЩ\гzўŒћНч2и'!!7nнФэD2TЎ]УЙѓ‘—Ш‘Ÿ™ŽМ›WŸ|&Дх ііШЛ Щ+Ф\k@ч­н1?n5ќТПХ(—>шэ2Ћ#˜ЁЅцЋп[фe Ѕ2C0у.M-aб.Šœ'80d4њйЯзЃ1j\„ђэWz7Г§im,Ўe…%Nцм”E;)3™_Œ‡Ш—5>Cф@Š[ђРUŒlм=( >дŽ|м]_№„Й‰Ъsє8‰† š‚ ђпnBЏЁј‰!Cтюi№'9]lоР:Џq˜9кCйїКОУж5{лѓU kгSmЈХ%2n=Дˆфh2†~A6MЇ ‰1_ŸМsY8|і[КC[иб?ХкЦбйIYX:= ‹&пХŠiw№г…ptPЬЉUЈЧdhЪуАЭЏ'ч­ П)ŠAЮ•иv“{IШ‰ УHЦнЅDŸц‚2KфЋЪ­Ё&ю‡:)zБaУЊ7g85sFSзІpvЖU _Г8єk§Ъп0Уvкй?ё‰‰7зЧэqЪ)]ЫNнKѕ]š№'&ѕ_‰Ѓa;Йsл€РИШfvZ‰3Ї ХР-nŸг}с цљј `ъ!о“eРxЅnbћв?щХ”)Ѕl‹еfмЏ> ЈюьезfjimAБ4’щД§0y|9їnСое•3€ЌˆWІ(ѓВnХ#WЮоvєOЖэћЋk1AKaFAŸV rГџ‹!уJ‘l;AXQ_ђЮcЈ›тс$UЫЉў"Њ/#Ÿ‹­НъЁZšAжўЋ6kgЎНЊjOmлq MлŒеЗѕ<Б‡Іо”Щ\ЗlиЗЦŒЋ‘˜@^‘bs[5ІjЛŽўд†r4ДH%cЙЩU6 и)C–mGrYЫ4k(эМ'аyс˜xХcжl—bГдњQЦј ‘ѓжџЂШhhmЉš"рЏ'ы“5:7qЧЅ7„bвŽ`МчхЮЛO]…˜ЉЪSДc џŸЎрѕЭ0D#ЬS]yqЙКНяяў ЌЭ-Бчж х@eє’ђѓЃЪcёѓљЕє†…йГП=šPќM=Z• "’У–b…rSЭM!ю~…і‹гЂАt@6ВqюcЌВС\ёыЊ^(xƒkП7BС2ђ0њХЄqkБШkм‹ОDН}kА`SsќДвM­]i‘ђG$ЪgЈгpДQ} K(v№ЪŸбШЗЃЏ;lріВ'xєы~œЂЅ<–w"є+oьвB3ЈsУРр{№бФo№ЦШM№ДHТŠV“‘Мb ŽjŒcпE№<Оя2ђ^ŒХхˆnXњЧFxЕАƒŒ<т1ЁˆшCЫ›ш-Ћ+†oп‚ЎbќЊ№pnЄ6ЏЯx‹ђяуЏ1ј—тв•Ѕs•†Dъ3юVЙž§/ОЪ‡X§ ф­; Лџ@Оe1rтn2rўŽ…МP†s–эБ№xім-3ŽIЖЬjdH84аUТŒ{ j;Ы1Шjœ`ЯЊJКe[ССйР+ЌLY:бzBїјД/•Щх’5]O їzOтQDWвoЂP6,˜XWт‚u}>ђЕіх„нq§HЙZ€}ъю pэњь•C ц*уТД„žІ”WйЉ№vБВqо†x7шюн‹kЪФD№6лbшцmј;4у|вs гўŒ€ЇН*1ъT1€Š ™Г-щЊЄФЖУ9_Р“CПZсІ€~ЅВІv)­зцOˆJ™Чm".;ТIс‘И2,}Е Н0šУcШ‹н‘L^_JuХ?k1А-o‘(HСч“Ќ@dЕылž^d“сбГ#<5~—ŠсЈo4ЦkЂv~ЉeщМ…ёЩЌЎЫj:2ЊНŠїН1}ўЌŽџØS5i…ТЗІУЫЪ{ПЉЂFbыМ:4jEћv`m– (&&:эz4гˆ Ћѓš0|€}ZtІePLБ§яCхV>’ VоТєйо"ПћбWую Y/ођѓИ ыќДoЙƒ0 ›джD6р&ВШCiЃ)ЧК5&юŽаР04s1& аљІYГдБ9YќїТf ƒЁ_iМ"є+Ћh ?xtрЇбе<2ф^Ђ4пgЗeџZŽ{]9БЭъ5wQбby/(K&xНижZPйэ;eщМ…`эRЙOЃgћkšžз’КвўDУ>Цdд@%h€ Пьђи[Hl)ЃA$hCї–ХEІЦщ. :УŒ=s7§ZvхVџnУњrє™=:љдЧЗъаdbdЃœx"ьШXiJцЧBуТ–bОф}мwї/Фси№яЈюQІI>ОДХгBГ\L’6cЄ(<7юј!s7М5l3цYвVO[зNYВ(ўХ1Aۘ*:^]:ЦlмVЏ eЉоžеж„ЦЦ™,xз˜ŒЈxYУt“3­ЭЫST‡VK(fhгеpФ=JвЛЙУ‰џЯоЕРEUьџ/яїSAA1СBEѓQвKЭJKИfъ§k–z{hжMГK-ЫКЗєоЪ,ЫђQ&ІVІ]Kдв4RTT$DDфЕАРТџї;Ыьž]ихЁ gќ,gЮœ™пЬљwі{f~}`u=Sr’Б§‹ЅЯЮZхsЫ,З}|)ГlŒŸє+^ПЕкСЇ\Y€Э˜†]/рЗЊ§јз”6x#т #ЖёъА•[V‹dЂKЉYШJЯBЦ™ dЄчhЅ/WЂ ЋкњUоН‰<[тУМіR<2ђШ23/ЉI–[Š’ьКd9ЗЄ•ЋьлKВ+Фџ ЫюW>|ѓ1—ЗRђЭ‰€BˆъAз–м'WŠяz=u•Ы зWt–љ$тџžl‚Џ$гTUUaeђ8’jКB-Ѕьсњї ззљSJсмЉ#\Луƒ—ЕЋCц–еr[І‹ Њˆ@ш-wŒ|яЭŠЊЎы [ мЬ)gлrЬ^о‹~~ŒМzEч’OƒŸ0ч…_ДDВН[В­ЈЖ ’ещЌjЋS–fOЋ7Љdб:C;ЧˆЎтсЮoтTЁњФХЩЗf`ˆd§Ъuй"m:ЕЩ†жъЮЩи!.ѕ?шБќMŒ№&ЫLя{ёЬŒ§: 4]=б˜ŽЦeКѓКdљїРмёxяюqяuZН&‹юзЈп:1— VЩ^3nš-ГШб [њžЙ€,ЗДБЂšњЉh(HшпfcРф;сгBŸ{_ХMjддЯЛ)хБr5{W‰ИGЇЪQ†Р7'~СОЌcВѓГ[ЯўЦкЦпaцK7ЏІ кГv$Uмгњњц–щ[д+Ѓ™'—М…qёДтЁГTеЖ ™і>ЖMгц]†=‹Dљ "щЭЊ:Ј.Yb&ъЯх9ЩъєАЎФйиzTw…21ЯтpЩd"YdЫ ЬсБ8XЋЋса}$ы-OЛФ[U—GКuNмІZgШЈ p6*Ћq^›,x!vе.<є!SъCъС‚ћu1ъЗ.Ьu7ЊdЎ)-ъgИRSПs1k›†/jѕ˜jљ~ЖjЗ ХХZVГž ћкpŠ•тщыїХъ‚OaЄ(ЇЮ8ŒЙг6bѕcDˆŒЎщл^‡-moџїзјaЭ 2O5=іы0*ЅK}лwЧК?ƒЭЧ9БƒСгyчбе(ИЉЌЩM›•,ЬШ]ХюŒЃ:etsСИL>Аі™2іzmnћЦж{k^—&‰ ›Ф>Є2an™%}—%W PE?єЖюuXЊZ"БёuMYПж-•,qНДJзuз3чjэВм ДЭ‘fЊNKФмд8oІВCˆ*++qhm"Ъ…ѓ=OСбг‘cn5qХВЂMёкх_Œ•[s2yтЈѕœŠŠŠQІЖD‘БЙдющ­ыKQщеR˜GxсЩXЛ#Ощ›Њƒ‰JqЪЎЏїUК}B?ьО‹ ’ю™§[—{tТаЩ#0C%ŒQ}]9\o\(Кћ­О!8tщЄn(Ќ\­"КŒЇЃъ:ї“ƒЦDТ+ТsœЙšЉЛ^_цGZ%ъяп“т‰YўBUŸьњЎ[c§>­“!Nц–е'[нœ^јŠ~єW”\s! `о\Ш6FnУ—[гЋ‰ЖжД$нy@gWєE]‹l}™Ѕ9&C‹^GРД‰рМШЪr˜їПyИ$HЂЫЪ(РЈF(а™з[UѓшЄѓОъш Хэ1.иLžЂ­bБ>YKИиЛ0{_Cš9žмћ*‡э/Я”Ъ#ЌfbЛЮ;ЌŠМУО‚5лі`i/jзk-97ц2ђ6ћk26“чX–5yj<ВЊНЭж&+uх;xa5$ЏА’WXМЬћ*QBѓnZЉuЭ0^Е`rTЎЉіњvЭGгђ;фgQ~=0ЛпxЬН}y}€НfѕМњvРLыД–‚ЉкР'8ˆVЉw€Іаiž2ѓцСЕqR[ !тл№ n І—<л†ДЇПGуюжDk&AтУ—/e_Ф_Ук5kMд6ЏˆUџRіDвўD$’;ќдtœCЂА`J]іЭЧ bй•НЏў=ЩcъвЗG`5y_=E{јэ—ЃёТЂ.XGq~>]BёЬ"–"­њїЎќвМ=ќi\}ъ] и:XŠ3T~) ю˜€я:<Ž•[gсРђ…иv”ѕŸj—Ѕѕ ЫУzЋ!ЏАмЗ6Бwc%Е\zД ‚›Н~eГЄB-љ$jЙ#n9#ышю‹ПїŽХCžFlЗЛруьYчр~<ЛЌœнIБdmT™ –#аbЖЬФаЛ ТсoŽВѓ]ВБЗF`џ@нyc2МMЖiЮЖЇOщsYu;ЩрсЗЬ$ЈЪu{Юиrf/zЗыЎk* -ЬдM]­НьљШ8ф7—%k6YВnlЁ–ЌДЂY@~ƒ*l(v!ЯPJRИОД8BФpјїђCіЉЈ дpёqAћэš ЅиФy<` '$НŒОœ*Е rФЖaУfќљшзRŸeхeЈДP‡H;XCкSћ }b’уhTƒЪВЉ(f§VФХј]дъ•I л†—L•БќњdJбžщ4 ьL]UЪZм|шощЅс№І›рппхі–0М7s,YлвіYLЗhRФ$щБі_…—Y”#љ2К­[{™NS}M_ЈЃДa–Ќ’%Ћ~Žс+MYВž?ŒydЩњe ГdЭˆ#bWыPёљ–­šˆ …Чы0Q2зIˆ8Иe—A‘Вѕ$X‘КЖ72Kс:ўqЮzЅЃ„ЂОлллУйй .Ў.puЁ›lЉ_Š5vљТep]N]э СŠе–$ж!ЪMKGŽЛ'J+ДJ?)м8]I:‡tŠшъSЯ‘[(&<L]Œ;’тp{ˆЎЄІЃЂC(:ЙЇЏklљ|Б>YДВt€"@T„Т] ,ЪоW шВ$бWЮхрJz‹ѓ1­пUWџЪЕцG€•Ћ!тоі)„H§,Y’ЉЪеRЄ{ŽvЯ д'7žE§„ Йц3•ф–Ќ0w`‡щУВv1т)u"!sгzmnTЌ(!+г•yњЪuœЈ§"Г%kЙХ–ЌUЕZВN#Kжou–ЌvtЇ-С’uYВ~ІГduьx;VžžŒ^С^Pг–яœ ixУX2Бё†3 +'  а" п‹~ѕЛ …›г‹ЦЇФ ‡%!ЯDЯ@~~>‘ WRS"в#S”Ќ"гџђJv97‰лДѕ_‡r‹‘-xЇъг‘cёЉlи3)ВђпяK!Ї`ŒяjЬмЗc$NЄП?;^Šч6ђЮv,РЫфЩ5Z'inв^‰ёЂ1M3UрРИ.YЮш3w2;ƒUћВ;‹ЙОБфЄ^›ўv/щ>ЭТoGй;­’Z}л‡ ŸD‹ЏHfхСž-mЈзt<Љф—iУЉ†}ња)}ЌЊ(іxЅ ьЊшУЧJ[)янЮG“3Е$ЪЦžŽКњН‹ѕDˆIажžћ .S#3ѓ<ž.'Нp•[И Эvоє’хэЏ_ZV KVZ;ъgѕ^Iњ#Ј{afKж/юž…iжџљWxabЭ œи’u>o$HСS%НŽ{Уљ[NVЋго@оЈћ‘;ћylЦ l<: П’uЋjќуА_=s—ЇЂя”WБpI ќЄa˜–ЅЕd% V?Œ„q1јМр„ѕЈ тмЙюŠvС7йŠEЋєH”?з Kˆя@я&цП K,’Љ&хъr ъgvbзяUGgВA–”я‡Š"HГs/rzŸTЃЋЩоW“dоWaыƒ‘я}‚aѓi+j9ШŠз=@–Ќ/Ѓ0ўMzљZŠЎхЏ"ˆ~Ъ/ўJ–Ќ[Гь]МгЗ›dЩZqщYВ& яќEdЩš‡‰УЩ’ѕёћ0ЉŸK­ВД–Ќпa7НTН9ГYВъ`Љ“ЗanB!ž˜еV@ЄЎ -š]DŒ:§ым9­Х™QyƒOщгйТ}r&BM•j“eЙWиІ‘"Ї)𹉗NщDМx†н;3ќьшн`_g/Pм7ж§ilъшц‹мік:yд+ŠЗЩ6НєЉžи2“o—5•%ыЗг–рhxЌ’Я%ыЗ:KV—K,YsаGfЩЊ2Аd­4aЩZ‰>rKж№џЪ,YMЫвZВ:рЄ KVuњќ#тut›ѓІ3ж•ЌjЅ‚‚@“" Ђzрмp‚от”Є аТИЅmЩ'Qa™Vсž}&‚ФŽoцIЋD%Dьк`|ЁАГ1Кd"$‘ •Zє…ОŸ}‹ЯmЩЪ[f/šiЩjOѕЁ=Д›нъr­nЄvT’‹2?жfЩJёЭjXВRйнrKжЖz]ЌкeБ%+ѕkdЩЊ:Б§Уц zЩr|4=JL L9*\Ьџ†_‡С)]*(˜‡ћ$ъя ЖŸ; kА7ѓЯ›žёЖйїgіш0Б$cce1няСNЗYв Б‰OжmЩJњBОeKжн’\u3[ВVВЛ&Bކ[UцXŸšВZ5UfŽ, S0'ьij‰Ю—šA хDAрš# Ђk 9{ЅЭЬЬФд%ЄШЌ$&D П_OB”’{WеE№dыЦ›,х/ЁЃ9Ї‘xQыЭ<ГiЗŽВX+§уlГ-YЙ.Ї`ВdЕЬpƒ GЉнхZ,Y‹“ЬЗd§ћsојg#-Y%уВd­S­,d KV`ЯЂЙЄйT‰Й!@jb irUРЖM0B%L”? з…]cдЏДз№›Ј;GбЩ­ф3‡oЛŠўэЃUЂa]щiД•`˜UtYђ&}$;\j№ЈCМ:`jЏ_Z­ IDATQpwpБHЦЏўъ›kЩњы6m§й ВdЕТ Вd]!ЁАdэKNжф–Ќle&’ ”жŸГѕщW˜‹9ВdѕжYВж&‹,YуЦbYВy‹§%-СхуZ2ИрюБbh{жЬ з+k€BˆˆxфhЫ–бE7s#  IМвЊ‘П †!впа#Жшык5PVТxcЧвTršію59фёїлъёWvЋь“шЏz2РNoTBФ&№iљY8Jˆ•ШsJЎЪhXіn с о‚lhК6–Ќ‡ъАd§]fЩ‹ƒU:[SА%ыС–ЌŸšЖd%†‰,W Ъи’ѕ7#KVгВ -YmБi7F WЮЎ; !jФ#ш1еhOо Y%П– ИИиŒšѕUб 9vŠ~ОЎ„H““Œ/пќ[оп‚S№UдTrъC­ЁзеЪa.yќ]нТ<ўпO_П0Ќ?ЙCч“ˆcpНz]<§ЋЖЪs љ KЭЫ ‹К“8LD(ŸЖЭIжЄTY% hдˆ6rАзыЁ„Ю–ЌьоЃЩ’bЩкdP*‚n.BдЯ{S<ЛD$—"#M$yРX.ёви+m™E^i…DGZ]&‡лHjlŸа<ШnдyЕTX9Urэ1SЖ`AЊ=њЊЉфX:~ГыгVЎЛЧпњGыfяŒpŸ`)Ф„ЈЭ>‰Z3!*г”#%7а)щОфёХФ=­`%щџмж.‘эКcыйпБћМiпZщўЗ>ƒr=вЗŠ%ыѕ€]щSA  _Ў!ъц,`2ИшuL›Ю3т{}dx BОB‚Бщh?М|Р~eiА­R[–†"˜<сIDXн*}цЌL­б>mхBШЫгжО‹Щ3wAл“)ёЫSн>bТfђCKЪŒ+пС Ћ)€ьИ‡IюBЄА-ЏфЙvfu_3Б=YxЉ#ЯЕфЅvЭЖ=Xк‹Цбk­фПЮ!0 БяAŸHђІk4ЌвTЬЗŠС'ДІрЕЫ&Ї“Шбо[с?јр№0БЋ‹ йZйр–ЖA’‰ќЛбЯ`VПqИЗsк8ЙзnƒЩу+§џяК‘ЁњА?wЎ Fk№нfэџчGяЊРи{+1vhЦоW‰ЅX#ы‚Ё)}}2•ы  Іhш НiiJЉДфE?†Вл`HZgИvtƒcјпQqљ,"їAч#ШАЗ ЄBiо˜@Юјc№Х4ыTžƒ,xж@КДр(RKGыЪ+ OтР‰9”žХВиB.ћ—Gлтє_ЬаzЧъˆWБZђ Ћ!oГбфЦВЮsэфЙvГ№\{i‹ЮsэЪjЯЕЂУ 6э­‘бqJ?x8souЫMы—TцсРћЋq њ)Ќмї~шџДЄDŠёГш|жїŸ/7?€EЉ q-FŽ| і}(Л?ёlя јКяnŒ‹tЗHŽv| xidќВ ўќг'M€Op&ѕНŠЗ;?ŽєЗ?Р/[}ёУјXŒ˜ˆУя „†Ќ$аXњbСжхˆшш‚+{ПЦмї‹№бщэш”ŸЛІѕал“|Йк9ЁЈœ\ЂSbСz6}(ФGKNхv•ј5уˆДЦr"I]cv xcьƒщ6пPђж,…к0UП›w'8бVћgщСрAx x@“ХJr›ђИёs7Lœц/?OЧCЄtѓШј@Š o[+TY[сGJ№Яg.bкŒr ОS™Ю›{EжЭ‡€ђ jф3чmВMsцIRФ–йЌ-іЕQСКƒ ь‚`яaƒЊЋ…Аqw…OŠ,XД?Tцt­:ў;‘!`AЪ‹и–;в?NbеE:Ё?5ImЈUoaiiFQF&добˆ d‚B)0нк}…йвЌYђ 2mэlс9hUš‡ƒ)Я#ˆЪhq#zйWˆ3зoˆcGLњјEю‰VEъ’эЌ­Sл_ЙЉпћSјeЧЇЄF§PФЛНŽ}ЋFТ™pIЁЋ x‰FƒФU‹)лSшбб‘ПuХ|эЗL‰i14G5’R>ЭўQМГrW fЏи‚ПŸЧ—dэ3КЇ lЗаa}5щCt n ё_Їџ‹{ƒЕ ч9M=€sЉWбgXdѕѓЌюЂ Жж6’OЂŸгъЄБOЂ–HˆЎ‘.ЗAwуЯž…јѓјOК1з–aВЧ+;ьcˆW„ЬёЦݘDP›§ДъфLФhrФƒ’Œкњh)хўэшm l9Юa"Т\Ё*.G;?ŽdXЁиж§:aйвѓDˆєЋЂ-eќЪ8Z !j‚ЇХDHвZЉ…ГГg*яМЮgГpuз:\ѕm‹ЪДTTЙЛСяё™Јz”ЁЭэWв]‰FЮкSs›щƒФR Ч0МКљ)Z)љ'†Ц#Ш3ьk’gXі KIцA–ЉЩ–к<зв–˜БчZnnnЊKЖЙ2ДѕНo)Ж“&j}‡ї 2ЄMіД{ч!e‹‘s”2IbtР‡еWщўuPš+G4ѕ„›.–І-ь‰Lz8в3ЗгšgЯэ=\TЦ? #CD#б!@з)|юxo=—„—†ЧтmаЪбО71В_гъЏє'яЪrBtьršЄ€ЬўuЎwЪ(Нˆ_ѓq ш2э.э)hАoУђrtУ­О!вJPЈwGА’ДЅ‰ дљТiQ#тEїAІ(аю§Дїю—гџќУ˜л#TёjWгЅNюэH/Ц—?бjŸDŽahPПІыФLIl<џ v^њЛr"KM$ШŒФБؘФDвvXPXЩ…З –Жзx›­ЕЄ‹WЪ‘S\… VOhя™rœЛb…?ЉBъ9;TЖё€“W4њ­РІОЗŠfџьŠ1иœ[§RG9иўяЏёУš/№kвmфsшDИ™ЎЏJоŒўкеuQУoШЋи˜Ѓ{Йхъѓ‡1Ќ<ПlaVžёяbDьj1Lј|ЫVMD‰{.J^‹AптЫТxD4pšгuЄdšЫ_Гše­SшёЋpіt:ўїг/и™№+ўиЧŽЅ ЊJMI1MR<ёk`EДе4a•_<M~э§›ЛsОAR^˜Б ) Pp! IЩ95“hJмЊ“… žСєїЉ …/’ЪI‰wЯЖ\ЉpAзоЗЖЅѕйƒ,Н]К…bТsД§Džkw&г˜KUШJNA†LAйА1UЈp%'ййчi%ц 2/ф‘ŸЅъ7UšїЌнŽД<E}ВЭ•Scuи ђqКЁ„…јxm TЅє&GјЅœЩЋЋQз№еŠ?$ЌВv|ƒIИш@hŸQ*&ОOXЉ ЪЫAjrFЕB{Mq9ћwсф,РЫaсДНжLЩXЙš}]ЋTQЉСм?ёюёЯёаЎg0эа||}~[НdˆKŽь:Џ| OСша!MB†јО9Yk"C<ц}{ѓБтW5*UкяTVю]щЏ4Юъ…8ї~Бa§SјtмXєwъ'сЗьg-~–ШТгзM!Ќzcшня#цѓUx$œ–Шљў#–/Фяшя}/FЯи/лР ёЪRб™_ёDФpєЕы‡‰Г`цжсMК:$КŠ"%jk+НЏЌ фЩ™6W*е”awіA,Hўї'LУєƒobCЦvф–]­ЕKЋ*+и]армВDмrШ Џ˜ˆЄшьчJћ‘JБк‘Ѕ?е3Е“‡ђЯхaС3—№к“чёігaеe№pз?gЫaSaЫд™XПу|= †ЅdС‘XR"јћу1къIќЈГ>- ыгXНЅЄ­юŸ:CяЛsаЪЈ§"2иK2Rqюм wEЛрrvѕ}нЏšТШЌ\№3͘2(uc.‡MЩ_;ДП—зЎПЎ'S^i­ŸўVф Џ ѓм%ф@ЪЖхWr‘w*…UќЖc~rю~'–T"OаjRкu€ƒЃvыьoIDЎЊ“sјpФ—пIЋ3Д0$эc?ІїK?и‹Ј§kд^CGЮnњ­7CВ,Ь#i;gи|•4й8Шtbъћгїћ’ЊЇ†Gз0l 7']Ђ­Ђкd;‡›/'dъ{Hš*Є:уўMGpП8ЅїЫ‘;ŽшяЪCbxЛ№џЄ•+О)в—[ Ч9<‡ЫcРЯефi\CzCЮеЯЛv(a<7ЖЯœcБ5Jэ’ЊbИŠ.=і*’ўі"Љnб[П­~<К M”саМMФ1НDњLзƒ<ŒЗCХUЫ…Д]јћхЃи™}ПчК’Щoн‰ЭуУ:# (єФWп­СЏ›NТžќY)Щ+вrrЕ•ЄDTgвК\ZN–›Вe У& :ЋИt юN@ЬВ%X9ћ*ў;ќuЬlˆud)Yz9 ЧОo‹в7IgЎп§˜<ўПx-тm„”ПзMKЗМVНле _uЙЉЗ>Ж:э'§ќCZP8ђs"JH ЏNшz{XЕѕыwиMŽ^п”Ќ_ЕdЏŒTІгgoў УNlРѓ“ўG/G˜н9Вђ|’Ќ<—j­<Ч§fЮбŽ]Ѓ"‹TВђ<ЬVž?~,YyjhEЉaбž­’jGРЊ vЖzraЭўЄЈЌЉSйй ŒпМГв’х9ЫvтџІ§Ž я ”КВВЋЭєђЩчјsu,ЦїО„’Єƒxњч„Й™БBUУZДŠ”ŠХГЁ-›g$wУ &YП:рЄА~ЅhuёШкі…ќ —šаГРьŸЄБi-q5X Ќ<‡п‚еFVžoЫЌіІршхTœ,IЏЛrѕUO;7 єФО}щ+тM%%%PЉTЄc^џJ’Yмр•ўѓ…5ŽІќџZzŽ=XCПi? ŸZлL–lыж†VlN"ь4фvRЏŽA˜Д~VЧЦЃУCЏcтнЕО…IеыњcKV–_ўё‰С`ыWК_#{Вж эЁ}с0X2aхйIfхЩэфVž<.ыiЁ,XѕтЃЃžЊNlEџА9ˆ&ын$ынКюX­.ЬЩ}’Ў !jfаеw=J>kшЃ$ы€€ф“Шяќђз!]яь“ШBфдйEНmё‰ЭИTdž"z;Ч6ИУЗ7†Д‹B/ЏюА!ѓxЖ2ЋЈ e[ СЁ$ЫhуY…Лnз“Ч;њЉ-`Am{;§ЊaUY.)Qї…§0за#н˜bЕkмчП›‡mЩїbdИсъ3mђi{Жг †bВЊЄ“dDFЄŠДmЫЪйŸеbхiЊЉВze•—S?Є(П'zI˜іŠфŸm‰ЙўйdwWцВ*Jі"`‰*Ы5VЫщъ‡Хл№ёŒ-g@ЪH,DрvЃPЧrЯЂ@MКNF‰‰Ы™Ћ™ˆ?™€уЗЂзВћQeKVu“Ё@ќ=ш!|ж!6нљ<6‘о=$2dд…rj!ЩIФі/–>;wh•OЬ-ГЄ+ћ.6јrюWHЭ!+I ?щWМ~Ћ eВ›1 Л"^РoUћёЏ)m№FФіGlуiP@at.Єi•їЏœЫ!+TrЦInuЊ-Ё-ГЋИ”š…Ќє,dœЩ@FzŽVQњr% ВЊ­_Ћыжv`+Яa8ƒзфVžIЕ[yж&‡Ыы’хм>VЎШђdГўtЯЂЙTR‰A! )1)‰ЩHMЏор3qПђОЭЧ\оJЩ7'Ъ Q=шкккR”ьz*)—Z0ь“ШпЕ-иЪŒS%Ÿ}ф“шО (Аyќ)Šјв)щSPVM”Œt$Œo/д5ЖТњт.П~шь`|Y9o"цO)…s'rDIQœ?xљ †ьГ…Йe Ё  jїЃэћОдЬф,|>+ЊZљпjЃЕ1ЭйЖГ—wСВьЧиЋю]ђ)/ХœЂБnљ=р0As}ЧH$џ#ь^јrєЦЃT_В:…GэAџєиK:DгЩтR$оЪZU№oє‰‹Б30ф­О’/#R@аЎЮTWД!‡Евj Ÿ“бH\ъ0?фYЩв“‹ДўŒ:rV_O:гўбЕ­.гз%ЫПцŽї хѓ)мб,|t.Я–$,И{ЌNzјлЋАfV8i‰Г•­ќ~ЦR'ц:qJц"pгЂШбЗ5жЙ‘ Ш:Љњ ЇAjoЄЩ!яЋп*оWkGHЙвT ˆРњ“;tтvа;md…ky|/]Ѓ Guш„л=#н> nэсрр@^”ѕл,FM”г&BРЦлжŽЄŠ{Z/ам2}‹КseД"ѓф’З0.žVxt–Њк6!гоЧЖiкМЫАg‘(A$}ЂYUѕТ‰P,ЉJдŸЫs’ещa]‰sјHВРЉ;7ШФ<‹У%“ЩдŸ-6щJx,VХъЊ8tIчњЖЮ]т­ЊˆЋaхiиŽ8ЩЊq^›,x!vе.<є!m[’%){іЙ‰”МuЃ2ЪнЏ‹QПuan$I9НFД(BTЉЉпɘЕMУwљzLЕ|?[Е[…ттšл Е>і=с+ХЖвзщ‹е&<ЖЊ3c.y_]нТНЏ‚МЏn^eкћЊў•\KF мЇ‹ДVUэыJiіeЋsШ•dщH;їuˆ~=сяеnфOЫХžlЄ•tMxk^—&ѕ6)”Ž™0ЗЬ’–%W PE?єЖюЖЦДЄпКъšВ~­ЋОEVžu ЂЋЕ[Œ:И1j|j‰˜7ўЎZЗ„Cˆ*++qhm"ЪUеNLръшщˆШ1ЗšИbYбІxэђЏЦЪ­ЅXd21ЕћРEEХ(S[ЂШX!?Нu=b#<Ё–B]8Т›”3ж’уОozуРІсZRœВыы}•L9Ш+l?ьО‹ ’аz_Œ^фpLўцtžBоWЩEWRыAрЊКHВ(уэАWв‰ Щ_эMп‡Ѓ=zyЪйŽѕГОФƒCGрж'ЩRЭК†­‘iJi“"lѕћЭ”d›[fў@№Рщu€ЏшЧќ–JЭ†" `оPфšГ]У—[šxTжЮЂѓ€ЮuJэ2Иё?ШL†НŽ€iСy&B‚ 1 :ўю ~ѓ(>pIЦRVVFq„XЮќФ~JН:щМЏњzACq{FŒ‹6“ЇhЋXЌOЎVМЋіО:ЧъжоW]OŠяMБЕ(Ц,ЌhЫЈЂ\MQ%Вп_WгІНVzч‹IŸй~О†s†щŽ4Pх€w4нМДVXІ+*Ѕ 7<ђy„Uo3WД8BФOЯП—ВOх@] †‹ кїhзd56qШII/ЋPCЅІ€ІєУГaУfќљшзRŸeхeЈДP‡H;XCкSћ }b’уhTƒЪВЉ(f§VФХј]дў–I л†—L•БќњdH‘МЏ’+zZjˆїUYЪIƒPW”сXnšD‚’rޘeЯ[_!^q›o(ЁPx9’6П,zДЏe{ІЄЉЊ”|нлЙЏЌVѓdХDХGžИјУfћ|фt|g 6МЖБy:7!е*іE№кšЉѕ5Ж+Н–c11<ЅHA@A 6P4а;wJWхѓчAЊЅiХ-’йикажYgЄl= VЄiwbЦХугVƒW:J(ъЛ=9:svv‚‹Ћ \]шCцФЖдЏ ХЛ|с2И.ЇЎv…`ХjKыхІЅ#Чн“отДŠЉ)*(]I:‡tђъSЯЙ[(&<L]Œ;’тp{ˆЎЄІЃЂC(:z™?iВЏO§6 аЁpЇџ{Х‘f0Зкћj*Ш1[0BјdЊg IDATыГљУRjж‚@qY ˜ќ№vЏо”s0Яz‡чшбІ3­uC/ŸЎd_ЗE+PЧŸт'ЌMП_јз‚qobВт‰KLdЎЎќvэк%}Єх‚€‚€‚€Иая7;Pц—+ёВеPЮа" cрEϜ퇆ТЭG;YšKU7–Ў?=CŠВэътJjJDzh9^Є*2§/ Џd—ss‘ИM[џЅQq(Зˆй‚wЊ>9Ÿ СtœI‘•џ~пXђУ:c|WcцОн#ё §§йи‘ѓ5Ž•#% yg;рeL 3Џъ47iЏDˆxᘲ™* pрG\—,gє™; ЏАƒБПЄ%ф}5UъMю}5”МЏЦГїU%59WK ‰Ѕт)FŸЬћЋN‹0бЙ“­zЖэ"­…гбСжќ-х(ђИЛсдN>+eџUp ьбК9“1тIЬŽўЯпwп}P“k‹ЋWЏJЧrŠХ ­Ьђ‡ЗЬјЃ$›ArјŠч 1oАcXOOO 6L*/YbžGKkБ„ˆoТ;ал’{1Ћю–˜UOTR“r5OЮf'v§^uq&DaIљ~Ј(‚4;їВA yjбеdяЋž[m}0ђНO0l>mхQ-7gjЃMБGшкi3Ю0,ЃѓG+jе!+ШР+Ќ "6ЉнћЊЇ…РЅт+в*асKЉHЫП`–,жѓщхBлa!Ѓ!^jHђЄ•J&SЩ—ЯшšяЭLОf„ˆ'*~››ЗЗ7FE/#(**‚JЅ’ŒxeV#…щ•’QИЉЯL‚œœœhwЧМВЬŽb=<<Є+žOФ<ЗiHjб„Ј!7ддmў:wNkqжT‚щЭойP­Ѓ^ЩL„š*е&ЫrЏАM5Ђ›GN­ТHцёД&тŠеwїmœ<$Фњ@СžšЬ"l@@OBєGжqФt‹n0ЩЊы>Ф›пђxыкббQZте N<ЉёЪ“Ё кrЋD|M!FŒ‚’nФм!^ xОЄˆ‰јœ?+)F'eŸFЉЦXнНцmВy|ЈW'‰€АNЇ‘y|ЭM_r{@И!т{`з\>‰xrтЩŠ Oj|ф$ЪљэNш ёVИŽ DM€"QA@A Ѕ#РѓAt!тЃX-’ЂЦЌ)„шџoр‡UЉЬ\cд›ОЛ"Щ<ўДДЦО‚xeЈОФЋ2lЯЋ0Ќэbgь|Њ> M{WЅк“OЂ‹2ŸDћI—шžР>Mл‘Lš˜иИHNˆИœ'8&Ab Mш‰z21JVA@Aр&A@ЌђˆЙƒC™Щ‰ЏёЙИЦmD;K`R‘%hЩъFŽОMvf~vnфšЇKbОдКkцьлŽ=йёРC!PxнXеu5Эу9f)EЇцe˜mю,9Jф(ђ:Ѓ%ЅДJФ&ј"ёЖYs"ё–Чф†'6N<‰q9Onќ‘Џ 1тКќQЖЪФгQŽ 7'bўрЙƒ?‚ј№‘?L†xсМЈУmјcIR~-AЫЈnЉ–ЭЭK~-Aq1ћС53•ІbОS,т ЊГП OQЋЕš kЌ шїн˜кп—їŒИчAtU< ф('ѕ! ™Ч J$t.?ЋОъвuw{мJ+@ЗЕ A7яРfБм2k fTъGzDпžкeр“ш|ЁebЭшFWE QРчL„!$H!&C !h)G›Anј(Я‚ё‘ЯEзkHRQCP3jГ)^ыO‹хЫђ€Б|.тЅЃŒœа™Ÿ*@ŽЄёєжѕˆ№„Z зсяZЩKЖЧП†ŠnZs}[O œ–ЭяєІЏљбсHЩ%— fш1Xmй<žЖТ8dFЯ€&3oюСКKЗД ’t D_{2“DЖIђIJL\L|x2у!~Л3&B jвG ShЕRФ7 HЙ\Ь'|ЮI^W*0ѓђi&PЕUc2ИшuTЄЇaгВ•И­H )ЛЬ9Мsѓ‡УКЖWŽ:уВЃ8S–†ПЊ,!DdMВ\:Слп0№cЮЏёxщŽ…8 . іХad?ЖP*У‰uP>Е;‚Мj>тŒёxэюъvбуёщчO!ŠТrЄ­]ˆwѕЦ—‡–JЉАyТџсфШcVŒ+ЖП</,J љбјWвыИ7мђ*ќ8ѕ ф=|?rg?MоЙgсЗЃЏШSкw+ётШїqŠ ŸXђВ6]Цу›џ‰"vikпХТўxШяцЮ.’VПn)LЦЇOЭЧ›йkv_Ьоњ2Ц ’DІ­\ˆхƒE)Ж%mћОј№Н;A†ф4žWPш„џНJaMЂ1ЖК^EaМПF>‡OwїCЋ4М0ё#gaCцНЈиЛc†?ŒЂн ˜:и ЅG‘Z:ZзKEсIисІ™LЫ/%`Сн 4ž%X9ы*>>#кт№{Эњ™чPЕЅ.ўZDЋAОЮЭo_л8šВМ—O8HIЕO"Ж4+№Њ;Zcњ75q1щ1žШфЄЈ1§)mnФќСw$ђ|љЦмЉBˆƒЕхmВMsцIRФ–йЌ-іЕQСКƒ ь‚`яaƒЊЋ…А!BуS Тд^Фj,HМZ#жwЩWX1= A1зL4*ДхjкduHж yеb тUܘ)‘‡‘$ыЛхcБяxТњн‰'Ап|Ї†рдцеДє:ЂкСœE”]6mэlс9hѕ1SžGP8­G‘ŽxєВЏ75ЬDп$~­эѓ™Ч"%В6ю“ЏАcѕПeuU” ПlšЪЉˆДХ#ЋW=&­ !f2ољ!^њзnL<’jа`DNЙЊЫhу7oХЌ‡ќЄ’—–эФшiПуТ;бQTЊб^_0,Ј?>:ВQ_@9^ šбчoрА7ZВГбњ$к%ѓItХЧ‚p5 DL`L|’“ qНт•f  7(ђЙAžoьэšёѓаи.nќіL„$Ё•Z8;{’џ”;я€ѓй,\нЕW}лЂ2-Uюn№{|&Њо›'mƒ™‹ г…йv\ЄсFTm}НZНѕ%љŽЎOb1.Ѕ:#:IdHЊMП{ќџлўLLъ†сЫЂ‰<ьС•ЩЎј~Ц<БѕM"1—%"ГeкуH˜&ыЃњ7ГŒ”œЂЪ.ШГХШЉю“‰6џЗЃMСo§Ъ’ыdyBoeƒАсtsУtьwC’Т^€|:шеЧmн˜-žDёPZАЋ7Б.аˆ.Ахь^]нЬЂ%G‹wvМMWv#enїя 9!*№Њ€­›V7Ў9юSN|X>Ÿ‹2qхЭбП"SA@A ѕ `ŠєШ_ЂФuqlшџ25TЮMл.6qШˆ‚уWУйОк>: ЅЉтвŽmPїFШр‡aхhЈdpЌCT#•ІHd(pЭFЌx,+gbФ{5jPtр*к—Ѕл^ЂНЉNдmэЅcШƒЃш^fргEчБ#Аa­й”_F6]YПq1кUЉВє‡щ­IЪоRжшшѓ/вю‰’ˆ•*ѕxЕо“QUqZ^эиPЧˆ48HЪ@mJЋ@<тSjБЪІFц э5бœіvВРЇЬиHЩЯ 2$d<иu Žчž3М2ќСЧйд •hй:]<§бЮй—TWЄЈ"нФ6б›ќfŒЩŸ !qф2QO›| Š@V‡€ AђЕ†#…1z LЧ?ЎТYЏt”Њ%Ÿ*ЮЮ[ХеЊ4а”CSp™$k`UuЪ/žƒ—ЊЊ5си­Ж™Ž€T@•“Š“ˆDєB>-Ё8зњTpы$ђ}ї\_,ЦЛKїрНчћCє?|Мœ Y?‰PIЋDq;2й—VФaњћдžЦ,VьiqСмЏѕЩпP~ы›љcЅэ8Уžj?ГЖВЦф№0џїЯQІб.…ЉщјYђx1jигє–и'бЗЉЛtЗх{/љГюДбAnсaФ>yq.ъˆcЃ;W((ДZ˜рˆ @|.Œ2ИŒч .“_Зє†k§щДTаЭV?qУaщ–Ÿ‰žќќ|ИКИ‚Іv^ћЧ}U(Й’т“Ѕаф_UU%кЛЙЁјT2l=МЉŽ%hйТЄ§’[ }Ў/^ЇѕQ4ўэЩ§>†’ЂєОїJdЃz…:Ѓ-Ѕ6кэŸЛІ`хВ|Lь?sЅa„`ююХЪ;RrЧ Ч‰4m^ЉнR]fƒ!яlЧМŒщбеeРмЄН!bЩњОt—uяЛ&cУz{ќїУ№™{–n…щУPНуFѕx|Кх Р+яZ„{?Aеzс#оўџŒщ(Щ Œ~Ё˜ƒ1DЌІЬТ‚љ4–C2Зьїв§(Fћ2SЂDЪй?НЅЭ[№—cŠэ~О8ЖUзŠƒЕўH[iд•н(™~ў=А‘‘јящтŠCb%ЎiюR&>Тљт•+W№Х_Hп#q]~lšž)  ­&:œ)GwwwLœ8ооо:rФs “"бЦ’{ЖЂ‰GЬѕЖуЊТЕ~II T* Ѕ‰,77+VЌРІM›0mоT<ѕк?ъ•wЃVpyњNXљљТЊИn(8’ЈО(П’‹тЌ‹„Y9Ќ—ыпФƒƒšН^;ЙУЈ­КЖЏœœЅ|}25Ѕ*ђiиИQ§њ*ЫЎsЄТкЩ6Ѕd5Le5PWишЦ•ёнЛ12›Kо@PІ№jЈ Љ7;8;ѕFŠф…Ф{МєšIкžЩ)eЏРъ§ІЉЅŽЉ1ж^іŸФx)МЈaCЋGsњџНй"б‹~ЎЧё§ƒпаVašЎkчЃхxўэ„усс7"іašcё‡паЬ™xФ4#V‚˜ ё\ТЧ%K–`оМyК>•Œ‚€‚€‚€ЙМўњы˜>}КЮ[ЕX5тyIЌ™+KY!2) ъА .OЃъгзQr’ZP№g2ЊЪ4јнО;цэИ„ШЋЋЊƒ›^бšIŠЙЩЦб™H†ЙЕѕѕ,щCДвЄ' oч"tфЄmABm­Y_тжD„jгћБu&2$z0<–‘ќBслКзZЧАEнgџwЫpМЖgŠЪЕЋ%Zё[‘є=^Н}"иBыFJь“HNˆJCШY"§kŠФЄˆ?‚ ‰—ЋЋWЏJтяМѓN 2Є)КRd((мрьмЙЛvэЯк811В4нXГЙЅwпŒѕ‹лw^]‡_У&i74э:Ѓь‘gсрŒr‹ѓfCKm8?Ѕ|…Ќ WPR6ЯDєDˆПљфЭВћpРЇ‰nњ{CВLŠМЖЛƒ ўоs8><ќ­Ў8‹ЂЎ?ЙѕИOWv#d8фˆм'QЅГЮh. -§klЋC|d2Ф“XiiЉ”gй=†„aєk7Ж›В§™3•xiœ–‡M ХќЉ™0ЗЬ|@Tјмj ї§Œщ§є/ZцЗWjZŽ€‚Йх˜QрєТkЏН&"­ЎŽў ЖвФъП€™Г‚-ЦаЊбŽ‘ƒУlИбЈЫ+ЊpеЪmzїСР–ˆћiqGѕ]ќЙЉ“ќК‡бчZ€`Ÿ`RnтФDap‡^јѕќQффЗ‡MєУкtж•ЕіŒ=Ÿэл> ЛЯбнЪQЋГш‡нyC2ђ-3БB$&2>*Љn‚ƒ­Б~Ÿ љ™ResЫъ–,ПЪ/ыšєeB.]Щ›B@См*–”ёЫ"&>bЛŒЗЪ„.‘%ВД?,iQK]KXX-"ъ-.#;Mщ[У…>ЖЊbЈOGyюe”“NSщ3U”6­hНƒR*м4ФvЛ m(f™<}žќ#TхЅђЂVŸПЖЭф)е*ЊЊЦп#“"žЄ˜1 т"žШB$GћzцЕ/>n–o5\ЯQЗюОЬћќxўр•fžO8Я‰ч™†$‹ ‘1ёчтиA˜л†ЭкIЯ‹Ъ‘[TFІЯж№Tчc?Х­кџШhzњYь:П=ќˆЙ"•z f#рhk/™тkэДЭЎЊ БцјџЬ–б*“Г*ћ§д БЊDbљ)ƒЁ[ђ}g"$Ши.[f !2€U9QPАБB$ШПpё‡чK‰‘Х[fb"GЛ "ФеyžБ4YLˆD<ŠЩPфХy;Д—”žDнІ:†oЭ6)ъ“Ѕfс бW&ЫЋ№ЎњS%Ї `Œ@X№-HЭЩФЉТtнЅѕ) х= ОŽ&ЄѕЇ\шpVжкѕА M6В*rсnеpe[БR$&-~ЃуenžШЎg:ѕщ:ŠQgo'Š9HЗkE[FєвЅ)ЊDіяћЏна,~Ѓ—ПМ”|Žn^ ВНv7ЇєЄ а<№|"V‡x.iШЪYƒ‘ >|dх%ўe&ЬцpЌЎ$кН=a…Jkэ[HљEšєн,є9о6uх›j­§;ї ŸОпž‘њP-{TGбНMн‹PCюLlЩI‘9Ык•Д"\_ВІUт†$;+єnч„JzlДЙ‡u%х•ЃГ“ЎjH/ЁЈvЎф<Д™Sё‘я0тіїqЫы_тЋИК•иеg~FпЎџ4QЬ’х˜==Ъ"Пb”VˆЯ%L„фdЈ!ЋC|ы "DмPЌ Щ ‘kѕЄСОјЃ$v† шщ>К[МтQ‚O’ПAжЗ'te­9гЦ*а€э-JТуVˆRC’и.ЄH>‰е%лZ›ˆrUэ+IŽžŽˆsk]bjНVІЉТUR86ж`ZХЋэe•U№ЂˆРgЇ?ЕН3ЪШ=ˆ˜ЙєИD’|оŸШл`m'ѓВ^k/ѕ_pшv'>љ‘мuЎЗ2ё4<§ўЛИы[рЊ:‹OЦЭDќŒ)Д—‚@7—K‹z‡ЅTPИц№ќ ^Ај(VЂХб’5ˆ“![[[ЩKф}їн'YАЃ$Ё,ЩKYž.‚MW§ъAЇIНаЎа Uй5…ЕФћЏђђїX|—й Е{OdUй мJЋу“Џ)ТбЂ“фв[їBdщ=‰Iژе%‡_К:шŒдŸOзZ­Ыр ZЏеwЁ‡#ŠJI “HPl0rВЕB>“Gkф'ІAUQ [T'Л”r %ЊRdЌ^kвkЖязњКа^/MУЧcоФЙ[СУ‘x"іCz#Ѕ№;[у0nXGhrгёгG›аюяўˆшю€э/П„Џ/Є№5 0i˜ВЖ­ФГУт™гoaHи=˜&КѕCьˆэDnv>*„H Ѓo|x.ЋC|ЗbniШ7ŠёdЪ[ebхx"ЃFBAAŠш ŠC{ШЭс)jШ@•6 -Вt ў М vыЬЪЮоOtCиOXГBJ Oђя0“ '''8;;ƒW{9LЧnG"Ruw‘wƒлыWХt,Ш0)тФGs'/ŸрЖШ>‘ќѓ5zjвžў†юjTЊЃР†SА‡m§Sј›ђ*xbu/GiЅˆŸ кЃ л2 Ѕoж4cV]VЁ’Жем)œLЉJ{/uˆз_"ї ЧП;„„я`+TО|_ќИњоў 2ЁoIтПп‰!wOЅ68v^X4Gw.FшЁ|?|)*ž\ŒлƒŒ=JSБ~†–”uЅјsJRИ™Я'"паћЗˆ‰•!ёV)ЃДЗЗ‡ЃЃЃД2ФФ‡“%;ZN OrBди7є†•v M@ї3v8ж]Џ№Џђа 'Ђ!i-[СZ|ŸХK ‡)bbФŸ>vн‘XЁ'Dфџ‰’*5­-к:3ўОѓЙqY}ЯЅЫ  ў†cЪд‰lh‹+А`}MыМ~ьr)‘WšЏHїKMлgeVДЂMў mсяDЮ_Iск†^ўЖq‚#­ЂQ>)ЏчiѕЛ’ЌZЭNДГFЊgp${Нeйo ’*?исIќу­иНїњv3”ф>+пNРФй јGяЉнЇoпcЄ#”ƒ5>ŽxŠ08~§FмoL– E*g 7$тХJ>ЇШѓцоДE„H.TўfЩФˆ'RБ=&ЎёЫ“Њ Dbаr9J^A Е#аІВ ŠЎjю™ЋЛ•ПђбЕмmKj ЦІЋz]3тЛ*HљХ†ПЗФЕk;јz"GЃ7VN{F 9р‘NїZ4n19‰Ѓhl|.ЪM<œа1В2žз]юе ЮіКѓ†dјЛ€Тгс щКйIJёЙj .ЈЪqібx ˆЗгЖ](F;"GLJ‰8х—вR=_Д0Е}( н‰ qђяц+гЯОF„ˆ/DNŸŠшйЛ‘@,0|ЩxDxIеЕx ЎпX|TŠйПlХИЛє №ВZJVAр†F Ж9D”ѓ‘ч9s’Х„ˆЫЉ™ 1ёсеўˆыbХˆЭjХ5AˆФ@Э RGA 5 p—к пhі иІкw}џtLЧпrРЎЪтЏYГпВ|‚`2$ЏшŠAŒюАŠФ†МК1§”Н1‡š=ЩшšШX:јїђCіЉЈ дpiы‚і=к™jYЏyллHJеўфч,РйŽVШт„\œШS#хЊ}qЎА …х•Ш!}Ѓв/jK+H Аlг”гj”6хehW{EДЇ‚šЪјЉ_oШзNžБIоа’ЂŠ ,эї(>Kъ„ЅчОЦ@!Q+WљЋ   `9 šЉy2х ” O |ф$Ъ™$Щнh …'Aˆ,ІвBA х#0БЖŠˆCѕЫHЁm јœХC•ZьрХ ŸљEG">ŠеЂЛ\Ђ б‰Т4ќЅЪB[‡k~_6Ж6ш2Ј3RЖžD—;‚š„”UtєGzцTGю}9*8юћ% $r”C–mŽDŒКЙ9рњ№vПlІ–уНь•–hч>K€ШкЙKVvТƒNуЭИƒЄЋ‚ўНiЩшЂЁ6­=)бo/СУъU˜ЗqГЃБnљ=јkХПёi’Zвsњуу‘D‹JKдˆzё) V”Њ ‘TЮЬC A„ˆEѓфЩ“('9!“*“ Б…&t‡D=Љ‘ђGAрCРоИPš‡e‡uw–d†>.=агЎ‹ЎЌ%eФJ‘ј>ѓЫ ЏхФШноЗКwУ‘‚“КЁџxa7žюі˜юќZfМ:zЁћаPИљш­ћгџ}пЎ“šГПЁ+Щттo{‘›є'’)vЂК"Ue|~&юDЦМHgЩќy’ђ|1­ЉH лвФ–e™я=…1IZ73ЗўQФ‡Š!’tІѓАі‰8Д‰x /ЭК~0>.Ћ?љ'тЇэFTЕ%Y%)МЏ^Єзё ˜2Хвс(ѕЊА˜‰7J&7<‰rт%vБфТŒŠ IDAT:Ф“ЉмП“!ЎЫK—ЧЋЧЈZ КХЩ‹фељВnЬпЈю w­\wЉEdФwšПЯќЄˆќar4Дн@BєгХНxЊлXIпцzм„w`г[SБѓХvЗї—>тžЪђѓqѕф)\9vEчqžђ'щX~ЅньсhљjLћ‡РтЭŸ@C^ІсфЎѓ0э‹ЄЊXб5&%ьХ$qf„YU1KœGОЄЉoˆ3хЈ   аXLˆDŸ‚ЩЯ™ B$H BL†B$аRŽ72Яй=†—гўKv?кэ”ЂJVlХKt?o-ъіљЛ,>‚ёїX#>ойЎ/–ž]CК3ZЉЫъ<ьПœŒл}zЕЈ{iъСи{xР7ЊЏєiДьђ АЦњ\1EwЏ†‡AiєX  5h!тЩS$1q2ёс‰“W„ј­в˜)dH ІotzК„тяхтѓѓ›uЗšXt;‹1ТwАЎЌ%e!т1 RФG.чяИƒЕюnз?\иЅіЪпш„HwГM‘q ХЇ7 žh™k…Mq“Š ж‹@ƒпЎ E|dђ#ˆтzr"ФхJRИx?иgЯБТ3Кл§,c#њЗ п6ZSkн…ы˜‘Ež‡УyўRФљсўƒ бЏй‡PTЎ‚ЋхлFзё–Џcз№ КŽ§+]+(д…@ƒ  (Oš"1щ‘ŸsЙœ‰zЪQAрFG .ќ˜Иџн6SieоN§єy•§щП3- ёц1‰<љs›w˜Dц.”№ЦЧњ*Чvв%zИу=вЙђЇ&џš№yЭB%/Ќj™лЉ&†Њ)мА4Š TФФЩчМBФI!A ЪŸ›ŽЎ~xЁћD,<іБ…cЇёхЙя№DзбКВ––‘Ÿхcуђwр“гёКт-™ЛBЄCУ0УdhхЊї k9›8с9(ЄЈp”bk„@ГНІђфЉ| nіџ#:м‰С>Н ОЮ_ЄmЦЩ‚Дћ§0Ќб o›ЩгБќгјЋ8K^ЄфИ<Н3јѓйaэъ9Џ Ы?Fе›§Д"'›>к‰­еГїЇt  аZh6BдZPЦЉ амЬщљ$љЏб[iЊ4x-љC џPжм]7Й|?'Dzї0ћCІ^бкр‚rb„€оgбЏ™ЩерT‘ЦЈŽЇдuОUoDXн*}nЕŠХтЅ{P3ќ­ЁLuЦaМід‘UЊ-OYƒ{"жЃиАšrІ pг! Ђ›ю‘+7|­`2єђ-†ѓв‹/`щЩезz(Mвпџ; фlЛ№ХњR & @‘|s_=ЦЪѕVXwЌ[Яш—fЌdѕ,ЯV —"­=Нu#vf~хkюРъOcйwѕЌи‘_)kВtЃXГRђ‡Х+)–o–?ЅХ †€BˆnАЊмNЫD`od ]›?“/ŸЄ–9р:Fн. Ž6’;eЉVŽњ фўYG‹›ћвуё]1vm0)VcnБХ№`[ АС­mlткИd…­Ћo;xћwDдc šЈЮЩsˆЗ;/д­ЭY№s­[dGvbeќIЩ7?ЉŒ›1ЃW]лЭЩaЭЈXЬ_ЉїˆТdЬБz;Яi§Rq;%)ДvBдкŸ 2ўVƒРГЁ!РШф~сŸЫ_VдjюъdыˆЛлї7ѓeлЬ“'Вх Бe–к˜-3б‰–Teэј] ;Ј_{ќёr,ў9;џ:ДП$§UqГ0хщ]ф,Дf*%R~ьћ ф‰hTтZŒИ{ŠFЬХ†sпcн/ Gћ„Q8ОŸ&mƒX{ЪјўkьF/мвYOŒkJVJZ !j]ЯKm+F€‰Ф<ŠMEюuwqY}я_Ё;o-™ћ”ЋwgDq…ЊЕ џšŽsХhэ–?uо2ћБzЫLЏQд№сИQгg<ƒЧ­"1єюХ}ю]ŒщukхрЁѕГpoЄ|ТсхнгО|5љХ2н—••l‰.%Ўњ x oН9!vз@„ји зшЉ(Ф ќ–ШЯ8?ŽлŽ>k…`S’‚Р ƒ€Bˆn˜GЉмHk@ м3“‚6ъ/—іƒЭз[SКЭ+ элъ†Ќ&ŸD?gэг+=“7hЗܘё–й§е[fЗ5С–їrЧА‡1љЧџ`нщФПwі•yOX7О,%Omь7;оЗЋ5#чh)\Gzеа'В ŽТьpgФЧŸ@С™}јјПсAЕJR.(ДFBдŸš2цVРФ.ЃаЭн№ЧфН_рRInЋЙ/­OЂ; ЦЫЁ<”d>leжи-3&>=‡пУ",иKлyЙі•ЉЗг”k-ЫeЋ“5GъŸЈЯCЏі-jЙуŽИGprб",zr‚І<ƒ^ен‰ЪQA Е# Ђжў•ёЗ:l­mёZјSLиљ€Ж›J0џЯZ•Cгсўƒ АOОšŠŒт‹eЪ ЌЬф[fП‘й}“Ѕr#ХfЗ@ФŒwЧ†й_!5G M^VMZ Ÿ!Cб™їиjMˆ||.'ПEKџР•BВ’“‘zA+ПуаЁИgА%Ё 1SoCудСk„rAAрК! ЂыНвёЭŒ@gзLя6о‚Ф+ЧБцмe-љ$РЙxыLžхj9кМА2“o™ ЊЖ2ЋYл’[˜ŽŠчŒћ?ќƒжcДo? Йђ0жyУћпЦ@xУВ†ЋЌ#WиЖБ—ЮнћMРК5“БeЦ q€Ё$IвEЗјлŒ6pУdм)$ЩФ(YVŽ@“„юhх(УWИ.p А]ЄŒќGnВЎџхЉыq{л[ьжQWж’3Ъуp^ŠnˆлВ~УдПщт щ.мФ™ЖKЯIwџ8§}М)\;†р­ЊDгШКaвџГw%pQUпџ; 00ь((› Ўh ! )šИфVb?ся†Ѕ™‚Y.е/ЕвмЪ%™ў~ZZ*j%™˜[Й&‰ŠK*** *20РПх!лАpOŸсн{пНчžћ}гМуЙчžГ/“ˆ•GAl9R3ѕi0ї@\, TыђŽ„(ЋbИMz1џš Yi,…Dѕ–ШСOрѕеи)ЛГ+C ! њЊЗ 5БЅ0šдчЃgBѕ>rŠxЂвbХzЖћЌ„йZгuђkчuqЁ$ъ6П­’Z ™WаЗЛЎ‹орђбмd4GYMЈЁђ˜IЬЄ5™ўщ>FH„Э™'Т№El>ОљWс VcДtџЗ…Э–СЈ#+ќЛЧt,ўgЃъі­мЛј2ў‡ЇЖдTtЈ %Ё“@‡DЊЄ:DNЬ1…ˆ‡ЃЁиX0r‹ˆ[Aшhгˆ“ВЉˆѓ!jDАйT ŠJ‚–ыѓCтaќuНЂю:з6Њ\*SЉ8'q” T'Є6NшЈ<ЩV'Nl0C@7`"н|.LЊV†РќюЏсbцUЄdr+/%ёb–ХlFXџе0бЏхЖG#aH“Нв˜D q3ЪK qќс9Œqєk$ tsšџLйЁ•`-ЩšЄеТYg†€Ž Р"yLŒж€ЉKž™…З.~Ђ‚*Ÿ]лЅГUmКX ОPЃˆsѕіл{Uтб@“­]!Ђ`„~џ… “Њ 5ѕ5ЊŠЛЧ`д Іе ?6š!Poєiг“]^Нџ-х Е{Ž|њжл< Сh$IхЁЉХ<О{ВT8’Ѓљ­ЎПYѕ‰Сю›“[;Dl§ @€љщФc`B0xfv „ЋЉЃŽеWЗ!ƒф<гeЂŠO/ЫnYL"5n_оCEuZ” тБ\дѓЉ2еS.Ви]вk™хrуАф; ќрŒ:СkAц’6Qя ?гз^Ћ…PlC љ"РЂцћь˜ф-CНzЉћlш‹дq€Г‹rёЩ•­:ПкбТTGќйЌ"o7$Рђш(86В}}№фЛnШнмйk\ы8e12ˆЏйЭ/оCш‰t/EŒ Š”“q%HXŽВЪюuХЧїтЗФЃ8uџЬs7FЗ…p<э(i;Œе3: ™АC …#РЂў€йђš]Ь1ЋЫрg§№ЛП кt­2ИН7IGТG<ІВQЈK$њ6#@вїŒ†ž†tь%˜Оzfoо‚Х‚;u†ЦИŒУЖ!_ .—ЦТЎˆВpјЃŸёмЬ xр8ЌмЂУкоvЮ6фкfmХ0ЗГ… iГƒ•:˜cE\YC Ѕ!РЂ–іDйzZ\F>ЕѕПЛHЎА]Ÿ‰О1ќЪљ:Бm3ўqоšљпўŸ†ИYŽЊO]f>aАјј&р7|Дф4ПV–мUЩ[~§PqіКЗ1}І5N­>ў,ЃВЛ2ІБяC@ащсc7!ЋУгуьKc7ЃИЄƒжѓкщi3M:•vВтЭІVYО§ŸгИГхю„ёiN4§‰ъЭv{/„œž‰ј/цтЛѓ2HЄj+Н§Яw_ гЬ №$щ;|fПЭ%oМ.№0Ђн1Z=ь”YЋџ 0t;cМзc–Ч~ЉёZіmю4uОжEъCbйYЋт)б”'RЯcDЛўК(nЃШєF—HЬL`cЎ;KЂПX‰6_„іц")zj/JЁLѓЏauа.ЌєйŒžЧь!і(уGœЉїЎJG2іa­є Юq7v~ џOНk?)Щh0…Ј>TЖЄ–ƒ=Юў‰ќL“Р*щЛ„јкzЂ‡…ю9НRЫ\zgŸR\’жуtЋVˆЮМc­ТЂЂBiieО?ѕЎЈ­˜4’ їŸЏExXоZЛAqЉ3ѕ1М€;_„aa!№\O8йnЧІU? nQ_И™‰*bШк­ІЕЪЧЮнœXиѓ Ф>ŽGfa6'ЖЂДKc6сЛ~Ћ`$ж=ЧWš†DS!Ђ)HфЇУFŸ˜GZ!ѕ[—#KSиR ‘`G,D–ФBD>…ѕNСІ/–эќFO‡žUВrpтЃНшОцNъЁF~˜9ж=Пž|З1,oНVjэ0Ђжў `ызy, Эёс33r&ЫbУѕ0A›ЎTœLьрaйU Юс”HAН5UЂоkƒoH№Уџ`§pМпW“ЛŠ1ФVЋЖU“>lICѕПk&ЭЦb3”d‹ П}kbex#H 6Я’э5Kœк-ŒUD'“ЈyU=7ЛЫhyАoЫ{ІlE-~ф%6Юi~N>ЊZнО{Ч1аж ЯлєRЕщJ:WЧ<ОЉчї‡g0Хё%UН5ъО%V ZF]АКєrЙ›Vм Ѕ‡YLщШrїi•lЏ} ЃwЄ<ёЇjœрЋ0Z L!j%š-Гљ#№VЗI8ŸKRb&б|Kт&)щxЦЙVЃ}N”ЁаяПP.НЪыkSцсНяЇUй‡нd0нјхlи52ю ‡@rД}nї СКhМŸА„_mM]щ0@ Blю-Єж=:Г€ЉŽVx//^8ЫI@?•‘Б1b0šІ5-ўlv†@­xХi(|к*s4№lООŽ[ЙwkЭГО:›иу‹ЮЖЇВеQЗ7ZhХrœџїj^š2VЄм*CCCakk ‘ˆW„J Љ>еˆ‚x,ѕ‡Ј7їщ- ФЦ-ФЊ!ЛЊК=‰н…оЂФ<ЉЊЛЧhо0…Јy??&}+GрУg‚an`ЊBЁИTСEБ.,;юЎКб„…Q/f?§И|ьСэSЁ?Ўд*єъ“р`c YчбопTAš:u*вввˆOѕ"т§ŠИ‚VŠ‘AМfўЇюџŠM_yу›™ј…cЌ+%яZ‰бcCщoкбл/‡Г:зp]Ї`у:‡Sˆtю‘05G ­Ф {L И§$_оќAаж”•!эМaЈg !Е(7 ’Tѕ–Z 6ŸЧ{хјюы]ˆЮ9 ƒ6њH ЯФуŸхиБcg!вгЋлO0ЭvojлжіNш?}4Кв­З"šлŒRN­]ЉВ -Zq щeЗфз#РуПH(р{ЪуŽazЏuˆ'uYl—ў#9bМ‰еiQАфo ”ŒЯфЦЫp0x>іDЦ""8у?=8)eМ(Ч„§Ё=ЫнлИ!‹ќo*,#†€#PЗџuxaL4†@kAРЏН7F—ГТќt—3Џщf&`гG ЫYŒ о+ЪW‘X„tq ЭХмa3КжiгІqЂ’~ЋLЙuІ-|8NЂЅg!zлЯИI,FЖmЈЏ’бтНјЯЅУ8ѓ?”.y3gџAюЛEOp'6Й|мL(Šг№WЬ ф“КДs_Ќ˜йІТІsЫсы(AQўќyŠє/SЈŠS/aХР)ияј:BП [WтШ?9œј9чvСпџ єнЙ ЧwЃЭХ8zъ>ђЕ]ыЯhd”џЯ6ђДl:†C >˜п} кЕА\ћ%žе}ћDРД–•э}#/ЩтPXZі6мi9•юP==j_ŠјЏгqчПЉ‚Хi:Yз6сН1сИІЯ@xјсp,ОtУœ‰BTp;WЅcЬžї1Ьг6юОјрt’Ж†сЊ†ЅЦ LF€Зрquc’‹Юг&.№ђv#ЩhХФюЄМЯ/Ё0Ї^kЖcлт‘№1‹нЅјѓќ}rSЫ?nG;№ж$Oи8Лaђз_Ё4& Р* нA€)DКѓ,˜$ Z#`Ђ/%/ЅђтRŸVJ-ШРgqлkЭГ>zYїDC’ъНŒ J St[Ym‘WхЩБЧсrdэ)рЖЯЈўС8{…јЭ ‚%ЙRт=‰Д‡Z]ЈбЯ{”лІФ UFTqыІЦ\bЩ'’U+AЪžUy4ЉМї4Е&UD…J0ddwѕ­ЖЪWIвџ)€еh'’1MI,К‹ vеm”пbн–’IЧ`T‹€ЇuLю(L њ{JN<<_эи†ю &Б‘†йіL]'ЈЗд =MfcУЬщ‹а-Ф§gv‡Й5Щщ3MK‘ЖPЅЧдС]frь?ыГqЙDН*3ОЅмЯSБTё1ЋŠ4•^ЪIЯ„й$г† UОJšЃHxdŸM†в6)‹П†П4чдьЮЪ B€)D:є0˜( К"0Гs :™: иЌЙі Щ›>іЯ‹эžШuKqйPПА7[D…W6шiВєєtnEЅ%Ѕ("JQRA:ТЎ‡ќRоЃД&еjйEє,˜Ѓ6~Žgp п;Й™3‚Ьёѓ‚нˆO—C‘•€яЇm„Э сp)Ы\Œ HИ–‚фШp ВY8ЕФy1‰HJ—q>GТ›зxuK‚>г&"хдJЌXCзСЧуcNйЊШ2U1'жЪh˜Bд4ИГY ‚€ž>Хк@ЄоІШ)ЪУЪи- 2Ÿ6LЅішjт,ЃwGPoI>1аЖm[юЃ\лџЅтоїа3жУСŸ~уЖвj‡њАU2ЅW+O|1 [!єHFmоЉї`œ­7žЕ~?ZOЦ{`NКJн|1 ћŒФ+Я`СWAšœрњтD<‡]OЌzпчЅ5-H†‚о|ХZТчЌO'[xѓwќWl?!СFтt]BЖр–Љ ЦГ&†@S# ўеljIиќ †@Н айЌfu€7ТTќЮgФрЇЄ#ј?чЊЖІ( mуƒ›yIЊЉcѕˆmЃe’в+чбЃGЊв#їJЂ[eєX>%БЁhMF]АКTгЩnЬлˆ)}ЛŒ• Іэ‹ФЄ\jхCjІДОІŒФјЌ<ˆЭЬAu™ЩСj Фі}БЁш,dФIIBЦ‰ˆ‹ЅeЄŒ‰Rw&оB'ў$=ддaьTl ˜Ъ5$я_ЧЉnfъШ ъŽЌФа!˜BЄCƒ‰ТЈ/ЦХ'2эўЪRћщlОЙо$В5нT4ак[“УAHRЪ=uћZ(MЕ-ц}чћi˜Jr”QЂЪ=`OOœщ•EЇkђ&І‘ћb}Мћ§TrЗaHbІvoЮ@”$+j/Њ„є%D‰Њф^ЭŠЄ“xЮх=t3‰ПсdL1vюAGдБ ди-]@€)DК№˜ zF€&V]т> AQ WLў™OHNЂW/й„ЏН—ƒ&ˆm 2%ЇсњšѕDTŽ:Q~ЗІ‘Ѕ1жџ.QŠZ‰рЗИнHy‰ќBМхб]ьMZ lНЭ–љOГfј ˜Ш њF Нq[ќлэuлы9 јціЯ‚ЖЦЎМ`бG0eA'rшлАх*E‚ХЖŠŠvннр9И?њшЫ”ЁVёЬ[Ц"™Bд2ž#[C B†лї‡_ЛО‚{пп‰Р•Чё‚ЖЦЌє2э =ѕяRCЌћ;6І:9зЕGАeю6” Хh 0…Ј5М–sЉ4Œ`Mžф]+ђSьн7’ѓd`@"Y‚\šф8:eNŒмŽU“:rrЄйАyиœpОŽ™и9,sfwDј–˜ЅЈ ŸTkКіџj­ˆБu3š)FbC.Š5Э+ІЄЌТЌКњВкЈзg КBЏT-‹мИЗВю5И zzzpщчRх<Ўјv•ЊЙI•!ЇеoУaжK eЊ)•!Њ]Yw—>С&“ЇТТB)*KЇZёd4—™ЕƒЌэm`чlG>VPФF`єфp$G,‚З({beм`i:5ъŠ<с!ъЕЁqЖЅ,§`>зю%šЃБЪ­;…|ˆGЮ`c/o щЕ 9$KйСрљи‹ˆр@nЬєрpЄЈ\в*цњо ЫТСЩЏРGД’ф\“#jэOшЙсјК ‘$XdР—ѓ‘Д5 7UМ*^7ke4ъ_Ѓ†рЮx2:…€›…+ош4N гщД‹ˆИwBаж‘К• O—E=ИвSУІS[X8VlkлЅ ,эеYтыK Њ)?”gjкCмН›ˆ];wеz Кћu1ч/уђёhФ'Щ эм+fv!ъO6[N,/Dй Tˆ“˜3ф=ИG|ƒkFу‡iŸу&MKдЂш&`щ*Wќxџ(6o{lDB™­шa$жŒœЧo~‚Яv (Tœz +NС~ЧзJRs\иКGўЁJTхМќќфaˆAaыЅёp0HУ“љаLЂ(2ЭБv3‘WтCF FC€)D5›ˆ! LqѕGO‹Юa6^У™zћJpГ+ю%BKЬЅ‡з‰•Єђ­ЌњХе—Ь]юPlЈgaОЕкЮIЗЩ’ўїП<х–™вJDЏћїяЧТрьйsЕ‚З7d–ЭјŸ Цю3Љ€Б<<aтс/o7иYЉн”W\:Щc<1`Œ†пXСMь\•оG›& IDATЏЏњЃ-‰šэф;ˆи€Тq1ŽWJ sJрїеn,  OO'n+‹Жy­йŽm‹GТsФX,v—тЯѓї*xIЛЂ[ кљі"ђu!9е pŸФяюцЂ>)ut…y(™Ulgж ,6˜!PЬ‡Ј pи-†@KD€n™}ьў&^=Л оgEІ( GёПФ—}“дхД„ЁSЉєdЅ(‘ŠИYђ‹хј+э&њкѕhРYyжЦЦp"ŠCђEѕ6]‡О ‘jк,ъ&ЇQŸЁPžв_ˆжіb;рУЗзі/н2ћwL&ЛѓV %Ÿb’L•’цœ!ќаЕo“ Яї“О‡B^ЧЩnџЇЬЅЋ№Q њі*‰ДmШШюъЮmеп™Ъy)ˆ•ŠЬ+/Sx,бƒd9‹N|LјиqМd БИH”Є‰ТѕЈ'b%†@У!РЂ†У–qfш,N&э1ЏлЌОіJ֘Ч7№]Т~LuЋjkш‚Бн,†ЌЗjЊЈћБЂб э{й!эf:ф9r˜Д5AћэTrдЕxyєѓ4• ТД(}29IИJќ…~оK‚dN8ЭM%/*D‰–>DМŒšjOхRгŒѓ ŠЏ|ЊzХ‡кіЦ’^1Qн#Ж"J…œУЖКЕВ6’вОZ^j.цpђ7FdZ9“ЏUм\˜BЄЦ‰• ЕZпX3Вy @Рпi0њЕžЄкvыgмЬIlTљŒo_шq‰Ш* Ж†'БОЎО.\іUз!*KМZз™“ЖЄсЮ­$ќўлqœ"YхЃЯ_ФеЋqHJМ‹мlD$цމЁ=xк—~rssQDЋЕ!ъCє(! щI)HОЬ}rЈCВФy1‰HJЇ™юЋ!ГЎxuž5іЎХЉи,Ш dH‰CrVЕ#Œ9ЩЋуE,K9)i$цх-ЯœЩˆY0 GoKeA2ЖxЌ‡ЫМИ XГ C Q`ЂF™MТаM>|&“ЮМь"^ЁYшiиЯ 9•жdUŠ'ё™0эbЭMGэg‰sѕ(зчczX9YЁћ№Ў0ГQЇЉЫФ‘?GsУпђ›‹ььl˜š˜’M В*’щ^IЅфшNN.ed ђпСи%Z*DњhЖљOФ6%crOќ„^}q"‰H‚ёЖa˜ю4ЦKЉЛ”z}bCКƒ>лХX„9~*N‹cЂ@ сœžЫЋiє›QОЭZB_'Uё’ТkЩDЌœ‹AЋЫт% ~ пЌЙ†7:{sѓrqˆVѕgGюUOQ)ЁЦœЭХ`шЄ^РТПз „ ь0яИН&hЋm…ўФЃЈЈљљљЩdœ5„* D!иЖmЮ*ЎЂуl/еэMЌБмw†Њо ѓFМœЧБ§мжњY.нšЫ'v3I y.oQ’˜Ik<І2a+уЅ (9БIдЮоВє,ф‘YЄъЪаdэšИЃ–.]ŠeЫ–Спп3fЬ€ЕЕ5,,,`ffH$ю#“фб5ДќВ-3M”Y™!а xЁнsxйa`х{юў†‹Wm YЩ8•‘F№ш‡y™Иѓј~CNЉsМя&&"ѕсУњ“KŸ(Z(CtbЊIыAЊŠ—иˆЬЁЁ бОR+иАД FMˆSˆš|65C@W˜л} ьŒmт,'ЇЮr‹ђm U)Ю-„y–p?ъ~уФ$jЈ5iЫwяѕŸp0qПЖУX†C ž` Q=Щи0š3&њЦф(ў,т‘Ђ>”.ЯФКИЖЌ6щBŸЅ у-&QЃ-’MФ`ш,L!вйGУc4.НЌКуеŽc“ўžњi Ђ"3Cт§[F4&бпiёЪ*Лj‰РЕGАeЎІЛЕ– Xw†@+C€)D­ьГх2ЊB`zчqшbц,шВюкЄd кЂB­Sоv=ЌЃФ ъЌRsєѕѕQТŽЬд0жГе# мДoѕp0­=}.ьДГЂА„Uœ[œ‡•Б_aƒзЂŸжЈ-ЧžСБЄ Њсз%тБќ ,I\жJЦѕ­евпё\‚ь\e’жZБЈt"-~ICПщ/РFп"ђЌ,ыH‹SkєD^БўSЮо€ъy) Ы-ци+Œнh0 QГxLLH†@у!рjъˆ7ЛNLx!ѓ ~L:"hkˆŠЃ™-œШGIЅ$~ЯЙfр\]Ђ(!QІЋў(зT›ЋsА-Д§ШђeШЫгТ)О ЫE}ИьѕЂомеS41ФШ”пћ ‡ќ)фXПn‘бkчс9k? Бˆ~ЁHЎ"5^њљУX>6оx{ыЭrKЉš—"=;цˆ‘^і§ Ѓz–‰UдэtНŒ9C€!PўЏУDІ]ТЅЬkЊо_ЦџŸЖp1uPЕ5DЁŸƒ;~М~\ХšiсZЧЄ_*nѕ_(!A/эКŒЂ*’YСsМ0*xm$йЗ‡ЅLKk4QЌ&)ѓЅ=y’‡"9‰]c*FQ@gоƒ@KШЙtFА&сА“w­DШO}АwпHAˆ ьhI/MHr2'FnЧЊI99вlEШ‚шцGSвjRѕМ$Ю}8u(М<{ЃЄс]ь4…cхB@§Ћг@0Ж †@ѓD qМч6M ќмDlН.hЋя =iцnгIР6ŠX‰t™l:Е……#ŸIОМœmЛДЅНEљц:зЉЄќPfЉiqїn"vэмUkо47Z\дEФœПŒЫЧЃŸ$ƒДs_Ќ˜й…Ј?Aиtn9БМ№‰W qs†МїˆoАqЭhќ0эsмЬЅ^м D0KWЙтЧћGБyАиc#ЪєшЂ‡‘X3r6Пљ >л1&dDqъ%Ќ8ћ_GшсїqaыJљ‡*Q•ѓr№ѓG‡!:}„­—ЦУС 7NцsЉFШ@ŽE(ЦмLф•8eЛ№Њ iHЪyŸзœW1MšЫЈE РЂёй" ƒРpћўж^˜SlgТЏˆЩ*яoQПѓгm3MКr E l™вœЏ6eW_b*ї‹*6дƒГ№д^mxг1t›,yсqџЫ\™Ж)­DєКџ~,\№Юž=Goеšі†lРВŸтгЁСи}&0Жƒ‡Ї#L<\рхэ;+uЪ$oкф1ž0цYѕ|7БsU:МОъЖњpђDl@сИЧ+%…9%№ћj7–…ЇЇЗ•EлМжlЧЖХ#с9b,ЛKёчyЉМ ^RчЎшжF‚vОНˆ|]`Žм'YуКЙXЊd‘:КТ‹<”Ь*Ж3U5 ХѕШK“/+ы4lлSЇŽ!аєМзcўЮКŽt9яЋB•.‹нŒяћ­†TПaв’?гжІЦxRФ{эЪШ) вnСЋ}їІЄ Œ-ŒсD‡ф‹їT=:єэ‰TpRuГN)Ђ>CЁќ`ЅП­эХv ŽЎVtЫьп1a˜ьЮ[јYˆЇЬ Bsд+Щ~шкƒЗŠЩ‹„Кu(фuœ Qі&Wўа" IЦћО§„J"m2RуйЖUk–•ѓ*ГьШЫLOF–шAyU<kеA˜BЄƒ…‰Фа%Ь Lёб3!˜{i•JЌљiX§[|јLАЊ­> њzbxлїФёЄ‹*ЖQїcuZ!Ђ‚кїВCкЭtШsф0ik‚і=кЉфЏk!№ђ шч ’Ф^@…єШИœ$e%ўB?яР• ЇЙћђЂBrђMS… ЋЂRГ1%TIЂŠ‘HШ‹(>iЄ%`Яa, рu‡2+чА­nЅЅТ кЈU/5s8љ#В@­œ‰ @Жаќрт ЅBDьM5чеzCBЈБo%Ео2жУVС`4}лКcМѓчїџрNЂ ыБвЯ^ИmvѕQВIL"]&БОЎО. P\vЌЗИMI[вpчV~џэ8NŒDєљ‹Иz5I‰w‘›-ƒˆФм114УЃ@ћвOnn.ŠˆcЕ6D}ˆ%$!=)ЩЗ“ЙOuH&q ђb‘”NЏъšuХЋѓЌБ?p-NХfANВлЇФЦ!9Ћк‘Юœфеё"–Ѕœ”4sˆђ–РgЮdФ,˜„ЃЗхdЛ-[<жУe^\(kŽЮŸЙќr—#c(3=OJy>щY9eїЊуE†ЫШиtЄЅ%Ѓ &їиGЙк­БL vб˜…HGƒ! ыЬъ2чХ )O}тkееЏбгЂ3Ќ% р4ln G3мЫMч сb=ИŠсНu*+'+tоf6ѕc9ˆќ9š[я[~s‘ SSВ DЌ ЅjKH)9њŸ““‹Gˆ<Тї_0v‰– ‘>кMn›џDlг@x>ёzѕХ‰xŽ˜ІЦл†aўЙг/ЅюRъѕ‰ 5ъb њl7cцxјЉ8-މ†sz.ЏІбMХђmжњzЊŠ—^K&bEр\ Z§BsО†Чрз№ЭškxЃ3џi7hЖЏъЏ:rџ8с:тKЋ”К;пПёs/№2žš‹сJ>D3ДЎ†—,nyЌ-[п-ŒsиŒч6ьЦЖ9nemьвм•jnB3y ІAрzNо8ЗŠRѕП„}m<ё™ч{• DbŠ‹‹QTT„ќќ|Шd2ЮzA_юфОmл6ьлЗГ>СЌЅТ§ c‰№г*оv&mБЬwКЊЮ •#0oФћШyќлЯm­М“6wшжqщ’˜IT FuУхЙМEIb&­ё˜ЪxVЦKA,Prb’ЉНeщYШ#3Zл˜зyоњфUйкXЛvИЃ–.]ŠeЫ–Спп3fЬ€ЕЕ5,,,`ffH$ю#‹klЉe[fк=ж›!аЊшnо3:0ј3§2і%ДеW…Ц$в#1‘””’ї‰й)Ъ*ЛVРнФDЄ>|XE-oщЅC eˆrЇŠД”ЁЊx‰ШЪэ+ЕБ‚M=(CѕЭ‹ђcЄЛ0…HwŸ “Œ! “u|ю–]ВmМ†{2rDЛžЩ\bїЖхbчjFе#АїњO8˜ИПњŽЌC€!Р!Р"іE`0ДB€F‘^тў&ŒХъ“;љ 9–“Ѓј тœZпєTLЂ‡q$ZЖzЫЎОчk ќK1СO§<Žcт0r<}x)&ОX‚›єђ€ySД†я[ЃІЉБ`%†C †8Jлa~їзНcЧуЛ;‚ЖњЈаЈе&м1!Ž]^Q“Ј>xЗVПь0УдŽјaџ јW3ІПщŠр願9Ї3RВксНЗєљGУІii­јГuы&L!вЭчТЄbш</;uЈжЄmЗї‚:^з'q1‰ьz XF=`лf@ДЌиЗ“ ГГ1єЅ$P!7S’ФU]:Їw§|фщыСТЛОкЈЖj9ыЮhv0…Јй=2&0C@wXдsЌ е9Мшщ3šЖ@Qўuнd.ПmvѕбфШIЊrFЕC€ь†‰Х"тАЮO!Љ3NF?†SЯ4Œ‘oЗl˜XBlЮ+LЕ›ЄžG‘Sn9фєXfVUyЩД›S‘‡ˆ- ]G a4NRzzŽ*L€vЋcНЕE€)Dк"Цњ3*hќ!ЊiSДщfэŒjђR–;˜ЗƒƒЉВŠr”џ‰IФЈv<Ь,Bz ‡ р§„ЂnсzІ›П.ХЛртm ”BA"n7ХmРP=фx|ѕ”Оо№ЕѕУ ы~>6 4ЯH$‹€‡ЈЗр3м/œ„e|šфїўТЧ!џC ' [$GєкyxЮкClb„_(’+QкžФюBoQbt;fЉnС[‰4L!ЊжЬ`д Ж}ря8Xа9ќюяˆ~TПлZ§žЬqіСAUjŽРЙЈll‹”ЃDЦ;UЇф(`юj‰kYіЕЗ‡ЁDŒфSwБyG§;Щ+ЅДНkC}ЙlїЪЖЪЎFNЯ#єжIќUњ7Ю%lEїˆјтчЪЖf IШ.иwЇюХo‰‡іг(HIДЂЃSќАh—Ц8вз’(•Эм№эŠл‡бWє!т5žє#[В ›Ю#Іш0ІтkЬ™§G…–"гŽ~и~|9œеnv /t )D-єСВe19н‚р`l+˜rх•ЏSTџlѕ&~Dš1‰ю?IGRN=ЦйHпТ+ф—пР„ќ){[ ;1 +оJХвїАfі]|џm!,Ье1 ДGD†ƒСѓБчD4vјѕу,6Sv!™І!”ѓї)„†прReфœЧ8б ŠЭсo"‡‚Б<4žЋлxї‡g'+.ШЂдЅћ™рQZйwЋ ЫEуpшКкD•‡Ю6АЖЗГ‰I$E|шgx7, 'ПбJФхђж1q;5ъŠ<9з†ЦЉyвeЌэеї)йхЗaњрu8О‹ЛЗу2IљqћЬэЕg"ЕрU€O:„ФЂ>}|˜XВфˆZћznxО.Ф‡Kп_ЮGвж0мЄи•[Џќс „Ў8†LNЁЊѓ2pйЅ˜BT 0Ќ™!РЈ94ы==ŠЏG“x•QК< kЏmWVы|Ѕ1‰žiы*рCО2вё26%|ЫœˆЄФWHQP i1Lъ/ЄAqъ%Ќ2ЩV!є№2˜‡­УќEg8…Ѓ€ЄЙњыЂ цоЃ0=(K=жp–’”№XВеу:?Е8yь,>™ oЖeїŒр4гЦъHе%xŒП]FLфeDGЦqЪ‚ƒŸ?‚< б!ш#lН4ž(№ќwЕ'1gШ{pјзŒЦг>ЧMЊ,eeЫ м˜МЧяяСш{џSЩЎeсТЩ0,<‰‡Ж`“ В4œŒ УЌяЁ[MyйcьWЏp­)ыC‰Bк’т4м8™ЯЅ8Q.^Qd€b\РЭDЊє з[”џžŠAn™…Љ*Ь•ќиЕb˜BT1.Ќ•!Ра+’дге_0ъјУs8ђрOA[]*Я—Kјz!…Х$ЊžЂRшѓ:^Џ„МMI[}SсbEЌїС/Рs„?}ѕ|qЪ^о"‘єЙIЅѕѕр7ѕyУУ1уиИ™ЉlкMžtГ<–ЁлЂMaЧ‹kф„i[ўўЮъq%ˆЧкїWaйьOёжР0Єц—BъмнкHаЮЗ<<ЛРœŸ˜уБ‚фk›<ЦЦ<Ыѓ$eзЮ"œЈnc†КBl`‰Ў#{"ыD’РчiЭ­џСЄ7:кЈ•БХ„зДѓ’ л нЙmЛЎ§мсцnqqю“luн\,UВH]сEzeЪpхж+ПпЇмѕЋsSVx ЏФSїXC€!Ра щў…ГщуFnЂjмчзП…ЛyX‹еЇбT7Е,єВэ )‰I$#Бˆ(=)ЪGlњm<лЎЋ–œZwїџ~Ћ‡тюТО?ЏљuНЃEѕ =khуЈNќЋoж†X„n ‹81—ŸЭЈ#Іэ‹0Ђ 9ŽY†ЉCH&X ’]? ЗE№лА_ЮщKВ—UNњ$эwб_УMрWЃ dЩzхeкXйpCјЁkўЛ)/вP LИ‹ћŒTMд!шЅ2Ž&ЉѕƒЃƒP кіŒ–МЪ9щеˆ(€F–шAf‰N|Lцх•>YB,.%iЂ…p>•`…Њ0w"IkUŽГUŽ ЛУ`h‰€Оž>鳘 C=хПW‰вR,УЊИЏIrv—–|•нљ˜D=”UюЪЖЭpдЈвЦВƒŸ/Dїn|їоrєэг0д†jыIiaqЂ~v͘‰oЬ—Пpнлџ1ŽФЊ}‚‡EnТяЋниP2T#4:•€ј")•vхq[YЁ™#†8sгЯя§‰s6OЋЈы]/’є˜њ1С@i 3‡“П1фъџ_Фф'ЊlЙ”SР4Хе,зsЭAЌLž#†C€!PȘ:р­Ў“/gХ!œœјЉъWnль ‰I”[ЈёђЌIZ8и}ђИЯЉМХЄІmк@cш*Цw‹w#>] І>-ЫzC@AЩœ›‚?<оХŸЅчёŸ™m№‰Ч'eŽЯ œYŘxњ”РЗ 9q—cŸTіЬ‹гqfзQ$dЉ-?д‡(5>)I)HОŒфЄtоQњQ rRвS\НŸ”ДЧsлXК0Щ$і‘,+ё1ЩœИRъš^Ћт%mяL,W'q.Š№цф’РgЮdФ,˜„ЃЗIиƒ‚dlёX—ypЅЏ жЋ)GЭ1зХЪІБяC€!PяtxЯЕ“п–ИIљ)užЫйЂ=ьL”ЕрђЇБ˜DкСК|fЄœ`кЙ6}РЧЊi›V3х”тŒГэ‡)8сџжПпЗŒ…)єлrezЬ|СVWЌ:6 цd3lи†o8ЂEя'ухxt-ыЗbШDŒы3ућLСвoѓ| сѓЩя#*A дЈNё˜у1У]Fbtч—ёŠЫЇФQк^K&тЦъЙd‚˜В8FœuІL"Б!o­ЁuЃ.Xџ_єињ)F“иG>жУ№жмѓЊhšуЪ†ЋЧ–5ЈњTХЫОY`§—1ЊЯ\М$ыСЏс›5ƒ№ngoxПŒ_ЭЦњU§ЙSvxjНєEN,LJЊse'v­1cЋэrѕ`m †C Єd"шЬrњEzЏЃБ>qyљOђ‘ŒŒ lлЖ ћіэУЌC0kiHfњФgљљц)U_G3,щїКЊЮ U#@­CfН;BЯH‚ьsзБчœ g-ЊI[еœ5яЪАгc(Аѓ$&Л)Cs+х†“fПЦ-+ шСv ЄFъ­МЊ%Pыљг1ећ№д–—<—(Іd‰†gЏŒDцЮ#jЕ9Џ UЭœмеMЬЋ[Ыюш…ЅK—bйВe№їїЧŒ3`mm ˜™™СФФ С’|ФbršRЄмŽЌz"f!Њv—!РЈ%ЖFжxП‡PIIШПв~Џ%Gѕ0ћžф€ПњGю^n:’sRеXЉJVя4Fюп œ2ф6wHЏi[•ŒЫн,Œ-F†ŒМшѕЅ:Ё QёФFR-”!nЄVцѕ  UЭKb&T†hoЉ‰ЁTSeˆŽts^2нџЋЁ‹ъОАLB†C y!0дюyDІ]ТяЃT‚џšq=ФЮА…њє‘ъf S.&QьЃВm2Ž:W')>U@ЇNzœUˆяyŸЛдД­zюЪМtыGР–?­Ѕleз†D€a^t™…Ј.шББ †@ЕМы6ЖkUПRrєљ›Œ§((Uњ|ЈniUxО\*ѓ)зP\RНГЌV“АЮu@@ ›NacVг­Љ:LХ†–!Р0ЏЫW)DuAe0ЊEРŒФsYф6Cая‘т1~)8-hгЖТХ$вWћtа˜DєФ#k`Ымm †C †0…Ј†@Бn †@эшcнУ .ХсК(YаІMХ€Ф<ъkзC0„Х$RУЁЏЏvdF +1ЊA€љUЛЭ`дг]ў…шŒXм-P'd=$ކщS!‹k>пѓю8•ќ—jZMc™6§i&•Pu, Ї<ІЎЃw<— ;W™,UЛБеѕVЄХсР/iш7§ишр[Dž•Eb iq:ЋXYБ~…ЮжUёR|Г а72‡9лЌюkЃѓїu№ЋЌѓ˜1 Z @ЃWПчњоЙЖŽ$Њф}}ђEr” "Бhvз‚!вбТэMкрa^Ч@QZъK4дйЋv k9ЊDQ}”g=qэ ђЮСЖZK&;-C^ž:фAЕ huу \ў.e_š#4чkx”‹,-Пї>љпM" QЙ{ЪБMs•#zэМБр7}ЛAѓА§шT8UђІK?_Ўк†№ˆ[xnУnl›уІ!vUМH ЩрQxw+џНЃƒОкŽСžUІб`ЮŠ:ˆ@%_””‰Ф`4{\ЅŽoћ"vІV­Eю,†эшЮЊКЖ…Gr2A IDAT~ФЙzяЭ?TУЮ’гfЉ•””рвЎЫ(Ђ‰7+!#K#xŽя]Щнš7ялУїЈ“šЅЎ’гT>и“'y(’ѓA*­#ђФс}іс=єА„МˆЎЧжDсIоЕ!?ѕСо}#љО h riB"JЩ”81r;VMъШЩA<†,ШУfЇЪз1;‡`ЮьŽпђB…q|hˆ,ЏЗaё.ЩА&Єъx9ОВ Wї‚“•>іo&ёp^Ч—/ЁП=s""й|jЕџ'KѓY#“”!Ра!^n3 9ЯxrЃкѓБЦ$JЮMУ=ђi,вггƒK?—*ЇsРПАЋьTЭMЊ 9­~Г^-SEHЉ Q%шЪКИєi 6™ьф8ЂHЁІ4xГЕƒЌэm`чlG>VPФF`єd’О"bМEиS–cŒFGN:†…"Oxˆzcmhœ*Š3…ЃЬчкНDѓq4VЙu'УЁБѓШlьх!Нv!‡<<{"cШ™Ž>/‘Јb^ёЁŸснА,œќ |D+Iš9Ђжў„žоЏ qЖзЗCР—ѓ‘Д5 7UМ„ л ‰Q#|аЭЏќОmuМ$pб—(CдЉ_ŒŽМб•ФХК™Ќ…EN( ЋщL!в‡РD`Д&єDzxЃЭbiP›ФFњHьœOœ€Ћпz*•Ѕ‘zЖ*э\mгЉ-,љŒщххkлЅ ,эksЉТжKус`†'ѓIT5)Š ШіьмL,Ы{ІОЅQR\bхМЯ‹ЕуuљыЏ‘ˆA№щЁSћ‡kdХš РЂš Фњ0ѕŠ€О^1(р)3SррmuGСЭj*Ял ѓІQ?"йЪjLrѕ%JYЙ_TБЁœ}œыE КM–М№ПИџх(ЗЬ”V"zнП?.јgЯžЋг|{C6`йŒOёща`ь>“JвIиСУг&.№ђvƒ•zKhХЅг˜<ЦЦ<ЋžГр&vЎJ‡зW§бж@NОƒˆ (уxЅЄ0Ї„ЫZП$x(<=И­,кцЕf;Ж- ЯcБи]Š?Яп'‰M+ч%uюŠnm$hчл‹Шз…ф@+Р}’ХЌ›‹ЅJЉЃ+МШCЩЌb;SеYГP\s^ёЛжaъ‚ ˜z мЬDš\XЙ™!Р|ˆšйcт2Z } {рВьnънS-щр(|{mџв-ГЧ„aВ;oRђ)ЦЎЈЙg?tэС[ХфEB н€:ђ:NjІІ+тЙ’Œѓ}ћ •Dк6ddwхt@[ЕfY9Џ2ЫŽМЬєdd‰аGtтcТЧŽу%KˆХEЂ$MДЎG=Q%ЅђŠй8AsObѕЅ“хЩћnUТ‘57˜Bд ‘!аR­ш‹[Щ(‘ђџВ.!ЙІЗЧРт~Sa(VoЉUЗ~19ео Їя§­ъJЗЭS!ЂлїВCкЭtШsф0ik‚і=ъ/•HрхаЯаT2Шœ…єШИ\ёњyoЎL8Эa /*D‰–>Dм@ O О^ёпЊ$QEШЈœU„(>дƒ+`Яa, р5‡2+чА­nЅЅТ кP^j.цpђ7FdZ9Ѓ_!ЊИЙ8hЉ{SuМвOlх”ЁџмК„aдV3Е<ЌдмPЋсЭMr&/C€!аь’SLцЇ„)кMn›џDlS2&зљФOше'’ˆD!$dBцŸ;ёRъ.Ѕ^ŸиРPЃ.Ц Яvc1aއŸŠгт˜(r*‹Zlˆ5HеЪ*jГ–азSUМЄ№Z2+чbаъВxIƒ_У7kЎсЮоc.бЊўЊ#їЎ#ОєБJЉЛѓ§ћ?ї/ФЉЙЎфC4CыЊxх “<…'C[?žќ]p) “= 8Œš%ЂRBЭRr&4C€!а, ?1ХХХ(**B~~>d2gН /ї ђпЖmіўО?L@ЁБккТаїŸSУђGЂ+_іс;ч№KќЊЬлсЃчЇЊъ­Љ0oФћШyќлЯm­Ÿeг­9bp“˜IT FuŒхЙМEIb&­ё˜ЪxVЦKA,Prb’ЉЗ­dщYШ#3Zл˜зyоњфUйкXЛvИЃ–.]ŠeЫ–‘јOў˜1cЌ­­aaa333˜˜˜@"‘pБX\cK-л2гю9Ао †@ P"WРх–1БOЈ§QВ ѓvэ7­fѓБЇ1‰дt7'їsге ­Јt71ЉжпŠ‰гКT eˆNL!i=(CUё‘94”!кWjc›zP†ъ›хЧHw` ‘ю>&C U!`ђDЃ;=/Xѓхд8{џŠ ­ЊŠ‰IфжІЃ KдƒXAНЕTі^џ їЗ–хВu2ъŒSˆъ !cР`дЃ]ћУйМН€нз!#_щXpЋТ MхЁIч4~L"ЭљuБœ˜XŠ ~ ьр' .ЦФaфxњ№RL|Б7щ!хѓІаХgЧdj8˜Bдpи2Ю †€–ˆIŒщ/С@O}оƒЦк{€DБЎй Z“H9uйzЛš‘ ЌВ+Aр—f˜в?ьр_џ rЦє7]<л3чtFJV;Мї–"џ(‹ёУPcД˜Bд 2["C 9!@Гзtѓˆ|3+GљгS‚Thќ"ЏіAўHŸЦNхQX:еdпN‚ЮЮЦа—ђБž<мLIW=tщDœоѕѓ‘ЇЏ яјjЃЖё{tj™L†€V0…H+ИXg†C 1№ыр‰х|"т#Iвжš9H?“(эђ9&QcрTы9ˆБM,AЏЬ=…ЄЮ8§N=г0zD МнВabeБyЭƒcжZ–š$–Тrz,3ЋЊМd5eЦїSЄХ!bЫHзQC“”žžЃ  нъžю­ыы}ZтЦma QутЭfc0jˆРTїQpѕИХЅ l‹љХ%ејыdщ[Љ:•§0Ў†3Зќn3‹žGТ!(јmШЈлEИž)ТцЏKёю‡ИxлЅPˆл Eq0дc9_=%‡Џƒ‡7|m§0ШК† EB%AeБ№ѕ|†ћ…“АŒO“ќо_ј8фHiмјO ђT‹бkчс9k? Бˆ~ЁHЎDikы} €&i` Q“РЮ&e0ЊCР’DGžвcИ л§'щиZаVYЅМ•ш,IхСˆGр\T6ЖEЪQ"у•Ы”Ь]-q-ЫЂіі0”ˆ‘|ъ.6яPЧ…ЊoььG/СкP_.л}uМœžGш­“јЋєoœKиŠюёХЯ•љ…’ ‘]А1ю(Nн?Šп#ь'Ђ\“hEGЇјaб.qЄЏ%QўЊ“ сю+nF_б‡ˆзPxвlEШ‚іœˆЦП~œХ&`Ъ.$гT „rў>…а№\ЊŒœѓс'šCБЪг„98ˆхЁё\_яў№ьdХY”КєТ`?}|˜XВфˆZћznxО.Ф‡Kп_ЮGвж0мЄи5“ѕrЎ™§)ћпЁ™IЭФe0Z КƒЕŸU.šОЦvФTeЖЏ kcstoу"ИЭœЋy8DФШи”D№-s"’_!EA,ЄХ05Њ~KRj•тдKX1d&’'ЌBшсe0[‡љ‹Юp GСЃ\§ѕQsяQ˜Ѕk8KIJјF,йъˆРqŸт.=‚Х'sсэбЖьžœfњРТXЉКёїБЫˆ‰МŒшШ8dы‹ƒŸ?‚< б!ш#lН4ЦМВWˆ“˜3ф=ИG|ƒkFу‡iŸу&U–ˆВВЦenL^уїї`єНџЉdWШВpсdžФŠC[0ШЩ YNЦ„aжРїа­ІМŒь1іЋW8‹ж”ѕЁD!э IqnœЬчRœ(Џ(2@1.рf"UњšСz•‚7Г+Sˆšйcт2ZR ІЙD Ю,ШСюkGЋ…ЂŸ}љ˜DWЩё§†лЊV ]щ *…>o!Ё"щ•Де7о)FPЩzќэЛUŠУГэКТшš! |:QšфъЃИлtЊtLkИёпoѕ№Oм]иїч• ПЎї`дЃЈо—NQЗqДPёе7kC,B7Eœ˜ŸЪPgдгіŒEQ†Ч,Уд!jЇxЪ@v§0|мСoУV|9Ї/Щ^V9щ“TДпE 7ЕO>щЌ IeЩzхeкXйpCјЁkо)/вP LИ‹ћŒTMд!шЅ2Ž&ЉѕƒЃƒP кіŒ–МЪ9щеˆ(€F–шAf‰N|Lцх•>YB,.%iЂ…p>Ѕ`:З^Ѕ`ЭьЪЂfіР˜И жŠ€—œ2CЋ•vэ:Y9€:`WDژDоQнŽ"Љ@ZЛBдЦВƒŸч•D Ь@я†;Mfh Жž”f'ъч`GВЩгзН€ˆoЬ—ПpMїіŒ#БУря^–9>7‹м>„пWЛБ!иM0ЌЎšГJeD“YQЗ•Е=s<…Кwb­ЂqЕq,ЋтE’S?&(­aцpђ7FdZ9#ЁЕ8ЬЅœІ)nMЫЕ’‘0Џh\Em5•CћБ-3]|*L&†Cр)hєjХZ,Rџlхрл+‡žъЋйPўДй?iё уZ3ХЦ(ш“Ч}Nр-&5mг7CW1О[Мёщ2ШHNЙ№i‘pXж6O1!'Рц†рwёgщyќgf|тёI™уГgV-&ž>%№эФ_ŽCмхXФ'•9QЇуЬЎЃHШR[~ЈQj| R’R|;ЩIщМЃєЃфЄЄ!ЇИz?)iч0ЗБta8’Iь#YV:тc’9'№ЇФЏІЁ*^віЮФruчЂoN. |цLFЬ‚I8z›(ЊЩитБ.ѓрJ-^Э`НŽЬЫgpъВњ/ееЋАQnЋYe:6 C€!РЈ=ŽfЖлe €н;yїВ MГвйЪ6RЕ?It!ЅuЧ$Z>ГвN0эм ›>р­C5mгФЖкrN)Q ўС8л~№q˜‚ўя`§ћ}Ы†™BП!WІЧЬluХЊc“`N6У†mј†ѓ'Zєюq2^ŽGзвИ~+†LФИ>1ОЯ,§ё6ЯЇр>Ÿќ>Ђ”/CЂ:ХcŽЧH w‰б_Ц+.ŸGicx-™ˆЋчbAbЪтqж™2‰Ф†МЕ†жК`IќбcыЇMbљXУ[sЯѓŠЙ­9ЎlјSmЊ>UёВяХAX?фeŒъѓ#g}ВќОY3яvі†‡ёЫјuаlЌ_еŸ;e‡цА^HъБѕиr№ЁšjыЊŽMX•jТљйд †@ G€ўФЃˆl фч“д2rss‘ŒŒ lлЖ ћіэУЌC0kiHЕhаœfŸ_и šЮCI†ФzДИп4Д3БV6 ЎoG!тVЄЊ­Ѓ…љМЊЊЗЖЕ™ѕю=# ВЯ]Чžs&œЕЈ&m5ЧJ†C'1йMЂ€˜[•mеœIНїTаƒэHд[yUOЂ ж!>в˜ŽЉи‡Їъёšw+ч%Я%Š)™CЂсШ"#‘ЙѓˆdmcЮ+CšЌjXnкѕжPH-ЛЙЃ–.]ŠeЫ–Спп3fЬ€ЕЕ5,,,`ffH$Kђ‹ЩiJ‘r;Въ‰˜…Јj|и]†C@Ча#?nєд™‘˜З.Pё Щ))ХZQRё 2ŸrЇЭВЩvЪ“ [Yу‰ГzЇ1rџNр”!Зi]Й‰kкІ”…БХШ‘НОT'”!*ЛиHЊ…2Ф€дЪМ”ЁЊyIЬ„Ъэ-ЕБ"1”jЏ q36щzЉЭ‡4tбц#4“”!РhнД1ЖРDЗaиqх  xёр3гy€ЊMYhCcY;“єIЪ&DŸ–q]Љъ­ЉаЉ“gтз|ŸЛдД­ц8I№в­[ўДVЭЧБž ІA€Yˆšw6+C€!PGžwxžфXН&Кsw?аlR•iM:ї€Ц$bš˜дoY ›NacVг­Љњqch‹SˆДEŒѕg0t #`aЈЖ@Pg{ьШOЧдёlз mЖlљФe$шЬZЌ=‚-sЗщŒHЂКwU%rЄфцš}x=,!/Ђ‘š`Mžф]+ђSьн7’Яљe`@‚Z‚\šH4ъ)#pbфvЌšдБLŸЪЂ†OŽ3se0 ЙЦi|›P\6uЋC іџjuPБ3КŒ Ж8кЕП@ФПIšŽ(-2zГŸЃЛ OКQВѕЩvЙPОА5Е,ReШiѕлp˜ѕh™*BJeˆ*AWжнРЅOcАЩd'ЧЙААEŠъSJhŠAƒ-[;8СкоvЮvфcElFO&щ&"С[ˆ=БќкhдфдЈcX(ђ„‡Ј7ж†ЦЉЂ.Y8њС|ЎнK4Gc•[w2 љ;œСЦ^овkrH,хƒСѓБ'2См˜щСсHQeCЉ˜W|шgx7, 'ПбJ>-‡ОFћcј‹ЯђЙВ4ЧЪ FF€)D 8›Ž!Рh8FЙ>ЊiвюИcЊ-2кNЗЬКYwаь‚[ІъmЛДЅН…р~}TЈЄќP~Љiqїn"vэмUkіtї+.ъ"bЮ_Цхуб\~/iчОX1Г Q‚Ащмrј:ђўQ4_жœ!яС=тl\3?LћœЄГ ВmјС,]хŠяХц РbH(K Vє0kFЮЦу7?Сg;фЌ$Vъ%Ќ8ћ_GшсїqaыJљ‡*Q•ѓr№ѓG‡!:}„­—ЦУСX=XežpaФh ˜BдЈГ9 A@ЌЇ‡зн_MхЁ$ЙЂлcЈЖвhћѓх"Wп6M%›5ЅъСйЧY9ДNWКM–М№ПИџх(ЗЬ”V"zнП?.јgЯžЋг<{C6`йŒOёща`ь>“Jв?иСУг&.№ђvƒ•:аŠKЇ1yŒ'ŒyV=gСMь\•ЏЏњЃ­>œ|P8.Цё–ЅТœ.Ыќ’рЁ№єtтœži›зšэиЖx$›š!РЈh>ГРюƒБѓкя*цЗпУя ч1Те‡kыCbэŽ;ЊŠW$г/DŠQњ{yB"5TЋkSŠЈЯP(ЯIщ/Dk{БрХсoжт/н2ћwL&Л OЩу ЧMsЮ~шкУœk/o‘1&­‡B^ЧIЭTreЁœ I†јО§„J"m2В;Ч‹ћгV§oыЪy)HVwb‘’ЋГвЋАC щ` Qг?&C€!PЯМ@Žсџ“v WнQqІЩ]{Жu…“Й-I iHЂ\wУйъ8D m20ЎG;UџК/ЯР€~О€І’A˜Ы!“Ы  ўB?яР• ЇЙЉфE…(бв‡ˆ—QSэЉ\ъЊ$…ФHНUХѕ&ŠO)ь9Œ%ТэFpЙз‰ЬœУЖwEmЈ/!Оіџэ \TХоЧЫюТВМŠсMQQЛ.>bтk‰ZjVиЃuЕ7ГTъЂн’JЛљRZhІЉЉTh„‚˜( ШЂ ,<3чь]^–]и…Eўгчь9gЮЬfОkГ?ў3g†mП)^(ые­БФGD Nж;Ј2Kˆhўуx*ЙПB †šjlЪј*йFА<№5‰LУyз+(gУkіЙoрмoЙјђ‹Џp эŽ;ŸЮDnЮ”–ш Ћ’УУе E—ŠРгђЃДД•lbЕ-Я!*:Ÿ‹Тм|фeч ‡–OnvѓФЭєф2сеœAЏќщI?|Н2ŠЁgЛСчgd"ЏИйœf–…š7g‹y–ДљаVIЖ аВн/Яl]Ы)ФЕBiBЗ™yК!'@"‡#Іˆh>LЬЙc2о:§imё—nсг_ПСџА!Е.р›Ф^•ж$Њ1рD~&ЦжНn_УЖЩ*О››дзЗG­K‡>>.<~"r1JJJрщсЩо bž“}гjЊ™0а–ЂшъUк+І_6-СFAЄ@WцYй5 ›L*Д„ЭњгНГиŠDБ˜й-KŽ~ƒ™l)&ў–™фJW“{9ЦНќт‡EšH) тг ­РыЫДЦтќмјЯ‰%[j K˜…ЄшХї’qН$х9Фw›ЩІ{W х.dіњk–тг8ИW[К '@‚ШсˆЉ"@к‹РБЭ_љjгЁБ§ЙпCуŒ]ƒ„gŸgЎ­оgьzxР(­ас;Ж­Чw—2„7дfœ`Е ’ŒНžЦ^зВ!шЫЫQYiœИcM>U$дœDBЃi‡c]хwа•1g‘—“)б8QSЗ’лР(vU—SсЈWпХф•ЂGЩЭdХшh&ŒЬƒцqьўыoY Ц`СVŸХeѓ gЋ#ЉU<}ЌЋ9%хЄ3hW$ˆк?Nˆ€Ѓ Ь ˆ_Џ]РеђКЁ 8 IDAT˜-?эТђQѓ0Љ%SAФ7|}ўH2ЎшЎ™UK&Эq1‹ЕяЭ…œ6\U˘Oы+˜шрcj6.„ьšВ%WЉaПRьU[ВCИ• Dр& bТр/šћЭ$Mqy)Жe~‰.*/x+љЪ:uЁОЊ{тиЋOЮ|„]9Ÿ9ЖВNˆ@“ШCд$z@ˆР­B ?›/toŸ|С^Н—Тёќ_pтђЖ>‘8EŠwЦsNN ž™[GžŒ’усёUёНж\и[YlnвШ(Ђ2 {НЅхŒпеЉc Aд1О'Њ% ­$еo,Оg"шѓIЁ#ˆ!^зOЗxсбX?МП%— "рПc‚рзE …\†&ŠО<]†ЇŸИŒиХ•{7uывїKg"` 2Г…Ѕ%D УPИШ1’mькCРма/Ш ЕRЈО&д“mтъ‚ўСeа)ЪpSсŸˆ^иАо|ЦŽиVЊ3h/$ˆк‹<•Kˆ@›рНМxКMЫД[aь­}9ѓё2ђйжiЧЏ#№ŽLœˆаxtq…м[LbЊvўd Pђ5†Ў›oœлšZ 2Бѓэƒ(tтХЎ ЅVЌ§д”зaH9 -&DР”WUрНŸvуЭ>СJіz —ЏUЂ№f Њ LБp$ЛgЎЩ№ц;5xъY%Ndћ@ЉЌAЋwXы2зЭРDЭvмДЂ„МдЕа(#0І[$ЦљТЄiЩ8_7RifA—БйГcRdЊqlГЄа_ќЫc_GОГ}U…иЗц5,†;Нуч&кЪ[s#c†Шf ]м]ХМtзЎhАЙ]ёSсD€8’РЙыПунєџ˜эvяШђeћш‘ќ?TыФžѓЕxїѕХ/Х*ИоЎ`›йж яРМЙ…OwЬФъ€Љ X3ж_иэОЙvЊG"љЗy ю}ЮqФѕ‰Х??ОыэгHж іКsќ3ѓMhиjŒzЖMˆBэУ^ЭзcпœЩјzЪfЌzԘOЉdi}™јkФLEВї`dПoБЕђєЏ§­BЅO/Lš7 ‡ы ф q6ё=xі‰ФцЏ† HX‡Љ*MХXE€Œ=ЖЛ%9ХHzт ч_ФъЧ/р_яUРЧЛ5bH‡] –`ћзЧБ%r”рБ™1gђŒK#iO@rъY&SэБTL—ЭЧю im'-v/ˆЦЪф,ЁоўЃ1”‰!9ЛSїУјH]"хYX)›Žнgъ†вИШщбЯ~ўшдўўjd%ПŒЇRŠБkіC!{™ЅЂwŒЏИ}хШ~<#*дqMrfэі$њмSX6МAнѕйћ1oќZьKн&<лrJ }іAцбY‹У‡lАU~/є{хи…И№pЬXАGєd)КуОQ˜tяБ5ЗыЙ~ъЕWљ,’“іуš0ьg™Йљ?Кs4DŽ&Lі‰h7]TоxrиL<­šлŒЯT|l|мЙ\C5ЎуєўSH?t Чe bЁGdb4Ўшѓ6žœ‰ютwPС6њX4сi ољ.жЏžŠЯ}ПrБФФЪъоѓqvіЋјъїэ˜zёѕкКtХј>-ЫЂгДћmŒ є€AW€Дє,Мыi Аж–*г6<$xДцМšЬщЖцv]аѓЭsѓіV–]ТЗвQjœe‰ySсP-я!Z-2NˆА.fЦ…cаmНБ9§sфh/лЧp[Z‘е@ЉЈћБuсдВ8{‡ŠsUˆйЙKwНлpާ—^-%“БW§…+5ю{g ~J‰FLј”ЅŸРућгъe.ѕЙ‡БPГтоР‚ЩЂMЈ1їэП›UНYXГtzБЁІМŒxOћwЛиQmВйjЛVЬŠТ_{Я?f^@РhQE†\„j ћžYQOТ7qѕящS›Zсе•y„ЮЂ˜MbvЏ5^Јњ`юіiH‰NEЯWрб l'X“ ;Г#BуЙn#оZ4мЬ“b’LИTА­hп?ўN=a`ѕaэе])ЦLЎˆDШ qыW3ŒqХёј№)Ец{Хм_+†xОž=L§9|укHќбF[Щ ФЯ*sX[А –˜кИѕŠ ХRвF j E"pkГ]ыш7ƒйцЎ›3>Чх›ц{–9kЋЛњж`ќШК=чяŠр3y\•uCY5Wй$ъ;б§0_Џ_›ѓVєЇBьХЯ–coЦ=ˆlмЅЌ4qЁЯ"rУXЗ Д~ЮVн st#•7…ЁЌЭзЖcЈЙ6цљ4–ЏБ8Ёr–lБ xљ<&(Š!6Ј)Ж­‘g–нsKyш™§ а"ћ3%‹D€89о>нёмШG1ОWИ“зTЌ^FКб#n ЧЏE‰ЕqЖ4аЕЏяЧ€ЌBt—2:їzЌџFи`‹cqPѓО­9†џ{Ќ+^аМ`œјlРсUёlІO5ЦА‘ЎЌS™Ш<•Ќ\у€{E§№Ж}8_\чљсsˆЎdх#?7yйyШЫ-'JUC›_mUѓѓЄдƒюФdd#ё™TфБЕtХ…ШJЯ&7Ј~3–lЉobžЋ4=ТlзжЫ ЌЙtщ|О`љZN!Ў'œ7в^гт­gnš‹ЎA€‘#Ј’M"@œž€Ћ\‰‡C'b ›tЭпFsцАђБrЈ{ТГ_0ој‡шВ6ЮІvik˜€јгЛТˆs№uдп№ъвсFžPtuЎ їnФВ}Бjџ#№fƒaїЌ{3№тžњŠхзЃш—!]в„Y˜> 3Уч ёУlбNy^™НGЮK/W&ВАH3“zOСд~рЁо/В‰вю–0 g_ZŒqЪXЄзіМ3ЦЩ•ЎЂЗ†пЋњ#!ы5 кј"ІВЕFјнƒ'Ћ}Э4Ÿ1{]^cDmKЖ!>ЦЏNxї…(ОeV~ён& *jЊ№=†оƒш‰ŸCD кЫ_d&)Xd.%Ђs[еАаQD€tNМ‹ЉЊbыДАЁ†В2Же„N‡ввR”””ръеЋиДivьи…ЫcБ01Ж] щ*ѕј ѓKc{5fБИШ^C{д&qм;ф5Є\Tn(9zлzо"kтЌЏ [5­i˜Ъ<L€xw1YoФю) х:&Бм Vе хY.ФРМC7йЄ'žЧ|Юх|=mк–О” SV†[Ћ&ž8'ѓЦH8Sм`„!11+VЌ`"4 ѓчЯ‡ŸŸ|||рххИЙБя†r9ШДђ-Qђ9гЗLu!D ]Ј•n˜Їy ТІСSй`њpЛдЩДа—ЖКЃєєyA …Ю YgjЇЙыŠŒ*\еБz…к)ФЏЏ\ЅЖA 9 ютm1dй–›WkХЗЯ&В;!sБfяГUкЖѓсЂ"p+П}њuщїк‹Œ"у488иE№ ‰Uљ]8Yg}ѕнpџoн<ЌЯB)[I€˜З ]Г“‡ШЎ8Щ €›'ў>sMjеbŽƒўС}ряeэаTЧkЁѓе˜˜;гwB‚Ш™О Њ  NC`lр$Žž‡юl§"=л жбсѓ5{ёітMŽ.†ь"а2k E"@ќеОXЮD‘V/­‘ь8& …‚-щ8ћd™ЫHYцCO‰шф\и*О*ычеŒ.НІnИП M@IЉДYЊmy›Km(ШФчŸ`дМЛсяlН~•ZЖnP•Т ~N№V[s,щљ­KРйўзИuISЫˆpе†ъfыт"oљŒ‚ нšЕ_?юnоdЏ‹[ј.ъю ћwIYјЩкw ЉЗЌ’ўтXћ)о„ ЂzЯЄМэqЮK]‹Љб)ЕEwzўѕ(њ8Qk+GЗ<DЗќWL $DР”@uu5Nn;…J]нJЩІЯљЕЪW…Ё3‡дЖљ~Чv1ЫДшКЌyЩХu7ь*№QqŸ‰7nЂRoЫ–ьyЖззу{Ж#Zу }%o ~LLфm{Б…у“SФ=Ф”JЖ /иЉ[нzЮd|=e3V=вGЈ‡*p$’›‡Ар.ачG\ŸXќѓуЛБюQёy;V–Šю„Zў'P'„EM&D уpaћ™ѕелbCњŽm§2C/§=о~Э…$†ИњiэYœ|1oxlъRQQJƒСbНъ?ф‹7ћѕ„_€?КugG2vbъlЖ}ХЮ8DШЂБ=CœџФWGОrd?ž‘ …F6k’3kWqŠБяK„јaВ%и—! нщА;іYlн{ыУ"0!l[}Y‡] –`ћЁ ь\-ф™З љхRэЗ••ќ2žJ)ЦЎйa„ьya›џˆбЪФЏMн; у#=PTpC2Dg"аІHЕ)n*Œg р||zŠ;ІзЏЯm§ЛТ7 nЧїњЯ[zЯEtpW .уТ…lлК­Ѕ&СG–2œ@њБS8ѕеqaП0uПсHzЌ?“?1xушJŒщ)ЎжЬїпZ4сi ољ.жЏžŠЯ}…mСgqpќ#qU_|јћ>МЙˆзЌЧyЃ­ђђ!Ќžђ8Ўџя xyЫXЖй+Puх$’юšƒЯzўЩ{–тћЯcя\D5mЋGdb4Ўшѓ6žœ‰юЦPY.є{ŸVŠЭmb}6&@Cfm œŠ#DР9єг?|є#иFZЕAюъ‚ AЕї­ЙрУd;žyM0! ™I"љйРЯАwЯ(/gЎ•i-/щ“иuјqp dйаl§ l8J3Д'<4Н1,"T2г]э'ќQCНa9,ћBŒ,џ[Wbи†бИMЉ€я˜qЬД'2џ†>ƒйJЪкjaзњ„к]ыuBмАе›Бi)пЮD‡јСЏcяБп17Œэќб„­шС!ае gЧ„Бњѕ7kА>ї0jV`@мX0ЙЛй3К!mE€Q[‘Іrˆp*ю>юdТ!я„Q-Акѕо njqS{T– !A%‹жЄљBќюlFˆё-§фCfOOСьСц{vUAv2€sE$B‰^1}Ѕљћ§|Г’нБAšщVr•b­*иŽѓУG™‹D7aЪРКjпV7иаД-л%ž•Ћ7ŸЛЅ;Г#BуЙn#оZ4\œѓTg™Ўˆ@› AдfЈЉ "@œ@@XwќZНVлT&|јоє3ЖяAТŒњоqўQ…0aлмvcqжи2ГRš‰ИаgдКZ”Y К!mF€Q›ЁІ‚ˆp6r…}ЧєFцžГш{WЋwХnЎЙoр\—\”Бб]]]ЁVЛУУгžlnOЖЗ‚•ысІFбЅ"№Д<+KQЩ&VлјЂЂѓЙ(єіEy•шyёa“ЌСЖЙ™žƒмBBќ›йБо+zвOGЏС]щ йп зВrQе3т pVUIЈysƘgI›_mUМйЏЯсUёlfS5тйZжЉLTБџ]ƒб?Ј™:[U#JDl#@‚Ш6^”š[Œ@іЋ?pRМќ=эвВCь<Й%%%LyВŸ|ц™Љa‡1дАWџЕкR]НŠC{ХєЫІ%и(ˆш 6EЭТ&Щ0;/aѓ„ўtя,Ж"Q,fvKС’Ѓп`&гќ-3)Ш•Ў&їrŒ{љФ#‹4‘RФЇ@Ќ/г‹ѓsу?'–lЉ1,a’ЂcмK|НЄu(њЅ@(/iТЌкrЏўЖ.e“—(6& ЋaЁЫЄтˆшDxSХМ•••(++ƒNЇCiiЉ Ў2AАiг&ьиБ —ЧbabНёЅNФщЩЩKЁН~›nДOЋља\syЙ ЏЕ[cT_Ъ†ђXB7/ЕеyšВл”-CЙz6SH­ЂMd›bGё– FБbХ DEEaўќљ№ѓѓƒ̘жƒybнмм„C.—[эљ%‘eює”"а&.фф@Яп8ГW`[aЈљ˜š  !{…ІlЩUjиЏ{е–ь€§+ D€8OЮ|фЕ *ЮK€Qч§юЉхD€t995xfn5yx0JއЧWAЦїZsaoŒБ!Щ‘Q D?d@ї€zouіQ5‰€3 Aф пе"`РЇ[М№hЌоп’Ы№п1Algx%rj˜(њђtž~т2bWbьнд­[@Iˆ@“ъVгj2 = D€і$№7є r‡B­ЊЁ ѕd›ИК 0›ЄЎ(УM… |"zaУzѓлГЮT6шhHuДoŒъKˆ@ч#Ро–3o!у!ŸmЇ‘vќ:я(РдЩљˆ-GWШНEС$ІjчOі–›ЖАзŠХХэQCA&vО}…ц‹]лУtыm8 Н­ЏYА… "[hQZ"@ˆ@;И|­…7йђq•”#й•8sM†7пЉСSЯ*q"лJe lХmG…Ьu30QГ7­( /u-4ЪŒщ‰q~Ѓ0iZ2Юѓ}F КŒаШ†˜“"Sйi ƒўтXћ:ђйrЮliяŒm"›tqwgjFЇЏ ЂNџO€"рьŽ)СІCzTыј*AмCd€w__ќRйэpu“#яРМЙХdЇZ;7*`jж$vЛoЮД*p$’KУ5ЇqєќF мЙџќј|й*и"‘§Б>sќО_фьAЪGїБWѓѕи7'qлLђ)•,­/M˜jƒhCі —=‹,/•-эѕь‰Э_­DЊ *KEиD€‘MИ(1 D АžZщС>Œ=ЖЛ%9ХHzт ч_ФъЧ/р_яUРЧЛ5o™щАkСlџњ8ЖDŽ<63цlCžqi$эщHN=Ыd  =–ŠщВљиЁ5Таbї‚hЌLЮю§#FchpaqGuя0Œє@Qб%Rž…•Вщи}ІЮФEN~ў№ №Gї ю№gлd%ПŒЇRŠБkіC!{™ЅЂwŒЏИ}хШ~<#*дqMrІА˜$/XŸ{ kТ†7ЈЛ>{?ц_‹}Љл„g[NiЁЯ>ˆХakqј ЖЪЯу…~ЯЁЛŽ іž,[кЋП|ЩIћqMT–™свЉ j#аT  D ЅdlўЛ'[qз8‰HЭц Ъ+сЃЎ‚ЇJєЕдЖiОЊ+'‘4с1ф=М Щ{VР;e-–ФGyQ:~ўЯ%&яˆћ0/& ‰šе‚Ї$?u=6іDєє~Іц„k}Ц^ФЇ•"Bs›ё™ €{нJееИŽгћO!§а)?”)ˆ…‘QˆбИЂWЬsиxr&zИ‹bЏ‚э~ЖhТгМѓ]Ќ_=џžћ ~хb‰‰•еНчуььWёеял1ѕтыЕu7шŠё}Z –EЇ!iїлшƒЎiщ)Xxзг`­-UІmxH№hЭy5™ в!lЭmѓа\{+Ы.слщ(5z˜,17ЗLwŽ&@яg:š0й'D€Д–€ЌJ…ш!сІ\ЊйЏ)‹ГwЈ8W…˜{АєAqзћИ №чияpщхбBQ2{е_ИRуОwЖрЇ”hФ„_AYњ <О? Ё^ц*}юa,дЌР€И7А`ВhЊ@Ь}ћяfUЏFж,]…^lЯЗМŒxOћ‹Ш `н‚ањ9[u_ 6Љž Vо†В6_лŽЁцкL№,5–ЏБИfmБMŠљ<&(ыФZйоІ˜З eЖ™Э!Вe D€Д-ŒtЂGмŽ_‹kуlЉЉk_9оџY…:ш.e uю!єX1ў ŒА7РЧт ц)|[s џїXWМ yС8ёй€УЋтйLŸjŒa#]YЇ2‘y*YЙЦЏЊBоЖч‹ы“Š<Жі‘ЎИYщyТ$№еo&Т’-ѕэAЬЋ“†ЃG˜mЁ^ЖЗзДxы™›цЂkG AфЊd“"`G++‡КW <ћуˆо!kуlЊ†Ж† ˆ1Нл(Œш1_G§ Џ.n4с EWWсКpяF,лиЋі?o6vЯКw1_ юЉЏX~=Š~)в%M˜…щсГ03|?Ьэ”с•йKqфМфёreв) ‹4S0ЉїLэїъ§"›(эŽa ГpіЅХЇŒEКq#С;cЌ‘\щ*zkјНЊ?В^У /b*[ћh„п=xbёБк7аLѓГзх5FдІБd+`тc|№ъ„p_ј‡Ьћdk{љЫ‚ЬУ$‹ЬЅDtn ВкЂ *ƒЮI€w1UUUЈdC eelЋ ЅЅЅ())СеЋWБiг&ьиБ —Чbablч„дLЋЙwШkHИЈмPrє ЖѕМEжФ5cкфБ[5­i˜j€– я.Ц!0“Tm}i(ч’У jUнPžх:˜wˆ-щЮѓ˜ЯВœЏБЇMлв—2aЪЪpkеФчdо gŠŒ0$&&bХŠˆŠŠТќљѓсччxyyСУУnnьЛa‡\ЮоЮ”™ oZhyˆ,РЁGD€g №вVw”ž>/ˆЁаЙ!B•ЌГЅўUИЊc?є ЕSˆ!^wЙJmƒr@нХлbШВ-7ЏжŠ!nŸMЊvBцbЭ:пgЋДmчУE-&DРžЌ§ЫЭževD[СС.‚WHЌћяТЩк8ылы†ћћш&О­e}>JйrФМхьФœіьCHЕіл ќD€4K ~Ї%нKчf P‚6 ‡pŸ6(‡ŠЈ#@ЬыXДќŠї#ѕћ’њїжX'Ad %JCˆ@ЋH“tцЦLЏљ}7ќ|n"@ˆ@k H§‹tЖЦЭ!В†Ѕ!DР.xч$uPвЕto—Ш Š€i?тттRлПДyˆZBђ"`3Iј№3яИјСпсg8 М9bГaЪ@ˆ@Ї#Рћ Lћ~- $сЁ$ˆlFЩ‰h9ЉГт—д‘yzŠkВT&ul|AЕiгІAЋетЦТТхххЈЈЈЈF$ˆZŒ2MРДПр"ШннjЕмГЬaф‹1ђ?Ќx" Сѓ<- $ˆZBђ"`5S!ФџŠ3§+Яее*•J№ qМSуїёЎyМ$ˆЄГе…SB"@:,Љяў€т§…$ŠИ0тПч‡Љ(jЉ0"AдaџЉPХ‰@Ч#`њзFМ#“†ЧЄgМгу$ˆЊЋЋkQЧk1е˜жњIё>ƒџХћ>ˆ{‹xŸСоЇаЂжаІМD€8œядЄU1”xзIDAT1~Љcу˜4OHzЮуxgЧ‡ЫЄg’ "яУП&*€8 о'HїRПС=AМŸр‚HF\$I‚ˆЇ“њS’-KgђYЂCЯˆАо9ёЮŠ оЉё3R<џыNš7Ф‡ЪјСгH‚Шn!CD€tМрG:’ тgЩ[d*ˆZу%"AдaўYPE‰@Ч' ulМ%І‚ˆЧѓŽ‹ iMš;$Ѕыј­Ї"`+ЩЫ#ѕ\№pqd*ŒИwˆпKЯx)Ÿ-х‘ В…Ѕ%D EЄПђИИсМуёМsу‡ЉWˆ‹!ž–4Tж"ф”‰м2Єўƒїќ„?ѓƒ‹!k) ЯУ[ "[hQZ"@ZE@@’~Я…$ˆ$$ !.†HIДшL:'Iм№Г$xxŸ!‰#~цїROз’ cMMK2R"@ˆ€­$#%d:<&=“ЮЖ–Aщ‰ИѕHЂˆЗLEќЬу%!Фяy0M+DXљA‚ШJP”ŒћрB‡.†x„ф’т„‡ьCJ'нг™ЮC@ђід9вН$ŠЄt’(j !D-ЁFyˆh5IqC‰гч­.Œ "pK„oŒt-‰Ѓж6Qk R~"@ьF€DнP’!"pЫ„НH“ЊэM”ь"аbŽъшZ\!ЪHˆ@Ї! Ю@ъ4ЭЅ†"@ˆ D !D ™P  D€"аЩ ъd_85—"@ˆhH€QC&Cˆ D€t2$ˆ:йNЭ%D€"@ Aд Х"@ˆ Œ ЂNі…Ss‰ D€†H5dB1D€"@ˆ@'#@‚Ј“}сд\"@ˆ D !џ^Ё|9!ѓIENDЎB`‚fwbuilder-5.1.0.3599/src/res/help/en_US/pf_Branch.html0000644000175000017500000000051311733011756023066 0ustar sylvestresylvestre

Rule Action "Branch"

This action is used to create a branch in the rule set. For PF this is implemented using anchors. To use this action, create new Policy rule set object, then drag and drop it into a well in the dialog of this action. Note that you can use policy rule set object of another firewall as well.

fwbuilder-5.1.0.3599/src/res/help/en_US/linux24AdvancedDialog.html0000644000175000017500000001550111733011756025262 0ustar sylvestresylvestre

Linux 2.4/2.6 kernel settings

All of these parameters are controlled either with sysctl command line tool or via /proc file system. See file ip-sysctl.txt for description of these parameters, and more. The file can be found online for example here

IPv6 related kernel settings are documented here:


Tab Options

IPv4 Packet Forwarding

Enable IPv4 forwarding between all interfaces

IPv6 Packet Forwarding

Enable IPv6 forwarding between all interfaces

Kernel anti-spoofing protection

/proc/sys/net/ipv4/conf/all/rp_filter

  • 1 - do source validation by reversed path, as specified in RFC1812 Recommended option for single homed hosts and stub network routers. Could cause troubles for complicated (not loop free) networks running a slow unreliable protocol (sort of RIP), or using static routes.
  • 0 - No source validation.

Ignore broadcast pings

/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

If set to true, then the kernel will ignore ICMP echo requests sent to broadcast/multicast addresses.

Accept source route

Accept packets with SRR option.

Accept ICMP redirects

Accept ICMP Redirects.

Ignore bogus ICMP errors

/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

Some routers violate RFC 1122 by sending bogus responses to broadcast frames. Such violations are normally logged via a kernel warning. If this is set to TRUE, the kernel will not give such warnings, which will avoid log file clutter.

Allow dynamic addresses

/proc/sys/net/ipv4/ip_dynaddr

If set, enables support for dynamic addresses.

Log martians

Log and drop "Martian" packets. A "Martian" packet is one for which the host does not have a route back to the source IP address (it apparently dropped in from Mars).


Tab TCP

TCP FIN timeout

/proc/sys/net/ipv4/tcp_fin_timeout

Time to hold socket in state FIN-WAIT-2, if it was closed by our side. Peer can be broken and never close its side, or even died unexpectedly. Default value is 60sec. Usual value used in 2.2 was 180 seconds, you may restore it, but remember that if your machine is even underloaded WEB server, you risk to overflow memory with kilotons of dead sockets, FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1, because they eat maximum 1.5K of memory, but they tend to live longer.

TCP keepalive time

/proc/sys/net/ipv4/tcp_keepalive_intvl

How often TCP sends out keepalive messages when keepalive is enabled. Default: 2hours.

TCP window scaling

/proc/sys/net/ipv4/tcp_window_scaling

Enable window scaling as defined in RFC1323.

TCP sack

/proc/sys/net/ipv4/tcp_sack

Enable select acknowledgments (SACKS).

TCP fack

/proc/sys/net/ipv4/tcp_fack

Enable FACK congestion avoidance and fast retransmission. The value is not used, if tcp_sack is not enabled.

TCP ECN

/proc/sys/net/ipv4/tcp_ecn

Enable Explicit Congestion Notification in TCP.

TCP SYN cookies

/proc/sys/net/ipv4/tcp_syncookies

Only valid when the kernel was compiled with CONFIG_SYNCOOKIES Send out syncookies when the syn backlog queue of a socket overflows. This is to prevent against the common 'syn flood attack' Default: FALSE

Note, that syncookies is fallback facility. It MUST NOT be used to help highly loaded servers to stand against legal connection rate. If you see synflood warnings in your logs, but investigation shows that they occur because of overload with legal connections, you should tune another parameters until this warning disappear. See: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.

syncookies seriously violate TCP protocol, do not allow to use TCP extensions, can result in serious degradation of some services (e.g. SMTP relaying), visible not by you, but your clients and relays, contacting you. While you see synflood warnings in logs not being really flooded, your server is seriously misconfigured.

TCP timestamps

/proc/sys/net/ipv4/tcp_timestamps

Enable timestamps as defined in RFC1323.


Tab Path

In this tab you can set path to the system command line tools used by generated iptables script. Use these if tools you expect to use are located in non-standard directories (such as "/usr/local/bin", "/use/local/sbin" etc.) Leave these blank if tools you expect to use are in standard system directories.


Tab conntrack

In this tab you can adjust parameters of the conntrack module to tune its performance. This is useful for firewalls passing a lot of traffic but probably is not necessary in most cases. See http://www.wallfire.org/misc/netfilter_conntrack_perf.txt for the detailed explanation.

You can adjust the following parameters:

  • CONNTRACK_MAX is the maximum number of "sessions" (connection tracking entries) that can be handled simultaneously by netfilter in kernel memory.
  • The hash table contains HASHSIZE linked lists. When the limit is reached (the total number of conntrack entries being stored has reached CONNTRACK_MAX), each list will contain ideally (in the optimal case) about CONNTRACK_MAX/HASHSIZE entries. The hash table occupies a fixed amount of non-swappable kernel memory, whether you have any connections or not. But the maximum number of conntrack entries determines how many conntrack entries can be stored (globally into the linked lists), i.e. how much kernel memory they will be able to occupy at most.
  • "Disable TCP window tracking": this is needed if you run conntrackd daemon in state synchronization mode for a firewall cluster and have kernel < 2.6.22. See http://conntrack-tools.netfilter.org/manual.html for more details.

fwbuilder-5.1.0.3599/src/res/help/en_US/iptables_Route.html0000644000175000017500000000036311733011756024170 0ustar sylvestresylvestre

Rule Action "Route"

This action makes the firewall route the packet that matches the rule through an interface or a gateway specified in the parameters of the action. This action is translated into ROUTE target for iptables

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.0.0.html0000644000175000017500000013514411733011756024564 0ustar sylvestresylvestre

Firewall Builder 4.0.0 Release Notes

Changes in the GUI

The editor panel and object tree are now detachable. You can "float" these windows and rearrange them on the screen any way you want. There is only one editor panel even when you open several data files at the dame time. Each data file is opened in its own project window with object tree and rules.

Selection of the object in the tree or rules does not automatically open it in the editor anymore. Use double click or context menu item "Edit" to open object in the editor. This helps, for example, when you need to populate large object group and need to switch between libraries to find objects. Switching to another library or accidentally clicking on a wrong object in the tree does not cause editor to switch.

Full implementation of the "undo" facility for all operations in the GUI. You can also monitor undo stack in the "Undo stack window" that you can open using main menu item "View/Undo Stack".

Behavior of all object dialogs has changed. According to the results of the user community opinion poll and discussion, object dialogs are losing button "Apply". All changes made in dialog entry fields are saved into the object immediately. This does not change the data in the .fwb file, only objects in memory. Combined with Undo, this allows for faster object editing and roll back of changes.

"Single rule compile": After you select a rule in policy or NAT rule set, you can compile it and see the result in the editor panel immediately if you hit "X" on the keyboard or use context menu that appears if you click right mouse button. The result is shown in the editor panel immediately. To select a rule click anywhere in it (any rule element, not just rule number).

Error and warning messages generated by the policy compilers are highlighted using red and blue colors in the compiler output panel when you compile single rule. When you compile all rules of the firewall using toolbar buttons or main menu items "Compile" or "Install", errors and warnings are also highlighted in the dialog. Clicking on the error or warning message opens corresponding firewall and selects the rule that caused it.

A new "Filter" input field is located above the object tree. Typing fragment of the name in this field automatically limits set of objects shown in the tree to those that match what was typed. The filter maintain history of strings entered in it for the duration of the session.

Right above the panel showing rules there are now two new buttons. These allow you to compile and install policy for the firewall object shown in the rules panel at the moment. The same functions are available via context menu associated with the firewall or cluster object in the object tree, but these buttons are easier to use.

The GUI can show brief summary of object attributes in the second column in the object tree. This is controlled by a checkbox in the global preferences dialog, tab "Objects". This is off by default. The first column always shows object icon and its name, the second (optional) column shows its attributes. Interface label is shown in the second column. The width of both columns in the tree is set automatically to accommodate all the text, then can be adjusted by the user using mouse. Column width is saved in settings and will be restored upon program restart. Column width is saved per-file, per-library.

Now you can change IP addresses of interfaces of the new firewall created from a template. Templates come preconfigured with some IP addresses which probably do not match addresses used on your networks. When you create new firewall object from a template, the "new firewall" wizard includes interface editor page where you can change addresses and interface types (static or dynamic). The program not only changes addresses of interfaces, it also scans policy and NAT rules of the template looking for network objects that match original template addresses and replaces them with network objects that match new ones.

"Add object to a groups directly from the group dialog". Group object dialog now has a button that shows a menu when clicked, this menu allows you to create new object and add it to the group in one operation.

Password caching: Built-in installer can remember firewall password (and enable password for Cisco) for the duration of the session. Passwords are never stored permanently in any form, encrypted or plain text, they are only kept in memory of working Firewall Builder GUI instance. You need to enter password once when you activate generated policy. If you keep the program open and need to modify and activate policy again, the password fields in the installer dialog can be filled automatically. The feature is optional and is off by default. Cached passwords are associated with the firewall object and account name used to activate policy. To use this feature, turn it on in Preferences and configure user name used to authenticate to the firewall in the "advanced" settings dialog of the firewall object. Warning: using this feature creates certain risk if working Firewall Builder GUI is left unattended on the unlocked workstation. Someone may walk up to the machine and make changes to the firewall using cached password of the administrator who used the same GUI session before. Always lock the screen or exit Firewall Builder GUI when leaving computer.

The program supports new types of interfaces: VLAN, bridge, bonding. This is fully implemented for Linux and partially for other platforms. VLANs are added as child objects of an interface, like so:

The GUI checks the name of the vlan subinterface against naming convention for vlan interfaces on the chosen OS. For example, both "eth0.100" and "vlan100" are supported on Linux, while on Cisco IOS or PIX it should be "FastEthernet0/1.101"

See below for more details on the bridge interfaces implementation.

The program can generate commands to configure vlans, bridges and bonding interfaces on Linux. This is off by default and controlled by checkboxes in the "script" tab of the firewall object dialog. Generated script adds and removes vlans, bridges, bridge ports, bond and bond slaves incrementally. That is, the script analyzes existing vlan interfaces and compares them with vlan interfaces defined in the Firewall Builder GUI and then adds new ones and removes those that do not exist in fwbuilder. The same algorithm is used to create bridges, add or remove bridge ports and create bonds and then add or remove slave interfaces.

Configlets: generated firewall script (for all platforms) is assembled from small fragments we call "configlets". These fragments are located in the "/usr/share/fwbuilder/configlets" (on Linux). Each configlet is a template that uses specially defined macros which the program replaces with actual strings and values when it generates firewall configuration. There are separate templates for different firewall platforms and for different parts of the configuration file to be created. Supported macros include simple variable expansion and conditional "If - then" construct. You can override configlets we provide with your own if you create directory "fwbuilder/configlets" in your home directory and place files with the same name there. You need to retain the structure of subdirectories inside this directory, that is, the directory should be "$HOME/fwbuilder/configlets/linux24" for the configlets installed in "linux24" subdirectory under "/usr/share/fwbuilder/configlets". This way, you can change virtually all aspects of generated configuration file.

Built-in policy installer gets commands that it needs to execute on the firewall from configlets. Two configlets are used for Unix-based firewalls (Linux, OpenWRT, DD-WRT, Sveasoft, IPCOP and its variants, OpenBSD, FreeBSD, MacOSX, Solaris): "installer_commands_reg_user" and "installer_commands_root". You can change the behavior of the installer without having to touch C++ code, just create a copy of the configlet file in $HOME/fwbuilder/configlets and modify it.

Terminology for policy rule actions that create branching in the rule set or tag packets has been unified. Now we call these actions "Branch" and "Tag" for all platforms. Before, the name was different and matched original action on each platform, that is for PF it was "Anchor" and "Tag" and for iptables "Chain" and "Mark" respectively.

"Find where used" function can now find all uses of the given object, as well as all uses of its children. For example, if the object is firewall, then this function can find all groups and rules that refer to it directly, or to it and all its interfaces and their addresses. This extension is optional, it is controlled by a checkbox in the "Find" dialog.

Added a place in the global Preferences dialog for options specific for different object types. First parameters include options for DNSName and AddressTable to let the user decide if the newly created objects of these types should be automatically configured with "Compile Time" or "Run Time" mode. Also, added an option that makes DNSName object editor copy the name of the object into the DNS record input field when new object is created or whenever the name changes. This is useful when the user does not want to keep object name and dns record different because they need to enter the name only once.

"Batch install" checkbox moved to the page that shows compiler progress so the user can decide to do batch install right before they perform installations instead of doing this before they start compile.

Standard objects library now comes with new IPv6 Network objects. These objects represent IPv6 networks that should not be routed on the Internet. Included: RFC3849 "Documentation Network" 2001:db8::; RFC4291 "Link local" fe80::/10; RFC4773 "Experimental Network" 2001:0000::/29 to 2001:01F8::/29. Also added a group "ipv6 private" that includes all these networks.

Added GUI elements to support IP option "router-alert" which is now available as an attribute of IPService object.

Changes in the Standard Objects library

Standard objects library now comes with new IPv6 Network objects. These objects represent IPv6 networks that should not be routed on the Internet. Included: RFC3849 "Documentation Network" 2001:db8::; RFC4291 "Link local" fe80::/10; RFC4773 "Experimental Network" 2001:0000::/29 to 2001:01F8::/29. Also added a group "ipv6 private" that includes all these networks.

Added address objects for standard multicast groups: all-hosts, all-routers, all DVMRP, OSPF, RIP, EIGRP, DHCP server / relay agent, PIM, RSVP-ENCAPSULATION, VRRP, IGMP, OSPFIGP-TE, HSRP, mDNS, Link-local Multicast Name Resolution, Teredo.

Common changes in all policy compilers

All compilers issue a warning when the firewall has no top level NAT or Policy rule set. Top rule set is used to generate iptables rules in the built-in chains INPUT/OUTPUT/FORWARD or the rules in the main PF configuration file (not anchors). If the firewall object has other not-top Policy and NAT rule sets but no top rule set, packets will never reach any rules. However there are legitimate cases when administrator may want to use fwbuilder to only generate iptables commands for a custom chain or configuration for a custom PF anchor, in which case this is not an error. Compilers generate warning for this condition to bring it to the attention of administrator but continue processing the rules.

Support for High Availability configurations

Test data file cluster.fwb with examples of different cluster configurations is available for download here.

New object type "Cluster" (located under Clusters in the tree) represents the HA pair. You configure policy and NAT rules in the rule sets of this object rather than in the actual firewalls.

Here is what you need to do to set up HA configuration:

  • Create your firewall objects. Assign platform and host OS and name interfaces as usual. Do not add any policy or NAT rules. These are your real (member) firewalls. Interfaces should have their real IP addresses (not CARP or VRRP addresses).
  • Create a Cluster object which you configure with proper platform and host OS. Use the usual "New Object" menu or toolbar button to create this object. Note that in order for the firewall object to become a member of a cluster, their platform and host OS settings must match.
  • The program guides you through the process of creation of the new Cluster object using wizard-like dialog. You start with the list of firewall objects where you choose which firewalls should become members of the cluster. Next, the program finds interfaces of the member firewalls that have the same name and can be part of the cluster and creates cluster interfaces with the same name. Not all interfaces are eligible, for example bridge ports, bonding interface slaves or parents of vlan interfaces can not be used for the cluster. Cluster interfaces define failover groups. You can add, remove or rename cluster interfaces, as well as change which interfaces of the member firewalls are used with each one. On the next page of the wizard you can change failover protocols and add, remove or change IP addresses of cluster interfaces. Not all failover protocols require IP addresses, for example VRRP or CARP do but heartbeat or OpenAIS don't. Finally, you can choose to use policy and NAT rules of one of the member firewalls to populate Policy and NAT rule sets of the new cluster. If this is done, all references to the original member firewall and its interfaces in rules are replaced with references to the cluster and its interfaces. The program also creates backup copies of the member firewall objects with the name with suffix "-bak" and clears Policy and NAT rule sets of the member firewall objects used with the cluster before new cluster is created.
  • OpenBSD or FreeBSD cluster gets carp interfaces. Name them "carp0", "carp1" or whatever indexes they have on your machines. You can add CARP password and ID at the same time, but if you don't, you can add them later.
  • If you use heartbeat or OpenAIS (on Linux) for failover, cluster interfaces should have the same names as corresponding member firewall interfaces. In this case, cluster interfaces are virtual entities that represent interfaces of the corresponding member firewalls. The program will make substitution when it compiles rules. This is also how it works for PIX failover configuration.
  • Each cluster interface has child "Failover group" object with the name "firewall:carp0:members" or similar. This is where you configure associated member firewall interfaces. Double click this object in the tree and then click "Manage Members" button in the dialog. Select interfaces of the member firewalls in the panel on the left hand side and click arrow button to add them to the list on the right. Use checkbox to select master. Click OK when done. The platform and host OS of the cluster object and members must match, otherwise firewall objects do not appear in the "members" dialog panel.
  • Besides interfaces, the Cluster object has a new child object "State Sync Group". This group represents state synchronization protocol. Currently pfsync is supported for OpenBSD and conntrackd for Linux. To configure, double click it in the tree to open it in the dialog and click "Manage Members". Select interfaces of the member firewalls in the panel on the left hand side and click arrow button to add them to the list on the right. Use checkbox to select master. Click OK when done. They should appear in the "members" table in the State Sync Group dialog. The platform and host OS of the cluster object and members must match, otherwise firewall objects do not appear in the "members" dialog panel.
  • Button "Edit protocol parameters" allows you to edit some parameters for chosen failover protocol. This is where you can configure an address and port for heartbeat and OpenAIS.
  • There are few new checkboxes in the "Script" tab of the firewall object dialog. These allow you to control whether the program will add shell commands to create and configure bonding, bridge and VLAN interfaces.
  • Compile by clicking right mouse button on the cluster object and using menu item "Compile". This will in fact compile each member firewall separately so you'll get .fw and .conf files for both of them.
  • Again, you configure all the rules in the policy and NAT rule sets that belong to the cluster object. If you put cluster's interfaces in rules, the program replaces them with interfaces of the member firewall when it compiles rules. If you put cluster object in a rule, it is like if you put member firewall object there instead, except the program automatically picks the member firewall it compiles the policy for.
  • First, the program looks at Policy and NAT rule set objects of the cluster and member firewalls and compares their names. If there is rule set object with the same name in both the cluster and member firewall and both have non-zero number of rules, the rule set object from the member is used and the one from the cluster is ignored. The program prints a warning message when this is done. If rule set objects with the same name exist but the one in the member firewall has zero rules, it is ignored and the one from the cluster is used (no warning is issued). Likewise, if there are rule sets with the same name but the one in the cluster has zero rules, it is ignored.
  • Here is what you need to do if you want to have most rules defined in the cluster so they will translate into rules for all member firewalls, but have some rules defined in the members so you can make configurations of the members slightly different:
    • Create separate rule set object in the cluster and in each member. Use name different from "Policy" or "NAT". Lets use name "member_override".
    • Create a rule with action "Branch" in the main Policy or NAT rule set of the cluster, drag rule set object "member_override" that belongs to the cluster to the well in the Branch action parameters dialog.
    • Leave "member_override" rule set that is a child of the cluster object empty (no rules)
    • Add rules to the rule set "member_override" in each member firewall
    • Make sure rule set "member_override" is not marked as "Top ruleset" in the cluster and each member. This rule set translates into user-defined chain (iptables) or anchor (PF) and should not be the "top ruleset".
    This method works for both policy and NAT rules for all platforms.

Cluster configuration for PIX

Firewall Builder supports PIX "lan based" failover configuration. Unlike in Linux or BSD, where each interface of the firewall runs its own instance of failover protocol, PIX runs one instance of failover protocol over dedicated interface. PIX can also run state synchronization protocol over the same or another dedicated interface. These dedicated interfaces should be connected via separate switch and do not see regular traffic. Here is how this is implemented in Firewall Builder:

  • Like with all other supported firewall platforms, interface objects that belong to a cluster object serve to establish association between actual interfaces of the member firewalls. Cluster interface object should have the same name as corresponding member firewall interfaces. It should have Failover Group child object which should be configured with interfaces of the member firewalls. You can create Failover Group object using context menu item "Add Failover Group", the menu appears when you right mouse click on the cluster interface object. Here is an example of correct interface mapping between cluster and member firewalls:
  • The Failover Group object "cluster1:e0.101:members" is configured with interfaces "Ethernet0.101" of both members:

  • Interface that is configured for the failover on the member firewall should be marked as "Dedicated Failover". Use checkbox with this name in the interface object dialog to do this.
  • Cluster interface that corresponds to the failover interface of the members should be configured with protocol "PIX failover protocol". Click on the "Edit protocol parameters" button to edit timeout, poll time and the key.
  • Cluster interfaces that represent regular interfaces of the members also must have failover group objects; that is where you add interfaces of the member firewalls. There is no need to configure protocol in these failover groups because PIX does not run it over these interfaces. Regular interfaces should not be marked as "Dedicated Failover".
  • Cluster object should have State Synchronization group child object. Create it using context menu "Add State Synchronization Group" item if this object does not exist. In this object you need to configure member interfaces that should be used for state synchronization. You can use separate dedicated interfaces or the same interfaces used for failover. If these are separate, corresponding interface objects of the member firewalls must be marked as "Dedicated Failover".
  • One of the member firewall interfaces used in the State Synchronization group must be marked as "master". This is where you define which PIX unit is going to be the primary and which is going to be the secondary in the HA pair.
  • Here is an example of the state synchronization and failover using the same interface Ethernet2:

    The State Synchronization Group object "State Sync Group" is configured with interfaces "Ethernet2" of both members:

  • Dedicated failover interfaces of the member firewalls must have IP addresses and these addresses must be different but belong to the same subnet.

Built-in policy installer treats PIX clusters in a special way:

  • For the PIX cluster, built-in installer installs generated configuration only on the master PIX unit. It determines which one is the master by looking in the StateSyncGroup object (state synchronization cluster group).
  • Dialog where user enters authentication credentials and other parameters for the installer has a checkbox that makes installer initiate copy of the configuration to the standby PIX if installation was successful.

Changes in the support for bridging firewalls

Skip this if you do not use Firewall Builder to configure iptables firewalls in bridging configuration. Otherwise, please read on.

Previous versions of Firewall Builder provided an attribute "bridge port" in the dialog of the Interface object. If an interface marked as "bridge port" was used in the "Interface" column of a policy rule, fwbuilder policy compiler used "--physdev-in" or "--physdev-out" option instead of conventional "-i" or "-o" option. The attribute "bridge port" has been deprecated in the new version. You need to make changes to your firewall and interface objects manually in order to make your old configurations compile properly with new version of Firewall Builder.

First, check if you have an interface object to represent the bridge. Usually it will have a name br0 or similar. If you do not have this interface object in the firewall in Firewall Builder, please create it. Regardless whether this object existed before or you just created it, open it in the editor and click "Advanced Interface Settings" button in the dialog. This button and the dialog it opens are new in this version of the program. In the dialog that appears use drop-down menu "Device Type" to set its type to "Bridge". Then click "OK" to close the dialog and save configuration.

Next, find interface objects that should represent bridge ports and simply drag them and drop under the interface br0 (copy/paste works too). In the end, these interfaces become "children" of br0 and should be located in the branch of the tree rooted at br0. The program displays a comment "bridge port" next to the name of an interface like this in the tree. Here is how it looks like:

In this configuration we have bridge interface br0 and two bridge ports eth0 and eth1. Note how eth0 and eth1 are located in the tree under br0, on the same level as its IP address object.

This is it, bridge port interfaces will be recognized by the program again and it will generate proper iptables configuration.

Changes in support for iptables

When an interface with dynamic address is used in a policy or NAT rule, compiler generates shell script to read its IP addresses at the time of execution, assigns them to temporary shell variables and uses them in rules. In previous versions (fwbuilder v2 and v3) only the first IPv4 address of an interface was used. V4 uses all IPv4 and IPv6 addresses of the interface by creating a shell "for" loop in the script. Note that support for dynamic IPv6 addresses was broken in v3 completely, it was fixed in v4.

Policy compiler for iptables can generate shell commands to configure bridge, bonding and vlan interfaces (see above).

Added support for branching rules in NAT.

Added support for option "--random" in SNAT rules

"SNAT instead of MASQUERADE on dynamic interfaces". NAT rule options dialog now has a checkbox that makes compiler use SNAT target instead of MASQUERADING when checked when TSrc has dynamic interface. Apparently MASQ target has problems when iptables NAT is used in combination with policy routing. Using SNAT with a variable that gets interface address solves the problem. By default this option is off, that is compiler uses MASQUERADE target when TSrc has dynamic interface.

Generated script can adjust conntrack kernel module parameters to tune its performance for firewalls that handle heavy traffic.

Generated iptables script now has standard structure per LSB ("Linux Standard Base Core Specification 3.1"). The script has the following actions controlled by the command line arguments: "start", "stop", "reload", "status". Action "start" reconfigured interfaces and then flushes current iptables tables and chains and loads new iptables configuration. Action "stop" flushes all tables and chains and sets default policy in all chains to "DROP" to shut down the firewall to all kinds of traffic. It can also optionally install iptables rules to permit ssh access to the firewall from the management workstation. Action "status" returns return code per LSB specification. Code 0 means the firewall is loaded and is running (but it does not check that the rules it is running with are those defined in fwbuilder). Return code 3 means iptables modules are not loaded or there are no tables. This return code means the firewall is not running or not configured. It also supports additional actions "interfaces" and "test_interfaces". Action "interfaces" only runs commands that manage IP addresses of interfaces, as well as configure vlan, bridge and bonding interfaces. Action "test_interfaces" runs the same commands in the test mode when it prints commands that would be executed but does not actually execute them.

Added support for negation in "-m limit --limit rate" and "-m connlimit --connlimit-above" clauses for iptables.

Option "--random" is now supported in all NAT rules (targets SNAT, DNAT, MASQUERADE)

Option "--persistent" is now supported in all NAT rules (targets SNAT, DNAT) if version is set to 1.4.3 or later in the firewall object.

Algorithm that finds policy rules that shadow each other can now recognize rules configured to use iptables modules "limit", "connlimit" and "hashlimit" and detects shadowing taking into account rate, burst and other parameters for these modules.

Support for IPCOP

Firewall Builder v4.0 comes with experimental integration with IPCOP firewalls. To turn it on, choose platform "iptables" and host OS "IPCOP firewall appliance". Generated script is supposed to be installed on the firewall as /etc/rc.d/rc.firewall.local and restarted by the command "/etc/rc.d/rc.firewall restart". Built-in policy installer in Firewall Builder GUI installs it using this name and runs restart command to activate it. Firewall Builder does not manage interfaces of IPCOP firewall to avoid conflicts with IPCOP itself, use fwbuilder only to generate iptables rules. The program comes with some template objects for IPCOP firewalls, you can use them when you create new Firewall object if you choose to create it from a template.

Support for OpenWRT

Another new host OS supported in Firewall Builder v4.0 is OpenWRT. To use fwbuilder with OpenWRT you need to install the following packages on the firewall using command "ipkg install package.ipk":

  • ip
  • ip6tables (if you need IPv6)
  • iptables-mod-extra
  • iptables-utils
  • kmod-ipt-extra
Firewall Builder uses name "fwbuilder.fw" for the generated script for OpenWRT and places it in directory "/etc/init.d/" on the firewall. To make the firewall run it during boot sequence, install the script using built-in policy installer or copy it to this directory manually, then run command
  /etc/init.d/fwbuilder.fw enable
and disable standard firewall script:
  /etc/init.d/firewall disable
To activate the firewall and load policy generated by fwbuilder, use command
  /etc/init.d/fwbuilder.fw start
To stop the firewall and block all traffic use command
  /etc/init.d/fwbuilder.fw stop
An option in the "Compiler" tab of the firewall object in fwbuilder GUI allows you to make the firewall block all traffic when stopped but still permit ssh connections from preconfigured address of the management machine.

This method works both on stable Kamikaze (v7.06) and the latest OpenWRT (v8.09 at the time of Firewall Builder v4.0 release).

In test mode fwbuilder copies generated firewall script to directory /tmp on the firewall.

Support for DD-WRT

This version of Firewall Builder introduces direct support for DD-WRT. There are two options: you can use nvram to install generated firewall policy or you can use jffs (Journaling Flash File System) on the device and store generated script there. Two host OS settings are provided: "DD-WRT (nvram)" and "DD-WRT (jffs)".

DD-WRT (nvram)

In this mode generated script is somewhat shorter and does not support command line arguments "start", "stop", "status". The script does not try to load iptables modules on the firewall but configures interface addresses, vlans, bridge ports and bonding interfaces. Built-in policy installer saves the script in nvram variable "fwb" and configures nvram variable "rc_firewall" to run this script.

DD-WRT (jffs)

First of all, you need to activate JFFS/JFFS2 (Journaling Flash File System) on the firewall. Instructions are provided in the DD-WRT wiki. Once jffs is mounted read-write, you also need to create directory "/jffs/firewall" where fwbuilder will store generated script. This is explained in this article in DD-WRT wiki.

When firewall is configured with host OS "dd-wrt (jffs)", built-in policy installer copies generated script to the file "/jffs/firewall/firewall.fs" on the firewall and configures nvram variable "rc_firewall" to call this script.

Note: recent builds of DD-WRT (tested with v24 and v24SP1) seem to disable JFFS for some reason. If you plan to use jffs method of installing firewall script, check if the version you run supports it.

Changes in support for PF

Added support for branching rules in NAT. Compiler generates keyword "anchor" if PF version is 4.3 or later and "nat-anchor" and "rdr-anchor" for earlier versions.

Optimization: rules that have several interface objects (or a group) in the "Interface" column are compiled using "{ }" grouping to produce only one configuration line instead of several for such rule.

Compiler for PF generates "allow-opts" keyword when IPService object used in the rule has IP options. This includes new option "router-alert".

Added support for pf state tracking options "no-sync" and "pflow". Set version to "4.5" or "4.6" in the firewall object to be able to use these new options.

Implemented support for incremental management of IP addresses of interfaces and VLAN pseudo-interfaces for OpenBSD and FreeBSD. The script analyzes existing vlan interfaces and compares them with vlan interfaces defined in the Firewall Builder GUI and then adds new ones and removes those that do not exist in fwbuilder.

OpenBSD 4.7 has changed the syntax of "nat" and "rdr" PF rules. These keywords are gone, corresponding translations are done using "nat-to" and "rdr-to" options in "pass" or "match" rules. Fwbuilder 4.0 adds support for this. The list of recognized versions for PF has been extended with "4.7", choosing this version number makes policy compiler generate NAT and rdr rules using new syntax. Since the "no" keyword has been removed as well, fwbuilder can no longer generate "no nat" rules for 4.7. Policy compiler recognizes this as a fatal error, administrator should use negation to implement exceptions in NAT rule sets.

Changes in support for for Cisco IOS ACL

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). This method can be combined with rollback. To use this method, turn on checkbox in the tab "Installer" of the "advanced settings" dialog of the router object. Since this option is configured separately for each firewall object, you can have a mix of installation methods if some routers do not support scp.

For instructions how to configure scp see Secure Copy. You need to do the following:

  • Create RSA keys
  • enable ssh v2 using command "ip ssh version 2"
  • enable scp server using command "ip scp server enable".
  • User account used to copy the policy should have privilege 15: "username vadim privilege 15 password 7 XXXXXXXXXXX".

To troubleshoot when scp is not working:

  • Test using command line scp tool rather than fwbuilder installer. Use "scp" on Linux and Mac OS X and "pscp.exe" on Windows like this: "scp file.fw router:nvram:file.fw"
  • check that ssh and scp are enabled on the router (see commands above)
  • check that user account has privilege 15
  • Use command "debug IP ssh" on the router to turn debugging on. Diagnostic messages that it prints to the console and to log may help you identify the problem

Note that installer does not use command "config replace" because configuration created by fwbuilder is incomplete and should be merged with running config rather than replace it.

Built-in policy installer uses EEM (Embedded Event Manager) on IOS 12.4 or later to schedule automatic configuration rollback instead of reloading the router. EEM appears in IOS 12.4 and supports background operations that can be triggered by some events on the router or by timers. In this new feature, fwbuilder creates EEM applet with a countdown timer that executes command "config replace nvram:startup-config force" when timer expires. User has the following options:

  • Schedule automatic rollback in a few minutes and install updated ACL configuration. This can be used to test new policy and revert to the original one after some short period of time. This also helps to avoid a situation when updated policy blocks access to the router because of an error; rolling back to the ACL configuration that was running before the update will restore access automatically.
  • Schedule rollback in a few minutes, install updated ACL but cancel rollback if installation of the new configuration was successful. This is mostly intended to prevent blocking access to the router in case of an error in the new ACL configuration. If fwbuilder was able to enter all lines of the new configuration all the way to the end, this means new configuration does not block access and installer executes command "no event manager applet fwbuilder-rollback" to cancel scheduled rollback.

Since IOS before 12.4 does not have EEM, automatic rollback on these older versions is implemented by scheduling router reload with command "reload in ". This hasn't changed since Firewall Builder v3.0

Added support for the "dry run" installer option for Cisco routers. When this option is on, installer logs into the router and switches to the enable mode, but does not execute any actual commands. If scp is used to copy configuration to the router, installer will copy the file but will not activate it. This tests ssh session in general, login password, enable password and scp but does not make any changes to the router configuration.

Added support for the object-group statement in generated IOS configuration. This helps reduce size of the generated access lists when the router should match long lists of IP addresses or ports. Both "network" and "service" object-groups are supported. This feature is controlled by a checkbox in the "Advanced" settings dialog of the firewall object; it requires IOS v12.4(20)T or later and is off by default. Check if your version of IOS supports "object-group" command before using!

Policy rule option "Add mirrored rule" (controlled by a checkbox in the rule options dialog) makes policy compiler for IOS ACL automatically create a rule with mirrored source and destination addresses and service fields. This can be used to match "reply" packets using address and service parameters matched by this rule. The action of the mirrored rule is the same as that of this one. Firewall Builder recognizes the following services and creates "mirrored" versions as follows:

  • UDP service: mirrored service has source and destination port ranges reversed
  • TCP service: mirrored service has source and destination port ranges reversed and "established" flag inverted. If TCP service used in this rule does not have "established" flag, the mirrored service gets it, and the other way around. This is designed to simplify creating ACL rules to permit "reply" TCP packets
  • ICMP service: ICMP echo request is recognized, mirrored service becomes ICMP echo reply. Other ICMP types are simply copied to the mirrored service
  • ICMPv6 service: like with ICMP, ICMP echo request is recognized and other ICMPv6 types are just copied
  • IP service: mirrored service is a copy

Changes in support for for Cisco ASA (PIX)

Built-in installer can use command scp to copy generated configuration to the firewall and then command "copy file running-config" to activate it. This method is much faster than running configuration line by line. The firewall should be configured with ssh v2 and scp server. This method can be combined with rollback. To use this method, turn on checkbox in the tab "Installer" of the "advanced settings" dialog of the PIX firewall. Since this option is configured separately for each firewall object, you can have a mix of installation methods if some firewalls do not support scp.

To configure scp on the PIX firewall you need to do the following:

  • Create RSA keys
  • enable ssh v2 using command "ssh version 2" in configuration mode
  • enable scp using command "ssh scopy enable" in configuration mode
  • make sure user account used to copy configuration has "privilege 15": "username fwbadmin password XXXXXXX privilege 15"

To troubleshoot when scp is not working:

  • Test using command line scp tool rather than fwbuilder installer. Use "scp" on Linux and Mac OS X and "pscp.exe" on Windows like this: "scp file.fw firewall:flash:file.fw"
  • check that ssh and scopy are enabled on the firewall
  • check that user account has privilege 15
  • Use command "debug ssh 10" on PIX to turn debugging on. Diagnostic messages that it prints to the console and to log may help you identify the problem

Note that when fwbuilder uses command "copy file.fw running-config" to activate uploaded policy, the firewall does not print it. If there are errors, they are printed but the lines they refer to are not printed. Some configuration lines trigger lines because they try to configure things that are already configured, such as some parameters of interfaces, global pools etc.

Generated PIX configuration will include commands that enable ssh v2 and enable scopy if this option is turned on to make sure they stay enabled after configuration is reloaded from the file.

When certain PIX configuration commands are executed again during configuration update, PIX detects this as an error. Commands that fall into this category are "inspect", "service-policy" and some "failover" commands, to name a few. To avoid this kind of errors while updating PIX using built-in installer and avoid entering commands for parts of configuration that do not change often, you can use checkbox "Generate only access-list, access-group... commands" in the "Script" tab of the PIX firewall "advanced" options dialog. If this checkbox is on, generated configuration file will only include "access-list", "access-group", "telnet", "ssh", "nat", "global" and "static" commands.

Changes in the command line tool fwbedit

User can now merge objects from two data files together using command line tool fwbedit just like the "Import library" function in the GUI.

fwbuilder-5.1.0.3599/src/res/help/en_US/release_notes_4.1.3.html0000644000175000017500000002271511733011756024567 0ustar sylvestresylvestre

Firewall Builder 4.1.3 Release Notes

SourceForge: Tickets for V4

v4.1.3 has been tested, and we believe it to be ready for production use, but if you do find a bug or issue please let us know.

GUI Updates

  • see #1823 "Add Preference option for Advanced / Power users". Added checkbox to the Preferences dialog, this checkbox turns off some tooltips that can be annoying for users who are sufficiently familiar with the GUI

  • see #1787 "new fw name input field should have focus when new firewall wizard opens"

  • code refactoring: see #1822 "refactor all GUI classes into libgui library and link executable with it"

  • code refactoring: see #1826 "Please place all unit tests in one directory". All GUI and other unit tests moved to the directory src/unit_tests

  • see #1809 "Add Firewall Setting in Logging settings for default log setting on new rules". Added a tab "Policy Rule" to the "Objects" page of the global preferences dialog; checkbox in this tab allows the user to choose whether new policy rules should be created with logging turned on or off.

  • See #1832, SF bug 3097419 "installer uses bare IP address instead of putty session name". It appears pscp.exe on Windows can use putty session name in place of the host name. This change restores old behavior where session name was used like that but does it for both plink.exe and pscp.exe. This only affects users who run fwbuilder GUI on Windows

  • fixed #1837 "generated script gets .fw suffix even when user set output file name". Suffix .fw should not be appended to the name entered by the user in the "output file name" input field in the firewall settings dialog.

  • Fixed SF bug #3106168 "Branch destinations lost when adding to cluster". Since the order in which I copy rule sets is undefined and because they may have references to each other via branching rules, I need to fix references after I create all of them.

  • Fixes #1858 'Remove "Summary of features" page from the package' and #1857 'Remove "Getting Started" guide from the package'. We have dediced to keep documentation and other content like this on the web site. Button "Watch Getting Started Tutorial" in the Tip of the Day dialog opens tutorial hosted on the web site in a web browser.

Changes and improvements in the API library libfwbuilder

  • added module uint128 (128-bt arithmetics by Evan Teran). Implemented basic operations with ipv6 addresses using this module. See #1834. Now all policy compilers can correctly compare ipv6 addresses used in rules with ipv6 addresses of interfaces. This helps perform various optimizations and fixes issues with the algorithm used to pick the right interface for the Cisco IOS ACL compiled from a policy rule with an empty "interface" rule element and direction "both".

Changes and improvements in the library of standard objects

  • added ICMPv6 object "parameter problem" (type 4, any code) per SF feature request 3094743. Also added service group object "ipv6 unreachable messages" that includes ICMPv6 messages "destination unreachable", "packet too big", "parameter problem" and "time exceeded" per SF feature request 3094758

Changes in support for iptables

  • fix for the SF bug #3095615 "reopen no PREROUTING rule with *-Interface - ID: 3077132". Configlet used wrong shell variable to access ip address of a wildcard interface.

  • fixed #1820 "skip module "nf_conntrack_ipv6" if generated script has no ipv6 rules" Shell function load_modules should not try to load module nf_conntrack_ipv6 if generated script does not load any ipv6 rules. Loading this module fails if ipv6 has been disabled in the kernel.

  • fixed SF bug 3091069: "Routing configuration failed". Iptables script generated by fwbuilder did not configure broadcast when it added ip addresses to interfaces. Using "ip addr add ADDR/NM boradcast + dev INTF" syntax to do this.

  • implemented SF feature request 3094738 "Set the HL to 255 for IPv6 Neighbor Discovery". Neighbor discovery packets must have hop limit of 255 per RFC 2461. Automatically generated rules that match neighbor discovery packets will math hooplimit 255.

  • fixed SF bug 3094273 "no state needed for ipv6-icmp in ip6tables". Rules that match ICMPv6 objects should be stateless. Compiler will check for this and reset "stateful" flag of a rule and issue warning if the rule was built stateful in the GUI. This could be version-dependent, we may need to revisit this in the future when netfilter fixes the underlying issue. Some resources: https://bugzilla.redhat.com/show_bug.cgi?id=243739 https://bugs.launchpad.net/ubuntu/+source/iptables/+bug/479105

  • fixed SF bug 3090249 "fwb_ipt ignores -d option ". Documented behavior is for the compiler to create files in the directory specified by the argument of the "-d" command line flag. If flag "-d" is not provided, files should be created in the current directory.

  • fixed #1824 "should not try to verify wildcard interfaces".

  • fixed #1838 "function configure_interfaces() does not manage ip addresses of vlan interfaces". This function used to take into account only interfaces that were direct children objects of the firewall. Since vlan interfaces are children of the corresponding physical interface, they were not included.

  • fixed SF bug 3103582 "Cant create redirect rule in cluster firewall object". Iptables nat rule with target REDIRECT could not be built in a cluster configuration. It should be possible to do this by putting cluster object in Translated Destination.

  • fixed #1856 "Pemit '-' in Linux interface names". OpenWRT uses name "ppp-dsl" for PPPoE interfaces. In addition to that, Linux bridge interfaces may have names with a "-" such as "br-lan". We will now permit a "-" in Linux interface names.

Support for PF

  • fixed #1807 "wrong order of address assignment in the generated OpenBSD/PF/CARP cluster configuration". Need to assign ip addresses to regular interfaces before trying to assign them to carp interfaces.

Support for ipfw

  • fixed #1836 "installer hangs and fails after activation of ipfw policy". As soon as .fw script swapped ipfw sets usig command "ipfw sawp" and deleted temporary set 1, ssh session would hang and eventually break. We optionally add ipfw rules to permit ssh session used to manage the firewall, as well as a rule to permit reply packets but the latter rule was not built correctly. It should match source and destination reversed, as well as match keyword "established" and recreate state with "keep-state". This rule automatically recreates state for the established ssh session over which firewall policy is being managed. Also added a comment to the firewall settings dialog for ipfw to remind the user that address or subnet they use with this automatic rule should be as narrow as possible.

Changes in support for for Cisco IOS ACL

  • see #1834 Fixed matching algorithm that determins which interface a rule should be associated with for Cisco IOS ACLs. Previously compiler did not compare subnets properly and because of that it interpreted some configurations incorrectly. For example in the case with a network object 10.0.0.0/8 in "source" and an interface with address 10.0.0.1/24 (network should not be considered matching) compiler considered this interface matching and assigned the rule to the interface only with direction "inbound".

Changes in support for for Cisco ASA (PIX)

  • There are no changes in the support for ASA in this release

Support for HP ProCurve

  • There are no changes in the support for HP ProCurve in this release

fwbuilder-5.1.0.3599/src/res/configlets/0000755000175000017500000000000011733011756020513 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/secuwall/0000755000175000017500000000000011733011756022332 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/secuwall/script_skeleton0000644000175000017500000000526711733011756025477 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Double '##' comments are removed when configlet is processed. ## Single '#' comments stay. ## ## Some shells (not bash) do not like empty functions. Placing a comment ## inside the function does not help. Using dummy ":" as a placeholder. ## {{$top_comment}} {{$errors_and_warnings}} {{$shell_debug}} FWBDEBUG="" {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} load_modules() { : echo "Modules are loaded only at startup!" } verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { for runstop in keepalived conntrackd network ; do /etc/init.d/${runstop} stop done /sbin/ifclear all for runstart in management network keepalived conntrackd ; do /etc/init.d/${runstart} start done } script_body() { {{$script_body}} } ip_forward() { : {{$ip_forward_commands}} } reset_all() { : {{$reset_all}} } {{$block_action}} {{$stop_action}} {{$status_action}} # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated {{$timestamp}} by {{$user}}" log "Database was {{$database}}" check_tools check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} {{if prolog_top}} prolog_commands {{endif}} load_modules "{{$load_modules_with_nat}} {{$load_modules_with_ipv6}}" configure_interfaces verify_interfaces {{if prolog_after_interfaces}} prolog_commands {{endif}} {{if not_using_iptables_restore}} reset_all {{endif}} {{if prolog_after_flush}} prolog_commands {{endif}} script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; *) echo "Usage $0 {start|stop|status|block|reload|interfaces|test_interfaces}" ;; esac exit $RETVAL fwbuilder-5.1.0.3599/src/res/configlets/secuwall/installer_commands_reg_user0000644000175000017500000000134211733011756030026 0ustar sylvestresylvestre## -*- 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## {{if run}} {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/secuwall/installer_commands_root0000644000175000017500000000133311733011756027176 0ustar sylvestresylvestre## -*- 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 root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## {{if run}} {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/secuwall/management_rules0000644000175000017500000000546311733011756025613 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## {{if has_secuwall_mgmt_mgmtaddr}} # SSH access from management stations/networks for mgmt in {{$secuwall_mgmt_mgmtaddr}} ; do {{$begin_rule}} INPUT -p tcp -m tcp -s ${mgmt} --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp -d ${mgmt} --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} done {{endif}} {{if has_secuwall_mgmt_loggingaddr}} # logging via SYSLOG to loghosts for loghost in {{$secuwall_mgmt_loggingaddr}} ; do {{$begin_rule}} OUTPUT -p udp -m udp -d ${loghost} --dport 514 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp -d ${loghost} --dport 514 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p tcp -m tcp -s ${loghost} --sport 514 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} done {{endif}} {{if has_secuwall_mgmt_ntpaddr}} # get current time via NTP for ntphost in {{$secuwall_mgmt_ntpaddr}} ; do {{$begin_rule}} OUTPUT -p udp -m udp -d ${ntphost} --dport 123 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p udp -m udp -s ${ntphost} --sport 123 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} done {{endif}} {{if has_secuwall_mgmt_snmpaddr}} # let us peek via SNMP for snmp in {{$secuwall_mgmt_snmpaddr}} ; do {{$begin_rule}} INPUT -p udp -m udp -s ${snmp} --dport 161 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p udp -m udp -d ${snmp} --sport 161 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p udp -m udp -d ${snmp} --dport 162 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} done {{endif}} {{if has_secuwall_mgmt_nagiosaddr}} # access to the NRPE client on the firewall for nagios in {{$secuwall_mgmt_nagiosaddr}} ; do {{$begin_rule}} INPUT -p tcp -m tcp -s ${nagios} --dport 5666 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp -d ${nagios} --sport 5666 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} done {{endif}} # client DNS for the firewall {{if has_secuwall_dns_srv1}} for dns in {{$secuwall_dns_srv1}} {{$secuwall_dns_srv2}} {{$secuwall_dns_srv3}} ; do {{$begin_rule}} OUTPUT -p udp -m udp -d ${dns} --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p udp -m udp -s ${dns} --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp -d ${dns} --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p tcp -m tcp -s ${dns} --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} done {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ios/0000755000175000017500000000000011733011756021305 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/ios/safety_net_acl0000644000175000017500000000242111733011756024207 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ios/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ! temporary access list for "safety net install" {{if ipv4}} no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip {{$management_addr}} {{$management_netm}} any deny ip any any exit interface {{$management_interface}} no ip access-group in no ip access-group out ip access-group tmp_acl in exit {{endif}} {{if ipv6}} no ipv6 access-list tmp_acl ipv6 access-list tmp_acl {{if slash_notation}} permit ipv6 {{$management_addr}} any {{endif}} {{if host_addr}} permit ipv6 host {{$management_addr}} any {{endif}} permit icmp any any deny ipv6 any any exit interface {{$management_interface}} no ipv6 traffic-filter in no ipv6 traffic-filter out ipv6 traffic-filter tmp_acl in exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ios/script_skeleton0000644000175000017500000000153711733011756024446 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ios/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{$top_comment}} {{$errors_and_warnings}} ! ! Prolog script: ! {{$prolog_script}} ! ! End of prolog script: ! {{$other_os_configuration_commands}} {{$system_configuration_script}} {{$policy_script}} {{$nat_script}} {{$routing_script}} ! ! Epilog script: ! {{$epilog_script}} ! End of epilog script: ! fwbuilder-5.1.0.3599/src/res/configlets/ios/top_comment0000644000175000017500000000035411733011756023556 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_iosacl v{{$version}} ! ! Generated {{$timestamp}} {{$tz}} by {{$user}} ! ! Compiled for {{$platform}} {{$fw_version}} ! {{$manifest}} ! {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/ios/installer_commands_reg_user0000644000175000017500000000165111733011756027004 0ustar sylvestresylvestre## -*- 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 ("flash:" or "nvram:" or similar) ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## ## {{$firewall_name}} -- the name of the firewall object ## {{if using_scp}} copy {{$fwdir}}{{$fwscript}} running-config {{endif}} {{if not_using_scp}} config term {{$fwbuilder_generated_configuration_lines}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ios/installer_commands_post_config0000644000175000017500000000106411733011756027501 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout ## {{$test}} -- doing installation in test mode ## {{if version_lt_124}} {{if cancel_rollback}} reload cancel {{endif}} {{endif}} {{if version_ge_124}} {{if cancel_rollback}} config term no event manager applet fwbuilder-rollback exit {{endif}} {{endif}} {{if run}} wr mem {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ios/installer_commands_pre_config0000644000175000017500000000142211733011756027300 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout (min) ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## {{$test}} -- doing installation in test mode ## terminal width 256 terminal length 0 {{if schedule_rollback}} {{if version_lt_124}} reload in {{$rbtimeout}} {{endif}} {{if version_ge_124}} config term event manager applet fwbuilder-rollback event timer countdown name rollback-countdown time {{$rbtimeout_sec}} action 1.0 cli command "enable" action 1.1 cli command "configure replace nvram:startup-config force" exit exit {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pf/0000755000175000017500000000000011733011756021120 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/pf/script_skeleton0000644000175000017500000000240711733011756024256 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pf/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{$top_comment}} {{$errors_and_warnings}} {{$shell_debug}} FWDIR=`dirname $0` {{$tools}} {{$shell_functions}} verify_interfaces() { : {{$verify_interfaces}} } set_kernel_vars() { : {{$kernel_vars_commands}} } prolog_commands() { : {{$prolog_script}} } epilog_commands() { : {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } log "Activating firewall script generated {{$timestamp}} by {{$user}}" set_kernel_vars configure_interfaces prolog_commands {{$activation_commands}} {{if pf_version_ge_4_x}} {{if pf_flush_states}} $PFCTL -F states {{endif}} {{endif}} {{$routing_script}} epilog_commands fwbuilder-5.1.0.3599/src/res/configlets/pf/top_comment0000644000175000017500000000036211733011756023370 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} # {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/pf/rc_conf_skeleton0000644000175000017500000000152511733011756024363 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pf/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Parts of this configlets will be translated to variable=value syntax ## used by rc.conf files ## {{$top_comment}} {{$errors_and_warnings}} {{$kernel_vars_commands}} {{$prolog_script}} {{$configure_interfaces}} pf_enable="YES" {{$activation_commands}} {{$routing_script}} {{$epilog_script}} fwbuilder-5.1.0.3599/src/res/configlets/pf/rc_conf_top_comment0000644000175000017500000000035011733011756025056 0ustar sylvestresylvestre# # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_pf v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} # {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/pf/rc_conf_activation0000644000175000017500000000110411733011756024671 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pf/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## pf_rules="{{$remote_file}}" fwbuilder-5.1.0.3599/src/res/configlets/pf/activation0000644000175000017500000000131511733011756023204 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pf/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## $PFCTL {{$pfctl_debug}} {{if anchor}}-a {{$anchor_name}}{{endif}} {{if pf_version_lt_3_2}}-R{{endif}} {{if pf_version_ge_3_2}}-f{{endif}} {{$remote_file}} || exit 1 fwbuilder-5.1.0.3599/src/res/configlets/macosx/0000755000175000017500000000000011733011756022005 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/macosx/installer_commands_reg_user0000644000175000017500000000261611733011756027506 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/macosx/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## Note: all commands should be on one line to avoid unnecessary linefeeds. ## These linefeeds are sent to the server side (to the firewall) and end up ## on the input of sudo and other commands. This creates difficult to catch ## race condition which breaks installation process. echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sudo -S {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' fwbuilder-5.1.0.3599/src/res/configlets/macosx/tools0000644000175000017500000000127711733011756023077 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/macosx/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Set path to all utilities that we need IFCONFIG="{{$path_ifconfig}}" IPFW="{{$path_ipfw}}" SYSCTL="{{$path_sysctl}}" LOGGER="{{$path_logger}}" fwbuilder-5.1.0.3599/src/res/configlets/macosx/kernel_vars0000644000175000017500000000152111733011756024242 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/macosx/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if have_macosx_ip_forward}}$SYSCTL -w net.inet.ip.forwarding={{$macosx_ip_forward}}{{endif}} {{if have_macosx_ip_sourceroute}}$SYSCTL -w net.inet.ip.sourceroute={{$macosx_ip_sourceroute}}{{endif}} {{if have_macosx_ip_redirect}}$SYSCTL -w net.inet.ip.redirect={{$macosx_ip_redirect}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/macosx/installer_commands_root0000644000175000017500000000217211733011756026653 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/macosx/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## {{if run}} echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sh {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/solaris/0000755000175000017500000000000011733011756022167 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/solaris/installer_commands_reg_user0000644000175000017500000000270611733011756027670 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/solaris/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout (min) ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## ## {{$firewall_name}} -- the name of the firewall object ## ## Note: all commands should be on one line to avoid unnecessary linefeeds. ## These linefeeds are sent to the server side (to the firewall) and end up ## on the input of sudo and other commands. This creates difficult to catch ## race condition which breaks installation process. echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sudo -S {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' fwbuilder-5.1.0.3599/src/res/configlets/solaris/tools0000644000175000017500000000131611733011756023253 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/solaris/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Set path to all utilities that we need IPFW="{{$path_ipfw}}" IPF="{{$path_ipf}}" IPNAT="{{$path_ipnat}}" SYSCTL="{{$path_sysctl}}" LOGGER="{{$path_logger}}" fwbuilder-5.1.0.3599/src/res/configlets/solaris/kernel_vars0000644000175000017500000000224511733011756024430 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/solaris/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if have_solaris_ip_forward}}ndd -set /dev/ip ip_forwarding {{$solaris_ip_forward}}{{endif}} {{if have_solaris_ip_ignore_redirect}}ndd -set /dev/ip ip_ignore_redirect {{$solaris_ip_ignore_redirect}}{{endif}} {{if have_solaris_ip_respond_to_echo_broadcast}}ndd -set /dev/ip ip_respond_to_echo_broadcast {{$solaris_ip_respond_to_echo_broadcast}}{{endif}} {{if have_solaris_ip_forward_directed_broadcasts}}ndd -set /dev/ip ip_forward_directed_broadcasts {{$solaris_ip_forward_directed_broadcasts}}{{endif}} {{if have_solaris_ip_forward_src_routed}}ndd -set /dev/ip ip_forward_src_routed {{$solaris_ip_forward_src_routed}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/solaris/installer_commands_root0000644000175000017500000000215111733011756027032 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/solaris/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sh {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' fwbuilder-5.1.0.3599/src/res/configlets/ipf/0000755000175000017500000000000011733011756021271 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/ipf/script_skeleton0000644000175000017500000000241411733011756024425 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipf/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{$top_comment}} {{$errors_and_warnings}} FWDIR=`dirname $0` {{$shell_debug}} {{$tools}} {{$shell_functions}} verify_interfaces() { : {{$verify_interfaces}} } set_kernel_vars() { : {{$kernel_vars_commands}} } prolog_commands() { : {{$prolog_script}} } epilog_commands() { : {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } log "Activating firewall script generated {{$timestamp}} by {{$user}}" set_kernel_vars configure_interfaces prolog_commands $IPF -Fa $IPNAT -C {{$activation_commands}} {{if have_filter}} $IPF -s {{endif}} epilog_commands /sbin/kldstat -n ipl.ko > /dev/null 2>&1 || $IPF -E fwbuilder-5.1.0.3599/src/res/configlets/ipf/top_comment0000644000175000017500000000036311733011756023542 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipf v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} # {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/ipf/activation0000644000175000017500000000175411733011756023364 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipf/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if dyn_addr}} {{if filter}} cat {{$remote_file}} | grep -v '#' | {{$interface_name_substitution_commands}} | $IPF {{$ipf_debug}} -I -f - {{endif}} {{if nat}} cat {{$remote_file}} | grep -v '#' | {{$interface_name_substitution_commands}} | $IPNAT {{$ipf_debug}} -f - {{endif}} {{endif}} {{if not_dyn_addr}} {{if filter}} $IPF {{$ipf_debug}} -I -f {{$remote_file}} {{endif}} {{if nat}} $IPNAT {{$ipf_debug}} -f {{$remote_file}} {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/0000755000175000017500000000000011733011756022020 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/linux24/routing_functions0000644000175000017500000000375511733011756025534 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## # ============== ROUTING RULES ============== HAVE_MKTEMP=$(which mktemp) test -n "$HAVE_MKTEMP" && { TMPDIRNAME=$(mktemp -d) test -z "$TMPDIRNAME" && exit 1 } test -z "$HAVE_MKTEMP" && { TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" (umask 077 && mkdir $TMPDIRNAME) || exit 1 } TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" OLD_ROUTES="$TMPDIRNAME/.old_routes" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules sh $OLD_ROUTES echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) $IP route show | sort -k 2 | awk '{printf "ip route add %s\n",$0;}' > $OLD_ROUTES echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v {{$proto_filter}} | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." fwbuilder-5.1.0.3599/src/res/configlets/linux24/script_body_iptables_restore0000644000175000017500000000225711733011756027720 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## iptables-restore method, not single rule compile {{if have_script}} ( {{if filter_or_auto}} echo '*filter' {{$filter_auto_script}} {{$filter_script}} echo COMMIT {{endif}} {{if mangle_or_auto}} echo '*mangle' {{$mangle_auto_script}} {{$mangle_script}} echo COMMIT {{endif}} {{if nat}} echo '*nat' {{$nat_script}} echo COMMIT {{endif}} {{if ipv4}} ) | $IPTABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES {{endif}} {{if ipv6}} ) | $IP6TABLES_RESTORE; IPTABLES_RESTORE_RES=$? test $IPTABLES_RESTORE_RES != 0 && run_epilog_and_exit $IPTABLES_RESTORE_RES {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/shell_functions0000644000175000017500000000516211733011756025146 0ustar sylvestresylvestre## -*- mode: shell-script; -*- log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } getInterfaceVarName() { echo $1 | sed 's/\./_/' } ## ## getaddr6() reimplementation idea courtesy Juergen Kammer ## See ticket #651 ## ## Can not use awk substr() function as originally suggested by ## Juergen because of the difference in behavior between GNU awk and ## mawk (a bug?). GNU awk substr() returns +1 character while mawk ## returns n characters. Tested with GNU awk v3.1.5 (CentOS 5.2) and ## mawk v1.3.3 (Ubuntu Jaunty) ## ## This sed command has been tested with GNU sed v4.1.5 and busybox v1.00 ## ## getaddr has been reimplemented to return list of all ipv4 addresses ## of the interface. This is different from its behavior in fwbuilder ## v2 and v3 where it returned only the first address. ## getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } getnet_internal() { dev=$1 name=$2 af=$3 L=$($IP route list proto kernel | grep $dev | grep -v default | sed 's! .*$!!') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } ## ## This function reads all ipv4 addresses of interface (arg 1) and ## assignes the list to the variable which name is given as arg 2. ## getaddr() { getaddr_internal $1 $2 "-4" } ## ## This function reads all ipv6 addresses of interface (arg 1) and ## assignes the list to the variable which name is given as arg 2. ## getaddr6() { getaddr_internal $1 $2 "-6" } ## ## This function reads all ipv4 addresses of interface (arg 1) and ## assignes list of addresses of attached networks with their netmasks ## to the variable which name is given as arg 2. ## getnet() { getnet_internal $1 $2 "-4" } ## ## This function reads all ipv6 addresses of interface (arg 1) and ## assignes list of addresses of attached networks with their netmasks ## to the variable which name is given as arg 2. ## getnet6() { getnet_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } fwbuilder-5.1.0.3599/src/res/configlets/linux24/script_skeleton0000644000175000017500000000625611733011756025164 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Double '##' comments are removed when configlet is processed. ## Single '#' comments stay. ## ## Some shells (not bash) do not like empty functions. Placing a comment ## inside the function does not help. Using dummy ":" as a placeholder. ## {{$top_comment}} {{$errors_and_warnings}} {{$shell_debug}} FWBDEBUG="" {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} load_modules() { : {{$load_modules}} } verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } script_body() { {{$script_body}} } ip_forward() { : {{$ip_forward_commands}} } reset_all() { : {{$reset_all}} } {{$block_action}} {{$stop_action}} {{$status_action}} # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated {{$timestamp}} by {{$user}}" check_tools {{if prolog_top}} prolog_commands {{endif}} check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} load_modules "{{$load_modules_with_nat}} {{$load_modules_with_ipv6}}" configure_interfaces verify_interfaces {{if prolog_after_interfaces}} prolog_commands {{endif}} {{if not_using_iptables_restore}} reset_all {{endif}} {{if prolog_after_flush}} prolog_commands {{endif}} script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; {{if using_ipset}} ## Usage: script.fw reload_address_table reload_address_table) reload_address_table $2 $3 ;; ## Usage: script.fw add_to_address_table
add_to_address_table) add_to_address_table $2 $3 $4 ;; ## Usage: script.fw remove_from_address_table
remove_from_address_table) remove_from_address_table $2 $3 $4 ;; ## Usage: script.fw test_address_table
test_address_table) test_address_table $2 $3 ;; {{endif}} *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces{{if using_ipset}}|reload_address_table|add_to_address_table|remove_from_address_table|test_address_table{{endif}}]" ;; esac exit $RETVAL fwbuilder-5.1.0.3599/src/res/configlets/linux24/conntrack0000644000175000017500000000146111733011756023727 0ustar sylvestresylvestre## -*- mode: shell-script; -*- {{if iptables_version_lt_1_4}} {{if if_conntrack_max}}echo {{$conntrack_max}} > /proc/sys/net/ipv4/netfilter/ip_conntrack_max{{endif}} {{if if_conntrack_hashsize}}echo {{$conntrack_hashsize}} > /sys/module/ip_conntrack/parameters/hashsize{{endif}} {{if if_conntrack_tcp_be_liberal}}echo {{$conntrack_tcp_be_liberal}} > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal {{endif}} {{endif}} {{if iptables_version_ge_1_4}} {{if if_conntrack_max}}echo {{$conntrack_max}} > /proc/sys/net/netfilter/nf_conntrack_max {{endif}} {{if if_conntrack_hashsize}}echo {{$conntrack_hashsize}} > /sys/module/nf_conntrack/parameters/hashsize{{endif}} {{if if_conntrack_tcp_be_liberal}}echo {{$conntrack_tcp_be_liberal}} > /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/update_bonding0000644000175000017500000001341711733011756024733 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ############ bonding ########################################### ## cat /proc/net/bonding/bond0 ## Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008) ## ## Bonding Mode: load balancing (round-robin) ## MII Status: up ## MII Polling Interval (ms): 0 ## Up Delay (ms): 0 ## Down Delay (ms): 0 ## ## Slave Interface: eth2 ## MII Status: up ## Link Failure Count: 0 ## Permanent HW addr: 00:0c:29:f6:be:aa ## ## Slave Interface: eth3 ## MII Status: up ## Link Failure Count: 0 ## Permanent HW addr: 00:0c:29:f6:be:b4 ## ## missing_bond() { bond_intf=$1 cmd=$2 test "$cmd" = "down" && { echo "# Bring unconfigured bonding interface $bond_intf down" $FWBDEBUG $IP link set $bond_intf down } } missing_slave() { slave=$1 cmd=$2 oldIFS=$IFS IFS="@" set $slave intf=$1 bond_interface=$2 IFS=$oldIFS test "$cmd" = "-d" && { echo "# Delete bonding interface slave: $bond_interface $intf" $FWBDEBUG $IFENSLAVE -d $bond_interface $intf } || { echo "# Add bonding interface slave: $bond_interface $intf" $FWBDEBUG $IP link set $bond_interface up $FWBDEBUG $IFENSLAVE $bond_interface $intf } } ## verify that bonding module is loaded with parameters that provide ## support for required number of bonding interfaces (bonding ## interfaces get created when module is loaded and if we need 2 -- ## bond0 and bond1 -- then the way to get them is to load the module ## with parameter max_bonds=2). ## ## Current implementation only supports identical bonding parameters ## for all bonding interfaces. This is because in my tests command ## "modprobe bonding -obond1" always causes kernel panic. This means I ## could not find a way to load bonding module two times with ## different parameters. Call for this function is generated in ## OSConfigurator_linux24::printBondingInterfaceConfigurationCommands() ## ## load_bonding_module "bond0 bond1" max_bonds=2 mode=balance-alb miimon=50 ## load_bonding_module() { bonding_interfaces=$1 shift module_parameters=$* PROC_DIR="/proc/net/bonding/" test -d $PROC_DIR || { ## module is not loaded. Load it with appropriate max_bonds argument cmd="$MODPROBE bonding $module_parameters" test -n "$FWBDEBUG" && echo "# $cmd" || $cmd || { # Module load failed. cat </dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES {{if need_iptables_restore}} find_program $IPTABLES_RESTORE{{endif}} {{if need_ip6tables_restore}} find_program $IP6TABLES_RESTORE{{endif}} {{if need_modprobe}} find_program $MODPROBE {{endif}} find_program $IP {{if need_vconfig}} find_program $VCONFIG {{endif}} {{if need_brctl}} find_program $BRCTL {{endif}} {{if need_ifenslave}} find_program $IFENSLAVE {{endif}} {{if need_ipset}} find_program $IPSET {{endif}} } fwbuilder-5.1.0.3599/src/res/configlets/linux24/reset_iptables0000644000175000017500000000234211733011756024751 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## reset_iptables_v4() { $IPTABLES -P OUTPUT DROP $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP cat /proc/net/ip_tables_names | while read table; do $IPTABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IPTABLES -t $table -F $chain fi done $IPTABLES -t $table -X done } reset_iptables_v6() { $IP6TABLES -P OUTPUT DROP $IP6TABLES -P INPUT DROP $IP6TABLES -P FORWARD DROP cat /proc/net/ip6_tables_names | while read table; do $IP6TABLES -t $table -L -n | while read c chain rest; do if test "X$c" = "XChain" ; then $IP6TABLES -t $table -F $chain fi done $IP6TABLES -t $table -X done } fwbuilder-5.1.0.3599/src/res/configlets/linux24/installer_commands_reg_user0000644000175000017500000000210511733011756027512 0ustar sylvestresylvestre## -*- 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## Note: all commands should be on one line to avoid unnecessary linefeeds. ## These linefeeds are sent to the server side (to the firewall) and end up ## on the input of sudo and other commands. This creates difficult to catch ## race condition which breaks installation process. echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sudo -S {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' fwbuilder-5.1.0.3599/src/res/configlets/linux24/block_action0000644000175000017500000000314411733011756024374 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## This configlet defines commands executed when iptables script is ran ## with command line argument "block". By default it resets iptables ## tables and chains using function reset_all and optionally adds backup ## ssh access rules. block_action() { reset_all ## it helps to add backup ssh access rule as early as possible so that ## ssh session opened from the management station won't break after ## all chains are flushed. The installation process may stall if ## stdout buffer gets filled with diagnostic or progress output from ## this script printed after chains are flushed but before a rule ## permitting ssh is installed. This may happen if script debugging is ## on or there are many NAT rules (so it prints a lot of "Rule NN ## (NAT)" lines). {{if mgmt_access}} # backup ssh access $IPTABLES -A INPUT -p tcp -m tcp -s {{$ssh_management_address}} --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -p tcp -m tcp -d {{$ssh_management_address}} --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT {{endif}} } fwbuilder-5.1.0.3599/src/res/configlets/linux24/verify_interfaces0000644000175000017500000000053311733011756025453 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## This is the body of the shell function verify_interfaces() {{if have_interfaces}} echo "Verifying interfaces: {{$interfaces}}" for i in {{$interfaces}} ; do $IP link show "$i" > /dev/null 2>&1 || { log "Interface $i does not exist" exit 1 } done {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/automatic_rules0000644000175000017500000001525511733011756025153 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## Each rule must start with {{$begin_rule}} and end with ## {{$end_rule}}. Variable $begin_rule has value "$IPTABLES -A" if ## generated script is in the shell script format, or just empty ## string if it is in iptables-restore format ## ## Variables in this configlet: ## ## $begin_rule "$IPTABLES -A" or empty string ## $end_rule ## $ssh_management_address address of the management address used for backup ssh access ## $management_interface the name of the management interface ## $cprange (ULOG --cprange) ## $nlgroup (ULOG --ulog-nlgroup) ## $qthreshold (ULOG --ulog-qthreshold) ## $invalid_match_log_prefix (ULOG --ulog-prefix or LOG --log-prefix) ## ## Conditional statements use the following variables: ## ## bridging_firewall the firewall is a bridge ## ipforw should generate rules in FORWARD chain ## accept_established should add rules to match --state ESTABLISHED,RELATED ## mgmt_access should add rules for management ssh access ## drop_new_tcp_with_no_syn should add rules to drop TCP sessions opened prior firewall restart ## add_rules_for_ipv6_neighbor_discovery should add rules to permit IPv6 Neighbor discovery ## drop_invalid should add rules to drop packets that match state INVALID ## drop_invalid_and_log drop and log packets that match state INVALID ## not_use_ulog use LOG for logging ## use_ulog use ULOG for logging ## use_nlgroup for --ulog-nlgroup ## use_cprange for --ulog-cprange ## use_qthreshold for --ulog-qthreshold ## bug #1092141: "irritating FORWARD rule for established connections" ## Need rules in FORWARD chain only if ip forwarding is on or set to ## "no change" {{if accept_established}} # accept established sessions {{$begin_rule}} INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{$begin_rule}} FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{endif}} ## it helps to add backup ssh access rule as early as possible so that ## ssh session opened from the management station won't break after ## all chains are flushed. The installation process may stall if ## stdout buffer gets filled with diagnostic or progress output from ## this script printed after chains are flushed but before a rule ## permitting ssh is installed. This may happen if script debugging is ## on or there are many NAT rules (so it prints a lot of "Rule NN ## (NAT)" lines). {{if mgmt_access}} # backup ssh access {{$begin_rule}} INPUT -p tcp -m tcp -s {{$ssh_management_address}} --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp -d {{$ssh_management_address}} --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{endif}} {{if drop_new_tcp_with_no_syn}} # drop TCP sessions opened prior firewall restart {{$begin_rule}} INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP {{$end_rule}} {{if ipforw}} {{$begin_rule}} FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP {{$end_rule}} {{endif}} {{endif}} {{if add_rules_for_ipv6_neighbor_discovery}} # rules to permit IPv6 Neighbor discovery {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{if bridging_firewall}} {{$begin_rule}} FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{$begin_rule}} FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT {{$end_rule}} {{endif}} {{endif}} {{if drop_invalid}} # drop packets that do not match any valid state {{$begin_rule}} OUTPUT -m state --state INVALID -j DROP {{$end_rule}} {{$begin_rule}} INPUT -m state --state INVALID -j DROP {{$end_rule}} {{if ipforw}} {{$begin_rule}} FORWARD -m state --state INVALID -j DROP {{$end_rule}} {{endif}} {{endif}} {{if drop_invalid_and_log}} # drop packets that do not match any valid state and log them {{$create_drop_invalid_chain}} {{$begin_rule}} OUTPUT -m state --state INVALID -j drop_invalid {{$end_rule}} {{$begin_rule}} INPUT -m state --state INVALID -j drop_invalid {{$end_rule}} {{if ipforw}} {{$begin_rule}} FORWARD -m state --state INVALID -j drop_invalid {{$end_rule}} {{endif}} {{if use_ulog}} {{$begin_rule}} drop_invalid -j ULOG {{if use_nlgroup}}--ulog-nlgroup {{$nlgroup}}{{endif}} {{if use_cprange}}--ulog-cprange {{$cprange}}{{endif}} {{if use_qthreshold}}--ulog-qthreshold {{$qthreshold}}{{endif}} --ulog-prefix {{$invalid_match_log_prefix}}{{$end_rule}} {{endif}} {{if not_use_ulog}} {{$begin_rule}} drop_invalid -j LOG --log-level debug --log-prefix {{$invalid_match_log_prefix}}{{$end_rule}} {{endif}} {{$begin_rule}} drop_invalid -j DROP {{$end_rule}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/update_vlans0000644000175000017500000000731011733011756024431 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ############ VLAN ############################################## ## /proc/net/vlan/config ## ## VLAN Dev name | VLAN ID ## Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD ## eth1.100 | 100 | eth1 ## eth1.101 | 101 | eth1 ## eth1.102 | 102 | eth1 ## ## Note about vlans: "ip link show" does not always accurately shows ## relationship between vlan subinterfaces and their parents. Example of ## the output where this happens (Sveasoft firmware for Linksys): ## ## ip link show | grep vlan ## 7: vlan0: mtu 1500 qdisc noqueue ## 8: vlan1: mtu 1500 qdisc noqueue missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@" set $vlan subint=$1 parent=$2 IFS=$oldIFS vlan_id=$(echo $subint | sed -r 's/(vlan|[^.]*\.)//') test "$cmd" = "add" && { echo $subint | grep -q "vlan" && name_type="VLAN_PLUS_VID" || name_type="DEV_PLUS_VID" test "$vlan_id" \< "1" || name_type="${name_type}_NO_PAD" echo "# Adding VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG set_name_type $name_type $FWBDEBUG $VCONFIG $cmd $parent $vlan_id $FWBDEBUG $IP link set $subint up } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (parent: $parent)" $FWBDEBUG $VCONFIG $cmd $subint } } parse_fwb_vlans() { set $1 vlan_parent_interface=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent_interface" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent_interface=$1 CURRENT_VLANS="" PROC_DIR="/proc/net/vlan/" test -d $PROC_DIR || $MODPROBE 8021q || { echo "$PROC_DIR does not exist. Vlan interfaces are not available." exit 1 } test -f "/proc/net/vlan/config" && { CURRENT_VLANS=$( cat /proc/net/vlan/config | grep -v 'Dev name' | grep $vlan_parent_interface | \ while read subint a vlan_id b parent; do echo "${subint}@$parent" done | sort ) } echo $CURRENT_VLANS } update_vlans_of_interface() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } add_vlans() { args="$1" set $1 vlan_parent_interface=$1 FWB_VLANS=$(parse_fwb_vlans $args) CURRENT_VLANS=$(parse_current_vlans $vlan_parent_interface) $IP link set $vlan_parent_interface up diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add } ## This function removes vlan interfaces not configured in fwbuilder. ## Missing vlans are added using function update_vlans ## ## clear_vlans_except_known eth1.100@eth1 eth1.101@eth1 vlan200@eth2 ## ## Call shown above would keep listed vlans but remove eth3.300 ## clear_vlans_except_known() { FWB_VLANS=$* CURRENT_VLANS=$(parse_current_vlans '|') diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } fwbuilder-5.1.0.3599/src/res/configlets/linux24/run_time_address_tables0000644000175000017500000001174311733011756026632 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## this function checks if ipset actually can work on the system note ## that we check if it is present separately in check_utilities ## configlet By this time, it is assumed the utility is installed and ## is available, but we still need to check if it works properly ## because it also depends on the kernel module. ## ## ipset -V checks the version of ipset utility and kernel module and ## is a good way to check if the utility can communicate with the module. ## Unfortunately "ipset -V" returns 0 return code even in the case of ## an error. Will use "ipset --list" which fails when it can't talk to ## the module and then use ipset -V to get diagnostics. {{if using_ipset}} check_module_ipset() { $IPSET --list > /dev/null 2>&1 || { echo "Detected an error with ipset utility :" $IPSET -V exit 1 } } ## reloads ipset from the data file. The file must have one address ## per line. The difficulty with ipset is that no set type accepts a ## mix of individual ip addresses and CIDR blocks. Set type iphash ## takes only ip addresses and type nethash takes only CIDR blocks ## with netmask between 1 and 31 bits (no 32 bits). Using a setlist ## set with two sub-sets, one for addresses and another for subnets. ## reload_address_table() { addrtbl_name=$1 data_file=$2 test -z "$addrtbl_name" -o -z "$data_file" && { echo "Usage: reload_address_table address_table_object_name file_name" exit 1 } $IPSET -X tmp_fwb_set:ip -q $IPSET -X tmp_fwb_set:net -q $IPSET -N tmp_fwb_set:ip iphash $IPSET -N tmp_fwb_set:net nethash grep -Ev '^#|^;|^\s*$' $data_file | while read L ; do set $L addr=$1 if echo $addr | grep -q "/" then $IPSET -A tmp_fwb_set:net $addr else $IPSET -A tmp_fwb_set:ip $addr fi done $IPSET --list ${addrtbl_name}:ip >/dev/null || $IPSET -N ${addrtbl_name}:ip iphash $IPSET --list ${addrtbl_name}:net >/dev/null || $IPSET -N ${addrtbl_name}:net nethash $IPSET -W ${addrtbl_name}:ip tmp_fwb_set:ip $IPSET -W ${addrtbl_name}:net tmp_fwb_set:net $IPSET --list ${addrtbl_name} >/dev/null || { $IPSET -N ${addrtbl_name} setlist } $IPSET --list ${addrtbl_name} | grep -q ${addrtbl_name}:ip || { $IPSET -A ${addrtbl_name} ${addrtbl_name}:ip } $IPSET --list ${addrtbl_name} | grep -q ${addrtbl_name}:net || { $IPSET -A ${addrtbl_name} ${addrtbl_name}:net } $IPSET -X tmp_fwb_set:ip $IPSET -X tmp_fwb_set:net } add_to_address_table() { addrtbl_name=$1 data_file=$2 address=$3 test -z "$addrtbl_name" -o -z "$data_file" -o -z "$address" && { echo "Usage: add_to_address_table address_table_object_name file_name address" exit 1 } echo $address >> $data_file if echo $address | grep -q "/" then $IPSET -A ${addrtbl_name}:net $address else $IPSET -A ${addrtbl_name}:ip $address fi } remove_from_address_table() { addrtbl_name=$1 data_file=$2 address=$3 test -z "$addrtbl_name" -o -z "$data_file" -o -z "$address" && { echo "Usage: remove_from_address_table address_table_object_name file_name address" exit 1 } ## note that $address may contain "/" escaped_addr=$(echo $address | sed 's!/!\\/!') sed -i "/^ *$escaped_addr *\$/d" $data_file if echo $address | grep -q "/" then $IPSET -D ${addrtbl_name}:net $address else $IPSET -D ${addrtbl_name}:ip $address fi } test_address_table() { addrtbl_name=$1 address=$2 test -z "$addrtbl_name" -o -z "$address" && { echo "Usage: test_address_table address_table_object_name address" exit 1 } if echo $address | grep -q "/" then $IPSET -T ${addrtbl_name}:net $address else $IPSET -T ${addrtbl_name}:ip $address fi } load_run_time_address_table_files() { : {{$load_files_commands}} } {{endif}} check_file() { test -r "$2" || { echo "Can not find file $2 referenced by address table object $1" exit 1 } } ## function to check if the data file is available. This is done ## regardless of whether we use module ipset or not. ## Since macro language does not support loops at this time, whole ## code for the body of this function is generated in ## OSConfigurator_linux24::printRunTimeAddressTablesCode() check_run_time_address_table_files() { : {{$check_files_commands}} } fwbuilder-5.1.0.3599/src/res/configlets/linux24/script_body_iptables_shell0000644000175000017500000000157611733011756027347 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## this template is used for single rule compile, both ## iptables-restore and regular, as well as for the regular ## (not iptables-restore) script {{if auto}}{{$filter_auto_script}} {{$mangle_auto_script}}{{endif}} {{if nat}}{{$nat_script}}{{endif}} {{if mangle}}{{$mangle_script}}{{endif}} {{if filter}}{{$filter_script}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/update_addresses0000644000175000017500000001242511733011756025266 0ustar sylvestresylvestre## -*- 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. ## ############ add or remove ip addresses of interfaces ####################### P2P_INTERFACE_WARNING="" missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS ## as of v4.0 we do not manage addresses of point-to-point ## interfaces. The output of "ip addr show" command for these inetrfaces has ## word "POINTOPOINT". ## Since the user can not define interface address without netmask in ## fwbuilder GUI, the script always assumes the address of p2p ## interface has one. It is therefore something like 1.2.3.4/32. The ## address in the output of "ip addr show" command does not have any ## netmask, like in ## ## 10: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500 ## link/[65534] ## inet 10.0.0.100 peer 10.0.0.200 scope global tun0 ## ## This means, we always have a discrepancy and the script will always ## want to update the address, even if the address defined in the GUI ## matches the one on the interface, the only difference being the ## missing netmask. This leads to many repetitive warnings. We get two ## warnings even if there is only one p2p interface. Using global ## variable to suppress redundant warnings. This means the user will ## see only one warning, citing the name of the first p2p interface ## even if they have many. $IP addr show dev $interface | grep -q POINTOPOINT && { test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet" P2P_INTERFACE_WARNING="yes" return } test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" ## Use "broadcast +" syntax to make ip assign broadcast automatically, ## but only for ipv4 addresses echo $addr | grep -q ':' && { $FWBDEBUG $IP addr $cmd $addr dev $interface } || { $FWBDEBUG $IP addr $cmd $addr broadcast + dev $interface } } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" $FWBDEBUG $IP addr $cmd $addr dev $interface || exit 1 } $FWBDEBUG $IP link set $interface up } ## ## The list of current addresses is taken using "ip addr show" command. ## Second argument defines address scrope; it should be in the form ## of the matching regex such as "scope global" or "scope .*". ## list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 $IP addr ls dev $interface | \ awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \ while read addr; do echo "${addr}@$interface" done | sort } ## arg 1 is like "eth1 1.1.1.1/24 2.2.2.2/24 fe80::20c:29ff:fef6:bea0/64" ## arg 2 is "3.3.3.3/24 4.4.4.4/24" - list of addresses we should ignore ## Using arg2 to provide list of addresses managed by heartbeat, so that ## incremental update does not delete them. ## ## Only "scope global" addreses are managed because fwbuilder script ## should not try to delete addresses configured for tunnels and IPv6 ## link scope addresses (fe80::) ("scope link" or "scope host" addresses) ## ## Addresses we should ignore are dropped from the list. ## update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IP link show dev $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } ## this function removes addresses from interfaces that do not exist in ## fwbuilder config. ## ## Usage: ## remove_unconfigured_addresses lo eth0 eth1 eth2.100 vlan20 br0 ## ## Arguments are all interfaces that have addresses in ## fwbuilder. Addresses will be removed from all other interfaces with ## addresses found on the firewall. ## clear_addresses_except_known_interfaces() { $IP link show | sed 's/://g' | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/state/ && !($2 in ignored_dict)) {print $2;}' | \ while read intf; do echo "# Removing addresses not configured in fwbuilder from interface $intf" $FWBDEBUG $IP addr flush dev $intf scope global $FWBDEBUG $IP link set $intf down done } fwbuilder-5.1.0.3599/src/res/configlets/linux24/kernel_vars0000644000175000017500000000464011733011756024262 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if if_linux24_ip_dynaddr}} echo {{$linux24_ip_dynaddr}} > /proc/sys/net/ipv4/ip_dynaddr {{endif}} {{if if_linux24_rp_filter}} echo {{$linux24_rp_filter}} > /proc/sys/net/ipv4/conf/all/rp_filter {{endif}} {{if if_linux24_accept_source_route}} echo {{$linux24_accept_source_route}} > /proc/sys/net/ipv4/conf/all/accept_source_route {{endif}} {{if if_linux24_accept_redirects}} echo {{$linux24_accept_redirects}} > /proc/sys/net/ipv4/conf/all/accept_redirects {{endif}} {{if if_linux24_log_martians}} echo {{$linux24_log_martians}} > /proc/sys/net/ipv4/conf/all/log_martians {{endif}} {{if if_linux24_icmp_echo_ignore_broadcasts}} echo {{$linux24_icmp_echo_ignore_broadcasts}} > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts {{endif}} {{if if_linux24_icmp_echo_ignore_all}} echo {{$linux24_icmp_echo_ignore_all}} > /proc/sys/net/ipv4/icmp_echo_ignore_all {{endif}} {{if if_linux24_icmp_ignore_bogus_error_responses}} echo {{$linux24_icmp_ignore_bogus_error_responses}} > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses {{endif}} {{if if_linux24_tcp_fin_timeout}} echo {{$linux24_tcp_fin_timeout}} > /proc/sys/net/ipv4/tcp_fin_timeout {{endif}} {{if if_linux24_tcp_keepalive_interval}} echo {{$linux24_tcp_keepalive_interval}} > /proc/sys/net/ipv4/tcp_keepalive_intvl {{endif}} {{if if_linux24_tcp_window_scaling}} echo {{$linux24_tcp_window_scaling}} > /proc/sys/net/ipv4/tcp_window_scaling {{endif}} {{if if_linux24_tcp_sack}} echo {{$linux24_tcp_sack}} > /proc/sys/net/ipv4/tcp_sack {{endif}} {{if if_linux24_tcp_fack}} echo {{$linux24_tcp_fack}} > /proc/sys/net/ipv4/tcp_fack {{endif}} {{if if_linux24_tcp_syncookies}} echo {{$linux24_tcp_syncookies}} > /proc/sys/net/ipv4/tcp_syncookies {{endif}} {{if if_linux24_tcp_ecn}} echo {{$linux24_tcp_ecn}} > /proc/sys/net/ipv4/tcp_ecn {{endif}} {{if if_linux24_tcp_timestamps}} echo {{$linux24_tcp_timestamps}} > /proc/sys/net/ipv4/tcp_timestamps {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/update_bridge0000644000175000017500000001025011733011756024537 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ############ bridge ############################################ ## brctl show ## bridge name bridge id STP enabled interfaces ## br0 8000.000c29f6bebe no eth4.102 ## eth5 ## missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $cmd $bridge_interface $port" $FWBDEBUG $BRCTL $cmd $bridge_interface $port test "$cmd" = "addif" && $FWBDEBUG $IP link set $port up } # update_bridge br0 "eth2 eth3" update_bridge() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCTL showmacs $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $BRCTL addbr $bridge_interface $FWBDEBUG $IP link set $bridge_interface up } PORTS=$( $BRCTL show | \ awk '($1~/^br/) { printf "\n"; } (!/bridge name/ && NF>3) {printf "%s %s ", $1,$NF;} (NF==1) {printf "%s ",$1;}' | grep $bridge_interface ) test -n "$PORTS" && { set $PORTS shift CURRENT_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" delif diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addif } ## This function synchronizes bridge interfaces between fwbuilder objects ## and actual configuration of the firewall machine. Birgde interfaces not ## listed as arguments will be deleted and those in the arguments will be ## created if missing. ## ## NOTE: we have to delete and create bridge interfaces before we add ## bridge ports to them because if a bridge interface that was not ## configured in fwbuilder existed before this script ran, its bridge ## ports could not be added to other bridges. This bridge interface ## should be deleted first. ## ## sync_bridge_interfaces br0 br1 sync_bridge_interfaces() { $BRCTL show | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^br[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IP link set $brintf down $FWBDEBUG $BRCTL delbr $brintf done for brint in $*; do $BRCTL showmacs $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $BRCTL addbr $brint $FWBDEBUG $IP link set $brint up } done } fwbuilder-5.1.0.3599/src/res/configlets/linux24/stop_action0000644000175000017500000000206611733011756024271 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## This configlet defines commands executed when iptables script is ran ## with command line argument "stop". By default it resets iptables ## tables and chains using function reset_all and sets all chains ## default policy to ACCEPT stop_action() { reset_all {{if have_ipv4}} $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT {{endif}} {{if have_ipv6}} $IP6TABLES -P OUTPUT ACCEPT $IP6TABLES -P INPUT ACCEPT $IP6TABLES -P FORWARD ACCEPT {{endif}} } fwbuilder-5.1.0.3599/src/res/configlets/linux24/installer_commands_root0000644000175000017500000000146511733011756026672 0ustar sylvestresylvestre## -*- 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 root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## {{if run}} echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sh {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/run_time_wrappers0000644000175000017500000000364411733011756025517 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if no_wrapper}} {{$command}} {{endif}} {{if address_table}} grep -Ev '^#|^;|^\s*$' {{$address_table_file}} | while read L ; do set $L; at_{{$address_table_var}}=$1; {{$command}} done {{endif}} ## ## Current implementation supports only one wildcard interface per rule. ## This can be something like "ppp*" ## {{if wildcard_interface}} getinterfaces {{$interface_family_name}} | while read I; do ivar=$(getInterfaceVarName $I) getaddr{{if ipv6}}6{{endif}} $I $ivar cmd="$"${ivar}_list eval "addr_list=$cmd" for addr in $addr_list do test -n "$addr" && {{$command}} done done {{endif}} ## If the rule uses address of dynamic interface, there can be either ## one such address or two (source and destination). It impossible to ## have more than two. ## ## intf_name is the name of the interface plus "_v6" suffix if ipv6 ## such as "ppp0" or "ppp0_v6" ## This is so because we call getaddr6 function with variable name ## constructed with suffix _v6 ## {{if one_dyn_addr}} for i_{{$intf_1_var_name}} in $i_{{$intf_1_var_name}}_list do test -n "$i_{{$intf_1_var_name}}" && {{$command}} done {{endif}} {{if two_dyn_addr}} for i_{{$intf_1_var_name}} in $i_{{$intf_1_var_name}}_list do for i_{{$intf_2_var_name}} in $i_{{$intf_2_var_name}}_list do test -n "$i_{{$intf_1_var_name}}" && test -n "$i_{{$intf_2_var_name}}" && {{$command}} done done {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/configure_interfaces0000644000175000017500000000143511733011756026132 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Double '##' comments are removed when configlet is processed. ## Single '#' comments stay. ## ## Some shells (not bash) do not like empty functions. Placing a comment ## inside the function does not help. Using dummy ":" as a placeholder. ## {{if have_interfaces}} {{if need_promote_command}} # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=429689 # this ensures that secondary ip address is "promoted" to primary # when primary address is deleted, instead of deleting both # primary and secondary addresses. It looks like this is only # available starting from Linux 2.6.16 test -f /proc/sys/net/ipv4/conf/all/promote_secondaries && \ echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries {{endif}} {{$configure_interfaces_script}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/ip_forwarding0000644000175000017500000000131111733011756024571 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if ipv4}} echo {{$ipv4_forw}} > /proc/sys/net/ipv4/ip_forward {{endif}} {{if ipv6}} echo {{$ipv6_forw}} > /proc/sys/net/ipv6/conf/all/forwarding {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/linux24/status_action0000644000175000017500000000316411733011756024627 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## This configlet defines commands executed when iptables script is ran ## with command line argument "status". Exit codes are defined in ## http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html ## Script should return with exit code 0 if iptables rules are loaded and ## 1 otherwise. We can not verify that the rules running at the moment ## are those configured in this script so we only check if some rules ## exist by checking if any tables are defined. check_iptables() { IP_TABLES="$1" [ ! -e $IP_TABLES ] && return 151 NF_TABLES=$(cat $IP_TABLES 2>/dev/null) [ -z "$NF_TABLES" ] && return 152 return 0 } status_action() { check_iptables "/proc/net/ip_tables_names" ret_ipv4=$? check_iptables "/proc/net/ip6_tables_names" ret_ipv6=$? [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0 [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && { echo "iptables modules are not loaded" } [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && { echo "Firewall is not configured" } exit 3 } fwbuilder-5.1.0.3599/src/res/configlets/linux24/constants0000644000175000017500000000124211733011756023756 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Place any constant definitions for the generated script here ## This code appears at the very top of the script. fwbuilder-5.1.0.3599/src/res/configlets/linux24/prolog_epilog_functions0000644000175000017500000000137611733011756026703 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } fwbuilder-5.1.0.3599/src/res/configlets/linux24/load_modules0000644000175000017500000000365411733011756024422 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## This is the body of the shell function load_modules(). I keep ## function definition in the script_skeleton configlet to make it ## more readable (the function and call to it are in the file, both ## clearly visible). I could put the code for the body of load_modules ## function in the script_skeleton configlet as well, but I keep it ## separate to make script_skeleton small and clean. ## ## Function load_modules is called with one parameter. This parameter ## is a space-separated list of options. Options (words) "nat" and ## "ipv6" are recognized. PArameter can be "", "nat", "ipv6", ## "nat ipv6" If word "nat" is included, the function should also load ## modules for nat. If word "ipv6" is included, it should also load ## module nf_conntrack_ipv6 {{if load_modules}} OPTS=$1 MODULES_DIR="{{$modules_dir}}" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi $MODPROBE ${module} || exit 1 done {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/procurve/0000755000175000017500000000000011733011756022360 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/procurve/safety_net_acl0000644000175000017500000000246211733011756025267 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/procurve/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ; temporary access list for "safety net install" {{if ipv4}} {{if management_interface_is_vlan}} no vlan {{$management_interface_vlan_id}} ip access-group tmp_acl in no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip {{$management_addr}} {{$management_netm}} any deny ip any any exit vlan {{$management_interface_vlan_id}} ip access-group tmp_acl in {{endif}} {{if management_interface_is_not_vlan}} interface {{$management_interface}} no ip access-group tmp_acl in exit no ip access-list extended tmp_acl ip access-list extended tmp_acl permit ip {{$management_addr}} {{$management_netm}} any deny ip any any exit interface {{$management_interface}} ip access-group tmp_acl in exit {{endif}} {{endif}} {{if ipv6}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/procurve/script_skeleton0000644000175000017500000000154411733011756025517 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/procurve/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{$top_comment}} {{$errors_and_warnings}} ; ; Prolog script: ; {{$prolog_script}} ; ; End of prolog script: ; {{$other_os_configuration_commands}} {{$system_configuration_script}} {{$policy_script}} {{$nat_script}} {{$routing_script}} ; ; Epilog script: ; {{$epilog_script}} ; End of epilog script: ; fwbuilder-5.1.0.3599/src/res/configlets/procurve/top_comment0000644000175000017500000000036211733011756024630 0ustar sylvestresylvestre; ; This is automatically generated file. DO NOT MODIFY ! ; ; Firewall Builder fwb_procurve_acl v{{$version}} ; ; Generated {{$timestamp}} {{$tz}} by {{$user}} ; ; Compiled for {{$platform}} {{$fw_version}} ; {{$manifest}} ; {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/procurve/installer_commands_reg_user0000644000175000017500000000165111733011756030057 0ustar sylvestresylvestre## -*- 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 ("flash:" or "nvram:" or similar) ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## ## {{$firewall_name}} -- the name of the firewall object ## {{if using_scp}} copy {{$fwdir}}{{$fwscript}} running-config {{endif}} {{if not_using_scp}} config term {{$fwbuilder_generated_configuration_lines}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/procurve/installer_commands_post_config0000644000175000017500000000062111733011756030552 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout ## {{$test}} -- doing installation in test mode ## {{if cancel_rollback}} no reload {{endif}} {{if run}} wr mem {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/procurve/installer_commands_pre_config0000644000175000017500000000073511733011756030361 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout (min) ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## {{$test}} -- doing installation in test mode ## terminal width 256 no page {{if schedule_rollback}} reload after {{$rbtimeout}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/0000755000175000017500000000000011733011756022014 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/pix_os/failover_commands_60000644000175000017500000000237011733011756025656 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## http://www.cisco.com/en/US/docs/security/pix/pix63/configuration/guide/failover.html ## ## failover ip address outside 209.165.201.2 ## failover ip address inside 192.168.2.2 ## failover ip address failover 192.168.254.2 ## failover ip address state 192.168.253.2 ## failover link state ## failover lan unit primary ## failover lan interface failover ## failover lan key 12345678 ## failover lan enable ## failover ## ## ## "failover ip address" commands are added bu the failover_interface_6 configlet failover link {{$state_sync_interface_label}} failober lan unit {{$primary_or_secondary}} failover lan interface {{$failover_interface_label}} failover key {{$failover_key}} failover lan enable failover fwbuilder-5.1.0.3599/src/res/configlets/pix_os/vlan_subinterface_60000644000175000017500000000207011733011756025655 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## interface ethernet0 vlan3 logical {{if static_address}} interface {{$parent_interface}} {{$interface_name}} logical nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}} ip address {{$interface_label}} {{$address}} {{$netmask}} {{endif}} {{endif}} {{if dhcp_address}} nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}} ip address {{$interface_label}} dhcp setroute retry 10 {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/regular_interface_70000644000175000017500000000204411733011756025646 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if static_address}} interface {{$interface_name}} nameif {{$interface_label}} {{if configure_interface_address}} ip address {{$address}} {{$netmask}} {{if configure_standby_address}} standby {{$standby_address}} {{endif}} {{endif}} security-level {{$security_level}} exit {{endif}} {{if dhcp_address}} interface {{$interface_name}} nameif {{$interface_label}} {{if configure_interface_address}} ip address dhcp setroute {{endif}} security-level {{$security_level}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/vlan_parent_interface_70000644000175000017500000000120111733011756026510 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## interface {{$interface_name}} no nameif no ip address no security-level exit fwbuilder-5.1.0.3599/src/res/configlets/pix_os/failover_interface_70000644000175000017500000000120711733011756026014 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## interface {{$interface_name}} description LAN/STATE Failover Interface no nameif exit fwbuilder-5.1.0.3599/src/res/configlets/pix_os/ntp0000644000175000017500000000202511733011756022537 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if clear}} {{if pix_version_lt_70}} clear ntp {{endif}} {{if pix_version_ge_70}} clear config ntp {{endif}} {{endif}} {{if not_server_1_empty}}ntp server {{$address_1}} source {{$interface_1_label}} {{if prefer_1}}prefer{{endif}} {{endif}} {{if not_server_2_empty}}ntp server {{$address_2}} source {{$interface_2_label}} {{if prefer_2}}prefer{{endif}} {{endif}} {{if not_server_3_empty}}ntp server {{$address_3}} source {{$interface_3_label}} {{if prefer_3}}prefer{{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/script_skeleton0000644000175000017500000000355011733011756025152 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Double '##' comments are removed when configlet is processed. ## Single '#' comments stay. ## ## {{$system_configuration_script}} -- commands to configure ## interfaces, snmp, syslog, ntp etc. ## {{$preamble_commands}} -- commands to configure temporary ## access list in "safety net install" ## mode and to set up FWSM commit mode. ## {{$clear_commands}} -- clear commands for access lists, global, ## static, nat, icmp, telnet, ssh, http, ## object-group ## ## {{$top_comment}} {{$errors_and_warnings}} ! ! Prolog script: ! {{$prolog_script}} ! ! End of prolog script: ! {{if short_script}} ! This script was generated with option "Generate only access-list, access-group, ! nat, static, global" commands turned on in the "Script" tab of the firewall ! object advanced settings dialog. Skipping system configuration commands. {{endif}} {{if not_short_script}} {{$system_configuration_script}} {{endif}} {{$preamble_commands}} {{$clear_commands}} {{$named_objects_and_object_groups}} {{$policy_script}} {{$nat_script}} {{$routing_script}} ! ! Epilog script: ! {{$epilog_script}} ! End of epilog script: ! fwbuilder-5.1.0.3599/src/res/configlets/pix_os/vlan_subinterface_70000644000175000017500000000211411733011756025655 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if static_address}} interface {{$interface_name}} vlan {{$vlan_id}} nameif {{$interface_label}} {{if configure_interface_address}} ip address {{$address}} {{$netmask}} {{if configure_standby_address}} standby {{$standby_address}} {{endif}} {{endif}} security-level {{$security_level}} exit {{endif}} {{if dhcp_address}} interface {{$interface_name}} vlan {{$vlan_id}} nameif {{$interface_label}} {{if configure_interface_address}} ip address dhcp setroute {{endif}} security-level {{$security_level}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/top_comment0000644000175000017500000000064611733011756024271 0ustar sylvestresylvestre! ! This is automatically generated file. DO NOT MODIFY ! ! ! Firewall Builder fwb_pix v{{$version}} ! ! Generated {{$timestamp}} {{$tz}} by {{$user}} ! ! Compiled for {{$platform}} {{$fw_version}} ! Outbound ACLs: {{$outbound_acl_supported}} ! Emulate outbound ACLs: {{$emulate_outb_acls}} ! Generating outbound ACLs: {{$generate_outb_acls}} ! Assume firewall is part of any: {{$afpa}} ! {{$manifest}} ! {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/vlan_parent_interface_60000644000175000017500000000105711733011756026520 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## fwbuilder-5.1.0.3599/src/res/configlets/pix_os/regular_interface_60000644000175000017500000000206611733011756025651 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if static_address}} nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}}ip address {{$interface_label}} {{$address}} {{$netmask}} {{endif}} {{if configure_standby_address}}failover ip address {{$interface_label}} {{$standby_address}} {{endif}} {{endif}} {{if dhcp_address}} nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}}ip address {{$interface_label}} dhcp setroute retry 10 {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/ssh0000644000175000017500000000150011733011756022530 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if clear}} {{if pix_version_lt_70}} clear ssh {{endif}} {{if pix_version_ge_70}} clear config ssh {{endif}} {{endif}} aaa authentication ssh console LOCAL {{if use_scp}} ssh version 2 ssh scopy enable {{endif}} {{if ssh_timeout}} ssh timeout {{$ssh_timeout}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/installer_commands_reg_user0000644000175000017500000000171311733011756027512 0ustar sylvestresylvestre## -*- 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 (in case of PIX, "flash:" or similar) ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## ## {{$firewall_name}} -- the name of the firewall object ## {{if using_scp}} copy /noconfirm {{$fwdir}}{{$fwscript}} running-config {{endif}} {{if not_using_scp}} config term terminal width 256 {{$fwbuilder_generated_configuration_lines}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/failover_commands_70000644000175000017500000000273611733011756025665 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## failover ## failover lan unit primary ## failover lan interface failover Ethernet3 ## failover lan enable ## failover key ****** ## failover link state Ethernet2 ## failover interface ip failover 10.1.0.1 255.255.255.0 standby 10.1.0.2 ## failover interface ip state 10.0.0.1 255.0.0.0 standby 10.0.0.2 failover lan unit {{$primary_or_secondary}} failover lan interface {{$failover_interface_label}} {{$failover_interface_name}} failover lan enable failover key {{$failover_key}} failover interface ip {{$failover_interface_label}} {{$failover_interface_primary_address}} {{$failover_interface_primary_netmask}} standby {{$failover_interface_standby_address}} failover link {{$state_sync_interface_label}} {{$state_sync_interface_name}} failover interface ip {{$state_sync_interface_label}} {{$state_sync_interface_primary_address}} {{$state_sync_interface_primary_netmask}} standby {{$state_sync_interface_standby_address}} failover fwbuilder-5.1.0.3599/src/res/configlets/pix_os/installer_commands_post_config0000644000175000017500000000070011733011756030204 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout ## {{$test}} -- doing installation in test mode ## {{if cancel_rollback}} reload cancel {{endif}} {{if run}} wr mem {{endif}} {{if save_standby}} wr standby {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/failover_interface_60000644000175000017500000000151011733011756026010 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}}ip address {{$interface_label}} {{$address}} {{$netmask}} {{endif}} {{if configure_standby_address}}failover ip address {{$interface_label}} {{$standby_address}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/installer_commands_pre_config0000644000175000017500000000060611733011756030012 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout ## {{$test}} -- doing installation in test mode ## {{if schedule_rollback}} reload in {{$rbtimeout}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/pix_os/snmp0000644000175000017500000000241011733011756022711 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if clear}} {{if pix_version_lt_70}} clear snmp-server {{endif}} {{if pix_version_ge_70}} clear config snmp-server {{endif}} {{endif}} {{if disable}} no snmp-server {{endif}} {{if not_disable}} {{if set_community}} snmp-server community {{$read_community}} {{endif}} {{if set_sysinfo}} {{if not_location_empty}}snmp-server location {{$location}}{{endif}} {{if not_contact_empty}}snmp-server contact {{$contact}}{{endif}} {{endif}} {{if not_enable_traps}}no {{endif}}snmp-server enable traps {{if not_server_1_empty}}snmp-server host {{$interface_1_label}} {{$address_1}} {{$poll_or_trap_1}} {{endif}} {{if not_server_2_empty}}snmp-server host {{$interface_2_label}} {{$address_2}} {{$poll_or_trap_2}} {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ipfw/0000755000175000017500000000000011733011756021460 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/ipfw/script_skeleton0000644000175000017500000000242511733011756024616 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipfw/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{$top_comment}} {{$errors_and_warnings}} {{$shell_debug}} cd {{$firewall_dir}} || exit 1 {{$tools}} {{$shell_functions}} verify_interfaces() { : {{$verify_interfaces}} } set_kernel_vars() { : {{$kernel_vars_commands}} } prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } log "Activating firewall script generated {{$timestamp}} by {{$user}}" set_kernel_vars configure_interfaces prolog_commands {{$activation_commands}} epilog_commands "$IPFW" set swap 0 1 || exit 1 "$IPFW" delete set 1 fwbuilder-5.1.0.3599/src/res/configlets/ipfw/top_comment0000644000175000017500000000036411733011756023732 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipfw v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} # {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/ipcop/0000755000175000017500000000000011733011756021625 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/ipcop/shell_functions0000644000175000017500000000205711733011756024753 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by AddressTable object $1" exit 1 } } getInterfaceVarName() { echo $1 | sed 's/\./_/' } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } fwbuilder-5.1.0.3599/src/res/configlets/ipcop/script_skeleton0000644000175000017500000000321311733011756024757 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{$top_comment}} {{$shell_debug}} {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } script_body() { {{$script_body}} } reset_all() { : {{$reset_all}} } case "$1" in start) check_tools check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} verify_interfaces prolog_commands script_body epilog_commands ;; stop) # on IPCOP "/etc/rc.firewall stop" purges all tables and chains # and then calls this script with command "stop", but there is # nothing left for us to do here. ;; reload) $0 stop $0 start ;; *) echo "Usage $0 {start|stop|reload}" ;; esac fwbuilder-5.1.0.3599/src/res/configlets/ipcop/update_bonding0000644000175000017500000000114511733011756024533 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## fwbuilder does not manage bonding interfaces on IPCOP fwbuilder-5.1.0.3599/src/res/configlets/ipcop/installer_commands_reg_user0000644000175000017500000000221511733011756027321 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## ## On IPCOP we use standard system script to reload firewall policy {{if run}} /etc/rc.d/rc.firewall restart {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ipcop/automatic_rules0000644000175000017500000000727011733011756024756 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## Each rule must start with {{$begin_rule}} and end with ## {{$end_rule}}. Variable $begin_rule has value "$IPTABLES -A" if ## generated script is in the shell script format, or just empty ## string if it is in iptables-restore format ## IPCOP runs ssh on port 222 {{if mgmt_access}} # backup ssh access {{$begin_rule}} INPUT -p tcp -m tcp -s {{$ssh_management_address}} --dport 222 -m state --state NEW,ESTABLISHED -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp -d {{$ssh_management_address}} --sport 222 -m state --state ESTABLISHED,RELATED -j ACCEPT {{$end_rule}} {{endif}} {{if drop_new_tcp_with_no_syn}} # drop TCP sessions opened prior firewall restart {{$begin_rule}} INPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP {{$end_rule}} {{$begin_rule}} OUTPUT -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP {{$end_rule}} {{if ipforw}} {{$begin_rule}} FORWARD -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP {{$end_rule}} {{endif}} {{endif}} {{if add_rules_for_ipv6_neighbor_discovery}} # rules to permit IPv6 Neighbor discovery {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT {{$end_rule}} {{$begin_rule}} INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT {{$end_rule}} {{$begin_rule}} OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT {{$end_rule}} {{endif}} {{if drop_invalid}} # drop packets that do not match any valid state {{$begin_rule}} OUTPUT -m state --state INVALID -j DROP {{$end_rule}} {{$begin_rule}} INPUT -m state --state INVALID -j DROP {{$end_rule}} {{if ipforw}} {{$begin_rule}} FORWARD -m state --state INVALID -j DROP {{$end_rule}} {{endif}} {{endif}} {{if drop_invalid_and_log}} # drop packets that do not match any valid state and log them {{$create_drop_invalid_chain}} {{$begin_rule}} OUTPUT -m state --state INVALID -j drop_invalid {{$end_rule}} {{$begin_rule}} INPUT -m state --state INVALID -j drop_invalid {{$end_rule}} {{if ipforw}} {{$begin_rule}} FORWARD -m state --state INVALID -j drop_invalid {{$end_rule}} {{endif}} {{if use_ulog}} {{$begin_rule}} drop_invalid -j ULOG {{if use_nlgroup}}--ulog-nlgroup {{$nlgroup}}{{endif}} {{if use_cprange}}--ulog-cprange {{$cprange}}{{endif}} {{if use_qthreshold}}--ulog-qthreshold {{$qthreshold}}{{endif}} --ulog-prefix {{$invalid_match_log_prefix}}{{$end_rule}} {{endif}} {{if not_use_ulog}} {{$begin_rule}} drop_invalid -j LOG --log-level debug --log-prefix {{$invalid_match_log_prefix}}{{$end_rule}} {{endif}} {{$begin_rule}} drop_invalid -j DROP {{$end_rule}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/ipcop/update_vlans0000644000175000017500000000113011733011756024230 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## fwbuilder does not manage vlans on IPCOP fwbuilder-5.1.0.3599/src/res/configlets/ipcop/update_addresses0000644000175000017500000000115511733011756025071 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## fwbuilder does not manage ip addresses of interfaces on IPCOP fwbuilder-5.1.0.3599/src/res/configlets/ipcop/kernel_vars0000644000175000017500000000114411733011756024063 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Fwbuilder does not control kernel variables on IPCOP fwbuilder-5.1.0.3599/src/res/configlets/ipcop/update_bridge0000644000175000017500000000114411733011756024346 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## fwbuilder does not manage bridge interfaces on IPCOP fwbuilder-5.1.0.3599/src/res/configlets/ipcop/installer_commands_root0000644000175000017500000000220611733011756026471 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/ipcop/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## On IPCOP we use standard system script to reload firewall policy {{if run}} /etc/rc.d/rc.firewall restart {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/openbsd/0000755000175000017500000000000011733011756022145 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/openbsd/routing_functions0000644000175000017500000000346711733011756025661 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## # ============== ROUTING RULES ============== TMPDIRNAME=`mktemp -d /tmp/.fwbuilder.XXXXXXXXXX` || exit 1 TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules route -n show -inet | awk '$3 ~ /S/ && $NF !~ /lo0/ { print $0;}' | \ while read route gw rest; do route delete $route $gw; done # restore old routing rules (IFS=" "; for route_cmd in $oldRoutes; do (IFS=' '; $route_cmd); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 oldRoutes=$(route -n show -inet | awk '{printf "route add %s %s\n",$1,$2;}') echo "Deleting routing rules previously set by user space processes..." route -n show -inet | grep S | grep -Ev {{$route_filter}} | \ while read route gw rest; do route delete $route $gw; done echo "Activating routing rules..." fwbuilder-5.1.0.3599/src/res/configlets/openbsd/installer_commands_reg_user0000644000175000017500000000314211733011756027641 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## See #1368 for the explanation of the need for the "sleep2; echo" commands ## On the other hand, since we use ssh keepalives in v4.0.2 and later, these ## commands may not be necessary anymore. ## ## Note: all commands should be on one line to avoid unnecessary linefeeds. ## These linefeeds are sent to the server side (to the firewall) and end up ## on the input of sudo and other commands. This creates difficult to catch ## race condition which breaks installation process. echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sudo -S {{$fwdir}}/{{$fwscript}} && (echo 'Policy activated'; sleep 2; echo) fwbuilder-5.1.0.3599/src/res/configlets/openbsd/tools0000644000175000017500000000130211733011756023224 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/openbsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Set path to all utilities that we need IFCONFIG="{{$path_ifconfig}}" PFCTL="{{$path_pfctl}}" SYSCTL="{{$path_sysctl}}" LOGGER="{{$path_logger}}" fwbuilder-5.1.0.3599/src/res/configlets/openbsd/kernel_vars0000644000175000017500000000207611733011756024410 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/openbsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if have_openbsd_ip_directed_broadcast}}$SYSCTL -w net.inet.ip.directed-broadcast={{$openbsd_ip_directed_broadcast}}{{endif}} {{if have_openbsd_ip_forward}}$SYSCTL -w net.inet.ip.forwarding={{$openbsd_ip_forward}}{{endif}} {{if have_openbsd_ipv6_forward}}$SYSCTL -w net.inet6.ip6.forwarding={{$openbsd_ipv6_forward}}{{endif}} {{if have_openbsd_ip_sourceroute}}$SYSCTL -w net.inet.ip.sourceroute={{$openbsd_ip_sourceroute}}{{endif}} {{if have_openbsd_ip_redirect}}$SYSCTL -w net.inet.ip.redirect={{$openbsd_ip_redirect}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/openbsd/installer_commands_root0000644000175000017500000000230611733011756027012 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## See #1368 for the explanation of the need for the "sleep2; echo" commands echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sh {{$fwdir}}/{{$fwscript}} && ( echo 'Policy activated'; sleep 2; echo ) fwbuilder-5.1.0.3599/src/res/configlets/bsd/0000755000175000017500000000000011733011756021263 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/bsd/shell_functions0000644000175000017500000000206611733011756024411 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. log() { echo "$1" command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } diff_intf() { func=$1 list1=$2 list2=$3 cmd=$4 for intf in $list1 do echo $list2 | grep -q $intf || { # $vlan is absent in list 2 $func $intf $cmd } done } {{if dyn_addr}} getaddr() { intf=$1 varname=$2 L=`ifconfig $1 | grep 'inet '` if [ -z "$L" ]; then L="inet 0.0.0.0/32" fi set $L a=$2 eval "$varname=$a" } {{$get_dyn_addr_commands}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/bsd/bridge_port0000644000175000017500000000046311733011756023511 0ustar sylvestresylvestre## -*- 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. ## $IFCONFIG {{$bridge_interface}} {{if stp_off}}-{{endif}}stp {{$bridge_port}} fwbuilder-5.1.0.3599/src/res/configlets/bsd/update_carp0000644000175000017500000000365011733011756023501 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ############ CARP interfaces ############################################ ## ## This function synchronizes carp interfaces between fwbuilder objects ## and actual configuration of the firewall machine. Carp interfaces not ## listed as arguments will be deleted and those in the arguments will be ## created if missing. ## ## This function only executes "ifconfig carp0 create" or "ifconfig carp0 destroy" ## commands. Other parameters of carp interfaces should be set up separately ## (see configlet carp_interface for that) ## ## sync_carp_interfaces carp0 carp1 sync_carp_interfaces() { $IFCONFIG {{if openbsd}}-A{{endif}} | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting carp interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating carp interface $intf" $SYSCTL -w net.inet.carp.allow=1 $FWBDEBUG $IFCONFIG $intf create || { echo "Error: CARP interface $intf could not be created. Does the kernel have CARP enabled?" exit 1 } } done } fwbuilder-5.1.0.3599/src/res/configlets/bsd/ifconfig_interface0000644000175000017500000000046611733011756025020 0ustar sylvestresylvestre## -*- 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. ## $IFCONFIG {{$interface_name}} {{if have_mtu}}mtu {{$mtu}}{{endif}} {{$options}} fwbuilder-5.1.0.3599/src/res/configlets/bsd/update_pfsync0000644000175000017500000000357511733011756024064 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ############ PFSYNC interfaces ############################################ ## ## This function synchronizes pfsync interfaces between fwbuilder objects ## and actual configuration of the firewall machine. Pfsync interfaces not ## listed as arguments will be deleted and those in the arguments will be ## created if missing. ## ## This function only executes "ifconfig pfsync0 create" or "ifconfig pfsync0 destroy" ## commands. Other parameters of pfsync interfaces should be set up separately ## (see configlet pfsync_interface for that) ## ## sync_pfsync_interfaces pfsync0 pfsync1 ## ## May be there can be only one pfsync interface ? The function in this configlet ## does not depend on this assumption. sync_pfsync_interfaces() { $IFCONFIG {{if openbsd}}-A{{endif}} | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^pfsync[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf destroy done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating pfsync interface $intf" $FWBDEBUG $IFCONFIG $intf create } done } fwbuilder-5.1.0.3599/src/res/configlets/bsd/update_vlans0000644000175000017500000000565211733011756023703 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ############ VLAN ############################################## ## arguments: ## ## $1: vlan_name:vlan_id@ e.g. vlan8101:101@em1 ## $2: command, can be "add" or "rem" ## missing_vlan() { vlan=$1 cmd=$2 oldIFS=$IFS IFS="@:" set $vlan subint=$1 vlan_id=$2 parent=$3 IFS=$oldIFS test "$cmd" = "add" && { echo "# Adding VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id vlandev $parent || exit 1 $FWBDEBUG $IFCONFIG $subint up || exit 1 } test "$cmd" = "rem" && { echo "# Removing VLAN interface $subint (vlan id: $vlan_id parent: $parent)" $FWBDEBUG $IFCONFIG $subint vlan $vlan_id -vlandev || exit 1 $FWBDEBUG $IFCONFIG $subint destroy || exit 1 } } parse_fwb_vlans() { set $1 vlan_parent=$1 shift FWB_VLANS=$( for subint in $*; do echo "${subint}@$vlan_parent" done | sort ) echo $FWB_VLANS } parse_current_vlans() { vlan_parent=$1 $IFCONFIG {{if openbsd}}-A{{endif}} | grep -E 'vlan[^ ]*:' | paste - - | \ sed 's/flags=.*vlan://;s/://g;s/parent interface//' | \ while read vlan_subint vlan_id parent do test "$parent" = "$vlan_parent" && echo "$vlan_subint:$vlan_id@$parent" done | sort } ## ## Call format: ## ## update_vlans_of_interface "pcn0 vlan101 vlan104" ## ## update_vlans_of_interface() { args="$1" set $1 vlan_parent=$1 FWB_VLANS=$(parse_fwb_vlans "$args") CURRENT_VLANS=$(parse_current_vlans $vlan_parent) $IFCONFIG $vlan_parent up || exit 1 diff_intf missing_vlan "$FWB_VLANS" "$CURRENT_VLANS" add diff_intf missing_vlan "$CURRENT_VLANS" "$FWB_VLANS" rem } sync_vlan_interfaces() { $IFCONFIG {{if openbsd}}-A{{endif}} | awk -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;} } ($1 ~ /^vlan[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\ while read intf; do echo "# Deleting vlan interface $intf" $FWBDEBUG $IFCONFIG $intf destroy || exit 1 done for intf in $*; do $IFCONFIG $intf >/dev/null 2>&1 || { echo "# Creating vlan interface $intf" $FWBDEBUG $IFCONFIG $intf create || exit 1 } done } fwbuilder-5.1.0.3599/src/res/configlets/bsd/carp_interface0000644000175000017500000000136711733011756024162 0ustar sylvestresylvestre## -*- 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. ## ## ## CARP ## ifconfig carp-interface [advbase n] [advskew n] [carpdev iface] ## [pass passphrase] [state state] [vhid host-id] ## ## for pfsync and CARP see http://www.kernel-panic.it/openbsd/carp/ ## "Redundant firewalls with OpenBSD, CARP and pfsync" $IFCONFIG {{$carp_interface}} vhid {{$vhid}} {{if have_password}}pass {{$carp_password}}{{endif}} {{if have_advbase}} advbase {{$advbase}}{{endif}} {{if have_advskew}} advskew {{$advskew}}{{endif}} {{if have_base_inetrface}} carpdev {{$base_inetrface}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/bsd/update_addresses0000644000175000017500000001052411733011756024527 0ustar sylvestresylvestre## -*- 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. ## ############ add or remove ip addresses of interfaces ####################### ## address (argument 1) is in the form of address/netmask, where ## netmask should be hex represenatation matching netmask in the ## output of ifconfig for ipv4 address. For ipv6 addresses netmask ## part should be given as prefix length. missing_address() { address=$1 cmd=$2 oldIFS=$IFS IFS="@" set $address addr=$1 interface=$2 IFS=$oldIFS if echo "$addr" | grep -q ':' then inet="inet6" addr=$(echo "$addr" | sed 's!/! prefixlen !') else inet="inet" addr=$(echo "$addr" | sed 's!/! netmask !') fi parameter="" test "$cmd" = "add" && { echo "# Adding ip address: $interface $addr" parameter="alias" } test "$cmd" = "del" && { echo "# Removing ip address: $interface $addr" parameter="delete" } $FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1 $FWBDEBUG $IFCONFIG $interface up } ## ## The list of current addresses is taken using "ifconfig $interface" ## command. Second argument defines address scrope; it should be in ## the form of the matching regex such as "scope global" or "scope ## .*". Unfortunately ifconfig prints "scopeid" for link and host ## scopes but does not print any "scopeid" parameter for the global ## scope (tested on OpenBSD 4.2). This means I have to invert the ## regex match logic and skip addresses with given scope (this is ## different from how this function works for addresses on Linux). If ## any non-empty scope string is given as second argument, this ## function will skip addresses with this scope. If this argument is ## an empty string, this function returns all addresses. ## list_addresses_by_scope() { interface=$1 scope=$2 ignore_list=$3 scope_regex="1" if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi $IFCONFIG $interface | sed "s/%$interface//" | \ awk -v IGNORED="$ignore_list" \ "BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } (/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \ while read addr; do echo "${addr}@$interface" done | sort } ## arg 1 is like "pcn1 1.1.1.1/24 2.2.2.2/24 fe80::20c:29ff:fef6:bea0/64" ## arg 2 is "3.3.3.3/24 4.4.4.4/24" - list of addresses we should ignore ## Using arg2 to provide list of addresses managed by heartbeat, so that ## incremental update does not delete them. ## ## Only "scope global" addreses are managed because fwbuilder script ## should not try to delete addresses configured for tunnels and IPv6 ## link scope addresses (fe80::) ("scope link" or "scope host" addresses) ## ## Addresses we should ignore are dropped from the list. ## update_addresses_of_interface() { ignore_list=$2 set $1 interface=$1 shift FWB_ADDRS=$( for addr in $*; do echo "${addr}@$interface" done | sort ) CURRENT_ADDRS_ALL_SCOPES="" CURRENT_ADDRS_GLOBAL_SCOPE="" $IFCONFIG $interface >/dev/null 2>&1 && { CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list") CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list") } || { echo "# Interface $interface does not exist" # Stop the script if we are not in test mode test -z "$FWBDEBUG" && exit 1 } ## carp interface on FreeBSD does not like to have two ip ## addresses. This means we should delete address first, then add new ## one. All other interfaces work with >1 address, so we add first, ## then delete to make sure there is no time window when interface has ## no address at all. echo "$interface" | grep -q carp && { diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add } || { diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del } } fwbuilder-5.1.0.3599/src/res/configlets/bsd/tools0000644000175000017500000000112311733011756022343 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Set path to all utilities that we need fwbuilder-5.1.0.3599/src/res/configlets/bsd/pfsync_interface0000644000175000017500000000110511733011756024525 0ustar sylvestresylvestre## -*- 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. ## ## ## PFSYNC ## ifconfig pfsync-interface [maxupd n] [[-]syncdev iface] ## [[-]syncpeer peer_address] ## ## for pfsync and CARP see http://www.kernel-panic.it/openbsd/carp/ ## "Redundant firewalls with OpenBSD, CARP and pfsync" $IFCONFIG pfsync0 syncdev {{$syncdev}} {{if have_syncpeer}} syncpeer {{$syncpeer}}{{endif}} $IFCONFIG pfsync0 up fwbuilder-5.1.0.3599/src/res/configlets/bsd/kernel_vars0000644000175000017500000000104711733011756023523 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. fwbuilder-5.1.0.3599/src/res/configlets/bsd/bridge_interface0000644000175000017500000000045011733011756024461 0ustar sylvestresylvestre## -*- 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. ## update_bridge_interface {{$bridge_interface}} "{{$bridge_ports}}" fwbuilder-5.1.0.3599/src/res/configlets/bsd/update_bridge0000644000175000017500000000763211733011756024014 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if openbsd_lt_47}} BRCONFIG="brconfig" {{endif}} {{if openbsd_ge_47}} BRCONFIG="$IFCONFIG" {{endif}} {{if freebsd}} BRCONFIG="$IFCONFIG" {{endif}} missing_port() { intf=$1 cmd=$2 oldIFS=$IFS IFS="@" set $intf port=$1 bridge_interface=$2 IFS=$oldIFS echo "# Updating bridge configuration: $bridge_interface $cmd $port" $FWBDEBUG $BRCONFIG $bridge_interface $cmd $port test "$cmd" = "addm" && $FWBDEBUG $IFCONFIG $port up } ## update_bridge br0 "eth2 eth3" update_bridge_interface() { bridge_interface=$1 shift FWB_PORTS="" CURRENT_PORTS="" FWB_PORTS=$( for subint in $*; do echo "${subint}@$bridge_interface" done | sort ) # this is really redundant because we create missing bridge # interfaces in sync_bridge_interfaces. However will leave this # here so that function update_bridge can be used without prior # call to sync_bridge_interfaces The difference is that # sync_bridge_interfaces also deletes bridge interfaces that exist # on the machine but are missing in fwbuilder confgiuration. The # update_bridge function can only add bridge interfaces. $BRCONFIG $bridge_interface >/dev/null 2>&1 || { echo "# Creating bridge interface $bridge_interface" $FWBDEBUG $IFCONFIG $bridge_interface create $FWBDEBUG $IFCONFIG $bridge_interface up } PORTS=$( $BRCONFIG $bridge_interface | awk '($1~/member:/) { print $2; }' ) test -n "$PORTS" && { CURRENT_PORTS=$( for subint in $PORTS; do echo "${subint}@$bridge_interface" done | sort ) } # first delete bridge ports, then add. This way, if an interface # moves from one bridge to another, we remove it first and then # add. It would not work if we tried to add it first, brctl issues # an error: # device eth2 is already a member of a bridge; can't enslave it to bridge br1. # diff_intf missing_port "$CURRENT_PORTS" "$FWB_PORTS" deletem diff_intf missing_port "$FWB_PORTS" "$CURRENT_PORTS" addm } ## This function synchronizes bridge interfaces between fwbuilder objects ## and actual configuration of the firewall machine. Birgde interfaces not ## listed as arguments will be deleted and those in the arguments will be ## created if missing. ## ## NOTE: we have to delete and create bridge interfaces before we add ## bridge ports to them because if a bridge interface that was not ## configured in fwbuilder existed before this script ran, its bridge ## ports could not be added to other bridges. This bridge interface ## should be deleted first. ## ## sync_bridge_interfaces bridge0 bridge1 sync_bridge_interfaces() { $BRCONFIG -a | awk -F: -v IGNORED="$*" \ 'BEGIN { split(IGNORED,ignored_arr); for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;} } ($1 ~ /^bridge[0-9]/ && !($1 in ignored_dict)) {print $1;}' | \ while read brintf; do echo "# Deleting bridge interface $brintf" $FWBDEBUG $IFCONFIG $brintf down $FWBDEBUG $IFCONFIG $brintf destroy done for brint in $*; do $BRCONFIG $brint >/dev/null 2>&1 || { echo "# Creating bridge interface $brintf" $FWBDEBUG $IFCONFIG $brint create $FWBDEBUG $IFCONFIG $brint up } done } fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/0000755000175000017500000000000011733011756023035 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/routing_functions0000644000175000017500000000374611733011756026551 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## The recent versions of DD-WRT V24 preSP2 Build 13064 and newer are ## missing modprobe and mktemp. This configlet does not use mktemp to ## create temporary file # ============== ROUTING RULES ============== TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" (umask 077 && mkdir $TMPDIRNAME) || exit 1 # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules (IFS=" "; for route in $oldRoutes; do (IFS=' '; $IP route add $route); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) oldRoutes=$($IP route show | sort -k 2) echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v {{$proto_filter}} | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/script_skeleton0000644000175000017500000000404611733011756026174 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Note that /bin/sh on Sveasoft (busybox) does not like empty shell ## functions and fails with an error "36: Syntax error: "}" unexpected" ## Will call /bin/true as a placeholder so that if some other ## commands are added to the function body during template expansion, ## they are executed after /bin/true and their return code is ## preserved. If no commands are added, then the function body won't ## be empty and will return success. {{$top_comment}} {{$shell_debug}} {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} load_modules() { : {{$load_modules}} } verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { : {{$prolog_script}} } epilog_commands() { : {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } script_body() { {{$script_body}} } ip_forward() { : {{$ip_forward_commands}} } reset_all() { : {{$reset_all}} } log "Activating firewall script generated {{$timestamp}} by {{$user}}" check_tools {{if prolog_top}}prolog_commands{{endif}} check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} load_modules configure_interfaces verify_interfaces {{if prolog_after_interfaces}}prolog_commands{{endif}} {{if not_using_iptables_restore}} reset_all {{endif}} {{if prolog_after_flush}}prolog_commands{{endif}} script_body ip_forward epilog_commands fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/top_comment0000644000175000017500000000036611733011756025311 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} DD-WRT (nvram) # fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/check_utilities0000644000175000017500000000355111733011756026134 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Known variables: ## ## need_iptables_restore ## need_ip6tables_restore ## need_modprobe : set to true if "load modules" option is on, or ## script needs to manage vlan or bonding interfaces. ## See configlets for vlan and bonding interfaces to find ## how modprobe is used to load corresponding modules ## need_vconfig : set to true if script manages vlans ## need_brctl : set to true if script manages bridge ports ## need_ifenslave : set to true if script manages bonding interfaces ## need_ipset : set to true if ipset is used for run-time address tables ## load_modules : set to true if "load modules" option is on ## ## These variables are set in OSConfigurator_linux24::printShellFunctions() ## find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES {{if need_iptables_restore}} find_program $IPTABLES_RESTORE{{endif}} {{if need_ip6tables_restore}} find_program $IP6TABLES_RESTORE{{endif}} find_program $IP {{if need_vconfig}} find_program $VCONFIG {{endif}} {{if need_brctl}} find_program $BRCTL {{endif}} {{if need_ifenslave}} find_program $IFENSLAVE {{endif}} {{if need_ipset}} find_program $IPSET {{endif}} } fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/installer_commands_reg_user0000644000175000017500000000214711733011756030535 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## ## We only use root to authenticate to Sveasoft firewall {{if run}} {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-nvram/installer_commands_root0000644000175000017500000000404411733011756027703 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/dd-wrt-nvram/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout (min) ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## ## {{$firewall_name}} -- the name of the firewall object ## {{if run}} {{if with_compression}} echo '{{$fwbprompt}}'; mv /tmp/{{$fwscript}} /tmp/fwb; /usr/sbin/nvram unset rc_firewall; /usr/sbin/nvram set rc_firewall="/usr/sbin/nvram get fwb|uudecode|gzip -dc|sh"; /usr/sbin/nvram unset fwb; /usr/sbin/nvram set fwb="`cat /tmp/fwb|gzip|uuencode -`" || exit 1; rm /tmp/fwb; echo "Saving data to flash memory"; /usr/sbin/nvram commit || exit 1; echo "Flash memory:"; /usr/sbin/nvram show >/dev/null; echo "Activating policy"; /usr/sbin/nvram get fwb|uudecode|gzip -dc|sh && echo 'Policy activated' {{endif}} {{if no_compression}} echo '{{$fwbprompt}}'; mv /tmp/{{$fwscript}} /tmp/fwb; /usr/sbin/nvram set rc_firewall="/usr/sbin/nvram get fwb|sh"; /usr/sbin/nvram unset fwb; /usr/sbin/nvram set fwb="`cat /tmp/fwb`" || exit 1; rm /tmp/fwb; echo "Saving data to flash memory"; /usr/sbin/nvram commit || exit 1; echo "Flash memory:"; /usr/sbin/nvram show >/dev/null; echo "Activating policy"; /usr/sbin/nvram get fwb|sh && echo 'Policy activated' {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/openwrt/0000755000175000017500000000000011733011756022211 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/openwrt/script_skeleton0000644000175000017500000000352211733011756025346 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Double '##' comments are removed when configlet is processed. ## Single '#' comments stay. ## ## Some shells (not bash) do not like empty functions. Placing a comment ## inside the function does not help. Using dummy ":" as a placeholder. ## {{$top_comment}} {{$errors_and_warnings}} START=46 EXTRA_COMMANDS="status interfaces test_interfaces" {{$shell_debug}} FWBDEBUG="" {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} load_modules() { : {{$load_modules}} } verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } script_body() { {{$script_body}} } ip_forward() { : {{$ip_forward_commands}} } reset_all() { : {{$reset_all}} } {{$stop_action}} {{$status_action}} start() { log "Activating firewall script generated {{$timestamp}} by {{$user}}" check_tools {{if prolog_top}} prolog_commands {{endif}} check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} load_modules "{{$load_modules_with_nat}} {{$load_modules_with_ipv6}}" configure_interfaces verify_interfaces {{if prolog_after_interfaces}} prolog_commands {{endif}} {{if not_using_iptables_restore}} reset_all {{endif}} {{if prolog_after_flush}} prolog_commands {{endif}} script_body ip_forward epilog_commands } stop() { stop_action } status() { status_action } interfaces() { configure_interfaces } test_interfaces() { FWBDEBUG="echo" configure_interfaces } fwbuilder-5.1.0.3599/src/res/configlets/openwrt/top_comment0000644000175000017500000000040211733011756024454 0ustar sylvestresylvestre#!/bin/sh /etc/rc.common # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} # {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/openwrt/check_utilities0000644000175000017500000000156511733011756025313 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IP {{if need_vconfig}} find_program $VCONFIG {{endif}} {{if need_brctl}} find_program $BRCTL {{endif}} {{if need_ifenslave}} find_program $IFENSLAVE {{endif}} } fwbuilder-5.1.0.3599/src/res/configlets/openwrt/installer_commands_reg_user0000644000175000017500000000214611733011756027710 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## ## We only use root to authenticate to OpenWRT firewall {{if run}} {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/openwrt/installer_commands_root0000644000175000017500000000144311733011756027057 0ustar sylvestresylvestre## -*- 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 root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; {{$fwdir}}/{{$fwscript}} start && echo 'Policy activated' fwbuilder-5.1.0.3599/src/res/configlets/openwrt/load_modules0000644000175000017500000000154711733011756024612 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## This configlet is a variant of linux24/load_modules except it uses insmod ## instead of modprobe because modprobe is not available on OpenWRT. See ## linux24/load_modules for more comments. {{if load_modules}} OPTS=$1 MODULES_DIR="{{$modules_dir}}" MODULES=$(find $MODULES_DIR -name '*conntrack*' \! -name '*ipv6*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/') echo $OPTS | grep -q nat && { MODULES="$MODULES $(find $MODULES_DIR -name '*nat*'|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } echo $OPTS | grep -q ipv6 && { MODULES="$MODULES $(find $MODULES_DIR -name nf_conntrack_ipv6|sed -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/')" } for module in $MODULES; do if $LSMOD | grep ${module} >/dev/null; then continue; fi insmod ${module} || exit 1 done {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/0000755000175000017500000000000011733011756022170 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/regular_interface_20000644000175000017500000000206611733011756026021 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if static_address}} nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}}ip address {{$interface_label}} {{$address}} {{$netmask}} {{endif}} {{if configure_standby_address}}failover ip address {{$interface_label}} {{$standby_address}} {{endif}} {{endif}} {{if dhcp_address}} nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}}ip address {{$interface_label}} dhcp setroute retry 10 {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/failover_commands_20000644000175000017500000000237011733011756026026 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## http://www.cisco.com/en/US/docs/security/pix/pix63/configuration/guide/failover.html ## ## failover ip address outside 209.165.201.2 ## failover ip address inside 192.168.2.2 ## failover ip address failover 192.168.254.2 ## failover ip address state 192.168.253.2 ## failover link state ## failover lan unit primary ## failover lan interface failover ## failover lan key 12345678 ## failover lan enable ## failover ## ## ## "failover ip address" commands are added bu the failover_interface_6 configlet failover link {{$state_sync_interface_label}} failober lan unit {{$primary_or_secondary}} failover lan interface {{$failover_interface_label}} failover key {{$failover_key}} failover lan enable failover fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/failover_commands_3_20000644000175000017500000000273611733011756026256 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## failover ## failover lan unit primary ## failover lan interface failover Ethernet3 ## failover lan enable ## failover key ****** ## failover link state Ethernet2 ## failover interface ip failover 10.1.0.1 255.255.255.0 standby 10.1.0.2 ## failover interface ip state 10.0.0.1 255.0.0.0 standby 10.0.0.2 failover lan unit {{$primary_or_secondary}} failover lan interface {{$failover_interface_label}} {{$failover_interface_name}} failover lan enable failover key {{$failover_key}} failover interface ip {{$failover_interface_label}} {{$failover_interface_primary_address}} {{$failover_interface_primary_netmask}} standby {{$failover_interface_standby_address}} failover link {{$state_sync_interface_label}} {{$state_sync_interface_name}} failover interface ip {{$state_sync_interface_label}} {{$state_sync_interface_primary_address}} {{$state_sync_interface_primary_netmask}} standby {{$state_sync_interface_standby_address}} failover fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/ntp0000644000175000017500000000040511733011756022713 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## See http://www.cisco.com/en/US/products/hw/modules/ps2706/products_configuration_example09186a00808b4d9f.shtml ## ## Cisco says: ## "Note: NTP cannot be configured on FWSM, because it takes its settings from the Switch." fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/vlan_subinterface_3_20000644000175000017500000000211411733011756026246 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if static_address}} interface {{$interface_name}} vlan {{$vlan_id}} nameif {{$interface_label}} {{if configure_interface_address}} ip address {{$address}} {{$netmask}} {{if configure_standby_address}} standby {{$standby_address}} {{endif}} {{endif}} security-level {{$security_level}} exit {{endif}} {{if dhcp_address}} interface {{$interface_name}} vlan {{$vlan_id}} nameif {{$interface_label}} {{if configure_interface_address}} ip address dhcp setroute {{endif}} security-level {{$security_level}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/vlan_parent_interface_3_20000644000175000017500000000120111733011756027101 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## interface {{$interface_name}} no nameif no ip address no security-level exit fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/failover_interface_20000644000175000017500000000151011733011756026160 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}}ip address {{$interface_label}} {{$address}} {{$netmask}} {{endif}} {{if configure_standby_address}}failover ip address {{$interface_label}} {{$standby_address}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/ssh0000644000175000017500000000150211733011756022706 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if clear}} {{if fwsm_version_lt_32}} clear ssh {{endif}} {{if fwsm_version_ge_32}} clear config ssh {{endif}} {{endif}} aaa authentication ssh console LOCAL {{if use_scp}} ssh version 2 ssh scopy enable {{endif}} {{if ssh_timeout}} ssh timeout {{$ssh_timeout}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/installer_commands_reg_user0000644000175000017500000000170511733011756027667 0ustar sylvestresylvestre## -*- 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 ## ## Variables: ## ## {{$fwbprompt}} -- "magic" prompt that installer uses to detect when it is ## logged in ## {{$fwdir}} -- directory on the firewall (in case of PIX, "flash:" or ## similar) ## {{$fwscript}} -- script name on the firewall ## {{$firewall_name}} -- the name of the firewall object ## {{if using_scp}} changeto context {{$firewall_name}} copy /noconfirm {{$fwdir}}/{{$fwscript}} running-config changeto system delete /noconfirm {{$fwdir}}/{{$fwscript}} exit {{endif}} {{if not_using_scp}} config term terminal width 256 {{$fwbuilder_generated_configuration_lines}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/vlan_parent_interface_20000644000175000017500000000105711733011756026670 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/installer_commands_post_config0000644000175000017500000000070011733011756030360 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout ## {{$test}} -- doing installation in test mode ## {{if cancel_rollback}} reload cancel {{endif}} {{if run}} wr mem {{endif}} {{if save_standby}} wr standby {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/failover_interface_3_20000644000175000017500000000120711733011756026405 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## interface {{$interface_name}} description LAN/STATE Failover Interface no nameif exit fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/vlan_subinterface_20000644000175000017500000000207011733011756026025 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## interface ethernet0 vlan3 logical {{if static_address}} interface {{$parent_interface}} {{$interface_name}} logical nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}} ip address {{$interface_label}} {{$address}} {{$netmask}} {{endif}} {{endif}} {{if dhcp_address}} nameif {{$interface_name}} {{$interface_label}} security{{$security_level}} {{if configure_interface_address}} ip address {{$interface_label}} dhcp setroute retry 10 {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/installer_commands_pre_config0000644000175000017500000000060611733011756030166 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Lines that start with "##" will be removed before this code is ## added to the generated script. ## ## These are commands built-in policy installer runs on the firewall ## ## Variables: ## ## {{$rbtimeout}} -- rollback timeout ## {{$test}} -- doing installation in test mode ## {{if schedule_rollback}} reload in {{$rbtimeout}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/snmp0000644000175000017500000000241311733011756023070 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/fwsm_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if clear}} {{if fwsm_version_lt_32}} clear snmp-server {{endif}} {{if fwsm_version_ge_32}} clear config snmp-server {{endif}} {{endif}} {{if disable}} no snmp-server {{endif}} {{if not_disable}} {{if set_community}} snmp-server community {{$read_community}} {{endif}} {{if set_sysinfo}} {{if not_location_empty}}snmp-server location {{$location}}{{endif}} {{if not_contact_empty}}snmp-server contact {{$contact}}{{endif}} {{endif}} {{if not_enable_traps}}no {{endif}}snmp-server enable traps {{if not_server_1_empty}}snmp-server host {{$interface_1_label}} {{$address_1}} {{$poll_or_trap_1}} {{endif}} {{if not_server_2_empty}}snmp-server host {{$interface_2_label}} {{$address_2}} {{$poll_or_trap_2}} {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/fwsm_os/regular_interface_3_20000644000175000017500000000204411733011756026237 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/pix_os/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## {{if static_address}} interface {{$interface_name}} nameif {{$interface_label}} {{if configure_interface_address}} ip address {{$address}} {{$netmask}} {{if configure_standby_address}} standby {{$standby_address}} {{endif}} {{endif}} security-level {{$security_level}} exit {{endif}} {{if dhcp_address}} interface {{$interface_name}} nameif {{$interface_label}} {{if configure_interface_address}} ip address dhcp setroute {{endif}} security-level {{$security_level}} exit {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/sveasoft/0000755000175000017500000000000011733011756022345 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/sveasoft/shell_functions0000644000175000017500000000322511733011756025471 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. log() { echo "$1" which "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1" } check_file() { test -r "$2" || { echo "Can not find file $2 referenced by AddressTable object $1" exit 1 } } getInterfaceVarName() { echo $1 | sed 's/\./_/' } getaddr_internal() { dev=$1 name=$2 af=$3 L=$($IP $af addr show dev $dev | sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}') test -z "$L" && { eval "$name=''" return } eval "${name}_list=\"$L\"" } ## ## This function reads all ipv4 addresses of interface (arg 1) and ## assignes the list to the variable which name is given as arg 2. ## getaddr() { getaddr_internal $1 $2 "-4" } ## ## This function reads all ipv6 addresses of interface (arg 1) and ## assignes the list to the variable which name is given as arg 2. ## getaddr6() { getaddr_internal $1 $2 "-6" } # function getinterfaces is used to process wildcard interfaces getinterfaces() { NAME=$1 $IP link show | grep ": $NAME" | while read L; do OIFS=$IFS IFS=" :" set $L IFS=$OIFS echo $2 done } fwbuilder-5.1.0.3599/src/res/configlets/sveasoft/script_skeleton0000644000175000017500000000411011733011756025474 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Note that /bin/sh on Sveasoft (busybox) does not like empty shell ## functions and fails with an error "36: Syntax error: "}" unexpected" ## Will call /bin/true as a placeholder so that if some other ## commands are added to the function body during template expansion, ## they are executed after /bin/true and their return code is ## preserved. If no commands are added, then the function body won't ## be empty and will return success. {{$top_comment}} {{$shell_debug}} {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} ## we do not load modules on Sveasoft load_modules() { : } verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { : {{$prolog_script}} } epilog_commands() { : {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } script_body() { {{$script_body}} } ip_forward() { : {{$ip_forward_commands}} } reset_all() { : {{$reset_all}} } {{$stop_action}} log "Activating firewall script generated {{$timestamp}} by {{$user}}" check_tools {{if prolog_top}}prolog_commands{{endif}} check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} load_modules configure_interfaces verify_interfaces {{if prolog_after_interfaces}}prolog_commands{{endif}} {{if not_using_iptables_restore}} reset_all {{endif}} {{if prolog_after_flush}}prolog_commands{{endif}} script_body ip_forward epilog_commands fwbuilder-5.1.0.3599/src/res/configlets/sveasoft/top_comment0000644000175000017500000000034711733011756024620 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} # fwbuilder-5.1.0.3599/src/res/configlets/sveasoft/installer_commands_reg_user0000644000175000017500000000214711733011756030045 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## ## We only use root to authenticate to Sveasoft firewall {{if run}} {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/sveasoft/installer_commands_root0000644000175000017500000000403711733011756027215 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout (min) ## {{$rbtimeout_sec}} -- rollback timeout (sec) ## ## {{$firewall_name}} -- the name of the firewall object ## {{if run}} {{if with_compression}} echo '{{$fwbprompt}}'; mv /tmp/{{$fwscript}} /tmp/fwb; /usr/sbin/nvram unset rc_firewall; /usr/sbin/nvram set rc_firewall="/usr/sbin/nvram get fwb|uudecode|gzip -dc|sh"; /usr/sbin/nvram unset fwb; /usr/sbin/nvram set fwb="`cat /tmp/fwb|gzip|uuencode -`" || exit 1; rm /tmp/fwb; echo "Saving data to flash memory"; /usr/sbin/nvram commit || exit 1; echo "Flash memory:"; /usr/sbin/nvram show >/dev/null; echo "Activating policy"; /usr/sbin/nvram get fwb|uudecode|gzip -dc|sh && echo 'Policy activated' {{endif}} {{if no_compression}} echo '{{$fwbprompt}}'; mv /tmp/{{$fwscript}} /tmp/fwb; /usr/sbin/nvram set rc_firewall="/usr/sbin/nvram get fwb|sh"; /usr/sbin/nvram unset fwb; /usr/sbin/nvram set fwb="`cat /tmp/fwb`" || exit 1; rm /tmp/fwb; echo "Saving data to flash memory"; /usr/sbin/nvram commit || exit 1; echo "Flash memory:"; /usr/sbin/nvram show >/dev/null; echo "Activating policy"; /usr/sbin/nvram get fwb|sh && echo 'Policy activated' {{endif}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/0000755000175000017500000000000011733011756022642 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/routing_functions0000644000175000017500000000374611733011756026356 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## The recent versions of DD-WRT V24 preSP2 Build 13064 and newer are ## missing modprobe and mktemp. This configlet does not use mktemp to ## create temporary file # ============== ROUTING RULES ============== TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" (umask 077 && mkdir $TMPDIRNAME) || exit 1 # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules $IP route show | while read route ; do $IP route del $route ; done # restore old routing rules (IFS=" "; for route in $oldRoutes; do (IFS=' '; $IP route add $route); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 # store previous routing configuration (sort: 'via' GW has to be # inserted after device routes) oldRoutes=$($IP route show | sort -k 2) echo "Deleting routing rules previously set by user space processes..." $IP route show | grep -v {{$proto_filter}} | \ while read route ; do $IP route del $route ; done echo "Activating non-ecmp routing rules..." fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/script_skeleton0000644000175000017500000000625611733011756026006 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## Double '##' comments are removed when configlet is processed. ## Single '#' comments stay. ## ## Some shells (not bash) do not like empty functions. Placing a comment ## inside the function does not help. Using dummy ":" as a placeholder. ## {{$top_comment}} {{$errors_and_warnings}} {{$shell_debug}} FWBDEBUG="" {{$path}} {{$constants}} {{$tools}} {{$shell_functions}} {{$run_time_address_tables}} load_modules() { : {{$load_modules}} } verify_interfaces() { : {{$verify_interfaces}} } prolog_commands() { echo "Running prolog script" {{$prolog_script}} } epilog_commands() { echo "Running epilog script" {{$epilog_script}} } run_epilog_and_exit() { epilog_commands exit $1 } configure_interfaces() { : {{$configure_interfaces}} } script_body() { {{$script_body}} } ip_forward() { : {{$ip_forward_commands}} } reset_all() { : {{$reset_all}} } {{$block_action}} {{$stop_action}} {{$status_action}} # See how we were called. # For backwards compatibility missing argument is equivalent to 'start' cmd=$1 test -z "$cmd" && { cmd="start" } case "$cmd" in start) log "Activating firewall script generated {{$timestamp}} by {{$user}}" check_tools {{if prolog_top}} prolog_commands {{endif}} check_run_time_address_table_files {{if using_ipset}} check_module_ipset load_run_time_address_table_files {{endif}} load_modules "{{$load_modules_with_nat}} {{$load_modules_with_ipv6}}" configure_interfaces verify_interfaces {{if prolog_after_interfaces}} prolog_commands {{endif}} {{if not_using_iptables_restore}} reset_all {{endif}} {{if prolog_after_flush}} prolog_commands {{endif}} script_body ip_forward epilog_commands RETVAL=$? ;; stop) stop_action RETVAL=$? ;; status) status_action RETVAL=$? ;; block) block_action RETVAL=$? ;; reload) $0 stop $0 start RETVAL=$? ;; interfaces) configure_interfaces RETVAL=$? ;; test_interfaces) FWBDEBUG="echo" configure_interfaces RETVAL=$? ;; {{if using_ipset}} ## Usage: script.fw reload_address_table reload_address_table) reload_address_table $2 $3 ;; ## Usage: script.fw add_to_address_table
add_to_address_table) add_to_address_table $2 $3 $4 ;; ## Usage: script.fw remove_from_address_table
remove_from_address_table) remove_from_address_table $2 $3 $4 ;; ## Usage: script.fw test_address_table
test_address_table) test_address_table $2 $3 ;; {{endif}} *) echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces{{if using_ipset}}|reload_address_table|add_to_address_table|remove_from_address_table|test_address_table{{endif}}]" ;; esac exit $RETVAL fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/top_comment0000644000175000017500000000040211733011756025105 0ustar sylvestresylvestre#!/bin/sh # # This is automatically generated file. DO NOT MODIFY ! # # Firewall Builder fwb_ipt v{{$version}} # # Generated {{$timestamp}} {{$tz}} by {{$user}} # {{$manifest}} # # Compiled for {{$platform}} {{$fw_version}} DD-WRT (jffs) # {{$comment}} fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/check_utilities0000644000175000017500000000362411733011756025742 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/linux24/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Known variables: ## ## need_iptables_restore ## need_ip6tables_restore ## need_modprobe : set to true if "load modules" option is on, or ## script needs to manage vlan or bonding interfaces. ## See configlets for vlan and bonding interfaces to find ## how modprobe is used to load corresponding modules ## need_vconfig : set to true if script manages vlans ## need_brctl : set to true if script manages bridge ports ## need_ifenslave : set to true if script manages bonding interfaces ## need_ipset : set to true if ipset is used for run-time address tables ## load_modules : set to true if "load modules" option is on ## ## These variables are set in OSConfigurator_linux24::printShellFunctions() ## About using "command" to find programs: ## find_program() { PGM=$1 which $PGM >/dev/null 2>&1 || { echo "\"$PGM\" not found" exit 1 } } check_tools() { find_program which find_program $IPTABLES {{if need_iptables_restore}} find_program $IPTABLES_RESTORE{{endif}} {{if need_ip6tables_restore}} find_program $IP6TABLES_RESTORE{{endif}} find_program $IP {{if need_vconfig}} find_program $VCONFIG {{endif}} {{if need_brctl}} find_program $BRCTL {{endif}} {{if need_ifenslave}} find_program $IFENSLAVE {{endif}} {{if need_ipset}} find_program $IPSET {{endif}} } fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/installer_commands_reg_user0000644000175000017500000000214711733011756030342 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/sveasoft/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## ## We only use root to authenticate to Sveasoft firewall {{if run}} {{endif}} {{if test}} {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/dd-wrt-jffs/installer_commands_root0000644000175000017500000000165411733011756027514 0ustar sylvestresylvestre## -*- 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 root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## {{if run}} echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; /usr/sbin/nvram unset rc_firewall; /usr/sbin/nvram set rc_firewall="{{$fwdir}}/{{$fwscript}}"; /usr/sbin/nvram commit; sh {{$fwdir}}/{{$fwscript}} && echo 'Policy activated' {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/0000755000175000017500000000000011733011756022125 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/res/configlets/freebsd/rc_conf_kernel_vars0000644000175000017500000000161711733011756026061 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/freebsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if have_freebsd_ip_forward}}gateway_enable="{{$freebsd_ip_forward}}"{{endif}} {{if have_freebsd_ipv6_forward}}ipv6_gateway_enable="{{$freebsd_ipv6_forward}}"{{endif}} {{if have_freebsd_ip_sourceroute}}forward_sourceroute="{{$freebsd_ip_sourceroute}}"{{endif}} {{if have_freebsd_ip_sourceroute}}accept_sourceroute="{{$freebsd_ip_sourceroute}}"{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/routing_functions0000644000175000017500000000357611733011756025642 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## # ============== ROUTING RULES ============== TMPDIRNAME=`mktemp -d /tmp/.fwbuilder.XXXXXXXXXX` || exit 1 TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" # # This function stops stdout redirection # and sends previously saved output to terminal restore_script_output() { exec 1>&3 2>&1 cat $TMPFILENAME rm -rf $TMPDIRNAME } # if any routing rule fails we do our best to prevent freezing the firewall route_command_error() { echo "Error: Routing rule $1 couldn't be activated" echo "Recovering previous routing configuration..." # delete current routing rules netstat -rn -f inet | awk '$3 ~ /S/ && $NF !~ /lo0/ { print $0;}' | \ while read route gw rest; do route delete $route $gw; done # restore old routing rules (IFS=" "; for route_cmd in $oldRoutes; do (IFS=' '; $route_cmd); done) echo "...done" restore_script_output epilog_commands exit 1 } # redirect output to prevent ssh session from stalling exec 3>&1 exec 1> $TMPFILENAME exec 2>&1 oldRoutes=$(netstat -rn -f inet | awk '/^$|Destination|Routing tables|Internet:/ {next;} {printf "route add %s %s\n",$1,$2;}') echo "Deleting routing rules previously set by user space processes..." netstat -rn -f inet | awk '$3 ~ /S/ { print $0;}' | grep -Ev {{$route_filter}} | \ while read route gw rest; do route delete $route $gw; done echo "Activating routing rules..." fwbuilder-5.1.0.3599/src/res/configlets/freebsd/rc_conf_pfsync_interface0000644000175000017500000000050311733011756027061 0ustar sylvestresylvestre## -*- 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. ## ## pfsync_syncdev="{{$syncdev}}" {{if have_syncpeer}}pfsync_syncpeer="{{$syncpeer}}"{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/rc_conf_ifconfig_interface0000644000175000017500000000043011733011756027342 0ustar sylvestresylvestre## -*- 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. ## {{if have_mtu}}mtu {{$mtu}}{{endif}} {{$options}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/rc_conf_carp_interface0000644000175000017500000000165611733011756026516 0ustar sylvestresylvestre## -*- 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. ## ## ## CARP ## ifconfig carp-interface [advbase n] [advskew n] [carpdev iface] ## [pass passphrase] [state state] [vhid host-id] ## ## for pfsync and CARP see http://www.kernel-panic.it/openbsd/carp/ ## "Redundant firewalls with OpenBSD, CARP and pfsync" ## ## here is how to configure CARP interfaces in rc.conf ## ## http://blas.phemo.us/articles/2007/04/04/setting-up-and-configuring-carp-interfaces-on-freebsd ## ## Unlike in OpenBSD, in FreeBSD ifconfig does not understand carpdev parameter create_args_{{$carp_interface}}="vhid {{$vhid}} {{if have_password}}pass {{$carp_password}}{{endif}} {{if have_advbase}} advbase {{$advbase}}{{endif}} {{if have_advskew}} advskew {{$advskew}}{{endif}}" fwbuilder-5.1.0.3599/src/res/configlets/freebsd/ifconfig_interface0000644000175000017500000000046611733011756025662 0ustar sylvestresylvestre## -*- 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. ## $IFCONFIG {{$interface_name}} {{if have_mtu}}mtu {{$mtu}}{{endif}} {{$options}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/rc_conf_bridge_port0000644000175000017500000000045111733011756026041 0ustar sylvestresylvestre## -*- 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. ## addm {{$bridge_port}} {{if stp_off}}-{{endif}}stp {{$bridge_port}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/installer_commands_reg_user0000644000175000017500000000322111733011756027617 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## 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 ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## See #1368 for the explanation of the need for the "sleep2; echo" commands ## ## Note: all commands should be on one line to avoid unnecessary linefeeds. ## These linefeeds are sent to the server side (to the firewall) and end up ## on the input of sudo and other commands. This creates difficult to catch ## race condition which breaks installation process. {{if shell_script_format}} echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sudo -S {{$fwdir}}/{{$fwscript}} && ( echo 'Policy activated'; sleep 2; echo) {{endif}} {{if rc_conf_format}} echo '{{$fwbprompt}}'; sudo -S /etc/rc.d/pf reload && ( echo 'Policy activated'; sleep 2; echo) {{endif}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/carp_interface0000644000175000017500000000141211733011756025013 0ustar sylvestresylvestre## -*- 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. ## ## ## CARP ## ifconfig carp-interface [advbase n] [advskew n] [carpdev iface] ## [pass passphrase] [state state] [vhid host-id] ## ## for pfsync and CARP see http://www.kernel-panic.it/openbsd/carp/ ## "Redundant firewalls with OpenBSD, CARP and pfsync" ## ## Unlike in OpenBSD, in FreeBSD ifconfig does not understand carpdev parameter $IFCONFIG {{$carp_interface}} vhid {{$vhid}} {{if have_password}}pass {{$carp_password}}{{endif}} {{if have_advbase}} advbase {{$advbase}}{{endif}} {{if have_advskew}} advskew {{$advskew}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/tools0000644000175000017500000000140411733011756023207 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/freebsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## Set path to all utilities that we need IFCONFIG="{{$path_ifconfig}}" PFCTL="{{$path_pfctl}}" IPFW="{{$path_ipfw}}" IPF="{{$path_ipf}}" IPNAT="{{$path_ipnat}}" SYSCTL="{{$path_sysctl}}" LOGGER="{{$path_logger}}" fwbuilder-5.1.0.3599/src/res/configlets/freebsd/kernel_vars0000644000175000017500000000167711733011756024376 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/freebsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. {{if have_freebsd_ip_forward}}$SYSCTL -w net.inet.ip.forwarding={{$freebsd_ip_forward}}{{endif}} {{if have_freebsd_ipv6_forward}}$SYSCTL -w net.inet6.ip6.forwarding={{$freebsd_ipv6_forward}}{{endif}} {{if have_freebsd_ip_sourceroute}}$SYSCTL -w net.inet.ip.sourceroute={{$freebsd_ip_sourceroute}}{{endif}} {{if have_freebsd_ip_redirect}}$SYSCTL -w net.inet.ip.redirect={{$freebsd_ip_redirect}}{{endif}} fwbuilder-5.1.0.3599/src/res/configlets/freebsd/installer_commands_root0000644000175000017500000000254411733011756026776 0ustar sylvestresylvestre## -*- mode: shell-script; -*- ## ## To be able to make changes to the part of configuration created ## from this configlet you need to copy this file to the directory ## fwbuilder/configlets/bsd/ in your home directory and modify it. ## Double "##" comments are removed during processing but single "#" ## comments are be retained and appear in the generated script. Empty ## lines are removed as well. ## ## Configlets support simple macro language with these constructs: ## {{$var}} is variable expansion ## {{if var}} is conditional operator. ## ## ## These are commands built-in policy installer runs on the firewall if ## installation is performed using root account for authentication ## ## Variables: ## ## {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in ## {{$fwdir}} -- directory on the firewall ## {{$fwscript}} -- script name on the firewall ## {{$rbtimeout}} -- rollback timeout ## ## {{$firewall_name}} -- the name of the firewall object ## ## See #1368 for the explanation of the need for the "sleep2; echo" commands {{if shell_script_format}} echo '{{$fwbprompt}}'; chmod +x {{$fwdir}}/{{$fwscript}}; sh {{$fwdir}}/{{$fwscript}} && ( echo 'Policy activated'; sleep 2; echo) {{endif}} {{if rc_conf_format}} echo '{{$fwbprompt}}'; /etc/rc.d/pf reload && ( echo 'Policy activated'; sleep 2; echo) {{endif}} fwbuilder-5.1.0.3599/src/fwbedit/0000755000175000017500000000000011733011756017211 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/fwbedit/list_object.cpp0000644000175000017500000001647611733011756022234 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: fwbedit.cpp 429 2008-07-31 07:03:39Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" #include #include #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #include #include #include #ifndef _WIN32 # include #endif #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #else # ifdef _WIN32 # include # else # include # endif #endif #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include #include "fwbedit.h" using namespace libfwbuilder; using namespace std; string getAttributeValue(FWObject *obj, const string &attr_name) { if (attr_name=="ID" || attr_name=="id") return FWObjectDatabase::getStringId(obj->getId()); if (attr_name=="type") return obj->getTypeName(); if (attr_name=="name") return obj->getName(); if (attr_name=="path") return obj->getPath(); if (attr_name=="comment") return obj->getComment(); string objtype = obj->getTypeName(); if (attr_name=="address") { if (objtype==IPv4::TYPENAME || objtype==IPv6::TYPENAME || objtype==Network::TYPENAME || objtype==NetworkIPv6::TYPENAME) { return Address::cast(obj)->getAddressPtr()->toString(); } } if (attr_name=="netmask") { if (objtype==IPv4::TYPENAME || objtype==Network::TYPENAME) { return Address::cast(obj)->getNetmaskPtr()->toString(); } if (objtype==IPv6::TYPENAME || objtype==NetworkIPv6::TYPENAME) { ostringstream str; str << Address::cast(obj)->getNetmaskPtr()->getLength(); return str.str(); } } if (attr_name=="start_address" && objtype==AddressRange::TYPENAME) { return AddressRange::cast(obj)->getRangeStart().toString(); } if (attr_name=="end_address" && objtype==AddressRange::TYPENAME) { return AddressRange::cast(obj)->getRangeEnd().toString(); } if (attr_name=="dnsname" && objtype==DNSName::TYPENAME) { return DNSName::cast(obj)->getSourceName(); } if (TCPUDPService::cast(obj)!=NULL) { ostringstream str; if (attr_name=="src_range_start") str << TCPUDPService::cast(obj)->getSrcRangeStart(); if (attr_name=="src_range_end") str << TCPUDPService::cast(obj)->getSrcRangeEnd(); if (attr_name=="dst_range_start") str << TCPUDPService::cast(obj)->getDstRangeStart(); if (attr_name=="dst_range_end") str << TCPUDPService::cast(obj)->getDstRangeEnd(); if (str.tellp()>0) return str.str(); } if (ICMPService::cast(obj)!=NULL) { if (attr_name=="icmp_type") return obj->getStr("type"); if (attr_name=="icmp_code") return obj->getStr("code"); } string av = obj->getStr(attr_name); return av; } /* * find first occurrence of the %attr% macro and replace it with the * value of corresponding attribute of the obj. Replacement is done in * the same string in place, function returns true if it found and * replaced at least one macro, false otherwise */ bool replaceFirstMacroInString(string &str, FWObject *obj) { string::size_type n = 0; for (n=0; n=str.length()) return false; n1 = n; string attr_name = str.substr(n0+1, n1-n0-1); string attr_value = getAttributeValue(obj, attr_name); str.replace(n0, n1-n0+1, attr_value); return true; } } return false; } void listObject(FWObject *obj, bool list_children, bool recursive, const string &list_format, bool full_dump, int offset) { int off = offset; /* * print according to the list_format * format macros are attribute names surrounded by %%, like * %name% or %address% */ if (!list_children) { if (full_dump) obj->dump(recursive, false); else { string format = list_format; while (replaceFirstMacroInString(format, obj)) ; string::size_type n; while ( (n=format.find("\\t"))!=string::npos ) format.replace(n, 2, "\t"); while ( (n=format.find("\\n"))!=string::npos ) format.replace(n, 2, "\n"); cout << string(offset,' ') << format << endl; off += 4; } } if (recursive || list_children) { for (FWObject::iterator it=obj->begin(); it!=obj->end(); ++it) listObject(*it, false, recursive, list_format, full_dump, off); } } void listObject(FWObjectDatabase *objdb, const string &path, bool list_children, bool recursive, const string &list_format, bool full_dump) { list objects; findObjects(path, objdb, objects); if (objects.size()==0) { cout << "Object " << path << " not found" << endl; exit(-1); } for (list::iterator it=objects.begin(); it!=objects.end(); ++it) listObject(*it, list_children, recursive, list_format, full_dump, 0); } fwbuilder-5.1.0.3599/src/fwbedit/new_object.cpp0000644000175000017500000006063111733011756022042 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: fwbedit.cpp 429 2008-07-31 07:03:39Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" #include #include #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #include #include #include #ifndef _WIN32 # include #endif #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #else # ifdef _WIN32 # include # else # include # endif #endif #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include #include "fwbedit.h" using namespace libfwbuilder; using namespace std; std::map systemGroupPaths; std::map systemGroupTypes; void initConstants() { systemGroupPaths[Library::TYPENAME] = ""; systemGroupPaths[IPv4::TYPENAME] = "Objects/Addresses"; systemGroupPaths[IPv6::TYPENAME] = "Objects/Addresses"; systemGroupPaths[DNSName::TYPENAME] = "Objects/DNS Names"; systemGroupPaths[AddressTable::TYPENAME] = "Objects/Address Tables"; systemGroupPaths[AddressRange::TYPENAME] = "Objects/Address Ranges"; systemGroupPaths[ObjectGroup::TYPENAME] = "Objects/Groups"; systemGroupPaths[Host::TYPENAME] = "Objects/Hosts"; systemGroupPaths[Network::TYPENAME] = "Objects/Networks"; systemGroupPaths[NetworkIPv6::TYPENAME] = "Objects/Networks"; systemGroupPaths[ServiceGroup::TYPENAME] = "Services/Groups"; systemGroupPaths[CustomService::TYPENAME] = "Services/Custom"; systemGroupPaths[IPService::TYPENAME] = "Services/IP"; systemGroupPaths[ICMPService::TYPENAME] = "Services/ICMP"; systemGroupPaths[TCPService::TYPENAME] = "Services/TCP"; systemGroupPaths[UDPService::TYPENAME] = "Services/UDP"; systemGroupPaths[TagService::TYPENAME] = "Services/TagServices"; systemGroupPaths[UserService::TYPENAME] = "Services/Users"; systemGroupPaths[Firewall::TYPENAME] = "Firewalls"; systemGroupPaths[Cluster::TYPENAME] = "Clusters"; systemGroupPaths[Interval::TYPENAME] = "Time"; systemGroupTypes["Objects/Addresses"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Addresses"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/DNS Names"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Address Tables"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Address Ranges"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Groups"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Hosts"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Networks"] = ObjectGroup::TYPENAME; systemGroupTypes["Objects/Networks"] = ObjectGroup::TYPENAME; systemGroupTypes["Services/Groups"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/Custom"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/IP"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/ICMP"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/TCP"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/UDP"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/TagServices"] = ServiceGroup::TYPENAME; systemGroupTypes["Services/Users"] = ServiceGroup::TYPENAME; systemGroupTypes["Firewalls"] = ObjectGroup::TYPENAME; systemGroupTypes["Clusters"] = ObjectGroup::TYPENAME; systemGroupTypes["Time"] = IntervalGroup::TYPENAME; } void notEnoughAttributesError() { cerr << "Incorrect number of attributes for given object type" << endl; exit(-1); } bool testIPv4(string s) { bool res=false; try { InetAddr( s.c_str() ); res=true; } catch (FWException &ex) { } return res; } bool testIPv6(string s) { bool res=false; try { InetAddr(AF_INET6, s.c_str()); res=true; } catch (FWException &ex) { } return res; } void invalidIPv4(string s) { if (!testIPv4(s)) { cout << "\"" << s << "\" - invalid IPv4 address." << endl; exit(0); } } void invalidIPv6(string s) { if (!testIPv6(s)) { cout << "\"" << s << "\" - invalid IPv6 address." << endl; exit(0); } } bool testPlatform(const string &pl, const string &os) { vector platforms = Resources::getListOfPlatforms(); operands lst; string str; if (platforms.empty() || ( platforms.size()==1 && platforms.front()=="unknown" )) { cout << "Failed to load list of supported platforms" << endl; exit(1); } for (vector::iterator i=platforms.begin();i!=platforms.end();i++) { string sos=Resources::platform_res[*i]->getResourceStr("/FWBuilderResources/Target/supported_os"); if (sos.empty()) return false; if (*i!="unknown") { if (*i==pl ) { int n = splitStr(',',sos,&lst); for (int i=0;icreate(type); // parent can be either full path to the parent object or // just the name of the library. If there are no "/" in the string, // then this is the latter case. string::size_type n = parent.find("/"); if (n==string::npos) path = "/" + parent + "/" + systemGroupPaths[type]; else path = parent; list parents; findObjects(path, objdb, parents); if (parents.size()) { FWObject *parent_obj = parents.front(); if (parent_obj && parent_obj->validateChild(obj)) parent_obj->add(obj); } return obj; } /* * _modObject takes a copy of ops (so the original can be used several times) */ void _modObject(FWObject *nobj, const string &comment_txt, operands ops) { string group; string addr1; string addr2; string dnsrec; string runtime; string path; string lib; string time1; string time2; string date1; string date2; string day1; string day2; string platform; string hostOS; string management; string addr3; string addr4; string tcpflags_mask; string tcpflags_bits; string protocol; string bitmap; string ICMPtype; string ICMPcode; string security; string addrtype; string objtype = nobj->getTypeName(); if (!comment_txt.empty()) nobj->setComment(comment_txt); if (ops.size()==0) return; if (objtype==IPv4::TYPENAME || objtype==IPv6::TYPENAME) { if (objtype==IPv4::TYPENAME) { addr1 = getNextOpt(ops); invalidIPv4(addr1); if (ops.size()>0) { addr2 = getNextOpt(ops); invalidIPv4(addr2); } } else { addr1 = getNextOpt(ops); invalidIPv6(addr1); if (ops.size()>0) { addr2 = getNextOpt(ops); // addr2 is mask length } } cout << "Address: " << addr1 << endl; if (!addr2.empty()) cout << "Netmask: " << addr2 << endl; Address *o = Address::cast(nobj); if (objtype==IPv6::TYPENAME) o->setAddress(InetAddr(AF_INET6, addr1)); else o->setAddress(InetAddr(addr1)); if (!addr2.empty()) { if (objtype==IPv6::TYPENAME) { istringstream istr(addr2); int masklen; istr >> masklen; o->setNetmask(InetAddr(AF_INET6, masklen)); } else o->setNetmask(InetAddr(addr2)); } } else if (objtype==DNSName::TYPENAME) { try { dnsrec = getNextOpt(ops); runtime = getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "DNS Record: " << dnsrec << endl; cout << "Run time: " << runtime << endl; DNSName *o=DNSName::cast(nobj); o->setSourceName(dnsrec); o->setRunTime(getBool(runtime)); } else if (objtype==AddressRange::TYPENAME) { try { addr1 = getNextOpt(ops); invalidIPv4(addr1); addr2 = getNextOpt(ops); invalidIPv4(addr2); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Range start: " << addr1 << endl << "Range end: " << addr2 << endl; AddressRange *o=AddressRange::cast(nobj); o->setRangeStart(InetAddr(addr1)); o->setRangeEnd(InetAddr(addr2)); } else if (objtype==ObjectGroup::TYPENAME) { //ObjectGroup *o=ObjectGroup::cast(nobj); ; } else if (objtype==Network::TYPENAME) { try { addr1 = getNextOpt(ops); invalidIPv4(addr1); addr2 = getNextOpt(ops); invalidIPv4(addr2); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Address: " << addr1 << endl << "Netmask: " << addr2 << endl; Network *o=Network::cast(nobj); o->setAddress(InetAddr(addr1)); o->setNetmask(InetAddr(addr2)); } else if (objtype==NetworkIPv6::TYPENAME) { try { addr1=getNextOpt(ops); invalidIPv6(addr1); addr2=getNextOpt(ops); invalidIPv6(addr2); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Address: " << addr1 << endl << "Netmask: " << addr2 << endl; NetworkIPv6 *o=NetworkIPv6::cast(nobj); o->setAddress(InetAddr(AF_INET6, addr1)); istringstream istr(addr2); int masklen; istr >> masklen; o->setNetmask(InetAddr(AF_INET6, masklen)); } else if (objtype==Firewall::TYPENAME || objtype==Cluster::TYPENAME) { try { platform=getNextOpt(ops); hostOS=getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Platform: " << platform << endl << "Host OS: " << hostOS << endl; if (testPlatform(platform, hostOS)) { Firewall *o=Firewall::cast(nobj); o->setStr("platform",platform); o->setStr("host_OS",hostOS); } else { cout << "Platform and Host OS combination is invalid." << endl; } } else if (objtype==Interval::TYPENAME) { try { time1 = getNextOpt(ops); date1 = getNextOpt(ops); day1 = getNextOpt(ops); time2 = getNextOpt(ops); date2 = getNextOpt(ops); day2 = getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } QTime time; QDate date; int m,h,d,mn,y,dw; cout << "Activate a rule on:" << endl << "Time: " << time1 << endl << "Date: " << date1 << endl << "Day of week:" << day1 << endl << "Deactivate a rule on:" << endl << "Time: " << time2 << endl << "Date: " << date2 << endl << "Day of week:" << day2 << endl; Interval *o=Interval::cast(nobj); if (time1 == "") { m=0; h=0; } else { time=QTime::fromString(time1.c_str()); m=time.minute(); h=time.hour(); } if (date1 == "") { mn=2; d=28; y=2935093; } else { date=QDate::fromString(date1.c_str(),Qt::ISODate); mn=date.month(); d=date.day(); y=date.year(); } if (day1 == "") { dw=-1; } else { dw=atoi(day1.c_str()); } o->setStartTime(m,h,d,mn,y,dw); if (time2 == "") { m=0; h=0; } else { time=QTime::fromString(time2.c_str()); m=time.minute(); h=time.hour(); } if (date2 == "") { mn=2; d=28; y=2935093; } else { date=QDate::fromString(date2.c_str(),Qt::ISODate); mn=date.month(); d=date.day(); y=date.year(); } if (day2 == "") { dw=-1; } else { dw=atoi(day2.c_str()); } o->setEndTime(m,h,d,mn,y,dw); } else if (objtype==Interface::TYPENAME) { try { security=getNextOpt(ops); addrtype=getNextOpt(ops); management=getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } if (security=="") { cout << "Security level is mandatory attribute." << endl; } else { cout << "Security level: " << security << endl << "Address type: " << addrtype << endl << "Management interface: " << management << endl; Interface *o = Interface::cast(nobj); int sl = atoi(security.c_str()); o->setSecurityLevel(sl); o->setDyn(addrtype=="dynamic"); o->setUnnumbered(addrtype=="unnumbered"); o->setManagement(getBool(management)); } } else if (objtype==Host::TYPENAME) { //Host *o=Host::cast(nobj); ; } else if (objtype==TCPService::TYPENAME) { try { addr1=getNextOpt(ops); addr2=getNextOpt(ops); addr3=getNextOpt(ops); addr4=getNextOpt(ops); tcpflags_mask=getNextOpt(ops); tcpflags_bits=getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Source port range:" << endl << "Start: " << addr1 << endl << "End: " << addr2 << endl << "Destination port range:" << endl << "Start: " << addr3 << endl << "End: " << addr4 << endl << "TCP Flags: " << endl << "Mask: " << tcpflags_mask << endl << "Settings: " << tcpflags_bits << endl; TCPService *o=TCPService::cast(nobj); o->setSrcRangeStart(atoi(addr1.c_str())); o->setSrcRangeEnd( atoi(addr2.c_str())); o->setDstRangeStart(atoi(addr3.c_str())); o->setDstRangeEnd( atoi(addr4.c_str())); o->setBool("urg_flag_mask", tcpflags_mask.find('u')!=string::npos || tcpflags_mask.find('U')!=string::npos); o->setBool("ack_flag_mask", tcpflags_mask.find('a')!=string::npos || tcpflags_mask.find('A')!=string::npos); o->setBool("psh_flag_mask", tcpflags_mask.find('p')!=string::npos || tcpflags_mask.find('P')!=string::npos); o->setBool("rst_flag_mask", tcpflags_mask.find('r')!=string::npos || tcpflags_mask.find('R')!=string::npos); o->setBool("syn_flag_mask", tcpflags_mask.find('s')!=string::npos || tcpflags_mask.find('S')!=string::npos); o->setBool("fin_flag_mask", tcpflags_mask.find('f')!=string::npos || tcpflags_mask.find('F')!=string::npos); o->setBool("urg_flag", tcpflags_bits.find('u')!=string::npos || tcpflags_bits.find('U')!=string::npos); o->setBool("ack_flag", tcpflags_bits.find('a')!=string::npos || tcpflags_bits.find('A')!=string::npos); o->setBool("psh_flag", tcpflags_bits.find('p')!=string::npos || tcpflags_bits.find('P')!=string::npos); o->setBool("rst_flag", tcpflags_bits.find('r')!=string::npos || tcpflags_bits.find('R')!=string::npos); o->setBool("syn_flag", tcpflags_bits.find('s')!=string::npos || tcpflags_bits.find('S')!=string::npos); o->setBool("fin_flag", tcpflags_bits.find('f')!=string::npos || tcpflags_bits.find('F')!=string::npos); } else if (objtype==UDPService::TYPENAME) { try { addr1=getNextOpt(ops); addr2=getNextOpt(ops); addr3=getNextOpt(ops); addr4=getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Source port range:" << endl << "Start: " << addr1 << endl << "End: " << addr2 << endl << "Destination port range:" << endl << "Start: " << addr3 << endl << "End: " << addr4 << endl; UDPService *o=UDPService::cast(nobj); o->setSrcRangeStart(atoi(addr1.c_str())); o->setSrcRangeEnd( atoi(addr2.c_str())); o->setDstRangeStart(atoi(addr3.c_str())); o->setDstRangeEnd( atoi(addr4.c_str())); } else if (objtype==ICMPService::TYPENAME) { try { ICMPtype=getNextOpt(ops); ICMPcode=getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "ICMP type: " << ICMPtype << endl << "ICMP code: " << ICMPcode << endl; ICMPService *o=ICMPService::cast(nobj); o->setInt("type",atoi(ICMPtype.c_str())); o->setInt("code",atoi(ICMPcode.c_str())); } else if (objtype==IPService::TYPENAME) { try { protocol=getNextOpt(ops); bitmap=getNextOpt(ops); } catch (OperandsError &e) { notEnoughAttributesError(); } cout << "Protocol number: " << protocol << endl << "Flags: " << bitmap << endl; IPService *o=IPService::cast(nobj); o->setInt("protocol_num",atoi(protocol.c_str())); o->setBool("lsrr",false); o->setBool("ssrr",false); o->setBool("rr",false); o->setBool("ts",false); o->setBool("fragm",false); o->setBool("short_fragm",false); operands flags; int n=splitStr('/',bitmap,&flags); string tt; try { for (int i=0; isetBool(tt,true); } else if (tt=="ssrr") { o->setBool(tt,true); } else if (tt=="rr") { o->setBool(tt,true); } else if (tt=="ts") { o->setBool(tt,true); } else if (tt=="fragm") { o->setBool(tt,true); } else if (tt=="short_fragm") { o->setBool(tt,true); } } } catch (OperandsError &e) { notEnoughAttributesError(); } } } void newObject(FWObjectDatabase *objdb, const string &objtype, const string &name, const string &comment_txt, const string &parent, operands &ops) { initConstants(); if (parent.empty()) { cout << "Parent for the object is undefined." << endl; usage(); exit(1); } if (objtype.empty() || name.empty()) { cout << "Need object type and name" << endl; usage(); exit(-1); } cout << "Adding a new object to '" << parent <<"': " << endl << "Type: " << objtype << endl << "Name: " << name << endl; FWObject *nobj = createObject(objdb, objtype, parent); nobj->setName(name); _modObject(nobj, comment_txt, ops); if (objtype==Library::TYPENAME) { FWObject *new_child = createObject(objdb, ObjectGroup::TYPENAME, nobj->getPath()); new_child->setName("Objects"); cout << new_child->getPath() << endl; new_child = createObject(objdb, ServiceGroup::TYPENAME, nobj->getPath()); new_child->setName("Services"); cout << new_child->getPath() << endl; std::map::iterator it; for (it=systemGroupPaths.begin(); it!=systemGroupPaths.end(); ++it) { string path = it->second; if (path.empty()) continue; string t = systemGroupTypes[path]; string::size_type n = path.find("/"); string parent_obj = path.substr(0,n); string obj_name = path.substr(n+1); if (n==string::npos) parent_obj = ""; new_child = createObject( objdb, t, nobj->getName() + "/" + parent_obj); new_child->setName(obj_name); cout << new_child->getPath() << endl; } } cout << endl; } void modObject(FWObjectDatabase *objdb, const string &object, const string &comment_txt, operands &ops) { list objects; findObjects(object, objdb, objects); if (objects.size()==0) { cout << "Object " << object << " not found" << endl; exit(-1); } for (list::iterator it=objects.begin(); it!=objects.end(); ++it) { FWObject *obj = *it; cout << obj->getPath() << endl; _modObject(obj, comment_txt, ops); } } void delObject(FWObjectDatabase *objdb, const string &object) { list objects; findObjects(object, objdb, objects); if (objects.size()==0) { cout << "Object " << object << " not found" << endl; exit(-1); } for (list::iterator it=objects.begin(); it!=objects.end(); ++it) { FWObject *obj = *it; cout << "Removing object '" << obj->getName() << "' from the tree." << endl; objdb->removeAllInstances(obj); } } fwbuilder-5.1.0.3599/src/fwbedit/fwbedit.h0000644000175000017500000000631011733011756021006 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: fwbedit.cpp 429 2008-07-31 07:03:39Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include #include #include #include // can't use 'DELETE' in this enum because it is degined somewhere on windows typedef enum { NONE, ADDGRP, REMGRP, DELOBJECT, NEWOBJECT, MODOBJECT, LIST, STRUCT, UPGRADE, MERGE, IMPORT} command; class OperandsError : public std::exception {}; // need to qualify deque even though we use "using namespace std;" // to make it compile on windows typedef std::deque operands; extern void listObject(libfwbuilder::FWObjectDatabase *objdb, const std::string &path, bool list_children, bool recursive, const std::string &list_format, bool full_dump); extern void newObject(libfwbuilder::FWObjectDatabase *objdb, const std::string &objtype, const std::string &name, const std::string &comment_txt, const std::string &parent, operands &ops); extern void delObject(libfwbuilder::FWObjectDatabase *objdb, const std::string &object); extern void modObject(libfwbuilder::FWObjectDatabase *objdb, const std::string &object, const std::string &comment_txt, operands &ops); extern void checkAndRepairTree(libfwbuilder::FWObjectDatabase *objdb); extern void mergeTree(libfwbuilder::FWObjectDatabase *objdb, const std::string &mergefile, int conflict_res); extern void importConfig(const std::string &import_config, libfwbuilder::FWObject *library, const std::string &fw_name, bool deduplicate); extern int splitStr(char ch,std::string s, operands * ops); extern std::string getNextOpt(operands &ops); extern std::string fixPath(const std::string &obj_path); extern void findObjects(const std::string &obj_path, libfwbuilder::FWObject *obj, std::list &res); extern bool getBool(std::string s); extern void usage(); fwbuilder-5.1.0.3599/src/fwbedit/fwbedit.cpp0000644000175000017500000005753111733011756021354 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" #include #include #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #ifndef _WIN32 # include #endif #include #include #include #include #include #include #ifndef errno extern int errno; #endif #ifdef HAVE_GETOPT_H # include #else # ifdef _WIN32 # include # else # include # endif #endif #include "fwbuilder/Resources.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interval.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Constants.h" #include "../common/init.cpp" #include "fwbedit.h" #include "upgradePredicate.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" #include #include using namespace libfwbuilder; using namespace std; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; string cmd_str = ""; command cmd = NONE; bool autoupgrade_flag = false; string filename = ""; string filemerge = ""; int conflict_res = 1; vector platforms; FWObjectDatabase *objdb = NULL; int fwbdebug = 0; void list_attributes() { cout << "Attributes for the new objects, by type:" << endl; cout << endl; cout << " " << " -t " < &res) { string path = fixPath(obj_path); if (obj->getPath()==path) res.push_back(obj); for (FWObject::iterator it=obj->begin(); it!=obj->end(); ++it) { if (FWReference::cast(*it)) continue; _findObjects(path, *it, res); } } string fixPath(const string &obj_path) { string res = obj_path; // add leading "/" if it is not there if (res[0]!='/') res = string("/") + res; // strip trailing "/" if (res[res.length()-1] == '/') res = res.substr(0, res.length()-1); if (res.find("/FWObjectDatabase")!=0) res = string("/FWObjectDatabase") + res; return res; } void findObjects(const string &obj_path, FWObject *obj, list &res) { if (obj_path.find('/')==string::npos) { int id = FWObjectDatabase::getIntId(obj_path); if (id>=0) { FWObject *o = obj->getRoot()->findInIndex(id); if (o) { res.push_back(o); return; } } } string path = fixPath(obj_path); _findObjects(path, obj, res); } int splitStr(char ch,string s, operands * ops) { int res=0; string::size_type pos; ops->clear(); if (s.length()>0) { while((pos=s.find_first_of(ch))!=string::npos) { ops->push_back(s.substr(0,pos)); s=s.substr(pos+1); res++; } ops->push_back(s); res++; } return res; } string getNextOpt(operands &ops) { operands::iterator it = ops.begin(); if (it == ops.end()) throw OperandsError(); string s = *it; ops.pop_front(); return s; } bool getBool(string s) { return (s.find("y")!=string::npos) || (s.find("Y")!=string::npos) || (s.find("1")!=string::npos); } int main(int argc, char * const *argv) { operands ops; string objtype; string name; string object; string group; string parent; string comment_txt; bool list_children = false; bool recursive = false; string list_format = "%path%"; bool full_dump = false; string import_config; bool deduplicate = false; if (argc<=1) { usage(); exit(1); } /* * Command line format: * fwbedit command [options] * * argv[1] is always command */ cmd_str = string(argv[1]); cmd = NONE; if (cmd_str=="new") cmd = NEWOBJECT; if (cmd_str=="delete") cmd = DELOBJECT; if (cmd_str=="modify") cmd = MODOBJECT; if (cmd_str=="add") cmd = ADDGRP; if (cmd_str=="remove") cmd = REMGRP; if (cmd_str=="list") cmd = LIST; if (cmd_str=="upgrade") cmd = UPGRADE; if (cmd_str=="checktree") cmd = STRUCT; if (cmd_str=="merge") cmd = MERGE; if (cmd_str=="import") cmd = IMPORT; char * const *args = argv; args++; argc--; int opt; switch (cmd) { case NEWOBJECT: { // -f file.fwb -t objtype -n name -c comment -p parent [-a attrs] while( (opt=getopt(argc, args, "f:t:n:c:p:a:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 't': objtype = optarg; break; case 'n': name = optarg; break; case 'c': comment_txt = optarg; break; case 'p': parent = optarg; break; case 'a': int num=0; if (optarg!=NULL) { string str = optarg; num = splitStr(',', str, &ops); } break; } } if (filename=="") { usage_new(); exit(1); } break; } case DELOBJECT: // -f file.fwb -o object_def // object_def can be either full path or object ID while( (opt=getopt(argc, args, "f:o:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 'o': object = optarg; break; } } if (filename.empty() || object.empty()) { usage_delete(); exit(1); } break; case MODOBJECT: { // -f file.fwb -o object -c comment [-a attrs] while( (opt=getopt(argc, args, "f:o:c:a:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 'o': object = optarg; break; case 'c': comment_txt = optarg; break; case 'a': int num=0; if (optarg!=NULL) { string str = optarg; num = splitStr(',', str, &ops); } break; } } if (filename.empty() || object.empty()) { usage_modify(); exit(1); } break; } case ADDGRP: case REMGRP: // -f file.fwb -p group -o object // Add/remove object to group // both group and object can be either path or ID while( (opt=getopt(argc, args, "f:g:o:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 'g': group = optarg; break; case 'o': object = optarg; break; } } if (filename.empty() || group.empty() || object.empty()) { if (cmd == ADDGRP) usage_add(); if (cmd == REMGRP) usage_remove(); exit(1); } break; case LIST: // -f file.fwb -o object [-r] [-Fformat_string] [-d] // object can be either path or ID while( (opt=getopt(argc, args, "f:o:crdF:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 'o': object = optarg; break; case 'c': list_children = true; break; case 'r': recursive = true; break; case 'F': list_format = optarg; break; case 'd': full_dump = true; break; } } if (filename.empty() || object.empty()) { usage_list(); exit(1); } break; case UPGRADE: // -f file.fwb autoupgrade_flag = true; while( (opt=getopt(argc, args, "f:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; } } if (filename.empty()) { usage_upgrade(); exit(1); } break; case STRUCT: // -f file.fwb while( (opt=getopt(argc, args, "f:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; } } if (filename.empty()) { usage_checktree(); exit(1); } break; case MERGE: // -f file1.fwb -i file2.fwb while( (opt=getopt(argc, args, "f:i:c:")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 'i': filemerge = optarg; break; case 'c': conflict_res = atoi(optarg); break; } } if (filename.empty() || filemerge.empty()) { usage_merge(); exit(1); } break; case IMPORT: // -f file.fwb -i config.txt -o /User/Firewalls/new_firewall while( (opt=getopt(argc, args, "f:i:o:d")) != EOF ) { switch(opt) { case 'f': filename = optarg; break; case 'i': import_config = optarg; break; case 'o': object = optarg; break; case 'd': deduplicate = true; break; } } if (filename.empty() || import_config.empty() || object.empty()) { usage_import(); exit(1); } break; case NONE: break; } if (cmd==NONE || filename=="") { usage(); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate(autoupgrade_flag); objdb->load(filename, &upgrade_predicate, Constants::getDTDDirectory()); if (cmd == MERGE) { if (filemerge.empty()) { cerr << "The name of the file that should be merged is missing" << endl; usage_merge(); exit(1); } mergeTree(objdb, filemerge, conflict_res); } else if (cmd == IMPORT) { if (import_config.empty() || object.empty()) { cerr << "Configuration file name and path to the new firewall " "object are mandatory options for import" << endl; usage_import(); exit(1); } QStringList components = QString::fromUtf8(object.c_str()) .split("/", QString::SkipEmptyParts); string fw_name = components.last().toUtf8().constData(); Library *library = NULL; while (library == NULL) { components.pop_back(); string library_path = components.join("/").toUtf8().constData(); list objects; findObjects(library_path, objdb, objects); if (objects.size() == 0) { cerr << "Library or folder '" << library_path << "' not found" << endl; usage_import(); exit(1); } library = Library::cast(objects.front()); } cout << "Import firewall configuration from file " << import_config << endl; cout << "New firewall object '" << fw_name << "' will be created in library '" << library->getName() << "'" << endl; importConfig(import_config, library, fw_name, deduplicate); } else if (cmd == STRUCT) { checkAndRepairTree(objdb); } else if (cmd == LIST) { listObject(objdb, object, list_children, recursive, list_format, full_dump); return(0); } else if (cmd == UPGRADE) { cout << "File upgraded; current data format version: " << libfwbuilder::Constants::getDataFormatVersion() << endl; } else if (cmd == NEWOBJECT) { newObject(objdb, objtype, name, comment_txt, parent, ops); } else if (cmd == DELOBJECT) { delObject(objdb, object); } else if (cmd == MODOBJECT) { modObject(objdb, object, comment_txt, ops); } else { list objects; findObjects(object, objdb, objects); if (objects.size()==0) { cout << "Object " << object << " not found" << endl; exit(-1); } for (list::iterator it=objects.begin(); it!=objects.end(); ++it) { FWObject *obj = *it; if (cmd==ADDGRP) { list groups; findObjects(group, objdb, groups); if (groups.size()==0) { cout << "Group " << group << " not found" << endl; exit(-1); } FWObject *grp = groups.front(); cout << "Adding object '" << obj->getName() << "' to the group '" << grp->getName() << "'" << endl; grp->addRef(obj); } if (cmd==REMGRP) { list groups; findObjects(group, objdb, groups); if (groups.size()==0) { cout << "Group " << group << " not found" << endl; exit(-1); } FWObject *grp = groups.front(); cout << "Removing object '" << obj->getName() << "' from the group '" << grp->getName() << "'" << endl; grp->removeRef(obj); } } } QString filename_qstr = QString::fromUtf8(filename.c_str()); QString bakfile = filename_qstr + ".bak"; QFile bakf(bakfile); if (bakf.exists()) bakf.remove(); QFile dataf(filename_qstr); if (dataf.rename(bakfile)) { objdb->saveFile(filename); } else { cout << "Could not rename data file, abroting operation" << endl; cout << dataf.errorString().toStdString() << endl; exit(-1); } } catch(FWException &ex) { cerr << ex.toString() << endl; exit(1); } catch (std::string s) { cerr << s; exit(1); } catch (std::exception ex) { cerr << ex.what(); exit(1); } catch (...) { cerr << "Unsupported exception"; exit(1); } return(0); } fwbuilder-5.1.0.3599/src/fwbedit/import.cpp0000644000175000017500000000601611733011756021232 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Library.h" #include "fwbedit.h" #include "PreImport.h" #include "IOSImporter.h" #include "IPTImporter.h" #include "PIXImporter.h" #include #include #include using namespace libfwbuilder; using namespace std; Logger& operator<<(Logger &logger, const QString &str) { logger << str.toUtf8().constData(); return logger; } void importConfig(const string &import_config, FWObject *library, const string &fw_name, bool deduplicate) { QFile f(QString::fromUtf8(import_config.c_str())); f.open(QFile::ReadOnly); string buffer = QString(f.readAll()).toStdString(); f.close(); std::istringstream instream(buffer); QueueLogger *logger = new QueueLogger(); logger->copyToStderr(); Importer* imp = NULL; QStringList sl_buf = QString::fromUtf8(buffer.c_str()).split("\n"); PreImport pi(&sl_buf); pi.scan(); switch (pi.getPlatform()) { case PreImport::PIX: case PreImport::FWSM: imp = new PIXImporter(library, instream, logger, fw_name); break; case PreImport::IOSACL: imp = new IOSImporter(library, instream, logger, fw_name); break; case PreImport::IPTABLES: imp = new IPTImporter(library, instream, logger, fw_name); break; case PreImport::IPTABLES_WITH_COUNTERS: cerr << "This appears to be iptables configuration saved using " "command \"iptables-save -c\"" "and it includes packet counters. Please save configuration " "using command \"iptables-save\" without option \"-c\" and " "try to import it again." << endl; exit(1); default: cerr << "Can not import configuration file: unrecognized firewall platform" << endl; exit(1); } if (deduplicate) imp->prepareForDeduplication(); try { imp->run(); } catch(ImporterException &e) { *logger << e.toString() << "\n"; } catch(ObjectMakerException &e) { *logger << e.toString() << "\n"; } imp->finalize(); } fwbuilder-5.1.0.3599/src/fwbedit/repair_tree.cpp0000644000175000017500000001166311733011756022225 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: fwbedit.cpp 429 2008-07-31 07:03:39Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/IntervalGroup.h" #include "fwbedit.h" #include using namespace libfwbuilder; using namespace std; void testAndFix(FWObjectDatabase *objdb, const string &path, const string &type, FWObject *root) { list objects; findObjects(path, root, objects); if (objects.size()==0) { string::size_type n = path.rfind('/'); string obj_name = path.substr(n+1); string parent_path = path.substr(0, n); findObjects(parent_path, root, objects); assert(objects.size()==1); FWObject *parent = objects.front(); cout << path << " is missing "; FWObject *new_obj = objdb->create(type); new_obj->setName(obj_name); parent->add(new_obj); cout << "( Fixed )" << endl; } else cout << path << " ok" << endl; } void checkAndRepairTree(FWObjectDatabase *objdb) { cout << "Check and repair tree structure:" << endl; FWObject *root=objdb; FWObject *nlib; string lib_name; bool ro_flag; for (FWObject::iterator i=root->begin(); i!=root->end(); ++i) { nlib = *i; lib_name = nlib->getName(); if (nlib->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID) { ro_flag = nlib->isReadOnly(); cout << "Library: " << lib_name << ((ro_flag)?"(Read only)":" ") << endl; nlib->setReadOnly(false); testAndFix(objdb, lib_name + "/Objects", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/Address Ranges", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/Address Tables", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/Addresses", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/DNS Names", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/Groups", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/Hosts", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Objects/Networks", ObjectGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services", ServiceGroup::TYPENAME,nlib); testAndFix(objdb, lib_name + "/Services/Custom", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/Groups", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/ICMP", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/IP", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/TCP", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/UDP", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/Custom", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/TagServices", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Services/Users", ServiceGroup::TYPENAME, root); testAndFix(objdb, lib_name + "/Clusters", ObjectGroup::TYPENAME,nlib); testAndFix(objdb, lib_name + "/Firewalls", ObjectGroup::TYPENAME,nlib); testAndFix(objdb, lib_name + "/Time", IntervalGroup::TYPENAME,nlib); nlib->setReadOnly(ro_flag); } } } fwbuilder-5.1.0.3599/src/fwbedit/upgradePredicate.h0000644000175000017500000000343411733011756022636 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003-2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "fwbuilder/XMLTools.h" #include class UpgradePredicate: public libfwbuilder::XMLTools::UpgradePredicate { bool autoupgrade_flag; public: UpgradePredicate(bool autoupgrade) { autoupgrade_flag = autoupgrade; } virtual bool operator()(const std::string&) const { bool res=false; std::cout << "Data file has been created in the old version of Firewall Builder." << std::endl << std::flush; if (autoupgrade_flag) { std::cout << "Do you want to convert it? (Y/n)" << std::endl; int a = getchar(); if (a=='y' || a=='Y' || a=='\n' ) res= true; } else { std::cout << "Use option '-u' to upgrade the file in fwbedit." " Alternatively, fwbuilder GUI can convert it." << std::endl; } if (res) std::cout << "Upgrading the file now ..." << std::endl; return res; } }; fwbuilder-5.1.0.3599/src/fwbedit/fwbedit.pro0000644000175000017500000000176011733011756021363 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # # TEMPLATE = app QT += network SOURCES = fwbedit.cpp new_object.cpp repair_tree.cpp list_object.cpp merge.cpp import.cpp HEADERS = ../../config.h fwbedit.h upgradePredicate.h INCLUDEPATH += ../libfwbuilder/src ../import ../compiler_lib ../libgui DEPENDPATH += ../libfwbuilder/src ../import ../compiler_lib ../libgui win32:INCLUDEPATH += ../libgui/ui !win32:INCLUDEPATH += ../libgui/.ui TARGET = fwbedit !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../import/$$BINARY_SUBDIR/libimport.a \ ../parsers/$$BINARY_SUBDIR/libfwbparser.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libgui/$$BINARY_SUBDIR/libgui.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$ANTLR_LIBS $$LIBS win32:CONFIG += console fwbuilder-5.1.0.3599/src/fwbedit/merge.cpp0000644000175000017500000000422211733011756021014 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Constants.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Constants.h" #include "fwbedit.h" #include "upgradePredicate.h" #include using namespace libfwbuilder; using namespace std; class MergeConflictRes : public libfwbuilder::FWObjectDatabase::ConflictResolutionPredicate { int conflict_res; public: MergeConflictRes(int cr) { conflict_res = cr; } virtual bool askUser(libfwbuilder::FWObject*, libfwbuilder::FWObject*) { return (conflict_res == 1); } }; void mergeTree(FWObjectDatabase *objdb, const string &mergefile, int conflict_res) { cout << "Merge objects from file " << mergefile << endl; UpgradePredicate upgrade_predicate(false); try { FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(mergefile, &upgrade_predicate, Constants::getDTDDirectory()); FWObject *dobj = ndb->findInIndex(FWObjectDatabase::DELETED_OBJECTS_ID); if (dobj) ndb->remove(dobj, false); MergeConflictRes mcr(conflict_res); objdb->merge(ndb, &mcr); delete ndb; } catch(FWException &ex) { cerr << ex.toString() << endl; } } fwbuilder-5.1.0.3599/src/ipfw/0000755000175000017500000000000011733011756016532 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/ipfw/ipfw.pro0000644000175000017500000000124611733011756020224 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # SOURCES = ipfw.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32:CONFIG += console INCLUDEPATH += ../pflib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../pflib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../pflib/$$BINARY_SUBDIR/libfwbpf.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_ipfw fwbuilder-5.1.0.3599/src/ipfw/ipfw.cpp0000644000175000017500000001167111733011756020211 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #ifndef _WIN32 # include # include #else # include # include # include #endif #include #include #include #include #include #include #include "CompilerDriver_ipfw.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Constants.h" #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; int fwbdebug = 0; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for ipfw" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-x] [-v] [-V] [-f filename.xml] [-o output.fw] [-d destdir] [-m] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->merge(ndb, NULL); delete ndb; objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_ipfw *driver = new CompilerDriver_ipfw(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; delete driver; delete objdb; return ret; } catch(const FWException &ex) { cerr << ex.toString() << endl; return 1; #if __GNUC__ >= 3 /* need to check version because std::ios::failure does not seem to be * supported in gcc 2.9.5 on FreeBSD 4.10 */ } catch (const std::ios::failure &e) { cerr << "Error while opening or writing to the output file" << endl; return 1; #endif } catch (const std::string &s) { cerr << s; return 1; } catch (const std::exception &ex) { cerr << ex.what(); return 1; } catch (...) { cerr << "Unsupported exception"; return 1; } } fwbuilder-5.1.0.3599/src/pflib/0000755000175000017500000000000011733011756016661 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/pflib/OSConfigurator_freebsd.cpp0000644000175000017500000004120111733011756023761 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "OSConfigurator_freebsd.h" #include "Configlet.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_freebsd::myPlatformName() { return "FreeBSD"; } string OSConfigurator_freebsd::printKernelVarsCommands() { FWOptions* options = fw->getOptionsObject(); std::auto_ptr kernel_vars; if (options->getBool("generate_rc_conf_file")) { kernel_vars = std::auto_ptr( new Configlet(fw, "freebsd", "rc_conf_kernel_vars")); } else { kernel_vars = std::auto_ptr( new Configlet(fw, "bsd", "kernel_vars")); } kernel_vars->removeComments(); setKernelVariable(fw, "freebsd_ip_forward", kernel_vars.get()); setKernelVariable(fw, "freebsd_ipv6_forward", kernel_vars.get()); setKernelVariable(fw, "freebsd_ip_sourceroute", kernel_vars.get()); //setKernelVariable(fw, "freebsd_ip_redirect", kernel_vars.get()); return kernel_vars->expand().toStdString(); } void OSConfigurator_freebsd::setKernelVariable(Firewall *fw, const string &var_name, Configlet *configlet) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { string s; s = options->getStr(var_name); if (!s.empty()) { configlet->setVariable(QString("have_") + var_name.c_str(), 1); string yesno = (s=="1" || s=="on" || s=="On") ? "YES" : "NO"; configlet->setVariable(QString(var_name.c_str()), QString(yesno.c_str())); } } else OSConfigurator_bsd::setKernelVariable(fw, var_name, configlet); } int OSConfigurator_freebsd::prolog() { //printPathForAllTools("freebsd"); //printFunctions(); //processFirewallOptions(); //configureInterfaces(); return 0; } void OSConfigurator_freebsd::summaryConfigLineIP(QStringList names, bool ipv6) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file") && !names.isEmpty()) { if (ipv6) { interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("ipv6_network_interfaces=\"%1\"").arg(names.join(" ")); } else { interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("network_interfaces=\"%1\"").arg(names.join(" ")); } } } void OSConfigurator_freebsd::interfaceConfigLineIP( Interface *iface, list > all_addresses) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { /* * lines in rc.conf have the following format: * * network_interfaces="ed0 ed1 lo0" * ifconfig_ed0="inet 192.0.2.1 netmask 0xffffff00" * ipv4_addrs_ed0="192.0.2.129/27 192.0.2.1-5/28" * */ QString interface_name = iface->getName().c_str(); if (iface->isDyn()) { ifconfig_lines[interface_name] << "DHCP"; return; } int ipv4_alias_counter = -2; int ipv6_alias_counter = -2; for (list >::iterator j = all_addresses.begin(); j != all_addresses.end(); ++j) { QString ipv4_conf_line; QString ipv6_conf_line; InetAddr ipaddr = j->first; InetAddr ipnetm = j->second; if (ipaddr.isV6()) { ipv6_conf_line += QString("%1/%2") .arg(ipaddr.toString().c_str()) .arg(ipnetm.getLength()); ipv6_alias_counter++; } else { int nbits = ipnetm.getLength(); uint32_t netm = 0; while (nbits) { netm = netm >> 1; netm |= 1<<31; nbits--; } ipv4_conf_line += QString("%1 netmask 0x%2") .arg(ipaddr.toString().c_str()) .arg(netm, -8, 16); ipv4_alias_counter++; } if (!ipv4_conf_line.isEmpty()) { QString suffix; if (ipv4_alias_counter>=0) suffix = QString("_alias%1").arg(ipv4_alias_counter); ifconfig_lines[interface_name + suffix] << ipv4_conf_line; } if (!ipv6_conf_line.isEmpty()) { QString suffix; if (ipv6_alias_counter>=0) suffix = QString("_alias%1").arg(ipv6_alias_counter); ipv6_ifconfig_lines[interface_name + suffix] << ipv6_conf_line; } } } else OSConfigurator_bsd::interfaceConfigLineIP(iface, all_addresses); } void OSConfigurator_freebsd::interfaceIfconfigLine(Interface *iface) { QString iface_name = iface->getName().c_str(); FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { Configlet configlet(fw, "freebsd", "rc_conf_ifconfig_interface"); QString config_lines = interfaceIfconfigLineInternal(iface, &configlet); if (!config_lines.isEmpty()) ifconfig_lines[iface_name] << config_lines; } else { Configlet configlet(fw, "freebsd", "ifconfig_interface"); QString config_lines = interfaceIfconfigLineInternal(iface, &configlet); if (!config_lines.isEmpty()) interface_configuration_lines[iface_name] << config_lines; } } void OSConfigurator_freebsd::summaryConfigLineVlan(QStringList vlan_names) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { cloned_interfaces += vlan_names; } else interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("sync_vlan_interfaces %1").arg(vlan_names.join(" ")); } /* For rc.conf format: If a vlans_ variable is set, a vlan(4) interface will be created for each item in the list with the vlandev argument set to interface. If a vlan interface's name is a number, then that number is used as the vlan tag and the new vlan interface is named interface.tag. Otherwise, the vlan tag must be specified via a vlan parameter in the create_args_ variable. To create a vlan device named em0.101 on em0 with the vlan tag 101: vlans_em0="101" To create a vlan device named myvlan on em0 with the vlan tag 102: vlans_em0="myvlan" create_args_myvlan="vlan 102" */ void OSConfigurator_freebsd::interfaceConfigLineVlan( Interface *iface, const list &vlan_subinterfaces) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { QString iface_name = iface->getName().c_str(); // the "vlans_em2="vlan101 vlan102" will appear next to other lines // intended for interface em2 QStringList vlan_names; list::const_iterator it; for (it=vlan_subinterfaces.begin(); it!=vlan_subinterfaces.end(); ++it) vlan_names << (*it)->getName().c_str(); interface_configuration_lines[iface_name] << QString("vlans_%1=\"%2\"").arg(iface->getName().c_str()) .arg(vlan_names.join(" ")); for (it=vlan_subinterfaces.begin(); it!=vlan_subinterfaces.end(); ++it) { QString vlan_intf_name = (*it)->getName().c_str(); int vlan_id = (*it)->getOptionsObject()->getInt("vlan_id"); interface_configuration_lines[iface_name] << QString("create_args_%1=\"vlan %2 vlandev %3\"") .arg(vlan_intf_name).arg(vlan_id).arg(iface->getName().c_str()); } } else OSConfigurator_bsd::interfaceConfigLineVlan(iface, vlan_subinterfaces); } void OSConfigurator_freebsd::summaryConfigLineBridge(QStringList bridge_names) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { cloned_interfaces += bridge_names; } else OSConfigurator_bsd::summaryConfigLineBridge(bridge_names); } /* For rc.conf format: Consider a system with two 4-port Ethernet boards. The following will cause a bridge consisting of all 8 ports with Rapid Spanning Tree enabled to be created: ifconfig bridge0 create ifconfig bridge0 \ addm fxp0 stp fxp0 \ addm fxp1 stp fxp1 \ addm fxp2 stp fxp2 \ addm fxp3 stp fxp3 \ addm fxp4 stp fxp4 \ addm fxp5 stp fxp5 \ addm fxp6 stp fxp6 \ addm fxp7 stp fxp7 \ up The bridge can be used as a regular host interface at the same time as bridging between its member ports. In this example, the bridge connects em0 and em1, and will receive its IP address through DHCP: cloned_interfaces="bridge0" ifconfig_bridge0="addm em0 addm em1 DHCP" ifconfig_em0="up" ifconfig_em1="up" Refernce: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-bridging.html */ void OSConfigurator_freebsd::interfaceConfigLineBridge(Interface *iface, QStringList bridge_port_names) { QString iface_name = iface->getName().c_str(); FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { FWOptions *ifopt = iface->getOptionsObject(); assert(ifopt != NULL); bool enable_stp = ifopt->getBool("enable_stp"); QStringList outp; QStringList bp; foreach(QString bridge_port, bridge_port_names) { Configlet port_configlet(fw, "freebsd", "rc_conf_bridge_port"); port_configlet.removeComments(); port_configlet.collapseEmptyStrings(true); port_configlet.setVariable("bridge_interface", iface_name); port_configlet.setVariable("bridge_port", bridge_port); port_configlet.setVariable("stp_off", !enable_stp); bp << port_configlet.expand(); } bp << "up"; ifconfig_lines[iface_name] << bp.join(" "); foreach(QString bridge_port, bridge_port_names) { ifconfig_lines[bridge_port] << "up"; } interface_configuration_lines[iface_name] << outp.join("\n"); } else OSConfigurator_bsd::interfaceConfigLineBridge(iface, bridge_port_names); } void OSConfigurator_freebsd::summaryConfigLineCARP(QStringList carp_names) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { cloned_interfaces += carp_names; } else OSConfigurator_bsd::summaryConfigLineCARP(carp_names); } void OSConfigurator_freebsd::interfaceConfigLineCARP(Interface *iface, FWObject *failover_group) { FWOptions* options = fw->getOptionsObject(); QString configlet_name = "carp_interface"; if (options->getBool("generate_rc_conf_file")) { configlet_name = "rc_conf_carp_interface"; } Configlet configlet(fw, "freebsd", configlet_name); interfaceConfigLineCARPInternal(iface, failover_group, &configlet); } void OSConfigurator_freebsd::summaryConfigLinePfsync(bool have_pfsync) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { if (have_pfsync) interface_configuration_lines["pfsync0"] << "pfsync_enable=\"YES\""; } else OSConfigurator_bsd::summaryConfigLinePfsync(have_pfsync); } /* in rc.conf format: pfsync_enable (bool) Set to ``NO'' by default. Setting this to ``YES'' enables exposing pf(4) state changes to other hosts over the network by means of pfsync(4). The pfsync_syncdev variable must also be set then. pfsync_syncdev (str) Empty by default. This variable specifies the name of the network interface pfsync(4) should operate through. It must be set accordingly if pfsync_enable is set to ``YES''. pfsync_syncpeer (str) Empty by default. This variable is optional. By default, state change messages are sent out on the synchroni- sation interface using IP multicast packets. The protocol is IP protocol 240, PFSYNC, and the multicast group used is 224.0.0.240. When a peer address is specified using the pfsync_syncpeer option, the peer address is used as a desti- nation for the pfsync traffic, and the traffic can then be protected using ipsec(4). See the pfsync(4) manpage for more details about using ipsec(4) with pfsync(4) interfaces. pfsync_ifconfig (str) Empty by default. This variable can contain additional options to be passed to the ifconfig(8) command used to set up pfsync(4). */ void OSConfigurator_freebsd::interfaceConfigLinePfsync( Interface *iface, StateSyncClusterGroup *state_sync_group) { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { Configlet configlet(fw, "freebsd", "rc_conf_pfsync_interface"); configlet.removeComments(); configlet.collapseEmptyStrings(true); configlet.setVariable("syncdev", iface->getName().c_str()); if (state_sync_group->getOptionsObject()->getBool("syncpeer")) { for (FWObjectTypedChildIterator it = state_sync_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *cluster_iface = Interface::cast( FWObjectReference::getObject(*it)); assert(cluster_iface); if (cluster_iface->getId() == iface->getId()) continue; IPv4 *ipv4 = IPv4::cast(cluster_iface->getFirstByType(IPv4::TYPENAME)); const InetAddr *addr = ipv4->getAddressPtr(); configlet.setVariable("have_syncpeer", 1); configlet.setVariable("syncpeer", addr->toString().c_str()); } } interface_configuration_lines[iface->getName().c_str()] << configlet.expand(); } else OSConfigurator_bsd::interfaceConfigLinePfsync(iface, state_sync_group); } QString OSConfigurator_freebsd::printAllInterfaceConfigurationLines() { FWOptions* options = fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { printIfconfigLines(ifconfig_lines); printIfconfigLines(ipv6_ifconfig_lines); if (!cloned_interfaces.isEmpty()) interface_configuration_lines["0_should_be_on_top_"] << QString("cloned_interfaces=\"%1\"") .arg(cloned_interfaces.join(" ")); } return OSConfigurator_bsd::printAllInterfaceConfigurationLines(); } void OSConfigurator_freebsd::printIfconfigLines(const QMap &lines) { if (!lines.isEmpty()) { QStringList keys = lines.keys(); keys.sort(); foreach (QString iface_name, keys) { const QStringList commands = lines[iface_name]; interface_configuration_lines[iface_name] << QString("ifconfig_%1=\"%2\"").arg(iface_name) .arg(commands.join(" ")); } } } fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_pf.cpp0000644000175000017500000007734111733011756023020 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_pf.h" #include "NATCompiler_pf.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_pf::myPlatformName() { return "pf"; } int PolicyCompiler_pf::prolog() { if (fw->getStr("platform")!=myPlatformName() ) abort("Unsupported platform " + fw->getStr("platform") ); list l2=fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if ( iface->isDyn()) { list l3=iface->getByType(IPv4::TYPENAME); if (l3.size()>0) { QString err( "Dynamic interface %1 should not have an IP " "address object attached to it. This IP address " "object will be ignored."); warning(err.arg(iface->getName().c_str()).toStdString()); for (list::iterator j=l3.begin(); j!=l3.end(); ++j) iface->remove(*j); } } } if (tables) { tables->init(dbcopy); if (!getSourceRuleSet()->isTop()) tables->setRuleSetName(getRuleSetName()); } return PolicyCompiler::prolog(); } /* * this is very much like * Compiler::swapMultiAddressObjectsInRE::processNext() except it also * registers the table using registerTable() */ bool PolicyCompiler_pf::swapAddressTableObjectsInRE::processNext() { PolicyCompiler_pf *pf_comp=dynamic_cast(compiler); Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); /* * All addressTable objects will be run-time here because we * switch them in preprocessor. The difference is: if address * table was originally run-time, at this point it will have * no children, however if it was compile-time originally, it * will have children objects. That is how we distinguish * them in this rule processor. Here we only deal with * AddressTable objects that originally used to be * compile-time because we need to create tables for them. */ if (AddressTable::cast(o)!=NULL && AddressTable::cast(o)->isRunTime() && o->size() > 0) cl.push_back(MultiAddress::cast(o)); } if (!cl.empty()) { for (list::iterator i=cl.begin(); i!=cl.end(); i++) { MultiAddress *atbl = *i; // Need to make sure the ID of the MultiAddressRunTime // object created here is stable and is always the same // for the same MultiAddress object. In particular this // ensures that we reuse tables between policy and NAT rules string mart_id_str = FWObjectDatabase::getStringId(atbl->getId()) + "_runtime"; int mart_id = FWObjectDatabase::registerStringId(mart_id_str); MultiAddressRunTime *mart = MultiAddressRunTime::cast(compiler->dbcopy->findInIndex(mart_id)); if (mart==NULL) { mart = new MultiAddressRunTime(atbl); // need to ensure stable ID for the runtime object, so // that when the same object is replaced in different // rulesets by different compiler passes, chosen // runtime object has the same ID and is identified as // the same by the compiler. mart->setId( mart_id ); compiler->dbcopy->addToIndex(mart); compiler->persistent_objects->add(mart); // register this object as a table string tblname = atbl->getName(); string tblID = tblname + "_addressTableObject"; pf_comp->tables->registerTable(tblname,tblID,atbl); } re->removeRef(atbl); re->addRef(mart); } tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::processMultiAddressObjectsInRE::processNext() { PolicyCompiler_pf *pf_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); bool neg = re->getNeg(); list maddr_runtime; try { for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { if (re->size()>1 && neg) { compiler->abort(rule, "AddressTable object can not be used " "with negation in combination with " "other objects in the same rule element."); } string tblname = o->getName(); string tblID = tblname + "_addressTableObject"; pf_comp->tables->registerTable(tblname,tblID,o); o->setBool("pf_table",true); maddr_runtime.push_back(o); } } } catch(FWException &ex) // TableFactory::registerTable throws exception { string err; err = "Can not process MultiAddress object: " + ex.toString(); compiler->abort(rule, err); } if (!maddr_runtime.empty()) { RuleElement *nre; for (FWObject::iterator i=maddr_runtime.begin(); i!=maddr_runtime.end(); i++) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( *i ); tmp_queue.push_back(r); } for (FWObject::iterator i=maddr_runtime.begin(); i!=maddr_runtime.end(); i++) re->removeRef( *i ); if (!re->isAny()) tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::splitIfFirewallInSrc::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; PolicyRule *r; RuleElementSrc *src = rule->getSrc(); assert(src); if (src->size()==1 || src->getNeg()) { tmp_queue.push_back(rule); return true; } FWObject *fw_in_src = NULL; vector cl; for (FWObject::iterator i1=src->begin(); i1!=src->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); if (obj==NULL) compiler->abort(rule, "Broken Src object"); if (obj->getId()==compiler->getFwId()) { fw_in_src = obj; RuleElementSrc *nsrc; r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc = r->getSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); nsrc->addRef( compiler->fw ); tmp_queue.push_back(r); } } if (fw_in_src!=NULL) src->removeRef( fw_in_src ); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::splitIfFirewallInDst::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; PolicyRule *r; RuleElementDst *dst = rule->getDst(); assert(dst); if (dst->size()==1 || dst->getNeg()) { tmp_queue.push_back(rule); return true; } FWObject *fw_in_dst = NULL; vector cl; for (FWObject::iterator i1=dst->begin(); i1!=dst->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); if (obj==NULL) compiler->abort(rule, "Broken Dst"); if (obj->getId()==compiler->getFwId()) { fw_in_dst = obj; RuleElementDst *ndst; r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst = r->getDst(); ndst->clearChildren(); ndst->setAnyElement(); ndst->addRef( compiler->fw ); tmp_queue.push_back(r); } } if (fw_in_dst!=NULL) dst->removeRef( fw_in_dst ); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::fillDirection::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); /* after interface policies have been merged with global policy, rules * with empty direction have disappeared. In fact, xslt * transformation 2.1.1->2.1.2 leaves empty direction in the old * global policy rules, but the GUI promptly fixes that replacing it * with "Both" whenever user opens the policy. So, we have to handle * both the case of an empty direction and direction "Both". To * preserve old semantics as accurately as possible, I check for a * combination of empty interface and direction "Both", this is what * old global rules become after user opens the combined policy in the * GUI. In fact, it does not matter what direction is set in the rule * as long as it misses interface - we need to determine direction * again anyway. */ if (rule->getDirection() == PolicyRule::Undefined) rule->setDirection( PolicyRule::Both ); /* * Correction for bug #2791950 "no way to generate "pass out" rule * with no interface". Do not reset direction just because interface * rule element is "any", otherwise we can not create rule with no * interface spec: * * pass out quick inet from any to any * * If we reset direction here, instead of this one rule we get two, * one "pass out" and another "pass in". However it is still useful to * change direction if fw is in source or destination. */ if (rule->getDirection() == PolicyRule::Both) { Address *src = compiler->getFirstSrc(rule); Address *dst = compiler->getFirstDst(rule); //int fwid = compiler->getFwId(); if (src==NULL || dst==NULL) compiler->abort(rule, "Broken src or dst"); if (!src->isAny() && !dst->isAny() && compiler->complexMatch(compiler->fw, src) && compiler->complexMatch(compiler->fw, dst)) return true; if (!src->isAny() && compiler->complexMatch(compiler->fw, src)) { rule->setDirection( PolicyRule::Outbound ); compiler->warning( rule, "Changing rule direction due to self reference"); } if (!dst->isAny() && compiler->complexMatch(compiler->fw, dst)) { rule->setDirection( PolicyRule::Inbound ); compiler->warning( rule, "Changing rule direction due to self reference"); } } return true; } bool PolicyCompiler_pf::SpecialServices::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementSrv *srv=rule->getSrv(); for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (IPService::cast(s)!=NULL && rule->getAction()==PolicyRule::Accept) { rule->setBool("allow_opts", IPService::constcast(s)->hasIpOptions()); } } return true; } bool PolicyCompiler_pf::SplitDirection::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getDirection()==PolicyRule::Both && rule->getRouting()) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection(PolicyRule::Inbound); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection(PolicyRule::Outbound); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::ProcessScrubOption::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); if ( ruleopt->getBool("scrub") ) { if (rule->getAction()!=PolicyRule::Accept) { ruleopt->setBool("scrub",false); tmp_queue.push_back(rule); compiler->abort(rule, "Rule option 'scrub' is supported only for rules " "with action 'Accept'"); return true; } PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Scrub); r->getOptionsObject()->setBool("scrub",false); tmp_queue.push_back(r); ruleopt->setBool("scrub",false); tmp_queue.push_back(rule); return true; } /* if service is ip_fragment and action is 'Deny', then add rule with scrub */ Service *srv=compiler->getFirstSrv(rule); assert(srv); if ( (srv->getBool("short_fragm") || srv->getBool("fragm")) && ( rule->getAction()==PolicyRule::Deny || rule->getAction()==PolicyRule::Reject) ) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Scrub); r->getOptionsObject()->setBool("scrub",false); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::setQuickFlag::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); FWOptions *ropt = rule->getOptionsObject(); switch (rule->getAction()) { case PolicyRule::Scrub: case PolicyRule::Accounting: case PolicyRule::Branch: case PolicyRule::Continue: break; default: rule->setBool("quick", true); break; } // as of 4.2.0 build 3477 we provide checkboxes to make Tag and // Classify actions (PF) terminating or non-terminating on // per-rule basis. Old behavior: Tag was non-terminating and // Classify was terminating. Set options accordingly if they are // not set. // // TODO #2367: now instead of checkboxes, user should use actions Accept // or Continue return true; } bool PolicyCompiler_pf::doSrcNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *src=rule->getSrc(); if (src->getNeg()) { RuleElementSrc *nsrc; PolicyRule *r; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); if (rule->getAction()==PolicyRule::Accept) r->setAction(PolicyRule::Deny); else r->setAction(PolicyRule::Accept); nsrc=r->getSrc(); nsrc->setNeg(false); r->setBool("quick",true); r->setLogging(false); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getSrc(); nsrc->setNeg(false); nsrc->clearChildren(); nsrc->setAnyElement(); r->setBool("quick",true); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::doDstNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementDst *dst=rule->getDst(); if (dst->getNeg()) { RuleElementDst *ndst; PolicyRule *r; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); if (rule->getAction()==PolicyRule::Accept) r->setAction(PolicyRule::Deny); else r->setAction(PolicyRule::Accept); ndst=r->getDst(); ndst->setNeg(false); r->setBool("quick",true); r->setLogging(false); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst=r->getDst(); ndst->setNeg(false); ndst->clearChildren(); ndst->setAnyElement(); r->setBool("quick",true); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::doSrvNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv=rule->getSrv(); if (srv->getNeg()) { compiler->abort(rule, "Negation in Srv is not implemented"); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::addLoopbackForRedirect::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; PolicyCompiler_pf *pf_comp = dynamic_cast(compiler); RuleElementDst *dst = rule->getDst(); RuleElementSrv *srv = rule->getSrv(); if (pf_comp->redirect_rules_info==NULL) compiler->abort( rule, "addLoopbackForRedirect needs a valid pointer to " "the list object"); tmp_queue.push_back(rule); if (pf_comp->redirect_rules_info->empty()) return true; for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++) { FWObject *o1 = FWReference::getObject(*i); Service *s = Service::cast( o1 ); assert(s); for (FWObject::iterator j=dst->begin(); j!=dst->end(); j++) { FWObject *o2 = FWReference::getObject(*j); if (o2->getName() == "self" && DNSName::isA(o2)) continue; Address *a = Address::cast( o2 ); assert(a); list::const_iterator k; for (k=pf_comp->redirect_rules_info->begin(); k!=pf_comp->redirect_rules_info->end(); ++k) { Address *old_tdst_obj = Address::cast( compiler->dbcopy->findInIndex(k->old_tdst)); Service *tsrv_obj = Service::cast( compiler->dbcopy->findInIndex(k->tsrv)); if ( *a == *(old_tdst_obj) && *s == *(tsrv_obj) ) { // insert address used for redirection in the NAT rule. FWObject *new_tdst_obj = compiler->dbcopy->findInIndex(k->new_tdst); dst->addRef(new_tdst_obj); return true; } } } } return true; } void PolicyCompiler_pf::checkForDynamicInterfacesOfOtherObjects::findDynamicInterfaces(RuleElement *re, Rule *rule) { if (re->isAny()) return; list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs =Interface::cast( obj ); if (ifs!=NULL && ifs->isDyn() && ifs->getParent()->getId()!=compiler->fw->getId() && ! ifs->getParent()->getBool("pf_table") ) { QString err( "Can not build rule using dynamic interface '%1' " "of the object '%2' because its address in unknown."); compiler->abort( rule, err .arg(ifs->getName().c_str()) .arg(ifs->getParent()->getName().c_str()).toStdString()); } } } bool PolicyCompiler_pf::checkForDynamicInterfacesOfOtherObjects::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; findDynamicInterfaces( rule->getSrc() , rule ); findDynamicInterfaces( rule->getDst() , rule ); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::splitIfInterfaceInRE::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); if (re->size()<=2) { tmp_queue.push_back(rule); return true; } list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Interface *interface_=Interface::cast(o); if (interface_!=NULL && interface_->isDyn()) cl.push_back(interface_); } if (!cl.empty()) { RuleElement *nre; PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); for (FWObject::iterator i=cl.begin(); i!=cl.end(); i++) nre->addRef( *i ); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); for (FWObject::iterator i=cl.begin(); i!=cl.end(); i++) nre->removeRef( *i ); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::createTables::processNext() { PolicyCompiler_pf *pf_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElementSrc *src = rule->getSrc(); RuleElementDst *dst = rule->getDst(); if (!src->isAny()) pf_comp->tables->createTablesForRE(src, rule); if (!dst->isAny()) pf_comp->tables->createTablesForRE(dst, rule); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pf::printScrubRule::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions* options=compiler->fw->getOptionsObject(); if (!init && options->getBool("pf_do_scrub")) { compiler->output << "#" << endl; compiler->output << "# Defragmentation" << endl; compiler->output << "#" << endl; compiler->output << "scrub in from any to any" << endl << endl; init=true; } tmp_queue.push_back(rule); return true; } void PolicyCompiler_pf::compile() { string banner = " Compiling " + fw->getName(); if (!getRuleSetName().empty()) banner += " ruleset " + getRuleSetName(); if (ipv6) banner += ", IPv6"; info(banner); Compiler::compile(); bool check_for_recursive_groups=true; if (fw->getOptionsObject()->getBool("check_shading") && ! inSingleRuleCompileMode()) { add(new Begin("Detecting rule shadowing")); add(new printTotalNumberOfRules()); add(new ItfNegation("process negation in Itf")); add(new InterfacePolicyRules( "process interface policy rules and store interface ids")); add(new recursiveGroupsInSrc("check for recursive groups in SRC")); add(new recursiveGroupsInDst("check for recursive groups in DST")); add(new recursiveGroupsInSrv("check for recursive groups in SRV")); check_for_recursive_groups=false; add(new ExpandGroups("expand groups")); add(new dropRuleWithEmptyRE("drop rules with empty rule elements")); add(new eliminateDuplicatesInSRC("eliminate duplicates in SRC")); add(new eliminateDuplicatesInDST("eliminate duplicates in DST")); add(new eliminateDuplicatesInSRV("eliminate duplicates in SRV")); add(new swapAddressTableObjectsInSrc( "AddressTable -> MultiAddressRunTime in Src")); add(new swapAddressTableObjectsInDst( "AddressTable -> MultiAddressRunTime in Dst")); add(new swapMultiAddressObjectsInSrc( "MultiAddress -> MultiAddressRunTime in Src")); add(new swapMultiAddressObjectsInDst( "MultiAddress -> MultiAddressRunTime in Dst")); add(new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC")); add(new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST")); add(new dropRuleWithEmptyRE( "drop rules with empty rule elements")); add(new ConvertToAtomic("convert to atomic rules")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add(new setQuickFlag("set 'quick' flag")); add(new DetectShadowing("Detect shadowing")); add(new simplePrintProgress()); runRuleProcessors(); deleteRuleProcessors(); } add(new Begin()); add(new printTotalNumberOfRules()); add( new singleRuleFilter()); // add(new printScrubRule(" Defragmentation")); if (check_for_recursive_groups) { add(new recursiveGroupsInSrc("check for recursive groups in SRC")); add(new recursiveGroupsInDst("check for recursive groups in DST")); add(new recursiveGroupsInSrv("check for recursive groups in SRV")); } add(new emptyGroupsInSrc("check for empty groups in SRC")); add(new emptyGroupsInDst("check for empty groups in DST")); add(new emptyGroupsInSrv("check for empty groups in SRV")); // add(new doSrcNegation("process negation in Src")); // add(new doDstNegation("process negation in Dst")); add(new doSrvNegation("process negation in Srv")); if (fw->getOptionsObject()->getBool("preserve_group_names")) { add(new RegisterGroupsAndTablesInSrc( "register object groups and tables in Src")); add(new RegisterGroupsAndTablesInDst( "register object groups and tables in Dst")); } // ExpandGroups opens groups, as well as groups in groups etc. add(new ExpandGroups("expand groups")); add(new dropRuleWithEmptyRE("drop rules with empty rule elements")); add(new CheckForTCPEstablished( "check for TCPService objects with flag \"established\"")); add(new eliminateDuplicatesInSRC("eliminate duplicates in SRC")); add(new eliminateDuplicatesInDST("eliminate duplicates in DST")); add(new eliminateDuplicatesInSRV("eliminate duplicates in SRV")); add(new swapAddressTableObjectsInSrc( "AddressTable -> MultiAddressRunTime in Src")); add(new swapAddressTableObjectsInDst( "AddressTable -> MultiAddressRunTime in Dst")); add(new swapMultiAddressObjectsInSrc( "MultiAddress -> MultiAddressRunTime in Src")); add(new swapMultiAddressObjectsInDst( "MultiAddress -> MultiAddressRunTime in Dst")); add(new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src")); add(new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst")); add(new replaceFailoverInterfaceInItf("replace carp interfaces")); add(new expandGroupsInItf("expand groups in Interface")); add(new replaceClusterInterfaceInItf( "replace cluster interfaces with member interfaces in " "the Interface rule element")); add(new ItfNegation("process negation in Itf")); //add(new InterfacePolicyRules( // "process interface policy rules and store interface ids")); add(new splitIfFirewallInSrc("split rule if firewall is in Src")); add(new ReplaceFirewallObjectWithSelfInSrc( "Replace firewall object with 'self' in Src")); add(new splitIfFirewallInDst("split rule if firewall is in Dst")); add(new ReplaceFirewallObjectWithSelfInDst( "Replace firewall object with 'self' in Dst")); // call these again since "self" is a MultiAddress object add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src")); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst")); add(new fillDirection("determine directions")); // commented out for bug #2828602 // ... and put back per #2844561 // both bug reports/patches are by Tom Judge (tomjudge on sourceforge) add( new SplitDirection("split rules with direction 'both'" )); add(new addLoopbackForRedirect( "add loopback to rules that permit redirected services")); add(new ExpandMultipleAddresses( "expand objects with multiple addresses")); add(new dropRuleWithEmptyRE("drop rules with empty rule elements")); add(new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls")); add(new MACFiltering("verify for MAC address filtering")); add(new checkForUnnumbered("check for unnumbered interfaces")); add(new addressRanges("expand address range objects")); add(new groupServicesByProtocol("split rules with different protocols")); add(new separateTCPWithFlags("separate TCP services with flags")); add(new separateSrcPort("split on TCP and UDP with source ports")); add(new separateTagged("split on TagService")); add(new separateTOS("split on IPService with TOS")); if (ipv6) add( new DropIPv4Rules("drop ipv4 rules")); else add( new DropIPv6Rules("drop ipv6 rules")); add(new verifyCustomServices("verify custom services for this platform")); // add(new ProcessScrubOption("process 'scrub' option")); add(new SpecialServices("check for special services")); add(new setQuickFlag("set 'quick' flag")); add(new checkForZeroAddr("check for zero addresses")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add(new createTables("create tables")); // add(new PrintTables("print tables")); add(new PrintRule("generate pf code")); add(new simplePrintProgress()); runRuleProcessors(); } void PolicyCompiler_pf::epilog() { } /** * virtual method to let policy compiler check rules using * options specific for the given fw platform. Base class * PolicyCompiler has no visibility into platform-specific * options and can not do this. */ bool PolicyCompiler_pf::checkForShadowingPlatformSpecific(PolicyRule *, PolicyRule *r2) { bool quick = r2->getBool("quick"); // if quick == false, the rule is non-terminating if (!quick) return false; return true; } PolicyCompiler_pf::~PolicyCompiler_pf() { // if (tables) tables->detach(); } fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_pf.cpp0000644000175000017500000003335311733011756023007 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "CompilerDriver_pf.h" #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver_pf::CompilerDriver_pf(FWObjectDatabase *db) : CompilerDriver(db) { have_nat = false; have_filter = false; } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_pf::clone() { CompilerDriver_pf* new_cd = new CompilerDriver_pf(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } /* * Generate file name for the ruleset .conf file using general conf * file name as a prototype. */ QString CompilerDriver_pf::getConfFileNameForRuleset(const QString &ruleset_name, const QString &conf_file_name, const QString &ext) { assert(!conf_file_name.isEmpty()); if (ruleset_name == "__main__") return conf_file_name; QString suffix = QString("-") + ruleset_name; QFileInfo fi(conf_file_name); QString path = fi.path(); // qDebug() << "getConfFileNameForRuleset:" // << "conf_file_name=" << conf_file_name // << "path=" << path; QString using_suffix = fi.completeSuffix(); if (!ext.isEmpty()) using_suffix = ext; QString new_name = fi.completeBaseName() + suffix + "." + using_suffix; if (!path.isEmpty() && path != ".") new_name = path + "/" + new_name; return new_name; } QString CompilerDriver_pf::getRemoteConfFileName(const QString &ruleset_name, const QString &local_conf_name, const QString &remote_fw_name, const QString &remote_conf_name) { QString conf_file_name; QString suffix = QString("-") + ruleset_name; if (ruleset_name == "__main__") suffix = ""; if (remote_conf_name.isEmpty() && remote_fw_name.isEmpty()) { // local_conf_name may be a relative or absolute path. Return // just the file name QFileInfo fi(local_conf_name); return fi.fileName(); } QFileInfo fi; if (!remote_conf_name.isEmpty()) fi = QFileInfo(remote_conf_name); else if (!remote_fw_name.isEmpty()) fi = QFileInfo(remote_fw_name); QString new_name = fi.completeBaseName() + suffix + ".conf"; QString path = fi.path(); if (path == ".") return new_name; else return path + "/" + new_name; } string CompilerDriver_pf::printTimeout(FWOptions* options, const string &OnOffOption, const string &ValOption, const string &pfCode) { std::ostringstream res; if (options->getBool(OnOffOption) && options->getInt(ValOption)>0) { res << "set timeout " << pfCode << " " << options->getInt(ValOption) << endl; } return res.str(); } void CompilerDriver_pf::printProlog(QTextStream &file, const string &prolog_code) { file << endl; file << "#" << endl; file << "# Prolog script" << endl; file << "#" << endl; file << prolog_code << endl; file << "#" << endl; file << "# End of prolog script" << endl; file << "#" << endl; } void CompilerDriver_pf::printStaticOptions(QTextStream &file, Firewall* fw) { FWOptions* options = fw->getOptionsObject(); list all_interfaces=fw->getByType(Interface::TYPENAME); string prolog_place = options->getStr("prolog_place"); if (prolog_place.empty()) prolog_place = "fw_file"; // old default string pre_hook = options->getStr("prolog_script"); if (prolog_place == "pf_file_top") printProlog(file, pre_hook); file << endl; string set_debug = options->getStr("pf_set_debug"); if (!set_debug.empty()) { file << "set debug " << set_debug << endl; } string state_policy = options->getStr("pf_state_policy"); if (!state_policy.empty()) { file << "set state-policy " << state_policy << endl; } string block_policy = options->getStr("pf_block_policy"); if (!block_policy.empty()) { file << "set block-policy " << block_policy << endl; } QStringList limits; if (options->getBool("pf_do_limit_frags") && options->getInt("pf_limit_frags")>0 ) limits.push_back(QString("frags ") + options->getStr("pf_limit_frags").c_str()); if (options->getBool("pf_do_limit_states") && options->getInt("pf_limit_states")>0 ) limits.push_back(QString("states ") + options->getStr("pf_limit_states").c_str()); if (options->getBool("pf_do_limit_src_nodes") && options->getInt("pf_limit_src_nodes")>0 ) limits.push_back(QString("src-nodes ") + options->getStr("pf_limit_src_nodes").c_str()); if (options->getBool("pf_do_limit_tables") && options->getInt("pf_limit_tables")>0 ) limits.push_back(QString("tables ") + options->getStr("pf_limit_tables").c_str()); if (options->getBool("pf_do_limit_table_entries") && options->getInt("pf_limit_table_entries")>0 ) limits.push_back(QString("table-entries ") + options->getStr("pf_limit_table_entries").c_str()); if (limits.size() > 0) { file << "set limit "; if (limits.size() > 1 ) file << "{ "; file << limits.join(", "); if (limits.size() > 1 ) file << " }"; file << endl; } if ( ! options->getStr("pf_optimization").empty() ) file << "set optimization " << options->getStr("pf_optimization") << endl; file << printTimeout(options, "pf_do_timeout_interval","pf_timeout_interval", "interval"); file << printTimeout(options, "pf_do_timeout_frag","pf_timeout_frag", "frag"); file << printTimeout(options, "pf_set_tcp_first","pf_tcp_first", "tcp.first" ); file << printTimeout(options, "pf_set_tcp_opening","pf_tcp_opening", "tcp.opening" ); file << printTimeout(options, "pf_set_tcp_established","pf_tcp_established", "tcp.established" ); file << printTimeout(options, "pf_set_tcp_closing","pf_tcp_closing", "tcp.closing" ); file << printTimeout(options, "pf_set_tcp_finwait","pf_tcp_finwait", "tcp.finwait" ); file << printTimeout(options, "pf_set_tcp_closed","pf_tcp_closed", "tcp.closed" ); file << printTimeout(options, "pf_set_udp_first","pf_udp_first", "udp.first" ); file << printTimeout(options, "pf_set_udp_single","pf_udp_single", "udp.single" ); file << printTimeout(options, "pf_set_udp_multiple","pf_udp_multiple", "udp.multiple" ); file << printTimeout(options, "pf_set_icmp_first","pf_icmp_first", "icmp.first" ); file << printTimeout(options, "pf_set_icmp_error","pf_icmp_error", "icmp.error" ); file << printTimeout(options, "pf_set_other_first","pf_other_first", "other.first" ); file << printTimeout(options, "pf_set_other_single","pf_other_single", "other.single" ); file << printTimeout(options, "pf_set_other_multiple","pf_other_multiple", "other.multiple" ); file << printTimeout(options, "pf_set_adaptive","pf_adaptive_start", "adaptive.start" ); file << printTimeout(options, "pf_set_adaptive","pf_adaptive_end", "adaptive.end"); // check if any interface is marked as 'unprotected' // and generate 'set skip on ' commands if (fw->getStr("version")=="ge_3.7" || // fw->getStr("version")=="4.x") XMLTools::version_compare(fw->getStr("version"), "4.0")>=0) { for (list::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if ( iface->isUnprotected()) file << "set skip on " << iface->getName() << endl; } } file << endl; if (prolog_place == "pf_file_after_set") printProlog(file, pre_hook); QStringList scrub_options; string scrub_rule_direction = "in "; if (options->getBool("pf_do_scrub")) { if (XMLTools::version_compare(fw->getStr("version"), "4.6")<0) { if (options->getBool("pf_scrub_reassemble")) scrub_options << "fragment reassemble"; if (options->getBool("pf_scrub_fragm_crop")) scrub_options << "fragment crop"; if (options->getBool("pf_scrub_fragm_drop_ovl")) scrub_options << "fragment drop-ovl"; } if (options->getBool("pf_scrub_reassemble_tcp")) { // "scrub all reassemble tcp" - does not allow direction scrub_options << "reassemble tcp"; scrub_rule_direction = ""; } } if (options->getBool("pf_scrub_no_df")) scrub_options << "no-df "; if (!scrub_options.empty()) { file << "#" << endl; file << "# Scrub rules" << endl; file << "#" << endl; if (XMLTools::version_compare(fw->getStr("version"), "4.6")>=0) { file << "match " << scrub_rule_direction << "all scrub (" << scrub_options.join(" ").toStdString() << ")" << endl; } else { file << "scrub " << scrub_rule_direction << "all " << scrub_options.join(" ").toStdString() << endl; } } scrub_options.clear(); if (options->getBool("pf_scrub_random_id")) scrub_options << "random-id"; if (options->getBool("pf_scrub_use_minttl")) scrub_options << "min-ttl " << options->getStr("pf_scrub_minttl").c_str(); if (options->getBool("pf_scrub_use_maxmss")) scrub_options << "max-mss " << options->getStr("pf_scrub_maxmss").c_str(); if (!scrub_options.empty()) { if (XMLTools::version_compare(fw->getStr("version"), "4.6")>=0) { file << "match out all scrub (" << scrub_options.join(" ").toStdString() << ")" << endl; } else { file << "scrub out all " << scrub_options.join(" ").toStdString() << endl; } } file << endl; if (prolog_place == "pf_file_after_scrub") printProlog(file, pre_hook); //file << table_factory->PrintTables(); //file << endl; //if (prolog_place == "pf_file_after_tables") // printProlog(file, pre_hook); } void CompilerDriver_pf::setToolPathVar(Firewall* fw, const string &os, const string &var_path_suffix, OSData::tools osdata_tool_type, Configlet *configlet) { OSData os_data; FWOptions* options = fw->getOptionsObject(); string s; string path; s = options->getStr(os + "_" + var_path_suffix); if (!s.empty()) path = s; else path = os_data.getPathForTool(os, osdata_tool_type); configlet->setVariable(var_path_suffix.c_str(), path.c_str()); } QString CompilerDriver_pf::printPathForAllTools(Firewall* fw, const string &os) { Configlet tools = Configlet(fw, "bsd", "tools"); tools.removeComments(); setToolPathVar(fw, os, "path_ifconfig", OSData::IFCONFIG, &tools); setToolPathVar(fw, os, "path_ipf", OSData::IPF, &tools); setToolPathVar(fw, os, "path_ipnat", OSData::IPNAT, &tools); setToolPathVar(fw, os, "path_ipfw", OSData::IPFW, &tools); setToolPathVar(fw, os, "path_pfctl", OSData::PFCTL, &tools); setToolPathVar(fw, os, "path_sysctl", OSData::SYSCTL, &tools); setToolPathVar(fw, os, "path_logger", OSData::LOGGER, &tools); return tools.expand(); } fwbuilder-5.1.0.3599/src/pflib/NATCompiler_ipf.h0000644000175000017500000001367211733011756022016 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NATCOMPILER_IPF_HH #define __NATCOMPILER_IPF_HH #include #include "NATCompiler_pf.h" #include #define FTP_PORT 21 #define RCMD_PORT 514 #define KRCMD_PORT 544 #define EKSHELL_PORT 2106 #define H323_PORT 1720 #define RAUDIO_PORT 5050 #define ISAKMP_PORT 500 #define PPTP_PORT 1723 #define IRC_PORT 6667 namespace fwcompiler { class NATCompiler_ipf : public NATCompiler_pf { protected: virtual std::string myPlatformName(); /** * verifies correctness of the NAT rules (some checks are the * same as in pf, some are specific for ipf) */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules); /** * splits NAT rules if user ordered using * application proxy * code for "map" rules */ DECLARE_NAT_RULE_PROCESSOR(appProxy); /** * splits rules with service 'any' because they need "proxy * tcp/udp auto" */ DECLARE_NAT_RULE_PROCESSOR(expandAnyService); /** * ipf nat and rdr rules do not support port tanges; need to * generate a separate rule for each port of the range. */ DECLARE_NAT_RULE_PROCESSOR(ExpandPortRange); /** * LB-type rules allow no more than two destination hosts on * the right side of '->'. This processor splits NAT rule if * necessary to satisfy this rule */ DECLARE_NAT_RULE_PROCESSOR(prepareForLB); /** * assigns NAT rules to interfaces */ DECLARE_NAT_RULE_PROCESSOR(AssignInterface); /** * replaces object in tdst with reference to firewall's * interface in 'Redirect' rules */ DECLARE_NAT_RULE_PROCESSOR(RedirectRules); friend class fwcompiler::NATCompiler_ipf::RedirectRules; /** * eliminates duplicate objects in SRC. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRC : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRC(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInODST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInODST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRV : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRV(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrv::TYPENAME) {} }; /** * Placeholder for MultiAddressRunTime objects that are not * supported for ipf */ class processMultiAddressObjectsInRE : public NATRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : NATRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInOSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInOSrc(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; class processMultiAddressObjectsInODst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInODst(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. Negation * should also have been taken care of before this method is * called. */ class PrintRule : public NATCompiler_pf::PrintRule { protected: virtual void _printProtocol(libfwbuilder::Service *srv); virtual void _printAddr_L(libfwbuilder::Address *o, bool print_netmask=true); virtual void _printAddr_R(libfwbuilder::Address *o, bool print_netmask=true); virtual void _printAddr_R_LB(libfwbuilder::RuleElementTDst *re); virtual void _printPort(libfwbuilder::Service *srv,bool eq); public: PrintRule(const std::string &name); virtual bool processNext(); }; public: NATCompiler_ipf(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : NATCompiler_pf(_db, fw, ipv6_policy, _oscnf) {} virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_openbsd.cpp0000644000175000017500000000407411733011756024010 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "OSConfigurator_openbsd.h" #include "Configlet.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "Configlet.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_openbsd::myPlatformName() { return "OpenBSD"; } string OSConfigurator_openbsd::printKernelVarsCommands() { Configlet kernel_vars(fw, "bsd", "kernel_vars"); kernel_vars.removeComments(); setKernelVariable(fw, "openbsd_ip_directed_broadcast", &kernel_vars); setKernelVariable(fw, "openbsd_ip_forward", &kernel_vars); setKernelVariable(fw, "openbsd_ipv6_forward", &kernel_vars); setKernelVariable(fw, "openbsd_ip_sourceroute", &kernel_vars); setKernelVariable(fw, "openbsd_ip_redirect", &kernel_vars); return kernel_vars.expand().toStdString(); } int OSConfigurator_openbsd::prolog() { //printPathForAllTools("openbsd"); //printFunctions(); //processFirewallOptions(); //configureInterfaces(); return 0; } fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_ipfw_run.cpp0000644000175000017500000002760011733011756024231 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "CompilerDriver_ipfw.h" #include "PolicyCompiler_ipfw.h" #include "AutomaticRules_pf.h" #include "OSConfigurator_freebsd.h" #include "OSConfigurator_macosx.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; QString CompilerDriver_ipfw::assembleManifest(Cluster*, Firewall* , bool ) { QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); script << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]); if (!remote_file_names[FW_FILE].isEmpty()) script << " " << this->escapeFileName(remote_file_names[FW_FILE]); script << "\n"; script << "#" << endl; script << "#" << endl; return script_buffer; } QString CompilerDriver_ipfw::printActivationCommands(Firewall*) { return activation_commands.join("\n"); } QString CompilerDriver_ipfw::assembleFwScript(Cluster *cluster, Firewall* fw, bool cluster_member, OSConfigurator *oscnf) { Configlet script_skeleton(fw, "ipfw", "script_skeleton"); Configlet top_comment(fw, "ipfw", "top_comment"); assembleFwScriptInternal( cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "#", true); return script_skeleton.expand(); } QString CompilerDriver_ipfw::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); FWOptions* options = fw->getOptionsObject(); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); string s; string firewall_dir=options->getStr("firewall_dir"); if (firewall_dir=="") firewall_dir="/etc/fw"; bool debug=options->getBool("debug"); string shell_dbg=(debug)?"-x":"" ; /* * Process firewall options, build OS network configuration script */ std::auto_ptr oscnf; string host_os = fw->getStr("host_OS"); string family = Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); if ( host_os == "macosx") oscnf = std::auto_ptr(new OSConfigurator_macosx(objdb , fw, false)); if ( host_os == "freebsd") oscnf = std::auto_ptr(new OSConfigurator_freebsd(objdb , fw, false)); if (oscnf.get()==NULL) { abort("Unrecognized host OS " + host_os + " (family " + family + ")"); return ""; } oscnf->prolog(); list all_policies = fw->getByType(Policy::TYPENAME); vector ipv4_6_runs; string generated_script; int policy_rules_count = 0; int ipfw_rule_number = 0; findImportedRuleSets(fw, all_policies); try { AutomaticRules_pf auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); auto_rules.addCarpRules(); auto_rules.addPfsyncRules(); auto_rules.addFallbackRule(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() // NB: these ids are not used by this compiler assignUniqueRuleIds(all_policies); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); /* We need to create and run preprocessor for this address family before nat and policy compilers, but if there are no nat / policy rules for this address family, we do not need preprocessor either. */ // Count rules for each address family int policy_count = 0; for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (policy_count) { std::auto_ptr prep(new Preprocessor(objdb , fw, ipv6_policy)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); } ostringstream c_str; bool empty_output = true; for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); string branch_name = policy->getName(); if (!policy->matchingAddressFamily(policy_af)) continue; PolicyCompiler_ipfw c(objdb, fw, ipv6_policy, oscnf.get()); c.setIPFWNumber(ipfw_rule_number); c.setSourceRuleSet( policy ); c.setRuleSetName(branch_name); c.setPersistentObjects(persistent_objects); c.setSingleRuleCompileMode(single_rule_id); c.setDebugLevel( dl ); if (rule_debug_on) c.setDebugRule( drp ); c.setVerbose( (bool)(verbose) ); if (inTestMode()) c.setTestMode(); if (inEmbeddedMode()) c.setEmbeddedMode(); if ( (policy_rules_count=c.prolog()) > 0 ) { c.compile(); c.epilog(); ipfw_rule_number = c.getIPFWNumber(); if (c.getCompiledScriptLength() > 0) { if (!single_rule_compile_on) c_str << "# ================ Rule set " << branch_name << endl; c_str << c.getCompiledScript(); c_str << endl; empty_output = false; } if (c.haveErrorsAndWarnings()) { all_errors.push_back(c.getErrors("").c_str()); } } } if (!empty_output && !single_rule_compile_on) { if (ipv6_policy) { generated_script += "\n\n"; generated_script += "# ================ IPv6\n"; generated_script += "\n\n"; } else { generated_script += "\n\n"; generated_script += "# ================ IPv4\n"; generated_script += "\n\n"; } } generated_script += c_str.str(); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8(generated_script.c_str())); } PolicyCompiler_ipfw c(objdb, fw, false, oscnf.get()); activation_commands.push_back(c.defaultRules().c_str()); activation_commands.push_back( QString::fromUtf8(generated_script.c_str())); /* * assemble the script and then perhaps post-process it if needed */ determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("script_name_on_firewall")); QString script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString output_file = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + output_file.toStdString()); QFile fw_file(output_file); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_ipf.h0000644000175000017500000000522111733011756022616 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_IPF_HH__ #define __COMPILER_DRIVER_IPF_HH__ #include "CompilerDriver_pf.h" #include "TableFactory.h" #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; }; namespace fwcompiler { class CompilerDriver_ipf : public CompilerDriver_pf { QStringList activation_commands; QString composeActivationCommand(libfwbuilder::Firewall *fw, bool filter, const std::string &debug, const std::string &version, const std::string &remote_file_name); protected: QString printActivationCommandWithSubstitution(libfwbuilder::Firewall *fw); virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); virtual QString printActivationCommands(libfwbuilder::Firewall *fw); virtual QString assembleFwScript(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf); public: CompilerDriver_ipf(libfwbuilder::FWObjectDatabase *db); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/OSData.h0000644000175000017500000000220511733011756020144 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OSDATA_HH #define __OSDATA_HH #include "config.h" #include #include class OSData { public: OSData(); typedef enum { IFCONFIG, SYSCTL, PFCTL, IPFW, IPF, IPNAT, LOGGER } tools; std::string getPathForTool(const std::string &os,tools t); }; #endif fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_openbsd.h0000644000175000017500000000274611733011756023461 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002,2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCONFIGURATOR_OPENBSD_HH #define _OSCONFIGURATOR_OPENBSD_HH #include "config.h" #include "OSConfigurator_bsd.h" #include "OSData.h" namespace fwcompiler { class OSConfigurator_openbsd : public OSConfigurator_bsd { public: virtual ~OSConfigurator_openbsd() {}; OSConfigurator_openbsd(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator_bsd(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual std::string printKernelVarsCommands(); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipfw_writers.cpp0000644000175000017500000004407211733011756025132 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "definitions.h" #include "PolicyCompiler_ipfw.h" #include "OSData.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObjectDatabase.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ void PolicyCompiler_ipfw::PrintRule::_printProtocol(Service *srv) { if ( srv->isAny() || srv->getProtocolName()=="ip") { compiler->output << "all "; return; } if ( CustomService::isA(srv) ) { // CustomService returns protocol name starting with v3.0.4 // However CustomService can return protocol name "any", which // we should just skip. Also, in ipfw option "established" is // only defined for tcp, so we should set protocol to "tcp" if // custom service inserts this option. string pn = srv->getProtocolName(); if (pn != "any") compiler->output << pn << " "; else { string cscode = CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ); if (cscode=="established") compiler->output << "tcp "; // custom service does not define protocol - do not add any. } return; } compiler->output << srv->getProtocolName(); compiler->output << " "; } string PolicyCompiler_ipfw::PrintRule::_printPort(int rs,int re,bool ) { ostringstream str; if (rs<0) rs=0; if (re<0) re=0; if (rs>0 || re>0) { if (rs==re) str << rs; else str << rs << "-" << re; } return str.str(); } string PolicyCompiler_ipfw::PrintRule::_printTCPFlags(TCPService *srv) { string str; if (srv->getEstablished()) str = "established"; else { if (srv->inspectFlags()) { if (srv->getTCPFlagMask(TCPService::FIN)) { if (!srv->getTCPFlag(TCPService::FIN)) str+="!"; str+="fin"; } if (srv->getTCPFlagMask(TCPService::SYN)) { str+=","; if (!srv->getTCPFlag(TCPService::SYN)) str+="!"; str+="syn"; } if (srv->getTCPFlagMask(TCPService::RST)) { str+=","; if (!srv->getTCPFlag(TCPService::RST)) str+="!"; str+="rst"; } if (srv->getTCPFlagMask(TCPService::PSH)) { str+=","; if (!srv->getTCPFlag(TCPService::PSH)) str+="!"; str+="psh"; } if (srv->getTCPFlagMask(TCPService::ACK)) { str+=","; if (!srv->getTCPFlag(TCPService::ACK)) str+="!"; str+="ack"; } if (srv->getTCPFlagMask(TCPService::URG)) { str+=","; if (!srv->getTCPFlag(TCPService::URG)) str+="!"; str+="urg"; } if (!str.empty()) return "tcpflags " + str; } } return str; } void PolicyCompiler_ipfw::PrintRule::_printAction(PolicyRule *rule) { FWOptions *ruleopt = rule->getOptionsObject(); Service *srv = compiler->getFirstSrv(rule); assert(srv); if (rule->getClassification()) { int portNum = ruleopt->getInt("ipfw_pipe_queue_num"); switch (ruleopt->getInt("ipfw_classify_method")) { case DUMMYNETPIPE: compiler->output << "pipe " << portNum << " "; return; case DUMMYNETQUEUE: compiler->output << "queue " << portNum << " "; return; default: compiler->output << "divert " << portNum << " "; return; } } switch (rule->getAction()) { case PolicyRule::Skip: compiler->output << "skipto " << rule->getInt("skip_to") << " "; break; case PolicyRule::Accounting: compiler->output << "count "; break; case PolicyRule::Accept: compiler->output << "permit "; break; case PolicyRule::Deny: compiler->output << "drop "; break; case PolicyRule::Reject: if (TCPService::isA(srv)) compiler->output << "reset "; else { string aor=ruleopt->getStr("action_on_reject"); if (aor.empty()) aor=compiler->getCachedFwOpt()->getStr("action_on_reject"); string code; if ( aor.find("ICMP")!=string::npos ) { code=""; if (aor.find("unreachable")!=string::npos ) { if (aor.find("net")!=string::npos) code="net "; if (aor.find("host")!=string::npos) code="host "; if (aor.find("protocol")!=string::npos) code="protocol "; if (aor.find("port")!=string::npos) code="port "; } if (aor.find("prohibited")!=string::npos ) { if (aor.find("net")!=string::npos) code="net-prohib "; if (aor.find("host")!=string::npos) code="host-prohib "; } } else code="host-prohib "; compiler->output << "unreach " << code; } break; case PolicyRule::Pipe: compiler->output << "divert " << ruleopt->getInt("ipfw_pipe_port_num") << " "; break; case PolicyRule::Custom: compiler->output << ruleopt->getStr("custom_str") << " "; break; default: compiler->abort( rule, string("Unknown action ") + rule->getActionAsString()); // compiler->output << rule->getActionAsString() << " "; } } /* * this is almost like the one in PolicyCompiler_pf, except it does * not print interface name for dynamic interface ('cause ipfilter * does not support it) */ void PolicyCompiler_ipfw::PrintRule::_printAddr(FWObject *o, bool neg) { if (o->getId()==compiler->fw->getId()) { compiler->output << "me "; return; } Address *addr_obj = Address::cast(o); assert(addr_obj!=NULL); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } // at this time we only support two types of MultiAddress // objects: AddressTable and DNSName. Both should be converted // to MultiAddressRunTime at this point. If we get some other // kind of MultiAddressRunTime object, we do not know what to do // with it so we stop. assert(atrt==NULL); } const InetAddr *addr = addr_obj->getAddressPtr(); if (Interface::cast(o)!=NULL && addr==NULL) { compiler->output << "me "; } if (addr) { InetAddr mask = *(addr_obj->getNetmaskPtr()); if (Interface::cast(o)!=NULL) mask = InetAddr(InetAddr::getAllOnes()); if (addr_obj->dimension()==1) mask = InetAddr(InetAddr::getAllOnes()); if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { if (neg) compiler->output << "not "; compiler->output << addr->toString(); if (!mask.isHostMask()) { compiler->output << "/" << mask.getLength(); } compiler->output << " "; } } } void PolicyCompiler_ipfw::PrintRule::_printDirection(libfwbuilder::PolicyRule *r) { switch (r->getDirection()) { case PolicyRule::Outbound: compiler->output << "out "; break; case PolicyRule::Inbound: compiler->output << "in "; break; case PolicyRule::Both: compiler->output << " "; break; default: break; } } void PolicyCompiler_ipfw::PrintRule::_printOppositeDirection(PolicyRule *r) { switch (r->getDirection()) { case PolicyRule::Outbound: compiler->output << "in "; break; case PolicyRule::Inbound: compiler->output << "out "; break; case PolicyRule::Both: compiler->output << " "; break; default: break; } } void PolicyCompiler_ipfw::PrintRule::_printInterface(PolicyRule *r) { Interface *intf = compiler->getFirstItf(r); if (intf) { switch (r->getDirection()) { case PolicyRule::Outbound: compiler->output << "xmit "; break; case PolicyRule::Inbound: compiler->output << "recv "; break; case PolicyRule::Both: compiler->output << "via "; break; default: break; } compiler->output << intf->getName() << " "; } } void PolicyCompiler_ipfw::PrintRule::_printSrcService(RuleElement *rel) { /* I do not want to use rel->getFirst because it traverses the tree to * find the object. I'd rather use a cached copy in the compiler */ FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s1= Service::cast(o); bool tcpudp= (UDPService::isA(s1) || TCPService::isA(s1)); bool first=true; for (list::iterator i1=rel->begin(); i1!=rel->end(); ++i1) { FWObject *o = *i1; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv=Service::cast(o); if (tcpudp) { string str=_printSrcService( srv , false ); if (! str.empty() ) { if (!first) compiler->output << ","; compiler->output << str; } } } } string PolicyCompiler_ipfw::PrintRule::_printSrcService(Service *srv,bool neg) { string res; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getSrcRangeStart(); int re=TCPUDPService::cast(srv)->getSrcRangeEnd(); string s1= _printPort(rs,re,neg); if (!s1.empty()) res= s1; } return res; } void PolicyCompiler_ipfw::PrintRule::_printDstService(RuleElement *rel) { FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s1= Service::cast(o); bool tcpudp= (UDPService::isA(s1) || TCPService::isA(s1)); bool icmp = ICMPService::isA(s1); bool custom= CustomService::isA(s1); if (icmp) compiler->output << "icmptypes "; bool first=true; for (list::iterator i1=rel->begin(); i1!=rel->end(); ++i1) { FWObject *o = *i1; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv=Service::cast(o); if (tcpudp || custom) { string str=_printDstService( srv , false ); if (! str.empty() ) { if (!first) compiler->output << ","; compiler->output << str; } } if (icmp) { if (!first) compiler->output << ","; compiler->output << srv->getStr("type"); } first=false; } compiler->output << " "; /* * TCP services with flags were separated in rule processor * separateTCPWithFlags. We can count on objects like that being a * single object in the SRV. */ if (TCPService::isA(s1)) { string str=_printTCPFlags(TCPService::cast(s1)); if (!str.empty()) compiler->output << str << " "; } const IPService *ip_srv = IPService::constcast(s1); if (ip_srv) { Rule *rule = Rule::cast(rel->getParent()); if ((ip_srv->getBool("fragm") || ip_srv->getBool("short_fragm")) ) compiler->output << " frag "; if (ip_srv->hasIpOptions()) { QStringList options; if (ip_srv->getBool("any_opt")) compiler->warning(rule, "ipfw can not match \"any IP option\" "); else { const char *option_names[] = {"lsrr", "ssrr", "rr", "ts", NULL}; for (const char* *cptr=option_names; *cptr; cptr++) if (ip_srv->getBool(*cptr)) options.push_back(*cptr); } if (!options.empty()) compiler->output << " ipoptions " << options.join(",").toStdString() << " "; } } } string PolicyCompiler_ipfw::PrintRule::_printDstService(Service *srv,bool neg) { string res; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getDstRangeStart(); int re=TCPUDPService::cast(srv)->getDstRangeEnd(); string s1=_printPort(rs,re,neg);; if (!s1.empty()) res= s1; } if (ICMPService::isA(srv) && srv->getInt("type")!=-1) { res= "icmptypes " + srv->getStr("type") + " "; } if (CustomService::isA(srv)) { res= CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ) + " "; } return res; } PolicyCompiler_ipfw::PrintRule::PrintRule(const std::string &name) : PolicyCompiler_pf::PrintRule(name) { } bool PolicyCompiler_ipfw::PrintRule::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); tmp_queue.push_back(rule); /* need to quote $IPFW because it may contain space, this happens on * Mac more often than anywhere else */ string quote = "\""; compiler->output << compiler->printComment(rule, current_rule_label, "#"); RuleElementSrc *srcrel=rule->getSrc(); Address *src =compiler->getFirstSrc(rule); assert(src); RuleElementDst *dstrel=rule->getDst(); Address *dst =compiler->getFirstDst(rule); assert(dst); RuleElementSrv *srvrel=rule->getSrv(); Service *srv =compiler->getFirstSrv(rule); assert(srv); if (rule->getBool("needs_established")) { /* * This flag means we need to automatically generate mirrored rule with * parameter "established" * * ipfw_num is assigned with a step of 10, so it is safe to substract 1 */ compiler->output << quote << "$IPFW" << quote << " add " << rule->getInt("ipfw_num")-1 << " set 1 "; _printAction(rule); if (rule->getLogging()) compiler->output << " log "; _printProtocol(srv); compiler->output << " from "; _printSrcAddr(dstrel); _printSrcService(dstrel); compiler->output << " to "; _printDstAddr(srcrel); _printDstService(dstrel); _printOppositeDirection(rule); _printInterface(rule); if ( ! ruleopt->getBool("stateless")) { TCPService *tcpsrv = TCPService::cast(srv); if ( tcpsrv!=NULL && !tcpsrv->inspectFlags() && !tcpsrv->getEstablished() ) compiler->output << "established "; compiler->output << "keep-state "; } compiler->output << endl; } compiler->output << quote << "$IPFW" << quote << " add " << rule->getInt("ipfw_num") << " set 1 "; _printAction(rule); if (rule->getLogging()) compiler->output << " log "; _printProtocol(srv); compiler->output << " from "; _printSrcAddr(srcrel); _printSrcService(srvrel); compiler->output << " to "; _printDstAddr(dstrel); _printDstService(srvrel); _printDirection(rule); _printInterface(rule); /* keeping state does not apply to deny/reject */ if ( ! ruleopt->getBool("stateless")) { /* * this is per advice from Darren Reed http://false.net/ipfilter/2002_12/0176.html * * Feature req. #653803: Implement flags for TCP keep state * * In ipfw the equivalend is * * setup TCP packets only. Match packets that have the SYN bit * set but no ACK bit. * */ TCPService *tcpsrv=TCPService::cast(srv); if ( tcpsrv!=NULL && !tcpsrv->inspectFlags() && !tcpsrv->getEstablished() ) compiler->output << "setup "; compiler->output << "keep-state "; } compiler->output << " || exit 1" << endl; //compiler->output << endl; return true; } string PolicyCompiler_ipfw::defaultRules() { FWOptions *options = fw->getOptionsObject(); string quote = "\""; ostringstream res; res << quote << "$IPFW" << quote << " set disable 1" << endl; /* checking if option add_check_state_rule is absent to * provide for backward compatibility: before 2.1.6 build 131 * this option did not exist and compiler alawys generated * check-state rule */ if (options->getStr("add_check_state_rule").empty() || options->getBool("add_check_state_rule")) { res << quote << "$IPFW" << quote << " add 1 set 1 check-state ip from any to any" << endl; } res << endl; return res.str(); } fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_solaris.cpp0000644000175000017500000000771411733011756024036 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "OSConfigurator_solaris.h" #include "Configlet.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_solaris::myPlatformName() { return "Solaris"; } string OSConfigurator_solaris::printKernelVarsCommands() { Configlet kernel_vars(fw, "bsd", "kernel_vars"); kernel_vars.removeComments(); setKernelVariable(fw, "solaris_ip_forward", &kernel_vars); setKernelVariable(fw, "solaris_ip_ignore_redirect", &kernel_vars); setKernelVariable(fw, "solaris_ip_respond_to_echo_broadcast", &kernel_vars); setKernelVariable(fw, "solaris_ip_forward_directed_broadcasts", &kernel_vars); setKernelVariable(fw, "solaris_ip_forward_src_routed", &kernel_vars); return kernel_vars.expand().toStdString(); } void OSConfigurator_solaris::addVirtualAddressForNAT(const Network*) { } void OSConfigurator_solaris::addVirtualAddressForNAT(const Address *addr) { if (virtual_addresses.empty() || find(virtual_addresses.begin(),virtual_addresses.end(), *(addr->getAddressPtr())) == virtual_addresses.end()) { FWObject *iaddr = findAddressFor(addr, fw ); if (iaddr!=NULL) { Address *iaddr_addr = Address::cast(iaddr); assert(iaddr_addr!=NULL); Interface *iface=Interface::cast(iaddr->getParent()); assert(iface!=NULL); output << "add_addr " << addr->getAddressPtr()->toString() << " " << iaddr_addr->getNetmaskPtr()->toString() << " " << iface->getName() << endl; virtual_addresses.push_back(*(addr->getAddressPtr())); } else warning("Can not add virtual address " + addr->getAddressPtr()->toString() ); } } int OSConfigurator_solaris::prolog() { //printPathForAllTools("solaris"); //processFirewallOptions(); //configureInterfaces(); return 0; } string OSConfigurator_solaris::configureInterfaces() { ostringstream ostr; FWOptions* options=fw->getOptionsObject(); if ( options->getBool("configure_interfaces") ) { ostr << endl; FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface=dynamic_cast(*i); assert(iface); if (!iface->isRegular()) continue; FWObjectTypedChildIterator j=iface->findByType(IPv4::TYPENAME); for ( ; j!=j.end(); ++j ) { Address *iaddr = Address::cast(*j); ostr << "add_addr " << iaddr->getAddressPtr()->toString() << " " << iaddr->getNetmaskPtr()->toString() << " " << iface->getName() << endl; virtual_addresses.push_back(*(iaddr->getAddressPtr())); } } ostr << endl; } return ostr.str(); } fwbuilder-5.1.0.3599/src/pflib/AutomaticRules_pf.h0000644000175000017500000000271411733011756022464 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __AUTOMATICRULES_PF_HH__ #define __AUTOMATICRULES_PF_HH__ #include "AutomaticRules.h" namespace libfwbuilder { class Address; class Firewall; class Interface; class Service; }; namespace fwcompiler { class AutomaticRules_pf : public AutomaticRules { public: AutomaticRules_pf(libfwbuilder::Firewall *fw, libfwbuilder::Library *presistent_objects) : AutomaticRules(fw, presistent_objects) {} void addSshAccessRule(); void addCarpRules(); void addPfsyncRules(); void addFallbackRule(); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_pf_run.cpp0000644000175000017500000007266511733011756023704 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "Configlet.h" #include "CompilerDriver_pf.h" #include "PolicyCompiler_pf.h" #include "NATCompiler_pf.h" #include "TableFactory.h" #include "Preprocessor_pf.h" #include "RoutingCompiler_openbsd.h" #include "RoutingCompiler_freebsd.h" #include "AutomaticRules_pf.h" #include "OSConfigurator_openbsd.h" #include "OSConfigurator_freebsd.h" #include "OSConfigurator_solaris.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" #include "fwcompiler/GroupRegistry.h" #include "fwcompiler/exceptions.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; // #define DEBUG_FILE_NAMES 1 QString CompilerDriver_pf::composeActivationCommand(Firewall *fw, const string &pfctl_debug, const string &anchor_name, const string &pf_version, const string &remote_file_name) { FWOptions* options = fw->getOptionsObject(); Configlet act(fw, "pf", options->getBool("generate_rc_conf_file") ? "rc_conf_activation" : "activation"); act.removeComments(); act.setVariable("pfctl_debug", pfctl_debug.c_str()); act.setVariable("anchor", !anchor_name.empty()); act.setVariable("anchor_name", anchor_name.c_str()); if (pf_version == "obsd_lt_3.2") { act.setVariable("pf_version_lt_3_2", 1); act.setVariable("pf_version_ge_3_2", 0); } else { act.setVariable("pf_version_lt_3_2", 0); act.setVariable("pf_version_ge_3_2", 1); } act.setVariable("remote_file", remote_file_name.c_str()); return act.expand(); } QString CompilerDriver_pf::printActivationCommands(Firewall *fw) { FWOptions* options = fw->getOptionsObject(); bool debug = options->getBool("debug"); string pfctl_dbg = (debug)?"-v ":""; QString remote_file_name = escapeFileName(remote_file_names[CONF1_FILE]); return composeActivationCommand( fw, pfctl_dbg, "", fw->getStr("version"), remote_file_name.toUtf8().constData()); #if 0 QStringList activation_commands; // skip first item in the list since it is .fw script for(int idx=1; idxgetStr("version"), remote_file_name.toUtf8().constData())); } return activation_commands.join("\n"); #endif } QString CompilerDriver_pf::assembleManifest(Cluster*, Firewall* , bool ) { QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); for(int idx=0; idxgetOptionsObject(); Configlet script_skeleton( fw, "pf", options->getBool("generate_rc_conf_file") ? "rc_conf_skeleton" : "script_skeleton"); Configlet top_comment(fw, "pf", options->getBool("generate_rc_conf_file") ? "rc_conf_top_comment" : "top_comment"); script_skeleton.setVariable("routing_script", QString::fromUtf8(routing_script.c_str())); assembleFwScriptInternal( cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "#", !options->getBool("generate_rc_conf_file")); if (fw->getStr("platform") == "pf") { script_skeleton.setVariable( "pf_flush_states", options->getBool("pf_flush_states")); script_skeleton.setVariable( "pf_version_ge_4_x", // fw->getStr("version")=="4.x"); XMLTools::version_compare(fw->getStr("version"), "4.0")>=0); } else { script_skeleton.setVariable("pf_flush_states", 0); script_skeleton.setVariable("pf_version_ge_4_x", 0); } return script_skeleton.expand(); } QString CompilerDriver_pf::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); FWOptions* options = fw->getOptionsObject(); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = QString::fromUtf8(fw->getName().c_str()); string firewall_dir = options->getStr("firewall_dir"); if (firewall_dir=="") firewall_dir="/etc/fw"; string prolog_place = options->getStr("prolog_place"); if (prolog_place.empty()) prolog_place = "fw_file"; // old default string pre_hook = fw->getOptionsObject()->getStr("prolog_script"); bool debug = options->getBool("debug"); string shell_dbg = (debug)?"set -x":"" ; string pfctl_dbg = (debug)?"-v ":""; /* * Process firewall options, build OS network configuration script */ std::auto_ptr oscnf; string platform = fw->getStr("platform"); string fw_version = fw->getStr("version"); string host_os = fw->getStr("host_OS"); string family = Resources::os_res[host_os]-> Resources::getResourceStr("/FWBuilderResources/Target/family"); if (host_os == "solaris") oscnf = std::auto_ptr(new OSConfigurator_solaris( objdb , fw, false)); if (host_os == "openbsd") oscnf = std::auto_ptr(new OSConfigurator_openbsd( objdb , fw, false)); if (host_os == "freebsd") oscnf = std::auto_ptr(new OSConfigurator_freebsd( objdb , fw, false)); if (oscnf.get()==NULL) { abort("Unrecognized host OS " + host_os + " (family " + family + ")"); return ""; } oscnf->prolog(); QString remote_fw_name = QString::fromUtf8( options->getStr("script_name_on_firewall").c_str()); QString remote_conf_name = QString::fromUtf8( options->getStr("conf_file_name_on_firewall").c_str()); list all_policies = fw->getByType(Policy::TYPENAME); list all_nat = fw->getByType(NAT::TYPENAME); findImportedRuleSets(fw, all_policies); findImportedRuleSets(fw, all_nat); try { AutomaticRules_pf auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); auto_rules.addCarpRules(); auto_rules.addPfsyncRules(); auto_rules.addFallbackRule(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() // NB: these ids are not really used by compiler for PF assignUniqueRuleIds(all_policies); assignUniqueRuleIds(all_nat); list all_rulesets; all_rulesets.insert( all_rulesets.begin(), all_policies.begin(), all_policies.end()); all_rulesets.insert( all_rulesets.begin(), all_nat.begin(), all_nat.end()); // establish mapping of rule sets to file names so it can be used // for "load anchor" commands QMap rulesets_to_file_names; QMap rulesets_to_remote_file_names; QMap rulesets_to_indexes; QStringList file_extensions; QStringList remote_file_options; anchor_names.clear(); anchor_names << ""; // for fw_file anchor_names << ""; // for main .conf file (both policy and nat top rule sets) // Can not make extension .conf when generating rc.conf file // because the second file also has extension .conf and this // causes conflict if both names are generated using default // algorithm from the fw name // file_extensions << "fw"; file_extensions << "conf"; remote_file_options << "script_name_on_firewall"; remote_file_options << "conf_file_name_on_firewall"; rulesets_to_indexes["__main__"] = CONF1_FILE; int idx = CONF2_FILE; for (list::iterator p=all_rulesets.begin(); p!=all_rulesets.end(); ++p) { RuleSet *rs = RuleSet::cast(*p); QString ruleset_name = QString::fromUtf8(rs->getName().c_str()); if (ruleset_name.endsWith("/*")) { QString err("The name of the %1 ruleset %2" " ends with '/*', assuming it is externally" " controlled and skipping it."); warning(fw, rs, NULL, err.arg(rs->getTypeName().c_str()) .arg(ruleset_name).toStdString()); rs->setBool(".skip_ruleset", true); continue; } if (rs->isTop()) continue; // record index of this ruleset in file_names and remote_file_names if (rulesets_to_indexes.count(ruleset_name) == 0) { anchor_names << ruleset_name; file_extensions << "conf"; remote_file_options << ""; // to make sure it has right number of items rulesets_to_indexes[ruleset_name] = idx; idx++; } } #ifdef DEBUG_FILE_NAMES qDebug() << "anchor_names=" << anchor_names; qDebug() << "file_extensions=" << file_extensions; qDebug() << "remote_file_options=" << remote_file_options; #endif // The order of file names in file_names and remote_file_names // is the same as the order of rule sets in all_rulesets determineOutputFileNames(cluster, fw, !cluster_id.empty(), anchor_names, file_extensions, remote_file_options); for (list::iterator p=all_rulesets.begin(); p!=all_rulesets.end(); ++p) { RuleSet *rs = RuleSet::cast(*p); if (rs->getBool(".skip_ruleset")) continue; QString ruleset_name = QString::fromUtf8(rs->getName().c_str()); if (rs->isTop()) ruleset_name = "__main__"; int idx = rulesets_to_indexes[ruleset_name]; rulesets_to_file_names[ruleset_name] = file_names[idx]; rulesets_to_remote_file_names[ruleset_name] = remote_file_names[idx]; } #ifdef DEBUG_FILE_NAMES qDebug() << "file_names=" << file_names; qDebug() << "remote_file_names=" << remote_file_names; qDebug() << "rulesets_to_file_names=" << rulesets_to_file_names; qDebug() << "rulesets_to_remote_file_names=" << rulesets_to_remote_file_names; #endif GroupRegistry group_registry; int routing_rules_count = 0; vector ipv4_6_runs; // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } ostringstream* main_str = new ostringstream(); list redirect_rules_info; for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int ruleset_address_family = *i; bool is_ipv6 = (ruleset_address_family == AF_INET6); Preprocessor_pf* prep = new Preprocessor_pf(objdb , fw, is_ipv6); prep->setSingleRuleCompileMode(single_rule_id); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); delete prep; } // ################################################################ // First I process NAT rules, both ipv4 and ipv6, then process // ipv4 and ipv6 policy rules. See SF bug 3428992 for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int ruleset_address_family = *i; bool is_ipv6 = (ruleset_address_family == AF_INET6); for (list::iterator p=all_nat.begin(); p!=all_nat.end(); ++p ) { NAT *nat = NAT::cast(*p); if (!nat->matchingAddressFamily(ruleset_address_family)) continue; if (nat->getBool(".skip_ruleset")) continue; QString ruleset_name = QString::fromUtf8(nat->getName().c_str()); if (nat->isTop()) ruleset_name = "__main__"; if (table_factories.count(ruleset_name) == 0) { table_factories[ruleset_name] = new fwcompiler::TableFactory(this, fw, persistent_objects, &group_registry); } NATCompiler_pf n( objdb, fw, is_ipv6, oscnf.get(), table_factories[ruleset_name] ); n.setSourceRuleSet( nat ); n.setRuleSetName(nat->getName()); n.setPersistentObjects(persistent_objects); n.setGroupRegistry(&group_registry); n.setSingleRuleCompileMode(single_rule_id); n.setDebugLevel( dl ); if (rule_debug_on) n.setDebugRule(drn); n.setVerbose( verbose ); if (inTestMode()) n.setTestMode(); if (inEmbeddedMode()) n.setEmbeddedMode(); int nat_rules_count = 0; if ( (nat_rules_count=n.prolog()) > 0 ) { n.compile(); n.epilog(); } have_nat = (have_nat || (nat_rules_count > 0)); if (nat->isTop()) { if (generated_scripts.count(ruleset_name) == 0) generated_scripts[ruleset_name] = main_str; } else { if (generated_scripts.count(ruleset_name) == 0) generated_scripts[ruleset_name] = new ostringstream(); } if (n.getCompiledScriptLength() > 0) { if (n.haveErrorsAndWarnings()) { // store errors and warnings so they will appear on top // of .fw file in addition to the .conf file if (!single_rule_compile_on) { *(generated_scripts[ruleset_name]) << "# NAT compiler errors and warnings:" << endl; *(generated_scripts[ruleset_name]) << n.getErrors("# "); } } *(generated_scripts[ruleset_name]) << n.getCompiledScript(); *(generated_scripts[ruleset_name]) << endl; } all_errors.push_back(n.getErrors("").c_str()); const list lst = n.getRedirRulesInfo(); redirect_rules_info.insert(redirect_rules_info.begin(), lst.begin(), lst.end()); } } // ################################################################ // Process policy rule sets for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int ruleset_address_family = *i; bool is_ipv6 = (ruleset_address_family == AF_INET6); for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(ruleset_address_family)) continue; if (policy->getBool(".skip_ruleset")) continue; QString ruleset_name = QString::fromUtf8(policy->getName().c_str()); if (policy->isTop()) ruleset_name = "__main__"; if (table_factories.count(ruleset_name) == 0) { table_factories[ruleset_name] = new fwcompiler::TableFactory(this, fw, persistent_objects, &group_registry); } PolicyCompiler_pf c( objdb, fw, is_ipv6, oscnf.get(), &redirect_rules_info, table_factories[ruleset_name] ); c.setSourceRuleSet( policy ); c.setRuleSetName(policy->getName()); c.setPersistentObjects(persistent_objects); c.setGroupRegistry(&group_registry); c.setSingleRuleCompileMode(single_rule_id); c.setDebugLevel( dl ); if (rule_debug_on) c.setDebugRule(drp); c.setVerbose( verbose ); if (inTestMode()) c.setTestMode(); if (inEmbeddedMode()) c.setEmbeddedMode(); int pf_rules_count = 0; if ( (pf_rules_count=c.prolog()) > 0 ) { c.compile(); c.epilog(); } have_filter = (have_filter || (pf_rules_count > 0)); if (policy->isTop()) { if (generated_scripts.count("__main__") == 0) generated_scripts["__main__"] = main_str; } else { if (generated_scripts.count(ruleset_name) == 0) generated_scripts[ruleset_name] = new ostringstream(); } if (c.getCompiledScriptLength() > 0) { if (c.haveErrorsAndWarnings()) { if (!single_rule_compile_on) { *(generated_scripts[ruleset_name]) << "# Policy compiler errors and warnings:" << endl; *(generated_scripts[ruleset_name]) << c.getErrors("# "); } } *(generated_scripts[ruleset_name]) << c.getCompiledScript(); *(generated_scripts[ruleset_name]) << endl; } all_errors.push_back(c.getErrors("").c_str()); } } std::auto_ptr routing_compiler; if (host_os == "openbsd") routing_compiler = std::auto_ptr( new RoutingCompiler_openbsd(objdb, fw, false, oscnf.get())); if (host_os == "freebsd") routing_compiler = std::auto_ptr( new RoutingCompiler_freebsd(objdb, fw, false, oscnf.get())); if (routing_compiler.get() == NULL) { abort("Unrecognized host OS " + host_os + " (family " + family + ")"); return ""; } RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); if (routing) { routing_compiler->setSourceRuleSet(routing); routing_compiler->setRuleSetName(routing->getName()); routing_compiler->setPersistentObjects(persistent_objects); routing_compiler->setSingleRuleCompileMode(single_rule_id); routing_compiler->setDebugLevel( dl ); if (rule_debug_on) routing_compiler->setDebugRule(drp); routing_compiler->setVerbose( verbose ); if (inTestMode()) routing_compiler->setTestMode(); if (inEmbeddedMode()) routing_compiler->setEmbeddedMode(); if ( (routing_rules_count=routing_compiler->prolog()) > 0 ) { routing_compiler->compile(); routing_compiler->epilog(); } if (routing_compiler->haveErrorsAndWarnings()) all_errors.push_back(routing_compiler->getErrors("").c_str()); routing_script += routing_compiler->getCompiledScript(); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } if (single_rule_compile_on) { // in single rule compile mode just return the result QString buffer; QTextStream pf_str(&buffer); for (map::iterator fi=generated_scripts.begin(); fi!=generated_scripts.end(); fi++) { QString ruleset_name = fi->first; ostringstream *strm = fi->second; pf_str << table_factories[ruleset_name]->PrintTables(); pf_str << QString::fromUtf8(strm->str().c_str()); pf_str << QString::fromUtf8(routing_script.c_str()); } // clear() calls destructors of all elements in the container table_factories.clear(); generated_scripts.clear(); return formSingleRuleCompileOutput(buffer); } /* add commands to load anchors to the bottom of the main .conf file */ QMap::iterator it; for (it=rulesets_to_remote_file_names.begin(); it!=rulesets_to_remote_file_names.end(); ++it) { QString ruleset_name = it.key(); if (ruleset_name == "__main__") continue; QString remote_file_name = it.value(); ostringstream *ostr = generated_scripts["__main__"]; // note that ostr can be NULL if the firewall we are // trying to compile has no top-level rule sets if (ostr == NULL) continue; *ostr << QString("load anchor %1 from \"%2\"") .arg(ruleset_name).arg(remote_file_name).toUtf8().constData() << endl; } /* * now write generated scripts to files */ idx = CONF1_FILE; for (map::iterator fi=generated_scripts.begin(); fi!=generated_scripts.end(); fi++) { QString ruleset_name = fi->first; QString file_name = rulesets_to_file_names[ruleset_name]; // file_names[idx]; ostringstream *strm = fi->second; if (strm==NULL) continue; if (ruleset_name.contains("/*")) continue; file_name = getAbsOutputFileName(file_name); info("Output file name: " + file_name.toStdString()); QFile pf_file(file_name); if (pf_file.open(QIODevice::WriteOnly)) { QTextStream pf_str(&pf_file); if (ruleset_name == "__main__") { printStaticOptions(pf_str, fw); // attach persistent_tables subtree inside TableFactory object // to the object tree table_factories[ruleset_name]->init(objdb); pf_str << table_factories[ruleset_name]->PrintTables(); if (prolog_place == "pf_file_after_tables") printProlog(pf_str, pre_hook); } else { pf_str << table_factories[ruleset_name]->PrintTables(); } pf_str << QString::fromUtf8(strm->str().c_str()); pf_file.close(); } else { // clear() calls destructors of all elements in the container table_factories.clear(); generated_scripts.clear(); QString err("Failed to open file %1 for writing: %2; " "Current dir: %3"); abort(err.arg(pf_file.fileName()) .arg(pf_file.error()) .arg(QDir::current().path()).toStdString()); } idx++; } /* * assemble the script and then perhaps post-process it if needed */ QString script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); // clear() calls destructors of all elements in the container table_factories.clear(); generated_scripts.clear(); file_names[FW_FILE] = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + file_names[FW_FILE].toStdString()); QFile fw_file(file_names[FW_FILE]); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } MapOstringStream::~MapOstringStream() { clear(); } void MapOstringStream::clear() { std::map::iterator it; for (it=begin(); it!=end(); ++it) delete it->second; std::map::clear(); } MapTableFactory::~MapTableFactory() { clear(); } void MapTableFactory::clear() { std::map::iterator it; for (it=begin(); it!=end(); ++it) delete it->second; std::map::clear(); } fwbuilder-5.1.0.3599/src/pflib/pflib.pro0000644000175000017500000000373311733011756020505 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib # SOURCES = TableFactory.cpp \ Preprocessor_pf.cpp \ NATCompiler_ipf.cpp \ NATCompiler_ipfw.cpp \ NATCompiler_ipf_writers.cpp \ NATCompiler_ipfw_writers.cpp \ NATCompiler_pf.cpp \ NATCompiler_pf_negation.cpp \ NATCompiler_pf_writers.cpp \ OSConfigurator_bsd.cpp \ OSConfigurator_bsd_interfaces.cpp \ OSConfigurator_freebsd.cpp \ OSConfigurator_macosx.cpp \ OSConfigurator_openbsd.cpp \ OSConfigurator_solaris.cpp \ OSData.cpp \ PolicyCompiler_ipf.cpp \ PolicyCompiler_ipf_optimizer.cpp \ PolicyCompiler_ipfw.cpp \ PolicyCompiler_ipf_writers.cpp \ PolicyCompiler_ipfw_writers.cpp \ PolicyCompiler_pf.cpp \ PolicyCompiler_pf_writers.cpp \ CompilerDriver_pf.cpp \ CompilerDriver_pf_run.cpp \ CompilerDriver_ipf.cpp \ CompilerDriver_ipf_run.cpp \ CompilerDriver_ipfw.cpp \ CompilerDriver_ipfw_run.cpp \ RoutingCompiler_openbsd.cpp \ RoutingCompiler_openbsd_writers.cpp \ RoutingCompiler_freebsd.cpp \ RoutingCompiler_freebsd_writers.cpp \ AutomaticRules_pf.cpp HEADERS = ../../config.h \ OSData.h \ TableFactory.h \ Preprocessor_pf.h \ NATCompiler_ipf.h \ NATCompiler_ipfw.h \ NATCompiler_pf.h \ OSConfigurator_bsd.h \ OSConfigurator_freebsd.h \ OSConfigurator_macosx.h \ OSConfigurator_openbsd.h \ OSConfigurator_solaris.h \ PolicyCompiler_ipf.h \ PolicyCompiler_ipfw.h \ PolicyCompiler_pf.h \ CompilerDriver_pf.h \ CompilerDriver_ipf.h \ CompilerDriver_ipfw.h \ RoutingCompiler_openbsd.h \ RoutingCompiler_freebsd.h \ AutomaticRules_pf.h macx:LIBS += $$LIBS_FWCOMPILER INCLUDEPATH += ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../compiler_lib ../libfwbuilder/src win32:PRE_TARGETDEPS = ../compiler_lib/release/libcompilerdriver.a !win32:PRE_TARGETDEPS = ../compiler_lib/libcompilerdriver.a CONFIG += staticlib TARGET = fwbpf INSTALLS -= target fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_ipf_run.cpp0000644000175000017500000003521411733011756024042 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "CompilerDriver_ipf.h" #include "PolicyCompiler_ipf.h" #include "NATCompiler_ipf.h" #include "AutomaticRules_pf.h" #include "OSConfigurator_openbsd.h" #include "OSConfigurator_freebsd.h" #include "OSConfigurator_solaris.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; QString CompilerDriver_ipf::composeActivationCommand(libfwbuilder::Firewall *fw, bool filter, const std::string &debug, const std::string &, const std::string &remote_file) { Configlet act(fw, "ipf", "activation"); act.removeComments(); act.collapseEmptyStrings(true); act.setVariable("dyn_addr", fw->getOptionsObject()->getBool("dynAddr")); act.setVariable("not_dyn_addr", !fw->getOptionsObject()->getBool("dynAddr")); act.setVariable("filter", filter); act.setVariable("nat", !filter); act.setVariable("ipf_debug", debug.c_str()); act.setVariable("remote_file", remote_file.c_str()); act.setVariable("interface_name_substitution_commands", printActivationCommandWithSubstitution(fw)); return act.expand(); } QString CompilerDriver_ipf::assembleManifest(Cluster*, Firewall* fw, bool ) { QString remote_name = remote_file_names[FW_FILE]; QString remote_ipf_name = remote_file_names[CONF1_FILE]; QString remote_nat_name = remote_file_names[CONF2_FILE]; QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); script << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]); if (remote_name != file_names[FW_FILE]) script << " " << this->escapeFileName(remote_name); script << endl; if (have_filter) { script << MANIFEST_MARKER << " " << this->escapeFileName(file_names[CONF1_FILE]); if (remote_ipf_name != file_names[CONF1_FILE]) script << " " << this->escapeFileName(remote_ipf_name); script << endl; } if (have_nat) { script << MANIFEST_MARKER << " " << this->escapeFileName(file_names[CONF2_FILE]); if (remote_nat_name != file_names[CONF2_FILE]) script << " " << this->escapeFileName(remote_nat_name); script << endl; } return script_buffer; } QString CompilerDriver_ipf::assembleFwScript(Cluster *cluster, Firewall* fw, bool cluster_member, OSConfigurator *oscnf) { Configlet script_skeleton(fw, "ipf", "script_skeleton"); Configlet top_comment(fw, "ipf", "top_comment"); assembleFwScriptInternal( cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "#", true); return script_skeleton.expand(); } QString CompilerDriver_ipf::printActivationCommands(libfwbuilder::Firewall*) { return activation_commands.join("\n"); } QString CompilerDriver_ipf::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); FWOptions* options = fw->getOptionsObject(); string fw_version = fw->getStr("version"); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); string s; bool debug = options->getBool("debug"); string ipf_dbg = (debug)?"-v":""; std::auto_ptr prep(new Preprocessor(objdb , fw, false)); prep->compile(); /* * Process firewall options, build OS network configuration script */ std::auto_ptr oscnf; string host_os = fw->getStr("host_OS"); string family=Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); if ( host_os == "solaris" ) oscnf = std::auto_ptr(new OSConfigurator_solaris(objdb , fw, false)); if ( host_os == "openbsd") oscnf = std::auto_ptr(new OSConfigurator_openbsd(objdb , fw, false)); if ( host_os == "freebsd") oscnf = std::auto_ptr(new OSConfigurator_freebsd(objdb , fw, false)); if (oscnf.get()==NULL) { abort("Unrecognized host OS " + host_os + " (family " + family + ")"); return ""; } oscnf->prolog(); list all_policies = fw->getByType(Policy::TYPENAME); list all_nat = fw->getByType(NAT::TYPENAME); try { AutomaticRules_pf auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); auto_rules.addCarpRules(); auto_rules.addPfsyncRules(); auto_rules.addFallbackRule(); } catch (FWException &ex) { abort(ex.toString()); } PolicyCompiler_ipf c(objdb , fw, false , oscnf.get() ); FWObject *policy = all_policies.front(); c.setSourceRuleSet(Policy::cast(policy)); c.setRuleSetName(policy->getName()); c.setPersistentObjects(persistent_objects); c.setSingleRuleCompileMode(single_rule_id); c.setDebugLevel( dl ); if (rule_debug_on) c.setDebugRule( drp ); c.setVerbose( verbose ); if (inTestMode()) c.setTestMode(); if (inEmbeddedMode()) c.setEmbeddedMode(); if ( c.prolog() > 0 ) { have_filter = true; c.compile(); c.epilog(); } NATCompiler_ipf n( objdb , fw, false , oscnf.get() ); FWObject *nat = all_nat.front(); n.setSourceRuleSet(NAT::cast(nat)); n.setRuleSetName(nat->getName()); n.setPersistentObjects(persistent_objects); n.setSingleRuleCompileMode(single_rule_id); n.setDebugLevel( dl ); if (rule_debug_on) n.setDebugRule( drn ); n.setVerbose( verbose ); if (inTestMode()) n.setTestMode(); if (inEmbeddedMode()) n.setEmbeddedMode(); if ( n.prolog() > 0 ) { have_nat = true; n.compile(); n.epilog(); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } if (single_rule_compile_on) { // in single rule compile mode just return the result ostringstream ostr; if (have_filter) { if (c.haveErrorsAndWarnings()) { all_errors.push_back(c.getErrors("").c_str()); } ostr << c.getCompiledScript(); } if (have_nat) { if (n.haveErrorsAndWarnings()) { all_errors.push_back(n.getErrors("").c_str()); } ostr << n.getCompiledScript(); } return formSingleRuleCompileOutput( QString::fromUtf8(ostr.str().c_str())); } determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList() << "" << "ipf" << "nat", QStringList() << "fw" << "conf" << "conf", QStringList() << "script_name_on_firewall" << "ipf_conf_file_name_on_firewall" << "nat_conf_file_name_on_firewall"); QString remote_ipf_name = remote_file_names[CONF1_FILE]; QString remote_nat_name = remote_file_names[CONF2_FILE]; if (have_filter) { QString output_file = getAbsOutputFileName(file_names[CONF1_FILE]); info("Output file name: " + output_file.toStdString()); QFile ipf_file(output_file); if (ipf_file.open(QIODevice::WriteOnly)) { QTextStream ipf_str(&ipf_file); if (c.haveErrorsAndWarnings()) { all_errors.push_back(c.getErrors("").c_str()); ipf_str << "# Policy compiler errors and warnings:" << endl; ipf_str << QString::fromUtf8(c.getErrors("# ").c_str()); } ipf_str << QString::fromUtf8(c.getCompiledScript().c_str()); ipf_file.close(); ipf_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); } else { QString err(" Failed to open file %1 for writing: %2; " "Current dir: %3"); abort(err.arg(ipf_file.fileName()) .arg(ipf_file.error()) .arg(QDir::current().path()).toStdString()); } QString remote_file_name = escapeFileName(remote_ipf_name); activation_commands.push_back( composeActivationCommand( fw, true, ipf_dbg, fw_version, remote_file_name.toUtf8().constData())); } if (have_nat) { QString output_file = getAbsOutputFileName(file_names[CONF2_FILE]); info("Output file name: " + output_file.toStdString()); QFile nat_file(output_file); if (nat_file.open(QIODevice::WriteOnly)) { QTextStream nat_str(&nat_file); if (n.haveErrorsAndWarnings()) { all_errors.push_back(n.getErrors("").c_str()); nat_str << "# NAT compiler errors and warnings:" << endl; nat_str << QString::fromUtf8(n.getErrors("# ").c_str()); } nat_str << QString::fromUtf8(n.getCompiledScript().c_str()); nat_file.close(); nat_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); } else { QString err(" Failed to open file %1 for writing: %2; " "Current dir: %3"); abort(err.arg(nat_file.fileName()) .arg(nat_file.error()) .arg(QDir::current().path()).toStdString()); } QString remote_file_name = escapeFileName(remote_nat_name); activation_commands.push_back( composeActivationCommand( fw, false, ipf_dbg, fw_version, remote_file_name.toUtf8().constData())); } /* * assemble the script and then perhaps post-process it if needed */ QString script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); file_names[FW_FILE] = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + file_names[FW_FILE].toStdString()); QFile fw_file(file_names[FW_FILE]); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_macosx.h0000644000175000017500000000274111733011756023314 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002,2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCONFIGURATOR_MACOSX_HH #define _OSCONFIGURATOR_MACOSX_HH #include "config.h" #include "OSConfigurator_bsd.h" #include "OSData.h" namespace fwcompiler { class OSConfigurator_macosx : public OSConfigurator_bsd { public: virtual ~OSConfigurator_macosx() {}; OSConfigurator_macosx(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator_bsd(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual std::string printKernelVarsCommands(); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/RoutingCompiler_freebsd.cpp0000644000175000017500000000734511733011756024212 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RoutingCompiler_freebsd.h" #include "fwbuilder/Firewall.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** * Need to reimplement this function even though it looks exactly the same * as the one in RoutingCompiler_openbsd. The difference is that it picks up * class RoutingCompiler_freebsd::PrintRule * */ void RoutingCompiler_freebsd::compile() { string banner = " Compiling routing rules for " + fw->getName(); info(banner); Compiler::compile(); //bool check_for_recursive_groups=true; add(new RoutingCompiler::Begin()); add(new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new recursiveGroupsInRDst("Check for recursive Groups in RDst")); add(new emptyGroupsInRDst("Check for empty Groups in RDst")); add(new emptyRDstAndRItf("Check if RDst and RItf are both empty")); add(new singleAdressInRGtw( "Check if RGtw object has exactly one IP adress")); add(new rItfChildOfFw("Check if RItf is an Iterface of this firewall")); add(new interfaceOrGateway( "Check that the rule has either gw or interface but not both")); add(new validateNetwork("Validate network addresses")); add(new reachableAddressInRGtw( "Check if RGtw is reachable via local networks")); add(new contradictionRGtwAndRItf( "Check if RGtw is in a network of RItf")); add(new ExpandGroups("Expand groups in DST")); add(new ExpandMultipleAddresses( "Expand objects with multiple addresses in DST")); add(new addressRangesInDst("process address ranges")); //add(new eliminateDuplicatesInDST("Eliminate duplicates in DST")); add(new FindDefaultRoute("Find rules that install default route")); #ifdef ECMP_SUPPORT_OLD_STYLE add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'competingRules'")); add(new competingRules("Check for competing rules")); #endif add(new ConvertToAtomicForDST( "Convert to atomic rules by dst address elements")); add(new sameDestinationDifferentGateways( "detect rules with the same destination but different gateways. We do not " "support ECMP at this time")); // add(new createSortedDstIdsLabel( // "Create label with a sorted dst-id-list for 'classifyRoutingRules'")); // add(new classifyRoutingRules( // "Classify into single path or part of a multi path rule")); add(new optimize3( "Eliminate duplicate rules generated from a single gui-rule")); add(new eliminateDuplicateRules( "Eliminate duplicate rules over the whole table")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add(printRule=new PrintRule("generate ip code")); add(new simplePrintProgress()); runRuleProcessors(); } fwbuilder-5.1.0.3599/src/pflib/TableFactory.h0000644000175000017500000000542411733011756021416 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TABLEFACTORY_HH #define __TABLEFACTORY_HH #include #include #include #include #include #include #include #include #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; }; namespace fwcompiler { class TableFactory { BaseCompiler *compiler; libfwbuilder::Firewall *firewall; libfwbuilder::FWObjectDatabase *dbroot; libfwbuilder::FWObject *persistent_tables; GroupRegistry *group_registry; std::map tables; std::map tblnames; std::string ruleSetName; std::map > table_deduplicator; std::string generateTblID(libfwbuilder::RuleElement *re); libfwbuilder::FWObject* createTableObject(const std::string &tblname, const std::string &tblid); public: TableFactory(BaseCompiler *comp, libfwbuilder::Firewall *firewall, libfwbuilder::Library *persistent_objects, GroupRegistry *group_registry); void init(libfwbuilder::FWObjectDatabase *_dbroot); void detach(); void setRuleSetName(const std::string &rsn="") { ruleSetName=rsn; } void registerTable(const std::string& tblname, const std::string& tblid, libfwbuilder::FWObject *tbl) throw(libfwbuilder::FWException); void createTablesForRE(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); void addObjectToTable(libfwbuilder::FWObject *tblgrp, libfwbuilder::FWObject *obj); std::string PrintTables(); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipf.h0000644000175000017500000002033211733011756022622 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_IPF_HH #define __POLICYCOMPILER_IPF_HH #include #include "PolicyCompiler_pf.h" namespace libfwbuilder { class TCPService; class UDPService; class ICMPService; }; #define ANY_IP_OBJ_ID "__any_ip_obj__" #define ANY_ICMP_OBJ_ID "__any_icmp_obj__" #define ANY_TCP_OBJ_ID "__any_tcp_obj__" #define ANY_UDP_OBJ_ID "__any_udp_obj__" namespace fwcompiler { class PolicyCompiler_ipf : public PolicyCompiler_pf { protected: libfwbuilder::TCPService *anytcp; libfwbuilder::UDPService *anyudp; libfwbuilder::ICMPService *anyicmp; virtual std::string myPlatformName(); /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls PolicyCompiler::_internalPrintPolicyRule and then adds * chain and target at the end of the printed line */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * split rules if direction is "Both" */ DECLARE_POLICY_RULE_PROCESSOR(SplitDirectionIpfilter); /** * splits rules with service 'any' because ipf can keep state * only for UDP/TCP/ICMP */ DECLARE_POLICY_RULE_PROCESSOR(expandAnyService); /** * deals with negation in Src in policy rules. * * this method is different from that in PolicyCompiler_pf */ DECLARE_POLICY_RULE_PROCESSOR(doSrcNegation); /** * deals with negation in Dst in policy rules. * * this method is different from that in PolicyCompiler_pf */ DECLARE_POLICY_RULE_PROCESSOR(doDstNegation); /** * deals with negation in Srv in policy rules. * * this method is different from that in PolicyCompiler_pf */ DECLARE_POLICY_RULE_PROCESSOR(doSrvNegation); /** * Placeholders for MultiAddressRunTime objects which are not * supported for ipf */ class processMultiAddressObjectsInRE : public PolicyRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInSrc(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class processMultiAddressObjectsInDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInDst(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * checks for the following situations: * * 1. dynamic interface is in source and direction is inbound * (drop interface from src since source address is * undertermined) * * 2. dynamic interface is in source, direction is outbound * (drop interface from the list, this rule has been created * while processing negation. TODO: this is kludge, need to * find a better way to process negation if firewall is in rule * element and it has dynamic interface) * * 3. dynamic interface is in destination and direction is * outbound (drop interface since dest. address is undefined) * */ class specialCaseWithDynInterface : public PolicyRuleProcessor { void dropDynamicInterface(libfwbuilder::RuleElement *re); public: specialCaseWithDynInterface(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * ipf supports "keep state" only for icmp/udp/tcp */ DECLARE_POLICY_RULE_PROCESSOR(checkForKeepState); /** * calculates N for action skip (used in negation) */ class calculateSkip : public PolicyRuleProcessor { std::map allrules; public: calculateSkip(const std::string &n); virtual bool processNext(); }; /** * eliminates duplicate atomic rules */ class eliminateDuplicateRules : public PolicyRuleProcessor { private: std::deque rules_seen_so_far; public: eliminateDuplicateRules(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class fwcompiler::PolicyCompiler_ipf::eliminateDuplicateRules; /** * optimize rules - instead of generating all possible * combinations of src,dst and srv we split the rule onto * three rules, checking on * rule element at a time and using * 'any' in the other two. This reduces the number of * generated elementary rules from N^3 to 3N (and reduces * compile time about the same). */ class optimize1 : public PolicyRuleProcessor { protected: void optimizeForRuleElement(libfwbuilder::PolicyRule *rule, const std::string &re_type); public: optimize1(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipf::optimize1; class optimizeSrc : public optimize1 { public: optimizeSrc(const std::string &name) : optimize1(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipf::optimizeSrc; class optimizeDst : public optimize1 { public: optimizeDst(const std::string &name) : optimize1(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipf::optimizeDst; class optimizeSrv : public optimize1 { public: optimizeSrv(const std::string &name) : optimize1(name) {} virtual bool processNext(); }; friend class PolicyCompiler_ipf::optimizeSrv; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. * Negation should also have been taken care of before this * method is called. */ class PrintRule : public PolicyCompiler_pf::PrintRule { virtual std::string _printPort(int rs,int re,bool neg=false); virtual void _printWith(libfwbuilder::Service *srv); virtual void _printAction(libfwbuilder::PolicyRule *r); virtual void _printAddr(libfwbuilder::Address *o,bool neg=false); virtual void _printDstService(libfwbuilder::RuleElement *o); public: PrintRule(const std::string &name); virtual bool processNext(); }; public: PolicyCompiler_ipf(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : PolicyCompiler_pf(_db, fw, ipv6_policy, _oscnf, NULL) {} virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/pflib/RoutingCompiler_openbsd.cpp0000644000175000017500000001770011733011756024226 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RoutingCompiler_openbsd.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Network.h" #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; static std::map tmp_chain_no; string RoutingCompiler_openbsd::myPlatformName() { return "pf"; } void RoutingCompiler_openbsd::verifyOS() { QStringList supported_os = QString( Resources::platform_res[fw->getStr("platform")]-> getResourceStr("/FWBuilderResources/Target/supported_os").c_str()) .split(","); QString host_os = fw->getStr("host_OS").c_str(); if (!supported_os.contains(host_os)) abort("Unsupported host OS " + host_os.toStdString()); } int RoutingCompiler_openbsd::prolog() { int n = RoutingCompiler::prolog(); verifyOS(); return n; } bool RoutingCompiler_openbsd::addressRangesInDst::processNext() { RoutingRule *rule; rule=getNext(); if (rule==NULL) return false; RuleElementRDst *dstrel = rule->getRDst(); compiler->_expandAddressRanges(rule, dstrel); tmp_queue.push_back(rule); return true; } bool RoutingCompiler_openbsd::FindDefaultRoute::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast(compiler); RoutingRule *rule; rule=getNext(); if (rule==NULL) return false; RuleElementRDst *dstrel = rule->getRDst(); FWObject *ref = dstrel->front(); Address *dst = Address::cast(FWReference::cast(ref)->getPointer()); if (dst->isAny()) bsd_comp->have_default_route = true; tmp_queue.push_back(rule); return true; } /* * this processor eliminates duplicate routing rules, generated from the same * rule in the GUI */ bool RoutingCompiler_openbsd::optimize3::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast(compiler); RoutingRule *rule = getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } assert (bsd_comp->printRule!=NULL); string thisRule = rule->getLabel() + " " + bsd_comp->printRule->RoutingRuleToString(rule, false); if (rules_seen_so_far.count(thisRule)!=0) return true; tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = true; return true; } /* * this processor eliminates duplicate atomic routing rules in one routing table */ bool RoutingCompiler_openbsd::eliminateDuplicateRules::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast(compiler); RoutingRule *rule = getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } assert (bsd_comp->printRule!=NULL); string thisRule = bsd_comp->printRule->RoutingRuleToString(rule, false); map::iterator rules_it = rules_seen_so_far.find(thisRule); if (rules_it != rules_seen_so_far.end()) { QString msg = QObject::tr("Two of the routing commands created from the gui " "routing rules %1 and %2 " "are identical, skipping the second. " "Revise them to avoid this warning"); compiler->warning( rule, msg.arg(rules_it->second.c_str()).arg(rule->getLabel().c_str()).toStdString()); return true; } tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = rule->getLabel(); return true; } /** *----------------------------------------------------------------------- */ void RoutingCompiler_openbsd::compile() { string banner = " Compiling routing rules for " + fw->getName(); info(banner); Compiler::compile(); //bool check_for_recursive_groups=true; add(new RoutingCompiler::Begin()); add(new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new recursiveGroupsInRDst("Check for recursive Groups in RDst")); add(new emptyGroupsInRDst("Check for empty Groups in RDst")); add(new emptyRDstAndRItf("Check if RDst and RItf are both empty")); add(new singleAdressInRGtw( "Check if RGtw object has exactly one IP adress")); add(new rItfChildOfFw("Check if RItf is an Iterface of this firewall")); add(new interfaceOrGateway( "Check that the rule has either gw or interface but not both")); add(new validateNetwork("Validate network addresses")); add(new reachableAddressInRGtw( "Check if RGtw is reachable via local networks")); add(new contradictionRGtwAndRItf( "Check if RGtw is in a network of RItf")); add(new ExpandGroups("Expand groups in DST")); add(new ExpandMultipleAddresses( "Expand objects with multiple addresses in DST")); add(new addressRangesInDst("process address ranges")); add( new processMultiAddressObjectsInRDst( "process MultiAddress objects in RDst") ); //add(new eliminateDuplicatesInDST("Eliminate duplicates in DST")); add(new FindDefaultRoute("Find rules that install default route")); #ifdef ECMP_SUPPORT_OLD_STYLE add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'competingRules'")); add(new competingRules("Check for competing rules")); #endif add(new ConvertToAtomicForDST( "Convert to atomic rules by dst address elements")); add(new sameDestinationDifferentGateways( "detect rules with the same destination but different gateways. We do not " "support ECMP at this time")); // add(new createSortedDstIdsLabel( // "Create label with a sorted dst-id-list for 'classifyRoutingRules'")); // add(new classifyRoutingRules( // "Classify into single path or part of a multi path rule")); add(new optimize3( "Eliminate duplicate rules generated from a single gui-rule")); add(new eliminateDuplicateRules( "Eliminate duplicate rules over the whole table")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add(printRule=new PrintRule("generate ip code")); add(new simplePrintProgress()); runRuleProcessors(); } string RoutingCompiler_openbsd::debugPrintRule(Rule *r) { RoutingRule *rule = RoutingRule::cast(r); return RoutingCompiler::debugPrintRule(rule); } void RoutingCompiler_openbsd::epilog() { if (!inSingleRuleCompileMode() && defined_restore_script_output) { // function restore_script_output may not be defined if we // have no rules or all rules are disabled output << endl; output << "restore_script_output" << endl; output << "echo \"...done.\"" << endl; } } fwbuilder-5.1.0.3599/src/pflib/NATCompiler_pf_writers.cpp0000644000175000017500000004170011733011756023750 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_pf.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/UserService.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AttachedNetworks.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ NATCompiler_pf::PrintRule::PrintRule(const std::string &name) : NATRuleProcessor(name) { init=true; } void NATCompiler_pf::PrintRule::_printInterface(NATRule *rule) { RuleElementItf *intf_re = rule->getItfOutb(); QStringList rule_interfaces; if ( ! intf_re->isAny()) { for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it) { FWObject *o = FWObjectReference::getObject(*it); rule_interfaces << o->getName().c_str(); } if (rule_interfaces.size() > 1) { rule_interfaces.push_front("{"); rule_interfaces.push_back("}"); } compiler->output << "on " << string((intf_re->getBool("single_object_negation")) ? "! " : " ") << rule_interfaces.join(" ").toStdString() << " "; } } bool NATCompiler_pf::PrintRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); string version = compiler->fw->getStr("version"); compiler->output << compiler->printComment(rule, current_rule_label, "#"); RuleElementOSrc *osrcrel = rule->getOSrc(); RuleElementODst *odstrel = rule->getODst(); RuleElementTSrc *tsrcrel = rule->getTSrc(); RuleElementTDst *tdstrel = rule->getTDst(); FWObject *osrc, *odst; osrc = osrcrel->front(); if (osrc && FWReference::cast(osrc)!=NULL) osrc = FWReference::cast(osrc)->getPointer(); odst = odstrel->front(); if (odst && FWReference::cast(odst)!=NULL) odst = FWReference::cast(odst)->getPointer(); //Address *osrc=compiler->getFirstOSrc(rule); //assert(osrc); //Address *odst=compiler->getFirstODst(rule); //assert(odst); Service *osrv = compiler->getFirstOSrv(rule); //assert(osrv); Address *tsrc = compiler->getFirstTSrc(rule); //assert(tsrc); Address *tdst = compiler->getFirstTDst(rule); //assert(tdst); Service *tsrv = compiler->getFirstTSrv(rule); //assert(tsrv); if (osrc==NULL || odst==NULL || osrv==NULL || tsrc==NULL || tdst==NULL || tsrv==NULL) { QString err; if (osrc==NULL) err = QString("NAT rule %1: osrc==NULL"); if (odst==NULL) err = QString("NAT rule %1: odst==NULL"); if (osrv==NULL) err = QString("NAT rule %1: osrv==NULL"); if (tsrc==NULL) err = QString("NAT rule %1: tsrc==NULL"); if (tdst==NULL) err = QString("NAT rule %1: tdst==NULL"); if (tsrv==NULL) err = QString("NAT rule %1: tsrv==NULL"); compiler->abort(rule, err.arg(rule->getLabel().c_str()).toStdString()); } switch ( rule->getRuleType() ) { case NATRule::Continue: case NATRule::NONAT: { if (XMLTools::version_compare(version, "4.7")>=0) { /* I could not find a better way to implement old "no nat" * behavior with 4.7. They seem to suggest that we should * implement exceptions to the translations using "pass" * or "block" actions. At least this is the only way they * show in examples and there is no "no" keyword anymore. */ compiler->output << "pass in quick "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr(osrcrel); _printSrcPort(osrv, true); compiler->output << "to "; _printREAddr(odstrel); _printPort(osrv, true); compiler->output << endl; } else { compiler->output << "no nat "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr(osrcrel); compiler->output << "to "; _printREAddr(odstrel); compiler->output << endl; compiler->output << "no rdr "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); compiler->output << "to "; _printREAddr( odstrel ); compiler->output << endl; } break; } case NATRule::SNAT: { if (XMLTools::version_compare(version, "4.7")>=0) { compiler->output << "match out "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); _printSrcPort(osrv, true); compiler->output << "to "; _printREAddr( odstrel ); _printPort( osrv, true ); compiler->output << "nat-to "; _printREAddr( tsrcrel ); _printSrcPort(tsrv, false); _printNATRuleOptions(rule); compiler->output << endl; } else { compiler->output << "nat "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); _printSrcPort(osrv, true); compiler->output << "to "; _printREAddr( odstrel ); _printPort( osrv, true ); compiler->output << "-> "; _printREAddr( tsrcrel ); _printSrcPort(tsrv, false); _printNATRuleOptions(rule); compiler->output << endl; } break; } case NATRule::DNAT: case NATRule::LB: { if (XMLTools::version_compare(version, "4.7")>=0) { compiler->output << "match in "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); _printSrcPort(osrv, true); // this is where it is different from NATRule::Redirect compiler->output << "to "; _printREAddr( odstrel ); _printPort(osrv, true); compiler->output << "rdr-to "; _printREAddr( tdstrel ); _printPort(tsrv, false); _printNATRuleOptions(rule); compiler->output << endl; } else { compiler->output << "rdr "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); _printSrcPort(osrv, true); // this is where it is different from NATRule::Redirect compiler->output << "to "; _printREAddr( odstrel ); _printPort(osrv, true); compiler->output << "-> "; _printREAddr( tdstrel ); _printPort(tsrv, false); _printNATRuleOptions(rule); compiler->output << endl; } break; } case NATRule::Redirect: { if (XMLTools::version_compare(version, "4.7")>=0) { compiler->output << "match in "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); compiler->output << "to "; _printREAddr( odstrel ); _printPort(osrv, true); compiler->output << "rdr-to "; _printREAddr( tdstrel ); _printPort(tsrv, false); _printNATRuleOptions(rule); compiler->output << endl; } else { compiler->output << "rdr "; _printInterface(rule); _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); compiler->output << "to "; _printREAddr( odstrel ); _printPort(osrv, true); compiler->output << "-> "; _printREAddr( tdstrel ); _printPort(tsrv, false); _printNATRuleOptions(rule); compiler->output << endl; } break; } case NATRule::NATBranch: { RuleSet *ruleset = rule->getBranch(); string ruleset_name; if (ruleset!=NULL) { ruleset_name = ruleset->getName(); } else { compiler->abort( rule, "Branching rule refers ruleset that does not exist"); // in test mode compiler->abort() does not really abort the program ruleset_name = "UNKNOWN"; } if (XMLTools::version_compare(version, "4.6")>=0) { _printAnchorRule("anchor", ruleset_name, rule); } else { _printAnchorRule("nat-anchor", ruleset_name, rule); _printAnchorRule("rdr-anchor", ruleset_name, rule); } } break; default: break; } return true; } void NATCompiler_pf::PrintRule::_printAnchorRule(const string &anchor_command, const std::string &ruleset_name, NATRule *rule) { RuleElementOSrc *osrcrel = rule->getOSrc(); RuleElementODst *odstrel = rule->getODst(); RuleElementOSrv *osrvrel = rule->getOSrv(); Service *osrv = compiler->getFirstOSrv(rule); compiler->output << anchor_command << " \"" << ruleset_name << "\" "; _printInterface(rule); if (!osrvrel->isAny() || !osrcrel->isAny() || !odstrel->isAny()) { _printProtocol(osrv); compiler->output << "from "; _printREAddr( osrcrel ); compiler->output << "to "; _printREAddr( odstrel ); _printPort(osrv, true); } compiler->output << endl; } void NATCompiler_pf::PrintRule::_printProtocol(Service *srv) { // CustomService returns protocol name starting with v3.0.4 if (CustomService::isA(srv)) { // check if the code string for this custom service already includes // "proto ..." fragment string code = CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName()); std::size_t minus_p = code.find("proto "); if (minus_p != string::npos) return; } if (!srv->isAny() && !TagService::isA(srv) && !UserService::isA(srv) && srv->getProtocolName()!="ip") { compiler->output << "proto "; compiler->output << srv->getProtocolName(); compiler->output << " "; } } /* * print port numbers for the service. For most platforms that inherit * classes for PF this is sufficient, but PF itself also supports * TagService and this method prints "tagged" keyword for it as well. * Arg controls which side of the "->" this service is on. On * the right hand side PF supports shortcut spec 'NNNN:*', but it is * not allowed on the left hand side. Also keyword "tagged" is only * allowed on the left hand side of "->". */ void NATCompiler_pf::PrintRule::_printPort(Service *srv, bool lhs) { if (TCPUDPService::cast(srv)) { int drs = TCPUDPService::cast(srv)->getDstRangeStart(); int dre = TCPUDPService::cast(srv)->getDstRangeEnd(); if (drs!=0) { compiler->output << "port " << drs; if (dre!=0 && dre!=drs) { if (lhs) compiler->output << ":" << dre; else compiler->output << ":*"; } } compiler->output << " "; } if (lhs && TagService::isA(srv)) { compiler->output << "tagged " << TagService::constcast(srv)->getCode() << " "; } } /* * Print port range spec using source ports of the given service object */ void NATCompiler_pf::PrintRule::_printSrcPort(Service *srv, bool lhs) { if (TCPUDPService::cast(srv)) { int srs = TCPUDPService::cast(srv)->getSrcRangeStart(); int sre = TCPUDPService::cast(srv)->getSrcRangeEnd(); if (srs!=0) { compiler->output << "port " << srs; if (sre != 0 && sre != srs) { if (lhs) compiler->output << ":" << sre; else compiler->output << ":*"; } compiler->output << " "; } } } void NATCompiler_pf::PrintRule::_printNegation(RuleElement *rel) { if (rel->getNeg()) compiler->output << "! "; } void NATCompiler_pf::PrintRule::_printREAddr(RuleElement *rel) { FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); // Address *addr= Address::cast(o); _printNegation(rel); if (rel->size()==1) { _printAddr(o); } else { _printAddrList(rel, rel->getNeg()); } } void NATCompiler_pf::PrintRule::_printAddrList(FWObject *grp,bool ) { compiler->output << "{ "; for (FWObject::iterator i=grp->begin(); i!=grp->end(); i++) { if (i!=grp->begin()) compiler->output << ", "; FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); _printAddr(o); } compiler->output << "} "; } void NATCompiler_pf::PrintRule::_printAddr(FWObject *o) { MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { compiler->output << "<" << o->getName() << "> "; return; } if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME) { compiler->output << atrt->getSourceName() << ":network "; return ; } assert(atrt==NULL); } if (Interface::cast(o)!=NULL) { compiler->output << "(" << o->getName() << ") "; return; } if (o->getBool("pf_table")) { compiler->output << "<" << o->getName() << "> "; return; } Address *addr_obj = Address::cast(o); assert(addr_obj!=NULL); const InetAddr *addr = addr_obj->getAddressPtr(); if (addr) { InetAddr mask = *(addr_obj->getNetmaskPtr()); if (Interface::cast(o)!=NULL || Address::cast(o)->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { compiler->output << addr->toString(); if (!mask.isHostMask()) { compiler->output << "/" << mask.getLength(); } compiler->output << " "; } } } void NATCompiler_pf::PrintRule::_printNATRuleOptions(Rule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); if (ruleopt->getBool("pf_bitmask")) compiler->output << "bitmask "; if (ruleopt->getBool("pf_random")) compiler->output << "random "; if (ruleopt->getBool("pf_source_hash")) compiler->output << "source-hash "; if (ruleopt->getBool("pf_round_robin")) compiler->output << "round-robin "; if (ruleopt->getBool("pf_static_port")) compiler->output << "static-port "; } bool NATCompiler_pf::PrintTables::processNext() { NATCompiler_pf *pf_comp=dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; /* print tables */ compiler->output << pf_comp->tables->PrintTables(); return true; } fwbuilder-5.1.0.3599/src/pflib/Preprocessor_pf.h0000644000175000017500000000264011733011756022207 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PREPROCESSOR_PF_HH #define __PREPROCESSOR_PF_HH #include #include "fwcompiler/Preprocessor.h" namespace libfwbuilder { class FWObjectDatabase; }; namespace fwcompiler { class Preprocessor_pf : public Preprocessor { public: Preprocessor_pf(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : Preprocessor(_db, fw, ipv6_policy) { } virtual void convertObject(libfwbuilder::FWObject *obj); }; } #endif fwbuilder-5.1.0.3599/src/pflib/NATCompiler_ipf.cpp0000644000175000017500000005161511733011756022350 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_ipf.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string NATCompiler_ipf::myPlatformName() { return "ipf"; } int NATCompiler_ipf::prolog() { int n=NATCompiler_pf::prolog(); return n; } bool NATCompiler_ipf::VerifyRules::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); if (rule->getRuleType()==NATRule::DNAT && odst->size()!=1) compiler->abort(rule, "There should be no more than one object in " "original destination"); // if (rule->getRuleType()==NATRule::SNAT && tsrc->size()!=1) // compiler->abort(rule, "There should be no more than one object in translated source in the rule "+rule->getLabel()); if (rule->getRuleType()==NATRule::DNAT && osrv->isAny()) compiler->abort(rule, "Service must be specified for destination translation rule"); if (tsrv->size()!=1) compiler->abort(rule, "Translated service should be 'Original' or should " "contain single object"); FWObject *o=tsrv->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if ( Group::cast(o)!=NULL) compiler->abort(rule, "Can not use group in translated service"); if (rule->getRuleType()==NATRule::SNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstOSrc(rule)); Network *a2=Network::cast(compiler->getFirstTSrc(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) compiler->abort(rule, "Original and translated source should both " "be networks of the same size"); } if (rule->getRuleType()==NATRule::DNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstODst(rule)); Network *a2=Network::cast(compiler->getFirstTDst(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) compiler->abort(rule, "Original and translated destination should " "both be networks of the same size"); } if (osrc->getNeg() || odst->getNeg() || osrv->getNeg()) compiler->abort(rule, "Negation in NAT rules is not supported"); return true; } bool NATCompiler_ipf::ExpandPortRange::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; Service *osrv=compiler->getFirstOSrv(rule); if (UDPService::isA(osrv) || TCPService::isA(osrv)) { int rs = TCPUDPService::cast(osrv)->getDstRangeStart(); int re = TCPUDPService::cast(osrv)->getDstRangeEnd(); int numPorts = re-rs+1; if (numPorts==1) { tmp_queue.push_back(rule); return true; } if (numPorts > 20) { ostringstream ostr; ostr << string("Expanding port range ") << osrv->getName() << " creates " << numPorts << " rules"; compiler->warning(rule, ostr.str()); } string newSrvType = TCPService::TYPENAME; if (UDPService::isA(osrv)) newSrvType = UDPService::TYPENAME; for (int p=rs; p<=re; ++p) { NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); FWObject *newSrv = compiler->dbcopy->create(newSrvType); newSrv->duplicate(osrv,true); TCPUDPService::cast(newSrv)->setDstRangeStart(p); TCPUDPService::cast(newSrv)->setDstRangeEnd(p); compiler->persistent_objects->add(newSrv,false); compiler->dbcopy->addToIndex(newSrv); RuleElementOSrv *nosrv = r->getOSrv(); nosrv->clearChildren(); nosrv->addRef(newSrv); compiler->temp_ruleset->add(r); tmp_queue.push_back(r); } } else { tmp_queue.push_back(rule); } return true; } bool NATCompiler_ipf::AssignInterface::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; RuleElementItfOutb *itf_re = rule->getItfOutb(); Address *a = NULL; switch (rule->getRuleType() ) { case NATRule::Continue: case NATRule::NONAT: { /* use heuristic to assign nonat rule to interfaces */ Interface *iface; a=compiler->getFirstODst(rule); iface=compiler->findInterfaceFor( compiler->getFirstODst(rule) , compiler->fw); if (iface!=NULL && !iface->isLoopback()) { if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); // rule->setInterfaceId( iface->getId() ); tmp_queue.push_back( rule ); return true; } /* slip into Redirect case to assign rule to all interfaces */ } case NATRule::Redirect: case NATRule::DNAT: case NATRule::DNetnat: case NATRule::LB: { /* * we do not have network zones here, so our ability to pick right * interfaces is rather limited. First, we try to find interface that * is connected to the subnet OSrc belongs to. If that does not work, * we assign rule to all interfaces, except loopback */ a = NULL; if ( ! rule->getOSrc()->isAny() ) a = compiler->getFirstOSrc(rule); if ( a==NULL && ! rule->getODst()->isAny() ) a = compiler->getFirstODst(rule); if (a!=NULL) { Interface *iface; iface = compiler->findInterfaceFor(a,compiler->fw); if (iface!=NULL && !iface->isLoopback()) { if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); // rule->setInterfaceId( iface->getId() ); tmp_queue.push_back(rule); return true; } } FWObjectTypedChildIterator j=compiler->fw->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *iface = Interface::cast(*j); assert(iface); if ( iface->isUnnumbered() || iface->isBridgePort() || iface->isLoopback()) continue; NATRule *r = compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementItfOutb *itf_re = r->getItfOutb(); if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); //r->setInterfaceId( iface->getId() ); tmp_queue.push_back( r ); } return true; } case NATRule::SNAT: case NATRule::SNetnat: { a=compiler->getFirstTSrc(rule); if ( (Interface::isA(a) || IPv4::isA(a)) && a->isChildOf(compiler->fw)) { FWObject *p = a; while ( ! Interface::isA(p) ) p = p->getParent(); if ( ! itf_re->hasRef(p)) itf_re->addRef(p); // rule->setInterfaceId( p->getId() ); tmp_queue.push_back(rule); return true; } /* if we appear here, then TSrc is not an interface or address of an * interface. */ int n=0; list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=Interface::cast(*i); assert(iface); if (iface->isLoopback() || iface->isUnnumbered() || iface->isBridgePort()) continue; NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); RuleElementItfOutb *itf_re = r->getItfOutb(); if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface); // r->setInterfaceId( iface->getId() ); tmp_queue.push_back(r); n++; } if (n==0) tmp_queue.push_back(rule); return true; } default: ; } compiler->abort(rule, "Could not assign NAT rule to the interface. " "Perhaps one of the objects has address which does not " "belong to any subnet the firewall has interface on"); return true; } bool NATCompiler_ipf::prepareForLB::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if (rule->getRuleType()==NATRule::LB ) { RuleElementTDst *tdst=rule->getTDst(); assert(tdst); if (tdst->size()>2) { std::vector cl; for(list::iterator i=tdst->begin(); i!=tdst->end(); ++i) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); cl.push_back(o); if (cl.size()==2) { NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementTDst *notdst=r->getTDst(); notdst->clearChildren(); notdst->addRef( cl[0] ); notdst->addRef( cl[1] ); cl.clear(); tmp_queue.push_back( r ); } } if (cl.size()!=0) { NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementTDst *notdst=r->getTDst(); notdst->clearChildren(); notdst->addRef( cl[0] ); // notdst->addRef( cl[1] ); cl.clear(); tmp_queue.push_back( r ); } } else tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); return true; } /* * by now the rule should have already been assigned to interface. * * TODO: We should also take into account a situation when interface has * multiple addresses... */ bool NATCompiler_ipf::RedirectRules::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; RuleElementItfOutb *itf_re = rule->getItfOutb(); Interface *rule_iface = Interface::cast(FWObjectReference::getObject(itf_re->front())); // Interface::cast( rule->getRoot()->getById(rule->getInterfaceId() ,true) ); tmp_queue.push_back(rule); RuleElementTDst *rel=rule->getTDst(); assert(rel); Address *otdst=compiler->getFirstTDst(rule); if (rule->getRuleType()==NATRule::Redirect && rule_iface!=NULL && otdst->getId()==compiler->fw->getId()) { rel->clearChildren(); rel->addRef( rule_iface ); } return true; } bool NATCompiler_ipf::appProxy::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; bool ftp_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_ftp_proxy"); bool rcmd_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_rcmd_proxy"); bool krcmd_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_krcmd_proxy"); bool ekshell_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_ekshell_proxy"); bool raudio_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_raudio_proxy"); bool h323_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_h323_proxy"); bool ipsec_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_ipsec_proxy"); bool pptp_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_pptp_proxy"); bool irc_proxy = compiler->getCachedFwOpt()->getBool("ipf_nat_irc_proxy"); QString ipsec_proxy_str = QString("proxy port %1 ipsec/udp ").arg(ISAKMP_PORT); QString ftp_proxy_str = QString("proxy port %1 ftp/tcp ").arg(FTP_PORT); QString rcmd_proxy_str = QString("proxy port %1 rcmd/tcp ").arg(RCMD_PORT); QString krcmd_proxy_str = QString("proxy port %1 rcmd/tcp ").arg(KRCMD_PORT); QString ekshell_proxy_str = QString("proxy port %1 rcmd/tcp ").arg(EKSHELL_PORT); QString raudio_proxy_str = QString("proxy port %1 raudio/tcp ").arg(RAUDIO_PORT); QString h323_proxy_str = QString("proxy port %1 h323/tcp ").arg(H323_PORT); QString pptp_proxy_str = QString("proxy port %1 pptp/tcp ").arg(PPTP_PORT); QString irc_proxy_str = QString("proxy port %1 irc/tcp ").arg(IRC_PORT); if (rule->getRuleType()==NATRule::SNAT || rule->getRuleType()==NATRule::NONAT) { Service *osrv = compiler->getFirstOSrv(rule); if (UDPService::isA(osrv)) { UDPService *s=UDPService::cast(osrv); if (ipsec_proxy && s->getDstRangeStart()==ISAKMP_PORT && s->getDstRangeEnd()==ISAKMP_PORT) rule->setStr("nat_rule_proxy", ipsec_proxy_str.toStdString()); } if (TCPService::isA(osrv)) { TCPService *s = TCPService::cast(osrv); int range_start = s->getDstRangeStart(); int range_end = s->getDstRangeEnd(); if (ftp_proxy && range_start==FTP_PORT && range_end==FTP_PORT) rule->setStr("nat_rule_proxy", ftp_proxy_str.toStdString()); if (rcmd_proxy && range_start==RCMD_PORT && range_end==RCMD_PORT) rule->setStr("nat_rule_proxy", rcmd_proxy_str.toStdString()); if (krcmd_proxy && range_start==KRCMD_PORT && range_end==KRCMD_PORT ) rule->setStr("nat_rule_proxy", krcmd_proxy_str.toStdString()); if (ekshell_proxy && range_start==EKSHELL_PORT && range_end==EKSHELL_PORT ) rule->setStr("nat_rule_proxy", ekshell_proxy_str.toStdString()); if (raudio_proxy && range_start==RAUDIO_PORT && range_end==RAUDIO_PORT ) rule->setStr("nat_rule_proxy", raudio_proxy_str.toStdString()); if (h323_proxy && range_start==H323_PORT && range_end==H323_PORT ) rule->setStr("nat_rule_proxy", h323_proxy_str.toStdString()); if (pptp_proxy && range_start==PPTP_PORT && range_end==PPTP_PORT ) rule->setStr("nat_rule_proxy", pptp_proxy_str.toStdString()); if (irc_proxy && range_start==IRC_PORT && range_end==IRC_PORT ) rule->setStr("nat_rule_proxy", irc_proxy_str.toStdString()); } } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipf::expandAnyService::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *srv=rule->getOSrv(); if (rule->getRuleType()==NATRule::SNAT && srv->isAny()) { NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setBool("needs_portmap",true); tmp_queue.push_back(r); } tmp_queue.push_back(rule); return true; } bool NATCompiler_ipf::processMultiAddressObjectsInRE::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) compiler->abort( rule, "Run-time AddressTable objects are not supported."); } tmp_queue.push_back(rule); return true; } void NATCompiler_ipf::compile() { bool manage_virtual_addr=getCachedFwOpt()->getBool("manage_virtual_addr"); info(" Compiling NAT rules for " + fw->getName()); Compiler::compile(); add( new Begin()); add( new printTotalNumberOfRules() ); add( new singleRuleFilter()); add( new recursiveGroupsInOSrc( "check for recursive groups in OSRC" ) ); add( new recursiveGroupsInODst( "check for recursive groups in ODST" ) ); add( new recursiveGroupsInOSrv( "check for recursive groups in OSRV" ) ); add( new recursiveGroupsInTSrc( "check for recursive groups in TSRC" ) ); add( new recursiveGroupsInTDst( "check for recursive groups in TDST" ) ); add( new recursiveGroupsInTSrv( "check for recursive groups in TSRV" ) ); add( new emptyGroupsInOSrc( "check for empty groups in OSRC" ) ); add( new emptyGroupsInODst( "check for empty groups in ODST" ) ); add( new emptyGroupsInOSrv( "check for empty groups in OSRV" ) ); add( new emptyGroupsInTSrc( "check for empty groups in TSRC" ) ); add( new emptyGroupsInTDst( "check for empty groups in TDST" ) ); add( new emptyGroupsInTSrv( "check for empty groups in TSRV" ) ); add( new ExpandGroups( "expand groups" ) ); add( new eliminateDuplicatesInOSRC( "eliminate duplicates in OSRC" ) ); add( new eliminateDuplicatesInODST( "eliminate duplicates in ODST" ) ); add( new eliminateDuplicatesInOSRV( "eliminate duplicates in OSRV" ) ); add( new swapMultiAddressObjectsInOSrc(" swap MultiAddress -> MultiAddressRunTime in OSrc") ); add( new swapMultiAddressObjectsInODst(" swap MultiAddress -> MultiAddressRunTime in ODst") ); add( new processMultiAddressObjectsInOSrc("process MultiAddress objects in OSrc") ); add( new processMultiAddressObjectsInODst("process MultiAddress objects in ODst") ); add( new splitOnOSrv( "split rule on original service" ) ); add( new ExpandPortRange("expand port ranges") ); add( new fillTranslatedSrv( "fill translated service" ) ); add( new NATRuleType( "determine NAT rule types" ) ); add( new VerifyRules( "verify NAT rules" ) ); add( new splitODstForSNAT("split rule if objects in ODst belong to different subnets" ) ); add( new ReplaceFirewallObjectsODst( "replace references to the firewall in ODst" ) ); add( new ReplaceFirewallObjectsTSrc( "replace references to the firewall in TSrc" ) ); if ( manage_virtual_addr ) { add( new addVirtualAddress( "add virtual addresses for NAT rules" ) ); } add( new ExpandMultipleAddresses( "expand multiple addresses" ) ); add( new checkForUnnumbered( "check for unnumbered interfaces" ) ); add( new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls" ) ); add( new ExpandAddressRanges( "expand address range objects" ) ); add( new ConvertToAtomicForOriginal( "convert to atomic rules in OSrc and ODst" ) ); add( new ConvertToAtomicForTSrc( "convert to atomic rules in TSrc" ) ); add( new prepareForLB( "prepare for load balancing rules" ) ); add( new appProxy( "add application proxy code to map rules" ) ); add( new expandAnyService("split NAT rules with ANY service" ) ); add( new AssignInterface( "assign rules to interfaces" ) ); add( new RedirectRules( "replace objects in TDst for 'Redirect' rules" ) ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new PrintRule("generate ipfilter code") ); add( new simplePrintProgress() ); runRuleProcessors(); } void NATCompiler_ipf::epilog() { } fwbuilder-5.1.0.3599/src/pflib/NATCompiler_ipfw.h0000644000175000017500000000314511733011756022177 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NATCOMPILER_IPFW_HH #define __NATCOMPILER_IPFW_HH #include #include "NATCompiler_pf.h" #include #define FTP_PORT 21 #define RCMD_PORT 514 #define H323_PORT 1720 #define RAUDIO_PORT 5050 #define ISAKMP_PORT 500 namespace fwcompiler { class NATCompiler_ipfw : public NATCompiler_pf { protected: virtual std::string myPlatformName(); public: NATCompiler_ipfw(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : NATCompiler_pf(_db, fw, ipv6_policy, _oscnf) {} virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/pflib/NATCompiler_pf.cpp0000644000175000017500000013014411733011756022172 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_pf.h" #include "fwcompiler/OSConfigurator.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string NATCompiler_pf::myPlatformName() { return "pf"; } int NATCompiler_pf::prolog() { int n=NATCompiler::prolog(); if ( n>0 ) { list l2=fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if ( iface->isDyn()) { iface->setBool("use_var_address",true); /* dynamic interface should not have IPv4 child object(s). We issue a * warning if it does in a policy compiler, there is no need to repeat * it here */ list l3=iface->getByType(IPv4::TYPENAME); for (list::iterator j=l3.begin(); j!=l3.end(); ++j) iface->remove(*j); } } } /* pseudo-host with ip address 127.0.0.1 We'll use it for redirection * NAT rules */ //FWObject *grp; loopback_address = dbcopy->createIPv4(); loopback_address->setName("__loopback_address__"); loopback_address->setId(FWObjectDatabase::generateUniqueId()); // "__loopback_address_id__"); IPv4::cast(loopback_address)->setAddress(InetAddr::getLoopbackAddr()); persistent_objects->add(loopback_address,false); if (tables) { tables->init(dbcopy); if (!getSourceRuleSet()->isTop()) tables->setRuleSetName(getRuleSetName()); } return n; } string NATCompiler_pf::debugPrintRule(libfwbuilder::Rule *r) { NATRule *rule = NATRule::cast(r); RuleElementItfOutb *itf_re = rule->getItfOutb(); FWObject *rule_iface = FWObjectReference::getObject(itf_re->front()); // FWObject *rule_iface = dbcopy->findInIndex(rule->getInterfaceId()); return NATCompiler::debugPrintRule(rule) + " " + string( (rule_iface!=NULL)?rule_iface->getName():"") + " (type=" + rule->getRuleTypeAsString() + ")"; } void NATCompiler_pf::_expand_addr(Rule *rule, FWObject *s, bool expand_cluster_interfaces_fully) { if (RuleElementTSrc::isA(s)) { // do not replace interfaces with their ip addresses in TSrc // to be able to generate "nat ... -> (em0)" command later list interfaces_in_re; for (FWObject::iterator i1=s->begin(); i1!=s->end(); ++i1) { FWObject *o = FWReference::getObject(*i1); assert(o); if (Interface::isA(o)) interfaces_in_re.push_back(o); } if (interfaces_in_re.size() > 1) { for (list::iterator i=interfaces_in_re.begin(); i!=interfaces_in_re.end(); ++i) s->removeRef(*i); NATCompiler::_expand_addr( rule, s, expand_cluster_interfaces_fully); for (list::iterator i=interfaces_in_re.begin(); i!=interfaces_in_re.end(); ++i) s->addRef(*i); } } else NATCompiler::_expand_addr( rule, s, expand_cluster_interfaces_fully); } bool NATCompiler_pf::NATRuleType::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()!=NATRule::Unknown) return true; RuleElementTSrc *tsrcre = rule->getTSrc(); RuleElementTDst *tdstre = rule->getTDst(); RuleElementTSrv *tsrvre = rule->getTSrv(); Service *osrv=compiler->getFirstOSrv(rule); Address *tsrc = compiler->getFirstTSrc(rule); Address *tdst = compiler->getFirstTDst(rule); Service *tsrv=compiler->getFirstTSrv(rule); if (rule->getAction() == NATRule::Branch) { rule->setRuleType(NATRule::NATBranch); if (!tsrcre->isAny() || !tdstre->isAny() || !tsrvre->isAny()) { tsrcre->clearChildren(); tsrcre->setAnyElement(); tdstre->clearChildren(); tdstre->setAnyElement(); tsrvre->clearChildren(); tsrvre->setAnyElement(); compiler->warning( rule, "Translated Src, Dst and Srv are ignored in the NAT " "rule with action 'Branch'"); } return true; } if (tsrc->isAny() && tdst->isAny() && (tsrv->isAny() || (tsrv->getId() == osrv->getId())) ) { rule->setRuleType(NATRule::NONAT); return true; } bool osrv_defines_src_port = false; bool osrv_defines_dst_port = false; bool tsrv_translates_src_port = false; bool tsrv_translates_dst_port = false; if (TCPUDPService::cast(osrv)) { TCPUDPService *tu_osrv = TCPUDPService::cast(osrv); osrv_defines_src_port = \ (tu_osrv->getSrcRangeStart() != 0 && tu_osrv->getDstRangeStart() == 0); osrv_defines_dst_port = \ (tu_osrv->getSrcRangeStart() == 0 && tu_osrv->getDstRangeStart() != 0); } if (TCPUDPService::cast(tsrv)) { TCPUDPService *tu_tsrv = TCPUDPService::cast(tsrv); tsrv_translates_src_port = \ (tu_tsrv->getSrcRangeStart() != 0 && tu_tsrv->getDstRangeStart() == 0); tsrv_translates_dst_port = \ (tu_tsrv->getSrcRangeStart() == 0 && tu_tsrv->getDstRangeStart() != 0); } if ( (! tsrc->isAny() && tdst->isAny()) || (tsrc->isAny() && tdst->isAny() && tsrv_translates_src_port) ) { rule->setRuleType(NATRule::SNAT); return true; } if ( (tsrc->isAny() && ! tdst->isAny()) || (tsrc->isAny() && tdst->isAny() && tsrv_translates_dst_port) ) { /* this is load balancing rule if there are multiple objects in TDst */ if ( tdstre->size()>1 ) rule->setRuleType(NATRule::LB); else { if ( compiler->complexMatch(tdst,compiler->fw) ) rule->setRuleType(NATRule::Redirect); else rule->setRuleType(NATRule::DNAT); // if ( tdst->getId()==compiler->fw->getId() ) rule->setRuleType(NATRule::Redirect); // else rule->setRuleType(NATRule::DNAT); } return true; } if ( ( ! tsrc->isAny() && ! tdst->isAny() ) || ( ! tsrc->isAny() && tsrv_translates_dst_port) || ( ! tdst->isAny() && tsrv_translates_src_port) ) { rule->setRuleType(NATRule::SDNAT); return true; } compiler->abort(rule, "Unsupported translation."); return false; } /* * This processor should be called after classifyNATRule. Should call * classifyNATRule after this processor again. * * This algorithm is very much specific to iptables. Platforms where * this simple algorithm for SDNAT rules is not appropriate, should * either implement equivalent of this processor using different * algorithm, or should catch SDNAT rules and abort in their own * verifyNATRule processor. */ bool NATCompiler_pf::splitSDNATRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; if ( rule->getRuleType()==NATRule::SDNAT) { RuleElementODst *odst; RuleElementOSrv *osrv; RuleElementTSrc *tsrc; RuleElementTDst *tdst; /* first rule translates destination and may translate service (depends * on the original rule) */ NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); r->setRuleType(NATRule::Unknown); tsrc=r->getTSrc(); tsrc->clearChildren(); tsrc->setAnyElement(); tmp_queue.push_back(r); /* the second rule translates source and uses translated object in * ODst. Since the service could have been translated by the first * rule, we use TSrv in OSrv */ r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); r->setRuleType(NATRule::Unknown); odst=r->getODst(); odst->clearChildren(); for (FWObject::iterator i=rule->getTDst()->begin(); i!=rule->getTDst()->end(); i++) { FWObject *o = FWReference::getObject(*i); odst->addRef(o); } if ( ! rule->getTSrv()->isAny()) { /* * See "pf flow diagram" at http://homepage.mac.com/quension/pf/flow.png * rdr happens first, then nat. This means nat sees packet with * translated destination address and port. * * If the first rule in the pair translated service and * changed destination port, we need to match it in the * second rule to only trsnslate source in the packets * that have been processed by the first rule. However * this only applies to the case when destination port has * been translated because the first rule uses DNAT which * can only translate dest. port. So, if TSrv has zero * dest. port range but non-zero source port range, we * should not match it here because in this case no * dest. port translation occurs. If TSrv translates both * source and destination ports, we create new TCP(UDP) * service object with only dest. port part and use it to * match. */ Service *tsrv = compiler->getFirstTSrv(rule); TCPUDPService *tu_tsrv = TCPUDPService::cast(tsrv); if (tu_tsrv && tu_tsrv->getDstRangeStart() != 0) { TCPUDPService *match_service = NULL; if (tu_tsrv->getSrcRangeStart() == 0) { // no source port tranlsation match_service = tu_tsrv; } else { // both source and dest port translation occurs match_service = TCPUDPService::cast( compiler->dbcopy->create(tsrv->getTypeName())); match_service->setName(tsrv->getName() + "_dport"); compiler->persistent_objects->add(match_service); match_service->setDstRangeStart(tu_tsrv->getDstRangeStart()); match_service->setDstRangeEnd(tu_tsrv->getDstRangeEnd()); } osrv = r->getOSrv(); osrv->clearChildren(); osrv->addRef(match_service); } } tdst=r->getTDst(); tdst->clearChildren(); tdst->setAnyElement(); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool NATCompiler_pf::VerifyRules::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; string version = compiler->fw->getStr("version"); RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); /* * because of the change in the nat and rdr rules syntax in * 4.7, I can no longer implement no-nat rules correctly for * this version. They dropped the "no" keyword and their * examples suggest using "pass" to implement exclusions for * the nat rules. I need no-nat rule to just not translate but * not make a decision whether the packet should be passed or * dropped. In the new PF model, translation rules are just * options on the matching policy rules and they do not offer * any keyword or option to not translate. */ if (rule->getRuleType()==NATRule::NONAT && XMLTools::version_compare(version, "4.7")>=0) { compiler->abort( rule, "No translation rules are not supported for PF 4.7, " "use negation to implement exclusions"); return true; } if (osrv->getNeg()) { compiler->abort( rule, "Negation in original service is not supported."); return true; } /* bug #1276083: "Destination NAT rules". this restriction is not * true at least as of OpenBSD 3.5 * if (rule->getRuleType()==NATRule::DNAT && osrv->isAny()) compiler->abort("Service must be specified for destination translation rule. Rule "+rule->getLabel()); */ if (rule->getRuleType()==NATRule::DNAT && osrv->isAny() && !tsrv->isAny()) { compiler->abort( rule, "Can not translate 'any' into a specific service."); return true; } if (tsrc->getNeg()) { compiler->abort( rule, "Can not use negation in translated source."); return true; } if (tdst->getNeg()) { compiler->abort( rule, "Can not use negation in translated destination."); return true; } if (tsrv->getNeg()) { compiler->abort( rule, "Can not use negation in translated service."); return true; } if (tsrv->size()!=1) { compiler->abort( rule, "Translated service should be 'Original' or should contain single object."); return true; } FWObject *o=tsrv->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if ( Group::cast(o)!=NULL) { compiler->abort( rule, "Can not use group in translated service."); return true; } #if 0 if (rule->getRuleType()==NATRule::SNAT ) { Address* o1=compiler->getFirstTSrc(rule); if ( Network::cast(o1)!=NULL || AddressRange::cast(o1)!=NULL ) compiler->abort("Can not use network or address range object in translated source. Rule "+rule->getLabel()); } #endif if (rule->getRuleType()==NATRule::SNAT ) { if (tsrc->isAny()) { compiler->abort(rule, "Source translation rule needs an address in " "Translated Source."); return true; } FWObject *o = FWReference::getObject(tsrc->front()); if (Interface::isA(o) && Interface::cast(o)->isUnnumbered()) { compiler->abort(rule, "Can not use unnumbered interface in " "Translated Source of a Source translation rule."); return true; } } if (rule->getRuleType()==NATRule::DNAT || rule->getRuleType()==NATRule::Redirect ) { if (tdst->isAny()) { compiler->abort( rule, "Destination translation rule needs an address in " "Translated Destination."); return true; } if ( tdst->size()!=1) { compiler->abort( rule, "There should be no more than one object in translated destination"); return true; } Address* o1=compiler->getFirstTDst(rule); if ( Network::cast(o1)!=NULL || AddressRange::cast(o1)!=NULL ) { compiler->abort( rule, "Can not use network or address range object in translated destination."); return true; } } if (rule->getRuleType()==NATRule::SNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstOSrc(rule)); Network *a2=Network::cast(compiler->getFirstTSrc(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated source should both be networks of the same size."); return true; } } if (rule->getRuleType()==NATRule::DNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstODst(rule)); Network *a2=Network::cast(compiler->getFirstTDst(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated destination should both be networks of the same size."); return true; } } if (rule->getRuleType()==NATRule::NATBranch ) { RuleSet *branch = rule->getBranch(); if (branch == NULL) { compiler->abort( rule, "Action 'Branch' needs NAT rule set to point to"); return true; } else { if (!NAT::isA(branch)) { compiler->abort( rule, "Action 'Branch' must point to a NAT rule set " "(points to " + branch->getTypeName() + ")"); return true; } } } tmp_queue.push_back(rule); return true; } bool NATCompiler_pf::splitOnOSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); if (osrv->size()!=1) { for(list::iterator i=osrv->begin(); i!=osrv->end(); ++i) { FWObject *o= *i; // if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementOSrv *nosrv=r->getOSrv(); nosrv->clearChildren(); nosrv->addRef( s ); tmp_queue.push_back( r ); } } else tmp_queue.push_back(rule); return true; } bool NATCompiler_pf::fillTranslatedSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); Service *osrv_o=compiler->getFirstOSrv(rule); Service *tsrv_o=compiler->getFirstTSrv(rule); if ( ! osrv_o->isAny() && tsrv_o->isAny() ) { RuleElementTSrv *tsrv=rule->getTSrv(); tsrv->addRef(osrv_o); } return true; } bool NATCompiler_pf::addVirtualAddress::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); Address *a=NULL; if (rule->getRuleType()==NATRule::SNAT) a=compiler->getFirstTSrc(rule); else if (rule->getRuleType()==NATRule::DNAT) a=compiler->getFirstODst(rule); else return true; assert(a!=NULL); const InetAddr *a_addr = a->getAddressPtr(); if ( ! a->isAny() && a->getId()!=compiler->getFwId() && a_addr) { list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); const InetAddr *iface_addr = iface->getAddressPtr(); if (iface_addr && *a_addr == *iface_addr ) return true; } compiler->osconfigurator->addVirtualAddressForNAT( a ); } return true; } bool NATCompiler_pf::splitForTSrc::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); map > interfaceGroups; for(list::iterator i=tsrc->begin(); i!=tsrc->end(); ++i) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Interface *iface = compiler->findInterfaceFor(Address::cast(o), compiler->fw); if (iface!=NULL) interfaceGroups[iface->getId()].push_back(o); } if (interfaceGroups.size()<=1) tmp_queue.push_back(rule); else { map >::iterator i; for (i=interfaceGroups.begin(); i!=interfaceGroups.end(); i++) { list &objSubset = (*i).second; RuleElementTSrc *ntsrc = NULL; NATRule *r = compiler->dbcopy->createNATRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); ntsrc=r->getTSrc(); ntsrc->clearChildren(); ntsrc->setAnyElement(); for (FWObject::iterator j=objSubset.begin(); j!=objSubset.end(); j++) { ntsrc->addRef(*j); } tmp_queue.push_back(r); } } return true; } bool NATCompiler_pf::assignInterfaceToNATRule(NATRule *rule, Address *addr) { RuleElementItfOutb *itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if (Interface::isA(addr) || IPv4::isA(addr)) { FWObject *p = addr; while ( p && ! Interface::isA(p) ) p = p->getParent(); Interface *intf = Interface::cast(p); if (intf && intf->isFailoverInterface()) { FailoverClusterGroup *fg = FailoverClusterGroup::cast( intf->getFirstByType(FailoverClusterGroup::TYPENAME)); if (fg) intf = fg->getInterfaceForMemberFirewall(fw); } if (intf && intf->isChildOf(fw)) { if ( ! itf_re->hasRef(intf)) itf_re->addRef(intf); return true; } } return false; } bool NATCompiler_pf::AssignInterface::processNext() { NATCompiler_pf *pf_comp = dynamic_cast(compiler); NATRule *rule = getNext(); if (rule==NULL) return false; if (rule->getStr(".iface") == "nil") { tmp_queue.push_back(rule); return true; } RuleElementItfOutb *itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->isAny()) { tmp_queue.push_back(rule); return true; } switch ( rule->getRuleType() ) { case NATRule::SNAT: { RuleElementTSrc *tsrc_re = rule->getTSrc(); bool have_interface = false; for (FWObject::iterator i1=tsrc_re->begin(); i1!=tsrc_re->end(); ++i1) { Address *addr = Address::cast(FWObjectReference::getObject(*i1)); have_interface |= pf_comp->assignInterfaceToNATRule(rule, addr); } if (have_interface) { tmp_queue.push_back(rule); return true; } /* if we appear here, then TSrc is not an interface or address of * an interface. Generate NAT rule without "on iface" clause */ // rule->setInterfaceStr(""); itf_re->clearChildren(); itf_re->setAnyElement(); } break; case NATRule::DNAT: { RuleElementODst *odst_re = rule->getODst(); bool have_interface = false; for (FWObject::iterator i1=odst_re->begin(); i1!=odst_re->end(); ++i1) { Address *addr = Address::cast(FWObjectReference::getObject(*i1)); have_interface |= pf_comp->assignInterfaceToNATRule(rule, addr); } if (have_interface) { tmp_queue.push_back(rule); return true; } /* if we appear here, then ODst is not an interface or address of an * interface. If this is so, just do not specify interface for rdr * rule. */ itf_re->clearChildren(); itf_re->setAnyElement(); } break; default: break; } tmp_queue.push_back(rule); return true; } /* * I assume that there is always only one object in ODst, TSrc and TDst * rule elements. This should have been assured by inspector VerifyRules */ bool NATCompiler_pf::ReplaceFirewallObjectsODst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); list cl; RuleElementODst *rel; Address *obj=NULL; rel = rule->getODst(); assert(rel); obj =compiler->getFirstODst(rule); assert(obj); if (obj->getId()==compiler->getFwId() ) { list l2 = compiler->fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *interface_ = Interface::cast(*i); /* * update 03/20/03: * * generally we assume that if firewall object is used in the rule, * then any or all its interface will be used. This means that if * firewall is in ODst we should really use all of its interfaces, not * only external ones. */ if (! interface_->isLoopback() ) cl.push_back(interface_); } if ( ! cl.empty() ) { rel->clearChildren(); for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) { rel->addRef( *i1 ); } } /* * update for ticket 1397 If firewall object is in ODst, do not assign * the rule to any interface. I use attribute ".iface" to signal * AssignInterface that it should not do anything. */ rule->setStr(".iface", "nil"); } return true; } /* * I assume that there is always only one object in ODst, TSrc and TDst * rule elements. This should have been assured by inspector VerifyRules */ bool NATCompiler_pf::ReplaceFirewallObjectsTSrc::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); list cl; RuleElementTSrc *rel; Address *obj=NULL; switch (rule->getRuleType()) { case NATRule::Masq: return true; default: rel=rule->getTSrc(); assert(rel); obj=compiler->getFirstTSrc(rule); assert(obj); if (obj->getId()==compiler->getFwId() ) { Address *odst=compiler->getFirstODst(rule); rel->clearChildren(); Interface *iface=compiler->findInterfaceFor(odst,compiler->fw); if (!odst->isAny() && !rule->getODst()->getNeg() && iface!=NULL) rel->addRef(iface); else // else use all interfaces except loopback and unnumbered ones { list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=Interface::cast(*i); if (! iface->isLoopback() && ! iface->isUnnumbered() && ! iface->isBridgePort()) rel->addRef( *i ); } for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) rel->addRef( *i1 ); /* it is an error if rule element is empty at this point. this could have * happened if all external interfaces are unnumbered */ if (rel->size()==0) { QString err( "Could not find suitable interface for the NAT rule %1. " "Perhaps all interfaces are unnumbered?"); compiler->abort( rule, err.arg(rule->getLabel().c_str()).toStdString()); } } } } return true; } /* * I assume that there is always only one object in ODst, TSrc and TDst * rule elements. This should have been assured by inspector VerifyRules */ bool NATCompiler_pf::ReplaceObjectsTDst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; NATCompiler_pf *pf_comp=dynamic_cast(compiler); tmp_queue.push_back(rule); if (rule->getRuleType()==NATRule::Redirect) { Service *tsrv=compiler->getFirstTSrv(rule); RuleElementTDst *rel=rule->getTDst(); assert(rel); Address *otdst=compiler->getFirstTDst(rule); Interface *loopback=NULL; FWObject *loopback_address=NULL; /* if firewall is used in TDst in redirection rule, replace it with * its loopback interface */ if (otdst->getId()==compiler->fw->getId()) { std::list l2=compiler->fw->getByType(Interface::TYPENAME); for (std::list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = dynamic_cast(*i); assert(iface); if (iface->isLoopback()) { loopback = iface; loopback_address = loopback->getFirstByType(IPv4::TYPENAME); } } if (loopback_address==NULL) { compiler->abort(rule, "Can not configure redirection for the NAT rule " "because loopback interface is missing."); } rel->clearChildren(); rel->addRef( loopback_address ); pf_comp->redirect_rules.push_back( redirectRuleInfo( rule->getLabel(), otdst, loopback_address, tsrv ) ); } } return true; } bool NATCompiler_pf::swapAddressTableObjectsInRE::processNext() { NATCompiler_pf *pf_comp=dynamic_cast(compiler); Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); list cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); /* * All addressTable objects will be run-time here because we * switch them in preprocessor. The difference is: if address * table was originally run-time, at this point it will have * no children, however if it was compile-time originally, it * will have children objects. That is how we distinguish * them in this rule processor. Here we only deal with * AddressTable objects that originally used to be * compile-time because we need to create tables for them. */ if (AddressTable::cast(o)!=NULL && AddressTable::cast(o)->isRunTime() && o->size() > 0) cl.push_back(MultiAddress::cast(o)); } if (!cl.empty()) { for (list::iterator i=cl.begin(); i!=cl.end(); i++) { MultiAddress *atbl = *i; // Need to make sure the ID of the MultiAddressRunTime // object created here is stable and is always the same // for the same MultiAddress object. In particular this // ensures that we reuse tables between policy and NAT rules string mart_id_str = FWObjectDatabase::getStringId(atbl->getId()) + "_runtime"; int mart_id = FWObjectDatabase::registerStringId(mart_id_str); MultiAddressRunTime *mart = MultiAddressRunTime::cast(compiler->dbcopy->findInIndex(mart_id)); if (mart==NULL) { mart = new MultiAddressRunTime(atbl); // need to ensure stable ID for the runtime object, so // that when the same object is replaced in different // rulesets by different compiler passes, chosen // runtime object has the same ID and is identified as // the same by the compiler. mart->setId( mart_id ); compiler->dbcopy->addToIndex(mart); compiler->persistent_objects->add(mart); // register this object as a table string tblname = atbl->getName(); string tblID = tblname + "_addressTableObject"; pf_comp->tables->registerTable(tblname,tblID,atbl); } re->removeRef(atbl); re->addRef(mart); } tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } bool NATCompiler_pf::processMultiAddressObjectsInRE::processNext() { NATCompiler_pf *pf_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); bool neg = re->getNeg(); list cl; try { for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { if (re->size()>1 && neg) { string err = "AddressTable object can not be used with " "negation in combination with other objects " "in the same rule element."; compiler->abort(rule, err); } o->setBool("pf_table",true); string tblname = o->getName(); string tblID = tblname + "_addressTableObject"; pf_comp->tables->registerTable(tblname,tblID,o); cl.push_back(o); } } } catch(FWException &ex) // TableFactory::registerTable throws exception { string err; err = "Can not process MultiAddress object in rule " + rule->getLabel() + ". Error: " + ex.toString(); compiler->abort(rule, err); } if (!cl.empty()) { RuleElement *nre; for (FWObject::iterator i=cl.begin(); i!=cl.end(); i++) { NATRule *r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( *i ); tmp_queue.push_back(r); } for (FWObject::iterator i=cl.begin(); i!=cl.end(); i++) re->removeRef( *i ); if (!re->isAny()) tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } void NATCompiler_pf::checkForDynamicInterfacesOfOtherObjects::findDynamicInterfaces(RuleElement *re, Rule *rule) { if (re->isAny()) return; list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs = Interface::cast(obj); if (ifs && Cluster::isA(ifs->getParent())) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( ifs->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *member_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(member_iface); if (member_iface->isChildOf(compiler->fw)) { ifs = member_iface; break; } } } } if (ifs && ifs->isDyn() && ! ifs->isChildOf(compiler->fw)) { QString err( "Can not build rule using dynamic interface '%1' " "of the object '%2' because its address is unknown."); compiler->abort( rule, err .arg(ifs->getName().c_str()) .arg(ifs->getParent()->getName().c_str()).toStdString()); } } } bool NATCompiler_pf::checkForDynamicInterfacesOfOtherObjects::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; findDynamicInterfaces( rule->getOSrc() , rule ); findDynamicInterfaces( rule->getODst() , rule ); findDynamicInterfaces( rule->getTSrc() , rule ); findDynamicInterfaces( rule->getTDst() , rule ); tmp_queue.push_back(rule); return true; } bool NATCompiler_pf::createTables::processNext() { NATCompiler_pf *pf_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrc=rule->getOSrc(); RuleElementODst *odst=rule->getODst(); if (osrc->size()!=1) pf_comp->tables->createTablesForRE(osrc,rule); if (odst->size()!=1) pf_comp->tables->createTablesForRE(odst,rule); #if 0 RuleElementTSrc *tsrc=rule->getTSrc(); RuleElementTDst *tdst=rule->getTDst(); if (tsrc->size()!=1) pf_comp->tables->createTablesForRE(tsrc,rule); if (tdst->size()!=1) pf_comp->tables->createTablesForRE(tdst,rule); #endif tmp_queue.push_back(rule); return true; } void NATCompiler_pf::compile() { bool manage_virtual_addr=fwopt->getBool("manage_virtual_addr"); string banner = " Compiling NAT rules for " + fw->getName(); if (!getRuleSetName().empty()) banner += " ruleset " + getRuleSetName(); if (ipv6) banner += ", IPv6"; info(banner); Compiler::compile(); add( new Begin()); add( new printTotalNumberOfRules() ); add( new singleRuleFilter()); add(new expandGroupsInItfOutb("expand groups in Interface")); add(new replaceClusterInterfaceInItfOutb( "replace cluster interfaces with member interfaces in " "the Interface rule element")); add(new singleObjectNegationItfOutb( "process single object negation in inbound Itf")); add(new ItfOutbNegation("process negation in Itf")); add( new recursiveGroupsInOSrc("check for recursive groups in OSRC") ); add( new recursiveGroupsInODst("check for recursive groups in ODST") ); add( new recursiveGroupsInOSrv("check for recursive groups in OSRV") ); add( new recursiveGroupsInTSrc("check for recursive groups in TSRC") ); add( new recursiveGroupsInTDst("check for recursive groups in TDST") ); add( new recursiveGroupsInTSrv("check for recursive groups in TSRV") ); add( new emptyGroupsInOSrc( "check for empty groups in OSRC" ) ); add( new emptyGroupsInODst( "check for empty groups in ODST" ) ); add( new emptyGroupsInOSrv( "check for empty groups in OSRV" ) ); add( new emptyGroupsInTSrc( "check for empty groups in TSRC" ) ); add( new emptyGroupsInTDst( "check for empty groups in TDST" ) ); add( new emptyGroupsInTSrv( "check for empty groups in TSRV" ) ); if (fw->getOptionsObject()->getBool("preserve_group_names")) { add(new RegisterGroupsAndTablesInOSrc( "register object groups and tables in OSrc")); add(new RegisterGroupsAndTablesInODst( "register object groups and tables in ODst")); } add( new ExpandGroups( "expand groups" ) ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new eliminateDuplicatesInOSRC( "eliminate duplicates in OSRC") ); add( new eliminateDuplicatesInODST( "eliminate duplicates in ODST") ); add( new eliminateDuplicatesInOSRV( "eliminate duplicates in OSRV") ); add( new swapMultiAddressObjectsInOSrc( " swap MultiAddress -> MultiAddressRunTime in OSrc") ); add( new swapMultiAddressObjectsInODst( " swap MultiAddress -> MultiAddressRunTime in ODst") ); add( new swapMultiAddressObjectsInTSrc( " swap MultiAddress -> MultiAddressRunTime in TSrc") ); add( new swapMultiAddressObjectsInTDst( " swap MultiAddress -> MultiAddressRunTime in TDst") ); add( new swapAddressTableObjectsInOSrc( "AddressTable -> MultiAddressRunTime in OSrc") ); add( new swapAddressTableObjectsInODst( "AddressTable -> MultiAddressRunTime in ODst") ); add( new swapAddressTableObjectsInTSrc( "AddressTable -> MultiAddressRunTime in TSrc") ); add( new swapAddressTableObjectsInTDst( "AddressTable -> MultiAddressRunTime in TDst") ); add( new processMultiAddressObjectsInOSrc( "process MultiAddress objects in OSrc") ); add( new processMultiAddressObjectsInODst( "process MultiAddress objects in ODst") ); add( new processMultiAddressObjectsInTSrc( "process MultiAddress objects in TSrc") ); add( new processMultiAddressObjectsInTDst( "process MultiAddress objects in TDst") ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new splitOnOSrv( "split rule on original service" ) ); add( new fillTranslatedSrv( "fill translated service" ) ); //add( new doOSrcNegation( "process negation in OSrc" ) ); //add( new doODstNegation( "process negation in ODst" ) ); //add( new doOSrvNegation( "process negation in OSrv" ) ); add( new NATRuleType( "determine NAT rule types" ) ); add( new splitSDNATRule("split SDNAT rules" ) ); add( new NATRuleType( "determine NAT rule types" ) ); add( new VerifyRules( "verify NAT rules" ) ); add( new ReplaceFirewallObjectsODst( "replace references to the firewall in ODst" ) ); add( new ReplaceFirewallObjectsTSrc( "replace references to the firewall in TSrc" ) ); add( new ReplaceObjectsTDst( "replace objects in TDst" ) ); add( new ExpandMultipleAddresses( "expand multiple addresses" ) ); // we might get empty RE after expanding multiple addresses, // for example when unnumbered interface is used in TSRC. Note // that VerifyRules should not allow this, but we may still // get here in the test mode. Calling dropRuleWithEmptyRE works // as a fail-safe and prevents crash. add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); if ( manage_virtual_addr ) add( new addVirtualAddress("add virtual addresses for NAT rules")); add( new checkForUnnumbered("check for unnumbered interfaces" ) ); add( new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls")); add( new ExpandAddressRanges( "expand address range objects" ) ); add( new splitForTSrc( "split if addresses in TSrc belong to different networks" )); add( new AssignInterface( "assign rules to interfaces" ) ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new createTables("create tables")); // add( new PrintTables( "print tables" ) ); add( new PrintRule("generate pf code") ); add( new simplePrintProgress() ); runRuleProcessors(); } void NATCompiler_pf::epilog() { } NATCompiler_pf::~NATCompiler_pf() { //if (tables) tables->detach(); } fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipf.cpp0000644000175000017500000004712211733011756023163 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_ipf.h" #include "fwcompiler/Compiler.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_ipf::myPlatformName() { return "ipf"; } int PolicyCompiler_ipf::prolog() { int n= PolicyCompiler_pf::prolog(); anytcp = dbcopy->createTCPService(); anytcp->setId(FWObjectDatabase::generateUniqueId()); //ANY_TCP_OBJ_ID); persistent_objects->add(anytcp,false); anyudp=dbcopy->createUDPService(); anyudp->setId(FWObjectDatabase::generateUniqueId()); //ANY_UDP_OBJ_ID); persistent_objects->add(anyudp,false); anyicmp=dbcopy->createICMPService(); anyicmp->setId(FWObjectDatabase::generateUniqueId()); //ANY_ICMP_OBJ_ID); persistent_objects->add(anyicmp,false); return n; } bool PolicyCompiler_ipf::expandAnyService::processNext() { PolicyCompiler_ipf *pcomp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv=rule->getSrv(); FWOptions *ruleopt =rule->getOptionsObject(); if (srv->isAny() && ! ruleopt->getBool("stateless") && rule->getAction()==PolicyRule::Accept) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anyicmp); //compiler->dbcopy->findInIndex(ANY_ICMP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anytcp); //compiler->dbcopy->findInIndex(ANY_TCP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anyudp); //compiler->dbcopy->findInIndex(ANY_UDP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); FWOptions *ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipf::doSrcNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *src=rule->getSrc(); if (src->getNeg()) { RuleElementSrc *nsrc; PolicyRule *r; FWOptions *ruleopt; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Continue); r->setLogging(false); nsrc=r->getSrc(); nsrc->setNeg(false); r->setBool("quick",false); r->setBool("skip_check_for_duplicates",true); ruleopt = r->getOptionsObject(); ruleopt->setBool("stateless", true); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getSrc(); nsrc->setNeg(false); nsrc->clearChildren(); nsrc->setAnyElement(); r->setBool("quick",true); r->setBool("skip_check_for_duplicates",true); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipf::doDstNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementDst *dst=rule->getDst(); if (dst->getNeg()) { RuleElementDst *ndst; PolicyRule *r; FWOptions *ruleopt; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Continue); r->setLogging(false); ndst=r->getDst(); ndst->setNeg(false); r->setBool("quick",false); r->setBool("skip_check_for_duplicates",true); ruleopt = r->getOptionsObject(); ruleopt->setBool("stateless", true); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst=r->getDst(); ndst->setNeg(false); ndst->clearChildren(); ndst->setAnyElement(); r->setBool("quick",true); r->setBool("skip_check_for_duplicates",true); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipf::doSrvNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv=rule->getSrv(); if (srv->getNeg()) { compiler->abort(rule, "Negation in Srv is not implemented"); return false; } tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipf::specialCaseWithDynInterface::dropDynamicInterface(RuleElement *re) { list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs =Interface::cast( obj ); if (ifs!=NULL && !ifs->isRegular()) continue; cl.push_back(obj); } if (!cl.empty()) { re->clearChildren(); for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->addRef( (*i1) ); } } bool PolicyCompiler_ipf::specialCaseWithDynInterface::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; dropDynamicInterface( rule->getDst() ); dropDynamicInterface( rule->getSrc() ); tmp_queue.push_back(rule); return true; } PolicyCompiler_ipf::calculateSkip::calculateSkip(const std::string &n) : PolicyRuleProcessor(n) { } bool PolicyCompiler_ipf::calculateSkip::processNext() { // PolicyRule *rule; slurp(); if (tmp_queue.size()==0) return false; /* * first, we scan all rules and build a hash that maps attribute * "skip_label" to rule number. Attribute "skip_label" is set in * optimize1, after which we could have split some rules, so this * attrbiute may not be unique. We want to skip to the first rule * marked with the same skip label if there are few with the same * label. The simplest way to find the first one with the same label * is to scan rules in reverse order, that is from the bottom up. */ int N=tmp_queue.size()-1; // The last rule number is N for (deque::reverse_iterator k=tmp_queue.rbegin(); k!=tmp_queue.rend(); ++k) { PolicyRule *r = PolicyRule::cast( *k ); if (!r->getStr("skip_label").empty()) allrules[r->getStr("skip_label")]=N; r->setInt("rule_num",N); N--; } for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { PolicyRule *r = PolicyRule::cast( *k ); string rl=r->getLabel(); int current_position=r->getPosition(); if (r->getAction()==PolicyRule::Skip) { assert(!r->getStr("skip_to").empty()); int to=allrules[r->getStr("skip_to")]; int n =r->getInt("rule_num"); r->setInt("no_to_skip",to-n-1); } /* Action 'Continue' means we need to jump to the next rule in the * GUI. We scan rules down from the current one, looking for the first * rule that corresponds to the next rule in the GUI. */ if (r->getAction()==PolicyRule::Continue) { r->setAction(PolicyRule::Skip); r->setBool("quick",false); deque::iterator j=k; ++j; int n=0; for ( ; j!=tmp_queue.end(); ++j) { PolicyRule *r2 = PolicyRule::cast( *j ); if (r2->getPosition()!=current_position) break; /* 'skip' only skips rules with the same setting of 'in' or 'out', * that is the same direction */ if (r2->getDirection()==r->getDirection()) ++n; } r->setInt("no_to_skip",n); } } return true; } bool PolicyCompiler_ipf::checkForKeepState::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); Service *srv=compiler->getFirstSrv(rule); assert(srv); FWOptions *ruleopt =rule->getOptionsObject(); if (! ICMPService::isA(srv) && ! UDPService::isA(srv) && ! TCPService::isA(srv) ) ruleopt->setBool("stateless",true); return true; } bool PolicyCompiler_ipf::eliminateDuplicateRules::processNext() { PolicyCompiler *pcomp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; // Note that if rule has "any" in Interface column, it is // implemented as reference to the AnyNetwork object. In this case // Compiler::getFirstItf() returns NULL. Interface *intf_rule = compiler->getFirstItf(rule); int intf_id_rule = (intf_rule) ? intf_rule->getId() : -1; if ( ! rule->getBool("skip_check_for_duplicates")) { for (deque::iterator i=rules_seen_so_far.begin(); i!=rules_seen_so_far.end(); ++i) { PolicyRule *r=(*i); if (r->getBool("skip_check_for_duplicates") ) continue; if (r->getAction()==PolicyRule::Continue || r->getAction()==PolicyRule::Skip) continue; Interface *intf_r = compiler->getFirstItf(r); int intf_id_r = (intf_r) ? intf_r->getId() : -1; if (intf_id_r==intf_id_rule && r->getAction()==rule->getAction() && r->getLogging()==rule->getLogging() && pcomp->cmpRules(*r,*rule) ) { // cout << "---------------------------------------" << endl; // cout << pcomp->debugPrintRule(r) << endl; // cout << pcomp->debugPrintRule(rule) << endl; return true; } } } tmp_queue.push_back(rule); rules_seen_so_far.push_back(rule); return true; } bool PolicyCompiler_ipf::processMultiAddressObjectsInRE::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) compiler->abort( rule, "Run-time AddressTable objects are not supported."); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipf::SplitDirectionIpfilter::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getDirection()==PolicyRule::Both) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection(PolicyRule::Inbound); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection(PolicyRule::Outbound); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipf::compile() { info(" Compiling policy for " + fw->getName()); Compiler::compile(); bool check_for_recursive_groups=true; if ( fw->getOptionsObject()->getBool ("check_shading") && ! inSingleRuleCompileMode()) { add( new Begin ("Detecting rule shadowing" ) ); add( new printTotalNumberOfRules( ) ); add( new ItfNegation("process negation in Itf" ) ); add( new InterfacePolicyRules( "process interface policy rules and store interface ids")); add( new recursiveGroupsInSrc("check for recursive groups in SRC")); add( new recursiveGroupsInDst("check for recursive groups in DST")); add( new recursiveGroupsInSrv("check for recursive groups in SRV")); check_for_recursive_groups=false; add( new ExpandGroups("expand groups") ); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC") ); add( new eliminateDuplicatesInDST("eliminate duplicates in DST") ); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV") ); add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src") ); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst") ); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC" ) ); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST" ) ); add( new ConvertToAtomic("convert to atomic rules" ) ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new DetectShadowing("Detect shadowing" ) ); add( new simplePrintProgress() ); runRuleProcessors(); deleteRuleProcessors(); } add( new Begin()); add( new printTotalNumberOfRules() ); add( new singleRuleFilter()); // add( new MACFiltering( "verify for MAC address filtering" ) ); add( new setQuickFlag("set 'quick' flag") ); if (check_for_recursive_groups) { add( new recursiveGroupsInSrc("check for recursive groups in SRC")); add( new recursiveGroupsInDst("check for recursive groups in DST")); add( new recursiveGroupsInSrv("check for recursive groups in SRV")); } add( new emptyGroupsInSrc("check for empty groups in SRC") ); add( new emptyGroupsInDst("check for empty groups in DST") ); add( new emptyGroupsInSrv("check for empty groups in SRV") ); add( new ItfNegation("process negation in Itf" ) ); add( new InterfacePolicyRules( "process interface policy rules and store interface ids") ); add( new doSrcNegation("process negation in Src") ); add( new doDstNegation("process negation in Dst") ); add( new doSrvNegation("process negation in Srv") ); add( new ExpandGroups( "expand groups") ); add( new CheckForTCPEstablished( "check for TCPService objects with flag \"established\"") ); add( new CheckForUnsupportedUserService("check for user service") ); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC") ); add( new eliminateDuplicatesInDST("eliminate duplicates in DST") ); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV") ); add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src") ); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst") ); add( new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src") ); add( new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst") ); add( new splitIfFirewallInSrc("split rule if firewall is in Src") ); add( new splitIfFirewallInDst("split rule if firewall is in Dst") ); add( new fillDirection("determine directions") ); add( new SplitDirectionIpfilter("split rules with direction 'both'" ) ); add( new ExpandMultipleAddresses( "expand objects with multiple addresses") ); add( new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls" )); add( new MACFiltering("verify for MAC address filtering" ) ); add( new checkForUnnumbered("check for unnumbered interfaces") ); add( new specialCaseWithDynInterface( "check for a special cases with dynamic interface") ); add( new addressRanges("expand address range objects") ); add( new groupServicesByProtocol("split rules with different protocols") ); add( new separateTCPWithFlags("separate TCP services with flags" ) ); add( new separateSrcPort("split on TCP and UDP with source ports")); add( new verifyCustomServices( "verify custom services for this platform") ); add( new SpecialServices("check for special services" ) ); add( new expandAnyService("expand ANY service for stateful rules") ); /* * it may make sense to do optimization even before we expand groups * (before ExpandGroups). Need to test this idea. */ if ( fw->getOptionsObject()->getBool ("optimize") ) { add( new optimizeSrc("optimization in SRC") ); add( new optimizeDst("optimization in DST") ); add( new optimizeSrv("optimization in SRV") ); } add( new ConvertToAtomic("convert to atomic rules") ); add( new checkForZeroAddr("check for zero addresses" ) ); if ( fw->getOptionsObject()->getBool ("eliminate_duplicates") ) add( new eliminateDuplicateRules("eliminate duplicate rules" ) ); add( new calculateSkip("calculate argument for skip") ); add( new checkForKeepState("check for 'keep state'") ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new PrintRule("generate ipf code") ); add( new simplePrintProgress() ); runRuleProcessors(); } string PolicyCompiler_ipf::debugPrintRule(Rule *r) { PolicyRule *rule=PolicyRule::cast(r); // FWOptions *ruleopt =rule->getOptionsObject(); ostringstream s; s << PolicyCompiler::debugPrintRule(rule) << " "; RuleElementItf *intf_re = rule->getItf(); string rule_interfaces; int intf_count = 0; for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it) { FWObject *o = *it; if (FWReference::cast(o)!=NULL) o = FWReference::cast(o)->getPointer(); rule_interfaces += " " + o->getName(); intf_count++; } if (intf_count > 0) { s << " intf: "; if (intf_count > 1) s << "{ "; s << rule_interfaces; if (intf_count > 1) s << " }"; } else s << " intf: ?"; s << " "; if (r->getBool("skip_check_for_duplicates")) s << "skip_check_for_duplicates "; if (r->getStr("skip_label")!="") s << "skip_label: " << r->getStr("skip_label") << " "; if (r->getStr("skip_to")!="") s << "skip_to: " << r->getStr("skip_to") << " "; if (r->getInt("no_to_skip")!=-1) s << "no_to_skip: " << r->getInt("no_to_skip"); s << " " << FWObjectDatabase::getStringId(r->getId()) << " (" << r->getId() << ")"; return s.str(); } void PolicyCompiler_ipf::epilog() { } fwbuilder-5.1.0.3599/src/pflib/NATCompiler_ipfw_writers.cpp0000644000175000017500000000254211733011756024311 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_ipfw.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_bsd_interfaces.cpp0000644000175000017500000005712311733011756025334 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "Configlet.h" #include "OSConfigurator_bsd.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_bsd::configureInterfaces() { FWOptions* options = fw->getOptionsObject(); // Update vlans first because we may need to update ip addresses // on vlan interfaces later if ( options->getBool("configure_vlan_interfaces") ) { // http://blog.scottlowe.org/2007/08/31/vlan-interfaces-with-openbsd-41/ // ifconfig vlan vlandev QStringList all_physical_interfaces; QMap parent_interfaces; QMap > vlans; QStringList all_vlan_interfaces; // all vlan interfaces FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); QString iface_name = iface->getName().c_str(); parent_interfaces[iface_name] = iface; all_physical_interfaces << iface_name; FWObjectTypedChildIterator si=iface->findByType(Interface::TYPENAME); for ( ; si!=si.end(); ++si ) { Interface *subinterface = Interface::cast(*si); assert(subinterface); if (subinterface->getOptionsObject()->getStr("type") == "8021q") { vlans[iface_name].push_back(subinterface); all_vlan_interfaces << subinterface->getName().c_str(); } } } // sort interfaces by name all_vlan_interfaces.sort(); all_physical_interfaces.sort(); // issue sync_vlan_interfaces command even if there are no vlans // since it deletes them on the firewall if they exist summaryConfigLineVlan(all_vlan_interfaces); foreach (QString iface_name, all_physical_interfaces) { Interface *iface = parent_interfaces[iface_name]; list vlan_subinterfaces = vlans[iface_name]; if (vlan_subinterfaces.size() > 0) interfaceConfigLineVlan(iface, vlan_subinterfaces); } } if (options->getBool("configure_bridge_interfaces")) { list all_bridges = fw->getInterfacesByType("bridge"); QStringList all_bridge_interfaces; QMap bridge_interfaces_by_name; QMap bridge_ports; for (list::iterator it=all_bridges.begin(); it!=all_bridges.end(); ++it) { Interface *iface = Interface::cast(*it); assert(iface); QString iface_name = iface->getName().c_str(); all_bridge_interfaces << iface_name; bridge_interfaces_by_name[iface_name] = iface; FWObjectTypedChildIterator si = iface->findByType(Interface::TYPENAME); for ( ; si!=si.end(); ++si ) { Interface *subinterface = Interface::cast(*si); assert(subinterface); bridge_ports[iface_name] << subinterface->getName().c_str(); } } // sort interfaces by name all_bridge_interfaces.sort(); summaryConfigLineBridge(all_bridge_interfaces); foreach (QString iface_name, all_bridge_interfaces) { Interface *iface = bridge_interfaces_by_name[iface_name]; if (bridge_ports.size() > 0) interfaceConfigLineBridge(iface, bridge_ports[iface_name]); } } if ( options->getBool("configure_carp_interfaces") ) { /* * Compiler::processFailoverGroup copies interfaces of the cluster to * the member firewall objects. This means when we scan interfaces of * the firewall here, we get both its normal interfaces and a copy of * cluster interfaces. * */ QStringList carp_interfaces; QMap carp_interfaces_by_name; QMap failover_groups; FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); QString iface_name = iface->getName().c_str(); if ( ! iface->isFailoverInterface()) continue; FWObject *failover_group = iface->getFirstByType(FailoverClusterGroup::TYPENAME); if (failover_group && failover_group->getStr("type") == "carp") { carp_interfaces << iface_name; carp_interfaces_by_name[iface_name] = iface; failover_groups[iface_name] = failover_group; } } // sort interfaces by name carp_interfaces.sort(); // issue "sync_carp_interfaces" call even when we have none, it will // delete those that might exist on the firewall summaryConfigLineCARP(carp_interfaces); foreach (QString iface_name, carp_interfaces) { Interface *iface = carp_interfaces_by_name[iface_name]; FWObject* failover_group = failover_groups[iface_name]; interfaceConfigLineCARP(iface, failover_group); } } if ( options->getBool("configure_interfaces") ) { std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( fw->getStr("host_OS"))); list all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); all_interfaces.sort(); QStringList configure_intf_commands; QStringList intf_names; QStringList ipv6_names; QStringList all_names; QMap > > all_addresses; QMap interfaces_by_name; for (list::iterator i=all_interfaces.begin(); i != all_interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); QString iface_name = iface->getName().c_str(); interfaces_by_name[iface_name] = iface; all_names << iface_name; QStringList update_addresses; QStringList ignore_addresses; if (int_prop->manageIpAddresses(iface, update_addresses, ignore_addresses)) { // unfortunately addresses in update_addresses are in // the form of address/masklen but OpenBSD ifconfig // uses hex netmask representation and so should we. // Will ignore update_addresses and ignore_addresses and // build our own list here. Returned value of manageIpAddresses() // is useful though. list all_addr = iface->getByType(IPv4::TYPENAME); list all_ipv6 = iface->getByType(IPv6::TYPENAME); all_addr.insert(all_addr.begin(), all_ipv6.begin(), all_ipv6.end()); bool have_ipv6 = false; const InetAddr *netmask = iface->getNetmaskPtr(); list > iface_all_addresses; for (list::iterator j = all_addr.begin(); j != all_addr.end(); ++j) { Address *iaddr = Address::cast(*j); const InetAddr *ipaddr = iaddr->getAddressPtr(); const InetAddr *ipnetm = iaddr->getNetmaskPtr(); iface_all_addresses.push_back( pair(*ipaddr, *ipnetm)); if (ipaddr->isV6()) have_ipv6 = true; } set::iterator it; for (it=virtual_addresses.begin(); it!=virtual_addresses.end(); ++it) { const Address *addr = Address::constcast(dbcopy->findInIndex(*it)); const InetAddr *ipaddr = addr->getAddressPtr(); FWObject *iaddr = findAddressFor(addr, fw ); if (iaddr!=NULL) { Interface *iface_2 = Interface::cast(iaddr->getParent()); if (iface_2 == iface) { iface_all_addresses.push_back( pair(*ipaddr, *netmask)); if (ipaddr->isV6()) have_ipv6 = true; } } } // see #2032. About interfaces with no addresses: // // - when we generate rc.conf file, we should add line // "ifconfig_em0="DHCP"" for dynamic interfaces, so we should // include them in the management list as well. // // Note that int_prop returns false for dynamic interfaces on // OpenBSD because we do not support rc.conf format for it atm // and should not try to manage dynamic interfaces in the shell // script format. // intf_names << iface_name; if (have_ipv6) ipv6_names << iface_name; all_addresses[iface_name] = iface_all_addresses; } } // sort interfaces by name all_names.sort(); // remove duplicates. We get duplicates in all_names when an // interface appears twice, once as a bridge port and another time as // vlan parent interface // // Note that QStringList::removeDuplicates() is only available in Qt 4.5 // all_names.removeDuplicates(); QStringList deduplicated_names; QString prev; foreach(QString name, all_names) { if (name != prev) deduplicated_names << name; prev = name; } all_names = deduplicated_names; ipv6_names.sort(); intf_names.sort(); summaryConfigLineIP(ipv6_names, true); summaryConfigLineIP(intf_names, false); foreach (QString iface_name, all_names) { interfaceConfigLineIP(interfaces_by_name[iface_name], all_addresses[iface_name]); } for (list::iterator i=all_interfaces.begin(); i != all_interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); interfaceIfconfigLine(iface); } } if ( options->getBool("configure_pfsync_interfaces") ) { bool have_pfsync_interfaces = false; QStringList pfsync_output; FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if ( ! iface->getOptionsObject()->getBool("state_sync_group_member")) continue; int state_sync_group_id = FWObjectDatabase::getIntId( iface->getOptionsObject()->getStr("state_sync_group_id")); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast(dbcopy->findInIndex(state_sync_group_id)); assert(state_sync_group!=NULL); // Interface can be state sync group member, but of a different type if (state_sync_group->getStr("type") != "pfsync") continue; have_pfsync_interfaces = true; summaryConfigLinePfsync(have_pfsync_interfaces); interfaceConfigLinePfsync(iface, state_sync_group); break; } if (!have_pfsync_interfaces) summaryConfigLinePfsync(false); } return printAllInterfaceConfigurationLines().toStdString(); } void OSConfigurator_bsd::interfaceIfconfigLine(Interface *iface) { QString iface_name = iface->getName().c_str(); Configlet configlet(fw, "bsd", "ifconfig_interface"); QString config_lines = interfaceIfconfigLineInternal(iface, &configlet); if (!config_lines.isEmpty()) interface_configuration_lines[iface_name] << config_lines; } /* * If user configured mtu and free-form ifconfig options in the GUI, * add ifconfig command to execute them. * * TODO: Add a checkbox "up" in interface dialog, it should be on by * default. */ QString OSConfigurator_bsd::interfaceIfconfigLineInternal(Interface *iface, Configlet *configlet) { QString iface_name = iface->getName().c_str(); configlet->removeComments(); configlet->collapseEmptyStrings(true); configlet->setVariable("interface_name", iface_name); FWOptions *ifopt = iface->getOptionsObject(); assert(ifopt != NULL); bool need_additional_ifconfig = false; QStringList ifconfig_options; if (ifopt->getBool("iface_configure_mtu") && ifopt->getInt("iface_mtu") > 0) { configlet->setVariable("have_mtu", true); configlet->setVariable("mtu", ifopt->getInt("iface_mtu")); need_additional_ifconfig = true; } else { configlet->setVariable("have_mtu", false); configlet->setVariable("mtu", ""); } QString options; if (!ifopt->getStr("iface_options").empty()) { options = ifopt->getStr("iface_options").c_str(); need_additional_ifconfig = true; } configlet->setVariable("options", options.simplified()); if (need_additional_ifconfig) return configlet->expand(); return ""; } void OSConfigurator_bsd::summaryConfigLineIP(QStringList , bool ) { } void OSConfigurator_bsd::interfaceConfigLineIP( Interface *iface, list > all_addresses) { if (iface->isDyn()) return; QStringList arg1; arg1 << iface->getName().c_str(); for (list >::iterator j = all_addresses.begin(); j != all_addresses.end(); ++j) { InetAddr ipaddr = j->first; InetAddr ipnetm = j->second; if (ipaddr.isV6()) arg1.push_back(QString("%1/%2").arg(ipaddr.toString().c_str()) .arg(ipnetm.getLength())); else { /* on OpenBSD ifconfig prints netmask of ipv4 addresses in hex # ifconfig em0 em0: flags=8843 mtu 1500 lladdr 00:0c:29:83:4d:2f media: Ethernet autoselect (1000baseT full-duplex,master) status: active inet 10.1.1.50 netmask 0xffffff00 broadcast 10.1.1.255 inet6 fe80::20c:29ff:fe83:4d2f%em0 prefixlen 64 scopeid 0x2 */ int nbits = ipnetm.getLength(); uint32_t netm = 0; while (nbits) { netm = netm >> 1; netm |= 1<<31; nbits--; } arg1 << QString("%1/0x%2") .arg(ipaddr.toString().c_str()).arg(netm, -8, 16); } } QString cmd = QString("update_addresses_of_interface \"%1\" \"\"") .arg(arg1.join(" ")); interface_configuration_lines[iface->getName().c_str()] << cmd; } void OSConfigurator_bsd::summaryConfigLineVlan(QStringList vlan_names) { interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("sync_vlan_interfaces %1").arg(vlan_names.join(" ")); } void OSConfigurator_bsd::interfaceConfigLineVlan( Interface *iface, const list &vlan_subinterfaces) { QStringList vlan_names; list::const_iterator it; for (it=vlan_subinterfaces.begin(); it!=vlan_subinterfaces.end(); ++it) { QString vlan_intf_name = (*it)->getName().c_str(); int vlan_id = (*it)->getOptionsObject()->getInt("vlan_id"); vlan_names << QString("%1:%2").arg(vlan_intf_name).arg(vlan_id); } interface_configuration_lines[iface->getName().c_str()] << QString("update_vlans_of_interface \"%1 %2\"") .arg(iface->getName().c_str()) .arg(vlan_names.join(" ")); } void OSConfigurator_bsd::summaryConfigLineBridge(QStringList bridge_names) { interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("sync_bridge_interfaces %1").arg(bridge_names.join(" ")); } void OSConfigurator_bsd::interfaceConfigLineBridge(Interface *iface, QStringList bridge_port_names) { QString iface_name = iface->getName().c_str(); FWOptions *ifopt = iface->getOptionsObject(); assert(ifopt != NULL); bool enable_stp = ifopt->getBool("enable_stp"); Configlet bridge_configlet(fw, "bsd", "bridge_interface"); bridge_configlet.removeComments(); bridge_configlet.collapseEmptyStrings(true); bridge_configlet.setVariable("bridge_interface", iface_name); bridge_configlet.setVariable("bridge_ports", bridge_port_names.join(" ")); interface_configuration_lines[iface_name] << bridge_configlet.expand(); foreach (QString bridge_port, bridge_port_names) { Configlet port_configlet(fw, "bsd", "bridge_port"); port_configlet.removeComments(); port_configlet.collapseEmptyStrings(true); port_configlet.setVariable("bridge_interface", iface_name); port_configlet.setVariable("bridge_port", bridge_port); port_configlet.setVariable("stp_off", !enable_stp); interface_configuration_lines[iface_name] << port_configlet.expand(); } } void OSConfigurator_bsd::summaryConfigLineCARP(QStringList carp_names) { interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("sync_carp_interfaces %1").arg(carp_names.join(" ")); } void OSConfigurator_bsd::interfaceConfigLineCARP(Interface *iface, FWObject *failover_group) { Configlet configlet(fw, "bsd", "carp_interface"); interfaceConfigLineCARPInternal(iface, failover_group, &configlet); } void OSConfigurator_bsd::interfaceConfigLineCARPInternal( Interface *iface, FWObject *failover_group, Configlet *configlet) { // failover_master and base_device are set in Compiler::processFailoverGroup FWOptions *ifopt = (Interface::cast(iface))->getOptionsObject(); assert(ifopt != NULL); bool master = ifopt->getBool("failover_master"); string base_interface = ifopt->getStr("base_device"); QStringList carp_interfaces; carp_interfaces.push_back(iface->getName().c_str()); FWOptions *failover_opts = FailoverClusterGroup::cast(failover_group)->getOptionsObject(); string carp_password = failover_opts->getStr("carp_password"); //if (carp_password.empty()) carp_password = "\"\""; int vhid = failover_opts->getInt("carp_vhid"); // use the same default as the one we use in // setDefaultFailoverGroupAttributes() in platforms.cpp if (vhid < 0) vhid = 1; int advbase = failover_opts->getInt("carp_advbase"); int master_advskew = failover_opts->getInt("carp_master_advskew"); int default_advskew = failover_opts->getInt("carp_default_advskew"); if (master_advskew < 0) master_advskew = 0; if (default_advskew < 0) default_advskew = 0; if (master_advskew == default_advskew) default_advskew++; int use_advskew; if (master) use_advskew = master_advskew; else use_advskew = default_advskew; configlet->removeComments(); configlet->collapseEmptyStrings(true); configlet->setVariable("carp_interface", iface->getName().c_str()); configlet->setVariable("have_advbase", advbase > 1); configlet->setVariable("advbase", advbase); configlet->setVariable("have_advskew", use_advskew > 0); configlet->setVariable("advskew", use_advskew); configlet->setVariable("have_base_inetrface", !base_interface.empty()); configlet->setVariable("base_inetrface", base_interface.c_str()); configlet->setVariable("carp_password", carp_password.c_str()); configlet->setVariable("have_password", !carp_password.empty()); configlet->setVariable("vhid", vhid); interface_configuration_lines[iface->getName().c_str()] << configlet->expand(); } void OSConfigurator_bsd::summaryConfigLinePfsync(bool have_pfsync) { interface_configuration_lines["1_should_sort_before_interfaces_"] << QString("sync_pfsync_interfaces %1").arg(have_pfsync?"pfsync0":""); } /* * http://www.kernel-panic.it/openbsd/carp/index.html * http://www.openbsd.org/faq/pf/carp.html * pfsync configuration: * * ifconfig pfsyncN syncdev syncdev [syncpeer syncpeer] */ void OSConfigurator_bsd::interfaceConfigLinePfsync( Interface *iface, StateSyncClusterGroup *state_sync_group) { Configlet configlet(fw, "bsd", "pfsync_interface"); configlet.removeComments(); configlet.collapseEmptyStrings(true); configlet.setVariable("syncdev", iface->getName().c_str()); if (state_sync_group->getOptionsObject()->getBool("syncpeer")) { for (FWObjectTypedChildIterator it = state_sync_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *cluster_iface = Interface::cast( FWObjectReference::getObject(*it)); assert(cluster_iface); if (cluster_iface->getId() == iface->getId()) continue; IPv4 *ipv4 = IPv4::cast(cluster_iface->getFirstByType(IPv4::TYPENAME)); const InetAddr *addr = ipv4->getAddressPtr(); configlet.setVariable("have_syncpeer", 1); configlet.setVariable("syncpeer", addr->toString().c_str()); } } interface_configuration_lines[iface->getName().c_str()] << configlet.expand(); } /* * I need to sort interfaces by name but make sure carp and bridge * interfaces are always last. See #1807 and #2104 */ bool sort_interface_names(QString a, QString b) { QString an = a; QString bn = b; if (a.startsWith("bridge")) an = "x_" + a; if (b.startsWith("bridge")) bn = "x_" + b; if (a.startsWith("carp")) an = "y_" + a; if (b.startsWith("carp")) bn = "y_" + b; if (a.startsWith("pfsync")) an = "z_" + a; if (b.startsWith("pfsync")) bn = "z_" + b; return an < bn; } QString OSConfigurator_bsd::printAllInterfaceConfigurationLines() { QStringList keys = interface_configuration_lines.keys(); //keys.sort(); qSort(keys.begin(), keys.end(), sort_interface_names); QStringList res; foreach (QString iface, keys) res << interface_configuration_lines[iface].join("\n"); return res.join("\n"); } fwbuilder-5.1.0.3599/src/pflib/NATCompiler_pf_negation.cpp0000644000175000017500000000750711733011756024064 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_pf.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* * negation in OSrc : * * !A B C RULE_TYPE *----------------------------------------------- * * A B C Continue ("no nat") * any B C SNAT/DNAT */ bool NATCompiler_pf::doOSrcNegation::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrc *osrcrel=rule->getOSrc(); if (osrcrel->getNeg()) { NATRule *r; osrcrel->setNeg(false); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setRuleType(NATRule::Continue); tmp_queue.push_back(r); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementOSrc *nsrc=r->getOSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } /* * negation in Odst : * * A !B C RULE_TYPE TARGET *------------------------------------- * * A B C Continue ("no nat") * A any C SNAT/DNAT */ bool NATCompiler_pf::doODstNegation::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementODst *odstrel=rule->getODst(); if (odstrel->getNeg()) { NATRule *r; odstrel->setNeg(false); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setRuleType(NATRule::Continue); tmp_queue.push_back(r); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementODst *ndst=r->getODst(); ndst->clearChildren(); ndst->setAnyElement(); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } /* * negation in OSrv : * * A B !C RULE_TYPE TARGET *------------------------------------- * * A B C Continue ("no nat") * A B any SNAT/DNAT */ bool NATCompiler_pf::doOSrvNegation::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElementOSrv *osrvrel=rule->getOSrv(); /* A B ! C */ if (osrvrel->getNeg()) { NATRule *r; osrvrel->setNeg(false); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setRuleType(NATRule::Continue); tmp_queue.push_back(r); r= compiler->dbcopy->createNATRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementOSrv *nsrv=r->getOSrv(); nsrv->clearChildren(); nsrv->setAnyElement(); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_pf.h0000644000175000017500000001176411733011756022456 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_PF_HH__ #define __COMPILER_DRIVER_PF_HH__ #include "CompilerDriver.h" #include "OSConfigurator_bsd.h" #include "TableFactory.h" #include "OSData.h" #include "Configlet.h" #include #include #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; }; class MapOstringStream : public std::map { public: MapOstringStream() {} ~MapOstringStream(); void clear(); }; class MapTableFactory : public std::map { public: MapTableFactory() {} ~MapTableFactory(); void clear(); }; namespace fwcompiler { class CompilerDriver_pf : public CompilerDriver { QStringList anchor_names; // QString conf_file_name; // Note that in the following maps ruleset name will be // "__main__" for both main Policy and NAT rulesets. // map ruleset_name -> conf file name // std::map conf_files; // map ruleset_name -> remote conf file name // std::map remote_conf_files; // map ruleset_name -> generated script // std::map generated_scripts; MapOstringStream generated_scripts; // map ruleset_name -> TableFactory* // std::map table_factories; MapTableFactory table_factories; void setToolPathVar(libfwbuilder::Firewall* fw, const std::string &os, const std::string &var_path_suffix, OSData::tools osdata_tool_type, Configlet *configlet); QString composeActivationCommand(libfwbuilder::Firewall *fw, const std::string &pfctl_debug, const std::string &anchor_name, const std::string &pf_version, const std::string &remote_file_name); protected: std::string routing_script; QString getConfFileNameForRuleset(const QString &ruleset_name, const QString &conf_file_name, const QString &ext=""); QString getRemoteConfFileName(const QString &ruleset_name, const QString &local_file_name, const QString &remote_fw_file_name, const QString &remote_conf_file_name); std::string printTimeout(libfwbuilder::FWOptions* options, const std::string &OnOffOption, const std::string &ValOption, const std::string &pfCode); void printProlog(QTextStream &file, const std::string &prolog_code); void printStaticOptions(QTextStream &file, libfwbuilder::Firewall* fw); virtual QString printPathForAllTools(libfwbuilder::Firewall* fw, const std::string &os); virtual QString printActivationCommands(libfwbuilder::Firewall *fw); virtual QString assembleFwScript(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf); virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); public: CompilerDriver_pf(libfwbuilder::FWObjectDatabase *db); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/TableFactory.cpp0000644000175000017500000002646511733011756021761 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "TableFactory.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/AttachedNetworks.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; void print_string(const string &s) { cerr << s << " "; } TableFactory::TableFactory(BaseCompiler *comp, Firewall *fwall, Library *persistent_objects, GroupRegistry *_group_registry) { compiler = comp; firewall = fwall; ruleSetName = ""; group_registry = _group_registry; dbroot = NULL; persistent_tables = new ObjectGroup(); persistent_tables->setName("PF Tables"); persistent_objects->add(persistent_tables); } void TableFactory::init(FWObjectDatabase *_dbr) { dbroot = _dbr; // dbroot->add(persistent_tables); // persistent_tables->fixTree(); } void TableFactory::detach() { // dbroot->remove(persistent_tables, false); } struct joinIDs : public unary_function { string out, sep; joinIDs(const string& _sep) { sep=_sep; }; void operator() (string x) { out += x + sep; } }; string TableFactory::generateTblID(RuleElement *re) { string res; list lids; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); lids.push_back(FWObjectDatabase::getStringId(o->getId())); } lids.sort(); joinIDs R = for_each(lids.begin(), lids.end(), joinIDs("_")); return R.out; } void TableFactory::registerTable(const string& tblname, const string& tblid, FWObject* tbl) throw(FWException) { // two different table objects should have different names // if (tables.count(tblid)!=0 && tblnames.count(tblname)!=0 && tables[tblid]->getName()!=tbl->getName() ) compiler->abort("table object name must be unique: '"+tblname+"'"); tblnames[tblname] = tblid; tables[tblid] = tbl; table_deduplicator[tblname] = set(); } FWObject* TableFactory::createTableObject(const string &tblname, const string &tblid) { FWObject *tblgrp = dbroot->createObjectGroup(); tblgrp->setName( tblname ); tblgrp->setId(FWObjectDatabase::generateUniqueId()); // "id_" + tblname ); persistent_tables->add(tblgrp, false); dbroot->addToIndex(tblgrp); tblgrp->setBool("pf_table", true); tblgrp->setStr("pf_table_id", tblid); registerTable(tblname, tblid, tblgrp); return tblgrp; } /* * Add object to the table group, but perform a check to make sure we * do not add it again if it is already there. See #2671 */ void TableFactory::addObjectToTable(FWObject *tblgrp, FWObject *obj) { int obj_id = obj->getId(); string tblname = tblgrp->getName(); if (table_deduplicator[tblname].count(obj_id) == 0) { tblgrp->addRef(obj); table_deduplicator[tblname].insert(obj_id); } } void TableFactory::createTablesForRE(RuleElement *re, Rule *rule) { // sanity checks assert(rule->getRoot()==re->getRoot()); assert(dbroot==rule->getRoot()); /* * get the list of groups that used to be in this rule element * when we started */ set original_groups = group_registry->getGroupsForRE(re); string tblID = generateTblID(re); FWObject *tblgrp = NULL; list objects_in_groups; list objects; set table_objects; /* * separate objects that should be in a user-defined groups * (tables) and those that dont */ for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = FWReference::getObject(*i); if ( ! group_registry->getGroupRegistryKey(o).empty()) objects_in_groups.push_back(o); else objects.push_back(o); } re->clearChildren(); if (original_groups.size() > 0) { for (FWObject::iterator i=objects_in_groups.begin(); i!=objects_in_groups.end(); i++) { FWObject *obj = *i; set groups = group_registry->getGroupsForObject(obj); set groups_in_this_re; /* * an object can be a member of multiple groups, but not all * of these groups belong to the given RE. * * set_intersection requires both sets to be sorted, but STL class set is * always sorted automatically. */ std::set_intersection( original_groups.begin(), original_groups.end(), groups.begin(), groups.end(), std::insert_iterator< set >( groups_in_this_re, groups_in_this_re.begin() )); for (set::iterator it=groups_in_this_re.begin(); it!=groups_in_this_re.end(); ++it) { string tblname = *it; if (tables.count(tblname)!=0) { tblgrp = tables[tblname]; } else { tblgrp = createTableObject(tblname, tblname); } /* * Add object to the table but first check if this object * already belongs to the group. If RE had two groups and * this object used to belong to both, set * groups_in_this_re will have two items. * * See #2671 */ addObjectToTable(tblgrp, obj); table_objects.insert(tblgrp); } } } else { // if RE never had any groups to begin with for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *obj = FWReference::getObject(*i); objects.push_back(obj); } } /* * Deal with objects that weren't part of any user-defined group */ if (objects.size() > 0) { if (objects.size() == 1) { re->addRef(objects.front()); } else { // objects.size() > 1 if (tables.count(tblID)!=0) { tblgrp = tables[tblID]; } else { // TODO: can two rules yeild the same name for the group using this method? std::ostringstream tblname; if (!ruleSetName.empty()) tblname << ruleSetName << ":"; int rp = rule->getPosition(); tblname << "tbl.r"; tblname << ((rp>0)?rp:0); //if (rule_iface) tblname << rule_iface->getName()+"."; // tblname=tblname+rule->getId(); if (RuleElementSrc::isA(re)) tblname << ".s"; if (RuleElementDst::isA(re)) tblname << ".d"; while (tblnames.count(tblname.str())>0) tblname << "x"; tblgrp = createTableObject(tblname.str(), tblID); for (FWObject::iterator i=objects.begin(); i!=objects.end(); i++) { addObjectToTable(tblgrp, *i); // tblgrp->addRef(*i); } } table_objects.insert(tblgrp); } } for (set::iterator i=table_objects.begin(); i!=table_objects.end(); i++) re->addRef(*i); } string TableFactory::PrintTables() { if (tables.size() == 0) return ""; stringstream output; output << endl; output << "# Tables: (" << tables.size() << ")" << endl; for (map::const_iterator i=tblnames.begin(); i!=tblnames.end(); i++) { string tblID = i->second; FWObject *grp = tables[tblID]; output << "table "; output << "<" << grp->getName() << "> "; MultiAddressRunTime *atrt = MultiAddressRunTime::cast(grp); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { output << "persist"; if ( !atrt->getSourceName().empty() ) { string path = atrt->getSourceNameAsPath(firewall->getOptionsObject()); if (path.empty()) { compiler->abort("Error: Firewall's data directory not set for address table: " + atrt->getName()); } output << " file \"" << path << "\""; } output << endl; continue; } output << "{ "; for (FWObject::iterator i=grp->begin(); i!=grp->end(); i++) { if (i!=grp->begin()) output << ", "; FWObject *o = FWReference::getObject(*i); if (o==NULL) compiler->abort("broken table object "); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { output << atrt->getSourceName() << " "; } if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME) { output << atrt->getSourceName() << ":network "; } } else { if (Interface::cast(o)) { output << o->getName(); } else { Address *A=Address::cast( o ); if (A==NULL) compiler->abort("table object must be an address: '" + o->getTypeName()+"'"); const InetAddr *addr = A->getAddressPtr(); InetAddr mask = *(A->getNetmaskPtr()); if (A->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } output << addr->toString(); if (!mask.isHostMask()) { output << "/" << mask.getLength(); } } } output << " "; } output << "} "; output << endl; } output << endl; return output.str(); } fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_bsd.cpp0000644000175000017500000001430011733011756023117 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "Configlet.h" #include "OSConfigurator_bsd.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_bsd::myPlatformName() { return "BSD"; } string OSConfigurator_bsd::getInterfaceVarName(FWObject *iface) { return string("i_") + iface->getName(); } string OSConfigurator_bsd::printKernelVarsCommands() { return ""; } void OSConfigurator_bsd::addVirtualAddressForNAT(const Network*) { } /** * This method is called from NATCompiler_pf::addVirtualAddress::processNext() */ void OSConfigurator_bsd::addVirtualAddressForNAT(const Address *addr) { FWObject *iaddr = findAddressFor(addr, fw ); if (iaddr!=NULL) { virtual_addresses.insert(addr->getId()); } else warning("Can not add virtual address " + addr->getAddressPtr()->toString() ); } int OSConfigurator_bsd::prolog() { return 0; } string OSConfigurator_bsd::printFunctions() { ostringstream ostr; FWOptions* options = fw->getOptionsObject(); string host_os = fw->getStr("host_OS"); string version = fw->getStr("version"); Configlet functions(fw, "bsd", "shell_functions"); functions.removeComments(); functions.setVariable("dyn_addr", options->getBool("dynAddr")); if (options->getBool("dynAddr")) { /* * get addresses of dynamic interfaces */ QString script_buffer; QTextStream ostr(&script_buffer, QIODevice::WriteOnly); FWObjectTypedChildIterator j=fw->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *iface=Interface::cast(*j); if ( iface->isDyn() ) { /* if interface name ends with '*', this is a wildcard interface. Do * not get its address at this time. * * Do we support wildcard interfaces on *BSD at all ? */ if (iface->getName().find("*")==string::npos) ostr << "getaddr " << iface->getName().c_str() << " " << getInterfaceVarName(iface).c_str() << "\n"; } } functions.setVariable("get_dyn_addr_commands", script_buffer); } else functions.setVariable("get_dyn_addr_commands", ""); ostr << functions.expand().toStdString(); if ( options->getBool("configure_interfaces") ) { Configlet update_addresses(fw, "bsd", "update_addresses"); update_addresses.removeComments(); update_addresses.setVariable("freebsd", host_os == "freebsd"); update_addresses.setVariable("openbsd", host_os == "openbsd"); ostr << update_addresses.expand().toStdString(); } if ( options->getBool("configure_vlan_interfaces") ) { Configlet update_vlans(fw, "bsd", "update_vlans"); update_vlans.removeComments(); update_vlans.setVariable("freebsd", host_os == "freebsd"); update_vlans.setVariable("openbsd", host_os == "openbsd"); ostr << update_vlans.expand().toStdString(); } if (options->getBool("configure_bridge_interfaces")) { Configlet update_bridge(fw, "bsd", "update_bridge"); update_bridge.removeComments(); update_bridge.setVariable("freebsd", host_os == "freebsd"); if (host_os == "openbsd") { update_bridge.setVariable("openbsd", true); update_bridge.setVariable("openbsd_lt_47", XMLTools::version_compare(version, "4.7")<0); update_bridge.setVariable("openbsd_ge_47", XMLTools::version_compare(version, "4.7")>=0); } ostr << update_bridge.expand().toStdString(); } if ( options->getBool("configure_carp_interfaces") ) { Configlet update_carp(fw, "bsd", "update_carp"); update_carp.removeComments(); update_carp.setVariable("freebsd", host_os == "freebsd"); update_carp.setVariable("openbsd", host_os == "openbsd"); ostr << update_carp.expand().toStdString(); } if ( options->getBool("configure_pfsync_interfaces") ) { Configlet update_pfsync(fw, "bsd", "update_pfsync"); update_pfsync.removeComments(); update_pfsync.setVariable("freebsd", host_os == "freebsd"); update_pfsync.setVariable("openbsd", host_os == "openbsd"); ostr << update_pfsync.expand().toStdString(); } return ostr.str(); } void OSConfigurator_bsd::setKernelVariable(Firewall *fw, const string &var_name, Configlet *configlet) { FWOptions* options = fw->getOptionsObject(); string s; s = options->getStr(var_name); if (!s.empty()) { configlet->setVariable(QString("have_") + var_name.c_str(), 1); configlet->setVariable(var_name.c_str(), s=="1" || s=="on" || s=="On"); } } fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_macosx.cpp0000644000175000017500000000346611733011756023654 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "OSConfigurator_macosx.h" #include "Configlet.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_macosx::myPlatformName() { return "Macosx"; } string OSConfigurator_macosx::printKernelVarsCommands() { Configlet kernel_vars(fw, "bsd", "kernel_vars"); kernel_vars.removeComments(); setKernelVariable(fw, "macosx_ip_forward", &kernel_vars); setKernelVariable(fw, "macosx_ip_sourceroute", &kernel_vars); setKernelVariable(fw, "macosx_ip_redirect", &kernel_vars); return kernel_vars.expand().toStdString(); } int OSConfigurator_macosx::prolog() { //printPathForAllTools("macosx"); //printFunctions(); //processFirewallOptions(); //configureInterfaces(); return 0; } fwbuilder-5.1.0.3599/src/pflib/RoutingCompiler_openbsd_writers.cpp0000644000175000017500000002115011733011756025777 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RoutingCompiler_openbsd.h" #include "Configlet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ string RoutingCompiler_openbsd::PrintRule::_printAddr(Address *o) { ostringstream ostr; if (Interface::cast(o)!=NULL) { Interface *iface = Interface::cast(o); if (iface->isDyn()) ostr << "$interface_" << iface->getName() << " "; return ostr.str(); } const InetAddr *addr; const InetAddr *mask; addr = o->getAddressPtr(); mask = o->getNetmaskPtr(); if (addr==NULL) { FWObject *obj=o; /* * check if this is object of class Address. since we want to * distinguish between Host, Interface and Address, and both Host and * Interface are inherited from Address, we can't use cast. Use isA * instead */ while (obj!=NULL && !Host::isA(obj) && !Firewall::isA(obj) && !Network::isA(obj)) obj=obj->getParent(); compiler->abort( "Problem with address or netmask in the object or " "one of its interfaces: '" + obj->getName() + "'"); } if (addr->isAny() && mask->isAny()) { ostr << "default "; } else { ostr << addr->toString(); if (Interface::cast(o)==NULL && Address::cast(o)->dimension() > 1 && !mask->isHostMask()) { ostr << "/" << mask->getLength(); } ostr << " "; } return ostr.str(); } RoutingCompiler_openbsd::PrintRule::PrintRule(const std::string &name) : RoutingRuleProcessor(name) { } bool RoutingCompiler_openbsd::PrintRule::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; if (!compiler->inSingleRuleCompileMode()) { Configlet routing_functions(compiler->fw, compiler->fw->getStr("host_OS"), "routing_functions"); // we should delete default route if we have a new one to // install. IF user did not define any routes that look like // default (i.e. where destination is "any"), then we should // preserve default so that we won't leave machine with no // default at all. QString route_pattern = ""; if (bsd_comp->have_default_route) { // If we will install default route, delete it now route_pattern = "'lo0'"; } else { // do not delete default if we won't install new one route_pattern = "'lo0|default'"; } routing_functions.setVariable("route_filter", route_pattern); compiler->output << routing_functions.expand().toStdString(); bsd_comp->defined_restore_script_output = true; } for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { RoutingRule *rule = RoutingRule::cast( *k ); string rl = rule->getLabel(); if (!compiler->inSingleRuleCompileMode() && rl!=current_rule_label) { compiler->output << "# " << endl; compiler->output << "# Rule " << rl << endl; //compiler->output << "# " << rule->getRuleTypeAsString() << endl; compiler->output << "# " << endl; compiler->output << "echo \"Routing rule " << rl << "\"" << endl; compiler->output << "# " << endl; } if (rule->getRuleType() != RoutingRule::MultiPath ) { if (!compiler->inSingleRuleCompileMode() && rl!=current_rule_label) { QStringList comment = QString::fromUtf8( rule->getComment().c_str()).split("\n"); int comment_lines = 0; foreach (QString str, comment) { if (!str.isEmpty()) { compiler->output << "# " << str.toUtf8().data() << endl; ++comment_lines; } } if (comment_lines) compiler->output << "#" << endl; string err = compiler->getErrorsForRule(rule, "# "); if (!err.empty()) compiler->output << err << endl; current_rule_label = rl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) compiler->output << "# " << err << endl; string command_line = RoutingRuleToString(rule); compiler->output << command_line; } } return true; } string RoutingCompiler_openbsd::PrintRule::RoutingRuleToString(RoutingRule *rule, bool add_decorations) { RuleElementRDst *dstrel = rule->getRDst(); Address *dst = Address::cast(FWReference::getObject(dstrel->front())); RuleElementRItf *itfrel = rule->getRItf(); Interface *itf = Interface::cast(FWReference::getObject(itfrel->front())); RuleElementRGtw *gtwrel = rule->getRGtw(); Address *gtw = Address::cast(FWReference::getObject(gtwrel->front())); if(dst==NULL) compiler->abort(rule, "Broken DST"); ostringstream command_line; command_line << "route add "; if (gtwrel->isAny() && itf != NULL) command_line << "-interface "; command_line << _printRDst(rule); if (gtw != NULL) command_line << _printRGtw(rule); if (itf != NULL) command_line << _printRItf(rule); // to make generated script more readable in single rule compile mode, // skip the part that rolls back in case of an error if (!compiler->inSingleRuleCompileMode() && add_decorations) { command_line << "|| route_command_error " << "\"" << rule->getLabel() << "\"" << endl;; } command_line << endl; return command_line.str(); } string RoutingCompiler_openbsd::PrintRule::_printRGtw(RoutingRule *rule) { RuleElementRGtw *gtwrel = rule->getRGtw(); Address *gtw = Address::cast(FWReference::getObject(gtwrel->front())); if(gtw==NULL) compiler->abort(rule, "Broken GTW"); string gateway = _printAddr(gtw); if( gateway != "default ") return gateway; else return ""; } string RoutingCompiler_openbsd::PrintRule::_printRItf(RoutingRule *rule) { RuleElementRItf *itfrel = rule->getRItf(); Interface *itf = Interface::cast(FWReference::getObject(itfrel->front())); if(itf != NULL) { IPv4 *addr = IPv4::cast(itf->getFirstByType(IPv4::TYPENAME)); if (addr == NULL) { QString err("Can not configure static route via interface %1 " "because its address is unknown"); compiler->abort(rule, err.arg(itf->getName().c_str()).toStdString()); } const InetAddr* ia = addr->getAddressPtr(); return ia->toString(); } else return ""; } string RoutingCompiler_openbsd::PrintRule::_printRDst(RoutingRule *rule) { RuleElementRDst *dstrel = rule->getRDst(); Address *dst = Address::cast(FWReference::getObject(dstrel->front())); if(dst==NULL) compiler->abort(rule, "Broken DST"); return _printAddr(dst); } fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_bsd.h0000644000175000017500000001055111733011756022570 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002,2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCONFIGURATOR_BSD_HH #define _OSCONFIGURATOR_BSD_HH #include "config.h" #include "fwcompiler/OSConfigurator.h" #include #include #include class Configlet; namespace libfwbuilder { class Firewall; class Interface; class StateSyncClusterGroup; } namespace fwcompiler { class OSConfigurator_bsd : public OSConfigurator { protected: QMap interface_configuration_lines; QStringList cloned_interfaces; std::set virtual_addresses; virtual void setKernelVariable(libfwbuilder::Firewall *fw, const std::string &var_name, Configlet *configlet); // functions that generate interface address configuration virtual void summaryConfigLineIP(QStringList intf_names, bool ipv6); virtual void interfaceConfigLineIP( libfwbuilder::Interface *iface, std::list > all_addresses); // functions that generate VLAN configuration virtual void summaryConfigLineVlan(QStringList vlan_names); virtual void interfaceConfigLineVlan( libfwbuilder::Interface *iface, const std::list &vlan_subinterfaces); // functions that generate bridge configuration virtual void summaryConfigLineBridge(QStringList vlan_names); virtual void interfaceConfigLineBridge( libfwbuilder::Interface *iface, QStringList vlan_names); // functions that generate CARP interface configuration virtual void summaryConfigLineCARP(QStringList carp_names); virtual void interfaceConfigLineCARP(libfwbuilder::Interface *iface, libfwbuilder::FWObject *failover_group); virtual void interfaceConfigLineCARPInternal( libfwbuilder::Interface *iface, libfwbuilder::FWObject *failover_group, Configlet *configlet); // functions that generate pfsync interface configuration virtual void summaryConfigLinePfsync(bool have_pfsync); virtual void interfaceConfigLinePfsync( libfwbuilder::Interface *iface, libfwbuilder::StateSyncClusterGroup *sync_group); // this function generates additional ifconfig parameters virtual void interfaceIfconfigLine(libfwbuilder::Interface *iface); virtual QString interfaceIfconfigLineInternal(libfwbuilder::Interface *iface, Configlet *configlet); virtual QString printAllInterfaceConfigurationLines(); public: virtual ~OSConfigurator_bsd() {}; OSConfigurator_bsd(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual void addVirtualAddressForNAT(const libfwbuilder::Address *addr); virtual void addVirtualAddressForNAT(const libfwbuilder::Network *nw); virtual std::string printFunctions(); virtual std::string printKernelVarsCommands(); virtual std::string configureInterfaces(); std::string getInterfaceVarName(libfwbuilder::FWObject *iface); virtual void processFirewallOptions() {} }; }; #endif fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipfw.h0000644000175000017500000002105711733011756023016 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_IPFW_HH #define __POLICYCOMPILER_IPFW_HH #include #include "PolicyCompiler_pf.h" namespace libfwbuilder { class TCPService; class UDPService; class ICMPService; }; #define ANY_IP_OBJ_ID "__any_ip_obj__" #define ANY_ICMP_OBJ_ID "__any_icmp_obj__" #define ANY_TCP_OBJ_ID "__any_tcp_obj__" #define ANY_UDP_OBJ_ID "__any_udp_obj__" namespace fwcompiler { class PolicyCompiler_ipfw : public PolicyCompiler_pf { protected: libfwbuilder::TCPService *anytcp; libfwbuilder::UDPService *anyudp; libfwbuilder::ICMPService *anyicmp; int ipfw_num; virtual std::string myPlatformName(); virtual void _expand_addr(libfwbuilder::Rule *rule, libfwbuilder::FWObject *s, bool expand_cluster_interfaces_fully); /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls PolicyCompiler::_internalPrintPolicyRule and then adds * chain and target at the end of the printed line */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * disabled rules with action Pipe, use this processor in the * run detecting rule shadowing */ DECLARE_POLICY_RULE_PROCESSOR(SpecialRuleActionsForShadowing); /** * splits rules with service 'any' because ipf can keep state * only for UDP/TCP/ICMP */ DECLARE_POLICY_RULE_PROCESSOR(expandAnyService); /** * deals with negation in Src in policy rules. * * this method is different from that in PolicyCompiler_pf */ DECLARE_POLICY_RULE_PROCESSOR(doSrcNegation); /** * deals with negation in Dst in policy rules. * * this method is different from that in PolicyCompiler_pf */ DECLARE_POLICY_RULE_PROCESSOR(doDstNegation); /** * deals with negation in Srv in policy rules. * * this method is different from that in PolicyCompiler_pf */ DECLARE_POLICY_RULE_PROCESSOR(doSrvNegation); /** * This processor separates TCP/UDP services with port ranges * (can only have one port range per group of ports in one * rule). Call this processor after TCP and UDP services were * separated by splitServices */ DECLARE_POLICY_RULE_PROCESSOR(separatePortRanges); /** * This processor rearranges order of TCP/UDP services to make * sure those with port ranges come first. Call this processor * after TCP and UDP services were separated by splitServices * and port ranges were separated by separatePortRanges */ DECLARE_POLICY_RULE_PROCESSOR(sortTCPUDPServices); /** * checks for the following situations: * * 1. dynamic interface is in source and direction is inbound * (drop interface from src since source address is * undertermined) * * 2. dynamic interface is in source, direction is outbound * (drop interface from the list, this rule has been created * while processing negation. TODO: this is kludge, need to * find a better way to process negation if firewall is in rule * element and it has dynamic interface) * * 3. dynamic interface is in destination and direction is * outbound (drop interface since dest. address is undefined) * */ class specialCaseWithDynInterface : public PolicyRuleProcessor { void dropDynamicInterface(libfwbuilder::RuleElement *re); public: specialCaseWithDynInterface(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * ipf supports "keep state" only for icmp/udp/tcp */ DECLARE_POLICY_RULE_PROCESSOR(checkForKeepState); /** * increments numbers for rules (ipfw numbers, that is) * The number itself is stored in the compiler class. */ class calculateNum : public PolicyRuleProcessor { public: calculateNum(const std::string &n); virtual bool processNext(); }; /** * eliminates duplicate atomic rules */ class eliminateDuplicateRules : public PolicyRuleProcessor { private: std::deque rules_seen_so_far; public: eliminateDuplicateRules(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class fwcompiler::PolicyCompiler_ipfw::eliminateDuplicateRules; /** * Placeholders for MultiAddressRunTime objects which are not * supported for ipfw */ class processMultiAddressObjectsInRE : public PolicyRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInSrc(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementSrc::TYPENAME) {} }; class processMultiAddressObjectsInDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInDst(const std::string &n) : processMultiAddressObjectsInRE( n, libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. * Negation should also have been taken care of before this * method is called. */ class PrintRule : public PolicyCompiler_pf::PrintRule { virtual std::string _printPort(int rs,int re,bool neg=false); virtual void _printProtocol(libfwbuilder::Service *srv); virtual void _printAction(libfwbuilder::PolicyRule *r); virtual void _printAddr(libfwbuilder::FWObject *o,bool neg=false); virtual void _printDirection(libfwbuilder::PolicyRule *r); virtual void _printOppositeDirection(libfwbuilder::PolicyRule *r); virtual void _printInterface(libfwbuilder::PolicyRule *r); virtual void _printSrcService(libfwbuilder::RuleElement *o); virtual void _printDstService(libfwbuilder::RuleElement *o); virtual std::string _printSrcService(libfwbuilder::Service *srv, bool neg=false); virtual std::string _printDstService(libfwbuilder::Service *srv, bool neg=false); virtual std::string _printTCPFlags(libfwbuilder::TCPService *srv); public: PrintRule(const std::string &name); virtual bool processNext(); }; public: PolicyCompiler_ipfw(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : PolicyCompiler_pf(_db, fw, ipv6_policy, _oscnf, NULL) { ipfw_num = 0; } virtual int prolog(); virtual void compile(); virtual void epilog(); std::string defaultRules(); int getIPFWNumber() { return ipfw_num; } void setIPFWNumber(int n) { ipfw_num = n; } }; } #endif fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_ipf.cpp0000644000175000017500000000424611733011756023157 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "CompilerDriver_ipf.h" #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver_ipf::CompilerDriver_ipf(FWObjectDatabase *db) : CompilerDriver_pf(db) { have_nat = false; have_filter = false; } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_ipf::clone() { CompilerDriver_ipf* new_cd = new CompilerDriver_ipf(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } QString CompilerDriver_ipf::printActivationCommandWithSubstitution(Firewall *fw) { QString script_buffer; QTextStream str(&script_buffer, QIODevice::WriteOnly); FWObjectTypedChildIterator j=fw->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *iface=Interface::cast(*j); if ( iface->isDyn() ) { str << "sed \"s/ (" << iface->getName() << ") " << "/ $i_" << iface->getName() << " /\""; } } return script_buffer; } fwbuilder-5.1.0.3599/src/pflib/RoutingCompiler_freebsd.h0000644000175000017500000000527411733011756023656 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ROUTINGCOMPILER_FREEBSD_HH__ #define __ROUTINGCOMPILER_FREEBSD_HH__ #include #include "RoutingCompiler_openbsd.h" #include "fwbuilder/RuleElement.h" #include "config.h" #include #include namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_freebsd : public RoutingCompiler_openbsd { int routing_rule_counter; QMap routing_rules_ids; QString getNextStaticRouteID(); protected: /** * prints single policy rule, assuming all groups have been * expanded, destination holds exactly one object, and this * object is not a group. Negation should also have been taken * care of before this method is called. * * This processor is not necessarily the last in the * conveyor, so it should push rules back to tmp_queue (for * example there could be progress indicator processor after * this one) */ class PrintRule : public RoutingCompiler_openbsd::PrintRule { public: PrintRule(const std::string &name); virtual bool processNext(); virtual std::string RoutingRuleToString(libfwbuilder::RoutingRule *r, bool add_decorations=true); }; friend class RoutingCompiler_freebsd::PrintRule; public: RoutingCompiler_freebsd(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler_openbsd(_db, fw, ipv6_policy, _oscnf) { routing_rule_counter = 0; } virtual void compile(); }; } #endif fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_freebsd.h0000644000175000017500000000703111733011756023431 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCONFIGURATOR_FREEBSD_HH #define _OSCONFIGURATOR_FREEBSD_HH #include "config.h" #include "OSConfigurator_bsd.h" #include "OSData.h" #include #include namespace libfwbuilder { class Interface; }; namespace fwcompiler { class OSConfigurator_freebsd : public OSConfigurator_bsd { QMap ifconfig_lines; QMap ipv6_ifconfig_lines; virtual void printIfconfigLines(const QMap &lines); virtual void setKernelVariable(libfwbuilder::Firewall *fw, const std::string &var_name, Configlet *configlet); virtual void summaryConfigLineIP(QStringList intf_names, bool ipv6); virtual void interfaceConfigLineIP( libfwbuilder::Interface *iface, std::list > all_addresses); virtual void summaryConfigLineVlan(QStringList vlan_names); virtual void interfaceConfigLineVlan( libfwbuilder::Interface *iface, const std::list &vlan_subinterfaces); // functions that generate bridge configuration virtual void summaryConfigLineBridge(QStringList vlan_names); virtual void interfaceConfigLineBridge( libfwbuilder::Interface *iface, QStringList vlan_names); // functions that generate CARP interface configuration virtual void summaryConfigLineCARP(QStringList carp_names); virtual void interfaceConfigLineCARP(libfwbuilder::Interface *iface, libfwbuilder::FWObject *failover_group); // functions that generate pfsync interface configuration virtual void summaryConfigLinePfsync(bool have_pfsync); virtual void interfaceConfigLinePfsync( libfwbuilder::Interface *iface, libfwbuilder::StateSyncClusterGroup *sync_group); // this function generates additional ifconfig parameters virtual void interfaceIfconfigLine(libfwbuilder::Interface *iface); virtual QString printAllInterfaceConfigurationLines(); public: virtual ~OSConfigurator_freebsd() {}; OSConfigurator_freebsd(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator_bsd(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual std::string printKernelVarsCommands(); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/RoutingCompiler_openbsd.h0000644000175000017500000001072411733011756023672 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ROUTINGCOMPILER_OPENBSD_HH__ #define __ROUTINGCOMPILER_OPENBSD_HH__ #include #include "fwcompiler/RoutingCompiler.h" #include "fwbuilder/RuleElement.h" #include "config.h" namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_openbsd : public RoutingCompiler { protected: /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls RoutingCompiler::debugPrintRule */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * expand address range objects in destination */ DECLARE_ROUTING_RULE_PROCESSOR(addressRangesInDst); /** * check if we have to install default route */ DECLARE_ROUTING_RULE_PROCESSOR(FindDefaultRoute); /** * remove duplicate rules */ class PrintRule; class optimize3 : public RoutingRuleProcessor { std::map rules_seen_so_far; public: optimize3(const std::string &name) : RoutingRuleProcessor(name) {} virtual bool processNext(); }; /** * eliminates duplicate rules */ class eliminateDuplicateRules : public RoutingRuleProcessor { std::map rules_seen_so_far; public: eliminateDuplicateRules(const std::string &name) : RoutingRuleProcessor(name) {} virtual bool processNext(); }; /** * prints single policy rule, assuming all groups have been * expanded, destination holds exactly one object, and this * object is not a group. Negation should also have been taken * care of before this method is called. * * This processor is not necessarily the last in the * conveyor, so it should push rules back to tmp_queue (for * example there could be progress indicator processor after * this one) */ class PrintRule : public RoutingRuleProcessor { protected: std::string current_rule_label; virtual std::string _printAddr(libfwbuilder::Address *o); public: PrintRule(const std::string &name); virtual bool processNext(); virtual std::string RoutingRuleToString(libfwbuilder::RoutingRule *r, bool add_decorations=true); virtual std::string _printRGtw(libfwbuilder::RoutingRule *r); virtual std::string _printRItf(libfwbuilder::RoutingRule *r); virtual std::string _printRDst(libfwbuilder::RoutingRule *r); }; friend class RoutingCompiler_openbsd::PrintRule; virtual std::string myPlatformName(); bool have_default_route; bool defined_restore_script_output; PrintRule *printRule; public: RoutingCompiler_openbsd(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler(_db, fw, ipv6_policy, _oscnf) { have_default_route = false; defined_restore_script_output = false; printRule = NULL; } virtual void verifyOS(); virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/pflib/Preprocessor_pf.cpp0000644000175000017500000000247611733011756022551 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Preprocessor_pf.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AttachedNetworks.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; void Preprocessor_pf::convertObject(FWObject *obj) { // do not convert attachedNetworks object, compiler for PF always // treats it as run-time object if ( AttachedNetworks::isA(obj)) AttachedNetworks::cast(obj)->setRunTime(true); else Preprocessor::convertObject(obj); } fwbuilder-5.1.0.3599/src/pflib/NATCompiler_pf.h0000644000175000017500000003405011733011756021636 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NATCOMPILER_PF_HH #define __NATCOMPILER_PF_HH #include #include "fwcompiler/NATCompiler.h" #include "TableFactory.h" #include #include #include #include namespace libfwbuilder { class Host; class IPv4; class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementOSrc; class RuleElementODst; class RuleElementOSrv; class RuleElementTSrc; class RuleElementTDst; class RuleElementTSrv; }; namespace fwcompiler { class NATCompiler_pf : public NATCompiler { public: struct redirectRuleInfo { std::string natrule_label; int old_tdst; int new_tdst; int tsrv; redirectRuleInfo(const std::string &rl, libfwbuilder::FWObject *oa, libfwbuilder::FWObject *na, libfwbuilder::Service *s) { natrule_label = rl; old_tdst = oa->getId(); new_tdst = na->getId(); tsrv = s->getId(); } }; protected: libfwbuilder::FWObject *loopback_address; TableFactory *tables; virtual std::string debugPrintRule(libfwbuilder::Rule *rule); virtual void _expand_addr(libfwbuilder::Rule *rule, libfwbuilder::FWObject *s, bool expand_cluster_interfaces_fully); /** * analyse given address and decide which interface this NAT * rule should be tied to. If interface is found, use * rule->setInterfaceId() to save its ID and return * true. Otherwise, return false. Most importantly, this * function checks if @obj is cluster interface and then * uses corresponding real interface instead of it. */ bool assignInterfaceToNATRule(libfwbuilder::NATRule *rule, libfwbuilder::Address *obj); /** * determines type of the NAT rule */ DECLARE_NAT_RULE_PROCESSOR(NATRuleType); /** * this processor spits SDNAT rule onto SNAT and DNAT rules. * SDNAT rule translates both source and destination. */ DECLARE_NAT_RULE_PROCESSOR(splitSDNATRule); /** * verifies correctness of the NAT rules */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules); /** * splits rule with multiple service objects in OSrv * onto * several rules */ DECLARE_NAT_RULE_PROCESSOR(splitOnOSrv); /** * fills translated service with the copy of original srv */ DECLARE_NAT_RULE_PROCESSOR(fillTranslatedSrv); /** * split rule if addresses in TSrc are from the networks * different interfaces of the firewall belong to. */ DECLARE_NAT_RULE_PROCESSOR(splitForTSrc); /** * assigns NAT rules to interfaces */ friend class AssignInterface; class AssignInterface : public NATRuleProcessor { std::string regular_interfaces; public: AssignInterface(const std::string &name) : NATRuleProcessor(name) {} virtual bool processNext(); }; /** * calls OSConfigurator to add virtual * address to the * firewall if it is needed for NAT rule */ DECLARE_NAT_RULE_PROCESSOR(addVirtualAddress); /** * replaces references to the firewall in odst with * references to its external interfaces */ DECLARE_NAT_RULE_PROCESSOR(ReplaceFirewallObjectsODst); /** * replaces references to the firewall in tsrc with * references to its external interfaces */ DECLARE_NAT_RULE_PROCESSOR(ReplaceFirewallObjectsTSrc); /** * replaces object in tdst with reference to firewall's * loopback interface address object */ DECLARE_NAT_RULE_PROCESSOR(ReplaceObjectsTDst); friend class fwcompiler::NATCompiler_pf::ReplaceObjectsTDst; /** * deals with negation in OSrc */ DECLARE_NAT_RULE_PROCESSOR(doOSrcNegation); /** * deals with negation in ODst */ DECLARE_NAT_RULE_PROCESSOR(doODstNegation); /** * deals with negation in OSrv */ DECLARE_NAT_RULE_PROCESSOR(doOSrvNegation); /** * eliminates duplicate objects in SRC. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRC : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRC(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInODST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInODST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRV : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRV(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrv::TYPENAME) {} }; class checkForDynamicInterfacesOfOtherObjects : public NATRuleProcessor { void findDynamicInterfaces(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: checkForDynamicInterfacesOfOtherObjects(const std::string &name) : NATRuleProcessor(name) {} virtual bool processNext(); }; friend class checkForDynamicInterfacesOfOtherObjects; /** * like standard processor swapMultiAddressObjectsInRE, but * swaps compile-time address tables. See comment for this * rule processor in PolicyCompiler_pf */ class swapAddressTableObjectsInRE : public NATRuleProcessor { std::string re_type; public: swapAddressTableObjectsInRE(const std::string &name, const std::string &t) : NATRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; friend class swapAddressTableObjectsInRE; class swapAddressTableObjectsInOSrc : public swapAddressTableObjectsInRE { public: swapAddressTableObjectsInOSrc(const std::string &n) : swapAddressTableObjectsInRE(n, libfwbuilder::RuleElementOSrc::TYPENAME) {} }; friend class swapAddressTableObjectsInOSrc; class swapAddressTableObjectsInODst : public swapAddressTableObjectsInRE { public: swapAddressTableObjectsInODst(const std::string &n) : swapAddressTableObjectsInRE(n, libfwbuilder::RuleElementODst::TYPENAME) {} }; friend class swapAddressTableObjectsInODst; class swapAddressTableObjectsInTSrc : public swapAddressTableObjectsInRE { public: swapAddressTableObjectsInTSrc(const std::string &n) : swapAddressTableObjectsInRE(n, libfwbuilder::RuleElementTSrc::TYPENAME) {} }; class swapAddressTableObjectsInTDst : public swapAddressTableObjectsInRE { public: swapAddressTableObjectsInTDst(const std::string &n) : swapAddressTableObjectsInRE(n, libfwbuilder::RuleElementTDst::TYPENAME) {} }; /** * Split rule if MultiAddress object is used in RE to make * sure it is single object. Also check for the case where * MultiAddress object is used in combination with negation, * this case is not supported. NOTE: this restriction can be * removed if PF adds support for recursively defined tables * (tables as elements inside tables). */ class processMultiAddressObjectsInRE : public NATRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : NATRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInOSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInOSrc(const std::string &n) : processMultiAddressObjectsInRE(n, libfwbuilder::RuleElementOSrc::TYPENAME) {} }; class processMultiAddressObjectsInODst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInODst(const std::string &n) : processMultiAddressObjectsInRE(n, libfwbuilder::RuleElementODst::TYPENAME) {} }; class processMultiAddressObjectsInTSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInTSrc(const std::string &n) : processMultiAddressObjectsInRE(n, libfwbuilder::RuleElementTSrc::TYPENAME) {} }; class processMultiAddressObjectsInTDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInTDst(const std::string &n) : processMultiAddressObjectsInRE(n, libfwbuilder::RuleElementTDst::TYPENAME) {} }; /** * this processor is only called if we are using tables. It * creates two tables for each rule element Processor * PrintRule uses these tables later. */ class createTables : public NATRuleProcessor { void createTablesForRE(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: createTables(const std::string &name) : NATRuleProcessor(name) {} virtual bool processNext(); }; friend class NATCompiler_pf::createTables; /** * this processor accumulates all rules fed to it by previous * processors, then prints commands for all tables, * then feeds all rules to the next processor. Usually this * processor is in chain right before PrintRules */ class PrintTables : public NATRuleProcessor { public: PrintTables(const std::string &n) : NATRuleProcessor(n) {} virtual bool processNext(); }; friend class NATCompiler_pf::PrintTables; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. Negation * should also have been taken care of before this method is * called. */ class PrintRule : public NATRuleProcessor { void _printAnchorRule(const std::string &anchor_command, const std::string &ruleset_name, libfwbuilder::NATRule *rule); protected: bool init; std::string current_rule_label; virtual void _printProtocol(libfwbuilder::Service *srv); virtual void _printPort(libfwbuilder::Service *srv, bool lhs); virtual void _printSrcPort(libfwbuilder::Service *srv, bool lhs); virtual void _printAddrList(libfwbuilder::FWObject *o,bool negflag); virtual void _printREAddr(libfwbuilder::RuleElement *o); virtual void _printAddr(libfwbuilder::FWObject *o); virtual void _printNATRuleOptions(libfwbuilder::Rule *rule); virtual void _printInterface(libfwbuilder::NATRule *r); virtual void _printNegation(libfwbuilder::RuleElement *o); public: PrintRule(const std::string &name); virtual bool processNext(); }; virtual std::string myPlatformName(); std::list redirect_rules; public: NATCompiler_pf(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, TableFactory *tbf = NULL ) : NATCompiler(_db, fw, ipv6_policy, _oscnf) { tables = tbf; } virtual ~NATCompiler_pf(); virtual int prolog(); virtual void compile(); virtual void epilog(); // virtual string atomicRuleToString(libfwbuilder::Rule *r); const std::list& getRedirRulesInfo() { return redirect_rules; } }; } #endif fwbuilder-5.1.0.3599/src/pflib/NATCompiler_ipf_writers.cpp0000644000175000017500000002274011733011756024124 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_ipf.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/DNSName.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ void NATCompiler_ipf::PrintRule::_printAddr_L(Address *o, bool print_netmask) { FWOptions* options=compiler->fw->getOptionsObject(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } // at this time we only support two types of MultiAddress // objects: AddressTable and DNSName. Both should be converted // to MultiAddressRunTime at this point. If we get some other // kind of MultiAddressRunTime object, we do not know what to do // with it so we stop. assert(atrt==NULL); } if (Interface::cast(o)!=NULL && Interface::cast(o)->isDyn()) { if (options->getBool("dynAddr")) compiler->output << "(" << o->getName() << ") "; else compiler->output << "any "; return; } const InetAddr *addr = o->getAddressPtr(); if (addr) { InetAddr mask = *(o->getNetmaskPtr()); if (Interface::cast(o)!=NULL && ! Interface::cast(o)->isDyn()) mask = InetAddr(InetAddr::getAllOnes()); if (o->dimension()==1) mask = InetAddr(InetAddr::getAllOnes()); if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { compiler->output << addr->toString(); if (print_netmask) compiler->output << "/" << mask.getLength(); compiler->output << " "; } } } void NATCompiler_ipf::PrintRule::_printAddr_R(Address *o, bool print_netmask) { const InetAddr *addr = o->getAddressPtr(); // check for the case when dynamic interface is used in TSrc (or when // interface in TSrc just has no IP address ) if (Interface::cast(o) != NULL && (addr==NULL || addr->isAny())) { compiler->output << "0/32 "; return; } if (addr) { InetAddr mask = *(o->getNetmaskPtr)(); if (Interface::cast(o) != NULL) mask = InetAddr(InetAddr::getAllOnes()); if (o->dimension()==1) mask = InetAddr(InetAddr::getAllOnes()); if (addr->isAny() && print_netmask && mask.isHostMask()) { compiler->output << "0/32 "; } else { compiler->output << addr->toString(); if (print_netmask) compiler->output << "/" << mask.getLength(); compiler->output << " "; } } } void NATCompiler_ipf::PrintRule::_printAddr_R_LB(RuleElementTDst *tdst) { bool first=true; for(list::iterator i=tdst->begin(); i!=tdst->end(); ++i) { FWObject *o= *i; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Address *a=Address::cast(obj); const InetAddr *addr = a->getAddressPtr(); if (!first) compiler->output << ","; compiler->output << addr->toString(); first=false; } compiler->output << " "; } void NATCompiler_ipf::PrintRule::_printProtocol(Service *srv) { if ( CustomService::isA(srv) ) { // CustomService returns protocol name starting with v3.0.4 // However CustomService can return protocol name "any", which we should // just skip. string pn = srv->getProtocolName(); if (pn == "any") return; } compiler->output << srv->getProtocolName() << " "; } /* * Note: ipfilter permits "port 0" to the right of "->", in fact, this is useful * and recommended construct for rules that should match "any tcp" or "any udp". * If this method is called to print port spec. for the part of the rule left * of "->", then parameter eq is true, otherwise it is false. We permit port 0 * only for the right part of the rule, that is, when eq is false */ void NATCompiler_ipf::PrintRule::_printPort(Service *srv,bool eq) { if (TCPService::isA(srv) || UDPService::isA(srv)) { int drs=TCPUDPService::cast(srv)->getDstRangeStart(); if (!eq || drs!=0) { compiler->output << "port "; if (eq) compiler->output << "= "; compiler->output<< drs << " "; } } } NATCompiler_ipf::PrintRule::PrintRule(const std::string &name) : NATCompiler_pf::PrintRule(name) { } bool NATCompiler_ipf::PrintRule::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); compiler->output << compiler->printComment(rule, current_rule_label, "#"); Address *osrc=compiler->getFirstOSrc(rule); assert(osrc); Address *odst=compiler->getFirstODst(rule); assert(odst); Service *osrv=compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc=compiler->getFirstTSrc(rule); assert(tsrc); Address *tdst=compiler->getFirstTDst(rule); assert(tdst); Service *tsrv=compiler->getFirstTSrv(rule); assert(tsrv); string iface_name; RuleElementItfOutb *itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->isAny()) iface_name = FWObjectReference::getObject(itf_re->front())->getName(); // string iface_name = rule->getInterfaceStr(); if (rule->getRuleType()==NATRule::NONAT) { compiler->output << "map " << iface_name << " "; compiler->output << "from "; _printAddr_L( osrc ); compiler->output << "to "; _printAddr_L( odst ); if ( rule->getStr("nat_rule_proxy")=="") _printPort(osrv,true); compiler->output << "-> 0/0"; // _printAddr_R( tsrc ); compiler->output << " "; if ( rule->getStr("nat_rule_proxy")!="") compiler->output << rule->getStr("nat_rule_proxy"); compiler->output << endl; } if (rule->getRuleType()==NATRule::SNAT) { compiler->output << "map " << iface_name << " "; compiler->output << "from "; _printAddr_L( osrc ); compiler->output << "to "; _printAddr_L( odst ); if ( rule->getStr("nat_rule_proxy")=="") _printPort(osrv,true); compiler->output << "-> "; _printAddr_R( tsrc ); compiler->output << " "; if ( rule->getStr("nat_rule_proxy")!="") compiler->output << rule->getStr("nat_rule_proxy"); else { if (osrv->getTypeName()==TCPService::TYPENAME || osrv->getTypeName()==UDPService::TYPENAME || rule->getBool("needs_portmap") ) compiler->output << " portmap tcp/udp auto "; } compiler->output << endl; } if (rule->getRuleType()==NATRule::DNAT) { compiler->output << "rdr " << iface_name << " "; compiler->output << "from "; _printAddr_L( osrc , true ); compiler->output << "to "; _printAddr_L( odst , true ); _printPort(osrv,true); compiler->output << "-> "; _printAddr_R( tdst , false ); _printPort(tsrv,false); if ( ! osrv->isAny()) _printProtocol(osrv); compiler->output << endl; } if (rule->getRuleType()==NATRule::LB) { compiler->output << "rdr " << iface_name << " "; compiler->output << "from "; _printAddr_L( osrc , true ); compiler->output << "to "; _printAddr_L( odst , true ); _printPort(osrv,true); compiler->output << "-> "; _printAddr_R_LB( rule->getTDst() ); _printPort(tsrv,false); if ( ! osrv->isAny()) _printProtocol(osrv); compiler->output << " round-robin "; compiler->output << endl; } if (rule->getRuleType()==NATRule::Redirect) { compiler->output << "rdr " << iface_name << " "; compiler->output << "from "; _printAddr_L( osrc , true ); compiler->output << "to "; _printAddr_L( odst , true ); _printPort(osrv,true); compiler->output << "-> "; _printAddr_R( tdst , false ); _printPort(tsrv,false); _printProtocol(osrv); compiler->output << endl; } return true; } fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_pf_writers.cpp0000644000175000017500000011123711733011756024570 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_pf.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/AttachedNetworks.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ void PolicyCompiler_pf::PrintRule::_printAction(PolicyRule *rule) { FWOptions *ruleopt = rule->getOptionsObject(); Service *srv = compiler->getFirstSrv(rule); assert(srv); string version = compiler->fw->getStr("version"); switch (rule->getAction()) { // case PolicyRule::Classify: #2367 // case PolicyRule::Route: #2367 case PolicyRule::Accept: case PolicyRule::Accounting: compiler->output << "pass "; break; case PolicyRule::Deny: compiler->output << "block "; break; case PolicyRule::Continue: if (XMLTools::version_compare(version, "4.6")>=0) { compiler->output << "match "; }else { compiler->output << "pass "; } break; case PolicyRule::Reject: { string aor = ruleopt->getStr("action_on_reject"); string code; if ( aor.find("ICMP")!=string::npos ) { code = "return-icmp "; if (aor.find("unreachable")!=string::npos ) { if (aor.find("net")!=string::npos) code = code + "( 0 ) "; if (aor.find("host")!=string::npos) code = code + "( 1 ) "; if (aor.find("protocol")!=string::npos) code = code + "( 2 ) "; if (aor.find("port")!=string::npos) code = code + "( 3 ) "; } if (aor.find("prohibited")!=string::npos ) { if (aor.find("net")!=string::npos) code = code + "( 9 ) "; if (aor.find("host")!=string::npos) code = code + "( 10 ) "; if (aor.find("filter")!=string::npos) code = code + "( 13 ) "; if (aor.find("admin")!=string::npos) code = code + "( 13 ) "; } } else { if ( aor.find("TCP")!=string::npos ) code = "return-rst "; else code = "return-icmp "; } compiler->output << "block " << code; break; } case PolicyRule::Scrub: { string version = compiler->fw->getStr("version"); if (XMLTools::version_compare(version, "4.7")>=0) { compiler->output << "match in all scrub "; } else { compiler->output << "scrub "; } break; } case PolicyRule::Custom: compiler->output << ruleopt->getStr("custom_str") << " "; break; case PolicyRule::Branch: { RuleSet *ruleset = rule->getBranch(); if (ruleset==NULL) { compiler->abort( rule, "Branching rule refers ruleset that does not exist"); // if we are in test mode or single-rule compile mode compiler->output << "anchor \"UNDEFINED\" "; }else { compiler->output << "anchor \"" << ruleset->getName() << "\" "; } break; } default: compiler->abort( rule, string("Unknown action ") + rule->getActionAsString()); } // #2367 // // if (rule->getTagging()) // { // if (XMLTools::version_compare(version, "4.6")>=0) // { // compiler->output << "match "; // }else // { // compiler->output << "pass "; // } // break; // } } void PolicyCompiler_pf::PrintRule::_printRouteOptions(PolicyRule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); if (rule->getRouting()) { string prefix = "pf"; if (compiler->myPlatformName()=="ipf") prefix = "ipf"; string ro = ruleopt->getStr(prefix+"_route_option"); if (ruleopt->getBool("pf_fastroute") && ro != "none") { compiler->abort( rule, "Cannot use fastroute and route methods in " "the same rule because they are mutually " "exclusive."); } else if (ruleopt->getBool("pf_fastroute") && ro == "none") { compiler->output << "fastroute "; } else { string roif = ruleopt->getStr(prefix+"_route_opt_if"); string roaddr_list = ruleopt->getStr(prefix+"_route_opt_addr"); string roload = ruleopt->getStr("pf_route_load_option"); if (!ro.empty()) { if (roif.empty()) compiler->abort( rule, "Interface specification is required " "for action Route."); if (ro == "route_through") compiler->output << "route-to "; else if (ro == "route_reply_through") compiler->output << "reply-to "; else if (ro == "route_copy_through") compiler->output << "dup-to "; else compiler->abort( rule, "Unknown option for rule action Route: '" + ro + "'"); compiler->output << "{ "; int route_member = 0; std::istringstream buf(roaddr_list); string roaddr; while (std::getline(buf, roaddr, ',')) { if (!roaddr.empty()) { if (route_member > 0 ) { compiler->output << ", "; } compiler->output << "( "; compiler->output << roif << " "; compiler->output << roaddr << " "; compiler->output << ") "; std::string::size_type sp = roaddr.find('/'); if (sp!=std::string::npos) { // roaddr is addr/netmask try { string a = roaddr.substr(0,sp); InetAddr roaddr_addr = InetAddr(a); } catch (FWException &ex) { compiler->abort( rule, "Illegal IP address for next hop"); } try { InetAddr roaddr_netmask; string n = roaddr.substr(sp+1); if (n.find('.')!=std::string::npos) { roaddr_netmask = InetAddr(n); } else { roaddr_netmask = InetAddr( atoi(n.c_str())); } if (roaddr_netmask.getLength()==32) route_member++; else // lame way to tell compiler that // we actually have several addresses for // the next hop. We do not exactly care // how many there are, as long as it is // greater than 1. route_member += 2; } catch (FWException &ex) { compiler->abort( rule, "Illegal netmask for next hop"); } } else { // roaddr is just an addres try { InetAddr roaddr_addr = InetAddr(roaddr); } catch (FWException &ex) { compiler->abort( rule, "Illegal IP address for next hop"); } route_member++; } } } if (route_member < 1) { compiler->abort( rule, "No router specified rule action Route: '" + ro + "'"); } if (route_member >= 2 && (roload.empty() || roload == "none")) { compiler->abort( rule, "More than one router specified without load " "balancing for rule action Route: '" + ro + "'"); } if (route_member == 1 && ((!roload.empty()) && roload != "none")) { compiler->abort( rule, "Only one router specified with load balancing " "for rule action Route: '" + ro + "'"); } compiler->output << "} "; if (!roload.empty()) { if (roload == "bitmask") compiler->output << "bitmask "; else if (roload == "random") compiler->output << "random "; else if (roload == "source_hash") compiler->output << "source-hash "; else if (roload == "round_robin") compiler->output << "round-robin "; } } } } } void PolicyCompiler_pf::PrintRule::_printQueue(PolicyRule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); if (rule->getClassification()) { compiler->output << "queue "; compiler->output << ruleopt->getStr("pf_classify_str") << " "; } } void PolicyCompiler_pf::PrintRule::_printUser(PolicyRule *rule) { RuleElementSrv *srvrel = rule->getSrv(); FWObject *o = srvrel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); if (!UserService::isA(srv)) return; ostringstream str; if (srvrel->size()==1) { str << "user "; if (srvrel->getNeg()) str << "!= "; str << UserService::constcast(srv)->getUserId() << " "; compiler->output << str.str() << " "; } else { int counter = 0; for (FWObject::iterator i=srvrel->begin(); i!=srvrel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); if (counter > 0) str << ","; str << " "; if (srvrel->getNeg()) str << "!= "; str << UserService::constcast(s)->getUserId(); counter++; } if ( counter ) { compiler->output << "user {" << str.str() << " } "; } } } void PolicyCompiler_pf::PrintRule::_printTag(PolicyRule *rule) { if (rule->getTagging()) compiler->output << "tag " << rule->getTagValue() << " "; } void PolicyCompiler_pf::PrintRule::_printDirection(PolicyRule *rule) { if (rule->getDirection()==PolicyRule::Outbound) compiler->output << "out "; if (rule->getDirection()==PolicyRule::Inbound) compiler->output << "in "; } void PolicyCompiler_pf::PrintRule::_printLogging(PolicyRule *rule) { if (rule->getAction() != PolicyRule::Branch && rule->getLogging()) compiler->output << " log "; } void PolicyCompiler_pf::PrintRule::_printLabel(PolicyRule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); string s=ruleopt->getStr("log_prefix"); if (s.empty()) s=compiler->getCachedFwOpt()->getStr("log_prefix"); if (!s.empty()) compiler->output << " label " << _printLogPrefix(rule,s) << " "; } string PolicyCompiler_pf::PrintRule::_printLogPrefix(PolicyRule *rule, const string &prefix) { string s=prefix; /* deal with our logging macros: * %N - rule number * %A - action * %I - interface name * %C - chain name */ string::size_type n; if (rule && (n=s.find("%N"))!=string::npos ) { std::ostringstream s1; s1 << rule->getPosition(); s.replace(n,2,s1.str()); } if (rule && (n=s.find("%A"))!=string::npos ) { std::ostringstream s1; switch (rule->getAction()) { case PolicyRule::Accept: s1 << "ACCEPT"; break; case PolicyRule::Deny: s1 << "DROP"; break; case PolicyRule::Reject: s1 << "REJECT"; break; case PolicyRule::Return: s1 << "RETURN"; break; default: break; } s.replace(n,2,s1.str()); } if (rule && (n=s.find("%I"))!=string::npos ) { std::ostringstream s1; RuleElementItf *intf_re = rule->getItf(); string rule_interfaces; if (!intf_re->isAny()) { for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it) { FWObject *o = FWObjectReference::getObject(*it); rule_interfaces += " " + o->getName(); } } if (!rule_interfaces.empty()) s.replace(n, 2, rule_interfaces); else s.replace(n, 2, "global"); } if (rule && (n=s.find("%C"))!=string::npos ) { s.replace(n,2,""); // there is no chain in PF and friends } return "\"" + s + "\" "; } void PolicyCompiler_pf::PrintRule::_printInterface(PolicyRule *rule) { RuleElementItf *intf_re = rule->getItf(); QStringList rule_interfaces; if (!intf_re->isAny()) { for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it) { FWObject *o = FWObjectReference::getObject(*it); rule_interfaces << o->getName().c_str(); } if (rule_interfaces.size() > 1) { rule_interfaces.push_front("{"); rule_interfaces.push_back("}"); } compiler->output << "on " << rule_interfaces.join(" ").toStdString() << " "; } } // print address family void PolicyCompiler_pf::PrintRule::_printAF(PolicyRule*) { PolicyCompiler_pf *pf_comp=dynamic_cast(compiler); if (pf_comp->ipv6) compiler->output << "inet6 "; else compiler->output << "inet "; } void PolicyCompiler_pf::PrintRule::_printProtocol(Service *srv) { // CustomService returns protocol name starting with v3.0.4 // However CustomService can return protocol name "any", which we should // just skip. // CustomService returns protocol name starting with v3.0.4 if (CustomService::isA(srv)) { // check if the code string for this custom service already includes // "proto ..." fragment string code = CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName()); std::size_t minus_p = code.find("proto "); if (minus_p != string::npos) return; string pn = srv->getProtocolName(); if (pn == "any") return; } if (!srv->isAny() && !TagService::isA(srv) && !UserService::isA(srv) && srv->getProtocolName()!="ip") { compiler->output << "proto "; compiler->output << srv->getProtocolName(); compiler->output << " "; } } string PolicyCompiler_pf::PrintRule::_printPort(int rs,int re,bool neg) { ostringstream str; if (rs<0) rs=0; if (re<0) re=0; if (!neg) { if (rs>0 || re>0) { if (rs>re && re==0) re=rs; if (rs==re) str << rs; // TODO: do we need '=' here ? else if (rs==0 && re!=0) str << "<= " << re; else if (rs!=0 && re==65535) str << ">= " << rs; else { /* * port range. Operator '><' defines range in a such way that boundaries * are not included. Since we assume it is inclusive, let's move boundaries */ if (rs>0 ) rs--; if (re<65535) re++; str << rs << " >< " << re; } } } else { if (rs>0 || re>0) { if (rs==re) str << "!= " << rs; else if (rs==0 && re!=0) str << "> " << re; else if (rs!=0 && re==65535) str << "< " << rs; else { str << rs << " <> " << re; } } } return str.str(); } /* * we made sure that all services in rel represent the same protocol. */ void PolicyCompiler_pf::PrintRule::_printSrcService(RuleElement *rel) { /* I do not want to use rel->getFirst because it traverses the tree to * find the object. I'd rather use a cached copy in the compiler */ FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); string prefix = ""; if (UDPService::isA(srv) || TCPService::isA(srv)) prefix = "port "; if (rel->size()==1) { if (UDPService::isA(srv) || TCPService::isA(srv)) { string str=_printSrcService( srv , rel->getNeg()); if (! str.empty() ) compiler->output << prefix << str << " "; } } else { string str; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s = Service::cast( o ); assert(s); string str1; if (UDPService::isA(srv) || TCPService::isA(srv)) str1 = _printSrcService(s , rel->getNeg() ); if (! str.empty() && ! str1.empty() ) str = str + ", "; str = str + str1; } if ( !str.empty() ) compiler->output << prefix << "{ " << str << "} "; } } string PolicyCompiler_pf::PrintRule::_printSrcService(Service *srv, bool neg) { ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getSrcRangeStart(); int re=TCPUDPService::cast(srv)->getSrcRangeEnd(); str << _printPort(rs,re,neg); } return str.str(); } void PolicyCompiler_pf::PrintRule::_printDstService(RuleElement *rel) { FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); if (rel->size()==1) { string str=_printDstService( srv , rel->getNeg()); if ( ! str.empty() ) { if (UDPService::isA(srv) || TCPService::isA(srv)) compiler->output << "port " << str << " "; else { if (ICMPService::isA(srv)) compiler->output << "icmp-type " << str << " "; else if (ICMP6Service::isA(srv)) compiler->output << "icmp6-type " << str << " "; else compiler->output << str << " "; } } if (TCPService::isA(srv)) { str=_printTCPFlags(TCPService::cast(srv)); if (!str.empty()) compiler->output << "flags " << str << " "; } if (IPService::isA(srv)) { if (srv->getBool("fragm") || srv->getBool("short_fragm")) compiler->output << " fragment "; const IPService *ip = IPService::constcast(srv); string tos = ip->getTOSCode(); string dscp = ip->getDSCPCode(); if (!tos.empty()) compiler->output << " tos " << tos << " "; if (!dscp.empty()) compiler->abort( rel->getParent(), "PF does not support DSCP matching"); } } else { string str; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast( o ); assert(s); string str1= _printDstService(s , rel->getNeg() ); if (! str.empty() && ! str1.empty() ) str = str + ", "; str = str + str1; } if ( !str.empty() ) { if (UDPService::isA(srv) || TCPService::isA(srv)) compiler->output << "port { " << str << " } "; else { if (ICMPService::isA(srv)) compiler->output << "icmp-type { " << str << " } "; else { if (ICMP6Service::isA(srv)) compiler->output << "icmp6-type { " << str << " } "; else compiler->output << str << " " << endl; } } } } } string PolicyCompiler_pf::PrintRule::_printDstService(Service *srv, bool neg) { ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getDstRangeStart(); int re=TCPUDPService::cast(srv)->getDstRangeEnd(); str << _printPort(rs,re,neg); } if (ICMPService::isA(srv) && srv->getInt("type")!=-1) { str << srv->getStr("type") << " "; if (srv->getInt("code")!=-1) str << "code " << srv->getStr("code") << " "; } if (CustomService::isA(srv)) { str << CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ) << " "; } if (TagService::isA(srv)) { str << "tagged " << TagService::constcast(srv)->getCode() << " "; } return str.str(); } string PolicyCompiler_pf::PrintRule::_printTCPFlags(libfwbuilder::TCPService *srv) { string str; if (srv->inspectFlags()) { if (srv->getTCPFlag(TCPService::URG)) str+="U"; if (srv->getTCPFlag(TCPService::ACK)) str+="A"; if (srv->getTCPFlag(TCPService::PSH)) str+="P"; if (srv->getTCPFlag(TCPService::RST)) str+="R"; if (srv->getTCPFlag(TCPService::SYN)) str+="S"; if (srv->getTCPFlag(TCPService::FIN)) str+="F"; str+="/"; if (srv->getTCPFlagMask(TCPService::URG)) str+="U"; if (srv->getTCPFlagMask(TCPService::ACK)) str+="A"; if (srv->getTCPFlagMask(TCPService::PSH)) str+="P"; if (srv->getTCPFlagMask(TCPService::RST)) str+="R"; if (srv->getTCPFlagMask(TCPService::SYN)) str+="S"; if (srv->getTCPFlagMask(TCPService::FIN)) str+="F"; } return str; } void PolicyCompiler_pf::PrintRule::_printAddr(FWObject *o, bool ) { MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { compiler->output << "<" << o->getName() << "> "; return; } if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME) { compiler->output << atrt->getSourceName() << ":network "; return ; } assert(atrt==NULL); } if (o->getBool("pf_table")) { compiler->output << "<" << o->getName() << "> "; return; } Address *addr_obj = Address::cast(o); assert(addr_obj!=NULL); const InetAddr *addr = addr_obj->getAddressPtr(); InetAddr mask; if (Interface::cast(o)!=NULL) { Interface *interface_=Interface::cast(o); if (interface_->isDyn()) { compiler->output << "(" << interface_->getName() << ") "; return; } mask = InetAddr(InetAddr::getAllOnes()); } else { mask = *(addr_obj->getNetmaskPtr()); } if (addr_obj->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { // if (neg) compiler->output << "! "; compiler->output << addr->toString(); if (!mask.isHostMask()) { compiler->output << "/" << mask.getLength(); } compiler->output << " "; } } void PolicyCompiler_pf::PrintRule::_printAddrList(FWObject *grp,bool negflag) { compiler->output << "{ "; for (FWObject::iterator i=grp->begin(); i!=grp->end(); i++) { if (i!=grp->begin()) compiler->output << ", "; FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); _printAddr(o , negflag); } compiler->output << "} "; } void PolicyCompiler_pf::PrintRule::_printSrcAddr(RuleElement *rel) { FWObject *o=rel->front(); FWReference *oref = FWReference::cast(o); if (o && oref!=NULL) o=oref->getPointer(); _printNegation(rel); if (o==NULL) { PolicyRule *rule = PolicyRule::cast(rel->getParent()); ostringstream errstr; errstr << "Broken rule element " << rel->getTypeName() << " in rule '" << rule->getLabel() << "' rel->front(): " << oref->getPointerId(); compiler->abort(rel->getParent(), errstr.str()); } if (rel->size()==1) { _printAddr(o, rel->getNeg() ); } else { _printAddrList(rel,rel->getNeg()); } } void PolicyCompiler_pf::PrintRule::_printDstAddr(RuleElement *rel) { FWObject *o=rel->front(); FWReference *oref = FWReference::cast(o); if (o && oref!=NULL) o=oref->getPointer(); _printNegation(rel); if (o==NULL) { PolicyRule *rule = PolicyRule::cast(rel->getParent()); ostringstream errstr; errstr << "Broken rule element " << rel->getTypeName() << " in rule '" << rule->getLabel() << "' rel->front(): " << oref->getPointerId(); compiler->abort(rel->getParent(), errstr.str()); } if (rel->size()==1) { _printAddr(o, rel->getNeg()); } else { _printAddrList(rel, rel->getNeg()); } } void PolicyCompiler_pf::PrintRule::_printNegation(libfwbuilder::RuleElement *rel) { if (rel->getNeg()) compiler->output << "! "; } PolicyCompiler_pf::PrintRule::PrintRule(const std::string &name) : PolicyRuleProcessor(name) { init=true; } bool PolicyCompiler_pf::PrintRule::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); string version = compiler->fw->getStr("version"); tmp_queue.push_back(rule); compiler->output << compiler->printComment(rule, current_rule_label, "#"); RuleElementSrc *srcrel=rule->getSrc(); // Address *src =compiler->getFirstSrc(rule); assert(src); RuleElementDst *dstrel=rule->getDst(); // Address *dst =compiler->getFirstDst(rule); assert(dst); RuleElementSrv *srvrel=rule->getSrv(); Service *srv =compiler->getFirstSrv(rule); assert(srv); _printAction(rule); _printDirection(rule); _printLogging(rule); if ( rule->getBool("quick") ) compiler->output << " quick "; _printInterface(rule); if (XMLTools::version_compare(version, "4.7")<0) _printRouteOptions(rule); _printAF(rule); _printProtocol(srv); // cerr << "CP 2" << endl; compiler->output << " from "; _printSrcAddr(srcrel); _printSrcService(srvrel); compiler->output << " to "; _printDstAddr(dstrel); _printDstService(srvrel); _printTag(rule); _printUser(rule); /* * Dealing with "keep state" and "modulate state" flags * * 1. both flags do not apply to deny/reject rules. * * 2. modulate state applies only to TCP services. Since we use * groupServicesByProtocol, all services in a rule are of the same * protocol, therefore we can simply check type of srv */ if ( ! ruleopt->getBool("stateless") ) { TCPService *tcpsrv=TCPService::cast(srv); if (tcpsrv!=NULL && ! tcpsrv->inspectFlags() ) { // tcp service, no special flag match // if ( version == "4.x") if (XMLTools::version_compare(version, "4.0")>=0) { if (compiler->getCachedFwOpt()->getBool( "accept_new_tcp_with_no_syn") ) // v4.x, accept connections opened prior to restart compiler->output << "flags any "; // else - no 'flags' option since in 4.x // 'flags S/SA' is the default if (ruleopt->getBool("pf_keep_state") ) compiler->output << "keep state "; } else { // v3.x if ( compiler->getCachedFwOpt()->getBool( "accept_new_tcp_with_no_syn") ) { // no 'flags ' option needed ; } else // v3.x, stateful compiler->output << "flags S/SA "; } } /* * in PF "modulate state", "synproxy state", "keep state" are * mutually exclusive "keep state" can be used with any * protocol, while "modulate state" and "synproxy state" can * only be used with tcp. */ bool have_state_option = false; /* * First, set explicit state tracking parameter, then add * stateful tracking options. */ if (ruleopt->getBool("pf_synproxy") && tcpsrv!=NULL) { compiler->output << "synproxy state "; have_state_option = true; } else { if ((ruleopt->getBool("pf_modulate_state") || compiler->getCachedFwOpt()->getBool("pf_modulate_state")) && tcpsrv!=NULL) { compiler->output << "modulate state "; have_state_option = true; } else { /* * "flags S/SA keep state" is implicit in 4.x * However see section "1.2. Operational changes" in * http://www.openbsd.org/faq/upgrade41.html * * Quote: * * In particular care should be taken with the enc0 * interface, as floating states are a potential problem * for filtering IPsec traffic: states need to be * interface bound, to avoid permitting unencrypted * traffic should isakmpd(8) exit. Therefore all rules on * the enc0 interface should explicitly set keep state * (if-bound). * * This seems to imply that even though "keep state" is * the default, it should be explicitly used with enc0 * interface. Adding rule option "Set 'keep state' * explicitly" to cope with this. */ if (XMLTools::version_compare(version, "4.0") < 0 || compiler->getCachedFwOpt()->getBool("pf_keep_state")) { compiler->output << "keep state "; have_state_option = true; } } } /* * Stateful tracking options. According to the pf.conf manual, * one of keep state, modulate state, or synproxy state must * be specified explicitly to apply these options to a rule. * Using flags need_state_option and have_state_option for that. */ QStringList options; bool need_state_option = false; if (ruleopt->getInt("pf_rule_max_state")>0) { options.push_back(QString("max %1").arg(ruleopt->getInt("pf_rule_max_state"))); need_state_option = true; } if (ruleopt->getBool("pf_sloppy_tracker")) { options.push_back("sloppy"); need_state_option = true; } if (ruleopt->getBool("pf_no_sync")) { options.push_back("no-sync"); need_state_option = true; } if (ruleopt->getBool("pf_pflow")) { options.push_back("pflow"); need_state_option = true; } if (ruleopt->getBool("pf_source_tracking")) { if (ruleopt->getInt("pf_max_src_nodes") > 0) { options.push_back(QString("max-src-nodes %1").arg( ruleopt->getInt("pf_max_src_nodes"))); need_state_option = true; } if (ruleopt->getInt("pf_max_src_states")>0) { options.push_back(QString("max-src-states %1").arg( ruleopt->getInt("pf_max_src_states"))); need_state_option = true; } } bool check_overload_opts = false; if (ruleopt->getInt("pf_max_src_conn")>0) { options.push_back(QString("max-src-conn %1").arg( ruleopt->getInt("pf_max_src_conn"))); check_overload_opts = true; need_state_option = true; } if (ruleopt->getInt("pf_max_src_conn_rate_num")>0 && ruleopt->getInt("pf_max_src_conn_rate_seconds")>0) { options.push_back(QString("max-src-conn-rate %1/%2") .arg(ruleopt->getInt("pf_max_src_conn_rate_num")) .arg(ruleopt->getInt("pf_max_src_conn_rate_seconds"))); check_overload_opts = true; need_state_option = true; } if (check_overload_opts) { QStringList overload_opts; if (ruleopt->getStr("pf_max_src_conn_overload_table")!="") overload_opts.push_back( QString("overload <%1>").arg( ruleopt->getStr("pf_max_src_conn_overload_table").c_str())); if (ruleopt->getBool("pf_max_src_conn_flush")) overload_opts.push_back("flush"); if (ruleopt->getBool("pf_max_src_conn_global")) overload_opts.push_back("global"); if (overload_opts.size() > 0) options.push_back(overload_opts.join(" ")); } if (need_state_option && !have_state_option) { compiler->output << "keep state "; } // looks like pf.conf syntax requires '(' ')' even if there is // only one option if (options.size() > 0) compiler->output << "( "; compiler->output << options.join(", ").toStdString(); if (options.size() > 0) compiler->output << " )"; } else { // stateless rule if (XMLTools::version_compare(version, "4.0")>=0) { // v4.x, stateless rule compiler->output << "no state "; } } if (rule->getBool("allow_opts")) compiler->output << "allow-opts "; _printQueue(rule); _printLabel(rule); if (XMLTools::version_compare(version, "4.7")>=0) _printRouteOptions(rule); compiler->output << endl; return true; } bool PolicyCompiler_pf::PrintTables::processNext() { PolicyCompiler_pf *pf_comp=dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; /* print tables */ compiler->output << pf_comp->tables->PrintTables(); return true; } fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_ipfw.cpp0000644000175000017500000000250711733011756023344 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "CompilerDriver_ipfw.h" #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver_ipfw::CompilerDriver_ipfw(FWObjectDatabase *db) : CompilerDriver_pf(db) { } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_ipfw::clone() { CompilerDriver_ipfw* new_cd = new CompilerDriver_ipfw(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipf_optimizer.cpp0000644000175000017500000001470411733011756025265 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_ipf.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Policy.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; static map skip_targets; void PolicyCompiler_ipf::optimize1::optimizeForRuleElement(PolicyRule *rule, const std::string &re_type) { RuleElement *re=RuleElement::cast(rule->getFirstByType(re_type)); PolicyRule *r; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); /* duplicate copies everything, including attribute * "skip_label". That's why I set skip_label after I create a copy of the rule */ string skip_target = FWObjectDatabase::getStringId(rule->getId()); while (skip_targets[skip_target]) skip_target+=".A"; skip_targets[skip_target]=true; // just need a unique label, and ID is unique rule->setStr("skip_label", skip_target); for (FWObject::iterator i=r->begin(); i!=r->end(); ++i) { if (RuleElement::cast(*i)!=NULL && (*i)->getTypeName()!=re_type) { RuleElement *nre=RuleElement::cast(*i); nre->clearChildren(); nre->setAnyElement(); } } r->setAction(PolicyRule::Skip); r->setBool("quick",false); r->setStr("skip_to",skip_target); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElement *re1; re1=r->getSrc(); re1->clearChildren(); re1->setAnyElement(); re1=r->getDst(); re1->clearChildren(); re1->setAnyElement(); re1=r->getSrv(); re1->clearChildren(); re1->setAnyElement(); r->setAction(PolicyRule::Continue); r->setStr("skip_label",""); tmp_queue.push_back(r); re->clearChildren(); re->setAnyElement(); /* rules that we have inserted above 'rule' will skip over it. We should * not drop them when we eliminate duplicates */ rule->setBool("skip_check_for_duplicates",true); tmp_queue.push_back(rule); } bool PolicyCompiler_ipf::optimize1::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); RuleElementSrv *srvrel=rule->getSrv(); int srcn=srcrel->size(); int dstn=dstrel->size(); int srvn=srvrel->size(); /* if all rule elements have exactly one object, there is nothing to optimize */ if ( (srcn==1 && dstn==1) || (dstn==1 && srvn==1) || (srvn==1 && srcn==1) ) { tmp_queue.push_back(rule); return true; } if (srcn==1) srcn=INT_MAX; if (dstn==1) dstn=INT_MAX; if (srvn==1) srvn=INT_MAX; string re=RuleElementSrc::TYPENAME; if (srcn>2 && srcn<=dstn && dstn<=srvn) { optimizeForRuleElement(rule,RuleElementSrc::TYPENAME); return true; } if (dstn>2 && dstn<=srvn && srvn<=srcn) { optimizeForRuleElement(rule,RuleElementDst::TYPENAME); return true; } if (srvn>2 && srvn<=srcn && srcn<=dstn) { optimizeForRuleElement(rule,RuleElementSrv::TYPENAME); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipf::optimizeSrc::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); RuleElementSrv *srvrel=rule->getSrv(); int srcn=srcrel->size(); int dstn=dstrel->size(); int srvn=srvrel->size(); /* without optimization we generate N^3 rules (n1*n2*n3), with it we * generate 3*N (n1+n2+n3) rules. If n1+n2+n3 is greater than * n1*n2*n3, then we should not optimize */ if (srcrel->isAny() || (srcn+dstn+srvn>=srcn*dstn*srvn)) { tmp_queue.push_back(rule); return true; } optimizeForRuleElement(rule,RuleElementSrc::TYPENAME); return true; } bool PolicyCompiler_ipf::optimizeDst::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); RuleElementSrv *srvrel=rule->getSrv(); int srcn=srcrel->size(); int dstn=dstrel->size(); int srvn=srvrel->size(); /* without optimization we generate N^3 rules (n1*n2*n3), with it we * generate 3*N (n1+n2+n3) rules. If n1+n2+n3 is greater than * n1*n2*n3, then we should not optimize */ if (dstrel->isAny() || (srcn+dstn+srvn>=srcn*dstn*srvn)) { tmp_queue.push_back(rule); return true; } optimizeForRuleElement(rule,RuleElementDst::TYPENAME); return true; } bool PolicyCompiler_ipf::optimizeSrv::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); RuleElementDst *dstrel=rule->getDst(); RuleElementSrv *srvrel=rule->getSrv(); int srcn=srcrel->size(); int dstn=dstrel->size(); int srvn=srvrel->size(); /* without optimization we generate N^3 rules (n1*n2*n3), with it we * generate 3*N (n1+n2+n3) rules. If n1+n2+n3 is greater than * n1*n2*n3, then we should not optimize */ if (srvrel->isAny() || (srcn+dstn+srvn>=srcn*dstn*srvn)) { tmp_queue.push_back(rule); return true; } optimizeForRuleElement(rule,RuleElementSrv::TYPENAME); return true; } fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_pf.h0000644000175000017500000003772111733011756022463 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_PF_HH #define __POLICYCOMPILER_PF_HH #include #include "fwcompiler/PolicyCompiler.h" #include "NATCompiler_pf.h" #include "TableFactory.h" #include #include #include namespace libfwbuilder { class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementSrc; class RuleElementDst; class RuleElementSrv; class IPv4; }; namespace fwcompiler { class PolicyCompiler_pf : public PolicyCompiler { protected: /** * virtual method to let policy compiler check rules using * options specific for the given fw platform. Base class * PolicyCompiler has no visibility into platform-specific * options and can not do this. */ virtual bool checkForShadowingPlatformSpecific(libfwbuilder::PolicyRule *r1, libfwbuilder::PolicyRule *r2); /** * splits rule if one of the objects in Src * is firewall * itself. This is needed to properly choose direction * * later in filDirection */ DECLARE_POLICY_RULE_PROCESSOR(splitIfFirewallInSrc); /** * splits rule if one of the objects in Dst * is firewall * itself. This is needed to properly choose direction * * later in filDirection */ DECLARE_POLICY_RULE_PROCESSOR(splitIfFirewallInDst); /** * decides on direction if it is empty. */ DECLARE_POLICY_RULE_PROCESSOR(fillDirection); /** * split rules if direction is "Both" */ DECLARE_POLICY_RULE_PROCESSOR(SplitDirection); /** * Option "scrub" does not accept "quick" and therefore does not * stop matching sequence. We need to split rule onto two, the first * will be generated with action "scrub", while the second one with * action "pass" and option "quick" */ DECLARE_POLICY_RULE_PROCESSOR(ProcessScrubOption); /** * checks for the services which require * special treatment. * Some of these will be checking for * source or destination * object as well because special * command may need to be * generated in case source or * destination is a firewall * itself. Therefore this processor * should be called after * converting to atomic rules, but * before interface * addresses in source and destination are * expanded. */ DECLARE_POLICY_RULE_PROCESSOR(SpecialServices); /** * sets 'quick' flag on rules */ DECLARE_POLICY_RULE_PROCESSOR(setQuickFlag); /** * deals with negation in Src in policy rules. */ DECLARE_POLICY_RULE_PROCESSOR(doSrcNegation); /** * deals with negation in Dst in policy rules. */ DECLARE_POLICY_RULE_PROCESSOR(doDstNegation); /** * deals with negation in Srv in policy rules. * * NOT IMPLEMENTED */ DECLARE_POLICY_RULE_PROCESSOR(doSrvNegation); /** * Replace carp interface in the "Interface" rule element * with firewall's real interface */ class replaceFailoverInterfaceInItf : public replaceFailoverInterfaceInRE { public: replaceFailoverInterfaceInItf(const std::string &n) : replaceFailoverInterfaceInRE(n, libfwbuilder::RuleElementItf::TYPENAME) {} }; /** * like standard processor swapMultiAddressObjectsInRE, * but swaps compile-time address tables * * We need this because unlike on other platforms, we need to * generate code for compile-time AddressTables using their * object name (to name the table after that). This * substantially complicates things, we have to register * AddressTable objects with TableFactory and then replace * them with corresponding run time objects. This is unique * feature of the compiler for PF. */ class swapAddressTableObjectsInRE : public PolicyRuleProcessor { std::string re_type; public: swapAddressTableObjectsInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class swapAddressTableObjectsInSrc : public swapAddressTableObjectsInRE { public: swapAddressTableObjectsInSrc(const std::string &n) : swapAddressTableObjectsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class swapAddressTableObjectsInDst : public swapAddressTableObjectsInRE { public: swapAddressTableObjectsInDst(const std::string &n) : swapAddressTableObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * Split rule if MultiAddress object is used in RE to make * sure it is single object. Also check for the case where * MultiAddress object is used in combination with negation, * this case is not supported. NOTE: this restriction can be * removed if PF adds support for recursively defined tables * (tables as elements inside tables). */ class processMultiAddressObjectsInRE : public PolicyRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInSrc(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class processMultiAddressObjectsInDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInDst(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * This is to work around a "feature" specific to PF: If NAT * policy defines a redirect rule (a rule which sends packets * to the firewall itself, possibly changing port numbers), * then the packet appears on the same _ingress_ interface * twice. The first time it is inspected, it has an original * destination address, but the second time it has destination * address of 127.0.0.1. This address appears there because * our NAT compiler uses it for redirection rules. Our normal * ExpandMultipleAddresses processor replaces firewall object * with a set of addresses of all its interfaces, but skips * loopback interface. Rule processor addLoopbackForRedirect * consults with NATCompiler_pf to find out whether we have * any Redirect rules to accomodate for. In case we do, and * destination service in the current policy rule matches TSrv * in the redirect rule and destination contains the same * object that was in TDst in the NAT rule, it adds a new * policy rule with the same source, destination being a new * object used in TDst by the NAT compiler and the same * service. * * Caveat: as everywhere in compiler for PF, we assume rule * elements may contain multiple objects. */ DECLARE_POLICY_RULE_PROCESSOR(addLoopbackForRedirect); friend class PolicyCompiler_pf::addLoopbackForRedirect; friend class checkForDynamicInterfacesOfOtherObjects; class checkForDynamicInterfacesOfOtherObjects : public PolicyRuleProcessor { void findDynamicInterfaces(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: checkForDynamicInterfacesOfOtherObjects(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * we can not put interface name in the table, so we need to * split the rule if src or dst contains both interface and * host or network objects. */ class splitIfInterfaceInRE : public PolicyRuleProcessor { std::string re_type; public: splitIfInterfaceInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; /** * we can not put interface name in the table, so we need to * split the rule if src contains both interface and host or * network objects. */ class splitIfInterfaceInSrc : public splitIfInterfaceInRE { public: splitIfInterfaceInSrc(const std::string &n) : splitIfInterfaceInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * we can not put interface name in the table, so we need to * split the rule if dst contains both interface and host or * network objects. */ class splitIfInterfaceInDst : public splitIfInterfaceInRE { public: splitIfInterfaceInDst(const std::string &n) : splitIfInterfaceInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * this processor is only called if we are using tables. It * creates two tables for each rule: one for source and * another for destination. Processor PrintRule uses these * tables later. */ class createTables : public PolicyRuleProcessor { void createTablesForRE(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: createTables(const std::string &name) : PolicyRuleProcessor(name) { } virtual bool processNext(); }; friend class PolicyCompiler_pf::createTables; /** * eliminates duplicate objects in SRC. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInSRC : public eliminateDuplicatesInRE { public: eliminateDuplicatesInSRC(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInDST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInDST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInSRV : public eliminateDuplicatesInRE { public: eliminateDuplicatesInSRV(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {} }; class printScrubRule : public PolicyRuleProcessor { protected: bool init; public: printScrubRule(const std::string &name) : PolicyRuleProcessor(name) { init=false; } virtual bool processNext(); }; /** * this processor accumulates all rules fed to it by previous * processors, then prints commands for all tables, * then feeds all rules to the next processor. Usually this * processor is in chain right before PrintRules */ class PrintTables : public PolicyRuleProcessor { public: PrintTables(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class PolicyCompiler_pf::PrintTables; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. Negation * should also have been taken care of before this method is * called. */ class PrintRule : public PolicyRuleProcessor { protected: bool init; std::string current_rule_label; virtual void _printSrcService(libfwbuilder::RuleElement *o); virtual void _printDstService(libfwbuilder::RuleElement *o); virtual void _printProtocol(libfwbuilder::Service *srv); virtual std::string _printPort(int rs,int re,bool neg=false); virtual std::string _printSrcService(libfwbuilder::Service *srv,bool neg=false); virtual std::string _printDstService(libfwbuilder::Service *srv,bool neg=false); virtual std::string _printTCPFlags(libfwbuilder::TCPService *srv); virtual void _printAddrList(libfwbuilder::FWObject *o,bool negflag); virtual void _printSrcAddr(libfwbuilder::RuleElement *o); virtual void _printDstAddr(libfwbuilder::RuleElement *o); virtual void _printAddr(libfwbuilder::FWObject *o, bool neg=false); virtual void _printNegation(libfwbuilder::RuleElement *o); virtual void _printAction(libfwbuilder::PolicyRule *r); virtual void _printRouteOptions(libfwbuilder::PolicyRule *r); virtual void _printLogging(libfwbuilder::PolicyRule *r); virtual void _printDirection(libfwbuilder::PolicyRule *r); virtual void _printInterface(libfwbuilder::PolicyRule *r); virtual void _printAF(libfwbuilder::PolicyRule *r); virtual void _printLabel(libfwbuilder::PolicyRule *r); virtual void _printQueue(libfwbuilder::PolicyRule *r); virtual void _printUser(libfwbuilder::PolicyRule *r); virtual void _printTag(libfwbuilder::PolicyRule *r); virtual std::string _printLogPrefix(libfwbuilder::PolicyRule *r,const std::string &prefix); public: PrintRule(const std::string &name); virtual bool processNext(); }; friend class PolicyCompiler_pf::PrintRule; virtual std::string myPlatformName(); public: PolicyCompiler_pf(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, const std::list *rri, TableFactory *tbf = NULL) : PolicyCompiler(_db, fw, ipv6_policy, _oscnf) { redirect_rules_info = rri; tables = tbf; } virtual ~PolicyCompiler_pf(); virtual int prolog(); virtual void compile(); virtual void epilog(); protected: TableFactory *tables; libfwbuilder::IPv4 *loopback_address; const std::list *redirect_rules_info; private: }; } #endif fwbuilder-5.1.0.3599/src/pflib/NATCompiler_ipfw.cpp0000644000175000017500000000351611733011756022534 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_ipfw.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string NATCompiler_ipfw::myPlatformName() { return "ipfw"; } int NATCompiler_ipfw::prolog() { int n=NATCompiler_pf::prolog(); return n; } void NATCompiler_ipfw::compile() { info(" Compiling NAT rules for " + fw->getName()); Compiler::compile(); add( new Begin()); add( new printTotalNumberOfRules() ); add( new simplePrintProgress() ); runRuleProcessors(); } void NATCompiler_ipfw::epilog() { } fwbuilder-5.1.0.3599/src/pflib/RoutingCompiler_freebsd_writers.cpp0000644000175000017500000001123011733011756025755 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RoutingCompiler_freebsd.h" #include "Configlet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ QString RoutingCompiler_freebsd::getNextStaticRouteID() { return QString("route_%1").arg(routing_rule_counter++); } RoutingCompiler_freebsd::PrintRule::PrintRule(const std::string &name) : RoutingCompiler_openbsd::PrintRule(name) { } bool RoutingCompiler_freebsd::PrintRule::processNext() { RoutingCompiler_freebsd* routing_comp = dynamic_cast(compiler); FWOptions* options = compiler->fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { slurp(); if (tmp_queue.size()==0) return false; QStringList rule_ids; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { RoutingRule *rule = RoutingRule::cast( *k ); QString routing_id = routing_comp->getNextStaticRouteID(); rule_ids << routing_id; routing_comp->routing_rules_ids[rule->getId()] = routing_id; //rule_ids << FWObjectDatabase::getStringId(rule->getId()).c_str(); } if (rule_ids.size() > 0) { compiler->output << QString("static_routes=\"%1\"") .arg(rule_ids.join(" ")).toStdString() << endl; } for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { RoutingRule *rule = RoutingRule::cast( *k ); compiler->output << RoutingRuleToString(rule) << endl; } return true; } else return RoutingCompiler_openbsd::PrintRule::processNext(); } string RoutingCompiler_freebsd::PrintRule::RoutingRuleToString(RoutingRule *rule, bool add_decorations) { RoutingCompiler_freebsd* routing_comp = dynamic_cast(compiler); FWOptions* options = compiler->fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { RuleElementRDst *dstrel = rule->getRDst(); Address *dst = Address::cast(FWReference::getObject(dstrel->front())); RuleElementRItf *itfrel = rule->getRItf(); Interface *itf = Interface::cast(FWReference::getObject(itfrel->front())); RuleElementRGtw *gtwrel = rule->getRGtw(); Address *gtw = Address::cast(FWReference::getObject(gtwrel->front())); if(dst==NULL) compiler->abort(rule, "Broken DST"); QStringList command_line; if (gtwrel->isAny() && itf != NULL) command_line << "-interface"; command_line << _printRDst(rule).c_str(); if (gtw != NULL) command_line << _printRGtw(rule).c_str(); if (itf != NULL) command_line << _printRItf(rule).c_str(); QString rule_code = command_line.join(" "); if (add_decorations) { rule_code = QString("route_%1=\"%2\"") .arg(routing_comp->routing_rules_ids[rule->getId()]) .arg(rule_code); } return rule_code.toUtf8().constData(); } else return RoutingCompiler_openbsd::PrintRule::RoutingRuleToString( rule, add_decorations); } fwbuilder-5.1.0.3599/src/pflib/CompilerDriver_ipfw.h0000644000175000017500000000435111733011756023010 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_IPFW_HH__ #define __COMPILER_DRIVER_IPFW_HH__ #include "CompilerDriver_pf.h" #include "TableFactory.h" #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; }; namespace fwcompiler { class CompilerDriver_ipfw : public CompilerDriver_pf { QStringList activation_commands; protected: virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); virtual QString printActivationCommands(libfwbuilder::Firewall *fw); virtual QString assembleFwScript(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf); public: CompilerDriver_ipfw(libfwbuilder::FWObjectDatabase *db); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipfw.cpp0000644000175000017500000005274211733011756023356 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_ipfw.h" #include "fwcompiler/Compiler.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_ipfw::myPlatformName() { return "ipfw"; } int PolicyCompiler_ipfw::prolog() { int n= PolicyCompiler_pf::prolog(); anytcp=dbcopy->createTCPService(); anytcp->setId(FWObjectDatabase::generateUniqueId()); // ANY_TCP_OBJ_ID); persistent_objects->add(anytcp,false); anyudp=dbcopy->createUDPService(); anyudp->setId(FWObjectDatabase::generateUniqueId()); //ANY_UDP_OBJ_ID); persistent_objects->add(anyudp,false); anyicmp=dbcopy->createICMPService(); anyicmp->setId(FWObjectDatabase::generateUniqueId()); //ANY_ICMP_OBJ_ID); persistent_objects->add(anyicmp,false); return n; } /* * (this is a virtual method). We do not want to expand a firewall * object that own the policy we are processing, because we can use * address 'me' in ipfw rules. */ void PolicyCompiler_ipfw::_expand_addr(Rule *rule, FWObject *s, bool expand_cluster_interfaces_fully) { RuleElement *re=RuleElement::cast(s); if (re!=NULL && re->size()==1 ) { FWObject *o=re->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if (o->getId()==fw->getId()) return; } Compiler::_expand_addr(rule, s, expand_cluster_interfaces_fully); } bool PolicyCompiler_ipfw::expandAnyService::processNext() { PolicyCompiler_ipfw *pcomp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv=rule->getSrv(); FWOptions *ruleopt =rule->getOptionsObject(); if (srv->isAny() && ! ruleopt->getBool("stateless") && rule->getAction()==PolicyRule::Accept) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anyicmp); //compiler->dbcopy->findInIndex(ANY_ICMP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anytcp); //compiler->dbcopy->findInIndex(ANY_TCP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anyudp); //compiler->dbcopy->findInIndex(ANY_UDP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); FWOptions *ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipfw::SpecialRuleActionsForShadowing::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getAction()==PolicyRule::Pipe || rule->getAction()==PolicyRule::Custom) return true; tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipfw::doSrcNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *src=rule->getSrc(); if (src->getNeg()) { RuleElementSrc *nsrc; PolicyRule *r; FWOptions *ruleopt; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Continue); r->setLogging(false); nsrc=r->getSrc(); nsrc->setNeg(false); r->setBool("quick",false); r->setBool("skip_check_for_duplicates",true); ruleopt = r->getOptionsObject(); ruleopt->setBool("stateless", true); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getSrc(); nsrc->setNeg(false); nsrc->clearChildren(); nsrc->setAnyElement(); r->setBool("quick",true); r->setBool("skip_check_for_duplicates",true); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipfw::doDstNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementDst *dst=rule->getDst(); if (dst->getNeg()) { RuleElementDst *ndst; PolicyRule *r; FWOptions *ruleopt; r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Continue); r->setLogging(false); ndst=r->getDst(); ndst->setNeg(false); r->setBool("quick",false); r->setBool("skip_check_for_duplicates",true); ruleopt = r->getOptionsObject(); ruleopt->setBool("stateless", true); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst=r->getDst(); ndst->setNeg(false); ndst->clearChildren(); ndst->setAnyElement(); r->setBool("quick",true); r->setBool("skip_check_for_duplicates",true); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipfw::doSrvNegation::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv=rule->getSrv(); if (srv->getNeg()) { compiler->abort(rule, "Negation in Srv is not implemented"); return false; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipfw::separatePortRanges::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *rel= rule->getSrv(); if (rel->size()==1) { tmp_queue.push_back(rule); return true; } list services; bool sawServiceWithPortRange=false; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast(o); assert(s!=NULL); if ( TCPService::isA(s) || UDPService::isA(s) ) { unsigned srs=TCPUDPService::cast(s)->getSrcRangeStart(); unsigned sre=TCPUDPService::cast(s)->getSrcRangeEnd(); unsigned drs=TCPUDPService::cast(s)->getDstRangeStart(); unsigned dre=TCPUDPService::cast(s)->getDstRangeEnd(); if (srs!=0 && sre==0) sre=srs; if (drs!=0 && dre==0) dre=drs; if (srs!=sre || drs!=dre) { /* leave the very first service with port range in this rule, * split others into separate rules */ if (sawServiceWithPortRange) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef( s ); tmp_queue.push_back(r); services.push_back(s); } sawServiceWithPortRange=true; } } } for (list::iterator i=services.begin(); i!=services.end(); i++) rel->removeRef( (*i) ); if (!rel->isAny()) tmp_queue.push_back(rule); return true; } bool PolicyCompiler_ipfw::sortTCPUDPServices::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *rel= rule->getSrv(); if (rel->size()==1) { tmp_queue.push_back(rule); return true; } FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s1= Service::cast(o); if ( !UDPService::isA(s1) && !TCPService::isA(s1)) { tmp_queue.push_back(rule); return true; } /* * we know that at this point if there the original rule had service * objects with port ranges, there is only one left. We just need to * move it to the front of the list. */ Service *portRangeSvc=NULL; for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *s=Service::cast(o); assert(s!=NULL); unsigned srs=TCPUDPService::cast(s)->getSrcRangeStart(); unsigned sre=TCPUDPService::cast(s)->getSrcRangeEnd(); unsigned drs=TCPUDPService::cast(s)->getDstRangeStart(); unsigned dre=TCPUDPService::cast(s)->getDstRangeEnd(); if (srs!=0 && sre==0) sre=srs; if (drs!=0 && dre==0) dre=drs; if (srs!=sre || drs!=dre) { portRangeSvc=s; break; } } if (portRangeSvc) { rel->removeRef(portRangeSvc); /* It certainly would have been better if we had FWObject::insertRef() */ FWReference *oref = portRangeSvc->createRef(); portRangeSvc->ref(); rel->push_front(oref); oref->setParent(rel); } tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipfw::specialCaseWithDynInterface::dropDynamicInterface(RuleElement *re) { list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *ifs =Interface::cast( obj ); if (ifs!=NULL && !ifs->isRegular()) continue; cl.push_back(obj); } if (!cl.empty()) { re->clearChildren(); for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->addRef( (*i1) ); } } bool PolicyCompiler_ipfw::specialCaseWithDynInterface::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; dropDynamicInterface( rule->getDst() ); dropDynamicInterface( rule->getSrc() ); tmp_queue.push_back(rule); return true; } PolicyCompiler_ipfw::calculateNum::calculateNum(const std::string &n) : PolicyRuleProcessor(n) {} bool PolicyCompiler_ipfw::calculateNum::processNext() { PolicyCompiler_ipfw *pcomp = dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { PolicyRule *r = PolicyRule::cast( *k ); pcomp->ipfw_num += 10; r->setInt("ipfw_num", pcomp->ipfw_num ); } for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { PolicyRule *r = PolicyRule::cast( *k ); int current_position = r->getPosition(); if (r->getAction()==PolicyRule::Continue) { r->setAction(PolicyRule::Skip); deque::iterator j = k; ++j; PolicyRule *r2; for ( ; j!=tmp_queue.end(); ++j) { r2 = PolicyRule::cast( *j ); if (r2->getPosition()!=current_position) { r->setInt("skip_to", r2->getInt("ipfw_num") ); break; } } } } return true; } bool PolicyCompiler_ipfw::checkForKeepState::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); Service *srv=compiler->getFirstSrv(rule); assert(srv); FWOptions *ruleopt =rule->getOptionsObject(); if (! ICMPService::isA(srv) && ! UDPService::isA(srv) && ! TCPService::isA(srv) ) ruleopt->setBool("stateless",true); return true; } bool PolicyCompiler_ipfw::eliminateDuplicateRules::processNext() { PolicyCompiler *pcomp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; // Note that if rule has "any" in Interface column, it is // implemented as reference to the AnyNetwork object. In this case // Compiler::getFirstItf() returns NULL. Interface *intf_rule = compiler->getFirstItf(rule); int intf_id_rule = (intf_rule) ? intf_rule->getId() : -1; if ( ! rule->getBool("skip_check_for_duplicates")) { for (deque::iterator i=rules_seen_so_far.begin(); i!=rules_seen_so_far.end(); ++i) { PolicyRule *r=(*i); if ( r->getBool("skip_check_for_duplicates") ) continue; Interface *intf_r = compiler->getFirstItf(r); int intf_id_r = (intf_r) ? intf_r->getId() : -1; if (intf_id_r==intf_id_rule && r->getAction()==rule->getAction() && r->getLogging()==rule->getLogging() && pcomp->cmpRules(*r,*rule) ) { // cout << "---------------------------------------" << endl; // cout << pcomp->debugPrintRule(r) << endl; // cout << pcomp->debugPrintRule(rule) << endl; return true; } } } tmp_queue.push_back(rule); rules_seen_so_far.push_back(rule); return true; } /* * this processor is the same as in PolicyCompiler_ipf */ bool PolicyCompiler_ipfw::processMultiAddressObjectsInRE::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) compiler->abort( rule, "Run-time AddressTable objects are not supported."); } tmp_queue.push_back(rule); return true; } void PolicyCompiler_ipfw::compile() { string banner = " Compiling " + fw->getName(); if (!getRuleSetName().empty()) banner += " ruleset " + getRuleSetName(); if (ipv6) banner += ", IPv6"; info(banner); Compiler::compile(); bool check_for_recursive_groups=true; if ( fw->getOptionsObject()->getBool("check_shading") && ! inSingleRuleCompileMode()) { add( new Begin("Detecting rule shadowing")); add( new printTotalNumberOfRules()); add( new SpecialRuleActionsForShadowing( "disable rules with action Pipe and Custom") ); add( new ItfNegation("process negation in Itf" ) ); add( new InterfacePolicyRules( "process interface policy rules and store interface ids")); add( new recursiveGroupsInSrc("check for recursive grps in SRC")); add( new recursiveGroupsInDst("check for recursive grps in DST")); add( new recursiveGroupsInSrv("check for recursive grps in SRV")); check_for_recursive_groups=false; add( new ExpandGroups("expand groups")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC")); add( new eliminateDuplicatesInDST("eliminate duplicates in DST")); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV")); add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src") ); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst") ); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC")); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new ConvertToAtomic("convert to atomic rules")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new DetectShadowing("Detect shadowing")); add( new simplePrintProgress()); runRuleProcessors(); deleteRuleProcessors(); } add( new Begin()); add( new printTotalNumberOfRules()); add( new singleRuleFilter()); if (check_for_recursive_groups) { add( new recursiveGroupsInSrc("check for recursive grps in SRC")); add( new recursiveGroupsInDst("check for recursive grps in DST")); add( new recursiveGroupsInSrv("check for recursive grps in SRV")); } add( new emptyGroupsInSrc("check for empty grps in SRC")); add( new emptyGroupsInDst("check for empty grps in DST")); add( new emptyGroupsInSrv("check for empty grps in SRV")); add( new ItfNegation("process negation in Itf")); add( new InterfacePolicyRules( "process interface policy rules and store interface ids")); add( new doSrcNegation("process negation in Src")); add( new doDstNegation("process negation in Dst")); add( new doSrvNegation("process negation in Srv")); add( new ExpandGroups("expand groups")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC")); add( new eliminateDuplicatesInDST("eliminate duplicates in DST")); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV")); add( new swapMultiAddressObjectsInSrc( " swap MultiAddress -> MultiAddressRunTime in Src") ); add( new swapMultiAddressObjectsInDst( " swap MultiAddress -> MultiAddressRunTime in Dst") ); add( new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src") ); add( new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst") ); add( new splitIfFirewallInSrc("split rule if firewall is in Src")); add( new splitIfFirewallInDst("split rule if firewall is in Dst")); add( new fillDirection("determine directions")); add( new ExpandMultipleAddresses( "expand objects with multiple addresses")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls")); add( new MACFiltering("verify for MAC address filtering")); add( new checkForUnnumbered("check for unnumbered interfaces")); add( new specialCaseWithDynInterface( "check for a special cases with dynamic interface")); add( new addressRanges("expand address range objects")); add( new groupServicesByProtocol("split rules with different protocols")); add( new splitIpOptions("split rules with multiple IPService objects with options")); add( new separateTCPWithFlags("separate TCP services with flags")); add( new separateSrcPort("split on TCP and UDP with source ports")); add( new separatePortRanges("split services with port ranges")); add( new sortTCPUDPServices("move port ranges to the front of ports")); add( new verifyCustomServices( "verify custom services for this platform")); add( new SpecialServices("check for special services")); // add( new expandAnyService("expand ANY service for stateful rules")); add( new ConvertToAtomicForAddresses( "convert to atomic rules in SRC and DST")); add( new checkForZeroAddr("check for zero addresses")); add( new calculateNum("calculate rule numbers ")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new PrintRule("generate ipf code")); add( new simplePrintProgress()); runRuleProcessors(); } string PolicyCompiler_ipfw::debugPrintRule(Rule *r) { PolicyRule *rule=PolicyRule::cast(r); ostringstream s; s << PolicyCompiler::debugPrintRule(rule); RuleElementItf *intf_re = rule->getItf(); string rule_interfaces; int intf_count = 0; for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it) { FWObject *o = *it; if (FWReference::cast(o)!=NULL) o = FWReference::cast(o)->getPointer(); rule_interfaces += " " + o->getName(); intf_count++; } if (intf_count > 0) { s << " intf: "; if (intf_count > 1) s << "{ "; s << rule_interfaces; if (intf_count > 1) s << " }"; } else s << " intf: ?"; return s.str(); } void PolicyCompiler_ipfw::epilog() { } fwbuilder-5.1.0.3599/src/pflib/OSConfigurator_solaris.h0000644000175000017500000000424311733011756023475 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSNETWORKCONFIGURATOR_SOLARIS_HH #define _OSNETWORKCONFIGURATOR_SOLARIS_HH #include "config.h" #include "fwbuilder/InetAddr.h" #include #include "OSConfigurator_bsd.h" #include "OSData.h" /* * Of course Solaris has nothing to do with BSD. Class * OSConfigurator_solaris inherits OSConfigurator_bsd only because the * latter is the base class for all OSConfigurator classes for the * pf-ipf-ipfw family. TODO: rename OSConfigurator_bsd to use more * generic name, something like OSConfigurator_generic_pf_ipf_family */ namespace fwcompiler { class OSConfigurator_solaris : public OSConfigurator_bsd { OSData os_data; std::vector virtual_addresses; public: virtual ~OSConfigurator_solaris() {}; OSConfigurator_solaris(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator_bsd(_db, fw, ipv6_policy) , os_data() {} virtual int prolog(); virtual std::string myPlatformName(); virtual std::string printKernelVarsCommands(); virtual void addVirtualAddressForNAT(const libfwbuilder::Address *addr); virtual void addVirtualAddressForNAT(const libfwbuilder::Network *nw); virtual std::string configureInterfaces(); }; }; #endif fwbuilder-5.1.0.3599/src/pflib/OSData.cpp0000644000175000017500000000275311733011756020507 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSData.h" #include "fwbuilder/Resources.h" using namespace std; using namespace libfwbuilder; OSData::OSData() {} string OSData::getPathForTool(const string &os,tools t) { string r = "/FWBuilderResources/Target/tools/"; switch (t) { case IFCONFIG: r += "path_ifconfig"; break; case SYSCTL: r += "path_sysctl"; break; case PFCTL: r += "path_pfctl"; break; case IPFW: r += "path_ipfw"; break; case IPF: r += "path_ipf"; break; case IPNAT: r += "path_ipnat"; break; case LOGGER: r += "path_logger"; break; } return Resources::os_res[os]->getResourceStr(r); } fwbuilder-5.1.0.3599/src/pflib/PolicyCompiler_ipf_writers.cpp0000644000175000017500000002717311733011756024746 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_ipf.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/DNSName.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ string PolicyCompiler_ipf::PrintRule::_printPort(int rs,int re,bool neg) { ostringstream str; if (rs<0) rs=0; if (re<0) re=0; if (!neg) { if (rs>0 || re>0) { if (rs>re && re==0) re=rs; if (rs==re) str << "= " << rs; else if (rs==0 && re!=0) str << "<= " << re; else if (rs!=0 && re==65535) str << ">= " << rs; else { /* * port range. Operator '><' defines range in a such way that boundaries * are not included. Since we assume it is inclusive, let's move boundaries */ if (rs>0 ) rs--; if (re<65535) re++; str << rs << " >< " << re; } } } else { if (rs>0 || re>0) { if (rs==re) str << "!= " << rs; else if (rs==0 && re!=0) str << "> " << re; else if (rs!=0 && re==65535) str << "< " << rs; else { str << rs << " <> " << re; } } } return str.str(); } void PolicyCompiler_ipf::PrintRule::_printDstService(RuleElement *rel) { FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Service *srv= Service::cast(o); IPService *ip_srv = IPService::cast(srv); if (ip_srv) { return; } else PolicyCompiler_pf::PrintRule::_printDstService(rel); } void PolicyCompiler_ipf::PrintRule::_printAction(PolicyRule *rule) { /* * difference between this and PolicyCompiler_pf::_printAction is as follows: * * 1. there is no support for action Scrub in ipf * 2. there is support for return-icmp-as-dest in ipf * 3. there is support for action Skip in ipf */ FWOptions *ruleopt =rule->getOptionsObject(); Service *srv=compiler->getFirstSrv(rule); assert(srv); switch (rule->getAction()) { case PolicyRule::Skip: compiler->output << "skip " << rule->getInt("no_to_skip") << " "; break; case PolicyRule::Accept: compiler->output << "pass "; break; case PolicyRule::Accounting: compiler->output << "count "; break; case PolicyRule::Deny: compiler->output << "block "; break; case PolicyRule::Reject: if (rule->getDirection()==PolicyRule::Inbound) { if (TCPService::isA(srv)) compiler->output << "block return-rst "; else { string aor=ruleopt->getStr("action_on_reject"); if (aor.empty()) aor=compiler->getCachedFwOpt()->getStr("action_on_reject"); string code; if ( aor.find("ICMP")!=string::npos ) { if (ruleopt->getBool("ipf_return_icmp_as_dest") || compiler->getCachedFwOpt()->getBool("ipf_return_icmp_as_dest") ) code="return-icmp-as-dest "; else code="return-icmp "; if (aor.find("unreachable")!=string::npos ) { if (aor.find("net")!=string::npos) code=code+"(0) "; if (aor.find("host")!=string::npos) code=code+"(1) "; if (aor.find("protocol")!=string::npos) code=code+"(2) "; if (aor.find("port")!=string::npos) code=code+"(3) "; } if (aor.find("prohibited")!=string::npos ) { if (aor.find("net")!=string::npos) code=code+"(9) "; if (aor.find("host")!=string::npos) code=code+"(10) "; } } else code="return-icmp "; compiler->output << "block " << code; } } else compiler->output << "block "; break; case PolicyRule::Custom: compiler->output << ruleopt->getStr("custom_str") << " "; break; default: compiler->abort( rule, string("Unknown action ") + rule->getActionAsString()); // compiler->output << rule->getActionAsString() << " "; } } void PolicyCompiler_ipf::PrintRule::_printWith(libfwbuilder::Service *srv) { IPService *ip_srv = IPService::cast(srv); if (ip_srv) { if (ip_srv->getBool("any_opt")) compiler->warning("ipfilter can not match \"any IP option\" "); bool with=true; if ( srv->getBool("short_fragm") ) { if (with) { compiler->output << " with"; with=false; } compiler->output << " short"; } if ( srv->getBool("fragm") ) { if (with) { compiler->output << " with"; with=false; } compiler->output << " frag"; } if (srv->getBool("rr") ) { if (with) { compiler->output << " with"; with=false; } compiler->output << " opt rr"; } if (srv->getBool("lsrr") ) { if (with) { compiler->output << " with"; with=false; } compiler->output << " opt lsrr"; } if (srv->getBool("ssrr") ) { if (with) { compiler->output << " with"; with=false; } compiler->output << " opt ssrr"; } if (srv->getBool("ts") ) { if (with) { compiler->output << " with"; with=false; } compiler->output << " opt ts"; } } } /* * this is almost like the one in PolicyCompiler_pf, except it does * not print interface name for dynamic interface ('cause ipfilter * does not support it) */ void PolicyCompiler_ipf::PrintRule::_printAddr(Address *o,bool neg) { FWOptions* options=compiler->fw->getOptionsObject(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } // at this time we only support two types of MultiAddress // objects: AddressTable and DNSName. Both should be converted // to MultiAddressRunTime at this point. If we get some other // kind of MultiAddressRunTime object, we do not know what to do // with it so we stop. assert(atrt==NULL); } if (options->getBool("dynAddr") && Interface::cast(o)!=NULL && Interface::cast(o)->isDyn()) { if (neg) compiler->output << "! "; compiler->output << "(" << o->getName() << ") "; return; } const InetAddr *addr = o->getAddressPtr(); if (Interface::cast(o)!=NULL && addr==NULL) { compiler->output << " "; } if (addr) { InetAddr mask = *(o->getNetmaskPtr()); if (Interface::cast(o)!=NULL) { mask = InetAddr(InetAddr::getAllOnes()); } if (o->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { if (neg) compiler->output << "! "; compiler->output << addr->toString(); if (!mask.isHostMask()) { compiler->output << "/" << mask.getLength(); } compiler->output << " "; } } } PolicyCompiler_ipf::PrintRule::PrintRule(const std::string &name) : PolicyCompiler_pf::PrintRule(name) { } bool PolicyCompiler_ipf::PrintRule::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); tmp_queue.push_back(rule); compiler->output << compiler->printComment(rule, current_rule_label, "#"); RuleElementSrc *srcrel=rule->getSrc(); Address *src =compiler->getFirstSrc(rule); assert(src); RuleElementDst *dstrel=rule->getDst(); Address *dst =compiler->getFirstDst(rule); assert(dst); RuleElementSrv *srvrel=rule->getSrv(); Service *srv =compiler->getFirstSrv(rule); assert(srv); _printAction(rule); _printDirection(rule); if (rule->getLogging()) { compiler->output << " log "; if (compiler->getCachedFwOpt()->getBool("ipf_log_or_block") && rule->getAction()==PolicyRule::Accept) compiler->output << " or-block"; if (compiler->getCachedFwOpt()->getBool("ipf_log_body")) compiler->output << " body"; string facility=ruleopt->getStr("ipf_log_facility"); if (facility.empty()) facility = compiler->getCachedFwOpt()->getStr("ipf_log_facility"); string level=ruleopt->getStr("log_level"); if (level.empty()) level=compiler->getCachedFwOpt()->getStr("ipf_log_level"); if (level!="") { compiler->output << " level "; if (facility!="") compiler->output << facility << "."; compiler->output << level; } compiler->output << " "; } if ( rule->getBool("quick") ) compiler->output << "quick "; _printInterface(rule); _printRouteOptions(rule); _printProtocol(srv); compiler->output << " from "; _printSrcAddr(srcrel); _printSrcService(srvrel); compiler->output << " to "; _printDstAddr(dstrel); _printDstService(srvrel); _printWith(srv); /* keeping state does not apply to deny/reject */ if ( ! ruleopt->getBool("stateless") ) { /* * this is per advice from Darren Reed http://false.net/ipfilter/2002_12/0176.html * * Feature req. #653803: Implement flags for TCP keep state * * If "keep state" option is given, the rule matches only first packet * in the session. To make the rule more secure, we also match on TCP * flags (if TCP service is used) looking for the correct session * opener packet which should have only SYN flag set and all other * flags cleared. * * However, if option "Accept tcp sessions opened prior to firewall * restart" is ON, we do not need to add "flags S" here ( bug #725853 ). * */ TCPService *tcpsrv=TCPService::cast(srv); if ( ! compiler->getCachedFwOpt()->getBool("accept_new_tcp_with_no_syn") && tcpsrv!=NULL && !tcpsrv->inspectFlags() ) compiler->output << "flags S "; compiler->output << "keep state "; } /* keep frags option */ if ( ruleopt->getBool("ipf_keep_frags") && rule->getAction()==PolicyRule::Accept) { compiler->output << "keep frags "; } compiler->output << endl; return true; } fwbuilder-5.1.0.3599/src/pflib/AutomaticRules_pf.cpp0000644000175000017500000001772111733011756023023 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AutomaticRules_pf.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; void AutomaticRules_pf::addSshAccessRule() { if (ruleset == NULL) return; FWOptions *fwopt = fw->getOptionsObject(); if (fwopt->getBool("mgmt_ssh") && ! fwopt->getStr("mgmt_addr").empty()) { PolicyRule *r; TCPService *ssh = ruleset->getRoot()->createTCPService(); ssh->setDstRangeStart(22); ssh->setDstRangeEnd(22); ssh->setName("mgmt_ssh"); persistent_objects->add(ssh,false); string mgmt_addr = fwopt->getStr("mgmt_addr"); InetAddr addr; InetAddr netmask(InetAddr::getAllOnes()); try { addr = InetAddr(mgmt_addr); string::size_type sep = mgmt_addr.find("/"); if (sep != string::npos) { addr = InetAddr(mgmt_addr.substr(0,sep)); string nm = mgmt_addr.substr(sep+1); int o1,o2,o3,o4; if (sscanf(nm.c_str(), "%3u.%3u.%3u.%3u", &o1, &o2, &o3, &o4)==4) { netmask = InetAddr(nm); } else { sscanf(nm.c_str(),"%u",&o1); netmask = InetAddr(o1); } } } catch(FWException &ex) { QString err("Invalid address for the backup ssh access: '%1'"); throw FWException(err.arg(mgmt_addr.c_str()).toStdString()); } Network *mgmt_workstation = ruleset->getRoot()->createNetwork(); mgmt_workstation->setName("mgmt_addr"); mgmt_workstation->setAddress(addr); mgmt_workstation->setNetmask(netmask); persistent_objects->add(mgmt_workstation,false); // r = ruleset->getRoot()->createPolicyRule(); // ruleset->push_front(r); r = PolicyRule::cast(ruleset->insertRuleAtTop(true)); r->setAction(PolicyRule::Accept); r->setLogging(false); r->setDirection(PolicyRule::Inbound); r->setPosition(9998); r->setComment(" backup ssh access rule "); r->setHidden(true); r->setFallback(false); r->setLabel("backup ssh access rule"); r->setBool("needs_established",true); // supported in ipfw RuleElement *src = r->getSrc(); assert(src!=NULL); src->addRef(mgmt_workstation); RuleElement *dst = r->getDst(); assert(dst!=NULL); dst->addRef(fw); RuleElement *srv = r->getSrv(); assert(srv!=NULL); srv->addRef(ssh); } } void AutomaticRules_pf::addCarpRules() { if (ruleset == NULL) return; /* Add CARP-Service to database */ IPService* carp_service = IPService::cast(ruleset->getRoot()->create(IPService::TYPENAME)); carp_service->setComment("CARP service"); carp_service->setProtocolNumber(112); persistent_objects->add(carp_service); FWObjectTypedChildIterator interfaces = fw->findByType(Interface::TYPENAME); for (; interfaces != interfaces.end(); ++interfaces) { Interface *iface = Interface::cast(*interfaces); if (iface->isFailoverInterface()) { FWObject *failover_group = iface->getFirstByType(FailoverClusterGroup::TYPENAME); if (failover_group->getStr("type") == "carp") { /* Add automatic rules for CARP * Rule should be associated with physical interface */ string phys_iface_name = iface->getOptionsObject()->getStr("base_device"); Interface *phys_iface = Interface::cast( fw->findObjectByName(Interface::TYPENAME, phys_iface_name)); if (phys_iface) { PolicyRule *rule = addMgmtRule(NULL, NULL, carp_service, phys_iface, PolicyRule::Both, PolicyRule::Accept, "CARP"); FWOptions *ruleopt = rule->getOptionsObject(); assert(ruleopt!=NULL); ruleopt->setBool("firewall_is_part_of_any_and_networks", false); } else { throw FWException( "Can not find interface " + phys_iface_name + " for the CARP interface " + iface->getName() + " of the cluster"); } } } } } void AutomaticRules_pf::addPfsyncRules() { if (ruleset == NULL) return; /* Add pfsync service to database */ IPService* pfsync_service = IPService::cast(ruleset->getRoot()->create(IPService::TYPENAME)); pfsync_service->setComment("pfsync service"); pfsync_service->setProtocolNumber(240); persistent_objects->add(pfsync_service); FWObjectTypedChildIterator interfaces = fw->findByType(Interface::TYPENAME); for (; interfaces != interfaces.end(); ++interfaces) { Interface *iface = Interface::cast(*interfaces); if (iface->getOptionsObject()->getBool("state_sync_group_member")) { FWObject *state_sync_group = ruleset->getRoot()->findInIndex( ruleset->getRoot()->getIntId( iface->getOptionsObject()->getStr("state_sync_group_id"))); assert(state_sync_group!=NULL); if (state_sync_group && state_sync_group->getStr("type") == "pfsync") { PolicyRule *rule = addMgmtRule(NULL, NULL, pfsync_service, iface, PolicyRule::Both, PolicyRule::Accept, "pfsync"); FWOptions *ruleopt = rule->getOptionsObject(); assert(ruleopt!=NULL); ruleopt->setBool("firewall_is_part_of_any_and_networks", false); } } } } void AutomaticRules_pf::addFallbackRule() { if (ruleset == NULL) return; FWOptions *fwopt = fw->getOptionsObject(); PolicyRule *r = PolicyRule::cast(ruleset->appendRuleAtBottom(true)); r->setUniqueId( ruleset->getRoot()->getPredictableId( FWObjectDatabase::getStringId(fw->getId()) + "." )); FWOptions *ruleopt; r->setAction(PolicyRule::Deny); r->setLogging(fwopt->getBool("fallback_log")); r->setDirection(PolicyRule::Both); r->setPosition(10000); r->setComment(" fallback rule "); r->setHidden(true); r->setFallback(true); r->setLabel("fallback rule"); ruleopt = r->getOptionsObject(); ruleopt->setBool("stateless", true); } fwbuilder-5.1.0.3599/src/gui/0000755000175000017500000000000011733011756016351 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/gui/main_mac.cpp0000644000175000017500000001007611733011756020625 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: main.cpp 493 2008-08-30 05:05:56Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "VERSION.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" using namespace std; #if defined(Q_WS_MAC) #include static OSErr checkAppleEventForMissingParams(const AppleEvent& theAppleEvent) { DescType returnedType; Size actualSize; OSErr err; switch (err = AEGetAttributePtr(&theAppleEvent, keyMissedKeywordAttr, typeWildCard, &returnedType, nil, 0, &actualSize)) { case errAEDescNotFound: return noErr; case noErr: return errAEEventNotHandled; default: return err; } } static pascal OSErr odocHandler(const AppleEvent* inEvent, AppleEvent* /*reply*/, long /*refCon*/) { if (fwbdebug) qDebug("Handling 'odoc'\n"); AEDescList documentList; OSErr err = AEGetParamDesc(inEvent, keyDirectObject, typeAEList, &documentList); if (err == noErr) { err = checkAppleEventForMissingParams(*inEvent); if (err == noErr) { long documentCount; err = AECountItems(&documentList, &documentCount); for (long documentIndex = 1; err == noErr && documentIndex <= documentCount; documentIndex++) { // What kind of document is it? DescType returnedType; Size actualSize; err = AESizeOfNthItem(&documentList, documentIndex, &returnedType, &actualSize); if (err == noErr) { // It's just a normal document file AEKeyword keyword; FSRef ref; err = AEGetNthPtr(&documentList, documentIndex, typeFSRef, &keyword, &returnedType, (Ptr)&ref, sizeof(FSRef), &actualSize); if (err == noErr) { char buf[1024]; FSRefMakePath(&ref, reinterpret_cast(buf),1024); QDir file(buf); mw->registerAutoOpenDocFile(file.canonicalPath(), false); //mw->openDocFiles << file.canonicalPath(); } } } } AEDisposeDesc(&documentList); } if (fwbdebug) qDebug("Returning %d from handleOpenDocuments\n", err); return err; } void connectOdocHandler() { AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(odocHandler),0,false); } #endif // Q_WS_MAC fwbuilder-5.1.0.3599/src/gui/.gitignore0000644000175000017500000000001311733011756020333 0ustar sylvestresylvestrefwbuilder fwbuilder-5.1.0.3599/src/gui/fwbuilder-macosx.icns0000644000175000017500000071527411733011756022522 0ustar sylvestresylvestreicnsšМis32„€џ2Sj’vP'32„џ2Sj’vP'32„џ2T’’vQ632„џ2T’’vQ632…џ›ніИКžƒ†џ­ні4Кžƒ†џ†Ѕп2…ni†џ­ІѕсНo‚ƒџ€­ЅѕсНm‚џџ€ƒЁп6…icџџ€­ні1Кžƒџџ€—еэДØ€6џџ'7QWPMA.78(џџ"LCMh”vY?6TD2џџP;@6iVA..JC;џџ  џ€џ2Sj’vP'32„џ2Sj’vP'32„џ2T’’vQ632„џ2T’’vQ632…џ›ніИКžƒ†џ­ні2Кžƒ†џ†Ѕп/…ni†џ­ІѕсНo‚ƒџ€­ЅѕсНm‚џџ€ƒЁп4…icџџ€­ні.Кžƒџџ€—еэДØ€6џџkziZPMA.9WyXџџdЄо›|”vY?YЌдr7џџWЙ`iVA.\”‚Ё:џџ;F>A4=FDH1џ€џ2Sj’vP'32„џ2Sj’vP'32„џ2T’’vQ632„џ2T’’vQ632…џ›ніИКžƒ†џ­ні,Кžƒ†џ†Ѕп)…ni†џ­ІѕсНo‚ƒџ€­ЅѕсНm‚џџ€ƒЁп.…icџџ€­ні(Кžƒџџ€—еэДØ€6џџ"HVPMA.6. џџ '/a”vY?+,џџ+*iVA.$џџ џs8mk№№џџ№џ№№№џџ№џ№№џџџџџџџ№№џџџџџџџ№џџџџџџђџџџџџџђџџџџџџѕџџџџџџђџџџџџџђџџџџџџѕџџџџџџђџџџџџџђ5ўџџџџџџџџЁїџџџџџџџџџџчbџџџџџџџџџџџџS •Л+3ЇКЪil32 X ”џџjZZYYXVpџ†‡“џџˆŠ€lzi„uџ[YFGIŠџ†‡™sbZrc.cBUZџZXgY[Šџ†‡@^ЎЊ—K(^L7ZwZk•’ZŠџ†‡+-cЇy1.Š ˜œž•y\bZŠџ†‡/1?qPE\ž’‚qY@2++‹Z†‡01CqLh‡‰yeR@51@E‹Z†‡+0Epƒ­ЎŒ{iVD7/Qn…Z˜‚idcz‡ˆ#AsЅВЄŒ|iVD710KXZ!|nkc^jqpZˆˆVџWiŠš‘†yfR@55F_ZZ_ae]]€_nUZZ‰ˆџ}ЁЅ ‘‡ykbXUg„rhhZTPLXN:DiyŸŸСРjџmДоюцрЩЕЄ‹ssƒA/EQ(:PaŠЉЫвŸЦЦeџkОтДЃЫПЃ‡n\`9 4'OƒЄЧгЫУЕŸФФUџnЎЬж`UЖž–€go??}–ХЯСЩДƒЈТŸФФ_^d”Щн<.ЁПЈ›bZEQˆФЭЙОМУЩ~KЋŸМЛYVzšТм˜užЌ—yrvk—ІЙЉ™ЏЦЧСq КŸНМebqžрњџчиЬПБ‘„qWx”•ji ЖМХ‡wЇБŸМРvw~ЄУоърЮЗЅ’vt^„П“L7ЁЗЛИЖЙРПŸЄ€‚‘дыђъэрЯЙŸЄ€[x–‡H:žЅЉЕНИЕГŸ ž…Њи№ђјълХЄЁ‚ePbž•xЄБВЖГИИ–W)ІІЛМСзЗЉЦИЄ™“‹}|bŽŠ—ЁЎЊЎЗИИ–MJB€Ќзмп^SГгООБЅ‹|E†œœ–­Б­Г}ŽSDONzxƒЌЫй>0­вМЗЃŒnjSˆ‹™œ ЁЉЈ]IHIQW]” УнŒf ЛЅ‡—‰Jx€ˆ‚…’˜›COC??8b†ЄміђжваФЕЃ“m:bnt}‹‘Žl. *Nz‘МкшнЭЗ­Œ|U=LLJGS\[&…)9[ˆЁЋЌЋЇ”†tdG:LLID7=2‡>WЄ­žŽq^J8D=N;L:65)†?[„ЅЋ™ˆziXH8QEMME6-)‡"S‰­Бž~m\HC?;WJ4/)Š ,XsuqhZH4(" . Œ ”џџjZZYYXVpџ†‡“џџˆŠ€lzi„uџ[YFGIŠџ†‡™sbZrc.cBUZџZXgY[Šџ†‡@^ЎЊ—K(^L7ZwZk•’ZŠџ†‡+-cЇx1.Š ˜œž•y\bZŠџ†‡/1?qMD\ž’‚qY@2++‹Z†‡01CqJh‡‰yeR@51@E‹Z†‡+0Ep‚­ЎŒ{iVD7/Qn…Z˜‚iccz‡ˆ#AsЅВЄŒ|iVD710KXZ!|mkc^iqpZ‡‡VџWiŠš‘†yfR@55F_ZZ_ae]]€_nUZZ‰‡џ}ЁЅ ‘‡ykbXUg„rhgZTPLXN:DiyŸŸСРjџmДоюцрЩЕЄ‹ssƒA/EQ(:PaŠЉЫвŸЦЦeџkОтГЃЫПЃ‡n\`9 4'OƒЄЧгЫУЕŸФФUџnЎЬж`UЗž–€go??}–ХЯСЩДƒЈТŸФФ_^d”Щн<. ПЈ›bZEQˆФЭЙОМУЩKЋŸМЛYVzšТм˜uЌ—yrvk—ІЙЉ™ЏЦЧСq КŸНМebqžрњџчиЬПБ‘„qWx”•ji ЖМХ‡wЇБŸМРvw~ЄУоърЮЗЅ’vt^„П“L7ЁЗЛИЖЙРПŸЃ€‚‘дыђъэрЯЙŸЄ€[x–‡H:žЅЉЕНИЕБŸ ž…Њи№ђјълХЄЁ‚ePbž•xЄБВЖГИВІЉbІІЛМСзЗЈЦИЄ™“‹}|bŽŠ—ЁЎЊЎЗИЕЂ‹Ў‘ €Ќзмп^SГгООБЅ‹|E†œœ–­Б­А}Ћ™ЊЂ"zxƒЌЫй=0­вМЗЃŒnjSˆ‹™œ ЁЉЄ‘­ ЎAW]” УнŒfŸЛЅ‡—ŠGr~‡…’˜šŽzЃ•†Ž(8b†ЄміѓжваФЕЃ‘eOšruŠ‘Žl-F) *Nz‘МкшнЭЗ­Œx^€ВΘ†š|X&…)9[ˆЁЋЌЋЇ”†tdKpШОЌšy‰q‡>WЄ­žŽq^FPŸ“Џ›ЋŒ{h†?[„ЅЋ™ˆziXC[Ж–—œ•…xg‡"S‰­Бž~m\FxŽz•swqNŠ ,XsuqhZH33^TEaEOF  Œ ”џџjZZYYXVpџ„…“џџˆŠ€lzi„uџ[YFGIŠџ„…™sbZrc.cBUZџZXgY[Šџ„…@^ЎЊ—K(^L7ZwZk•’ZŠџ„…+-dЇs./Š ˜œž•y\bZŠџ„…/1?pFB]ž’‚qY@2++‹Z„…01CpBe‡‰yeR@51@E‹Z„…+0Eo~­ЎŒ{iVD7/Qn…Z–€iccy…†#AsІВЄŒ|iVD710KXZ{mjc^iqpZ……VџWiŠš‘†yfR@55F`ZZ^`d\]_`_mUZZ‡…џ}ЁЅ ‘‡ykbXUg„qffZTPLWN:EhyŸŸСРjџmДоюцрЩЕЄ‹ssƒA/DP(9PaŠЉЫбŸЦЦeџkОтБŸЪПЃ‡n\`9 2'O‚ЃЧгЫУЕŸФФUџnЎЭе^R›Зž–€go??}–ХЯСЩД‚ЇТŸФФ_^d”Щм:,žПЈ›bZEPˆФЭЙОМУЩ~J‹ЌŸМЛYVzšТм•rœЌ—yrvk—ІЙЉ˜ЏЦЧСpŒКŸНМebqžрњџциЬПБ‘„qWx”•ifŸЖМХ…tІБŸМРvw~ЄУоърЮЗЅ’vt^„Р“K6ŸИЛИЖЙСПŸЄ€‚‘дыђъэрЯЙŸЄ€[x–‡F8ІЉЕНИЕДŸ ž…Њи№ђјълХЄЁ‚ePbž•vŒЄБВЖГИК’@ІІЛМСжЕЅХИЄ™“‹}|bŽŠ—ЂЎЊЎЗИЙ‘9.(€Ќзмо\QБгООБЅ‹|E†œœ–­Б­ДŠ9(51zxƒЌЫи;.ЋгМЗЃŒnjSˆ‹™œ ЁЉЈJ-.06 W]” Ум‰cžЛЅ‡—‰Kz€ˆƒ†’˜›Ž'0*$(8b†ЄмїѓжваФЕЃ“p4Pms}"Œ‘Žl/*Nz‘МкшнЭЗ­Œ~S(+$+1;P\&…)9[ˆЁЋЌЋЇ”†tdF(%(%$#‡>WЄ­žŽq^K2' ).‡?[„ЅЋ™ˆziXJ,0&+*$‡"S‰­Бž~m\J,41Š ,XsuqhZH5   l8mkЕЯжмпЦWNќџџџџџыГїЦ`Ээџџџџџџџџџџџџbјџџџџџџџџџ;џџџџџеџџџџџџџџ§џџџџџџеџџџџџџџџџџџџџџџзџџџџџџџџџџџџџџџгџџўўўџџџџџџџџџџ RаэфoT№џў§њџџџџџџџџЮDmЫјџџџџџžџџџџџџџџџџџџY ŒйќџџџџџџџџЃџџџџџџџџџџџџgаўџџџџџџџџџџџДџџџџџџџџџџџџ§џџџџџџџџџџџџџџНџџџџџџџџџџџџџџџџџџџџџџџџџџџЧџџџџџџџџџџџџџџџџџџџџџџџџџџџгџџџџџџџџџџџџџџџџџџџџџџџџџџџжџџџџџџџџџџџџџџџџџџџџџџџџџџџ фџџџџџџџџџџџџџџџџџџџџџџџџџџџъџџџџџџџџџџџџџџџџџџџџџџџџџџџяџџџџџџџџџџџџџџџџџџџџџџџџџџџ ѕџџџџџџџџџџџџџџџџџџџџџџџџџџїІ&љџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ 1ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџG6џџџџџџџџџџџџџџџџџџџџџџџџџџџџџ^џџџџџџџџџџџџџџџџџџџџџџџџџџџџљ_жџџџџџџџџџџџџџџџџџџџџџџдhQЅuQ8 їџџџџџџџџџџџџџџџџџџџћЬa Jџџџџџџџџџџџџџџџџџџџџг †џџџџџџџџџџџџџџџџџџџџгЁџџџџџџџџџџџџџџџџџџџіD$Гћџџџџџџџџџџџџџџџџџв 6wЌЮуьё№ъмЮ№йЗѕиндF#!)' it32›§џ‚“Žqn€oligcb_^\YWWURRQOONMLKJJI€H FBKTTSSTYUQOKI‡HJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“Žqn€o(ligcb_]\ZXXWVUSSRQPPOMMLLJCI{ЙщыъъяЛSPOKI‡HJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“Žni€k(geedcba`_^]\[ZYWUTRQOMLLIItБЭШЧШШЪР\PQOKI‡HJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“Žˆ’‘‘Ž‘Šyogbb€ca^ZVY^aeijtxxu|АаРЗЗ€ЖН…MTQOKI‡HJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“€”€›œЅЋЏГБЉšpgo„ЉДСХХФММДЉЏЋаЉЊЋ ­ЅZRTQNKJJI…HJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“€Ž‰ˆ‰ˆ‡Šš­НЬЭЦЕЁŠ€sjmmf]RC2%.К›‚žЁoCHIMNNMMLLJJIHIHHJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“€‘‹€€€|{†Л) ,AS_dc\QD5$2Е‹ƒŽЊЗЖАwePQQPONMLLKKJJ•KJP‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚“‘‘suƒvuoІ$6GVafd]RE6&5Ќz‚~‘”–Œ>csWUTSSRPPONM–LKO‡‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡ƒ– •”“’‘ŽznkhhkeЁ$6GVafd]RE6&5Ђh‚nu: QpWYXWVUTSRQQNM“NK^‰‹ЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚ "œšš™—–•”‘‰u_^__Y™$6GVafd]RE6&4“X‚^ aAkd\WTT‚VTV[’ZYgŠŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡ЅІЂ€žœšš™˜™˜lMRSMŽ$6GVafd]RE6'1INK_ƒa`ЇЄЁœ{jbYRM€Ј‘Ѓ Ђ›Šƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡€H$FMІЇЂЂЁ Ÿžœ››–hD@?‚$6GVafd]RE6'.i9€>;@†„w6K™™ІЕОЪЬЩЛЊЃŠ[a!`e‚€ƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡€,?+'aЖ­ЃЄЄЃЂЁЁ ž Ÿƒ\8t$6GVafd]RE6(,U*./,.oˆƒw= M…ƒ‚„А›ИОF15!-^†ƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/=,]ЕСЉЄІІЅЅЄЃЁБЧWc$6GVafd\PB3$'Ej…ƒ€~qMM}||}}||{x•3:;"8Oƒ„ƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/43+DœдФЌЅІЇЇЄЈЧСy4Y$6GVafb\`SEAAI;GP`‹ˆ‡†…ƒƒ„…{zxrorp†š9;<$=:@‚†ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/433/1bЎзгМЋІРа–NE.L$6GV`cn‰›™—˜–’—™›™‘‹Šˆ‡…„‚‹‹gd|š;>?$>Ai†„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€3279DlІбмжБb@GN+>$6FRd…ŸЅЂЁ Ÿžœš˜˜–•”’‘Ž‹‹“ЇЈ …Z€[Xp›?BC$PN‰O(NM€wz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€38?GP[f‰œA€JIPX€WTt”ŽŠ†‚~yupkgb\XSOJFB>;86‚3 4:. ""0UR‰S(Mo­{wz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚0€38?GP[eˆœA€JIUd€c`y“Š†‚~yupkgb\XSOJFB>;86‚3 49(!nYTˆU)PlЎЌzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€38?GQ\f‰œA€JGZr€pn~“Š†‚~yupkgb\XSOJFB>;86‚3 49  d]VˆW)QˆДЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€38?GQ\f‰œA€JG_€}{„’Š†‚~yupkgb\XSOJFB>;86ƒ3 70 \`Z†[+Z[i‹ВЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€38?GQ]hˆ™A€JFdŒ‰Š‘Š†‚~yupkgb\XSOJFB>;86ƒ3/_Œ}mYOi^†[,\Z`rŠВЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€38?HR^i‡“BJJHAk™–Š†‚~yupkgb\XSOJFB>;86ƒ3 -ež™Ÿl^Y„Z-[YckpŠВЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœŸš›ŸЁ˜œŸ›˜Ÿ•†…‡‚/€38?HR^i…ŒCHDPu›Ѓ€ЂЃ•Š†‚~yupkgb\XSOJFB>;86ƒ3 ,lАЅ“wgga\„]-\ZjmpŠВЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–™šœ š› Ђ˜œŸ›˜Ÿ•†…‡‚.3348?HS_j„…>MuЁВЏ­ЏšŽŠ†‚~yupkgb\XSOJFB>;86ƒ3 ,l“i[ahha[„\-]eimpŠВЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•–˜›–šš›š˜˜š›˜œŸ›™ •†…‡‚*2348?HS_jƒ‡oЉОЛƒИКžŠ†‚~yupkgb\XSOJFB>;86„3;=EXcgh[QƒR!QVjimpŠВЊzwz~ƒ„ƒƒ‰ŠЊЌ“’•—™š••“’‚‘€’‘’—™†ˆ‚'.348@IS_lzŽЂАЕМПРТ€УФЂŒŠ†‚~yupkgb\XSOJFB>;86„34;HVahfV‚Q PQh\himpŠВЊzwz~ƒ„ƒƒ‰ŠЊЌ““•’Œ€‹Œ‹Š‰‹”žЁ–†‹‚&-(148@IT`myƒ– ІЊАЖЖЕЗСІŠ†‚~yupkgb\XSOJFB>;86„34:ES`f\Ošџ­•‹ˆƒ‚‚„„… „ƒ‚†‘ž”lb…‰„ˆƒ%,)29@IUamy…™ ЅЇЈЇЃžš™•Š†‚~yupkgb\XSOJFB>;86„349CQ\[Q˜џŠžЇЉЃŸš’Šƒ~{z{š›yh^_bb†‰„ˆ„%+)5@JUamy…™ ЅЈЉЉЅ ›–“Š†‚~yupkgb\XSOJFB>;86„348BKOO•џ …ywvx~†–ЃІ –”Ž—˜ŒsbY[`bcdb†‰„ˆ„%,&+7GVamy„™ŸЄЈЉЈЅ ›—“Š†‚~yupkgb\XSOJFB>;864ƒ345:>E“џ€ƒ|wonl€mllkjijk|”БЁj\TW\^_abcdb†‰„ˆ„ +&-?@H]lyƒŽ˜žЃІЇЇЃŸš–“Š†‚~yupkgb\XSOJFB>;86ƒ31.1=H‘џvrmleccddedc`an‘Ž~^ˆƒLWZ[]^_abcdb†‰„ˆƒE7DSaf88X]n~Œ–ЂЅІІЂžš–“Š†‚~yupkgb\XSOJFB?;964331/-0:FObŽџ)ŠБЏ˜†wja]YVVWZYWXh|Ž‹z^NIG„‡PXZ[]^_abcdb†‰„ˆ„v6trwCIm]_fvˆ•žЃІІЂŸš—”Š†‚~yupkgb\XSOJGB?<840.-/5?IRZalŠџ-kiib^htƒ˜ЁЂ›“‰{kY`x‹‡rWGBHLOJ…‡PXZ[]^_a`bebˆ‰„ˆ†€4†O[…uskilt|†”–•”’Š‡ƒzvqlhb\WRLGC;831026?ENU\dmrv‡џ.koYXNJFGEDCGKOXdo‚”Ќ ~jO?@AFKPX`hov{~}„џUaUPC@=„?#>;7=Rm~q•€/4;@CEGIKMOJ…‡PXXZ]fozƒœІ†Є…|5zŒ\tЎЂЄЃЂ ™”‘Œ‡ƒpnunkjdda^\YVVWVUUVR7gOPPQTYaipw|„ƒџ4­В}Q=3+.13456652/9RpwZ=&uy0;>ACEGIKMOJ†‡NXblw™ЅБКІ†П…ynwŠ]zИЎГЗЙЙКЙЗДАЋЇ‘•ŒŠ„‚{vusoopoonngH€b`_^aflt{€„‡‡…ƒџQSMj€–Š{cM:1*%&2No{rQ6').+yz1;>ACEGIKMMH‚‰cu€Œ—ЄЏИРЦЪІ†Э…uns…[{ЛАМФЧЬЮЯааЭЩФ‘ЎЕЏЌІЁœ–•’ŽŒŠ‰‡…|W˜pnighlryƒ†‡††t?,& "(2H^u†”™…xbhwkH-")-/0+yz1;>ACEGGHMVeey•Ђ­ЖОФЩЬЯаІ†в…qnpWzКГНЦЭгиоссрмй‘РЯЩЦТНИЗГЏ­ЈЅЃ œ™–ŠaЈyvokkmrw}„…„…f-VtІ“9%"%(+-/0+yz1;>AABFO\kzŠv“ВДНУШЫЮабввІ†в…o7n}WzЗВЛФЬемтхчшхш‘аскижвЮЩЧТОЙЖВ­ЉЅЁ“hБ~yrljjnsx}‚€‚h-"@_eS&ph  "$%(+-/0+yz1::@IXiwƒ‹™ЇЎЩХЪЭЯбб€вгІ†г…^f]nU}ЕВКФЬенрфчщщш‘йшхромйжбЭШТОКЕАЊЄ–kД€zqjhgjnry}~Y  8V^M+ km "$%(+-/0*zy/AUfuŒ• ЋЏНŸЛгЪЮабгзгІЪ…Ы…[n^K0uЌГНСЬдкотхфхш‘кюыхтснйдЯЪФПЛЖБЋІ—mЖ}tlffhlrw||i:# +BJd"24(  lm "$%''*3H^u‚‰sБЎЕМОСЧЧЦЫІСгЪЫЮгЯЙ“z‚ЋІ†Щ…jniq—cGLlБЭйрхщыс€LEEXгткгЯЫХПКЗА­ЉœxЕ“Š|ri_TH8+%:s…k    lm ! "+AXp€‹•ЁЅ‰ЫСЦЩШЩЫЧШЫЅСаЪЫПЃ†€ЂЩнйІ†в†dWgx’ЌА„sx‚˜ЕРЮкІ“БГЁw3JИлжаЬЧРНЙВЌЈšvЄ†qbN?6:BVsKdŒqh  lm&9Sk|‰“žЊГЛИ•зШЬЫШХЫЈТЭ­–ЈЋчдЬЩІ†Ъ…ZXYfw†–ЈНШЭШНЎžЉДЖК•]a|ЊБ=NЊЗБ­Ÿ˜–vldcca[]ht„„|Fcƒsm  ln59_}„žЈБЗЙЛХРšнЪ€ЭЬЬЫЫЧЄЁЇУйуЁЊз€ЬІ†Ш†ZWeuˆ–ЄЎЖТЯизЇтшиЎSAKNRЂ0zœ›Ž•~{‚‰› ЇЎІ­ЈšŠtf`eoEc…tm  by`~XvšžЈВЛОТЦФССœмЩ€ЫЭЬРЌЄБОШвиЧۘЊеЫЫЪІ†Ъ†Wmev…—ЃЎМЦХЪа‘хынœJ:EKKfЙ=ŒЭеЯЯЭ™­ШОКДЊЇІxnhcbepFc„tn %Ccv‚œmСЕЗСРСУТУТОœкШЬЮХЖЃЅЦШ†=*‹ПЩ™ЉЯЩЪЩІ†Щ†Vmdu‡—ЂЎЖЗСУЬ‘оцк˜E0;AEVЖ=}ЗЩЪРУ‘ЉКЅІ œЅ“Š{sidcbpHdƒso" =^v…™ЄЎК}ŸЮПХЧУНЪСФУЖœпЦЙЅ šЮыž!%rЈВ’ЈФ–ЋаФШЪІ†Э†WmfwˆšЈЇЋВОЫЫ‘пшк™A%18;OЕ=zМЧПОС–ЇЛЉІ žœ—Žˆ|sljgipHe‚sr&.Zr‚‹•Ђ­ЕЛОШ†ЄвНСФТРЦНСЧС—ВšЇШкЉъ{cАiwНЂГ“ЊвШЩРІ†Љ…PONZ{›ЌЋЏКМжЫ‘уыкœ<&-2FЕ=zПЩПЕЗœЋК­ІŸŸ˜ŒƒzvnilsMl†ub/Y;T’‘ЈАИМТФУЫˆЅзРТХС€ФСЇ—šИзхзРЊЗmЏ^LFSЅЈЏ˜ЊЦЊˆuІ†~„koliAK}œ ЗЙИПЫб‘пшй7$'=Д>xЖСУКЖ—ЄДЇІЁЂЂš•‰‰{rlsuSnzA3/=^vŒKdЏЋВИНСТЧЦФЪ†ІЯСТШЪОЈ“ЉЭупЩМОТБq#Ж^LJ?N ВГˆm™ХІ†е…v@y‚_Df~ЁЙЧРНЯ‘очзž3 3Г>{ЙРСЏГ  АЋЇ›Ÿ›•Ž†}ytynM92JyZ@[vŒЈ\rФМК€Н*ТФХЧЬˆІзХТА™†˜НйпгТРМОШЧ­\Z›DF@5IЃЉƒ•Ў|гЩІ†Ч†`myœ“qbi’ЊЬЫ‘пхкž- )Г=xФИБІБЂ­ЌЄЈЄ›ŸŸ’…vq_P@GTv“RJi‹ ЙbvЧКЛЗРКОУФУЧˆІЧ–~‚zЭлвНЙУНОУЦРОЌZ^:<5)EЃЂ˜ЮжУ}ЦХІ†Ф†nmw‚žБЌs‚ƒІЃТХаžN-&Г={ИФРВЌšЙНЅЃЈ——zpaPVU^n~‰ŽŠxw\Ss•ЋКb{ТЖЗГЕДНЛХЩН|hx•ХжŒбВШЛЏКИЪСЛКМЌZ^Œ/1+?ЃЕЖКОВ{ЫОІ†П…engw‰–œА‚•жУЖЕЉВМЙНЇ‘|smuК:sŸЗГž”—˜|tjjdb[d}”“–ސy~{dYqŽ­Л_zЩГЙДЗКУРЄ|h„ЗкиаЗ‡аСЙ­­ДЗЬННТЖЋ\^†$' ;ЄЏАЙБЏ}ЦНІ†О„ao`g|…’ЂВŒœЬЭлнклЫаЦККЙЙНОЎYx’ЂЄ›–‰Ђœœ­Ў­П†ŒЌ–†|ƒ}€y~yc[o’ЋЛbwШВЕТЙЈbižджЛЏМФБ„кОНГЕФФКФЗПФ ?b4ЅАЄЛНЉzШКІ†Ш„docm{Š—ЅЗ„“згминсдриРТЌ›ŸЁƒЋРЫЯХФСИЧРЦОРЙЏЇЃu–ЄŒ†ƒ}~€zyvb[r‘ЉЖczШЙЎŠ\IxИсЙX-€ЕБˆгЊМЋКШТЙЛЅžŸМIb{ QЋ­ЃЗЛД~ТœІ†‹„cpam{‹œЈОƒ“йеклпооконуйбЯЫБеЭЧУЙЖЖУЙИ­ЕЎВЎЌЄ|ŽЌŠˆˆƒ~}zxwaVp‘ЃЛfr›aHaXнЬX?ЏД–ЁЏ‹ЫДЎЗМНЕ•ЅФпмEbw/N|ЊГ›ЕНЛЈoz}І—…–…\nVlŽІВЛˆ—зжпмпйслхфццсхл‘сваЧМДИАИИЕЕЎВГВЎƒ˜І’’…†„{€zaCUo’ž™H,KyДЯС]Ш:‘Ћ}[uКЂЏ‰еТНБЅ–ВгуеЬК9\j—ЎДœŒЇО­yЖЭІ†Ю„oƒrDZДШ‹žигзкмнщртфущрнр‘тжЭЭРШОХЛИИЛВЌЊЈВ~–­‹‡Š‹‹ˆlB&N\iZ=6fžРЦМИЏ`lЁ‘SLGQЃЊІŠзЌ ‰УмлХНЖЗТaiТЏЃŠ‚”А ˆ‡ЅЦЯЦЙІ†Л„xovƒ’`Mg–™жзммхтпццъссрзл‘либШТЩМЗЙЎБМЖАЌЏІ~“І–”Ž‚iD(Ctf$;wБФОВБГКДKrŸLNI?LŸАž~’ŠЈ’тбТЗЙПМСМЃvˆ–Ј—ПжЯРЕГНІ†Л„oont’zsƒZ^qЄТгдшьыьээцнлум‘йибЭЬТМЙДИЖЕЕДЌЇЈv›Ћˆ{jZIES{‹wQ4h’ЊЊ­БЏВБИЏ? ЏgGF@5H ™j–Ома–кЎКЗЙИОКБДЌБЋ™šЖдкЩЕЏЖГКЗІ†Ж…‰sŠ“|˜ЦЏЄ‹x‰—ДЦвфэщьнинж‘деЪЮУШТЦОУНГБЊ’ujla``x‰™–‰xl[Yj˜Ѕ­ЏЎЎБДА>ДS@<6*C ЉЗлЦГЅ”гИЖЛЛЖЗНИЖ­ššЋДмкЩГМНЗАЕГЛІООНРЩЪ„ˆt‡˜‹ОКзЩМНОИЖЏГНЦЩЮЬЪЧТКИНОНЁЇ š‹~wkh[ep–šЄЉŸ—Œ†uk\K^}•ЃЋ­­ЋГЗВ>ВK73+ =ЁЖЈЛЗДД”ЬЗИЏЕБЋДБ›ŸЛймІЭЕЛАЙНАЋВЎЗІЕЕКЎ`\„’s‘š ~ƒНЩОШбивншьычудабЬЮМЙМЈ›Є–Ž‹˜˜ЃpžГГЗВЎЅ–‹‹……‚€wi[K]–ЃЋЎ­­АЕГ@ВA,)"9ЃЋ ЗЕАА‘Э›ВЎЏЄš•ІЦокЧЗ дЖМЕЗЌЂАЙЊЎІДНЖ8‚„š^›—І‰ПУСЮдЫйлфэ№ђѕ‘лэыфртчбФФЧИЯЫУЧЮЬШ‚ЦБЄЄЊ›Ѕ–Œ„ƒ{ti[L`}• ЈЊ­АДЈ„8Б9# 3ЄЇ›ГВЋЊЧЅЕЅ”ЋЬмЪ€ЗЖЁгЕЛЙАГЋВЗšxІq>ƒ„‹pŽ—Ї‚˜СНЬЧЬднтхышьё‘лѓщупвувЯЭСПКЖНПСЗЎ…ИЂІЊЇЅЈŠ‡‚}|wqg]N]z‘žЇАЌ’iL`zЏ/0ЂЏ˜ГЅ ЃŠЖ‰Š’ГввЛГВВЗЛДЁвЖДЎВЛК”rЈІ5…ƒ‰pˆŒ­В|’ТУЧЮЭкнстъьь№‘кђщуупрлбЮФХФВЛПЦЃЌМ ЉžЁŸ’Š…€zysoh^MUxЁ™tJDlЄЧžЎ% 1gЖЋšЎЉЂ—xˆ™ЊЮЧПЇ­ЏИЕЖЗГ вИИЙЋ~ИЪЯІ†„‡[†Е~ŽТШЧЫЮйуфцъ№ьё‘ояъчтнегЪЩЯИНГВОБЏН}О­ЅЅЃІ™š†zwsol`N]unO8O…БКЏЅ…­$!>j˜ЖЇ‡•Њ•}…ЊЧХ›НЋИЌ€ДКДЗВЁеВЂŽ‡|ТЮР­–S …ƒ†t‡€U˜wˆУОХЯейпхфъюёє‘кшнуоЭгжШЯЬЛЩБУСИНБzЙЏЈЇЇЉЃ•“‡~|wwv[;F:+2dŸЖАЁœžЁ€Вv‰ЋЗЇ…‚”xxŒГаХАЌ›ЬВДЛКЕИЗЖЗВ›ЕšНЬŠЧЏЌ‚;4, ‚„Љ>Ћ{FEЩЬЫбзйоуцщяђѓ‘гщкжкдмЯаеЫЬУГЭОЕАЎˆОЎ­ЂЊЅ™—“Љ†nI3Y@ BžЌЂœ€™2—™ˆ?ЕДЃy|{pu›ХгН ЏŸАšЮЎЎЋЕМЖЗКЏž•ЌЭжЫЖ‡У­šOAkdH8/ „ЄtІДgCc‘Йжоосхчююёђ‘кфгкдЬизЯФУЭМСЧЈАВЅˆЕЊЌЄЄžЅœ˜‘€gG4N}ˆb,Tއ•œ——™——•„yLuriyЉбЪРДЙЁЕЗЖЭЊАЊКЖЏЉЂНйзСБЕ­…ЛˆXLR|jE>>%„ЂtЁЈЗНЁoJQt˜Игцьёѕєє‘бсопоЭедФУЭВЛКВЏУДЛŒХДДБЉЋš„nT8/J‹_"OŽ’–š›šœ™›˜‡OsaoЄбЬЇ œЄЛ­БЛЋ›гЏИЌЋІЋЫнбЛАББВЋƒœ97@Pk_\KU+„ЄtЃЉЏЖЩЯФІ†svƒ›ЖШйхы‘нђпхпжерЪПФВЏЖЛКФФЊК˜—„zjZX]lŠ]sЅˆƒƒ` O‹”›”•›œІ˜z`_Ы”­ЈЉЅАœГЏЋЙЕŸЯЎЊ— ЛнШДЎАВГГЖЋ~’8MdQW=>;%.6€ƒvœŸЉЎЕРХХЧЩЮеоо‘№ѕђЪ]a|Љ­@†аЯбгПгА­зУНТТОМ­ЋЋЅЄЁ Ѓ^pІ”‘kG„‚`@M‚АЙДŸЃЊЄЊ}ЄДЌДЕЋЅ—’ІЩжЦБ­ЌžСЙЎВААЎžS5-32=5MULaD7;1€ƒŠv‰ŽœЉДОТФЧЧЬдно‘яєц­SAKNRЂ™=­аХЗФЧ™ІШКРЖБЛЎЉЉЄЉЇЁЁŸЂ_qІ•–mDeB:Z“ВЋŸœЂЅЄЅЅЈyЄГЄžЄ­›ˆŠЏвсЛЁЈ­БЏžПЗ­ААЌœf>TpR972EK]oUGGE€ƒ„vƒ‰—ЈБЙТУХФШглн‘яєсœJ:EKKfЙ=–ЬзЪЬЮ›ЉЭЖЛНВМВЉЇІЈЈЃžЁ_nЇ™”—l/`ЊЂ“”™š›—œŸŸІtЄЙЂЄŽ}ŒИеЮВŸЈЌЈ­ЌЏНИ­Јˆ_GQaƒO@>3BV\YNL_T/€ƒoymw—ЂЏЗПФЪЧЪайм‘юєп—E0;AEVЖ>‰ЯлгЪкЁЂЮЛНКЕИЎЖЕЎЌЅ žžboЇ•“™\H€Ž>™’‘’—˜™žЁ˜sІБ~uƒзУІЅЉŸЅЈЌЌЎЎЛАž›Ёe1=F_h`NTABFTICmLK9ƒzyYfЁДКНХШЫЭЮйл‘яєн™A%18;OЕ>ˆЬлкЬеžЃЪХСЖИЗВАЇ­ІЅŸ›™ž^qЄ—•b;@Tit;Ѓ‘Ž•”—–—›ЁЃІzlw˜ЪЧ‰ШžЇ­ЉЇЏЌЋЊЊЋžЄŸЏА[8`YTJ9SXC8=p?MK&@A ƒy‘†BP—РФХЫЫазкл‘яєо›<&-2FЕ>‰апкедІдУПМЛЗЏБЏЊЋІ œ˜›^tЉF.g3Ffr< ‘’“–Ÿ˜ƒiqŸЪЪЋ›†П–ЇЏ ЉЅЄЇЈ šЂЗХЈЉTVJ3]HPk10MegFVMCK=ƒwyu…˜[5]Рбджинм‘юєп7$'=Д>ˆЮпкзйЇдУПЙЗДЖДЏЊЇЃЁžž `VX)F‘}-Dcp< ŠŽ“–oZpЅЧЛЇš›™†П›ЂœŸЅЃЁš–ЅМУДЃ—ž`-%J_x:I<3A78@]XJJW8+ƒuytxŒЋœX;QƒЋШйхт‘№ѕп3 3Г>‡ЭнидзœЇзПННЗВЕАЎ­ЉЇŸ•}_;-I…Ÿ”u0Cbo< ŠŠ‘Œ}bRuЉРГ›•šž™ƒЛ—›žš’“ЅНРЎ œ™’‚.JN[VKW[P@E'?QX_[..- ƒqypt‘ЏУ­‡[VeƒЈП‘щѓп- )Г>„Ыомжи™ЈиЧТХЧКЖЋЂ’gM<:JoЅ›Ž‹w3Dan<ЁŒ‡lNM]ЉГŽ•—‘’–Д“—ˆŽЇНКЈ›˜˜š”Œi'.84,BTSQ^G14.jl8";1ƒiyhn| ЎПиƒЛŸ‘ŸЊКЪŸM-&В>ƒЦкгЬЪ”ŸСЈ™’ŠzhTHFFRrŠœЎЈœ““Œz6D`o=•\@R‹Є]Ђ‡ˆ‹ŠˆŒ‘“Š|Ќ€€‰ЇЛГž’’–””—‘†Y6=>G2Z`T8IYtm.5UA ‚MzKJfy‹œЉГФ‚яцътлжвЫНІ‘}snuЛ9`Ž–‡||rjhdc`bm}”m{МЙЕЉЁ—–›œš‘}9Gb^%BYdNEBGYSC`]z”‡ƒy‚ˆ†„ƒ‚€™…‹}N‚џџ”+[/T……nao‰›Ўy™жЮжмущэя№№яэышс‘цжбЪЧПЛЖЗДЌЌЊЏЋ ЄuŒЂœ˜–‘„‚znV8"8A@C@:gsX>>_hF3Ftƒ}{}œˆpD‚ƒџƒƒџ†-Y25W„~iewštŸдЪажнфщыьэьщцфм‘фвЭЧТМИД­ЌІЇЅЅ˜žj“Ќƒˆˆƒw\;(*=MKX`NAR5RGMF9/,FJdT><:7h|{y{‡> ’џ†€+X-48:Ls’”‚nfhЎВКЪдкпуцчццусож‘сЪЦСМЖЏВБ­ЈЄ •–›œh‰xl\K8.0:FJOK;@QGTSaGAAXT518`[[M\2Jvva1 ”џ†€-V.48=BHaƒœ •„zjk”ЁПвзоццурлг‘пХРКЗВЊЈЈžЈЇ˜’‹ŒiЃwLD;;BST?RUVR_c_E_oRJLaKVO3'=5@`RID[0–џ†€,T048>DKPYl‡ŸЏБЊ›†vnjiq’—˜› Ѕ‘ЯІЌЇЄ›‹Ž’‹{lbXSIK~TScpsqeK>NLGA?F`n]N6Y[XOE1K?(.4\S,J+˜џ†V,,+148=DKS\dnz‰›ЎОЩЮШПГЃ’ƒwqlicƒ‚]_^\\[\[\]`bhr{††Œ…q\G85:HNKFDD?I\`HE^6[XUSK!1:2CH*ІW++-258=CKR\fp{…”žЈАЛХбипцыцснигвЯЪЩЦФЦУППНЛЛБЂ’€lXD91..14$5?\VBF_=DIP'/TN( VUH2ІV,448=CKS\fp|†˜ ІЉЋЋЊЇЂœ•‹‡‚~{vqmida^YVRPLIFB@=615KBGf27(U>.1/@H+#ІW.448=DKS\fq|†˜ ІЊЋЋЊЇЃœ—“‹ˆ„}yuqlhd_[WSNKGC@;06OA0GY0=ZHB[;-2.1LO]M 3FM4)D+/-U?ЅV3348=DKS\gr|†‘™ ІЊЋЋЊЇЂœ—’Ž‹ˆ„}yuqlhd_[WSNKGC@8.7di6IZ/;N`Q>0>Q9-6OTY&"*,K72967?L6 ІU5348=DKS]gr|‡‘™ЁІЉЋЋЉІЂ›–’Ž‹ˆ„}yuqlhd_[WSNKGC?52OSCqQZ3AeZ9=NKJIhn]Fij5(4:H9.*)3<. ЇT5348=DKS]gs}‡‘™ЁІЉЋЋЉІЂ›–’Ž‹ˆ„}yuqlhd_[WSNKGC>4+8VRjULBFCTD+:#=0)7&5&$ЈS3348=DKS]hs~ˆ’šЁІЊЋЋЉІЁš–’Ž‹ˆ„}yuqlhd_[WSNKGC>4+/4VQI\<7:A@;SJA=23L+@RA8+7'8)*0ЉR.248=DKS]ht~‰’šЁІЉЋЋЈІ š•’Ž‹ˆ„}yuqlhd_[WSNKGC>3,=>_lO=3&KT3/BWLB=9L3A<.I)$/45. ЊR/38=DKT^htˆ’šЂІЉЋЋЈЅ š•’Ž‹ˆ„}yuqlhd_[WSNKGC=18EL\UR3;3D6AUTYrxE-;I62/*(.@E*2ЋQ/6=DLT^itŠ“šЂЇЊЋЊЈЅ ™•‘Ž‹ˆ„}yuqlhd_[WSNKGB:0>?.FP@!;O_3Wzhh[P-L,A523%54&84!ЌP-8BJU_iuŠ“šЂЇЊЋЊЈЄŸ™•‘Ž‹ˆ„}yuqlhd_[WSNKGA65KQD%=816]sZ8G=19UDZUULO4.8*1A91@$$4+:"БK'@Tbn{‡‘™ЁЅЈЉЉІЃ™”‘Ž‹ˆ„}yuqlhd_[WSNKF<03LI*5C>'?6;:OO]=I=//$/1;,';(ГH=Wl~‰’šЁЄЇЇІЂ˜”’Ž‹ˆ„}yuqlhd_[WSNKF=.(98-!;0%,'5IN;I:6$ )+*0&!'ЗD 9]wŠ–žŸŸžœ˜“‘Š‡ƒ€}yuqkgc^ZVQLHC<2&(#)+;0"(&0>++/;?+ (*.$#/ Л  %9Igy€……€ƒ4€~|ywsplhc_\WROJD?92*&1-?A0!(-8-,С&)/25AFKMKMMKHA<:2-$(/€ +  Я „џџџГ§џ‚“Žqn€oligcb_^\YWWURRQOONMLKJJI€H FBKTTSSTYUQOKI‡HJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“Žqn€o(ligcb_]\ZXXWVUSSRQPPOMMLLJCI{ЙщыъъяЛSPOKI‡HJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“Žni€k(geedcba`_^]\[ZYWUTRQOMLLIItБЭШЧШШЪР\PQOKI‡HJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“Žˆ’‘‘Ž‘Šyogbb€ca^ZVY^aeijtxxu|АаРЗЗ€ЖН…MTQOKI‡HJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“€”€›œЅЋЏГБЉšpgo„ЉДСХХФММДЉЏЋаЉЊЋ ­ЅZRTQNKJJI…HJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“€Ž‰ˆ‰ˆ‡Šš­НЬЭЦЕЁŠ€sjmmf]RC2%.К›‚žЁoCHIMNNMMLLJJIHIHHJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“€‘‹€€€|{†Л) ,AS_dc\QD5$2Е‹ƒŽЊЗЖАwePQQPONMLLKKJJ•KJP†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚“‘‘suƒvuoІ$6GVafd]RE6&5Ќz‚~‘”–Œ>csWUTSSRPPONM–LKO†ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡ƒ– •”“’‘ŽznkhhkeЁ$6GVafd]RE6&5Ђh‚nu: QpWYXWVUTSRQQNM“NK^‰ŠЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚ "œšš™—–•”‘‰u_^__Y™$6GVafd]RE6&4“X‚^ aAkd\WTT‚VTV[’ZYg‰‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡ЅІЂ€žœšš™˜™˜lMRSMŽ$6GVafd]RE6'1INK_ƒa`ЇЄЁœ{jbYRM€Ј‘Ѓ ЂœŠƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡€H$FMІЇЂЂЁ Ÿžœ››–hD@?‚$6GVafd]RE6'.i9€>;@†„w6K™™ІЕОЪЬЩЛЊЃŠ[a!`e‚€ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡€,?+'aЖ­ЃЄЄЃЂЁЁ ž Ÿƒ\8t$6GVafd]RE6(,U*./,.oˆƒw= M…ƒ‚„А›ИОF15!-]…ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/=,]ЕСЉЄІІЅЅЄЃЁБЧWc$6GVafd\PB3$'Ej…ƒ€~qMM}||}}||{x•3:;"8Oƒƒƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/43+DœдФЌЅІЇЇЄЈЧСx3Y$6GVafb\`SEAAI;GP`‹ˆ‡†…ƒƒ„…{zxrorp†š9;<$=:@†‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/433/1bЎзгМЋІРа•LC-L$6GV`cn‰›™—˜–’—™›™‘‹Šˆ‡…„‚‹‹gd|š;>?$>Ah†„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€3279DlІбмжА`>EL*>$6FRd…ŸЅЂЁ Ÿžœš˜˜–•”’‘Ž‹‹“ЇЈ …Z€[Xp›?BC$BHHL%4#4El™ЇЄ€ЂЁ Ÿž›š˜—šœŸЃАНППЌ‘oK75HQPPMeœDEŒF%DSz~ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38@IWgs–>€H&J42+9ЬЫЦТСМЗЗЕЗЛОЦУШЮгжЯС­ŽmI7/+/5PN‰O(NLŒ€wz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38?GP[f‰œ?€HGOX€WTt”ŽŠ†‚~yupkgb\XSOJFB>;86‚3 4:. ""0UR‰S(MoЌ{wz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚0€38?GP[eˆœ?€HGSd€c`y“Š†‚~yupkgb\XSOJFB>;86‚3 49(!nYTˆU)Pk­Ћzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38?GQ\f‰œ?€HEYr€pn~“Š†‚~yupkgb\XSOJFB>;86‚3 49  d]VˆW)QˆГЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38?GQ\f‰œ?€HE^€}{„’Š†‚~yupkgb\XSOJFB>;86ƒ3 70 \`Z†[+Z[i‹АЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38?GQ]hˆ™?€HDcŒ‰Š‘Š†‚~yupkgb\XSOJFB>;86ƒ3/_Œ}mYOi^†[,\Z`rŠАЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38?HR^i‡“@HHF?j™–Š†‚~yupkgb\XSOJFB>;86ƒ3 -ež™Ÿl^Y„Z-[YcjpŠАЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœŸš›Ÿ ˜œŸ›˜ž”†…‡‚/€38?HR^i…‹AFBNt›Ѓ€ЂЃ•Š†‚~yupkgb\XSOJFB>;86ƒ3 ,lАЅ“wgga\„]-\ZjmpŠАЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–™šœ š› Ё˜œŸ›˜ž”†…‡‚.3348?HS_j„…;KtЁВЏ­ЏšŽŠ†‚~yupkgb\XSOJFB>;86ƒ3 ,l“i[ahha[„\-]eilpŠАЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•–˜›–šš›š˜˜š›˜œŸ›™Ÿ”†…‡‚*2348?HS_jƒ†nЉОЛƒИКžŠ†‚~yupkgb\XSOJFB>;86„3;=EXcgh[QƒR!QVjilpŠАЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž’•—™›••’’‚‘€’‘’—˜†ˆ‚'.348@IS_lzŽЂАЕМПРТ€УФЂŒŠ†‚~yupkgb\XSOJFB>;86„34;HVahfV‚Q PQg\hilpŠАЉzwz}ƒ„‚ƒˆ‰ЉЋ’Ž“•‘Œ€‹Œ ‹Š‰‹”žЁ–Љ„Š‚&-(148@IT`myƒ– ІЊАЖЖЕЗСІŠ†‚~yupkgb\XSOJFB>;86„34:ES`f\OšџЌ”Šˆƒ‚‚„„… „ƒ‚†‘ž”lb„ˆ„‡ƒ%,)29@IUamy…™ ЅЇЈЇЃžš™•Š†‚~yupkgb\XSOJFB>;86„349CQ\[Q˜џ ‰žЇЈЂž™’Šƒ~€{ š›yh^_bb…ˆ„‡„%+)5@JUamy…™ ЅЈЉЉЅ ›–“Š†‚~yupkgb\XSOJFB>;86„348BKOO•џ „~ywvx~†Ž•œЂЅŸ–“Ž—˜ŒsbY[`bcdb…ˆ„‡„%,&+7GVamy„™ŸЄЈЉЈЅ ›—“Š†‚~yupkgb\XSOJFB>;864ƒ345:>E“џƒ|wonl€mllkjijk|”АЁj\TW\^_abcdb…ˆ„‡„ +&-?@H]lyƒŽ˜žЃІЇЇЃŸš–“Š†‚~yupkgb\XSOJFB>;86ƒ31.1=H‘џvrmleccddedc`an‘Ž~^ˆ‚LWZ[]^_abcdb…ˆ„‡ƒE7DSaf88X]n~Œ–ЂЅІІЂžš–“Š†‚~yupkgb\XSOJFB?;964331/-0:FObŽџ)ŠАЎ˜†wja]YVVWZYWXh|Ž‹z^NIG„†PXZ[]^_abcdb…ˆ„‡„v6trwCIm]_fvˆ•žЃІІЂŸš—”Š†‚~yupkgb\XSOJGB?<840.-/5?IRZalŠџ-kiib^hsƒŽ— Ёš’‰{kY`x‹‡rWFBHLOJ…†PXZ[]^_a`beb‡ˆ„‡†€4†O[…uskilt|†”–•”’Š‡ƒzvqlhb\WRLGC;831026?ENU\dmrv‡џ.knYXNJGGEDCFKNXdo‚“Ќ ~jO?@AFKPX`hov{~}„џU`UPC@=„?#>;7=Rm~q”/4;@CEGIKMOJ…†PXXZ]eozƒœІ†Є…|5zŒ\tЎЂЄЃЂ ™”‘Œ‡ƒpnunkjdda^\YVVWVUUVR7gOPPQTYaipw|„ƒџ4­Б}Q<3+.13456652/9RpwZ=&sy0;>ACEGIKMOJ††NXbkw™ЅБКІ†П…ynwŠ]zИЎГЗЙЙКЙЗДАЋЇ‘•ŒŠ„‚{vusoopoonngH€b`_^aflt{€„‡‡…ƒџQRMj–‰zcM:1*%&2No{rQ6').+xz1;>ACEGIKMMH‰cu€Œ—ЄЏИРЦЪІ†Э…uns…[{ЛАМФЧЬЮЯааЭЩФ‘ЎЕЏЌІЁœ–•’ŽŒŠ‰‡…|W˜pnighlryƒ†‡††t?,& "(2H^u†”˜„xahwkH-")-/0+xz1;>ACEGGHMVdey•Ђ­ЖОФЩЬЯаІ†в…qnpWzКГНЦЭгиоссрмй‘РЯЩЦТНИЗГЏ­ЈЅЃ œ™–ŠaЈyvokkmrw}„…„…f-VsЅ’9%"%(+-/0+xz1;>AABFO\kzŠv“ВДНУШЫЮабввІ†в…o7n}WzЗВЛФЬемтхчшхш‘аскижвЮЩЧТОЙЖВ­ЉЅЁ“hБ~yrljjnsx}‚€‚h-"@_eS&oh  "$%(+-/0+xz1::@IWiwƒ‹™ЇЎЩХЪЭЯбб€вгІ†г…^f]nU}ЕВКФЬенрфчщщш‘йшхромйжбЭШТОКЕАЊЄ–kД€zqjhgjnry}~Y  8V^M+ jm "$%(+-/0*yy/AUfuŒ• ЋЏНŸЛгЪЮабгзгІЪ…Ы…[n^K0uЌГНСЬдкотхфхш‘кюыхтснйдЯЪФПЛЖБЋІ—mЖ}tlffhlrw||i:# +BJd"24(  km "$%''*3G^u‚‰sБЎЕМОСЧЧЦЫІСгЪЫЮгЯЙ“z‚ЋІ†Щ…jniq—cGLlБЭйрхщысJBBVгткгЯЫХПКЗА­ЉœxЕ“Š|ri_TH8+%:s…k    km ! "+AXp‹•ЁЅ‰ЫСЦЩШЩЫЧШЫЅСаЪЫПЃ†€ЂЩнйІ†в†dWgx’ЌА„sx‚˜ЕРЮкІ“БГЁv/HИлжаЬЧРНЙВЌЈšvЄ†qbN?6:BVsKdŒqh  km&9Sk|‰“žЊГЛИ•зШЬЫШХЫЈТЭ­–ЈЋчдЬЩІ†Ъ…ZXYfw†–ЈНШЭШНЎžЉДЕК•^a|ЌВ:KЊЗБ­Ÿ˜–vldcca[]ht„„|Fcƒsm  lm59_}„žЈБЗЙЛХРšнЪ€ЭЬЬЫЫЧЄЁЇУйуЁЊз€ЬІ†Ш†ZWeuˆ–ЄЎЖТЯизЇтшйЎRAKMRЃ-zœ›Ž•~{‚‰› ЇЎІ­ЈšŠtf`eoEc…tm  by`~XvšžЈВЛОТЦФССœмЩ€ЫЭЬРЌЄБОШвиЧۘЊеЫЫЪІ†Ъ†Wmev…—ЃЎМЦХЪа‘хъоœI:EKKfК:ŒЭеЯЯЭ™­ШОКДЊЇІxnhcbepFc„tn %Ccu‚œmСЕЗСРСУТУТОœкШЬЮХЖЃЅЦШ…=*‹ПЩ™ЉЯЩЪЩІ†Щ†Vmdu‡—ЂЎЖЗСУЬ‘охл˜D0;AEVЗ:}ЗЩЪРУ‘ЉКЅІ œЅ“Š{sidcbpHdƒso" =^v…™ЄЎК}ŸЮПХЧУНЪСФУЖœпЦЙЅ šЮыž!&sЉГ“ЈФ–ЋаФШЪІ†Э†WmfwˆšЈЇЋВОЫЫ‘пшк˜@%18;OЖ:zМЧПОС–ЇЛЉІ žœ—Žˆ|sljgipHe‚sr&.Zr‚‹•Ђ­ЕЛОШ†ЄвНСФТРЦНСЧС—ВšЇШкЉъ{dБ‘iwНЂГ“ЊвШЩРІ†Љ…PONZ{›ЌЋЏКМжЫ‘уык›:&-2FЕ:yПЩПЕЗœЋК­ІŸŸ˜ŒƒzvnilsMl†ub/X;T’‘ЈАИМТФУЫˆЅзРТХС€ФСЇ—šИзхзРЊЗnА^LGRЄЈЏ˜ЊЦЊˆuІ†~„koliAK}œ ЗЙИПЫб‘пшк6$'=Е;xЖСУКЖ—ЄДЇІЁЂЂš•‰‰{rlsuSnzA3/=^vŒKdЏЋВИНСТЧЦФЪ†ІЯСТШЪОЈ“ЉЭупЩМОТБq#З_LJ@MŸВГˆm™ХІ†е…v@y‚_Df~ЁЙЧРНЯ‘очзž2 3Д;zЙРСЏГ  АЋЇ›Ÿ›•Ž†}ytynM92JyZ?[vŒЈ\rФМК€Н*ТФХЧЬˆІзХТА™†˜НйпгТРМОШЧ­\[œDF@5HЂЉ‚•Ў|гЩІ†Ч†`myœ“qbi’ЊЬЫ‘пхк, )Д:wФИБІБЂ­ЌЄЈЄ›ŸŸ’…vq_P@GTv“RJi‹ ЙbvЧКЛЗРКОУФУЧˆІЧ–~‚zЭлвНЙУНОУЦРОЌZ_‘:<5)CЃЃ˜ЮжУ}ЦХІ†Ф†nmw‚žБЌs‚ƒІЃТХаžL+%Г:{ИФРВЌšЙНЅЃЈ——zpaPVU^n~‰ŽŠxw\Ss•ЋКb{ТЖЗГЕДНЛХЩН|hx•ХжŒбВШЛЏКИЪСЛКМЌZ^Œ/1+>ЂЖЖКОВ{ЫОІ†П…engw‰–œА‚•жУЖЕЉВЛКОІ|qksК7rŸЗГž”—˜|tjjdb[d}”“–ސy~{dYqŽ­Л_zЩГЙДЗКУРЄ|h„ЗкиаЗ‡аСЙ­­ДЗЬННТЖЋ[_‡$' :ЄААЙБЏ}ЦНІ†О„ao`g|…’ЂВŒœЬЭлнклЬаЦЛЛККООЏYx’ЂЄ›–‰Ђœœ­Ў­П†ŒЌ–†|ƒ}€y~yc[o’ЋЛbwШВЕТЙЈbižджЛЏМФБ„кОНГЕФФКФЗПФ ?c3ЅАЄЛНЉzШКІ†Ш„docm{Š—ЅЗ„“згминсдриРТЌ›ŸЁƒЋРЫЯХФСИЧРЦОРЙЏЇЃu–ЄŒ†ƒ}~€zyvb[r‘ЉЖczШЙЎŠ\IxИсЙX.€ЕБˆгЊМЋКШТЙЛЅžŸМHc| OЋЎЃЗЛД~ТœІ†‹„cpam{‹œЈОƒ“йеклпооконуйбЯЫБеЭЧУЙЖЖУЙИ­ЕЎВЎЌЄ|ŽЌŠˆˆƒ~}zxwaVp‘ЃЛfr›aHaXнЬX@АЕ—ЁЏ‹ЫДЎЗМНЕ•ЅФпмEcx.M{ЊДœЕНЛЈoz}І—…–…\nVlŽІВЛˆ—зжпмпйслхфццсхл‘сваЧМДИАИИЕЕЎВГВЎƒ˜І’’…†„{€zaCUo’ž™H,KyДЯС]Ш:‘Ћ}[sЛЂЏ‰еТНБЅ–ВгуеЬК9\i–ЏЕœЇО­yЖЭІ†Ю„oƒrDZДШ‹žигзкмнщртфущрнр‘тжЭЭРШОХЛИИЛВЌЊЈВ~–­‹‡Š‹‹ˆlB&N\iZ=6fžРЦМИЏ`lЂ‘SLGPЃЋІŠзЌ ‰УмлХНЖЗТajУАЃ‹‚”А ˆ‡ЅЦЯЦЙІ†Л„xovƒ’`Mg–™жзммхтпццъссрзл‘либШТЩМЗЙЎБМЖАЌЏІ~“І–”Ž‚iD(Ctf$;wБФОВБГКДKr LNI?KžАž~’ŠЈ’тбТЗЙПМСМЃvˆ–Ј—ПжЯРЕГНІ†Л„oont’zsƒZ^qЄТгдшьыьээцнлум‘йибЭЬТМЙДИЖЕЕДЌЇЈv›Ћˆ{jZIES{‹wQ4h’ЊЊ­БЏВБИЏ? АgGF@5G šj–Ома–кЎКЗЙИОКБДЌБЋ™šЖдкЩЕЏЖГКЗІ†Ж…‰sŠ“|˜ЦЏЄ‹x‰—ДЦвфэщьнинж‘деЪЮУШТЦОУНГБЊ’ujla``x‰™–‰xl[Yj˜Ѕ­ЏЎЎБДА>ЕS@<6*BŸЊЖлЦГЅ”гИЖЛЛЖЗНИЖ­ššЋДмкЩГМНЗАЕГЛІООНРЩЪ„ˆt‡˜‹ОКзЩМНОИЖЏГНЦЩЮЬЪЧТКИНОНЁЇ š‹~wkh[ep–šЄЉŸ—Œ†uk\K^}•ЃЋ­­ЋГЗВ>ГK73+ <ЁЗЈЛЗДД”ЬЗИЏЕБЋДБ›ŸЛймІЭЕЛАЙНАЋВЎЗІЕЕКЎ`\„’s‘š ~ƒНЩОШбивншьычудабЬЮМЙМЈ›Є–Ž‹˜˜ЃpžГГЗВЎЅ–‹‹……‚€wi[K]–ЃЋЎ­­АЕГ@ГA,)"8ЃЋ ЗЕАА‘Э›ВЎЏЄš•ІЦокЧЗ дЖМЕЗЌЂАЙЊЎІДНЖ8‚„š^›—І‰ПУСЮдЫйлфэ№ђѕ‘лэыфртчбФФЧИЯЫУЧЮЬШ‚ЦБЄЄЊ›Ѕ–Œ„ƒ{ti[L`}• ЈЊ­АДЈ„8В9# 2ЃЈ›ГВЋЊЧЅЕЅ”ЋЬмЪ€ЗЖЁгЕЛЙАГЋВЗšxІq>ƒ„‹pŽ—Ї‚˜СНЬЧЬднтхышьё‘лѓщупвувЯЭСПКЖНПСЗЎ…ИЂІЊЇЅЈŠ‡‚}|wqg]N]z‘žЇАЌ’iL`zА0/ЁА˜ГЅ ЃŠЖ‰Š’ГввЛГВВЗЛДЁвЖДЎВЛК”rЈІ5…ƒ‰pˆŒ­В|’ТУЧЮЭкнстъьь№‘кђщуупрлбЮФХФВЛПЦЃЌМ ЉžЁŸ’Š…€zysoh^MUxЁ™tJDlЄЧžЏ% 0eЖЋšЎЉЂ—xˆ™ЊЮЧПЇ­ЏИЕЖЗГ вИИЙЋ~ИЪЫІ†„‡[†Е~ŽТШЧЫЮйуфцъ№ьё‘ояъчтнегЪЩЯИНГВОБЏН}О­ЅЅЃІ™š†zwsol`N]unO8O…БКЏЅ…Ў$>i˜ЖЈ†•Њ•}…ЊЧХ›НЋИЌ€ДКДЗВЁеВЂŽ‡|ТЮРЉЃ‰"…ƒ†t‡€U˜wˆУОХЯейпхфъюёє‘кшнуоЭгжШЯЬЛЩБУСИНБzЙЏЈЇЇЉЃ•“‡~|wwv[;F:+2dŸЖАЁœžЁ€ГuˆЋЙЈ…‚”xxŒГаХАЌ›ЬВДЛКЕИЗЖЗВ›ЕšНЬŠЧЏЇ™‘zH8$‚„Љ>Ћ{FEЩЬЫбзйоуцщяђѓ‘гщкжкдмЯаеЫЬУГЭОЕАЎˆОЎ­ЂЊЅ™—“Љ†nI3Y@ BžЌЂœ€™2—™ˆ?ЗЕЄy|{pu›ХгН ЏŸАšЮЎЎЋЕМЖЗКЏž•ЌЭжЫЖ‡УЉ˜›žЦМ‹|„ЄuІДgCc‘Йжоосхчююёђ‘кфгкдЬизЯФУЭМСЧЈАВЅˆЕЊЌЄЄžЅœ˜‘€gG4N}ˆb,Tއ•œ——™——•„yLuriyЉбЪРДЙЁЕЗЖЭЊАЊКЖЏЉЂНйзСБЕ­…К™ЋЊлР’ˆŒd€„ЂuЁЈЗНЁoJQt˜Игцьёѕєє‘бсопоЭедФУЭВЛКВЏУДЛŒХДДБЉЋš„nT8/J‹_"OŽ’–š›šœ™›˜†OsaoЄбЬЇ œЄЛ­БЛЋ›гЏИЌЋІЋЫнбЛАББВЋЇ‰ЊЬЛЖšЈm€„ЄuЃЉЏЖЩЯФІ†svƒ›ЖШйхы‘нђрхпжерЪПФВЏЖЛКФФЊК˜—„zjZX]lŠ]sЅˆƒƒ` O‹”›”•›œІ˜z`_Ы”­ЈЉЅАœГЏЋЙЕŸЯЎЊ— ЛнШДЎАВГГЖЋ|–БЪБЕ•Й€„ІuЅЋБИПУЭиммвФЕžЎЗРЦГ“Š‡”ЙЦЙКСЅОМ›“ž–‘—ŠqieolŽ ЈВЏЊbpЃ‘ˆdMˆŠ”•›ЁhOeШЦЖ{ЄХЏЎЏИЇ›ІІ•ЏœЛ”ŸНмДТНЈ­АБВАВГЉw‹šМ’œН™ФЊoƒ€…ЇtЊБИМХЩЬЮбкшчЋяёьЩЈ­Њœ{GwАЊš‹В›ЊŒƒІЁš ЋДМТООГЌЋŸЂ_rЃ“•gIˆ˜xQIrЇПЗЈЊЉ~ЂЕЈЋКЏЋГЁœЏœ‡ЂФзЭКœУТБАЏББ­Їž•mvy‡•œ——nz…1€ƒvœŸЉЎЕРХХЧЩЮеоо‘№ѕђЫ]a|ЊЎ>…аЯбгПгА­зУНТТОМ­ЋЋЅЄЁ Ѓ^pІ”‘kG„‚`@M‚АЙДŸЃЊЄЊ}ЄДЌДЕЋЅ—’ІЩжЦБ­ЌžСЙЎВАА­žŽ“~|‚ŒЋАЅО•„‰}<€ƒŠy‰ŽœЉДОТФЧЧЬдно‘яєц­RAKMRЃ˜;­аХЗФЧ™ІШКРЖБЛЎЉЉЄЉЇЁЁŸЂ_qІ•–mDeB:Z“ВЋŸœЂЅЄЅЅЈyЄГЄžЄ­›ˆŠЏвсЛЁЈ­БЏžПЗ­ААЊ’…Ÿ­ЫЈ…„ƒЂЃЖЬЉ”‘‘Tƒ„yƒ‰—ЈБЙТУХФШглн‘яєт›I:EKKfК:•ЬзЪЬЮ›ЉЭЖЛНВМВЉЇІЈЈЃžЁ_nЇ™”—l/`ЊЂ“”™š›—œŸŸІtЄЙЂЄŽ}ŒИеЮВŸЈЌЈ­ЌЏНИ­Јœ™ЏКсž‹‡|™ЖЛДЃœГЄqƒoymw—ЂЏЗПФЪЧЪайм‘юєп—D0;AEVЖ;‰ЯлгЪкЁЂЮЛНКЕИЎЖЕЎЌЅ žžboЇ•“™\H€Ž>™’‘’—˜™žЁ˜sІБ~uƒзУІЅЉŸЅЈЌЌЎЎЛАžš ‘•žЁМЦМ Ѕ”ЃДЂ–Ы™˜„ƒzyYfЁДКНХШЫЭЮйл‘яѓп˜@%18;OЖ;‡ЬлкЬеžЃЪХСЖИЗВАЇ­ІЅŸ›™ž^qЄ—•b;@Tit;Ѓ‘Ž•”—–—›ЁЃІzlw˜ЪЧ‰ШžЇ­ЉЇЏЌЋЊЊЋžЄŸЎЌ|—ЦМДЄ‰Њ­‘‹šкœЈŸfŠ’)ƒy‘†BP—РФХЫЫазкл‘яѓпš:&-2FЕ;ˆапкедІдУПМЛЗЏБЏЊЋІ œ˜›^tЉF.g3Ffr< ‘’“–Ÿ˜ƒiqŸЪЪЋ›†П–ЇЏ ЉЅЄЇЈ šЂЗХЈЈŒЛЌŽСЄЌЫyyЁЧбЅЕЇ—žIƒwyu…˜[5]Рбджинм‘юѓпœ6$'=Д;‡ЮпкзйЇдУПЙЗДЖДЏЊЇЃЁžž `VX)F‘}-Dcp< ŠŽ“–oZpЅЧЛЇš›™†П›ЂœŸЅЃЁš–ЅМУДЃ– ˆ||ЈУц˜І€‘‡ЗЕІЄВ…p ƒuytxŒЋœX;QƒЋШйхт‘№ѕр2 3Д;†ЮнидзœЇзПННЗВЕАЎ­ЉЇŸ•}_;-I…Ÿ”u0Cbo< ŠŠ‘Œ}bRuЉРГ›•šž™ƒЛ—›žš’“ЅНРЎ œ™|ЄЈМЖЌДКЎ–šo\‘ЄАРЗzwx%ƒqypt‘ЏУ­‡[VeƒЈП‘щѓр, )Г;ƒЫомжи™ЈиЧТХЧКЖЋЂ’gM<:JoЅ›Ž‹w3Dan<ЁŒ‡lNM]ЉГŽ•—‘’–Д“—ˆŽЇНКЈ›˜˜š”ˆ}ns‚„z˜ЇЋЎО|ztЦШ†\i‹2ƒiyhn| ЎПиƒЛŸ‘ŸЊКЫžL+%Г;‚ЦкгЬЪ”ŸСЈ™’ŠzhTHFFRrŠœЎЈœ““Œz6D`o=•\@R‹Є]Ђ‡ˆ‹ŠˆŒ‘“Š|Ќ€€‰ЇЛГž’’–””—‘t~€ƒ’\zЏКЎ…Zb‘ЋвЬy„А”e‚MzKJfy‹œЉГФ‚яцътлжвЫПІ|rltЛ6_Ž–‡||rjhdc`bm}”m{МЙЕЉЁ—–›œš‘}9Gb^% ’џ†€+X-48:Ls’”‚nfhЎВКЪдкпуцчццусож‘сЪЦСМЖЏВБ­ЈЄ •–›œh‰xl\K7-fŸЅРЩТГИХЖНЛХЅ  Е­„€€ВБВ™Ў{hqva1 ”џ†€-V.48=BHaƒœ •„zjk”ЁПвзоццурлг‘пХРКЗВЊЈЈžЈЇ˜’‹ŒiЃwLD;;BOfЇЬЬЪШвбЮЖЫзЕЋЊПЂЌžoUh†|ЖЁžfW0–џ†€,T048>DKPYl‡ŸЏБЊ›†vnjiq’—˜› Ѕ‘ЯІЌЇЄ›‹Ž’‹{lbXSIK~TScpsq^ЗТТНЙЕИЬйЦØКЙВЄ•rˆsZtwВЄlœ]˜џ†W,,+148=DKS\dnz‰›ЎОЩЮШПГЃ’ƒwqlicƒ‚]_^\\[\[\]`bhr{††Œ„q\G53ˆНТСЙЖГБЕЦЩЋzЃК‰ЕVЈž•ŠYt‚{‘™kЅW++-258=CKR\fp{…”žЈАЛХбипцыцснигвЯЪЩЦФЦУППНЛЛБЂ’€lXD6++(@rrœЕЭХААЪЉЎБВ„ŠЌЋzd‚ŒWoax’—•}*ЅW+448=CKS\fp{†—ŸЄЈЉЈЇЇІЃЁІЋЏЕВБЗЖГЏЉ™”‚wiZQIB:738jY8DyuOŽЛОМЋЎСœЎЊŒЉ­Ÿ‘cu™rnceƒБА›NІW,448=CKS\fp|†˜ ІЉЋЋЊЇЂœ•‹‡‚~{vqmida^YVRPLIFB@<5G•Ђ™Њ–_bЗКСЪЈ•‡Ё­ЃЧ‚OkАsum˜d`vdЅW.448=DKS\fq|†˜ ІЊЋЋЊЇЃœ—“‹ˆ„}yuqlhd_[WSNKGC@8>ƒДЂŒЃЕcœЗЅЂУЂ’ЎАНЅ]h™Ÿyk“jgJt­“^ЅW3348=DKS\gr|†‘™ ІЊЋЋЊЇЂœ—’Ž‹ˆ„}yuqlhd_[WSNKGC@5>—Эа”ЈЗz•ЈНЌ˜ЁВ–Š“ЏЖЗхrnuvЂ…zƒu‡Ђ…_#ЅU5348=DKS]gr|‡‘™ЁІЉЋЋЉІЂ›–’Ž‹ˆ„}yuqlhd_[WSNKGC?3XЖЙЅдАИ„˜СЙ“™­ЇЂžУЫЗЪЬ‰v‡Ž ˆt[ngqŠ~2ЇT5348=DKS]gs}‡‘™ЁІЉЋЋЉІЂ›–’Ž‹ˆ„}yuqlhd_[WSNKGC>3YšМДЩГЇ•ЉœšХхЉ}‚œˆŒ’•­˜zŽq”qƒg€gHb?ЈS3348=DKS]hs~ˆ’šЁІЊЋЋЉІЁš–’Ž‹ˆ„}yuqlhd_[WSNKGC>0?ˆ’ЖЈЄЙ‡€†…~ЃšŽ‰{~ЅsЉ“‰WyŠm‚kny3ЉR.248=DKS]ht~‰’šЁІЉЋЋЈІ š•’Ž‹ˆ„}yuqlhd_[WSNKGC>.K——Оа­~h•ЃvqЎ‘Œ‡Ё}‡wЂsbcft}x'ЊR/38=DKT^htˆ’šЂІЉЋЋЈЅ š•’Ž‹ˆ„}yuqlhd_[WSNKGC;9yžЃЙВЋƒ‹x„k}œ™ЄЭиkƒš}yytqx0‘–Sl~5ЋR/6=DLT^itŠ“šЂЇЊЋЊЈЅ ™•‘Ž‹ˆ„}yuqlhd_[WSNKGB6P“ŒušЈ’kˆ˜ЇT‘ЭЎВЇ›hšhˆyu|j‚MhƒWdIЋP-8BJU_iuŠ“šЂЇЊЋЊЈЄŸ™•‘Ž‹ˆ„}yuqlhd_[WSNKG@5jœžWf†„{l{ГГt|qv‘|Žjp˜ƒkNOZSu™mc'ЎN #8FQ\hu€Š’šЂІЉЊЊЇЄŸ™•‘Ž‹ˆ„}yuqlhd_[WSNKG;C~АЩЉ|“„tIcuš“™šocr]m‹u“eUep‰d9АK'@Tbn{‡‘™ЁЅЈЉЉІЃ™”‘Ž‹ˆ„}yuqlhd_[WSNKF8N|’`wŽˆj‰mjg”ЏuŒ{daO>pr<Œs]h‹XlX ГH=Wl~‰’šЁЄЇЇІЂ˜”’Ž‹ˆ„}yuqlhd_[WSNKF<5Jyq]R€sanVHRd…‘s‘yqL@SkNjnzf\fPOЗD 9]wŠ–žŸŸžœ˜“‘Š‡ƒ€}yuqkgc^ZVQLHC<1"HY@H^g‚s]eNYfxYW^s€XQdisb_xEJY.Л  %9Igy€……€ƒ4€~|ywsplhc_\WROJD?92*6]nh…vb@ M_F]r^bK3FKI[FZ_D6С&)/25AFKMKMMKHA<:2-$Egs;;3€ HKhS0*#!ЯŒ#„џџџВ§џ‚“Žqn€oligcb_^\YWWURRQOONMLKJJI€H FBKTTSSTYUQOKI‡HJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“Žqn€o(ligcb_]\ZXXWVUSSRQPPOMMLLJCI{ЙщыъъяЛSPOKI‡HJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“Žni€k(geedcba`_^]\[ZYWUTRQOMLLIItБЭШЧШШЪР\PQOKI‡HJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“Žˆ’‘‘Ž‘Šyogbb€ca^ZVY^aeijtxxu|АаРЗЗ€ЖН…MTQOKI‡HJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“€”€›œЅЋЏГБЉšpgo„ЉДСХХФММДЉЏЋаЉЊЋ ­ЅZRTQNKJJI…HJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“€Ž‰ˆ‰ˆ‡Šš­НЬЭЦЕЁŠ€sjmmf]RC2%.К›‚žЁoCHIMNNMMLLJJIHIHHJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“€‘‹€€€|{†Л) ,AS_dc\QD5$2Е‹ƒŽЊЗЖАwePQQPONMLLKKJJ•KJO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚“‘‘suƒvuoІ$6GVafd]RE6&5Ќz‚~‘”–Œ>csWUTSSRPPONM–LKO…‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……ƒ– •”“’‘ŽznkhhkeЁ$6GVafd]RE6&5Ђh‚nu: QpWYXWVUTSRQQNM“NK]ˆ‰ŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚ "œšš™—–•”‘‰u_^__Y™$6GVafd]RE6&4“X‚^ aAkd\WTT‚VTV[’ZYf€ˆˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……ЅІЂ€žœšš™˜™˜lMRSMŽ$6GVafd]RE6'1INK_ƒa`ЇЄЁœ{jbYRM€Ј‘Ѓ Ђ›‰‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……€H$FMІЇЂЂЁ Ÿžœ››–hD@?‚$6GVafd]RE6'.i9€>;@†„w6K™™ІЕОЪЬЩЛЊЃŠ[a!`e‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……€,?+'aЖ­ЃЄЄЃЂЁЁ ž Ÿƒ\8t$6GVafd]RE6(,U*./,.oˆƒw= M…ƒ‚„А›ИОF15!-]„~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/=,]ЕСЉЄІІЅЅЄЃЁБЧVc$6GVafd\PB3$'Ej…ƒ€~qMM}||}}||{x•3:;"8O‚‚~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/43+DœдФЌЅІЇЇЄЈЧПq/Z$6GVafb\`SEAAI;GP`‹ˆ‡†…ƒƒ„…{zxrorp†š9;<$=:@…~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/433/1bЎзгМЋІРЯ‘F;)L$6GV`cn‰›™—˜–’—™›™‘‹Šˆ‡…„‚‹‹gd|š;>?$>Ah„ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€3279DlІбмжЎZ7>D&?$6FRd…ŸЅЂЁ Ÿžœš˜˜–•”’‘Ž‹‹“ЇЈ …Z€[Xp›?BC$=cƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38@JVd{ЋЏ7;AAE!4#4El™ЇЄ€ЂЁ Ÿž›š˜—šœŸЃАНППЌ‘oK75HQPPMeœDEŒF%DSx}ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38@IWgs—š7€A&C02+9ЬЫЦТСМЗЗЕЗЛОЦУШЮгжЯС­ŽmI7/+/5PNŠO'MŠ~vx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38?GP[f‰™8€A@JY€WTt”ŽŠ†‚~yupkgb\XSOJFB>;86‚3 4:. ""0UR‰S(NmЉyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚0€38?GP[e‰™8€A?Oe€c`y“Š†‚~yupkgb\XSOJFB>;86‚3 49(!nYTˆU)QjЉЇyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38?GQ\f‰™8€A>Tr€pn~“Š†‚~yupkgb\XSOJFB>;86‚3 49  d]VˆW)Q†ЏЅyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38?GQ\f‰™8€A>Z€}{„’Š†‚~yupkgb\XSOJFB>;86ƒ3 70 \`Z†[+Z[gˆЌЅyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38?GQ]h‰–8€A<_‰Š‘Š†‚~yupkgb\XSOJFB>;86ƒ3/_Œ}mYOi^†[,\Z`q‡ЌЅyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38?HR^iˆ9AA?7fš–Š†‚~yupkgb\XSOJFB>;86ƒ3 -ež™Ÿl^Y…Z,Ycio‡ЌЅyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›ššž˜š™—œ“„……‚/€38?HR^i…ˆ:?:GpšЄ€ЂЃ•Š†‚~yupkgb\XSOJFB>;86ƒ3 ,lАЅ“wgga\…],Zikn‡ЌЅyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•˜™›žššžŸ˜š™—œ“„……‚.3348?HS_j…‚4Dp ГЏ­ЏšŽŠ†‚~yupkgb\XSOJFB>;86ƒ3 ,l“i[ahha[„\-]dgkn‡ЌЅyvx|ƒ~‚‡ˆŽЅЇ‘“”–™•™™š™˜˜™š˜š™˜“„……‚*2348?HS_jƒƒiЇПМƒИКžŠ†‚~yupkgb\XSOJFB>;86„3;=EXcgh[Q„R Vigkn‡ЌЅyvx|ƒ~‚‡ˆŽЅЇ‘“•—™”•’’‚‘€’‘’–—††‚'.348@IS_lzŽЂБЕМПРТ€УФЂŒŠ†‚~yupkgb\XSOJFB>;86„34;HVahfV‚Q"PQf[fgkn‡ЌЅyvx|ƒ~‚‡ˆŽЅЇ‘‘“‘ŒŒ‹‹‚Œ‹Š‰‹”žЁ–†ˆ‚&-(148@IT`myƒ– ІЊАЖЖЕЗСІŠ†‚~yupkgb\XSOJFB>;86„34:ES`f\OšџЈ“‰ˆ€ƒ„„… „ƒ‚†œž”lb‚†„…ƒ%,)29@IUamy…™ ЅЇЈЇЃžš™•Š†‚~yupkgb\XSOJFB>;86„349CQ\[Q˜џ ˆŒšЃЄŸ›—‰ƒ~€{ Œššyh^_bbƒ†„…„%+)5@JUamy…™ ЅЈЉЉЅ ›–“Š†‚~yupkgb\XSOJFB>;86„348BKOO•џ ƒ~€~ywvx}…Œ“™žЁœ“‘Ž——ŒsbY[`bcdbƒ†„…„%,&+7GVamy„™ŸЄЈЉЈЅ ›—“Š†‚~yupkgb\XSOJFB>;864ƒ345:>E“џ~{vonl€mllkjijk{’›ЏŸj\TW\^_abcdbƒ†„…„ +&-?@H]lyƒŽ˜žЃІЇЇЃŸš–“Š†‚~yupkgb\XSOJFB>;86ƒ31.1=H‘џuqlkeccddedc`an‘Ž~_…€MWZ[]^_abcdbƒ†„…ƒE7DSaf88X]n~Œ–ЂЅІІЂžš–“Š†‚~yupkgb\XSOJFB?;964331/-0:FObŽџ)‡ЋЉ•ƒvj`]YVVXZYWXh|Ž‹z^NIH„QXZ[]^_abcdbƒ†„…„v6trwCIm]_fvˆ•žЃІІЂŸš—”Š†‚~yupkgb\XSOJGB?<840.-/5?IRZalŠџ-igha]gr€‹”—†xjX`x‹‡rWFBHLOK‚„QXZ[]^_aabeb„†„…†€4†O[…uskilt|†”–•”’Š‡ƒzvqlhb\WRLGC;831026?ENU\dmrv‡џ/imXWMJGGEDCGKNWcm€ЉŸ~jO?@AFKPX`hov{~}„џT`TOC@=„?#>;7>Rm~q“}04;@CEGIKMOK‚„QXXZ]eozƒœІ†Є…|5zŒ\tЎЂЄЃЂ ™”‘Œ‡ƒpnunkjdda^\YVVWVUUVR7gOPPQTYaipw|„ƒџ4ЉЌzP<3,.13456652/9QpwZ=&qw1;>ACEGIKMOKƒ„NXakw™ЅБКІ†П…ynwŠ]zИЎГЗЙЙКЙЗДАЋЇ‘•ŒŠ„‚{vusoopoonngH€b`_^aflt{€„‡‡…ƒџOQLh}Œ™’†xaM91*&&2Mo{qQ6').+vx2;>ACEGIKMMI†cu€Œ—ЄЏИРЦЪІ†Э…uns…[{ЛАМФЧЬЮЯааЭЩФ‘ЎЕЏЌІЁœ–•’ŽŒŠ‰‡…|W˜pnighlryƒ†‡††t>,& "(2G\rƒ”vahwkH-")-/0+vx2;>ACEGGHMVddx•Ђ­ЖОФЩЬЯаІ†в…qnpWzКГНЦЭгиоссрмй‘РЯЩЦТНИЗГЏ­ЈЅЃ œ™–ŠaЈyvokkmrw}„…„…f-UrЄ‘9%"%(+-/0+vx2;>ABBFO\kzŠv“ВДНУШЫЮабввІ†в…o7n}WzЗВЛФЬемтхчшхш‘аскижвЮЩЧТОЙЖВ­ЉЅЁ“hБ~yrljjnsx}‚€‚h-"@_eS'mf  "$%(+-/0+vx2::@IWiwƒ‹™ЇЎЩХЪЭЯбб€вгІ†г…^f]nU}ЕВКФЬенрфчщщш‘йшхромйжбЭШТОКЕАЊЄ–kД€zqjhgjnry}~Y  8V^M+ hk "$%(+-/0*ww0AUfuŒ• ЋЏНŸЛгЪЮабгзгІЪ…Ы…[n^K0uЌГНСЬдкотхфхш‘кюыхтснйдЯЪФПЛЖБЋІ—mЖ}tlffhlrw||i:# +BJd"24(  ik "$%''*3G^u‚‰sБЎЕМОСЧЧЦЫІСгЪЫЮгЯЙ“z‚ЋІ†Щ…jniq—cGLlБЭйрхщыс{D;=QŒгткгЯЫХПКЗА­ЉœxЕ“Š|ri_TH8+%:s…k    ik ! "+AXp‹•ЁЅ‰ЫСЦЩШЩЫЧШЫЅСаЪЫПЃ†€ЂЩнйІ†в†dWgx’ЌА„sx‚˜ЕРЮкЃŒЋ­›o(BЗлжаЬЧРНЙВЌЈšvЄ†qbN?6:BVsKdŒqh  ik%9Sj{‰“žЊГЛИ•зШЬЫШХЫЈТЭ­–ЈЋчдЬЩІ†Ъ…ZXYfw†–ЈНШЭШНЎžЉДЕЕ\a{ЈЌ2GЊЗБ­Ÿ˜–vldcca[]ht„„|Fcƒsm  ik59_}„žЈБЗЙЛХРšнЪ€ЭЬЬЫЫЧЄЁЇУйуЁЊз€ЬІ†Ш†ZWeuˆ–ЄЎЖТЯизЇтшжЇOAKNSŸ–'yœ›Ž•~{‚‰› ЇЎІ­ЈšŠtf`eoEc…tm  `w`~XvšžЈВЛОТЦФССœмЩ€ЫЭЬРЌЄБОЩвиЧۘЊеЫЫЪІ†Ъ†Wmev…—ЃЎМЦХЪа‘хыл–G;EKLeД4‹ЭеЯЯЭ™­ШОКДЊЇІxnhcbepFc„tn %Bcv‚œmСЕЗСРСУТУТОœкШЬЮХЖЃЅЦШ†=*‹ПЩ™ЉЯЩЪЩІ†Щ†Vmdu‡—ЂЎЖЗСУЬ‘оци‘B0;AEVБ4}ЗЩЪРУ‘ЉКЅІ œЅ“Š{sidcbpHdƒso" =]v…™ЄЎК}ŸЮПХЧУНЪСФУЖœпЦЙЅ šЮыž!$oЄ­ЈФ–ЋаФШЪІ†Э†WmfwˆšЈЇЋВОЫЫ‘пшз’=%18;NА4yМЧПОС–ЇЛЉІ žœ—Žˆ|sljgipHe‚sr&-Yr‚Œ•Ђ­ЕЛОШ†ЄвНСФТРЦНСЧС—ВšЇШкЉъ{aЌhsЗЁГ“ЊвШЩРІ†Љ…PONZ{›ЌЋЏКМжЫ‘уыз•8&-2EА4yПЩПЕЗœЋК­ІŸŸ˜ŒƒzvnilsMl†ub/X;T’‘ЈАИМТФУЫˆЅзРТХС€ФСЇ—šИзхзРЊЗjЋ^LGPžЅА˜ЊЦЊˆuІ†~„koliAK}œ ЗЙИПЫб‘пшз—3$'<Џ4wЖСУКЖ—ЄДЇІЁЂЂš•‰‰{rlsuSnzA3/=^vŒKdЏЋВИНСТЧЦФЪ†ІЯСТШЪОЈ“ЉЭупЩМОТБq!Б^LJ@K˜ЏГˆm™ХІ†е…v@y‚_Df~ЁЙЧРНЯ‘очд—/ 3Ў4zЙРСЏГ  АЋЇ›Ÿ›•Ž†}ytynM92JyZ?[vŒЈ\rФМК€Н*ТФХЧЬˆІзХТА™†˜НйпгТРМОШЧ­]W˜DF@5EœІƒ•Ў|гЩІ†Ч†`myœ“qbi’ЊЬЫ‘пхз—* )Ў3xФИБІБЂ­ЌЄЈЄ›ŸŸ’…vq_P@GTv“RJi‹ ЙbvЧКЛЗРКОУФУЧˆІЧ–~‚zЭлвНЙУНОУЦРОЌ[[:<5)@ ˜ЮжУ}ЦХІ†Ф†nmw‚žБЌs‚ƒІЃТХЭ—H)%­3zИФРВЌšЙНЅЃЈ——zpaPVU^n~‰ŽŠxw\Ss•ЋКb{ТЖЗГЕДНЛХЩН|hx•ХжŒбВШЛЏКИЪСЛКМЌZ[‰01+<œГЖКОВ{ЫОІ†П…engw‰–œА‚•жУЖЕЉВМЗИ ŠvlgoД1rŸЗГž”—˜|tjjdb[d}”“–ސy~{dYqŽ­Л_zЩГЙДЗКУРЄ|h„ЗкиаЗ‡аСЙ­­ДЗЬННТЖЋ\\ƒ$' 7ž­АЙБЏ}ЦНІ†О„ao`g|…’ЂВŒœЬЭлнклЬаХЗЖДДИЙЊXx’ЂЄ›–‰Ђœœ­Ў­П†ŒЌ–†|ƒ}€y~yc[o’ЋЛbwШВЕТЙЈbižджЛЏМФБ„кОНГЕФФКФЗПФ ?`~0ž­ЄЛНЉzШКІ†Ш„docm{Š—ЅЗ„“згминсдрйРТЌ›Ÿ ƒЌРЫЯХФСИЧРЦОРЙЏЇЃu–ЄŒ†ƒ}~€zyvb[r‘ЉЖczШЙЎŠ\IxИсЙY-ЕБˆгЊМЋКШТЙЛЅžŸМI_x KЄЋЃЗЛД~ТœІ†‹„cpam{‹œЈОƒ“йеклпооконуйбЯЫБеЭЧУЙЖЖУЙИ­ЕЎВЎЌЄ|ŽЌŠˆˆƒ~}zxwaVp‘ЃЛfr›aHaXнЬX=ŠЋЏ“ЁЏ‹ЫДЎЗМНЕ•ЅФпмF_t,IvЄЏšЕНЛЈoz}І—…–…\nVlŽІВЛˆ—зжпмпйслхфццсхл‘сваЧМДИАИИЕЕЎВГВЎƒ˜І’’…†„{€zaCUo’ž™H,KyДЯС]Ш:Ї|[pДЁЏ‰еТНБЅ–ВгуеЬК9Y˜dЉАšŒЇО­yЖЭІ†Ю„oƒrDZДШ‹žигзкмнщртфущрнр‘тжЭЭРШОХЛИИЛВЌЊЈВ~–­‹‡Š‹‹ˆlB&N\iZ=6fžРЦМИЏ`lSLGNЈЇŠзЌ ‰УмлХНЖЗТbgНЋ ‰‚”А ˆ‡ЅЦЯЦЙІ†Л„xovƒ’`Mg–™жзммхтпццъссрзл‘либШТЩМЗЙЎБМЖАЌЏІ~“І–”Ž‚iD(Ctf$;wБФОВБГКДKnœMNI@I˜Ўž~’ŠЈ’тбТЗЙПМСМЃuˆ–Ј—ПжЯРЕГНІ†Л„oont’zsƒZ^qЄТгдшьыьээцнлум‘йибЭЬТМЙДИЖЕЕДЌЇЈv›Ћˆ{jZIES{‹wQ4h’ЊЊ­БЏВБИЏ? ЋfHF@5E™–j–Ома–кЎКЗЙИОКБДЌБЋ™šЖдкЩЕЏЖГКЗІ†Ж…‰sŠ“|˜ЦЏЄ‹x‰—ДЦвфэщьнинж‘деЪЮУШТЦОУНГБЊ’ujla``x‰™–‰xl[Yj˜Ѕ­ЏЎЎБДА>АR@<6+?™ЇЗлЦГЅ”гИЖЛЛЖЗНИЖ­ššЋДмкЩГМНЗАЕГЛІООНРЩЪ„ˆt‡˜‹ОКзЩМНОИЖЏГНЦЩЮЬЪЧТКИНОНЁЇ š‹~wkh[ep–šЄЉŸ—Œ†uk\K^}•ЃЋ­­ЋГЗВ>­K73+ :›ДЈЛЗДД”ЬЗИЏЕБЋДБ›ŸЛймІЭЕЛАЙНАЋВЎЗІЕЕКЎ`\„’s‘š ~ƒНЩОШбивншьычудабЬЮМЙМЈ›Є–Ž‹˜˜ЃpžГГЗВЎЅ–‹‹……‚€wi[K]–ЃЋЎ­­АЕГ@­A,)"5Ј ЗЕАА‘Э›ВЎЏЄš•ІЦокЧЗ дЖМЕЗЌЂАЙЊЎІДНЖ8‚„š^›—І‰ПУСЮдЫйлфэ№ђѕ‘лэыфртчбФФЧИЯЫУЧЮЬШ‚ЦБЄЄЊ›Ѕ–Œ„ƒ{ti[L`}• ЈЊ­АДЈ„8­8# 0Ѕ›ГВЋЊЧЅЕЅ”ЋЬмЪ€ЗЖЁгЕЛЙАГЋВЗšxІq>ƒ„‹pŽ—Ї‚˜СНЬЧЬднтхышьё‘лѓщупвувЯЭСПКЖНПСЗЎ…ИЂІЊЇЅЈŠ‡‚}|wqg]N]z‘žЇАЌ’iL`zЊ/,›­˜ГЅ ЃŠЖ‰Š’ГввЛГВВЗЛДЁвЖДЎВЛК”rЈІ5…ƒ‰pˆŒ­В|’ТУЧЮЭкнстъьь№‘кђщуупрлбЮФХФВЛПЦЃЌМ ЉžЁŸ’Š…€zysoh^MUxЁ™tJDlЄЧžЊ% -aАЈšЎЉЂ—xˆ™ЊЮЧПЇ­ЏИЕЖЗГ вИИЙЋ~ИЪЯІ†„‡[†Е~ŽТШЧЫЮйуфцъ№ьё‘ояъчтнегЪЩЯИНГВОБЏН}О­ЅЅЃІ™š†zwsol`N]unO8O…БКЏЅ…Љ#;e‘БЄ‡–Њ•}…ЊЧХ›НЋИЌ€ДКДЗВЁеВЂŽ‡|ТЮРЎ‘B…ƒ†t‡€U˜wˆУОХЯейпхфъюёє‘кшнуоЭгжШЯЬЛЩБУСИНБzЙЏЈЇЇЉЃ•“‡~|wwv[;F:+2dŸЖАЁœžЁ€­pƒЅГЄ„ƒ•wxŒГаХАЌ›ЬВДЛКЕИЗЖЗВ›ЕšНЬŠЧЏЌz‚„Љ>Ћ{FEЩЬЫбзйоуцщяђѓ‘гщкжкдмЯаеЫЬУГЭОЕАЎˆОЎ­ЂЊЅ™—“Љ†nI3Y@ BžЌЂœ€™2—™ˆ?БЏ Œy|{pu›ХгН ЏŸАšЮЎЎЋЕМЖЗКЏž•ЌЭжЫЖ‡УЏœ:%]O)„ЄtІДgCc‘Йжоосхчююёђ‘кфгкдЬизЯФУЭМСЧЈАВЅˆЕЊЌЄЄžЅœ˜‘€gG4N}ˆb,Tއ•œ——™——•„xLuriyЉбЪРДЙЁЕЗЖЭЊАЊКЖЏЉЂНйзСБЕ­…Л‚E+0fU%! „ЂtЁЈЗНЁoJQt˜Игцьёѕєє‘бсопоЭедФУЭВЛКВЏУДЛŒХДДБЉЋš„nT8/J‹_"OŽ’–š›šœ™›˜‡OsaoЄбЬЇ œЄЛ­БЛЋ›гЏИЌЋІЋЫнбЛАББВЋƒ™ "3SH>-9„ЄtЃЉЏЖЩЯФІ†svƒ›ЖШйхы‘нђрхпжерЪПФВЏЖЛКФФЊК˜—„zjZX]lŠ]sЅˆƒƒ` O‹”›”•›œІ˜z`_Ы”­ЈЉЅАœГЏЋЙЕŸЯЎЊ— ЛнШДЎАВГГЖЋ~"6R;A!$B/ „ІuЅЋБИПУЭиммвФЕžЎЗРЦВ†„’ИЦЙКСЅОМ›“ž–‘—ŠqieolŽ ЈВЏЊbpЃ‘ˆdMˆŠ”•›ЁhOeШЦЖ{ЄХЏЎЏИЇ›ІІ•ЏœЛ”ŸНмДТНЈ­АБВАГЙЎ|{.8%B&K?€…ЇtЊБИМХЩЬЮбкшчЋяёэЧЂЇЃ•tAuАЊš‹В›ЊŒƒІЁš ЋДМТООГЌЋŸЂ_rЃ“•gIˆ˜xQIrЇПЗЈЊЉ~ЂЕЈЋКЏЋГЁœЏœ‡ЂФзЭКœУТБАЏББАІuqV$ #&' €ƒvœŸЉЎЕРХХЧЩЮеоо‘№ѕёЦ‹\azЇЇ6‚аЯбгПгА­зУНТТОМ­ЋЋЅЄЁ Ѓ^pІ”‘kG„‚`@M‚АЙДŸЃЊЄЊ}ЄДЌДЕЋЅ—’ІЩжЦБ­ЌžСЙЎВААЎž@(270P(€ƒŠv‰ŽœЉДОТФЧЧЬдно‘яєхЇOAKNSŸ’4­аХЗФЧ™ІШКРЖБЛЎЉЉЄЉЇЁЁŸЂ_qІ•–mDeB:Z“ВЋŸœЂЅЄЅЅЈyЄГЄžЄ­›ˆŠЏвсЛЁЈ­БЏžПЗ­ААЌŸ\">c7#)=V9))'€ƒ„vƒ‰—ЈБЙТУХФШглн‘яѕп•G;EKLeД3•ЬзЪЬЮ›ЉЭЖЛНВМВЉЇІЈЈЃžЁ_nЇ™”—l/`ЊЂ“”™š›—œŸŸІtЄЙЂЄŽ}ŒИеЮВŸЈЌЈ­ЌЏНИ­Јž†T,/Cq3! +?ED3+B7€ƒoymw—ЂЏЗПФЪЧЪайм‘юѕм‘B0;AEVА4ˆЯлгЪкЁЂЮЛНКЕИЎЖЕЎЌЅ žžboЇ•“™\H€Ž>™’‘’—˜™žЁ˜sІБ~uƒзУІЅЉŸЅЈЌЌЎЎЛАž›ЂX)DQG.8$*.;.&R0.ƒzyYfЁДКНХШЫЭЮйл‘яєл‘=%18;NА4‡ЬлкЬеžЃЪХСЖИЗВАЇ­ІЅŸ›™ž^qЄ—•b;@Tit;Ѓ‘Ž•”—–—›ЁЃІzlw˜ЪЧ‰ШžЇ­ЉЇЏЌЋЊЊЋžЄŸЏАQND?25;("Z%20%%ƒy‘†BP—РФХЫЫазкл‘яєм•8&-2EЏ4ˆапкедІдУПМЛЗЏБЏЊЋІ œ˜›^tЉF.g3Ffr< ‘’“–Ÿ˜ƒiqŸЪЪЋ›†П–ЇЏ ЉЅЄЇЈ šЂЗХЈЉ‘C6,D-6R6PS,=4)0! ƒwyu…˜[5]Рбджинм‘юєм–3$'<Џ5‡ЮпкзйЇдУПЙЗДЖДЏЊЇЃЁžž `VX)F‘}-Dcp< ŠŽ“–oZpЅЧЛЇš›™†П›ЂœŸЅЃЁš–ЅМУДЃ—žR /Ff!/!)$B?10> ƒuytxŒЋœX;QƒЋШйхт‘№ѕн–/ 3Ў5†ЮнидзœЇзПННЗВЕАЎ­ЉЇŸ•}_;-I…Ÿ”u0Cbo< ŠŠ‘Œ}bRuЉРГ›•šž™ƒЛ—›žš’“ЅНРЎ œ™“.7<;0 ’џ†€+X-48:Ls’”‚nfhЎВКЪдкпуцчццусож‘сЪЦСМЖЏВБ­ЈЄ •–›œh‰xl\K8/")%&$$",0=!31 JE>-?=xva1 ”џ†€-V.48=BHaƒœ •„zjk”ЁПвзоццурлг‘пХРКЗВЊЈЈžЈЇ˜’‹ŒiЃwLD;;BTO!/11.>C>DKPYl‡ŸЏБЊ›†vnjiq’—˜› Ѕ‘ЯІЌЇЄ›‹Ž’‹{lbXSIK~TScpsqg<))$#>H3$37-<(D<,˜џ†V,,+148=DKS\dnz‰›ЎОЩЮШПГЃ’ƒwqlicƒ‚]_^\\[\[\]`bhr{††Œ…q\G96" +'"#-<7##8"C>771"+,ІW++-258=CKR\fp{…”žЈАЛХбипцыцснигвЯЪЩЦФЦУППНЛЛБЂ’€lXD92.0, 93 %3, 9> 1  $4,,)ЅW+448=CKS\fp{†—ŸЄЈЉЈЇЇІЃЁІЋЏЕВБЗЖГЏЉ™”‚wiZQIB:750!&)")-+!8  &**( 6 '=>2 ІV,448=CKS\fp|†˜ ІЉЋЋЊЇЂœ•‹‡‚~{vqmida^YVRPLIFB@=6*) ,17= $0 ?<%*6 ІW.448=DKS\fq|†˜ ІЊЋЋЊЇЃœ—“‹ˆ„}yuqlhd_[WSNKGC@<- 4" "96!<;0D9&,#&;( ЅV3348=DKS\gr|†‘™ ІЊЋЋЊЇЂœ—’Ž‹ˆ„}yuqlhd_[WSNKGC@9(KM$=)8).,7Ct  1',6# ІU5348=DKS]gr|‡‘™ЁІЉЋЋЉІЂ›–’Ž‹ˆ„}yuqlhd_[WSNKGC?5'38'P.?"@2'">D5&IK.!!)ЇT5348=DKS]gs}‡‘™ЁІЉЋЋЉІЂ›–’Ž‹ˆ„}yuqlhd_[WSNKGC>4=5H71!+'&H`6 !$3%! ЈR3348=DKS]hs~ˆ’šЁІЊЋЋЉІЁš–’Ž‹ˆ„}yuqlhd_[WSNKGC>5%9+-B# $1% & !1*$ !ЊR.248=DKS]ht~‰’šЁІЉЋЋЈІ š•’Ž‹ˆ„}yuqlhd_[WSNKGC>5 #)& % .+.=;0 ) # ДH=Wl~‰’šЁЄЇЇІЂ˜”’Ž‹ˆ„}yuqlhd_[WSNKF=,  '.5(! ЗD 9]wŠ–žŸŸžœ˜“‘Š‡ƒ€}yuqkgc^ZVQLHC<3)    & Л  %9Igy€……€ƒ3€~|ywsplhc_\WROJD?92* %(    Т%)/25AFKMKMMKHA<:2-$ ‚ ЯŽˆџџџГt8mk@ (5*! œџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњПk/ +>VlT3# ЭџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјЙe- "! ђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѕДa+ HџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓЎ\* vџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№ЊY( ЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэІV' еџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкY& !їџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџв" PџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљKџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“ЏџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџКпџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩ9њџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњ`mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ÿџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєž% Ѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџй-rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЌE 1ФџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџР?JЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџеB EБ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœ62wЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯP* !?|Фіџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђp5!7ašЮђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ—> &=Y„ЏзіџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёќџџџџџџџџџџџџџџџџџџНI) !-CZ{šГЯшї§џџџџџџџџџџџџџџџџџџџџџџџћђрблјџџџџџџТ_eЧџџџџџџткхјџџџџџ§УT. %.>O\r†—ЃАМУЬбблпппзабШСЗЊž|fYUZm‹ЦєњРВ;|м§џђМkUVu œ†…„h>) !%),28=@BGJJIE@@;60*'# ,;OpwE4" ,b}d@)    #   ic08Рp jP ‡ ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cџOџQ2џR џ\ PXX`XX`XX`XXXPPXџdKakadu-v5.2.1џ Пƒџ“ЯС:7Ј_ЃйдVEй Ш—c№"› Џрb”Т™jЌƒЎcDЩЗGкpЬяЌФэ07Œcљч–ЭrДюі!sЈзuph4ЌЯР\S `P+Ыу!#еуKТ)|Њ_д5-Чк0Rс їса~Fџ}bН=фГ“=s ЯС$‹–Ёž•b™ јЙЕ>aЖЕќŸФCGВ„Х3Р"ФйŠчВЈн•Э‹2>ў,ђNˆц?Њ™C^N6ь‡ Ц)ы›y8"ГЧр‡?4h~ з™јzФAДшзФЏ„ї`—‹o*шoАнХШd;ЮN`ЄЁ,юX‹ZЖ9iцЅ ~ХпїƒŸнКш—ыhb\“дJіEU№ћї˜%ЪЙЇъ‡ќ7*ОZl–ВbНH‰КV‹ œию‘ˆПоТ‹Э- mжUƒ#raZ“О?œЅМŸЈg-!Й~”“nТвђua,!„ц†_ЄЈ*p*ЌК•Aj™—јж•ц$ю8РгЌ;6/рЉSЫј ЊŠЯ!ЇУэ‡к9Рp]Щ[#AЁИL5кpК %mгœ3; SQкUŸxcјО&%ХuP#yЁ.Џяqщ†bLЈЈю<Ї["ѓыђІўмDUƒ/ЛmLu9<^Сѕ УэƒэMШoЕЗЉ3 jУЋд,ѓœ›аћUE‚Q}ЙрЉЌь€R2яPHС АёнЩъ+oLЅ] C‡\ŠyЫogЅдLГў4%vс„kžЯЬњ?xќЮ€9dŸ ѕFBРи|ннщVwуP/ћn…a(иS!CиgТo#’ат†FЫй­сyА&а:>…ЁоЋT’.ЎmЬеFh[вЛxLлfљДnV™• E1ўП|ђЯMѓцžsbHbѓW]eЦf]њБ%4к"hэ}K&qˆѓlХ^ѕ7Б‡Нт”gяк]E,ю€H7Єљ…КnT*,ЧrRУ%]Qщ!kaco(КЧсnOЮё‡сqvьсёZk цФkŠ“?ЭКJЬhМуgZлŽaŸ<}œтцД5ql:Ї№•›у,6ТЯjb х8Чxœь Х‡2C; Eqў0|QђуKB№L|ѓ{‡yВ`‚gв{гa<Ышt,фьKM)АЧ*ЛЉв6”ИЉТеVŸ1!гmŸQ‡)мOgjV4 ЄкцбŒВš›dq,ЃE.Ћ“JюFкХQЦˆ7gТзŠЧ7 ќњbPџa‰bхPŽi3дsъPLйŽЃЁ2":0ЪсuЊ`ІШНмнэW4p4лЂ^bшы’Јˆizл_B3&-8Я}Œh$uё%gыkзО@-є~­(F№я4IЉZ6=с!YЭŠGЙІ ѓQћЦFSœБиtZ/љЬ ЌiЖЛEЊў—QяVјт9‘?—W‘žњ~*Г9RЈЖГ2бЧŽе_z‡ЌџAŽKнfИm‚={#ИQѕЗгЛ‡ухƒ‚g…œД‹t;є‰,”(P-№ШfюKcl’`Lа№YїžK+n1ьLQкоЯ.ѓЫчƒo`ЇP. _ †ѓЮ'пвeА5Bд15]!аЧƒš„/:ЮЋ­ѕ:–Ж‘! $=ѓZpтE^§ЏŸ$O П~TмхЌн@АЅ8o vUм9ђvірї’йk*пЧ’ТЧМЗ™/б3N3ŠГ_s/6,šLЩђйБўAa(vьхЁИ(…ђ;ZjƒHМэjчб0Зйxѕ%NЗўЪњ~“rфk“vGnћmЕнлtи˜r7в_šЧ; Џ5HЊb_bс”H$З?фQјЉDUJw!v7р%0ѓт-Ю&%Ѕ\љCpФ%&%Ѓ–”Шщ>тјЁУэE‡кк”šeAЋъЩяыŸhUф_ Љър:кЉЎЧJљЛА^”а6ЋУ^ѕ!ŠBЄ™2ԘХSWїЃ7FІеёўmŠlс} Дщ1ЪВyЙ€Ѕџƒ†иЌPЅєЛƒHЌBrGRy*—ВЌRŸЦ. ЫњљTE˜7иПџHJ|ЄПIiЅу,Qœ~щQXQйРšЅрЅHЖхўЇeОнЄ‘фю•‡P­А…№ЏД#Я8Ш•Э`йљС‹шJ•чл_ИАSDeж\ЄХo"ЪЙ]Е4ФЭ!х5МЎУэ?ƒъ8ƒэAœФAхrКЛShњcЌn„ ч!ЯOрЩзd?ЃС\ЇЗœ)СЬ””ђƒ”ЛюСB–вghеЬWdЫі, s—›ЈфіNRНб=›,uGщ|ј{ $ЃG(!­квYяЏцCtW­њк7Р}tkLž(sП6Ї"xhтS•‡+^sЧџ3ЮД—:tд хz.› ЊyЪЪ–ГХвjЉ‡.Ћ3ЬD‰IpЏ ”ьчuЋљ[вD_]ЧсHЯЮ‰‡сB€*eцˆCvЃSВуШ_к uGўGЇи9IUЗьЊ&е~Sƒ‘œЩ‚шQеGMf˜Є‘(R 'WГAJ–'!—€›ЫЅЎ9]БХ#щl!Т6ћа2п DЁ~waх'Д•I№ŽПЮуqн“#эАіNФьЄЇsЂ@Тї€чЦЁiЫх~*M0ydŸЛyŸ ЦЄлЌ>ajjгфЁcЦзЁђ.E™]›2’:WQ:АkŽвcLƒиIеƒ–;-ыq[~ †hЙ4чPу:гЄМ@П€р"EnXы‹‡єр 7‰Wзo?юЯ)KжŽ?ў§Џвh‡k ДG /Зчv†ІfRЭv9р/ч9œ‚ј 1!­ерŒў;IоюUgR[+J€чzП9–i‡џ бн,ЕХH1ЬшP8иПи9ŽЁkCd(ЎЮ ЃЙЫЇШьуЧЂа<:ёћ-ЕХіГŠaИ"пТЖ(‡€в„і]виiq:;šОks;FХe˜lъ@М}gш/ИЭtЦFЌ ŽWЧсз|~”У№ыœЩ<эI љчуо+щŠл-ќ‰Š‚ЯWŒ8j-С7F П кс:Kk›‹У-шAп3ЦW х!п‘хŽ№/ˆoь5РvМ„Џд_ЏЫTh'wрŠРЙУa .ќКr†8кT]тЋљЎсЁшџc;;cf.ђuŒ,цЯ~]oЧ"cР.тв‚€м8ЖЏљкy§Н#eZy„є't …sЩш.ЭЦВ“ёQƒBўtеž\^ƒ.ЁЁЪЄКR§0€sоЭфФ„ј`Бi{ьVПМZ:оЧЇmސАA“hр„Ё'žЕУмЗ^ЮџW"Г<ŽђчV;ЎаИI`–CiСк§ѕ{˜А~v$М'žXxw­&ЪсЩЖneЪЎєДi–I@ѓ™Sа™ШЂс2Ю".1_JNСъы>•Gl<6IsZмч&2ёЬj{гЋ9…V—БУVls `C”t…_2……Ш.)ь=…™Тїї•7*>\"mќмСR&>#, Ё|12ІТчbЄЧNFФЇ9~ё V%qФдœXбх„вЃ—фeђŠжяЉеП0RˆИЁŒ’†œЃ˜”глЎV" цЈgWїkBєSф>АЌђt–•х3 ЇцЗ‹ЃЪв/Иgо6ОЎжA:\zƒ!фйgе<{7Л|R2ЅW%ЮЎд[ЉК*7'ИЄёЏт’g /Ер`#=мећ‚€œђХљ#Ѓъ"щЯпQЮлП 2'aZ“Лк9YјАГЫцŠЅ PWЂvЉЃ‰™ф+ %_i `EOS ЕСОЃђ+$†ыX№~†чo§ЄнJсш ЮBЂ}ŸrшE~WГ_R… dnжы‹TƒЅѓ=§=дOЗК+8гƒ4˜1[тfЇМЫ+ЮaN™9ЯzguЊмуM#/bšЮ/ЩЃ˜•/u ярІГˆmsdЌ„хxY™bЎhY0ѕ‚ъ(šNo *Ѕ|0JoЃSF8ёдијўчЈšэ[5l†UjƒZНWйaяЗ1C8*kЪ#йѕ XZиVZ9}\ђ(гП,qŒЦЉ#тЧѕLФљ!7’№фСјZRг„ЮJуЙ1§oЅY НбО щмЅјШ5э"‰І—<‰ŒWю–ШъоСтRЛ.‘=Вз}tZШsˆл%3ъ:jHЎ‚Y§Хв4Д#ц,Ч„ЖЊр­ќ&@GХНТŸ3Ёдp?gZmзпФy™f рz]Aі+ї9ЄNKw*yY-ˆз7п.›5вŸиЁ EЉ‹UЛ‹ьЕjс~ ?нГ/6?jит•…­zz}ьХЦ/У=t2Bt™gW)џz‚k1Ÿњ56 :ƒ—ђNпŒ›Yu†Йa1 у}бƒЁяgь4j‘`qВ•|{с^Фрsy]}юqдњо“ёЗšиУнe$1KП.ЪoЖасSnЅїсаtЇr—Шћ`›™š8 0хUъ•ЪŒ"ркƒбП4HЇЅ3ВЁHЉq„Š#13ХQTjaЮЭюЌOEџ302JТ‘|TB{Ѕˆі-эдCРкAлшѕ\ˆVєkйEж‘{‚ъŸyiЗ~MзП9*еНђ8Ё yJQШ м.šуZL6ї FЅuО xxљс›{Ш6†сЗrV„x\’aФбЪ"в*is^рaEгожёпИ–юЙYчм„E‘‚({o}WŸ№жqEЗž\@ я\гяр§гУЛ/Њ"BUЉ„В;A40вќЯKХу›њBwu2и~m‡H† ђьіУJŸ7HЕˆЋЈйfж+ˆмвтЃaD^СПu@9Д. в FTтI%3{еЬЦёqЩЙіжЕюнˆИГбLіЉычЦЅ(ЏНБА 8bЃ†)~T­;mUйXЙЈlE’lЅ(Љwћѓ k’A№ЖG5ЇЌНŽѓЇq…tЋШ}…Тvа–OЯNЬф…upЊ Ж ™ј3ЫсЙЫK1С gjKќ“уЧU€МѕWч†‘dPјrМчiwV Н1 >G†;УэЏ!іжp}Е№дtŒ•Ž­ДFќ§iЫСfьЮiš•‚3Ф ЋhGн%…aЦjCВuWzњ@ЬйЩКВ їZ˜Mlт”&@5‚TŽEGdжJ=џ#–R‰*o;]•m—С{:иjos8эЅЉэ{ймОkLС~TŒЅюЗ4IvбюуEз†FЕfЩЕHƒ#чїІЧђ r$ ;зујfZшўйЭИ6`иD€аO ПЭРЃшw IŸбˆvqрyY<‘н_ё;-šгu­ˆVЊѕух3‘VŸЯ-Р•„6ГіxфЦяяДьqу–]UKпхŠЫŠƒл@F ёšЖJзхЊ( ‘є> ^Жa‹ЗГ№‘gЭЪ3Е=nЯЂMђ$œ sI цk.[.ѕуZзIЃ^еr›_hƒОьћнѕы†Ђђ5™"qЉБљ№Чћ`}PяЎCЃ{DюЏШr Y%3љKд8AŒчО\Л$yQŠ–8№_(ѓмWЄ{ŽVОйЩ4щp4[RЂdŠЮЬИъTХ%йšІв'ВŒ*WXДz;Љ8чпJ9Ю—0(uђpwlQQž[Ь^ЫлзcZ‚LExrB‘ъаЎ[zЧ~*);йBъ•.гёљHu„“/#qA ‡ хuŒbrŽЕrЖ.4А?дR !ђОЏЃ%ЯHЉ{ Те~™цЇ~ф[з€$‡їƒУэЅaіба}ДРнeкЕщŠ ѕќйfМfl:]!/яŒоm—ъош]+–СшНoE`†Х—VЊo%блO‹яG^&ЫZ}Ќаœ§ тЦЙQ8wd5€в`J"Јьqж —E‹‘oUё‡лu†™}DЌh§;дЮћёдX€7*Вж…‹Љ5&ВЉЇѕ”KOСнпwjHŒ,ˆрy^VБTжФq)ŒhCkWі+€ŸЌ;.юфэ\•­ѓN‘3"S :Y” xВrn дэзђ ,ЦД^^{€OЃЃќФz1LШ&hФU‘ЄqzуС…•uК—.–љлЙЎk3_ЕшПWЇ˜\>Ђ›щ“'вС|gСЖW‹вцБ^–Ÿ{{E­єHoрd-кЅТpp›8мel8P,Ф~іJ{LцЃЯџ!+˜i––‡EЏsУCЊE5L4cуцXl!*ЫŽжы‹ЖЫаpтѓуо~№ž*ˆKbШЪ HТ Х:уОЗ#Ў…эш\YŒ™)€кDћ†ŠЋbQyІіІEювV;йБ8zЕhЋ4кНЛЭ“‘Л9ЫЬОМЛˆSŒз=1q6кЗ‘Bщв}Žk…ЊЕф•Цџ№ћЯдgЅцimŒl’8Д3NoБ6ќь›ўє№яС‹)tЩc ‰Ў'‰EZлYЇЧ^ЛоA)FШ?sab6sУ;xЖ"<К—§—GсFN5 1ыЖр9ёЄЂЁяaš†v$VXR|Гѕ#ЇWd=‰-§ˆўФЬъЩнўісшJŠE!bяъa[bG еžЉ9ЫYoKЯ Фэ$~ZёG[X’ˆВ^Q=ПRmjТЗэMКѕІЊўџrBХ№йпІ‡’ХuOH]HЄ—М„Щ,д0Y#иW;(ЛlжH7мВк1и WІЋЈ`_†“˜”uмR‘УўH/s…W)ЏЉ…б+„ скЁVЯвдЉИ˜\^ožпбP№з~[W‡j††б8чытЂWuЯЯщBŸŸгљ‡бќєЊ3EЦsЗbzMёtVvх3UvQbѕлЯyS{ЪЙДeрџ šN|IAEjЧЙŠЛ/яƒџBWХэбJуї™ OŸеЋžїшвvЅ”WП}ŸѕЪчWxЬž юЖ”"QнMмЄТ6ЁЎvžaЁrzmњ.О9e2ž+ „š”7TgjЖЛвйџNA€_`РЩКрˆC]:“‚,нГ"ЭющИ>џUЋ>БЫУ4aЯ<Ч‹ђ ][у#с/xщŸќH1^БЂYЉєš‚хf>Ž“xєОGЂг в :Ќ‰(ы­‚ЂЖ“y L}csЛЙв9§$Ї@X3й:яE?fJctІ yЯФpxk*Y&С*еF“ K$ИJA|,vь=F[Qѓ6јъЃжЋ*` GWсKЅ[8*вз`§чыƒџvЙKQ‰щ€дыcСhR ц9A™ЦcпЬQЗИu„С|аc6ш№}iЂ­Эр+?МXўТ–AС5п™•ЂЛлŒ)Я2шР)=НшАkgS YOГ}ѕЗ­lкЅЛВх‡О}buS9Ž{m2Z]WI ~1gnэEьЄ”я=Г™д 9є\xŸ:ŠЙ',ЈqчеДЃчКЯgmW3 ‘xMЌЖЪтЭ{™-h'ŒPY‘UTyК# к>мЦ…Ч?<Йœv >,/"ЈџЕБЊѓАВ/–еS?Š6OЋ"lйZнЧЬŸƒ^ќ.%П^WЯрcЊЁђ…Яжž„’ ™Нtмј‚’шЫAтиBЂ“W’щ;08š[ 0УнУcф ю§_м1тУрmЉЯ8ЦЗђk8ˆeoг­юП^џ.’Єo5š}ƒКР˜œж%ФюіCгš(†ьž)xЁ‚oўЬЙ'<Ci<јRdlѓ€ы\ыдuщNфМ3&ыЗў|&­@k яBо€лДЙJIЗї‚ЛЩ4gѕ•I„рА{DфepB;žмC!шўЦМКњ,НЎѓ кдФЅљŽ.–)МюзГ7цюHэWТЅУе„]Jю‚2:ONУ?љ…Рв,Eтждя–ЅQ‘цu;SЬщь-Й8З)xцЯSCјіŠgИz‰Н]ц’РхкэѕЗ'С"юdУŽ мG‚9žЅjАOНђ“PtЄyG’у„њiQыъТ1*;м2šNБќЊњ”ДJ'ЮuЕ‘цђoFeam.$ АЧ's РпZроСѕш+C*Šѕћдг?Ъ0тЎžЌ<~[*/D#У7њ-VћЎб§и)ф`œŠœe„љвuL‡5ё%6цР3ў"‰.цфЎУ4`95ш|Џ:Z%eAzфркoф_QlМ`_Ђї­WDРЭР~гo)ѕа)r M5GъА[Œт=ЧuКJн~›$.ЕІ!?/ТИЭЋ†ŽeБп*~VЛщ ‹ѕТgЫТТ&]іy/ѓ#ЉgЙOй3#д“аBзТЃJњШpkмюЇЕ‡‹ F*ѓO2аSБЪs/cm†Ѓ3ЭmИ:є­>г№~"2ј3\2|йTЏƒAњ nB2иЋ8ЮV@Œ™N•”q˜гrža_w,гф+Ћ„~˜'kbЂђњ Ѓ{ќоšШЂэЉ€Цc~Єю=nE!Гs‚]:хЕO ш›…Cї6,!)i те­'ТЦДbфyЭ7Эєљѓ fЂиЕbАa˜}; 2EJ‹ ZuЇŽE ЉLf3ШtЦAƒ.я“>Ё*Ѕ“qrсst˜#№ЪЯ"Пo$Яб…Y—ТВвz№A№]ч3ˆрaŠпЊЃ IМ€мЁ РЊ3щёхрЈraHхxз}t‘­§}ѕ(ˆkМ‚,;Е&MіŸf‚^ср;Ÿ%ƒLŒѕ‘ЇTNУу gі; єdќ`ъц5žx‰=Ю5ШnаЌOвЅ)‹ЎХ^Mы.WѓŠ9ЁагQѕ`.SН†ћђ%mЉa  1ќЪЗ[ŠŠс†‰[в%ŽЁђ•}жDЉJшюЊKжVЯѕфЏR cuптtѓХЭyШ‹Zwдtт…\2NК"йлЄћV&T~} №Ш6Nc(яЈб{щ@ЯьBќйЌoџV—,ШЌуяhMwћj^л^[ЏX/їнюKžˆСДMЇтЖО)~ГЛml3S+u­)*OІ…’oЈpьЅЉ^Ы8VЗšdцЁmš:ќ\Њ}к­СXVЅg•b',‚QqAџ~ъЋЕ,Х‚`EѕЅЁkl\žђ jƒПЯoqч@лЌPыvЙ ПЕ­ЛЊёnaˆŠгс&;BОЅ'<пqˆ>ющUB€~IЕШ—0РШЮ„ДвQR№yГѕќtdЕ•{ab zЏч’лЋПh ж‡D`…џ6ž!&f0)E№ёqЉхCбАЈЙFKBT_~Є№9љЁ@i@Ьєba\i§O •›) ƒuaTCРIЏћЎ Kр!Šя‹ѓ!э+Лє _CВ—YТ5HэhEž У Бшш|"нU‹ЙXmBš.л†А}АІREё›o_шY›ь3$f4с–™џ<єЄфsЮ"ЉdЁlлaŽ+˜пЯTˆiDўПw~іЎМшAz&ЭѕiX…т ЁТ‰ЎbМg)Щ‡ [ Nм\ЬawАR>Y("яЈ:gцƒ§=­—œт• Ф’yњъїyOќVZŠˆzCЬУ ю“kѓ‰iq$S№ФУ2>Ј@жв9ƒ“д* A€1јсŠm‘[л‡дкšуќм6 ‘жЮёжлШ№]B kэ‘~эЫ”ДBYќN<:І=ы%З‚8T>сLВlЂЌ­Ѕ?ЁЈФ<р~\Ss{EЖЎPЗЩ‰€1 я №сЈ"ОG‚ЛЪДИ/њAS”БUфќx\у[ЏDQыъћ`ыуЎЋт_х‰FNб"eшрeF$Ќ—!<o> Ѓэ>Щ­Y ‡х*OTЛKЁй<ХКvЇ,НŽэБЊ†ˆfыѓ“М`Pііиђ6–H!IŠw 8с 'ЩuЄNsf7ƒBS,"'гƒ^мvyMЙфХ%лЗwБg‰bcCџTє!уТ›_—BpT Иv^БvўXуY›нK,ЬcОжжfзЛ­ НzлsнЃ’бНБ;"Олъ?0uфcЫЭ™5Шз†јцу[]JТRЗ%>юЦГˆQЂ ŠvЎ^fѕ >эžH…є ]˜ў;щnЋрU'г)ЗšH ž!Jм" &ЊuZЭу•є:@Е™ щЅУюбŸ…§+шnюєœ`|\­;јЅFоCЗН +*,)УPˆ@НеЂ ОУ:‹йZІYЯOЉ›‡оєIEН|шПХѓ‘$мП…чˆ%п"ЗO/ Dš@љдАFЬСефГF зЅ-9б3„%JсХф˜^’˜kЎУ{TdCъ6‰|yћQф:ї™т5ŠЖœЌЫ9Ю)’sЛrЋtf 7кЖ‰“tАŽYŽƒ=!оя?bђ&aЧ•СЯ\мДW]0СSїмОЗЄВS|\n`Э ЬЇkТЃYж$4ў‚№ŒДњ—SA’|п†аIНићЙБОј)’av)ЙѓVRБЮЈmLіk+АУ;п€Ёь1hlъ_q7xTNЊџ-ѕЅ ЊˆьооїђС3SBƒ~FЗQAв€qF№%;їпјѕN Ÿ'!LwMŽ‚їDzoj3Ž—Х ыR{м†,жnp.Wџ_янПфЅ%ЬГjt=§OЉGрОbXŒЌŽŒВ?ЄЈВR_л[м 6ќ>й5СяD>Ў’e06ДКх!Ђ98GLІhЫ1’TSSжXVЂѓ‡?6ЄTfxъ.рЎНQЯPь{ЁыKvyчеКа4l›ŽёЦ ЫврG лХH˜пRЊA.ДЂЭљзiџIўЪтЂ“Ф2!kЅтјТ э6?†71њВIŽсЁg*ќ4дŸ7ЬЏчЕтИRзЭіHЦБ}'7й–˜ђмi›E!~гSБЂЖ•їЛўШiньќњ‡:^ш*iFYЦА^Ш)$еž7 aћ]ЪЄ`ЁМЌ„;v™1oRЬ`2ОљвЛ*Поџ-98ІЃ-У§е2цљctИyŒЉj­ѓ#­(кM/ Z U <jЊv”ѕ ^gи­ЮpЖ7пыƒtC€ƒБp8hнЮŠj8 ‚3ЈU8ІюPџTO–бGш‘,†1К G{д И]YјЌŽЈЇиоƒКёrх’Ѕ>шШ$Fxu‚uЈ/XІџaЎp’Žu*1UA{МиŸ;ЄkЂОїLл:с&м­еђиЂ=EВ7ѕN5(5—ЋЫ"1HО}Мѕ”ы ъBзE%mЁEd!kб‰^ИQ0| ъоY—:аёJ’Бo§=Фіtћ˜ qЄwГфхXфП•Ы -іП"zТЂžGС ™ўѕ\g|ј+AKyrЬсўѕ!е •ЕѕК›ЧTWоJl`dc>№Њр†a›=„T;;мѕдД’;­рі y;Šє˜]XD'TъВ5ІћѕіМfЇWй_ЉР‡ˆTЉЇFФшЙRЮ3š$F4XХіIФЖœДМхœfŽУA?zLЁ'ДпШ„1г_AЃ‘џS-ЩЬзДђ@8+жЗ)eqt\i‚єДзЕoс\—ДЂ*ПRfvBkяXХС‹˜^\№7•яУД#gо„ъmOPcхЁш!РЭ$ria мœ!ШE~§7I'Рl”KўƒЖ8GЧиЈE}ŠАL]$ТёиZ}1бТ иEaˆЊЎє?!>шEИ<Іё˜Žрm g§W>ПYОSD•ЛZ‹П„Q вw‚—+\Ž‹$ sёda@/яiЁЊHГ ƒ7QtУ*ЅMГАJїАН0CКЎ0!pЬЉНУnФ1!€К‘dлXШ†Ѕs‚œN](ќщЇЙ~ИЕл0Rа… œ–H ;z’уRŠ<ш­pйО‹$qer ?HЄЯ ›хџВяŽ’b{пѓзТАjЉ,RЌPIuРS‚Ё1H7­šiМО}b)%лž‰‡ƒТуХеˆ&пTМїУ‹6о N‘с“€† ПP яCxГ5ЕNЩGxбiуFcн}ЦТL…фЎYO{ ЩбХ_ j4ОЂ>Øфн,Љ+ћžrцUžћіс,ЕтЊA|TaэxM%См—ЈЖЈТ›˜JБЎ'XЇо‹ZZ“ѕ|ќЏ0O=ЧC„— арyЋ/ ˜’ш˜mф„|СЅяcМж6ЈEd$+CT|ёШЮлјмKpЁЂХ’ЎТMEŽˆ’QВ /fZt /аљёj)Ц=GBђgСэq1Ыђ 5vНmЖŒѕ a’ќБq–Ÿš‹ЗєиЎ›ёЫ`ˆ}{@ш Š_ћј:z[зХƒz>р €ЯднЦу ? ~1ŸёГ8n€™xСПБФіЅgH^TŒл6l‹–‚2ŽюЄоЙ‘>cМЊњcuVGЈ9Ÿщ #‚шJdPЙЪzˆ^Щљфm-œ?/ЌNіњ№4-xГpKМXр=ˆаъЛћE5ж*м$џh&†€№:ЈћгW~ŠЈŒьЅ#ф[иWa78kс~g5љ”>Ѓ+y\­\юYЬˆVX+]\#И „a(hЃ nх„жў'd{oдc•Ÿ#zœ„п€о‚хвpA›к1˜ [‚ЭЈlЫТНц.|ъ•~yFфCœЬь=ќяFФмRхє Pw(WяВ'pKД е|ў(оНж,ŠjhHgоE•ё`Љl•ЅXШЎkMiХб(.‰4‚wѓшkK=ЫсpcQuѓЎ.гЪзы.f”гЛіƒЄЪыьЯху”С9џ>‹ђŽ_XуЖ„Ј•"CeФщэЩ–U7}КЎ­Ъ—A›ж{PЩ­ ЁEфо^HмЇBЌиз[b 5Њљžx§њЩ(ФЄ!0жмСзѓњ'Ў$:Јzь‡,“y 1в—‚|шЪ'5NŒ5Ї’цn@tЧ)івž‰и>фZЈяЏ{ пz…ѕш‹Qr„йdлZJJƒМ"ђЭ,іўeпiжЬ я:ёBLю/ В–&$ІнeшTžе­6^‡+5]Ѓa ˜ЌYД\ои:uЁ№ˆŸZЩЮ~ГЩLМ…BiШ/JC‡РьQ“щрДЭVрЖ?цtІЭDТT‡ёFЮ7hBWh S&Є…H2ы Л ѕkЈ+ЙР^v љкp6˜ЋХРМАЅ{8+ЮчUZДзЬ•ЅHчžЂSњ^ 3.BљИ™ЙЋг'хd__ы}r3щ­џ$ВŽКѓ№ ƒlЃj7лSHD>rПЌšќ[Џњ5+ТЫTќ П§6Чё|H $щ$W‘1‘aўЂШ_zиˆН"@Гк€АфwŽlЄЮŽё\$ЏЏхжPнAtЎЛ*›Н>Txa’V+Б„„таwЖЉ7jLfнљFJЁwЮjЂ%fЉшвi§g™‚&n;ќQ1ЄЯPЏаБNQC^§–Jzћиф}žй™ыo k0}CэM+Ц;юv|Ёрж*E3ЬsлдЗФYхfА‚.ЕwЊЋKўmџa$ЦйЈќАЯ­ІЭˆ+˜Ÿ}ƒєф‘у>&VЅ@Фу=aoFэgзФ“Ё§б­%пQYщ~(§ъКwЙЮ.М;ob щS&УДL ZЭњУЈ Y•ЅЂ$KћрI——A'&РRфx[і0Š &УЬж–УC yРa8E„@!dB&O@ЭlE„ЌјЩ‡œ(T!Цu˜Ќ.ОЏЊЖсюВЕц‰ёMM0tїЖL гѓЎRІ=d{Б/fGšv й(пщЙ6Џ=t&зьBХYtoЎ˜Ћђ4ПA OћнРє‹ехѕSЏУэоx}ЛЉЗv€ѕРŠ|фїuŸiЄeЩ чWCQ- ‘^>ezіjј‡XidЧH\Pєя_9Ѓ4rœœ;дячън3Аї!dщзš\Hќ+ hџR,шФљ”П(гикFгЕ&ММ;‡šЩі IШg{Q-Ы—Амзh2g-<О-xёN\*zј_WI€/![hЉтѕž3—K8e>q-„.•/v6,Ъо ВеIЗІЁч{О]gSFо6`ЫboЛ4ы,В—=nŒ$pМ€ kѕ аЙћфОyж‚ŠMт p§R<се.Іці,ц1'Лpvй!—Йв ‚Lˆлe‡c;oЕ!ОПГСрржЃЦНвЃГFьнŸгђ _ \ цЗUсл4Г…–ѕс@?xOˆLД^љ+y‘H>цSОчиŒ[к]OЛIИjzЉЦK-xЩ]74Гax„† HьЏЙзё?п€бqнч@щм4‘ЙШc{i]’ьіgBщ/њsRБw5ТšniР‚yЋђат')eѕГЦїЩxВC]п=U/ЈLјЈвHрДX№{"ёТ‡ЙгчЂўОд;eЈ3њсU4y~>Rзk ]жfŒжђzs›žЧ<^—{ХсFї31ŠeБіW jцХqЊЖењxё}†…Yžc Б)х‚БЖА(\ххT4Э,ЅЧ‹XX*žЌMnќє’x"‡Ѕё„(Ч”ЪJ.ёKЏ0v]+ ‹ђx†Єрr‹спŠзЈKйœ2ƒеˆ@P"}mоU‚ўq#Р†0ЎХ5пmвsЉ€m* l:pРk[wэѓыЙщ1OШ-аdMГя дђЌН–3§f К,ЈатMЦTŸ0Rд.;%ў—uУCз$Ьh~љlЖЄ2§jвLъКюMйvЌ$8ъl=ƒЫ8R€їšф‰яt6+ а ˆxJ]v$„ŸЕaЫыЂW+Ž1а7єіQ_ЕНсAјќmSiы(ІgBƒу|a•UоЂ:rаДl№tbЅь'ћЪ–f’ x4„ѓ' gЁ`ГаIЪB€,э#ЊЙWПЁН|аІб@q(Џp< ЂЪ‹мДQЯЯџ^8й€@Ю“_'4лœСˆ_ ‰ОSе–’Щ{ЬњZcіН–Њkк…Ќ1|IbKШScэ>г!vќczВAЅШRjВX[[чЗ`щ‹^ %v:S@ЙЉхsЬ‡ЌvŠшq6uTФыŸ€нњrѓnџ<§^|vN-sю/жыЙЏa7r:я=$^i!Z­ЩуѓаRц ]TвWїнRO‘ииМек6L8P[ц‡ыžM‡јLЂ\vчHшR0лkˆ#ЃќъxšрЊ7NKžМ~бgŽXЌў"ЁЪнеОZŒгzG;)…Oдсh~§ž"И‚Hц9%]-šЯ U№ Tn§;!Б2ђ›ЇSЁp0х[e /љ…„2}квPЖ ХЭ7й~ш…Б6ЇЯ7(_zšя{Шѕѓ˜Я[P! МуР7ЃдDм–еcбŸЂН;Аё(VUmёl1ƒ yB bт,ЋЃМћ/Эˆлkџ9УїsBјйjЯ§ЄhщЌУQ_DнQЛД;м ф†Ш›=Fв.фр”—‚ЋsЯy™ѓ<лl'БZ–шQ\&–нZO„ќЉіКЩbЗє4хwысћ„зе|ЛЇї&ЙŽu„!ЖyыШъїШ/]G‰Ыt#1(*цъМїіR8ўžчЧѓŒ8™ЩэџeгјГ aЮЦЌ+дya&lUЅ>ЩIŸЃјF>#H”ЎЅ(ƒ4ˆ\џ i5П}сљМ$ЎsxБiEYVA•ЈD |ѕ~€УэиИ}Л%ЗjРїk 2яч/‚fЕeaNЧŸHX#>6'С-Л$ˆdзК09ЅVўLЛ3}мкgљЊХтћЪХЯ4uˆ^ѓk)ФЎъэТЃТ(PН]6QД'&ю#H"уšъoв%eщl,мwе8YЏњeuск†r ЎД„G{0GкТЅz?G L –^ЏЪYkMzХ9I§Щ6бНУk…i:ч6А…3№ЏЯц!НŒі%—‰'+Qї!еУdШP­wп&kЌyОoпхњ™UЬ+ŸгX{ЗЮvFя6—1’ЛБSР*ялгq‘Б\nАипзЭQћы< т-\– q3zЗГФЯ"ЌˆPџ:ƒcр)ЩЉМФгŒ”\9аh{C§{ќŠ~І$ќ>Э8эLž&[;Ш]1)чЈд№КЄDВ€кY-ЭŠс“‚оЁФлЬе/X:ЖбрR!§D ZќиOFлyfAФИVж†CсзА.ДRЃ;=єM‰‰ј"zФJ&7Eh(X”>їa>уEvЁPŒ}м ьыr–ќ@4>i8 ц;у3k&Ьmc:ЅЧg0ы‘sЇї;м„—TгMSГP<ЏŽBЙХ9;;Eаvdк!—дœф§Ж1ЄИЈk m;lїнKpєЧ'‡3гО/˜Њ•u‘f\PчБV8^Ащ"/bmвKОюаu”Ъ$Ш•щ tЗ'љƒЕ}›A‚п Є{|ЦO–ŒёˆЪЧаwЁ2“‰тЕ!~їєuж.Cœ#Ъ4йЯMЖЄ‘•rГwx–з QЩnуП…Х SЈ љpRфЩ(ŒЎLF|дв4M•–H~f˜!Ÿш!vSст‰1Ž/bfW(Š­љДZј3cбБЏЦ+Вhувi!A 6 Œ{Л1E`f<,cRAё"ЃюМЎѓ6,ъєю4щ сTт{8Ц^и*a%z#dЩ~&Cw9bЖE•э†tЗBЎ{4ѕJ ‡.а„LXѕ—c§xИ§П)Є)swВќZо@jжŒ|єы`Ќš,Ђ—лQDѓRuX”€˜ Й8ї]‹б;ЌеЪьёkœ§†ЛЪтв1’Ы]y\>?6ыЩlоT˜e­iФъ_OGxсPCеU•bуEŽнящј:/ЄLњHяЎЇŽ‘ГДСŠƒе7Q“с„mюиџSeRРыЭY•4вMљ&‚ r‹иtЂFmЂ9ЛnЮгgU‹яш fs›т•pљкЄЏМ`ŠлщцBЈK›R=ЪкWвх)іX Y@ш)Cјї{шMš.цЩв#/ѓKодувќ€A‚QєmFЌљq‹8ЧhЃјosMEПГы˜m;и˜šЂ­jjUЗнГ•ш•Bад–БT_јŸНЏ6ыœXФwЛ=пС{ѕч6;•яm…дхѕ=)2 Д§BЗкŸLŠс@Phх}™Э]$œ;ХE,ЏEЇЊŒzˆЎєСЮхрl-ЭqДА+ˆїу;+Єѕ'ЪЄjЇШy—\'n48tЂYgЧQмўбЁЊмф} ЧсгL~)ЧсбH3ŒыЏ•”SbXЕUЯ Ћfп'‰6“С!в yМ­wЊЇф9пчeа Kзё9њъNЏГ[Šdј6ёEГ Vч4лњž9о\]ЅГ`ьŸІМ|е|{T-аеЖcf’єШнгзЙ$Зш!Zd‡НQ’Ыозx+C& КЬŒFWr2V !ю5Н –ќЃІТЪ“\щІ–—Щ3ёƒ9ZpќlљyФ–Аb#дz'  Шл›ИK К vщ;HЧъuЄ!§ŒчrЊў§№$№а+Иxш8жвЇ<laOЙ)sC -Ыс9УЉіZVЃ5Ўї‰…љЪif—‹Lїю‹TeXЗ]f&,КЧ6ВFcљОа–$ | PЊEќb…А‰WыbЂzЇРa~sх!]хы\‡ŒМу%ждН.&&иŽРЭА[Ls^№ЃˆчУ —љі*BvФЬЉЭЙыOГюЄЕ3V ”lщЖfј!x~Єом2"сTКqF'ІKддѕЌ@YJјЛ”cуkм€УIUИ4!@v”>5ŒТЁ2fЧ@™GfНтKoќ?ЫЇ^Lg'AkšТfМЊз,Й VŒŽJ-ЏwпwшщЛ:8цphhпMАlС2ѕЖUJёћ$шЯwу^Щ#Е>RИƒŽх)Ÿш,ЇV ‹œЩд~оDœ›ќ8‚pтLй@ž=Q‘4рГЊ§ќ†К aо;дђПч№КЖЭ_†%gџ#TО RW6šjBЯUЯЧїяŠ/SA ŒsœB7fpˆ"ёOЇЧЩцЂђж,cPŽxFьœO‚ѓѓ.ŒЎFђVВ`sUязИjPьЮLv:ŽD›,‚•К7КЫУ—щ$ XпХр=ltю†"VKј‘3”xTaT{—ЊF;;и.C˜№рэMt‡уMфЌ„ \L‹˜ъЧЊЋW—E*,ТEљgKtœшИОк†$ЫЂцhоQжЦOї +ЫюЦ<Уˆ CXяWbNљBиЭ} Їп2‘,Єfѕ‚бЪŠƒr;ИфБB!Q<€kїyђ[ŽяMиЫФaћкMЃЗk•lc1Мfм4AќтnнЏФЯсgUы‰X/фNZїСCјВ–ЕsЁђ§чXYђЖЗкЙU…1-vюIИЈщžЧ3 ­ДG_зищI Ѕ|]^Јс§IЗlb2а0Щ2Й^ЙЎV Н‘п чuы?ЗXZw67HeАBoHa]1\оW…СКН зvHХi[ШбФ‡>.З]' prLƒќДvG0. юlMcСЇЉ`ЈBМ‘P]~њщƒ–^dЃї[фВЈŠ‹яй‹6вeІ)|ЌіxšОFCъЛŒ’LкЎ•ERuЅбн‘„Ёч–7єхЊkEЇyЧ+GwЖМжq[%yЏЄ‰Њ"§хVЊT#a#˜^(Ђ/еэОUГтv’VЉ@­ХGœO<ЁєЮ@„єЉФв!^&uрќ-Я9Ќц'2;†диц§џtЭЂG$‰m$ч‰peІ:ЁЃќQ „З7.ˆDсX(#`мЙ5KЎ­œљ‚џ\N^Ѓ&šхю-№‹\pTQ>‘tа(7ь>З}žяЌl:д_'…^ў’_(но‘}žВhя№EќЌУ‰[]Тnы№іXПAЫ№њПŸаЉЏУйjќ=яУшШўF>?‡Ќ_№юЇј{еzРС"Œbфbхїd$Я{Е†+[ЌjќђмУњ%нН>ћ;ЖA"@yЄ)eaxяД=ђPaЌч5iaЏИ*g;sdr\”Лм‘•“vqli)Пљ‡ИК‡рЕНYЂ›–ЭZ№юоœ_5g§n dбЫМ§я7DФЏ\’V#}Yc>x V]ux {C„уŸЌeЮїЦЯ яѕаžВPјdœ†–zЁ\% )у%ZЉъІѕœКv8r€I*ќXўf КЈо'ežЕV_ˆЧ‡%}сBe­ГМЅl80ш*ж'Ћ­ФГЫ=ЛЭМtŽrЉ|=џ{‡Бёœ1ѕч7'”gў—NгЅ№ЌzР%gŸb^Е$“тУ]эX6Ѕšѓu№лЯYчHм“QлŠZ‘) Кs8рїGС%ѕ2"Ч%сЇ-‡&aИЩ2>%V'šЇш•њœ Щ -ДыЇД:у*ЂnYјY1сзЁЦ:”xLR4HЩUйаn.ёг~0Э!фž1iЧчЧГ…№яЩ† Tк€PgZFh|§?6aїPp+…4їqOFтH8ъхЉѕ‰ЪДяШb:ЭР ЄXх€{ƒb,zUщ Ь=эеqˆ##ьashrЯh˜u=ЇtžЦњ„c‹бЯŠЗ’“ЅRэ™‰КК4,Ря–QOуеЙт Ÿё’rДЏЭІёŸ[vз%\РnййаЛз\Mщ`œL‚‘Cс)ОџBh;"‚ЩѓN—џyЧfЛ!§ žуСєZ6И05Nv$PœNЩ\3Y5ђŸц{Œex(8PЄKSxВвоOгС(FŸq@ѓŽ7§т‹ЎU"яИ,_ВоcбСI{х_ЇюЫЏQЪ аzЫ „}ИX…NˆvЖ9ъУvЗѓO0.EэX(ЄД#ЌOіšЖ)ыK8и}e3мŠЫŠ$_Ыš}V\^-ѓЌ ћЗИBуSу•eФN(Р.JЏV–ќ‘ЎъˆrKУŠ€?ИQ]уў2ѕШ2бЎДєaJ<ъњєT.›m™фЬrИ@[Ж‘EВфдсш­žЛЬС—ё6Ћ0hЁD  щ)\$ћјuŸ…Ф—Ё ] 0КVь)*2.]0+fPГw№А­‚Щ_ОЮ(ююlкД&˜ Л›—‘ж?n|HЃ V˜N6…Šк)ƒ0 Я‘yjЋШтзФэбŽН›Б?уаS›YS Mаѕ$я… V„qЕ{aќПq{оти_.,щ[ОцD•Ўј№Ќ•\РˆЈ984бХўaѓOтrq6M0ю)&rрУUЗСПYц—Ѓкf—e7%#`@НEж”;ЌЪgжЏЦЭ*ћbфХ)œ9ЁŠ˜нъQYYY‹- g›Ё.nыЅњlm{fQ.'€њŠr-€ЕО|fйх5xЌVе“КЬv’Жц›v@п AœХ=К*ШІШxUн˜РкЩшaй@R•}‚ЏС•oŠБTЇГq’Ÿт9ё~2PXНШBkЙbn‘?\ЙљˆH7]гFŸˆpUИp7рЌПmu†Гbiр„О$ZamпЋ_™‰лЩ‚‹ЂР‡ђоHОqпГ$ЌзHВѕ=п›„Ы*4ћжŒЅџэСзІЉ~^Uoѓј™ˆwЕѓZ7ЮЏу™9TцЃ­$НHЪn|t'†КБ№†o3_FыдѓЂ/h—e“…އ’Ѕф4,aY58Ѕ=њЋgнZПШX\ў›Œ›Z6шѓтњ#&цЮйgдІЪФЂ1A ”У‰ƒ~пIІ›=_є?JЂѓGЊKБEЗ;с-Gt)ЇŠиЫ'ЧЄ№aєыЛ„>тSлkOм’Kй№Л/'‰Кію}LЩЬ0Гѓ/*P†твжS_бAў†SЊ3‰ьbцќ%aНц§2EЌ‘ёлOЇ•к јDŸz(Дџ}ъЭ[?qфiж}U•OP~kЪ]=˜љлI?>ЇхдM'HРЅ˜;ќћ;kсˆ'dл‚дђŽЮe">уЌПRъ.афиА•‡ц(1ўпwyшјЂj=ШfЛzлЁSкЩƒпЁ1жхЅ_жмъе™аЙ *Д YsYЈ™Ѕp>є~tkєƒЁaДW{зˆШ+ЊЯ Dќ6ўaПь~%,x‡љ"ЕЯІEU<МЛых_lЄщmA[ўЖ‚(FA=)ІPЧЊˆ|–Ta№Яћ?ZGъsфEХКlЏd}вЎі[Š03f‘#W6ЃšЭ^q>“ХŠ3cш•У2yБCxоь†Ж€КѓrХЊ1Ы‚хNy Х@д]э ]Ю Ъ„:КяfІnЗoЖ#_ќНш9Пкўkр<џrНfœ @’дгЂ”Єwкmи:г PІъєхhАF РЪХм~‘\G;ЧнТч †РИnтЁt ђхчєIL™]ВRЅД™“ёЃ­ŒAЁщї}ДћlлГфaі™nЈџrŒlч•ж_E# oY@о§=cЪАМТжTŠђН?@XuдрФ[;џ`Ÿ›Ћ­П1ФАнЈњэ>ыDCлћIb{mЙдPŠ,я!v}бЙža!Хй AсUыšWB"GјЂcТЧ–™•ЌДиCМbЬ)ўŸЕœ0Ѓ_`•^9skйnŸзЩч#ѕ&=[Џi]YэŠ\њDOЂУwN0ƒя:i_œ_Q˜bЌ‘сгaRЌ/' EЮU)цюƒ?Sэ‚Љ•+,N“Zr]Tћž+Бk(Тў“М,fžVуБ‹ОL:Н*nъл{Uђ|K‰}_рПћим1Rz)jsЎљІMцž\{vэj‹Я„ќŽ)ы = 4 sidьиšMШ™YŒ‰r%\ЦОр,xАƒП ˆŽ\{fшл еЏћтЂE_›П№P@hw b™fƒ4!P6МN…єBЂnќњ4[)& i‚gRkіWZ5~:цТ!NэMbœ|Ч BдДm/арЎј& ЈшŸтЪЌМћ, |Ђі0ŠЧЯLйцъбЃ1^яm`6#<Пняn№”eлЮФГЫб0u=9„ќJ!9Ž@Шzr”fкмtьзEЇЊd,ˆrQd–дZъ]<'ЛТо“›ЌэMUЕ:ХVЭђ”К#5­ЇЈxИНя ѕ.ф!!жі}qNNЫ›ЯŒ (рt+ЛHЦът ѓщbЛ1k6^Ї02ƒ=/$O!Ињp–Їч{7ZеB9їHг/дІœЅХВ+O%t'ЬєКи…ЈЭЩѓ‚žcTjEксь?BфКhёюlќё%бѓ‹ sШ…vЃЂšVwk-‹`ле  žys Ъѓ6?Н“‹S‘i|/] РўАЃ/ЇoІХХ“X'}Iі?;‰Ы ˆ#fщбШx-l=DљЋvЯЙ2ВYс{њД ?v-ўХ)Œ2YЈ˜e=<"ИV+Ѕн|Koбџ „3•^‚ЏУm*šЁvЌA х@D‚ыПeј ˆAADіъ= /WpІ!іДLHSЎЃ6WИ-bЅЬCд ўЛѕ’аaD•xђУU>ю-`ЬЏы=оM‚сZЙ'а˜О-ыO‚jТєЋњљ}Юз–У™xюєЧeьqIД%ѓ<ы9+Xѕј™СiПа@U&щЖюБрœ—щВpжGШМQ8УяxЫhЗŒrю…їk\žCнЇРЋPдџ$мLЎцќЦі9~S Пu<“iљˆ Ыв"й;7рY dУaі‘бwП-9XФсrњ˜J` і)"'~Œ = D|§ЏU˜х€ј.rФї(зGў§BбЗЙШlГ5ярлаєD =‘‘Ѕ 0:‡ѕ_%fVBU‚”Эьjƒ2К>9H…І{н:Ыш™~6SЗеƒа„X­>ъчДq/Г‹vlL:гРђ!r}1YЉH…РкХgLьѕ§u0~Јд˜UФўМ–/yGЅ‚˜ѕн“bЋ€H€h™—nБеЈ‹ШаNMЛ™LуІ т[Rf2y&Š‚ўљqIK‰sa $и;—Ц"вTЅbРњCС`я­DcIБcqЭdcз—ХШUQaЁАpъ=ыЏ!ыИѓftпj;2>ѕ—cОЎ\лzPтn>~Ў˜4вo‚œЧ‡й}Й[‰X"Q-fЋ|ДŠђ€}а<И ЏЯjDŸ%ђBњ8 zp—Б ЛS-Сљ{Р6МVё†ю$mŠaЁЌњЩ’ёx­sеn2"Vл<ыkbЪ,|§CЃsœD\B8‚х Fƒ‹н'эVWOЋ‹кСcihљd$еїq–†‘Ј8тŒП›ї'ŸмяХ•nGјt ƒЋй6§љХSXЂ,+}о“YЎCёФсвЎTЉЖ.“uљ~Sь‚ДnЈe_кџUJњї<СлІ]й6jШWеШЯRU‡псыИё7›З0Po™‘џn&=ВJЁXn)”Є+бyКьQ/СџUАM“uг­Џ|и—|=‘^9aЏ"ЌЮюч›z€•Г§д‘§Ёv•+3'"хLз—вУыфўй\биƒ[дЋо ѓЖ‚)АTšюлЂѕщkD ]йѓeЃГЖ"hѕ]SО&х{7й%%/…ї#;Џря…™‘џsГ@яы4ђmЕNхй Ÿѕ/–НcЙ‚яЊML #КY+еІE•.ft'#ц9BvJіЩ™нн;мљMМЇ#1žл9<›і ЖФ3”ЃЙФџІюйд?-єgэOqи€Вrџ™яL ЬP+M2§ър7 AsІй=цёкГЊланMmЉ^fˆ'XъГ<њъtлSeОyЄ…ЯЏ!ЈЏEЅ#яsмаi”јЈќ=™œк6"Въ,|%Ш—•›ќfsёжŒ{ЭХљЭ†ІЁFЇ\ТЊHЃ--Юњв,F< к ТЃ№МЁжбЬ+Ж''6ўєEu˜‚СЅsS Ќ8h‰oЊ[™ŸŒ9ВъЈ Ивz;ЌЕ‚G[ТжжCБ„—EЊМH­=§ЧQ2іŠxIg<NіЋЪCЉ—zГЭu"1˜wG 6- аЌ?ŠCЄ†ŸѕІЏМ‡Mњ—'г{Д`Ќ‚†ПољіС(ЈШёЄ т?zKJФ^њЭыЁBр”… сwOУy”Œћ§}–QЂ‡nх~„l`˜ќsNŠ“\,я#йƒ^Шаœ&"&SШFЂЬТ–XRБьЫЎмДпнЙэЉљ:kћgyЭ‘І4/Oы3КYйeх.Х,PчЇ—šNД9вP`KРsRО‰ЭŒƒж’tЭw—Fр{tI CsїZGњ|SЦє~ЂеfZЇЏЖл1ш$ ‹TЉю;IљЫJпn Ц™тoЛvƒyљцˆдљ8дјЁЪ вЄ?ї2ЅЯ‡2:Ч…їd0ЈъШ7QŸфMЛ–§jXВGу œЇидžm|#цу…щф4*ЧЊI“s>?сv C">PДЮ§ваMйтѕOЄ.aТfзЋЩеЭFSnЩђЖnzT5ХDsЉ8ЭIФŽ$ œ ГCХd[-[= Т’7:Ы|ћ дAјд.œ^ЯЕ^ziK!!/} Мю/K„~ЊТŸ‚ќп?ЫxSpћ˜ћЖ:ŒВш$yљOщЯuПv’]ьlЊм+,ѓётц ”ЈРb+XВUw]Tњ§Н^Ž^СеNJИ@4$?:9ЩFњ’U™’з*]-зQ7$МЄ™ MLj Аїуџ5Й‚gжШ­§–}ЋЅєи:іх‡lwЖћL”M/sXДЧЁ†+%њЂМXœ{ъЙ€'YG2§м›^ЛluGŒ;ЉžšМШKЩйзч'g…PЕ JеЄв4ЯіЦпУЫGY^BлДƒO5|Rџ^фу‚пђїхмЋЩ]:J‘ЗШџ%.Ԙд},—?џ`мtWM\ЏJь^•‰Я<.WЃщђХšѕ"Ћїdэю)KјP_•™Є  ,`ўјюЁшCЅ§-8/‹ыm”k 4Œ €ош ‡w-ш—ѕ’„ЦхhU“ЎнmSЕвЉ"M6їѕ hF§šh4/ЊFnяОЋtЉ…EцЇ'ђо tБ>юSцѓяЙЅ‰'0ѓ1ТSчї\ЅvЪyьƒf‰ћD‡rс#ДB єX—ЗDВ9ЩП‘r—3 W”ИU?Ё;+3˜Яbtв†‹0ї-ЉоП‚УЧlйЖМ–ћ•žн№Ъјkюl1фVиЎуmfрГcBwcЈQ]ЃvыЊщЗ АЙУ™рыЃ;KЈkUS7kZ>Š(1Є5x >,ћOЧАj"‚ў›ЩŒgШ Љ:Ёъ5˜бKP§кpD[xPHфa*љЬRSS œ№Hя— љЦ“ŸяЅЋGˆyl=|}<К2%CЬzТKгТ3До9хщbK…yYц`­Я<[;[Œ…Ќс‚„‰Тп<ыn кС№1чšckч1ц[{ЧНI–Uƒ MтљYPш==юУ{ЪƒЊцуЧЊъЪЪ†к-P;ЖЈ<%ўЌщЧYЦФšrњ‹ХџnЋoКй )Чвћ2w“bЛyJ!}Й‚&фй‰ЃХ ЮTоl!жях‹џ')b9ЛŸ^еўBХМ™NЬ ї}‰ПъRЙ#JZc1<вim iЗ‡ЭщЙЪ†Щ2лїiА/)ЛпЄ1Ѓ5›ћБ[єїV_ћР*wЈЮbНуŒЫиЙЉПCД3сwjK)йІЯм~б%Щ\йбы'ˆІgXcЧhD(ћцК)/Ќ8U šМ˜^ёlQE(i|ь6žК;УАŒю[…œKŒ„гxЉ˜ињє~.:koH!g>"‡€ш'Y ЯѓЖ$Я‰щкe ”~шЁdl*$YФ2yюЙ(ŒC XQАqЅ4ˆaыIХ]гбПы;б",ј|є§GшГ№ФЈZx‚ ўП<ШeЂQšа'н3‰ћР&jŠА‘-ДIО‘x0~f@ЋХіGѓMщСx–оУiХ‘оO „ЊЄч&ЁUŸиZA6_н\я"‹ѕњЩT{ћќћЕw!‘сEэЅъЦѕ>,ш#м{#KљѕL@7›хьП‘™vyћFЖЩE,ŽzіkJьёђнђес+_ЙGД~–FjАЋ• ze'ШЇяrАНѓ?NОD%MДъЁ˜ЧdЫЂ™q<ѕ‡>ЄAT”-ƒLЫѓEшœ—Hjьџ5ЦTNзa!ƒK:)^н Я  Q%0(Х—ќTh"Пњаs’сЖ7|_ІФЇ_X;qЊWН.Тнгг€6Зе:Г`&[ЌвAЩ ŸИѕ‹ž€P,б3:Н/Є­ЙѓАВ§НШ СoЬmzaОьА dЇ L"Uхт”јfуЭ)УЬys,№ У Ае \*$['š­J^чZфrq_ш/ev%ЦоЭ‚НщБ)Щ‰vвЬќžФЮŒА6`фfфлuуЏэoћ4ї^–'$ВаЈP,wќ ЉќpŸѓа #)Є Щ‹Md![бм;`rEЅУ|>ТЕз.Эr%Ћ[ XŠрvhs\!ЇКKп˜hљT ћг(UЉђт$ 3№Џм-Њ“ЩЄўОЫжЧOrPО/С ~№O•д CПБ|Іаždда™žЩeИ?ЃФйбі№FпеЯиР0–ЮS‹МШј”ЙmJф|-П„Wuв.ZЋРюхю=KЛзm*щzф4ИЋ„t<Яm†AšКС†офIЈёyLЎС^г5уе&7‚\@ŸРd†c‘zWЧчЛ5ШЅvњИO%ОTђ ™ёФ™ўЉ” †\ ŽЅ.ЊГА8ƒ$ –U`лЄ]ыMC)в™DCсЏДJЦ•еыŒёе% ~эоAI•чI0JРWТŒЊCW€—чNГу˜™–^ќLЗ}gЭ…Ц?+Ѓф§Хu[ћV>LЎ˜†њ\ЭбŒк”i G4žэћВ$ѕ=Џ†пй$ў-јw&'7YЩОG+BтХžКС#ЦчžџPGнм|Zјш[$5ч3™ јОSеeк„pQVБї"6**1Ш‰/W‚ржш3ж ЕWгСAё…ІщVАеЗIY ŒЗ-}Ÿђ3~ЁљДШ№Ч7WЭ$YЁp\НЃЇ=ЅYM7K]q”€ Б|œ‘7›5:s_.•Fˆ­UТрр,3ыЗЭ=фўM иЫR——m-s ?бљ %н­ЁчѓМ“N’…ыЎiŒЗa(WŒЩ‡ед\§-ё•™`pЂб#EПˆрSТњПzЬпhEДR|tЧBв f0k| "Dм9ŸBЂ5аХ}Пw‡сћ]ТЕ^ТФЂѓгБAН1мш‰і/Ы˜уœK™БДUHы?_њЌ“F|cиОѓЭё‡^ђЂя‘‘hxЉeщ"Cбг—Z—,ЊЏ0ђiонѓЋг‘]џ ЂІЊŒ#†Ђ˜ˆЦќ"ЫЕшјM—ЫeП“[В/3…Ђ2тЕ‚|Ћ!ХО™Н(˜АBd*bЏЉъF/vљІьсND'пp€'aЫЬ8pegи‰R€%wш4сЭ?лЅ)§,JёoюƒцrѓjiŠ40щЁЧг€GБS96#i•o5U=љHw_rЬ†Б–1ЮEбЕsОф&ЌдЖф„GwшЊхŽа|Њjƒe GЊдЈIyз UьЄDњbZŠЉzДлХtИ73Ф3|е?_TЉzМ ы ŽhВ№yї“Xь\w7бxНѓ§`Б]щЏфр*  J…є“У!bлоnЉвПju(aЫsцРrПONŠ  p§Зg @(зЇ‰ЖХЗ†.•sЅіћ™ˆtмд-ДbЈ1ж3ЌŠqЊэЯU2VЖѓш4el90*'|Ÿ9–!“|sM_J+HЉ3Ш‘эžbЏО[AЭœF*­ЙѕHТgž“bVaqд\krЦЄљjщІВАл^Ђ’yнѕhКџoD›ƒЦЋЈЅiЎЧјOyќzF|TЧїn”ˆ=ЉPW!„‡О›Т–ѓЈЫJ”ь ,GЖyыАоПЩЃЗР ЬФА"ЛйŸщњКчЁ?ЖYM-І пЩй _Ћ>лжыІеХ3^Ѓjў…*Р}њй?œwТƒЯ] Y„ТЂХЪ?™ZЏйЬмqѕВ,[ћqЇ‹лЩywСЏ†5eэyЯdhЄsЯuі_ ;іxчУВШ$ЯвhљKмb“`№UlЅ*~єІЯ<›XК‹dисeЎ;AЁIсZо5hA№и(рH3}ИЃSdК3RДx!јт\H‡арбќоЪОLП~Dј )84$ 1{ŸЏ1З‹аЃ—У={QK_vбFиеqўЯ'ЎpлŒ­p:#йЯ–Љгзіq№qŽ{[оRѕG‡ЬzђŸиєfі>i—pёBрˆЙ[7КуњЏЇЄаK)MtyƒT79™x€ЖZШp™чЧ’c\C|QДSЧЂКиўщЇ1Ќ‰ФиgХŸŸУIЉMЛœ ВЧm'–€џpCŠ#Р@_%3Ÿ{С>е™ЗК|AV‘fхPабЫ= (Ј/У]dі‰™ˆC ХМЬTнљШAZЖ-’›G Жз{тР RE‹)г6їzСЛЖ91ОhЏ@Ыh§=šJјєуЛ Ѓ›u§{їŒЦ0V”ƒdнc–џ[ЫллzqчKщC™вП/x:џo;ЎНг…ЉоCŒH,rќЗ Jь.Іoк.З*ВйП Zv.н+ИЊAюCџMкї•*bх?Э-џ!РшœљЊWх!S€DЧОoC5  DЃ+Ћˆ]уК`ьШlМoуJшZl)­gU#ЙМв-ѕ“EgŸlОYk)М§є8щBЛr>R–УЊ>FoЅьэ,C0…bц^Qр'=‡ ЫЪ] ‰QърnќŸ@вŠсЕХАШїlmЎЄђцХ2БЃl>JЅŸnд€<.d/ ‰šЊѓ‡ЙX†ёуmпAž…ž$™тРLœёxq%Чf–ж\ЄIEРчAэЉ­)Ÿш)?*rrB.QzŸcCп‘0› яеђУсЊ Ђ лj:XWВ•9pzйё#ogdЉz'Ф§Kќбv'9ЄЂyxЗюЗи\ОЯ\ Zю#Ь-ЕВ;йdНд,ГШrоiƒ§Л6И„I—lЮV*fYЎгв)ХФў-иwТ8.НIЧ2DšD%яR1[сc$Я˜Ќтг%їиэ ЄЖz,ClФDед-Їп–а“rдG4[Ь{s:иЪѓйњtа›€‡2KІdU<џiE2Ј“ШЛz”фOфu5ЏЁ42CWrlU-8^Ўr5œАќ8yckpF_ 2/NV„Ч=с{KU4Ш\ЏŽy…–Њ§<хЛтА+nenВ3nSiД…4—+ ўьy^…МЯQ4 ы+ΘжЪ–gVфь' њ%‹Ю–B„†оd„Zяvѓє vэЛу*˜ $RЦъNсб' ŸHˆGСŒБМ}Н}ібћ\H;fОJђ’Ї}ш9ј)OХQ MР<уў/Г@lИnvOѕHлƒЊ%Qш=ћш;!0ˆљZ­lЎц­`вн­Яі ”тя`ЕЬ;ѓоaТЈДЉЋп@?Ь98НЫ @C ,ЗњEHНЮ ъЁДэH ƒМЇ?OгЅkLŠlлAЬŠnмкИ1№pя§і_вЄіyr8†1е^ˆR ь!жk„чЗfк$Жц>FcфЫf)W,„BЄe,ЎЕ ,оеl \›SRсњ†ї5G.тaN_џ~m2СKЉYPЎЂ5–wl,`ЎѓNwH&lЧтЃБƒ”ЎСЁ4Й6хvWкT1gpSз“[VњVuЇї!ЮЈ}*Ѓ‰њмAe5ˆжм•ЮOgЧСмЗеѕU}Їа%`f`Єхг0ЙFѕФSSpяьCѕjКкIcЁкАъщюшT^0э€юeоћgDЯиОŽ ›фX0}Ь–ВЅІoЖб ќў‚ЯШЏэњфЂЈI Ж€§:ЛвšпМЪН6 КзПДЭ…<О&=рWŽЂнРp(61ш*њэ<Сž ЦИHUfФв{ееoбušЦУŽ‘Щe0/tЪѕыбё'Y@NЧс­ŠlФ€А:*оШЉt–ЄЉ™п‡нЅZ И:.Khz^XРп XНЅгХш™S^а= ѓѓњnэ­о<’ƒ§ы‡ХС FЋ Ѕ€YI•eв‚ФœНѕюЕксџ*Щ1IАђ;уБх"Џ‹@_VчКй‚д§БEs[PЖ3} фїˆМќw=%DгHG?ЕЊ2ЬзiжqнгtУ к‚iвпЇI§|Cc КiI PŸ.wUрЈЁBžFM<ІЅѓŽ6ї@њ{€2n{jмRНрn]aлѓDёŠnt†юИrУ„!І4Q№%,L+аЖ;œeŽ˜Zo,N"€|Ю7:кU3я!dи‰_cм‘ѕCqqуф[@>&Р„ѕEeзЧЊN2МН ТБc‰в>РО4œ;x‰з|%цœ"Yцƒ‡4;фд‡щўia †џA­ lтгжžC&u”?CГ™"іIaоt‡'ф> ?w&\Ђ9C7ЌІрeb]_Л"YШБ 0єўUGUQLБЕ•w мБ)˜c‡ћD†G pbgЊ/йЧжжК)b“cq Ыіы!–юKeСШJ'п[б.УUVН#]Ы*@ў§ИўElФ ƒdeІФ:Lъtkj”UэmI4KVрYойqС“!гЧЅзa"jYцGбhэ*uz=ЖЩ’ЙfN†G|OдНvяЃV,t[7Ь'хW iс s“K!EЅ;еŒЙnё_#ђZL™ЇЛxОюŽ;ї„QЌй0ФмKcK’ФГд!ЎMЗуЁя*Kќй”ЈžеCбй@<–’щhP03У№№Ёl3ўшzZu Ј†Žž;Ÿp3Xlф‡CЮ Ў‰>Н:ЫHqЏciLNtО‚@С^’Iѓ_ƒП4fžGn*ў'ŸŸEcљEО№kc@+`йZ’‘ЬA~еS:RxТXЃosmQ: Ы –gмЉIЬfЯ<‹ Ш4ИрБ$2№Џ“?sЦокрњ|к‚Ц(ЕЦўЁ—Ш‰‡џQ[NP\“D%‰ўLŸ„vžа›/Ѓ…YшSЄ„@O2Е>АJЊ.Ш(џАљXŒщ^Ў‡7fя5љ–iDZ~ЧЂqц3™й\ЕVяٯ৉mБј)#ЊоРiIцУ‹/ЌsEи}†ЩžLЈžаІT^F'њЬ4Y.ž\yz+љZЎ>шЏ4э'LHЈ[п№?Ь—{h “Ъў)Љ]?5ЬF uЕ_wѓЭ‚лђcуK…‰:vЖВ37k Ќ№™!…+љИn№ Ј—гЋ]?6flWяэĘсЦ№aœьч\ЊkрzћшШУбf_Š™ћЪо$)яз„]ъh-3йЩдhIђЭ u))ЪЧ™]рМU]=fЫ6Fw# ШЙћ?Цв‰@Ѕ&+їXцЋ@ш $!Аo7хРаZ@s?XэУ:ŒL ,eёђ“2gѕŒ]е—@Ж-ыxXлw1Ш/КУ’сdФ<;{ѕKш5Ъ}+Іxк›5ššUbuEШ2йЭЄ]сГІэŸ.cKq OjA vo#ЊЃёŒgŸв0 aјYEб4іКsЛuљБз "GžІР7 Ж(€ЖЫЈOcщylуз4ўHмMњOю§šrчs sИ*JkэŸ>Н і—Цv#xц Г0X‰?дрHžЫЧTuшCœ›j‘‰œˆXпбU}пвt?ЭяTЧ ОЏKћiдtЏFžя>„щ_ЁЅЯЦZ›˜уро Ѕ†ЌjЃ†2œЙИƒ =ybgІЖNеЏв‚їЩyїёН[а ж& zЫŠhжюћCUŽnIхЯ тH>4cyG4fтs™2дщѓ,йуДе!<Г Liќhс3…D]lЗsœ…ŒЌќš gј‰j”H-ѓ†б€ЛaH7lЏЙаЉБЄ‚™Yѓu§1N˜ТRг‰cн„Я(Н&|Ф,( 5_‰ћыэF&-rZТЖЛN›*ЊР”ZuыjАёіР0Б`Іћ“Яc;_s№ŸЁLOаВЙЌ}Б‡РUЅлЙ0‹…‡г2ш‚+гgШ}Уњ„dА}B ЇЌnƒЯŠ=Šѕ„љGšоŒ6Q@Ђ}ю€m >T- ё‚•WЃBђoNHыЫэ›ЧЃГ№л}H{%ЦQиЄ‰­ J’_ўбгЙяŸџГФе™шV'Њ]зў6˜ƒ(˜ќШCœvЗ•3ЈЧн‚‚м0uыФдDXaД( И€RНС{ѕ&BCJђ\†Pm™Baьи“yƒxr'ой# БРП_оcщ+OЫъ’Љ№WЪ§cRшшЏеЌѓ@ъЖЎŒџ2T!cxT‚Ќ QU .h-EЄцљэђњn"EFЂљR.В!Г­ФЎeё&сQЈri(Et/h[эњSЎЦ Ž/,іМ{АВЙpЙglЋБр›шЗ4”4јГC Я>юйYЁv†Јпp—b™ъŠРkњW—ŒFšж‘ёЬ9.–§МО•ьеќ#h&7_-ЁЭmcйnвјл€zЋlёЄ 8B­e”\;БА€–лЫаТБфAˆNХœК?(r‡]EgИь4qђАFэиEyз ТэŸЎі/+?мія]ИЈ0вэЄК‘ќ`&Н-њъ~/Z mХСNgнгs,БžЕА1*†в)Ѕ!‰Пža~щ‘3фnНTЄrгГ*Ч`…[`ogЗщЕеКшNY5ъйG&MЌbМ2q7]ДЉkчNяПx:МЕУNыС[~cчUz0Ё–GљВCЪlS?wHЦdk&^%Išь-KЯ ЛчЁšх/Єt­№ФFVaЂqЮэaК)€GЩЊgЌRЁэ#4Œ_‚Ј =щ]‹4ЖУљЭЎPЃdO3 9žг4aЃˆ‹д—ТA7;иYЗ0сбL=ЌAйЅ_%„xё3Њhzы)џ ёŽ*$ђхrQй),œ ЏЕm 9XžЧѓŠБсо4тЌGŒ4‹§"lџ~йf'Ёд4:>ф{(г[<иGЖ ЂPќиU;ц_йЫЕд~жU’$цуэ_а'Q&JэНTЯ=е‘ŽЎjU–ŸО Є0И:žМ‚ю[ŸиЭHђ:џtъъsSЌОt&ур)ЉLћL4*Ÿоfƒ 7ШšТШgФющr7ьfa”ј†šКjЧЮHтєaXщ„ €ФЪџbТAюхŠ =(ЄЕП@­7KчёgIД<šдlxЫЈO`•Љз[]о>рй•d!PъXВ›ЇЛЇх) =CёvжŽ§_Ћч "ЧЎЇ‡SЃHdж_‘dщк@Ъ€*М§"6С›Д€Ђ‚K(Аqэ­uф’ќз_ѓbЪš%Œ$pŸИ$іЋ0qG…ЙЂэБi{кŠд\ЬН!СЃЈ„‰‹Jћв;Е6Š_ГIхQЉ!XЗƒnо$“6“Ј„a,Pƒ‹QOгs` qЬЇC€ш‰cђйз_2ИРк…†ьˆКЗчцg,Еž+=F\^b шЮ’ЃЮ{o$Ke\Ю Я"ВЙT„ч*уWк9ѕж|jЁКiA&XцМbЩф-ѓhЦMМ;<_Жj)ж]œ?фIFABXъ6ХџђћŒk‰Це#GLгѕ1д8зУ€vе ƒпЌT] BЭ›люфC`цJ<Ю‘ЅPсБ@ў№€ 8?ЋНЪЯЧЯ сFgѓњŠƒЮоД№Xm}є(h $дЂ#зr!’ЄръПC"і?gњЛoв’СšœЗ6z3ыуѕцйUpЭ_€Sr‘Ф2р0hY(Ma)ŸтХoC˜хv%Л+№—ыPНGф3Q‰@яАC]УДqH'ЫоKDzХ>ЪУ'Ю!6м‘ЧеЉє&”ЧЎ<зЏЄЊ6-HїЙUb•жЊ‰АўИ­œŒsWё!^эщсАТsчt6оxМР.LcЈ7 bЮ№1!žЌЎю–5ЏЂADХЎ“а`яЗьaщє§i^Ё-Яmбœ0;ЮУДЧ/О чѓPС‘7-‚шхпsŽ<~€М•шWЋcЊщф8„^ мэ.АDˆЩЗ‡П)ЈНzЫт•ЁсP|1ДЩЦњі002шИЗ*мZ)O3 pщrxЧЏ-йбqЋmЊ%ш54ЃФЁR5,Ё9ЋvЦ••p‰ЏЬўуќ^шuџ%hЏnœЗ1ЃsйпHU)и1$ПYБРУщЮŒ€Bx,:6NJ€n Х9™§ЏŒ”1еєъЖЈі*Ш.@&zэ!Џ$ьnp*ОЊ*г=§€ ђфХаVЊћЃаЖЈДЁЁЌсVoБя§РђŸфyђГ‰wE/†ѓБ,n—0НеhЇ(O=8чсЈ”YМW'ћ^Д259ЩёХ…пщБЯGАœд§О ЖrGЕЬ–ь/ юYжy,№ ‰?Фa ЮИU`ПЗзєbK‹3to^NБЙЩьPXDТ‡Žu"Й№YгœІњЧЛўp{‚+ћСгЅŒ”9ЙœљЖЊќќЙѓвіЊI*лцзvWšqЌlлЊ0ўЖФ$ПЈ›:В+0 н ’љёЪкЃ–ˆQ„џ!w†" ‰zрW—žю-’№ЎќTІHръЮрP лЅ-TJ4j Ћ8/ц[ёнtч>ЪЬ5La‘h„’тKЃшКЉѓљРP6?yќЋМKг&+Žѓ+MО M B™ьšе­:c{uгqБAWЖ#q‡—ћХЙЋD2B^,№Ž’ №И(ёФЙџw:‚ Є.Oкoк­Cс%сž№ўUФ.ЮkДф@Яh–й.гчP|‚іК–Gtч*нb˜m5‡пМoЬa)ЫяАї‚1їlЂ0:•ОРбф.G…ыб[Ѓ‚сЦ2Sє С`єЧ(wwoYА*sbЭ-Хз/–cQі™rћVЅ‰)ЉQЎтAю9ж!+`їыя9ІЗЃLƒюgФЗкђэ”у§ЩЬiњžМ‹ЛЪ4<lM‰џOЏ„С]Щ(љчн_ПЙћѕMAoюZO)НHŸђNё 6т'hzШtvО3 E$љ‚уЖм‰{p•!Y‡щЗ,4cЫѓ”„Df8h_У АnGCўXќgТ ‰“}АСєШ9МљœУ;ЃУџ."‚тЄЁw†)q“ЊЙyАЋ_}*ЗH\-{<уаEQѓ-ІЄЏВкTзљ›’‰Йg&VюPzYєСеЄqЗ/ZцœЃмGдЩЙјсPQЬ?u+ц‰Ÿ‡ЇШl‘7єžЊUѕŠ‰„YC*gхвнаu/eм,Џqm…YqRdгRЗп–o=Tиaє'Ргщ ?об`'d7!NBЊuЙ,єK`[ A"(’wИWјфp&uРLОMYЉ“ryJ'­%V—р1.ЯЬqШЦч}U3ƒд97z”*5*і ‹јљЩїNreя~Ђџ'иЈх“‘Ф–ъЫРКНsIK'D \“/ЩŽєB].ї-QЖBІ0Œ ѓЩdUЇш 5ц xУ'а“ЩВinФ#р.ˆ:г“$3ѓП5RЋd“ яŒстLн6ŸrЏpз кЕ†Љ6<Иб(–Ÿ4ѓОв№pЅкYh`Л<ж›Х‚•шЕдмљ^–"%і2ƒ•“†Ќ˜$ЦЭzš-“д§BƒYїј­Crіж_‚ˆyг›*щкК‘џ.§zаyЬUРТљІžžBX=)Збz"#M†+mP ƒ`P kкfœмдЖЛdВr/)lў'ˆЋL˜вcšЪZЮ}4YаGXЫЌй€-М9,ѕЗzЋ0Ѓћ$MSauƒ4Жё†Я—ДЏГ ЕѕСХ§ЛЖъџ:fъј:шЃ ЉSЃyњl4t“Ž х”}з<ЕД—FLхА`nlНU^Ќ 5кёO!м2‡ЉЗЗaŽ˜[№идB›ƒE‡œњЧЗЅ~a†иеРCU-ес}юъЈЦMёьќI›5гK(-v˜tcц‹dšрjWeœyЖћ9†№&Нуm“Ъљ+Ф—вђ2"ь bџQ”AЇBm§ЈЯmЮ„вnыЭП‘ѕA cЛ#LWо… z№Œ”]є+…lO. лмф"ѓSFЃ'SSјXyŽeџ~ьRчq|киVKЯГ„иkэE№˜8*итf(c˜Љ…ƒkЇљщ‘кЯb сдЭ—пŠ-Йtšѕ€іЬ˜•ЙŸчќZCKюњ9ІтНYѓn— ђ@РъЁї”[ў^Є|Р[х@G™ЮЊТ9ŠФNАсЉ:=г:СtsјІрO;ВрCТеE+ЛЁQŸь˜4№гk-‘A?БUuuОtМwвФРљь]ž6NŸ)цECžv;б‚ И*QpАCФюЯ5^6з\+ХФkŠ‚HС[ єі&FЅo@R,"o CЋсЈЭЇNˆ ŽjС:‹ЩяЩESJСwЧDуiЉH$ї~Š5љ(ЪрB›–AАКgЧч­тZЈ9№Їё[єщFЬ2цЊЇuѕђbЂ‡eЛ3Њ‹ДhЪІНАВdўЈ;b8х“}еИŒƒ`yrGЃHдЬоL%чDЏ‹œЦХrЇwйpя™ZˆH 8вдВeYМЖяbpЬDЪR‰HЎвЯћу;^Iчљd6ѕ3Ж €жЬ#ћк­PeЎАѓm_юY-ъc—˜ jNњnТœ^L…яR–еWuС…%мHУž[‰4ІVŸ;y/џkЇЬњќъ,ЌСАдB.ђ^г ж]›$бjtпWљ1в$ЯUђ™2ђ”VƒЪ љрwЩШSЇ–ћgOКeŽД\sьyUС\‘~‹\,XQ‡ЎЬwPД­ЖТЖ2OхЪљxҘЩлЫVлЧњ*;-фсЬјєh&&—[(VлзеЎЄбЪс НёvьКујѕ1UюpMf•>CіVШкѓVLI„aBЎB Йф^ьsЖИ3Ює{‘цЭНf›]^рїHU*ЄŸhХlтсЇњѓZ`>ёўГЌІе—йГъЯи›`ЎЄС:эЏfђlЕћЊљ#СЬ юzя V™бsВM–“Є(7фyЂlOтњЧžТ•жї/ЄРZЕˆнЁ_,r|яlmx•yЁŸ#ХšыяžM%€”ё–ERЂqiŸд‡Њ‰Их`њыb`r‹ ’КˆйфfЉW­Џ2гbЉаХaoНќЫв>hфоТЛ;CIŠКЪе&Іw‹љ FЅіuЎЦ`.МЩ‚ У „%hО›Ќ^Bd[ю ™бПрђx…tcд“u?рћZZк=цi­ЃЗрЙ2…|iˆЖ%ЕƒЖХ>њ  œoMЕЌ zX^‘zC1UŒ™фГIЙг=ЁA}‚7ŸдИžУ{“‹p\/сЦLџQnЖЋсЎ:ёXчт !ГЈŸ2)a ШЇ•у^щhЦ•IІіЛ9ъp'ЎяšE8oЬ?†xЄБмoотбџTkл @ О.w—І;-ќXžbЊУu-`?†‘*S&ЄтнLГФЭьтWЧ‹Б­-А/Eњ'пBeќzDо‰эKиh7ЪQџ ,‰>љngvЈфвЏўcŸ1Mћхw ц$=Ч:/9Д†–р3JСєjй7‚HfylюЏЩх‰@я[vуˆ9B; уq“ыЧ{NЅ{ШІТ-zЈцВтЩ(Jtt-1P?šZлšШRYъ ћз–МX&ЬwПVЙ2rд‡5$п!лah73W{‹ЙgМ‘Ч”ƒЯ&eB‹ƒгт‚d0`ъЇ\][”>ŸЕžеПЫћџbeГЕ EоqRѓіЎUЙ žM;хsP+ƒМ-з$ шF™q%xM8(O­ c!ˆhKНР,i$ž-ЮЏJЧ]Ъ›‡yFcнѓ”Э…ћ skЉ€Л§XћЗК§ЇЦГ{їюOЛ/z@€že,a. Њ)РЅNјзљ#3ДF‚Вoиdx!юА!РJ„mТ}€КРnіЂ–з†ŸюUфЇК[ЪАєР&ќњџ0$жlљFШ OЖ”Ёх”–1ёЇNš-…ОзG?§LR“ ЁыYх*‚(Їhdч y‘Х cіпф­ЫSAx™ђ?БњЉtZђhбYi=”ЮA"{ЊIF‹И)І9VkЕ!)љ‹И^r™zscюaˆCi^b=eГЇ3­œћ‰tйyЊyьXJ˜xеЋ=ыЦ.Ow‡;†г&№(ЗћАЦЯѕзyК\rL*Е$еbБ#ђбАЮ‘8]ЦЎПGЂэŸК”О”}bр\t~гЭЉwр Ф"&wы$ВжŽ“шНп†TЅxЯУBwMxТФt%_Lє,dsж\Oљ‡х{ПQSМ;g)MкJнИљA$ОЗaR[!-eeIf1єG 4Œєъъa‡Јщ„e5mш‡ˆKМ+ОмАА?О62 iк Ÿ qџa‡Щ2\Ахq k>ую‹a6ђiѕЌ>K—ЬЂ›GхlRЪ3›љлюьxо&§а§гјбКlZџiG*ЭЪ’5юgјLh1Вo›пЩŸКд[/}цЖЉOЁэЮnЯ8Q\{FЃ ѓhзТ™Ÿп @ч‡‘і<Шs ЭІW…ЪУK&IŽlhVa{ђ{цЅИт›\;8ўF“UрА›6)…‡3r№~Ь!ПjЊМˆDSCъмХќF№9Ї­{ˆEЬdƒйвЊjšПєF"FА wюЛžrш• Љj=˜ЉерWщŽJ`f(?їˆ­ jaЮпІ ˜Я&Є$‰а‹ІЧЯ$nииLЦХUYФgAДЏдV#ŒiqЮжЂ8чЅзK(qЖ-Ы 6јЬНЉч]›KЏљyоHiubљTŒк1їч–†?гOPrЌыЁœЦ­sЪKhИЏkufе§ŒЄбœИ­pŽііъџx„С-ўNnНий€гЇKтqд+Ћ$§;„Xœ ІOУƒ<Ъ:rЂИƒs=‹ˆc† ‚бRƒкЇлiЫпЙ| Н(<уq8пJн•в„žЕX[aй‡\“ЮСпЄЋгБбW6.Ёхѓ”{.šQЧаmшљ}vpю“8ЅТвЮЙЗХЛ*слWёЋѓ& д[јƒЭВЭsЉUŠЄ2m3Ѓьыџ>S LeАИВ„˜ С \šоЙ{ЌяKз;€эsт‹zpМЋ– :ЪІЮ ‹wjѕъЮkЁ›Х@Є_яЃђнZЯќ6[#ЊЦнП;КЕ—ЇBВyџe'љ›_Њ–ы.Е€ЉЮЯ&3y8MX‰ЭХ;[‚*}(–Н‰љедŒ–Њ4?Ё= ЛуAn(&мХПППасчъW ) KзТъRG[б;<џsињф_”ў5ЙІЭ‡ћm[йšˆўя&ф9@—ь–уI1ыxнmЙ vч†ЏvХ€щSЌ`єc?-@zЗцtfFТуBw#‚Ю…Дъ-˜‡Iлƒ%iНя3-ќ)ЕŸї мŠхЇ4+оV•њыO"iюаІ№3Hћ“l>/aSOKВБYьZaa€џMЧбВѕИv ѕ?Ц8яЂ”ЃajўСt?АЅуЫqšпл[тN ”вТ%у&‘pУ?kvбиSЇ‘LšИCЧћ˜ZГŠЃЩKтЏышm"rвУЖVџHАLpШjъA—nш^Ѓz№Q8x{ц7j”U˜Є Љ–ЂкAћйi*6IрqсЉEИд.m9ŽТдјz[ra˜,9cA+фpƒwFё~ѓр&ио<ѕ6W3pѕ_ХЇwэ ŠеЛк3яU~УЧuќkЇŽ QУЛчVм‚>c%3p‡љ”кЮс[nьUЄ_š0h~RдђЩнёoЩЕэЃДЌ ЙЙNzsn2]“н=IЏ Ы нъЧэйі2’КlбOћЏwс†”ЏБ%kEлu_ —GLA=ЊЬаsš9šjЇИч§aхq№їU§s;5ЯHхзЯгНЪXOiџUЄЋццђс,Ц8€Ж0zЫN”'(ъ`n*к~!-C­tЇy[T#уу[cЛRЎі,…n$tTѓтMэ˜ї9~Аш…Ќ+ђѓb”iŒ.Л2WюВЛ\зЌбDуKnU˜ј”кИIYимвfNxў|”4TЙU|#я‚ђ)ЃШ‘еsЯŒѕ"ŸjіoэeК…Їщс 9цъc}'E™C ?f•?ѓЊЪЛ„—сRA€сМA‹!˜dRО*шXэвВ<ь.’IљмР=pЩy…ŽтF?"97Б`Ћ%o§-7&ˆ_г(т AF@ƒЇПА|pЦ‡/Н›;чщa0хДвЗx‚0ѓѕ8&N!ЄйЦ№y‹œVF szЕц`Ч™Q’ЎђŠзGUЬзcПк8 !FLЎ>йl/vнBјP)~г“Ыьју~ЇЋтkšъ€уf№‡ј†œМ Ў‰џ;ќoTкBSкаFbЬQП K0<Ъ i'ЎћїCНѕГЕ)В.z)К"Dѕљ …шЗіЯl №/ОѕЮ•ћЎvlѕйЊ2œюЧdщtK§Qю+Вѕ УјmЗЩ-Д†Ѕ†Фюш[h§…РлrtaёЈ!yЗ1Ѓ>1" s&Лкw„„šUНє4Гj]ќюфа‡Я,_їgІHGa~EЕЎЋСЕѕЉM/Ёj‚yUСD"_бQЧ%65mƒU'•ЌAЎ“†]ЧёЃFpALлcЅ}гнfЙ,Ф+uRŽкс=ОCsvлщƒnќш˜лJ8Пˆ§ї.nƒЅЂˆм*hЁxeДз†CљVfgL‰ШЯ›=п7Ѕ?hП.Оa6"Ої/š‹эsІДсЬІЃž0&‹Э'­CrЂ@l,TY1y рр J%ЕсœaР Бџ‘$IШмЎ-ъбдЊщ>Ќlk%=ЌљоЁžћж@т mVmBЪ"ЋэaŸNЕ{zw“TWDФГU§A%ЮЙXџ8ЙQ:(ыОž†Р@Њv ПЧ,в№U uŽљ NQ…VZЩЧ3ѓЭГмI>Ио—kZ:ШЫˆэUjeЫ}^‡мS‰”KћяЧŠ<ўd!‘ЁЬuюгЅRлEŠдЃ+@оІоНš ЏфаjЕ8[OMЬГgКв‚u"‚мнЌЈщЌE1ТAcœQяЊuыь|pВџAЧ {#ЃкFђсžpАPЦй1K–јK1ЏFБPо НpУ$–йy]‰Ќщэ|}З Vz,еФЖK‘Wз/‰ ЙMKхИ#ьXrАIIеНюЊ™“ЂŽЦI‰S@‡КG›u&КwЪlнkˆч†;qјъ;о’^SЌ‡и}Бљ"Ф(ŽшvМ>?J hzjГMs3а[“2 xе‹XŠ|GЊСdђо”&Л&(‡€GJ*Єшщ…MЧЂE:ˆ“Я{‚šKџ^З-CqК ї‰œЩ[#€c[ўгќПSЌИыџyїдуЗKСиДёѕlІyСYЅS љi­EЉт€Ќiє{оІZЈ&'$жЎZPЄА:Пэpчb[ь)ЈjšХ”%зцx Р fk”NvCЬ?…—ZЖ›wЃе‡i_ˆЯs2LЧn™[Й…хќЈBsЪU”vАyvD6}œыIкoHэzМ&ZпМ lїљнЊ€­!Ћ-:Р8EЛ–H+№–№гВAњЁeжeBлы}Бeсh:ђM-Е’/Џч—(IKC№Б—Гrf ѕу– ЄWЖЇŒW аеЮњ}ТљќLџ!€8z#Ї195•єZ SMVѕ,UŠ„Ž?xфэЯжБћMlЉbљDЦ$›№И›8sFз9 е‹`ц}МmeTуg‘q Б—яЂSЌ!—œ#0Ѕ нˆлhzG@яЫ“Њо.фy5жФпЌЯp#ƒhœыєzв=§Ю3d%?їх@wЛMВК+,iЎ€еїIОB'z;z< \Цe2п%‡$п­Њ›o‚ъК;YџMмT"пŸжЏiH_oП"дз8yСžiп5ѕ`ЖnZ№!YыъџnWEЭ}: :яп™ъщЙ1ѓVщ Tыл5(9d&г~8Š5‘q@:ььќккESm"Xy02ЈfE,ёЈAш}v1щэp!œO№DЙЉFcЎ4Нjќ~3VФ†bЈъЌ/бьВ р4Ѕ™ˆpXЫ•ђyёъЌC:8GaoЅэƒ&Є§й’~YП‰~ъеи‡8cх)Г~ є– ­,“І*ј2=Й ћуƒšЏœyг Н8%дзрЉЊіq^ДŠT4@IхЕсDЌDђ2‚НMГіeдёw=жЬ6№LЃ=Ѕі?‹™їЊЙГš1ЄAЫќЌэ3йИЪ•VAJ‚Юqс ќ;Бў­§]‹т д>š§К+ћ{:ТлCспяЋCo^@јrШi„fŒWРЊёЪМЅA Ў#$”HОо‰E!a%‹‘ ao*Ч‡шEgNХцЗЧw.кxG€|-ёхНМё‚Шњђђyб§™Kъ*‡ЭAuIˆXŒMRЭЏoоM/‘MN}2ЫhЏ?ћѕЎЃqАл$ŠќћјpЫ›шƒŸ<фpчjЛт0ђuм№ы8Юю7ZивШsё˜ежсЮ.4є~!2=anйKъР|„Kр=ЄSeGM5Е‰жэЃш@žгBP)шбФ%јгjБдўе.п щ5їЦ“Ъt yzc o нтЬdHЎGN=<$ Д)џpххЅо45S`оaАФЊ-ЏёОњt1OQЩЙSїŠ.?ИОљЈY$ Bi>Q>'DПЙЬШo|7vђfЌg‡уAЃЁF#cГS.ШЄйлѓГJЯ'!жіьБ$QДgАыOw zZЧD+TDўы–Јm‚‚71FJаžУ.hвkЗЛеЄR2sч1НЖчщ к бУГ H?^'Г-*^зф;Н7р`а“Ѕ–1Ÿ…[МХNЂЃZEЂМ)ьk{Ьзg'пуŒо C_]f|сOYь>‡жtj ‹•пТA]Й ШшЛVSм{ž…p]P\qіOИ:іѕћќпрvфTФwУl№–Гз3h"X\FђЌ ™cМ>й$c~р›C§5ђ#ЊћК<‘чгкcфзYђRйXД­KGКjkлА Є;сXDПэ*uђ>ж›*Яњ›”ж#I@Lf<§,Тщ%В*л<ќOImоЊ…џ~ЪЋЃ9›oџQ@ЊRЃ?yђквЭVг`и‰цAnё.ŽU›6 ’e?gДm­$ж9 ѕŒœ8Фс IюCФ$KПjоg ЂоХz&J+@ЁМЛЌUд(I~TљbЧяn˜skЧ/N­’?›y‰‰йiЏclеи€рЛфsPЗd;риrн <Ёї=Qy^юŠu…ЯKѓтчѓЕо–”Ћч!ЫZ3RЙ+S“аЃїv$@_ЬNю—‰‡>сњЉРHщsЙМwi~3<ім овєёЅ~бЯ_ н-h~жK›у™)qъЕ… ьЖсо†kШA*/сЇ2‘ЎУСJћ1TS•ЖЦу!†~]ЉЎTБ– 7Ї#3ёW‡ЂQRxPЙб{(ВcѓЎЬ==Ь{…Дэ2њaЋ^сщхžŽ c.№YеiлВ,XYЎЊз“їЧШpŠq˜™бљZ—еКХ е‚—ЕQ•=њу­-бfzNVYaDOк &bќiєЯNdь~‰$ве~‡.ŒЯ Љм^>BІЎ _?;0„шlЕЯ8OЌЁѓ8\о ъ)Б]ѕnћŒ№ўжŒkєp‚UѓONZFN]8ЅБ№БМєђўЪж˜і1Ѕ4і>ЃО Ќ|ЗZ›еЭLј 6т“ѕ9П3 9j[К^ИмН_•ЪšI0‡ифk9ƒ9яv†чЕђžUšј˜zбTѕ(ф ІX%?9$ЯПЄEјMŽЧ$OT@Ч\*|ёWœTa‚мЕТ'Гъ рШwєN†‚SЋžTИОŸwЎўаˆл3LЇЇ†§>Х$dгaœ8й9j.­0œiG?•щКТрНЄZХ”ŽHзЅW 7дˆЙљд^ŠѕСзэНођeОD)ѓvуRC-Ѓ(ея—&pЦhК™”YїЅЇ.Ѓ-цм—УДЌђ‘;Њ^‚IЂo__V5 вБ.ЂАœ$seйц~гЩт‰rž•?51<п-Јуe#VoШьўj /{qЫž^эiЄIЈКТ,ую1]a’ёТЂ]лpx/ nr–й4 %ЉoCЧ4н@0|!'ї—б,ЮА™eСDuzŠђКmb Lп' BO…И:™ИH ѓмo!HGйЈ5зuxяСjАAб YaЎд”!)Л’|–)jГеwОа8•Ћ еEАI•ЄЫ{№ЫЇжј(лњ:Ч sH+жМ1HйTСItўœЏyŠLЏЏŸ4ЇCу.щёъ?ьVC4JЇŸgœQh;}VtqИЭтЧIѓь }P}‡б8ŠяƒсЙѕ<‰Q…јHt•ъЈl–ЏЕЕГBЬ@ФŠусЌЋ­ƒє‹Д~двЫm1cš­HЪ_љЂЙЗcxѕs ПВ€]žіпSТ2ћ1ŠЙ RY=]G„2(Х`жAŠQЏ[N‘*Н ra‰ГKХмˆ\Ы_їнzZJ‰OR ˜2TющДЖbŸE@xžNC,pчП N№Gк6ь}иj9M(€оnƒki‘СВ=мёНcнЈd_[LѓЯИg{ЇOа@Гa l~™]FызWѕўь_EќoAШсХfНsOu4~х.яЊ"ŒТХОHТ33–2WвБ1І˜ћw‡šcѕ 6з,WgЕž‚ьЖЭРEЌŒXvJz шр;Яс#лг—EЎž?ЛЋД^-‘^Ћ#jCТCUі6‘Y5іMы?1Єm= Fба&$tKgbDђfk[ей\ СО№@ТЩіуби7M)ч{љ:№UМ;C€ѕ`{АqМ ,kѕЛК‘Ђ'ч?\˜;“ ;Е*ТПа,ƒТr <уNѓЕ ^tŸŠЗWфiSB@э`ŠQсжE_Э§cЅд%kR–CїЧУ‘t0§ƒ‘Lмн,Roв5о˜LџиbP‰7t†хxƒ:=}Чb|l>%VЉwзЅRjхЇ=м ™чЮWЪ?ђFи‡Eэ|Ц Ї.хnЃI†† ”qеъF\7Œ\ХxPёМХИРJЬAAэQ]НЪгУ‹всIyFЈ№ Eий]3IОтЧ?9ƒпВFЁ‹\хŸЕšXјм У\L753хŒйŸ"М><‹ЯT”ЫеIЗi03 NxЊV~VъUјbђ™ШvrФЋўL*7„UМгё›в^ЄАЙ†ИSЇтІ…Œт_8ыА?ЙT(dЩа9$+(?Юk, XђKКVзЙЁъљаjˆK .љ5'Ъ=аоЦoСћТГ$"ѕјЖNPѕO-рЩ`\Й0LЩ‹ћ -;CѓHАˆсьЄХ!k9Х+0pˆ|ц^8}H™№ШНыГ)-ŽDїšIЪТуо1Х#2Ю•ЫИpщ а‘пPЮЉЖ/vjџn~ˆ=BIЉ0ъy,ыв•5Zуp"(CтiУiо4&ЏB‡yщ№Ы\‹і>m”pŽyБ<ръBЉ€о…ŽЭ"f ›ƒђHSчсFSВБВжЁDЂ дXNєvЌiwQШIkЌћџЩ—цŸД>FЮ$'] rb{Z$ŠПIZ/ІЌ@я„ щы%т“.hЊ’I’˜БЂИ3›GћЫNF ўeё“схТГЩЕ(ЧmsсZ"дŒ~‡H/рЗ@ZBгgl2_3yх ЮUМ\O'ќW8дь.€Te\/`aЅ‡­ЫД9 бfћ™уg&+єaEхТ>бцП“•€dЉOaџ8CQПVYšС4‹†Т|sЮ ITцeБaз-{љќŠƒ^€ЃСйЈ‰Ф$УЉрОЬрЛїлSг$О0ЅЄЫЌѓ$^q] OЕ“ЗoХ%&ЙчE…ћuqЙ|iTѕЯБб6лi^gœO.џdї6…ЋеZБQ3.)Ц ю…У%ОШvG‚r}Ђ… H‹Мaі ЃЂа]‚ЏцЯM;œwjЪ/ыxйSТсНѓКз{:ъэ$@шA|Б)h…k м~­§}"$ЗH9;I:aEщЪђ)j–bдЗnОўхДmГKЌVwЦМAeбЭdž*[гAR'оKДбqяВpв›JЦзйцšТ$и†ч)щšЊ€ZftЃ ЭчW&б‡ рЪЋ;?лYФeХЈHзВћž}‹%S}бЛN:D‚х щG|йjшиE*7e<НЙ~hUi›ЕДЛюEЕžA6Њ–Oщƒ"CV#rћф ЭЛМ”„W„AXiRœышfХŽщм;•Ѕq~РЯ Шjj=‡ЉцраƒЁПё&WЌЏ>еf0ыUєџ†G^e#іф–šЗšFНнqй:€WУ<ЪЧšРЦЇ›эъиДae 8?УЄииВх§J–ДЃ•›SИ;йi .-wМŒU 5-iAJЇИЫƒ•$йЧ‹Ч&ЂьJБ1Блš-­š‰ЪU1ƒpw^wlЯƒтпі€Mе+%V9ёН(’_ДT-:>dj:—Ї…ЅИЧыiзnЙVžЌ†—oCЮDˆ У-Ч9tжЭ}Šу g,-гЖ‡6q #BБЯщBгТКЄxЊfѕЊЪgќ}#МФ>’(ƒ9 tтъФіШ:aCЙЩKЇ™)DџyеqјNЈЯюд; ў-Ќ ИeићнБт3ќЦiлš•ЩW/Cи?/Z Nљ–†˜A}^Кф‡_ІЖ\Um CŽмоw*z•њЪZ™^(U:—Еќ•Л ˜“КіM–‚Ън2Žt<чCгњ(ЛЈ™uрыУaуrп{ŒZъ€eЊN™+—tnцсх2xя§ Н2ЦЋVЊа’Цў+ј2* šOЁК[ ЧDUxэШЬjzєn'ѓ—сгУЗ_ЋAџ+­ь!кvгѕ_ПЋАlэ\aњЏ/ееШі6P=цqС|жrОІОЉ?Юё.ЬАо  MˆЙœзщpјє И ј‚˜RnŒw€Б~?— ПмС.с:wЖ‰П#йоR>*ЩTHЄЯйЕYє‚^№ШKTПP|єљШš>FЦЋЕ‚Ѓ‹ї˜]ihћѓэг–яжREt˜жwRžQžгyЏЃ$Ц“ЙтГŒ@Bga пЏ‘”kv •$Јgе ЎбС№ž(ЕЈ" s`Eк$ѓwЅмщєДжђ ‰Њp;“эC8ї @чš­cБЛžЅI#ПЅи7-ЩЯX[™ЩЬ+гЅpщгFЪф€Ц”mw]Әn (sšШYЛ€є’ИеЪ<—aБ)•ˆ~Žj'ЛГS‹АУBсВџЁхВ<5KкТМыagї5WНј7н2:ЋёбnVwuЮpоBС(ЧІesжtхтUеЪbuќЉ†ƒлq—‹гђщ­д&K wњЁƘkщUФh…3ХNzЅšБооТПІ6Бмџ?шb!5ЭkАшzЎšпЈы 1ъяЩ:e3}сћЃŠJг І Ђœ<д-ЉOб+а!Ž€ZІќIе{Н}ŸuЮЬk `эuŸОФYYxPЏЫ)нOj,Zƒ4LЃяЎA2в.ѓxц‹ў|oTў@˜Cрс8›sЭ‡З‹tЮ>‹г(b&с"бЗ@гŠ3IVNЦј&тu$lhJБЈўmRZДх  э /‰пf\ЩЌOŒ?žЬХ?6(!Ѕз‹{пўNnА:Ќ%НЕb }Ш?;MеЛR %ЦЛh€ЬRXОHРтž}ŽZгAЅXŽOї”Ўљ—?VBд˜ЦšЪГ<9›5PдkœI–єќ*•#ѓ›AЙ ЯДЌE_$эт“Ђюс2ГG&7оъCТЭp?h€p“Є:k^LpъЈћіѓТ?„enHЙvh6—XМьйоІ<ДэМsи[^hѓ1ц ъ‰rS›KJ-ЯНbћOŒ_ЬuHHmyN:ЃъЌ‘L^цдЬВгц‘к›8ЁЫхНy'ЋЦ›уyмы§'Ѓ„ЪІtšї<+Ь*gћžНqоХSkШ :qS^Ыл№i.E&1gДдЉnЃ іЄ "ШwU$\еeYЮсНŠ”?э Ѕ]ю1ї мОFEмЎъT§˜*Ždz†l’‹ЋjXМ9pњЅаvшS&ЮЄtыВl(:у?jw(0фr™E0V'Ц}ХЮ L$ўL@Ц89Єїа3Œ‘VГе6†щчUЉV5ЏФKЇcиbFх$R&;œЫН!ФеMUщ},хБхn•Јёˆдv_$I™’„­ŸNŠАŸhЖКO6Ъqx‰)нN˜uоХГbиvG 2 Kыч!шќ":pЮDьЇЯQТjш’ с№f—|bQрž0ЭД *„чjO3n<ђXђŸПбпrѕwш›Šu0Œu єЫЇ=EФмш§Нgи’ptь>mz ^MрŠќ‚diuѓvУк%œ9Ѓ8ер 6Mюадт‚ЋZКŒиBёиRsљnЭбsGИё‰?•иЏ|GгџS>wшГы У“p//р_l—їзИь`–Ќ\&rчRр f€у№Qфгy ІSйфQЎ,DгrsELtЬП•i"{ќЬцiЏc[ДЭЈ рfL;8;8ѓs'Т0е%=ˆZ‘qgЯ‚Щ( Зe[—`|ШxT9ž“œвC(ЙїЗИ?$СЖŸшUT4п4cрйїŽEѓŠзbrР?ЦS™V5‡aэQs‚Чf ЃEјЊEŽ,4‘oъ%у:ДCqА|cіІр…ћ АЕ2и:2#nе]Т/H&›еMtHЅWHЎ|`yQJбл0ЫЮ'ˆAч}6XІьКJ\ЂиОТ?]3ЖўN*–TE]А•ОFK-‰(Є‰[хфMŠДrюYžŠoO@ŽёїBис„щDЕhАb7?Іm|ќ:†ёљ.8ЂС˜šŸƒШр"ЮШѓNЭQƒЩФЬшпjф№џРМ]и#zф’n.цž5ZŠЋ^нv€ІГЗZ'–Зѕ­ž”z‚`FIАBЈVЭя)]2ыl\Ж•чKˆry9РSня0neќUmуЁ2лє]—УЇ2кb5Ѓ!…љqЂlрЈГЅД$к#0ю„шц™зя‚лDе2LR…D– M…RБѕ,yd ВKЊGН>ЭŠЫd'=gА їВJtўak+хф—&`š„1b!;$%ЪфkИ'y№JБZм‹ўйТ4išiќbоJ?ЛгkA} ™[ПюtЅыЁ…чd нЇŽПХ3”ƒйЫMXŒ3|Љcв”ЭІыу?Ь!g…чˆuYsgЭЉ˜нйЉън)Cќ„чцсŽGеf3КD5цїeЕ ЪЦЎG ищЏЗ­sœVXlrdтГ„kсKoц‘пя]cк‚|>Ъ*”f§ZЌХQ!PEе36J~QDф<џk/0™ˆЏo ѕI0Vt‡5РЮ1ЫSљжШьЎRŒФšrк;#ГАфtЫОqŠСєНй5,чшЅьЦаˆ"Xш КћЃДФЩfƒš.-›oгN*ŽВЩ'Урp"7ŠPe‡8{4Ї? в9,I ЪhКK™ѓаmЁйОO3ізпЯ"вѕЦЬШ;Z(_gжzx‹ ТџHRйР?\olCВJ№*h№Мн4˜Яeм4вEў@јr_нђ‘ЩkoХъ7rж)DэDЂ‘оБ‡Ч7Žе ЇЊYџaSјZй—ШёмЅТ5ёiшечХClˆš gйОЮ{в6sdђ/jЦрЄѓ6kr…ъmfииy‘ќЌгoшPЉRpэЩш›лaХ!ѕ›§?+№ЏВЁEѕ­…KќЩq8АЮuwšяwЂ И]пB…№žЇ]ъyŒ 3K'ьI“aмЭїѓ1ВэъуЩз%6ФЧZv”іЬИzYDЎ^ч}Мƒ;г.Џм9. ’я6ўкжd*tѓгс—6Z™K„=ZЬQ mјkгУБ{Нѕ0ZаFЊЪўвc+GПю..3 ћZЇф БeяЖ;–І8Siх>{юх˜щcЦџ"п”ВOД†єH„{uJи?e йЫRреIљŽвaEІŸщ[щ aѓ†йљ%ЌЉВЙu—ЋвЇvT))PяM0t…?^Бv’ІцQzЛ–цг?m#8Й@Dђ„‘‡HжC–”іёZOHP‰rbu@L-нлщлh” МŽтќŽ€Х-s'ŸsјrЃА%zm‹БЄgœПедняог+њBб%lЋѕЈ‹aV ВаАGО%Ч›“$…† dz(Ž^.РЕ3—Ы—@УЏД/xѕ›™<ŠіD‘з=FНВдMБ#~#5•_Я…х}ё\эЁy9ШЩЗn€}пq•Qea/iU]сЏ=Z2Пўxr(/жШАˆЈh~L‹ШЗW—bіЧ[vОщw6И—ЄТšœЄ’Жi‰Фт‰ЯJо’’YuюэУШQ№ѓ-zƒЊˆЎ0їŒдАJЌбРЉ•j€JхџB“њњžгDМЛђ9Ф<Ж ЭYЯЌ>bН‹*R,Ф}`Ддћ’ДKМ‚oЁМžКа­~ж‡GњЉлыŠUг­8gA—Ы(Sђ˜ёuе CBћЋпГŒ v„рк–Х=ytшo]z +х§В‘њК+–НmЪ0ъ}їДЧS~лn(hwcжЂ и§TFqx l#фXыf6 ЏьB…U#p_YPЊЩЕcj˜0­њtЛ \ЁМxЮ|do=EК5‚Іл—RЕuФ>уХљМ•qе33Tt†N"{y>ыCЉэgиі}ЧX{X8ŒPѓq Зющ"Оч›­ZЉKњ?‡Сћ/Вае Г пJ\t‰J*0nƒsч;Ђ#ірлœ№(ТN(;Щ'§œЙпUxа9ЏP?АЬBяє 3PR€l3€№.k­,u$№*JІqG_–э_ЯeПe:ФBев Їdg\Іœ–ЛžІЩц:l1œ;ЕRу[Ђ#е:2…o^ЮY=ОцŒ_RфЧя>bнуoK \АлNКж }ВЇ•Омd†џbc‹4В"xNхuY Кz9 j4ѕ[ЖЅaиТвЧ5ŠЉІKƒЧяxŒэЋevцгЈ=л gх$( яЊЧјЉёКи–‚f+*ЛЃPЛ—ŒЈн ф™‘ќИјі•OŽš0"НZоЎƒFГ’ІіЖ­Ёџ@ЃО…яjъ†д˜ЕЉR]Џ‡(яŸ1ьЩКˆЁ№”I‚|ХsрšъCШ%OC T)Ш–Её™aФ–Q/1Ћю )Їкrdžы KBюK =Tkс52`:“ЯCI>šй-ќ|МgЙњ Н œЅ(є]JOНAŸTе–ЯЦVІ:HLЄЪфTјƒЎсШ!m3y,9­0XљcXфНО,Ди$7дšWI%THЕӘЫйCuF№–@ъ4ОЪOушКok”)WXжЇлЕsŠжз’ˆЖmФгЪ5K‰$oФе)кШzрл_fЦ.=џ.ТИ@Х‘ѕX ЏЛаь-:G\R––ˆЧуСАВ-ИЬ8Юs0vKsЌ‚ж‚f35Gџ]8­аЩќƒJX—љјmФŠ‘iЩhNƒu‹вiнЏсŠ,”УzCрз6gзcеї•ˆdљМўG?в&$Šє#m ŒtKљЕЇzсiоЛ$Ёкь1œЎ]Ќн _’зAXЄ І№\ьк-4МЅnЃЋ>џ0Ь‘/ёŽSF­ф*мЇа„R8ŸtЎЗњЕЊ3М\YaЩЗЊgЈ!ЮaћќšsСхG3 cЗtŸ#"‰n—”*ЪNГ#J…Яw‚фRsalЦ'?lr­О&ŸВќGћтў §шSЉд&Чз„)T=•њтЦiГ‹sв+s[фSnБUj:IqЩ€ йНZf…М€†jRб†gDЛФ‘С ЦЬ+žЪŒM$ЫнCŠццљљ„f‡m|nžЕЭы’шКЁ tЪрЩ+&X нрРЯT№ДAJЌ"!]РO?!f{Н@PЖoуž‘3О№8Эч^2Ѓ9їЊ† C–іЎIЄжbL „аhЖ­МnU“ †‹Šc@ЉeимInђњ, 쉈S˜Wнїэgclй(Z1­E‹о/ђ8'шмЩœї2Ј{и’лћі B›ЦОіfЎZьœЗDЄ!@§LhЛ)(Е§ы{„ЇяУЃр ДЏ*оŠfЂъЛ1 ЙMжзАљ1rv­%3Š‡Ъ№,ЦM=ђЖтƒЃNТ’‰R  ё[-О*œвЅ€nQp<км7ц,x?ќ–‰ZбЅН,кнч9‰пЅŒ‰ьЬt}zђ7(3щ{Јrzд 4{eEёs~“…N /јъ šxYУЏВЇ—„Ž+њѕuŒрx>}єЮтmћЉ(4ЉšЭ 4= хўб(ѕ'dЬХq-Њaђt6E6П,С",t>љJж‹ љц—BЕх‚Ю^р"ЧНБQ№VПТбЛ#уЮQјu‘’ыVЌSбWЛ1Њ„Љ\њє…>AZAЅNcЖдIщрПm’žЈN ЪдДыyЏ3ЙЋ$6y’ђqЅЌ7ŽdЛ’ `$ZиU ~^UЗХчŸоwЃ™ўЈvкŒТˆіЦgЉ:T*zPЄ{Щ+/щ{п 6C @КПё€\!ŸGІ<-ЄЈ'м™!ЉЉоћєь2пN‰ѕ •'дЮЙйEшјHN^ЎЅR=хTо+юХ™юХpŸЦ7!оD­ЮX‹~NЎ ЧyQw`€рњ@:Йј„еЗy#ЌКˆ`eІŠУеи§kічџu=џYЈ^tРшЅл‰J•ЛŒ‡1w“ЬЉ+ьЏЪйс&]єВ@žШ]єзc1@кACчjQв†"ХнxvЦЂ…ФЪuŽ4}nелчkя€–v>™Ђ>…$3ГfпK›]–Vœ“ћ“+Щ ьfn6PдF:ќУЪЈЖцђ)ŠЅ#~pЊhƒŽ}LВd.L+i\Вћe6еЅk8 нx’юг6.н‹ЇžБSРs>фYўЧн ІЈDт=3ётфX:iЂЪбŸ9z,ЄW‡щжВД+вїJ8G#UеТЌqI7vsB %s5Mж?ІuxŒ]З{ЛЉvЎиˆИ(ФвI,fuї№C6>‚Fj™ƒK›ОеTб§БѓшШ†єь3кыуЙscBžHzR=eЊбIžPЊ”ГЖВў=^šy™чЌVХч(у[‹PПT)iЏŽХ›V‘билq.”ЙjАUсMќШ… н У@ц›Ч‹%€SWHЎЃќЇ–XHŠ}}8хлЙС+R`Œнуht4i,ЃбIн"№ <žp–ї'ќ"z8†і+еѕ1УД^e€ 7вРЉ2цЅцeЇћ [Mѕ0€ˆIтЃкКuЕБ†_ь’ая=кЇUTЮcфfїџz Їка 3 ­ъšKЎx{ ZAI ’gРУсЮтr,ГЧыC,ЊSJ|—^м РТpЌс%+№" х ЁчЮІ%&Wcs­ZE%[NЙ™Q^UŽњN ј6™ЕЁ @)фJnлТЊЏжL%ЧЫЦV wlщe+Ёb€@ђ|ЁLфМH ПfЭtФпЌиT_цћ…`3uyж"ДI™NнЉФ›5,ѓсk#чрwuю’Єт ўЬg Сд%Њ5эNц>]/Л@lЌ•ЌдF—Гу]Ћ0hN(ў%ѓ}феŽ˜sCќКМiяŸUKСЂƒˆ мlœїДШo478иPNš ]Таn–Вт№КШbЅJtfлcгМpzЪ Цжg>тq.h•­WЋ^дјЦ‚Ў]ЂІС”1ЦВsмdhzR“4+Ќмj($yфuU‡ є=њ0Ч)в KŸ6-›ђ…”gЖїк™xsf!FьЈОжсBФŸЫ;™“Шs^cнЕЧІyžжHwЏ<сƒЙсcc9jZхТL6ŽG`ІyЬщ[О.z„›…4Ч1Ё]%А"бРxЏХФ9aЌ nGЬ&џl‡iЎN–!ю­ZeЅТ<њc u ZбSжKSЩyЇЁщlwАЫ9ЧЃžЯЅЧg‚}šHWЭ”~GŸˆгL2ж01kdTнљЮ=‘o@§Га"тв6(ƒŸ™Pл„€0Lуџйic09э5 jP ‡ ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cџOџQ2џR џ\ PXX`XX`XX`XXXPPXџdKakadu-v5.2.1џ ьHџ“ЯУBxхšйŸћўўлM9Ж—„Ÿ"W№Ъ-€DmЅљ6-Бхoa.>5WgлцAЫŠŸRq^:зБŸDщ)}КдЄ‰.OрЉO)ЂХЛЕАШ@ІPЕјъd ˜uХЩ›UЧA*ћ|;1RЭ7щБ™*џ<).дж•sш8xI'lz8 §3^ћ\нyU*pоПk&mQ”N4ЕoI•hтДўіCD–Я"YГєDЇŠ?ЙЫO_ЁЊ$еЭу`­И4ЎпfJ€ ‘э)UshуЃ”ƒХuМSК'd“ЇcЊ]ныГп€yИ{§В­k+ЃЖЗvїnЊќ_\tѓ‰A[Ћ”ʘЯРќ›vц? пHЎ"?Їœ‰й • %ЮЦZрВчJ’lq‘ѕоЫhЭќЗѕђuOјгцу Э@Г]DU&\ЯР№Ѕ‡;1L=~ЭЪ:4Y4ГЙБхbR>гС,žк}•œЁГЇižэžЦМ`зэB‚ХЌТ˜4ѓqњЃSTк…ЯТч т$]otrN8 ю>К„gn›€&н^йЗƒыт‚Й–<M6 'qЃр\‚пї$ЂХ“Ž%ЋлЖI,^hн‘$ЊовjˆжY’Ћ˜J:LЊ+fgm†C\ЃД­/ОUуЎВЯ,F!аzѓжWьwvуgДўViЛ 4 ‰ЏГШ ?їc!U^0­$Н`TЩTcЋЊ5U‰•Пh ‘=ѕЮЗ–}a]ЫЖ№UTеbL|к€ИРезdЙkcЬ`ŽЪNѕf|]#|яряы2ƒўШ…kœBУ­Ц.rШјтТЧсlGсuУ№ЗvьмiЛ:LщЖ0qŽ|ў‘VёИкС+NСГšЛПzЮў‹ЄAEи8d}\ИР. ?ЏŒцТ™З 5<іХ/*\3hІ4‡–]„РКсњˆšЖdm~АІЈCРЁQгј9Іб•O„iБLiВV№щjs ЇEг `В-”‡jŸ|ЁЁzc{x†љVбƒm)] aeœ Њ†cйLћN%šТA‰ИnП™˜–Ј-'`Š15SŒa5Ху`єœRЎш§6&ьHtkClИџU>0;Sъ„[;еU ),Cћzх•h;#Џ`MХZх—ѓ2О АП дјXлrяpUQ9БочMиыN”Ђe З4E€ц=—` M6ЋЂ.%oя“g-€жKpmНЄ$Ъс˜yiЛн9Ъ6KќBЌђВ\/6cіѕ:уЗ1K‡В;г_0Nр†~xа^“y€KР›ЗqБa>jЋсьП/1лРNчwУЭЭDгИ(ЅкУэF‡ккšœФ;щ?ЖпiЌ.MqZHяLY—ИŽ4yжMљѓўЎpк^ю”Т@‰žiчзš6Ну~і{‰сџpВ_48эcЫŸPнЅџƒ‚xLсT­Uуgю3ќЁхђZИц ШFгмЪЉbn›ˆfJдWрXi€‚HЉКbhntYсqŸJ$ф~Г\?5wšЅрЃ.я:НФ(oЎСЩ3о’іIܘЖи\ЭЦCo}ъі4 ‡ыЬ– ]HУћ‰kБЇLё­'8bFѕс(Є-Й7Тћ2ˆvУэAƒъ8ƒэBœг›у}\ :ˆ”nЌП;ЪЉ!о+ХLRX›ь1šЂЯАїКЊ’,4)иqЕlэT7˜MвЧЩWHЅ˜P€Ъмн3ЉЅpDk&з_eH(C*k’х]щн4ч1{OF–’HЗ?шр еэИжE|в 4’ШiгјМ<3ф…šІgipўрЃ(Ž+N9іVЧ(BУЕ56HX&“=lRЁ6•6B4ЭkЂ_ .Чuё?BІ#ŠeЋя)Ѕ…`ЧсHOЮ‹‡рќ*eц‡Ї 1ћƒw žъд:ЕЮB\ЖƒўщTвsrцƒ‚јE†€ЅsБ02ЙBŒUb“ЙЈ?BІКUNŽc-Л–`єИi!ѓztН™Tпъ*яІ3ф&ЈЛvP аBiŠŒKHВTCщ ІoО$›№] ~ŒѓCЩWI!ЉЬzƒAП:“>OZэ[MІђ9у`ŸЛyŸ sнОY$)˜ŸРЦ#'иj]ДЏ>G› YќъG#@ƒiэŠуiФUќJmО RgЙЇЧO‘чкщГ §мn_ќ@Ч)#"яЙCйŒМ@ШЖдяћс$Nz=<(:лyСв"[{ Ё№бњєаўЂ[eп*›WЊdQР}ЛвX}їДзжШ71!­ѓцiчщ“V‰]+VћЈумЩ;Љт2Uя zVL§o)Ѕg”"ѓxкЬУ№žѕ! ЋшVqк<їзѕkе; eэрзмnˆžŽб‰\ ЖЄљvЮ– ^CтОг=ј ВђlѓЦЙ?О‘нрУЖAš }ЧLlќBТCћ(щЯЯ­шќ;ЯЎ@нйиbx*УžНŸТ˜к‰ЙYЅŽЋNoЛneOдЖS˜}ЉM^йп#lъмэІяёД VZЛEО-+ЈN˜ЂёCyrвК=NїUчр(ž.ш„@jОФ<ѓђƒєю”0•‡‡аШf˜гюA ж ћ}ёњu{ƒ]ќВ'ъэ–ы5}юйў#ZA"ф;™-1ik“С`ИсяЩЇ_н'XЧQъЬДLИn‚,еБWИЬйbЯ–Iэk‹ˆыБ< Жг?O ќQШ)@RЉ тT?„ц%И;ШЗVХгтalЊјˆžЮz3\чы]ЬиUнЕ™"ˆвP‘щЇгS81/йж8ШѓЫ7—IQФa3ЊЗДа‘bSщќОeС џ_}yp‡№e,qхЏїчT&“W‚ЬЈoР"6ѓЅ˜Ах‡CH˜ZqˆTЏЋ–фЎш^=џ(IКŒQш—:ДТХљ§E7ћW…ЏPба*A.iЧЏaY^ ьЉ[‘ТO]Ж#чЮptOGДиŒR‚яэa&Уъ—k9?S†ТМбnЕЃєы‰‰m‰Нс–€/7ЅjЃcбяh†7ѓэНIVефX LЪ”Dg- ѕЪЗзœ‰_kl”y*•cС9т:Žё"œЗОс:uШ S6cщ]хЛУ„Т›кHо)LЊ"Ќž|HаТрIF6y ’5ZSuгЭž`˜vŒ•oŒЩэxˆ№РВЊЋsЄ8ФJaL#&0ЦZП]ёкIАэ‚љЄNПyЭИcWMˆ пt š !Ж Р!џЦЂШ`Єpщnˆ№г€Œuц ХŠЂ6Й"-ЯБJ]Э!!тLTЭ54N,Z†эɘnёэC"zCGЮФњ*•9uю˜”ЈАЂ’qъЏСѓasЃЖЩ>|я$zС‹Д0JoЃI=жйŒЏ#~ОцЏ•i[ў| œТўЕъw&8ЁТ_Дмё{do_АLФK57ЙСHш˜~(џ=бЩЅ ы2šf…‘8š†ˆЂДŒЇЋсџUCB8ЉЗ‚Щ:Šj™z€\jh"f!ЂC—Кп[]ЋбЯRЮpывЅj}2!ё~bЩЪј‡Ž‹кs№Ш0УЎ…м™e ;”Юljс4Ќт­J1ѕ)Є!0ŽStXвяsŠk`Ф†w>й]1ц—7?#eэЗ3b*­˜0БЇGыО“&5zƒ,–uOїm I†3Ю§уJFOw}ЗkzЂqёЃ=n­”^Юьу> ЌЦŽ~3JœЕ?§РФ3›м#|AŸTIˆаћA§бr$ТтЄ{†љP­4т“ I—PnнiW5z†}шfшKш еZМlдWЄ6tXCc0іЌšЉЉњ@Й'ЛsКU<”’O CЏЫЏчъџN=†ГзЂQЊ^чфСТuъžKБ„mѕ Ї­є1’жЄŽ)6Œ‰ДщHј89т–z2›Вт9Робц^ьWF)нЂ(Й/%Œ&Їm§N{=”ѕ/wцдцx,бН4ьjgО6&Œ|Ї[ЃuUJП-НЇЅйЁnMDгПщќt‘354{:†d5cЂьЩпПсЭLєPљ™ъі“ктЬšZoщU2‡Vв€ЋђЋ†д'VЅq—55AЏЩU/yИ№І}ƒˆЯн™SЋbuюМыВV˜Tў+f$[жХ;%ЂШцК4~§6"AїЮ:Gдфб#а‘`‰Ут>4ы3T—ќ(OaЕ`vаv,‡шО€v|Щ œќpпKvѕ_LГOvЖц(sdU™œѕР•м Џ'(H:ŽлcJЁзРТЇqј”‘vЗšаФ>ѕХ%T/ЊЖаЧ,_;O%=H§ЭЃksbLs‰l Эц1щкmJжœй]іўrmМ lЈWЂ> вЎqPЊк”ЂдvртПpšц1•Ђ‹фЏo&gТЖъš–ёY•ЇAЉЂg‹z_|ЇоІŒYенvяу‚ФчХЏ_Ьѓ*$tŽ FWјш“Ёљџ`5q3W7GsјЫŸД–}\,NcЭ”›‘ŠрuЮ’š &Й7  X,АxkE віДYRт0YA– h SѓQOS ЛGКў Mѓo%‡oQo\d?oWЮ„C!Œмc•ыpSќпVЮЪ<тJЩЙШ‰пm{Лы7ЅоЩƒ§ НNxК$Ю!'8Nѓцfю35DЯЬИwrUU™йKЩ‰NШI Шџ&діѓ‚‹‚FVђVђ ƒx$ъzlџWtАœхUBЈј‚ДВ7фM&ЩрЫ*Њ К] јјЈЎфЙв0Д(9?1†Њ˜' ѕ2РЫЈ1‚№Hј@~нлƒЧ6б7уЉэ§UАЭœ7ŽEqќй|Iгb}x‡-2еhЙСЊ2˜0ЈѕИž“mš€$@ПќRSг7ЗVKY9аоБyпФХа/`Š‰ЯђEњ’Vy&G[кдbи]\|М~ єуУэЎЁіз0}ЖдtŒ•Ž­Гьљал:ТШЎ v5}еЅЦbИП9PЇЩ>o”]nь$FИR’Ы AWёJсrЭзOƒNНЬœтэЄЇЕсNљ„№AI}тВ%ЖšЩѓ•ю#:ўaФ :ІЅтx)'SѕЖš6ічм{>ЕБўGR8.ћ€ˆхX–KрQъпƒдйЂюZА„QьHšТu;zоћEŽ[›Šљ дјœ$QPL’шњБrВ‘О-рyPP[§њlzL’œЙаќЮЊ БеuHѕ‚жЁ.м uH /Ѕ™T…9d…da0Ѕ2R-Žа•NСЧи:{0MyТ]{вOЎƒr€‚ЮЏ{э„ и;=а&{ЬŸуЧЂMžФ„›ВI™§"(ьg„%-Šcв J|ЅтcКћšюИьъ`yГђU‚Лa2WГ6оГ&М§1щгX@§'ю В[ШЗї2ФŠŒ…САУед8AŒч†НOEЎљ!V '2іЋž›wpЖžРФ6™p6=жЧ ЖцЛOЦтŸMmн\Ѕ™- †ŒФіU“Рќчч/с4тm_ВНш†Ђы4“‡*Oтї4,1оFoДR‹ŒоЋlж‡Y+;Lшв)ЕTЪ F6Ён` bы8зѕђЈнkWl:rGc(ђwеыЗу‰ѓ“Зg!j’R€hvЃ`ПwЦи<іsЄъL#6‘ y§yУ—ЧLКлУэІсіг}ДјдuLї]wn?AGl;žиgШ-ўЬ)M_›:јІcЏшЋw&єІыП,р‹@аœ2UуДлL]?Ў)Јs:ЩŸ ЄŽОІyZi ›3Lє^іMљ\†55Б8АlШpДОMxё‘гръw3Ў­uш›Iнс”‚j•дЬv9]д—ч(кx;`А…[іq^Ђрy^VБTm§pЩиЄ—.oд B Хя;W€CЛ[ЎC т‚ј%<дІ:ў‡|‘BOšЏz–˜Amињ$ё ЯMЮˆСњ›9вфПЃxKЃ~ѕГffаŸ& ЅL|јћл<zцUсџ&ЛЙцше@хu"№і­qЖТ™‰a/1ЌЪŠuё№їЄ‚~№'j|!TAуЫ[ZDќDЉн‹јЧK2:XWпУћвB’!bВЩЩР#З˜ЩѓС№“i'›ЫDYољюT PЩRСMJплwњEЅ7ЉЯБI;wˆavйєW[ސЬуiš+ЇРІÜuёУЗ/’JAЊwиЖ­.23,UиЦG% W%7nъс˜ šС`ЅI{#Š$;Bа|qЛЮЋšC“ё^й`фољ”OЯЯNу№вИќєXн[ъm]Щ}hЏ6}‘ТtђўЎSeyњzЉУ%ЃЁŽZIуžKХ^“XЛі “§Ыc:UdіІђпˆк[UпЃWЦAnА‘тЮЌ П:К‡9š IЫиДѓ§O%)LИ8в mSзќ­u63[+ГЫ­u”ѕTŒсЁьSŒ',нcВЈеyыtЈrƒN ‹/Wб—pвRˆј! r“ш5(ыJЅ$Г& Ї7дch[ыL@VФ н6ЪWlœjЫб•„Ž~*œЎТН.ћЁб/ГыуGN1уЮo„РAЌфќd_нhЧŸaњвЌкЛчрœХ}S)—+МЗ‹ђ*ч6F!бдM!ІŒхаsџж&ц f GTш?TNя­l%Є ‡P Q+Тyє+pОxb?M №тє8<ŸрxŽz@qŠz(зDU}yц ШX_MmїРŸ е$аЬ›%uўУЋРB gMЕыгˆ_і§ nЛ^lЃTѓ~ ЖmЕ&ш+iЎ*uщfcъ!ZŒбFˆ%*\š}`оWp6Š™ЋлиЈПI!"qЗщ-z@™‰ ЂЪ(›-ЕЭўШрЉрЉќ\wЎО—#(ƒЮдиО^[нЇo!•%!‡зˆ›ФСФmiЖ“Я}™œЯ'ПвМёYГsn}фhHюџ`\ЎWщ˜омAбСк‘П EkПѕКŒ—еSouй0” Ьk›GЛЎХ]ЁЬзјйжЬLЗNчЬОj_[ oц‹џZyhєœz[* ›ОUbЏ'Ўюжв”WТЃЧЭєЩ?"h:гŒ|`Б6!ЫЌN,!пsOџЖЙAѓ<БFЊн%]“кxЙ8&ЫуH{ž)k;№<ф_еTЌб |c6.ЩF9-~tZЂbUДиikћD1ЖшСъАЬ%•L~2Цъ9АXЃГ+lxЩf„Н… [ž6XЙ6~8†E§8БЌ<=ЄдрzxaRПаV‰YŠзї8LпвdsQю€JМ*_џ!Ъwќа{‰фПŸaŒёйfыК ~(cЈœ$яUх:щ69ј/АІ4MбЙBUм‘гцDв  pЧџ`бrКI†=з]–Ћ^1›K`UoоŒoЖѓ™ИyБЋoЗk+Зщ™ЄН›UЌ’ ЈЄz#!RЈ„­UbїWђл<Ю2 “‹pЈхлuFР”I9; И№йНŒ лV˜VM ХxxэYЯЃK!k…ъгм;ˆІ“зtЖџаўyЏOT QА,ЋКЌЊ.ий’:"К[а[/{zbъ jЏјКЏ:ЭСeцЊњE №ˆAѕаyfe…ж„:ц‹ідЫмh Вy фЧSЉфtмœ ГЙ1\ь;2%‚ЗlпШю9:ПгNљОц@f у5чvсїЈ‹D {н=Н}˜›0ѓzЧ•A$˜zюь€['Ђ[*ŒN‰ЛЪа0ўŸєјр\ЌŸСp‡9ŽЦƒёчvЙXв@y’yCn]щŠ<Ё@›8жGХPі8мˆ.ŸСЈvК|ЁЄ§№р —‘Жцг<є…№М^%jMЙј„CП\бmOІ#м_VНО+о­UVNGЩћcdHyЭЉ!œИYwо>флЌOщ“p.vVЂ œ–\ў’pЛLчЫnхрn–B]ЮЗЙfQlєN§Uw:D~Іђ2%†ъE"EukbР/lќ)юљюWТЖ–Ю…ŸмщRмЮЁы]ЎЇЌЄ ссЉїг2ўN^‚еѓДN3UЛ!L4ЂQYИ18Š1F™я%ММƒf:Њ]дјыћG2kŒXPЮВи Іє:Œя@Ц&L–йm#|' ЈwМЪSŸЁЁВІк ;ІDуњА}8k%…й|ГбвЇGL…_Фuќ(м6!lиD. šгЭ]‘HР§9KЅ\ЈПыCђi—јт&юПMdЇ(Cœ5џХ)0o9Њ6œщШuѕD/ђ„gіƒ.ю+Xšіиљ€Жѓ{йf'Я?о‹! ХШоTъ'•Јƒъ(сqgDЊ4вU“hmЛ-&Я‘эlˆtœќЈћЫуб_(-ІѕuJшЫѕиЖ „ЉфУpbЬЯ&ЌFЖИ([тRу№QУкD>,ћмIŒ6wˆW? еш”uh0 №nBС“ОЮ_юcb\C:-бИж$ЄAЖLOЫо|2 ЭЉŒ/ -ЅXxЮ ЃТ 5žCLт]Фќ:љKеF Fx”eІ;'=XВ „\ЉЂqЅЮšК֘JsэLФ[Ў!Ѕа}tikGѕєЙt3t‰†ѓІ?R^9dPёшuЖщ—^Пe‰Я#m?Q‹/…8™ЇэY(<ЧU)СфСˆ^нCэо~yБ"д!%QЏƒТYnрSƒ,цо@БdхOЫ#л§ТЏ? +ъ,Тк‡ БЮбAМMa№ЄјуB.scю­›J@dїoТB-&%ЗOМ_‡c0шРš%~у;#FJxЪAГ*Ці5gI’,Qеѓ>Bџ % ћ/Сящ0рДў…П}сЉ#Є+С,ічKЮрqмfЇQ2—Ќ$3SЉ‚џK›w#WЦ&zиŽЉDіII "Љ —RD‹ЕІ9?WuHчqЪоЎОw‹ВƒшГъдGбioЦГЎYБO–ЖŸДСмQѕРхФ ЎŒї„џ#јFИŸyŒМjBрЩof'н_ЃѓEЇє>к4r$ВиBИDg"Ÿ-еU*ЛїS_еo ZЋiчЎ№щЏOWoX’LgВdЯщ4ЦB0p-аўwВ)])И‘і‚.†™:ІŒ Ÿ@–чЎC\w 'уьB"eЁkФ7Ra; юœlЂвoŽьАВ•‚dИќ_ Hvuђм>TБїa1f‰˜yБЋ=џ&щѓсgŽž”1Њ9˜Cќ-lтUFE‰Щ"ЧЧt}7ŸьoБ€ЭШа–жEv%ІЎw옼RbЬ•MёечGя^uћ\ТlЏvˆК57ђCЫPУ'Ѕ Z!ХF˜X4:{%YШNлgj3ЈWыšЙ,HєєЄg>︺٘ŠђёAJ$ѓ0QŠЄe60Н^єп ЦДёЫЄЌk…,`@}єшdцP….—Rg76#х 'ЯЋютŸŠ4кВ™w7iлв№[TўJ№%‡Už§ˆaХfуŸ;}Pѓю7уљ‡Ќ%жRћЭѓщ3Щ~EžHп.cW цRIЅѕ>— Нш^˜}™EЦ}Е$ ЌСчiыЉљОvщєђИF—xyРдsKƒ‹ЎЙRІЕ дКkІ\ЎEФг+рЩZ$,ŽgцыёЬц ;?ƒьsЕ4мPєК§w[’ћq3=‘%Є л‹~~‘ђ9 †@ZАŽ&[ЖО\A'ЉВџЯЏъД‘ЕеАџ"ш3ОšАдг§ЩёЮQюэЈ%К}еŠ+@eŠ3пЙSHšSљBCЏЃ†I›#Кі ŒpШгС:9n5еGsJwщ=h@~ЇПE,шjG’~Э;;/"ѕ?хЖx S*)ЈЫŽ %Є•ь“_Ѓ€€ иhMC!ЬœiKTЫ~еSи"  w,џ1QСsдАFъŒŠdŒЗўљ…ŽˆуC Рь+Lмэ” ~KоА  я ƒ­ќA†Ž…“Ь]ще NЌяšd78>†аўN6Г'8аЂ0ТEэ(њ>ƒрЫ™IZоцœпё4іkПbЏе р‚ž™NЄk6vЅЙD3мИn­Ѓ§ѕЌ›uF&5l…AmƒЮЫЅŒUfwfгЫ2ЮКfMS9…nШ.snЁ2№e›+ށZ[РYD˜!už4И\–сE„иK'ucЙŠ'=žъP‚w$Щai+/$івEbшДўUё\Q 4єПУyj3žРўп[уч'"ѕ* кo†v хFlk$9Šˆзeј'оjаЧ…˜‡A7žnŠуWUЇ{№ВЭ§*№Sео)jлЩzжlWw‚]!„Šu'l "mTОGи]ХJ7ЊѓOеpщдЙgєrЉ§2eы'КerТ оШ­ю?hђэУrвpŽЎŠэѓrЈeUЭLёжыЅp]џDД €рy&I+ЗмnжЌщv›TŒƒиB‡ЃПaєЖњФчќЁОwЂЄЉyж|lЖcЖe$Ј*7’чŒœ$€њrЂ“ПЕo“ьхœ™ƒ.“.Їœ(…g‹CѓHžJ№њ$,0h/ХЊ2-т G ‰й(ђ~* wJнВф*Фњкmmр+oœoŠЧЇГ_ё|Afжљšт]UdaбhЋpЅєКВ^SnН6~…ныЙa­Ъ%Бdъњ$5 €„ѓ Ws тзП;єьr#пь @:УЖЙНw #ћћŒў]šЅЄ„i‰ВlЁ9цсqaA,{tљМч щы\–й.%—цАГˆќбёяO+‰Ъкг яЫmRЋSњщ XR4Ѕ ‘4Ѕйѓ‘Ы7рІq†›xHIУерwЭФwэЅ2ЏКь‰ТБ7„жВУQ _W` ]ƒt{˜qвЉўƒgwЊ‘PY Ъ’ˆuŒ=} › |Q9ŽИг+cB‡ЃБ$ц옢v’У-эnYБzWH[ ;ъЅ 4а4‘emHc%щкtœсЅu:ЕЊwGєЦx‰(cкH&_Ќs’‡ о+ў rРXƒ ;гнЪjc0Хfžі–uїB˜–рD}”ЎРњ…‹§ЃЯ8sНлБƒМеокјЈЄdM њ‹\AhИ7f#™JŸ5юЛ­Œв[Сc8ХtcRшƒ‚Шˆ] 7У~ъшЃЉP3ёмјˆqŽЉПэ†иїMРН‡&Aе'№9,ќХ4sŸюBЕ8j‹d)аљ!ЫP;SoqGi[ѕхC<2m)‹ў nРУзФOWWwїь“Bос‘ж№эŸНШ~ћ#Z‘ZЌu/yЋїЂWyАђЊр`:НЯЦKYЙКx™#гkSN‡Н>пІсaмьЉ-Ѕ\n lh4Дœ`ЕѓНвѓбBш9ppŒб‰3АХšЗЧџsи_!lи АcИі-ё=Ž_е^y1Zй"Пфч”хЌ59-ѕŠЮ=ˆааM\з*aB_XПл'ЯXCІЂРвДœОжЕ!…?›Л„U[_”^kjЪс.чфИъсымŸŠYЦWхжaГљogD/х кЈМЈœѓ-‡В(њ=TЄМ Ѕ*hZR]UG‚ZЦМ0­\CГъўќ)іыšШУB1Ѕк~Jр5ЃЁћ&eИх~,ЭЁЁSB.Є-wЖYИŒ$_D.сцЏ%@~ЌІёGŒq іŠЄ/П…Тb"6Ž7чѓE*Ё|ЙмД~…€Є(i\Р Бˆ’V•шT:ЗŒ#ќ‘Юв(‹\шMдЏєJМВ[эЫœСшŽ-ЯШЉАOT=5T7КЄ˜œOSi!Р;ЉБka!Н–ё‹—рdЮVќќ:бS~c­zК ЗS|ДЩРдЛкИс…”bбQ™wѓ}Юw8пюїe? !хЉ&H ХK QІіx! x^"ЦlэЉI|?ДcaQQF—g|Ю"I/ЪЫ“ЬVВЦњшм‚d§Єй3вЦ/0ы<_Эš3Aч$У~њjѓ+ВЈђ6ЕБѕhyЦЇ вЎz– кЯoеJjБQhk‹ёУР|žŸ}މГЦУ ЙФјьŠА'йM*SВŽь|йЭмчPЛˆ Š?v,XWŽЯФ žЇ@6ч?I‰Бмk 3œKАpŒRцг O н?|9оаi‘'•gŠoжŸђ!МG)Ъп€м6Щ g=zG.†Tƒ&B vЭzsLRѓY_ihN O }Ы”b@Ж3!.`h:ўжg.ЖЮGoƒ-“СыŒшH‰N„ЃЌVљkЄф)О,Ћ=)ђ=Yс§ŸЖ^кЄкЫa™єHб&пШуэ™u3sПЮО{w ЩT;.|y !œя\ аiJwыHŸСА]ОŒЇSїЂСчД!шŸ ТNQžн0HYiИR;рFФЂ‘Цžма№-ž@&'ўNа+&щЫuКtј%ЄjБїiёџ€nйфЩЋљїюв‘HЙфіLn%%сCБяuCИ з;žЌF,UЌYkѓ—яu…шvЦ7` Fяw­ЭЅ9ЫxХ4ю;чМJЇ ыс<;u], Ь%;ЮЇfђg9фІŠ<gпb4X?%пЅbњЭ[EїNUQчпёя“Žb6чoгХ™эчКЛ§йІЦБ1РDп€вIЃп,Џу]ЁО94ѓЏеЗuЬZяїщОL‘SОѕЃXxЯмqNl?Ÿ.Ѓ eЄu'У{Cˆtє9IсzЄ:`џ І9Шф`г&HуВХмщЅХчbjoІvl­'_юхю4ЌњзяžеЃ‹^єЏKЮћrауžф,2фИ–іyeVНёЌЗPѓrє"nІX№Y У4! РРќ&t„uо„']ƒяљˆ@ .Tb­њšіяŽšЃнbР—-YЗ8I%yъ Žиїгnz”œ4…ИЅ;V:SzЖмP‰tlЋЧg|/x’ѓEƒіпХuЁЫ$!\ŒЏˆP$veL>ЋQEm}J№хІbЯF‡N†$Ё“>Hс,O`щБt(їг3OУ(ХtgІеь€вж 9KЋ•V u+)цшRшg9юЛ Jџ “йŸAфэ!лћНJьИpœ/УœАМ‡Б )jcи?ЬАјl’ŠJ“‚<’ЦЏзЕ%mqвsОЏTšХ iџwшЗšc%т˜fjяy\&7Ж‚rK€mцŸG‰йлЅYЦLРМP=ШЃ™ї!Џь§єЃl_ˆky3‰bM8mPC(k‡‘uL>.t›<Pv"d?Н9ŠCу:ƒФƒјХ~Л™Н§›Ё:ZЖV]nM+ЩHу_`ъ=oJЈЅэІ„\Ч@Aє5e8_Q •u.ЛŠљЁЋмтyСъKxZ*_Ž‚љДЛЦ/ЖћŒ~Tf;WŸdЮrE“` #eв”WPТR‚ќ'Q.‚ў3 HŠ0Х{И3w‘йГх „Ь•|>Ј—6bWHVEjжXd!Гt€zГ_кМІ1РР%ƒcm9C—Є,СO­ЎjмЪЧЇёT*ˆбіЖЙфх!ќcхеШлˆі{ЛŠі­РЇWВKя(FфV8Žz‡З…љ'Е х…РaтPФ5Ќ‘у;](іWŸв\ззђPwЧф7юћA8ѓc0чYёњ*/0ѕГВ. jEZu5‰УЎaо5,эvwъОќlѓђŽaœ[ŽьБ7Ј1ЄЁИ+–8ОZЈХ0Нќ%˜ WЫнѕ4WОЕiuŸІˆЕБ§ЮˆŒњ?Њв<ХTMШN_-&xЮэш˜е4шEѕmЮщг KЈ„дЃХф‘|єЎa$ѕhЬЂIa‹ђ~ЫoЉ:+\#&ї| шМЙSes“"HН№А~„ФмŒоk(r"сЮe'ŠЖв8мс[Р p~яs,8:АЙW7x~‘j§j)'B…С№<­yДЂЁnmkЦЪ:ЌmJЪЋK(9€п>-Ÿ>Чв+i‘оОPљ?yЫЪ‹ѕX–ЂКPТU6ЮАљF”c/бЂ4†ШŠ@УЭИћIz<) ž—sМрн1ър6вPTKщA bj†н*Ь”}ЂЃжИоtЭqФрƒ*GЖЃ:Й0бџUљkZПЬ_ ЦRІ€k№лцЬо†сЁаќСlЊЬў›&…y/ўЕеMfzТ™šy”ѓ:„Г1ђˆUЅ“K4—ёІ-raт “ЃЪ™КЄn`nчЕ_#+’Ы mWИv˜qгšОьzмyq;ч'г ž‚옳fOЮ/ЫцДЋЈч(iп+ћМЦ$Џ_бE%Œ45З‚Ы§.:ЮyC§АК:ЂЋ‹–ѕрЗОчQъ§qЗfˆ^‹ЋЭгщ1žїŽЛ›”CvXК;ЂNТГќwg&кшП#{SКCMГ‰GЈ M&Vгƒг=ТI4Abz?Иf9ф–fŒЫЕgsœ•ЁpёЩаѓaWЉ6Єрˆxўр§пhHjЗaлžЃЯщh:'ЌЖЗсѕсu>ЮЫЉtZ›МDИFѕ ЊќЮŸ ЫMнŠЈŸ:ЮYvИЦћ3[›ЖC2Вєƒ,qŽ{э,$hTБ'Ю•ПЃРzP}pыvˆљЏ3ец_ юЄ)9>чї†X У‡0PсŠ[шNNр zУЩyМ$"*b­Іh@—dkк6ВЎ1mвж*[LжP8дXh2-”‹6у/ 'OhьDЯVп~dcрc2Щй)kуPw2ZuжРЮѓ)6`ёЬРG=иЦSњŒkћOEc\$ћT/-зŠ‹ѓ§ .Єс'‚nЕЧиЉ”жjoЛёУPCљv)МО\P<ВЗ­pдВR86Ъ4[n}H85.§ЂUхѓџ}0Rљ…fNюHШedЏЯ|ЛУэк}Л'лЖ€ѕР—гяl*ЦKЩ'ђ(fл‰aЇТluсNЛїЈkDд‚(МтТv–L МŸ@ h№ќYцљў€Ц‡ пJљŠЭ)i7HƒSє‰_ѓ6ЪКЉ6PmїчsЁЦ }№юўбU}ŸС; ?‘уoц6i}#;YŽQ'#Œіч-ќ™„фЁъh[­чл žˆЅ­KNњGФEъ)zмЏАˆ—7„ —]ф' #8Pљ_јѓ‰ƒй!§ ьфоЊkцˆmюэ%ЇЅЫmW 0zAŠ8‰ІЈэЛWє†ЈL! +цЋ:Н3%Иg@ЗёІц`ЫюHЊч„цxэ}ЧхŒЏєM™У'G ‘>yП7pžю,ЕССг@ nЙЁ~ŽИ„Fу /у/YОФsj8Y9XBQ}OВ@_3№=QеЧЈxђЋˆpуЙ С@\т8:{6Щc_hbžбƒбГU§`–nЕБѓ\…‡q 0eП&„‡зF ƒaяeыwэ?ѕ:}ЂžЌКЇ‚C§аM—Ючƒ^ /vѓk­Ž4mд”cAbхg рcЩХ~“:>|pJЁD"3?ЗБ$ћ вЫwмЏ.-џ ›_bєVЇОи.ЊˆъэSƒ}я­ Ќˆ1pS@цAаG2ЭfЌe,с™š}“АэNžn  СaлgA jж, E=X)ULвAап6ђцС Ёкc1нGпп›_Wя™Я"Ђд '3„w‚Kœ-хsё€х2зXт‹Yбƒвї„kgYыЕ—ЄДšцП4MђџXЈ‚Б’'ŽЕЊЁЖW2ќІ*<"З­H#Й 7ИК‹=]Ѕ{Rѕ6‚>‚’\‡:ћѓWCП4…vГЧѓ0&T…Ъ&уŠK…QЦх—Ы№п# ЙoоЊЭ[БјББСN1тkОфх.ѕЊS-OFZu_НП3au,B…№QЯ$Ќ–љ’бз шгсЋ€С’О )Ш@^ВФ›ќ~т' p]­ЦŠSЦoъЫ Е;ыЮЦPSн‚8влјgН{ЛT0˜ыBІ&Ј’гŒиЈAл'‘е| ѓaЅОу„љ b$?wšЮ=&=Уы-M#жТјїїЈhQ‘–ЏЏš}РАјСTдUЌŒ…42‡]бGЛsд!€Д_ВЛчR› ў†'cYlN˜ВKЫПшжЬќg&я†Ћ ™xOмRъHЩz“ˆ+q\w‚ЂбU р–ъ‹’МхЎNIГљ№ Œ~еќ6еЬкТGмб%q:ъЫF‡бP.^Ц^N5 љъџ[Q#yЗп§|нэцАK’­гwњ1[ЕQ^—Iвˆ,[?ЊT„Kя д#1Hws=LяVmINI.[’/Џ ЁQDY+˜'hfjсйЏH—Є^•Щќ,o]x<ДњЊmЋZи§w‹Qс@™хn…єiХф§#ілcЫ•д Ьƒ ш&SЃА{#O‡ќ–mxэ›=Aƒ3ф­|4Ј‰N`9ЌгЁ {#]Yь}СЧсгД~,C№шР3Œы’P_†тDнцл-ЬЎˆЉ}N‘`§|+Ž‹w?[‘‚љuxМ hkљsƒjžX7mџzW…љZ`]j<‚Z.рMГЅМчЧ bЧ"„ 4xѓ2Š„oкC§я‡DXPCи?2TЌЈoкхœ<_Зx8i4C”ѓ•Ž7щяmk5­ЈoCZ%N—кOоъйи“MkђMлnŽІєŠ„днІRйеСь|fџlnu†“ЦcЏly„ FloB тцѓќяP}“‘ћ‹ЇurК‚Ё. ЊЛœYѓЂ6ФeТи’˜ЁAC"ž‹6Ь№9яАKZŸ6Д.­5||hПNлр:WЊџв-Пa$РUдЅгЦФpгЦцыЭрaщT—ша=Ях1Ањ:б–чж,—їє^O5хџ0ѕ8?O же…!еуrЂŽ‹ЧzЭ_ЗJЩiGG#;%ц‹ tWьbнЧћ^ЬЁˆбXu‘K~хŸwМFЧь Чiиˆ!бюу*DY‡бЮ…Я<ИCаqŸЬ.ЅH#F•бШ`њ$:ѓ{=џ 2<ЭX…AСg;уG^–џoСNвдйСуrј ЛЩј@+'I~лBзK]#CђЗёЕ“ ЉнЖЋ–н‰ tЮт’zJФAyH@'"irВ­\#RщfІЯ—Ђ/›сЂСМЛJr6№”‡‰œTЛ№ ФMЊЊ2э#іб;С.}ТИћkБл17‹tђ<4ЊЊwWnV@Hп“MONcxѓ<дQ0rBWмjЬЌqт<qещoA$гc7Хчћnlш#Z\ьЉыИŠ}4Нџљ^qxћїпж]>“##ЩOГВ3›&іх _7pШЂyLГ‰Ъc Ž–ab'.š0Yё% AВѕn$IЅИ]1!9XВ—ЂR |Л1Иd=bТhНЋяеЅ ўF§џHТuбкАи<ZйRЎЋнWbUы5%Ц5Я>‡K—“вчr=З)~bўj– ѕ5cтг–JкгXbЋ іьи…С“ЯХ0ZС#ШїїЌBИOбg ƒьeњнKи­ўїc’йуnwћН8яŒйІЯkШCЪЃ8’$Яј9˜цFVlSўЌй‰щь‰<i™hRїAВгдЫUm$C`рXX €ьƒnrtЇAЩ§F юЂœqYdі@хOЕ•7#Ћ]{%t#зh[+:SЕGiыT˜г" хfя*!EъYjDЪєšлlЦZfсИ§§ђТЯP^yќВlрЎ>ЯЭ ї,™r0‹k)ѕ„ЊЙNк‘уъ `вЫрлkЋMзq0WјŽsл_Њ DK=ъЅYИ@иMa'd ›`Р…tŸш+–ЇOl]•#їJАЧФˆ{ГRJЁkэЌjš:—ЎhS^–иc”:r `М§ђЯд7ЭNчНЕjБ)„ъУќ ќkv0ЃэЌ‹1цо]Jˆ|+]Ыг„QСЁЈ4сliœU;x•” VћwќС8Kkы24щУeЕYgџ‚Й!амqcЋг_[‘ТЉ|}Ю+•ezEZэ OЖѕ%ї}тb1ь1шю$%тS…1wŸ ј\gr §,ЏѓУ_О^ўwЋое_ШDT&Й‡*Ÿ]^ddy^ШР_‘ с>7IРHЬ‚kЅž4С,Tщ*GZZM§і[ШjfТєСbбщTмЩvќъ<‘т=nV ђ~6lлшfь.XSw‡lкєXP/žCЌ\—ЋР_Жў3ПL)NЕzcŸЖ Ž2Яср=ScіxА(л‹љт&ЬЦXdж‡–FzК”Ѓ—z$*=у„ˆYЧ ќуck-™ PЩuѕе,4P+QЪ€3ЯЙ}#S;и)Vезkх‚* цWQŸ MфT№вЭ­ЊюЧ-8щЋј,"ћГDС/ЅN|Є*Šо/ЇщMТ!Є-…СzВ2_qфБQПКi>'ЉT^n­?м.­ш-ЊXуъѓЪ‡јГ‘ѕwqYП`џRЁЁŸюC{глSвМ: 7Щršb6ЦЪи(1v>Ъњ_u:d ‹^–›.nёДKЉ"е'œѓ ьЦН0e „їэн`l2 ~ГЛ,Зh„ЅйЇЌпЭvu0ƒ{ЃЎ$ѕБ–(ЄIžwІеєЩ)6ЅГ?х‘їГКџjЫršЭХо%…і2гm‚е€1Їp[ђч сКС~/ДшsСРW€jр…є|Мu|гŸшЦх ХaГїLœNУмхЗь’?}ГV“Ў^ƒО8Їh"|y?cЈТ,ХузМjІуј{bEпсє@џаХ—сэе~›їсєЄ?ЄГУиwјz сяФСŒo}zё\е Т\юйђ5œЫМ?gх4эiЃŠш8ЙаЌщŸхжпCSиЉщM–d6PFxKЧ^Ї8qЕяѕЬЋŠLGRnћо)ЏPmЭ›Жќ>ыяУ мЃFеVЏR~ЂŒ0d1‹К „xФ)_ШціW>тХš‘Ї]еЕы„6•њ~ЯuR| fхЫ €ХЁлekЉ>ЦZЛЖсСУˆn}ОpъlœGСГіGДƒћhž†Ъ(ЗbУx™ƒ–ћQ„|№е<№Ђ}Й‘5Pі\‰Л˜œ`ТмГbBЮ™Ђ‚Lе0Ќфм4§о}ОnjYˆЁиЎŽвNp;”ZE <ѓƒмœХ/ŽdиGD€гШmсY&лyшJ§Уј‡їфg„х,EЙлIœ–ГйцзˆpлJкДƒ”?А­ѕSИЃ<ОЫДбП‰Žx\тЪиZ5ЊзŒяiUyСhжг˜„@’™*EАœмVmL^30­fыњ0;SgfЩМгцQvБcн27B‰F†жB„"&]яр‘ZъяРT63ŠЕ@m:Шрня˜ŸAЇœх6X:1:ЭЅœKCЋс†q—œCЬџ AХŠ›vжг3TF№D—›d+жi’t:кš3gљ†FƒJ fтtRRXiV№…дЂ$uУUљД& AДЕ>вт=N3И:zk…Чr5Š@ІЯвOr \5егЗtљL$(uЩ*Qэbяƒёf[­Щ}&ќ‚T(јx{рЌxЉJбwРшСл&Н5к:0ˆfИ‚ЖЂWWž%fPbQKGiЋvrR-BЬhP^ЏTЌo(,__Ѕ”ДTB‰n5SхДШх`'^Ко=њXA/„*u3,ѕш]~E6ŸV;[3йРрj3|9Вќ.z[лSиО‰0–ћ@уY|Ўѓфщ#8IряГЮЮь№qMрKЂ>šg §xщЛaРх㋇ѓ0"Г€з4Ю’ kШјіЋ–XѕфиФњнУwАУVѓЙсГ…J1Ÿй?UpўвхГащіŽмх5sуЪPїxl•бхуЬŠSо˜ЊSLД}™з/]юр>0чєђЇѕЁтјŸіЙLq€БHŒ&mѕежšљп‰ОнŸч“Ь3u8&ЃTї—SЅe /\'дКО$BŸZjDБ^™\е7мыю:ЈsЩеE9oЛУz=ќ(яGtъom…˜‘й3e:Фс ЖЃ#Ї=`sћсGPкїQ3ВЙ]†Цњє—dў)пЂQ`#ддxIєЋгFTэš‘D їк*.yiШ-ЪG‘ЄЌьFЏј у/ч+яKH|rаГЯх{Ыߘ6}ƒ#'ЅЇЏ–Ў>Њ]ИљыЃVYŒF+‘:џtя+"сC^аDР•кЇ51œрc7sнlEњЛCXЇ78гzЙћсј З МЦzЄ‡ =ђпХH&?sЧС@сЁ3;iХ П‡‡#ё e4Єе\­гP+оњ‘|ЭOBАѕAк0*ЫfЕьdЉd˜N8њњОЈ$VY›ќŒvФ;шРЖfZl{є7x‚љя‘- џAОTВfЕЖќoU OЪ\/№мнX˜іeнжUŠEъŒ5чк*>Сœ<щю>biЭє„Є‚MmнЁ“X“p.№ePЅ1ю­RwТнs%R§YюZAqВЭеLаѓєiі№“сLwcmуœ8+TУ#;,eeљT!”А\г 5Ф\ыгlЄ“Љфl‹гHй†|$?ЧJНлдРžяuWИедASQAќ”С@ы;шъb*Ќ[ЫqFлџjœ{7MJtЗ'ЮыхdEы@€Ў‚i~*uЃЃQ#lАЊrŽ~‡Z “F­ЅИŸSЈЙ›Т†atƒO`ue+hќєф]гіƒgђѓ`пиsЩƒйЈ№D œ3ЇŽx ђы>žjфЯŠ9Ѕ1:RощЦ-зН–Г\xБ€­„o1||љdоžL,yуlL]ѓљЫ'Ј{qђ%rsхЉRй™бЈ*Цї!уЌ%зHћIђ№fƒ=ЉЯ‹]ВLПУЯnЧŠœbш„ѓн++r”к3ъЫYyя2І1џhGWп! AZgевФЙlЕЖ%VЉєУМЅьKYфЋ/|ЄUШuNЄы]о& wЃКЫ{CІ€J3•oъл,ь+оьїAншГуZXw‘ `7/`l,JЬмvf–зW#3[рЄмЙEїЎ2&љLtlсTDAžz™bc_†—рюК­7Л{B 3Ÿ&иэBJОfЃшўжˆ“[Д€‰zВ–РАœo‘НcЇBЦt8,ЗbUя2Ž ЁьЈCƒ=gn2VтЋЙLз(ѓжrСЩхњ~ ьл'Н;”роЄФ_юЙBUутЧd€]’дЎ‡B#2Р›КлњkЁЛдїяž”лšБЛ"U“xф=јBO/:єњёУˆ^ТWГЊl9Ф.Ё†Ž†мю9ГМ`ш "dK…[‡к™ЏYMkл.гka@rzD3ЩЬSнхл?f‘з–ўEЧsw˜3ѓ яEФЩд;ЊС‹иcw%””W™fБЂЪ‘;№ˆћиС у~ЋьFфГcХvЅЩг%ЖЖ€pШсУTО€7x|jыUъ…0 ’ПŸWКњpjG3mQЪПЂб•lв№ћh]SЯэЂМІХ\Еœ?Мˆ“ТvЭ^dj $ŽыEСi_* “$ЁЦƒ'S„Ёvaе8У.™]Й4яHфyФЎœNЋMIoшyЊ-$Рž‚šєђ§o…C@„^у˜.я5šv_Z™ ЛОГ%г§WHUњœ#ї9TH6t?џsRr1ўwФy\ Ю юCVуNxЪ'ђ‰€!C[Йj*U”бV[ЇU$У Ež&V{ђX=т[Я:‚“К.§t :o5ЉьКЌf‘{23Цž1ФЫђЕ>Ђ†”ПJJ vЂkнLwѓџhb.КХС/cо ™тцоH@b–9(‰ZтRd ф‚<\koе%ž з‡QЏVO†ŠuЏяћр“ћˆяB-ьр}ЇтЫ4џUКьЫ]ф†DI{м–ћ”|vЧыa-XRaОЋtAD‡ušЙQдё"я3 Š*ъwDLўfЮ‹х#hѕђwУS,By љLМœР E9ƒ˜ьё4€v‡љqѓ( ФпvЏЊ‘vЩпу$ЪUЮ:э>Jx №-ЃГЦK“щ'Р%g\щТŒЇOгЧяš цW%T(5рFўŸ–)(ŠУQхGЉrв”јп+Ю U‰ѕОі0ЕцFmAфљЇIШP„КСю‚ŸYN49@иw§ŽЫѓЋАмŽлtbjsМЏЏCфjО0ђ…dStс[qЧLЋk6HяќhKЯ?vкФ€Ыа4ЕHиI—Џ;LЇ|ЏrMЂ=р эа›Р†дEoЎъ€*’3о/*Ќжц2w>2|˜JŠѕрдУШfЩм\№ё&JpнŒPŒщm……UД Ц­ељЙft4utР­вП\SЦ•Ц%ћбB ]П'оч#Г• VKРWˆФшЧ‚•Uг“H^œ–o&yŒMDV}ќ…X-‘ˆUŠ4З‚ЂЭŸ=ЭЋGwфЇиЦХ.(oбMАY>иCLVšb›Ё›uВjFVГnš$у†оF%ы—Ц ~Йп(-аНžSфџ њѓkд•ЬCЌwoђфжQPjЪз aЋмКv€dнЯb.a…OWrLњ"ˆвЦи\и n$Я]‰ьN"d ч,ЃШHцљЖDЉpЩЖ Œё”—‘™Ђ+dy’ШnВžпq‚]\ тыЁ’>Ѕў”TYР`.N\эА\Уг-ёв!дпЮ OёћmжЄ Nъ&oОœ ­ШV б‚FXЛ fXН/‘‡tг>Юо]њ’АР№Ў#FjЦ ЉXŠRšшЋTЕ9Џнœb‰YгєЫ2(ЈэcK§™чрћС aј_2^рљsZJ&3т“#й6@tгnёЕіNsсЖфўІj ьТДНMwŠЈЇ™УTZBцЯж>! ‚уѕу№ЉП$мAћ6ЏИJйРАeх­‘В›3ќyЈ‚ЦЌбуЂќВ Уtcю@M\ лнKY]Шиј(Цr‡ЃƒksЇ.X?ВФ< ЌspАоC’ёn– IЮЈЉJžнy•зР??ДC,џmCБыЩ{D )K …Б мТЮCў;›7Ыr-MŒБшЫlƒЖЄЗЋ јКцЈхЕС‚с#gчjdwŒ}bu„'ђW5К’u3ЋJIFуqдC{?cБтЮЅl`ѓЗїЋЕ~XЭ8EВ`яњYЭiЩeоŸоц‹Љ(XxяЖ!М“7HМZ+ш,5Чќuбиz3amŽЙИŒэаBщЩ6˜o+№fЋTлГ#)9hUUžбpм‘Ё9Ћ#a2…ŒŒ;9ПxнA;ѓ`кD€q%4‘ыЉќЗМц1ОuНdo&ЁњтнніЕ– 4чjm[˜hАУŒl‹‰вsЏ1іеhфq­ж_Df)œ4&_?ЙЎЕ`%‰­ќ§,ЅВГ{YИ}i1]іѓЭ/ОFKhІ@`шŒд^Dпс"зpые3A=Й%XУŠ@48NЂяvњ'@E9˜sтПьєwhск„“/r]XЉ­ D›—ЬђЙ=іЉsŸыБЗjЇKS^Тї8Т`м0GщКЁЫDЃыgЖWйф$‰6z0ЮЯEЊwBмpa8Ѕ у–*Z<‘YЦџUўYZхu()ЕТ"ЛYZ2ХљrйобСч>8 ё4kЅЄ‹|џŒDОѓ #˜o'uВќуѓнH-ЦЕБ“рNB)„'Фд­Чkzšžо‰Dжя]{уЈч”аT‡д#ЏЛЖh’ТЋш< –О§y ,uјхZwЮV<Е‹ќы”œ…с.*ЈJŒЬВЂдћSiЩBйVЋ9р&зжЏѓ›F(–йЫ“ШціqŒЃкІшuiˆW~r9}ўКС1ŒРžЇиm …м „žUR$/œЄ5лeч“VŠB?ЎК+pyБО‡~Š1хд­]ЖЉƒАГzЗЄmmj `ў…ЙJТM\ž-bqЂ_Uљ­р)QСЭYЋŠQ•ƒeЋќВВFЩEŒFБ*ЯщСRњиsЙ†џ хС­K n‰с‡0a…XЉAР ‘Šq yК<Ї o‚Л$Lбf.dЃ*vAњШЋе—?LY„жF эhЮы№"­ЪЛџ")aИФ ŒвAЌтiИAfkнХЩJЦз7РГл%&m1bx$J'>:П$њХ4щ‹‚MBx"dХѕ` §|в6)ZЄэ8Ї§ДЉQ”Q{Ш^‘нŠЮБ)юЄЊ‹n!'Ьцг†ZЪ‹Xmxц-/&/Сэcсиж#…ЬpѕгG#\@СЌ)$ 9?šУ‘žQоїqoGˆД@мВў˜&zтb2MлІл \ ŽўгŸЩ;cт>ЯѓЇ› eь‰Bй>АђВdB4Q‘ЯVќP0% D“ёјй=n ГАŽцšЁЃРqmг{Y9lјGšg|ЃѓЉМЙMHmБИ"ЗЌTЩсФДfˆЕЩв]ўЕqюP#§Pфf—OєEЯЅ—ЬЇх2ѕŸ6Ј‹sх":фjШT€LЌМђПd‘уШ79LAёўщЖ#зКЮЙfеЖ2@?u†Й[ДХМ ѕ\f­Ё•B+‘ЧГр{їЫVА=‰–ЫeMИкЛ$Ї—яcбcу8є’Yržyд*ЎHн.›YBˆЂЃNЈŠ[A!рhip˜ќањ4ібgKKPА`Ѓ{/Q$књх_Cyfхшu,БФ]ќœОЂEЃЂy W?ЊЮ ИBbgии•7ЋTьв9:џb?A§х­НЮĘ1QCђфƒcГФ:`ќЗќц›Oі<ЏQЋi –†ОЃnO™ь2žЦџc 'Ь*T‡/-юЛ<˜—хP'КVX@З-ЯЁa—HЄ%2‚`б˜‹//Ш5Т™F|а4=—ьО&b~ѕs›йЄљёњQpReЪЉц:ОАvкЬ30}о)j pђbtN?d’i2N‰ ьˆУX”ћЉ $ю˜$ћяЁt $ш)‰ы…ДBl@sиp/ŒЄE‚йj™Ž+_ˆ"œшжж"0У-лŠUŠЏХцО} џ{§ббЯO™jЭ|о—SИэыbM[MDЊC{{ѕfpеђ9вJьb^Ъ2Єг6Og•БЮю|хoФћdžй№7{СMцщІџdЈ6`ЂXЪzВ– %žЅЖdSOegBШ7yЊLћЩћpвќa\3VHЙWЗОйКЄЇСsВЌVџdФРєЄѓ‰_j@тЅ$ s\žКф3щ{V+šљ€‚Е„ Kэ:кырLЇ­Ÿ›“2яў­xS_Iѓ:Aљ=ё•/—nгєaЎhй<lE[u3бф†МcО.ИJѓtuЗЛƒsŒх$љQк­X Ш8Џ8е-MkŒ(j!ы†ЙБсјPшЖ.И s@%єLž8Ѓaх­62<8/QŠKёЫаJМYчxЬ’BчКМ0їРриŸ’]‰„Йvi“]aБЊЏфюXЈДO|Б4 Š_>Xншљ$eш~hŽ­ЧЧp№:ЯŽў\гriЈ:Дcзj­э їMРkѓ+МЏбЪњsЛ • tŸ<~Ь„Фє0$‹] ”ЯкљLкЭ-QЃ‰ЊŸЋ:eСИпNн„ЬХWрDЩѕъьїXBгмЭžVнР^ьЉЯ•\šUюІкк№nE2yuЄЎB<эејЖK 9D›P/ю—Б!pљŸУцnЩ&U8!ь&)•зїшИCѕvx\С&IЖѕЄƒQќуЫХХЄŒ1Єд!XФ6'm5:УТвOу Гл5›”!Цљш3_ћb ѓ$џZU6ђпо*~ЖTЯћ˜иЖ< gЋNЫN€Qїh2€yi6m`ЋГ"fНйЊИ#cёкŠzЎК™’4хŸЌˆАлšІг9лЫ€:Іi€Ч$)1§dЊФџDН[жуYa‰Ц<Ѓ#j]nS’#тAzІВсї†у(єЊЯ!Wх™BuvЌkъя˜ž"ЮcВDАVu7мgгz#№En)Т E № Хл­•Ш4”ї#•МШыЯ[61–ж/ЮKЎб Œ=а#с… ZЊЄЅYФt4ŒЌ3’1ЫAyГкЃЫ›сC­azVƒ”Кќ –6мЎoаBд.TЃТ“!тѓэѕурЄ!­<ђKxH}Ћšн UдŒ<†ЗbебЁdі’bŸ4D/mоЊяesыїєК=ЙTшу[џEнйљrU–уЩ@Іѕёџ|щU џnЏМ:Йc jfwSГпЮW#Ьў*Ю5ќ/GЁ†ооЕ}’pЎ\)&p4яш‘VБ%Ш:cRŒY(‹$8yƒБ)_|>]Ђ:YFlХwё€™|2ŠЙъхPe‚Šƒl6аaUаy †wћъ[ч)CВЊwxЋућќ˜y\m(žѓ+МНцюй“Гпž8f§˜ ›ˆ_^ш—™ѓЛљ‘л‹‹’Фџnлl<|VЮЫжsC/" p+шx9hožkMJrаyве#\§юъњ™F(W3,9h+эИ|ˆ‰…ЦгиŠ;˜‹єдФЎЇ7Œ+љ8KjНY*ѕOЈхAя"o'qП:фЌuјьiЧс­g ёуж[, žŒ5иPСIƒlPф?М0DвД+пЏ‡-˜ЕђзЎ™§\­ЋЊiъD}BAU]Ф Z_Ўі№1ЯссЭЬФ‘2g Ц+еEvlOЭЁ%8&7‚ЫнOДтЂpу,N“Й8CRпp‹ф§ј@gфhQгŠPГœ}гFя5Ѓ|КnѕEЦ‚Ь€А8АJНЇЬŠфбAћ>^6ўвjЌ Ўрkџl&шЅЪНІ_‰Ќ{1,дЅТпm;pV\ђQpЋ>–нСRQ+aЃиMРплВТŒ;1-2TŸ fu† Щ3 уžх„šGNa­Ялgšcѓ§РSј*Э^%ІжVФоiчO­<Ќ†ЋЗр№UЉт+xб^–!zr3QYЖѕ<ГНLЅ TU­P‘'xpE‡ЏJ/шgE™ тˆfuš1ZѓўZЫg'w#'dЯ]^Yn0e?VQœЛ@_]ъУDњЖ˜…r– IнMЛёщbQосёџ1­K 2фћФ.9qд‰=­№"e ZЏТЊxв /E~6ё#ˆ%|Зƒ†ЯУ”ЙЏяlи†ŠХйіГН9П‡ fa~‡ЭєsћрЩЈ}ОЏVS/ПГUм!IЈЪ%0:Ё8Хњ$Щлdk\џ^/џ= оЁБЂѕž@Р‰Zібg(> ч<)UСЁt‡ЏлЮ ѕwЬј ktФ…1Rs1:W{Н‘п[ВVKZ\зФK%€ЮB…ЗU nd‰ŒOыjЋТю‚j­ЌuЧШ\}ЮT‹М.ДЦЉ'Žѓ-#rbB7ЁІРЎЮ'\5 ХW™ B.uHмѕД^о0#uкд–wж^ 7}Cu]ݘ[И"Р<т"ЩС ™zџ +`їиdіG>џ)*WCљCєcэ[‰eœІЁ№@н\— њJ’ЗжQ‚зO"› 'WЬ;2њmQn#HcФЃб‘cKДЂУШ'9‡sбƒŸе#ХM–q7Lъ!8Š#Jџ7gЊ™єЧ‚ќс,h§нЙФ&‡т™ 0в5~kћЏ/lџ2šЊЭДЮИBЩVТФ— кGNЙрŸКчPёn[єЪsPАс7ЬƒhЌc˜Ž&АНšФц†” œK?€яŽ8= ŸЃ+`ќm‰КТMvxnHDш/ё§sЪе$и@зс ї… ‰Ÿт •‹mJe’*”ЭšMlgЮЕЙ$€нк‹\Ћ”ёЦlЂ•€,Л?п;Ќ-5ѕ†1TКj’k[VсH—јin9наšIrЙЗWз@ЌoП 6сEнrч}Ы8Ж­ѓOЃ•’9СKsЙ›rcŽВbЬ јe#оhKA"дЃZЖ8fЋнѓUŒг"eЎ#ЙЕ"РKJNУщbўЊ1=юм hђл‘дЋЮй{~2NLжЃ`\люHЋфq_1 УтHЅЕЫžГƒPъі)*tЭˆuЮЦђЗY3Кх\@dСбћэЕ CеУьQTT–G&K z3+ЦЇСyШ*gVКi<jˆfФ“ ,cйО5Zx•I1žв­ŽжЮА@<ˆt)!тŒ„н_=–кАТzъЮоm\;‹мQpПЭЫХ1qЗ’”3+ЌŠV[ Еч46RЦ H+‚|W—Сe… ХіQCЙРИ5JWmB5ШoфДЂTšЃг 0ай#;v­В)QŠНg1ЭћšНБд@[ Р ЯыГŸѓixж0ŸСБ‡ž==L ЦЗы јЎЄНƒ2Тc`QkЧhЛ<Рfз„Є}]”ЮВJŽВˆ§TЄђe@IJ7…PaCўn-›’EЪщvr )†Зš­н]юЭоёФќ ^Eo"Ž ggР7†e чCЯьтэmШnаћqšБ…1•Y}т,Ф‚ЂПRcz^bB7 йŒ6ш{<бї?h?{Mu`ўЧ ўЋ‹&ЁћјгЈˆ2]pсптЂѕриZŸ~зы-@•аIж™еПяO ерЎXo~5ГПzРцe™ЉMOfёWЇ7ЯœA~˜H'§ёZ6zж”o‡ŒCмСsЯ9‡hя“{7)LВ‡-ЛУОˆжЉПBdPГі1љ(i_Hв^vЩ`ћ/0Ри2&лЯžЮЦK?зLgzк*’'^㇛Ÿя(FRЦЂ%CјƒIK>Ž ™ ]‘gў‰е7)сIgcv§аі_P`ЊчбЌ+oAНo1ё# RВZИЃ§2ЛО"Dч=~A’|”ђUЮ",јЇIƒ˜†їцаёЉ0А#ТŒэWбгЯъžьFс^ФRyЬЧhŽ|АпЕњ4ЯјЏ][љ’`ч\ чBUМШD^a– ‰нoOђžоВ•ВDЈЄђVіЊ5н1jЛ+фѕ3Ш…ba*-јРг,Г992Zљ—pE6іzћ‘hЅўЗЏwДЮmn,LlеtUМKbз”ЛцХ@НYŒ0ьп=ЫБѕ•яM[уSgсPqЧwїџX‘G5WJѕVžMтp+зPЧѕ^2Bg№б•-j*zі*ычЂЃ ŠУГхіCЛ лќА†’I$’I$ŽvqШчў'&0>юг+фЕЃУќЁ­вE§2ньZ0#Q4œТ ЬЁъl,Bt=.:ъЖf4')ЬтёЙyЯхИОу5+Zf DМЎф'Wi]жFЅˆэ2ЉшuІ0L{ЯŒ`?q/КӘјјЪDкок:веKсВнвZ‡Щ?Дз; Eыwy&jхWА[ щmŒЋф}rх[їч2MГ5­IYЌ4ƒЄ$љyщMR(•Уf^ШсD`с˜ЁИKЋ& Šk†gФY-‘t˜ЮЫтnѓNгWє'СV’ЪЛЫыBА§jwу–ЭŠш*Ш+ъх$ |C5%\ёˆŒŠ ђ’0RЂH*яvЎчl“*яЩsY/ў>qЭ] `,ГьЋWъЁм›Rзne­ЙWѕDts˜Й‚ВXея!;­“ћй †ІЄн ›Б<ТŠat™ž!a–~БяЂhм­b]ЊXmВ’cjX Ѓ`UkЮЧZщК!wPoј*$2>9bc+чWуЌ9т&ЦЙ1AЊуEN“=ž4ж Ю‘{ ›ЂгTМ›{ХСєЩdя9“ЗaД,Чbџrq<Д‚оЛeцBљфь?i х<,œњFTЎfZŽѕиЎ~IЏ.ЃzЏuСжЇNq $2‘–њSGЏЅрЕe^-ЈY‚Žї~ №fcРs­Ь@­иhА„e3žЖБ 'OmЈї№*ХœmЖ шЋЏЪШvтўѓ@Kєn8xЮ0Ћ‰ёYПс‘AЙyІЛћš…ЭџeІ›ќ№X?lЌ-сД4Дa…ЋЂ+OBю@7(сfС{qКиnѕy#Ѕu№TЛсO~OBнофVПРЧ,œ63hєqаЎIŠ{бuѓљ\ОZz97>Н-wСvqЅ0Њг2&qзЏ™r;ovФ†Wд€<у}4ъvы,gя/lР Ы‹цBЌŠАЫФJ#ВгУwПЃФšњM}'ЫIАсЌ5‚Œ˜2ЅбЏю€{jлЗЈн},kђђHƒd ъ!FL§|ƒКyRЇš’*ПЖ X ФеРЋs`Ђ †TмW7Аќ'Бe”К YюWZЈїу‹ЉЗ<ГLуЕцyy›YQm@KL ЕшяdрФВпcПhљенЩ+EœБФцяуэАкЏљŠгl@l™ˆЂЊ‡ЛЩ6ѓќŒ§@Ь_?Ыѓ0еj/рєБ:‰jЕG$Ђ>БЖяRОч%„ячGЉЙЋI†УѕтPŠCfъq‡†Œ‘еu„Gа ѕB™еlш'јКX БлYйN аХс”liЙ)$ F‘:Aѕ‡ƒоІо.WxZр  eI‘p;Šті";}і1Ф+Д$ьDЭЌVЎsЌЎ‚Є3™АsќžЉŽ‹`ЧЫ?2,д•(8QПіE-т…QЧ•Є‹ЏкФxФ2YN‚ВR:zї?ЦјlP~ЪИVСuZу"Ѕц•с%'ыЅіхОці#šЫаР}ШЌŸдїЇыЅљ 0јŒЌ CЌЏБ“slй…юг*йft3љФЇGrОм{Їл*КшG`ЭšвТ*>ВЏпNgъ›ШWЬMt_-" ‹SЛ(zњ:KKЃiТOаФы!eewuјЁ]юДэ—=ё ~Љ`ј>Ц‘œ[9ЁШ€їŸU<цдKxЃЕ,‹щnП•,@ћO“lмШвˆФ•Э91ц€оГœ7$ЃюNyж}.BфОrŽyeшqТ!B­I™H„F:јRлMD#]lmbІ2y|Ѓ Z{‡—}8фb$.Ьё †ŸТщёJ:єiЫМqдє 72V:-ЏбlВбЇЛГWш`жˆ2ІА&­[;}їЂЯ™ь›ў7н.2mљРЂf‚Ь‹m юU—–ЗvюМCdWEXэУ„д‰гЁзбOПдзЭАЅН…JгжиŒ" 1ѓGыХjbј” O&ѓtФа˜ЎА3 ” Ф+EїЪvHњ§Ћеpˆ бфїџ<З"Жи,uВЧМдщчћ§‡ыџ4Ъ9Н&}ˆ@у‡)cЯwAДм;€a‰(e-ъ.F­IЪŽ8,8ъпy“тe“‰й—г Wц$ъa€NV!ѓСз)ќІеG S[;Е[чТXЄOЃјМ1МЂв"9PЬєШuvЏжœBoЦё%jK` pк6 Ќ§Й$dˆ C^хЎеa ›Eђ8іpќ ‘“Z‚€9_Ф:xТД хјo{жЦprštњehЊVдizњxђI7Hc`а)АЇp( цR|eSЬъЖvмDњыЁl€&)џ*aЬdvѓsуъ‰{YёѓJљЙИDћЧ™Ъ?]HІ;1 R#qBО2ЁWH!ПCVьЗ’}А+"žдЕУm|ПГ ­эш>›§і%ндёё ˆьVфM№xђ |g?рМщCsЅд–жWzHSЙћшьOыГŒ$ ЖHјГ!зeцжebcРƒ4­BЙ pV—.jŸй­€‡NžцЅin[кТЗцA—’ж<“ŸЈ‚KЖxЉ!^fИюњШ^ еђ?HрјG>’фšEvк!4y‘ћЉЮ]Ј EŒlJOK{*А7EєyШсgTr“[-№zœfК{>Гщ=§1cж'т—•х<ъ*=wуr[­о‰-Kѕ§цŽƒюђБ]пХї ž~нWЄ>AЭ+ЄЂkФшlПФє)‚/EС-GŽy8}шёdUBч?”єЬ+4 щpоTs†Мв)њOHpfжŠя_rЊИ‰2ё56‚=я@•Къ~uж•м+~lРmй|+_џf`хзža>Ѕ‘щŠnъdWмWOеutЫЕкыЁ-ЪŸ[yЖY‘И„~ёPUiмс}ЂЧ;ЫўZмŽ‘ШЙK:х§џ[œˆ†ŽZ“LЛЂHяЫPGSOcы%ГVЃyC"Ÿ|9>ŽO!­ыВЙCs3~ЄLНAќxIчЯјƒрiЧ]К>юuщ. И™mЬЕ*kЅaЄЃ›bt:tŒ~я;ЧqfдЁд уЫžtыeVЦљNВФю-“Š@ЩˆFиvѓЖЄЯЊ№bф ЉуGodўћ§ми„ЊП:_­6хм‚В— —‚Ђ8@y(№1єЧ й/u!^D;7{љO;Љ§ІЗвŽЄsЯ W~ЂеДИДРZŸыф*уїщЊі“–_ў8у”ЄК9~ ЁƒЅтŒПx>ѓALЂ+фpЁџFž2˜ЎькWуIв™VЈoŠЎ‹YуTcP+Ю† ЫIэхy–>c[ˆ3ЯUœЏ^0+.cЪвС?2 žЪЃыЉЃhя†иŽІє+лЯŒЃbвV• RїЌг7ЭОI—пСЎЮмђќ)–нŠБ&і‡яаW˜ жаztD v$D‘ю\э@фqоFR1PЖ0Qб•чиТuњ>gРЪеZlЗЌ(мBОВ<[HŸ,dШј˜cvdh: яuъєŽ/oAФ§Zс0ѓџ š"6#Р3S—Шд_d(РтwŽЊFƒЛЦІy†Пј/8MдwйpШЋ0 ЁГ5q†ћ;“c‰ЇёЄX–v;7q`4ЁЅbэ,k|œ\к&ъъО ЕвgЁИ3gXЋГ‡+”0eѓtЮWЃW{“СљjђŒ/еЏўIŽ]я’ВMdё›ѕЇH$4їЄ§„Ѕc5УyФРцЕ™%R_Вnъ”нАTŸ \е(БqŸЭЁ щ_iнџ^‘#ц€hQЂOwKѓ™!qвuЛStдUЉБђКcЄ!a@T:iМ~уЦc&јц–`Я#qKїžIчі™CKkO +/dе§NOШpАв%™ž3 „ж™,n ћ/'№ђ•™іХЈЭ"фЅmЎУw†ЋI›^E[+x’ !–_эц—f мcПyџ/8‡Й~1BQМ)ЬVс(|б5A}Р “ Жo8WhђЉЊ‡Kѕй,§ШX=[айpV2”мЄаUOŠХdG™иWgвaJ ‚ жњ.†<Лiƒц]HNЖчƒХхœ&dž™Ъl.Вумєјœѓv[zяб'э-x[[Хr†Ъ‰+ьѓјГбbЉP(–‰тєѓяPs]\ЪќI…ћ˜чПz?‚АбВ"ёŸ‚|_d+ lr›ЙBІгг €T…˜Ћ6)\Hз№oм:ъ~pЕ№УxЋd‚ƒu#RВqDўЁg€­-ДIЬ7уГХ э{Н№ЃУuН`В•iњяRч#}ЄЇgžрHmєі&жёАDН‡z8ћ3%ud,`8e ˆюцI[†; юgуB<™‡›Сј`КбœыmF'6кЪoб<уљЌ‘™щ8}<ц)1щCЙФт~зLPHBŽ`ђDхA"БВF‹aZ“@Œ­ѓўтљХЌКьБэbw&…пqзy 1œоРЂВэ$XЏCРbCеЎŽч№ЄzЂњn7ЙрДdГэ2їиpсЪYЊИW^-№ъЃ‡?vЋЅЪ‚P§Mщ1"аДЌS•+–<[ŠШgœl)1Д0ёј}*ня_+шЧdхˆљ5‡SкЇэУKє4щiИЎИW˜НrАЗn‘?ў†pшЬйЊ К%M™ еTбЎŠЭPцyUя[ГšХ†[ЋЧщnЯKДЧгcœ­•Ц,b/Жd- Л“пzЦ дzuЗЎШzЮ\v№Ў7v?RGsйXbђДmаYёіччЃеЬт\6Y Rе@ТKr‰.,Ѕ#КњЪ ОџQє"RЫ0І’6єZD—‚WЛгˆрУоT*]о t*(Ј РЄZwБx”№ВFИт$ћRgЙœѕEхІHL}њ“ўК‡WШ“ЅшСЅ‚ƒЕрЫИjA…ЅV3 vv5пˆіФ`ы“FУQѓиrHДЧ…Б`Ok-FmВcаz=}5ƒYљFLRШ­=ЌoкˆЉ˜&a`НKpuHўc+ZsчЏPОhЗtyуН=–мчЎ€;ЦK @%УшAЄ#<—э&ІА|-єТ]еDхЈ4/MёAбsЪ :]Y-P<}efE@Й‚]йуF‚ёіQыkЏЇGЦŠlDВ@хн +—BЪˆъ‹ИЃѕ*:њ xd‘ѕ&Š0J*6-№7 ЮpP#‘=АŒў…Ђєё‘"D4ќщxќыЗЅџTћфИќiЫƒ—Ї…‹ЂФ™{–ГЏAг„ƒgц­žЁВ‹‘Фf,п•J&Ў:^™vtѕ•’Ф"qо9ЈЩDТ9ФEnТ8ЂіЅЄщхсL!(*EЈКPJл'ŽДcp№\ :!R‹=Ы—Щ-ЩЙ–)‘ПЅM~’Ш'ЅU.ћп5S 5iйДP]˜еV5;? LPШі…МлрbГ"ŠЋ/LMhЛi'ЁЃФГДrне OL‚† <чlыЊNcn}2 >ї]Ÿ ’:ёL(‹)yфгфP—УУ‚ј)=аЯо+Ъот§HЖ:щ>ѓЉі€(Ь Г$W0lьїŠ>Щ@<s3гљД9Ч8§G­ЧpАШ#‚йЗ! Щы k1оПlСЬuЩЃЏі‘п ўэ;Э[Аg,пsLZJV§фд/КmhZa<C›]ЭІh ЮVxб#”Œ|oSd€#%Ш…,‹ХэћФЉІvBЇЇ&PELцїпUЩи ГGЕ8{єЊъœвВЇјzШ3HЙkгЖMdŒѕєЎ$dƒRW9јј{(Їјkї›Н~‚qЎIš“VNUЋ-бвŠ{йvNљИЖtшnИѓ}q^]Рf‹Q‚ы:И€ЈsлХџf*Ж?ў гDР%ћђшaЙmoјЧfmEiC[Эp)HОФž9з§3X y3Є&єB“фw{ешсцф$Щ):faBЋцkЂtb+vЋО ЩЛ бтЪс™ ек„жяёю jnE;0+ё$EК“qу|YЕ"5ЪУg+KpЋЊчїауKфƒ'Hи;xGЎЛхіЉљmŠеМ­ЃM‘р‚&ƒ8ябxЃ|Bgш{6JtJ !Lћ ЧЊ8сVmћYKGL?“•ЉЂ8ЭAьиАўї§ЖG*Mil|іЏhž3Ž.•j‰~vZёНѕбхErчYk0кШq79œЄе]ГУ]П’М4Оа} a[™НЙедбЇ„(Ќ]wЋzзJМъ4rџoбXFН}Rј=0ъвŽ+№ЙGе ЖєO-!^MкhЛpэьUЈNЧ­IНEћ =0.ѕТz&KР“a–f[nA‰,џ]hиЮ ў‰ј"[GЂЕ\m™aЕ’(€~„бЧнeјС&]єјд,ˆІƒЃ=ОH(Ћ;Ÿ9УŽј.Б%ОД?•AЭ&}. сf†Цx'9Yk†Лш›ІШaЯ “57ТeЃАGЇЏNdeSoЦ“­dДЯўz|­псўр}wScђоQкHmЅ№‹Ј’ЎвЖ3ИхВ6Š0эћMјеАЬGЯTС4,,о ќНТ†8ыŠjŒt@G™ІЌьSјgdЋŽ5 <~YŸо^p]ЩдaLZŸЗrtЙ8jЙˆЗjЧˆyзuЂ\m-Іn8ё#CPLХљ8аШ7˜Э1хgaЧя~ѕFlхœ.Pь’—U ЂЩ}€М:чЯAШјжЈ6џDežНћтШmъdbўѓеMIењКЗ5ЫнЯЛžшїœeЋMОKБПL'ьŒj•АZ”Т ƒpб^ь ›ьЧ Љи‡SЅйŠ5–я H<ЩяВЛ‚_ЮСRд–єcЋuNs0d]ЫФьеf 'ш$Tў™ RГH*=œ>И”ІЅ}Qиt<jц[hЖZpУi§АСvЄя‹@l=й№*.uћАлpг]D›ЩPјлнtSaџ"І;#5v—"wЊрkHвX`rJm h.К3ђ] њШ^­Yћ›N—йEлЮ ж>BVѓів<8c†Žˆyaкw нNц=TВ%жОќї\}ЮˆП“§LйLQ`‰Ё ŒLnнУU|ГИФ€J-šт№{ЃёЏ%0ѕ'/berMЂ}$КYƒ­ЈБFФyЦцюхЩОЪ</€ч-IlзR™єўxQDKэ-LQ->R-O@_Сqюrzу‡ЭCА^№Њ2—ЪћFЇyœьNГ;АЙ fѕ IZ™МЩаZнжІ8t ?кц ;)DЮН‘Ž”е.ш\цьGkэРx<#Ыщyю@§ЈD•І‘B`”˜fѓ0ЈЭ%Ѕбi-яNх№§ $ђ:П@Ф?zMzУюIЛцE* 'žWn Oz]DJGл  BV;o‡яЛ“a‚Ђb~Ÿ|—`-„ыz/ЃC?їъ‡8cв&НBŽВ“š'ЃУ,)J7тІQрQШ8BЫБ|$9ву…fSKŒТa2}є‚rgШмёЩЦљ§cŒSѓSЮd"чnвд№МF PXvE(pKуц{щDIOз\kл4OƒNЭѓTgМGъ* `lѕHюио4 |№к•6@А—ь‚|œnЩщ4 jŒK'ЗШЏˆ јy]4 ]vЅмLmйZŠOт~+Ž˜џ(~5ЗЅХ5qе+Ь/ЌaІё_}0fюЗ;)ндaиT1с5~оњЪqPИЫ~шDд.n0UА;зЌFТЅ$ь|H§›ічУШ’њЊд#Ж6{Пъpд2кЬДX8Фыg€ЮбЁ^ЛoЎG15:šc VdpўЖhА]Щ…ч6Až ˆ %тm˜>_u\ƒЫѓрcояДОyУКў џ-яХЁH|˜яТдЈs№y@N{0‚ЌVкЁ^|іА3ФўЗQmk§Њ‘§nхJѓ€ЂgПШБЊ язёšЩЦ7Kxз@Ё’cW”AџSjT8љ№#N[ŸрГєЋi…д,C ВЉєŒfZiЧюС"zЋвZ+>ўлdˆэЇEЏR)DЬ‘&c„;ћQЈ?Мђ"=lœЁРЦŒўƒЈяУ[|uеКО%‰З2>3яџЉ˜/•QжG1вy ЅƒДMыs№ЁёUƒ@ОьMD?•7$бВncнЮЌs‹‚†mЎPЏ&ТI4G†?ЇППНўвŠ:0“.чwo_Њo’ЌГ ВУАЯNzљЛіС>ЃВoОыЩI ђЖfoч—Ѓ}МD<жI4ЅДj А'Ў9OЏqнЏЕ<"гtы}ЪˆџW>œшYЊ мгђ‚*#-2І‹Дљr=V|Vв=д б Yf&дЌрЬJиЋˆ?IC?іИр0—Єvxќ‰я­§сл јЋГAЩuъятЃС)ПбяєыŸ$ђРf+ШјHЬš­3 п6Ÿ8V`ЂђЄs§л@B8aЎќ–]œћ0^ЎдШьэЛхV )Ф*цЩXсСrЛсOАнЭœъ1UGagh=УНЉ ПЯ ^L“|~х7бў9хeхc—ЋЋ­l]xайRqЕ>Ъцs.АQЯ№^ПcрЁэ%ЛК8ь˜‡CБбКЕ#Dй&ЖщЂOOЇMЋВ=лIŸG{‚'ЖрбаК'аHЅЏ№ЪCk+№Wy„q(уJњ*oѓˆаџtC’§Nи=`Щшz"юЈL’‰4Йз‹ЃР§ЉСmД­є[2†aG7IўQ:f4ўЫlћ‰3+s…Ъ~-uЊN#&BFіСeяци_лŸРZ0$щкІ}=љIЪп пˆІ4lђtMT^ЎбE:ш№olc|_ЃлmwaOЮуtfDFZйупжЭЦЬ§MЎdтєGєяAв%8rzлœЙ@‚0…ОХє2Дь ьIЗбO БFn”я ”гž<‹%1m ~КГм›Цб.gZёR)DЉYG‰x’9бЌ% (—ѓVДЅ4s9L‰E№TЩ.ЦŒ‚и9%=MтSŸpЌQ2•3 .Нpъ0'ƒyRтeя'sх)gђ„\ƒ`iїљ8AыЇ§rЦhћs+Ž~PMЭHR˜“‰Аp9r†} gЙД+8фЦ “<гVъЛьHo™K†I?Љ†uSQXЦn„Ї€43Xё&g…Ъ™#y7сH›qЫv*X_Z=”uH {ЙзЯ=ާБ6(Ё…љ‡A|”Jйr5,”вЙo}}>UW) ѕd6ŽmZœ‰ Ея9Ь†ЏоŠn&хI4Y'gДкzл„чЬ‹žnМ'Ќr_бДгТkЬїлž­[._шЪЉz УfёS@DЫЏгМeNь ZїzЭ2в/дЄћƒA]v[--Ф‹лraGGћbЩ“ћмЙ ТЭH№rJ&ыxЊG/Ц›}Ђ6уЁ-рyЇЌ8lнЭњ‹+ѕѕ-m‚Њ7b­–:Љ тЛ.ўдЕ’hЧ)їˆѓк3ŸYыРйћZc/ˆ|o0мёZѓілїЗИЭѕ*ТЦV)ы‘Аd]_љяs<ю#`uИдэ0Нб уŽiЋUdaA2ŽOЊЕ2…щАЬrgxЃоdW&Ки˜5кVzйХ!Эj rQbqW>кYЈщlжfK‰’[џqЇФ?Cd(ы>EџKГ R ЛХ0‰ФчЄo3ЩуњOшњ8{HФ4B—yЛJЪП Eg‰’<ŸQ2E ZiЭЇU•суѓ“{bо-V]9pбЧЈYэ‚иz{dZ=„tйQžь“yяђЏрІ6XВ\Œn?€ ”Хg#N.н›йлЫt)еж­Iм QLЌHИљ;ьј9ŽD.е\/э™2}o#IyВшKищeUчг э44ё™ћ7ья­щFЁёю|E­…-ч9і‡%ЮyиЩй›qF%)„ocуїњЉ5‚ќ /Хš”њИКб^ЩЋЙљ—|3ьИъФе3ЇВ #фUћтШ!І$,KTн8ЭЯxЙБФНнПG‚1V–№Jy~§ZЋ ЌєuѓЌўъЗЎєzЯпhЁ{pХwˆсж;мЉуэ”\аѕ{U‡лђ-ЋRНЃМ/р ЃK@8ІYejƒ­<|O:ОмJ4Біъ•7ЬRDГtgш“яЏaSga} ­џcтzSТ$ъіФŠ“ЪГnњi|n&RZ  ƒ‹ЁvќHо‘gњЂ7е™yЎD'ldWјšпŠ\l`чxœ<цЈЌ’r’Љ/ыŒЮњс™ЦAM•V)™Ё…—мш"ИоЛ`Р4ѓAхF4W${ н},ИьЫbs1УйїЪќu…ХДььЏОЧЪŒЃJєMЪС‹еїlСЙтїЃž'кubBПгРƒ`ж<ˆ 5Ѓ[+r)„ЩœалрpN?aЂ,ў1˜Юi1q,аWусјк%ь,ѓ/е~Т} а€>Екбюе­`QЕcyœПZбЗ&Хы=v@Љ/ц`ЋWKф0зђRіЖvе}-Щ‘дН7IЂ€bH•ОšрsNН§=”–a•TFŸ‘LЛWц.ј““‡ž”ц„О=ˆрj {:w~ˆуЗiѓ/Юў4Її0ˆ§Ўё+YEўїёТ“g,Оь№‘†5В *.f‘Uѓ Tј›œl†ЭMHнJЬJ›9 O$„žŠ4/tlћYђb lшd.Ию ўŠЏ<йBgпЋa~0tВNDŸ љ]Тgй›Џ‡Ч\Т[ы†ј* Фарэ„Ч[ўˆFЇУ§ц —гмuЪТ™e#8T9•}+ј@сl+ Ц§Себ2шRЗљsўаbХŽ9pїO“Еч/ДjхYВ P§{RHЗЩ ˜У’oЭе­D“ь`Q“ЄјЕuЩЅL>’С g!$o @ГщЖKяОБaUŽ9эRœo.ф•ЩF’,—СДјЫW˜y§1`Оа"љaЙ|-НИ/D!,-чШP„к)A?Ж Ђфёs–Г^ЏђЋЙџ`VwfJО­YОVnfЃњ9&ж”м$p”I1ЙU^Зњй‰ еF d$бJлFчG7mj­[3ф_є‰ЌІ†ѓ,і§рЅu‡&чЌ†hУœхH Я…Pƒьš “`аї0ГУпЏћ0Џ3—РRŽГPJt!jњ:uн№иДa’|PЏIДPZ-жŽJ:ТuЄpўКж­Љ/P—mЈУЗ1 8’ ˆЖ ’…>nQлpbчd‹r^ƒ>НRRDћЎYuњЩ Љ€JŽк\еhr_3lџNХмџ+х ) Њм-5Q–K „оJѕEБ+=2%ЖнLь!СыZњЛтЫI­FЙѕk­VzЯШ 3x1#ѓ K!8‰^$AЮ&OО\$бPсїМNy“ОuК"щ6@nьGP”€D‚Ђе<ЯЏFђ-К3+ЧwtЧ Ta,@ѕ4іПШ\бUjoKЊaЭQф&_“.$ˆёуужрлЂфЬ "pЛ 1X{…VкЯ9GHм,k‹Ѕ9иГžXŒY%цЦ|IјSiЙ GЅXz]D\*YЦAОб*BЃ§Ж0ЎЭQ9U}зnI’iM‚Wэ•~ЊЇЁ„ЪiкŠЬлMhлЊ<ŠЊЊ^`рГОO0А&sODFЎmдї[Ћl(ТюT Ÿƒюр/~кRfƒ€NьТЌ~+Ё‹ уC8Ovи _Ь,Uњ,ХЛ•гH†Nп&,СU-фUb— GІ@Іtец­uLuLюб›-И8Нм_Zк‚DЮ”+ŸcЮЋ)сф‡qрхœlT„i2”TSЉœъЬ^ЈŒч2г2жЋS˜6˜т>РЯ:Рѓ™ЮˆИ]1š5аВZ `EЊYWD %J лЉ™ЦWц_ќdќУБиnї!_”РэЅЂUјЃ%•qѓр1јXtЗ_šjБ=юО™§rФVWя›yдЙњ0cXЩCѓXd]Maє’ююvB?sN%)@Шќ™ЇЕ/wkѓ[ЛX˜>f{Н@Љ;‚№5СYœ*ж\Ѓ{dZ\УYˆ!_)>­ийїz.€'б5ЁPŠa~ИіоЈ’tњhџB™'OЬY?9$dє"Јg§рж/ˆэzšoЧ0мѕ8’xgБџ.%уhЫkТ’Ns•ъ•њеДс‡H‡УГўн§Н“с‡F‡УБ~н§НЃa‡AƒКчэМПo]Рі1+ŒЗCСIПXzщъІЏй˜s™J|ёIЂHќшЦгп\fVtТmyсКV7 8жk8•КuщžpЪъЩAбџ-8/хБHј2Ў|СЇWwpсMEфВб!XмДHfy†чЇТ>ѓqЧ…ђqН’ƒЗођ”њz!wњ­ЁkЇ Бн6+ёТ ФlРфИ€Qvў}Ь’жwWђЌdЫ2"G@m\<ъУє‚ћшЫ‰Dиzf ?тЏвt mњ`“о”тщВфуSЛŠмŽмGšXЉZƒТІˆНk_KHIЄюJ|˜VЇ›˜wlxбз–нIТjаЪ,šохa™њЫhсюпйI‚U)Йk!qH–jћр\Sхsї;H4lА %]дєWMVќYe.pДиюњМђх8}€кЮЮxнЭціLЪ)eКl1lm€%lџ#5 n‚Нz;ДЂ'імЮ73—+|m‚—†#‚0_(1Л;qЏсђk…y"vѕjMŸП‘6D%ž%gќі+чžч%ђ(ФюУˆ,№f0ieСБЖЖвA+ѕGjхž[э!IтЯRз%Мшƒмј€?œжuч9§`№ћ"tТJ{qб­qaЄ"јГ§п@EŽо[r TЮr'ёЎ/!XЄKэ‰љEфќOр™/ѕAРŸЦАxОw| БЩЖNё~kŠ<–]7?ш.у†‹!•М(‹XF†›ЕЕ m—ЅYК–Я@;n2IК;j?ќгŠЪр‘аK']H‹v[миD—ЄлЩ"М„ЪЯEі 2SнуYЎšЁЄўРЕвhF гLФ@Ÿ>wyˆ8тU}J-„ MЦу‡фp§‹>_‡№"цЄБџoТеџRЏKL_нжГcyЄY”ЇыЙ!‹љС lgqЬ AЛн:mБКoеџrpЩѓрШ_dKidˆZЫЋ6Ф#lvгLњяЙFЭывфqPфb­+АЃY,#—nq}›Ъed›і— _.ŸФљ +\чЛМœ!кvБг єЅЅ+кv'? Ц’yВѕ’ъYяQрLЖА`:ЬМ\эhњ-АЌWžњў‚)Œ.Ђ4•*ePi>Ѓ)*Э7ъ`Œhє€L‚1ж–™„UQЭхѕ№Вr‚€їQФ—R-a–ї*џгВя™>н ‡Ч\5uќшиЧеЯя…dаяGI% щМk›[$Џek:ŽXТxмb!ЅQ$>€іЧЌЪˆTGqFю С8Ol*Ѕ\\цњФЫCу<‚(С|цnЅŸ:…ЮjЩ|ЙŸ&Œ'Q3 бЂqCЕo(о”H;`9Ќ=™N­яѓіЂ?T›ѓдy§mЂhnЉ˜дю>‰QП_‹3Е‘i8ŸОCВ’PSZv4ЖŽП8†oZ„ЧК(ч|=Ћѕ-D>жАЦ?'Њ‡ЩDYQ яvzХiЕ*ЎnN?ry“ГЉpЖ6BОКŒ;,mmѕ)д˜U€fКђw!Џ ”w7bšщ™г5d3уЫізXмjЎ}ГН/L–уѓ,ˆІб—žО?ŠћшƒO№щl3hњBСSbœhiƒ”pЏlŠ9!-bн*дbџL‚‚†mКv‘рs‡E№r .ЗѕFМ­ЏќЄЉ'–.jЁЌ; ” N_НdUЇЎbŒB}^o@Е Їy%—gV№'vАМпсЦгxѕњлdш$d‚џfœЌ*rG§#Йъ}NДhЈe#ѕ•ПjАW lд0џuфЎёYцХ$‹ИьњаWsэм4XGkc•зюžj8>ю‚C№Уkz’YMўЁAЪјŽZУAнОЗюўўXа‡уф(крЮaНфиЩ]&іЫ8sЄ ж™UЙАwCр*IУ™АcœКІ!)ТAчэKъіJLaZ]m1іЕ‰0]Їс“6ј9Eф, i&ЬLчaB4нЧДbŠЎп`‡8AŒЛ‚ЯГР›‡"Јї“ …шSЎbи*Кcш/и> cZЉx|вyЏ ;*и+Г)8пƒZNр("ЕUXSиЈPš є%џhМu0,{жО7Ъy +wv’8y”j5с Є,uQжЂp‹ЬЪЌi›ЇA Э”%‡|’s9ќ(џ-w Аєun4mk#Т/л3ъX˜ &О{ 2EZƒwъ…И“+@gЄе‘MЇ'}іюьU?­ђ+8žкбЋz‚sў"ѓ™Зќуфѕ/MЁ‚ƒžMі,b д^CУи YѕWFШ­„‚ав+ЛV€‡Уƒи<ђ" zЖ.#шкЌќfШBм7ННэє|;[ЪвВ ,№dг‡Aб–ХЄ€—7еьGђY‡{Гзѓrс4Щџ77ЈФрЂzpў ŠьѕЅоз?œР/†ЃНЗR_јЗ0Ь‘V2OaэF ŸcуB%xЬ hпA:ЅЬт<ХЯN= р Њ ^]лЯф1K˜ˆmrтЧїIрЕЗЬУЬр \Sё<,ŒЕcєЦМ…тёЩљ]€Кј_ Dїщ№Td= Їr‰ŠoŒУ)юэОŸ‚ОH.еРП! 6”ЮDИ/B‰Mр&•уoR2ѕcŽ($‚ ­е1ˆ&RWqЃжёwиЧлi3—hn#ЕџpЊO №>Ÿ• б/L’№ЗЩЭ nk=:лœTМБпР`ч{ЯJй ўђ'Уща>џ2o?ўP*zl­<яu!жofўl~Ї{Р­Œžиымyc5ЯѕCВLуљР …ЭсKz‹оfьb|n0 iк?MЊјЅМХ_cгіы‡С"ЂЊ{ З^i%[1§ю>~UAb<›ФvOЗ}й­§xEm”27Ѓg9И=ФіЇЋр tэпштиючЫдvцЂŒ{мћНа•%х,ХпpіO‚іЅ™ГEUџk'hЎX>оšУНџZ ШкŽƒwU‰П.›0НЃА“ї8Ки(УUБљD§{HQИІoцf…ТМe"KOБп ФЎnГяqS&†œь§бw7“ШuDГП9iwJ5? jqЅu‚“ŽЂ#6#)АhlСV§sЭ3p[фue…‚>йg,Lн=CК('fХЗKo#ThЭЇ­" {€ЊХиЦЎ$ ;~8t™x hмЄ“‡Щ>цž%*Щ„Џ&жр*СзМЁыВˆЙWPјшQusCbˆЏќЎ™›РЁБљДЎыkЬЇЩќ’WА/]Х” ЖЕq$gў4М~!wl˜цЪ„Е›= Д—QЫЃРcо’ˆЛiѕcў№ѓ/ьтR[`мѕ˜иbёKI&œ~Ф]јХ|wИmdЅiћ[‚<w ђюЎП799$!юъыnуh Бђ™щз№RoЈУК\єL\‚јBP•РСљМъnf:%ь3Охм “ЕЕЖя˜ёI)cИйГЮAВ*‡ ‡ЛѕЭйELЌ}\NEЭ КЈ$бTю}ЦёНa нŠ^ИлER˜цёзјјrѓіњйтŽyе"Ќ)МШкeЬѕBКѓџкБ%тžпšъГ’фш;cћnлеpі12e?4к+Ёххт н@IMž ‡^ді$ сЊwBФ”kTZЅЩ›рŠ0ёЦМІцQq/]—й&ШЦўМтAхV ьƒ›Ў уЫG–А fžЮO1 Ÿ†вЂ3юОЊкOє‚ћшгZ-ЬJ.ж•ШІ|o‡вxќ§ Ќ,чз u~(iš“ПyЖ)ЄWеfGFšЦЈ…бHЈОЉ$Ј Sг|Ц…wб<“Œ РyњGі!AT^ю.8Є†КHž=ї• g&ЛвBЎП Чоvњ!qšёs/ŒпIНcеž5йh&:Ћ/€Vщћ“xєЬЂрйa.ћ.LbДДЯ0\оС m)NсўZ3пxБ{лШeLЖ(Йа+3ћeŽ zoѓ^б`Lbж2;K;žFф lfСчШЈq ЃЙmЊК”ч<є)q!74?ДР]7Aтњэ$мt.ЗX‚~к‘nћ[ў№VXН6Фїщп? оhщТƒA‡VоX8ч'ƒргОR•і"c _sMMдGeпЉЫ›SКVZPbн(Nsвя-р4x†^М4e5Ÿб&[‰мAКЂЪšXМs`ёpПQшf”ЛЬлРC&Ъ§R^ТDПQчšСуРКјFrУг-еП]'3Y л Ъ]6žс–ŒŸэ9l*™X8nхD?W2о"хДs[ыFr ј-ЏЫ‡ВЊЊhhЅXшІоЫu№@ншЛ‰ўыћ_ѓ[š[оУ+ы:жE*‹˜ м>Щ%7Puикоуgч †СуоCK‚Ъ$a*шІ.XyсHЅ DЩ2VYšUгы№џ4ŽhКЭW‰єв8ыu2hцoъi‚˜ IњnзY&IŒ§ЗRЎцж08“рбsЄ4ZПБжy ЯhbпЁ‹`•Щu0З”ИYИЙqЧ`ˆ# Ќ ў'pPXуџ-ЈЃšˆQ.LsСЂ{7тrfУЅЇžФ­їЫ qдŸ'сd~ыПaкіh3г#wZoЮЗJЩ€Э_œц.”ЗQЖ™6ЙTѕу€ЉгОv%zHjЊ0B\iЛ%IЉЫY`~-ЕЕ‡€/Oœ™˜‹EьљbЃЉe‡сЦV?eєхпќ^ќ–-“б‰Хн•М L,N[Šoм€@9Юu˜]Х_тMaјOK‰ƒ’0ЫкЈ<фЩдк5ѓQЦЬ›žЬv˜zбѕц‰‚ъc2e…‚;Щ8оwџ}шВџFгп‰“*HHТѓѓчŒт]ш'ЬŽЈ#Ј6R]voэЮkчvХ_aЈ qЦУ Vл`•ЮЈ:h i' *ђО‹RќВQe%ЈЁkB’‚23лпѓЛђЯж’—Ю ŽЬ‰m}н/œЅЈяДkс šЃхкэєЎДЌгДš'ЭюUВкЂІЈЏ№YЛH ІЭЂмђ@ПТбш;QyрУ>ˆ‚щ<…сЎ?oЇ‡юtэКт„ЌдmЖ3{T@O#в%ћ# ЎО7мЫз ЦzeѓrTр`щƒ^›)KOиЯлСpoЦ;Q]iзƒен-7—oх–вkLCШ=щ nGN›ЧН`7СLЯ6б "!XO.=†*ѓ~цšх#я*„[†жR0d8ъ3#QшŽi  ^{xщрCВ+Nцkєy‘=!B/pˆ… {vкWvk˜‰‘к]„љМD"Ќб‹ќw,ЮЄ€Д л‹zU} У€­ƒсMwсЛ+Є"юЄ­U+Юђbf’оWЕ`Xo8L^iЌ&ЪrЬŸxђЗћHЕН[Ѕ!бzЯђ§Є"„ƒќ0b]ƒ4И…МЩBё?šPЪеBЏlДЮ4с Tў(ЂQјр теn_§Gд†Єm7TЏNjzА” ЮCrЦN\Р/ў[\аХ>i#ш‹ЬŽ-‰т/ŸЅВжf Ћoы˜ъ4`bORжАМЅ|@‰UoSKžОчє…‡ЙбсBF§ЅЙ@ц• hKќr.jk‚ЕƒјХ=ТФЬ1ч:ї$ААлN+ў7бcхrЭ•п5„&$Э…уК\шЎМ9x`dыНќ>шУ-­^'Gк6юђз1?Ь?љtПЂуWw)9њщVK‚у}БЅ†wь,Ац•#ŽкШєю@и*ЯХЇFЖ­Фœ|П”#гњСHkFFДиєХжv‰ЩXї™JЄГЋёn-›ЕPhАЈь ‡˜…/Іyе”)_}сsЪх о}žЏovлYŸЇЫЮ—%јЄvK‰40kшx:}'ЛIXЈyŽЩъЦЖ  I§“šУ4O4n“Ж%зщБCю€mчœ Юыђ2 вZЛ)ЉЄ2Э>нPЈ)XO„cцˆIѕ“u‰;тz gдGHŒю)Iov)ШCRаŠђr п†K3фŽфмєџ+žџYжpФWќвљgSqILиГXЃ‡†ъsѓѓ•D§>>QмF_#єс"Яќ/I8fxBООѕ}Б/ƒ‡ђxZ%Џd=@ф…†fH† „ЅЦ$ZˆЋ ЈЙс4…&џL9ду)Ь{,cчf<Ž‹Шо­5%№яЂ&ДУЬs\d;w†rЭ—x2a‹даЌњјиZXpŠMWLoЖХWsЯџyЅЋ$Q(ЄuЁ“(™ЩЉЯ ;Й!л БœxЛ+$jуTђс @!З–ЋъЬВЮо…бКЖУx0_Г^MВЫ|njRА =U€o”dПš)ЈЖL!%А&œGQvоЏŠƒ+rZL0J˜ўЮўа№ёŠд‹ё#кэ–ŽnуlŠЏі2;jж ЗД^п`Ы™žОЦ2EЭnV@&)Рйi |в’j§ъ‘u—RъБЃBђЮЅчЦГтўьэzwЌXqX3ф’qЪѓЊqёVя7ЌсЊBИThH–Š€љvцУє|?nЩзašjš]ОЪн?p“^@шgI’zЖњ@Ѓ=qTМТ)жFe&,ЬоЈѕюрк—›Й3Ђˆинq3у‘†EдЁnG•ЂЃCЧpдшnЌѓЇ €лPEьQlчПE‚AЅхƒ}GжФqћЭ8жф_Ьгў|”:T˜y“Œз†du*ъђз1•Ѓ!дЮ>1>’D>tі.|Ђ%ЩqпI+=ГВhZмq?‘Q9§…рOpєќЈ^БQb m5 Л„ЕoI4zйцлiU§ЬнФщІ]CЬіžXƒљёЧБЋ( &‰Э7‚еjC йL9­p4rќєЈЇ”CАђ˜ЦЏРH/6М@€ь_‹ Л2P]j’аiН8]™ UФ~ЩТ_–НwuўєZЁѓ{Qђ[Й ЃеKšХ‹&Š Њ"^kOђF[ЪК"^ ІђсW ‡л 8lP{ŽЩЯDJZMЊv•Г6и+™яИќз^qu њzяэ'uАН<Fљ’pЬпі{hLceЂъ%вдЊf•Pп…шЂрыКц ›LGo/РэхАЩР­!›зŒ94?5Г‰sШZ^Rp&’'зл1\ќROяЫу.ш:ЧМж&Ќ™?Јй˜œ€в0|ЭХS™С“мO ФЗ 3о'CdшКэ6к}X"д0bд›Œ$ЇўЫkŠЖ-CАЃМ—^:Žљ TkмБкДІА'<јтШАNЇЅКHcш3FйЬьйЋ—qя,ЕьРЊWъetSх7п:h7•ыmЩ\S›)-wxm'єCоя“лVљ‚ё4ѕVŸЎСžeЪ†Ї…Я6€Ю"TУ#UД8§Ѕk.г;fпsp*Wѕпџ-S5ˆЬй­•M*Їщаўї#§Э,KK^ˆЇП@ђх‚ œ+sІ* Ђ0ЗСй0RŽ!K.]ЙНHтoEРћDю tуmќ7ДцЩШў4LKУћc23T1бLЧušоFу@kп/Ќ‚Я­єo#!Q№r3зУVќвКђэœs[@'Ф†n~‚,”фЭŽујl/№бсЄŸУWqќ5 ј]їлЄУSБќ4ПјZ_У@П†—L(‡гУРtiSo/к)че"Ё'pIня5‰Ь–ƒ$ъ< щIxЄеxЦ‰ ЖАˆѓ0lN0вЁt-\/7(зЎІвНе ёЮˆxlkћЧєйCЃ\“ C/нЧŒRCw'ж†эwI D•бqш:ыъ Sr:ри*DH„ЄУFЈї%RHДljl‚s кGSж]њV!Ыљ•ќЋ№ ЫъkЧhжЛY žпw&—АQ{ећW@ПЗ§еTic?ёPХZФ :r•PFvИа=qЉх$№џ1E5>?ŠЌy—зВ=–РЗёё" YШв†–^pЊвбO,šи?BВфŒTёZWyзRGњїŠПН"+0uІЁ­H[КИ€œлD7Ф Ÿ !п~’ ў+цZЗ‰шЊvкˆЫЖоЈЙŒБ-!г=йЫHЩЖ ЖзC'­‘n8Рžщl |ЫРФюR?w Пƒ)(“$Q ђ­TуЮvўќщ}‚ЎмгУїhaј~Э™;€eПR€hdXж=X Е9L,b&!”{Щ э~РЋД*}Ѓ Дс@‘šжЁк<[рЫŠ­Rхq ?Žб8y@КЅ€x|~!В‘лcюк@‚‚Y”‹Dƒ˜,4В™“Ё] tNH‰ѓ”‡ІwŠЂK§ˆьЁСrkDlO§ю%в~оЋтЄ:ДћЦŸЁ06kА=Gd&ѕs€Ў~ац`т$ќ\\јљЭѓ§ZефiwЏЇ†mљpTpШD™{š>Ђ§”з!юv8ЦtMіQОK№ЗЯщд‚Nв‚ю^aэ(ЏЋvMЏ R~€ё•‰O4^Е7&ИѕCњжyƒ]Dn…хsиj X[шk0›d;ПЄЕ єЄЌў@&ЎЂ6'vпŒ$,cn@]д„(9Б])І6љiA†ъзEнџ$­оVpсMОž/ЋAŸГa9HцЙ№8ћdнb58Rъо1ЇфV‚d]Ц.+Я†вШ6wХАl")Ф_'г ,эpэЕј•ЊgХыЄІX~ЗŽсQ9Іѕg•Цœ(>4\ˆTљqš—CAЫtqzbE{[їПДТ M5‰Ÿh^Zo%8їћT•щЄцvўfгВМ)‹R+ДwXё"[X-иœ„Dп?5№Da4N.їШТ№&ŽХыE)јо 4аZqэУ1‰XКЎ?жgT ѓёчƒZ~aƒЮTЙNj‹—А"VЇ†-њ‡›FЉyœ(„`ZъуNVдoГtЮ;ФЈ%еnєŠTЅ)ЖЦTY”џ*Oѕ;гж юОAЛJЄXо”›MЈRi?6єЅIі>Р†Љ№=ЊV80њ+pЌЙщЬ†~НбУЁыšaдFлEМОЙ‘P„Šл„}иu—5b#З1кЃZpЖ nфysd."eœц Kщˆ%TF>MХЖ6U6!Zho" №ЃоšRД€гЖАЋVОЅё ЪЕОUЭДўMЃtЃ>Й'ч‘ЕXњжФЈŠј@xR O`%іžNЕОЮИ’Е>${™}Ї §“eyА О/ƒšЩyЧŸi$Хк>пјч7нЪ0Ђ`•ю…ŽЗТ“1QeŠ ~№gМцU№ьB ІЊ–\Љ&I\Іє‹K^VщPЙf@~ŒQйшEœG„ и_‡ФМNУб=*\Ђ{vX >c“–]+qMeх˜ЇŒ%nЁЅ››Ь-ї6љXТCВŸНnж-ЪŽџЋin мЌцй+їƒ˜М*г€Н&їжмфЖќфчC2Љы=Йе |лДNл™С{cš+сRЎИJ LХE_Љ>P-И/БљбЙр уыr7ЎВ6f№}Ч.ž$kFПA/’[Fкˆ‚s –ЂИhі]оWt&_/?ŸБЅ}Ÿ А‚ЎЅ>]x‹НEХЭБгсыeo€8Є‡“ЈЩ\Pкk(D#mс5йщмњ2CѕрŸ)f"IIiˆ–Yd>ьi(+е§иS’~гъYАииs5эшGа†ёcVЙюoXVІ…S€Гўm3Дж8‚ЖRn"Ы#&ЩTЉСя №Ъwdп ˜^n)Jгnѓb} bD№ЏZП"h4ёкCŽŒ^t‹ЮЗ№'љMfVђ,є"b'іщž%U@р]ыЁ№bƒ }CДDšРДŒEsЉJбЫuЌЫ”йлp'я}I‘oЖп ћcž+жdvРSCІЖЄ aЏЙFœ~PшŒ_Кos‚ЙmэичJxя€ЂeЂ‘­@У?Ї(K”„n*У60\;еЫГі К2Ьž§f–м'Эы2ГŽ9}|_еjыHsT,:RуT"!в&Ы‰Ш6јнЫf•%Я" “ђлH J§ОёФhˆ№,Е‰iЋЪѕjeЮахЂії~œєя‡ZyМ&ёZг5Д§јQUhу&тž&ЬqхЧЌ‘эђ74€`2Lr~Ё5Pў„ЗМ™ІxHt“и”йлЩFŒ\уаf•ЕoАиМЏЈЉ.гЪ7ё6 ч`GНŠ*эА{˜<!"Ц+ vƒђбC•и’….аФвPфUєgŽ8э№оUop~FsŠvћ>JЙ?оиЯlk?ЮХ[їНУИWєD#ьќg*6э`@ЈЏ7Иў. хГћЁS’`„T+pЖЈчC… }S ѓ0ц•ЦXfЉŽжn|/"в@ЋP`ЂдXƒFLoѕЁ+Б# Aƒ‡R›€q!55ФЕ 'Ѕ”IfѕЊ4гn†ЎЃEsлёЃsЯ‚мŒ>‚БcќxюаЮ9:+ё6Bktо'реАŽFЅѕ ‘ќ$ЦŽ(OXы MJHгHmˆ†\QФ<ЦžИЧхы€}дцO­ n›GЉ оftЊhqЁЛЁ>;NК:ђЯKVHLlЅП‰н=sЋвkƒ@ŽKOt7wЃ[в+Эy VaеDЙyˆu№Влkv‚@ ~џ7F=PХJЄы8wЎеDq“_ѓE{ђГЯ uhЪ15!шŠ˜]c№'тц4…ЄЕer›†+тЄЌЗЌ‡Є‘DOЌa=жЁЌcŸЭЗџ%!Б­Кiєќ5ЂqaіjЙBЇ2YхhHŽQ“7Пм2>Нšжƒ‰ЏXЌŠ~Яcо†)v‰œйA жЛ16ІDК4™лЧЗƒžвЋЌЃЬ-ТwД”н˜Кёy№њэЯЪdЊmЭrmкаYац{”ѕо~ёЬ­(@ѕЅ4[в‘пЌ $C(ХїŠXx_‹й‰с—2sју@ЌŸXЛ№wŸsEмЉЅж/ух/ЁrО 4ЮЧЕПTEULаЏыp"4Ÿ6[Аfє{­­‘оЅvе+‰Ÿ{":4HљиЅbhчАŒj9ё"Ъц`ZŒ˜ЮN$˜DanNwSЅяД-Ќ‰а$§ЁЈS’nQ vњ oК ЯviЖ;‡ˆвЧшё‚рЛ цaГјe„Џыл\[ИšjŒDвZи"”м-jв|i)•@‡ђK-LЃMcУj L5ыхˆiл3h1ŽЈЫ;Trлчсѕ~з•'єе4"dуg‘яxdјm:€КСr;ЖDб;ЎЩ#ФE1ЌчuŸь*ТФз[rKФ)k2 ЇПќ_X­ZЕх":Њ4HЁщqЙЊбШГGЖСk•љ*ђ‚ЙUnГ<‚ГMоIэа\љ*хЦ•LŸœX)7в)/мCШщl4Ћ—eRЉ’кaлW*) dшІ?9'м›ЫugLКUО;= ^@šBїMoЋь-,М6#љ)тѓќ;:ўeџaROЉWјzЌџЌ%іњ•_oЅЗќ=›oЗпƒОпЁOј{ч_ov—лщнќ=~П…SЫіѕЗћzёпЖЉ§Д?эє№§ОГ_ЗеgіњQУзТћ~ƒnћ~‰ясєйП‡ЊO№іnўGэшзјtkџє|ѕ{эятћ} ЏЗа‚ћ{НџCвn}^Г;іћ‚~пfŸсж„|ўуoЁwэЂ@јZъ*иа {‘ъХ,+Š_­ёюџ‚4KPфšВ€jimТFѕPZУ>RPє//ЅќУэ<•†Нн3BТ%"ШG/™#Ћ‹И‰0™єјu˜PЖRЁйž7H<ћЅ:bИД&>хИфЁqGтйє)?и Сx$УŸЧ“ќ@yѕvыгqЮ蹓АZ зQ!бFЙJВ‡ф(ќoтZѕмЧ6ЂъоŽиЄq"ж q№h.”nяА|Т=ЊfЕЇWКю]џ}DP&4Я*зЏEйИбƒDпєRЩіUЏ`…у‚Lnидћ!zЛ›Xвp<ХёZ№– –PЅЪЭЈ…$ЕztšГrю эЭbЗь…їзWwїў‹Œ`%aЬЃ§йќЭ'Џ-)|$ЭЕ{ЩeA^ О&МЛы2Є7@7яПО[gfMCц! jWГК6ОХMHЄ’Џќџ:а@O<]&ИЯіб5‚зYTgћgaКОr˜x-Е”›Ђ-6˜нAќSЋы e~jWМœxD ‡ИЛ|ЗrОЇ™ќёРВѕeO+IpgоЛИ€ ЅŒ ‘QђсšgеЭрGівЗy дaХU—Wl>5Ьњя cqуSXц~z‚9ЁBАœ№p:яКO§ШЋЧР"5eO^н–фcфw Вsw8нDйпaё(B™њѕС"&jDншЩ83‘АW"ш`cS'І7JќdеdyЪС8Wі3;Nћб”j‚E\ HГ=KЧЖ1№^{f3XsQѕ:yфEр’ЈгNї№ЭHЩ™А"™ZчЬЪPЊЦсЬ+*'ЫR)xЭtљ*œP“-Tг‡ —jіИsxЃ_ Q!їЎшAHЎNж…i ‡нX-f”$д3<~гG&Ђю]?КUкЄ кТдˆMБцч~•ЏМ_М€œJо§k/{ @ЗxІq—Ь9ќ†’Ÿк|€36&+ œТЮыQІІм(к?”‰ЇмaТ­ё )Б€,ІnРќn2SktЊpьБ˜M1На$ ”С \Цаъ"cшнѓінŸЈЯЈЮY3ŠИ‰вZ‚эuWћwWvзи|`.`œъzУЯžфZ…§ИSен{ъ5Ё§!=NЯФвфхЪПЕ~фіёы~P'g(%|ќюqіј”™A|ŽSќ{њh)ъVа›O UДЁf‰р|' €й )5ЂI'U$ љPPFЏЗА:аdЧКBбyЅOЊй+2шRА}S96ЭЕНждhщ•№fЩсXыzv –PЄЇс^ЄњkHЇР§ *Y›bщ]ОFЛгБ˜ЂCиЧtњЯNаUЗ™z›+:Ўƒё'•ттIк ŠО>oЈžун>н8bXad‘r}ЛжВA‚лєЅНd%САq.ЭHЕТ,Б)>WM|ХhQєћŒЎЬ2ЮUг*R–т‰WPг1Г!—7`$‹ckяfƒ7{†šx о“?dы›]!WmаœюŽѕ0Піѕ2lcЈНаsд еГPё^ГFо­ ЖФ™Њˆїx%NЅjwG_^:І’Эѓэ“ѕЫxШРЬxєЃ47Ql№!<ЁЦЌw™рл зИIьЖcд)БZэEж.UЊ™_Ў|ƒЌлЎ*i9XiЖD#к☼М1Л†^Sг„<^ Ћ,Ії“Хx „лTпч‘ѕЋ_žШ{ыв‘kr…пDbћ"‚­I JWo›;ћ0BUЈ7“*b|ˆBФ4жXхћц`–ЏQ$|Vwш§ѓ‰Б–KЪ?ш§ў‘W­бƒ\2 pИKˆУ_ВЮFWP2jрŸз@CcЮІН1Цщ[ФђQjKџm8ЬСФ‡‡0ЏЩБУЂ6ѕх{0Ю (фŸ‰hŸiМм<ЫАыЁЁ MФє™vhБ™ˆSј<ЈT9˜Л:sQPвm{ѕЋz6Z‘Ѓ”Єc?Дmь5ф  јъЂ‚$жI–К–љOnЖ™Ђ3nлНЩўS(ЭХОгФ Ё~лnрЇУі,&*fВ€ ЪЋЯLОдƒZ< MmŸуМф)о#Ќ=bПk W-ГWЕфЇJјьP\МЃљ†ЕБ‡dvПcQЯћЛi\€ƒГ­юнPQ&nкoОD/Є+6ШКFљмоMVЩ~­ўњ›œ!ЛGј;ФР‘чГАТP]UпЛ№ИСLЈŠМ/ЃЋ@єЌR=ўхЬј„_‚?Ыљќˆъ6Q}ьЛэxv­јDNп8#Љ`љ$/М}wдoцЇo˜c4ъїшІС‡Єh§]PœˆH?Я!НRіџЋ_™#т(Уљѕ;иПЂ‹˜„ЏS­–Y xёV Fэ(мˆЃ›=ŽЪоСЙh)Х =БД›дЭХ5кН›ђt—2lџsULTРіб€Ю‹Ћ•?a˜чо` ђб!Я{žRѓ8K‰јЃƒ‚і Ю[ЎœЮтAЦl3йxZЭь`п:М›H=Їˆ‹X№ЃЉXя]Ы|G!>m‹Кcзž”YpњЯ8Як6‚CлИ4п"G"6Ь.’LЈSc|LaрєчР,хNо9BЎх]yёTи §ы}P”43ЊЅдFzдсФъs8яO‹u}|ъ­ѓјeиСфЋM1Ѕ<ѕќІ‹ј'ŠKSЌ?ъБЊЅ бŠc$$ЅFвд3ŽuТGщєЋпYоNф…‘™ћ№F„‡Бтž—X8Йe+е\LLu зЌ!• ~7ћЇ1ЩєИФ‘ѓ25uРПš^&эх‘ћ‹zАhnюђmкЦюUH@Ž–$_ŽББ…Ў 7S4Ъя Zі)e="УЎƒПїwл9ЋhЄF)Mѓ‘УУ5в‡bЈд"ŒКŠOѓeждkuЮ—hфЏю€j#ЯK'ї&ˆJ 9м4 Г•ЋˆЄяЦЛ)]KŸs( щЏЖDrЏuwж~˜c&;Oщє†„ЎТR ˜Їxfwy#PDPVЦ-ї‘р›5rпчš`gў’уM1xЫOлъЦ9је=‘ jIТ‚кyŸ0ЃЈѓ&сR†)ЂST'Ё—*ї@jЮФ>ЯРбД€Н€MQЁмьИ>и К—1‰ ц]§T бЭтђGыP9KG.ѓ^wž !аB5сђrЫ67дeМFЇ›xfюЎЈњ*”zх‘ФQЃ#§О)‰ќЂDJМ5жR8™t№РњцзТEНT=^дІ„;цђc(u:оƒ?Јй;YўpЌЧ@\„OŸDэл`ЁхњoВЖѓм(ѕ”(šЇDЩЉЅvњXpFмМanсЌfrУѓG|—N›;8пњ~ЦЙђљсxіtОЯїxyЕчИЅa|daА.œK-gŸТђФН1ˆWђџAŒш4‡эржƒ(ђDjлГWьыА KСЃWљћ:YОZфšЧГ)p*[Ф1м W.žnЌ:М“Iy+ P8пjŒЗї$Њ‘ьwР) ЈМ_зTЂОƒ3œ]1Y2ЛqјЛQЃфCћ”ŠЩrЖ4>ГлЗLЧ™ђ\Њezœ”Яю“FРЦ3vа•BwЌ1Эчдт,‹nj™SzЦ!Щ=@lfлЦЂмБФJ­“в†-'(EЧ*їOeM2цъг`№нигюLuM6аH;д'ђ˜w2ЪмЬ>ФкТRj5™РЂ+ќ IlТў Щ2џ;• mьGеѓб™LОТŒN>›˜ж!“6ъ`Т јхЄчP…(FДЇ5Єжџ}у{m,Ё ч}&Ѕл’чBkЦЙаTйx/xІИBЁ›“/Ъb$™/oRD/DћЉ“УwGЎсkzђaйK…cЊxЦ8†40ЫЎіу)­ш™A'Nијq$//Л@§xНъЅ{˜?‡“SXiс‘nGg@H\"’свŸ_/‰!ЇЪ Ddш§Ѓ’О$еУЃЉЧЦї‡ЭумЈ$8Дš!љеl*w‹?NŸ6~ё"š$.Ё=UЄќћn6ЯЉрYёB™98Ї„ сЗ„>,˜сb"ЅПчќЦ€*6ч'6˜z*І-ўз’У‹ђXаФшЕ›ОККœ+0d љ6Э&pюL‰УЛЋiщ‰0-ЁЙLПзэІ]Ђt8Ё žСВ%‰ь2}3Я‹›-C9ПmЌ9ІЩЦЮ Е Ъ­шFЗXtlкŸeж>Dkw?эм‚oCLЯ*jєТнЃ[}V ф3<щГг`5{ЁhFЅУŒЛЖc6ЖтІ4‹›hн"LЩ‰гЇvTуіe–иІ˜XщЋПЄШd7K…Š:юЬЧfЏd9ЕЋ›у W­hsгrbEЛСR.Ј;Х=™†-U{bHЯ+†ѕjм'uUžqA4,yлХ”‚M™Т‰ќ…yЃЏ cБ ОуЗк%ŸфФ/ІД№L>i(љРpy9lŒ@p–!щвfВJќДОXIО'‘ЎiющŸЏчь”Šњ!хбюKђэЙёO@ХЦeh—ГpќeЉЫьЎgиюIxэ­›тGhY*AB \TdBИ8€яW5“vиІЖ:~œщ› сtQ0Ѕ#BэєgPЯ0˜:АТЏгG˜O“nсѓ;˜т`ВfцD=IГт-ЦшШ&ТAйч#2упnv8•ІгЖЂ^hО НhЏф H[ц"п]•ыyXЭлЃ–Ц–ГіС`>ћQЪеХv0"п†’уЊ!ЬБ/ArІNb]ЙифМП&‡h?}Њ…ШЙЮ•смлg+Љэнљ‡/iПч8S’%а€Mн№i&Aˆ рђHЇљХўЕ№ўTZШІЖЙеГіёгЃгУЕ+ZLЉџ xцрP‹J^EЉєџ|Œ]ђёџuF”Џ]Ј#H(ЬМcйќЁtэЉЯ}žОЄNЊё–KNYvwRЧъ)ы‘КШѕPВќВ•SЄrВсбеVГз„-№Ф.Я™‡z'8ЂњЩ: ЌС=ZUgBЁŽћ„љыi>™LЋЄSuVЕУЛ–Q‚>>ВгˆКю=`:зN%Ц,ХгћЙЬн PќЉG:Љ™*§‰і4T=і+Сў"ЪuoЫWyщџWЅ(юkSЧ wDша>.CЭMvќvКЫ.eУяхiњйR‚Й^™~їв=Шм:'рІ,б Уѕ‚"оhрQ k5; Ф3 вы&qНЅшFВтrv…>fe^›=?ьpз{Н%…:`Р#hЈO‡jiИ’ к’тœ_^j[нО+ПqT=š•dЗEѕNЌyИжй…h~—џI=ž/ в6Уп… ™[щR=юДЕс8U$о•7кЯиЉбяБ”ЎGЋіН)GzXVfœЯL~ЫSl‘­U>>€Љћлмо@Ѕ5{+ЪšжeЁЈ:у5XЩsœЌы-ћьKїoНёbмУ—йАP‡8BМС2ƒљqшщїЄўЕібЉФ$цŸ‰м Ѓђ\gF•I*vЅ œЭšN+HЉ%QўHvђЯIљ3тл=-aяЖЊ“FZ^ЩщTŽ5q\ыАlœNˆ!_:Ќ•ŒЭ‚ій…зЛъi§BŠвbЫ8ЄыOYп1 0z`ТSЮoЫagKzхncЋсY+НRЏ‚8СпЃяƒьќ‡a‘ЧŸч4МЄU%ƒп&ЄЭpЅ(R§TQЌnф‚'ю&Зџ*{э=дб ɘлџ!§,HFЯїAN#іƒPљ/п‰ЎN™WBвK{ VO3Wlf7QђфvАv3€ЦŒХgгИа€,ч\kфШ ркяЗУЎџoSД"dт‹К+Упз hHъж]•”Ш'gКД7јZi\>€†*bcі1]ѕ?]K Q1ў”ХЧŸоy E цЎS$DЭsІЋrиЫЗnO;KЛЄ?жх- `Ѓ•1‰Іь‹ЪЄ Эб{ыФoез_$@t0†аџ=%M,Гw_IK KЧЇчд=?x“nŒЋe&МЭH0ЊОЯА>†ЎДРTОDŒŠm/’NЏk ПVѓ‚ьšzФ`ъўъ’В|QХў‹эy'•Ф„˜eАgU4Jc‘фГМ nыи тQnпttТЇ<”ї–ыЏJLЙuИDвˆыБЬєЋŽ-ЙзW‰ЪБJOƒђgg0,JЃTS4vЫ/xЅ„!j•Сq§Пj0ЩЉ-7‚яёбM€э{ё?JdOuЬмІfюBъ<ˆВв§рфср .Ъ {ˆњNŒРю0ъЎчЄ/lHfH‘МгїТЃˆh;Е6ХCМЈЮ"џGНaB4 ‡PњзZNЮqщЧ‘ќц€:‘ЧŽ œРpё~кўJШЙыeбQ;§УЌ'&]x­Фл}“—екuRnm&)‰њ„’0њ–1œжхїІЄFђKfЩZHŸ`йš‰NЪЙлйI%•žZuhп4‹оš3ш8WAŠѓхFќŠѓfђи]haћDзЂy?ˆ0LѕСЋžуеhsкhг–бЩ“(щ@B‹0Ј^ЧšщˆфFВШ>ЂYVцџZ*Би[чс„№JхЁЈЁyјŽЌаЃЃП6]{Y=еЄvјЂцеŠСтq’йя’‹&Хьё&ˆ›АвC ™*—Ц/ŠющќЂM–€Ы.7›6­В5ђм$ќPPЧ%ч “і^UДМЂН8\БrPGЬ^%!TЏaxє+ьЃб м’GЎ™!œ_жzЬ m]‡Е8+hњcАи'BРюІб(СњКў/§<в% l „YŸ’ь‡K?’Ўэ˜‹д›Д№ѕјbAУкШДWМDVu‰ЦVс>нЪ—ѕљqF@s=nCWЋ,к-GŠЈЊœзіі2Ќ’юИХ‚ uўјБn!НсROš‘vРIі,_0щlŠ­6ёC­љк–ТЯ™CM2ЏК-ƒbћ~…Ÿѓъtњ!ПSœœГфFИЄioxЋ\зL”йЙ„3R”љ‡§ЦjUh*Нм–’-Ї„)МфlшЧЮ7rзy‹ъ,ћэVэІ„š]и˜uЖvХџiИ%(B’эЇŸ;H“Tb сVв$D ]Фъ4 -и(еwQ?(zЌЦˆЇIћ‡љЪ˜ЉCF/Жb_Џ“VХ-QyїЃ0w§/P1]‹]бЏqS'ƒЃGжYdHcПхК83{|Tж\U)мfЗб“И&IжН”ˆ'*ˆ32ь№2JХбPoœјхLLV№ZчЏtѓ$uлЇ^dK Бю&Єц^QzWЊџ? й%–ьЬФЬЎ_u)ІyиТБВЅЫJ№в~2№,‡# ‹OќWКG$‹Ё і№eOu3dЎ#_ˆЭ}­ЖYёќJЩ“9 4$8vˆіˆЕаDЄк‹Bk‘FbWI шфlэh/Ђ3m‹š5УEoy/R1ЯѕMašdэЏОЄхFоj~-+fxѓ8{A“…RК‡ЄзrЯTqT4LТ’П Q†kФ šЏўukо›F|тQ„|…Ÿ&ž1E˜JЖЁёъ…†гФd]|еcgДв”э)С#‰Zk_Я{“х2ЙV=уˆЈр4]“%эъе ч П KLK“ї…КФм,”ГšWФгфAїЋ@уHН ,PАЏЧ‹…о§ўчƒ–dqkсnžН0F^ф+ЧЗnЪUвkП‡ c) ‹IйJЗ|Х” Э}HэDzХю6§щ8 Z:П—3‘<kp#‚F+ž_$Š§йž‘-C:o$'N>P–_НЗ‹ИлњНОyЏDяŠŽxЅŸst#‚ш4^ я,Yыс7fRя%Эuи~l ­Цтјј!K]ХЭС}ўЅЛЛ—c№Ш(„ЁL ЂXо2Уќ/]№ўŒ0ЏJ ngнэѓѕКЋrГxДOљD1Jп@iŸ‰h‰ъЎsив;ЅйiяЧЭгИ…eљ&fsŠгѕžRzЭФХЧ*ћB @JnГ]нО/K3ШёEУ]ƒуcVдЇmy№ Я№ {R9ИV5+ЙƒЗЛЂUтh~йє ‘Й^N?xЭнXa№††vNVэћvГX”А†њчЂЕсК;6„УЉђ`RVњ/ˆ№0B>œ{зE,пŸъж­їLŒКЙžkkaЄ]wBz;›MИЇP}dтПxЫЪKŽWЕgцЃrў~ ЭOдюЩжы_.F3х.P8Ъ++ђды Зђ*”СчВ<Ъ}GпъЬLГQ/#yuџ8д ”: :ИКЯКщ,СЉф‡i­ТцчK"'8е?JєD~ьЬyWО)"Q&Ѓgž’рЮb[›О.ЯИ Алўtфu‡ГU˜I ЉѓLЗЙŸŽ Х§‚ЊЯшVџK‚ЕaтНJА‡ˆ`MjЩ 4э]ф1КсмR?Тg­Ew‰ы,Œ_Oибљ­З€ы`† |УІƒЪ›-Єƒ”pQ9чЫ2эš~7,Ч]amж|lщЦЏ :Вэ]ѕОѕ‘оLTР]Z3ЇйRКbпѕiИѕ‡hЬѓХєtЗ|ЈРdьСЉЂ"(J„q ѕ+№ ‘rХ—7воТrNr> •Jиa0_BsO™,\ЖФЃУE/ЋžАг2ИѓЦ0q•|EьеИyJЈчH“Њ1iжF^б{цp’Н#]M$ЦМEЪ…””ЧТ_Q|zRA€Аiќg­fИ—шœѕkіО-дCЕ |/QQАwБ^ж}џdXˆBЛKВРˆєжЈСоџg з}жЕЫЬ„Ьч;‚ §QЎпa9 џжЈЎ™ѓ93ЯѕЌ ЗџДп~ё6ЙHb}gw7ю~уƒЮe4Pё€З[њcй9ќ-жЊЪ~С„N*,†qБ`ЎG—z&užpЇљDAŠŸŠ=‡КЬвI9сqš^B&[Ј=Д&­еˆю TЇ”вЕT`*r‚LqЃГУ ђЯ)@2&žъъ‚WжмхMЊSРВ&пи$†4kу”hzя›wb_ЏэZл+АЕ9уiЯjЅ˜KЕЖШ"n<ѓЪ•GАfH›эиЎpe†Дw$№SƒO'KУ4чa‡РsJтЯVIвкРXћ%”p{Uƒ!ИHТDАДyяр™#iuvЛ ‘-мЮŽgЭеIb}3™qЅсaЪЇхkлhz’НМДж;fЅŸф6­Ф§э4 š‹ЦЮђjиЕЈ2Ь<# uЃ—Ѓыz‹ €sоm#аї5ЏгLbсщЇ@ЛНwьQ[їС Њ–›2Бг†2тeЏђ’>аЦy.ЉиsяZ ћЃPтz”У(њgПШTпЧТ !Г]KГF‰/еcС’У4сHaс&PЃЅИ# Тн9Н~ж x@&t€mяD уя:Ѕ=Ї,xќŸ˜Xї3m ЬWЗЂ> QРоi'ьdъ’fОИS­л$Œ;~џ&л@ФCV]&іЁЎџX|v2\5>нИЮ§Šo*xkoŽQЌъКn–Ъає‚&Г—ГУуњKЕbŽџ!цпD3Э—лZх…h§™y3п qžуЩиЬш­1 яю’ЮdqџC+Я"фа<Ш2`WУєюvлbq,žтыыf№šщ )Ђnf!5Л(%a8ƒmТ(WSюУ›IЦ5ž/]BЎjˆ#zYu™ ;ъQЫУLxУ&бъX”Чb+А7e@в\}пѓNiйїŠXЏ•нх0в:MZAЯХжh+ьћЖG%jЖзIКеиcFїGд‹iАНЇ[№4ЭЙйВИFvŘб>hv–с|р„ћ-&Єй~оkƒџ)ЬvС[LТ§†WяpŒx&ЦЋпрьЛ,PЩЬлДA-8кQv(iРж Œ5Лъ? јЌэ_GCїу†UщU-†ЏрщЈ.Ѕзœ?1жžЖ@,yjцlБ†ЬЛЛЪ@k‚ ГУІtп<Л/Ž X7;Мя‡СНœъѕyођл #Зи[pр5SЋ!;u ЩџfˆЮDђ!Jue †лaиУсГSю*ѓK—ђQ‰†=ы”ћЃќЊд†ѓp]/)/ЌrчКŽCљ УЁ‡Њ — 4ЧRЪ\Џё(4ˆЊn ZХ_ЩўШѓ‘Ў[•‘т}A:ИЮюУ‹‘'–vbмс€Ѓ[QЮžUќMОнTЩЏKƒ–ІЦЁЌ‘МШјФ|z"VњШЁЕ7ав№tГ}Т_„4Ячj )FЇЭЄ)4џEm7sˆaqx”pЪŸBгўoˆвa‚‚)pЙ'—.ТG›T˜&œНƒВSХŽ†\ЎUа}џZтЫžŽu=У™аmžkз-“eЏ{$4д;‰|еƒ4Wp­Œƒўаmd„…yћE`78kžыdоД—ВњЏѓЭвІЅиі‡Yх?fCЧn$УаƒїyƒЃќ?} IО8Rэ]t>7к Ы\]•~fКѕёЫVН›'…лЭUМY[L"+шсЎ Ощ53‡1ѓУDЗ$ьEљЛ•пиHlаш‡!{&BK|яka)ЅWMŒ1&H>ŽиГ6#Zoт1^А F‚жж+!RўќV  єш(=ј/\(‚Ђ-ѓ.‡ЭЊГж†QЛдyVЈ!U-fЋывЕЂ˜ЕˆkФtэч5A~o$І$О>оSма ˜u'Fр6“МXШaаэ9ѓ ‰ду~st+Ч<ЧEь)aшУыT ЪkвЄ.Xoтмњk пfPKз(уБЄпїдУuЇ‚Ќљ_UKБ}ЮЩ"/ТЕv:ЂЎ­=–!QПЏ|н1–5Ъ"VуvЯГ>sьŠъœЂm@ЉoзмИˆхОCSжEАXъ Цlђ40;/D +јБСGƒGiўjљ/8h/И ^R”‚жмѕЋ,е†Ж*f:/8д—‚jлB+ЧkR j§Џэ*gгz,ц‡F’&jэQЎ­В9ŠуХZвСF#rЉЎN:|$|KфG AШоJœ~XК‡p2~XrXO6G!ъmЩЃB@КЅŠЮWv’О[“%rcoпюЏzзyž-œцфв ƒOърс…7В’§Ш2”z№нТ!LЄ1’П5M#Э}а!OF^RСн™/“&œ:)0 g zњc„ћeQ6SNz ѕ%&?lAвљBcѕвfЉЯЦ№VнA№ К8ъSREa(dПжЃ}Ђ/A_#€xиеDГВ9g”єG6ƒё“ЯЯ™ЏiжЂ]э№—ё9xQkЄ SЧћx9ЅФUДŒЄJ„;ЂзOА`Џ!R“^T[ПјŸ›}#;D OŽЗ<ыЉ€{ђ,йПl§љМQG˜›пљ_7=џi+aЏЮџkzшu†з_)ьЬЪ††YyжгFжVXђ’vŠ/‚”0Ђe.б™t$э]s†VерЖdОWС‚;ўШ/Ѕ0СGf}NЮЉmhПчЃн:ЪЛЫD)$ Ž:*Т}ƒ‰–j‹о'Иˆ>kО•ьЁЁя`Х" u3TЬуЈяcС’1Сƒt?К`й„\я•;Хqю 9RhBСOъ ѓš6тoё.л-д!1cqCеLмй/‚EЎяђN6tЉМ=:ЯЅ&MГјюˆф)˜Еp|№yаЂZЉXВfцDІЁcOж .C…”љ‰>60я?РчРэЗz^ф Ь/9вr.ƒžпjн…GуI:Lдйќ­{5Ќ­С€(‡ ,оШ,МЌ7vёЅsФп>)cз›;Е)єq\Ж 1МhƒXVIС­m У ž–ОЈџ4&ЄCЇ‰ѕт ЮQ;<RпwNШA‹R|Zw qС§п;bdЖVЬ@#_љ§>5eфц]у69/žqRй+еІ% Ј* HЎЛф#SэоHuXx=†f‡й •DP&ЯСKŽ,лGвŠѕ—КІШ/П›cЩгL‰zЁ ОРaв$Дд€эS]ДЊ Ї(ЈЄ›DŒ4T– х_UЅ~УOКйн5@^Љн‹80`?nъ7з9дх1WЗ™‘GюфD›Дї0@F1сYАX> i(ЏІ†x<ЧAЩуУ„7ѕ$Уf0ѓsA'Rъ•Ф їЇ…ˆ…zЅDBр сuЮЙдuКAd˜K‰7Њ@ЉL"љCQXцО›п“„Iѓ”Т™8MO #/$JхD<ШнЧОr&іљлд’@_! z  #}чmQ! јjSЈРtыDо…T\Až#ž›3XнP-‰ћ%ОˆПјв ŒKщГэНЌO-ј8гhJTЖ.По"кЋєw@žtП_]MЇY!І2n‡PюWh‘sŸУАMЕsољlc‘Cэ%Ќбј#+gлopдbВ^ЧTjw•ДтU‘–]хЉ4яхWXz')КMmlrЊуоїЦд<Ж5]є•в7p‰bЊIъˆFœ LЗ^Œё(И€цЎŠќО[X/Ћљn7PУр­&хnQWй]Ž8зPUX` ЕC".˜BSO#йˆ„|'-?жЯ4ю’/IкџGN‘Чy;…БХ2БмЄГ†qЧ€3ЉЯЧ]tфЛ(Мuz0—Z•рАяю_R‰RчщКCƒts,0XЈc+MђcКАљXi7Cw bю<§ѓ0\№№—жРМКЛ.qŸыєЎњмЊЁьј8чi…-Е-C‚Ќ—uж@bnuђЬ1&SЂ9Џ0йЭUœsм%.ОзЃЭTЭEAЊBІ%LЊД ‹DUiKbѕ0ё›­HDЗлзЊЌfНіДe”7œ;Iœ(н4Фњ’Wb8`ЄуHeњцe™)Т*zИIЦ^Р&@P,­эДHŸоіJУш;ђ[žпœz05еFwџf ѓšфИ–ŽЧœ]яУnЭЕШЉI™vБŒsамй6ЋГЭ\р,еќKб'D Фn‹b y…]9њf_ъсj8Ив`"yaЙ–sІZс`›Чр_FИУіT0ШВ@ˆƒ_ј,•КшT!UiZ…p&YwˆђХ’ФшQ=Œž’ѕ ЭsœѕГр uф•И'&l† КЃhкOЂ”‡вФe,Иšš0–Ш|, Є g|,Ъб'ЖЪSIŽюмЊHРч&ЉPіt›јŸлЈŒ.јЌЊ~ )мYр9—ЃНЬШђ2YЈЦКE`ЮZЛЎБ(˜Š§ИП{…ƒѕhОћб(˜gBrс>kзZŒR—'gЕчОЊЖэОЖŠКџŽЏnžˆ|qz+?аЕ"N\Љ.фhЖLвпJh‚V XqyI vZ”ЬpM“X RЄЛLWпy {>ѓJB?h\ ўŸёѓЁ,л рoЁ{ƒђ3NARkк™њИкv0IТ 3t4+ ЏўЃЁnьpжЉлЭРBјš‚ѕVХ(,^њŠNа•щд~.э­gQ‹7р˜ŸKЃY’g„2r$Х`9МЪiзQ7цzЛyЂ/6ŠЩNПeюpуŒ8šIязAN“њŸ?Eг@"ѕљыoлУ/–|Dо‡Ж’енЊе\ЉEZж8Оучк5~ї3њвнf:•#ћа,эgїŒ—A˜œkлTиП„S˜|а§Жц[<,fpˆ‹cЄ,HЮ•ђЎ№W~tМjщLЌ™дВљнƒд4G$1W<˜а$М ЖаЌЮлjнлwЄ‡БЏ‹Вšg)N/Єo”Г(9ђ0Ш45ы“Є•gшgї3ѕЂbyЉ€—К(@ˆtЩVмп1ЂKзЂєБuћгФМIќH8г~7aЄвЉя"PKр‚Y|ѕˆ.ЯWj--еЕ€<.UЄТэrŸrSч–mЅЩ‹мVsюY]œ^п ЌHЏ*FqyДкЭАGš™!Ђ\жŠ‚йЅььщˆ=-ъЙ ѓ’ќШQOЅ@aЊД“2€:уwЬŸУXйŠйѕwoTžНy" 4V„3гюIіB4‡nШ Ў|г1Ze%&oЙbcI~­qyчБ…Ќ?•ЫFГSжОZэ ЌaюЌaбхѓaе1щкŽэ€orЖзЭJS<Ъ УVЂТZ0тs{N1ЛКеKю`ЇЉЋ‘kŒдУaч]Г}…Ц”AЧЬЮГ(Л, j‡ъ—Р@П=уЫќ†@+фЬ?†ƒЏ1P$›R6dgЏ1NѕЬAˆm–ЛJВ}vИ—wuЂа”Ї%Іz4Q‚MлжЌ:GпыbіJq,Фдs dТУŽW.]ЈˆЖ,rЩ)акћЖИш‘ lьгЧ<рНpUД\Є’Vз<зZ&нoЎљK)П!Ь4кEv№ДДЫ]є\›Юощг\&c9ё‹];2€ЄЬ№Б"pўЌ уcƒ`VxМ[ї>ц%4АР550цУѓЬшнmЪbљ5“q–ƒ:v~cЧџы\rБPP'Єu[ZcдuwIї$6МеХ3sxaŠl&€‘ŠŸжїч”—уrУІ)%бOЉнЫBЭж1чYІpЗdгтe\ХЪлMѓFф{ŽяЙ’дКaѓhр’Дpё№ЈЮу”Х‰ыiq.ЫDі§f Мp>РаA›Ш№y€”КьRУ•jzЗŒu+Бэ/%Ș2’XЇ,ЗЃ/Ч0&“}n>‚Б‡48ƒ‘]и|ѕ.Рф f…Й›ёђ~д$.ВA‡Fоэ˜pИТнЂїKY\Ъ’)pgКVЬ\НX`ъ#ЕPtmа]0О хАыЯ9І~^+B!ё Р|OЋну–ЫВЩЬ*шTэur1ѕ '`yѕQcBцПЎЋїџ>ЙќмйЈў!)xє g'ЩС;м05/YƒHџ™€3x—ИД(“Œи5МѕїўЗ‰ё8ЗB!ЪрŸ@Ќ њйЎь9IL№bЃ|тކ@›‡Ювz‚­›ФЌбМО9 ќHЦл„ŽВ|Днu›UXмƒ#ЎЏUn E{h™ЦšLLсzsJШ`&2ШПJ1Œ2Я+VLUІ0јƒЦу8AXѕЁж’FƒП ІQZѕ+ДѓЬde—[hмV™=ЙЮ]OfšNЮІ;bэ]џgфІ2ѕкЫєп' s%Ѓ^тUХdц ЂЬЕщОюСЧR2^A.‹ЉSш’ѓU"e‘>*й]\!ч5B^…хy/љъ_Лы& kОhЧж ГOЁ{cЫHдѕIr “ц2ЎЎhвчЫ|#6 п"ДеФ8д7ю>Х_*7ф;й ŸЎRЕЃХuсУзО‹žыШџr ў‰šэїЩМXJ0о[ЯїЩРUНрёФ vі JM!%ˆўўcЈŸLпUОLЈ,ZпСšR#@јб“АЮ­ТОŠUи>6­ЯFxмКGFчХM ќ[žFК_L"…У$_Œз‹ї…и–іЌ7НІWBX#д†YK"щ%Т+РfЁ>OhsЗNзАјОrЮK†Eѓ†+xŸc`†И8YаХЃЂjЕШwВIл„\­зси4ЃџkH~Я`У –п2…Е И,>uPL хХ{lнГПDЫNГЪѓJ~‡HZh”aˆUv 9Њ№уќй8 2g™N.C| йЫC1…*ˆ•†пШЭcт…л2XH›ђ%ЁИ=ЖГ ЛtвЎѕ_w7*Ќ*lЫ‘ц+˜hА#mtС НLrAпВTœЉбtqЂQF‡!Žі8ШzpВЁd іцr$<4шЬЋй?CЈDЌt3рјуЯя;vњ3ЎXвpЗ%q`Ѓ{%`ЄšлЮєh"žrИaoх-Щ'LсПн–pъЄОЈRmЩEс Оќ,Ў$ŒўќTQ„Pb[ еšxѓТосњйч[tTV%{pє‚’НБt‡тхЬ.Y…'іEў*#ЄBЧЭаO4оЁ8Љц?O–d—ЂŽПГ ШWђLиъDCхЎ^’ЄHЅїu ’sGЁuЫІчЅЗўвВ ,н%м[3kb0Чт`ЩВ&nОЗ“ўХКyДЪGœ*ђBU1'b–H[aьяg­Ў3п™cЭZщuŒд™M•леF€5лзїћСyњх€хї3xŸЎIыŒыzg'йœ(uщmЩ0“C–ъчМŒБ и #9.j-%ћŸСNРј’ьОЮюнQdЄ№§МOм_‰ ‚3ѓ'Епў}ќЪl­нE'‚Эж‘ЦеAеР;м*€‘Ю„ИЎОуШёIС–2жAOœ=KŒ˜Г-Q"Ѕ30NБпсп\БЉмнk%<ђњ;vMПЈOы*ly@pЂpзЋLsLТ{„Је*10 z%`€a…„зшъ1њ!9†ёлј`UбЪЄD=ъŒ% /7л€хрBcЂП ШрG•xE#Ђа”XхпMїB:бЬВЇš|X™У‚Lt аӘ чз‚аДN;coЧЭHIъљёGЩаAФžРLŠВю/œѓŠЋљ}>‘§[™лs!№Kn,ЈўQЫиwp „OT)ž^t‚`@eŸ"ы‚ЩEн„уо]_^jo™Ва(Ѓ‘ЙЕ†Y‘iь“JтD=ієB)АњT…LМaъCЫЭєGo€ТЛvіE€Ÿ0зз№ й­мјК]Щ=ЉџIј_Ф>4ЈZ"†Г(bƒтћхZщм\†Ф„ћW\œBAХ—*Šэ~ї,Аqiџ-йg [_slњ˜—ЉшT}4šКў4ЁнЧ EQ^}Ёs\š.Pљ-Zзžт/ч%q|PkквЮеPЧxœЎRoЮЩУ6b§o"y4jPзЖШR:вgмЇйшšWв= sМеэ=ЫfvIŒчл3VёcЕщanЏYб›Ÿвѓ`ђЇˆiJЯтзV1 mЗIЊћ›иЪ;Vp;fцЎ)ˆГwћГŸSœтЏH9Iš/—$ЈкPлdVіOм0п­+$ЦЧЂ`@З{!f2ЊЗюо~gژžЂ.ИюVWA!˜зЈкP ZЗ€aы/5˜CB“V^ПаЮїћoеR9йжбЗX'|iЊдuй lМf-•вAtщЫVЭЋогWНЏ”CIт‡єд%­щŸ+ET-і[ЦCк№]xјВ€ Š&Ъ$#PˆГзist \*ћёж?чёфs&T š1 WX­r2ЏЃ/скВиa™йK(h=€ПЗекŒЇЄК *e-а:ФZ­ЭЄxЖЮGIBъksЌy-6г‰{б:ЏОIm™‚РрdMъK  џtё’M\ˆз}&ЈŸ д|ФГ YЄўєЪз•ПѕCІэ›БъxбщПЬ‡шрi#„ŸIЪPШйWn§%[rЈRцГ‚ )bШ~‘]“НJ@ЯwДЭБtмќ—:иЇы,М‰њФ?‚єИ,eвІiђ-жј[bFCісјќ4yХžOФX['™IЅ CzмœМrщ ~Ц8Stф™З“щБ™пЃ†]г7nk^~ћ[OŸjф†8гˆ5Є8ЦUZtхЭЎн]JWўзш_bvMyёсFнЫŠ щЎ2аdЛЎUћДб'Щн­О„jмG€XK:‡ џBcЬmЂКћшШ4…СguMIjк[…RС_еЫД`cHЫЮцещП)А‘€žвѕ-Ѓ[ћ…ŸЛXMwђeЯъ^Ў—…)_ЦZ•p% hЄu7Кс‚Kл9ЗtВŸхНеP‡+bЂ(‡sН§ІЄ“%АB№tщ§pЮпЖ(­є…F1(ЁЦlIТіР^іˆйѕxќш6uОЛDЊЃП к_ jVєяSіŽЖtƒ9lЊЙНцfё“ А|ѕђ.дЩЈDSЪЖKоЂј/WќdfНХ;Еѕ TXŸ9|„—~M›шќ{sT№АрtЙзs–>Ѕ‚"n|uыс ]m`mЃŒѓ b^эW—њ%št$„Ъnr;АИ€U­І_[pРб_мNYјЙЉ"|ВO АЋ4 Ю[‘zгБ8Дš^EЊЁЎ8LМжam,Ш уtїнžыОuaњ˜=9ЪE‘YЂѓїХФ\xYЋІ™sXХ†c™h•№Oйњ]ц—…Hчз‘сѓЋђљ7’#eЁ8gиX2h~DсsПjiч†4Дh§џ J,GЎfЯѕ„JаЕM| KCюњџWф ._2™ѕНt§ЏІЯа ЬzS3^Ч—ЋцМeo—тiЃQвF*ЕЃuo6>OЯЏDtпXи лыџ!М(M>lМм?ђ3•ЗРйŽEf…СšэHЧLЂ%Tt:ЫWGщН— kНA9Хƒ<Іz?мvџRЄжb€€PЩ›!q Ч@‡ŠF>„aЗђбАJeц-›tШk†`.T†цЬ†НУєP\яо­QсЕCЕ>RQэф…Р]m №›ш5—FЖЁcЊшЄРч~^ЊŸIxƒdВж_Х№ 3VDaбgѓ=r{{Фг›ž} ƒЇТ+IІQЧћd†Ыh˜Њхœж‘j‡ІїЭEgwŒъиQl–Y[Јg`цШyi'Д ’EЈјЕѕД'V}@О‡оNлxМ€^^8CaV›љŽŽІtЮЬТ2ГPQaЁ†Ћ§мЕ­JpxЌХр$ŠсЙo§ЃQžЋяъ(]ŒS!š5ъ€DёY–иўф,я/ЕZUчM[ксжvМt—#ЃяО@%aз%\чвъЛi"Вi|fж ЏЄЪж"Чо|ЋБ†sŸС5ић‡,ca1єgu P“ћДыОьЊF јs \ЗBК€дС~Cлн`ЊNїЯШ+užЋ}œжžлЁОљзєСЖ‡ ъ@‡ј-2пxDЬФН  0%5ы |nЂЮЉŽ@vђ 5ВЯqB>Є*ZюЎ…Яћfvу†%(x4г‹EŠ5ніЪБPnТ{†В2ЋсЅ п”oќ.љAK:Ељюш!вПшїЖƒyУKцыПђiЕz]PPх{ D`Ф7‡Rј БSЂiVXРџХY.і‚ŒПЖQћpЪйЬ–=,Ч 6Ћс\!г_ёR‹‰vœiуЉkЧи§ уaіzЅŸб˜фSOW2aІкИ3#‘/ИКр„С†щJy_’”р‡­ЗџNА щ<%QІDPѕ:Rз>БUе8BG3ДЋ>ЅQћ˜Œ)"'uЙтя€lЩч‰вШСqъШnMѕе>jvзš*л Љ&ђМЉИпZmN5͘ ЫˆцЃy_'s yŸЄцZГиКЧ ?Žc{еСb‡;’ EЭі„фDŒX’]у‚ˆFi;ЅaР–_46%:–rr’BМя'UгЊЧMщЖ*NjџAŽюзс8gцMm *qеЋ:SQ{ъЂсR'ІъE lњCc№‡0"ЎѓѕЁќсLЬ`/оm†DZъьњ[8ƒ 9\Щ;ЯУМS‘юОg&У#ЌПљЂщўK’Œ‘L1r06Мё•;"< EьdГЮСHУыbЊЙCCXњ– ёцD&™ ќ"gУќЂ_Мkю0Ј”б5с"ї9л@9 †cCI0=,*]‡QЁЕуЋšqž—яєflбlšЭ™Сdg.9pЅљš DХ‚[/…й ФЪ‚КжѕtуTюnœціоєжLЗэ|Ш;†A‡§Hа7Т›–vуИ„Cи(f”љ%ХУў‘%SћДCТb2"IdYA№uШЃшЧбkEcAFЃwѓЉл!6Є/Ќ kІ6бі.tyмм’є1лzžz†ŽYЯN@СyљЪ”цjѕŠ%B‹J/-jЗЋ9в&€‘7 дIУі њ3s24”™урФj 7U Z(рюMЃ’т‰a=!сWd‘hэCэЅжgiшi<дzЗNR*&ЙѕЊМшb]йœцЩщXО6,и {gтGв,ФAЛ‹Пдбы I.Ц*АЬM3Р„€НБE`<’дЊ#dкGГta]ф#Šс•€УњƒnЃ2а*AОдб žљфвэk1hТЕV@’8[%ДЯqƒ ЃT}kщi5)гœсj’./Ё{l6ˆГѕЕtМ V&^ж’+g#к憂^yэћ„wгјИЈtžўХf•2йХТЭ <Щз˜x?ФўщшдСtЮбЋюЅЯS§uYE˜\sJqIЌчџnр \`ѕ1“шгyЊ}S[л R[­йT!огE вП{9otBћћі~;ћБ4kЧЁызh/6нKSн_Šмw§ДBЯxДвтЃЌэлХрјu•cˆ˜2д9жМnСNU"Yh*#TYтЌ Dе:З*н|ћ]ыЕh’хO}<}з‘Ј„i;лiо6hХf`$ šLNџ1SŒ28\P6њџJ ЭšpuР‹$лИг>Њв§ƒХe‚ЃZвZ]ъ6ЁŸs:›ffС%(І•™˜B7|ЏАН#_гEх›З­4ДK%n‹ ~лДАРJЮGjТh\ЃщyJњџRОFбJ С=8n:єP€yˆjVз‚ѕІ'žС,ў•YJz“д&fVK+`ЈБЦ“sхkmТтe%ЄžЕžRjя4Ш”ѓXщ~9w!Й"Ю^ЋYгbo­эИ1&ЃƒbАOУЄаЦCœo|EБмQ*гыт^Кhdd (V]CК„*ЖњњšСј ўмса0”њ€змRр•ЕZ“ЩњжўїЂЙц Ш”Ё%b€bnХHCgЭ™ЬzоTdTcpSl71-qWŠ;чY€ВŸƒЄT‡˜№ŒQˆ8іTЏсСšyцѕѕz‡„жюыЧIШ ?qžxu@Р”бф`№e{—(ј‚ŠCс+Bї2uЎ'њЅџ>[и7pџ~гљFJл%Ÿ…џQЪДёЂEиŸ#FЛ3оR/*МŠuнџBЇ7| nЭР{ŽСЈ—л…лпиљ№иЉМž•т'лЁЅ-}§‡юL‚СзїH›У’їl“њ~eзžOьxї MТqБэSBBЫљ&ЪЋаф•д шуП‘ГP1q9Ÿ…}Š>џJенІH DSK-žїzŸьџ ЅўuХ‰)m ї›АȘВэ Uа‡ЩК^вП/Я…%4вœaќШДЅA'™ >йзШkPПоK№ъ()гŒSїI1ь™]вc‡ч ВЌVЭ3 ќ+УSeŠс/›0уБŒiŸ?~дС9}ф’ ќgОO=JЃlтsщ|ЃОЊeоjqVЁъ}ъQрш{-еMєD˜sE џ8ѕZсѓ{„Л5Ьn"lЉVНKАšхщ&>oBŸuНБњлхbњ4sУvek# 9u#јŸ}Њ‹С3lБf#о гЋg IЯР–ѕДTаPЖ+ …šЇЋj„2u ‹kД!gSƒСИ!м`ВAСЬЁьыKеЃхz#;nЁаЄ‘‡§Т’ЈУzv:" c—=z‘GОЭ—uХРУjЕъ:I tŒL5Ѕ$1ЮфЄkLш!аpIЧŽг+т/ЁШЊU€™п—pY^[изє'з2њHПf"НЛ  3˜3!>с >љЭўьн0Уф‡Ђ,oЗ?РZq‹>:^rѕLD!vТ4MЙ U(ъыжвнЯnVwєgі?9#Й›пчuЕ'Ћ иGРхНkv ђй0§gЁ­Юч$(†ѓ7,бч—‘ЎјтЂ№Uг• Hб}GNФІ}dPgйџ5ШDoiнЦяcXПV–dнЅшZИьЊлškз\2ї6ГВaџŸхЁћЫОЂ›hОШЩ".ф]€ јСЉЈ ЂBCXбѕ§„//жOИ@ТCЁMЖ/’B‘ƒцьцЩюДДЕО2AXќі[gєVІЎVN&вбIьEJ№Љє,6ЊХzлаt*]n?§nћЧƒЛэQоГ@,;PVЧ]ВўN5RЗPNЌ5вЭнМЊЭOXЧ‘њЉPх4bœ‚`\кчСљ[н>š6вBсЏЏмcмЕN+ј™ЋЎaьFЃ@\‹kLcЌ,юŸ;јЁ­зhїїWИє&ђж=ёЯd•яOJsџ]dаеOР„Яf#~№ЩtH€ИНQЉХѓЇЧНж1_щп|SыЬH.Уй{2ЇГа‰ /ЕД+ў6˜ яCПБіђъя5Nђ6.‘,H|ѓ Зцp†ЎцЛ€h“ гЕПвcuЧЛЩIЉ†[neяŽњ8ю†яQѓ|"хРEМZџEЅ%і9e—MЁ@Vz^ь~ЪНхO‘†ЦрRn†vдx€3pщ ЗЛПt Лќѕ52ŸКn,ЉљЭКи?Ё–Š›`џ€.'нŠѕњз‹ ,nK‘2"чНN”pЖ‰МdCѓ:тŸ‡џ<оYmЧ)XРQHЌ5ЩбгЬv0жьёџ_dВjМ]wk{ŒЙT№u–5Ќd•5р—0Л‡І75ШБIрвАc@єXOџa_ќ4FS4gB[р ŸЊ^еЙУ‚d0Œџ&rC~Xœ}Р9М‡ѓЋћ5Ћ—ЯGЙ6,JŒzЄИбс/*Jеѕ8’OуšZ–›y&i™:=/ є‚y cАyuш’Jk?qЇ0‘–\;Q< яigEћрpьнхlcвGэ/„Е?HBta ТЩt†Ъ‘E#zоЇЛНм‘…7јU‹yЕs§вщž§Ц^ДEКЦю}вьS—Џб5EЭ"СWъП]ЙŸжђi•,Д К7^6 ’ йЬЄTЛ†Я y1L}qоЙ›+]Џy*д№0“еM55%Јњ_/МћхˆрЦJЇ№њЅсТЛp—*ZЋѕ;‹0dћЯЋHž!euiIk*Cё`&Ие$яЏ^qПzTАych№МЪQ.івѓІњ8Ќ…„ƒyЦ‘М:„єР; ЖžmћБrІЈ‰ОМФЕяVl—ЮХфšZ_)ќрАРКХ‡в6r0WšЮжџ^xx“T^щO‘тбЂхWІСЇЕ€#$[ІйGп(ƒBPЌЎџV<ўyІ„Ї]mьJŒЪрФкЊ.дШЇЯOгЎ(W"lpœчАЗ•/ІE–Б€—’ЙNІЇY SŽСwšІ /gИ7џ"›rяЕi№Нg-wЉnћб7юьšрX/W.ъ/-xчE2‰\ВУb#"™!Џt’vДКЮ PK-7Т7ЇАfPёЪof"‰ёѕ‰ЯyViYbooш—0[ƒЅ\ш!НL„нЯ­­ыЛ—?‹Nв‹їит•.ЮИаф ЖЦ ШТЅМmэРаH€C˜§бqbdэLOЭxпea‘pЬаžьД‚‚TUl5Ъщ%“F@„0)@Ч k№–g•vO—чj”^GэМ“XKГчDчТHю /тІ†г,9ј УL(Тщё Џ3dG”с!ќы”1‡К>tРRк-&‚ЦФF,ЅЅMыФdЗ2эd–цМYЉЭџ U1Ш•ЊњКzOnyю'Лh)w;ŒЕvwЫM-ПЭufАТ*6…‘jJБЮ-p_лћ'%hЛ‚ТИђGћсfНвШо/НЛЙŽЅœ7оА™R<[$<ђPЉŠз#tЋћ7еJ•uБQмr’Ћєmœ , ДПŽрlЊgъўSLбM0ї1Ч›+ Рј†zGYŸЎRдљmАDзцW˜дdњ€ИIкCxРBƒы‘зQ/|oюю№ЫcФ*,ЬŠB’—ш gжН'‡0FvБ"–сћ›Ў_& ђ)ЈЄƒ?r.еIwFX_ g|гbќ–т~БвЈ+|%VЗb"CГє§ˆxЭmщ;Г.ўPW(l›C 1џ"Z>YcЫŸHхэуZ$З…sAЬXЁŒrўяq_3`[ЄМŠЭEЦ0Я-Щz7Y&)7ЛБ{wдOХХ(skDђt–M—ѕІчU!Š>Џ6& С5іЁуT>­РŸ ђ•sЁЌЙдj Ё†ПKўђ]%Щ ‰зџž’ЄЎrЯТŠџЦЅЏ–јЫМšЭљЙ[т€jДrйL-kBГ§kNюѕg”~Ҙс!c)̘fžPjЭјfuУ16%aƒ‹&ўДu)ŠаЧQq-†ёђ——.зЎ7[NIЮB|˜§vх|UKhЌ&аВЇ3advmdKеоѓg­%Nлљ~Š2(z[“Њ~џcэм™&і‚MBWЃш›И"ž ‰Ї7оlЄ/QIіѕ—Ішk2гU2щSdŒCpйи'ZяњЈ˜ћkОЙХhм0NYћ ƒч%к. ,>ЂцЖ3˜ѕxщuъBкЪfv#ufсlPnPф‡{Gœ$і•СO “жцqvб]>iiПWљ№$[б№…Щ+^9Іrи.7”+63CcюЗaC^СњКєи>i`’EЏЧ1O|С:§ДЛž~ТP]GŒ!рщ%ќt"P˜@Ъїо)ЖИ8УIЂgЏvў~Д­dЋћм>&ЄфސЕзZV~ђq‡"љ=Ц”Aљl7l‡иN QгKRŸ2%Cяу–mъ о†љЮGњ"BШ№Ћ„ТЦЕцx6%ЭЙkgУ'~о БЯєXнQ Щ1бwqrЊ…ш ‘ѓщA Я+№а‹Lбшgпd’G˜BG\1Єˆ†Е‚БОљ)K™Ђdјx-Mю@О Ћo, WƒfІ€ф‘ ~ ЫeЈ.w[{/ђ№xXо‚:В7ЯБкDФХдѕa˜ ѓ;§ђ8&˜ЋЂРЏОЙт1ЧzтFМ-AAOIї&qдZs(šцi"ˆŒNfн ,››r!Йи™+‡œЄЃ_ПЂFьЧ;QDZЎъ†ю%8члу‚P’ЉРiЋ­&JЇГ(ЕБ™6и4`(]($в#TаШВ s­ДxБо//s! сeЊдчэo\"дlЛКхэœт,Uў№2„qЪђќЦKАЏФ9Ћ СЮ@ОGZљИ^Nј§’*}e>eЇGбGu zXђ;vytШј•MД`зˆ‘љџ.@оБй+аlЖ†Ї.P`!)лЛDѕ;Zpnƒ)сР^Ы$т@U&њ%Р^ач ~щpг?нєnA:юAывTМA K‰љІ-€'Онќ)п:Іy™6КTєXzmо–yњ|oДёПў”а‰n'„WY\eпhŸР§ž|pЙi–u 9к HЅЙvм=ђЪ—аaРЊ>m`)yŸ!GDKIк˜уLSаAbAЩ6Ы€ЩкYљGРfЖЈШŒŒ [чЉ}H‘ЃЛIЎьПйЙЃИvё{ Г=Iз-R2Гfd@ъ11F02ei mw—`5@­†v`НЯфEpнв-cМ„м†8^™$ѓМˆђ6ѓЩиaq"З@уЕюБцŒƒесC Sщ)…~ЛAШi-Ќ№Ю;!ѕŠ`KTљќ)Шѓй)s—,Лm9 IЯЧnКВzƒЛ‡ЎЛСњTjaи/хЈiЛч=вЄџэОЋъёškђ5Х4ВФрCл†5xcчЁf Ж ХЈ^P(e‘Іm=їc=}Hќw€Ў?ХЇН 1Fџ>Т[.’pSv–лыЏƒ№_ю…ЇsЁRћ’Ј"efƒtUOУtIbбАџVЌ4}LДQwzюыa|жъљу—вг4ovнџЏAЄaЫпО‹?J6ђО—a—Бюoeќu–жћРM/iАїюkIBё‚šэ№€=чtN{txЅœ›ƒ˜`ўвц\Кi`(6Ч›„fе~{tŒl%pJФQƒži/lЩZЛМ<0UБс5ь-‹K AqlьўlхVA”O4ТзeЯ6г Ц[§ІвЯ>P8 ьtѕ^P7(G†bМ9І'„…Ъ@й(.@ўšž.LвЭФMЫк жЫ !zпФžдY4YоžЂ6Њ^Ќ=Цмua7 ZR3уДš&№ыД“ ЋдJє1лР–ЕпNН/џzкН…ѓ—ˆQЬxС„Ь„˜††•’ѓ˜їh ]зЁГд]/ —2IhСŸѓw|КŸеЫф­ —aлЛГwTм$x–б‘a„yAш|ЮXОЇŒe. &iїяOyЉеEр3ЋДgщЎ“B­’%†з5œn‹ШЂ R›ШRљнЮYwёфР—S543)оNBНЩ;KрЮhPЛŽ†UЇяEЎcmјцЫZЏ›\Ѓs‰Ў`Лiх=NНV‡ft—ŽюZ Ѓј†•MаЪЭШП}GEнA}nPњ“щЌ |&wШБьАиeЎю(ƒ7ZЭNЛРќ­lh4™жnTИ}ИаQѕП#ЮИшuž=“~]bѕА  В‹п;Дiоїэ­‡с~ЩаЎ0+Р…ЛлТdtLjVуДсЅ8GГАо*Fў ЦЗrљz™i?Р‡Ењ§Юё ЪImмђ…ѓLъл…;УЁOг йЃЭ‰“KКз>P|х):†иY=ўƒд^ЃAQЌ•Сл"пМ"EtNџiџe9Іт˜WЅзGЂЖˆЉ X;>чЖSSл\…Z€соЛŸw‘X:ђ ЗАК Lџ#Vє;ЂЕPчVГђkf8QFЈj“ьUъћђO0њ_(`2oЩOO Ш@b?'h}›~†м4N„q2ue-чžюhˆЋbкzё№њNЮ ~НUŠ2т,%’ЪЈЛ[и{UŸKВИї7n "$†ѕзyZѓфUfЌЅzџ€7tEнj ю к-чYqО~ˆЄŠ”ZЉ3шH‰ њr“j$+pП\жЬžюkRCpZ† vDбШX[Иš[p`†D—WƒJ”ьиuGђћ‰/fCЦdхШ№1аЃ+}N>0ЖкŒїАˆЈ5ТљƒљАњ‚[sФЩT Й“/ 3Лn–ќа–чefЇ6„*˜Kw6зЫяDЫ"Hš>ЭlИі]щL„3­$CпЈь(А‰ми;$ўVў]qт DrFYšЮЄщЭс}ъ†уНIGџјS[оŽиОЏЯд`P{дyкј‘>йрO1Џтн-‚у aЎlwS`Ÿа‰ѓlДHўё Aт=в{вl—­ФЦ{dХ‹>ЈnГы Г8ЩŠАе`!ˆ/–{ј7†#в•-БdШ@;ЋvШПЯТ3i4џXЂ~cˆюœ[e cwЕ=пИi}ђ]u"$upØcн‚8`№ѕD$VWЕ`˜ЧR§c-›‚’{еZ7ќ}ТmL\–6c?­њ“oэлERw-Gќ8ГУн5˜’–)RZt,ЏўЮ6ˆ‹“тжTІєU Єш,)#ЄqЮЛЁДL†ТхX•†к‘ іaЖJъМРЊљЭїІ'ЭЎiа­е4lгxђЈ“ mM(œ1ї†wz:љ3ЙхЙ_ЋZоПГY••л\oЧ}ˆhЎЊJ,Io!M"_ЧAi:4†›\TЄупŠпбё^Я`JЦo<цєј‡xг„Н@м–: єбе3 ‚ўї 5Є3€OžxX№рФМоЌŸЇb_пї’<‡г†U…l’дж^№О–јœхИг[kZє€]ААзБиЫ_щЧ‡аЭ(ЬyдJ>жК†Њ š­ŒˆŠЗЇкg1IjљН+ƒS~›,*тУ;Rћщ‰шб…Џ“џ1А–(џ-qл› щmЇ-“L РЎŸЃ.юq,ї{єU|Zfк@HZЧ09ѕЄM­ьЈ7ољ]:-`шs™{Бћ‚фˆф О8ЕњЦЄvЕF"Ш†ЋFэлтпk­еDбЗє"tпЂhFЇќЦН њбAl6Џ…"rяIРТшІ1ЈлЫ7h3`s$ [РТFЯgcВУLoлu™іќђ—ЇrЧІwГи'fЮт<QфяГЃfќ‘G7Ту ћо–Э ™”є­k'Ы_cГzпЕШ4‰C>еR4г}Ž6:ˆь##{^єœjт˜1§с“ГCёп №Elк”вЕi#Ы>!ущ>АОАІ С5ЪџfЗb ё Ю+m~J6УёФUeЩэx–‹нб1<М/бЬЇђpЦj}“ˆОТ,3кы–П№СQ[рШх_Љцю„MЬд&3АС ЇЖM‚Њ2–iЬŽе‡ГЛР&Фљь!- JB`Ÿу§­Џ–TЌIŒ”§/wЫO6Y&zcјBщО‰=NV4_ŸP9Ј†{ёX№От2eт {N'# „XBњзЅьA%†А2§ЂчqУXYёƒ‹р<ма™”^ХШPнф›‘чSЛRvъЎж}–ЂхWчє|{!yсшІўW“Љ+€дЯM}уьцт/Ќ[‚ж‚Юњџ'…јї ?*Чує$+4н›ОсДсЬK9ЖБ™у”‡–ГфьшУ<|sƘ'оЊ}џxЬPфЌ&—ШХxg9FDўКД(q&OУћmцX§o€sљќ-ё;ЪЧ<кХ‘v%ѕ Ж/џ 2СцsЖ<Ÿmж•фОњna›-kxяI*0MЈg$U‡Ш ОЎ:ˆЊП Цд7}Хц(иИ0*РїsЧz|smБlPШ+`&4,œCєzK|чсјР‹Ћћƒн™{;ы†šж ЂЈЯDYJnЊa­Б;ИGQ_ЁYHуBћ­ёЉSЦ§ў9hNж5УжњАОFЬš—Я4%бшьP„!‡ѕRh›аѓб4RјьіћANC•+ЃнУћЗХд СЉjC›j кПхІ-+t“ЄRвќѕМмeиy~њnU<н€C^І,ЊРНДфM|~Мф›чДтK‘„љ„N”їПъО~ЕЯ8Цv­Р„|3§ŸгœЊМ‘SЎЯЅд“пЧГЌыј –c5ЉA{7ѕЛЉй“^џIGр№ЄИM'ѕ%)џиЅŒ‚QЁjаNTv“ФF+Ѓћ3yУІ|FŒœfБM‚~XgоЛЈ 3/иЪоlџY\x5#Р”ЏН]йкNћѕ9‹Їщ1aљ2œїj$’шўс•Ё;Ээn~Я™ŠыIМяo№њхqЗTF˜0ЄYbе*б`3Ш?CjѓЁ*ОцфчИІD­7™ђ$hѓ~Ў~Ј‘Ф\pC@Љ+ ш€_їз—Бі—9–Hfnњ­ }зI•-(“ФУыˆЌ ЩПМ‰MсWн‘b‘юЩЈтf‡љ(Іm)!аRm9.‹Ўнt~ПPœ…ђ`чhXеаšВ’ИрmUNЬ{Јf$о”“sj Х”tOd#•LД"m`qMДЙ.Ј‚FКЅs„4‘ыqюЙ‚жў€$гюT 0Б’ЏCžЭR0TTM?^мтneГєnмЉБ(МЃ`yшnvƒ‚Г ЌмјйШ2%˜ˆўf(nЛеŒ)&| Юўˆf;tЙ HЛъ†Ї'ТК‚с=СaSєќkѓяЁ‚3d"иЙ|S Ђ<лG%8Ъ>rМЬ`У ЈŒxu~Я&aжGШЏ1ЧЉџƒ˜R“m­bћ7В’7…яфіІЬ bgтvqтћ“СЌA.0п8со1–7ы.У5е@лї7дЛ‹:Lœ­&—йкеБкЕ `­WXЅЦqБ3–’f*ŸХдЇЅЊZgˆъHя"%~ОGZН-t@ Фх™œ "УЬљХšn 0jЯскбМђТ4Є'—Šх№xўмIгбЎ…ўІ6?8ађw,\JРеzuйpsѕу=ВХЛ§DТC`‰]€y;ХЕоЪ|=§А'D§’ѓаUЋОѕМ†g˜œЮЄ Š7]5*яv&MTЕc:yœŽЏ…ЁlmLУ)§xВ,рa lsњШх„кФ? kЖўш€нђ„ZbЧvБьNѓ=]ЏшТзФЏgG`j7l:OУ]*јm4њb6$mƒе”)j…ЁыгсбРћ8щ'ЈштxК2”П6ш- уЬЕИФWмТ€ 8PЮ\/šеYЗb\њ(43ЎЂѓЦђ\Д/1ЄЬFзш€wД›Їvы~>lшO№‘NдЂ+2Ц=L*„ажЛџ ’%›4&}йk%š- Фи’А1‘žћ)"khžY2gWъОјˆ`cџ0Г8Нa'&УЇЃ˜ +ŠШ8ƒр/J­ЭФq­XzБЙ!!ы­ˆ“Y^сfUW)lХьUyєjЗйrџ1S1ЁЇТЪГЮ]ЉMЄ%К—a"Ж­ђЇa™/ƒкˆѕ•.М№$cЎhн˜ кRі‚ХЬa,pш eS L„зŸ•7AЄГЛйž№яvyыЬƒE[Єf•E˜„ (њѓОЩХйkсfыѕм8‘Іkџ5jŠ‹сКЉzvЯˆ|ОўU/dfД2^ё)j~nЎк№ѓ]џ-—ХџxЎ.я‡“ўх3”…‡о/уœuћЧДзwтoщЁH”МW)Пњ#ИЋШ ќ}В/аa2Юmг aЄђHAЩъК;‹QzUђЉ-‡=RЃB­'Н‘Srі"^Uз`OАкЁpЙ]§EдГƒи›1zчk‚wГЧ‡8Ќ{ъ_з|kž!нЯв—ЛцjЖ…чБ˜MДЋЉчX—єХ%ЯЋЉЉL1!~nЕƒез>M 1X5ŽДxA‘‘ќkљ,мh’ќЭхЙ,ђЪЄ…Єи%œоїјI{ГnЫђџФ<*ХЮWрЩ ['“пУ—Do-шyjwє˜iЧїIдлMъKаМбцAьПтI­Мkˆ!лќ)b–Ф[Ÿ”ќ|uтkЈ;;?цsoцWe3rvkƒыёJЈŽ'Ђ‰4ЯhLѕj}_Ÿ ЋЉQтф‚kэŒзЅ{(€cЪ“6Qс8J№У-KЧW;‘хы…tэ;˜њЗ‚~PіЄvоЪцхЊŽl)ъ_;#(§KØ?НЏёRmm:—6Ј@Ом2эмє24=iS5Hw”Q‰nб’—ІЫоѓ7<:@lqŒN_KлE€ œ%+Tˆ SьІЁ#вО‰ž~ёЖP №шhзЇэгљR‘,•ЂгDјѓM§2ihŠosђсPBТœ>tй%ž КёАЯЊZ2Уџ1јv[R0Q™еБ“ЅD’pСkхзюиZГрЩС&–i ~УyO7іђ{ФЕ+tbЬYЗD9j€ˆиJ‚AxžJ„хиэYЃzz6uєњ%6DмЦHœјTѓ_O§Xђl+чКѓ1‚ПѓЏLћя/юh.z"Vі^-ˆН0ЃЎГЯ^'b„xвєR|л§нU]V4ьњW1Асъ-АmЇkDO+\nЇG:­–БžNЧЇx™zњЊ.№РуЯ‘>v/є8я—WTQ ЏЇеЪшd=,сk%hx‡xџŒ"ђ,іЯ(d]IЂеJnОV0ДФЋИ)ъяRoгG27Œ–<‡Гл\Ю‹Ѕ6ірaёџXЗТxw]V$цтреє”>t:–tё„ВєнЃ _*й™еЦKnP%пЃЖВмЗ6:‰Фt+і^а8єІ7СoLэ-чзОD-ЕЫр&д0EЩ”ЦTŽъ ыдqЏџ2NZ–Žј–Z†UcЉ\#ЊЦF9С€:р)d0Ћёі_рš•+lxЊœZ.йЗЇ|Є—<2™™Kе&.G~МMVˆmЦдoЛ*nŒ„yH˜‘с&Љ™_.jNŽ%€ ‘ЯПh0Ж‚[‘є]ыNCOБL&pму* @*рНЫ"xїЃ•aБиЌбРџZмИtTRЁЛx=Tў%, УђBЭ~е І2івХŒПpђЯчЗX‰0vІ#ЁfQЄ[/uТбTnOцB&)s‰^"—з9и„0Ює–и+ƒ` ўёЅƒ”}$b3xOIFY!jЅЕgрт.ЙљK™‰–~ј–˜Ђ:еˆРeЄ#U˜Jу+ДПTе$ЁнФктOёќ HЇ'уЁ‘$—v'qЃЦ3œЁ9(–П*Љ!‹vnоЈ\Ѕz—Е<0РЬ•Йє&у‘№аcl/\5}X.‘Ў›iв Di.ЙBџO0ЌвцЛЫГлU_6Ю[4Ф‡QmRЄЈ ГЕГуёлЯдЉцpuЌФЇ<н+^G6FУ>Юi№Яq˜Q}žpŸ Ю>SФл”§џ­?л.7({|JCrnЛОМœnПnЅnёTтVШ§№}њGhQ]Q›Ё‰l%ж‡ l[­Aе>г+{п§д­Ђ^”RЯўA†k}5CЌ%ЈџvКяъЗР+РЂѕ[–ъцh‹7dBХФGкz%š#–ОŒz:*_cmЦr$,*йЦDиќejя—1xЭђFœ\пZЅDІj=ˆеБЦjm—DПй!Ў…>›zЈh;FSZ(€ётЛ.vGюpžї­^{7ЈUQ?Ai…fŒВъn“ hrьcsx…ˆёGБЂћ>2йЈTˆ0?ТSй7zУtƒIJi.‹ёЙˆWжЙ@Е–“‘ A_Ў1`РЂЪНЕј(Sь<ё‡ZXЊ{Ѓ#Й‰F‹Јi^Џ5тВЌ8 с,9џq2цnч;Ы2K-ЂЉо_ќФožА(щЈjн`d&У}КЁйвк№5ЧsЏNR>rЊќ.;>TРаˆ*Ld%Њ=C*Ž,RИvšл„—fЗ—“'яЯџ/Ћ‚“Z;” u{F“Ў=лoHz›ЉœŸ>„ЮWГJ$ІЎЩя/Ёч'н4&Ь„[žђEЭMЩ€Ў)Tr–И§Ÿнb™ ˜ЮmхќіКz@ѓ+еѓƒи(ЧNВsa”?Ѕ..ЅЙdзоtŽш]Ш‘иOышK74[ђзюаѕ",Џ,UWi4ЕZ ЂёЛHwе Ё…РkЃe•…зUœy“мo№/єO№S†фQdр+ШъмXЂ%`Ё=cгЗ}Z ?|HнVxиŒe!лќЌТЩh”œ›Ÿш0nљВћtЧ­YzИrYФjYŒdг`H…Hэ}‡/†И1Я;иС€љБgM]*"ЪП9ux6=фšxFJшЗ№T.ЛЯ5вЧФQњT ;Ђ‹— D0 $.о–•ŠЦЗщА+@§ љђ‘kkHЊэбо9шВFfŽЁ,ChV єЮ?§œЯw#rѕRе~ъ—Ÿ,Гk"F—…ѓ„tї№п­CŠђі)•k9жtœ#Жlы [*j}rЙPhF~ђкgžЕ?Ъ1)IўŒG,ьi ИЇtBRJ7˜&uTF_ыћЁ‹EгšЇћх§q1rSїI(—ШЙw œУэШП„Ÿr sЅ†МОіОБГЏOЋ§wЮ9Эƒа0э2MнТgѕgхЉVиђrh8§2–ZЃъ6 даВ@3Й8ХrЦ>ТDуДђX‰цs !љЇc!ЫY Р:ЯgПУО>Nt8dЌhl†’{—aыїBrМ™ЙPЪ|œшG!4BП5@Яд/Ћ…žŸаг˜ГяАu6<‚ЯДЅЊlП!гб( Ї{В;\ˆЩˆq":ћ+kчёwqэgdњмДh2Иfх‰lЊmM{YляхJџm§0йpdZo‘Ас'жkб`МЋ{б=pЛ? Б’|V(xХл–ЭЬиВ†—а™х,Њ*с-PaдєLЦНцŸћu˜јвђ”§КBт}і­“–гЈцЧ П%8Ў9cФ‚МЋ‹сиВAр8”ъдT„юУ3ХPъю'ђпъ:ВbъР›J.УЛЫlOКAєЎHЋ Ь’Y',КBаWlгЮ ЙH͘N с-я‰œ К <ЈЙ@{ьэЄ€>KX„Ф.Qw х]YšmŠх.і6‘J*Ињ|rыФ‡Г ‘@гќNMDяЁh›ФНМюАЂС‚№ЕМrЪнmлdбXдќ}Ž%ѓсљ}‚№qлІ|‘•&(pc‰гЃ3qUЄ6Ёк/w|ѕhWl4MC‹QLSЇ–мBfА=ѕšZЄФњБgVщы}ЁsтlъmFŠ;`pŒ€ƒЛM/;K,юЋRЪœ|ќdњЏлV%АxМз­а7Фh^ЄiьA8иБџ.rCkдъŒ@0уw™Yn?Ѕт#лv gќЪ'NцВUkЩЊKЂшtЪЙџrСАќ6Щ4г’…y4ѕŽ,<і!ˆB?М‘ ё–ЯzйўLч€‹šпdb4pMЙ"Ѓ!m‹C+ш‰ГшЉ—$ЋQя•Чг[ t-њY—Žcf%‰Љє^˜ДѕУ"ЃWИ6єј‡#O#‡К‹—лžЕтЯ1q"(Š˜З{MсЏШуѓщїШ7tНт{ЫЉџpС €8gн:4зН7“LGъгЛЎPPЊPф‹:йjџC‚ЭU0Š€j ›/PЁlџ;ЩдЮCџ=нNёZ(Ÿ0-З})8аіјРЛД‹ЯšЎЪЮeрУˆnцАЙйћЃ5б№гіИƒЕ˜wE;Pї эЛє€ik–jR™џ[N1§EМвга‡.lцП0…•иЙЂЏџ%'>Ц`ІMЋ9нŒYџ@ЗћT!Ф02[q•‚ѕ СQ3XС“+œ%Ё[•sдЄ| ШEM'fЮ’,E9+ŸнпFоЯАQ Ш†ЏЃЃыьэЄ[Рк>Ф"ЈBsВ…@б#`ђ­dP†&J"bч уњLўфt `вA‚‰\;ЅЯ€цСƒFч&šнСLzў-ШOШЄЫі,YMцЕ кЄ‹/щ9~sЂќ‚Уо‰ю„1kW8ŒЋмD9сF‡cћэ{ђя#O№A&%•иМ`єж–Лїbiцuн‚}!g„mъ#; ‡Ы@!d.зо AїыоћЄI XЃžX„ŽГbnћтˆoрrfqр"И=ўSkЕn{џpщЂš2ї|Іy8Nљ+.І8•Ђ@žйюќ]Vvяэ­<вˆЮ Zв кђІdЇHоwОњыi.rђ\СE­TїшcТCўш\-DƒEQйпћџCSТd чіœY_pщ `рЇ­"]u’?”UрцЇк• иЗћ]э§ЌПћџKJ€ї…ЧКBлІМїРЦйь@Б}ПТV<7ˆу@ŒэЇИWЄ–v@xC“ $ѓм›Ѓбо“I…NЗŸHВ„L™œ#'њ!#;voШ^ЋЪќцdeЄ§1<ф0GеЊo”ЇŒeЇоЖoŒТG9р i8Ь+rQ6ЊЕьhрCиаЈБЌxVЖъЄм1Ж(:єЩЃ -i—FA)п{‘9X­QЬІвЉЋ-•–књZf#й њ+ уdЕЈЌ[f%… 6ўLztё”-vкрgoiаЋ њЪ!сщ•Х`—KюеЪFЇШЇkp›M5, !2нB5в`KћщйхoД5A1AЁ&;Ёш§~0'сЦ@щSзGR™їшЪМц›$Э[ВЌqЫ‚2EВа„~иEЄЁzу'/ аащ[=яйAВ­‚эCg ќrф№+е‚цTФЎmэўƒ7“8ЩИРЗdѕодšЖЌщˆ ёшйєя0§БУD3л‘йЬkeкМ›н=Ъэ”lП=xCж‡Нž(ѕtbBJ xо4|W‰жѕFд‹Šб1S„|XЊЅ9zœŒvŠ~ЈpЌ`”Дщ‡’‚иQ ЮШRАJе\1}П’eŠnПРˆKšЃ…ој`х4’UЎж§ё ŒЏtФOцЭ-=ђ‘h%m‹§.\…Хc…9ныR=]QŒЅѓЋk…‘ХЫRr1ŽH'ч€#Ч4Hž’Е§:ДDЭФыDкЈуVRџD tфѓ0Ў..д~# —ŠіУІ3T:;ЖІЂD_GP)Fс‰;впчHДс9ёшЎы’ШQ–[#ќ]а^ЄА!1g‡ЌСhFиЯ=Џ"№ЙЯюзgЦf.(Ѓ\џ“БЏ]СюЛe YК% иZБ&Ž5‰E№‹Q&R™‰д5К€gЫ‡pŽЃ-ЧSЦCѓ2З,ўh[f’CћЮNэtПЃђўОоЦ]j4E3nKCŽЅыm9oъю5Бд-LуЎ7кЉ†™– :gŸwižЯ кe$Ž*jb… ф–ЂmV`јPj†ях"wdвўhœ ™нМeм<љ>.иЮ‚нТрiцћ–SЯ‡Юœ,5˜,?NЯД…BBŒŸЦfцU{ѓƒvW…‹Yњ“м`y0›џC”‘4†TVџхZ№ЯзŸБщШЯУ8ВщСцbŸЮ'ГIњ*`Ÿ5ЌЮžзљвтnеПњhGDхфC]€БhфџeB/.dя†Ue­ e-&fgмГ'ўZD—Љ?Э i›г  Ѕм–h€{hžР’HС3рЅ ДRк :ЙЌШb;фcДхL–RN&}ˆJM&GpR=ЌgvКШрћGЌ,ыH>ё-ИЉBuRљ[bяў†3OвХўvмЪя1бMАЦЩуl*tЗSG6O˜ЯlАсЎЬƒп№R‡-&“š'вZХу!‡J&­Z:>С)м?––eй•„yxФЖХ ЎzхТвМ9]ЩN[ЗЋ™d/ϘЁъоЂг­aЪ„ЋQл џfšЋV%Нњ2ˆœEуzfwПЦ}R"Єjєщyїn—u;dшёU.18єЧ™ћЋfdХЪСi~=§Ш9J\'x “тЎyЕ›О-‚љ%Є юо“D-ОјЫŸ'э,•*Iу{'–ОK YL\5YUЅ[lњЃ3гЅэжpА”'yfTгsєжŽъ*ѕOЖ<РмzБН#я‰р‹sЗ йЂ‚биr ђ'ŒЫлзК*cЎ Šт>БУЗсџr8‚ orЃпдЯjЛёЗљsTП#‡c6lbK‡ Щ]Л™пшЬh*zнciD“ПšрoW*лы;єmIЯ№ЌЦ*3ВšїсЋђ›Iа6P&Яіж’ŽrkQщS4щw%#фVІЃЋБЊK-2Хз{Двџ(!mі1xБЗ №wљyм^іп?NЈЉ8•XчФ§Ђ:А/ЩxёўА ƒQF9эЗАжПZѓх>DXО5dљ)ybCK–вjkе6_yŒJJ€acшY`2ќ++ЅNЎNšЎўi>CувfМ*|“^Lя:D€ЛP§ЦТtО ‡ІЇў-`T‘0еˆз-dўх$ tЁ‚ы†‰їG.ЙCу\Z:ьŸХ]яJ\ˆЗЅq‰еА$жЂWлЪ•šёj9b­ЋОZр€b:€ьР^ЎЋSсvЗFŒє6ж№З1ИBјЏј†Ўмx{fY[m<їм1ќM–лy<~ЂюCw~3СєsR}œ’~p ьш0ЫyyBbИт+SŠНа п тœЉBr)р = †ШИƒ8pŸ"Е!Ч)Д„x \Ўœ‚Sd’№ДUьѓЋлmYžЁю мbX­Ф чHNšFРИKМЁz*SE…РE…јBчŒ\Б˜' ] 3|ЏasБ-!ѕ UЄЎНбU №оi€О~яfыЂFGD€bЖ[Œ+#.ЕЊxяIкђљз§žЩIŠchТд(‡žаЩ‚ЌIT3ђv…фїіQkMвXћХšЯрћ"ˆ‘[s1тuУјЗLМю&СЪWP­› ^`юФВ еПЌŸЕД–ЧЕзм/оiVTG%v‡У6Ф‚O№чДWУзџФ˜ht:A} КІу$\\˜'ƒ„kзzœ!uІgЖ1„tљyЂd„Qэ5ЉЖ:ŠёNˆчќљдŒžП0Ющя“9у |Ёасxёљ=Bё`€шƒ/UWнU‚рƒ5д}чн†lЏћт˜Т§­ŸЭЬ…#х@) Lь 1U ‡Ÿ*jяб>ЌT‚їЭcM4Џ­+AвїПMЯO Ќo|†g,№ZО„qY#Б>І\ƒЊ‹ˆ•šјuшЄёŒLЛ ї*Tl‘lСFг”/e>[KсnUмGБџBы'cCрьiкVЖAі[jв~XubЃJDxLѕЫ дkdЏHјhъЅьуіВ(Пh2йчс Е$пKТОзчO5FYu*ЏўЩъ‚­GЛ‡9ёnZИ‡zTАЛшdъjоpsћЭЇŠiтАаН-б(‘.K›я˜QlЮі4оїѓВ&‚SћДЫ>Є–йЉ ущЃЎfU1ю:vk;H#8яЪЌ ќfЎzШW 1- лл u–oц„бiв{ў7”ЖиJЕAэЗk?Зw™QО0”ал/мШы-аз‹)–І$ЕЩЎudB XћЖ??T,šdЅL`ірЃ„*&Р“uё@ˆ sцЌџ–ј{k яЎRЈ~4W\куеlz7ŸBАдбжݘЌФ§Ђї@рNРЄ!eоzŸеўьnЩэטв# R’Ќ‰Eeї2[ЊюAг№Ии ‘S Ў‚ЎЯйIs V=РЌXiнзљвБш=ћФ8јОMZОd!ЄLjѓЊФКhђм#ічcЅŠ­№~Ћt —Йъ €ФЮЪ{ЋЃщAфѓ3.žє\lYзOŸсEбUњES˜ЮllטеЏyhЪЁ™ш}ьЪтй“MЋтŠe40ЇoИwѕ­}^„kўWžšg?‘СєNуЙ{гIХh‰ћѓ 7ЮћS иsfѓВЂгЊќŸ…ƒ›Љэ>X•ъ/ ~dgДЉbрx­s]‰МfфŒЈ'snvА0 :37аt!~УV„ђ]ŠД#(gаž ЂŽ‚]šWŒpм,ЊчДuWѕЦ3šБŠJюnёЭWКЭЬ1Z‰ІeOьЭоўMѕР’3 фъ4RŒјтДБ(мёе Tтk­ёЫƒ’я- LV€–˜:ŒФг—ФмbрЩP7kсѕЩ•n‘Х§“sƒ\a"ЯќЭзNбТмѕqB•QU8єWiщ;й.$кЃЫeY–Г ': Гџ ащzЯэw‘ю56(.cІgСєЯš … пйtфqœƒ.,)Џ§Ї–хЃЛ D80(Дœ?eјЪ~FыЯЊЦzќ7Ч†КžкЁЏщ^їwHћУц ”Lв„—ЩЌjе;ZШЄJМFъѕ˜NSu~Иьћуi,…ў гЁУŠoэGфВьЮђЧп+Dѓ<оЖ–ШHJ(–u ЗoQ<IџhрyћLNи=НgBшAБ[eћ› рЄХЪШBZ>ю%тЗ”УK$Сїl Ly/BЊўEЇлЇlŽ]4?ЄR,GІtЏУcQ9‚ЦD|\ЈЮMJ‰fX&IРo?ф Чaдј ƒ,tыЫV)\pšmcЮРЂмœ{ЦzхgэgхsgЪ}§ЩtяhёьŸзщ0Ё]oЊ†V%€hsо>€"KVбЯ,ѕЏЄ gё9QОРтsъsе™9хуЬtс'.Ь ТšhkЗюіэIXЇ%БнѓC—{ѓa{‰[элЈіŽшM§6љO=-цŸИ hiЖ@Œ„ …5g,huъ@Š­cтZЂVЧp ъ!oСё‘С$пд=ЗS–ЄІЎ"ХН•нEŒ}.–уТзЈёa‹ZXщcspM%ЛИ–Њўžd–aЏl<Я“{ @͘Tљ%:Е=Ÿ“ЦN9•qЮ'Yѓˆk*X Ц”јє+п3’ФЁІНŠc@iНcхѓа.Й꘹lmа‡Ї}2№7є2b0!абЮвр# pйЕLМ“ь~Ћ_OѓМдDA‡Š %е$ХЙїSEГ^чVЪыС–$3ŒMтoPCа’žV•ы”тne№a­œ$ ЏујЂuФ‰ЕjрЉYf p&ЇŸ‚"FЕќUвd_П†@г‘ўЊ}ёЖ˜TњF:њlFћ‘iIoJ2у••cъъW4Ъ=Z;‹&ќФ{нџkчєzБМИ“$'7OFр['\c‚”Дdд6Ѓ‰›+8Ф\ЩvцЁ‘TŽtЄL‹бхЛ}nўИ!Ъ‚ьABщГJ__7­dЇв"ЛwЯГ7ЊžqЉћf=Еœ$ЧсuмДX`А=Ž7кхQюŒ=Po;^ХГМ|IљрХ№Р$рФ]сkNхl‰O“95†*}Јi{IђН>OмzхЅяЖ0mг +ьJwD(эŒЄКš•­ Z™тyB5šCœљœбКІ'xŠ3б‰].Я–"Žn6СЖ лн›FЋH/ЃЃ…Dwј)U`26єŠJЎ-ЫбфјФзЛoXГw.ZšМПЃч„кbС‡№ˆ„›x‹­вшу"ЎЋэЛл’З7ѓхтŒ1ії6c Н‰œмбўщІpЄЪЂЉѕ;’€жнœ‘ў~tЎE|0НЗ!Т+АЌ#вГd)Е]у7п]фВcЎvSMwаwџ8ЖщXFoš*МWšчАщкќ ZІКxЗЛОŠЋЊДR€ні…Ы•z8S@иЬ… пр‹ЇЧNэ†,м–tі%“7”cЇвћ’rB58ХнDЌШ<Д|rр3œšЌэб˜юЊ*аЦДКУ<ЦС—В‘Vz4>ф5F%К<Ni”Сљ,Aт{a ^EШі’еfіљžrдˆpG ЩЋъмТвЏYША*{Лёнrп:€2Й7^Uг@ŸЅЏ™Б‡ŽЃz*:н4гпp”Ž‹>+tЦШПщ=даЋ-ƒPa+}Ч”ЦбOОЮВ+УАЪq€6НfщдбЖБeƒў@вƒЩ‹o$*иIГѓюљIaЧTРЎаћAЂ—7eЭsщ|ЌьOToШMƒ.ТJ4;Ђ8юЁžŒ`ўё6РеиБЎœ‹` SЙзŽдЈш ЯпPo@€lр+иРp ??()Х–йgn(ЩhgСЩеWoПkОЫpOGMК7pŒвX=њ‚ш`ј.Яя"ќ б.Ѓ^тљ’уV ŸИ•jL^ЄџЂнѕЃрЎРЊNu.qЯHŸй?pцЄQат!…ЂО/ЏgŠхГЌ$Йx[цaяТjчOmдЏв цU„)ё —a л*‡Дˆ'ѓgb Џ;h]FззцдŸ­ќщOr‚mс[пT%*™@в #)OоœP\Јc‰УL4г`tМ3 гнQއ:qXp;Щ'ЩюLЫИЖЂ™§Гœ8ЗЖUИЩJК™вKœ&<Ѕ§ О)ѓэЖ9pЅ8ўD~AыtzЌЉK х4ŸHтZp9И0%еЎКїƒšeeZљб›tfхљ— U‰XАlЁ‰K•m№у Юob“ЇЈпS›D“l­;ьpŒžєйџo Eѓр<ŽE(­oЖжЉ/eg™',ћd kо&˜Ё”yЩuЦ,ѕџD™ѕ\CѕрЩјˆБў4ФпіНЩ~7Эщ1rцL ЧRШˆˆЛCxжrъp%KЇД†‚Ъ$ ~Ќ–р(єо8›PењН…Ї ИФ?NfЉ\DaЎVŒFиKЌkuцмAJ"Тkа" ѕИХџmM "yжqw?™ Wz(ДݘЯ‚iЃ‹6dмЊ4Б Hћ†“А6ŽСЄдТmxiЫL9тbЈЂ3кc3њрƒNdѕdCгoЕ~†’’ˆј#ів0‡.Ћй“nа щŽpЁ„ю^MЙ ?ŠбИЂЭЎ›*Ћ”gJ.‹‘fœFЇЌфш17n5‰+ъ|ТЃhсdР1шžœ]т.‘$DŸИн& yціггHѕ Jв02?}˜:SМ’[%JЫ€§@Yй1vЛХŠZє'н0R8r/qB&dМЗe>,№™ъ\h-;џK$(и˜М3ИŸнPЃаE5~rR›yБ’‚НЩˆo 4ЊЇ—rE” €P‘6Ј FЗНаЫu ЎЄMj%Зt=/‡‡Ÿ-r,!cwжТˆй!^ТјЙЭ/Ъъ–лљ!€&гƒy'[Ћv]“PДп7їiѓafvЊж‡ы->Ђ†Чeœ/$ЕПmћјћˆЧ.ЛH 2єОєаX^ Љ@uEdЋп;ЇMЙГЄCžт0џRQЭGn:ўиИтФЂ*хŽŠбRœ№4Ѓх%<3(ЦX!VЂpВSW>­Им4wxВнДЬUŸжЫltвя.L*Ю›ННЁЋ'иzˆ=. /тЄЮЁмkЯ]ѕЯ~i˜7FNkЩИ‚ uœEšvџя{Q‡n?Јљв„тй- žЙ%;E-~џAŒњrKfyд^”уlлџD*хŒMBІ~Цєђ*цY\пzџFёч hsцf”Э­тm$FUCэіЅn щБзЋѓ$нYWьyjлIRQі2жЯЖ—(kZЏTy*КУНСВЬЉl„ˆ‘R‚VSŽSТ5џ%,hзє"чХ’х Щz2=ћ?њ`Ю ци}xяђŒучbМдЦУ8аJ FЫkЋ V­J„РуEwћќЂЗIѕ‚*nDљ'м\(8"кН)ННяeЉ_‘„jˆМАŒх€І‚а'fю.:ЩШ|ЖуМ.„˜ђhК9§З(Ю”ЕAфхрa—#›-€c6еўіlє {МOМЋ1)šЗ*.Qojq bm sМЏ#ьBі[ЋуЃЎќќш*Б–†4й—‹*‚йЇ=бIClУБ*Щ{9РpFідMiяb‚`Ї›­—VF­Ћє–t_ƒТ}щЕњѓа„№fђlЦJL#жвџFєе“lЩЖВџ;ЇТ›ДЦMА[жЗQэ-SЄ>1ќsШќяЫ9Dюr_sўС!Ь€аfKѓkt)ЈnЧ Й&"шёN(œСY~œх>QЗѕдdCю“f@MЖ:Ж­ўГWZКРэJЗc ШsДwd"w: z(юtПАДпfX`еnл^<@œ кe7йƒTЯў’<ЏQžUiЌњй‚);QАŽBИlћ)ЧјР‹@bEz“жиr G8kGtЖЎ“9Wж*†hY“јатР]žдЦ„=љ^є”ЙыDЗmаS…lЮ+оYб UЎгЅoТ\Ы•Х‹Ьфr—ђ0шLЋьCЉŽ[е ДќѓvUЎЬАВ—œSќеfA‰Аhe-Ÿvm™инЪо“егѕЪSзщЅxМs/Пјƒ_џeШ'i—"ˆV§bЕ“і,Mژ2UЖѓяцяQm9œч[Я›ХB0) nСpРЫ­5ућЭЖр/n UT+Љлž|Ы+ŠbПЫ(‚Ј Ы~%Gqйt’Љ…™ћ<ыq0!нqWЭ,ввЯ‰Qc€|ш+pе €Ъo|!kљ!рЄ'Њня$|ѓш р†яw(•b€МЗrтh+Y•аd‚Ol,е Cцo~їŒ‹™e8Ѓ­šŸ”ЧЪ•[Uƒ–ˆ9ЩAж[9C•wє’ВWЭjИ|:.м9  jOy`WP§ HЂіё&гBVŒЧн§ќ э§ŸС\œ›Qћо)рд‰*4_ .`Ўуt‡MІ6vЃЧ ЖЋs )w~†*жЏ7xђ_ЃЯ™@­\ыСю\hžэxЁ6 т.тяіХлU8RЊ ћMмKfkЉє‹ж IЇEЮгŽЃУЬE„ЦВk—54й^ŒпiдPо?Ц GНEZ еа№ая ЇoA+ё‰9!ЈЯк\ ыЌ}ЧАШ{yBh*Tcд?тR“Щ6yА#w)уŒ8HтsrŸєћh>ьЁж ќЌ<йІТЄс‘.эhXмёВМoAaЖеl%і0рi-ћ &­нЃГpЊMelЗп—ВЕWЎ2ŠфGю•П‡T–GЙў_ОуП6-й]kПDЫp.cб|ЕИ*”ея.rJѓАДђі§@u:lІХ“Y^ЎЊqьG2жРkЃ}Ѕ?ИбЇ6Ж9‹ Іе DњЇЫ<щєlmѓнь™a—iј%l}6^Р5НvБА|Ї_Q@9M(BЏ@ђФ§S‚лqя4Ѕ–) |тUƒ"BOАн­7ЮyoZs‹t~тDuЃПoi>Єз*›fд€96‰яўzj%JђђuZЌX'*Ч:ѓzѕs›ыјˆ›‡к-И@fнKЇdxЏfјб™нчЗš$)ž˜IЕO&-,ЂЏбя–БЋ9Z™ў„ЉЪугЊлq ›$YUm щ;™ˆ2,žл'ИіœI%}u№*Ўћ6г9(етЗыуйm‹1‰џe`сƒЎД.Ќ!ёЭОцЯ_„кj'8p1ьјеЅdз~‘*v5 ?т\1˜X–ХVХEЕ_ДuOž ……X&Фџ;ќіјqѕ& іўl‡žPИмШІ+тЃО|циб—B‡ФY_ч*~ =?!ЩшьZЈnД№џ†Х†_.Бwѓ>oЋў„–|ј7њА!Q)ЄЄ‘LУx5ЛБhЅ>#|я-h‘wMЄhМ{ˆ:m'2NФy˜ёЫvчЁфoС,њjŠdЛуЎГ))џя?еБI‹ z#єхІїƒџu^jМі“ŒхлuЩЁ:ˆч Vџ"].#ЄГ?B—“ eSэьёR$€Kjє7SЅžz<Аюb№Й%‚WъЗ cM?“›ћ№&ˆœФ|еЂЙЯ-ЕФ†КM{Й ˆзЬёў#Ап;#Иї* шчёe‹Щн/\6Ÿ8b­іЩ+p3„І-&,GQАvЇNЭр|в~SMіЈ)2 †Œ‰N xЪѓWтD:JЉЕfЋА‡{Ж)я3вЇЃ:ЊЩЄчmг7љ‰гёDуcд_zАfŸФy*єЭL ‡b†*™ИІ\GС1‰X;WЗЄ’Ъ6*œ:`3ikїФOллЇDšCБLЕЏьџI$›з=<НРЙю…ŽЂа.Ќ•?mЁЉ˜[ћЛ—П{і0OН1‡W(%ОƒСН^Е{8ž_ЯфЧBnŒ ѓкЉ#ŠХCPМšЉш(жpЋfщВ;Ю*ЮЄ›ЌDЎ5Š5Ѕ р.h‰Gj{fСЫИўAžћлЩОИфдЦБ™h3Ія9N[є03К‘g­є ;?5g ыЪOСЪLš"оЪ•бш2=0‰o>ŠZ§ ь+hі”Зљw Яёp+ітВmA[GШ ŒЬЉГ8v_г=‹ШЗXщ,зnЋP\vеъŠ:P0#IŒ^œэпZ!ёо#БGGƒ&ч9Х7И9M"YЦœРˆ@Д*cІrє]•є, a|<Ÿ5п,хD|t@;Ѓ–`Нef§cњbѕ’Јгє>A}Ююњф4Ј@L8-ŠhО”’БЎotЛj='5?5=Йи4Ё†Ÿї0bб$@Й`xѓ_єєщcАЙ8њ{КД|љzНЖDЁйžœpёл(уЂоYќ eQMC†lwЌ•nZІEюЂ№K?%Ео—Ћ‚UЦБЛіСиvерi5j‰3•9KмџOЮhиЈUкOЏа!Ж№бщ%QєvџYЎzQ›%№1,ФKКИAІФeLЮ6†^К№ЋcМє’l&“!ы†ќšЇњHм€ў”OН!ЯclŒtТ}ўFiФГI<ŠРTŸ^2Дпъ№iRЭ…ЯJK*ЦВЃЧ‚еUt,б@NшMuЋњ(=Яs}’›7ZюЫЖв]^Z;ќX˜UЉЩjyШnнЊi–ЖФТЪaЖ–k@_рn‹§ЩгОlПѓ<\к]3жxЙ0ГЄ3эћQщ—И˜oЫLDЋ\№2^‘ќи‚ дZщ2Љsлžжs2эдЩк`@žЇž1ааъ‘ь”YЄнA—јŠƒфЖУ(xŽŽ6ёч&йДgœIь7Ўшˆќ-sбќ ўЬкЉфФžF.lїА"ЈПnG@Я†—ФіЮё­>o5тбеЦўŠoRн hшU= 1zьtЗ;‰дHи‡о!ћM§мol№›5*вг: ЏЧ'Y0р?^>h ОrRTsњ€Ќю˜~’єi„4„vПp‡Ц&Н1Ш#€Gх@їsЅ1N*>XЊ9"ѓ Щ7PЛmи…?.{Їw2N—ƒ9ьБy?# РgA|гВVuБuP  Ф-їОгЇУј‘šDјГWК;­§)V#ќ‚ІђжOЫМДI@GJœтеtЊu*OЮ’‰<И-wXѓ›ЋLOB=Є3сlф:…№LIVщЮH ƒE\}]œ5 Њ ”wиїR§€ШрpВYw“™wJeпUюКKєйЂќŒa(*†`ŽQV‘Э‰’ˆДQПЋ‡Л&;‡т–MHфПzKXЖћёШВ\?РјЭxuш=C—bMtУœ!~4Їѕš Ъёдjq)r*Т ю'Гd”E%sUЗЁсvp8•tж›)ыœИиОоQxm%Фh S$†T2ЦРЅшW=№\.(НіЁNт#ж˜ ‹$-Мe*шгqЯž~ЩЊšЧnжСвw"Ÿj(ъ(фWWАC{9М‰ ЊLл}ќ ‰мбKВ%с­–&Т+Ћ,AфНjЭзС†=L я4ън]†џYЅRxFU)ь Џ?Ю†wsЎЖКФФЄd&T**Љ0ы`уС‘в œ(ЋЬ8 gлЅЯ Ю_ЯŠФ‚q='t1 †U‹‘ОHL7‹M*•eЃGЃчќ!,’ЇЏ^\і"ЕмЦэ.RHЄізHжн™™„3k,УЬџVpЖŽ2ц.WY§GЁDzР‚О БИќмчY`Ш,јW~oќtFЇЭє•nѓўgшŒ.ГAќB‚@л™bŠ•ЇhГ j+>YXиPzэV*ф€WВoFЄfоWИmжЫpŠ\Й‰hв„ кŒgС`мtНіъЯ-Ь5gKђЩ }Bвd 'd}Bj–Д*N‰юQ9№U,ІЈв­УfTЯU.)<яД.tœђТО‹dHд§№RсdУxiњУВАМx ЎT„ƒлх82iWЃL63кЩ,Jљх^­_cMqkЫъsж"<ыyуˆ1“ѓjмфзaьgt%|жFpЏhќІЧЩGњ)а Jп*I]c‚œ PcT„ 5\JПмМ=žžиgЂUшЋqc!€Ш#іт в0k6„’5Œd‰ƒхТ+БŠ_у"в>GЎ„=QИŸW?ќНk_Ќъ KНЈЦ,†q€c јЏ FўŠ~Q_’ѓ<#м„"Ньj–84еaБ•xŒХvІЪlЦQpМ*КмщШЋтк„МЮъК01ШTZx8•єŽ˜tеЭˆm @tPФ} ѓ"gхeŸ7•гR{чеџk-єКє?‹QЛ%y1$УGўлр kTз%Ксш~№'зЪѕ‰Ї>бaˆ­ђЪDP7Яgz }‰Д|x|yѓџ"vїqІS 1ŒD4ёіqхНsBi=їd!Vbf+эУ;9 ]ЉuЅЋ9э7ђ‚Ž­/єЛа–&TлмЃњžч lГrІЏф 5 DF“=Гв’-(н8ёkвM Э+k›TPћO%gQYЬЇЩ–‹КUx/€ѕ.ђGЈјЯЬoлEЂяxr‹”˜Œ„)PBe/с*YаДВHВМ\”@мwœЇƒ2&Іо€;ˆ›˜‰^,ыЂ9бJ?•Хž™OgЬyЪЌЫ"sо§m˜‡*s“їЧџsЌ–лкœ‰сIцф6g@њR}л:шˆЁ-ІђЂЁоО'zтqyЕ”Й>7ёžеvьч0јЫзdDЁѓ$РВи>ДЫГD(Бюq iqž);Ѓ’†УVpўq_б§ЇЬp[Йє*Ji„жў<ЕљGХ)ќ­ЗFšh@Вsўвlж‹ˆwеЌ€5r~з§|s‚Є(USР,YD…*ƒ›Эх}s‚ёmЦ-Ц8ƒuYGHЅC%Š)h*иСИВР $цh™Й ^Ѕ гд‹jЫw…c‘jєЗV•:Ю-oS!‰єгГ Г‘ДЗѕMЋ$ыoЏхЁОощљ7ЂЏ0ІаЎ?ІW' уHH>fŸ[•8ЙіknN7:@д+ƒ†FЩбh<”žс$Tl–AЊі$ЅУ3e†NУ~o_‹™пVгр~a!‘і7нУ^і{‘dдбWoЎХв4зƒh„XŠvзVЉWtЮРГ@sЦDц& ђФІaсKЌ\ЉОРќЩvЧ’5)јїd‡furpQuŽчxђŠ^h]уж ЕaзMЬD&0™Uч˜ ВžйC<Мjƒ/ДЖ%b—зSi—PEЗИ€ •ЃЌ•ѓh‰ЖВNЁN”vОј•8—dмњ ЂљМeАgЯЛ„\T™i#аЩNЇфичzUБВф tž№Б@š?юS‹i˜Cаc]ЦЬ‰Еф‹„qLр&ЅЫiцЇm‚пyОЄхЙ LКб>llєО ЙЪ0ef}z–№ž[в Ё^ Ю…!-а”z€4y~К›ћ(ъЬш<к›юeш‚СуЖёPЃФB€ш^JU\ШlІŸ |"ˆlFr/D=…@rрёПZa<ѓ~ !ййœ)zБ6?ЯниИFNыrхYД08uСТŸЕ}rQфЖГšДg юг„`­…`[№‰р|ЈХ9еЁH~{kv7 ФлДяЊtёL)|59ю›eриЅ~уй›P*SЫD§Y›K‘ 2Ї‹BКЅŒuёёД\І‹ВМѕŸ0ЖRќE_Q‹УsXМгь<п$гхК7Nv_;ЭAњрx$oŠ’—a‹ˆŠ{F8ZwіЄ щZ…lU8яќ5йО#QћнФ6іUtыƒ‚-Ц> §~p-ќzNТђXжђпёL5Г”LХН‡Sј№УdZцџeйqГ|_| s/0hvЩёŸЊЅLФЩШЬ$В`O“V TЯВ b 7gы*–!Жж;Њ<ф“X‘kУкH№ђтH‘ІvчМnєp‡ЏЗЭ QБ8Цn]Пјђz№Н>o§KЩАжˆ.=ђ№кЧШаЧх?чZ\Н6i,п”j•Й›џ.Ѕ ‘pЧ‹bОчО‚В7Э ЭЙяnзђ[slq'№нТъчn@0рУ(7f25љjР0@gБ%$GocъёtКя`œЧƒ6™‘чQŒЛ˜ђДЮs&пvќСЂд$“@ž™ж3“Ю^tМ jdvІПш№ASоЇіТyшЃZћ~ыЮJ‡:ДЧЏьИYаХ.'ръУtHЬYћШ~Лd/h%\Т1z~хrЫ™^яю АЈђyvБŒ_(Р{[ЉЇqЮЫ|–Ьк§BЏRо‹te\[ч\Ѕе`ey*ж% k7•Ћ.O:Ѓ“ъэŒ›A$ыsyџWяxЭžР|Œчэ7УnЙо d{п:юœ’йа'p‹Йž“Ќv@E4# ЛzЗУ\гыђёщ™нЧћJх’p3д§ФxŒqnпџtCЩ^pЎlнЏЅчњgR|zЫЏќ('‘ЦяT6’њуR FEюћй_‰QѓяbМЭMŽ{ЦŒp1РОMы‚9ЌX•ФЬЉђ7Є“УЬ<ЁЋк^^4Ќх1і"х‰’ЁюbмЋЬш_ jдн6KOОRѓа~јLѕКСэA+F.ЮŒYцP%  ;zƒџдCHXЭ-щ|Въ‡RплЄІ“{гБц1yШ cz™eгЬ‘“бН6 ЯсTЭчЭНэnуž€1еF^#sюGжKmП2b0rФœШa(dVѓ 3:qU<ќђU›fУй‡оФЉqЊ7G ТlУьp ПЫ_эфћ‚1ЮˆM™a<ь2@Л‡\Gёь O‚§U>Tr њ=ЖЗЙ”ѓ:–уXIˆ>ћ[гжАkЇБ!%t’m$|€ЄŸ&шйTpкЧ кKPЮ&{ž‹ИOn уеEОХћк.syИнˆчDэ7ѓ‰ŠI"ДЋ*D‰КVeŒЇЩO­шzбм‚љ‚49Ё—Ш№ыЈvЛB 2Ъ2 VКўgUЦ”ŸoрНEAАяЃgяW5бшwЅѕ™=Q…ёЗ1ьГЅ6ФiдЁ]eхАКjїPnю@nr№Wр”ЇXСBJп€пЭ/Z^=rnŸ{"­ жЃH€TМNпxZWp^п‹bь.JЄ‹гљ8JщєI‹ћђнJlї€ур`ц+ž­Pе\Њ”+ВгŠиZБA6юšпi+1ИHLju#Л&эA*zСgKпvnmѕ.*бЛŸT№ …1ЫGчžQKNwФЗ}о?ь@5псЯёIр(9AЧМЄZ •_ќ_’ш4VML|ГЪеK•™VћЂЕ юLooЄв|€Ѓ%,а–ыEћ“уZа1€х“Ђ[Tѕм№v оїwхhc­ЌŒžа_~.7ЂЁОЃ’Сж}Œ'ІЙh~MС€•ЕЦ$дJ’їИы–АЙˆˆэо Зu„Э DЬжQЊXFuєЊ2|Ж{ўЂЮ•д,Y&RЛM|Т=‚Ќо\№CњгĘ+6ˆeђŠ–пБf\3‰-ЉoЯќФ”—ЛXnќ|bЩ1­[е•ZФ"™^Жb‡і(@’m:@Їv2ІLЙ'”G-ь‹М Ђc лeC4дмЖGv7QpаЯеVRНѓТкьэƒDѓcAMГi–ЃrЌЭЋgыЅ˜:(dЈК#HњNеХƒкўOfЄ"0Ї”Фп.сIlDыH Э0хDПЗnњEДK˜яЮ Ь7НmA гАЭC с Г‘8@‚ є‰K~тДе8* GіlК~?B“;Єa9ВI ШЇ75ЂŽр`ыž(мЈ§ˆХ*Ьаm„<.&ž%JщПж2u€YЪDУbVl™“zњк*kI“оГAЎEріВ—`f#Ђлх=5aљDћW‹ŸТ!чŸдЮј§W„-=nсШuЎФЈ=eъDeMИЯEbhьщZwsБ3дйs.Ъ~Щ\яFaˆ)€6ƒ^LКаи5Нљb‘іœіS/ž Q8НNь1Ц?„”іGкЇ‰›G˜<ђЎБЃЂљ№/tмЖиЩаSя’ЂЉ7DЬ7€` IwHЌLзŠ9^†2ј•œЊдЌZГўpХыВfх^kЛvѕзѕЪ…ў’№ŠHŸ­Кё=d!“эkTЦАНъ—Ќш†sЅюГk’]7‰уsЬztе[\ДьŽ%Дѕ9ПЧg#Ъ­Ѕ'bšХ;кМЫ—Їy8yЗлѓђ§ 6tК,DЖ„šЎеЪбЂ=­Цд";!rЧэcОYvEžДъћь‹'eЦЗ R_Ѓ9YОч-~L|д$жN O*Е~ЇnС@Cf=œQЂUїHкУS0žыуЂ+_B:двд#Ъ†АœFХ˜›тцGжир˜ЃI”Д!|цТm™Tхœ'іј†?ЁeЄ:ЖС6QНўЉJŸSš9hdŸ2v_=SYєmА{ЫeЊCФtо…F|ЮЯ—mŸXžT3и€,kћ"Щ†ч+ьs5Ђыa‹,бs“Щo=ЬУИХ7CђЅг яJ.сЫ5-šа чРOPwv‘ѕюОNЫcZ- м(‘‰ КЋ||ёљЩИаNђёк*Ч4чдc\І;˜g№Њ §cRїvhЗМKYKќ qLЖ‘вz%r“дя2pЖ^`gFM2ZЩ””GeЉџfџ.0п!њ…!#ВбwR(Oп Atб­@VД<лБ9^яХ%R`9ѓТš0~-ЧkdQ‡žэЁЕЩС ЭšЎwbјKЇ)'јд]›ўŠ †5Ње)œОiѓŽЅŸž< д*,^ЩОCkЏ§8ќЫdЗџ_e‚Е—@–)§#1‡c ЋЉЩЕNПьН jњњ9Кr&›„Шѕ˜Ѕъ`ўекЁJОЫd™6Т*EyC ЪЉЊ_†Хтqїœ‘MЇsн%к ы п68Ыж5”:Œœ'мQЖй Пч\VfЎ}?Qщ\џkёђТВgtФ№E{йhНџPu{I‰ШШj^iТМDoxКpђšЃ,†)9Тnњu)ђѓ›H@XVЫa_Б‡А‘ЈєШЧzlDQ0nRЮ ‡јmќf~1Ч ў˜чё[э|‘`ЂpлНœ xА"ŽЂž6JиЏ[h]ИM[TЂ4мS<Ђ5лпЕБКпNнЮбЁŒп!@ѓы3ф34лж€ЄїPQ˜P "Q „ чо{ы?ОЉ‰—}kЧƒlЏ ўOвућŠ&z`i~cїЦёЖlѓœ‹ѕJOJ4'L‡Fo”Y`vБЗ‡ЙьёЎ)мzѓћFЃK]Ж9r–ДмхТ8о,djўBxхЇ"ћдY…w3Ў-4;Ъ•'ЮЧ†iNуњZ*шLxрZ e)w ШdИМ5 Зы’Хгd,˜oсИУЂЯОђA”EYй 5эюaј‰–e#™ЃвG:гŒАjiž њйuXt#ES‚Ы J„4{YšЁ-ЋК№lњq:дg.мЯ5oѓП‚UДЪuK3­.ТЊ<еtяАђЬЁK+/žTљє‘†бтcЗ—ЯюЯ 0‰ŸŠ@GU$9Э1Ю*%ІfdЯ> ]yэ)_у мё ЖЪXќ:е}е}йј|:l?‡УЊ~оЧ_ЗЃ_лш}MАРЮђU”œMvК-Е`мЦ{qыa§ЌtЌЋБт/ћqП€hYшДзтш€6'šэ{жUТвэ“.Љpdf_˜0 ‡n;S83њЛцojВš4њ~rртUЅVdLєЫоя˜Т$ш;ыйЃ Ё№1Р…Ы9NўТёЧBlзfB{љхB‘Ѕ”&ЬЉšтИмJh5ьZ`Шт%дq9ZgЙ:}иPh1BЯE йH Ѓ†kЮНј”uљ6Я"КЗ‰Ѕ–DFХ[ И }ъыJЦЌа$я8јLJ„›ХG‡?š кB=тТn (  бWз‹ЮЙR†8ІFсшЕЦ;5АЄDѓ СютTМРНl‚@Щ0FЊзœƒџx?‰IвзmŒЯ ђWЗ•hДє\Нts§*dђцeMцУu”&љ†˜Auњ'кџV'љ Х'се2Ю‹…+‚iљ8D‰Ю‡“џSžpЈ-rъG5[cП~ћЄB $1мbІ –Ё1№Ыtr›0dыZЌ№В~;qˆˆUВ9FЧр№žР’ U[лАJ0Е#,:”Јёx†ёVц%JzљOSщШlP™ОкhљУГЌЗ Њ"6„нЄЄjOyKtsџWћE>—LaвЅ6q]ŒгŸЌњЃШц~d™ Чј#&Џ•лАУь1U‡ќ |ЇМн™%r*?w­џM(d ЂН8- УЁxlLйЕ2maЬ[CIG­кtbа/nx„fjXNwAcпhЃf7pNtе>.œйЏЛ8.K‹Ё3‰œФ№\РЈzй R/_bћGьoBœ–‹Ыј 3–ёЅ­Їƒ”У=-ЋЧJЖ‹єnr=/9–} Ƙ)ЂHьŸ\R‚Ћзы3ЗвЂ*ЭЄ*š9YlElw#З'ъГоxФKS‘б;ш%bЊœаc$ѓ8М?cSy !імIvэјŠЇа_%\њЎ?Кƒ ЅитOлнr6ЪНГЂоzG‰0ŸGRЛxІ>PЃЏE&uŸяKОіГœмСц˜"§"qЏZЉ~о˜+8ud‡наЋэЧ””)уњ!”~фxPїyQЦиsRЧlї№€ТQЬќз'3оцбђsfшЯВ3}њ”хmд!?vNьыяX w(ѕJfпGзЃтW‡<љлхнTмW%tЉP:‰YЯ4‡’­ЖlЗў˜Ћ| *ЪЕкё}A›ьs M„%Ъ4юKј“DН†B ІBР#KхмКš—?КР“SъџФZ>‹яdX/™Ћ"8ЄQФppїћF‰CеА.DrОЊl™ƒЃ9 Bвхі3rШuhUЈ—Трy–r<…2І вsŸШž“‹| qЬšЦііџ№&ѓx Ћ~дEШі|][(э4ХžчђЗ$ŸЄ_"G&Ќ*ъ’ьBZЏY-КУТ#4н2ѕgІбћ4ˆЬ8Ш™Є j'ђZє nАЈ яЏ-…иH˜Щљ‘ˆА€oЮф/ж=л‚#ЩѓFŽwЋЏ—iFЎz­іoВfSюРR’љЉѓ41ѓЪfpтŸhmTЕОпАаcR]Шd„Ђo 2ћyЭ$К™ЩDx! >оаaИ—›ŽИ@ќk™A­Ъ{(tNWпЌ‡е ­с9ц‘ИPхьœЅУ­"шЉЈы|СиlЃё(оMxЮBP’,хЎъФўЁ-9(#уZэ( “=SX~Pй˜Qхе3яЦЎз$ЊЁ W*є…Jи/ ќљc+ˆ}№<УIіPў™!ѓ,јВ™eЈ­7яoёfњ1Л@њ&ш_##]лишА z-ЕЗ–,Sк,Њf–y–Ъ#ŸКц?Ey5˜–фYqЭ†`њ€!мT›`ЄZЖЙŒ%р™$‹žйлj; /’ч~€ЩјцWTы5Ђv ёYГьЧ Щ,Аџ ФйљRcЂ7Ји 3]&ІŸŒ|vm…4sџ;ІyO‘|П*‚МЏЈЩпŽє‡w•j/Ј{|K^э-ёŒœAwю––кv•ŠY›UОЌ`ёˆ™зs@дэX…шцs& D<хч?яW0ћѓ­ишvуўэ a­§:‡KЁaЇTь“0+Њяn{—К9A—єCFЅЖy,РьedЌун"Y{Gэxђ}пЦдMМбЎo9)Oђ­ът~™ЉaјЬшЈЮЏOI—JRиЬCWoАLJ]–я"7Йѓяё3ЦРѕ[#D 1 оЦпL++ё вʘуу+u[ѕR‘ .{иВ!—И8Z=jтfшюљюкtМ %;Lrи4ы0Š сД]цЎ)2#ф'N™’T…WHхзпš'–Wdнz ЙС'`яќa е­‘ цf9љЖЬ*К^ютІd ’иT:ј†FгфOPћ‚}ЭяHуœ[Žп™_wђRПЌpƒ^рЗЕ9›X;3˜шFЊo№y"-тљ8`Љ $PЉj8~Г.ж†Б‹lе›НxS'йH МŠŒ№"™~Ш&UˆA#ƒ–`х>ж‡ћєФ•9BЪЙ0_{Р@k„aЕљѕў Йz”рЄѕbьћфyтHПZ2с\ƒ?oaяф4ѕќQnBДИяФ7Wф%IРw<Сfйc@Г”іўХЎћŠЛЙŽѓubђIenЄbЙРИЧФЋOа 4АŒТˆLїК‘–5:нh(нкъє–Лg[р6—Lh.НюS3“їњ˜љжјч)ІЉўу~НЛ3'ЕoB$”єЖ$:§C[ц]SбтЌjр“5ф‘„ьk сLfф §'gMМgЭЏЮзрVъ#ћjЯ7#pg…’сй+н3gЖѓЏИHЩЋV}*ЬОQЋЌЫI~A4ЊпctЖ1ЙЩoІё ‡ЫPБб„6фj`nЬs’+ў.b-HMnei}ˆ[MXУВŸb­~уsM’Я$ŽX0ќ^qтГДЫr _\=(–М sIwE›-НgTъ9р Щ№ *nIfK:шП=f/.дWыЪo>„+'ЛСZѓ џj‡§$й‰xЃAЯ€{ПФ2ДщЬ5QWйБjЭ'ЌќtПŒбr’пЉ8ХЕТ cшЉUh”ЁR‹jЋr`ъУишЩН€zp‰ЦюeŽФцј(˜B щMВ~ИДTt—у›:(?Д2O˜z-…Uе@–Žvў=1†œіXџnГŒP˜ѕtшŸI2LвE­№НMаџ,ХЛЅKe™'НњОГN‚и}/Ѕю”€ЮfPСєфVTŒєY’B›ј"­Н7мцгЅмЧщ.фr„њ$uMК]ђ!ЩЕ%(ЊТ?wБ'—јuЦЇь‘Rs ђ(Y,zю˜‹‚"&ћ*яН\К8x@g#ю“ K‘љ@гыuЩ/i&wўј›ЛфщkЩUю ўг8юх1š^†TCŒFыЧ$Ц@ЉоЈюѕFF_sїCЄЧЈ@І0nцл#/5Xьœџ"Дyz рƒЯНa/W№ьгžŽН[‘Йf~a%;pљ5HјЅ зуУ!9[#Фэ~Ы^OДЉє–ЫMЖBg{бЯц—шQXCNкцmŸMФxОќ-Xтui“JёМ§іCтZ5& Г“*•џ9*| KЮŒЕЙxаТѕrі‘ŽyX1дЬ“ŒЬЁ‰Ypє”№юfгŠпНvђ+”’Xoљ(QVк7Е[Олw"y…Јqа8i(ђ6`b-bh;ІtŒ*†VБ+„кЦŠk0VоdАЫцђV СоoД ' Rb7кЩСwЋМлhf:8^ёЧ`аЙ‚.jš^Щ$ЎІxЗсWБVtІ,ћ„zLБЬЗєєВRиmAOШ€ќ‹МGГay‡lУ<№u‡ЯцК ^k@aoV2з/ѕ1$.А)'kёЎЗЭM`‘Џ}ошž6Uсe™0Ё%# сѓкЎЄqйЙѕ'0g–€†ЮИХuИ9ЂМZ”yџ&ї/‰е`маш’ьЫеДљВ(9уЖѕлQAш)аqспf=іЙ = ОaK?I$@ъ№ƒЯzјііњIяљьЪЈФэЪ2lМж‹muVYДёчyH| їMƒ>)пЫЂNgрR|МйHЭѓiefV"Яp;а|яŒC'$ъ]Rџ‚‹цO[йœЛ`яSEэCJТ„<–Є€ŽI§UГat„цV‘‰hŠЏФз1XŒЕї­бKc™0‰№VџE‡FБ"–0]*4ўŽS~Vэ—уŒгЦєЁƒ{єAй(Eт8|ыХ2л‰ Ђ ЅнО͘NХа7ЃEœ—{љ!њчўжмйЎАwROXGН`™'НfНЇ}*7Ѓ‡ыѓЫ?и&)иiи+ЎсЯ‘ћŠp’ HTЯыd˜I#6žjХ[ч@дІ^ІиЬєсiхKќ#Hџid%Сч“эщя61q #{Q!еuлоXмSњA“b‹ЃЦЅH0В+yыє˜Рц]дRxЬСY>њhОЃїSЫo6ДPі˜СXшЄˆЪ]їв~и(†о:ж`cYу˜їxњнФТмГЬXСЬ*ьбйЯєэXW‚‚фgQЁЭлХnЎy ›Ђ3!yУ…ŸА№Y—нi%{l<Ђг§›pzЁхћр.l}жюcОuЫw1й%Ћqо'aсАізтjfА>ЊSС_jOчi‘ѓn7xн „Гі<ь,~š%u›p“.&мс фь~­&КБнѓъTvє5ЮnNКpЂ5Фј ўКЮEїG‹БDScВiиъ‰@Ђ&Ђ;24ГP@ ђ“I(БжъSiЧ?ЭЉ…HMЪ?vUНi,[tр>8СaJŽц‚эK„ЗŒњv!ђ\ЁЊьх Œћ›R`ЪУЬ2W73Ž*цe2gЩёbVЛmNo<ЌвЯGЙў”+д`tзњБпКС<&?Q;‘ Нd7еAЋ9–UсJ!55вkQ\G-ШкщœŠFUйЗe­—хCѓ)ŠЙq 7ЉrKSJ>A”$чјЕ9]њс*AН™Ж‡X Ќ5V†>‰~xdŒ€_ѓR@ Џ}[Ћч йcћSЉ,^ЏФЌнЏŸоkЗa C%jŒ:­ь` D/~/цE“‹йSА’`І™в6ЩчќœїнP@tDГ„yїгђOўкMŸž№љіEДкI.Ж]ЪОА;ZY5 Pџ:Кœд*ВдЂСžЊЗ}К'УГУ%P6ЕUBЉ ТБQ>WЂЗŽю ’d5эŒ-иЇ+ЄLg^2YoŸGва|xo.œ_шзМwbіPOпˆ)4„Žь ьЕрч юЪК 8kя‚Ш(CЂpИеЖž0oёTа=Уафрџ_ЖЂИ0™J€‘еBZ—ЩItШЬ@@ИЬrЙ4Ї[:еœ9KІRgЈ(ЎЅZqTХ`he;šbЪу ŸСЧнш›•АжЂvЙфиvžV*ЭYЈлžџ~{%ЩЫlљ.@КШœЕH‚юoыEyd№p[C˜ЬŒ0ЫSіУО!žїќэ[(uVгѕ†A ­ІS h%Rnœ.ГП=VNЈ|˜7џhu37єxЙEGо`хО#| ѕ3мўex.ЦфВž 9iƒ;Б g@Aq_бОЎЏ№…сhvэ?Ё xSЪЅВЙzхкUxСГЁ‹WіXh`Х~HMсl ž6Чн8Œ3Е0ЕšЙГ+ѕKи9<ьИ_Эћjђ™PŒ`š$leyїт3|Ею$щOЎ#‘rЙ”ХƒЅg\)jўџ?СNэluт!E,†М‡#’AGdё˜ПЃ9>2пiІє~ЃЅ‘Ÿhў@jипп?ZЛыĘ=PЭ:ќфOўk+эЇŸщ ЅAу2E&{ŠRŸ:ЂЭW-ˆQёсwјa‹$c{т{AА’‹HTЏ&№ь@ Œ`Х2л‡ЎF&кЁБ$є?пФЮуК@ЭИВ”хЋьiЗ!џЯ hEcЮGшƒgйб’)sс—h;5ЭйеѓŽaЄ`м<‚IЯC™ўL­6ёI<‡Fw  I‘›6'{p§Ox N^&>ј ќpЊˆn=бе3GёŽц>Х{НMпfІ БмˆШыЇч;•)qЯ8€CvXx†3œЏZUŽg.Ђ7>ъ6о + 7MF ато&№Т‡м3w—Ќљ4J т0!2eznГG}ПіKd’УјњБќЗ,в~%чDЄ9UїzЎvМКєAћуЧt-/6j†к#ЛвђЄјј ОНEKvЖЧ\Q`Rэ.\Б б€ВRа':‹ы‰гDџ9ѓхV 7ъNХ0В­‰ъыЁЎжJ?Hb…’їЃЖЄ$‘ч,ˆwpЉ‹н|)хљ>1Я7ъVЧ ~. oЃ,ы–p™sh‰БМЌ˜{ЗћA§#Lъ›УЌЌЎГКЃЄeЬПеѕ XБiFˆЊ1+ƒ\š‡263бМ)Н DИюCТ‰w@*ГђНѕŠв˜VвX%ѕaаѓжЋž§IТЧЃѓS(фз‰JІ—")ф*7эиŽЦ*pФ$‚yyhђ&кБШvN pƒУ5‘›Н$“с НшВzК.ŒFuЁзz(BZІМ;yawыєжGхЖђXМСЖ1-Б‰iy›†Ё–єЦЂVЛХ‰Цфъ 1R•3|iыœ‹пчщŠЖВhецGўuiЃѓбБ вЎ?|ъХОJЫ6І>юRђ зgоF™x‚;™И<кlіЃ†N@)ћсъЯ:|ДЋаX 7оG)‹"­яuеИЗ\ЛІ)Д хl”цј\–Kк{ ­Bс:FQEˆ ‹Bqшo‘љ~ЂuЫТ\†ўГ•Ћ.ЛКТтUb#<–?…pЧИт§‹M›AwГёЂš—`>+ЭXvм˜3жt#Н л?с€ ЉТP—Sno~aњгMПЪЂšПэЪAЄ‡РаŠ ž{sКS§ђ55ШэБ Ѓхзpз–СbЧ:Ў{jњхУјкc\“+Рœыъый’>ЦЈнмЭLоМЧZЬ mбaЛybюDњћ*скY9нёІ=[йvпэD h5eЌ‘Ё6~ЩP#ыžфžЮнY 0~ЮІN€ќfяаB›Ьж-Ж$?б$]t‘ ‘ў№ЫЎчяƒ}+їЌШ,ЧpRUХCRX ШИЗХecEЧб@ s>бeДVJcЯГ…пВŸЗž'њ§^јщФТ‹§Р)ШЄддcј…2ЉcМЅђ‰Ё>цœчќ|яѕXcЛ|Šн…ˆЄАЦ№ ўgqf6~јњ‘Š Џ€р>R)МнЗ%8Ц Ў4 Ž 5sГ›ў_€Э9ЋMњн?ŠмHОЂе?ˆžpЧпЁълN Ж,Х<щ иуLJпЊЦ€чWЈЧя Ф‹ Ф<Щiй!аяeiчE~ž. w+п5џ•§кЫєšЉоцŽ„U_Ÿs—ЭЯJТн|8йI›PW мr~­„ынШ QšъЎ?g tUNіEЦЅOл%‹ЄШJЫ d'o„H>ƒїI8ъкК№SДуЉб&Ukr†)8cŠ”ЪъЌяЖтCВPОЗй љЧkщс0ќBвЅ+ћ|mБШтE"LЯЧ‰#@-vгœЏФdošІЇXј0ФЏŒœ–5У|psx[Мџ*pЙMЄЯЁрŽF'q"cеаЪS‘л" лWђЎ ŒЁJФ3šj@JЙ*xН&rФў,E)ћСп1GЭз\Ў)ц ІвX!‹љsˆЁ9(пЦн|Л™”ЉOЈж0ќt‚m}~иЂK?рўСФџMпƒuюЄШ!6ŒmDW;ЫЃЈлѕЎё№ˆ.i- СњхЂщ ёsDWYсЊW„ Иr џ& њŸ{АЋ ЬщRž/š„їМGw‚p’Џв§8­хI—тЎELNUbќx†ŽБК3мъƒ—Е§Вќ1Av…<_мeК5lІ§1юѓэ]ЙњƒW!•ˆ]1аЋг'їыKœsЙ@ё д =НLaU,0а т—І =a*]ъааbŠНwCт”1Эzц’о7Ј|ˆ• Ў? ˜X^wŒYЮњpўФж—†zў,пшЛ, хcк „lšомЧЄЇчMjЭDњœЈсnf#ђ”tЅМJ%эx оsѕ!Ќџёуџ;Цуf ]Бspeƒ•вAqєЏJЗ&fД“a,Ѓжƒюя&-\,єљ-XhHМъН€x_š"Ш[ЪгРэ [b{іšŒv+­јР+2Ъ†ўАЭБxё9л9нЬS,c+ФЂm`Є4jЦT>UhшБЯ.џ6jа3ѕДщЗѓ6gё& JѓkйѕœИжѓ|ž_иъt AŸrЭх/:šЛ;ыя'`ѕгыgЦEО‚ТFэЮ–…R€g08ЫФлЧ+<Ћ*˜ъBфL^.%№~T…МnЩЬПIхє<5TљК6ЯшЇ`€ y;M@ѓ2OnыУ’Š^њ(v‘Ч„\ЗХHЖ””/‰еHvšђzџ{s`мБШЇgw%0жДЅо Iж}Šœm]Г7)акё_09Сбт B‡.& ”Мfџe­cтFіЌ6eі…Wx—лДО'Ѕcpg2hхg_ЙС{ОxтtЂСэї,‡zoЃ=”MN5ЏчвЅ6ЂˆМ—)`Ÿi–9і>dџ\&.Є:§ щ0-K-SЭbIв<јŠ\Рб§3x@ІЬЖЧЮT—wJW rnЌнЂю§œžŠ‹SТVƒѕХХ—*wЩCє€р€сЪ­W'"“lЊЊx№[ЮЉ‚ф YxBš{Ї1oгС‹ѓяJИЕ6žг œK Яоиіт/qЛіvŒ?z.3щцFЁqЫНѓЭ1KУ”єђaŒЃGEnЙƒё#UЖХƒЅТі;TЪФѓ †КЌ@-y%œiL˜сT3[AsRрJaпtU™ŠЪ{"Т}дїеё*ЋЬk$ъDЗ'ЪІ•˜ыїЊWCЏ…‡’т%КчЃ[ЮК >3ƒ}>еBВ‡еЃЭU>BЉMн‘“/yrƒQМ@œОд’NOюI8ц H+Ллзфtƒ,Žћ+hEеŠ`k 2ќžFG1‰jБуф$йЬДАbБ9кЪлš!х4h(­їTџМѓ'—†}Gш Ў‘kI|™ЙЭHЂ!‹A_4юˆ‘’YZHHШщг ˆЂdI8Л*Нф)5xЙъa Z6чnч)І‰,АŸ+PВсwФ_Bу9™Њ?t# €ШЪб…Э"sЈИDœѕЕњcч ”cўQ1і|†ŸДА„+?зђїT„Q%Бƒйыњt8v†`|KGр2у Q ‰_eЦ,уї$ЙЬфёG<сБJ&іціJ9т‘?“–.S#нИzt7VI“бЈСВL]rя.+оі­"Љaѓ,AЎ'.м ѓ+…М3‰LЖ­9‡qŒIСYvЗ4oЊ§Bj мŽгdrж"+HЏqщЖtEюёaЩh‹b{ЫTrшž‹їЁJјNSТužЅПЇі|6hћ€эц$ЕЭ |aил*{Iђл{ѕѕŽњЛSЮ‹”ГJ–№с’КNaGтgч7йыDސX$њІФlмнь7tэœWлЇ"Ј*YИџ|!ŽУNК[ДєЋ9<пAЩЗЯлЁ@тђ,u8Ѓ}A] гЖ‹ŽПюЦ’нq­ˆ3ьR&љЙѕƒFSvГU„Y|§ ею7 Ъ6žйR™GEK ЕwКH”Awж1S;ЊЁП{њ1KХђZща’[#•ёЗУЬcФЗлUн€Гђw™§МИй%#іУTќ •ˆЙLРвЌЃ'ЂНе‘rИ+б7dGћЮ7-пjэХ9ЈдW%KшъЉП№—2{U*8ЈУМ++мп>‘oBйBљЩЖrт d…РZkџoЕ,žrЦZ,Й§ЌуНš3q8lћк˜I\ї>SЏnяaїі#Йыšž§.иЬЛ‚Е ‰аo"qРZі,3иЄГ~ЉЩ[HТ‡gл’џOxŸsПyIŠ˜xеЄЇХr /Лќ-ПDHs‡ѕnВ;5тЃ” ш=&EЈXv L;\kXZк,У–=ЗОW Д:нJ],р.ь№ љ’eŽжС­9Ъ#яГ‚‚cЩЅf[„vт%@/K`}“^хЇВ”СmЖ-BdЪcэ>Ѕ‹ ЖŠYyЫ шA†Ѓд]“јŸџ Ў6Ж{€кЂuћПp&§U)щгt'эЌь\˜#}МœЄун“Нўиъы†.йœМkчыЙŠSЛь{ О&лCі"%Иƒ!Pb!mŠbp‚‹цКАмйЈ0Ÿч^˜ЛЇ јЧˆАЎœYg{Ѓaѓ'Jt?ЫCKћЖ5dšОN“Р„№ oW=NЬПg-Ьр™ЬЩcУIТћйЫ`šPиA‡Њuі%ТIћДіЧ RCWнДз]EOvEфxёDшwнШ#Г ЖO&ЖIсщm)ˆ‘ГНЃТpp#Ёол~f8^ѕзрЬŠCrр ь—”ЯэzюcйЙД‹Rr:U"qы0FЋ­huуЖЛЏъцЩІ Fрi9AlщЩмŠ$кP9 ш2ЗJЪL+ьuB@P”ЁЬz6ЅˆO”юм‘рVVћ6}[N’йи<+Eню^ВpйOœ)ќ-ёжI}TЦЮџ8xO йUsл<оТ5рOitЯя77ыч`˜e[MЅw^Н< ˜ЯXўbУK­TпЇj^d?кЉЛЊ%ЪZ \7ЋФюю9еIљз3ƒпYxбcѕлAeIтc№С№ЩўњyїxrC;Ѓ]эA8јsЃЈasФаH–ј8SЙvX uђ!Еj6SXнcyІФ'pяTHтhЗ™<%ЛD –cd6Bв”TЙЙЈ@CЎ6LёLсп.їЄый+_цR˜-;Ш…­E‡PяА"s$vx­ъr…ve?тЋК пејЬЄKФkDюZеѓœ6ЏЃъcм-ЅKЬЊЧO 6тРZЯ }Ў‚.{‘96pмј‹M[j™ёФ?Ю$’6sн2LД|їЙœ"J4шžН#TЈђ!U  ^C% І­fЉДJц5ЈЩЫЎ™чЯKиr(/јg”Eкl­ї }‰ИъйS|ЎœђXЛХх{ъDr”GNKQЙьЋžkІŽ ТЭšіОў№ёЂ›У–bgХ‡2OЅџwmVЩrІqKк€ъ§Б ўtYП‡5ИOљ іјќ™Vi”ч>]о‚7ŽYїКђ№зюЏћ›АФ #”РXфбršмвЦmТ|љлЩгЈхѕЂЯ˜„ЏўlЭд0’аœЯЈёiл€сFѓ–†›O‘n…”GЫJY*T(7љ•Ћ№Г\ŠždY8МЉЇёЬkЮ”Рu’ўW]EѓќсSh#ёuRЈIuA !%пL‡˜рркE–ХНјЪ&єЛ k•P&—*ŽБo kЈYWy_ŒNУsГЎИзЃQbјєotн†Ѓ‚ n">Џr |:PЈ$ђeЉ("V%†€XПЁHUЏ‚аEШ#›Л јW-‘šSспэг}НОxA—4ю25ѓсЙПРЛZXхЮ’<пб6cЯTMрХЭ0џE\@d:y1Зœ {6JIЖ„їƒИI|дqївСюЙˆg—š—vл5}iIЃрnД_@ž’ГbmЄu•?еюИLEЋlž3ДlЫ'DŒю?џuyУХ$D}6‹єinrЛУ,“›v2 :GSAџхz'ќ­/tH^EFMmќ№ЁБ^œtз7їс№в5анв@aС+МКZu9$&3Л'ДКЫ .F4'Э<=ќqMюrв\xahљ)XžXИЉ- .qь­lъr|еЏЪС^МЗ€OWp'ф20ШVЁVіYСЎЌvв‹ _\ МŒ”!3ЊЛXЛщъмтr9ѓСЉR+вq:chІQ’—ъІ*КПТГЏR{3wП;ь~пЎ­ЛU€8Н  Eк“й{bП"|ъb8!є. ОюЭNх‘—і/Лв}ŸœИŒgZˆPŒ )бLѓ–ўш˜=ь yв9Юu}L{a:1Y,ЯŠš­HаŠj[fr щЩ=ЩF7ЬІp@{œw1ћЪ^L 8o<гьЛе gяххз{P~ЃQ@FЛMH™2 EP„ Їn№ехFдЮ3ќNЗТGŠ ƒZГ|P3Г (р`пф oMиХКiГ`"s‚Еj4Ѕ@}В-fZ,.bыUї З%66N+—ПtH0D nЖњСєv№S`ЖЙшC ЦжЪИйЁZA`дщ1ELчжѓba4юСЊ€†т˜{.йPƒђŒ{GoФš§•Vй4ыФхkшнKc €иэi .Fј@‹ œњвHgŒrЦЅ§5J7зФБМФРућЁ‰ŠSІeјўџyš="ЅVš‚ЪkR"ўЖ˜ФqlїЏЋvŠtЎя3˜Л—iњd7НЫ$€$ЪVnХтЗИБAU‚œŸяёmeњЙСqЂЅ*поˆКЃ_gВkвЄкC9цв!t‡џnё[щ.œiЁъ[З ФlDЖDŠР;ы3[r(.&cKh)Њ=l#Мфа65кWМЛ№aуŒ+іˆyыl#ієе+Tьїчм_~…hљ,:ZЁ=Pv#ЂьфaЋу6oё>ЯРч}Іы…ЧГ“ Bj( Ћ2ЛЃЮњqvћт}рњZd8HСЈxC‡S­ыpе4LCч=њ&%vщИ™FЅdOИцouЂўРzEЖкpАШžъ­ЉщдS!дЄNЕKL7Lѓaуѓ)гЦ$тЁ[зЙлO[є№СІО:=МЛxВлЁWќ•цђ ѕхівн„ЧrdЎ%Џa‘ѓћТ›шШГ,}#[U•;эбk -бз8oy0 $”M8ЕЩяZ]0чщm“Ѓw <;\Пn6У›2sŸŽ ќ‹-. .U№DЂ,C:Qџ{DЁєЛќwІ|яDˆ)ВrќЕћИu1цˆTчїзХ„х3a­Ф€ІЂ`ƒА—’“uл™Ѕ Zv…d20Tа=RЯ)ЧКєgE6 ‡џiSЂўѓр(оИ;(<ЏXlКЩм—ощА­@ŽxTWєВ›cюЭNuАхњѓМИ'8€xЖе-5%ЌG#uЧ}žз|ицўЉшчqFOф.QЮЮRЅ‚ђ‹pJчьmюO%рpбЗ"Ѓ5uћТ#xЛlаћ5/R‡хTx _ХQКюE{ђх„Ѕ€R,ъЃ\Ѕ‹˜ЃВA[`ГkЩbˆцЩЏmоњ рж—Щќ”џy:д$›"млMйњ З 8ВˆRЗoівyŽДA>q•qЮ№ўKўоL:"н†юЁгA0t]@_r^`‚АагВ&з}po7mzЅДнbТх5EТ§АеFчЄџUšЮrывїФеŒхRŒ28vюН3:Žћe};9Œ‹A"Й„УКшќН3лцаUЄЛве‡В]ЂtM*FHь1њў*6ќl2$ПоЙЧЗ&ёфzŽ ї}fПфБћ D~№м4]Rк.{$B›7œ!}0И*‡эцщFјжsnЛƒЎ:KЉјЊ“іy(_ oт;*}š'dOкВе$!~%ф› ZЎ`!GŸVХВХт8^но“К(:К€kїдп?MЃьЧЦСvШeэюyІќПлs§:с„o‡Ћ^—g‰ЯTT„ЋS(v™ƒŠІ?ŒFrv{оaЕф 0ж~dcШžЖ>$у(^)юPmсaAјH{HuрЖ<ЭwфЛАњ8Ђ˜„VљњQc@єЮ6№ТfTнВмиUImД?OБќмйн-ј/оtŠrNЬKђ_ЧЁеџx•кІ|БѕƒDGЋ+uЇv#Ю!X6І(Ў[ч_D ыЌbМƒ œЭzђTш/LЇ+’(К8—†Јпй}ЧЌˆ€Нj0BXŽљлєНщЄ<СRЫy—"’ЧSє+Ž(ж9#т ‘ѕ6"‚dTх‹—6‹€Pр•N:лѓвs]Кб'л ОэGJгЕ5ђОЁgFžŽTхь€–ЊїЋ@R_ў§" NЕ3­NxvЗР•JРЃq—iђYыJн”GaїцnGчwM}L(cњЭ‡'VоQѕzž?Д ьŒ›CъƒЃЈ"хєIЄFXмšUУт_я5ѕЖcнЇŽаФЋНжјЗ2‚‡бЂ|ѕЌјXЅŽ{ЖJЪShTРЮ‹GЫІ–ПYѕЃк<ЉKц€‹B,№ ЊУSЯ&ЙGсq лqЬ+жiРnRЬи%у.oа}Ъp™ŠуНic6ЙŒ д‚EŠБг1“ШРBАёх_}*НЕЄ |кŠИї†ўик<к—3Ѕ>žн|'1Іu=ЋЙд8ЯаД㘹јh[) hѕ#ƒф+ЈР”+3‚ўВЦC€јЫAњŽƒь#wтМСПqкЩЉožЌ—~M.cн3O‰[bўХѓКвкWgГHЫ(лY*зžcм-KО™Œ W™Ib ѕ(‡=ЗЫ•F›Bя\ћШђj'<‡‘a0ж1+cXДL T­•j(3Yг(ˆ6Щ,Vѕ§ЏШ6!ЄЉ§ю}dљZДEЕ‹{WHъ–HOЗКџNЮ‹ЩёPPoАияјžkЦ85 ,ўЩ;M)њ•eЋrДЊ;ЗmZВ7˜‚*OЦШ\i•jВ;€ёur3ЙLЖџ~V§:‡мЯŒ SО>ЧCжф$ŸыzЩц3}ує 1ъeќЩ юђ№ШXЈІЃы‘Њ;ЁбІ&Œb{H,СЃy˜ђХїя?aВЭ­])Щ[D ЙШо Ыs}fL!;ЩT?cД<% dџzH*1Fб№.ŒŒeKБ˜2с ц,MГ;DXЋ…э\СОlš щД8Ї`‘§›’ш`л­S Ѕ&\‹žesфюкxпTцŒкВt9мc|GAЊB3!ЯL%Ўmu˜Њ|Ь§`ЖŒ’УІ9iЋКЗГsvAШL!(ЊŸ"уЮMoCРОHvп- $љёWJзšд›\"5ЎEТ)™ћ™t#:vжяL„D|Ј;ъU ЭLŸЭ&œЪаAяіфkAщJ[єзI+Ју!т;‹LА"ž“u~fLЧхБ$УљTЛш&Хч{—F<єI/cуuЧЗка‚м/ФўИ#y Вђ>ЗsЛbеЄг,H?š§OОkцoPгнCћсДї,{A^O‚Œ€б*ЮљЂR|:скœВ~=гйх9Њ"%епЭyкЦ0ЗўЯ–Ъ‡> iйrнЫ<О„6Є S=> xf.“Єе|5cwдАбЬ„аіEЫwVЌХ:[В–|ђ%7ZS#ЈCИOyђoДYпі~3у*‹=э­ЙQ0А]Юм‡,юП.сЭAсu1Й•dАЙTК№ŽA>Їq~КпФЧ6-^ПЁ…jг Jђ76 ї‹Пyкх6]сС™бњ_5Ѕя›ЕНdтGы@™§$C№у-*yёуѓ\Е?i_дs/Џ–€~ЯВƒcw?уЁНВ @ЬiЌСsh:13zѓШАxlw`sщљ€KUФа›‰ЕЗ'РЕЈб'їŒ%’$ы1ў ~ЂЛєжŠџ<;LоП+oxж0>ЅБ8‹„†Q§кŠ2T`жАy’PЦЫІ ъ‰хА#рC”>а”F`јVпT`ІUIгJAŽџ^Д=:ЅхS<ЇX˜N0ѓЇ дЩр,oН\˜ ‰єsyП)Šb‚xюˆЁ јдъ‡кi˜ГВеYФax‚xэф5fѓМ…Б†А"бœ-#v6dbЧ~JЄ3шя O1с(UwaUŒ;eВ0CвMK|ŸХ“хNM+ž'nЬ+…k8сэ39Kiyю+УШŸ“Kк(šŽ‰@ЯЖбА8ldV†жП§l—б@єbc”/Г_.ЏZ˜щ-зvу,Ј" цБT$Ѕ|УpyД№BуXрVуГИэGЈщЗNТЁўФ”(6іјћ\.Гi1ёq/яn(еШL[Т-U3&ЦlЪОУгr1 Няiš/ХЏmБWSЧ›$\1šoћ­ь!Šпœй/М„џ5UzІЄ™иžKа]v т–(э^М%[™NABЁ\TDЯ%вЅ R%V™кЉбдxЛч|Y-йрк&Ocфцu)сюЁ*љ*а ДљђВ“GУUKMж'~э„ЊД~!аЭy+хьv?–8,§ѓу#їяPr}ысwЗ5ƒuн9ЪњжEžВѓЂж1яvR—Ж8Ъ~ w2ЋŸRgV%Мažгц;xlИЬ:ПKхЄšˆъMЦэъ‘ў + PGЊ[ЦH-‘xiЃŠuє|ž’ш#eжй§mч0’qв=ѕ<˜зоэy“pѕxrчѕtš?y’™wчQ˜Зъы ппд'§Ш`<Ыx† Б†OН=PZ2КЛБšшѓќ,ћэВЛэMОжэЈП‚UіеСў*§З-ішŒ|њ{іщ…ѕUœџќ+ž>vџ`Э}Ўwкcќ*Џр[ПjzПm‡ћt_ік?ЗO/ЊЗс§ЕOэЇкy}JџZнћLПm)}EэU_лZпV†ўкГіщ]ѕU€ьqJИcуН(Б…Ќр;ЕVPќF5ыё„шRС0—OЮЂwЩВ!ѓ–oёч$|ЛDKdоmРl@?јAЎ­CмB,QFayhћtFdEŸЉФPЏЭ.7­7Мl2ђЙЅЎXЋr<и™чы•ь2.Eѕ5Ъњ‡МT=ДO ŒБZ"5 ѓЋ;ЯкчэЗT”њЉЩlbIНЯНšюзѓєџ,q{К{cЁw6N,rcAИяVSsїqдцїрXšЕШ^2pП~їПЇŽєдДFЗˆ‹‘УС%ŸЯсzЛ‹ќХŠ1ИФtJh„{\_ЧврыO5Љ•ЦqG ‘Ъ№2єCьЕoŸШ”т@Оw­ŠьLјYQu4ˆP,эЪ}дjЯIѓътЂW8Иex!jйМБeЃЩQ2А јЕеќ2s-’#чЪсЉy ђћэД+ЪАjŽbкQЩFХ|iZќ~к$рsВQЏ _Ыџ;2•Щ7ОC;jVY№Џ[Fіr=ez•RP!Ч8 V'ќдуХ­›3њќВz%ѕеBДЬУ z>aЮ-xк€xПЏфq@4CЁп1– #e pС$P‰юњјDнЧЧKo1h_f/ЈzЪн^|јƒР3ќK#ёZaћЙ™_Bэsѕ˜yB\0 ›яФ?d’ЧХ7ЄjџфЧ]ЖЮЯ„яJ_ш\6+мЦWMЩƒ,YЧbКіћјќПO’~G•%ЖБпЋЮZ#„ХTc]6I‚Н(яЗїu/Vw`QG@ќDэ~и>Ѕ jЩпєо_P'Ц’EК’l[ ЮЏBˆEF†лђ2WsiвbгЉ5^.s­#F‚KЁЄинzЊfqЪ›9œ Я;dVIŒJ+q чNњЬƒкИФ‘зHў‚pмOф:е#‡гфKЂ}ЁUœКи@у8‚$3 Њ%Ѓјmъ gї^3ЖРЁ7всдъmN…ы 5цAК~йH”$]n9Olg=ѕMЖc"ДНДчщcЛœ)ћ&˜ yЇО^ЅнJ ГuЬ>јЂ‚І†cuћhfzбЯn“мўžїіRKћ'W/WY‰ю6ѓ GЙ }хрQЄ­?О?л^mУВOž{D цBi–& ­ћ=:gјbЌ>ШR<_X;"&ІB9МЌфЛЭыдЕОЯyжѓ7П1,laQEЮzо;Ћ> v‘ёуЛ,gћ•Z:яОДŒ;СrцЮўWžŽь?6`ФO5ђz4Э OМSГ/Тле9cРF СQЮеХЗЯ–  ZЏPH`}‘аt–•ЮЕvђЃŽС4^џ;З3~–н‚ЫьЌ/(„Šўd%‹fІeтвъ.@^c˜9'e Ь3ђМUT Џз4ЅЩЫоgU2mш’BЋ?rЂ)CБXћLЊЁf'ГЋ(з ‹o^*)GЖ‘ЌBNl~џ6њГ|зtЛф—kшUтКИ­R\šи ЄыЁХ™ˆƒіУ‹ьйЬOŽGfи4sJ’жсі‚uгH;ѓ*ъЫŒЌA^xtЮЧі­рTІ3&ќЬ‰„йОю/™‹…ЎўЎwћV?ыm ЏЅ3Y$>ЃШWЗ6,ћіПp’p>†е<‰’нљгИ тcдЇJврќжС{a4Jа:OЪыїAFр+ј –kЪН_ЧKщ.АЅЊэ^ђцc@ ќтЩ/ЖUosIAИ/3oЖfxЛbS#AC‘ЭLKaц шмЄF€Ч‹ХŒ(ј„'Д#$"|h‡ЂЋМЗ}„о$B';кМ›”ZИђѕSхР„ч8Ojуф0њт…Кё _—DџpЈEPяx Ш;Xп>ж€ъцŸв˜ЮŠ%iz2‹ЕœLk=•Q}F0јД=PЎ8JВАэф2Rўœ)W…GӘУw•Зkэi’0Vь’д[4+™ —анAЂјъ "авАmнчПФ‘ŠЇŸW$єы‚ИмD^ЮТэ!”œјЁ& S/щь9в)(jUл˜кdXѓп.8:ъЭ7Ч=sЅwжsK% ŒдфІВьO<6By’ЖƒŠao€sсАZЛ nhР­Д•ЛqЄхУ„Но!М~а’3FžСUЬЃ ј}ƒЁuТ—Ї(ЄœЌ˜0ЃIгv‚I›8^6#-ЛV ЏЏHЬМч]}‰ гэкœwХЈfЬІюх…уИзЯЬœЛ%П6ЙмлаkTљёŽЁM.œДjp˜ГXaз™Чƒ“  Щ‰|їцn=VѕтнЛt—Ы‘МЂџGЏ(‹.ZcНLРONˆKНxWЪVYЂ:5<~^#?)3]XА№dгnRдpQ$SЏheИuу†eшЩљ(AЇРЙЋЊj&’Eбwр‚й‰Ю˜Р[UтJš* 8^ђp]i=д]Ы!ћŽч]ЇьI nЦ|ЅTкK ]пцж8М)/meLжиЪЮUtТEŽpщ”вGOпЩДіЈPГі]„м`иУ –ШКawжћЙХOD‹SЉ9й“–§ИuаАЊŠse™ƒ/M>аBїЫN*(ЕЉ<еc]ІйЅД LЕyкpPќ­9Й“Ў!K#KрGб@ѕF‡н*„HЕЁ?˜ыС|ПŒ +œИА*<Йњн–рћtSя=}h­…хУŽгIœ;ГБыAцdќХdwіФow<&УF•9ВfD0qžи_Е^еИЃ0е‘кЎЭ=p7–Њ<"O€Й‰,Й.ё:оЈэв‚‚&H БYмПіA†оЉuъЬb§1SJэU Nў§PВЕI|е~•ХМЫ]—аЪђb`ЊК+}Ю‚ЯцЧ шiис=jјњ­Ь†№Э8б[‡|ЇH9Љb*[;/б)0<р}oWЇ‰ЖЭЩщ=ЂфнUшГ4ЬнvDЉ!Аš`ЃbЇ—XaЎДraац›‚о§–Е иo ЛЛ bгЉ8B~фN™Л+\Е 0цЄUTeзyшлѕdƒ{'зб^)‰qП!Г\їЭ+:Bэџƒ—зe*дŸJKыбАфдЏM~6uњ ˆŒІЂ№7№U§0E#;Ejw–œ .ЪЧќБ4;ЦЊЋОћS@=<,Њ™LЫrА~Юn_C>SЈC4=aњУ2ј:Є7Щё`!:‚ … §<ѓ#ЋAгО”ИœШ=f€6F Јў_mOі>d нHЬ5"ш"oŠЦƒуЖSY…zЙUџ&vOАPKуфЫ‡ЅsПФ5Ž 2r)ˆD5У+Д"[}їž“””Ћщ[XlIx0b…QЖ/p…‹іЈДЯ6вМ}1чЗsфkDUDџ2ѓщyИ‘є˜ЬЯЯ4€НЫн:Кiв,ІЂH:'K2 k8TcЫ(ъџ0G9”І’YQrmУћЫzкNсmЮ‚ФRV№яBП[LИЂ)%$ВЈ?vЏлнrЊ‰ПдE=uZ*Ј(Цѓј]зEuХРФ,э˜Ь%ТиgsвѓЉbъVт“s%GqЧŒЮgїјѓ*?Imаг˜лићЗ`;}m/*ЯицVЇЊ|m{Ьs9ДъЦZCЛ\gКЗœŸ^9IРНЭK # TЁ$т$љCГ6П вupq\Т-СŠЋаж•,н§•ЙЦ œmИZэ?ўШQbЉбц>jOЪ`фWKќя>рГьlѓF/бЧŒ]ЋЎ3Оi9ЅU‰'K1+ь„ЏKšПиK(Нtс–?ЅLчюпEЇтЫ@˜F2h1Њ‚š6%‘ЮТТфUКХ$sОъЏ UˆnІ7DђЙ”ы: 7FМ щёФƒхх-єжљГƒsƒеящёy(ќ(ћѕ`U‚Ÿ2Џ”яљmDl…q—9ЯœђсХA†rФUO~Фen,†X•‹Є‹”ЪЎDd^Б^jv/ƒ§7МЙђ{ЛVБk‹™ есБ0`PЭ@~ѓˆЗ;™ aЮ< +sЭЮЧрЄ"Z7d™ЈVr­Ge$v’ИТqа™гЕp%(щLDЈж9_~AЏkйЬзXЕCt5*­xѓ]ВНгiЋЙцљ„ ОН„BйŸЫбЗYt[X†Иѕšачu…йVRФ"ІЛџ y-у’тcэ†нюfюŠSСSЏ)>F<єСљWH˜ьЦR3њх„7)C~0иЌЕмйwЖбюІќ[w`EFГODHічЊ!BГЦ­ЗЈR K3сОЃ‰ЇTQї.Џ1’)щЇШ1/ЦЖvс0ЯЊ“ž л;}х‹cа!іуq€јUt]щ> NУА8vБX—0 ёМ#цUcƒЮдЫ~˜rP,sg4м˜†ѕ  Аў@RczFu>Ђt“G№_W’рŒГЊДЈш м%ЈБYуdOЌM‡‚„Иw$?ƒбFSqд?ъ4PоЕршЊ‹ЕAїФЮЕѕбъђЩ}HЇjiА1W…* Е wаѓ+іч­+ЏŒЗ|‰ШqRХЦ‹­йQaH‡щ‰ Q†•˜ѕё~kfЬh•ы‹ІЙ‡|„%žqblы…ќВДƒœžыЭ3гьџiQšЊђЈW l$эbФ‚pilЯж Жѕ;uиU{”%МБPю”cзІќ~ю ’”[іe№з•ьвТ”юнпЪМ­‹ ^šƒ0їІ•_З7œЊХ=НЉFШŠ0/КЅВќеœ)вЯ4ВG-ˆfћl6Ѓ;6њh„x˜8џ+ЉюŸFЛnНяKЅгВеЌGнG|Cів‹&їч~тuJ, m)‹Pцѕч€2тЫ;з&§~+olќO ™ыФcoѕu&ўO"ЛТ {:qNРуЅнЭ@P†T]—№ЧV†h Q6Л&=нЉшЏхu “#`№8‰d” f„ULEhXN@ёPџ|'<†“ўСYЉsW)ВЗ•Ay%щ=6­Я9ђуSt$|Й”Ѕs"šІ,б–ЈЋM@ЯRLж7Ь金ЧŸвО‘@Б3g' Зс€%ЩђЙпpcB1j‚dQчtŽю?ŒPдbоЗюGы…TзщЫЂп›*ЊИЬŽ0iDсшh”…й=њ}Œ o!RЎЇЖsPтєУ2џк­^Ђs&a:^ОWЋф,eЮž щЬGэ[b1l‚ ЕAIЯч#."ТG Ь]єш У`шbрХХуЇmЊЛ3s <Ћ^Э! {1"АЩџ#˜”KdЊqаЩэЩ?„ЁіљЖG ЃфŠЉuNfœЕU|bЫ ъЛЫ\НЧ9;ЮЙzуТxdbˆІ”ЅdЪНм"xЩлр)-˜ ЯДgЎCz:SЛ,@EМŠЅ_ИЦЩоJяРьэЄW6ЦИШEaПр(БlТх Чяв(!)m;pœ  пfED!ИJGiР`y ›ўYюIJT”X—В*бџ0a\м\ v…''3Aл:>Ѓ”ДEšєѕ ъE +ОPЎф e!’рŽ0ЗYhтъ†RI[Ќ`Ў(№ІуЭˆУiПfЊіўPљ%Х–ќкЌ˜Ъї!х<ŒнеOЃющ§ij x9‰b"wщBњ‡ Ю„ ёSМЪfв1b[fЅ|в.^Г[пќЋбЮ6=мя Жg‘јњВ\їб,цхzЃ—AФ“Г…R „зџ@И+Э€Znп82ЊЯжi7књЁн.$ i>Сц‰р€цљAон—Л;іыІg^jЮЋЏCа`p8{5E‘ѕ|wX >…~бO' Сw ]Лтй{­ј3ž},Еэ(ƒk2axн|Ї 0%ј—гaќџОЏъQRн gэŒ8ЦсвŠЭС'PЇДšeѕФšПЄ3љбuќ3дФ*ЕИl%,bЩъl‡>ЇюќGЙПŸbhжБыˆПа!Сн‡и8ќдeМ„А‚жgЋЅ]ЎЉЖ3z­рх(Ёmѓ‹ЈdЭG’ ШЃъ-”U вY= ЁCalс їд[.ш…(P‹˜9јЊ,žЏьa'vоT8†RДžS`hhюІsU8‹вс”УОe3ЊхЌќ$ц eрvds8С}tћК­ї?ќZ—œŽЗ|ђ№Ќp;‚эn^оfPэЕo8сљНІA:V іЗO|!њБГІ:іb_Ѕ иVщwПфЊ`€О"2їkƒё žU ЅЩф?дžrц?ь‚ЋKЙП1Ј[mрл4Ж,–"wgЂЛЙzњў cЗѕів– $Ћ+ШbАZjЛСxї-Ё?q[Ў,2ѕ(…Юeе7Џн@œ9Њ#*мтћбrJV6Ю€bЮдк–‰UŒ‹О‡W6Ѓтy@ыгк­ЉVЉ&а;Ф"SM q + |Šsжљ[†ƒш”#˜„ЛRяУ­xЉ5з//РыK§5пyБјšўи‚$‚FhrB/ЋEfЖћŠ3э…t!'YыMOК\ij†Œух?ЉT№Хсo^вЊПhoTзјшЋІУYbЗzэОpтZTЅUйZКЂю>aU#јД?ђDЋЎ'=€Є RЯ2Ц}ЌŠ…@}С&ПJЛ}КМн!ЅєGчЈ‚š \Л—ƒ!C•.ь0ЎUTмЄдьƒUž€љ<ѓC‰ ю…ЊсfЈбкM €u]hњšюTёXV"‡ˆeE јX7ЙЪэЧБw(yDn+…окˆŠЎ= џ;+№йh)Ш^BГo_ьkGРk kЄV?ёˆbxoE'ђ[qчтюЄф“љ”'uЂoШг†бв;~f>]эЭŸмџhцƒУ‚ВпкЁМ"РрьžLЫяї.&Йд†иEŠE9ЖM’c8gгшQЂИ—ADT‰MBвШеbЪо˜nјщœ§дя7†пNрКйsiwбв3=G"ЯЄS%|%кS,LАŒWЎj хХMІrœЩГMёэ`†ŠьЩ*}[&o!•пGbЁЕОKа/О–йEЫ fД§E$„ЇЂ K\Rg­ЂћœіlЊ г8еЃ†JьMЏЌ „ј€[Ч€вљon*вХОЊ‘‰Œhџx”aеЧшaН>S†›Т˜ЖєГMдщЈЁqtЂЦЬ=KEЇ•WУXsEЎr‚vВч…\œЙЕѕЁ5+FёХf_Q'xPыOџ€h?пS’Ќ2Ј)тF.ХиW~е(v˜ЮлжCЧ{;уЊ 4˜|dћЈIыЂў=‚AШ0zН:"YOœЦШ’Шв(зcˆpм^eЮ џ&qIrNAє$ ї„ с6ъьB&c^Ьб е~е)’O тўИџйicnV B№fwbuilder-5.1.0.3599/src/gui/fwbuilder-windows-app.ico0000644000175000017500000052604411733011756023311 0ustar sylvestresylvestre О v€€ (4 HH ˆT\00 Ј%фg  ЈŒ ˆ 4ž hМЇ‰PNG  IHDR\rЈfsRGBЎЮщgAMAБ ќa cHRMz&€„њ€шu0ъ`:˜pœКQ<џŽIDATx^ьни]U•7p$єо{zBHIhBяzяНїоЅї.Mщ *і†‚:і:EбqдqfЧоЦВПѕЛфŸяјš Т$яѓьчмїоsЯ=gяЕўЋЏ=лlГўfЭРЌ˜5Гf`ж ЬšY30SЮРV[mЕ№Ž;ю8jRc›mЖelКщІ Ь”4ыЁgЭРŒ<{юЙчТ5FэЖлnЃїиcЃъxдюЛя~чЎЛюzOvйe—/ŽЈc3vоyч cЇvj-c‡vhлoП}ЫиnЛэZwlЛэЖП­џПhдыеёцŒUgф9›uoГfрM5ћяПџ}ійgїНїоћœНікыС:~БŽпЏбŠљ{cмИqН1vьио(0˜0 šQра ЦєїrѕеWсЅ—^КЅЕ6K[xSQиЌ›!fррƒuрюwаA]zР<^у+5Z@oьЗп~НБяОћіFBo є&œP L “вњj хќѓЯџё‹/Ојёј‡јСО№…_Ь“9ы&fЭРŒ<%Ећyф‘›~јсчvиa8єаCUЧVЧvШ!‡єFBo Д†оЏ%(DKшj fУiЇіПяџћПёOџєO?*Цo%§[СЯgфyŸuoГfр ™SO=uоЃ>zыcŽ9цв:~ЌЦjДЃŽ:Њ7 кGб Н@ш ajAaZЕ„Ўљ0)гС}уџј[пњжџ|љЫ_n/М№BћФ'>‘ёšРж[oНRљЮ,ПФЄsН! :ыGgЭР”fрФO\ђЄ“N:ЊЦъѕŸN8с„fќёэИуŽыc=Ж7 Ц („О ^ (L/гђдSO§њG?њбя‹љ{ŒџсјЏЦ‡>єЁз 0{9/яxь9#ыѕъј|)чуbSZ“YŸЯšзmžўљ5~јсімsЯ§ф=яyЯOyф‘_мrЫ-эВЫ.kЅД… €аТф@ЁЋ%є…ЎщаWS˜˜?С}œsЮ9НqійgїЦYgеgžyfoмxуљўїПџчџјџhŸљЬgZ=лDЧ{пћозHћbєъ…ш‘јS§џ‚§fiЏ™ЯњЁIЭР]wнЕтƒ>иž|ђЩГP“?ћйЯЖOњгlхVввgџ{Я=ї№ OКZB@Ёk:DS(œrЪ)эЪ+Џlїп?‰н>ђ‘ДO}ъSд6~їЛпMгјэoл~іГŸЕ_ќтэня~w{ійg'7І+C/YЬџŽn(выЩСјЯ~*$YcШ, 5oШ м|ѓЭjДюИѕж[{Œ >јСЖПћЛПkхDkџђ/џв~№ƒДђЄї€тбGmз_};љф“{ZBL‡h @СыыЎЛЎЧф§шGл?ўу?іЕ/ƒџїџwё]ћcћXoМуяhїнw_>wоygs_%хлХ_мs@в.КшЂvоyчѕ4‚M6йЄ§ъWПj?ўјdЧc=6н "Ч–ГёчЏ$?Ёf№TЦА7„f§шЬ;%е`т) f†,ЧZћтПиўэпў­ЧlПўѕЏщћня~З}ђ“Ÿlя|ч;лнwпноїОї5ЮЗпќц7˜§лпўv8Š{ pњщЇїќТ…LкM!Gџ{ŸI @nІй|ѓЭл†nиFе† ж дVZiЅжПџо§<єаCSЏъ^жЎd% Lг;iщЉЪ|0ѓRфЌ']g\uеUэ• Z-руџxћц7Пй~ђ“ŸL`іџїяI}’у<И7FŒбcо-ЗмВ—б'hz0zлло6ЅёŠ €hŠ<м\!Ш?ѕMZšжќ„‰e1Ž7~U@wЮ,СыЪ 3ч•:=рђЫ/oгkмtгM=˜cŽ9кМѓЮлYd‘ЖЬ2ЫДW\ёuПЭT˜м(mц@e1ЎZу—Д‘Щ…"Ї&?a*S›_р_˜9)sжSП.3ибгsМ‘@ИікkЇ4^ќќч?_Ќ|Пч“(ЭцЯ2ЛЉЭS“Ÿ@š–дцвО?ЫIјКАТ›ћG8ѓJњ[cэiy’"фчž{n›žу!ЬЩK/Нє€y2dШ/„-™Lќ&r"І&Е™ЉѓJыЪTГ4i!ь™щм’тsнvлm_ЄіrжејCС‹ 7дqяzЅIЭрŒ›žƒ~ЃLNGQ)ŒW Ы.ЛьЯ—[nЙЖкjЋѕ"L~ŽзЁос…™‰Іg=ы4Ь@…ШŽКуŽ;šqћэЗїFТ;x<(ќДˆѕ —–ЛcНз“(•8 F›žу€_ўђ—ђџ';*СщU083E4Ю8уŒщZ5Бz‡Š:l7 d1ыд™e*™чEЁЗ:і†˜Й1%P(0јю 7м№ъПЌПЄћ&Уя•…то( рЇ?§щ„цЄ2Oф8нlБХ=ЭkrEPгЃоЁќЯЯ,4=ы9ЇaюНїоп&єХAe„IBWKшЋ)Аm/М№ТžI’л?-GйxoT РяЙ —І+)ЩsrEPЏЖоЁ|?ž˜uъЬ2•Ъћ[™{ВцŒ„о˜P˜˜–P еиИB„ьнHИ)Iс7 d†б&sœю€ё€ЊШTFNkНУ”њ'дoќЧЬBгГžsf nО!Ÿпxрz L+(LЮtPŒ“fS:*ЦyЃрK_њв_uъvЪы’ЄгxјЏЙцš^"3Œ&%e™o`zѕO(gюWІ,f:ГЬ@Ѕш~Jš.т{ћлпо„i…I™4}КЮЉIНЎŠМПМQ ЈЈл+pЏЇ;ЌНікэ‚ .hUQй+lв|фЋ_§jЏіс{пћ^/SRM…т*ZšТ*рІ*SъŸ бJЅWyfЁщYЯ9 3PŒљ_EџІЌd$'О/(МR-Aм[тKпЊЗОџWЮџO?§tЯ)7ЙQЕгј@ЗЈ ˜Ž/ЕюUWў§пџ}“"-T)R’‚ЈўчnŸџќч{е˜LЗЪSш•awAЁЊTХO?˜˜uъЬ2ђы‹pОPuюПЌzў–јК а-’yЅ Рg XGјkRуk_ћкРM­СЦkœЇS*ЊђyE^zкšВeuЬ–вšZeі€@Њ&iЅ9ќЄД‰ŸnДбFГ`faъiyNъgЕ Ђ"~ЎTап)аQ•—б& „Ўљ09MНЋJoܘ13JšНaРq9rфШЩŽЬз.Йф’žjџj†ћЗДZУзПўѕія|чпЭuк,˜֘YЮ>|xЏ4VŽyРЗЊ жЯдФ+ЛЏ&чO ђŠГW‡›ЖўњыїFuуyУ@“‘5з\sВЃвyЇ 4G­ЬТ+_тёzж?3yd&(Gб’+ЎИbКš€ш*ž3 COыs€€*Гbќх+_љ>3Э1€AЦФ@arІCŒs2вH+Э9ж[oн^ЙoеќџљrRУW]uе))@y№ЈБ]IнVзќ/іНQэХ'Є ѓmМёЦm…VшС[пњжžчz&РЁсЭ2І•3f’ѓЛЅЮ9пјЦ7ўЛ€рwхhO<ёDotЛхL &І%‡‰љЊ`Џƒ.AwоqkЉн#z’їјР€hР€“е8фo ді…KzяXEDWеxQ1gœAЕSЇjаxѓ…™SQ‡0Mчpж,˜IzZГ/ƒj^цРŸќуџЖ<аџKRkѓ0˜@˜˜?ˆ№ZsZН№ТЧлa‡ьзvиnѓ6tшšmѕеWз`є ЭAѕ˜д ЌЗоzП.ЦQХєїдxЁbі?fЗ‹н“тS"ъ|z%L‚ACBiTњj@у”ъ(< І•1f–ѓ'ыЌГN[wнu{}ђxž+§чbи?–WЙЇ‚ю˜ZPаfћПўѓ?Ћ%иїлх—]иcќŒAƒVя5ў(-bК€Шƒžƒдn =LL‘z|uііŒКœЭJЄ4ЋжУдrhFO|<іŠy }87Тф@!%Чбњj €Ряы™јJG€ Ў?œYhzжsNУ LJ%эz!1RD\КrхџRНќў\=§ўGыьwНы]}Ер Ч_yЃ{сЉЧ}ИэБ[mЬйa~ЏWYeхЖќђЫЋEјгєђЈЗЧ„S›кœ"ЈЩе;$V Ё/(ЄБШЄ@–MЁЋ%DSЭ€™Р&S 4бЯч.`+0ŸгР3ЭЉ“^y@ƒ˜фњkа‰ИŠЁѕвџVрэЕЋЙч_Tј}ё‹ŸoGy№п0~€`рРmЉЅ–’ ѓЊу“ЌВц^ijs*#ЇTя є6%Pшj бюыЋ%єІ„ДlZˆњ„ьЎ45ЧЏэЯgРLУег№ г$ ЯЯaЅэwšyђ8ќ!`P]~џђŸџљэЧ?ўїvЭе—O’ё+ЌА\[lБХHьWTgнЈУдц'LIS˜кRщО а5Ђ)LЪt ЮwџцЗБ=g)ѓ‰ ПЉ9FцЭf›m6 І/fšSЇ$ьађњхЁ+љeЇ’ВOўыПўkBŠ*uџщЇoуіиiŠЬ–YzЉЖр‚ ђ˜П"РЏu˜\ввєЎw˜Rџ„€Bзtˆ?A7&сRZ”ь>yџ6V1Џ шšсМє˜šc€Ѓ2/4гѕЌњ˜pvM§є9“ €ЃŒЊ­я5U•tУ€яьГN›*ЦАФ‹ї:WТЬЇХ М˜ эwћ&-Нšќ„Wk:LЪŸР,yц™gzћ кmXс=јTјJЬЁ Р лѕБlАAяЕљ—>=Б ХIНG+гlTсU…gРдГХЬsцдh|ˆP'ЕЖVaЦЛЎO9››У‹ЄћьНЧ4Рb‹-вцšk.эИІH}Œ:=ѓІgТдВKџƒ Q”;ЫнчGQ!§Е!Ќ СrР&„@Љ№=-РќOэ …k1 fžžІ'Z@|с3’—#Ъі]Мдб„ЧР^{э6MАф‹џО_П~=f˜’@Ђ‘”Џ$љjS›уO:’™lCfWЃJœъ•эbюџЌP'щ›т9Ÿћмчzv=Џ>*Ь>Бc_ˆ#– |9Еƒѓ•ЉАkэfiгФ3ЩЩS,rO<ЪдJ&TU­Ќ˜lUoМк`Я=w&иd“1НyПБшЂ‹іВёV^yхЖЦkєR„ЉУЃGюйСeЖГп љь?шˆбиайЌдЖd‰œI`5јŽloƒГ CлlTMОkЊИSXC‚+ЩдцЃ>s>`рЙв3Oю›*/Ќъ90јфРg] РїiaДы0Е№шD (џЭПЯ$$=ы1Їe&•„ћ†Ѕ”že’…'š ўœ Н•=ŽAЦнyš`Ы-ІŽА9Фhі Фl@г }Ә‘М$ ї1‚Vcœ”TpŒњУўА'­}З;МяŽњž= yс•ж:VЊr@˜ТZy‰Я“ЪЬ$Ь 01ЌДjвћ•@r1|Ÿ#0Іvx^d­*љiL cЬ,чN­ €АI_@'U˜~bZ_-#ŽJяœ€лlГUяњS3dђ9 ˜gIЛџв“РФ!чмє)ЬЙ4 ёuЬ$рИ€&Ър0)JmgњАЇ=? 2"#˜п}ПV@{@…1ЕƒЦbмняЌІ 3 SOЫsNNH& Т4mВ8Ќи•˜0ЄЋЪ]Ї€=ІvиaЛЉiЧе;N˜!jh#œ“˜šэ-wЉBj _­lOФ<‡†э,<ЃЉЌзд]„8k%еšЭ€iaŒ™хмОћД› ѕ“”K.iˆА„c`*Lж€нwœ&`—]vюЫд р3Г@7ЫЄЈ~S=јAЂХЬ€™…ЃЇё9'— Фpfkюл№р“А/' LŒЛ{OЋ˜šxўЏ@_G _-`*њL8‡г@3Ъt™ЅL#oЬЇOM Џ Mˆ#к,јW0‘‚ŸО@нџїо{ЏЉщЩп;‡Tы@2ътјП`t @ 8еCЯ†T6`Я€™‚ЃЇё!ѕ БuCSѓ@wM€h˜1љ€#АЇL#pРў=Л{j†п“K/‰†„џ‹uр шлJlrџ›Ÿј2jНfm 2М1Sœш—žœ€а€hЩx%pшЁ/ћІfЈA˜™ )С@`Щ%—œъ‘]™hЅБЭ€™‚ЃЇё!_‰ жѕLршЃŽь…пІf№мЯlІЉ’ЄІvdЛ1Z@љVfР4ђЦLqњ+>€8€МќWу8сјуzЁЙЉ’Žfшы*&ЇvXaZ›хЏљљLAаГrкfL,5ujТ€“™xг8ѕ”“UNѕ˜€3PХфдцTvfЎЕњпiЃŒYgЯ3№j4€n@4L,wZрЌГЮьЕРšš!Б'Ж\џ€}5ОEYj#дJЬ=їмН ЪIюЖьЕVž)zжCNл LM*№Фђ&–ФПјХ/ІЮ?џМ ]uг]wRGЉЛ3 nъoп9‘})sQv$a•UVщљTVrўљ Tжц, `кXcц8ћ•€lН“Ц œwьw fZ5€K.ЙxЊіЦ#щѕ˜™ •ŽSГ sфB ™в~6sPєЌЇœІx% Z€‰@užfИђЪ+zq§Љдў™Іf~œcŽN9х” Е хјЯi"ŒY'Я30-0Бb €Ю@ЉјюwП;ЭpнuзєšyNЭаofцРдЬ @fІт&Ž@Z@iГ`ц`щi{ЪW BLL€.шŒ3Е&РћэY|WЗn“Ю)Н~лло6S€эУ&77JŸ…H1~F |Г`кXcц8ће€"“. >е€КѕL ілglйђo§Ћ­ШЛ{ Nю5&˜™4€8РФцEsѓ.wРџоЏВрY0sАєД=х+€4I[0@zj>)иЋZ…НѕЪЫ&КЃPп-Ч&ѕПf›ђўcыў_­ш[›сџюœјВ"…cе§sіaіОР˜гЦ“;Ла№№C=p\ѕŽ\kњ§тkxЅaУ†ѕvІэ[ а­CO0>€nG B шЉзіи}‡у?ћь3НžyЏfиnlfQ {ІяЖiТ}}Е`˜eМ:&Њмял>Y;F§.{@LщЈенwпѕ›ˆя@|фўћяНйuj чzuw3П][rП(Бdrаэ4Б–`ща\sьј~ЛэВ]mzQс5фœУ–c -Оf Жj ’Сiгs,S PЕЗNGВ™).uп}oЛрž{юўZэљ'-хІчИѓЮ;ўXр№пu§oоwп=8œўрƒoлрuŸиСƒŸ3ЉЖ`}7ISP€yщ иm І=ИVй{W[№ /8Ззqз&гsшф;Г@і аxдzДg‘Ёюcњ.а jЭFПюФѕ&ћСъ#ЙєНїоsu1чїJИќ%{>О^Ч[oНЅшњšПT;ЛЅ_ЗЉЋSЋ:єO}Э€‰э Єљe4€.(ЯMO@РF/Дќ-U]нДмž^GnfаœєЕj :БђьОkВеV[ѕЖ:зЈ4u}`М№ЛЏAНЩ~Ј˜~­{юКыслnЛѕ?гX&Л=ПжGП'_уњъm!М;~я­јКNciяІtA /БЩAŸH:‘– 4т”‰&MM/[щwхЉўiyАўюwПЛЇ шЛџJЧ‡>єЁ^ЫЎР€О­к€&Љ н™ићBбBЉџgПЎ5ƒџX9юЖЛуіл?rѓЭ7§2лИП^GбЋыЏЏqнЕ=ІЧ іЎрлС3ђ7ЊCџзu +|еђќЁы ˜и€Я3 Ј?я <ѕœ!кt Wйgќž}ПЏ–U?ЊџvљО]L§э~єЃџkМ) šDРeF-ЂЂПš}&ЕcŠРД Я†­Yн™тЄ™џ\ї2ЧыJP3рнuзэGоvлЭ/]wнЕџ‹б^ЯqЭ5WзйWїгЃ_‘2ЛTЉkЩZY/Џ_wА^Ѕ\$"˜аR; -xW˜xx=ыlБХTШ№}іы‰яжюОпЌёwѕо{kCЭ—ЪœxЖ@ЂіљФзi3“А[тьFјdт^8ь8ђуk~K<эwоyћ™7оp§?\ѕжЗўYwЄзshK/Нгл%*ЛMйZNХЋѕЁ­ба Ьџ†@љц*јиZk­5a+ЎО;1иœй(@6Ёa*›nв B'ЃLz /ЖЬ6a&Pі_6љ(Џь_mє13Dњ–gЧ`kG`ЪГгАжщњзœгf (!ВигO<ЖпSO=іьгO=њЋЇŸ*ѓиУэЁЗЃŸЛŠoЎВk{Œ95eчгzКПьВK{Пnmёn+ДЋHЮК›ЇL{†ыX{ё-\{ё}=Qxœ…уш•гCL `ъlх=  wsAжŸ-ЕgР_я˜ƒ ˆ@4РЈџŸ˜xѓ5Л•вG• yЖМч?М­ќž{ю,Сё@{ђ‰w60Љсsч9П з^Sъјх=6-CoŠK/НЄВZЏюб,еў#љПWЏ6(ЫNГлЌRmаЙ<  p:!Дu3^ч8Ј/н­СК/ЊиiW˜^@ГјПbLЭfЁл'€ŸAЇfkЂD[ŸFeкѕњ‘џЫvџM7]ЗЧЕW_ѕёbМпи‡bRуЂ‹.ъIћnИЎh№іііяыi“ŸНуЁz@QЄFЊ“рљ~Ў‹.КАW–Nˆй€…MjŒУЃcў72(x–&@  ˜эСЛaЇДŸ €T/ЛОч™˜р=ŸMIјПKљ”0О™ь,Р  ЈЈФЏ Є{ЭФэxсbФГЫaіХsЯ=чЮ^ЭаК^џ EhЗпvKЛяоЛл#П}’Р№Фує>{єїЂOќU_јТкЛоѕЎž™+тТќŠіѕІ€ЌsРЅтt"mтшvš$ 81' `утt|Ѓ€іЕоOi{№Щ@"йКНњЋ•8ш фбщњг7п|хвW_uхе]tСїJ•ў‹<“зzpdыLue™$џUoНМЄўY=Iџв‹ŸъЙ зq№БуEТhТr0ўO€­$ЁЕ*?рЋ$N7ь41 NРDRБ' Ш†чЬ‹HzLпРg@‚#Eш@ј„)СЖтќПЊL˜ @€v6~ы№п•фŸ{КrрpБыЏМr№W\vпyчћуO<ЁНЧЉЇžвЮ.g6ѓUЦ)ѕM~№ЯЗgŸyВзG!цŸ)дCї+[ѓћ$Ž-А™&Ёш&ёžъ]Ц'ѕ#cъ‰љКвП/Ш!јПSkїїЩZ6sЩ†.|4Ѕ™§ќ рзщђ“W]uљ&_|СЯ<уŒŸ%yщѕ>žXvћйgŸеkЁ&s•#b*`roќ3%XщВoОŠё+aЈЇ =~ ж­фЅ&Б—фQ“кBx€WПЏa3bџ чв^+аФtFнМЫјaz>™вШš| вп:ŒќfКpуыt‘Gžwой/ќqшv.~=_Ћ_СєЩxэХщб'šццTUѓтѕ,(ТЈ0Ц?@Пў§ћЗх—_ОчmNќY˜#й€<ЅМЏ2œиN&˜Ъ’ H €А}10ОщŸ ГсЕ[™Н^@UЇЖГџЇFњczIYazл‚_зШNЭуЗiћуыФЛЏшgЪnюїјуямсђЫ/љд1Ч§ЧxЧ_Я#=В"VЄ:z”їТ /є„“†ЖвК 8ѓЉчх,шГдхћŽ[qХ{`вј #``ШdвФ$G  V%(~€˜.ѓO ’єfђˆžибзрH%ЕLo`zRУ—#ЖїПk0Пв“‘š{ZTЭї •ю[LП№3O<:Ў’ržЊЄœŸwCoОѓЁѕЛ*і~uyу/Њ’3кq•Nю98дІзр•ЇUЈQaB’ђ•IкГябЊАЖbЎё”Y09x/†џ!ЕЩўє6Ѕ5Й@СDЧ*с6 L#'€)­М9ёњšбвъЪџдѕПoр›КЕ€h‰DЪГчх]`z’гћпљ‰ѕЇ+ё~ЖЉy'йЌC9ЫEтy:~щТ /uњщЇ=yєбGўфШ#јЫYgб.ЛєтvУѕз–шЮ)&чМƒППjGn­мљЗ]ххэЭhœS3іo–Ђ?ДѓвK/ѕbє2S…чфMQѓ9 Іaё EbR+]И­ДвJ='iйгw.6\2ŸМя;œ‚щSsЄ8Јkxн€ОY€o Ы9нN=їмГі8љф>~№A§Ц=NiьЗпОэЈ#hgžqzЛтђKлЭ7]п‹УO)9ЧчїпwOЛхц*LwYяћ6”ЭМа@IzкЅъ:Mc˜ЁцŒЏФ|Ъ™˜QЏ”&є—K/НјцвцfœŽAЁ”’ц?+„яle іl'(1xli€ *€€@e Š­ГЕљфKsRУD" @mР№ћП›ьweЮˆa@„FbOŒёcЯwžCЯћќОчћIьa“’і1БhXiћe>1>3Lє…уЊЬЎсгЋЇpЁгO?ѕЄуŽ;іГ{эЕчнчє=p(ІЎы—цxYeтнTŽр{џdъa9ц&ёљЯОчCЂuВхЭчf›mжѓ—ЬШpFй•{@Ѓ.ўњэыЕ†гќ;UIѕ;RŸ=J  ЊЋЎ2сR#ƒ#&‡Ф€a"аƒ˜.iхф ј^B†iJПn'–”§v›6ЄЈЛ/ UЖСєprј#ќРr~Wžі”œ€Ž]ЪзСЯ1%GЛ‘‰aУјТЄ$~l}ЬIOЭї?M`|ь~BkPKйЃˆЗ+эЃцKNЌ™;skž= &(кhšu*ПpёЉЇ.vЪI']qшЁ‡|gчwњГ{}НЧ>eђˆƒ:АЧ,/Нєb/1‡ФGkюЧм[<#€\ƒѓЮ=Їїh}вVŠŽgмhNЊћЈАЄ˜4H Šљ0Ђ˜?Цѓ a<ЊТ|  €№ПЯœ—‚Š qe0Lœсwђžc~3љлdZ˜ž­ˆщ9и0=†ФєЁaX’%’ОысO‚Е?uЬй%J*)u4Ж=Їž ‰ДW8’.П4+sИi]‡$І7Ђqtcљ!*РФэЦНLŒљнГ{s?j7Аl7nмиlКщ&ПФTг2июЛяжŽ=цЈvёEчЗ;nПyВЩ9вy%ёœ]й~x@96Зэi†љMt№Ь=ЯНѕ2/ДЅъBнЫ(х8б€9wBiDЧwlЯ?ФЙMcI­‹џ“сŠiБˆуэњ <ЬХxiп cŽgќ?}эk_›1 $г)уЂxи<0{ѓ{PLŒ™1ћWОђзгŒМЖјпџ§пї†з†‰`^˜œL0 љMЎы@CS№@ ZдešаL|'mШНNrQзI™HBн†Ѓ@У{ю€FЂР#љ<њМћуbфn‚  Hє"љ1Gh‘ў kѓ#6Ь№:$ќfљў\=лє›T4 @ЅgT1Oeэнѕ7РpзЗѕо{зГOі4s дЭ3 у3RC"ƒд§Эш€б)яє’ібЪ8Œљl˜Їh­x>L3§I;Ц„SСє=~Я3&r=ОœЮлеHџ0?ѕНяC‡љПёo4ƒџг?§SћЮwОгўљŸџЙ§ЫПќKox§Ня}oТћпўіЗ›ёџ№AЦžд7€0Б4ˆMFbnX€аѕ9јюSO=еqRЦi™іcšнЈF7’ЈD  Byƒм3Ц$!’…Б™$}˜о(ФщG2&ОO­ŒРl!суј‹–веNЂ P5ЏЧXmЕU+ДnлЈTћ1c6юe{ОXs>џљЯѕƒŸƒ:Џrд§ 8p†‘›#Ž8М|C'їќCнMnЬ{і\Фм„ -MŒщћЊј‘є]ІŸ ‹GfL(О•”!§јx‡Iu€Б0)lАq0#ЦФ Ю#ѕIі0џwПћні§яП§лП§[ћС~0сјЃ§Ј§№‡?œџјџиc*`ќŽї %@‰ЩрwLz&žцс>PрcША€€!рР|b‡Ў30@ќ”&їэMЮDМћТ{ž‡я! PО‚n6dЗЫ `HбХy- !? Їg7\*ЊАмrЫНцSc~NPiiCяџ{{‰9юAЕш +Ќ0У€œC9ИРљ„ZŸ{kdў“™чЙ€<рO’-ЭѓwQёЛЮМЃ˜ЖлОЧx`МЊ?Q˜aM€€w D@дtЬ‚qhЄ.{=NЬ љœ‡YIюo}ы[ ѓџыПўkё1;І7~ќуЗџјџш1‘џ„Ѓѓh ˜ј> Т‘†Sиј=ПЫ„ ŠК ѓФ=іu Ÿыб!Сz"pІФє]Ц)<‘уŒЉ‘>—„„  ˜&441AD*:цƒ|T’›$`t€С1њO~ђ“ќїџї №І203„§йЯ~ж Сl&Ўщ7 0Е‘сž,Xœ”wq6вh1РТ'T ]7LЩTОьFї.ZˆH‘дFА#[дўT№%ќч§8›Tп$џ < Ÿљ\?ЁQЬЫОјт‹OЗЉхеЊ8Зgч’K.й–Xb‰оqЉЅ–zS€АІžЄ|ьz4 T™Ж|=ЩuёМ4?Ж=А#ё­)Sр?џѓ?'8З'ца›I?)˜a5€"‚“hTPщЁ<ɘ C€DЄ-Љ(ЩнUџЛвџпџ§п{ЬŽ‘ўыПўЋЮ з„џтПшц–р5p‰Йр5mУ<~?fH!š rП€ k& h š@wЧ"ё}Щ+џѓ?џг#$„‚Y)яЦŒiTъъo g€zFЄc’€иъ(^њРˆВЋОcZŒІŽ& МІ ФŽgјŸІѓ„kКV   t Ћ @э€€ NУ„ЛРY˜цЅq Њw ~ѓТв„Киuа!ТфЈЩ L>@rˆДЂrћnЊ#“хH+№кyr„ж$хЬ7п|S5ЈэbітєЄšы1a\gўљчo ,А@Hо, сˆУѕщпЋWЙ Ф€d73Угѓлю€yђ№ЃёЁ_ц!zpŒšŸўџћПџл3) Є„ЋcъNЋфЯљhјшџyjђr^їsЪСєПй‘6НэЈFБƒ  2{#Zdd‹ГЩћ>ЮР@ЬƒD0t|@8з{Р"€sСбр š€пцp/P7~ ™„%HLў€nкrќЬ€ф$Э—v‚аx™4#ѕ ‰Dњ€њ€щрЛ}€F!ь(‘Fl]Œ]иmюЙчžф ЖЫdЊц‡L<ЖўМѓЮлЬџf€wі‘nЈЙzЙh PPќ1$z2W1=:Е^КЩ[ЁЕwkмu ЃlOљНІ&тѓЧ?ўq‚њŸ№ZJBO4Ў/ Œо=Ђeї„>BЕіyн™{j~А’€zэž0? ѕзŠZ˜&мФР6ۘЫФPНЛ@тў‰8’цљD•CЛ–љљЯ>A[ !0К  з‰AFФ!ШnЎБћтŒZи5<3Q™ižAT€К(q*•{3€xџ-zwwX ™Ј€ѓК Ч пСДЪ%ги@Ў>&˜cŽ9ўj,ЖиЂ=U^UЂп“Џ ‚У–ѓЬ3OoМY€џщ€ія…ь1Ё eŠ^чпЊХ †щЉіЩVЅЅ&х<šцУЧwеЭ3I"Oђ?ўєЇ?Mа’чm2QЏЎ9аezяЃ%р”Мд˜аФJјЬ˜н Ѕ~‰јЗpр,<ХВр<‰ir1Sl% Gњ&СЇ›„YЩ РаоЇъ'L 5ЩŸ(@˜мб5ђ§.$Сhbдd( €HvД`€D˜ЬŸd‚БСљhT9Щ0)VBœЄSњXјд $-8aЄŸsЎ+мІ"Nš­дY’шЫф˜}ій{Ьэ}й‰4НЩ>чœsЖЙцšЋ7о,РєдшГі˜PЭ/веЇЕœu`jЁЗ˜Ѕ@<Ж|Bw1їа%Л§ЄЂЧЩ‡>вŠx?пСєнї€ѓРРєh)[„Ї ЭНђчИO4Ъ|,К§ндфз§œ"апА7M‚‡2Ї€Tж{-J-UKe…˜д,R6Я|2iQѕу ŒCt7)@s__{Еэ5nзЖѕЗk ъM6ZЗэЖѓv•ВyRЏБЄпIЎAР&~€ЄБуЩMBi„Ў &€ХJБЈaйг~(€d €$™ѓШс†щS,D:KЁѕП*AіИЦ#Rhйіщ ё]‡3RтЂr Ž:Z™DЬŒоЏ_П ZС›дšTS’ЪЃ'$рŒя™з лбЎhYшc%7Еш%™ЉуЫl'$‰aє€}’еŠ9˜і0:Рш@4зщжГФ1ˆО\ƒ–ШёиэF…ДЪd$аа  Јяݘе€%™ўA,!.@5J‡ЖVДR‡†@цCа˜У‚љ№  tгЩэhсў‹эџЭo~ЃИџ^˜>Ь?Бушѕжn'wTym_˜`r$<Ш‘zƒ„ІДˆдFсˆЄ$1(ЉЯŽTLЇ’вPˆЅ~PыЌy‹@Bƒ`Ўdbx%Хй(mТћ€kёCаЖњ6FсД{Ы[овДуЭk­5Ќ„ЪNНŠУ8A1 9­Г’ƒщГУtT|ZšЙ1пG вRj)н->Гў]o~€!’пЙЩ0э@LFз XD˜03œ›HMкрб ŽЗAkE“нˆTi3&”Дњ‚к$#nNЭ,„ШІй7ЭЫ†хiNF[Д“[ѓGї?ешФуnИW1кmхgxЌ}ія*ФXуљчŸ­иэ-эќѓЮh;nПХ_Фшѕ†їDГЧ™ЂЃМяОЉ…а7!@*# JЪpњ8&3 `~€9tT:`C@œˆд‰@Сц7/@hін0„фыIЯБ…ˆМІјн4BIСsСњpєН™€iВ§ілеМєі5шIћHq*>a“Vt€6{Jvs№Л@-OХ\џъWПъ ЈIIш0>:ш‚@2њ}пgЉN ќљЯžD–r|Є}ЪЮ-%РwE@аP“/Gt@i†€"мПфьMˆЬОM$B'‘HJЬ†19тяvџMж$—xAŠ&”@bЋ™xзњ№‡?T*д%˜>Ь?Бу#uŸZŸЦЂЄ|škІuјФ€eЎЭБп‘mHЭЇ №щlŒ–]vй7lНе–„є˜ˆЅl* =; г'Vп•єЉ;Б~€;рљюў№‡ y(ж7š^7#4’7Ёрœ4RЭš(€sК@Šам“ћьіЛДVh†ZџЫ_ўђЏ ~ЧDђЛуяcЦд7ц'Х sъгХF1AJu1‰ХŒдm*=›оУQ­1;TL‘Eь7v4›ZX&…ЎsЯнЗї˜џS/~Ќ6„ИЎW—-Л SU_њК— Ћярнэ…O~dH\|бй@`k–ПтŽcfЂ“šœВc‹‰иљ)уtЏщR„ ЁћІоЇўžšš œ~~ц*ЛѕЄй(цчШKcQ>“ДЎц;@јцр˜CФFњanš…ыѓцї€hЮs/*яfT `у7jлз\qХхvŽЂ11Ч4MO‹&Ь?КHz6‰ŸОж)N<Чь7СQ•П[‰ш†эђyш#vПcвХB]гќтуIš 3эCЖ пџб„Џ'Й'&eг`ѓњкƒЮw€ЦЎ;oгuGэЄNsЦ 8‰Юсy$;2‰;ЉхO›Џє№sdЋbаlŠъ;ЎMИ!LЯ ј€ љр@š@)Л(aќ4)5зFz$yЈ ќ)ЄПћKk‰Мб0jдШЖgiiц&]™;LŒэйЉъц*f `ІuёЕі>Uwlь8уЬ)ЦtŒ­Ž‰ рšўМOJzWк†ЩЛЊxРРu­ЌtРџю…ПJV ЩŽ^бxrURу7К€ыт{шš 3d ЄиіˆA’6ьO ƒЁHUоMHˆљwlцЈg&‹GЄ ‡j$€0#ЏhТ^KЈљв—ЋјЇ˜љъЋ.mЧ}X/䘧ђВƒЮФДЧŸxЄї=ТD 0KˆŽ"iм{šmќ ™}^'‰Чy]Gr,8Ї_ђ„s<b Ž& Ьžp љK‘?цƒ$–nz0щЭ‹€г “”№R* ФkЎ9ЄІе+dЧЂ8~ЭНЕршСœFе'ёcnЁŸh€IдIЌ>Œ;Ь‡mŽp~бТd їEЭѓ­[ТМ@4C};виЌ7џІїкoЂЄЧ'п щjо№Ф™џЧ‡Ђg<  $ь>4ˆžВ`в2№фV'ўšЩЅЅ№!љђCSРnЂ*q$ўнчЪ‹[Œ|жеdГ ЛьШ„“s0)mр‚ Юы}_ €- п•_єcПKmKa3EВпEv$r?* Л­Э,8Љ”RQ*kœšцTУј~7"Ё,sg$*{ЪƒгI8вŸ mРœg0Œ{KгвnЉБТыКэКы.ЕAчQ=ІOK3ЯчY9Cг(УsnЪ&’@г'С*Ѓ1НuJX†ŽКЖ>•мЙ УcЏЛ`НЂТЇz/Йћ>K„РбЕаnіБѓЃeТъзПўu>iшO„JЦщх]x.~Ћ4ТI’QЈ Љ ˆuС`Мі0у@љŽчЈ"‰HšYа‚фщœ0Ё"&Іъ=“‡gd+pŒh€„џюяЊЃљФуk#ЬHдШ$MJрH” ЋXTh yн ем  duХыOЭіM<ЙЬš\к‰!тДbIѕ^њ21вЁ8Э<D4€”cv~ае’lо…uЮiuž”˜(ЎХЦ~-@kЏЊ‹ŽжYiaž>†йё†s,‚!ОšlИТмKБ˜uˆуaЬl ’ц2)еNЙЖ5Jъ.†v-tхМО@ТD5яF0(OO‡0=šD#LRyџОЃйŠLJL?БAѓВ.шФ§%ЊфwЛрбZЂ ЩpœaЃЅ\Š8TXЯ™Eъek#еЪcыЅ‚в[Œд ˜`Њ2ЭСФCW„‘8Rќ„уŽlЧuX/+.ŽЄ)i}УЙW ЩСŒвРНa|„цˆАIWїF-MяG‹Ј“ ˜^’n.ќ^КЪ` ѓ%‚‚ \7Бћdfe 0 $-8YцИЛзgKBДьщ КmНѕ–•щxШІяіСO‰mТvйќ"нqcЦaЫa†YбIETxkс0xДМ—OО†vДVLZDЌcЊє"ёiнEЕOЈs2=9ћлпі|U|K’ЉТє ,09vЧЕ›*"•Ш“уйчМЪ$П‘ШSзроS$—gŽ№ŸQ8уi7Ф@€ДM"ѕŒєpLЏ4„šK‹' ­РУrZ’rо4јpќk8ДЗ§–|xЩ2Sвње‚%Ц"Ф$LIџE4юг9йQ„lг",ЏГГQЗб( N#ЧьQ@{ŠэNzЇ4˜/€–ˆГ1aFѓHŒbџgoзв`z€Ц ›oЖi/З!MJмo oтO‰Єяn~†OИЃ{M3у0Х\ц<оќdECД6жРч@™„ О“R]яЅW*O­g’Ѕs`ЇtЖЊ‹дчЬ:фЧсЋђОжfaќЅ—YКrъIэуŸја$sR,g5ZFџžиИЗЎрYЛMlSƒ’:„:Юp‚ЄŽ"6іgwЫ#“'`ь_ Ю.BЌМсA=ЈjA,лŠ$•NœJРE8і0iБlс)i}#aDФ‰ЩC€|РЩB 2ї‰№,\:ю№аВ $Н”DЧшш™yŽГїa6(I— Фяг $б€TЦ˜Њ@їŸ­ЦMЂж#>š<ƒW Šˆlрa ює)tэ‰хр[sЊsж=;CХ{ŸЖэ9bX…IЬj5&@|3яёРЃпї>s ѓЄЩ+€ЖŽБё]Ыы.ј> ЭНRжпšxЯZГыЂIюсЗQ!цпcн&0ўG>њvя}wїђO˜AЧ}x™;7єЂNhюmo{yћЏ€Сžь€[œ†@+&ђјЄžЄGтcџЧРфT^ЬoaLІ&у ЗдЂ„@Lgя"Ђ4ўрŒѓšyаTПЉ„cOI˜V@Щ„#ЈAŠ~0}Ж*Є5еš—?;д0a6FMЃаь’ŒиHџ'$Ш ̘=уњіˆ­OŠ›ч8ГCpь{9#‰­EB SrŒN hќ1lиавЊFNHjJm}п|ЯEТYпюvpн­Ў0(†Mf^4-sžќЉДЩБїyЄy4Б$р$S3uыГHФG{›šА&цмš3M˜hю‹„їG !tд~€aMcы+œКњъ+ztјБАДИЋ{Я vCO>=іиНjOŽЌ9y[яМ'ž|Д2„šqЭn*pќM]г3IцЌшfЦЋЌъОO$1%ЉРБћ"§1FЄ~:хXhAM„Я-- Bb;Г SФˆрЅOЂ7СЧuh/ЫMэЛd—)i}C!`ї|o„— Гьc˜†&…ДТ’aќД>ЫЖOˆ ГЇsƒ`|’ёeЎІыё-ЄЩG}`рюF!)wнgJА™>€6$ сб)щ6Ђ€DЌ№h"…и§Ј”йв^КyЩіLЌ>ŒcЫЧЦ'ъЏЖ‘WЫ‘-фбч—]и;ї}яwoэiGРЪ3Ж—“л^ю4„жМ6Џh#ИшtЦkRaŽQ-йЈжЭf›cbЇ&€„Рќ8M40П0ћž•єJ@=Šњсb˜T|є‘‡іl2=щ•ЙNIш $Ј{ХРˆс!Тxd-bI:2BЃхШHБџЉИщ в2:ОŒф5а€чbЄ~&$ЦŸщ”|~вП Ж€Ыœ;*ёхфK@Т€@йѓ‘ўš}L HzaЛDtтХ7ЏТZР8ЩRю7`ж•і€В[_•!Эдбч5рЯ ўћm яљ,CТq˜ѓ$юЯy:ѓЄœз9h')ФЫkRœ„§Эo~гћ-є$тdН}7що€'qўпџўїН9Œк_[ІП\pіОчzйl'OъЫ=‘‘ lеv OЁъžІ№БіЬcs†ОЛ€pГЙ3W АюнMg+WdЦ€ZИ_JТ‘ХЅ‚4бС‰Ащ1˜ €p 3˜ќxsгЖ›˜bšДїsOЧп0ёЫpHЏѕ2Ы,глtbJкРФ#’$‹{СЬЄ  KK(ч[LЮJЬŽ`ФћуLЪіч@€кч9џiОt0аLU B9анx4jЄ90HИаQјSˆe;0LЌПˆ,@1ъ.ЌКъ*хиВЗг/Œyбнѕ& ъ@ЖRt1}ВэZвЛ1eьиМюJ№ЎеО iН–Y6rqMtI"љГлT2н0аr,h.Д;tзUёхttѓв &еƒh2[в ѕ2/Р€z6§'^јpЏо$ѕrаПљVЩI(rКЂOЁj4їтKя(:BWц/эУ}*н}#­!šZuџxн›}LщыfА )$ў.#кS Г€ 9А˜›#у'S3iПё9|ВTЎŸмч[OПЃўрƒ•ГRpxyљ'&ѕSЩ@ю Ь>єA“BC€8аlугˆSиTїєЫзСЇєƒЛ§/вžT4Yь8шЧ ‚SљFZ9Oˆ,?!‹}<ЌEТ„€УШц˜?@:n_аЕ–зZњ)isR1rˆЮѓИW’Уњ ##xˆ90 MЎz,p˜@,žцT’Ѓт$†љIЉ/ `0&щ@2ћ?нp>т;'й“ћ ŠЪ/э“;/ФVъфяН иЉдWыХдp}щОн_ђ0ПШ BLЂV:;gkv€`N’Їпзёз х%K/РЌwТє€ {I  зšьйE;hIД7ŸaBx„H˜:™IфJx-в?Э^Гїƒ5їкzY;NчкЁўЧЩЧЗЉO–„ˆ0№э нf?ЯA#8Iwˆ0Йч˜Z3$ќм"АCyZЧ‡+zf@њZ\вKИPh у˜\L–EЂN“4IИIФРD :Вט}@Kнk…iІЄ L* „R‚‰ГнxZ|a~Dщ3LKz[8’= ƒ‘Нž1~dњ аф8ьРg>ћЩ3y<џР%хЬžйН€‚Я’!Xs7CР,RlвЎ41‘ёрšLj­…Œ3‹єA€йХ–ТГaІtR1Q€Zї}|я?Ќhх•і\ŠбNIш Є*FM€O" їBРЬ н‘ъˆгрЄЁІYМДwNgр§x&ИчоK-9S@фЃК1qLOBЫгI™НЮЄђ^Є?ИВ+qMзBh%Іf7їЊг8­\(3/Ќ‹ѕщзЯ~1š—TsbƘm4ЄЈ§йZ=ŽA@‘†ЊЩЄDаоЧИй,6`žуяH”gЈ$ЅП.ј]ыуH8 ~И_kEct^GАОйєƒЖр;оK• зИ.|ДрSR?ЭZI}`IkЪІ,шѓф™0ЏбмЙяа\Ž˜џ€к—hUу3g<'`еŸВmšВгblнєАшˆ0{Ч“x˜уЧћL-ЦL‘F‰3[<‹œЭТФ'P у=­ЧsxлgЏнлІ›lи­ОJХЏ—я9ћњњ ђЛЩK *Š #&D”А пƒИgŒ Х}/Rа\Вы8&кМ$4“к‹бйуL&69цЄ^’іi J]cђ0ЕЙУци}d;0ѓ „1M6Е>йHФѕcћЇz€Иg`gо='b%ЩЈВќ0ц"-И"ЙнC6Ъ4Тџ Ѓcpя™;LхќјЂx†€9L˜€ЖDѓ№ЇЃƒvРмbюфжЧ‰ышГša6ЏЩ›?!9ыFз˜pђEъ'в,I}y(’†фO ЭSO9nBы:ыуЙќNРдя'Œi~КN@кŠѓЦЇЯxP’хЯйŸŽ$#щ’№B]ѓAЄeЖЂR Ши"Ac3R‹I#L5жї“`яЏ… ПЗКџ^sѕeэЬгOš„I'–€1гЭ‘d€ЈЛЭч$m$Н{EфЫћTyЯŸ}HbsУмqLƒєќ'н#сŽsтШц P№ЬХЈлй†Ъ|cnїЇ LŠ.($Ыаѕi.iНюй5Э3Рѕœ€Ыџ]Р@ 9мЉ0МNЙДѕ˜AЧtЄб0$FцФ4цЬќГщeр‰‘а)ro]HL=е€ж#Л—ьр7=5Єебт€NЙq2 гЕЪіёП­МzКк‚пuз­Х—іњYXgŸyЪ_CF­=ЄЇVчОгЮёа:HZЯуѓ”йЦ{O‚zу'§Тcјьќ‹АS*]€I}я#|ПЭОЧьР aS ЮясЙЭ …уГ3›„М ї• <Г#NRvљмѓ’ЃˆпђЛЩћ47Z@њ5˜wDъwЄ љЯ:dg  1\r'0k77?y>w?ž“Т” Шљ=!;jэi`Йnœ…бКрw03šH(в?Т' I]g%ZJynі‚H}ЉL‡Ї€{јkРzR_ˆ4R_ЦЄ4‰hв„Ђ…Єћšh+рdн_їО=_7 єЌ‡љ,№§ѕ”ТђЏычЕЈIъ'bK{+Dž 0,2FВPTТ‰и-ъіAЯ^}!@ О Ёc;Z$9й[ ЪПуЕ Ч“Еgž}ВНчНЯЖ|№НЯѕв/ћ‚‚8ю3Я>бS…IELgF ѕїgŽ`Рє6$-b6ї 4ЬH†ћL‚gПЪ=ЯNФ]‚ѕ=цћcxІДЏ6ЇЎэ70)Fv/ЩŒZя=Ÿг:"ѕгІ=РNC$?щ‹!љ<ПпЫN:ЩiриDt€œк}š\нКb8šяЄ{3Mи‹Xp<ђi`_=GцLФиКFДфŒoˆбг(Л€Ž0r Й\Ы:D{LЅivЁŽЩ’Z{‚z ЇЄkЬm_рф›”д—&-$н€!ZŠ30>ŠD€p€yl~у[Љy›Б ЄжЦi№˜švЬ“2ЫH:Ф-\JЖ€Т˜A@gNL’нzx§ РЄ„sЃxЯтcЄŸ˜D“LRbˆt)&!1Г%@Ю…№Ч=б8мƒ{IwbПЯ,с№sЦ=щхї§n’WВЧе8%Љё-*„dВ}ќ%$"ч—пfяЧŒJ+ыЬoЪpiЩsЅЇ@MКД&Е;н„œА;Щ„yhmiZш Э97;ЧГNMa2ЉЦРo›g ЭЎяfИaIRГлNKMœЉёЛ`VsиД0œk“7gY_ Eт9kF`<рu™tBЫ[_Pt6)ЉЯщ,=p`џПёXGТ1@‚ЦмЙЯT а›ЯГMСo^W ?Ѕ+Fк-IjAйЋЉ„‹ЄH Ј„Ж07цŠЁГ+АЯHœьŒщ1$&K`РŒо'0ЃkaЮ€ ‚Жи&<Э(€Ev–I.xвX€{‚ўqшЬ=0 < р@ЃнŽ@hSЦ!‰ЎD_шкњ6]5­Оjлcї'0ўЉ'Wы{ує]Я=е—tBWю%•Єжн<ачЇЙes™) хзѕѓКБ“вО*Q€xШ%Нd—єg7љO,aФСƒI#С‚ЯHaЬN§tєЯ­Яг' {X,Ÿ‘4ь'€тu*|пРˆю)л’a~а(Ў`,ˆ…qЏ4‹HўЄ‹ІШwв цџЎцЩvт S9?uхР+щИЉeYEРЌ˜ЯˆНO#H;vв?yЄj Ќѕјв8VœŸ)нІўb*sdЬ­Фї’ќ"юЕФ%@gн0N€c/6Еg—5F’АЅцsХ]ЭЛпѓLћШGп?сНпўrѕЄ9qОa@я[ ы~нPfŠ™gыц{ž ГY#`GЕЉ аІћOх zЄqfЛКОАиb‹ЕЅJњЏ5lЭЖгліJвvVўЋ[-ы<›уwНМСŒпі[@&б4’| <г-ŽЩLHд§ќёue№)§XЅ Оƒкš–жьі’ѓ )ЈСliД@вљN4LЦёЧюwФРI&Ёйп˜г‚:гSѕiйJЬљЎ(ВНВ .к…Lџœ— ,)Цй‚9ЛВјNтз‰)cђdКaж$УЩ“5˜X=‚Dhi…†№’[3IMi™N~ЇЉJк†%д—HFgnБћг›Нљi $mЬ3š€()Эйh .з1RњŠ@­]КщЈє2ницj ќ€hCцѓЄЖ?`<ы  ВFЭЯЫДМјв'z}єЮ;ямёaС}{]žЏНцŠ \ћ7,1zWРH)ю!QBЬЮЌOвЏi[щЦФL%э­;MХ_ЖчB[i’ІЎ}3їоkП -cњsЯ=Г=0О§W@эЁw<а.Офтž9dЭE2Э1††т^Ќ[RŸё Žі'ДвŠ?%ž|]?/њŒЄФ„РL0i…Јнxbџ/Lэdbv‹gЂ1wі$щTЖьЦдиЄ9&Gp>УФs€™`ЂHQзp>Щ4˜ўїд~#PчvŽqNв ’фcС’ЄЬтœJ+s€р}Р"DЌ>ыЦ}НŸєbЖОky3ŠЈЄПФЇEЅ’ДАЩлчƘ›@вG#HП€˜œprŠTЌWЖKc 4пO{/їуО0^@Т‹фї ЬЬЬЗ$ХА.Р„Ч< ДлnЛtšdоUZШбгNkьи—™ыўюю-ѓЄ—Dп0рј$™ž@Sщю lS_‘Ž@пZб“aш9$&„ЕШКгLЦю[ ”FgVŽЩwм2с™вјуСя+mэв ‘Рj^н[:(к-,эл€Е№WЁЦ; gЌ<€RUО.|%kM^4U0qюи’ЅЌ‘кщ!InтуљЧt L 0,)žэ”Iю} ­С‚:Чч>…Ўэ\ŸAxŸ‘ю‡?Сї]?™Мњ$:br/Юuо#ЭhЄЗ{хcHV•?ЮЅ„n’"LŒ31ŽЮ F ю:$ie>йŽ$„їЃq%A уЇЕ8фЯVc˜8љќтжй7‘€љ-аа$ј!’мтhЩ3c–TlІіЃ%Vэа ѓPљ1ˆ\њѓk‡&>„IЕг:ЖвКгKOX—džќV’}ˆy­“пЏ$|—vцs!YG к–ЕLВ5Ndƒщ@Z[K- AТрї?pЯп„—пљш; „/я™Ию1kgЭу˜vЉіL? €FаЉ{Ущtь;KбтŒU TRъ“ˆ&=а›цЄDTЩё9Ь=t5С@‚C#’н{Є3ЦKСщŸ­УŽУЈ˜ЄwО#bє9ІŽэoђhЄ}‹‹ $0{2Ўh ~'Іѓг/ѓ#вј>b В%CЯГyф#UЈkћпgБY“4Cr"&ФшН”м"Ю9 рw^Ж ўй&;yI,ТРˆQЖ?`юfЋ)PЧ№Ды.Czз^wЉЌ$6лˆ9Яk}0Ebвqz†8yГ˜П0Ю:ыŒьIIНѓO>хЄI6бL}НЏгO;БЧdкm{>@ъЗК€IЬ%ЭУe?GscюDZЩ0Д–)Šs6“ЅŠаzЦДsmacsдѕW|№CЯзZ=RПyiOЈбЈ№CRТЕ{v}зcкkыˆс­`ХР2ЕЉ™Ш|њюx_вŒE@яЁІВ“ЄЖZ<Њ&TчiІв’,AXФD§dы’а)нДˆЄJД‚d&жЙ!Ѓa114щЯЉšqšШЈNqblъœsвaХbG›шv"ŽѓУGэЧ”ЁYЌƒJ;гч)’qNvЄщ2zВ iˆЭќ АЄыІg"bЁEљL8c™Ѕj~‚Д!­LœI"Щ,МЩсqŽНIе1‘L~RоЄc4ЈL Ї#0)mб0 EХ—Ђj№dцiЈвЏ/yq^&g>eТЩЋші§їЬцw? їлsѓ?ђШл'4бьЖЮžXWŽ@v6цї]Pv5€tJBFЁ§yVчћшЬ­Ќgќ?ю3Ž] K9b>пI@2єЌQZЖ‘рй•=Ф‚љ tbој€7АжЁgB+iэю;™Вx"Y‘1)­ЩЫЉяЯЯXPўsœOPXЬšъJ•hBт&ў‡ј€€›нnL”ХД‰`j@@bcиxєйХyг }!(еЮ„z3,r“/= ]$Iъ% €`ќHyр€иSпŽ™“Ѕ…ЈтєLђї0KђœЛ? 7)”B\цƒњMRУgЄJzІŒи{ QщЉя†8МАЕC\П08˜ЈАlSЬ&fMт3нHЯlн ’cЗмЗчHџ#нЂйtUUs„љ%ХіН|бEєhЃoыьnWєвГзЖ ’г@еŽ@vЏц,с;k№Ffs“И)Яb]’чЙ @!&Mœ‰n@оЕ<ѓFЂЃ9ZгЮМавп!žЬ:“…Žгr,)Ыiš$ЖєW оCSуMЪ Ъ ј• @a)"€щГч{5еg’€HКд{“^РšcА7“ )NsOи&€€љ}–юЉ о~з0h Ži-–<џh˜;v>а№ћоѓ9DFоKСHRNуб–C*ц”ївŒІDЪ#^G’"[Ќ#(DŠШЬ "'mФп1Мq1’зьy\ѓэїbZŠб,€†п№]f@№yВ4{4[—YиУ ЇyоdІw‚ѓЬK"=ц ИŸ@ЖЦBSъЅ'в диRРј:hJш“Ѓ‘$sьїћ ›ЈТьЉa`tkgnLБ$VЮIŠ4gнD’RКžм‚„ќH{Ÿc|ДG›Œfˆf"D"ќЖgТ‰*ХOсЙъН џЩbJёД*BЁњЇю›эœьЖtAEˆЩnъjЄдDˆ+™{Д Ž‘1НХ—hтш=L§Kž@ђ 0r˜ьQГ§iайљйfЪkc OqJ\“ідлЌ']вх8vq˜"Еa*в"{чAxв>€0 ЩТI—=? >ѓПї9Tљ € EЭdgfр‘vгц;ЩF’Б0Ѓыdї!NЖД-У,Ў•Ц I\ tїˆ€Pг нrКЁ3RМЛaЦФЄ>“%ŽЫЃћhž•АА˜cY[Œb=1В{v?]ЃgЇј2ЬU2“Ѕ˜ЭFzтььUGZЩ‹ЉЛЏГЅz€Ži@ ЙЉš~сGƒЩž@—і• ‡“h~пЕ™РкЄD7~Пeрьў“M@’ЭiRMЦџ‘Рж.ЁP Yi_ `JRПлR+ЉЕ Лa4šRњџ%З3Ч‰&‘Qїъ}ZZsуещˆф;нќ яь1БgИЬВ0О#J€FДЃ_є—2уј’Jю~’5-Чp !ћ]яG‹ЉяЭXе€%e~‚`Јэ$Ž х!eчyIєа<ы$Ў…HЇf…œl`L*іьмиз&&a6 ˜NГйЖй$zэ;~+лGa žЮ5щБ–и}’t’Ё‡ЈПХ%Ѕ1 Т TаHXf:=ћУРТyToŒGZ“оќ‰ѓc~џЇIgЊђ00ІІ% @sФ™­Ф=˜gѓ h’М†яn5n-ЌƒћШйяј0!8 yсгР3ŒD€YЊЃ8ІW0zБŸЭYœцuRаэ›?1ЉпmЉеQfФ!ˆ™sЬЯhщЄ`JRП[cпЉЙŠ*э~м : ХЂ “ѓЎ9iЩЇ›Я}–врn•`:/гФ0=кГvЩˆџ ЧО 7Оє№ž{ЇmŠ ЙFŽ@@ечю‘ІSЯўлзЕиgJ?VЬ№{“ЫFЅЪ˜HˆЈч s‡ зЉMwnЎщ5щыЗhю‡6Aq>[Ю‚Їw!pЪFЅ€Х§RещРєЎX€Я 5œЪя3„ЧhЪ‡@„ц,>ГAкЅ `ј˜#I4 у'е”Bы陉РРЁ(d›Ц Ў•.ЮЩ piѕ?ХM‘Кўw^ДЈ”|OЬаЗ‘Іій“ъЌcГ—юІš@”`>УDŸ$-ХIчљЭњH Ў9‹=OМЙt‰л эZ ˆNE•4П‘пNвN7 Аt Ьn]<Ў'qB~OšТФБыќдždGi _~œЋ!Hь_H@7u)­­’1†A0gКЩІ™FоO3PŸг0lв~A2§RщЧ ˆi€“)3@xHŠoТ‚$0@РœЎ… i ЎmaНчГ4LV’xBГi–gБШžУѕВх"#§Ÿ 'Ь ц7Э•ЯУм)Жјiž’~ю!^цn% uI@-Nc4Ѕ`в№Јџ|4в?=I&‹ыђTІ”9цRz;‚иЊ.оїлœŒ“в&з>ЛogОРœŒц†`n0]Зькkѓ›}бJ€+Qš]НК^РИ3 †а№ЯZ'*BЬŸзIъ I5Ž)ьїаЭoнкWœІM9цNpцјK2Г@BТJ/&Ž‘ЭY0\Bl10ƒїЌ7аa`VЄ%˜#_Pп(@6ݘš~zGq№_iЂ+цšœL9є•–уEG‹йСкfWІД[Ч№Ў•ч5Џ8ЃІ#FuН4‚‰ЦсhЭbпw5гы?EВ(“-š~ЙšŠлМZc~#ѓšЬYїY|ђЇзСЇєCu“ )B†Xq :nо„&С"  З™ИtпIIp$1fДь.GLKЪ;у{ЃG#HЮ>эРBRџœу;1!iю№01h (Хa-„„ЇYј<ЁЪdf!„ё6NбХЎw-‹Œј<+ц4/Ў“њђHќ„s*ѕ4*Ф`Ž9џnRKАљ#љг ёg›6IYŸdabL\ЮЩь3@ГHЎBŠZHЁ˜1˜~ƒ&бm &3‘fB 27} яІыЇgƒW[Лѕї–~џ)ЦbrвиэIЌЂЉЄEZP>Я|бЦМ$h0Ѕ€?]yЌ5` нœ4‰‰щ“ Н8$H@X0%ч‰Ž$СбќXчдW^x…†wвШњYІ$­И„цІФ—Џлч5‘kЧё‡ ”"q›‡Œjц2‰)ўС,ЉЙЧŒѓsиaў”їz?6НХа˜лыhьu“˜дK‘ощˆйJ€†Vї… т›hї€……ВШЎŸ&“˜лТ DDф˜]p“‹™уžвЪ[d#!шsЊ$чVТMiTi>c›bЌЈ§ьСT—EхOaL6/ЁњGНO3€ Є3ЈьђвS §Rи’p iшŽCе…zŽ ]ЭЉЙЄ€Є/LЉ‹Ў]—[v™ЖЧn;ѕЄП]’э$fHВєЭЇс>“GA8ХР'@ъЃYїHp ‡˜iЩЙаё-“„:yRЂэ“' В оKБQЎ‘Ь>МгХ=ЃnCРNРDfoУ(3ŽАdKЇз$цЯж_1dГž.@ёј‡Бвј#a1Œ›^€T9Lео1ЙџБз0/&Ь9ЩŒц€8]€@А`~Пѓ ћЪЇюhyв;;ЩzЯэ3ІLР œјŸdђ9OКmœ€>MрЈлЄTТOЩч‰Иdу•tNїŸЈНlџ.1eW`ъОЕсќL(аZq"К$1љ§xЦНІ†rъu[‚q$rD&П#Л§bNDMє[eMJъьгIїЌъДѓОї?зЛъb^ѓfN€2&ФриD;Ё)e›Д˜Dž!ž{Њ6i.mЬд„}“’ Ю88уМ P$§8ОLо€H%ъае”Ѕ!ˆ5KЕ к–0—ТЄ$"е5РьуЧ[ъhМ15щ;#XŒ‰hadЛ‘<ЄgъЉcŸc иџIЯ…Р^cN:‡iуСГCm^џ8 Ц#Œе“ћ&ї=GšC|ю1ERld КŸxђн{МДй|"Њaв=“gЕS€fDЛш†г09ц7€ЇyDаЎ‹№вЏ?Q€ЄJ8“№“ Б§Ѓў“ўœH €Щ`X/Rˆ6с7"ТЄ%t[‚йўкѕм7­-Х-ž)•„˜дГи} ЛcŽољ‹,ВpmЏ5ЄЛы„ўzЇœtlнuR€?єсч+GскžЩЭ КKRђВu[дЬOwŸYї$vЁЙ˜ I.У @$U}йк -$Ы1Э;1rHО qь%<ѕ й7 AЬГЕFДSt‡ОRР”JCїѕёO~ьЗЋяЛР5Џs嘁Џ?д‚\D‘14ЄRьќOЇKЪЎ#цРxˆŠCнЁ"“Ю˜6€†ž>УШ3Ьч cВ“0ф)ŠC1mЧSќ“§рЈіi‘$Iсžн›ЩOY0‚шzž!Пя`tФЏsоwЄ{&ѓ*щ8HЯФоЭiQ’n§г§Б#ЄxўгЉ™TЁ`~ŽОєcдД%л €4ѕО=я8ьвP„­Ёi>ц„&Ÿ &Џн'ѓmєНѓ—Љ­ГFЌНVЏ“n*ўЈћgŸuZЯ-еIїю{юœАїbšnЄQJд~Яю9S"L‹СŒж­з&i)‘ЁdŒM"ЉСЩ гЇУS,љ#IANКЎѕh?`ѓ“:0?iмЇ­љVж 4IsЧќш"ЙяxфЁЖяѕлЗnмрO#оКдћG^Еь 5ЗѓMЂМіšA-№УJR› А ŽTL9п&оУЇ( гѓјcжЄњЦюw~ђвЊЫ9P1eРQязЧп1€ э6 ёО“њL™!ЊVю C~ЊМї-"аˆЊH{ˆР{Ъя†@Џ$зїЌišm&c.§ К§ тмє @Ћяn:TљУ=№Џ:щžQ6ўеW_олЦ-ЖўЇ?ѓЩъКs[Я/9июЬ#з‰‚yhfž šЇtјE/IџіОяZDPФі­UЗx+к[*CD$Sœ~оЧјоOO~ŸгА’ H’H“Ў@b б`6Оаu^З ]Ќ4\\иЩжЦ– XцЙёЌЄЭФ§iз}э=ЊЙѓxоЉл}5’^ŸПЫ/ПИ=ѕєЃе_OпПЗн{WmVzjЯЬШŽG(хг᪘SžЫМLыD/t м‰šVэLЯd;ЪuЭлd'!LьЙ1!!сћqfг трM7Є„„Эk”M\™UЎ•ћ$шЬmН{ŽёљўНѕwнwg[яЪхлЈo[<ИJлфЮmЭbўGЯбЖЙoѕЖХ]ЋvШ‰KŽ[эиw\эфљ/YэдљO_zщ О‚зNЈz НцГŸ=g‘Кmі%ѕ>v”IЕ0ЉмЫ&iќ‘`що љЅ@Ъ~1<€ ^Sч˜L(юМј \' Aгm•tˆщсГnС †Žѓcѓ],чЇ]І–KПЯ@іœЗˆЉ—w-ЬCraL ŸюAiтмJГ ™("Х($+;q!цl‚љS€Ј’ш7­‡ўйЯ^Л.ц€Ў@TrmЛГъž6gC'U#ЃxлГЗaњцћnЊхм#Рўx@ в=NНќЏЉцM7пPЬ|JЏVТ}ЅоТ{NšNr|N+СPжЪњЇбЇ9Ф€ЩлOТ Iѓš”{c&vЫЛщЮaђ”рf>zTt рsb=ГІ€8lЭ ЭЂsРтšh5€ЦЛNG4PП§ ’ќЫЗ­\Ѓ ПpбЖуыДЫџ§ЌЖЫ}#кІзЏм6НyеЖСU+Дu/_І­uо"m№™ѓЗ!Ї-ємxѓрЕš№+= 5tЩюЏВРœŒŠ•ŽР)ŠmАц s˜2y&FCcђб0>fNV`Rr}Ч5L:dMbB>йDТ9й}иТPsЛ9ЄПЯн#Isчљпu–ХDLЄЂKоЙХМ‰ГПн›ѓbКNР`Њ„š\У“dˆ–*‹СYВ7@ЖЇ.ЧVуkfP§ig˜Гщ ШЋ@pЎa’е™ъЗH~Ьž…ЮuOЙOG ˆ…{DЇлIїбЧ*™чў{zћd‡bŒЭ” ƒR• —ф.Єr’*VЈ№й+вЇЁцЗоzЅOі|ЙО8НѕIœгЧ7уSщˆnSПŸъ>ы‡љу А†йQ:р=ДќћпџОЇЅвc"Лз8Л@hШ3šџ›oЙЙmwзШЖЫгыЗ>М]лўQэ„Явnљээиіmg~Ѓvvzi—ЖЩѕ§лZЇ/иЦ\; myЧjmаI ДшwE˜ўNТzШkт7il\j%щ˜$Šѓ(б€tтС\iН•І ЕЛБG04†щ˜цŠДDL83€ъžЊУxє“1ˆ Hl™dwЩ „иX‘іЫтИ/ “]}NЅЇ:ЯГ‘ZиЕя'%HъDF\+l’#›_"VЊŸcTьд Ї8ЬщwыbДдПSхїы ˆсЕцТќтѕˆЭo“АжŠэё˜9@BzЎБГ›БgїПпЧlLя=УН'sPЩИсЦыJЅ?Л8†kАёгŽЬsšŒЙ 0Па%`АжшЃk’jSѓлб›Cї@ХікНc:ДТ*хК)aNˆ-‰OжЦкEГKJnŠr’qиэрyЃ=1Yћ˜P)vпР& oM˜kё3Йп˜/ћ_ЛKлюБ5лИчGЕ}ž_П}zd;њЅmк]КБ]њнГкСянЎmzЭЪm“ыДюкvКxлђЖСmШё Еч/ењя?з.у}|гпЈIО-Ѕl`*>bЖxLн_дѓ8s:•šДMБMBrqfw ‹щu!Dѕр= шR DњЛnі6И8/Šої^њХ{Џ--Рui4‘Єќ:Ј%љ'вгѓ%8bђё;Лі~ЧuSoŸи5"Œ*РТ№1щЎ4 Fђ’4)`сЃО“ДЪl ;9LEjЅ[SœgИД 6OЪГЛљТ(Оуїbл‡ЩЃЄd6к€їГйfЖеN^>mЇиШ1aЈјќHB’шGИв3ZR4{A˜/Œj^вяДХр@>ЩJюСч„Bš€˜ƒlЕЎ[Аы$qШ§˜пњ$q уК~8“{”iзAO|ю• HЩєД†qІAˆїЬЗyAцјђл/jнКKлтІ5кЦw/пvz|ЭЖяћзk{ОkTЉџkД§ž[Пнјѓ3кi_кЗ ?mСЖеMЋЕэякжщЇšяRoS–Šб˜iŒ'`L˜ј гmияёб@ф!$Uš$ЗЦцб§gЛlŒяЎэ3ъИH'3!„цЈјцк}zДЧ єћЎуўК&@ƒІjЯuЭ ~7ЮЮј`œKрp$ЂMBРu0wT§nН€їаNђў“9K`Fћј‹mчпrFvбm“ђюoір ЖљCƒкЈ›—i#n\Вї•=к.OŽjћdГvЭoЮncŸйВћљ=л™п>Аm{ЯjmГњЗоНE;тЃлЕБя\ЗОb@[эиЙ_*Ž—44яјарt€чS(тЁвь# 3IЄСаЩ$‘,iU1ЪZЫ&—щNkтRSŸ†O?€˜) Šк–ЎС˜Эт№о‹Ѓ(x/ Jљ#€АA\щAˆ@$щб ЩŒ'ЄЈ”Є7ЦПРЄЌиНЇžл‘М@Ю=#к€ЅѓЂFb:/Ю!}hRйвГЄž?v>ХЄ˜Ÿр~-Hт‹п"БёЉхL†Ў€Р­…пOЄС=Х9I“pнД УPвЄЭyŽ˜(цЙѓж-BЎaюКBц”f$Љ˜4Зш'sЯ5SПŸД[si RЅz nНcаВW@ш6ŒЩgpo]‰яћ„‰O˜ИЎѕKPŠ{ќсЛkПAЂŽž)Ђўи‡кйWж6:wH[уŠyлш;—oG~nџvќзhћ|лvиЇwn{<ЗqoќБлШђњЏsйвm‹лW+Чп*mпїlдћШvmЯЧGЗЏXБm{їА6єŒХП^ПЬј<~€щћW’юЉЭN—G ˆШГе†СœдОиє‘PK…uЈЧ]@„Б'SПM*Їј&ЭBЂ)№`vЬD ЬžMB€Pvі§ь”z~ сќ„+тіНЈ“‘иŽ‘Жрћщœ‹ЯўDžƒџУГ""DЦDдййG”Р\pšБiJIнMбŽфЮБфХЇU9blls„xЭ!ЏЗsГ%U:хєЮяЉ$м'ЦŠ#Ѓ%сœЎЄ'=_|Оƒ&в=ЩГ0’Ÿцићш$MY’08'Iжфx.&†J\>е†46@кэє0|ˆЂ)$ЖЮŸHР:Кvr/’s‘ЦŸ4‚€€ћ№Iрr]ЏгТ‹ж?f]РРg€&#iСќ7@зћ—еў‚лœ9КЌ˜џИїŽnыпОB;яЧД“ў~џ6цžелvЎнŽњЛБmЧЧJгЛЙ[ћт%к*'ЮйF]ЖTћдњmЯЇ6l#Ю]Вчиэбк цќЅО_Пмx?€ДсщћW‹ѓ9‹эсLB*Ђ0B€˜пТЅхvjdГъ8‰ŽйЈVЎT*}бbЏЅЛJЎЭ™§FšŒЬ™}ўт№;)?і)эЛiC–6e8ї№ђ{‰ƒЇyтєЌž !Мдї'qбЩзЇю‘‚ˆмРм˜іЏ|bсltЭ;йШй0€“mЌ тLОь"­“3Рœ9ЖоzыЖшЂ‹69њ=iЊнц#бL\/хЗЩQH‚R|жЯ§Кo&{ŸЙТїуїгБ‰ПЧsЄ'ŸљєьѓoФGBZЂ„Ъ0ЈяЃ @"$ЌЇѓRІNћ$ж;& НФп3%о|ыJXIщ ќ л&o yqіХЖVFLќŸcќfРBg_xVлђм‘mГ{WmўлбmџOTчэЋЕžоњŸжЏэјЬШvЦ?аЖКpлљБЕлўкЂёOћЗЋsZЛэ/ЕsП{@~іЂm‹›Ы„ИqЕЖжй‹ыИB…jLЈХћІ‰MFi—0‡Х ƒІё'&У”FvЪІœЄt}L4л Ѓ&я›ŠЕЊ Щ/pМё†ык>{эо6пdƒ6b­AНБёшQmћm6ozЬ_vщХХЄ/oxaЁ,"Ah щd7˜ФЄ„Яќ>bD щПЁIИЈїЄ+bЬо˜(jjjє!>цN‡RŸ МЯ&еBАœ`цЫяhйМнPaТqZˆЭМЇ‘iтвЩˆj8 5ё8—4J0І@Єa"ж$іАc…Ь‡<~ ц…k‹Nјœ*.ŠbM3їЉЇА"€щтPП^xЖГц=Хы=Я†‘“Жэ5А3?hг9бh‚О›ўžЭџ„3 š{`р”$ѕн“{щњМ"љЛNОdF;ŽрY їCѓE яЌ†Ч^PГ{†Жm_ЃђщЭлzЗ/лV;oюЖЦ%ѓЗсWWаcУл™џ|`лЁŽоЖb}у€Ъ\Гѕйъэ№ЮѕквуцjoYgЖЖЦ‰ Жѕ/а6Иr`[dшœkѓ/ќšDJт}вzАЈ?Щ–"вџD[4в9š@6э ІŸ{_ •v€ийd„нІŠoљЈйŸњд'лЙчœ^ u[вc’Nžўй"ˆ[кљчбvм~‹ ЌПЮZmП}ЦѕЪb&ц‹hђ[‡­Œ0zѕ!|чC dё8еœ›J<хћˆ‘4УD„єTq;э­™@аГrFvw"2@ЯяК_цI†ž{F Юсэ‡h#Еу‘wLC‘ь]00Њl@@ђынsЊцвz,{5ј­фјMРBjczˆшƒмZ Т|CЫоs`ќ€ЙЙLЇп€Е6?ЮБF~ЯНa8кš#@вЕ8)Дц’Й˜І!бФмщŸЎЧб0iFцХ(ЩEДQ х;Iя Є~РГ ља}м§zЩп—снПйЎd(ТшpьоmЯ“vnыŸЗ|[џцE*ќЗD[їЦ…zNП§>4І Лzс6шђyкnя^ПўЯ‡Жў'ЭоF\Лl;ђ {ДuпК\yс’%љoKя3Gлр­ЋЖЭnZН§к<;єk+œ8OxммmЋћ†Ею.i^ў€юи†^КHvйтmЃ[WiлП}DyёвmЊqљAXЄ 9w6твЅzРšЇ/оV 6`њ§БўЪƒ#к„60ПЩ‰J… “~‹8RЖы €NZnкt‘ђ} a@оXоџЯОьўЊ2ћд‹kЗT љ 'WNЇБНОwЧwlХП/,Љsw{с“™_tvF_Ѓ]}еRГЅ |Ф,Iз`> ЯФvuŸТ@юT‰cГ[i˜(аУаz›mДКщР€€дK?>GŸЛBJ“Lƒ0’C№вЏљЬuњрc$ŸЁйт˜Z!%4NH&LЬ э\зѓ]~ Іƒ#m№мcrыhоHH4‘ОіЄ~К yЈb$пё qРu ЅАЎƒЁS|Ьeз›0[/=џ}зowš'РKуbjЄ]Мk’ШцпEАљ?@ћŒпuіY›0Мћ3№EРк§мzяЭm›ыжў›ŠОб'Џж†_Аd|ЦmуыVncпИŽƒлК7,пжћh­Жѓ“#лиwoмі|O­Wy§w{zL;ф…Н FЕБЯnиv{bЖў•KУЯп6МjљЖйm+Е!Ї.а†БD[уЄEXПќxGрє ЎTXDW’-оџь™ЦNFГ A21&Kчž.$(=џўу?~мл;ооq—^r^лПН{Й$S7ЦЬ™Цs~знЗO /8ГыŒXГНуЁЗOш“†%@ ‰=cіH#SЮDŒФІ˜лј# …6`.CМйёGNŠЉџЭЁпK’KђЬc‡Ї‰EўOŽ>;›$ЖЗžyяЦщSO@І.F”У r˜'ьx pKwоћЄё™l?ьгдs`jцI #'B,;Яц9Y„HзˆѓЙЧєLЉ1IYВЙѓлй•—?УњЄqŠљ ‰Qё є8ЬЕ{ХДIђ:š—зtч P w ЫќН\ŠЛoiы\Оь$+њ6Оy`tђЬKr1C0~bѓŽ—&уо“€A8ї€&№§є4ЮѕЬ‰8&B’PЂ6)fщЖ ЫМ& —4ѓ9ІJоzМђ>Ѓв+ѕЅ}$ ™TLі цH?ЙЊlїlmЦЖ—`дэ`I’ЈRЫl@ щ™вIиы\l§Ў6“–шн(&KдMR ы:„];ў‚8§Yz&šУьдKъ‹ш˜ѓ<ПІŽГ5)ио@пhDтGъ{?’пКбšіОd‡iЎшzоЂmЬн+Ж­ЋxЯwj‡|dуЖїsыДюмі,рвйŽљф.m­гцo[\ЗJліŽ5кšхќrд|m›[ЗMыН­oYН 8 _[z—Зм3о а3`њј YW‘Y”є9ЧH˜&qq„ ИйZs$Ÿњ˜–м)а!Y'ЅPџПњЕк(ØљъЋ*KюшУ& =‰oOJxќ‰Gzпу ЌЛVЯž p1KЈВйБQtkу“х‡Шј ˜@ДOѓGР–Г]щт7ВsтЂ$ѕ4Ж"‚Ц$ц4NJDхќ$о˜—lтI@дpдrїšДедшqzQщНІУр]œУ/`>CG Zеп=x.Ящ™ќ.F"HпФа“cяЗ#Е“LЭ$-г4™Ў рй“Š LHыЄ"'Мš№Ап—ъl0_H}Р$˜0з8 SмcОнOL­$БбRЂэНHѕšKOWеяЫќЎЭgф^N;§ДЖеmУ^QEпZeгoўрrm‹ћДЭяYЅmtcIљћ†ДГџщ JоЛэўиэˆvh'•3№€їnвvЙwxл­вw{`dлыБJКl`Аї[к€ƒњ}oМ OРє1jВ‡B7„‡-drмуAьš^c tˆЪЅєЖ 9Q€ўPХzХ?_|йў?ыŒъ{_Р6ХX|{RкРœзћП@Т…˜ѓЦWXмfЪо‚Є7ge‚єОs^’žЩˆ$lD]ˆЮ†˜РѓEњxЄ'DžˆC˜%~h35њ˜€аЦ+Х9ŽFЪUFЂНpкБх€P яІ)ШЪ+Wўyi2SIчКж")О@Ё‚@Š…0t*н›ЭХљ>OТPР,РЙЩN‚;?~&L_іbДђмњbЋЛM.Х;IЪ†Ÿё-ИѓKpyЖДрJhВыšю:§В>б ’nЬo‚љ™Rc/Ћ<ˆWQб7њІлШы—)ѓaщvќWЧЕ]+2pР‡7kз§њœ6ющ-кq•|жЗlлнНZлМЊzїцэјOUЊѕs›Еmn^Ѓ­wўТх˜ї—Хј+Mз|€ВЏЦФБеƒžё†ІqBЪ6У1lg‹F`Є3\_'`зн?їЙкМљФуъi&FN9ђФД>DьE„€йнKњЄІ@Бћ}–VЯ)СM%brЫ“ Щ“їo>\?&Ez ФTœEЂ9ˆFк›[‹‰Ѓj#\`‘tU ш™йщœ\aШєLj0‰I) Щ^| .И`T.ЛьВНфбьg 2оњЩ РаЩжDЎ™|ПЉ“•фяЅ в@xFдsФл“)—"(Ÿc4ЬŸ†'щќыwиєМљ„š2‡˜9֘JIŽŠГгЧёšf­hИkыG*?ЙИЇl™ѓzњ'ЕБWoUykОъŠО ._­S)С|ЄвЋі_*№иwщЅКlйЖЮЅKїlў­o_Еэџюк•Мпг›Д­Џді)gсU-ИђAsќЙ˜ѕ‹ŽїМњH@!юЎ€…D!rDMеХ№‘јqќБЅE0[ЪiH^~‚Ц€ш] @и&R\›ЉcŽ:ЌчЇѓ†OIш дGŒ˜т‡ йг(еeў@$—гв3esVh ]™ яљЬыиСц+]“˜!МB‹f\ѕєсCј:Œјh~3y’А“њ| „™ЊxНŽ=@[0Z“yHЂ&4hPЯ€ШЛЅРibэ“‰—мƒќЖs—эХ{г}ЬЂ!Фл“ЩGOPЇЫ?E€ЪсЭG/h-NЧД0 ˜sр^Rыpуˆ4jFЧр‰j9/zГНnЭзUXј–ЫлюЗik_ПиtЉш[хиyкщџph;сЋћЖM*xћwŽhGK~МвoъпF\Мd[э„Йк:—,]ЉРыЕНžЌ\s—n;U-Р‘ŸиБmsЧ6јјљлЋЯБQq§туѓ^=T†зе<ЦI| ‘Zмn2iI2ZœДУќнА {;Y‚йЄ3‘€˜}џ5кыdЋБ%ЕvJк@_ UFЯЮФщTœяS+“GЩœЃА‹щ“6бЏ $ Щк\uЛв$Š‚“"U5*1f7'IJр‹0yќ>э‘Ђ>S™ЏO?­I”DVЃgТdI њЗфФЉ˜Ф<8иb€A1Hlъфк“Ј‘ Ь€Јп’њњ˜|аИ/pXБc9­ІЄ єvd:Чbќtr/˜>рppЯОC=&}0Ес™­'ЛЩbш„EgzФLJ†X^МŸ2csŠX“№{>8˜зДЯФœ†Я‘ŒY™.€R”„Рa*…7…F2Г(рЙвгzmјэ0AЬ€јќOКGвЧ 3ЦD№lž3€v0ЛiЕЉPBPћЭ[ВёhЉND‡iгFЛrљпwТшqАF3ˆO&Ж}4ТЌ[ГЮ„кO?о.ИўьЖс9kLЗŠ>9Ћœ1WrI%ј\ПxлљщЕлйп?ИэєT…bяXЉmtг€ЖнkVip­_9—йcЎ6л№йка“j[\ПZлщmдЫЖі˜чєщ (т?)+Œ ,zъВM|Ъ3?#ф7a(N5Œх(-Л˜в[јЯn_аЪZ/{kJкРФ J@$НRRށ—{wtЏдe!3’!ЛЮФi˜PaTџЎЄї^З/`dGš`<сЦНУ8ѕКŽ=Œ„9@%ц˜ѓЗф-cQщ9љ„G†u”$ѕ`:špxn@ŸBР Ч'а-Юƒˆ„.гВ+™|I(Nъ4fІ ZџЬ3† „Д^3?ёшGѕO4$Л/uЋVЛй•Оч:Ф§%0uK‚“vmŽМцЦаˆ.Мш‚ЖещыП\бї|UєнQ}?ЌŠОЈŠОЗM{EпК—-пњиХ№ыДЋ%иMэТvљ/NnKXч–хкqпиГО^SакkсТ%к’{Ьо6ПqXлЁj 6К|`їд˜Њ шп–пkЮл –žnE”"ФCђЈWG„Є[š&’Dˆнd…1Ry—,@GЬпЭРp}M€О @"аЫ>€Cл€šЭ'Оšœ601РhЄ7ђћщTœшІЧќЉd6`ЈьJ”иxД0}UdnhДD–ъ0ъПпї~в#‘ЂФ6O!Pдџ0XR9яЂЂv~ммJў  ˜L40 ‰ \РГЅ@˜]’?ћH˜‘v€IмSЊSAщг%]…|ˆњн€Ш !’№жzžф(Прё} ЉСqЎњн8VЎ6зFДжhaЩНHђ.ѓ;Ÿf‡>˜Њёƒ  ЯЭqzњЙЇЖЭЯб6ЛoеvQ1ўŸЌz‹wЌжv|Њі\8Н_лЉTј3П{`лъП­шЛНTјsПї7}е§gГЖяћЊ“вУkДъœ‹ўчЄЖц•‹ДMя_­эўЎJХО~љЖх]ƒкюOЌ[>%к.ш…ЗО}H%ѕЏю@ЫДUŽžџ“ХќzиLфе‡+{Э 'юŸ6Z‰§С’РžŽ@Еюš] €‘€jП„АВБХфДIiйІ\Šh6 A€юHecSЏ1‰bŽ@ђ<+ІБљГзG ТLД„jJњ8/yф-6h"aњxХ“ ЉŒШ€(@*иH`RIдCл0šцЗV]%ЂїsNЖFd№я0q€:MBг‹аЕЃdЏ‚˜ЙЏDУHоУ,щuрўќЎ’iТ‚ГWваIџФh€}eЏEY}ншHДŠTл LьsinЭe|Щ уЧ—љѕ]р€Щб!@РЙ‡ЏЕЅ]xЩНЄŸюоЖ{rvичЖhмН\[§ЂЙла+J…ПaБ—Uј=Иэјфк•лПbеѕhл>0Дѓљ]люЏп–оГ*њж­ŠОъёЗўхUPН§Ž|aїvљžжŽћвИvLIќ]пЗAyэ’х мЙѕНCкич6lG}aЗvюЏNAЗ1•QИѓ#•4T>€-nм6ПyP}еŠП_rуž#P@ЅСЏЮPФџ6qX СЇ‡’зй?.сОdFтc|ЏZщЯ‡ёдt}qіѕќ8ЄЦтдкš’609'`КG рє‹sв}І~!>€žCВldD’ааCРьF@IъЇs-pьfГ‘њбBИ‘HTр$ЫP3{—8SЬ?pД1L…Й™Ci/Eк§`Bj6@Ћ.хЛLf?@з HZЧё'яНз 3ЦЩ№~ю7} MB’ЁщšцуЇ79 FКЇ‚Єјƒ’W€yЃ-™Ћ€ЅїУр>3ЧМJ?УьП€ёi!ю ]ЂUk”Ю4™dYZЯsЎ<Нuёm“ЫVnмКHлфў%лw,мЦОoНvьзvhЛНg§Њчеn,ўВ_žвœ>{ЕћZЎ[ Н~I№u._ЊЇТ/БчьmЬCЊгOЕ+л}г›Збз.п6ИaЩЖф‘oiƒ/}Kлћ§cJ#иИіТЖэ€nQZ@•u?8Д­ѓжeлšч,д†ПXльжUKњ/гЦдо%§лкu­еŽZшНуS‚_}e`ygOуHˆh"WZP“2дLRRBЩ„ў"љi$kL€Јмˆ ЛѕvЃ“з™Pз.Є5%m`bHkђј$нЋ|р' №ыЖїL?]‘В;І#егд0˜7яƒиЃŽ@ )ДIВJs‹фОwhЄ/&Г“ЌL3і=3уfN=к&ЅОcєџМв˜ЇQERN›~Д. ЄЮ !СФлAсš}л- ћт™›˜˜4ХB˜?эз\Яgйњ M$П ›!ш5К‹s:}%rДжб™ы&Єj]RJ€YЗјќVœŒщѕ№єГOЗэ/]Џmvy9ЁO_И-ДUєэкЏ-uLПЖќ1ГЗ§?Кm;№лДmљџ*ќЫK…/3aЗw­з6(иМTxE=#.YМэја№Ж_ЉќW:яаГ—Ј ?–h›Wcа Ћf`‡'зjЃo[Ў— Иу§kЗэюкіџ№mь{7n[>0Є}Яэ˜/эжN§Ї§кщп:ЈmuзАЖШГЕѕЏи†НФojЯ щу(ьy!‹KэT`“ЪжЬўё@€}‰ИиЬ&ž6В;"шІgSЉР“€„Л€xvvК™’601АШ$wі'ШІ%ў70ОћXюнѓ DЧ`"T§ЄCјМ‰Е?>т|rь†Эт сѕнЄƒ4”ЗŸ˜dТ˜Ÿ“ж‘Ri–™ЭDTўХ *P …š Ь и„рЂXЏYoЏг8yMшV’аЄМ(ƒkЃh†Щі4_ЩћObSBŠНєЭ 0ј ’0•т€Gо'нcB%sвoФ1šœЗЖм:И'#ўsŸ6hЩЇИћэwЖ‘W.еж<СЖYѕчля›WзžЕЊ”w^%п9п;Ќ]ћЛs*“oЏvЬ7K…ОTјЋ—ЈFЅТџЫ!mwnG|n—vжїkЛ?Нaлшњхй_ЛmV9§ы^ЖBtЪb­џ!‹•}П\™ ыЕЭя\ЛэљЮѕ{aО>Л[лыйuл–їєo‡НИeЛќЇ'ДнŸн†œЙTлѕс1eŽЌS&РРо~ƒO^И-КYЯ ќъЬ€šќOВй„”,~ђСЛIDДTJТt‡‘šG“яšШtиMИ ѓЇX’ЧЄj&’Zl9­К-]n&Ѕ єФюЗ@œ~ёGЄ…ћпР 4>LдЋKПЛpіK3””w;њЄsЩТ{?Bь~s˜чO<„ŒљЈшTiЊ;­ авКМ&љ§!™Ў—А]іЊЃ pЖ šC4€`ыpOu`пб{щ”ўƒ:мH3–X”–`Ўe­S2 ­Ь ™м€0, ›ШGКanŒž Aљ‚|wbћ$ќ˜”щјК AЬ/fьйЯУЧдиКюНbўlШrс-gЕСgЯгV?mіЖг#Cкyџz@;ёЋ{єBsћ|xнЊЈ^§З/е–<МTј‹пRе}зFЗCK+иџУ›Знž]в{huхЫ*ќа kc*xэ2 F^Мlpј\mБэgkѓo3[Uў­Tй}kЗ1з-пvyЧрvъзw-р mЯїkЇ§ѓžэфЏ\^џm™fk‹я9[[с9 @цn+§–Жц•эЙгьЧO Жmи+ї”їћЫiтЩЁƒРLДЂТ’xвyI7 AJuiMH (МЮˆ‡кK"№LЊ!HњL цž{ю6яМѓЖљчŸП—н69m /&уfУвьZ„hAZ™б0D:і’х ў3s\QEHпСЄ' 5к@тбнјsъсЭ'f4дs<)њС№$7‰Ÿ­ПЬ)†L­Aœp!XD‹q™oюјОыаж…йж€^іp Z@RЁ­=їлРžЦ'Ќшz~Ым˜?їдв`$Y‰‘РщaѓЃІbnё'dW`ŽтЄCЧ?’ЅlSцї^й ­1еВѓ# VaіЄSЈmp]їхйВУ/лЋ­XЊўрSчl#Я™П­zјьmр!ГЗѕ.^ЄmqяЪmwЏнЖЉHРЦЗ• џxЉ№О;щ‹ЅНmxлЖЪwї§рцuN ЪвіЈ?ŽњтЎэи/+‰Оs[Џœ€‹­ 9nЖl1єšU§Зm…ї/9ўгЛЗK~pBэ 4ИљщБmыЗjѓn=[[љиљкЪЧЭй9[[ю йк2ћЯжњ:[э!8А-Г{ПkЦЇПК„ €ЂтБBњБAддRГ7MВ˜К…ђПаbF0bОдBйg =!4“юќ$‰PѕтдЈ/uФ!mŽ9цhsЭ5W›gžyz)Ў“г&~ г’јШ}'-˜Zhdgaр~1‘ћb#Їd˜‰ƒш“ш§4FaћЇb2-Ї’vJb!PРJ зў›„O=R=u˜Ÿz H\DщоIY@’№_˜ЌЋа LІƒпш€ѕшkЄЁhЖ#УДˆhzю !=їDЊzNL 82"…гq(ICqЌa0їNMЧщmшш>В;0КJ$"v|$}њ КпD0Ь  ЦјќRiВbюЃmdПяeнњ,К's˜bЄ=ЯлІpЬе†>grтьЕOп[ккgОЅw\pћЗДEw›Џ­xфтmф%Ы—j_О‚л‡ЗqUЧПsmтqмЇwi{>НNэђЛB;ф“[ДKr\љ6hkT3­яйF_Нjzц"ХьукшK—o ƒКpў*ZЋ]ђНук%пЏ„ЉOэ_ЁОСѕ;oiУЯYЂ­|д\ѕЛГЕѕЪБИџЧT9qеЧTd`њў€ƒц{l|JАврWо!Ј˜іћЄDД‹’њэ”€"t‰ш…ЉЯьzћА 1эA( ЂwРтЙžEH•”NŸўоƒŒ@1аЪ+ l§њѕksЮ9g›’601 ю‘R˜9эЩм3 €Yч_і Lк,`PїУь)ЪžI ŠWл|‘$;†Ё!‘юй№#ъ3ЦФф†з˜žЅ ™4Ѕq$\ •ŒНЈЦˆ3ХvgBа*ЌрЏ 0+€rњv}ˆо5€Чьн–`€ˆіЧG’ŠLџЧwЮ<9іНЇ4яHž3OžPЄ Ч=9LЧDœ"hВйˆїбNР›™fтёcг2’8хтШŒ&aуј3эv— ЊCRUн­~шmј ѓVо|mЫm{?Гn;ћЎМќлЛЬж(цншЪл7Ќн6ЙfљЖѓCƒлЩ_­mРЊнзИї mЇ|{\;щЋЕ№e§лвЅТ/БwI№ƒgoŽшзџрэМ*осі5к‘пІўс­лхџqd;уыћЕ=ŸиД: i‹яVв~Ÿйкъ'ЬгvyhT;цяviЧ~nЖы;7)ћбž&БвС п]ŒoГWЕиџmh&Лы@˜i–Є ЖurхГЙч™0Žъ/’ж9Р#ЊпФ€VЩ&>щ„Ѓ{ЙЦqЧоы Мщ&ЖAЋЏвVXaљ^ЛЋОк@_№Љ юf/ї…ЙAтќй >Ÿaє8ы8тˆ†€109цfЃ§а‚ЄпЬ"вѓыЄЫnvЄJ’9AИЉCШЖV —Ѕ=XВгКЊ$)FТ<@ dњ-’мкbАО@zќгв 0)Žцd нCќ>цcЇЙhўуаб=`Rd–mМ’nŸƒљ%4м# і=ЬžF=šЬIю(H)“NГTЬMЂ›ѓ”Вщ˜еh9?л‚#[І :rюЖы=#кaUŽЛўi‹ЖѕЯ^ЌmrЩrU›_ёўK–-`ЁЖl1tO…ПkЕЖ_yэ{qЗvёїocЎYНётmЋЛGЖyЗ*ў˜љкJЧЬбV8МњРйквћЭжь2oлтВСэ№їo[ЛџькŽўфЮэ”/югЮќЧCкОянВ‡Ћджр‹—3pHлѓљMлЩџxPлщЃы:‹•`‘ 8Ь§еЙŸm№tбЪNќщ…(LМE0ЉiRС H[Ј4!]йУˆŒтaЇHЈ‘иЁКK‰-Љ‹щGВч4‹0ёЛоѕDаЅэЬгOš„IћцЄЮc ‹uб‘–оOkoЯыЙ1ІЄ> GŒУ~–!щ5'^:b~›}IrЁг0іO4цаp„š#Z‰gOŠЖвY' Ё-Ÿ{†T№гДљТ|ž “Ј™шЋdПвM2• ї ,фјŽ{ХЬйѕйНЙŸ8ЄЎїаGZt™Kƒ„Чј˜Щџ>Чмо“Ѕш{]O}:§`Vs8ГСІЃ5ђ\p›Cj?ЦЯ–чё1Иv„M7 ѓ'Фщѓ$…UюлošCO> ~kџЖлCCл^ЎоЦ=ИjлѕŽ•лк‡-нж=~`[ВZ‡žы~{ZлфЊўmЁњдљѓЗБOЌе.ўnѕЌќз“лQŸЌD­sЕEw)ўЌ%кJGЬекБђљЯ^ИmxэРЖЦБ‹ЕЁ‡/зZfСЭkЗ]ю^ЛѓћЕ>Гk;ѕ+уЊZpџvв7іiЇќуўmпlQФелЦ7Ќж†žЕd[bЏЗ€Ье–=`юŸЯЗrПэ‹љWьј^™ PФ0W…ўd .В&/ЭRм’XwъМчЩLю=ЩЫўfуS­ Aб‡ПДЇ–цГ/›нёф“TЛ›{€ O Pа0фь3Oљ+pш $4ˆ&“4жHЇHt‹.ќI}Te@h.0НpЧ&5г“і†ы3}hФо^{г=њŽіФ“яЌмњЇлЛž{ЊˆуoСсc—}їЮЖѕV›ѕьI эомРuјЈ<є{Ђ^(рPFДїу§na2]›c R€˜ьРdџ1‹Јк€mŸ2рTІќ4Щ)$|—P ƒ%{0Ž­”ёbVR “pія_%J­W(”Tjѕь|k а89 `ЬЩIŸf#ЬІKд CXјŽђžcоУєљ ]‘Жд}–шэ„yтљВыS§E›№l>‹#б=ƒTQš‹ь№J㔈CЪ 1 V'Ÿrr;њДCлњћЏ^ZР’mЃк–{}jЋUШnЁбГЕUіьзFИdyjФбKЖmoбvЙ'*ќ.TјООW;сk{їrљз­€aч.г:o[fуйкАƒjУ_Ќ-ЗY…їŸЗэrпШЖбEчѕoCŽ^ИЬ‡хк*G-и–ЋAV?aбŠ,гж:gЙ6фєeўИќИпUЬ>Кл_1щ/˜њ?ѕy%њуџŽ}K•хиТ8‘˜№d‚%i"dž]T0B7’@“нz™н=0&$11[Z‚aDУ{Ю<№$ффžи…Tua-„#§еНГПI;„„№|Ч=ђж“ЬщqЯЩФ– Ha„„ћКœЄЫQZœЅRZ‚aњ0Ж‰NћщєЁу#p_žйsФ‹ŸїДK$С=#вю7Щ"LМ<žіфш#рПљQДiG‰SBŒ$Б{NОŽЙhHе=L‘ Сh|8ш"ŽЙH}чcњќ 9зкX+f“ЪkŸ››Ќƒ$'ївѓЛРСМЪ=хѓфCt[œЅ[rкЇЇšpІŸA’”€PA3юй 9ŽкvШЯV?|ў?:dюЖюЩKЖ-ЊwѓЋД­ефW:ю _оЕэірzmзЗ­н6ЅТП№В ПўšmŸїmвќШжЎ[­діe+Ї`‰ЖТИyБќVsўx§чkыžИx}ъ’mєЙ§+„ИaеЌд†ГHEцoЋБH[у„ХлкХєЋНP[љˆ…кr{ЬѓХЅ6›їК’ѓ›ŒW§эИШxяПjРЉgў:yЖbўAриЖ#&KZpД€ЄeІѓ b/  ­%ћЎЛ'@HхОћ0 О‡I1 ‰хЗКm›вЗ.(ЮwA­Mџ:ZŠя!и0=ІNš2ЭРНІЉi6Э^‡~—§йнА”fт=оћдјs‘}щ“ўKMИ€4Г4€ }г№"’?6*аѕs]ЏNK4%1і0 цЦгѓ“њ˜.…7I№БЖYWЬœf!$ОsтЭЧtLLhц3zч;7R=’>лЊЙЎAЕЯ\$WP0‹05mЪ|u# €'о|Пч7RС€Ьљю!T iVѓЉkФЌ#5Q‡šЋП?ќАЬЅ'ц\ј-З-НmПЏ:rОп­]RјРЪєїШˆЖћ;FTkЎm*co\лцЦA=ћНЇТпQ*ќ;J…?ЏЄuЉўTx!М!ХјЃKu_уфe~1Яв§оЖР*§оОЪо |аѓџiх}цn[ж5†АH[qЏйлЪћїћуj‡,јЃ•žя—§їчV>lЁŸ/НлџОФ6s|tžegзHкяа§Ч;ў^™ъ_ЁЊ#IOƒ—›s‹$Ѕ$c,iСйQЦdaЎn ?y]H‡нn' ь 0% PП•нљ€ ŒјHbLˆhихЉФ‹$Ш>|йв*ЭIRЊœve:вр„6^Љpє{˜мяџgcšF:esŒЮ <("тsЬžfTW€ѓRыŸ†–4„8­М6ї)^Aрщ|‹шI/в7qry )Км“œЛсcююZc˜\+Хaй€6=њ]'ћ%bRЏ#EšŠУ”6\S™Д9i XКљ]ЩŸз‰*XћDGм{ђ т Œнoю’(•Rч ‡0г`|ўџы>ПQН'dеUу˜'ЬЛм[ЎZr“9ž|иЂп~ЪТm№С•W…8ыУŽ* Нќ< _н|Ј№чЎаж8jс6тьeлЪ‡Я_aТ~mЅ#чЏQ[„ ŸыОКцIЎЛа ~7.ГЭ<\qмќŸ]уиEK{iО M0ЗB‚юБgПRк?]ip|ˆ?]lМЮ>|Є•?[—[ъМ#гMіЛѓ:%=лzЇ ч)I9Ѓ6`кfРж>в;Щ71hJ‘њшФ Q`BРAњг,#€ Цї ц @гфќNіbŒ=п§?в8|З›М“Іž?щМyнuњƒињ‰ зtўЗЬ‘ЯWЉљХЛжРhлŽ?юVЧНgŸsЖУ6чѕ+4ппЏv№ќпYyмœџ6ќЈљлЇ/б6€еMJAR_Pш ц(‰Dё ЅГІNЎA|%ЖnŽ@§ія‹ц?Yšв ХbщcjŒЌAН&emСЭЫЮоЦˆcч[aЖ3ч0ћ‹ыwЫъ-јНС— П/~ѕž ?pяйлJћѕћуЪЯџУЬћЫRнџ~Щ-ч~tюхfSЌу›gцыИйxц6лїызћ|ыёяћœД5ў>еq@ЅjиœкџЪ$?ц/ЏtПZ˜?fЯ8R№а €‚ЯКp`ŠƒBшг}їL1ц%е1tКЬпч ЦЃH v‘‘ВZPЇиGШ`~їћОЛЅyœ|‘јйі(`vR‡§nўŽiў 0hwПxšp.%§vZRaг"qе$Жј sЖв т№? – 7ВhТ›Є&ХДЇt`рРmьОЛЗ/кИmњш*mнЇЋ+э{њЗuYЊКnХЖлU›Зƒ.зŽ;эшžд"Fd$ԘD ѓ0–Я8 a~РЧЧAsт+aВ`јdцuўOЎc@!@ 6жУГЧ7 sё Є8ЊЛhŠъї~WЊў‡+“єшbвžtХьЄ+ЇšкzŒЖlkЌQlŠQkьQcџEжœѓъхЖ›ч§§ЧЮџ™СЧ,R*|П?ЏАзьПXn—9?V qfIїCыМнk`№€‹kљ§ќНіЛ$;F>ў>~•kјю‡дWђЋрGИoкеўњRяЏТDƒЈhМЏЉїПPž$ šЂ ЈžBФqуСNO6LuФю "]G`rњF&Д~Фм}ѓгŒц”d”Ю?щѕЦШVRќЙЧ44ЩЮ>Б§ 89˜>эОВїœ#5=ѕџQЫ1*PHVЁпN@р€q}Яљ!cј˜˜'m$Eќ˜н{жУwЛvКЄŸЅ–ZъџРђЫЕіеЖЙw­ЖщsЕећћЗm?Дjлњ§лЮ_­mёDе•п]Vо6МZM iЧ]~XO§Ї)И.fD'h€ ймљŸАрпn,њ‚љžчšžНt?IXž#Yƒaє.У'Г0[Е%g ‰@IE`pпIў†пLТ‘їъ~YїїОJ?МXуo8žс0šD6ЕpщjhГ…щ„йьР#с&яя6ч|Г4я’sЛ№а~—/ЖоœWЯЛТьЧ—­ Hѓ-Чџ.rіmээЕп%й1К#f<^ПџEj,T#ŒOъЧл?mџњт„П€C$§$ѕ‘ЭF ррЁM/y ŸЬ­n$ ;СЈУŒšЭB…нВ+‰Ь6ЇЎЧ@ Ра]?РФL€h €nL? Ч €VcќIIŽŸсІю?mŸЛЮ>ЬŽpSљЧLHяУфщ€ДњJњДšN„уfЋk "(­а|sЇ)F~bИ!bО C*GШж'R0ёZџчдBъПтš•вzx%œœ7ВmUi­{~zD;шKUnќЮкцЯ-еvћh%Ђ”&АЮ=‹ЖЭа6}b@л§ь­{Ю; я=ІЦpё ›”‚;b| ‘ R€! K.{ŽzŸ„ Яин,УЄаšЙpЭD\Ч<ИЧОPкЬЯ œž­bВƒŠHcёs’уc6Œй#Y1˜йзч`V@@r“ж4*=Енuйъ›е,$:S‚ДчАУь‹дРШР…§ю7]›Jя3GЬю}ŸћmБ}їб•јЏœёыBНПЪЛY+'„”А ЕкЦc в@вb›|ЫіJBPі ŒZлЬFK$ [„Ч РИIЪ ƒOJˆ3АЋ$щў€% ;рPџгžŒкўДOoУlp‚љSїŸpŸџЃіcjУ3cђl'žоЇ>eЯе| 9&Э7-Пm7>`ЪjЭН9O гРzХ“Ÿи:ІВn2§џЇіcўэvпІ'ЁЧX-ЈпQлRПИv;ѕ_ЦЖ§?Лnлт]ЕеsKЗ1O,оVЛiў6ьŽкvяYНmідJmЯ+ЖыE„81SІЋRЄЊућэЋПЈ]qЫџOJлЎЈфЩЭЧр +v‹…ХH*qЊђт_ јћЎя@\7~…”єж=џwi+Йя[c›XI1~WЅЦdў`к€ФІЦг †зX[е ОczŸ ’~‘}%ИыbjЬЩ3Ть>Я§И—ŒџОъП€Я)IТEБ4 \C•єВЙтiІv"рДsNќЛ/№ЌЇт.ЮИОZS ы˜ЄЋlL€‰FХx€ЮПQџ€ћ2H~Œ‰Oв“`ŽqX%д‡б1|Зч|B}ёў;‡tOЬ9( DŠФєљЫіU˜?[ƒa„эћ‰­гР\сгаЌGТw@ƒ:bpёў4Nѕк躘QmŸуїhm:К>thэ<;Њ§Е-л^ŸЉh~X \>=ЌэњсAmпзmу>6ЌэўЁЁmзЎеЖyІКн<4 mйК=`сјгœTxXыkЏЛЖУЧ3ДMп:И КtоЖсЩƒкэїНМE™чI} ѓ чНѕЌvжeЇMШыOЦaj "бЛuЩ0Œ`ŽНюы LНA™\џUQ‡ŠIіЎЦ'ЅЬ’јSkK‡щК@@*Ч4РмЎЧo`PпгЧœшj]fžвыWЭчН@ѕ‹›ЋрЗ:Ц(RAP$IвHљтƒЮБ€ёЎ&}•M)иv5)›„ ОZ83 ЮРn4 в>ЧDњњІqќEH{/Ж}ьћ„ќH{LOКdЋяЄљЪ3@шбx аЫ&Є>айI6q}ъ=`Є$ё&™ tНкЩЙАqцœІ ЂЅЙцGоcNв˜дчјУєB~іQиjЏMлїj›]0М­wдрЖў+VЛЊMkC‹qmм‹еhђ•ЯўС•Kаvћ№А6юуkЗŸдЖxЌлљНƒл.о6ИgЩЪCЏЄ–^n1&šсО}ьбvйНчЗ3Џ;ЉэuбmУ[ЖѕoYОmXнq†_T;н\4І]tуЙ=џвчŸжіЙxЧЖ~%Ы Ћ­Б‡œЛ@}і*эЄѓŽыAЬ„.Ѓwы R рWIёV „Љ х§ЈъдХ ГQЫyб1>ЕcN-уOŒoњj˜:j<ЕнР№QёItОЏ$m˜zZЎZіџ([HЅх5.f@ђЛM0ЛЁб8Щ”J, РFє˜Ё a2R/Z@З8Ј[@ЧЬё№'=И }L‡ЎэO§*] a@Плз §1x—љ…ѓ˜;ушK ъь;чЯŸЦ”>L$їAHоz ”"-г-ƒe=’мCђsЮr(sм1mŸУЧЕMЖпЈ­4d`[uЫкЊїяљШћзxћУ+cя‰Њ{zЉЖљ#ЋTыЊj$њ№ВmУgmћqxлуХСmЏ—жj›=S‰+,й†о9јжљлˆ{цkЃ\ДэђОелцO,зЖrh;рыЕuю\Мэzг†эФ;iЇнp\;јќНкЦgечЏиЖМККи>8М UFЗ=jчкMnЉвй'6n|ЯЖ§ƒЯnиыŒЛў•KWwнљЋЩХђmГл*хѕ”EкЇэй р–z‚žІPяeЄ\;`=М—MDŠюў­кХbыь№ѕ'Уј]†œЖЩЙ}Е‚ЈёTї‰ЉяЏф7^ля•=івљВ'э7a™фu#МРФ'б"}0GЈжтшДjw@€4І–ЧшњddLŒё“ачŸы•.ЄїŸ№MDј/vК ?˜Ÿc)[{Ѕ™g’zвЪ;›L"@ Л?E=Є;ѕ=[dХцВ@*?йr*^ыФћI5Z@Є 0НvbћьеЖЗeДе€гНrqдЪmћ–n›~xљЖmэYПё{—l>Пxлш}KЕпПtїйuкa_пВŽkЖѕŸY ˜•ЖWН^щжr>НRIўuкжяиVЙnО6цбeк6OUїкgVm›?ИTлцБел>нА6Џоv|vhyгbmЭЫh›ž[§ъOижЛК}нJmЧ€БOŒjЛWšьіїЏбіьuЭ9ІѕЉНлюЏ_M/WЈвихкvwV9lѕЫГѕѕšЧ/T=ю—k[МN;їМszЯІO2QЂQёG™cgбф_Ъ‡ѕ/егрњтI3a|69‰Ї)MZПzЯљпВхЄTјз–_эе юы l;-ž!k2ВRyЉXlЭd R=™‘h˜@Х ЙЉдды€РЄ4Ё:Œ™“ &5˜ Fœ~Є>ЦЯŽ?]HGиЈўРH\8ЩэУ/9§йў;[xcќиѕb№$z<ѕœy=бnл4БŒ*ŸЭ23oq†!њд]аРМN=чѕŸЦ4ЄіHм~ХЖжб§ЋšЌŽЛзFgЎк6}|ХЖ§'Ћ#Э—зkћ|Бьў/ЌгЦ}nD;ќ[Д“ўyїvќЗwnЧ}{Ыv№ззkу>SіњлŠљпU5џВW;єs›Д ^Д­{яќэШкѕцфЏяTЬПlл§ЙкŸўэЋДоНfэ|Гf[ћšŠљчiнВlyквЕ=uСйUЅvю‚U;ПLлхосmЇ{†UлЌвXЋџ­CлQнЉ ;uўЖEэfЛэkД5O\А 9jО^3MЋО}ы[Voшзv=aЫ}6iўa^’ЇB5%xў\ №ƒёщКТmBmыер|[ёubќWЫ‚oьїK]њŠj1ѕтбтм‘ш!!(@’Kn3нЎ92ОІа!ЄЖHМивy;яюФё–ўm1К•‚€€4O\bGŸGняЫќ$~Hў„§HўdџaўnwпlфAђS§Stфџє<Шžs4`цЉлwєьi7-Ь—}ѕ#'аJ‡šЄЌвКтб7‡i7Fе9BЬ\ЃжїšwŒвFœАR[їЦкњ7 hcЎZНm{џЖљЛWh[}t…ЖуЇViуўnЭЖoЉљ;—Єпя‹хљЁња?Г`НПz@ЉфŸ­mЉ?ДrлчЅ‘эФиЖ|`ўЖцmѓЕcОМuЛ№‡ЖЃ>_ЛвгЏuѕТmЬнк.O m#юXЈД‹Ко‡дДl{T_|*§:ЕсХ№‹цkkœН@[НTњЕЊшeуЫWiЧ~|l;ъcЛЕ\Зњ‘Š&|nїvР{6щФnїЌ–Z#л^UдЫЖ{WГЭ#—эЭƒмfzzЭZТцOE›пЎЊЦ+‹{vЋБХdŸ§§ZHќ7–qЇЧЏ—'wоjџєЇЩЇm€‡™Њщ–ю*Є•ЄJ10Є'ЩъмnЫАЄнvУƒЉH’Lm`ђ‰ чdа8ж0Оx?ѓЂ iђ™DŸt№MRO$~œz˜;Nвсзџ){N€]Ÿp€єЌF‰Єž?PЪŽ“XЬљаmЏЯЏйv}БТ{Ÿд•ДпъНЅ~?Wlя]Бэѓ‰Qmм‡‡Зƒ_мЈ­wзBmЯї­нv}oЫук†ї.бЖЏЈР˜;—j›мК|;њГ[ДГџe\;фcеЭјњ%л&7жНм?Ќ 9{ЙЖa™cЎдvМ{vЮ7Ži;пПqoМгПЙліЮекцзhUНу?Еs;№ЙЭк67ЏQ~„…лкЇ-оѓo Йl>очёЇ ;~Л6„ЙЄш_ž>Ц_wМФjыЊњГJ Q€еЄ€š $wZTzъ?ШMЄ[jжуАъy{K‚YРєЯ“ўš>tдaЮ5ЁЗ€@7D˜t] Б3КЬUп9@УH˜/Лaъ„™ЩчŸ˜д'э›Днфч3gтФЫЖиLTAš Ж|Тvi4I ’иw<ћЄ8ІЦdЯФM{bшмн§Їл‘7-ЙШN‡mгЖИsHлє™ ЯНP}ъ>?ЊŽЋЖ=>Лvлћ ЅіiнRџзmc?Зv;ц[лЖSО[О‡‡UЪяRm­Gl›ПoЙЖі#ѓЗѕ[Єэ№ЁСэЄoэвЎўљБэмнЇјЕэлОеЖzgџЖзFД7ЮS[ЌY]m—)0И6М(тбUЋaхіеНvLћШАЖљѕеѓдyкZ'.Z=эFДхїН ;kёrє-ж6ОdHлљž1mш)KЕЕЋ‡нfз­кЖМЅ4ˆч6jG|xЛЖпг›Д­Џді)Їс7U—ЂЊАг€Y‰~Jјc…џ~Ё…К`<уKИСј’p0~rтйјГJŒŸЯKЊœЬўOїз‰™]рР’YH| ‘6‰I5ояж„; ˆЄљƒ\ё,2ЉG“p­юNТйI xѓЛ ‰Ÿ]}Iz`ТЩзі>ѓ'ЖŸЎ=Ÿ”R"хЃкg?yЯ”„врЅ#rкLЇ'НcвQйющб8 ќѕЏнЫ—r0ФеЕщЪžЩВУьжРм;?‰8{]Й}лњ‰ г}`@ЉёkЗ#ўaыЖЫKk”šП~лѓѓ#кŸЉP^1џŸкŽћЮэиomз.џя#кМ н№ЋjѕўЃ}к^Ÿ^Лmѕ|I§,поњгcл…?>Аэіў5к&Um@…§ЖzЄ;щЫВЛuСЖћ3CлЕ?­ˆЅ ьѓєmєMsЖmюYЂmu{mNyѕRе,Гœ~ЗЌлпhі6їˆйлН`лБTўОМaлѕЅ5лоŸ_Зэ^ЬПЩћ—mл|tЅЖй—mНgё6ъЉк†Я-оі§мшvњwЧЕГўmЯvтЗwjW§ќЈvдзЪ9љž­я<Гlэk7ИМќ+—Ъ_лVf‹Ж]йћG~zѓЖнУ+ЕНоS;чiпѕјTzї“њїфžЫyuož—іB ƒSэІ‘ОџЋЬЯR г­Ѓђ›O’нsК6m)-ЪЭЇэ ˜wзГSеš?бП xVlл|h`лт§ЫЕ­?Дb1zэ0ћСк^ŸЋ]h>4 mQАУ ekзч›Нw™ЖоSЕ'нлчok=XЊхўoџОэјonнјlэјф"ЕчмЖmл'ЋWн-Ео[чiлМsЅкћnЫJкИѕ™-лўЈэЏп1 ќСъ„ѓD…їžвЖОmхЖђ!§кj‡дF7i‡?5ЖќP™Œз oЫ™­fЬгжЉ>zƒŽЏЄŸc–nkМtЕЮ^­ђЁэлno_ЏЖБšЋUђlzвBm ­ЕЊKЎ-Г—3з=Eг;зВKеŸХјЏ„Щ'ѕRћ&§'RHœŠyф€˜ˆ Ÿ€51t<џЩж\яФек:-жж{lбЖщЛjgšз*р 6іѓkЌбЖ§p5 ќє:5жЏдоўmЫwѕЏ4пС)XЙэќБ5лŽ•уПжлVlƒn_ §ѕъeїэ]л6яа§ьzmа5ѓДU.™Л­rщмmшU ДA—Эеі}~эvљПдц7g[ѕŒўэДП?ЊэќјШЖTХьчоlіъ‚;ДќвmлVicЮ[КmXyч|щ€vљOjЃŽ]Ж мЕіа;uБЖЪ! ЗбчWПЛjЈЙсх+їЄ§кTЊpѕд;т…кiјіЪ&МДљ–б>ыГу%?ЯО”кщSњ:=™шЭ|­€sbџ#0DGвlИс†Š<Вї[ди˜} @BXœ_щ-ШЖV<цi}…)ј ВЭ6Эу‹‘ї­ ШŽСœg6‘`”Ј@lцFzЩо FvкI3ШєЯЖZœw^ѓgєн/c^~їэ˜эЫВR7ĘЯVL-<ѕX2!˜r.Ь= СУјaўhiŽыя5ЌZL-нV?i‘6тКЅкzї–­ќ№Bmу*у]яЙE‹љзlЧўу6mПЯoаЖЊАрUшГOіlЫžwm,ёR9№*эwнЗЯлVПmRћWЊїЕM+сёe*ю_}юаЊM+VОhЎЖвљхЌЋŒР+J[Ј.}mшe‹ЗѕnдFпБJtцЕ?§еЉЖ|wЎеv`нvР;6kЧОЇ6ђшEкаƒh;WПќБчvЬќmdIќuЯЎf#wmо6ЛjXлћй­jЯМђƒЩ ˜|џdџЩBФЬ4‡ОyBŽIL_ЁAоџ8/Гї^М§м|pђQпyіГћ/g -JHЏ Д,aПѓoRкзўkЖuvЎмњb~LпeќaУ‡–#mЩjеЕDлш†Ѕ*„6gX›C,7vЮЖЮUЫДЭп9 э№ќЊmяђьўбСmлїжўє\­эњбamыїЎвжylщ6№жy{jџm:Їьў=ляYЖm№p9чюŸЇ$џЅ!,нЖ{Ж6ЉИjЎЖrЉќ›нП\§lи§ф˜ЖѕCЫЗхNЊ-йЧЮбŽўТ6епОZˆ]ZБ§кЊj№I З%ї|KУЪmфyЫЕ .XЙ:Ћ›cDэP[^Ќ]l* XaЏ~ѕК_ХїчiУXЁW0Деmе5ЗzчэњфК•mXћп§г~эєoдЖЊўњ‹T—нѕЏЈjСГ—јM)џLоўWЖЧн›‘9_ы{ЎЂ‰ecџGэœT*pWш†Їв|‘g}b&яЋЄЮ>t&щ™ѕ=M&ВiGZGtїЂуQяњ т+ˆc‘o€mЯжя:=/Їѓ‡Гѓ#аœpN+ФБ7jѓсmдE+ДѕюЉTк–kkеTCЖ^Й­ЙЮmЭVЊ˜xm q^йуЭпЖМiP[p‹9ZџБЅТзnА+зfуоUЩ>ЛпћCkДБ•аГї хЌБСЃKЖ=^йЖxп 6В^~rљЖIіЌ|у‚mщKчikп5oЉўЫЖнЊолgЊ‰хЭsЗAЗЬн\RšХm‹Е}?МAлунU)јЎъ №ЬэЈЏЏ[ДD[ПіІ?ИЖЅкяй-лрiKVœѓлЊшЈд§]žгNўіAmјхщПЕЂwЌожНА Šю^Г­vф|m™кл~ы‹*тpaэАsС2ЕЕіFэ‚=ЊэњиeN,еv}xLлсОuЪЈЖdЗ ЎэЎn‹n6‡N;|гОЭеkЭHoвыПЅьџнbџw€Tšœ а7 aРЎ Џƒ&GОЛыАлдŸA4€l§ќf€Јџй~{э­‡Дс——m]I5›><АТpХЗ/бFдоѓcо6 эќLѕюЛЋpL9рЊpfЙqѓД•XАѕпЇrіЋ ѕЮO Ћ˜§*mћgW( кyqL;шгЕC>ЗY;ъЋ[—pхЖљГ+•§ПQлМ`ѕ ё-љмmыћ7/XпЋo?ОqлцщЪђћРЈЖWхїoѕіmУлЏƒ ЭнЗL;ёЋ;ЖЭяZМrЏTпmћЛ‡Д-ЪАtm‰5ч†ГЕЗŒœ­-Ећ[коиКўЏ‡Еmяоі~~“*оЌ ;iбЖ^ѕ^щНk”яb‹K†ЕсЧUбЋЖ#>Йc;цЅ}лњ—•зџ€йктЕеж ‡ЬбRƒЃпвжYОGY8”ЦЖт$Я ИР=+E\ЩoЙѓŸ>2~ЙSdўѓx€иkfv€бМ˜zу|0#Ь@Ћй0…Y ЛŠк˜?CїэАWaј…&^ђ mЋ7rїxcвйд‹СШгMXѕz'ђж…СЇŽФ›sЉЈП3@acІ>‹5yžОщш~„р3бШeПуb>žЋЁ{я@ћ˜С–оІѓHлХџ›юЯG1cњцHС}”<§ЫŽВнїb Ѓ“4рL ?5Ы~аЅ/ЭBф€I:ЁчYЩИпОЩ“NЄ bo8ЪHž|{К,Ч5/ВЙчлPК-ˆѓ№˜ЋXnAЫЉtL?“ƒД+Ga‡Ёj5л™ ~6ŽбŠІ‘ЙФэl ^њR–Нм™чџ‡!‚žEкМPЩzIWЯ Ÿгјѕ4€bЈ ъХеИ€Lнљ“’€Ÿф(af<%зЦ‘]LЯќчS—W-оЬЬ3уБ]=UЎж@ јпщў3л_мТ$з A(;…YOOРЖ_/Т П_…о'*Pv8;МбФp`Лю&ваfм]€–3vик'ЈGZƒ’ЈprМ@%4бo]=€б`&п~ZР”ЧЪW ”Tќ_QYтв"фЯMDћХRt\*Х‚WІaфS‘Н}їWbчoGАу7dЩ]$5іˆ ‹~аЪšќ4 lЄТжс‡iчй­w.SNЅ`югЕXёкdц QIПuќЊc68И&FыCœњCуo§;j\ЬУ„cЁЈTŽІ;rа~оZЦї=—шЦŸЯЃФ+<­{Щ˜~g:VНв‚ы3„ƒo_ƒCя,g3Ю0tЬВ/ѕТќ'Ш<м€Њы}0ћ!& щA4Ё(Ч…\ОF,КяхЬВ ›ЦЃчЁJдмOЙЏц*‘ЙЦ‚ЩЇ3‘К†ќ-Єщ^//" YЬФ2іwŒЁrP-AЂˆяхƒP†b N:–ћbКX*ьdтp5У…є ц"Ё/сVОљ…љАw%ЃќP,’ЗxЁрІPtЛ– П^єЫіућKЙвпf U€m€L4ЮA ]ўјA_Tг№Ыѓg/…cW*j™ш+йЫ^џ4R‡ QД1О uxў‹­вњВOИu5їЈ†jjzЎФ?ДgнЎџ8с–Иъ™ќ#У€џр|к2рh@мy…ЬјpuУЩ0ЭqЩz)ј, рX}_y Єwv3OtMЭэ‰Hпъ…єэžLоХЁїQЮхc|^}cJА|vО=;HіiF+ћч+їФЃŠгtЊїХгР"IЕ ЦмG`_DY-rю­FЕјђ–њqќVкЮцc:“y-'I+&лЏ“ЁC_З‘ESnЃšаqОЮŽ@ъіЁƒьПсЇыHСѕE4™|Эџ˜t+хМјї~цВ–y9йyЭgJ8 &%=™НOІс`?O ŽFахwьNEїљz†i <ЮЧR$Њ!ЂQА.!жŸћиР‘<ђ§гшQdБп?пйрЄD`l‹џЏИ'ЅєЛ№ђщЏЩКЎYЗёƒёы%дLЁЙфхЛ5XТшЬ›P`<@vŸЧp L' с|R#a~еРю`ІœН№•7+™Юј>=K(Чны˜И[ўк ЖЦЮТЎЗ†Ає5вfiЄ­w8…32—ј"kieЕТБрлшЛЇ ыHзѓP КюЫCэnіvД№tяИ‡ЊС‡уйEШ~–ьв+пВЭ‘˜|‚ЎќёŠuF0Bе}SщфЂс–иWљвнчДfѕK6q(3њЉ пГkЏћб‰Мо4Яfжž”р]Б4zoxВ1(aˆ†л8Ј„'П}U8*v$ЃzY†[™'8’K@HBЩ–Xz‰Hь ј=їф.ьnрЪсRЕЪДџКЙџуrЇдW­КъTŽRzЁРПOFм$%‘e<‰_\ Dц+И|\#аWЄ  ГРA@ Щ0Lœ5б5Ÿ|šѓј)EKzц5mчБ2v&`!5ї1Љ№jŒˆaЖЅ1qЧœ8hє™ЄПf ƒнw]фѓO9›ˆ­oіcˆЭ=9›<œМњ…Я‘t”LО3™ћХ ОGѓ‘иOїM*8[Џ~S4ВZЌ˜М…LПыsб}‚=і?_†КЕhкB…žл(§§ыƒ8њЇc8ќЮў~й„хдй|А эVdQОkЦЉ2ф/ЅPчЪіщГkqO2yboЃ2ЯB?Дœ.!Н7‡љъњ/ @Шt{ уyОџ ’~Ђ{ќ`)ДР6%ЕџXіѓ—aшщV’Б|Џ2цSFl5eЬЖs–сЕ g:Нс›dб@Я.эK.€ЛѓяKР+‘(Ф С‰Ж••ѕЖТхЬ€P5ЋИЮ ’З2C= H|гxп‡™Š#ЦžКї”М’0”Tр Ў€j5Оš@сб€Ќйrр Ж† ˆйћЌеО,‘EаU/ф,=Юз Ёрf;–P‚ЛўHц"9љHe|_Д“uжжѓV…2іРьЊАэГАюХVд/ЃптDіхOXœˆѕЯєbю}­и№Нљ8ђЇуr 7џсfŸ›Ш0Gєъ8Ъ;ѕњvэЕŸ%щў ’s,(ЇaаНŸ@RN97ФмkBЩ3ЈpВљRG|TШс€Њ§Д?8ГžlFЦR›ГЃ/‚ Ž}iш|Ј‚D dЉEХ.ОЮ<DГuXо@l'BY=ˆšщ…рrOuћiЬ—Цx‹јc<Зћ?Ž@ dŠМ'˜KЩ–fџещщщџ‹ AЮpР€€N+mZm`šSgB€/ JюЙъšрыЎ%@ЙџNw›1uћНдЩнБ“BЛ"˜Eї@.uгяЪсIOљ†GR˜\Г€б1ВжFЂўцtЏAѓ 9XџУNЌ{ЙЭ[’QмF­џŽtэ+УОŸ-Т­>„ЃяюТ–gЃs)ъ—$Ђf+‡ бМ+к}yhЛНƒ9™йяїЧМ'&aЮ#еHЃ„WбЪ–йЬГ‡уЦœˆ&њ2‡rpа^N оЧD8Š6'’-hgыњ7цВ"р‹ЖћFQ+0‘р13НРœ@УбLt=R…6ХїzАˆЭI,UкЉ œMРшЉAпЙ šъ+е уhјцЅL;АHКСЋЄzk3й SSSџб$ŠUГъє2’`F{’иО’`фРфEрO †hdДG{f зеШ€šјп9яo*{'KБќ3qэТрЗQGьF nІRh#~6уч5$Q(ГšТї”P3?•J:ўt›)гѕШd Qv+ПЧЩœЋf&Ню&Г wќŸЏУБ?РŽŸ.Рœь8$еж1›ЩТNvьѕyЃ~}$њяЌBяzЮ–cюcL r"oі Чp=3‰яUŒТхTљ]ф‡А ”­Cппq6CŽ<Ж№–гр; ­ј Gw-O lЗ ЁЬ+$@тx=Б\1}ќoўK~хи™ўЬW„Гq‰„%*9Vищ9ф‘˜yM!№]ЏЇтO+—ЈПк—ЖЫ‡•лg а U(  ЋyšАк}gNNЮЛЦPлЊX$jЉбU’А– ˆ+H7Я€‘џ4!€<€БzЦђЦъ-v5VœКwЙџŽа^AЙы}ри ŽПЊf{lы‰|єн[ŽсGсGУ)'™eМфAvыэIфш-:Љ›пР,~ЅЕв{tАМЗ'‹юЉAнмHћУ ьџйц"ШtиYG5Ёш9–•4ю…ЄЗ0i˜>Э•+S1э`Іь#ihE4Чw’?`GхЕ‘”эІt‡{fQМГэюЮщЃжпVNАqS&ГљlкaѓNѓщJ$є ˜!@WTЛbКIэmѕц XфЏЇjб2гI6нТ ХЗS‹€+]f,Ки‚мчџ<Ы=м{Гuqq%pЙхПЦй№]НЃ `@@с€h—Ик™\AoрћT4  “LГ$~)!Lз*€ЋАsчNчРз€+hЌ€‘s5~WР_ FOњЌЂ yPN А€ЭvЊтВGаƒкўœ–[Œ-o р6*ѕz{-–=пŽdNд­ к—!†ёrЅЖ‹ЏЕqv^$В— ЊС!vžЮГ9 `^ –оGА‡'"!Bх 2QЗтR3sкю\†н,Лu)ФTсШ№bшЧЌ55љТ‘2УyС([JА!‹Yќкэд왆4&чІ‘дvеŠщђOЁVЫiВiаEыRш№їзsа‡,gј2/6цk­ЄўrЮРБbЪQlgЮхЩO2бжDц/Ђœ‰Пxz б­ўopЯЭчRќ/P6—ІќЊbхnќљ’A@7Xс€м­ИЫ7_.˜И— Т­ЌМЊЄ•Ћ' ž P#ИL3ˆ@JаhЏOУИЊ-@#:–€QОZ=Хџ Ѕ*(œХXЇьаЃMиѕ?Vу&ŽтОўЭ˜їP КЯV24( …з#7aЫ/‡БђхN |“Т‡xRSw?gyтf Љ•nџZЖдЖЃ›9і§љЈН†НјGђ1|ЮЁћщтуd`іпwёgї‰2,фkЮ>OСћи:м‹'‹ћГЃoY<ъvА]ј@кŽW ЇšTё™†Ъu1vКˆ“|XКc~)ЏЁ|ўьБhПаР>†;’Xо ЂЄ™‡jњa‚/oЇџHЃ…0&њ”3h ЈrošтX-ˆlї}з+ЬК™{­Ÿk2—ш|ДТЁedєQ'оD,чћe. ІGрA‰0RŒяЖГŠ‘I†2уsШиЪА‡дрЊGwјР?зу~юЏaЎ\Ъў‹ўЋ=ш>§џŒпМ…ё­uу…ОjПT-Vё˜єи} –ggg?Loр-ШP>@ž€щš† ЈL7–,Иi’БаЯбmРІ(P2бЕ`М@р5žs\РYўЋ,ƒ}8’§№,ƒёTLaЙ­† МС‡+аЯЎКК-l Х!NzoЦ%Рч{ЃŒЉиЭ:МŸы‰BЦж“nЩGйЊXчфнЉ[гYћ'So(ŽсЌћ'Ѓэжєœ)Ує[ђ0|Бž]… нЈлŸФX=mRVМ2‚вkЈРГЙy§qШŒA§vNjg~€Їј„B ˆžфКёe›Љ=И4оы3‘=k •ыЈћ‚­О$“Бг‡иЧя_Ђ$&Л fЃœ"йlѓ•8h\—7чDpŽA85|Т=Е€Ћ“ЋžKeiyЁюЖпџDуwWo@” дb€@B}aC111{9Њъi–џ(OР„’+PЉЫP(`І}pбщoДUј2@зќЅ@E9ь“шЯ‰#c/‰šјщєXŽ;”ŽЩ{RPЭ’Xуu1ˆЄ‘цŒ щ`КIЎi;S‚Jqђ–2Vgn ’™јТU1ˆяфd VŠsЂьмуяь]ьея  Шц4t(Цд]™шЛЃ Ÿš‚і…|L,‡wVQ?А™нœ%Иžƒ;n,BFG(bАх№ЕhР!™јаШэL“Й—иC№щД!Ѕ'’]}Й, F!jЊъ0Uє:Rщ9ЄЯ#?cПcЈX\sC:;ўxњї9џO—?vІЫ‚l0jїћНWАГёg—\џ.гљчnћ§+€+ˆ+ м€b0…T›J+G ОЖtкдЙ5— У[шт>Э С›ђF#PЭAЂkPЈ$ТЧъ дщ.#—БЫ#PX`€ŒћЏФЁ)Ъ0б€ЧЫј2р#`G|e#Ї‰ю№&л8 Ј€ЩГxЮт„н,’ГќL"MЮМNмЭƒc{b™ LЄ:nйц&р"‘N1|%юЈ'ЫFœ&гgpЄW+н№VJ†/ŽBЫўLй™ŽЦЭЩhиH^џ,Юп›‚™Ї˜yw5Њ7ІЃv[6І-AЩ‚x$5ј’BЬЁЃ‘M'™ЧсƒœХTћYЯФe2#Сў™ЧеЮЅЌП[ёч*0јЛ…ђЄФ"9&• UŸ•>›Т% ЩЫ)Lа—лЧ5ФЎУ LоKжры;яJWRеї:вiяs.\Њ Ј&ФЙ€УЪС’\жˆэУјNŸїЂ&y§4ЁУыџ%ЗQІ‹ RБ:нї0єрщŸн„\m\%пЇž*@§a(ЁЖп0;љГŒБzšЪК~У€|јГ옣#ЋeLтЌ!`ЛOQ <•я RГXЖ3УП&1$ХL@Ь oD№ѓ$ј;?ЄЦѓ—мMjљч"—Ћт фшЫ‰CLЎTЎ,.Е‹nlA‚Ъ>"~ШKрILLмШгђv–/‘Tє4впв џЏЋQۘ]OncШњЉЪƒŒZ?ЕtЂ+І7qНNv /•Ё‹ДdŒ]DWƒŸ?ОГЂсj№JpКžєЦЭwџ­“оНќ)УкŒћІёПЯЦЋп&%%§˜КŒЯ?тххuЏg€х\XЙѕеєРџ“3ќЖ}$јН‰dм•P6Л’’YеlиЉe,_ЦeфѓWђдf_Нюy\ЗзћЁ,/јЅXзѓ>*/#аUТЖ:8з:7jŠчЯЂZ№uag‹pк & I jиE­О[8їљцrШШьхcGП—оњ_cъ§žЖ9ЌOUxМTi}%АдђЃ€bЫџє/ВМпќ^t ‡ƒ№ёЩ,BУЉі€нўфЙaЌФ!| ЩJ<œRc§Ё—Э"ЊЏОsПіƒ~TђSxщVќљ €ыЅК‚’7 ”Хе—*я@€ Мyy\Ъ”]БЙф)ˆ .їPйa'0p-тЩy#ЫhЧщb“'яw /3ЄјGžаПбЂ1 ƒж’8Љ– [K4eИJ”:ехЮ›“]ќужЛМС‹ѕ8кНWlЏњОт{3ьƒџп‘0ѕ^ы/ђѓѓ_"њ™”””Y-Йaа~ЋеКŒŸEюЏж"Ў%\:еПЭ3ауІ  ЏsО – ‰-ОП,Й6цУŠmЪXО’Їr ѕђГц…џSpхЭИvяџMнџž1і‹ИVПK~qVн+•kEЄшІr)i+abКё7GLДќ)Н?i]ўˆЌbmŸЦ[Н#•‚Кэщ}!F7yџ1ЌкѓЕРLS^‘–ѕ\Ћ}’-›ќ2ЌыrЌлƒЫaо?Ћї{ЮVч§œ_žхй rgУ&њ=RыѓL`‘чж0ЫR^ƒ _пЏЙFП %™нJПМ _‡ F‡ rяєEAЈЏAjЏrUfTAž‚6p9—М ђ”-nЛМ‘Ty@H=fˆk.—ЈЄ‹”o Oa?Oй\7в ярi|A‹ђ з7x*ƒдмgЃПDwнЙhШ/ёw/б˜_"gџ%>ўy&ыОA*ДsёфО@Э„ |э{bccoт:РЕŸЉmz_.еГ•ивѕшКФlгujуыКu§SИtњЉчB?'дyљё#ќ)PX”ъyKиПšцљF\Їял C‘Г4тw‘ЕОїzЧYіљeYŽІY7јЦXG5ыѕT™б=д=UHЦ%№еНГ.л7кsВ­ЦуСИ6ПЗЃšМосПйрѕ—ИџwЂ›}ўЩЦј<АауqŸDЫ.ЋЗѓњuЭŠгеŸ_СКP%ЁНЮ3Ьвтh№ŽЗЬѓєqzr№дcѕSFЎЯЅвžЎЋ‘Ky!Н†N}%ќ*ъёЛу~оŒЏу?&‰шъ!(`@A›UB'‚€A6•Ыƒ<%‹ђ”l@(ƒЌЭ%—WЅM'#гF”+,oBЦЇ„Є Б“Kо…bPЇТ-‰YцwњЛЇЧыyz~Чхзвыjуkг› Џї—Бшzt]к№КN]o —Ў_ЙШ2Tв2žўЎЧ7^~MНпke чсmЏіКƒЇќQu~‡­~V5Ьш:єѕx=ЏK'Њ<-y]КЗЪбИzbКЗл<жпkƒэжu!eї…8<žчЯЧƒьžGR­›­!V—>“РW@Ќы“з&o"ѕђвїЂЯЁЯЃїжїRrљЇ<;§Ю|^}wzЌž#Уз5ъћ–‡Ј“пmќМ KџЦХfУŽUtŠiуJ Д™Е)ЕБdLкd2(mJm>mBmЦ.‡оKљЙц.}і’Ызу$Ьi< =_KŸA€ЂзвїЁї7KџЏчш3ыяњlzЌžcуш ˜єЛŸ7С§япюР•€Aa„mt…кPЦее&е2`ЁЭЇMЈЭЈMi6Њ MKЦ)бJuYцwњЛyЌ6ЗyБ6ЗоSя-ЃжѕшКt}КNmx]ЗЎ__Њ“O`€Oгce$Ў*“ЁЛz:ŒЎOŸOяkN}зUїSџєгЛєўК]Ѓ SŸK *р1рЅџзчжпѕyt]К>]ЗYzбп…>ЏыgжћtДЬgзѕpв5™kМ|Љюю;№я€Г‘]O6cDкXЎ›Sд†6Њ6Ё6ЄY@ЬІ§ИŸЦ€Эѓє:z=Wƒ6F=кА]OaГйЭg1Ÿвѕ3щГŒ6PŽ 툑РЧœІ2z]—1NНпЧ•y_н;ѓ>њ,њмžФЬkЛžдzmзeМ НЏљєпf™яI?Эѓ\ПKї^wпqПЎЬ—й|ЎвD\7эЧmр+mц/z’Ц@eŒ6.§ |d˜cІWКW/ЫЎ Н$ŸtR~эбїњJя=ю_Жћнwрыv\РЈ н,7œGёYю‡+Œ>н]_џГМІћБю;рОуpЦђdFџnоЦ§ю;рОю;рО3wрџPћP:”ЎIENDЎB`‚(€      #   !%),28=@BGJJIE@@;60*'# ,;Op" wE4" ,b}d@) %.>O\r)))†///—222Ѓ555АAAAМFFFУKKKЬLLLбJJJбLLLлLLLпKKKпHHHпAAAз<<<а:::б111Ш,,,С$$$ЗЊž|fYUZm‹ EЦg'єs.њ:Р:В2; |GмJ§h+џ Sђ/ МkUVu)  " œ†… „h>) !-CZ%%%{888šHHHГgggЯxxxш€€€ї………§………џƒƒƒџƒƒƒџƒƒƒџ€€€џ~~~џ|||џyyyџwwwџsssџpppџlllџhhhџcccџ___џ\\\џWWWџRRRџOOOџJJJџDDDџ???џ999џ111ћ***ђрб5л \&јn1џh-џ%…?џ(Aџv0џ b!џ@Т _e LЧ_(џFџ]-џr8џ^-џb,џ Jт3кFх Kј Iџ[џFџZџ_џC§5УT.&=Y „888Џ\\\зwwwіŠŠŠџ–––џžžžџŸŸŸџŸŸŸџžžžџœœœџ˜˜˜џ“““џ‘‘‘џџџŠŠŠџ‡‡‡џƒƒƒџ€€€џ}}}џyyyџuuuџqqqџkkkџgggџcccџ^^^џZZZџVVVџQQQџLLLџHHHџCCCџ<<<џ312џ)"&џH(џY#џ@џHџ ^)џg+џ ‚;џs0џ ]"џe(џNё Y&ќf0џx>џY+џW+џ^/џs;џ&€?џX+џQ џd(џi*џs.џb$џ_#џx/џEџJџ Yџ- НI)!7aš<<<ЮWWWђlllџ~~~џ‰‰‰џ’’’џšššџЁЁЁџЄЄЄџЇЇЇџЇЇЇџІІІџЂЂЂџџ˜˜˜џ”””џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџFFFџ=<=џ,5.џJ(џy9џq8џ ]-џR!џ€;џs0џ a%џn,џVџHџR'џd5џ'…Iџ.‘Nџs;џ5‘Iџ(y:џ!q6џL$џ @џS џk)џNџj+џn*џz0џf&џ\!џf'џPџOџ—> !?|'''Ф@@@іTTTџbbbџnnnџ{{{џ‡‡‡џ‘‘‘џ™™™џЁЁЁџЅЅЅџЈЈЈџЉЉЉџЉЉЉџІІІџЃЃЃџџ™™™џ”””џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџFFFџ>8<џ#N0џ|3џ)’Lџ&Iџ `*џw5џ%ŽCџ ˆ>џ j'џ.‰?џm6џj;џg:џ+Oџ.”Oџ=Џ]џu=џ;ŒIџ0{=џd/џa/џO$џ>џp/џr1џ <џ)Œ;џs,џ ]џh'џ#‹;џ Xџl(џ Xђ p52 w"""Ю888џFFFџQQQџ\\\џhhhџuuuџ€€€џŠŠŠџ’’’џšššџЂЂЂџІІІџЉЉЉџЊЊЊџЊЊЊџЇЇЇџЄЄЄџŸŸŸџ™™™џ•••џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџ?;>џ*C1џ~6џ?А]џVЩsџ@ЉZџ|8џ,“Gџ „=џt1џ Iџc9џ.UџuDџ1šZџ-“Uџ0™Uџ)Lџ6šOџo4џc.џr8џ]*џm1џ$‹Aџ9џu1џ0“@џe$џUџe$џ4џp+џ%‰:џd"џ8ЯP*  EБ---§888џBBBџJJJџUUUџ___џiiiџuuuџџŠŠŠџ“““џšššџЂЂЂџЇЇЇџЊЊЊџЋЋЋџЊЊЊџЈЈЈџЄЄЄџŸŸŸџ™™™џ•••џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџA@Aџ756џ#j5џ.œKџ2žQџ&DџWџf%џ†=џ„8џ {<џl?џ!{JџKГmџRГmџ!tFџ|Hџq=џv=џ-‘Lџ|=џ%ŽEџ j-џp1џ/˜Hџ!ƒ:џ,@џk(џNџOџ Zџ Sџu/џ+™Dџm)џ c!џ' œ6JЮ///џ666џ===џDDDџLLLџTTTџ^^^џiiiџtttџџŠŠŠџ“““џšššџЂЂЂџЇЇЇџЊЊЊџЋЋЋџЊЊЊџЈЈЈџЅЅЅџ   џ™™™џ•••џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџBBBџ<6:џ$P0џ!“>џŒ?џ u.џ!šFџ,ЈPџ!’@џk!џ#ˆ;џ/˜Oџ8Ї_џT3џ<‘WџfЭzџVЎhџZВhџBЇ[џ4›Pџh-џ.šLџh,џ(ˆAџy5џu2џ|3џj%џ&‚5џ"4џMџh&џ"ƒ8џ4џWџ d!џ IеB 1Ф///џ333џ888џ===џDDDџKKKџTTTџ^^^џhhhџtttџџˆˆˆџ’’’џšššџЂЂЂџІІІџЉЉЉџЋЋЋџЋЋЋџЈЈЈџЅЅЅџ   џšššџ•••џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ=;=џ.91џy8џžEџ&ЃLџ6Й\џ1ВUџ1ЋRџƒ3џ#‹;џx3џ„Dџk6џ!}Aџ=œUџD™TџPЄYџcЭrџeиxџ0Eџk-џ&ƒ;џ.šIџ}6џy2џy/џt*џq(џx.џ0џ0‘@џ/–EџSџl*џ~2џ5Р? r...џ222џ444џ888џ===џDDDџKKKџSSSџ]]]џhhhџtttџ~~~џ‰‰‰џ’’’џšššџЁЁЁџІІІџЉЉЉџЋЋЋџЋЋЋџЈЈЈџІІІџ   џšššџ•••џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ>>>џ5.3џ K,џ—=џ—>џ<О_џLаlџ/­Oџ=џ~3џ h&џ,•Kџ3ЃTџv3џ q/џBџ0ЎWџ)Lџ"‘BџŒ=џ‡9џ-ЁLџ}3џ Aџ‡<џw.џ:ЂIџs)џbџ cџf$џt/џ}4џ5џx.џ& ЌEЃ333џ333џ444џ888џ===џDDDџKKKџSSSџ]]]џhhhџsssџ~~~џˆˆˆџ’’’џšššџЁЁЁџІІІџЊЊЊџЋЋЋџЋЋЋџЉЉЉџІІІџЁЁЁџšššџ–––џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ>>>џ504џ%?+џˆ/џ’4џ9ЖVџ+ЈQџ-ЄIџBЙ\џ#<џ‡7џ€:џ †Aџ$…@џ~;џ1ЃSџ%šJџŽAџ‰=џ {2џ ~3џ&ЅLџ s+џ!@џ1ЉRџ*“Aџ$‰8џ Wџy+џŠ7џm'џ!‚8џk)џn*џy0џ2й- Ÿ555џ333џ444џ888џ===џDDDџKKKџSSSџ]]]џgggџsssџ}}}џ‡‡‡џ‘‘‘џ™™™џЁЁЁџІІІџЉЉЉџЋЋЋџЋЋЋџЉЉЉџІІІџЂЂЂџ›››џ–––џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ>>>џ434џY+џš8џ=МVџ5ДRџHЩjџ7ГUџ1ЇLџ!•<џ+ЉMџ'œOџ&šLџHХmџ`х…џ6ЉWџ}5џ ‚:џ!œNџˆ>џŒBџ’Fџ$•Cџ3­Tџ%˜Dџz+џŽ:џq#џ!”=џ0џq)џƒ7џg&џ€5џg&џHџb#є >ž% m555џ333џ444џ888џ===џDDDџKKKџSSSџ]]]џgggџrrrџ|||џ‡‡‡џ‘‘‘џ™™™џЁЁЁџІІІџЉЉЉџЋЋЋџЋЋЋџЉЉЉџІІІџЂЂЂџ›››џ–––џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ???џ535џ'X2џ3ЖOџ8ЙSџ'ЅCџPдqџ.АQџ?ИZџ„3џ"˜Aџ@Сeџ2ЙZџ“9џ™=џ'­Nџ"ЇKџЂJџžIџ>УhџDЫnџ5З]џ&FџIЪiџKЬjџ‰5џv(џ‡4џŽ:џ. Hџ!ˆ9џt.џ[џn*џg)џ!q3џ)Š<џ~.џ1 9222њ333џ444џ888џ===џDDDџKKKџSSSџ\\\џgggџrrrџ|||џ†††џ‘‘‘џ™™™џ   џІІІџЊЊЊџЋЋЋџЋЋЋџЊЊЊџЇЇЇџЂЂЂџœœœџ———џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ@@@џ958џ(>.џ—7џKЭdџMаiџ”6џ$ЈIџ=ЗZџz/џ•;џ)ЈNџ8Н`џ)ЌQџ˜>џ0џЁ>џ.ВQџ–9џŠ-џ“6џ,ЏOџ7ЖTџCЗYџtхџ r&џn"џ u*џv,џ1ЂKџ…7џz2џƒ9џ6џ'u7џ,‡?џ6ЂLџ#…6џ ^њ" `---п444џ444џ888џ===џDDDџKKKџSSSџ\\\џfffџqqqџ|||џ†††џџ˜˜˜џ   џІІІџЊЊЊџЋЋЋџЋЋЋџЊЊЊџЇЇЇџЃЃЃџœœœџ———џ“““џџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ@@@џ<8;џ->0џ ƒ6џ4ДOџ"ЂAџ Œ0џ"ЃGџ9ЕYџcџ0џœ=џ6ЗZџ!ЅHџЂBџ<У[џЂ;џ-џ’2џ.џ1џ;ЎLџ0АOџDН]џ9ЅMџ]џh џ3џ&™Fџ,ŸMџy4џk)џ#“Dџj+џ&g/џJџt-џ;­Uџ(“?џ ]Щ+++Џ444џ444џ888џ===џCCCџKKKџSSSџ\\\џfffџpppџ|||џ†††џџ˜˜˜џ   џІІІџЉЉЉџЋЋЋџЋЋЋџЊЊЊџЇЇЇџЂЂЂџœœœџ•••џџ‹‹‹џ‡‡‡џ‚‚‚џ~~~џ{{{џvvvџqqqџmmmџiiiџdddџaaaџ^^^џYYYџVVVџRRRџPPPџLLLџIIIџFFFџBBBџ@@@џ=<=џ656џ*G1џ•5џЂ<џ™?џ)ЊJџ–?џ _џ bџ9џ,ЗTџ1КWџ7СYџ=Ъ^џЈ<џ•-џ ‡"џ-џ$Ё>џ0­KџBџ ЃGџ?Чfџ2џ‚7џOџk(џ<АUџ%>џs.џu1џm/џ*@џ6˜Hџdџ`џ v+џ d#К***444џ444џ888џ===џCCCџKKKџSSSџ\\\џfffџpppџ{{{џ†††џџ———џŸŸŸџЄЄЄџЈЈЈџЉЉЉџЈЈЈџЇЇЇџЇЇЇџІІІџЃЃЃџЁЁЁџІІІџЋЋЋџЏЏЏџЕЕЕџВВВџБББџЗЗЗџЖЖЖџГГГџЏЏЏџЉЉЉџ™™™џ”””џџ‚‚‚џwwwџiiiџZZZџQQQџIIIџBBBџ:::џ777џ534џ082џ!j3џ&Y2џ)8-џ"D+џy-џu+џOџŽ:џ)ЛSџ-ОUџ+МOџЋ:џ!Ў=џ8СVџ œ3џЎFџЊCџ Œ(џ&ЉJџ*­Oџ3џ*ŸKџ(‘Eџ c џu-џ6™Fџr,џn+џ c$џe,џ'ƒ>џ=БVџ>АUџ2›Hџ2џ N“,,,P222џ555џ888џ===џCCCџKKKџRRRџ\\\џfffџpppџ{{{џ………џџ”””џžžžџЈЈЈџАААџЛЛЛџХХХџбббџиииџпппџцццџыыыџцццџсссџнннџиииџгггџвввџЯЯЯџЪЪЪџЩЩЩџЦЦЦџФФФџЦЦЦџУУУџПППџПППџНННџЛЛЛџЛЛЛџБББџЂЂЂџ’’’џ€€€џlllџXXXџDDDџ969џ2+1џ.+.џ0(.џ,@1џr4џ r$џœ5џЕ?џ9Э\џ3ХVџ АBџ%АFџ3Ъ_џЉ=џЎDџБIџ,ВPџ „'џ Š/џ9ЌTџ>ЋNџz(џd џ ‚<џ1ŒKџ W'џo5џ a&џ$x7џ4’Fџ,—Cџ,Gџ)•Cџ|1љ( K...!000ї444џ888џ===џDDDџKKKџSSSџ\\\џdddџnnnџzzzџ‰‰‰џ›››џЎЎЎџОООџЩЩЩџЮЮЮџШШШџПППџГГГџЃЃЃџ’’’џƒƒƒџwwwџqqqџlllџiiiџcccџƒƒƒџ‚‚‚џ]]]џ___џ^^^џ\\\џ\\\џ[[[џ\\\џ[[[џ\\\џ]]]џ```џbbbџhhhџrrrџ{{{џ†††џџ†††џŒŒŒџ…„…џqqqџ\\\џGGGџ958џ635џ"ˆ:џ НHџ+ТNџ'СKџ"ЙFџ#ЖDџГDџБ?џ-ЕIџ<Ц\џ7Щ`џ#ЋHџzџ#ЃEџ8К^џ"‰6џCЕ[џVџ>ЈXџ7žUџ7•Sџ1ŠKџY!џt1џ"‚:џ{2џ+‘Cџ,™Hџj*в" ***///е444џ888џ>>>џDDDџKKKџPPPџYYYџlllџ‡‡‡џŸŸŸџЏЏЏџБББџЊЊЊџ›››џ†††џvvvџnnnџjjjџiiiџqqqџџ’’’џ———џ˜˜˜џ›››џ   џЅЅЅџ‘‘‘џЯЯЯџІІІџЌЌЌџЇЇЇџЄЄЄџ›››џ‹‹‹џŽŽŽџ’’’џ‹‹‹џџ{{{џlllџbbbџXXXџSSSџIIIџKKKџ~~~џTTTџSSSџcccџpppџsssџqqqџg^eџ<KџЗ>џ)ТNџ)ТLџ$НGџЙAџЕ?џ#ИFџ>Ь`џHйnџ3Ц]џ$ГNџ˜6џ3КYџ7Й[џ-ВXџЄOџ•Eџr1џ<ˆKџ(s?џZ(џt.џw4џDВ\џ<ЄSџl,џ,œJџ]+кY& ...Ѕ444џ888џ===џBBBџHHHџaaaџƒƒƒџœœœџ   џ•••џ„„„џzzzџjjjџkkkџџ”””џЁЁЁџПППџвввџзззџоооџцццџцццџуууџрррџлллџгггџ‘‘‘џпппџХХХџРРРџКККџЗЗЗџВВВџЊЊЊџЈЈЈџЈЈЈџžžžџЈЈЈџЇЇЇџ˜˜˜џџ’’’џ‹‹‹џŒŒŒџiiiџЃЃЃџwwwџLLLџDDDџ;;;џ;;;џBBBџTOSџOfTџ!Ї?џ/ЬRџ1ЬUџ1ЪVџ.ШRџ>в_џCбcџ>Ю_џЖEџ<Ы_џLзoџ)ЕRџ$ЋJџ%ЊLџ5ПaџЂKџ*ЌVџ(žOџo3џUџ h'џ)†=џ|5џ#@џAЖ`џ5ЁRџ+žIџ5fDџ\W[э///ІV' ---v444џ888џ:::џLLLџsssџ’’’џ”””џ‚‚‚џnnnџfffџhhhџЎЎЎџВВВџКККџЪЪЪџдддџкккџпппџуууџцццџчччџцццџцццџуууџсссџоооџжжжџ‘‘‘џсссџЪЪЪџЦЦЦџСССџМММџЖЖЖџЏЏЏџВВВџБББџ­­­џЈЈЈџЄЄЄџ   џ•••џ–––џ›››џœœœџhhhџџџ‰‰‰џxxxџlllџ\\\џKKKџ878џ/-.џ"f0џŸ:џ)ЅFџ%РJџ&ЩOџ$ТKџГ;џИ@џ$ХQџ"ЖGџ,НTџ0ЛSџ=Хaџ!ЅGџ Aџ Aџ3ЕXџ1­Tџ„5џ€1џ €8џJВ`џEБ[џ>В[џ-™Mџ?Ў\џ{2џ=hJџxqvџvvvџ```№111Њ Y( ...H222џ555џWWWџ„„„џџ~~~џiiiџeeeџwwwџšššџtttџŸŸŸџдддџЪЪЪџаааџжжжџнннџфффџщщщџыыыџьььџэээџьььџщщщџцццџфффџмммџ‘‘‘џфффџвввџЭЭЭџЧЧЧџТТТџМММџИИИџДДДџ­­­џЌЌЌџІІІџЇЇЇџЅЅЅџЅЅЅџ˜˜˜џџžžžџjjjџ“““џЌЌЌџџƒƒƒџˆˆˆџˆˆˆџƒƒƒџwwwџ\Z\џ7H;џM(џW*џЈ=џ+ИMџ%ТKџ7ЮXџ;г`џ!УNџАAџ1МRџž5џ.ЗRџ ЇGџ+АMџ$ЌFџ9џq/џ},џ)—Fџ*™JџJТdџ:ЎTџ>џ…<џ‰:џs7џdphџ|z|џ{{{џyyyџ{{{џ‡‡‡ѓ===Ў \* //////ђTTTџ………џ………џnnnџaaaџoooџ‰‰‰џ›››џЎЎЎџyyyџ™™™џжжжџЮЮЮџжжжџмммџуууџщщщџэээџяяяџ№№№џ№№№џяяяџэээџыыыџшшшџсссџ‘‘‘џцццџжжжџбббџЪЪЪџЧЧЧџПППџЛЛЛџЖЖЖџЗЗЗџДДДџЌЌЌџЌЌЌџЊЊЊџЏЏЏџЋЋЋџ   џЄЄЄџuuuџŒŒŒџЂЂЂџœœœџ˜˜˜џ–––џ‘‘‘џ„„„џ‚‚‚џzzzџnnnџUZVџ6B8џ+џ"$"џ*d8џ'›Aџ$‰<џ0УXџ/ЧWџ АCџЈ>џІ@џ­Cџ š@џ,g:џbygџksџHXџ$›>џ#”>џRš_џ^–hџ/ˆFџ3џ2{Fџr{tџ„ƒџџ}}}џ{{{џ}}}џœœœџˆˆˆџpppѕCCCДa+ :::Эzzzџџiiiџbbbџyyyџ‡‡‡џ“““џ   џДДДџ|||џšššџиииџвввџкккџсссџцццџыыыџ№№№џђђђџђђђџёёёџ№№№џюююџьььџщщщџтттџ‘‘‘џцццџзззџвввџЬЬЬџШШШџУУУџТТТџНННџОООџОООџАААџЉЉЉџЌЌЌџЎЎЎџЏЏЏџЅЅЅџ   џwwwџ•••џЃЃЃџ›››џ›››џ˜˜˜џ•••џŠŠŠџ‡‡‡џ………џџwvwџ{y{џPMPџџџ:L>џ;WBџ9ЙYџ@дdџ#ЛNџБEџБBџ,ŸGџTiYџVLSџD?Cџa]`џ†џM]џrŽzџ•‘”џ‰‡џ‚„ƒџuƒyџ‚‚‚џ‰†ˆџ†††џ„„„џƒƒƒџ‚‚‚џ€€€џ™™™џџ………џ‹‹‹џ}}}јNNNЙe- "! IIIœџoooџaaaџvvvџ€€€џ‰‰‰џ–––џЃЃЃџЖЖЖџ}}}џšššџкккџгггџнннџуууџшшшџэээџёёёџђђђџђђђџёёёџ№№№џюююџьььџъъъџфффџ‘‘‘џцццџиииџдддџЮЮЮџЬЬЬџЪЪЪџФФФџСССџЧЧЧџУУУџЛЛЛџГГГџЏЏЏџЋЋЋџ­­­џЈЈЈџЌЌЌџ‚‚‚џ“““џЖЖЖџЁЁЁџžžžџšššџžžžџ–––џ™™™џџ‹‹‹џŠŠŠџ‘‘‘џ‰‰‰џVVVџџџ6mBџ$ИFџ ПGџАAџ™:џ1“Iџgvjџ‚{џ}}}џQQQџzzzџTSTџb^aџˆ‹џЉЈЉџџ‹џ‡„†џ‡†‡џ‡‡‡џ‡‡‡џ‡‡‡џ………џ„„„џџœœœџŽŽŽџˆˆˆџŒŒŒџŒŒŒџџ‚‚‚њUUUПk/ +> Vl T3# LLL~xxxџeeeџiiiџuuuџ~~~џŠŠŠџ———џЄЄЄџЗЗЗџ|||џšššџкккџеееџоооџхххџъъъџюююџёёёџђђђџђђђџђђђџ№№№џяяяџьььџъъъџтттџ‘‘‘џхххџйййџиииџбббџЩЩЩџЫЫЫџШШШџЧЧЧџЦЦЦџУУУџКККџИИИџЗЗЗџВВВџАААџЎЎЎџЎЎЎџ‡‡‡џ’’’џДДДџЂЂЂџ–––џœœœџšššџšššџœœœџœœœџŸŸŸџ’’’џ“““џ———џƒƒƒџ&&&џџ7?9џN‚Yџ0žHџ*–@џY|`џ€џ€|џ‰‰‰џ~~~џTTTџЄЄЄџƒƒƒџuttџ]]]џ^^^џ………џЄЄЄџ   џџ„„„џ‡‡‡џˆˆˆџˆˆˆџ‰‰‰џ‚‚‚џџ———џ•••џџџŒŒŒџŽŽŽџ”””џ‹‹‹ў^^^Х$$$q3+Ab+˜ Z#мq.јSх8­' ‰ L./5>5*! WWWRlllџcccџiiiџuuuџ€€€џ‹‹‹џ˜˜˜џЅЅЅџЗЗЗџ|||џšššџлллџеееџрррџцццџыыыџяяяџђђђџѓѓѓџђђђџюююџуууџиииџЮЮЮџЩЩЩџСССџ   џЦЦЦџЪЪЪџбббџаааџЯЯЯџЩЩЩџЦЦЦџХХХџТТТџФФФџСССџЙЙЙџЛЛЛџЖЖЖџГГГџБББџ­­­џwwwџ“““џЖЖЖџЁЁЁџŸŸŸџžžžџ›››џЁЁЁџ˜˜˜џžžžџџ•••џŸŸŸџ‹‹‹џџ...џџVTUџzrxџsrsџy~yџ‚‚џ‹џŠŠŠџ€€€џ€€€џSSSџžžžџ}}}џ‚‚‚џ„„„џqqqџ]]]џaaaџ€€€џЂЂЂџІІІџ”””џˆˆˆџ‡‡‡џ‹‹‹џƒƒƒџ   џœœœџџŽŽŽџ“““џ‘‘‘џџŽŽŽџџ———џџdddЫ###€Ub8Ѓf)чi/ћm4џ!‚?џz8џi(џcџ Tт of1–MЩ8­ v q L!fffYYYДaaaџiiiџwwwџ„„„џџ›››џЇЇЇџИИИџ}}}џšššџнннџиииџсссџцццџыыыџяяяџђђђџђђђџхххџЩЩЩџЏЏЏџœœœџџ‰ŠŠџ‚‚џghhџ‰‰‰џБББџеееџйййџнннџнннџЮЮЮџдддџиииџбббџЫЫЫџЦЦЦџОООџЗЗЗџБББџАААџ­­­џwwwџ™™™џВВВџ›››џЁЁЁџЂЂЂџ™™™џ”””џ™™™џЅЅЅџ˜˜˜џ“““џ–––џ‘‘‘џƒƒƒџ***џџPPPџџŸžŸџ˜–—џˆ‡ˆџ†††џ‰‰‰џ†††џƒƒƒџTTTџџ~~~џ‚‚‚џ€€€џ~~~џ|||џvvvџfffџeeeџ‚‚‚џЅЅЅџ­­­џšššџ‹‹‹џџ   џ’’’џ‹‹‹џџ”””џџ”””џ”””џ•••џ———џ™™™џ‘‘‘џ€€€џ[UYм@г k,џ ‡Bџ/Nџ8ЄTџ €?џ;­Zџ&‘Cџ&?џˆ7џ Mн<з e-џ „=џj,џ a$іh$љ Vт+ )FFFRRRЗgggўwwwџˆˆˆџ–––џЂЂЂџЌЌЌџНННџџšššџрррџкккџтттџщщщџ№№№џіііџљљљџэээџЪЬЫџЖЙЙџЏГВџ­ГВџБЗЖџЖМЛџИННџІЌЌџFJKџ„„„џКККџЛЛЛџЗЗЗџКККџКККџЛЛЛџЛЛЛџЛЛЛџСССџЧЧЧџЭЭЭџбббџЯЯЯџЩЩЩџЦЦЦџ€€€џ–––џИИИџžžžџœœœџ›››џžžžџ”””џœœœџšššџšššџžžžџ“““џџџ222џ555џ+++џ000џfffџџЏЏЏџ›››џ†††џˆˆˆџ~~~џSSSџŸŸŸџџџ€€€џ~~~џџ€€€џ‚‚‚џ~~~џrrrџlllџƒƒƒџЅЅЅџБББџŽŽŽџžžžџџ‹‹‹џ–––џџ‘‘‘џ“““џџ“““џ———џ———џ‹‹‹џ€€џRp[џp7џ#Jџ&†Dџt9џ)„AџAЎ\џWаsџQЩkџ:ЊPџ,™Dџ ƒ5џp4џ$Bџ{<џ)Fџt0џ g#џ4џ%Œ9џ @Ÿ DDDeeeюyyyџ‹‹‹џœœœџЉЉЉџГГГџФФФџ‚‚‚џџяяяџцццџъъъџтттџлллџжжжџвввџЩЫЫџИПНџ ІІџŠ‘џw|}џmrsџglnџotuџЕЛЛџ069џ__`џŽŽŽџ–––џ‡‡‡џ|||џ|||џrrrџjjjџhhhџdddџcccџ```џbbbџmmmџ}}}џ”””џmmmџ{{{џМММџЙЙЙџЕЕЕџЉЉЉџЁЁЁџ———џ–––џ›››џœœœџšššџ‘‘‘џџ}}}џ999џGGGџbbbџ^^^џ%%%џ<<<џYYYџ“““џЏЏЏџЄЄЄџƒƒƒџSSSџЂЂЂџƒƒƒџ†††џ………џƒƒƒџƒƒƒџ„„„џ„„„џŽŽŽџ‹‹‹џ‚‚‚џpppџ~~~џ‡‡‡џŒŒŒџЄЄЄџЏЏЏџ™™™џ‘‘‘џџŽŽŽџџ’’’џ‘‘‘џ”””џ”””џŒŒŒџ~|~џ3xFџ@џ%œTџ6•Qџ*ŠGџNСhџ Š?џTЯqџ]Ъnџf"џ]џ4џ ‚8џ)‚?џ/”KџMЦlџAЗ^џFН]џ6ЅMџ&Œ:џcџ( y fff mmmф|||џџ   џЎЎЎџПППџиииџџƒƒƒџЛЛЛџŸŸŸџџ‘‘‘џŸŸŸџЊЊЊџЛККџШЫЪџ˜žŸџGLMџ)+-џџџџ%%&џ­ГВџ5;>џ‚‚ƒџЦЦЦџкккџгггџЬЬЬџЪЪЪџ”””џŸŸŸџСССџЈЈЈџ™™™џ’’’џŠŠŠџzzzџhhhџTTTџHHHџFFFџFFFџRRRџrrrџŠŠŠџœœœџЎЎЎџЈЈЈџœœœџ“““џ“““џџŒŒŒџzzzџ666џDDDџ```џoooџ===џ•••џ\\\џ@@@џRRRџ‹‹‹џЄЄЄџ]]]џЂЂЂџ‡‡‡џˆˆˆџ‹‹‹џŠŠŠџˆˆˆџџŒŒŒџ‘‘‘џ“““џŠŠŠџ|||џЌЌЌџ€€€џ€€€џ‰‰‰џЇЇЇџЛЛЛџГГГџžžžџ’’’џ’’’џ–––џ”””џ”””џ———џ‘‘‘џˆ†џMtYџ~6џ€=џƒ>џ0’Gџ\џz2џ:ЏZџCК`џ;ЎTџ$…8џZџbџ2‘Iџ=ЋYџXвtџXЬmџy.џ„5џ?АUџ/”Aџ dё@fff sssмџ‘‘‘џЏЏЏџУУУџ­­­џ‡‡‡џ[[[џVVVџeeeџƒƒƒџЈЈЈџПППџ‘‘‘џщщщџѓѓѓџнрпџ—џ*,-џџ џџџ)))џЎГГџ5;>џƒƒ„џЫЫЫџоооџмммџжжжџиииџ™™™џЈЈЈџиииџЧЧЧџТТТџХХХџЧЧЧџКККџЖЖЖџЋЋЋџЂЂЂџ’’’џџgggџMMMџ<<<џ:::џJJJџoooџџЅЅЅџ›››џŽŽŽџ‹‹‹џwwwџ333џDDDџaaaџnnnџ<<<џЁЁЁџŒŒŒџ‡‡‡џlllџNNNџMMMџ]]]џЉЉЉџГГГџџџŽŽŽџ•••џ———џ‘‘‘џ’’’џ–––џџџДДДџ“““џ———џџˆˆˆџŽŽŽџЇЇЇџНННџКККџЈЈЈџ›››џ˜˜˜џ˜˜˜џšššџ”””џˆŒџb}iџn'џs.џ‚8џ„4џz,џ*˜Bџ8ЇTџ5ЋSџ3ЎQџEО^џ3Gџ|1џz4џt.џKЦjџYШlџ(†8џ\џi"џ ‹;џ1џ2`mmmxxxвŒŒŒџЋЋЋџœœœџXXXџ;;;џQQQџƒƒƒџЋЋЋџШШШџйййџхххџтттџ‘‘‘џ№№№џѕѕѕџнрпџ–џ/23џ џџџџ333џЎДГџ5;>џ††‡џЮЮЭџнннџиииџдддџзззџœœœџЇЇЇџзззџПППџНННџНННџЗЗЗџВВВџЕЕЕџАААџЎЎЎџ­­­џЉЉЉџЇЇЇџŸŸŸџ•••џ}}}џ___џ;;;џ---џIIIџ………џŸŸŸџ”””џuuuџ000џCCCџbbbџoooџ<<<џ   џŠŠŠџŠŠŠџ‘‘‘џŒŒŒџ}}}џbbbџRRRџuuuџЉЉЉџРРРџГГГџ›››џ•••џšššџžžžџџ™™™џƒƒƒџЛЛЛџ———џџ›››џžžžџšššџ’’’џ“““џЅЅЅџНННџРРРџЎЎЎџ   џœœœџ™™™џ“’џ‚џ|.џ.ЄJџ7ЈNџ<М[џ;ЖVџ0ЌKџ<ДWџCК[џ9ЎPџ%–@џ+šEџo'џ \џ+‘?џ3ЄQџ6АXџ?Р_џFЗ[џz.џw.џw-§# :UUU………Х˜˜˜џ[[[џ555џ]]]џџРРРџбббџдддџжжжџиииџнннџмммџ‘‘‘џюююџєѓєџмппџ–œџ367џџџ$$$џ'''џ<==џЏДДџ5;>џ‡‡ˆџЮЮЮџпппџкккџзззџйййџџЇЇЇџдддџУУУџПППџЙЙЙџЗЗЗџДДДџЖЖЖџДДДџЏЏЏџЊЊЊџЇЇЇџЃЃЃџЁЁЁџžžžџžžžџ   џ```џVVVџXXXџ)))џFFFџ‘‘‘џ}}}џ---џDDDџcccџpppџ<<<џ   џŠŠŠџџџŽŽŽџ“““џ–––џџoooџZZZџpppџЅЅЅџЧЧЧџЛЛЛџЇЇЇџšššџ›››џ™™™џ†††џПППџ›››џЂЂЂџœœœџŸŸŸџЅЅЅџЃЃЃџЁЁЁџšššџ–––џЅЅЅџМММџУУУџДДДџЃЃЃџ—–—џž žџRˆ`џ|-џ |%џ/ЈJџFУ_џfцxџ!˜:џ/ІIџ!<џ€3џ)‘Aџ‡7џ8џ$@џBЗ]џ?ЕXџ1ІJџ0ЄJџ>ВWџ …8џp+п ………УBBBџPPPџ———џРРРџФФФџХХХџЫЫЫџЫЫЫџаааџзззџкккџлллџ‘‘‘џяяяџєѓєџмпоџ•š›џ8:<џџ&&&џ---џ222џEFFџЏЕЕџ4;>џˆˆ‰џаааџпппџкккџеееџдддџџІІІџдддџУУУџПППџМММџЛЛЛџЗЗЗџЏЏЏџБББџЏЏЏџЊЊЊџЋЋЋџІІІџ   џœœœџ˜˜˜џ›››џ^^^џtttџЉЉЉџџFFFџ...џgggџ333џFFFџfffџrrrџ<<<џ   џџџ‘‘‘џџ’’’џ“““џ–––џŸŸŸџ˜˜˜џƒƒƒџiiiџqqqџŸŸŸџЪЪЪџЪЪЪџЋЋЋџ›››џ†††џПППџ–––џЇЇЇџЏЏЏџ   џЉЉЉџЅЅЅџЄЄЄџЇЇЇџЈЈЈџ   џšššџЂЂЂџЗЗЗџХХХџЈЈЈџЉЈЉџ‘ŒџCTџ6ЛVџ,ЌJџŽ3џDС]џ-ЄHџ6ЌPџRЫkџy1џy0џ6ЁMџPЧeџSбgџ,ЅFџ=ЕVџ4ЇMџ)—Cџ0žKџ!=џ H…fffYYYЭfffџЁЁЁџДДДџКККџНННџХХХџШШШџЫЫЫџЭЭЭџЮЮЮџйййџлллџ‘‘‘џяяяџєѓєџлпнџ‘˜™џ=@Aџ%%%џ111џ888џ;;;џNOOџАЖЕџ4;>џ‡‡ˆџЬЬЬџлллџкккџЬЬЬџеееџžžžџЃЃЃџЪЪЪџХХХџСССџЖЖЖџИИИџЗЗЗџВВВџАААџЇЇЇџ­­­џІІІџЅЅЅџŸŸŸџ›››џ™™™џžžžџ^^^џqqqџЄЄЄџ———џ•••џbbbџ;;;џ@@@џTTTџiiiџtttџ;;;џЃЃЃџ‘‘‘џŽŽŽџ•••џ”””џ———џ–––џ———џ›››џЁЁЁџЃЃЃџІІІџzzzџlllџwwwџ˜˜˜џЪЪЪџЧЧЧџ‰‰‰џШШШџžžžџЇЇЇџ­­­џЉЉЉџЇЇЇџЏЏЏџЌЌЌџЋЋЋџЊЊЊџЊЊЊџЋЋЋџžžžџџЄЄЄџŸŸŸџЏЎЏџАЌАџQ|[џ—8џNЦ`џDМYџ?ДTџ2ЄJџ‰9џ5ЊSџ;­Xџ(‘Cџ‹8џ"š=џZкpџ%œ?џ2ЈMџ0ŸKџf&џ%Š@џ%‘Aў( RwwwЏ———џЂЂЂџЏЏЏџЗЗЗџПППџФФФџЪЪЪџЧЧЧџЪЪЪџаааџйййџмммџ‘‘‘џюююџѕєєџмппџ‘——џBDEџ000џ;;;џAAAџEEEџVVVџАЖЖџ4;>џˆ‰‰џЯЯЯџлллџгггџЪЪЪџкккџЁЁЁџЂЂЂџЮЮЮџЛЛЛџНННџКККџЕЕЕџИИИџЎЎЎџЖЖЖџЕЕЕџЎЎЎџЌЌЌџЅЅЅџ   џžžžџџžžžџbbbџoooџЇЇЇџ•••џ“““џ™™™џ\\\џџHHHџ€€€џŽŽŽџ>>>џ™™™џ’’’џ‘‘‘џ’’’џ———џ˜˜˜џ™™™џžžžџЁЁЁџџ˜˜˜џџsssџІІІџБББџ~~~џuuuџџƒƒƒџзззџУУУџІІІџЅЅЅџЉЉЉџŸŸŸџЅЅЅџЈЈЈџЌЌЌџЌЌЌџЎЎЎџЎЎЎџџЛЛЛџАААџžžžџ›š›џЂ ЁџX‘eџ•1џž=џ)ЁFџDМ_џQЦhџGМ`џ. Nџ8ЅTџ$Aџ*”Bџ.ЃFџ;ДTџ.ЂIџ&–CџRЫmџ0™Lџ.˜Kџƒ8ј9ˆˆˆ•———џЈЈЈџБББџЙЙЙџТТТџУУУџХХХџФФФџШШШџгггџлллџнннџ‘‘‘џяяяџѕєєџптсџ•›œџGIJџ;::џEEEџKKKџLKKџeffџДКЙџ3:=џ••–џЬЬЬџзззџЪЪЪџЬЬЬџЮЮЮџ›››џЉЉЉџЭЭЭџЖЖЖџЛЛЛџНННџВВВџМММџВВВџЉЉЉџЇЇЇџІІІџЈЈЈџЈЈЈџЃЃЃџžžžџџЁЁЁџ___џnnnџЇЇЇџ™™™џ”””џ———џlllџџџ///џ```џџЊЊЊџЂЂЂџ“““џ”””џ™™™џšššџ›››џ———џœœœџŸŸŸџŸŸŸџІІІџtttџЄЄЄџЙЙЙџЂЂЂџЄЄЄџŽŽŽџ}}}џŒŒŒџИИИџеееџЮЮЮџВВВџŸŸŸџЈЈЈџЌЌЌџЈЈЈџ­­­џЌЌЌџЏЏЏџџНННџИИИџ­­­џЈЈЈџžœџ†ˆџT_џ,™Gџ/ЏQџCКaџqсƒџ3žOџ!‹@џ ‡>џ|3џ+™Bџ?ЖVџEЛ\џDДYџ3ЃNџ+œLџBГ_џ7ЄTџp/ђ&‰œœœџЉЉЉџДДДџОООџТТТџФФФџЧЧЧџЧЧЧџЬЬЬџдддџнннџоооџ‘‘‘џяяяџєєєџхццџЇ­­џORSџAAAџKKKџNMNџSRRџŸЃЂџ’˜™џ4;=џ­­­џаааџХХХџЗЗЗџФФФџЧЧЧџ™™™џІІІџШШШџКККџРРРџЖЖЖџБББџЛЛЛџЎЎЎџЉЉЉџЉЉЉџЄЄЄџЉЉЉџЇЇЇџЁЁЁџЁЁЁџŸŸŸџЂЂЂџ___џqqqџІІІџ•••џџ–––џmmmџџDDDџeeeџBBBџ:::џZZZџ“““џВВВџЋЋЋџŸŸŸџœœœџЂЂЂџЅЅЅџЄЄЄџЅЅЅџЅЅЅџЈЈЈџyyyџЄЄЄџГГГџЄЄЄџžžžџЄЄЄџ­­­џ›››џˆˆˆџŠŠŠџЏЏЏџвввџсссџЛЛЛџЁЁЁџЈЈЈџ­­­џБББџЏЏЏџžžžџПППџЗЗЗџ­­­џАААџАААџЌЊЌџŸ’œџ\…fџ"Ÿ>џ>­TџcЫpџ7ЈRџ…9џ„7џƒ2џ#ЂEџ)ЃKџ=Ж]џVЬoџ9ЉUџ)”Gџ)‘Gџ'‘EџTгŸŸŸ}ЉЉЉџЎЎЎџЕЕЕџРРРџХХХџХХХџЧЧЧџЩЩЩџЮЮЮџеееџоооџоооџ‘‘‘џ№№№џѕѕѕџёђђџЦЫЪџ‹џ\]]џaaaџz||џЇЊЉџЇЎ­џ6>@џ‚…†џаааџЯЯЯџбббџгггџПППџгггџАААџ­­­џзззџУУУџНННџТТТџТТТџОООџМММџ­­­џЋЋЋџЋЋЋџЅЅЅџЄЄЄџЁЁЁџ   џџЃЃЃџ^^^џpppџІІІџ”””џџ‘‘‘џkkkџџGGGџ„„„џџ‚‚‚џ```џ@@@џMMMџ‚‚‚џАААџЙЙЙџДДДџŸŸŸџЃЃЃџЊЊЊџЄЄЄџЊЊЊџ}}}џЄЄЄџДДДџџЌЌЌџДДДџЕЕЕџЋЋЋџЅЅЅџ———џ’’’џџІІІџЩЩЩџжжжџЦЦЦџБББџ­­­џЌЌЌџžžžџСССџЙЙЙџЎЎЎџВВВџАААџАААџЎ­Ўџžžžџ@ŽSџ“5џ~-џ|3џ‚2џ(Œ=џ5џ2ЋMџ7АUџ0ЅLџPОaџ(•Dџ„7џ‰;џ}1џ;ІІІsЊЊЊџБББџИИИџМММџХХХџЩЩЩџЬЬЬџЮЮЮџбббџкккџшшшџчччџЋЋЋџяяяџёёёџэьэџЧЩЩџЂЈЈџЇ­­џЃЊЊџ•œœџt{{џAGJџuwxџАААџЊЊЊџšššџ‹‹‹џВВВџ›››џЊЊЊџŒŒŒџƒƒƒџџІІІџЁЁЁџšššџ   џЋЋЋџДДДџМММџТТТџОООџОООџГГГџЌЌЌџЋЋЋџŸŸŸџЂЂЂџ___џrrrџЃЃЃџ“““џџ•••џgggџџIIIџџˆˆˆџџџ˜˜˜џxxxџQQQџIIIџrrrџЇЇЇџПППџЗЗЗџЈЈЈџЊЊЊџЉЉЉџ~~~џЂЂЂџЕЕЕџЈЈЈџЋЋЋџКККџЏЏЏџЋЋЋџГГГџЁЁЁџœœœџЏЏЏџœœœџ‡‡‡џЂЂЂџФФФџзззџЭЭЭџКККџœœœџУУУџТТТџБББџАААџЏЏЏџБББџБББџА­ЏџІЇІџuž~џq•yџVm\џ$v:џ y&џ‡1џ•;џ#œ>џ&—=џ'—>џ ;џ n%џz.џ„6ў0YЅЅЅjЋЋЋџБББџИИИџПППџУУУџЭЭЭџиииџмммџмммџвввџФФФџЕЕЕџžžžџЎЎЎџЗЗЗџРРРџЦЦЦџВГГџ“”џ†Š‹џ„‡ˆџ’””џИЙЙџЦЦЦџЙЙЙџКККџСССџЅЅЅџОООџМММџ›››џ“““џžžžџ–––џ‘‘‘џ———џŠŠŠџqqqџiiiџeeeџoooџlllџџŽŽŽџ   џЈЈЈџВВВџЏЏЏџЊЊЊџbbbџpppџЃЃЃџ‘‘‘џˆˆˆџџdddџџMMMџˆˆˆџŠŠŠџ”””џ•••џ›››џЁЁЁџџџhhhџOOOџeeeџџШШШџЦЦЦџЖЖЖџ{{{џЄЄЄџХХХџЏЏЏџЎЎЎџЏЏЏџИИИџЇЇЇџ›››џІІІџІІІџ•••џЏЏЏџœœœџЛЛЛџ”””џŸŸŸџНННџмммџДДДџТТТџНННџЈЈЈџ­­­џАААџБББџВВВџАААџГВГџЙГЗџЎЉ­џ|w{џ{‹џ.šIџ8МWџ’6џ%œ?џBН\џ&™AџKФdџ?ЊUџo*џ‚7ђ%ЂЂЂaЉЉЉџЏЏЏџЖЖЖџЩЩЩџЯЯЯџФФФџІІІџ†††џsssџvvvџƒƒƒџ›››џЖЖЖџШШШџйййџхххџыыыџ‘‘‘џнннџђђђџррпџхххџпппџжжжџеееџрррџЪЪЪџПППџФФФџВВВџЏЏЏџЖЖЖџЛЛЛџКККџФФФџФФФџЊЊЊџџКККџ˜˜˜џ———џ„„„џzzzџjjjџZZZџXXXџ]]]џlllџŠŠŠџ]]]џsssџЅЅЅџˆˆˆџƒƒƒџƒƒƒџ```џ џOOOџ‹‹‹џ”””џ›››џ”””џ•••џ›››џœœœџџІІІџ˜˜˜џzzzџ```џ___џџЫЫЫџ”””џџ­­­џЈЈЈџЉЉЉџЅЅЅџАААџœœœџГГГџЏЏЏџЋЋЋџЙЙЙџЕЕЕџŸŸŸџЯЯЯџЎЎЎџЊЊЊџ———џ   џџЛЛЛџнннџШШШџДДДџЎЎЎџАААџВВВџГГГџГГГџЖЖЖџЋЋЋџ~|~џ–’џ"8џ6БMџRЪdџ;БQџAЕWџ!<џ$•AџBЙ^џ/Lџ€9тЂЂЂXЈЈЈџЗЗЗџНННџЁЁЁџoooџJJJџQQQџtttџ˜˜˜џИИИџгггџцццџьььџёёёџѕѕѕџєєєџєєєџ‘‘‘џбббџсссџоооџпппџоооџЭЭЭџеееџдддџФФФџУУУџЭЭЭџВВВџЛЛЛџКККџВВВџЏЏЏџУУУџДДДџЛЛЛџŒŒŒџХХХџДДДџДДДџБББџЉЉЉџЋЋЋџšššџ„„„џnnnџTTTџ888џ///џJJJџџџ‹‹‹џџ___џ"""џOOOџŽŽŽџ’’’џ–––џšššџџ›››џšššџœœœџ™™™џ›››џ˜˜˜џ‡†‡џOOOџsssџaaaџoooџЄЄЄџбббџЬЬЬџЇЇЇџ   џœœœџЄЄЄџЛЛЛџ­­­џБББџЛЛЛџЋЋЋџ›››џгггџЏЏЏџИИИџЌЌЌџЋЋЋџІІІџџЋЋЋџЫЫЫџнннџбббџЛЛЛџАААџБББџБББџВВВџЋЋЋџƒƒџ™Їœџ ‰9џ7џ"@џ3ЊPџSЬkџHЛ_џ>Ж\џ-šKџ9ЈUџl*иЅЅЅMДДДџџgggџCCCџcccџ‘‘‘џЙЙЙџжжжџоооџоооџсссџхххџчччџюююџюююџёёёџђђђџ‘‘‘џкккџфффџгггџкккџдддџЬЬЬџиииџзззџЯЯЯџФФФџУУУџЭЭЭџМММџСССџЧЧЧџЈЈЈџАААџВВВџЅЅЅџˆˆˆџЕЕЕџЊЊЊџЌЌЌџЄЄЄџЄЄЄџžžžџЅЅЅџœœœџ˜˜˜џ‘‘‘џ€€€џgggџGGGџ444џNNNџ}}}џˆˆˆџbbbџ,,,џTTTџŽŽŽџ‡‡‡џ•••џœœœџ———џ———џ™™™џ———џ———џ•••џ„„„џxyyџLLLџџuuuџrrrџiiiџyyyџЉЉЉџбббџЪЪЪџРРРџДДДџЙЙЙџЁЁЁџЕЕЕџЗЗЗџЖЖЖџџЭЭЭџЊЊЊџАААџЊЊЊџКККџЖЖЖџЏЏЏџЉЉЉџџЂЂЂџНННџйййџзззџСССџБББџЕЕЕџ­­­џ………џЛКЛџ‚™ˆџEXџ+ЋLџ0ЊRџfл|џUРjџ%’Eџˆ>џ!Œ>џ d$ЕЉЉЉQ{{{џFFFџEEEџџЩЩЩџЬЬЬџЫЫЫџбббџзззџйййџоооџуууџцццџщщщџяяяџђђђџѓѓѓџ‘‘‘џгггџщщщџкккџжжжџкккџдддџмммџЯЯЯџаааџеееџЫЫЫџЬЬЬџУУУџГГГџЭЭЭџОООџЕЕЕџАААџЎЎЎџˆˆˆџОООџЎЎЎџ­­­џЂЂЂџЊЊЊџЅЅЅџ™™™џ———џ“““џŠŠŠџ‰‰‰џ†††џџnnnџIIIџ333џYYYџ@@@џ џBBBџžžžџЌЌЌџЂЂЂџœœœџ™™™џ™™™џ™™™џ———џ™™™џˆˆˆџ???џБЗЕџЏЕДџ ЄЃџŒџyyyџ|||џ{{{џpppџuuuџ›››џХХХџгггџНННџ   џЏЏЏџŸŸŸџАААџšššџЮЮЮџЎЎЎџЎЎЎџЋЋЋџЕЕЕџМММџЖЖЖџЗЗЗџКККџЏЏЏџžžžџ•••џЌЌЌџЭЭЭџжжжџЫЫЫџЖЖЖџ‡‡‡џУУУџЏЉ­џœ˜šџ:›Oџ%žAџ]ЦkџOМdџ)HџŠ7ќ{/у /\UUUџ˜˜˜џwwwџˆˆˆџУУУџОООџХХХџЯЯЯџеееџйййџпппџхххџфффџъъъџюююџёёёџєєєџ‘‘‘џкккџшшшџнннџуууџоооџЭЭЭџгггџжжжџШШШџЯЯЯџЬЬЬџЛЛЛџЩЩЩџБББџУУУџСССџИИИџНННџБББџzzzџЙЙЙџЏЏЏџЈЈЈџЇЇЇџЇЇЇџЉЉЉџЃЃЃџ•••џ“““џ‡‡‡џ~~~џ|||џwwwџwwwџvvvџ[[[џ;;;џFFFџ:::џ+++џ222џdddџŸŸŸџЖЖЖџАААџЁЁЁџœœœџžžžџЁЁЁџ€€€џџ­ГВџpuvџƒˆ‰џЅЋЋџГЙЗџЄЈЇџ„……џƒ‚‚џ•””џwxxџxxxџŒŒŒџГГГџаааџХХХџАААџЌЌЌџ›››џЬЬЬџВВВџДДДџЛЛЛџКККџЕЕЕџИИИџЗЗЗџЖЖЖџЗЗЗџВВВџ›››џЕЕЕџџšššџНННџЬЬЬџŠŠŠџЧЧЧџЏЏЏџЌЇЌџz™‚џ;џ‘4џ z+уHU6=& (………=§ЕЕЕџ~~~џŽŽŽџТТТџШШШџЧЧЧџЫЫЫџЮЮЮџйййџуууџфффџцццџъъъџ№№№џьььџёёёџ‘‘‘џоооџяяяџъъъџчччџтттџнннџеееџгггџЪЪЪџЩЩЩџЯЯЯџИИИџНННџГГГџВВВџОООџБББџЏЏЏџНННџ}}}џОООџ­­­џЅЅЅџЅЅЅџЃЃЃџІІІџ™™™џšššџџ†††џџzzzџwwwџsssџoooџlllџ```џNNNџ]]]џuuuџnnnџOOOџ888џOOOџ………џБББџКККџЏЏЏџЅЅЅџ………џџЉЎ­џ#$$џ!џ;>>џeijџ‘˜˜џБЖЖџЄЈЇџ‡†‡џ–••џЊЊЊџ•••џ}}}џ………џЊЊЊџЧЧЧџХХХџ›››џНННџЋЋЋџИИИџЌЌЌџДДДџДДДџДДДџКККџДДДџЗЗЗџВВВџЁЁЁџеееџВВВџЂЂЂџŽŽŽџ‡‡‡џ|||џТТТџЮЮЮџРРРџЎЉ­џ‘Ѓ–џB‰SД )ŒŒŒ(­­­їВВВџ|||џ’’’џТТТџУУУџЧЧЧџЮЮЮџЭЭЭџкккџнннџсссџтттџъъъџьььџьььџ№№№џ‘‘‘џкккџђђђџщщщџуууџуууџпппџрррџлллџбббџЮЮЮџФФФџХХХџФФФџВВВџЛЛЛџПППџЦЦЦџЃЃЃџЌЌЌџџМММџ   џЉЉЉџžžžџџЁЁЁџŸŸŸџ’’’џŠŠŠџ………џ€€€џzzzџyyyџsssџoooџhhhџ^^^џMMMџUUUџxxxџџЁЁЁџ™™™џtttџJJJџDDDџlllџЄЄЄџЧЧЧџžžžџџЊЏЎџ%%%џ џ џџ-01џaegџАЖЖџЈЋЋџšššџЎЎЎџЉЉЉџЂЂЂџ———џxxxџˆˆˆџ™™™џЊЊЊџЮЮЮџЧЧЧџПППџЇЇЇџ­­­џЏЏЏџИИИџЕЕЕџЖЖЖџЗЗЗџГГГџ   џвввџИИИџИИИџЙЙЙџЋЋЋџџ~~~џџИИИџЪЪЪџЯЫЯџІІІџŠŠŠ–––ђЇЇЇџ‚‚‚џ˜˜˜џСССџНННџЬЬЬџЧЧЧџЬЬЬџдддџнннџтттџхххџыыыџшшшџьььџёёёџ‘‘‘џлллџѓѓѓџщщщџуууџпппџвввџуууџвввџЯЯЯџЭЭЭџСССџПППџКККџЖЖЖџНННџПППџСССџЗЗЗџЎЎЎџ………џИИИџЂЂЂџІІІџЊЊЊџЇЇЇџЅЅЅџЈЈЈџџŠŠŠџ‡‡‡џ‚‚‚џ}}}џ|||џwwwџqqqџgggџ]]]џNNNџ]]]џzzzџ‘‘‘џžžžџЇЇЇџАААџЌЌЌџ’’’џiiiџLLLџ```џzzzџџЊАЏџ/0/џџџџџ,/0џ›ЁЂџ­АЏџ˜˜˜џГГГџЅЅЅџ   џЃЃЃџŠŠŠџЖЖЖџ‰‰‰џŠŠŠџ’’’џГГГџвввџвввџЛЛЛџГГГџВВВџВВВџЗЗЗџЛЛЛџДДДџЁЁЁџвввџЖЖЖџДДДџЎЎЎџВВВџЛЛЛџКККџ”””џrrrџџЈЈЈџІІІџ™™™–––эІІІџџ‰‰‰џПППџУУУџСССџЮЮЮџдддџЫЫЫџйййџлллџфффџэээџ№№№џђђђџѕѕѕџ‘‘‘џлллџэээџыыыџфффџрррџтттџчччџбббџФФФџФФФџЧЧЧџИИИџЯЯЯџЫЫЫџУУУџЧЧЧџЮЮЮџЬЬЬџШШШџ‚‚‚џЦЦЦџБББџЄЄЄџЄЄЄџЊЊЊџ›››џЅЅЅџ–––џŒŒŒџџ„„„џƒƒƒџџ{{{џtttџiiiџ[[[џLLLџ```џ}}}џ•••џ   џЈЈЈџЊЊЊџ­­­џАААџДДДџЈЈЈџ„„„џ888џџ­ВБџ899џ###џџџ џ023џЃЄџЅЈЇџ›››џГГГџВВВџЋЋЋџЊЊЊџџЧЧЧџЅЅЅџЕЕЕџЅЅЅџ”””џџЋЋЋџЬЬЬџмммџЪЪЪџЗЗЗџЗЗЗџЗЗЗџЖЖЖџЁЁЁџгггџЕЕЕџЛЛЛџЙЙЙџАААџГГГџЋЋЋџВВВџЗЗЗџšššџxxxџІІІџ‘‘‘šššщ   џ~~~џƒƒƒџНННџЩЩЩџОООџШШШџбббџиииџвввџнннџшшшџьььџыыыџчччџуууџдддџаааџбббџЬЬЬџЮЮЮџМММџЙЙЙџМММџЈЈЈџ›››џЄЄЄџ–––џџŽŽŽџџџ‹‹‹џ˜˜˜џ˜˜˜џЃЃЃџpppџžžžџГГГџГГГџЗЗЗџВВВџЎЎЎџЅЅЅџ–––џ‹‹‹џ‹‹‹џ………џ………џ‚‚‚џ€€€џwwwџiiiџ[[[џKKKџ]]]џџ–––џЃЃЃџЋЋЋџЎЎЎџ­­­џ­­­џАААџЕЕЕџГГГџ@@@џџ­ГВџAAAџ,,,џ)))џ"""џџ589џЃЃџЈЋЋџ   џЗЗЗџЕЕЕџАААџАААџ‘‘‘џЭЭЭџ›››џВВВџЎЎЎџЏЏЏџЄЄЄџšššџ•••џІІІџЦЦЦџоооџкккџЧЧЧџЗЗЗџ   џдддџЖЖЖџМММџЕЕЕџЗЗЗџЌЌЌџЂЂЂџАААџЙЙЙџЊЊЊџЎЎЎџІІІџ ŒŒŒц˜˜˜џџ‹‹‹џОООџКККџзззџЩЩЩџМММџНННџОООџИИИџЖЖЖџЏЏЏџГГГџНННџЦЦЦџЩЩЩџЮЮЮџЬЬЬџЪЪЪџЧЧЧџТТТџКККџИИИџНННџОООџНННџЁЁЁџЇЇЇџ   џšššџџ‹‹‹џ~~~џwwwџkkkџhhhџ[[[џeeeџpppџџџ–––џšššџЄЄЄџЉЉЉџŸŸŸџ———џŒŒŒџ†††џџuuuџkkkџ\\\џKKKџ^^^џ}}}џ•••џЃЃЃџЋЋЋџ­­­џ­­­џЋЋЋџГГГџЗЗЗџВВВџ>>>џџ­ГВџKKKџ777џ333џ+++џ џ:<=џ›ЁЁџДЗЖџЈЈЈџЛЛЛџЗЗЗџДДДџДДДџ”””џЬЬЬџЗЗЗџИИИџЏЏЏџЕЕЕџБББџЋЋЋџДДДџБББџ›››џŸŸŸџЛЛЛџйййџмммџІІІџЭЭЭџЕЕЕџЛЛЛџАААџЙЙЙџНННџАААџЋЋЋџВВВџЎЎЎџЗЗЗџІІІџ‹‹‹ ‰‰‰р“““џ|||џ˜˜˜џЦЦЦџЏЏЏџЄЄЄџ‹‹‹џxxxџ‰‰‰џџ———џДДДџЦЦЦџвввџфффџэээџщщщџьььџнннџиииџнннџжжжџ‘‘‘џдддџеееџЪЪЪџЮЮЮџУУУџШШШџТТТџЦЦЦџОООџУУУџНННџГГГџБББџЊЊЊџџџ’’’џuuuџjjjџlllџaaaџ```џ```џxxxџ‰‰‰џ™™™џ–––џ‰‰‰џxxxџlllџ[[[џYYYџjjjџџ˜˜˜џЅЅЅџ­­­џЏЏЏџЎЎЎџЎЎЎџБББџДДДџАААџ>>>џџАЕДџRSSџ@@@џ<<<џ666џ+**џ?BCџ™Ÿ џЇЊЉџЗЖЗџлллџЦЦЦџГГГџЅЅЅџ”””џгггџИИИџЖЖЖџЛЛЛџЛЛЛџЖЖЖџЗЗЗџНННџИИИџЖЖЖџ­­­џšššџšššџЋЋЋџДДДџмммџкккџЩЩЩџГГГџМММџНННџЗЗЗџАААџЕЕЕџГГГџЛЛЛџІІІџqqq tttй’’’џzzzџsssџƒƒƒџZZZџ^^^џqqqџЄЄЄџТТТџгггџдддџшшшџьььџыыыџьььџэээџэээџцццџнннџлллџуууџмммџ‘‘‘џйййџиииџбббџЭЭЭџЬЬЬџТТТџМММџЙЙЙџДДДџИИИџЖЖЖџЕЕЕџЕЕЕџДДДџЌЌЌџЇЇЇџЈЈЈџvvvџ›››џЋЋЋџˆˆˆџ{{{џjjjџZZZџIIIџEEEџSSSџ{{{џ‹‹‹џwwwџQQQџ444џhhhџ’’’џЊЊЊџЊЊЊџ­­­џБББџЏЏЏџВВВџБББџИИИџЏЏЏџ???џ џЋАЏџfggџHGGџFFFџ@@@џ555џEGHџ™  џ–š™џjjjџ–––џОООџмммџаааџ–––џкккџЎЎЎџКККџЗЗЗџЙЙЙџИИИџОООџКККџБББџДДДџЌЌЌџџБББџЋЋЋџ™™™џšššџЖЖЖџдддџкккџЩЩЩџЕЕЕџЏЏЏџЖЖЖџГГГџКККџЗЗЗџІІІџƒƒƒа’’’џ```џMMMџgggџ–––џџ™™™џжжжџзззџмммџмммџхххџтттџпппџцццџцццџъъъџсссџсссџрррџзззџлллџ‘‘‘џлллџиииџбббџШШШџТТТџЩЩЩџМММџЗЗЗџЙЙЙџЎЎЎџБББџМММџЖЖЖџАААџЌЌЌџЏЏЏџІІІџ~~~џ“““џІІІџ–––џџ”””џŽŽŽџ‚‚‚џiiiџDDDџ(((џCCCџtttџfffџ$$$џџ;;;џwwwџБББџФФФџОООџВВВџБББџГГГџКККџДДДџKKKџџnrrџœ ŸџMLLџNNNџIIIџ@??џIKLџ˜žŸџЎААџžžžџ~~~џ’’’џŠŠŠџЈЈЈџ’’’џтттџбббџТТТџЗЗЗџЙЙЙџПППџМММџСССџМММџЃЃЃџџuvvџˆˆˆџџ–––џЈЈЈџ———џџџПППџжжжџЯЯЯџРРРџЕЕЕџГГГџНННџІІІџ rrrиDDDџZZZџџДДДџШШШџ‹‹‹џžžžџиииџгггџзззџкккџмммџнннџщщщџрррџтттџфффџуууџщщщџрррџнннџрррџ‘‘‘џтттџжжжџЭЭЭџЭЭЭџРРРџШШШџОООџХХХџЛЛЛџИИИџИИИџЛЛЛџВВВџЌЌЌџЊЊЊџЈЈЈџВВВџ~~~џ–––џ­­­џџ‹‹‹џ‡‡‡џŠŠŠџ‹‹‹џ‹‹‹џˆˆˆџlllџBBBџ&&&џNNNџ\\\џiiiџZZZџ===џ666џfffџžžžџРРРџЦЦЦџМММџИИИџЏЏЏџ```џlllџџЂЁџ‘‘џSSSџLLLџGGGџNPQџЃЃџЈЋЊџЇІІџŠŠŠџзззџЌЌЌџ   џ‰‰‰џџУУУџмммџлллџХХХџНННџЖЖЖџЗЗЗџТТТџbaaџgjiџНУТџЋАЏџ ЃЃџ‰‹Šџ‚‚‚џ”””џАААџ   џˆˆˆџ‡‡‡џЅЅЅџЦЦЦџЯЯЯџЦЦЦџЙЙЙџІІІџUUUVVVЯlllџŽŽŽџІІІџВВВџЛЛЛџˆˆˆџ———џзззџжжжџпппџмммџпппџйййџсссџлллџхххџфффџцццџцццџсссџхххџлллџ‘‘‘џсссџвввџаааџЧЧЧџМММџДДДџИИИџАААџИИИџИИИџЕЕЕџЕЕЕџЎЎЎџВВВџГГГџВВВџЎЎЎџƒƒƒџ˜˜˜џІІІџ’’’џ’’’џ………џ†††џ„„„џ{{{џџ€€€џzzzџaaaџCCCџUUUџoooџ’’’џžžžџ™™™џHHHџ,,,џKKKџyyyџДДДџЯЯЯџСССџ]]]џШШШџ:::џџ‘‘џЇЋЋџ|}}џ[[[џpsuџДЛКџЁЂЂџЏЏЏџ‰‰‰џеееџТТТџНННџБББџЅЅЅџџ–––џВВВџгггџуууџеееџЬЬЬџКККџ999џY\\џ˜џdijџ–—џЉЏЎџАЕДџšœœџŒŒџЇЇЇџОООџ­­­џџyyyџџЖЖЖџЭЭЭџІІІџmmm­{{{џ‹‹‹џœœœџЈЈЈџОООџƒƒƒџ“““џйййџеееџкккџлллџпппџоооџоооџкккџоооџнннџуууџйййџбббџЯЯЯџЫЫЫџБББџеееџЭЭЭџЧЧЧџУУУџЙЙЙџЖЖЖџЖЖЖџУУУџЙЙЙџИИИџ­­­џЕЕЕџЎЎЎџВВВџЎЎЎџЌЌЌџЄЄЄџ|||џŽŽŽџЌЌЌџŠŠŠџˆˆˆџˆˆˆџƒƒƒџџ~~~џ}}}џzzzџxxxџwwwџaaaџVVVџpppџ‘‘‘џЃЃЃџЛЛЛџfffџrrrџ›››џaaaџHHHџaaaџџXXXџнннџЬЬЬџXXXџџ=@?џŠџЋАЏџЏЕДџ“—–џЁЁЁџЏЏЏџ‹‹‹џЫЫЫџДДДџЎЎЎџЗЗЗџМММџНННџЕЕЕџџ•••џЅЅЅџФФФџпппџмммџFEEџ_cbџtxwџџ,./џIMNџv{|џЄЊЊџЏДГџšœ›џЕЕЕџНННџЛЛЛџЈЈЈџoooџzzzџ}}}џІІІџmmmž{{{џŠŠŠџ———џЅЅЅџЗЗЗџ„„„џ“““џзззџгггџмммџиииџнннџсссџдддџрррџйииџРРРџТТТџЌЌЌџ›››џŸŸŸџ ЁЁџƒƒƒџЌЋЋџРРРџЫЫЫџЯЯЯџХХХџФФФџСССџИИИџЧЧЧџРРРџЦЦЦџОООџРРРџЙЙЙџЏЏЏџЇЇЇџЃЃЃџuuuџ–––џЄЄЄџŒŒŒџ†††џƒƒƒџ}}}џ~~~џ€€€џџzzzџyyyџvvvџbbbџ[[[џrrrџ‘‘‘џЉЉЉџЖЖЖџcccџzzzџШШШџЙЙЙџЎЎЎџŠŠŠџ\\\џIIIџxxxџИИИџсссџЙЙЙџYXXџџџ-.-џ€€џЕЕЕџБББџˆˆˆџгггџЊЊЊџМММџЋЋЋџКККџШШШџТТТџЙЙЙџЛЛЛџЅЅЅџžžžџŸŸŸџМММџIHIџ_cbџx|{џ џ џ џџKOQџЄЋЋџЋЎ­џЃЃЃџЗЗЗџЛЛЛџДДДџ~~~џТТТџœœœџІІІџgggˆ|||џ………џ’’’џЂЂЂџВВВџŒŒŒџœœœџЬЬЬџЭЭЭџлллџнннџкккџлллџЬЬЫџаааџХЦЦџЗЛКџЖЛКџДКЙџДКЙџИОНџЙООџЊЏЎџXYYџxxxџ’’’џЂЂЂџЄЄЄџ›››џџ–––џ‰‰‰џџЂЂЂџœœœџœœœџ­­­џЎЎЎџ­­­џПППџ†††џŒŒŒџЌЌЌџ–––џ†††џ|||џƒƒƒџ}}}џџ€€€џyyyџ~~~џyyyџcccџ[[[џoooџ’’’џЋЋЋџЛЛЛџbbbџwwwџШШШџВВВџЕЕЕџТТТџЙЙЙџЈЈЈџџbbbџiiiџžžžџдддџжжжџЛЛЛџЏЏЏџМММџФФФџБББџ„„„џкккџОООџНННџГГГџЕЕЕџФФФџФФФџКККџФФФџЗЗЗџПППџФФФџ   џ???џ`cbџ~џџџџџ034џžЅЅџ­ААџЄЄЄџЛЛЛџНННџЉЉЉџzzzџШШШџКККџІІІџfffwwwџ‰‰‰џ–––џœœœџАААџ‚‚‚џ•••џжжжџУУУџЖЖЖџЕЕЕџЉЉЉџВВВџМЛМџЗКЙџИОНџ ІЇџŠ‘џv||џlqsџgkmџosuџДККџ17:џrrsџŸŸŸџЗЗЗџГГГџžžžџ”””џ———џџ˜˜˜џџ|||џtttџjjjџjjjџdddџbbbџ[[[џdddџ}}}џ”””џ“““џ–––џŽŽŽџџџyyyџ~~~џџ{{{џdddџYYYџqqqџŽŽŽџ­­­џЛЛЛџ___џzzzџЩЩЩџГГГџЙЙЙџДДДџЗЗЗџКККџУУУџРРРџЄЄЄџ|||џhhhџ„„„џЗЗЗџкккџиииџаааџЗЗЗџ‡‡‡џаааџСССџЙЙЙџ­­­џ­­­џДДДџЗЗЗџЬЬЬџНННџНННџТТТџЖЖЖџЋЋЋџ\[\џ\_^џƒ‡†џ$$$џ'''џ џџ7:;џžЄЄџ­АЏџАААџЙЙЙџБББџЏЏЏџ}}}џЦЦЦџНННџІІІџmmm~wwwџ‚‚‚џžžžџБББџЌЌЌџџsssџ‚‚‚џƒƒƒџџІІІџЃЃЃџТТТџХХХџЭааџ—žžџHLNџ)+-џџџџ%%&џ­ГГџ3:=џz{{џИИИџФФФџРРРџВВВџЌЌЌџšššџЙЙЙџНННџЅЅЅџЃЃЃџЈЈЈџ———џ———џџzzzџpppџaaaџPPPџVVVџUUUџ^^^џnnnџ~~~џ‰‰‰џŽŽŽџŠŠŠџxxxџwwwџ\\\џSSSџsssџ•••џЋЋЋџКККџbbbџ{{{џТТТџЖЖЖџЗЗЗџГГГџЕЕЕџДДДџНННџЛЛЛџХХХџЩЩЩџНННџ|||џhhhџxxxџ•••џХХХџжжжџŒŒŒџбббџВВВџШШШџЛЛЛџЏЏЏџКККџИИИџЪЪЪџСССџЛЛЛџКККџМММџЌЌЌџZZZџ[^^џ‰ŒŒџ0//џ111џ+++џџ<>?џœЂЃџГЖЕџЖЖЖџКККџОООџВВВџ{{{џЫЫЫџОООџІІІџ```zyyyџœœœџ“““џqqqџbbbџiiiџџ’’’џЊЊЊџЬЬЬџЫЫЫџ‘‘‘џпппџхххџзккџ—žџ*,-џџ џџџ)))џЎДГџ3:=џxwxџФФФџИИИџБББџІІІџБББџЂЂЂџ­­­џЌЌЌџЄЄЄџЈЈЈџЄЄЄџ›››џŸŸŸџŸŸŸџџ’’’џџ………џvvvџqqqџ___џPPPџ@@@џGGGџTTTџvvvџ“““џўRRRўJJJџiiiџ‹‹‹џ   џЙЙЙџbbbџvvvџЧЧЧџКККџЛЛЛџЗЗЗџРРРџКККџОООџУУУџФФФџУУУџЧЧЧџˆˆˆџІІІџЧЧЧџ–––џ~~~џ‚‚‚џzzzџЭЭЭџлллџвввџНННџЙЙЙџУУУџНННџОООџУУУџЦЦЦџРРРџОООџЌЌЌџ[ZZџ[_^џ‘џ:::џ<<<џ555џ)))џ@CEџЃЃџ ЃЂџ˜˜˜џЮЮЮџжжжџУУУџ}}}џЦЦЦџХХХџІІІџyyyv‚‚‚џ___џDDDџfffџ~~~џЁЁЁџЙЙЙџЧЧЧџРРРџНННџЯЯЯџ‘‘‘џоооџчччџдззџ—žžџ/23џ џџџџ333џЎДГџ4;>џzz{џЙЙЙџРРРџСССџЏЏЏџГГГџ   џ   џАААџЋЋЋџЇЇЇџ›››џŸŸŸџ›››џџ•••џџŽŽŽџ†††џ}}}џyyyџtttџyyyџnnnџMMMџ999џ222џJJJџyyyўZZZќ??@џ[[[џvvvџŒŒŒџЈЈЈџ\\\џrrrџФФФџМММџКККџНННџНННџНННџТТТџФФФџХХХџЧЧЧџЬЬЬџˆˆˆџІІІџзззџХХХџТТТџАААџ™™™џ†††џ˜˜˜џНННџйййџпппџгггџТТТџРРРџМММџОООџШШШџЧЧЧџ­­­џ]\\џW[Zџ˜œ›џDDDџFFFџ@@@џ555џEHIџœЂЃџІЉЉџƒ‚ƒџџ•••џЎЎЎџ|||џгггџЩЩЩџІІІџhhhzAAAџKKKџ}}}џœœœџ   џЗЗЗџЙЙЙџИИИџПППџЫЫЫџбббџ‘‘‘џпппџшшшџзкйџ—џ367џџџ$$$џ'''џ<==џЏЕДџ4;>џwxxџЖЖЖџСССџУУУџКККџЖЖЖџ———џЄЄЄџДДДџЇЇЇџІІІџЁЁЁџЂЂЂџЂЂЂџšššџ•••џ‰‰‰џ‰‰‰џџ{{{џrrrџlllџsssџuuuџSSSџnnnџzzzџAAAџ333џ///џџ===џ^^^џvvvџŒŒŒџKKKџdddџЏЏЏџЋЋЋџВВВџИИИџНННџСССџТТТџЧЧЧџЦЦЦџФФФџЪЪЪџ†††џІІІџЯЯЯџСССџТТТџШШШџЪЪЪџОООџЈЈЈџ“““џџЉЉЉџЭЭЭџуууџпппџЩЩЩџМММџОООџТТТџБББџqqqџ!##џБЗЖџ^_^џLLLџJJJџ@@?џKMNџ˜Ÿ џЏВВџГГГџџˆˆˆџџmmmџ™™™џХХХџІІІџMMMlZZZџ{{{џџ›››џЌЌЌџЋЋЋџЏЏЏџКККџМММџжжжџЫЫЫџ‘‘‘џуууџыыыџзккџ•›œџ8:<џџ&&&џ---џ222џEFFџАЕЕџ4:=џyyzџПППџЩЩЩџПППџЕЕЕџЗЗЗџœœœџЋЋЋџКККџ­­­џІІІџŸŸŸџŸŸŸџџ˜˜˜џџŒŒŒџƒƒƒџzzzџvvvџnnnџiiiџlllџsssџMMMџlllџ†††џuuuџbbbџџџџџ///џXXYџ;;;џTTTџ’’’џ‘‘‘џџЈЈЈџАААџИИИџМММџТТТџФФФџУУУџЫЫЫџˆˆˆџЅЅЅџзззџРРРџТТТџХХХџСССџФФФџФФФџФФФџСССџЇЇЇџ———џšššџИИИџзззџхххџзззџРРРџЊЊЊџЗЗЗџџjnmџЋАЏџ^^^џLLLџGGFџPRSџžЄЅџЅЈЈџАЏЏџ˜˜˜џЊЊЊџЦЦЦџЊЊЊџˆˆˆџuuuџІІІџWWWWfffџwwwџˆˆˆџšššџЈЈЈџЇЇЇџЋЋЋџВВВџОООџЫЫЫџЫЫЫџ‘‘‘џпппџшшшџзккџ’˜™џ=@Aџ%%%џ111џ888џ;;;џNOOџАЖЕџ4:=џyzzџМММџЧЧЧџПППџОООџСССџ–––џЇЇЇџЛЛЛџЉЉЉџІІІџ   џžžžџœœœџ———џŽŽŽџˆˆˆџ|||џsssџlllџjjjџgggџiiiџpppџHHHџeeeџ‚‚‚џsssџrrrџ&&&џџџџџџџ-..џYZZџrrrџ‚‚‚џŒ‹‹џ•••џЂЂЂџ­­­џЕЕЕџЛЛЛџОООџШШШџ†††џЄЄЄџвввџНННџСССџФФФџТТТџРРРџЦЦЦџНННџСССџЧЧЧџСССџ———џВВВџšššџЇЇЇџШШШџкккџЉЉЉџъъъџ{{{џџadcџЌБАџ‘џhiiџswwџЗННџЁЂЂџГГГџ“““џЊЊЊџвввџШШШџЩЩЩџРРРџІІІџVVVJdddџuuuџ‡‡‡џ———џЂЂЂџЎЎЎџЖЖЖџЗЗЗџСССџУУУџЬЬЬџ‘‘‘џоооџцхцџилкџ‘˜˜џBDEџ000џ;;;џAAAџEEEџVVVџБЗЖџ4:=џ}}}џЗЗЗџЩЩЩџЪЪЪџРРРџУУУџ‘‘‘џЉЉЉџКККџЅЅЅџІІІџ   џœœœџЅЅЅџџ“““џŠŠŠџ{{{џsssџiiiџdddџcccџbbbџpppџHHHџdddџƒƒƒџsssџoooџ"""џџџџџџџџ џџ===џ]^^џvvvџ………џџ™™™џЄЄЄџЎЎЎџКККџ}}}џŸŸŸџЮЮЮџПППџХХХџЧЧЧџУУУџНННџЪЪЪџСССџФФФџУУУџЖЖЖџœœœџпппџЦЦЦџЙЙЙџЅЅЅџ   џšššџЮЮЮџыыыџžžžџ!!!џ$&%џosrџЄЉЈџ­ГВџ“’џЈЈЈџФФФџ–––џЋЋЋџаааџФФФџШШШџЪЪЪџІІІџVVV;ddd§vvvџ………џ———џЃЃЃџЎЎЎџМММџЦЦЦџХХХџЪЪЪџаааџ‘‘‘џхххџыъыџлонџ–œœџGIJџ;::џEEEџKKKџLKKџeffџДКЙџ4:=џ‹ŒŒџЭЭЭџеееџЯЯЯџЯЯЯџЭЭЭџ™™™џ­­­џШШШџОООџКККџДДДџЊЊЊџЇЇЇџІІІџџџxxxџnnnџhhhџcccџbbbџeeeџpppџFFFџcccџ„„„џtttџnnnџџџџџџџџ џ џ џџџ%%%џBCCџcccџvuvџ‚‚‚џџœœœџmmmџџСССџЕЕЕџЗЗЗџСССџРРРџСССџУУУџТТТџУУУџТТТџОООџœœœџкккџШШШџЬЬЬџЮЮЮџХХХџЖЖЖџЃЃЃџЅЅЅџЦЦЦџШШШџ†…†џ===џџ***џ‹‹‹џПППџЩЩЩџ™™™џЉЉЉџЯЯЯџЩЩЩџЪЪЪџЩЩЩџІІІџXXX+eeeїuuuџˆˆˆџ–––џЄЄЄџЎЎЎџЖЖЖџТТТџЯЯЯџиииџзззџЇЇЇџтттџшшшџжйиџЇЎЎџORSџAAAџKKKџNMNџSRRџŸЃЂџ–џ'-0џyzzџœœœџ›››џŽŽŽџџ•••џ~~~џ{{{џ‚‚‚џ‰‰‰џ›››џ   џЇЇЇџЎЎЎџІІІџ­­­џЈЈЈџšššџŠŠŠџtttџfffџ```џeeeџoooџEEEџcccџ………џtttџmmmџџџџџџџџ џ џ џџџ џџџ`bbџwyyџ```џ~~~џXXXџvvvџšššџžžžџЈЈЈџВВВџЛЛЛџОООџТТТџЦЦЦџФФФџСССџСССџœœœџмммџЩЩЩџЫЫЫџЫЫЫџЫЫЫџЭЭЭџЬЬЬџРРРџЌЌЌџЄЄЄџБББџОООџЩШШџвввџиииџЧЧЧџЫЫЫџ˜˜˜џЊЊЊџеееџЫЫЫџЫЫЫџЪЪЪџІІІџ\\\eeeёwwwџ†††џ–––џЈЈЈџНННџШШШџЭЭЭџШШШџНННџЎЎЎџžžžџЉЉЉџДДДџЕЕЖџЕККџ••џ\^]џaaaџ{||џЈЌЊџЌВБџ2:=џGKNџЊЊЊџЗЗЗџБББџ­­­џŸŸŸџ˜˜˜џ–––џџџvvvџlllџdddџcccџcccџaaaџ[[[џ]]]џhhhџtttџџ„„„џ„„„џџ|||џFFFџcccџƒƒƒџsssџmmmџџџџџџџџ џ џ џџџџџ џillџkmnџџ555џ999џ___џ}}}џ„„„џџžžžџЈЈЈџБББџЗЗЗџЙЙЙџЛЛЛџХХХџРРРџšššџнннџЪЪЪџЭЭЭџЭЭЭџЭЭЭџЬЬЬџЬЬЬџЫЫЫџЫЫЫџЧЧЧџЄЄЄџџЁЁЁџЇЇЇџУУУџйййџуууџЁЁЁџЊЊЊџзззџЬЬЬџЬЬЬџЬЬЬџІІІџ[[[fffюxxxџ’’’џЌЌЌџАААџџ„„„џsssџxxxџ‚‚‚џ˜˜˜џЕЕЕџРРРџЮЮЮџкккџЃІІџŒ““џЋББџ­ГГџ›ЁЁџovwџ(/3џBHJџЗИИџлллџжжжџаааџЬЬЬџЧЧЧџРРРџНННџЙЙЙџВВВџЌЌЌџЈЈЈџšššџvvvџЄЄЄџ†††џqqqџbbbџNNNџ???џ666џ:::џBBBџVVVџsssџKKKџdddџŒŒŒџqqqџhhhџџџџџџџџ џ џ џџџџџ џiklџkmmџџџџ%&&џ999џSSSџjkkџ{||џ‰‰‰џ“““џžžžџЊЊЊџГГГџЛЛЛџИИИџ•••џзззџШШШџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЫЫЫџШШШџХХХџЫЫЫџЈЈЈџТТТџЭЭЭџ­­­џ–––џџЈЈЈџџЋЋЋџчччџдддџЬЬЬџЩЩЩџІІІџmmmqqqь———џџcccџGGGџLLLџlllџџБББџЭЭЭџйййџрррџхххџщщщџыыыџсссџ{€џDJLџ;BEџ=BEџQVXџŒџгггџтттџкккџгггџЯЯЯџЫЫЫџХХХџПППџКККџЗЗЗџАААџ­­­џЉЉЉџœœœџxxxџЕЕЕџ“““џŠŠŠџ|||џrrrџiiiџ___џTTTџHHHџ888џ+++џ%%%џ:::џsssџ………џkkkџ џџ џџџџџ џ џ џџџџџ џiklџkmmџџџ џ!!!џ џ"""џ+++џAAAџXXXџpppџ€џ‹‹‹џ•••џЁЁЁџЅЅЅџ‰‰‰џЫЫЫџСССџЦЦЦџЩЩЩџШШШџЩЩЩџЫЫЫџЧЧЧџШШШџЫЫЫџЅЅЅџСССџаааџЪЪЪџЫЫЫџПППџЃЃЃџ†††џ€€€џЂЂЂџЩЩЩџнннџйййџІІІџ{{{ы[[[џ;;;џNNNџ}}}џЈЈЈџРРРџЯЯЯџиииџмммџоооџсссџфффџуууџуууџщщщџ‘‘‘џЬЭЭџзииџкллџфффџээьџцццџрррџкккџгггџЯЯЯџШШШџЦЦЦџТТТџЛЛЛџЖЖЖџАААџЊЊЊџЅЅЅџšššџpppџВВВџŠŠŠџџuuuџnnnџhhhџfffџhhhџmmmџoooџgggџWWWџ:::џ!!!џ>>>џdddџџ"""џ222џ444џ(((џџџџџ џџџџџ џiklџkmmџџџ џ"""џ$$$џ%%%џ'''џ'''џ***џ333џGGHџ^^^џuuuџ‚‚‚џ‰‰‰џsssџБББџЎЎЎџЕЕЕџМММџОООџСССџЧЧЧџЧЧЧџЦЦЦџЫЫЫџІІІџСССџгггџЪЪЪџЫЫЫџЮЮЮџгггџЯЯЯџЙЙЙџ“““џzzzџ‚‚‚џЋЋЋџІІІџfffJJJь000џuuuџЌЌЌџГГГџНННџСССџЬЬЬџдддџкккџоооџтттџхххџфффџхххџшшшџ‘‘‘џкккџюююџыыыџхххџтттџсссџнннџйййџдддџЯЯЯџЪЪЪџФФФџПППџЛЛЛџЖЖЖџБББџЋЋЋџІІІџ———џmmmџЖЖЖџџ}}}џtttџlllџfffџfffџhhhџlllџrrrџwwwџ|||џ|||џiiiџ:::џ###џ џџџџ+++џBBBџJJJџ<<<џ!!!џ џџ џџџ џiklџkmmџџџ џ"""џ$$$џ%%%џ(((џ+++џ---џ...џ,,,џ***џprrџ}џZZZџ\\\џџŒŒŒџ™™™џЂЂЂџЋЋЋџДДДџЛЛЛџНННџФФФџЩЩЩџІІІџРРРџеееџЬЬЬџЭЭЭџЯЯЯџаааџвввџдддџеееџЪЪЪџЉЉЉџ………џІІІџTTT mmmлUUUџ}}}џЕЕЕџВВВџКККџФФФџЬЬЬџеееџнннџрррџфффџчччџщщщџщщщџшшшџ‘‘‘џйййџшшшџхххџрррџоооџмммџйййџжжжџбббџЭЭЭџШШШџТТТџОООџКККџЕЕЕџАААџЊЊЊџЄЄЄџ–––џkkkџДДДџ€€€џzzzџqqqџjjjџhhhџgggџjjjџnnnџrrrџyyyџ}}}џ~~~џџџYYYџџ џџ џ џ џџ888џVVVџ^^^џMMMџ+++џџ џџhjkџkmmџџџ џ"""џ$$$џ%%%џ(((џ+++џ---џ///џ000џ***џwyzџwyyџ0//џAAAџUUUџfffџuuuџџŒŒŒџ•••џ   џЋЋЋџЏЏЏџНННџŸŸŸџЛЛЛџгггџЪЪЪџЮЮЮџаааџбббџбббџбббџбббџгггџзззџгггџІІІџ}}}ЩWWWџzzzџЗЗЗџВВВџЛЛЛџФФФџЬЬЬџеееџмммџтттџхххџчччџшшшџхххџшшшџ‘‘‘џаааџсссџкккџиииџжжжџвввџЮЮЮџЩЩЩџЧЧЧџТТТџОООџЙЙЙџЖЖЖџВВВџ­­­џЉЉЉџЅЅЅџЁЁЁџ“““џhhhџБББџ~~~џyyyџrrrџlllџjjjџjjjџnnnџsssџxxxџ}}}џџ‚‚‚џ€€€џ‚‚‚џhhhџџџџџџџџџџ"""џ@@@џ___џeeeџSSSџ'&&џmopџfhhџ џџ џ"""џ$$$џ%%%џ(((џ+++џ---џ///џ000џ+++џvxyџxzzџ211џ:::џ:::џ@@@џIIIџWWXџiiiџwwwџƒƒƒџ‹‹‹џ™™™џЇЇЇџџЎЎЎџЩЩЩџХХХџЪЪЪџЭЭЭџЯЯЯџбббџбббџвввџвввџвввџгггџІІІџМWWWџzzzџКККџГГГџНННџЦЦЦџЭЭЭџгггџиииџоооџсссџсссџрррџмммџйййџ‘‘‘џРРРџЯЯЯџЩЩЩџЦЦЦџТТТџНННџИИИџЗЗЗџГГГџЏЏЏџ­­­џЈЈЈџЅЅЅџЃЃЃџ   џœœœџ™™™џ–––џŠŠŠџaaaџЈЈЈџyyyџvvvџoooџkkkџkkkџmmmџrrrџwwwџ}}}џџ„„„џ………џ„„„џ………џfffџџџџџџџџџџџџџ---џUVVџrstџЄЅІџ‘’“џ999џ%%%џџџ"""џ%%%џ(((џ+++џ---џ///џ000џ+++џvxyџxzzџ211џ;;;џ>>>џAAAџBAAџBBBџFFFџOOOџ\\\џkkkџzzzџŠŠŠџvvvџ“““џВВВџДДДџНННџУУУџШШШџЫЫЫџЮЮЮџаааџбббџвввџвввџІІІџ………Ў[[[џ{{{џЛЛЛџАААџМММџФФФџЧЧЧџЬЬЬџЮЮЮџЯЯЯџаааџаааџЭЭЭџЩЩЩџФФФџ‘‘‘џЎЎЎџЕЕЕџЏЏЏџЌЌЌџІІІџЁЁЁџџœœœџ–––џ•••џ’’’џџŽŽŽџŒŒŒџŠŠŠџ‰‰‰џ‡‡‡џ………џ|||џWWWџ˜˜˜џpppџnnnџiiiџgggџhhhџlllџrrrџyyyџџƒƒƒџ†††џ‡‡‡џ†††џ†††џsssм>>>И,,,ё&&&џ џџ"""џ(((џ222џGHHџ\^^џruuџƒ††џ””џ”˜™џ„…џvxxџaabџhhhџwwwџkkkџHHHџ---џџ"""џ)))џ---џ///џ000џ+++џvxyџxzzџ211џ;;;џ>>>џAAAџCCCџEEEџGGGџGGGџHHHџMMMџVVVџddeџdeeџxyyџџ•••џЂЂЂџ­­­џЖЖЖџОООџФФФџЩЩЩџЬЬЬџЯЯЯџаааџІІІџ‰‰‰Ÿ]]]џzzzџИИИџЎЎЎџГГГџЗЗЗџЙЙЙџЙЙЙџКККџЙЙЙџЗЗЗџДДДџАААџЋЋЋџЇЇЇџ‘‘‘џџ•••џŒŒŒџŠŠŠџ„„„џ‚‚‚џџ{{{џvvvџuuuџsssџoooџoooџpppџoooџoooџnnnџnnnџgggџHHHџ€€€џbbbџ```џ___џ^^^џaaaџfffџlllџtttџ{{{џ€€€џ„„„џ‡‡‡џ‡‡‡џ………џ‚‚‚АQQQPPSeKLLŸgjjн}ўŒџ™џ’––џ†‰Šџxz{џaccџMMMџ9::џ111џ***џ&%%џ&&&џ222џMNNџoooџ{{{џqrrџQQQџ666џ'''џ)))џ...џ+++џvxyџxzzџ211џ;;;џ>>>џAAAџCCCџEEEџGGGџIIIџKKKџMMMџMMMџIHHџ‚џ†‰‰џcccџuuuџ€€€џŒŒŒџ———џЄЄЄџЏЏЏџИИИџРРРџЦЦЦџЪЪЪџІІІџŒŒŒ‘\\\џtttџЎЎЎџЂЂЂџЄЄЄџЃЃЃџЂЂЂџ   џџ™™™џ”””џ‘‘‘џŒŒŒџ‡‡‡џƒƒƒџpppџnnnџuuuџnnnџkkkџjjjџdddџdddџaaaџ^^^џ\\\џYYYџVVVџVVVџWWWџVVVџUUUџUUUџVVVџRRRџ777џgggџOOOџPPPџPPPџQQQџTTTџYYYџaaaџiiiџpppџwwwџ|||џџ„„„џƒƒƒџЋВВВ ЋЏГ@z}}’PPPс<<=џ333џ,++џ...џ111џ333џ444џ555џ666џ666џ555џ222џ///џ999џQRRџpppџџwwwџZZZџ===џ&&&џqsuџwyyџ100џ;;;џ>>>џAAAџCCCџEEEџGGGџIIIџKKKџMMMџOOOџKJJџƒ††џ„†‡џNNNџXXXџabbџkklџwwwџџџ™™™џЅЅЅџБББџКККџІІІџŒŒŒƒXXXџiiiџžžžџ‘‘‘џŽŽŽџ‰‰‰џ………џ€€€џ{{{џwwwџuuuџtttџuuuџvvvџuuuџoooџoooџtttџtttџtttџsssџrrrџoooџlllџiiiџeeeџaaaџ\\\џWWWџSSSџNNNџIIIџFFFџCCCџ???џ222џDDDџ===џ>>>џ@@@џAAAџFFFџKKKџPPPџXXXџ```џhhhџoooџvvvџ{{{џ~~~џ||| \\\ ```BTTTˆNOOгCCCњ@@@џ===џ???џ???џ???џ???џ???џ???џ???џ>>>џ;;;џ777џ>==џRRRџmmmџ~~~џqqqџ“”•џ}€џ0//џ444џ;;;џ@@@џCCCџEEEџGGGџIIIџKKKџMMMџOOOџKJJџ‚……џ„†‡џQPPџXXXџXXXџZZZџ]]]џeefџoooџzzzџƒƒƒџџœœœџІІІџ………zOOOџ[[[џ………џuuuџsssџkkkџiiiџlllџtttџ|||џ†††џџ”””џ–––џ•••џ”””џ’’’џџџџŠŠŠџ‡‡‡џƒƒƒџџzzzџvvvџqqqџlllџhhhџbbbџ\\\џWWWџRRRџLLLџGGGџCCCџ;;;џ888џ333џ111џ000џ222џ666џ???џEEEџNNNџUUUџ\\\џdddџmmmџrrrџvvv—mmmmmm1WYYxVXXТMNNѕJJJџGGFџGGGџEEEџDDDџCCCџGFGџKKKџNNOџWXXџcddџmooџ€‚‚џ“”џЉЌЌџŸ  џ~~~џjjjџOOOџ???џ<<<џBBBџFFFџIIIџKKKџMMMџOOOџKJJџ‚……џ„†‡џQPPџXXXџZZZџ[[[џ]]]џ\\\џ^^^џbbbџijjџqqqџ|}}џІІІџwwwuCCCџIIIџmmmџ]]]џ___џfffџvvvџˆˆˆџ•••џžžžџЃЃЃџІІІџІІІџЂЂЂџŸŸŸџšššџ———џ”””џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџGGGџBBBџ???џ<<<џ888џ444џ000џ...џ---џ///џ555џ???џIIIџRRRџZZZџaaaџkkkŒiii"giioabbА]^^юghhџrstџ€ƒƒџ‹Žџ”—˜џ ЁџЁЂџ—š›џ’“џ†‰‰џx{{џjkkџXYYџ```џxxxџ‹‹‹џ‡‡‡џrrrџWWWџFFGџBBBџHHHџLLLџOOOџKJJџ‚……џ„†‡џQPPџXXXџZZZџ[[[џ]]]џ^^^џ___џaaaџa``џbbbџeeeџbbbџeeel888џ888џXXXџ]]]џnnnџ~~~џŒŒŒџ–––џџЂЂЂџЅЅЅџІІІџІІІџЂЂЂџžžžџšššџ–––џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ???џ;;;џ999џ666џ444џ333џ333џ111џ///џ---џ000џ:::џFFFџOOOџbbb‡‡‡ЉББHЈ­Џ”——сƒ††џvwwџjjjџ`aaџ]]]џYYYџVVVџVVVџXWWџZZZџYYYџWWWџXXXџhhhџ|||џŽŽŽџ‹‹‹џzzzџ^^^џNNNџIIIџHGGџ„„џ„†‡џQPPџXXXџZZZџ[[[џ]]]џ^^^џ___џaaaџbbbџcccџdddџbbbџˆˆ???t@@@џHHHџ]]]џlllџyyyџƒƒƒџŽŽŽџ˜˜˜џžžžџЃЃЃџІІІџЇЇЇџЇЇЇџЃЃЃџŸŸŸџšššџ–––џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ111џ...џ111џ===џFFFssss pppOkmmŽkllлeeeќcccџcccџdddџdddџeeeџeeeџeeeџeeeџdddџcccџ```џaaaџnnnџџ‘‘‘џŽŽŽџ~~~џ_^^џ…ˆˆџ€‚ƒџMLLџWWWџZZZџ[[[џ]]]џ^^^џ___џaaaџbbbџcccџdddџbbbџˆˆ***m666ъGGGџVVVџaaaџmmmџyyyџ„„„џџ™™™џŸŸŸџЄЄЄџЈЈЈџЉЉЉџЈЈЈџЅЅЅџ   џ›››џ———џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ444џ333џ333џ333џ333џ333џ333џ444џ555џ:::џ===БDDDqq ;z||vwwЭoooјnnnџlllџmmmџmmmџmmmџlllџlllџkkkџjjjџiiiџjjjџkkkџ{||џ’””џ›џЏАБџŸЁЁџjjjџ\\\џTTTџWWWџ\\\џ^^^џ___џaaaџbbbџcccџdddџbbbџˆˆ (((œ555џ@@@џJJJџUUUџaaaџmmmџyyyџ………џџ™™™џ   џЅЅЅџЈЈЈџЉЉЉџЉЉЉџЅЅЅџ   џ›››џ–––џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ888џBBBџKKKџOOOЫOOO0™™™*€€€u~~Кxxxѓwwwџvvvџxxxџ}~~џ…††џŒŽџ“•–џ™œџžЂЃџЁЅІџœŸ џ“––џ‘“”џŽŽŽџ———џ—˜˜џŒŒŒџsssџbbbџYYYџ[[[џ```џbbbџcccџdddџbbbџˆˆ)))Ё222џ999џ@@@џIIIџUUUџaaaџmmmџyyyџ………џџ™™™џ   џЅЅЅџЇЇЇџЈЈЈџЇЇЇџЂЂЂќžžžјšššі™™™і”””ќџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ999џCCCџQQQџ\\\џZZZфRRR(ˆˆˆg™žž—ЃІІмЄЈЉџŸЂЃџ›žŸџ—™šџ’’џ‰ŠŠџƒƒƒџџ~~~џ{{{џ{{zџ{{{џџŒџšššџš››џџyyyџhhhџ^^^џ___џbbbџbbbџˆˆ'''h111џ444џ888џ@@@џIIIџTTTџ```џmmmџyyyџƒƒƒџџ–––§ŸŸŸўІІІ§ЊЊЊёАААяЖЖЖ§ЖЖЖіЕЕЕшЗЗЗрСССпЅЅЅѕџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ:::џEEEџSSSџ```џfffџ\\\ТUUUВВВ ”””V‰‰‹–ˆˆˆтƒƒƒџƒ‚‚џƒ‚‚џ„„„џ„„„џ………џ………џ………џ………џ„„„џƒƒƒџ‚‚‚џ†††џ‘‘џœџžžžџ”””џџlllџbbbџˆ---...у333џ444џ888џ@@@џIIIџSSSџ___џlllџzzzџŽŽŽ§ЂЂЂџБААљДДДћЛЛЛўОООћПППњСССўУУУџУУУџУУУџФФФџЂЂЂџŒŒŒџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ;;;џHHHџVVVџaaaџhhhџfffџTTTW””” ”””H‘Šе‹ŒŒњŒŒŒџ‹‹‹џ‹‹‹џŒ‹‹џŒŒŒџŒŒŒџŒŒŒџŒŒŒџ‹‹‹џŠŠŠџ‰‰‰џ‹‹‹џ”””џžžžџЁЁЁџ–––џˆˆˆ)))V222џ333џ444џ888џ???џHHHџSSSџ___џjjjџƒƒƒџ‚…†ўinoџЇЉЉџПООџМЛЛџИИИџИИИџИИИџИИИџИИИџИИИџКККџžžžџџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ;;;џ===џEEEџXXXџcccџgggџhhhџZZZБŸŸŸ›››3”””z•••Ц’’“і’’’џ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ’’’џ’’’џ‘‘‘ў№’’’у•——Н——™…‰‰‰ ---333џ333џ444џ888џ???џHHHџSSSџ___џjjjџ…„„џ‚……џ4;>џDKMџptuџ ЁЁџГВВџЏЏЏџ­­­џ­­­џ­­­џ­­­џЏЏЏџšššџŽŽŽџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ,,,џlllџ“““џiiiџ[[[џaaaџhhhџhhhџaaaчUUU ЊЊЊ———%™››q™™™В˜˜˜ю˜˜˜ь˜ššвššš ———~™œœjœ  A–––””” ///€333џ333џ333џ888џ???џHHHџRRRџ^^^џiiiџ………џˆ‹Œџ:ACџ?FHџ:BDџGNPџptuџš››џЄЃЃџЂЂЂџЂЂЂџЂЂЂџЃЃЃџ•••џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ,,,џlllџАААџЅЅЅџ“““џwwwџgggџgggџaaaчbbb ™™™‘ЃЃ‘‘‘///€333џ333џ333џ888џ???џHHHџRRRџ^^^џiiiџˆ‡‡џ““џ9@BџAHJџAHJџ?FHџ7?Aџfjkџš™™џ–––џ–––џ–––џ–––џџџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ---џeeeџžžžџ™™™џџŸŸŸџџlllџ^^^цbbb ///€333џ333џ333џ888џ???џGGGџQQQџ]]]џhhhџ‰ˆˆџ–™™џ8?AџAHJџAHJџAHJџ>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ///џ___џŒŒŒџ}}}џmmmџYYYџOOOџiiiџ^^^ы[[[///€333џ333џ333џ888џ???џGGGџQQQџ\\\џfffџ‰‰‰џ™œœџ8?AџAHJџAHJџAHJџ>EGџZ^_џџ}}}џ}}}џ}}}џ{{{џ„„„џ’’’џџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ777џ000џџџ џџџ\\\џ```юUUU///€333џ333џ333џ888џ???џGGGџQQQџ\\\џfffџ‰‰‰џ™œœџ8?AџAHJџAHJџAHJџ>EGџTYZџrrrџpppџpppџpppџnnnџ~~~џ“““џџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ444џ999џ џџ џ џ џџdddџ\\\чNNN ///€333џ333џ333џ888џ???џGGGџPPPџ[[[џeeeџ‰ˆˆџ™œœџ8?AџAHJџAHJџAHJџ?GIџOSUџeddџcccџcccџcccџ```џyyyџ“““џџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ444џ999џ(((џџџџџ!!!џnnnџYYYхUUU ///€333џ333џ333џ888џ???џGGGџPPPџ[[[џfffџ‰‰‰џ™œœџ8?AџAHJџAHJџAHJџ@GIџJOPџYXXџWWWџWWWџWWWџTTTџtttџ”””џŽŽŽџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ444џ:::џ...џ џ"""џ"""џџ000џџTTTхUUU ///€333џ333џ444џ888џ???џGGGџQQQџ]]]џhhhџ‹‹‹џ™œџ8?AџAHJџAHJџAHJџ@HJџFJKџMMMџMMMџMMMџMMMџHHHџkkkџ‘‘‘џˆˆˆџƒƒƒџџ~~~џzzzџuuuџqqqџlllџgggџbbbџZZZџRRRџOOOџJJJџGGGџDDDџBBBџ???џ<<<џ:::џ888џ666џ333џ333џ333џ333џ333џ444џ;;;џ444џ+++џ,,,џ,,,џ)))џ>>>џџPPPхUUU ///€333џ333џ444џ888џ@@@џHHHџTTTџaaaџmmmџ‘џ›žžџ8?AџAHJџAHJџAHJџAHJџCGHџBBBџAAAџBBBџBBBџDDDџŒŒŒџНННџОООџСССџФФФџХХХџПППџЙЙЙџЕЕЕџАААџЎЎЎџЏЏЏџЉЉЉџЇЇЇџœœœџ”””џ†††џsssџ\\\џLLLџAAAџ555џ,,,џ...џ///џ111џ222џ333џ333џ555џ;;;џ<<<џ777џ888џ888џ555џMMMџ———џKKKхUUU ///€333џ333џ333џ888џ@@@џIIIџWWWџgggџsssџ—––џšџ7>@џAHJџAHJџAHJџCJMџ045ў222ўџџ+++џ999џџЬЬЬџЫЫЫџЦЦЦџТТТџСССџМММџЗЗЗџЗЗЗџЕЕЕџЗЗЗџЛЛЛџОООџЦЦЦџУУУџШШШџЮЮЮџгггџжжжџЯЯЯџСССџ­­­џŽŽŽџmmmџIIIџ777џ///џ+++џ///џ555џ<<<џCCCџDDDџDDDџDDDџAAAџYYYџœœœџGGGх??? ///€333џ333џ333џ888џ@@@џJJJџVVVџdddџ{{{џЋЋЋџЏВВџ7>Aџ;BDџAHJџAHJџELNџ!%&џ444§ўџ###џ444џEEEџlllџ™™™џЇЇЇџЄЄЄџЂЂЂџЂЂЂџЂЂЂџЁЁЁџ   џŸŸŸџžžžџџ›››џšššџ˜˜˜џ———џšššџœœœџŸŸŸџЃЃЃџАААџМММўПППџПППџЌЌЌџ‘‘‘џoooџKKKџ777џ555џHHHџQQQџPPPџPPPџMMMџeeeџœœœџDDDф??? ///€333џ333џ333џ777џ999џDDDџlllџЅЅЅўаааўлллўжжжџЎАБџZ`bџ7>@џ>EGџDLNџ&*+џ?>>ўџџ$$$џ666џFFFџRRRџdddџ………џŸŸŸџЅЅЅџЂЂЂџЁЁЁџ   џŸŸŸџžžžџџœœœџšššџ˜˜˜џ˜˜˜џ–––џ•••џ”””џ’’’џ‘‘‘џŽŽŽџ‹‹‹џ‹‹‹џџ“““џџЇЇЇџЈЈЈџ   џ………џZZZџ[[[џ[[[џ[[[џXXXџpppџ›››џ>>>ф??? ///€333џ333џ///џ111џbbbџЎЎЎ§зззћввв§ЛЛЛўЋЋЋџІІІџРРРџЯааџ‘•–џFLNџ;CEџ)-.џLLLўџџ$$$џ666џGGGџVVVџ```џcccџnnnџ‰‰‰џ›››џ™™™џ———џ˜˜˜џ–––џ’’’џ———џ™™™џ›››џ™™™џ‘‘‘џџџџџ‹‹‹џŠŠŠџˆˆˆџ‡‡‡џ………џ„„„џџ‚‚‚џ‹‹‹џ‹‹‹џgggџgggџgggџgggџdddџ|||џšššџ;;;ф??? ///€333џ+++џDDDџ›››ќдддќУУУ§ЋЋЋўЅЅЅџІІІџЇЇЇџЇЇЇџЄЄЄџЈЈЈџЧЧЧџПССџqxyџ/34џZYYўџџ$$$џ666џGGGџVVVџaaaџfffџbbbџ\\\џ```џSSSџEEEџAAAџAAAџIIIџ;;;џGGGџPPPџ```іМŠŠŠнˆˆˆѕ‡‡‡џ†††џ………џƒƒƒџƒƒƒџ„„„џ………џ{{{џzzzџxxxџrrrџoooџrrrџrrrџrrrџrrrџpppџ†††џšššџ999ф??? ///€,,,џ]]]іДДДєСССќЉЉЉџЄЄЄџІІІџІІІџЅЅЅџЅЅЅџЄЄЄџЃЃЃџЁЁЁџџБББџЧЧЧџVWWџcccўџџ$$$џ666џGGGџVVVџaaaџfffџdddџ\\\џPPPџBBBџ333џ$$$џ'''џEEEџџџџшjjj ™™™ ‡‡‡"‚‚‚Z€€€‘~~~дџџqqqџMMMџMMMџ}}}џ|||џ|||џ}}}џ}}}џ|||џ|||џ{{{џxxxџџ•••џ222у??? '''```њЖЖЖю­­­§ЃЃЃџЄЄЄџЄЄЄџЃЃЃџЂЂЂџЁЁЁџЁЁЁџ   џžžžџ   џŸŸŸџƒƒƒџ\\\џ888џtttџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ(((џ,,,џUUUџ***џ...џ///џ+++щ... mmmuuuL<<<єџ џMMMџџ………џƒƒƒџ‚‚‚џџ„„„џŠŠŠџџ›››џИИИџОООќFFFс*** LLLuЅЅЅљЇЇЇџЂЂЂџЂЂЂџЁЁЁџ   џŸŸŸџžžžџџœœœџ›››џ›››џ–––џhhhџDDDџ@@@џ???џ‚‚‚џџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ'''џ...џiiiџ999џ>>>џ>>>џ>>>щ::: UUUчџџKKKџ™™™џ™™™џІІІџЕЕЕџОООџЪЪЪџЬЬЬџЩЩЩџЛЛЛџЊЊЊџЂЂЂќ‰‰‰йbbb ЅЅЅjЂЂЂџžžžџžžžџžžžџџœœœџšššџšššџ™™™џ˜˜˜џ™™™џ˜˜˜џlllџMMMџRRRџSSSџMMMџŽŽŽџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ'''џ111џџIIIџNNNџNNNџMMMщNNN  щџџ```џЇЇЇџЄЄЄџЁЁЁџœœœџџ{{{џjjjџbbbџYYYџRRRџMMMџ€€€лВВВ ŸŸŸ~œœœџšššџšššџ™™™џ———џ–––џ•••џ”””џ‘‘‘џ‰‰‰џџuuuџ___џ^^^џ___џ___џYYYџ™™™џџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ&&&џ444џ“““џXXXџ^^^џ^^^џ^^^щbbb  щџџkkkџdddџ\\\џWWWџTTTџTTTџVVVџVVVџVVVџVVVџVVVџTTTџVVVчUUU •••P–––џ•••џ”””џ’’’ї’’’нЋuyyyДnnnџkkkџhhhџhhhџkkkџkkkџkkkџkkkџeeeџЁЁЁџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ&&&џ555џЂЂЂџhhhџnnnџnnnџnnnщuuu  щџQQQџpppџWWWџYYYџXXXџWWWџVVVџUUUџTTTџSSSџRRRџQQQџQQQџMMMЛUUU™™™‘‘‘ŒŽŽŽŽ[ŒŒŒ(™™™ sss‡uuuџvvvџvvvџvvvџvvvџvvvџvvvџuuuџoooџІІІџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ&&&џ555џЌЌЌџzzzџ~~~џ~~~џ}}}щuuu ‘‘‘===ьcccџsssџWWWџUUUџTTTџSSSџSSSџRRRџPPPџPPPџOOOџNNNџMMMџKKKѕMMM;€€€џџ€€€џ€€€џџ|||џ{{{џџ†††џЛЛЛџ)))џ џџ,,,џAAAџSSSџ___џdddџcccџ\\\џQQQџDDDџ555џ$$$џ222џЕЕЕџ‹‹‹џŽŽŽџŽŽŽџŽŽŽщ‰‰‰ ДДДwwwыeeeџPPPџQQQџQQQџPPPџOOOџNNNџMMMџLLLџLLLџKKKџKKKџIIIчKKKN‰‰‰ˆˆˆџ‡‡‡џŠŠŠџџšššџ­­­џНННџЬЬЬџЭЭЭџЦЦЦџЕЕЕџЁЁЁџŠŠŠџ€€€џsssџjjjџmmmџmmmџfffџ]]]џRRRџCCCџ222џ%%%џ...џКККџ›››џžžžџžžžџщœœœ UUUKKK3NNNЗNNNџMMMџMMMџLLLџLLLџJJJџJJJџIIIџHHHџIIIўGGGЋJJJ)›››•ЅЅЅџЋЋЋџЏЏЏџВВВўБББџЉЉЉџšššџџpppџgggџoooџ„„„џџЉЉЉџДДДџСССџХХХџХХХџФФФџМММџМММџДДДџЉЉЉџЏЏЏџЋЋЋџаааџЉЉЉџЊЊЊџЋЋЋџЊЊЊщААА KKK^IIIнJJJџIIIџHHHџHHHџHHHџHHHѓHHHЉGGG@b‘‘‘пŠŠŠљyyyџoooџgggџbbbџbbbџcccџcccџcccџaaaџ^^^џZZZџVVVџYYYџ^^^џaaaџeeeџiiiџjjjџtttџxxxџxxxџuuuџ|||џАААќаааћРРРџЗЗЗџЖЖЖщААА DDDGGG•GGGјGGGѕGGGМGGGrFFF$jjj eee:eeeqcccЇbbbоaaaјaaaџ```џ___џ^^^џ]]]џ\\\џ[[[џZZZџYYYџWWWџUUUџTTTџRRRџQQQџOOOџMMMџLLLџLLLџIIIџIIIўsssљБББяЭЭЭіЧЧЧьФФФ JJJ0HHH#fff \\\,^^^Q[[[uYYY™WWWНXXXпVVVёUUUїTTT§SSSџSSSџRRRџQQQџPPPџPPPџOOOџMMMџMMMџLLLџLLLџJJJџCCCџIIIџzzzљЙЙЙЬюююLLL PPPRRR(PPPDB=94-**2CQK5    #/AZ///qGGG–:::žCCCВ>>>ГQQQУNNNУHHHФIIIЛAAAП;;;Ф888У000О"""В­œ›™ ДKпHв.“?9LEТFф1 šR# N4 3 †0 I" &? \,,,ŠTTTЛvvvеˆˆˆцŽŽŽџџ†††џ~~~џyyyџwwwџsssџmmmџgggџ```џYYYџRRRџKKKџCCCџ;;;џ,,,џџ5ќ [(џm3џt4џo.џ Wё Nн]+џ]/џc3џ^,џPј TџZ џYџ SџKјy-  #Jƒ666ИUUUыlllџџџœœœџЁЁЁџŸŸŸџ™™™џџŠŠŠџ†††џ€€€џyyyџrrrџkkkџcccџ\\\џTTTџMMMџCCCџ111џ=#џr5џi2џo1џ~9џj*џ]-џr>џ!yCџ'{Bџ#q;џ]/џV'џh+џn-џm+џh(џ`"џKэ _# - t(((У===џOOOџcccџzzzџŒŒŒџџЇЇЇџЊЊЊџЈЈЈџЁЁЁџ———џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџGGGџ888џL(џ*“Hџ$‹Eџƒ;џ„9џg0џsDџ,ŠRџ)‹Oџ.‰Jџ'{?џf1џg.џ }8џ!{3џg%џk)џt.џi'џ?ЦD|***ђ666џFFFџXXXџkkkџ€€€џ‘‘‘џ   џЉЉЉџЋЋЋџЉЉЉџЂЂЂџ———џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ<<<џ(5+џ‚7џ‹<џŒ=џ*™Eџx3џ$‚Jџ8—[џ8™Yџ:Wџ/‘Lџ =џ~:џ#ˆ>џ €5џj&џg$џ~4џx0џb"џh 5)))ь000џ<<<џJJJџZZZџlllџ€€€џџŸŸŸџЉЉЉџЋЋЋџЉЉЉџЃЃЃџ˜˜˜џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ>>>џ---џY)џ,ЌOџ/­Rџ*ЁHџ‰:џ‚?џ2’OџBЃZџE­_џ1™Nџ"‰?џ"Š>џ"Š>џ3џz/џl&џz2џz2џ [ їm$C...џ444џ>>>џKKKџZZZџkkkџџџŸŸŸџЈЈЈџЋЋЋџЉЉЉџЃЃЃџ™™™џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ>>>џ.0/џS&џ*ЇHџ5ВTџ4ЌRџŠ6џ#”EџŽBџ(ŸMџ!™Hџ‘Bџ‘Aџ#™Gџ+ Jџ%:џu)џy.џz2џ~7џ Rќ- О: ///ќ555џ>>>џJJJџYYYџjjjџ~~~џџžžžџЈЈЈџЋЋЋџЊЊЊџЄЄЄџ™™™џ‘‘‘џŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ@@@џ454џX*џ/­Kџ4ДTџ+Gџ Œ;џ%ЄKџ1ВXџ*ЈOџŸHџ$ЄMџ*ЇPџ0ЌRџ4АTџƒ1џŠ7џ!<џy2џw1џZ#џe(џ YЭ$...Я555џ>>>џJJJџYYYџjjjџ}}}џŽŽŽџžžžџЈЈЈџЋЋЋџЊЊЊџЅЅЅџšššџ‘‘‘џŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџBBBџ999џ*=.џ’:џ$ЁEџŒ<џ€5џ žBџ$ЉJџ ЈDџЁ>џ™7џ%ЃAџ>ИVџ<ЎSџq&џ‚6џ!@џ ŒAџp,џ^)џt0џ}3џ aa...™444џ>>>џJJJџYYYџiiiџ|||џŽŽŽџџЇЇЇџЊЊЊџЅЅЅџžžžџџšššџ”””џ———џ   џ™™™џ“““џџxxxџhhhџaaaџSSSџ???џ:::џ666џ"_1џ#N.џa-џx1џ9џ+ИPџ)ЖIџ Ћ?џЄ;џЃ>џ&ЇGџ)ЇKџˆ:џi'џ(Aџx4џh*џ"m3џ#‚:џx1џXB+++c333џ>>>џJJJџYYYџiiiџzzzџ‰‰‰џšššџЅЅЅџЃЃЃџџ———џˆˆˆџƒƒƒџ€€€џvvvџrrrџdddџbbbџcccџdddџnnnџiiiџfffџnnnџgggџ___џWWWџCCCџ555џ,Q5џЋ?џ+РOџ%ЗGџ#ЖGџ&ЗKџ"­Fџ!ЃCџ+ІKџ&’@џt0џ*„Dџq8џe(џ#r6џ'†Aџm-ь0----333џ>>>џIIIџ\\\џzzzџ‚‚‚џzzzџhhhџ]]]џcccџzzzџœœœџЎЎЎџЏЏЏџЈЈЈџЦЦЦџгггџЗЗЗџАААџЇЇЇџЅЅЅџџŠŠŠџxxxџlllџ```џџ@@@џ>>>џHHHџMPMџЅ=џ(СKџ(РLџ-СQџ/ТTџ,ЛRџ*БNџ,­Qџ'ЃMџ‹Bџ!x<џp0џm/џ(@џ)‹Fџ'k<њFFFМQ.111і@@@џeeeџlllџ___џ]]]џžžžџИИИџЭЭЭџиииџрррџцццџцццџхххџоооџЪЪЪџнннџШШШџОООџДДДџЎЎЎџЉЉЉџІІІџ›››џ———џ‰‰‰џ–––џŠŠŠџtttџ___џHHHџ+P3џ#“<џ"НGџ*СMџ)ПOџ)КPџ*ЕQџ*АQџ$ІJџ@џs+џ%z9џ,ˆCџ,Hџ‚>џ>qMџtttџgggёPPPОV0444Цcccџ^^^џWWWџŠŠŠџІІІџ˜˜˜џЮЮЮџиииџуууџыыыџ№№№џюююџьььџчччџЭЭЭџфффџаааџЦЦЦџОООџИИИџГГГџЋЋЋџ­­­џЅЅЅџџ———џšššџ–––џџџhhhџBNEџ<%џ(ƒ<џ&‹>џ%ИKџ$ЏIџ"ЉGџ€7џCfKџ>qKџ"ƒ:џD‚Tџ5Iџ>zOџ{|џџ|||џџuuuѓPPPК]1  QQQЖ```џbbbџ„„„џ™™™џАААџ™™™џбббџрррџъъъџяяяџђђђџюююџшшшџпппџСССџлллџаааџЪЪЪџЦЦЦџТТТџРРРџВВВџЎЎЎџЋЋЋџ™™™џџЁЁЁџœœœџ˜˜˜џ‘‘‘џ‹‹‹џ‡‡‡џbbbџ џ.l<џБAџ=џ7GџhhhџSSSџcccџuyvџ›››џ‹‹‹џ‡‡‡џ‡‡‡џ†††џƒƒƒџ•••џŠŠŠџŠŠŠџ………і[[[Рe93DV dZ9*)'JJJŒVVVџrrrџ†††џ›››џБББџ™™™џгггџтттџьььџяяяџчччџЯЯЯџЗЗЗџЈЈЈџџЕЕЕџШШШџЭЭЭџЩЩЩџЦЦЦџФФФџНННџЗЗЗџАААџœœœџžžžџЃЃЃџџџџ›››џ———џ‰‰‰џ!!!џ???џ]eџkznџ{{{џ}}}џjjjџ‡‡‡џyyyџjjjџ{{{џžžžџŒŒŒџˆˆˆџˆˆˆџ˜˜˜џ’’’џџџŽŽŽџŠŠŠї[[[Я“ ’AУh-ёq1§ Yс( ‘ m) †h@??? GGGяrrrџŒŒŒџЁЁЁџДДДџ™™™џзззџфффџэээџъъъџЫЫЫџџiiiџdeeџjkkџ—˜˜џЙЙЙџЮЮЮџкккџкккџгггџЯЯЯџШШШџЗЗЗџœœœџŸŸŸџЁЁЁџ   џ™™™џ›››џœœœџ–––џŠŠŠџ(((џAAAџˆˆˆџ•••џ‡‡‡џ………џlllџ………џ~~~џ{{{џyyyџqqqџ‚‚‚џЂЂЂџ’’’џšššџ‹‹‹џ‘‘‘џ’’’џ’’’џ“““џ|||џ]`^§Y*ј|<џ'‰Eџ-–Jџ*’Bџt+ў \$эz6џw3§h%єK˜ KKKtttџ“““џ­­­џОООџ›››џхххџлллџжжжџЪЪЪџ™™™џ•˜˜џБЗЖџЃЇЇџ…„џПХФџmmmџЂЂЂџ’’’џ~~~џ€€€џkkkџxxxџyyyџƒƒƒџ„„„џЌЌЌџБББџŸŸŸџ˜˜˜џšššџ’’’џ†††џ:::џ^^^џGGGџXXXџ„„„џЁЁЁџmmmџŠŠŠџ†††џ„„„џ………џ‰‰‰џ………џ}}}џˆˆˆџ   џЄЄЄџ“““џџ’’’џ’’’џ€€€џOgVџ†@џ-Kџ/™MџAЎXџ3œIџ3џp,џ,“Iџ3ЂOџ-—Cџ|.џY}}}ўœœœџТТТџЇЇЇџjjjџ†††џ­­­џВВВџзззџЉЉЉџТШЧџ.//џџ џЗМЛџ,,,џйййџбббџЅЅЅџЫЫЫџПППџНННџЏЏЏџ–––џ„„„џoooџVVVџ```џ‹‹‹џЄЄЄџџ€€€џ888џcccџZZZџ‰‰‰џqqqџ```џ___џЈЈЈџ”””џ‘‘‘џ“““џ“““џ’’’џ•••џ”””џŽŽŽџ–––џ­­­џАААџœœœџ˜˜˜џŠŠŠџptqџ4џ%‘Bџ)—Eџ6ЉRџ5ЈNџ&‘>џu-џ6ЅRџKКaџ3џ$Œ<џ{1џL јxxxџlllџžžžџЩЩЩџиииџпппџТТТџхххџЋЋЋџТШЧџ333џ###џџЗМЛџ---џкккџдддџЇЇЇџЪЪЪџПППџИИИџДДДџБББџЊЊЊџЄЄЄџŸŸŸџ“““џZZZџ\\\џkkkџ‡‡‡џ666џeeeџ[[[џŒŒŒџŒŒŒџŽŽŽџ‡‡‡џoooџџБББџЌЌЌџžžžџ›››џœœœџžžžџŸŸŸџ   џџŸŸŸџЎЎЎџЗЗЗџŸŸŸџŠŠŠџ)t<џ$š@џ3ЌMџ6ЎPџ1ЄLџ'Aџx0џ+Gџ;ВXџ1ЃKџ#Œ>џk(оeeeћџМММџХХХџЭЭЭџвввџмммџТТТџцццџЌЌЌџТШЧџCCCџ333џ###џЗМЛџ...џиииџаааџЅЅЅџШШШџРРРџЙЙЙџДДДџЏЏЏџ­­­џІІІџžžžџ———џkkkџžžžџyyyџSSSџ;;;џjjjџ[[[џџџ’’’џ”””џ™™™џ™™™џ~~~џџАААџИИИџŸŸŸџЁЁЁџЉЉЉџІІІџЈЈЈџЈЈЈџЅЅЅџ   џБББџŸŸŸџp{rџ'š@џ;ЗTџ8ЏQџ2ЁMџ(Dџ†5џ9ДSџ4ЋPџ,–Fџ&ŽAџ b ‡ˆˆˆчЈЈЈџЛЛЛџХХХџЩЩЩџЮЮЮџмммџТТТџщщщџЕЕЕџТШЧџQQQџCCCџ444џЛСРџ///џбббџЮЮЮџІІІџТТТџНННџИИИџДДДџЏЏЏџЌЌЌџІІІџŸŸŸџ›››џlllџЁЁЁџ”””џxxxџ&&&џkkkџjjjџ’’’џ“““џ———џ™™™џžžžџџџЅЅЅџџŒŒŒџ•••џЧЧЧџЏЏЏџЅЅЅџЊЊЊџЌЌЌџ­­­џЂЂЂџЪЪЪџ   џŠ‹џ,ŽBџ9ЏSџ<ЎVџ5ЂSџ#‰Aџ Ž;џ=ЗVџ3ЅOџ4 Pџ#ŠAџb![œœœйЎЎЎџПППџЦЦЦџЩЩЩџбббџпппџУУУџяяяџЮЮЮџЙПОџ_``џQQQџbddџЇЌЋџ000џТТТџФФФџЈЈЈџСССџЛЛЛџЗЗЗџЕЕЕџЉЉЉџЈЈЈџЇЇЇџЁЁЁџžžžџlllџŸŸŸџ’’’џ|||ў000џYYYџUUUџxxxџЇЇЇџ   џЂЂЂџЃЃЃџЅЅЅџ–––џІІІџЃЃЃџІІІџЂЂЂџ———џЉЉЉџЫЫЫџВВВџ­­­џЏЏЏџЃЃЃџеееџАААџЉЉЉџ‘‘‘џ/Eџ.žJџ"Š?џu+џ)ЁEџ;ЏUџ1ŸLџ)“Gџw3џf#9ЊЊЊШЕЕЕџРРРџЪЪЪџЯЯЯџеееџсссџФФФџяяяџрррџЋЎЎџ­ВБџЅЊЉџ—››џ"##џDDDџЗЗЗџВВВџ˜˜˜џЏЏЏџГГГџЇЇЇџВВВџЛЛЛџЙЙЙџЈЈЈџІІІџžžžџmmmџžžžџџzzzў666џ{{{џџ‰‰‰џgggџpppџЃЃЃџБББџЉЉЉџœœœџЇЇЇџЇЇЇџДДДџАААџЃЃЃџЁЁЁџ   џІІІџШШШџТТТџЃЃЃџкккџБББџЏЏЏџЎЎЎџžЇ џ\ˆgџ;bDџˆ7џ’7џ#–=џ$’>џƒ5џv/юЇЇЇЛГГГџРРРџЪЪЪџИИИџЋЋЋџІІІџЋЋЋџЧЧЧџйййџЪЪЪџ(((џџ џJJJџИИИџЛЛЛџЎЎЎџІІІџЊЊЊџЏЏЏџ‘‘‘џ’’’џџwwwџ~~~џŒŒŒџ”””џiiiџ™™™џˆˆˆџpppў;;;џ„„„џ———џ˜˜˜џšššџ˜˜˜џyyyџsssџ   џЌЌЌџЃЃЃџ­­­џЋЋЋџЈЈЈџЈЈЈџЈЈЈџЊЊЊџЙЙЙџЈЈЈџЈЈЈџЈЈЈџрррџДДДџВВВџВВВџВВВџЅЅЅџsssџ'†=џ7ВQџ;ВTџ3ЂMџ,–Iџt-ПЈЈЈБЋЋЋџyyyџiiiџœœœџНННџйййџыыыџ№№№џёёёџиииџпппџДДДџЭЭЭџеееџЪЪЪџФФФџМММџЛЛЛџДДДџЕЕЕџ›››џЙЙЙџ­­­џІІІџšššџƒƒƒџpppџJJJџbbbџ………џkkkў???џ………џ˜˜˜џ›››џšššџ‘‘‘џ€€€џtttџlllџuuuџџТТТџЕЕЕџЋЋЋџДДДџВВВџГГГџЛЛЛџБББџЎЎЎџ­­­џЋЋЋџИИИџЯЯЯџНННџДДДџЏЏЏџ‡‰ˆџA†Qџ1ЈLџ>БXџ7ЂSџ'Eџ i&Ѕиeeeџ‰‰‰џУУУџЯЯЯџйййџрррџчччџюююџђђђџлллџуууџкккџдддџдддџаааџЬЬЬџУУУџРРРџЛЛЛџГГГџ”””џЙЙЙџЉЉЉџЇЇЇџŸŸŸџ”””џˆˆˆџ~~~џlllџOOOџ\\\ў&&&џ€€€џЈЈЈџџšššџ‡‡‡џMMMџДЙЙџ—ššџ‡‰ˆџ†††џ‚‚‚џџЕЕЕџРРРџЉЉЉџЌЌЌџЙЙЙџАААџДДДџЙЙЙџЖЖЖџДДДџ   џБББџХХХџЦЦЦџ™™™џЂЂЂџO_џ*œFџ&Cїv,Ш g%/ŠŠŠПЂЂЂџ‘‘‘џТТТџЬЬЬџеееџтттџчччџэээџюююџнннџьььџхххџнннџжжжџЭЭЭџЩЩЩџНННџЕЕЕџМММџЕЕЕџ———џЖЖЖџІІІџЅЅЅџ   џ‘‘‘џƒƒƒџxxxџrrrџhhhџPPPў```џeeeџXXXџwwwџ­­­џџџЗМЛџ-..џmooџБЖЕџЂЅЄџšššџšššџŽŽŽџЈЈЈџЛЛЛџЏЏЏџЕЕЕџГГГџЕЕЕџИИИџЖЖЖџІІІџеееџІІІџœœœџ”””џРРРџЎАЎџ~Ёˆљ{+•••ЎЁЁЁџ———џСССџЫЫЫџбббџоооџцццџыыыџэээџмммџяяяџхххџнннџмммџЭЭЭџФФФџОООџИИИџТТТџЖЖЖџšššџБББџЇЇЇџЅЅЅџЂЂЂџџ„„„џ|||џvvvџhhhџSSSўgggџ“““џЅЅЅџ–––џkkkџ^^^џџЗМЛџ(((џџ џТШЧџЈЈЈџЋЋЋџЃЃЃџ•••џ•••џŸŸŸџРРРџСССџГГГџЖЖЖџЙЙЙџЇЇЇџйййџЗЗЗџГГГџЉЉЉџџ˜˜˜џВВВљ‰‰‰ЉšššџŽŽŽџСССџЩЩЩџбббџеееџхххџ№№№џюююџйййџхххџмммџбббџЮЮЮџЛЛЛџЖЖЖџДДДџБББџЗЗЗџШШШџ’’’џМММџБББџЋЋЋџŸŸŸџ‘‘‘џŠŠŠџƒƒƒџ}}}џkkkџRRRўlllџ˜˜˜џЊЊЊџ­­­џЎЎЎџ–––џ џЗММџ888џ+++џџТШЧџЋЋЋџДДДџБББџЂЂЂџ­­­џЎЎЎџЂЂЂџЅЅЅџМММџбббџРРРџЈЈЈџйййџКККџЕЕЕџ­­­џБББџЋЋЋџšššј|||Є•••џ“““џМММџСССџАААџЖЖЖџИИИџНННџбббџйййџвввџЫЫЫџМММџФФФџОООџАААџЎЎЎџІІІџ•••џŽŽŽџŒŒŒџyyyџ{{{џ†††џ“““џ–––џšššџŽŽŽџ€€€џmmmџTTT§lllџ™™™џЋЋЋџЎЎЎџЎЎЎџœœœџџЗНМџGGGџ;;;џ...џТШЧџУУУџЛЛЛџГГГџЈЈЈџМММџЕЕЕџГГГџЏЏЏџЎЎЎџІІІџЙЙЙџЎЎЎџдддџЛЛЛџЗЗЗџЗЗЗџЏЏЏџБББџИИИѕooo™џuuuџqqqџyyyџЎЎЎџФФФџнннџчччџыыыџшшшџиииџгггџИИИџвввџЮЮЮџШШШџРРРџИИИџИИИџЗЗЗџВВВџЈЈЈџ•••џџ………џxxxџjjjџUUUџoooџyyyџGGGўgggџЉЉЉџАААџБББџВВВџЅЅЅџџДКЙџZZZџJJJџ???џТШЧџџЇЇЇџЪЪЪџЎЎЎџРРРџЛЛЛџКККџГГГџšššџ”””џ›››џЂЂЂџІІІџПППџЭЭЭџКККџЗЗЗџИИИџИИИѓuuuВ^^^џ………џЖЖЖџœœœџбббџлллџпппџрррџзззџЦЦЦџБББџŸŸŸџŽŽŽџВВВџТТТџФФФџСССџКККџЖЖЖџЙЙЙџБББџЌЌЌџџœœœџ–––џ‹‹‹џ‹‹‹џџbbbџBBBџ^^^§TTTџQQQџyyyџЏЏЏџЛЛЛџВВВџ&&&џNPPџšžžџZ[[џUVVџОУТџВВВџЁЁЁџЅЅЅџšššџМММџгггџУУУџЈЈЈџ^^^џЖЛЛџŸЃЂџ–˜˜џ   џЉЉЉџžžžџЄЄЄџТТТџРРРџЛЛЛђaaaџ   џЖЖЖџ———џдддџнннџоооџзззџИИИџ†††џcccџ___џhiiџ‘’’џВВВџМММџЗЗЗџКККџЗЗЗџДДДџВВВџЏЏЏџ™™™џœœœџ”””џ‰‰‰џ„„„џ~~~џ{{{џpppџWWWќ{{{џЄЄЄџnnnџsssџhhhџ———џmmmџџ788џ™žџЛСРџЈЋЋџЗЗЗџЈЈЈџЗЗЗџЕЕЕџАААџІІІџВВВџБББџџЗМЛџ-..џnqpџДЙИџЎААџЗЗЗџЗЗЗџƒƒƒџ———џЎЎЎјbbbt€€€џ˜˜˜џАААџ———џЮЮЮџиииџмммџЮЮЮџŸŸŸџ”˜—џВЗЖџЃЇЇџ…„џПХФџxxxџНННџБББџЏЏЏџОООџЗЗЗџЕЕЕџИИИџœœœџ–––џŽŽŽџƒƒƒџ€€€џ€€€џ{{{џwwwџ___ћџЋЋЋџrrrџКККџЕЕЕџšššџxxxџ{{{џYYYџџ$$$џВВВџДДДџЇЇЇџИИИџГГГџУУУџОООџИИИџ———џџЗМЛџ(((џџ џТШЧџВВВџЙЙЙџŒŒŒџЯЯЯџЏЏЏі___cџ———џЊЊЊџ‘‘‘џЙЙЙџКККџИИИџВВВџ………џТШЧџ.//џџ џЗМЛџ&&&џЙЙЙџЂЂЂџ———џ›››џ“““џ„„„џzzzџhhhџqqqџŒŒŒџŒŒŒџџџ~~~џyyyџaaaћ€€€џ­­­џtttџНННџЕЕЕџЕЕЕџИИИџЛЛЛџšššџ|||џЅЅЅџЬЬЬџХХХџЇЇЇџРРРџДДДџГГГџФФФџРРРџЁЁЁџџЗММџ888џ+++џџТШЧџЕЕЕџИИИџџбббџРРРѓ^^^Q‡‡‡џŽŽŽџwwwџ‚‚‚џ   џЛЛЛџИИИџдддџ™™™џТШЧџ333џ###џџЗМЛџ)))џГГГџЌЌЌџЉЉЉџЌЌЌџЈЈЈџžžžџџ–––џџsssџlllџYYYџXXXџwwwџ€€€џVVVћxxxџЄЄЄџrrrџМММџЛЛЛџКККџЛЛЛџСССџФФФџŠŠŠџвввџšššџ”””џџдддџТТТџПППџРРРџТТТџЇЇЇџџЗНМџGGGџ;;;џ...џТШЧџŸŸŸџХХХџ“““џгггџТТТђoooPUUUџiiiџ™™™џЗЗЗџОООџЩЩЩџЛЛЛџкккџЁЁЁџТШЧџCCCџ333џ###џЗМЛџ(((џОООџЕЕЕџЃЃЃџЎЎЎџІІІџ   џџ“““џŠŠŠџ|||џqqqџrrrџ]]]џXXXџEEEџ===ўHHHџ{{{џ]]]џЇЇЇџДДДџМММџТТТџЧЧЧџЧЧЧџ‹‹‹џрррџТТТџФФФџЕЕЕџЁЁЁџЈЈЈџЫЫЫџжжжџСССџБББџџДКЙџZZZџJJJџ???џТШЧџВВВџџ‚‚‚џБББџЪЪЪѕWWW kkkџџЉЉЉџЏЏЏџКККџЮЮЮџМММџоооџАААџТШЧџQQQџCCCџ444џЛСРџ+++џРРРџЛЛЛџЄЄЄџГГГџЇЇЇџ   џ›››џŽŽŽџџrrrџjjjџlllџ\\\џ€€€џkkkџ џџџ567џ]]]џ‡‡‡џ›››џЎЎЎџМММџУУУџŠŠŠџсссџТТТџФФФџТТТџТТТџТТТџџГГГџЙЙЙџЭЭЭџ888џNPPџšžžџZ[[џUVVџОУТџЖЖЖџЅЅЅџСССџЎЎЎџІІІїHHHmmmџ‹‹‹џЄЄЄџЗЗЗџТТТџЪЪЪџНННџтттџШШШџЙОНџ_``џQQQџbddџЇЌЋџ...џЦЦЦџПППџЁЁЁџВВВџЈЈЈџЁЁЁџЁЁЁџџ|||џkkkџdddџhhhџYYYџџpppџџџџџ џџHHIџhiiџŽŽŽџЁЁЁџ{{{џвввџРРРџХХХџУУУџХХХџУУУџЁЁЁџхххџХХХџЕЕЕџ”””џџ788џ™žџЛСРџЉ­ЌџРРРџЇЇЇџЧЧЧџЩЩЩџЪЪЪёџџџmmmџ‹‹‹џІІІџЙЙЙџШШШџеееџЛЛЛџпппџдддџЉЌЋџ­ВБџЅЊЉџ—››џ"##џCCCџŸŸŸџ˜˜˜џ‹‹‹џџ™™™џŸŸŸџЅЅЅџ   џ–––џyyyџdddџiiiџWWWџџooo§џџџџ џџџџ–™šџY[[џSSSџœœœџ›››џЏЏЏџМММџУУУџТТТџЂЂЂџцццџЫЫЫџЬЬЬџЪЪЪџЖЖЖџVVVџџ&&&џЦЦЦџШШШџЈЈЈџЬЬЬџЬЬЬџЪЪЪёnnn§’’’џБББџžžžџšššџ˜˜˜џЏЏЏџЧЧЧџзззџШШШџ)))џџ џMMMџШШШџЩЩЩџЖЖЖџЋЋЋџЃЃЃџ™™™џ}}}џџsssџYYYџLLLџ___џkkkџXXXџ‚‚‚џnnnљџџџџ џџџџЇЋЌџ445џџ566џUVVџsttџ‘‘‘џЄЄЄџДДДџœœœџтттџЫЫЫџЭЭЭџЬЬЬџЪЪЪџЦЦЦџЛЛЛџЕЕЕџІІІџЋЋЋџ   џеееџЭЭЭџЪЪЪёћ\\\џ```џ˜˜˜џРРРџмммџсссџуууџцццџжжжџыыыџПППџпппџнннџгггџЪЪЪџТТТџИИИџБББџЇЇЇџ‡‡‡џЂЂЂџ€€€џoooџgggџ___џXXXџ===џBBBџlllў444џ+++џџџ џџџџЇЋЌџ445џџ"""џ&&&џ)))џBBBџ^^_џƒƒƒџxxxџРРРџЛЛЛџУУУџЧЧЧџЪЪЪџЩЩЩџМММџШШШџЫЫЫџЩЩЩџЎЎЎџ™™™џЊЊЊџЪЪЪѕZZZњvvvџБББџУУУџгггџнннџфффџцццџхххџзззџщщщџуууџпппџлллџгггџЪЪЪџСССџИИИџАААџЅЅЅџƒƒƒџœœœџyyyџkkkџhhhџmmmџuuuџ{{{џhhhџIIIџ џ џ333џMMNџCCCџ)))џџџЇЋЌџ445џџ"""џ&&&џ)))џ---џ111џ˜›œџQRSџllmџџ–––џЇЇЇџЕЕЕџРРРџИИИџЬЬЬџЮЮЮџаааџбббџбббџТТТџЏЏЏєrrrщџДДДџХХХџгггџрррџчччџъъъџшшшџжжжџцццџрррџмммџеееџаааџШШШџРРРџЗЗЗџАААџІІІџџœœœџxxxџmmmџmmmџsssџ}}}џџ‚‚‚џdddџџџџџџ<<<џbccџOOOџЎБВџ445џџ"""џ&&&џ)))џ---џ111џšžџ?@@џ===џ@@@џYZZџklmџ~~~џ———џŸŸŸџОООџШШШџЮЮЮџбббџвввџвввџввв№xxxмџЕЕЕџШШШџеееџрррџцццџхххџнннџХХХџЮЮЮџХХХџЛЛЛџЗЗЗџВВВџЌЌЌџЅЅЅџŸŸŸџžžžџ˜˜˜џwwwџ”””џyyyџrrrџuuuџ|||џ„„„џ‡‡‡џ†††џvvvь@AAы%%%џ###џ112џGHHџ\^_џruuџtvwџ~€€џrssџ\]]џLLLџ&&&џ)))џ---џ111џšžџ?@@џ===џ@@@џDDDџHHHџLLLџcccџyyyџˆˆˆџ   џГГГџТТТџЫЫЫџаааџввв№}}}Я‚‚‚џЕЕЕџПППџСССџТТТџОООџЕЕЕџЊЊЊџ’’’џ’’’џ………џџzzzџsssџmmmџkkkџkkkџmmmџmmmџYYYџtttџeeeџfffџnnnџyyyџ„„„џˆˆˆџ‰‰‰џ‚‚‚Лiii•——^ŒЙ`abљGHHџ333џ333џ333џ333џ333џJJKџrstџiijџXXXџ333џšžџ?@@џ===џ@@@џDDDџHHHџKKKџOOOџ“–—џXXXџijjџyzzџџЄЄЄџЖЖЖџЩЩЩёРxxxџџ–––џŠŠŠџ~~~џƒƒƒџ‘‘‘џ•••џџџџџ|||џvvvџnnnџeeeџ]]]џ[[[џWWWџKKKџJJJџDDDџ@@@џNNNџ\\\џkkkџyyyџ‚‚‚џЏloo|abdбMNNќEEEџEEEџEEEџEEEџEEEџEEEџ__`џ‚џЎББџeffџBBBџ@@@џDDDџHHHџKKKџOOOџ“–—џUUUџXXXџ[[[џbbbџprrџ|}}џЇЇЇѓnnnЛXXXџiiiџsssџ‡‡‡џџ™™™џžžžџџ˜˜˜џ“““џџ‹‹‹џ………џ~~~џvvvџmmmџeeeџ[[[џSSSџJJJџBBBџ<<<џ555џ333џ<<<џAAAџLLLџcccџrrrЋy||\qqrС|~€щˆŠ‹џ‡‰ŠџˆŠ‹џ~€€џtuuџfggџ```џ‚‚џ€џjjjџPPPџKKKџOOOџ“–—џUUUџXXXџ[[[џ^^^џ```џbbbџiijџfffYYYПPPPџ[[[џqqqџ‡‡‡џ———џЁЁЁџЅЅЅџЁЁЁџ›››џ•••џ‘‘‘џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ222џ111џ000џ???џQQQЛ……Š;|ИttuяgggџgggџgggџgggџgggџgggџlllџŠ‹‹џ‡ˆˆџvvvџ—š›џUUUџXXXџ[[[џ^^^џ```џbbbџdddџfff№(((K666№IIIџ```џvvvџ‹‹‹џšššџЃЃЃџЅЅЅџ   џ˜˜˜џ’’’џџŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ666џFFFіNNNXŒ’’(‰ŠŠœ‚ƒƒчyyyџyyyџ‚џŠ‹Œџ‘“”џ˜›œџ ЁџІЈЉџŒŒџџfffџ^^^џ```џbbbџdddџfff№'''-000љ999џKKKџ```џuuuџˆˆˆџ•••џœœœћс›››й———ХšššДŒŒŒџŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ:::џOOOџ___љQQQ5ЉЉЉ ІЉ­NЃЇЉЄ–——єџŠŠ‹џ………џ………џ………џ†††џ——˜џ”••џ‰‰‰џnnnџdddџfff№,,,Н333џ999џJJJџ___џ}}}џ’’’тДДДыПППџПППџПППџПППџЛЛЛџˆˆˆџŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ;;;џSSSџeeeџ^^^Ә›n˜˜™Ч”””ћ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ’’’џœџ›››іjjjи---№333џ999џHHHџ]]]џ†††џLRSџquvџЅІІџ­­­џ­­­џ­­­џЊЊЊџ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ222џ„„„ћ___ыfffџcccџŸŸЂHžŸŸЛšœœшš››щšššЮ›››Љ˜˜˜h™™™?———333ќ333џ999џHHHџ\\\џџHNPџAHJџFMOџ“““џ———џ———џ•••џ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ222џ‘‘‘џ———џ}}}џaaa§444џ333џ999џGGGџ[[[џ”””џHNPџAHJџAHJџ|}}џ€€€џ€€€џџ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ:::џ%%%џџpppџ 222§333џ888џFFFџZZZџ”””џHNPџAHJџAHJџfffџhhhџhhhџiiiџ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ555џџџџrrrї...ё333џ888џFFFџ[[[џ•••џHNPџAHJџAHJџQQRџRRRџRRRџTTTџˆˆˆџŒŒŒџ„„„џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ777џ///џ---џ---џ}}}ю...№333џ999џJJJџbbbџџJPRџAHJџAHJџBCCџ333џ888џџТТТџШШШџФФФџСССџОООџЬЬЬџЧЧЧџЙЙЙџЗЗЗџ–––џŒŒŒџ___џIIIџ333џ333џ444џ:::џBBBџBBBџBBBџ‚‚‚№...№333џ:::џOOOџrrrџМММџ^bdџAHJџAHJџ888нџџ999џcccџ’’’џŸŸŸџџ›››џšššџ˜˜˜џ™™™џЈЈЈџЅЅЅџЎЎЎџИИИџЕЕЕџ­­­џ–––џeeeџBBBџVVVџWWWџWWWџ„„„я...№222џEEEџЉЉЉљЩЩЩќОООџШШШў‘џDKMџJJJнџџ888џWWWџfffџuuuџ‚‚‚џyyyџyyyўzzz№………ѕ‹‹‹џˆˆˆџ†††џ„„„џџџ‚‚‚џ‘‘‘џџjjjџlllџlllџ€€€я000№———єРРРњЋЋЋџЄЄЄџЂЂЂџЁЁЁџДДДџГГДџoopуџџ888џWWWџfffџ^^^џFFFџ,,,џ)))џџ№ B}}}xzzzКtttўQQQџyyyє~~~џ~~~џ~~~џ~~~џ~~~џ|||юџџџŒŒŒсЃЃЃџЁЁЁџŸŸŸџџ›››џšššџˆˆˆџWWWџvvvнџџ888џWWWџfffџ^^^џFFFџ,,,џ===џ)))џ)))№№џ’’’ѓŽŽŽџŽŽŽџ———џЁЁЁџЌЌЌџ   ьџџџœœœэ›››џšššџ˜˜˜џ–––џ”””џ‰‰‰џ\\\џWWWџˆˆˆоџџ888џWWWџfffџ^^^џFFFџ,,,џNNNџGGGџGGG№№џєї———ќŠŠŠџsssџWWWџfffџ•••К“““ѓ‘‘‘КŽŽŽ„vvvџnnnџlllџlllџlllџšššпџџ888џWWWџfffџ^^^џFFFџ,,,џ^^^џfffџfff№№BBBџ]]]џWWWџUUUџSSSџQQQџPPPџNNNо””” ~~~џ~~~џ~~~џ~~~џ~~~џІІІпџџ888џWWWџfffџ^^^џFFFџ,,,џdddџ………џ„„„№]]]хbbbљQQQџPPPџNNNџMMMџKKKџIIIфGGG'ŽŽŽџ———џІІІџАААџГГГђ­­­яЁЁЁѓ“““ј‘‘‘џ™™™џŽŽŽџ}}}џiiiџUUUџrrrџЃЃЃџЂЂЂ№UUU LLL™KKKџJJJџIIIџHHHэGGG„??? ВВВ†•••Єtttвjjjџgggџeeeџcccџaaaџ^^^џ\\\џpppџxxxџwwwџuuuџњЏЏЏљЛЛЛ№HHH?GGG™HHHTUUUUUU]]]9[[[oYYY™WWWБWWWЬUUUЬRRRоQQQџPPPџNNNџMMMџVVVъ”””ЩЦЦЦ џў`џџџџўџџџ№џџџРџџџџ?џџ?џџ?џџ?џџ?џџ?џџ€џџ€џџ€џџ€aџРРРРр№№№№№№№№№№№№№№№№№№№№№№№№јјјјјјјрјќ№џ€рџ№рџџрџџррџџџџрџџџџрџџџџрџџџџрџџџџрџџџџрџџџџрџџџџР№џџџџР№џџџџр№џџџџю№џџџџў№џџџџўќ?џџџџџРџџџџџџџџџџџџџџ(0` €%#C _%%%t***„222“333000Ђ)))™ ~lZ m >Г3• < 71Ћ3­\ira>###ˆIIIЛ|||ы™™™џ   џ™™™џ’’’џ‹‹‹џ‚‚‚џxxxџkkkџ___џSRSџDACџ&@.џa-џr3џy2џ Pєo7ѕ#y=џf2џ Nџf'џi'џ`!џ" œ 4КEEEљmmmџŽŽŽџЄЄЄџ­­­џЊЊЊџџ‘‘‘џ‰‰‰џџtttџiiiџ]]]џRRRџGAEџ&`7џ,žNџv1џo1џ(Nџ5šZџ/ŒJџm4џl0џ z5џg%џv.џl)§c'''ч@@@џRRRџlllџ‰‰‰џŸŸŸџЊЊЊџЉЉЉџџџˆˆˆџџtttџhhhџ]]]џRRRџHDGџ5E9џŽ>џ)ЅKџ!Œ=џ"‚Eџ2‹MџLДbџ ƒ<џ…<џ{3џq)џm(џz0џ,•666џ===џPPPџjjjџ‡‡‡џžžžџЊЊЊџЊЊЊџџ‘‘‘џˆˆˆџџtttџhhhџ]]]џRRRџHFGџ697џ$<џ8ЛXџ+žGџ Cџ(šKџ—Hџ“Dџ"—Eџ&•Bџx+џv-џr,џGб +444џ===џPPPџiiiџ†††џžžžџЊЊЊџЉЉЉџџŽŽŽџ„„„џ{{{џoooџdddџYYYџNNNџECDџ676џ,•Bџ.ЛQџ%šBџ'ЅKџ&ЋLџž?џ% DџAО]џ*šEџ1џ"?џt1џ"~6џa&Ц333ъ===џOOOџfffџƒƒƒџŸŸŸџБББџГГГџЉЉЉџЁЁЁџŸŸŸџšššџ”””џ‡‡‡џyyyџfffџWWWџJFIџ1X:џ$e5џj*џ–;џ/СTџ"Ќ@џž8џ"ЂBџ"“@џy1џ9џq1џ,“Cџw/м000И;;;џNNNџuuuџџџІІІџЈЈЈџЅЅЅџŸŸŸџЃЃЃџЇЇЇџџ‰‰‰џ………џ~~~џuuuџzzzџrnqџQFNџ=OAџ#ЗGџ&ХKџ+ПNџ6Ч\џЂAџ,ЇMџ$ŒAџ!r9џq0џ-›Hџ_,Ш---’JJJџuuuџ‚‚‚џ‚‚‚џЅЅЅџСССџлллџхххџфффџжжжџдддџСССџГГГџЉЉЉџЁЁЁџ•••џџџiiiџ]Y\џ.n<џ#ЊCџ1ЭUџ)СOџ.КRџ#ЏKџ$›Hџ4џ2ŸKџ!”AџLuXџ]V\к***y333gsssџuuuџ‘‘‘џ‹‹‹џЬЬЬџхххџ№№№џѓѓѓџђђђџрррџлллџЬЬЬџСССџКККџЎЎЎџЊЊЊџšššџЂЂЂџšššџŒŒŒџxtwџGPIџ&P0џ.ИQџЕBџ>ˆPџTaWџW‹dџy™€џf„nџ€‚€џ‡†‡џŽŽŽџkkkс---| HHH1iiiџyyyџŸŸŸџŽŽŽџЬЬЬџщщщџєєєџёё№џссрџЦЦЦџЮЮЮџеееџЭЭЭџЫЫЫџПППџЕЕЕџЅЅЅџЈЈЈџœœœџ›››џџŒŽџ.)-џS€^џe’pџ|~џ{vyџ€|џ}w{џ‹џџ‰‰‰џџ•••џ”””џvvvр303xH8Ÿa+п GЙ[ kTVVV“€€€џ­­­џ”””џаааџсррџуууџЛННџ‘‘џ†ŠŠџ‚„„џПППџДДДџЎЎЎџЄЄЄџџџЂЂЂџЄЄЄџžžžџџџ@@@џ`Y^џ…ƒџ‹‹‹џ‚‚‚џ‡‡‡џ|||џ|||џ†††џ“““џ“““џ•••џџšššџ“’џ3oIћ€;џ7ЃTџ<ЎTџe&њ$…Bџ&?џX Фmmm:ŽŽŽџŸŸŸџzzzџЉЉЉџПППџиййџhlmџ џBDEџ}€џаЯЯџЖЖЖџЉЉЉџЇЇЇџ–––џ………џџyyyџqqqџŠŠŠџŠŠŠџPPPџ]]]џnnnџxxxџzzzџ™™™џ–––џ•••џ“““џ˜˜˜џ•••џЂЂЂџЅЅЅџџ—‘•џ2KџŠ:џ,šFџ;­Sџ~1џ,”GџAДZџ‡4џ,bzzz6oooџŽŽŽџЙЙЙџжжжџлллџ№ё№џadeџџNPPџƒ‡ˆџпооџЧЧЧџМММџФФФџЙЙЙџЕЕЕџЊЊЊџ™™™џxxxџnnnџbbbџQQQџeeeџˆˆˆџџˆˆˆџ‰‰‰џ•••џЉЉЉџЈЈЈџ­­­џ   џЂЂЂџЇЇЇџЌЌЌџАЌЏџszџ'ЃDџ8ЕQџ. Hџ"ˆ:џ4ЉLџ7ЌQџ"‹;џ ?ttt0”””џСССџЩЩЩџаааџиииџьээџjmnџ.--џceeџƒ‡ˆџиииџТТТџЗЗЗџОООџЖЖЖџ­­­џЈЈЈџЁЁЁџŒŒŒџџzzzџ>>>џbbbџ’’’џšššџ›››џ   џџџœœœџ­­­џЕЕЕџЋЋЋџЊЊЊџЉЉЉџВБВџŸ Ÿџ=•Qџ;ЗUџ8ЈSџ#?џ<ЕUџ>АYџ#†>ѕ –––'ЉЉЉњРРРџЬЬЬџкккџкккџяяяџ”˜˜џeggџnrsџ““џРРРџБББџЌЌЌџЖЖЖџДДДџБББџ­­­џЉЉЉџџ˜˜˜џ„„„џAAAџkkkџ}}}џŠŠŠџЇЇЇџ­­­џšššџ­­­џЇЇЇџžžžџЋЋЋџГГГџЙЙЙџАААџЛЛЛџА­Џџ—™џJ ]џ'‡?џŽ8џ4ЊPџ,œIџh+вЅЅЅ"ВВВїОООџВВВџЉЉЉџЙЙЙџиииџвггџПТТџВГДџХХХџДЕЕџЉЉЉџЇЇЇџІІІџ™™™џ™™™џŠŠŠџ………џџ’’’џzzzџLLLџ———џ–––џ†††џ‰‰‰џџ   џДДДџ­­­џЉЉЉџЈЈЈџЌЌЌџИИИџЏЏЏџРРРџЖЖЖџЖДЖџЎЉ­џdkџ'ЃBџ6­Oџ*FџM!‘ЁЁЁŒŒŒѕwwwџЇЇЇџЧЧЧџрррџђђђџщщщџрппџнннџдееџЪЪЪџУУУџОООџЏЏЏџБББџЊЊЊџœœœџ†††џiiiџ^^^џbbbџGGGџ———џ   џŸŸŸџˆˆˆџoqqџˆ‰‰џ’’’џЏЏЏџДДДџЏЏЏџЖЖЖџДДДџАААџБББџИИИџНННџЙЖИџžžžџMž`џ>НZџ.ЂMџ 8g„„„‚‚‚ѓ“““џбббџкккџхххџюююџцццџфффџрррџиииџЭЭЭџТТТџОООџБББџ­­­џІІІџЂЂЂџџ€€€џqqqџRRRџOOOџwwwџ………џ   џxyxџW[[џ^bbџ‰џ“””џžžžџЅЅЅџБББџНННџЕЕЕџЖЖЖџВВВџЗЗЗџЉЉЉџЄЁЄџЎГЏџ?~NЦ$˜˜˜э˜˜˜џЭЭЭџеееџфффџюююџтттџуууџрррџдддџПППџКККџЛЛЛџГГГџЋЋЋџЈЈЈџЇЇЇџ‘‘‘џџxxxџZZZџqqqџЃЃЃџ———џ’’’џdeeџ@BAџџY]]џБГГџЊЉЉџ˜˜˜џЅЅЅџЌЌЌџЛЛЛџОООџКККџУУУџЕЕЕџЅІЅџЉЈЉџ‘‘‘џ‰‰‰ ŠŠŠш‘‘‘џЛЛЛџБББџЙЙЙџЩЩЩџйййџдддџЧЧЧџСССџЗЗЗџЉЉЉџ   џ”””џ‚‚‚џ„„„џŒŒŒџџŠŠŠџ‚‚‚џZZZџsssџЋЋЋџВВВџЖЖЖџ[\\џXYYџ$##џ[^_џЖИЗџЙЙЙџЎЎЎџЖЖЖџ­­­џБББџДДДџТТТџЦЦЦџПППџЖЖЖџБББџ‘‘‘џ vvvфvvvџџЛЛЛџдддџуууџыыыџуууџзззџжжжџЮЮЮџСССџЙЙЙџИИИџЎЎЎџšššџ“““џџkkkџ___џNNNџ\\\џ•••џБББџОООџ^__џillџGGGџhkkџЃЅЅџ­­­џАААџРРРџСССџЛЛЛџ•••џ ЁЁџЅЅЅџЖЖЖџИИИџНННџ‘‘‘џfffhhhйЃЃЃџ———џЯЯЯџрррџрррџсссџпппџЭЭЭџвввџЦЦЦџЛЛЛџЛЛЛџЗЗЗџГГГџЃЃЃџ   џŠŠŠџ„„„џsssџVVVџ{{{џџƒƒƒџ’’’џ†††џnpoџ]__џ€„„џАББџНММџЋЋЋџДДДџОООџЙЙЙџehgџ`ccџ‚††џІЈЇџЄЄЄџ   џ‘‘‘џqqqСžžžџ‘‘‘џПППџЯЮЮџЮЮЮџКННџ—››џ’••џ†‡‡џБББџŸŸŸџœœœџ———џ“““џџ’’’џ„„„џ„„„џ‚‚‚џgggџ‡‡‡џЇЇЇџЌЌЌџЅЅЅџžžžџ›››џ„„„џЁЁЁџИИИџСССџЕЕЕџМММџИИИџАААџeggџџ%''џЋЏЏџЗЗЗџЄЄЄџ‘‘‘џrrrЛ†††џ†††џЁЁЁџОООџиййџfjjџџACCџx|}џКЙЙџЄЄЄџЉЉЉџџ”””џ‡‡‡џuuuџfffџeeeџqqqџ^^^џ€€€џЁЁЁџЎЎЎџРРРџТТТџУУУџЇЇЇџЊЊЊџЉЉЉџЙЙЙџРРРџЦЦЦџУУУџЗЗЗџqssџ@@@џ344џЈЌЌџЎ­­џЉЉЉџ‘‘‘џ\\\Ж{{{џ­­­џРРРџЮЭЭџфххџadeџџOPQџz}~џСССџЏЏЏџЌЌЌџЅЅЅџžžžџ‘‘‘џ~~~џpppџiiiџgggџ///џ555џ__`џџДДДџТТТџЫЫЫџЏЏЏџУУУџСССџВВВџБББџФФФџУУУџЧЧЧџoqqџbccџSTTџЇЊЊџ ŸŸџœœœџ‘‘‘џ\\\ џЎЎЎџУУУџЮЮЮџхццџknnџ...џdffџz~џЫЫЪџЖЖЖџЏЏЏџЊЊЊџ   џџsssџdddџhhhџ‚‚‚џ444џџџ!!!џIIIџ{{{џЃЃЃџŸžžџНННџФФФџЧЧЧџСССџЕЕЕџРРРџФФФџЁЁЁџoqpџadcџЉЋЋџПООџЪЪЪџ‘‘‘џbbb‡ŽŽŽџЉЉЉџКККџЙЙЙџЫЫЫџ‡‹‹џXZ[џlqrџ‚…†џММЛџЅЅЅџ•••џџ†††џtttџpppџkkkџdddџƒƒƒџ222џџџџџџ`bbџDDDџ|||џЁЁЁџИИИџРППџПППџдддџЫЫЫџШШШџДДДџ–––џПППџЛЛЛџгггџ‘‘‘џjjjqqqџ‚‚‚џГГГџгггџфууџНППџˆŽџЋЎЏџлллџаааџТТТџЕЕЕџŸŸŸџšššџwwwџ___џYYYџNNNџ```џ222џ џџџ џџXZZџџ$$$џ<<<џaaaџ†‡‡џџСССџЧЧЧџЬЬЬџОООџЦЦЦџСССџЋЋЋџЗЗЗџ‘‘‘џZZZtuuuџУУУџзззџхххџыыыџфууџщщщџчццџзззџЩЪЪџОООџГГГџžžžџ›››џwwwџjjjџrrrџ~~~џtttџ'''џ џ!!!џ###џ,++џ555џ_aaџџ џ&&&џ)((џNPPџLLLџhhhџˆˆˆџІІІџЎЎЎџХХХџгггџеееџЪЪЪџ‘‘‘џmmm]џТТТџЭЭЭџгггџбббџМММџВВВџЋЋЋџŸŸŸџ———џ‘‘‘џŽŽŽџƒƒƒџ………џmmmџjjjџxxxџ†††џŒ‹‹џMOOЮ###ю---џBCCџbddџvxyџ`aaџIIIџ777џ,,,џ)))џNOOџ:::џ===џGGGџVVVџrrrџ“““џЏЏЏџФФФџбббџ‘‘‘џvvvItttџŸŸŸџ“““џŽŽŽџ‹‹‹џ~~~џvvvџrrrџkkkџbbbџ[[[џVVVџOOOџPPPџIIIџNNNџbbbџwwwџƒƒƒџuuuAmmm““GddfЂQRRх;<<ў111џ===џJJJџUUUџ```џcdeџCCCџ>>>џCCCџFFFџhiiџdddџeeeџ€€€џœœœџ‘‘‘џeee?LLLџlllџ}}}џ•••џџ———џџ‰‰‰џџrrrџfffџXXXџJJJџ???џ666џ000џ666џDDDџYYYџmmm1___^^^A```”mppШkll§sttџ€‚‚џsttџjjjџ___џ\\\џMLLџghhџ___џVVVџ\\\џaaaџ\\\џ???666•PPPџwwwџ–––џІІІџЈЈЈџœœœџ’’’џŠŠŠџ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ222џ///џ777џKKKUџџџvvv6uwwulllУgggћiiiџpppџ}}}џ„…†џŠŒŒџtuuџ^^^џ]]]џ^^^џ\\\џ***Ѓ<<<џXXXџyyyџžžžџЌЌЌўЏЏЏќЌЌЌёšššњ‰‰‰џ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ333џ222џ888џXXXјRRRA‡‡‡"—ššY“–—Й‹ŒŒъ‹ŒŒџ‰‰‰џ‰‰‰џ†‡‡џ‡ˆˆџsssџ\\\џ111ћ<<<џTTTџ}}}џ…ˆ‰џЌ­­ўЙЙЙўЛЛЛ§œœœўˆˆˆџ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ222џ999џ^^^џdddџ```Й‘‘‘”””V“““Ё’’’н““”у”••Л˜™™І”””n222џ<<<џSSSџƒƒ„џGNPџJPRџ‘‘‘џœœœџ’’’џŠŠŠџ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ000џ@@@џžžžџџQQQџЉЉЉ 222џ;;;џQQQџ‡ˆˆџQWYџ;BEџjklџyyyџ†††џŒŒŒџџrrrџfffџZZZџMMMџBBBџ999џ444џ333џ555џ,,,џџQQQџ222џ;;;џQPPџ‡ˆˆџPWYџ>EGџSUUџVVUџ}}}џџ„„„џwwwџjjjџ[[[џKKKџ<<<џ222џ,,,џ111џ444џџ!!!џQQQџ222џ888џRRRџ”••џLSUџ>>џWWWџџЄЄЄџ­­­џžžžџŽŽŽџџqqqџ^^^џKFJџ2P8џ'ŸDџ “=џ)ЏNџ›;џ.ЋLџŒ:џ6џ{5џg)г)))J999џ[[[џˆˆˆџЁЁЁџЋЋЋџЌЌЌџЋЋЋџЇЇЇџ”””џ†††џtttџdddџFKGџ(p:џ%ШLџ(ОLџ%ЌIџ$šDџy7џ#‰=џq1г ''' NNNїzzzџ‘‘‘џМММџкккџшшшџнннџЭЭЭџЗЗЗџ­­­џџŒŒŒџ~x|џS^Uџ(€=џ+ВLџ$ОLџ+˜Jџ1†Gџ;šSџP{\ћ\W[Ь$$$a ???aaa憆†џЄЄЄџмммџїііџѓѓђџжжжџвввџаааџФФФџЕЕЕџџЃЃЃџ“‘“џpemџ4O:џPšbџmrnџsutџ}}џŒŠ‹џ‘‘‘џŽŽŽџlllд.,.h QE Ѕ)u Q 8\\\^”””џ   џУУУџмннџ‰ŒŒџcffџžŸ џЛЛЛџЅЅЅџџ‡‡‡џџ———џ‰Š‰џKGJџzrxџ€~€џˆ‡ˆџƒ‚џ†……џ’’’џ˜˜˜џ›š›џŽŽџ'zCџ0ЃOџ*•Cџ$†?џ'Ž?љ( _vvv6ƒƒƒџЌЌЌџЫЫЫџиййџ;=>џ.00џЋ­­џгввџМММџЗЗЗџЃЃЃџŒŒŒџnnnџjjjџSSSџџˆˆˆџ‹‹‹џ™™™џœœœџ   џЁЁЁџЉЉЉџЈЄЈџJ‘]џ-­Iџ.Hџ0 Iџ6ЎQџ A‚‚‚1ЋЋЋўзззџмммџоппџ\^^џQSSџБГГџгггџОООџОООџБББџЅЅЅџ‹‹‹џ|||џEEEџ†††џœœœџœœœџ–––џџ­­­џБББџ­­­џДАГџŠŽџ9ЋSџ(™Dџ5ЊOџ1ЂNџ GЇЇЇ&ЛЛЛљМММџСССџжззџЕЗЗџЅЈЉџХЦЦџИИИџЄЄЄџ™™™џ“““џ‹‹‹џ}}}џ|||џbbbџŽŽŽџŠŠŠџ———џЂЁЁџЎЎЎџЊЊЊџЎЎЎџЗЗЗџИИИџЙЕИџ‘Ђ–џ9‹Mџ.ЎJџ(‘A§ ŸŸŸ ………ѕЊЊЊџиииџ№№№џђђђџјјјџъъъџлллџХХХџЄЄЄџЁЁЁџ‚‚‚џeeeџPPPџbbbџžžžџ•••џvxxџŒџЄЄЄџБББџВВВџЖЖЖџГГГџИИИџКВИџ’І–џ@ЉVїb)І‘‘‘ядддџыыыџђђђџъъъџэээџрррџЯЯЯџЙЙЙџŸŸŸџЄЄЄџџ€€€џ[[[џxxxџ–––џ‡‡‡џFHHџ8::џžžџІЅЅџЉЉЉџЕЕЕџНННџИИИџЕЕЕџДБГџŸŸŸџooo~~~ъЄЄЄџУУУџоооџъъъџрррџЮЮЮџЗЗЗџЅЅЅџ’’’џџvvvџtttџ^^^џ„„„џРППџ“““џKLLџ677џŸЁЁџИЗЗџЛЛЛџИИИџЖЖЖџЙЙЙџСРРџПППџŸŸŸџbbb pppфžžžџрррџњњњџџџџџцччџиииџЬЬЬџПППџБББџ‘‘‘џ„„„џqqqџWWWџxxxџ”””џ•••џijjџfiiџŸ  џЖЖЖџМММџХХХџ…‡‡џtwwџІЇЇџБББџŸŸŸџfffyyyжšššџТТТџмммџ•˜˜џruuџœžџЌЌЌџ———џџyyyџrrrџvvvџkkkџ———џІІІџЙЙЙџЉЉЉџ˜™™џЏЏЏџЦЦЦџЧЧЧџСССџpqqџ џŒџКККџŸŸŸџUUUdddг”””џЩЩЩџмннџ:<<џ,..џž ЁџПППџЈЈЈџ›››џџbbbџZZZџEEEџPQQџˆˆˆџФФФџЭЭЭџЙЙЙџОООџМММџУУУџЩЩЩџ~~џJKKџ‹џЌЋЋџŸŸŸџnnnЧЎЎЎџЭЬЬџежжџ^``џRUUџ›џЗЗЖџžžžџ–––џ€€€џgggџoooџ???џџџ???џ}}}џ–––џХХХџЯЯЯџСССџЩЩЩџДДДџ‚ƒƒџЇЈЈџТТТџŸŸŸџjjjНџОООџтттџБГДџŸЃЃџЪЫЫџПППџЃЃЃџ‡‡‡џnnnџ\\\џ```џ999џ џ џџ244џ'''џOOOџ‚ƒƒџЃЄЄџЧЧЧџгггџЫЫЫџУУУџЕЕЕџŸŸŸџmmmДДДДџоооџюююџцццџрррџЩЩЩџЕЕЕџЄЄЄџ‹‹‹џsssџsssџƒƒƒџ@@@§џ///џDEEџPQQџ(((џџ9::џPPPџaaaџŠŠŠџЉЉЉџЫЫЫџбввџŸŸŸџ}}}ЃЁЁЁџЅЅЅџ   џ‘‘‘џ‡‡‡џyyyџkkkџbbbџXXXџUUUџgggџ„„„џprregggefhаZZZўTTTџPPPџLLLџWXXџNNNџ:::џEDDџhiiџyyyџŸŸŸџŸŸŸџWWWžiiiџŠŠŠџšššџ‘‘‘џ†††џyyyџfffџRRRџ@@@џ555џ555џFFFџa^^Y___ ```Œceeй\]]ќ]]]џ___џ`__џ___џmnnџUUUџZZZџZZZџ$$$T@@@№sssџЅЄЄўВВВ§ЄЄЄњŒŒŒџ|||џiiiџVVVџDDDџ777џ111џ000џKKKЮVVVDxxxmmmmijjЫbbbј^^^џiijџqqqџpppџZZZџUUU000гEEEџoppџ~‚ўЌЌЌў­­­ўŒŒŒџ{{{џiiiџVVVџDDDџ777џ///џQQQџnnnџZZZџ ‚‚Riiiаbbdэcccфyyyo333000зCCCџpqqџBJLџehhџ‡‡‡џ‰‰‰џyyyџeeeџRRRџ@@@џ555џ111џ@@@џEEEџZZZџ333111е???џpqqџFMPџBDEџ]\\џžžžџ’’’џ‚‚‚џqqqџYYYџ@@@џ222џ+++џ+++џZZZџ333---еdccџЇЇЇџsxyџ.11џ/..џŠŠŠџ   џ˜˜˜џœœœ§žžžџ•••џyyyџ\\\џbbbџZZZџ???]]]јЎЎЎџЊЊЊџ———џKKKџ(((џ^^^џLLLџ777џZZZџyyy;ZZZџkkkџ•••џ’’’џZZZџrrrЭaaaэZZZџrrrџcccџ...џcccџBBBџUUUџZZZџZZZџXXXџgggџYYYџ[[[b‰‰‰N‰‰‰ќ€€€џlllџzzzџiiiџ„„„џuuuы[[[ГXXXїEEEЦGGG`UUUmmmZZZЕYYYЯYYYжYYYмXXXпVVVЦoooWјџРџџџџџ€€€€€€€€€€РРРРРР€xџџџџџрџрџџ(0 ` =S9k2_4 / @?P<‡7“Bз4 ˆF‚$pEџb6џp5џz4џp.џK`OџxxxџpppџdddџWWWџJJJџ>>>џC%џ.~Oџa6џ w:џ|6џs,џ7f YS)ŠMњAџ!Aџ*™Eџ‚6џ9cCџ———џ†††џvvvџdddџQQQџAAAџ!I+џ1—Yџ‚Cџ)•Hџ,Gџ€4џ<f f#9% Kя)БRџ.ГPџ5ЋQџ{7џŠ•џšššџ†††џvvvџdddџQQQџAAAџ+G2џ.АXџ*ВRџ1ЗSџ7ЋQџt4љ6•2К$ДGњ%ВEџ/ЉPџDqPџЊЊЊџ›››џ†††џvvvџdddџQQQџAAAџ:>;џ,ŽCџ%ВEџ)ЕHџ-ЉOњNat'S$„:џJdPџ{{{џ………џyyyџiiiџ___џTTTџHHHџ===џ???џTTTџ)M1џ~*Ѓ eЃЃЃіƒƒƒџпппџюююџшшшџВВВџХХХџАААџšššџiiiџэЈЈЈхŒŒŒџчччџїїїџяяяџЖЖЖџЬЬЬџЖЖЖџ   џnnnџ‘‘‘лІІІЭŽŽŽџчччџїїїџяяяџ(.1џЬЬЬџЖЖЖџ   џrrrџЩ………ЪџБББџлллџиииџ'.1џ“““џ}}}џpppџsssџtttУЈЈЈЈЦЦЦџфффџлллџёёёџ28:џЩЩЩџ}}}џЃЃЃџ———џЂІІІ“ЦЦЦџфффџлллџёёёџсссџЩЩЩџ~~~џЃЃЃџ———џŽŽŽ†††’џВВВџлллџиииџЖЖЖџ“““џ~~~џtttџvvvџuuu‰   oџчччџїїїџяяяџЖЖЖџЬЬЬџЖЖЖџ   џwwwџŽŽŽfžžžZџчччџїїїџяяяџ(.1џЬЬЬџЖЖЖџ   џwwwџŽŽŽTŠŠŠU‘‘‘џДДДџлллџиииџ'.1џ“““џ€€€џyyyџxxxџwwwMЄЄЄ0УУУџфффџлллџёёёџ28:џЩЩЩџ€€€џЃЃЃџ”””џ0ЉЉЉУУУџфффџлллџёёёџсссџЩЩЩџ€€€џЃЃЃџ”””џЉЉЉ ŒŒŒџЄЄЄџІІІџ­­­џЁЁЁџ‘‘‘џkkkџtttџkkkџbbb )))џ333џVVVџuuuџyyyџoooџ^^^џJJJџ888џ+++џ)))џ)))џ&&&ѓ333џ@@@џkkkџ’’’џ———џ‹‹‹џvvvџ]]]џFFFџ666џ333џ333џ111№333џ@@@џkkkџfff‹‹‹џvvvџ]]]џ"""333џ333џ111№333џ@@@џkkkџfff‹‹‹џvvvџ]]]џ"""333џ333џ111№333џ@@@џkkkџfffoooџ^^^џJJJџ"""333џ333џ111№рџРРРР№ќќќќќќќќќќќќќј?ј?ј„?ј„?ј„?(  @E F•=AЛ5 +<3FЇ DК GЪ6Ub+Pџ;џЙ@џ*`6џiiiџVVVџAAAџ...џ\.џ”Jџ$‚CџЁ;џ:S f&'ЄLїоCџ/›Mџa|hџ”””џvvvџYYYџ???џ+Y6џ,ЌTџдDџq1ч3i&5"z7ўHiQџVZWџPPPџMMMџAAAџ...џ697џ.W8џx'Ё [———џеееџэээџДДДџГГГџ˜˜˜џђ­­­џнннџіііџ(.1џКККџžžžџ‚‚‚ђƒƒƒџЁЁЁџпппџ.46џ………џiiiџbbbѕ­­­џЅЅЅџѕѕѕџсссџНННџmmmџђ­­­џІІІџѕѕѕџсссџНННџoooџђ†††џЅЅЅџпппџ)/2џ………џnnnџiiiѕ­­­џнннџіііџ,24џКККџžžžџ‚‚‚ђ›››џнннџіііџИИИџКККџžžžџ‚‚‚ђ111№TTTџ’’’џ’’’џvvvџQQQџ666џ333џ111№111№TTTџ’’’џ’’’џvvvџQQQџ666џ333џ111№111№RRR№fff’’’џvvvџOOO№"""333џ111№111№RRR№fff’’’џvvvџOOO№"""333џ111№ƒС€€Р№№№№№№№№ррррfwbuilder-5.1.0.3599/src/gui/gui.pro0000644000175000017500000000417111733011756017662 0ustar sylvestresylvestre# -*- mode: makefile; tab-width: 4; -*- # $Id$ TEMPLATE = app LANGUAGE = C++ QT += network TARGET = fwbuilder include(../../qmake.inc) exists(qmake.inc):include( qmake.inc) SOURCES += main.cpp # Arrange static libraries before dynamic ones in the linker command # line. libgui goes first IMPORT_LIB = ../import/$$BINARY_SUBDIR/libimport.a FWBPARSER_LIB = ../parsers/$$BINARY_SUBDIR/libfwbparser.a # FWTRANSFER_LIB = ../fwtransfer/$$BINARY_SUBDIR/libfwtransfer.a INCLUDEPATH += $$ANTLR_INCLUDEPATH DEFINES += $$ANTLR_DEFINES STATIC_LIBS += ../libgui/$$BINARY_SUBDIR/libgui.a \ $$IMPORT_LIB $$FWBPARSER_LIB $$ANTLR_LIBS # fwtransfer lib. Add this before adding -lQtDBus to LIBS below # STATIC_LIBS += $$FWTRANSFER_LIB # contains( HAVE_QTDBUS, 1 ):unix { # !macx:QT += network \ # dbus # macx:STATIC_LIBS += -framework \ # QtDBus # } # !macx:STATIC_LIBS += -lQtDBus # workaround for QT += dbus not working with Qt < 4.4.0 INCLUDEPATH += \ ../libgui \ ../compiler_lib \ ../libfwbuilder/src win32:INCLUDEPATH += ../libgui/ui !win32:INCLUDEPATH += ../libgui/.ui DEPENDPATH += \ ../libgui \ ../compiler_lib \ ../libfwbuilder/src OTHER_LIBS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../iptlib/$$BINARY_SUBDIR/libiptlib.a \ ../pflib/$$BINARY_SUBDIR/libfwbpf.a \ ../cisco_lib/$$BINARY_SUBDIR/libfwbcisco.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a STATIC_LIBS += $$OTHER_LIBS PRE_TARGETDEPS = $$STATIC_LIBS macx:STATIC_LIBS += -framework Carbon STATIC_LIBS += $$LIBS_FWCOMPILER LIBS = $$STATIC_LIBS $$LIBS win32 { RC_FILE = fwbuilder-windows.rc win_ico.files = fwbuilder-windows.ico win_ico.path = $$PREFIX INSTALLS += win_ico } macx { QMAKE_INFO_PLIST = FwbuilderInfo.plist ICON = fwbuilder-macosx.icns SOURCES += main_mac.cpp } # TRANSLATIONS = fwbuilder_ru.ts fwbuilder_ja.ts fwbuilder_en.ts # ja.path = $$PKGLOCALEDIR # ja.files = fwbuilder_ja.qm # ru.path = $$PKGLOCALEDIR # ru.files = fwbuilder_ru.qm # INSTALLS += ja ru fwbuilder-5.1.0.3599/src/gui/main.cpp0000644000175000017500000001527211733011756020010 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "VERSION.h" #include "../common/commoninit.h" #ifdef HAVE_GETOPT_H # include #else # ifdef _WIN32 # include # else # include # endif #endif #include #include #include #include #include #include #include #include #include #include #include "FWBApplication.h" #include "FWBSettings.h" #include "RCS.h" #include "FWWindow.h" #include "FWObjectClipboard.h" #include "FWBTree.h" #include "platforms.h" #include "ObjectEditor.h" #include "findDialog.h" #include "ProjectPanel.h" #include "RCS.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Tools.h" #include "fwbuilder/dns.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Constants.h" #if defined(Q_WS_MAC) extern void connectOdocHandler(); #endif #ifndef INIT2 #define INIT2 #endif extern void extras(); extern void ssh_wrapper(int argc, char *argv[]); using namespace libfwbuilder; using namespace std; static QString filename; static QString print_output_file_name; bool auto_load_from_rcs_head_revision = false; FWBApplication *app = NULL; FWWindow *mw = NULL; FWBSettings *st = NULL; int fwbdebug = 0; bool safemode = false; bool cli_print = false; QString cli_print_fwname = ""; int sig = FWB_SIG; void usage() { cerr << "Usage: fwbuilder [-hv] [-P object_name] [-o file_name] [-r] [ [-f] filename]\n"; cerr << endl; } int main( int argc, char *argv[] ) { cout << "Firewall Builder GUI " VERSION << endl << flush; filename = ""; print_output_file_name = ""; fwbdebug = 0; safemode = false; bool force_first_time_run_flag = false; ssh_wrapper(argc, argv); // can not use "-p" for command line printing because // Mac OS X supplies switch "-psnXXXXX" when program is // started via Finder. int c; while ((c = getopt (argc , argv , "1hvf:o:P:dxgr")) != EOF ) switch (c) { case 'h': usage(); exit(0); case 'f': filename = optarg; break; case 'o': print_output_file_name=optarg; break; case 'r': auto_load_from_rcs_head_revision = true; break; case 'd': fwbdebug++; break; case 'v': cout << VERSION << endl; exit(0); case 'P': cli_print = true ; cli_print_fwname = optarg; break; case '1': force_first_time_run_flag = true; break; } if ( (argc-1)==optind) filename = strdup( argv[optind++] ); //QApplication::setDesktopSettingsAware(desktopaware); Q_INIT_RESOURCE(MainRes); app = new FWBApplication( argc, argv ); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); if (fwbdebug) qDebug("Initializing ..."); /* need to initialize in order to be able to use FWBSettings */ init(argv); init_platforms(); RCS::init(); if (fwbdebug) qDebug("Reading settings ..."); st = new FWBSettings(); st->init(force_first_time_run_flag); FWObject::setDataDir(st->getDataDir().toUtf8().constData()); if (fwbdebug) qDebug("done"); QPixmapCache::setCacheLimit(4096); // INIT2; string full_res_path = Constants::getResourcesFilePath(); if (fwbdebug) { qDebug("reading resources from '%s' ...", full_res_path.c_str()); } QFileInfo fi(full_res_path.c_str()); if (!fi.exists()) { qDebug() << QString("Resource file %1 does not exist").arg(fi.filePath()); exit(1); } Resources res(full_res_path); if (fwbdebug) qDebug("done"); vector platforms = Resources::getListOfPlatforms(); if (platforms.empty() || ( platforms.size()==1 && platforms.front()=="unknown" )) { qDebug("Failed to load list of supported platforms"); exit(1); } if (cli_print) { if (fwbdebug) qDebug("Print from command line"); FWWindow::printFirewallFromFile(filename, cli_print_fwname, print_output_file_name); return 0; } if (fwbdebug) qDebug("creating widgets ..."); //new FWObjectDatabase(); new FWObjectClipboard(); if (fwbdebug) qDebug("loading translation for the current locale ..."); QString local = QLocale::system().name();//"en_US";// QTranslator translator(0); translator.load(QLatin1String("fwbuilder_") + QString(local), Constants::getLocaleDirectory().c_str()); app->installTranslator (&translator); QString qt_resource_dir = QLibraryInfo::location(QLibraryInfo::TranslationsPath); QTranslator qt_translator(0); qt_translator.load(QLatin1String("qt_") + QLocale::system().name(), qt_resource_dir); app->installTranslator (&qt_translator); mw = new FWWindow(); //mw->setSafeMode(safemode); if (filename != "") mw->registerAutoOpenDocFile(filename, auto_load_from_rcs_head_revision); mw->show(); // it is connected to QApplication's slot, not to FWBApplication app->setQuitOnLastWindowClosed(false); // connecting to right slot app->connect(app, SIGNAL(lastWindowClosed()), app, SLOT(quit())); #if defined(Q_WS_MAC) connectOdocHandler(); #endif // setup single shot timer to call startupLoad() QTimer::singleShot(500, mw, SLOT(startupLoad())); try { app->exec(); } catch (const libfwbuilder::FWException &ex) { qDebug() << "Caught FWException: " << ex.toString().c_str(); } mw->hide(); // must do this before settings object is destroyed st->save(); delete st; res.clear(); XMLTools::close(); } fwbuilder-5.1.0.3599/src/gui/FwbuilderInfo.plist0000644000175000017500000000373111733011756022171 0ustar sylvestresylvestre CFBundleDocumentTypes CFBundleTypeExtensions fwb CFBundleTypeIconFile @ICON@ CFBundleTypeMIMETypes text/xml CFBundleTypeName Firewall Builder Object File CFBundleTypeRole Viewer LSIsAppleDefaultForType CFBundleTypeExtensions fwl CFBundleTypeIconFile @ICON@ CFBundleTypeMIMETypes text/xml CFBundleTypeName Firewall Builder Library File CFBundleTypeRole Viewer LSIsAppleDefaultForType CFBundleIconFile @ICON@ CFBundlePackageType APPL CFBundleGetInfoString Created by Qt/QMake CFBundleSignature @TYPEINFO@ CFBundleExecutable @EXECUTABLE@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. fwbuilder-5.1.0.3599/src/gui/fwbuilder-windows.rc0000644000175000017500000000011411733011756022346 0ustar sylvestresylvestreIDI_ICON1 ICON DISCARDABLE "fwbuilder-windows-app.ico" fwbuilder-5.1.0.3599/src/gui/fwbuilder-windows.ico0000644000175000017500000052604411733011756022533 0ustar sylvestresylvestre О v€€ (4 HH ˆT\00 Ј%фg  ЈŒ ˆ 4ž hМЇ‰PNG  IHDR\rЈfsRGBЎЮщgAMAБ ќa cHRMz&€„њ€шu0ъ`:˜pœКQ<џŽIDATx^ьни]U•7p$єо{zBHIhBяzяНїоЅї.Mщ *і†‚:і:EбqдqfЧоЦВПѕЛфŸяјš Т$яѓьчмїоsЯ=gяЕўЋЏ=лlГўfЭРЌ˜5Гf`ж ЬšY30SЮРV[mЕ№Ž;ю8jRc›mЖelКщІ Ь”4ыЁgЭРŒ<{юЙчТ5FэЖлnЃїиcЃъxдюЛя~чЎЛюzOvйe—/ŽЈc3vоyч cЇvj-c‡vhлoП}ЫиnЛэZwlЛэЖП­џПhдыеёцŒUgф9›uoГfрM5ћяПџ}ійgїНїоћœНікыС:~БŽпЏбŠљ{cмИqН1vьио(0˜0 šQра ЦєїrѕеWсЅ—^КЅЕ6K[xSQиЌ›!fррƒuрюwаA]zР<^у+5Z@oьЗп~НБяОћіFBo є&œP L “вњj хќѓЯџё‹/Ојёј‡јСО№…_Ь“9ы&fЭРŒ<%Ећyф‘›~јсчvиa8єаCUЧVЧvШ!‡єFBo Д†оЏ%(DKшj fУiЇіПяџћПёOџєO?*Цo%§[СЯgфyŸuoГfр ™SO=uоЃ>zыcŽ9цв:~ЌЦjДЃŽ:Њ7 кGб Н@ш ajAaZЕ„Ўљ0)гС}уџј[пњжџ|љЫ_n/М№BћФ'>‘ёšРж[oНRљЮ,ПФЄsН! :ыGgЭР”fрФO\ђЄ“N:ЊЦъѕŸN8с„fќёэИуŽыc=Ж7 Ц („О ^ (L/гђдSO§њG?њбя‹љ{ŒџсјЏЦ‡>єЁз 0{9/яxь9#ыѕъј|)чуbSZ“YŸЯšзmžўљ5~јсімsЯ§ф=яyЯOyф‘_мrЫ-эВЫ.kЅД… €аТф@ЁЋ%є…ЎщаWS˜˜?С}œsЮ9НqійgїЦYgеgžyfoмxуљўїПџчџјџhŸљЬgZ=лDЧ{пћозHћbєъ…ш‘јS§џ‚§fiЏ™ЯњЁIЭР]wнЕтƒ>иž|ђЩГP“?ћйЯЖOњгlхVввgџ{Я=ї№ OКZB@Ёk:DS(œrЪ)эЪ+Џlїп?‰н>ђ‘ДO}ъSд6~їЛпMгјэoл~іГŸЕ_ќтэня~w{ійg'7І+C/YЬџŽn(выЩСјЯ~*$YcШ, 5oШ м|ѓЭjДюИѕж[{Œ >јСЖПћЛПkхDkџђ/џв~№ƒДђЄї€тбGmз_};љф“{ZBL‡h @СыыЎЛЎЧф§шGл?ўу?іЕ/ƒџїџwё]ћcћXoМуяhїнw_>wоygs_%хлХ_мs@в.КшЂvоyчѕ4‚M6йЄ§ъWПj?ўјdЧc=6н "Ч–ГёчЏ$?Ёf№TЦА7„f§шЬ;%е`т) f†,ЧZћтПиўэпў­ЧlПўѕЏщћня~З}ђ“Ÿlя|ч;лнwпноїОї5ЮЗпќц7˜§лпўv8Š{ pњщЇїќТ…LкM!Gџ{ŸI @nІй|ѓЭл†nиFе† ж дVZiЅжПџо§<єаCSЏъ^жЎd% Lг;iщЉЪ|0ѓRфЌ']g\uеUэ• Z-руџxћц7Пй~ђ“ŸL`іџїяI}’у<И7FŒбcо-ЗмВ—б'hz0zлло6ЅёŠ €hŠ<м\!Ш?ѕMZšжќ„‰e1Ž7~U@wЮ,СыЪ 3ч•:=рђЫ/oгkмtгM=˜cŽ9кМѓЮлYd‘ЖЬ2ЫДW\ёuПЭT˜м(mц@e1ЎZу—Д‘Щ…"Ї&?a*S›_р_˜9)sжSП.3ибгsМ‘@ИікkЇ4^ќќч?_Ќ|Пч“(ЭцЯ2ЛЉЭS“Ÿ@š–дцвО?ЫIјКАТ›ћG8ѓJњ[cэiy’"фчž{n›žу!ЬЩK/Нє€y2dШ/„-™Lќ&r"І&Е™ЉѓJыЪTГ4i!ь™щм’тsнvлm_ЄіrжејCС‹ 7дqяzЅIЭрŒ›žƒ~ЃLNGQ)ŒW Ы.ЛьЯ—[nЙЖкjЋѕ"L~ŽзЁос…™‰Іg=ы4Ь@…ШŽКуŽ;šqћэЗїFТ;x<(ќДˆѕ —–ЛcНз“(•8 F›žу€_ўђ—ђџ';*СщU083E4Ю8уŒщZ5Бz‡Š:l7 d1ыд™e*™чEЁЗ:і†˜Й1%P(0јю 7м№ъПЌПЄћ&Уя•…то( рЇ?§щ„цЄ2Oф8нlБХ=ЭkrEPгЃоЁќЯЯ,4=ы9ЇaюНїоп&єХAe„IBWKшЋ)Аm/М№ТžI’л?-GйxoT РяЙ —І+)ЩsrEPЏЖоЁ|?ž˜uъЬ2•Ъћ[™{ВцŒ„о˜P˜˜–P еиИB„ьнHИ)Iс7 d†б&sœю€ё€ЊШTFNkНУ”њ'дoќЧЬBгГžsf nО!Ÿпxрz L+(LЮtPŒ“fS:*ЦyЃрK_њв_uъvЪы’ЄгxјЏЙцš^"3Œ&%e™o`zѕO(gюWІ,f:ГЬ@Ѕш~Jš.т{ћлпо„i…I™4}КЮЉIНЎŠМПМQ ЈЈл+pЏЇ;ЌНікэ‚ .hUQй+lв|фЋ_§jЏіс{пћ^/SRM…т*ZšТ*рІ*SъŸ бJЅWyfЁщYЯ9 3PŒљ_EџІЌd$'О/(МR-Aм[тKпЊЗОџWЮџO?§tЯ)7ЙQЕгј@ЗЈ ˜Ž/ЕюUWў§пџ}“"-T)R’‚ЈўчnŸџќч{е˜LЗЪSш•awAЁЊTХO?˜˜uъЬ2ђы‹pОPuюПЌzў–јК а-’yЅ Рg XGјkRуk_ћкРM­СЦkœЇS*ЊђyE^zкšВeuЬ–вšZeі€@Њ&iЅ9ќЄД‰ŸnДбFГ`faъiyNъgЕ Ђ"~ЎTап)аQ•—б& „Ўљ09MНЋJoܘ13JšНaРq9rфШЩŽЬз.Йф’žjџj†ћЗДZУзПўѕія|чпЭuк,˜֘YЮ>|xЏ4VŽyРЗЊ жЯдФ+ЛЏ&чO ђŠГW‡›ЖўњыїFuуyУ@“‘5з\sВЃвyЇ 4G­ЬТ+_тёzж?3yd&(Gб’+ЎИbКš€ш*ž3 COыs€€*Гbќх+_љ>3Э1€AЦФ@arІCŒs2вH+Э9ж[oн^ЙoеќџљrRУW]uе))@y№ЈБ]IнVзќ/іНQэХ'Є ѓmМёЦm…VшС[пњжžчz&РЁсЭ2І•3f’ѓЛЅЮ9пјЦ7ўЛ€рwхhO<ёDotЛхL &І%‡‰љЊ`Џƒ.AwоqkЉн#z’їјР€hР€“е8фo ді…KzяXEDWеxQ1gœAЕSЇjаxѓ…™SQ‡0Mчpж,˜IzZГ/ƒj^цРŸќуџЖ<аџKRkѓ0˜@˜˜?ˆ№ZsZН№ТЧлa‡ьзvиnѓ6tшšmѕеWз`є ЭAѕ˜д ЌЗоzП.ЦQХєїдxЁbі?fЗ‹н“тS"ъ|z%L‚ACBiTњj@у”ъ(< І•1f–ѓ'ыЌГN[wнu{}ђxž+§чbи?–WЙЇ‚ю˜ZPаfћПўѓ?Ћ%иїлх—]иcќŒAƒVя5ў(-bК€Шƒžƒдn =LL‘z|uііŒКœЭJЄ4ЋжУдrhFO|<іŠy }87Тф@!%Чбњj €Ряы™јJG€ Ў?œYhzжsNУ LJ%эz!1RD\КrхџRНќў\=§ўGыьwНы]}Ер Ч_yЃ{сЉЧ}ИэБ[mЬйa~ЏWYeхЖќђЫЋEјгєђЈЗЧ„S›кœ"ЈЩе;$V Ё/(ЄБШЄ@–MЁЋ%DSЭ€™Р&S 4бЯч.`+0ŸгР3ЭЉ“^y@ƒ˜фњkа‰ИŠЁѕвџVрэЕЋЙч_Tј}ё‹ŸoGy№п0~€`рРmЉЅ–’ ѓЊу“ЌВц^ijs*#ЇTя є6%Pшj бюыЋ%єІ„ДlZˆњ„ьЎ45ЧЏэЯgРLУег№ г$ ЯЯaЅэwšyђ8ќ!`P]~џђŸџљэЧ?ўїvЭе—O’ё+ЌА\[lБХHьWTgнЈУдц'LIS˜кRщО а5Ђ)LЪt ЮwџцЗБ=g)ѓ‰ ПЉ9FцЭf›m6 І/fšSЇ$ьађњхЁ+љeЇ’ВOўыПўkBŠ*uџщЇoуіиiŠЬ–YzЉЖр‚ ђ˜П"РЏu˜\ввєЎw˜Rџ„€Bзtˆ?A7&сRZ”ь>yџ6V1Џ шšсМє˜šc€Ѓ2/4гѕЌњ˜pvM§є9“ €ЃŒЊ­я5U•tУ€яьГN›*ЦАФ‹ї:WТЬЇХ М˜ эwћ&-Нšќ„Wk:LЪŸР,yц™gzћ кmXс=јTјJЬЁ Р лѕБlАAяЕљ—>=Б ХIНG+гlTсU…gРдГХЬsцдh|ˆP'ЕЖVaЦЛЎO9››У‹ЄћьНЧ4Рb‹-вцšk.эИІH}Œ:=ѓІgТдВKџƒ Q”;ЫнчGQ!§Е!Ќ СrР&„@Љ№=-РќOэ …k1 fžžІ'Z@|с3’—#Ъі]Мдб„ЧР^{э6MАф‹џО_П~=f˜’@Ђ‘”Џ$љjS›уO:’™lCfWЃJœъ•эbюџЌP'щ›т9Ÿћмчzv=Џ>*Ь>Бc_ˆ#– |9Еƒѓ•ЉАkэfiгФ3ЩЩS,rO<ЪдJ&TU­Ќ˜lUoМк`Я=w&иd“1НyПБшЂ‹іВёV^yхЖЦkєR„ЉУЃGюйСeЖГп љь?шˆбиайЌдЖd‰œI`5јŽloƒГ CлlTMОkЊИSXC‚+ЩдцЃ>s>`рЙв3Oю›*/Ќъ90јфРg] РїiaДы0Е№шD (џЭПЯ$$=ы1Їe&•„ћ†Ѕ”že’…'š ўœ Н•=ŽAЦнyš`Ы-ІŽА9Фhі Фl@г }Ә‘М$ ї1‚Vcœ”TpŒњУўА'­}З;МяŽњž= yс•ж:VЊr@˜ТZy‰Я“ЪЬ$Ь 01ЌДjвћ•@r1|Ÿ#0Іvx^d­*љiL cЬ,чN­ €АI_@'U˜~bZ_-#ŽJяœ€лlГUяњS3dђ9 ˜gIЛџв“РФ!чмє)ЬЙ4 ёuЬ$рИ€&Ър0)JmgњАЇ=? 2"#˜п}ПV@{@…1ЕƒЦbмняЌІ 3 SOЫsNNH& Т4mВ8Ќи•˜0ЄЋЪ]Ї€=ІvиaЛЉiЧе;N˜!jh#œ“˜šэ-wЉBj _­lOФ<‡†э,<ЃЉЌзд]„8k%еšЭ€iaŒ™хмОћД› ѕ“”K.iˆА„c`*Lж€нwœ&`—]vюЫд р3Г@7ЫЄЈ~S=јAЂХЬ€™…ЃЇё9'— Фpfkюл№р“А/' LŒЛ{OЋ˜šxўЏ@_G _-`*њL8‡г@3Ъt™ЅL#oЬЇOM Џ Mˆ#к,јW0‘‚ŸО@нџїо{ЏЉщЩп;‡Tы@2ътјП`t @ 8еCЯ†T6`Я€™‚ЃЇё!ѕ БuCSѓ@wM€h˜1љ€#АЇL#pРў=Л{j†п“K/‰†„џ‹uр шлJlrџ›Ÿј2jНfm 2М1Sœш—žœ€а€hЩx%pшЁ/ћІfЈA˜™ )С@`Щ%—œъ‘]™hЅБЭ€™‚ЃЇё!_‰ жѕLршЃŽь…пІf№мЯlІЉ’ЄІvdЛ1Z@љVfР4ђЦLqњ+>€8€МќWу8сјуzЁЙЉ’Žfшы*&ЇvXaZ›хЏљљLAаГrкfL,5ujТ€“™xг8ѕ”“UNѕ˜€3PХфдцTvfЎЕњпiЃŒYgЯ3№j4€n@4L,wZрЌГЮьЕРšš!Б'Ж\џ€}5ОEYj#дJЬ=їмН ЪIюЖьЕVž)zжCNл LM*№Фђ&–ФПјХ/ІЮ?џМ ]uг]wRGЉЛ3 nъoп9‘})sQv$a•UVщљTVrўљ Tжц, `кXcц8ћ•€lН“Ц œwьw fZ5€K.ЙxЊіЦ#щѕ˜™ •ŽSГ sфB ™в~6sPєЌЇœІx% Z€‰@užfИђЪ+zq§Љдў™Іf~œcŽN9х” Е хјЯi"ŒY'Я30-0Бb €Ю@ЉјюwП;ЭpнuзєšyNЭаofцРдЬ @fІт&Ž@Z@iГ`ц`щi{ЪW BLL€.шŒ3Е&РћэY|WЗn“Ю)Н~лло6S€эУ&77JŸ…H1~F |Г`кXcц8ће€"“. >е€КѕL ілglйђo§Ћ­ШЛ{ Nю5&˜™4€8РФцEsѓ.wРџоЏВрY0sАєД=х+€4I[0@zj>)иЋZ…НѕЪЫ&КЃPп-Ч&ѕПf›ђўcыў_­ш[›сџюœјВ"…cе§sіaіОР˜гЦ“;Ла№№C=p\ѕŽ\kњ§тkxЅaУ†ѕvІэ[ а­CO0>€nG B шЉзіи}‡у?ћь3НžyЏfиnlfQ {ІяЖiТ}}Е`˜eМ:&Њмял>Y;F§.{@LщЈенwпѕ›ˆя@|фўћяНйuj чzuw3П][rП(Бdrаэ4Б–`ща\sьј~ЛэВ]mzQс5фœУ–c -Оf Жj ’Сiгs,S PЕЗNGВ™).uп}oЛрž{юўZэљ'-хІчИѓЮ;ўXр№пu§oоwп=8œўрƒoлрuŸиСƒŸ3ЉЖ`}7ISP€yщ иm І=ИVй{W[№ /8Ззqз&гsшф;Г@і аxдzДg‘Ёюcњ.а jЭFПюФѕ&ћСъ#ЙєНїоsu1чїJИќ%{>О^Ч[oНЅшњšПT;ЛЅ_ЗЉЋSЋ:єO}Э€‰э Єљe4€.(ЯMO@РF/Дќ-U]нДмž^GnfаœєЕj :БђьОkВеV[ѕЖ:зЈ4u}`М№ЛЏAНЩ~Ј˜~­{юКыслnЛѕ?гX&Л=ПжGП'_уњъm!М;~я­јКNciяІtA /БЩAŸH:‘– 4т”‰&MM/[щwхЉўiyАўюwПЛЇ шЛџJЧ‡>єЁ^ЫЎР€О­к€&Љ н™ићBбBЉџgПЎ5ƒџX9юЖЛуіл?rѓЭ7§2лИП^GбЋыЏЏqнЕ=ІЧ іЎрлС3ђ7ЊCџзu +|еђќЁы ˜и€Я3 Ј?я <ѕœ!кt Wйgќž}ПЏ–U?ЊџvљО]L§э~єЃџkМ) šDРeF-ЂЂПš}&ЕcŠРД Я†­Yн™тЄ™џ\ї2ЧыJP3рнuзэGоvлЭ/]wнЕџ‹б^ЯqЭ5WзйWїгЃ_‘2ЛTЉkЩZY/Џ_wА^Ѕ\$"˜аR; -xW˜xx=ыlБХTШ№}іы‰яжюОпЌёwѕо{kCЭ—ЪœxЖ@ЂіљФзi3“А[тьFјdт^8ь8ђуk~K<эwоyћ™7оp§?\ѕжЗўYwЄзshK/Нгл%*ЛMйZNХЋѕЁ­ба Ьџ†@љц*јиZk­5a+ЎО;1иœй(@6Ёa*›nв B'ЃLz /ЖЬ6a&Pі_6љ(Џь_mє13Dњ–gЧ`kG`ЪГгАжщњзœгf (!ВигO<ЖпSO=іьгO=њЋЇŸ*ѓиУэЁЗЃŸЛŠoЎВk{Œ95eчгzКПьВK{Пnmёn+ДЋHЮК›ЇL{†ыX{ё-\{ё}=Qxœ…уш•гCL `ъlх=  wsAжŸ-ЕgР_я˜ƒ ˆ@4РЈџŸ˜xѓ5Л•вG• yЖМч?М­ќž{ю,Сё@{ђ‰w60Љсsч9П з^Sъјх=6-CoŠK/НЄВZЏюб,еў#љПWЏ6(ЫNГлЌRmаЙ<  p:!Дu3^ч8Ј/н­СК/ЊиiW˜^@ГјПbLЭfЁл'€ŸAЇfkЂD[ŸFeкѕњ‘џЫvџM7]ЗЧЕW_ѕёbМпи‡bRуЂ‹.ъIћnИЎh№іііяыi“ŸНуЁz@QЄFЊ“рљ~Ў‹.КАW–Nˆй€…MjŒУЃcў72(x–&@  ˜эСЛaЇДŸ €T/ЛОч™˜р=ŸMIјПKљ”0О™ь,Р  ЈЈФЏ Є{ЭФэxсbФГЫaіХsЯ=чЮ^ЭаК^џ EhЗпvKЛяоЛл#П}’Р№Фує>{єїЂOќU_јТкЛоѕЎž™+тТќŠіѕІ€ЌsРЅтt"mтшvš$ 81' `утt|Ѓ€іЕоOi{№Щ@"йКНњЋ•8ш фбщњг7п|хвW_uхе]tСїJ•ў‹<“зzpdыLue™$џUoНМЄўY=Iџв‹ŸъЙ зq№БуEТhТr0ўO€­$ЁЕ*?рЋ$N7ь41 NРDRБ' Ш†чЬ‹HzLпРg@‚#Eш@ј„)СЖтќПЊL˜ @€v6~ы№п•фŸ{КrрpБыЏМr№W\vпyчћуO<ЁНЧЉЇžвЮ.g6ѓUЦ)ѕM~№ЯЗgŸyВзG!цŸ)дCї+[ѓћ$Ž-А™&Ёш&ёžъ]Ц'ѕ#cъ‰љКвП/Ш!јПSkїїЩZ6sЩ†.|4Ѕ™§ќ рзщђ“W]uљ&_|СЯ<уŒŸ%yщѕ>žXvћйgŸеkЁ&s•#b*`roќ3%XщВoОŠё+aЈЇ =~ ж­фЅ&Б—фQ“кBx€WПЏa3bџ чв^+аФtFнМЫјaz>™вШš| вп:ŒќfКpуыt‘Gžwой/ќqшv.~=_Ћ_СєЩxэХщб'šццTUѓтѕ,(ТЈ0Ц?@Пў§ћЗх—_ОчmNќY˜#й€<ЅМЏ2œиN&˜Ъ’ H €А}10ОщŸ ГсЕ[™Н^@UЇЖГџЇFњczIYazл‚_зШNЭуЗiћуыФЛЏшgЪnюїјуямсђЫ/љд1Ч§ЧxЧ_Я#=В"VЄ:z”їТ /є„“†ЖвК 8ѓЉчх,шГдхћŽ[qХ{`вј #``ШdвФ$G  V%(~€˜.ѓO ’єfђˆžибзрH%ЕLo`zRУ—#ЖїПk0Пв“‘š{ZTЭї •ю[LП№3O<:Ў’ržЊЄœŸwCoОѓЁѕЛ*і~uyу/Њ’3кq•Nю98дІзр•ЇUЈQaB’ђ•IкГябЊАЖbЎё”Y09x/†џ!ЕЩўє6Ѕ5Й@СDЧ*с6 L#'€)­М9ёњšбвъЪџдѕПoр›КЕ€h‰DЪГчх]`z’гћпљ‰ѕЇ+ё~ЖЉy'йЌC9ЫEтy:~щТ /uњщЇ=yєбGўфШ#јЫYgб.ЛєтvУѕз–шЮ)&чМƒППjGn­мљЗ]ххэЭhœS3іo–Ђ?ДѓвK/ѕbє2S…чфMQѓ9 Іaё EbR+]И­ДвJ='iйгw.6\2ŸМя;œ‚щSsЄ8Јkxн€ОY€o Ы9нN=їмГі8љф>~№A§Ц=NiьЗпОэЈ#hgžqzЛтђKлЭ7]п‹УO)9ЧчїпwOЛхц*LwYяћ6”ЭМа@IzкЅъ:Mc˜ЁцŒЏФ|Ъ™˜QЏ”&є—K/НјцвцfœŽAЁ”’ц?+„яle іl'(1xli€ *€€@e Š­ГЕљфKsRУD" @mР№ћП›ьweЮˆa@„FbOŒёcЯwžCЯћќОчћIьa“’і1БhXiћe>1>3Lє…уЊЬЎсгЋЇpЁгO?ѕЄуŽ;іГ{эЕчнчє=p(ІЎы—цxYeтнTŽр{џdъa9ц&ёљЯОчCЂuВхЭчf›mжѓ—ЬШpFй•{@Ѓ.ўњэыЕ†гќ;UIѕ;RŸ=J  ЊЋЎ2сR#ƒ#&‡Ф€a"аƒ˜.iхф ј^B†iJПn'–”§v›6ЄЈЛ/ UЖСєprј#ќРr~Wžі”œ€Ž]ЪзСЯ1%GЛ‘‰aУјТЄ$~l}ЬIOЭї?M`|ь~BkPKйЃˆЗ+эЃцKNЌ™;skž= &(кhšu*ПpёЉЇ.vЪI']qшЁ‡|gчwњГ{}НЧ>eђˆƒ:АЧ,/Нєb/1‡ФGkюЧм[<#€\ƒѓЮ=Їїh}вVŠŽgмhNЊћЈАЄ˜4H Šљ0Ђ˜?Цѓ a<ЊТ|  €№ПЯœ—‚Š qe0Lœсwђžc~3љлdZ˜ž­ˆщ9и0=†ФєЁaX’%’ОысO‚Е?uЬй%J*)u4Ж=Їž ‰ДW8’.П4+sИi]‡$І7Ђqtcљ!*РФэЦНLŒљнГ{s?j7Аl7nмиlКщ&ПФTг2июЛяжŽ=цЈvёEчЗ;nПyВЩ9вy%ёœ]й~x@96Зэi†љMt№Ь=ЯНѕ2/ДЅъBнЫ(х8б€9wBiDЧwlЯ?ФЙMcI­‹џ“сŠiБˆуэњ <ЬХxiп cŽgќ?}эk_›1 $г)уЂxи<0{ѓ{PLŒ™1ћWОђзгŒМЖјпџ§пї†з†‰`^˜œL0 љMЎы@CS№@ ZдešаL|'mШНNrQзI™HBн†Ѓ@У{ю€FЂР#љ<њМћуbфn‚  Hє"љ1Gh‘ў kѓ#6Ь№:$ќfљў\=лє›T4 @ЅgT1Oeэнѕ7РpзЗѕо{зГOі4s дЭ3 у3RC"ƒд§Эш€б)яє’ібЪ8Œљl˜Їh­x>L3§I;Ц„SСє=~Я3&r=ОœЮлеHџ0?ѕНяC‡љПёo4ƒџг?§SћЮwОгўљŸџЙ§ЫПќKox§Ня}oТћпўіЗ›ёџ№AЦžд7€0Б4ˆMFbnX€аѕ9јюSO=еqRЦi™іcšнЈF7’ЈD  Byƒм3Ц$!’…Б™$}˜о(ФщG2&ОO­ŒРl!суј‹–веNЂ P5ЏЧXmЕU+ДnлЈTћ1c6юe{ОXs>џљЯѕƒŸƒ:Џrд§ 8p†‘›#Ž8М|C'їќCнMnЬ{і\Фм„ -MŒщћЊј‘є]ІŸ ‹GfL(О•”!§јx‡Iu€Б0)lАq0#ЦФ Ю#ѕIі0џwПћні§яП§лП§[ћС~0сјЃ§Ј§№‡?œџјџиc*`ќŽї %@‰ЩрwLz&žцс>PрcША€€!рР|b‡Ў30@ќ”&їэMЮDМћТ{ž‡я! PО‚n6dЗЫ `HбХy- !? Їg7\*ЊАмrЫНцSc~NPiiCяџ{{‰9юAЕш +Ќ0У€œC9ИРљ„ZŸ{kdў“™чЙ€<рO’-ЭѓwQёЛЮМЃ˜ЖлОЧx`МЊ?Q˜aM€€w D@дtЬ‚qhЄ.{=NЬ љœ‡YIюo}ы[ ѓџыПўkё1;І7~ќуЗџјџш1‘џ„Ѓѓh ˜ј> Т‘†Sиј=ПЫ„ ŠК ѓФ=іu Ÿыб!Сz"pІФє]Ц)<‘уŒЉ‘>—„„  ˜&441AD*:цƒ|T’›$`t€С1њO~ђ“ќїџї №І203„§йЯ~ж Сl&Ўщ7 0Е‘сž,Xœ”wq6вh1РТ'T ]7LЩTОьFї.ZˆH‘дFА#[дўT№%ќч§8›Tп$џ < Ÿљ\?ЁQЬЫОјт‹OЗЉхеЊ8Зgч’K.й–Xb‰оqЉЅ–zS€АІžЄ|ьz4 T™Ж|=ЩuёМ4?Ж=А#ё­)Sр?џѓ?'8З'ца›I?)˜a5€"‚“hTPщЁ<ɘ C€DЄ-Љ(ЩнUџЛвџпџ§п{ЬŽ‘ўыПўЋЮ з„џтПшц–р5p‰Йр5mУ<~?fH!š rП€ k& h š@wЧ"ё}Щ+џѓ?џг#$„‚Y)яЦŒiTъъo g€zFЄc’€иъ(^њРˆВЋОcZŒІŽ& МІ ФŽgјŸІѓ„kКV   t Ћ @э€€ NУ„ЛРY˜цЅq Њw ~ѓТв„Киuа!ТфЈЩ L>@rˆДЂrћnЊ#“хH+№кyr„ж$хЬ7п|S5ЈэbітєЄšы1a\gўљчo ,А@Hо, сˆУѕщпЋWЙ Ф€d73Угѓлю€yђ№ЃёЁ_ц!zpŒšŸўџћПџл3) Є„ЋcъNЋфЯљhјшџyjђr^їsЪСєПй‘6НэЈFБƒ  2{#Zdd‹ГЩћ>ЮР@ЬƒD0t|@8з{Р"€sСбр š€пцp/P7~ ™„%HLў€nкrќЬ€ф$Э—v‚аx™4#ѕ ‰Dњ€њ€щрЛ}€F!ь(‘Fl]Œ]иmюЙчžф ЖЫdЊц‡L<ЖўМѓЮлЬџf€wі‘nЈЙzЙh PPќ1$z2W1=:Е^КЩ[ЁЕwkмu ЃlOљНІ&тѓЧ?ўq‚њŸ№ZJBO4Ў/ Œо=Ђeї„>BЕіyн™{j~А’€zэž0? ѕзŠZ˜&мФР6ۘЫФPНЛ@тў‰8’цљD•CЛ–љљЯ>A[ !0К  з‰AFФ!ШnЎБћтŒZи5<3Q™ižAT€К(q*•{3€xџ-zwwX ™Ј€ѓК Ч пСДЪ%ги@Ў>&˜cŽ9ўj,ЖиЂ=U^UЂп“Џ ‚У–ѓЬ3OoМY€џщ€ія…ь1Ё eŠ^чпЊХ †щЉіЩVЅЅ&х<šцУЧwеЭ3I"Oђ?ўєЇ?Mа’чm2QЏЎ9аezяЃ%р”Мд˜аФJјЬ˜н Ѕ~‰јЗpр,<ХВр<‰ir1Sl% Gњ&СЇ›„YЩ РаоЇъ'L 5ЩŸ(@˜мб5ђ§.$Сhbдd( €HvД`€D˜ЬŸd‚БСљhT9Щ0)VBœЄSњXјд $-8aЄŸsЎ+мІ"Nš­дY’шЫф˜}ій{Ьэ}й‰4НЩ>чœsЖЙцšЋ7о,РєдшГі˜PЭ/веЇЕœu`jЁЗ˜Ѕ@<Ж|Bw1їа%Л§ЄЂЧЩ‡>вŠx?пСєнї€ѓРРєh)[„Ї ЭНђчИO4Ъ|,К§ндфз§œ"апА7M‚‡2Ї€Tж{-J-UKe…˜д,R6Я|2iQѕу ŒCt7)@s__{Еэ5nзЖѕЗk ъM6ZЗэЖѓv•ВyRЏБЄпIЎAР&~€ЄБуЩMBi„Ў &€ХJБЈaйг~(€d €$™ѓШс†щS,D:KЁѕП*AіИЦ#Rhйіщ ё]‡3RтЂr Ž:Z™DЬŒоЏ_П ZС›дšTS’ЪЃ'$рŒя™з лбЎhYшc%7Еш%™ЉуЫl'$‰aє€}’еŠ9˜і0:Рш@4зщжГФ1ˆО\ƒ–ШёиэF…ДЪd$аа  Јяݘе€%™ўA,!.@5J‡ЖVДR‡†@цCа˜У‚љ№  tгЩэhсў‹эџЭo~ЃИџ^˜>Ь?Бушѕжn'wTym_˜`r$<Ш‘zƒ„ІДˆдFсˆЄ$1(ЉЯŽTLЇ’вPˆЅ~PыЌy‹@Bƒ`Ўdbx%Хй(mТћ€kёCаЖњ6FсД{Ы[овДуЭk­5Ќ„ЪNНŠУ8A1 9­Г’ƒщГУtT|ZšЙ1пG вRj)н->Гў]o~€!’пЙЩ0э@LFз XD˜03œ›HMкрб ŽЗAkE“нˆTi3&”Дњ‚к$#nNЭ,„ШІй7ЭЫ†хiNF[Д“[ѓGї?ешФуnИW1кmхgxЌ}ія*ФXуљчŸ­иэ-эќѓЮh;nПХ_Фшѕ†їDГЧ™ЂЃМяОЉ…а7!@*# JЪpњ8&3 `~€9tT:`C@œˆд‰@Сц7/@hін0„фыIЯБ…ˆМІјн4BIСsСњpєН™€iВ§ілеМєі5шIћHq*>a“Vt€6{Jvs№Л@-OХ\џъWПъ ЈIIш0>:ш‚@2њ}пgЉN ќљЯžD–r|Є}ЪЮ-%РwE@аP“/Gt@i†€"мПфьMˆЬОM$B'‘HJЬ†19тяvџMж$—xAŠ&”@bЋ™xзњ№‡?T*д%˜>Ь?Бу#uŸZŸЦЂЄ|škІuјФ€eЎЭБп‘mHЭЇ №щlŒ–]vй7lНе–„є˜ˆЅl* =; г'Vп•єЉ;Б~€;рљюў№‡ y(ж7š^7#4’7Ёрœ4RЭš(€sК@Šам“ћьіЛДVh†ZџЫ_ўђЏ ~ЧDђЛуяcЦд7ц'Х sъгХF1AJu1‰ХŒдm*=›оУQ­1;TL‘Eь7v4›ZX&…ЎsЯнЗї˜џS/~Ќ6„ИЎW—-Л SU_њК— Ћярнэ…O~dH\|бй@`k–ПтŽcfЂ“šœВc‹‰иљ)уtЏщR„ ЁћІоЇўžšš œ~~ц*ЛѕЄй(цчШKcQ>“ДЎц;@јцр˜CФFњanš…ыѓцї€hЮs/*яfT `у7jлз\qХхvŽЂ11Ч4MO‹&Ь?КHz6‰ŸОж)N<Чь7СQ•П[‰ш†эђyш#vПcвХB]гќтуIš 3эCЖ пџб„Џ'Й'&eг`ѓњкƒЮw€ЦЎ;oгuGэЄNsЦ 8‰Юсy$;2‰;ЉхO›Џє№sdЋbаlŠъ;ЎMИ!LЯ ј€ љр@š@)Л(aќ4)5зFz$yЈ ќ)ЄПћKk‰Мб0jдШЖgiiц&]™;LŒэйЉъц*f `ІuёЕі>Uwlь8уЬ)ЦtŒ­Ž‰ рšўМOJzWк†ЩЛЊxРРu­ЌtРџю…ПJV ЩŽ^бxrURу7К€ыт{шš 3d ЄиіˆA’6ьO ƒЁHUоMHˆљwlцЈg&‹GЄ ‡j$€0#ЏhТ^KЈљв—ЋјЇ˜љъЋ.mЧ}X/䘧ђВƒЮФДЧŸxЄї=ТD 0KˆŽ"iм{šmќ ™}^'‰Чy]Gr,8Ї_ђ„s<b Ž& Ьžp љK‘?цƒ$–nz0щЭ‹€г “”№R* ФkЎ9ЄІе+dЧЂ8~ЭНЕршСœFе'ёcnЁŸh€IдIЌ>Œ;Ь‡mŽp~бТd їEЭѓ­[ТМ@4C};виЌ7џІїкoЂЄЧ'п щjо№Ф™џЧ‡Ђg<  $ь>4ˆžВ`в2№фV'ўšЩЅЅ№!љђCSРnЂ*q$ўнчЪ‹[Œ|жеdГ ЛьШ„“s0)mр‚ Юы}_ €- п•_єcПKmKa3EВпEv$r?* Л­Э,8Љ”RQ*kœšцTУј~7"Ё,sg$*{ЪƒгI8вŸ mРœg0Œ{KгвnЉБТыКэКы.ЕAчQ=ІOK3ЯчY9Cг(УsnЪ&’@г'С*Ѓ1НuJX†ŽКЖ>•мЙ УcЏЛ`НЂТЇz/Йћ>K„РбЕаnіБѓЃeТъзПўu>iшO„JЦщх]x.~Ћ4ТI’QЈ Љ ˆuС`Мі0у@љŽчЈ"‰HšYа‚фщœ0Ё"&Іъ=“‡gd+pŒh€„џюяЊЃљФуk#ЬHдШ$MJрH” ЋXTh yн ем  duХыOЭіM<ЙЬš\к‰!тДbIѕ^њ21вЁ8Э<D4€”cv~ае’lо…uЮiuž”˜(ЎХЦ~-@kЏЊ‹ŽжYiaž>†йё†s,‚!ОšlИТмKБ˜uˆуaЬl ’ц2)еNЙЖ5Jъ.†v-tхМО@ТD5яF0(OO‡0=šD#LRyџОЃйŠLJL?БAѓВ.шФ§%ЊфwЛрбZЂ ЩpœaЃЅ\Š8TXЯ™Eъek#еЪcыЅ‚в[Œд ˜`Њ2ЭСФCW„‘8Rќ„уŽlЧuX/+.ŽЄ)i}УЙW ЩСŒвРНa|„цˆАIWїF-MяG‹Ј“ ˜^’n.ќ^КЪ` ѓ%‚‚ \7Бћdfe 0 $-8YцИЛзgKBДьщ КmНѕ–•щxШІяіСO‰mТvйќ"нqcЦaЫa†YбIETxkс0xДМ—OО†vДVLZDЌcЊє"ёiнEЕOЈs2=9ћлпі|U|K’ЉТє ,09vЧЕ›*"•Ш“уйчМЪ$П‘ШSзроS$—gŽ№ŸQ8уi7Ф@€ДM"ѕŒєpLЏ4„šK‹' ­РУrZ’rо4јpќk8ДЗ§–|xЩ2Sвње‚%Ц"Ф$LIџE4юг9йQ„lг",ЏГГQЗб( N#ЧьQ@{ŠэNzЇ4˜/€–ˆГ1aFѓHŒbџgoзв`z€Ц ›oЖi/З!MJмo oтO‰Єяn~†OИЃ{M3у0Х\ц<оќdECД6жРч@™„ О“R]яЅW*O­g’Ѕs`ЇtЖЊ‹дчЬ:фЧсЋђОжfaќЅ—YКrъIэуŸја$sR,g5ZFџžиИЗЎрYЛMlSƒ’:„:Юp‚ЄŽ"6іgwЫ#“'`ь_ Ю.BЌМсA=ЈjA,лŠ$•NœJРE8і0iБlс)i}#aDФ‰ЩC€|РЩB 2ї‰№,\:ю№аВ $Н”DЧшш™yŽГїa6(I— Фяг $б€TЦ˜Њ@їŸ­ЦMЂж#>š<ƒW Šˆlрa ює)tэ‰хр[sЊsж=;CХ{ŸЖэ9bX…IЬj5&@|3яёРЃпї>s ѓЄЩ+€ЖŽБё]Ыы.ј> ЭНRжпšxЯZГыЂIюсЗQ!цпcн&0ўG>њvя}wїђO˜AЧ}x™;7єЂNhюmo{yћЏ€Сžь€[œ†@+&ђјЄžЄGтcџЧРфT^ЬoaLІ&у ЗдЂ„@Lgя"Ђ4ўрŒѓšyаTПЉ„cOI˜V@Щ„#ЈAŠ~0}Ж*Є5еš—?;д0a6FMЃаь’ŒиHџ'$Ш ̘=уњіˆ­OŠ›ч8ГCpь{9#‰­EB SrŒN hќ1lиавЊFNHjJm}п|ЯEТYпюvpн­Ў0(†Mf^4-sžќЉДЩБїyЄy4Б$р$S3uыГHФG{›šА&цмš3M˜hю‹„їG !tд~€aMcы+œКњъ+ztјБАДИЋ{Я vCO>=іиНjOŽЌ9y[яМ'ž|Д2„šqЭn*pќM]г3IцЌшfЦЋЌъОO$1%ЉРБћ"§1FЄ~:хXhAM„Я-- Bb;Г SФˆрЅOЂ7СЧuh/ЫMэЛd—)i}C!`ї|o„— Гьc˜†&…ДТ’aќД>ЫЖOˆ ГЇsƒ`|’ёeЎІыё-ЄЩG}`рюF!)wнgJА™>€6$ сб)щ6Ђ€DЌ№h"…и§Ј”йв^КyЩіLЌ>ŒcЫЧЦ'ъЏЖ‘WЫ‘-фбч—]и;ї}яwoэiGРЪ3Ж—“л^ю4„жМ6Џh#ИшtЦkRaŽQ-йЈжЭf›cbЇ&€„Рќ8M40П0ћž•єJ@=Šњсb˜T|є‘‡іl2=щ•ЙNIш $Ј{ХРˆс!Тxd-bI:2BЃхШHБџЉИщ в2:ОŒф5а€чbЄ~&$ЦŸщ”|~вП Ж€Ыœ;*ёхфK@Т€@йѓ‘ўš}L HzaЛDtтХ7ЏТZР8ЩRю7`ж•і€В[_•!Эдбч5рЯ ўћm яљ,CТq˜ѓ$юЯy:ѓЄœз9h')ФЫkRœ„§Эo~гћ-є$тdН}7що€'qўпџўїН9Œк_[ІП\pіОчzйl'OъЫ=‘‘ lеv OЁъžІ№БіЬcs†ОЛ€pГЙ3W АюнMg+WdЦ€ZИ_JТ‘ХЅ‚4бС‰Ащ1˜ €p 3˜ќxsгЖ›˜bšДїsOЧп0ёЫpHЏѕ2Ы,глtbJкРФ#’$‹{СЬЄ  KK(ч[LЮJЬŽ`ФћуLЪіч@€кч9џiОt0аLU B9анx4jЄ90HИаQјSˆe;0LЌПˆ,@1ъ.ЌКъ*хиВЗг/Œyбнѕ& ъ@ЖRt1}ВэZвЛ1eьиМюJ№ЎеО iН–Y6rqMtI"љГлT2н0аr,h.Д;tзUёхttѓв &еƒh2[в ѕ2/Р€z6§'^јpЏо$ѕrаПљVЩI(rКЂOЁj4їтKя(:BWц/эУ}*н}#­!šZuџxн›}LщыfА )$ў.#кS Г€ 9А˜›#у'S3iПё9|ВTЎŸмч[OПЃўрƒ•ГRpxyљ'&ѕSЩ@ю Ь>єA“BC€8аlугˆSиTїєЫзСЇєƒЛ§/вžT4Yь8шЧ ‚SљFZ9Oˆ,?!‹}<ЌEТ„€УШц˜?@:n_аЕ–зZњ)isR1rˆЮѓИW’Уњ ##xˆ90 MЎz,p˜@,žцT’Ѓт$†љIЉ/ `0&щ@2ћ?нp>т;'й“ћ ŠЪ/э“;/ФVъфяН иЉдWыХдp}щОн_ђ0ПШ BLЂV:;gkv€`N’Їпзёз х%K/РЌwТє€ {I  зšьйE;hIД7ŸaBx„H˜:™IфJx-в?Э^Гїƒ5їкzY;NчкЁўЧЩЧЗЉO–„ˆ0№э нf?ЯA#8Iwˆ0Йч˜Z3$ќм"АCyZЧ‡+zf@њZ\вKИPh у˜\L–EЂN“4IИIФРD :Вט}@Kнk…iІЄ L* „R‚‰ГнxZ|a~Dщ3LKz[8’= ƒ‘Нž1~dњ аф8ьРg>ћЩ3y<џР%хЬžйН€‚Я’!Xs7CР,RlвЎ41‘ёрšLj­…Œ3‹єA€йХ–ТГaІtR1Q€Zї}|я?Ќhх•і\ŠбNIш Є*FM€O" їBРЬ н‘ъˆгрЄЁІYМДwNgр§x&ИчоK-9S@фЃК1qLOBЫгI™НЮЄђ^Є?ИВ+qMзBh%Іf7їЊг8­\(3/Ќ‹ѕщзЯ~1š—TsbƘm4ЄЈ§йZ=ŽA@‘†ЊЩЄDаоЧИй,6`žуяH”gЈ$ЅП.ј]ыуH8 ~И_kEct^GАОйєƒЖр;оK• зИ.|ДрSR?ЭZI}`IkЪІ,шѓф™0ЏбмЙяа\Ž˜џ€к—hUу3g<'`еŸВmšВгblнєАшˆ0{Ч“x˜уЧћL-ЦL‘F‰3[<‹œЭТФ'P у=­ЧsxлgЏнлІ›lи­ОJХЏ—я9ћњњ ђЛЩK *Š #&D”А пƒИgŒ Х}/Rа\Вы8&кМ$4“к‹бйуL&69цЄ^’іi J]cђ0ЕЙУци}d;0ѓ „1M6Е>йHФѕcћЇz€Иg`gо='b%ЩЈВќ0ц"-И"ЙнC6Ъ4Тџ Ѓcpя™;LхќјЂx†€9L˜€ЖDѓ№ЇЃƒvРмbюфжЧ‰ышГša6ЏЩ›?!9ыFз˜pђEъ'в,I}y(’†фO ЭSO9nBы:ыуЙќNРдя'Œi~КN@кŠѓЦЇЯxP’хЯйŸŽ$#щ’№B]ѓAЄeЖЂR Ши"Ac3R‹I#L5жї“`яЏ… ПЗКџ^sѕeэЬгOš„I'–€1гЭ‘d€ЈЛЭч$m$Н{EфЫћTyЯŸ}HbsУмqLƒєќ'н#сŽsтШц P№ЬХЈлй†Ъ|cnїЇ LŠ.($Ыаѕi.iНюй5Э3Рѕœ€Ыџ]Р@ 9мЉ0МNЙДѕ˜AЧtЄб0$FцФ4цЬќГщeр‰‘а)ro]HL=е€ж#Л—ьр7=5Єебт€NЙq2 гЕЪіёП­МzКк‚пuз­Х—іњYXgŸyЪ_CF­=ЄЇVчОгЮёа:HZЯуѓ”йЦ{O‚zу'§Тcјьќ‹АS*]€I}я#|ПЭОЧьР aS ЮясЙЭ …уГ3›„М ї• <Г#NRvљмѓ’ЃˆпђЛЩћ47Z@њ5˜wDъwЄ љЯ:dg  1\r'0k77?y>w?ž“Т” Шљ=!;jэi`Йnœ…бКрw03šH(в?Т' I]g%ZJynі‚H}ЉL‡Ї€{јkРzR_ˆ4R_ЦЄ4‰hв„Ђ…Єћšh+рdн_їО=_7 єЌ‡љ,№§ѕ”ТђЏычЕЈIъ'bK{+Dž 0,2FВPTТ‰и-ъіAЯ^}!@ О Ёc;Z$9й[ ЪПуЕ Ч“Еgž}ВНчНЯЖ|№НЯѕв/ћ‚‚8ю3Я>бS…IELgF ѕїgŽ`Рє6$-b6ї 4ЬH†ћL‚gПЪ=ЯNФ]‚ѕ=цћcxІДЏ6ЇЎэ70)Fv/ЩŒZя=Ÿг:"ѕгІ=РNC$?щ‹!љ<ПпЫN:ЩiриDt€œк}š\нКb8šяЄ{3Mи‹Xp<ђi`_=GцLФиКFДфŒoˆбг(Л€Ž0r Й\Ы:D{LЅivЁŽЩ’Z{‚z ЇЄkЬm_рф›”д—&-$н€!ZŠ30>ŠD€p€yl~у[Љy›Б ЄжЦi№˜švЬ“2ЫH:Ф-\JЖ€Т˜A@gNL’нzx§ РЄ„sЃxЯтcЄŸ˜D“LRbˆt)&!1Г%@Ю…№Ч=б8мƒ{IwbПЯ,с№sЦ=щхї§n’WВЧе8%Љё-*„dВ}ќ%$"ч—пfяЧŒJ+ыЬoЪpiЩsЅЇ@MКД&Е;н„œА;Щ„yhmiZш Э97;ЧГNMa2ЉЦРo›g ЭЎяfИaIRГлNKMœЉёЛ`VsиД0œk“7gY_ Eт9kF`<рu™tBЫ[_Pt6)ЉЯщ,=p`џПёXGТ1@‚ЦмЙЯT а›ЯГMСo^W ?Ѕ+Fк-IjAйЋЉ„‹ЄH Ј„Ж07цŠЁГ+АЯHœьŒщ1$&K`РŒо'0ЃkaЮ€ ‚Жи&<Э(€Ev–I.xвX€{‚ўqшЬ=0 < р@ЃнŽ@hSЦ!‰ЎD_шкњ6]5­Оjлcї'0ўЉ'Wы{ує]Я=е—tBWю%•Єжн<ачЇЙes™) хзѕѓКБ“вО*Q€xШ%Нd—єg7љO,aФСƒI#С‚ЯHaЬN§tєЯ­Яг' {X,Ÿ‘4ь'€тu*|пРˆю)л’a~а(Ў`,ˆ…qЏ4‹HўЄ‹ІШwв цџЎцЩvт S9?uхР+щИЉeYEРЌ˜ЯˆНO#H;vв?yЄj Ќѕјв8VœŸ)нІўb*sdЬ­Фї’ќ"юЕФ%@gн0N€c/6Еg—5F’АЅцsХ]ЭЛпѓLћШGп?сНпўrѕЄ9qОa@я[ ы~нPfŠ™gыц{ž ГY#`GЕЉ аІћOх zЄqfЛКОАиb‹ЕЅJњЏ5lЭЖгліJвvVўЋ[-ы<›уwНМСŒпі[@&б4’| <г-ŽЩLHд§ќёue№)§XЅ Оƒкš–жьі’ѓ )ЈСliД@вљN4LЦёЧюwФРI&Ёйп˜г‚:гSѕiйJЬљЎ(ВНВ .к…Lџœ— ,)Цй‚9ЛВјNтз‰)cђdКaж$УЩ“5˜X=‚Dhi…†№’[3IMi™N~ЇЉJк†%д—HFgnБћг›Нљi $mЬ3š€()Эйh .з1RњŠ@­]КщЈє2ницj ќ€hCцѓЄЖ?`<ы  ВFЭЯЫДМјв'z}єЮ;ямёaС}{]žЏНцŠ \ћ7,1zWРH)ю!QBЬЮЌOвЏi[щЦФL%э­;MХ_ЖчB[i’ІЎ}3їоkП -cњsЯ=Г=0О§W@эЁw<а.Офтž9dЭE2Э1††т^Ќ[RŸё Žі'ДвŠ?%ž|]?/њŒЄФ„РL0i…Јнxbџ/Lэdbv‹gЂ1wі$щTЖьЦдиЄ9&Gp>УФs€™`ЂHQзp>Щ4˜ўїд~#PчvŽqNв ’фcС’ЄЬтœJ+s€р}Р"DЌ>ыЦ}НŸєbЖОky3ŠЈЄПФЇEЅ’ДАЩлчƘ›@вG#HП€˜œprŠTЌWЖKc 4пO{/їуО0^@Т‹фї ЬЬЬЗ$ХА.Р„Ч< ДлnЛtšdоUZШбгNkьи—™ыўюю-ѓЄ—Dп0рј$™ž@Sщю lS_‘Ž@пZб“aш9$&„ЕШКгLЦю[ ”FgVŽЩwм2с™вјуСя+mэв ‘Рj^н[:(к-,эл€Е№WЁЦ; gЌ<€RUО.|%kM^4U0qюи’ЅЌ‘кщ!InтуљЧt L 0,)žэ”Iю} ­С‚:Чч>…Ўэ\ŸAxŸ‘ю‡?Сї]?™Мњ$:br/Юuо#ЭhЄЗ{хcHV•?ЮЅ„n’"LŒ31ŽЮ F ю:$ie>йŽ$„їЃq%A уЇЕ8фЯVc˜8љќтжй7‘€љ-аа$ј!’мтhЩ3c–TlІіЃ%Vэа ѓPљ1ˆ\њѓk‡&>„IЕг:ЖвКгKOX—džќV’}ˆy­“пЏ$|—vцs!YG к–ЕLВ5Ndƒщ@Z[K- AТрї?pЯп„—пљш; „/я™Ию1kgЭу˜vЉіL? €FаЉ{Ущtь;KбтŒU TRъ“ˆ&=а›цЄDTЩё9Ь=t5С@‚C#’н{Є3ЦKСщŸ­УŽУЈ˜ЄwО#bє9ІŽэoђhЄ}‹‹ $0{2Ўh ~'Іѓг/ѓ#вј>b В%CЯГyф#UЈkћпgБY“4Cr"&ФшН”м"Ю9 рw^Ж ўй&;yI,ТРˆQЖ?`юfЋ)PЧ№Ды.Czз^wЉЌ$6лˆ9Яk}0Ebвqz†8yГ˜П0Ю:ыŒьIIНѓO>хЄI6бL}НЏгO;БЧdкm{>@ъЗК€IЬ%ЭУe?GscюDZЩ0Д–)Šs6“ЅŠаzЦДsmacsдѕW|№CЯзZ=RПyiOЈбЈ№CRТЕ{v}зcкkыˆс­`ХР2ЕЉ™Ш|њюx_вŒE@яЁІВ“ЄЖZ<Њ&TчiІв’,AXФD§dы’а)нДˆЄJД‚d&жЙ!Ѓa114щЯЉšqšШЈNqblъœsвaХbG›шv"ŽѓУGэЧ”ЁYЌƒJ;гч)’qNvЄщ2zВ iˆЭќ АЄыІg"bЁEљL8c™Ѕj~‚Д!­LœI"Щ,МЩсqŽНIе1‘L~RоЄc4ЈL Ї#0)mб0 EХ—Ђj№dцiЈвЏ/yq^&g>eТЩЋші§їЬцw? їлsѓ?ђШл'4бьЖЮžXWŽ@v6цї]Pv5€tJBFЁ§yVчћшЬ­Ќgќ?ю3Ž] K9b>пI@2єЌQZЖ‘рй•=Ф‚љ tbој€7АжЁgB+iэю;™Вx"Y‘1)­ЩЫЉяЯЯXPўsœOPXЬšъJ•hBт&ў‡ј€€›нnL”ХД‰`j@@bcиxєйХyг }!(еЮ„z3,r“/= ]$Iъ% €`ќHyр€иSпŽ™“Ѕ…ЈтєLђї0KђœЛ? 7)”B\цƒњMRУgЄJzІŒи{ QщЉя†8МАЕC\П08˜ЈАlSЬ&fMт3нHЯlн ’cЗмЗчHџ#нЂйtUUs„љ%ХіН|бEєhЃoыьnWєвГзЖ ’г@еŽ@vЏц,с;k№Ffs“И)Яb]’чЙ @!&Mœ‰n@оЕ<ѓFЂЃ9ZгЮМавп!žЬ:“…Žгr,)Ыiš$ЖєW оCSуMЪ Ъ ј• @a)"€щГч{5еg’€HКд{“^РšcА7“ )NsOи&€€љ}–юЉ о~з0h Ži-–<џh˜;v>а№ћоѓ9DFоKСHRNуб–C*ц”ївŒІDЪ#^G’"[Ќ#(DŠШЬ "'mФп1Мq1’зьy\ѓэїbZŠб,€†п№]f@№yВ4{4[—YиУ ЇyоdІw‚ѓЬK"=ц ИŸ@ЖЦBSъЅ'в диRРј:hJш“Ѓ‘$sьїћ ›ЈТьЉa`tkgnLБ$VЮIŠ4gнD’RКžм‚„ќH{Ÿc|ДG›Œfˆf"D"ќЖgТ‰*ХOсЙъН џЩbJёД*BЁњЇю›эœьЖtAEˆЩnъjЄдDˆ+™{Д Ž‘1НХ—hтш=L§Kž@ђ 0r˜ьQГ§iайљйfЪkc OqJ\“ідлЌ']вх8vq˜"Еa*в"{чAxв>€0 ЩТI—=? >ѓПї9Tљ € EЭdgfр‘vгц;ЩF’Б0Ѓыdї!NЖД-У,Ў•Ц I\ tїˆ€Pг нrКЁ3RМЛaЦФЄ>“%ŽЫЃћhž•АА˜cY[Œb=1В{v?]ЃgЇј2ЬU2“Ѕ˜ЭFzтььUGZЩ‹ЉЛЏГЅz€Ži@ ЙЉš~сGƒЩž@—і• ‡“h~пЕ™РкЄD7~Пeрьў“M@’ЭiRMЦџ‘Рж.ЁP Yi_ `JRПлR+ЉЕ Лa4šRњџ%З3Ч‰&‘Qїъ}ZZsуещˆф;нќ яь1БgИЬВ0О#J€FДЃ_є—2уј’Jю~’5-Чp !ћ]яG‹ЉяЭXе€%e~‚`Јэ$Ž х!eчyIєа<ы$Ў…HЇf…œl`L*іьмиз&&a6 ˜NГйЖй$zэ;~+лGa žЮ5щБ–и}’t’Ё‡ЈПХ%Ѕ1 Т TаHXf:=ћУРТyToŒGZ“оќ‰ѓc~џЇIgЊђ00ІІ% @sФ™­Ф=˜gѓ h’М†яn5n-ЌƒћШйяј0!8 yсгР3ŒD€YЊЃ8ІW0zБŸЭYœцuRаэ›?1ЉпmЉеQfФ!ˆ™sЬЯhщЄ`JRП[cпЉЙŠ*э~м : ХЂ “ѓЎ9iЩЇ›Я}–врn•`:/гФ0=кГvЩˆџ ЧО 7Оє№ž{ЇmŠ ЙFŽ@@ечю‘ІSЯўлзЕиgJ?VЬ№{“ЫFЅЪ˜HˆЈч s‡ зЉMwnЎщ5щыЗhю‡6Aq>[Ю‚Їw!pЪFЅ€Х§RещРєЎX€Я 5œЪя3„ЧhЪ‡@„ц,>ГAкЅ `ј˜#I4 у'е”Bы陉РРЁ(d›Ц Ў•.ЮЩ piѕ?ХM‘Кўw^ДЈ”|OЬаЗ‘Іій“ъЌcГ—юІš@”`>УDŸ$-ХIчљЭњH Ў9‹=OМЙt‰л эZ ˆNE•4П‘пNвN7 Аt Ьn]<Ў'qB~OšТФБыќдždGi _~œЋ!Hь_H@7u)­­’1†A0gКЩІ™FоO3PŸг0lв~A2§RщЧ ˆi€“)3@xHŠoТ‚$0@РœЎ… i ЎmaНчГ4LV’xBГi–gБШžУѕВх"#§Ÿ 'Ь ц7Э•ЯУм)Жјiž’~ю!^цn% uI@-Nc4Ѕ`в№Јџ|4в?=I&‹ыђTІ”9цRz;‚иЊ.оїлœŒ“в&з>ЛogОРœŒц†`n0]Зькkѓ›}бJ€+Qš]НК^РИ3 †а№ЯZ'*BЬŸзIъ I5Ž)ьїаЭoнкWœІM9цNpцјK2Г@BТJ/&Ž‘ЭY0\Bl10ƒїЌ7аa`VЄ%˜#_Pп(@6ݘš~zGq№_iЂ+цšœL9є•–уEG‹йСкfWІД[Ч№Ў•ч5Џ8ЃІ#FuН4‚‰ЦсhЭbпw5гы?EВ(“-š~ЙšŠлМZc~#ѓšЬYїY|ђЇзСЇєCu“ )B†Xq :nо„&С"  З™ИtпIIp$1fДь.GLKЪ;у{ЃG#HЮ>эРBRџœу;1!iю№01h (Хa-„„ЇYј<ЁЪdf!„ё6NбХЎw-‹Œј<+ц4/Ў“њђHќ„s*ѕ4*Ф`Ž9џnRKАљ#љг ёg›6IYŸdabL\ЮЩь3@ГHЎBŠZHЁ˜1˜~ƒ&бm &3‘fB 27} яІыЇgƒW[Лѕї–~џ)ЦbrвиэIЌЂЉЄEZP>Я|бЦМ$h0Ѕ€?]yЌ5` нœ4‰‰щ“ Н8$H@X0%ч‰Ž$СбќXчдW^x…†wвШњYІ$­И„цІФ—Џлч5‘kЧё‡ ”"q›‡Œjц2‰)ўС,ЉЙЧŒѓsиaў”їz?6НХа˜лыhьu“˜дK‘ощˆйJ€†Vї… т›hї€……ВШЎŸ&“˜лТ DDф˜]p“‹™уžвЪ[d#!шsЊ$чVТMiTi>c›bЌЈ§ьСT—EхOaL6/ЁњGНO3€ Є3ЈьђвS §Rи’p iшŽCе…zŽ ]ЭЉЙЄ€Є/LЉ‹Ў]—[v™ЖЧn;ѕЄП]’э$fHВєЭЇс>“GA8ХР'@ъЃYїHp ‡˜iЩЙаё-“„:yRЂэ“' В оKБQЎ‘Ь>МгХ=ЃnCРNРDfoУ(3ŽАdKЇз$цЯж_1dГž.@ёј‡Бвј#a1Œ›^€T9Lео1ЙџБз0/&Ь9ЩŒц€8]€@А`~Пѓ ћЪЇюhyв;;ЩzЯэ3ІLР œјŸdђ9OКmœ€>MрЈлЄTТOЩч‰Иdу•tNїŸЈНlџ.1eW`ъОЕсќL(аZq"К$1љ§xЦНІ†rъu[‚q$rD&П#Л§bNDMє[eMJъьгIїЌъДѓОї?зЛъb^ѓfN€2&ФриD;Ё)e›Д˜Dž!ž{Њ6i.mЬд„}“’ Ю88уМ P$§8ОLо€H%ъае”Ѕ!ˆ5KЕ к–0—ТЄ$"е5РьуЧ[ъhМ15щ;#XŒ‰hadЛ‘<ЄgъЉcŸc иџIЯ…Р^cN:‡iуСГCm^џ8 Ц#Œе“ћ&ї=GšC|ю1ERld КŸxђн{МДй|"Њaв=“gЕS€fDЛш†г09ц7€ЇyDаЎ‹№вЏ?Q€ЄJ8“№“ Б§Ѓў“ўœH €Щ`X/Rˆ6с7"ТЄ%t[‚йўкѕм7­-Х-ž)•„˜дГи} ЛcŽољ‹,ВpmЏ5ЄЛы„ўzЇœtlнuR€?єсч+GскžЩЭ КKRђВu[дЬOwŸYї$vЁЙ˜ I.У @$U}йк -$Ы1Э;1rHО qь%<ѕ й7 AЬГЕFДSt‡ОRР”JCїѕёO~ьЗЋяЛР5Џs嘁Џ?д‚\D‘14ЄRьќOЇKЪЎ#цРxˆŠCнЁ"“Ю˜6€†ž>УШ3Ьч cВ“0ф)ŠC1mЧSќ“§рЈіi‘$Iсžн›ЩOY0‚шzž!Пя`tФЏsоwЄ{&ѓ*щ8HЯФоЭiQ’n§г§Б#ЄxўгЉ™TЁ`~ŽОєcдД%л €4ѕО=я8ьвP„­Ёi>ц„&Ÿ &Џн'ѓmєНѓ—Љ­ГFЌНVЏ“n*ўЈћgŸuZЯ-еIїю{юœАїbšnЄQJд~Яю9S"L‹СŒж­з&i)‘ЁdŒM"ЉСЩ гЇУS,љ#IANКЎѕh?`ѓ“:0?iмЇ­љVж 4IsЧќш"ЙяxфЁЖяѕлЗnмрO#оКдћG^Еь 5ЗѓMЂМіšA-№УJR› А ŽTL9п&оУЇ( гѓјcжЄњЦюw~ђвЊЫ9P1eРQязЧп1€ э6 ёО“њL™!ЊVю C~ЊМї-"аˆЊH{ˆР{Ъя†@Џ$зїЌišm&c.§ К§ тмє @Ћяn:TљУ=№Џ:щžQ6ўеW_олЦ-ЖўЇ?ѓЩъКs[Я/9июЬ#з‰‚yhfž šЇtјE/IџіОяZDPФі­UЗx+к[*CD$Sœ~оЧјоOO~ŸгА’ H’H“Ў@b б`6Оаu^З ]Ќ4\\иЩжЦ– XцЙёЌЄЭФ§iз}э=ЊЙѓxоЉл}5’^ŸПЫ/ПИ=ѕєЃе_OпПЗн{WmVzjЯЬШŽG(хг᪘SžЫМLыD/t м‰šVэLЯd;ЪuЭлd'!LьЙ1!!сћqfг трM7Є„„Эk”M\™UЎ•ћ$шЬmН{ŽёљўНѕwнwg[яЪхлЈo[<ИJлфЮmЭbўGЯбЖЙoѕЖХ]ЋvШ‰KŽ[эиw\эфљ/YэдљO_zщ О‚зNЈz НцГŸ=g‘Кmі%ѕ>v”IЕ0ЉмЫ&iќ‘`що љЅ@Ъ~1<€ ^Sч˜L(юМј \' Aгm•tˆщсГnС †Žѓcѓ],чЇ]І–KПЯ@іœЗˆЉ—w-ЬCraL ŸюAiтмJГ ™("Х($+;q!цl‚љS€Ј’ш7­‡ўйЯ^Л.ц€Ў@TrmЛГъž6gC'U#ЃxлГЗaњцћnЊхм#Рўx@ в=NНќЏЉцM7пPЬ|JЏVТ}ЅоТ{NšNr|N+СPжЪњЇбЇ9Ф€ЩлOТ Iѓš”{c&vЫЛщЮaђ”рf>zTt рsb=ГІ€8lЭ ЭЂsРтšh5€ЦЛNG4PП§ ’ќЫЗ­\Ѓ ПpбЖуыДЫџ§ЌЖЫ}#кІзЏм6НyеЖСU+Дu/_І­uо"m№™ѓЗ!Ї-ємxѓрЕš№+= 5tЩюЏВРœŒŠ•ŽР)ŠmАц s˜2y&FCcђб0>fNV`Rr}Ч5L:dMbB>йDТ9й}иТPsЛ9ЄПЯн#Isчљпu–ХDLЄЂKоЙХМ‰ГПн›ѓbКNР`Њ„š\У“dˆ–*‹СYВ7@ЖЇ.ЧVуkfP§ig˜Гщ ШЋ@pЎa’е™ъЗH~Ьž…ЮuOЙOG ˆ…{DЇлIїбЧ*™чў{zћd‡bŒЭ” ƒR• —ф.Єr’*VЈ№й+вЇЁцЗоzЅOі|ЙО8НѕIœгЧ7уSщˆnSПŸъ>ы‡љу А†йQ:р=ДќћпџОЇЅвc"Лз8Л@hШ3šџ›oЙЙmwзШЖЫгыЗ>М]лўQэ„Явnљээиіmg~Ѓvvzi—ЖЩѕ§лZЇ/иЦ\; myЧjmаI ДшwE˜ўNТzШkт7il\j%щ˜$Šѓ(б€tтС\iН•І ЕЛБG04†щ˜цŠДDL83€ъžЊУxє“1ˆ Hl™dwЩ „иX‘іЫтИ/ “]}NЅЇ:ЯГ‘ZиЕя'%HъDF\+l’#›_"VЊŸcTьд Ї8ЬщwыbДдПSхїы ˆсЕцТќтѕˆЭo“АжŠэё˜9@BzЎБГ›БgїПпЧlLя=УН'sPЩИсЦыJЅ?Л8†kАёгŽЬsšŒЙ 0Па%`АжшЃk’jSѓлб›Cї@ХікНc:ДТ*хК)aNˆ-‰OжЦкEГKJnŠr’qиэрyЃ=1Yћ˜P)vпР& oM˜kё3Йп˜/ћ_ЛKлюБ5лИчGЕ}ž_П}zd;њЅmк]КБ]њнГкСянЎmzЭЪm“ыДюкvКxлђЖСmШё Еч/ењя?з.у}|гпЈIО-Ѕl`*>bЖxLн_дѓ8s:•šДMБMBrqfw ‹щu!Dѕр= шR DњЛnі6И8/Šої^њХ{Џ--Рui4‘Єќ:Ј%љ'вгѓ%8bђё;Лі~ЧuSoŸи5"Œ*РТ№1щЎ4 Fђ’4)`сЃО“ДЪl ;9LEjЅ[SœgИД 6OЪГЛљТ(Оуїbл‡ЩЃЄd6к€їГйfЖеN^>mЇиШ1aЈјќHB’шGИв3ZR4{A˜/Œj^вяДХр@>ЩJюСч„Bš€˜ƒlЕЎ[Аы$qШ§˜пњ$q уК~8“{”iзAO|ю• HЩєД†qІAˆїЬЗyAцјђл/jнКKлтІ5кЦw/пvz|ЭЖяћзk{ОkTЉџkД§ž[Пнјѓ3кi_кЗ ?mСЖеMЋЕэякжщЇšяRoS–Šб˜iŒ'`L˜ј гmияёб@ф!$Uš$ЗЦцб§gЛlŒяЎэ3ъИH'3!„цЈјцк}zДЧ єћЎуўК&@ƒІjЯuЭ ~7ЮЮј`œKрp$ЂMBРu0wT§nН€їаNђў“9K`Fћј‹mчпrFvбm“ђюoір ЖљCƒкЈ›—i#n\Вї•=к.OŽjћdГvЭoЮncŸйВћљ=л™п>Аm{ЯjmГњЗоНE;тЃлЕБя\ЗОb@[эиЙ_*Ž—44яјарt€чS(тЁвь# 3IЄСаЩ$‘,iU1ЪZЫ&—щNkтRSŸ†O?€˜) Šк–ЎС˜Эт№о‹Ѓ(x/ Jљ#€АA\щAˆ@$щб ЩŒ'ЄЈ”Є7ЦПРЄЌиНЇžл‘М@Ю=#к€ЅѓЂFb:/Ю!}hRйвГЄž?v>ХЄ˜Ÿр~-Hт‹п"БёЉхL†Ў€Р­…пOЄС=Х9I“pнД УPвЄЭyŽ˜(цЙѓж-BЎaюКBц”f$Љ˜4Зш'sЯ5SПŸД[si RЅz nНcаВW@ш6ŒЩgpo]‰яћ„‰O˜ИЎѕKPŠ{ќсЛkПAЂŽž)Ђўи‡кйWж6:wH[уŠyлш;—oG~nџvќзhћ|лvиЇwn{<ЗqoќБлШђњЏsйвm‹лW+Чп*mпїlдћШvmЯЧGЗЏXБm{їА6єŒХП^ПЬј<~€щћW’юЉЭN—G ˆШГе†СœдОиє‘PK…uЈЧ]@„Б'SПM*Їј&ЭBЂ)№`vЬD ЬžMB€Pvі§ь”z~ сќ„+тіНЈ“‘иŽ‘Жрћщœ‹ЯўDžƒџУГ""DЦDдййG”Р\pšБiJIнMбŽфЮБфХЇU9blls„xЭ!ЏЗsГ%U:хєЮяЉ$м'ЦŠ#Ѓ%сœЎЄ'=_|Оƒ&в=ЩГ0’Ÿцићш$MY’08'Iжфx.&†J\>е†46@кэє0|ˆЂ)$ЖЮŸHР:Кvr/’s‘ЦŸ4‚€€ћ№Iрr]ЏгТ‹ж?f]РРg€&#iСќ7@зћ—еў‚лœ9КЌ˜џИїŽnыпОB;яЧД“ў~џ6цžелvЎнŽњЛБmЧЧJгЛЙ[ћт%к*'ЮйF]ЖTћдњmЯЇ6l#Ю]Вчиэбк цќЅО_Пмx?€ДсщћW‹ѓ9‹эсLB*Ђ0B€˜пТЅхvjdГъ8‰ŽйЈVЎT*}бbЏЅЛJЎЭ™§FšŒЬ™}ўт№;)?і)эЛiC–6e8ї№ђ{‰ƒЇyтєЌž !Мдї'qбЩзЇю‘‚ˆмРм˜іЏ|bсltЭ;йШй0€“mЌ тLОь"­“3Рœ9ЖоzыЖшЂ‹69њ=iЊнц#бL\/хЗЩQH‚R|жЯ§Кo&{ŸЙТїуїгБ‰ПЧsЄ'ŸљєьѓoФGBZЂ„Ъ0ЈяЃ @"$ЌЇѓRІNћ$ж;& НФп3%о|ыJXIщ ќ л&o yqіХЖVFLќŸcќfРBg_xVлђм‘mГ{WmўлбmџOTчэЋЕžоњŸжЏэјЬШvЦ?аЖКpлљБЕлўкЂёOћЗЋsZЛэ/ЕsП{@~іЂm‹›Ы„ИqЕЖжй‹ыИB…jLЈХћІ‰MFi—0‡Х ƒІё'&У”FvЪІœЄt}L4л Ѓ&я›ŠЕЊ Щ/pМё†ык>{эо6пdƒ6b­AНБёшQmћm6ozЬ_vщХХЄ/oxaЁ,"Ah щd7˜ФЄ„Яќ>bD щПЁIИЈїЄ+bЬо˜(jjjє!>цN‡RŸ МЯ&еBАœ`цЫяhйМнPaТqZˆЭМЇ‘iтвЩˆj8 5ё8—4J0І@Єa"ж$іАc…Ь‡<~ ц…k‹Nјœ*.ŠbM3їЉЇА"€щтPП^xЖГц=Хы=Я†‘“Жэ5А3?hг9бh‚О›ўžЭџ„3 š{`р”$ѕн“{щњМ"љЛNОdF;ŽрY їCѓE яЌ†Ч^PГ{†Жm_ЃђщЭлzЗ/лV;oюЖЦ%ѓЗсWWаcУл™џ|`лЁŽоЖb}у€Ъ\Гѕйъэ№ЮѕквуцjoYgЖЖЦ‰ Жѕ/а6Иr`[dшœkѓ/ќšDJт}вzАЈ?Щ–"вџD[4в9š@6э ІŸ{_ •v€ийd„нІŠoљЈйŸњд'лЙчœ^ u[вc’Nžўй"ˆ[кљчбvм~‹ ЌПЮZmП}ЦѕЪb&ц‹hђ[‡­Œ0zѕ!|чC dё8еœ›J<хћˆ‘4УD„єTq;э­™@аГrFvw"2@ЯяК_цI†ž{F Юсэ‡h#Еу‘wLC‘ь]00Њl@@ђынsЊцвz,{5ј­фјMРBjczˆшƒмZ Т|CЫоs`ќ€ЙЙLЇп€Е6?ЮБF~ЯНa8кš#@вЕ8)Дц’Й˜І!бФмщŸЎЧб0iFцХ(ЩEДQ х;Iя Є~РГ ља}м§zЩп—снПйЎd(ТшpьоmЯ“vnыŸЗ|[џцE*ќЗD[їЦ…zNП§>4І Лzс6шђyкnя^ПўЯ‡Жў'ЭоF\Лl;ђ {ДuпК\yс’%љoKя3Gлр­ЋЖЭnZН§к<;єk+œ8OxммmЋћ†Ею.i^ў€юи†^КHvйтmЃ[WiлП}DyёвmЊqљAXЄ 9w6твЅzРšЇ/оV 6`њ§БўЪƒ#к„60ПЩ‰J… “~‹8RЖы €NZnкt‘ђ} a@оXоџЯОьўЊ2ћд‹kЗT љ 'WNЇБНОwЧwlХП/,Љsw{с“™_tvF_Ѓ]}еRГЅ |Ф,Iз`> ЯФvuŸТ@юT‰cГ[i˜(аУаz›mДКщР€€дK?>GŸЛBJ“Lƒ0’C№вЏљЬuњрc$ŸЁйт˜Z!%4NH&LЬ э\зѓ]~ Іƒ#m№мcrыhоHH4‘ОіЄ~К yЈb$пё qРu ЅАЎƒЁS|Ьeз›0[/=џ}зowš'РKуbjЄ]Мk’ШцпEАљ?@ћŒпuіY›0Мћ3№EРк§мzяЭm›ыжў›ŠОб'Џж†_Аd|ЦmуыVncпИŽƒлК7,пжћh­Жѓ“#лиwoмі|O­Wy§w{zL;ф…Н FЕБЯnиv{bЖў•KУЯп6МjљЖйm+Е!Ї.а†БD[уЄEXПќxGрє ЎTXDW’-оџь™ЦNFГ A21&Kчž.$(=џўу?~мл;ооq—^r^лПН{Й$S7ЦЬ™Цs~знЗO /8ГыŒXГНуЁЗOш“†%@ ‰=cіH#SЮDŒФІ˜лј# …6`.CМйёGNŠЉџЭЁпK’KђЬc‡Ї‰EўOŽ>;›$ЖЗžyяЦщSO@І.F”У r˜'ьx pKwоћЄё™l?ьгдs`jцI #'B,;Яц9Y„HзˆѓЙЧєLЉ1IYВЙѓлй•—?УњЄqŠљ ‰Qё є8ЬЕ{ХДIђ:š—зtч P w ЫќН\ŠЛoiы\Оь$+њ6Оy`tђЬKr1C0~bѓŽ—&уо“€A8ї€&№§є4ЮѕЬ‰8&B’PЂ6)fщЖ ЫМ& —4ѓ9ІJоzМђ>Ѓв+ѕЅ}$ ™TLі цH?ЙЊlїlmЦЖ—`дэ`I’ЈRЫl@ щ™вIиы\l§Ў6“–шн(&KдMR ы:„];ў‚8§Yz&šУьдKъ‹ш˜ѓ<ПІŽГ5)ио@пhDтGъ{?’пКбšіОd‡iЎшzоЂmЬн+Ж­ЋxЯwj‡|dуЖїsыДюмі,рвйŽљф.m­гцo[\ЗJліŽ5кšхќrд|m›[ЗMыН­oYН 8 _[z—Зм3о а3`њј YW‘Y”є9ЧH˜&qq„ ИйZs$Ÿњ˜–м)а!Y'ЅPџПњЕк(ØљъЋ*KюшУ& =‰oOJxќ‰Gzпу ЌЛVЯž p1KЈВйБQtkу“х‡Шј ˜@ДOѓGР–Г]щт7ВsтЂ$ѕ4Ж"‚Ц$ц4NJDхќ$о˜—lтI@дpдrїšДедшqzQщНІУр]œУ/`>CG Zеп=x.Ящ™ќ.F"HпФа“cяЗ#Е“LЭ$-г4™Ў рй“Š LHыЄ"'Мš№Ап—ъl0_H}Р$˜0з8 SмcОнOL­$БбRЂэНHѕšKOWеяЫќЎЭgф^N;§ДЖеmУ^QEпZeгoўрrm‹ћДЭяYЅmtcIљћ†ДГџщ JоЛэўиэˆvh'•3№€їnвvЙwxл­вw{`dлыБJКl`Аї[к€ƒњ}oМ OРє1jВ‡B7„‡-drмуAьš^c tˆЪЅєЖ 9Q€ўPХzХ?_|йў?ыŒъ{_Р6ХX|{RкРœзћП@Т…˜ѓЦWXмfЪо‚Є7ge‚єОs^’žЩˆ$lD]ˆЮ†˜РѓEњxЄ'DžˆC˜%~h35њ˜€аЦ+Х9ŽFЪUFЂНpкБх€P яІ)ШЪ+Wўyi2SIчКж")О@Ё‚@Š…0t*н›ЭХљ>OТPР,РЙЩN‚;?~&L_іbДђмњbЋЛM.Х;IЪ†Ÿё-ИѓKpyЖДрJhВыšю:§В>б ’nЬo‚љ™Rc/Ћ<ˆWQб7њІлШы—)ѓaщvќWЧЕ]+2pР‡7kз§њœ6ющ-кq•|жЗlлнНZлМЊzїцэјOUЊѕs›Еmn^Ѓ­wўТх˜ї—Хј+Mз|€ВЏЦФБеƒžё†ІqBЪ6У1lg‹F`Є3\_'`зн?їЙкМљФуъi&FN9ђФД>DьE„€йнKњЄІ@Бћ}–VЯ)СM%brЫ“ Щ“їo>\?&Ez ФTœEЂ9ˆFк›[‹‰Ѓj#\`‘tU ш™йщœ\aШєLj0‰I) Щ^| .И`T.ЛьВНфбьg 2оњЩ РаЩжDЎ™|ПЉ“•фяЅ в@xFдsФл“)—"(Ÿc4ЬŸ†'щќыwиєМљ„š2‡˜9֘JIŽŠГгЧёšf­hИkыG*?ЙИЇl™ѓzњ'ЕБWoUykОъŠО ._­S)С|ЄвЋі_*№иwщЅКlйЖЮЅKїlў­o_Еэџюк•Мпг›Д­Џді)gсU-ИђAsќЙ˜ѕ‹ŽїМњH@!юЎ€…D!rDMеХ№‘јqќБЅE0[ЪiH^~‚Ц€ш] @и&R\›ЉcŽ:ЌчЇѓ†OIш дGŒ˜т‡ йг(еeў@$—гв3esVh ]™ яљЬыиСц+]“˜!МB‹f\ѕєсCј:Œјh~3y’А“њ| „™ЊxНŽ=@[0Z“yHЂ&4hPЯ€ШЛЅРibэ“‰—мƒќЖs—эХ{г}ЬЂ!Фл“ЩGOPЇЫ?E€ЪсЭG/h-NЧД0 ˜sр^Rыpуˆ4jFЧр‰j9/zГНnЭзUXј–ЫлюЗik_ПиtЉш[хиyкщџph;сЋћЖM*xћwŽhGK~МвoъпF\Мd[э„Йк:—,]ЉРыЕНžЌ\s—n;U-Р‘ŸиБmsЧ6јјљлЋЯБQq§туѓ^=T†зе<ЦI| ‘Zмn2iI2ZœДУќнА {;Y‚йЄ3‘€˜}џ5кыdЋБ%ЕvJк@_ UFЯЮФщTœяS+“GЩœЃА‹щ“6бЏ $ Щк\uЛв$Š‚“"U5*1f7'IJр‹0yќ>э‘Ђ>S™ЏO?­I”DVЃgТdI њЗфФЉ˜Ф<8иb€A1Hlъфк“Ј‘ Ь€Јп’њњ˜|аИ/pXБc9­ІЄ єvd:Чbќtr/˜>рppЯОC=&}0Ес™­'ЛЩbш„EgzФLJ†X^МŸ2csŠX“№{>8˜зДЯФœ†Я‘ŒY™.€R”„Рa*…7…F2Г(рЙвгzmјэ0AЬ€јќOКGвЧ 3ЦD№lž3€v0ЛiЕЉPBPћЭ[ВёhЉND‡iгFЛrљпwТшqАF3ˆO&Ж}4ТЌ[ГЮ„кO?о.ИўьЖс9kLЗŠ>9Ћœ1WrI%ј\ПxлљщЕлйп?ИэєT…bяXЉmtг€ЖнkVip­_9—йcЎ6л№йка“j[\ПZлщmдЫЖі˜чєщ (т?)+Œ ,zъВM|Ъ3?#ф7a(N5Œх(-Л˜в[јЯn_аЪZ/{kJкРФ J@$НRRށ—{wtЏдe!3’!ЛЮФi˜PaTџЎЄї^З/`dGš`<сЦНУ8ѕКŽ=Œ„9@%ц˜ѓЗф-cQщ9љ„G†u”$ѕ`:špxn@ŸBР Ч'а-Юƒˆ„.гВ+™|I(Nъ4fІ ZџЬ3† „Д^3?ёшGѕO4$Л/uЋVЛй•Оч:Ф§%0uK‚“vmŽМцЦаˆ.Мш‚ЖещыП\бї|UєнQ}?ЌŠОЈŠОЗM{EпК—-пњиХ№ыДЋ%иMэТvљ/NnKXч–хкqпиГО^SакkсТ%к’{Ьо6ПqXлЁj 6К|`їд˜Њ шп–пkЮл –žnE”"ФCђЈWG„Є[š&’Dˆнd…1Ry—,@GЬпЭРp}M€О @"аЫ>€Cл€šЭ'Оšœ601РhЄ7ђћщTœшІЧќЉd6`ЈьJ”иxД0}UdnhДD–ъ0ъПпї~в#‘ЂФ6O!Pдџ0XR9яЂЂv~ммJў  ˜L40 ‰ \РГЅ@˜]’?ћH˜‘v€IмSЊSAщг%]…|ˆњн€Ш !’№жzžф(Прё} ЉСqЎњн8VЎ6зFДжhaЩНHђ.ѓ;Ÿf‡>˜Њёƒ  ЯЭqzњЙЇЖЭЯб6ЛoеvQ1ўŸЌz‹wЌжv|Њі\8Н_лЉTј3П{`лъП­шЛНTјsПї7}е§gГЖяћЊ“вУkДъœ‹ўчЄЖц•‹ДMя_­эўЎJХО~љЖх]ƒкюOЌ[>%к.ш…ЗО}H%ѕЏю@ЫДUŽžџ“ХќzиLфе‡+{Э 'юŸ6Z‰§С’РžŽ@Еюš] €‘€jП„АВБХфДIiйІ\Šh6 A€юHecSЏ1‰bŽ@ђ<+ІБљГзG ТLД„jJњ8/yф-6h"aњxХ“ ЉŒШ€(@*иH`RIдCл0šцЗV]%ЂїsNЖFd№я0q€:MBг‹аЕЃdЏ‚˜ЙЏDУHоУ,щuрўќЎ’iТ‚ГWваIџФh€}eЏEY}ншHДŠTл LьsinЭe|Щ уЧ—љѕ]р€Щб!@РЙ‡ЏЕЅ]xЩНЄŸюоЖ{rvичЖhмН\[§ЂЙла+J…ПaБ—Uј=Иэјфк•лПbеѕhл>0Дѓљ]люЏп–оГ*њж­ŠОъёЗўхUPН§Ž|aїvљžжŽћвИvLIќ]пЗAyэ’х мЙѕНCкич6lG}aЗvюЏNAЗ1•QИѓ#•4T>€-nм6ПyP}еŠП_rуž#P@ЅСЏЮPФџ6qX СЇ‡’зй?.сОdFтc|ЏZщЯ‡ёдt}qіѕќ8ЄЦтдкš’609'`КG рє‹sв}І~!>€žCВldD’ааCРьF@IъЇs-pьfГ‘њбBИ‘HTр$ЫP3{—8SЬ?pД1L…Й™Ci/Eк§`Bj6@Ћ.хЛLf?@з HZЧё'яНз 3ЦЩ№~ю7} MB’ЁщšцуЇ79 FКЇ‚Єјƒ’W€yЃ-™Ћ€ЅїУр>3ЧМJ?УьП€ёi!ю ]ЂUk”Ю4™dYZЯsЎ<Нuёm“ЫVnмКHлфў%лw,мЦОoНvьзvhЛНg§Њчеn,ўВ_žвœ>{ЕћZЎ[ Н~I№u._ЊЇТ/БчьmЬCЊгOЕ+л}г›Збз.п6ИaЩЖф‘oiƒ/}Kлћ§cJ#иИіТЖэ€nQZ@•u?8Д­ѓжeлšч,д†ПXльжUKњ/гЦдо%§лкu­еŽZшНуS‚_}e`ygOуHˆh"WZP“2дLRRBЩ„ў"љi$kL€Јмˆ ЛѕvЃ“з™Pз.Є5%m`bHkђј$нЋ|р' №ыЖїL?]‘В;І#егд0˜7яƒиЃŽ@ )ДIВJs‹фОwhЄ/&Г“ЌL3і=3уfN=к&ЅОcєџМв˜ЇQERN›~Д. ЄЮ !СФлAсš}л- ћт™›˜˜4ХB˜?эз\Яgйњ M$П ›!ш5К‹s:}%rДжб™ы&Єj]RJ€YЗјќVœŒщѕ№єГOЗэ/]Џmvy9ЁO_И-ДUєэкЏ-uLПЖќ1ГЗ§?Кm;№лДmљџ*ќЫK…/3aЗw­з6(иМTxE=#.YМэја№Ж_ЉќW:яаГ—Ј ?–h›Wcа Ћf`‡'зjЃo[Ў— Иу§kЗэюкіџ№mь{7n[>0Є}Яэ˜/эжN§Ї§кщп:ЈmuзАЖШГЕѕЏи†НФojЯ щу(ьy!‹KэT`“ЪжЬўё@€}‰ИиЬ&ž6В;"шІgSЉР“€„Л€xvvК™’601АШ$wі'ШІ%ў70ОћXюнѓ DЧ`"T§ЄCјМ‰Е?>т|rь†Эт сѕнЄƒ4”ЗŸ˜dТ˜Ÿ“ж‘Ri–™ЭDTўХ *P …š Ь и„рЂXЏYoЏг8yMшV’аЄМ(ƒkЃh†Щі4_ЩћObSBŠНєЭ 0ј ’0•т€Gо'нcB%sвoФ1šœЗЖм:И'#ўsŸ6hЩЇИћэwЖ‘W.еж<СЖYѕчля›WзžЕЊ”w^%п9п;Ќ]ћЛs*“oЏvЬ7K…ОTјЋ—ЈFЅТџЫ!mwnG|n—vжїkЛ?Нaлшњхй_ЛmV9§ы^ЖBtЪb­џ!‹•}П\™ ыЕЭя\ЛэљЮѕ{aО>Л[лыйuл–їєo‡НИeЛќЇ'ДнŸн†œЙTлѕс1eŽЌS&РРо~ƒO^И-КYЯ ќъЬ€šќOВй„”,~ђСЛIDДTJТt‡‘šG“яšШtиMИ ѓЇX’ЧЄj&’Zl9­К-]n&Ѕ єФюЗ@œ~ёGЄ…ћпР 4>LдЋKПЛpіK3””w;њЄsЩТ{?Bь~s˜чO<„ŒљЈшTiЊ;­ авКМ&љ§!™Ў—А]іЊЃ pЖ šC4€`ыpOu`пб{щ”ўƒ:мH3–X”–`Ўe­S2 ­Ь ™м€0, ›ШGКanŒž Aљ‚|wbћ$ќ˜”щјК AЬ/fьйЯУЧдиКюНbўlШrс-gЕСgЯгV?mіЖг#Cкyџz@;ёЋ{єBsћ|xнЊЈ^§З/е–<МTј‹пRе}зFЗCK+иџУ›Знž]в{huхЫ*ќа kc*xэ2 F^Мlpј\mБэgkѓo3[Uў­Tй}kЗ1з-пvyЧрvъзw-р mЯїkЇ§ѓžэфЏ\^џm™fk‹я9[[с9 @цn+§–Жц•эЙгьЧO Жmи+ї”їћЫiтЩЁƒРLДЂТ’xвyI7 AJuiMH (МЮˆ‡кK"№LЊ!HњL цž{ю6яМѓЖљчŸП—н69m /&уfУвьZ„hAZ™б0D:і’х ў3s\QEHпСЄ' 5к@тбнјsъсЭ'f4дs<)њС№$7‰Ÿ­ПЬ)†L­Aœp!XD‹q™oюјОыаж…йж€^іp Z@RЁ­=їлРžЦ'Ќшz~Ым˜?їдв`$Y‰‘РщaѓЃІbnё'dW`ŽтЄCЧ?’ЅlSцї^й ­1еВѓ# VaіЄSЈmp]їхйВУ/лЋ­XЊўрSчl#Я™П­zјьmр!ГЗѕ.^ЄmqяЪmwЏнЖЉHРЦЗ• џxЉ№О;щ‹ЅНmxлЖЪwї§рцuN ЪвіЈ?ŽњтЎэи/+‰Оs[Џœ€‹­ 9nЖl1єšU§Зm…ї/9ўгЛЗK~pBэ 4ИљщБmыЗjѓn=[[љиљкЪЧЭй9[[ю йк2ћЯжњ:[э!8А-Г{ПkЦЇПК„ €ЂтБBњБAддRГ7MВ˜К…ђПаbF0bОдBйg =!4“юќ$‰PѕтдЈ/uФ!mŽ9цhsЭ5W›gžyz)Ў“г&~ г’јШ}'-˜Zhdgaр~1‘ћb#Їd˜‰ƒш“ш§4FaћЇb2-Ї’vJb!PРJ зў›„O=R=u˜Ÿz H\DщоIY@’№_˜ЌЋа LІƒпш€ѕшkЄЁhЖ#УДˆhzю !=їDЊzNL 82"…гq(ICqЌa0їNMЧщmшш>В;0КJ$"v|$}њ КпD0Ь  ЦјќRiВbюЃmdПяeнњ,К's˜bЄ=ЯлІpЬе†>grтьЕOп[ккgОЅw\pћЗДEw›Џ­xфтmф%Ы—j_О‚л‡ЗqUЧПsmтqмЇwi{>НNэђЛB;ф“[ДKr\љ6hkT3­яйF_Нjzц"ХьукшK—o ƒКpў*ZЋ]ђНук%пЏ„ЉOэ_ЁОСѕ;oiУЯYЂ­|д\ѕЛГЕѕЪБИџЧT9qеЧTd`њў€ƒц{l|JАврWо!Ј˜іћЄDД‹’њэ”€"t‰ш…ЉЯьzћА 1эA( ЂwРтЙžEH•”NŸўоƒŒ@1аЪ+ l§њѕksЮ9g›’601 ю‘R˜9эЩм3 €Yч_і Lк,`PїУь)ЪžI ŠWл|‘$;†Ё!‘юй№#ъ3ЦФф†з˜žЅ ™4Ѕq$\ •ŒНЈЦˆ3ХvgBа*ЌрЏ 0+€rњv}ˆо5€Чьн–`€ˆіЧG’ŠLџЧwЮ<9іНЇ4яHž3OžPЄ Ч=9LЧDœ"hВйˆїбNР›™fтёcг2’8хтШŒ&aуј3эv— ЊCRUн­~шmј ѓVо|mЫm{?Гn;ћЎМќлЛЬж(цншЪл7Ќн6ЙfљЖѓCƒлЩ_­mРЊнзИї mЇ|{\;щЋЕ№e§лвЅТ/БwI№ƒgoŽшзџрэМ*осі5к‘пІўс­лхџqd;уыћЕ=ŸиД: i‹яVв~Ÿйкъ'ЬгvyhT;цяviЧ~nЖы;7)ћбž&БвС п]ŒoГWЕиџmh&Лы@˜i–Є ЖurхГЙч™0Žъ/’ж9Р#ЊпФ€VЩ&>щ„Ѓ{ЙЦqЧоы Мщ&ЖAЋЏвVXaљ^ЛЋОк@_№Љ юf/ї…ЙAтќй >Ÿaє8ы8тˆ†€109цfЃ§а‚ЄпЬ"вѓыЄЫnvЄJ’9AИЉCШЖV —Ѕ=XВгКЊ$)FТ<@ dњ-’мкbАО@zќгв 0)Žцd нCќ>цcЇЙhўуаб=`Rd–mМ’nŸƒљ%4м# і=ЬžF=šЬIю(H)“NГTЬMЂ›ѓ”Вщ˜еh9?л‚#[І :rюЖы=#кaUŽЛўi‹ЖѕЯ^ЌmrЩrU›_ёўK–-`ЁЖl1tO…ПkЕЖ_yэ{qЗvёїocЎYНётmЋЛGЖyЗ*ў˜љкJЧЬбV8МњРйквћЭжь2oлтВСэ№їo[ЛџькŽўфЮэ”/югЮќЧCкОянВ‡Ћджр‹—3pHлѓљMлЩџxPлщЃы:‹•`‘ 8Ь§еЙŸm№tбЪNќщ…(LМE0ЉiRС H[Ј4!]йУˆŒтaЇHЈ‘иЁКK‰-Љ‹щGВч4‹0ёЛоѕDаЅэЬгOš„IћцЄЮc ‹uб‘–оOkoЯыЙ1ІЄ> GŒУ~–!щ5'^:b~›}IrЁг0іO4цаp„š#Z‰gOŠЖвY' Ё-Ÿ{†T№гДљТ|ž “Ј™шЋdПвM2• ї ,фјŽ{ХЬйѕйНЙŸ8ЄЎїаGZt™Kƒ„Чј˜Щџ>Чмо“Ѕш{]O}:§`Vs8ГСІЃ5ђ\p›Cj?ЦЯ–чё1Иv„M7 ѓ'Фщѓ$…UюлošCO> ~kџЖлCCл^ЎоЦ=ИjлѕŽ•лк‡-нж=~`[ВZ‡žы~{ZлфЊўmЁњдљѓЗБOЌе.ўnѕЌќз“лQŸЌD­sЕEw)ўЌ%кJGЬекБђљЯ^ИmxэРЖЦБ‹ЕЁ‡/зZfСЭkЗ]ю^ЛѓћЕ>Гk;ѕ+уЊZpџvв7іiЇќуўmпlQФелЦ7Ќж†žЕd[bЏЗ€Ье–=`юŸЯЗrПэ‹љWьј^™ PФ0W…ўd .В&/ЭRм’XwъМчЩLю=ЩЫўfуS­ Aб‡ПДЇ–цГ/›нёф“TЛ›{€ O Pа0фь3Oљ+pш $4ˆ&“4жHЇHt‹.ќI}Te@h.0НpЧ&5г“і†ы3}hФо^{г=њŽіФ“яЌмњЇлЛž{ЊˆуoСсc—}їЮЖѕV›ѕьI эомРuјЈ<є{Ђ^(рPFДїу§na2]›c R€˜ьРdџ1‹Јк€mŸ2рTІќ4Щ)$|—P ƒ%{0Ž­”ёbVR “pія_%J­W(”Tjѕь|k а89 `ЬЩIŸf#ЬІKд CXјŽђžcоУєљ ]‘Жд}–шэ„yтљВыS§E›№l>‹#б=ƒTQš‹ь№J㔈CЪ 1 V'Ÿrr;њДCлњћЏ^ZР’mЃк–{}jЋUШnЁбГЕUіьзFИdyjФбKЖmoбvЙ'*ќ.TјООW;сk{їrљз­€aч.г:o[fуйкАƒjУ_Ќ-ЗY…їŸЗэrпШЖбEчѕoCŽ^ИЬ‡хк*G-и–ЋAV?aбŠ,гж:gЙ6фєeўИќИпUЬ>Кл_1щ/˜њ?ѕy%њуџŽ}K•хиТ8‘˜№d‚%i"dž]T0B7’@“нz™н=0&$11[Z‚aDУ{Ю<№$ффžи…Tua-„#§еНГПI;„„№|Ч=ђж“ЬщqЯЩФ– Ha„„ћКœЄЫQZœЅRZ‚aњ0Ж‰NћщєЁу#p_žйsФ‹ŸїДK$С=#вю7Щ"LМ<žіфш#рПљQДiG‰SBŒ$Б{NОŽЙhHе=L‘ Сh|8ш"ŽЙH}чcњќ 9зкX+f“ЪkŸ››Ќƒ$'ївѓЛРСМЪ=хѓфCt[œЅ[rкЇЇšpІŸA’”€PA3юй 9ŽкvШЯV?|ў?:dюЖюЩKЖ-ЊwѓЋД­ефW:ю _оЕэірzmзЗ­н6ЅТП№В ПўšmŸїmвќШжЎ[­діe+Ї`‰ЖТИyБќVsўx§чkыžИx}ъ’mєЙ§+„ИaеЌд†ГHEцoЋБH[у„ХлкХєЋНP[љˆ…кr{ЬѓХЅ6›їК’ѓ›ŒW§эИШxяПjРЉgў:yЖbўAриЖ#&KZpД€ЄeІѓ b/  ­%ћЎЛ'@HхОћ0 О‡I1 ‰хЗКm›вЗ.(ЮwA­Mџ:ZŠя!и0=ІNš2ЭРНІЉi6Э^‡~—§йнА”fт=оћдјs‘}щ“ўKMИ€4Г4€ }г№"’?6*аѕs]ЏNK4%1і0 цЦгѓ“њ˜.…7I№БЖYWЬœf!$ОsтЭЧtLLhц3zч;7R=’>лЊЙЎAЕЯ\$WP0‹05mЪ|u# €'о|Пч7RС€Ьљю!T iVѓЉkФЌ#5Q‡šЋП?ќАЬЅ'ц\ј-З-НmПЏ:rОп­]RјРЪєїШˆЖћ;FTkЎm*co\лцЦA=ћНЇТпQ*ќ;J…?ЏЄuЉўTx!М!ХјЃKu_уфe~1Яв§оЖР*§оОЪо |аѓџiх}цn[ж5†АH[qЏйлЪћїћуj‡,јЃ•žя—§їчV>lЁŸ/НлџОФ6s|tžegзHкяа§Ч;ў^™ъ_ЁЊ#IOƒ—›s‹$Ѕ$c,iСйQЦdaЎn ?y]H‡нn' ь 0% PП•нљ€ ŒјHbLˆhихЉФ‹$Ш>|йв*ЭIRЊœve:вр„6^Љpє{˜мяџgcšF:esŒЮ <("тsЬžfTW€ѓRыŸ†–4„8­М6ї)^Aрщ|‹шI/в7qry )Км“œЛсcююZc˜\+Хaй€6=њ]'ћ%bRЏ#EšŠУ”6\S™Д9i XКљ]ЩŸз‰*XћDGм{ђ т Œнoю’(•Rч ‡0г`|ўџы>ПQН'dеUу˜'ЬЛм[ЎZr“9ž|иЂп~ЪТm№С•W…8ыУŽ* Нќ< _н|Ј№чЎаж8jс6тьeлЪ‡Я_aТ~mЅ#чЏQ[„ ŸыОКцIЎЛа ~7.ГЭ<\qмќŸ]уиEK{iО M0ЗB‚юБgПRк?]ip|ˆ?]lМЮ>|Є•?[—[ъМ#гMіЛѓ:%=лzЇ ч)I9Ѓ6`кfРж>в;Щ71hJ‘њшФ Q`BРAњг,#€ Цї ц @гфќNіbŒ=п§?в8|З›М“Іž?щМyнuњƒињ‰ зtўЗЬ‘ЯWЉљХЛжРhлŽ?юVЧНgŸsЖУ6чѕ+4ппЏv№ќпYyмœџ6ќЈљлЇ/б6€еMJAR_Pш ц(‰Dё ЅГІNЎA|%ЖnŽ@§ія‹ц?Yšв ХbщcjŒЌAН&emСЭЫЮоЦˆcч[aЖ3ч0ћ‹ыwЫъ-јНС— П/~ѕž ?pяйлJћѕћуЪЯџУЬћЫRнџ~Щ-ч~tюхfSЌу›gцыИйxц6лїызћ|ыёяћœД5ў>еq@ЅjиœкџЪ$?ц/ЏtПZ˜?fЯ8R№а €‚ЯКp`ŠƒBшг}їL1ц%е1tКЬпч ЦЃH v‘‘ВZPЇиGШ`~їћОЛЅyœ|‘јйі(`vR‡§nўŽiў 0hwПxšp.%§vZRaг"qе$Жј sЖв т№? – 7ВhТ›Є&ХДЇt`рРmьОЛЗ/кИmњш*mнЇЋ+э{њЗuYЊКnХЖлU›Зƒ.зŽ;эшžд"Fd$ԘD ѓ0–Я8 a~РЧЧAsт+aВ`јdцuўOЎc@!@ 6жУГЧ7 sё Є8ЊЛhŠъї~WЊў‡+“єшbвžtХьЄ+ЇšкzŒЖlkЌQlŠQkьQcџEжœѓъхЖ›ч§§ЧЮџ™СЧ,R*|П?ЏАзьПXn—9?V qfIїCыМнk`№€‹kљ§ќНіЛ$;F>ў>~•kјю‡дWђЋрGИoкеўњRяЏТDƒЈhМЏЉїПPž$ šЂ ЈžBФqуСNO6LuФю "]G`rњF&Д~Фм}ѓгŒц”d”Ю?щѕЦШVRќЙЧ44ЩЮ>Б§ 89˜>эОВїœ#5=ѕџQЫ1*PHVЁпN@р€q}Яљ!cј˜˜'m$Eќ˜н{жУwЛvКЄŸЅ–ZъџРђЫЕіеЖЙw­ЖщsЕећћЗm?Дjлњ§лЮ_­mёDе•п]Vо6МZM iЧ]~XO§Ї)И.fD'h€ ймљŸАрпn,њ‚љžчšžНt?IXž#Yƒaє.У'Г0[Е%g ‰@IE`pпIў†пLТ‘їъ~YїїОJ?МXуo8žс0šD6ЕpщjhГ…щ„йьР#с&яя6ч|Г4я’sЛ№а~—/ЖоœWЯЛТьЧ—­ Hѓ-Чџ.rіmээЕп%й1К#f<^ПџEj,T#ŒOъЧл?mџњт„П€C$§$ѕ‘ЭF ррЁM/y ŸЬ­n$ ;СЈУŒšЭB…нВ+‰Ь6ЇЎЧ@ Ра]?РФL€h €nL? Ч €VcќIIŽŸсІю?mŸЛЮ>ЬŽpSљЧLHяУфщ€ДњJњДšN„уfЋk "(­а|sЇ)F~bИ!bО C*GШж'R0ёZџчдBъПтš•вzx%œœ7ВmUi­{~zD;шKUnќЮкцЯ-еvћh%Ђ”&АЮ=‹ЖЭа6}b@л§ь­{Ю; я=ІЦpё ›”‚;b| ‘ R€! K.{ŽzŸ„ Яин,УЄаšЙpЭD\Ч<ИЧОPкЬЯ œž­bВƒŠHcёs’уc6Œй#Y1˜йзч`V@@r“ж4*=Енuйъ›е,$:S‚ДчАУь‹дРШР…§ю7]›Jя3GЬю}ŸћmБ}їб•јЏœёыBНПЪЛY+'„”А ЕкЦc в@вb›|ЫіJBPі ŒZлЬFK$ [„Ч РИIЪ ƒOJˆ3АЋ$щў€% ;рPџгžŒкўДOoУlp‚љSїŸpŸџЃіcjУ3cђl'žоЇ>eЯе| 9&Э7-Пm7>`ЪjЭН9O гРzХ“Ÿи:ІВn2§џЇіcўэvпІ'ЁЧX-ЈпQлRПИv;ѕ_ЦЖ§?Лnлт]ЕеsKЗ1O,оVЛiў6ьŽкvяYНmідJmЯ+ЖыE„81SІЋRЄЊућэЋПЈ]qЫџOJлЎЈфЩЭЧр +v‹…ХH*qЊђт_ јћЎя@\7~…”єж=џwi+Йя[c›XI1~WЅЦdў`к€ФІЦг †зX[е ОczŸ ’~‘}%ИыbjЬЩ3Ть>Я§И—ŒџОъП€Я)IТEБ4 \C•єВЙтiІv"рДsNќЛ/№ЌЇт.ЮИОZS ы˜ЄЋlL€‰FХx€ЮПQџ€ћ2H~Œ‰Oв“`ŽqX%д‡б1|Зч|B}ёў;‡tOЬ9( DŠФєљЫіU˜?[ƒa„эћ‰­гР\сгаЌGТw@ƒ:bpёў4Nѕк躘QmŸуїhm:К>thэ<;Њ§Е-л^ŸЉh~X \>=ЌэњсAmпзmу>6ЌэўЁЁmзЎеЖyІКн<4 mйК=`сјгœTxXыkЏЛЖУЧ3ДMп:И КtоЖсЩƒкэїНМE™чI} ѓ чНѕЌvжeЇMШыOЦaj "бЛuЩ0Œ`ŽНюы LНA™\џUQ‡ŠIіЎЦ'ЅЬ’јSkK‡щК@@*Ч4РмЎЧo`PпгЧœшj]fžвыWЭчН@ѕ‹›ЋрЗ:Ц(RAP$IвHљтƒЮБ€ёЎ&}•M)иv5)›„ ОZ83 ЮРn4 в>ЧDњњІqќEH{/Ж}ьћ„ќH{LOКdЋяЄљЪ3@шбx аЫ&Є>айI6q}ъ=`Є$ё&™ tНкЩЙАqцœІ ЂЅЙцGоcNв˜дчјУєB~іQиjЏMлїj›]0М­wдрЖў+VЛЊMkC‹qmм‹еhђ•ЯўС•Kаvћ№А6юуkЗŸдЖxЌлљНƒл.о6ИgЩЪCЏЄ–^n1&šсО}ьбvйНчЗ3Џ;ЉэuбmУ[ЖѕoYОmXнq†_T;н\4І]tуЙ=џвчŸжіЙxЧЖ~%Ы Ћ­Б‡œЛ@}і*эЄѓŽыAЬ„.Ѓwы R рWIёV „Љ х§ЈъдХ ГQЫyб1>ЕcN-уOŒoњj˜:j<ЕнР№QёItОЏ$m˜zZЎZіџ([HЅх5.f@ђЛM0ЛЁб8Щ”J, РFє˜Ё a2R/Z@З8Ј[@ЧЬё№'=И }L‡ЎэO§*] a@Плз §1x—љ…ѓ˜;ушK ъь;чЯŸЦ”>L$їAHоz ”"-г-ƒe=’мCђsЮr(sм1mŸУЧЕMЖпЈ­4d`[uЫкЊїяљШћзxћУ+cя‰Њ{zЉЖљ#ЋTыЊj$њ№ВmУgmћqxлуХСmЏ—жj›=S‰+,й†о9јжљлˆ{цkЃ\ДэђОелцO,зЖrh;рыЕuю\Мэzг†эФ;iЇнp\;јќНкЦgечЏиЖМККи>8М UFЗ=jчкMnЉвй'6n|ЯЖ§ƒЯnиыŒЛў•KWwнљЋЩХђmГл*хѕ”EкЇэй р–z‚žІPяeЄ\;`=М—MDŠюў­кХbыь№ѕ'Уј]†œЖЩЙ}Е‚ЈёTї‰ЉяЏф7^ля•=івљВ'э7a™фu#МРФ'б"}0GЈжтшДjw@€4І–ЧшњddLŒё“ачŸы•.ЄїŸ№MDј/vК ?˜Ÿc)[{Ѕ™g’zвЪ;›L"@ Л?E=Є;ѕ=[dХцВ@*?йr*^ыФћI5Z@Є 0НvbћьеЖЗeДе€гНrqдЪmћ–n›~xљЖmэYПё{—l>Пxлш}KЕпПtїйuкa_пВŽkЖѕŸY ˜•ЖWН^щжr>НRIўuкжяиVЙnО6цбeк6OUїкgVm›?ИTлцБел>нА6Џоv|vhyгbmЭЫh›ž[§ъOижЛК}нJmЧ€БOŒjЛWšьіїЏбіьuЭ9ІѕЉНлюЏ_M/WЈвихкvwV9lѕЫГѕѕšЧ/T=ю—k[МN;їМszЯІO2QЂQёG™cgбф_Ъ‡ѕ/егрњтI3a|69‰Ї)MZПzЯљпВхЄTјз–_эе юы l;-ž!k2ВRyЉXlЭd R=™‘h˜@Х ЙЉдды€РЄ4Ё:Œ™“ &5˜ Fœ~Є>ЦЯŽ?]HGиЈўРH\8ЩэУ/9§йў;[xcќиѕb№$z<ѕœy=бnл4БŒ*ŸЭ23oq†!њд]аРМN=чѕŸЦ4ЄіHм~ХЖжб§ЋšЌŽЛзFgЎк6}|ХЖ§'Ћ#Э—зkћ|Бьў/ЌгЦ}nD;ќ[Д“ўyїvќЗwnЧ}{Ыv№ззkу>SіњлŠљпU5џВW;єs›Д ^Д­{яќэШкѕцфЏяTЬПlл§ЙкŸўэЋДоНfэ|Гf[ћšŠљчiнВlyквЕ=uСйUЅvю‚U;ПLлхосmЇ{†UлЌвXЋџ­CлQнЉ ;uўЖEэfЛэkД5O\А 9jО^3MЋО}ы[Voшзv=aЫ}6iўa^’ЇB5%xў\ №ƒёщКТmBmыер|[ёubќWЫ‚oьїK]њŠj1ѕтбтм‘ш!!(@’Kn3нЎ92ОІа!ЄЖHМивy;яюФё–ўm1К•‚€€4O\bGŸGняЫќ$~Hў„§HўdџaўnwпlфAђS§Stфџє<Шžs4`цЉлwєьi7-Ь—}ѕ#'аJ‡šЄЌвКтб7‡i7Fе9BЬ\ЃжїšwŒвFœАR[їЦкњ7 hcЎZНm{џЖљЛWh[}t…ЖуЇViуўnЭЖoЉљ;—Єпя‹хљЁња?Г`НПz@ЉфŸ­mЉ?ДrлчЅ‘эФиЖ|`ўЖцmѓЕcОМuЛ№‡ЖЃ>_ЛвгЏuѕТmЬнк.O m#юXЈД‹Ко‡дДl{T_|*§:ЕсХ№‹цkkœН@[НTњЕЊшeуЫWiЧ~|l;ъcЛЕ\Зњ‘Š&|nїvР{6щФnїЌ–Z#л^UдЫЖ{WГЭ#—эЭƒмfzzЭZТцOE›пЎЊЦ+‹{vЋБХdŸ§§ZHќ7–qЇЧЏ—'wоjџєЇЩЇm€‡™Њщ–ю*Є•ЄJ10Є'ЩъмnЫАЄнvУƒЉH’Lm`ђ‰ чdа8ж0Оx?ѓЂ iђ™DŸt№MRO$~œz˜;Nвсзџ){N€]Ÿp€єЌF‰Єž?PЪŽ“XЬљаmЏЯЏйv}БТ{Ÿд•ДпъНЅ~?Wlя]Бэѓ‰Qmм‡‡Зƒ_мЈ­wзBmЯї­нv}oЫук†ї.бЖЏЈР˜;—j›мК|;њГ[ДГџe\;фcеЭјњ%л&7жНм?Ќ 9{ЙЖa™cЎдvМ{vЮ7Ži;пПqoМгПЙліЮекцзhUНу?Еs;№ЙЭк67ЏQ~„…лкЇ-оѓo Йl>очёЇ ;~Л6„ЙЄш_ž>Ц_wМФjыЊњГJ Q€еЄ€š $wZTzъ?ШMЄ[jжуАъy{K‚YРєЯ“ўš>tдaЮ5ЁЗ€@7D˜t] Б3КЬUп9@УH˜/Лaъ„™ЩчŸ˜д'э›Днфч3gтФЫЖиLTAš Ж|Тvi4I ’иw<ћЄ8ІЦdЯФM{bшмн§Їл‘7-ЙШN‡mгЖИsHлє™ ЯНP}ъ>?ЊŽЋЖ=>Лvлћ ЅіiнRџзmc?Зv;ц[лЖSО[О‡‡UЪяRm­Gl›ПoЙЖі#ѓЗѕ[Єэ№ЁСэЄoэвЎўљБэмнЇјЕэлОеЖzgџЖзFД7ЮS[ЌY]m—)0И6М(тбUЋaхіеНvLћШАЖљѕеѓдyкZ'.Z=эFДхїН ;kёrє-ж6ОdHлљž1mш)KЕЕЋ‡нfз­кЖМЅ4ˆч6jG|xЛЖпг›Д­Џді)Їс7U—ЂЊАг€Y‰~Jјc…џ~Ё…К`<уKИСј’p0~rтйјГJŒŸЯKЊœЬўOїз‰™]рР’YH| ‘6‰I5ояж„; ˆЄљƒ\ё,2ЉG“p­юNТйI xѓЛ ‰Ÿ]}Iz`ТЩзі>ѓ'ЖŸЎ=Ÿ”R"хЃкg?yЯ”„врЅ#rкLЇ'НcвQйющб8 ќѕЏнЫ—r0ФеЕщЪžЩВУьжРм;?‰8{]Й}лњ‰ г}`@ЉёkЗ#ўaыЖЫKk”šП~лѓѓ#кŸЉP^1џŸкŽћЮэиomз.џя#кМ н№ЋjѕўЃ}к^Ÿ^Лmѕ|I§,поњгcл…?>Аэіў5к&Um@…§ЖzЄ;щЫВЛuСЖћ3CлЕ?­ˆЅ ьѓєmєMsЖmюYЂmu{mNyѕRе,Гœ~ЗЌлпhі6їˆйлН`лБTўОМaлѕЅ5лоŸ_Зэ^ЬПЩћ—mл|tЅЖй—mНgё6ъЉк†Я-оі§мшvњwЧЕГўmЯvтЗwjW§ќЈvдзЪ9љž­я<Гlэk7ИМќ+—Ъ_лVf‹Ж]йћG~zѓЖнУ+ЕНоS;чiпѕјTzї“њїфžЫyuož—іB ƒSэІ‘ОџЋЬЯR г­Ѓђ›O’нsК6m)-ЪЭЇэ ˜wзГSеš?бП xVlл|h`лт§ЫЕ­?Дb1zэ0ћСк^ŸЋ]h>4 mQАУ ekзч›Нw™ЖоSЕ'нлчok=XЊхўoџОэјonнјlэјф"ЕчмЖmл'ЋWн-Ео[чiлМsЅкћnЫJкИѕ™-лўЈэЏп1 ќСъ„ѓD…їžвЖОmхЖђ!§кj‡дF7i‡?5ЖќP™Œз oЫ™­fЬгжЉ>zƒŽЏЄŸc–nkМtЕЮ^­ђЁэлno_ЏЖБšЋUђlzвBm ­ЕЊKЎ-Г—3з=Eг;зВKеŸХјЏ„Щ'ѕRћ&§'RHœŠyф€˜ˆ Ÿ€51t<џЩж\яФек:-жж{lбЖщЛjgšз*р 6іѓkЌбЖ§p5 ќє:5жЏдоўmЫwѕЏ4пС)XЙэќБ5лŽ•уПжлVlƒn_ §ѕъeїэ]л6яа§ьzmа5ѓДU.™Л­rщмmшU ДA—Эеі}~эvљПдц7g[ѕŒўэДП?ЊэќјШЖTХьчоlіъ‚;ДќвmлVicЮ[КmXyч|щ€vљOjЃŽ]Ж мЕіа;uБЖЪ! ЗбчWПЛjЈЙсх+їЄ§кTЊpѕд;т…кiјіЪ&МДљ–б>ыГу%?ЯО”кщSњ:=™шЭ|­€sbџ#0DGвlИс†Š<Вї[ди˜} @BXœ_щ-ШЖV<цi}…)ј ВЭ6Эу‹‘ї­ ШŽСœg6‘`”Ј@lцFzЩо FvкI3ШєЯЖZœw^ѓgєн/c^~їэ˜эЫВR7ĘЯVL-<ѕX2!˜r.Ь= СУјaўhiŽыя5ЌZL-нV?i‘6тКЅкzї–­ќ№Bmу*у]яЙE‹љзlЧўу6mПЯoаЖЊАрUшГOіlЫžwm,ёR9№*эwнЗЯлVПmRћWЊїЕM+сёe*ю_}юаЊM+VОhЎЖвљхЌЋŒР+J[Ј.}mшe‹ЗѕnдFпБJtцЕ?§еЉЖ|wЎеv`нvР;6kЧОЇ6ђшEкаƒh;WПќБчvЬќmdIќuЯЎf#wmо6ЛjXлћй­jЯМђƒЩ ˜|џdџЩBФЬ4‡ОyBŽIL_ЁAоџ8/Гї^М§м|pђQпyіГћ/g -JHЏ Д,aПѓoRкзўkЖuvЎмњb~LпeќaУ‡–#mЩjеЕDлш†Ѕ*„6gX›C,7vЮЖЮUЫДЭп9 э№ќЊmяђьўбСmлїжўє\­эњбamыїЎвжylщ6№жy{jџm:Їьў=ляYЖm№p9чюŸЇ$џЅ!,нЖ{Ж6ЉИjЎЖrЉќ›нП\§lи§ф˜ЖѕCЫЗхNЊ-йЧЮбŽўТ6епОZˆ]ZБ§кЊj№I З%ї|KУЪmфyЫЕ .XЙ:Ћ›cDэP[^Ќ]l* XaЏ~ѕК_ХїчiУXЁW0Деmе5ЗzчэњфК•mXћп§г~эєoдЖЊўњ‹T—нѕЏЈjСГ—јM)џLоўWЖЧн›‘9_ы{ЎЂ‰ecџGэœT*pWш†Їв|‘g}b&яЋЄЮ>t&щ™ѕ=M&ВiGZGtїЂуQяњ т+ˆc‘o€mЯжя:=/Їѓ‡Гѓ#аœpN+ФБ7jѓсmдE+ДѕюЉTк–kkеTCЖ^Й­ЙЮmЭVЊ˜xm q^йуЭпЖМiP[p‹9ZџБЅТзnА+зfуоUЩ>ЛпћCkДБ•аГї хЌБСЃKЖ=^йЖxп 6В^~rљЖIіЌ|у‚mщKчikп5oЉўЫЖнЊолgЊ‰хЭsЗAЗЬн\RšХm‹Е}?МAлунU)јЎъ №ЬэЈЏЏ[ДD[ПіІ?ИЖЅкяй-лрiKVœѓлЊшЈд§]žгNўіAmјхщПЕЂwЌожНА Šю^Г­vф|m™кл~ы‹*тpaэАsС2ЕЕіFэ‚=ЊэњиeN,еv}xLлсОuЪЈЖdЗ ЎэЎn‹n6‡N;|гОЭеkЭHoвыПЅьџнbџw€Tšœ а7 aРЎ Џƒ&GОЛыАлдŸA4€l§ќf€Јџй~{э­‡Дс——m]I5›><АТpХЗ/бFдоѓcо6 эќLѕюЛЋpL9рЊpfЙqѓД•XАѕпЇrіЋ ѕЮO Ћ˜§*mћgW( кyqL;шгЕC>ЗY;ъЋ[—pхЖљГ+•§ПQлМ`ѕ ё-љмmыћ7/XпЋo?ОqлцщЪђћРЈЖWхїoѕіmУлЏƒ ЭнЗL;ёЋ;ЖЭяZМrЏTпmћЛ‡Д-ЪАtm‰5ч†ГЕЗŒœ­-Ећ[коиКўЏ‡Еmяоі~~“*оЌ ;iбЖ^ѕ^щНk”яb‹K†ЕсЧUбЋЖ#>Йc;цЅ}лњ—•зџ€йктЕеж ‡ЬбRƒЃпвжYОGY8”ЦЖт$Я ИР=+E\ЩoЙѓŸ>2~ЙSdўѓx€иkfv€бМ˜zу|0#Ь@Ћй0…Y ЛŠк˜?CїэАWaј…&^ђ mЋ7rїxcвйд‹СШгMXѕz'ђж…СЇŽФ›sЉЈП3@acІ>‹5yžОщш~„р3бШeПуb>žЋЁ{я@ћ˜С–оІѓHлХџ›юЯG1cњцHС}”<§ЫŽВнїb Ѓ“4рL ?5Ы~аЅ/ЭBф€I:ЁчYЩИпОЩ“NЄ bo8ЪHž|{К,Ч5/ВЙчлPК-ˆѓ№˜ЋXnAЫЉtL?“ƒД+Ga‡Ёj5л™ ~6ŽбŠІ‘ЙФэl ^њR–Нм™чџ‡!‚žEкМPЩzIWЯ Ÿгјѕ4€bЈ ъХеИ€Lнљ“’€Ÿф(af<%зЦ‘]LЯќчS—W-оЬЬ3уБ]=UЎж@ јпщў3л_мТ$з A(;…YOOРЖ_/Т П_…о'*Pv8;МбФp`Лю&ваfм]€–3vик'ЈGZƒ’ЈprМ@%4бo]=€б`&п~ZР”ЧЪW ”Tќ_QYтв"фЯMDћХRt\*Х‚WІaфS‘Н}їWbчoGАу7dЩ]$5іˆ ‹~аЪšќ4 lЄТжс‡iчй­w.SNЅ`югЕXёкdц QIПuќЊc68И&FыCœњCуo§;j\ЬУ„cЁЈTŽІ;rа~оZЦї=—шЦŸЯЃФ+<­{Щ˜~g:VНв‚ы3„ƒo_ƒCя,g3Ю0tЬВ/ѕТќ'Ш<м€Њы}0ћ!& щA4Ё(Ч…\ОF,КяхЬВ ›ЦЃчЁJдмOЙЏц*‘ЙЦ‚ЩЇ3‘К†ќ-Єщ^//" YЬФ2іwŒЁrP-AЂˆяхƒP†b N:–ћbКX*ьdтp5У…є ц"Ё/сVОљ…љАw%ЃќP,’ЗxЁрІPtЛ– П^єЫіућKЙвпf U€m€L4ЮA ]ўјA_Tг№Ыѓg/…cW*j™ш+йЫ^џ4R‡ QД1О uxў‹­вњВOИu5їЈ†jjzЎФ?ДgнЎџ8с–Иъ™ќ#У€џр|к2рh@мy…ЬјpuУЩ0ЭqЩz)ј, рX}_y Єwv3OtMЭэ‰Hпъ…єэžLоХЁїQЮхc|^}cJА|vО=;HіiF+ћч+їФЃŠгtЊїХгР"IЕ ЦмG`_DY-rю­FЕјђ–њqќVкЮцc:“y-'I+&лЏ“ЁC_З‘ESnЃšаqОЮŽ@ъіЁƒьПсЇыHСѕE4™|Эџ˜t+хМјї~цВ–y9йyЭgJ8 &%=™НOІс`?O ŽFахwьNEїљz†i <ЮЧR$Њ!ЂQА.!жŸћиР‘<ђ§гшQdБп?пйрЄD`l‹џЏИ'ЅєЛ№ђщЏЩКЎYЗёƒёы%дLЁЙфхЛ5XТшЬ›P`<@vŸЧp L' с|R#a~еРю`ІœН№•7+™Юј>=K(Чны˜И[ўк ЖЦЮТЎЗ†Ає5вfiЄ­w8…32—ј"kieЕТБрлшЛЇ ыHзѓP КюЫCэnіvД№tяИ‡ЊС‡уйEШ~–ьв+пВЭ‘˜|‚ЎќёŠuF0Bе}SщфЂс–иWљвнчДfѕK6q(3њЉ пГkЏћб‰Мо4Яfжž”р]Б4zoxВ1(aˆ†л8Ј„'П}U8*v$ЃzY†[™'8’K@HBЩ–Xz‰Hь ј=їф.ьnрЪсRЕЪДџКЙџуrЇдW­КъTŽRzЁРПOFм$%‘e<‰_\ Dц+И|\#аWЄ  ГРA@ Щ0Lœ5б5Ÿ|šѓј)EKzц5mчБ2v&`!5ї1Љ№jŒˆaЖЅ1qЧœ8hє™ЄПf ƒнw]фѓO9›ˆ­oіcˆЭ=9›<œМњ…Я‘t”LО3™ћХ ОGѓ‘иOїM*8[Џ~S4ВZЌ˜М…LПыsб}‚=і?_†КЕhкB…žл(§§ыƒ8њЇc8ќЮў~й„хдй|А эVdQОkЦЉ2ф/ЅPчЪіщГkqO2yboЃ2ЯB?Дœ.!Н7‡љъњ/ @Шt{ уyОџ ’~Ђ{ќ`)ДР6%ЕџXіѓ—aшщV’Б|Џ2цSFl5eЬЖs–сЕ g:Нс›dб@Я.эK.€ЛѓяKР+‘(Ф С‰Ж••ѕЖТхЬ€P5ЋИЮ ’З2C= H|гxп‡™Š#ЦžКї”М’0”Tр Ў€j5Оš@сб€Ќйrр Ж† ˆйћЌеО,‘EаU/ф,=Юз Ёрf;–P‚ЛўHц"9љHe|_Д“uжжѓV…2іРьЊАэГАюХVд/ЃптDіхOXœˆѕЯєbю}­и№Нљ8ђЇуr 7џсfŸ›Ш0Gєъ8Ъ;ѕњvэЕŸ%щў ’s,(ЇaаНŸ@RN97ФмkBЩ3ЈpВљRG|TШс€Њ§Д?8ГžlFЦR›ГЃ/‚ Ž}iш|Ј‚D dЉEХ.ОЮ<DГuXо@l'BY=ˆšщ…рrOuћiЬ—Цx‹јc<Зћ?Ž@ dŠМ'˜KЩ–fџещщщџ‹ AЮpР€€N+mZm`šSgB€/ JюЙъšрыЎ%@ЙџNw›1uћНдЩнБ“BЛ"˜Eї@.uгяЪсIOљ†GR˜\Г€б1ВжFЂўцtЏAѓ 9XџУNЌ{ЙЭ[’QмF­џŽtэ+УОŸ-Т­>„ЃяюТ–gЃs)ъ—$Ђf+‡ бМ+к}yhЛНƒ9™йяїЧМ'&aЮ#еHЃ„WбЪ–йЬГ‡уЦœˆ&њ2‡rpа^N оЧD8Š6'’-hgыњ7цВ"р‹ЖћFQ+0‘р13НРœ@УбLt=R…6ХїzАˆЭI,UкЉ œMРшЉAпЙ šъ+е уhјцЅL;АHКСЋЄzk3й SSSџб$ŠUГъє2’`F{’иО’`фРфEрO †hdДG{f зеШ€šјп9яo*{'KБќ3qэТрЗQGьF nІRh#~6уч5$Q(ГšТї”P3?•J:ўt›)гѕШd Qv+ПЧЩœЋf&Ню&Г wќŸЏУБ?РŽŸ.Рœь8$еж1›ЩТNvьѕyЃ~}$њяЌBяzЮ–cюcL r"oі Чp=3‰яUŒТхTљ]ф‡А ”­Cппq6CŽ<Ж№–гр; ­ј Gw-O lЗ ЁЬ+$@тx=Б\1}ќoўK~хи™ўЬW„Гq‰„%*9Vищ9ф‘˜yM!№]ЏЇтO+—ЈПк—ЖЫ‡•лg а U(  ЋyšАк}gNNЮЛЦPлЊX$jЉбU’А– ˆ+H7Я€‘џ4!€<€БzЦђЦъ-v5VœКwЙџŽа^AЙы}ри ŽПЊf{lы‰|єн[ŽсGсGУ)'™eМфAvыэIфш-:Љ›пР,~ЅЕв{tАМЗ'‹юЉAнмHћУ ьџйц"ШtиYG5Ёш9–•4ю…ЄЗ0i˜>Э•+S1э`Іь#ihE4Чw’?`GхЕ‘”эІt‡{fQМГэюЮщЃжпVNАqS&ГљlкaѓNѓщJ$є ˜!@WTЛbКIэmѕц XфЏЇjб2гI6нТ ХЗS‹€+]f,Ки‚мчџ<Ы=м{Гuqq%pЙхПЦй№]НЃ `@@с€h—Ик™\AoрћT4  “LГ$~)!Lз*€ЋАsчNчРз€+hЌ€‘s5~WР_ FOњЌЂ yPN А€ЭvЊтВGаƒкўœ–[Œ-o р6*ѕz{-–=пŽdNд­ к—!†ёrЅЖ‹ЏЕqv^$В— ЊС!vžЮГ9 `^ –оGА‡'"!Bх 2QЗтR3sкю\†н,Лu)ФTсШ№bшЧЌ55љТ‘2УyС([JА!‹Yќкэд왆4&чІ‘дvеŠщђOЁVЫiВiаEыRш№їзsа‡,gј2/6цk­ЄўrЮРБbЪQlgЮхЩO2бжDц/Ђœ‰Пxz б­ўopЯЭчRќ/P6—ІќЊbхnќљ’A@7Xс€м­ИЫ7_.˜И— Т­ЌМЊЄ•Ћ' ž P#ИL3ˆ@JаhЏOУИЊ-@#:–€QОZ=Хџ Ѕ*(œХXЇьаЃMиѕ?Vу&ŽтОўЭ˜їP КЯV24( …з#7aЫ/‡БђхN |“Т‡xRSw?gyтf Љ•nџZЖдЖЃ›9і§љЈН†НјGђ1|ЮЁћщтуd`іпwёgї‰2,фkЮ>OСћи:м‹'‹ћГЃoY<ъvА]ј@кŽW ЇšTё™†Ъu1vКˆ“|XКc~)ЏЁ|ўьБhПаР>†;’Xо ЂЄ™‡jњa‚/oЇџHЃ…0&њ”3h ЈrošтX-ˆlї}з+ЬК™{­Ÿk2—ш|ДТЁedєQ'оD,чћe. ІGрA‰0RŒяЖГŠ‘I†2уsШиЪА‡дрЊGwјР?зу~юЏaЎ\Ъў‹ўЋ=ш>§џŒпМ…ё­uу…ОjПT-Vё˜єи} –ggg?Loр-ШP>@ž€щš† ЈL7–,Иi’БаЯбmРІ(P2бЕ`М@р5žs\РYўЋ,ƒ}8’§№,ƒёTLaЙ­† МС‡+аЯЎКК-l Х!NzoЦ%Рч{ЃŒЉиЭ:МŸы‰BЦж“nЩGйЊXчфнЉ[гYћ'So(ŽсЌћ'Ѓэжєœ)Ує[ђ0|Бž]… нЈлŸФX=mRVМ2‚вkЈРГЙy§qШŒA§vNjg~€Їј„B ˆžфКёe›Љ=И4оы3‘=k •ыЈћ‚­О$“Бг‡иЧя_Ђ$&Л fЃœ"йlѓ•8h\—7чDpŽA85|Т=Е€Ћ“ЋžKeiyЁюЖпџDуwWo@” дb€@B}aC111{9Њъi–џ(OР„’+PЉЫP(`І}pбщoДUј2@зќЅ@E9ь“шЯ‰#c/‰šјщєXŽ;”ŽЩ{RPЭ’Xуu1ˆЄ‘цŒ щ`КIЎi;S‚Jqђ–2Vgn ’™јТU1ˆяфd VŠsЂьмуяь]ьея  Шц4t(Цд]™шЛЃ Ÿš‚і…|L,‡wVQ?А™нœ%Иžƒ;n,BFG(bАх№ЕhР!™јаШэL“Й—иC№щД!Ѕ'’]}Й, F!jЊъ0Uє:Rщ9ЄЯ#?cПcЈX\sC:;ўxњї9џO—?vІЫ‚l0jїћНWАГёg—\џ.гљчnћ§+€+ˆ+ м€b0…T›J+G ОЖtкдЙ5— У[шт>Э С›ђF#PЭAЂkPЈ$ТЧъ дщ.#—БЫ#PX`€ŒћЏФЁ)Ъ0б€ЧЫј2р#`G|e#Ї‰ю№&л8 Ј€ЩГxЮт„н,’ГќL"MЮМNмЭƒc{b™ LЄ:nйц&р"‘N1|%юЈ'ЫFœ&гgpЄW+н№VJ†/ŽBЫўLй™ŽЦЭЩhиH^џ,Юп›‚™Ї˜yw5Њ7ІЃv[6І-AЩ‚x$5ј’BЬЁЃ‘M'™ЧсƒœХTћYЯФe2#Сў™ЧеЮЅЌП[ёч*0јЛ…ђЄФ"9&• UŸ•>›Т% ЩЫ)Lа—лЧ5ФЎУ LоKжры;яJWRеї:вiяs.\Њ Ј&ФЙ€УЪС’\жˆэУјNŸїЂ&y§4ЁУыџ%ЗQІ‹ RБ:нї0єрщŸн„\m\%пЇž*@§a(ЁЖп0;љГŒБzšЪК~У€|јГ옣#ЋeLтЌ!`ЛOQ <•я RГXЖ3УП&1$ХL@Ь oD№ѓ$ј;?ЄЦѓ—мMjљч"—Ћт фшЫ‰CLЎTЎ,.Е‹nlA‚Ъ>"~ШKрILLмШгђv–/‘Tє4впв џЏЋQۘ]OncШњЉЪƒŒZ?ЕtЂ+І7qНNv /•Ё‹ДdŒ]DWƒŸ?ОГЂсj№JpКžєЦЭwџ­“оНќ)УкŒћІёПЯЦЋп&%%§˜КŒЯ?тххuЏg€х\XЙѕеєРџ“3ќЖ}$јН‰dм•P6Л’’YеlиЉe,_ЦeфѓWђдf_Нюy\ЗзћЁ,/јЅXзѓ>*/#аUТЖ:8з:7jŠчЯЂZ№uag‹pк & I jиE­О[8їљцrШШьхcGП—оњ_cъ§žЖ9ЌOUxМTi}%АдђЃ€bЫџє/ВМпќ^t ‡ƒ№ёЩ,BУЉі€нўфЙaЌФ!| ЩJ<œRc§Ё—Э"ЊЏОsПіƒ~TђSxщVќљ €ыЅК‚’7 ”Хе—*я@€ Мyy\Ъ”]БЙф)ˆ .їPйa'0p-тЩy#ЫhЧщb“'яw /3ЄјGžаПбЂ1 ƒж’8Љ– [K4eИJ”:ехЮ›“]ќужЛМС‹ѕ8кНWlЏњОт{3ьƒџп‘0ѕ^ы/ђѓѓ_"њ™”””Y-Йaа~ЋеКŒŸEюЏж"Ў%\:еПЭ3ауІ  ЏsО – ‰-ОП,Й6цУŠmЪXО’Їr ѕђГц…џSpхЭИvяџMнџž1і‹ИVПK~qVн+•kEЄшІr)i+abКё7GLДќ)Н?i]ўˆЌbmŸЦ[Н#•‚Кэщ}!F7yџ1ЌкѓЕРLS^‘–ѕ\Ћ}’-›ќ2ЌыrЌлƒЫaо?Ћї{ЮVч§œ_žхй rgУ&њ=RыѓL`‘чж0ЫR^ƒ _пЏЙFП %™нJПМ _‡ F‡ rяєEAЈЏAjЏrUfTAž‚6p9—М ђ”-nЛМ‘Ty@H=fˆk.—ЈЄ‹”o Oa?Oй\7в ярi|A‹ђ з7x*ƒдмgЃПDwнЙhШ/ёw/б˜_"gџ%>ўy&ыОA*ДsёфО@Э„ |э{bccoт:РЕŸЉmz_.еГ•ивѕшКФlгujуыКu§SИtњЉчB?'дyљё#ќ)PX”ъyKиПšцљF\Їял C‘Г4тw‘ЕОїzЧYіљeYŽІY7јЦXG5ыѕT™б=д=UHЦ%№еНГ.л7кsВ­ЦуСИ6ПЗЃšМосПйрѕ—ИџwЂ›}ўЩЦј<АауqŸDЫ.ЋЗѓњuЭŠгеŸ_СКP%ЁНЮ3Ьвтh№ŽЗЬѓєqzr№дcѕSFЎЯЅвžЎЋ‘Ky!Н†N}%ќ*ъёЛу~оŒЏу?&‰шъ!(`@A›UB'‚€A6•Ыƒ<%‹ђ”l@(ƒЌЭ%—WЅM'#гF”+,oBЦЇ„Є Б“Kо…bPЇТ-‰YцwњЛЇЧыyz~Чхзвыjуkг› Џї—Бшzt]к№КN]o —Ў_ЙШ2Tв2žўЎЧ7^~MНпke чсmЏіКƒЇќQu~‡­~V5Ьш:єѕx=ЏK'Њ<-y]КЗЪбИzbКЗл<жпkƒэжu!eї…8<žчЯЧƒьžGR­›­!V—>“РW@Ќы“з&o"ѕђвїЂЯЁЯЃїжїRrљЇ<;§Ю|^}wzЌž#Уз5ъћ–‡Ј“пmќМ KџЦХfУŽUtŠiуJ Д™Е)ЕБdLкd2(mJm>mBmЦ.‡оKљЙц.}і’Ызу$Ьi< =_KŸA€ЂзвїЁї7KџЏчш3ыяњlzЌžcуш ˜єЛŸ7С§япюР•€Aa„mt…кPЦее&е2`ЁЭЇMЈЭЈMi6Њ MKЦ)бJuYцwњЛyЌ6ЗyБ6ЗоSя-ЃжѕшКt}КNmx]ЗЎ__Њ“O`€Oгce$Ў*“ЁЛz:ŒЎOŸOяkN}зUїSџєгЛєўК]Ѓ SŸK *р1рЅџзчжпѕyt]К>]ЗYzбп…>ЏыgжћtДЬgзѕpв5™kМ|Љюю;№я€Г‘]O6cDкXЎ›Sд†6Њ6Ё6ЄY@ЬІ§ИŸЦ€Эѓє:z=Wƒ6F=кА]OaГйЭg1Ÿвѕ3щГŒ6PŽ 툑РЧœІ2z]—1NНпЧ•y_н;ѓ>њ,њмžФЬkЛžдzmзeМ НЏљєпf™яI?Эѓ\ПKї^wпqПЎЬ—й|ЎвD\7эЧmр+mц/z’Ц@eŒ6.§ |d˜cІWКW/ЫЎ Н$ŸtR~эбїњJя=ю_Жћнwрыv\РЈ н,7œGёYю‡+Œ>н]_џГМІћБю;рОуpЦђdFџnоЦ§ю;рОю;рО3wрџPћP:”ЎIENDЎB`‚(€      #   !%),28=@BGJJIE@@;60*'# ,;Op" wE4" ,b}d@) %.>O\r)))†///—222Ѓ555АAAAМFFFУKKKЬLLLбJJJбLLLлLLLпKKKпHHHпAAAз<<<а:::б111Ш,,,С$$$ЗЊž|fYUZm‹ EЦg'єs.њ:Р:В2; |GмJ§h+џ Sђ/ МkUVu)  " œ†… „h>) !-CZ%%%{888šHHHГgggЯxxxш€€€ї………§………џƒƒƒџƒƒƒџƒƒƒџ€€€џ~~~џ|||џyyyџwwwџsssџpppџlllџhhhџcccџ___џ\\\џWWWџRRRџOOOџJJJџDDDџ???џ999џ111ћ***ђрб5л \&јn1џh-џ%…?џ(Aџv0џ b!џ@Т _e LЧ_(џFџ]-џr8џ^-џb,џ Jт3кFх Kј Iџ[џFџZџ_џC§5УT.&=Y „888Џ\\\зwwwіŠŠŠџ–––џžžžџŸŸŸџŸŸŸџžžžџœœœџ˜˜˜џ“““џ‘‘‘џџџŠŠŠџ‡‡‡џƒƒƒџ€€€џ}}}џyyyџuuuџqqqџkkkџgggџcccџ^^^џZZZџVVVџQQQџLLLџHHHџCCCџ<<<џ312џ)"&џH(џY#џ@џHџ ^)џg+џ ‚;џs0џ ]"џe(џNё Y&ќf0џx>џY+џW+џ^/џs;џ&€?џX+џQ џd(џi*џs.џb$џ_#џx/џEџJџ Yџ- НI)!7aš<<<ЮWWWђlllџ~~~џ‰‰‰џ’’’џšššџЁЁЁџЄЄЄџЇЇЇџЇЇЇџІІІџЂЂЂџџ˜˜˜џ”””џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџFFFџ=<=џ,5.џJ(џy9џq8џ ]-џR!џ€;џs0џ a%џn,џVџHџR'џd5џ'…Iџ.‘Nџs;џ5‘Iџ(y:џ!q6џL$џ @џS џk)џNџj+џn*џz0џf&џ\!џf'џPџOџ—> !?|'''Ф@@@іTTTџbbbџnnnџ{{{џ‡‡‡џ‘‘‘џ™™™џЁЁЁџЅЅЅџЈЈЈџЉЉЉџЉЉЉџІІІџЃЃЃџџ™™™џ”””џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџFFFџ>8<џ#N0џ|3џ)’Lџ&Iџ `*џw5џ%ŽCџ ˆ>џ j'џ.‰?џm6џj;џg:џ+Oџ.”Oџ=Џ]џu=џ;ŒIџ0{=џd/џa/џO$џ>џp/џr1џ <џ)Œ;џs,џ ]џh'џ#‹;џ Xџl(џ Xђ p52 w"""Ю888џFFFџQQQџ\\\џhhhџuuuџ€€€џŠŠŠџ’’’џšššџЂЂЂџІІІџЉЉЉџЊЊЊџЊЊЊџЇЇЇџЄЄЄџŸŸŸџ™™™џ•••џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџ?;>џ*C1џ~6џ?А]џVЩsџ@ЉZџ|8џ,“Gџ „=џt1џ Iџc9џ.UџuDџ1šZџ-“Uџ0™Uџ)Lџ6šOџo4џc.џr8џ]*џm1џ$‹Aџ9џu1џ0“@џe$џUџe$џ4џp+џ%‰:џd"џ8ЯP*  EБ---§888џBBBџJJJџUUUџ___џiiiџuuuџџŠŠŠџ“““џšššџЂЂЂџЇЇЇџЊЊЊџЋЋЋџЊЊЊџЈЈЈџЄЄЄџŸŸŸџ™™™џ•••џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџA@Aџ756џ#j5џ.œKџ2žQџ&DџWџf%џ†=џ„8џ {<џl?џ!{JџKГmџRГmџ!tFџ|Hџq=џv=џ-‘Lџ|=џ%ŽEџ j-џp1џ/˜Hџ!ƒ:џ,@џk(џNџOџ Zџ Sџu/џ+™Dџm)џ c!џ' œ6JЮ///џ666џ===џDDDџLLLџTTTџ^^^џiiiџtttџџŠŠŠџ“““џšššџЂЂЂџЇЇЇџЊЊЊџЋЋЋџЊЊЊџЈЈЈџЅЅЅџ   џ™™™џ•••џ‘‘‘џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџBBBџ<6:џ$P0џ!“>џŒ?џ u.џ!šFџ,ЈPџ!’@џk!џ#ˆ;џ/˜Oџ8Ї_џT3џ<‘WџfЭzџVЎhџZВhџBЇ[џ4›Pџh-џ.šLџh,џ(ˆAџy5џu2џ|3џj%џ&‚5џ"4џMџh&џ"ƒ8џ4џWџ d!џ IеB 1Ф///џ333џ888џ===џDDDџKKKџTTTџ^^^џhhhџtttџџˆˆˆџ’’’џšššџЂЂЂџІІІџЉЉЉџЋЋЋџЋЋЋџЈЈЈџЅЅЅџ   џšššџ•••џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ=;=џ.91џy8џžEџ&ЃLџ6Й\џ1ВUџ1ЋRџƒ3џ#‹;џx3џ„Dџk6џ!}Aџ=œUџD™TџPЄYџcЭrџeиxџ0Eџk-џ&ƒ;џ.šIџ}6џy2џy/џt*џq(џx.џ0џ0‘@џ/–EџSџl*џ~2џ5Р? r...џ222џ444џ888џ===џDDDџKKKџSSSџ]]]џhhhџtttџ~~~џ‰‰‰џ’’’џšššџЁЁЁџІІІџЉЉЉџЋЋЋџЋЋЋџЈЈЈџІІІџ   џšššџ•••џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ>>>џ5.3џ K,џ—=џ—>џ<О_џLаlџ/­Oџ=џ~3џ h&џ,•Kџ3ЃTџv3џ q/џBџ0ЎWџ)Lџ"‘BџŒ=џ‡9џ-ЁLџ}3џ Aџ‡<џw.џ:ЂIџs)џbџ cџf$џt/џ}4џ5џx.џ& ЌEЃ333џ333џ444џ888џ===џDDDџKKKџSSSџ]]]џhhhџsssџ~~~џˆˆˆџ’’’џšššџЁЁЁџІІІџЊЊЊџЋЋЋџЋЋЋџЉЉЉџІІІџЁЁЁџšššџ–––џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ>>>џ504џ%?+џˆ/џ’4џ9ЖVџ+ЈQџ-ЄIџBЙ\џ#<џ‡7џ€:џ †Aџ$…@џ~;џ1ЃSџ%šJџŽAџ‰=џ {2џ ~3џ&ЅLџ s+џ!@џ1ЉRџ*“Aџ$‰8џ Wџy+џŠ7џm'џ!‚8џk)џn*џy0џ2й- Ÿ555џ333џ444џ888џ===џDDDџKKKџSSSџ]]]џgggџsssџ}}}џ‡‡‡џ‘‘‘џ™™™џЁЁЁџІІІџЉЉЉџЋЋЋџЋЋЋџЉЉЉџІІІџЂЂЂџ›››џ–––џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ>>>џ434џY+џš8џ=МVџ5ДRџHЩjџ7ГUџ1ЇLџ!•<џ+ЉMџ'œOџ&šLџHХmџ`х…џ6ЉWџ}5џ ‚:џ!œNџˆ>џŒBџ’Fџ$•Cџ3­Tџ%˜Dџz+џŽ:џq#џ!”=џ0џq)џƒ7џg&џ€5џg&џHџb#є >ž% m555џ333џ444џ888џ===џDDDџKKKџSSSџ]]]џgggџrrrџ|||џ‡‡‡џ‘‘‘џ™™™џЁЁЁџІІІџЉЉЉџЋЋЋџЋЋЋџЉЉЉџІІІџЂЂЂџ›››џ–––џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ???џ535џ'X2џ3ЖOџ8ЙSџ'ЅCџPдqџ.АQџ?ИZџ„3џ"˜Aџ@Сeџ2ЙZџ“9џ™=џ'­Nџ"ЇKџЂJџžIџ>УhџDЫnџ5З]џ&FџIЪiџKЬjџ‰5џv(џ‡4џŽ:џ. Hџ!ˆ9џt.џ[џn*џg)џ!q3џ)Š<џ~.џ1 9222њ333џ444џ888џ===џDDDџKKKџSSSџ\\\џgggџrrrџ|||џ†††џ‘‘‘џ™™™џ   џІІІџЊЊЊџЋЋЋџЋЋЋџЊЊЊџЇЇЇџЂЂЂџœœœџ———џ’’’џŽŽŽџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ@@@џ958џ(>.џ—7џKЭdџMаiџ”6џ$ЈIџ=ЗZџz/џ•;џ)ЈNџ8Н`џ)ЌQџ˜>џ0џЁ>џ.ВQџ–9џŠ-џ“6џ,ЏOџ7ЖTџCЗYџtхџ r&џn"џ u*џv,џ1ЂKџ…7џz2џƒ9џ6џ'u7џ,‡?џ6ЂLџ#…6џ ^њ" `---п444џ444џ888џ===џDDDџKKKџSSSџ\\\џfffџqqqџ|||џ†††џџ˜˜˜џ   џІІІџЊЊЊџЋЋЋџЋЋЋџЊЊЊџЇЇЇџЃЃЃџœœœџ———џ“““џџ‹‹‹џˆˆˆџ„„„џџ}}}џyyyџuuuџqqqџlllџhhhџdddџ___џ[[[џWWWџSSSџNNNџKKKџGGGџCCCџ@@@џ<8;џ->0џ ƒ6џ4ДOџ"ЂAџ Œ0џ"ЃGџ9ЕYџcџ0џœ=џ6ЗZџ!ЅHџЂBџ<У[џЂ;џ-џ’2џ.џ1џ;ЎLџ0АOџDН]џ9ЅMџ]џh џ3џ&™Fџ,ŸMџy4џk)џ#“Dџj+џ&g/џJџt-џ;­Uџ(“?џ ]Щ+++Џ444џ444џ888џ===џCCCџKKKџSSSџ\\\џfffџpppџ|||џ†††џџ˜˜˜џ   џІІІџЉЉЉџЋЋЋџЋЋЋџЊЊЊџЇЇЇџЂЂЂџœœœџ•••џџ‹‹‹џ‡‡‡џ‚‚‚џ~~~џ{{{џvvvџqqqџmmmџiiiџdddџaaaџ^^^џYYYџVVVџRRRџPPPџLLLџIIIџFFFџBBBџ@@@џ=<=џ656џ*G1џ•5џЂ<џ™?џ)ЊJџ–?џ _џ bџ9џ,ЗTџ1КWџ7СYџ=Ъ^џЈ<џ•-џ ‡"џ-џ$Ё>џ0­KџBџ ЃGџ?Чfџ2џ‚7џOџk(џ<АUџ%>џs.џu1џm/џ*@џ6˜Hџdџ`џ v+џ d#К***444џ444џ888џ===џCCCџKKKџSSSџ\\\џfffџpppџ{{{џ†††џџ———џŸŸŸџЄЄЄџЈЈЈџЉЉЉџЈЈЈџЇЇЇџЇЇЇџІІІџЃЃЃџЁЁЁџІІІџЋЋЋџЏЏЏџЕЕЕџВВВџБББџЗЗЗџЖЖЖџГГГџЏЏЏџЉЉЉџ™™™џ”””џџ‚‚‚џwwwџiiiџZZZџQQQџIIIџBBBџ:::џ777џ534џ082џ!j3џ&Y2џ)8-џ"D+џy-џu+џOџŽ:џ)ЛSџ-ОUџ+МOџЋ:џ!Ў=џ8СVџ œ3џЎFџЊCџ Œ(џ&ЉJџ*­Oџ3џ*ŸKџ(‘Eџ c џu-џ6™Fџr,џn+џ c$џe,џ'ƒ>џ=БVџ>АUџ2›Hџ2џ N“,,,P222џ555џ888џ===џCCCџKKKџRRRџ\\\џfffџpppџ{{{џ………џџ”””џžžžџЈЈЈџАААџЛЛЛџХХХџбббџиииџпппџцццџыыыџцццџсссџнннџиииџгггџвввџЯЯЯџЪЪЪџЩЩЩџЦЦЦџФФФџЦЦЦџУУУџПППџПППџНННџЛЛЛџЛЛЛџБББџЂЂЂџ’’’џ€€€џlllџXXXџDDDџ969џ2+1џ.+.џ0(.џ,@1џr4џ r$џœ5џЕ?џ9Э\џ3ХVџ АBџ%АFџ3Ъ_џЉ=џЎDџБIџ,ВPџ „'џ Š/џ9ЌTџ>ЋNџz(џd џ ‚<џ1ŒKџ W'џo5џ a&џ$x7џ4’Fџ,—Cџ,Gџ)•Cџ|1љ( K...!000ї444џ888џ===џDDDџKKKџSSSџ\\\џdddџnnnџzzzџ‰‰‰џ›››џЎЎЎџОООџЩЩЩџЮЮЮџШШШџПППџГГГџЃЃЃџ’’’џƒƒƒџwwwџqqqџlllџiiiџcccџƒƒƒџ‚‚‚џ]]]џ___џ^^^џ\\\џ\\\џ[[[џ\\\џ[[[џ\\\џ]]]џ```џbbbџhhhџrrrџ{{{џ†††џџ†††џŒŒŒџ…„…џqqqџ\\\џGGGџ958џ635џ"ˆ:џ НHџ+ТNџ'СKџ"ЙFџ#ЖDџГDџБ?џ-ЕIџ<Ц\џ7Щ`џ#ЋHџzџ#ЃEџ8К^џ"‰6џCЕ[џVџ>ЈXџ7žUџ7•Sџ1ŠKџY!џt1џ"‚:џ{2џ+‘Cџ,™Hџj*в" ***///е444џ888џ>>>џDDDџKKKџPPPџYYYџlllџ‡‡‡џŸŸŸџЏЏЏџБББџЊЊЊџ›››џ†††џvvvџnnnџjjjџiiiџqqqџџ’’’џ———џ˜˜˜џ›››џ   џЅЅЅџ‘‘‘џЯЯЯџІІІџЌЌЌџЇЇЇџЄЄЄџ›››џ‹‹‹џŽŽŽџ’’’џ‹‹‹џџ{{{џlllџbbbџXXXџSSSџIIIџKKKџ~~~џTTTџSSSџcccџpppџsssџqqqџg^eџ<KџЗ>џ)ТNџ)ТLџ$НGџЙAџЕ?џ#ИFџ>Ь`џHйnџ3Ц]џ$ГNџ˜6џ3КYџ7Й[џ-ВXџЄOџ•Eџr1џ<ˆKџ(s?џZ(џt.џw4џDВ\џ<ЄSџl,џ,œJџ]+кY& ...Ѕ444џ888џ===џBBBџHHHџaaaџƒƒƒџœœœџ   џ•••џ„„„џzzzџjjjџkkkџџ”””џЁЁЁџПППџвввџзззџоооџцццџцццџуууџрррџлллџгггџ‘‘‘џпппџХХХџРРРџКККџЗЗЗџВВВџЊЊЊџЈЈЈџЈЈЈџžžžџЈЈЈџЇЇЇџ˜˜˜џџ’’’џ‹‹‹џŒŒŒџiiiџЃЃЃџwwwџLLLџDDDџ;;;џ;;;џBBBџTOSџOfTџ!Ї?џ/ЬRџ1ЬUџ1ЪVџ.ШRџ>в_џCбcџ>Ю_џЖEџ<Ы_џLзoџ)ЕRџ$ЋJџ%ЊLџ5ПaџЂKџ*ЌVџ(žOџo3џUџ h'џ)†=џ|5џ#@џAЖ`џ5ЁRџ+žIџ5fDџ\W[э///ІV' ---v444џ888џ:::џLLLџsssџ’’’џ”””џ‚‚‚џnnnџfffџhhhџЎЎЎџВВВџКККџЪЪЪџдддџкккџпппџуууџцццџчччџцццџцццџуууџсссџоооџжжжџ‘‘‘џсссџЪЪЪџЦЦЦџСССџМММџЖЖЖџЏЏЏџВВВџБББџ­­­џЈЈЈџЄЄЄџ   џ•••џ–––џ›››џœœœџhhhџџџ‰‰‰џxxxџlllџ\\\џKKKџ878џ/-.џ"f0џŸ:џ)ЅFџ%РJџ&ЩOџ$ТKџГ;џИ@џ$ХQџ"ЖGџ,НTџ0ЛSџ=Хaџ!ЅGџ Aџ Aџ3ЕXџ1­Tџ„5џ€1џ €8џJВ`џEБ[џ>В[џ-™Mџ?Ў\џ{2џ=hJџxqvџvvvџ```№111Њ Y( ...H222џ555џWWWџ„„„џџ~~~џiiiџeeeџwwwџšššџtttџŸŸŸџдддџЪЪЪџаааџжжжџнннџфффџщщщџыыыџьььџэээџьььџщщщџцццџфффџмммџ‘‘‘џфффџвввџЭЭЭџЧЧЧџТТТџМММџИИИџДДДџ­­­џЌЌЌџІІІџЇЇЇџЅЅЅџЅЅЅџ˜˜˜џџžžžџjjjџ“““џЌЌЌџџƒƒƒџˆˆˆџˆˆˆџƒƒƒџwwwџ\Z\џ7H;џM(џW*џЈ=џ+ИMџ%ТKџ7ЮXџ;г`џ!УNџАAџ1МRџž5џ.ЗRџ ЇGџ+АMџ$ЌFџ9џq/џ},џ)—Fџ*™JџJТdџ:ЎTџ>џ…<џ‰:џs7џdphџ|z|џ{{{џyyyџ{{{џ‡‡‡ѓ===Ў \* //////ђTTTџ………џ………џnnnџaaaџoooџ‰‰‰џ›››џЎЎЎџyyyџ™™™џжжжџЮЮЮџжжжџмммџуууџщщщџэээџяяяџ№№№џ№№№џяяяџэээџыыыџшшшџсссџ‘‘‘џцццџжжжџбббџЪЪЪџЧЧЧџПППџЛЛЛџЖЖЖџЗЗЗџДДДџЌЌЌџЌЌЌџЊЊЊџЏЏЏџЋЋЋџ   џЄЄЄџuuuџŒŒŒџЂЂЂџœœœџ˜˜˜џ–––џ‘‘‘џ„„„џ‚‚‚џzzzџnnnџUZVџ6B8џ+џ"$"џ*d8џ'›Aџ$‰<џ0УXџ/ЧWџ АCџЈ>џІ@џ­Cџ š@џ,g:џbygџksџHXџ$›>џ#”>џRš_џ^–hџ/ˆFџ3џ2{Fџr{tџ„ƒџџ}}}џ{{{џ}}}џœœœџˆˆˆџpppѕCCCДa+ :::Эzzzџџiiiџbbbџyyyџ‡‡‡џ“““џ   џДДДџ|||џšššџиииџвввџкккџсссџцццџыыыџ№№№џђђђџђђђџёёёџ№№№џюююџьььџщщщџтттџ‘‘‘џцццџзззџвввџЬЬЬџШШШџУУУџТТТџНННџОООџОООџАААџЉЉЉџЌЌЌџЎЎЎџЏЏЏџЅЅЅџ   џwwwџ•••џЃЃЃџ›››џ›››џ˜˜˜џ•••џŠŠŠџ‡‡‡џ………џџwvwџ{y{џPMPџџџ:L>џ;WBџ9ЙYџ@дdџ#ЛNџБEџБBџ,ŸGџTiYџVLSџD?Cџa]`џ†џM]џrŽzџ•‘”џ‰‡џ‚„ƒџuƒyџ‚‚‚џ‰†ˆџ†††џ„„„џƒƒƒџ‚‚‚џ€€€џ™™™џџ………џ‹‹‹џ}}}јNNNЙe- "! IIIœџoooџaaaџvvvџ€€€џ‰‰‰џ–––џЃЃЃџЖЖЖџ}}}џšššџкккџгггџнннџуууџшшшџэээџёёёџђђђџђђђџёёёџ№№№џюююџьььџъъъџфффџ‘‘‘џцццџиииџдддџЮЮЮџЬЬЬџЪЪЪџФФФџСССџЧЧЧџУУУџЛЛЛџГГГџЏЏЏџЋЋЋџ­­­џЈЈЈџЌЌЌџ‚‚‚џ“““џЖЖЖџЁЁЁџžžžџšššџžžžџ–––џ™™™џџ‹‹‹џŠŠŠџ‘‘‘џ‰‰‰џVVVџџџ6mBџ$ИFџ ПGџАAџ™:џ1“Iџgvjџ‚{џ}}}џQQQџzzzџTSTџb^aџˆ‹џЉЈЉџџ‹џ‡„†џ‡†‡џ‡‡‡џ‡‡‡џ‡‡‡џ………џ„„„џџœœœџŽŽŽџˆˆˆџŒŒŒџŒŒŒџџ‚‚‚њUUUПk/ +> Vl T3# LLL~xxxџeeeџiiiџuuuџ~~~џŠŠŠџ———џЄЄЄџЗЗЗџ|||џšššџкккџеееџоооџхххџъъъџюююџёёёџђђђџђђђџђђђџ№№№џяяяџьььџъъъџтттџ‘‘‘џхххџйййџиииџбббџЩЩЩџЫЫЫџШШШџЧЧЧџЦЦЦџУУУџКККџИИИџЗЗЗџВВВџАААџЎЎЎџЎЎЎџ‡‡‡џ’’’џДДДџЂЂЂџ–––џœœœџšššџšššџœœœџœœœџŸŸŸџ’’’џ“““џ———џƒƒƒџ&&&џџ7?9џN‚Yџ0žHџ*–@џY|`џ€џ€|џ‰‰‰џ~~~џTTTџЄЄЄџƒƒƒџuttџ]]]џ^^^џ………џЄЄЄџ   џџ„„„џ‡‡‡џˆˆˆџˆˆˆџ‰‰‰џ‚‚‚џџ———џ•••џџџŒŒŒџŽŽŽџ”””џ‹‹‹ў^^^Х$$$q3+Ab+˜ Z#мq.јSх8­' ‰ L./5>5*! WWWRlllџcccџiiiџuuuџ€€€џ‹‹‹џ˜˜˜џЅЅЅџЗЗЗџ|||џšššџлллџеееџрррџцццџыыыџяяяџђђђџѓѓѓџђђђџюююџуууџиииџЮЮЮџЩЩЩџСССџ   џЦЦЦџЪЪЪџбббџаааџЯЯЯџЩЩЩџЦЦЦџХХХџТТТџФФФџСССџЙЙЙџЛЛЛџЖЖЖџГГГџБББџ­­­џwwwџ“““џЖЖЖџЁЁЁџŸŸŸџžžžџ›››џЁЁЁџ˜˜˜џžžžџџ•••џŸŸŸџ‹‹‹џџ...џџVTUџzrxџsrsџy~yџ‚‚џ‹џŠŠŠџ€€€џ€€€џSSSџžžžџ}}}џ‚‚‚џ„„„џqqqџ]]]џaaaџ€€€џЂЂЂџІІІџ”””џˆˆˆџ‡‡‡џ‹‹‹џƒƒƒџ   џœœœџџŽŽŽџ“““џ‘‘‘џџŽŽŽџџ———џџdddЫ###€Ub8Ѓf)чi/ћm4џ!‚?џz8џi(џcџ Tт of1–MЩ8­ v q L!fffYYYДaaaџiiiџwwwџ„„„џџ›››џЇЇЇџИИИџ}}}џšššџнннџиииџсссџцццџыыыџяяяџђђђџђђђџхххџЩЩЩџЏЏЏџœœœџџ‰ŠŠџ‚‚џghhџ‰‰‰џБББџеееџйййџнннџнннџЮЮЮџдддџиииџбббџЫЫЫџЦЦЦџОООџЗЗЗџБББџАААџ­­­џwwwџ™™™џВВВџ›››џЁЁЁџЂЂЂџ™™™џ”””џ™™™џЅЅЅџ˜˜˜џ“““џ–––џ‘‘‘џƒƒƒџ***џџPPPџџŸžŸџ˜–—џˆ‡ˆџ†††џ‰‰‰џ†††џƒƒƒџTTTџџ~~~џ‚‚‚џ€€€џ~~~џ|||џvvvџfffџeeeџ‚‚‚џЅЅЅџ­­­џšššџ‹‹‹џџ   џ’’’џ‹‹‹џџ”””џџ”””џ”””џ•••џ———џ™™™џ‘‘‘џ€€€џ[UYм@г k,џ ‡Bџ/Nџ8ЄTџ €?џ;­Zџ&‘Cџ&?џˆ7џ Mн<з e-џ „=џj,џ a$іh$љ Vт+ )FFFRRRЗgggўwwwџˆˆˆџ–––џЂЂЂџЌЌЌџНННџџšššџрррџкккџтттџщщщџ№№№џіііџљљљџэээџЪЬЫџЖЙЙџЏГВџ­ГВџБЗЖџЖМЛџИННџІЌЌџFJKџ„„„џКККџЛЛЛџЗЗЗџКККџКККџЛЛЛџЛЛЛџЛЛЛџСССџЧЧЧџЭЭЭџбббџЯЯЯџЩЩЩџЦЦЦџ€€€џ–––џИИИџžžžџœœœџ›››џžžžџ”””џœœœџšššџšššџžžžџ“““џџџ222џ555џ+++џ000џfffџџЏЏЏџ›››џ†††џˆˆˆџ~~~џSSSџŸŸŸџџџ€€€џ~~~џџ€€€џ‚‚‚џ~~~џrrrџlllџƒƒƒџЅЅЅџБББџŽŽŽџžžžџџ‹‹‹џ–––џџ‘‘‘џ“““џџ“““џ———џ———џ‹‹‹џ€€џRp[џp7џ#Jџ&†Dџt9џ)„AџAЎ\џWаsџQЩkџ:ЊPџ,™Dџ ƒ5џp4џ$Bџ{<џ)Fџt0џ g#џ4џ%Œ9џ @Ÿ DDDeeeюyyyџ‹‹‹џœœœџЉЉЉџГГГџФФФџ‚‚‚џџяяяџцццџъъъџтттџлллџжжжџвввџЩЫЫџИПНџ ІІџŠ‘џw|}џmrsџglnџotuџЕЛЛџ069џ__`џŽŽŽџ–––џ‡‡‡џ|||џ|||џrrrџjjjџhhhџdddџcccџ```џbbbџmmmџ}}}џ”””џmmmџ{{{џМММџЙЙЙџЕЕЕџЉЉЉџЁЁЁџ———џ–––џ›››џœœœџšššџ‘‘‘џџ}}}џ999џGGGџbbbџ^^^џ%%%џ<<<џYYYџ“““џЏЏЏџЄЄЄџƒƒƒџSSSџЂЂЂџƒƒƒџ†††џ………џƒƒƒџƒƒƒџ„„„џ„„„џŽŽŽџ‹‹‹џ‚‚‚џpppџ~~~џ‡‡‡џŒŒŒџЄЄЄџЏЏЏџ™™™џ‘‘‘џџŽŽŽџџ’’’џ‘‘‘џ”””џ”””џŒŒŒџ~|~џ3xFџ@џ%œTџ6•Qџ*ŠGџNСhџ Š?џTЯqџ]Ъnџf"џ]џ4џ ‚8џ)‚?џ/”KџMЦlџAЗ^џFН]џ6ЅMџ&Œ:џcџ( y fff mmmф|||џџ   џЎЎЎџПППџиииџџƒƒƒџЛЛЛџŸŸŸџџ‘‘‘џŸŸŸџЊЊЊџЛККџШЫЪџ˜žŸџGLMџ)+-џџџџ%%&џ­ГВџ5;>џ‚‚ƒџЦЦЦџкккџгггџЬЬЬџЪЪЪџ”””џŸŸŸџСССџЈЈЈџ™™™џ’’’џŠŠŠџzzzџhhhџTTTџHHHџFFFџFFFџRRRџrrrџŠŠŠџœœœџЎЎЎџЈЈЈџœœœџ“““џ“““џџŒŒŒџzzzџ666џDDDџ```џoooџ===џ•••џ\\\џ@@@џRRRџ‹‹‹џЄЄЄџ]]]џЂЂЂџ‡‡‡џˆˆˆџ‹‹‹џŠŠŠџˆˆˆџџŒŒŒџ‘‘‘џ“““џŠŠŠџ|||џЌЌЌџ€€€џ€€€џ‰‰‰џЇЇЇџЛЛЛџГГГџžžžџ’’’џ’’’џ–––џ”””џ”””џ———џ‘‘‘џˆ†џMtYџ~6џ€=џƒ>џ0’Gџ\џz2џ:ЏZџCК`џ;ЎTџ$…8џZџbџ2‘Iџ=ЋYџXвtџXЬmџy.џ„5џ?АUџ/”Aџ dё@fff sssмџ‘‘‘џЏЏЏџУУУџ­­­џ‡‡‡џ[[[џVVVџeeeџƒƒƒџЈЈЈџПППџ‘‘‘џщщщџѓѓѓџнрпџ—џ*,-џџ џџџ)))џЎГГџ5;>џƒƒ„џЫЫЫџоооџмммџжжжџиииџ™™™џЈЈЈџиииџЧЧЧџТТТџХХХџЧЧЧџКККџЖЖЖџЋЋЋџЂЂЂџ’’’џџgggџMMMџ<<<џ:::џJJJџoooџџЅЅЅџ›››џŽŽŽџ‹‹‹џwwwџ333џDDDџaaaџnnnџ<<<џЁЁЁџŒŒŒџ‡‡‡џlllџNNNџMMMџ]]]џЉЉЉџГГГџџџŽŽŽџ•••џ———џ‘‘‘џ’’’џ–––џџџДДДџ“““џ———џџˆˆˆџŽŽŽџЇЇЇџНННџКККџЈЈЈџ›››џ˜˜˜џ˜˜˜џšššџ”””џˆŒџb}iџn'џs.џ‚8џ„4џz,џ*˜Bџ8ЇTџ5ЋSџ3ЎQџEО^џ3Gџ|1џz4џt.џKЦjџYШlџ(†8џ\џi"џ ‹;џ1џ2`mmmxxxвŒŒŒџЋЋЋџœœœџXXXџ;;;џQQQџƒƒƒџЋЋЋџШШШџйййџхххџтттџ‘‘‘џ№№№џѕѕѕџнрпџ–џ/23џ џџџџ333џЎДГџ5;>џ††‡џЮЮЭџнннџиииџдддџзззџœœœџЇЇЇџзззџПППџНННџНННџЗЗЗџВВВџЕЕЕџАААџЎЎЎџ­­­џЉЉЉџЇЇЇџŸŸŸџ•••џ}}}џ___џ;;;џ---џIIIџ………џŸŸŸџ”””џuuuџ000џCCCџbbbџoooџ<<<џ   џŠŠŠџŠŠŠџ‘‘‘џŒŒŒџ}}}џbbbџRRRџuuuџЉЉЉџРРРџГГГџ›››џ•••џšššџžžžџџ™™™џƒƒƒџЛЛЛџ———џџ›››џžžžџšššџ’’’џ“““џЅЅЅџНННџРРРџЎЎЎџ   џœœœџ™™™џ“’џ‚џ|.џ.ЄJџ7ЈNџ<М[џ;ЖVџ0ЌKџ<ДWџCК[џ9ЎPџ%–@џ+šEџo'џ \џ+‘?џ3ЄQџ6АXџ?Р_џFЗ[џz.џw.џw-§# :UUU………Х˜˜˜џ[[[џ555џ]]]џџРРРџбббџдддџжжжџиииџнннџмммџ‘‘‘џюююџєѓєџмппџ–œџ367џџџ$$$џ'''џ<==џЏДДџ5;>џ‡‡ˆџЮЮЮџпппџкккџзззџйййџџЇЇЇџдддџУУУџПППџЙЙЙџЗЗЗџДДДџЖЖЖџДДДџЏЏЏџЊЊЊџЇЇЇџЃЃЃџЁЁЁџžžžџžžžџ   џ```џVVVџXXXџ)))џFFFџ‘‘‘џ}}}џ---џDDDџcccџpppџ<<<џ   џŠŠŠџџџŽŽŽџ“““џ–––џџoooџZZZџpppџЅЅЅџЧЧЧџЛЛЛџЇЇЇџšššџ›››џ™™™џ†††џПППџ›››џЂЂЂџœœœџŸŸŸџЅЅЅџЃЃЃџЁЁЁџšššџ–––џЅЅЅџМММџУУУџДДДџЃЃЃџ—–—џž žџRˆ`џ|-џ |%џ/ЈJџFУ_џfцxџ!˜:џ/ІIџ!<џ€3џ)‘Aџ‡7џ8џ$@џBЗ]џ?ЕXџ1ІJџ0ЄJџ>ВWџ …8џp+п ………УBBBџPPPџ———џРРРџФФФџХХХџЫЫЫџЫЫЫџаааџзззџкккџлллџ‘‘‘џяяяџєѓєџмпоџ•š›џ8:<џџ&&&џ---џ222џEFFџЏЕЕџ4;>џˆˆ‰џаааџпппџкккџеееџдддџџІІІџдддџУУУџПППџМММџЛЛЛџЗЗЗџЏЏЏџБББџЏЏЏџЊЊЊџЋЋЋџІІІџ   џœœœџ˜˜˜џ›››џ^^^џtttџЉЉЉџџFFFџ...џgggџ333џFFFџfffџrrrџ<<<џ   џџџ‘‘‘џџ’’’џ“““џ–––џŸŸŸџ˜˜˜џƒƒƒџiiiџqqqџŸŸŸџЪЪЪџЪЪЪџЋЋЋџ›››џ†††џПППџ–––џЇЇЇџЏЏЏџ   џЉЉЉџЅЅЅџЄЄЄџЇЇЇџЈЈЈџ   џšššџЂЂЂџЗЗЗџХХХџЈЈЈџЉЈЉџ‘ŒџCTџ6ЛVџ,ЌJџŽ3џDС]џ-ЄHџ6ЌPџRЫkџy1џy0џ6ЁMџPЧeџSбgџ,ЅFџ=ЕVџ4ЇMџ)—Cџ0žKџ!=џ H…fffYYYЭfffџЁЁЁџДДДџКККџНННџХХХџШШШџЫЫЫџЭЭЭџЮЮЮџйййџлллџ‘‘‘џяяяџєѓєџлпнџ‘˜™џ=@Aџ%%%џ111џ888џ;;;џNOOџАЖЕџ4;>џ‡‡ˆџЬЬЬџлллџкккџЬЬЬџеееџžžžџЃЃЃџЪЪЪџХХХџСССџЖЖЖџИИИџЗЗЗџВВВџАААџЇЇЇџ­­­џІІІџЅЅЅџŸŸŸџ›››џ™™™џžžžџ^^^џqqqџЄЄЄџ———џ•••џbbbџ;;;џ@@@џTTTџiiiџtttџ;;;џЃЃЃџ‘‘‘џŽŽŽџ•••џ”””џ———џ–––џ———џ›››џЁЁЁџЃЃЃџІІІџzzzџlllџwwwџ˜˜˜џЪЪЪџЧЧЧџ‰‰‰џШШШџžžžџЇЇЇџ­­­џЉЉЉџЇЇЇџЏЏЏџЌЌЌџЋЋЋџЊЊЊџЊЊЊџЋЋЋџžžžџџЄЄЄџŸŸŸџЏЎЏџАЌАџQ|[џ—8џNЦ`џDМYџ?ДTџ2ЄJџ‰9џ5ЊSџ;­Xџ(‘Cџ‹8џ"š=џZкpџ%œ?џ2ЈMџ0ŸKџf&џ%Š@џ%‘Aў( RwwwЏ———џЂЂЂџЏЏЏџЗЗЗџПППџФФФџЪЪЪџЧЧЧџЪЪЪџаааџйййџмммџ‘‘‘џюююџѕєєџмппџ‘——џBDEџ000џ;;;џAAAџEEEџVVVџАЖЖџ4;>џˆ‰‰џЯЯЯџлллџгггџЪЪЪџкккџЁЁЁџЂЂЂџЮЮЮџЛЛЛџНННџКККџЕЕЕџИИИџЎЎЎџЖЖЖџЕЕЕџЎЎЎџЌЌЌџЅЅЅџ   џžžžџџžžžџbbbџoooџЇЇЇџ•••џ“““џ™™™џ\\\џџHHHџ€€€џŽŽŽџ>>>џ™™™џ’’’џ‘‘‘џ’’’џ———џ˜˜˜џ™™™џžžžџЁЁЁџџ˜˜˜џџsssџІІІџБББџ~~~џuuuџџƒƒƒџзззџУУУџІІІџЅЅЅџЉЉЉџŸŸŸџЅЅЅџЈЈЈџЌЌЌџЌЌЌџЎЎЎџЎЎЎџџЛЛЛџАААџžžžџ›š›џЂ ЁџX‘eџ•1џž=џ)ЁFџDМ_џQЦhџGМ`џ. Nџ8ЅTџ$Aџ*”Bџ.ЃFџ;ДTџ.ЂIџ&–CџRЫmџ0™Lџ.˜Kџƒ8ј9ˆˆˆ•———џЈЈЈџБББџЙЙЙџТТТџУУУџХХХџФФФџШШШџгггџлллџнннџ‘‘‘џяяяџѕєєџптсџ•›œџGIJџ;::џEEEџKKKџLKKџeffџДКЙџ3:=џ••–џЬЬЬџзззџЪЪЪџЬЬЬџЮЮЮџ›››џЉЉЉџЭЭЭџЖЖЖџЛЛЛџНННџВВВџМММџВВВџЉЉЉџЇЇЇџІІІџЈЈЈџЈЈЈџЃЃЃџžžžџџЁЁЁџ___џnnnџЇЇЇџ™™™џ”””џ———џlllџџџ///џ```џџЊЊЊџЂЂЂџ“““џ”””џ™™™џšššџ›››џ———џœœœџŸŸŸџŸŸŸџІІІџtttџЄЄЄџЙЙЙџЂЂЂџЄЄЄџŽŽŽџ}}}џŒŒŒџИИИџеееџЮЮЮџВВВџŸŸŸџЈЈЈџЌЌЌџЈЈЈџ­­­џЌЌЌџЏЏЏџџНННџИИИџ­­­џЈЈЈџžœџ†ˆџT_џ,™Gџ/ЏQџCКaџqсƒџ3žOџ!‹@џ ‡>џ|3џ+™Bџ?ЖVџEЛ\џDДYџ3ЃNџ+œLџBГ_џ7ЄTџp/ђ&‰œœœџЉЉЉџДДДџОООџТТТџФФФџЧЧЧџЧЧЧџЬЬЬџдддџнннџоооџ‘‘‘џяяяџєєєџхццџЇ­­џORSџAAAџKKKџNMNџSRRџŸЃЂџ’˜™џ4;=џ­­­џаааџХХХџЗЗЗџФФФџЧЧЧџ™™™џІІІџШШШџКККџРРРџЖЖЖџБББџЛЛЛџЎЎЎџЉЉЉџЉЉЉџЄЄЄџЉЉЉџЇЇЇџЁЁЁџЁЁЁџŸŸŸџЂЂЂџ___џqqqџІІІџ•••џџ–––џmmmџџDDDџeeeџBBBџ:::џZZZџ“““џВВВџЋЋЋџŸŸŸџœœœџЂЂЂџЅЅЅџЄЄЄџЅЅЅџЅЅЅџЈЈЈџyyyџЄЄЄџГГГџЄЄЄџžžžџЄЄЄџ­­­џ›››џˆˆˆџŠŠŠџЏЏЏџвввџсссџЛЛЛџЁЁЁџЈЈЈџ­­­џБББџЏЏЏџžžžџПППџЗЗЗџ­­­џАААџАААџЌЊЌџŸ’œџ\…fџ"Ÿ>џ>­TџcЫpџ7ЈRџ…9џ„7џƒ2џ#ЂEџ)ЃKџ=Ж]џVЬoџ9ЉUџ)”Gџ)‘Gџ'‘EџTгŸŸŸ}ЉЉЉџЎЎЎџЕЕЕџРРРџХХХџХХХџЧЧЧџЩЩЩџЮЮЮџеееџоооџоооџ‘‘‘џ№№№џѕѕѕџёђђџЦЫЪџ‹џ\]]џaaaџz||џЇЊЉџЇЎ­џ6>@џ‚…†џаааџЯЯЯџбббџгггџПППџгггџАААџ­­­џзззџУУУџНННџТТТџТТТџОООџМММџ­­­џЋЋЋџЋЋЋџЅЅЅџЄЄЄџЁЁЁџ   џџЃЃЃџ^^^џpppџІІІџ”””џџ‘‘‘џkkkџџGGGџ„„„џџ‚‚‚џ```џ@@@џMMMџ‚‚‚џАААџЙЙЙџДДДџŸŸŸџЃЃЃџЊЊЊџЄЄЄџЊЊЊџ}}}џЄЄЄџДДДџџЌЌЌџДДДџЕЕЕџЋЋЋџЅЅЅџ———џ’’’џџІІІџЩЩЩџжжжџЦЦЦџБББџ­­­џЌЌЌџžžžџСССџЙЙЙџЎЎЎџВВВџАААџАААџЎ­Ўџžžžџ@ŽSџ“5џ~-џ|3џ‚2џ(Œ=џ5џ2ЋMџ7АUџ0ЅLџPОaџ(•Dџ„7џ‰;џ}1џ;ІІІsЊЊЊџБББџИИИџМММџХХХџЩЩЩџЬЬЬџЮЮЮџбббџкккџшшшџчччџЋЋЋџяяяџёёёџэьэџЧЩЩџЂЈЈџЇ­­џЃЊЊџ•œœџt{{џAGJџuwxџАААџЊЊЊџšššџ‹‹‹џВВВџ›››џЊЊЊџŒŒŒџƒƒƒџџІІІџЁЁЁџšššџ   џЋЋЋџДДДџМММџТТТџОООџОООџГГГџЌЌЌџЋЋЋџŸŸŸџЂЂЂџ___џrrrџЃЃЃџ“““џџ•••џgggџџIIIџџˆˆˆџџџ˜˜˜џxxxџQQQџIIIџrrrџЇЇЇџПППџЗЗЗџЈЈЈџЊЊЊџЉЉЉџ~~~џЂЂЂџЕЕЕџЈЈЈџЋЋЋџКККџЏЏЏџЋЋЋџГГГџЁЁЁџœœœџЏЏЏџœœœџ‡‡‡џЂЂЂџФФФџзззџЭЭЭџКККџœœœџУУУџТТТџБББџАААџЏЏЏџБББџБББџА­ЏџІЇІџuž~џq•yџVm\џ$v:џ y&џ‡1џ•;џ#œ>џ&—=џ'—>џ ;џ n%џz.џ„6ў0YЅЅЅjЋЋЋџБББџИИИџПППџУУУџЭЭЭџиииџмммџмммџвввџФФФџЕЕЕџžžžџЎЎЎџЗЗЗџРРРџЦЦЦџВГГџ“”џ†Š‹џ„‡ˆџ’””џИЙЙџЦЦЦџЙЙЙџКККџСССџЅЅЅџОООџМММџ›››џ“““џžžžџ–––џ‘‘‘џ———џŠŠŠџqqqџiiiџeeeџoooџlllџџŽŽŽџ   џЈЈЈџВВВџЏЏЏџЊЊЊџbbbџpppџЃЃЃџ‘‘‘џˆˆˆџџdddџџMMMџˆˆˆџŠŠŠџ”””џ•••џ›››џЁЁЁџџџhhhџOOOџeeeџџШШШџЦЦЦџЖЖЖџ{{{џЄЄЄџХХХџЏЏЏџЎЎЎџЏЏЏџИИИџЇЇЇџ›››џІІІџІІІџ•••џЏЏЏџœœœџЛЛЛџ”””џŸŸŸџНННџмммџДДДџТТТџНННџЈЈЈџ­­­џАААџБББџВВВџАААџГВГџЙГЗџЎЉ­џ|w{џ{‹џ.šIџ8МWџ’6џ%œ?џBН\џ&™AџKФdџ?ЊUџo*џ‚7ђ%ЂЂЂaЉЉЉџЏЏЏџЖЖЖџЩЩЩџЯЯЯџФФФџІІІџ†††џsssџvvvџƒƒƒџ›››џЖЖЖџШШШџйййџхххџыыыџ‘‘‘џнннџђђђџррпџхххџпппџжжжџеееџрррџЪЪЪџПППџФФФџВВВџЏЏЏџЖЖЖџЛЛЛџКККџФФФџФФФџЊЊЊџџКККџ˜˜˜џ———џ„„„џzzzџjjjџZZZџXXXџ]]]џlllџŠŠŠџ]]]џsssџЅЅЅџˆˆˆџƒƒƒџƒƒƒџ```џ џOOOџ‹‹‹џ”””џ›››џ”””џ•••џ›››џœœœџџІІІџ˜˜˜џzzzџ```џ___џџЫЫЫџ”””џџ­­­џЈЈЈџЉЉЉџЅЅЅџАААџœœœџГГГџЏЏЏџЋЋЋџЙЙЙџЕЕЕџŸŸŸџЯЯЯџЎЎЎџЊЊЊџ———џ   џџЛЛЛџнннџШШШџДДДџЎЎЎџАААџВВВџГГГџГГГџЖЖЖџЋЋЋџ~|~џ–’џ"8џ6БMџRЪdџ;БQџAЕWџ!<џ$•AџBЙ^џ/Lџ€9тЂЂЂXЈЈЈџЗЗЗџНННџЁЁЁџoooџJJJџQQQџtttџ˜˜˜џИИИџгггџцццџьььџёёёџѕѕѕџєєєџєєєџ‘‘‘џбббџсссџоооџпппџоооџЭЭЭџеееџдддџФФФџУУУџЭЭЭџВВВџЛЛЛџКККџВВВџЏЏЏџУУУџДДДџЛЛЛџŒŒŒџХХХџДДДџДДДџБББџЉЉЉџЋЋЋџšššџ„„„џnnnџTTTџ888џ///џJJJџџџ‹‹‹џџ___џ"""џOOOџŽŽŽџ’’’џ–––џšššџџ›››џšššџœœœџ™™™џ›››џ˜˜˜џ‡†‡џOOOџsssџaaaџoooџЄЄЄџбббџЬЬЬџЇЇЇџ   џœœœџЄЄЄџЛЛЛџ­­­џБББџЛЛЛџЋЋЋџ›››џгггџЏЏЏџИИИџЌЌЌџЋЋЋџІІІџџЋЋЋџЫЫЫџнннџбббџЛЛЛџАААџБББџБББџВВВџЋЋЋџƒƒџ™Їœџ ‰9џ7џ"@џ3ЊPџSЬkџHЛ_џ>Ж\џ-šKџ9ЈUџl*иЅЅЅMДДДџџgggџCCCџcccџ‘‘‘џЙЙЙџжжжџоооџоооџсссџхххџчччџюююџюююџёёёџђђђџ‘‘‘џкккџфффџгггџкккџдддџЬЬЬџиииџзззџЯЯЯџФФФџУУУџЭЭЭџМММџСССџЧЧЧџЈЈЈџАААџВВВџЅЅЅџˆˆˆџЕЕЕџЊЊЊџЌЌЌџЄЄЄџЄЄЄџžžžџЅЅЅџœœœџ˜˜˜џ‘‘‘џ€€€џgggџGGGџ444џNNNџ}}}џˆˆˆџbbbџ,,,џTTTџŽŽŽџ‡‡‡џ•••џœœœџ———џ———џ™™™џ———џ———џ•••џ„„„џxyyџLLLџџuuuџrrrџiiiџyyyџЉЉЉџбббџЪЪЪџРРРџДДДџЙЙЙџЁЁЁџЕЕЕџЗЗЗџЖЖЖџџЭЭЭџЊЊЊџАААџЊЊЊџКККџЖЖЖџЏЏЏџЉЉЉџџЂЂЂџНННџйййџзззџСССџБББџЕЕЕџ­­­џ………џЛКЛџ‚™ˆџEXџ+ЋLџ0ЊRџfл|џUРjџ%’Eџˆ>џ!Œ>џ d$ЕЉЉЉQ{{{џFFFџEEEџџЩЩЩџЬЬЬџЫЫЫџбббџзззџйййџоооџуууџцццџщщщџяяяџђђђџѓѓѓџ‘‘‘џгггџщщщџкккџжжжџкккџдддџмммџЯЯЯџаааџеееџЫЫЫџЬЬЬџУУУџГГГџЭЭЭџОООџЕЕЕџАААџЎЎЎџˆˆˆџОООџЎЎЎџ­­­џЂЂЂџЊЊЊџЅЅЅџ™™™џ———џ“““џŠŠŠџ‰‰‰џ†††џџnnnџIIIџ333џYYYџ@@@џ џBBBџžžžџЌЌЌџЂЂЂџœœœџ™™™џ™™™џ™™™џ———џ™™™џˆˆˆџ???џБЗЕџЏЕДџ ЄЃџŒџyyyџ|||џ{{{џpppџuuuџ›››џХХХџгггџНННџ   џЏЏЏџŸŸŸџАААџšššџЮЮЮџЎЎЎџЎЎЎџЋЋЋџЕЕЕџМММџЖЖЖџЗЗЗџКККџЏЏЏџžžžџ•••џЌЌЌџЭЭЭџжжжџЫЫЫџЖЖЖџ‡‡‡џУУУџЏЉ­џœ˜šџ:›Oџ%žAџ]ЦkџOМdџ)HџŠ7ќ{/у /\UUUџ˜˜˜џwwwџˆˆˆџУУУџОООџХХХџЯЯЯџеееџйййџпппџхххџфффџъъъџюююџёёёџєєєџ‘‘‘џкккџшшшџнннџуууџоооџЭЭЭџгггџжжжџШШШџЯЯЯџЬЬЬџЛЛЛџЩЩЩџБББџУУУџСССџИИИџНННџБББџzzzџЙЙЙџЏЏЏџЈЈЈџЇЇЇџЇЇЇџЉЉЉџЃЃЃџ•••џ“““џ‡‡‡џ~~~џ|||џwwwџwwwџvvvџ[[[џ;;;џFFFџ:::џ+++џ222џdddџŸŸŸџЖЖЖџАААџЁЁЁџœœœџžžžџЁЁЁџ€€€џџ­ГВџpuvџƒˆ‰џЅЋЋџГЙЗџЄЈЇџ„……џƒ‚‚џ•””џwxxџxxxџŒŒŒџГГГџаааџХХХџАААџЌЌЌџ›››џЬЬЬџВВВџДДДџЛЛЛџКККџЕЕЕџИИИџЗЗЗџЖЖЖџЗЗЗџВВВџ›››џЕЕЕџџšššџНННџЬЬЬџŠŠŠџЧЧЧџЏЏЏџЌЇЌџz™‚џ;џ‘4џ z+уHU6=& (………=§ЕЕЕџ~~~џŽŽŽџТТТџШШШџЧЧЧџЫЫЫџЮЮЮџйййџуууџфффџцццџъъъџ№№№џьььџёёёџ‘‘‘џоооџяяяџъъъџчччџтттџнннџеееџгггџЪЪЪџЩЩЩџЯЯЯџИИИџНННџГГГџВВВџОООџБББџЏЏЏџНННџ}}}џОООџ­­­џЅЅЅџЅЅЅџЃЃЃџІІІџ™™™џšššџџ†††џџzzzџwwwџsssџoooџlllџ```џNNNџ]]]џuuuџnnnџOOOџ888џOOOџ………џБББџКККџЏЏЏџЅЅЅџ………џџЉЎ­џ#$$џ!џ;>>џeijџ‘˜˜џБЖЖџЄЈЇџ‡†‡џ–••џЊЊЊџ•••џ}}}џ………џЊЊЊџЧЧЧџХХХџ›››џНННџЋЋЋџИИИџЌЌЌџДДДџДДДџДДДџКККџДДДџЗЗЗџВВВџЁЁЁџеееџВВВџЂЂЂџŽŽŽџ‡‡‡џ|||џТТТџЮЮЮџРРРџЎЉ­џ‘Ѓ–џB‰SД )ŒŒŒ(­­­їВВВџ|||џ’’’џТТТџУУУџЧЧЧџЮЮЮџЭЭЭџкккџнннџсссџтттџъъъџьььџьььџ№№№џ‘‘‘џкккџђђђџщщщџуууџуууџпппџрррџлллџбббџЮЮЮџФФФџХХХџФФФџВВВџЛЛЛџПППџЦЦЦџЃЃЃџЌЌЌџџМММџ   џЉЉЉџžžžџџЁЁЁџŸŸŸџ’’’џŠŠŠџ………џ€€€џzzzџyyyџsssџoooџhhhџ^^^џMMMџUUUџxxxџџЁЁЁџ™™™џtttџJJJџDDDџlllџЄЄЄџЧЧЧџžžžџџЊЏЎџ%%%џ џ џџ-01џaegџАЖЖџЈЋЋџšššџЎЎЎџЉЉЉџЂЂЂџ———џxxxџˆˆˆџ™™™џЊЊЊџЮЮЮџЧЧЧџПППџЇЇЇџ­­­џЏЏЏџИИИџЕЕЕџЖЖЖџЗЗЗџГГГџ   џвввџИИИџИИИџЙЙЙџЋЋЋџџ~~~џџИИИџЪЪЪџЯЫЯџІІІџŠŠŠ–––ђЇЇЇџ‚‚‚џ˜˜˜џСССџНННџЬЬЬџЧЧЧџЬЬЬџдддџнннџтттџхххџыыыџшшшџьььџёёёџ‘‘‘џлллџѓѓѓџщщщџуууџпппџвввџуууџвввџЯЯЯџЭЭЭџСССџПППџКККџЖЖЖџНННџПППџСССџЗЗЗџЎЎЎџ………џИИИџЂЂЂџІІІџЊЊЊџЇЇЇџЅЅЅџЈЈЈџџŠŠŠџ‡‡‡џ‚‚‚џ}}}џ|||џwwwџqqqџgggџ]]]џNNNџ]]]џzzzџ‘‘‘џžžžџЇЇЇџАААџЌЌЌџ’’’џiiiџLLLџ```џzzzџџЊАЏџ/0/џџџџџ,/0џ›ЁЂџ­АЏџ˜˜˜џГГГџЅЅЅџ   џЃЃЃџŠŠŠџЖЖЖџ‰‰‰џŠŠŠџ’’’џГГГџвввџвввџЛЛЛџГГГџВВВџВВВџЗЗЗџЛЛЛџДДДџЁЁЁџвввџЖЖЖџДДДџЎЎЎџВВВџЛЛЛџКККџ”””џrrrџџЈЈЈџІІІџ™™™–––эІІІџџ‰‰‰џПППџУУУџСССџЮЮЮџдддџЫЫЫџйййџлллџфффџэээџ№№№џђђђџѕѕѕџ‘‘‘џлллџэээџыыыџфффџрррџтттџчччџбббџФФФџФФФџЧЧЧџИИИџЯЯЯџЫЫЫџУУУџЧЧЧџЮЮЮџЬЬЬџШШШџ‚‚‚џЦЦЦџБББџЄЄЄџЄЄЄџЊЊЊџ›››џЅЅЅџ–––џŒŒŒџџ„„„џƒƒƒџџ{{{џtttџiiiџ[[[џLLLџ```џ}}}џ•••џ   џЈЈЈџЊЊЊџ­­­џАААџДДДџЈЈЈџ„„„џ888џџ­ВБџ899џ###џџџ џ023џЃЄџЅЈЇџ›››џГГГџВВВџЋЋЋџЊЊЊџџЧЧЧџЅЅЅџЕЕЕџЅЅЅџ”””џџЋЋЋџЬЬЬџмммџЪЪЪџЗЗЗџЗЗЗџЗЗЗџЖЖЖџЁЁЁџгггџЕЕЕџЛЛЛџЙЙЙџАААџГГГџЋЋЋџВВВџЗЗЗџšššџxxxџІІІџ‘‘‘šššщ   џ~~~џƒƒƒџНННџЩЩЩџОООџШШШџбббџиииџвввџнннџшшшџьььџыыыџчччџуууџдддџаааџбббџЬЬЬџЮЮЮџМММџЙЙЙџМММџЈЈЈџ›››џЄЄЄџ–––џџŽŽŽџџџ‹‹‹џ˜˜˜џ˜˜˜џЃЃЃџpppџžžžџГГГџГГГџЗЗЗџВВВџЎЎЎџЅЅЅџ–––џ‹‹‹џ‹‹‹џ………џ………џ‚‚‚џ€€€џwwwџiiiџ[[[џKKKџ]]]џџ–––џЃЃЃџЋЋЋџЎЎЎџ­­­џ­­­џАААџЕЕЕџГГГџ@@@џџ­ГВџAAAџ,,,џ)))џ"""џџ589џЃЃџЈЋЋџ   џЗЗЗџЕЕЕџАААџАААџ‘‘‘џЭЭЭџ›››џВВВџЎЎЎџЏЏЏџЄЄЄџšššџ•••џІІІџЦЦЦџоооџкккџЧЧЧџЗЗЗџ   џдддџЖЖЖџМММџЕЕЕџЗЗЗџЌЌЌџЂЂЂџАААџЙЙЙџЊЊЊџЎЎЎџІІІџ ŒŒŒц˜˜˜џџ‹‹‹џОООџКККџзззџЩЩЩџМММџНННџОООџИИИџЖЖЖџЏЏЏџГГГџНННџЦЦЦџЩЩЩџЮЮЮџЬЬЬџЪЪЪџЧЧЧџТТТџКККџИИИџНННџОООџНННџЁЁЁџЇЇЇџ   џšššџџ‹‹‹џ~~~џwwwџkkkџhhhџ[[[џeeeџpppџџџ–––џšššџЄЄЄџЉЉЉџŸŸŸџ———џŒŒŒџ†††џџuuuџkkkџ\\\џKKKџ^^^џ}}}џ•••џЃЃЃџЋЋЋџ­­­џ­­­џЋЋЋџГГГџЗЗЗџВВВџ>>>џџ­ГВџKKKџ777џ333џ+++џ џ:<=џ›ЁЁџДЗЖџЈЈЈџЛЛЛџЗЗЗџДДДџДДДџ”””џЬЬЬџЗЗЗџИИИџЏЏЏџЕЕЕџБББџЋЋЋџДДДџБББџ›››џŸŸŸџЛЛЛџйййџмммџІІІџЭЭЭџЕЕЕџЛЛЛџАААџЙЙЙџНННџАААџЋЋЋџВВВџЎЎЎџЗЗЗџІІІџ‹‹‹ ‰‰‰р“““џ|||џ˜˜˜џЦЦЦџЏЏЏџЄЄЄџ‹‹‹џxxxџ‰‰‰џџ———џДДДџЦЦЦџвввџфффџэээџщщщџьььџнннџиииџнннџжжжџ‘‘‘џдддџеееџЪЪЪџЮЮЮџУУУџШШШџТТТџЦЦЦџОООџУУУџНННџГГГџБББџЊЊЊџџџ’’’џuuuџjjjџlllџaaaџ```џ```џxxxџ‰‰‰џ™™™џ–––џ‰‰‰џxxxџlllџ[[[џYYYџjjjџџ˜˜˜џЅЅЅџ­­­џЏЏЏџЎЎЎџЎЎЎџБББџДДДџАААџ>>>џџАЕДџRSSџ@@@џ<<<џ666џ+**џ?BCџ™Ÿ џЇЊЉџЗЖЗџлллџЦЦЦџГГГџЅЅЅџ”””џгггџИИИџЖЖЖџЛЛЛџЛЛЛџЖЖЖџЗЗЗџНННџИИИџЖЖЖџ­­­џšššџšššџЋЋЋџДДДџмммџкккџЩЩЩџГГГџМММџНННџЗЗЗџАААџЕЕЕџГГГџЛЛЛџІІІџqqq tttй’’’џzzzџsssџƒƒƒџZZZџ^^^џqqqџЄЄЄџТТТџгггџдддџшшшџьььџыыыџьььџэээџэээџцццџнннџлллџуууџмммџ‘‘‘џйййџиииџбббџЭЭЭџЬЬЬџТТТџМММџЙЙЙџДДДџИИИџЖЖЖџЕЕЕџЕЕЕџДДДџЌЌЌџЇЇЇџЈЈЈџvvvџ›››џЋЋЋџˆˆˆџ{{{џjjjџZZZџIIIџEEEџSSSџ{{{џ‹‹‹џwwwџQQQџ444џhhhџ’’’џЊЊЊџЊЊЊџ­­­џБББџЏЏЏџВВВџБББџИИИџЏЏЏџ???џ џЋАЏџfggџHGGџFFFџ@@@џ555џEGHџ™  џ–š™џjjjџ–––џОООџмммџаааџ–––џкккџЎЎЎџКККџЗЗЗџЙЙЙџИИИџОООџКККџБББџДДДџЌЌЌџџБББџЋЋЋџ™™™џšššџЖЖЖџдддџкккџЩЩЩџЕЕЕџЏЏЏџЖЖЖџГГГџКККџЗЗЗџІІІџƒƒƒа’’’џ```џMMMџgggџ–––џџ™™™џжжжџзззџмммџмммџхххџтттџпппџцццџцццџъъъџсссџсссџрррџзззџлллџ‘‘‘џлллџиииџбббџШШШџТТТџЩЩЩџМММџЗЗЗџЙЙЙџЎЎЎџБББџМММџЖЖЖџАААџЌЌЌџЏЏЏџІІІџ~~~џ“““џІІІџ–––џџ”””џŽŽŽџ‚‚‚џiiiџDDDџ(((џCCCџtttџfffџ$$$џџ;;;џwwwџБББџФФФџОООџВВВџБББџГГГџКККџДДДџKKKџџnrrџœ ŸџMLLџNNNџIIIџ@??џIKLџ˜žŸџЎААџžžžџ~~~џ’’’џŠŠŠџЈЈЈџ’’’џтттџбббџТТТџЗЗЗџЙЙЙџПППџМММџСССџМММџЃЃЃџџuvvџˆˆˆџџ–––џЈЈЈџ———џџџПППџжжжџЯЯЯџРРРџЕЕЕџГГГџНННџІІІџ rrrиDDDџZZZџџДДДџШШШџ‹‹‹џžžžџиииџгггџзззџкккџмммџнннџщщщџрррџтттџфффџуууџщщщџрррџнннџрррџ‘‘‘џтттџжжжџЭЭЭџЭЭЭџРРРџШШШџОООџХХХџЛЛЛџИИИџИИИџЛЛЛџВВВџЌЌЌџЊЊЊџЈЈЈџВВВџ~~~џ–––џ­­­џџ‹‹‹џ‡‡‡џŠŠŠџ‹‹‹џ‹‹‹џˆˆˆџlllџBBBџ&&&џNNNџ\\\џiiiџZZZџ===џ666џfffџžžžџРРРџЦЦЦџМММџИИИџЏЏЏџ```џlllџџЂЁџ‘‘џSSSџLLLџGGGџNPQџЃЃџЈЋЊџЇІІџŠŠŠџзззџЌЌЌџ   џ‰‰‰џџУУУџмммџлллџХХХџНННџЖЖЖџЗЗЗџТТТџbaaџgjiџНУТџЋАЏџ ЃЃџ‰‹Šџ‚‚‚џ”””џАААџ   џˆˆˆџ‡‡‡џЅЅЅџЦЦЦџЯЯЯџЦЦЦџЙЙЙџІІІџUUUVVVЯlllџŽŽŽџІІІџВВВџЛЛЛџˆˆˆџ———џзззџжжжџпппџмммџпппџйййџсссџлллџхххџфффџцццџцццџсссџхххџлллџ‘‘‘џсссџвввџаааџЧЧЧџМММџДДДџИИИџАААџИИИџИИИџЕЕЕџЕЕЕџЎЎЎџВВВџГГГџВВВџЎЎЎџƒƒƒџ˜˜˜џІІІџ’’’џ’’’џ………џ†††џ„„„џ{{{џџ€€€џzzzџaaaџCCCџUUUџoooџ’’’џžžžџ™™™џHHHџ,,,џKKKџyyyџДДДџЯЯЯџСССџ]]]џШШШџ:::џџ‘‘џЇЋЋџ|}}џ[[[џpsuџДЛКџЁЂЂџЏЏЏџ‰‰‰џеееџТТТџНННџБББџЅЅЅџџ–––џВВВџгггџуууџеееџЬЬЬџКККџ999џY\\џ˜џdijџ–—џЉЏЎџАЕДџšœœџŒŒџЇЇЇџОООџ­­­џџyyyџџЖЖЖџЭЭЭџІІІџmmm­{{{џ‹‹‹џœœœџЈЈЈџОООџƒƒƒџ“““џйййџеееџкккџлллџпппџоооџоооџкккџоооџнннџуууџйййџбббџЯЯЯџЫЫЫџБББџеееџЭЭЭџЧЧЧџУУУџЙЙЙџЖЖЖџЖЖЖџУУУџЙЙЙџИИИџ­­­џЕЕЕџЎЎЎџВВВџЎЎЎџЌЌЌџЄЄЄџ|||џŽŽŽџЌЌЌџŠŠŠџˆˆˆџˆˆˆџƒƒƒџџ~~~џ}}}џzzzџxxxџwwwџaaaџVVVџpppџ‘‘‘џЃЃЃџЛЛЛџfffџrrrџ›››џaaaџHHHџaaaџџXXXџнннџЬЬЬџXXXџџ=@?џŠџЋАЏџЏЕДџ“—–џЁЁЁџЏЏЏџ‹‹‹џЫЫЫџДДДџЎЎЎџЗЗЗџМММџНННџЕЕЕџџ•••џЅЅЅџФФФџпппџмммџFEEџ_cbџtxwџџ,./џIMNџv{|џЄЊЊџЏДГџšœ›џЕЕЕџНННџЛЛЛџЈЈЈџoooџzzzџ}}}џІІІџmmmž{{{џŠŠŠџ———џЅЅЅџЗЗЗџ„„„џ“““џзззџгггџмммџиииџнннџсссџдддџрррџйииџРРРџТТТџЌЌЌџ›››џŸŸŸџ ЁЁџƒƒƒџЌЋЋџРРРџЫЫЫџЯЯЯџХХХџФФФџСССџИИИџЧЧЧџРРРџЦЦЦџОООџРРРџЙЙЙџЏЏЏџЇЇЇџЃЃЃџuuuџ–––џЄЄЄџŒŒŒџ†††џƒƒƒџ}}}џ~~~џ€€€џџzzzџyyyџvvvџbbbџ[[[џrrrџ‘‘‘џЉЉЉџЖЖЖџcccџzzzџШШШџЙЙЙџЎЎЎџŠŠŠџ\\\џIIIџxxxџИИИџсссџЙЙЙџYXXџџџ-.-џ€€џЕЕЕџБББџˆˆˆџгггџЊЊЊџМММџЋЋЋџКККџШШШџТТТџЙЙЙџЛЛЛџЅЅЅџžžžџŸŸŸџМММџIHIџ_cbџx|{џ џ џ џџKOQџЄЋЋџЋЎ­џЃЃЃџЗЗЗџЛЛЛџДДДџ~~~џТТТџœœœџІІІџgggˆ|||џ………џ’’’џЂЂЂџВВВџŒŒŒџœœœџЬЬЬџЭЭЭџлллџнннџкккџлллџЬЬЫџаааџХЦЦџЗЛКџЖЛКџДКЙџДКЙџИОНџЙООџЊЏЎџXYYџxxxџ’’’џЂЂЂџЄЄЄџ›››џџ–––џ‰‰‰џџЂЂЂџœœœџœœœџ­­­џЎЎЎџ­­­џПППџ†††џŒŒŒџЌЌЌџ–––џ†††џ|||џƒƒƒџ}}}џџ€€€џyyyџ~~~џyyyџcccџ[[[џoooџ’’’џЋЋЋџЛЛЛџbbbџwwwџШШШџВВВџЕЕЕџТТТџЙЙЙџЈЈЈџџbbbџiiiџžžžџдддџжжжџЛЛЛџЏЏЏџМММџФФФџБББџ„„„џкккџОООџНННџГГГџЕЕЕџФФФџФФФџКККџФФФџЗЗЗџПППџФФФџ   џ???џ`cbџ~џџџџџ034џžЅЅџ­ААџЄЄЄџЛЛЛџНННџЉЉЉџzzzџШШШџКККџІІІџfffwwwџ‰‰‰џ–––џœœœџАААџ‚‚‚џ•••џжжжџУУУџЖЖЖџЕЕЕџЉЉЉџВВВџМЛМџЗКЙџИОНџ ІЇџŠ‘џv||џlqsџgkmџosuџДККџ17:џrrsџŸŸŸџЗЗЗџГГГџžžžџ”””џ———џџ˜˜˜џџ|||џtttџjjjџjjjџdddџbbbџ[[[џdddџ}}}џ”””џ“““џ–––џŽŽŽџџџyyyџ~~~џџ{{{џdddџYYYџqqqџŽŽŽџ­­­џЛЛЛџ___џzzzџЩЩЩџГГГџЙЙЙџДДДџЗЗЗџКККџУУУџРРРџЄЄЄџ|||џhhhџ„„„џЗЗЗџкккџиииџаааџЗЗЗџ‡‡‡џаааџСССџЙЙЙџ­­­џ­­­џДДДџЗЗЗџЬЬЬџНННџНННџТТТџЖЖЖџЋЋЋџ\[\џ\_^џƒ‡†џ$$$џ'''џ џџ7:;џžЄЄџ­АЏџАААџЙЙЙџБББџЏЏЏџ}}}џЦЦЦџНННџІІІџmmm~wwwџ‚‚‚џžžžџБББџЌЌЌџџsssџ‚‚‚џƒƒƒџџІІІџЃЃЃџТТТџХХХџЭааџ—žžџHLNџ)+-џџџџ%%&џ­ГГџ3:=џz{{џИИИџФФФџРРРџВВВџЌЌЌџšššџЙЙЙџНННџЅЅЅџЃЃЃџЈЈЈџ———џ———џџzzzџpppџaaaџPPPџVVVџUUUџ^^^џnnnџ~~~џ‰‰‰џŽŽŽџŠŠŠџxxxџwwwџ\\\џSSSџsssџ•••џЋЋЋџКККџbbbџ{{{џТТТџЖЖЖџЗЗЗџГГГџЕЕЕџДДДџНННџЛЛЛџХХХџЩЩЩџНННџ|||џhhhџxxxџ•••џХХХџжжжџŒŒŒџбббџВВВџШШШџЛЛЛџЏЏЏџКККџИИИџЪЪЪџСССџЛЛЛџКККџМММџЌЌЌџZZZџ[^^џ‰ŒŒџ0//џ111џ+++џџ<>?џœЂЃџГЖЕџЖЖЖџКККџОООџВВВџ{{{џЫЫЫџОООџІІІџ```zyyyџœœœџ“““џqqqџbbbџiiiџџ’’’џЊЊЊџЬЬЬџЫЫЫџ‘‘‘џпппџхххџзккџ—žџ*,-џџ џџџ)))џЎДГџ3:=џxwxџФФФџИИИџБББџІІІџБББџЂЂЂџ­­­џЌЌЌџЄЄЄџЈЈЈџЄЄЄџ›››џŸŸŸџŸŸŸџџ’’’џџ………џvvvџqqqџ___џPPPџ@@@џGGGџTTTџvvvџ“““џўRRRўJJJџiiiџ‹‹‹џ   џЙЙЙџbbbџvvvџЧЧЧџКККџЛЛЛџЗЗЗџРРРџКККџОООџУУУџФФФџУУУџЧЧЧџˆˆˆџІІІџЧЧЧџ–––џ~~~џ‚‚‚џzzzџЭЭЭџлллџвввџНННџЙЙЙџУУУџНННџОООџУУУџЦЦЦџРРРџОООџЌЌЌџ[ZZџ[_^џ‘џ:::џ<<<џ555џ)))џ@CEџЃЃџ ЃЂџ˜˜˜џЮЮЮџжжжџУУУџ}}}џЦЦЦџХХХџІІІџyyyv‚‚‚џ___џDDDџfffџ~~~џЁЁЁџЙЙЙџЧЧЧџРРРџНННџЯЯЯџ‘‘‘џоооџчччџдззџ—žžџ/23џ џџџџ333џЎДГџ4;>џzz{џЙЙЙџРРРџСССџЏЏЏџГГГџ   џ   џАААџЋЋЋџЇЇЇџ›››џŸŸŸџ›››џџ•••џџŽŽŽџ†††џ}}}џyyyџtttџyyyџnnnџMMMџ999џ222џJJJџyyyўZZZќ??@џ[[[џvvvџŒŒŒџЈЈЈџ\\\џrrrџФФФџМММџКККџНННџНННџНННџТТТџФФФџХХХџЧЧЧџЬЬЬџˆˆˆџІІІџзззџХХХџТТТџАААџ™™™џ†††џ˜˜˜џНННџйййџпппџгггџТТТџРРРџМММџОООџШШШџЧЧЧџ­­­џ]\\џW[Zџ˜œ›џDDDџFFFџ@@@џ555џEHIџœЂЃџІЉЉџƒ‚ƒџџ•••џЎЎЎџ|||џгггџЩЩЩџІІІџhhhzAAAџKKKџ}}}џœœœџ   џЗЗЗџЙЙЙџИИИџПППџЫЫЫџбббџ‘‘‘џпппџшшшџзкйџ—џ367џџџ$$$џ'''џ<==џЏЕДџ4;>џwxxџЖЖЖџСССџУУУџКККџЖЖЖџ———џЄЄЄџДДДџЇЇЇџІІІџЁЁЁџЂЂЂџЂЂЂџšššџ•••џ‰‰‰џ‰‰‰џџ{{{џrrrџlllџsssџuuuџSSSџnnnџzzzџAAAџ333џ///џџ===џ^^^џvvvџŒŒŒџKKKџdddџЏЏЏџЋЋЋџВВВџИИИџНННџСССџТТТџЧЧЧџЦЦЦџФФФџЪЪЪџ†††џІІІџЯЯЯџСССџТТТџШШШџЪЪЪџОООџЈЈЈџ“““џџЉЉЉџЭЭЭџуууџпппџЩЩЩџМММџОООџТТТџБББџqqqџ!##џБЗЖџ^_^џLLLџJJJџ@@?џKMNџ˜Ÿ џЏВВџГГГџџˆˆˆџџmmmџ™™™џХХХџІІІџMMMlZZZџ{{{џџ›››џЌЌЌџЋЋЋџЏЏЏџКККџМММџжжжџЫЫЫџ‘‘‘џуууџыыыџзккџ•›œџ8:<џџ&&&џ---џ222џEFFџАЕЕџ4:=џyyzџПППџЩЩЩџПППџЕЕЕџЗЗЗџœœœџЋЋЋџКККџ­­­џІІІџŸŸŸџŸŸŸџџ˜˜˜џџŒŒŒџƒƒƒџzzzџvvvџnnnџiiiџlllџsssџMMMџlllџ†††џuuuџbbbџџџџџ///џXXYџ;;;џTTTџ’’’џ‘‘‘џџЈЈЈџАААџИИИџМММџТТТџФФФџУУУџЫЫЫџˆˆˆџЅЅЅџзззџРРРџТТТџХХХџСССџФФФџФФФџФФФџСССџЇЇЇџ———џšššџИИИџзззџхххџзззџРРРџЊЊЊџЗЗЗџџjnmџЋАЏџ^^^џLLLџGGFџPRSџžЄЅџЅЈЈџАЏЏџ˜˜˜џЊЊЊџЦЦЦџЊЊЊџˆˆˆџuuuџІІІџWWWWfffџwwwџˆˆˆџšššџЈЈЈџЇЇЇџЋЋЋџВВВџОООџЫЫЫџЫЫЫџ‘‘‘џпппџшшшџзккџ’˜™џ=@Aџ%%%џ111џ888џ;;;џNOOџАЖЕџ4:=џyzzџМММџЧЧЧџПППџОООџСССџ–––џЇЇЇџЛЛЛџЉЉЉџІІІџ   џžžžџœœœџ———џŽŽŽџˆˆˆџ|||џsssџlllџjjjџgggџiiiџpppџHHHџeeeџ‚‚‚џsssџrrrџ&&&џџџџџџџ-..џYZZџrrrџ‚‚‚џŒ‹‹џ•••џЂЂЂџ­­­џЕЕЕџЛЛЛџОООџШШШџ†††џЄЄЄџвввџНННџСССџФФФџТТТџРРРџЦЦЦџНННџСССџЧЧЧџСССџ———џВВВџšššџЇЇЇџШШШџкккџЉЉЉџъъъџ{{{џџadcџЌБАџ‘џhiiџswwџЗННџЁЂЂџГГГџ“““џЊЊЊџвввџШШШџЩЩЩџРРРџІІІџVVVJdddџuuuџ‡‡‡џ———џЂЂЂџЎЎЎџЖЖЖџЗЗЗџСССџУУУџЬЬЬџ‘‘‘џоооџцхцџилкџ‘˜˜џBDEџ000џ;;;џAAAџEEEџVVVџБЗЖџ4:=џ}}}џЗЗЗџЩЩЩџЪЪЪџРРРџУУУџ‘‘‘џЉЉЉџКККџЅЅЅџІІІџ   џœœœџЅЅЅџџ“““џŠŠŠџ{{{џsssџiiiџdddџcccџbbbџpppџHHHџdddџƒƒƒџsssџoooџ"""џџџџџџџџ џџ===џ]^^џvvvџ………џџ™™™џЄЄЄџЎЎЎџКККџ}}}џŸŸŸџЮЮЮџПППџХХХџЧЧЧџУУУџНННџЪЪЪџСССџФФФџУУУџЖЖЖџœœœџпппџЦЦЦџЙЙЙџЅЅЅџ   џšššџЮЮЮџыыыџžžžџ!!!џ$&%џosrџЄЉЈџ­ГВџ“’џЈЈЈџФФФџ–––џЋЋЋџаааџФФФџШШШџЪЪЪџІІІџVVV;ddd§vvvџ………џ———џЃЃЃџЎЎЎџМММџЦЦЦџХХХџЪЪЪџаааџ‘‘‘џхххџыъыџлонџ–œœџGIJџ;::џEEEџKKKџLKKџeffџДКЙџ4:=џ‹ŒŒџЭЭЭџеееџЯЯЯџЯЯЯџЭЭЭџ™™™џ­­­џШШШџОООџКККџДДДџЊЊЊџЇЇЇџІІІџџџxxxџnnnџhhhџcccџbbbџeeeџpppџFFFџcccџ„„„џtttџnnnџџџџџџџџ џ џ џџџ%%%џBCCџcccџvuvџ‚‚‚џџœœœџmmmџџСССџЕЕЕџЗЗЗџСССџРРРџСССџУУУџТТТџУУУџТТТџОООџœœœџкккџШШШџЬЬЬџЮЮЮџХХХџЖЖЖџЃЃЃџЅЅЅџЦЦЦџШШШџ†…†џ===џџ***џ‹‹‹џПППџЩЩЩџ™™™џЉЉЉџЯЯЯџЩЩЩџЪЪЪџЩЩЩџІІІџXXX+eeeїuuuџˆˆˆџ–––џЄЄЄџЎЎЎџЖЖЖџТТТџЯЯЯџиииџзззџЇЇЇџтттџшшшџжйиџЇЎЎџORSџAAAџKKKџNMNџSRRџŸЃЂџ–џ'-0џyzzџœœœџ›››џŽŽŽџџ•••џ~~~џ{{{џ‚‚‚џ‰‰‰џ›››џ   џЇЇЇџЎЎЎџІІІџ­­­џЈЈЈџšššџŠŠŠџtttџfffџ```џeeeџoooџEEEџcccџ………џtttџmmmџџџџџџџџ џ џ џџџ џџџ`bbџwyyџ```џ~~~џXXXџvvvџšššџžžžџЈЈЈџВВВџЛЛЛџОООџТТТџЦЦЦџФФФџСССџСССџœœœџмммџЩЩЩџЫЫЫџЫЫЫџЫЫЫџЭЭЭџЬЬЬџРРРџЌЌЌџЄЄЄџБББџОООџЩШШџвввџиииџЧЧЧџЫЫЫџ˜˜˜џЊЊЊџеееџЫЫЫџЫЫЫџЪЪЪџІІІџ\\\eeeёwwwџ†††џ–––џЈЈЈџНННџШШШџЭЭЭџШШШџНННџЎЎЎџžžžџЉЉЉџДДДџЕЕЖџЕККџ••џ\^]џaaaџ{||џЈЌЊџЌВБџ2:=џGKNџЊЊЊџЗЗЗџБББџ­­­џŸŸŸџ˜˜˜џ–––џџџvvvџlllџdddџcccџcccџaaaџ[[[џ]]]џhhhџtttџџ„„„џ„„„џџ|||џFFFџcccџƒƒƒџsssџmmmџџџџџџџџ џ џ џџџџџ џillџkmnџџ555џ999џ___џ}}}џ„„„џџžžžџЈЈЈџБББџЗЗЗџЙЙЙџЛЛЛџХХХџРРРџšššџнннџЪЪЪџЭЭЭџЭЭЭџЭЭЭџЬЬЬџЬЬЬџЫЫЫџЫЫЫџЧЧЧџЄЄЄџџЁЁЁџЇЇЇџУУУџйййџуууџЁЁЁџЊЊЊџзззџЬЬЬџЬЬЬџЬЬЬџІІІџ[[[fffюxxxџ’’’џЌЌЌџАААџџ„„„џsssџxxxџ‚‚‚џ˜˜˜џЕЕЕџРРРџЮЮЮџкккџЃІІџŒ““џЋББџ­ГГџ›ЁЁџovwџ(/3џBHJџЗИИџлллџжжжџаааџЬЬЬџЧЧЧџРРРџНННџЙЙЙџВВВџЌЌЌџЈЈЈџšššџvvvџЄЄЄџ†††џqqqџbbbџNNNџ???џ666џ:::џBBBџVVVџsssџKKKџdddџŒŒŒџqqqџhhhџџџџџџџџ џ џ џџџџџ џiklџkmmџџџџ%&&џ999џSSSџjkkџ{||џ‰‰‰џ“““џžžžџЊЊЊџГГГџЛЛЛџИИИџ•••џзззџШШШџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЫЫЫџШШШџХХХџЫЫЫџЈЈЈџТТТџЭЭЭџ­­­џ–––џџЈЈЈџџЋЋЋџчччџдддџЬЬЬџЩЩЩџІІІџmmmqqqь———џџcccџGGGџLLLџlllџџБББџЭЭЭџйййџрррџхххџщщщџыыыџсссџ{€џDJLџ;BEџ=BEџQVXџŒџгггџтттџкккџгггџЯЯЯџЫЫЫџХХХџПППџКККџЗЗЗџАААџ­­­џЉЉЉџœœœџxxxџЕЕЕџ“““џŠŠŠџ|||џrrrџiiiџ___џTTTџHHHџ888џ+++џ%%%џ:::џsssџ………џkkkџ џџ џџџџџ џ џ џџџџџ џiklџkmmџџџ џ!!!џ џ"""џ+++џAAAџXXXџpppџ€џ‹‹‹џ•••џЁЁЁџЅЅЅџ‰‰‰џЫЫЫџСССџЦЦЦџЩЩЩџШШШџЩЩЩџЫЫЫџЧЧЧџШШШџЫЫЫџЅЅЅџСССџаааџЪЪЪџЫЫЫџПППџЃЃЃџ†††џ€€€џЂЂЂџЩЩЩџнннџйййџІІІџ{{{ы[[[џ;;;џNNNџ}}}џЈЈЈџРРРџЯЯЯџиииџмммџоооџсссџфффџуууџуууџщщщџ‘‘‘џЬЭЭџзииџкллџфффџээьџцццџрррџкккџгггџЯЯЯџШШШџЦЦЦџТТТџЛЛЛџЖЖЖџАААџЊЊЊџЅЅЅџšššџpppџВВВџŠŠŠџџuuuџnnnџhhhџfffџhhhџmmmџoooџgggџWWWџ:::џ!!!џ>>>џdddџџ"""џ222џ444џ(((џџџџџ џџџџџ џiklџkmmџџџ џ"""џ$$$џ%%%џ'''џ'''џ***џ333џGGHџ^^^џuuuџ‚‚‚џ‰‰‰џsssџБББџЎЎЎџЕЕЕџМММџОООџСССџЧЧЧџЧЧЧџЦЦЦџЫЫЫџІІІџСССџгггџЪЪЪџЫЫЫџЮЮЮџгггџЯЯЯџЙЙЙџ“““џzzzџ‚‚‚џЋЋЋџІІІџfffJJJь000џuuuџЌЌЌџГГГџНННџСССџЬЬЬџдддџкккџоооџтттџхххџфффџхххџшшшџ‘‘‘џкккџюююџыыыџхххџтттџсссџнннџйййџдддџЯЯЯџЪЪЪџФФФџПППџЛЛЛџЖЖЖџБББџЋЋЋџІІІџ———џmmmџЖЖЖџџ}}}џtttџlllџfffџfffџhhhџlllџrrrџwwwџ|||џ|||џiiiџ:::џ###џ џџџџ+++џBBBџJJJџ<<<џ!!!џ џџ џџџ џiklџkmmџџџ џ"""џ$$$џ%%%џ(((џ+++џ---џ...џ,,,џ***џprrџ}џZZZџ\\\џџŒŒŒџ™™™џЂЂЂџЋЋЋџДДДџЛЛЛџНННџФФФџЩЩЩџІІІџРРРџеееџЬЬЬџЭЭЭџЯЯЯџаааџвввџдддџеееџЪЪЪџЉЉЉџ………џІІІџTTT mmmлUUUџ}}}џЕЕЕџВВВџКККџФФФџЬЬЬџеееџнннџрррџфффџчччџщщщџщщщџшшшџ‘‘‘џйййџшшшџхххџрррџоооџмммџйййџжжжџбббџЭЭЭџШШШџТТТџОООџКККџЕЕЕџАААџЊЊЊџЄЄЄџ–––џkkkџДДДџ€€€џzzzџqqqџjjjџhhhџgggџjjjџnnnџrrrџyyyџ}}}џ~~~џџџYYYџџ џџ џ џ џџ888џVVVџ^^^џMMMџ+++џџ џџhjkџkmmџџџ џ"""џ$$$џ%%%џ(((џ+++џ---џ///џ000џ***џwyzџwyyџ0//џAAAџUUUџfffџuuuџџŒŒŒџ•••џ   џЋЋЋџЏЏЏџНННџŸŸŸџЛЛЛџгггџЪЪЪџЮЮЮџаааџбббџбббџбббџбббџгггџзззџгггџІІІџ}}}ЩWWWџzzzџЗЗЗџВВВџЛЛЛџФФФџЬЬЬџеееџмммџтттџхххџчччџшшшџхххџшшшџ‘‘‘џаааџсссџкккџиииџжжжџвввџЮЮЮџЩЩЩџЧЧЧџТТТџОООџЙЙЙџЖЖЖџВВВџ­­­џЉЉЉџЅЅЅџЁЁЁџ“““џhhhџБББџ~~~џyyyџrrrџlllџjjjџjjjџnnnџsssџxxxџ}}}џџ‚‚‚џ€€€џ‚‚‚џhhhџџџџџџџџџџ"""џ@@@џ___џeeeџSSSџ'&&џmopџfhhџ џџ џ"""џ$$$џ%%%џ(((џ+++џ---џ///џ000џ+++џvxyџxzzџ211џ:::џ:::џ@@@џIIIџWWXџiiiџwwwџƒƒƒџ‹‹‹џ™™™џЇЇЇџџЎЎЎџЩЩЩџХХХџЪЪЪџЭЭЭџЯЯЯџбббџбббџвввџвввџвввџгггџІІІџМWWWџzzzџКККџГГГџНННџЦЦЦџЭЭЭџгггџиииџоооџсссџсссџрррџмммџйййџ‘‘‘џРРРџЯЯЯџЩЩЩџЦЦЦџТТТџНННџИИИџЗЗЗџГГГџЏЏЏџ­­­џЈЈЈџЅЅЅџЃЃЃџ   џœœœџ™™™џ–––џŠŠŠџaaaџЈЈЈџyyyџvvvџoooџkkkџkkkџmmmџrrrџwwwџ}}}џџ„„„џ………џ„„„џ………џfffџџџџџџџџџџџџџ---џUVVџrstџЄЅІџ‘’“џ999џ%%%џџџ"""џ%%%џ(((џ+++џ---џ///џ000џ+++џvxyџxzzџ211џ;;;џ>>>џAAAџBAAџBBBџFFFџOOOџ\\\џkkkџzzzџŠŠŠџvvvџ“““џВВВџДДДџНННџУУУџШШШџЫЫЫџЮЮЮџаааџбббџвввџвввџІІІџ………Ў[[[џ{{{џЛЛЛџАААџМММџФФФџЧЧЧџЬЬЬџЮЮЮџЯЯЯџаааџаааџЭЭЭџЩЩЩџФФФџ‘‘‘џЎЎЎџЕЕЕџЏЏЏџЌЌЌџІІІџЁЁЁџџœœœџ–––џ•••џ’’’џџŽŽŽџŒŒŒџŠŠŠџ‰‰‰џ‡‡‡џ………џ|||џWWWџ˜˜˜џpppџnnnџiiiџgggџhhhџlllџrrrџyyyџџƒƒƒџ†††џ‡‡‡џ†††џ†††џsssм>>>И,,,ё&&&џ џџ"""џ(((џ222џGHHџ\^^џruuџƒ††џ””џ”˜™џ„…џvxxџaabџhhhџwwwџkkkџHHHџ---џџ"""џ)))џ---џ///џ000џ+++џvxyџxzzџ211џ;;;џ>>>џAAAџCCCџEEEџGGGџGGGџHHHџMMMџVVVџddeџdeeџxyyџџ•••џЂЂЂџ­­­џЖЖЖџОООџФФФџЩЩЩџЬЬЬџЯЯЯџаааџІІІџ‰‰‰Ÿ]]]џzzzџИИИџЎЎЎџГГГџЗЗЗџЙЙЙџЙЙЙџКККџЙЙЙџЗЗЗџДДДџАААџЋЋЋџЇЇЇџ‘‘‘џџ•••џŒŒŒџŠŠŠџ„„„џ‚‚‚џџ{{{џvvvџuuuџsssџoooџoooџpppџoooџoooџnnnџnnnџgggџHHHџ€€€џbbbџ```џ___џ^^^џaaaџfffџlllџtttџ{{{џ€€€џ„„„џ‡‡‡џ‡‡‡џ………џ‚‚‚АQQQPPSeKLLŸgjjн}ўŒџ™џ’––џ†‰Šџxz{џaccџMMMџ9::џ111џ***џ&%%џ&&&џ222џMNNџoooџ{{{џqrrџQQQџ666џ'''џ)))џ...џ+++џvxyџxzzџ211џ;;;џ>>>џAAAџCCCџEEEџGGGџIIIџKKKџMMMџMMMџIHHџ‚џ†‰‰џcccџuuuџ€€€џŒŒŒџ———џЄЄЄџЏЏЏџИИИџРРРџЦЦЦџЪЪЪџІІІџŒŒŒ‘\\\џtttџЎЎЎџЂЂЂџЄЄЄџЃЃЃџЂЂЂџ   џџ™™™џ”””џ‘‘‘џŒŒŒџ‡‡‡џƒƒƒџpppџnnnџuuuџnnnџkkkџjjjџdddџdddџaaaџ^^^џ\\\џYYYџVVVџVVVџWWWџVVVџUUUџUUUџVVVџRRRџ777џgggџOOOџPPPџPPPџQQQџTTTџYYYџaaaџiiiџpppџwwwџ|||џџ„„„џƒƒƒџЋВВВ ЋЏГ@z}}’PPPс<<=џ333џ,++џ...џ111џ333џ444џ555џ666џ666џ555џ222џ///џ999џQRRџpppџџwwwџZZZџ===џ&&&џqsuџwyyџ100џ;;;џ>>>џAAAџCCCџEEEџGGGџIIIџKKKџMMMџOOOџKJJџƒ††џ„†‡џNNNџXXXџabbџkklџwwwџџџ™™™џЅЅЅџБББџКККџІІІџŒŒŒƒXXXџiiiџžžžџ‘‘‘џŽŽŽџ‰‰‰џ………џ€€€џ{{{џwwwџuuuџtttџuuuџvvvџuuuџoooџoooџtttџtttџtttџsssџrrrџoooџlllџiiiџeeeџaaaџ\\\џWWWџSSSџNNNџIIIџFFFџCCCџ???џ222џDDDџ===џ>>>џ@@@џAAAџFFFџKKKџPPPџXXXџ```џhhhџoooџvvvџ{{{џ~~~џ||| \\\ ```BTTTˆNOOгCCCњ@@@џ===џ???џ???џ???џ???џ???џ???џ???џ>>>џ;;;џ777џ>==џRRRџmmmџ~~~џqqqџ“”•џ}€џ0//џ444џ;;;џ@@@џCCCџEEEџGGGџIIIџKKKџMMMџOOOџKJJџ‚……џ„†‡џQPPџXXXџXXXџZZZџ]]]џeefџoooџzzzџƒƒƒџџœœœџІІІџ………zOOOџ[[[џ………џuuuџsssџkkkџiiiџlllџtttџ|||џ†††џџ”””џ–––џ•••џ”””џ’’’џџџџŠŠŠџ‡‡‡џƒƒƒџџzzzџvvvџqqqџlllџhhhџbbbџ\\\џWWWџRRRџLLLџGGGџCCCџ;;;џ888џ333џ111џ000џ222џ666џ???џEEEџNNNџUUUџ\\\џdddџmmmџrrrџvvv—mmmmmm1WYYxVXXТMNNѕJJJџGGFџGGGџEEEџDDDџCCCџGFGџKKKџNNOџWXXџcddџmooџ€‚‚џ“”џЉЌЌџŸ  џ~~~џjjjџOOOџ???џ<<<џBBBџFFFџIIIџKKKџMMMџOOOџKJJџ‚……џ„†‡џQPPџXXXџZZZџ[[[џ]]]џ\\\џ^^^џbbbџijjџqqqџ|}}џІІІџwwwuCCCџIIIџmmmџ]]]џ___џfffџvvvџˆˆˆџ•••џžžžџЃЃЃџІІІџІІІџЂЂЂџŸŸŸџšššџ———џ”””џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџGGGџBBBџ???џ<<<џ888џ444џ000џ...џ---џ///џ555џ???џIIIџRRRџZZZџaaaџkkkŒiii"giioabbА]^^юghhџrstџ€ƒƒџ‹Žџ”—˜џ ЁџЁЂџ—š›џ’“џ†‰‰џx{{џjkkџXYYџ```џxxxџ‹‹‹џ‡‡‡џrrrџWWWџFFGџBBBџHHHџLLLџOOOџKJJџ‚……џ„†‡џQPPџXXXџZZZџ[[[џ]]]џ^^^џ___џaaaџa``џbbbџeeeџbbbџeeel888џ888џXXXџ]]]џnnnџ~~~џŒŒŒџ–––џџЂЂЂџЅЅЅџІІІџІІІџЂЂЂџžžžџšššџ–––џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ???џ;;;џ999џ666џ444џ333џ333џ111џ///џ---џ000џ:::џFFFџOOOџbbb‡‡‡ЉББHЈ­Џ”——сƒ††џvwwџjjjџ`aaџ]]]џYYYџVVVџVVVџXWWџZZZџYYYџWWWџXXXџhhhџ|||џŽŽŽџ‹‹‹џzzzџ^^^џNNNџIIIџHGGџ„„џ„†‡џQPPџXXXџZZZџ[[[џ]]]џ^^^џ___џaaaџbbbџcccџdddџbbbџˆˆ???t@@@џHHHџ]]]џlllџyyyџƒƒƒџŽŽŽџ˜˜˜џžžžџЃЃЃџІІІџЇЇЇџЇЇЇџЃЃЃџŸŸŸџšššџ–––џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ111џ...џ111џ===џFFFssss pppOkmmŽkllлeeeќcccџcccџdddџdddџeeeџeeeџeeeџeeeџdddџcccџ```џaaaџnnnџџ‘‘‘џŽŽŽџ~~~џ_^^џ…ˆˆџ€‚ƒџMLLџWWWџZZZџ[[[џ]]]џ^^^џ___џaaaџbbbџcccџdddџbbbџˆˆ***m666ъGGGџVVVџaaaџmmmџyyyџ„„„џџ™™™џŸŸŸџЄЄЄџЈЈЈџЉЉЉџЈЈЈџЅЅЅџ   џ›››џ———џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ444џ333џ333џ333џ333џ333џ333џ444џ555џ:::џ===БDDDqq ;z||vwwЭoooјnnnџlllџmmmџmmmџmmmџlllџlllџkkkџjjjџiiiџjjjџkkkџ{||џ’””џ›џЏАБџŸЁЁџjjjџ\\\џTTTџWWWџ\\\џ^^^џ___џaaaџbbbџcccџdddџbbbџˆˆ (((œ555џ@@@џJJJџUUUџaaaџmmmџyyyџ………џџ™™™џ   џЅЅЅџЈЈЈџЉЉЉџЉЉЉџЅЅЅџ   џ›››џ–––џ“““џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ888џBBBџKKKџOOOЫOOO0™™™*€€€u~~Кxxxѓwwwџvvvџxxxџ}~~џ…††џŒŽџ“•–џ™œџžЂЃџЁЅІџœŸ џ“––џ‘“”џŽŽŽџ———џ—˜˜џŒŒŒџsssџbbbџYYYџ[[[џ```џbbbџcccџdddџbbbџˆˆ)))Ё222џ999џ@@@џIIIџUUUџaaaџmmmџyyyџ………џџ™™™џ   џЅЅЅџЇЇЇџЈЈЈџЇЇЇџЂЂЂќžžžјšššі™™™і”””ќџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ999џCCCџQQQџ\\\џZZZфRRR(ˆˆˆg™žž—ЃІІмЄЈЉџŸЂЃџ›žŸџ—™šџ’’џ‰ŠŠџƒƒƒџџ~~~џ{{{џ{{zџ{{{џџŒџšššџš››џџyyyџhhhџ^^^џ___џbbbџbbbџˆˆ'''h111џ444џ888џ@@@џIIIџTTTџ```џmmmџyyyџƒƒƒџџ–––§ŸŸŸўІІІ§ЊЊЊёАААяЖЖЖ§ЖЖЖіЕЕЕшЗЗЗрСССпЅЅЅѕџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ:::џEEEџSSSџ```џfffџ\\\ТUUUВВВ ”””V‰‰‹–ˆˆˆтƒƒƒџƒ‚‚џƒ‚‚џ„„„џ„„„џ………џ………џ………џ………џ„„„џƒƒƒџ‚‚‚џ†††џ‘‘џœџžžžџ”””џџlllџbbbџˆ---...у333џ444џ888џ@@@џIIIџSSSџ___џlllџzzzџŽŽŽ§ЂЂЂџБААљДДДћЛЛЛўОООћПППњСССўУУУџУУУџУУУџФФФџЂЂЂџŒŒŒџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ444џ;;;џHHHџVVVџaaaџhhhџfffџTTTW””” ”””H‘Šе‹ŒŒњŒŒŒџ‹‹‹џ‹‹‹џŒ‹‹џŒŒŒџŒŒŒџŒŒŒџŒŒŒџ‹‹‹џŠŠŠџ‰‰‰џ‹‹‹џ”””џžžžџЁЁЁџ–––џˆˆˆ)))V222џ333џ444џ888џ???џHHHџSSSџ___џjjjџƒƒƒџ‚…†ўinoџЇЉЉџПООџМЛЛџИИИџИИИџИИИџИИИџИИИџИИИџКККџžžžџџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ333џ;;;џ===џEEEџXXXџcccџgggџhhhџZZZБŸŸŸ›››3”””z•••Ц’’“і’’’џ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ’’’џ’’’џ‘‘‘ў№’’’у•——Н——™…‰‰‰ ---333џ333џ444џ888џ???џHHHџSSSџ___џjjjџ…„„џ‚……џ4;>џDKMџptuџ ЁЁџГВВџЏЏЏџ­­­џ­­­џ­­­џ­­­џЏЏЏџšššџŽŽŽџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ,,,џlllџ“““џiiiџ[[[џaaaџhhhџhhhџaaaчUUU ЊЊЊ———%™››q™™™В˜˜˜ю˜˜˜ь˜ššвššš ———~™œœjœ  A–––””” ///€333џ333џ333џ888џ???џHHHџRRRџ^^^џiiiџ………џˆ‹Œџ:ACџ?FHџ:BDџGNPџptuџš››џЄЃЃџЂЂЂџЂЂЂџЂЂЂџЃЃЃџ•••џџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ,,,џlllџАААџЅЅЅџ“““џwwwџgggџgggџaaaчbbb ™™™‘ЃЃ‘‘‘///€333џ333џ333џ888џ???џHHHџRRRџ^^^џiiiџˆ‡‡џ““џ9@BџAHJџAHJџ?FHџ7?Aџfjkџš™™џ–––џ–––џ–––џ–––џџџџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ---џeeeџžžžџ™™™џџŸŸŸџџlllџ^^^цbbb ///€333џ333џ333џ888џ???џGGGџQQQџ]]]џhhhџ‰ˆˆџ–™™џ8?AџAHJџAHJџAHJџ>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ///џ___џŒŒŒџ}}}џmmmџYYYџOOOџiiiџ^^^ы[[[///€333џ333џ333џ888џ???џGGGџQQQџ\\\џfffџ‰‰‰џ™œœџ8?AџAHJџAHJџAHJџ>EGџZ^_џџ}}}џ}}}џ}}}џ{{{џ„„„џ’’’џџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ333џ777џ000џџџ џџџ\\\џ```юUUU///€333џ333џ333џ888џ???џGGGџQQQџ\\\џfffџ‰‰‰џ™œœџ8?AџAHJџAHJџAHJџ>EGџTYZџrrrџpppџpppџpppџnnnџ~~~џ“““џџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ444џ999џ џџ џ џ џџdddџ\\\чNNN ///€333џ333џ333џ888џ???џGGGџPPPџ[[[џeeeџ‰ˆˆџ™œœџ8?AџAHJџAHJџAHJџ?GIџOSUџeddџcccџcccџcccџ```џyyyџ“““џџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ444џ999џ(((џџџџџ!!!џnnnџYYYхUUU ///€333џ333џ333џ888џ???џGGGџPPPџ[[[џfffџ‰‰‰џ™œœџ8?AџAHJџAHJџAHJџ@GIџJOPџYXXџWWWџWWWџWWWџTTTџtttџ”””џŽŽŽџŠŠŠџ†††џ‚‚‚џ~~~џyyyџuuuџpppџkkkџgggџbbbџ\\\џXXXџSSSџOOOџJJJџFFFџBBBџ>>>џ;;;џ888џ666џ333џ333џ333џ333џ333џ444џ:::џ...џ џ"""џ"""џџ000џџTTTхUUU ///€333џ333џ444џ888џ???џGGGџQQQџ]]]џhhhџ‹‹‹џ™œџ8?AџAHJџAHJџAHJџ@HJџFJKџMMMџMMMџMMMџMMMџHHHџkkkџ‘‘‘џˆˆˆџƒƒƒџџ~~~џzzzџuuuџqqqџlllџgggџbbbџZZZџRRRџOOOџJJJџGGGџDDDџBBBџ???џ<<<џ:::џ888џ666џ333џ333џ333џ333џ333џ444џ;;;џ444џ+++џ,,,џ,,,џ)))џ>>>џџPPPхUUU ///€333џ333џ444џ888џ@@@џHHHџTTTџaaaџmmmџ‘џ›žžџ8?AџAHJџAHJџAHJџAHJџCGHџBBBџAAAџBBBџBBBџDDDџŒŒŒџНННџОООџСССџФФФџХХХџПППџЙЙЙџЕЕЕџАААџЎЎЎџЏЏЏџЉЉЉџЇЇЇџœœœџ”””џ†††џsssџ\\\џLLLџAAAџ555џ,,,џ...џ///џ111џ222џ333џ333џ555џ;;;џ<<<џ777џ888џ888џ555џMMMџ———џKKKхUUU ///€333џ333џ333џ888џ@@@џIIIџWWWџgggџsssџ—––џšџ7>@џAHJџAHJџAHJџCJMџ045ў222ўџџ+++џ999џџЬЬЬџЫЫЫџЦЦЦџТТТџСССџМММџЗЗЗџЗЗЗџЕЕЕџЗЗЗџЛЛЛџОООџЦЦЦџУУУџШШШџЮЮЮџгггџжжжџЯЯЯџСССџ­­­џŽŽŽџmmmџIIIџ777џ///џ+++џ///џ555џ<<<џCCCџDDDџDDDџDDDџAAAџYYYџœœœџGGGх??? ///€333џ333џ333џ888џ@@@џJJJџVVVџdddџ{{{џЋЋЋџЏВВџ7>Aџ;BDџAHJџAHJџELNџ!%&џ444§ўџ###џ444џEEEџlllџ™™™џЇЇЇџЄЄЄџЂЂЂџЂЂЂџЂЂЂџЁЁЁџ   џŸŸŸџžžžџџ›››џšššџ˜˜˜џ———џšššџœœœџŸŸŸџЃЃЃџАААџМММўПППџПППџЌЌЌџ‘‘‘џoooџKKKџ777џ555џHHHџQQQџPPPџPPPџMMMџeeeџœœœџDDDф??? ///€333џ333џ333џ777џ999џDDDџlllџЅЅЅўаааўлллўжжжџЎАБџZ`bџ7>@џ>EGџDLNџ&*+џ?>>ўџџ$$$џ666џFFFџRRRџdddџ………џŸŸŸџЅЅЅџЂЂЂџЁЁЁџ   џŸŸŸџžžžџџœœœџšššџ˜˜˜џ˜˜˜џ–––џ•••џ”””џ’’’џ‘‘‘џŽŽŽџ‹‹‹џ‹‹‹џџ“““џџЇЇЇџЈЈЈџ   џ………џZZZџ[[[џ[[[џ[[[џXXXџpppџ›››џ>>>ф??? ///€333џ333џ///џ111џbbbџЎЎЎ§зззћввв§ЛЛЛўЋЋЋџІІІџРРРџЯааџ‘•–џFLNџ;CEџ)-.џLLLўџџ$$$џ666џGGGџVVVџ```џcccџnnnџ‰‰‰џ›››џ™™™џ———џ˜˜˜џ–––џ’’’џ———џ™™™џ›››џ™™™џ‘‘‘џџџџџ‹‹‹џŠŠŠџˆˆˆџ‡‡‡џ………џ„„„џџ‚‚‚џ‹‹‹џ‹‹‹џgggџgggџgggџgggџdddџ|||џšššџ;;;ф??? ///€333џ+++џDDDџ›››ќдддќУУУ§ЋЋЋўЅЅЅџІІІџЇЇЇџЇЇЇџЄЄЄџЈЈЈџЧЧЧџПССџqxyџ/34џZYYўџџ$$$џ666џGGGџVVVџaaaџfffџbbbџ\\\џ```џSSSџEEEџAAAџAAAџIIIџ;;;џGGGџPPPџ```іМŠŠŠнˆˆˆѕ‡‡‡џ†††џ………џƒƒƒџƒƒƒџ„„„џ………џ{{{џzzzџxxxџrrrџoooџrrrџrrrџrrrџrrrџpppџ†††џšššџ999ф??? ///€,,,џ]]]іДДДєСССќЉЉЉџЄЄЄџІІІџІІІџЅЅЅџЅЅЅџЄЄЄџЃЃЃџЁЁЁџџБББџЧЧЧџVWWџcccўџџ$$$џ666џGGGџVVVџaaaџfffџdddџ\\\џPPPџBBBџ333џ$$$џ'''џEEEџџџџшjjj ™™™ ‡‡‡"‚‚‚Z€€€‘~~~дџџqqqџMMMџMMMџ}}}џ|||џ|||џ}}}џ}}}џ|||џ|||џ{{{џxxxџџ•••џ222у??? '''```њЖЖЖю­­­§ЃЃЃџЄЄЄџЄЄЄџЃЃЃџЂЂЂџЁЁЁџЁЁЁџ   џžžžџ   џŸŸŸџƒƒƒџ\\\џ888џtttџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ(((џ,,,џUUUџ***џ...џ///џ+++щ... mmmuuuL<<<єџ џMMMџџ………џƒƒƒџ‚‚‚џџ„„„џŠŠŠџџ›››џИИИџОООќFFFс*** LLLuЅЅЅљЇЇЇџЂЂЂџЂЂЂџЁЁЁџ   џŸŸŸџžžžџџœœœџ›››џ›››џ–––џhhhџDDDџ@@@џ???џ‚‚‚џџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ'''џ...џiiiџ999џ>>>џ>>>џ>>>щ::: UUUчџџKKKџ™™™џ™™™џІІІџЕЕЕџОООџЪЪЪџЬЬЬџЩЩЩџЛЛЛџЊЊЊџЂЂЂќ‰‰‰йbbb ЅЅЅjЂЂЂџžžžџžžžџžžžџџœœœџšššџšššџ™™™џ˜˜˜џ™™™џ˜˜˜џlllџMMMџRRRџSSSџMMMџŽŽŽџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ'''џ111џџIIIџNNNџNNNџMMMщNNN  щџџ```џЇЇЇџЄЄЄџЁЁЁџœœœџџ{{{џjjjџbbbџYYYџRRRџMMMџ€€€лВВВ ŸŸŸ~œœœџšššџšššџ™™™џ———џ–––џ•••џ”””џ‘‘‘џ‰‰‰џџuuuџ___џ^^^џ___џ___џYYYџ™™™џџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ&&&џ444џ“““џXXXџ^^^џ^^^џ^^^щbbb  щџџkkkџdddџ\\\џWWWџTTTџTTTџVVVџVVVџVVVџVVVџVVVџTTTџVVVчUUU •••P–––џ•••џ”””џ’’’ї’’’нЋuyyyДnnnџkkkџhhhџhhhџkkkџkkkџkkkџkkkџeeeџЁЁЁџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ&&&џ555џЂЂЂџhhhџnnnџnnnџnnnщuuu  щџQQQџpppџWWWџYYYџXXXџWWWџVVVџUUUџTTTџSSSџRRRџQQQџQQQџMMMЛUUU™™™‘‘‘ŒŽŽŽŽ[ŒŒŒ(™™™ sss‡uuuџvvvџvvvџvvvџvvvџvvvџvvvџuuuџoooџІІІџџџ$$$џ666џGGGџVVVџaaaџfffџdddџ]]]џRRRџEEEџ666џ&&&џ555џЌЌЌџzzzџ~~~џ~~~џ}}}щuuu ‘‘‘===ьcccџsssџWWWџUUUџTTTџSSSџSSSџRRRџPPPџPPPџOOOџNNNџMMMџKKKѕMMM;€€€џџ€€€џ€€€џџ|||џ{{{џџ†††џЛЛЛџ)))џ џџ,,,џAAAџSSSџ___џdddџcccџ\\\џQQQџDDDџ555џ$$$џ222џЕЕЕџ‹‹‹џŽŽŽџŽŽŽџŽŽŽщ‰‰‰ ДДДwwwыeeeџPPPџQQQџQQQџPPPџOOOџNNNџMMMџLLLџLLLџKKKџKKKџIIIчKKKN‰‰‰ˆˆˆџ‡‡‡џŠŠŠџџšššџ­­­џНННџЬЬЬџЭЭЭџЦЦЦџЕЕЕџЁЁЁџŠŠŠџ€€€џsssџjjjџmmmџmmmџfffџ]]]џRRRџCCCџ222џ%%%џ...џКККџ›››џžžžџžžžџщœœœ UUUKKK3NNNЗNNNџMMMџMMMџLLLџLLLџJJJџJJJџIIIџHHHџIIIўGGGЋJJJ)›››•ЅЅЅџЋЋЋџЏЏЏџВВВўБББџЉЉЉџšššџџpppџgggџoooџ„„„џџЉЉЉџДДДџСССџХХХџХХХџФФФџМММџМММџДДДџЉЉЉџЏЏЏџЋЋЋџаааџЉЉЉџЊЊЊџЋЋЋџЊЊЊщААА KKK^IIIнJJJџIIIџHHHџHHHџHHHџHHHѓHHHЉGGG@b‘‘‘пŠŠŠљyyyџoooџgggџbbbџbbbџcccџcccџcccџaaaџ^^^џZZZџVVVџYYYџ^^^џaaaџeeeџiiiџjjjџtttџxxxџxxxџuuuџ|||џАААќаааћРРРџЗЗЗџЖЖЖщААА DDDGGG•GGGјGGGѕGGGМGGGrFFF$jjj eee:eeeqcccЇbbbоaaaјaaaџ```џ___џ^^^џ]]]џ\\\џ[[[џZZZџYYYџWWWџUUUџTTTџRRRџQQQџOOOџMMMџLLLџLLLџIIIџIIIўsssљБББяЭЭЭіЧЧЧьФФФ JJJ0HHH#fff \\\,^^^Q[[[uYYY™WWWНXXXпVVVёUUUїTTT§SSSџSSSџRRRџQQQџPPPџPPPџOOOџMMMџMMMџLLLџLLLџJJJџCCCџIIIџzzzљЙЙЙЬюююLLL PPPRRR(PPPDB=94-**2CQK5    #/AZ///qGGG–:::žCCCВ>>>ГQQQУNNNУHHHФIIIЛAAAП;;;Ф888У000О"""В­œ›™ ДKпHв.“?9LEТFф1 šR# N4 3 †0 I" &? \,,,ŠTTTЛvvvеˆˆˆцŽŽŽџџ†††џ~~~џyyyџwwwџsssџmmmџgggџ```џYYYџRRRџKKKџCCCџ;;;џ,,,џџ5ќ [(џm3џt4џo.џ Wё Nн]+џ]/џc3џ^,џPј TџZ џYџ SџKјy-  #Jƒ666ИUUUыlllџџџœœœџЁЁЁџŸŸŸџ™™™џџŠŠŠџ†††џ€€€џyyyџrrrџkkkџcccџ\\\џTTTџMMMџCCCџ111џ=#џr5џi2џo1џ~9џj*џ]-џr>џ!yCџ'{Bџ#q;џ]/џV'џh+џn-џm+џh(џ`"џKэ _# - t(((У===џOOOџcccџzzzџŒŒŒџџЇЇЇџЊЊЊџЈЈЈџЁЁЁџ———џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџGGGџ888џL(џ*“Hџ$‹Eџƒ;џ„9џg0џsDџ,ŠRџ)‹Oџ.‰Jџ'{?џf1џg.џ }8џ!{3џg%џk)џt.џi'џ?ЦD|***ђ666џFFFџXXXџkkkџ€€€џ‘‘‘џ   џЉЉЉџЋЋЋџЉЉЉџЂЂЂџ———џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ<<<џ(5+џ‚7џ‹<џŒ=џ*™Eџx3џ$‚Jџ8—[џ8™Yџ:Wџ/‘Lџ =џ~:џ#ˆ>џ €5џj&џg$џ~4џx0џb"џh 5)))ь000џ<<<џJJJџZZZџlllџ€€€џџŸŸŸџЉЉЉџЋЋЋџЉЉЉџЃЃЃџ˜˜˜џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ>>>џ---џY)џ,ЌOџ/­Rџ*ЁHџ‰:џ‚?џ2’OџBЃZџE­_џ1™Nџ"‰?џ"Š>џ"Š>џ3џz/џl&џz2џz2џ [ їm$C...џ444џ>>>џKKKџZZZџkkkџџџŸŸŸџЈЈЈџЋЋЋџЉЉЉџЃЃЃџ™™™џџŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ>>>џ.0/џS&џ*ЇHџ5ВTџ4ЌRџŠ6џ#”EџŽBџ(ŸMџ!™Hџ‘Bџ‘Aџ#™Gџ+ Jџ%:џu)џy.џz2џ~7џ Rќ- О: ///ќ555џ>>>џJJJџYYYџjjjџ~~~џџžžžџЈЈЈџЋЋЋџЊЊЊџЄЄЄџ™™™џ‘‘‘џŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџ@@@џ454џX*џ/­Kџ4ДTџ+Gџ Œ;џ%ЄKџ1ВXџ*ЈOџŸHџ$ЄMџ*ЇPџ0ЌRџ4АTџƒ1џŠ7џ!<џy2џw1џZ#џe(џ YЭ$...Я555џ>>>џJJJџYYYџjjjџ}}}џŽŽŽџžžžџЈЈЈџЋЋЋџЊЊЊџЅЅЅџšššџ‘‘‘џŠŠŠџ„„„џ}}}џvvvџnnnџfffџ___џWWWџPPPџIIIџBBBџ999џ*=.џ’:џ$ЁEџŒ<џ€5џ žBџ$ЉJџ ЈDџЁ>џ™7џ%ЃAџ>ИVџ<ЎSџq&џ‚6џ!@џ ŒAџp,џ^)џt0џ}3џ aa...™444џ>>>џJJJџYYYџiiiџ|||џŽŽŽџџЇЇЇџЊЊЊџЅЅЅџžžžџџšššџ”””џ———џ   џ™™™џ“““џџxxxџhhhџaaaџSSSџ???џ:::џ666џ"_1џ#N.џa-џx1џ9џ+ИPџ)ЖIџ Ћ?џЄ;џЃ>џ&ЇGџ)ЇKџˆ:џi'џ(Aџx4џh*џ"m3џ#‚:џx1џXB+++c333џ>>>џJJJџYYYџiiiџzzzџ‰‰‰џšššџЅЅЅџЃЃЃџџ———џˆˆˆџƒƒƒџ€€€џvvvџrrrџdddџbbbџcccџdddџnnnџiiiџfffџnnnџgggџ___џWWWџCCCџ555џ,Q5џЋ?џ+РOџ%ЗGџ#ЖGџ&ЗKџ"­Fџ!ЃCџ+ІKџ&’@џt0џ*„Dџq8џe(џ#r6џ'†Aџm-ь0----333џ>>>џIIIџ\\\џzzzџ‚‚‚џzzzџhhhџ]]]џcccџzzzџœœœџЎЎЎџЏЏЏџЈЈЈџЦЦЦџгггџЗЗЗџАААџЇЇЇџЅЅЅџџŠŠŠџxxxџlllџ```џџ@@@џ>>>џHHHџMPMџЅ=џ(СKџ(РLџ-СQџ/ТTџ,ЛRџ*БNџ,­Qџ'ЃMџ‹Bџ!x<џp0џm/џ(@џ)‹Fџ'k<њFFFМQ.111і@@@џeeeџlllџ___џ]]]џžžžџИИИџЭЭЭџиииџрррџцццџцццџхххџоооџЪЪЪџнннџШШШџОООџДДДџЎЎЎџЉЉЉџІІІџ›››џ———џ‰‰‰џ–––џŠŠŠџtttџ___џHHHџ+P3џ#“<џ"НGџ*СMџ)ПOџ)КPџ*ЕQџ*АQџ$ІJџ@џs+џ%z9џ,ˆCџ,Hџ‚>џ>qMџtttџgggёPPPОV0444Цcccџ^^^џWWWџŠŠŠџІІІџ˜˜˜џЮЮЮџиииџуууџыыыџ№№№џюююџьььџчччџЭЭЭџфффџаааџЦЦЦџОООџИИИџГГГџЋЋЋџ­­­џЅЅЅџџ———џšššџ–––џџџhhhџBNEџ<%џ(ƒ<џ&‹>џ%ИKџ$ЏIџ"ЉGџ€7џCfKџ>qKџ"ƒ:џD‚Tџ5Iџ>zOџ{|џџ|||џџuuuѓPPPК]1  QQQЖ```џbbbџ„„„џ™™™џАААџ™™™џбббџрррџъъъџяяяџђђђџюююџшшшџпппџСССџлллџаааџЪЪЪџЦЦЦџТТТџРРРџВВВџЎЎЎџЋЋЋџ™™™џџЁЁЁџœœœџ˜˜˜џ‘‘‘џ‹‹‹џ‡‡‡џbbbџ џ.l<џБAџ=џ7GџhhhџSSSџcccџuyvџ›››џ‹‹‹џ‡‡‡џ‡‡‡џ†††џƒƒƒџ•••џŠŠŠџŠŠŠџ………і[[[Рe93DV dZ9*)'JJJŒVVVџrrrџ†††џ›››џБББџ™™™џгггџтттџьььџяяяџчччџЯЯЯџЗЗЗџЈЈЈџџЕЕЕџШШШџЭЭЭџЩЩЩџЦЦЦџФФФџНННџЗЗЗџАААџœœœџžžžџЃЃЃџџџџ›››џ———џ‰‰‰џ!!!џ???џ]eџkznџ{{{џ}}}џjjjџ‡‡‡џyyyџjjjџ{{{џžžžџŒŒŒџˆˆˆџˆˆˆџ˜˜˜џ’’’џџџŽŽŽџŠŠŠї[[[Я“ ’AУh-ёq1§ Yс( ‘ m) †h@??? GGGяrrrџŒŒŒџЁЁЁџДДДџ™™™џзззџфффџэээџъъъџЫЫЫџџiiiџdeeџjkkџ—˜˜џЙЙЙџЮЮЮџкккџкккџгггџЯЯЯџШШШџЗЗЗџœœœџŸŸŸџЁЁЁџ   џ™™™џ›››џœœœџ–––џŠŠŠџ(((џAAAџˆˆˆџ•••џ‡‡‡џ………џlllџ………џ~~~џ{{{џyyyџqqqџ‚‚‚џЂЂЂџ’’’џšššџ‹‹‹џ‘‘‘џ’’’џ’’’џ“““џ|||џ]`^§Y*ј|<џ'‰Eџ-–Jџ*’Bџt+ў \$эz6џw3§h%єK˜ KKKtttџ“““џ­­­џОООџ›››џхххџлллџжжжџЪЪЪџ™™™џ•˜˜џБЗЖџЃЇЇџ…„џПХФџmmmџЂЂЂџ’’’џ~~~џ€€€џkkkџxxxџyyyџƒƒƒџ„„„џЌЌЌџБББџŸŸŸџ˜˜˜џšššџ’’’џ†††џ:::џ^^^џGGGџXXXџ„„„џЁЁЁџmmmџŠŠŠџ†††џ„„„џ………џ‰‰‰џ………џ}}}џˆˆˆџ   џЄЄЄџ“““џџ’’’џ’’’џ€€€џOgVџ†@џ-Kџ/™MџAЎXџ3œIџ3џp,џ,“Iџ3ЂOџ-—Cџ|.џY}}}ўœœœџТТТџЇЇЇџjjjџ†††џ­­­џВВВџзззџЉЉЉџТШЧџ.//џџ џЗМЛџ,,,џйййџбббџЅЅЅџЫЫЫџПППџНННџЏЏЏџ–––џ„„„џoooџVVVџ```џ‹‹‹џЄЄЄџџ€€€џ888џcccџZZZџ‰‰‰џqqqџ```џ___џЈЈЈџ”””џ‘‘‘џ“““џ“““џ’’’џ•••џ”””џŽŽŽџ–––џ­­­џАААџœœœџ˜˜˜џŠŠŠџptqџ4џ%‘Bџ)—Eџ6ЉRџ5ЈNџ&‘>џu-џ6ЅRџKКaџ3џ$Œ<џ{1џL јxxxџlllџžžžџЩЩЩџиииџпппџТТТџхххџЋЋЋџТШЧџ333џ###џџЗМЛџ---џкккџдддџЇЇЇџЪЪЪџПППџИИИџДДДџБББџЊЊЊџЄЄЄџŸŸŸџ“““џZZZџ\\\џkkkџ‡‡‡џ666џeeeџ[[[џŒŒŒџŒŒŒџŽŽŽџ‡‡‡џoooџџБББџЌЌЌџžžžџ›››џœœœџžžžџŸŸŸџ   џџŸŸŸџЎЎЎџЗЗЗџŸŸŸџŠŠŠџ)t<џ$š@џ3ЌMџ6ЎPџ1ЄLџ'Aџx0џ+Gџ;ВXџ1ЃKџ#Œ>џk(оeeeћџМММџХХХџЭЭЭџвввџмммџТТТџцццџЌЌЌџТШЧџCCCџ333џ###џЗМЛџ...џиииџаааџЅЅЅџШШШџРРРџЙЙЙџДДДџЏЏЏџ­­­џІІІџžžžџ———џkkkџžžžџyyyџSSSџ;;;џjjjџ[[[џџџ’’’џ”””џ™™™џ™™™џ~~~џџАААџИИИџŸŸŸџЁЁЁџЉЉЉџІІІџЈЈЈџЈЈЈџЅЅЅџ   џБББџŸŸŸџp{rџ'š@џ;ЗTџ8ЏQџ2ЁMџ(Dџ†5џ9ДSџ4ЋPџ,–Fџ&ŽAџ b ‡ˆˆˆчЈЈЈџЛЛЛџХХХџЩЩЩџЮЮЮџмммџТТТџщщщџЕЕЕџТШЧџQQQџCCCџ444џЛСРџ///џбббџЮЮЮџІІІџТТТџНННџИИИџДДДџЏЏЏџЌЌЌџІІІџŸŸŸџ›››џlllџЁЁЁџ”””џxxxџ&&&џkkkџjjjџ’’’џ“““џ———џ™™™џžžžџџџЅЅЅџџŒŒŒџ•••џЧЧЧџЏЏЏџЅЅЅџЊЊЊџЌЌЌџ­­­џЂЂЂџЪЪЪџ   џŠ‹џ,ŽBџ9ЏSџ<ЎVџ5ЂSџ#‰Aџ Ž;џ=ЗVџ3ЅOџ4 Pџ#ŠAџb![œœœйЎЎЎџПППџЦЦЦџЩЩЩџбббџпппџУУУџяяяџЮЮЮџЙПОџ_``џQQQџbddџЇЌЋџ000џТТТџФФФџЈЈЈџСССџЛЛЛџЗЗЗџЕЕЕџЉЉЉџЈЈЈџЇЇЇџЁЁЁџžžžџlllџŸŸŸџ’’’џ|||ў000џYYYџUUUџxxxџЇЇЇџ   џЂЂЂџЃЃЃџЅЅЅџ–––џІІІџЃЃЃџІІІџЂЂЂџ———џЉЉЉџЫЫЫџВВВџ­­­џЏЏЏџЃЃЃџеееџАААџЉЉЉџ‘‘‘џ/Eџ.žJџ"Š?џu+џ)ЁEџ;ЏUџ1ŸLџ)“Gџw3џf#9ЊЊЊШЕЕЕџРРРџЪЪЪџЯЯЯџеееџсссџФФФџяяяџрррџЋЎЎџ­ВБџЅЊЉџ—››џ"##џDDDџЗЗЗџВВВџ˜˜˜џЏЏЏџГГГџЇЇЇџВВВџЛЛЛџЙЙЙџЈЈЈџІІІџžžžџmmmџžžžџџzzzў666џ{{{џџ‰‰‰џgggџpppџЃЃЃџБББџЉЉЉџœœœџЇЇЇџЇЇЇџДДДџАААџЃЃЃџЁЁЁџ   џІІІџШШШџТТТџЃЃЃџкккџБББџЏЏЏџЎЎЎџžЇ џ\ˆgџ;bDџˆ7џ’7џ#–=џ$’>џƒ5џv/юЇЇЇЛГГГџРРРџЪЪЪџИИИџЋЋЋџІІІџЋЋЋџЧЧЧџйййџЪЪЪџ(((џџ џJJJџИИИџЛЛЛџЎЎЎџІІІџЊЊЊџЏЏЏџ‘‘‘џ’’’џџwwwџ~~~џŒŒŒџ”””џiiiџ™™™џˆˆˆџpppў;;;џ„„„џ———џ˜˜˜џšššџ˜˜˜џyyyџsssџ   џЌЌЌџЃЃЃџ­­­џЋЋЋџЈЈЈџЈЈЈџЈЈЈџЊЊЊџЙЙЙџЈЈЈџЈЈЈџЈЈЈџрррџДДДџВВВџВВВџВВВџЅЅЅџsssџ'†=џ7ВQџ;ВTџ3ЂMџ,–Iџt-ПЈЈЈБЋЋЋџyyyџiiiџœœœџНННџйййџыыыџ№№№џёёёџиииџпппџДДДџЭЭЭџеееџЪЪЪџФФФџМММџЛЛЛџДДДџЕЕЕџ›››џЙЙЙџ­­­џІІІџšššџƒƒƒџpppџJJJџbbbџ………џkkkў???џ………џ˜˜˜џ›››џšššџ‘‘‘џ€€€џtttџlllџuuuџџТТТџЕЕЕџЋЋЋџДДДџВВВџГГГџЛЛЛџБББџЎЎЎџ­­­џЋЋЋџИИИџЯЯЯџНННџДДДџЏЏЏџ‡‰ˆџA†Qџ1ЈLџ>БXџ7ЂSџ'Eџ i&Ѕиeeeџ‰‰‰џУУУџЯЯЯџйййџрррџчччџюююџђђђџлллџуууџкккџдддџдддџаааџЬЬЬџУУУџРРРџЛЛЛџГГГџ”””џЙЙЙџЉЉЉџЇЇЇџŸŸŸџ”””џˆˆˆџ~~~џlllџOOOџ\\\ў&&&џ€€€џЈЈЈџџšššџ‡‡‡џMMMџДЙЙџ—ššџ‡‰ˆџ†††џ‚‚‚џџЕЕЕџРРРџЉЉЉџЌЌЌџЙЙЙџАААџДДДџЙЙЙџЖЖЖџДДДџ   џБББџХХХџЦЦЦџ™™™џЂЂЂџO_џ*œFџ&Cїv,Ш g%/ŠŠŠПЂЂЂџ‘‘‘џТТТџЬЬЬџеееџтттџчччџэээџюююџнннџьььџхххџнннџжжжџЭЭЭџЩЩЩџНННџЕЕЕџМММџЕЕЕџ———џЖЖЖџІІІџЅЅЅџ   џ‘‘‘џƒƒƒџxxxџrrrџhhhџPPPў```џeeeџXXXџwwwџ­­­џџџЗМЛџ-..џmooџБЖЕџЂЅЄџšššџšššџŽŽŽџЈЈЈџЛЛЛџЏЏЏџЕЕЕџГГГџЕЕЕџИИИџЖЖЖџІІІџеееџІІІџœœœџ”””џРРРџЎАЎџ~Ёˆљ{+•••ЎЁЁЁџ———џСССџЫЫЫџбббџоооџцццџыыыџэээџмммџяяяџхххџнннџмммџЭЭЭџФФФџОООџИИИџТТТџЖЖЖџšššџБББџЇЇЇџЅЅЅџЂЂЂџџ„„„џ|||џvvvџhhhџSSSўgggџ“““џЅЅЅџ–––џkkkџ^^^џџЗМЛџ(((џџ џТШЧџЈЈЈџЋЋЋџЃЃЃџ•••џ•••џŸŸŸџРРРџСССџГГГџЖЖЖџЙЙЙџЇЇЇџйййџЗЗЗџГГГџЉЉЉџџ˜˜˜џВВВљ‰‰‰ЉšššџŽŽŽџСССџЩЩЩџбббџеееџхххџ№№№џюююџйййџхххџмммџбббџЮЮЮџЛЛЛџЖЖЖџДДДџБББџЗЗЗџШШШџ’’’џМММџБББџЋЋЋџŸŸŸџ‘‘‘џŠŠŠџƒƒƒџ}}}џkkkџRRRўlllџ˜˜˜џЊЊЊџ­­­џЎЎЎџ–––џ џЗММџ888џ+++џџТШЧџЋЋЋџДДДџБББџЂЂЂџ­­­џЎЎЎџЂЂЂџЅЅЅџМММџбббџРРРџЈЈЈџйййџКККџЕЕЕџ­­­џБББџЋЋЋџšššј|||Є•••џ“““џМММџСССџАААџЖЖЖџИИИџНННџбббџйййџвввџЫЫЫџМММџФФФџОООџАААџЎЎЎџІІІџ•••џŽŽŽџŒŒŒџyyyџ{{{џ†††џ“““џ–––џšššџŽŽŽџ€€€џmmmџTTT§lllџ™™™џЋЋЋџЎЎЎџЎЎЎџœœœџџЗНМџGGGџ;;;џ...џТШЧџУУУџЛЛЛџГГГџЈЈЈџМММџЕЕЕџГГГџЏЏЏџЎЎЎџІІІџЙЙЙџЎЎЎџдддџЛЛЛџЗЗЗџЗЗЗџЏЏЏџБББџИИИѕooo™џuuuџqqqџyyyџЎЎЎџФФФџнннџчччџыыыџшшшџиииџгггџИИИџвввџЮЮЮџШШШџРРРџИИИџИИИџЗЗЗџВВВџЈЈЈџ•••џџ………џxxxџjjjџUUUџoooџyyyџGGGўgggџЉЉЉџАААџБББџВВВџЅЅЅџџДКЙџZZZџJJJџ???џТШЧџџЇЇЇџЪЪЪџЎЎЎџРРРџЛЛЛџКККџГГГџšššџ”””џ›››џЂЂЂџІІІџПППџЭЭЭџКККџЗЗЗџИИИџИИИѓuuuВ^^^џ………џЖЖЖџœœœџбббџлллџпппџрррџзззџЦЦЦџБББџŸŸŸџŽŽŽџВВВџТТТџФФФџСССџКККџЖЖЖџЙЙЙџБББџЌЌЌџџœœœџ–––џ‹‹‹џ‹‹‹џџbbbџBBBџ^^^§TTTџQQQџyyyџЏЏЏџЛЛЛџВВВџ&&&џNPPџšžžџZ[[џUVVџОУТџВВВџЁЁЁџЅЅЅџšššџМММџгггџУУУџЈЈЈџ^^^џЖЛЛџŸЃЂџ–˜˜џ   џЉЉЉџžžžџЄЄЄџТТТџРРРџЛЛЛђaaaџ   џЖЖЖџ———џдддџнннџоооџзззџИИИџ†††џcccџ___џhiiџ‘’’џВВВџМММџЗЗЗџКККџЗЗЗџДДДџВВВџЏЏЏџ™™™џœœœџ”””џ‰‰‰џ„„„џ~~~џ{{{џpppџWWWќ{{{џЄЄЄџnnnџsssџhhhџ———џmmmџџ788џ™žџЛСРџЈЋЋџЗЗЗџЈЈЈџЗЗЗџЕЕЕџАААџІІІџВВВџБББџџЗМЛџ-..џnqpџДЙИџЎААџЗЗЗџЗЗЗџƒƒƒџ———џЎЎЎјbbbt€€€џ˜˜˜џАААџ———џЮЮЮџиииџмммџЮЮЮџŸŸŸџ”˜—џВЗЖџЃЇЇџ…„џПХФџxxxџНННџБББџЏЏЏџОООџЗЗЗџЕЕЕџИИИџœœœџ–––џŽŽŽџƒƒƒџ€€€џ€€€џ{{{џwwwџ___ћџЋЋЋџrrrџКККџЕЕЕџšššџxxxџ{{{џYYYџџ$$$џВВВџДДДџЇЇЇџИИИџГГГџУУУџОООџИИИџ———џџЗМЛџ(((џџ џТШЧџВВВџЙЙЙџŒŒŒџЯЯЯџЏЏЏі___cџ———џЊЊЊџ‘‘‘џЙЙЙџКККџИИИџВВВџ………џТШЧџ.//џџ џЗМЛџ&&&џЙЙЙџЂЂЂџ———џ›››џ“““џ„„„џzzzџhhhџqqqџŒŒŒџŒŒŒџџџ~~~џyyyџaaaћ€€€џ­­­џtttџНННџЕЕЕџЕЕЕџИИИџЛЛЛџšššџ|||џЅЅЅџЬЬЬџХХХџЇЇЇџРРРџДДДџГГГџФФФџРРРџЁЁЁџџЗММџ888џ+++џџТШЧџЕЕЕџИИИџџбббџРРРѓ^^^Q‡‡‡џŽŽŽџwwwџ‚‚‚џ   џЛЛЛџИИИџдддџ™™™џТШЧџ333џ###џџЗМЛџ)))џГГГџЌЌЌџЉЉЉџЌЌЌџЈЈЈџžžžџџ–––џџsssџlllџYYYџXXXџwwwџ€€€џVVVћxxxџЄЄЄџrrrџМММџЛЛЛџКККџЛЛЛџСССџФФФџŠŠŠџвввџšššџ”””џџдддџТТТџПППџРРРџТТТџЇЇЇџџЗНМџGGGџ;;;џ...џТШЧџŸŸŸџХХХџ“““џгггџТТТђoooPUUUџiiiџ™™™џЗЗЗџОООџЩЩЩџЛЛЛџкккџЁЁЁџТШЧџCCCџ333џ###џЗМЛџ(((џОООџЕЕЕџЃЃЃџЎЎЎџІІІџ   џџ“““џŠŠŠџ|||џqqqџrrrџ]]]џXXXџEEEџ===ўHHHџ{{{џ]]]џЇЇЇџДДДџМММџТТТџЧЧЧџЧЧЧџ‹‹‹џрррџТТТџФФФџЕЕЕџЁЁЁџЈЈЈџЫЫЫџжжжџСССџБББџџДКЙџZZZџJJJџ???џТШЧџВВВџџ‚‚‚џБББџЪЪЪѕWWW kkkџџЉЉЉџЏЏЏџКККџЮЮЮџМММџоооџАААџТШЧџQQQџCCCџ444џЛСРџ+++џРРРџЛЛЛџЄЄЄџГГГџЇЇЇџ   џ›››џŽŽŽџџrrrџjjjџlllџ\\\џ€€€џkkkџ џџџ567џ]]]џ‡‡‡џ›››џЎЎЎџМММџУУУџŠŠŠџсссџТТТџФФФџТТТџТТТџТТТџџГГГџЙЙЙџЭЭЭџ888џNPPџšžžџZ[[џUVVџОУТџЖЖЖџЅЅЅџСССџЎЎЎџІІІїHHHmmmџ‹‹‹џЄЄЄџЗЗЗџТТТџЪЪЪџНННџтттџШШШџЙОНџ_``џQQQџbddџЇЌЋџ...џЦЦЦџПППџЁЁЁџВВВџЈЈЈџЁЁЁџЁЁЁџџ|||џkkkџdddџhhhџYYYџџpppџџџџџ џџHHIџhiiџŽŽŽџЁЁЁџ{{{џвввџРРРџХХХџУУУџХХХџУУУџЁЁЁџхххџХХХџЕЕЕџ”””џџ788џ™žџЛСРџЉ­ЌџРРРџЇЇЇџЧЧЧџЩЩЩџЪЪЪёџџџmmmџ‹‹‹џІІІџЙЙЙџШШШџеееџЛЛЛџпппџдддџЉЌЋџ­ВБџЅЊЉџ—››џ"##џCCCџŸŸŸџ˜˜˜џ‹‹‹џџ™™™џŸŸŸџЅЅЅџ   џ–––џyyyџdddџiiiџWWWџџooo§џџџџ џџџџ–™šџY[[џSSSџœœœџ›››џЏЏЏџМММџУУУџТТТџЂЂЂџцццџЫЫЫџЬЬЬџЪЪЪџЖЖЖџVVVџџ&&&џЦЦЦџШШШџЈЈЈџЬЬЬџЬЬЬџЪЪЪёnnn§’’’џБББџžžžџšššџ˜˜˜џЏЏЏџЧЧЧџзззџШШШџ)))џџ џMMMџШШШџЩЩЩџЖЖЖџЋЋЋџЃЃЃџ™™™џ}}}џџsssџYYYџLLLџ___џkkkџXXXџ‚‚‚џnnnљџџџџ џџџџЇЋЌџ445џџ566џUVVџsttџ‘‘‘џЄЄЄџДДДџœœœџтттџЫЫЫџЭЭЭџЬЬЬџЪЪЪџЦЦЦџЛЛЛџЕЕЕџІІІџЋЋЋџ   џеееџЭЭЭџЪЪЪёћ\\\џ```џ˜˜˜џРРРџмммџсссџуууџцццџжжжџыыыџПППџпппџнннџгггџЪЪЪџТТТџИИИџБББџЇЇЇџ‡‡‡џЂЂЂџ€€€џoooџgggџ___џXXXџ===џBBBџlllў444џ+++џџџ џџџџЇЋЌџ445џџ"""џ&&&џ)))џBBBџ^^_џƒƒƒџxxxџРРРџЛЛЛџУУУџЧЧЧџЪЪЪџЩЩЩџМММџШШШџЫЫЫџЩЩЩџЎЎЎџ™™™џЊЊЊџЪЪЪѕZZZњvvvџБББџУУУџгггџнннџфффџцццџхххџзззџщщщџуууџпппџлллџгггџЪЪЪџСССџИИИџАААџЅЅЅџƒƒƒџœœœџyyyџkkkџhhhџmmmџuuuџ{{{џhhhџIIIџ џ џ333џMMNџCCCџ)))џџџЇЋЌџ445џџ"""џ&&&џ)))џ---џ111џ˜›œџQRSџllmџџ–––џЇЇЇџЕЕЕџРРРџИИИџЬЬЬџЮЮЮџаааџбббџбббџТТТџЏЏЏєrrrщџДДДџХХХџгггџрррџчччџъъъџшшшџжжжџцццџрррџмммџеееџаааџШШШџРРРџЗЗЗџАААџІІІџџœœœџxxxџmmmџmmmџsssџ}}}џџ‚‚‚џdddџџџџџџ<<<џbccџOOOџЎБВџ445џџ"""џ&&&џ)))џ---џ111џšžџ?@@џ===џ@@@џYZZџklmџ~~~џ———џŸŸŸџОООџШШШџЮЮЮџбббџвввџвввџввв№xxxмџЕЕЕџШШШџеееџрррџцццџхххџнннџХХХџЮЮЮџХХХџЛЛЛџЗЗЗџВВВџЌЌЌџЅЅЅџŸŸŸџžžžџ˜˜˜џwwwџ”””џyyyџrrrџuuuџ|||џ„„„џ‡‡‡џ†††џvvvь@AAы%%%џ###џ112џGHHџ\^_џruuџtvwџ~€€џrssџ\]]џLLLџ&&&џ)))џ---џ111џšžџ?@@џ===џ@@@џDDDџHHHџLLLџcccџyyyџˆˆˆџ   џГГГџТТТџЫЫЫџаааџввв№}}}Я‚‚‚џЕЕЕџПППџСССџТТТџОООџЕЕЕџЊЊЊџ’’’џ’’’џ………џџzzzџsssџmmmџkkkџkkkџmmmџmmmџYYYџtttџeeeџfffџnnnџyyyџ„„„џˆˆˆџ‰‰‰џ‚‚‚Лiii•——^ŒЙ`abљGHHџ333џ333џ333џ333џ333џJJKџrstџiijџXXXџ333џšžџ?@@џ===џ@@@џDDDџHHHџKKKџOOOџ“–—џXXXџijjџyzzџџЄЄЄџЖЖЖџЩЩЩёРxxxџџ–––џŠŠŠџ~~~џƒƒƒџ‘‘‘џ•••џџџџџ|||џvvvџnnnџeeeџ]]]џ[[[џWWWџKKKџJJJџDDDџ@@@џNNNџ\\\џkkkџyyyџ‚‚‚џЏloo|abdбMNNќEEEџEEEџEEEџEEEџEEEџEEEџ__`џ‚џЎББџeffџBBBџ@@@џDDDџHHHџKKKџOOOџ“–—џUUUџXXXџ[[[џbbbџprrџ|}}џЇЇЇѓnnnЛXXXџiiiџsssџ‡‡‡џџ™™™џžžžџџ˜˜˜џ“““џџ‹‹‹џ………џ~~~џvvvџmmmџeeeџ[[[џSSSџJJJџBBBџ<<<џ555џ333џ<<<џAAAџLLLџcccџrrrЋy||\qqrС|~€щˆŠ‹џ‡‰ŠџˆŠ‹џ~€€џtuuџfggџ```џ‚‚џ€џjjjџPPPџKKKџOOOџ“–—џUUUџXXXџ[[[џ^^^џ```џbbbџiijџfffYYYПPPPџ[[[џqqqџ‡‡‡џ———џЁЁЁџЅЅЅџЁЁЁџ›››џ•••џ‘‘‘џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ222џ111џ000џ???џQQQЛ……Š;|ИttuяgggџgggџgggџgggџgggџgggџlllџŠ‹‹џ‡ˆˆџvvvџ—š›џUUUџXXXџ[[[џ^^^џ```џbbbџdddџfff№(((K666№IIIџ```џvvvџ‹‹‹џšššџЃЃЃџЅЅЅџ   џ˜˜˜џ’’’џџŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ666џFFFіNNNXŒ’’(‰ŠŠœ‚ƒƒчyyyџyyyџ‚џŠ‹Œџ‘“”џ˜›œџ ЁџІЈЉџŒŒџџfffџ^^^џ```џbbbџdddџfff№'''-000љ999џKKKџ```џuuuџˆˆˆџ•••џœœœћс›››й———ХšššДŒŒŒџŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ:::џOOOџ___љQQQ5ЉЉЉ ІЉ­NЃЇЉЄ–——єџŠŠ‹џ………џ………џ………џ†††џ——˜џ”••џ‰‰‰џnnnџdddџfff№,,,Н333џ999џJJJџ___џ}}}џ’’’тДДДыПППџПППџПППџПППџЛЛЛџˆˆˆџŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ;;;џSSSџeeeџ^^^Ә›n˜˜™Ч”””ћ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ‘‘‘џ’’’џœџ›››іjjjи---№333џ999џHHHџ]]]џ†††џLRSџquvџЅІІџ­­­џ­­­џ­­­џЊЊЊџ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ222џ„„„ћ___ыfffџcccџŸŸЂHžŸŸЛšœœшš››щšššЮ›››Љ˜˜˜h™™™?———333ќ333џ999џHHHџ\\\џџHNPџAHJџFMOџ“““џ———џ———џ•••џ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ222џ‘‘‘џ———џ}}}џaaa§444џ333џ999џGGGџ[[[џ”””џHNPџAHJџAHJџ|}}џ€€€џ€€€џџ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ333џ:::џ%%%џџpppџ 222§333џ888џFFFџZZZџ”””џHNPџAHJџAHJџfffџhhhџhhhџiiiџ‡‡‡џŒŒŒџ………џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ555џџџџrrrї...ё333џ888џFFFџ[[[џ•••џHNPџAHJџAHJџQQRџRRRџRRRџTTTџˆˆˆџŒŒŒџ„„„џ~~~џvvvџmmmџeeeџ\\\џTTTџKKKџDDDџ>>>џ888џ444џ333џ333џ777џ///џ---џ---џ}}}ю...№333џ999џJJJџbbbџџJPRџAHJџAHJџBCCџ333џ888џџТТТџШШШџФФФџСССџОООџЬЬЬџЧЧЧџЙЙЙџЗЗЗџ–––џŒŒŒџ___џIIIџ333џ333џ444џ:::џBBBџBBBџBBBџ‚‚‚№...№333џ:::џOOOџrrrџМММџ^bdџAHJџAHJџ888нџџ999џcccџ’’’џŸŸŸџџ›››џšššџ˜˜˜џ™™™џЈЈЈџЅЅЅџЎЎЎџИИИџЕЕЕџ­­­џ–––џeeeџBBBџVVVџWWWџWWWџ„„„я...№222џEEEџЉЉЉљЩЩЩќОООџШШШў‘џDKMџJJJнџџ888џWWWџfffџuuuџ‚‚‚џyyyџyyyўzzz№………ѕ‹‹‹џˆˆˆџ†††џ„„„џџџ‚‚‚џ‘‘‘џџjjjџlllџlllџ€€€я000№———єРРРњЋЋЋџЄЄЄџЂЂЂџЁЁЁџДДДџГГДџoopуџџ888џWWWџfffџ^^^џFFFџ,,,џ)))џџ№ B}}}xzzzКtttўQQQџyyyє~~~џ~~~џ~~~џ~~~џ~~~џ|||юџџџŒŒŒсЃЃЃџЁЁЁџŸŸŸџџ›››џšššџˆˆˆџWWWџvvvнџџ888џWWWџfffџ^^^џFFFџ,,,џ===џ)))џ)))№№џ’’’ѓŽŽŽџŽŽŽџ———џЁЁЁџЌЌЌџ   ьџџџœœœэ›››џšššџ˜˜˜џ–––џ”””џ‰‰‰џ\\\џWWWџˆˆˆоџџ888џWWWџfffџ^^^џFFFџ,,,џNNNџGGGџGGG№№џєї———ќŠŠŠџsssџWWWџfffџ•••К“““ѓ‘‘‘КŽŽŽ„vvvџnnnџlllџlllџlllџšššпџџ888џWWWџfffџ^^^џFFFџ,,,џ^^^џfffџfff№№BBBџ]]]џWWWџUUUџSSSџQQQџPPPџNNNо””” ~~~џ~~~џ~~~џ~~~џ~~~џІІІпџџ888џWWWџfffџ^^^џFFFџ,,,џdddџ………џ„„„№]]]хbbbљQQQџPPPџNNNџMMMџKKKџIIIфGGG'ŽŽŽџ———џІІІџАААџГГГђ­­­яЁЁЁѓ“““ј‘‘‘џ™™™џŽŽŽџ}}}џiiiџUUUџrrrџЃЃЃџЂЂЂ№UUU LLL™KKKџJJJџIIIџHHHэGGG„??? ВВВ†•••Єtttвjjjџgggџeeeџcccџaaaџ^^^џ\\\џpppџxxxџwwwџuuuџњЏЏЏљЛЛЛ№HHH?GGG™HHHTUUUUUU]]]9[[[oYYY™WWWБWWWЬUUUЬRRRоQQQџPPPџNNNџMMMџVVVъ”””ЩЦЦЦ џў`џџџџўџџџ№џџџРџџџџ?џџ?џџ?џџ?џџ?џџ?џџ€џџ€џџ€џџ€aџРРРРр№№№№№№№№№№№№№№№№№№№№№№№№јјјјјјјрјќ№џ€рџ№рџџрџџррџџџџрџџџџрџџџџрџџџџрџџџџрџџџџрџџџџрџџџџР№џџџџР№џџџџр№џџџџю№џџџџў№џџџџўќ?џџџџџРџџџџџџџџџџџџџџ(0` €%#C _%%%t***„222“333000Ђ)))™ ~lZ m >Г3• < 71Ћ3­\ira>###ˆIIIЛ|||ы™™™џ   џ™™™џ’’’џ‹‹‹џ‚‚‚џxxxџkkkџ___џSRSџDACџ&@.џa-џr3џy2џ Pєo7ѕ#y=џf2џ Nџf'џi'џ`!џ" œ 4КEEEљmmmџŽŽŽџЄЄЄџ­­­џЊЊЊџџ‘‘‘џ‰‰‰џџtttџiiiџ]]]џRRRџGAEџ&`7џ,žNџv1џo1џ(Nџ5šZџ/ŒJџm4џl0џ z5џg%џv.џl)§c'''ч@@@џRRRџlllџ‰‰‰џŸŸŸџЊЊЊџЉЉЉџџџˆˆˆџџtttџhhhџ]]]џRRRџHDGџ5E9џŽ>џ)ЅKџ!Œ=џ"‚Eџ2‹MџLДbџ ƒ<џ…<џ{3џq)џm(џz0џ,•666џ===џPPPџjjjџ‡‡‡џžžžџЊЊЊџЊЊЊџџ‘‘‘џˆˆˆџџtttџhhhџ]]]џRRRџHFGџ697џ$<џ8ЛXџ+žGџ Cџ(šKџ—Hџ“Dџ"—Eџ&•Bџx+џv-џr,џGб +444џ===џPPPџiiiџ†††џžžžџЊЊЊџЉЉЉџџŽŽŽџ„„„џ{{{џoooџdddџYYYџNNNџECDџ676џ,•Bџ.ЛQџ%šBџ'ЅKџ&ЋLџž?џ% DџAО]џ*šEџ1џ"?џt1џ"~6џa&Ц333ъ===џOOOџfffџƒƒƒџŸŸŸџБББџГГГџЉЉЉџЁЁЁџŸŸŸџšššџ”””џ‡‡‡џyyyџfffџWWWџJFIџ1X:џ$e5џj*џ–;џ/СTџ"Ќ@џž8џ"ЂBџ"“@џy1џ9џq1џ,“Cџw/м000И;;;џNNNџuuuџџџІІІџЈЈЈџЅЅЅџŸŸŸџЃЃЃџЇЇЇџџ‰‰‰џ………џ~~~џuuuџzzzџrnqџQFNџ=OAџ#ЗGџ&ХKџ+ПNџ6Ч\џЂAџ,ЇMџ$ŒAџ!r9џq0џ-›Hџ_,Ш---’JJJџuuuџ‚‚‚џ‚‚‚џЅЅЅџСССџлллџхххџфффџжжжџдддџСССџГГГџЉЉЉџЁЁЁџ•••џџџiiiџ]Y\џ.n<џ#ЊCџ1ЭUџ)СOџ.КRџ#ЏKџ$›Hџ4џ2ŸKџ!”AџLuXџ]V\к***y333gsssџuuuџ‘‘‘џ‹‹‹џЬЬЬџхххџ№№№џѓѓѓџђђђџрррџлллџЬЬЬџСССџКККџЎЎЎџЊЊЊџšššџЂЂЂџšššџŒŒŒџxtwџGPIџ&P0џ.ИQџЕBџ>ˆPџTaWџW‹dџy™€џf„nџ€‚€џ‡†‡џŽŽŽџkkkс---| HHH1iiiџyyyџŸŸŸџŽŽŽџЬЬЬџщщщџєєєџёё№џссрџЦЦЦџЮЮЮџеееџЭЭЭџЫЫЫџПППџЕЕЕџЅЅЅџЈЈЈџœœœџ›››џџŒŽџ.)-џS€^џe’pџ|~џ{vyџ€|џ}w{џ‹џџ‰‰‰џџ•••џ”””џvvvр303xH8Ÿa+п GЙ[ kTVVV“€€€џ­­­џ”””џаааџсррџуууџЛННџ‘‘џ†ŠŠџ‚„„џПППџДДДџЎЎЎџЄЄЄџџџЂЂЂџЄЄЄџžžžџџџ@@@џ`Y^џ…ƒџ‹‹‹џ‚‚‚џ‡‡‡џ|||џ|||џ†††џ“““џ“““џ•••џџšššџ“’џ3oIћ€;џ7ЃTџ<ЎTџe&њ$…Bџ&?џX Фmmm:ŽŽŽџŸŸŸџzzzџЉЉЉџПППџиййџhlmџ џBDEџ}€џаЯЯџЖЖЖџЉЉЉџЇЇЇџ–––џ………џџyyyџqqqџŠŠŠџŠŠŠџPPPџ]]]џnnnџxxxџzzzџ™™™џ–––џ•••џ“““џ˜˜˜џ•••џЂЂЂџЅЅЅџџ—‘•џ2KџŠ:џ,šFџ;­Sџ~1џ,”GџAДZџ‡4џ,bzzz6oooџŽŽŽџЙЙЙџжжжџлллџ№ё№џadeџџNPPџƒ‡ˆџпооџЧЧЧџМММџФФФџЙЙЙџЕЕЕџЊЊЊџ™™™џxxxџnnnџbbbџQQQџeeeџˆˆˆџџˆˆˆџ‰‰‰џ•••џЉЉЉџЈЈЈџ­­­џ   џЂЂЂџЇЇЇџЌЌЌџАЌЏџszџ'ЃDџ8ЕQџ. Hџ"ˆ:џ4ЉLџ7ЌQџ"‹;џ ?ttt0”””џСССџЩЩЩџаааџиииџьээџjmnџ.--џceeџƒ‡ˆџиииџТТТџЗЗЗџОООџЖЖЖџ­­­џЈЈЈџЁЁЁџŒŒŒџџzzzџ>>>џbbbџ’’’џšššџ›››џ   џџџœœœџ­­­џЕЕЕџЋЋЋџЊЊЊџЉЉЉџВБВџŸ Ÿџ=•Qџ;ЗUџ8ЈSџ#?џ<ЕUџ>АYџ#†>ѕ –––'ЉЉЉњРРРџЬЬЬџкккџкккџяяяџ”˜˜џeggџnrsџ““џРРРџБББџЌЌЌџЖЖЖџДДДџБББџ­­­џЉЉЉџџ˜˜˜џ„„„џAAAџkkkџ}}}џŠŠŠџЇЇЇџ­­­џšššџ­­­џЇЇЇџžžžџЋЋЋџГГГџЙЙЙџАААџЛЛЛџА­Џџ—™џJ ]џ'‡?џŽ8џ4ЊPџ,œIџh+вЅЅЅ"ВВВїОООџВВВџЉЉЉџЙЙЙџиииџвггџПТТџВГДџХХХџДЕЕџЉЉЉџЇЇЇџІІІџ™™™џ™™™џŠŠŠџ………џџ’’’џzzzџLLLџ———џ–––џ†††џ‰‰‰џџ   џДДДџ­­­џЉЉЉџЈЈЈџЌЌЌџИИИџЏЏЏџРРРџЖЖЖџЖДЖџЎЉ­џdkџ'ЃBџ6­Oџ*FџM!‘ЁЁЁŒŒŒѕwwwџЇЇЇџЧЧЧџрррџђђђџщщщџрппџнннџдееџЪЪЪџУУУџОООџЏЏЏџБББџЊЊЊџœœœџ†††џiiiџ^^^џbbbџGGGџ———џ   џŸŸŸџˆˆˆџoqqџˆ‰‰џ’’’џЏЏЏџДДДџЏЏЏџЖЖЖџДДДџАААџБББџИИИџНННџЙЖИџžžžџMž`џ>НZџ.ЂMџ 8g„„„‚‚‚ѓ“““џбббџкккџхххџюююџцццџфффџрррџиииџЭЭЭџТТТџОООџБББџ­­­џІІІџЂЂЂџџ€€€џqqqџRRRџOOOџwwwџ………џ   џxyxџW[[џ^bbџ‰џ“””џžžžџЅЅЅџБББџНННџЕЕЕџЖЖЖџВВВџЗЗЗџЉЉЉџЄЁЄџЎГЏџ?~NЦ$˜˜˜э˜˜˜џЭЭЭџеееџфффџюююџтттџуууџрррџдддџПППџКККџЛЛЛџГГГџЋЋЋџЈЈЈџЇЇЇџ‘‘‘џџxxxџZZZџqqqџЃЃЃџ———џ’’’џdeeџ@BAџџY]]џБГГџЊЉЉџ˜˜˜џЅЅЅџЌЌЌџЛЛЛџОООџКККџУУУџЕЕЕџЅІЅџЉЈЉџ‘‘‘џ‰‰‰ ŠŠŠш‘‘‘џЛЛЛџБББџЙЙЙџЩЩЩџйййџдддџЧЧЧџСССџЗЗЗџЉЉЉџ   џ”””џ‚‚‚џ„„„џŒŒŒџџŠŠŠџ‚‚‚џZZZџsssџЋЋЋџВВВџЖЖЖџ[\\џXYYџ$##џ[^_џЖИЗџЙЙЙџЎЎЎџЖЖЖџ­­­џБББџДДДџТТТџЦЦЦџПППџЖЖЖџБББџ‘‘‘џ vvvфvvvџџЛЛЛџдддџуууџыыыџуууџзззџжжжџЮЮЮџСССџЙЙЙџИИИџЎЎЎџšššџ“““џџkkkџ___џNNNџ\\\џ•••џБББџОООџ^__џillџGGGџhkkџЃЅЅџ­­­џАААџРРРџСССџЛЛЛџ•••џ ЁЁџЅЅЅџЖЖЖџИИИџНННџ‘‘‘џfffhhhйЃЃЃџ———џЯЯЯџрррџрррџсссџпппџЭЭЭџвввџЦЦЦџЛЛЛџЛЛЛџЗЗЗџГГГџЃЃЃџ   џŠŠŠџ„„„џsssџVVVџ{{{џџƒƒƒџ’’’џ†††џnpoџ]__џ€„„џАББџНММџЋЋЋџДДДџОООџЙЙЙџehgџ`ccџ‚††џІЈЇџЄЄЄџ   џ‘‘‘џqqqСžžžџ‘‘‘џПППџЯЮЮџЮЮЮџКННџ—››џ’••џ†‡‡џБББџŸŸŸџœœœџ———џ“““џџ’’’џ„„„џ„„„џ‚‚‚џgggџ‡‡‡џЇЇЇџЌЌЌџЅЅЅџžžžџ›››џ„„„џЁЁЁџИИИџСССџЕЕЕџМММџИИИџАААџeggџџ%''џЋЏЏџЗЗЗџЄЄЄџ‘‘‘џrrrЛ†††џ†††џЁЁЁџОООџиййџfjjџџACCџx|}џКЙЙџЄЄЄџЉЉЉџџ”””џ‡‡‡џuuuџfffџeeeџqqqџ^^^џ€€€џЁЁЁџЎЎЎџРРРџТТТџУУУџЇЇЇџЊЊЊџЉЉЉџЙЙЙџРРРџЦЦЦџУУУџЗЗЗџqssџ@@@џ344џЈЌЌџЎ­­џЉЉЉџ‘‘‘џ\\\Ж{{{џ­­­џРРРџЮЭЭџфххџadeџџOPQџz}~џСССџЏЏЏџЌЌЌџЅЅЅџžžžџ‘‘‘џ~~~џpppџiiiџgggџ///џ555џ__`џџДДДџТТТџЫЫЫџЏЏЏџУУУџСССџВВВџБББџФФФџУУУџЧЧЧџoqqџbccџSTTџЇЊЊџ ŸŸџœœœџ‘‘‘џ\\\ џЎЎЎџУУУџЮЮЮџхццџknnџ...џdffџz~џЫЫЪџЖЖЖџЏЏЏџЊЊЊџ   џџsssџdddџhhhџ‚‚‚џ444џџџ!!!џIIIџ{{{џЃЃЃџŸžžџНННџФФФџЧЧЧџСССџЕЕЕџРРРџФФФџЁЁЁџoqpџadcџЉЋЋџПООџЪЪЪџ‘‘‘џbbb‡ŽŽŽџЉЉЉџКККџЙЙЙџЫЫЫџ‡‹‹џXZ[џlqrџ‚…†џММЛџЅЅЅџ•••џџ†††џtttџpppџkkkџdddџƒƒƒџ222џџџџџџ`bbџDDDџ|||џЁЁЁџИИИџРППџПППџдддџЫЫЫџШШШџДДДџ–––џПППџЛЛЛџгггџ‘‘‘џjjjqqqџ‚‚‚џГГГџгггџфууџНППџˆŽџЋЎЏџлллџаааџТТТџЕЕЕџŸŸŸџšššџwwwџ___џYYYџNNNџ```џ222џ џџџ џџXZZџџ$$$џ<<<џaaaџ†‡‡џџСССџЧЧЧџЬЬЬџОООџЦЦЦџСССџЋЋЋџЗЗЗџ‘‘‘џZZZtuuuџУУУџзззџхххџыыыџфууџщщщџчццџзззџЩЪЪџОООџГГГџžžžџ›››џwwwџjjjџrrrџ~~~џtttџ'''џ џ!!!џ###џ,++џ555џ_aaџџ џ&&&џ)((џNPPџLLLџhhhџˆˆˆџІІІџЎЎЎџХХХџгггџеееџЪЪЪџ‘‘‘џmmm]џТТТџЭЭЭџгггџбббџМММџВВВџЋЋЋџŸŸŸџ———џ‘‘‘џŽŽŽџƒƒƒџ………џmmmџjjjџxxxџ†††џŒ‹‹џMOOЮ###ю---џBCCџbddџvxyџ`aaџIIIџ777џ,,,џ)))џNOOџ:::џ===џGGGџVVVџrrrџ“““џЏЏЏџФФФџбббџ‘‘‘џvvvItttџŸŸŸџ“““џŽŽŽџ‹‹‹џ~~~џvvvџrrrџkkkџbbbџ[[[џVVVџOOOџPPPџIIIџNNNџbbbџwwwџƒƒƒџuuuAmmm““GddfЂQRRх;<<ў111џ===џJJJџUUUџ```џcdeџCCCџ>>>џCCCџFFFџhiiџdddџeeeџ€€€џœœœџ‘‘‘џeee?LLLџlllџ}}}џ•••џџ———џџ‰‰‰џџrrrџfffџXXXџJJJџ???џ666џ000џ666џDDDџYYYџmmm1___^^^A```”mppШkll§sttџ€‚‚џsttџjjjџ___џ\\\џMLLџghhџ___џVVVџ\\\џaaaџ\\\џ???666•PPPџwwwџ–––џІІІџЈЈЈџœœœџ’’’џŠŠŠџ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ222џ///џ777џKKKUџџџvvv6uwwulllУgggћiiiџpppџ}}}џ„…†џŠŒŒџtuuџ^^^џ]]]џ^^^џ\\\џ***Ѓ<<<џXXXџyyyџžžžџЌЌЌўЏЏЏќЌЌЌёšššњ‰‰‰џ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ333џ222џ888џXXXјRRRA‡‡‡"—ššY“–—Й‹ŒŒъ‹ŒŒџ‰‰‰џ‰‰‰џ†‡‡џ‡ˆˆџsssџ\\\џ111ћ<<<џTTTџ}}}џ…ˆ‰џЌ­­ўЙЙЙўЛЛЛ§œœœўˆˆˆџ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ222џ999џ^^^џdddџ```Й‘‘‘”””V“““Ё’’’н““”у”••Л˜™™І”””n222џ<<<џSSSџƒƒ„џGNPџJPRџ‘‘‘џœœœџ’’’џŠŠŠџ€€€џsssџgggџZZZџMMMџBBBџ999џ444џ000џ@@@џžžžџџQQQџЉЉЉ 222џ;;;џQQQџ‡ˆˆџQWYџ;BEџjklџyyyџ†††џŒŒŒџџrrrџfffџZZZџMMMџBBBџ999џ444џ333џ555џ,,,џџQQQџ222џ;;;џQPPџ‡ˆˆџPWYџ>EGџSUUџVVUџ}}}џџ„„„џwwwџjjjџ[[[џKKKџ<<<џ222џ,,,џ111џ444џџ!!!џQQQџ222џ888џRRRџ”••џLSUџ>>џWWWџџЄЄЄџ­­­џžžžџŽŽŽџџqqqџ^^^џKFJџ2P8џ'ŸDџ “=џ)ЏNџ›;џ.ЋLџŒ:џ6џ{5џg)г)))J999џ[[[џˆˆˆџЁЁЁџЋЋЋџЌЌЌџЋЋЋџЇЇЇџ”””џ†††џtttџdddџFKGџ(p:џ%ШLџ(ОLџ%ЌIџ$šDџy7џ#‰=џq1г ''' NNNїzzzџ‘‘‘џМММџкккџшшшџнннџЭЭЭџЗЗЗџ­­­џџŒŒŒџ~x|џS^Uџ(€=џ+ВLџ$ОLџ+˜Jџ1†Gџ;šSџP{\ћ\W[Ь$$$a ???aaa憆†џЄЄЄџмммџїііџѓѓђџжжжџвввџаааџФФФџЕЕЕџџЃЃЃџ“‘“џpemџ4O:џPšbџmrnџsutџ}}џŒŠ‹џ‘‘‘џŽŽŽџlllд.,.h QE Ѕ)u Q 8\\\^”””џ   џУУУџмннџ‰ŒŒџcffџžŸ џЛЛЛџЅЅЅџџ‡‡‡џџ———џ‰Š‰џKGJџzrxџ€~€џˆ‡ˆџƒ‚џ†……џ’’’џ˜˜˜џ›š›џŽŽџ'zCџ0ЃOџ*•Cџ$†?џ'Ž?љ( _vvv6ƒƒƒџЌЌЌџЫЫЫџиййџ;=>џ.00џЋ­­џгввџМММџЗЗЗџЃЃЃџŒŒŒџnnnџjjjџSSSџџˆˆˆџ‹‹‹џ™™™џœœœџ   џЁЁЁџЉЉЉџЈЄЈџJ‘]џ-­Iџ.Hџ0 Iџ6ЎQџ A‚‚‚1ЋЋЋўзззџмммџоппџ\^^џQSSџБГГџгггџОООџОООџБББџЅЅЅџ‹‹‹џ|||џEEEџ†††џœœœџœœœџ–––џџ­­­џБББџ­­­џДАГџŠŽџ9ЋSџ(™Dџ5ЊOџ1ЂNџ GЇЇЇ&ЛЛЛљМММџСССџжззџЕЗЗџЅЈЉџХЦЦџИИИџЄЄЄџ™™™џ“““џ‹‹‹џ}}}џ|||џbbbџŽŽŽџŠŠŠџ———џЂЁЁџЎЎЎџЊЊЊџЎЎЎџЗЗЗџИИИџЙЕИџ‘Ђ–џ9‹Mџ.ЎJџ(‘A§ ŸŸŸ ………ѕЊЊЊџиииџ№№№џђђђџјјјџъъъџлллџХХХџЄЄЄџЁЁЁџ‚‚‚џeeeџPPPџbbbџžžžџ•••џvxxџŒџЄЄЄџБББџВВВџЖЖЖџГГГџИИИџКВИџ’І–џ@ЉVїb)І‘‘‘ядддџыыыџђђђџъъъџэээџрррџЯЯЯџЙЙЙџŸŸŸџЄЄЄџџ€€€џ[[[џxxxџ–––џ‡‡‡џFHHџ8::џžžџІЅЅџЉЉЉџЕЕЕџНННџИИИџЕЕЕџДБГџŸŸŸџooo~~~ъЄЄЄџУУУџоооџъъъџрррџЮЮЮџЗЗЗџЅЅЅџ’’’џџvvvџtttџ^^^џ„„„џРППџ“““џKLLџ677џŸЁЁџИЗЗџЛЛЛџИИИџЖЖЖџЙЙЙџСРРџПППџŸŸŸџbbb pppфžžžџрррџњњњџџџџџцччџиииџЬЬЬџПППџБББџ‘‘‘џ„„„џqqqџWWWџxxxџ”””џ•••џijjџfiiџŸ  џЖЖЖџМММџХХХџ…‡‡џtwwџІЇЇџБББџŸŸŸџfffyyyжšššџТТТџмммџ•˜˜џruuџœžџЌЌЌџ———џџyyyџrrrџvvvџkkkџ———џІІІџЙЙЙџЉЉЉџ˜™™џЏЏЏџЦЦЦџЧЧЧџСССџpqqџ џŒџКККџŸŸŸџUUUdddг”””џЩЩЩџмннџ:<<џ,..џž ЁџПППџЈЈЈџ›››џџbbbџZZZџEEEџPQQџˆˆˆџФФФџЭЭЭџЙЙЙџОООџМММџУУУџЩЩЩџ~~џJKKџ‹џЌЋЋџŸŸŸџnnnЧЎЎЎџЭЬЬџежжџ^``џRUUџ›џЗЗЖџžžžџ–––џ€€€џgggџoooџ???џџџ???џ}}}џ–––џХХХџЯЯЯџСССџЩЩЩџДДДџ‚ƒƒџЇЈЈџТТТџŸŸŸџjjjНџОООџтттџБГДџŸЃЃџЪЫЫџПППџЃЃЃџ‡‡‡џnnnџ\\\џ```џ999џ џ џџ244џ'''џOOOџ‚ƒƒџЃЄЄџЧЧЧџгггџЫЫЫџУУУџЕЕЕџŸŸŸџmmmДДДДџоооџюююџцццџрррџЩЩЩџЕЕЕџЄЄЄџ‹‹‹џsssџsssџƒƒƒџ@@@§џ///џDEEџPQQџ(((џџ9::џPPPџaaaџŠŠŠџЉЉЉџЫЫЫџбввџŸŸŸџ}}}ЃЁЁЁџЅЅЅџ   џ‘‘‘џ‡‡‡џyyyџkkkџbbbџXXXџUUUџgggџ„„„џprregggefhаZZZўTTTџPPPџLLLџWXXџNNNџ:::џEDDџhiiџyyyџŸŸŸџŸŸŸџWWWžiiiџŠŠŠџšššџ‘‘‘џ†††џyyyџfffџRRRџ@@@џ555џ555џFFFџa^^Y___ ```Œceeй\]]ќ]]]џ___џ`__џ___џmnnџUUUџZZZџZZZџ$$$T@@@№sssџЅЄЄўВВВ§ЄЄЄњŒŒŒџ|||џiiiџVVVџDDDџ777џ111џ000џKKKЮVVVDxxxmmmmijjЫbbbј^^^џiijџqqqџpppџZZZџUUU000гEEEџoppџ~‚ўЌЌЌў­­­ўŒŒŒџ{{{џiiiџVVVџDDDџ777џ///џQQQџnnnџZZZџ ‚‚Riiiаbbdэcccфyyyo333000зCCCџpqqџBJLџehhџ‡‡‡џ‰‰‰џyyyџeeeџRRRџ@@@џ555џ111џ@@@џEEEџZZZџ333111е???џpqqџFMPџBDEџ]\\џžžžџ’’’џ‚‚‚џqqqџYYYџ@@@џ222џ+++џ+++џZZZџ333---еdccџЇЇЇџsxyџ.11џ/..џŠŠŠџ   џ˜˜˜џœœœ§žžžџ•••џyyyџ\\\џbbbџZZZџ???]]]јЎЎЎџЊЊЊџ———џKKKџ(((џ^^^џLLLџ777џZZZџyyy;ZZZџkkkџ•••џ’’’џZZZџrrrЭaaaэZZZџrrrџcccџ...џcccџBBBџUUUџZZZџZZZџXXXџgggџYYYџ[[[b‰‰‰N‰‰‰ќ€€€џlllџzzzџiiiџ„„„џuuuы[[[ГXXXїEEEЦGGG`UUUmmmZZZЕYYYЯYYYжYYYмXXXпVVVЦoooWјџРџџџџџ€€€€€€€€€€РРРРРР€xџџџџџрџрџџ(0 ` =S9k2_4 / @?P<‡7“Bз4 ˆF‚$pEџb6џp5џz4џp.џK`OџxxxџpppџdddџWWWџJJJџ>>>џC%џ.~Oџa6џ w:џ|6џs,џ7f YS)ŠMњAџ!Aџ*™Eџ‚6џ9cCџ———џ†††џvvvџdddџQQQџAAAџ!I+џ1—Yџ‚Cџ)•Hџ,Gџ€4џ<f f#9% Kя)БRџ.ГPџ5ЋQџ{7џŠ•џšššџ†††џvvvџdddџQQQџAAAџ+G2џ.АXџ*ВRџ1ЗSџ7ЋQџt4љ6•2К$ДGњ%ВEџ/ЉPџDqPџЊЊЊџ›››џ†††џvvvџdddџQQQџAAAџ:>;џ,ŽCџ%ВEџ)ЕHџ-ЉOњNat'S$„:џJdPџ{{{џ………џyyyџiiiџ___џTTTџHHHџ===џ???џTTTџ)M1џ~*Ѓ eЃЃЃіƒƒƒџпппџюююџшшшџВВВџХХХџАААџšššџiiiџэЈЈЈхŒŒŒџчччџїїїџяяяџЖЖЖџЬЬЬџЖЖЖџ   џnnnџ‘‘‘лІІІЭŽŽŽџчччџїїїџяяяџ(.1џЬЬЬџЖЖЖџ   џrrrџЩ………ЪџБББџлллџиииџ'.1џ“““џ}}}џpppџsssџtttУЈЈЈЈЦЦЦџфффџлллџёёёџ28:џЩЩЩџ}}}џЃЃЃџ———џЂІІІ“ЦЦЦџфффџлллџёёёџсссџЩЩЩџ~~~џЃЃЃџ———џŽŽŽ†††’џВВВџлллџиииџЖЖЖџ“““џ~~~џtttџvvvџuuu‰   oџчччџїїїџяяяџЖЖЖџЬЬЬџЖЖЖџ   џwwwџŽŽŽfžžžZџчччџїїїџяяяџ(.1џЬЬЬџЖЖЖџ   џwwwџŽŽŽTŠŠŠU‘‘‘џДДДџлллџиииџ'.1џ“““џ€€€џyyyџxxxџwwwMЄЄЄ0УУУџфффџлллџёёёџ28:џЩЩЩџ€€€џЃЃЃџ”””џ0ЉЉЉУУУџфффџлллџёёёџсссџЩЩЩџ€€€џЃЃЃџ”””џЉЉЉ ŒŒŒџЄЄЄџІІІџ­­­џЁЁЁџ‘‘‘џkkkџtttџkkkџbbb )))џ333џVVVџuuuџyyyџoooџ^^^џJJJџ888џ+++џ)))џ)))џ&&&ѓ333џ@@@џkkkџ’’’џ———џ‹‹‹џvvvџ]]]џFFFџ666џ333џ333џ111№333џ@@@џkkkџfff‹‹‹џvvvџ]]]џ"""333џ333џ111№333џ@@@џkkkџfff‹‹‹џvvvџ]]]џ"""333џ333џ111№333џ@@@џkkkџfffoooџ^^^џJJJџ"""333џ333џ111№рџРРРР№ќќќќќќќќќќќќќј?ј?ј„?ј„?ј„?(  @E F•=AЛ5 +<3FЇ DК GЪ6Ub+Pџ;џЙ@џ*`6џiiiџVVVџAAAџ...џ\.џ”Jџ$‚CџЁ;џ:S f&'ЄLїоCџ/›Mџa|hџ”””џvvvџYYYџ???џ+Y6џ,ЌTџдDџq1ч3i&5"z7ўHiQџVZWџPPPџMMMџAAAџ...џ697џ.W8џx'Ё [———џеееџэээџДДДџГГГџ˜˜˜џђ­­­џнннџіііџ(.1џКККџžžžџ‚‚‚ђƒƒƒџЁЁЁџпппџ.46џ………џiiiџbbbѕ­­­џЅЅЅџѕѕѕџсссџНННџmmmџђ­­­џІІІџѕѕѕџсссџНННџoooџђ†††џЅЅЅџпппџ)/2џ………џnnnџiiiѕ­­­џнннџіііџ,24џКККџžžžџ‚‚‚ђ›››џнннџіііџИИИџКККџžžžџ‚‚‚ђ111№TTTџ’’’џ’’’џvvvџQQQџ666џ333џ111№111№TTTџ’’’џ’’’џvvvџQQQџ666џ333џ111№111№RRR№fff’’’џvvvџOOO№"""333џ111№111№RRR№fff’’’џvvvџOOO№"""333џ111№ƒС€€Р№№№№№№№№ррррfwbuilder-5.1.0.3599/src/pix/0000755000175000017500000000000011733011756016365 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/pix/pix.pro0000644000175000017500000000126011733011756017706 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) SOURCES = pix.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32:CONFIG += console INCLUDEPATH += ../cisco_lib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../cisco_lib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../cisco_lib/$$BINARY_SUBDIR/libfwbcisco.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_pix fwbuilder-5.1.0.3599/src/pix/pix.cpp0000644000175000017500000001123511733011756017673 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #ifdef _WIN32 # include #else # include #endif #include #include #include #include #include #include #include #include "CompilerDriver_pix.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Constants.h" #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string &msg) const { msg.size(); // to make compiler happy about unused parameter cout << "Data file has been created in the old version of Firewall Builder.\nLoad it in the GUI to convert it to the new version." << endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for Cisco PIX firewall (with support for FWSM)" << endl; cout << "Copyright 2002-2009 NetCitadel, LLC" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-tvV] [-f filename.xml] [-d destdir] [-o output.fw] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; bool only_print_inspection_code = false; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-I") { only_print_inspection_code = true; continue; } if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_pix *driver = new CompilerDriver_pix(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } if (only_print_inspection_code) { cout << driver->protocolInspectorCommands(); } else driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; delete driver; delete objdb; return ret; } catch(libfwbuilder::FWException &ex) { cerr << ex.toString() << endl; return 1; } catch (std::string s) { cerr << s << endl; return 1; } return 0; } fwbuilder-5.1.0.3599/src/ipt/0000755000175000017500000000000011733011756016361 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/ipt/ipt.pro0000644000175000017500000000124411733011756017700 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) SOURCES = ipt.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32: CONFIG += console INCLUDEPATH += ../iptlib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../iptlib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../iptlib/$$BINARY_SUBDIR/libiptlib.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_ipt fwbuilder-5.1.0.3599/src/ipt/ipt.cpp0000644000175000017500000001177611733011756017675 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include "CompilerDriver_ipt.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for " "Linux 2.4.x and 2.6.x iptables" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-x level] [-v] [-V] [-q] [-f filename.xml] [-d destdir] " "[-D datadir ] [-m] [-4|-6] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); QTime total_time_timer; total_time_timer.start(); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); // register protocols we need IPService::addNamedProtocol(51, "ah"); IPService::addNamedProtocol(112, "vrrp"); try { Resources res(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cerr << " *** Loading data ..."; cerr << flush; objdb->setReadOnly( false ); objdb->load( filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(filename); objdb->reIndex(); cerr << " done\n"; cerr << flush; FWObject *slib = objdb->findInIndex(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_ipt *driver = new CompilerDriver_ipt(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; QTime time_spent = QTime().addMSecs(total_time_timer.elapsed()); cerr << "Compile time: " << time_spent.toString("hh:mm:ss").toStdString() << endl; delete driver; delete objdb; return ret; } catch(const FWException &ex) { cerr << "Error: " << ex.toString() << std::endl; /* Cleanup resources */ delete objdb; return 1; #if __GNUC__ >= 3 /* need to check version because std::ios::failure does not seem to be * supported in gcc 2.9.5 on FreeBSD 4.10 */ } catch (const std::ios::failure &e) { cerr << "Error while opening or writing to the output file" << std::endl; /* Cleanup ressources */ delete objdb; return 1; #endif } catch (const std::string &s) { cerr << s << std::endl; return 1; } catch (const std::exception &ex) { cerr << ex.what() << std::endl; return 1; } catch (...) { cerr << "Unsupported exception" << std::endl; return 1; } } fwbuilder-5.1.0.3599/src/antlr/0000755000175000017500000000000011733011756016705 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/antlr/ParserSharedInputState.hpp0000644000175000017500000000374011733011756024026 0ustar sylvestresylvestre#ifndef INC_ParserSharedInputState_hpp__ #define INC_ParserSharedInputState_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This object contains the data associated with an * input stream of tokens. Multiple parsers * share a single ParserSharedInputState to parse * the same stream of tokens. */ class ANTLR_API ParserInputState { public: /** Construct a new ParserInputState * @param in the TokenBuffer to read from. The object is deleted together * with the ParserInputState object. */ ParserInputState( TokenBuffer* in ) : guessing(0) , filename() , input(in) , inputResponsible(true) { } /** Construct a new ParserInputState * @param in the TokenBuffer to read from. */ ParserInputState( TokenBuffer& in ) : guessing(0) , filename("") , input(&in) , inputResponsible(false) { } virtual ~ParserInputState() { if (inputResponsible) delete input; } TokenBuffer& getInput( void ) { return *input; } /// Reset the ParserInputState and the underlying TokenBuffer void reset( void ) { input->reset(); guessing = 0; } public: /** Are we guessing (guessing>0)? */ int guessing; /** What file (if known) caused the problem? * @todo wrap this one.. */ ANTLR_USE_NAMESPACE(std)string filename; private: /** Where to get token objects */ TokenBuffer* input; /// Do we need to free the TokenBuffer or is it owned by another.. bool inputResponsible; // we don't want these: ParserInputState(const ParserInputState&); ParserInputState& operator=(const ParserInputState&); }; /// A reference counted ParserInputState typedef RefCount ParserSharedInputState; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ParserSharedInputState_hpp__ fwbuilder-5.1.0.3599/src/antlr/config.hpp0000644000175000017500000002054111733011756020665 0ustar sylvestresylvestre#ifndef INC_config_hpp__ #define INC_config_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ /* * Just a simple configuration file to differentiate between the * various compilers used and reconfigure stuff for any oddities of the * compiler in question. * * These are the defaults. Per compiler these are amended. */ #define ANTLR_USE_NAMESPACE(_x_) _x_:: #define ANTLR_USING_NAMESPACE(_x_) using namespace _x_; #define ANTLR_CXX_SUPPORTS_NAMESPACE 1 #define ANTLR_C_USING(_x_) #define ANTLR_API #ifndef CUSTOM_API # define CUSTOM_API #endif #define ANTLR_IOS_BASE ios_base /** define if cctype functions/macros need a std:: prefix. A lot of compilers * define these as macros, in which case something barfs. */ #define ANTLR_CCTYPE_NEEDS_STD /// Define if C++ compiler supports std::uncaught_exception #define ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION #define ANTLR_ATOI_IN_STD /******************************************************************************/ /*{{{ Microsoft Visual C++ */ // NOTE: If you provide patches for a specific MSVC version guard them for // the specific version!!!! // _MSC_VER == 1100 for Microsoft Visual C++ 5.0 // _MSC_VER == 1200 for Microsoft Visual C++ 6.0 // _MSC_VER == 1300 for Microsoft Visual C++ 7.0 #if defined(_MSC_VER) # if _MSC_VER < 1300 # define NOMINMAX # pragma warning(disable : 4786) # define min _cpp_min # endif // This warning really gets on my nerves. // It's the one about symbol longer than 256 chars, and it happens // all the time with STL. # pragma warning( disable : 4786 4231 ) // this shuts up some DLL interface warnings for STL # pragma warning( disable : 4251 ) # ifdef ANTLR_CXX_USE_STLPORT # undef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION # endif # if ( _MSC_VER < 1300 ) && ( defined(ANTLR_EXPORTS) || defined(ANTLR_IMPORTS) ) # error "DLL Build not supported on these MSVC versions." // see comment in lib/cpp/src/dll.cpp # endif // For the DLL support originally contributed by Stephen Naughton // If you are building statically leave ANTLR_EXPORTS/ANTLR_IMPORTS undefined // If you are building the DLL define ANTLR_EXPORTS // If you are compiling code to be used with the DLL define ANTLR_IMPORTS # ifdef ANTLR_EXPORTS # undef ANTLR_API # define ANTLR_API __declspec(dllexport) # endif # ifdef ANTLR_IMPORTS # undef ANTLR_API # define ANTLR_API __declspec(dllimport) # endif # if ( _MSC_VER < 1200 ) // supposedly only for MSVC5 and before... // Using vector requires operator<(X,X) to be defined # define NEEDS_OPERATOR_LESS_THAN # endif // VC6 # if ( _MSC_VER == 1200 ) # undef ANTLR_ATOI_IN_STD # endif # if ( _MSC_VER < 1310 ) // Supposedly only for MSVC7 and before... // Not allowed to put 'static const int XXX=20;' in a class definition # define NO_STATIC_CONSTS # define NO_TEMPLATE_PARTS # endif // No strcasecmp in the C library (so use stricmp instead) // - Anyone know which is in which standard? # define NO_STRCASECMP # undef ANTLR_CCTYPE_NEEDS_STD # define NO_STATIC_CONSTS #endif // End of Microsoft Visual C++ /*}}}*/ /******************************************************************************/ /*{{{ SunPro Compiler (Using OBJECTSPACE STL) *****************************************************************************/ #ifdef __SUNPRO_CC # if (__SUNPRO_CC >= 0x500) # define NEEDS_OPERATOR_LESS_THAN # define NO_TEMPLATE_PARTS # else # undef namespace # define namespace # if (__SUNPRO_CC == 0x420) /* This code is specif to SunWspro Compiler 4.2, and will compile with the objectspace 2.1 toolkit for Solaris2.6 */ # define HAS_NOT_CASSERT_H # define HAS_NOT_CSTRING_H # define HAS_NOT_CCTYPE_H # define HAS_NOT_CSTDIO_H # define HAS_OSTREAM_H /* #define OS_SOLARIS_2_6 #define OS_NO_WSTRING #define OS_NO_ALLOCATORS #define OS_MULTI_THREADED #define OS_SOLARIS_NATIVE #define OS_REALTIME #define __OSVERSION__=5 #define SVR4 */ // ObjectSpace + some specific templates constructions with stl. /* #define OS_NO_ALLOCATOR */ // This great compiler does not have the namespace feature. # undef ANTLR_USE_NAMESPACE # define ANTLR_USE_NAMESPACE(_x_) # undef ANTLR_USING_NAMESPACE # define ANTLR_USING_NAMESPACE(_x_) # undef ANTLR_CXX_SUPPORTS_NAMESPACE # endif // End __SUNPRO_CC == 0x420 # undef explicit # define explicit # define exception os_exception # define bad_exception os_bad_exception // Not allowed to put 'static const int XXX=20;' in a class definition # define NO_STATIC_CONSTS // Using vector requires operator<(X,X) to be defined # define NEEDS_OPERATOR_LESS_THAN # endif # undef ANTLR_CCTYPE_NEEDS_STD #endif // end __SUNPRO_CC /*}}}*/ /*****************************************************************************/ /*{{{ Inprise C++ Builder 3.0 *****************************************************************************/ #ifdef __BCPLUSPLUS__ # define NO_TEMPLATE_PARTS # define NO_STRCASECMP # undef ANTLR_CCTYPE_NEEDS_STD #endif // End of C++ Builder 3.0 /*}}}*/ /*****************************************************************************/ /*{{{ IBM VisualAge C++ ( which includes the Dinkumware C++ Library ) *****************************************************************************/ #ifdef __IBMCPP__ // No strcasecmp in the C library (so use stricmp instead) // - Anyone know which is in which standard? #if (defined(_AIX) && (__IBMCPP__ >= 600)) # define NO_STATIC_CONSTS #else # define NO_STRCASECMP # undef ANTLR_CCTYPE_NEEDS_STD #endif #endif // end IBM VisualAge C++ /*}}}*/ /*****************************************************************************/ /*{{{ Metrowerks Codewarrior *****************************************************************************/ #ifdef __MWERKS__ # if (__MWERKS__ <= 0x2201) # define NO_TEMPLATE_PARTS # endif // CW 6.0 and 7.0 still do not have it. # define ANTLR_REALLY_NO_STRCASECMP # undef ANTLR_C_USING # define ANTLR_C_USING(_x_) using std:: ## _x_; # define ANTLR_CCTYPE_NEEDS_STD # undef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION #endif // End of Metrowerks Codewarrior /*}}}*/ /*****************************************************************************/ /*{{{ SGI Irix 6.5.10 MIPSPro compiler *****************************************************************************/ // (contributed by Anna Winkler) // Note: you can't compile ANTLR with the MIPSPro compiler on // anything < 6.5.10 because SGI just fixed a big bug dealing with // namespaces in that release. #ifdef __sgi # define HAS_NOT_CCTYPE_H # define HAS_NOT_CSTRING_H # define HAS_NOT_CSTDIO_H # undef ANTLR_CCTYPE_NEEDS_STD #endif // End IRIX MIPSPro /*}}}*/ /*****************************************************************************/ /*{{{ G++ in various incarnations *****************************************************************************/ // With the gcc-2.95 and 3.0 being in the near future we should start handling // incompatabilities between the various libstdc++'s. #if defined(__GNUC__) || defined(__GNUG__) // gcc 2 branch.. # if (__GNUC__ == 2 ) # if (__GNUC_MINOR__ <= 8 ) # undef ANTLR_USE_NAMESPACE # define ANTLR_USE_NAMESPACE(_x_) # undef ANTLR_USING_NAMESPACE # define ANTLR_USING_NAMESPACE(_x_) # undef ANTLR_CXX_SUPPORTS_NAMESPACE # endif # if (__GNUC_MINOR__ > 8 && __GNUC_MINOR__ <= 95 ) # undef ANTLR_IOS_BASE # define ANTLR_IOS_BASE ios # undef ANTLR_CCTYPE_NEEDS_STD // compiling with -ansi ? # ifdef __STRICT_ANSI__ # undef ANTLR_REALLY_NO_STRCASECMP # define ANTLR_REALLY_NO_STRCASECMP # endif # else // experimental .96 .97 branches.. # undef ANTLR_CCTYPE_NEEDS_STD # endif # endif #endif // ! __GNUC__ /*}}}*/ /*****************************************************************************/ /*{{{ Digital CXX (Tru64) *****************************************************************************/ #ifdef __DECCXX #define __USE_STD_IOSTREAM #endif /*}}}*/ /*****************************************************************************/ #ifdef __BORLANDC__ # if __BORLANDC__ >= 560 # include # include # define ANTLR_CCTYPE_NEEDS_STD # else # error "sorry, compiler is too old - consider an update." # endif #endif // Redefine these for backwards compatability.. #undef ANTLR_BEGIN_NAMESPACE #undef ANTLR_END_NAMESPACE #if ANTLR_CXX_SUPPORTS_NAMESPACE == 1 # define ANTLR_BEGIN_NAMESPACE(_x_) namespace _x_ { # define ANTLR_END_NAMESPACE } #else # define ANTLR_BEGIN_NAMESPACE(_x_) # define ANTLR_END_NAMESPACE #endif #endif //INC_config_hpp__ fwbuilder-5.1.0.3599/src/antlr/String.hpp0000644000175000017500000000123711733011756020667 0ustar sylvestresylvestre#ifndef INC_String_hpp__ #define INC_String_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif ANTLR_API ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, const int rhs ); ANTLR_API ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, size_t rhs ); ANTLR_API ANTLR_USE_NAMESPACE(std)string charName( int ch ); #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_String_hpp__ fwbuilder-5.1.0.3599/src/antlr/Token.hpp0000644000175000017500000000420111733011756020473 0ustar sylvestresylvestre#ifndef INC_Token_hpp__ #define INC_Token_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif struct TokenRef; /** A token is minimally a token type. Subclasses can add the text matched * for the token and line info. */ class ANTLR_API Token { public: // constants #ifndef NO_STATIC_CONSTS static const int MIN_USER_TYPE = 4; static const int NULL_TREE_LOOKAHEAD = 3; static const int INVALID_TYPE = 0; static const int EOF_TYPE = 1; static const int SKIP = -1; #else enum { MIN_USER_TYPE = 4, NULL_TREE_LOOKAHEAD = 3, INVALID_TYPE = 0, EOF_TYPE = 1, SKIP = -1 }; #endif Token() : ref(0) , type(INVALID_TYPE) { } Token(int t) : ref(0) , type(t) { } Token(int t, const ANTLR_USE_NAMESPACE(std)string& txt) : ref(0) , type(t) { setText(txt); } virtual ~Token() { } virtual int getColumn() const; virtual int getLine() const; virtual ANTLR_USE_NAMESPACE(std)string getText() const; virtual const ANTLR_USE_NAMESPACE(std)string& getFilename() const; virtual int getType() const; virtual void setColumn(int c); virtual void setLine(int l); virtual void setText(const ANTLR_USE_NAMESPACE(std)string& t); virtual void setType(int t); virtual void setFilename( const std::string& file ); virtual ANTLR_USE_NAMESPACE(std)string toString() const; private: friend struct TokenRef; TokenRef* ref; int type; ///< the type of the token Token(RefToken other); Token& operator=(const Token& other); Token& operator=(RefToken other); Token(const Token&); }; extern ANTLR_API RefToken nullToken; #ifdef NEEDS_OPERATOR_LESS_THAN // RK: Added after 2.7.2 previously it was undefined. // AL: what to return if l and/or r point to nullToken??? inline bool operator<( RefToken l, RefToken r ) { return nullToken == l ? ( nullToken == r ? false : true ) : l->getType() < r->getType(); } #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_Token_hpp__ fwbuilder-5.1.0.3599/src/antlr/antlr.pro0000644000175000017500000000430211733011756020546 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib # SOURCES = ANTLRUtil.cpp \ ASTFactory.cpp \ ASTNULLType.cpp \ ASTRefCount.cpp \ BaseAST.cpp \ BitSet.cpp \ CharBuffer.cpp \ CharScanner.cpp \ CommonAST.cpp \ CommonASTWithHiddenTokens.cpp \ CommonHiddenStreamToken.cpp \ CommonToken.cpp \ InputBuffer.cpp \ LLkParser.cpp \ MismatchedCharException.cpp \ MismatchedTokenException.cpp \ NoViableAltException.cpp \ NoViableAltForCharException.cpp \ Parser.cpp \ RecognitionException.cpp \ String.cpp \ TokenBuffer.cpp \ Token.cpp \ TokenRefCount.cpp \ TokenStreamBasicFilter.cpp \ TokenStreamHiddenTokenFilter.cpp \ TokenStreamRewriteEngine.cpp \ TokenStreamSelector.cpp \ TreeParser.cpp # dll.cpp \ HEADERS = ANTLRException.hpp \ ANTLRUtil.hpp \ ASTArray.hpp \ ASTFactory.hpp \ AST.hpp \ ASTNULLType.hpp \ ASTPair.hpp \ ASTRefCount.hpp \ BaseAST.hpp \ BitSet.hpp \ CharBuffer.hpp \ CharInputBuffer.hpp \ CharScanner.hpp \ CharStreamException.hpp \ CharStreamIOException.hpp \ CircularQueue.hpp \ CommonAST.hpp \ CommonASTWithHiddenTokens.hpp \ CommonHiddenStreamToken.hpp \ CommonToken.hpp \ config.hpp \ InputBuffer.hpp \ IOException.hpp \ LexerSharedInputState.hpp \ LLkParser.hpp \ MismatchedCharException.hpp \ MismatchedTokenException.hpp \ NoViableAltException.hpp \ NoViableAltForCharException.hpp \ Parser.hpp \ ParserSharedInputState.hpp \ RecognitionException.hpp \ RefCount.hpp \ SemanticException.hpp \ String.hpp \ TokenBuffer.hpp \ Token.hpp \ TokenRefCount.hpp \ TokenStreamBasicFilter.hpp \ TokenStreamException.hpp \ TokenStreamHiddenTokenFilter.hpp \ TokenStream.hpp \ TokenStreamIOException.hpp \ TokenStreamRecognitionException.hpp \ TokenStreamRetryException.hpp \ TokenStreamRewriteEngine.hpp \ TokenStreamSelector.hpp \ TokenWithIndex.hpp \ TreeParser.hpp \ TreeParserSharedInputState.hpp CONFIG += staticlib INCLUDEPATH += $$ANTLR_INCLUDEPATH DEPENDPATH += $$ANTLR_INCLUDEPATH DEFINES += $$ANTLR_DEFINES TARGET = antlr INSTALLS -= target fwbuilder-5.1.0.3599/src/antlr/IOException.hpp0000644000175000017500000000166111733011756021610 0ustar sylvestresylvestre#ifndef INC_IOException_hpp__ #define INC_IOException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** Generic IOException used inside support code. (thrown by XML I/O routs) * basically this is something I'm using since a lot of compilers don't * support ios_base::failure. */ class ANTLR_API IOException : public ANTLRException { public: ANTLR_USE_NAMESPACE(std)exception io; IOException( ANTLR_USE_NAMESPACE(std)exception& e ) : ANTLRException(e.what()) { } IOException( const ANTLR_USE_NAMESPACE(std)string& mesg ) : ANTLRException(mesg) { } virtual ~IOException() throw() { } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_IOException_hpp__ fwbuilder-5.1.0.3599/src/antlr/CommonAST.hpp0000644000175000017500000000344311733011756021222 0ustar sylvestresylvestre#ifndef INC_CommonAST_hpp__ #define INC_CommonAST_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API CommonAST : public BaseAST { public: CommonAST() : BaseAST() , ttype( Token::INVALID_TYPE ) , text() { } CommonAST( RefToken t ) : BaseAST() , ttype( t->getType() ) , text( t->getText() ) { } CommonAST( const CommonAST& other ) : BaseAST(other) , ttype(other.ttype) , text(other.text) { } virtual ~CommonAST() { } virtual const char* typeName( void ) const { return CommonAST::TYPE_NAME; } /// Clone this AST node. virtual RefAST clone( void ) const { CommonAST *ast = new CommonAST( *this ); return RefAST(ast); } virtual ANTLR_USE_NAMESPACE(std)string getText() const { return text; } virtual int getType() const { return ttype; } virtual void initialize( int t, const ANTLR_USE_NAMESPACE(std)string& txt ) { setType(t); setText(txt); } virtual void initialize( RefAST t ) { setType(t->getType()); setText(t->getText()); } virtual void initialize( RefToken t ) { setType(t->getType()); setText(t->getText()); } #ifdef ANTLR_SUPPORT_XML virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in ); #endif virtual void setText( const ANTLR_USE_NAMESPACE(std)string& txt ) { text = txt; } virtual void setType( int type ) { ttype = type; } static RefAST factory(); static const char* const TYPE_NAME; protected: int ttype; ANTLR_USE_NAMESPACE(std)string text; }; typedef ASTRefCount RefCommonAST; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CommonAST_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamHiddenTokenFilter.cpp0000644000175000017500000001014711733011756025133 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/TokenStreamHiddenTokenFilter.hpp" #include "antlr/CommonHiddenStreamToken.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /**This object filters a token stream coming from a lexer * or another TokenStream so that only certain token channels * get transmitted to the parser. * * Any of the channels can be filtered off as "hidden" channels whose * tokens can be accessed from the parser. */ TokenStreamHiddenTokenFilter::TokenStreamHiddenTokenFilter(TokenStream& input) : TokenStreamBasicFilter(input) { } void TokenStreamHiddenTokenFilter::consume() { nextMonitoredToken = input->nextToken(); } void TokenStreamHiddenTokenFilter::consumeFirst() { consume(); // Handle situation where hidden or discarded tokens // appear first in input stream RefToken p; // while hidden or discarded scarf tokens while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) { if ( hideMask.member(LA(1)->getType()) ) { if ( !p ) { p = LA(1); } else { static_cast(p.get())->setHiddenAfter(LA(1)); static_cast(LA(1).get())->setHiddenBefore(p); // double-link p = LA(1); } lastHiddenToken = p; if (!firstHidden) firstHidden = p; // record hidden token if first } consume(); } } BitSet TokenStreamHiddenTokenFilter::getDiscardMask() const { return discardMask; } /** Return a ptr to the hidden token appearing immediately after * token t in the input stream. */ RefToken TokenStreamHiddenTokenFilter::getHiddenAfter(RefToken t) { return static_cast(t.get())->getHiddenAfter(); } /** Return a ptr to the hidden token appearing immediately before * token t in the input stream. */ RefToken TokenStreamHiddenTokenFilter::getHiddenBefore(RefToken t) { return static_cast(t.get())->getHiddenBefore(); } BitSet TokenStreamHiddenTokenFilter::getHideMask() const { return hideMask; } /** Return the first hidden token if one appears * before any monitored token. */ RefToken TokenStreamHiddenTokenFilter::getInitialHiddenToken() { return firstHidden; } void TokenStreamHiddenTokenFilter::hide(int m) { hideMask.add(m); } void TokenStreamHiddenTokenFilter::hide(const BitSet& mask) { hideMask = mask; } RefToken TokenStreamHiddenTokenFilter::LA(int) { return nextMonitoredToken; } /** Return the next monitored token. * Test the token following the monitored token. * If following is another monitored token, save it * for the next invocation of nextToken (like a single * lookahead token) and return it then. * If following is unmonitored, nondiscarded (hidden) * channel token, add it to the monitored token. * * Note: EOF must be a monitored Token. */ RefToken TokenStreamHiddenTokenFilter::nextToken() { // handle an initial condition; don't want to get lookahead // token of this splitter until first call to nextToken if ( !LA(1) ) { consumeFirst(); } // we always consume hidden tokens after monitored, thus, // upon entry LA(1) is a monitored token. RefToken monitored = LA(1); // point to hidden tokens found during last invocation static_cast(monitored.get())->setHiddenBefore(lastHiddenToken); lastHiddenToken = nullToken; // Look for hidden tokens, hook them into list emanating // from the monitored tokens. consume(); RefToken p = monitored; // while hidden or discarded scarf tokens while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) { if ( hideMask.member(LA(1)->getType()) ) { // attach the hidden token to the monitored in a chain // link forwards static_cast(p.get())->setHiddenAfter(LA(1)); // link backwards if (p != monitored) { //hidden cannot point to monitored tokens static_cast(LA(1).get())->setHiddenBefore(p); } p = lastHiddenToken = LA(1); } consume(); } return monitored; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CharScanner.cpp0000644000175000017500000000564511733011756021612 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include "antlr/CharScanner.hpp" #include "antlr/CommonToken.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif ANTLR_C_USING(exit) CharScanner::CharScanner(InputBuffer& cb, bool case_sensitive ) : saveConsumedInput(true) //, caseSensitiveLiterals(true) , caseSensitive(case_sensitive) , literals(CharScannerLiteralsLess(this)) , inputState(new LexerInputState(cb)) , commitToPath(false) , tabsize(8) , traceDepth(0) { setTokenObjectFactory(&CommonToken::factory); } CharScanner::CharScanner(InputBuffer* cb, bool case_sensitive ) : saveConsumedInput(true) //, caseSensitiveLiterals(true) , caseSensitive(case_sensitive) , literals(CharScannerLiteralsLess(this)) , inputState(new LexerInputState(cb)) , commitToPath(false) , tabsize(8) , traceDepth(0) { setTokenObjectFactory(&CommonToken::factory); } CharScanner::CharScanner( const LexerSharedInputState& state, bool case_sensitive ) : saveConsumedInput(true) //, caseSensitiveLiterals(true) , caseSensitive(case_sensitive) , literals(CharScannerLiteralsLess(this)) , inputState(state) , commitToPath(false) , tabsize(8) , traceDepth(0) { setTokenObjectFactory(&CommonToken::factory); } /** Report exception errors caught in nextToken() */ void CharScanner::reportError(const RecognitionException& ex) { ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Parser error-reporting function can be overridden in subclass */ void CharScanner::reportError(const ANTLR_USE_NAMESPACE(std)string& s) { if (getFilename() == "") ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; else ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Parser warning-reporting function can be overridden in subclass */ void CharScanner::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { if (getFilename() == "") ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; else ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; } void CharScanner::traceIndent() { for( int i = 0; i < traceDepth; i++ ) ANTLR_USE_NAMESPACE(std)cout << " "; } void CharScanner::traceIn(const char* rname) { traceDepth++; traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "> lexer " << rname << "; c==" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; } void CharScanner::traceOut(const char* rname) { traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "< lexer " << rname << "; c==" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; traceDepth--; } #ifndef NO_STATIC_CONSTS const int CharScanner::NO_CHAR; const int CharScanner::EOF_CHAR; #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/String.cpp0000644000175000017500000000312011733011756020653 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/String.hpp" #include #ifdef HAS_NOT_CSTDIO_H #include #else #include #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif // wh: hack for Borland C++ 5.6 #if __BORLANDC__ using std::snprintf; #endif // RK: should be using snprintf actually... (or stringstream) ANTLR_C_USING(snprintf) ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, const int rhs ) { char tmp[100]; snprintf(tmp, sizeof(tmp), "%d", rhs); return lhs+tmp; } ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, size_t rhs ) { char tmp[100]; snprintf(tmp, sizeof(tmp), "%zu", rhs); // sprintf(tmp,"%u",rhs); return lhs+tmp; } /** Convert character to readable string */ ANTLR_USE_NAMESPACE(std)string charName(int ch) { if (ch == EOF) return "EOF"; else { ANTLR_USE_NAMESPACE(std)string s; // when you think you've seen it all.. an isprint that crashes... ch = ch & 0xFF; #ifdef ANTLR_CCTYPE_NEEDS_STD if( ANTLR_USE_NAMESPACE(std)isprint( ch ) ) #else if( isprint( ch ) ) #endif { s.append("'"); s += ch; s.append("'"); // s += "'"+ch+"'"; } else { s += "0x"; unsigned int t = ch >> 4; if( t < 10 ) s += t | 0x30; else s += t + 0x37; t = ch & 0xF; if( t < 10 ) s += t | 0x30; else s += t + 0x37; } return s; } } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/InputBuffer.hpp0000644000175000017500000000655011733011756021655 0ustar sylvestresylvestre#ifndef INC_InputBuffer_hpp__ #define INC_InputBuffer_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** A Stream of characters fed to the lexer from a InputStream that can * be rewound via mark()/rewind() methods. *

* A dynamic array is used to buffer up all the input characters. Normally, * "k" characters are stored in the buffer. More characters may be stored during * guess mode (testing syntactic predicate), or when LT(i>k) is referenced. * Consumption of characters is deferred. In other words, reading the next * character is not done by conume(), but deferred until needed by LA or LT. *

* * @see antlr.CharQueue */ class ANTLR_API InputBuffer { public: /** Create a character buffer */ InputBuffer() : nMarkers(0) , markerOffset(0) , numToConsume(0) { } virtual ~InputBuffer() { } /// Reset the input buffer to empty state virtual inline void reset( void ) { nMarkers = 0; markerOffset = 0; numToConsume = 0; queue.clear(); } /** This method updates the state of the input buffer so that * the text matched since the most recent mark() is no longer * held by the buffer. So, you either do a mark/rewind for * failed predicate or mark/commit to keep on parsing without * rewinding the input. */ inline void commit( void ) { nMarkers--; } /** Mark another character for deferred consumption */ virtual inline void consume() { numToConsume++; } /** Ensure that the character buffer is sufficiently full */ virtual void fill(unsigned int amount); /** Override this in subclasses to get the next character */ virtual int getChar()=0; /** Get a lookahead character */ virtual inline int LA(unsigned int i) { fill(i); return queue.elementAt(markerOffset + i - 1); } /** Return an integer marker that can be used to rewind the buffer to * its current state. */ virtual unsigned int mark(); /// Are there any marks active in the InputBuffer virtual inline bool isMarked() const { return (nMarkers != 0); } /** Rewind the character buffer to a marker. * @param mark Marker returned previously from mark() */ virtual void rewind(unsigned int mark); /** Get the number of non-consumed characters */ virtual unsigned int entries() const; ANTLR_USE_NAMESPACE(std)string getLAChars() const; ANTLR_USE_NAMESPACE(std)string getMarkedChars() const; protected: // char source // leave to subclasses // Number of active markers unsigned int nMarkers; // = 0; // Additional offset used when markers are active unsigned int markerOffset; // = 0; // Number of calls to consume() since last LA() or LT() call unsigned int numToConsume; // = 0; // Circular queue CircularQueue queue; /** Sync up deferred consumption */ void syncConsume(); private: InputBuffer(const InputBuffer& other); InputBuffer& operator=(const InputBuffer& other); }; /** Sync up deferred consumption */ inline void InputBuffer::syncConsume() { if (numToConsume > 0) { if (nMarkers > 0) markerOffset += numToConsume; else queue.removeItems( numToConsume ); numToConsume = 0; } } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_InputBuffer_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamRewriteEngine.hpp0000644000175000017500000003045411733011756024350 0ustar sylvestresylvestre#ifndef INC_TokenStreamRewriteEngine_hpp__ #define INC_TokenStreamRewriteEngine_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This token stream tracks the *entire* token stream coming from * a lexer, but does not pass on the whitespace (or whatever else * you want to discard) to the parser. * * This class can then be asked for the ith token in the input stream. * Useful for dumping out the input stream exactly after doing some * augmentation or other manipulations. Tokens are index from 0..n-1 * * You can insert stuff, replace, and delete chunks. Note that the * operations are done lazily--only if you convert the buffer to a * String. This is very efficient because you are not moving data around * all the time. As the buffer of tokens is converted to strings, the * toString() method(s) check to see if there is an operation at the * current index. If so, the operation is done and then normal String * rendering continues on the buffer. This is like having multiple Turing * machine instruction streams (programs) operating on a single input tape. :) * * Since the operations are done lazily at toString-time, operations do not * screw up the token index values. That is, an insert operation at token * index i does not change the index values for tokens i+1..n-1. * * Because operations never actually alter the buffer, you may always get * the original token stream back without undoing anything. Since * the instructions are queued up, you can easily simulate transactions and * roll back any changes if there is an error just by removing instructions. * For example, * * TokenStreamRewriteEngine rewriteEngine = * new TokenStreamRewriteEngine(lexer); * JavaRecognizer parser = new JavaRecognizer(rewriteEngine); * ... * rewriteEngine.insertAfter("pass1", t, "foobar");} * rewriteEngine.insertAfter("pass2", u, "start");} * System.out.println(rewriteEngine.toString("pass1")); * System.out.println(rewriteEngine.toString("pass2")); * * You can also have multiple "instruction streams" and get multiple * rewrites from a single pass over the input. Just name the instruction * streams and use that name again when printing the buffer. This could be * useful for generating a C file and also its header file--all from the * same buffer. * * If you don't use named rewrite streams, a "default" stream is used. * * Terence Parr, parrt@cs.usfca.edu * University of San Francisco * February 2004 */ class TokenStreamRewriteEngine : public TokenStream { public: typedef ANTLR_USE_NAMESPACE(std)vector token_list; static const char* DEFAULT_PROGRAM_NAME; #ifndef NO_STATIC_CONSTS static const size_t MIN_TOKEN_INDEX; static const int PROGRAM_INIT_SIZE; #else enum { MIN_TOKEN_INDEX = 0, PROGRAM_INIT_SIZE = 100 }; #endif struct tokenToStream { tokenToStream( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {} template void operator() ( const T& t ) { out << t->getText(); } ANTLR_USE_NAMESPACE(std)ostream& out; }; class RewriteOperation { protected: RewriteOperation( size_t idx, const ANTLR_USE_NAMESPACE(std)string& txt ) : index(idx), text(txt) { } public: virtual ~RewriteOperation() { } /** Execute the rewrite operation by possibly adding to the buffer. * Return the index of the next token to operate on. */ virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& /* out */ ) { return index; } virtual size_t getIndex() const { return index; } virtual const char* type() const { return "RewriteOperation"; } protected: size_t index; ANTLR_USE_NAMESPACE(std)string text; }; struct executeOperation { ANTLR_USE_NAMESPACE(std)ostream& out; executeOperation( ANTLR_USE_NAMESPACE(std)ostream& s ) : out(s) {} void operator () ( RewriteOperation* t ) { t->execute(out); } }; /// list of rewrite operations typedef ANTLR_USE_NAMESPACE(std)list operation_list; /// map program name to tuple typedef ANTLR_USE_NAMESPACE(std)map program_map; class InsertBeforeOp : public RewriteOperation { public: InsertBeforeOp( size_t index, const ANTLR_USE_NAMESPACE(std)string& text ) : RewriteOperation(index, text) { } virtual ~InsertBeforeOp() {} virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) { out << text; return index; } virtual const char* type() const { return "InsertBeforeOp"; } }; class ReplaceOp : public RewriteOperation { public: ReplaceOp(size_t from, size_t to, ANTLR_USE_NAMESPACE(std)string text) : RewriteOperation(from,text) , lastIndex(to) { } virtual ~ReplaceOp() {} virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) { out << text; return lastIndex+1; } virtual const char* type() const { return "ReplaceOp"; } protected: size_t lastIndex; }; class DeleteOp : public ReplaceOp { public: DeleteOp(size_t from, size_t to) : ReplaceOp(from,to,"") { } virtual const char* type() const { return "DeleteOp"; } }; TokenStreamRewriteEngine(TokenStream& upstream); TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize); RefToken nextToken( void ); void rollback(size_t instructionIndex) { rollback(DEFAULT_PROGRAM_NAME, instructionIndex); } /** Rollback the instruction stream for a program so that * the indicated instruction (via instructionIndex) is no * longer in the stream. UNTESTED! */ void rollback(const ANTLR_USE_NAMESPACE(std)string& programName, size_t instructionIndex ); void deleteProgram() { deleteProgram(DEFAULT_PROGRAM_NAME); } /** Reset the program so that no instructions exist */ void deleteProgram(const ANTLR_USE_NAMESPACE(std)string& programName) { rollback(programName, MIN_TOKEN_INDEX); } void insertAfter( RefTokenWithIndex t, const ANTLR_USE_NAMESPACE(std)string& text ) { insertAfter(DEFAULT_PROGRAM_NAME, t, text); } void insertAfter(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { insertAfter(DEFAULT_PROGRAM_NAME, index, text); } void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, RefTokenWithIndex t, const ANTLR_USE_NAMESPACE(std)string& text ) { insertAfter(programName, t->getIndex(), text); } void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, size_t index, const ANTLR_USE_NAMESPACE(std)string& text ) { // to insert after, just insert before next index (even if past end) insertBefore(programName,index+1, text); } void insertBefore( RefTokenWithIndex t, const ANTLR_USE_NAMESPACE(std)string& text ) { // std::cout << "insertBefore index " << t->getIndex() << " " << text << std::endl; insertBefore(DEFAULT_PROGRAM_NAME, t, text); } void insertBefore(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { insertBefore(DEFAULT_PROGRAM_NAME, index, text); } void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName, RefTokenWithIndex t, const ANTLR_USE_NAMESPACE(std)string& text ) { insertBefore(programName, t->getIndex(), text); } void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName, size_t index, const ANTLR_USE_NAMESPACE(std)string& text ) { addToSortedRewriteList(programName, new InsertBeforeOp(index,text)); } void replace(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { replace(DEFAULT_PROGRAM_NAME, index, index, text); } void replace( size_t from, size_t to, const ANTLR_USE_NAMESPACE(std)string& text) { replace(DEFAULT_PROGRAM_NAME, from, to, text); } void replace( RefTokenWithIndex indexT, const ANTLR_USE_NAMESPACE(std)string& text ) { replace(DEFAULT_PROGRAM_NAME, indexT->getIndex(), indexT->getIndex(), text); } void replace( RefTokenWithIndex from, RefTokenWithIndex to, const ANTLR_USE_NAMESPACE(std)string& text ) { replace(DEFAULT_PROGRAM_NAME, from, to, text); } void replace(const ANTLR_USE_NAMESPACE(std)string& programName, size_t from, size_t to, const ANTLR_USE_NAMESPACE(std)string& text ) { addToSortedRewriteList(programName,new ReplaceOp(from, to, text)); } void replace( const ANTLR_USE_NAMESPACE(std)string& programName, RefTokenWithIndex from, RefTokenWithIndex to, const ANTLR_USE_NAMESPACE(std)string& text ) { replace(programName, from->getIndex(), to->getIndex(), text); } void remove(size_t index) { remove(DEFAULT_PROGRAM_NAME, index, index); } void remove(size_t from, size_t to) { remove(DEFAULT_PROGRAM_NAME, from, to); } void remove(RefTokenWithIndex indexT) { remove(DEFAULT_PROGRAM_NAME, indexT, indexT); } void remove(RefTokenWithIndex from, RefTokenWithIndex to) { remove(DEFAULT_PROGRAM_NAME, from, to); } void remove( const ANTLR_USE_NAMESPACE(std)string& programName, size_t from, size_t to) { replace(programName,from,to,""); } void remove( const ANTLR_USE_NAMESPACE(std)string& programName, RefTokenWithIndex from, RefTokenWithIndex to ) { replace(programName,from,to,""); } void discard(int ttype) { discardMask.add(ttype); } RefToken getToken( size_t i ) { return RefToken(tokens.at(i)); } size_t getTokenStreamSize() const { return tokens.size(); } void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { ANTLR_USE_NAMESPACE(std)for_each( tokens.begin(), tokens.end(), tokenToStream(out) ); } void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out, size_t start, size_t end ) const; void toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { toStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); } void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, const ANTLR_USE_NAMESPACE(std)string& programName ) const { toStream( out, programName, MIN_TOKEN_INDEX, getTokenStreamSize()); } void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, size_t start, size_t end ) const { toStream(out, DEFAULT_PROGRAM_NAME, start, end); } void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, const ANTLR_USE_NAMESPACE(std)string& programName, size_t firstToken, size_t lastToken ) const; void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { toDebugStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); } void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out, size_t start, size_t end ) const; size_t getLastRewriteTokenIndex() const { return getLastRewriteTokenIndex(DEFAULT_PROGRAM_NAME); } /** Return the last index for the program named programName * return 0 if the program does not exist or the program is empty. * (Note this is different from the java implementation that returns -1) */ size_t getLastRewriteTokenIndex(const ANTLR_USE_NAMESPACE(std)string& programName) const { program_map::const_iterator rewrites = programs.find(programName); if( rewrites == programs.end() ) return 0; const operation_list& prog = rewrites->second; if( !prog.empty() ) { operation_list::const_iterator last = prog.end(); --last; return (*last)->getIndex(); } return 0; } protected: /** If op.index > lastRewriteTokenIndexes, just add to the end. * Otherwise, do linear */ void addToSortedRewriteList(RewriteOperation* op) { addToSortedRewriteList(DEFAULT_PROGRAM_NAME, op); } void addToSortedRewriteList( const ANTLR_USE_NAMESPACE(std)string& programName, RewriteOperation* op ); protected: /** Who do we suck tokens from? */ TokenStream& stream; /** track index of tokens */ size_t index; /** Track the incoming list of tokens */ token_list tokens; /** You may have multiple, named streams of rewrite operations. * I'm calling these things "programs." * Maps String (name) -> rewrite (List) */ program_map programs; /** Which (whitespace) token(s) to throw out */ BitSet discardMask; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif fwbuilder-5.1.0.3599/src/antlr/TokenBuffer.hpp0000644000175000017500000000540211733011756021631 0ustar sylvestresylvestre#ifndef INC_TokenBuffer_hpp__ #define INC_TokenBuffer_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /**A Stream of Token objects fed to the parser from a TokenStream that can * be rewound via mark()/rewind() methods. *

* A dynamic array is used to buffer up all the input tokens. Normally, * "k" tokens are stored in the buffer. More tokens may be stored during * guess mode (testing syntactic predicate), or when LT(i>k) is referenced. * Consumption of tokens is deferred. In other words, reading the next * token is not done by conume(), but deferred until needed by LA or LT. *

* * @todo: see if we can integrate this one with InputBuffer into one template * or so. * * @see antlr.Token * @see antlr.TokenStream * @see antlr.TokenQueue */ class ANTLR_API TokenBuffer { public: /** Create a token buffer */ TokenBuffer(TokenStream& input_); virtual ~TokenBuffer(); /// Reset the input buffer to empty state inline void reset( void ) { nMarkers = 0; markerOffset = 0; numToConsume = 0; queue.clear(); } /** Get a lookahead token value */ int LA( unsigned int i ); /** Get a lookahead token */ RefToken LT( unsigned int i ); /** Return an integer marker that can be used to rewind the buffer to * its current state. */ unsigned int mark(); /**Rewind the token buffer to a marker. * @param mark Marker returned previously from mark() */ void rewind(unsigned int mark); /** Mark another token for deferred consumption */ inline void consume() { numToConsume++; } /// Return the number of entries in the TokenBuffer virtual unsigned int entries() const; private: /** Ensure that the token buffer is sufficiently full */ void fill(unsigned int amount); /** Sync up deferred consumption */ void syncConsume(); protected: /// Token source TokenStream& input; /// Number of active markers unsigned int nMarkers; /// Additional offset used when markers are active unsigned int markerOffset; /// Number of calls to consume() since last LA() or LT() call unsigned int numToConsume; /// Circular queue with Tokens CircularQueue queue; private: TokenBuffer(const TokenBuffer& other); const TokenBuffer& operator=(const TokenBuffer& other); }; /** Sync up deferred consumption */ inline void TokenBuffer::syncConsume() { if (numToConsume > 0) { if (nMarkers > 0) markerOffset += numToConsume; else queue.removeItems( numToConsume ); numToConsume = 0; } } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenBuffer_hpp__ fwbuilder-5.1.0.3599/src/antlr/ASTNULLType.cpp0000644000175000017500000000421511733011756021377 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/config.hpp" #include "antlr/AST.hpp" #include "antlr/ASTNULLType.hpp" #include ANTLR_USING_NAMESPACE(std) #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif RefAST ASTNULLType::clone( void ) const { return RefAST(this); } void ASTNULLType::addChild( RefAST ) { } size_t ASTNULLType::getNumberOfChildren() const { return 0; } bool ASTNULLType::equals( RefAST ) const { return false; } bool ASTNULLType::equalsList( RefAST ) const { return false; } bool ASTNULLType::equalsListPartial( RefAST ) const { return false; } bool ASTNULLType::equalsTree( RefAST ) const { return false; } bool ASTNULLType::equalsTreePartial( RefAST ) const { return false; } vector ASTNULLType::findAll( RefAST ) { return vector(); } vector ASTNULLType::findAllPartial( RefAST ) { return vector(); } RefAST ASTNULLType::getFirstChild() const { return this; } RefAST ASTNULLType::getNextSibling() const { return this; } string ASTNULLType::getText() const { return ""; } int ASTNULLType::getType() const { return Token::NULL_TREE_LOOKAHEAD; } void ASTNULLType::initialize( int, const string& ) { } void ASTNULLType::initialize( RefAST ) { } void ASTNULLType::initialize( RefToken ) { } #ifdef ANTLR_SUPPORT_XML void ASTNULLType::initialize( istream& ) { } #endif void ASTNULLType::setFirstChild( RefAST ) { } void ASTNULLType::setNextSibling( RefAST ) { } void ASTNULLType::setText( const string& ) { } void ASTNULLType::setType( int ) { } string ASTNULLType::toString() const { return getText(); } string ASTNULLType::toStringList() const { return getText(); } string ASTNULLType::toStringTree() const { return getText(); } #ifdef ANTLR_SUPPORT_XML bool ASTNULLType::attributesToStream( ostream& ) const { return false; } void ASTNULLType::toStream( ostream& out ) const { out << "" << endl; } #endif const char* ASTNULLType::typeName( void ) const { return "ASTNULLType"; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CommonToken.hpp0000644000175000017500000000312611733011756021651 0ustar sylvestresylvestre#ifndef INC_CommonToken_hpp__ #define INC_CommonToken_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API CommonToken : public Token { public: CommonToken(); CommonToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt); CommonToken(const ANTLR_USE_NAMESPACE(std)string& s); /// return contents of token virtual ANTLR_USE_NAMESPACE(std)string getText() const { return text; } /// set contents of token virtual void setText(const ANTLR_USE_NAMESPACE(std)string& s) { text = s; } /** get the line the token is at (starting at 1) * @see CharScanner::newline() * @see CharScanner::tab() */ virtual int getLine() const { return line; } /** gt the column the token is at (starting at 1) * @see CharScanner::newline() * @see CharScanner::tab() */ virtual int getColumn() const { return col; } /// set line for token virtual void setLine(int l) { line = l; } /// set column for token virtual void setColumn(int c) { col = c; } virtual ANTLR_USE_NAMESPACE(std)string toString() const; static RefToken factory(); protected: // most tokens will want line and text information int line; int col; ANTLR_USE_NAMESPACE(std)string text; private: CommonToken(const CommonToken&); const CommonToken& operator=(const CommonToken&); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CommonToken_hpp__ fwbuilder-5.1.0.3599/src/antlr/ASTPair.hpp0000644000175000017500000000276411733011756020672 0ustar sylvestresylvestre#ifndef INC_ASTPair_hpp__ #define INC_ASTPair_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** ASTPair: utility class used for manipulating a pair of ASTs * representing the current AST root and current AST sibling. * This exists to compensate for the lack of pointers or 'var' * arguments in Java. * * OK, so we can do those things in C++, but it seems easier * to stick with the Java way for now. */ class ANTLR_API ASTPair { public: RefAST root; // current root of tree RefAST child; // current child to which siblings are added /** Make sure that child is the last sibling */ void advanceChildToEnd() { if (child) { while (child->getNextSibling()) { child = child->getNextSibling(); } } } // /** Copy an ASTPair. Don't call it clone() because we want type-safety */ // ASTPair copy() { // ASTPair tmp = new ASTPair(); // tmp.root = root; // tmp.child = child; // return tmp; // } ANTLR_USE_NAMESPACE(std)string toString() const { ANTLR_USE_NAMESPACE(std)string r = !root ? ANTLR_USE_NAMESPACE(std)string("null") : root->getText(); ANTLR_USE_NAMESPACE(std)string c = !child ? ANTLR_USE_NAMESPACE(std)string("null") : child->getText(); return "["+r+","+c+"]"; } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ASTPair_hpp__ fwbuilder-5.1.0.3599/src/antlr/ASTRefCount.cpp0000644000175000017500000000116111733011756021505 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/ASTRefCount.hpp" #include "antlr/AST.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif ASTRef::ASTRef(AST* p) : ptr(p), count(1) { if (p && !p->ref) p->ref = this; } ASTRef::~ASTRef() { delete ptr; } ASTRef* ASTRef::getRef(const AST* p) { if (p) { AST* pp = const_cast(p); if (pp->ref) return pp->ref->increment(); else return new ASTRef(pp); } else return 0; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/dll.cpp0000644000175000017500000002370411733011756020172 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ /* * DLL stub for MSVC++. Based upon versions of Stephen Naughton and Michael * T. Richter */ // RK: Uncommented by instruction of Alexander Lenski //#if _MSC_VER > 1000 //# pragma once //#endif // _MSC_VER > 1000 // Exclude rarely-used stuff from Windows headers #define WIN32_LEAN_AND_MEAN #include #if defined( _MSC_VER ) && ( _MSC_VER < 1300 ) # error "DLL Build not supported on old MSVC's" // Ok it seems to be possible with STLPort in stead of the vanilla MSVC STL // implementation. This needs some work though. (and don't try it if you're // not that familiar with compilers/building C++ DLL's in windows) #endif #include #include "antlr/config.hpp" #include "antlr/Token.hpp" #include "antlr/CircularQueue.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif // Take care of necessary implicit instantiations of templates from STL // This should take care of MSVC 7.0 #if defined( _MSC_VER ) && ( _MSC_VER == 1300 ) // these come from AST.hpp template class ANTLR_API ASTRefCount< AST >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< RefAST >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< RefAST >; //template ANTLR_API int operator<( ASTRefCount< AST >, ASTRefCount< AST > ); // ASTFactory.hpp template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< factory_descriptor_* >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ > >; template struct ANTLR_API ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< factory_descriptor_*, ANTLR_USE_NAMESPACE(std)allocator< factory_descriptor_* > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< factory_descriptor_* >; // BitSet.hpp template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< bool >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< bool, ANTLR_USE_NAMESPACE(std)allocator< bool > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< bool >; // CharScanner.hpp template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, int > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >, false > >::_Node >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >, false > >::_Nodeptr >; template struct ANTLR_API ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, int >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_val< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, int > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)map< ANTLR_USE_NAMESPACE(std)string, int, CharScannerLiteralsLess >; // CircularQueue.hpp // RK: it might well be that a load of these ints need to be unsigned ints // (made some more stuff unsigned) template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< int >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< int, ANTLR_USE_NAMESPACE(std)allocator< int > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< int >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< int, ANTLR_USE_NAMESPACE(std)allocator< int > >; // template ANTLR_API inline int CircularQueue< int >::entries() const; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< RefToken >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Vector_val< RefToken, ANTLR_USE_NAMESPACE(std)allocator< RefToken > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< RefToken >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)vector< RefToken, ANTLR_USE_NAMESPACE(std)allocator< RefToken > >; // template ANTLR_API inline int CircularQueue< RefToken >::entries() const; // CommonAST.hpp template class ANTLR_API ASTRefCount< CommonAST >; // CommonASTWithHiddenTokenTypes.hpp template class ANTLR_API ASTRefCount< CommonASTWithHiddenTokens >; // LexerSharedInputState.hpp template class ANTLR_API RefCount< LexerInputState >; // ParserSharedInputState.hpp template class ANTLR_API RefCount< ParserInputState >; // TokenStreamSelector.hpp template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, TokenStream* > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >, false > >::_Node >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >, false > >::_Nodeptr >; template struct ANTLR_API ANTLR_USE_NAMESPACE(std)pair< ANTLR_USE_NAMESPACE(std)string, TokenStream* >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_nod< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_ptr< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree_val< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Tree< ANTLR_USE_NAMESPACE(std)_Tmap_traits< ANTLR_USE_NAMESPACE(std)string, TokenStream*, ANTLR_USE_NAMESPACE(std)less< ANTLR_USE_NAMESPACE(std)string >, ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)pair< const ANTLR_USE_NAMESPACE(std)string, TokenStream* > >,false > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)map< ANTLR_USE_NAMESPACE(std)string, TokenStream* >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< TokenStream* >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)allocator< ANTLR_USE_NAMESPACE(std)_Deque_map< TokenStream* , ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >::_Tptr >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Deque_map< TokenStream*, ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)_Deque_val< TokenStream*, ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)deque< TokenStream*, ANTLR_USE_NAMESPACE(std)allocator< TokenStream* > >; template class ANTLR_API ANTLR_USE_NAMESPACE(std)stack< TokenStream*, ANTLR_USE_NAMESPACE(std)deque >; #elif defined( _MSC_VER ) && ( _MSC_VER == 1310 ) // Instantiations for MSVC 7.1 template class ANTLR_API CircularQueue< int >; template class ANTLR_API CircularQueue< RefToken >; // #else future msvc's #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } fwbuilder-5.1.0.3599/src/antlr/ASTFactory.cpp0000644000175000017500000002777311733011756021410 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/CommonAST.hpp" #include "antlr/ANTLRException.hpp" #include "antlr/IOException.hpp" #include "antlr/ASTFactory.hpp" #include "antlr/ANTLRUtil.hpp" #include #include using namespace std; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** AST Support code shared by TreeParser and Parser. * We use delegation to share code (and have only one * bit of code to maintain) rather than subclassing * or superclassing (forces AST support code to be * loaded even when you don't want to do AST stuff). * * This class collects all factories of AST types used inside the code. * New AST node types are registered with the registerFactory method. * On creation of an ASTFactory object a default AST node factory may be * specified. * * When registering types gaps between different types are filled with entries * for the default factory. */ /// Initialize factory ASTFactory::ASTFactory() : default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(CommonAST::TYPE_NAME,&CommonAST::factory)) { nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor ); } /** Initialize factory with a non default node type. * factory_node_name should be the name of the AST node type the factory * generates. (should exist during the existance of this ASTFactory instance) */ ASTFactory::ASTFactory( const char* factory_node_name, factory_type fact ) : default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(factory_node_name, fact)) { nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor ); } /// Delete ASTFactory ASTFactory::~ASTFactory() { factory_descriptor_list::iterator i = nodeFactories.begin(); while( i != nodeFactories.end() ) { if( *i != &default_factory_descriptor ) delete *i; i++; } } /// Register a factory for a given AST type void ASTFactory::registerFactory( int type, const char* ast_name, factory_type factory ) { // check validity of arguments... if( type < Token::MIN_USER_TYPE ) throw ANTLRException("Internal parser error invalid type passed to RegisterFactory"); if( factory == 0 ) throw ANTLRException("Internal parser error 0 factory passed to RegisterFactory"); // resize up to and including 'type' and initalize any gaps to default // factory. if( nodeFactories.size() < (static_cast(type)+1) ) nodeFactories.resize( type+1, &default_factory_descriptor ); // And add new thing.. nodeFactories[type] = new ANTLR_USE_NAMESPACE(std)pair( ast_name, factory ); } void ASTFactory::setMaxNodeType( int type ) { if( nodeFactories.size() < (static_cast(type)+1) ) nodeFactories.resize( type+1, &default_factory_descriptor ); } /** Create a new empty AST node; if the user did not specify * an AST node type, then create a default one: CommonAST. */ RefAST ASTFactory::create() { RefAST node = nodeFactories[0]->second(); node->setType(Token::INVALID_TYPE); return node; } RefAST ASTFactory::create(int type) { RefAST t = nodeFactories[type]->second(); t->initialize(type,""); return t; } RefAST ASTFactory::create(int type, const ANTLR_USE_NAMESPACE(std)string& txt) { RefAST t = nodeFactories[type]->second(); t->initialize(type,txt); return t; } #ifdef ANTLR_SUPPORT_XML RefAST ASTFactory::create(const ANTLR_USE_NAMESPACE(std)string& type_name, ANTLR_USE_NAMESPACE(std)istream& infile ) { factory_descriptor_list::iterator fact = nodeFactories.begin(); while( fact != nodeFactories.end() ) { if( type_name == (*fact)->first ) { RefAST t = (*fact)->second(); t->initialize(infile); return t; } fact++; } string error = "ASTFactory::create: Unknown AST type '" + type_name + "'"; throw ANTLRException(error); } #endif /** Create a new empty AST node; if the user did not specify * an AST node type, then create a default one: CommonAST. */ RefAST ASTFactory::create(RefAST tr) { if (!tr) return nullAST; // cout << "create(tr)" << endl; RefAST t = nodeFactories[tr->getType()]->second(); t->initialize(tr); return t; } RefAST ASTFactory::create(RefToken tok) { // cout << "create( tok="<< tok->getType() << ", " << tok->getText() << ")" << nodeFactories.size() << endl; RefAST t = nodeFactories[tok->getType()]->second(); t->initialize(tok); return t; } /** Add a child to the current AST */ void ASTFactory::addASTChild(ASTPair& currentAST, RefAST child) { if (child) { if (!currentAST.root) { // Make new child the current root currentAST.root = child; } else { if (!currentAST.child) { // Add new child to current root currentAST.root->setFirstChild(child); } else { currentAST.child->setNextSibling(child); } } // Make new child the current child currentAST.child = child; currentAST.advanceChildToEnd(); } } /** Deep copy a single node. This function the new clone() methods in the AST * interface. Returns nullAST if t is null. */ RefAST ASTFactory::dup(RefAST t) { if( t ) return t->clone(); else return RefAST(nullASTptr); } /** Duplicate tree including siblings of root. */ RefAST ASTFactory::dupList(RefAST t) { RefAST result = dupTree(t); // if t == null, then result==null RefAST nt = result; while( t ) { // for each sibling of the root t = t->getNextSibling(); nt->setNextSibling(dupTree(t)); // dup each subtree, building new tree nt = nt->getNextSibling(); } return result; } /** Duplicate a tree, assuming this is a root node of a tree * duplicate that node and what's below; ignore siblings of root node. */ RefAST ASTFactory::dupTree(RefAST t) { RefAST result = dup(t); // make copy of root // copy all children of root. if( t ) result->setFirstChild( dupList(t->getFirstChild()) ); return result; } /** Make a tree from a list of nodes. The first element in the * array is the root. If the root is null, then the tree is * a simple list not a tree. Handles null children nodes correctly. * For example, make(a, b, null, c) yields tree (a b c). make(null,a,b) * yields tree (nil a b). */ RefAST ASTFactory::make(ANTLR_USE_NAMESPACE(std)vector& nodes) { if ( nodes.size() == 0 ) return RefAST(nullASTptr); RefAST root = nodes[0]; RefAST tail = RefAST(nullASTptr); if( root ) root->setFirstChild(RefAST(nullASTptr)); // don't leave any old pointers set // link in children; for( unsigned int i = 1; i < nodes.size(); i++ ) { if ( nodes[i] == 0 ) // ignore null nodes continue; if ( root == 0 ) // Set the root and set it up for a flat list root = tail = nodes[i]; else if ( tail == 0 ) { root->setFirstChild(nodes[i]); tail = root->getFirstChild(); } else { tail->setNextSibling(nodes[i]); tail = tail->getNextSibling(); } if( tail ) // RK: I cannot fathom why this missing check didn't bite anyone else... { // Chase tail to last sibling while (tail->getNextSibling()) tail = tail->getNextSibling(); } } return root; } /** Make a tree from a list of nodes, where the nodes are contained * in an ASTArray object */ RefAST ASTFactory::make(ASTArray* nodes) { RefAST ret = make(nodes->array); delete nodes; return ret; } /// Make an AST the root of current AST void ASTFactory::makeASTRoot( ASTPair& currentAST, RefAST root ) { if (root) { // Add the current root as a child of new root root->addChild(currentAST.root); // The new current child is the last sibling of the old root currentAST.child = currentAST.root; currentAST.advanceChildToEnd(); // Set the new root currentAST.root = root; } } void ASTFactory::setASTNodeFactory( const char* factory_node_name, factory_type factory ) { default_factory_descriptor.first = factory_node_name; default_factory_descriptor.second = factory; } #ifdef ANTLR_SUPPORT_XML bool ASTFactory::checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& in ) { char ch; if( in.get(ch) ) { if( ch == '<' ) { char ch2; if( in.get(ch2) ) { if( ch2 == '/' ) { in.putback(ch2); in.putback(ch); return true; } in.putback(ch2); in.putback(ch); return false; } } in.putback(ch); return false; } return false; } void ASTFactory::loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current ) { char ch; for(;;) // for all children of this node.... { eatwhite(infile); infile.get(ch); // '<' if( ch != '<' ) { string error = "Invalid XML file... no '<' found ("; error += ch + ")"; throw IOException(error); } infile.get(ch); // / or text.... if( ch == '/' ) // check for close tag... { string temp; // read until '>' and see if it matches the open tag... if not trouble temp = read_identifier( infile ); if( strcmp(temp.c_str(), current->typeName() ) != 0 ) { string error = "Invalid XML file... close tag does not match start tag: "; error += current->typeName(); error += " closed by " + temp; throw IOException(error); } infile.get(ch); // must be a '>' if( ch != '>' ) { string error = "Invalid XML file... no '>' found ("; error += ch + ")"; throw IOException(error); } // close tag => exit loop break; } // put our 'look ahead' back where it came from infile.putback(ch); infile.putback('<'); // and recurse into the tree... RefAST child = LoadAST(infile); current->addChild( child ); } } void ASTFactory::loadSiblings(ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current ) { for(;;) { eatwhite(infile); if( infile.eof() ) break; if( checkCloseTag(infile) ) break; RefAST sibling = LoadAST(infile); current->setNextSibling(sibling); } } RefAST ASTFactory::LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile ) { RefAST current = nullAST; char ch; eatwhite(infile); if( !infile.get(ch) ) return nullAST; if( ch != '<' ) { string error = "Invalid XML file... no '<' found ("; error += ch + ")"; throw IOException(error); } string ast_type = read_identifier(infile); // create the ast of type 'ast_type' current = create( ast_type, infile ); if( current == nullAST ) { string error = "Unsuported AST type: " + ast_type; throw IOException(error); } eatwhite(infile); infile.get(ch); // now if we have a '/' here it's a single node. If it's a '>' we get // a tree with children if( ch == '/' ) { infile.get(ch); // get the closing '>' if( ch != '>' ) { string error = "Invalid XML file... no '>' found after '/' ("; error += ch + ")"; throw IOException(error); } // get the rest on this level loadSiblings( infile, current ); return current; } // and finaly see if we got the close tag... if( ch != '>' ) { string error = "Invalid XML file... no '>' found ("; error += ch + ")"; throw IOException(error); } // handle the ones below this level.. loadChildren( infile, current ); // load the rest on this level... loadSiblings( infile, current ); return current; } #endif // ANTLR_SUPPORT_XML #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif /* Heterogeneous AST/XML-I/O ramblings... * * So there is some heterogeneous AST support.... * basically in the code generators a new custom ast is generated without * going throug the factory. It also expects the RefXAST to be defined. * * Is it maybe better to register all AST types with the ASTFactory class * together with the respective factory methods. * * More and more I get the impression that hetero ast was a kindoff hack * on top of ANTLR's normal AST system. * * The heteroast stuff will generate trouble for all astFactory.create( ... ) * invocations. Most of this is handled via getASTCreateString methods in the * codegenerator. At the moment getASTCreateString(GrammarAtom, String) has * slightly to little info to do it's job (ok the hack that is in now * works, but it's an ugly hack) * * An extra caveat is the 'nice' action.g thing. Which also judiciously calls * getASTCreateString methods because it handles the #( ... ) syntax. * And converts that to ASTFactory calls. * * */ fwbuilder-5.1.0.3599/src/antlr/NoViableAltException.hpp0000644000175000017500000000166711733011756023447 0ustar sylvestresylvestre#ifndef INC_NoViableAltException_hpp__ #define INC_NoViableAltException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API NoViableAltException : public RecognitionException { public: const RefToken token; const RefAST node; // handles parsing and treeparsing NoViableAltException(RefAST t); NoViableAltException(RefToken t,const ANTLR_USE_NAMESPACE(std)string& fileName_); ~NoViableAltException() throw() {} /** * Returns a clean error message (no line number/column information) */ ANTLR_USE_NAMESPACE(std)string getMessage() const; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_NoViableAltException_hpp__ fwbuilder-5.1.0.3599/src/antlr/RecognitionException.hpp0000644000175000017500000000324211733011756023556 0ustar sylvestresylvestre#ifndef INC_RecognitionException_hpp__ # define INC_RecognitionException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ # include # include # ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { # endif class ANTLR_API RecognitionException : public ANTLRException { public: RecognitionException(); RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s); RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s, const ANTLR_USE_NAMESPACE(std)string& fileName, int line, int column ); virtual ~RecognitionException() throw() { } /// Return file where mishap occurred. virtual ANTLR_USE_NAMESPACE(std)string getFilename() const throw() { return fileName; } /** * @return the line number that this exception happened on. */ virtual int getLine() const throw() { return line; } /** * @return the column number that this exception happened on. */ virtual int getColumn() const throw() { return column; } /// Return complete error message with line/column number info (if present) virtual ANTLR_USE_NAMESPACE(std)string toString() const; /// See what file/line/column info is present and return it as a string virtual ANTLR_USE_NAMESPACE(std)string getFileLineColumnString() const; protected: ANTLR_USE_NAMESPACE(std)string fileName; // not used by treeparsers int line; // not used by treeparsers int column; // not used by treeparsers }; # ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } # endif #endif //INC_RecognitionException_hpp__ fwbuilder-5.1.0.3599/src/antlr/NoViableAltForCharException.hpp0000644000175000017500000000173511733011756024710 0ustar sylvestresylvestre#ifndef INC_NoViableAltForCharException_hpp__ # define INC_NoViableAltForCharException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ # include # include # include # ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { # endif class ANTLR_API NoViableAltForCharException : public RecognitionException { public: NoViableAltForCharException(int c, CharScanner* scanner); NoViableAltForCharException(int c, const ANTLR_USE_NAMESPACE(std)string& fileName_, int line_, int column_); virtual ~NoViableAltForCharException() throw() { } /// Returns a clean error message (no line number/column information) ANTLR_USE_NAMESPACE(std)string getMessage() const; protected: int foundChar; }; # ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } # endif #endif //INC_NoViableAltForCharException_hpp__ fwbuilder-5.1.0.3599/src/antlr/AST.hpp0000644000175000017500000001217511733011756020053 0ustar sylvestresylvestre#ifndef INC_AST_hpp__ #define INC_AST_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif struct ASTRef; class ANTLR_API AST { public: AST() : ref(0) {} AST(const AST&) : ref(0) {} virtual ~AST() {} /// Return the type name for this AST node. (for XML output) virtual const char* typeName( void ) const = 0; /// Clone this AST node. virtual RefAST clone( void ) const = 0; /// Is node t equal to this in terms of token type and text? virtual bool equals(RefAST t) const = 0; /** Is t an exact structural and equals() match of this tree. The * 'this' reference is considered the start of a sibling list. */ virtual bool equalsList(RefAST t) const = 0; /** Is 't' a subtree of this list? The siblings of the root are NOT ignored. */ virtual bool equalsListPartial(RefAST t) const = 0; /** Is tree rooted at 'this' equal to 't'? The siblings of 'this' are * ignored. */ virtual bool equalsTree(RefAST t) const = 0; /** Is 't' a subtree of the tree rooted at 'this'? The siblings of * 'this' are ignored. */ virtual bool equalsTreePartial(RefAST t) const = 0; /** Walk the tree looking for all exact subtree matches. Return * a vector of RefAST that lets the caller walk the list * of subtree roots found herein. */ virtual ANTLR_USE_NAMESPACE(std)vector findAll(RefAST t) = 0; /** Walk the tree looking for all subtrees. Return * a vector of RefAST that lets the caller walk the list * of subtree roots found herein. */ virtual ANTLR_USE_NAMESPACE(std)vector findAllPartial(RefAST t) = 0; /// Add a node to the end of the child list for this node virtual void addChild(RefAST c) = 0; /// Get the number of children. Returns 0 if the node is a leaf virtual size_t getNumberOfChildren() const = 0; /// Get the first child of this node; null if no children virtual RefAST getFirstChild() const = 0; /// Get the next sibling in line after this one virtual RefAST getNextSibling() const = 0; /// Get the token text for this node virtual ANTLR_USE_NAMESPACE(std)string getText() const = 0; /// Get the token type for this node virtual int getType() const = 0; /** Various initialization routines. Used by several factories to initialize * an AST element. */ virtual void initialize(int t, const ANTLR_USE_NAMESPACE(std)string& txt) = 0; virtual void initialize(RefAST t) = 0; virtual void initialize(RefToken t) = 0; #ifdef ANTLR_SUPPORT_XML /** initialize this node from the contents of a stream. * @param in the stream to read the AST attributes from. */ virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in ) = 0; #endif /// Set the first child of a node. virtual void setFirstChild(RefAST c) = 0; /// Set the next sibling after this one. virtual void setNextSibling(RefAST n) = 0; /// Set the token text for this node virtual void setText(const ANTLR_USE_NAMESPACE(std)string& txt) = 0; /// Set the token type for this node virtual void setType(int type) = 0; /// Return this AST node as a string virtual ANTLR_USE_NAMESPACE(std)string toString() const = 0; /// Print out a child-sibling tree in LISP notation virtual ANTLR_USE_NAMESPACE(std)string toStringList() const = 0; virtual ANTLR_USE_NAMESPACE(std)string toStringTree() const = 0; #ifdef ANTLR_SUPPORT_XML /** get attributes of this node to 'out'. Override to customize XML * output. * @param out the stream to write the AST attributes to. * @returns if a explicit closetag should be written */ virtual bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const = 0; /** Print a symbol over ostream. Overload this one to customize the XML * output for AST derived AST-types * @param output stream */ virtual void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const = 0; /** Dump AST contents in XML format to output stream. * Works in conjunction with to_stream method. Overload that one is * derived classes to customize behaviour. * @param output stream to write to string to put the stuff in. * @param ast RefAST object to write. */ friend ANTLR_USE_NAMESPACE(std)ostream& operator<<( ANTLR_USE_NAMESPACE(std)ostream& output, const RefAST& ast ); #endif private: friend struct ASTRef; ASTRef* ref; AST(RefAST other); AST& operator=(const AST& other); AST& operator=(RefAST other); }; #ifdef ANTLR_SUPPORT_XML inline ANTLR_USE_NAMESPACE(std)ostream& operator<<( ANTLR_USE_NAMESPACE(std)ostream& output, const RefAST& ast ) { ast->toStream(output); return output; } #endif extern ANTLR_API RefAST nullAST; extern ANTLR_API AST* const nullASTptr; #ifdef NEEDS_OPERATOR_LESS_THAN // RK: apparently needed by MSVC and a SUN CC, up to and including // 2.7.2 this was undefined ? inline bool operator<( RefAST l, RefAST r ) { return nullAST == l ? ( nullAST == r ? false : true ) : l->getType() < r->getType(); } #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_AST_hpp__ fwbuilder-5.1.0.3599/src/antlr/BitSet.cpp0000644000175000017500000000216211733011756020604 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/BitSet.hpp" #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif BitSet::BitSet(unsigned int nbits) : storage(nbits) { for (unsigned int i = 0; i < nbits ; i++ ) storage[i] = false; } BitSet::BitSet( const unsigned long* bits_, unsigned int nlongs ) : storage(nlongs*32) { for ( unsigned int i = 0 ; i < (nlongs * 32); i++) storage[i] = (bits_[i>>5] & (1UL << (i&31))) ? true : false; } BitSet::~BitSet() { } void BitSet::add(unsigned int el) { if( el >= storage.size() ) storage.resize( el+1, false ); storage[el] = true; } bool BitSet::member(unsigned int el) const { if ( el >= storage.size()) return false; return storage[el]; } ANTLR_USE_NAMESPACE(std)vector BitSet::toArray() const { ANTLR_USE_NAMESPACE(std)vector elems; for (unsigned int i = 0; i < storage.size(); i++) { if (storage[i]) elems.push_back(i); } return elems; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/NoViableAltForCharException.cpp0000644000175000017500000000175311733011756024703 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/NoViableAltForCharException.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif NoViableAltForCharException::NoViableAltForCharException(int c, CharScanner* scanner) : RecognitionException("NoViableAlt", scanner->getFilename(), scanner->getLine(),scanner->getColumn()), foundChar(c) { } NoViableAltForCharException::NoViableAltForCharException( int c, const ANTLR_USE_NAMESPACE(std)string& fileName_, int line_, int column_) : RecognitionException("NoViableAlt",fileName_,line_,column_), foundChar(c) { } ANTLR_USE_NAMESPACE(std)string NoViableAltForCharException::getMessage() const { return ANTLR_USE_NAMESPACE(std)string("unexpected char: ")+charName(foundChar); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CharInputBuffer.hpp0000644000175000017500000000334311733011756022450 0ustar sylvestresylvestre#ifndef INC_CharInputBuffer_hpp__ # define INC_CharInputBuffer_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ # include # include # ifdef HAS_NOT_CCTYPE_H # include # else # include # endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** CharInputBuffer.hpp provides an InputBuffer for plain character arrays (buffers). */ class CharInputBuffer : public InputBuffer { public: /** Construct a CharInputBuffer.hpp object with a char* buffer of 'size' * if 'owner' is true, then the buffer will be delete[]-ed on destruction. * @note it is assumed the buffer was allocated with new[]! */ CharInputBuffer( unsigned char* buf, size_t size, bool owner = false ) : buffer(buf) , ptr(buf) , end(buf + size) , delete_buffer(owner) { } /** Destructor * @note If you're using malloced data, then you probably need to change * this destructor. Or better use this class as template for your own. */ ~CharInputBuffer( void ) { if( delete_buffer && buffer ) delete [] buffer; } /** Reset the CharInputBuffer to initial state * Called from LexerInputState::reset. * @see LexerInputState */ virtual inline void reset( void ) { InputBuffer::reset(); ptr = buffer; } virtual int getChar( void ) { return (ptr < end) ? *ptr++ : EOF; } protected: unsigned char* buffer; ///< the buffer with data unsigned char* ptr; ///< position ptr into the buffer unsigned char* end; ///< end sentry for buffer bool delete_buffer; ///< flag signifying if we have to delete the buffer }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif fwbuilder-5.1.0.3599/src/antlr/CharStreamIOException.hpp0000644000175000017500000000131611733011756023557 0ustar sylvestresylvestre#ifndef INC_CharStreamIOException_hpp__ #define INC_CharStreamIOException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API CharStreamIOException : public CharStreamException { public: ANTLR_USE_NAMESPACE(std)exception io; CharStreamIOException(ANTLR_USE_NAMESPACE(std)exception& e) : CharStreamException(e.what()), io(e) {} ~CharStreamIOException() throw() {} }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CharStreamIOException_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamIOException.hpp0000644000175000017500000000143511733011756023764 0ustar sylvestresylvestre#ifndef INC_TokenStreamIOException_hpp__ #define INC_TokenStreamIOException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class TokenStreamIOException : public TokenStreamException { public: TokenStreamIOException() : TokenStreamException() { } TokenStreamIOException(const ANTLR_USE_NAMESPACE(std)exception& e) : TokenStreamException(e.what()) , io(e) { } ~TokenStreamIOException() throw() { } private: ANTLR_USE_NAMESPACE(std)exception io; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamIOException_hpp__ fwbuilder-5.1.0.3599/src/antlr/Parser.hpp0000644000175000017500000002117511733011756020660 0ustar sylvestresylvestre#ifndef INC_Parser_hpp__ #define INC_Parser_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif extern bool DEBUG_PARSER; /** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of * utility routines useful at any lookahead depth. We distinguish between * the LL(1) and LL(k) parsers because of efficiency. This may not be * necessary in the near future. * * Each parser object contains the state of the parse including a lookahead * cache (the form of which is determined by the subclass), whether or * not the parser is in guess mode, where tokens come from, etc... * *

* During guess mode, the current lookahead token(s) and token type(s) * cache must be saved because the token stream may not have been informed * to save the token (via mark) before the try block. * Guessing is started by: *

    *
  1. saving the lookahead cache. *
  2. marking the current position in the TokenBuffer. *
  3. increasing the guessing level. *
* * After guessing, the parser state is restored by: *
    *
  1. restoring the lookahead cache. *
  2. rewinding the TokenBuffer. *
  3. decreasing the guessing level. *
* * @see antlr.Token * @see antlr.TokenBuffer * @see antlr.TokenStream * @see antlr.LL1Parser * @see antlr.LLkParser * * @todo add constructors with ASTFactory. */ class ANTLR_API Parser { protected: Parser(TokenBuffer& input) : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0) { } Parser(TokenBuffer* input) : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0) { } Parser(const ParserSharedInputState& state) : inputState(state), astFactory(0), traceDepth(0) { } public: virtual ~Parser() { } /** Return the token type of the ith token of lookahead where i=1 * is the current token being examined by the parser (i.e., it * has not been matched yet). */ virtual int LA(unsigned int i)=0; /// Return the i-th token of lookahead virtual RefToken LT(unsigned int i)=0; /** DEPRECATED! Specify the factory to be used during tree building. (Compulsory) * Setting the factory is nowadays compulsory. * @see setASTFactory */ virtual void setASTNodeFactory( ASTFactory *factory ) { astFactory = factory; } /** Specify the factory to be used during tree building. (Compulsory) * Setting the factory is nowadays compulsory. */ virtual void setASTFactory( ASTFactory *factory ) { astFactory = factory; } /** Return a pointer to the ASTFactory used. * So you might use it in subsequent treewalkers or to reload AST's * from disk. */ virtual ASTFactory* getASTFactory() { return astFactory; } /** Get the root AST node of the generated AST. When using a custom AST type * or heterogenous AST's, you'll have to convert it to the right type * yourself. */ virtual RefAST getAST() = 0; /// Return the filename of the input file. virtual inline ANTLR_USE_NAMESPACE(std)string getFilename() const { return inputState->filename; } /// Set the filename of the input file (used for error reporting). virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f) { inputState->filename = f; } virtual void setInputState(ParserSharedInputState state) { inputState = state; } virtual inline ParserSharedInputState getInputState() const { return inputState; } /// Get another token object from the token stream virtual void consume()=0; /// Consume tokens until one matches the given token virtual void consumeUntil(int tokenType) { while (LA(1) != Token::EOF_TYPE && LA(1) != tokenType) consume(); } /// Consume tokens until one matches the given token set virtual void consumeUntil(const BitSet& set) { while (LA(1) != Token::EOF_TYPE && !set.member(LA(1))) consume(); } /** Make sure current lookahead symbol matches token type t. * Throw an exception upon mismatch, which is catch by either the * error handler or by the syntactic predicate. */ virtual void match(int t) { if ( DEBUG_PARSER ) { traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "enter match(" << t << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; } if ( LA(1) != t ) { if ( DEBUG_PARSER ) { traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << "!=" << t << ANTLR_USE_NAMESPACE(std)endl; } throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, false, getFilename()); } else { // mark token as consumed -- fetch next token deferred until LA/LT consume(); } } virtual void matchNot(int t) { if ( LA(1)==t ) { // Throws inverted-sense exception throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, true, getFilename()); } else { // mark token as consumed -- fetch next token deferred until LA/LT consume(); } } /** Make sure current lookahead symbol matches the given set * Throw an exception upon mismatch, which is catch by either the * error handler or by the syntactic predicate. */ virtual void match(const BitSet& b) { if ( DEBUG_PARSER ) { traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "enter match(" << "bitset" /*b.toString()*/ << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; } if ( !b.member(LA(1)) ) { if ( DEBUG_PARSER ) { traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << " not member of " << "bitset" /*b.toString()*/ << ANTLR_USE_NAMESPACE(std)endl; } throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), b, false, getFilename()); } else { // mark token as consumed -- fetch next token deferred until LA/LT consume(); } } /** Mark a spot in the input and return the position. * Forwarded to TokenBuffer. */ virtual inline unsigned int mark() { return inputState->getInput().mark(); } /// rewind to a previously marked position virtual inline void rewind(unsigned int pos) { inputState->getInput().rewind(pos); } /** called by the generated parser to do error recovery, override to * customize the behaviour. */ virtual void recover(const RecognitionException& , const BitSet& tokenSet) { consume(); consumeUntil(tokenSet); } /// Parser error-reporting function can be overridden in subclass virtual void reportError(const RecognitionException& ex); /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s); /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s); /// get the token name for the token number 'num' virtual const char* getTokenName(int num) const = 0; /// get a vector with all token names virtual const char* const* getTokenNames() const = 0; /** Get the number of tokens defined. * This one should be overridden in subclasses. */ virtual int getNumTokens(void) const = 0; /** Set or change the input token buffer */ // void setTokenBuffer(TokenBuffer* t); virtual void traceIndent(); virtual void traceIn(const char* rname); virtual void traceOut(const char* rname); protected: // void setTokenNames(const char** tokenNames_); ParserSharedInputState inputState; // /// AST return value for a rule is squirreled away here // RefAST returnAST; /// AST support code; parser and treeparser delegate to this object ASTFactory *astFactory; // used to keep track of the indentation for the trace int traceDepth; /** Utility class which allows tracing to work even when exceptions are * thrown. */ class Tracer { /*{{{*/ private: Parser* parser; const char* text; public: Tracer(Parser* p,const char * t) : parser(p), text(t) { parser->traceIn(text); } ~Tracer() { #ifdef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION // Only give trace if there's no uncaught exception.. if(!ANTLR_USE_NAMESPACE(std)uncaught_exception()) #endif parser->traceOut(text); } private: Tracer(const Tracer&); // undefined const Tracer& operator=(const Tracer&); // undefined /*}}}*/ }; private: Parser(const Parser&); // undefined const Parser& operator=(const Parser&); // undefined }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_Parser_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamHiddenTokenFilter.hpp0000644000175000017500000000424011733011756025135 0ustar sylvestresylvestre#ifndef INC_TokenStreamHiddenTokenFilter_hpp__ #define INC_TokenStreamHiddenTokenFilter_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /**This object filters a token stream coming from a lexer * or another TokenStream so that only certain token channels * get transmitted to the parser. * * Any of the channels can be filtered off as "hidden" channels whose * tokens can be accessed from the parser. */ class ANTLR_API TokenStreamHiddenTokenFilter : public TokenStreamBasicFilter { // protected BitSet discardMask; protected: BitSet hideMask; private: RefToken nextMonitoredToken; protected: /** track tail of hidden list emanating from previous * monitored token */ RefToken lastHiddenToken; RefToken firstHidden; // = null; public: TokenStreamHiddenTokenFilter(TokenStream& input); protected: void consume(); private: void consumeFirst(); public: BitSet getDiscardMask() const; /** Return a ptr to the hidden token appearing immediately after * token t in the input stream. */ RefToken getHiddenAfter(RefToken t); /** Return a ptr to the hidden token appearing immediately before * token t in the input stream. */ RefToken getHiddenBefore(RefToken t); BitSet getHideMask() const; /** Return the first hidden token if one appears * before any monitored token. */ RefToken getInitialHiddenToken(); void hide(int m); void hide(const BitSet& mask); protected: RefToken LA(int i); public: /** Return the next monitored token. * Test the token following the monitored token. * If following is another monitored token, save it * for the next invocation of nextToken (like a single * lookahead token) and return it then. * If following is unmonitored, nondiscarded (hidden) * channel token, add it to the monitored token. * * Note: EOF must be a monitored Token. */ RefToken nextToken(); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamHiddenTokenFilter_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamException.hpp0000644000175000017500000000147111733011756023534 0ustar sylvestresylvestre#ifndef INC_TokenStreamException_hpp__ #define INC_TokenStreamException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** Baseclass for exceptions thrown by classes implementing the TokenStream * interface. * @see TokenStream */ class ANTLR_API TokenStreamException : public ANTLRException { public: TokenStreamException() : ANTLRException() { } TokenStreamException(const ANTLR_USE_NAMESPACE(std)string& s) : ANTLRException(s) { } virtual ~TokenStreamException() throw() { } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamException_hpp__ fwbuilder-5.1.0.3599/src/antlr/LLkParser.hpp0000644000175000017500000000270111733011756021255 0ustar sylvestresylvestre#ifndef INC_LLkParser_hpp__ #define INC_LLkParser_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /**An LL(k) parser. * * @see antlr.Token * @see antlr.TokenBuffer * @see antlr.LL1Parser */ class ANTLR_API LLkParser : public Parser { public: LLkParser(const ParserSharedInputState& lexer, int k_); LLkParser(TokenBuffer& tokenBuf, int k_); LLkParser(TokenStream& lexer, int k_); /** Consume another token from the input stream. Can only write sequentially! * If you need 3 tokens ahead, you must consume() 3 times. *

* Note that it is possible to overwrite tokens that have not been matched. * For example, calling consume() 3 times when k=2, means that the first token * consumed will be overwritten with the 3rd. */ virtual inline void consume() { inputState->getInput().consume(); } virtual inline int LA(unsigned int i) { return inputState->getInput().LA(i); } virtual RefToken LT(unsigned int i); protected: /// the lookahead this LL(k) parser is using. int k; private: void trace(const char* ee, const char* rname); public: virtual void traceIn(const char* rname); virtual void traceOut(const char* rname); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_LLkParser_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenRefCount.hpp0000644000175000017500000000330211733011756022142 0ustar sylvestresylvestre#ifndef INC_TokenRefCount_hpp__ # define INC_TokenRefCount_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ # include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class Token; struct ANTLR_API TokenRef { Token* const ptr; unsigned int count; TokenRef(Token* p); ~TokenRef(); TokenRef* increment() { ++count; return this; } bool decrement() { return (--count==0); } static TokenRef* getRef(const Token* p); private: TokenRef( const TokenRef& ); TokenRef& operator=( const TokenRef& ); }; template class ANTLR_API TokenRefCount { private: TokenRef* ref; public: TokenRefCount(const Token* p=0) : ref(p ? TokenRef::getRef(p) : 0) { } TokenRefCount(const TokenRefCount& other) : ref(other.ref ? other.ref->increment() : 0) { } ~TokenRefCount() { if (ref && ref->decrement()) delete ref; } TokenRefCount& operator=(Token* other) { TokenRef* tmp = TokenRef::getRef(other); if (ref && ref->decrement()) delete ref; ref=tmp; return *this; } TokenRefCount& operator=(const TokenRefCount& other) { if( other.ref != ref ) { TokenRef* tmp = other.ref ? other.ref->increment() : 0; if (ref && ref->decrement()) delete ref; ref=tmp; } return *this; } operator T* () const { return ref ? static_cast(ref->ptr) : 0; } T* operator->() const { return ref ? static_cast(ref->ptr) : 0; } T* get() const { return ref ? static_cast(ref->ptr) : 0; } }; typedef TokenRefCount RefToken; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenRefCount_hpp__ fwbuilder-5.1.0.3599/src/antlr/ANTLRException.hpp0000644000175000017500000000252611733011756022162 0ustar sylvestresylvestre#ifndef INC_ANTLRException_hpp__ #define INC_ANTLRException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API ANTLRException { public: /// Create ANTLR base exception without error message ANTLRException() : text("") { } /// Create ANTLR base exception with error message ANTLRException(const ANTLR_USE_NAMESPACE(std)string& s) : text(s) { } virtual ~ANTLRException() throw() { } /** Return complete error message with line/column number info (if present) * @note for your own exceptions override this one. Call getMessage from * here to get the 'clean' error message stored in the text attribute. */ virtual ANTLR_USE_NAMESPACE(std)string toString() const { return text; } /** Return error message without additional info (if present) * @note when making your own exceptions classes override toString * and call in toString getMessage which relays the text attribute * from here. */ virtual ANTLR_USE_NAMESPACE(std)string getMessage() const { return text; } private: ANTLR_USE_NAMESPACE(std)string text; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ANTLRException_hpp__ fwbuilder-5.1.0.3599/src/antlr/CharBuffer.hpp0000644000175000017500000000255611733011756021435 0ustar sylvestresylvestre#ifndef INC_CharBuffer_hpp__ #define INC_CharBuffer_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /**A Stream of characters fed to the lexer from a InputStream that can * be rewound via mark()/rewind() methods. *

* A dynamic array is used to buffer up all the input characters. Normally, * "k" characters are stored in the buffer. More characters may be stored * during guess mode (testing syntactic predicate), or when LT(i>k) is * referenced. * Consumption of characters is deferred. In other words, reading the next * character is not done by consume(), but deferred until needed by LA or LT. *

* A dynamic array is used to buffer up all the input tokens. Normally, * "k" tokens are stored in the buffer. More tokens may be stored during * guess mode (testing syntactic predicate), or when LT(i>k) is referenced. * Consumption of tokens is deferred. In other words, reading the next * token is not done by conume(), but deferred until needed by LA or LT. *

* * @see antlr.Token * @see antlr.TokenStream * @see antlr.TokenQueue */ /** Create a token buffer */ TokenBuffer::TokenBuffer( TokenStream& inp ) : input(inp) , nMarkers(0) , markerOffset(0) , numToConsume(0) { } TokenBuffer::~TokenBuffer( void ) { } /** Ensure that the token buffer is sufficiently full */ void TokenBuffer::fill(unsigned int amount) { syncConsume(); // Fill the buffer sufficiently to hold needed tokens while (queue.entries() < (amount + markerOffset)) { // Append the next token queue.append(input.nextToken()); } } /** Get a lookahead token value */ int TokenBuffer::LA(unsigned int i) { fill(i); return queue.elementAt(markerOffset+i-1)->getType(); } /** Get a lookahead token */ RefToken TokenBuffer::LT(unsigned int i) { fill(i); return queue.elementAt(markerOffset+i-1); } /** Return an integer marker that can be used to rewind the buffer to * its current state. */ unsigned int TokenBuffer::mark() { syncConsume(); nMarkers++; return markerOffset; } /**Rewind the token buffer to a marker. * @param mark Marker returned previously from mark() */ void TokenBuffer::rewind(unsigned int mark) { syncConsume(); markerOffset=mark; nMarkers--; } /// Get number of non-consumed tokens unsigned int TokenBuffer::entries() const { return queue.entries() - markerOffset; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/TokenStreamSelector.hpp0000644000175000017500000000517211733011756023360 0ustar sylvestresylvestre#ifndef INC_TokenStreamSelector_hpp__ #define INC_TokenStreamSelector_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** A token stream MUX (multiplexor) knows about n token streams * and can multiplex them onto the same channel for use by token * stream consumer like a parser. This is a way to have multiple * lexers break up the same input stream for a single parser. * Or, you can have multiple instances of the same lexer handle * multiple input streams; this works great for includes. */ class ANTLR_API TokenStreamSelector : public TokenStream { protected: /** The set of inputs to the MUX */ #ifdef OS_NO_ALLOCATOR typedef ANTLR_USE_NAMESPACE(std)less lessp; typedef ANTLR_USE_NAMESPACE(std)map inputStreamNames_coll; #else typedef ANTLR_USE_NAMESPACE(std)map inputStreamNames_coll; #endif inputStreamNames_coll inputStreamNames; /** The currently-selected token stream input */ TokenStream* input; /** Used to track stack of input streams */ #ifdef OS_NO_ALLOCATOR typedef ANTLR_USE_NAMESPACE(std)stack > streamStack_coll; #else typedef ANTLR_USE_NAMESPACE(std)stack streamStack_coll; #endif streamStack_coll streamStack; public: TokenStreamSelector(); ~TokenStreamSelector(); void addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key); /// Return the stream from which tokens are being pulled at the moment. TokenStream* getCurrentStream() const; TokenStream* getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const; RefToken nextToken(); TokenStream* pop(); void push(TokenStream* stream); void push(const ANTLR_USE_NAMESPACE(std)string& sname); /** Abort recognition of current Token and try again. * A stream can push a new stream (for include files * for example, and then retry(), which will cause * the current stream to abort back to this.nextToken(). * this.nextToken() then asks for a token from the * current stream, which is the new "substream." */ void retry(); /** Set the stream without pushing old stream */ void select(TokenStream* stream); void select(const ANTLR_USE_NAMESPACE(std)string& sname); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamSelector_hpp__ fwbuilder-5.1.0.3599/src/antlr/CommonHiddenStreamToken.cpp0000644000175000017500000000200711733011756024131 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/CommonHiddenStreamToken.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif CommonHiddenStreamToken::CommonHiddenStreamToken() : CommonToken() { } CommonHiddenStreamToken::CommonHiddenStreamToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt) : CommonToken(t,txt) { } CommonHiddenStreamToken::CommonHiddenStreamToken(const ANTLR_USE_NAMESPACE(std)string& s) : CommonToken(s) { } RefToken CommonHiddenStreamToken::getHiddenAfter() { return hiddenAfter; } RefToken CommonHiddenStreamToken::getHiddenBefore() { return hiddenBefore; } RefToken CommonHiddenStreamToken::factory() { return RefToken(new CommonHiddenStreamToken); } void CommonHiddenStreamToken::setHiddenAfter(RefToken t) { hiddenAfter = t; } void CommonHiddenStreamToken::setHiddenBefore(RefToken t) { hiddenBefore = t; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/LexerSharedInputState.hpp0000644000175000017500000000650011733011756023646 0ustar sylvestresylvestre#ifndef INC_LexerSharedInputState_hpp__ #define INC_LexerSharedInputState_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This object contains the data associated with an * input stream of characters. Multiple lexers * share a single LexerSharedInputState to lex * the same input stream. */ class ANTLR_API LexerInputState { public: /** Construct a new LexerInputState * @param inbuf the InputBuffer to read from. The object is deleted together * with the LexerInputState object. */ LexerInputState(InputBuffer* inbuf) : column(1) , line(1) , tokenStartColumn(1) , tokenStartLine(1) , guessing(0) , filename("") , input(inbuf) , inputResponsible(true) { } /** Construct a new LexerInputState * @param inbuf the InputBuffer to read from. */ LexerInputState(InputBuffer& inbuf) : column(1) , line(1) , tokenStartColumn(1) , tokenStartLine(1) , guessing(0) , filename("") , input(&inbuf) , inputResponsible(false) { } /** Construct a new LexerInputState * @param in an istream to read from. * @see antlr.CharBuffer */ LexerInputState(ANTLR_USE_NAMESPACE(std)istream& in) : column(1) , line(1) , tokenStartColumn(1) , tokenStartLine(1) , guessing(0) , filename("") , input(new CharBuffer(in)) , inputResponsible(true) { } /** Reset the LexerInputState with a specified stream and filename. * This method is a hack, dunno what I was thinking when I added it. * This should actually be done in a subclass. * @deprecated */ virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in, const char* file = "" ) { column = 1; line = 1; tokenStartColumn = 1; tokenStartLine = 1; guessing = 0; filename = file; if( input && inputResponsible ) delete input; input = new CharBuffer(in); inputResponsible = true; } /** Reset the LexerInputState to initial state. * The underlying InputBuffer is also reset. */ virtual void reset( void ) { column = 1; line = 1; tokenStartColumn = 1; tokenStartLine = 1; guessing = 0; input->reset(); } /** Set the file position of the SharedLexerInputState. * @param line_ line number to be set * @param column_ column number to be set */ void setPosition( int line_, int column_ ) { line = line_; column = column_; } virtual ~LexerInputState() { if (inputResponsible) delete input; } int column; int line; int tokenStartColumn; int tokenStartLine; int guessing; /** What file (if known) caused the problem? */ ANTLR_USE_NAMESPACE(std)string filename; InputBuffer& getInput(); private: /// Input buffer we use InputBuffer* input; /// Who is responsible for cleaning up the InputBuffer? bool inputResponsible; // we don't want these: LexerInputState(const LexerInputState&); LexerInputState& operator=(const LexerInputState&); }; inline InputBuffer& LexerInputState::getInput() { return *input; } /// A reference counted LexerInputState object typedef RefCount LexerSharedInputState; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_LexerSharedInputState_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamSelector.cpp0000644000175000017500000000465611733011756023361 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/TokenStreamSelector.hpp" #include "antlr/TokenStreamRetryException.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** A token stream MUX (multiplexor) knows about n token streams * and can multiplex them onto the same channel for use by token * stream consumer like a parser. This is a way to have multiple * lexers break up the same input stream for a single parser. * Or, you can have multiple instances of the same lexer handle * multiple input streams; this works great for includes. */ TokenStreamSelector::TokenStreamSelector() : input(0) { } TokenStreamSelector::~TokenStreamSelector() { } void TokenStreamSelector::addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key) { inputStreamNames[key] = stream; } TokenStream* TokenStreamSelector::getCurrentStream() const { return input; } TokenStream* TokenStreamSelector::getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const { inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname); if (i == inputStreamNames.end()) { throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found"; } return (*i).second; } RefToken TokenStreamSelector::nextToken() { // keep looking for a token until you don't // get a retry exception for (;;) { try { return input->nextToken(); } catch (TokenStreamRetryException&) { // just retry "forever" } } } TokenStream* TokenStreamSelector::pop() { TokenStream* stream = streamStack.top(); streamStack.pop(); select(stream); return stream; } void TokenStreamSelector::push(TokenStream* stream) { streamStack.push(input); select(stream); } void TokenStreamSelector::push(const ANTLR_USE_NAMESPACE(std)string& sname) { streamStack.push(input); select(sname); } void TokenStreamSelector::retry() { throw TokenStreamRetryException(); } /** Set the stream without pushing old stream */ void TokenStreamSelector::select(TokenStream* stream) { input = stream; } void TokenStreamSelector::select(const ANTLR_USE_NAMESPACE(std)string& sname) { inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname); if (i == inputStreamNames.end()) { throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found"; } input = (*i).second; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/TokenStreamRewriteEngine.cpp0000644000175000017500000001310711733011756024337 0ustar sylvestresylvestre#include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif #ifndef NO_STATIC_CONSTS const size_t TokenStreamRewriteEngine::MIN_TOKEN_INDEX = 0; const int TokenStreamRewriteEngine::PROGRAM_INIT_SIZE = 100; #endif const char* TokenStreamRewriteEngine::DEFAULT_PROGRAM_NAME = "default"; namespace { struct compareOperationIndex { typedef TokenStreamRewriteEngine::RewriteOperation RewriteOperation; bool operator() ( const RewriteOperation* a, const RewriteOperation* b ) const { return a->getIndex() < b->getIndex(); } }; struct dumpTokenWithIndex { dumpTokenWithIndex( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {} void operator() ( const RefTokenWithIndex& t ) { out << "[txt='" << t->getText() << "' tp=" << t->getType() << " idx=" << t->getIndex() << "]\n"; } ANTLR_USE_NAMESPACE(std)ostream& out; }; } TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream) : stream(upstream) , index(MIN_TOKEN_INDEX) , tokens() , programs() , discardMask() { } TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize ) : stream(upstream) , index(MIN_TOKEN_INDEX) , tokens(initialSize) , programs() , discardMask() { } RefToken TokenStreamRewriteEngine::nextToken( void ) { RefTokenWithIndex t; // suck tokens until end of stream or we find a non-discarded token do { t = RefTokenWithIndex(stream.nextToken()); if ( t ) { t->setIndex(index); // what is t's index in list? if ( t->getType() != Token::EOF_TYPE ) { tokens.push_back(t); // track all tokens except EOF } index++; // move to next position } } while ( t && discardMask.member(t->getType()) ); return RefToken(t); } void TokenStreamRewriteEngine::rollback( const std::string& programName, size_t instructionIndex ) { program_map::iterator rewrite = programs.find(programName); if( rewrite != programs.end() ) { operation_list& prog = rewrite->second; operation_list::iterator j = prog.begin(), end = prog.end(); std::advance(j,instructionIndex); if( j != end ) prog.erase(j, end); } } void TokenStreamRewriteEngine::originalToStream( std::ostream& out, size_t start, size_t end ) const { token_list::const_iterator s = tokens.begin(); std::advance( s, start ); token_list::const_iterator e = s; std::advance( e, end-start ); std::for_each( s, e, tokenToStream(out) ); } void TokenStreamRewriteEngine::toStream( std::ostream& out, const std::string& programName, size_t firstToken, size_t lastToken ) const { if( tokens.size() == 0 ) return; program_map::const_iterator rewriter = programs.find(programName); if ( rewriter == programs.end() ) return; // get the prog and some iterators in it... const operation_list& prog = rewriter->second; operation_list::const_iterator rewriteOpIndex = prog.begin(), rewriteOpEnd = prog.end(); size_t tokenCursor = firstToken; // make sure we don't run out of the tokens we have... if( lastToken > (tokens.size() - 1) ) lastToken = tokens.size() - 1; while ( tokenCursor <= lastToken ) { // std::cout << "tokenCursor = " << tokenCursor << " first prog index = " << (*rewriteOpIndex)->getIndex() << std::endl; if( rewriteOpIndex != rewriteOpEnd ) { size_t up_to_here = std::min(lastToken,(*rewriteOpIndex)->getIndex()); while( tokenCursor < up_to_here ) out << tokens[tokenCursor++]->getText(); } while ( rewriteOpIndex != rewriteOpEnd && tokenCursor == (*rewriteOpIndex)->getIndex() && tokenCursor <= lastToken ) { tokenCursor = (*rewriteOpIndex)->execute(out); ++rewriteOpIndex; } if( tokenCursor <= lastToken ) out << tokens[tokenCursor++]->getText(); } // std::cout << "Handling tail operations # left = " << std::distance(rewriteOpIndex,rewriteOpEnd) << std::endl; // now see if there are operations (append) beyond last token index std::for_each( rewriteOpIndex, rewriteOpEnd, executeOperation(out) ); rewriteOpIndex = rewriteOpEnd; } void TokenStreamRewriteEngine::toDebugStream( std::ostream& out, size_t start, size_t end ) const { token_list::const_iterator s = tokens.begin(); std::advance( s, start ); token_list::const_iterator e = s; std::advance( e, end-start ); std::for_each( s, e, dumpTokenWithIndex(out) ); } void TokenStreamRewriteEngine::addToSortedRewriteList( const std::string& programName, RewriteOperation* op ) { program_map::iterator rewrites = programs.find(programName); // check if we got the program already.. if ( rewrites == programs.end() ) { // no prog make a new one... operation_list ops; ops.push_back(op); programs.insert(std::make_pair(programName,ops)); return; } operation_list& prog = rewrites->second; if( prog.empty() ) { prog.push_back(op); return; } operation_list::iterator i, end = prog.end(); i = end; --i; // if at or beyond last op's index, just append if ( op->getIndex() >= (*i)->getIndex() ) { prog.push_back(op); // append to list of operations return; } i = prog.begin(); if( i != end ) { operation_list::iterator pos = std::upper_bound( i, end, op, compareOperationIndex() ); prog.insert(pos,op); } else prog.push_back(op); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/BaseAST.cpp0000644000175000017500000001500011733011756020627 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/config.hpp" #include #include "antlr/AST.hpp" #include "antlr/BaseAST.hpp" ANTLR_USING_NAMESPACE(std) #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif size_t BaseAST::getNumberOfChildren() const { RefBaseAST t = this->down; size_t n = 0; if( t ) { n = 1; while( t->right ) { t = t->right; n++; } return n; } return n; } void BaseAST::doWorkForFindAll( ANTLR_USE_NAMESPACE(std)vector& v, RefAST target,bool partialMatch) { // Start walking sibling lists, looking for matches. for (RefAST sibling=this; sibling; sibling=sibling->getNextSibling()) { if ( (partialMatch && sibling->equalsTreePartial(target)) || (!partialMatch && sibling->equalsTree(target)) ) { v.push_back(sibling); } // regardless of match or not, check any children for matches if ( sibling->getFirstChild() ) { RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch); } } } /** Is t an exact structural and equals() match of this tree. The * 'this' reference is considered the start of a sibling list. */ bool BaseAST::equalsList(RefAST t) const { // the empty tree is not a match of any non-null tree. if (!t) return false; // Otherwise, start walking sibling lists. First mismatch, return false. RefAST sibling=this; for (;sibling && t; sibling=sibling->getNextSibling(), t=t->getNextSibling()) { // as a quick optimization, check roots first. if (!sibling->equals(t)) return false; // if roots match, do full list match test on children. if (sibling->getFirstChild()) { if (!sibling->getFirstChild()->equalsList(t->getFirstChild())) return false; } // sibling has no kids, make sure t doesn't either else if (t->getFirstChild()) return false; } if (!sibling && !t) return true; // one sibling list has more than the other return false; } /** Is 'sub' a subtree of this list? * The siblings of the root are NOT ignored. */ bool BaseAST::equalsListPartial(RefAST sub) const { // the empty tree is always a subset of any tree. if (!sub) return true; // Otherwise, start walking sibling lists. First mismatch, return false. RefAST sibling=this; for (;sibling && sub; sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) { // as a quick optimization, check roots first. if (!sibling->equals(sub)) return false; // if roots match, do partial list match test on children. if (sibling->getFirstChild()) if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild())) return false; } if (!sibling && sub) // nothing left to match in this tree, but subtree has more return false; // either both are null or sibling has more, but subtree doesn't return true; } /** Is tree rooted at 'this' equal to 't'? The siblings * of 'this' are ignored. */ bool BaseAST::equalsTree(RefAST t) const { // check roots first if (!equals(t)) return false; // if roots match, do full list match test on children. if (getFirstChild()) { if (!getFirstChild()->equalsList(t->getFirstChild())) return false; } // sibling has no kids, make sure t doesn't either else if (t->getFirstChild()) return false; return true; } /** Is 'sub' a subtree of the tree rooted at 'this'? The siblings * of 'this' are ignored. */ bool BaseAST::equalsTreePartial(RefAST sub) const { // the empty tree is always a subset of any tree. if (!sub) return true; // check roots first if (!equals(sub)) return false; // if roots match, do full list partial match test on children. if (getFirstChild()) if (!getFirstChild()->equalsListPartial(sub->getFirstChild())) return false; return true; } /** Walk the tree looking for all exact subtree matches. Return * an ASTEnumerator that lets the caller walk the list * of subtree roots found herein. */ ANTLR_USE_NAMESPACE(std)vector BaseAST::findAll(RefAST target) { ANTLR_USE_NAMESPACE(std)vector roots; // the empty tree cannot result in an enumeration if (target) { doWorkForFindAll(roots,target,false); // find all matches recursively } return roots; } /** Walk the tree looking for all subtrees. Return * an ASTEnumerator that lets the caller walk the list * of subtree roots found herein. */ ANTLR_USE_NAMESPACE(std)vector BaseAST::findAllPartial(RefAST target) { ANTLR_USE_NAMESPACE(std)vector roots; // the empty tree cannot result in an enumeration if (target) doWorkForFindAll(roots,target,true); // find all matches recursively return roots; } ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const { ANTLR_USE_NAMESPACE(std)string ts=""; if (getFirstChild()) { ts+=" ( "; ts+=toString(); ts+=getFirstChild()->toStringList(); ts+=" )"; } else { ts+=" "; ts+=toString(); } if (getNextSibling()) ts+=getNextSibling()->toStringList(); return ts; } ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const { ANTLR_USE_NAMESPACE(std)string ts = ""; if (getFirstChild()) { ts+=" ( "; ts+=toString(); ts+=getFirstChild()->toStringList(); ts+=" )"; } else { ts+=" "; ts+=toString(); } return ts; } #ifdef ANTLR_SUPPORT_XML /* This whole XML output stuff needs a little bit more thought * I'd like to store extra XML data in the node. e.g. for custom ast's * with for instance symboltable references. This * should be more pluggable.. * @returns boolean value indicating wether a closetag should be produced. */ bool BaseAST::attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { out << "text=\"" << this->getText() << "\" type=\"" << this->getType() << "\""; return false; } void BaseAST::toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { for( RefAST node = this; node != 0; node = node->getNextSibling() ) { out << "<" << this->typeName() << " "; // Write out attributes and if there is extra data... bool need_close_tag = node->attributesToStream( out ); if( need_close_tag ) { // got children so write them... if( node->getFirstChild() != 0 ) node->getFirstChild()->toStream( out ); // and a closing tag.. out << "typeName() << ">" << endl; } } } #endif // this is nasty, but it makes the code generation easier ANTLR_API RefAST nullAST; #if defined(_MSC_VER) && !defined(__ICL) // Microsoft Visual C++ extern ANTLR_API AST* const nullASTptr = 0; #else ANTLR_API AST* const nullASTptr = 0; #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/TreeParser.cpp0000644000175000017500000000373611733011756021476 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/TreeParser.hpp" #include "antlr/ASTNULLType.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** The AST Null object; the parsing cursor is set to this when * it is found to be null. This way, we can test the * token type of a node without having to have tests for null * everywhere. */ RefAST TreeParser::ASTNULL(new ASTNULLType); /** Parser error-reporting function can be overridden in subclass */ void TreeParser::reportError(const RecognitionException& ex) { ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Parser error-reporting function can be overridden in subclass */ void TreeParser::reportError(const ANTLR_USE_NAMESPACE(std)string& s) { ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Parser warning-reporting function can be overridden in subclass */ void TreeParser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Procedure to write out an indent for traceIn and traceOut */ void TreeParser::traceIndent() { for( int i = 0; i < traceDepth; i++ ) ANTLR_USE_NAMESPACE(std)cout << " "; } void TreeParser::traceIn(const char* rname, RefAST t) { traceDepth++; traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "> " << rname << "(" << (t ? t->toString().c_str() : "null") << ")" << ((inputState->guessing>0)?" [guessing]":"") << ANTLR_USE_NAMESPACE(std)endl; } void TreeParser::traceOut(const char* rname, RefAST t) { traceIndent(); ANTLR_USE_NAMESPACE(std)cout << "< " << rname << "(" << (t ? t->toString().c_str() : "null") << ")" << ((inputState->guessing>0)?" [guessing]":"") << ANTLR_USE_NAMESPACE(std)endl; traceDepth--; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CharStreamException.hpp0000644000175000017500000000120011733011756023317 0ustar sylvestresylvestre#ifndef INC_CharStreamException_hpp__ #define INC_CharStreamException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API CharStreamException : public ANTLRException { public: CharStreamException(const ANTLR_USE_NAMESPACE(std)string& s) : ANTLRException(s) {} ~CharStreamException() throw() {} }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CharStreamException_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamBasicFilter.hpp0000644000175000017500000000172111733011756023763 0ustar sylvestresylvestre#ifndef INC_TokenStreamBasicFilter_hpp__ #define INC_TokenStreamBasicFilter_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This object is a TokenStream that passes through all * tokens except for those that you tell it to discard. * There is no buffering of the tokens. */ class ANTLR_API TokenStreamBasicFilter : public TokenStream { /** The set of token types to discard */ protected: BitSet discardMask; /** The input stream */ protected: TokenStream* input; public: TokenStreamBasicFilter(TokenStream& input_); void discard(int ttype); void discard(const BitSet& mask); RefToken nextToken(); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamBasicFilter_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamRecognitionException.hpp0000644000175000017500000000236311733011756025736 0ustar sylvestresylvestre#ifndef INC_TokenStreamRecognitionException_hpp__ #define INC_TokenStreamRecognitionException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** Exception thrown from generated lexers when there's no default error * handler specified. * @see TokenStream */ class TokenStreamRecognitionException : public TokenStreamException { public: TokenStreamRecognitionException(RecognitionException& re) : TokenStreamException(re.getMessage()) , recog(re) { } virtual ~TokenStreamRecognitionException() throw() { } virtual ANTLR_USE_NAMESPACE(std)string toString() const { return recog.getFileLineColumnString()+getMessage(); } virtual ANTLR_USE_NAMESPACE(std)string getFilename() const throw() { return recog.getFilename(); } virtual int getLine() const throw() { return recog.getLine(); } virtual int getColumn() const throw() { return recog.getColumn(); } private: RecognitionException recog; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamRecognitionException_hpp__ fwbuilder-5.1.0.3599/src/antlr/ASTNULLType.hpp0000644000175000017500000000331711733011756021406 0ustar sylvestresylvestre#ifndef INC_ASTNULLType_hpp__ #define INC_ASTNULLType_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** There is only one instance of this class **/ class ANTLR_API ASTNULLType : public AST { public: const char* typeName( void ) const; RefAST clone( void ) const; void addChild(RefAST c); size_t getNumberOfChildren() const; void setFirstChild(RefAST c); void setNextSibling(RefAST n); bool equals(RefAST t) const; bool equalsList(RefAST t) const; bool equalsListPartial(RefAST t) const; bool equalsTree(RefAST t) const; bool equalsTreePartial(RefAST t) const; ANTLR_USE_NAMESPACE(std)vector findAll(RefAST tree); ANTLR_USE_NAMESPACE(std)vector findAllPartial(RefAST subtree); RefAST getFirstChild() const; RefAST getNextSibling() const; ANTLR_USE_NAMESPACE(std)string getText() const; int getType() const; void initialize(int t, const ANTLR_USE_NAMESPACE(std)string& txt); void initialize(RefAST t); void initialize(RefToken t); void initialize(ANTLR_USE_NAMESPACE(std)istream& infile); void setText(const ANTLR_USE_NAMESPACE(std)string& text); void setType(int ttype); ANTLR_USE_NAMESPACE(std)string toString() const; ANTLR_USE_NAMESPACE(std)string toStringList() const; ANTLR_USE_NAMESPACE(std)string toStringTree() const; bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const; void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ASTNULLType_hpp__ fwbuilder-5.1.0.3599/src/antlr/RecognitionException.cpp0000644000175000017500000000313511733011756023552 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/RecognitionException.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif RecognitionException::RecognitionException() : ANTLRException("parsing error") , line(-1) , column(-1) { } RecognitionException::RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s) : ANTLRException(s) , line(-1) , column(-1) { } RecognitionException::RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s, const ANTLR_USE_NAMESPACE(std)string& fileName_, int line_,int column_) : ANTLRException(s) , fileName(fileName_) , line(line_) , column(column_) { } ANTLR_USE_NAMESPACE(std)string RecognitionException::getFileLineColumnString() const { ANTLR_USE_NAMESPACE(std)string fileLineColumnString; if ( fileName.length() > 0 ) fileLineColumnString = fileName + ":"; if ( line != -1 ) { if ( fileName.length() == 0 ) fileLineColumnString = fileLineColumnString + "line "; fileLineColumnString = fileLineColumnString + line; if ( column != -1 ) fileLineColumnString = fileLineColumnString + ":" + column; fileLineColumnString = fileLineColumnString + ":"; } fileLineColumnString = fileLineColumnString + " "; return fileLineColumnString; } ANTLR_USE_NAMESPACE(std)string RecognitionException::toString() const { return getFileLineColumnString()+getMessage(); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/Token.cpp0000644000175000017500000000231211733011756020467 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/Token.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif int Token::getColumn() const { return 0; } int Token::getLine() const { return 0; } ANTLR_USE_NAMESPACE(std)string Token::getText() const { return ""; } int Token::getType() const { return type; } void Token::setColumn(int) { } void Token::setLine(int) { } void Token::setText(const ANTLR_USE_NAMESPACE(std)string&) { } void Token::setType(int t) { type = t; } void Token::setFilename(const ANTLR_USE_NAMESPACE(std)string&) { } ANTLR_USE_NAMESPACE(std)string emptyString(""); const ANTLR_USE_NAMESPACE(std)string& Token::getFilename() const { return emptyString; } ANTLR_USE_NAMESPACE(std)string Token::toString() const { return "[\""+getText()+"\",<"+type+">]"; } ANTLR_API RefToken nullToken; #ifndef NO_STATIC_CONSTS const int Token::MIN_USER_TYPE; const int Token::NULL_TREE_LOOKAHEAD; const int Token::INVALID_TYPE; const int Token::EOF_TYPE; const int Token::SKIP; #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CommonASTWithHiddenTokens.cpp0000644000175000017500000000333511733011756024351 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/config.hpp" #include "antlr/AST.hpp" #include "antlr/BaseAST.hpp" #include "antlr/CommonAST.hpp" #include "antlr/CommonASTWithHiddenTokens.hpp" #include "antlr/CommonHiddenStreamToken.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif const char* const CommonASTWithHiddenTokens::TYPE_NAME = "CommonASTWithHiddenTokens"; // RK: Do not put constructor and destructor into the header file here.. // this triggers something very obscure in gcc 2.95.3 (and 3.0) // missing vtables and stuff. // Although this may be a problem with with binutils. CommonASTWithHiddenTokens::CommonASTWithHiddenTokens() : CommonAST() { } CommonASTWithHiddenTokens::~CommonASTWithHiddenTokens() { } void CommonASTWithHiddenTokens::initialize(int t,const ANTLR_USE_NAMESPACE(std)string& txt) { CommonAST::initialize(t,txt); } void CommonASTWithHiddenTokens::initialize(RefAST t) { CommonAST::initialize(t); hiddenBefore = RefCommonASTWithHiddenTokens(t)->getHiddenBefore(); hiddenAfter = RefCommonASTWithHiddenTokens(t)->getHiddenAfter(); } void CommonASTWithHiddenTokens::initialize(RefToken t) { CommonAST::initialize(t); hiddenBefore = static_cast(t.get())->getHiddenBefore(); hiddenAfter = static_cast(t.get())->getHiddenAfter(); } RefAST CommonASTWithHiddenTokens::factory() { return RefAST(new CommonASTWithHiddenTokens); } RefAST CommonASTWithHiddenTokens::clone( void ) const { CommonASTWithHiddenTokens *ast = new CommonASTWithHiddenTokens( *this ); return RefAST(ast); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/ASTArray.hpp0000644000175000017500000000147211733011756021050 0ustar sylvestresylvestre#ifndef INC_ASTArray_hpp__ #define INC_ASTArray_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** ASTArray is a class that allows ANTLR to * generate code that can create and initialize an array * in one expression, like: * (new ASTArray(3))->add(x)->add(y)->add(z) */ class ANTLR_API ASTArray { public: int size; // = 0; ANTLR_USE_NAMESPACE(std)vector array; ASTArray(int capacity) : size(0) , array(capacity) { } ASTArray* add(RefAST node) { array[size++] = node; return this; } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ASTArray_hpp__ fwbuilder-5.1.0.3599/src/antlr/TreeParser.hpp0000644000175000017500000001023511733011756021473 0ustar sylvestresylvestre#ifndef INC_TreeParser_hpp__ #define INC_TreeParser_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API TreeParser { public: TreeParser() : astFactory(0) , inputState(new TreeParserInputState()) , traceDepth(0) { } TreeParser(const TreeParserSharedInputState& state) : astFactory(0) , inputState(state) , traceDepth(0) { } virtual ~TreeParser() { } /// Get the AST return value squirreled away in the parser virtual RefAST getAST() = 0; /** Make sure current lookahead symbol matches the given set * Throw an exception upon mismatch, which is caught by either the * error handler or by a syntactic predicate. */ virtual void match(RefAST t, const BitSet& b) { if ( !t || t==ASTNULL || !b.member(t->getType()) ) throw MismatchedTokenException( getTokenNames(), getNumTokens(), t, b, false ); } /** Specify the AST factory to be used during tree building. (Compulsory) * Setting the factory is compulsory (if you intend to modify * the tree in the treeparser). The AST Factory is shared between * parser (who builds the initial AST) and treeparser. * @see Parser::getASTFactory() */ virtual void setASTFactory(ASTFactory* factory) { astFactory = factory; } /// Return pointer to ASTFactory virtual ASTFactory* getASTFactory() const { return astFactory; } /// Get the name for token 'num' virtual const char* getTokenName(int num) const = 0; /// Return the number of tokens defined virtual int getNumTokens() const = 0; /// Return an array of getNumTokens() token names virtual const char* const* getTokenNames() const = 0; /// Parser error-reporting function can be overridden in subclass virtual void reportError(const RecognitionException& ex); /// Parser error-reporting function can be overridden in subclass virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s); /// Parser warning-reporting function can be overridden in subclass virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s); /// These are used during when traceTreeParser commandline option is passed. virtual void traceIndent(); virtual void traceIn(const char* rname, RefAST t); virtual void traceOut(const char* rname, RefAST t); /** The AST Null object; the parsing cursor is set to this when * it is found to be null. This way, we can test the * token type of a node without having to have tests for 0 * everywhere. */ static RefAST ASTNULL; protected: virtual void match(RefAST t, int ttype) { if (!t || t == ASTNULL || t->getType() != ttype ) throw MismatchedTokenException( getTokenNames(), getNumTokens(), t, ttype, false ); } virtual void matchNot(RefAST t, int ttype) { if ( !t || t == ASTNULL || t->getType() == ttype ) throw MismatchedTokenException( getTokenNames(), getNumTokens(), t, ttype, true ); } /** AST support code; parser and treeparser delegate to this object */ ASTFactory* astFactory; /// The input state of this tree parser. TreeParserSharedInputState inputState; /** Used to keep track of indent depth with -traceTreeParser */ int traceDepth; /** Utility class which allows tracing to work even when exceptions are * thrown. */ class Tracer { private: TreeParser* parser; const char* text; RefAST tree; public: Tracer(TreeParser* p, const char* t, RefAST a) : parser(p), text(t), tree(a) { parser->traceIn(text,tree); } ~Tracer() { parser->traceOut(text,tree); } private: Tracer(const Tracer&); // undefined const Tracer& operator=(const Tracer&); // undefined }; private: // no copying of treeparser instantiations... TreeParser(const TreeParser& other); TreeParser& operator=(const TreeParser& other); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TreeParser_hpp__ fwbuilder-5.1.0.3599/src/antlr/MismatchedTokenException.hpp0000644000175000017500000000577611733011756024373 0ustar sylvestresylvestre#ifndef INC_MismatchedTokenException_hpp__ #define INC_MismatchedTokenException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API MismatchedTokenException : public RecognitionException { public: MismatchedTokenException(); /// Expected range / not range MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefAST node_, int lower, int upper_, bool matchNot ); // Expected token / not token MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefAST node_, int expecting_, bool matchNot ); // Expected BitSet / not BitSet MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefAST node_, BitSet set_, bool matchNot ); // Expected range / not range MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefToken token_, int lower, int upper_, bool matchNot, const ANTLR_USE_NAMESPACE(std)string& fileName_ ); // Expected token / not token MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefToken token_, int expecting_, bool matchNot, const ANTLR_USE_NAMESPACE(std)string& fileName_ ); // Expected BitSet / not BitSet MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefToken token_, BitSet set_, bool matchNot, const ANTLR_USE_NAMESPACE(std)string& fileName_ ); ~MismatchedTokenException() throw() {} /** * Returns a clean error message (no line number/column information) */ ANTLR_USE_NAMESPACE(std)string getMessage() const; public: /// The token that was encountered const RefToken token; /// The offending AST node if tree walking const RefAST node; /// taken from node or token object ANTLR_USE_NAMESPACE(std)string tokenText; /// Types of tokens #ifndef NO_STATIC_CONSTS static const int TOKEN = 1; static const int NOT_TOKEN = 2; static const int RANGE = 3; static const int NOT_RANGE = 4; static const int SET = 5; static const int NOT_SET = 6; #else enum { TOKEN = 1, NOT_TOKEN = 2, RANGE = 3, NOT_RANGE = 4, SET = 5, NOT_SET = 6 }; #endif public: /// One of the above int mismatchType; /// For TOKEN/NOT_TOKEN and RANGE/NOT_RANGE int expecting; /// For RANGE/NOT_RANGE (expecting is lower bound of range) int upper; /// For SET/NOT_SET BitSet set; private: /// Token names array for formatting const char* const* tokenNames; /// Max number of tokens in tokenNames const int numTokens; /// Return token name for tokenType ANTLR_USE_NAMESPACE(std)string tokenName(int tokenType) const; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_MismatchedTokenException_hpp__ fwbuilder-5.1.0.3599/src/antlr/CommonAST.cpp0000644000175000017500000000165311733011756021216 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/config.hpp" #include #include #include "antlr/CommonAST.hpp" #include "antlr/ANTLRUtil.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif const char* const CommonAST::TYPE_NAME = "CommonAST"; #ifdef ANTLR_SUPPORT_XML void CommonAST::initialize( ANTLR_USE_NAMESPACE(std)istream& in ) { ANTLR_USE_NAMESPACE(std)string t1, t2, text; // text read_AttributeNValue( in, t1, text ); read_AttributeNValue( in, t1, t2 ); #ifdef ANTLR_ATOI_IN_STD int type = ANTLR_USE_NAMESPACE(std)atoi(t2.c_str()); #else int type = atoi(t2.c_str()); #endif // initialize first part of AST. this->initialize( type, text ); } #endif RefAST CommonAST::factory() { return RefAST(new CommonAST); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/MismatchedCharException.cpp0000644000175000017500000000606611733011756024154 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/CharScanner.hpp" #include "antlr/MismatchedCharException.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif MismatchedCharException::MismatchedCharException() : RecognitionException("Mismatched char") {} // Expected range / not range MismatchedCharException::MismatchedCharException( int c, int lower, int upper_, bool matchNot, CharScanner* scanner_ ) : RecognitionException("Mismatched char", scanner_->getFilename(), scanner_->getLine(), scanner_->getColumn()) , mismatchType(matchNot ? NOT_RANGE : RANGE) , foundChar(c) , expecting(lower) , upper(upper_) , scanner(scanner_) { } // Expected token / not token MismatchedCharException::MismatchedCharException( int c, int expecting_, bool matchNot, CharScanner* scanner_ ) : RecognitionException("Mismatched char", scanner_->getFilename(), scanner_->getLine(), scanner_->getColumn()) , mismatchType(matchNot ? NOT_CHAR : CHAR) , foundChar(c) , expecting(expecting_) , scanner(scanner_) { } // Expected BitSet / not BitSet MismatchedCharException::MismatchedCharException( int c, BitSet set_, bool matchNot, CharScanner* scanner_ ) : RecognitionException("Mismatched char", scanner_->getFilename(), scanner_->getLine(), scanner_->getColumn()) , mismatchType(matchNot ? NOT_SET : SET) , foundChar(c) , set(set_) , scanner(scanner_) { } ANTLR_USE_NAMESPACE(std)string MismatchedCharException::getMessage() const { ANTLR_USE_NAMESPACE(std)string s; switch (mismatchType) { case CHAR : s += "expecting '" + charName(expecting) + "', found '" + charName(foundChar) + "'"; break; case NOT_CHAR : s += "expecting anything but '" + charName(expecting) + "'; got it anyway"; break; case RANGE : s += "expecting token in range: '" + charName(expecting) + "'..'" + charName(upper) + "', found '" + charName(foundChar) + "'"; break; case NOT_RANGE : s += "expecting token NOT in range: " + charName(expecting) + "'..'" + charName(upper) + "', found '" + charName(foundChar) + "'"; break; case SET : case NOT_SET : { s += ANTLR_USE_NAMESPACE(std)string("expecting ") + (mismatchType == NOT_SET ? "NOT " : "") + "one of ("; ANTLR_USE_NAMESPACE(std)vector elems = set.toArray(); for ( unsigned int i = 0; i < elems.size(); i++ ) { s += " '"; s += charName(elems[i]); s += "'"; } s += "), found '" + charName(foundChar) + "'"; } break; default : s += RecognitionException::getMessage(); break; } return s; } #ifndef NO_STATIC_CONSTS const int MismatchedCharException::CHAR; const int MismatchedCharException::NOT_CHAR; const int MismatchedCharException::RANGE; const int MismatchedCharException::NOT_RANGE; const int MismatchedCharException::SET; const int MismatchedCharException::NOT_SET; #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/TreeParserSharedInputState.hpp0000644000175000017500000000207411733011756024645 0ustar sylvestresylvestre#ifndef INC_TreeParserSharedInputState_hpp__ #define INC_TreeParserSharedInputState_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This object contains the data associated with an * input AST. Multiple parsers * share a single TreeParserSharedInputState to parse * the same tree or to have the parser walk multiple * trees. */ class ANTLR_API TreeParserInputState { public: TreeParserInputState() : guessing(0) {} virtual ~TreeParserInputState() {} public: /** Are we guessing (guessing>0)? */ int guessing; //= 0; private: // we don't want these: TreeParserInputState(const TreeParserInputState&); TreeParserInputState& operator=(const TreeParserInputState&); }; typedef RefCount TreeParserSharedInputState; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TreeParserSharedInputState_hpp__ fwbuilder-5.1.0.3599/src/antlr/BaseAST.hpp0000644000175000017500000001073611733011756020647 0ustar sylvestresylvestre#ifndef INC_BaseAST_hpp__ #define INC_BaseAST_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API BaseAST; typedef ASTRefCount RefBaseAST; class ANTLR_API BaseAST : public AST { public: BaseAST() : AST() { } BaseAST(const BaseAST& other) : AST(other) { } virtual ~BaseAST() { } /// Return the class name virtual const char* typeName( void ) const = 0; /// Clone this AST node. virtual RefAST clone( void ) const = 0; /// Is node t equal to this in terms of token type and text? virtual bool equals(RefAST t) const; /** Is t an exact structural and equals() match of this tree. The * 'this' reference is considered the start of a sibling list. */ virtual bool equalsList(RefAST t) const; /** Is 't' a subtree of this list? The siblings of the root are NOT ignored. */ virtual bool equalsListPartial(RefAST t) const; /** Is tree rooted at 'this' equal to 't'? The siblings of 'this' are * ignored. */ virtual bool equalsTree(RefAST t) const; /** Is 't' a subtree of the tree rooted at 'this'? The siblings of * 'this' are ignored. */ virtual bool equalsTreePartial(RefAST t) const; /** Walk the tree looking for all exact subtree matches. Return * an ASTEnumerator that lets the caller walk the list * of subtree roots found herein. */ virtual ANTLR_USE_NAMESPACE(std)vector findAll(RefAST t); /** Walk the tree looking for all subtrees. Return * an ASTEnumerator that lets the caller walk the list * of subtree roots found herein. */ virtual ANTLR_USE_NAMESPACE(std)vector findAllPartial(RefAST t); /// Add a node to the end of the child list for this node virtual void addChild(RefAST c) { if( !c ) return; RefBaseAST tmp = down; if (tmp) { while (tmp->right) tmp = tmp->right; tmp->right = c; } else down = c; } /** Get the number of child nodes of this node (shallow e.g. not of the * whole tree it spans). */ virtual size_t getNumberOfChildren() const; /// Get the first child of this node; null if no children virtual RefAST getFirstChild() const { return RefAST(down); } /// Get the next sibling in line after this one virtual RefAST getNextSibling() const { return RefAST(right); } /// Get the token text for this node virtual ANTLR_USE_NAMESPACE(std)string getText() const { return ""; } /// Get the token type for this node virtual int getType() const { return 0; } /// Remove all children virtual void removeChildren() { down = static_cast(static_cast(nullAST)); } /// Set the first child of a node. virtual void setFirstChild(RefAST c) { down = static_cast(static_cast(c)); } /// Set the next sibling after this one. virtual void setNextSibling(RefAST n) { right = static_cast(static_cast(n)); } /// Set the token text for this node virtual void setText(const ANTLR_USE_NAMESPACE(std)string& /*UNUSED txt */) { } /// Set the token type for this node virtual void setType(int /*UNUSED type */) { } #ifdef ANTLR_SUPPORT_XML /** print attributes of this node to 'out'. Override to customize XML * output. * @param out the stream to write the AST attributes to. */ virtual bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const; /** Write this subtree to a stream. Overload this one to customize the XML * output for AST derived AST-types * @param output stream */ virtual void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const; #endif /// Return string representation for the AST virtual ANTLR_USE_NAMESPACE(std)string toString() const { return getText(); } /// Print out a child sibling tree in LISP notation virtual ANTLR_USE_NAMESPACE(std)string toStringList() const; virtual ANTLR_USE_NAMESPACE(std)string toStringTree() const; protected: RefBaseAST down; RefBaseAST right; private: void doWorkForFindAll(ANTLR_USE_NAMESPACE(std)vector& v, RefAST target, bool partialMatch); }; /** Is node t equal to this in terms of token type and text? */ inline bool BaseAST::equals(RefAST t) const { if (!t) return false; return ((getType() == t->getType()) && (getText() == t->getText())); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_BaseAST_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenWithIndex.hpp0000644000175000017500000000314411733011756022324 0ustar sylvestresylvestre#ifndef INC_TokenWithIndex_hpp__ #define INC_TokenWithIndex_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API TokenWithIndex : public ANTLR_USE_NAMESPACE(antlr)CommonToken { public: // static size_t count; TokenWithIndex() : CommonToken(), index(0) { // std::cout << __PRETTY_FUNCTION__ << std::endl; // count++; } TokenWithIndex(int t, const ANTLR_USE_NAMESPACE(std)string& txt) : CommonToken(t,txt) , index(0) { // std::cout << __PRETTY_FUNCTION__ << std::endl; // count++; } TokenWithIndex(const ANTLR_USE_NAMESPACE(std)string& s) : CommonToken(s) , index(0) { // std::cout << __PRETTY_FUNCTION__ << std::endl; // count++; } ~TokenWithIndex() { // count--; } void setIndex( size_t idx ) { index = idx; } size_t getIndex( void ) const { return index; } ANTLR_USE_NAMESPACE(std)string toString() const { return ANTLR_USE_NAMESPACE(std)string("[")+ index+ ":\""+ getText()+"\",<"+ getType()+">,line="+ getLine()+",column="+ getColumn()+"]"; } static RefToken factory() { return RefToken(new TokenWithIndex()); } protected: size_t index; private: TokenWithIndex(const TokenWithIndex&); const TokenWithIndex& operator=(const TokenWithIndex&); }; typedef TokenRefCount RefTokenWithIndex; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CommonToken_hpp__ fwbuilder-5.1.0.3599/src/antlr/Parser.cpp0000644000175000017500000000641411733011756020652 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/Parser.hpp" #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of * utility routines useful at any lookahead depth. We distinguish between * the LL(1) and LL(k) parsers because of efficiency. This may not be * necessary in the near future. * * Each parser object contains the state of the parse including a lookahead * cache (the form of which is determined by the subclass), whether or * not the parser is in guess mode, where tokens come from, etc... * *

* During guess mode, the current lookahead token(s) and token type(s) * cache must be saved because the token stream may not have been informed * to save the token (via mark) before the try block. * Guessing is started by: *

    *
  1. saving the lookahead cache. *
  2. marking the current position in the TokenBuffer. *
  3. increasing the guessing level. *
* * After guessing, the parser state is restored by: *
    *
  1. restoring the lookahead cache. *
  2. rewinding the TokenBuffer. *
  3. decreasing the guessing level. *
* * @see antlr.Token * @see antlr.TokenBuffer * @see antlr.TokenStream * @see antlr.LL1Parser * @see antlr.LLkParser */ bool DEBUG_PARSER = false; /** Parser error-reporting function can be overridden in subclass */ void Parser::reportError(const RecognitionException& ex) { ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Parser error-reporting function can be overridden in subclass */ void Parser::reportError(const ANTLR_USE_NAMESPACE(std)string& s) { if ( getFilename()=="" ) ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; else ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Parser warning-reporting function can be overridden in subclass */ void Parser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) { if ( getFilename()=="" ) ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; else ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; } /** Set or change the input token buffer */ // void setTokenBuffer(TokenBuffer* t); void Parser::traceIndent() { for( int i = 0; i < traceDepth; i++ ) ANTLR_USE_NAMESPACE(std)cout << " "; } void Parser::traceIn(const char* rname) { traceDepth++; for( int i = 0; i < traceDepth; i++ ) ANTLR_USE_NAMESPACE(std)cout << " "; ANTLR_USE_NAMESPACE(std)cout << "> " << rname << "; LA(1)==" << LT(1)->getText().c_str() << ((inputState->guessing>0)?" [guessing]":"") << ANTLR_USE_NAMESPACE(std)endl; } void Parser::traceOut(const char* rname) { for( int i = 0; i < traceDepth; i++ ) ANTLR_USE_NAMESPACE(std)cout << " "; ANTLR_USE_NAMESPACE(std)cout << "< " << rname << "; LA(1)==" << LT(1)->getText().c_str() << ((inputState->guessing>0)?" [guessing]":"") << ANTLR_USE_NAMESPACE(std)endl; traceDepth--; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/ANTLRUtil.cpp0000644000175000017500000000707311733011756021136 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** Eat whitespace from the input stream * @param is the stream to read from */ ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is ) { char c; while( is.get(c) ) { #ifdef ANTLR_CCTYPE_NEEDS_STD if( !ANTLR_USE_NAMESPACE(std)isspace(c) ) #else if( !isspace(c) ) #endif { is.putback(c); break; } } return is; } /** Read a string enclosed by '"' from a stream. Also handles escaping of \". * Skips leading whitespace. * @param in the istream to read from. * @returns the string read from file exclusive the '"' * @throws IOException if string is badly formatted */ ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in ) { char ch; ANTLR_USE_NAMESPACE(std)string ret(""); // States for a simple state machine... enum { START, READING, ESCAPE, FINISHED }; int state = START; eatwhite(in); while( state != FINISHED && in.get(ch) ) { switch( state ) { case START: // start state: check wether starting with " then switch to READING if( ch != '"' ) throw IOException("string must start with '\"'"); state = READING; continue; case READING: // reading state: look out for escape sequences and closing " if( ch == '\\' ) // got escape sequence { state = ESCAPE; continue; } if( ch == '"' ) // close quote -> stop { state = FINISHED; continue; } ret += ch; // else append... continue; case ESCAPE: switch(ch) { case '\\': ret += ch; state = READING; continue; case '"': ret += ch; state = READING; continue; case '0': ret += '\0'; state = READING; continue; default: // unrecognized escape is not mapped ret += '\\'; ret += ch; state = READING; continue; } } } if( state != FINISHED ) throw IOException("badly formatted string: "+ret); return ret; } /* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace. * @param in the istream to read from. */ ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in ) { char ch; ANTLR_USE_NAMESPACE(std)string ret(""); eatwhite(in); while( in.get(ch) ) { #ifdef ANTLR_CCTYPE_NEEDS_STD if( ANTLR_USE_NAMESPACE(std)isupper(ch) || ANTLR_USE_NAMESPACE(std)islower(ch) || ANTLR_USE_NAMESPACE(std)isdigit(ch) || ch == '_' ) #else if( isupper(ch) || islower(ch) || isdigit(ch) || ch == '_' ) #endif ret += ch; else { in.putback(ch); break; } } return ret; } /** Read a attribute="value" thing. Leading whitespace is skipped. * Between attribute and '=' no whitespace is allowed. After the '=' it is * permitted. * @param in the istream to read from. * @param attribute string the attribute name is put in * @param value string the value of the attribute is put in * @throws IOException if something is fishy. E.g. malformed quoting * or missing '=' */ void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in, ANTLR_USE_NAMESPACE(std)string& attribute, ANTLR_USE_NAMESPACE(std)string& value ) { attribute = read_identifier(in); char ch; if( in.get(ch) && ch == '=' ) value = read_string(in); else throw IOException("invalid attribute=value thing "+attribute); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/cisco_lib/0000755000175000017500000000000011733011756017513 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_iosacl_run.cpp0000644000175000017500000003553211733011756025373 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "CompilerDriver_iosacl.h" #include "AutomaticRules_iosacl.h" #include "PolicyCompiler_iosacl.h" #include "RoutingCompiler_iosacl.h" #include "OSConfigurator_ios.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManagerIOS.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; QString CompilerDriver_iosacl::assembleManifest(Cluster *, Firewall* , bool ) { QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); script << "!" << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]) << endl; return script_buffer; } QString CompilerDriver_iosacl::printActivationCommands(Firewall*) { return ""; } QString CompilerDriver_iosacl::assembleFwScript(Cluster *cluster, Firewall *fw, bool cluster_member, OSConfigurator *oscnf) { Configlet script_skeleton(fw, "cisco", "script_skeleton"); Configlet top_comment(fw, "cisco", "top_comment"); script_skeleton.setVariable("system_configuration_script", QString::fromUtf8(system_configuration_script.c_str())); script_skeleton.setVariable("policy_script", QString::fromUtf8(policy_script.c_str())); script_skeleton.setVariable("nat_script", QString::fromUtf8(nat_script.c_str())); script_skeleton.setVariable("routing_script", QString::fromUtf8(routing_script.c_str())); FWOptions* options = fw->getOptionsObject(); options->setStr("prolog_script", options->getStr("iosacl_prolog_script")); options->setStr("epilog_script", options->getStr("iosacl_epilog_script")); // we do not offer user a choice of the place where to put prolog // lines, therefore we can reset this attribute to make sure it // does not interfere options->setStr("prolog_place", ""); assembleFwScriptInternal(cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "!", true); return script_skeleton.expand(); } QString CompilerDriver_iosacl::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("")); /* Now that all checks are done, we can drop copies of cluster * interfaces that were added to the firewall by * CompilerDriver::populateClusterElements() */ list all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); list copies_of_cluster_interfaces; for (std::list::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) copies_of_cluster_interfaces.push_back(iface); } while (copies_of_cluster_interfaces.size()) { fw->remove(copies_of_cluster_interfaces.front()); copies_of_cluster_interfaces.pop_front(); } FWOptions* options = fw->getOptionsObject(); string fwvers = fw->getStr("version"); if (fwvers == "") fw->setStr("version", "12.1"); if (fwvers == "12.x") fw->setStr("version", "12.1"); string platform = fw->getStr("platform"); string clearACLCmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + fwvers + "/iosacl_commands/clear_ip_acl"); if (clearACLCmd.empty()) { // incorrect version. This could have happened if user converted // firewall platform. See bug #2662290 fw->setStr("version", "12.1"); } bool ios_acl_basic = options->getBool("ios_acl_basic"); bool ios_acl_no_clear = options->getBool("ios_acl_no_clear"); bool ios_acl_substitution = options->getBool("ios_acl_substitution"); bool ios_add_clear_statements = options->getBool("ios_add_clear_statements"); if ( !ios_acl_basic && !ios_acl_no_clear && !ios_acl_substitution ) { if ( ios_add_clear_statements ) options->setBool("ios_acl_basic",true); else options->setBool("ios_acl_no_clear",true); } std::auto_ptr oscnf(new OSConfigurator_ios(objdb, fw, false)); oscnf->prolog(); oscnf->processFirewallOptions(); list all_policies = fw->getByType(Policy::TYPENAME); try { AutomaticRules_iosacl auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() // NB: these ids are not used by this compiler assignUniqueRuleIds(all_policies); vector ipv4_6_runs; if (!single_rule_compile_on) system_configuration_script = safetyNetInstall(fw); NamedObjectsManagerIOS named_objects_manager(persistent_objects, fw); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } string clear_commands; string object_groups_definitions; for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); // Count rules for each address family int policy_count = 0; for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (policy_count) { std::auto_ptr prep(new Preprocessor(objdb, fw, false)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); } for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(policy_af)) continue; PolicyCompiler_iosacl c(objdb, fw, ipv6_policy, oscnf.get()); c.setNamedObjectsManager(&named_objects_manager); c.setSourceRuleSet( policy ); c.setRuleSetName(policy->getName()); c.setPersistentObjects(persistent_objects); c.setSingleRuleCompileMode(single_rule_id); if (inTestMode()) c.setTestMode(); if (inEmbeddedMode()) c.setEmbeddedMode(); c.setDebugLevel( dl ); if (rule_debug_on) c.setDebugRule( drp ); c.setVerbose( verbose ); if ( c.prolog() > 0 ) { c.compile(); c.epilog(); if (!single_rule_compile_on) { if (ipv6_policy) { policy_script += "\n\n"; policy_script += "! ================ IPv6\n"; policy_script += "\n\n"; } else { policy_script += "\n\n"; policy_script += "! ================ IPv4\n"; policy_script += "\n\n"; } } if (c.haveErrorsAndWarnings()) { all_errors.push_back(c.getErrors("").c_str()); } policy_script += c.getCompiledScript(); clear_commands += c.printClearCommands(); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in Policy"); } if (!ipv6_policy) { list all_routing = fw->getByType(Routing::TYPENAME); RuleSet *routing = RuleSet::cast(all_routing.front()); // currently routing is supported only for ipv4 RoutingCompiler_iosacl r(objdb, fw, false, oscnf.get()); r.setNamedObjectsManager(&named_objects_manager); r.setSourceRuleSet(routing); r.setRuleSetName(routing->getName()); r.setPersistentObjects(persistent_objects); r.setSingleRuleCompileMode(single_rule_id); if (inTestMode()) r.setTestMode(); if (inEmbeddedMode()) r.setEmbeddedMode(); r.setDebugLevel( dl ); if (rule_debug_on) r.setDebugRule( drp ); r.setVerbose( verbose ); if ( r.prolog() > 0 ) { r.compile(); r.epilog(); if (r.haveErrorsAndWarnings()) { all_errors.push_back(r.getErrors("").c_str()); } routing_script += r.getCompiledScript(); } else info(" Nothing to compile in Routing"); } } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } object_groups_definitions += named_objects_manager.getNamedObjectsDefinitions(); if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (object_groups_definitions + policy_script + routing_script).c_str())); } if ( fw->getOptionsObject()->getBool("iosacl_acl_basic") || fw->getOptionsObject()->getBool("iosacl_acl_substitution")) { clear_commands += named_objects_manager.getClearCommands() + "\n"; } system_configuration_script += clear_commands; system_configuration_script += object_groups_definitions; QString script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString ofname = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + ofname.toStdString()); QFile fw_file(ofname); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_iosacl_writers.cpp0000644000175000017500000004334711733011756026275 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_iosacl.h" #include "IOSObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include "PortRangeConverter.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Network.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; bool PolicyCompiler_iosacl::ClearACLs::processNext() { PolicyCompiler_iosacl *iosacl_comp=dynamic_cast(compiler); string vers = compiler->fw->getStr("version"); string platform = compiler->fw->getStr("platform"); string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+vers+"/iosacl_commands/clear_acl"); slurp(); if (tmp_queue.size()==0) return false; if ( compiler->fw->getOptionsObject()->getBool("iosacl_acl_basic") ) { compiler->output << clearACLcmd << endl; } if (compiler->fw->getOptionsObject()->getBool("iosacl_acl_substitution")) { for (map::iterator i=iosacl_comp->acls.begin(); i!=iosacl_comp->acls.end(); ++i) { ciscoACL *acl=(*i).second; compiler->output << clearACLcmd << " " << acl->workName() << endl; } compiler->output << endl; } if ( !compiler->fw->getOptionsObject()->getBool("iosacl_acl_no_clear") ) { string clearICMPcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+vers+"/iosacl_commands/clear_icmp"); string clearTelnetcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+vers+"/iosacl_commands/clear_telnet"); string clearSSHcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+vers+"/iosacl_commands/clear_ssh"); //compiler->output << clearICMPcmd << endl; //compiler->output << clearTelnetcmd << endl; //compiler->output << clearSSHcmd << endl; } return true; } void PolicyCompiler_iosacl::PrintCompleteACLs::printRulesForACL::operator()( Rule* rule) { // print rule if it belongs to ACL PolicyRule *prule = PolicyRule::cast(rule); string acl_name = prule->getStr("acl"); assert (acl_name!=""); ciscoACL *rule_acl = iosacl_comp->acls[acl_name]; assert(rule_acl!=NULL); if (acl == rule_acl) { *output << print_acl_p->_printRule(prule); } } bool PolicyCompiler_iosacl::PrintCompleteACLs::processNext() { PolicyCompiler_iosacl *iosacl_comp=dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; string addr_family_prefix = "ip"; if (iosacl_comp->ipv6) addr_family_prefix = "ipv6"; for (map::iterator i=iosacl_comp->acls.begin(); i!=iosacl_comp->acls.end(); ++i) { ciscoACL *acl=(*i).second; compiler->output << addr_family_prefix << " access-list "; if (!iosacl_comp->ipv6) compiler->output << "extended "; compiler->output<< acl->workName() << endl; std::for_each(tmp_queue.begin(), tmp_queue.end(), printRulesForACL(iosacl_comp, this, acl, &(compiler->output))); compiler->output << "exit" << endl; compiler->output << endl; } return true; } string PolicyCompiler_iosacl::PrintRule::_printRule(PolicyRule *rule) { PolicyCompiler_iosacl *iosacl_comp = dynamic_cast(compiler); string platform = compiler->fw->getStr("platform"); //FWOptions *ruleopt =rule->getOptionsObject(); bool write_comments = compiler->fw->getOptionsObject()->getBool( platform + "_include_comments"); ostringstream ruleout; ostringstream aclstr; if (write_comments) compiler->output << compiler->printComment( rule, current_rule_label1, iosacl_comp->comment_symbol); /* * all three rule elements contain exactly one object, which can * be either group (in case processor CreateObjectGroups created * object group for it) or a regular object */ RuleElementSrc *src=rule->getSrc(); RuleElementDst *dst=rule->getDst(); RuleElementSrv *srv=rule->getSrv(); assert(src->size()==1); assert(dst->size()==1); assert(srv->size()==1); FWObject *srcobj = src->front(); FWObject *dstobj = dst->front(); FWObject *srvobj = srv->front(); assert(srcobj); assert(dstobj); assert(srvobj); if (FWReference::cast(srcobj)!=NULL) { srcobj=FWReference::cast(srcobj)->getPointer(); assert(srcobj); } if (FWReference::cast(dstobj)!=NULL) { dstobj=FWReference::cast(dstobj)->getPointer(); assert(dstobj); } if (FWReference::cast(srvobj)!=NULL) { srvobj=FWReference::cast(srvobj)->getPointer(); assert(srvobj); } string acl_name=rule->getStr("acl"); assert (acl_name!=""); ciscoACL *acl = iosacl_comp->acls[acl_name]; assert(acl!=NULL); /* * Assemble ACL command in aclstr */ aclstr << _printAction(rule); IOSObjectGroup *pgsrc = IOSObjectGroup::cast(srcobj); IOSObjectGroup *pgdst = IOSObjectGroup::cast(dstobj); IOSObjectGroup *pgsrv = IOSObjectGroup::cast(srvobj); /* * Possible configurations: * * permit object-group service_group object-group src_grp object-group dst_grp * permit object-group service_group SRC_SPEC DST_SPEC * permit SRC_SPEC DST_SPEC * * Where SRC_SPEC and DST_SPEC are * obejct-group network_group * or traidtional
* */ if ( pgsrv!=NULL && pgsrv->isServiceGroup()) { aclstr << "object-group " << pgsrv->getName(); aclstr << " "; if ( pgsrc!=NULL && pgsrc->isObjectGroup()) { aclstr << "object-group " << pgsrc->getName(); aclstr << " "; } else { aclstr << _printAddr( compiler->getFirstSrc(rule) ); } if ( pgdst!=NULL && pgdst->isObjectGroup()) { aclstr << "object-group " << pgdst->getName(); aclstr << " "; } else { aclstr << _printAddr( compiler->getFirstDst(rule) ); } } else { // Service is not object group aclstr << _printProtocol(Service::cast(srvobj)); aclstr << " "; if ( pgsrc!=NULL && pgsrc->isObjectGroup()) { aclstr << "object-group " << pgsrc->getName(); aclstr << " "; } else { aclstr << _printAddr( compiler->getFirstSrc(rule) ); } aclstr << _printSrcService( compiler->getFirstSrv(rule) ); if ( pgdst!=NULL && pgdst->isObjectGroup()) { aclstr << "object-group " << pgdst->getName(); aclstr << " "; } else { aclstr << _printAddr( compiler->getFirstDst(rule) ); } aclstr << _printDstService( compiler->getFirstSrv(rule) ); } aclstr << _printLog( rule ); // "fragments" should be the last option in the access-list command aclstr << _printIPServiceOptions(rule); // Note that option "use_acl_remarks" is set in prolog() because // we use different options for this function in GUI dialogs for // iosacl and procurve. This is historical. if (compiler->fw->getOptionsObject()->getBool("use_acl_remarks")) { ruleout << acl->addRemark(rule->getLabel(), rule->getComment()); } ruleout << acl->addLine(aclstr.str()); return ruleout.str(); } string PolicyCompiler_iosacl::PrintRule::_printAction(PolicyRule *rule) { ostringstream str; switch (rule->getAction()) { case PolicyRule::Accept: str << "permit "; break; case PolicyRule::Deny: str << "deny "; break; case PolicyRule::Reject: str << "deny "; break; default: str << rule->getActionAsString() << " "; } return str.str(); } string PolicyCompiler_iosacl::PrintRule::_printACL(PolicyRule *rule) { // PolicyCompiler_iosacl *iosacl_comp=dynamic_cast(compiler); string acl_name=rule->getStr("acl"); assert (acl_name!=""); return acl_name+" "; } string PolicyCompiler_iosacl::PrintRule::_printLog(PolicyRule *rule) { if (rule->getLogging()) { FWOptions *ruleopt =rule->getOptionsObject(); if (ruleopt->getBool("iosacl_log_input")) return "log-input "; return "log "; } return ""; } string PolicyCompiler_iosacl::PrintRule::_printPortRangeOp(int rs, int re) { return PortRangeConverter(rs, re).toString(); } string PolicyCompiler_iosacl::PrintRule::_printSrcService(Service *srv) { if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getSrcRangeStart(); int re = TCPUDPService::cast(srv)->getSrcRangeEnd(); return _printPortRangeOp(rs, re); } return ""; } string PolicyCompiler_iosacl::PrintRule::_printIPServiceOptions(PolicyRule *r) { Service *srv = compiler->getFirstSrv(r); const IPService *ip; if ((ip=IPService::constcast(srv))!=NULL) { string version = compiler->fw->getStr("version"); if (srv->getBool("fragm") || srv->getBool("short_fragm")) return "fragments "; if (ip->hasIpOptions() && XMLTools::version_compare(version, "12.4")<0) compiler->abort(r, "IP options match requires IOS v12.4 or later."); if (ip->getBool("lsrr")) return "option lsr"; if (ip->getBool("ssrr")) return "option ssr"; if (ip->getBool("rr")) return "option record-route"; if (ip->getBool("rtralt")) return "option router-alert"; if (ip->getBool("any_opt")) return "option any-options "; string tos = ip->getTOSCode(); string dscp = ip->getDSCPCode(); if (!dscp.empty()) return string("dscp ") + dscp; else if (!tos.empty()) return string("tos ") + tos; } return ""; } string PolicyCompiler_iosacl::PrintRule::_printDstService(Service *srv) { ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getDstRangeStart(); int re = TCPUDPService::cast(srv)->getDstRangeEnd(); str << _printPortRangeOp(rs, re); } if (TCPService::isA(srv)) { if (srv->getBool("established")) str << "established "; else str << _printTCPFlags(TCPService::cast(srv)); } if ((ICMPService::isA(srv) || ICMP6Service::isA(srv)) && srv->getInt("type")!=-1) { str << srv->getStr("type") << " "; } if (CustomService::isA(srv)) str << CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ) << " "; return str.str(); } string PolicyCompiler_iosacl::PrintRule::getTcpFlagName(const TCPService::TCPFlag f) { switch (f) { case TCPService::URG: return "urg"; case TCPService::ACK: return "ack"; case TCPService::PSH: return "psh"; case TCPService::RST: return "rst"; case TCPService::SYN: return "syn"; case TCPService::FIN: return "fin"; default: return ""; } return ""; } string PolicyCompiler_iosacl::PrintRule::_printTCPFlags(TCPService *srv) { if (srv->inspectFlags()) { // We check the version and call compiler->abort() if its // wrong in SpecialServices rule processor. Here we should just execute. string version = compiler->fw->getStr("version"); if (XMLTools::version_compare(version, "12.4")>=0) { std::set flags = srv->getAllTCPFlags(); std::set masks = srv->getAllTCPFlagMasks(); std::set::iterator mit = masks.begin(); QStringList match_specs; for (; mit!=masks.end(); mit++) { if (flags.count(*mit) > 0) match_specs.push_back(QString("+%1").arg(getTcpFlagName(*mit).c_str())); else match_specs.push_back(QString("-%1").arg(getTcpFlagName(*mit).c_str())); } if (!match_specs.empty()) match_specs.push_front("match-all"); return match_specs.join(" ").toStdString() + " "; } } return ""; } string PolicyCompiler_iosacl::PrintRule::_printProtocol(Service *srv) { PolicyCompiler_iosacl *iosacl_comp = dynamic_cast( compiler); string addr_family_prefix = "ip "; if (iosacl_comp->ipv6) addr_family_prefix = "ipv6 "; string proto = srv->getProtocolName(); if (ICMP6Service::isA(srv)) proto = "icmp"; if (CustomService::isA(srv)) { // special case standard CusctomService objects "ESTABLISHED" // and "ESTABLISHED ipv6": these require protocol "tcp" but // protocol is set in the Custom Service object for all // platforms at once, so we can't have protocol defined only // for iosacl to be used here. string srv_code = CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName()); if (srv_code == "established") proto = "tcp"; } if (proto=="ip") return addr_family_prefix; return proto + " "; } string PolicyCompiler_iosacl::PrintRule::_printAddr(Address *o) { PolicyCompiler_iosacl *iosacl_comp = dynamic_cast(compiler); if (Interface::cast(o)!=NULL) { Interface *interface_ = Interface::cast(o); if (interface_->isDyn()) { return string("interface ") + interface_->getLabel() + " "; } } ostringstream str; const InetAddr *srcaddr = o->getAddressPtr(); if (srcaddr) { const InetAddr *nm = o->getNetmaskPtr(); InetAddr srcmask; if (nm != NULL) { srcmask = *nm; } else { cerr << "Address object " << o << " " << o->getName() << " (" << o->getTypeName() << ") " << " has no netmask" << endl; srcmask = InetAddr(InetAddr::getAllOnes(srcaddr->addressFamily())); } // const InetAddr srcmask = *(o->getNetmaskPtr()); if (srcaddr->isAny() && srcmask.isAny()) { str << "any "; } else { if (Interface::cast(o)==NULL && Interface::cast(o->getParent())==NULL && o->dimension() > 1 && !srcmask.isHostMask()) { if (iosacl_comp->ipv6) { str << srcaddr->toString() << "/" << srcmask.getLength() << " "; } else { str << srcaddr->toString() << " "; // cisco uses "wildcards" instead of netmasks //long nm = srcmask.to32BitInt(); //struct in_addr na; //na.s_addr = ~nm; InetAddr nnm( ~srcmask ); str << nnm.toString() << " "; } } else { str << "host " << srcaddr->toString() << " "; } } return str.str(); } ostringstream errstr; errstr << "Object " << o->getName() << " (id=" << o->getId() << ") " << " has no ip address and can not be used " << "in the rule."; compiler->abort(errstr.str()); return ""; // to make compiler happy } /* * the following additional attributes should have been defined by now: * * "acl" - string, name of the access list * choices are: outside-in, outside-out, inside-in, indside-out, * dmz-in, dmz-out etc. * General rule for the acl name: "iface_name-{in,out}" */ bool PolicyCompiler_iosacl::PrintRule::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); compiler->output << _printRule(rule); return true; } fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManagerIOS.cpp0000644000175000017500000000330111733011756024420 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NamedObjectsManagerIOS.h" #include "NamedObject.h" #include "BaseObjectGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Library.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; NamedObjectsManagerIOS::NamedObjectsManagerIOS(Library *po, Firewall *fw) : NamedObjectsManager(po, fw) { } NamedObjectsManagerIOS::~NamedObjectsManagerIOS() { } string NamedObjectsManagerIOS::getClearCommands() { ostringstream output; FWObject *object_groups = getObjectGroupsGroup(); for (FWObject::iterator i=object_groups->begin(); i!=object_groups->end(); ++i) { BaseObjectGroup *og = dynamic_cast(*i); assert(og!=NULL); output << "no " << og->getObjectGroupHeader() << endl; } return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/splitByNetworkZonesForRE.h0000644000175000017500000000327011733011756024603 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SPLIT_BY_NETWORK_ZONES_FOR_RE_HH #define __SPLIT_BY_NETWORK_ZONES_FOR_RE_HH #include "fwbuilder/RuleElement.h" #include "fwcompiler/RuleProcessor.h" namespace libfwbuilder { class Address; class Rule; }; namespace fwcompiler { /** * this processor splits rules if objects in rule element * re_type belong to different network zones */ class splitByNetworkZonesForRE : public BasicRuleProcessor { std::string re_type; std::map rules; void AddToInterface(int interface_id, libfwbuilder::Address *addr, libfwbuilder::Rule *rule); public: splitByNetworkZonesForRE(const std::string &name,const std::string &_type) : BasicRuleProcessor(name) {re_type=_type; } virtual bool processNext(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/PIXObjectGroup.cpp0000644000175000017500000001072111733011756023024 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PIXObjectGroup.h" #include "fwbuilder/Address.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; const char *PIXObjectGroup::TYPENAME={"PIXObjectGroup"}; QString PIXObjectGroup::groupMemberToString(FWObject *obj, NamedObjectsManager*) throw(libfwbuilder::FWException) { ostringstream ostr; if (this->getObjectGroupType() == NETWORK) { Address *a = Address::cast(obj); assert(a!=NULL); const InetAddr *addr = a->getAddressPtr(); ostr << "network-object "; if (Network::cast(obj)!=NULL) { const InetAddr *mask = a->getNetmaskPtr(); ostr << addr->toString() << " "; ostr << mask->toString() << " "; } else { ostr << "host "; ostr << addr->toString() << " "; } return ostr.str().c_str(); } else { if (IPService::isA(obj)) { ostr << "protocol-object "; Service *s=Service::cast(obj); assert(s!=NULL); ostr << s->getProtocolName(); return ostr.str().c_str(); } if (ICMPService::isA(obj)) { ostr << "icmp-object "; ICMPService *s=ICMPService::cast(obj); assert(s!=NULL); if ( s->getInt("type")== -1) ostr << "any"; else ostr << s->getInt("type"); return ostr.str().c_str(); } if (TCPService::isA(obj) || UDPService::isA(obj)) { ostr << "port-object "; Service *s=Service::cast(obj); assert(s!=NULL); int rs=TCPUDPService::cast(s)->getDstRangeStart(); int re=TCPUDPService::cast(s)->getDstRangeEnd(); if (rs<0) rs=0; if (re<0) re=0; if (rs>0 || re>0) { if (rs==re) ostr << "eq " << rs; else ostr << "range " << rs << " " << re; } else ostr << "range 0 65535"; return ostr.str().c_str(); } QString err("PIXObjectGroup: Unsupported object '%1' found in " "object group"); throw FWException(err.arg(obj->getName().c_str()).toStdString()); } return ostr.str().c_str(); } string PIXObjectGroup::getObjectGroupClass() { switch (this->getObjectGroupType()) { case NETWORK: return "network"; case PROTO: return "protocol"; case ICMP_TYPE: return "icmp-type"; case TCP_SERVICE: return "service"; case UDP_SERVICE: return "service"; case TCP_UDP_SERVICE: return "service"; case MIXED_SERVICE: return "service";; default: { QString err("PIXObjectGroup::getObjectGroupClass(): Unknown object " "group type '%1'"); throw FWException(err.arg(this->getObjectGroupType()).toStdString()); } } } string PIXObjectGroup::getObjectGroupHeader() { ostringstream ostr; ostr << "object-group " << getObjectGroupClass() << " " << this->getName(); switch (this->getObjectGroupType()) { case TCP_SERVICE: ostr << " tcp"; break; case UDP_SERVICE: ostr << " udp"; break; case TCP_UDP_SERVICE: ostr << " tcp-udp"; break; default: break; } return ostr.str(); } string PIXObjectGroup::getObjectGroupFooter() { return "exit"; } fwbuilder-5.1.0.3599/src/cisco_lib/IOSObjectGroup.h0000644000175000017500000000276611733011756022475 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IOSOBJECTGROUP_HH #define __IOSOBJECTGROUP_HH #include "BaseObjectGroup.h" namespace fwcompiler { class IOSObjectGroup : public BaseObjectGroup { public: IOSObjectGroup() : BaseObjectGroup() { } virtual ~IOSObjectGroup() {}; DECLARE_FWOBJECT_SUBTYPE(IOSObjectGroup); virtual std::string getObjectGroupClass(); virtual std::string getObjectGroupHeader(); virtual std::string getObjectGroupFooter(); virtual QString groupMemberToString( libfwbuilder::FWObject *obj, NamedObjectsManager *named_obj_manager) throw(libfwbuilder::FWException); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_pix_os.h0000644000175000017500000000663711733011756024165 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSNETWORKCONFIGURATOR_PIX_OS_HH #define _OSNETWORKCONFIGURATOR_PIX_OS_HH #include "config.h" #include "fwcompiler/OSConfigurator.h" #include #include class Configlet; namespace libfwbuilder { class ClusterGroup; }; namespace fwcompiler { class OSConfigurator_pix_os : public OSConfigurator { //std::string _printNameif(); //std::string _printIPAddress(); void _getFailoverAddresses(libfwbuilder::ClusterGroup *cluster_group, QString *primary_addr, QString *primary_netm, QString *standby_addr); void _getAddressConfigurationForInterface(libfwbuilder::Interface *iface, QString *addr, QString *netm, QString *standby_addr); std::string _printInterfaceConfiguration(); std::string _printFailoverConfiguration(); std::string _printLogging(); void _configureSNMPServer(Configlet *cnf, int server_num, const std::string &srv, int poll_trap); void _configureNTPServer(Configlet *cnf, int server_num, const std::string &server, bool pref); std::string _printSNMP(); std::string _printSysopt(); std::string _printNTP(); std::string _printServiceTimeout(const std::string &pix_service); std::string _printTimeouts(); std::string _printSSHConfiguration(); std::string _printFixupCommand(const std::string &fixup_name, const std::string &sw, int arg1, int arg2, bool ov); std::string _printFixups(); std::string _printMPFPolicyMap(); std::string _printPolicyMapTypeInspect(); public: virtual ~OSConfigurator_pix_os() {}; OSConfigurator_pix_os(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual void processFirewallOptions(); virtual void addVirtualAddressForNAT(const libfwbuilder::Address *addr); virtual void addVirtualAddressForNAT(const libfwbuilder::Network *nw); std::string getProtocolInspectionCommands(); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManagerPIX.h0000644000175000017500000000260611733011756024102 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _NAMED_OBJECTS_MANAGER_PIX_HH #define _NAMED_OBJECTS_MANAGER_PIX_HH #include "config.h" #include "NamedObjectsManager.h" namespace libfwbuilder { class Group; class Firewall; class Library; }; namespace fwcompiler { class NamedObjectsManagerPIX : public NamedObjectsManager { public: NamedObjectsManagerPIX(libfwbuilder::Library *persistent_objects, libfwbuilder::Firewall *_fw); virtual ~NamedObjectsManagerPIX(); virtual std::string getClearCommands(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_cisco.h0000644000175000017500000001051111733011756024164 0ustar sylvestresylvestre/* * Copyright (c) 2008 Steven Mestdagh * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __ROUTINGCOMPILER_CISCO_HH__ #define __ROUTINGCOMPILER_CISCO_HH__ #include #include "fwcompiler/RoutingCompiler.h" #include "fwbuilder/RuleElement.h" #include "config.h" #include "NamedObjectsAndGroupsSupport.h" namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_cisco : public RoutingCompiler { protected: NamedObjectsManager *named_objects_manager; /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls RoutingCompiler::debugPrintRule */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); /** * processes rules with negation in Dst if it holds only one object */ DECLARE_ROUTING_RULE_PROCESSOR(singleDstNegation); /** * processes rules with negation in Dst */ DECLARE_ROUTING_RULE_PROCESSOR(DstNegation); /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInDST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInDST(const std::string &name) : eliminateDuplicatesInRE(name, libfwbuilder::RuleElementRDst::TYPENAME) {} }; /** * eliminates duplicate rules */ class eliminateDuplicateRules : public RoutingRuleProcessor { std::map rules_seen_so_far; std::map::iterator rules_it; public: eliminateDuplicateRules(const std::string &name) : RoutingRuleProcessor(name) {} virtual bool processNext(); }; /** * prints single policy rule, assuming all groups have been * expanded, destination holds exactly one object, and this * object is not a group. Negation should also have been taken * care of before this method is called. * * This processor is not necessarily the last in the * conveyor, so it should push rules back to tmp_queue (for * example there could be progress indicator processor after * this one) */ class PrintRule : public RoutingRuleProcessor { protected: std::string current_rule_label; virtual std::string _printAddr(libfwbuilder::Address *o); public: PrintRule(const std::string &name); virtual bool processNext(); virtual std::string RoutingRuleToString(libfwbuilder::RoutingRule *r); virtual std::string _printRGtw(libfwbuilder::RoutingRule *r); virtual std::string _printRItf(libfwbuilder::RoutingRule *r); virtual std::string _printRDst(libfwbuilder::RoutingRule *r); }; friend class RoutingCompiler_cisco::PrintRule; public: RoutingCompiler_cisco::PrintRule *printRule; RoutingCompiler_cisco(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler(_db, fw, ipv6_policy, _oscnf) {} virtual int prolog(); virtual void compile(); void setNamedObjectsManager(NamedObjectsManager *mgr); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_pix_v6_acls.cpp0000644000175000017500000003174511733011756025460 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Rule processors in this module build ACLs for PIX v6 they employ number of assumptions that are only valid for PIX <7.0 */ #include "config.h" #include "PolicyCompiler_pix.h" #include "NATCompiler_pix.h" #include "PIXObjectGroup.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; bool PolicyCompiler_pix::InterfaceAndDirection_v6::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); bool icmp_cmd = rule->getBool("icmp_cmd"); bool tcp_service_to_fw = rule->getBool("tcp_service_to_fw"); // int interface_id = rule->getInterfaceId(); RuleElementItf *intf_re = rule->getItf(); if (rule->getDirection()==PolicyRule::Undefined) rule->setDirection( PolicyRule::Both ); if (intf_re->isAny() && rule->getDirection()==PolicyRule::Both) return true; if (intf_re->isAny() && !icmp_cmd && !tcp_service_to_fw && ( rule->getDirection()==PolicyRule::Inbound || rule->getDirection()==PolicyRule::Outbound) ) compiler->abort(rule, "Direction set without interface"); return true; } /* * rules with direction 'both' associated with an interface are split * and copies are assigned directions Inbound and Outbound * * rules with direction 'both' not associated with any interface are * simply converted to "Inbound". This is because we only generate * outbound ACLs for rules that explicitly were defined by the user * with direction "Outbound"; everything else is implemented using * inbound ACLs * * 04/21/06 --vk */ bool PolicyCompiler_pix::SplitDirection_v6::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; // FWObject *rule_iface = compiler->dbcopy->findInIndex(rule->getInterfaceId()); RuleElementItf *intf_re = rule->getItf(); if (rule->getDirection()==PolicyRule::Both) { if ( ! intf_re->isAny()) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection(PolicyRule::Inbound); tmp_queue.push_back(r); r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection(PolicyRule::Outbound); tmp_queue.push_back(r); } else { rule->setDirection(PolicyRule::Inbound); tmp_queue.push_back(rule); } } else tmp_queue.push_back(rule); return true; } /** * this processor emulates outbound ACL by splitting a rule onto * several rules and assigning them to interfaces. This processor * works only with rules that have direction "Outbound" and have * interface specified. * * Prerequisities: * * Rule should have been split before this processor is called if * objects in src and/or dst belong to different network zones * * * Internet ("any") * ^ * | * | i4 * +----------+ * i1| |i3 * ---------------+ PIX +---------------- * host1 | | host3 * +----------+ * |i2 * | * |host2 * * src dst interface * * h1 h2 i2 change interface to i1 * any h2 i2 split, use all interfaces but i2 * h1 any i2 change interface to i1 * any any i2 split, use all interfaces but i2 * * * FWSM v2.3 and beyond, as well as PIX 7.0, support outbound ACLs * (via "access-group out ..." command) We do not need to do this * for these platforms. */ bool PolicyCompiler_pix::EmulateOutboundACL_v6::processNext() { Helper helper(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; // FWObject *rule_iface = compiler->dbcopy->findInIndex(rule->getInterfaceId()); RuleElementItf *intf_re = rule->getItf(); FWObject *rule_iface = FWObjectReference::getObject(intf_re->front()); if (rule->getDirection()==PolicyRule::Outbound && ! intf_re->isAny()) { if ( compiler->fw->getOptionsObject()->getBool("pix_emulate_out_acl") ) { RuleElementSrc *src = rule->getSrc(); assert(src); RuleElementDst *dst = rule->getDst(); assert(dst); try { if (!src->isAny()) { int iface1_id = helper.findInterfaceByNetzone( compiler->getFirstSrc(rule) ); /* special case: interface detected via comparison of src and the * network zone is the same as the one this rule is assigned to, but * direction is Outbound - drop this rule */ if (iface1_id == rule_iface->getId()) { compiler->warning(rule, "Rule with direction 'Outbound' was suppressed " "because generation of outbound access lists " "is turned off in firewall object settings" ); return true; } // rule->setInterfaceId(iface1_id); intf_re->reset(); intf_re->addRef(compiler->dbcopy->findInIndex(iface1_id)); rule->setDirection(PolicyRule::Inbound); tmp_queue.push_back(rule); } else { int iface2_id; iface2_id = helper.findInterfaceByNetzone( compiler->getFirstDst(rule) ); list l2 = compiler->fw->getByTypeDeep( Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { if ( (*i)->getId()==iface2_id ) continue; PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); // r->setInterfaceId((*i)->getId()); RuleElementItf *itf_re = r->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(*i); rule->setDirection(PolicyRule::Inbound); tmp_queue.push_back(r); } } } catch (string addr) { ostringstream str; str << "Can not find interface to assign rule " << rule->getLabel() << ": " << endl << "Address " << addr << " does not match address or network zone of any interface" << endl; compiler->abort(rule, str.str()); } } else compiler->abort( rule, "Outbound ACLs are not supported and emulation is " "not activated"); } else tmp_queue.push_back(rule); return true; } /** * this processor assigns rules to interfaces (since PIX only * supports ACLs on interfaces and direction can only be "inbound"). * * * Internet ("any") * ^ * | * | i4 * +----------+ * i1| |i3 * ---------------+ PIX +---------------- * host1 | | host3 * +----------+ * |i2 * | * |host2 * * src dst assign to interface * * any i1 i1 * any i2 i2 * any i3 i3 * any i4 i4 * any host2 all * host1 host2 i1 * host1 any i1 * any any all */ bool PolicyCompiler_pix::assignRuleToInterface_v6::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; Helper helper(compiler); RuleElementSrc *src = rule->getSrc(); assert(src); RuleElementDst *dst = rule->getDst(); assert(dst); RuleElementItf *intf_re = rule->getItf(); // FWObject *rule_iface = FWObjectReference::getObject(intf_re->front()); if (intf_re->isAny()) { try { if (! src->isAny() ) { Address *a = compiler->getFirstSrc(rule); int iface1_id = helper.findInterfaceByNetzone(a); // rule->setInterfaceId(iface1_id); intf_re->reset(); intf_re->addRef(compiler->dbcopy->findInIndex(iface1_id)); tmp_queue.push_back(rule); } else { Address *a=compiler->getFirstDst(rule); if ( ! dst->isAny() && compiler->complexMatch(a,compiler->fw)) { int iface2_id = helper.findInterfaceByNetzone( a ); // rule->setInterfaceId(iface2_id); intf_re->reset(); intf_re->addRef(compiler->dbcopy->findInIndex(iface2_id)); rule->setStr("direction","Inbound"); tmp_queue.push_back(rule); return true; } list l2 = compiler->fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *intf = Interface::cast(*i); if (intf->isUnprotected()) continue; if (intf->getOptionsObject()->getBool("cluster_interface")) continue; PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); // r->setInterfaceId(intf->getId()); RuleElementItf *itf_re = r->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(intf); r->setStr("direction","Inbound"); tmp_queue.push_back(r); } } } catch (string addr) { ostringstream str; str << "Can not find interface to assign rule " << rule->getLabel() << ": " << endl << "Address " << addr << " does not match address or network zone of any interface" << endl; compiler->abort(rule, str.str()); } } else { tmp_queue.push_back(rule); } return true; } /* * This processor is called after emulateOutboundACL */ bool PolicyCompiler_pix::pickACL_v6::processNext() { PolicyCompiler_pix *pix_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; // Interface *rule_iface = Interface::cast(compiler->dbcopy->findInIndex(rule->getInterfaceId())); RuleElementItf *intf_re = rule->getItf(); Interface *rule_iface = Interface::cast( FWObjectReference::getObject(intf_re->front())); if (intf_re->isAny() || rule_iface==NULL) compiler->abort(rule, "Missing interface assignment"); string acl_name = rule_iface->getLabel() + "_acl_in"; rule->setStr("acl", acl_name); ciscoACL *acl = new ciscoACL(acl_name, rule_iface, "in"); pix_comp->acls[acl_name] = acl; acl->setWorkName(acl_name); tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_procurve_acl.h0000644000175000017500000000432111733011756025356 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_PROCURVE_ACL_HH__ #define __COMPILER_DRIVER_PROCURVE_ACL_HH__ #include "CompilerDriver_iosacl.h" #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; }; namespace fwcompiler { class CompilerDriver_procurve_acl : public CompilerDriver_iosacl { protected: void printProlog(QTextStream &file, const std::string &prolog_code); virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); virtual QString assembleFwScript(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf); public: CompilerDriver_procurve_acl(libfwbuilder::FWObjectDatabase *db); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_asa8.cpp0000644000175000017500000003731211733011756023256 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_asa8.h" #include "NamedObject.h" #include "ASA8ObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Network.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; NATCompiler_asa8::NATCompiler_asa8(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf) : NATCompiler_pix(_db, fw, ipv6_policy, _oscnf) { } NATCompiler_asa8::~NATCompiler_asa8() { } /* * Option "translate dns" can not be used if the rule has "destination" * part. */ bool NATCompiler_asa8::VerifyValidityOfDNSOption::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ropt = rule->getOptionsObject(); if (ropt->getBool("asa8_nat_dns")) { Address *odst = compiler->getFirstODst(rule); assert(odst); if (!odst->isAny()) { compiler->abort(rule, "Option 'translate dns' can not be used in combination " "with destination matching or translation"); } Service *osrv = compiler->getFirstOSrv(rule); assert(osrv); if (!osrv->isAny()) { compiler->abort(rule, "Option 'translate dns' can not be used in combination " "with service matching or translation"); } } tmp_queue.push_back(rule); return true; } /* * After we call CreateObjectGroupsForTSrc to create object group for * TSrc, it can be one of the following: * * - any * - single address * - single group (object group that was created by CreateObjectGroupsForTSrc) * - an address and interface * - a group and interface * * CreateObjectGroups::processNext() always puts interface first and group or * address second in TSrc */ bool NATCompiler_asa8::VerifyValidityOfTSrc::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementTSrc *tsrc_re = rule->getTSrc(); assert(tsrc_re); if (tsrc_re->isAny()) return true; if (tsrc_re->size()==1) return true; if (tsrc_re->size()==2) { FWObject *obj1 = NULL; FWObject *obj2 = NULL; for (FWObject::iterator it=tsrc_re->begin(); it!=tsrc_re->end(); ++it) { if (obj1 == NULL) obj1 = FWReference::getObject(*it); if (obj2 == NULL) obj2 = FWReference::getObject(*it); } if (Interface::isA(obj1) && Address::cast(obj2)!=NULL) return true; if (Interface::isA(obj1) && Group::cast(obj2)!=NULL) return true; QString err("Invalid combination of objects in TSrc: %1 (%2) and %3 (%4) "); compiler->abort( rule, err.arg(obj1->getName().c_str()).arg(obj1->getTypeName().c_str()) .arg(obj2->getName().c_str()).arg(obj2->getTypeName().c_str()) .toStdString()); } compiler->abort(rule, "TSrc has >2 objects"); return true; } bool NATCompiler_asa8::VerifyRules::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; string version = compiler->fw->getStr("version"); RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); if (rule->getRuleType()==NATRule::LB) { compiler->abort( rule, "Load balancing rules are not supported."); return true; } // if (rule->getRuleType()==NATRule::NONAT && (!osrv->isAny() || !tsrv->isAny())) // { // compiler->abort( // rule, // "'no nat' rules should have no services"); // return true; // } if (osrc->getNeg() || odst->getNeg() || osrv->getNeg() || tsrc->getNeg() || tdst->getNeg() || tsrv->getNeg()) { compiler->abort( rule, "Negation is not supported in NAT rules."); return true; } if (osrv->size()!=1 && !tsrv->isAny()) { compiler->abort( rule, "Can not translate multiple services into one service in one rule. "); return true; } if (tsrv->size()!=1) { compiler->abort( rule, "Translated service should be 'Original' or should contain " "single object."); return true; } if ( Group::cast( compiler->getFirstTSrv(rule) )!=NULL) { compiler->abort( rule, "Can not use group in translated service."); return true; } if (rule->getRuleType()==NATRule::SNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstOSrc(rule)); Network *a2=Network::cast(compiler->getFirstTSrc(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated source should both be networks " "of the same size"); return true; } } if (rule->getRuleType()==NATRule::DNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstODst(rule)); Network *a2=Network::cast(compiler->getFirstTDst(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated destination should both be networks " "of the same size."); return true; } } if (rule->getRuleType()==NATRule::SNetnat) rule->setRuleType(NATRule::SNAT); if (rule->getRuleType()==NATRule::DNetnat) rule->setRuleType(NATRule::DNAT); if ((rule->getRuleType()==NATRule::DNAT || rule->getRuleType()==NATRule::SDNAT) && odst->isAny()) { compiler->abort( rule, "Oiginal destination can not be \"any\" in rules that translate " "destination"); return true; } tmp_queue.push_back(rule); return true; } bool NATCompiler_asa8::verifyInterfacesInNatRule::processNext() { NATRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); return true; } void NATCompiler_asa8::compile() { info(" Compiling NAT rules for " + fw->getName()); Compiler::compile(); add( new Begin( "Begin processing")); add( new printTotalNumberOfRules()); add( new singleRuleFilter()); /* REMOVE_OLD_OPTIMIZATIONS if (fw->getOptionsObject()->getBool( "pix_optimize_default_nat")) add (new optimizeDefaultNAT( "optimize commands 'nat (interface) 0.0.0.0 0.0.0.0'")); */ add( new recursiveGroupsInOSrc("check for recursive groups in OSRC")); add( new recursiveGroupsInODst("check for recursive groups in ODST")); add( new recursiveGroupsInOSrv("check for recursive groups in OSRV")); add( new recursiveGroupsInTSrc("check for recursive groups in TSRC")); add( new recursiveGroupsInTDst("check for recursive groups in TDST")); add( new recursiveGroupsInTSrv("check for recursive groups in TSRV")); add( new emptyGroupsInOSrc("check for empty groups in OSRC")); add( new emptyGroupsInODst("check for empty groups in ODST")); add( new emptyGroupsInOSrv("check for empty groups in OSRV")); add( new emptyGroupsInTSrc("check for empty groups in TSRC")); add( new emptyGroupsInTDst("check for empty groups in TDST")); add( new emptyGroupsInTSrv("check for empty groups in TSRV")); add( new ExpandGroups("expand groups")); /* * We do not support ipv6 yet */ add( new DropIPv6RulesWithWarning( "drop ipv6 rules", "Rule has been suppressed because it contains IPv6 objects and " "Firewall Builder does not support IPv6 for this platform")); add( new eliminateDuplicatesInOSRC("eliminate duplicates in OSRC")); add( new eliminateDuplicatesInODST("eliminate duplicates in ODST")); add( new eliminateDuplicatesInOSRV("eliminate duplicates in OSRV")); add( new processMultiAddressObjectsInOSrc( "process MultiAddress objects in OSrc")); add( new processMultiAddressObjectsInODst( "process MultiAddress objects in ODst")); add( new classifyNATRule("determine NAT rule types")); add( new VerifyRules("verify rules" )); // ReplaceFirewallObjectsODst, ReplaceFirewallObjectsODst and // UseFirewallInterfaces assume there is one object in ODst, // TSrc and TDst rule elements. This should have been assured // by inspector VerifyRules add( new ReplaceFirewallObjectsODst("replace fw object in ODst" )); add( new ReplaceFirewallObjectsTSrc("replace fw object in TSrc" )); add( new UseFirewallInterfaces( "replace host objects with firewall's interfaces if " "the have the same address")); // ExpandMultipleAddresses acts on different rule elements // depending on the rule type. // Also using overloaded virtual function _expand_interface add( new ExpandMultipleAddresses("expand multiple addresses")); add( new MACFiltering( "check for MAC address filtering")); // ASA8 nat commands support address range directly. // add( new ExpandAddressRanges("expand address range objects")); add( new checkForUnnumbered("check for unnumbered interfaces")); add( new splitByNetworkZonesForOSrc("split by netzone for OSrc")); //add( new groupServicesByProtocol("group services by protocol in OSrv")); add( new ConvertToAtomicForOSrv("convert to atomic for OSrv")); add( new ConvertToAtomicForTDst("convert to atomic for TDst")); add( new ConvertToAtomicForTSrv("convert to atomic for TSrv")); add( new AssignInterface("assign rules to interfaces" )); add( new verifyInterfacesInNatRule("verify assignment of interfaces")); add( new fillTranslatedSrv("fill translated service element" )); add( new verifyRuleElements( "verify rule elements for static NAT rules")); add( new processNONATRules("process NONAT" )); add( new VerifyValidityOfDNSOption( "Check validity of 'translate dns' option")); //add( new groupTCPUDP("split rules with TCP or UDP services")); add( new SpecialServicesOSrv( "check for special services" )); add( new CreateObjectGroupsForOSrc("create object groups for OSrc", named_objects_manager)); add( new CreateObjectGroupsForODst("create object groups for ODst", named_objects_manager)); add( new CreateObjectGroupsForOSrv("create object groups for OSrv", named_objects_manager)); // need special rule processor to create object groups in TSrc // because of a special tratment that an Interface object gets in TSrc add( new CreateObjectGroupsForTSrc("create object groups for TSrc", named_objects_manager)); add( new VerifyValidityOfTSrc("verify objects in TSrc")); /* REMOVE_OLD_OPTIMIZATIONS if (fw->getOptionsObject()->getBool("pix_optimize_default_nat")) add (new clearOSrc ("clear OSrc" )); */ /* WE_DO_NOT_USE_NATCMD_FOR_ASA8 add( new createNATCmd ("create NAT commands" )); add( new createStaticCmd ("create static commands" )); */ /* REMOVE_OLD_OPTIMIZATIONS add( new mergeNATCmd ("merge NAT commands" )); add( new SuppressDuplicateNONATStatics( "suppress duplicate NONAT statics" )); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); */ //add( new PrintClearCommands("Clear ACLs" )); add( new createNamedObjectsForNAT( "create named objects", named_objects_manager)); //add( new printObjectGroups( // "definitions of object groups", named_objects_manager)); add( new PrintRule("generate PIX code" )); add( new storeProcessedRules ("store processed rules" )); add( new simplePrintProgress ()); /* REMOVE_OLD_OPTIMIZATIONS bool pix_check_duplicate_nat = fw->getOptionsObject()->getBool("pix_check_duplicate_nat"); bool pix_check_overlapping_global_pools = fw->getOptionsObject()->getBool("pix_check_overlapping_global_pools"); bool pix_check_overlapping_statics = fw->getOptionsObject()->getBool("pix_check_overlapping_statics"); bool pix_check_overlapping_global_statics = fw->getOptionsObject()->getBool("pix_check_overlapping_global_statics"); if ( pix_check_duplicate_nat || pix_check_overlapping_global_pools || pix_check_overlapping_statics || pix_check_overlapping_global_statics ) { add( new createNewCompilerPass(" Detecting nat problems ...")); if ( pix_check_duplicate_nat ) add( new DetectDuplicateNAT(" Detect duplicate nat entries")); if ( pix_check_overlapping_global_pools ) add( new DetectGlobalPoolProblems( " Detect global pool overlapping" )); if ( pix_check_overlapping_statics ) add( new DetectOverlappingStatics( " Detect overlapping statics" )); if ( pix_check_overlapping_global_statics ) add( new DetectOverlappingGlobalPoolsAndStaticRules( " Detect overlapping global pools and statics" )); add( new simplePrintProgress ( )); } */ runRuleProcessors(); } string NATCompiler_asa8::printClearCommands() { ostringstream output; string version = fw->getStr("version"); string platform = fw->getStr("platform"); if ( !fw->getOptionsObject()->getBool("pix_acl_no_clear") && !inSingleRuleCompileMode()) { output << Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_xlate") << endl; output << Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_nat") << endl; } return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_iosacl.h0000644000175000017500000002441511733011756024156 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_IOSACL_HH #define __POLICYCOMPILER_IOSACL_HH #include #include "fwcompiler/PolicyCompiler.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "Helper.h" #include "ACL.h" #include "PolicyCompiler_cisco.h" #include namespace libfwbuilder { class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementSrc; class RuleElementDst; class RuleElementSrv; class Group; }; namespace fwcompiler { class PolicyCompiler_iosacl : public PolicyCompiler_cisco { protected: std::string comment_symbol; /** * dynamic interfaces can not be used in policy rules in IOS ACLs */ friend class checkForDynamicInterface; class checkForDynamicInterface : public PolicyRuleProcessor { bool findDynamicInterface(libfwbuilder::PolicyRule *rule, libfwbuilder::RuleElement *re); public: checkForDynamicInterface(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /* ************************************************************************* * * the following rule processors are intended for IOSACL < 7.0 * the code is in the module PolicyCompiler_iosacl_v6_acls.cpp * ************************************************************************* */ /** * verifies combination of interface and direction and * fills interface and direction. After this predicate it * is guaranteed that both interface and direction have * some value. In certain situations interface ID may be * set to "nil" though (e.g. global policy rules). */ DECLARE_POLICY_RULE_PROCESSOR( InterfaceAndDirection_v6 ); /** * if interface has not been defined (this is global policy * rule), then multiply the rule for each interface and set * direction to "Inbound" */ DECLARE_POLICY_RULE_PROCESSOR( assignRuleToInterface_v6 ); /** * split rules with direction "both". * TODO: This is used in OpenBSD pf. Move to class PolicyCompiler */ DECLARE_POLICY_RULE_PROCESSOR( SplitDirection_v6 ); /** * in IOSACL, ACLs are always applied on interface and direction * can only be "inbound". We emulate outbound ACLs though. */ DECLARE_POLICY_RULE_PROCESSOR( EmulateOutboundACL_v6 ); /** * determine acl rules should belong to */ DECLARE_POLICY_RULE_PROCESSOR( pickACL_v6 ); friend class PolicyCompiler_iosacl::pickACL_v6; /* ************************************************************************* * * end of module PolicyCompiler_iosacl_v6_acls.cpp * ************************************************************************* */ /* ************************************************************************* * * rule processors intended to manage ACLs for IOSACL < 7.0 are inherited * from PolicyCompiler_cisco. * The code is in the module PolicyCompiler_cisco_acls.cpp * * The processors assume that all objects in src and dst * belong to the same network zone (respectively) * * All these rule processors assume outbound ACLs are supported. * Check corresponding capability flag and do not include these * processors in the processors chain in iosacl.cpp if outbound acls * are not supported. * ************************************************************************* */ /** * this processor checks for the services which require * special treatment. Some of these will be checking for * source or destination object as well because special * command may need to be generated in case source or * destination is a firewall itself. Therefore this processor * should be called after converting to atomic rules, but * before interface addresses in source and destination are * expanded. */ DECLARE_POLICY_RULE_PROCESSOR( SpecialServices ); friend class PolicyCompiler_iosacl::SpecialServices; /** * to implement action "Reject" add command "service resetinbound" */ DECLARE_POLICY_RULE_PROCESSOR( RejectAction ); friend class PolicyCompiler_iosacl::RejectAction; /** * Implements "mirrored" rules */ class mirrorRule : public PolicyRuleProcessor { void duplicateRuleElement(libfwbuilder::RuleElement *re1, libfwbuilder::RuleElement *re2); public: mirrorRule(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class PolicyCompiler_iosacl::mirrorRule; /** * this processor accumulates all rules fed to it by previous * * processors, prints commands to clear access-lists, then * feeds all rules to the next processor. Usually this * processor is in chain right before PrintRules. * * We use this processor to print "clear" commands because * they need to be generated when all access lists have been * created but before they are printed. */ class ClearACLs : public PolicyRuleProcessor { public: ClearACLs(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class PolicyCompiler_iosacl::ClearACLs; /** * "object-group service" does not seem to support matching of * tcp flags and "established". Need to separate objects using * these into separate rules to avoid object-group */ DECLARE_POLICY_RULE_PROCESSOR(splitTCPServiceWithFlags); friend class PolicyCompiler_iosacl::splitTCPServiceWithFlags; /** * this processor prints single policy rule, assuming all * groups have been expanded, so source, destination and * service hold exactly one object each, and this object is * not a group. Negation should also have been taken care of * before this method is called. */ class PrintRule : public PolicyRuleProcessor { protected: std::string current_rule_label1; std::map current_rule_label2; int aclLineCounter; std::string _printPortRangeOp(int rs, int re); std::string getTcpFlagName(const libfwbuilder::TCPService::TCPFlag f); std::string _printSrcService(libfwbuilder::Service *srv); std::string _printDstService(libfwbuilder::Service *srv); std::string _printAddr(libfwbuilder::Address *o); std::string _printProtocol(libfwbuilder::Service *srv); std::string _printTCPFlags(libfwbuilder::TCPService *srv); std::string _printAction(libfwbuilder::PolicyRule *r); std::string _printACL(libfwbuilder::PolicyRule *r); std::string _printLog(libfwbuilder::PolicyRule *r); std::string _printIPServiceOptions(libfwbuilder::PolicyRule *r); std::string _printRule(libfwbuilder::PolicyRule *rule); public: PrintRule(const std::string &name) : PolicyRuleProcessor(name) { aclLineCounter=0; } virtual bool processNext(); }; friend class PolicyCompiler_iosacl::PrintRule; /** * this processor accumulates all rules fed to it by previous * * processors, prints commands to clear access-lists, then * generates commands for the new ACLs. * */ class PrintCompleteACLs : public PrintRule { public: PrintCompleteACLs(const std::string &n) : PrintRule(n) {} virtual bool processNext(); struct printRulesForACL : public std::unary_function { ciscoACL *acl; std::stringstream *output; PolicyCompiler_iosacl *iosacl_comp; PolicyCompiler_iosacl::PrintCompleteACLs *print_acl_p; printRulesForACL(PolicyCompiler_iosacl *_comp, PolicyCompiler_iosacl::PrintCompleteACLs *pp, ciscoACL* _acl, std::stringstream *_out) { iosacl_comp = _comp; print_acl_p = pp; acl = _acl; output = _out; } // print rule if it belongs to ACL void operator() (libfwbuilder::Rule* x); }; friend struct PrintCompleteACLs::printRulesForACL; }; friend class PolicyCompiler_iosacl::PrintCompleteACLs;; bool resetinbound; bool fragguard; protected: virtual std::string myPlatformName(); virtual std::string printAccessGroupCmd(ciscoACL *acl, bool neg=false); public: PolicyCompiler_iosacl(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf); virtual ~PolicyCompiler_iosacl() {} virtual int prolog(); virtual void compile(); virtual void epilog(); virtual std::string printClearCommands(); static std::string getAccessGroupCommandForAddressFamily(bool ipv6); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_pix_os.cpp0000644000175000017500000007161411733011756024515 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator_pix_os.h" #include "Helper.h" #include "Configlet.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_pix_os::myPlatformName() { return "pix_os"; } int OSConfigurator_pix_os::prolog() { string host_os = fw->getStr("host_OS"); if (host_os!="pix_os" && host_os!="fwsm_os") abort("Unsupported OS " + host_os ); return Compiler::prolog(); } void OSConfigurator_pix_os::processFirewallOptions() { // FWOptions* options=fw->getOptionsObject(); string s; // int i; string version = fw->getStr("version"); string platform = fw->getStr("platform"); if ( fw->getOptionsObject()->getBool("pix_set_host_name") ) { output << "hostname " << fw->getName() << endl; output << endl; } output << _printInterfaceConfiguration(); output << endl; if (fw->getOptionsObject()->getBool("cluster_member")) { output << _printFailoverConfiguration(); output << endl; output << endl; output << endl; } output << _printLogging(); output << endl; output << _printTimeouts(); output << endl; output << _printSSHConfiguration(); output << endl; output << _printSNMP(); output << endl; output << _printNTP(); output << endl; output << _printSysopt(); output << endl; output << getProtocolInspectionCommands(); output << endl; } void OSConfigurator_pix_os::_getFailoverAddresses(ClusterGroup *cluster_group, QString *primary_addr, QString *primary_netm, QString *standby_addr) { int master_id = FWObjectDatabase::getIntId(cluster_group->getStr("master_iface")); if (master_id <= 0) { QString err; if (StateSyncClusterGroup::isA(cluster_group)) err = QObject::tr("One of the state synchronization group members " "must be marked as master. Can not configure " "PIX failover without master."); else err = QObject::tr("One of the failover group members must be marked " "as master. Can not configure PIX failover " "without master."); abort(err.toStdString()); } for (FWObjectTypedChildIterator it = cluster_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *gorup_intf = Interface::cast(FWObjectReference::getObject(*it)); assert(gorup_intf); QString addr; QString netm; const InetAddr *a = gorup_intf->getAddressPtr(); const InetAddr *n = gorup_intf->getNetmaskPtr(); if (a && n) { addr = a->toString().c_str(); netm = n->toString().c_str(); if (gorup_intf->getId() == master_id) { *primary_addr = addr; *primary_netm = netm; } else { *standby_addr = addr; } } } } void OSConfigurator_pix_os::_getAddressConfigurationForInterface( Interface *iface, QString *addr, QString *netm, QString *standby_addr) { const InetAddr *a = iface->getAddressPtr(); const InetAddr *n = iface->getNetmaskPtr(); if (a && n) { *addr = a->toString().c_str(); *netm = n->toString().c_str(); } if (standby_addr) { // find standby address (address of the other unit in failover group) int failover_group_id = FWObjectDatabase::getIntId( iface->getOptionsObject()->getStr("failover_group_id")); FWObject *failover_group = fw->getRoot()->findInIndex(failover_group_id); if (failover_group) { for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *failover_intf = Interface::cast(FWObjectReference::getObject(*it)); assert(failover_intf); if (failover_intf->getId() != iface->getId()) { const InetAddr *a = failover_intf->getAddressPtr(); if (a) *standby_addr = a->toString().c_str(); break; } } } } } string OSConfigurator_pix_os::_printInterfaceConfiguration() { ostringstream res; string host_os = fw->getStr("host_OS"); string version = fw->getStr("version"); string platform = fw->getStr("platform"); bool configure_address = fw->getOptionsObject()->getBool("pix_ip_address"); bool configure_standby_address = configure_address && fw->getOptionsObject()->getBool("cluster_member"); list l2=fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) continue; Configlet *cnf = NULL; QString configlet_name; if (iface->isDedicatedFailover()) { configlet_name = "failover_interface_"; if (iface->getLabel().empty()) iface->setLabel("failover"); } if (iface->getOptionsObject()->getStr("type") == "8021q") configlet_name = "vlan_subinterface_"; if ((iface->getOptionsObject()->getStr("type") == "" || iface->getOptionsObject()->getStr("type") == "ethernet") && iface->getByType(Interface::TYPENAME).size() > 0) { // vlan parent configlet_name = "vlan_parent_interface_"; } if (configlet_name.isEmpty()) configlet_name = "regular_interface_"; if (host_os == "pix_os") { if (XMLTools::version_compare(version, "7.0") < 0) configlet_name += "6"; if (XMLTools::version_compare(version, "7.0") >= 0) configlet_name += "7"; } if (host_os == "fwsm_os") { if (XMLTools::version_compare(version, "3.2") < 0) configlet_name += "2"; if (XMLTools::version_compare(version, "3.2") >= 0) configlet_name += "3_2"; } cnf = new Configlet(fw, "pix_os", configlet_name); cnf->removeComments(); cnf->collapseEmptyStrings(true); cnf->setVariable("configure_interface_address", configure_address); cnf->setVariable("configure_standby_address", configure_standby_address); cnf->setVariable("interface_name", iface->getName().c_str()); cnf->setVariable("interface_label", iface->getLabel().c_str()); cnf->setVariable("security_level", iface->getSecurityLevel()); if (iface->getOptionsObject()->getStr("type") == "8021q") { cnf->setVariable("vlan_id", iface->getOptionsObject()->getInt("vlan_id")); cnf->setVariable("parent_interface", iface->getParent()->getName().c_str()); } cnf->setVariable("static_address", ! iface->isDyn()); cnf->setVariable("dhcp_address", iface->isDyn()); if (!iface->isDyn()) { QString addr; QString netm; QString standby_addr; _getAddressConfigurationForInterface( iface, &addr, &netm, (configure_standby_address) ? &standby_addr : NULL); if (!addr.isEmpty() && !netm.isEmpty()) { cnf->setVariable("address", addr); cnf->setVariable("netmask", netm); } else { cnf->setVariable("configure_interface_address", false); cnf->setVariable("configure_standby_address", false); } if (configure_standby_address && !standby_addr.isEmpty()) cnf->setVariable("standby_address", standby_addr); } res << cnf->expand().toStdString(); res << endl; res << endl; delete cnf; } return res.str(); } string OSConfigurator_pix_os::_printFailoverConfiguration() { ostringstream res; string host_os = fw->getStr("host_OS"); string version = fw->getStr("version"); string platform = fw->getStr("platform"); QString configlet_name = "failover_commands_"; if (host_os == "pix_os") { if (XMLTools::version_compare(version, "7.0") < 0) configlet_name += "6"; if (XMLTools::version_compare(version, "7.0") >= 0) configlet_name += "7"; } if (host_os == "fwsm_os") { if (XMLTools::version_compare(version, "3.2") < 0) configlet_name += "2"; if (XMLTools::version_compare(version, "3.2") >= 0) configlet_name += "3_2"; } Configlet cnf(fw, "pix_os", configlet_name); cnf.removeComments(); cnf.collapseEmptyStrings(true); list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) continue; // Intrfaces used for failover and state sync must be marked // as "dedicated failover" in PIX firewall objects. This can // be the same or two different interfaces. if (iface->isDedicatedFailover()) { // configure state sync. StateSyncClusterGroup object // belongs to the cluster but method // CompilerDriver::processStateSyncGroups sets variables // "state_sync_group_id" and "state_sync_interface" in the // member firewall object int state_sync_group_id = FWObjectDatabase::getIntId( fw->getOptionsObject()->getStr("state_sync_group_id")); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast( fw->getRoot()->findInIndex(state_sync_group_id)); if (state_sync_group && state_sync_group->hasMember(iface)) { cnf.setVariable("state_sync_interface_name", iface->getName().c_str()); cnf.setVariable("state_sync_interface_label", iface->getLabel().c_str()); QString key = state_sync_group->getOptionsObject()->getStr("pix_failover_key").c_str(); cnf.setVariable("failover_key", key); QString primary_addr; QString primary_netm; QString standby_addr; /* * Note that in the "failover interface ip" command * the first address is always that of the primary * unit and the second address is that of the * standby. They come in this order in the * configuration of BOTH units which is rather * counter-intuitive. */ _getFailoverAddresses( state_sync_group, &primary_addr, &primary_netm, &standby_addr); cnf.setVariable("state_sync_interface_primary_address", primary_addr); cnf.setVariable("state_sync_interface_primary_netmask", primary_netm); cnf.setVariable("state_sync_interface_standby_address", standby_addr); } int failover_group_id = FWObjectDatabase::getIntId( iface->getOptionsObject()->getStr("failover_group_id")); FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( fw->getRoot()->findInIndex(failover_group_id)); if (failover_group) { cnf.setVariable("failover_interface_name", iface->getName().c_str()); cnf.setVariable("failover_interface_label", iface->getLabel().c_str()); QString primary_or_secondary = "secondary"; int master_id = FWObjectDatabase::getIntId( failover_group->getStr("master_iface")); if (iface->getId() == master_id) primary_or_secondary = "primary"; cnf.setVariable("primary_or_secondary", primary_or_secondary); QString primary_addr; QString primary_netm; QString standby_addr; _getFailoverAddresses( failover_group, &primary_addr, &primary_netm, &standby_addr); cnf.setVariable("failover_interface_primary_address", primary_addr); cnf.setVariable("failover_interface_primary_netmask", primary_netm); cnf.setVariable("failover_interface_standby_address", standby_addr); } } } return cnf.expand().toStdString(); } string OSConfigurator_pix_os::_printLogging() { Helper helper(this); ostringstream str; bool logging_on=false; string syslog_host = fw->getOptionsObject()->getStr("pix_syslog_host"); int syslog_queue_size = fw->getOptionsObject()->getInt( "pix_syslog_queue_size"); string syslog_facility = fw->getOptionsObject()->getStr( "pix_syslog_facility"); string trap_level = fw->getOptionsObject()->getStr( "pix_logging_trap_level"); bool buffered = fw->getOptionsObject()->getBool("pix_logging_buffered"); string buffered_level = fw->getOptionsObject()->getStr( "pix_logging_buffered_level"); bool console = fw->getOptionsObject()->getBool("pix_logging_console"); string console_level = fw->getOptionsObject()->getStr( "pix_logging_console_level"); bool timestamp = fw->getOptionsObject()->getBool("pix_logging_timestamp"); if ( ! syslog_host.empty() ) { InetAddr syslog_addr(syslog_host); int iface_id = helper.findInterfaceByNetzone(&syslog_addr); if (iface_id == -1) abort("Log server " + syslog_host + " does not belong to any known network zone"); Interface *syslog_iface = Interface::cast(dbcopy->findInIndex(iface_id)); str << endl; str << "logging host " << syslog_iface->getLabel() << " " << syslog_host; if ( fw->getOptionsObject()->getBool("pix_emblem_log_format") ) str << " format emblem "; str << endl; str << "logging queue " << syslog_queue_size << endl; if ( ! syslog_facility.empty() ) str << "logging facility " << syslog_facility << endl; if ( ! trap_level.empty() ) str << "logging trap " << trap_level << endl; logging_on=true; } if ( ! buffered ) str << "no logging buffered" << endl; else { str << "logging buffered " << buffered_level << endl; logging_on=true; } if ( ! console ) str << "no logging console" << endl; else { str << "logging console " << console_level << endl; logging_on=true; } if ( ! timestamp ) str << "no "; str << "logging timestamp" << endl; if ( ! logging_on) str << "no "; str << "logging on" << endl; string s=fw->getOptionsObject()->getStr("pix_syslog_device_id_opt"); string v=fw->getOptionsObject()->getStr("pix_syslog_device_id_val"); if (s=="hostname") str << "logging device-id hostname" << endl; if (s=="interface") str << "logging device-id ipaddress " << v << endl; if (s=="string") str << "logging device-id string " << v << endl; str << endl; return str.str(); } void OSConfigurator_pix_os::_configureSNMPServer(Configlet *cnf, int server_num, const string &srv, int poll_trap) { QString interface_var = QString("interface_%1_label").arg(server_num); QString address_var = QString("address_%1").arg(server_num); QString poll_or_trap_var = QString("poll_or_trap_%1").arg(server_num); Helper helper(this); InetAddr srv_addr(srv); int iface_id = helper.findInterfaceByNetzone(&srv_addr); if (iface_id == -1) abort(string("SNMP server ") + srv + " does not belong to any known network zone"); Interface *snmp_iface = Interface::cast(dbcopy->findInIndex(iface_id)); cnf->setVariable(interface_var, snmp_iface->getLabel().c_str()); cnf->setVariable(address_var, srv.c_str()); switch (poll_trap) { case 1: cnf->setVariable(poll_or_trap_var, "poll"); break; case 2: cnf->setVariable(poll_or_trap_var, "trap"); break; default: cnf->setVariable(poll_or_trap_var, ""); break; } } string OSConfigurator_pix_os::_printSNMP() { string version = fw->getStr("version"); string platform = fw->getStr("platform"); // for pix bool version_ge_70 = XMLTools::version_compare(version, "7.0") >= 0; // for fwsm bool version_ge_32 = XMLTools::version_compare(version, "3.2") >= 0; Configlet cnf(fw, "pix_os", "snmp"); cnf.removeComments(); cnf.collapseEmptyStrings(true); cnf.setVariable("pix_version_lt_70", ! version_ge_70); cnf.setVariable("pix_version_ge_70", version_ge_70); cnf.setVariable("fwsm_version_lt_32", ! version_ge_32); cnf.setVariable("fwsm_version_ge_32", version_ge_32); bool set_communities = fw->getOptionsObject()->getBool( "pix_set_communities_from_object_data"); bool set_sysinfo = fw->getOptionsObject()->getBool( "pix_set_sysinfo_from_object_data" ); bool enable_traps = fw->getOptionsObject()->getBool( "pix_enable_snmp_traps"); cnf.setVariable("clear", !fw->getOptionsObject()->getBool("pix_acl_no_clear")); cnf.setVariable("disable", fw->getOptionsObject()->getBool("pix_disable_snmp_agent")); cnf.setVariable("not_disable", ! fw->getOptionsObject()->getBool("pix_disable_snmp_agent")); cnf.setVariable("set_community", set_communities); cnf.setVariable( "read_community", fw->getManagementObject()->getSNMPManagement()->getReadCommunity().c_str()); cnf.setVariable("set_sysinfo", set_sysinfo); QString location = fw->getOptionsObject()->getStr("snmp_location").c_str(); QString contact = fw->getOptionsObject()->getStr("snmp_contact").c_str(); cnf.setVariable("not_enable_traps", ! enable_traps); string snmp_server_1 = fw->getOptionsObject()->getStr("pix_snmp_server1"); string snmp_server_2 = fw->getOptionsObject()->getStr("pix_snmp_server2"); int snmp_poll_traps_1 = fw->getOptionsObject()->getInt("pix_snmp_poll_traps_1"); int snmp_poll_traps_2 = fw->getOptionsObject()->getInt("pix_snmp_poll_traps_2"); cnf.setVariable("not_server_1_empty", ! snmp_server_1.empty()); cnf.setVariable("not_server_2_empty", ! snmp_server_2.empty()); _configureSNMPServer(&cnf, 1, snmp_server_1, snmp_poll_traps_1); _configureSNMPServer(&cnf, 2, snmp_server_2, snmp_poll_traps_2); return cnf.expand().toStdString() + "\n"; } void OSConfigurator_pix_os::_configureNTPServer(Configlet *cnf, int server_num, const std::string &server, bool pref) { Helper helper(this); InetAddr srv_addr(server); int iface_id = helper.findInterfaceByNetzone(&srv_addr); if (iface_id == -1) { QString err("NTP server %1 does not belong to any known network zone"); abort(fw, err.arg(server.c_str()).toStdString()); } Interface *ntp_iface = Interface::cast(dbcopy->findInIndex(iface_id)); QString var_name("not_server_%1_empty"); cnf->setVariable(var_name.arg(server_num), ! server.empty()); var_name = QString("address_%1"); cnf->setVariable(var_name.arg(server_num), server.c_str()); var_name = QString("interface_%1_label"); cnf->setVariable(var_name.arg(server_num), ntp_iface->getLabel().c_str()); var_name = QString("prefer_%1"); cnf->setVariable(var_name.arg(server_num), pref); } string OSConfigurator_pix_os::_printNTP() { string version = fw->getStr("version"); string platform = fw->getStr("platform"); // for pix bool version_ge_70 = XMLTools::version_compare(version, "7.0") >= 0; // for fwsm bool version_ge_32 = XMLTools::version_compare(version, "3.2") >= 0; Configlet cnf(fw, "pix_os", "ntp"); cnf.removeComments(); cnf.collapseEmptyStrings(true); cnf.setVariable("pix_version_lt_70", ! version_ge_70); cnf.setVariable("pix_version_ge_70", version_ge_70); cnf.setVariable("fwsm_version_lt_32", ! version_ge_32); cnf.setVariable("fwsm_version_ge_32", version_ge_32); string ntp_server_1=fw->getOptionsObject()->getStr("pix_ntp1"); bool ntp1_pref=fw->getOptionsObject()->getBool("pix_ntp1_pref"); string ntp_server_2=fw->getOptionsObject()->getStr("pix_ntp2"); bool ntp2_pref=fw->getOptionsObject()->getBool("pix_ntp2_pref"); string ntp_server_3=fw->getOptionsObject()->getStr("pix_ntp3"); bool ntp3_pref=fw->getOptionsObject()->getBool("pix_ntp3_pref"); cnf.setVariable("clear", !fw->getOptionsObject()->getBool("pix_acl_no_clear")); _configureNTPServer(&cnf, 1, ntp_server_1, ntp1_pref); _configureNTPServer(&cnf, 2, ntp_server_2, ntp2_pref); _configureNTPServer(&cnf, 3, ntp_server_3, ntp3_pref); return cnf.expand().toStdString() + "\n"; } string OSConfigurator_pix_os::_printSysopt() { ostringstream res; string platform = fw->getStr("platform"); string version = fw->getStr("version"); FWOptions *options=fw->getOptionsObject(); assert(options!=NULL); bool tcpmss = fw->getOptionsObject()->getBool("pix_tcpmss"); int tcpmss_val = fw->getOptionsObject()->getInt("pix_tcpmss_value"); res << endl; if (fw->getOptionsObject()->getBool("pix_resetinbound")) res << "service resetinbound" << endl; else res << "no service resetinbound" << endl; if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_" + version + "/pix_resetoutside_supported")) { if (fw->getOptionsObject()->getBool("pix_resetoutside")) res << "service resetoutside" << endl; else res << "no service resetoutside" << endl; } if (tcpmss) res << "sysopt connection tcpmss " << tcpmss_val << endl; if (fw->getStr("platform")=="pix") { if (fw->getOptionsObject()->getBool("pix_connection_timewait")) res << "sysopt connection timewait" << endl; else res << "no sysopt connection timewait" << endl; } if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_" + version + "/pix_security_fragguard_supported") ) { if ( fw->getOptionsObject()->getBool("pix_fragguard") ) res << "sysopt security fragguard" << endl; else res << "no sysopt security fragguard" << endl; } if ( fw->getOptionsObject()->getBool("pix_nodnsalias_inbound") ) res << "sysopt nodnsalias inbound" << endl; else res << "no sysopt nodnsalias inbound" << endl; if ( fw->getOptionsObject()->getBool("pix_nodnsalias_outbound") ) res << "sysopt nodnsalias outbound" << endl; else res << "no sysopt nodnsalias outbound" << endl; if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_"+version+ "/pix_route_dnat_supported") ) { if ( fw->getOptionsObject()->getBool("pix_route_dnat") ) res << "sysopt route dnat" << endl; else res << "no sysopt route dnat" << endl; } if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_"+version+ "/pix_floodguard_supported") ) { if ( fw->getOptionsObject()->getBool("pix_floodguard") ) res << "floodguard enable" << endl; else res << "floodguard disable" << endl; } res << endl; return res.str(); } string OSConfigurator_pix_os::_printServiceTimeout(const string &pix_service) { QStringList res; QString hh, mm, ss; string version = fw->getStr("version"); string platform = fw->getStr("platform"); bool use_sunrpc = Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_" + version + "/pix_timeout_rpc_is_sunrpc"); hh = fw->getOptionsObject()->getStr(pix_service+"_hh").c_str(); mm = fw->getOptionsObject()->getStr(pix_service+"_mm").c_str(); ss = fw->getOptionsObject()->getStr(pix_service+"_ss").c_str(); if ( ! hh.isEmpty() && ! mm.isEmpty() && ! ss.isEmpty()) { QString service_name = pix_service.c_str(); if (pix_service == "rpc" && use_sunrpc) service_name = "sunrpc"; bool ok1, ok2, ok3; int hh_int = hh.toInt(&ok1); if (!ok1) hh_int = 0; int mm_int = mm.toInt(&ok2); if (!ok2) mm_int = 0; int ss_int = ss.toInt(&ok3); if (!ok3) ss_int = 0; if (!ok1 || !ok2 || !ok3) qDebug() << QString("Invalid timeout spec '%1:%2:%3'") .arg(hh).arg(mm).arg(ss); if (pix_service == "xlate" && hh_int == 0 && mm_int == 0 && ss_int == 0) { ss_int = 30; } res << QString("timeout %1 %2:%3:%4") .arg(service_name).arg(hh_int).arg(mm_int).arg(ss_int); if (pix_service == "uauth") { bool abs = fw->getOptionsObject()->getBool("uauth_abs"); bool inact = fw->getOptionsObject()->getBool("uauth_inact"); if (abs) res << "absolute"; if (inact) res << "inactivity"; } res << "\n"; } return res.join(" ").toStdString(); } string OSConfigurator_pix_os::_printTimeouts() { ostringstream res; res << _printServiceTimeout("xlate"); res << _printServiceTimeout("conn"); res << _printServiceTimeout("udp"); res << _printServiceTimeout("rpc"); res << _printServiceTimeout("h323"); res << _printServiceTimeout("sip"); res << _printServiceTimeout("sip_media"); res << _printServiceTimeout("half-closed"); res << _printServiceTimeout("uauth"); res << endl; int to; to = fw->getOptionsObject()->getInt("pix_telnet_timeout"); if (to>60) abort("Telnet timeout should not exceed 60 minutes"); if (to!=0) res << "telnet timeout " << to << endl; return res.str(); } void OSConfigurator_pix_os::addVirtualAddressForNAT(const Address*) { } void OSConfigurator_pix_os::addVirtualAddressForNAT(const Network*) { } string OSConfigurator_pix_os::_printSSHConfiguration() { string platform = fw->getStr("platform"); string version = fw->getStr("version"); // for pix bool version_ge_70 = XMLTools::version_compare(version, "7.0") >= 0; // for fwsm bool version_ge_32 = XMLTools::version_compare(version, "3.2") >= 0; Configlet cnf(fw, "pix_os", "ssh"); cnf.removeComments(); cnf.collapseEmptyStrings(true); cnf.setVariable("pix_version_lt_70", ! version_ge_70); cnf.setVariable("pix_version_ge_70", version_ge_70); cnf.setVariable("fwsm_version_lt_32", ! version_ge_32); cnf.setVariable("fwsm_version_ge_32", version_ge_32); cnf.setVariable("clear", ! fw->getOptionsObject()->getBool("pix_acl_no_clear") ); cnf.setVariable("use_scp", fw->getOptionsObject()->getBool("use_scp")); int to = fw->getOptionsObject()->getInt("pix_ssh_timeout"); if (to>60) abort("SSH timeout should not exceed 60 minutes"); cnf.setVariable("ssh_timeout", to); // ssh accress control is added later when we generate rules return cnf.expand().toStdString() + "\n"; } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_iosacl.cpp0000644000175000017500000001167511733011756024705 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "RoutingCompiler_iosacl.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Network.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; string RoutingCompiler_iosacl::myPlatformName() { return "iosacl"; } int RoutingCompiler_iosacl::prolog() { int n = RoutingCompiler_cisco::prolog(); if (fw->getStr("platform")!="iosacl") abort("Unsupported platform " + fw->getStr("platform") ); return n; } void RoutingCompiler_iosacl::epilog() { } /* * Replace objects in dst and gw with their ip addresses, except if * interface of the firewall is found in gw, it is left intact because * IOS allows for using interface name as gateway in "ip route" * command. */ bool RoutingCompiler_iosacl::ExpandMultipleAddressesExceptInterface::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRDst *dst = rule->getRDst(); assert(dst); compiler->_expand_addr(rule, dst, true); RuleElementRGtw *gtwrel = rule->getRGtw(); assert(gtwrel); Address *gtw = Address::cast( FWReference::cast(gtwrel->front())->getPointer()); if (gtw == NULL) compiler->abort(rule, "Broken GTW"); if (Interface::isA(gtw) && gtw->isChildOf(compiler->fw)) return true; compiler->_expand_addr(rule, gtwrel, false); return true; } bool RoutingCompiler_iosacl::checkRItfAndGw::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRItf *itfrel = rule->getRItf(); assert(itfrel); RuleElementRGtw *gtwrel = rule->getRGtw(); assert(gtwrel); if (!itfrel->isAny() && !gtwrel->isAny()) compiler->abort(rule, "Can not use both gateway address and interface in " "IOS routing rule"); return true; } /** *----------------------------------------------------------------------- */ void RoutingCompiler_iosacl::compile() { printRule = new RoutingCompiler_iosacl::PrintRule(""); info(" Compiling routing rules for " + fw->getName()); Compiler::compile(); add(new RoutingCompiler::Begin()); add(new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new recursiveGroupsInRDst("Check for recursive Groups in RDst")); add(new emptyGroupsInRDst("Check for empty Groups in RDst")); add(new emptyRDstAndRItf("Check if RDst and RItf are both empty")); // add(new singleAdressInRGtw( // "Check if RGtw object has exactly one IP adress")); add(new rItfChildOfFw("Check if RItf is an Iterface of this firewall")); add(new checkRItfAndGw("Both gateway and interface can not be used in the same rule")); add(new validateNetwork("Validate network addresses")); add(new reachableAddressInRGtw( "Check if RGtw is reachable via local networks")); //add(new contradictionRGtwAndRItf( // "Check if RGtw is in a network of RItf")); add(new ExpandGroups("Expand groups in DST")); add(new ExpandMultipleAddressesExceptInterface( "Expand objects with multiple addresses in DST")); add(new eliminateDuplicatesInDST("Eliminate duplicates in DST")); add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'competingRules'")); add(new competingRules("Check for competing rules")); add(new ConvertToAtomicForDST( "Convert to atomic rules by dst address elements")); add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'classifyRoutingRules'")); add(new classifyRoutingRules( "Classify into single path or part of a multi path rule")); //add(new eliminateDuplicateRules( // "Eliminate duplicate rules over the whole table")); add(new PrintRule("generate ip code")); add(new simplePrintProgress()); runRuleProcessors(); } fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManager.cpp0000644000175000017500000001302211733011756024046 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NamedObjectsManager.h" #include "NamedObject.h" #include "PIXObjectGroup.h" #include "ASA8ObjectGroup.h" #include "IOSObjectGroup.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Management.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwcompiler/Compiler.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; FWObject* create_IOSObjectGroup(int id) { FWObject *nobj = new IOSObjectGroup(); if (id > -1) nobj->setId(id); return nobj; } FWObject* create_PIXObjectGroup(int id) { FWObject *nobj = new PIXObjectGroup(); if (id > -1) nobj->setId(id); return nobj; } FWObject* create_ASA8ObjectGroup(int id) { FWObject *nobj = new ASA8ObjectGroup(); if (id > -1) nobj->setId(id); return nobj; } NamedObjectsManager::NamedObjectsManager(Library *persistent_objects, Firewall *_fw) { fw = _fw; version = fw->getStr("version"); platform = fw->getStr("platform"); this->persistent_objects = persistent_objects; Group *object_groups = new Group(); object_groups->setName("Object Groups"); persistent_objects->add( object_groups ); object_groups_group_id = FWObjectDatabase::getStringId(object_groups->getId()); BaseObjectGroup::name_disambiguation.clear(); NamedObject::name_disambiguation.clear(); FWObjectDatabase::registerObjectType(IOSObjectGroup::TYPENAME, &create_IOSObjectGroup); FWObjectDatabase::registerObjectType(PIXObjectGroup::TYPENAME, &create_PIXObjectGroup); FWObjectDatabase::registerObjectType(ASA8ObjectGroup::TYPENAME, &create_ASA8ObjectGroup); } NamedObjectsManager::~NamedObjectsManager() { std::map::iterator it1; for (it1=named_objects.begin(); it1!=named_objects.end(); ++it1) { delete it1->second; } named_objects.clear(); } void NamedObjectsManager::addNamedObject(const FWObject *obj) { if (getNamedObject(obj) == NULL) named_objects[obj->getId()] = new NamedObject(obj, platform.c_str()); } NamedObject* NamedObjectsManager::getNamedObject(const FWObject *obj) { if (named_objects.count(obj->getId()) == 0) return NULL; else return named_objects[obj->getId()]; } bool NamedObjectsManager::haveNamedObjects() { return (named_objects.size() > 0); } bool NamedObjectsManager::haveObjectGroups() { FWObject *object_groups = persistent_objects->getRoot()->findInIndex( FWObjectDatabase::getIntId(object_groups_group_id)); return (object_groups->size() > 0); } string NamedObjectsManager::getNamedObjectsDefinitions() { QStringList output; map::iterator it; for (it=named_objects.begin(); it!=named_objects.end(); ++it) { NamedObject *nobj = it->second; if (nobj==NULL) continue; output << nobj->getCommand(); } FWObject *object_groups = persistent_objects->getRoot()->findInIndex( FWObjectDatabase::getIntId(object_groups_group_id)); for (FWObject::iterator i=object_groups->begin(); i!=object_groups->end(); ++i) { BaseObjectGroup *og = dynamic_cast(*i); assert(og!=NULL); if (og->size()==0) continue; output << og->toString(this); // ends with an empty line } return output.join("\n").toUtf8().constData(); } string NamedObjectsManager::getClearCommands() { return ""; } BaseObjectGroup* NamedObjectsManager::createObjectGroup() { BaseObjectGroup *grp = NULL; if (platform == "pix") { if (XMLTools::version_compare(version, "8.0")<0) grp = new PIXObjectGroup(); else grp = new ASA8ObjectGroup(); } if (platform == "fwsm") grp = new PIXObjectGroup(); if (platform == "iosacl") grp = new IOSObjectGroup(); assert(grp!=NULL); return grp; } Group* NamedObjectsManager::getObjectGroupsGroup() { return Group::cast(persistent_objects->getRoot()->findInIndex( FWObjectDatabase::getIntId(object_groups_group_id))); } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_pix_run.cpp0000644000175000017500000011252711733011756024721 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "CompilerDriver_pix.h" #include "PolicyCompiler_pix.h" #include "NATCompiler_pix.h" #include "NATCompiler_asa8.h" #include "RoutingCompiler_pix.h" #include "OSConfigurator_pix_os.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManagerPIX.h" #include "NamedObjectsManagerASA8.h" #include "AutomaticRules_cisco.h" #include "Helper.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; class sort_by_net_zone { string any_address_id; public: explicit sort_by_net_zone() { any_address_id = FWObjectDatabase::getStringId( FWObjectDatabase::ANY_ADDRESS_ID); } bool operator()(const FWObject *a, const FWObject *b) { if (Interface::constcast(a) && Interface::constcast(b)) { string netzone_a=a->getStr("network_zone"); string netzone_b=b->getStr("network_zone"); if ( netzone_a==any_address_id) return false; if ( netzone_b==any_address_id) return true; } return false; } }; QString CompilerDriver_pix::assembleManifest(Cluster*, Firewall*, bool) { QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); script << "!" << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]) << endl; return script_buffer; } QString CompilerDriver_pix::printActivationCommands(Firewall*) { return ""; } QString CompilerDriver_pix::assembleFwScript(Cluster *cluster, Firewall* fw, bool cluster_member, OSConfigurator *oscnf) { Configlet script_skeleton(fw, "pix_os", "script_skeleton"); Configlet top_comment(fw, "pix_os", "top_comment"); FWOptions* options = fw->getOptionsObject(); options->setStr("prolog_script", options->getStr("pix_prolog_script")); options->setStr("epilog_script", options->getStr("pix_epilog_script")); options->setStr("prolog_place", ""); string vers = fw->getStr("version"); string platform = fw->getStr("platform"); bool outbound_acl_supported = Resources::platform_res[platform]->getResourceBool( string("/FWBuilderResources/Target/options/")+ "version_"+vers+ "/pix_outbound_acl_supported"); bool afpa = options->getBool("pix_assume_fw_part_of_any"); bool emulate_outb_acls = options->getBool("pix_emulate_out_acl"); bool generate_outb_acls = options->getBool("pix_generate_out_acl"); top_comment.setVariable( "outbound_acl_supported", QString((outbound_acl_supported) ? "supported" : "not supported")); top_comment.setVariable("emulate_outb_acls", QString((emulate_outb_acls)?"yes":"no")); top_comment.setVariable("generate_outb_acls", QString((generate_outb_acls)?"yes":"no")); top_comment.setVariable("afpa", QString((afpa)?"yes":"no")); script_skeleton.setVariable("short_script", options->getBool("short_script")); script_skeleton.setVariable("not_short_script", ! options->getBool("short_script")); script_skeleton.setVariable("preamble_commands", QString::fromUtf8( preamble_commands.c_str())); script_skeleton.setVariable("clear_commands", QString::fromUtf8( clear_commands.c_str())); script_skeleton.setVariable("system_configuration_script", QString::fromUtf8( system_configuration_script.c_str())); script_skeleton.setVariable("named_objects_and_object_groups", QString::fromUtf8( named_objects_and_groups.c_str())); script_skeleton.setVariable("policy_script", QString::fromUtf8(policy_script.c_str())); script_skeleton.setVariable("nat_script", QString::fromUtf8(nat_script.c_str())); script_skeleton.setVariable("routing_script", QString::fromUtf8(routing_script.c_str())); assembleFwScriptInternal(cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "!", true); return script_skeleton.expand(); } QString CompilerDriver_pix::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); if (cluster) { // PIX failover is dfferent from VRRP and other failover protocols // in that it does not create new virtual address. Instead, each // unit is configured with two ip addresses, one for the active // unit and another for standby one. When active unit fails, the // other one assumes its address. // // This matters because when we use cluster object or one of its // interfaces in rules, compiler should expand it to the set of // addresses that includes addresses of the corresponding // interface of both member firewalls. Method // CompilerDriver::copyFailoverInterface adds a copy of firewall // interface to the cluster object. This works for all firewalls, // but for PIX we need to add copies of interfaces from both // members. // FWObjectTypedChildIterator cl_iface = cluster->findByType(Interface::TYPENAME); for (; cl_iface != cl_iface.end(); ++cl_iface) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( (*cl_iface)->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { FWObject *this_member_interface = NULL; list other_member_interfaces; for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { FWObject *intf = FWObjectReference::getObject(*it); assert(intf); if (intf->isChildOf(fw)) this_member_interface = intf; else other_member_interfaces.push_back(intf); } if (!other_member_interfaces.empty()) { for (list::iterator it=other_member_interfaces.begin(); it!=other_member_interfaces.end(); ++it) { cluster->addCopyOf(*it, true); } } } } } #if 0 FWObjectTypedChildIterator iface = fw->findByType(Interface::TYPENAME); for (; iface != iface.end(); ++iface) { (*iface)->dump(true, true); } #endif determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("")); FWOptions* options = fw->getOptionsObject(); QString script_buffer; std::auto_ptr n; std::auto_ptr c; std::auto_ptr r; try { clearReadOnly(fw); commonChecks2(cluster, fw); pixClusterConfigurationChecks(cluster, fw); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); bool pix_acl_basic = options->getBool("pix_acl_basic"); bool pix_acl_no_clear = options->getBool("pix_acl_no_clear"); bool pix_acl_substitution = options->getBool("pix_acl_substitution"); bool pix_add_clear_statements = options->getBool("pix_add_clear_statements"); if (!pix_acl_basic && !pix_acl_no_clear && !pix_acl_substitution) { if ( pix_add_clear_statements ) options->setBool("pix_acl_basic",true); else options->setBool("pix_acl_no_clear",true); } list all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); pixSecurityLevelChecks(fw, all_interfaces); pixNetworkZoneChecks(fw, all_interfaces); /* Now that all checks are done, we can drop copies of cluster * interfaces that were added to the firewall by * CompilerDriver::populateClusterElements() */ list copies_of_cluster_interfaces; for (std::list::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) copies_of_cluster_interfaces.push_back(iface); } while (copies_of_cluster_interfaces.size()) { fw->remove(copies_of_cluster_interfaces.front()); copies_of_cluster_interfaces.pop_front(); } NamedObjectsManagerPIX named_objects_manager(persistent_objects, fw); all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); for (std::list::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); /* * missing labels on interfaces * */ if (iface->getLabel()=="") { string lbl; if (iface->isDedicatedFailover()) { // dedicated failover interface misses label. This // interface can be used in failover cluster group // or state sync group. Assign label depending on // the function. FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast(*it); if (state_sync_group && state_sync_group->hasMember(iface)) lbl = "state"; if (!iface->getOptionsObject()->getStr("failover_group_id").empty()) lbl = "failover"; } if (lbl.empty()) { if (iface->getSecurityLevel()==0) lbl="outside"; else { if (iface->getSecurityLevel()==100) lbl="inside"; else { QString l("dmz%1"); lbl = l.arg(iface->getSecurityLevel()).toStdString(); } } } iface->setLabel(lbl); } } /* * now sort interfaces by their network zone "width" (that * is, more narrow network zone should go first, interface * with network zone "any" should be the last) * std::sort(fw->begin(), fw->end(), sort_by_net_zone() ); */ try { AutomaticRules_cisco auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); } catch (FWException &ex) { abort(ex.toString()); } std::auto_ptr prep( new Preprocessor(objdb , fw, false)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); std::auto_ptr oscnf( new OSConfigurator_pix_os(objdb , fw, false)); if (inTestMode()) oscnf->setTestMode(); if (inEmbeddedMode()) oscnf->setEmbeddedMode(); oscnf->prolog(); oscnf->processFirewallOptions(); bool have_named_objects = false; bool have_object_groups = false; /* create compilers and run the whole thing */ string version = fw->getStr("version"); if (XMLTools::version_compare(version, "8.3")>=0) n = std::auto_ptr( new NATCompiler_asa8(objdb, fw, false, oscnf.get())); else n = std::auto_ptr( new NATCompiler_pix(objdb, fw, false, oscnf.get())); RuleSet *nat = RuleSet::cast(fw->getFirstByType(NAT::TYPENAME)); if (nat) { nat->assignUniqueRuleIds(); n->setNamedObjectsManager(&named_objects_manager); n->setSourceRuleSet(nat); n->setRuleSetName(nat->getName()); n->setPersistentObjects(persistent_objects); if (inTestMode()) n->setTestMode(); if (inEmbeddedMode()) n->setEmbeddedMode(); n->setSingleRuleCompileMode(single_rule_id); n->setDebugLevel( dl ); if (rule_debug_on) n->setDebugRule( drn ); n->setVerbose( verbose ); if ( n->prolog() > 0 ) { n->compile(); n->epilog(); preamble_commands += n->printPreambleCommands(); clear_commands += n->printClearCommands(); have_named_objects = (have_named_objects || named_objects_manager.haveNamedObjects()); have_object_groups = (have_object_groups || named_objects_manager.haveObjectGroups()); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in NAT"); } c = std::auto_ptr( new PolicyCompiler_pix(objdb, fw, false, oscnf.get() , n.get())); RuleSet *policy = RuleSet::cast(fw->getFirstByType(Policy::TYPENAME)); if (policy) { policy->assignUniqueRuleIds(); c->setNamedObjectsManager(&named_objects_manager); c->setSourceRuleSet(policy); c->setRuleSetName(policy->getName()); c->setPersistentObjects(persistent_objects); if (inTestMode()) c->setTestMode(); if (inEmbeddedMode()) c->setEmbeddedMode(); c->setSingleRuleCompileMode(single_rule_id); c->setDebugLevel( dl ); if (rule_debug_on) c->setDebugRule( drp ); c->setVerbose( verbose ); if ( c->prolog() > 0 ) { c->compile(); c->epilog(); preamble_commands += c->printPreambleCommands(); clear_commands += c->printClearCommands(); have_named_objects = (have_named_objects || named_objects_manager.haveNamedObjects()); have_object_groups = (have_object_groups || named_objects_manager.haveObjectGroups()); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in Policy"); } r = std::auto_ptr( new RoutingCompiler_pix(objdb, fw, false, oscnf.get())); RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); if (routing) { routing->assignUniqueRuleIds(); r->setNamedObjectsManager(&named_objects_manager); r->setSourceRuleSet(routing); r->setRuleSetName(routing->getName()); r->setPersistentObjects(persistent_objects); if (inTestMode()) r->setTestMode(); if (inEmbeddedMode()) r->setEmbeddedMode(); r->setSingleRuleCompileMode(single_rule_id); r->setDebugLevel( dl ); if (rule_debug_on) r->setDebugRule( drp ); r->setVerbose( verbose ); if ( r->prolog() > 0 ) { r->compile(); r->epilog(); } else info(" Nothing to compile in Routing"); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } policy_script = c->getCompiledScript(); nat_script = n->getCompiledScript(); routing_script = r->getCompiledScript(); named_objects_and_groups = named_objects_manager.getNamedObjectsDefinitions(); if (c->haveErrorsAndWarnings()) all_errors.push_back(c->getErrors("C ").c_str()); if (n->haveErrorsAndWarnings()) all_errors.push_back(n->getErrors("N ").c_str()); if (r->haveErrorsAndWarnings()) all_errors.push_back(r->getErrors("R ").c_str()); if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (named_objects_and_groups + policy_script + nat_script + routing_script).c_str())); } system_configuration_script = oscnf->getCompiledScript(); system_configuration_script += "\n"; clear_commands += named_objects_manager.getClearCommands() + "\n"; // system_configuration_script += preamble_commands; // system_configuration_script += clear_commands; script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString ofname = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + ofname.toStdString()); QFile fw_file(ofname); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } void CompilerDriver_pix::pixSecurityLevelChecks(Firewall *fw, list &all_interfaces) { for (std::list::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = dynamic_cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) continue; if ((iface->getOptionsObject()->getStr("type") == "" || iface->getOptionsObject()->getStr("type") == "ethernet") && iface->getByType(Interface::TYPENAME).size() > 0) { // Parent vlan interface (i.e. trunk) if (!iface->isUnprotected()) { QString err( "Interface %1 has vlan subinterfaces, it can not " "be used for ACL. Marking this interface \"unprotected\" " "to exclude it." ); warning(fw, NULL, NULL, err.arg(iface->getName().c_str()) .toStdString()); iface->setUnprotected(true); } } // Tests for label, security level and network zone make sense // only for interfaces that can be used in ACLs or to bind // ACLs to. Unnumbered interfaces can't, so we do not need to // run these checks. One example of unnumbered interface is // parent interface for vlan subinterfaces. if (iface->isUnnumbered()) continue; if (iface->isUnprotected()) continue; /* * there shouldn't be two interfaces with the same security level and * same label * */ for (std::list::iterator j=all_interfaces.begin(); j!=all_interfaces.end(); ++j) { Interface *iface2 = dynamic_cast(*j); assert(iface2); if (iface2->isUnnumbered()) continue; if (iface2->isUnprotected()) continue; if (iface->getId()==iface2->getId()) continue; if (iface->getOptionsObject()->getBool("cluster_interface") || iface2->getOptionsObject()->getBool("cluster_interface")) continue; // see #2351. Security levels do not have to be unique // if (iface->getSecurityLevel()==iface2->getSecurityLevel()) // { // QString err( // "Security level of each interface should be unique, " // "however interfaces %1 (%2) and %3 (%4)" // " have the same security level." // ); // abort(fw, NULL, NULL, // err.arg(iface->getName().c_str()) // .arg(iface->getLabel().c_str()) // .arg(iface2->getName().c_str()) // .arg(iface2->getLabel().c_str()).toStdString()); // throw FatalErrorInSingleRuleCompileMode(); // } if (iface->getLabel()==iface2->getLabel()) { QString err( "Label of each interface should be unique, " "however interfaces %1 (%2) and %3 (%4)" " have the same." ); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()) .arg(iface->getLabel().c_str()) .arg(iface2->getName().c_str()) .arg(iface2->getLabel().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } // We only do limited checks for dedicated failover // interfaces because they are not used in ACLs or // anywhere else in configuration, except in "failover" // commands. if (iface->isDedicatedFailover()) continue; } } void CompilerDriver_pix::pixNetworkZoneChecks(Firewall *fw, list &all_interfaces) { multimap netzone_objects; Helper helper(NULL); for (std::list::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = dynamic_cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) continue; if (iface->isDedicatedFailover()) continue; if (iface->isUnprotected()) continue; /* * in PIX, we need network zones to be defined for all * interfaces */ string netzone_id = iface->getStr("network_zone"); if (netzone_id=="") { QString err("Network zone definition is missing for interface '%1' (%2)"); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()) .arg(iface->getLabel().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } FWObject *netzone = objdb->findInIndex( FWObjectDatabase::getIntId(netzone_id)); if (netzone==NULL) { QString err("Network zone points at nonexisting object for " "interface '%1' (%2)"); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()) .arg(iface->getLabel().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } /* * netzone may be a group, in which case we need to expand it * (recursively). * * 1. We create new temporary object (type Group). * * 2. put it in the database somewhere * * 3. add all objects that belong to the network zone to this * group. We add objects directly, not as a reference. * * 4. finally replace reference to the old network zone object in the * interface with reference to this new group. * * 5. we store ID of the original network zone object * using iface->setStr("orig_netzone_id") * * This ensures netzones do not contain other groups and do not * require any recursive expanding anymore. Since objects were added * to netzones directly, we do not need to bother with dereferencing, * too. */ list ol; helper.expand_group_recursive(netzone, ol); FWObject *nz = objdb->createObjectGroup(); assert(nz!=NULL); nz->setName("netzone_" + iface->getLabel()); objdb->add(nz); for (list::iterator j=ol.begin(); j!=ol.end(); ++j) { Address *addr = Address::cast(*j); if (addr == NULL || addr->getAddressPtr() == NULL) { QString err("Network zone of interface '%1' uses object '%2' " "that is not an address"); abort(fw, NULL, NULL, err.arg(iface->getLabel().c_str()) .arg((*j)->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } /* Commented out for SF bug 3213019 currently we do not support ipv6 with PIX/ASA and FWSM. If user creates a group to be used as network zone object and places ipv6 address in it, this address should be ignored while compiling the policy but this should not be an error. Compiler uses network zone group to do various address matching operations when it tries to determine an interface for a rule where user did not specify one. Since we never (should) have ipv6 in policy and nat rules, compiler is not going to have anything to compare to ipv6 address in the network zone even if there is one and this ipv6 address is going to be ignored. if (addr->getAddressPtr()->isV6()) { QString err("Network zone of interface '%1' uses object '%2' " "that is IPv6 address"); abort(fw, NULL, NULL, err.arg(iface->getLabel().c_str()) .arg((*j)->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } */ netzone_objects.insert( pair(iface->getLabel(),*j)); nz->addRef(*j); } iface->setStr("orig_netzone_id", netzone_id ); iface->setStr("network_zone", FWObjectDatabase::getStringId(nz->getId()) ); } /* * the same object (network or host) can not belong to network zones * of two different interfaces. Map netzone_objects holds pairs * interface_id/object. We just make sure the same object does not * appear in two pairs with different interfaces. */ multimap::iterator k; for (k=netzone_objects.begin(); k!=netzone_objects.end(); ++k) { multimap::iterator l; l=k; ++l; for ( ; l!=netzone_objects.end(); ++l) { if ( l->second->getId() == k->second->getId() ) { if (k->first==l->first) { QString err("Object %1 is used more than once in network " "zone of interface '%2'"); abort(fw, NULL, NULL, err.arg(l->second->getName().c_str()) .arg(k->first.c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } else { QString err("Object %1 is used in network zones of " "interfaces '%2' and '%3'"); abort(fw, NULL, NULL, err.arg(l->second->getName().c_str()) .arg(k->first.c_str()) .arg(l->first.c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } } } } /* * Sanity checks for the cluster configuration. Per ticket #606: * * - state sync group must have master * * - one interface must be marked as "dedicated failover" for failover * group. * * - this interface must have failover group with members, one of * which must be master * * - failover interfaces in member firewalls must have ip addresses * which should be different but in the same subnet. * * - possibly another interface can be defined as "dedicated failover" * and used in state sync group. * * - if second interface is used for state sync, it must have ip * address in member firewalls (different) * * - addresses of the dedicated failover interfaces must belong to the * same subnet in each pair of failover inetrfaces (failover and state sync) * * - failover interfaces of both members used in the failover cluster * group of the cluster object must have the same name. * * - The same check should be performed in the state sync group. * * */ void CompilerDriver_pix::pixClusterConfigurationChecks(Cluster *cluster, Firewall*) { if (cluster==NULL) return; FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast(*it); if (state_sync_group->getStr("master_iface").empty()) { QString err("One of the interfaces in the state synchronization group " "must be marked as 'Master'"); abort(cluster, NULL, NULL, err.toStdString()); throw FatalErrorInSingleRuleCompileMode(); } pixClusterGroupChecks(state_sync_group); bool failover_group_inspected = false; list l2 = cluster->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = dynamic_cast(*i); assert(iface); FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( iface->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *member_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(member_iface); pixClusterGroupChecks(failover_group); if (member_iface->isDedicatedFailover()) { failover_group_inspected = true; } } } } } void CompilerDriver_pix::pixClusterGroupChecks(ClusterGroup *cluster_group) { FWObject *cluster = cluster_group; while (cluster && !Cluster::isA(cluster)) cluster = cluster->getParent(); FWObject *cluster_interface = NULL; FWObject *p = cluster_group->getParent(); if (Interface::isA(p)) cluster_interface = p; map addresses_and_masks; for (FWObjectTypedChildIterator it = cluster_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *member_iface = Interface::cast(FWObjectReference::getObject(*it)); assert(member_iface); FWObject *member = Host::getParentHost(member_iface); //FWObject *member = member_iface->getParentHost(); if (cluster_interface) { // check consistency of the names. // In case of PIX the name of the cluster interface should match // names of member interfaces if (cluster_interface->getName() != member_iface->getName()) { QString err("Names of interfaces used in state synchronization " "or failover group must match the name of the " "cluster inetrface. Interface %1:%2 has the name " "that is different from the cluster interface name %3"); abort(cluster, NULL, NULL, err.arg(member->getName().c_str()) .arg(member_iface->getName().c_str()) .arg(cluster_interface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } if (StateSyncClusterGroup::isA(cluster_group) && !member_iface->isDedicatedFailover()) { QString err("Interface %1 is used in a state synchronization " "but is not marked as 'Dedicated Failover' " "interface. All interfaces used for the state " "synchronization or failover must be marked " "'Dedicated Failover'. "); abort(member, NULL, NULL, err.arg(member_iface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } if (!member_iface->isRegular() || member_iface->countInetAddresses(true)==0) { QString err("Interface %1 which is used in state synchronization " "or failover group does not have an IP address. " "All interfaces used for the state " "synchronization or failover must have ip addresses."); abort(member, NULL, NULL, err.arg(member_iface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } QString key("%1:%2"); FWObjectTypedChildIterator it_addr = member_iface->findByType(IPv4::TYPENAME); IPv4* addr = IPv4::cast(*it_addr); addresses_and_masks[key.arg(member->getName().c_str()).arg(member_iface->getName().c_str())] = addr->getInetAddrMaskObjectPtr(); } if (addresses_and_masks.size() >= 2) { QString first_key; const InetAddr *first_network_addr = NULL; map::iterator it; for (it=addresses_and_masks.begin(); it!=addresses_and_masks.end(); ++it) { QString key = it->first; const InetAddrMask *am = it->second; if (first_network_addr == NULL) { first_key = key; first_network_addr = am->getNetworkAddressPtr(); } else { const InetAddr *network_addr = am->getNetworkAddressPtr(); if (*first_network_addr != *(network_addr)) { QString err("Interfaces used in state synchronization " "or failover group must have IP addresses on " "the same subnet. Interfaces %1 and %2 have " "addresses on different subnets: %3 , %4"); abort(cluster, NULL, NULL, err.arg(first_key).arg(key) .arg(first_network_addr->toString().c_str()) .arg(network_addr->toString().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } } } } fwbuilder-5.1.0.3599/src/cisco_lib/ACL.cpp0000644000175000017500000000761011733011756020622 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ACL.h" #include using namespace fwcompiler; using namespace std; string ciscoACL::addLine(const std::string &s) { acl.push_back(s); nlines++; return printLastLine(); } /* * "remark" lines should be less than 101 on PIX/ASA and less than 100 on IOS */ string ciscoACL::trimLine(const string &s) { string trimmed_comment_line; if (s.length() < 100) trimmed_comment_line = s; else trimmed_comment_line = s.substr(0, 100); // remove white space at the beginning and the end string whitespaces(" \t\f\v\n\r"); string::size_type n1,n2; n1 = trimmed_comment_line.find_first_not_of(whitespaces); if (n1 != string::npos) trimmed_comment_line.erase(0, n1); else trimmed_comment_line.clear(); // all whitespace n2 = trimmed_comment_line.find_last_not_of(whitespaces); if (n2 != string::npos) trimmed_comment_line.erase(n2+1); else trimmed_comment_line.clear(); return trimmed_comment_line; } string ciscoACL::quoteLine(const string &s) { if (quote_remarks && s.find(' ') != string::npos) return "\"" + s + "\""; else return s; } /* * Adds remark to access list. Checks and adds each remark only * once. We use rule labels for remarks */ string ciscoACL::addRemark(const std::string &rl, const std::string &comment) { string output; if (_last_rule_label != rl) { acl.push_back(" remark " + quoteLine(trimLine(rl))); output += printLastLine(); nlines++; if (!comment.empty()) { string::size_type n, c1; c1 = 0; string trimmed_comment_line; while ( (n = comment.find("\n", c1)) != string::npos ) { trimmed_comment_line = trimLine(comment.substr(c1, n-c1)); if (!trimmed_comment_line.empty()) { acl.push_back(" remark " + quoteLine(trimmed_comment_line)); output += printLastLine(); nlines++; } c1 = n + 1; } trimmed_comment_line = trimLine(comment.substr(c1, n-c1)); if (!trimmed_comment_line.empty()) { acl.push_back(" remark " + quoteLine(trimmed_comment_line)); output += printLastLine(); nlines++; } } _last_rule_label = rl; return output; } return ""; } string ciscoACL::print() { ostringstream str; for (list::iterator s=acl.begin(); s!=acl.end(); s++) str << printLine(*s); return str.str(); } string ciscoACL::printLastLine() { return printLine(acl.back()); } string ciscoACL::printLine(const string &s) { ostringstream str; // _ip_acl means Cisco IOS "ip access-list extended " style ACL // actual lines of the access list just start with "permit" or "deny" if ( s.find('!')!=0 ) { if (_ip_acl) str << " "; else str << "access-list " << _workName << " "; } str << s << endl; return str.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_procurve_acl_writers.cpp0000644000175000017500000000566311733011756027506 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_procurve_acl.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleSet.h" #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_procurve_acl::printAccessGroupCmd(ciscoACL *acl, bool neg) { if (getSourceRuleSet()->isTop()) { QString dir; if (acl->direction()=="in" || acl->direction()=="Inbound") dir="in"; if (acl->direction()=="out" || acl->direction()=="Outbound") dir="out"; QString addr_family_prefix = "ip"; if (ipv6) addr_family_prefix = "ipv6"; // ProCurve uses different syntax for vlan ACLs Interface *intf = acl->getInterface(); FWOptions *ifopt = intf->getOptionsObject(); string itype = ifopt->getStr("type"); if (itype == "8021q") { int vlan_id = ifopt->getInt("vlan_id"); QStringList outp; if (neg) outp.push_back("no"); outp.push_back("vlan"); outp.push_back(QString("%1").arg(vlan_id)); outp.push_back(addr_family_prefix); outp.push_back(getAccessGroupCommandForAddressFamily(ipv6).c_str()); outp.push_back(acl->workName().c_str()); outp.push_back(dir); return outp.join(" ").toStdString() + "\n"; } else { QStringList outp; QStringList outp_combined; outp_combined.push_back( QString("interface %1").arg(intf->getName().c_str())); if (neg) outp.push_back("no"); outp.push_back(addr_family_prefix); outp.push_back(getAccessGroupCommandForAddressFamily(ipv6).c_str()); outp.push_back(acl->workName().c_str()); outp.push_back(dir); outp_combined.push_back(" " + outp.join(" ")); outp_combined.push_back("exit"); outp_combined.push_back(""); return outp_combined.join("\n").toStdString(); } } return ""; } fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_procurve.h0000644000175000017500000000274011733011756024520 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSNETWORKCONFIGURATOR_PROCURVE_HH #define _OSNETWORKCONFIGURATOR_PROCURVE_HH #include "config.h" #include "OSConfigurator_ios.h" #include namespace fwcompiler { class OSConfigurator_procurve : public OSConfigurator_ios { public: virtual ~OSConfigurator_procurve() {}; OSConfigurator_procurve(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator_ios(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual void processFirewallOptions(); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/IOSObjectGroup.cpp0000644000175000017500000000761711733011756023030 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "IOSObjectGroup.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; const char *IOSObjectGroup::TYPENAME={"IOSObjectGroup"}; QString IOSObjectGroup::groupMemberToString(FWObject *obj, NamedObjectsManager*) throw(libfwbuilder::FWException) { ostringstream ostr; switch (getObjectGroupType()) { case NETWORK: { Address *a = Address::cast(obj); assert(a!=NULL); if (AddressRange::cast(a)) { const InetAddr &start = AddressRange::cast(a)->getRangeStart(); const InetAddr &end = AddressRange::cast(a)->getRangeEnd(); ostr << "range " << start.toString() << " " << end.toString(); } else { const InetAddr *addr = a->getAddressPtr(); if (Network::cast(obj)!=NULL) { const InetAddr *mask = a->getNetmaskPtr(); // Note: the syntax is "A.B.C.D /NN" (there must be space before /) ostr << addr->toString() << " /" << mask->getLength(); } else { ostr << "host " << addr->toString(); } } break; } case PROTO: { Service *s = Service::cast(obj); assert(s!=NULL); ostr << s->getProtocolNumber(); break; } case ICMP_TYPE: { ostr << "icmp "; ICMPService *s = ICMPService::cast(obj); assert(s!=NULL); if ( s->getInt("type")== -1) ostr << ""; else ostr << s->getInt("type"); break; } case TCP_SERVICE: case UDP_SERVICE: { if (getObjectGroupType()==TCP_SERVICE) ostr << "tcp "; else ostr << "udp "; TCPUDPService *s = TCPUDPService::cast(obj); assert(s!=NULL); int rs = s->getDstRangeStart(); int re = s->getDstRangeEnd(); if (rs<0) rs = 0; if (re<0) re = 0; if (rs>0 || re>0) { if (rs==re) ostr << "eq " << rs; else ostr << "range " << rs << " " << re; } else ostr << "range 0 65535"; break; } default: throw FWException("Unknown object group type"); } return ostr.str().c_str(); } string IOSObjectGroup::getObjectGroupClass() { switch (this->getObjectGroupType()) { case NETWORK: return "network"; case PROTO: case ICMP_TYPE: case TCP_SERVICE: case UDP_SERVICE: return "service"; default: throw FWException("Unknown object group type"); } } string IOSObjectGroup::getObjectGroupHeader() { ostringstream ostr; ostr << "object-group " << getObjectGroupClass() << " " << this->getName(); return ostr.str(); } string IOSObjectGroup::getObjectGroupFooter() { return "exit"; } fwbuilder-5.1.0.3599/src/cisco_lib/globalNATPool.cpp0000644000175000017500000000405411733011756022657 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_pix.h" #include "helpers.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Interface.h" using namespace libfwbuilder; using namespace fwcompiler; globalNATPool::globalNATPool(int id,Interface *ifs,Address *a) { nat_id=id; iface=ifs; addr= a; if (Interface::cast(a)!=NULL || iface->isDyn()) { type=INTERFACE; } else { type= (AddressRange::cast(a)!=NULL)?ADDRESS_RANGE:SINGLE_ADDRESS; } } /* * global pool prints itself only once */ ostream& fwcompiler::operator<<(ostream &s,const globalNATPool &pool) { s << "global (" << pool.iface->getLabel() << ") " << pool.pool_no; switch (pool.type) { case globalNATPool::INTERFACE: s << " interface" << endl; break; case globalNATPool::SINGLE_ADDRESS: s << " " << pool.addr->getAddressPtr()->toString() << endl; break; case globalNATPool::ADDRESS_RANGE: AddressRange *ar=AddressRange::cast(pool.addr); s << " " << ar->getRangeStart().toString() << "-" << ar->getRangeEnd().toString() << " netmask " << pool.iface->getNetmask().toString() << endl; break; } return s; } fwbuilder-5.1.0.3599/src/cisco_lib/PIXObjectGroup.h0000644000175000017500000000276111733011756022476 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PIXOBJECTGROUP_HH #define __PIXOBJECTGROUP_HH #include "BaseObjectGroup.h" namespace fwcompiler { class PIXObjectGroup : public BaseObjectGroup { public: PIXObjectGroup() : BaseObjectGroup() { } virtual ~PIXObjectGroup() {}; DECLARE_FWOBJECT_SUBTYPE(PIXObjectGroup); virtual std::string getObjectGroupClass(); virtual std::string getObjectGroupHeader(); virtual std::string getObjectGroupFooter(); virtual QString groupMemberToString( libfwbuilder::FWObject *obj, NamedObjectsManager *named_obj_manager) throw(libfwbuilder::FWException); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObject.h0000644000175000017500000000352311733011756022042 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ASA8_OBJECT_HH #define _ASA8_OBJECT_HH #include "fwbuilder/FWObject.h" #include #include namespace fwcompiler { class NamedObject { const libfwbuilder::FWObject *obj; QString platform; QString name; static QSet reserved_words; QString printPorts(int port_range_start, int port_range_end); protected: QString sanitizeObjectName(const QString &name); QString createNetworkObjectCommand(const libfwbuilder::Address *addr); QString createServiceObjectCommand(const libfwbuilder::Service *addr); public: static std::map name_disambiguation; NamedObject(const libfwbuilder::FWObject *obj, const QString &platform); virtual QString getCommand(); virtual QString getCommandWhenObjectGroupMember(); QString getName() { return name; } QString getCommandWord(); const libfwbuilder::FWObject* getObject() { return obj; } }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/ASA8TwiceNatLogic.h0000644000175000017500000000236411733011756023002 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ASA8_TWICE_NAT_LOGIC_HH #define _ASA8_TWICE_NAT_LOGIC_HH #include "fwbuilder/Rule.h" class ASA8TwiceNatStaticLogic { libfwbuilder::NATRule *rule; int countAddresses(libfwbuilder::FWObject *re); public: enum TwiceNatRuleType {STATIC, DYNAMIC}; ASA8TwiceNatStaticLogic(libfwbuilder::NATRule *rule); TwiceNatRuleType getAutomaticType(); TwiceNatRuleType getType(); }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsAndGroupsSupport.cpp0000644000175000017500000002141711733011756026002 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "NamedObject.h" #include "PIXObjectGroup.h" #include "ASA8ObjectGroup.h" #include "IOSObjectGroup.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Firewall.h" #include "fwcompiler/Compiler.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; CreateObjectGroups::~CreateObjectGroups() { } BaseObjectGroup* CreateObjectGroups::findObjectGroup(RuleElement *re) { list relement; for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1) relement.push_back(FWReference::getObject(*i1)); FWObject *object_groups = named_objects_manager->getObjectGroupsGroup(); for (FWObject::iterator i=object_groups->begin(); i!=object_groups->end(); ++i) { BaseObjectGroup *og = dynamic_cast(*i); assert(og!=NULL); if (og->size()==0 || (og->size()!=re->size()) ) continue; bool match = true; for (FWObject::iterator i1=og->begin(); i1!=og->end(); ++i1) { if ( find(relement.begin(), relement.end(), FWReference::getObject(*i1))==relement.end() ) { match = false; break; } } if (match) return og; } return NULL; } bool CreateObjectGroups::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string version = compiler->fw->getStr("version"); string platform = compiler->fw->getStr("platform"); RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); if (re->size()==1) { /* create object group if the object in the RE is AddressRange * because IOS normally does not support ranges in ACLs, but * supports them in groups */ FWObject *re_obj = FWReference::getObject(re->front()); if ( ! AddressRange::isA(re_obj)) { tmp_queue.push_back(rule); return true; } } BaseObjectGroup *obj_group = findObjectGroup(re); if (obj_group==NULL) { obj_group = named_objects_manager->createObjectGroup(); named_objects_manager->getObjectGroupsGroup()->add(obj_group); packObjects(re, obj_group); obj_group->setObjectGroupTypeFromMembers(named_objects_manager); QStringList group_name_prefix; group_name_prefix.push_back(rule->getUniqueId().c_str()); group_name_prefix.push_back(name_suffix.c_str()); QString reg_name = BaseObjectGroup::registerGroupName( group_name_prefix.join("."), obj_group->getObjectGroupType()); obj_group->setName(reg_name.toUtf8().constData()); } else { re->clearChildren(false); //do not want to destroy children objects re->addRef(obj_group); } tmp_queue.push_back(rule); return true; } void CreateObjectGroups::packObjects(RuleElement *re, BaseObjectGroup *obj_group) { for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); obj_group->addRef(obj); } re->clearChildren(false); //do not want to destroy children objects re->addRef(obj_group); } void CreateObjectGroupsForTSrc::packObjects(RuleElement *re, BaseObjectGroup *obj_group) { if (libfwbuilder::XMLTools::version_compare( compiler->fw->getStr("version"), "8.3")>=0) { // put all objects inside of the group, except for the interface // if it belongs to the firewall FWObject *re_interface = NULL; for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj = FWReference::cast(o)->getPointer(); if (Interface::isA(obj) && obj->isChildOf(compiler->fw)) { re_interface = obj; continue; } obj_group->addRef(obj); } re->clearChildren(false); //do not want to destroy children objects if (re_interface) { // add interface back. re->addRef(re_interface); } re->addRef(obj_group); } else { CreateObjectGroups::packObjects(re, obj_group); } } void createNamedObjectsCommon::printObjectsForRE(FWObject *re) { if (RuleElement::cast(re)!=NULL && RuleElement::cast(re)->isAny()) return; for (FWObject::iterator it=re->begin(); it!=re->end(); ++it) { FWObject *obj = FWReference::getObject(*it); if (Interface::isA(obj)) continue; if (BaseObjectGroup::cast(obj)!=NULL) printObjectsForRE(obj); else named_objects_manager->addNamedObject(obj); } } /* * We only need named objects for address ranges in policy. At least * at this time, we have decided to not create named objects for * everything and use them only in cases where it is inevitable. */ void createNamedObjectsForPolicy::printObjectsForRE(FWObject *re) { if (RuleElement::cast(re)!=NULL && RuleElement::cast(re)->isAny()) return; for (FWObject::iterator it=re->begin(); it!=re->end(); ++it) { FWObject *obj = FWReference::getObject(*it); if (Interface::isA(obj)) continue; if (BaseObjectGroup::cast(obj)!=NULL) printObjectsForRE(obj); if (AddressRange::isA(obj)) named_objects_manager->addNamedObject(obj); } } /* * We support named objects only for ASA 8.3 and in policy rules, only for * address ranges. * * See #1962, it looks like ASA 8.3 does not support named objects or * object-groups in place of port specification in access-list commands. */ bool createNamedObjectsForPolicy::processNext() { slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { PolicyRule *policy_rule = PolicyRule::cast( *k ); if (policy_rule) { RuleElementSrc *src_re = policy_rule->getSrc(); assert(src_re); printObjectsForRE(src_re); RuleElementDst *dst_re = policy_rule->getDst(); assert(dst_re); printObjectsForRE(dst_re); //RuleElementSrv *srv_re = policy_rule->getSrv(); assert(srv_re); //printObjectsForRE(srv_re); } } return true; } bool createNamedObjectsForNAT::processNext() { slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { NATRule *nat_rule = NATRule::cast( *k ); if (nat_rule) { RuleElementOSrc *osrc_re = nat_rule->getOSrc(); assert(osrc_re); printObjectsForRE(osrc_re); RuleElementODst *odst_re = nat_rule->getODst(); assert(odst_re); printObjectsForRE(odst_re); RuleElementOSrv *osrv_re = nat_rule->getOSrv(); assert(osrv_re); printObjectsForRE(osrv_re); RuleElementTSrc *tsrc_re = nat_rule->getTSrc(); assert(tsrc_re); printObjectsForRE(tsrc_re); RuleElementTDst *tdst_re = nat_rule->getTDst(); assert(tdst_re); printObjectsForRE(tdst_re); RuleElementTSrv *tsrv_re = nat_rule->getTSrv(); assert(tsrv_re); printObjectsForRE(tsrv_re); } } return true; } fwbuilder-5.1.0.3599/src/cisco_lib/AutomaticRules_iosacl.cpp0000644000175000017500000000510611733011756024514 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AutomaticRules_iosacl.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; void AutomaticRules_iosacl::addSshAccessRule() { if (ruleset == NULL) return; FWOptions *fwopt = fw->getOptionsObject(); if (fwopt->getBool("mgmt_ssh") && ! fwopt->getStr("mgmt_addr").empty()) { AutomaticRules_cisco::addSshAccessRule(); /* * AutomaticRules_cisco::addDefaultPolicyRule() adds a rule to * permit backup ssh access to the firewall. Since IOS ACL are * stateless, we need to add another rule to permit reply * packets. */ TCPService *ssh_rev = ruleset->getRoot()->createTCPService(); ssh_rev->setSrcRangeStart(22); ssh_rev->setSrcRangeEnd(22); persistent_objects->add(ssh_rev, false); Network *mgmt_workstation = ruleset->getRoot()->createNetwork(); mgmt_workstation->setAddressNetmask(fwopt->getStr("mgmt_addr")); persistent_objects->add(mgmt_workstation, false); addMgmtRule( fw, mgmt_workstation, ssh_rev, NULL, PolicyRule::Outbound, PolicyRule::Accept, "backup ssh access rule (out)"); } } fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsAndGroupsSupport.h0000644000175000017500000001172111733011756025444 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OBJECT_GROUPS_SUPPORT_HH #define _OBJECT_GROUPS_SUPPORT_HH #include "config.h" #include "BaseObjectGroup.h" #include "NamedObject.h" #include "fwbuilder/Group.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwcompiler/RuleProcessor.h" namespace fwcompiler { class CreateObjectGroups : public BasicRuleProcessor { protected: std::string re_type; std::string name_suffix; NamedObjectsManager *named_objects_manager; BaseObjectGroup* findObjectGroup(libfwbuilder::RuleElement *re); virtual void packObjects(libfwbuilder::RuleElement *re, BaseObjectGroup *obj_group); public: CreateObjectGroups(const std::string &name, const std::string &_ns, const std::string &_type, NamedObjectsManager *m) : BasicRuleProcessor(name) { re_type=_type; name_suffix=_ns; named_objects_manager = m; } virtual ~CreateObjectGroups(); virtual bool processNext(); }; class CreateObjectGroupsForSrc : public CreateObjectGroups { public: CreateObjectGroupsForSrc(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"src",libfwbuilder::RuleElementSrc::TYPENAME, m) {} }; class CreateObjectGroupsForDst : public CreateObjectGroups { public: CreateObjectGroupsForDst(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"dst",libfwbuilder::RuleElementDst::TYPENAME, m) {} }; class CreateObjectGroupsForSrv : public CreateObjectGroups { public: CreateObjectGroupsForSrv(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"srv",libfwbuilder::RuleElementSrv::TYPENAME, m) {} }; // ################################################################ // OSrc, ODst, OSrv, TSrc class CreateObjectGroupsForOSrc : public CreateObjectGroups { public: CreateObjectGroupsForOSrc(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"osrc",libfwbuilder::RuleElementOSrc::TYPENAME, m){} }; class CreateObjectGroupsForODst : public CreateObjectGroups { public: CreateObjectGroupsForODst(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"odst",libfwbuilder::RuleElementODst::TYPENAME, m){} }; class CreateObjectGroupsForOSrv : public CreateObjectGroups { public: CreateObjectGroupsForOSrv(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"osrv",libfwbuilder::RuleElementOSrv::TYPENAME, m){} }; class CreateObjectGroupsForTSrc : public CreateObjectGroups { protected: virtual void packObjects(libfwbuilder::RuleElement *re, BaseObjectGroup *obj_group); public: CreateObjectGroupsForTSrc(const std::string &n, NamedObjectsManager *m) : CreateObjectGroups(n,"tsrc",libfwbuilder::RuleElementTSrc::TYPENAME, m){} }; class createNamedObjectsCommon : public BasicRuleProcessor { protected: virtual void printObjectsForRE(libfwbuilder::FWObject *re); NamedObjectsManager *named_objects_manager; public: createNamedObjectsCommon(const std::string &n, NamedObjectsManager *_m) : BasicRuleProcessor(n) { named_objects_manager = _m; } }; class createNamedObjectsForPolicy : public createNamedObjectsCommon { protected: virtual void printObjectsForRE(libfwbuilder::FWObject *re); public: createNamedObjectsForPolicy(const std::string &n, NamedObjectsManager *m) : createNamedObjectsCommon(n, m) {} virtual bool processNext(); }; class createNamedObjectsForNAT : public createNamedObjectsCommon { public: createNamedObjectsForNAT(const std::string &n, NamedObjectsManager *m) : createNamedObjectsCommon(n, m) {} virtual bool processNext(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_pix_os_inspectors.cpp0000644000175000017500000001244011733011756026756 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator_pix_os.h" #include "inspectionProtocol.h" #include "inspectionClassMap.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* ******************************************************************** * * Generating class-map, class and match commands instead of fixups * for PIX 7.0 * * ********************************************************************/ string OSConfigurator_pix_os::_printMPFPolicyMap() { ostringstream res; string platform = fw->getStr("platform"); string version = fw->getStr("version"); string vers = "version_" + version; FWOptions *options = fw->getOptionsObject(); assert(options!=NULL); std::list defaultClassMaps; std::list customClassMaps; std::map DefaultInspectionInspectStatements; std::map CustomInspectionInspectStatements; QStringList allowed_fixups = QString(Resources::platform_res[platform]->getResourceStr( "/FWBuilderResources/Target/options/" + vers + "/fixups/list").c_str()).split(","); defaultClassMaps.clear(); customClassMaps.clear(); DefaultInspectionInspectStatements.clear(); CustomInspectionInspectStatements.clear(); foreach (QString fixup_xml_element, allowed_fixups) { string f = options->getStr(fixup_xml_element.toAscii().constData()); if (!f.empty()) { QString fixup_name = fixup_xml_element.replace("_fixup", ""); int status; int p1,p2; string an; int av; istringstream str(f); str >> status >> p1 >> p2 >> an >> av; /* We should really fix this in the GUI and pass max length parameter * as an/av rather than as port p1 */ if (fixup_name == "dns" && p1 != 0) { an = "maximum-length"; av = p1; p1 = 53; } if (fixup_name.startsWith("ip_options")) { continue; } InspectionClassMap cm(fixup_name.toAscii().constData(), status, p1, p2, an, av); if (cm.isDefault()) defaultClassMaps.push_back(cm); else customClassMaps.push_back(cm); } } res << "class-map inspection_default" << endl; res << " match default-inspection-traffic" << endl; res << endl; std::list::iterator i1; if (customClassMaps.size()>0) { for (i1=customClassMaps.begin(); i1!=customClassMaps.end(); i1++) { res << "class-map " << i1->class_map_name << endl; res << " " << i1->getMatchCommand() << endl; } res << endl; } res << "policy-map global_policy" << endl; if (defaultClassMaps.size()>0) { res << " class inspection_default" << endl; for (i1=defaultClassMaps.begin(); i1!=defaultClassMaps.end(); i1++) { string pn = i1->getPrintableName(); if (i1->status!=FIXUP_SKIP && DefaultInspectionInspectStatements[pn]!=1) { res << " "; if (i1->status==FIXUP_DISABLE) res << "no "; res << "inspect " << pn << endl; DefaultInspectionInspectStatements[pn]=1; } } } if (customClassMaps.size()>0) { for (i1=customClassMaps.begin(); i1!=customClassMaps.end(); i1++) { string pn = i1->getPrintableName(); if (i1->status!=FIXUP_SKIP && CustomInspectionInspectStatements[pn]!=1) { res << " class " << i1->class_map_name << endl; res << " "; if (i1->status==FIXUP_DISABLE) res << "no "; res << "inspect " << i1->getPrintableName() << endl; CustomInspectionInspectStatements[pn]=1; } } } res << endl; res << "service-policy global_policy global" << endl; res << endl; return res.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_pix.h0000644000175000017500000000621211733011756023473 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_PIX_HH__ #define __COMPILER_DRIVER_PIX_HH__ #include "CompilerDriver.h" #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; }; namespace fwcompiler { class CompilerDriver_pix : public CompilerDriver { protected: std::string clear_commands; std::string preamble_commands; std::string system_configuration_script; std::string named_objects_and_groups; std::string nat_script; std::string policy_script; std::string routing_script; void pixSecurityLevelChecks(libfwbuilder::Firewall *fw, std::list &all_interfaces); void pixNetworkZoneChecks(libfwbuilder::Firewall *fw, std::list &all_interfaces); void pixClusterGroupChecks(libfwbuilder::ClusterGroup *clgrp); void pixClusterConfigurationChecks(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall *fw); std::string safetyNetInstall(libfwbuilder::Firewall *fw); void printProlog(QTextStream &file, const std::string &prolog_code); virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); virtual QString printActivationCommands(libfwbuilder::Firewall *fw); virtual QString assembleFwScript(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf); public: CompilerDriver_pix(libfwbuilder::FWObjectDatabase *db); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); std::string protocolInspectorCommands(); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/specialServices.cpp0000644000175000017500000000540011733011756023342 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "specialServices.h" #include "PolicyCompiler_pix.h" #include "fwbuilder/IPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/CustomService.h" #include "fwcompiler/Compiler.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; bool SpecialServices::processNext() { PolicyCompiler_pix *pix_comp = dynamic_cast(compiler); Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); if (re->size() == 0) { cerr << "Rule " << rule->getLabel() << "rule element " << re_type << " is empty" << endl; assert(re->size() != 0); } FWObject *obj = FWReference::getObject(re->front()); Service *s = Service::cast(obj); string version = compiler->fw->getStr("version"); if (IPService::cast(s)!=NULL) { if (s->getBool("short_fragm") || s->getBool("fragm") ) { if (pix_comp) pix_comp->fragguard = true; return true; // do not copy the rule } if (s->getBool("rr") || s->getBool("ssrr") || s->getBool("ts") ) { compiler->abort( rule, "PIX does not support checking for IP options in ACLs."); return true; } } if (TCPService::cast(s)!=NULL) { if (s->getBool("ack_flag") || s->getBool("fin_flag") || s->getBool("rst_flag") || s->getBool("syn_flag") ) { compiler->abort( rule, "PIX does not support checking for TCP options in ACLs."); return true; } } if (CustomService::cast(s)!=NULL && pix_comp==NULL) { compiler->abort( rule, "CustomService objects are not supported in NAT rules"); return true; } tmp_queue.push_back(rule); return true; } fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_asa8_writers.cpp0000644000175000017500000001374611733011756025042 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_asa8.h" #include "NamedObject.h" #include "ASA8TwiceNatLogic.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Resources.h" #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; NATCompiler_asa8::PrintRule::PrintRule(const std::string &name) : NATCompiler_pix::PrintRule(name) { } void NATCompiler_asa8::PrintRule::printNONAT(libfwbuilder::NATRule *rule) { printSDNAT(rule); } void NATCompiler_asa8::PrintRule::printSNAT(libfwbuilder::NATRule *rule) { printSDNAT(rule); } void NATCompiler_asa8::PrintRule::printDNAT(libfwbuilder::NATRule *rule) { printSDNAT(rule); } QString NATCompiler_asa8::PrintRule::printSingleObject(FWObject *obj) { NATCompiler_asa8 *pix_comp = dynamic_cast(compiler); if (Address::cast(obj) && Address::cast(obj)->isAny()) return "any"; NamedObject* asa8_object = pix_comp->named_objects_manager->getNamedObject(obj); if (asa8_object) return asa8_object->getCommandWord(); if (BaseObjectGroup::cast(obj)!=NULL) return obj->getName().c_str(); if (Interface::isA(obj) && obj->isChildOf(compiler->fw)) return "interface"; QString err("Found unknown object '%1' in the NAT rule: it is not " "an ASA8 object, object group or an interface of the firewall"); compiler->abort(err.arg(obj->getName().c_str()).toStdString()); return ""; } void NATCompiler_asa8::PrintRule::printSDNAT(NATRule *rule) { FWOptions *ropt = rule->getOptionsObject(); QStringList cmd; RuleElementOSrc *osrc_re = rule->getOSrc(); assert(osrc_re!=NULL); FWObject *osrc = FWReference::getObject(osrc_re->front()); RuleElementODst *odst_re = rule->getODst(); assert(odst_re!=NULL); FWObject *odst = FWReference::getObject(odst_re->front()); RuleElementOSrv *osrv_re = rule->getOSrv(); assert(osrv_re!=NULL); FWObject *osrv = FWReference::getObject(osrv_re->front()); RuleElementTSrc *tsrc_re = rule->getTSrc(); assert(tsrc_re!=NULL); Address *tdst = compiler->getFirstTDst(rule); assert(tdst); Service *tsrv = compiler->getFirstTSrv(rule); assert(tsrv); RuleElementItfInb *itf_in_re = rule->getItfInb(); assert(itf_in_re!=NULL); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); assert(itf_out_re!=NULL); Interface *i_iface = Interface::cast( FWObjectReference::getObject(itf_in_re->front())); Interface *o_iface = Interface::cast( FWObjectReference::getObject(itf_out_re->front())); cmd << QString("nat (%1,%2)") .arg(i_iface->getLabel().c_str()) .arg(o_iface->getLabel().c_str()); cmd << "source"; switch (ASA8TwiceNatStaticLogic(rule).getType()) { case ASA8TwiceNatStaticLogic::STATIC: cmd << "static"; break; case ASA8TwiceNatStaticLogic::DYNAMIC: cmd << "dynamic"; break; } cmd << printSingleObject(osrc); if (tsrc_re->isAny()) cmd << printSingleObject(osrc); else { // TSrc can have one object, which can be either an address or // a group, or two objects in which case one must be an interface if (tsrc_re->size() == 1) { FWObject *tsrc = FWReference::getObject(tsrc_re->front()); cmd << printSingleObject(tsrc); } else { // first, print name of the address or group, then interface bool have_interface = false; for (FWObject::iterator it=tsrc_re->begin(); it!=tsrc_re->end(); ++it) { FWObject *obj = FWReference::getObject(*it); if (Interface::isA(obj)) { have_interface = true; continue; } else { cmd << printSingleObject(obj); break; } } if (have_interface) cmd << "interface"; } } // only need "destination" part if ODst is not any if (!odst_re->isAny()) { // ASA documentation says destination translation is always "static" cmd << "destination" << "static"; cmd << printSingleObject(odst); if (tdst->isAny()) cmd << printSingleObject(odst); else cmd << printSingleObject(tdst); } if (!osrv_re->isAny()) { cmd << "service"; cmd << printSingleObject(osrv); if (tsrv->isAny()) cmd << printSingleObject(osrv); else cmd << printSingleObject(tsrv); } if (ropt->getBool("asa8_nat_dns")) cmd << "dns"; cmd << QString("description \"%1\"").arg(rule->getLabel().c_str()); compiler->output << cmd.join(" ").toStdString() << endl; } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_iosacl_writers.cpp0000644000175000017500000001140311733011756026451 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RoutingCompiler_iosacl.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ RoutingCompiler_iosacl::PrintRule::PrintRule(const std::string &name) : RoutingCompiler_cisco::PrintRule(name) { } bool RoutingCompiler_iosacl::PrintRule::processNext() { RoutingRule *rule = getNext(); if (rule == NULL) return false; tmp_queue.push_back(rule); string rl = rule->getLabel(); string comm = rule->getComment(); string::size_type c1, c2; c1 = 0; if (!compiler->inSingleRuleCompileMode() && rl != current_rule_label) { compiler->output << "! " << endl; compiler->output << "! Rule " << rl << endl; compiler->output << "! " << endl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) compiler->output << "# " << err << endl; if( rule->getRuleType() != RoutingRule::MultiPath ) { if (!compiler->inSingleRuleCompileMode() && rl != current_rule_label) { while ( (c2 = comm.find('\n',c1)) != string::npos ) { compiler->output << "! " << comm.substr(c1,c2-c1) << endl; c1 = c2 + 1; } compiler->output << "! " << comm.substr(c1) << endl; compiler->output << "! " << endl; string err = compiler->getErrorsForRule(rule, "! "); if (!err.empty()) compiler->output << err << endl; current_rule_label = rl; } string command_line = RoutingRuleToString(rule); compiler->output << command_line; } else { string err = compiler->getErrorsForRule(rule, "! "); if (!err.empty()) compiler->output << err << endl; compiler->abort(rule, "MultiPath routing not supported by platform"); } return true; } string RoutingCompiler_iosacl::PrintRule::_printRGtw(RoutingRule *rule) { FWObject *ref; RuleElementRGtw *gtwrel = rule->getRGtw(); ref = gtwrel->front(); Address *gtw = Address::cast(FWReference::cast(ref)->getPointer()); if (Interface::isA(gtw) && gtw->isChildOf(compiler->fw)) { // gateway is interface of this firewall. Generate command // ip route A.B.C.D N.N.N.N interface metric return gtw->getName() + " "; } string gateway = _printAddr(gtw); if (gateway != "default ") return gateway; else return " "; } string RoutingCompiler_iosacl::PrintRule::_printRItf(RoutingRule *rule) { RuleElementRItf *itfrel = rule->getRItf(); if (!itfrel->isAny()) { Interface *itf = Interface::cast(FWObjectReference::getObject(itfrel->front())); if (itf != NULL) return itf->getName() + " "; } return ""; } string RoutingCompiler_iosacl::PrintRule::RoutingRuleToString(RoutingRule *rule) { FWObject *ref; RuleElementRDst *dstrel = rule->getRDst(); ref = dstrel->front(); Address *dst = Address::cast(FWReference::cast(ref)->getPointer()); if(dst == NULL) compiler->abort(rule, "Broken DST"); std::ostringstream command_line; command_line << "ip route "; command_line << _printRDst(rule); command_line << _printRGtw(rule); command_line << _printRItf(rule); // default metric in IOS is 1 (can't have metric 0) if (rule->getMetricAsString() == "0") { command_line << "1"; } else { command_line << rule->getMetricAsString(); } command_line << endl; return command_line.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/PortRangeConverter.h0000644000175000017500000000346311733011756023463 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PORT_RANGE_CONVERTER_HH #define _PORT_RANGE_CONVERTER_HH #include #include class PortRangeConverter { int rs; int re; public: PortRangeConverter(int range_start, int range_end) { rs = range_start; re = range_end; } std::string toString() { std::ostringstream str; if (rs<0) rs = 0; if (re<0) re = 0; if (rs>0 || re>0) { if (rs==re) str << "eq " << rs << " "; else { if (rs==0 && re!=0) { str << "lt " << re + 1 << " "; } else { if (rs!=0 && re==65535) { str << "gt " << rs - 1 << " "; } else { str << "range " << rs << " " << re << " "; } } } } return str.str(); } }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_pix.cpp0000644000175000017500000000753111733011756024227 0ustar sylvestresylvestre/* * Copyright (c) 2008 Steven Mestdagh * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "RoutingCompiler_pix.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Network.h" #include using namespace libfwbuilder; using namespace fwcompiler; string RoutingCompiler_pix::myPlatformName() { return "pix"; } int RoutingCompiler_pix::prolog() { int n = RoutingCompiler_cisco::prolog(); string platform = fw->getStr("platform"); if (platform!="pix" && platform!="fwsm") abort("Unsupported platform " + platform ); return n; } void RoutingCompiler_pix::epilog() { } bool RoutingCompiler_pix::emptyRDstOrRItf::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRGtw *gtwrel = rule->getRGtw(); RuleElementRItf *itfrel = rule->getRItf(); if (itfrel->isAny() || gtwrel->isAny()) { compiler->abort( rule, "Interface and gateway rule elements can not be empty in " "the PIX routing rule"); } return true; } /** *----------------------------------------------------------------------- */ void RoutingCompiler_pix::compile() { printRule = new RoutingCompiler_pix::PrintRule(""); info(" Compiling routing rules for " + fw->getName()); Compiler::compile(); add(new RoutingCompiler::Begin()); add(new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new recursiveGroupsInRDst("Check for recursive Groups in RDst")); add(new emptyGroupsInRDst("Check for empty Groups in RDst")); add(new emptyRDstOrRItf("Check if RDst or RItf is empty")); add(new singleAdressInRGtw( "Check if RGtw object has exactly one IP adress")); add(new rItfChildOfFw("Check if RItf is an Iterface of this firewall")); add(new validateNetwork("Validate network addresses")); add(new reachableAddressInRGtw( "Check if RGtw is reachable via local networks")); add(new contradictionRGtwAndRItf( "Check if RGtw is in a network of RItf")); add(new ExpandGroups("Expand groups in DST")); add(new ExpandMultipleAddresses( "Expand objects with multiple addresses in DST")); add(new eliminateDuplicatesInDST("Eliminate duplicates in DST")); add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'competingRules'")); add(new competingRules("Check for competing rules")); add(new ConvertToAtomicForDST( "Convert to atomic rules by dst address elements")); add(new createSortedDstIdsLabel( "Create label with a sorted dst-id-list for 'classifyRoutingRules'")); add(new classifyRoutingRules( "Classify into single path or part of a multi path rule")); add(new eliminateDuplicateRules( "Eliminate duplicate rules over the whole table")); add(new PrintRule("generate ip code")); add(new simplePrintProgress()); runRuleProcessors(); } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_pix.cpp0000644000175000017500000000432011733011756024024 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "CompilerDriver_pix.h" #include "PolicyCompiler_pix.h" #include "OSConfigurator_pix_os.h" #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver_pix::CompilerDriver_pix(FWObjectDatabase *db) : CompilerDriver(db) { } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_pix::clone() { CompilerDriver_pix* new_cd = new CompilerDriver_pix(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } string CompilerDriver_pix::protocolInspectorCommands() { OSConfigurator_pix_os oscnf(objdb , locateObject(), false); oscnf.prolog(); return oscnf.getProtocolInspectionCommands(); } void CompilerDriver_pix::printProlog(QTextStream &file, const string &prolog_code) { file << endl; file << "#" << endl; file << "# Prolog script" << endl; file << "#" << endl; file << prolog_code << endl; file << "#" << endl; file << "# End of prolog script" << endl; file << "#" << endl; } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_pix_writers.cpp0000644000175000017500000003455511733011756025624 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PolicyCompiler_pix.h" #include "PIXObjectGroup.h" #include "NamedObjectsManager.h" #include "PortRangeConverter.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_pix::PrintRule::_printAction(PolicyRule *rule) { ostringstream str; switch (rule->getAction()) { case PolicyRule::Accept: str << "permit "; break; case PolicyRule::Deny: str << "deny "; break; case PolicyRule::Reject: str << "deny "; break; default: str << rule->getActionAsString() << " "; } return str.str(); } string PolicyCompiler_pix::PrintRule::_printACL(PolicyRule *rule) { // PolicyCompiler_pix *pix_comp=dynamic_cast(compiler); string acl_name=rule->getStr("acl"); assert (acl_name!=""); return acl_name+" "; } string PolicyCompiler_pix::PrintRule::_printLog(PolicyRule *rule) { string platform = compiler->fw->getStr("platform"); string vers = compiler->fw->getStr("version"); if (platform=="pix" && (vers=="6.1" || vers=="6.2")) return ""; // PolicyCompiler_pix *pix_comp=dynamic_cast(compiler); FWOptions *ruleopt =rule->getOptionsObject(); QStringList str; if (ruleopt->getBool("disable_logging_for_this_rule")) return "log disable "; if (rule->getLogging()) { string level = ruleopt->getStr("log_level"); int logint = ruleopt->getInt("log_interval"); /* * PIX always adds logging interval in "show * access-list" command, * so we should always add it, too. Otherwise ACL lines look * different when diff is generated. */ if (logint<=0) logint = Resources::platform_res[platform]->getResourceInt( string("/FWBuilderResources/Target/options/") + "version_" + compiler->fw->getStr("version") + "/pix_default_logint"); if (level.empty()) level = compiler->fw->getOptionsObject()->getStr( "pix_logging_trap_level"); if (level.empty()) level = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + compiler->fw->getStr("version") + "/pix_default_loglevel"); if (level=="alert") level = "1"; if (level=="crit") level = "2"; if (level=="error") level = "3"; if (level=="warning") level = "4"; if (level=="notice") level = "5"; if (level=="info") level = "6"; if (level=="debug") level = "7"; str << "log" << level.c_str(); if (logint>0 || platform=="pix") // can't use "interval 0" on fwsm { str << "interval" << QString().setNum(logint); } } return str.join(" ").toStdString(); } string PolicyCompiler_pix::PrintRule::_printPortRangeOp(int rs, int re) { return PortRangeConverter(rs, re).toString(); } string PolicyCompiler_pix::PrintRule::_printSrcService(Service *srv) { if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getSrcRangeStart(); int re = TCPUDPService::cast(srv)->getSrcRangeEnd(); return _printPortRangeOp(rs, re); } return ""; } string PolicyCompiler_pix::PrintRule::_printDstService(Service *srv) { ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs=TCPUDPService::cast(srv)->getDstRangeStart(); int re=TCPUDPService::cast(srv)->getDstRangeEnd(); str << _printPortRangeOp(rs, re); } if (ICMPService::isA(srv) && srv->getInt("type")!=-1) { str << srv->getStr("type") << " "; } if (CustomService::isA(srv)) { str << CustomService::cast(srv)->getCodeForPlatform( compiler->myPlatformName() ) << " "; } const IPService *ip_srv = IPService::constcast(srv); if (ip_srv && ip_srv->hasIpOptions()) compiler->warning("PIX can not match IP options"); return str.str(); } string PolicyCompiler_pix::PrintRule::_printAddr(libfwbuilder::Address *o) { if (Interface::cast(o)!=NULL) { Interface *interface_=Interface::cast(o); if (interface_->isDyn()) { return string("interface ") + interface_->getLabel() + " "; } } ostringstream str; const InetAddr *srcaddr = o->getAddressPtr(); if (srcaddr) { InetAddr srcmask = *(o->getNetmaskPtr()); if (Interface::cast(o)!=NULL) srcmask = InetAddr(InetAddr::getAllOnes()); if (IPv4::cast(o)!=NULL) srcmask = InetAddr(InetAddr::getAllOnes()); if (srcaddr->isAny() && srcmask.isAny()) { str << "any "; } else { if (srcmask.isHostMask()) { str << "host " << srcaddr->toString() << " "; } else { str << srcaddr->toString() << " "; str << srcmask.toString() << " "; } } return str.str(); } ostringstream errstr; errstr << "Object " << o->getName() << " (id=" << o->getId() << ") " << " has no ip address and can not be used " << "in the rule."; compiler->abort(errstr.str()); return ""; // to make compiler happy } bool PolicyCompiler_pix::PrintRule::suppressDuplicateICMPCommands(const string &cmd) { list::iterator i; i = std::find(seen_icmp_commands.begin(), seen_icmp_commands.end(), cmd); if (i!=seen_icmp_commands.end()) return true; seen_icmp_commands.push_back(cmd); return false; } string PolicyCompiler_pix::PrintRule::_printICMPCommand(PolicyRule *rule) { ostringstream str; Address *src = compiler->getFirstSrc(rule); RuleElementSrv *srvrel = rule->getSrv(); FWObject *srv = srvrel->front(); if (FWReference::cast(srv)!=NULL) srv = FWReference::cast(srv)->getPointer(); // Interface *rule_iface = // Interface::cast(compiler->dbcopy->findInIndex(rule->getInterfaceId())); RuleElementItf *intf_re = rule->getItf(); Interface *rule_iface = Interface::cast( FWObjectReference::getObject(intf_re->front())); assert(rule_iface); if (PIXObjectGroup::cast(srv)!=NULL) { for (FWObject::iterator i1=srv->begin(); i1!=srv->end(); ++i1) { ICMPService *s = ICMPService::cast(FWReference::getObject(*i1)); assert(s!=NULL); ostringstream str1; str1 << "icmp "; str1 << _printAction(rule); str1 << _printAddr( src ); str1 << s->getStr("type"); str1 << " "; str1 << rule_iface->getLabel(); str1 << endl; if ( ! suppressDuplicateICMPCommands(str1.str())) str << str1.str(); } return str.str(); } else { str << "icmp "; str << _printAction(rule); str << _printAddr( src ); str << _printDstService( Service::cast(srv) ); str << " "; str << rule_iface->getLabel(); str << endl; if ( ! suppressDuplicateICMPCommands(str.str())) return str.str(); } return ""; } string PolicyCompiler_pix::PrintRule::_printSSHTelnetCommand(PolicyRule *rule) { ostringstream str; int port; RuleElementSrc *rel = rule->getSrc(); Service *srv = compiler->getFirstSrv(rule); RuleElementItf *intf_re = rule->getItf(); Interface *rule_iface = Interface::cast( FWObjectReference::getObject(intf_re->front())); assert(rule_iface); port = TCPUDPService::cast(srv)->getDstRangeStart(); for (FWObject::iterator i=rel->begin(); i!=rel->end(); ++i) { FWObject *o = FWReference::getObject(*i); if (dynamic_cast(o)!=NULL) { for (FWObject::iterator j=o->begin(); j!=o->end(); ++j) { Address *a = Address::cast(FWReference::getObject(*j)); assert(a!=NULL); str << _printSingleSSHTelnetCommand(port, a, rule_iface->getLabel()); } } else { Address *a = Address::cast(o); assert(a!=NULL); str << _printSingleSSHTelnetCommand(port, a, rule_iface->getLabel()); } } return str.str(); } string PolicyCompiler_pix::PrintRule::_printSingleSSHTelnetCommand( int port, Address *a, const string &interfaceLabel) { string res; if (port==22) res = "ssh "; if (port==23) res = "telnet "; if (port==80) res = "http "; if (!res.empty()) { res += a->getAddressPtr()->toString() + " " + a->getNetmaskPtr()->toString() + " " + interfaceLabel + "\n"; } return res; } /* * the following additional attributes should have been defined by now: * * "acl" - string, name of the access list * choices are: outside-in, outside-out, inside-in, indside-out, * dmz-in, dmz-out etc. * General rule for the acl name: "iface_name-{in,out}" */ bool PolicyCompiler_pix::PrintRule::processNext() { PolicyCompiler_pix *pix_comp = dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); ostringstream comment; compiler->output << compiler->printComment(rule, current_rule_label1, "!"); if (rule->getBool("icmp_cmd")) { compiler->output << _printICMPCommand(rule); // need to generate access list command as well as icmp command // in order to properly serve icmp through nat // 04/21/06 --vk // return true; } if (rule->getBool("tcp_service_to_fw")) { compiler->output << _printSSHTelnetCommand(rule); return true; } /* * all three rule elements contain exactly one object, which can * be either group (in case processor CreateObjectGroups created * object group for it) or a regular object */ RuleElementSrc *src = rule->getSrc(); RuleElementDst *dst = rule->getDst(); RuleElementSrv *srv = rule->getSrv(); assert(src->size()==1); assert(dst->size()==1); assert(srv->size()==1); FWObject *srcobj = FWReference::getObject(src->front()); FWObject *dstobj = FWReference::getObject(dst->front()); FWObject *srvobj = FWReference::getObject(srv->front()); assert(srcobj); assert(dstobj); assert(srvobj); ostringstream aclstr; string acl_name = rule->getStr("acl"); assert(acl_name!=""); ciscoACL *acl = pix_comp->acls[acl_name]; assert(acl!=NULL); if (compiler->fw->getOptionsObject()->getBool("pix_use_acl_remarks")) { compiler->output << acl->addRemark(rule->getLabel(), rule->getComment()); } /* * Assemble ACL command in aclstr */ aclstr << _printAction(rule); /* * processor groupServicesByProtocol guaranties that rule has * services of the same type (that is, the same protocol, like all * tcp, all udp, all icmp or all IP with the same protocol * number). PIX can use object-group for protocol only if protocol * numbers are different and these are not icmp/tcp/udp * protocols. This means that because of processor * groupServicesByProtocol we never use object-group in protocol * part of ACL. */ PIXObjectGroup *pgsrv = PIXObjectGroup::cast(srvobj); PIXObjectGroup *pgsrc = PIXObjectGroup::cast(srcobj); PIXObjectGroup *pgdst = PIXObjectGroup::cast(dstobj); Service *srv_s = Service::cast(srvobj); assert(pgsrv!=NULL || srv_s!=NULL); if ( pgsrv!=NULL && pgsrv->isServiceGroup()) { aclstr << pgsrv->getSrvTypeName(); } else aclstr << srv_s->getProtocolName(); aclstr << " "; NamedObject* asa8_object; asa8_object = pix_comp->named_objects_manager->getNamedObject(srcobj); if (asa8_object) { aclstr << "object " << asa8_object->getCommandWord().toStdString() << " "; } else { if (pgsrc!=NULL) { aclstr << "object-group " << srcobj->getName() << " "; } else { aclstr << _printAddr(Address::cast(srcobj)); } } if ( pgsrv==NULL ) aclstr << _printSrcService( compiler->getFirstSrv(rule) ); asa8_object = pix_comp->named_objects_manager->getNamedObject(dstobj); if (asa8_object) { aclstr << "object " << asa8_object->getCommandWord().toStdString() << " "; } else { if (pgdst!=NULL) { aclstr << "object-group " << dstobj->getName() << " "; } else { aclstr << _printAddr(Address::cast(dstobj)); } } if (pgsrv!=NULL) { aclstr << "object-group " << srvobj->getName() << " "; } else { aclstr << _printDstService(Service::cast(srvobj)); } aclstr << _printLog( rule ); // aclstr << endl; compiler->output << acl->addLine(aclstr.str()); return true; } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_procurve_acl.h0000644000175000017500000000325111733011756025553 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id: RoutingCompiler_procurve.h -1 $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ROUTINGCOMPILER_PROCURVE_ACL_HH__ #define __ROUTINGCOMPILER_PROCURVE_ACL_HH__ #include #include "config.h" #include "RoutingCompiler_iosacl.h" namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_procurve_acl : public RoutingCompiler_iosacl { protected: virtual std::string myPlatformName(); public: RoutingCompiler_procurve_acl(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler_iosacl(_db, fw, ipv6_policy, _oscnf) {} virtual int prolog(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_cisco_writers.cpp0000644000175000017500000001040711733011756026302 0ustar sylvestresylvestre/* * Copyright (c) 2008 Steven Mestdagh * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "RoutingCompiler_cisco.h" #include "NamedObjectsAndGroupsSupport.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ RoutingCompiler_cisco::PrintRule::PrintRule(const std::string &name) : RoutingRuleProcessor(name) { } bool RoutingCompiler_cisco::PrintRule::processNext() { RoutingRule *rule = getNext(); if (rule == NULL) return false; tmp_queue.push_back(rule); return true; } string RoutingCompiler_cisco::PrintRule::_printAddr(Address *o) { std::ostringstream ostr; if (Interface::cast(o)!=NULL) { Interface *iface=Interface::cast(o); if (iface->isDyn()) ostr << "$interface_" << iface->getName() << " "; return ostr.str(); } const InetAddr *addr; const InetAddr *mask; addr = o->getAddressPtr(); mask = o->getNetmaskPtr(); if (addr==NULL) { FWObject *obj=o; /* * check if this is object of class Address. since we want to * distinguish between Host, Interface and Address, and both Host and * Interface are inherited from Address, we can't use cast. Use isA * instead */ while (obj!=NULL && !Host::isA(obj) && !Firewall::isA(obj) && !Network::isA(obj)) obj=obj->getParent(); compiler->abort( "Problem with address or netmask in the object or one " "of its interfaces: '" + obj->getName() + "'"); } if (addr->isAny() && mask->isAny()) { ostr << "default "; } else { ostr << addr->toString(); if (Interface::cast(o)==NULL && Address::cast(o)->dimension() > 1 && !mask->isHostMask()) { ostr << " "; ostr << mask->toString(); } ostr << " "; } return ostr.str(); } string RoutingCompiler_cisco::PrintRule::RoutingRuleToString(RoutingRule*) { return ""; } string RoutingCompiler_cisco::PrintRule::_printRGtw(RoutingRule *rule) { FWObject *ref; RuleElementRGtw *gtwrel = rule->getRGtw(); ref = gtwrel->front(); Address *gtw = Address::cast(FWReference::cast(ref)->getPointer()); if (gtw == NULL) compiler->abort(rule, "Broken GTW"); string gateway = _printAddr(gtw); if (gateway != "default ") return gateway; else return " "; } string RoutingCompiler_cisco::PrintRule::_printRItf(RoutingRule *rule) { FWObject *ref; RuleElementRItf *itfrel = rule->getRItf(); ref = itfrel->front(); Interface *itf = Interface::cast(FWReference::cast(ref)->getPointer()); if (itf != NULL) return itf->getLabel() + " "; else return ""; } string RoutingCompiler_cisco::PrintRule::_printRDst(RoutingRule *rule) { FWObject *ref; RuleElementRDst *dstrel = rule->getRDst(); ref = dstrel->front(); Address *dst = Address::cast(FWReference::cast(ref)->getPointer()); if (dst==NULL) compiler->abort(rule, "Broken DST"); string dest = _printAddr(dst); if (dest != "default ") return dest; else return "0.0.0.0 0.0.0.0 "; } fwbuilder-5.1.0.3599/src/cisco_lib/AutomaticRules_cisco.h0000644000175000017500000000257411733011756024015 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __AUTOMATICRULES_CISCO_HH__ #define __AUTOMATICRULES_CISCO_HH__ #include "AutomaticRules.h" namespace libfwbuilder { class Address; class Firewall; class Interface; class Service; }; namespace fwcompiler { class AutomaticRules_cisco : public AutomaticRules { public: AutomaticRules_cisco(libfwbuilder::Firewall *fw, libfwbuilder::Library *presistent_objects) : AutomaticRules(fw, presistent_objects) {} void addSshAccessRule(); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/AutomaticRules_iosacl.h0000644000175000017500000000262211733011756024161 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __AUTOMATICRULES_IOSACL_HH__ #define __AUTOMATICRULES_IOSACL_HH__ #include "AutomaticRules_cisco.h" namespace libfwbuilder { class Address; class Firewall; class Interface; class Service; }; namespace fwcompiler { class AutomaticRules_iosacl : public AutomaticRules_cisco { public: AutomaticRules_iosacl(libfwbuilder::Firewall *fw, libfwbuilder::Library *presistent_objects) : AutomaticRules_cisco(fw, presistent_objects) {} void addSshAccessRule(); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/inspectionProtocol.h0000644000175000017500000000354311733011756023566 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSPECTION_PROTOCOL_HH #define INSPECTION_PROTOCOL_HH #include #include typedef enum { FIXUP_ENABLE=0, FIXUP_DISABLE=1, FIXUP_SKIP=2, FIXUP_CLEAR=3 } FixupTypes; /* * par1 and par2 are parameters for the inspection protocol. These are * port numbers most of the time, but for some protocols the meaning * may be different. For example for dns it is "maximum-length". */ class InspectionProtocol { public: std::string name; std::string printable_name; std::string ip_proto; int par1,par2; static std::map protocols; InspectionProtocol(const std::string &fn, const std::string &prn, const std::string &pn, int p1, int p2) { name = fn; printable_name = prn; ip_proto = pn; par1 = p1; par2 = p2; if (protocols.count(fn)==0) protocols[fn] = this; } }; extern InspectionProtocol protocolDefinitions[]; #endif fwbuilder-5.1.0.3599/src/cisco_lib/Helper.cpp0000644000175000017500000003522711733011756021447 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Helper.h" #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; // #define DEBUG_NETZONE_OPS 1 static unsigned long calculateDimension(FWObject* obj) { if (Group::cast(obj)!=NULL) { unsigned long res=0; for (FWObject::iterator i1=obj->begin(); i1!=obj->end(); ++i1) { unsigned long n=calculateDimension( *i1 ); if (n==LONG_MAX) return n; if (LONG_MAX-resisAny()) return LONG_MAX; return a->dimension(); } } return 0; } void Helper::expand_group_recursive(FWObject *o,list &ol) { if (Group::cast( o )!=NULL) { for (FWObject::iterator i2=o->begin(); i2!=o->end(); ++i2) { FWObject *o1= *i2; if (FWReference::cast(o1)!=NULL) o1=FWReference::cast(o1)->getPointer(); assert(o1); expand_group_recursive(o1,ol); } } else { ol.push_back( o ); } } int Helper::findInterfaceByAddress(Address *obj) { return findInterfaceByAddress(obj->getAddressPtr(), obj->getNetmaskPtr()); } /* * ticket #1293 * Weird corner case: user made a mistake setting netmask of an * intrface to 0.0.0.0, which made this interface match any address. * At the same time, this interface was marked as "unprotected". So, * if we get an interface from helper.findInterfaceByNetzoneOrAll() * but this interface is unprotected, issue a warning and use all * interfaces instead. */ int Helper::findInterfaceByAddress(const InetAddr *addr, const InetAddr *nm) { if (addr==NULL) return -1; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " addr=" << addr->toString(); cerr << " nm=" << nm->toString(); cerr << endl; #endif Firewall *fw = compiler->fw; list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->isDedicatedFailover()) continue; if (iface->isUnprotected()) continue; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " intf=" << iface->getName(); cerr << endl; #endif FWObjectTypedChildIterator j = iface->findByType((addr->isV4())?IPv4::TYPENAME:IPv6::TYPENAME); for (; j!=j.end(); ++j) { const Address *i_addr = Address::constcast(*j); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " i_addr=" << i_addr->getName(); cerr << endl; cerr << " " << i_addr->getAddressPtr()->toString(); cerr << " " << i_addr->getNetmaskPtr()->toString(); cerr << endl; #endif if (nm != NULL) { InetAddrMask interface_subnet(*(i_addr->getAddressPtr()), *(i_addr->getNetmaskPtr())); InetAddrMask other_subnet(*addr, *nm); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " addr=" << other_subnet.toString(); cerr << " intf=" << iface->getName() << " " << interface_subnet.toString(); cerr << endl; #endif vector ovr = libfwbuilder::getOverlap(interface_subnet, other_subnet); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " overlap:"; cerr << " ovr.size()=" << ovr.size(); if (ovr.size() > 0) cerr << " ovr.front()=" << ovr.front().toString(); cerr << endl; #endif if (ovr.size()==0) continue; // if interface_subnet is equal or wider than other_subnet, // getOverlap() returns subnet object equal to other_subnet // If other_subnet is wider, returned object is equal // to interface_subnet. If they intersect but one does not fit // completely in the other, returned object is not equal // to either. if (ovr.front() == other_subnet) { return iface->getId(); } } else { if ( i_addr->belongs(*addr) ) return iface->getId(); } } } return -1; } int Helper::findInterfaceByNetzone(Address *obj) { if (IPv4::isA(obj)) { InetAddr host_netmask("255.255.255.255"); return findInterfaceByNetzone(obj->getAddressPtr(), &host_netmask); } else return findInterfaceByNetzone(obj->getAddressPtr(), obj->getNetmaskPtr()); } /** * finds interface of the firewall associated with the netzone * that object 'obj' belongs to. Returns interface ID * */ int Helper::findInterfaceByNetzone(const InetAddr *addr, const InetAddr *nm) throw(FWException) { #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " matching to"; cerr << " addr=" << addr; if (addr) cerr << " " << addr->toString(); cerr << " nm=" << nm; if (nm) cerr << " " << nm->toString(); cerr << endl; #endif Firewall *fw = compiler->fw; map zones; list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->isDedicatedFailover()) continue; if (iface->isUnprotected()) continue; // NOTE: "network_zone" is globally unique string ID int netzone_id = FWObjectDatabase::getIntId(iface->getStr("network_zone")); if (netzone_id != -1) { FWObject *netzone = fw->getRoot()->findInIndex(netzone_id); list nz; expand_group_recursive(netzone, nz); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " netzone_id=" << netzone_id << " " << iface->getStr("network_zone") << " " << netzone->getName() << endl; #endif for (list::iterator j=nz.begin(); j!=nz.end(); ++j) { Address *netzone_addr = Address::cast(*j); if (netzone_addr == NULL) continue; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " " << netzone_addr->getName() << " " << netzone_addr->getAddressPtr()->toString() << endl; #endif // if addr==NULL, return id of the interfacce that has // net_zone=="any" if (addr==NULL) { if (netzone_addr->getId()==FWObjectDatabase::ANY_ADDRESS_ID) return iface->getId(); // id of the interface } else { // see SF bug 3213019 // skip ipv6 addresses in network zone group if (netzone_addr->getAddressPtr()->addressFamily() != addr->addressFamily()) continue; const InetAddr *nz_addr = netzone_addr->getAddressPtr(); const InetAddr *nz_netm = netzone_addr->getNetmaskPtr(); if (nm != NULL && nz_netm != NULL) { InetAddrMask nz_subnet(*nz_addr, *nz_netm); InetAddrMask other_subnet(*addr, *nm); vector ovr = libfwbuilder::getOverlap(nz_subnet, other_subnet); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " addr=" << other_subnet.toString(); cerr << " nz=" << nz_subnet.toString(); cerr << " overlap:"; cerr << " ovr.size()=" << ovr.size(); if (ovr.size() > 0) cerr << " ovr.front()=" << ovr.front().toString(); cerr << endl; #endif if (ovr.size()==0) continue; // if nz_subnet is equal or wider than other_subnet, // getOverlap() returns subnet object equal to other_subnet // If other_subnet is wider, returned object is equal // to nz_subnet. If they intersect but one does not fit // completely in the other, returned object is not equal // to either. if (ovr.front() == other_subnet) { zones[iface->getId()] = netzone_addr; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " match" << endl; #endif } } else { if (netzone_addr->belongs(*addr)) { zones[iface->getId()] = netzone_addr; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " match" << endl; #endif } } } } } } /* * now compare dimensions of all netzones that contain address obj and * pick the one with smallest dimension */ int res_id = -1; unsigned long res_dim = LONG_MAX; for (map::iterator i=zones.begin(); i!=zones.end(); ++i) { int iface_id = (*i).first; FWObject *netzone = (*i).second; unsigned long dim = calculateDimension(netzone); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " netzone=" << netzone->getName() << " dim=" << dim << " res_dim=" << res_dim << endl; #endif if (dim<=res_dim) { res_id = iface_id; res_dim = dim; } } #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " Result after scanning network zones: " << res_id << endl; #endif /* * Subnets defined by addresses of interfaces are automatically part * of the corresponding network zones */ if (res_id == -1) res_id = findInterfaceByAddress(addr, nm); if (res_id == -1) { QString err = QObject::tr("Can not find interface with network zone " "that includes address '%1%2'"); throw(FWException(err .arg((addr)?addr->toString().c_str():"NULL") .arg((nm)?QString("/%1").arg(nm->toString().c_str()):"") .toStdString())); } #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " returning " << res_id << endl; #endif return res_id; } list Helper::getAllInterfaceIDs() { Firewall *fw = compiler->fw; list intf_id_list; FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i) { Interface *ifs = Interface::cast(*i); assert(ifs); if (ifs->isUnprotected()) continue; // skip! intf_id_list.push_back( (*i)->getId() ); } return intf_id_list; } list Helper::findInterfaceByNetzoneOrAll(RuleElement *re) { list intf_id_list; if (re->isAny()) { return getAllInterfaceIDs(); } else { FWObject *fo = re->front(); if (FWReference::cast(fo)!=NULL) fo=FWReference::cast(fo)->getPointer(); Address *a = Address::cast(fo); if (a==NULL) { Rule *rule = Rule::cast(re->getParent()); compiler->abort( re->getParent(), string("findInterfaceByNetzoneOrAll failed to retrieve first " "object from the rule element; is argument not of " "the type RuleElementSrc or RuleElementDst ?")); return intf_id_list; } try { int intf_id = findInterfaceByNetzone(a); intf_id_list.push_back(intf_id); } catch(FWException &ex) { // could not find interface with netzone to match address 'a' // will assign rule to all interfaces. Act as if all interfaces // had network zone 'any' and each matches this address. // issue warning only if platform uses netwrk zones. bool supports_network_zones = Resources::getTargetCapabilityBool( compiler->fw->getStr("platform"), "network_zones"); if (supports_network_zones) compiler->warning(ex.toString()); FWObjectTypedChildIterator i = compiler->fw->findByType( Interface::TYPENAME); for ( ; i!=i.end(); ++i) { Interface *ifs = Interface::cast(*i); intf_id_list.push_back( ifs->getId() ); } } } return intf_id_list; } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_procurve_acl_run.cpp0000644000175000017500000003277011733011756026606 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "CompilerDriver_procurve_acl.h" #include "AutomaticRules_iosacl.h" #include "PolicyCompiler_procurve_acl.h" #include "RoutingCompiler_procurve_acl.h" #include "OSConfigurator_procurve.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManagerIOS.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; QString CompilerDriver_procurve_acl::assembleManifest(Cluster*, Firewall*, bool) { QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); script << ";" << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]) << endl; return script_buffer; } QString CompilerDriver_procurve_acl::assembleFwScript(Cluster *cluster, Firewall *fw, bool cluster_member, OSConfigurator *oscnf) { Configlet script_skeleton(fw, "procurve", "script_skeleton"); Configlet top_comment(fw, "procurve", "top_comment"); script_skeleton.setVariable("system_configuration_script", QString::fromUtf8(system_configuration_script.c_str())); script_skeleton.setVariable("policy_script", QString::fromUtf8(policy_script.c_str())); script_skeleton.setVariable("nat_script", QString::fromUtf8(nat_script.c_str())); script_skeleton.setVariable("routing_script", QString::fromUtf8(routing_script.c_str())); FWOptions* options = fw->getOptionsObject(); options->setStr("prolog_script", options->getStr("procurve_acl_prolog_script")); options->setStr("epilog_script", options->getStr("procurve_acl_epilog_script")); assembleFwScriptInternal(cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, ";", true); return script_skeleton.expand(); } QString CompilerDriver_procurve_acl::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("")); FWOptions* options = fw->getOptionsObject(); string fwvers = fw->getStr("version"); if (fwvers == "") fw->setStr("version", "K.13"); string platform = fw->getStr("platform"); bool procurve_acl_acl_basic = options->getBool("procurve_acl_acl_basic"); bool procurve_acl_acl_no_clear = options->getBool("procurve_acl_acl_no_clear"); bool procurve_acl_acl_substitution = options->getBool("procurve_acl_acl_substitution"); bool procurve_acl_add_clear_statements = options->getBool("procurve_acl_add_clear_statements"); if ( !procurve_acl_acl_basic && !procurve_acl_acl_no_clear && !procurve_acl_acl_substitution ) { if ( procurve_acl_add_clear_statements ) options->setBool("procurve_acl_acl_basic",true); else options->setBool("procurve_acl_acl_no_clear",true); } std::auto_ptr oscnf(new OSConfigurator_procurve(objdb, fw, false)); oscnf->prolog(); oscnf->processFirewallOptions(); list all_policies = fw->getByType(Policy::TYPENAME); try { AutomaticRules_iosacl auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() // NB: these ids are not used by this compiler assignUniqueRuleIds(all_policies); vector ipv4_6_runs; if (!single_rule_compile_on) system_configuration_script = safetyNetInstall(fw); NamedObjectsManagerIOS named_objects_manager(persistent_objects, fw); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } string clear_commands; string object_groups_definitions; for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); // Count rules for each address family int policy_count = 0; for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (policy_count) { std::auto_ptr prep(new Preprocessor(objdb, fw, false)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); } for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(policy_af)) continue; PolicyCompiler_procurve_acl c(objdb, fw, ipv6_policy, oscnf.get()); c.setNamedObjectsManager(&named_objects_manager); c.setSourceRuleSet( policy ); c.setRuleSetName(policy->getName()); c.setPersistentObjects(persistent_objects); c.setSingleRuleCompileMode(single_rule_id); if (inTestMode()) c.setTestMode(); if (inEmbeddedMode()) c.setEmbeddedMode(); c.setDebugLevel( dl ); if (rule_debug_on) c.setDebugRule( drp ); c.setVerbose( verbose ); if ( c.prolog() > 0 ) { c.compile(); c.epilog(); if (!single_rule_compile_on) { if (ipv6_policy) { policy_script += "\n\n"; policy_script += "; ================ IPv6\n"; policy_script += "\n\n"; } else { policy_script += "\n\n"; policy_script += "; ================ IPv4\n"; policy_script += "\n\n"; } } if (c.haveErrorsAndWarnings()) { all_errors.push_back(c.getErrors("").c_str()); } policy_script += c.getCompiledScript(); clear_commands += c.printClearCommands(); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in Policy"); } if (!ipv6_policy) { list all_routing = fw->getByType(Routing::TYPENAME); RuleSet *routing = RuleSet::cast(all_routing.front()); // currently routing is supported only for ipv4 RoutingCompiler_procurve_acl r(objdb, fw, false, oscnf.get()); r.setNamedObjectsManager(&named_objects_manager); r.setSourceRuleSet(routing); r.setRuleSetName(routing->getName()); r.setPersistentObjects(persistent_objects); r.setSingleRuleCompileMode(single_rule_id); if (inTestMode()) r.setTestMode(); if (inEmbeddedMode()) r.setEmbeddedMode(); r.setDebugLevel( dl ); if (rule_debug_on) r.setDebugRule( drp ); r.setVerbose( verbose ); if ( r.prolog() > 0 ) { r.compile(); r.epilog(); if (r.haveErrorsAndWarnings()) { all_errors.push_back(r.getErrors("").c_str()); } routing_script += r.getCompiledScript(); } else info(" Nothing to compile in Routing"); } } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } object_groups_definitions += named_objects_manager.getNamedObjectsDefinitions(); if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (object_groups_definitions + policy_script + routing_script).c_str())); } if ( fw->getOptionsObject()->getBool("procurve_acl_acl_basic") || fw->getOptionsObject()->getBool("procurve_acl_acl_substitution")) { clear_commands += named_objects_manager.getClearCommands() + "\n"; } system_configuration_script += clear_commands; system_configuration_script += object_groups_definitions; QString script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString ofname = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + ofname.toStdString()); QFile fw_file(ofname); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_pix.cpp0000644000175000017500000006741311733011756024044 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "Helper.h" #include "PolicyCompiler_pix.h" #include "NATCompiler_pix.h" #include "PIXObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_pix::myPlatformName() { return "pix"; } PolicyCompiler_pix::PolicyCompiler_pix(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf, NATCompiler_pix *_natcmp) : PolicyCompiler_cisco(_db, fw, ipv6_policy, _oscnf) { natcmp=_natcmp; resetinbound=false; fragguard=false; } int PolicyCompiler_pix::prolog() { string platform = fw->getStr("platform"); if (platform!="pix" && platform!="fwsm") abort("Unsupported platform " + platform ); return PolicyCompiler::prolog(); } void PolicyCompiler_pix::_expand_interface(Rule *rule, Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully) { Compiler::_expand_interface(rule, iface, ol, expand_cluster_interfaces_fully); } bool PolicyCompiler_pix::checkVersionAndDynamicInterface::findDynamicInterface( PolicyRule *rule, RuleElement *rel) { string vers=compiler->fw->getStr("version"); for (list::iterator i1=rel->begin(); i1!=rel->end(); ++i1) { FWObject *o = *i1; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *iface=Interface::cast(obj); if (iface!=NULL && iface->isDyn() && (vers=="6.1" || vers=="6.2")) { compiler->abort( rule, "Dynamic interface can be used in the policy rule only " "in v6.3 or later."); return false; } } return true; } bool PolicyCompiler_pix::checkVersionAndDynamicInterface::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; Service *s = compiler->getFirstSrv(rule); /* if service is ssh, telnet or icmp then we can use dynamic interface * even in earlier versions */ if (ICMPService::isA(s)) { tmp_queue.push_back(rule); return true; } if (TCPService::isA(s)) { if ( s->getInt("dst_range_start")==22 && s->getInt("dst_range_end")==22) { tmp_queue.push_back(rule); return true; } if ( s->getInt("dst_range_start")==23 && s->getInt("dst_range_end")==23) { tmp_queue.push_back(rule); return true; } } if (findDynamicInterface(rule,rule->getSrc()) && findDynamicInterface(rule,rule->getDst())) tmp_queue.push_back(rule); return true; } /* * if dst contains firewall, it must be a single object there. */ bool PolicyCompiler_pix::PrepareForICMPCmd::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; Address *dst=compiler->getFirstDst(rule); Service *srv=compiler->getFirstSrv(rule); if (ICMPService::isA(srv) && compiler->complexMatch(dst,compiler->fw)) rule->setBool("icmp_cmd",true); tmp_queue.push_back(rule); return true; } bool PolicyCompiler_pix::SplitSRCForICMPCmd::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getBool("icmp_cmd")) { RuleElementSrc *src=rule->getSrc(); if (src->size()==1) { tmp_queue.push_back(rule); return true; } for (FWObject::iterator i=src->begin(); i!=src->end(); ++i) { FWObject *o = *i; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Address *a=Address::cast(obj); assert(a!=NULL); PolicyRule *new_rule= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); RuleElementSrc *new_re=new_rule->getSrc(); new_re->clearChildren(); new_re->addRef(a); tmp_queue.push_back(new_rule); } } else tmp_queue.push_back(rule); return true; } /* * About "service resetinbound" command: * * "The service command works with all inbound TCP connections to * statics whose access lists or uauth (user authorization) do not * allow inbound" */ bool PolicyCompiler_pix::RejectAction::processNext() { PolicyCompiler_pix *pix_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; if (rule->getAction()==PolicyRule::Reject) pix_comp->resetinbound=true; tmp_queue.push_back(rule); return true; } /* * processor splitIfDstMatchesFw should have made a firewall a single * object in dst */ bool PolicyCompiler_pix::splitIfTelnetSSHICMPtoFw::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; // PolicyCompiler_pix *pix_comp=dynamic_cast(compiler); Address *dst=compiler->getFirstDst(rule); RuleElement *re=rule->getSrc(); if (re->size()!=1 && dst->getId()==compiler->getFwId()) { for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = *i1; FWObject *obj = o; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrc *nsrc=r->getSrc(); nsrc->clearChildren(); nsrc->addRef( obj ); tmp_queue.push_back(r); } } else tmp_queue.push_back(rule); return true; } /* * this is probably not necessary. PIX prints all acl rules with * object-groups twice: first time as entered, with object-group, and * the second time it expands the group (for convenience ?). I thought * it does not print original rule for icmp but it looks like it it * does it for icmp just like for other protocols. PIX is ok, I made a * mistake. I keep with rule processor just in case, but comment out * the call to it. */ bool PolicyCompiler_pix::AvoidObjectGroup::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; // PolicyCompiler_pix *pix_comp=dynamic_cast(compiler); RuleElement *srv=RuleElement::cast(rule->getFirstByType(RuleElementSrv::TYPENAME)); if (srv->size()==1) // no need to create object-group since there is single object in the rule element { tmp_queue.push_back(rule); return true; } FWObject *o = srv->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if (ICMPService::isA(o)) { /* we have a rule with multiple icmp services in Srv. We do not want * to use object-group for it because PIX 6.3(3) expands them anyway, * which breaks incremental installer. */ for (FWObject::iterator i1=srv->begin(); i1!=srv->end(); ++i1) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); r->duplicate(rule); compiler->temp_ruleset->add(r); FWObject *s; s=r->getSrv(); assert(s); s->clearChildren(); s->add( *i1 ); tmp_queue.push_back(r); } return true; } tmp_queue.push_back(rule); return true; } /* * See #2662: commands "ssh", "telnet" and "http" (those that control * access on the corresponding protocols to the firewall itself) * accept only ip address of a host or a network as their * argument. They do not accept address range, named object or object * group. This is so at least as of ASA 8.3. Since we expand address * ranges only for versions < 8.3 and use named object for 8.3 and * later, we need to make this additional check and still expand * address ranges in rules that will later convert to "ssh", "telnet" * or "http" command. Call this rule processor after telnetToFirewall, * sshToFirewall and httpToFirewall */ bool PolicyCompiler_pix::AddressRangesIfTcpServiceToFW::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; if (rule->getBool("tcp_service_to_fw")) { expandAddressRangesInSrc(rule); } tmp_queue.push_back(rule); return true; } void PolicyCompiler_pix::compile() { string banner = " Compiling ruleset " + getSourceRuleSet()->getName(); if (ipv6) banner += ", IPv6"; info(banner); string vers = fw->getStr("version"); string platform = fw->getStr("platform"); bool outbound_acl_supported = Resources::platform_res[platform]->getResourceBool( string("/FWBuilderResources/Target/options/")+ "version_"+vers+ "/pix_outbound_acl_supported"); bool generate_out_acl = fw->getOptionsObject()->getBool("pix_generate_out_acl"); bool object_groups_supported = Resources::platform_res[platform]->getResourceBool( string("/FWBuilderResources/Target/options/")+ "version_"+vers+ "/pix_object_groups_supported"); if (outbound_acl_supported && !generate_out_acl) { // behave like if outbound acls are not supported but are emulated outbound_acl_supported = false; fw->getOptionsObject()->setBool("pix_emulate_out_acl", true); } Compiler::compile(); if ( fw->getOptionsObject()->getBool ("check_shading") && ! inSingleRuleCompileMode()) { add( new Begin ("Detecting rule shadowing" )); add( new printTotalNumberOfRules ( )); add( new expandGroupsInItf("expand groups in Interface" )); add( new replaceClusterInterfaceInItf( "replace cluster interfaces with member interfaces in " "the Interface rule element")); add( new ItfNegation( "process negation in Itf" )); add( new InterfacePolicyRules("process interface policy rules and " "store interface ids")); add( new recursiveGroupsInSrc( "check for recursive groups in SRC" )); add( new recursiveGroupsInDst( "check for recursive groups in DST" )); add( new recursiveGroupsInSrv( "check for recursive groups in SRV" )); add( new ExpandGroups ("expand groups" )); add( new eliminateDuplicatesInSRC ("eliminate duplicates in SRC" )); add( new eliminateDuplicatesInDST ("eliminate duplicates in DST" )); add( new eliminateDuplicatesInSRV ("eliminate duplicates in SRV" )); add( new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src")); add( new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst")); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC" )); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST" )); add( new ConvertToAtomic ("convert to atomic rules" )); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new DetectShadowing ("Detect shadowing" )); add( new simplePrintProgress ( )); runRuleProcessors(); deleteRuleProcessors(); } add( new Begin (" Start processing rules" )); add( new printTotalNumberOfRules ( )); add( new singleRuleFilter()); add( new RejectAction ("check for action 'Reject'" )); add( new recursiveGroupsInSrc( "check for recursive groups in SRC" )); add( new recursiveGroupsInDst( "check for recursive groups in DST" )); add( new recursiveGroupsInSrv( "check for recursive groups in SRV" )); add( new emptyGroupsInSrc( "check for empty groups in SRC" )); add( new emptyGroupsInDst( "check for empty groups in DST" )); add( new emptyGroupsInSrv( "check for empty groups in SRV" )); add( new ExpandGroups ("expand groups" )); add( new eliminateDuplicatesInSRC( "eliminate duplicates in SRC" )); add( new eliminateDuplicatesInDST( "eliminate duplicates in DST" )); add( new eliminateDuplicatesInSRV( "eliminate duplicates in SRV" )); add( new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src")); add( new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst")); add( new expandGroupsInItf("expand groups in Interface" )); add( new replaceClusterInterfaceInItf( "replace cluster interfaces with member interfaces in " "the Interface rule element")); add( new ItfNegation( "process negation in Itf" )); add( new InterfacePolicyRules( "process interface policy rules and store interface ids")); if (XMLTools::version_compare(vers, "8.3")<0) add( new addressRanges("process address ranges" )); /* * We do not support ipv6 yet */ add( new DropIPv6RulesWithWarning( "drop ipv6 rules", "Rule has been suppressed because it contains IPv6 objects and " "Firewall Builder does not support IPv6 for this platform")); if ( fwopt->getBool("pix_assume_fw_part_of_any")) { // Note that this splits the rule if Dst==any and one or more // icmp services are found in Srv. The name of this rule // processor needs to be more descriptive. add( new splitIfDstAny( "split rule if dst is any" )); } add( new splitIfSrcMatchesFw ("split rule if Src matches FW" )); add( new splitIfDstMatchesFw ("split rule if Dst matches FW" )); add( new telnetToFirewall( "separate rules controlling telnet to firewall")); add( new sshToFirewall( "separate rules controlling ssh to firewall" )); add( new httpToFirewall( "separate rules controlling http to firewall")); add( new AddressRangesIfTcpServiceToFW( "process address ranges in rules that control telnet/ssh/http to Fw")); add( new separateSrcPort("split rules matching source ports")); add( new separateCustom("split rules matching custom services")); add( new groupServicesByProtocol("split rules with different protocols")); add( new PrepareForICMPCmd("prepare for icmp command" )); add( new replaceFWinSRCInterfacePolicy( "replace fw with its interface in SRC in interface policy rules")); add( new replaceFWinDSTInterfacePolicy( "replace fw with its interface in DST in interface policy rules")); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC" )); add( new MACFiltering("check for MAC address filtering" )); add( new splitByNetworkZonesForSrc( "split rule if objects in Src belong to different network zones " )); add( new replaceFWinDSTPolicy( "replace fw with its interface in DST in global policy rules")); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST" )); add( new MACFiltering("check for MAC address filtering" )); add( new splitByNetworkZonesForDst( "split rule if objects in Dst belong to different network zones " )); add( new checkForUnnumbered( "check for unnumbered interfaces" )); if (outbound_acl_supported ) { // Call these after splitIfSrcMatchesFw and splitIfDstMatchesFw add( new setInterfaceAndDirectionBySrc( "Set interface and direction for rules with interface " "'all' using SRC; v7")); add( new setInterfaceAndDirectionByDst( "Set interface and direction for rules with interface " "'all' using DST; v7")); add(new setInterfaceAndDirectionIfInterfaceSet( "Set direction for rules with interface not 'all'; v7")); } else { add( new SplitDirection_v6("split rules with direction 'both'" )); // add( new assignRuleToInterface ("assign rules to interfaces" )); add( new EmulateOutboundACL_v6("emulate outbound ACL" )); add( new assignRuleToInterface_v6("assign rules to interfaces" )); add( new InterfaceAndDirection_v6( "check for combinations of interface and direction")); } add( new specialCaseWithDynInterface( "check for a special cases with dynamic interface" )); add( new SplitSRCForICMPCmd( "split SRC for icmp commands" )); if (XMLTools::version_compare(vers, "8.3")<0) { if ( fwopt->getBool("pix_replace_natted_objects")) add( new replaceTranslatedAddresses( "replace objects in DST that are TDst in DNAT " "translations")); } else { add( new warnWhenTranslatedAddressesAreUsed( "warng when addresses that are ODst in DNAT translations " "are used in DST")); } if (outbound_acl_supported ) // first arg is false because we are not using // "ip access-list" for PIX. add( new pickACL( false, "assign ACLs for v7" )); else add( new pickACL_v6( "assign ACLs for v6" )); add( new SpecialServicesSrv( "check for special services" )); add( new CheckForUnsupportedUserService("check for user service") ); add( new checkForZeroAddr( "check for zero addresses" )); add( new checkVersionAndDynamicInterface( "check for dynamic interfaces in policy rule and verify " "version of PIX OS")); add( new splitIfTelnetSSHICMPtoFw( "split rule if there are multiple objects in src and it " "controlls access to the firewall")); /* remove redundant objects only after all splits has been * done, right before object groups are created */ add( new removeRedundantAddressesFromSrc( "remove redundant addresses from Src")); add( new removeRedundantAddressesFromDst( "remove redundant addresses from Dst")); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); if (object_groups_supported) { // add( new AvoidObjectGroup("avoid object groups for certain cases")); add( new CreateObjectGroupsForSrc("create object groups for Src", named_objects_manager)); add( new CreateObjectGroupsForDst("create object groups for Dst", named_objects_manager)); add( new CreateObjectGroupsForSrv("create object groups for Srv", named_objects_manager)); } else { add( new ConvertToAtomic ("convert to atomic rules" )); } add( new simplePrintProgress()); add( new createNewCompilerPass("Creating object groups and ACLs ...")); if (XMLTools::version_compare(vers, "8.3")>=0) { add( new createNamedObjectsForPolicy( "create named objects", named_objects_manager)); } add( new PrintRule("generate code for ACLs")); add( new simplePrintProgress()); /* if ( fw->getOptionsObject()->getBool("pix_check_rule_shadowing")) { add( new createNewCompilerPass (" Detecting rule shadowing ..." )); add( new ExpandGroups ("expand groups" )); add( new ConvertToAtomic ("convert to atomic rules" )); add( new DetectShadowing ("Detect shadowing" )); add( new simplePrintProgress ( )); } */ runRuleProcessors(); } string PolicyCompiler_pix::printAccessGroupCmd(ciscoACL *acl) { if (getSourceRuleSet()->isTop()) { string dir; if (acl->direction()=="in" || acl->direction()=="Inbound") dir="in"; if (acl->direction()=="out" || acl->direction()=="Outbound") dir="out"; return string("access-group ") + acl->workName() + " " + dir + " interface " + acl->getInterface()->getLabel() + "\n"; } return ""; } void PolicyCompiler_pix::epilog() { output << endl; if (resetinbound) output << "service resetinbound" << endl; output << endl; if (fw->getStr("platform")=="fwsm" && fw->getOptionsObject()->getBool("pix_use_manual_commit")) { output << "access-list commit" << endl; output << endl; } for (map::iterator i=acls.begin(); i!=acls.end(); ++i) { ciscoACL *acl=(*i).second; if (acl->size()!=0) output << printAccessGroupCmd(acl); } output << endl; if ( fw->getOptionsObject()->getBool("pix_regroup_commands")) { info(" Regrouping commands"); regroup(); } } string PolicyCompiler_pix::printClearCommands() { ostringstream output; string vers = fw->getStr("version"); string platform = fw->getStr("platform"); string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + vers + "/pix_commands/clear_acl"); // string clearOGcmd = Resources::platform_res[platform]->getResourceStr( // string("/FWBuilderResources/Target/options/") + // "version_" + vers + "/pix_commands/clear_og"); string clearICMPcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + vers + "/pix_commands/clear_icmp"); string clearTelnetcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + vers + "/pix_commands/clear_telnet"); if ( fw->getOptionsObject()->getBool("pix_acl_basic") ) { output << clearACLcmd << endl; //output << clearOGcmd << endl; } if (fw->getOptionsObject()->getBool("pix_acl_substitution")) { for (map::iterator i=acls.begin(); i!=acls.end(); ++i) { ciscoACL *acl = (*i).second; output << clearACLcmd << " " << acl->workName() << endl; } //output << clearOGcmd << endl; } if ( !fw->getOptionsObject()->getBool("pix_acl_no_clear") ) { output << clearICMPcmd << endl; output << clearTelnetcmd << endl; } // see #2322 If this is FWSM and if manual commit mode is used, we // need to commit after clearing ACLs before we clear object groups if (fw->getStr("platform")=="fwsm" && fw->getOptionsObject()->getBool("pix_use_manual_commit") ) { output << "access-list commit" << endl; } return output.str(); } /* * This includes commands that should be added first, such as commit mode * for FWSM, setting up temporary access list etc. */ string PolicyCompiler_pix::printPreambleCommands() { string version = fw->getStr("version"); string platform = fw->getStr("platform"); ostringstream output; output << "!################" << endl; if (platform=="fwsm") { if (fw->getOptionsObject()->getBool("pix_use_manual_commit") ) output << "access-list mode manual" << endl; else output << "access-list mode auto" << endl; } if ( fw->getOptionsObject()->getBool("pix_acl_substitution") ) { /* Generate short temporary ACL and assign it to all * interfaces. This ACL permits IPSEC (IP proto 50 and UDP port 500) as well as ssh from given subnet to any. */ string temp_acl = "tmp_acl"; string temp_acl_addr = fw->getOptionsObject()->getStr("pix_acl_temp_addr"); if (temp_acl_addr.empty()) { abort( "Missing address for management host or subnet for " "temporary ACL. Enter it in the tab 'Script " "options' in 'Firewall Settings' dialog"); } string::size_type slash_idx = temp_acl_addr.find('/'); string addr = temp_acl_addr; string netmask = "255.255.255.255"; if (slash_idx!=string::npos) { addr = temp_acl_addr.substr(0,slash_idx); netmask = temp_acl_addr.substr(slash_idx+1); try { if (netmask.find(".")!=string::npos) { InetAddr nm(netmask); nm.isAny(); // to avoid warning abt unused var } else { int nm_length; istringstream str(netmask); str >> nm_length; InetAddr nm(nm_length); netmask = nm.toString(); } } catch(FWException &ex) { abort("Invalid netmask for management subnet: '"+netmask+"'"); } } try { InetAddr(addr); } catch(FWException &ex) { abort("Invalid address for management subnet: '"+addr+"'"); } string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+version+"/pix_commands/clear_acl"); output << endl; output << clearACLcmd << " " << temp_acl << endl; if (fw->getStr("platform")=="fwsm" && fw->getOptionsObject()->getBool("pix_use_manual_commit") ) { output << "access-list commit" << endl; } output << "access-list " << temp_acl << " permit ip " << addr << " " << netmask << " any " << endl; output << "access-list " << temp_acl << " deny ip any any " << endl; if (platform=="fwsm" && fw->getOptionsObject()->getBool("pix_use_manual_commit") ) output << "access-list commit" << endl; output << endl; // see #2347 attach temporary acl to all interfaces list all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator i; for (i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); output << "access-group " << temp_acl << " in interface " << iface->getLabel() << endl; } output << endl; } return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_pix_os_fixups.cpp0000644000175000017500000001262511733011756026110 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator_pix_os.h" #include "Helper.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* ******************************************************************** * * Generating old school fixup commands for PIX 6.X * and FWSM 2.3 * * ********************************************************************/ /* * Copy this method into class PIXAdvancedFWDialog in fwbuilder/src/pix */ string OSConfigurator_pix_os::_printFixupCommand(const string &fixup_name, const string &sw, int arg1, int arg2, bool ov) { ostringstream res; if (sw=="0") { if (fixup_name=="dns") { if (arg1) { res << "fixup protocol " << fixup_name; res << " maximum-length " << arg1; res << endl; } } else { if (fixup_name=="ftp") { if (arg1) { res << "fixup protocol " << fixup_name << " "; if (ov) res << "strict "; res << arg1; res << endl; } } else { if (fixup_name=="mgcp") { if (arg1) { res << "fixup protocol " << fixup_name << " "; res << arg1; res << endl; } if (arg2) { res << "fixup protocol " << fixup_name << " "; res << arg2; res << endl; } } else { res << "fixup protocol " << fixup_name << " "; if (arg1) res << arg1; if (arg2 && arg1!=arg2) res << "-" << arg2; res << endl; } } } } if (sw=="1") { res << "no fixup protocol " << fixup_name; res << endl; } return res.str(); } string OSConfigurator_pix_os::_printFixups() { ostringstream res; string platform = fw->getStr("platform"); string version = fw->getStr("version"); FWOptions *options = fw->getOptionsObject(); assert(options!=NULL); string lst = Resources::platform_res[platform]->getResourceStr( "/FWBuilderResources/Target/options/version_" + version + "/fixups/list"); string::size_type i,j, k; i=0; while ( igetStr(fixup_xml_element); if (!f.empty()) { string fixup_name=fixup_xml_element.substr(0, fixup_xml_element.find("_fixup") ); while ( (k=fixup_name.find("_"))!=string::npos ) fixup_name.replace(k,1,1,' '); string sw; int arg1,arg2; string on; bool ov; istringstream str(f); str >> sw >> arg1 >> arg2 >> on >> ov; res << _printFixupCommand(fixup_name, sw, arg1, arg2, ov ); } if (j==string::npos) break; } return res.str(); } string OSConfigurator_pix_os::getProtocolInspectionCommands() { string platform = fw->getStr("platform"); string version = fw->getStr("version"); ostringstream res; if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_" + version + "/fixups/use_fixup_commands")) res << _printFixups(); if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_" + version + "/fixups/use_mpf_policy_map")) res << _printMPFPolicyMap(); if (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/version_" + version + "/fixups/use_policy_map_type_inspect")) res << _printPolicyMapTypeInspect(); return res.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/BaseObjectGroup.cpp0000644000175000017500000001620411733011756023240 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "BaseObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/Address.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/FWException.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; map BaseObjectGroup::name_disambiguation; const char *BaseObjectGroup::TYPENAME={"BaseObjectGroup"}; FWObject& BaseObjectGroup::shallowDuplicate(const FWObject *other, bool preserve_id) throw(FWException) { gt = BaseObjectGroup::constcast(other)->gt; return FWObject::shallowDuplicate(other, preserve_id); } QString BaseObjectGroup::registerGroupName(const QString &prefix, object_group_type gt) { QString type_suffix; switch (gt) { case UNKNOWN: type_suffix = "unknown"; break; case NETWORK: type_suffix = "net"; break; case PROTO: type_suffix = "proto"; break; case ICMP_TYPE: type_suffix = "icmp"; break; case TCP_SERVICE: type_suffix = "tcp"; break; case UDP_SERVICE: type_suffix = "udp"; break; case TCP_UDP_SERVICE: type_suffix = "tcpudp"; break; case MIXED_SERVICE: type_suffix = "mixed"; break; default: type_suffix = "unknown"; break; } int n = 0; while (true) { QString full_name = QString("%1.%2.%3").arg(prefix).arg(type_suffix).arg(n); if (name_disambiguation.count(full_name) == 0) { name_disambiguation[full_name] = 0; return full_name; } n++; } return ""; } BaseObjectGroup::object_group_type BaseObjectGroup::getObjectGroupTypeFromFWObject( const FWObject *obj) { if (Address::constcast(obj)!=NULL) return NETWORK; if (IPService::constcast(obj)!=NULL) return PROTO; if (ICMPService::constcast(obj)!=NULL) return ICMP_TYPE; if (TCPService::constcast(obj)!=NULL) return TCP_SERVICE; if (UDPService::constcast(obj)!=NULL) return UDP_SERVICE; return UNKNOWN; } void BaseObjectGroup::setObjectGroupTypeFromFWObject(const FWObject *obj) { setObjectGroupType(getObjectGroupTypeFromFWObject(obj)); } void BaseObjectGroup::setObjectGroupTypeFromMembers( NamedObjectsManager *named_objects_manager) { object_group_type my_type = UNKNOWN; std::map type_counters; for (FWObject::iterator i1=this->begin(); i1!=this->end(); ++i1) { const FWObject *obj = FWReference::getObject(*i1); NamedObject *named_object = named_objects_manager->named_objects[obj->getId()]; if (named_object) obj = named_object->getObject(); object_group_type t = getObjectGroupTypeFromFWObject(obj); if (type_counters.count(t) == 0) type_counters[t] = 1; else type_counters[t]++; } if (type_counters[NETWORK]!=0 && (type_counters[PROTO]!=0 || type_counters[ICMP_TYPE]!=0 || type_counters[TCP_SERVICE]!=0 || type_counters[UDP_SERVICE]!=0 || type_counters[MIXED_SERVICE]!=0)) throw FWException("Object group should not contain both " "network and service objects"); if (type_counters[NETWORK]!=0) my_type = NETWORK; if (type_counters[PROTO]==0 && type_counters[ICMP_TYPE]==0 && (type_counters[TCP_SERVICE]!=0 || type_counters[UDP_SERVICE]!=0) && type_counters[MIXED_SERVICE]==0) { if (type_counters[TCP_SERVICE]!=0 && type_counters[UDP_SERVICE]!=0) my_type = TCP_UDP_SERVICE; if (type_counters[TCP_SERVICE]!=0 && type_counters[UDP_SERVICE]==0) my_type = TCP_SERVICE; if (type_counters[TCP_SERVICE]==0 && type_counters[UDP_SERVICE]!=0) my_type = UDP_SERVICE; } if (type_counters[PROTO]!=0 && type_counters[ICMP_TYPE]==0 && type_counters[MIXED_SERVICE]==0) my_type = PROTO; if (type_counters[PROTO]==0 && type_counters[ICMP_TYPE]!=0 && type_counters[MIXED_SERVICE]==0) my_type = ICMP_TYPE; if (my_type==UNKNOWN) my_type = MIXED_SERVICE; setObjectGroupType(my_type); } bool BaseObjectGroup::isServiceGroup() { switch (getObjectGroupType()) { case PROTO: return true; case ICMP_TYPE: return true; case TCP_SERVICE: return true; case UDP_SERVICE: return true; case TCP_UDP_SERVICE: return true; case MIXED_SERVICE: return true; default: return false; } return false; } bool BaseObjectGroup::isObjectGroup() { switch (getObjectGroupType()) { case UNKNOWN: return true; case NETWORK: return true; default: return false; } return false; } string BaseObjectGroup::getSrvTypeName() { switch (getObjectGroupType()) { case ICMP_TYPE: return "icmp"; case TCP_SERVICE: return "tcp"; case UDP_SERVICE: return "udp"; case TCP_UDP_SERVICE: return "tcp-udp"; default: break; } return ""; } string BaseObjectGroup::getObjectGroupClass() { switch (getObjectGroupType()) { case PROTO: case ICMP_TYPE: case TCP_SERVICE: case UDP_SERVICE: case TCP_UDP_SERVICE: case MIXED_SERVICE: return "service"; default: return "network"; } return ""; } QString BaseObjectGroup::groupMemberToString(FWObject*, NamedObjectsManager*) throw(libfwbuilder::FWException) { return ""; } QString BaseObjectGroup::toString(NamedObjectsManager *nm) throw(FWException) { QStringList res; if (this->size()==0) return ""; res << getObjectGroupHeader().c_str(); for (FWObject::iterator i1=this->begin(); i1!=this->end(); ++i1) { res << QString(" %1").arg( groupMemberToString(FWReference::getObject(*i1), nm)); } res << getObjectGroupFooter().c_str(); res << ""; return res.join("\n"); } string BaseObjectGroup::getObjectGroupHeader() { return ""; } string BaseObjectGroup::getObjectGroupFooter() { return ""; } fwbuilder-5.1.0.3599/src/cisco_lib/cisco_lib.pro0000644000175000017500000000746211733011756022174 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # TEMPLATE = lib # SOURCES = PolicyCompiler_cisco.cpp \ PolicyCompiler_cisco_acls.cpp \ NamedObjectsAndGroupsSupport.cpp \ NamedObjectsManager.cpp \ NamedObjectsManagerIOS.cpp \ NamedObjectsManagerPIX.cpp \ RoutingCompiler_cisco.cpp \ RoutingCompiler_cisco_writers.cpp \ splitByNetworkZonesForRE.cpp \ specialServices.cpp \ ACL.cpp \ NamedObject.cpp \ ASA8TwiceNatLogic.cpp \ Helper.cpp \ inspectionProtocol.cpp \ InspectionClassMap.cpp \ OSConfigurator_ios.cpp \ CompilerDriver_iosacl.cpp \ CompilerDriver_iosacl_run.cpp \ PolicyCompiler_iosacl.cpp \ PolicyCompiler_iosacl_writers.cpp \ RoutingCompiler_iosacl.cpp \ RoutingCompiler_iosacl_writers.cpp \ CompilerDriver_pix.cpp \ CompilerDriver_pix_run.cpp \ NATCompiler_pix.cpp \ NATCompiler_pix_find_translations.cpp \ NATCompiler_pix_writers.cpp \ NATCompiler_asa8.cpp \ NATCompiler_asa8_writers.cpp \ NATCompiler_pix_optimizers.cpp \ OSConfigurator_pix_os.cpp \ OSConfigurator_pix_os_fixups.cpp \ OSConfigurator_pix_os_inspectors.cpp \ OSConfigurator_pix_os_inspectors_pix8.cpp \ CompilerDriver_procurve_acl.cpp \ CompilerDriver_procurve_acl_run.cpp\ OSConfigurator_procurve.cpp \ PolicyCompiler_procurve_acl.cpp \ PolicyCompiler_procurve_acl_writers.cpp \ RoutingCompiler_procurve_acl.cpp \ BaseObjectGroup.cpp \ PIXObjectGroup.cpp \ ASA8ObjectGroup.cpp \ IOSObjectGroup.cpp \ PolicyCompiler_pix.cpp \ PolicyCompiler_pix_writers.cpp \ PolicyCompiler_pix_v6_acls.cpp \ PolicyCompiler_pix_replace_translations.cpp \ RoutingCompiler_pix.cpp \ RoutingCompiler_pix_writers.cpp \ AutomaticRules_cisco.cpp \ AutomaticRules_iosacl.cpp HEADERS = ../../config.h \ PortRangeConverter.h \ splitByNetworkZonesForRE.h \ specialServices.h \ ACL.h \ Helper.h \ NamedObject.h \ ASA8TwiceNatLogic.h \ NamedObjectsAndGroupsSupport.h \ NamedObjectsManager.h \ NamedObjectsManagerIOS.h \ NamedObjectsManagerPIX.h \ NamedObjectsManagerASA8.h \ inspectionProtocol.h \ InspectionClassMap.h \ PolicyCompiler_cisco.h \ RoutingCompiler_cisco.h \ CompilerDriver_iosacl.h \ OSConfigurator_ios.h \ PolicyCompiler_iosacl.h \ CompilerDriver_pix.h \ NATCompiler_pix.h \ NATCompiler_asa8.h \ OSConfigurator_pix_os.h \ CompilerDriver_procurve_acl.h \ OSConfigurator_procurve.h \ PolicyCompiler_procurve_acl.h \ RoutingCompiler_procurve_acl.h \ BaseObjectGroup.h \ PIXObjectGroup.h \ ASA8ObjectGroup.h \ IOSObjectGroup.h \ PolicyCompiler_pix.h \ RoutingCompiler_pix.h \ AutomaticRules_cisco.h \ AutomaticRules_iosacl.h macx:LIBS += $$LIBS_FWCOMPILER INCLUDEPATH += ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../compiler_lib ../libfwbuilder/src win32:PRE_TARGETDEPS = ../compiler_lib/release/libcompilerdriver.a !win32:PRE_TARGETDEPS = ../compiler_lib/libcompilerdriver.a CONFIG += staticlib TARGET = fwbcisco INSTALLS -= target fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_asa8.h0000644000175000017500000001011511733011756022713 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _NATCOMPILER_ASA8_HH #define _NATCOMPILER_ASA8_HH #include "NATCompiler_pix.h" #include #include namespace fwcompiler { class NamedObject; class ASA8ObjectGroup; class NATCompiler_asa8 : public NATCompiler_pix { public: QString sanitizeObjectName(const QString &name); std::string createNetworkObjectCommand(libfwbuilder::Address *addr); std::string createServiceObjectCommand(libfwbuilder::Service *addr); /** * verifies correctness of the NAT rules. Some rule types * that were not supported in PIX v <8.3 are supported now, * so this rule processor is slightly different from * NATCompiler_pix::VerifyRules */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules); /* * Check that TSrc has right combination of objects after * object group has been created. Call after CreateObjectGroupsForTSrc */ DECLARE_NAT_RULE_PROCESSOR(VerifyValidityOfTSrc); /* * Check if "translate dns" option can be used with the rule */ DECLARE_NAT_RULE_PROCESSOR(VerifyValidityOfDNSOption); /** * for #1954 Issue a warning when nat rule with the same interface * is used for the real and mapped interface, as in * nat (outside,outside) */ DECLARE_NAT_RULE_PROCESSOR(verifyInterfacesInNatRule); /** * Split rule to make sure objects in OSrc match network zones * of interfaces. We only need to do this for ASA 8.3 where we * support object-groups in "nat" rules. Older versions did * not support groups and so required all nat rules to be * atomic which achieved the same effect. */ class splitByNetworkZonesForOSrc : public splitByNetworkZonesForRE { public: splitByNetworkZonesForOSrc(const std::string &n) : splitByNetworkZonesForRE(n, libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. Negation * should also have been taken care of before this method is * called. */ friend class PrintRule; class PrintRule : public NATCompiler_pix::PrintRule { QString printSingleObject(libfwbuilder::FWObject *obj); public: PrintRule(const std::string &n); virtual void printNONAT(libfwbuilder::NATRule *rule); virtual void printSNAT(libfwbuilder::NATRule *rule); virtual void printSDNAT(libfwbuilder::NATRule *rule); virtual void printDNAT(libfwbuilder::NATRule *rule); }; friend class NATCompiler_asa8::PrintRule; NATCompiler_asa8(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf); virtual ~NATCompiler_asa8(); virtual void compile(); virtual std::string printClearCommands(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_pix.h0000644000175000017500000004530711733011756022672 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _NATCOMPILER_PIX_HH #define _NATCOMPILER_PIX_HH #include "fwcompiler/NATCompiler.h" #include "Helper.h" #include "NamedObjectsAndGroupsSupport.h" #include "splitByNetworkZonesForRE.h" #include "specialServices.h" #include #include namespace fwcompiler { typedef enum { UNKNOWN, INTERFACE, SINGLE_ADDRESS, NETWORK_ADDRESS, ADDRESS_RANGE } global_pool_type; typedef enum { NONAT_NAT0, NONAT_STATIC } nonat_types; struct NATCmd { bool ignore_nat; bool ignore_nat_and_print_acl; bool ignore_global; bool use_nat_0_0; bool outside; std::string rule_label; std::string comment; libfwbuilder::Address *o_src; // for "nat" command libfwbuilder::Address *o_dst; // for "nat" command libfwbuilder::Service *o_srv; // for acl in "nat" command for 6.3 libfwbuilder::Address *t_addr; // for "global" command libfwbuilder::Interface *i_iface; // inbound libfwbuilder::Interface *o_iface; // ountbound int nat_id; std::string nat_acl_name; global_pool_type type; }; struct StaticCmd { bool ignore_scmd_and_print_acl; std::string acl_name; std::string rule; libfwbuilder::Address *iaddr; libfwbuilder::Address *oaddr; libfwbuilder::Address *osrc; libfwbuilder::Service *osrv; libfwbuilder::Service *tsrv; libfwbuilder::Interface *i_iface; // inbound libfwbuilder::Interface *o_iface; // outbound StaticCmd() { }; bool operator==(const StaticCmd &other); }; class NATCompiler_pix : public NATCompiler { public: Helper helper; NamedObjectsManager *named_objects_manager; int global_pool_no; std::map nat_commands; std::map static_commands; struct nonat { std::string acl_name; //libfwbuilder::Interface *i_iface; //libfwbuilder::Interface *o_iface; libfwbuilder::Address *src; libfwbuilder::Address *dst; bool last; nonat() { last=false; } }; // first: rule->getId(), second: nonat object std::map nonat_rules; // first: interface->getId(), second: rule->getId() std::map first_nonat_rule_id; int final_ruleset_id; std::string debugPrintRule(libfwbuilder::Rule *r); void _expand_addr_recursive_pix(libfwbuilder::Rule *rule, libfwbuilder::FWObject *re, libfwbuilder::FWObject *s, std::list &ol, bool expand_cluster_interfaces_fully); virtual void _expand_addr_recursive(libfwbuilder::Rule *rule, libfwbuilder::FWObject *s, std::list &ol, bool expand_cluster_interfaces_fully); /** * internal: checks if interface is a child of a cluster and calls * Compiler::_expand_interface() with a pointer to the master member * interface. If @iface is not cluster interface, just calls * Compiler::_expand_interface() */ virtual void _expand_interface(libfwbuilder::Rule *rule, libfwbuilder::Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully); /* this is a dictionary of all nat acl names and associated boolean * flag that indicates that corresponding 'clear' command has been * issued. We use this to keep track of all names that are created to * make sure they are unique */ std::map nat_acl_names; std::string getNATACLname(libfwbuilder::Rule *r,int nat_id); std::string getNATACLname(libfwbuilder::Rule *r,std::string suffix); /** * verifies correctness of the NAT rules */ DECLARE_NAT_RULE_PROCESSOR(VerifyRules); friend class NATCompiler_pix::VerifyRules; /** * using network zone information determine inside and outside * interfaces for the NAT rule */ DECLARE_NAT_RULE_PROCESSOR( AssignInterface ); friend class NATCompiler_pix::AssignInterface; /** * if previous processor assigned the same interface as both * internal and external one for the NAT operation, drop the rule */ DECLARE_NAT_RULE_PROCESSOR( verifyInterfaces ); friend class NATCompiler_pix::verifyInterfaces; /** * in case of DNAT both odst and tdst should be of the same size: * either both hosts, or both networks of the same size and can not * be address ranges. There are other limitations, too. */ DECLARE_NAT_RULE_PROCESSOR( verifyRuleElements ); friend class NATCompiler_pix::verifyRuleElements; /** * expands address ranges in OSrc and ODst */ DECLARE_NAT_RULE_PROCESSOR( ExpandAddressRanges ); friend class NATCompiler_pix::ExpandAddressRanges; /** * in case OSrv is not "any" but TSrv is "original", copy it over */ DECLARE_NAT_RULE_PROCESSOR( fillTranslatedSrv ); friend class NATCompiler_pix::fillTranslatedSrv; /** * replaces firewall objects in ODst with its external interface(s) */ DECLARE_NAT_RULE_PROCESSOR( ReplaceFirewallObjectsODst ); friend class NATCompiler_pix::ReplaceFirewallObjectsODst; /** * replaces firewall objects in TSrc with its external interface(s) */ DECLARE_NAT_RULE_PROCESSOR( ReplaceFirewallObjectsTSrc ); friend class NATCompiler_pix::ReplaceFirewallObjectsTSrc; /** * replace host object with firewall's interace if host object * has the same address */ class UseFirewallInterfaces : public NATRuleProcessor { void scanInterfaces(libfwbuilder::RuleElement *rel); public: UseFirewallInterfaces(const std::string &name) : NATRuleProcessor(name){} virtual bool processNext(); }; friend class NATCompiler_pix::UseFirewallInterfaces; /** * this processor creates ACL for nat 0 rules */ class processNONATRules : public NATRuleProcessor { protected: int nonat_no; public: processNONATRules(const std::string &name) : NATRuleProcessor(name){ nonat_no=1; } virtual bool processNext(); }; friend class NATCompiler_pix::processNONATRules; /** * this processor creates object of class NATCmd if rule is of * type SNAT */ class createNATCmd : public NATRuleProcessor { protected: int nat_id_counter; public: createNATCmd(const std::string &name) : NATRuleProcessor(name){ nat_id_counter=1; } virtual bool processNext(); }; friend class NATCompiler_pix::createNATCmd; /** * Creates objects of class StaticCmd for all DNAT rules */ class createStaticCmd : public NATRuleProcessor { protected: int sc_id_counter; public: createStaticCmd(const std::string &name) : NATRuleProcessor(name){ sc_id_counter=1; } virtual bool processNext(); }; friend class NATCompiler_pix::createStaticCmd; /** * this processor manipulates list of NATCmd objects so that * to reuse identical "nat" and "global" rules. It also * merges objects of class StaticCmd in DNAT rules to avoid * * duplicate "static" commands */ DECLARE_NAT_RULE_PROCESSOR( mergeNATCmd ); friend class NATCompiler_pix::mergeNATCmd; /** * takes ID of the original object used in OSrc that has been * stored in storeOriginalOSrcID and compares this object with * network zones of interfaces. If FirewallOption * "pix_optimize_default_nat" is set and original OSrc is the * same as network zone of one of the interfaces, replaces * OSrc in this rule with "Any". */ DECLARE_NAT_RULE_PROCESSOR( optimizeDefaultNAT ); friend class NATCompiler_pix::optimizeDefaultNAT; /** * this rule processor uses boolean flag "clear_osrc" set by * optimizeDefaultNAT and removes objects in OSrc if this flag is set. */ DECLARE_NAT_RULE_PROCESSOR( clearOSrc ); friend class NATCompiler_pix::clearOSrc; class SpecialServicesOSrv : public SpecialServices { public: SpecialServicesOSrv(const std::string &n): SpecialServices(n, libfwbuilder::RuleElementOSrv::TYPENAME) {} }; /** * eliminates duplicate objects in SRC. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRC : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRC(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInODST : public eliminateDuplicatesInRE { public: eliminateDuplicatesInODST(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV. Uses default comparison * in eliminateDuplicatesInRE which compares IDs */ class eliminateDuplicatesInOSRV : public eliminateDuplicatesInRE { public: eliminateDuplicatesInOSRV(const std::string &n) : eliminateDuplicatesInRE(n,libfwbuilder::RuleElementOSrv::TYPENAME) {} }; /** * Placeholder for MultiAddressRunTime objects that are not * supported for ipf */ class processMultiAddressObjectsInRE : public NATRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : NATRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInOSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInOSrc(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementOSrc::TYPENAME) {} }; class processMultiAddressObjectsInODst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInODst(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementODst::TYPENAME) {} }; /** * prints single policy rule, assuming all groups have been * expanded, so source, destination and service hold exactly * one object each, and this object is not a group. Negation * should also have been taken care of before this method is * called. */ friend class PrintRule; class PrintRule : public NATRuleProcessor { protected: bool init; std::string current_rule_label; std::string _printPortRangeOp(int rs, int re); std::string _printSrcService(libfwbuilder::Service *srv); std::string _printDstService(libfwbuilder::Service *srv); virtual void _printPort(libfwbuilder::Service *srv); std::string _printAddress(libfwbuilder::Address *a,bool print_netmask); std::string _printConnOptions(libfwbuilder::NATRule *rule); std::map printed_global_pools; public: PrintRule(const std::string &n); virtual bool processNext(); virtual void printNONAT(libfwbuilder::NATRule *rule); virtual void printSNAT(libfwbuilder::NATRule *rule); virtual void printSDNAT(libfwbuilder::NATRule *rule); virtual void printDNAT(libfwbuilder::NATRule *rule); }; friend class NATCompiler_pix::PrintRule; /** * detects duplicate nat */ class DetectDuplicateNAT : public NATRuleProcessor { public: DetectDuplicateNAT(const std::string &n) : NATRuleProcessor(n){} virtual bool processNext(); }; friend class NATCompiler_pix::DetectDuplicateNAT; /** * base class that has a method that checks for overlapping addresses * taking into account address ranges and other situations */ friend class DetectOverlap; class DetectOverlap : public NATRuleProcessor { protected: bool checkOverlapping(const libfwbuilder::Address &a1, const libfwbuilder::InetAddr &a2); std::string printGlobalPoolAddress(const libfwbuilder::Address &pool); public: DetectOverlap(const std::string &n) : NATRuleProcessor(n){} virtual ~DetectOverlap(); }; friend class NATCompiler_pix::DetectOverlap; /** * detects overlapping and some other problems with global pools */ friend class DetectGlobalPoolProblems; class DetectGlobalPoolProblems : public DetectOverlap { public: DetectGlobalPoolProblems(const std::string &n) : DetectOverlap(n){} virtual bool processNext(); }; friend class NATCompiler_pix::DetectGlobalPoolProblems; /** * detects overlapping global pools and static rules */ friend class DetectOverlappingGlobalPoolsAndStaticRules; class DetectOverlappingGlobalPoolsAndStaticRules : public DetectOverlap { public: DetectOverlappingGlobalPoolsAndStaticRules(const std::string &n) : DetectOverlap(n){} virtual bool processNext(); }; friend class NATCompiler_pix::DetectOverlappingGlobalPoolsAndStaticRules; /** * suppress identical nonat static (this happens in rules * that request no translation in access from a low security * zone to a high security zone and have group or multiple * objects in OSrc). */ friend class SuppressDuplicateNONATStatics; class SuppressDuplicateNONATStatics : public NATRuleProcessor { protected: typedef struct { std::string iface1, iface2; libfwbuilder::InetAddr addr; libfwbuilder::InetAddr mask; } nonat_static_parameters; std::deque all_nonat_statics; public: SuppressDuplicateNONATStatics(const std::string &n) : NATRuleProcessor(n){} virtual bool processNext(); }; friend class NATCompiler_pix::SuppressDuplicateNONATStatics; /** * detects overlapping static */ friend class DetectOverlappingStatics; class DetectOverlappingStatics : public NATRuleProcessor { protected: public: DetectOverlappingStatics(const std::string &n) : NATRuleProcessor(n){} virtual bool processNext(); }; friend class NATCompiler_pix::DetectOverlappingStatics; /** * this processor stores processed NAT rules in final_ruleset */ DECLARE_NAT_RULE_PROCESSOR( storeProcessedRules ); friend class NATCompiler_pix::storeProcessedRules; protected: virtual std::string myPlatformName(); public: NATCompiler_pix(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf); virtual ~NATCompiler_pix(); virtual int prolog(); virtual void compile(); virtual void epilog(); void regroup(); virtual std::string printClearCommands(); virtual std::string printPreambleCommands(); /** * scans all rules in source_ruleset and finds rules (if * any) that define DNAT translation for a combination of * src,dst and srv where src matches OSrc, srv matches OSrv * and dst matches rule element defined by argument * nat_re_type_to_match_dst. If such rules could be found, returns * a list of triplets (src,odst,osrv) */ std::list findMatchingDNATRules( libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv, const std::string &nat_re_type_to_match_dst); // virtual string atomicRuleToString(libfwbuilder::Rule *r); void registerACL(const std::string& acl_name) { setACLFlag(acl_name,0); } int getACLFlag(const std::string& acl_name) { if (nat_acl_names.count(acl_name)!=0) return nat_acl_names[acl_name]; return -1; } void setACLFlag(const std::string& acl_name, int f) { nat_acl_names[acl_name] = f; } void setNamedObjectsManager(NamedObjectsManager *mgr); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManagerASA8.h0000644000175000017500000000251211733011756024132 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _NAMED_OBJECTS_MANAGER_ASA8_HH #define _NAMED_OBJECTS_MANAGER_ASA8_HH #include "config.h" #include "NamedObjectsManagerPIX.h" namespace fwcompiler { class NamedObjectsManagerASA8 : public NamedObjectsManagerPIX { public: NamedObjectsManagerASA8(libfwbuilder::Library *persistent_objects, libfwbuilder::Firewall *fw) : NamedObjectsManagerPIX(persistent_objects, fw) {} virtual ~NamedObjectsManagerASA8() {}; }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_cisco_acls.cpp0000644000175000017500000003257511733011756025347 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_cisco.h" #include "NamedObjectsManager.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* * Call this rule processor after splitIfSrcMatchesFw and * splitIfDstMatchesFw to make sure that if firewall or its interface * or address is in src or dst, it is the only object there. */ bool PolicyCompiler_cisco::setInterfaceAndDirectionBySrc::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; Helper helper(compiler); list intf_id_list; RuleElementItf *intf_re = rule->getItf(); if (intf_re->isAny()) { bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); Cluster *cluster = NULL; if (cluster_member) cluster = Cluster::cast( compiler->dbcopy->findInIndex( compiler->fw->getInt("parent_cluster_id"))); RuleElementSrc *srcre = rule->getSrc(); RuleElementDst *dstre = rule->getDst(); Address *srcobj = compiler->getFirstSrc(rule); if (rule->getDirection()==PolicyRule::Both && ! compiler->complexMatch(srcobj, compiler->fw) && ! compiler->complexMatch(srcobj, cluster)) { intf_id_list = helper.findInterfaceByNetzoneOrAll( srcre ); } if (rule->getDirection()==PolicyRule::Inbound) intf_id_list = helper.getAllInterfaceIDs(); for (list::iterator i = intf_id_list.begin(); i!=intf_id_list.end(); ++i) { int intf_id = *i; Interface *ifs = Interface::cast(rule->getRoot()->findInIndex(intf_id)); assert(ifs); if (ifs->isUnprotected()) continue; // skip! if (ifs->isLoopback()) continue; // skip! PolicyRule *new_rule = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); // new_rule->setInterfaceId(intf_id); RuleElementItf *itf_re = new_rule->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(ifs); new_rule->setDirection(PolicyRule::Inbound); new_rule->setBool("interface_and_direction_set_from_src",true); tmp_queue.push_back(new_rule); } // If dst does not match firewall, preserve original rule as // well to let setInterfaceAndDirectionByDst work on it. // // Note for #1298 // // if address in dst is multicast, it can be forwarded and so // we need to preserve the rule. But broadcasts are not // forwarded so we should consider them as matching the fw. // FWObject *d = dstre->front(); if (FWReference::cast(d)!=NULL) d = FWReference::cast(d)->getPointer(); if (!compiler->complexMatch(Address::cast(d), compiler->fw, true, false)) tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_cisco::setInterfaceAndDirectionByDst::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; Helper helper(compiler); if (rule->getBool("interface_and_direction_set_from_src")) { tmp_queue.push_back(rule); return true; } RuleElementItf *intf_re = rule->getItf(); list intf_id_list; if (intf_re->isAny()) { bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member"); Cluster *cluster = NULL; if (cluster_member) cluster = Cluster::cast( compiler->dbcopy->findInIndex( compiler->fw->getInt("parent_cluster_id"))); RuleElementDst *dstre = rule->getDst(); Address *dstobj = compiler->getFirstDst(rule); if (rule->getDirection()==PolicyRule::Both && ! compiler->complexMatch(dstobj, compiler->fw) && ! compiler->complexMatch(dstobj, cluster)) { intf_id_list = helper.findInterfaceByNetzoneOrAll( dstre ); } if (rule->getDirection()==PolicyRule::Outbound) intf_id_list = helper.getAllInterfaceIDs(); for (list::iterator i = intf_id_list.begin(); i!=intf_id_list.end(); ++i) { int intf_id = *i; Interface *ifs = Interface::cast(rule->getRoot()->findInIndex(intf_id)); assert(ifs); if (ifs->isUnprotected()) continue; // skip! if (ifs->isLoopback()) continue; // skip! PolicyRule *new_rule = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); // new_rule->setInterfaceId(intf_id); RuleElementItf *itf_re = new_rule->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(ifs); new_rule->setDirection(PolicyRule::Outbound); new_rule->setBool("interface_and_direction_set_from_dst",true); tmp_queue.push_back(new_rule); } return true; } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_cisco::setInterfaceAndDirectionIfInterfaceSet::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; //RuleElementItf *itfre=rule->getItf(); RuleElementItf *intf_re = rule->getItf(); if (intf_re->isAny() || rule->getBool("interface_and_direction_set_from_src") || rule->getBool("interface_and_direction_set_from_dst")) { tmp_queue.push_back(rule); return true; } PolicyRule *new_rule; if ( ! intf_re->isAny()) { FWObject *rule_iface = FWObjectReference::getObject(intf_re->front()); RuleElementItf *itf_re; if (rule->getDirection()==PolicyRule::Both) { new_rule =compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); // new_rule->setInterfaceId( rule_iface_id ); itf_re = new_rule->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(rule_iface); new_rule->setDirection(PolicyRule::Inbound); new_rule->setBool("interface_and_direction_set",true); tmp_queue.push_back(new_rule); new_rule =compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); // new_rule->setInterfaceId( rule_iface_id ); itf_re = new_rule->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(rule_iface); new_rule->setDirection(PolicyRule::Outbound); new_rule->setBool("interface_and_direction_set",true); tmp_queue.push_back(new_rule); } else { new_rule =compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); // new_rule->setInterfaceId( rule_iface_id ); itf_re = new_rule->getItf(); assert(itf_re!=NULL); itf_re->reset(); itf_re->addRef(rule_iface); // direction is copied from the original rule new_rule->setBool("interface_and_direction_set",true); tmp_queue.push_back(new_rule); } } return true; } bool PolicyCompiler_cisco::pickACL::processNext() { PolicyCompiler_cisco *cisco_comp = dynamic_cast( compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; // Interface *rule_iface = Interface::cast(compiler->dbcopy->findInIndex( // rule->getInterfaceId())); RuleElementItf *intf_re = rule->getItf(); Interface *rule_iface = Interface::cast( FWObjectReference::getObject(intf_re->front())); if(rule_iface==NULL) { compiler->abort(rule, "Missing interface assignment"); return true; } /* * option 'Generate outbound access lists' is called * 'pix_generate_out_acl' for PIX and 'generate_out_acl' for * IOS. Need to check the right one depending on what platform * this compiler is for. Class PolicyCompiler_cisco is base class * and can be used for both. */ /* * TODO: Here we hardcode this option to True for IOS. Instead of * doing it here, just set option "generate_out_acl" to true in * PolicyCompiler_iosacl::prolog(). It is done that way in * PolicyCompiler_procurveacl already. This way, base class * PolicyCompiler_cisco does not need to be aware of the actual * platform. */ bool generate_out_acl = false; if (compiler->myPlatformName()=="pix") generate_out_acl = compiler->fw->getOptionsObject()-> getBool("pix_generate_out_acl"); else { if (compiler->myPlatformName()=="iosacl") generate_out_acl = true; else generate_out_acl = compiler->fw->getOptionsObject()-> getBool("generate_out_acl"); } if (rule->getDirection() == PolicyRule::Outbound && !generate_out_acl) { compiler->abort( rule, "Rule with direction 'Outbound' requires outbound ACL " "but option 'Generate outbound access lists' is OFF."); return true; } /* The choice of the ACL name depends on whether this is a named * acl or not. If not, should use unique numbers. Also need to * pass this flag to the ciscoACL object. */ string acl_name = rule_iface->getLabel(); if (acl_name.empty()) acl_name = rule_iface->getName(); acl_name = cisco_comp->mangleInterfaceName(acl_name); string dir = "in"; if (rule->getDirection() == PolicyRule::Inbound) { acl_name += "_in"; dir="in"; } if (rule->getDirection() == PolicyRule::Outbound) { acl_name += "_out"; dir="out"; } // if this is not the "main" rule set, use its name for the acl name if (!compiler->getSourceRuleSet()->isTop()) acl_name = compiler->getSourceRuleSet()->getName() + "_" + acl_name; if (cisco_comp->ipv6) acl_name = "ipv6_" + acl_name; rule->setStr("acl",acl_name); ciscoACL *acl = cisco_comp->createACLObject(acl_name, rule_iface, dir, using_named_acl); cisco_comp->acls[acl_name] = acl; acl->setWorkName(acl_name); tmp_queue.push_back(rule); return true; } /* * Take interface name as an argument and produce * shortened, space-free string that uniquely identifies interface * in a human-readable way. */ std::string PolicyCompiler_cisco::mangleInterfaceName( const string &interface_name) { string::size_type n; string s = interface_name; // lowercase all characters transform (s.begin(), s.end(), // source s.begin(), // destination ::tolower); // operation map name_mapping; map::iterator nmi; name_mapping["async"] = "as"; name_mapping["atm"] = "atm"; name_mapping["bri"] = "bri"; name_mapping["ethernet"] = "e"; name_mapping["fastethernet"] = "fe"; name_mapping["fddi"] = "fddi"; name_mapping["gigabitethernet"] = "ge"; name_mapping["hssi"] = "h"; name_mapping["loopback"] = "l"; name_mapping["port-channel"] = "pc"; name_mapping["pos"] = "pos"; name_mapping["serial"] = "s"; name_mapping["switch"] = "sw"; name_mapping["tokenring"] = "tr"; name_mapping["tunnel"] = "tun"; name_mapping["tengigabitethernet"] = "te"; name_mapping["sonet"] = "so"; name_mapping["vg-anylan"] = "vg"; for (nmi=name_mapping.begin(); nmi!=name_mapping.end(); nmi++) { if (s.find( nmi->first )==0) { s.replace(0, nmi->first.size(), nmi->second); break; } } while ( (n=s.find(" "))!=string::npos) { s.replace(n,1,"_"); } while ( (n=s.find("/"))!=string::npos) { s.replace(n,1,"_"); } return s; } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_iosacl.h0000644000175000017500000000510211733011756024336 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ROUTINGCOMPILER_IOSACL_HH__ #define __ROUTINGCOMPILER_IOSACL_HH__ #include #include "fwcompiler/RoutingCompiler.h" #include "fwbuilder/RuleElement.h" #include "config.h" #include "RoutingCompiler_cisco.h" namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_iosacl : public RoutingCompiler_cisco { protected: virtual std::string myPlatformName(); /** * this inspector replaces references to hosts and firewalls * in dst and gw with references to their interfaces, except * for interfaces of the firewall found in gw, which are left * intact. */ DECLARE_ROUTING_RULE_PROCESSOR(ExpandMultipleAddressesExceptInterface); DECLARE_ROUTING_RULE_PROCESSOR(checkRItfAndGw); class PrintRule : public RoutingCompiler_cisco::PrintRule { public: PrintRule(const std::string &name); virtual bool processNext(); virtual std::string RoutingRuleToString(libfwbuilder::RoutingRule *r); virtual std::string _printRGtw(libfwbuilder::RoutingRule *r); virtual std::string _printRItf(libfwbuilder::RoutingRule *r); }; friend class RoutingCompiler_iosacl::PrintRule; public: RoutingCompiler_iosacl(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler_cisco(_db, fw, ipv6_policy, _oscnf) {}; virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/ASA8ObjectGroup.h0000644000175000017500000000261111733011756022524 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _ASA8_OBJECT_GROUP_HH #define _ASA8_OBJECT_GROUP_HH #include "PIXObjectGroup.h" namespace fwcompiler { class ASA8ObjectGroup : public PIXObjectGroup { public: ASA8ObjectGroup() : PIXObjectGroup() { } virtual ~ASA8ObjectGroup() {}; DECLARE_FWOBJECT_SUBTYPE(ASA8ObjectGroup); virtual std::string getObjectGroupClass(); virtual QString groupMemberToString( libfwbuilder::FWObject *obj, NamedObjectsManager *named_obj_manager) throw(libfwbuilder::FWException); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_pix_replace_translations.cpp0000644000175000017500000001611311733011756030327 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "Helper.h" #include "PolicyCompiler_pix.h" #include "NATCompiler_pix.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; bool PolicyCompiler_pix::matchTranslatedAddresses::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; string version = compiler->fw->getStr("version"); transformed_rules.clear(); RuleElementSrc *srcrel = rule->getSrc(); RuleElementDst *dstrel = rule->getDst(); RuleElementSrv *srvrel = rule->getSrv(); for (list::iterator i1=srcrel->begin(); i1!=srcrel->end(); ++i1) { for (list::iterator i2=dstrel->begin(); i2!=dstrel->end(); ++i2) { for (list::iterator i3=srvrel->begin(); i3!=srvrel->end(); ++i3) { FWObject *o1 = *i1; FWObject *o2 = *i2; FWObject *o3 = *i3; FWObject *obj1 = NULL; FWObject *obj2 = NULL; FWObject *obj3 = NULL; obj1 = FWReference::getObject(o1); Address *src = Address::cast(obj1); assert(src!=NULL); obj2 = FWReference::getObject(o2); Address *dst = Address::cast(obj2); assert(dst!=NULL); obj3 = FWReference::getObject(o3); Service *srv = Service::cast(obj3); assert(srv!=NULL); list tl = findMatchingNATRules(src, dst, srv); for( list::iterator t=tl.begin(); t!=tl.end(); ++t) action(rule, *t, src, dst, srv); } } } /* *list transformed_rules has all the atomic rules that have a matching * NAT rule, with dst and srv already converted. We just add them to * the policy on top of the original rule. */ list::iterator i1; for (i1=transformed_rules.begin(); i1!=transformed_rules.end(); ++i1) { PolicyRule *r=PolicyRule::cast( *i1 ); tmp_queue.push_back(r); } tmp_queue.push_back(rule); return true; } list PolicyCompiler_pix::matchTranslatedAddresses::findMatchingNATRules( Address*, Address*, Service*) { return list(); } void PolicyCompiler_pix::matchTranslatedAddresses::action( PolicyRule* , NATRule* , Address*, Address*, Service*) { } list PolicyCompiler_pix::replaceTranslatedAddresses::findMatchingNATRules( Address *src, Address *dst, Service *srv) { PolicyCompiler_pix *pix_comp = dynamic_cast(compiler); return pix_comp->natcmp->findMatchingDNATRules( src, dst, srv, RuleElementTDst::TYPENAME); } void PolicyCompiler_pix::replaceTranslatedAddresses::action( PolicyRule* policy_rule, NATRule* nat_rule, Address *src, Address*, Service *srv) { // FWObject *rule_iface = compiler->dbcopy->findInIndex( // policy_rule->getInterfaceId()); RuleElementItf *intf_re = policy_rule->getItf(); FWObject *rule_iface = FWObjectReference::getObject(intf_re->front()); RuleElement *re = nat_rule->getOSrc(); FWObject *o = FWReference::getObject(re->front()); Address *osrc = Address::cast(o); assert(osrc); re = nat_rule->getODst(); o = FWReference::getObject(re->front()); Address *odst = Address::cast(o); assert(odst); re = nat_rule->getOSrv(); o = FWReference::getObject(re->front()); Service *osrv = Service::cast(o); assert(osrv); re = nat_rule->getTSrc(); o = FWReference::getObject(re->front()); Address *tsrc = Address::cast(o); assert(tsrc); re = nat_rule->getTDst(); o = FWReference::getObject(re->front()); Address *tdst = Address::cast(o); assert(tdst); re = nat_rule->getTSrv(); o = FWReference::getObject(re->front()); Service *tsrv = Service::cast(o); assert(tsrv); FWObject *p = odst->getParent(); if (odst->getId() == rule_iface->getId() || p->getId() == rule_iface->getId()) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(policy_rule); RuleElementSrc *nsrc = r->getSrc(); nsrc->clearChildren(); nsrc->addRef( src ); RuleElementDst *ndst = r->getDst(); ndst->clearChildren(); ndst->addRef( odst ); RuleElementSrv *nsrv = r->getSrv(); nsrv->clearChildren(); if (osrv->isAny()) nsrv->addRef( srv ); else nsrv->addRef( osrv ); transformed_rules.push_back(r); } } list PolicyCompiler_pix::warnWhenTranslatedAddressesAreUsed::findMatchingNATRules( Address *src, Address *dst, Service *srv) { PolicyCompiler_pix *pix_comp = dynamic_cast(compiler); return pix_comp->natcmp->findMatchingDNATRules( src, dst, srv, RuleElementODst::TYPENAME); } void PolicyCompiler_pix::warnWhenTranslatedAddressesAreUsed::action( PolicyRule* policy_rule, NATRule* nat_rule, Address*, Address *dst, Service*) { // FWObject *rule_iface = compiler->dbcopy->findInIndex( // policy_rule->getInterfaceId()); RuleElementItf *intf_re = policy_rule->getItf(); FWObject *rule_iface = FWObjectReference::getObject(intf_re->front()); string version = compiler->fw->getStr("version"); RuleElement *re; FWObject *o; re = nat_rule->getODst(); o = FWReference::getObject(re->front()); Address *odst = Address::cast(o); assert(odst); FWObject *p = odst->getParent(); if (odst->getId() == rule_iface->getId() || p->getId() == rule_iface->getId()) { QString err("Object %1 that represents translated address in a NAT rule %2 " "is used in a policy rule of ASA v%3 firewall. " "Starting with v8.3, ASA requires using real IP addresses " "in the firewall policy rules. "); compiler->warning( policy_rule, err.arg(QString::fromUtf8(dst->getName().c_str())) .arg(nat_rule->getLabel().c_str()) .arg(version.c_str()).toStdString()); } } fwbuilder-5.1.0.3599/src/cisco_lib/specialServices.h0000644000175000017500000000343511733011756023015 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SPECIALSERVICES_HH #define __SPECIALSERVICES_HH #include "fwbuilder/RuleElement.h" #include "fwcompiler/RuleProcessor.h" namespace libfwbuilder { class Address; class Rule; }; namespace fwcompiler { /** * this processor checks for the services which require * special treatment. Some of these will be checking for * source or destination object as well because special * command may need to be generated in case source or * destination is a firewall itself. Therefore this processor * should be called after converting to atomic rules, but * before interface addresses in source and destination are * expanded. */ class SpecialServices : public BasicRuleProcessor { std::string re_type; public: SpecialServices(const std::string &name, const std::string &_type) : BasicRuleProcessor(name) {re_type=_type; } virtual bool processNext(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManagerIOS.h0000644000175000017500000000260711733011756024075 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _NAMED_OBJECTS_MANAGER_IOS_HH #define _NAMED_OBJECTS_MANAGER_IOS_HH #include "config.h" #include "NamedObjectsManager.h" namespace libfwbuilder { class Group; class Firewall; class Library; }; namespace fwcompiler { class NamedObjectsManagerIOS : public NamedObjectsManager { public: NamedObjectsManagerIOS(libfwbuilder::Library *persistent_objects, libfwbuilder::Firewall *_fw); virtual ~NamedObjectsManagerIOS(); virtual std::string getClearCommands(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/ACL.h0000644000175000017500000000623411733011756020270 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ACL_H #define __ACL_H #include #include #include "fwbuilder/Interface.h" namespace fwcompiler { class ciscoACL { bool _ip_acl; std::string _name; std::string _workName; libfwbuilder::Interface *_interface; std::string _dir; std::string _last_rule_label; int nlines; std::list acl; bool quote_remarks; std::string printLine(const std::string &s); std::string quoteLine(const std::string &s); std::string trimLine(const std::string &s); public: ciscoACL() { _ip_acl = false; _name = ""; _workName = ""; _interface = NULL; _dir = "in"; nlines = 0; _last_rule_label = ""; quote_remarks = false; } ciscoACL(const std::string &n, libfwbuilder::Interface *intf, const std::string &d="in", bool _ip_list=false) { _ip_acl = _ip_list; _name = n; _workName = ""; _interface = intf; _dir = d; nlines = 0; _last_rule_label = ""; quote_remarks = false; } std::string addLine(const std::string &s); /* * Adds remark to access list. Checks and adds each remark only * once. We use rule labels and comments for remarks */ std::string addRemark(const std::string &rl, const std::string &comment); void setName(const std::string &s) { _name=s; } std::string name() { return _name; } void setWorkName(const std::string &s) { _workName=s; } std::string workName() { return _workName; } void setInterface(libfwbuilder::Interface *intf) { _interface=intf; } libfwbuilder::Interface* getInterface() { return _interface; } void setDirection(const std::string &d) { _dir=d; } std::string direction() { return _dir; } void setQuoteRemarks(bool f) { quote_remarks = f; } std::string print(); std::string printLastLine(); int size() { return nlines; } }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/BaseObjectGroup.h0000644000175000017500000000617211733011756022710 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BASEOBJECTGROUP_HH #define __BASEOBJECTGROUP_HH #include "NamedObject.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/FWException.h" #include namespace fwcompiler { class NamedObjectsManager; class BaseObjectGroup : public libfwbuilder::Group { public: typedef enum { UNKNOWN, NETWORK, PROTO, ICMP_TYPE, TCP_SERVICE, UDP_SERVICE, TCP_UDP_SERVICE, MIXED_SERVICE } object_group_type; private: object_group_type gt; public: static std::map name_disambiguation; static QString registerGroupName(const QString &prefix, object_group_type gt); BaseObjectGroup() : libfwbuilder::Group() { gt = UNKNOWN; } virtual ~BaseObjectGroup() {}; DECLARE_FWOBJECT_SUBTYPE(BaseObjectGroup); virtual bool validateChild(FWObject*) { return true; } virtual FWObject& shallowDuplicate(const FWObject *obj, bool preserve_id = true) throw(libfwbuilder::FWException); void setObjectGroupType(object_group_type _gt) { gt=_gt; } object_group_type getObjectGroupType() { return gt; } void setObjectGroupTypeFromMembers(NamedObjectsManager *named_obj_manager); object_group_type getObjectGroupTypeFromFWObject( const libfwbuilder::FWObject *o); void setObjectGroupTypeFromFWObject(const libfwbuilder::FWObject *obj); bool isServiceGroup(); bool isObjectGroup(); virtual std::string getSrvTypeName(); virtual std::string getObjectGroupClass(); virtual std::string getObjectGroupHeader(); virtual std::string getObjectGroupFooter(); virtual QString groupMemberToString( libfwbuilder::FWObject *obj, NamedObjectsManager *named_obj_manager) throw(libfwbuilder::FWException); virtual QString toString(NamedObjectsManager *named_obj_manager) throw(libfwbuilder::FWException); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_procurve_acl.cpp0000644000175000017500000000260711733011756026112 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id: RoutingCompiler_procurve.cpp -1 $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "RoutingCompiler_procurve_acl.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include using namespace libfwbuilder; using namespace fwcompiler; string RoutingCompiler_procurve_acl::myPlatformName() { return "procurve_acl"; } int RoutingCompiler_procurve_acl::prolog() { int n = RoutingCompiler_cisco::prolog(); if (fw->getStr("platform")!="procurve_acl") abort("Unsupported platform " + fw->getStr("platform") ); return n; } fwbuilder-5.1.0.3599/src/cisco_lib/ASA8ObjectGroup.cpp0000644000175000017500000000476011733011756023066 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "ASA8ObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/Address.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include #include using namespace libfwbuilder; using namespace std; using namespace fwcompiler; const char *ASA8ObjectGroup::TYPENAME={"ASA8ObjectGroup"}; /* * see #2263. It looks like "object-group service" that includes named * objects defined as "service-object" can not be used in access-list * commands and therefore is useless. Unless I misunderstood and * there is a way to use it, I should not generate ASA configuration * like this: * * object-group service id5102X14531.srv.tcp.0 tcp * service-object object http.0 * service-object object https.0 * exit * * */ QString ASA8ObjectGroup::groupMemberToString( FWObject *obj, NamedObjectsManager *named_objects_manager) throw(libfwbuilder::FWException) { if (this->getObjectGroupType() == NETWORK) { NamedObject *named_object = named_objects_manager->named_objects[obj->getId()]; if (named_object) { return named_object->getCommandWhenObjectGroupMember(); } } return PIXObjectGroup::groupMemberToString(obj, named_objects_manager); } string ASA8ObjectGroup::getObjectGroupClass() { switch (this->getObjectGroupType()) { case MIXED_SERVICE: return "service";; default: return PIXObjectGroup::getObjectGroupClass(); } } fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_pix_writers.cpp0000644000175000017500000004630411733011756025002 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_pix.h" #include "PortRangeConverter.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Resources.h" #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string NATCompiler_pix::PrintRule::_printAddress(Address *a,bool print_netmask) { string addr = a->getAddressPtr()->toString(); string mask = a->getNetmaskPtr()->toString(); if (addr=="0.0.0.0" && mask=="0.0.0.0") return "any"; // if (addr=="0.0.0.0") addr="0"; // if (mask=="0.0.0.0") mask="0"; /* * If the object 'a' is a Host or a IPv4 (that is, it defines only * a single IP address) but its netmask is not 255.255.255.255, PIX will * issue an error "address,mask doesn't pair". * * I am not sure if it is appropriate to just fix this for the user, * may be I should issue a warning or even abort. */ if (Host::isA(a) || IPv4::isA(a)) mask="255.255.255.255"; if (mask=="255.255.255.255") { addr="host "+addr; mask=""; } if (print_netmask) return addr+" "+mask; else return addr; } NATCompiler_pix::PrintRule::PrintRule(const std::string &name) : NATRuleProcessor(name) { init=true; } /* * we verify that port ranges are not used in verifyRuleElements */ void NATCompiler_pix::PrintRule::_printPort(Service *srv) { if (TCPService::isA(srv) || UDPService::isA(srv)) { int drs = TCPUDPService::cast(srv)->getDstRangeStart(); if (drs!=0) compiler->output << drs << " "; } } string NATCompiler_pix::PrintRule::_printPortRangeOp(int rs, int re) { return PortRangeConverter(rs, re).toString(); } string NATCompiler_pix::PrintRule::_printSrcService(Service *srv) { if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getSrcRangeStart(); int re = TCPUDPService::cast(srv)->getSrcRangeEnd(); return _printPortRangeOp(rs, re); } return ""; } string NATCompiler_pix::PrintRule::_printDstService(Service *srv) { ostringstream str; if (TCPService::isA(srv) || UDPService::isA(srv)) { int rs = TCPUDPService::cast(srv)->getDstRangeStart(); int re = TCPUDPService::cast(srv)->getDstRangeEnd(); str << _printPortRangeOp(rs, re); } if (ICMPService::isA(srv) && srv->getInt("type")!=-1) { str << srv->getStr("type") << " "; } return str.str(); } string NATCompiler_pix::PrintRule::_printConnOptions(NATRule *rule) { if (rule==NULL) return ""; ostringstream ostr; int max_conns=compiler->fw->getOptionsObject()->getInt("pix_max_conns"); int emb_limit=compiler->fw->getOptionsObject()->getInt("pix_emb_limit"); if (max_conns<0) max_conns=0; if (emb_limit<0) emb_limit=0; // we only support tcp connection options at this time // however PIX 7.0 (7.2?) also supports udp conn limit // // Note that keyword 'tcp' here is only valid in 7.x if (libfwbuilder::XMLTools::version_compare( compiler->fw->getStr("version"),"7.0")>=0) ostr << "tcp "; ostr << max_conns << " " << emb_limit; return ostr.str(); } void NATCompiler_pix::PrintRule::printNONAT(NATRule *rule) { Helper helper(compiler); NATCompiler_pix *pix_comp = dynamic_cast(compiler); string platform = compiler->fw->getStr("platform"); string version = compiler->fw->getStr("version"); string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+version+"/pix_commands/clear_acl"); Address *osrc=compiler->getFirstOSrc(rule); assert(osrc); Address *odst=compiler->getFirstODst(rule); assert(odst); Service *osrv=compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc=compiler->getFirstTSrc(rule); assert(tsrc); Address *tdst=compiler->getFirstTDst(rule); assert(tdst); Service *tsrv=compiler->getFirstTSrv(rule); assert(tsrv); RuleElementItfInb *itf_in_re = rule->getItfInb(); assert(itf_in_re!=NULL); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); assert(itf_out_re!=NULL); Interface *i_iface = Interface::cast( FWObjectReference::getObject(itf_in_re->front())); Interface *o_iface = Interface::cast( FWObjectReference::getObject(itf_out_re->front())); switch (rule->getInt("nonat_type")) { case NONAT_NAT0: { nonat n0 = pix_comp->nonat_rules[rule->getId()]; if (rule->getBool("use_nat_0_0")) { /* old, < 6.3 */ compiler->output << "nat (" << i_iface->getLabel() << ") 0 0 0"; compiler->output << endl; } else { /* new, >=6.3 */ compiler->output << endl; if (pix_comp->getACLFlag(n0.acl_name)==0 && compiler->fw->getOptionsObject()->getBool( "pix_acl_substitution")) { compiler->output << clearACLcmd <<" " << n0.acl_name << endl; pix_comp->setACLFlag(n0.acl_name,1); } compiler->output << "access-list " << n0.acl_name << " permit ip " << _printAddress(n0.src,true) << " " << _printAddress(n0.dst,true) << endl; if (pix_comp->first_nonat_rule_id[i_iface->getId()]==rule->getId()) { if (compiler->fw->getStr("platform")=="fwsm" && compiler->fw->getOptionsObject()->getBool( "pix_use_manual_commit") ) { compiler->output << "access-list commit" << endl; compiler->output << endl; } compiler->output << "nat (" << i_iface->getLabel() << ") 0 access-list " << n0.acl_name << endl; } } break; } case NONAT_STATIC: { string addr = odst->getAddressPtr()->toString(); string mask; if (Network::isA(odst)) mask=odst->getNetmaskPtr()->toString(); else mask="255.255.255.255"; compiler->output << "static (" << o_iface->getLabel() << "," << i_iface->getLabel() << ") " << addr << " " << addr << " netmask " << mask << endl; } break; } } void NATCompiler_pix::PrintRule::printSNAT(NATRule *rule) { NATCompiler_pix *pix_comp = dynamic_cast(compiler); NATCmd *natcmd = pix_comp->nat_commands[ rule->getInt("nat_cmd") ]; string platform = compiler->fw->getStr("platform"); string version = compiler->fw->getStr("version"); string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_acl"); Address *osrc = compiler->getFirstOSrc(rule); assert(osrc); Address *odst = compiler->getFirstODst(rule); assert(odst); Service *osrv = compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc = compiler->getFirstTSrc(rule); assert(tsrc); Address *tdst = compiler->getFirstTDst(rule); assert(tdst); Service *tsrv = compiler->getFirstTSrv(rule); assert(tsrv); RuleElementItfInb *itf_in_re = rule->getItfInb(); assert(itf_in_re!=NULL); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); assert(itf_out_re!=NULL); Interface *i_iface = Interface::cast( FWObjectReference::getObject(itf_in_re->front())); Interface *o_iface = Interface::cast( FWObjectReference::getObject(itf_out_re->front())); if ( ! natcmd->ignore_global) { compiler->output << "global (" << o_iface->getLabel() << ") " << natcmd->nat_id; switch (natcmd->type) { case INTERFACE: compiler->output << " interface" << endl; break; case SINGLE_ADDRESS: compiler->output << " " << natcmd->t_addr->getAddressPtr()->toString() << endl; break; case NETWORK_ADDRESS: compiler->output << " " << natcmd->t_addr->getAddressPtr()->toString() << " netmask " << natcmd->t_addr->getNetmaskPtr()->toString() << endl; break; case ADDRESS_RANGE: { AddressRange *ar=AddressRange::cast(natcmd->t_addr); compiler->output << " " << ar->getRangeStart().toString() << "-" << ar->getRangeEnd().toString() << " netmask " << o_iface->getNetmaskPtr()->toString() << endl; } break; default: ; // TODO: should actually be always_assert } } if ( natcmd->ignore_nat) { compiler->output <<"! " << natcmd->comment << endl; } else { if (rule->getBool("use_nat_0_0") || libfwbuilder::XMLTools::version_compare(compiler->fw->getStr("version"),"6.3")<0) { /* old, < 6.3 */ compiler->output << "nat (" << i_iface->getLabel() << ") " << natcmd->nat_id << " " << natcmd->o_src->getAddressPtr()->toString() << " " << natcmd->o_src->getNetmaskPtr()->toString(); if (natcmd->outside) compiler->output << " outside"; else compiler->output << " " << _printConnOptions(rule); compiler->output << endl; } else { /* new, >=6.3 */ if (pix_comp->getACLFlag(natcmd->nat_acl_name)==0 && compiler->fw->getOptionsObject()->getBool("pix_acl_substitution")) { compiler->output << clearACLcmd << " " << natcmd->nat_acl_name << endl; pix_comp->setACLFlag(natcmd->nat_acl_name,1); } compiler->output << "access-list " << natcmd->nat_acl_name << " permit "; compiler->output << osrv->getProtocolName(); compiler->output << " "; compiler->output << _printAddress(osrc,true); compiler->output << " "; compiler->output << _printSrcService( osrv ); compiler->output << " "; compiler->output << _printAddress(odst,true); compiler->output << " "; compiler->output << _printDstService( osrv ); compiler->output << endl; if (!natcmd->ignore_nat_and_print_acl) { if (compiler->fw->getStr("platform")=="fwsm" && compiler->fw->getOptionsObject()->getBool("pix_use_manual_commit") ) { compiler->output << "access-list commit" << endl; compiler->output << endl; } compiler->output << "nat (" << i_iface->getLabel() << ") " << natcmd->nat_id << " access-list " << natcmd->nat_acl_name; if (natcmd->outside) compiler->output << " outside"; else compiler->output << " " << _printConnOptions(rule); compiler->output << endl; } } } } void NATCompiler_pix::PrintRule::printSDNAT(NATRule*) { } void NATCompiler_pix::PrintRule::printDNAT(NATRule *rule) { NATCompiler_pix *pix_comp = dynamic_cast(compiler); string platform = compiler->fw->getStr("platform"); string version = compiler->fw->getStr("version"); string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version+"/pix_commands/clear_acl"); Address *osrc = compiler->getFirstOSrc(rule); assert(osrc); Address *odst = compiler->getFirstODst(rule); assert(odst); Service *osrv = compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc = compiler->getFirstTSrc(rule); assert(tsrc); Address *tdst = compiler->getFirstTDst(rule); assert(tdst); Service *tsrv = compiler->getFirstTSrv(rule); assert(tsrv); RuleElementItfInb *itf_in_re = rule->getItfInb(); assert(itf_in_re!=NULL); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); assert(itf_out_re!=NULL); Interface *i_iface = Interface::cast( FWObjectReference::getObject(itf_in_re->front())); Interface *o_iface = Interface::cast( FWObjectReference::getObject(itf_out_re->front())); StaticCmd *scmd = pix_comp->static_commands[ rule->getInt("sc_cmd") ]; const InetAddr *outa = scmd->oaddr->getAddressPtr(); const InetAddr *outm = scmd->oaddr->getNetmaskPtr(); const InetAddr *insa = scmd->iaddr->getAddressPtr(); /* * we verify that odst and tdst have the same size in verifyRuleElements, * so we can rely on that now. */ if (libfwbuilder::XMLTools::version_compare(compiler->fw->getStr("version"),"6.3")<0) { /* old, < 6.3 */ compiler->output << "static (" << o_iface->getLabel() << "," << i_iface->getLabel() << ") " ; bool use_ports=false; if (TCPService::cast(osrv)) { use_ports=true; compiler->output << "tcp "; } if (UDPService::cast(osrv)) { use_ports=true; compiler->output << "udp "; } if (Interface::cast(scmd->oaddr)!=NULL) { compiler->output << "interface "; if (use_ports) _printPort(scmd->osrv); compiler->output << insa->toString() << " "; if (use_ports) _printPort(scmd->tsrv); } else { compiler->output << outa->toString() << " "; if (use_ports) _printPort(scmd->osrv); compiler->output << insa->toString() << " "; if (use_ports) _printPort(scmd->tsrv); compiler->output << " netmask " << outm->toString(); } compiler->output << " " << _printConnOptions(rule) << endl; } else { /* new, >=6.3 */ if (pix_comp->getACLFlag(scmd->acl_name)==0 && compiler->fw->getOptionsObject()->getBool("pix_acl_substitution")) { compiler->output << clearACLcmd << " " << scmd->acl_name << endl; pix_comp->setACLFlag(scmd->acl_name,1); } compiler->output << "access-list " << scmd->acl_name << " permit "; /* * This acl does not make any sense if treated as a regular access * list. I just follow example from * http://www.cisco.com/en/US/products/sw/secursw/ps2120/products_configuration_guide_chapter09186a0080172786.html#1113601 */ compiler->output << scmd->osrv->getProtocolName(); compiler->output << " "; compiler->output << _printAddress(scmd->iaddr,true); compiler->output << " "; compiler->output << _printDstService( scmd->tsrv ); compiler->output << " "; compiler->output << _printAddress(scmd->osrc,true); compiler->output << " "; compiler->output << _printSrcService( scmd->osrv ); compiler->output << endl; if (!scmd->ignore_scmd_and_print_acl) { if (compiler->fw->getStr("platform")=="fwsm" && compiler->fw->getOptionsObject()->getBool("pix_use_manual_commit")) { compiler->output << "access-list commit" << endl; compiler->output << endl; } compiler->output << "static (" << o_iface->getLabel() << "," << i_iface->getLabel() << ") " ; bool use_ports=false; if (TCPService::cast(scmd->osrv)) { use_ports=true; compiler->output << "tcp "; } if (UDPService::cast(scmd->osrv)) { use_ports=true; compiler->output << "udp "; } if (Interface::cast(scmd->oaddr)!=NULL) compiler->output << "interface "; else compiler->output << outa->toString() << " "; if (use_ports) _printPort(scmd->osrv); compiler->output << " "; compiler->output << "access-list " << scmd->acl_name << " " << _printConnOptions(rule) << endl; } } } bool NATCompiler_pix::PrintRule::processNext() { string platform = compiler->fw->getStr("platform"); string version = compiler->fw->getStr("version"); string clearACLcmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_acl"); NATRule *rule = getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); bool suppress_comments = ! compiler->fw->getOptionsObject()->getBool("pix_include_comments"); compiler->output << compiler->printComment( rule, current_rule_label, "!", suppress_comments); switch (rule->getRuleType()) { case NATRule::NONAT: printNONAT(rule); break; case NATRule::SNAT: { printSNAT(rule); break; } case NATRule::SDNAT: { printSDNAT(rule); break; } case NATRule::DNAT: { printDNAT(rule); break; } default: ; // TODO: should actually be always_assert } return true; } fwbuilder-5.1.0.3599/src/cisco_lib/AutomaticRules_cisco.cpp0000644000175000017500000000467711733011756024356 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AutomaticRules_cisco.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include using namespace fwcompiler; using namespace libfwbuilder; using namespace std; void AutomaticRules_cisco::addSshAccessRule() { if (ruleset == NULL) return; FWOptions *fwopt = fw->getOptionsObject(); if (fwopt->getBool("mgmt_ssh") && ! fwopt->getStr("mgmt_addr").empty()) { TCPService *ssh = ruleset->getRoot()->createTCPService(); ssh->setDstRangeStart(22); ssh->setDstRangeEnd(22); persistent_objects->add(ssh, false); TCPService *ssh_rev = ruleset->getRoot()->createTCPService(); ssh_rev->setSrcRangeStart(22); ssh_rev->setSrcRangeEnd(22); persistent_objects->add(ssh_rev, false); Network *mgmt_workstation = ruleset->getRoot()->createNetwork(); mgmt_workstation->setAddressNetmask(fwopt->getStr("mgmt_addr")); persistent_objects->add(mgmt_workstation, false); addMgmtRule( mgmt_workstation, fw, ssh, NULL, PolicyRule::Inbound, PolicyRule::Accept, "backup ssh access rule"); } } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_iosacl.h0000644000175000017500000000520411733011756024145 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_IOSACL_HH__ #define __COMPILER_DRIVER_IOSACL_HH__ #include "CompilerDriver.h" #include #include #include namespace libfwbuilder { class FWObjectDatabase; class Cluster; class ClusterGroup; class Firewall; class RuleSet; class Interface; }; namespace fwcompiler { class ciscoACL; class NamedObjectsManager; class CompilerDriver_iosacl : public CompilerDriver { protected: std::string system_configuration_script; std::string nat_script; std::string policy_script; std::string routing_script; std::string safety_net_install_option_name; std::string safety_net_install_acl_addr_option_name; std::string safetyNetInstall(libfwbuilder::Firewall *fw); void printProlog(QTextStream &file, const std::string &prolog_code); virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); virtual QString printActivationCommands(libfwbuilder::Firewall *fw); virtual QString assembleFwScript(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf); public: CompilerDriver_iosacl(libfwbuilder::FWObjectDatabase *db); // create a copy of itself, including objdb virtual CompilerDriver* clone(); virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_pix_os_inspectors_pix8.cpp0000644000175000017500000000724711733011756027737 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator_pix_os.h" #include "Helper.h" #include "inspectionProtocol.h" #include "inspectionClassMap.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* ******************************************************************** * * Generating policy-map type inspect commands for PIX 8.0 * * ********************************************************************/ string OSConfigurator_pix_os::_printPolicyMapTypeInspect() { ostringstream res; string platform = fw->getStr("platform"); string version = fw->getStr("version"); string vers = "version_" + version; FWOptions *options = fw->getOptionsObject(); assert(options!=NULL); // first, generate commands for ip-options QStringList allowed_fixups = QString(Resources::platform_res[platform]->getResourceStr( "/FWBuilderResources/Target/options/" + vers + "/fixups/list").c_str()).split(","); list ip_options_matches; foreach (QString fixup_xml_element, allowed_fixups) { string f = options->getStr(fixup_xml_element.toAscii().constData()); if (!f.empty()) { QString fixup_name = fixup_xml_element.replace("_fixup", ""); int status; int p1,p2; string an; int av; istringstream str(f); str >> status >> p1 >> p2 >> an >> av; if (fixup_name.startsWith("ip_options") && status != FIXUP_SKIP) { InspectionClassMap cm(fixup_name.toAscii().constData(), status, p1, p2, an, av); ip_options_matches.push_back(cm); } } } if (ip_options_matches.size() > 0) { res << "policy-map type inspect ip-options ip-options-map" << endl; res << "parameters" << endl; for(list::iterator i=ip_options_matches.begin(); i!=ip_options_matches.end(); ++i) { switch (i->status) { case FIXUP_ENABLE: res << " " << i->getPrintableName() << " action "; res << "allow" << endl; break; case FIXUP_CLEAR: res << " " << i->getPrintableName() << " action "; res << "clear" << endl; break; default: break; } } } res << endl; return res.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_pix_writers.cpp0000644000175000017500000000755011733011756026007 0ustar sylvestresylvestre/* * Copyright (c) 2008 Steven Mestdagh * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "RoutingCompiler_pix.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Network.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /** *----------------------------------------------------------------------- * Methods for printing */ RoutingCompiler_pix::PrintRule::PrintRule(const std::string &name) : RoutingCompiler_cisco::PrintRule(name) { } bool RoutingCompiler_pix::PrintRule::processNext() { RoutingRule *rule = getNext(); if (rule == NULL) return false; tmp_queue.push_back(rule); string rl = rule->getLabel(); string comm = rule->getComment(); string::size_type c1, c2; c1 = 0; if (!compiler->inSingleRuleCompileMode() && rl != current_rule_label) { compiler->output << "! " << endl; compiler->output << "! Rule " << rl << endl; compiler->output << "! " << endl; compiler->output << "! \"Routing rule " << rl << "\"" << endl; compiler->output << "! " << endl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) compiler->output << "# " << err << endl; if( rule->getRuleType() != RoutingRule::MultiPath ) { if (!compiler->inSingleRuleCompileMode() && rl != current_rule_label) { while ( (c2 = comm.find('\n',c1)) != string::npos ) { compiler->output << "! " << comm.substr(c1,c2-c1) << endl; c1 = c2 + 1; } compiler->output << "! " << comm.substr(c1) << endl; compiler->output << "! " << endl; string err = compiler->getErrorsForRule(rule, "! "); if (!err.empty()) compiler->output << err << endl; current_rule_label = rl; } string command_line = RoutingRuleToString(rule); compiler->output << command_line; } else { string err = compiler->getErrorsForRule(rule, "! "); if (!err.empty()) compiler->output << err << endl; compiler->abort(rule, "MultiPath routing not supported by platform"); } return true; } string RoutingCompiler_pix::PrintRule::RoutingRuleToString(RoutingRule *rule) { FWObject *ref; RuleElementRDst *dstrel = rule->getRDst(); ref = dstrel->front(); Address *dst = Address::cast(FWReference::cast(ref)->getPointer()); if(dst == NULL) compiler->abort(rule, "Broken DST"); std::ostringstream command_line; command_line << "route "; command_line << _printRItf(rule); command_line << _printRDst(rule); command_line << _printRGtw(rule); // default metric in PIX is 1 if (rule->getMetricAsString() == "0") { command_line << "1"; } else { command_line << rule->getMetricAsString(); } command_line << endl; return command_line.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_cisco.cpp0000644000175000017500000000554411733011756024531 0ustar sylvestresylvestre/* * Copyright (c) 2008 Steven Mestdagh * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "RoutingCompiler_cisco.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Network.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; int RoutingCompiler_cisco::prolog() { return RoutingCompiler::prolog(); } /* * this processor eliminates duplicate atomic routing rules in one * routing table */ bool RoutingCompiler_cisco::eliminateDuplicateRules::processNext() { RoutingCompiler_cisco *cisco_comp = dynamic_cast(compiler); RoutingRule *rule = getNext(); if (rule == NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } string label = rule->getLabel(); int bracepos = label.find("("); label.erase(0, bracepos); string thisRule = label + " " + cisco_comp->printRule->RoutingRuleToString(rule); rules_it = rules_seen_so_far.find(thisRule); if (rules_it != rules_seen_so_far.end()) { string msg; msg = "Two of the sub rules created from the gui routing rules " + rules_it->second + " and " + rule->getLabel() + " are identical, skipping the second. " + "Revise them to avoid this warning"; compiler->warning(rule, msg.c_str() ); return true; } tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = rule->getLabel(); return true; } void RoutingCompiler_cisco::compile() { printRule = new RoutingCompiler_cisco::PrintRule(""); } string RoutingCompiler_cisco::debugPrintRule(Rule *r) { RoutingRule *rule = RoutingRule::cast(r); string s = RoutingCompiler::debugPrintRule(rule); return s; } void RoutingCompiler_cisco::setNamedObjectsManager(NamedObjectsManager *mgr) { named_objects_manager = mgr; } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_iosacl.cpp0000644000175000017500000004253611733011756024515 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_iosacl.h" #include "NamedObjectsAndGroupsSupport.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Management.h" #include "fwbuilder/Network.h" #include "fwbuilder/ObjectMirror.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_iosacl::myPlatformName() { return "iosacl"; } PolicyCompiler_iosacl::PolicyCompiler_iosacl(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf) : PolicyCompiler_cisco(_db, fw, ipv6_policy, _oscnf) { resetinbound = false; fragguard = false; comment_symbol = "!"; } int PolicyCompiler_iosacl::prolog() { string version = fw->getStr("version"); string platform = fw->getStr("platform"); string host_os = fw->getStr("host_OS"); if (platform!="iosacl") abort("Unsupported platform " + platform ); fw->getOptionsObject()->setBool( "use_acl_remarks", fw->getOptionsObject()->getBool("iosacl_use_acl_remarks")); // object_groups = new Group(); // persistent_objects->add( object_groups ); setAllNetworkZonesToNone(); return PolicyCompiler::prolog(); } bool PolicyCompiler_iosacl::checkForDynamicInterface::findDynamicInterface( PolicyRule *rule, RuleElement *rel) { string vers=compiler->fw->getStr("version"); for (list::iterator i1=rel->begin(); i1!=rel->end(); ++i1) { FWObject *o = *i1; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Interface *iface=Interface::cast(obj); if (iface!=NULL && iface->isDyn()) compiler->abort( rule, "Dynamic interface can not be used in the IOS ACL rules."); } return true; } bool PolicyCompiler_iosacl::checkForDynamicInterface::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; findDynamicInterface(rule,rule->getSrc()); findDynamicInterface(rule,rule->getDst()); tmp_queue.push_back(rule); return true; } /* * Copy all references from rule element re1 to rule element re2. */ void PolicyCompiler_iosacl::mirrorRule::duplicateRuleElement( RuleElement *re1, RuleElement *re2) { re2->clearChildren(); for (list::iterator i1=re1->begin(); i1!=re1->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); re2->addRef(obj); } } bool PolicyCompiler_iosacl::mirrorRule::processNext() { //PolicyCompiler_iosacl *iosacl_comp=dynamic_cast(compiler); PolicyRule *rule = getNext(); if (rule==NULL) return false; if (rule->getOptionsObject()->getBool("iosacl_add_mirror_rule")) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(rule->getAction()); switch (rule->getDirection()) { case PolicyRule::Inbound: r->setDirection(PolicyRule::Outbound); break; case PolicyRule::Outbound: r->setDirection(PolicyRule::Inbound); break; default: r->setDirection(PolicyRule::Both); break; } RuleElementSrc *osrc = rule->getSrc(); RuleElementDst *odst = rule->getDst(); RuleElementSrv *osrv = rule->getSrv(); RuleElementItf *oitf = rule->getItf(); RuleElementSrc *nsrc = r->getSrc(); RuleElementDst *ndst = r->getDst(); RuleElementSrv *nsrv = r->getSrv(); RuleElementItf *nitf = r->getItf(); duplicateRuleElement(osrc, ndst); duplicateRuleElement(odst, nsrc); duplicateRuleElement(oitf, nitf); if (!osrv->isAny()) { ObjectMirror mirror; nsrv->clearChildren(); for (list::iterator i1=osrv->begin(); i1!=osrv->end(); ++i1) { Service *nobj = mirror.getMirroredService( Service::cast(FWReference::getObject(*i1))); if (nobj->getParent() == NULL) compiler->persistent_objects->add(nobj, false); nsrv->addRef(nobj); } } tmp_queue.push_back(r); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_iosacl::SpecialServices::processNext() { //PolicyCompiler_iosacl *iosacl_comp=dynamic_cast(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; Service *s = compiler->getFirstSrv(rule); if (IPService::cast(s)!=NULL) { if (s->getBool("rr") || s->getBool("ssrr") || s->getBool("ts") ) compiler->abort( rule, "IOS ACL does not support checking for IP options in ACLs."); } if (TCPService::cast(s)!=NULL && TCPService::cast(s)->inspectFlags()) { string version = compiler->fw->getStr("version"); if (XMLTools::version_compare(version, "12.4")<0) compiler->abort(rule, "TCP flags match requires IOS v12.4 or later."); } tmp_queue.push_back(rule); return true; } /* * This rule processor is used to separate TCP service objects that * match tcp flags when generated config uses object-group clause */ bool PolicyCompiler_iosacl::splitTCPServiceWithFlags::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv = rule->getSrv(); if (srv->size() > 1) { std::list cl; for (list::iterator i1=srv->begin(); i1!=srv->end(); ++i1) { FWObject *o = *i1; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Service *s=Service::cast(obj); assert(s!=NULL); TCPService *tcp_srv = TCPService::cast(s); if (tcp_srv && (tcp_srv->inspectFlags() || tcp_srv->getEstablished())) cl.push_back(s); } while (!cl.empty()) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv = r->getSrv(); nsrv->clearChildren(); nsrv->addRef( cl.front() ); tmp_queue.push_back(r); srv->removeRef( cl.front() ); cl.pop_front(); } if (srv->size()>0) tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); return true; } void PolicyCompiler_iosacl::compile() { string banner = " Compiling ruleset " + getSourceRuleSet()->getName(); if (ipv6) banner += ", IPv6"; info(banner); string version = fw->getStr("version"); bool supports_object_groups = XMLTools::version_compare(version, "12.4")>=0 && fw->getOptionsObject()->getBool("iosacl_use_object_groups") && ! ipv6; string vers = fw->getStr("version"); string platform = fw->getStr("platform"); Compiler::compile(); if ( fw->getOptionsObject()->getBool ("check_shading") && ! inSingleRuleCompileMode()) { add( new Begin("Detecting rule shadowing" ) ); add( new printTotalNumberOfRules()); add( new ItfNegation("process negation in Itf" ) ); add( new InterfacePolicyRules( "process interface policy rules and store interface ids")); add( new recursiveGroupsInSrc("check for recursive groups in SRC")); add( new recursiveGroupsInDst("check for recursive groups in DST")); add( new recursiveGroupsInSrv("check for recursive groups in SRV")); add( new ExpandGroups("expand groups")); add( new dropRuleWithEmptyRE( "drop rules with empty rule elements")); add( new eliminateDuplicatesInSRC("eliminate duplicates in SRC")); add( new eliminateDuplicatesInDST("eliminate duplicates in DST")); add( new eliminateDuplicatesInSRV("eliminate duplicates in SRV")); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC" ) ); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST" ) ); add( new dropRuleWithEmptyRE( "drop rules with empty rule elements")); add( new mirrorRule("Add mirrored rules")); add( new ConvertToAtomic("convert to atomic rules" ) ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); add( new DetectShadowing("Detect shadowing" ) ); add( new simplePrintProgress() ); runRuleProcessors(); deleteRuleProcessors(); } add( new Begin (" Start processing rules" ) ); add( new printTotalNumberOfRules ( ) ); add( new singleRuleFilter()); add( new recursiveGroupsInSrc( "check for recursive groups in SRC" ) ); add( new recursiveGroupsInDst( "check for recursive groups in DST" ) ); add( new recursiveGroupsInSrv( "check for recursive groups in SRV" ) ); add( new emptyGroupsInSrc( "check for empty groups in SRC" ) ); add( new emptyGroupsInDst( "check for empty groups in DST" ) ); add( new emptyGroupsInSrv( "check for empty groups in SRV" ) ); add( new ExpandGroups ("expand groups" ) ); add( new dropRuleWithEmptyRE( "drop rules with empty rule elements")); add( new eliminateDuplicatesInSRC( "eliminate duplicates in SRC" ) ); add( new eliminateDuplicatesInDST( "eliminate duplicates in DST" ) ); add( new eliminateDuplicatesInSRV( "eliminate duplicates in SRV" ) ); add( new processMultiAddressObjectsInSrc( "process MultiAddress objects in Src") ); add( new processMultiAddressObjectsInDst( "process MultiAddress objects in Dst") ); add( new expandGroupsInItf("expand groups in Interface" )); add( new replaceClusterInterfaceInItf( "replace cluster interfaces with member interfaces in the Interface rule element")); add( new ItfNegation( "process negation in Itf" ) ); add( new InterfacePolicyRules( "process interface policy rules and store interface ids") ); add( new groupServicesByProtocol ("split rules with different protocols" ) ); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC" ) ); add( new MACFiltering ("check for MAC address filtering" ) ); // add( new splitByNetworkZonesForSrc ("split rule if objects in Src belong to different network zones " ) ); // add( new replaceFWinDSTPolicy ("replace fw with its interface in DST in global policy rules") ); add( new ExpandMultipleAddressesInDst( "expand objects with multiple addresses in DST" ) ); add( new MACFiltering( "check for MAC address filtering" ) ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); // add( new splitByNetworkZonesForDst ("split rule if objects in Dst belong to different network zones " ) ); if (ipv6) add( new DropIPv4Rules("drop ipv4 rules")); else add( new DropIPv6Rules("drop ipv6 rules")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new checkForUnnumbered("check for unnumbered interfaces")); if ( ! supports_object_groups) add( new addressRanges("process address ranges")); add( new mirrorRule("Add mirrored rules")); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new setInterfaceAndDirectionBySrc( "Set interface and direction for rules with interface 'all' using SRC")); add( new setInterfaceAndDirectionByDst( "Set interface and direction for rules with interface 'all' using DST")); add( new setInterfaceAndDirectionIfInterfaceSet( "Set direction for rules with interface not 'all'")); add( new specialCaseWithDynInterface( "check for a special cases with dynamic interface" ) ); // first arg is true because we use "ip access-list" for IOS. add( new pickACL( true, "assign ACLs" ) ); add( new SpecialServices( "check for special services" ) ); add( new CheckForUnsupportedUserService("check for user service") ); add( new checkForZeroAddr( "check for zero addresses" ) ); add( new checkForDynamicInterface("check for dynamic interfaces" ) ); /* remove redundant objects only after all splits has been * done, right before object groups are created */ add( new removeRedundantAddressesFromSrc( "remove redundant addresses from Src") ); add( new removeRedundantAddressesFromDst( "remove redundant addresses from Dst") ); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); if (supports_object_groups) { // "object-group service" does not seem to support // matching of tcp flags and "established". Need to // separate objects using these into separate rules to avoid // object-group add( new splitTCPServiceWithFlags( "separate TCP service with tcp flags")); add( new CreateObjectGroupsForSrc("create object groups for Src", named_objects_manager)); add( new CreateObjectGroupsForDst("create object groups for Dst", named_objects_manager)); add( new CreateObjectGroupsForSrv("create object groups for Srv", named_objects_manager)); } else { add( new ConvertToAtomic ("convert to atomic rules" ) ); } add( new simplePrintProgress()); add( new createNewCompilerPass("Creating object groups and ACLs")); // This processor prints each ACL separately in one block. // It adds comments inside to denote original rules. // add( new PrintCompleteACLs("Print ACLs")); add( new simplePrintProgress()); runRuleProcessors(); } string PolicyCompiler_iosacl::printAccessGroupCmd(ciscoACL *acl, bool neg) { ostringstream str; string addr_family_prefix = "ip"; if (ipv6) addr_family_prefix = "ipv6"; if (getSourceRuleSet()->isTop()) { string dir; if (acl->direction()=="in" || acl->direction()=="Inbound") dir="in"; if (acl->direction()=="out" || acl->direction()=="Outbound") dir="out"; str << "interface " << acl->getInterface()->getName() << endl; if (neg) str << " no"; str << " " << addr_family_prefix << " "; str << getAccessGroupCommandForAddressFamily(ipv6); str << " " << acl->workName() << " " << dir << endl; str << "exit" << endl; } return str.str(); } void PolicyCompiler_iosacl::epilog() { output << endl; for (map::iterator i=acls.begin(); i!=acls.end(); ++i) { ciscoACL *acl=(*i).second; if (acl->size()!=0) output << printAccessGroupCmd(acl, false); } output << endl; if ( fw->getOptionsObject()->getBool("iosacl_regroup_commands") ) { info(" Regrouping commands"); regroup(); } } string PolicyCompiler_iosacl::getAccessGroupCommandForAddressFamily(bool ipv6) { if (ipv6) return "traffic-filter"; return "access-group"; } string PolicyCompiler_iosacl::printClearCommands() { ostringstream output; string version = fw->getStr("version"); string platform = fw->getStr("platform"); string xml_element = "clear_ip_acl"; if (ipv6) xml_element = "clear_ipv6_acl"; string clearACLCmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/iosacl_commands/" + xml_element); assert( !clearACLCmd.empty()); // No need to output "clear" commands in single rule compile mode if ( fw->getOptionsObject()->getBool("iosacl_acl_basic") || fw->getOptionsObject()->getBool("iosacl_acl_substitution")) { for (map::iterator i=acls.begin(); i!=acls.end(); ++i) { ciscoACL *acl = (*i).second; output << clearACLCmd << " " << acl->workName() << endl; } } return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_procurve_acl.cpp0000644000175000017500000000374411733011756025721 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include "CompilerDriver_procurve_acl.h" #include "PolicyCompiler_procurve_acl.h" #include "fwbuilder/Resources.h" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver_procurve_acl::CompilerDriver_procurve_acl(FWObjectDatabase *db) : CompilerDriver_iosacl(db) { safety_net_install_option_name = "procurve_acl_acl_substitution"; safety_net_install_acl_addr_option_name = "procurve_acl_acl_temp_addr"; } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_procurve_acl::clone() { CompilerDriver_procurve_acl* new_cd = new CompilerDriver_procurve_acl(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } void CompilerDriver_procurve_acl::printProlog(QTextStream &file, const string &prolog_code) { file << endl; file << ";" << endl; file << "; Prolog script" << endl; file << ";" << endl; file << prolog_code << endl; file << ";" << endl; file << "; End of prolog script" << endl; file << ";" << endl; } fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_pix.cpp0000644000175000017500000012733611733011756023230 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_pix.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string NATCompiler_pix::myPlatformName() { return "pix"; } string _print_addr(const InetAddr* addr) { if (addr) return addr->toString(); return "NULL"; } NATCompiler_pix::NATCompiler_pix(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf) : NATCompiler(_db, fw, ipv6_policy, _oscnf) , helper(this) { } NATCompiler_pix::~NATCompiler_pix() { std::map::iterator it1; for (it1=nat_commands.begin(); it1!=nat_commands.end(); ++it1) { delete it1->second; } nat_commands.clear(); std::map::iterator it2; for (it2=static_commands.begin(); it2!=static_commands.end(); ++it2) { delete it2->second; } static_commands.clear(); nonat_rules.clear(); first_nonat_rule_id.clear(); } bool StaticCmd::operator==(const StaticCmd &other) { return (*oaddr == *(other.oaddr) && *iaddr == *(other.iaddr) && *osrv == *(other.osrv) && *tsrv == *(other.tsrv) && i_iface->getId() == other.i_iface->getId() && o_iface->getId() == other.o_iface->getId()); } /* * Do not expand interfaces in ODst and TSrc * */ void NATCompiler_pix::_expand_addr_recursive_pix(Rule *rule, FWObject *re, FWObject *s, list &ol, bool expand_cluster_interfaces_fully) { bool odst_or_tsrc = (re->getTypeName() == RuleElementODst::TYPENAME || re->getTypeName() == RuleElementTSrc::TYPENAME); list addrlist; for (FWObject::iterator i1=s->begin(); i1!=s->end(); ++i1) { FWObject *o = FWReference::getObject(*i1); assert(o); Address *addr = Address::cast(o); // this condition includes Host, Firewall and Interface if (addr && !addr->hasInetAddress()) { addrlist.push_back(o); continue; } // IPv4, IPv6, Network, NetworkIPv6 if (addr && addr->hasInetAddress() && MatchesAddressFamily(o)) { addrlist.push_back(o); continue; } if (o->getId() == FWObjectDatabase::ANY_ADDRESS_ID || MultiAddress::cast(o)!=NULL || Interface::cast(o) || physAddress::cast(o)) { addrlist.push_back(o); continue; } } if (addrlist.empty()) { if (RuleElement::cast(s)==NULL) ol.push_back(s); } else { for (list::iterator i2=addrlist.begin(); i2!=addrlist.end(); ++i2) { Interface *i2itf = Interface::cast(*i2); if (i2itf) { // if this is ODst or TSrc, just use interface if (odst_or_tsrc) { ol.push_back(i2itf); continue; } _expand_interface(rule, i2itf, ol, expand_cluster_interfaces_fully); continue; } _expand_addr_recursive_pix(rule, re, *i2, ol, expand_cluster_interfaces_fully); } } } void NATCompiler_pix::_expand_addr_recursive(Rule *rule, FWObject *re, list &ol, bool expand_cluster_interfaces_fully) { _expand_addr_recursive_pix(rule, re, re, ol, expand_cluster_interfaces_fully); } void NATCompiler_pix::_expand_interface(Rule *rule, Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully) { Compiler::_expand_interface(rule, iface, ol, expand_cluster_interfaces_fully); } string NATCompiler_pix::getNATACLname(Rule *rule,int nat_id) { int n=-1; string res; do { n++; ostringstream os; os << rule->getUniqueId() << "." << nat_id << "." << n; res=os.str(); } while (nat_acl_names.count(res)!=0); return res; } string NATCompiler_pix::getNATACLname(Rule *rule,string suffix) { int n=-1; string res; do { n++; ostringstream os; os << rule->getUniqueId(); if (!suffix.empty()) os << "." << suffix; os << "." << n; res=os.str(); } while (nat_acl_names.count(res)!=0); return res; } int NATCompiler_pix::prolog() { global_pool_no = 1; NAT *final_ruleset = new NAT(); final_ruleset->setName("Final NAT Rule Set"); persistent_objects->add( final_ruleset ); final_ruleset_id = final_ruleset->getId(); return NATCompiler::prolog(); } string NATCompiler_pix::debugPrintRule(Rule *r) { NATRule *rule=NATRule::cast(r); RuleElementItfInb *itf_in_re = rule->getItfInb(); assert(itf_in_re!=NULL); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); assert(itf_out_re!=NULL); ostringstream os; switch (rule->getRuleType()) { case NATRule::NONAT: os << "NONAT Type: " << rule->getInt("nonat_type"); break; case NATRule::SNAT: { if ( ! rule->exists("nat_cmd") ) break; NATCmd *natcmd = nat_commands[ rule->getInt("nat_cmd") ]; if (natcmd != NULL) { os <<" NATCmd: "; os << " rule=[" << natcmd->rule_label << "]"; os << " id=" << natcmd->nat_id; os << " rule=" << natcmd->rule_label; os << " nat_acl_name=" << natcmd->nat_acl_name; os << " (" << nat_acl_names[natcmd->nat_acl_name] << ")"; os << " o_src=" << _print_addr(natcmd->o_src->getAddressPtr()); os << " o_dst=" << _print_addr(natcmd->o_dst->getAddressPtr()); os << " o_srv=" << natcmd->o_srv->getName(); os << " t_addr=" << _print_addr(natcmd->t_addr->getAddressPtr()); os << " ignore_global=" << string((natcmd->ignore_global)?"1":"0"); os << " ignore_nat=" << string((natcmd->ignore_nat)?"1":"0"); os << " ignore_nat_and_print_acl=" << string((natcmd->ignore_nat_and_print_acl)?"1":"0"); os << " use_nat_0_0=" << string((rule->getBool("use_nat_0_0"))?"1":"0"); } } break; case NATRule::DNAT: { if ( ! rule->exists("sc_cmd") ) break; StaticCmd *scmd=static_commands[ rule->getInt("sc_cmd") ]; if (scmd!=NULL) { string iaddr_str = _print_addr(scmd->iaddr->getAddressPtr()); string oaddr_str = _print_addr(scmd->oaddr->getAddressPtr()); os << " StaticCmd:"; os << " ignore=" << scmd->ignore_scmd_and_print_acl; os << " acl=" << scmd->acl_name; os << " (" << nat_acl_names[scmd->acl_name] << ")"; os << " iaddr=" << iaddr_str; os << " oaddr=" << oaddr_str; os << " osrc=" << _print_addr(scmd->osrc->getAddressPtr()); os << " osrv=" << scmd->osrv->getName(); os << " tsrv=" << scmd->tsrv->getName(); } } break; default: ; // TODO: should actually be always_assert } return NATCompiler::debugPrintRule(rule) + " " + " (type=" + rule->getRuleTypeAsString() + ") " + "use_nat_0_0=" + string((rule->getBool("use_nat_0_0"))?"1":"0") + " " + os.str(); } /* * store final nat rules in final rule set object in * persistent_obejcts. Note that we can't add the same rules since an * object can not be placed in two different places in the tree, so we * have to add copies. */ bool NATCompiler_pix::storeProcessedRules::processNext() { NATCompiler_pix *pix_comp = dynamic_cast(compiler); FWObject *final_ruleset = compiler->persistent_objects->getRoot()->findInIndex( pix_comp->final_ruleset_id); slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { NATRule *rule = NATRule::cast( *k ); NATRule *r = compiler->dbcopy->createNATRule(); final_ruleset->add(r); r->duplicate(rule); } return true; } bool NATCompiler_pix::VerifyRules::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; string version = compiler->fw->getStr("version"); if (rule->getRuleType()==NATRule::SDNAT) { compiler->abort( rule, "Rules that translate both source and destination are not supported."); return true; } bool version_lt_63= ( compiler->fw->getStr("platform")=="pix" && libfwbuilder::XMLTools::version_compare(version, "6.3")<0); // fwsm is always above 6.3 - its OS is based on 6.3 RuleElementOSrc *osrc=rule->getOSrc(); assert(osrc); RuleElementODst *odst=rule->getODst(); assert(odst); RuleElementOSrv *osrv=rule->getOSrv(); assert(osrv); RuleElementTSrc *tsrc=rule->getTSrc(); assert(tsrc); RuleElementTDst *tdst=rule->getTDst(); assert(tdst); RuleElementTSrv *tsrv=rule->getTSrv(); assert(tsrv); if (rule->getRuleType()==NATRule::LB) { compiler->abort( rule, "Load balancing rules are not supported."); return true; } if (rule->getRuleType()==NATRule::NONAT && (!osrv->isAny() || !tsrv->isAny())) { compiler->abort( rule, "'no nat' rules should have no services"); return true; } if (osrc->getNeg() || odst->getNeg() || osrv->getNeg() || tsrc->getNeg() || tdst->getNeg() || tsrv->getNeg()) { compiler->abort( rule, "Negation is not supported in NAT rules."); return true; } if (rule->getRuleType()==NATRule::SNAT) { // if ( tsrc->size()!=1) // compiler->abort("There should be no more than one object in translated source in the rule "+rule->getLabel()); if ( ! odst->isAny() && version_lt_63) // can do on fwsm { compiler->warning( rule, "Original destination is ignored in 'nat' NAT rules " "when compiling for PIX v6.2 and earlier."); odst->clearChildren(); odst->setAnyElement(); } } if (rule->getRuleType()==NATRule::DNAT) { if ( odst->size()!=1 && version_lt_63) { compiler->abort( rule, "There should be no more than one object in original destination"); return true; } if ( ! osrc->isAny() && version_lt_63) compiler->warning( rule, "Original source is ignored in 'static' NAT rules " "when compiling for PIX v6.2 and earlier."); } if (osrv->size()!=1 && !tsrv->isAny()) { compiler->abort( rule, "Can not translate multiple services into one service in one rule. "); return true; } if (tsrv->size()!=1) { compiler->abort( rule, "Translated service should be 'Original' or should contain single object."); return true; } if ( Group::cast( compiler->getFirstTSrv(rule) )!=NULL) { compiler->abort( rule, "Can not use group in translated service."); return true; } if (rule->getRuleType()==NATRule::SNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstOSrc(rule)); Network *a2=Network::cast(compiler->getFirstTSrc(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated source should both be networks of the same size"); return true; } } if (rule->getRuleType()==NATRule::DNetnat && !tsrc->isAny() ) { Network *a1=Network::cast(compiler->getFirstODst(rule)); Network *a2=Network::cast(compiler->getFirstTDst(rule)); if ( a1==NULL || a2==NULL || a1->getNetmaskPtr()->getLength()!=a2->getNetmaskPtr()->getLength() ) { compiler->abort( rule, "Original and translated destination should both be networks of the same size."); return true; } } if (rule->getRuleType()==NATRule::SNetnat) rule->setRuleType(NATRule::SNAT); if (rule->getRuleType()==NATRule::DNetnat) rule->setRuleType(NATRule::DNAT); tmp_queue.push_back(rule); return true; } bool NATCompiler_pix::AssignInterface::processNext() { Helper helper(compiler); NATRule *rule = getNext(); if (rule==NULL) return false; RuleElement *itf_re; Address *a1 = NULL; Address *a2 = NULL; if (rule->getRuleType()==NATRule::SNAT || rule->getRuleType()==NATRule::SDNAT) { a1 = compiler->getFirstOSrc(rule); a2 = compiler->getFirstTSrc(rule); } if (rule->getRuleType()==NATRule::DNAT) { a1 = compiler->getFirstODst(rule); a2 = compiler->getFirstTDst(rule); } if (rule->getRuleType()==NATRule::NONAT) { a1 = compiler->getFirstOSrc(rule); a2 = compiler->getFirstODst(rule); } assert(a1!=NULL && a2!=NULL); int org_intf_id = helper.findInterfaceByNetzone(a1); int trn_intf_id = helper.findInterfaceByNetzone(a2); FWObject *iface_org = compiler->dbcopy->findInIndex(org_intf_id); FWObject *iface_trn = compiler->dbcopy->findInIndex(trn_intf_id); if ( org_intf_id==-1 ) { QString err("Object '%1' does not belong to any known network zone."); compiler->abort(rule, err.arg(a1->getName().c_str()).toStdString()); return true; } if ( trn_intf_id==-1 ) { QString err("Object '%1' does not belong to any known network zone."); compiler->abort(rule, err.arg(a2->getName().c_str()).toStdString()); return true; } itf_re = rule->getItfInb(); assert(itf_re!=NULL); if (itf_re->isAny() && ! itf_re->hasRef(iface_org)) itf_re->addRef(iface_org); itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if (itf_re->isAny() && ! itf_re->hasRef(iface_trn)) itf_re->addRef(iface_trn); if (org_intf_id == trn_intf_id) { QString err("Objects used in Original Source and Translated Source " "of the rule dictate that the same interface '%1' is going " "to be used as real and mapped interface in the generated " "nat command."); compiler->warning( rule, err.arg( Interface::cast(iface_org)->getLabel().c_str()).toStdString()); } tmp_queue.push_back(rule); return true; } bool NATCompiler_pix::verifyInterfaces::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); return true; } bool NATCompiler_pix::verifyRuleElements::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; Address *osrc=compiler->getFirstOSrc(rule); assert(osrc); Address *odst=compiler->getFirstODst(rule); assert(odst); Service *osrv=compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc=compiler->getFirstTSrc(rule); assert(tsrc); Address *tdst=compiler->getFirstTDst(rule); assert(tdst); Service *tsrv=compiler->getFirstTSrv(rule); assert(tsrv); string version = compiler->fw->getStr("version"); if (rule->getRuleType()==NATRule::SNAT) { if ((! osrv->isAny() || ! tsrv->isAny()) && libfwbuilder::XMLTools::version_compare(version, "6.3")<0) { compiler->abort( rule, "only PIX v6.3 and later recognizes services in global NAT."); return true; } } if (rule->getRuleType()==NATRule::DNAT) { if ((AddressRange::cast(odst) || AddressRange::cast(tdst)) && libfwbuilder::XMLTools::version_compare(version, "8.3")<0) { compiler->abort( rule, "Address ranges are not supported in original destination or " "translated destination "); return true; } if (Network::isA(odst) && Network::isA(tdst)) { InetAddr n1 = (Interface::cast(odst)) ? InetAddr(InetAddr::getAllOnes()) : (*(odst->getNetmaskPtr())); InetAddr n2 = (Interface::cast(tdst)) ? InetAddr(InetAddr::getAllOnes()) : (*(tdst->getNetmaskPtr())); if ( !(n1==n2) ) { compiler->abort( rule, "Original and translated destination must be of the same " "size"); return true; } } if (osrv->getTypeName()!=tsrv->getTypeName()) { compiler->abort( rule, "Original and translated services must be of " "the same type."); return true; } if (ICMPService::isA(osrv)) { compiler->abort( rule, "ICMP services are not supported in static NAT. "); return true; } if (TCPService::isA(osrv) || UDPService::isA(osrv)) { int drs=TCPUDPService::cast(osrv)->getDstRangeStart(); int dre=TCPUDPService::cast(osrv)->getDstRangeEnd(); if (drs!=dre) { compiler->abort( rule, "TCP or UDP service with a port range is not " "supported in NAT."); return true; } } if (TCPService::isA(tsrv) || UDPService::isA(tsrv)) { int drs=TCPUDPService::cast(tsrv)->getDstRangeStart(); int dre=TCPUDPService::cast(tsrv)->getDstRangeEnd(); if (drs!=dre) { compiler->abort( rule, "TCP or UDP service with a port range is not " "supported in NAT."); return true; } } } tmp_queue.push_back(rule); return true; } bool NATCompiler_pix::fillTranslatedSrv::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); Service *osrv_o=compiler->getFirstOSrv(rule); Service *tsrv_o=compiler->getFirstTSrv(rule); if ( ! osrv_o->isAny() && tsrv_o->isAny() ) { RuleElementTSrv *tsrv=rule->getTSrv(); tsrv->addRef(osrv_o); } return true; } /** * unlike standard inspector addressRanges in the base class NATCompiler, * this one does not expand address ranges in TSrc and TDst */ bool NATCompiler_pix::ExpandAddressRanges::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *rel; rel=rule->getOSrc(); assert(rel); compiler->_expandAddressRanges(rule,rel); rel=rule->getODst(); assert(rel); compiler->_expandAddressRanges(rule,rel); #if 0 // if we want to support NAT rules with address ranges. For example, // could compile these as a bunch of individual host translations switch (rule->getRuleType()) { case NATRule::SNAT: rel=rule->getTSrc(); assert(rel); compiler->_expandAddressRanges(rule,rel); break; case NATRule::DNAT: rel=rule->getTDst(); assert(rel); compiler->_expandAddressRanges(rule,rel); break; } #endif return true; } /* * I assume that there is always only one object in ODst, TSrc and TDst * rule elements. This should have been assured by inspector VerifyRules */ bool NATCompiler_pix::ReplaceFirewallObjectsODst::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); list cl; RuleElementODst *rel; Address *obj=NULL; switch (rule->getRuleType()) { case NATRule::Masq: // case NATRule::Redirect: return true; case NATRule::DNAT: rel=rule->getODst(); assert(rel); obj=compiler->getFirstODst(rule); assert(obj!=NULL); if (obj->getId()==compiler->getFwId() ) { list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (! iface->isLoopback() && iface->getSecurityLevel()==0 ) cl.push_back(iface); } if ( ! cl.empty() ) { // while (rel->size()) // rel->remove( rel->front() ); rel->clearChildren(); for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) { rel->addRef( *i1 ); } } } default: ; // TODO: should actually be always_assert } return true; } bool NATCompiler_pix::ReplaceFirewallObjectsTSrc::processNext() { Helper helper(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; list cl; RuleElementTSrc *rel; Address *obj=NULL; switch (rule->getRuleType()) { case NATRule::Masq: case NATRule::Redirect: { tmp_queue.push_back(rule); return true; } case NATRule::SNAT: { int osrc_level=100; Address *osrc=NULL; Interface *osrc_iface=NULL; if ( ! rule->getOSrc()->isAny()) { osrc=compiler->getFirstOSrc(rule); assert(osrc!=NULL); osrc_iface = Interface::cast( compiler->dbcopy->findInIndex( helper.findInterfaceByNetzone(osrc))); osrc_level = osrc_iface->getSecurityLevel(); } rel = rule->getTSrc(); assert(rel); if (rel->size() == 0) { compiler->abort(rule, "Empty TSrc"); return true; } obj = compiler->getFirstTSrc(rule); assert(obj!=NULL); if (obj->getId()==compiler->getFwId() ) { /* if ODst is 'any', pick all interfaces with security level _less_ than * level of the interface OSrc is associated with. If ODst is not 'any', * find interface it is associated with and use only it. */ if (rule->getODst()->isAny()) { list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->getSecurityLevel()getFirstODst(rule); assert(odst!=NULL); FWObject *odst_iface = compiler->dbcopy->findInIndex( helper.findInterfaceByNetzone(odst ) ); if (odst_iface!=NULL) cl.push_back(odst_iface); } if ( ! cl.empty() ) { // while (rel->size()) // rel->remove( rel->front() ); rel->clearChildren(); for (FWObject::iterator i1=cl.begin(); i1!=cl.end(); ++i1) { rel->addRef( *i1 ); } } } } break; default: ; // TODO: should actually be always_assert } tmp_queue.push_back(rule); return true; } void NATCompiler_pix::UseFirewallInterfaces::scanInterfaces(RuleElement *rel) { FWObject *o= rel->front(); if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); Address *obj=Address::cast(o); if(obj==NULL) { compiler->abort(rel->getParent(), "Broken rule element "+ rel->getTypeName()+ " in rule "+ NATRule::cast(rel->getParent())->getLabel()+ " ( found object with type "+ string((o!=NULL)?o->getTypeName():"") + ")"); return; } const InetAddr *obj_addr = obj->getAddressPtr(); if (obj_addr==NULL) return; list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=Interface::cast(*i); const InetAddr *iface_addr = iface->getAddressPtr(); if (iface_addr == NULL) continue; if (*iface_addr == *obj_addr) { rel->removeRef(obj); rel->addRef(iface); return; } } } bool NATCompiler_pix::UseFirewallInterfaces::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElement *rel; rel=rule->getODst(); assert(rel); if (!rel->isAny()) scanInterfaces(rel); rel=rule->getTSrc(); assert(rel); if (!rel->isAny()) scanInterfaces(rel); return true; } bool NATCompiler_pix::processNONATRules::processNext() { Helper helper(compiler); NATCompiler_pix *pix_comp = dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()==NATRule::NONAT) { Address *osrc=compiler->getFirstOSrc(rule); assert(osrc); Address *odst=compiler->getFirstODst(rule); assert(odst); Interface *osrc_iface = Interface::cast( compiler->dbcopy->findInIndex(helper.findInterfaceByNetzone(osrc))); Interface *odst_iface = Interface::cast( compiler->dbcopy->findInIndex(helper.findInterfaceByNetzone(odst))); int osrc_level = osrc_iface->getSecurityLevel(); int odst_level = odst_iface->getSecurityLevel(); /* * PIX has two types of NONAT rules, one is when connection goes from * low security interface to the high security interface and another * for the opposite */ if (osrc_level>odst_level) { rule->setInt("nonat_type", NONAT_NAT0); nonat n0; // n0.i_iface = osrc_iface; // n0.o_iface = odst_iface; RuleElement *itf_re = rule->getItfInb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(osrc_iface)) itf_re->addRef(osrc_iface); itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(odst_iface)) itf_re->addRef(odst_iface); n0.src = osrc; n0.dst = odst; n0.acl_name = "nat0."+osrc_iface->getLabel(); n0.last = true; pix_comp->nonat_rules[rule->getId()] = n0; pix_comp->registerACL(n0.acl_name); if (pix_comp->first_nonat_rule_id.count(osrc_iface->getId()) == 0) pix_comp->first_nonat_rule_id[osrc_iface->getId()] = rule->getId(); } else { rule->setInt("nonat_type", NONAT_STATIC); Interface *osrc_iface = Interface::cast( compiler->dbcopy->findInIndex(helper.findInterfaceByNetzone(osrc))); Interface *odst_iface = Interface::cast( compiler->dbcopy->findInIndex(helper.findInterfaceByNetzone(odst))); RuleElement *itf_re = rule->getItfInb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(osrc_iface)) itf_re->addRef(osrc_iface); itf_re = rule->getItfOutb(); assert(itf_re!=NULL); if ( ! itf_re->hasRef(odst_iface)) itf_re->addRef(odst_iface); } } return true; } bool NATCompiler_pix::createNATCmd::processNext() { // Helper helper(compiler); NATCompiler_pix *pix_comp = dynamic_cast(compiler); NATRule *rule = getNext(); if (rule==NULL) return false; string version = compiler->fw->getStr("version"); if (rule->getRuleType()==NATRule::SNAT) { Address *osrc = compiler->getFirstOSrc(rule); assert(osrc); Address *odst = compiler->getFirstODst(rule); assert(osrc); Service *osrv = compiler->getFirstOSrv(rule); assert(osrv); Address *tsrc = compiler->getFirstTSrc(rule); assert(tsrc); RuleElementItfInb *itf_in_re = rule->getItfInb(); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); Interface *i_iface = Interface::cast( FWObjectReference::getObject(itf_in_re->front())); Interface *o_iface = Interface::cast( FWObjectReference::getObject(itf_out_re->front())); NATCmd *natcmd = new NATCmd(); natcmd->nat_id = nat_id_counter; natcmd->rule_label = rule->getLabel(); natcmd->o_src = osrc; natcmd->o_dst = odst; natcmd->o_srv = osrv; natcmd->t_addr = tsrc; natcmd->i_iface = i_iface; // inbound interface natcmd->o_iface = o_iface; // outbound interface natcmd->nat_acl_name = pix_comp->getNATACLname(rule,""); pix_comp->registerACL(natcmd->nat_acl_name); if (Interface::cast(tsrc)!=NULL || o_iface->isDyn()) { natcmd->type = INTERFACE; } else { if (Network::cast(tsrc)) { natcmd->type = NETWORK_ADDRESS; } else { if (AddressRange::cast(tsrc)) natcmd->type = ADDRESS_RANGE; else natcmd->type = SINGLE_ADDRESS; } } natcmd->ignore_nat = natcmd->ignore_nat_and_print_acl = natcmd->ignore_global = false; natcmd->use_nat_0_0 = rule->getBool("use_nat_0_0"); /* * "nat ... outside" is only supported in PIX 6.2 */ natcmd->outside = ( i_iface->getSecurityLevel() < o_iface->getSecurityLevel()); if (natcmd->outside && compiler->fw->getStr("platform")=="pix" && libfwbuilder::XMLTools::version_compare(version, "6.2")<0 ) { compiler->abort( rule, "Bi-Directional NAT of source addresses is only " "supported in PIX 6.2 and newer."); return true; } /* * map is sorted container, this means that objects are going to be arranged * in nat_commands in the order of the key. */ pix_comp->nat_commands[nat_id_counter]= natcmd; rule->setInt("nat_cmd",nat_id_counter); nat_id_counter++; } tmp_queue.push_back(rule); return true; } bool NATCompiler_pix::createStaticCmd::processNext() { NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()==NATRule::DNAT) { Address *osrc = compiler->getFirstOSrc(rule); assert(osrc); Address *odst = compiler->getFirstODst(rule); assert(odst); Service *osrv = compiler->getFirstOSrv(rule); assert(osrv); Address *tdst = compiler->getFirstTDst(rule); assert(tdst); Service *tsrv = compiler->getFirstTSrv(rule); assert(tsrv); RuleElementItfInb *itf_in_re = rule->getItfInb(); RuleElementItfOutb *itf_out_re = rule->getItfOutb(); Interface *i_iface = Interface::cast( FWObjectReference::getObject(itf_in_re->front())); Interface *o_iface = Interface::cast( FWObjectReference::getObject(itf_out_re->front())); StaticCmd *scmd = new StaticCmd(); scmd->acl_name = pix_comp->getNATACLname(rule,""); pix_comp->registerACL(scmd->acl_name); scmd->rule=rule->getLabel(); // source and destination addresses are swapped here because // access lists used for NAT should have 'real' addresses in source scmd->iaddr=tdst; scmd->oaddr=odst; scmd->osrc= osrc; scmd->osrv= osrv; scmd->tsrv= tsrv; scmd->ignore_scmd_and_print_acl=false; scmd->i_iface = i_iface; scmd->o_iface = o_iface; pix_comp->static_commands[sc_id_counter]=scmd; rule->setInt("sc_cmd",sc_id_counter); sc_id_counter++; } return true; } bool NATCompiler_pix::clearOSrc::processNext() { // NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; if (rule->getBool("clear_osrc")) { RuleElementOSrc *osrc=rule->getOSrc(); osrc->clearChildren(); osrc->setAnyElement(); } tmp_queue.push_back(rule); return true; } bool NATCompiler_pix::processMultiAddressObjectsInRE::processNext() { NATRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddress *atrt = MultiAddress::cast(o); if (atrt!=NULL && atrt->isRunTime()) { compiler->abort( rule, "Run-time AddressTable and DNSName objects are not supported."); return true; } } tmp_queue.push_back(rule); return true; } void NATCompiler_pix::compile() { info(" Compiling NAT rules for " + fw->getName()); Compiler::compile(); add( new Begin( "Begin processing")); add( new printTotalNumberOfRules()); add( new singleRuleFilter()); add(new expandGroupsInItfInb("expand groups in inbound Interface")); add(new replaceClusterInterfaceInItfInb( "replace cluster interfaces with member interfaces in " "the inbound Interface rule element")); add(new ItfInbNegation("process negation in inbound Itf")); add(new expandGroupsInItfOutb("expand groups in outbound Interface")); add(new replaceClusterInterfaceInItfOutb( "replace cluster interfaces with member interfaces in " "the outbound Interface rule element")); add(new ItfOutbNegation("process negation in outbound Itf")); add( new ConvertToAtomicForItfInb("convert to atomic for inbound interface") ); add( new ConvertToAtomicForItfOutb("convert to atomic for outbound interface")); if (fw->getOptionsObject()->getBool( "pix_optimize_default_nat")) add (new optimizeDefaultNAT( "optimize commands 'nat (interface) 0.0.0.0 0.0.0.0'")); add( new recursiveGroupsInOSrc("check for recursive groups in OSRC")); add( new recursiveGroupsInODst("check for recursive groups in ODST")); add( new recursiveGroupsInOSrv("check for recursive groups in OSRV")); add( new recursiveGroupsInTSrc("check for recursive groups in TSRC")); add( new recursiveGroupsInTDst("check for recursive groups in TDST")); add( new recursiveGroupsInTSrv("check for recursive groups in TSRV")); add( new emptyGroupsInOSrc("check for empty groups in OSRC")); add( new emptyGroupsInODst("check for empty groups in ODST")); add( new emptyGroupsInOSrv("check for empty groups in OSRV")); add( new emptyGroupsInTSrc("check for empty groups in TSRC")); add( new emptyGroupsInTDst("check for empty groups in TDST")); add( new emptyGroupsInTSrv("check for empty groups in TSRV")); add( new ExpandGroups("expand groups")); /* * We do not support ipv6 yet */ add( new DropIPv6RulesWithWarning( "drop ipv6 rules", "Rule has been suppressed because it contains IPv6 objects and " "Firewall Builder does not support IPv6 for this platform")); add( new eliminateDuplicatesInOSRC("eliminate duplicates in OSRC")); add( new eliminateDuplicatesInODST("eliminate duplicates in ODST")); add( new eliminateDuplicatesInOSRV("eliminate duplicates in OSRV")); add( new processMultiAddressObjectsInOSrc( "process MultiAddress objects in OSrc")); add( new processMultiAddressObjectsInODst( "process MultiAddress objects in ODst")); add( new classifyNATRule("determine NAT rule types")); add( new VerifyRules("verify rules" )); // ReplaceFirewallObjectsODst, ReplaceFirewallObjectsODst and // UseFirewallInterfaces assume there is one object in ODst, // TSrc and TDst rule elements. This should have been assured // by inspector VerifyRules add( new ReplaceFirewallObjectsODst("replace fw object in ODst" )); add( new ReplaceFirewallObjectsTSrc("replace fw object in TSrc" )); add( new UseFirewallInterfaces( "replace host objects with firewall's interfaces if the have the same address")); // ExpandMultipleAddresses acts on different rule elements // depending on the rule type. // Also using overloaded virtual function _expand_interface add( new ExpandMultipleAddresses("expand multiple addresses")); add( new MACFiltering( "check for MAC address filtering")); add( new ExpandAddressRanges("expand address range objects")); add( new checkForUnnumbered("check for unnumbered interfaces")); add( new ConvertToAtomic("convert to atomic rules" )); add( new AssignInterface("assign rules to interfaces" )); add( new verifyInterfaces("verify interfaces assignment" )); add( new fillTranslatedSrv("fill translated service element" )); add( new verifyRuleElements( "verify rule elements for static NAT rules")); add( new processNONATRules("process NONAT" )); if (fw->getOptionsObject()->getBool("pix_optimize_default_nat")) add (new clearOSrc ("clear OSrc" )); add( new SpecialServicesOSrv( "check for special services" )); add( new createNATCmd ("create NAT commands" )); add( new createStaticCmd ("create static commands" )); add( new mergeNATCmd ("merge NAT commands" )); add( new SuppressDuplicateNONATStatics( "suppress duplicate NONAT statics" )); add( new checkForObjectsWithErrors( "check if we have objects with errors in rule elements")); //add( new PrintClearCommands( "Clear ACLs" )); add( new PrintRule ("generate PIX code" )); add( new storeProcessedRules ("store processed rules" )); add( new simplePrintProgress ()); bool pix_check_duplicate_nat = fw->getOptionsObject()->getBool("pix_check_duplicate_nat"); bool pix_check_overlapping_global_pools = fw->getOptionsObject()->getBool("pix_check_overlapping_global_pools"); bool pix_check_overlapping_statics = fw->getOptionsObject()->getBool("pix_check_overlapping_statics"); bool pix_check_overlapping_global_statics = fw->getOptionsObject()->getBool("pix_check_overlapping_global_statics"); if ( pix_check_duplicate_nat || pix_check_overlapping_global_pools || pix_check_overlapping_statics || pix_check_overlapping_global_statics ) { add( new createNewCompilerPass(" Detecting nat problems ...")); if ( pix_check_duplicate_nat ) add( new DetectDuplicateNAT(" Detect duplicate nat entries")); if ( pix_check_overlapping_global_pools ) add( new DetectGlobalPoolProblems( " Detect global pool overlapping" )); if ( pix_check_overlapping_statics ) add( new DetectOverlappingStatics( " Detect overlapping statics" )); if ( pix_check_overlapping_global_statics ) add( new DetectOverlappingGlobalPoolsAndStaticRules( " Detect overlapping global pools and statics" )); add( new simplePrintProgress ( )); } runRuleProcessors(); } void NATCompiler_pix::regroup() { list commands; map > script; commands.push_back("THE_REST"); commands.push_back("access-list "); commands.push_back("global "); commands.push_back("nat "); commands.push_back("static "); string acl, agrp, icmp, telnet, ssh; string new_output; char buf[1024]; istringstream in(output.str()); while (in) { in.getline(buf, 1023, '\n'); strcat(buf,"\n"); if (buf[0]=='!') continue; string slot="THE_REST"; for (list::iterator i=commands.begin(); i!=commands.end(); ++i) { if (strncmp(buf, (*i).c_str(), (*i).size())==0) { slot= *i; break; } } script[slot].push_back(buf); } output.str(""); for (list::iterator i=commands.begin(); i!=commands.end(); ++i) { for (list::iterator j=script[*i].begin(); j!=script[*i].end(); ++j) output << *j; output << "! \n"; output << "! \n"; } } void NATCompiler_pix::epilog() { if ( fw->getOptionsObject()->getBool("pix_regroup_commands")) { info(" Regrouping commands"); regroup(); } } string NATCompiler_pix::printClearCommands() { ostringstream output; string version = fw->getStr("version"); string platform = fw->getStr("platform"); if ( !fw->getOptionsObject()->getBool("pix_acl_no_clear") && !inSingleRuleCompileMode()) { output << Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_xlate") << endl; output << Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_static") << endl; output << Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_global") << endl; output << Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_nat") << endl; } return output.str(); } /* * This includes commands that should be added first, such as commit mode * for FWSM, setting up temporary access list etc. */ string NATCompiler_pix::printPreambleCommands() { return ""; } class MergeConflictRes : public FWObjectDatabase::ConflictResolutionPredicate { public: MergeConflictRes() { } virtual bool askUser(FWObject*, FWObject*) {return false;} }; void NATCompiler_pix::setNamedObjectsManager(NamedObjectsManager *mgr) { named_objects_manager = mgr; } fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_procurve.cpp0000644000175000017500000000336311733011756025055 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator_procurve.h" #include "Helper.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_procurve::myPlatformName() { return "procurve"; } int OSConfigurator_procurve::prolog() { string host_os = fw->getStr("host_OS"); if (host_os!="procurve") abort("Unsupported OS " + host_os ); return Compiler::prolog(); } void OSConfigurator_procurve::processFirewallOptions() { if ( fw->getOptionsObject()->getBool("procurve_set_host_name") ) { output << "hostname " << fw->getName() << endl; output << endl; } } fwbuilder-5.1.0.3599/src/cisco_lib/Helper.h0000644000175000017500000000460011733011756021103 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __HELPER_HH #define __HELPER_HH #include #include #include #include #include namespace fwcompiler { class Helper { fwcompiler::Compiler *compiler; public: Helper(fwcompiler::Compiler *comp) { compiler=comp; } /** * finds interface of the firewall to whose subnet object * 'obj' belongs to. Returns interface ID */ int findInterfaceByAddress(const libfwbuilder::InetAddr *a, const libfwbuilder::InetAddr *nm=NULL); int findInterfaceByAddress(libfwbuilder::Address *obj); /** * finds interface of the firewall associated with the netzone * that object 'obj' belongs to. Returns interface ID */ int findInterfaceByNetzone(const libfwbuilder::InetAddr *a, const libfwbuilder::InetAddr *nm=NULL) throw(libfwbuilder::FWException); int findInterfaceByNetzone(libfwbuilder::Address *obj); std::list findInterfaceByNetzoneOrAll( libfwbuilder::RuleElement *re); std::list getAllInterfaceIDs(); /** * recursively expands object 'o' and places all its children * objects in the list 'ol'. */ void expand_group_recursive(libfwbuilder::FWObject *o, std::list &ol); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManagerPIX.cpp0000644000175000017500000000374711733011756024444 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NamedObjectsManagerPIX.h" #include "PIXObjectGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; NamedObjectsManagerPIX::NamedObjectsManagerPIX(Library *po, Firewall *fw) : NamedObjectsManager(po, fw) { } NamedObjectsManagerPIX::~NamedObjectsManagerPIX() { } string NamedObjectsManagerPIX::getClearCommands() { ostringstream output; string clear_obj_group = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_og"); string clear_object = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/") + "version_" + version + "/pix_commands/clear_obj"); if ( !fw->getOptionsObject()->getBool("pix_acl_no_clear") ) { if (haveObjectGroups()) output << clear_obj_group << endl; if (haveNamedObjects()) output << clear_object << endl; } return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_pix.h0000644000175000017500000002764311733011756023512 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_PIX_HH #define __POLICYCOMPILER_PIX_HH #include #include "fwcompiler/PolicyCompiler.h" #include "fwbuilder/RuleElement.h" #include "Helper.h" #include "ACL.h" #include "PolicyCompiler_cisco.h" #include "specialServices.h" namespace libfwbuilder { class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementSrc; class RuleElementDst; class RuleElementSrv; class Group; }; namespace fwcompiler { class NATCompiler_pix; class PolicyCompiler_pix : public PolicyCompiler_cisco { protected: /** * dynamic interfaces can be used in policy rules only in v6.3 and later * */ friend class checkVersionAndDynamicInterface; class checkVersionAndDynamicInterface : public PolicyRuleProcessor { bool findDynamicInterface(libfwbuilder::PolicyRule *rule, libfwbuilder::RuleElement *re); public: checkVersionAndDynamicInterface(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * internal: checks if interface is a child of a cluster and calls * Compiler::_expand_interface() with a pointer to the master member * interface. If @iface is not cluster interface, just calls * Compiler::_expand_interface() */ virtual void _expand_interface(libfwbuilder::Rule *rule, libfwbuilder::Interface *iface, std::list &ol, bool expand_cluster_interfaces_fully); /* ************************************************************************* * * the following rule processors are intended for PIX < 7.0 * the code is in the module PolicyCompiler_pix_v6_acls.cpp * ************************************************************************* */ /** * verifies combination of interface and direction and * fills interface and direction. After this predicate it * is guaranteed that both interface and direction have * some value. In certain situations interface ID may be * set to "nil" though (e.g. global policy rules). */ DECLARE_POLICY_RULE_PROCESSOR( InterfaceAndDirection_v6 ); /** * if interface has not been defined (this is global policy * rule), then multiply the rule for each interface and set * direction to "Inbound" */ DECLARE_POLICY_RULE_PROCESSOR( assignRuleToInterface_v6 ); class AddressRangesIfTcpServiceToFW : public PolicyCompiler::addressRanges { public: AddressRangesIfTcpServiceToFW(const std::string &n): addressRanges(n) {} virtual bool processNext(); }; friend class AddressRangesIfTcpServiceToFW; /** * split rules with direction "both". * TODO: This is used in OpenBSD pf. Move to class PolicyCompiler */ DECLARE_POLICY_RULE_PROCESSOR( SplitDirection_v6 ); /** * in PIX, ACLs are always applied on interface and direction * can only be "inbound". We emulate outbound ACLs though. */ DECLARE_POLICY_RULE_PROCESSOR( EmulateOutboundACL_v6 ); /** * determine acl rules should belong to */ DECLARE_POLICY_RULE_PROCESSOR( pickACL_v6 ); friend class PolicyCompiler_pix::pickACL_v6; /* ************************************************************************* * * end of module PolicyCompiler_pix_v6_acls.cpp * ************************************************************************* */ /* ************************************************************************* * * rule processors intended to manage ACLs for PIX < 7.0 are inherited * from PolicyCompiler_cisco. * The code is in the module PolicyCompiler_cisco_acls.cpp * * The processors assume that all objects in src and dst * belong to the same network zone (respectively) * * All these rule processors assume outbound ACLs are supported. * Check corresponding capability flag and do not include these * processors in the processors chain in pix.cpp if outbound acls * are not supported. * ************************************************************************* */ class SpecialServicesSrv : public SpecialServices { public: SpecialServicesSrv(const std::string &n): SpecialServices(n, libfwbuilder::RuleElementSrv::TYPENAME) {} }; friend class SpecialServices; /** * sets boolean flag icmp_cmd to be able to generate command * "icmp" instead of "access-list" later. Call this processor * after SplitServices and splitIfDstMatchesFw */ DECLARE_POLICY_RULE_PROCESSOR( PrepareForICMPCmd ); /** * splits SRC if this is icmp_cmd rule */ DECLARE_POLICY_RULE_PROCESSOR( SplitSRCForICMPCmd ); /** * to implement action "Reject" add command "service resetinbound" */ DECLARE_POLICY_RULE_PROCESSOR( RejectAction ); friend class PolicyCompiler_pix::RejectAction; /* * Rule processors that inherit this class match objects used * in policy rules to the nat rules and do something about * them. */ class matchTranslatedAddresses : public PolicyRuleProcessor { protected: std::list transformed_rules; public: matchTranslatedAddresses(const std::string &n):PolicyRuleProcessor(n) {} virtual bool processNext(); virtual std::list findMatchingNATRules( libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv); virtual void action( libfwbuilder::PolicyRule* policy_rule, libfwbuilder::NATRule* nat_rule, libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv); }; /** * this processor replaces objects in dst for which we have * DNAT rule in a NAT policy. Call _after_ telnetToFirewall, * sshToFirewall and PrepareForICMPCmd */ class replaceTranslatedAddresses : public matchTranslatedAddresses { public: replaceTranslatedAddresses(const std::string &n) : matchTranslatedAddresses(n) {} virtual std::list findMatchingNATRules( libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv); virtual void action( libfwbuilder::PolicyRule* policy_rule, libfwbuilder::NATRule* nat_rule, libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv); }; friend class PolicyCompiler_pix::replaceTranslatedAddresses; /** * this processor issues warning when translated addresses are * used in policy rules. Use for PIX 8.3 and later. */ class warnWhenTranslatedAddressesAreUsed : public matchTranslatedAddresses { public: warnWhenTranslatedAddressesAreUsed(const std::string &n) : matchTranslatedAddresses(n) {} virtual std::list findMatchingNATRules( libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv); virtual void action( libfwbuilder::PolicyRule* policy_rule, libfwbuilder::NATRule* nat_rule, libfwbuilder::Address *src, libfwbuilder::Address *dst, libfwbuilder::Service *srv); }; friend class PolicyCompiler_pix::warnWhenTranslatedAddressesAreUsed; /** * can not use object-group in "icmp", "telnet" and "ssh" commands */ DECLARE_POLICY_RULE_PROCESSOR( splitIfTelnetSSHICMPtoFw ); class AvoidObjectGroup : public PolicyRuleProcessor { public: AvoidObjectGroup(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class PolicyCompiler_pix::AvoidObjectGroup; /** * this processor prints single policy rule, assuming all * groups have been expanded, so source, destination and * service hold exactly one object each, and this object is * not a group. Negation should also have been taken care of * before this method is called. */ class PrintRule : public PolicyRuleProcessor { protected: std::string current_rule_label1; std::map current_rule_label2; std::list seen_icmp_commands; int aclLineCounter; std::string _printPortRangeOp(int rs, int re); std::string _printSingleSSHTelnetCommand(int port, libfwbuilder::Address *a, const std::string &interfaceLabel); std::string _printSrcService(libfwbuilder::Service *srv); std::string _printDstService(libfwbuilder::Service *srv); std::string _printAddr(libfwbuilder::Address *o); std::string _printAction(libfwbuilder::PolicyRule *r); std::string _printACL(libfwbuilder::PolicyRule *r); std::string _printSSHTelnetCommand(libfwbuilder::PolicyRule *r); std::string _printICMPCommand(libfwbuilder::PolicyRule *r); std::string _printLog(libfwbuilder::PolicyRule *r); bool suppressDuplicateICMPCommands(const std::string &cmd); public: PrintRule(const std::string &name) : PolicyRuleProcessor(name) { aclLineCounter=0; } virtual bool processNext(); }; friend class PolicyCompiler_pix::PrintRule; bool resetinbound; bool fragguard; NATCompiler_pix *natcmp; protected: virtual std::string myPlatformName(); std::string printAccessGroupCmd(ciscoACL *acl); public: PolicyCompiler_pix(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf, NATCompiler_pix *_natcmp); virtual ~PolicyCompiler_pix() {} virtual int prolog(); virtual void compile(); virtual void epilog(); virtual std::string printClearCommands(); virtual std::string printPreambleCommands(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_procurve_acl.h0000644000175000017500000000402511733011756025363 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_PROCURVE_ACL_HH #define __POLICYCOMPILER_PROCURVE_ACL_HH #include #include "PolicyCompiler_iosacl.h" namespace libfwbuilder { class FWObjectDatabase; class Firewall; }; namespace fwcompiler { class OSConfigurator; }; namespace fwcompiler { class PolicyCompiler_procurve_acl : public PolicyCompiler_iosacl { protected: virtual std::string myPlatformName(); virtual std::string printAccessGroupCmd(ciscoACL *acl, bool neg=false); virtual ciscoACL* createACLObject(const std::string &n, libfwbuilder::Interface *intf, const std::string &d="in", bool _ip_list=false); public: PolicyCompiler_procurve_acl(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf); virtual ~PolicyCompiler_procurve_acl() {} virtual int prolog(); virtual std::string printClearCommands(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/splitByNetworkZonesForRE.cpp0000644000175000017500000000721511733011756025141 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "splitByNetworkZonesForRE.h" #include "Helper.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Interface.h" #include "fwcompiler/Compiler.h" using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* * create new rule and associate it with given interface. If we * already have a rule associated with it, then just add Address to * the rule element of that existing rule. */ void splitByNetworkZonesForRE::AddToInterface( int interface_id, Address *addr, Rule *rule) { Rule *new_rule; RuleElement *new_re; new_rule = rules[interface_id]; if (new_rule==NULL) { new_rule = Rule::cast(compiler->dbcopy->create(rule->getTypeName())); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); rules[interface_id] = new_rule; new_re = RuleElement::cast(new_rule->getFirstByType(re_type)); new_re->clearChildren(); new_re->setAnyElement(); } new_re = RuleElement::cast(new_rule->getFirstByType(re_type)); new_re->addRef( addr ); } bool splitByNetworkZonesForRE::processNext() { Helper helper(compiler); Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); if (re->size()==1) { tmp_queue.push_back(rule); return true; } rules.clear(); std::list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { Address *a = Address::cast(FWReference::getObject(*i1)); assert(a!=NULL); try { int interface_id = helper.findInterfaceByNetzone(a); AddToInterface(interface_id, a, rule); } catch (string err) { // could not find interface with netzone to match address 'a' // will assign rule to all interfaces. Act as if all interfaces // had network zone 'any' and each matches this address. // issue warning only if platform uses netwrk zones. bool supports_network_zones = Resources::getTargetCapabilityBool( compiler->fw->getStr("platform"), "network_zones"); if (supports_network_zones) compiler->warning(rule, err); FWObjectTypedChildIterator i = compiler->fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i) { Interface *ifs = Interface::cast(*i); AddToInterface(ifs->getId(), a, rule); } } } for (std::map::iterator i=rules.begin(); i!=rules.end(); ++i) { tmp_queue.push_back((*i).second); } return true; } fwbuilder-5.1.0.3599/src/cisco_lib/inspectionClassMap.h0000644000175000017500000000346511733011756023473 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSPECTION_CLASS_MAP_HH #define INSPECTION_CLASS_MAP_HH #include /* * status: * 0: enable * 1: disable * 2: skip */ class InspectionClassMap { public: std::string class_map_name; std::string fixup_name; std::string inspect_name; int status; int port1,port2; std::string arg_name; int arg_val; InspectionClassMap(const std::string &fn,int s,int p1,int p2, const std::string &a,int v) { status=s; port1=p1; port2=p2; arg_name=a; arg_val=v; std::string ss = fn; std::string::size_type k; while ( (k=ss.find(" ")) != std::string::npos ) ss.replace(k,1,1,'_'); inspect_name = ss; fixup_name = fn; class_map_name = std::string("custom_") + ss + std::string("_inspection"); } bool isDefault(); std::string getIPProtocol(); std::string getPrintableName(); std::string getMatchCommand(); }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/NamedObject.cpp0000644000175000017500000002230111733011756022370 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NamedObject.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* * Reserved words for all versions of IOS and ASA that support named * objects. It does not make sense to maintain sets of reserved words * separately for each version because it would take a lot of effort * for very little gain. We will maintain super-set of words that * corresponds to the version that has most extensive set. */ const char* rw[] = { "ah", "eigrp", "esp", "gre", "icmp", "icmp6", "igmp", "igrp", "ip", "ipinip", "ipsec", "nos", "ospf", "pcp", "pim", "pptp", "snp", "tcp", "udp", "tcp-aol", "tcp-bgp", "tcp-chargen", "tcp-cifs", "tcp-citrix-ica", "tcp-ctiqbe", "tcp-daytime", "tcp-discard", "tcp-domain", "tcp-echo", "tcp-exec", "tcp-finger", "tcp-ftp", "tcp-ftp-data", "tcp-gopher", "tcp-ident", "tcp-imap4", "tcp-irc", "tcp-hostname", "tcp-kerberos", "tcp-klogin", "tcp-kshell", "tcp-ldap", "tcp-ldaps", "tcp-login", "tcp-lotusnotes", "tcp-nfs", "tcp-netbios-ssn", "tcp-whois", "tcp-nntp", "tcp-pcanywhere-data", "tcp-pim-auto-rp", "tcp-pop2", "tcp-pop3", "tcp-pptp", "tcp-lpd", "tcp-rsh", "tcp-rtsp", "tcp-sip", "tcp-smtp", "tcp-ssh", "tcp-sunrpc", "tcp-tacacs", "tcp-talk", "tcp-telnet", "tcp-uucp", "tcp-www", "tcp-http", "tcp-https", "tcp-cmd", "tcp-sqlnet", "tcp-h323", "tcp-udp-cifs", "tcp-udp-discard", "tcp-udp-domain", "tcp-udp-echo", "tcp-udp-kerberos", "tcp-udp-nfs", "tcp-udp-pim-auto-rp", "tcp-udp-sip", "tcp-udp-sunrpc", "tcp-udp-tacacs", "tcp-udp-www", "tcp-udp-http", "tcp-udp-talk", "udp-biff", "udp-bootpc", "udp-bootps", "udp-cifs", "udp-discard", "udp-domain", "udp-dnsix", "udp-echo", "udp-www", "udp-http", "udp-nameserver", "udp-kerberos", "udp-mobile-ip", "udp-nfs", "udp-netbios-ns", "udp-netbios-dgm", "udp-ntp", "udp-pcanywhere-status", "udp-pim-auto-rp", "udp-radius", "udp-radius-acct", "udp-rip", "udp-secureid-udp", "udp-sip", "udp-snmp", "udp-snmptrap", "udp-sunrpc", "udp-syslog", "udp-tacacs", "udp-talk", "udp-tftp", "udp-time", "udp-who", "udp-xdmcp", "udp-isakmp", "icmp6-unreachable", "icmp6-packet-too-big", "icmp6-time-exceeded", "icmp6-parameter-problem", "icmp6-echo", "icmp6-echo-reply", "icmp6-membership-query", "icmp6-membership-report", "icmp6-membership-reduction", "icmp6-router-renumbering", "icmp6-router-solicitation", "icmp6-router-advertisement", "icmp6-neighbor-solicitation", "icmp6-neighbor-advertisement", "icmp6-neighbor-redirect", "icmp-echo", "icmp-echo-reply", "icmp-unreachable", "icmp-source-quench", "icmp-redirect", "icmp-alternate-address", "icmp-router-advertisement", "icmp-router-solicitation", "icmp-time-exceeded", "icmp-parameter-problem", "icmp-timestamp-request", "icmp-timestamp-reply", "icmp-information-request", "icmp-information-reply", "icmp-mask-request", "icmp-mask-reply", "icmp-traceroute", "icmp-conversion-error", "icmp-mobile-redirect", NULL }; QSet NamedObject::reserved_words; map NamedObject::name_disambiguation; NamedObject::NamedObject(const FWObject *_obj, const QString &_platform) { obj = _obj; platform = _platform; if (reserved_words.empty()) { const char** cptr = rw; while (*cptr!=NULL) { reserved_words.insert(QString(*cptr)); cptr++; } } name = sanitizeObjectName(QString::fromUtf8(obj->getName().c_str())); } QString NamedObject::getCommandWord() { if (Address::constcast(obj)!=NULL && Address::constcast(obj)->isAny()) return "any"; if (Service::constcast(obj)!=NULL && Service::constcast(obj)->isAny()) return "any"; if (Interface::constcast(obj)) return "interface"; return name; } QString NamedObject::sanitizeObjectName(const QString &name) { QString qs = name; qs = qs.replace(" ", "_").replace("/", "_").left(64); if (reserved_words.contains(qs)) { qs = qs + "_obj"; } int n = name_disambiguation[qs]; name_disambiguation[qs] = n + 1; qs = QString("%1.%2").arg(qs).arg(n); return qs; } QString NamedObject::createNetworkObjectCommand(const Address *addr_obj) { if (addr_obj == NULL) return ""; if (addr_obj->isAny()) return ""; if (Interface::constcast(obj)) return ""; QStringList res; res << QString("object network %1") .arg(name); if (AddressRange::isA(addr_obj)) { const AddressRange *ar = AddressRange::constcast(addr_obj); res << QString(" range %1 %2") .arg(ar->getRangeStart().toString().c_str()) .arg(ar->getRangeEnd().toString().c_str()); } else { string addr = addr_obj->getAddressPtr()->toString(); if (IPv4::isA(addr_obj)) { res << QString(" host %1").arg(addr.c_str()); } if (Network::isA(addr_obj)) { string netm = addr_obj->getNetmaskPtr()->toString(); res << QString(" subnet %1 %2") .arg(addr.c_str()) .arg(netm.c_str()); } } res << "exit"; res << ""; return res.join("\n"); } QString NamedObject::printPorts(int rs, int re) { QStringList res; if (rs<0) rs = 0; if (re<0) re = 0; if (rs>0 || re>0) { if (rs==re) res << "eq" << QString::number(rs); else if (rs==0 && re!=0) res << "lt" << QString::number(re); else if (rs!=0 && re==65535) res << "gt" << QString::number(rs); else res << "range " << QString::number(rs) << "" << QString::number(re); } return res.join(" "); } QString NamedObject::createServiceObjectCommand(const Service *serv_obj) { if (serv_obj == NULL) return ""; if (serv_obj->isAny()) return ""; QStringList res; QString proto_name = serv_obj->getProtocolName().c_str(); res << QString("object service %1").arg(name); QStringList service_line; service_line << " service"; if (TCPService::isA(serv_obj) || UDPService::isA(serv_obj)) { service_line << proto_name; int rs = TCPUDPService::constcast(serv_obj)->getSrcRangeStart(); int re = TCPUDPService::constcast(serv_obj)->getSrcRangeEnd(); if (rs != 0 || re != 0) { service_line << "source" << printPorts(rs, re); } rs = TCPUDPService::constcast(serv_obj)->getDstRangeStart(); re = TCPUDPService::constcast(serv_obj)->getDstRangeEnd(); if (rs != 0 || re != 0) { service_line << "destination" << printPorts(rs, re); } } if (ICMPService::isA(serv_obj)) { service_line << proto_name; if (serv_obj->getInt("type")!=-1) service_line << QString::number(serv_obj->getInt("type")); } if (CustomService::isA(serv_obj)) { service_line << CustomService::constcast(serv_obj)->getCodeForPlatform( platform.toStdString()).c_str(); } res << service_line.join(" "); res << "exit"; res << ""; return res.join("\n"); } QString NamedObject::getCommand() { if (Address::constcast(obj)!=NULL) return createNetworkObjectCommand(Address::constcast(obj)); if (Service::constcast(obj)!=NULL) return createServiceObjectCommand(Service::constcast(obj)); return ""; } QString NamedObject::getCommandWhenObjectGroupMember() { if (Address::constcast(obj)!=NULL) return "network-object object " + name; if (Service::constcast(obj)!=NULL) return "service-object object " + name; return ""; } fwbuilder-5.1.0.3599/src/cisco_lib/inspectionProtocol.cpp0000644000175000017500000000766311733011756024130 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "inspectionProtocol.h" std::map InspectionProtocol::protocols; /* * Default ports are defined here jsut like they are filled in the * options by the GUI. If the GUI allows for port range, we specify * port range here, and vice versa. Some of the cases seem to differ * from what Cisco doc specify in the table of the default ports here * http://www.cisco.com/en/US/products/sw/secursw/ps2120/products_upgrade_guides09186a0080369ee2.html * I suppose this is ok since we always can use port range map with * "match" command even if they did not intend it to be like that by * default. However if the GUI returned port numbers that match those * defined in protocolDefinitions, we do not generate 'match' commands * at all and put everything in the "inspection_default" class-map * * Here is how this works: constructor of the class InspectionProtocols * adds object to map 'protocols'. Every initialization of an object * of this class in array protocolDefinitions calls constructor and * therefore creates an entry in the map 'protocols'. It is done this * way because we can statically initialize an array but cant initialize * std::map (at least I do not know how) * * Note: in PIX 7.0 inspector that corresponds to fixup 'smtp' is * called 'esmtp' */ InspectionProtocol protocolDefinitions[] = { InspectionProtocol("ctiqbe", "ctiqbe", "tcp", 2748, 0 ), InspectionProtocol("dns", "dns", "udp", 53, 0 ), InspectionProtocol("ftp", "ftp", "tcp", 21, 0 ), InspectionProtocol("gtp", "gtp", "udp", 2123, 3386 ), InspectionProtocol("h323_h225", "h323 h225", "tcp", 1720, 1720 ), InspectionProtocol("h323_ras", "h323 ras", "udp", 1718, 1719 ), InspectionProtocol("http", "http", "tcp", 80, 80 ), InspectionProtocol("icmp_error","icmp", "icmp", 0, 0 ), InspectionProtocol("ils", "ils", "tcp", 389, 389 ), InspectionProtocol("mgcp", "mgcp", "udp", 2427, 2727 ), InspectionProtocol("netbios", "netbios", "udp", 137, 138 ), InspectionProtocol("rpc", "rpc", "udp", 111, 0 ), InspectionProtocol("rsh", "rsh", "tcp", 514, 0 ), InspectionProtocol("rtsp", "rtsp", "tcp", 554, 0 ), InspectionProtocol("sip", "sip", "tcp", 5060, 5060 ), InspectionProtocol("sip_udp", "sip", "udp", 5060, 0 ), InspectionProtocol("skinny", "skinny", "tcp", 2000, 2000 ), InspectionProtocol("smtp", "esmtp", "tcp", 25, 25 ), InspectionProtocol("sqlnet", "sqlnet", "tcp", 1521, 1521 ), InspectionProtocol("tftp", "tftp", "udp", 69, 0 ), InspectionProtocol("xdmcp", "xdmcp", "udp", 177, 0 ), InspectionProtocol("ip_options_eool", "eool","", 0, 0 ), InspectionProtocol("ip_options_nop", "nop", "", 0, 0 ), InspectionProtocol("ip_options_rtralt", "router-alert", "", 0, 0 ), }; fwbuilder-5.1.0.3599/src/cisco_lib/CompilerDriver_iosacl.cpp0000644000175000017500000001763011733011756024506 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "Configlet.h" #include "CompilerDriver_iosacl.h" #include "PolicyCompiler_iosacl.h" #include "ACL.h" #include "BaseObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; #ifdef _WIN32 string fs_separator = "\\"; #else string fs_separator = "/"; #endif CompilerDriver_iosacl::CompilerDriver_iosacl(FWObjectDatabase *db) : CompilerDriver(db) { safety_net_install_option_name = "iosacl_acl_substitution"; safety_net_install_acl_addr_option_name = "iosacl_acl_temp_addr"; } // create a copy of itself, including objdb CompilerDriver* CompilerDriver_iosacl::clone() { CompilerDriver_iosacl* new_cd = new CompilerDriver_iosacl(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } void CompilerDriver_iosacl::printProlog(QTextStream &file, const string &prolog_code) { file << endl; file << "#" << endl; file << "# Prolog script" << endl; file << "#" << endl; file << prolog_code << endl; file << "#" << endl; file << "# End of prolog script" << endl; file << "#" << endl; } string CompilerDriver_iosacl::safetyNetInstall(Firewall *fw) { ostringstream output; if ( fw->getOptionsObject()->getBool(safety_net_install_option_name) ) { /* Generate short temporary ACL and assign it to all * interfaces. This ACL permits IPSEC (IP proto 50 and UDP port 500) as well as ssh from given subnet to any. */ string temp_acl_addr = fw->getOptionsObject()->getStr( safety_net_install_acl_addr_option_name); if (temp_acl_addr.empty()) { QString err = QObject::tr("Missing address for management host or subnet " "for the temporary ACL.\nPlease enter it in the " "tab 'Script options' in 'Firewall Settings' dialog"); abort(fw, NULL, NULL, err.toStdString()); } // if templ_acl_addr is ipv4 address, then we can not create this // temporary ACL while compiling ipv6 policy. And vice versa. bool create_temp_acl = false; bool tmp_acl_ipv6 = false; if (temp_acl_addr.find(":")!=string::npos) { //looks like ipv6 create_temp_acl = true; tmp_acl_ipv6 = true; } else { // not ipv6, assume ipv4 create_temp_acl = true; tmp_acl_ipv6 = false; } if (create_temp_acl) { string::size_type slash_idx = temp_acl_addr.find('/'); string addr = temp_acl_addr; string netmask = "255.255.255.255"; bool tmp_acl_v6 = false; // check if addr is v6 try { InetAddr addrv6(AF_INET6, temp_acl_addr); tmp_acl_v6 = true; } catch(FWException &ex) { // Assume cnf->maddr is ipv4 if (slash_idx!=string::npos) { addr = temp_acl_addr.substr(0,slash_idx); netmask = temp_acl_addr.substr(slash_idx+1); try { if (netmask.find(".")!=string::npos) { InetAddr nm(netmask); nm.getLength(); // to avoid warning abt unused var } else { int nm_length; istringstream str(netmask); str >> nm_length; InetAddr nm(nm_length); netmask = nm.toString(); } } catch(FWException &ex) { QString err = QObject::tr("Invalid netmask for management subnet: " "'%1'").arg(netmask.c_str()); abort(fw, NULL, NULL, err.toStdString()); } } try { InetAddr a(addr); a.isAny(); } catch(FWException &ex) { QString err = QObject::tr("Invalid address for management subnet: " "'%1'").arg(addr.c_str()); abort(fw, NULL, NULL, err.toStdString()); } } Configlet configlet(fw, "cisco", "safety_net_acl"); configlet.collapseEmptyStrings(true); if (tmp_acl_v6) { configlet.setVariable("ipv4", false); configlet.setVariable("ipv6", true); configlet.setVariable("slash_notation", slash_idx!=string::npos); configlet.setVariable("host_addr", slash_idx==string::npos); configlet.setVariable("management_addr", addr.c_str()); configlet.setVariable("management_netm", ""); } else { InetAddr nnm( ~(InetAddr(netmask)) ); configlet.setVariable("ipv4", true); configlet.setVariable("ipv6", false); configlet.setVariable("management_addr", addr.c_str()); configlet.setVariable("management_netm", nnm.toString().c_str()); } // find management interface list ll = fw->getByType(Interface::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { Interface *intf = Interface::cast( *i ); if (intf->isManagement()) { configlet.setVariable("management_interface", intf->getName().c_str()); FWOptions *ifopt = intf->getOptionsObject(); string itype = ifopt->getStr("type"); configlet.setVariable("management_interface_is_vlan", (itype == "8021q")); configlet.setVariable("management_interface_is_not_vlan", (itype != "8021q")); if (itype == "8021q") configlet.setVariable("management_interface_vlan_id", ifopt->getInt("vlan_id")); else configlet.setVariable("management_interface_vlan_id", ""); break; } } output << configlet.expand().toStdString(); output << endl; } } return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_procurve_acl.cpp0000644000175000017500000001003411733011756025713 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_procurve_acl.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Resources.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_procurve_acl::myPlatformName() { return "procurve_acl"; } PolicyCompiler_procurve_acl::PolicyCompiler_procurve_acl(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf) : PolicyCompiler_iosacl(_db, fw, ipv6_policy, _oscnf) { comment_symbol = ";"; } int PolicyCompiler_procurve_acl::prolog() { string platform = fw->getStr("platform"); if (platform!="procurve_acl") abort("Unsupported platform " + platform ); /* This is optional for PIX (controller by a checkbox in * "asvanced" settings dialog) and is hardcoded as "true" for * iosacl in PolicyCompiler_cisco::pickACL::processNext(). I do * not want a function in the base class PolicyCompiler_cisco be * aware of yet another platform, especially one that is not * strictly speaking Cisco. Just set this option here which is * equivalent to hardcoding it to true. * * TODO: use the same method in PolicyCompiler_iosacl */ fw->getOptionsObject()->setBool("generate_out_acl", true); fw->getOptionsObject()->setBool( "use_acl_remarks", fw->getOptionsObject()->getBool("procurve_acl_use_acl_remarks")); setAllNetworkZonesToNone(); return PolicyCompiler::prolog(); } ciscoACL* PolicyCompiler_procurve_acl::createACLObject(const string &acl_name, Interface *intf, const string &dir, bool using_named_acl) { ciscoACL *acl = new ciscoACL(acl_name, intf, dir, using_named_acl); acl->setQuoteRemarks(true); return acl; } string PolicyCompiler_procurve_acl::printClearCommands() { ostringstream output; string vers = fw->getStr("version"); string platform = fw->getStr("platform"); string xml_element = "clear_ip_acl"; if (ipv6) xml_element = "clear_ipv6_acl"; string clearACLCmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/")+ "version_"+vers+"/procurve_acl_commands/" + xml_element); assert( !clearACLCmd.empty()); // No need to output "clear" commands in single rule compile mode if ( fw->getOptionsObject()->getBool("procurve_acl_acl_basic") || fw->getOptionsObject()->getBool("procurve_acl_acl_substitution")) { for (map::iterator i=acls.begin(); i!=acls.end(); ++i) { ciscoACL *acl = (*i).second; output << printAccessGroupCmd(acl, true); output << clearACLCmd << " " << acl->workName() << endl; output << endl; } output << endl; } output << endl; return output.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/RoutingCompiler_pix.h0000644000175000017500000000420611733011756023670 0ustar sylvestresylvestre/* * Copyright (c) 2008 Steven Mestdagh * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __ROUTINGCOMPILER_PIX_HH__ #define __ROUTINGCOMPILER_PIX_HH__ #include #include "fwcompiler/RoutingCompiler.h" #include "fwbuilder/RuleElement.h" #include "config.h" #include "RoutingCompiler_cisco.h" namespace libfwbuilder { class RuleElementRDst; class RuleElementRItf; class RuleElementRGtw; }; namespace fwcompiler { class RoutingCompiler_pix : public RoutingCompiler_cisco { protected: virtual std::string myPlatformName(); class PrintRule : public RoutingCompiler_cisco::PrintRule { public: PrintRule(const std::string &name); virtual bool processNext(); virtual std::string RoutingRuleToString(libfwbuilder::RoutingRule *r); }; friend class RoutingCompiler_pix::PrintRule; public: RoutingCompiler_pix(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf) : RoutingCompiler_cisco(_db, fw, ipv6_policy, _oscnf) {}; /** * checks if the gateway or Interface rule element is empty * (both are mandatory on PIX) */ DECLARE_ROUTING_RULE_PROCESSOR(emptyRDstOrRItf); virtual int prolog(); virtual void compile(); virtual void epilog(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_ios.h0000644000175000017500000000327311733011756023447 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSNETWORKCONFIGURATOR_IOS_HH #define _OSNETWORKCONFIGURATOR_IOS_HH #include "config.h" #include "fwcompiler/OSConfigurator.h" #include namespace fwcompiler { class OSConfigurator_ios : public OSConfigurator { std::string _printNameif(); std::string _printIPAddress(); std::string _printLogging(); public: virtual ~OSConfigurator_ios() {}; OSConfigurator_ios(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy) : OSConfigurator(_db, fw, ipv6_policy) {} virtual int prolog(); virtual std::string myPlatformName(); virtual void processFirewallOptions(); virtual void addVirtualAddressForNAT(const libfwbuilder::Address *addr); virtual void addVirtualAddressForNAT(const libfwbuilder::Network *nw); }; }; #endif fwbuilder-5.1.0.3599/src/cisco_lib/inspectionClassMap.cpp0000644000175000017500000000355211733011756024023 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "inspectionClassMap.h" #include "inspectionProtocol.h" #include using namespace std; bool InspectionClassMap::isDefault() { InspectionProtocol *ip = InspectionProtocol::protocols[fixup_name]; if (ip!=NULL) return (ip->par1==port1 && ip->par2==port2); return false; } string InspectionClassMap::getIPProtocol() { InspectionProtocol *ip = InspectionProtocol::protocols[fixup_name]; if (ip!=NULL) return ip->ip_proto; return ""; } string InspectionClassMap::getPrintableName() { InspectionProtocol *ip = InspectionProtocol::protocols[fixup_name]; if (ip!=NULL) return ip->printable_name; return ""; } string InspectionClassMap::getMatchCommand() { ostringstream res; res << "match port " << getIPProtocol() << " "; if (port1!=0 && port2==0) res << "eq " << port1; if (port1!=0 && port1==port2) res << "eq " << port1; if (port1!=0 && port2!=0 && port1!=port2) res << "range " << port1 << " " << port2; res << endl; return res.str(); } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_cisco.h0000644000175000017500000004547111733011756024011 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POLICYCOMPILER_CISCO_HH #define __POLICYCOMPILER_CISCO_HH #include #include "fwcompiler/PolicyCompiler.h" #include "fwbuilder/RuleElement.h" #include "Helper.h" #include "ACL.h" #include "BaseObjectGroup.h" #include "NamedObjectsAndGroupsSupport.h" #include "splitByNetworkZonesForRE.h" namespace libfwbuilder { class IPService; class ICMPService; class TCPService; class UDPService; class RuleElementSrc; class RuleElementDst; class RuleElementSrv; class Group; }; namespace fwcompiler { class PolicyCompiler_cisco : public PolicyCompiler { protected: /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes. This method * calls PolicyCompiler::_internalPrintPolicyRule and then adds * fields specific to PIX rules at the end of the printout */ virtual std::string debugPrintRule(libfwbuilder::Rule *rule); virtual ciscoACL* createACLObject(const std::string &n, libfwbuilder::Interface *intf, const std::string &d="in", bool _ip_list=false); /* see #1690. After recent changes (aug 2010) in how we deal with * network zones, we do not assume that interfaces have network * zone "any" if they don't have network zone configured at all. * To work around this, will set network zone to "any" on all * interfaces. Note that this needs to be done only for IOS ACL and * Procurve ACL but not PIX where network zone must be configured * by the user. */ virtual void setAllNetworkZonesToAny(); /* * complementary operation: sets all interface's network zones * to blank to make sure compiler operates with predictable * configuration. This can be important if user switches from * platform that requires network zones (PIX) to the one that * does not support them, but compiler code uses the same * classes. */ virtual void setAllNetworkZonesToNone(); /** * drops dynamic interface from the rule in the following * cases because its address is unknown and we can not build * ACL rule for it. * * assuming interface 'INT' is dynamic * * src. rule bound to interface direction decision * ----------------------------------------------------------------- * INT INT outbound keep * INT any other outbound remove * INT INT inbound remove * INT any other inbound remove * * dest. rule bound to interface direction decision * ------------------------------------------------------------------- * INT INT inbound keep * INT any other inbound remove * INT INT outbound remove * INT any other outbound remove * * */ friend class specialCaseWithDynInterface; class specialCaseWithDynInterface : public PolicyRuleProcessor { bool dropDynamicInterface(libfwbuilder::PolicyRule *rule, libfwbuilder::PolicyRule::Direction dir, libfwbuilder::RuleElement *re); public: specialCaseWithDynInterface(const std::string &name) : PolicyRuleProcessor(name) {} virtual bool processNext(); }; /** * only for rules with interface element 'all' and direction * 'both' or 'inbound'; for interfaces with zones that match * src: create rule with that interface, direction * inbound. 'Any' in src matches all interfaces. * * Set flag (boolean) 'interface_and_direction_set_from_src' * so other rule processors in the same batch can skip the * rule. */ DECLARE_POLICY_RULE_PROCESSOR( setInterfaceAndDirectionBySrc ); /** * only for rules with interface element 'all'and direction * 'both' or 'outbound'; for interfaces with zones that match * dst: create rule with that interface, direction * outbound. 'Any' in dst matches all interfaces. * * Set flag (boolean) 'interface_and_direction_set_from_dst' * so other rule processors in the same batch can skip the * rule. */ DECLARE_POLICY_RULE_PROCESSOR( setInterfaceAndDirectionByDst ); /** * for rules with interface element not 'all' and direction * 'both': create two rules with the same interface and * directions Inbound and Outbound * * for rules with interface element not 'all' and direction * 'inbound' or 'outbound': setInterfaceId to this interface * * Skip rule if flag 'interface_and_direction_set_from_src' or * 'interface_and_direction_set_from_dst' is set * * Set flag (boolean) 'interface_and_direction_set' * so other rule processors in the same batch can skip the * rule. */ DECLARE_POLICY_RULE_PROCESSOR( setInterfaceAndDirectionIfInterfaceSet ); /** * determine acl rules should belong to */ class pickACL : public PolicyRuleProcessor { bool using_named_acl; public: pickACL(bool use_named_acl,const std::string &name) : PolicyRuleProcessor(name) {using_named_acl = use_named_acl;} virtual bool processNext(); }; friend class PolicyCompiler_cisco::pickACL; /** * split rule if Src==any * * This is special case since we assume that "any" includes * also a firewall object. Packets headed to or from the * firewall must be inspected by INPUT or OUTPUT chain, while * packets crossing the firewall are inspected by FORWARD * chain. If we assume that "any" also includes firewall * itself, then we need to generate code for both FORWARD and * INPUT/OUTPUT chains from the same rule. This processor * splits the rule onto two and sets chain and direction in * the second copy appropriately. It preserve original src and * dst in both copies, it only changes chain and direction in * the second copy. */ DECLARE_POLICY_RULE_PROCESSOR(splitIfSrcAny); /** * split rule if Dst==any. See comment in splitIfSrcAny */ DECLARE_POLICY_RULE_PROCESSOR(splitIfDstAny); /** * TODO: move this processor to class PolicyCompiler. The same * processor is used in ipt and in pf (although in pf there it * is present in two copies that have different names * splitIfFirewallInSrc and splitIfFirewallInDst). Move also * splitIfSrcMatchesFw and splitIfDstMatchesFw */ friend class splitIfRuleElementMatchesFW; class splitIfRuleElementMatchesFW : public PolicyRuleProcessor { std::string re_type; public: splitIfRuleElementMatchesFW(const std::string &n, std::string _type) : PolicyRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; friend class splitIfSrcMatchesFw; class splitIfSrcMatchesFw : public splitIfRuleElementMatchesFW { public: splitIfSrcMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class splitIfDstMatchesFw : public splitIfRuleElementMatchesFW { public: splitIfDstMatchesFw (const std::string &n) : splitIfRuleElementMatchesFW(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; friend class PolicyCompiler_cisco::splitIfDstMatchesFw; /** * find redundant objects in rule element and eliminate * them. This only works for SRC and DST since all objects are * assumed to be addresses. Redundant object is such that has * narrower address range than some other object in the same * rule element. */ friend class removeRedundantAddresses; class removeRedundantAddresses : public PolicyRuleProcessor { std::string re_type; public: removeRedundantAddresses(const std::string &n,std::string _type) : PolicyRuleProcessor(n) { re_type=_type; } virtual bool processNext(); }; friend class removeRedundantAddressesFromSrc; class removeRedundantAddressesFromSrc : public removeRedundantAddresses { public: removeRedundantAddressesFromSrc (const std::string &n) : removeRedundantAddresses(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; friend class removeRedundantAddressesFromDst; class removeRedundantAddressesFromDst : public removeRedundantAddresses { public: removeRedundantAddressesFromDst (const std::string &n) : removeRedundantAddresses(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * this processor splits rules if it finds rule that controls * access for tcp service with port number "port" to the firewall */ class tcpServiceToFW : public PolicyRuleProcessor { int port; public: tcpServiceToFW(int p,const std::string &name) : PolicyRuleProcessor(name) {port=p;} virtual bool processNext(); }; friend class PolicyCompiler_cisco::tcpServiceToFW; /** * this processor splits rules if it finds telnet to firewall */ class telnetToFirewall : public tcpServiceToFW { public: telnetToFirewall(const std::string &n):tcpServiceToFW(23, n) {} }; friend class telnetToFirewall; /** * this processor splits rules if it finds ssh to firewall */ class sshToFirewall : public tcpServiceToFW { public: sshToFirewall(const std::string &n):tcpServiceToFW(22, n) {} }; friend class sshToFirewall; /** * this processor splits rules if it finds telnet to firewall */ class httpToFirewall : public tcpServiceToFW { public: httpToFirewall(const std::string &n):tcpServiceToFW(80, n) {} }; friend class httpToFirewall; /** * replace fw with one of its interfaces in SRC in interface * policy rule */ DECLARE_POLICY_RULE_PROCESSOR( replaceFWinSRCInterfacePolicy ); /** * replace fw with one of its interfaces in DST in interface * policy rule */ DECLARE_POLICY_RULE_PROCESSOR( replaceFWinDSTInterfacePolicy ); /** * replace fw with one of its interfaces in DST in global * policy rule */ DECLARE_POLICY_RULE_PROCESSOR( replaceFWinDSTPolicy ); class splitByNetworkZonesForSrc : public splitByNetworkZonesForRE { public: splitByNetworkZonesForSrc(const std::string &n): splitByNetworkZonesForRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class splitByNetworkZonesForDst : public splitByNetworkZonesForRE { public: splitByNetworkZonesForDst(const std::string &n): splitByNetworkZonesForRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * this processor deals with negation in all fields by * splitting the rule and using temporary action * "CONTINUE". Rules must be filtered through NegationPhase2 * later */ DECLARE_POLICY_RULE_PROCESSOR( NegationPhase1 ); /** * eliminates duplicate objects in rule element * 're_type'. Uses special comparison function class to * detect equivalent ICMP objects */ class equalObjCISCO : public PolicyCompiler::equalObj { public: virtual bool operator()(libfwbuilder::FWObject *o); }; class eliminateDuplicatesInRE_cisco : public PolicyCompiler::eliminateDuplicatesInRE { public: eliminateDuplicatesInRE_cisco(const std::string &n,const std::string &re_type) : eliminateDuplicatesInRE(n,re_type) { comparator=new equalObjCISCO(); } }; /** * eliminates duplicate objects in SRC. */ class eliminateDuplicatesInSRC : public eliminateDuplicatesInRE_cisco { public: eliminateDuplicatesInSRC(const std::string &n) : eliminateDuplicatesInRE_cisco(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; /** * eliminates duplicate objects in DST. */ class eliminateDuplicatesInDST : public eliminateDuplicatesInRE_cisco { public: eliminateDuplicatesInDST(const std::string &n) : eliminateDuplicatesInRE_cisco(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; /** * eliminates duplicate objects in SRV */ class eliminateDuplicatesInSRV : public eliminateDuplicatesInRE_cisco { public: eliminateDuplicatesInSRV(const std::string &n) : eliminateDuplicatesInRE_cisco(n,libfwbuilder::RuleElementSrv::TYPENAME) {} }; /** * Placeholders for MultiAddressRunTime objects which are not * supported for Cisco devices (IOS and PIX, at least) */ class processMultiAddressObjectsInRE : public PolicyRuleProcessor { std::string re_type; public: processMultiAddressObjectsInRE(const std::string &name, const std::string &t) : PolicyRuleProcessor(name) { re_type=t; } virtual bool processNext(); }; class processMultiAddressObjectsInSrc : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInSrc(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementSrc::TYPENAME) {} }; class processMultiAddressObjectsInDst : public processMultiAddressObjectsInRE { public: processMultiAddressObjectsInDst(const std::string &n) : processMultiAddressObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; #ifdef OLD_STYLE_OBJECT_GROUP_SUPPORT /** * this processor creates PIX-specific object groups * (PIX CLI command "object-group") for rules with * more than one object in src or dst or srv */ class CreateObjectGroups : public PolicyRuleProcessor { std::string re_type; std::string name_suffix; public: CreateObjectGroups(const std::string &name, const std::string &_ns, const std::string &_type) : PolicyRuleProcessor(name) {re_type=_type; name_suffix=_ns; } virtual bool processNext(); }; friend class PolicyCompiler_cisco::CreateObjectGroups; class CreateObjectGroupsForSrc : public CreateObjectGroups { public: CreateObjectGroupsForSrc(const std::string &n): CreateObjectGroups(n,"src",libfwbuilder::RuleElementSrc::TYPENAME) {} }; class CreateObjectGroupsForDst : public CreateObjectGroups { public: CreateObjectGroupsForDst(const std::string &n): CreateObjectGroups(n,"dst",libfwbuilder::RuleElementDst::TYPENAME) {} }; class CreateObjectGroupsForSrv : public CreateObjectGroups { public: CreateObjectGroupsForSrv(const std::string &n): CreateObjectGroups(n,"srv",libfwbuilder::RuleElementSrv::TYPENAME) {} }; /** * this processor accumulates all rules fed to it by previous * processors, then prints all object groups and feeds all * rules to the next processor. Usually this processor is in * chain right before PrintRules. * */ class printObjectGroups : public PolicyRuleProcessor { public: printObjectGroups(const std::string &n) : PolicyRuleProcessor(n) {} virtual bool processNext(); }; friend class PolicyCompiler_cisco::printObjectGroups; #endif protected: Helper helper; NamedObjectsManager *named_objects_manager; virtual std::string myPlatformName(); std::string mangleInterfaceName(const std::string &interface_name); public: std::map acls; PolicyCompiler_cisco(libfwbuilder::FWObjectDatabase *_db, libfwbuilder::Firewall *fw, bool ipv6_policy, fwcompiler::OSConfigurator *_oscnf); virtual ~PolicyCompiler_cisco() {} virtual std::string createRuleLabel(const std::string &txt, libfwbuilder::Interface *iface, int rule_num); virtual int prolog(); virtual void compile(); virtual void epilog(); virtual std::string printClearCommands(); virtual std::string printPreambleCommands(); /** * sort commands ('icmp', 'telnet', 'ssh') and access lists * in some kind of 'natural' order. Useful for both IOS and PIX */ void regroup(); void setNamedObjectsManager(NamedObjectsManager *mgr); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/OSConfigurator_ios.cpp0000644000175000017500000001527211733011756024004 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "OSConfigurator_ios.h" #include "Helper.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string OSConfigurator_ios::myPlatformName() { return "ios"; } int OSConfigurator_ios::prolog() { string host_os = fw->getStr("host_OS"); if (host_os!="ios") abort("Unsupported OS " + host_os ); return Compiler::prolog(); } void OSConfigurator_ios::processFirewallOptions() { // FWOptions* options=fw->getOptionsObject(); string s; // int i; string version = fw->getStr("version"); string platform = fw->getStr("platform"); if ( fw->getOptionsObject()->getBool("ios_set_host_name") ) { output << "hostname " << fw->getName() << endl; output << endl; } output << _printNameif(); output << endl; output << _printIPAddress(); output << endl; output << _printLogging(); output << endl; } string OSConfigurator_ios::_printNameif() { ostringstream res; string version = fw->getStr("version"); string platform = fw->getStr("platform"); string::size_type n; list l2=fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); string nameifCmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/version_")+ version+"/ios_commands/nameif"); if ((n = nameifCmd.find("%il"))!=string::npos) nameifCmd.replace(n,3,iface->getLabel()); if ((n = nameifCmd.find("%in"))!=string::npos) nameifCmd.replace(n,3,iface->getName()); res << nameifCmd; } res << endl; return res.str(); } string OSConfigurator_ios::_printIPAddress() { ostringstream res; string version = fw->getStr("version"); string platform = fw->getStr("platform"); string setAddrCmd; string::size_type n; if ( fw->getOptionsObject()->getBool("ios_ip_address") ) { list l2=fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=dynamic_cast(*i); assert(iface); if (iface->isDyn()) { setAddrCmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/version_")+ version+"/ios_commands/ip_addr_dyn"); } else { if (iface->isUnnumbered()) { setAddrCmd = ""; } else { setAddrCmd = Resources::platform_res[platform]->getResourceStr( string("/FWBuilderResources/Target/options/version_")+ version+"/ios_commands/ip_addr_static"); } } if ((n = setAddrCmd.find("%il"))!=string::npos) setAddrCmd.replace(n,3,iface->getLabel()); if ((n = setAddrCmd.find("%in"))!=string::npos) setAddrCmd.replace(n,3,iface->getName()); if ((n = setAddrCmd.find("%a"))!=string::npos) setAddrCmd.replace(n,2,iface->getAddressPtr()->toString()); if ((n = setAddrCmd.find("%n"))!=string::npos) setAddrCmd.replace(n,2,iface->getNetmaskPtr()->toString()); res << setAddrCmd; } } res << endl; return res.str(); } string OSConfigurator_ios::_printLogging() { Helper helper(this); ostringstream str; bool logging_on=false; bool iosacl_generate_logging_commands = fw->getOptionsObject()->getBool( "iosacl_generate_logging_commands"); if (iosacl_generate_logging_commands) { string syslog_host = fw->getOptionsObject()->getStr("iosacl_syslog_host"); string syslog_facility= fw->getOptionsObject()->getStr("iosacl_syslog_facility"); string trap_level= fw->getOptionsObject()->getStr("iosacl_logging_trap_level"); bool buffered = fw->getOptionsObject()->getBool("iosacl_logging_buffered"); string buffered_level = fw->getOptionsObject()->getStr("iosacl_logging_buffered_level"); bool console = fw->getOptionsObject()->getBool("iosacl_logging_console"); string console_level = fw->getOptionsObject()->getStr("iosacl_logging_console_level"); bool timestamp = fw->getOptionsObject()->getBool("iosacl_logging_timestamp"); if ( ! timestamp ) str << "no "; str << "service timestamp log datetime localtime" << endl; if ( ! syslog_host.empty() ) { str << endl; str << "logging host " << syslog_host << endl; if ( ! syslog_facility.empty() ) str << "logging facility " << syslog_facility << endl; if ( ! trap_level.empty() ) str << "logging trap " << trap_level << endl; logging_on=true; } if ( ! buffered ) str << "no logging buffered" << endl; else { str << "logging buffered " << buffered_level << endl; logging_on=true; } if ( ! console ) str << "no logging console" << endl; else { str << "logging console " << console_level << endl; logging_on=true; } str << endl; } return str.str(); } void OSConfigurator_ios::addVirtualAddressForNAT(const Address*) { } void OSConfigurator_ios::addVirtualAddressForNAT(const Network*) { } fwbuilder-5.1.0.3599/src/cisco_lib/PolicyCompiler_cisco.cpp0000644000175000017500000005620411733011756024340 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "PolicyCompiler_cisco.h" #include "NamedObjectsManager.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Management.h" #include "fwbuilder/Network.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; string PolicyCompiler_cisco::myPlatformName() { return ""; } PolicyCompiler_cisco::PolicyCompiler_cisco(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy, OSConfigurator *_oscnf) : PolicyCompiler(_db, fw, ipv6_policy, _oscnf) , helper(this) { } int PolicyCompiler_cisco::prolog() { return PolicyCompiler::prolog(); } string PolicyCompiler_cisco::createRuleLabel(const string &txt, Interface *iface, int rule_num) { ostringstream str; str << rule_num; if (iface!=NULL) str << "(" << iface->getLabel() << ")"; else str << "(" << txt << ")"; return str.str(); } void PolicyCompiler_cisco::setAllNetworkZonesToAny() { /* see #1690. After recent changes (aug 2010) in how we deal with * network zones, we do not assume that interfaces have network * zone "any" if they don't have network zone configured at all. * To work around this, will set network zone to "any" on all * interfaces. Note that this needs to be done only for IOS ACL and * Procurve ACL but not PIX where network zone must be configured * by the user. */ list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); int netzone_id = FWObjectDatabase::getIntId(iface->getStr("network_zone")); if (netzone_id == -1) iface->setStr("network_zone", FWObjectDatabase::getStringId(FWObjectDatabase::ANY_ADDRESS_ID)); } } void PolicyCompiler_cisco::setAllNetworkZonesToNone() { list l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->getStr("network_zone") != "") iface->setStr("network_zone", ""); } } ciscoACL* PolicyCompiler_cisco::createACLObject(const string &acl_name, Interface *intf, const string &dir, bool using_named_acl) { ciscoACL *acl = new ciscoACL(acl_name, intf, dir, using_named_acl); return acl; } string PolicyCompiler_cisco::debugPrintRule(Rule *r) { ostringstream str; PolicyRule *rule = PolicyRule::cast(r); // FWObject *rule_iface = dbcopy->findInIndex(rule->getInterfaceId()); // string iname = (rule_iface!=NULL)?rule_iface->getName():""; string dir = rule->getDirectionAsString(); str << PolicyCompiler::debugPrintRule(rule) << " " << dir // << " " << iname << " " << rule->getStr("acl"); // " intfId=" << rule->getInterfaceId() << // " intfstr=" << rule->getInterfaceStr(); return str.str(); } bool PolicyCompiler_cisco::splitIfSrcAny::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrc *srcrel=rule->getSrc(); Address *src = compiler->getFirstSrc(rule); if ( rule->getDirection()!=PolicyRule::Inbound && ( srcrel->isAny() || ( srcrel->size()==1 && src!=NULL && !compiler->complexMatch(src,compiler->fw) && srcrel->getBool("single_object_negation")) ) ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection( PolicyRule::Outbound ); RuleElementSrc *nsrc=r->getSrc(); nsrc->clearChildren(); nsrc->addRef(compiler->fw); tmp_queue.push_back(r); } tmp_queue.push_back(rule); // add old rule anyway return true; } /* * This splits the rule if Dst==any and one or more icmp services are * found in Srv. The name of this rule processor needs to be more * descriptive. */ bool PolicyCompiler_cisco::splitIfDstAny::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srvrel=rule->getSrv(); RuleElementDst *dstrel=rule->getDst(); Address *dst=compiler->getFirstDst(rule); std::list cl; for (list::iterator i1=srvrel->begin(); i1!=srvrel->end(); ++i1) { FWObject *o = *i1; FWObject *obj = NULL; if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer(); Service *s=Service::cast(obj); assert(s!=NULL); if (ICMPService::isA(s)) cl.push_back(s); if (TCPService::isA(s) && TCPUDPService::cast(s)->getDstRangeStart()==22 && TCPUDPService::cast(s)->getDstRangeEnd()==22) cl.push_back(s); if (TCPService::isA(s) && TCPUDPService::cast(s)->getDstRangeStart()==23 && TCPUDPService::cast(s)->getDstRangeEnd()==23) cl.push_back(s); } if ( !cl.empty() && rule->getDirection()!=PolicyRule::Outbound && ( dstrel->isAny() || ( dstrel->size()==1 && dst!=NULL && !compiler->complexMatch(dst,compiler->fw) && dstrel->getBool("single_object_negation")) ) ) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setDirection( PolicyRule::Inbound ); RuleElementDst *ndst=r->getDst(); ndst->clearChildren(); ndst->addRef(compiler->fw); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); for (list::iterator i=cl.begin(); i!=cl.end(); ++i) nsrv->addRef( (*i) ); tmp_queue.push_back(r); } tmp_queue.push_back(rule); // add old rule in any case return true; } bool PolicyCompiler_cisco::NegationPhase1::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; return true; #ifdef DO_NEGATION if (compiler->debug>=5) { cerr << rule->getLabel() + " >>> neg 1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"; cerr << rule << " " << compiler->atomicRuleToString( rule ); } RuleElementSrc *src=rule->getSrc(); assert(src); RuleElementDst *dst=rule->getDst(); assert(dst); RuleElementSrv *srv=rule->getSrv(); assert(srv); /* do not use clearChildren because it * destroys children objects (can delete * rules created on the previous pass) */ compiler->temp_ruleset->clear(); if (src->getNeg()) { PolicyRule *r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("action","CONTINUE"); RuleElementSrc *nsrc=r->getSrc(); nsrc->setNeg(false); vr->push_back(r); r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrc=r->getSrc(); nsrc->clearChildren(); nsrc->setAnyElement(); nsrc->setNeg(false); vr->push_back(r); } if (dst->getNeg()) { PolicyRule *r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("action","CONTINUE"); RuleElementDst *ndst=r->getDst();; ndst->setNeg(false); vr->push_back(r); r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); ndst=r->getDst();; ndst->clearChildren(); ndst->setAnyElement(); ndst->setNeg(false); vr->push_back(r); } if (srv->getNeg()) { PolicyRule *r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("action","CONTINUE"); RuleElementSrv *nsrv=r->getSrv(); nsrv->setNeg(false); vr->push_back(r); r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->setAnyElement(); nsrv->setNeg(false); vr->push_back(r); } if (vr->empty()) { PolicyRule *r= getCompiler()->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); if (compiler->debug>=5) { cerr << "****************** copying rule\n"; rule->dump(true,true); } r->duplicate(rule); vr->push_back(r); } if (compiler->debug>=5) { cerr << rule->getLabel() + " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"; rule->dump(true,true); cerr << " ------------------------------------------------\n"; for (vector::iterator i=vr->begin(); i!=vr->end(); i++) { Rule *r=(*i); r->dump(true,true); cerr << r << " " << compiler->atomicRuleToString( r ); } } #endif } /** * re_type can be either RuleElementSrc::TYPENAME or RuleElementDst::TYPENAME * * TODO: this has to move to class PolicyRuleProcessor */ bool PolicyCompiler_cisco::splitIfRuleElementMatchesFW::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; PolicyCompiler_cisco *cisco_comp = dynamic_cast(compiler); RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); int nre = re->size(); list cl; for (list::iterator i1=re->begin(); nre>1 && i1!=re->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); Address *a = Address::cast(obj); assert(a!=NULL); if (cisco_comp->complexMatch(a,cisco_comp->fw)) { cl.push_back(obj); nre--; PolicyRule *new_rule = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(new_rule); new_rule->duplicate(rule); RuleElement *new_re = RuleElement::cast(new_rule->getFirstByType(re_type)); new_re->clearChildren(); new_re->setAnyElement(); new_re->addRef( a ); tmp_queue.push_back(new_rule); } } if (!cl.empty()) { for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) re->removeRef(*i1); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_cisco::specialCaseWithDynInterface::dropDynamicInterface( PolicyRule *rule, PolicyRule::Direction cmp_dir, RuleElement *re) { PolicyRule::Direction dir=rule->getDirection(); // FWObject *rule_iface = compiler->dbcopy->findInIndex(rule->getInterfaceId()); RuleElementItf *intf_re = rule->getItf(); FWObject *rule_iface = FWObjectReference::getObject(intf_re->front()); list cl; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *obj = FWObjectReference::getObject(*i1); Interface *ifs = Interface::cast( obj ); if (ifs!=NULL && ifs->isDyn()) { if (ifs->getId()==rule_iface->getId() && dir==cmp_dir) cl.push_back(obj); // keep it else continue; // remove it } else cl.push_back(obj); } if (re->size()==1 && cl.empty()) // remove the whole rule return false; if (!cl.empty()) { re->clearChildren(); for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) { FWObject *oo = *i1; re->addRef( oo ); } } return true; } /** * checks for the following situations: * * assuming interface 'INT' is dynamic * * src. rule bound to interface direction decision * ----------------------------------------------------------------- * INT INT outbound keep * INT any other outbound remove * INT INT inbound remove * INT any other inbound remove * * dest. rule bound to interface direction decision * ------------------------------------------------------------------- * INT INT inbound keep * INT any other inbound remove * INT INT outbound remove * INT any other outbound remove * */ bool PolicyCompiler_cisco::specialCaseWithDynInterface::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; if ( dropDynamicInterface( rule, PolicyRule::Outbound, rule->getSrc() ) && dropDynamicInterface( rule, PolicyRule::Inbound, rule->getDst() ) ) tmp_queue.push_back(rule); return true; } /* * processor splitIfRuleElementMatchesFW (or one derived from it) * should have been called before tcpServiceToFW. This way we know * that if dst is a firewall, it is a single object there. */ bool PolicyCompiler_cisco::tcpServiceToFW::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; PolicyCompiler_cisco *cisco_comp = dynamic_cast(compiler); RuleElementSrv *srv = rule->getSrv(); Address *a = compiler->getFirstDst(rule); assert(a!=NULL); if (rule->getAction()==PolicyRule::Accept && ( (Cluster::cast(a) != NULL && Cluster::cast(a)->hasMember(compiler->fw)) || a->getId() == compiler->fw->getId() ) ) { std::list cl; for (list::iterator i1=srv->begin(); i1!=srv->end(); ++i1) { FWObject *obj = FWReference::getObject(*i1); Service *s = Service::cast(obj); assert(s!=NULL); if (TCPService::isA(s) && TCPUDPService::cast(s)->getDstRangeStart()==port && TCPUDPService::cast(s)->getDstRangeEnd()==port) cl.push_back(obj); } if (!cl.empty()) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementDst *ndst = r->getDst(); ndst->clearChildren(); ndst->addRef( compiler->fw ); RuleElementSrv *nsrv = r->getSrv(); nsrv->clearChildren(); nsrv->addRef( cl.front() ); r->setBool("tcp_service_to_fw", true); tmp_queue.push_back(r); for (list::iterator i1=cl.begin(); i1!=cl.end(); ++i1) srv->removeRef(*i1); if ( ! srv->isAny()) tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); } else tmp_queue.push_back(rule); return true; } /* * firewall should be a single object in SRC. If object in SRC matches * firewall (in a sence of complexMatch) but is not actual firewall object, * do nothing assuming user wanted it that way. */ bool PolicyCompiler_cisco::replaceFWinSRCInterfacePolicy::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; // FWObject *rule_iface = compiler->dbcopy->findInIndex(rule->getInterfaceId()); RuleElementItf *intf_re = rule->getItf(); Interface *rule_iface = Interface::cast( FWObjectReference::getObject(intf_re->front())); if ( rule_iface!=NULL && rule->getDirection()==PolicyRule::Outbound) { RuleElementSrc *src = rule->getSrc(); if (compiler->getFirstSrc(rule)->getId()==compiler->fw->getId()) { src->clearChildren(); src->addRef(rule_iface); } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_cisco::replaceFWinDSTInterfacePolicy::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; // FWObject *rule_iface = compiler->dbcopy->findInIndex(rule->getInterfaceId()); RuleElementItf *intf_re = rule->getItf(); Interface *rule_iface = Interface::cast( FWObjectReference::getObject(intf_re->front())); if ( rule_iface!=NULL && rule->getDirection()==PolicyRule::Inbound) { RuleElementDst *dst = rule->getDst(); if (compiler->getFirstDst(rule)->getId()==compiler->fw->getId()) { dst->clearChildren(); dst->addRef(rule_iface); } } tmp_queue.push_back(rule); return true; } /* * dst should contain objects that belong to the network zone of the * same interface (use splitByNetworkZonesForRE for that) */ bool PolicyCompiler_cisco::replaceFWinDSTPolicy::processNext() { Helper helper(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; // FWObject *rule_iface = compiler->dbcopy->findInIndex(rule->getInterfaceId()); RuleElementItf *intf_re = rule->getItf(); if (intf_re->isAny()) { RuleElementSrc *src = rule->getSrc(); RuleElementDst *dst = rule->getDst(); if (!src->isAny() && compiler->getFirstDst(rule)->getId()==compiler->fw->getId()) { try { int iface_id = helper.findInterfaceByNetzone( compiler->getFirstSrc(rule)); FWObject *iface = compiler->dbcopy->findInIndex(iface_id); dst->clearChildren(); dst->addRef(iface); } catch (string addr) { ostringstream str; str << "Address " << addr << " does not match address or network zone of any interface." ; compiler->abort(rule, str.str()); return true; } } } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_cisco::equalObjCISCO::operator()(FWObject *o) { if (ICMPService::cast(obj)!=NULL && ICMPService::cast(o)!=NULL) { return (obj->getInt("type")==o->getInt("type")); } else return o->getId()==obj->getId(); } /* re_type can be either RuleElementSrc::TYPENAME or RuleElementDst::TYPENAME */ bool PolicyCompiler_cisco::removeRedundantAddresses::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast(rule->getFirstByType(re_type)); if (re->size()==1) { tmp_queue.push_back(rule); return true; } map status; for (list::iterator i1=re->begin(); i1!=re->end(); ++i1) { Address *a = Address::cast(FWReference::getObject(*i1)); assert(a!=NULL); // assuming all objects are addresses. status[a] = false; } map::iterator i1; map::iterator i2; for (i1=status.begin(); i1!=status.end(); ++i1) { Address *a1 = i1->first; // const InetAddrMask* am1 = a1->getInetAddrMaskObjectPtr(); for (i2=status.begin(); i2!=status.end(); ++i2) { if (i2->second) continue; Address *a2 = i2->first; if (a1->getId() == a2->getId()) continue; // const InetAddrMask* am2 = a2->getInetAddrMaskObjectPtr(); // if (am1 && am2 && am1->toString() == am2->toString()) continue; if (compiler->checkForShadowing(*a1, *a2) ) status[a1] = true; } } for (i1=status.begin(); i1!=status.end(); ++i1) { if (i1->second) re->removeRef(i1->first); } tmp_queue.push_back(rule); return true; } bool PolicyCompiler_cisco::processMultiAddressObjectsInRE::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o = *i; if (FWReference::cast(o)!=NULL) o = FWReference::cast(o)->getPointer(); MultiAddress *atrt = MultiAddress::cast(o); if (atrt!=NULL && atrt->isRunTime()) { compiler->abort( rule, "Run-time AddressTable and DNSName objects are not supported."); return true; } } tmp_queue.push_back(rule); return true; } void PolicyCompiler_cisco::compile() { } class acl_sort_order { public: acl_sort_order() {}; bool operator()(const string &a, const string &b) { string::size_type i1,i2; i1=a.find(' ',a.find(' ')+1); i2=b.find(' ',b.find(' ')+1); return a.substr(0,i1) < b.substr(0,i2); } }; void PolicyCompiler_cisco::regroup() { list commands; map > script; commands.push_back("THE_REST"); commands.push_back("access-list "); commands.push_back("access-group "); commands.push_back("icmp "); commands.push_back("ssh "); commands.push_back("telnet "); string acl, agrp, icmp, telnet, ssh; string new_output; char buf[1024]; istringstream in(output.str()); while (in) { in.getline(buf, 1023, '\n'); strcat(buf,"\n"); if (buf[0]=='!') continue; string slot="THE_REST"; string cmd(buf); string::size_type n=cmd.find(' '); list::iterator s = ::find(commands.begin(),commands.end(),cmd.substr(0,n+1)); if (s!=commands.end()) slot = *s; script[slot].push_back(buf); } script["access-list "].sort(acl_sort_order()); output.str(""); for (list::iterator i=commands.begin(); i!=commands.end(); ++i) { for (list::iterator j=script[*i].begin(); j!=script[*i].end(); ++j) output << *j; output << "! \n"; output << "! \n"; } } void PolicyCompiler_cisco::epilog() { } string PolicyCompiler_cisco::printClearCommands() { return ""; } /* * This includes commands that should be added first, such as commit mode * for FWSM, setting up temporary access list etc. */ string PolicyCompiler_cisco::printPreambleCommands() { return ""; } void PolicyCompiler_cisco::setNamedObjectsManager(NamedObjectsManager *mgr) { named_objects_manager = mgr; } fwbuilder-5.1.0.3599/src/cisco_lib/NamedObjectsManager.h0000644000175000017500000000407011733011756023516 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _NAMED_OBJECTS_MANAGER_HH #define _NAMED_OBJECTS_MANAGER_HH #include "config.h" #include "BaseObjectGroup.h" namespace libfwbuilder { class Group; class Firewall; class Library; }; namespace fwcompiler { class NamedObjectsManager { protected: libfwbuilder::Firewall *fw; std::string platform; std::string version; // storage for object groups created to be used with PIX // command object-group std::string object_groups_group_id; libfwbuilder::Library *persistent_objects; public: std::map named_objects; NamedObjectsManager(libfwbuilder::Library *persistent_objects, libfwbuilder::Firewall *_fw); virtual ~NamedObjectsManager(); void addNamedObject(const libfwbuilder::FWObject *obj); NamedObject* getNamedObject(const libfwbuilder::FWObject *obj); virtual std::string getNamedObjectsDefinitions(); virtual std::string getClearCommands(); bool haveNamedObjects(); bool haveObjectGroups(); BaseObjectGroup* createObjectGroup(); libfwbuilder::Group* getObjectGroupsGroup(); }; } #endif fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_pix_find_translations.cpp0000644000175000017500000001061111733011756027014 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NATCompiler_pix.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; class triplet { public: libfwbuilder::Address *src; libfwbuilder::Address *dst; libfwbuilder::Service *srv; triplet() {src=NULL; dst=NULL; srv=NULL;} triplet(libfwbuilder::Address *s, libfwbuilder::Address *d, libfwbuilder::Service *v) {src=s; dst=d; srv=v;} std::string hash(); }; std::string triplet::hash() { ostringstream ostr; string dst_str; string src_str; Interface *intf = Interface::cast(src); if (intf && intf->isDyn()) src_str = intf->getId(); else src_str = src->getAddressPtr()->toString(); intf = Interface::cast(dst); if (intf && intf->isDyn()) dst_str = intf->getId(); else dst_str = dst->getAddressPtr()->toString(); ostr << src_str << "." << dst_str <<"." << srv->getId(); return ostr.str(); } list NATCompiler_pix::findMatchingDNATRules( Address *src, Address *dst, Service *srv, const string &nat_re_type_to_match_dst) { list res; map res_dict; FWObject *final_ruleset = persistent_objects->getRoot()->findInIndex(final_ruleset_id); for (FWObject::iterator i=final_ruleset->begin(); i!=final_ruleset->end(); ++i) { NATRule *rule = NATRule::cast(*i); if (rule == NULL) continue; // skip RuleSetOptions object switch (rule->getRuleType()) { case NATRule::DNAT: { FWObject *re_to_compare = rule->getFirstByType(nat_re_type_to_match_dst); Address *dst_to_compare = Address::cast( FWReference::getObject(re_to_compare->front())); Address *osrc = getFirstOSrc(rule); assert(osrc); Address *odst = getFirstODst(rule); assert(odst); Service *osrv = getFirstOSrv(rule); assert(osrv); Address *tsrc = getFirstTSrc(rule); assert(tsrc); // Address *tdst = getFirstTDst(rule); assert(tdst); Service *tsrv = getFirstTSrv(rule); assert(tsrv); const InetAddr *dst_to_compare_addr = dst_to_compare->getAddressPtr(); // dst_to_compare_addr can be NULL if object in rule // element is a dynamic interface or a group. We should // have expanded groups by now, but dynamic interface can // still be there. if (*(src->getAddressPtr()) == *(osrc->getAddressPtr()) && (osrv->isAny() || srv->getId()==tsrv->getId()) && (dst_to_compare_addr == NULL || *(dst->getAddressPtr()) == *(dst_to_compare_addr))) { if (osrv->isAny()) { triplet tr(src, odst, srv); res_dict[tr.hash()] = rule; } else { triplet tr(src, odst, osrv); res_dict[tr.hash()] = rule; } } } break; default: ; // TODO: should actually be always_assert } } for (map::iterator i=res_dict.begin(); i!=res_dict.end(); ++i) { res.push_back(i->second); } return res; } fwbuilder-5.1.0.3599/src/cisco_lib/NATCompiler_pix_optimizers.cpp0000644000175000017500000005416411733011756025513 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2002-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "NATCompiler_pix.h" #include "NamedObjectsAndGroupsSupport.h" #include "NamedObjectsManager.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Network.h" #include "fwbuilder/Resources.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; /* * this processor uses slurp to make sure all previous processors ran before * it starts scanning rules. */ bool NATCompiler_pix::mergeNATCmd::processNext() { NATCompiler_pix *pix_comp = dynamic_cast(compiler); slurp(); if (tmp_queue.size()==0) return false; for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { NATRule *rule = NATRule::cast( *k ); if (rule->getRuleType() == NATRule::DNAT) { StaticCmd *scmd = pix_comp->static_commands[rule->getInt("sc_cmd")]; map::iterator i1; for (i1=pix_comp->static_commands.begin(); i1!=pix_comp->static_commands.end(); ++i1) { StaticCmd *sc = (*i1).second; if (scmd==sc) break; if ( *scmd == *sc) { /* * rule 'sc' is above rule 'scmd', we need to print 'static' command * only in the last rule using the same access list. That's why we set * flag ignore_scmd_and_print acl in sc and not in scmd */ scmd->acl_name = sc->acl_name; sc->ignore_scmd_and_print_acl = true; } } } if (rule->getRuleType()==NATRule::SNAT) { NATCmd *natcmd = pix_comp->nat_commands[ rule->getInt("nat_cmd") ]; map::iterator i1; for (i1 = pix_comp->nat_commands.begin(); i1 != pix_comp->nat_commands.end(); ++i1) { NATCmd *nc = (*i1).second; /* since map nat_commands is sorted by the key, we only have to scan it * until we hit natcmd */ if (natcmd==nc) break; const InetAddr *a1 = natcmd->t_addr->getAddressPtr(); const InetAddr *a2 = nc->t_addr->getAddressPtr(); Interface *int1 = natcmd->o_iface; Interface *int2 = nc->o_iface; if ((natcmd->t_addr == nc->t_addr || (a1 && a2 && *a1 == *a2)) && int1->getId() == int2->getId() ) { natcmd->ignore_global = true; natcmd->nat_id = nc->nat_id; } } for (map::iterator i1=pix_comp->nat_commands.begin(); i1!=pix_comp->nat_commands.end(); ++i1) { NATCmd *nc = (*i1).second; /* since map nat_commands is sorted by the key, we only have to scan it * until we hit natcmd */ if (natcmd == nc) break; if (nc->ignore_nat) continue; /* using operator==(const Address &o1,const Address &o2) here */ if ( *(natcmd->o_src) == *(nc->o_src) && *(natcmd->o_dst) == *(nc->o_dst) && *(natcmd->o_srv) == *(nc->o_srv) && natcmd->i_iface->getId() == nc->i_iface->getId() ) { /* * there is another nat rule (rule #2) with the same "original" * addresses and the same interface. We can drop this nat rule, but need * to merge its global pool with pool of the rule #2. * * This nat rule could have been sharing a global pool with some other * nat rule; in this case we need to find this other rule and also * reassign it to the global pool of the rule #2. */ natcmd->ignore_nat = true; map::iterator i2; for (i2 = pix_comp->nat_commands.begin(); i2 != pix_comp->nat_commands.end(); ++i2) { NATCmd *nc2 = i2->second; if (natcmd->nat_id == nc2->nat_id) nc2->nat_id = nc->nat_id; } natcmd->nat_id = nc->nat_id; } } if (!natcmd->use_nat_0_0) { map::iterator i1; for (i1 = pix_comp->nat_commands.begin(); i1 != pix_comp->nat_commands.end(); ++i1) { NATCmd *nc=(*i1).second; /* since map nat_commands is sorted by the key, we only have to scan it * until we hit natcmd */ if (natcmd==nc) break; /* ignore nat natcmd entries for rules where we won't print 'nat' * command or use 'nat 0' command since this means we won't print * access-list for those rules and hense can not merge lists */ if (nc->ignore_nat) continue; if (nc->use_nat_0_0) continue; if ( natcmd->nat_id == nc->nat_id && natcmd->t_addr == nc->t_addr && natcmd->i_iface->getId() == nc->i_iface->getId() ) { /* two nat commands with the same id, the same interface and the same * translated address, but different osrc and odst. OSrc and ODst must * be different, otherwise these two commands would have been merged * in the previous cycle. We can merge access lists and drop one of * these nat commands. We merge ACLs by assigning them the same name. */ natcmd->nat_acl_name = nc->nat_acl_name; nc->ignore_nat_and_print_acl = true; } } } } } return true; } /* * The goal of this processor is to find SNAT rules that could be * translated as "nat (interface) 0.0.0.0 0.0.0.0. These rules should * have the same network object in OSrc that is used to define * interface's network zone. The logic is simple: if network "A" is a * network zone for internal interface, then only packets from this * network can hit it and therefore there is no need to check source * address once more in the "nat" rule. * * We also check for ODst and OSrv, because if the destination or the * service are defined, then this optimization can not be done. * * This optimization can be turned off using checkbutton in the * "Firewall" tab. * * call this processor really early, when groups have not been * expanded yet. At this point both NAT rule type and interfaces it * is associated with are unknown yet. We have to partially repeat * algorithms used in other rule processors to determine NAT rule type * and interface. * * We do this optimization in two steps: * * 1. in this rule processor we replace object in OSrc with firewall's * interface. This way we can still use other rule processors that * determine rule type and assign it to interfaces, but rule won't be * split onto multiple rules because of objects in OSrc. We also set * boolean flags "clear_osrc" and "use_nat_0_0" on the rule. * * 2. further down in rule processor clearOSrc we check the flag and * clear OSrc if it is set. * * 3. flag "use_nat_0_0" is used in printRule processor. */ bool NATCompiler_pix::optimizeDefaultNAT::processNext() { // NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementOSrc *osrc=rule->getOSrc(); RuleElementOSrv *osrv=rule->getOSrv(); RuleElementODst *odst=rule->getODst(); RuleElementTSrc *tsrc=rule->getTSrc(); RuleElementTDst *tdst=rule->getTDst(); if (osrc->size()>1) return true; if (osrc->isAny()) return true; if (!osrv->isAny()) return true; if (!odst->isAny()) return true; /* * can't use RuleElementOSrc::getFirst(bool dereference) because it * returns Address::cast(o), but child element of rule element may be * a group when this processor is called. */ FWObject *o=osrc->front(); string osrc_id; if (FWReference::cast(o)!=NULL) osrc_id = FWObjectDatabase::getStringId(FWReference::cast(o)->getPointerId()); else osrc_id = FWObjectDatabase::getStringId(o->getId()); if ( ( !tsrc->isAny() && tdst->isAny()) || ( !osrc->isAny() && odst->isAny() && tsrc->isAny() && tdst->isAny() ) ) { // this rule type is SNAT or NONAT list l2=compiler->fw->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface=Interface::cast(*i); if (iface->getStr("orig_netzone_id")==osrc_id ) { rule->setBool("clear_osrc",true); rule->setBool("use_nat_0_0",true); osrc->clearChildren(); osrc->addRef(iface); break; } } } return true; } bool NATCompiler_pix::SuppressDuplicateNONATStatics::processNext() { Helper helper(compiler); // NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; if (rule->getRuleType()== NATRule::NONAT && rule->getInt("nonat_type")==NONAT_STATIC) { Address *osrc=compiler->getFirstOSrc(rule); assert(osrc); Address *odst=compiler->getFirstODst(rule); assert(odst); nonat_static_parameters sp; sp.iface1 = helper.findInterfaceByNetzone(osrc ); sp.iface2 = helper.findInterfaceByNetzone(odst ); sp.addr = *(odst->getAddressPtr()); sp.mask = *(odst->getNetmaskPtr()); for (deque::iterator i=all_nonat_statics.begin(); i!=all_nonat_statics.end(); ++i ) { if ( i->iface1==sp.iface1 && i->iface2==sp.iface2 && i->addr==sp.addr && i->mask==sp.mask ) return true; } all_nonat_statics.push_back(sp); } tmp_queue.push_back(rule); return true; } NATCompiler_pix::DetectOverlap::~DetectOverlap() {}; bool NATCompiler_pix::DetectOverlap::checkOverlapping( const libfwbuilder::Address &addr1, const libfwbuilder::InetAddr &addr2) { if (AddressRange::isA(&addr1)) { const InetAddr a1 = AddressRange::constcast(&addr1)->getRangeStart(); const InetAddr a2 = AddressRange::constcast(&addr1)->getRangeEnd(); return (addr2==a1 || addr2==a2 || (addr2>a1 && addr2getRangeStart(); const InetAddr a2=AddressRange::constcast(&pool)->getRangeEnd(); return a1.toString()+"-"+a2.toString(); } else { return pool.getAddressPtr()->toString() + "/" + pool.getNetmaskPtr()->toString(); } } bool NATCompiler_pix::DetectGlobalPoolProblems::processNext() { NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()== NATRule::SNAT ) { NATCmd *natcmd = pix_comp->nat_commands[ rule->getInt("nat_cmd") ]; if (natcmd->ignore_global) return true; if (natcmd->type != INTERFACE) { if (checkOverlapping(*(natcmd->t_addr), *(natcmd->o_iface->getAddressPtr()))) compiler->abort( rule, "Global pool " + printGlobalPoolAddress(*(natcmd->t_addr)) + " overlaps with interface address."); if (checkOverlapping(*(natcmd->t_addr), *(natcmd->o_iface->getBroadcastAddressPtr())) || checkOverlapping(*(natcmd->t_addr), *(natcmd->o_iface->getAddressPtr())) ) compiler->warning( rule, "Global pool " + printGlobalPoolAddress(*(natcmd->t_addr)) + " overlaps with broadcast address."); } for (map::iterator i1=pix_comp->nat_commands.begin(); i1!=pix_comp->nat_commands.end(); ++i1) { NATCmd *nc = (*i1).second; /* since map nat_commands is sorted by the key, we only have to scan it * until we hit natcmd */ if (nc->ignore_global) continue; if (natcmd==nc) break; Interface *int1 = natcmd->o_iface; Interface *int2 = nc->o_iface; if ( int1->getId()==int2->getId() ) { if ( ! fwcompiler::_find_obj_intersection(natcmd->t_addr,nc->t_addr).empty() ) { compiler->abort( rule, string("Global pool overlap: ") + rule->getLabel() + " : " + printGlobalPoolAddress(*(natcmd->t_addr)) + nc->rule_label + " : " + printGlobalPoolAddress(*(nc->t_addr)) ); } } } } return true; } bool NATCompiler_pix::DetectOverlappingGlobalPoolsAndStaticRules::processNext() { NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()== NATRule::DNAT ) { Address *outa=compiler->getFirstODst(rule); assert(outa); Address *insa=compiler->getFirstTDst(rule); assert(insa); for (map::iterator i=pix_comp->nat_commands.begin(); i!=pix_comp->nat_commands.end(); ++i) { NATCmd *natcmd=(*i).second; if (natcmd->ignore_global) return true; /* in this case natcmd->t_addr is interface. Interface creates * single-address global pool, but since it has netmask, * method checkOverlapping would treat it as network. I create * temporary substitution Address object to avoid this . * * If interface is used for a global pool (SNAT rule) and * for a static (DNAT rule), then this is ok even though * such global pool overlaps with such static (added 10/17/03) * * But first I need to check if this interface has dynamic * address, in which case I can not really do this check * at all. */ IPv4 addr; Interface *iface=Interface::cast(natcmd->t_addr); if (iface!=NULL && iface->isDyn()) return true; if (iface!=NULL && iface->getId()==outa->getId()) return true; addr.setAddress(*(natcmd->t_addr->getAddressPtr())); addr.setNetmask(*(natcmd->t_addr->getNetmaskPtr())); if (natcmd->type== INTERFACE) { addr.setNetmask(InetAddr(InetAddr::getAllOnes())); } if ( checkOverlapping( addr, *(outa->getAddressPtr())) || checkOverlapping( *outa, *(addr.getAddressPtr())) ) compiler->abort( rule, "Global pool " +printGlobalPoolAddress(addr) +" from rule " +natcmd->rule_label +" overlaps with static translation address in rule " +rule->getLabel()); } } return true; } bool NATCompiler_pix::DetectDuplicateNAT::processNext() { NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()== NATRule::SNAT) { NATCmd *natcmd=pix_comp->nat_commands[ rule->getInt("nat_cmd") ]; if (natcmd->ignore_nat) return true; for (map::iterator i1=pix_comp->nat_commands.begin(); i1!=pix_comp->nat_commands.end(); ++i1) { NATCmd *nc = (*i1).second; /* since map nat_commands is sorted by the key, we only have to scan it * until we hit natcmd */ if (nc->ignore_nat) continue; if (natcmd==nc) break; Interface *int1 = natcmd->o_iface; Interface *int2 = nc->o_iface; // InetAddr a1=natcmd->o_addr->getAddress(); // InetAddr a2=nc->o_addr->getAddress(); // // InetAddr m1=natcmd->o_addr->getInetAddr(); // InetAddr m2=nc->o_addr->getNetmask(); if ( int1->getId()==int2->getId() && natcmd->o_src==nc->o_src && natcmd->o_dst==nc->o_dst && *(natcmd->o_srv)==*(nc->o_srv) ) { ostringstream str; str << "Duplicate NAT detected: rules " << rule->getLabel() << " and "<< nc->rule_label << " : "<< natcmd->o_src->getAddressPtr()->toString() << "/"<< natcmd->o_src->getNetmaskPtr()->toString() << " " << natcmd->o_srv->getProtocolName() << " " << TCPUDPService::cast(natcmd->o_srv)->getSrcRangeStart() << ":" << TCPUDPService::cast(natcmd->o_srv)->getSrcRangeEnd() << " " << "->"<< natcmd->o_dst->getAddressPtr()->toString() << "/"<< natcmd->o_dst->getNetmaskPtr()->toString() << " " << TCPUDPService::cast(natcmd->o_srv)->getDstRangeStart() << "/" << TCPUDPService::cast(natcmd->o_srv)->getDstRangeEnd(); compiler->abort(rule, str.str()); } } } return true; } bool NATCompiler_pix::DetectOverlappingStatics::processNext() { NATCompiler_pix *pix_comp=dynamic_cast(compiler); NATRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); if (rule->getRuleType()== NATRule::DNAT ) { StaticCmd *scmd=pix_comp->static_commands[ rule->getInt("sc_cmd") ]; for (map::iterator i1=pix_comp->static_commands.begin(); i1!=pix_comp->static_commands.end(); i1++ ) { // int scid=i1->first; StaticCmd *sc= i1->second; if (sc->ignore_scmd_and_print_acl) continue; if (sc==scmd) break; if (Interface::isA(scmd->oaddr) && Interface::isA(sc->oaddr)) { if ( *(sc->osrv) == *(scmd->osrv) && *(sc->tsrv) == *(scmd->tsrv) && *(sc->osrc) == *(scmd->osrc) && sc->oaddr->getId() == scmd->oaddr->getId()) compiler->abort( rule, "Static NAT rules overlap or are redundant : rules "+ sc->rule+" and "+scmd->rule+" : "+ "outside address: "+ "interface "+Interface::cast(scmd->oaddr)->getLabel()+ " inside address: "+ scmd->iaddr->getAddressPtr()->toString()+"/"+ scmd->iaddr->getNetmaskPtr()->toString()); } else { if ( *(sc->osrv) == *(scmd->osrv) && *(sc->tsrv) == *(scmd->tsrv) && *(sc->osrc) == *(scmd->osrc)) { const InetAddrMask *ia1 = scmd->iaddr->getInetAddrMaskObjectPtr(); const InetAddrMask *ia2 = sc->iaddr->getInetAddrMaskObjectPtr(); const InetAddrMask *oa1 = scmd->oaddr->getInetAddrMaskObjectPtr(); const InetAddrMask *oa2 = sc->oaddr->getInetAddrMaskObjectPtr(); if ( ! getOverlap(*(ia1), *(ia2)).empty() || ! getOverlap(*(oa1), *(oa2)).empty() ) compiler->abort( rule, "Static NAT rules overlap or are redundant: rules "+ sc->rule+" and "+scmd->rule+" : "+ "outside address: "+ scmd->oaddr->getAddressPtr()->toString()+"/"+ scmd->oaddr->getNetmaskPtr()->toString()+ " inside address: "+ scmd->iaddr->getAddressPtr()->toString()+"/"+ scmd->iaddr->getNetmaskPtr()->toString()); } } } } return true; } fwbuilder-5.1.0.3599/src/cisco_lib/ASA8TwiceNatLogic.cpp0000644000175000017500000000616411733011756023337 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ASA8TwiceNatLogic.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Network.h" #include using namespace libfwbuilder; using namespace std; ASA8TwiceNatStaticLogic::ASA8TwiceNatStaticLogic(NATRule *_rule) { rule = _rule; } int ASA8TwiceNatStaticLogic::countAddresses(FWObject *re) { int res = 0; for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1) { FWObject *o = FWReference::getObject(*i1); if (Group::cast(o) != NULL) res += countAddresses(o); else { Address *addr = Address::cast(o); assert(addr); res += addr->dimension(); } } return res; } ASA8TwiceNatStaticLogic::TwiceNatRuleType ASA8TwiceNatStaticLogic::getAutomaticType() { RuleElementOSrc *osrc_re = rule->getOSrc(); assert(osrc_re!=NULL); //Address *osrc = Address::cast(FWReference::getObject(osrc_re->front())); RuleElementTSrc *tsrc_re = rule->getTSrc(); assert(tsrc_re!=NULL); //Address *tsrc = Address::cast(FWReference::getObject(tsrc_re->front())); if (tsrc_re->isAny()) return STATIC; else { /* * Default behavior: if the number of ip addresses in OSrc is * equal to that in TSrc, then use "static". Otherwise use * "dynamic". Note that TSrc may be a group, in which case we * assume it has different number of addresses and we fall * back to dynamic */ if (tsrc_re->size() > 1) return DYNAMIC; //if (tsrc == NULL) return DYNAMIC; Address *tsrc = Address::cast(FWReference::getObject(tsrc_re->front())); // ASA sez: "ERROR: Subnet can not be used as mapped source in // dynamic NAT policy." if (Network::isA(tsrc)) return STATIC; // If we tranlate one-to-one, then use static as well if (countAddresses(osrc_re) == countAddresses(tsrc_re)) return STATIC; else return DYNAMIC; } return DYNAMIC; } ASA8TwiceNatStaticLogic::TwiceNatRuleType ASA8TwiceNatStaticLogic::getType() { TwiceNatRuleType res = getAutomaticType(); FWOptions *ropt = rule->getOptionsObject(); if (ropt->getBool("asa8_nat_dynamic")) res = DYNAMIC; if (ropt->getBool("asa8_nat_static")) res = STATIC; return res; } fwbuilder-5.1.0.3599/src/unit_tests/0000755000175000017500000000000011733011756017766 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsLinux/0000755000175000017500000000000011733011756025154 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsLinux/generatedScriptTestsLinux.h0000644000175000017500000000562011733011756032516 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GENERATEDSCRIPTTESTS_LINUX_H #define GENERATEDSCRIPTTESTS_LINUX_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include class GeneratedScriptTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *objdb; void loadDataFile(const std::string &file_name); void runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name); public: void setUp(); void tearDown(); void ManifestTest(); void FwCommentTest(); void CheckUtilitiesTest(); void verifyInterfacesTest(); void configureInterfacesTest(); void configureInterfacesClusterTest(); void virtualAddressesForNat1Test(); void virtualAddressesForNat2Test(); void runTimeAddressTablesWithIpSet1Test(); void runTimeAddressTablesWithIpSet2Test(); void minusDTest(); void minusOTest1(); void minusOTest2(); void minusDminusOTest(); void outputFileNameOptionTest1(); void outputFileNameOptionTest2(); void outputFileNameOptionTest3(); CPPUNIT_TEST_SUITE(GeneratedScriptTest); CPPUNIT_TEST(ManifestTest); CPPUNIT_TEST(FwCommentTest); CPPUNIT_TEST(CheckUtilitiesTest); CPPUNIT_TEST(verifyInterfacesTest); CPPUNIT_TEST(configureInterfacesTest); CPPUNIT_TEST(configureInterfacesClusterTest); CPPUNIT_TEST(virtualAddressesForNat1Test); CPPUNIT_TEST(virtualAddressesForNat2Test); CPPUNIT_TEST(runTimeAddressTablesWithIpSet1Test); CPPUNIT_TEST(runTimeAddressTablesWithIpSet2Test); CPPUNIT_TEST(minusDTest); CPPUNIT_TEST(minusOTest1); CPPUNIT_TEST(minusOTest2); CPPUNIT_TEST(minusDminusOTest); CPPUNIT_TEST(outputFileNameOptionTest1); CPPUNIT_TEST(outputFileNameOptionTest2); CPPUNIT_TEST(outputFileNameOptionTest3); CPPUNIT_TEST_SUITE_END(); }; #endif // GENERATEDSCRIPTTESTS_LINUX_H fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsLinux/main_generatedScriptTestsLinux.cpp0000644000175000017500000000343611733011756034060 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsLinux.h" #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include "../../../common/init.cpp" using namespace std; using namespace libfwbuilder; int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( GeneratedScriptTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsLinux/generatedScriptTestsLinux.pro0000644000175000017500000000044111733011756033063 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS = generatedScriptTestsLinux.h SOURCES = main_generatedScriptTestsLinux.cpp \ generatedScriptTestsLinux.cpp TARGET = generatedScriptTestsLinux run_tests.commands = echo "Running tests..." && \ rm -f *.fw && \ ./${TARGET} fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsLinux/test1.fwb0000644000175000017500000044607111733011756026730 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsLinux/generatedScriptTestsLinux.cpp0000644000175000017500000005560611733011756033062 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsLinux.h" #include "CompilerDriver_ipt.h" #include "Configlet.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; void GeneratedScriptTest::setUp() { // register protocols we need IPService::addNamedProtocol(51, "ah"); IPService::addNamedProtocol(112, "vrrp"); Configlet::setDebugging(true); } void GeneratedScriptTest::tearDown() { } void GeneratedScriptTest::loadDataFile(const string &file_name) { try { /* load the data file */ UpgradePredicate upgrade_predicate; objdb->setReadOnly( false ); objdb->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(file_name); objdb->reIndex(); } catch (FWException &ex) { qDebug() << ex.toString().c_str(); } } void GeneratedScriptTest::runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name) { loadDataFile(test_file); QStringList args; args << firewall_object_name.c_str(); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file test1.fw QFileInfo fi(generate_file_name.c_str()); CPPUNIT_ASSERT_MESSAGE("Generated file " + generate_file_name + " not found", fi.exists() == true); } // I can check only certain parts of the top comment. Can't // compare against "golden" file because some parts of the comment // are variable, such as date, version and build number void GeneratedScriptTest::ManifestTest() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test1", "test1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "test1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test3", "test3.fw"); res = Configlet::findConfigletInFile("top_comment", "test3.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * test3.fw firewall.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") == -1); delete objdb; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test4", "test4.fw"); res = Configlet::findConfigletInFile("top_comment", "test4.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * test4.fw /etc/init.d/firewall.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test4.fw firewall.fw") == -1); CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") == -1); delete objdb; } void GeneratedScriptTest::FwCommentTest() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test1", "test1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "test1.fw"); // find string from the firewall object comment and compare CPPUNIT_ASSERT(res.indexOf("# Firewall object test1 comment") != -1); delete objdb; } void GeneratedScriptTest::CheckUtilitiesTest() { QStringList utils; QStringList test1_utils; test1_utils << "find_program which"; test1_utils << "find_program $IPTABLES"; test1_utils << "find_program $MODPROBE"; test1_utils << "find_program $IP"; QStringList test2_utils; test2_utils << "find_program which"; test2_utils << "find_program $IPTABLES"; test2_utils << "find_program $IPTABLES_RESTORE"; test2_utils << "find_program $MODPROBE"; test2_utils << "find_program $IP"; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test1", "test1.fw"); QString res = Configlet::findConfigletInFile("check_utilities", "test1.fw"); foreach(QString line, res.split("\n")) { if (line.indexOf("find_program ")!=-1) { utils.push_back(line.trimmed()); } } CPPUNIT_ASSERT(utils == test1_utils); delete objdb; utils.clear(); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test2", "test2.fw"); res = Configlet::findConfigletInFile("check_utilities", "test2.fw"); foreach(QString line, res.split("\n")) { if (line.indexOf("find_program ")!=-1) { utils.push_back(line.trimmed()); } } CPPUNIT_ASSERT(utils == test2_utils); delete objdb; } void GeneratedScriptTest::verifyInterfacesTest() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test1", "test1.fw"); QString res = Configlet::findConfigletInFile("verify_interfaces", "test1.fw"); CPPUNIT_ASSERT(res.indexOf("for i in eth0 eth1 lo eth2 ; do") != -1); delete objdb; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test4", "test4.fw"); res = Configlet::findConfigletInFile("verify_interfaces", "test4.fw"); CPPUNIT_ASSERT(res.indexOf("for i in eth0 eth1 lo eth2 eth1.200 vlan110 vlan111 ; do") != -1); delete objdb; } void GeneratedScriptTest::configureInterfacesTest() { QStringList sample; sample << "update_addresses_of_interface \"eth0 192.0.2.1/24\" \"\""; sample << "update_addresses_of_interface \"lo 127.0.0.1/8\" \"\""; sample << "update_addresses_of_interface \"eth1.200 fe80::20c:29ff:fed2:cca1/64 192.168.1.1/24\" \"\""; sample << "update_addresses_of_interface \"vlan110 192.168.2.1/24\" \"\""; sample << "update_addresses_of_interface \"vlan111 192.168.3.1/24\" \"\""; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test4", "test4.fw"); // unfortunately function configure_interfaces is not generated by its // own configlet QString res = Configlet::findConfigletInFile("script_skeleton", "test4.fw"); int n1 = res.indexOf("configure_interfaces() {"); CPPUNIT_ASSERT_MESSAGE("Shell function configure_interfaces is missing", n1 != -1); int n2 = res.indexOf("}", n1); res = res.mid(n1, n2-n1); QStringList intf_list; foreach(QString line, res.split("\n")) { if (line.indexOf("update_addresses_of_interface ")!=-1) { intf_list.push_back(line.trimmed()); } } sample.sort(); intf_list.sort(); CPPUNIT_ASSERT(sample == intf_list); delete objdb; } void GeneratedScriptTest::configureInterfacesClusterTest() { QStringList sample_2; sample_2 << "update_addresses_of_interface \"eth0 192.0.2.1/24\" \"192.0.2.100/24 192.0.2.101/24\""; sample_2 << "update_addresses_of_interface \"eth1 192.168.1.1/24\" \"192.168.1.100/24\""; sample_2 << "update_addresses_of_interface \"lo 127.0.0.1/8\" \"\""; sample_2 << "update_addresses_of_interface \"eth2 192.168.2.1/24\" \"192.168.2.100/24\""; QStringList sample_3; sample_3 << "update_addresses_of_interface \"eth0 192.0.2.2/24\" \"192.0.2.100/24 192.0.2.101/24\""; sample_3 << "update_addresses_of_interface \"eth1 192.168.1.2/24\" \"192.168.1.100/24\""; sample_3 << "update_addresses_of_interface \"lo 127.0.0.1/8\" \"\""; sample_3 << "update_addresses_of_interface \"eth2 192.168.2.2/24\" \"192.168.2.100/24\""; sample_2.sort(); sample_3.sort(); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "cluster-2-3", "test2.fw"); // unfortunately function configure_interfaces is not generated by its // own configlet QString res = Configlet::findConfigletInFile("script_skeleton", "test2.fw"); int n1 = res.indexOf("configure_interfaces() {"); CPPUNIT_ASSERT_MESSAGE("Shell function configure_interfaces is missing", n1 != -1); int n2 = res.indexOf("}", n1); res = res.mid(n1, n2-n1); QStringList intf_list; foreach(QString line, res.split("\n")) { if (line.indexOf("update_addresses_of_interface ")!=-1) { intf_list.push_back(line.trimmed()); } } intf_list.sort(); CPPUNIT_ASSERT(sample_2 == intf_list); intf_list.clear(); res = Configlet::findConfigletInFile("script_skeleton", "test3.fw"); n1 = res.indexOf("configure_interfaces() {"); CPPUNIT_ASSERT_MESSAGE("Shell function configure_interfaces is missing", n1 != -1); n2 = res.indexOf("}", n1); res = res.mid(n1, n2-n1); foreach(QString line, res.split("\n")) { if (line.indexOf("update_addresses_of_interface ")!=-1) { intf_list.push_back(line.trimmed()); } } intf_list.sort(); CPPUNIT_ASSERT(sample_3 == intf_list); delete objdb; } void GeneratedScriptTest::virtualAddressesForNat1Test() { QStringList sample_1; sample_1 << "update_addresses_of_interface \"eth0 192.0.2.1/24 192.0.2.100/24 192.0.2.101/24\" \"\""; sample_1 << "update_addresses_of_interface \"lo 127.0.0.1/8\" \"\""; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test5", "test5.fw"); // unfortunately function configure_interfaces is not generated by its // own configlet QString res = Configlet::findConfigletInFile("script_skeleton", "test5.fw"); int n1 = res.indexOf("configure_interfaces() {"); CPPUNIT_ASSERT_MESSAGE("Shell function configure_interfaces is missing", n1 != -1); int n2 = res.indexOf("}", n1); res = res.mid(n1, n2-n1); QStringList intf_list; foreach(QString line, res.split("\n")) { if (line.indexOf("update_addresses_of_interface ")!=-1) { intf_list.push_back(line.trimmed()); } } intf_list.sort(); CPPUNIT_ASSERT(sample_1 == intf_list); delete objdb; } void GeneratedScriptTest::virtualAddressesForNat2Test() { QStringList sample_1; sample_1 << "update_addresses_of_interface \"eth0 192.0.2.100/24 192.0.2.101/24\" \"192.0.2.1/24\""; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test6", "test6.fw"); // unfortunately function configure_interfaces is not generated by its // own configlet QString res = Configlet::findConfigletInFile("script_skeleton", "test6.fw"); int n1 = res.indexOf("configure_interfaces() {"); CPPUNIT_ASSERT_MESSAGE("Shell function configure_interfaces is missing", n1 != -1); int n2 = res.indexOf("}", n1); res = res.mid(n1, n2-n1); QStringList intf_list; foreach(QString line, res.split("\n")) { if (line.indexOf("update_addresses_of_interface ")!=-1) { intf_list.push_back(line.trimmed()); } } intf_list.sort(); CPPUNIT_ASSERT(sample_1 == intf_list); delete objdb; } /* * negative test first. test6 does not use ipset module and the configlet should * only insert blank function check_run_time_address_table_files() */ void GeneratedScriptTest::runTimeAddressTablesWithIpSet1Test() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test6", "test6.fw"); QString res = Configlet::findConfigletInFile("run_time_address_tables", "test6.fw"); CPPUNIT_ASSERT(!res.isEmpty()); int n1 = res.indexOf("load_run_time_address_table_files() {"); CPPUNIT_ASSERT(n1 == -1); n1 = res.indexOf("check_run_time_address_table_files() {"); CPPUNIT_ASSERT(n1 != -1); delete objdb; } void GeneratedScriptTest::runTimeAddressTablesWithIpSet2Test() { QStringList sample_1; sample_1 << "reload_address_table \"bad_guys\" \"/etc/fw/bad_guys.dat\""; sample_1 << "reload_address_table \"bad_guys_2\" \"/etc/fw/bad_guys.dat\""; QStringList sample_2; sample_2 << "check_file \"bad_guys\" \"/etc/fw/bad_guys.dat\""; sample_2 << "check_file \"bad_guys_2\" \"/etc/fw/bad_guys.dat\""; objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "test7", "test7.fw"); QString res = Configlet::findConfigletInFile("run_time_address_tables", "test7.fw"); int n1 = res.indexOf("load_run_time_address_table_files() {"); CPPUNIT_ASSERT_MESSAGE("Shell function load_run_time_address_table_files is missing", n1 != -1); int n2 = res.indexOf("}", n1); QString conf = res.mid(n1, n2-n1); QStringList cmd_list; foreach(QString line, conf.split("\n")) { if (line.indexOf("reload_address_table ")!=-1) { cmd_list.push_back(line.trimmed()); } } cmd_list.sort(); CPPUNIT_ASSERT(sample_1 == cmd_list); n1 = res.indexOf("check_run_time_address_table_files() {"); CPPUNIT_ASSERT_MESSAGE("Shell function check_run_time_address_table_files is missing", n1 != -1); n2 = res.indexOf("}", n1); conf = res.mid(n1, n2-n1); cmd_list.clear(); foreach(QString line, conf.split("\n")) { if (line.indexOf("check_file ")!=-1) { cmd_list.push_back(line.trimmed()); } } cmd_list.sort(); CPPUNIT_ASSERT(sample_2 == cmd_list); delete objdb; } // compiler should place generated script in the directory specified // with -d option void GeneratedScriptTest::minusDTest() { QDir current = QDir::current(); QFile f("/tmp/test1.fw"); f.remove(); objdb = new FWObjectDatabase(); loadDataFile("test1.fwb"); QStringList args; args << "-d" << "/tmp" << "test1"; CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file /tmp/test1.fw QFileInfo fi("/tmp/test1.fw"); CPPUNIT_ASSERT_MESSAGE("Generated file /tmp/test1.fw not found", fi.exists() == true); QString res = Configlet::findConfigletInFile("top_comment", "/tmp/test1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; QDir::setCurrent(current.path()); } // if -o option is given, it defines the path and name for the // generated script void GeneratedScriptTest::minusOTest1() { QDir current = QDir::current(); objdb = new FWObjectDatabase(); qDebug() << "Data load starts"; loadDataFile("test1.fwb"); qDebug() << "Data loaded"; QString full_output_file_name = QString("%1/test1.fw").arg(current.path()); QStringList args; args << "-o" << full_output_file_name << "test1"; if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file full_output_file_name QFileInfo fi(full_output_file_name); CPPUNIT_ASSERT_MESSAGE("Generated file " + full_output_file_name.toStdString() + " not found", fi.exists() == true); QString res = Configlet::findConfigletInFile( "top_comment", full_output_file_name); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + full_output_file_name) != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; } // same as the previous but different output file name void GeneratedScriptTest::minusOTest2() { QDir current = QDir::current(); objdb = new FWObjectDatabase(); loadDataFile("test1.fwb"); QString full_output_file_name = QString("%1/foo1.fw").arg(current.path()); QStringList args; args << "-o" << full_output_file_name << "test1"; if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file full_output_file_name QFileInfo fi(full_output_file_name); CPPUNIT_ASSERT_MESSAGE("Generated file " + full_output_file_name.toStdString() + " not found", fi.exists() == true); QString res = Configlet::findConfigletInFile( "top_comment", full_output_file_name); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + full_output_file_name) != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") == -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; } // if both -d and -o are present, -o takes precedence void GeneratedScriptTest::minusDminusOTest() { QDir current = QDir::current(); objdb = new FWObjectDatabase(); loadDataFile("test1.fwb"); QString full_output_file_name = QString("%1/test1.fw").arg(current.path()); if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); QStringList args; args << "-d" << "/tmp" << "-o" << full_output_file_name << "test1"; CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file full_output_file_name QFileInfo fi(full_output_file_name); CPPUNIT_ASSERT_MESSAGE("Generated file " + full_output_file_name.toStdString() + " not found", fi.exists() == true); QString res = Configlet::findConfigletInFile( "top_comment", full_output_file_name); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + full_output_file_name) != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; QDir::setCurrent(current.path()); } // output file name is set in firewall settins to foo.fw void GeneratedScriptTest::outputFileNameOptionTest1() { QDir current = QDir::current(); objdb = new FWObjectDatabase(); loadDataFile("test1.fwb"); QString full_output_file_name = "foo.fw"; QStringList args; args << "test1-1"; if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file full_output_file_name QFileInfo fi(full_output_file_name); CPPUNIT_ASSERT_MESSAGE("Generated file " + full_output_file_name.toStdString() + " not found", fi.exists() == true); QString res = Configlet::findConfigletInFile( "top_comment", full_output_file_name); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + full_output_file_name) != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") == -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; } // output file name is set in firewall settins to /tmp/foo.fw void GeneratedScriptTest::outputFileNameOptionTest2() { QDir current = QDir::current(); objdb = new FWObjectDatabase(); loadDataFile("test1.fwb"); QString full_output_file_name = "/tmp/foo.fw"; QStringList args; args << "test1-2"; if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file full_output_file_name QFileInfo fi(full_output_file_name); CPPUNIT_ASSERT_MESSAGE("Generated file " + full_output_file_name.toStdString() + " not found", fi.exists() == true); QString res = Configlet::findConfigletInFile( "top_comment", full_output_file_name); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + full_output_file_name) != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") == -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; } // output file name is set in firewall settins to foo.fw but is overridden // by -o option to a file name with absolute path void GeneratedScriptTest::outputFileNameOptionTest3() { QDir current = QDir::current(); objdb = new FWObjectDatabase(); loadDataFile("test1.fwb"); QString full_output_file_name = QString("%1/bar.fw").arg(current.path()); if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); QStringList args; args << "-o" << full_output_file_name << "test1-1"; if (QFile::exists(full_output_file_name)) QFile::remove(full_output_file_name); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file full_output_file_name QFileInfo fi(full_output_file_name); CPPUNIT_ASSERT_MESSAGE("Generated file " + full_output_file_name.toStdString() + " not found", fi.exists() == true); QString res = Configlet::findConfigletInFile( "top_comment", full_output_file_name); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + full_output_file_name) != -1); CPPUNIT_ASSERT(res.indexOf("# files: * test1.fw") == -1); CPPUNIT_ASSERT(res.indexOf("# files: * test2.fw") == -1); delete objdb; } fwbuilder-5.1.0.3599/src/unit_tests/compilerLibTest/0000755000175000017500000000000011733011756023067 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/compilerLibTest/interfacePropertiesTests.pro0000644000175000017500000000023011733011756030644 0ustar sylvestresylvestreinclude(../tests_common.pri) TARGET = interfacePropertiesTest SOURCES = interfacePropertiesTest.cpp tests_main.cpp HEADERS = interfacePropertiesTest.h fwbuilder-5.1.0.3599/src/unit_tests/compilerLibTest/test.fwb0000644000175000017500000027717311733011756024567 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/compilerLibTest/interfacePropertiesTest.h0000644000175000017500000000614511733011756030123 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivkiy a2k0001@gmail.com $Id: interfaceProperties.h 2043 2009-12-06 01:10:10Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INTERFACEPROPERTIESTEST #define INTERFACEPROPERTIESTEST #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include #include #include class interfacePropertiesTest: public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *db; void isValidVlanInterfaceNameLinuxFamilies(interfaceProperties *int_prop); public: //interfaceProperties( std::string name ) : CppUnit::TestCase( name ) {} interfaceProperties* getIntProps(const QString &os); void validateInterfaceNameCommon(); void validateInterfaceNameLinux(); void validateInterfaceNameProCurve(); void validateInterface(); void isEligibleForCluster(); void isValidVlanInterfaceNameLinux24(); void isValidVlanInterfaceNameOpenWRT(); void isValidVlanInterfaceNameDDWRT1(); void isValidVlanInterfaceNameDDWRT2(); void isValidVlanInterfaceNameSecuwall(); void isValidVlanInterfaceNameBSD(); void isValidVlanInterfaceNameIOS(); void isValidVlanInterfaceNamePIX(); void isValidVlanInterfaceNameProCurve(); void validateInterfaceProCurve(); void testManageIpAddresses(); void testManageIpAddressesCluster(); void setUp(); CPPUNIT_TEST_SUITE(interfacePropertiesTest); CPPUNIT_TEST(validateInterfaceNameCommon); CPPUNIT_TEST(validateInterfaceNameLinux); CPPUNIT_TEST(validateInterfaceNameProCurve); CPPUNIT_TEST(validateInterface); CPPUNIT_TEST(isEligibleForCluster); CPPUNIT_TEST(isValidVlanInterfaceNameLinux24); CPPUNIT_TEST(isValidVlanInterfaceNameOpenWRT); CPPUNIT_TEST(isValidVlanInterfaceNameDDWRT1); CPPUNIT_TEST(isValidVlanInterfaceNameDDWRT2); CPPUNIT_TEST(isValidVlanInterfaceNameSecuwall); CPPUNIT_TEST(isValidVlanInterfaceNameBSD); CPPUNIT_TEST(isValidVlanInterfaceNameIOS); CPPUNIT_TEST(isValidVlanInterfaceNamePIX); CPPUNIT_TEST(testManageIpAddresses); CPPUNIT_TEST(testManageIpAddressesCluster); CPPUNIT_TEST_SUITE_END(); }; #endif fwbuilder-5.1.0.3599/src/unit_tests/compilerLibTest/tests_main.cpp0000644000175000017500000000277011733011756025747 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivkiy a2k0001@gmail.com $Id: main.cpp 2039 2009-12-05 20:16:44Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "common/init.cpp" #include "interfacePropertiesTest.h" #include "fwbuilder/Constants.h" #include #include #include //QString user_name; int main(int, char **argv) { init(argv); init(); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( interfacePropertiesTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/compilerLibTest/interfacePropertiesTest.cpp0000644000175000017500000006005511733011756030456 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivkiy a2k0001@gmail.com $Id: interfaceProperties.cpp 2043 2009-12-06 01:10:10Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "interfacePropertiesTest.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Constants.h" #include #include using namespace std; using namespace libfwbuilder; using namespace CppUnit; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; interfaceProperties* interfacePropertiesTest::getIntProps(const QString &os) { Resources* os_res = Resources::os_res[os.toStdString()]; string os_family = os.toStdString(); if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); return interfacePropertiesObjectFactory::getInterfacePropertiesObject(os_family); } void interfacePropertiesTest::setUp() { db = new FWObjectDatabase(); } void interfacePropertiesTest::validateInterfaceNameCommon() { QString err; Firewall fw; fw.setStr("host_OS", "unknown"); db->add(&fw); Interface* iface = Interface::cast(db->create(Interface::TYPENAME)); fw.add(iface); iface->getOptionsObject()->setStr("type", "ethernet"); interfaceProperties * int_prop = getIntProps("unknown"); CPPUNIT_ASSERT(int_prop != NULL); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "eth0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "bar0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "vlan100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "Vlan100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "VlAn100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo 0", err) == false); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo-1", err) == false); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo 12345", err) == false); iface->getOptionsObject()->setStr("type", "bridge"); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "br0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "Br0", err) == true); // all OS except Linux and possibly some other do not permit // interface name with "-" CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "br-lan", err) == false); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "br 200", err) == false); } void interfacePropertiesTest::validateInterfaceNameLinux() { QString err; Firewall fw; fw.setStr("host_OS", "linux24"); db->add(&fw); Interface* iface = Interface::cast(db->create(Interface::TYPENAME)); fw.add(iface); iface->getOptionsObject()->setStr("type", "ethernet"); interfaceProperties * int_prop = getIntProps("linux24"); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "eth0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "bar0", err) == true); // we do not have special type for p2p interfaces yet // Linux permits "-" in interface names (see #1856) CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "ppp-dsl", err) == true); iface->getOptionsObject()->setStr("type", "8021q"); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "vlan100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "Vlan100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "VlAn100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo 0", err) == false); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "foo 12345", err) == false); iface->getOptionsObject()->setStr("type", "bridge"); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "br0", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "Br0", err) == true); // Linux permits "-" in interface names (see #1856) CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "br-lan", err) == true); // spaces are not permitted CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "br 200", err) == false); } void interfacePropertiesTest::validateInterfaceNameProCurve() { QString err; Firewall fw; fw.setStr("host_OS", "procurve"); db->add(&fw); Interface* iface = Interface::cast(db->create(Interface::TYPENAME)); fw.add(iface); iface->getOptionsObject()->setStr("type", "ethernet"); interfaceProperties * int_prop = getIntProps("procurve"); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "a1", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "b1", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "A1", err) == true); // basicValidateInterfaceName() only checks name format, // it does not check if port number makes sense CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "A1234567890", err) == true); // "-" is not permitted CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "vlan-100", err) == false); // but space is permitted CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "vlan 100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "Vlan 100", err) == true); CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "VlAn 100", err) == true); // basicValidateInterfaceName() only checks name format, // it does not check if vlan ID is valid. CPPUNIT_ASSERT(int_prop->basicValidateInterfaceName( iface, "VlAn 1000000000", err) == true); } void interfacePropertiesTest::validateInterface() { string host_OS = "linux24"; Resources* os_res = Resources::os_res[host_OS]; string os_family = host_OS; if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); interfaceProperties * int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject(os_family); CPPUNIT_ASSERT(int_prop != NULL); QString err; Cluster *cluster1 = Cluster::cast(db->create(Cluster::TYPENAME)); Interface *parent1 = Interface::cast(db->create(Interface::TYPENAME)); Interface *iface1 = Interface::cast(db->create(Interface::TYPENAME)); db->add(cluster1); db->add(parent1); parent1->add(iface1, false); parent1->getOptionsObject()->setStr("type", "eternet"); iface1->setUnnumbered(false); iface1->getOptionsObject()->setStr("type", "ethernet"); cluster1->setStr("host_OS", host_OS); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(cluster1), dynamic_cast(iface1), false, err) == true ); iface1->setUnnumbered(true); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(cluster1), dynamic_cast(iface1), false, err) == true ); parent1->getOptionsObject()->setStr("type", "bonding"); iface1->setUnnumbered(false); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(cluster1), dynamic_cast(iface1), false, err) == false ); parent1->getOptionsObject()->setStr("type", "bridge"); iface1->setUnnumbered(false); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(cluster1), dynamic_cast(iface1), false, err) == false ); Firewall fw; fw.setStr("host_OS", host_OS); db->add(&fw); Interface* parent = Interface::cast(db->create(Interface::TYPENAME)); Interface* iface = Interface::cast(db->create(Interface::TYPENAME)); Interface* subiface = Interface::cast(db->create(Interface::TYPENAME)); fw.add(parent); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(parent), dynamic_cast(iface), true, err) == false); parent->getOptionsObject()->setStr("type", "bridge"); iface->getOptionsObject()->setStr("type", "ethernet"); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(parent), FWObject::cast(iface), true, err) == true); iface->getOptionsObject()->setStr("type", "ethernet"); iface->add(subiface); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(parent), dynamic_cast(iface), false, err) == false); iface->remove(subiface); Cluster *cluster = Cluster::cast(db->create(Cluster::TYPENAME)); iface->setName("vlan0"); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(cluster), dynamic_cast(iface), false, err) == true); iface->setName("vlan34324"); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(cluster), dynamic_cast(iface), false, err) == false); parent->setName("vlan"); parent->getOptionsObject()->setStr("type", "bridge"); iface->setName("vlan1"); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(parent), dynamic_cast(iface), false, err) == true); IPv4 *adr = IPv4::cast(db->create(IPv4::TYPENAME)); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(adr), dynamic_cast(iface), false, err) == false); parent->setName("notAVlan"); parent->getOptionsObject()->setStr("type", "ethernet"); iface->setName("vlan1"); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(parent), dynamic_cast(iface), false, err) == true); iface->setName("eth0"); CPPUNIT_ASSERT(int_prop->validateInterface(dynamic_cast(parent), dynamic_cast(iface), false, err) == false); } void interfacePropertiesTest::isEligibleForCluster() { Resources* os_res = Resources::os_res["linux24"]; string os_family = "linux24"; if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); interfaceProperties * int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject(os_family); CPPUNIT_ASSERT(int_prop != NULL); Firewall *fw1 = Firewall::cast(db->create(Firewall::TYPENAME)); fw1->setName("iface"); fw1->setStr("host_OS", "unknown"); db->add(fw1); Interface *parent1 = Interface::cast(db->create(Interface::TYPENAME)); Interface *iface1 = Interface::cast(db->create(Interface::TYPENAME)); fw1->add(parent1); parent1->add(iface1); iface1->getOptionsObject()->setStr("type", "ethernet"); parent1->getOptionsObject()->setStr("type", "ethernet"); CPPUNIT_ASSERT(int_prop->isEligibleForCluster(iface1) == true); iface1->getOptionsObject()->setStr("type", "ethernet"); parent1->getOptionsObject()->setStr("type", "bridge"); CPPUNIT_ASSERT(int_prop->isEligibleForCluster(iface1) == false); iface1->getOptionsObject()->setStr("type", "bonding"); parent1->getOptionsObject()->setStr("type", "ethernet"); CPPUNIT_ASSERT(int_prop->isEligibleForCluster(iface1) == true); iface1->getOptionsObject()->setStr("type", "bridge"); parent1->getOptionsObject()->setStr("type", "ethernet"); CPPUNIT_ASSERT(int_prop->isEligibleForCluster(iface1) == true); iface1->getOptionsObject()->setStr("type", "8021q"); parent1->getOptionsObject()->setStr("type", "ethernet"); CPPUNIT_ASSERT(int_prop->isEligibleForCluster(iface1) == true); iface1->getOptionsObject()->setStr("type", "ethernet"); parent1->getOptionsObject()->setStr("type", "bridge"); CPPUNIT_ASSERT(int_prop->isEligibleForCluster(iface1) == false); Firewall *fw = Firewall::cast(db->create(Firewall::TYPENAME)); fw->setName("iface"); Interface *iface = Interface::cast(db->create(Interface::TYPENAME)); iface->setName("iface1"); Interface *subface = Interface::cast(db->create(Interface::TYPENAME)); subface->setName("iface"); fw->add(iface); iface->getOptionsObject()->setStr("type", "bonding"); iface->add(subface); CPPUNIT_ASSERT ( interfaceProperties().isEligibleForCluster(subface) == false ); iface->getOptionsObject()->setStr("type", "ethernet"); CPPUNIT_ASSERT ( interfaceProperties().isEligibleForCluster(iface) == false ); } void interfacePropertiesTest::isValidVlanInterfaceNameLinuxFamilies( interfaceProperties * int_prop) { QString err, parent = "eth0"; /* sub parent result vlan101 eth0 true eth0.101 eth0 true foo eth0 false foo101 eth0 false eth0.bar eth0 false eth0.99999 eth0 false eth1.101 eth0 false */ CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("eth0.101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("foo", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("foo101", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("eth0.bar", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("eth0.99999", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("eth1.101", parent, err) == false); parent = "bond1"; CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("bond1.15", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("bond1.515", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("bond1.1205", parent, err) == true); } void interfacePropertiesTest::isValidVlanInterfaceNameLinux24() { isValidVlanInterfaceNameLinuxFamilies(getIntProps("linux24")); } void interfacePropertiesTest::isValidVlanInterfaceNameOpenWRT() { isValidVlanInterfaceNameLinuxFamilies(getIntProps("openwrt")); } void interfacePropertiesTest::isValidVlanInterfaceNameDDWRT1() { isValidVlanInterfaceNameLinuxFamilies(getIntProps("dd-wrt-nvram")); } void interfacePropertiesTest::isValidVlanInterfaceNameDDWRT2() { isValidVlanInterfaceNameLinuxFamilies(getIntProps("dd-wrt-jffs")); } void interfacePropertiesTest::isValidVlanInterfaceNameSecuwall() { isValidVlanInterfaceNameLinuxFamilies(getIntProps("secuwall")); } void interfacePropertiesTest::isValidVlanInterfaceNameBSD() { QString err, parent = "en0"; interfaceProperties *int_prop = getIntProps("openbsd"); /* vlan101 en0 true en0.101 en0 false foo en0 false foo101 en0 false */ CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("eth0.101", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("foo", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("foo101", parent, err) == false); int_prop = getIntProps("freebsd"); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("eth0.101", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("foo", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("foo101", parent, err) == false); } void interfacePropertiesTest::isValidVlanInterfaceNameIOS() { QString err, parent; /* FastEthernet0/1.101 FastEthernet0/1 true vlan101 FastEthernet0/1 false Ethernet0/0.101 FastEthernet0/1 false Ethernet0/0.99999 Ethernet0/0 false */ interfaceProperties *int_prop = getIntProps("ios"); parent = "FastEthernet0/1"; CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("FastEthernet0/1.101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan101", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("Ethernet0/0.101", parent, err) == false); parent = "Ethernet0/0"; CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("Ethernet0/0.99999", parent, err) == false); } void interfacePropertiesTest::isValidVlanInterfaceNamePIX() { QString err, parent; interfaceProperties *int_prop = getIntProps("pix_os"); parent = "FastEthernet0/1"; CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("FastEthernet0/1.101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan101", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("Ethernet0/0.101", parent, err) == false); parent = "Ethernet0/0"; CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("Ethernet0/0.99999", parent, err) == false); } void interfacePropertiesTest::isValidVlanInterfaceNameProCurve() { QString err, parent; /* * As of 05/10/2010 we do not restrict interfaces for ProCurve * Vlan interface name parent ok/not ok vlan 2 anything true vlan2 anything false Ethernet0/0.101 FastEthernet0/1 false Ethernet0/0.99999 Ethernet0/0 false */ interfaceProperties *int_prop = getIntProps("procurve"); parent = "FastEthernet0/1"; CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan 2", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("VLAN 2", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("Vlan 2", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan2", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan 101", parent, err) == true); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("vlan101", parent, err) == false); CPPUNIT_ASSERT (int_prop->isValidVlanInterfaceName("Ethernet0/0.101", parent, err) == false); } void interfacePropertiesTest::validateInterfaceProCurve() { string host_OS = "procurve"; Resources* os_res = Resources::os_res[host_OS]; string os_family = host_OS; if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); interfaceProperties * int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject(os_family); CPPUNIT_ASSERT(int_prop != NULL); QString err; Firewall fw; fw.setStr("host_OS", host_OS); db->add(&fw); Interface* parent = Interface::cast(db->create(Interface::TYPENAME)); Interface* iface = Interface::cast(db->create(Interface::TYPENAME)); Interface* subiface = Interface::cast(db->create(Interface::TYPENAME)); fw.add(parent); iface->setName("vlan 2"); CPPUNIT_ASSERT(int_prop->validateInterface(&fw, iface, false, err) == true); iface->setName("vlan 34324"); CPPUNIT_ASSERT(int_prop->validateInterface(&fw, iface, false, err) == false); } void interfacePropertiesTest::testManageIpAddresses() { UpgradePredicate upgrade_predicate; string file_name = "test.fwb"; db->setReadOnly( false ); db->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); db->setFileName(file_name); db->reIndex(); FWObject *fw = db->findObjectByName(Firewall::TYPENAME, "fw1"); CPPUNIT_ASSERT(fw != NULL); Interface *intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "eth0")); interfaceProperties *int_prop = getIntProps("linux24"); QStringList update_addresses; QStringList ignore_addresses; CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == true); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "lo")); CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == true); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "eth1")); // dyn CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == false); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "eth2")); // bridge port CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == false); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "eth3")); // bonding intf slave CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == false); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "tun0")); // unnumbered CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == false); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "tun*")); // unnumbered CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == false); } void interfacePropertiesTest::testManageIpAddressesCluster() { UpgradePredicate upgrade_predicate; string file_name = "test.fwb"; db->setReadOnly( false ); db->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); db->setFileName(file_name); db->reIndex(); FWObject *fw = db->findObjectByName(Cluster::TYPENAME, "cluster1"); CPPUNIT_ASSERT(fw != NULL); Interface *intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "lo")); intf->getOptionsObject()->setBool("cluster_interface", true); interfaceProperties *int_prop = getIntProps("linux24"); QStringList update_addresses; QStringList ignore_addresses; CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == false); intf = Interface::cast( fw->findObjectByName(Interface::TYPENAME, "eth0")); CPPUNIT_ASSERT( int_prop->manageIpAddresses( intf, update_addresses, ignore_addresses) == true); } fwbuilder-5.1.0.3599/src/unit_tests/FirewallDialogTest/0000755000175000017500000000000011733011756023513 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/FirewallDialogTest/main_FirewallDialogTest.cpp0000644000175000017500000000330111733011756030745 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FirewallDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new FirewallDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/FirewallDialogTest/FirewallDialogTest.pro0000644000175000017500000000030011733011756027753 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = FirewallDialogTest SOURCES += main_FirewallDialogTest.cpp \ FirewallDialogTest.cpp HEADERS += FirewallDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/FirewallDialogTest/FirewallDialogTest.h0000644000175000017500000000260511733011756027414 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: FirewallDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FirewallDialogTest_H #define FirewallDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" #include "fwbuilder/Cluster.h" class FirewallDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; libfwbuilder::Firewall *firewall; bool dialog_rejected; private slots: void initTestCase(); void testDialog(); public slots: void rejectDialog(); }; #endif // FirewallDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/FirewallDialogTest/FirewallDialogTest.cpp0000644000175000017500000001673611733011756027761 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: FirewallDialogTestTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FirewallDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "FirewallDialog.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "FirewallDialogTest.h" #include "fwbuilder/IPService.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; void FirewallDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); mw->resize(1200, 600); QTest::qWait(2000); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); } Library* FirewallDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void FirewallDialogTest::rejectDialog() { QMessageBox *box = dynamic_cast(app->activeModalWidget()); Q_ASSERT(box != NULL); box->reject(); } void FirewallDialogTest::testDialog() { firewall = Firewall::cast( om->createObject( FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); QTest::qWait(1000); FirewallDialog *dialog = mw->findChild("w_FirewallDialog"); QVERIFY(dialog != NULL); QLineEdit *obj_name = dialog->findChild("obj_name"); TextEditWidget *comment = dialog->findChild("comment"); QComboBox *platform = dialog->findChild("platform"); QComboBox *version = dialog->findChild("version"); QComboBox *hostOS = dialog->findChild("hostOS"); QCheckBox *inactive = dialog->findChild("inactive"); QLabel *last_modified = dialog->findChild("last_modified"); QLabel *last_compiled = dialog->findChild("last_compiled"); QLabel *last_installed = dialog->findChild("last_installed"); // setting object name obj_name->clear(); QTest::keyClicks(obj_name, "TestFirewallName"); QTimer::singleShot(10, this, SLOT(rejectDialog())); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(firewall->getName() == "TestFirewallName"); // setting comment comment->clear(); QTest::qWait(2000); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(obj_name, Qt::LeftButton); //QTest::mouseClick(comment, Qt::LeftButton); //QTest::keyClick(comment, Qt::Key_Tab); qDebug() << "Dialog comment text=" << comment->toPlainText(); qDebug() << "Object comment=" << QString(firewall->getComment().c_str()); QVERIFY (firewall->getComment() == "Test comment"); // switching inactive QTest::mouseClick(inactive, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); QVERIFY(firewall->getInactive() == true); QTest::mouseClick(inactive, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); QVERIFY(firewall->getInactive() == false); // Testing that platform changes in firewall object and // version and hostOS combo boxes changes their values // when changing platform string oldplatform = firewall->getStr("platform"); bool versionChanges = false; bool osChanges = false; QString versionstr = version->currentText(); QString hostOSstr = hostOS->currentText(); for (int i=0; icount(); i++) { if (platform->itemText(i).isEmpty()) continue; oldplatform = firewall->getStr("platform"); platform->setCurrentIndex(i); dialog->changed(); QVERIFY2(firewall->getStr("platform") != oldplatform, oldplatform.c_str()); if (version->currentText() != versionstr) versionChanges = true; if (hostOS->currentText() != hostOSstr) osChanges = true; } QVERIFY(osChanges); QVERIFY(versionChanges); // setting platform to iptables to test version changing int iptidx = -1; for (int i=0; icount(); i++) { if (platform->itemText(i) == "iptables") { iptidx = i; break; } } platform->setCurrentIndex(iptidx); dialog->changed(); version->setCurrentIndex(0); dialog->changed(); for (int i=1; icount(); i++) { string oldversion = firewall->getStr("version"); version->setCurrentIndex(i); dialog->changed(); QVERIFY(oldversion != firewall->getStr("version")); } // Checking that host OS in firewall object changes when switching // it in combo box hostOS->setCurrentIndex(0); dialog->changed(); for (int i=1; icount(); i++) { string oldos = firewall->getStr("host_OS"); hostOS->setCurrentIndex(i); dialog->changed(); QVERIFY(oldos != firewall->getStr("host_OS")); } // Checking last_modified, last_compiled and last_installed labels QDateTime dt; time_t t; firewall->setInt("lastModified", 0); dialog->changed(); QVERIFY(last_modified->text() == "-"); firewall->setInt("lastModified", 123456789); t = 123456789; dt.setTime_t(t); dialog->changed(); QVERIFY(last_modified->text() == dt.toString()); firewall->setInt("lastCompiled", 0); dialog->changed(); QVERIFY(last_compiled->text() == "-"); firewall->setInt("lastCompiled", 123456789); t = 123456789; dt.setTime_t(t); dialog->changed(); QVERIFY(last_compiled->text() == dt.toString()); firewall->setInt("lastInstalled", 0); dialog->changed(); QVERIFY(last_installed->text() == "-"); firewall->setInt("lastInstalled", 123456789); t = 123456789; dt.setTime_t(t); dialog->changed(); QVERIFY(last_installed->text() == dt.toString()); } fwbuilder-5.1.0.3599/src/unit_tests/InetAddrMaskTest/0000755000175000017500000000000011733011756023134 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/InetAddrMaskTest/InetAddrMaskTest.h0000644000175000017500000000331511733011756026455 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INETADDRMASKTEST_H #define INETADDRMASKTEST_H #include #include "fwbuilder/InetAddrMask.h" #include class InetAddrMaskTest : public CppUnit::TestFixture { public: std::string vectorInetAddrMaskToString( std::vector vect); void testIntToInetAddr(); void testStringToInetAddr(); void testStringToInetAddrExceptions(); void testStringToInetAddrMask(); void testInetAddressOps(); void testIPv4Overlap(); CPPUNIT_TEST_SUITE(InetAddrMaskTest); CPPUNIT_TEST(testStringToInetAddrExceptions); CPPUNIT_TEST(testIntToInetAddr); CPPUNIT_TEST(testStringToInetAddr); CPPUNIT_TEST(testStringToInetAddrMask); CPPUNIT_TEST(testInetAddressOps); CPPUNIT_TEST(testIPv4Overlap); CPPUNIT_TEST_SUITE_END(); }; #endif // INETADDRMASKTEST_H fwbuilder-5.1.0.3599/src/unit_tests/InetAddrMaskTest/main.cpp0000644000175000017500000000265011733011756024567 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "InetAddrMaskTest.h" #include "fwbuilder/FWObjectDatabase.h" #include using namespace libfwbuilder; int fwbdebug = 0; //QString user_name; std::string platform; int main( int, char** argv) { //init(argv); init(); CppUnit::TextUi::TestRunner runner; runner.addTest( InetAddrMaskTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/InetAddrMaskTest/InetAddrMaskTest.cpp0000644000175000017500000002666311733011756027023 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "InetAddrMaskTest.h" #include using namespace libfwbuilder; using namespace std; void InetAddrMaskTest::testIntToInetAddr() { InetAddr *sa1 = new InetAddr(0); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "0.0.0.0"); sa1 = new InetAddr(AF_INET, 0); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "0.0.0.0"); sa1 = new InetAddr(1); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "128.0.0.0"); sa1 = new InetAddr(24); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "255.255.255.0"); } void InetAddrMaskTest::testStringToInetAddr() { InetAddr *sa1 = new InetAddr("0.0.0.1"); CPPUNIT_ASSERT_MESSAGE("0.0.0.1 -> " + sa1->toString(), sa1->toString() == "0.0.0.1"); sa1 = new InetAddr("0.0.0.0"); CPPUNIT_ASSERT_MESSAGE("0.0.0.0 -> " + sa1->toString(), sa1->toString() == "0.0.0.0"); sa1 = new InetAddr("1.2.3.4"); CPPUNIT_ASSERT_MESSAGE("1.2.3.4 -> " + sa1->toString(), sa1->toString() == "1.2.3.4"); sa1 = new InetAddr("0.0.1"); CPPUNIT_ASSERT_MESSAGE("0.0.1 -> " + sa1->toString(), sa1->toString() == "0.0.1.0"); sa1 = new InetAddr("0.1"); CPPUNIT_ASSERT_MESSAGE("0.1 -> " + sa1->toString(), sa1->toString() == "0.1.0.0"); // "1" ---> "128.0.0.0" I am not sure this is correct sa1 = new InetAddr("1"); CPPUNIT_ASSERT_MESSAGE("1 -> " + sa1->toString(), sa1->toString() == "128.0.0.0"); sa1 = new InetAddr("1.0"); CPPUNIT_ASSERT_MESSAGE("1.0 -> " + sa1->toString(), sa1->toString() == "1.0.0.0"); sa1 = new InetAddr("1.0.0"); CPPUNIT_ASSERT_MESSAGE("1.0.0 -> " + sa1->toString(), sa1->toString() == "1.0.0.0"); sa1 = new InetAddr("255.255.255.255"); CPPUNIT_ASSERT_MESSAGE("255.255.255.255 -> " + sa1->toString(), sa1->toString() == "255.255.255.255"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true); sa1 = new InetAddr("255.255.255.128"); CPPUNIT_ASSERT_MESSAGE("255.255.255.128 -> " + sa1->toString(), sa1->toString() == "255.255.255.128"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true); sa1 = new InetAddr("255.255.255.0"); CPPUNIT_ASSERT_MESSAGE("255.255.255.0 -> " + sa1->toString(), sa1->toString() == "255.255.255.0"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true); sa1 = new InetAddr("255.255.0.0"); CPPUNIT_ASSERT_MESSAGE("255.255.0.0 -> " + sa1->toString(), sa1->toString() == "255.255.0.0"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true); sa1 = new InetAddr("255.0.0.0"); CPPUNIT_ASSERT_MESSAGE("255.0.0.0 -> " + sa1->toString(), sa1->toString() == "255.0.0.0"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true); sa1 = new InetAddr("0.0.0.0"); CPPUNIT_ASSERT_MESSAGE("0.0.0.0 -> " + sa1->toString(), sa1->toString() == "0.0.0.0"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == true); sa1 = new InetAddr("255.0.255.0"); CPPUNIT_ASSERT_MESSAGE("255.0.255.0 -> " + sa1->toString(), sa1->toString() == "255.0.255.0"); CPPUNIT_ASSERT(sa1->isValidV4Netmask() == false); } void InetAddrMaskTest::testStringToInetAddrExceptions() { CPPUNIT_ASSERT_NO_THROW(new InetAddr("1.2.3.4")); CPPUNIT_ASSERT_NO_THROW(new InetAddr("1.2.3.4/24")); CPPUNIT_ASSERT_THROW(new InetAddr("1.2.3.4/40"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr("300.300.300.300"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr("1.2.3.4.5"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr("foo.bar"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr("1.2.foo.bar"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr(40), FWException); CPPUNIT_ASSERT_NO_THROW(new InetAddr(24)); CPPUNIT_ASSERT_THROW(new InetAddr((char*)(NULL)), FWException); CPPUNIT_ASSERT_NO_THROW(new InetAddr(0)); } void InetAddrMaskTest::testInetAddressOps() { InetAddr x1("1.2.3.4"); InetAddr y1(24); InetAddr z1 = x1 & y1; CPPUNIT_ASSERT(z1.toString() == "1.2.3.0"); CPPUNIT_ASSERT( (~y1).toString() == "0.0.0.255"); InetAddr z2 = z1 | ~y1; CPPUNIT_ASSERT(z2.toString() == "1.2.3.255"); InetAddr z3 = z1 | ~y1; CPPUNIT_ASSERT(z3.toString() == "1.2.3.255"); InetAddr z4 = x1 + 1; CPPUNIT_ASSERT(z4.toString() == "1.2.3.5"); InetAddr z5 = z4 - 1; CPPUNIT_ASSERT(z5.toString() == "1.2.3.4"); CPPUNIT_ASSERT(z5 == x1); InetAddr x2("255.255.255.255"); InetAddr z6 = x2 + 1; CPPUNIT_ASSERT(z6.toString() == "0.0.0.0"); InetAddr x3("1.2.2.4"); CPPUNIT_ASSERT(x3 < x1); CPPUNIT_ASSERT(x1 > x3); } void InetAddrMaskTest::testStringToInetAddrMask() { string sa; InetAddrMask *a1 = new InetAddrMask(); CPPUNIT_ASSERT(a1->toString() == "0.0.0.0/0.0.0.0"); sa = a1->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="0.0.0.0"); // 0.0.0.0/0.0.0.0 has maximum dimension (represents all possible addresses) CPPUNIT_ASSERT(a1->dimension() == (((unsigned int)1)<<31)-1); InetAddrMask *a2 = new InetAddrMask(InetAddr("1.1.1.1"), InetAddr("255.255.255.0")); sa = a2->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="1.1.1.0"); sa = a2->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.255.255.0"); CPPUNIT_ASSERT(a2->dimension()==256); CPPUNIT_ASSERT(a2->toString()=="1.1.1.0/255.255.255.0"); InetAddrMask *a3 = new InetAddrMask(string("1.1.1.1")); sa = a3->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="1.1.1.1"); sa = a3->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.255.255.255"); CPPUNIT_ASSERT(a3->dimension()==1); CPPUNIT_ASSERT(a2->belongs( *(a3->getAddressPtr()) )); InetAddrMask *a4 = new InetAddrMask(*a3); sa = a4->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="1.1.1.1"); sa = a4->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.255.255.255"); CPPUNIT_ASSERT(a4->dimension()==1); a4->setAddress(InetAddr("2.2.2.2")); sa = a4->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="2.2.2.2"); sa = a4->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.255.255.255"); CPPUNIT_ASSERT(a4->dimension()==1); a4->setNetmask(InetAddr("255.255.0.0")); sa = a4->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="2.2.2.2"); sa = a4->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.255.0.0"); CPPUNIT_ASSERT(a4->dimension()==256*256); a4->setNetmask(InetAddr("8")); sa = a4->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="2.2.2.2"); sa = a4->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.0.0.0"); CPPUNIT_ASSERT(a4->dimension()==256*256*256); CPPUNIT_ASSERT_THROW(a4->setNetmask(InetAddr("40")), FWException); // a4 should not have changed sa = a4->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="2.2.2.2"); sa = a4->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.0.0.0"); CPPUNIT_ASSERT(a4->dimension()==256*256*256); InetAddrMask *a5 = new InetAddrMask(string("1.1.1.1/24")); sa = a5->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="1.1.1.1"); sa = a5->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="255.255.255.0"); CPPUNIT_ASSERT(a5->dimension()==256); } string InetAddrMaskTest::vectorInetAddrMaskToString(vector vect) { string res; vector::iterator it; for (it=vect.begin(); it!=vect.end(); ++it) { res += it->toString() + " "; } return res; } void InetAddrMaskTest::testIPv4Overlap() { string res; res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")) ) ); CPPUNIT_ASSERT(res=="10.0.0.0/255.255.255.0 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")), InetAddrMask(InetAddr("10.0.0.255"), InetAddr("255.255.255.255")) ) ); CPPUNIT_ASSERT(res=="10.0.0.255/255.255.255.255 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.255"), InetAddr("255.255.255.255")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")) ) ); CPPUNIT_ASSERT(res=="10.0.0.255/255.255.255.255 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.254")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")) ) ); CPPUNIT_ASSERT(res=="10.0.0.0/255.255.255.254 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.254")) ) ); CPPUNIT_ASSERT(res=="10.0.0.0/255.255.255.254 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.252"), InetAddr("255.255.255.252")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")) ) ); CPPUNIT_ASSERT(res=="10.0.0.252/255.255.255.252 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")), InetAddrMask(InetAddr("10.0.0.252"), InetAddr("255.255.255.252")) ) ); CPPUNIT_ASSERT(res=="10.0.0.252/255.255.255.252 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.128"), InetAddr("255.255.255.252")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")) ) ); CPPUNIT_ASSERT(res=="10.0.0.128/255.255.255.252 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0")), InetAddrMask(InetAddr("10.0.0.128"), InetAddr("255.255.255.252")) ) ); CPPUNIT_ASSERT(res=="10.0.0.128/255.255.255.252 "); // test specifically for #1934 res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.2"), InetAddr("255.255.255.254")), InetAddrMask(InetAddr("10.0.0.0"), InetAddr("255.255.255.0"))) ); CPPUNIT_ASSERT(res=="10.0.0.2/255.255.255.254 "); res = vectorInetAddrMaskToString( libfwbuilder::getOverlap( InetAddrMask(InetAddr("10.0.0.2"), InetAddr("255.255.255.254")), InetAddrMask(InetAddr("0.0.0.0"), InetAddr("0.0.0.0"))) ); CPPUNIT_ASSERT(res=="10.0.0.2/255.255.255.254 "); } fwbuilder-5.1.0.3599/src/unit_tests/InetAddrMaskTest/InetAddrMaskTest.pro0000644000175000017500000000111711733011756027024 0ustar sylvestresylvestreinclude(../../../qmake.inc) QT -= core gui TARGET = InetAddrMaskTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS LIBS += $$CPPUNIT_LIBS SOURCES += main.cpp InetAddrMaskTest.cpp HEADERS += InetAddrMaskTest.h INCLUDEPATH += ../../.. ../../libfwbuilder/src DEPENDPATH += ../../libfwbuilder/src LIBS += ../../libfwbuilder/src/fwbuilder/libfwbuilder.a run_tests.commands = echo "Running tests..." && ./${TARGET} run_tests.depends = all clean_tests.depends = clean build_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/InterfaceDialogTest/0000755000175000017500000000000011733011756023646 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/InterfaceDialogTest/InterfaceDialogTest.pro0000644000175000017500000000027411733011756030253 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = InterfaceDialogTest SOURCES += main_InterfaceDialogTest.cpp \ InterfaceDialogTest.cpp HEADERS += InterfaceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/InterfaceDialogTest/main_InterfaceDialogTest.cpp0000644000175000017500000000330211733011756031234 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "InterfaceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new InterfaceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/InterfaceDialogTest/InterfaceDialogTest.cpp0000644000175000017500000001530311733011756030234 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: InterfaceDialogTestTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "InterfaceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "InterfaceDialog.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "InterfaceDialogTest.h" #include "fwbuilder/IPService.h" using namespace std; using namespace libfwbuilder; void InterfaceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); // mw->resize(1200, 600); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); firewall->setStr("platform", "pix"); // using pix platforms as it supports all dialog options interface = Interface::cast(om->createObject(firewall, Interface::TYPENAME, "TestInterface")); QVERIFY(interface!=NULL); } Library* InterfaceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void InterfaceDialogTest::testDialog() { om->editObject(interface); InterfaceDialog *dialog = mw->findChild("w_InterfaceDialog"); QVERIFY(dialog != NULL); QLineEdit *obj_name = dialog->findChild("obj_name"); QLineEdit *label = dialog->findChild("label"); TextEditWidget *comment = dialog->findChild("comment"); //options: QSpinBox *seclevel = dialog->findChild("seclevel"); QComboBox *netzone = dialog->findChild("netzone"); QCheckBox *management = dialog->findChild("management"); QCheckBox *unprotected = dialog->findChild("unprotected"); QCheckBox *dedicated_failover = dialog->findChild("dedicated_failover"); QRadioButton *regular = dialog->findChild("regular"); QRadioButton *dynamic = dialog->findChild("dynamic"); QRadioButton *unnumbered = dialog->findChild("unnumbered"); // setting object name obj_name->clear(); QTest::keyClicks(obj_name, "TestInterfaceName"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(interface->getName() == "TestInterfaceName"); // setting label label->clear(); QTest::keyClicks(label, "TestInterfaceLabel"); QTest::keyClick(label, Qt::Key_Enter); QVERIFY(interface->getLabel() == "TestInterfaceLabel"); // setting comment comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (interface->getComment() == "Test comment"); // setting security level QTest::mouseClick(seclevel, Qt::LeftButton); QTest::keyClick(seclevel, Qt::Key_Up); QTest::keyClick(seclevel, Qt::Key_Up); QTest::keyClick(seclevel, Qt::Key_Enter); QVERIFY(interface->getSecurityLevel() == 2); // testing management QVERIFY(interface->isManagement() == false); QTest::mouseClick(management, Qt::LeftButton); QVERIFY(interface->isManagement() == true); QTest::mouseClick(management, Qt::LeftButton); QVERIFY(interface->isManagement() == false); // testing unprotected QVERIFY(interface->isUnprotected() == false); QTest::mouseClick(unprotected, Qt::LeftButton); QVERIFY(interface->isUnprotected() == true); QTest::mouseClick(unprotected, Qt::LeftButton); QVERIFY(interface->isUnprotected() == false); // testing dedicated failover QVERIFY(interface->isDedicatedFailover() == false); QTest::mouseClick(dedicated_failover, Qt::LeftButton); QVERIFY(interface->isDedicatedFailover() == true); QTest::mouseClick(dedicated_failover, Qt::LeftButton); QVERIFY(interface->isDedicatedFailover() == false); // testing regular/dynamic/unnumbered switch QTest::mouseClick(regular, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); QVERIFY(interface->isRegular() == true); QVERIFY(interface->isDyn() == false); QVERIFY(interface->isUnnumbered() == false); QTest::mouseClick(dynamic, Qt::LeftButton); QVERIFY(interface->isRegular() == false); QVERIFY(interface->isDyn() == true); QVERIFY(interface->isUnnumbered() == false); QTest::mouseClick(unnumbered, Qt::LeftButton); QVERIFY(interface->isRegular() == false); QVERIFY(interface->isDyn() == false); QVERIFY(interface->isUnnumbered() == true); // testing that changing netzone combo value changed interface's property string zone = interface->getStr("network_zone"); bool changed = false; for(int i=0; icount(); i++) { netzone->setCurrentIndex(i); dialog->changed(); if (interface->getStr("network_zone") != zone) { changed = true; break; } } QVERIFY(changed); } fwbuilder-5.1.0.3599/src/unit_tests/InterfaceDialogTest/InterfaceDialogTest.h0000644000175000017500000000256011733011756027702 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: InterfaceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef InterfaceDialogTest_H #define InterfaceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" #include "fwbuilder/Cluster.h" class InterfaceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; libfwbuilder::Firewall *firewall; libfwbuilder::Interface *interface; private slots: void initTestCase(); void testDialog(); }; #endif // InterfaceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/TCPServiceDialogTest/0000755000175000017500000000000011733011756023715 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/TCPServiceDialogTest/TCPServiceDialogTest.h0000644000175000017500000000241011733011756030012 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: TCPServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef TCPServiceDialogTest_H #define TCPServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class TCPServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testDialog(); }; #endif // TCPServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/TCPServiceDialogTest/TCPServiceDialogTest.cpp0000644000175000017500000002200111733011756030343 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: TCPServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "TCPServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "TCPServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/TCPService.h" #include "TCPServiceDialog.h" using namespace std; using namespace libfwbuilder; void TCPServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* TCPServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void TCPServiceDialogTest::testDialog() { TCPService *service = TCPService::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), TCPService::TYPENAME), TCPService::TYPENAME, "testTCPService")); om->editObject(service); TCPServiceDialog *dialog = mw->findChild("w_TCPServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QCheckBox *fin_s = dialog->findChild("fin_s"); QCheckBox *rst_s = dialog->findChild("rst_s"); QCheckBox *urg_s = dialog->findChild("urg_s"); QCheckBox *syn_s = dialog->findChild("syn_s"); QCheckBox *psh_s = dialog->findChild("psh_s"); QCheckBox *ack_s = dialog->findChild("ack_s"); QCheckBox *psh_m = dialog->findChild("psh_m"); QCheckBox *syn_m = dialog->findChild("syn_m"); QCheckBox *urg_m = dialog->findChild("urg_m"); QCheckBox *fin_m = dialog->findChild("fin_m"); QCheckBox *rst_m = dialog->findChild("rst_m"); QCheckBox *ack_m = dialog->findChild("ack_m"); QCheckBox *established = dialog->findChild("established"); QSpinBox *ss = dialog->findChild("ss"); QSpinBox *se = dialog->findChild("se"); QSpinBox *ds = dialog->findChild("ds"); QSpinBox *de = dialog->findChild("de"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestTCPService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestTCPService"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (service->getComment() == "Test comment"); // checking all small checkboxes QTest::mouseClick(urg_m, Qt::LeftButton); QVERIFY(service->getBool("urg_flag_mask")); QTest::mouseClick(urg_m, Qt::LeftButton); QVERIFY(!service->getBool("urg_flag_mask")); QTest::mouseClick(ack_m, Qt::LeftButton); QVERIFY(service->getBool("ack_flag_mask")); QTest::mouseClick(ack_m, Qt::LeftButton); QVERIFY(!service->getBool("ack_flag_mask")); QTest::mouseClick(psh_m, Qt::LeftButton); QVERIFY(service->getBool("psh_flag_mask")); QTest::mouseClick(psh_m, Qt::LeftButton); QVERIFY(!service->getBool("psh_flag_mask")); QTest::mouseClick(rst_m, Qt::LeftButton); QVERIFY(service->getBool("rst_flag_mask")); QTest::mouseClick(rst_m, Qt::LeftButton); QVERIFY(!service->getBool("rst_flag_mask")); QTest::mouseClick(syn_m, Qt::LeftButton); QVERIFY(service->getBool("syn_flag_mask")); QTest::mouseClick(syn_m, Qt::LeftButton); QVERIFY(!service->getBool("syn_flag_mask")); QTest::mouseClick(fin_m, Qt::LeftButton); QVERIFY(service->getBool("fin_flag_mask")); QTest::mouseClick(fin_m, Qt::LeftButton); QVERIFY(!service->getBool("fin_flag_mask")); QTest::mouseClick(urg_s, Qt::LeftButton); QVERIFY(service->getBool("urg_flag")); QTest::mouseClick(urg_s, Qt::LeftButton); QVERIFY(!service->getBool("urg_flag")); QTest::mouseClick(ack_s, Qt::LeftButton); QVERIFY(service->getBool("ack_flag")); QTest::mouseClick(ack_s, Qt::LeftButton); QVERIFY(!service->getBool("ack_flag")); QTest::mouseClick(psh_s, Qt::LeftButton); QVERIFY(service->getBool("psh_flag")); QTest::mouseClick(psh_s, Qt::LeftButton); QVERIFY(!service->getBool("psh_flag")); QTest::mouseClick(rst_s, Qt::LeftButton); QVERIFY(service->getBool("rst_flag")); QTest::mouseClick(rst_s, Qt::LeftButton); QVERIFY(!service->getBool("rst_flag")); QTest::mouseClick(syn_s, Qt::LeftButton); QVERIFY(service->getBool("syn_flag")); QTest::mouseClick(syn_s, Qt::LeftButton); QVERIFY(!service->getBool("syn_flag")); QTest::mouseClick(fin_s, Qt::LeftButton); QVERIFY(service->getBool("fin_flag")); QTest::mouseClick(fin_s, Qt::LeftButton); QVERIFY(!service->getBool("fin_flag")); QTest::mouseClick(established, Qt::LeftButton, Qt::NoModifier, QPoint(10,10)); QVERIFY(service->getBool("established")); QTest::mouseClick(established, Qt::LeftButton, Qt::NoModifier, QPoint(10,10)); QVERIFY(!service->getBool("established")); // check that it is not possible to set value more than 65535 se->setValue(65530); for (int i=0; i<100; i++) QTest::keyClick(se, Qt::Key_Up); QTest::keyClick(se, Qt::Key_Enter); QVERIFY(service->getSrcRangeEnd() == 65535); ss->setValue(65530); for (int i=0; i<65560; i++) QTest::keyClick(ss, Qt::Key_Up); QTest::keyClick(ss, Qt::Key_Enter); QVERIFY(service->getSrcRangeStart() == 65535); de->setValue(65530); for (int i=0; i<100; i++) QTest::keyClick(de, Qt::Key_Up); QTest::keyClick(de, Qt::Key_Enter); QVERIFY(service->getDstRangeEnd() == 65535); ds->setValue(65530); for (int i=0; i<100; i++) QTest::keyClick(ds, Qt::Key_Up); QTest::keyClick(ds, Qt::Key_Enter); QVERIFY(service->getDstRangeStart() == 65535); // check that range end change when range start is more se->clear(); for (int i=0; i<11; i++) QTest::keyClick(se, Qt::Key_Up); QTest::keyClick(se, Qt::Key_Enter); ss->clear(); for (int i=0; i<21; i++) QTest::keyClick(ss, Qt::Key_Up); QTest::keyClick(ss, Qt::Key_Enter); QVERIFY(ss->value() == se->value()); de->clear(); for (int i=0; i<11; i++) QTest::keyClick(de, Qt::Key_Up); QTest::keyClick(de, Qt::Key_Enter); ds->clear(); for (int i=0; i<21; i++) QTest::keyClick(ds, Qt::Key_Up); QTest::keyClick(ds, Qt::Key_Enter); QVERIFY(ds->value() == de->value()); // check that range end does not change if range start is less ss->setValue(0); se->setValue(0); for (int i=0; i<20; i++) QTest::keyClick(se, Qt::Key_Up); QTest::keyClick(se, Qt::Key_Enter); for (int i=0; i<10; i++) QTest::keyClick(ss, Qt::Key_Up); QTest::keyClick(ss, Qt::Key_Enter); QVERIFY(se->value() == 20); ds->setValue(0); de->setValue(0); for (int i=0; i<20; i++) QTest::keyClick(de, Qt::Key_Up); QTest::keyClick(de, Qt::Key_Enter); for (int i=0; i<10; i++) QTest::keyClick(ds, Qt::Key_Up); QTest::keyClick(ds, Qt::Key_Enter); QVERIFY(de->value() == 20); } fwbuilder-5.1.0.3599/src/unit_tests/TCPServiceDialogTest/TCPServiceDialogTest.pro0000644000175000017500000000030011733011756030357 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = TCPServiceDialogTest SOURCES += main_TCPServiceDialogTest.cpp \ TCPServiceDialogTest.cpp HEADERS += TCPServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/TCPServiceDialogTest/main_TCPServiceDialogTest.cpp0000644000175000017500000000330411733011756031354 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "TCPServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new TCPServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/0000755000175000017500000000000011733011756022427 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/main_ImporterTest.cpp0000644000175000017500000000331511733011756026602 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "ImporterTest.h" #include "fwbuilder/Resources.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" #include #include #include #include "../../../common/init.cpp" int fwbdebug = 0; //QString user_name; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; std::string platform; int main(int argc, char** argv) { QApplication app(argc, argv, false); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( ImporterTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/.gitignore0000644000175000017500000000002711733011756024416 0ustar sylvestresylvestre*.fwb !test_data/*.fwb fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/ImporterTest.cpp0000644000175000017500000002347411733011756025606 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ImporterTest.h" #include "config.h" #include "global.h" #include #include #include #include #include #include #include "Importer.h" #include "IOSImporter.h" #include "IPTImporter.h" #include "FWBTree.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; extern string platform; const char* iptables_sample = "# Generated by iptables-save %VERSION% on Mon Apr 11 15:50:58 2011\n" "*filter\n" ":INPUT ACCEPT [0:0]\n" ":FORWARD ACCEPT [0:0]\n" ":OUTPUT ACCEPT [0:0]\n" ":CHAIN-1-INPUT - [0:0]\n" "-A INPUT -j CHAIN-1-INPUT \n" "-A FORWARD -j CHAIN-1-INPUT \n" "-A CHAIN-1-INPUT -j ACCEPT \n" "COMMIT\n" "# Completed on Mon Apr 11 15:50:58 2011\n"; extern QString findBestVersionMatch(const QString &platform, const QString &discovered_version); class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string &) const { return false; } }; void ImporterTest::setUp() { //init(); FWBTree *tree = new FWBTree(); /* create database */ db = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; db->setReadOnly( false ); db->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); db->setFileName(""); lib = Library::cast(tree->createNewLibrary(db)); lib->setName("User"); logger = new QueueLogger(); // this makes the test compile and link. There is a problem with // dependencies, the test depends on libimport.a and additionally, // PIXImporter.cpp depends on this function that is implemented in // platforms.cpp in libgui.a; however since libgui.a comes before // libimport.a in linker command line, this function does not get // pulled since it is not used anywhere except by this test module // and so linking fails. Making this call creates dependency and // pulls this function at linking time before libimport.a and its // dependencies are considered QString version = findBestVersionMatch("pix", "7.0"); } void ImporterTest::compareResults(QueueLogger* logger, QString expected_result_file_name, QString obtained_result_file_name) { QString result; QStringList obtained_result; while (logger->ready()) result.append(logger->getLine().c_str()); obtained_result = result.split("\n"); QFile rw(obtained_result_file_name); rw.open(QFile::WriteOnly); rw.write(result.toAscii()); rw.close(); QFile rr(expected_result_file_name); rr.open(QFile::ReadOnly); QString result_file = rr.readAll(); QStringList expected_result = result_file.split("\n"); CPPUNIT_ASSERT_MESSAGE( QString( "Sizes of the generated importer output and test files are different.\n" "Expected: %1 (%2)\n" "Obtained: %3 (%4)\n" "diff -u %1 %3 | less -S") .arg(expected_result_file_name).arg(expected_result.size()) .arg(obtained_result_file_name).arg(obtained_result.size()).toStdString(), expected_result.size() == obtained_result.size()); int max_idx = max(expected_result.size(), obtained_result.size()); for (int i=0; i < max_idx; ++i) { QString err = QString("%1:%2:\nExpected: '%3'\nResult: '%4'\n") .arg(expected_result_file_name) .arg(i) .arg(expected_result[i]) .arg(obtained_result[i]); CPPUNIT_ASSERT_MESSAGE( err.toStdString(), obtained_result[i] == expected_result[i]); } } void ImporterTest::compareFwbFiles(QString expected_result_file_name, QString obtained_result_file_name) { QString result; QStringList obtained_result; QFile rr(obtained_result_file_name); rr.open(QFile::ReadOnly); QString result_file = rr.readAll(); rr.close(); obtained_result = result_file.split("\n"); QFile er(expected_result_file_name); er.open(QFile::ReadOnly); result_file = er.readAll(); er.close(); QStringList expected_result = result_file.split("\n"); // find all lastModified attributes and replace them with identical values // because they are always going to be different QString err("Sizes of the generated .fwb and test files are different: \n" "Expected: %1 (%2)\n" "Obtained: %3 (%4)\n" "diff -u %1 %3 | less -S"); CPPUNIT_ASSERT_MESSAGE( err .arg(expected_result_file_name).arg(expected_result.size()) .arg(obtained_result_file_name).arg(obtained_result.size()) .toStdString(), expected_result.size() == obtained_result.size()); QRegExp last_mod_re("lastModified=\"\\d+\""); int max_idx = max(expected_result.size(), obtained_result.size()); for (int i=0; i < max_idx; ++i) { QString os = obtained_result[i]; obtained_result[i] = os.replace(last_mod_re, "lastModified=\"0000000000\""); QString es = expected_result[i]; expected_result[i] = es.replace(last_mod_re, "lastModified=\"0000000000\""); } for (int i=0; i < max_idx; ++i) { QString err = QString("%1:%2:\nExpected: '%3'\nResult: '%4'\n") .arg(expected_result_file_name) .arg(i) .arg(expected_result[i]) .arg(obtained_result[i]); CPPUNIT_ASSERT_MESSAGE( err.toStdString(), obtained_result[i] == expected_result[i]); } } void ImporterTest::IOSImporterTest() { platform = "iosacl"; QFile f("test_data/ios.test"); f.open(QFile::ReadOnly); string buffer = QString(f.readAll()).toStdString(); f.close(); std::istringstream instream(buffer); Importer* imp = new IOSImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("ios.fwb"); compareFwbFiles("test_data/ios.fwb", "ios.fwb"); compareResults(logger, "test_data/ios.output", "ios.output"); } void ImporterTest::IPTImporterTest() { platform = "iptables"; QFile f("test_data/ipt.test"); f.open(QFile::ReadOnly); string buffer = QString(f.readAll()).toStdString(); f.close(); std::istringstream instream(buffer); Importer* imp = new IPTImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("ipt.fwb"); compareFwbFiles("test_data/ipt.fwb", "ipt.fwb"); compareResults(logger, "test_data/ipt.output", "ipt.output"); } void ImporterTest::IPTImporterNoNatTest() { platform = "iptables"; QFile f("test_data/ipt-no-nat.test"); f.open(QFile::ReadOnly); string buffer = QString(f.readAll()).toStdString(); f.close(); std::istringstream instream(buffer); Importer* imp = new IPTImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("ipt-no-nat.fwb"); compareFwbFiles("test_data/ipt-no-nat.fwb", "ipt-no-nat.fwb"); compareResults(logger, "test_data/ipt-no-nat.output", "ipt-no-nat.output"); } void ImporterTest::IPTImporterParseVersionsTest() { platform = "iptables"; QString iptables_save_file(iptables_sample); QStringList versions; versions << "v1.1.1" << "v1.1.1.1" << "v12.1.1" << "v12.1.1.1" << "v1.12.1" << "v1.12.1.1" << "v1.1.12" << "v1.1.12.1" << "v1.1.1.12" << "v1.2.1a"; foreach (QString v, versions) { QString file_name = QString("ipt-%1").arg(v); QString actual_iptables_save = iptables_save_file; actual_iptables_save.replace("%VERSION%", v); std::istringstream instream(actual_iptables_save.toStdString()); Importer* imp = new IPTImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); // db->setPredictableIds(); // db->saveFile(file_name.toStdString() + ".fwb"); // // no need to compare .fwb files, we do not recognize these // test version numbers anyway so version will be set to "any" // in all tests anyway // // compareFwbFiles(QString("test_data/%1.fwb").arg(file_name), // QString("%1.fwb").arg(file_name)); compareResults(logger, QString("test_data/%1.output").arg(file_name), QString("%1.output").arg(file_name)); } } fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/ImporterTest.h0000644000175000017500000000411011733011756025235 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IMPORTERTEST_H #define IMPORTERTEST_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include #include class ImporterTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *db; libfwbuilder::Library *lib; libfwbuilder::QueueLogger *logger; int predictable_id_tracker; std::map id_mapping; void compareResults(libfwbuilder::QueueLogger* logger, QString expected_result_file_name, QString obtained_result_file_name); void compareFwbFiles(QString expected_result_file_name, QString obtained_result_file_name); public: void setUp(); void IOSImporterTest(); void IPTImporterTest(); void IPTImporterNoNatTest(); void IPTImporterParseVersionsTest(); CPPUNIT_TEST_SUITE(ImporterTest); CPPUNIT_TEST(IOSImporterTest); CPPUNIT_TEST(IPTImporterTest); CPPUNIT_TEST(IPTImporterNoNatTest); CPPUNIT_TEST(IPTImporterParseVersionsTest); CPPUNIT_TEST_SUITE_END(); }; #endif // IMPORTERTEST_H fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/0000755000175000017500000000000011733011756024377 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ios.output0000644000175000017500000001110611733011756026452 0ustar sylvestresylvestre10: Host name: "c3620" 106: New interface: FastEthernet0/0 107: Interface address: 192.168.100.100/255.255.255.0 108: Interface address: 10.3.14.201/255.255.255.0 109: Interface FastEthernet0/0 ruleset fe0_0_acl_in direction 'in' 110: Interface FastEthernet0/0 ruleset fe0_0_acl_out direction 'out' 115: New interface: Ethernet1/0 116: Interface comment: Test [ test ] { test } ( and one more test) / weird:characters#$%^&*/ 117: Interface address: 192.168.171.2/255.255.255.0 118: Interface Ethernet1/0 ruleset e1_0_acl_in direction 'in' 119: Interface Ethernet1/0 ruleset e1_0_acl_out direction 'out' 125: New interface: Serial1/0 131: New interface: Ethernet1/1 132: Interface address: 10.10.10.10/255.255.255.0 136: Interface Ethernet1/1 ruleset acl_133 direction 'in' 137: Interface Ethernet1/1 ruleset acl_133 direction 'out' 141: New interface: Ethernet1/2 142: Interface address: 10.10.20.20/255.255.255.0 147: Interface Ethernet1/2 ruleset acl_133 direction 'in' 148: Interface Ethernet1/2 ruleset acl_133 direction 'out' 152: New interface: ATM0 161: New interface: ATM0.1 161: Warning: point-to-point interfaces are not supported 162: Interface comment: $FW_OUTSIDE$$ES_WAN$ 165: Interface address: 10.0.0.1/255.255.255.252 194: access list rule: access list e1_0_acl_in, action deny 195: access list rule: access list e1_0_acl_in, action permit 196: access list rule: access list e1_0_acl_in, action permit 197: access list rule: access list e1_0_acl_in, action permit 198: access list rule: access list e1_0_acl_in, action deny 201: access list rule: access list e1_0_acl_out, action permit 202: access list rule: access list e1_0_acl_out, action deny 205: access list rule: access list fe0_0_acl_in, action permit 206: access list rule: access list fe0_0_acl_in, action permit 207: access list rule: access list fe0_0_acl_in, action permit 208: access list rule: access list fe0_0_acl_in, action deny 211: access list rule: access list fe0_0_acl_out, action permit 212: access list rule: access list fe0_0_acl_out, action deny 215: Rule comment: / / path1/path2/path3 216: Rule comment: access list comment 218: access list rule: access list outside, action permit 220: access list rule: access list outside, action permit 222: access list rule: access list outside, action permit 224: access list rule: access list outside, action permit 225: access list rule: access list outside, action deny 227: access list rule: access list outside, action permit 229: access list rule: access list outside, action permit 230: access list rule: access list outside, action permit 233: access list rule: access list outside, action deny 234: access list rule: access list outside, action deny 235: access list rule: access list outside, action deny 236: access list rule: access list outside, action deny 238: access list rule: access list outside, action permit 239: access list rule: access list outside, action permit 241: access list rule: access list outside, action permit 243: access list rule: access list outside, action permit 245: access list rule: access list outside, action permit 246: access list rule: access list outside, action permit 247: access list rule: access list outside, action permit 251: access list rule: access list outside, action permit 252: access list rule: access list outside, action permit 253: access list rule: access list outside, action permit 255: access list rule: access list outside, action permit 256: access list rule: access list outside, action deny 261: access list rule: access list tmp_acl, action permit 262: access list rule: access list tmp_acl, action deny 264: access list rule: access list acl_133, action permit 265: access list rule: access list acl_133, action permit 266: access list rule: access list acl_133, action deny 267: access list rule: access list acl_144, action permit 268: access list rule: access list acl_144, action permit 269: access list rule: access list acl_144, action permit 270: access list rule: access list acl_144, action permit 271: access list rule: access list acl_144, action permit 272: access list rule: access list acl_144, action permit 273: access list rule: access list acl_144, action permit 274: access list rule: access list acl_144, action permit 275: access list rule: access list acl_199, action permit 276: access list rule: access list acl_199, action permit 278: Rule comment: Standard access lists are 1 to 99 and 1300 to 1999 279: access list rule: access list acl_1300, action permit 280: access list rule: access list acl_1300, action permit 281: access list rule: access list acl_1300, action permit 282: access list rule: access list acl_1300, action permit fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v12.1.1.1.output0000644000175000017500000000112511733011756027517 0ustar sylvestresylvestre1: Version: 12.1.1.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt.fwb0000644000175000017500000101017611733011756025701 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk -m state --state NEW,ESTABLISHED -m state --state NEW,RELATED,ESTABLISHED -m length --length 400:65535 -m recent --name badguy --rcheck --seconds 60 -m recent --name badguy --set -m length --length 400:1500 -m pkttype --pkt-type broadcast fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v12.1.1.output0000644000175000017500000000112311733011756027356 0ustar sylvestresylvestre1: Version: 12.1.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-no-nat.fwb0000644000175000017500000026461711733011756027105 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt.output0000644000175000017500000001766611733011756026475 0ustar sylvestresylvestre1: Version: 1.2.1 3: New ruleset: filter / INPUT 3: Default action: Deny 4: New ruleset: filter / FORWARD 4: Default action: Deny 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / user_chain 6: Default action: Deny 9: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 12: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 13: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 14: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 18: Created branch INPUT_state_match_0 18: Warning: Rule matches combination of states 'NEW,ESTABLISHED'. Iptables rules generated by fwbuilder can be stateless (match no state) or stateful (match state NEW). Fwbuilder also adds a rule at the top of the script to match states ESTABLISHED,RELATED. Combination of states 'NEW,ESTABLISHED' does not fit these standard cases and to match it, the program created new Custom Service object. This may require manual checking. 23: Created branch OUTPUT_established_1 23: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 28: Created branch OUTPUT_established_2 28: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 31: Created branch FORWARD_state_match_3 31: Warning: Rule matches combination of states 'NEW,RELATED,ESTABLISHED'. Iptables rules generated by fwbuilder can be stateless (match no state) or stateful (match state NEW). Fwbuilder also adds a rule at the top of the script to match states ESTABLISHED,RELATED. Combination of states 'NEW,RELATED,ESTABLISHED' does not fit these standard cases and to match it, the program created new Custom Service object. This may require manual checking. 34: Warning: Using automatic rule controlled by option 'Drop packet that do not match any known connection' to match state INVALID 37: Warning: Using automatic rule controlled by option 'Drop packet that do not match any known connection' to match state INVALID 40: New interface: lo 45: Created branch Policy_eth1 45: New interface: eth1 45: New interface: eth0 45: Warning: Creating branch ruleset 'Policy_eth1' to match inbound and outbound interfaces -i eth0 -o eth1 106: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 218: Created branch user_chain_55_mod_match 222: Created branch user_chain_56_mod_match 223: Created branch user_chain_57_mod_match 224: Created branch user_chain_58_mod_match 227: Created branch user_chain_59_mod_match 230: Created branch user_chain_60_mod_match 233: Created branch user_chain_61_mod_match 233: Error: Original rule combines match of tcp/udp/icmp protocols with two or more module matches, such as module 'mark', 'recent' or 'length'. Use additional branches to implement this complex match. 233: Error: Error: Original rule combines match of tcp/udp/icmp protocols with two or more module matches, such as module 'mark', 'recent' or 'length'. Use additional branches to implement this complex match. 234: Created branch user_chain_62_mod_match 234: Error: Original rule combines match of tcp/udp/icmp protocols with two or more module matches, such as module 'mark', 'recent' or 'length'. Use additional branches to implement this complex match. 234: Error: Error: Original rule combines match of tcp/udp/icmp protocols with two or more module matches, such as module 'mark', 'recent' or 'length'. Use additional branches to implement this complex match. 245: New ruleset: mangle / PREROUTING 245: Default action: Accept 246: New ruleset: mangle / INPUT 246: Default action: Accept 247: New ruleset: mangle / FORWARD 247: Default action: Accept 248: New ruleset: mangle / OUTPUT 248: Default action: Accept 249: New ruleset: mangle / POSTROUTING 249: Default action: Accept 252: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain FORWARD 252: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain FORWARD 255: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain FORWARD 255: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain FORWARD 256: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain FORWARD 256: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain FORWARD 262: Warning: Skipping command with '-j CONNMARK --restore-mark' This rule is generated automatically. 265: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 265: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 266: Warning: Turned option on in previous rule with action Mark for '-j CONNMARK --save-mark' 269: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 269: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 270: New interface: eth2 270: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 270: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 274: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 274: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 275: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 275: Error: Error: Fwbuilder can not reproduce iptables rule in the table 'mangle', chain POSTROUTING 283: New ruleset: nat / PREROUTING 283: Default action: Accept 284: New ruleset: nat / POSTROUTING 284: Default action: Accept 285: New ruleset: nat / OUTPUT 285: Default action: Accept 289: New interface: eth+ 318: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT 318: Warning: Line 247: Can not reproduce default action in table 'mangle' chain 'FORWARD'. (Generated rule may not generate equivalent iptables command when compiled) 318: Warning: Line 247: Added rule to reproduce default policy ACCEPT in mangle/FORWARD 318: Warning: Line 246: Can not reproduce default action in table 'mangle' chain 'INPUT'. (Generated rule may not generate equivalent iptables command when compiled) 318: Warning: Line 246: Added rule to reproduce default policy ACCEPT in mangle/INPUT 318: Warning: Line 248: Added rule to reproduce default policy ACCEPT in mangle/OUTPUT 318: Warning: Line 249: Added rule to reproduce default policy ACCEPT in mangle/POSTROUTING 318: Warning: Line 245: Added rule to reproduce default policy ACCEPT in mangle/PREROUTING fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ios.test0000644000175000017500000002155211733011756026077 0ustar sylvestresylvestre! ! Last configuration change at 12:24:46 PST Fri May 11 2007 by vadim ! NVRAM config last updated at 12:24:46 PST Fri May 11 2007 by vadim ! version 12.2 service timestamps debug uptime no service timestamps log uptime service password-encryption ! hostname "c3620" ! no logging buffered no logging console aaa new-model aaa new-model aaa group server tacacs+ inttac server 10.1.0.1 ! enable secret 5 $1$U6dJ$BfnMsC23.X8BCFJB0XIJA. enable password 7 ! username user1 password 7 0123456789ABCDEF00 username user2 password 7 01234567890ABCDEF01234567890 clock timezone PST -7 ip subnet-zero ! ! ip tcp synwait-time 10 ip cef ip domain-name fwbuilder.org ip name-server 10.1.1.10 ! ip audit notify log ip audit po max-events 100 ! crypto isakmp policy 10 encr 3des hash md5 authentication pre-share group 2 crypto isakmp key address 22.22.22.22 crypto isakmp key address 192.168.171.1 ! crypto ipsec security-association lifetime seconds 28800 ! crypto ipsec transform-set test-transform esp-3des esp-md5-hmac crypto ipsec transform-set pix-transform esp-3des esp-md5-hmac ! crypto map test 10 ipsec-isakmp set peer 22.22.22.22 set transform-set test-transform match address 133 ! crypto map real 10 ipsec-isakmp set peer 192.168.171.1 set transform-set pix-transform match address 144 ! ! See bug 2334007 for "certificate" ! https://sourceforge.net/tracker2/?func=detail&aid=2334007&group_id=5314&atid=1070394 ! certificate self-signed 01 30820254 308201BD A0030201 02020101 300D0609 2A864886 F70D0101 04050030 E7CF84EC 9FED5F77 EBE589EF 832F6AC3 DFFE3FD8 5F73C105 quit ! call rsvp-sync ! ! ! module ContentSwitchingModule 3 ft group 1 vlan 9 preempt ! ! -- test behavior for the "ip address" command in the "vlan" context ! (should ignore it) ! vlan 706 server ip address 172.16.1.1 255.255.255.128 alias 172.16.1.2 255.255.255.128 ! vlan 111 client ip address 172.16.10.1 255.255.255.0 gateway 172.16.10.254 ! static nat virtual real 192.168.16.20 real 192.168.16.19 ! ! vserver TEST virtual 172.16.1.51 tcp www vlan 706 serverfarm BBTEST-HTTP persistent rebalance slb-policy BBTEST inservice ! ! See bug 2334007 for "controller" with "description" ! https://sourceforge.net/tracker2/?func=detail&aid=2334007&group_id=5314&atid=1070394 ! controller T3 2/0 description Any description will crash the parser ! ! interface FastEthernet0/0 ip address 192.168.100.100 255.255.255.0 secondary ip address 10.3.14.201 255.255.255.0 ip access-group fe0_0_acl_in in ip access-group fe0_0_acl_out out no ip mroute-cache duplex auto speed auto ! interface Ethernet1/0 description Test [test] {test} (and one more test) /weird:characters#$%^&*/ ip address 192.168.171.2 255.255.255.0 ip access-group e1_0_acl_in in ip access-group e1_0_acl_out out no ip mroute-cache ip ospf cost 65000 half-duplex crypto map real ! interface Serial1/0 ip unnumbered Loopback0 no ip mroute-cache shutdown no fair-queue ! interface Ethernet1/1 ip address 10.10.10.10 255.255.255.0 no ip mroute-cache ! ! Note - the same access list applied both in and out ip access-group 133 in ip access-group 133 out no shutdown half-duplex ! interface Ethernet1/2 ip address 10.10.20.20 255.255.255.0 no ip mroute-cache ! ! Note - the same access list applied both in and out ! the same list is applied to eth 1/1 and eth 1/2 ip access-group 133 in ip access-group 133 out no shutdown half-duplex ! interface ATM0 no ip address no ip redirects no ip unreachables no ip proxy-arp ip route-cache flow no atm ilmi-keepalive dsl operating-mode auto ! interface ATM0.1 point-to-point description $FW_OUTSIDE$$ES_WAN$ no snmp trap link-status pvc 0/38 ip address 10.0.0.1 255.255.255.252 encapsulation aal5mux ppp dialer dialer pool-member 1 ! router ospf 1 network 10.3.14.0 0.0.0.255 area 0 ! ip classless ip route 0.0.0.0 0.0.0.0 192.168.171.1 no ip http server ! ip bgp-community new-format ip community-list standard AS65530.INTERNAL permit 65532:10100 ip community-list expanded ASFOO permit _65533:10200_ ip community-list expanded ASFOO.CUST permit _65532:103.._ ip community-list expanded TEST99 permit 65532:102.* 65533:.* ! ! See bug 2334007 for problems with commands using character "|" ! https://sourceforge.net/tracker2/?func=detail&aid=2334007&group_id=5314&atid=1070394 ! ip community-list expanded Test2 permit ^65063:1[8-9][0-9]|65063:20[0-9]$ ! ip as-path access-list 10 permit ^1239_ ip as-path access-list 10 permit .* ip flow-export source Loopback0 ip flow-export version 5 ! !################################################################ ip access-list extended e1_0_acl_in deny ip any any fragments permit tcp host 10.3.14.40 host 192.168.171.2 eq 22 log permit tcp host 10.3.14.40 host 10.3.14.201 eq 22 log permit ip any 10.3.14.0 0.0.0.255 log deny ip any any log !################################################################ ip access-list extended e1_0_acl_out permit ip 10.3.14.0 0.0.0.255 any log deny ip any any log !################################################################ ip access-list extended fe0_0_acl_in permit tcp host 10.3.14.40 host 192.168.171.2 eq 22 log permit tcp host 10.3.14.40 host 10.3.14.201 eq 22 log permit ip 10.3.14.0 0.0.0.255 any log deny ip any any log !################################################################ ip access-list extended fe0_0_acl_out permit ip any 10.3.14.0 0.0.0.255 log deny ip any any log !################################################################ ip access-list extended outside remark //path1/path2/path3 remark access list comment ! destination port permit udp any any eq isakmp ! source port permit tcp any eq 80 any ! source port and established permit tcp any eq 80 any established ! different port operators permit tcp any gt 1023 any deny tcp any lt 1023 any ! ports can be defined by number or by name permit tcp any any eq www ! port ranges permit tcp any any range 22 80 permit tcp any any range 22 www ! ! two identical services, one tcp, another udp deny tcp any any eq 2967 deny tcp any eq 2967 any deny udp any any eq 2967 deny udp any eq 2967 any ! permit ahp any any permit esp any any ! icmp rule with no icmp spec permit icmp any any ! icmp rule with icmp spec in the form of two integers permit icmp any any 8 0 ! icmp rule with icmp spec in the form of a word permit icmp any any unreachable permit icmp any any host-unreachable permit icmp any any host-precedence-unreachable ! ! check for empty line inside ACL definition permit udp any any eq bootpc permit udp any any eq bootps permit udp any eq domain any ! 'time-range' option permit tcp 10.10.10.0 0.0.0.255 eq 80 host 10.3.14.40 established time-range evening deny ip any any log !################################################################ ! empty access list declaration ip access-list extended foo ip access-list extended tmp_acl permit ip 10.3.14.0 0.0.0.255 any deny ip any any ! access-list 133 permit ip 10.3.14.0 0.0.0.255 10.10.10.0 0.0.0.255 access-list 133 permit ip 10.10.10.0 0.0.0.255 10.3.14.0 0.0.0.255 access-list 133 deny ip any any log access-list 144 permit icmp 10.3.14.0 0.0.0.255 10.2.1.0 0.0.0.255 access-list 144 permit icmp 10.2.1.0 0.0.0.255 10.3.14.0 0.0.0.255 access-list 144 permit ip 10.3.14.0 0.0.0.255 10.2.1.0 0.0.0.255 access-list 144 permit ip 10.2.1.0 0.0.0.255 10.3.14.0 0.0.0.255 access-list 144 permit icmp 10.3.14.0 0.0.0.255 host 192.168.171.1 access-list 144 permit icmp host 192.168.171.1 10.3.14.0 0.0.0.255 access-list 144 permit ip 10.3.14.0 0.0.0.255 host 192.168.171.1 access-list 144 permit ip host 192.168.171.1 10.3.14.0 0.0.0.255 access-list 199 permit icmp 10.3.14.0 0.0.0.255 10.10.10.0 0.0.0.255 log access-list 199 permit ip any any ! access-list 1300 remark Standard access lists are 1 to 99 and 1300 to 1999 access-list 1300 permit 22.22.22.21 access-list 1300 permit 22.23.24.25 access-list 1300 permit 22.23.25.0 0.0.0.15 access-list 1300 permit 10.0.0.0 0.255.255.255 ! route-map AS65530_AGGREGATION permit 10 match ip address prefix-list AS65530_AGGR set community 65532:111 65533:101 65533:111 65533:121 65533:131 65533:141 65533:151 65533:201 65533:301 65533:311 65533:321 65533:401 ! ! snmp-server community public RO snmp-server enable traps tty ! dial-peer cor custom ! ip prefix-list AS65530_AGGR permit 22.23.24.0/19 le 24 ! logging facility syslog logging source-interface Loopback0 logging 10.1.0.91 logging 10.1.0.92 ! ! ! banner motd ^C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~ B A N N E R ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^C ! line con 0 line aux 0 line vty 0 4 password 7 ! ntp clock-period 17179753 ntp server 10.3.14.10 ! time-range evening periodic daily 17:00 to 23:59 ! end fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.12.1.output0000644000175000017500000000112311733011756027356 0ustar sylvestresylvestre1: Version: 1.12.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-no-nat.output0000644000175000017500000000146611733011756027656 0ustar sylvestresylvestre1: Version: 1.3.5 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / RH-Firewall-1-INPUT 6: Default action: Deny 9: New interface: lo 16: Warning: Rule matches states 'RELATED,ESTABLISHED'. Consider using automatic rule controlled by the checkbox in the firewall settings dialog. Automatic rule matches in all standard chains which may be different from the original imported configuration. This requires manual checking. 18: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 18: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 18: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.1.1.1.output0000644000175000017500000000112411733011756027434 0ustar sylvestresylvestre1: Version: 1.1.1.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.1.12.1.output0000644000175000017500000000112511733011756027517 0ustar sylvestresylvestre1: Version: 1.1.12.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.1.1.12.output0000644000175000017500000000112511733011756027517 0ustar sylvestresylvestre1: Version: 1.1.1.12 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.2.1a.output0000644000175000017500000000112211733011756027435 0ustar sylvestresylvestre1: Version: 1.2.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ios.fwb0000644000175000017500000030570611733011756025704 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-no-nat.test0000644000175000017500000000160211733011756027265 0ustar sylvestresylvestre# Generated by iptables-save v1.3.5 on Mon Apr 11 15:46:04 2011 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [1593531:5659620982] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT -A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT -A RH-Firewall-1-INPUT -p esp -j ACCEPT -A RH-Firewall-1-INPUT -p ah -j ACCEPT -A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT # Completed on Mon Apr 11 15:46:04 2011 fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt.test0000644000175000017500000003605211733011756026102 0ustar sylvestresylvestre# Generated by iptables-save v1.2.1a on Fri Jun 1 14:04:15 2001 *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [1531191:180073476] :user_chain - [0:0] # this should produce rule in the same chain -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # and these, too -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # unusual combination of states, creates custom service object. Also, since the same rule # matches tcp service and custom service, branch will be created -A INPUT -s 192.168.2.0/24 -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT # this creates a branch, matching service in the main policy and # ESTABLISHED,RELATE states in the branch # -A OUTPUT -d 21.21.21.21 -p tcp -m tcp --sport 22 -m state --state RELATED,ESTABLISHED -j ACCEPT # variant with a different action. New branch rule set should be created, different # from the one created for the rule above. # -A OUTPUT -d 21.21.21.21 -p tcp -m tcp --dport 23 -m state --state RELATED,ESTABLISHED -j DROP # more complex combination of states -A FORWARD -s 1.1.1.0/24 -d 2.2.2.0/24 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp ! --dport 80 -j ACCEPT # this should be recognized as built-in rule -A FORWARD -m state --state INVALID -j drop_invalid # this should be recognized as built-in rule -A OUTPUT -m state --state INVALID -j drop_invalid # these go into INPUT chain, should end up with firewall object in DST -A INPUT -i lo -j ACCEPT -A INPUT -j user_chain -A INPUT -j scan_checks_chain # both -i intf and -o intf in the same rule. Crearing a branch -A FORWARD -i eth0 -o eth1 -p udp --dport 1604 -j ACCEPT # testing action REJECT with option. Trying all possible options and aliases -A INPUT -p tcp --dport 0:8000 -j REJECT --reject-with tcp-reset -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-net-unreachable -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with net-unreach -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-host-unreachable -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with host-unreach -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-proto-unreachable -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with proto-unreach -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-port-unreachable -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with port-unreach -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-net-prohibited -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with net-prohib -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-host-prohibited -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with host-prohib -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-admin-prohibited -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with admin-prohib # was: bad --reject-with argument -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with icmp-admin-prohibited -A INPUT -p udp --dport 0:8000 -j REJECT --reject-with admin-prohib # v2.1 does not support passing control to the same branch from # several rules This rule will have action 'branch' but branch name # will be 'user_chain1' This rule will have a comment explaining this # and branch rule set will be emtpy -A OUTPUT -j user_chain # Tests for module iprange -A FORWARD -m iprange --src-range 10.212.66.2-10.212.66.3 --dst-range 192.11.1.11-192.11.1.63 -j ACCEPT -A FORWARD -m iprange -s 10.212.66.2 --dst-range 192.11.1.11-192.11.1.63 -j ACCEPT -A FORWARD -m iprange --src-range 10.212.66.2-10.212.66.3 -d 192.11.1.11 -j ACCEPT # -A FORWARD -s 192.168.0.0/16 -m state --state NEW -j ACCEPT # this should end up with action "Continue" and logging on -A FORWARD -j LOG --log-prefix "FORWARD catch-all" # should have icmp (-1,-1) in SRV -- should recognize this as icmp # even though it is uppercased -A user_chain -s 128.143.0.0/16 -p ICMP -j ACCEPT # numeric protocol spec -A user_chain -d 192.168.1.1 -i eth0 -p 47 -j ACCEPT # target RETURN -A user_chain -s 1.1.0.0/16 -p ICMP -j RETURN # this should be reproduced using custom service object even though it # is in user-defined chain # -A user_chain -m state --state RELATED,ESTABLISHED -j ACCEPT -A user_chain -s 192.168.19.0/24 -p tcp -m tcp --dport 5432 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.16.125 -p tcp -m tcp --dport 5432 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p tcp -m tcp --dport 873 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT -A user_chain -s 192.0.34.166 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.19.0/24 -p tcp -m tcp --dport 137:139 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.19.0/24 -p tcp -m tcp --dport :1023 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.19.0/24 -p tcp -m tcp --dport 6000: -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p udp --dport 137 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p udp --dport 138 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p tcp -m tcp --dport 139 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p tcp -m tcp --dport 445 -m state --state NEW -j ACCEPT -A user_chain -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT -A user_chain -s 192.168.0.0/16 -p tcp -m tcp --dport 8080 -m state --state NEW -j ACCEPT -A user_chain -s 192.0.34.166 -p tcp -m tcp --dport 8080 -m state --state NEW -j ACCEPT -A user_chain -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT -A user_chain -s 127.0.0.1 -p tcp -m tcp --dport 631 -m state --state NEW -j ACCEPT -A user_chain -s 127.0.0.1 -p tcp -m tcp --dport 515 -m state --state NEW -j ACCEPT # different combinations of tcp flags in combination with some other # options. Taken from a real policy. # -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -m limit --limit 3/min -j LOG --log-prefix "Stealth XMAS scan: " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,ACK,URG -m limit --limit 3/min -j LOG --log-prefix "Stealth XMAS-PSH scan: " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -m limit --limit 3/min -j LOG --log-prefix "Stealth XMAS-ALL scan: " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -m limit --limit 3/min -j LOG --log-prefix "Stealth FIN scan: " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 3/min -j LOG --log-prefix "Stealth SYN/RST scan: " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -m limit --limit 3/min -j LOG --log-prefix "Stealth SYN/FIN scan(?): " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -m limit --limit 3/min -j LOG --log-prefix "Stealth Null scan: " --log-level 7 -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,ACK,URG -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP -A scan_checks_chain -i eth0 -p tcp -m tcp --syn -j ACCEPT -A scan_checks_chain -i eth0 -p tcp -m tcp ! --syn -j ACCEPT # was: bad port spec -A user_chain -s 192.168.0.0/16 -p tcp -m tcp --dport 8088 -m state --state NEW -j ACCEPT # Log prefix and log limit test # Also need action Continue (or NOP) -A user_chain -s ! 128.143.0.0/16 -m limit --limit 25/hour -j LOG --log-prefix user_chain_notlocal: -A user_chain -s 128.143.0.0/16 -p tcp --dport 427 -j ACCEPT -A user_chain -s 128.143.0.0/16 -p udp --dport 427 -j ACCEPT -A user_chain -s 128.143.0.0/16 -p tcp --dport 548 -j ACCEPT -A user_chain -s 128.143.0.0/16 -p tcp --dport 201 -j ACCEPT -A user_chain -s 128.143.0.0/16 -p tcp --dport 202 -j ACCEPT -A user_chain -s 128.143.0.0/16 -p tcp --dport 204 -j ACCEPT -A user_chain -s 128.143.0.0/16 -p tcp --dport 206 -j ACCEPT # --dports does not necessarily follow -m multiport # -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --dports 548,201,202,204,206 -j ACCEPT # there can be just one port with multiport # -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --dports 2222 -j ACCEPT # source ports with multiport -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --sports 548,201,202,204,206 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --sports 2222 -j ACCEPT # --ports (source OR destination port) -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --ports 548,201,202,204,206 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --ports 2222 -j ACCEPT # various port range cases # it is unclear if multiport supports open-ended ranges such as ":1024" or "1024:" # -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --dports 201:206,311 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --dports 548,201:206 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --dports 548,201:206,311:315 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --dports 201:206,311:315,548 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --sports 201:206,311 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --sports 548,201:206 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --sports 548,201:206,311:315 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --sports 201:206,311:315,548 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --ports 201:206,311 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --ports 548,201:206 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --ports 548,201:206,311:315 -j ACCEPT -A user_chain -m multiport -s 128.143.0.0/16 -p tcp --ports 201:206,311:315,548 -j ACCEPT # now with negation -A user_chain -m multiport -s 128.143.0.0/16 -p tcp ! --dports 548,201,202,204,206 -j ACCEPT # icmp -A user_chain -p icmp -s 128.143.0.0/16 --icmp-type any -j ACCEPT -A user_chain -p icmp -s 128.143.0.0/16 --icmp-type 3 -j ACCEPT -A user_chain -p icmp -s 128.143.0.0/16 --icmp-type network-unknown -j ACCEPT # module length -A user_chain -m length --length 400:65535 -j DROP # Module recent -A user_chain -m recent --name badguy --rcheck --seconds 60 -j DROP -A user_chain -p tcp -i eth0 --dport 139 -m recent --name badguy --set -j DROP # combinations of a regular service and module or two modules # -A user_chain -s 128.143.0.0/16 -p tcp --dport 5190 -m mark --mark 0x11 -j DROP -A user_chain -s 128.143.0.0/16 -p tcp --dport 5190 -m length --length 400:1500 -j DROP -A user_chain -m mark --mark 0x11 -m length --length 400:1500 -j DROP # this rule has negation in the mark match but no negation in port match -A user_chain -p tcp -m mark ! --mark 0x4 -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN -j MARK --set-mark 0x1 # negation with tcp match -A user_chain -p tcp -m mark --mark 0x4 -m tcp ! --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN -j MARK --set-mark 0x1 # this rule has three matches which is not supported -A user_chain -p tcp -m length --length 0:128 -m mark --mark 0x4 -m tcp --sport 53 -j ACCEPT -A user_chain -p tcp -m length --length 0:128 -m mark ! --mark 0x4 -m tcp --sport 53 -j ACCEPT # bug 1703, SF bug 3065435 -A user_chain -m pkttype --pkt-type broadcast -j DROP -A user_chain -j DROP COMMIT # mangle table *mangle :PREROUTING ACCEPT :INPUT ACCEPT :FORWARD ACCEPT :OUTPUT ACCEPT :POSTROUTING ACCEPT # mark in FORWARD -A FORWARD -i eth1 -p tcp --dport smtp -j MARK --set-mark 16 # mark in FORWARD, argument is hex -A FORWARD -i eth1 -p tcp --dport smtp -j MARK --set-mark 0xa -A FORWARD -i eth1 -p tcp --dport smtp -j MARK --set-mark 0xB # mark in PREROUTING (check option "ipt_mark_prerouting") -A PREROUTING -i eth1 -p tcp --dport smtp -j MARK --set-mark 16 # option "ipt_mark_connections" -A PREROUTING -j CONNMARK --restore-mark # packets from me going out -A POSTROUTING -o eth1 -p tcp --sport smtp -j MARK --set-mark 16 -A POSTROUTING -j CONNMARK --save-mark # test ROUTE target -A POSTROUTING -m mark --mark 1 -j ROUTE --oif eth0 --continue -A POSTROUTING -m mark --mark 2 -j ROUTE --oif eth2 --continue # test TOS target with parameters (unsupported, but parser # should not crash on it) -A POSTROUTING -d 192.168.1.1 -j TOS --set-tos Minimize-Delay -A POSTROUTING -d 192.168.1.1 -j TOS --set-tos 0x10 -A POSTROUTING -s 192.168.1.0/24 -j CLASSIFY --set-class 0001:0010 -A POSTROUTING -s 192.168.2.0/24 -j CLASSIFY --set-class 1:10 COMMIT *nat :PREROUTING ACCEPT [1502:275921] :POSTROUTING ACCEPT [406:45653] :OUTPUT ACCEPT [406:45653] -A POSTROUTING -o eth1 -s 192.168.1.0/24 -j SNAT --to-source 222.222.222.222 -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1 -A POSTROUTING -o eth+ -s 192.168.1.32/27 -j SNAT --to-source 222.222.222.10-222.222.222.100 -A POSTROUTING -o eth+ -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.20 --dport 80 -j SNAT --to-source 192.168.1.1 -A POSTROUTING -o eth+ -p tcp -m tcp -s 192.168.1.0/24 -d 192.168.1.20 --dport 80 -j SNAT --to-source 192.168.1.1-192.168.1.10 -A POSTROUTING -o eth1 -p tcp -m tcp -s 192.168.1.10 --sport 1000:1010 -j SNAT --to-source 222.222.222.222:1000-1010 -A POSTROUTING -o eth2 -s 192.168.1.0/24 -j MASQUERADE -A POSTROUTING -s 192.168.1.0/24 -j NETMAP --to 222.222.222.0/24 -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 25 -j DNAT --to-destination 192.168.1.10:25 -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 25 -j DNAT --to-destination 192.168.1.10:25-50 -A PREROUTING -p icmp -m icmp -d 222.222.222.222 --icmp-type 8/0 -j DNAT --to-destination 192.168.1.10 -A PREROUTING -p tcp -m tcp --sport 1000:1010 -d 222.222.222.222 -j DNAT --to-destination 192.168.1.10 -A PREROUTING -p tcp -m tcp -d 222.222.222.222 --dport 4000:4010 -j DNAT --to-destination 192.168.1.10:4000-4010 -A PREROUTING -p tcp -m tcp -m multiport -d 222.222.222.222 --dports 6667,3128,113,53,21,80,119,25,22,23,540,70,13,2105,443 -j DNAT --to-destination 192.168.1.10 -A PREROUTING -d 222.222.222.13/32 -p tcp -m multiport --dports 1720,3230:3243 -j DNAT --to-destination 192.168.1.212 # numeric protocol spec -A PREROUTING -d 192.168.3.145 -i eth0 -p 47 -j DNAT --to-destination 1.1.1.1 # a "no nat" rule -A POSTROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT # redirect rule -A PREROUTING -s 192.168.1.0/24 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 # a couple of nat rules in chain OUTPUT -A OUTPUT -p tcp -m tcp -d 192.168.1.22 --dport 80 -j DNAT --to-destination 192.168.2.10:80 -A OUTPUT -p icmp -m icmp -d 22.22.22.23 --icmp-type 11/0 -j DNAT --to-destination 192.168.1.10 COMMIT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.1.12.output0000644000175000017500000000112311733011756027356 0ustar sylvestresylvestre1: Version: 1.1.12 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.1.1.output0000644000175000017500000000112211733011756027273 0ustar sylvestresylvestre1: Version: 1.1.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/test_data/ipt-v1.12.1.1.output0000644000175000017500000000112511733011756027517 0ustar sylvestresylvestre1: Version: 1.12.1.1 3: New ruleset: filter / INPUT 3: Default action: Accept 4: New ruleset: filter / FORWARD 4: Default action: Accept 5: New ruleset: filter / OUTPUT 5: Default action: Accept 6: New ruleset: filter / CHAIN-1-INPUT 6: Default action: Deny Could not find enough information in the data file to create firewall interface objects. 9: Warning: Line 4: Added rule to reproduce default policy ACCEPT in filter/FORWARD 9: Warning: Line 3: Added rule to reproduce default policy ACCEPT in filter/INPUT 9: Warning: Line 5: Added rule to reproduce default policy ACCEPT in filter/OUTPUT fwbuilder-5.1.0.3599/src/unit_tests/ImporterTest/ImporterTest.pro0000644000175000017500000000021111733011756025604 0ustar sylvestresylvestreinclude(../tests_common.pri) TARGET = ImporterTest HEADERS += ImporterTest.h SOURCES += main_ImporterTest.cpp \ ImporterTest.cppfwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/0000755000175000017500000000000011733011756023163 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/AddressTableTest.pro0000644000175000017500000000112011733011756027074 0ustar sylvestresylvestre include(../../../qmake.inc) QT -= core gui TARGET = AddressTableTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS LIBS += $$CPPUNIT_LIBS SOURCES += main.cpp AddressTableTest.cpp HEADERS += AddressTableTest.h INCLUDEPATH += ../../.. ../../libfwbuilder/src DEPENDPATH += ../../libfwbuilder/src LIBS += ../../libfwbuilder/src/fwbuilder/libfwbuilder.a run_tests.commands = echo "Running tests..." && ./${TARGET} run_tests.depends = all clean_tests.depends = clean build_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/AddressTableTest.cpp0000644000175000017500000000777011733011756027077 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AddressTableTest.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Group.h" #include "fwbuilder/Library.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Network.h" using namespace std; using namespace libfwbuilder; void AddressTableTest::setUp() { objdb = new FWObjectDatabase(); FWObject *nlib = objdb->create(Library::TYPENAME,true); objdb->add(nlib); nlib->setName( "Library" ); FWObject *o1 = objdb->create(ObjectGroup::TYPENAME,true); o1->setName("Objects"); nlib->add(o1); address_tables_group = objdb->create(ObjectGroup::TYPENAME,true); address_tables_group->setName("Address Tables"); o1->add(address_tables_group); } void AddressTableTest::positiveTest() { setStrings addrres; setStrings addrset; // This matches contents of the test file addresstable-1.txt addrset.insert("216.193.197.238/255.255.255.255"); addrset.insert("207.46.20.60/255.255.255.0"); addrset.insert("207.46.198.3/255.255.255.255"); addrset.insert("207.46.198.60/255.255.255.255"); addrset.insert("207.46.199.30/255.255.255.255"); addrset.insert("207.46.225.60/255.255.255.252"); addrset.insert("207.46.19.60/255.255.255.255"); addrset.insert("192.168.105.57/255.255.255.255"); addrset.insert("192.168.105.69/255.255.255.255"); addrset.insert("192.168.105.68/255.255.255.255"); addrset.insert("192.168.100.0/255.255.255.0"); addrset.insert("192.168.11.0/255.255.255.0"); CPPUNIT_ASSERT(address_tables_group!=NULL); AddressTable *nobj = AddressTable::cast(objdb->create(AddressTable::TYPENAME, true)); address_tables_group->add(nobj); nobj->setName("TestADT"); nobj->setSourceName("addresstable-1.txt"); nobj->loadFromSource(false, NULL, true); list::const_iterator t = nobj->begin(); Network *net; FWReference *ref; for ( ; t != nobj->end(); ++t ) { ref = FWReference::cast(*t); CPPUNIT_ASSERT(ref!=NULL); net = Network::cast(ref->getPointer()); CPPUNIT_ASSERT(net!=NULL); addrres.insert(net->getAddressPtr()->toString() + "/" + net->getNetmaskPtr()->toString()); } CPPUNIT_ASSERT(addrset==addrres); } void AddressTableTest::negativeTest1() { setStrings addrres; CPPUNIT_ASSERT(address_tables_group!=NULL); AddressTable *nobj = AddressTable::cast(objdb->create(AddressTable::TYPENAME, true)); address_tables_group->add(nobj); nobj->setName("TestADT2"); nobj->setSourceName("addresstable-2.txt"); CPPUNIT_ASSERT_THROW(nobj->loadFromSource(false, NULL, true), FWException); } void AddressTableTest::negativeTest2() { setStrings addrres; CPPUNIT_ASSERT(address_tables_group!=NULL); AddressTable *nobj = AddressTable::cast(objdb->create(AddressTable::TYPENAME, true)); address_tables_group->add(nobj); nobj->setName("TestADT3"); nobj->setSourceName("addresstable-not-found.txt"); CPPUNIT_ASSERT_THROW(nobj->loadFromSource(false, NULL, true), FWException); } fwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/main.cpp0000644000175000017500000000252711733011756024621 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "AddressTableTest.h" #include "fwbuilder/FWObjectDatabase.h" #include int fwbdebug = 0; std::string platform; int main( int, char** argv) { CppUnit::TextUi::TestRunner runner; runner.addTest( AddressTableTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/AddressTableTest.h0000644000175000017500000000312111733011756026526 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ADDRESSTABLETEST_H #define ADDRESSTABLETEST_H #include "fwbuilder/FWObjectDatabase.h" #include #include #include typedef std::set > setStrings; class AddressTableTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *objdb; libfwbuilder::FWObject *address_tables_group; CPPUNIT_TEST_SUITE(AddressTableTest); CPPUNIT_TEST(positiveTest); CPPUNIT_TEST(negativeTest1); CPPUNIT_TEST(negativeTest2); CPPUNIT_TEST_SUITE_END(); public: void setUp(); void positiveTest(); void negativeTest1(); void negativeTest2(); }; #endif // ADDRESSTABLETEST_H fwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/addresstable-1.txt0000644000175000017500000000067511733011756026527 0ustar sylvestresylvestre# This is a comment ;; comment too # Test of Address Table # # 1.2.3.4 this address should be ignored because it is in the comment 216.193.197.238 www.rebol.com www.microsoft.com: 207.46.20.60/24 207.46.198.3 207.46.198.60 207.46.199.30 207.46.225.60/30 207.46.19.60 OKC Network: 192.168.105.57 OKC_B0 192.168.105.69 OKC_DEVP2 192.168.105.68 OKC_SQL RK Network: 192.168.100.0/24 TT Lan: 192.168.11.0/24 fwbuilder-5.1.0.3599/src/unit_tests/AddressTableTest/addresstable-2.txt0000644000175000017500000000023511733011756026520 0ustar sylvestresylvestre# This is a comment ;; comment too # Test of Address Table # # This file is different from addresstable-1.txt , it has invalid ip address 300.300.300.300 fwbuilder-5.1.0.3599/src/unit_tests/FWWindowTest/0000755000175000017500000000000011733011756022332 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/FWWindowTest/FWWindowTest.h0000644000175000017500000000256411733011756025056 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWWINDOWTEST_H #define FWWINDOWTEST_H #include #include #include class FWWindowTest : public QMainWindow { Q_OBJECT; public: FWWindowTest(QWidget *parent = 0); public slots: void findMessageBox(); void findNoMessageBox(); void prepareMW(); private slots: void initTestCase(); void cleanupTestCase(); void checkForUpgrade_1(); void checkForUpgrade_2(); void checkForUpgrade_3(); void checkForUpgrade_4(); }; #endif // FWWINDOWTEST_H fwbuilder-5.1.0.3599/src/unit_tests/FWWindowTest/FWWindowTest.pro0000644000175000017500000000025011733011756025415 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = FWWindowTest HEADERS += FWWindowTest.h SOURCES += main_FWWindowTest.cpp \ FWWindowTest.cpp fwbuilder-5.1.0.3599/src/unit_tests/FWWindowTest/FWWindowTest.cpp0000644000175000017500000000670711733011756025414 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FWWindowTest.h" #include "FWWindow.h" #include #include "global.h" #include "FWBSettings.h" #include #include #include FWWindowTest::FWWindowTest(QWidget *parent) : QMainWindow(parent) { } void FWWindowTest::initTestCase() { st->setCheckUpdates(true); st->setBool("UI/NoStartTip", true); } void FWWindowTest::cleanupTestCase() { if (QFile::exists("/tmp/update_4.0.0")) qDebug() << "file /tmp/update_4.0.0 exists"; QFile::remove("/tmp/update_4.0.0"); } void FWWindowTest::findMessageBox() { QList boxes = mw->findChildren(); QVERIFY(!boxes.empty()); bool found = false; foreach(QMessageBox *box, boxes) { if (box->text().contains("http://www.fwbuilder.org")) { found = true; box->reject(); break; } } QVERIFY(found); } void FWWindowTest::findNoMessageBox() { QList boxes = mw->findChildren(); if (!boxes.isEmpty()) boxes.first()->reject(); QVERIFY(boxes.empty()); } void FWWindowTest::prepareMW() { mw = new FWWindow(); mw->show(); QFile updatefile("/tmp/update_4.0.0"); updatefile.open(QFile::ReadWrite); updatefile.write("update = 1\n"); updatefile.close(); setenv("FWBUILDER_CHECK_UPDATE_URL", "file:///tmp/update_4.0.0", 1); st->setCheckUpdates(true); } void FWWindowTest::checkForUpgrade_1() { prepareMW(); st->setTimeOfLastUpdateAvailableWarning(0); QTimer::singleShot(1000, this, SLOT(findMessageBox())); mw->startupLoad(); QTest::qWait(1500); mw->hide(); } void FWWindowTest::checkForUpgrade_2() { prepareMW(); st->setTimeOfLastUpdateAvailableWarning(QDateTime::currentDateTime().addSecs(-60*60*25).toTime_t()); QTimer::singleShot(1000, this, SLOT(findMessageBox())); mw->startupLoad(); QTest::qWait(1500); mw->hide(); } void FWWindowTest::checkForUpgrade_3() { prepareMW(); st->setTimeOfLastUpdateAvailableWarning(QDateTime::currentDateTime().addSecs(-60*60*2).toTime_t()); QTimer::singleShot(1000, this, SLOT(findNoMessageBox())); mw->startupLoad(); QTest::qWait(1500); mw->hide(); } void FWWindowTest::checkForUpgrade_4() { prepareMW(); QFile updatefile("/tmp/update_4.0.0"); updatefile.open(QFile::WriteOnly); updatefile.resize(0); updatefile.close(); st->setTimeOfLastUpdateAvailableWarning(QDateTime::currentDateTime().addSecs(-60*60*25).toTime_t()); QTimer::singleShot(1000, this, SLOT(findNoMessageBox())); mw->startupLoad(); QTest::qWait(1500); mw->hide(); } fwbuilder-5.1.0.3599/src/unit_tests/FWWindowTest/main_FWWindowTest.cpp0000644000175000017500000000317711733011756026416 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FWWindowTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new FWWindowTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/.gitignore0000644000175000017500000000000511733011756021751 0ustar sylvestresylvestre*.a fwbuilder-5.1.0.3599/src/unit_tests/instDialogInspectTest/0000755000175000017500000000000011733011756024251 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/instDialogInspectTest/test.fwb0000644000175000017500000057047711733011756025754 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/instDialogInspectTest/instDialogInspectTest.h0000644000175000017500000000372111733011756030710 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogInspectTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include "FWBTree.h" #include "FWWindow.h" #include "ObjectManipulator.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Library.h" #include "fwbuilder/Policy.h" #include "instDialog.h" #include "newClusterDialog.h" #include "upgradePredicate.h" class instDialogInspectTest : public QObject { Q_OBJECT; bool dialogClosed; ObjectManipulator *om; ObjectTreeView *tree; QStringList filesToCleanup; private slots: void initTestCase(); void cleanupTestCase(); void testInspect_cluster(); void testInspect_firewall(); void testInspect_space(); void testInspect_ascii(); void testInspect_russian(); public slots: void closeInstallOptions(); void closeContextMenu(); void openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText); void testInspect(QString fwname); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogInspectTest/instDialogInspectTest.cpp0000644000175000017500000001455011733011756031245 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogInspectTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "instDialogInspectTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include #include "FWObjectClipboard.h" #include "FWBApplication.h" using namespace std; using namespace QTest; using namespace libfwbuilder; bool checkProgress(QTreeWidget *list) { for(int i=0; itopLevelItemCount(); i++) { if ( (list->topLevelItem(i)->text(1).toStdString() == "Compiling ...") || (list->topLevelItem(i)->text(1).toStdString() == "Installing ...") ) return false; } return true; } void instDialogInspectTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->loadFile("test_work.fwb", false); dialogClosed = false; om = mw->activeProject()->findChild("om"); tree = mw->activeProject()->getCurrentObjectTree(); tree->expandAll(); } void instDialogInspectTest::cleanupTestCase() { foreach(QString filename, filesToCleanup) if (QFileInfo(filename).exists()) QVERIFY(QFile::remove(filename)); } void instDialogInspectTest::closeInstallOptions() { QVERIFY(dynamic_cast(app->activeModalWidget()) != NULL); dynamic_cast(app->activeModalWidget())->cancelAll(); dialogClosed = true; } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { tree->scrollToItem(item); for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void instDialogInspectTest::closeContextMenu() { QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } menu->hide(); } /* * This function finds and activates an item with given name in the * context menu. If item is absent in the menu or is disabled, it * fails the test. */ void instDialogInspectTest::openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText) { QTimer::singleShot(100, this, SLOT(closeContextMenu())); om->contextMenuRequested(findItemPos(item, tree)); bool found_menu_item = false; QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } QVERIFY(menu != NULL); foreach (QObject *act, menu->children()) { QAction *action = dynamic_cast(act); if (action == NULL) continue; if (action->text() == actionText) { QVERIFY(action->isEnabled() == true); action->activate(QAction::Trigger); found_menu_item = true; break; } } QVERIFY2(found_menu_item == true, QString("Item %1 not found in the context menu").arg(actionText).toAscii().constData()); } void instDialogInspectTest::testInspect(QString firewall) { filesToCleanup.append(firewall+".fw"); ObjectTreeViewItem *treeitem = dynamic_cast(tree->findItems(firewall, Qt::MatchExactly | Qt::MatchRecursive).first()); this->openContextMenu(om, treeitem, tree, "Install"); instDialog *dlg = mw->findChild(); QTest::mouseClick(dlg->findChild("pushButton16"), Qt::LeftButton); QPushButton *back = dlg->findChild("backButton"); QPushButton *next = dlg->findChild("nextButton"); QPushButton *inspect = dlg->findChild("inspectGeneratedFiles"); QTest::mouseClick(next, Qt::LeftButton); QTreeWidget *list= dlg->findChild("fwWorkList"); QTextBrowser *processLogDisplay = dlg->findChild("procLogDisplay"); while (!checkProgress(list)) { QVERIFY(!inspect->isEnabled()); QTest::qWait(50); } QTest::qWait(50); Q_ASSERT(inspect->isEnabled()); QString oldtext = processLogDisplay->toPlainText(); QStackedWidget *stack = dlg->findChild(); QVERIFY(stack->currentIndex() == 1); QTest::mouseClick(inspect, Qt::LeftButton); QVERIFY(stack->currentIndex() == 2); QVERIFY(back->isEnabled()); QVERIFY(next->isEnabled()); QTest::mouseClick(back, Qt::LeftButton); QVERIFY(stack->currentIndex() == 1); QVERIFY(oldtext == processLogDisplay->toPlainText()); QTest::mouseClick(inspect, Qt::LeftButton); QTimer::singleShot(100, this, SLOT(closeInstallOptions())); QTest::mouseClick(next, Qt::LeftButton); QVERIFY(dialogClosed); QVERIFY(stack->currentIndex() == 1); dlg->reject(); QTest::qWait(500); } void instDialogInspectTest::testInspect_firewall() { testInspect("test1"); } void instDialogInspectTest::testInspect_cluster() { testInspect("cluster1"); } void instDialogInspectTest::testInspect_space() { testInspect("firewall name"); } void instDialogInspectTest::testInspect_ascii() { testInspect("firewall !@#$%^&()-+{},;"); } void instDialogInspectTest::testInspect_russian() { testInspect("б€бƒббаКаИаЙ б„аАаЕб€аВаОаЛаЛ"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogInspectTest/instDialogInspectTest.pro0000644000175000017500000000050711733011756031260 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = instDialogInspectTest SOURCES += main_instDialogInspectTest.cpp \ instDialogInspectTest.cpp HEADERS += instDialogInspectTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/instDialogInspectTest/main_instDialogInspectTest.cpp0000644000175000017500000000332011733011756032242 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogInspectTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "instDialogInspectTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new instDialogInspectTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/parseCommandLineTest/0000755000175000017500000000000011733011756024047 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/parseCommandLineTest/parseCommandLineTest.cpp0000644000175000017500000001467311733011756030647 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "parseCommandLineTest.h" #include "config.h" #include "utils.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; void parseCommandLineTest::parseCommandLines() { QStringList argv; parseCommandLine( "/usr/local/bin/ssh -i identity.key -o arg1=val1 -o arg2 val2 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "/usr/local/bin/ssh"); CPPUNIT_ASSERT(argv[1] == "-i"); CPPUNIT_ASSERT(argv[2] == "identity.key"); CPPUNIT_ASSERT(argv[3] == "-o"); CPPUNIT_ASSERT(argv[4] == "arg1=val1"); CPPUNIT_ASSERT(argv[5] == "-o"); CPPUNIT_ASSERT(argv[6] == "arg2"); CPPUNIT_ASSERT(argv[7] == "val2"); CPPUNIT_ASSERT(argv[8] == "foo"); CPPUNIT_ASSERT(argv[9] == "bar"); argv.clear(); parseCommandLine( "/usr/local/bin/ssh -i identity.key -o arg1=val1 -o arg2 val2 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "/usr/local/bin/ssh"); CPPUNIT_ASSERT(argv[1] == "-i"); CPPUNIT_ASSERT(argv[2] == "identity.key"); CPPUNIT_ASSERT(argv[3] == "-o"); CPPUNIT_ASSERT(argv[4] == "arg1=val1"); CPPUNIT_ASSERT(argv[5] == "-o"); CPPUNIT_ASSERT(argv[6] == "arg2"); CPPUNIT_ASSERT(argv[7] == "val2"); CPPUNIT_ASSERT(argv[8] == "foo"); CPPUNIT_ASSERT(argv[9] == "bar"); argv.clear(); parseCommandLine( "-i identity.key -o arg1=val1 -o arg2 val2 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "-i"); CPPUNIT_ASSERT(argv[1] == "identity.key"); CPPUNIT_ASSERT(argv[2] == "-o"); CPPUNIT_ASSERT(argv[3] == "arg1=val1"); CPPUNIT_ASSERT(argv[4] == "-o"); CPPUNIT_ASSERT(argv[5] == "arg2"); CPPUNIT_ASSERT(argv[6] == "val2"); CPPUNIT_ASSERT(argv[7] == "foo"); CPPUNIT_ASSERT(argv[8] == "bar"); argv.clear(); parseCommandLine( " -i identity.key -o arg1=val1 -o arg2 val2 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "-i"); CPPUNIT_ASSERT(argv[1] == "identity.key"); CPPUNIT_ASSERT(argv[2] == "-o"); CPPUNIT_ASSERT(argv[3] == "arg1=val1"); CPPUNIT_ASSERT(argv[4] == "-o"); CPPUNIT_ASSERT(argv[5] == "arg2"); CPPUNIT_ASSERT(argv[6] == "val2"); CPPUNIT_ASSERT(argv[7] == "foo"); CPPUNIT_ASSERT(argv[8] == "bar"); argv.clear(); parseCommandLine( "-i \"identity.key\" -o arg1=val1 -o arg2 val2 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "-i"); CPPUNIT_ASSERT(argv[1] == "identity.key"); CPPUNIT_ASSERT(argv[2] == "-o"); CPPUNIT_ASSERT(argv[3] == "arg1=val1"); CPPUNIT_ASSERT(argv[4] == "-o"); CPPUNIT_ASSERT(argv[5] == "arg2"); CPPUNIT_ASSERT(argv[6] == "val2"); CPPUNIT_ASSERT(argv[7] == "foo"); CPPUNIT_ASSERT(argv[8] == "bar"); argv.clear(); parseCommandLine( "/usr/local/bin/program -arg1 \"val1 'val2 val3' val4\" -o arg1=val1 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "/usr/local/bin/program"); CPPUNIT_ASSERT(argv[1] == "-arg1"); CPPUNIT_ASSERT(argv[2] == "val1 'val2 val3' val4"); CPPUNIT_ASSERT(argv[3] == "-o"); CPPUNIT_ASSERT(argv[4] == "arg1=val1"); CPPUNIT_ASSERT(argv[5] == "foo"); CPPUNIT_ASSERT(argv[6] == "bar"); argv.clear(); parseCommandLine( "/usr/local/bin/program -arg1 \"val1 'val2 \"val3 val4\" val5' val6\" -o arg1=val1 foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "/usr/local/bin/program"); CPPUNIT_ASSERT(argv[1] == "-arg1"); CPPUNIT_ASSERT(argv[2] == "val1 'val2 \"val3 val4\" val5' val6"); CPPUNIT_ASSERT(argv[3] == "-o"); CPPUNIT_ASSERT(argv[4] == "arg1=val1"); CPPUNIT_ASSERT(argv[5] == "foo"); CPPUNIT_ASSERT(argv[6] == "bar"); argv.clear(); parseCommandLine( "c:\\putty\\plink.exe -i identity.key -q foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "c:\\putty\\plink.exe"); CPPUNIT_ASSERT(argv[1] == "-i"); CPPUNIT_ASSERT(argv[2] == "identity.key"); CPPUNIT_ASSERT(argv[3] == "-q"); CPPUNIT_ASSERT(argv[4] == "foo"); CPPUNIT_ASSERT(argv[5] == "bar"); argv.clear(); parseCommandLine( "c:\\Program Files\\plink.exe -i identity.key -q foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "c:\\Program Files\\plink.exe"); CPPUNIT_ASSERT(argv[1] == "-i"); CPPUNIT_ASSERT(argv[2] == "identity.key"); CPPUNIT_ASSERT(argv[3] == "-q"); CPPUNIT_ASSERT(argv[4] == "foo"); CPPUNIT_ASSERT(argv[5] == "bar"); argv.clear(); parseCommandLine( "c:\\Program Files\\plink.exe -i \"c:\\Documents and Settings\\firewall\\identity.key\" -q foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "c:\\Program Files\\plink.exe"); CPPUNIT_ASSERT(argv[1] == "-i"); CPPUNIT_ASSERT(argv[2] == "c:\\Documents and Settings\\firewall\\identity.key"); CPPUNIT_ASSERT(argv[3] == "-q"); CPPUNIT_ASSERT(argv[4] == "foo"); CPPUNIT_ASSERT(argv[5] == "bar"); argv.clear(); parseCommandLine( "c:\\Program Files\\plink.exe -i 'c:\\Documents and Settings\\firewall\\identity.key' -q foo bar", argv); qDebug() << argv; CPPUNIT_ASSERT(argv[0] == "c:\\Program Files\\plink.exe"); CPPUNIT_ASSERT(argv[1] == "-i"); CPPUNIT_ASSERT(argv[2] == "c:\\Documents and Settings\\firewall\\identity.key"); CPPUNIT_ASSERT(argv[3] == "-q"); CPPUNIT_ASSERT(argv[4] == "foo"); CPPUNIT_ASSERT(argv[5] == "bar"); } fwbuilder-5.1.0.3599/src/unit_tests/parseCommandLineTest/parseCommandLineTest.h0000644000175000017500000000222711733011756030304 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef RCSTEST_H #define RCSTEST_H #include class parseCommandLineTest : public CppUnit::TestFixture { public: void parseCommandLines(); CPPUNIT_TEST_SUITE(parseCommandLineTest); CPPUNIT_TEST(parseCommandLines); CPPUNIT_TEST_SUITE_END(); }; #endif // RCSTEST_H fwbuilder-5.1.0.3599/src/unit_tests/parseCommandLineTest/main_parseCommandLineTest.cpp0000644000175000017500000000265111733011756031644 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "parseCommandLineTest.h" #include #include //int fwbdebug = 0; //QString user_name; int fwbdebug = 0; void *mw = NULL; void *st = NULL; void *app = NULL; void *wfl; int sig = FWB_SIG; int main( int, char** ) { CppUnit::TextUi::TestRunner runner; runner.addTest( parseCommandLineTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/parseCommandLineTest/parseCommandLineTest.pro0000644000175000017500000000026311733011756030653 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS += parseCommandLineTest.h SOURCES += main_parseCommandLineTest.cpp parseCommandLineTest.cpp TARGET = parseCommandLineTest fwbuilder-5.1.0.3599/src/unit_tests/startTipDialogTest/0000755000175000017500000000000011733011756023560 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/startTipDialogTest/main_startTipDialogTest.cpp0000644000175000017500000000330711733011756031065 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_startTipDialogTest.cpp 2948 2010-06-02 19:11:31Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "startTipDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new startTipDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/startTipDialogTest/startTipDialogTest.pro0000644000175000017500000000027011733011756030073 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = startTipDialogTest HEADERS += startTipDialogTest.h SOURCES += main_startTipDialogTest.cpp \ startTipDialogTest.cpp fwbuilder-5.1.0.3599/src/unit_tests/startTipDialogTest/startTipDialogTest.h0000644000175000017500000000236511733011756027531 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: startTipDialogTest.h 3043 2010-06-30 14:19:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWWINDOWTEST_H #define FWWINDOWTEST_H #include #include #include class startTipDialogTest : public QObject { Q_OBJECT public: startTipDialogTest(QWidget *parent = 0); private slots: void testDialogAppear(); void testDialogNotAppear(); void cleanupTestCase(); }; #endif // FWWINDOWTEST_H fwbuilder-5.1.0.3599/src/unit_tests/startTipDialogTest/startTipDialogTest.cpp0000644000175000017500000000643211733011756030063 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: startTipDialogTest.cpp 3043 2010-06-30 14:19:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "startTipDialogTest.h" #include "FWWindow.h" #include "FWBApplication.h" #include "StartTipDialog.h" #include #include "global.h" #include "FWBSettings.h" #include #include #include #include #include "common/commoninit.h" #include "platforms.h" startTipDialogTest::startTipDialogTest(QWidget *parent) : QObject(parent) { } void startTipDialogTest::testDialogAppear() { st->setBool("UI/NoStartTip", false); st->setBool("UI/FirstRun", true); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *dialog = NULL; for(int i=0; i<10; i++) { qDebug() << "app->topLevelWidgets():"; foreach (QWidget *widget, QApplication::topLevelWidgets()) { if (dynamic_cast(widget) != NULL) { qDebug() << widget << "isHidden()=" << widget->isHidden(); if (widget->objectName() == "StartTipDialog_q") dialog = dynamic_cast(widget); } } // qDebug() << "app->activeWindow()=" << app->activeWindow(); // dialog = dynamic_cast(app->activeWindow()); qDebug() << "--"; if (dialog == NULL) QTest::qWait(1000); else break; } Q_ASSERT(dialog != NULL); QPushButton *prevTip = dialog->findChild("prevTipButton"); QPushButton *nextTip = dialog->findChild("nextTipButton"); QTextBrowser *textview = dialog->findChild("textview"); QString oldtext = textview->toPlainText(); QTest::mouseClick(prevTip, Qt::LeftButton); QVERIFY(oldtext != textview->toPlainText()); oldtext = textview->toPlainText(); QTest::mouseClick(nextTip, Qt::LeftButton); QVERIFY(oldtext != textview->toPlainText()); dialog->reject(); mw->hide(); mw->deleteLater(); } void startTipDialogTest::testDialogNotAppear() { st->setBool("UI/NoStartTip", true); st->setBool("UI/FirstRun", false); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *dialog = NULL; for(int i=0; i<10; i++) { dialog = dynamic_cast(app->activeWindow()); if (dialog == NULL) QTest::qWait(1000); else break; } Q_ASSERT(dialog == NULL); } void startTipDialogTest::cleanupTestCase() { } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/0000755000175000017500000000000011733011756025634 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/generatedScriptTestsSecuwall.cpp0000644000175000017500000001057311733011756034214 0ustar sylvestresylvestre/* * generatedScriptTestsSecuwall.h - secuwall unit tests * * Copyright (c) 2010 secunet Security Networks AG * Copyright (c) 2010 Adrian-Ken Rueegsegger * Copyright (c) 2010 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "../../config.h" #include "generatedScriptTestsSecuwall.h" #include "CompilerDriver_ipt.h" #include "Configlet.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; void GeneratedScriptTest::setUp() { // register protocols we need IPService::addNamedProtocol(51, "ah"); IPService::addNamedProtocol(112, "vrrp"); Configlet::setDebugging(true); } void GeneratedScriptTest::tearDown() { } void GeneratedScriptTest::loadDataFile(const string &file_name) { /* load the data file */ UpgradePredicate upgrade_predicate; objdb->setReadOnly( false ); objdb->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(file_name); objdb->reIndex(); } void GeneratedScriptTest::runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name) { loadDataFile(test_file); QStringList args; args << firewall_object_name.c_str(); CompilerDriver_ipt driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipt initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file secuwall-1.fw and test1 directory with // secuwall-specific configuration files. QFileInfo fi(generate_file_name.c_str()); CPPUNIT_ASSERT_MESSAGE("Generated file " + generate_file_name + " not found", fi.exists() == true); } void GeneratedScriptTest::assertDirsEqual(const std::string &left_dir, const std::string &right_dir) { QStringList leftList, rightList; QDirIterator leftIt(QString (left_dir.c_str()), QDir::Files, QDirIterator::Subdirectories); QDirIterator rightIt(QString (right_dir.c_str()), QDir::Files, QDirIterator::Subdirectories); while (leftIt.hasNext() && rightIt.hasNext()) { leftList += leftIt.next(); rightList += rightIt.next(); } if (leftIt.hasNext()) { CPPUNIT_FAIL("Directory " + left_dir + " contains more files than " + right_dir); } if (rightIt.hasNext()) { CPPUNIT_FAIL("Directory " + right_dir + " contains more files than " + left_dir); } leftList.sort(); rightList.sort(); QList::const_iterator i, j; for (i = leftList.constBegin(), j = rightList.constBegin(); i != leftList.constEnd(); ++i, ++j) { assertFilesEqual(QString(*i).toStdString(), QString(*j).toStdString()); } } void GeneratedScriptTest::assertFilesEqual(const std::string &left_filename, const std::string &right_filename) { bool result = false; QFile leftFile(left_filename.c_str()); QFile rightFile(right_filename.c_str()); if (leftFile.open(QFile::ReadOnly) && rightFile.open(QFile::ReadOnly)) { result = leftFile.readAll() == rightFile.readAll(); leftFile.close(); rightFile.close(); } CPPUNIT_ASSERT_MESSAGE("Files " + left_filename + " and " + right_filename + " differ", result); } void GeneratedScriptTest::FilesGenerationTest() { const string fwname ("secuwall-1"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "secuwall_cluster_1", "secuwall-1.fw"); delete objdb; assertDirsEqual("ref.secuwall-1", "secuwall-1"); } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/generatedScriptTestsSecuwall.h0000644000175000017500000000272611733011756033662 0ustar sylvestresylvestre/* * generatedScriptTestsSecuwall.h - secuwall unit tests * * Copyright (c) 2010 secunet Security Networks AG * Copyright (c) 2010 Adrian-Ken Rueegsegger * Copyright (c) 2010 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef GENERATEDSCRIPTTESTS_SECUWALL_H #define GENERATEDSCRIPTTESTS_SECUWALL_H #include #include "fwbuilder/FWObjectDatabase.h" class GeneratedScriptTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *objdb; void loadDataFile(const std::string &file_name); void runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name); void assertDirsEqual(const std::string &left_dir, const std::string &right_dir); void assertFilesEqual(const std::string &left_filename, const std::string &right_filename); public: void setUp(); void tearDown(); void FilesGenerationTest(); CPPUNIT_TEST_SUITE(GeneratedScriptTest); CPPUNIT_TEST(FilesGenerationTest); CPPUNIT_TEST_SUITE_END(); }; #endif // GENERATEDSCRIPTTESTS_SECUWALL_H fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/ref.secuwall-1.tar.gz0000644000175000017500000000166111733011756031517 0ustar sylvestresylvestre‹&шТKэ™[sЂ0€}•_САЯuЎлёЂuЎр лNŸ: —Y'СК§ї№ŽЕд–вv<_Ї#‰€'_rЂ”єkŒГЙ?Ÿся•ї!$š–МbУP“W„tyёК ‚БЂ#MW‘ЂTVR*Ђі.w“aЦbŸŠb…Ю02њd;оЌп/у†Ъ…юЦ?dl>Šƒa-ˆТТž6 ЗЊŒПЬcО]УЈ"ЂЂnр9N<ўSŸGќўgЕк иаПцыт€FГщК$ #ГUQМ™@т!Ёы*!$ёФgyХК<шІ<ЅQбx]AЇСІoBFYПїбЭIёŸ Е?пЌYџБЎ€џeРˆOƒaЕJўљ“щ˜№ШO„аŸDFBЋј\Ўa§G зd„НН!ƒУŸŒџщ _tyў#CЫјЏ!]џЫЫF ё?\G?Nт/пФоrHˆщ€ж#D7~+`їз'у?{dЩк?Й<~џЇѓ9іep0ўЫд§Œt4й[ЦУбё—1пBќЫрХёѕƒўрŒяї№б}ф­џ Т™јѓ жџ2h4ЏлVГ.%•„ ЧёКЎу9u)ŒB" эЎйhИui+Ћ—ЛщuЬоU]’5­ЖњGi§у^mЗцЕЎc6,Гчэ\Eг$СБ“ўъв#a’№Лmѓ3%ЁcZ‹.љЁї‡ŸЃ!~гэ.лyЗнХэЪ‡Ј9Шл8вџJЇGOЙўc-ыђ• ј_+џгРОhРŸbHю—_кь5љЌІЏў0П Џ№џh-ѓ§—їќ— №П Ж§GЯљoШ5YMО(xBД+џЊiЦ§Eѕђœ‚хG џы8>џ?оЪмпџ }/џџЫa+џ‘ўOЅџeыЩqєт‡ў€LHПЙ<џU%Лџчu2ј_Vчn+ƒNŠэюnЂЎŠл%…лъДіёyЁgwК{ѕxYo9К4yМcсdЪb: |Ъ№ілsнЏЙяІы%“€uйZк.WŸOщAі4ѕœŸцКнFк"9ъ5-ЗщЅ]&йт4™0јФх5нД•хиЖчšжUc]М;Нt"o§/ЂмпџхŒџиP1ьџKaЙlЗэVjAЫєš7цm"мђ0UB~9=Я6;|ѕнŒIИtмгmpЏех§б'Р_ИPfwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/test1.fwb0000644000175000017500000026301611733011756027404 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/generatedScriptTestsSecuwall.pro0000644000175000017500000000116411733011756034226 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS = generatedScriptTestsSecuwall.h SOURCES = main_generatedScriptTestsSecuwall.cpp \ generatedScriptTestsSecuwall.cpp TARGET = generatedScriptTestsSecuwall run_tests.commands = echo "Running tests..." && \ ./${TARGET} && \ echo "OK" || { echo "FAILED"; exit 1; } build_tests.commands = @tar -zxf ./ref.secuwall-1.tar.gz clean_tests.commands = @rm -rf ./secuwall-* && \ rm -rf ./ref.secuwall-1 && \ rm -f ${TARGET} run_tests.depends = build_tests build_tests.depends = all clean_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests build_tests clean_tests ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootfwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/main_generatedScriptTestsSecuwall.cppfwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsSecuwall/main_generatedScriptTestsSecuwall.c0000644000175000017500000000272711733011756034662 0ustar sylvestresylvestre/* * generatedScriptTestsSecuwall.h - secuwall unit test runner * * Copyright (c) 2010 secunet Security Networks AG * Copyright (c) 2010 Adrian-Ken Rueegsegger * Copyright (c) 2010 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "../../config.h" #include "generatedScriptTestsSecuwall.h" #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include "../../../common/init.cpp" using namespace std; using namespace libfwbuilder; int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( GeneratedScriptTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/0000755000175000017500000000000011733011756024762 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/main_generatedScriptTestsIpfw.cpp0000644000175000017500000000343511733011756033473 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsIpfw.h" #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include "../../../common/init.cpp" using namespace std; using namespace libfwbuilder; int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( GeneratedScriptTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/.gitignore0000644000175000017500000000001011733011756026741 0ustar sylvestresylvestreipfw2-1 fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/generatedScriptTestsIpfw.pro0000644000175000017500000000052711733011756032504 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS = generatedScriptTestsIpfw.h SOURCES = main_generatedScriptTestsIpfw.cpp \ generatedScriptTestsIpfw.cpp TARGET = generatedScriptTestsIpfw run_tests.commands = echo "Running tests..." && \ rm -f *.fw *.conf && \ ./${TARGET} && \ echo "OK" || { echo "FAILED"; exit 1; } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/generatedScriptTestsIpfw.h0000644000175000017500000000453711733011756032140 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GENERATEDSCRIPTTESTS_IPFILTER_H #define GENERATEDSCRIPTTESTS_IPFILTER_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include class GeneratedScriptTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *objdb; void loadDataFile(const std::string &file_name); void runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name, const std::string &output_file_option=""); public: void setUp(); void tearDown(); void ManifestTest_1(); void ManifestTest_2(); void ManifestTest_3(); void ManifestTest_4(); void ManifestTest_5(); void ManifestTest_6(); void ManifestTest_7(); void FwCommentTest(); CPPUNIT_TEST_SUITE(GeneratedScriptTest); // The order of tests matters because activation commands tests use // files produced in manifest tests CPPUNIT_TEST(ManifestTest_1); CPPUNIT_TEST(ManifestTest_2); CPPUNIT_TEST(ManifestTest_3); CPPUNIT_TEST(ManifestTest_4); // CPPUNIT_TEST(ManifestTest_5); // CPPUNIT_TEST(ActivationCommandsTest_5); CPPUNIT_TEST(ManifestTest_6); CPPUNIT_TEST(ManifestTest_7); CPPUNIT_TEST(FwCommentTest); CPPUNIT_TEST_SUITE_END(); }; #endif // GENERATEDSCRIPTTESTS_IPFILTER_H fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/test1.fwb0000644000175000017500000030267211733011756026534 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfw/generatedScriptTestsIpfw.cpp0000644000175000017500000001510611733011756032465 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsIpfw.h" #include "CompilerDriver_ipfw.h" #include "Configlet.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; void GeneratedScriptTest::setUp() { Configlet::setDebugging(true); } void GeneratedScriptTest::tearDown() { } void GeneratedScriptTest::loadDataFile(const string &file_name) { /* load the data file */ UpgradePredicate upgrade_predicate; objdb->setReadOnly( false ); objdb->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(file_name); objdb->reIndex(); } void GeneratedScriptTest::runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name, const std::string &output_file_option) { loadDataFile(test_file); QStringList args; if (!output_file_option.empty()) { args << "-o" << output_file_option.c_str(); } args << firewall_object_name.c_str(); CompilerDriver_ipfw driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipfw initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file generate_file_name QFileInfo fi(generate_file_name.c_str()); CPPUNIT_ASSERT_MESSAGE("Generated file " + generate_file_name + " not found", fi.exists() == true); } // I can check only certain parts of the top comment. Can't // compare against "golden" file because some parts of the comment // are variable, such as date, version and build number void GeneratedScriptTest::ManifestTest_1() { QFile::remove("ipfw1.fw"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipfw1", "ipfw1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipfw1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipfw1.fw") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_2() { /* * output script name is set to ipfw2-1.fw in the fw object. */ QFile::remove("ipfw2-1.fw"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipfw2", "ipfw2-1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipfw2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipfw2-1.fw") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_3() { /* * output script name is set to ipfw2-1 in the fw object (no extension) */ QFile::remove("ipfw2-1"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipfw2a", "ipfw2-1"); QString res = Configlet::findConfigletInFile("top_comment", "ipfw2-1"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipfw2-1") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_4() { /* * Compile ipfw2 and ipfw2a adding "-o" option as instDialog does */ objdb = new FWObjectDatabase(); QString option_o = QDir::currentPath() + "/ipfw2-1.fw"; QFile::remove(option_o); runCompiler("test1.fwb", "ipfw2", "ipfw2-1.fw", option_o.toStdString()); QString res = Configlet::findConfigletInFile("top_comment", "ipfw2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + option_o) != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_5() { objdb = new FWObjectDatabase(); QString option_o = QDir::currentPath() + "/ipfw2-1"; QFile::remove(option_o); runCompiler("test1.fwb", "ipfw2a", "ipfw2-1.fw", option_o.toStdString()); QString res = Configlet::findConfigletInFile("top_comment", "ipfw2-1"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipfw2-1") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_6() { /* * remote ipfw and nat files are configured as /etc/fw/ipfw3-ipfw.conf and * /etc/fw/ipfw3-nat.conf in ipfw3 */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipfw3", "ipfw3.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipfw3.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipfw3.fw") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_7() { /* * remote ipfw and nat files in ipfw4 have spaces in the path */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipfw4", "ipfw4.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipfw4.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipfw4.fw /etc/path\\ with\\ space/ipfw4.fw") != -1); delete objdb; } // ************************************************************************ void GeneratedScriptTest::FwCommentTest() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipfw1", "ipfw1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipfw1.fw"); // find string from the firewall object comment and compare CPPUNIT_ASSERT(res.indexOf("# Firewall object test1 comment") != -1); delete objdb; } fwbuilder-5.1.0.3599/src/unit_tests/ObjectManipulatorTest/0000755000175000017500000000000011733011756024250 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/ObjectManipulatorTest/test.fwb0000644000175000017500000024210111733011756025727 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/ObjectManipulatorTest/ObjectManipulatorTest.pro0000644000175000017500000000050711733011756031256 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = ObjectManipulatorTest SOURCES += main_ObjectManipulatorTest.cpp \ ObjectManipulatorTest.cpp HEADERS += ObjectManipulatorTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/ObjectManipulatorTest/ObjectManipulatorTest.h0000644000175000017500000000207711733011756030711 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECTMANIPULATORTEST_H #define OBJECTMANIPULATORTEST_H #include class ObjectManipulatorTest : public QObject { Q_OBJECT private slots: void editSelectedObject(); }; #endif // OBJECTMANIPULATORTEST_H fwbuilder-5.1.0.3599/src/unit_tests/ObjectManipulatorTest/ObjectManipulatorTest.cpp0000644000175000017500000000566411733011756031251 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ObjectManipulatorTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "fwbuilder/RuleSet.h" using namespace std; using namespace libfwbuilder; QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void ObjectManipulatorTest::editSelectedObject() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->loadFile("test.fwb", false); ObjectTreeView *tree = mw->getCurrentObjectTree(); tree->expandAll(); ObjectTreeViewItem *policy = dynamic_cast( tree->findItems("Policy", Qt::MatchRecursive | Qt::MatchExactly, 0).first()); ObjectTreeViewItem *fw = dynamic_cast( tree->findItems("TestFirewall", Qt::MatchRecursive | Qt::MatchExactly, 0).first()); ObjectManipulator *om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); tree->setCurrentItem( policy, 0, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); om->editSelectedObject(); QTest::qWait(100); QVERIFY(mw->getOpenedEditor() == NULL); QVERIFY(mw->activeProject()->getCurrentRuleSet() == RuleSet::cast(policy->getFWObject())); om->editSelectedObject(); QTest::qWait(100); QVERIFY(mw->getOpenedEditor() == policy->getFWObject()); mw->closeEditor(); tree->setCurrentItem( fw, 0, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); om->editSelectedObject(); QTest::qWait(100); QVERIFY(mw->getOpenedEditor() == fw->getFWObject()); } fwbuilder-5.1.0.3599/src/unit_tests/ObjectManipulatorTest/main_ObjectManipulatorTest.cpp0000644000175000017500000000322111733011756032240 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ObjectManipulatorTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new ObjectManipulatorTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/newClusterDialogTest/0000755000175000017500000000000011733011756024101 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/newClusterDialogTest/test.fwb0000644000175000017500000010400611733011756025561 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/unit_tests/newClusterDialogTest/newClusterDialogTest.h0000644000175000017500000000266611733011756030377 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef NEWCLUSTERDIALOGTEST_H #define NEWCLUSTERDIALOGTEST_H #include #include "newClusterDialog.h" #include "upgradePredicate.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "ObjectManipulator.h" class newClusterDialogTest : public QObject { Q_OBJECT void openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText); private slots: void test1(); void test2(); void test3(); public slots: void initTestCase(); void closeContextMenu(); void test3_part2(); }; #endif // NEWCLUSTERDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/newClusterDialogTest/newClusterDialogTest.pro0000644000175000017500000000050511733011756030736 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = newClusterDialogTest SOURCES += main_newClusterDialogTest.cpp \ newClusterDialogTest.cpp HEADERS += newClusterDialogTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/newClusterDialogTest/main_newClusterDialogTest.cpp0000644000175000017500000000321711733011756031727 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "newClusterDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new newClusterDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/newClusterDialogTest/newClusterDialogTest.cpp0000644000175000017500000003234511733011756030727 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "newClusterDialogTest.h" #include #include #include "ui_newclusterdialog_q.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ProjectPanel.h" #include "StartTipDialog.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "FWObjectClipboard.h" #include "FWBApplication.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Constants.h" using namespace libfwbuilder; using namespace std; class newClusterDialog_ext: public newClusterDialog { public: newClusterDialog_ext(QWidget *parent, libfwbuilder::FWObject* obj): newClusterDialog(parent, obj) { } Ui::newClusterDialog_q* getUi() { return this->m_dialog; } QStringList getFirewallList() { QStringList res; for (int i=0; im_dialog->firewallSelector->rowCount(); i++) { res.append(this->m_dialog->firewallSelector->item(i, 0)->text()); } return res; } }; void newClusterDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); QTest::qWait(5000); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); } void newClusterDialogTest::test1() { //init(); FWObjectDatabase *db = new FWObjectDatabase(); XMLTools::UpgradePredicate p; db->load("test_work.fwb", &p, Constants::getDTDDirectory()); newClusterDialog_ext *dialog = new newClusterDialog_ext(NULL, db); vector fws; QStringList fwnames; foreach(FWObject *obj, db->getByTypeDeep(Firewall::TYPENAME)) { fws.push_back(obj); fwnames.append(obj->getName().c_str()); } dialog->setFirewallList(fws); dialog->setModal(false); dialog->show(); QStringList dfws = dialog->getFirewallList(); QVERIFY(dfws.count() == int(fws.size())); foreach( QString fwname, dfws) QVERIFY(fwnames.contains(fwname)); QVERIFY(!dialog->getUi()->nextButton->isEnabled()); QTest::keyClicks(dialog->getUi()->obj_name, "New Cluster"); QVERIFY(dialog->getUi()->nextButton->isEnabled()); for (int i=0; i< dialog->getUi()->firewallSelector->rowCount(); i++) dynamic_cast(dialog->getUi()->firewallSelector->cellWidget(i, 1))->setChecked(true); dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==1); QList ifaces = dialog->getUi()->interfaceSelector->getInterfaces(); foreach (ClusterInterfaceData iface, ifaces) { QVERIFY(iface.interfaces.count() == 2); for(int i=0; i < iface.interfaces.count(); i++) QVERIFY(iface.interfaces.at(i).second->getName().c_str() == iface.name); } dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==2); for (int i=1; igetUi()->interfaceEditor->count(); i++) dynamic_cast(dialog->getUi()->interfaceEditor->widget(i))->setProtocolIndex(2); InterfaceEditorWidget* eth0 = qFindChild(dialog->getUi()->interfaceEditor, "eth0_widget"); eth0->setProtocolIndex(0); eth0->addNewAddress("123.45.67.89", "24", true); QList addresses = dialog->getUi()->interfaceEditor->getNewData(); foreach( EditedInterfaceData iface, addresses) { if (iface.name == "eth0") { qDebug() << iface.addresses.values().count(); QVERIFY(iface.addresses.values().count() == 1); QVERIFY(iface.addresses.values().first().address == "123.45.67.89"); QVERIFY(iface.addresses.values().first().netmask == "24"); break; } } dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==3); dialog->getUi()->backButton->click(); QVERIFY(dialog->currentPage()==2); QList addresses2 = dialog->getUi()->interfaceEditor->getNewData(); foreach( EditedInterfaceData iface, addresses2) { if (iface.name == "eth0") { QVERIFY(iface.addresses.values().count() == 1); QVERIFY(iface.addresses.values().first().address == "123.45.67.89"); QVERIFY(iface.addresses.values().first().netmask == "24"); } } dialog->getUi()->interfaceEditor->setCurrentIndex(1); InterfaceEditorWidget* eth1 = qFindChild(dialog->getUi()->interfaceEditor, "eth1_widget"); eth1->setProtocolIndex(0); QTableWidget *addrs = eth1->findChild("addresses"); QVERIFY(addrs != NULL); QPushButton *addaddr = eth1->findChild("addAddress"); QVERIFY(addaddr != NULL); addaddr->click(); addrs->item(0,0)->setText("98.76.54.32"); addrs->item(0,1)->setText("24"); dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==3); dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==4); QVERIFY(dialog->getUi()->finishButton->isEnabled()); dialog->getUi()->finishButton->click(); Cluster *newc = dialog->getNewCluster(); QVERIFY(newc != NULL); QVERIFY(Cluster::isA(newc)); dialog->findChild("cancelButton")->click(); dialog->accept(); dialog->close(); dialog->deleteLater(); } void newClusterDialogTest::test2() { mw->loadFile("test_work.fwb", false); FWObjectDatabase *db = mw->db(); Library *lib = NULL; foreach(FWObject *obj, db->getByTypeDeep(Library::TYPENAME)) { qDebug() << obj->getName().c_str(); if (obj->getName() == "new_cluster_test") lib = Library::cast(obj); } QVERIFY(lib != NULL); newClusterDialog_ext *dialog = new newClusterDialog_ext(NULL, FWBTree().getStandardSlotForObject(lib, Cluster::TYPENAME)); vector fws; QStringList fwnames; foreach(FWObject *obj, db->getByTypeDeep(Firewall::TYPENAME)) { fws.push_back(obj); fwnames.append(obj->getName().c_str()); } dialog->setFirewallList(fws); dialog->setModal(false); dialog->show(); QStringList dfws = dialog->getFirewallList(); QVERIFY(dfws.count() == int(fws.size())); foreach( QString fwname, dfws) QVERIFY(fwnames.contains(fwname)); QVERIFY(!dialog->getUi()->nextButton->isEnabled()); QTest::keyClicks(dialog->getUi()->obj_name, "New Cluster"); QVERIFY(dialog->getUi()->nextButton->isEnabled()); for (int i=0; i< dialog->getUi()->firewallSelector->rowCount(); i++) dynamic_cast(dialog->getUi()->firewallSelector->cellWidget(i, 1))->setChecked(true); dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==1); dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==2); dynamic_cast(dialog->getUi()->interfaceEditor->widget(0))->setProtocolIndex(3); dynamic_cast(dialog->getUi()->interfaceEditor->widget(1))->setProtocolIndex(3); dynamic_cast(dialog->getUi()->interfaceEditor->widget(2))->setProtocolIndex(3); dynamic_cast(dialog->getUi()->interfaceEditor->widget(3))->setProtocolIndex(3); dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==3); QList btns= dialog->getUi()->page_4->findChildren(); foreach(QRadioButton *btn, btns) { if (btn->objectName() == "linux-1") QTest::mouseClick(btn, Qt::LeftButton); } dialog->getUi()->nextButton->click(); QVERIFY(dialog->currentPage()==4); QVERIFY(dialog->getUi()->finishButton->isEnabled()); dialog->getUi()->finishButton->click(); Cluster *newc = dialog->getNewCluster(); QVERIFY(newc != NULL); QVERIFY(Cluster::isA(newc)); Firewall *bak = Firewall::cast(mw->getCurrentLib()->findObjectByName(Firewall::TYPENAME, "linux-1-bak")); QVERIFY(bak != NULL); QVERIFY(bak->getInactive() == true); Firewall *linux1 = Firewall::cast(mw->getCurrentLib()->findObjectByName(Firewall::TYPENAME, "linux-1")); QVERIFY(linux1 != NULL); QVERIFY(linux1->getPolicy()->getChildrenCount() == 1); // there should be only RuleSetOptions object dialog->findChild("cancelButton")->click(); dialog->accept(); dialog->close(); dialog->deleteLater(); } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if((tree->itemAt(w,h)) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void newClusterDialogTest::closeContextMenu() { foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { qDebug() << w; w->hide(); } } } void newClusterDialogTest::openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText) { QTimer::singleShot(1000, this, SLOT(closeContextMenu())); om->contextMenuRequested(findItemPos(item, tree)); QMenu *menu; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } foreach (QObject *act, menu->children()) { QAction *action = dynamic_cast(act); if (action == NULL) continue; if (action->text() == actionText) { QTimer::singleShot(100, this, SLOT(test3_part2())); action->trigger(); break; } } } void newClusterDialogTest::test3() { mw->loadFile("test_work.fwb", false); FWObjectDatabase *db = mw->db(); Library *lib = NULL; foreach(FWObject *obj, db->getByTypeDeep(Library::TYPENAME)) { qDebug() << obj->getName().c_str(); if (obj->getName() == "new_cluster_test") lib = Library::cast(obj); } QVERIFY(lib != NULL); mw->show(); ObjectManipulator *om = mw->activeProject()->findChild("om"); om->openLib(lib); QVERIFY ( om->getCurrentLib() == lib); ObjectTreeView *tree = mw->getCurrentObjectTree(); ObjectTreeViewItem *linux1 = dynamic_cast(tree->findItems("linux-1", Qt::MatchContains | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *linux2 = dynamic_cast(tree->findItems("linux-2", Qt::MatchContains | Qt::MatchRecursive, 0).first()); tree->selectionModel()->select(tree->indexAt(findItemPos(linux1, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(linux1); tree->selectionModel()->select(tree->indexAt(findItemPos(linux2, tree)), QItemSelectionModel::Select); openContextMenu(om, linux2, tree, "New cluster from selected firewalls"); } void newClusterDialogTest::test3_part2() { QTest::qWait(100); newClusterDialog *dialog = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dialog = dynamic_cast(w); QVERIFY(dialog != NULL); QPushButton *nextButton = dialog->findChild("nextButton"); QPushButton *finishButton = dialog->findChild("finishButton"); InterfacesTabWidget *interfaceEditor = dialog->findChild("interfaceEditor"); QLineEdit *obj_name = dialog->findChild("obj_name"); QVERIFY(nextButton != NULL); QVERIFY(finishButton != NULL); QVERIFY(interfaceEditor != NULL); QVERIFY(obj_name != NULL); QTest::keyClicks(obj_name, "New Cluster"); QVERIFY(nextButton->isEnabled()); nextButton->click(); QVERIFY(dialog->currentPage()==1); QTest::qWait(1000); nextButton->click(); QVERIFY(dialog->currentPage()==2); dynamic_cast(interfaceEditor->widget(0))->setProtocolIndex(3); dynamic_cast(interfaceEditor->widget(1))->setProtocolIndex(3); dynamic_cast(interfaceEditor->widget(2))->setProtocolIndex(3); dynamic_cast(interfaceEditor->widget(3))->setProtocolIndex(3); nextButton->click(); QVERIFY(dialog->currentPage()==3); nextButton->click(); QVERIFY(dialog->currentPage()==4); QVERIFY(finishButton->isEnabled()); finishButton->click(); Cluster *newc = dialog->getNewCluster(); QVERIFY(newc != NULL); QVERIFY(Cluster::isA(newc)); } fwbuilder-5.1.0.3599/src/unit_tests/genericDialogTest/0000755000175000017500000000000011733011756023362 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/genericDialogTest/genericDialogTest.h0000644000175000017500000000334511733011756027134 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: genericDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef genericDialogTest_H #define genericDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" #include "fwbuilder/Cluster.h" class genericDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; bool dialog_rejected; QList scanDialog(QWidget*); bool testControl(QWidget* control); void testDialog(QWidget *dialog, libfwbuilder::FWObject *object); void activateTab(QWidget *widget); private slots: void initTestCase(); void testFirewallSettingsDialog_iptables(); /* void testRuleOptionsDialog(); */ /* void testRoutingRuleOptionsDialog(); */ /* void testNATRuleOptionsDialog(); */ void testHostOSSettingsDialog_linux24(); public slots: //void rejectDialog(); }; #endif // genericDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/genericDialogTest/genericDialogTest.cpp0000644000175000017500000003317411733011756027472 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: genericDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "genericDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "FirewallDialog.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "genericDialogTest.h" #include "fwbuilder/IPService.h" #include "DialogFactory.h" #include "FWCmdChange.h" #include "RuleOptionsDialog.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Routing.h" #include "fwbuilder/NAT.h" #include "RoutingRuleOptionsDialog.h" #include "platforms.h" #include "NATRuleOptionsDialog.h" using namespace std; using namespace libfwbuilder; void genericDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); mw->resize(1200, 600); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); init_platforms(); QTest::qWait(1000); } QList genericDialogTest::scanDialog(QWidget *dialog) { QList result; foreach(QLineEdit *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QCheckBox *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QComboBox *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QRadioButton *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QTextEdit *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(TextEditWidget *item, dialog->findChildren()) result.append(dynamic_cast(item)); foreach(QSpinBox *item, dialog->findChildren()) result.append(dynamic_cast(item)); return result; } // Activates tab which contains widget void genericDialogTest::activateTab(QWidget *widget) { QWidget *current = widget; while (current->parent() != NULL) { if (dynamic_cast(current->parent()) != NULL) { QTabWidget *tabs = dynamic_cast(current->parent()); for (int i=0; icount(); i++) { if (tabs->widget(i)->findChildren(widget->objectName()).contains(widget)) { tabs->setCurrentIndex(i); break; } } } current = dynamic_cast(current->parent()); } } bool genericDialogTest::testControl(QWidget *control) { if (dynamic_cast(control) != NULL) { QSpinBox *box = dynamic_cast(control); QTest::keyClick(box, Qt::Key_Up); QTest::keyClick(box, Qt::Key_Up); QTest::keyClick(box, Qt::Key_Enter); QTest::keyClick(box, Qt::Key_Tab); } else if (dynamic_cast(control) != NULL) { QLineEdit *line = dynamic_cast(control); line->clear(); QTest::keyClicks(line, QString("Some text for %1").arg(line->objectName())); //line->setText(QString("Some text for %1").arg(control->objectName())); QTest::keyClick(line, Qt::Key_Enter); } else if (dynamic_cast(control) != NULL) { QCheckBox *box = dynamic_cast(control); QTest::mouseClick(box, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); } else if (dynamic_cast(control) != NULL) { QRadioButton *box = dynamic_cast(control); // if it is not checked, jut clicking it if (!box->isChecked()) QTest::mouseClick(box, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); else { QList buttons; if (box->group() == NULL) { foreach(QRadioButton *button, box->parent()->findChildren()) { if (button->group() == NULL) buttons.append(button); } if (buttons.isEmpty()) { qDebug() << "Can not test QRadioButton" << box << "that is not in group and has no buttons nearby."; return false; } } else { buttons = box->group()->buttons(); } if (buttons.count() < 2) { qDebug() << "Can not test QRadioButton" << box << " that is only one button in group."; return false; } // looking for first radio button in same group that is not checked and clicking it foreach(QAbstractButton *button, buttons) { if (button->isChecked() == false && button != box) { QTest::mouseClick(button, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); return true; } } } } else if (dynamic_cast(control) != NULL) { QComboBox *box = dynamic_cast(control); if (box->count() < 2) { for (int i=0; icount(); i++) qDebug() << box->itemText(i); qDebug() << "Can not change value of QComboBox" << box << "which has less than two items."; return false; } box->setCurrentIndex((box->currentIndex() + 1) % box->count()); } else if (dynamic_cast(control) != NULL) { QTextEdit *edit = dynamic_cast(control); QTest::mouseClick(edit, Qt::LeftButton, Qt::NoModifier); QTest::keyClicks(edit, "Some test input for " + edit->objectName()); QTest::mouseClick(edit, Qt::LeftButton, Qt::NoModifier); QTest::keyClick(edit, Qt::Key_Tab); } else return false; return true; } void genericDialogTest::testDialog(QWidget *dialog, FWObject *object) { qDebug() << "testing dialog" << dialog; QList widgets = scanDialog(dialog); qDebug() << "it contains" << widgets.size() << "controls"; QList tabs = dialog->findChildren(); FWObject *old = mw->db()->create(object->getTypeName()); for (int i=0; iduplicate(object); QWidget *widget = widgets.at(i); // Skipping QSpinBox (which inherits QLineEdit) with QLineEdit type // there should be another one with right type in list if (widget->objectName() == "qt_spinbox_lineedit") continue; if (dynamic_cast(dialog) != NULL) dynamic_cast(dialog)->open(); activateTab(widget); if (!widget->isVisible() || !widget->isEnabled()) continue; if (!testControl(widget)) { QWARN(QString("Dont know how to test widget %1. It might be unknown class, empty QComboBox or QRadioButton with not other QRadio button in group.") .arg(widgets.at(i)->objectName()).toAscii().data()); continue; } if (dynamic_cast(dialog) != NULL) dynamic_cast(dialog)->accept(); else { QMetaObject::invokeMethod(dialog, "changed"); QMetaObject::invokeMethod(dialog, "applyChanges"); } QVERIFY2(!old->cmp(object, true), QString("Widget %1 does not affect object").arg(widget->objectName()).toAscii().data()); } } void genericDialogTest::testFirewallSettingsDialog_iptables() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); firewall->setStr("platform", "iptables"); firewall->setStr("host_OS", "linux24"); QDialog *dialog = dynamic_cast(DialogFactory::createFWDialog(mw, firewall)); testDialog(dialog, firewall); } void genericDialogTest::testHostOSSettingsDialog_linux24() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); firewall->setStr("platform", "iptables"); firewall->setStr("host_OS", "linux24"); QDialog *dialog = dynamic_cast(DialogFactory::createOSDialog(mw, firewall)); testDialog(dialog, firewall); } #if 0 // rule options dialog uses stacked widget with only one page visible, // depending on the firewall platform. Some widgets in invisible pages // are not even initialized, also depending on the platform. Need to // devise better test that would take this into account. void genericDialogTest::testRuleOptionsDialog() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); QMap platforms = getAllPlatforms(); platforms.remove("unknown"); // dialog does not set options for it foreach(QString platform, platforms.keys()) { qDebug() << "Testing platform:" << platform; firewall->setStr("platform", platform.toStdString()); PolicyRule *rule = PolicyRule::cast(firewall->getPolicy()->createRule()); firewall->getPolicy()->add(rule); QWidget *dialog = dynamic_cast(DialogFactory::createDialog(mw->activeProject(), Rule::TYPENAME)); dynamic_cast(dialog)->attachToProjectWindow(mw->activeProject()); dialog->setVisible(true); dynamic_cast(dialog)->loadFWObject(rule); testDialog(dynamic_cast(dialog), FWObject::cast(rule)); } } void genericDialogTest::testRoutingRuleOptionsDialog() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); /* QMap platforms = getAllPlatforms(); platforms.remove("unknown"); // dialog does not set options for it foreach(QString platform, platforms.keys()) { firewall->setStr("platform", platform.toStdString()); */ // it currently works only with iptables firewall->setStr("platform", "iptables"); RoutingRule *rule = RoutingRule::cast(firewall->getRouting()->createRule()); firewall->getRouting()->add(rule); QWidget *dialog = dynamic_cast(DialogFactory::createDialog(mw->activeProject(), RoutingRule::TYPENAME)); dynamic_cast(dialog)->attachToProjectWindow(mw->activeProject()); dialog->setVisible(true); dynamic_cast(dialog)->loadFWObject(rule); testDialog(dynamic_cast(dialog), FWObject::cast(rule)); } void genericDialogTest::testNATRuleOptionsDialog() { Firewall *firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "TestFirewall")); QMap platforms = getAllPlatforms(); platforms.remove("unknown"); // dialog does not set options for it foreach(QString platform, platforms.keys()) { qDebug() << "Testing platform:" << platform; firewall->setStr("platform", platform.toStdString()); NATRule *rule = NATRule::cast(firewall->getNAT()->createRule()); firewall->getNAT()->add(rule); QWidget *dialog = dynamic_cast(DialogFactory::createDialog(mw->activeProject(), NATRule::TYPENAME)); dynamic_cast(dialog)->attachToProjectWindow(mw->activeProject()); dialog->setVisible(true); dynamic_cast(dialog)->loadFWObject(rule); testDialog(dynamic_cast(dialog), FWObject::cast(rule)); } } #endif Library* genericDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } fwbuilder-5.1.0.3599/src/unit_tests/genericDialogTest/main_genericDialogTest.cpp0000644000175000017500000000327711733011756030477 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "genericDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new genericDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/genericDialogTest/genericDialogTest.pro0000644000175000017500000000026411733011756027502 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = genericDialogTest SOURCES += main_genericDialogTest.cpp \ genericDialogTest.cpp HEADERS += genericDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/instDialogInstallTest/0000755000175000017500000000000011733011756024252 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/instDialogInstallTest/test.fwb0000644000175000017500000035062311733011756025742 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/instDialogInstallTest/instDialogInstallTest.cpp0000644000175000017500000005362511733011756031255 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogInstallTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ================================ All tests in this module are designed to either fail installation or never supposed to complete it because they lack authentication credentials when they run unattended. Tests that perform successfull installs are located in a separate module fwbuilder-tests. Ticket 1358: using the same data file test.fwb but work with a copy because instDialog saves data to the disk and modifies the file keep common parts of all these tests in a separate function. There will be more tests like these in the future, the difference will be in the installer parameters and in the options stored in the firewall object. These tests check the status in the column on the left (Success or Error) and status of the buttons in the dialog (Finish). They also check if the file has been created and look for certain lines in the progress output panel. before running the test, check if files "test1.fw", "test2.fw", "test3.fw", "test4.fw" exist and delete them. If delete operation fails, fail the test. This should be done in the unit test code (C++) rather than in the runner shell script create subdirectory "test_install" in the current directory. If this directory exists, remove files in it. find firewall object test1, open it in the editor, click "Firewall settings" button and in the dialog change "Directory on the firewall where script should be installed" to the current directory. Alternatively, you can do this by manipulating data in the object instead of opening dialogs: FWOptions *fwoptions = firewall_object->getOptionsObject(); fwoptions->setStr("firewall_dir", current_dir + "/test_install"); test2 test for "authentication failed" error: * before compiling and installing, set environment variable "SSH_AUTH_SOCK" to empty string. Save its value before destroying it and then restore when this test is done * repeat the test1 with address 127.0.0.1. Since you have turned off ssh-agent and left password field empty, the program should not be able to authenticate and you should see "Permission denied" in the progress output test3 another kind of error is a timeout. * To simulate timeout repeat the test with ip address 127.0.0.2. Ssh should time out after some considerable time with appropriate error message in the output. Check for this message and make sure at that point button "Finish" is enabled and status is "Failed" (or is it "Error" ? ) test4 test cancellation. * Repeat the test using address 127.0.0.2 but click "Cancel" 1 sec after you start installation (this is too short for the ssh timeout to occur). Wait after that until the line "Stopping background process" appears, then check that the installer dialog closes. */ #include "instDialogInstallTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include #include "FWObjectClipboard.h" using namespace std; using namespace QTest; using namespace libfwbuilder; bool checkProgress(QTreeWidget *list) { for(int i=0; itopLevelItemCount(); i++) { if ( (list->topLevelItem(i)->text(1).toStdString() == "Compiling ...") || (list->topLevelItem(i)->text(1).toStdString() == "Installing ...") ) return false; } return true; } void instDialogInstallTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->loadFile("test_work.fwb", false); ssh_auth_sock = getenv("SSH_AUTH_SOCK"); } void instDialogInstallTest::cleanupTestCase() { if (ssh_auth_sock != NULL) setenv("SSH_AUTH_SOCK", ssh_auth_sock, 1); else unsetenv("SSH_AUTH_SOCK"); QDir().rmdir("test_install"); QFile::remove("test1.fw"); } void instDialogInstallTest::resetDialogs() { instOptionsDialog *optdlg = mw->findChild("instOptionsDialog_q"); if (optdlg && optdlg->isVisible()) optdlg->reject(); instDialog *dlg = mw->findChild(); if (dlg && dlg->isVisible()) dlg->reject(); QTest::qWait(500); } void instDialogInstallTest::fillInstOptionsDialog(const QString &user_name, const QString &passwd, const QString &alt_address, bool verbose_flag) { instOptionsDialog *optdlg = mw->findChild("instOptionsDialog_q"); QVERIFY(optdlg != NULL); QVERIFY(optdlg->isVisible() == true); QLineEdit *uname = optdlg->findChild("uname"); QLineEdit *pwd = optdlg->findChild("pwd"); QLineEdit *altAddress = optdlg->findChild("altAddress"); QCheckBox *verbose = optdlg->findChild("verbose"); if (!user_name.isEmpty()) uname->setText(user_name); if (!passwd.isEmpty()) pwd->setText(passwd); if (!alt_address.isEmpty()) altAddress->setText(alt_address); verbose->setChecked(verbose_flag); optdlg->findChild("okButton")->click(); } void instDialogInstallTest::instOptionsForTest1() { // set verbose on to reveal scp and ssh command line fillInstOptionsDialog(QString("root"), QString(""), QString("127.0.0.1"), true); } void instDialogInstallTest::instOptionsForTest2() { // set verbose on to reveal scp and ssh command line fillInstOptionsDialog(QString("root"), QString(""), QString("127.0.0.1"), true); } void instDialogInstallTest::instOptionsForTest3() { // set verbose on to reveal scp and ssh command line fillInstOptionsDialog(QString("root"), QString(""), QString("192.168.254.254"), true); } void instDialogInstallTest::instOptionsForTest4() { fillInstOptionsDialog(QString("root"), QString(""), QString("192.168.254.254"), false); } void instDialogInstallTest::instOptionsForTest5() { fillInstOptionsDialog(QString("root"), QString(""), QString("192.168.254.254"), false); } void instDialogInstallTest::removeFiles() { if (QFileInfo("test1.fw").exists()) QVERIFY(QFile::remove("test1.fw")); if (QFileInfo("test2.fw").exists()) QVERIFY(QFile::remove("test2.fw")); if (QFileInfo("test3.fw").exists()) QVERIFY(QFile::remove("test3.fw")); if (QFileInfo("test4.fw").exists()) QVERIFY(QFile::remove("test4.fw")); if (QDir("test_install").exists()) { foreach(QString file, QDir("test_install").entryList()) { if (QFileInfo("test_install/"+file).isFile()) QVERIFY(QFile::remove("test_install/"+file)); } QVERIFY(QDir().rmdir("test_install")); } QVERIFY(QDir().mkdir("test_install")); } void instDialogInstallTest::verifyInstallSuccess(const QString &) { instDialog *dlg = mw->findChild(); QTreeWidget *list= dlg->findChild("fwWorkList"); QTextBrowser *processLogDisplay = dlg->findChild("procLogDisplay"); for(int i=0; itopLevelItemCount(); i++) { QString txt = processLogDisplay->toPlainText(); if (list->topLevelItem(i)->text(1) != "Success") { foreach(QString line, txt.split("\n")) qDebug() << line; QFAIL("Installation failure detected, see debug above for details"); } } } /* test for "authentication failed" error: * before compiling and installing, set environment variable "SSH_AUTH_SOCK" to empty string. Save its value before destroying it and then restore when this test is done * repeat the test1 with address 127.0.0.1. Since you have turned off ssh-agent and left password field empty, the program should not be able to authenticate and you should see "Permission denied" in the progress output */ void instDialogInstallTest::testInstall2() { resetDialogs(); removeFiles(); Firewall *test1 = NULL; foreach(FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == "test1") { test1 = Firewall::cast(fw); break; } } QVERIFY(test1 != NULL); // reset additional args for scp and ssh FWOptions *fwoptions = test1->getOptionsObject(); fwoptions->setStr("scpArgs", ""); fwoptions->setStr("sshArgs", ""); fwoptions->setStr("firewall_dir", (QDir::currentPath()+"/test_install").toStdString()); setenv("SSH_AUTH_SOCK", "nothinghere", 1); QTest::qWait(500); mw->findChild("installAction")->trigger(); QTest::qWait(500); instDialog *dlg = mw->findChild(); dlg->findChild("pushButton17")->click(); QPushButton *back = dlg->findChild("backButton"); QPushButton *next = dlg->findChild("nextButton"); QPushButton *finish = dlg->findChild("finishButton"); QPushButton *cancel = dlg->findChild("cancelButton"); QTreeWidget *selectTable = dlg->findChild("selectTable"); QTreeWidgetItem *test1item = selectTable->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first(); test1item->setCheckState(1, Qt::Checked); test1item->setCheckState(2, Qt::Checked); QTest::qWait(500); next->click(); QTreeWidget *list= dlg->findChild("fwWorkList"); int waited = 0; while (!checkProgress(list)) { QVERIFY(back->isEnabled() == true); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY2(finish->isEnabled() == false, "Button Finish is enabled during operation"); QTest::qWait(500); waited += 500; QVERIFY(waited < 10000); } qDebug() << "Test 2 continues"; verifyInstallSuccess("instDialogInstallTest::testInstall2()"); QTest::qWait(500); QVERIFY(next->isEnabled()); QVERIFY(!dlg->findChild("finishButton")->isEnabled()); QVERIFY(QFile::exists("test1.fw")); QVERIFY(QFile::remove("test1.fw")); QFile testfile("test1.fw"); testfile.open(QFile::WriteOnly); testfile.write("#!/bin/sh\n#\n# This is automatically generated file. DO NOT MODIFY !\n#\n# Firewall Builder fwb_ipt v4.0.0-2784\n#\n# Generated Wed Mar 31 16:41:46 2010 EEST by a2k\n#\n# files: * test1.fw\n#\n# Compiled for iptables (any version)\n#\n# This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside.\n# Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0\n\n\necho \"Testing policy activation script\"\n"); testfile.close(); testfile.setPermissions(testfile.permissions() | QFile::ExeOwner); QTimer::singleShot(200, this, SLOT(instOptionsForTest2())); next->click(); QTest::qWait(500); waited = 0; while (!checkProgress(list)) { QVERIFY(back->isEnabled() == false); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY2(finish->isEnabled() == false, "Button Finish is enabled during operation"); QTest::qWait(500); waited += 500; QVERIFY(waited < 10000); } QTest::qWait(500); for(int i=0; itopLevelItemCount(); i++) { QVERIFY(list->topLevelItem(i)->text(1) == "Failure"); } if (ssh_auth_sock != NULL) setenv("SSH_AUTH_SOCK", ssh_auth_sock, 1); else unsetenv("SSH_AUTH_SOCK"); QString text = dlg->findChild("procLogDisplay")->toPlainText(); QVERIFY(!text.isEmpty()); // foreach(QString line, text.split("\n")) // qDebug() << line; QVERIFY(text.contains("lost connection")); QVERIFY(text.contains("SSH session terminated, exit status: 1")); dlg->reject(); QTest::qWait(500); qDebug() << "Test 2 done"; } /* * Another kind of error is a timeout. * To simulate timeout repeat the test with an ip address that does * not exist. Ssh should time out after some considerable time with * appropriate error message in the output. Check for this message * and make sure at that point button "Finish" is enabled and status * is "Failed" (or is it "Error" ? ) * this test also tests custom scp command line argument * addition. The argument is ConnectTimeout, we both test the code * path that adds custom arguments for scp and make the test run * faster by shirtening the timeout. */ void instDialogInstallTest::testInstall3() { qDebug() << "Test 3 begins"; resetDialogs(); removeFiles(); Firewall *test1 = NULL; foreach(FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == "test1") { test1 = Firewall::cast(fw); break; } } QVERIFY(test1 != NULL); // reset additional args for scp and ssh FWOptions *fwoptions = test1->getOptionsObject(); fwoptions->setStr("scpArgs", ""); fwoptions->setStr("sshArgs", ""); fwoptions->setStr("firewall_dir", (QDir::currentPath()+"/test_install").toStdString()); // reduce timeout time to make test run faster fwoptions->setStr("scpArgs", "-o ConnectTimeout=2"); mw->findChild("installAction")->trigger(); QTest::qWait(500); instDialog *dlg = mw->findChild(); dlg->findChild("pushButton17")->click(); QPushButton *back = dlg->findChild("backButton"); QPushButton *next = dlg->findChild("nextButton"); QPushButton *finish = dlg->findChild("finishButton"); QPushButton *cancel = dlg->findChild("cancelButton"); QTreeWidget *selectTable = dlg->findChild("selectTable"); QTreeWidgetItem *test1item = selectTable->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first(); test1item->setCheckState(1, Qt::Checked); test1item->setCheckState(2, Qt::Checked); QTest::qWait(500); next->click(); QTreeWidget *list= dlg->findChild("fwWorkList"); int waited = 0; while (!checkProgress(list)) { QVERIFY(back->isEnabled() == true); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY2(finish->isEnabled() == false, "Button Finish is enabled during operation"); QTest::qWait(500); waited += 500; QVERIFY(waited < 10000); } verifyInstallSuccess("instDialogInstallTest::testInstall3()"); QTest::qWait(500); QVERIFY(next->isEnabled()); QVERIFY(!finish->isEnabled()); QVERIFY(QFile::exists("test1.fw")); QVERIFY(QFile::remove("test1.fw")); QFile testfile("test1.fw"); testfile.open(QFile::WriteOnly); testfile.write("#!/bin/sh\n#\n# This is automatically generated file. DO NOT MODIFY !\n#\n# Firewall Builder fwb_ipt v4.0.0-2784\n#\n# Generated Wed Mar 31 16:41:46 2010 EEST by a2k\n#\n# files: * test1.fw\n#\n# Compiled for iptables (any version)\n#\n# This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside.\n# Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0\n\n\necho \"Testing policy activation script\"\n"); testfile.close(); testfile.setPermissions(testfile.permissions() | QFile::ExeOwner); QTimer::singleShot(200, this, SLOT(instOptionsForTest3())); next->click(); QTest::qWait(500); waited = 0; while (!checkProgress(list)) { QVERIFY(back->isEnabled() == false); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY2(finish->isEnabled() == false, "Button Finish is enabled during operation"); QTest::qWait(500); waited += 500; QVERIFY(waited < 1000000); } for(int i=0; itopLevelItemCount(); i++) { QVERIFY(list->topLevelItem(i)->text(1) == "Failure"); } QString text = dlg->findChild("procLogDisplay")->toPlainText(); // check that additional scp command line argument was indeed used QVERIFY(text.contains("-o ConnectTimeout=2")); // check that ssh timed out as expected QVERIFY(text.contains("lost connection")); QVERIFY(text.contains("SSH session terminated, exit status: 1")); QVERIFY(!text.isEmpty()); dlg->reject(); QTest::qWait(500); } /* * Test cancellation. * * This function does two tests: it runs install but hits Cancel or Stop * button (per @button_name argument) to interrupt the process and then * checks that the dialog is still open or not (per @dialog_should_stay_open * arg) * * Repeat the test using address that does not exist but click * "Cancel" 1 sec after you start installation (this is too short for * the ssh timeout to occur). Wait after that until the line "Stopping * background process" appears, then check that the installer dialog * closes. * */ void instDialogInstallTest::executeCancelAndStopTests(const QString &button_name, bool dialog_should_stay_open) { resetDialogs(); removeFiles(); Firewall *test1 = NULL; foreach(FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == "test1") { test1 = Firewall::cast(fw); break; } } QVERIFY(test1 != NULL); // reset additional args for scp and ssh FWOptions *fwoptions = test1->getOptionsObject(); fwoptions->setStr("scpArgs", ""); fwoptions->setStr("sshArgs", ""); fwoptions->setStr("firewall_dir", (QDir::currentPath()+"/test_install").toStdString()); mw->findChild("installAction")->trigger(); QTest::qWait(500); instDialog *dlg = mw->findChild(); dlg->findChild("pushButton17")->click(); QPushButton *back = dlg->findChild("backButton"); QPushButton *next = dlg->findChild("nextButton"); QPushButton *finish = dlg->findChild("finishButton"); QPushButton *cancel = dlg->findChild("cancelButton"); QTreeWidget *selectTable = dlg->findChild("selectTable"); QTreeWidgetItem *test1item = selectTable->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first(); test1item->setCheckState(1, Qt::Checked); test1item->setCheckState(2, Qt::Checked); QTest::qWait(500); next->click(); QTreeWidget *list= dlg->findChild("fwWorkList"); int waited = 0; while (!checkProgress(list)) { QVERIFY(back->isEnabled() == true); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY2(finish->isEnabled() == false, "Button Finish is enabled during operation"); QTest::qWait(500); waited += 500; QVERIFY(waited < 10000); } for(int i=0; itopLevelItemCount(); i++) { QVERIFY(list->topLevelItem(i)->text(1) == "Success"); } QTest::qWait(500); QVERIFY(next->isEnabled()); QVERIFY(!finish->isEnabled()); QVERIFY(QFile::exists("test1.fw")); QVERIFY(QFile::remove("test1.fw")); QFile testfile("test1.fw"); testfile.open(QFile::WriteOnly); testfile.write("#!/bin/sh\n#\n# This is automatically generated file. DO NOT MODIFY !\n#\n# Firewall Builder fwb_ipt v4.0.0-2784\n#\n# Generated Wed Mar 31 16:41:46 2010 EEST by a2k\n#\n# files: * test1.fw\n#\n# Compiled for iptables (any version)\n#\n# This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside.\n# Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall uses one of the machines on internal network for DNS. Internal network is configured with address 192.168.1.0/255.255.255.0\n\n\necho \"Testing policy activation script\"\n"); testfile.close(); testfile.setPermissions(testfile.permissions() | QFile::ExeOwner); QTimer::singleShot(200, this, SLOT(instOptionsForTest4())); next->click(); QTest::qWait(1000); // Now click button to interrupt the process dlg->findChild(button_name)->click(); QTest::qWait(2000); QString text = dlg->findChild("procLogDisplay")->toPlainText(); QVERIFY(text.contains("Stopping background process")); QTest::qWait(500); QVERIFY(mw->findChild()->isVisible() == dialog_should_stay_open); QTest::qWait(500); } void instDialogInstallTest::testInstall4() { executeCancelAndStopTests("cancelButton", false); } /* * Test "Stop" button. This is just like "Cancel", except the dialog * stays open. * */ void instDialogInstallTest::testInstall5() { executeCancelAndStopTests("stopButton", true); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogInstallTest/main_instDialogInstallTest.cpp0000644000175000017500000000332011733011756032244 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogInstallTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "instDialogInstallTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new instDialogInstallTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogInstallTest/instDialogInstallTest.h0000644000175000017500000000424011733011756030707 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogInstallTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include "FWBTree.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Library.h" #include "fwbuilder/Policy.h" #include "instDialog.h" #include "newClusterDialog.h" #include "upgradePredicate.h" class instDialogInstallTest : public QObject { Q_OBJECT; const char *ssh_auth_sock; void removeFiles(); void verifyInstallSuccess(const QString &test_name); void resetDialogs(); void fillInstOptionsDialog(const QString &user_name, const QString &pwd, const QString &alt_address, bool verbose); void executeCancelAndStopTests(const QString &button_name, bool dialog_should_stay_open); private slots: void initTestCase(); void cleanupTestCase(); void testInstall2(); void testInstall3(); void testInstall4(); void testInstall5(); public slots: void instOptionsForTest1(); void instOptionsForTest2(); void instOptionsForTest3(); void instOptionsForTest4(); void instOptionsForTest5(); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogInstallTest/instDialogInstallTest.pro0000644000175000017500000000050711733011756031262 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = instDialogInstallTest SOURCES += main_instDialogInstallTest.cpp \ instDialogInstallTest.cpp HEADERS += instDialogInstallTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/unit_tests.pro0000644000175000017500000000062411733011756022713 0ustar sylvestresylvestreDOLLAR = $ libgui.target = ../libgui/libgui.a libgui.commands = cd ../libgui && qmake -spec $$QMAKESPEC && make && cd - build_tests.commands = ./unit_tests.sh make build_tests run_tests.commands = ./unit_tests.sh make run_tests clean_tests.commands = ./unit_tests.sh make clean build_tests.depends = libgui run_tests.depends = libgui QMAKE_EXTRA_TARGETS += libgui run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/IPServiceDialogTest/0000755000175000017500000000000011733011756023577 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/IPServiceDialogTest/IPServiceDialogTest.h0000644000175000017500000000251011733011756027557 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: IPServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IPServiceDialogTest_H #define IPServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class IPServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testIpOptions(); void testAnyOpt(); void testTOS(); void testDSCP(); }; #endif // IPServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/IPServiceDialogTest/IPServiceDialogTest.cpp0000644000175000017500000002212011733011756030111 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: IPServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "IPServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "IPServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" using namespace std; using namespace libfwbuilder; void IPServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->resize(QSize(1200,600)); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* IPServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void IPServiceDialogTest::testIpOptions() { IPService *service = IPService::cast( om->createObject( FWBTree().getStandardSlotForObject( findUserLibrary(), IPService::TYPENAME), IPService::TYPENAME, "testIPService-1")); om->editObject(service); IPServiceDialog *dialog = mw->findChild("w_IPServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QSpinBox *protocolNum = dialog->findChild("protocolNum"); TextEditWidget *comment = dialog->findChild("comment"); //options: QCheckBox *any_opt = dialog->findChild("any_opt"); QCheckBox *lsrr = dialog->findChild("lsrr"); QCheckBox *ssrr = dialog->findChild("ssrr"); QCheckBox *rr = dialog->findChild("rr"); QCheckBox *timestamp = dialog->findChild("timestamp"); QCheckBox *router_alert = dialog->findChild("router_alert"); QCheckBox *all_fragm = dialog->findChild("all_fragments"); QCheckBox *short_fragm = dialog->findChild("short_fragments"); obj_name->clear(); QTest::keyClicks(obj_name, "TestIPService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestIPService"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "test comment"); QTest::mouseClick(obj_name, Qt::LeftButton); QVERIFY(service->getComment() == "test comment"); QTest::keyClick(protocolNum, Qt::Key_Up); QTest::keyClick(protocolNum, Qt::Key_Up); QTest::keyClick(protocolNum, Qt::Key_Enter); QVERIFY(service->getProtocolNumber() == 2); QTest::mouseClick(lsrr, Qt::LeftButton, Qt::NoModifier, QPoint(8,8)); QVERIFY(service->getBool("lsrr") == true); QTest::mouseClick(lsrr, Qt::LeftButton); QVERIFY(service->getBool("lsrr") == false); QTest::mouseClick(ssrr, Qt::LeftButton); QVERIFY(service->getBool("ssrr") == true); QTest::mouseClick(ssrr, Qt::LeftButton); QVERIFY(service->getBool("ssrr") == false); QTest::mouseClick(rr, Qt::LeftButton); QVERIFY(service->getBool("rr") == true); QTest::mouseClick(rr, Qt::LeftButton); QVERIFY(service->getBool("rr") == false); // Have to expicitly specify position for the click; if not, mouseClick() // does not change checkbox state. This could be because the text // of this checkbox widget is shorter than in the others and clicking // in the center of the widget misses the text. Looks like clicking // outside the text of the checkbox does not switch it. QTest::mouseClick(timestamp, Qt::LeftButton, Qt::NoModifier, QPoint(8,8)); QVERIFY(service->getBool("ts") == true); QTest::mouseClick(timestamp, Qt::LeftButton, Qt::NoModifier, QPoint(8,8)); QVERIFY(service->getBool("ts") == false); QTest::mouseClick(router_alert, Qt::LeftButton); QVERIFY(service->getBool("rtralt") == true); QTest::mouseClick(router_alert, Qt::LeftButton); QVERIFY(service->getBool("rtralt") == false); QTest::mouseClick(all_fragm, Qt::LeftButton); QVERIFY(service->getBool("fragm") == true); QTest::mouseClick(all_fragm, Qt::LeftButton); QVERIFY(service->getBool("fragm") == false); QTest::mouseClick(short_fragm, Qt::LeftButton); QVERIFY(service->getBool("short_fragm") == true); QTest::mouseClick(short_fragm, Qt::LeftButton); QVERIFY(service->getBool("short_fragm") == false); QTest::mouseClick(any_opt, Qt::LeftButton); QVERIFY(service->getBool("any_opt") == true); QTest::mouseClick(any_opt, Qt::LeftButton); QVERIFY(service->getBool("any_opt") == false); } void IPServiceDialogTest::testAnyOpt() { IPService *service = IPService::cast( om->createObject( FWBTree().getStandardSlotForObject( findUserLibrary(), IPService::TYPENAME), IPService::TYPENAME, "testIPService-2")); om->editObject(service); IPServiceDialog *dialog = mw->findChild("w_IPServiceDialog"); //options: QCheckBox *any_opt = dialog->findChild("any_opt"); QCheckBox *lsrr = dialog->findChild("lsrr"); QCheckBox *ssrr = dialog->findChild("ssrr"); QCheckBox *rr = dialog->findChild("rr"); QCheckBox *timestamp = dialog->findChild("timestamp"); QCheckBox *router_alert = dialog->findChild("router_alert"); QTest::mouseClick(lsrr, Qt::LeftButton); QTest::mouseClick(ssrr, Qt::LeftButton); QTest::mouseClick(rr, Qt::LeftButton); QTest::mouseClick(timestamp, Qt::LeftButton); QTest::mouseClick(router_alert, Qt::LeftButton); QTest::mouseClick(any_opt, Qt::LeftButton); QVERIFY(service->getBool("any_opt") == true); QVERIFY(service->getBool("lsrr") == false); QVERIFY(service->getBool("ssrr") == false); QVERIFY(service->getBool("rr") == false); QVERIFY(service->getBool("ts") == false); QVERIFY(service->getBool("rtralt") == false); } void IPServiceDialogTest::testTOS() { IPService *service = IPService::cast( om->createObject( FWBTree().getStandardSlotForObject( findUserLibrary(), IPService::TYPENAME), IPService::TYPENAME, "testIPService-3")); om->editObject(service); IPServiceDialog *dialog = mw->findChild("w_IPServiceDialog"); QRadioButton *use_tos = dialog->findChild("use_tos"); QLineEdit *code = dialog->findChild("code"); QTest::mouseClick(use_tos, Qt::LeftButton); QLabel *code_label = dialog->findChild("code_label"); QVERIFY(code_label->text() == tr("TOS code (numeric):")); QTest::keyClicks(code, "10"); QTest::keyClick(code, Qt::Key_Enter); QVERIFY(service->getTOSCode() == "10"); } void IPServiceDialogTest::testDSCP() { IPService *service = IPService::cast( om->createObject( FWBTree().getStandardSlotForObject( findUserLibrary(), IPService::TYPENAME), IPService::TYPENAME, "testIPService-4")); om->editObject(service); IPServiceDialog *dialog = mw->findChild("w_IPServiceDialog"); QRadioButton *use_dscp = dialog->findChild("use_dscp"); QLineEdit *code = dialog->findChild("code"); QTest::mouseClick(use_dscp, Qt::LeftButton); QLabel *code_label = dialog->findChild("code_label"); QVERIFY(code_label->text() == tr("DSCP code or class:")); QTest::keyClicks(code, "af4"); QTest::keyClick(code, Qt::Key_Enter); QVERIFY(service->getDSCPCode() == "af4"); } fwbuilder-5.1.0.3599/src/unit_tests/IPServiceDialogTest/IPServiceDialogTest.pro0000644000175000017500000000027411733011756030135 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = IPServiceDialogTest SOURCES += main_IPServiceDialogTest.cpp \ IPServiceDialogTest.cpp HEADERS += IPServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/IPServiceDialogTest/main_IPServiceDialogTest.cpp0000644000175000017500000000330211733011756031116 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "IPServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new IPServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/DNSTest/0000755000175000017500000000000011733011756021252 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/DNSTest/DNSTest.cpp0000644000175000017500000000705711733011756023253 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "DNSTest.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Host.h" #include "fwbuilder/Library.h" #include "fwbuilder/DNSName.h" #include using namespace libfwbuilder; using namespace std; bool DNSTest::testDNSNameObject(FWObjectDatabase *objdb, FWObject *root, const string &dnsrec, char* results[]) { list expected_results; for (char** cptr=results; *cptr!=NULL; ++cptr) expected_results.push_back(*cptr); FWObject *nobj = objdb->create(DNSName::TYPENAME); if (root != NULL) { root->add(nobj); } DNSName* dnsnameobj = DNSName::cast(nobj); dnsnameobj->setName(dnsrec); dnsnameobj->setStr("dnsrec", dnsrec); dnsnameobj->setRunTime(false); for (FWObject::iterator j=dnsnameobj->begin(); j!=dnsnameobj->end(); ++j) { Address* addr = Address::cast(FWReference::cast(*j)->getPointer()); const InetAddr* inet_addr = addr->getAddressPtr(); list::const_iterator res; res = std::find(expected_results.begin(), expected_results.end(), inet_addr->toString()); if ( res != expected_results.end()) { return true; } else { return false; } } return true; } void DNSTest::runTest() { libfwbuilder::init(); objdb = new FWObjectDatabase(); FWObject *nlib = objdb->create(Library::TYPENAME); objdb->add(nlib); nlib->setName( "Library" ); FWObject *o1 = objdb->create(ObjectGroup::TYPENAME); o1->setName("Objects"); nlib->add(o1); FWObject *root = objdb->create(ObjectGroup::TYPENAME); root->setName("DNS Names"); o1->add(root); InetAddr addr; char* test1[] = {"localhost", "127.0.0.1", NULL}; CPPUNIT_ASSERT(testDNSNameObject(objdb, root, test1[0], &(test1[1]))); char* test2[] = {"www.fwbuilder.org","70.85.175.170", NULL}; CPPUNIT_ASSERT(testDNSNameObject(objdb, root, test2[0], &(test2[1]))); char* test3[] = {"www.microsoft.com", "65.55.21.250", "207.46.232.182", "207.46.197.32", "207.46.19.254", "207.46.192.254", "207.46.193.254", NULL}; CPPUNIT_ASSERT(testDNSNameObject(objdb, root, test3[0], &(test3[1]))); } fwbuilder-5.1.0.3599/src/unit_tests/DNSTest/DNSTest.h0000644000175000017500000000322111733011756022705 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DNSTEST_H #define DNSTEST_H #include #include #include #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObject.h" class DNSTest : public CppUnit::TestCase { libfwbuilder::FWObjectDatabase *objdb; bool testDNSNameObject(libfwbuilder::FWObjectDatabase *objdb, libfwbuilder::FWObject *root, const std::string &dnsrec, char* results[]); public: void runTest(); static CppUnit::Test *suite() { CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite( "ObjectMatcherTest" ); suiteOfTests->addTest( new CppUnit::TestCaller( "runTest", &DNSTest::runTest ) ); return suiteOfTests; } }; #endif // DNSTEST_H fwbuilder-5.1.0.3599/src/unit_tests/DNSTest/main.cpp0000644000175000017500000000250511733011756022704 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "DNSTest.h" #include "fwbuilder/FWObjectDatabase.h" #include int fwbdebug = 0; std::string platform; int main( int, char** argv) { CppUnit::TextUi::TestRunner runner; runner.addTest( DNSTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/DNSTest/DNSTest.pro0000644000175000017500000000106511733011756023262 0ustar sylvestresylvestre include(../../../qmake.inc) QT -= core gui TARGET = DNSTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS LIBS += $$CPPUNIT_LIBS SOURCES += main.cpp DNSTest.cpp HEADERS += DNSTest.h INCLUDEPATH += ../../.. ../../libfwbuilder/src DEPENDPATH += ../../libfwbuilder/src LIBS += ../../libfwbuilder/src/fwbuilder/libfwbuilder.a run_tests.commands = echo "Running tests..." && ./${TARGET} run_tests.depends = all clean_tests.depends = clean build_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/CustomServiceDialogTest/0000755000175000017500000000000011733011756024541 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/CustomServiceDialogTest/CustomServiceDialogTest.h0000644000175000017500000000252011733011756031464 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: CustomServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CustomServiceDialogTest_H #define CustomServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class CustomServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; void selectComboItem(QWidget *widget, QString name); private slots: void initTestCase(); void testDialog(); }; #endif // CustomServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/CustomServiceDialogTest/CustomServiceDialogTest.pro0000644000175000017500000000040311733011756032033 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = CustomServiceDialogTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main_CustomServiceDialogTest.cpp \ CustomServiceDialogTest.cpp HEADERS += CustomServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/CustomServiceDialogTest/CustomServiceDialogTest.cpp0000644000175000017500000001633611733011756032031 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: CustomServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "CustomServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "CustomServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/CustomService.h" #include "CustomServiceDialog.h" #include "platforms.h" using namespace std; using namespace libfwbuilder; void CustomServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* CustomServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void CustomServiceDialogTest::selectComboItem(QWidget *widget, QString name) { QComboBox * combo = dynamic_cast(widget); Q_ASSERT(combo != NULL); int id = combo->findText(name); combo->setCurrentIndex(id); } void CustomServiceDialogTest::testDialog() { CustomService *service = CustomService::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), CustomService::TYPENAME), CustomService::TYPENAME, "testCustomService")); om->editObject(service); CustomServiceDialog *dialog = mw->findChild("w_CustomServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QComboBox *platform = dialog->findChild("platform"); QLineEdit *code = dialog->findChild("code"); QComboBox *protocol = dialog->findChild("protocol"); QRadioButton *ipv4 = dialog->findChild("ipv4"); QRadioButton *ipv6 = dialog->findChild("ipv6"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestCustomService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestCustomService"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (service->getComment() == "Test comment"); // testing saving platform code to service object selectComboItem(platform, "iptables"); dialog->platformChanged(); QTest::keyClicks(code, "code for iptables"); QTest::keyClick(code, Qt::Key_Tab); QTest::keyClick(code, Qt::Key_Enter); QTest::qWait(100); QVERIFY(service->getCodeForPlatform("iptables") == "code for iptables"); // platform code should clear when we change platform to one that currently does not have code selectComboItem(platform, "PF"); dialog->platformChanged(); QVERIFY(code->text().isEmpty()); // platform code for iptables should not change when setting code for PF or changing platform QVERIFY(service->getCodeForPlatform("iptables") == "code for iptables"); QTest::keyClicks(code, "code for pf"); QTest::keyClick(code, Qt::Key_Enter); QVERIFY(service->getCodeForPlatform("iptables") == "code for iptables"); QVERIFY(service->getCodeForPlatform("pf") == "code for pf"); // testing saving platform code to service object for all platforms QMap platforms = getAllPlatforms(); foreach (QString key, platforms.keys()) { selectComboItem(platform, platforms[key]); dialog->platformChanged(); code->clear(); QTest::keyClicks(code, "code for "+key); QTest::keyClick(code, Qt::Key_Tab); QTest::keyClick(code, Qt::Key_Enter); QTest::qWait(100); QVERIFY2(service->getCodeForPlatform(key.toStdString().c_str()) == (string("code for ")+key.toStdString()), (string("failed for platform ") + key.toStdString()).c_str()); } // testing changing protocol to tcp selectComboItem(platform, "iptables"); dialog->platformChanged(); selectComboItem(protocol, "tcp"); dialog->applyChanges(); QTest::qWait(100); QVERIFY(service->getProtocol() == "tcp"); selectComboItem(platform, "pf"); dialog->platformChanged(); QVERIFY(service->getProtocol() == "tcp"); // testing saving address family to service object selectComboItem(platform, "iptables"); dialog->platformChanged(); QTest::mouseClick(ipv6, Qt::LeftButton, Qt::NoModifier, QPoint(10,10)); QVERIFY(service->getAddressFamily() == AF_INET6); selectComboItem(platform, "PF"); dialog->platformChanged(); QVERIFY(service->getAddressFamily() == AF_INET6); // testing that changing address family does not change platform code foreach (QString key, platforms.keys()) { string oldcode = service->getCodeForPlatform(key.toStdString().c_str()); string oldprotocol = service->getProtocol(); QTest::mouseClick(ipv4, Qt::LeftButton, Qt::NoModifier, QPoint(10,10)); QVERIFY(service->getAddressFamily() == AF_INET); QVERIFY(oldcode == service->getCodeForPlatform(key.toStdString().c_str())); QVERIFY(oldprotocol == service->getProtocol()); QTest::mouseClick(ipv6, Qt::LeftButton, Qt::NoModifier, QPoint(10,10)); QVERIFY(service->getAddressFamily() == AF_INET6); QVERIFY(oldcode == service->getCodeForPlatform(key.toStdString().c_str())); QVERIFY(oldprotocol == service->getProtocol()); } } fwbuilder-5.1.0.3599/src/unit_tests/CustomServiceDialogTest/main_CustomServiceDialogTest.cpp0000644000175000017500000000331311733011756033024 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "CustomServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new CustomServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/FWObjectTest/0000755000175000017500000000000011733011756022271 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/FWObjectTest/FWObjectTest.cpp0000644000175000017500000000515711733011756025310 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: FWObjectTest.cpp 581 2010-03-10 18:31:03Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FWObjectTest.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Host.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" using namespace libfwbuilder; using namespace std; void FWObjectTest::cmpTest() { FWObjectDatabase db; FWObject *obj1 = db.create(Firewall::TYPENAME); FWObject *obj2 = db.create(Firewall::TYPENAME); obj2->duplicate(obj1); obj1->setStr("key", "value1"); CPPUNIT_ASSERT(obj1->cmp(obj2) == false); obj2->setStr("key", "value2"); CPPUNIT_ASSERT(obj1->cmp(obj2) == false); obj2->remStr("key"); obj1->setStr("key", ""); CPPUNIT_ASSERT(obj1->cmp(obj2) == false); obj1->remStr("key"); CPPUNIT_ASSERT(obj2->cmp(obj1) == true); FWObject *ch1 = db.create(Interface::TYPENAME); FWObject *ch2 = db.create(Interface::TYPENAME); FWObject *ch3 = db.create(Interface::TYPENAME); FWObject *ch4 = db.create(Interface::TYPENAME); ch1->setStr("key", "value1"); ch2->duplicate(ch1); CPPUNIT_ASSERT(ch1->cmp(ch2) == true); ch3->duplicate(ch1); CPPUNIT_ASSERT(ch1->cmp(ch3) == true); ch4->duplicate(ch1); ch4->setStr("key", "value2"); CPPUNIT_ASSERT(ch1->cmp(ch4) == false); obj1->add(ch1); obj1->add(ch2); obj2->add(ch3); obj2->add(ch4); CPPUNIT_ASSERT(obj1->cmp(obj2, true) == false); ch4->setStr("key", "value1"); CPPUNIT_ASSERT(obj1->cmp(obj2, true) == true); } fwbuilder-5.1.0.3599/src/unit_tests/FWObjectTest/FWObjectTest.pro0000644000175000017500000000110311733011756025311 0ustar sylvestresylvestreinclude(../../../qmake.inc) QT -= core gui TARGET = FWObjectTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS LIBS += $$CPPUNIT_LIBS SOURCES += main.cpp FWObjectTest.cpp HEADERS += FWObjectTest.h INCLUDEPATH += ../../.. ../../libfwbuilder/src DEPENDPATH += ../../libfwbuilder/src LIBS += ../../libfwbuilder/src/fwbuilder/libfwbuilder.a run_tests.commands = echo "Running tests..." && ./${TARGET} run_tests.depends = all clean_tests.depends = clean build_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/FWObjectTest/main.cpp0000644000175000017500000000271211733011756023723 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main.cpp 581 2010-03-10 18:31:03Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "FWObjectTest.h" #include "fwbuilder/FWObjectDatabase.h" #include using namespace libfwbuilder; int fwbdebug = 0; //QString user_name; std::string platform; int main( int, char** argv) { //init(argv); init(); CppUnit::TextUi::TestRunner runner; runner.addTest( FWObjectTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/FWObjectTest/FWObjectTest.h0000644000175000017500000000273211733011756024751 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: FWObjectTest.h 581 2010-03-10 18:31:03Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECTMATCHERTEST_H #define OBJECTMATCHERTEST_H #include #include #include class FWObjectTest : public CppUnit::TestCase { public: void cmpTest(); static CppUnit::Test *suite() { CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite( "FWObjectTest" ); suiteOfTests->addTest( new CppUnit::TestCaller( "cmpTest", &FWObjectTest::cmpTest ) ); return suiteOfTests; } }; #endif // OBJECTMATCHERTEST_H fwbuilder-5.1.0.3599/src/unit_tests/ObjectMatcherTest/0000755000175000017500000000000011733011756023340 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/ObjectMatcherTest/ObjectMatcherTest.h0000644000175000017500000000270611733011756027070 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECTMATCHERTEST_H #define OBJECTMATCHERTEST_H #include #include #include class ObjectMatcherTest : public CppUnit::TestCase { public: void matchTest(); static CppUnit::Test *suite() { CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite( "ObjectMatcherTest" ); suiteOfTests->addTest( new CppUnit::TestCaller( "matchTest", &ObjectMatcherTest::matchTest ) ); return suiteOfTests; } }; #endif // OBJECTMATCHERTEST_H fwbuilder-5.1.0.3599/src/unit_tests/ObjectMatcherTest/ObjectMatcherTest.cpp0000644000175000017500000002101111733011756027411 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define o(x) dbsearch(db, x) #include "ObjectMatcherTest.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/ObjectMatcher.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Network.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Host.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Constants.h" using namespace libfwbuilder; using namespace std; FWObject* dbsearch(FWObject *parent, string name) { for (list::iterator it = parent->begin(); it != parent->end(); it++) { FWObject *obj = *it; if (obj->getName() == name) return obj; FWObject *chs = dbsearch(obj, name); if (chs != NULL) return chs; } return NULL; } void ObjectMatcherTest::matchTest() { FWObjectDatabase *db = new FWObjectDatabase(); XMLTools::UpgradePredicate up; db->load(string("test_data.fwb"), &up, Constants::getTemplateDirectory()); ObjectMatcher om; om.setRecognizeBroadcasts(true); om.setRecognizeMulticasts(true); om.setIPV6(false); om.setMatchSubnets(false); om.setAddressRangeMatchMode(ObjectMatcher::EXACT); Firewall *fw1 = Firewall::cast(dbsearch(db, "fw1")); CPPUNIT_ASSERT(fw1 != NULL); Interface *fw1_eth0 = Interface::cast(dbsearch(fw1, "eth0")); CPPUNIT_ASSERT(fw1_eth0 != NULL); Interface *fw1_eth1 = Interface::cast(dbsearch(fw1, "eth1")); CPPUNIT_ASSERT(fw1_eth1 != NULL); Interface *fw1_eth2 = Interface::cast(dbsearch(fw1, "eth2")); CPPUNIT_ASSERT(fw1_eth2 != NULL); IPv6 *fw1_eth2_ipv6 = IPv6::cast(dbsearch(fw1_eth2, "fw1:eth2:ipv6")); CPPUNIT_ASSERT(fw1_eth2_ipv6 != NULL); physAddress *fw1_eth2_mac = physAddress::cast(dbsearch(fw1_eth2, "fw1:eth2:mac")); CPPUNIT_ASSERT(fw1_eth2_mac != NULL); Host *host1 = Host::cast(dbsearch(db, "host1")); CPPUNIT_ASSERT(host1 != NULL); Host *host2 = Host::cast(dbsearch(db, "host2")); CPPUNIT_ASSERT(host2 != NULL); Host *host3 = Host::cast(dbsearch(db, "host3")); CPPUNIT_ASSERT(host3 != NULL); Interface *host1_eth0 = Interface::cast(dbsearch(host1, "eth0")); CPPUNIT_ASSERT(host1_eth0 != NULL); Interface *host2_eth0 = Interface::cast(dbsearch(host2, "eth0")); CPPUNIT_ASSERT(host2_eth0 != NULL); IPv4 *host2_eth0_ip = IPv4::cast(dbsearch(host2_eth0, "ip")); CPPUNIT_ASSERT(host2_eth0_ip != NULL); Interface *host3_eth0 = Interface::cast(dbsearch(host3, "eth0")); CPPUNIT_ASSERT(host3_eth0 != NULL); Interface *host3_eth1 = Interface::cast(dbsearch(host3, "eth1")); CPPUNIT_ASSERT(host3_eth1 != NULL); CPPUNIT_ASSERT(om.dispatch(fw1, fw1)); CPPUNIT_ASSERT(om.dispatch(fw1_eth0, fw1)); CPPUNIT_ASSERT(om.dispatch(fw1_eth1, fw1)); CPPUNIT_ASSERT(om.dispatch(fw1_eth0, fw1_eth0)); CPPUNIT_ASSERT( ! om.dispatch(fw1_eth2_ipv6, fw1)); om.setIPV6(true); CPPUNIT_ASSERT( om.dispatch(fw1_eth2_ipv6, fw1)); om.setIPV6(false); CPPUNIT_ASSERT(om.dispatch(fw1_eth2_mac, fw1)); CPPUNIT_ASSERT(om.dispatch(host1_eth0, fw1)); CPPUNIT_ASSERT(om.dispatch(host1, fw1)); CPPUNIT_ASSERT(om.dispatch(host2_eth0_ip, fw1) == false); CPPUNIT_ASSERT(om.dispatch(host2_eth0, fw1) == false); CPPUNIT_ASSERT(om.dispatch(host2, fw1) == false); om.setMatchSubnets(true); CPPUNIT_ASSERT(om.dispatch(host2_eth0_ip, fw1)); om.setMatchSubnets(false); CPPUNIT_ASSERT(om.dispatch(host3_eth0, fw1) == false); CPPUNIT_ASSERT(om.dispatch(host3_eth1, fw1) == false); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.1")), fw1)); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.1")), fw1_eth1)); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.1")), fw1_eth0) == false); om.setIPV6(true); CPPUNIT_ASSERT(om.dispatch(IPv6::cast(o("addr-ipv6-1")), fw1)); CPPUNIT_ASSERT(om.dispatch(IPv6::cast(o("addr-ipv6-2")), fw1) == false); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.1")), fw1) == false); om.setIPV6(false); CPPUNIT_ASSERT(om.dispatch(IPv6::cast(o("addr-ipv6-1")), fw1) == false); CPPUNIT_ASSERT(om.dispatch(IPv6::cast(o("addr-ipv6-2")), fw1) == false); CPPUNIT_ASSERT(om.dispatch(Network::cast(o("net-192.168.1.0")), fw1) == false); CPPUNIT_ASSERT(om.dispatch(Network::cast(o("net-192.168.1.0")), fw1_eth1) == false); CPPUNIT_ASSERT(om.dispatch(Network::cast(o("net-192.168.1.0")), fw1_eth0) == false); CPPUNIT_ASSERT(om.dispatch(Network::cast(o("net-192.168.1.1")), fw1)); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.255")), fw1)); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.0")), fw1)); CPPUNIT_ASSERT(om.dispatch(Network::cast(o("all multicasts")), fw1)); om.setRecognizeBroadcasts(false); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.255")), fw1) == false); CPPUNIT_ASSERT(om.dispatch(IPv4::cast(o("addr-192.168.1.0")), fw1) == false); // ================================================================ // AddressRange tests // here match_subnets == false address_range_match_mode = EXACT // range1 192.168.1.10 - 192.168.1.20 // does not match fw1 exactly, but matches when match_subnets == true CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range1")), fw1) == false); // range2 192.168.2.1-192.168.2.3 does not match fw1:eth2 at all CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range2")), fw1) == false); // range3 192.168.2.27-192.168.2.50 partially overlaps with fw1:eth2 subnet CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range3")), fw1) == false); // range4 192.168.2.27-192.168.2.30 is completely inside fw1:eth2 subnet CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range4")), fw1) == false); // ================================================================ om.setAddressRangeMatchMode(ObjectMatcher::PARTIAL); // here match_subnets == false address_range_match_mode = PARTIAL // when match_subnets == false, ObjectMatcher compares address of interface with // the range and ignores netmask of the interface. Address has to be inside the range // to match // range3 192.168.2.27-192.168.2.50 partially overlaps with fw1:eth2 subnet // but address of interface 192.168.2.24 is outside the range CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range3")), fw1) == false); // range4 192.168.2.27-192.168.2.30 is completely inside fw1:eth2 subnet CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range4")), fw1) == false); // fw1:eth2:ip 192.168.2.24 falls inside range5 CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range5")), fw1)); // ================================================================ om.setMatchSubnets(true); // ranges will be compared to subnets defined by interface addr/mask // here match_subnets == true address_range_match_mode = PARTIAL CPPUNIT_ASSERT(om.dispatch(host2_eth0_ip, fw1)); CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range1")), fw1)); // range2 192.168.2.1-192.168.2.3 does not match fw1:eth2 at all CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range2")), fw1) == false); // range3 192.168.2.27-192.168.2.50 partially overlaps with fw1:eth2 subnet CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range3")), fw1)); // range4 192.168.2.27-192.168.2.30 is completely inside fw1:eth2 subnet CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range4")), fw1)); // range5 192.168.2.21-192.168.2.27 partially overlaps with fw1:eth2 subnet CPPUNIT_ASSERT(om.dispatch(AddressRange::cast(o("range5")), fw1)); } fwbuilder-5.1.0.3599/src/unit_tests/ObjectMatcherTest/main.cpp0000644000175000017500000000265211733011756024775 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "ObjectMatcherTest.h" #include "fwbuilder/FWObjectDatabase.h" #include using namespace libfwbuilder; int fwbdebug = 0; //QString user_name; std::string platform; int main( int, char** argv) { //init(argv); init(); CppUnit::TextUi::TestRunner runner; runner.addTest( ObjectMatcherTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/ObjectMatcherTest/ObjectMatcherTest.pro0000644000175000017500000000112211733011756027430 0ustar sylvestresylvestreinclude(../../../qmake.inc) QT -= core gui TARGET = ObjectMatcherTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS LIBS += $$CPPUNIT_LIBS SOURCES += main.cpp ObjectMatcherTest.cpp HEADERS += ObjectMatcherTest.h INCLUDEPATH += ../../.. ../../libfwbuilder/src DEPENDPATH += ../../libfwbuilder/src LIBS += ../../libfwbuilder/src/fwbuilder/libfwbuilder.a run_tests.commands = echo "Running tests..." && ./${TARGET} run_tests.depends = all clean_tests.depends = clean build_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/ObjectMatcherTest/test_data.fwb0000644000175000017500000003324311733011756026015 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/unit_tests/tests_common.pri0000644000175000017500000000444411733011756023222 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) QT += network OBJECTS_DIR = .obj MOC_DIR = .moc QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS CONFIG -= release CONFIG += debug INCLUDEPATH += ../../.. \ ../.. \ ../../common \ ../../parsers \ ../../import \ ../../compiler_lib \ ../../libgui \ ../../libgui/.ui \ ../../iptlib \ ../../pflib \ ../../cisco_lib \ ../../libfwbuilder/src DEPENDPATH += ../../.. \ ../.. \ ../../common \ ../../parsers \ ../../import \ ../../compiler_lib \ ../../libgui \ ../../libgui/.ui \ ../../iptlib \ ../../pflib \ ../../cisco_lib \ ../../libfwbuilder/src run_tests.commands = echo "Running tests..."; ./${TARGET} run_tests.depends = build_tests build_tests.depends = all clean_tests.depends = clean QMAKE_EXTRA_TARGETS += run_tests build_tests clean_tests INCLUDEPATH += $$ANTLR_INCLUDEPATH DEPENDPATH += $$ANTLR_INCLUDEPATH DEFINES += $$ANTLR_DEFINES DEPENDPATH = ../../common \ ../../iptlib \ ../../pflib \ ../../cisco_lib/ \ ../../compiler_lib \ ../../libgui \ ../../libfwbuilder/src/fwbuilder \ ../../libfwbuilder/src/fwcompiler STATIC_LIBS += \ ../main/libtest_main.a \ ../../libgui/libgui.a \ ../../import/libimport.a \ ../../common/libcommon.a \ ../../iptlib/libiptlib.a \ ../../pflib/libfwbpf.a \ ../../cisco_lib/libfwbcisco.a \ ../../compiler_lib/libcompilerdriver.a \ ../../libfwbuilder/src/fwcompiler/libfwcompiler.a \ ../../libfwbuilder/src/fwbuilder/libfwbuilder.a \ ../../parsers/libfwbparser.a \ $$ANTLR_LIBS \ $$CPPUNIT_LIBS PRE_TARGETDEPS += ../../common/libcommon.a \ ../main/libtest_main.a \ ../../iptlib/libiptlib.a \ ../../pflib/libfwbpf.a \ ../../cisco_lib/libfwbcisco.a \ ../../compiler_lib/libcompilerdriver.a \ ../../parsers/libfwbparser.a \ ../../import/libimport.a \ ../../libfwbuilder/src/fwcompiler/libfwcompiler.a \ ../../libfwbuilder/src/fwbuilder/libfwbuilder.a \ $$ANTLR_LIBS LIBS = $$STATIC_LIBS $$LIBS fwbuilder-5.1.0.3599/src/unit_tests/ICMP6ServiceDialogTest/0000755000175000017500000000000011733011756024105 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/ICMP6ServiceDialogTest/ICMP6ServiceDialogTest.cpp0000644000175000017500000001034511733011756030733 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: ICMPServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ICMP6ServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMP6Service.h" #include "ICMPServiceDialog.h" using namespace std; using namespace libfwbuilder; void ICMP6ServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* ICMP6ServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void ICMP6ServiceDialogTest::testDialog() { ICMP6Service *service = ICMP6Service::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), ICMP6Service::TYPENAME), ICMP6Service::TYPENAME, "testICMP6Service")); om->editObject(service); ICMPServiceDialog *dialog = mw->findChild("w_ICMP6ServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QSpinBox *type = dialog->findChild("icmpType"); QSpinBox *code = dialog->findChild("icmpCode"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestICMPService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestICMPService"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (service->getComment() == "Test comment"); type->clear(); for (int i=0; i<52; i++) QTest::keyClick(type, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("type") == 50); for (int i=0; i<210; i++) QTest::keyClick(type, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("type") == 255); code->clear(); for (int i=0; i<52; i++) QTest::keyClick(code, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("code") == 50); for (int i=0; i<210; i++) QTest::keyClick(code, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("code") == 255); } fwbuilder-5.1.0.3599/src/unit_tests/ICMP6ServiceDialogTest/ICMP6ServiceDialogTest.h0000644000175000017500000000242211733011756030375 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: ICMP6ServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ICMP6ServiceDialogTest_H #define ICMP6ServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class ICMP6ServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testDialog(); }; #endif // ICMP6ServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/ICMP6ServiceDialogTest/main_ICMP6ServiceDialogTest.cpp0000644000175000017500000000331111733011756031732 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ICMP6ServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new ICMP6ServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/ICMP6ServiceDialogTest/ICMP6ServiceDialogTest.pro0000644000175000017500000000031011733011756030740 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = ICMP6ServiceDialogTest SOURCES += main_ICMP6ServiceDialogTest.cpp \ ICMP6ServiceDialogTest.cpp HEADERS += ICMP6ServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewTest/0000755000175000017500000000000011733011756023044 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewTest/RuleSetViewTest.pro0000644000175000017500000000025411733011756026645 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = RuleSetViewTest SOURCES += main_RuleSetViewTest.cpp \ RuleSetViewTest.cpp HEADERS += RuleSetViewTest.h fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewTest/RuleSetViewTest.cpp0000644000175000017500000005262111733011756026634 0ustar sylvestresylvestre /* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: RuleSetViewTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RuleSetViewTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include #include #include "StartTipDialog.h" #include "QMetaProperty" #include "FWObjectClipboard.h" #include "RuleSetModel.h" #include "FWBApplication.h" using namespace std; using namespace QTest; using namespace libfwbuilder; #define getRuleForPosition( x ) ((RuleSetModel*)view->model())->findRuleForPosition( x ) void RuleSetViewTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->resize(QSize(800,600)); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d) if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "testFirewall")); openPolicy("testFirewall"); view = mw->findChild(""); om->closeObject(); } /* * Opens context menu at point relative to RuleSetView widget */ void RuleSetViewTest::showContextMenu(QPoint point) { view->showContextMenu(view->pos() + point); } void RuleSetViewTest::showContextMenu(int x, int y) { view->showContextMenu(view->pos() + QPoint(x,y)); } /* * Opens Policy of firewall with name fwname in RuleSetView of active project */ void RuleSetViewTest::openPolicy(QString fwname) { Policy *p = NULL; foreach (FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == fwname.toStdString()) { p = Firewall::cast(fw)->getPolicy(); } } QVERIFY (p != NULL); QCoreApplication::postEvent(mw, new openRulesetImmediatelyEvent(mw->activeProject()->getFileName(), p->getId())); QTest::qWait(100); } /* * Returns libfwbuilder::Library with name "User" */ Library* RuleSetViewTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } /* * Returns menu-relative position of topmost pixel clicking * which will trigger action */ QPoint findActionPos(QMenu *menu, QAction *action) { int x = menu->width()/2; for (int y=0; yheight(); y++) { if (menu->actionAt(QPoint(x,y)) != NULL && menu->actionAt(QPoint(x,y))->text() == action->text()) return QPoint(x,y); } return QPoint(-1,-1); } /* * Clicks item in topmost visible modal context menu. * Should be called right before opening menu (it waits 10 ms for menu to appear). */ void RuleSetViewTest::clickMenuItem(QString item) { clicked = false; itemToClick = item; QTimer::singleShot(100, this, SLOT(actuallyClickMenuItem())); } void RuleSetViewTest::actuallyClickMenuItem() { QMenu *menu = dynamic_cast(app->activePopupWidget()); Q_ASSERT(menu != NULL); foreach(QAction *action, menu->actions()) { if (action->text() == itemToClick) { //qDebug() << "clicking menu item" << action << action->text(); clicked = true; QPoint pos = findActionPos(menu, action); //qDebug() << pos; //QTest::mouseMove(menu, pos); QTest::mouseClick(menu, Qt::LeftButton, Qt::NoModifier, pos); //action->trigger(); //menu->hide(); return; } } // menu item not found. Include menu items that were actually // present in the menu in the error message to implify debugging QStringList items; foreach(QAction *action, menu->actions()) { items.push_back(QString("\"%1\"").arg(action->text())); } // need to hide the menu, otherwise test just hangs menu->hide(); QFAIL(QString("Menu item %1 not found. Menu consists of: %2") .arg(itemToClick) .arg(items.join(" ")).toAscii().constData()); } /* * Returns topmost pixel which belongs to first cell * of rule in RuleSetView */ QPoint RuleSetViewTest::findRulePosition(Rule *rule) { // Scroll view to make rule visible view->scrollTo(((RuleSetModel*)view->model())->indexForPosition(rule->getPosition()), QAbstractItemView::EnsureVisible); // Find top left pixel of rule's first cell for (int x=0; xwidth(); x++) { for(int y=0; yheight(); y++) { QModelIndex index = view->indexAt(QPoint(x,y)); Rule *found = ((RuleSetModel*)view->model())->getRule(view->indexAt(QPoint(x,y))); if (found == rule && index.column() == 0) return QPoint(x,y); } } return QPoint(-1,-1); } /* * Scrolls view to bottom and returns middle pixel of view's middle line. * There */ QPoint RuleSetViewTest::getViewBottomPoint() { view->scrollToBottom(); view->viewport()->mapToParent(QPoint(view->viewport()->width()/2, view->viewport()->height()-2)); return QPoint(view->viewport()->width()/2, view->viewport()->height()-2); } /* * Returns topmost pixel which belongs to first cell * of row #rule in RuleSetView */ QPoint RuleSetViewTest::findRulePosition(int rule) { return findRulePosition(getRuleForPosition(rule)); } /* * Fills group name request modal dialog with group name * and clicks OK. * Should be executed right before opening dialog. */ void RuleSetViewTest::createGroup(QString name) { groupToCreate = name; // timeout should be more than clickMenuItem timeout QTimer::singleShot(150, this, SLOT(actuallyCreateGroup())); } void RuleSetViewTest::actuallyCreateGroup() { QInputDialog *dlg = dynamic_cast(app->activeModalWidget()); Q_ASSERT(dlg != NULL); QLineEdit *name = dlg->findChild(); QTest::keyClicks(name, groupToCreate); dlg->accept(); } void RuleSetViewTest::test_add_remove() { QVERIFY(view->model()->rowCount(QModelIndex()) == 0); // Adding one new rule clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 1); Rule *rule1 = ((RuleSetModel*)view->model())->findRuleForPosition(0); // Adding rule at the bottom clickMenuItem("Add New Rule at the Bottom"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 2); Rule *rule2 = getRuleForPosition(1); QVERIFY(rule1!=rule2); QVERIFY(getRuleForPosition(0) == rule1); // Adding rule on top clickMenuItem("Add New Rule on Top"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 3); Rule *rule3 = getRuleForPosition(0); QVERIFY(rule1!=rule2 && rule1!=rule3 && rule2!=rule3); QVERIFY(getRuleForPosition(1) == rule1); QVERIFY(getRuleForPosition(2) == rule2); // Remove last rule view->selectRE(rule1, 0); clickMenuItem("Insert New Rule"); showContextMenu(findRulePosition(rule1)); QVERIFY(view->model()->rowCount(QModelIndex()) == 4); QVERIFY(getRuleForPosition(0) == rule3); QVERIFY(getRuleForPosition(2) == rule1); QVERIFY(getRuleForPosition(3) == rule2); Rule *rule4 = getRuleForPosition(1); // Remove last rule view->selectRE(rule2, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule2)); QVERIFY(view->model()->rowCount(QModelIndex()) == 3); QVERIFY(getRuleForPosition(0) == rule3); QVERIFY(getRuleForPosition(1) == rule4); QVERIFY(getRuleForPosition(2) == rule1); // Remove first rule view->selectRE(rule3, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule3)); QVERIFY(view->model()->rowCount(QModelIndex()) == 2); QVERIFY(getRuleForPosition(0) == rule4); QVERIFY(getRuleForPosition(1) == rule1); // Remove all created rules view->selectRE(rule4, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule4)); view->selectRE(rule1, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule1)); QVERIFY(view->model()->rowCount(QModelIndex()) == 0); } void RuleSetViewTest::test_group() { // Adding one new rule clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 1); Rule *rule1 = ((RuleSetModel*)view->model())->findRuleForPosition(0); // Adding seven new rules at the bottom Rule *rules[7]; for (int i=0; i<7;i++) { clickMenuItem("Add New Rule at the Bottom"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == i+2); rules[i] = getRuleForPosition(i+1); } // Create new group view->selectRE(rules[2], 0); createGroup("Test Group Name"); clickMenuItem("New Group"); showContextMenu(findRulePosition(rules[2])); QList groups; ((RuleSetModel*)view->model())->getGroups(groups); QVERIFY(groups.size() == 1); QVERIFY(rules[2]->getRuleGroupName() == "Test Group Name"); // Add two more rules to the group view->selectRE(rules[3], 0); clickMenuItem("Add To the Group Test Group Name"); showContextMenu(findRulePosition(rules[3])); view->clearSelection(); view->selectRE(rules[1], 0); clickMenuItem("Add To the Group Test Group Name"); showContextMenu(findRulePosition(rules[1])); QList groups2; ((RuleSetModel*)view->model())->getGroups(groups2); QVERIFY(groups.size() == 1); QVERIFY(rules[1]->getRuleGroupName() == "Test Group Name"); QVERIFY(rules[2]->getRuleGroupName() == "Test Group Name"); QVERIFY(rules[3]->getRuleGroupName() == "Test Group Name"); QVERIFY(groups2.first().internalId() == groups.first().internalId()); // Expanding created group view->expandAll(); // Creating new rule in group using "Add Rule Below" view->selectRE(rules[2], 0); clickMenuItem("Add New Rule Below"); showContextMenu(findRulePosition(rules[2])); Rule *newrule1 = ((RuleSetModel*)view->model())->findRuleForPosition(4); for (int i=0; i<5; i++) QVERIFY(newrule1 != rules[i]); QVERIFY(newrule1 != rule1); QVERIFY(newrule1->getRuleGroupName() == "Test Group Name"); // Creating new rule in group using "Insert Rule" view->selectRE(rules[2], 0); clickMenuItem("Insert New Rule"); showContextMenu(findRulePosition(rules[2])); Rule *newrule2 = ((RuleSetModel*)view->model())->findRuleForPosition(3); for (int i=0; i<5; i++) QVERIFY(newrule2 != rules[i]); QVERIFY(newrule2 != rule1); QVERIFY(newrule2 != newrule1); QVERIFY(newrule2->getRuleGroupName() == "Test Group Name"); // Select and add to group two rules under it view->clearSelection(); view->selectionModel()->select(((RuleSetModel*)view->model())->indexForPosition(rules[4]->getPosition()), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); view->selectionModel()->select(((RuleSetModel*)view->model())->indexForPosition(rules[5]->getPosition()), QItemSelectionModel::Select); clickMenuItem("Add To the Group Test Group Name"); showContextMenu(findRulePosition(rules[4])); QList groups3; ((RuleSetModel*)view->model())->getGroups(groups3); QVERIFY(groups3.size() == 1); QVERIFY(rules[4]->getRuleGroupName() == "Test Group Name"); QVERIFY(rules[5]->getRuleGroupName() == "Test Group Name"); QVERIFY(groups3.first().internalId() == groups.first().internalId()); // Remoe first rule from group QVERIFY(view->model()->rowCount(groups3.first()) == 7); view->selectRE(rules[1], 0); clickMenuItem("Remove From the Group"); showContextMenu(findRulePosition(rules[1])); QVERIFY(rules[1]->getRuleGroupName() == ""); QVERIFY(view->model()->rowCount(groups3.first()) == 6); // Remoe last rule from group view->selectRE(rules[5], 0); clickMenuItem("Remove From the Group"); showContextMenu(findRulePosition(rules[5])); QVERIFY(rules[5]->getRuleGroupName() == ""); QVERIFY(view->model()->rowCount(groups3.first()) == 5); // Remove rule inside group view->selectRE(rules[3], 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rules[3])); QVERIFY(view->model()->rowCount(groups3.first()) == 4); // Remove all created rules for (int i=0; i<7; i++) { if (i==3) continue; view->selectRE(rules[i], 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rules[i])); } view->selectRE(newrule1, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(newrule1)); view->selectRE(newrule2, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(newrule2)); view->selectRE(rule1, 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule1)); QVERIFY(view->model()->rowCount() == 0); } void RuleSetViewTest::test_move() { // Adding one new rule clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 1); Rule *rules[4]; rules[0] = ((RuleSetModel*)view->model())->findRuleForPosition(0);; // Adding three new rules at the bottom for (int i=1; i<4;i++) { clickMenuItem("Add New Rule at the Bottom"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == i+1); rules[i] = getRuleForPosition(i); } // Verifying that all rules' positions match their indexes for (int i=0; i<4; i++) QVERIFY(rules[i]->getPosition() == i); // Moving second rule up view->selectRE(rules[1], 0); clickMenuItem("Move Rule Up"); showContextMenu(findRulePosition(rules[1])); QVERIFY(rules[1]->getPosition() == 0); QVERIFY(rules[0]->getPosition() == 1); // Moving first rule down view->selectRE(rules[1], 0); clickMenuItem("Move Rule Down"); showContextMenu(findRulePosition(rules[1])); QVERIFY(rules[1]->getPosition() == 1); QVERIFY(rules[0]->getPosition() == 0); // Moving first rule up (rule order should not change) view->selectRE(rules[0], 0); clickMenuItem("Move Rule Up"); showContextMenu(findRulePosition(rules[0])); for (int i=0; i<4; i++) QVERIFY(rules[i]->getPosition() == i); // Moving last rule down (rule order should not change) view->selectRE(rules[3], 0); clickMenuItem("Move Rule Down"); showContextMenu(findRulePosition(rules[3])); for (int i=0; i<4; i++) QVERIFY(rules[i]->getPosition() == i); // Selecting two rules and moving them up view->selectRE(rules[1], 0); view->selectionModel()->select(((RuleSetModel*)view->model())->indexForPosition(2), QItemSelectionModel::Select); clickMenuItem("Move Rules Up"); showContextMenu(findRulePosition(rules[1])); QVERIFY(rules[1]->getPosition() == 0); QVERIFY(rules[2]->getPosition() == 1); QVERIFY(rules[0]->getPosition() == 2); QVERIFY(rules[3]->getPosition() == 3); // Selecting two rules and moving them down view->selectRE(rules[2], 0); view->selectionModel()->select(((RuleSetModel*)view->model())->indexForPosition(2), QItemSelectionModel::Select); clickMenuItem("Move Rules Down"); showContextMenu(findRulePosition(rules[2])); QVERIFY(rules[1]->getPosition() == 0); QVERIFY(rules[3]->getPosition() == 1); QVERIFY(rules[2]->getPosition() == 2); QVERIFY(rules[0]->getPosition() == 3); // Adding two more rules Rule *newrules[6] = { rules[1], rules[3], rules[2], rules[0], NULL, NULL }; for (int i=4; i<6;i++) { clickMenuItem("Add New Rule at the Bottom"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == i+1); newrules[i] = getRuleForPosition(i); } // Creating a group to test moving rules inside of it view->selectRE(newrules[1], 0); for (int i=2; i<5; i++) view->selectionModel()->select(((RuleSetModel*)view->model())->indexForPosition(i), QItemSelectionModel::Select); createGroup("Test Group Name"); clickMenuItem("New Group"); showContextMenu(findRulePosition(newrules[1])); for (int i=1; i<5; i++) QVERIFY(newrules[i]->getRuleGroupName() == "Test Group Name"); // Expanding created group view->expandAll(); // Moving second rule of group up view->selectRE(newrules[2], 0); clickMenuItem("Move Rule Up"); showContextMenu(findRulePosition(newrules[2])); QVERIFY(newrules[2]->getPosition() == 1); QVERIFY(newrules[1]->getPosition() == 2); // Moving first rule of group up. It should leave the group. view->selectRE(newrules[2], 0); clickMenuItem("Move Rule Up"); showContextMenu(findRulePosition(newrules[2])); QVERIFY(newrules[2]->getPosition() == 1); QVERIFY(newrules[0]->getPosition() == 0); QVERIFY(newrules[1]->getPosition() == 2); QVERIFY(newrules[2]->getRuleGroupName() == ""); // Moving first rule above group down. It should be added to group. view->selectRE(newrules[2], 0); clickMenuItem("Move Rule Down"); showContextMenu(findRulePosition(newrules[2])); QVERIFY(newrules[2]->getPosition() == 1); QVERIFY(newrules[0]->getPosition() == 0); QVERIFY(newrules[1]->getPosition() == 2); QVERIFY(newrules[2]->getRuleGroupName() == "Test Group Name"); // Moving last rule of group down. It should leave the group. view->selectRE(newrules[4], 0); clickMenuItem("Move Rule Down"); showContextMenu(findRulePosition(newrules[4])); QVERIFY(newrules[4]->getPosition() == 4); QVERIFY(newrules[5]->getPosition() == 5); QVERIFY(newrules[3]->getPosition() == 3); QVERIFY(newrules[4]->getRuleGroupName() == ""); // Moving first rule below group up. It should be added to group. view->selectRE(newrules[4], 0); clickMenuItem("Move Rule Up"); showContextMenu(findRulePosition(newrules[4])); QVERIFY(newrules[4]->getPosition() == 4); QVERIFY(newrules[5]->getPosition() == 5); QVERIFY(newrules[3]->getPosition() == 3); QVERIFY(newrules[4]->getRuleGroupName() == "Test Group Name"); // Removing all created rules for (int i=0; i<6; i++) { view->selectRE(newrules[i], 0); clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(newrules[i])); } QVERIFY(view->model()->rowCount() == 0); } void RuleSetViewTest::test_copy_paste() { // Adding one new rule clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 1); Rule *rules[4]; rules[0] = ((RuleSetModel*)view->model())->findRuleForPosition(0); // Adding three new rules at the bottom for (int i=1; i<4;i++) { clickMenuItem("Add New Rule at the Bottom"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == i+1); rules[i] = getRuleForPosition(i); } // Cutting second rule view->selectRE(rules[1], 0); clickMenuItem("Cut Rule"); showContextMenu(findRulePosition(rules[1])); QVERIFY(view->model()->rowCount() == 3); // Pasting cutted rule above first view->selectRE(rules[0], 0); clickMenuItem("Paste Rule Above"); showContextMenu(findRulePosition(rules[0])); QVERIFY(view->model()->rowCount() == 4); rules[1] = getRuleForPosition(0); // Copying second rule view->selectRE(rules[1], 0); clickMenuItem("Copy Rule"); showContextMenu(findRulePosition(rules[1])); QVERIFY(view->model()->rowCount() == 4); // Pasting rule after first rule view->selectRE(rules[1], 0); clickMenuItem("Paste Rule Below"); showContextMenu(findRulePosition(rules[1])); QVERIFY(view->model()->rowCount() == 5); // Copy two rules view->selectRE(getRuleForPosition(1), 0); view->selectionModel()->select(((RuleSetModel*)view->model())->indexForPosition(2), QItemSelectionModel::Select); clickMenuItem("Copy Rules"); showContextMenu(findRulePosition(getRuleForPosition(1))); QVERIFY(view->model()->rowCount() == 5); // Paste rules at the bottom view->selectRE(getRuleForPosition(4), 0); clickMenuItem("Paste Rule Below"); showContextMenu(findRulePosition(getRuleForPosition(4))); QVERIFY(view->model()->rowCount() == 7); } fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewTest/main_RuleSetViewTest.cpp0000644000175000017500000000327511733011756027641 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RuleSetViewTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new RuleSetViewTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewTest/RuleSetViewTest.h0000644000175000017500000000413311733011756026274 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: RuleSetViewTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include #include "newClusterDialog.h" #include "upgradePredicate.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "instDialog.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "RuleSetView.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" class RuleSetViewTest : public QObject { Q_OBJECT ObjectManipulator *om; RuleSetView *view; const char *ssh_auth_sock; void openPolicy(QString fw); libfwbuilder::Library* findUserLibrary(); QString groupToCreate; QString itemToClick; bool clicked; void clickMenuItem(QString item); QPoint findRulePosition(int rule); QPoint findRulePosition(libfwbuilder::Rule *rule); QPoint getViewBottomPoint(); void showContextMenu(QPoint point); void showContextMenu(int,int); void createGroup(QString name); private slots: void initTestCase(); void test_add_remove(); void test_group(); void test_move(); void test_copy_paste(); public slots: void actuallyClickMenuItem(); void actuallyCreateGroup(); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogClusterTest/0000755000175000017500000000000011733011756024265 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/instDialogClusterTest/instDialogClusterTest.cpp0000644000175000017500000002542411733011756031277 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogClusterTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ================================ Tests implemented in this module: ticket 1089 Tests for clusters: * when user clicks "install", checkboxes "install" should appear only next to the firewalls and should not appear next to the clusters in the list Ticket 1308: test2: * select cluster "cluster1" in the tree and use context menu to compile it * check that the list has objects "cluster1", "test3" and "test4" * check that the warning message is hidden test3: * regardless of the selection in the tree, simulate clicking on the main toolbar button "Compile" * check that the list includes objects "cluster1", "test3", "test4", "test1", "test2" and the warning message is hidden the focus of these tests is on the warning message. We verify settings of the "Compile" checkboxes in other tests. */ #include "instDialogClusterTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include "FWBApplication.h" #include "FWObjectClipboard.h" #include "StartTipDialog.h" using namespace std; using namespace QTest; using namespace libfwbuilder; void instDialogClusterTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); QTest::qWait(5000); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); mw->loadFile("test_work.fwb", false); QTest::qWait(1000); ObjectManipulator *om = mw->activeProject()->findChild("om"); FWObject *user_lib = mw->db()->findObjectByName(Library::TYPENAME, "User"); QVERIFY(user_lib != NULL); om->openLibForObject(user_lib); FWObject *cl = om->getCurrentLib(); QVERIFY(cl != NULL); QVERIFY(cl == user_lib); } void instDialogClusterTest::openPolicy(QString fwname) { Policy *p = NULL; foreach (FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == fwname.toStdString()) { p = Firewall::cast(fw)->getPolicy(); } } QVERIFY (p != NULL); QCoreApplication::postEvent(mw, new openRulesetImmediatelyEvent(mw->activeProject()->getFileName(), p->getId())); QTest::qWait(100); } void instDialogClusterTest::verifyDialog(instDialog *dlg, int items) { QVERIFY(dlg != NULL); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); if (items != -1) QVERIFY(table->topLevelItemCount() == items); QTreeWidgetItemIterator it(table, QTreeWidgetItemIterator::Enabled); while (*it) { if ((*it)->text(0) == "cluster1") QVERIFY((*it)->checkState(1) == Qt::Checked); if ((*it)->text(0) == "test1") QVERIFY((*it)->checkState(1) == Qt::Unchecked); if ((*it)->text(0) == "test2") QVERIFY((*it)->checkState(1) == Qt::Checked); it++; } } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void instDialogClusterTest::closeContextMenu() { QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } menu->hide(); } void instDialogClusterTest::openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText) { QTimer::singleShot(100, this, SLOT(closeContextMenu())); QPoint item_pos = findItemPos(item, tree); om->contextMenuRequested(item_pos); QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } foreach (QObject *act, menu->children()) { QAction *action = dynamic_cast(act); if (action == NULL) continue; if (action->text() == actionText) { action->activate(QAction::Trigger); break; } } } void instDialogClusterTest::page1_8() { ObjectTreeView *tree = mw->getCurrentObjectTree(); QVERIFY(tree != NULL); ObjectTreeViewItem *test3 = dynamic_cast( tree->findItems( "test3", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); QVERIFY(test3 != NULL); tree->selectionModel()->select( tree->indexAt(findItemPos(test3, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(test3); ObjectManipulator *om = mw->activeProject()->findChild("om"); openContextMenu(om, test3, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QVERIFY(dlg != NULL); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->topLevelItemCount() == 1); QVERIFY(table->topLevelItem(0)->text(0) == "test3"); QFrame *warning_space = dlg->findChild("warning_space"); QLabel *warning_message_1 = dlg->findChild("warning_message_1"); QLabel *warning_message_2 = dlg->findChild("warning_message_2"); QVERIFY(warning_space->isVisible()); QVERIFY(warning_message_1->isVisible()); QVERIFY(warning_message_2->isVisible()); QTest::qWait(1000); dlg->findChild("cancelButton")->click(); QTest::qWait(1000); } void instDialogClusterTest::page1_9() { ObjectTreeView *tree = mw->getCurrentObjectTree(); ObjectTreeViewItem *cluster1 = dynamic_cast(tree->findItems("cluster1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); tree->selectionModel()->select(tree->indexAt(findItemPos(cluster1, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(cluster1); ObjectManipulator *om = mw->activeProject()->findChild("om"); openContextMenu(om, cluster1, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QVERIFY(dlg != NULL); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->topLevelItemCount() == 1); QVERIFY(table->topLevelItem(0)->text(0) == "cluster1"); QVERIFY(table->topLevelItem(0)->childCount() == 2); QVERIFY(table->topLevelItem(0)->child(0)->text(0) == "test3"); QVERIFY(table->topLevelItem(0)->child(1)->text(0) == "test4"); QFrame *warning_space = dlg->findChild("warning_space"); QVERIFY(warning_space->isHidden()); QTest::qWait(1000); dlg->findChild("cancelButton")->click(); QTest::qWait(1000); } void instDialogClusterTest::page1_10() { QAction *compile = mw->findChild("compileAction"); compile->activate(QAction::Trigger); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QVERIFY(dlg != NULL); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->topLevelItemCount() == 3); QVERIFY(! table->findItems("cluster1", Qt::MatchExactly, 0).isEmpty()); QVERIFY(! table->findItems("test1", Qt::MatchExactly, 0).isEmpty()); QVERIFY(! table->findItems("test2", Qt::MatchExactly, 0).isEmpty()); QVERIFY(! table->findItems("test3", Qt::MatchExactly | Qt::MatchRecursive, 0).isEmpty()); QVERIFY(! table->findItems("test4", Qt::MatchExactly | Qt::MatchRecursive, 0).isEmpty()); QFrame *warning_space = dlg->findChild("warning_space"); QVERIFY(warning_space->isHidden()); QTest::qWait(1000); dlg->findChild("cancelButton")->click(); QTest::qWait(1000); } void instDialogClusterTest::page1_11() { QAction *compile = mw->findChild("installAction"); compile->activate(QAction::Trigger); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QVERIFY(dlg != NULL); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->topLevelItemCount() == 3); //QTest::qWait(100000); for (int i=0; i< table->topLevelItemCount(); i++) { QTreeWidgetItem *item = table->topLevelItem(i); if (item->text(0) == "cluster1") { QVERIFY(item->checkState(2) == Qt::Unchecked); QVERIFY(item->checkState(1) == Qt::Checked); QVERIFY(item->child(0)->checkState(1) == Qt::Unchecked); QVERIFY(item->child(0)->checkState(2) == Qt::Checked); QVERIFY(item->child(1)->checkState(1) == Qt::Unchecked); QVERIFY(item->child(1)->checkState(2) == Qt::Checked); } if (item->text(0) == "test1") { QVERIFY(item->checkState(1) == Qt::Unchecked); QVERIFY(item->checkState(2) == Qt::Checked); } if (item->text(0) == "test2") { QVERIFY(item->checkState(1) == Qt::Checked); QVERIFY(item->checkState(2) == Qt::Checked); } } QTest::qWait(1000); //dlg->findChild("cancelButton")->click(); dlg->reject(); QTest::qWait(1000); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogClusterTest/instDialogClusterTest.h0000644000175000017500000000342011733011756030734 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogClusterTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include "newClusterDialog.h" #include "upgradePredicate.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "instDialog.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" class instDialogClusterTest : public QObject { Q_OBJECT const char *ssh_auth_sock; void openPolicy(QString fw); void verifyDialog(instDialog *dlg, int items = -1); void openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText); void removeFiles(); private slots: void initTestCase(); void page1_8(); void page1_9(); void page1_10(); void page1_11(); public slots: void closeContextMenu(); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogClusterTest/test.fwb0000644000175000017500000035062311733011756025755 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/instDialogClusterTest/main_instDialogClusterTest.cpp0000644000175000017500000000331111733011756032272 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "instDialogClusterTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new instDialogClusterTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogClusterTest/instDialogClusterTest.pro0000644000175000017500000000051611733011756031310 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = instDialogClusterTest SOURCES += main_instDialogClusterTest.cpp \ instDialogClusterTest.cpp HEADERS += instDialogClusterTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/FWBTreeTest/0000755000175000017500000000000011733011756022064 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/FWBTreeTest/FWBTreeTest.pro0000644000175000017500000000023311733011756024702 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network TARGET = FWBTreeTest SOURCES += main_FWBTreeTest.cpp \ FWBTreeTest.cpp HEADERS += FWBTreeTest.hfwbuilder-5.1.0.3599/src/unit_tests/FWBTreeTest/main_FWBTreeTest.cpp0000644000175000017500000000242611733011756025676 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "FWBTreeTest.h" int fwbdebug; int main(int /*UNUSED argc*/, char ** /*UNUSED argv[]*/) { CppUnit::TextUi::TestRunner runner; runner.addTest( FWBTreeTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/FWBTreeTest/FWBTreeTest.cpp0000644000175000017500000001777711733011756024711 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "FWBTreeTest.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Host.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Network.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" using namespace libfwbuilder; using namespace std; void FWBTreeTest::isSystem() { FWBTree fwbtree; FWObjectDatabase db; CPPUNIT_ASSERT(fwbtree.isSystem(&db) == true); Library *lib = db.createLibrary(4); CPPUNIT_ASSERT(fwbtree.isSystem(lib) == true); lib = db.createLibrary(7); CPPUNIT_ASSERT(fwbtree.isSystem(lib) == true); lib = db.createLibrary(1); CPPUNIT_ASSERT(fwbtree.isSystem(lib) == false); lib = Library::cast(fwbtree.createNewLibrary(&db)); FWObject *slot = fwbtree.getStandardSlotForObject(lib, Firewall::TYPENAME); CPPUNIT_ASSERT(fwbtree.isSystem(slot) == true); Firewall fw; CPPUNIT_ASSERT(fwbtree.isSystem(&fw) == false); } QSet FWBTreeTest::getStandardFolders(FWObject *root) { QSet res; for (FWObject::iterator i = root->begin(); i != root->end(); i++) { if (FWBTree().isStandardFolder(*i)) res.insert(*i); res += getStandardFolders(*i); } return res; } void FWBTreeTest::validateForInsertion() { FWObjectDatabase db; FWBTree().createNewLibrary(&db); QSet stdFolders = getStandardFolders(&db); QString err; FWBTree tree; Host host; Firewall firewall; Interface iface; IPv4 ipv4; IPv6 ipv6; Firewall fw; Network net; CPPUNIT_ASSERT(tree.validateForInsertion(&host, &iface, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&firewall, &iface, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&iface, &ipv4, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&iface, &ipv6, err) == true); firewall.addInterface(&iface); CPPUNIT_ASSERT(tree.validateForInsertion(&iface, &ipv4, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&iface, &ipv6, err) == true); ObjectGroup grp, grp2; Cluster cluster; DNSName dnsname; AddressRange addrrange; AddressTable addrtable; CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &host, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &firewall, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &cluster, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &dnsname, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &addrrange, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &addrtable, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &grp2, err) == true); ServiceGroup sgrp, sgrp2; IPService ip; ICMPService icmp; TCPService tcp; UDPService udp; CustomService custom; CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &ip, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &icmp, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &tcp, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &udp, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &custom, err) == true); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &sgrp2, err) == true); Interval interval; IntervalGroup igrp; CPPUNIT_ASSERT(tree.validateForInsertion(&igrp, &interval, err) == true); foreach (FWObject* folder, stdFolders) { if (folder->getName() == "Hosts") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &host, err) == true); if (folder->getName() == "Firewalls") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &fw, err) == true); if (folder->getName() == "Addresses") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &ipv4, err) == true); if (folder->getName() == "Addresses") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &ipv6, err) == true); if (folder->getName() == "TCP") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &tcp, err) == true); if (folder->getName() == "UDP") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &udp, err) == true); if (folder->getName() == "ICMP") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &icmp, err) == true); if (folder->getName() == "Address ranges") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &addrrange, err) == true); if (folder->getName() == "Networks") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &net, err) == true); } CPPUNIT_ASSERT(tree.validateForInsertion(&host, &ipv4, err) == false); CPPUNIT_ASSERT(tree.validateForInsertion(&firewall, &ipv4, err) == false); CPPUNIT_ASSERT(tree.validateForInsertion(&cluster, &ipv4, err) == false); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &ip, err) == false); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &ipv4, err) == false); CPPUNIT_ASSERT(tree.validateForInsertion(&grp, &interval, err) == false); CPPUNIT_ASSERT(tree.validateForInsertion(&sgrp, &interval, err) == false); foreach (FWObject* folder, stdFolders) { if (folder->getName() == "Addresses") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &host, err) == false); if (folder->getName() == "Addresses") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &fw, err) == false); if (folder->getName() == "Hosts") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &ipv4, err) == false); if (folder->getName() == "Firewalls") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &ipv6, err) == false); if (folder->getName() == "Networks") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &tcp, err) == false); if (folder->getName() == "TCP") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &udp, err) == false); if (folder->getName() == "Address ranges") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &icmp, err) == false); if (folder->getName() == "ICMP") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &addrrange, err) == false); if (folder->getName() == "UDP") CPPUNIT_ASSERT(tree.validateForInsertion(folder, &net, err) == false); } // destructor ~FWObject calls FWObject::destroyChildren() which // tries to delete all child objects. Since interface iface was // not created using new, it can not be deleted. Remove it to // avoid crash. Also need to ref() it so that FWObject::remove() // does not try to delete it as well. All these hacks just because // a2k@codeminders.com was too lazy to create objects as recommended. iface.ref(); firewall.removeInterface(&iface); } fwbuilder-5.1.0.3599/src/unit_tests/FWBTreeTest/FWBTreeTest.h0000644000175000017500000000247111733011756024337 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWBTREETEST_H #define FWBTREETEST_H #include "FWBTree.h" #include class FWBTreeTest : public CppUnit::TestFixture { QSet getStandardFolders(libfwbuilder::FWObject *root); public: void isSystem(); void validateForInsertion(); CPPUNIT_TEST_SUITE(FWBTreeTest); CPPUNIT_TEST(isSystem); CPPUNIT_TEST(validateForInsertion); CPPUNIT_TEST_SUITE_END(); }; #endif // FWBTREETEST_H fwbuilder-5.1.0.3599/src/unit_tests/ICMPServiceDialogTest/0000755000175000017500000000000011733011756024017 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/ICMPServiceDialogTest/ICMPServiceDialogTest.cpp0000644000175000017500000001037511733011756030562 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: ICMPServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ICMPServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "ICMPServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "ICMPServiceDialog.h" using namespace std; using namespace libfwbuilder; void ICMPServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* ICMPServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void ICMPServiceDialogTest::testDialog() { ICMPService *service = ICMPService::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), ICMPService::TYPENAME), ICMPService::TYPENAME, "testICMPService")); om->editObject(service); ICMPServiceDialog *dialog = mw->findChild("w_ICMPServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QSpinBox *type = dialog->findChild("icmpType"); QSpinBox *code = dialog->findChild("icmpCode"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestICMPService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestICMPService"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (service->getComment() == "Test comment"); type->clear(); for (int i=0; i<52; i++) QTest::keyClick(type, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("type") == 50); for (int i=0; i<210; i++) QTest::keyClick(type, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("type") == 255); code->clear(); for (int i=0; i<52; i++) QTest::keyClick(code, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("code") == 50); for (int i=0; i<210; i++) QTest::keyClick(code, Qt::Key_Up); QTest::keyClick(type, Qt::Key_Enter); QVERIFY(service->getInt("code") == 255); } fwbuilder-5.1.0.3599/src/unit_tests/ICMPServiceDialogTest/ICMPServiceDialogTest.h0000644000175000017500000000241511733011756030223 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: ICMPServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ICMPServiceDialogTest_H #define ICMPServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class ICMPServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testDialog(); }; #endif // ICMPServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/ICMPServiceDialogTest/ICMPServiceDialogTest.pro0000644000175000017500000000030411733011756030567 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = ICMPServiceDialogTest SOURCES += main_ICMPServiceDialogTest.cpp \ ICMPServiceDialogTest.cpp HEADERS += ICMPServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/ICMPServiceDialogTest/main_ICMPServiceDialogTest.cpp0000644000175000017500000000330711733011756031563 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ICMPServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new ICMPServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/unit_tests.sh0000755000175000017500000000052411733011756022527 0ustar sylvestresylvestre#!/bin/sh QMAKE="${QMAKE:-qmake}" QMAKEPARAMS="${QMAKESPEC:+ -spec $QMAKESPEC}" set -e build() { local _d="$1" shift ( cd "$_d" && $QMAKE $QMAKEPARAMS && "$@" ) } build main "$@" find . -maxdepth 1 -type d | egrep -- '^\./[A-Za-z0-9_-]*$' | while read _d do echo "======================= $_d" build "$_d" "$@" done fwbuilder-5.1.0.3599/src/unit_tests/GroupObjectDialogTest/0000755000175000017500000000000011733011756024171 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/GroupObjectDialogTest/GroupObjectDialogTest.cpp0000644000175000017500000002742011733011756031105 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: GroupObjectDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "GroupObjectDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "GroupObjectDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWServiceReference.h" #include "FWBApplication.h" #include "GroupObjectDialog.h" using namespace std; using namespace libfwbuilder; void GroupObjectDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); address = createObject("address"); address6 = createObject("address6"); network = createObject("network"); network6 = createObject("netowork6"); range = createObject("range"); table = createObject("table"); dns = createObject("dns"); ipservice = createObject("ipservice"); icmpservice = createObject("icmpservice"); udpservice = createObject("udpservice"); tcpservice = createObject("tcpservice"); tagservice = createObject("tagservice"); userservice = createObject("userservice"); FWObject *object_group = createObject("Object Group"); FWObject *service_group = createObject("Service Group"); } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void GroupObjectDialogTest::checkMessageBox() { QVERIFY(app->activeModalWidget()->metaObject()->className() == QMessageBox().metaObject()->className()); QTimer::singleShot(10, app->activeModalWidget(), SLOT(reject())); QVERIFY(dynamic_cast(app->activeModalWidget())->text().contains("300.300.300.300") || dynamic_cast(app->activeModalWidget())->text().contains("foo:345:1") || dynamic_cast(app->activeModalWidget())->text().contains("145") || dynamic_cast(app->activeModalWidget())->text().contains("300") || dynamic_cast(app->activeModalWidget())->text().contains("0") || dynamic_cast(app->activeModalWidget())->text().contains("0.0.0.0") || dynamic_cast(app->activeModalWidget())->text().contains("255.300.300.0") ); } void GroupObjectDialogTest::checkNoMessageBox() { foreach(QWidget *w, app->topLevelWidgets()) QVERIFY(w->metaObject()->className() != QMessageBox().metaObject()->className()); } void setLineEditText(QLineEdit *line, QString text) { line->clear(); QTest::keyClicks(line, text); QTest::keyClick(line, Qt::Key_Enter); } Library* GroupObjectDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } template ObjectTreeViewItem* findItemForType(ObjectTreeView *tree) { foreach(QTreeWidgetItem* item, tree->findItems("", Qt::MatchRecursive | Qt::MatchContains, 0)) { if (TYPE::isA(dynamic_cast(item)->getFWObject()) != NULL) return dynamic_cast(item); } return NULL; } template FWTYPE* GroupObjectDialogTest::createObject(QString name) { return FWTYPE::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), FWTYPE::TYPENAME), FWTYPE::TYPENAME, name)); } bool checkObjectInsertion(GroupObjectDialog *dlg, Group *grp, FWObject *obj) { qDebug() << "Trying to add object" << obj->getName().c_str() << "(" << obj->getTypeName().c_str() << ")" << "to group" << grp->getPath().c_str(); dlg->insertObject(obj); dlg->applyChanges(); for (Group::iterator i = grp->begin(); i!= grp->end(); i++) { if (FWReference::cast(*i)->getPointer() == obj) return true; } //object was not inserted into group return false; } /* * Test insertion of objects of different types into an object group */ void GroupObjectDialogTest::testObjectGroup() { ObjectTreeViewItem *groupItem = dynamic_cast( mw->getCurrentObjectTree()->findItems( "Object Group", Qt::MatchRecursive, 0).first()); QVERIFY(groupItem != NULL); mw->getCurrentObjectTree()->setCurrentItem( groupItem, 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear); ObjectGroup *group = ObjectGroup::cast(groupItem->getFWObject()); QVERIFY(group != NULL); om->editObject(group); QTest::qWait(50); GroupObjectDialog *groupdialog = mw->findChild( "w_ObjectGroupDialog"); QVERIFY(groupdialog != NULL); QVERIFY(checkObjectInsertion(groupdialog, group, address)); QVERIFY(checkObjectInsertion(groupdialog, group, address6)); QVERIFY(checkObjectInsertion(groupdialog, group, network)); QVERIFY(checkObjectInsertion(groupdialog, group, network6)); QVERIFY(checkObjectInsertion(groupdialog, group, range)); QVERIFY(checkObjectInsertion(groupdialog, group, table)); QVERIFY(checkObjectInsertion(groupdialog, group, dns)); QVERIFY(checkObjectInsertion(groupdialog, group, group)); QVERIFY(!checkObjectInsertion(groupdialog, group, ipservice)); QVERIFY(!checkObjectInsertion(groupdialog, group, icmpservice)); QVERIFY(!checkObjectInsertion(groupdialog, group, udpservice)); QVERIFY(!checkObjectInsertion(groupdialog, group, tcpservice)); QVERIFY(!checkObjectInsertion(groupdialog, group, tagservice)); QVERIFY(!checkObjectInsertion(groupdialog, group, userservice)); QPushButton *newButton = mw->findChild( "w_ObjectGroupDialog")->findChild("newButton"); QVERIFY(newButton != NULL); QTimer::singleShot(50, this, SLOT(checkObjectGroupMenu())); QTest::mouseClick(newButton, Qt::LeftButton); } void GroupObjectDialogTest::checkObjectGroupMenu() { QMenu *menu = mw->findChild("w_ObjectGroupDialog")->findChild("GroupObjectDialog_newObjectMenu"); QList names; names << (QString("newObject_") + Host::TYPENAME) << (QString("newObject_") + Firewall::TYPENAME) << (QString("newObject_") + Cluster::TYPENAME) << (QString("newObject_") + Network::TYPENAME) << (QString("newObject_") + NetworkIPv6::TYPENAME) << (QString("newObject_") + IPv4::TYPENAME) << (QString("newObject_") + IPv6::TYPENAME) << (QString("newObject_") + DNSName::TYPENAME) << (QString("newObject_") + AddressRange::TYPENAME) << (QString("newObject_") + AddressTable::TYPENAME); QList menuNames; foreach(QAction *act, menu->actions()) menuNames.append(act->objectName()); QVERIFY(menuNames.size() == names.size()); foreach(QString name, names) QVERIFY(menuNames.contains(name)); menu->close(); } void GroupObjectDialogTest::checkObjectServiceGroupMenu() { QMenu *menu = mw->findChild("w_ServiceGroupDialog")->findChild("GroupObjectDialog_newObjectMenu"); QList names; names << (QString("newObject_") + IPService::TYPENAME) << (QString("newObject_") + ICMPService::TYPENAME) << (QString("newObject_") + ICMP6Service::TYPENAME) << (QString("newObject_") + TCPService::TYPENAME) << (QString("newObject_") + UDPService::TYPENAME) << (QString("newObject_") + CustomService::TYPENAME) << (QString("newObject_") + TagService::TYPENAME) << (QString("newObject_") + UserService::TYPENAME); QList menuNames; foreach(QAction *act, menu->actions()) menuNames.append(act->objectName()); QVERIFY(menuNames.size() == names.size()); foreach(QString name, names) QVERIFY(menuNames.contains(name)); menu->close(); } void GroupObjectDialogTest::testServiceGroup() { ObjectTreeViewItem *groupItem = dynamic_cast( mw->getCurrentObjectTree()->findItems( "Service Group", Qt::MatchRecursive, 0).first()); mw->getCurrentObjectTree()->setCurrentItem( groupItem, 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear); QVERIFY(groupItem != NULL); ServiceGroup *group = ServiceGroup::cast(groupItem->getFWObject()); QVERIFY(group != NULL); om->editObject(group); QTest::qWait(50); GroupObjectDialog *groupdialog = mw->findChild( "w_ServiceGroupDialog"); QVERIFY(groupdialog != NULL); QVERIFY(!checkObjectInsertion(groupdialog, group, address)); QVERIFY(!checkObjectInsertion(groupdialog, group, address6)); QVERIFY(!checkObjectInsertion(groupdialog, group, network)); QVERIFY(!checkObjectInsertion(groupdialog, group, network6)); QVERIFY(!checkObjectInsertion(groupdialog, group, range)); QVERIFY(!checkObjectInsertion(groupdialog, group, table)); QVERIFY(!checkObjectInsertion(groupdialog, group, dns)); QVERIFY(checkObjectInsertion(groupdialog, group, group)); FWObject *objGroup = dynamic_cast(mw->getCurrentObjectTree()->findItems("Object Group", Qt::MatchRecursive, 0).first())->getFWObject(); QVERIFY(!checkObjectInsertion(groupdialog, group, objGroup)); QVERIFY(checkObjectInsertion(groupdialog, group, ipservice)); QVERIFY(checkObjectInsertion(groupdialog, group, icmpservice)); QVERIFY(checkObjectInsertion(groupdialog, group, udpservice)); QVERIFY(checkObjectInsertion(groupdialog, group, tcpservice)); QVERIFY(checkObjectInsertion(groupdialog, group, tagservice)); QVERIFY(checkObjectInsertion(groupdialog, group, userservice)); QPushButton *newButton = mw->findChild("w_ServiceGroupDialog")->findChild("newButton"); QVERIFY(newButton != NULL); QTimer::singleShot(50, this, SLOT(checkObjectServiceGroupMenu())); QTest::mouseClick(newButton, Qt::LeftButton); } fwbuilder-5.1.0.3599/src/unit_tests/GroupObjectDialogTest/GroupObjectDialogTest.h0000644000175000017500000000514211733011756030547 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: GroupObjectDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IPDIALOGTEST_H #define IPDIALOGTEST_H #include #include "fwbuilder/Library.h" #include "ObjectManipulator.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/CustomService.h" class GroupObjectDialogTest : public QObject { Q_OBJECT; libfwbuilder::Library* findUserLibrary(); template FWTYPE* createObject(QString name); ObjectManipulator *om; libfwbuilder::IPv4 *address; libfwbuilder::IPv6 *address6; libfwbuilder::Network *network; libfwbuilder::NetworkIPv6 *network6; libfwbuilder::AddressRange *range; libfwbuilder::AddressTable *table; libfwbuilder::DNSName *dns; libfwbuilder::IPService *ipservice; libfwbuilder::ICMPService *icmpservice; libfwbuilder::UDPService *udpservice; libfwbuilder::TCPService *tcpservice; libfwbuilder::TagService *tagservice; libfwbuilder::UserService *userservice; private slots: void initTestCase(); void testObjectGroup(); void testServiceGroup(); public slots: void checkMessageBox(); void checkNoMessageBox(); void checkObjectGroupMenu(); void checkObjectServiceGroupMenu(); }; #endif // IPDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/GroupObjectDialogTest/main_GroupObjectDialogTest.cpp0000644000175000017500000000332011733011756032102 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_GroupObjectDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "GroupObjectDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new GroupObjectDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/GroupObjectDialogTest/GroupObjectDialogTest.pro0000644000175000017500000000030411733011756031113 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = GroupObjectDialogTest SOURCES += main_GroupObjectDialogTest.cpp \ GroupObjectDialogTest.cpp HEADERS += GroupObjectDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/UsageResolverTest/0000755000175000017500000000000011733011756023414 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/UsageResolverTest/UsageResolverTest.h0000644000175000017500000000356311733011756027222 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWOBJECTDATABASETEST_H #define FWOBJECTDATABASETEST_H #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Address.h" #include "fwbuilder/Library.h" #include "FWBTree.h" #include class UsageResolverTest : public CppUnit::TestFixture { void addToLib(libfwbuilder::FWObject* obj); public: libfwbuilder::FWObjectDatabase *db; libfwbuilder::Library *lib; libfwbuilder::IPv4 *addr1; libfwbuilder::IPv4 *addr2; libfwbuilder::IPv4 *addr3; libfwbuilder::PolicyRule *r1, *r2, *r3, *r4; void setUp(); void findWhereObjectIsUsed(); void findFirewallsForObject(); void humanizeSearchResults(); CPPUNIT_TEST_SUITE(UsageResolverTest); CPPUNIT_TEST(findWhereObjectIsUsed); CPPUNIT_TEST(findFirewallsForObject); CPPUNIT_TEST(humanizeSearchResults); CPPUNIT_TEST_SUITE_END(); }; #endif // FWOBJECTDATABASETEST_H fwbuilder-5.1.0.3599/src/unit_tests/UsageResolverTest/UsageResolverTest.cpp0000644000175000017500000001734011733011756027553 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UsageResolverTest.h" #include "UsageResolver.h" #include #include using namespace std; using namespace libfwbuilder; void UsageResolverTest::addToLib(FWObject* obj) { FWBTree().getStandardSlotForObject(lib, obj->getTypeName().c_str())->add(obj); } void UsageResolverTest::setUp() { db = new FWObjectDatabase(); db->setName("Database"); lib = Library::cast(FWBTree().createNewLibrary(db)); lib->setName("Library"); Firewall *fw1 = Firewall::cast(db->create(Firewall::TYPENAME)); Firewall *fw2 = Firewall::cast(db->create(Firewall::TYPENAME)); Firewall *fw3 = Firewall::cast(db->create(Firewall::TYPENAME)); Firewall *fw4 = Firewall::cast(db->create(Firewall::TYPENAME)); fw1->setName("Firewall 1"); fw2->setName("Firewall 2"); fw3->setName("Firewall 3"); fw4->setName("Firewall 4"); addToLib(fw1); addToLib(fw2); addToLib(fw3); addToLib(fw4); addr1 = IPv4::cast(db->create(IPv4::TYPENAME)); addr2 = IPv4::cast(db->create(IPv4::TYPENAME)); addr3 = IPv4::cast(db->create(IPv4::TYPENAME)); addr1->setName("Address 1"); addr2->setName("Address 2"); addr3->setName("Address 3"); addToLib(addr1); addToLib(addr2); addToLib(addr3); FWObject *grp1 = db->create(ObjectGroup::TYPENAME); FWObject *grp2 = db->create(ObjectGroup::TYPENAME); FWObject *grp3 = db->create(ObjectGroup::TYPENAME); grp1->setName("Group 1"); grp2->setName("Group 2"); grp3->setName("Group 3"); addToLib(grp1); addToLib(grp2); addToLib(grp3); // addr1 belongs to grp1 // addr2 belongs to grp2 // grp1 belongs to grp2 grp1->addRef(addr1); grp2->addRef(addr2); grp2->addRef(grp1); grp3->addRef(grp2); Policy *policy = fw1->getPolicy(); PolicyRule *rule; rule = PolicyRule::cast(policy->createRule()); rule->setName("PolicyRule 1 of Firewall 1"); rule->getSrc()->addRef(addr1); policy->add(rule); rule = PolicyRule::cast(policy->createRule()); rule->setName("PolicyRule 2 of Firewall 1"); rule->getSrc()->addRef(grp1); policy->add(rule); rule = PolicyRule::cast(policy->createRule()); rule->setName("PolicyRule 3 of Firewall 1"); rule->getSrc()->addRef(grp2); policy->add(rule); /* * Branches: * * fw4 rule1 --> fw3 Policy * fw3 rule2 --> fw2 Policy * fw3 rule3 --> fw4 Policy (circular) * * object addr3 is used in rule 1 of fw2. */ rule = PolicyRule::cast(fw2->getPolicy()->createRule()); rule->setName("PolicyRule 1 of Firewall 2"); rule->getSrc()->addRef(addr2); rule->getDst()->addRef(addr3); fw2->getPolicy()->add(rule); rule = PolicyRule::cast(fw3->getPolicy()->createRule()); rule->setName("PolicyRule 1 of Firewall 3"); rule->getSrc()->addRef(grp3); fw3->getPolicy()->add(rule); rule = PolicyRule::cast(fw3->getPolicy()->createRule()); rule->setName("PolicyRule 2 of Firewall 3"); rule->setAction(PolicyRule::Branch); rule->setBranch(fw2->getPolicy()); fw3->getPolicy()->add(rule); rule = PolicyRule::cast(fw4->getPolicy()->createRule()); rule->setName("PolicyRule 1 of Firewall 4"); rule->setAction(PolicyRule::Branch); rule->setBranch(fw3->getPolicy()); fw4->getPolicy()->add(rule); rule = PolicyRule::cast(fw3->getPolicy()->createRule()); rule->setName("PolicyRule 3 of Firewall 3"); rule->setAction(PolicyRule::Branch); rule->setBranch(fw4->getPolicy()); fw3->getPolicy()->add(rule); } /* * addr1 is found in: * - system group "Addresses" * - group grp1 * - rule 1 of firewall 1 */ void UsageResolverTest::findWhereObjectIsUsed() { // db->dump(true, true); set res; db->findWhereObjectIsUsed(addr1, db, res); CPPUNIT_ASSERT(res.size() == 3); set::iterator iter = res.begin(); while (iter!=res.end()) { FWObject *obj = *iter; string name = obj->getName(); if (FWReference::cast(obj)) { // if we get reference, the parent must be rule element or user group obj = obj->getParent(); CPPUNIT_ASSERT( obj->getTypeName() == RuleElementSrc::TYPENAME || obj->getTypeName() == ObjectGroup::TYPENAME); if (RuleElementSrc::isA(obj)) { CPPUNIT_ASSERT(obj->getParent()->getName() == "PolicyRule 1 of Firewall 1"); } if (ObjectGroup::isA(obj)) { CPPUNIT_ASSERT(obj->getName() == "Group 1"); } } else { // otherwise we should get system folder "Addresses" CPPUNIT_ASSERT(name == "Addresses" ); } iter++; } qDebug() << "test FWObjectDatabase::findWhereObjectIsUsed done"; qDebug() << ""; } void UsageResolverTest::findFirewallsForObject() { qDebug() << "Dependencies for addr1:"; list res = UsageResolver().findFirewallsForObject(addr1, db); list::iterator iter = res.begin(); CPPUNIT_ASSERT(res.size() == 3); while (iter!=res.end()) { string name = (*iter)->getName(); qDebug() << name.c_str() << "' (" << (*iter)->getTypeName().c_str() << ")"; CPPUNIT_ASSERT ( name == "Firewall 1" || name == "Firewall 3" || name == "Firewall 4" ); iter++; } qDebug() << "Dependencies for addr2:"; res = UsageResolver().findFirewallsForObject(addr2, db); iter = res.begin(); CPPUNIT_ASSERT(res.size() == 4); while (iter!=res.end()) { string name = (*iter)->getName(); qDebug() << name.c_str() << "' (" << (*iter)->getTypeName().c_str() << ")"; CPPUNIT_ASSERT ( name == "Firewall 1" || name == "Firewall 2" || name == "Firewall 3" || name == "Firewall 4"); iter++; } //fwbdebug = 1; qDebug() << "Dependencies for addr3:"; res = UsageResolver().findFirewallsForObject(addr3, db); iter = res.begin(); //CPPUNIT_ASSERT(res.size() == 3); while (iter!=res.end()) { string name = (*iter)->getName(); qDebug() << name.c_str() << "' (" << (*iter)->getTypeName().c_str() << ")"; CPPUNIT_ASSERT ( name == "Firewall 2" || name == "Firewall 3" || name == "Firewall 4" ); iter++; } } void UsageResolverTest::humanizeSearchResults() { set res; db->findWhereObjectIsUsed(addr1, db, res); UsageResolver().humanizeSearchResults(res); set::iterator iter = res.begin(); while (iter!=res.end()) { string name = (*iter)->getName(); string type = (*iter)->getTypeName(); if (type == "ObjectRef") { FWObjectReference *o = FWObjectReference::cast(*iter); CPPUNIT_ASSERT(o->getPointer()->getName() == "Address 1"); } else { CPPUNIT_ASSERT ( name == "Group 1" || name == "Addresses"); } iter++; } } fwbuilder-5.1.0.3599/src/unit_tests/UsageResolverTest/main_UsageResolverTest.cpp0000644000175000017500000000245111733011756030554 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "UsageResolverTest.h" #include int fwbdebug = 0; QString user_name; int main( int, char** ) { CppUnit::TextUi::TestRunner runner; runner.addTest( UsageResolverTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/UsageResolverTest/UsageResolverTest.pro0000644000175000017500000000025411733011756027565 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network TARGET = UsageResolverTest SOURCES += main_UsageResolverTest.cpp \ UsageResolverTest.cpp HEADERS += UsageResolverTest.h fwbuilder-5.1.0.3599/src/unit_tests/NetworkDialogTest/0000755000175000017500000000000011733011756023377 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/NetworkDialogTest/NetworkDialogTest.cpp0000644000175000017500000002141511733011756027517 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: NetworkDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NetworkDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "NetworkDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; void NetworkDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); QTest::qWait(1000); } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void NetworkDialogTest::checkMessageBox() { QVERIFY(app->activeModalWidget()->metaObject()->className() == QMessageBox().metaObject()->className()); QTimer::singleShot(10, app->activeModalWidget(), SLOT(reject())); QVERIFY(dynamic_cast(app->activeModalWidget())->text().contains("300.300.300.300") || dynamic_cast(app->activeModalWidget())->text().contains("foo:345:1") || dynamic_cast(app->activeModalWidget())->text().contains("145") || dynamic_cast(app->activeModalWidget())->text().contains("300") || dynamic_cast(app->activeModalWidget())->text().contains("0") || dynamic_cast(app->activeModalWidget())->text().contains("0.0.0.0") || dynamic_cast(app->activeModalWidget())->text().contains("255.300.300.0") ); } void NetworkDialogTest::checkNoMessageBox() { foreach(QWidget *w, app->topLevelWidgets()) QVERIFY(w->metaObject()->className() != QMessageBox().metaObject()->className()); } void setLineEditText(QLineEdit *line, QString text) { line->clear(); QTest::keyClicks(line, text); QTest::keyClick(line, Qt::Key_Enter); } Library* NetworkDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void NetworkDialogTest::testNetwork4Dialog() { ObjectManipulator *om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); Library *lib = findUserLibrary(); Network *obj = Network::cast(om->createObject(FWBTree().getStandardSlotForObject(lib, Network::TYPENAME), Network::TYPENAME, "testNetwork")); QTest::qWait(100); om->editObject(obj); QLineEdit *name, *addr, *mask; TextEditWidget *comment; QWidget *ipv4dialog = mw->findChild("w_NetworkDialog"); name = ipv4dialog->findChild("obj_name"); addr = ipv4dialog->findChild("address"); mask = ipv4dialog->findChild("netmask"); comment = ipv4dialog->parent()->findChild("comment"); // test1 qDebug() << "test1"; QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(name, "testNetwork"); QTest::qWait(300); QVERIFY (obj->getName() == "testNetwork"); QTest::qWait(100); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (obj->getComment() == "Test comment"); //test2 qDebug() << "test2"; QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(addr, "192.0.2.1"); QTest::qWait(300); QVERIFY (obj->getAddressPtr()->toString() == "192.0.2.1"); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(addr, "300.300.300.300"); QTest::qWait(400); QVERIFY (obj->getAddressPtr()->toString() == "192.0.2.1"); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(mask, "255.255.0.0"); QTest::qWait(300); QVERIFY (obj->getNetmaskPtr()->toString() == "255.255.0.0"); //test3 qDebug() << "test3"; QTest::qWait(100); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(mask, "300.300.300.300"); QTest::qWait(400); QVERIFY (obj->getNetmaskPtr()->toString() == "255.255.0.0"); //test4 qDebug() << "test4"; QTest::qWait(100); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(mask, "255.300.300.0"); QTest::qWait(400); QVERIFY (obj->getNetmaskPtr()->toString() == "255.255.0.0"); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(mask, "0.0.0.0"); QTest::qWait(500); QVERIFY (obj->getNetmaskPtr()->toString() == "255.255.0.0"); } void NetworkDialogTest::testNetwork6Dialog() { ObjectManipulator *om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); Library *lib = findUserLibrary(); QLineEdit *name, *addr, *mask; TextEditWidget *comment; QWidget *ipv6dialog = mw->findChild("w_NetworkDialogIPv6"); name = ipv6dialog->findChild("obj_name"); addr = ipv6dialog->findChild("address"); mask = ipv6dialog->findChild("netmask"); comment = ipv6dialog->parent()->findChild("comment"); //test5 qDebug() << "test5"; NetworkIPv6 *obj = NetworkIPv6::cast(om->createObject(FWBTree().getStandardSlotForObject(lib, NetworkIPv6::TYPENAME), NetworkIPv6::TYPENAME, "testNetworkIPv6")); om->editObject(obj); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(name, "testNetworkIPv6"); QTest::qWait(300); QVERIFY (obj->getName() == "testNetworkIPv6"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (obj->getComment() == "Test comment"); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(addr, "2001:db8::"); QTest::qWait(300); QVERIFY (obj->getAddressPtr()->toString() == "2001:db8::"); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(mask, "120"); QTest::qWait(300); QVERIFY (obj->getNetmaskPtr()->toString() == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); //test6 qDebug() << "test6"; QTimer::singleShot(200, this, SLOT(checkMessageBox())); setLineEditText(addr, "foo:345:1"); QTest::qWait(300); QVERIFY (obj->getAddressPtr()->toString() == "2001:db8::"); //test7 qDebug() << "test7"; QTimer::singleShot(200, this, SLOT(checkMessageBox())); setLineEditText(mask, "300"); QTest::qWait(300); QVERIFY (obj->getNetmaskPtr()->toString() == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); QTimer::singleShot(200, this, SLOT(checkMessageBox())); setLineEditText(mask, "0"); QTest::qWait(300); QVERIFY (obj->getNetmaskPtr()->toString() == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); QTest::qWait(1000); } fwbuilder-5.1.0.3599/src/unit_tests/NetworkDialogTest/main_NetworkDialogTest.cpp0000644000175000017500000000330311733011756030517 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_NetworkDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NetworkDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new NetworkDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/NetworkDialogTest/NetworkDialogTest.pro0000644000175000017500000000026511733011756027535 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = NetworkDialogTests SOURCES += main_NetworkDialogTest.cpp \ NetworkDialogTest.cpp HEADERS += NetworkDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/NetworkDialogTest/NetworkDialogTest.h0000644000175000017500000000243711733011756027167 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: NetworkDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IPDIALOGTEST_H #define IPDIALOGTEST_H #include #include "fwbuilder/Library.h" class NetworkDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); private slots: void initTestCase(); void testNetwork4Dialog(); void testNetwork6Dialog(); public slots: void checkMessageBox(); void checkNoMessageBox(); }; #endif // IPDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogCompileTest/0000755000175000017500000000000011733011756024234 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/instDialogCompileTest/instDialogCompileTest.h0000644000175000017500000000320511733011756030653 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogCompileTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include "newClusterDialog.h" #include "upgradePredicate.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "instDialog.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" class instDialogCompileTest : public QObject { Q_OBJECT private slots: void initTestCase(); void testSelectButtonsVisibility(); void testCompile(); public slots: void closeContextMenu(); void openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogCompileTest/test.fwb0000644000175000017500000045146311733011756025730 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/instDialogCompileTest/instDialogCompileTest.cpp0000644000175000017500000002264011733011756031212 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogCompileTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ================================ Ticket 1357: before running the test check if files "test1.fw", "test2.fw", "test3.fw", "test4.fw" exist and delete them if they are there. If delete operation fails for any reason, fail the test click on the toolbar button "Compile" click "CompileALL" click "Next" let it run until it is done check that status in the list in the column on the left is "Success" for all objects: cluster1, test1 and test2 check that it produced files "test1.fw", "test2.fw", "test3.fw", "test4.fw" check that each of these files has non-zero length */ #include "instDialogCompileTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include "FWObjectClipboard.h" #include "FWBApplication.h" using namespace std; using namespace QTest; using namespace libfwbuilder; void instDialogCompileTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->loadFile("test_work.fwb", false); } bool checkProgress(QTreeWidget *list) { for(int i=0; itopLevelItemCount(); i++) { if ( (list->topLevelItem(i)->text(1).toStdString() == "Compiling ...") || (list->topLevelItem(i)->text(1).toStdString() == "Installing ...") ) return false; } return true; } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { QRect rect = tree->visualItemRect(item); return QPoint(rect.x() + 1, rect.y() + 1); } void instDialogCompileTest::closeContextMenu() { QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } menu->hide(); } /* * This function finds and activates an item with given name in the * context menu. If item is absent in the menu or is disabled, it * fails the test. */ void instDialogCompileTest::openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText) { QTimer::singleShot(100, this, SLOT(closeContextMenu())); om->contextMenuRequested(findItemPos(item, tree)); bool found_menu_item = false; QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } QVERIFY(menu != NULL); foreach (QObject *act, menu->children()) { QAction *action = dynamic_cast(act); if (action == NULL) continue; if (action->text() == actionText) { QVERIFY(action->isEnabled() == true); action->activate(QAction::Trigger); found_menu_item = true; break; } } QVERIFY2(found_menu_item == true, QString("Item %1 not found in the context menu").arg(actionText).toAscii().constData()); } void instDialogCompileTest::testSelectButtonsVisibility() { ObjectManipulator *om = mw->activeProject()->findChild("om"); ObjectTreeView *tree = om->getCurrentObjectTree(); tree->expandAll(); ObjectTreeViewItem *test1 = dynamic_cast(tree->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *test2 = dynamic_cast(tree->findItems("test2", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *cluster1 = dynamic_cast(tree->findItems("cluster1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); // case when compiling only one firewall: buttons should not be visible tree->clearSelection(); tree->scrollToItem(test1); test1->setSelected(true); tree->setCurrentItem(test1); //QTest::qWait(2000); openContextMenu(om, test1, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QFrame *selectFrame = dlg->findChild("selectAllNoneFrame"); QTest::qWait(1000); QVERIFY(selectFrame->isHidden()); dlg->reject(); // case when compiling more than one firewall: button should be visible tree->clearSelection(); tree->scrollToItem(test1); test1->setSelected(true); tree->setCurrentItem(test1); test2->setSelected(true); openContextMenu(om, test1, tree, "Compile"); //QTest::qWait(2000); QTest::qWait(1000); QVERIFY(!selectFrame->isHidden()); dlg->reject(); // case when compiling cluster: buttons should be visible tree->clearSelection(); tree->scrollToItem(cluster1); cluster1->setSelected(true); tree->setCurrentItem(cluster1); openContextMenu(om, cluster1, tree, "Compile"); QTest::qWait(1000); QVERIFY(!selectFrame->isHidden()); dlg->reject(); // case when compiling one firewall and one cluster: buttons should be visible tree->clearSelection(); tree->scrollToItem(cluster1); cluster1->setSelected(true); tree->setCurrentItem(cluster1); test2->setSelected(true); openContextMenu(om, cluster1, tree, "Compile"); QTest::qWait(1000); QVERIFY(!selectFrame->isHidden()); dlg->reject(); } void instDialogCompileTest::testCompile() { if (QFileInfo("test1.fw").exists()) QVERIFY(QFile("test1.fw").remove()); if (QFileInfo("test2.fw").exists()) QVERIFY(QFile("test2.fw").remove()); if (QFileInfo("test3.fw").exists()) QVERIFY(QFile("test3.fw").remove()); if (QFileInfo("test4.fw").exists()) QVERIFY(QFile("test4.fw").remove()); if (QFileInfo("pf firewall.fw").exists()) QVERIFY(QFile("pf firewall.fw").remove()); if (QFileInfo("ipfilter firewall.fw").exists()) QVERIFY(QFile("ipfilter firewall.fw").remove()); mw->findChild("compileAction")->trigger(); instDialog *dlg = mw->findChild(); dlg->findChild("pushButton16")->click(); dlg->findChild("nextButton")->click(); QTreeWidget *list = dlg->findChild("fwWorkList"); QPushButton *back = dlg->findChild("backButton"); QPushButton *next = dlg->findChild("nextButton"); QPushButton *finish = dlg->findChild("finishButton"); QPushButton *cancel = dlg->findChild("cancelButton"); int waited = 0; while (!checkProgress(list)) { // test state of the buttons QVERIFY(back->isEnabled() == true); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY(finish->isEnabled() == false); QTest::qWait(500); waited += 500; QVERIFY(waited < 10000); } for(int i=0; itopLevelItemCount(); i++) { QVERIFY(list->topLevelItem(i)->text(1) == "Success"); } // test state of the buttons QVERIFY(back->isEnabled() == true); QVERIFY(next->isEnabled() == false); QVERIFY(cancel->isEnabled() == true); QVERIFY(finish->isEnabled() == true); dlg->reject(); QVERIFY(QFileInfo("test1.fw").exists() && QFileInfo("test1.fw").size()); QVERIFY(QFileInfo("test2.fw").exists() && QFileInfo("test2.fw").size()); QVERIFY(QFileInfo("test3.fw").exists() && QFileInfo("test3.fw").size()); QVERIFY(QFileInfo("test4.fw").exists() && QFileInfo("test4.fw").size()); QVERIFY(QFileInfo("pf firewall.fw").exists() && QFileInfo("pf firewall.conf").exists() && QFileInfo("pf firewall.fw").size() && QFileInfo("pf firewall.conf").size()); QVERIFY(QFileInfo("ipfilter firewall.fw").exists() && QFileInfo("ipfilter firewall-ipf.conf").exists() && QFileInfo("ipfilter firewall-nat.conf").exists() && QFileInfo("ipfilter firewall.fw").size() && QFileInfo("ipfilter firewall-ipf.conf").size() && QFileInfo("ipfilter firewall-nat.conf").size()); QFile::remove("test1.fw"); QFile::remove("test2.fw"); QFile::remove("test3.fw"); QFile::remove("test4.fw"); QFile::remove("pf firewall.fw"); QFile::remove("pf firewall.conf"); QFile::remove("ipfilter firewall.fw"); QFile::remove("ipfilter firewall-ipf.conf"); QFile::remove("ipfilter firewall-nat.conf"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogCompileTest/main_instDialogCompileTest.cpp0000644000175000017500000000331111733011756032210 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "instDialogCompileTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new instDialogCompileTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogCompileTest/instDialogCompileTest.pro0000644000175000017500000000050711733011756031226 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = instDialogCompileTest SOURCES += main_instDialogCompileTest.cpp \ instDialogCompileTest.cpp HEADERS += instDialogCompileTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/0000755000175000017500000000000011733011756024362 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/generatedScriptTestsPF.pro0000644000175000017500000000056711733011756031510 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS = generatedScriptTestsPF.h SOURCES = main_generatedScriptTestsPF.cpp \ generatedScriptTestsPF.cpp TARGET = generatedScriptTestsPF run_tests.commands = echo "Running tests..." && \ rm -f *.fw *.conf tmp/*.fw tmp/*.conf && \ mkdir -p tmp && \ ./${TARGET} && \ echo "OK" || { echo "FAILED"; exit 1; } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/.gitignore0000644000175000017500000000000711733011756026347 0ustar sylvestresylvestreipf2-1 fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/generatedScriptTestsPF.cpp0000644000175000017500000003405311733011756031467 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsPF.h" #include "CompilerDriver_pf.h" #include "Configlet.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; void GeneratedScriptTest::setUp() { Configlet::setDebugging(true); } void GeneratedScriptTest::tearDown() { } void GeneratedScriptTest::loadDataFile(const string &file_name) { /* load the data file */ UpgradePredicate upgrade_predicate; objdb->setReadOnly( false ); objdb->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(file_name); objdb->reIndex(); } void GeneratedScriptTest::runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name, const std::string &output_file_option) { loadDataFile(test_file); QStringList args; if (!output_file_option.empty()) { args << "-o" << output_file_option.c_str(); } args << firewall_object_name.c_str(); CompilerDriver_pf driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_pf initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file generate_file_name QFileInfo fi(generate_file_name.c_str()); CPPUNIT_ASSERT_MESSAGE("Generated file " + generate_file_name + " not found", fi.exists() == true); } // I can check only certain parts of the top comment. Can't // compare against "golden" file because some parts of the comment // are variable, such as date, version and build number void GeneratedScriptTest::ManifestTest_1() { QFile::remove("pf1.fw"); QFile::remove("pf1.conf"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf1", "pf1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "pf1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * pf1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: pf1.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_2() { /* * output script name is set to ipf2-1.fw in the fw object and * conf file name is set to ipf2-1.conf */ QFile::remove("ipf2-1.fw"); QFile::remove("ipf2-1.conf"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf2", "ipf2-1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf2-1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_3() { /* * output script name is set to "ipf2-1" in the fw object (no .fw * extension) and conf file name is set to ipf2-1.conf */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf2a", "ipf2-1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf2-1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_4() { /* * Compile pf2 and pf2a adding "-o" option as instDialog * does. This oevverides .fw file name but does not override .conf * file name */ objdb = new FWObjectDatabase(); QString option_o = QDir::currentPath() + "/pf2-1.fw"; runCompiler("test1.fwb", "pf2", "pf2-1.fw", option_o.toStdString()); QString res = Configlet::findConfigletInFile("top_comment", "pf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + option_o) != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_5() { objdb = new FWObjectDatabase(); QString option_o = QDir::currentPath() + "/pf2-1"; runCompiler("test1.fwb", "pf2a", "pf2-1.fw", option_o.toStdString()); QString res = Configlet::findConfigletInFile("top_comment", "pf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf2-1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_6() { /* * remote pf file is configured as /etc/fw/pf3.conf in pf3 */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf3", "pf3.fw"); QString res = Configlet::findConfigletInFile("top_comment", "pf3.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * pf3.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: pf3.conf /etc/fw/pf3.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_7() { /* * remote pf and nat files in pf4 have spaces in the path */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf4", "pf4.fw"); QString res = Configlet::findConfigletInFile("top_comment", "pf4.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * pf4.fw /etc/path\\ with\\ space/pf4.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: pf4.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_8() { /* * generated .fw and .conf files have different base names */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf5", "pf5.fw"); QString res = Configlet::findConfigletInFile("top_comment", "pf5.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * pf5.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: pf5.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_9() { /* * generated .fw and .conf files have different base names */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf6", "/tmp/pf6.fw"); QString res = Configlet::findConfigletInFile("top_comment", "/tmp/pf6.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * /tmp/pf6.fw /etc/fw/pf6.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: /tmp/pf6.conf /etc/pf.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_10() { /* * generated .fw and .conf files have different base names */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf7", "tmp/pf7.fw"); QString res = Configlet::findConfigletInFile("top_comment", "tmp/pf7.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * tmp/pf7.fw /etc/fw/pf7.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: tmp/pf.conf /etc/pf.conf") != -1); delete objdb; } /* * pf8 has an achor and compiler generates two .conf files. The name * of the second file is derived from the name of the main .conf file * that is is set in fw options */ void GeneratedScriptTest::ManifestTest_11() { /* * generated .fw and .conf files have different base names */ if (QFile::exists("tmp/pf8.fw")) QFile::remove("tmp/pf8.fw"); if (QFile::exists("tmp/pf.conf")) QFile::remove("tmp/pf.conf"); if (QFile::exists("tmp/pf-anchor_1.conf")) QFile::remove("tmp/pf-anchor_1.conf"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf8", "tmp/pf8.fw"); QString res = Configlet::findConfigletInFile("top_comment", "tmp/pf8.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * tmp/pf8.fw /etc/fw/pf8.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: tmp/pf.conf /etc/pf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: tmp/pf-anchor_1.conf /etc/pf-anchor_1.conf") != -1); delete objdb; } /* * pf9 has an achor and compiler generates two .conf files. Names for * all generated files are constructed using firewall name and default * algorithm */ void GeneratedScriptTest::ManifestTest_12() { /* * generated .fw and .conf files have different base names */ if (QFile::exists("pf9.fw")) QFile::remove("pf9.fw"); if (QFile::exists("pf9.conf")) QFile::remove("pf9.conf"); if (QFile::exists("pf9-anchor_1.conf")) QFile::remove("pf9-anchor_1.conf"); objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf9", "pf9.fw"); QString res = Configlet::findConfigletInFile("top_comment", "pf9.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * pf9.fw /etc/pf9.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: pf9.conf /etc/pf9.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: pf9-anchor_1.conf /etc/pf9-anchor_1.conf") != -1); delete objdb; } // ************************************************************************ void GeneratedScriptTest::FwCommentTest() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "pf1", "pf1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "pf1.fw"); // find string from the firewall object comment and compare CPPUNIT_ASSERT(res.indexOf("# Firewall object test1 comment") != -1); delete objdb; } // ************************************************************************ // // $PFCTL \ // -f \ // ${FWDIR}/pf1.conf || exit 1 void GeneratedScriptTest::ActivationCommandsTest_1() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "pf1.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf1.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_2() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf2-1.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_3() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf2-1.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_4() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "pf2-1.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/ipf2-1.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_6() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "pf3.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/fw/pf3.conf") != -1); delete objdb; } /* * object pf4 defines remote name for the .fw file but does not define * remote name for the .conf file. The latter is determined by * default, by combining local file name with directory defined in * firewall_dir option (in the tab "Installer") */ void GeneratedScriptTest::ActivationCommandsTest_7() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "pf4.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf4.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_8() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "pf5.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf5.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_9() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "/tmp/pf6.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_10() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "tmp/pf7.fw") .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_11() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "tmp/pf8.fw", 1) .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_12() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "pf9.fw", 1) .split(QRegExp("\\s+")).join(" "); CPPUNIT_ASSERT(res.indexOf("$PFCTL -f /etc/pf9.conf") != -1); delete objdb; } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/test1.fwb0000644000175000017500000047463511733011756026145 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/main_generatedScriptTestsPF.cpp0000644000175000017500000000343311733011756032471 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsPF.h" #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include "../../../common/init.cpp" using namespace std; using namespace libfwbuilder; int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( GeneratedScriptTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsPF/generatedScriptTestsPF.h0000644000175000017500000000710411733011756031131 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GENERATEDSCRIPTTESTS_IPFILTER_H #define GENERATEDSCRIPTTESTS_IPFILTER_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include class GeneratedScriptTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *objdb; void loadDataFile(const std::string &file_name); void runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name, const std::string &output_file_option=""); public: void setUp(); void tearDown(); void ManifestTest_1(); void ManifestTest_2(); void ManifestTest_3(); void ManifestTest_4(); void ManifestTest_5(); void ManifestTest_6(); void ManifestTest_7(); void ManifestTest_8(); void ManifestTest_9(); void ManifestTest_10(); void ManifestTest_11(); void ManifestTest_12(); void FwCommentTest(); void ActivationCommandsTest_1(); void ActivationCommandsTest_2(); void ActivationCommandsTest_3(); void ActivationCommandsTest_4(); // void ActivationCommandsTest_5(); void ActivationCommandsTest_6(); void ActivationCommandsTest_7(); void ActivationCommandsTest_8(); void ActivationCommandsTest_9(); void ActivationCommandsTest_10(); void ActivationCommandsTest_11(); void ActivationCommandsTest_12(); CPPUNIT_TEST_SUITE(GeneratedScriptTest); // The order of tests matters because activation commands tests use // files produced in manifest tests CPPUNIT_TEST(ManifestTest_1); CPPUNIT_TEST(ActivationCommandsTest_1); CPPUNIT_TEST(ManifestTest_2); CPPUNIT_TEST(ActivationCommandsTest_2); CPPUNIT_TEST(ManifestTest_3); CPPUNIT_TEST(ActivationCommandsTest_3); CPPUNIT_TEST(ManifestTest_4); CPPUNIT_TEST(ActivationCommandsTest_4); // CPPUNIT_TEST(ManifestTest_5); // CPPUNIT_TEST(ActivationCommandsTest_5); CPPUNIT_TEST(ManifestTest_6); CPPUNIT_TEST(ActivationCommandsTest_6); CPPUNIT_TEST(ManifestTest_7); CPPUNIT_TEST(ActivationCommandsTest_7); CPPUNIT_TEST(ManifestTest_8); CPPUNIT_TEST(ActivationCommandsTest_8); CPPUNIT_TEST(ManifestTest_9); CPPUNIT_TEST(ActivationCommandsTest_9); CPPUNIT_TEST(ManifestTest_10); CPPUNIT_TEST(ActivationCommandsTest_10); CPPUNIT_TEST(ManifestTest_11); CPPUNIT_TEST(ActivationCommandsTest_11); CPPUNIT_TEST(ManifestTest_12); CPPUNIT_TEST(ActivationCommandsTest_12); CPPUNIT_TEST(FwCommentTest); CPPUNIT_TEST_SUITE_END(); }; #endif // GENERATEDSCRIPTTESTS_IPFILTER_H fwbuilder-5.1.0.3599/src/unit_tests/IPDialogTest/0000755000175000017500000000000011733011756022256 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/IPDialogTest/main_IPDialogTest.cpp0000644000175000017500000000326411733011756026263 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "IPDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new IPDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/IPDialogTest/IPDialogTest.h0000644000175000017500000000230111733011756024713 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: IPDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IPDIALOGTEST_H #define IPDIALOGTEST_H #include class IPDialogTest : public QObject { Q_OBJECT private slots: void initTestCase(); void testIPv4Dialog(); void testIPv6Dialog(); public slots: void checkMessageBox(); void checkNoMessageBox(); }; #endif // IPDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/IPDialogTest/IPDialogTest.cpp0000644000175000017500000002164511733011756025262 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "IPDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "IPDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; void IPDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); QTest::qWait(1000); } void IPDialogTest::checkMessageBox() { QVERIFY(app->activeModalWidget()->metaObject()->className() == QMessageBox().metaObject()->className()); QTimer::singleShot(10, app->activeModalWidget(), SLOT(reject())); QVERIFY(dynamic_cast(app->activeModalWidget())->text().contains("300.300.300.300") || dynamic_cast(app->activeModalWidget())->text().contains("foo:345:1") || dynamic_cast(app->activeModalWidget())->text().contains("145") ); } void IPDialogTest::checkNoMessageBox() { foreach(QWidget *w, app->topLevelWidgets()) QVERIFY(w->metaObject()->className() != QMessageBox().metaObject()->className()); } void setLineEditText(QLineEdit *line, QString text) { line->clear(); QTest::keyClicks(line, text); QTest::keyClick(line, Qt::Key_Enter); } void IPDialogTest::testIPv4Dialog() { ObjectManipulator *om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } IPv4 *addrobj = IPv4::cast(om->createObject(FWBTree().getStandardSlotForObject(lib, IPv4::TYPENAME), IPv4::TYPENAME, "testAddress")); QTest::qWait(100); om->editObject(addrobj); QLineEdit *name, *addr, *mask; TextEditWidget *comment; QWidget *ipv4dialog = mw->findChild("w_IPv4Dialog"); name = ipv4dialog->findChild("obj_name"); addr = ipv4dialog->findChild("address"); mask = ipv4dialog->findChild("netmask"); comment = ipv4dialog->parent()->findChild("comment"); // test1 qDebug() << "test1"; QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(name, "testNetwork"); QTest::qWait(300); QVERIFY (addrobj->getName() == "testNetwork"); QTest::qWait(100); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (addrobj->getComment() == "Test comment"); QTest::qWait(100); //test2 qDebug() << "test2"; QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(addr, "192.0.2.1"); QTest::qWait(300); QVERIFY (addrobj->getAddressPtr()->toString() == "192.0.2.1"); //test3 qDebug() << "test3"; QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(addr, "300.300.300.300"); QTest::qWait(400); QVERIFY (addrobj->getAddressPtr()->toString() == "192.0.2.1"); //test4 qDebug() << "test4"; Firewall *fw = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(lib, Firewall::TYPENAME), Firewall::TYPENAME, "newFirewall")); Interface *intf = Interface::cast(om->createObject(fw, Interface::TYPENAME, "newInterface")); IPv4 *addr2obj = IPv4::cast(om->createObject(intf, IPv4::TYPENAME, "newAddress")); QTest::qWait(100); QTest::qWait(500); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(addr, "192.0.2.1"); QTest::qWait(300); QVERIFY (addr2obj->getAddressPtr()->toString() == "192.0.2.1"); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(mask, "255.255.0.0"); QTest::qWait(300); QVERIFY (addr2obj->getNetmaskPtr()->toString() == "255.255.0.0"); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(addr, "300.300.300.300"); QTest::qWait(400); QVERIFY (addr2obj->getAddressPtr()->toString() == "192.0.2.1"); QTest::qWait(100); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(mask, "300.300.300.300"); QTest::qWait(400); QVERIFY (addr2obj->getNetmaskPtr()->toString() == "255.255.0.0"); } void IPDialogTest::testIPv6Dialog() { ObjectManipulator *om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } QLineEdit *name, *addr, *mask; TextEditWidget *comment; QWidget *ipv6dialog = mw->findChild("w_IPv6Dialog"); name = ipv6dialog->findChild("obj_name"); addr = ipv6dialog->findChild("address"); mask = ipv6dialog->findChild("netmask"); comment = ipv6dialog->parent()->findChild("comment"); //test5 qDebug() << "test5"; IPv6 *addrobj = IPv6::cast(om->createObject(FWBTree().getStandardSlotForObject(lib, IPv6::TYPENAME), IPv6::TYPENAME, "testAddress6")); om->editObject(addrobj); setLineEditText(name, "testNetwork6"); QVERIFY (addrobj->getName() == "testNetwork6"); QTest::qWait(300); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (addrobj->getComment() == "Test comment"); QTest::qWait(100); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(addr, "2001:db8:1:1::1"); QTest::qWait(300); QVERIFY (libfwbuilder::IPv6::cast(addrobj)->getAddressPtr()->toString() == "2001:db8:1:1::1"); //test6 qDebug() << "test6"; QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(addr, "foo:345:1"); QTest::qWait(400); QVERIFY (libfwbuilder::IPv6::cast(addrobj)->getAddressPtr()->toString() == "2001:db8:1:1::1"); //test7 qDebug() << "test7"; Interface *intf = Interface::cast(dynamic_cast(mw->getCurrentObjectTree()->findItems("newInterface", Qt::MatchExactly | Qt::MatchRecursive, 0).first())->getFWObject()); IPv6 *addr62obj = IPv6::cast(om->createObject(intf, IPv6::TYPENAME, "newAddress2")); QTest::qWait(100); QTest::qWait(500); setLineEditText(addr, "2001:db8:1:1::1"); QVERIFY (addr62obj->getAddressPtr()->toString() == "2001:db8:1:1::1"); QTimer::singleShot(200, this, SLOT(checkNoMessageBox())); setLineEditText(mask, "120"); QTest::qWait(300); QVERIFY (addr62obj->getNetmaskPtr()->toString() == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(addr, "foo:345:1"); QVERIFY (addr62obj->getAddressPtr()->toString() == "2001:db8:1:1::1"); QTest::qWait(300); QTimer::singleShot(300, this, SLOT(checkMessageBox())); setLineEditText(mask, "145"); QTest::qWait(400); QVERIFY (addr62obj->getNetmaskPtr()->toString() == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); QTest::qWait(100); } fwbuilder-5.1.0.3599/src/unit_tests/IPDialogTest/IPDialogTest.pro0000644000175000017500000000024011733011756025264 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = IPDialogTest SOURCES += main_IPDialogTest.cpp \ IPDialogTest.cpp HEADERS += IPDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/TagServiceDialogTest/0000755000175000017500000000000011733011756024002 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/TagServiceDialogTest/TagServiceDialogTest.cpp0000644000175000017500000000723411733011756030530 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: TagServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "TagServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "TagServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/TagService.h" #include "TagServiceDialog.h" using namespace std; using namespace libfwbuilder; void TagServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* TagServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void TagServiceDialogTest::testDialog() { TagService *service = TagService::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), TagService::TYPENAME), TagService::TYPENAME, "testTagService")); om->editObject(service); TagServiceDialog *dialog = mw->findChild("w_TagServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QLineEdit *tagcode = dialog->findChild("tagcode"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestTagService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestTagService"); tagcode->clear(); QTest::keyClicks(tagcode, "45"); QTest::keyClick(tagcode, Qt::Key_Enter); QVERIFY(service->getCode() == "45"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (service->getComment() == "Test comment"); } fwbuilder-5.1.0.3599/src/unit_tests/TagServiceDialogTest/TagServiceDialogTest.pro0000644000175000017500000000030011733011756030531 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = TagServiceDialogTest SOURCES += main_TagServiceDialogTest.cpp \ TagServiceDialogTest.cpp HEADERS += TagServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/TagServiceDialogTest/main_TagServiceDialogTest.cpp0000644000175000017500000000330511733011756031527 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "TagServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new TagServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/TagServiceDialogTest/TagServiceDialogTest.h0000644000175000017500000000241011733011756030164 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: TagServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef TagServiceDialogTest_H #define TagServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class TagServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testDialog(); }; #endif // TagServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewContextMenuTest/0000755000175000017500000000000011733011756025236 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewContextMenuTest/RuleSetViewContextMenuTest.cpp0000644000175000017500000003715011733011756033220 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: RuleSetViewContextMenuTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RuleSetViewContextMenuTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include #include #include "FWBApplication.h" #include "StartTipDialog.h" #include "QMetaProperty" #include "FWObjectClipboard.h" #include "RuleSetModel.h" using namespace std; using namespace QTest; using namespace libfwbuilder; #define getRuleForPosition( x ) ((RuleSetModel*)view->model())->findRuleForPosition( x ) #define showContextMenu( x ) view->showContextMenu(view->pos() + x); void RuleSetViewContextMenuTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->move(0,0); if (app->desktop()->size().width() < 1024 || app->desktop()->size().height()<768) mw->resize(app->desktop()->size()); else mw->resize(1024, 768); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); firewall = Firewall::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), Firewall::TYPENAME), Firewall::TYPENAME, "testFirewall")); firewall->setStr("platform", "iptables"); openPolicy("testFirewall"); view = mw->findChild(""); om->closeObject(); } /* * Opens Policy of firewall with name fwname in RuleSetView of active project */ void RuleSetViewContextMenuTest::openPolicy(QString fwname) { Policy *p = NULL; foreach (FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == fwname.toStdString()) { p = Firewall::cast(fw)->getPolicy(); } } QVERIFY (p != NULL); QCoreApplication::postEvent(mw, new openRulesetImmediatelyEvent(mw->activeProject()->getFileName(), p->getId())); QTest::qWait(100); } /* * Returns libfwbuilder::Library with name "User" */ Library* RuleSetViewContextMenuTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } /* * Returns menu-relative position of topmost pixel clicking * which will trigger action */ QPoint findActionPos(QMenu *menu, QAction *action) { int x = menu->width()/2; for (int y=0; yheight(); y++) { if (menu->actionAt(QPoint(x,y)) != NULL && menu->actionAt(QPoint(x,y))->text() == action->text()) return QPoint(x,y); } return QPoint(-1,-1); } /* * Clicks item in topmost visible modal context menu. * Should be called right before opening menu (it waits 10 ms for menu to appear). */ void RuleSetViewContextMenuTest::clickMenuItem(QString item) { clicked = false; itemToClick = item; QTimer::singleShot(100, this, SLOT(actuallyClickMenuItem())); } void RuleSetViewContextMenuTest::actuallyClickMenuItem() { QMenu *menu = dynamic_cast(app->activePopupWidget()); Q_ASSERT(menu != NULL); foreach(QAction *action, menu->actions()) { if (action->text() == itemToClick) { //qDebug() << "clicking menu item" << action << action->text(); clicked = true; QPoint pos = findActionPos(menu, action); //qDebug() << pos; //QTest::mouseMove(menu, pos); QTest::mouseClick(menu, Qt::LeftButton, Qt::NoModifier, pos); //action->trigger(); //menu->hide(); return; } } // menu item not found. Include menu items that were actually // present in the menu in the error message to implify debugging QStringList items; foreach(QAction *action, menu->actions()) { items.push_back(QString("\"%1\"").arg(action->text())); } // need to hide the menu, otherwise test just hangs menu->hide(); QFAIL(QString("Menu item %1 not found. Menu consists of: %2") .arg(itemToClick) .arg(items.join(" ")).toAscii().constData()); } /* * Returns topmost pixel which belongs to first cell * of rule in RuleSetView */ QPoint RuleSetViewContextMenuTest::findRulePosition(Rule *rule) { int x = 30; view->scrollTo(((RuleSetModel*)view->model())->index(rule, 0)); for (int y=view->header()->height(); yheight(); y+=5) { Rule *found = ((RuleSetModel*)view->model())->getRule(view->indexAt(QPoint(x,y))); if (found == rule) return QPoint(x,y); } return QPoint(-1,-1); } /* * Returns topmost pixel which belongs to first cell * of row #rule in RuleSetView */ QPoint RuleSetViewContextMenuTest::findRulePosition(int rule) { return findRulePosition(getRuleForPosition(rule)); } /* * Fills group name request modal dialog with group name * and clicks OK. * Should be executed right before opening dialog. */ void RuleSetViewContextMenuTest::createGroup(QString name) { groupToCreate = name; // timeout should be more than clickMenuItem timeout QTimer::singleShot(200, this, SLOT(actuallyCreateGroup())); } void RuleSetViewContextMenuTest::actuallyCreateGroup() { QInputDialog *dlg = dynamic_cast(app->activeModalWidget()); Q_ASSERT(dlg != NULL); QLineEdit *name = dlg->findChild(); QTest::keyClicks(name, groupToCreate); dlg->accept(); } QPoint RuleSetViewContextMenuTest::findCell(Rule *rule, int col) { view->scrollTo(((RuleSetModel*)view->model())->index(rule, col)); for (int x=0; xwidth(); x++) { for(int y=view->height(); y>0; y--) { QModelIndex index = view->indexAt(QPoint(x,y)); Rule *found = ((RuleSetModel*)view->model())->getRule(view->indexAt(QPoint(x,y))); if (found == rule && index.column() == col) return QPoint(x,y); } } return QPoint(-1,-1); } void RuleSetViewContextMenuTest::verifyMenu(int column) { names.clear(); if (column == 0) { names << "New Group" << "Change color" << "Insert New Rule" << "Add New Rule Below" << "Remove Rule" << "Move Rule Up" << "Move Rule Down" << "Copy Rule" << "Cut Rule" << "Paste Rule Above" << "Paste Rule Below" << "Disable Rule" << "Compile rule"; } if (column > 0 && (column < 5 || column == 7)) { names << "Edit" << "Copy" << "Cut" << "Paste" << "Delete"<< "Where used" << "Reveal in tree" << "Negate" << "Compile rule"; } if (column == 5) { names << "Inbound" << "Outbound" << "Both" << "Compile rule"; } if (column == 6) { QMap possibleItems; QStringList order; order << "Accept" << "Deny" << "Reject" << "Accounting" << "Pipe" << "Tag" << "Classify" << "Custom" << "Branch" << "Route" << "Continue"; possibleItems["Accept"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Accept)); possibleItems["Deny"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Deny)); possibleItems["Reject"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Reject)); possibleItems["Accounting"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Accounting)); possibleItems["Pipe"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Pipe)); possibleItems["Custom"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Custom)); possibleItems["Branch"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Branch)); possibleItems["Continue"] = getActionNameForPlatform(firewall, PolicyRule::getActionAsString(PolicyRule::Continue)); string currentPlatform = firewall->getStr("platform"); foreach(QString item, order) if (Resources::isTargetActionSupported(currentPlatform, item.toStdString())) { //qDebug() << item << "is valid for" << currentPlatform.c_str() << "with name" << possibleItems[item]; names.append(possibleItems[item]); } names << "Parameters" << "Compile rule"; } if (column == 8) { names << "Rule options" << "Logging On" << "Logging Off" << "Compile Rule"; } if (column == 9) { names << "Edit" << "Compile Rule"; } QStringList groupCommon; groupCommon << "Change color" << "Insert New Rule" << "Add New Rule Below" << "Remove Rule" << "Move Rule up" << "Move Rule down" << "Copy Rule" << "Cut Rule" << "Paste Rule Above" << "Paste Rule Below" << "Disable Rule" << "Compile rule"; if (column == -1) // column 0 for rule above group { names << "New group" << "Add to the group Test Group Name" << groupCommon; } if (column == -2) // column 0 for first rule in group { names << "Remove from the group" << groupCommon; } if (column == -3) // rule in the middle of the group { names << groupCommon; } if (column == -4) { names << "Remove from the group" << groupCommon; } if (column == -5) { names << "New group" << "Add to the group Test Group Name" << groupCommon; } QTimer::singleShot(150, this, SLOT(actuallyVerifyMenu())); } void RuleSetViewContextMenuTest::actuallyVerifyMenu() { QMenu *menu = dynamic_cast(app->activePopupWidget()); menu->hide(); int j =0; for (int i=0; iactions().size(); i++) { if (menu->actions()[i]->text().isEmpty() || !menu->actions()[i]->isVisible()) continue; if (menu->actions()[i]->text().toLower() != names[j++].toLower()) { failed = true; qDebug() << QString("Menu item not found or item order is wrong for item: %1").arg(names[j-1]); } } QVERIFY(j == names.size()); } /* * Scrolls view to bottom and returns middle pixel of view's middle line. * There */ QPoint RuleSetViewContextMenuTest::getViewBottomPoint() { view->scrollToBottom(); view->viewport()->mapToParent(QPoint(view->viewport()->width()/2, view->viewport()->height()-1)); return QPoint(view->viewport()->width()/2, view->viewport()->height()-1); } void RuleSetViewContextMenuTest::test_menus() { failed = false; // Adding one new rule clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 1); Rule *rule = ((RuleSetModel*)view->model())->findRuleForPosition(0); // Verify columns 1..5 and 7..10 for (int i=0; i<10; i++) { if (i==6) continue; // it depens on platform qDebug() << "Verifying context menu for column" << i; verifyMenu(i); showContextMenu(findCell(rule, i)); QVERIFY2(!failed, QString("Failed for column %1").arg(i).toAscii().constData()); } // Remove created rule clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule)); } void RuleSetViewContextMenuTest::test_group_menus() { failed = false; // Adding five new rules Rule *rules[5]; clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); rules[0] = getRuleForPosition(0); for (int i=0; i<4; i++) { clickMenuItem("Add New Rule at the Bottom"); showContextMenu(getViewBottomPoint()); rules[i+1] = getRuleForPosition(i+1); } // Create new group view->selectRE(rules[2], 0); createGroup("Test Group Name"); clickMenuItem("New Group"); showContextMenu(findRulePosition(rules[3])); // Add two rules to group view->selectRE(rules[1], 0); clickMenuItem("Add To the Group Test Group Name"); showContextMenu(findRulePosition(rules[1])); view->selectRE(rules[3], 0); clickMenuItem("Add To the Group Test Group Name"); showContextMenu(findRulePosition(rules[3])); view->expandAll(); // Check that columns 2..10 acts same for grouped and ungrouped items for (int j=0; j<5; j++) { // Verify columns 1..5 and 7..10 for (int i=1; i<10; i++) { qDebug() << "Verifying context menu for column" << i; verifyMenu(i); showContextMenu(findCell(getRuleForPosition(j), i)); QVERIFY2(!failed, QString("Failed for column %1").arg(i).toAscii().constData()); } } // Verify column 1 for all rules. They all should be different. for (int i=0; i<5; i++) { qDebug() << "Verifying rule #" <selectRE(getRuleForPosition(i),0); // QTest::qWait(1000); showContextMenu(findCell(getRuleForPosition(i), 0)); QVERIFY2(!failed, QString("Failed for rule #%1 of 5").arg(i+1).toAscii().constData()); } // remove created rules for (int i=1; i<4; i++) { clickMenuItem("Remove From the Group"); view->selectRE(rules[i],0); showContextMenu(findCell(rules[i],0)) } for (int i=0; i<5; i++) { clickMenuItem("Remove Rule"); view->selectRE(rules[i],0); showContextMenu(findCell(rules[i],0)) } } void RuleSetViewContextMenuTest::test_platforms() { failed = false; // Adding one new rule clickMenuItem("Insert New Rule"); showContextMenu(getViewBottomPoint()); QVERIFY(view->model()->rowCount(QModelIndex()) == 1); Rule *rule = ((RuleSetModel*)view->model())->findRuleForPosition(0); // Verify column 6 for all platforms QMap platforms = getAllPlatforms(); foreach(QString platform, platforms.keys()) { qDebug() << "Verifying conext menu for column 6 and platform" << platform; firewall->setStr("platform", platform.toStdString()); verifyMenu(6); showContextMenu(findCell(rule, 6)); QVERIFY2(!failed, QString("Failed for paltform %1").arg(platform).toAscii().constData()); } // Verify that column count changes depending of firewall platform QVERIFY(view->model()->columnCount() == 10); firewall->setStr("platform", "unknown"); openPolicy("testFirewall"); view = mw->findChild(""); QVERIFY(view->model()->columnCount() == 8); firewall->setStr("platform", "ipf"); openPolicy("testFirewall"); view = mw->findChild(""); QVERIFY(view->model()->columnCount() == 9); firewall->setStr("platform", "unknown"); openPolicy("testFirewall"); view = mw->findChild(""); // Remove created rule clickMenuItem("Remove Rule"); showContextMenu(findRulePosition(rule)); } fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewContextMenuTest/main_RuleSetViewContextMenuTest.cpp0000644000175000017500000000332311733011756034217 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RuleSetViewContextMenuTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new RuleSetViewContextMenuTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewContextMenuTest/RuleSetViewContextMenuTest.h0000644000175000017500000000432711733011756032665 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: RuleSetViewContextMenuTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include #include "newClusterDialog.h" #include "upgradePredicate.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "instDialog.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "RuleSetView.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" class RuleSetViewContextMenuTest : public QObject { Q_OBJECT bool failed; ObjectManipulator *om; RuleSetView *view; const char *ssh_auth_sock; void openPolicy(QString fw); libfwbuilder::Library* findUserLibrary(); QString groupToCreate; QString itemToClick; bool clicked; void clickMenuItem(QString item); QPoint findRulePosition(int rule); QPoint findRulePosition(libfwbuilder::Rule *rule); QPoint getViewBottomPoint(); QPoint findCell(libfwbuilder::Rule *rule, int col); void createGroup(QString name); void verifyMenu(int column); QStringList names; libfwbuilder::Firewall *firewall; private slots: void initTestCase(); void test_menus(); void test_group_menus(); void test_platforms(); public slots: void actuallyClickMenuItem(); void actuallyCreateGroup(); void actuallyVerifyMenu(); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/RuleSetViewContextMenuTest/RuleSetViewContextMenuTest.pro0000644000175000017500000000033011733011756033224 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = RuleSetViewContextMenuTest SOURCES += main_RuleSetViewContextMenuTest.cpp \ RuleSetViewContextMenuTest.cpp HEADERS += RuleSetViewContextMenuTest.h fwbuilder-5.1.0.3599/src/unit_tests/UserSerivceDialogTest/0000755000175000017500000000000011733011756024205 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/UserSerivceDialogTest/UserServiceDialogTest.h0000644000175000017500000000241511733011756030577 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: UserServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef UserServiceDialogTest_H #define UserServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class UserServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testDialog(); }; #endif // UserServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/UserSerivceDialogTest/main_UserServiceDialogTest.cpp0000644000175000017500000000330611733011756032136 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UserServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new UserServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/UserSerivceDialogTest/UserServiceDialogTest.cpp0000644000175000017500000001054111733011756031131 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: UserServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UserServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "UserServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/UserService.h" #include "UserDialog.h" using namespace std; using namespace libfwbuilder; void UserServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); mw->resize(1200, 600); QTest::qWait(2000); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); } Library* UserServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void UserServiceDialogTest::testDialog() { UserService *service = UserService::cast( om->createObject( FWBTree().getStandardSlotForObject(findUserLibrary(), UserService::TYPENAME), UserService::TYPENAME, "testUserService")); QTest::qWait(1000); //om->editObject(service); UserDialog *dialog = mw->findChild("w_UserDialog"); QVERIFY(dialog != NULL); QLineEdit *obj_name = dialog->findChild("obj_name"); QLineEdit *userid = dialog->findChild("userid"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestUserService"); QTest::keyClick(obj_name, Qt::Key_Enter); QTest::qWait(100); QVERIFY(service->getName() == "TestUserService"); userid->clear(); QTest::keyClicks(userid, "username"); QTest::keyClick(userid, Qt::Key_Enter); QTest::qWait(100); QVERIFY(service->getUserId() == "username"); // need to click inside the comment input field to make sure it // has focus. Looks like keyClicks() works even when widget has no // focus, so clicking outside of it does not trigger "edit // finished" signal. also looks like waiting a little after // clicking inside the text editor widget makes test more stable. comment->clear(); QTest::mouseClick(comment, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); QTest::qWait(100); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(obj_name, Qt::LeftButton); QTest::qWait(100); qDebug() << "Dialog comment text=" << comment->toPlainText(); qDebug() << "Object comment=" << QString(service->getComment().c_str()); QVERIFY(service->getComment() == "Test comment"); } fwbuilder-5.1.0.3599/src/unit_tests/UserSerivceDialogTest/UserServiceDialogTest.pro0000644000175000017500000000030411733011756031143 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = UserServiceDialogTest SOURCES += main_UserServiceDialogTest.cpp \ UserServiceDialogTest.cpp HEADERS += UserServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/commandLinePrintingTest/0000755000175000017500000000000011733011756024567 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/commandLinePrintingTest/test.fwb0000644000175000017500000025311711733011756026257 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/commandLinePrintingTest/commandLinePrintingTest.pro0000644000175000017500000000050211733011756032107 0ustar sylvestresylvestreTEMPLATE = app LANGUAGE = bash CONFIG += console CONFIG -= app_bundle TARGET = commandLinePrintingTest run_tests.commands = echo "Running tests..." && ./${TARGET} && echo "OK" || echo "FAILED" run_tests.depends = build_tests clean_tests.commands = rm -f print.pdf QMAKE_EXTRA_TARGETS += run_tests build_tests clean_tests fwbuilder-5.1.0.3599/src/unit_tests/commandLinePrintingTest/commandLinePrintingTest0000755000175000017500000000241611733011756031321 0ustar sylvestresylvestre#!/bin/sh rm -f print.pdf >/dev/null 2>/dev/null QTVERSION=$(${QMAKE:-qmake} --version 2>&1 | tail -n1| cut -d' ' -f4) TESTNAME=${0##/} PASSED=0 FAILED=0 SKIPPED=0 pass() # test_name { echo "PASS : ${TESTNAME}::$1()" PASSED=$((PASSED+1)) } fail() # test_name { echo "FAIL! : ${TESTNAME}::$1()" FAILED=$((FAILED+1)) } output() # test_name text { echo -n "QDEBUG : ${TESTNAME}::$1() " shift echo $@ } run_command() # test_name command { test=$1 shift output=$("$@" 2>&1) returned=$? ORIGIFS=$IFS IFS=`printf "\n\b"` for line in $output do output $test $line done IFS=$ORIGIFS [ "$returned" -eq 0 ] && pass "$test" || fail "$test" } echo "********* Start testing of ${TESTNAME} *********" echo "Config: Using QTest library ${QTVERSION}, Qt ${QTVERSION}" pass "initTestCase" # -------- actual testing goes here -------- run_command "runPrinting" ../../gui/fwbuilder -f test.fwb -P test run_command "fileExists" ls print.pdf # --------- end of actual testing --------- rm -f print.pdf >/dev/null 2>&1 pass "cleanupTestCase" echo "Totals: ${PASSED} passed, ${FAILED} failed, ${SKIPPED} skipped" echo "********* Finished testing of ${TESTNAME} *********" [ "${FAILED}" -eq 0 ] && exit 0 || exit 1 fwbuilder-5.1.0.3599/src/unit_tests/RCS/0000755000175000017500000000000011733011756020415 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/RCS/RCSTest.h0000644000175000017500000000217111733011756022056 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef RCSTEST_H #define RCSTEST_H #include class RCSTest : public CppUnit::TestFixture { public: void verifyRevisions(); CPPUNIT_TEST_SUITE(RCSTest); CPPUNIT_TEST(verifyRevisions); CPPUNIT_TEST_SUITE_END(); }; #endif // RCSTEST_H fwbuilder-5.1.0.3599/src/unit_tests/RCS/RCSTest.cpp0000644000175000017500000000740411733011756022415 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RCSTest.h" #include "../../../../config.h" //#include "../../global.h" #include "../../libgui/RCS.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; int fwbdebug = 0; QString test_file = "zu.fwb,v"; QString rlog_unit_test_log_file = "rlog_unit_test.log"; void RCSTest::verifyRevisions() { RCS::init(); RCS *rcs = new RCS(test_file); QList rcsrevs; for (QList::iterator i=rcs->begin(); i!=rcs->end(); ++i) { Revision rev = *i; QStringList log = rev.log.split("\n"); log.removeFirst(); rev.log = log.join("\n"); rcsrevs.append(rev); } QProcess rlog; rlog.start("rlog", QStringList() << test_file); rlog.waitForFinished(); QList realrevs; QRegExp revlock("revision\\s+([\\.\\d]+)(\\s+locked by: (\\w+);)?\\n"); revlock.setPatternSyntax(QRegExp::RegExp2); QRegExp dateauth("date: (\\d\\d\\d\\d/\\d\\d/\\d\\d \\d\\d\\:\\d\\d\\:\\d\\d);\\s+author\\: (\\w+);\\s+state\\: (\\w+);(\\s+lines: \\+(\\d+) \\-(\\d+))?\\n"); QMap realrevsmap; QString line; while (!rlog.atEnd() && line != "----------------------------\n") // skip header line = rlog.readLine(); while (!rlog.atEnd()) { QStringList lines; while (!rlog.atEnd()) { line = rlog.readLine(); if (line != "----------------------------\n" && line != "=============================================================================\n") lines.append(line); else break; } QStringList comment; for (int i = 2; i< lines.size(); i++) comment.append(lines.at(i)); Revision rev; rev.log = comment.join(""); revlock.indexIn(lines[0]); rev.locked_by = revlock.capturedTexts()[3]; rev.rev = revlock.capturedTexts()[1]; dateauth.indexIn(lines[1]); rev.date = dateauth.capturedTexts()[1].replace("/", "-"); rev.author = dateauth.capturedTexts()[2]; rev.filename = test_file; realrevs.insert(0, rev); realrevsmap[rev.rev] = rev; } CPPUNIT_ASSERT(realrevs.size() == rcsrevs.size()); for (int i = 0; i < realrevs.size(); i++) { Revision rcsr = rcsrevs.at(i); Revision realr = realrevsmap[rcsr.rev]; /* qDebug() << realr.author << rcsr.author; qDebug() << realr.date << rcsr.date; qDebug() << realr.filename << rcsr.filename; qDebug() << realr.locked_by << rcsr.locked_by; qDebug() << realr.log << rcsr.log; qDebug() << realr.rev << rcsr.rev; qDebug() << "----------"; qDebug() << (realr == rcsr); */ CPPUNIT_ASSERT (realr == rcsr); } } fwbuilder-5.1.0.3599/src/unit_tests/RCS/zu.fwb,v0000644000175000017500000001670211733011756022023 0ustar sylvestresylvestrehead 1.9; access; symbols; locks; strict; comment @# @; expand @b@; 1.9 date 2011.05.06.05.06.32; author vadim; state Exp; branches; next 1.8; 1.8 date 2011.02.23.00.03.49; author vadim; state Exp; branches; next 1.7; 1.7 date 2006.07.19.03.42.51; author vadim; state Exp; branches; next 1.6; 1.6 date 2006.07.19.03.40.24; author vadim; state Exp; branches; next 1.5; 1.5 date 2006.07.19.03.39.45; author vadim; state Exp; branches 1.5.1.1; next 1.4; 1.4 date 2006.06.26.03.16.12; author vadim; state Exp; branches; next 1.3; 1.3 date 2005.09.05.07.49.31; author vadim; state Exp; branches; next 1.2; 1.2 date 2004.09.29.07.01.31; author vadim; state Exp; branches; next 1.1; 1.1 date 2004.06.13.19.54.03; author vadim; state Exp; branches; next ; 1.5.1.1 date 2006.07.19.03.41.19; author vadim; state Exp; branches; next 1.5.1.2; 1.5.1.2 date 2006.07.19.03.41.57; author vadim; state Exp; branches; next ; desc @"Initial checkin" @ 1.9 log @upgraded to the latest dtd version @ text @ @ 1.8 log @upgrade to dtd 18 @ text @d3 13 a15 16 d17 13 a29 34 @ 1.7 log @working in the main trunk @ text @d3 1 a3 1 d5 3 d9 2 a10 7 d12 3 d16 4 a20 1 d22 30 a51 8 @ 1.6 log @added dns name object @ text @d3 1 a3 1 d14 1 @ 1.5 log @fixed file using fwbedit @ text @d3 1 a3 1 d12 3 a14 1 @ 1.5.1.1 log @added dns name object #2, creating a branch @ text @d3 1 a3 1 d12 1 a12 3 @ 1.5.1.2 log @working in the branch @ text @d3 1 a3 1 a13 1 @ 1.4 log @_ @ text @d3 2 a4 2 d6 1 a6 1 d12 1 d15 1 a15 1 @ 1.3 log @test commit @ text @d3 1 a3 1 d6 1 d14 1 @ 1.2 log @. @ text @d3 1 a3 1 @ 1.1 log @Initial revision @ text @d3 1 a3 1 @ fwbuilder-5.1.0.3599/src/unit_tests/RCS/rlog_unit_test.log0000644000175000017500000000245711733011756024171 0ustar sylvestresylvestre--------------------------------- revision: 1.7 date: 2006-07-18 20:42:51-07 author: vadim locked by: log: revision 1.7 working in the main trunk --------------------------------- revision: 1.6 date: 2006-07-18 20:40:24-07 author: vadim locked by: vadim log: revision 1.6 locked by: vadim; added dns name object --------------------------------- revision: 1.5 date: 2006-07-18 20:39:45-07 author: vadim locked by: log: revision 1.5 branches: 1.5.1; fixed file using fwbedit --------------------------------- revision: 1.4 date: 2006-06-25 20:16:12-07 author: vadim locked by: log: revision 1.4 _ --------------------------------- revision: 1.3 date: 2005-09-05 00:49:31-07 author: vadim locked by: log: revision 1.3 test commit --------------------------------- revision: 1.2 date: 2004-09-29 00:01:31-07 author: vadim locked by: log: revision 1.2 . --------------------------------- revision: 1.1 date: 2004-06-13 12:54:03-07 author: vadim locked by: log: revision 1.1 Initial revision --------------------------------- revision: 1.5.1.2 date: 2006-07-18 20:41:57-07 author: vadim locked by: log: revision 1.5.1.2 working in the branch --------------------------------- revision: 1.5.1.1 date: 2006-07-18 20:41:19-07 author: vadim locked by: log: revision 1.5.1.1 added dns name object #2, creating a branch fwbuilder-5.1.0.3599/src/unit_tests/RCS/RCSTest.pro0000644000175000017500000000020611733011756022424 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS += RCSTest.h SOURCES += main_RCS.cpp \ RCSTest.cpp TARGET = RCSTest fwbuilder-5.1.0.3599/src/unit_tests/RCS/zu.fwb0000644000175000017500000000413111733011756021552 0ustar sylvestresylvestre fwbuilder-5.1.0.3599/src/unit_tests/RCS/main_RCS.cpp0000644000175000017500000000245411733011756022561 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "RCSTest.h" #include #include //int fwbdebug = 0; //QString user_name; int main( int, char** ) { CppUnit::TextUi::TestRunner runner; runner.addTest( RCSTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/0000755000175000017500000000000011733011756022655 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/PFImporterTest.pro0000644000175000017500000000022411733011756026264 0ustar sylvestresylvestreinclude(../tests_common.pri) TARGET = PFImporterTest HEADERS += PFImporterTest.h SOURCES += main_PFImporterTest.cpp \ PFImporterTest.cpp fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/.gitignore0000644000175000017500000000004011733011756024637 0ustar sylvestresylvestre*.fwb !test_data/*.fwb !*.conf fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/PFImporterTest.h0000644000175000017500000000575111733011756025725 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PFIMPORTERTEST_H #define PFIMPORTERTEST_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include #include #include #include class PFImporterTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *db; libfwbuilder::Library *lib; libfwbuilder::QueueLogger *logger; int predictable_id_tracker; std::map id_mapping; void compareResults(libfwbuilder::QueueLogger* logger, QString expected_result_file_name, QString obtained_result_file_name); void compareFwbFiles(QString expected_result_file_name, QString obtained_result_file_name); std::string openTestFile(const QString &file_name); public: void setUp(); void macrosTest(); void hostsMatchTest(); void blockReturnTest(); void icmpMatchTest(); void interfaceMatchTest(); void portMatchTest(); void setCommandsTest(); void stateMatchTest(); void tcpFlagsMatchTest(); void natCommands(); void rdrCommands(); void setTimeoutCommands(); void scrubCommandsOld(); void scrubCommandsNew(); void tableDefinitions(); void userGroupMatches(); void routeToTest(); void routeTo47Test(); CPPUNIT_TEST_SUITE(PFImporterTest); CPPUNIT_TEST(macrosTest); CPPUNIT_TEST(hostsMatchTest); CPPUNIT_TEST(blockReturnTest); CPPUNIT_TEST(icmpMatchTest); CPPUNIT_TEST(interfaceMatchTest); CPPUNIT_TEST(portMatchTest); CPPUNIT_TEST(setCommandsTest); CPPUNIT_TEST(stateMatchTest); CPPUNIT_TEST(tcpFlagsMatchTest); CPPUNIT_TEST(natCommands); CPPUNIT_TEST(rdrCommands); CPPUNIT_TEST(setTimeoutCommands); CPPUNIT_TEST(scrubCommandsOld); CPPUNIT_TEST(scrubCommandsNew); CPPUNIT_TEST(tableDefinitions); CPPUNIT_TEST(userGroupMatches); CPPUNIT_TEST(routeToTest); CPPUNIT_TEST(routeTo47Test); CPPUNIT_TEST_SUITE_END(); }; #endif // PFIMPORTERTEST_H fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/PFImporterTest.cpp0000644000175000017500000004144411733011756026257 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PFImporterTest.h" #include "config.h" #include "global.h" #include #include #include #include #include #include #include "Importer.h" #include "PFImporter.h" #include "FWBTree.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; extern string platform; extern QString findBestVersionMatch(const QString &platform, const QString &discovered_version); class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string &) const { return false; } }; void PFImporterTest::setUp() { FWBTree *tree = new FWBTree(); /* create database */ db = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; db->setReadOnly( false ); db->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); db->setFileName(""); lib = Library::cast(tree->createNewLibrary(db)); lib->setName("User"); logger = new QueueLogger(); // this makes the test compile and link. There is a problem with // dependencies, the test depends on libimport.a and additionally, // PFImporter.cpp depends on this function that is implemented in // platforms.cpp in libgui.a; however since libgui.a comes before // libimport.a in linker command line, this function does not get // pulled since it is not used anywhere except by this test module // and so linking fails. Making this call creates dependency and // pulls this function at linking time before libimport.a and its // dependencies are considered QString version = findBestVersionMatch("pf", "4.0"); } void PFImporterTest::compareResults(QueueLogger* logger, QString expected_result_file_name, QString obtained_result_file_name) { QString result; QStringList obtained_result; while (logger->ready()) result.append(logger->getLine().c_str()); obtained_result = result.split("\n"); QFile rw(obtained_result_file_name); rw.open(QFile::WriteOnly); rw.write(result.toAscii()); rw.close(); QFile rr(expected_result_file_name); rr.open(QFile::ReadOnly); QString result_file = rr.readAll(); QStringList expected_result = result_file.split("\n"); CPPUNIT_ASSERT_MESSAGE( QString( "Sizes of the generated importer output and test files are different.\n" "Expected: %1 (%2)\n" "Obtained: %3 (%4)\n" "diff -u %1 %3 | less -S") .arg(expected_result_file_name).arg(expected_result.size()) .arg(obtained_result_file_name).arg(obtained_result.size()).toStdString(), expected_result.size() == obtained_result.size()); int max_idx = max(expected_result.size(), obtained_result.size()); for (int i=0; i < max_idx; ++i) { QString err = QString("Line %1:\nExpected: '%2'\nResult: '%3'\n") .arg(i).arg(expected_result[i]).arg(obtained_result[i]); CPPUNIT_ASSERT_MESSAGE(err.toStdString(), obtained_result[i] == expected_result[i]); } } void PFImporterTest::compareFwbFiles(QString expected_result_file_name, QString obtained_result_file_name) { QString result; QStringList obtained_result; QFile rr(obtained_result_file_name); rr.open(QFile::ReadOnly); QString result_file = rr.readAll(); rr.close(); obtained_result = result_file.split("\n"); QFile er(expected_result_file_name); er.open(QFile::ReadOnly); result_file = er.readAll(); er.close(); QStringList expected_result = result_file.split("\n"); // find all lastModified attributes and replace them with identical values // because they are always going to be different QString err("Sizes of the generated .fwb and test files are different: \n" "Expected: %1 (%2)\n" "Obtained: %3 (%4)\n" "diff -u %1 %3 | less -S"); CPPUNIT_ASSERT_MESSAGE( err .arg(expected_result_file_name).arg(expected_result.size()) .arg(obtained_result_file_name).arg(obtained_result.size()) .toStdString(), expected_result.size() == obtained_result.size()); QRegExp last_mod_re("lastModified=\"\\d+\""); int max_idx = max(expected_result.size(), obtained_result.size()); for (int i=0; i < max_idx; ++i) { QString os = obtained_result[i]; obtained_result[i] = os.replace(last_mod_re, "lastModified=\"0000000000\""); QString es = expected_result[i]; expected_result[i] = es.replace(last_mod_re, "lastModified=\"0000000000\""); } for (int i=0; i < max_idx; ++i) { QString err = QString("Line %1:\nExpected: '%2'\nResult: '%3'\n") .arg(i).arg(expected_result[i]).arg(obtained_result[i]); CPPUNIT_ASSERT_MESSAGE(err.toStdString(), obtained_result[i] == expected_result[i]); } } std::string PFImporterTest::openTestFile(const QString &file_name) { QFile f(file_name); f.open(QFile::ReadOnly); string buffer = QString(f.readAll()).toStdString(); f.close(); return buffer; } void PFImporterTest::macrosTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-macros.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-macros.fwb"); compareResults(logger, "test_data/pf-macros.output", "pf-macros.output"); compareFwbFiles("test_data/pf-macros.fwb", "pf-macros.fwb"); } void PFImporterTest::hostsMatchTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-hosts-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-hosts-matches.fwb"); compareResults(logger, "test_data/pf-hosts-matches.output", "pf-hosts-matches.output"); compareFwbFiles("test_data/pf-hosts-matches.fwb", "pf-hosts-matches.fwb"); } void PFImporterTest::blockReturnTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-block-return-actions.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-block-return-actions.fwb"); compareResults(logger, "test_data/pf-block-return-actions.output", "pf-block-return-actions.output"); compareFwbFiles("test_data/pf-block-return-actions.fwb", "pf-block-return-actions.fwb"); } void PFImporterTest::icmpMatchTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-icmp-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-icmp-matches.fwb"); compareResults(logger, "test_data/pf-icmp-matches.output", "pf-icmp-matches.output"); compareFwbFiles("test_data/pf-icmp-matches.fwb", "pf-icmp-matches.fwb"); } void PFImporterTest::interfaceMatchTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-interface-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-interface-matches.fwb"); compareResults(logger, "test_data/pf-interface-matches.output", "pf-interface-matches.output"); compareFwbFiles("test_data/pf-interface-matches.fwb", "pf-interface-matches.fwb"); } void PFImporterTest::portMatchTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-port-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-port-matches.fwb"); compareResults(logger, "test_data/pf-port-matches.output", "pf-port-matches.output"); compareFwbFiles("test_data/pf-port-matches.fwb", "pf-port-matches.fwb"); } void PFImporterTest::setCommandsTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-set-commands.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); //db->setPredictableIds(); //db->saveFile("pf-set-commands.fwb"); compareResults(logger, "test_data/pf-set-commands.output", "pf-set-commands.output"); //compareFwbFiles("test_data/pf-set-commands.fwb", // "pf-set-commands.fwb"); } void PFImporterTest::stateMatchTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-state-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-state-matches.fwb"); compareResults(logger, "test_data/pf-state-matches.output", "pf-state-matches.output"); compareFwbFiles("test_data/pf-state-matches.fwb", "pf-state-matches.fwb"); } void PFImporterTest::tcpFlagsMatchTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-tcp-flags-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-tcp-flags-matches.fwb"); compareResults(logger, "test_data/pf-tcp-flags-matches.output", "pf-tcp-flags-matches.output"); compareFwbFiles("test_data/pf-tcp-flags-matches.fwb", "pf-tcp-flags-matches.fwb"); } void PFImporterTest::natCommands() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-nat-rules.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-nat-rules.fwb"); compareResults(logger, "test_data/pf-nat-rules.output", "pf-nat-rules.output"); compareFwbFiles("test_data/pf-nat-rules.fwb", "pf-nat-rules.fwb"); } void PFImporterTest::rdrCommands() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-rdr-rules.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-rdr-rules.fwb"); compareResults(logger, "test_data/pf-rdr-rules.output", "pf-rdr-rules.output"); compareFwbFiles("test_data/pf-rdr-rules.fwb", "pf-rdr-rules.fwb"); } void PFImporterTest::setTimeoutCommands() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-timeouts.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); // db->setPredictableIds(); // db->saveFile("pf-timeouts.fwb"); compareResults(logger, "test_data/pf-timeouts.output", "pf-timeouts.output"); // compareFwbFiles("test_data/pf-timeouts.fwb", // "pf-timeouts.fwb"); } void PFImporterTest::scrubCommandsOld() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-scrub-commands-old.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); compareResults(logger, "test_data/pf-scrub-commands-old.output", "pf-scrub-commands-old.output"); } void PFImporterTest::scrubCommandsNew() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-scrub-commands-new.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); compareResults(logger, "test_data/pf-scrub-commands-new.output", "pf-scrub-commands-new.output"); } void PFImporterTest::tableDefinitions() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-tables.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-tables.fwb"); compareResults(logger, "test_data/pf-tables.output", "pf-tables.output"); compareFwbFiles("test_data/pf-tables.fwb", "pf-tables.fwb"); } void PFImporterTest::userGroupMatches() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-user-group-matches.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-user-group-matches.fwb"); compareResults(logger, "test_data/pf-user-group-matches.output", "pf-user-group-matches.output"); compareFwbFiles("test_data/pf-user-group-matches.fwb", "pf-user-group-matches.fwb"); } void PFImporterTest::routeToTest() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-route-to.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-route-to.fwb"); compareResults(logger, "test_data/pf-route-to.output", "pf-route-to.output"); compareFwbFiles("test_data/pf-route-to.fwb", "pf-route-to.fwb"); } void PFImporterTest::routeTo47Test() { platform = "pf"; std::istringstream instream( openTestFile("test_data/pf-route-to-4.7.conf")); Importer* imp = new PFImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pf-route-to-4.7.fwb"); compareResults(logger, "test_data/pf-route-to-4.7.output", "pf-route-to-4.7.output"); compareFwbFiles("test_data/pf-route-to-4.7.fwb", "pf-route-to-4.7.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/main_PFImporterTest.cpp0000644000175000017500000000330611733011756027256 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "PFImporterTest.h" #include "fwbuilder/Resources.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" #include #include #include #include "../../../common/init.cpp" int fwbdebug = 0; //QString user_name; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; std::string platform; int main(int argc, char** argv) { QApplication app(argc, argv, false); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( PFImporterTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/0000755000175000017500000000000011733011756024625 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-route-to-4.7.conf0000644000175000017500000000172011733011756030163 0ustar sylvestresylvestre pass in log quick inet from 192.168.1.0/24 to any route-to { ( em0 10.1.2.3 ) } pass in quick on bce0 inet from 192.168.1.0/24 to any reply-to ( bce0 10.3.4.5 ) pass out quick on bce0 proto tcp from any port 80 to any dup-to (em0 10.1.2.3) # here we test that parameters round-robin, bitmask, random and source-hash # are imported correctly. # Also as of fwbuilder 5 we do not support route-to with multiple different # interface-gateway pairs; multiple gateway addresses and only one interface # are allowed. These rules will be imported partially. pass in quick on bce0 from 172.16.20.0/24 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } round-robin pass in quick on bce0 from 172.16.20.0/24 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } bitmask pass in quick on bce0 from 172.16.20.0/24 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } random pass in quick on bce0 from 172.16.20.0/24 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } source-hash fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-route-to-4.7.output0000644000175000017500000000167611733011756030610 0ustar sylvestresylvestre2: New interface: em0 2: filtering rule: action pass; interfaces: 4: New interface: bce0 4: filtering rule: action pass; interfaces: bce0 6: filtering rule: action pass; interfaces: bce0 14: New interface: em2 14: New interface: em1 14: filtering rule: action pass; interfaces: bce0 14: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" 15: filtering rule: action pass; interfaces: bce0 15: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" 16: filtering rule: action pass; interfaces: bce0 16: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" 17: filtering rule: action pass; interfaces: bce0 17: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-route-to.conf0000644000175000017500000000171111733011756027655 0ustar sylvestresylvestre pass in log quick route-to { ( em0 10.1.2.3 ) } inet from 192.168.1.0/24 to any pass in quick on bce0 reply-to ( bce0 10.3.4.5 ) inet from 192.168.1.0/24 to any pass out quick on bce0 dup-to (em0 10.1.2.3) proto tcp from any port 80 to any # here we test that parameters round-robin, bitmask, random and source-hash # are imported correctly. # Also as of fwbuilder 5 we do not support route-to with multiple different # interface-gateway pairs; multiple gateway addresses and only one interface # are allowed. These rules will be imported partially. pass in quick on bce0 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } round-robin from 172.16.20.0/24 pass in quick on bce0 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } bitmask from 172.16.20.0/24 pass in quick on bce0 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } random from 172.16.20.0/24 pass in quick on bce0 route-to { (em2 172.16.2.20), (em1 172.16.3.20) } source-hash from 172.16.20.0/24 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-tables.fwb0000644000175000017500000024134511733011756027213 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-user-group-matches.output0000644000175000017500000000137511733011756032252 0ustar sylvestresylvestre1: Error: import of 'user' match is not supported. 1: filtering rule: action pass; interfaces: 2: Error: import of 'user' match is not supported. 2: filtering rule: action pass; interfaces: 3: Error: import of 'user' match is not supported. 3: filtering rule: action pass; interfaces: 4: Error: import of 'user' match is not supported. 4: filtering rule: action pass; interfaces: 5: Error: import of 'group' match is not supported. 5: filtering rule: action pass; interfaces: 6: Error: import of 'group' match is not supported. 6: filtering rule: action pass; interfaces: 7: Error: import of 'group' match is not supported. 7: filtering rule: action pass; interfaces: Could not find enough information in the data file to create firewall interface objects. fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-scrub-commands-old.conf0000644000175000017500000000035711733011756031575 0ustar sylvestresylvestre # supported commands scrub all fragment reassemble scrub all fragment crop scrub all fragment drop-ovl scrub all reassemble tcp scrub all no-df scrub out all min-ttl 10 scrub out all max-mss 1470 scrub out all random-id block log all fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-hosts-matches.conf0000644000175000017500000000403411733011756030662 0ustar sylvestresylvestre addr_list_macro = "{ 10.123.12.32/27 10.123.14.8/27 10.123.10.16/28 10.123.0.0/24 }" table { 192.168.1.1, 192.168.1.2, 192.168.2.0/24 } table { pcn0, pcn0:network } table { pcn0:peer, pcn0:0 } table { www.fwbuilder.org, www.netcitadel.com } # interface:network interface:broacast interface:peer and interface:0 pass in quick from pcn0:network to self pass in quick from pcn0:broadcast to self pass in quick from pcn0:peer to self pass in quick from pcn0:0 to self pass in quick from any to 192.168.1.1 pass in quick from any to 192.168.1.0/24 pass in quick inet proto tcp from any to pcn0 port 80 pass in quick inet proto tcp from any to (pcn0) port 80 pass in quick inet proto tcp from any to www.fwbuilder.org port 80 pass in quick inet proto tcp from any to self port 22 pass in quick from any to pass in quick from any to pass in quick from any to pass in quick from any to pass in quick from any to $addr_list_macro pass in quick proto tcp from any to $addr_list_macro port 22 pass in quick proto tcp from any to $addr_list_macro port 22 keep state pass in quick inet6 from any to 2001:470:1f0e:162::2 pass in quick inet6 from any to ipv6.fwbuilder.org pass in quick from 192.168.1.1 to any pass in quick from 192.168.1.0/24 to any pass in quick inet proto tcp from pcn0 port 80 to any pass in quick inet proto tcp from (pcn0) port 80 to any pass in quick inet proto tcp from www.fwbuilder.org port 80 to any pass in quick inet proto tcp from self port 22 to any pass in quick from to any pass in quick from to any pass in quick from to any pass in quick from to any pass in quick from $addr_list_macro to any pass in quick proto tcp from $addr_list_macro port 22 to any pass in quick proto tcp from $addr_list_macro port 22 to any keep state pass in quick inet6 from 2001:470:1f0e:162::2 to any pass in quick inet6 from ipv6.fwbuilder.org to any fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-user-group-matches.fwb0000644000175000017500000024171011733011756031467 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-icmp-matches.output0000644000175000017500000000100611733011756031061 0ustar sylvestresylvestre5: New interface: pcn0 5: filtering rule: action pass; interfaces: pcn0 6: filtering rule: action pass; interfaces: pcn0 7: filtering rule: action pass; interfaces: pcn0 8: filtering rule: action pass; interfaces: pcn0 9: filtering rule: action pass; interfaces: pcn0 10: filtering rule: action pass; interfaces: pcn0 11: filtering rule: action pass; interfaces: pcn0 12: filtering rule: action pass; interfaces: pcn0 13: filtering rule: action pass; interfaces: pcn0 14: filtering rule: action pass; interfaces: pcn0 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-tables.output0000644000175000017500000000236011733011756027765 0ustar sylvestresylvestre2: Address Table: file 3: Warning: attribute "counters" will be dropped from table configuration since this attribute is not supported at this time 3: Address Table: file 4: Warning: attribute "counters" will be dropped from table configuration since this attribute is not supported at this time 4: Address Table: file "./pf_block_permanent" 5: Address Table: file "./pf_table" 6: Address Table: file 7: Warning: attribute "const" will be dropped from table configuration since this attribute is not supported at this time 7: Address Table: : 10/8, 172.16/12, 192.168/16 9: Address Table: : 192.168.1.1, 192.168.1.2, 192.168.2.0/24 10: Address Table: : pcn0, pcn0 10: New interface: pcn0 11: Address Table: : pcn0, pcn0 12: Address Table: : www.fwbuilder.org, www.netcitadel.com 15: Address Table: : 192.168.10.1, !192.168.10.2, 192.168.20.0/24 15: Error: import of table definition with negated addresses is not supported. 18: New interface: em1 18: filtering rule: action pass; interfaces: em1 18: Error: Address table 'dst_addresses_5' has a mix of negated and non-negated addresses in the original file. fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-port-matches.fwb0000644000175000017500000045162411733011756030352 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-macros.fwb0000644000175000017500000030757611733011756027236 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-block-return-actions.fwb0000644000175000017500000032422311733011756032003 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-tables.conf0000644000175000017500000000124611733011756027354 0ustar sylvestresylvestre table persist table counters table counters file "./pf_block_permanent" table file "./pf_table" table table const { 10/8, 172.16/12, 192.168/16 } table { 192.168.1.1, 192.168.1.2, 192.168.2.0/24 } table { pcn0, pcn0:network } table { pcn0:peer, pcn0:0 } table { www.fwbuilder.org, www.netcitadel.com } # unsupported: this table has a mix of negated and non-negated addresses table { 192.168.10.1, !192.168.10.2, 192.168.20.0/24 } # the rule should be marked as "broken" pass in quick on em1 from to any fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-hosts-matches.fwb0000644000175000017500000032433011733011756030517 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-state-matches.output0000644000175000017500000000055311733011756031257 0ustar sylvestresylvestre5: filtering rule: action pass; interfaces: 6: filtering rule: action pass; interfaces: 7: filtering rule: action pass; interfaces: 10: filtering rule: action pass; interfaces: 11: filtering rule: action pass; interfaces: 12: filtering rule: action pass; interfaces: Could not find enough information in the data file to create firewall interface objects. fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-interface-matches.output0000644000175000017500000000071511733011756032077 0ustar sylvestresylvestre4: New interface: pcn0 4: filtering rule: action pass; interfaces: 5: filtering rule: action pass; interfaces: 5: Error: import of 'interface:broadcast' is not supported. 6: filtering rule: action pass; interfaces: 6: Error: import of 'interface:peer' is not supported. 7: filtering rule: action pass; interfaces: 7: Error: import of 'interface:0' is not supported. 9: filtering rule: action pass; interfaces: 10: filtering rule: action pass; interfaces: fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-block-return-actions.conf0000644000175000017500000000375211733011756032153 0ustar sylvestresylvestre # state matches block in quick inet proto tcp from any to self port = 80 # the same as the one above block drop in quick inet proto tcp from any to self port = 80 block return in quick inet proto tcp from any to self port = 80 block return in quick inet from any to self block return in quick inet proto udp from any to self port = 123 block return in quick inet proto icmp from any to self block return in quick inet proto { tcp, udp, icmp } from any to self block return-rst in quick inet proto tcp from any to self port = 80 # incorrect rule (cant ue return-rst with udp). But we import it anyway block return-rst in quick inet proto udp from any to self port = 123 block return-icmp in quick inet proto tcp from any to self port = 1080 block return-icmp (net-unr) in quick inet proto tcp from any to self port = 1081 block return-icmp (0) in quick inet proto tcp from any to self port = 1082 block return-icmp ( net-unr ) in quick inet proto tcp from any to self port = 1083 block return-icmp ( 0 ) in quick inet proto tcp from any to self port = 1084 block return-icmp (host-unr) in quick inet proto tcp from any to self port = 1085 block return-icmp (1) in quick inet proto tcp from any to self port = 1086 block return-icmp (proto-unr) in quick inet proto tcp from any to self port = 1087 block return-icmp (2) in quick inet proto tcp from any to self port = 1088 block return-icmp (port-unr) in quick inet proto tcp from any to self port = 1089 block return-icmp (3) in quick inet proto tcp from any to self port = 1090 block return-icmp (net-prohib) in quick inet proto tcp from any to self port = 1091 block return-icmp (9) in quick inet proto tcp from any to self port = 1092 block return-icmp (host-prohib) in quick inet proto tcp from any to self port = 1093 block return-icmp (10) in quick inet proto tcp from any to self port = 1094 block return-icmp (filter-prohib) in quick inet proto tcp from any to self port = 1095 block return-icmp (13) in quick inet proto tcp from any to self port = 1096 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-interface-matches.conf0000644000175000017500000000044511733011756031464 0ustar sylvestresylvestre # interface:network interface:broacast interface:peer and interface:0 pass in quick from pcn0:network to self pass in quick from pcn0:broadcast to self pass in quick from pcn0:peer to self pass in quick from pcn0:0 to self pass in quick from any to (pcn0) pass out quick from (pcn0) to any fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-tcp-flags-matches.conf0000644000175000017500000000122111733011756031375 0ustar sylvestresylvestre # tcp flags matches pass in quick proto tcp from any to self port = 22 pass in quick proto tcp from any to self port = 22 flags any pass in quick proto tcp from any to self port = 22 flags S/SA pass in quick proto tcp from any to self port = 22 flags S/SAFR block in log quick proto tcp flags FUP/WEUAPRSF label "FUP/WEUAPRSF" block in log quick proto tcp flags WEUAPRSF/WEUAPRSF label "WEUAPRSF/WEUAPRSF" block in log quick proto tcp flags SRAFU/WEUAPRSF label "SRAFU/WEUAPRSF" block in log quick proto tcp flags /WEUAPRSF label "/WEUAPRSF" block in log quick proto tcp flags SR/SR label "SR/SR" block in log quick proto tcp flags SF/SF label "SF/SF" fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-user-group-matches.conf0000644000175000017500000000050311733011756031627 0ustar sylvestresylvestrepass out quick from self to any user foo pass out quick from self to any user 500 pass out quick from self to any user > 500 pass out quick from self to any user { 500, 501, 502 } pass out quick from self to any group bar pass out quick from self to any group > 500 pass out quick from self to any group { 500, 501, 502 } fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-route-to.output0000644000175000017500000000167611733011756030302 0ustar sylvestresylvestre2: New interface: em0 2: filtering rule: action pass; interfaces: 4: New interface: bce0 4: filtering rule: action pass; interfaces: bce0 6: filtering rule: action pass; interfaces: bce0 14: New interface: em2 14: New interface: em1 14: filtering rule: action pass; interfaces: bce0 14: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" 15: filtering rule: action pass; interfaces: bce0 15: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" 16: filtering rule: action pass; interfaces: bce0 16: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" 17: filtering rule: action pass; interfaces: bce0 17: Warning: 'route-to' parameters with multiple interface-gateway pairs are not supported: "(em2 172.16.2.20), (em1 172.16.3.20)" fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-port-matches.output0000644000175000017500000000662011733011756031124 0ustar sylvestresylvestre5: filtering rule: action pass; interfaces: 6: filtering rule: action pass; interfaces: 7: filtering rule: action pass; interfaces: 7: Error: 'Port not equal' operation is not supported yet. 8: filtering rule: action pass; interfaces: 9: filtering rule: action pass; interfaces: 10: filtering rule: action pass; interfaces: 11: filtering rule: action pass; interfaces: 12: filtering rule: action pass; interfaces: 14: filtering rule: action pass; interfaces: 15: filtering rule: action pass; interfaces: 16: filtering rule: action pass; interfaces: 17: filtering rule: action pass; interfaces: 18: filtering rule: action pass; interfaces: 19: filtering rule: action pass; interfaces: 20: filtering rule: action pass; interfaces: 21: filtering rule: action pass; interfaces: 24: filtering rule: action pass; interfaces: 25: filtering rule: action pass; interfaces: 26: filtering rule: action pass; interfaces: 26: Error: 'Port not equal' operation is not supported yet. 27: filtering rule: action pass; interfaces: 28: filtering rule: action pass; interfaces: 29: filtering rule: action pass; interfaces: 30: filtering rule: action pass; interfaces: 31: filtering rule: action pass; interfaces: 33: filtering rule: action pass; interfaces: 34: filtering rule: action pass; interfaces: 35: filtering rule: action pass; interfaces: 36: filtering rule: action pass; interfaces: 37: filtering rule: action pass; interfaces: 38: filtering rule: action pass; interfaces: 39: filtering rule: action pass; interfaces: 40: filtering rule: action pass; interfaces: 43: filtering rule: action pass; interfaces: 44: filtering rule: action pass; interfaces: 45: filtering rule: action pass; interfaces: 45: Error: 'except ranges' ('<>') for port numbers are not supported yet. 47: filtering rule: action pass; interfaces: 48: filtering rule: action pass; interfaces: 49: filtering rule: action pass; interfaces: 49: Error: 'except ranges' ('<>') for port numbers are not supported yet. 52: filtering rule: action pass; interfaces: 55: filtering rule: action pass; interfaces: 56: filtering rule: action pass; interfaces: 56: Error: 'Port not equal' operation is not supported yet. 57: filtering rule: action pass; interfaces: 58: filtering rule: action pass; interfaces: 59: filtering rule: action pass; interfaces: 60: filtering rule: action pass; interfaces: 61: filtering rule: action pass; interfaces: 62: filtering rule: action pass; interfaces: 63: filtering rule: action pass; interfaces: 63: Error: 'except ranges' ('<>') for port numbers are not supported yet. 65: filtering rule: action pass; interfaces: 66: filtering rule: action pass; interfaces: 66: Error: 'Port not equal' operation is not supported yet. 67: filtering rule: action pass; interfaces: 68: filtering rule: action pass; interfaces: 69: filtering rule: action pass; interfaces: 70: filtering rule: action pass; interfaces: 71: filtering rule: action pass; interfaces: 72: filtering rule: action pass; interfaces: 73: filtering rule: action pass; interfaces: 73: Error: 'except ranges' ('<>') for port numbers are not supported yet. 75: filtering rule: action pass; interfaces: 78: filtering rule: action pass; interfaces: 80: filtering rule: action pass; interfaces: 82: filtering rule: action pass; interfaces: 84: filtering rule: action pass; interfaces: Could not find enough information in the data file to create firewall interface objects. fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-set-commands.conf0000644000175000017500000000112011733011756030463 0ustar sylvestresylvestre # supported set commands set debug crit set state-policy if-bound set block-policy drop set block-policy return set limit { frags 5000, states 10000, src-nodes 100000, tables 100000, tables-entries 100000 } set optimization normal set optimization aggressive set optimization conservative set optimization high-latency set skip on lo0 set skip on { lo0, em0 } set skip on {pcn0 pcn1} # unsupported set commands set fingerprints set hostid 1234567890 set loginterface dc0 set reassemble set require-order set ruleset-optimization basic set state-defaults pflow, no-sync block log all fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-icmp-matches.conf0000644000175000017500000000157211733011756030456 0ustar sylvestresylvestre icmp_services="echorep unreach squench redir althost echoreq routeradv routersol timex paramprob timereq timerep inforeq inforep maskreq maskrep trace dataconv mobredir ipv6-where ipv6-here mobregreq mobregrep skip photuris" # icmp matches pass quick on pcn0 inet proto icmp all icmp-type 8 pass quick on pcn0 inet proto icmp all icmp-type 8 code 0 pass quick on pcn0 inet proto icmp all icmp-type echoreq pass quick on pcn0 inet proto icmp all icmp-type echoreq code 0 pass quick on pcn0 inet proto icmp all icmp-type unreach code net-unr pass quick on pcn0 inet proto icmp all icmp-type unreach code 1 pass quick on pcn0 inet proto icmp all icmp-type unreach code host-unr pass quick on pcn0 inet proto icmp all icmp-type unreach code proto-unr pass quick on pcn0 inet proto icmp all icmp-type unreach code port-unr pass quick on pcn0 inet proto icmp all icmp-type { $icmp_services } fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-scrub-commands-new.output0000644000175000017500000000040011733011756032210 0ustar sylvestresylvestre14: filtering rule: action block; interfaces: Could not find enough information in the data file to create firewall interface objects. scrub reassemble tcp scrub no-df scrub min-ttl 10 scrub max-mss 1470 scrub random-id scrub no-df scrub max-mss 1440 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-interface-matches.fwb0000644000175000017500000024147111733011756031323 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-macros.conf0000644000175000017500000000436711733011756027375 0ustar sylvestresylvestre one_address = 10.1.1.1 # comment is allowed here addr_list_1 = "{ 10.123.12.32/27 10.123.14.8/27 10.123.10.16/28 10.123.0.0/24 }" # another macro is used inside this one recursively and only {} are in quotes addr_list_2 = "{" $one_address 10.123.12.32/27 10.123.14.8/27 10.123.10.16/28 10.123.0.0/24 "}" # now use comma as a separator addr_list_3 = "{" $one_address, 10.123.12.33/27, 10.123.14.9/27 "}" # spaces are mixed with tabs and messed up addr_list_4 = "{$one_address, 10.123.12.34/27, 10.123.14.10/27}" # multi-line addr_list_5 = "{$one_address, \ 10.123.12.35/27,\ 10.123.14.11/27}" # another macro name is a substring of this one's name addr_list_1_foo = "{ 10.1.2.3 10.4.5.6 10.7.8.9 }" host1 = "192.168.1.1" host2 = "192.168.1.2" recursive_macro = "{" $host1 $host2 "}" tcp_services = "{ ssh, smtp }" ext_if = "em1" mixed_macro_1 = "{ $host1 192.168.2.1 www.fwbuilder.org }" mixed_macro_2 = "{ $host1 192.168.2.1 em1 }" mixed_macro_3 = "{ $host1 192.168.2.1 em1:network }" mixed_macro_4 = "{ em1:network www.fwbuilder.org }" # test for an undefined macro # undefined_macro = 192.168.23.45 pass in quick from any to $one_address pass in quick from any to { 10.11.11.11 $one_address } pass in quick from any to { 10.12.12.12 $one_address} pass in quick from any to { 10.13.13.13, $one_address } pass in quick from any to { $one_address 10.14.14.14 } pass in quick from any to {$one_address 10.15.15.15 } pass in quick from any to { $one_address, 10.16.16.16 } pass in quick from any to { $one_address , 10.17.17.17 } pass in quick from any to {$one_address , 10.18.18.18 } pass in quick from any to $addr_list_1 pass in quick from any to $addr_list_2 pass in quick from any to $addr_list_3 pass in quick from any to $addr_list_4 pass in quick from any to $addr_list_5 pass in quick from any to $addr_list_1_foo # test for undefined macro pass in quick from any to $undefined_macro pass out quick on $ext_if proto tcp to $recursive_macro port $tcp_services pass in quick on $ext_if proto tcp from any to $mixed_macro_1 port 80 pass in quick on $ext_if proto tcp from any to $mixed_macro_2 port 80 pass in quick on $ext_if proto tcp from any to $mixed_macro_3 port 80 pass in quick on $ext_if proto tcp from any to $mixed_macro_4 port 80 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-port-matches.conf0000644000175000017500000001026411733011756030510 0ustar sylvestresylvestre port_group = {22, 80, 119, 20} # destination port matches pass in quick proto tcp from any to self port = 22 pass in quick proto tcp from any to self port 22 pass in quick proto tcp from any to self port != 22 pass in quick proto tcp from any to self port < 1024 pass in quick proto tcp from any to self port <= 1024 pass in quick proto tcp from any to self port > 1024 pass in quick proto tcp from any to self port >= 1024 pass in quick proto tcp from any to self port $port_group pass in quick proto tcp from any to self port ssh pass in quick proto tcp from any to self port smtp pass in quick proto tcp from any to self port www pass in quick proto tcp from any to self port https pass in quick proto tcp from any to self port ntp pass in quick proto tcp from any to self port ftp pass in quick proto tcp from any to self port ftp-data pass in quick proto udp from any to self port domain # source port matches pass in quick proto tcp from any port = 22 to self pass in quick proto tcp from any port 22 to self pass in quick proto tcp from any port != 22 to self pass in quick proto tcp from any port < 1024 to self pass in quick proto tcp from any port <= 1024 to self pass in quick proto tcp from any port > 1024 to self pass in quick proto tcp from any port >= 1024 to self pass in quick proto tcp from any port $port_group to self pass in quick proto tcp from any port ssh to self pass in quick proto tcp from any port smtp to self pass in quick proto tcp from any port www to self pass in quick proto tcp from any port https to self pass in quick proto tcp from any port ntp to self pass in quick proto tcp from any port ftp to self pass in quick proto tcp from any port ftp-data to self pass in quick proto udp from any port domain to self # port ranges pass in quick proto tcp from any to self port 1000:1010 pass in quick proto tcp from any to self port 1000><1010 pass in quick proto tcp from any to self port 1000<>1010 pass in quick proto tcp from any port 1000:1010 to self pass in quick proto tcp from any port 1000><1010 to self pass in quick proto tcp from any port 1000<>1010 to self # that difficult port range match pass in quick proto tcp from any to self port 1024:65535 # combined source and destination port matches pass in quick proto tcp from any port 1024:65535 to self port 22 pass in quick proto tcp from any port 1024:65535 to self port != 22 pass in quick proto tcp from any port 1024:65535 to self port < 1024 pass in quick proto tcp from any port 1024:65535 to self port <= 1024 pass in quick proto tcp from any port 1024:65535 to self port > 1024 pass in quick proto tcp from any port 1024:65535 to self port >= 1024 pass in quick proto tcp from any port 1024:65535 to self port 1000:1010 pass in quick proto tcp from any port 1024:65535 to self port 1000><1010 pass in quick proto tcp from any port 1024:65535 to self port 1000<>1010 pass in quick proto tcp from any port > 1024 to self port 22 pass in quick proto tcp from any port > 1024 to self port != 22 pass in quick proto tcp from any port > 1024 to self port < 1024 pass in quick proto tcp from any port > 1024 to self port <= 1024 pass in quick proto tcp from any port > 1024 to self port > 1024 pass in quick proto tcp from any port > 1024 to self port >= 1024 pass in quick proto tcp from any port > 1024 to self port 1000:1010 pass in quick proto tcp from any port > 1024 to self port 1000><1010 pass in quick proto tcp from any port > 1024 to self port 1000<>1010 pass in quick proto tcp from any port > 1024 to self port $port_group pass in quick proto udp from any port { 10001, 10002, 10003 } to \ self port { 20001, 20002, 20003 } pass in quick proto udp from any port { 10001, 10002, 10003 } to \ self port { 20000:20020, 20030:20040 } pass in quick proto udp from any port { 10000:10010, 10030:10040 } to \ self port { 20000:20020, 20030:20040 } pass in quick proto udp from any port { <1024 , >10030 } to \ self port { 20000:20020, 20030:20040 } fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-nat-rules.conf0000644000175000017500000000272411733011756030016 0ustar sylvestresylvestre# nat rules nat on em0 from 192.168.168.0/24 to any -> 192.0.2.111 nat on ! em0 from 192.168.168.0/24 to any -> 192.0.2.111 nat on em0 inet from any to any -> 192.0.2.16/28 bitmask nat on em0 inet from any to any -> 192.0.2.16/28 random nat on em0 inet from any to any -> 192.0.2.16/28 random sticky-address nat on em0 inet from any to any -> 192.0.2.16/28 source-hash nat on em0 inet from any to any -> 192.0.2.16/28 source-hash hex-key nat on em0 inet from any to any -> 192.0.2.16/28 source-hash string-key nat on em0 inet from any to any -> 192.0.2.16/28 round-robin nat on em0 inet from any to any -> 192.0.2.16/28 round-robin sticky-address nat on em0 inet from any to any -> 192.0.2.16/28 static-port nat on em0 inet proto udp from any port 10000 to any -> em0 nat on em0 inet proto udp from any port 10000 to any -> (em0) nat on em0 inet proto udp from any port 10000 to any -> (em0) port 10000 nat on em0 inet proto udp from any port 10000:10010 to any -> (em0) port 10000 nat on em0 inet proto udp from any port 10000:10010 to any -> (em0) port 10000:* nat on em0 inet proto udp from any port 10000 to any -> \ 192.0.2.16/28 port 10000 bitmask nat on em0 inet proto udp from any port 10000:10010 to any -> \ 192.0.2.16/28 port 10000:* bitmask # no nat rule no nat on em0 proto ah from 192.168.1.0/24 to any nat on em0 from 192.168.1.0/24 to any -> 192.0.2.100 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-route-to-4.7.fwb0000644000175000017500000025257411733011756030033 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-state-matches.conf0000644000175000017500000000076411733011756030650 0ustar sylvestresylvestre # state matches pass in quick proto tcp from any to self port = 22 label "no state word" pass in quick proto tcp from any to self port = 22 keep state label "keep state" pass in quick proto tcp from any to self port = 22 no state label "no state" # add modulate state , synproxy and other state-related variants here pass out proto tcp from any to any modulate state pass in proto tcp from any to any port 25 flags S/SFRA modulate state pass in proto tcp from any to any port 80 synproxy state fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-icmp-matches.fwb0000644000175000017500000025574711733011756030326 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-nat-rules.fwb0000644000175000017500000030206211733011756027645 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-state-matches.fwb0000644000175000017500000024420211733011756030476 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-rdr-rules.fwb0000644000175000017500000024514711733011756027664 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-tcp-flags-matches.output0000644000175000017500000000142211733011756032013 0ustar sylvestresylvestre4: filtering rule: action pass; interfaces: 5: filtering rule: action pass; interfaces: 6: filtering rule: action pass; interfaces: 7: filtering rule: action pass; interfaces: 9: filtering rule: action block; interfaces: 9: Error: TCP flag matches 'E' and 'W' are not supported. 10: filtering rule: action block; interfaces: 10: Error: TCP flag matches 'E' and 'W' are not supported. 11: filtering rule: action block; interfaces: 11: Error: TCP flag matches 'E' and 'W' are not supported. 12: filtering rule: action block; interfaces: 12: Error: TCP flag matches 'E' and 'W' are not supported. 13: filtering rule: action block; interfaces: 14: filtering rule: action block; interfaces: Could not find enough information in the data file to create firewall interface objects. fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-nat-rules.output0000644000175000017500000000202311733011756030421 0ustar sylvestresylvestre3: New interface: em0 3: nat rule: action nat; interfaces: em0 4: nat rule: action nat; interfaces: em0 6: nat rule: action nat; interfaces: em0 7: nat rule: action nat; interfaces: em0 8: nat rule: action nat; interfaces: em0 9: nat rule: action nat; interfaces: em0 10: nat rule: action nat; interfaces: em0 10: Error: import of commands with pool type 'source-hash hex-key' option is not supported 11: nat rule: action nat; interfaces: em0 11: Error: import of commands with pool type 'source-hash string-key' option is not supported 12: nat rule: action nat; interfaces: em0 13: nat rule: action nat; interfaces: em0 14: nat rule: action nat; interfaces: em0 16: nat rule: action nat; interfaces: em0 17: nat rule: action nat; interfaces: em0 18: nat rule: action nat; interfaces: em0 19: nat rule: action nat; interfaces: em0 20: nat rule: action nat; interfaces: em0 22: nat rule: action nat; interfaces: em0 23: nat rule: action nat; interfaces: em0 26: nat rule: action nonat; interfaces: em0 27: nat rule: action nat; interfaces: em0 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-tcp-flags-matches.fwb0000644000175000017500000025666611733011756031257 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-route-to.fwb0000644000175000017500000025257411733011756027525 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-scrub-commands-old.output0000644000175000017500000000044611733011756032207 0ustar sylvestresylvestre14: filtering rule: action block; interfaces: Could not find enough information in the data file to create firewall interface objects. scrub fragment reassemble scrub fragment crop scrub fragment drop-ovl scrub reassemble tcp scrub no-df scrub min-ttl 10 scrub max-mss 1470 scrub random-id fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-rdr-rules.conf0000644000175000017500000000076611733011756030027 0ustar sylvestresylvestre# rdr rules rdr on em0 inet proto tcp from any to (em0) port 80 -> 10.0.1.111 port 8080 rdr on em0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080 # pool-type comes after portspec rdr on em0 inet proto tcp from any to (em0) port 80 -> \ { 10.0.1.111, 10.0.1.112, 10.0.1.113 } port 8080 round-robin # no rdr rule no rdr on em0 inet proto tcp from 192.168.1.1 to any port 80 rdr on em0 inet proto tcp from 192.168.1.0/24 to any port 80 -> \ 192.0.2.100 port 8080 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-timeouts.output0000644000175000017500000000126311733011756030365 0ustar sylvestresylvestre12: Parser error: line 12:13: unexpected token: foo 14: filtering rule: action block; interfaces: Could not find enough information in the data file to create firewall interface objects. Configuring timeouts: set timeout interval 10 set timeout frag 30 set timeout tcp.first 60 set timeout tcp.opening 30 set timeout tcp.established 3600 set timeout tcp.closing 30 set timeout tcp.finwait 2 set timeout tcp.closed 10 set timeout udp.first 20 set timeout udp.single 10 set timeout udp.multiple 15 set timeout icmp.first 11 set timeout icmp.error 6 set timeout other.first 40 set timeout other.single 20 set timeout other.multiple 30 set timeout adaptive.start 10 set timeout adaptive.end 5 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-timeouts.conf0000644000175000017500000000074711733011756027760 0ustar sylvestresylvestre # these should be all timeouts we support in 4.3 set timeout interval 10 set timeout frag 30 set timeout { tcp.first 60, tcp.opening 30, tcp.established 3600, tcp.closing 30, tcp.finwait 2, tcp.closed 10 } set timeout { udp.first 20, udp.single 10, udp.multiple 15 } set timeout { icmp.first 11, icmp.error 6 } set timeout { other.first 40, other.single 20, other.multiple 30 } set timeout { adaptive.start 10, adaptive.end 5 } # invalid timeout name set timeout foo 20 block log all fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-block-return-actions.output0000644000175000017500000000335711733011756032567 0ustar sylvestresylvestre5: filtering rule: action block; interfaces: 8: filtering rule: action block; interfaces: 10: filtering rule: action block; interfaces: 10: Error: 'block return' is not supported in fwbuilder, replacing with 'block return-icmp' 11: filtering rule: action block; interfaces: 11: Error: 'block return' is not supported in fwbuilder, replacing with 'block return-icmp' 12: filtering rule: action block; interfaces: 12: Error: 'block return' is not supported in fwbuilder, replacing with 'block return-icmp' 13: filtering rule: action block; interfaces: 13: Error: 'block return' is not supported in fwbuilder, replacing with 'block return-icmp' 14: filtering rule: action block; interfaces: 14: Error: 'block return' is not supported in fwbuilder, replacing with 'block return-icmp' 16: filtering rule: action block; interfaces: 18: filtering rule: action block; interfaces: 20: filtering rule: action block; interfaces: 21: filtering rule: action block; interfaces: 22: filtering rule: action block; interfaces: 23: filtering rule: action block; interfaces: 24: filtering rule: action block; interfaces: 26: filtering rule: action block; interfaces: 27: filtering rule: action block; interfaces: 29: filtering rule: action block; interfaces: 30: filtering rule: action block; interfaces: 32: filtering rule: action block; interfaces: 33: filtering rule: action block; interfaces: 35: filtering rule: action block; interfaces: 36: filtering rule: action block; interfaces: 38: filtering rule: action block; interfaces: 39: filtering rule: action block; interfaces: 41: filtering rule: action block; interfaces: 42: filtering rule: action block; interfaces: Could not find enough information in the data file to create firewall interface objects. fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-set-commands.output0000644000175000017500000000173711733011756031114 0ustar sylvestresylvestre22: Error: import of 'set fingerprints' commands is not supported. 23: Error: import of 'set hostid' commands is not supported. 24: Error: import of 'set loginterface' commands is not supported. 25: Error: import of 'set reassemble' commands is not supported. 26: Error: import of 'set require-order' commands is not supported. 27: Error: import of 'set ruleset-optimization' commands is not supported. 28: Error: import of 'set state-defaults' commands is not supported. 30: filtering rule: action block; interfaces: Could not find enough information in the data file to create firewall interface objects. Configuring limits: set limit frags 5000 set limit states 10000 set limit src-nodes 100000 set limit tables 100000 set limit tables-entries 100000 set optimization high-latency set block-policy return set state-policy if-bound New interface: lo0set skip on lo0 New interface: em0set skip on em0 New interface: pcn0set skip on pcn0 New interface: pcn1set skip on pcn1 set debug crit fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-hosts-matches.output0000644000175000017500000000422411733011756031276 0ustar sylvestresylvestre2: Address Table: : 10.123.12.32/27, 10.123.14.8/27, 10.123.10.16/28, 10.123.0.0/24 5: Address Table: : 192.168.1.1, 192.168.1.2, 192.168.2.0/24 6: Address Table: : pcn0, pcn0 6: New interface: pcn0 7: Address Table: : pcn0, pcn0 8: Address Table: : www.fwbuilder.org, www.netcitadel.com 11: filtering rule: action pass; interfaces: 12: filtering rule: action pass; interfaces: 12: Error: import of 'interface:broadcast' is not supported. 13: filtering rule: action pass; interfaces: 13: Error: import of 'interface:peer' is not supported. 14: filtering rule: action pass; interfaces: 14: Error: import of 'interface:0' is not supported. 16: filtering rule: action pass; interfaces: 17: filtering rule: action pass; interfaces: 18: filtering rule: action pass; interfaces: 19: filtering rule: action pass; interfaces: 20: filtering rule: action pass; interfaces: 21: filtering rule: action pass; interfaces: 22: filtering rule: action pass; interfaces: 23: filtering rule: action pass; interfaces: 24: filtering rule: action pass; interfaces: 25: filtering rule: action pass; interfaces: 26: filtering rule: action pass; interfaces: 27: filtering rule: action pass; interfaces: 28: filtering rule: action pass; interfaces: 30: filtering rule: action pass; interfaces: 30: Error: IPv6 import is not supported. 31: filtering rule: action pass; interfaces: 33: filtering rule: action pass; interfaces: 34: filtering rule: action pass; interfaces: 35: filtering rule: action pass; interfaces: 36: filtering rule: action pass; interfaces: 37: filtering rule: action pass; interfaces: 38: filtering rule: action pass; interfaces: 39: filtering rule: action pass; interfaces: 40: filtering rule: action pass; interfaces: 41: filtering rule: action pass; interfaces: 42: filtering rule: action pass; interfaces: 43: filtering rule: action pass; interfaces: 44: filtering rule: action pass; interfaces: 45: filtering rule: action pass; interfaces: 47: filtering rule: action pass; interfaces: 47: Error: IPv6 import is not supported. 48: filtering rule: action pass; interfaces: fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-rdr-rules.output0000644000175000017500000000034711733011756030435 0ustar sylvestresylvestre3: New interface: em0 3: nat rule: action rdr; interfaces: em0 5: nat rule: action rdr; interfaces: em0 8: nat rule: action rdr; interfaces: em0 11: nat rule: action nonat; interfaces: em0 12: nat rule: action rdr; interfaces: em0 fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-scrub-commands-new.conf0000644000175000017500000000041711733011756031605 0ustar sylvestresylvestre # supported commands for PF v4.6 and newer match all scrub ( reassemble tcp ) match all scrub ( no-df ) match out all scrub ( min-ttl 10 ) match out all scrub ( max-mss 1470 ) match out all scrub ( random-id ) match in all scrub (no-df max-mss 1440) block log all fwbuilder-5.1.0.3599/src/unit_tests/PFImporterTest/test_data/pf-macros.output0000644000175000017500000000355711733011756030010 0ustar sylvestresylvestreWarning: Macro undefined_macro is undefined3: Address Table: : 10.123.12.32/27, 10.123.14.8/27, 10.123.10.16/28, 10.123.0.0/24 5: Address Table: : 10.1.1.1, 10.123.12.32/27, 10.123.14.8/27, 10.123.10.16/28, 10.123.0.0/24 7: Address Table: : 10.1.1.1, 10.123.12.33/27, 10.123.14.9/27 9: Address Table: : 10.1.1.1, 10.123.12.34/27, 10.123.14.10/27 12: Address Table: : 10.1.1.1, 10.123.12.35/27, 10.123.14.11/27 15: Address Table: : 10.1.2.3, 10.4.5.6, 10.7.8.9 19: Address Table: : 192.168.1.1, 192.168.1.2 23: Address Table: : 192.168.1.1, 192.168.2.1, www.fwbuilder.org 24: Address Table: : 192.168.1.1, 192.168.2.1, em1 24: New interface: em1 25: Address Table: : 192.168.1.1, 192.168.2.1, em1 31: filtering rule: action pass; interfaces: 33: filtering rule: action pass; interfaces: 34: filtering rule: action pass; interfaces: 35: filtering rule: action pass; interfaces: 36: filtering rule: action pass; interfaces: 37: filtering rule: action pass; interfaces: 38: filtering rule: action pass; interfaces: 39: filtering rule: action pass; interfaces: 40: filtering rule: action pass; interfaces: 42: filtering rule: action pass; interfaces: 43: filtering rule: action pass; interfaces: 44: filtering rule: action pass; interfaces: 45: filtering rule: action pass; interfaces: 46: filtering rule: action pass; interfaces: 47: filtering rule: action pass; interfaces: 50: filtering rule: action pass; interfaces: 50: Warning: Macro '$undefined_macro' was undefined, rule may be broken 52: filtering rule: action pass; interfaces: em1 54: filtering rule: action pass; interfaces: em1 55: filtering rule: action pass; interfaces: em1 56: filtering rule: action pass; interfaces: em1 57: filtering rule: action pass; interfaces: em1 fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/0000755000175000017500000000000011733011756023010 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/.gitignore0000644000175000017500000000002711733011756024777 0ustar sylvestresylvestre*.fwb !test_data/*.fwb fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/main_PIXImporterTest.cpp0000644000175000017500000000331011733011756027537 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "PIXImporterTest.h" #include "fwbuilder/Resources.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" #include #include #include #include "../../../common/init.cpp" int fwbdebug = 0; //QString user_name; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; std::string platform; int main(int argc, char** argv) { QApplication app(argc, argv, false); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( PIXImporterTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/PIXImporterTest.cpp0000644000175000017500000002713411733011756026545 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PIXImporterTest.h" #include "config.h" #include "global.h" #include #include #include #include #include #include #include "Importer.h" #include "PIXImporter.h" #include "FWBTree.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; extern string platform; extern QString findBestVersionMatch(const QString &platform, const QString &discovered_version); class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string &) const { return false; } }; void PIXImporterTest::setUp() { FWBTree *tree = new FWBTree(); /* create database */ db = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; db->setReadOnly( false ); db->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); db->setFileName(""); lib = Library::cast(tree->createNewLibrary(db)); lib->setName("User"); logger = new QueueLogger(); // this makes the test compile and link. There is a problem with // dependencies, the test depends on libimport.a and additionally, // PIXImporter.cpp depends on this function that is implemented in // platforms.cpp in libgui.a; however since libgui.a comes before // libimport.a in linker command line, this function does not get // pulled since it is not used anywhere except by this test module // and so linking fails. Making this call creates dependency and // pulls this function at linking time before libimport.a and its // dependencies are considered QString version = findBestVersionMatch("pix", "7.0"); } void PIXImporterTest::compareResults(QueueLogger* logger, QString expected_result_file_name, QString obtained_result_file_name) { QString result; QStringList obtained_result; while (logger->ready()) result.append(logger->getLine().c_str()); obtained_result = result.split("\n"); QFile rw(obtained_result_file_name); rw.open(QFile::WriteOnly); rw.write(result.toAscii()); rw.close(); QFile rr(expected_result_file_name); rr.open(QFile::ReadOnly); QString result_file = rr.readAll(); QStringList expected_result = result_file.split("\n"); CPPUNIT_ASSERT_MESSAGE( QString( "Sizes of the generated importer output and test files are different.\n" "Expected: %1 (%2)\n" "Obtained: %3 (%4)\n" "diff -u %1 %3 | less -S") .arg(expected_result_file_name).arg(expected_result.size()) .arg(obtained_result_file_name).arg(obtained_result.size()).toStdString(), expected_result.size() == obtained_result.size()); int max_idx = max(expected_result.size(), obtained_result.size()); for (int i=0; i < max_idx; ++i) { QString err = QString("Line %1:\nExpected: '%2'\nResult: '%3'\n") .arg(i).arg(expected_result[i]).arg(obtained_result[i]); CPPUNIT_ASSERT_MESSAGE(err.toStdString(), obtained_result[i] == expected_result[i]); } } void PIXImporterTest::compareFwbFiles(QString expected_result_file_name, QString obtained_result_file_name) { QString result; QStringList obtained_result; QFile rr(obtained_result_file_name); rr.open(QFile::ReadOnly); QString result_file = rr.readAll(); rr.close(); obtained_result = result_file.split("\n"); QFile er(expected_result_file_name); er.open(QFile::ReadOnly); result_file = er.readAll(); er.close(); QStringList expected_result = result_file.split("\n"); // find all lastModified attributes and replace them with identical values // because they are always going to be different QString err("Sizes of the generated .fwb and test files are different: \n" "Expected: %1 (%2)\n" "Obtained: %3 (%4)\n" "diff -u %1 %3 | less -S"); CPPUNIT_ASSERT_MESSAGE( err .arg(expected_result_file_name).arg(expected_result.size()) .arg(obtained_result_file_name).arg(obtained_result.size()) .toStdString(), expected_result.size() == obtained_result.size()); QRegExp last_mod_re("lastModified=\"\\d+\""); int max_idx = max(expected_result.size(), obtained_result.size()); for (int i=0; i < max_idx; ++i) { QString os = obtained_result[i]; obtained_result[i] = os.replace(last_mod_re, "lastModified=\"0000000000\""); QString es = expected_result[i]; expected_result[i] = es.replace(last_mod_re, "lastModified=\"0000000000\""); } for (int i=0; i < max_idx; ++i) { QString err = QString("Line %1:\nExpected: '%2'\nResult: '%3'\n") .arg(i).arg(expected_result[i]).arg(obtained_result[i]); CPPUNIT_ASSERT_MESSAGE(err.toStdString(), obtained_result[i] == expected_result[i]); } } std::string PIXImporterTest::openTestFile(const QString &file_name) { QFile f(file_name); f.open(QFile::ReadOnly); string buffer = QString(f.readAll()).toStdString(); f.close(); return buffer; } void PIXImporterTest::PIX_6_Test() { platform = "pix"; std::istringstream instream(openTestFile("test_data/pix6.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pix6.fwb"); compareResults(logger, "test_data/pix6.output", "pix6.output"); compareFwbFiles("test_data/pix6.fwb", "pix6.fwb"); } void PIXImporterTest::PIX_7_Test() { platform = "pix"; std::istringstream instream(openTestFile("test_data/pix7.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pix7.fwb"); compareResults(logger, "test_data/pix7.output", "pix7.output"); compareFwbFiles("test_data/pix7.fwb", "pix7.fwb"); } void PIXImporterTest::PIX_7_NAT_Test() { platform = "pix"; std::istringstream instream(openTestFile("test_data/pix7-nat.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("pix7-nat.fwb"); compareResults(logger, "test_data/pix7-nat.output", "pix7-nat.output"); compareFwbFiles("test_data/pix7-nat.fwb", "pix7-nat.fwb"); } void PIXImporterTest::ASA_8_0_Test() { platform = "pix"; std::istringstream instream(openTestFile("test_data/asa8.0.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("asa8.0.fwb"); compareResults(logger, "test_data/asa8.0.output", "asa8.0.output"); compareFwbFiles("test_data/asa8.0.fwb", "asa8.0.fwb"); } void PIXImporterTest::ASA_8_3_Test() { platform = "pix"; std::istringstream instream(openTestFile("test_data/asa8.3.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("asa8.3.fwb"); compareResults(logger, "test_data/asa8.3.output", "asa8.3.output"); compareFwbFiles("test_data/asa8.3.fwb", "asa8.3.fwb"); } void PIXImporterTest::ObjectsAndGroupsTest() { platform = "pix"; std::istringstream instream(openTestFile("test_data/asa8.3-objects-and-groups.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("asa8.3-objects-and-groups.fwb"); compareResults(logger, "test_data/asa8.3-objects-and-groups.output", "asa8.3-objects-and-groups.output"); compareFwbFiles("test_data/asa8.3-objects-and-groups.fwb", "asa8.3-objects-and-groups.fwb"); } void PIXImporterTest::ACLObjectsAndGroupsTest() { platform = "pix"; std::istringstream instream(openTestFile("test_data/asa8.3-acl-object-groups.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("asa8.3-acl-object-groups.fwb"); compareResults(logger, "test_data/asa8.3-acl-object-groups.output", "asa8.3-acl-object-groups.output"); compareFwbFiles("test_data/asa8.3-acl-object-groups.fwb", "asa8.3-acl-object-groups.fwb"); } void PIXImporterTest::ACLTest() { platform = "pix"; std::istringstream instream(openTestFile("test_data/asa8.3-acl.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("asa8.3-acl.fwb"); compareResults(logger, "test_data/asa8.3-acl.output", "asa8.3-acl.output"); compareFwbFiles("test_data/asa8.3-acl.fwb", "asa8.3-acl.fwb"); } void PIXImporterTest::NamesTest() { platform = "pix"; std::istringstream instream(openTestFile("test_data/asa8.0-names.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("asa8.0-names.fwb"); compareResults(logger, "test_data/asa8.0-names.output", "asa8.0-names.output"); compareFwbFiles("test_data/asa8.0-names.fwb", "asa8.0-names.fwb"); } void PIXImporterTest::FWSM_4_1_Test() { std::istringstream instream(openTestFile("test_data/fwsm1.test")); Importer* imp = new PIXImporter(lib, instream, logger, "test_fw"); imp->setAddStandardCommentsFlag(true); CPPUNIT_ASSERT_NO_THROW( imp->run() ); imp->finalize(); db->setPredictableIds(); db->saveFile("fwsm1.fwb"); compareResults(logger, "test_data/fwsm1.output", "fwsm1.output"); compareFwbFiles("test_data/fwsm1.fwb", "fwsm1.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/0000755000175000017500000000000011733011756024760 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3.fwb0000644000175000017500000025066611733011756026474 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix6.fwb0000644000175000017500000043061211733011756026354 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3.output0000644000175000017500000000416411733011756027244 0ustar sylvestresylvestre3: Platform: ASA 3: Version: 8.3 14: New interface: Vlan1 14: Interface comment: inside interface 15: Interface parameters: inside 15: Interface label: inside 17: Interface address: dhcp/ 20: New interface: Vlan2 20: Interface comment: outside interface 21: Interface parameters: outside 21: Interface label: outside 23: Interface address: 192.168.2.1/255.255.255.0 26: New interface: Ethernet0/0 26: Interface comment: Switch port 0 / 0 27: Switch port vlan 2 30: New interface: Vlan2020 35: New interface: Ethernet0/1 Warning: interface Ethernet0/1 was not imported because it is in "shutdown" mode 37: New interface: Ethernet0/2 Warning: interface Ethernet0/2 was not imported because it is in "shutdown" mode 39: New interface: Ethernet0/3 Warning: interface Ethernet0/3 was not imported because it is in "shutdown" mode 41: New interface: Ethernet0/4 Warning: interface Ethernet0/4 was not imported because it is in "shutdown" mode 43: New interface: Ethernet0/5 Warning: interface Ethernet0/5 was not imported because it is in "shutdown" mode 45: New interface: Ethernet0/6 Warning: interface Ethernet0/6 was not imported because it is in "shutdown" mode 47: New interface: Ethernet0/7 Warning: interface Ethernet0/7 was not imported because it is in "shutdown" mode 53: Named object (address) internal_subnet_1 56: Named object (address) internal_subnet_2 59: Named object (address) Internal_net 61: Named object (address) hostA:eth0 65: filtering rule: access list outside_acl_in, action deny 84: Interface Vlan1 ruleset http_commands_inside direction 'in' 84: filtering rule: access list http_commands_inside, action permit 85: Interface Vlan1 ruleset http_commands_inside direction 'in' 85: filtering rule: access list http_commands_inside, action permit 86: Interface Vlan1 ruleset http_commands_inside direction 'in' 86: filtering rule: access list http_commands_inside, action permit 95: Interface Vlan1 ruleset ssh_commands_inside direction 'in' 95: filtering rule: access list ssh_commands_inside, action permit 96: Interface Vlan1 ruleset ssh_commands_inside direction 'in' 96: filtering rule: access list ssh_commands_inside, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix6.output0000644000175000017500000001730311733011756027134 0ustar sylvestresylvestre3: Platform: PIX 3: Version: 6.3 4: New interface: ethernet0 5: New interface: ethernet1 5: Interface parameters: ethernet0 outside security0 5: Interface parameters: ethernet1 inside security100 34: Object Group (icmp) inside.id12349X2458.srv.icmp.0 38: Object Group (icmp) outside.id12363X2458.srv.icmp.0 43: Object Group (service) outside.id12376X2458.srv.udp.0 46: Object Group (service) outside.id12438X2458.srv.tcp.0 49: Object Group (service) outside.id12466X2458.srv.tcp.0 52: Rule comment: 0 ( ethernet0 ) 53: filtering rule: access list outside_acl_in, action deny 54: filtering rule: access list outside_acl_in, action deny 55: Rule comment: 3 ( global ) 56: filtering rule: access list outside_acl_in, action permit 57: filtering rule: access list outside_acl_in, action permit 58: Rule comment: 4 ( global ) 59: Rule comment: fw uses DHCP 60: Rule comment: plus many DHCP requests 61: Rule comment: from cable modem 62: filtering rule: access list outside_acl_in, action permit 63: filtering rule: access list outside_acl_in, action permit 64: Rule comment: 6 ( global ) 65: filtering rule: access list outside_acl_in, action deny 66: Rule comment: 7 ( global ) 67: filtering rule: access list outside_acl_in, action permit 68: Rule comment: 10 ( global ) 69: Rule comment: using swatch to automatically 70: Rule comment: block probing ssh connections , so no 71: Rule comment: need to limit 72: filtering rule: access list outside_acl_in, action permit 73: filtering rule: access list outside_acl_in, action permit 74: filtering rule: access list outside_acl_in, action permit 75: Rule comment: 11 ( global ) 76: filtering rule: access list outside_acl_in, action permit 77: filtering rule: access list outside_acl_in, action permit 78: filtering rule: access list outside_acl_in, action permit 79: Rule comment: 17 ( global ) 80: filtering rule: access list outside_acl_in, action permit 81: filtering rule: access list outside_acl_in, action permit 82: Rule comment: 19 ( global ) 83: Rule comment: ' catch all' rule 84: filtering rule: access list outside_acl_in, action deny 85: Rule comment: 1 ( global ) 86: filtering rule: access list inside_acl_in, action permit 87: filtering rule: access list inside_acl_in, action permit 88: Rule comment: 2 ( global ) 89: filtering rule: access list inside_acl_in, action permit 90: filtering rule: access list inside_acl_in, action permit 91: Rule comment: 3 ( global ) 92: filtering rule: access list inside_acl_in, action permit 93: Rule comment: 5 ( global ) 94: filtering rule: access list inside_acl_in, action permit 95: Rule comment: 6 ( global ) 96: filtering rule: access list inside_acl_in, action deny 97: Rule comment: 7 ( global ) 98: filtering rule: access list inside_acl_in, action permit 99: Rule comment: 10 ( global ) 100: Rule comment: using swatch to automatically 101: Rule comment: block probing ssh connections , so no 102: Rule comment: need to limit 103: filtering rule: access list inside_acl_in, action permit 104: Rule comment: 11 ( global ) 105: filtering rule: access list inside_acl_in, action permit 106: Rule comment: 17 ( global ) 107: filtering rule: access list inside_acl_in, action permit 108: filtering rule: access list inside_acl_in, action permit 109: Rule comment: 18 ( global ) 110: filtering rule: access list inside_acl_in, action permit 111: Rule comment: 19 ( global ) 112: Rule comment: ' catch all' rule 113: filtering rule: access list inside_acl_in, action deny 114: filtering rule: access list id12594X2458.0, action permit 115: filtering rule: access list id12594X2458.1, action permit 116: filtering rule: access list id12594X2458.2, action permit 117: filtering rule: access list id12594X2458.3, action permit 118: filtering rule: access list id12626X2458.0, action permit 119: filtering rule: access list id12626X2458.1, action permit 120: filtering rule: access list id12626X2458.2, action permit 121: filtering rule: access list id12642X2458.0, action permit 122: filtering rule: access list id12656X2458.0, action permit 123: filtering rule: access list id12670X2458.0, action permit 124: filtering rule: access list id12684X2458.0, action permit 125: filtering rule: access list id12743X2458.0, action permit 136: Interface ethernet0 ruleset icmp_commands_outside direction 'in' 136: filtering rule: access list icmp_commands_outside, action permit 137: Interface ethernet0 ruleset icmp_commands_outside direction 'in' 137: filtering rule: access list icmp_commands_outside, action permit 138: Interface ethernet0 ruleset icmp_commands_outside direction 'in' 138: filtering rule: access list icmp_commands_outside, action permit 139: Interface ethernet0 ruleset icmp_commands_outside direction 'in' 139: filtering rule: access list icmp_commands_outside, action permit 140: Interface ethernet0 ruleset icmp_commands_outside direction 'in' 140: filtering rule: access list icmp_commands_outside, action permit 141: Interface ethernet0 ruleset icmp_commands_outside direction 'in' 141: filtering rule: access list icmp_commands_outside, action permit 142: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 142: filtering rule: access list icmp_commands_inside, action permit 143: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 143: filtering rule: access list icmp_commands_inside, action permit 144: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 144: filtering rule: access list icmp_commands_inside, action permit 145: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 145: filtering rule: access list icmp_commands_inside, action permit 146: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 146: filtering rule: access list icmp_commands_inside, action permit 147: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 147: filtering rule: access list icmp_commands_inside, action permit 148: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 148: filtering rule: access list icmp_commands_inside, action permit 149: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 149: filtering rule: access list icmp_commands_inside, action permit 150: Interface ethernet1 ruleset icmp_commands_inside direction 'in' 150: filtering rule: access list icmp_commands_inside, action permit 152: Interface ethernet1 ruleset telnet_commands_inside direction 'in' 152: filtering rule: access list telnet_commands_inside, action permit 154: Interface ethernet1 ruleset ssh_commands_inside direction 'in' 154: filtering rule: access list ssh_commands_inside, action permit 155: Interface ethernet1 ruleset ssh_commands_inside direction 'in' 155: filtering rule: access list ssh_commands_inside, action permit 155: Interface address: dhcp/ 155: Interface address: 10.1.1.202/255.255.255.0 166: Global address pool: number 1, interface outside, address range interface-interface, netmask 255.255.255.255 167: Source translation rule ("nat" command) 168: Destination translation rule ("static" command) 169: Destination translation rule ("static" command) 170: Destination translation rule ("static" command) 171: Destination translation rule ("static" command) 172: Destination translation rule ("static" command) 173: Destination translation rule ("static" command) 174: Destination translation rule ("static" command) 175: Destination translation rule ("static" command) 176: Destination translation rule ("static" command) 177: Interface ethernet0 ruleset outside_acl_in direction 'in' 178: Interface ethernet1 ruleset inside_acl_in direction 'in' 196: Interface ethernet1 ruleset http_commands_inside direction 'in' 196: filtering rule: access list http_commands_inside, action permit 197: Interface ethernet1 ruleset http_commands_inside direction 'in' 197: filtering rule: access list http_commands_inside, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/fwsm1.test0000644000175000017500000000371511733011756026724 0ustar sylvestresylvestre: Saved : FWSM Version 4.1(4) ! hostname fwb domain-name default.domain.invalid enable password xxxxxxxxxxxxxxx encrypted names dns-guard ! interface Vlan350 description management nameif vlan0350 security-level 100 ip address 192.0.2.1 255.255.255.0 management-only ! interface Vlan351 nameif vlan0351 security-level 0 no ip address ! interface Vlan352 nameif vlan0352 security-level 0 no ip address ! interface Vlan353 nameif vlan0353 security-level 0 no ip address ! interface Vlan354 nameif vlan0354 security-level 0 no ip address ! passwd yyyyyyyyyyyyyyyy encrypted pager lines 24 logging enable logging asdm informational mtu vlan0350 1500 mtu vlan0351 1500 mtu vlan0352 1500 mtu vlan0353 1500 mtu vlan0354 1500 icmp permit any vlan0350 no asdm history enable arp timeout 14400 timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02 timeout sunrpc 0:10:00 h323 1:00:00 h225 1:00:00 mgcp 0:05:00 timeout mgcp-pat 0:05:00 sip 0:30:00 sip_media 0:02:00 timeout sip-invite 0:03:00 sip-disconnect 0:02:00 timeout pptp-gre 0:02:00 timeout uauth 0:05:00 absolute username netcitadel password MMMMMMMMMMMMMMMM encrypted privilege 15 aaa authentication enable console LOCAL aaa authentication http console LOCAL aaa authentication ssh console LOCAL aaa authorization command LOCAL http server enable http 192.0.2.0 255.255.255.0 vlan0350 no snmp-server location no snmp-server contact telnet timeout 5 ssh 192.0.2.0 255.255.255.0 vlan0350 ssh timeout 5 ssh version 2 ! class-map inspection_default match default-inspection-traffic ! ! policy-map global_policy class inspection_default inspect dns maximum-length 512 inspect ftp inspect h323 h225 inspect h323 ras inspect netbios inspect rsh inspect skinny inspect smtp inspect sqlnet inspect sunrpc inspect tftp inspect sip inspect xdmcp ! service-policy global_policy global Cryptochecksum:34b2ef08671bc98ed1d598733ed72e73 : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-acl.fwb0000644000175000017500000052614111733011756027223 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3.test0000755000175000017500000000716511733011756026672 0ustar sylvestresylvestre: Saved : ASA Version 8.3(2) ! hostname asa5505 enable password XXXXXXXXXXXXXXXX encrypted passwd YYYYYYYYYYYYYYYY encrypted names name 1.2.3.4 gw name 192.168.3.0 fake_network name 192.168.4.1 inside_ip name 2001:0db8:85a3:0000:0000:8a2e:0370:7334 some_ipv6_address ! interface Vlan1 description inside interface nameif inside security-level 100 ip address dhcp setroute ! interface Vlan2 description outside interface nameif outside security-level 0 ip address 192.168.2.1 255.255.255.0 ! interface Ethernet0/0 description Switch port 0/0 switchport access vlan 2 ! interface Vlan2020 no nameif no security-level no ip address ! interface Ethernet0/1 ! interface Ethernet0/2 ! interface Ethernet0/3 ! interface Ethernet0/4 ! interface Ethernet0/5 ! interface Ethernet0/6 ! interface Ethernet0/7 ! boot system disk0:/asa832-k8.bin ftp mode passive ! object network internal_subnet_1 subnet 192.168.1.0 255.255.255.192 description Internal Subnet 1 object network internal_subnet_2 subnet 192.168.1.64 255.255.255.192 description Internal Subnet 2 object network Internal_net subnet 192.168.1.0 255.255.255.0 object network hostA:eth0 host 192.168.1.10 access-list outside_acl_in extended deny ip any any log pager lines 24 logging enable logging buffered errors logging asdm informational mtu inside 1500 mtu outside 1500 icmp unreachable rate-limit 1 burst-size 1 no asdm history enable arp timeout 14400 timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02 timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00 timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00 timeout sip-provisional-media 0:02:00 uauth 0:05:00 absolute timeout tcp-proxy-reassembly 0:01:00 dynamic-access-policy-record DfltAccessPolicy aaa authentication ssh console LOCAL http server enable http 192.168.1.0 255.255.255.0 inside http 10.0.0.0 255.255.255.0 inside http 10.1.1.1 255.255.255.255 inside no snmp-server location no snmp-server contact snmp-server enable traps snmp authentication linkup linkdown coldstart service resetinbound interface outside crypto ipsec security-association lifetime seconds 28800 crypto ipsec security-association lifetime kilobytes 4608000 telnet timeout 5 ssh scopy enable ssh 10.10.10.0 255.255.255.0 inside ssh 10.1.1.0 255.255.255.0 inside ssh timeout 30 ssh version 2 console timeout 0 threat-detection basic-threat threat-detection statistics access-list no threat-detection statistics tcp-intercept webvpn username foo password AAAAAAAAAAAAAAAA encrypted privilege 15 ! class-map inspection_default match default-inspection-traffic ! ! policy-map global_policy class inspection_default inspect ctiqbe inspect dns inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect icmp inspect ils inspect mgcp inspect rsh inspect rtsp inspect sip inspect skinny inspect esmtp inspect sqlnet inspect tftp policy-map type inspect ip-options ip-options-map parameters eool action allow nop action allow router-alert action allow ! service-policy global_policy global prompt hostname context call-home profile CiscoTAC-1 no active destination address http https://tools.cisco.com/its/service/oddce/services/DDCEService destination address email callhome@cisco.com destination transport-method http subscribe-to-alert-group diagnostic subscribe-to-alert-group environment subscribe-to-alert-group inventory periodic monthly subscribe-to-alert-group configuration periodic monthly subscribe-to-alert-group telemetry periodic daily Cryptochecksum:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.0.fwb0000644000175000017500000031731311733011756026462 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix7.output0000644000175000017500000000541411733011756027135 0ustar sylvestresylvestre3: Platform: PIX 3: Version: 7.2 16: New interface: Ethernet0 21: New interface: Ethernet0.101 22: Interface parameters: outside 22: Interface label: outside 24: Interface address: 192.0.2.253/255.255.255.0 27: New interface: Ethernet0.102 28: Interface parameters: dmz20 28: Interface label: dmz20 30: Interface address: 10.0.0.253/255.255.255.0 30: Warning: failover IP detected. Failover is not supported by import at this time 33: New interface: Ethernet1 35: Interface parameters: inside 35: Interface label: inside 37: Interface address: 10.1.1.206/255.255.255.0 40: New interface: Ethernet2 40: Interface comment: LAN/STATE Failover Interface 44: New interface: Ethernet3 Warning: interface Ethernet3 was not imported because it is in "shutdown" mode 50: New interface: Ethernet4 Warning: interface Ethernet4 was not imported because it is in "shutdown" mode 56: New interface: Ethernet5 Warning: interface Ethernet5 was not imported because it is in "shutdown" mode 62: New interface: Ethernet6 Warning: interface Ethernet6 was not imported because it is in "shutdown" mode 70: Object Group (network) outside.id12051X6282.src.net.0 73: Object Group (network) outside.id12051X6282.src.net.1 78: Object Group (network) outside.id12051X6282.src.net.2 81: filtering rule: access list outside_in, action deny 82: filtering rule: access list outside_in, action deny 83: filtering rule: access list outside_in, action deny 84: filtering rule: access list outside_in, action deny 85: filtering rule: access list inside_out, action permit 86: filtering rule: access list inside_out, action permit 87: filtering rule: access list inside_out, action permit 88: filtering rule: access list inside_out, action permit 89: filtering rule: access list inside_out, action deny 90: filtering rule: access list inside_in, action deny 91: filtering rule: access list inside_in, action deny 92: filtering rule: access list inside_in, action deny 93: filtering rule: access list inside_in, action permit 94: filtering rule: access list inside_in, action deny 95: filtering rule: access list id12251X6282.0, action permit 97: Interface Ethernet1 ruleset inside_in direction 'in' 98: Interface Ethernet0.101 ruleset outside_in direction 'in' 123: Interface Ethernet0.101 ruleset outside_in direction 'in' 124: Interface Ethernet1 ruleset inside_in direction 'in' 125: Interface Ethernet1 ruleset inside_out direction 'out' 164: Interface Ethernet1 ruleset ssh_commands_inside direction 'in' 164: filtering rule: access list ssh_commands_inside, action permit 165: Interface Ethernet1 ruleset ssh_commands_inside direction 'in' 165: filtering rule: access list ssh_commands_inside, action permit 166: Interface Ethernet0.101 ruleset ssh_commands_outside direction 'in' 166: filtering rule: access list ssh_commands_outside, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.0.test0000644000175000017500000000761611733011756026665 0ustar sylvestresylvestre: Saved : PIX Version 8.0(3) ! hostname pixfirewall enable password XXXXXXXXXXXXXXXX encrypted names ! interface Ethernet0 nameif inside security-level 100 ip address 192.168.2.221 255.255.255.0 ! interface Ethernet1 nameif outside security-level 0 ip address 192.0.2.221 255.255.255.0 ! interface Ethernet2 shutdown no nameif no security-level no ip address ! interface Ethernet3 shutdown no nameif no security-level no ip address ! interface Ethernet4 shutdown no nameif no security-level no ip address ! passwd YYYYYYYYYYYYYYYY encrypted ftp mode passive object-group network net-1 description single network object-group network-object 192.168.2.0 255.255.255.0 object-group network net-2 description multiple network-object objects network-object 192.168.1.0 255.255.255.0 network-object 192.168.2.0 255.255.255.0 network-object 192.168.3.0 255.255.255.0 object-group network host-1 network-object host 192.168.1.5 object-group network mixed-1 description mix of objects network-objects host objects network-object host 192.168.1.5 network-object 172.16.0.0 255.255.0.0 network-object host 172.16.15.12 network-object 10.0.0.0 255.0.0.0 object-group network host-2 network-object host 172.16.15.1 network-object host 172.16.15.2 object-group service tcp-1 service-object tcp eq www object-group service mixed-service-1 description mix of service tcp & udp objects service-object tcp eq https service-object udp eq dnsix service-object tcp eq domain service-object udp eq ntp object-group service service-ranges service-object tcp gt 1024 service-object tcp range 1024 8080 service-object udp eq www service-object udp eq nfs service-object udp lt 8080 service-object udp gt 1024 service-object udp range www 101 service-object tcp lt 65535 object-group icmp-object icmp-1 icmp-object echo-reply object-group icmp-object icmp-2 description multiple icmp-objects icmp-object 1 icmp-object redirect icmp-object router-advertisement object-group icmp-object icmp-3 object-group protocol protocol-1 protocol-object ip protocol-object igmp object-group protocol proto-icmp protocol-object icmp object-group protocol proto-icmp6 protocol-object icmp6 object-group protocol proto-ip protocol-object ip object-group protocol proto-ipsec protocol-object esp object-group protocol proto-pptp protocol-object gre object-group protocol proto-snp protocol-object snp object-group protocol proto-tcp protocol-object tcp object-group protocol proto-udp protocol-object udp pager lines 24 mtu inside 1500 mtu outside 1500 icmp unreachable rate-limit 1 burst-size 1 icmp permit any echo outside icmp permit any 111 outside icmp permit any time-exceeded outside icmp permit any echo-reply outside icmp permit any unreachable outside icmp permit any outside icmp permit host 10.1.1.202 time-exceeded inside icmp permit host 10.1.1.202 echo-reply inside icmp permit host 10.1.1.202 unreachable inside icmp permit any echo inside icmp permit any time-exceeded inside icmp permit any echo-reply inside icmp permit any unreachable inside icmp permit any inside icmp permit 10.1.1.0 255.255.255.0 inside no asdm history enable arp timeout 14400 timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02 timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00 timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00 timeout uauth 0:05:00 absolute dynamic-access-policy-record DfltAccessPolicy no snmp-server location no snmp-server contact snmp-server enable traps snmp authentication linkup linkdown coldstart telnet 192.168.2.0 255.255.255.0 inside telnet timeout 5 ssh 192.168.2.0 255.255.255.0 inside ssh timeout 5 console timeout 0 threat-detection basic-threat threat-detection statistics access-list username cisco password ZZZZZZZZZZZZZZZZ encrypted ! ! prompt hostname context Cryptochecksum:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-objects-and-groups.fwb0000644000175000017500000037562511733011756032203 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.0-names.output0000644000175000017500000000645211733011756030344 0ustar sylvestresylvestre3: Platform: PIX 3: Version: 8.0 14: New interface: Ethernet0 14: Interface parameters: inside 14: Interface label: inside 16: Interface address: 192.168.2.221/255.255.255.0 19: New interface: Ethernet1 19: Interface parameters: outside 19: Interface label: outside 21: Interface address: 192.0.2.221/255.255.255.0 24: New interface: Ethernet2 Warning: interface Ethernet2 was not imported because it is in "shutdown" mode 30: New interface: Ethernet3 Warning: interface Ethernet3 was not imported because it is in "shutdown" mode 36: New interface: Ethernet4 Warning: interface Ethernet4 was not imported because it is in "shutdown" mode 44: Object Group (network) net_1_group 47: Object Group (network) another_group_net_1 50: Object Group (network) host_net_1 53: Object Group (network) host_net_2 56: Object Group (network) net-1 59: Object Group (network) net-2 65: filtering rule: access list inside_in, action permit 66: filtering rule: access list inside_in, action deny 68: Interface Ethernet0 ruleset inside_in direction 'in' 74: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 74: filtering rule: access list icmp_commands_outside, action permit 75: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 75: filtering rule: access list icmp_commands_outside, action permit 76: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 76: filtering rule: access list icmp_commands_outside, action permit 77: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 77: filtering rule: access list icmp_commands_outside, action permit 78: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 78: filtering rule: access list icmp_commands_outside, action permit 79: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 79: filtering rule: access list icmp_commands_outside, action permit 80: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 80: filtering rule: access list icmp_commands_inside, action permit 81: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 81: filtering rule: access list icmp_commands_inside, action permit 82: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 82: filtering rule: access list icmp_commands_inside, action permit 83: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 83: filtering rule: access list icmp_commands_inside, action permit 84: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 84: filtering rule: access list icmp_commands_inside, action permit 85: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 85: filtering rule: access list icmp_commands_inside, action permit 86: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 86: filtering rule: access list icmp_commands_inside, action permit 87: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 87: filtering rule: access list icmp_commands_inside, action permit 88: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 88: filtering rule: access list icmp_commands_inside, action permit 101: Interface Ethernet0 ruleset telnet_commands_inside direction 'in' 101: filtering rule: access list telnet_commands_inside, action permit 103: Interface Ethernet0 ruleset ssh_commands_inside direction 'in' 103: filtering rule: access list ssh_commands_inside, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.0.output0000644000175000017500000000727511733011756027247 0ustar sylvestresylvestre3: Platform: PIX 3: Version: 8.0 9: New interface: Ethernet0 9: Interface parameters: inside 9: Interface label: inside 11: Interface address: 192.168.2.221/255.255.255.0 14: New interface: Ethernet1 14: Interface parameters: outside 14: Interface label: outside 16: Interface address: 192.0.2.221/255.255.255.0 19: New interface: Ethernet2 Warning: interface Ethernet2 was not imported because it is in "shutdown" mode 25: New interface: Ethernet3 Warning: interface Ethernet3 was not imported because it is in "shutdown" mode 31: New interface: Ethernet4 Warning: interface Ethernet4 was not imported because it is in "shutdown" mode 39: Object Group (network) net-1 42: Object Group (network) net-2 47: Object Group (network) host-1 49: Object Group (network) mixed-1 55: Object Group (network) host-2 58: Object Group (service) tcp-1 60: Object Group (service) mixed-service-1 66: Object Group (service) service-ranges 75: Object Group (icmp) icmp-1 77: Object Group (icmp) icmp-2 82: Object Group (icmp) icmp-3 83: Object Group (protocol) protocol-1 87: Object Group (protocol) proto-icmp 89: Object Group (protocol) proto-icmp6 90: Warning: IPv6 import is not supported. 91: Object Group (protocol) proto-ip 93: Object Group (protocol) proto-ipsec 95: Object Group (protocol) proto-pptp 97: Object Group (protocol) proto-snp 99: Object Group (protocol) proto-tcp 101: Object Group (protocol) proto-udp 108: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 108: filtering rule: access list icmp_commands_outside, action permit 109: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 109: filtering rule: access list icmp_commands_outside, action permit 110: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 110: filtering rule: access list icmp_commands_outside, action permit 111: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 111: filtering rule: access list icmp_commands_outside, action permit 112: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 112: filtering rule: access list icmp_commands_outside, action permit 113: Interface Ethernet1 ruleset icmp_commands_outside direction 'in' 113: filtering rule: access list icmp_commands_outside, action permit 114: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 114: filtering rule: access list icmp_commands_inside, action permit 115: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 115: filtering rule: access list icmp_commands_inside, action permit 116: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 116: filtering rule: access list icmp_commands_inside, action permit 117: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 117: filtering rule: access list icmp_commands_inside, action permit 118: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 118: filtering rule: access list icmp_commands_inside, action permit 119: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 119: filtering rule: access list icmp_commands_inside, action permit 120: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 120: filtering rule: access list icmp_commands_inside, action permit 121: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 121: filtering rule: access list icmp_commands_inside, action permit 122: Interface Ethernet0 ruleset icmp_commands_inside direction 'in' 122: filtering rule: access list icmp_commands_inside, action permit 135: Interface Ethernet0 ruleset telnet_commands_inside direction 'in' 135: filtering rule: access list telnet_commands_inside, action permit 137: Interface Ethernet0 ruleset ssh_commands_inside direction 'in' 137: filtering rule: access list ssh_commands_inside, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-acl.test0000755000175000017500000002370511733011756027425 0ustar sylvestresylvestre: Saved : ASA Version 8.3(2) ! hostname asa5505 interface Vlan1 nameif inside security-level 100 ip address 192.168.1.1 255.255.255.0 exit interface Vlan2 nameif outside security-level 0 ip address dhcp setroute exit interface Ethernet0/0 description Switch port 0/0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:0 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object service http.0 service tcp destination eq 80 exit object service https.0 service tcp destination eq 443 exit object service match-1 service tcp destination eq 80 object service match-2 service tcp destination lt 1024 object network server-1.0 host 192.168.1.100 exit object network Internal_net.0 subnet 192.168.1.0 255.255.255.0 exit object network external_net.0 subnet 192.0.2.0 255.255.255.0 object-group service id5102X14531.srv.tcp.0 tcp port-object eq 80 port-object eq 443 exit object service ip2 service eigrp object-group protocol pg1 protocol-object 111 protocol-object ah protocol-object ip protocol-object eigrp object-group network src-network-group-1 network-object 192.168.1.0 255.255.255.0 network-object 192.168.2.0 255.255.255.0 object-group network dst-network-group-1 network-object object external_net.0 object-group service test-service-1 tcp port-object eq www object-group service test-service-2 tcp port-object range 1000 1010 object-group service test-service-3 tcp port-object eq 25 group-object test-service-1 object-group service test-service-4 tcp port-object eq 25 port-object eq 88 group-object test-service-1 !################ ! ! remark access-list inside_in remark 0 (global) ! protocols, including named object and object group ! access-list inside_in extended permit ah 192.168.1.0 255.255.255.0 any access-list inside_in extended permit eigrp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit esp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit gre 192.168.1.0 255.255.255.0 any access-list inside_in extended permit icmp 192.168.1.0 255.255.255.0 any ! access-list inside_in extended permit icmp6 192.168.1.0 255.255.255.0 any access-list inside_in extended permit igmp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit igrp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit ip 192.168.1.0 255.255.255.0 any access-list inside_in extended permit ipinip 192.168.1.0 255.255.255.0 any access-list inside_in extended permit ipsec 192.168.1.0 255.255.255.0 any access-list inside_in extended permit nos 192.168.1.0 255.255.255.0 any access-list inside_in extended permit object ip2 192.168.1.0 255.255.255.0 any access-list inside_in extended permit object-group pg1 192.168.1.0 255.255.255.0 any access-list inside_in extended permit ospf 192.168.1.0 255.255.255.0 any access-list inside_in extended permit pcp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit pim 192.168.1.0 255.255.255.0 any access-list inside_in extended permit pptp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit snp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit tcp 192.168.1.0 255.255.255.0 any access-list inside_in extended permit udp 192.168.1.0 255.255.255.0 any ! named object reference in source access-list inside_in extended permit ip object Internal_net.0 any access-list inside_in remark 3 (global) ! logging access-list inside_in extended deny ip any any log ! interval w/o level access-list inside_in extended deny ip any any log interval 100 ! level w/o interval, numeric and a word access-list inside_in extended deny ip any any log 1 access-list inside_in extended deny ip any any log alerts access-list inside_in extended deny ip any any log disable ! both level and interval access-list inside_in extended deny ip any any log 0 interval 300 ! more complex tests: named objects, object groups, inline address and ! port definitions in both source and destination access-list inside_in extended permit tcp object server-1.0 object-group id5102X14531.srv.tcp.0 any access-list inside_in extended permit tcp object server-1.0 object-group dst-network-group-1 access-list inside_in extended permit tcp object server-1.0 eq 80 any access-list inside_in extended permit tcp object server-1.0 gt 1010 any access-list inside_in extended permit tcp object server-1.0 lt 1024 any access-list inside_in extended permit tcp object server-1.0 range 1010 1020 any access-list inside_in extended permit tcp object server-1.0 neq 88 any access-list inside_in extended permit tcp 192.168.2.0 255.255.255.192 object-group id5102X14531.srv.tcp.0 any access-list inside_in extended permit tcp 192.168.2.0 255.255.255.192 eq 80 any access-list inside_in extended permit tcp 192.168.2.0 255.255.255.192 gt 1010 any access-list inside_in extended permit tcp 192.168.2.0 255.255.255.192 lt 1024 any access-list inside_in extended permit tcp 192.168.2.0 255.255.255.192 range 1010 1020 any access-list inside_in extended permit tcp 192.168.2.0 255.255.255.192 neq 88 any access-list inside_out extended permit tcp any object server-1.0 object-group id5102X14531.srv.tcp.0 access-list inside_out extended permit tcp any object server-1.0 eq 80 access-list inside_out extended permit tcp any object server-1.0 gt 1010 access-list inside_out extended permit tcp any object server-1.0 lt 1024 access-list inside_out extended permit tcp any object server-1.0 range 1010 1020 access-list inside_out extended permit tcp any object server-1.0 neq 88 access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 object-group id5102X14531.srv.tcp.0 access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 eq 80 access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 gt 1010 access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 lt 1024 access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 range 1010 1020 access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 neq 88 ! invalid port name access-list inside_out extended permit tcp any 192.168.2.0 255.255.255.192 neq foo access-list inside_out extended permit tcp any object-group dst-network-group-1 access-list inside_out extended permit tcp object-group src-network-group-1 object-group dst-network-group-1 access-list inside_out extended permit tcp object-group src-network-group-1 gt 1023 object-group dst-network-group-1 eq 80 access-list inside_out extended permit tcp object-group src-network-group-1 gt 1023 object-group dst-network-group-1 neq 88 access-list inside_out extended permit tcp any eq www any range 1024 65535 access-list inside_out permit tcp any range 1080 1090 any range 1080 1090 access-list outside_out standard permit 192.0.2.0 255.255.255.0 access-list outside_out standard permit host 192.0.2.1 access-list outside_out standard permit any ! test for access list using service group that matches destination port to match ! service port access-list outside_in permit tcp object-group dst-network-group-1 object-group test-service-1 any access-list outside_in permit tcp object-group dst-network-group-1 object-group test-service-2 any access-list outside_in permit tcp object-group dst-network-group-1 object-group test-service-3 any access-list outside_in permit tcp object-group dst-network-group-1 object-group test-service-4 any ! same groups but matching destination ports access-list outside_in permit tcp object-group dst-network-group-1 gt 1024 any object-group test-service-1 access-list outside_in permit tcp object-group dst-network-group-1 gt 1024 any object-group test-service-2 access-list outside_in permit tcp object-group dst-network-group-1 gt 1024 any object-group test-service-3 access-list outside_in permit tcp object-group dst-network-group-1 gt 1024 any object-group test-service-4 ! unsupported configuration: neq in bouth source and destination access-list outside_in permit tcp any neq www any neq www ! however named object can not be used to match source ports in ASA ! 8.3 so the following rules are invalid ! ! access-list outside_in permit tcp object-group dst-network-group-1 object match-1 any ! access-list outside_in permit tcp object-group dst-network-group-1 object match-2 any ! tests for access lists using object groups for both source service and destination address ! access-list inside_in permit tcp 192.168.1.0 255.255.255.0 object-group test-service-1 host 4.2.2.1 object-group test-service-2 access-list inside_in permit tcp 192.168.1.0 255.255.255.0 object-group test-service-2 host 4.2.2.1 object-group test-service-1 access-list inside_in permit tcp 192.168.1.0 255.255.255.0 object-group test-service-1 host 4.2.2.1 object-group test-service-3 access-list inside_in permit tcp 192.168.1.0 255.255.255.0 object-group test-service-3 host 4.2.2.1 object-group test-service-1 access-list inside_in permit tcp 192.168.1.0 255.255.255.0 object-group test-service-1 host 4.2.2.1 gt 1024 access-list inside_in permit tcp 192.168.1.0 255.255.255.0 gt 1024 host 4.2.2.1 object-group test-service-1 ! access-group statements access-group inside_in in interface inside access-group inside_out out interface inside access-group outside_in in interface outside access-group outside_out out interface outside fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix7-nat.fwb0000644000175000017500000061235711733011756027145 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-objects-and-groups.test0000644000175000017500000002010411733011756032357 0ustar sylvestresylvestre: Saved : ASA Version 8.3(2) ! hostname asa5505 ! interface Vlan1 description inside interface nameif inside security-level 100 ip address dhcp setroute ! interface Vlan2 description outside interface nameif outside security-level 0 ip address 192.168.2.1 255.255.255.0 ! interface Ethernet0/0 description Switch port 0/0 switchport access vlan 2 ! ! object network internal_subnet_1 subnet 192.168.1.0 255.255.255.192 description Internal Subnet 1 object network internal_subnet_2 subnet 192.168.1.64 255.255.255.192 description Internal Subnet 2 ! this object matches network in standard objects lib, but it should be created anyway object network internal_subnet_3 subnet 192.168.1.0 255.255.255.0 description Internal Subnet 1 ! this object matches internale_subnet_1 but has different name and should be created object network internal_subnet_4 subnet 192.168.1.0 255.255.255.192 object network Internal_net subnet 192.168.1.0 255.255.255.0 object network outside_range-1 range 22.22.22.30 22.22.22.40 object network range_1 range 10.1.1.1 10.1.1.100 object network firewall90:FastEthernet1:ip-1 host 22.22.22.23 object network hostA:eth0 host 192.168.1.10 object network spamhost1 host 61.150.47.112 object network spamhost2 host 61.150.47.113 object network external_gw2 host 22.22.22.100 ! ! Example of a named object with "nat" command ! object network my-range-obj range 10.2.2.1 10.2.2.10 object network my-inside-net subnet 192.168.2.0 255.255.255.0 nat (inside,outside) dynamic my-range-ob ! ! ipv6 addresses ! object network ipv6-host-object-1 host 2001:0db8:85a3:0000:0000:8a2e:0370:7334 description Example of IPv6 host object object network ipv6-network-object-1 subnet 2001::/64 description IPv6 network object example object network ipv6-host-object-3 host fe80::202:b3ff:fe1e:8329 description Example of IPv6 host object object network ipv6-host-object-3 host a1b2:c3d4:e5f6:b3ff:fe1e:8329:0:1234 description Example of IPv6 host object ! empty named object definition object network dummy-address ! ! more good network objects after the empty one object network internal_subnet_5 subnet 10.10.1.0 255.255.255.0 ! ! another test for an empty object and non-empty object but no comments this time object network dummy-address-1 object network internal_subnet_6 subnet 10.10.2.0 255.255.255.0 ! object network ipv6-host-object-2 host 2001:af::1 description Test IPv6 host object network host-1 host 10.0.0.1 ! object service smtp service tcp destination eq smtp object service http service tcp destination eq www object service ssh service tcp destination eq 22 object service squid service tcp destination eq 3128 object service smtps service tcp destination eq 465 ! object service icmp1 service icmp echo object service icmp2 service icmp unreachable object service ip5 service 111 ! object service tcp-src-1 service tcp source lt 1024 description object description tcp src 1 object service tcp-src-2 service tcp source gt 1024 object service tcp-src-3 service tcp source eq 80 object service tcp-src-4 service tcp source neq 88 object service tcp-src-5 service tcp source range 1000 1010 ! object service tcp-dst-1 service tcp destination lt 1024 object service tcp-dst-2 service tcp destination gt 1024 object service tcp-dst-3 service tcp destination eq 80 object service tcp-dst-4 service tcp destination neq 88 object service tcp-dst-5 service tcp destination range 1001 1011 ! object service tcp-src-dst-1 service tcp source lt 1024 destination eq 80 object service tcp-src-dst-2 service tcp source gt 1024 destination eq 2222 object service tcp-src-dst-3 service tcp source eq 80 destination gt 1024 object service tcp-src-dst-4 service tcp source neq 88 destination gt 1024 object service tcp-src-dst-5 service tcp source range 1002 1012 destination gt 1024 ! object service udp-src-1 service udp source lt 1024 object service udp-src-2 service udp source gt 1024 object service udp-src-3 service udp source eq 80 object service udp-src-4 service udp source neq 88 object service udp-src-5 service udp source range 1000 1010 ! object service udp-dst-1 service udp destination lt 1024 object service udp-dst-2 service udp destination gt 1024 object service udp-dst-3 service udp destination eq 80 object service udp-dst-4 service udp destination neq 88 object service udp-dst-5 service udp destination range 1001 1011 ! object service ip1 service ip object service ip2 service eigrp object service icmp6-1 service icmp6 neighbor-advertisement ! ! named object using unknown protocol name object service ip3 service some_weird_protocol ! incomplete statement ! object service ip4 ! object-group network outside.id178211X29963.osrc.net.0 network-object object internal_subnet_1 network-object object internal_subnet_2 object-group network outside.id21353X4994.osrc.net.0 network-object object internal_subnet_1 network-object object Internal_net network-object object internal_subnet_2 object-group network outside.id77971X5929.osrc.net.1 network-object object internal_subnet_1 network-object object internal_subnet_2 object-group network outside.id77971X5929.odst.net.1 network-object object spamhost1 network-object object spamhost2 object-group network outside.id77971X5929.tsrc.net.1 network-object object outside_range-1 network-object object external_gw2 object-group network outside.id77971X5929.osrc.net.0 network-object object internal_subnet_1 network-object object internal_subnet_2 object-group network outside.id77971X5929.odst.net.0 network-object object spamhost1 network-object object spamhost2 object-group network outside.id77971X5929.tsrc.net.0 network-object object outside_range-1 network-object object external_gw2 object-group service outside.id77971X5929.osrv.1 service-object object smtp service-object object smtps object-group service sg1 service-object ip service-object eigrp service-object gre service-object 111 object-group service sg2 service-object icmp echo service-object icmp echo-reply service-object icmp 111 object-group service sg3 service-object tcp source gt 1024 destination eq www service-object tcp source gt 1024 destination range 10000 10010 service-object tcp source gt 1024 destination neq www service-object tcp source gt 1024 destination lt 1024 service-object tcp destination eq 22 object-group service sg4 service-object tcp source gt 1024 service-object tcp source lt 1024 service-object tcp source eq www service-object tcp source neq www object-group service sg5 service-object udp source gt 1024 service-object udp source gt 1024 destination eq www service-object udp destination eq domain service-object udp destination eq 5353 service-object object udp-dst-1 service-object object udp-dst-2 group-object sg1 group-object sg2 ! object-group service combo-group-1 service-object tcp-udp eq 10000 service-object tcp-udp lt 1024 service-object tcp-udp gt 1024 object-group service neq-group-2 service-object tcp neq www service-object tcp neq 81 service-object tcp neq 82 service-object tcp-udp neq 82 service-object tcp-udp neq 83 service-object tcp-udp neq 84 service-object udp neq 85 service-object udp neq 86 service-object udp neq 87 service-object udp neq www service-object udp neq nfs service-object udp neq radius service-object udp neq radius-acct service-object tcp neq ident object-group protocol pg1 protocol-object 111 protocol-object ah protocol-object ip protocol-object eigrp object-group protocol pg2 protocol-object 112 protocol-object object ip5 group-object pg1 ! object-group icmp-type ig1 icmp-object echo icmp-object 111 object-group icmp-type ig2 icmp-object echo-reply icmp-object 112 object-group icmp-type ig3 icmp-object mask-reply group-object ig1 ! also check for the terminating "exit" line (but this line is absent ! in show run output so we can't rely on it) object-group service id5102X14531.srv.tcp.0 tcp port-object eq 80 port-object eq 443 exit object-group service tcp-udp-1 tcp-udp port-object eq 10001 access-list inside_in extended permit ip any any access-group inside_in in interface inside fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix6.test0000755000175000017500000002337611733011756026565 0ustar sylvestresylvestre: Saved : PIX Version 6.3(5) interface ethernet0 auto interface ethernet1 100baseTX nameif ethernet0 outside security0 nameif ethernet1 inside security100 enable password XXXXXXXXXXXXXXXX encrypted passwd YYYYYYYYYYYYYYYY encrypted hostname guardian domain-name some-domain.org clock timezone PDT -7 clock summer-time PDT recurring fixup protocol ctiqbe 2748 fixup protocol dns maximum-length 65535 fixup protocol ftp 21 fixup protocol h323 h225 1720 fixup protocol h323 ras 1718-1719 fixup protocol http 80 fixup protocol icmp error fixup protocol ils 389 fixup protocol mgcp 2427 fixup protocol mgcp 2727 fixup protocol pptp 1723 fixup protocol rsh 514 fixup protocol rtsp 554 fixup protocol sip 5060 fixup protocol sip udp 5060 fixup protocol skinny 2000 no fixup protocol smtp 25 fixup protocol sqlnet 1521 fixup protocol tftp 69 names object-group icmp-type inside.id12349X2458.srv.icmp.0 icmp-object time-exceeded icmp-object echo-reply icmp-object unreachable object-group icmp-type outside.id12363X2458.srv.icmp.0 icmp-object echo icmp-object time-exceeded icmp-object echo-reply icmp-object unreachable object-group service outside.id12376X2458.srv.udp.0 udp port-object eq bootpc port-object eq bootps object-group service outside.id12438X2458.srv.tcp.0 tcp port-object eq ssh port-object eq www object-group service outside.id12466X2458.srv.tcp.0 tcp port-object eq 8765 port-object eq ssh access-list outside_acl_in remark 0 (ethernet0) access-list outside_acl_in deny ip host 10.1.1.202 any log 5 access-list outside_acl_in deny ip 10.1.1.0 255.255.255.0 any log 5 access-list outside_acl_in remark 3 (global) access-list outside_acl_in permit icmp any interface outside echo access-list outside_acl_in permit icmp any interface outside object-group outside.id12363X2458.srv.icmp.0 access-list outside_acl_in remark 4 (global) access-list outside_acl_in remark fw uses DHCP access-list outside_acl_in remark plus many DHCP requests access-list outside_acl_in remark from cable modem access-list outside_acl_in permit udp any interface outside object-group outside.id12376X2458.srv.udp.0 access-list outside_acl_in permit udp any host 255.255.255.255 object-group outside.id12376X2458.srv.udp.0 access-list outside_acl_in remark 6 (global) access-list outside_acl_in deny tcp any interface outside eq ident access-list outside_acl_in remark 7 (global) access-list outside_acl_in permit tcp any host 10.1.1.10 eq smtp access-list outside_acl_in remark 10 (global) access-list outside_acl_in remark using swatch to automatically access-list outside_acl_in remark block probing ssh connections, so no access-list outside_acl_in remark need to limit access-list outside_acl_in permit tcp any interface outside eq ssh access-list outside_acl_in permit tcp any interface outside eq www access-list outside_acl_in permit tcp any host 10.1.1.43 object-group outside.id12438X2458.srv.tcp.0 access-list outside_acl_in remark 11 (global) access-list outside_acl_in permit tcp any interface outside eq 8765 access-list outside_acl_in permit tcp any interface outside eq 2222 access-list outside_acl_in permit tcp any host 10.1.1.46 object-group outside.id12466X2458.srv.tcp.0 access-list outside_acl_in remark 17 (global) access-list outside_acl_in permit icmp any interface outside access-list outside_acl_in permit icmp any any access-list outside_acl_in remark 19 (global) access-list outside_acl_in remark 'catch all' rule access-list outside_acl_in deny ip any any log 5 access-list inside_acl_in remark 1 (global) access-list inside_acl_in permit tcp 10.1.1.0 255.255.255.0 host 10.1.1.202 eq www access-list inside_acl_in permit udp 10.1.1.0 255.255.255.0 host 10.1.1.202 eq snmp access-list inside_acl_in remark 2 (global) access-list inside_acl_in permit icmp host 10.1.1.202 host 10.1.1.202 object-group inside.id12349X2458.srv.icmp.0 access-list inside_acl_in permit icmp host 10.1.1.202 any object-group inside.id12349X2458.srv.icmp.0 access-list inside_acl_in remark 3 (global) access-list inside_acl_in permit icmp any host 10.1.1.202 object-group outside.id12363X2458.srv.icmp.0 access-list inside_acl_in remark 5 (global) access-list inside_acl_in permit ip host 10.1.1.202 any access-list inside_acl_in remark 6 (global) access-list inside_acl_in deny tcp any host 10.1.1.202 eq ident access-list inside_acl_in remark 7 (global) access-list inside_acl_in permit tcp any host 10.1.1.10 eq smtp access-list inside_acl_in remark 10 (global) access-list inside_acl_in remark using swatch to automatically access-list inside_acl_in remark block probing ssh connections, so no access-list inside_acl_in remark need to limit access-list inside_acl_in permit tcp any host 10.1.1.43 object-group outside.id12438X2458.srv.tcp.0 access-list inside_acl_in remark 11 (global) access-list inside_acl_in permit tcp any host 10.1.1.46 object-group outside.id12466X2458.srv.tcp.0 access-list inside_acl_in remark 17 (global) access-list inside_acl_in permit icmp any host 10.1.1.202 access-list inside_acl_in permit icmp any any access-list inside_acl_in remark 18 (global) access-list inside_acl_in permit ip 10.1.1.0 255.255.255.0 any access-list inside_acl_in remark 19 (global) access-list inside_acl_in remark 'catch all' rule access-list inside_acl_in deny ip any any log 5 access-list id12594X2458.0 permit tcp host 10.1.1.43 eq www any access-list id12594X2458.1 permit tcp host 127.0.0.1 eq www any access-list id12594X2458.2 permit tcp host 10.1.1.43 eq ssh any access-list id12594X2458.3 permit tcp host 127.0.0.1 eq ssh any access-list id12626X2458.0 permit tcp host 10.1.1.42 eq smtp any access-list id12626X2458.1 permit tcp host 10.1.1.42 eq 993 any access-list id12626X2458.2 permit tcp host 10.1.1.42 eq 587 any access-list id12642X2458.0 permit tcp host 10.1.1.46 eq ssh any access-list id12656X2458.0 permit tcp host 10.1.1.46 eq 8765 any access-list id12670X2458.0 permit tcp host 10.1.1.32 eq 5900 any access-list id12684X2458.0 permit tcp host 10.1.1.102 eq 5901 any access-list id12743X2458.0 permit ip 10.1.1.0 255.255.255.0 any no pager logging on logging timestamp logging buffered informational logging trap notifications logging facility 16 logging queue 10 logging device-id ipaddress inside logging host inside 10.1.1.10 logging host inside 10.1.1.40 format emblem icmp permit any echo outside icmp permit any 111 outside icmp permit any time-exceeded outside icmp permit any echo-reply outside icmp permit any unreachable outside icmp permit any outside icmp permit host 10.1.1.202 time-exceeded inside icmp permit host 10.1.1.202 echo-reply inside icmp permit host 10.1.1.202 unreachable inside icmp permit any echo inside icmp permit any time-exceeded inside icmp permit any echo-reply inside icmp permit any unreachable inside icmp permit any inside icmp permit 10.1.1.0 255.255.255.0 inside telnet 10.1.1.0 255.255.255.0 inside telnet timeout 5 ssh 10.1.1.30 255.255.255.255 inside ssh 10.1.1.0 255.255.255.0 inside ssh timeout 5 mtu outside 1500 mtu inside 1500 ip address outside dhcp setroute retry 10 ip address inside 10.1.1.202 255.255.255.0 ip audit info action alarm ip audit attack action alarm pdm history enable arp timeout 14400 global (outside) 1 interface nat (inside) 1 access-list id12743X2458.0 0 0 static (inside,outside) tcp interface www access-list id12594X2458.0 0 0 static (inside,outside) tcp interface ssh access-list id12594X2458.2 0 0 static (inside,outside) tcp interface smtp access-list id12626X2458.0 0 0 static (inside,outside) tcp interface 993 access-list id12626X2458.1 0 0 static (inside,outside) tcp interface 587 access-list id12626X2458.2 0 0 static (inside,outside) tcp interface 2222 access-list id12642X2458.0 0 0 static (inside,outside) tcp interface 8765 access-list id12656X2458.0 0 0 static (inside,outside) tcp interface 5900 access-list id12670X2458.0 0 0 static (inside,outside) tcp interface 5901 access-list id12684X2458.0 0 0 access-group outside_acl_in in interface outside access-group inside_acl_in in interface inside timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:00:00 udp 0:02:00 rpc 0:10:00 h225 1:00:00 timeout h323 0:05:00 mgcp 0:05:00 sip 0:30:00 sip_media 0:00:00 timeout sip-disconnect 0:02:00 sip-invite 0:03:00 timeout uauth 2:00:00 absolute aaa-server TACACS+ protocol tacacs+ aaa-server TACACS+ max-failed-attempts 3 aaa-server TACACS+ deadtime 10 aaa-server RADIUS protocol radius aaa-server RADIUS max-failed-attempts 3 aaa-server RADIUS deadtime 10 aaa-server LOCAL protocol local aaa authentication ssh console LOCAL aaa authentication telnet console LOCAL aaa authorization command LOCAL ntp server 10.1.1.10 source inside prefer http server enable http 10.1.1.40 255.255.255.255 inside http 10.1.1.0 255.255.255.0 inside snmp-server host inside 10.1.1.30 snmp-server host inside 10.1.1.41 snmp-server host inside 10.1.1.42 no snmp-server location no snmp-server contact snmp-server community public no snmp-server enable traps floodguard enable sysopt connection permit-ipsec service resetinbound service resetoutside crypto ipsec transform-set tripledes esp-3des esp-md5-hmac crypto map real 10 ipsec-isakmp crypto map real 10 set peer 192.168.171.2 crypto map real 10 set transform-set tripledes ! Incomplete crypto map real interface outside crypto map real interface inside isakmp enable outside isakmp key ******** address 192.168.171.2 netmask 255.255.255.255 isakmp identity address isakmp policy 1 authentication pre-share isakmp policy 1 encryption 3des isakmp policy 1 hash md5 isakmp policy 1 group 2 isakmp policy 1 lifetime 86400 isakmp policy 10 authentication pre-share isakmp policy 10 encryption 3des isakmp policy 10 hash sha isakmp policy 10 group 2 isakmp policy 10 lifetime 86400 console timeout 0 username foo password AAAAAAAAAAAAAAAA encrypted privilege 15 terminal width 256 Cryptochecksum:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix7-nat.test0000644000175000017500000002630111733011756027332 0ustar sylvestresylvestre: Saved : PIX Version 7.2(1) ! terminal width 511 hostname pix1 domain-name some-domain.org enable password XXXXXXXXXXXXXXXX encrypted names name 1.2.3.4 gw name 192.168.3.0 fake_network name 192.168.4.1 inside_ip ! dns-guard ! interface Ethernet0 no nameif no security-level no ip address ! interface Ethernet0.101 vlan 101 nameif outside security-level 0 ip address 192.0.2.253 255.255.255.0 ! interface Ethernet0.102 vlan 102 nameif dmz20 security-level 20 ip address 10.0.0.253 255.255.255.0 standby 10.0.0.254 ! interface Ethernet1 speed 100 duplex full nameif inside security-level 100 ip address 10.1.1.206 255.255.255.0 ! interface Ethernet2 shutdown description LAN/STATE Failover Interface speed 10 ! interface Ethernet3 shutdown no nameif no security-level no ip address ! interface Ethernet4 shutdown no nameif no security-level no ip address ! interface Ethernet5 shutdown no nameif no security-level no ip address ! interface Ethernet6 ! passwd MMMMMMMMMMMMMMMM encrypted boot system flash:/pix721.bin ftp mode passive clock timezone PDT -7 dns server-group DefaultDNS domain-name some-domain.org object-group network outside.id12051X6282.src.net.0 network-object host 10.1.1.206 network-object host 10.1.1.207 object-group network outside.id12051X6282.src.net.1 network-object host 172.17.1.253 network-object host 172.17.1.254 network-object host 192.0.2.253 network-object host 192.0.2.254 object-group network outside.id12051X6282.src.net.2 network-object host 10.0.0.253 network-object host 10.0.0.254 object-group network network-zone-inside network-object 10.1.1.0 255.255.255.0 object-group network network-zone-dmz20 network-object 10.0.0.0 255.255.255.0 access-list outside_in extended deny ip object-group outside.id12051X6282.src.net.0 any log warnings access-list outside_in extended deny ip object-group outside.id12051X6282.src.net.1 any log warnings access-list outside_in extended deny ip object-group outside.id12051X6282.src.net.2 any log warnings access-list outside_in extended deny ip 10.1.1.0 255.255.255.0 any log warnings access-list inside_out extended permit udp object-group outside.id12051X6282.src.net.0 10.1.1.0 255.255.255.0 eq domain log warnings access-list inside_out extended permit udp object-group outside.id12051X6282.src.net.1 10.1.1.0 255.255.255.0 eq domain log warnings access-list inside_out extended permit udp object-group outside.id12051X6282.src.net.2 10.1.1.0 255.255.255.0 eq domain log warnings access-list inside_out extended permit ip 10.1.1.0 255.255.255.0 any access-list inside_out extended deny ip any any log warnings access-list inside_in extended deny ip any object-group outside.id12051X6282.src.net.0 log warnings access-list inside_in extended deny ip any object-group outside.id12051X6282.src.net.1 log warnings access-list inside_in extended deny ip any object-group outside.id12051X6282.src.net.2 log warnings access-list inside_in extended permit ip 10.1.1.0 255.255.255.0 any access-list inside_in extended deny ip any any log warnings access-list id12251X6282.0 extended permit ip 10.1.1.0 255.255.255.0 any access-list id12594X2458.0 permit tcp host 10.1.1.43 eq www any ! example from cisco docs, see also nat command below access-list WEB permit tcp 10.1.1.0 255.255.255.0 4.2.2.1 255.255.255.255 eq 80 access-list WEB2 permit tcp 192.168.2.0 255.255.255.0 4.2.2.1 255.255.255.255 eq 80 access-list WEB2 permit tcp 192.168.3.0 255.255.255.0 4.2.2.1 255.255.255.255 eq 80 access-list EXEMPT permit ip 192.168.4.0 255.255.255.0 any access-list NET1 permit ip host 10.1.1.20 host 4.2.2.1 pager lines 24 logging enable logging emblem logging trap debugging logging history informational logging facility 16 logging queue 10 logging device-id ipaddress inside logging host inside 192.168.240.20 logging host inside 10.1.1.40 format emblem logging class config buffered debugging mtu outside 1500 mtu dmz20 1500 mtu inside 1500 failover failover lan unit primary failover lan interface failover Ethernet2 failover lan enable failover key ***** failover link failover Ethernet2 failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 no asdm history enable arp timeout 14400 nat-control global (outside) 1 interface nat (inside) 1 access-list id12251X6282.0 global (outside) 2 192.0.2.10 global (outside) 2 192.0.2.11-192.0.2.15 global (outside) 2 192.0.2.128 netmask 255.255.255.240 global (dmz20) 2 10.0.0.128 netmask 255.255.255.240 global (outside) 3 192.0.2.20 global (outside) 3 192.0.2.30-192.0.2.31 nat (inside) 2 10.1.1.1 255.255.255.255 nat (inside) 2 10.1.1.32 255.255.255.240 nat (inside) 1 access-list WEB nat (inside) 1 access-list WEB2 ! multiple address blocks in pool 3 and multiple lines in access list WEB2 nat (inside) 3 access-list WEB2 ! nat exemption example nat (inside) 0 access-list EXEMPT ! example of nat () 1 0 0 command nat (inside) 3 0 0 ! "nat outside example with max_conn parameter nat (dmz20) 2 10.2.2.0 255.255.255.0 outside 1000 static (inside,dmz20) 10.0.0.16 10.1.1.16 netmask 255.255.255.240 static (inside,dmz20) 10.0.0.100 10.1.1.100 netmask 255.255.255.255 static (inside,dmz20) interface 10.1.1.111 static (inside,outside) tcp 10.5.80.16 80 10.1.1.16 8080 netmask 255.255.255.240 0 0 static (inside,outside) tcp 10.5.80.200 80 10.10.1.200 8080 netmask 255.255.255.255 0 0 static (inside,outside) tcp 10.5.80.16 aol 10.1.1.16 aol static (inside,outside) tcp 10.5.80.16 bgp 10.1.1.16 bgp static (inside,outside) tcp 10.5.80.16 chargen 10.1.1.16 chargen static (inside,outside) tcp 10.5.80.16 cifs 10.1.1.16 cifs static (inside,outside) tcp 10.5.80.16 citrix-ica 10.1.1.16 citrix-ica static (inside,outside) tcp 10.5.80.16 cmd 10.1.1.16 cmd static (inside,outside) tcp 10.5.80.16 ctiqbe 10.1.1.16 ctiqbe static (inside,outside) tcp 10.5.80.16 daytime 10.1.1.16 daytime static (inside,outside) tcp 10.5.80.16 discard 10.1.1.16 discard static (inside,outside) tcp 10.5.80.16 domain 10.1.1.16 domain static (inside,outside) tcp 10.5.80.16 echo 10.1.1.16 echo static (inside,outside) tcp 10.5.80.16 exec 10.1.1.16 exec static (inside,outside) tcp 10.5.80.16 finger 10.1.1.16 finger static (inside,outside) tcp 10.5.80.16 ftp 10.1.1.16 ftp static (inside,outside) tcp 10.5.80.16 ftp-data 10.1.1.16 ftp-data static (inside,outside) tcp 10.5.80.16 gopher 10.1.1.16 gopher static (inside,outside) tcp 10.5.80.16 h323 10.1.1.16 h323 static (inside,outside) tcp 10.5.80.16 hostname 10.1.1.16 hostname static (inside,outside) tcp 10.5.80.16 http 10.1.1.16 http static (inside,outside) tcp 10.5.80.16 https 10.1.1.16 https static (inside,outside) tcp 10.5.80.16 ident 10.1.1.16 ident static (inside,outside) tcp 10.5.80.16 imap4 10.1.1.16 imap4 static (inside,outside) tcp 10.5.80.16 irc 10.1.1.16 irc static (inside,outside) tcp 10.5.80.16 kerberos 10.1.1.16 kerberos static (inside,outside) tcp 10.5.80.16 klogin 10.1.1.16 klogin static (inside,outside) tcp 10.5.80.16 kshell 10.1.1.16 kshell static (inside,outside) tcp 10.5.80.16 ldap 10.1.1.16 ldap static (inside,outside) tcp 10.5.80.16 ldaps 10.1.1.16 ldaps static (inside,outside) tcp 10.5.80.16 login 10.1.1.16 login static (inside,outside) tcp 10.5.80.16 lotusnotes 10.1.1.16 lotusnotes static (inside,outside) tcp 10.5.80.16 lpd 10.1.1.16 lpd static (inside,outside) tcp 10.5.80.16 netbios-ssn 10.1.1.16 netbios-ssn static (inside,outside) tcp 10.5.80.16 nntp 10.1.1.16 nntp static (inside,outside) tcp 10.5.80.16 pcanywhere-data 10.1.1.16 pcanywhere-data static (inside,outside) tcp 10.5.80.16 pim-auto-rp 10.1.1.16 pim-auto-rp static (inside,outside) tcp 10.5.80.16 pop2 10.1.1.16 pop2 static (inside,outside) tcp 10.5.80.16 pop3 10.1.1.16 pop3 static (inside,outside) tcp 10.5.80.16 pptp 10.1.1.16 pptp static (inside,outside) tcp 10.5.80.16 rsh 10.1.1.16 rsh static (inside,outside) tcp 10.5.80.16 rtsp 10.1.1.16 rtsp static (inside,outside) tcp 10.5.80.16 sip 10.1.1.16 sip static (inside,outside) tcp 10.5.80.16 smtp 10.1.1.16 smtp static (inside,outside) tcp 10.5.80.16 sqlnet 10.1.1.16 sqlnet static (inside,outside) tcp 10.5.80.16 ssh 10.1.1.16 ssh static (inside,outside) tcp 10.5.80.16 sunrpc 10.1.1.16 sunrpc static (inside,outside) tcp 10.5.80.16 tacacs 10.1.1.16 tacacs static (inside,outside) tcp 10.5.80.16 talk 10.1.1.16 talk static (inside,outside) tcp 10.5.80.16 telnet 10.1.1.16 telnet static (inside,outside) tcp 10.5.80.16 uucp 10.1.1.16 uucp static (inside,outside) tcp 10.5.80.16 whois 10.1.1.16 whois static (inside,outside) tcp 10.5.80.16 www 10.1.1.16 www static (inside,outside) tcp interface www access-list id12594X2458.0 0 0 static (inside,outside) tcp interface 80 access-list id12594X2458.0 0 0 static (inside,outside) interface access-list id12594X2458.0 0 0 static (inside,outside) 192.0.2.15 access-list NET1 ! acl WEB2 has multiple lines. Does this even make sense ? static (inside,outside) 192.0.2.15 access-list WEB2 access-group outside_in in interface outside access-group inside_in in interface inside access-group inside_out out interface inside route inside 192.168.10.0 255.255.255.0 10.1.1.254 1 route inside 10.1.2.0 255.255.255.0 10.1.1.201 1 timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02 timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00 timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00 timeout uauth 2:00:00 absolute aaa-server TACACS+ protocol tacacs+ aaa-server RADIUS protocol radius username fwbtest password AAAAAAAAAAAAAAAA encrypted privilege 15 aaa authentication ssh console LOCAL snmp-server host inside 10.1.1.180 community public snmp-server host inside 10.1.1.30 community public snmp-server host inside 10.1.1.40 poll community public version 2c no snmp-server location no snmp-server contact snmp-server community public crypto ipsec transform-set spde esp-des esp-sha-hmac crypto map spdemap 21 set peer 192.0.2.254 crypto map spdemap 21 set transform-set spde crypto isakmp identity address crypto isakmp policy 21 authentication pre-share encryption des hash sha group 1 lifetime 3600 crypto isakmp policy 65535 authentication pre-share encryption 3des hash sha group 2 lifetime 86400 tunnel-group 192.0.2.254 type ipsec-l2l tunnel-group 192.0.2.254 ipsec-attributes pre-shared-key * telnet timeout 5 ssh scopy enable ssh 10.1.1.0 255.255.255.0 inside ssh 10.1.2.0 255.255.255.0 inside ssh 192.0.2.100 255.255.255.255 outside ssh timeout 20 console timeout 0 ! class-map custom_h323_h225_inspection match port tcp range h323 1721 class-map custom_http_inspection match port tcp range www 88 class-map inspection_default match default-inspection-traffic ! ! policy-map type inspect dns migrated_dns_map_1 parameters message-length maximum 512 policy-map global_policy class inspection_default inspect dns migrated_dns_map_1 inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect netbios inspect rsh inspect rtsp inspect skinny inspect sqlnet inspect sunrpc inspect tftp inspect sip inspect xdmcp inspect ctiqbe inspect icmp inspect ils inspect mgcp inspect esmtp class custom_h323_h225_inspection inspect h323 h225 class custom_http_inspection inspect http ! service-policy global_policy global prompt hostname context Cryptochecksum:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/fwsm1.fwb0000644000175000017500000024160311733011756026523 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-acl-object-groups.test0000644000175000017500000001113211733011756032172 0ustar sylvestresylvestre: Saved : ASA Version 8.3(2) ! hostname asa5505 interface Vlan1 nameif inside security-level 100 ip address 192.168.1.1 255.255.255.0 exit interface Vlan2 nameif outside security-level 0 ip address dhcp setroute exit interface Ethernet0/0 description Switch port 0/0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:0 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object service http.0 service tcp destination eq 80 exit object service https.0 service tcp destination eq 443 exit object network server-1.0 host 192.168.1.100 exit object network Internal_net.0 subnet 192.168.1.0 255.255.255.0 exit object network external_net.0 subnet 192.0.2.0 255.255.255.0 object-group service srv-group-1 tcp port-object eq 80 port-object eq 443 exit object service ip2 service eigrp object-group protocol pg1 protocol-object 111 protocol-object ah protocol-object ip protocol-object eigrp object-group network src-network-group-1 network-object 192.168.1.0 255.255.255.0 network-object 192.168.2.0 255.255.255.0 object-group network dst-network-group-1 network-object object external_net.0 !################ ! access-list inside_in extended permit object-group pg1 192.168.1.0 255.255.255.0 any access-list inside_in extended permit tcp object server-1.0 any access-list inside_in extended permit tcp object server-1.0 host 192.0.2.1 access-list inside_in extended permit tcp object server-1.0 192.0.2.0 255.255.255.0 access-list inside_in extended permit tcp object server-1.0 object external_net.0 access-list inside_in extended permit tcp object server-1.0 object-group dst-network-group-1 ! named object in both source and destination ! access-list inside_in extended permit tcp object server-1.0 object external_net.0 ! src port definitions ! access-list inside_in extended permit tcp object server-1.0 eq 80 any access-list inside_in extended permit tcp object server-1.0 lt 1024 any access-list inside_in extended permit tcp object server-1.0 gt 1024 any access-list inside_in extended permit tcp object server-1.0 range 1000 1100 any ! ASA 8.3 does not take this acl definition (assumes object http.0 is dest address) ! access-list inside_in extended permit tcp object server-1.0 object http.0 any access-list inside_in extended permit tcp object server-1.0 object-group srv-group-1 any ! dest port is defined using in-line port operators ! access-list inside_in extended permit tcp object server-1.0 any eq 80 access-list inside_in extended permit tcp object server-1.0 host 192.0.2.1 eq 80 access-list inside_in extended permit tcp object server-1.0 192.0.2.0 255.255.255.0 eq 80 access-list inside_in extended permit tcp object server-1.0 object external_net.0 eq 80 access-list inside_in extended permit tcp object server-1.0 object-group dst-network-group-1 eq 80 ! object-group service is used to define destination ports ! access-list inside_in extended permit tcp object server-1.0 any object-group srv-group-1 access-list inside_in extended permit tcp object server-1.0 host 192.0.2.1 object-group srv-group-1 access-list inside_in extended permit tcp object server-1.0 192.0.2.0 255.255.255.0 object-group srv-group-1 access-list inside_in extended permit tcp object server-1.0 object external_net.0 object-group srv-group-1 ! object-group service is used to define source ports ! access-list inside_in extended permit tcp object server-1.0 object-group srv-group-1 any access-list inside_in extended permit tcp object server-1.0 object-group srv-group-1 host 192.0.2.1 access-list inside_in extended permit tcp object server-1.0 object-group srv-group-1 192.0.2.0 255.255.255.0 access-list inside_in extended permit tcp object server-1.0 object-group srv-group-1 object external_net.0 access-list inside_in extended permit tcp object server-1.0 object-group srv-group-1 object-group dst-network-group-1 access-group inside_in in interface inside fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix7-nat.output0000644000175000017500000001676611733011756027731 0ustar sylvestresylvestre3: Platform: PIX 3: Version: 7.2 16: New interface: Ethernet0 21: New interface: Ethernet0.101 22: Interface parameters: outside 22: Interface label: outside 24: Interface address: 192.0.2.253/255.255.255.0 27: New interface: Ethernet0.102 28: Interface parameters: dmz20 28: Interface label: dmz20 30: Interface address: 10.0.0.253/255.255.255.0 30: Warning: failover IP detected. Failover is not supported by import at this time 33: New interface: Ethernet1 35: Interface parameters: inside 35: Interface label: inside 37: Interface address: 10.1.1.206/255.255.255.0 40: New interface: Ethernet2 Warning: interface Ethernet2 was not imported because it is in "shutdown" mode 45: New interface: Ethernet3 Warning: interface Ethernet3 was not imported because it is in "shutdown" mode 51: New interface: Ethernet4 Warning: interface Ethernet4 was not imported because it is in "shutdown" mode 57: New interface: Ethernet5 Warning: interface Ethernet5 was not imported because it is in "shutdown" mode 63: New interface: Ethernet6 Warning: interface Ethernet6 was not imported because it is in "shutdown" mode 71: Object Group (network) outside.id12051X6282.src.net.0 74: Object Group (network) outside.id12051X6282.src.net.1 79: Object Group (network) outside.id12051X6282.src.net.2 83: Object Group (network) network-zone-inside 85: Object Group (network) network-zone-dmz20 89: filtering rule: access list outside_in, action deny 90: filtering rule: access list outside_in, action deny 91: filtering rule: access list outside_in, action deny 92: filtering rule: access list outside_in, action deny 93: filtering rule: access list inside_out, action permit 94: filtering rule: access list inside_out, action permit 95: filtering rule: access list inside_out, action permit 96: filtering rule: access list inside_out, action permit 97: filtering rule: access list inside_out, action deny 98: filtering rule: access list inside_in, action deny 99: filtering rule: access list inside_in, action deny 100: filtering rule: access list inside_in, action deny 101: filtering rule: access list inside_in, action permit 102: filtering rule: access list inside_in, action deny 104: filtering rule: access list id12251X6282.0, action permit 106: filtering rule: access list id12594X2458.0, action permit 109: filtering rule: access list WEB, action permit 111: filtering rule: access list WEB2, action permit 112: filtering rule: access list WEB2, action permit 113: filtering rule: access list EXEMPT, action permit 115: filtering rule: access list NET1, action permit 143: Global address pool: number 1, interface outside, address range interface-interface, netmask 255.255.255.255 144: Source translation rule ("nat" command) 146: Global address pool: number 2, interface outside, address range 192.0.2.10-192.0.2.10, netmask 255.255.255.255 147: Global address pool: number 2, interface outside, address range 192.0.2.11-192.0.2.15, netmask 255.255.255.255 148: Global address pool: number 2, interface outside, address range 192.0.2.128-192.0.2.128, netmask 255.255.255.240 149: Global address pool: number 2, interface dmz20, address range 10.0.0.128-10.0.0.128, netmask 255.255.255.240 150: Global address pool: number 3, interface outside, address range 192.0.2.20-192.0.2.20, netmask 255.255.255.255 151: Global address pool: number 3, interface outside, address range 192.0.2.30-192.0.2.31, netmask 255.255.255.255 153: Source translation rule ("nat" command) 154: Source translation rule ("nat" command) 156: Source translation rule ("nat" command) 157: Source translation rule ("nat" command) 160: Source translation rule ("nat" command) 163: Source translation rule ("nat" command) 163: NAT exemption rule ("nat (interface) 0" command) 166: Source translation rule ("nat" command) 169: Source translation rule ("nat" command) 173: Destination translation rule ("static" command) 174: Destination translation rule ("static" command) 175: Destination translation rule ("static" command) 176: Destination translation rule ("static" command) 177: Destination translation rule ("static" command) 179: Destination translation rule ("static" command) 180: Destination translation rule ("static" command) 181: Destination translation rule ("static" command) 182: Destination translation rule ("static" command) 183: Destination translation rule ("static" command) 184: Destination translation rule ("static" command) 185: Destination translation rule ("static" command) 186: Destination translation rule ("static" command) 187: Destination translation rule ("static" command) 188: Destination translation rule ("static" command) 189: Destination translation rule ("static" command) 190: Destination translation rule ("static" command) 191: Destination translation rule ("static" command) 192: Destination translation rule ("static" command) 193: Destination translation rule ("static" command) 194: Destination translation rule ("static" command) 195: Destination translation rule ("static" command) 196: Destination translation rule ("static" command) 197: Destination translation rule ("static" command) 198: Destination translation rule ("static" command) 199: Destination translation rule ("static" command) 200: Destination translation rule ("static" command) 201: Destination translation rule ("static" command) 202: Destination translation rule ("static" command) 203: Destination translation rule ("static" command) 204: Destination translation rule ("static" command) 205: Destination translation rule ("static" command) 206: Destination translation rule ("static" command) 207: Destination translation rule ("static" command) 208: Destination translation rule ("static" command) 209: Destination translation rule ("static" command) 210: Destination translation rule ("static" command) 211: Destination translation rule ("static" command) 212: Destination translation rule ("static" command) 213: Destination translation rule ("static" command) 214: Destination translation rule ("static" command) 215: Destination translation rule ("static" command) 216: Destination translation rule ("static" command) 217: Destination translation rule ("static" command) 218: Destination translation rule ("static" command) 219: Destination translation rule ("static" command) 220: Destination translation rule ("static" command) 221: Destination translation rule ("static" command) 222: Destination translation rule ("static" command) 223: Destination translation rule ("static" command) 224: Destination translation rule ("static" command) 225: Destination translation rule ("static" command) 226: Destination translation rule ("static" command) 227: Destination translation rule ("static" command) 228: Destination translation rule ("static" command) 229: Destination translation rule ("static" command) 234: Destination translation rule ("static" command) 235: Destination translation rule ("static" command) 236: Destination translation rule ("static" command) 238: Destination translation rule ("static" command) 241: Destination translation rule ("static" command) 244: Interface Ethernet0.101 ruleset outside_in direction 'in' 245: Interface Ethernet1 ruleset inside_in direction 'in' 246: Interface Ethernet1 ruleset inside_out direction 'out' 287: Interface Ethernet1 ruleset ssh_commands_inside direction 'in' 287: filtering rule: access list ssh_commands_inside, action permit 288: Interface Ethernet1 ruleset ssh_commands_inside direction 'in' 288: filtering rule: access list ssh_commands_inside, action permit 289: Interface Ethernet0.101 ruleset ssh_commands_outside direction 'in' 289: filtering rule: access list ssh_commands_outside, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-acl-object-groups.output0000644000175000017500000000504211733011756032556 0ustar sylvestresylvestre3: Platform: ASA 3: Version: 8.3 8: New interface: Vlan1 8: Interface parameters: inside 8: Interface label: inside 10: Interface address: 192.168.1.1/255.255.255.0 14: New interface: Vlan2 14: Interface parameters: outside 14: Interface label: outside 16: Interface address: dhcp/ 20: New interface: Ethernet0/0 20: Interface comment: Switch port 0 / 0 77: Named object (service) http.0 81: Named object (service) https.0 85: Named object (address) server-1.0 89: Named object (address) Internal_net.0 93: Named object (address) external_net.0 96: Object Group (service) srv-group-1 101: Named object (service) ip2 104: Object Group (protocol) pg1 110: Object Group (network) src-network-group-1 114: Object Group (network) dst-network-group-1 122: filtering rule: access list inside_in, action permit 125: filtering rule: access list inside_in, action permit 127: filtering rule: access list inside_in, action permit 129: filtering rule: access list inside_in, action permit 131: filtering rule: access list inside_in, action permit 133: filtering rule: access list inside_in, action permit 138: filtering rule: access list inside_in, action permit 143: filtering rule: access list inside_in, action permit 145: filtering rule: access list inside_in, action permit 147: filtering rule: access list inside_in, action permit 149: filtering rule: access list inside_in, action permit 155: filtering rule: access list inside_in, action permit 155: Object Group (service) srv-group-1-mirror 162: filtering rule: access list inside_in, action permit 164: filtering rule: access list inside_in, action permit 166: filtering rule: access list inside_in, action permit 168: filtering rule: access list inside_in, action permit 170: filtering rule: access list inside_in, action permit 175: filtering rule: access list inside_in, action permit 177: filtering rule: access list inside_in, action permit 179: filtering rule: access list inside_in, action permit 181: filtering rule: access list inside_in, action permit 188: filtering rule: access list inside_in, action permit 188: Object Group (service) srv-group-1-mirror 190: filtering rule: access list inside_in, action permit 190: Object Group (service) srv-group-1-mirror 192: filtering rule: access list inside_in, action permit 192: Object Group (service) srv-group-1-mirror 194: filtering rule: access list inside_in, action permit 194: Object Group (service) srv-group-1-mirror 196: filtering rule: access list inside_in, action permit 196: Object Group (service) srv-group-1-mirror 199: Interface Vlan1 ruleset inside_in direction 'in' fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix7.fwb0000644000175000017500000027747111733011756026371 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.0-names.fwb0000644000175000017500000027737311733011756027576 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/fwsm1.output0000644000175000017500000000174611733011756027307 0ustar sylvestresylvestre3: Platform: FWSM 3: Version: 4.1 11: New interface: Vlan350 11: Interface comment: management 12: Interface parameters: vlan0350 12: Interface label: vlan0350 14: Interface address: 192.0.2.1/255.255.255.0 18: New interface: Vlan351 18: Interface parameters: vlan0351 18: Interface label: vlan0351 23: New interface: Vlan352 23: Interface parameters: vlan0352 23: Interface label: vlan0352 28: New interface: Vlan353 28: Interface parameters: vlan0353 28: Interface label: vlan0353 33: New interface: Vlan354 33: Interface parameters: vlan0354 33: Interface label: vlan0354 47: Interface Vlan350 ruleset icmp_commands_vlan0350 direction 'in' 47: filtering rule: access list icmp_commands_vlan0350, action permit 63: Interface Vlan350 ruleset http_commands_vlan0350 direction 'in' 63: filtering rule: access list http_commands_vlan0350, action permit 67: Interface Vlan350 ruleset ssh_commands_vlan0350 direction 'in' 67: filtering rule: access list ssh_commands_vlan0350, action permit fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-nat.test0000755000175000017500000000754611733011756027455 0ustar sylvestresylvestre: Saved : ASA Version 8.3(2) ! hostname asa5505 interface Vlan1 nameif inside security-level 100 ip address 192.168.1.1 255.255.255.0 exit interface Vlan2 nameif outside security-level 0 ip address dhcp setroute exit interface Ethernet0/0 description Switch port 0/0 exit no logging buffered no logging console no logging timestamp no logging on timeout xlate 0:0:0 timeout conn 0:0:0 timeout udp 0:0:0 timeout sunrpc 0:0:0 timeout h323 0:0:0 timeout sip 0:0:0 timeout sip_media 0:0:0 timeout half-closed 0:0:0 timeout uauth 0:0:0 clear config ssh aaa authentication ssh console LOCAL clear config snmp-server no snmp-server enable traps clear config ntp no service resetinbound no service resetoutside no sysopt connection timewait no sysopt nodnsalias inbound no sysopt nodnsalias outbound class-map inspection_default match default-inspection-traffic policy-map global_policy class inspection_default service-policy global_policy global clear xlate clear config nat clear config access-list clear config icmp clear config telnet clear config object-group clear config object object network internal_subnet_1 subnet 192.168.1.0 255.255.255.192 description Internal Subnet 1 object network internal_subnet_2 subnet 192.168.1.64 255.255.255.192 description Internal Subnet 2 object network Internal_net subnet 192.168.1.0 255.255.255.0 object network hostA:eth0 host 192.168.1.10 object service http.0 service tcp destination eq 80 exit object service https.0 service tcp destination eq 443 exit object network server-1.0 host 192.168.1.100 exit object network Internal_net.0 subnet 192.168.1.0 255.255.255.0 exit object network external_net.0 subnet 192.0.2.0 255.255.255.0 object-group service id5102X14531.srv.tcp.0 tcp port-object eq 80 port-object eq 443 exit object service ip2 service eigrp object-group protocol pg1 protocol-object 111 protocol-object ah protocol-object ip protocol-object eigrp object-group network src-network-group-1 network-object 192.168.1.0 255.255.255.0 network-object 192.168.2.0 255.255.255.0 object-group network dst-network-group-1 network-object object external_net.0 object-group network outside.id178211X29963.osrc.net.0 network-object object internal_subnet_1 network-object object internal_subnet_2 ! object-group network outside.id21353X4994.osrc.net.0 network-object object internal_subnet_1 network-object object Internal_net network-object object internal_subnet_2 ! object-group network outside.id77971X5929.osrc.net.1 network-object object internal_subnet_1 network-object object internal_subnet_2 !################ ! access-list outside_in extended deny ip any any log ! access-group statements access-group outside_in in interface outside ! ! Rule 0 (NAT) nat (inside,outside) source dynamic Internal_net.0 interface description "0 (NAT)" ! ! Rule 1 (NAT) nat (outside,inside) source static any any destination static interface server-1.0 service http.0 http.0 description "1 (NAT)" nat (outside,inside) source static any any destination static interface server-1.0 service https.0 https.0 description "1 (NAT)" nat (inside,outside) source dynamic outside.id178211X29963.osrc.net.0 firewall90:FastEthernet1:ip-1 service smtp smtp nat (inside,outside) source dynamic outside.id21353X4994.osrc.net.0 firewall90:FastEthernet1:ip-1 service smtp smtp nat (outside,inside) source static any any destination static interface hostA:eth0 service http squid nat (inside,outside) source dynamic outside.id77971X5929.osrc.net.0 outside.id77971X5929.tsrc.net.0 interface destination static outside.id77971X5929.odst.net.0 outside.id77971X5929.odst.net.0 service smtp smtp nat (inside,outside) source dynamic outside.id77971X5929.osrc.net.0 outside.id77971X5929.tsrc.net.1 interface destination static outside.id77971X5929.odst.net.0 outside.id77971X5929.odst.net.0 service smtps smtps fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/pix7.test0000644000175000017500000001405311733011756026553 0ustar sylvestresylvestre: Saved : PIX Version 7.2(1) ! terminal width 511 hostname pix1 domain-name some-domain.org enable password XXXXXXXXXXXXXXXX encrypted names name 1.2.3.4 gw name 192.168.3.0 fake_network name 192.168.4.1 inside_ip ! dns-guard ! interface Ethernet0 no nameif no security-level no ip address ! interface Ethernet0.101 vlan 101 nameif outside security-level 0 ip address 192.0.2.253 255.255.255.0 ! interface Ethernet0.102 vlan 102 nameif dmz20 security-level 20 ip address 10.0.0.253 255.255.255.0 standby 10.0.0.254 ! interface Ethernet1 speed 100 duplex full nameif inside security-level 100 ip address 10.1.1.206 255.255.255.0 ! interface Ethernet2 description LAN/STATE Failover Interface speed 10 ! interface Ethernet3 shutdown no nameif no security-level no ip address ! interface Ethernet4 shutdown no nameif no security-level no ip address ! interface Ethernet5 shutdown no nameif no security-level no ip address ! interface Ethernet6 ! passwd MMMMMMMMMMMMMMMM encrypted boot system flash:/pix721.bin ftp mode passive clock timezone PDT -7 dns server-group DefaultDNS domain-name some-domain.org object-group network outside.id12051X6282.src.net.0 network-object host 10.1.1.206 network-object host 10.1.1.207 object-group network outside.id12051X6282.src.net.1 network-object host 172.17.1.253 network-object host 172.17.1.254 network-object host 192.0.2.253 network-object host 192.0.2.254 object-group network outside.id12051X6282.src.net.2 network-object host 10.0.0.253 network-object host 10.0.0.254 access-list outside_in extended deny ip object-group outside.id12051X6282.src.net.0 any log warnings access-list outside_in extended deny ip object-group outside.id12051X6282.src.net.1 any log warnings access-list outside_in extended deny ip object-group outside.id12051X6282.src.net.2 any log warnings access-list outside_in extended deny ip 10.1.1.0 255.255.255.0 any log warnings access-list inside_out extended permit udp object-group outside.id12051X6282.src.net.0 10.1.1.0 255.255.255.0 eq domain log warnings access-list inside_out extended permit udp object-group outside.id12051X6282.src.net.1 10.1.1.0 255.255.255.0 eq domain log warnings access-list inside_out extended permit udp object-group outside.id12051X6282.src.net.2 10.1.1.0 255.255.255.0 eq domain log warnings access-list inside_out extended permit ip 10.1.1.0 255.255.255.0 any access-list inside_out extended deny ip any any log warnings access-list inside_in extended deny ip any object-group outside.id12051X6282.src.net.0 log warnings access-list inside_in extended deny ip any object-group outside.id12051X6282.src.net.1 log warnings access-list inside_in extended deny ip any object-group outside.id12051X6282.src.net.2 log warnings access-list inside_in extended permit ip 10.1.1.0 255.255.255.0 any access-list inside_in extended deny ip any any log warnings access-list id12251X6282.0 extended permit ip 10.1.1.0 255.255.255.0 any access-group inside_in in interface inside access-group outside_in in interface outside pager lines 24 logging enable logging emblem logging trap debugging logging history informational logging facility 16 logging queue 10 logging device-id ipaddress inside logging host inside 192.168.240.20 logging host inside 10.1.1.40 format emblem logging class config buffered debugging mtu outside 1500 mtu dmz20 1500 mtu inside 1500 failover failover lan unit primary failover lan interface failover Ethernet2 failover lan enable failover key ***** failover link failover Ethernet2 failover interface ip failover 172.17.1.253 255.255.255.252 standby 172.17.1.254 no asdm history enable arp timeout 14400 access-group outside_in in interface outside access-group inside_in in interface inside access-group inside_out out interface inside route inside 192.168.10.0 255.255.255.0 10.1.1.254 1 route inside 10.1.2.0 255.255.255.0 10.1.1.201 1 timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02 timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00 timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00 timeout uauth 2:00:00 absolute aaa-server TACACS+ protocol tacacs+ aaa-server RADIUS protocol radius username fwbtest password AAAAAAAAAAAAAAAA encrypted privilege 15 aaa authentication ssh console LOCAL snmp-server host inside 10.1.1.180 community public snmp-server host inside 10.1.1.30 community public snmp-server host inside 10.1.1.40 poll community public version 2c no snmp-server location no snmp-server contact snmp-server community public crypto ipsec transform-set spde esp-des esp-sha-hmac crypto map spdemap 21 set peer 192.0.2.254 crypto map spdemap 21 set transform-set spde crypto isakmp identity address crypto isakmp policy 21 authentication pre-share encryption des hash sha group 1 lifetime 3600 crypto isakmp policy 65535 authentication pre-share encryption 3des hash sha group 2 lifetime 86400 tunnel-group 192.0.2.254 type ipsec-l2l tunnel-group 192.0.2.254 ipsec-attributes pre-shared-key * telnet timeout 5 ssh scopy enable ssh 10.1.1.0 255.255.255.0 inside ssh 10.1.2.0 255.255.255.0 inside ssh 192.0.2.100 255.255.255.255 outside ssh timeout 20 console timeout 0 ! class-map custom_h323_h225_inspection match port tcp range h323 1721 class-map custom_http_inspection match port tcp range www 88 class-map inspection_default match default-inspection-traffic ! ! policy-map type inspect dns migrated_dns_map_1 parameters message-length maximum 512 policy-map global_policy class inspection_default inspect dns migrated_dns_map_1 inspect ftp inspect h323 h225 inspect h323 ras inspect http inspect netbios inspect rsh inspect rtsp inspect skinny inspect sqlnet inspect sunrpc inspect tftp inspect sip inspect xdmcp inspect ctiqbe inspect icmp inspect ils inspect mgcp inspect esmtp class custom_h323_h225_inspection inspect h323 h225 class custom_http_inspection inspect http ! service-policy global_policy global prompt hostname context Cryptochecksum:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-acl.output0000644000175000017500000001610711733011756030001 0ustar sylvestresylvestre3: Platform: ASA 3: Version: 8.3 8: New interface: Vlan1 8: Interface parameters: inside 8: Interface label: inside 10: Interface address: 192.168.1.1/255.255.255.0 14: New interface: Vlan2 14: Interface parameters: outside 14: Interface label: outside 16: Interface address: dhcp/ 20: New interface: Ethernet0/0 20: Interface comment: Switch port 0 / 0 77: Named object (service) http.0 81: Named object (service) https.0 85: Named object (service) match-1 88: Named object (service) match-2 91: Named object (address) server-1.0 95: Named object (address) Internal_net.0 99: Named object (address) external_net.0 102: Object Group (service) id5102X14531.srv.tcp.0 107: Named object (service) ip2 110: Object Group (protocol) pg1 116: Object Group (network) src-network-group-1 120: Object Group (network) dst-network-group-1 123: Object Group (service) test-service-1 126: Object Group (service) test-service-2 129: Object Group (service) test-service-3 133: Object Group (service) test-service-4 144: Rule comment: 0 ( global ) 148: filtering rule: access list inside_in, action permit 149: filtering rule: access list inside_in, action permit 150: filtering rule: access list inside_in, action permit 151: filtering rule: access list inside_in, action permit 152: filtering rule: access list inside_in, action permit 154: filtering rule: access list inside_in, action permit 155: filtering rule: access list inside_in, action permit 156: filtering rule: access list inside_in, action permit 157: filtering rule: access list inside_in, action permit 158: filtering rule: access list inside_in, action permit 159: filtering rule: access list inside_in, action permit 160: filtering rule: access list inside_in, action permit 161: filtering rule: access list inside_in, action permit 162: filtering rule: access list inside_in, action permit 163: filtering rule: access list inside_in, action permit 164: filtering rule: access list inside_in, action permit 165: filtering rule: access list inside_in, action permit 166: filtering rule: access list inside_in, action permit 167: filtering rule: access list inside_in, action permit 168: filtering rule: access list inside_in, action permit 171: filtering rule: access list inside_in, action permit 172: Rule comment: 3 ( global ) 175: filtering rule: access list inside_in, action deny 177: filtering rule: access list inside_in, action deny 179: filtering rule: access list inside_in, action deny 180: filtering rule: access list inside_in, action deny 181: filtering rule: access list inside_in, action deny 183: filtering rule: access list inside_in, action deny 189: filtering rule: access list inside_in, action permit 189: Object Group (service) id5102X14531.srv.tcp.0-mirror 191: filtering rule: access list inside_in, action permit 193: filtering rule: access list inside_in, action permit 194: filtering rule: access list inside_in, action permit 195: filtering rule: access list inside_in, action permit 196: filtering rule: access list inside_in, action permit 197: filtering rule: access list inside_in, action permit 199: filtering rule: access list inside_in, action permit 199: Object Group (service) id5102X14531.srv.tcp.0-mirror 200: filtering rule: access list inside_in, action permit 201: filtering rule: access list inside_in, action permit 202: filtering rule: access list inside_in, action permit 203: filtering rule: access list inside_in, action permit 204: filtering rule: access list inside_in, action permit 206: filtering rule: access list inside_out, action permit 207: filtering rule: access list inside_out, action permit 208: filtering rule: access list inside_out, action permit 209: filtering rule: access list inside_out, action permit 210: filtering rule: access list inside_out, action permit 211: filtering rule: access list inside_out, action permit 213: filtering rule: access list inside_out, action permit 214: filtering rule: access list inside_out, action permit 215: filtering rule: access list inside_out, action permit 216: filtering rule: access list inside_out, action permit 217: filtering rule: access list inside_out, action permit 218: filtering rule: access list inside_out, action permit 221: filtering rule: access list inside_out, action permit 221: Error: tcp port name 'foo' is unknown 223: filtering rule: access list inside_out, action permit 225: filtering rule: access list inside_out, action permit 227: filtering rule: access list inside_out, action permit 229: filtering rule: access list inside_out, action permit 231: filtering rule: access list inside_out, action permit 232: filtering rule: access list inside_out, action permit 234: filtering rule: access list outside_out, action permit 235: filtering rule: access list outside_out, action permit 236: filtering rule: access list outside_out, action permit 240: filtering rule: access list outside_in, action permit 240: Object Group (service) test-service-1-mirror 241: filtering rule: access list outside_in, action permit 241: Object Group (service) test-service-2-mirror 242: filtering rule: access list outside_in, action permit 242: Object Group (service) test-service-3-mirror 242: Object Group (service) test-service-1-mirror 243: filtering rule: access list outside_in, action permit 243: Object Group (service) test-service-4-mirror 243: Object Group (service) test-service-1-mirror 247: filtering rule: access list outside_in, action permit 247: Object Group (service) tcp port match line 247 248: filtering rule: access list outside_in, action permit 248: Object Group (service) tcp port match line 248 249: filtering rule: access list outside_in, action permit 249: Object Group (service) tcp port match line 249 250: filtering rule: access list outside_in, action permit 250: Object Group (service) tcp port match line 250 253: filtering rule: access list outside_in, action permit 253: Error: Rule matches tcp or udp ports using "neq" port operator in both source and destination. This configuration is not supported by import at this time, please fix manually 264: filtering rule: access list inside_in, action permit 264: Object Group (service) test-service-1-mirror 264: Object Group (service) tcp port match line 264 265: filtering rule: access list inside_in, action permit 265: Object Group (service) test-service-2-mirror 265: Object Group (service) tcp port match line 265 266: filtering rule: access list inside_in, action permit 266: Object Group (service) test-service-1-mirror 266: Object Group (service) tcp port match line 266 267: filtering rule: access list inside_in, action permit 267: Object Group (service) test-service-3-mirror 267: Object Group (service) test-service-1-mirror 267: Object Group (service) tcp port match line 267 268: filtering rule: access list inside_in, action permit 268: Object Group (service) test-service-1-mirror 268: Object Group (service) tcp port match line 268 269: filtering rule: access list inside_in, action permit 269: Object Group (service) tcp port match line 269 276: Interface Vlan1 ruleset inside_in direction 'in' 277: Interface Vlan1 ruleset inside_out direction 'out' 278: Interface Vlan2 ruleset outside_in direction 'in' 279: Interface Vlan2 ruleset outside_out direction 'out' fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.0-names.test0000644000175000017500000000573211733011756027763 0ustar sylvestresylvestre: Saved : PIX Version 8.0(3) ! hostname pixfirewall enable password XXXXXXXXXXXXXXXX encrypted names name 192.168.2.0 inside_network name 192.168.2.221 inside_ip name 192.168.2.240 net_1 name 1.1.1.1 named-host-1 name 1.2.3.4 object-1234 ! interface Ethernet0 nameif inside security-level 100 ip address inside_ip 255.255.255.0 ! interface Ethernet1 nameif outside security-level 0 ip address 192.0.2.221 255.255.255.0 ! interface Ethernet2 shutdown no nameif no security-level no ip address ! interface Ethernet3 shutdown no nameif no security-level no ip address ! interface Ethernet4 shutdown no nameif no security-level no ip address ! passwd YYYYYYYYYYYYYYYY encrypted ftp mode passive object-group network net_1_group network-object net_1 255.255.255.240 network-object 192.168.2.0 255.255.255.0 object-group network another_group_net_1 network-object net_1 255.255.255.240 network-object 192.168.3.0 255.255.255.0 object-group network host_net_1 network-object host net_1 ! whitespace after net_1 object-group network host_net_2 network-object host net_1 object-group network net-1 description single network object-group network-object inside_network 255.255.255.0 object-group network net-2 description multiple network-object objects network-object 192.168.1.0 255.255.255.0 network-object inside_network 255.255.255.0 network-object 192.168.3.0 255.255.255.0 access-list inside_in extended permit ip inside_network 255.255.255.0 any access-list inside_in extended deny ip any any log warnings access-group inside_in in interface inside pager lines 24 mtu inside 1500 mtu outside 1500 icmp unreachable rate-limit 1 burst-size 1 icmp permit any echo outside icmp permit any 111 outside icmp permit any time-exceeded outside icmp permit any echo-reply outside icmp permit any unreachable outside icmp permit any outside icmp permit host 10.1.1.202 time-exceeded inside icmp permit host 10.1.1.202 echo-reply inside icmp permit host 10.1.1.202 unreachable inside icmp permit any echo inside icmp permit any time-exceeded inside icmp permit any echo-reply inside icmp permit any unreachable inside icmp permit any inside icmp permit 10.1.1.0 255.255.255.0 inside no asdm history enable arp timeout 14400 timeout xlate 3:00:00 timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02 timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00 timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00 timeout uauth 0:05:00 absolute dynamic-access-policy-record DfltAccessPolicy no snmp-server location no snmp-server contact snmp-server enable traps snmp authentication linkup linkdown coldstart telnet inside_network 255.255.255.0 inside telnet timeout 5 ssh inside_network 255.255.255.0 inside ssh timeout 5 console timeout 0 threat-detection basic-threat threat-detection statistics access-list username cisco password ZZZZZZZZZZZZZZZZ encrypted ! ! prompt hostname context Cryptochecksum:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : end fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-objects-and-groups.output0000644000175000017500000001067611733011756032755 0ustar sylvestresylvestre3: Platform: ASA 3: Version: 8.3 7: New interface: Vlan1 7: Interface comment: inside interface 8: Interface parameters: inside 8: Interface label: inside 10: Interface address: dhcp/ 13: New interface: Vlan2 13: Interface comment: outside interface 14: Interface parameters: outside 14: Interface label: outside 16: Interface address: 192.168.2.1/255.255.255.0 19: New interface: Ethernet0/0 19: Interface comment: Switch port 0 / 0 20: Switch port vlan 2 25: Named object (address) internal_subnet_1 28: Named object (address) internal_subnet_2 32: Named object (address) internal_subnet_3 36: Named object (address) internal_subnet_4 39: Named object (address) Internal_net 41: Named object (address) outside_range-1 43: Named object (address) range_1 45: Named object (address) firewall90:FastEthernet1:ip-1 47: Named object (address) hostA:eth0 49: Named object (address) spamhost1 51: Named object (address) spamhost2 53: Named object (address) external_gw2 58: Named object (address) my-range-obj 60: Named object (address) my-inside-net 62: Warning: Import of ASA 8.3 nat command is not supported at this time 62: Warning: Import of named objects with "nat" command is not supported at this time 67: Named object (address) ipv6-host-object-1 68: Warning: IPv6 import is not supported. 70: Named object (address) ipv6-network-object-1 71: Warning: IPv6 import is not supported. 73: Named object (address) ipv6-host-object-3 74: Warning: IPv6 import is not supported. 76: Named object (address) ipv6-host-object-3 77: Warning: IPv6 import is not supported. 81: Named object (address) dummy-address 84: Named object (address) internal_subnet_5 88: Named object (address) dummy-address-1 89: Named object (address) internal_subnet_6 92: Named object (address) ipv6-host-object-2 93: Warning: IPv6 import is not supported. 95: Named object (address) host-1 99: Named object (service) smtp 101: Named object (service) http 103: Named object (service) ssh 105: Named object (service) squid 107: Named object (service) smtps 110: Named object (service) icmp1 112: Named object (service) icmp2 114: Named object (service) ip5 118: Named object (service) tcp-src-1 121: Named object (service) tcp-src-2 123: Named object (service) tcp-src-3 125: Named object (service) tcp-src-4 127: Named object (service) tcp-src-5 130: Named object (service) tcp-dst-1 132: Named object (service) tcp-dst-2 134: Named object (service) tcp-dst-3 136: Named object (service) tcp-dst-4 138: Named object (service) tcp-dst-5 142: Named object (service) tcp-src-dst-1 144: Named object (service) tcp-src-dst-2 146: Named object (service) tcp-src-dst-3 148: Named object (service) tcp-src-dst-4 150: Named object (service) tcp-src-dst-5 154: Named object (service) udp-src-1 156: Named object (service) udp-src-2 158: Named object (service) udp-src-3 160: Named object (service) udp-src-4 162: Named object (service) udp-src-5 165: Named object (service) udp-dst-1 167: Named object (service) udp-dst-2 169: Named object (service) udp-dst-3 171: Named object (service) udp-dst-4 173: Named object (service) udp-dst-5 177: Named object (service) ip1 179: Named object (service) ip2 181: Named object (service) icmp6-1 182: Warning: Import of IPv6 addresses and servcies is not supported at this time 185: Named object (service) ip3 186: Warning: Unknown service name some_weird_protocol 190: Named object (service) ip4 193: Object Group (network) outside.id178211X29963.osrc.net.0 196: Object Group (network) outside.id21353X4994.osrc.net.0 200: Object Group (network) outside.id77971X5929.osrc.net.1 203: Object Group (network) outside.id77971X5929.odst.net.1 206: Object Group (network) outside.id77971X5929.tsrc.net.1 209: Object Group (network) outside.id77971X5929.osrc.net.0 212: Object Group (network) outside.id77971X5929.odst.net.0 215: Object Group (network) outside.id77971X5929.tsrc.net.0 219: Object Group (service) outside.id77971X5929.osrv.1 223: Object Group (service) sg1 228: Object Group (service) sg2 232: Object Group (service) sg3 238: Object Group (service) sg4 243: Object Group (service) sg5 254: Object Group (service) combo-group-1 258: Object Group (service) neq-group-2 274: Object Group (protocol) pg1 279: Object Group (protocol) pg2 284: Object Group (icmp) ig1 287: Object Group (icmp) ig2 290: Object Group (icmp) ig3 296: Object Group (service) id5102X14531.srv.tcp.0 301: Object Group (service) tcp-udp-1 304: filtering rule: access list inside_in, action permit 305: Interface Vlan1 ruleset inside_in direction 'in' fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/test_data/asa8.3-acl-object-groups.fwb0000644000175000017500000032304011733011756031775 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/PIXImporterTest.h0000644000175000017500000000474311733011756026213 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PIXIMPORTERTEST_H #define PIXIMPORTERTEST_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include #include #include #include class PIXImporterTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *db; libfwbuilder::Library *lib; libfwbuilder::QueueLogger *logger; int predictable_id_tracker; std::map id_mapping; void compareResults(libfwbuilder::QueueLogger* logger, QString expected_result_file_name, QString obtained_result_file_name); void compareFwbFiles(QString expected_result_file_name, QString obtained_result_file_name); std::string openTestFile(const QString &file_name); public: void setUp(); void PIX_6_Test(); void PIX_7_Test(); void PIX_7_NAT_Test(); void ASA_8_0_Test(); void ASA_8_3_Test(); void FWSM_4_1_Test(); void ObjectsAndGroupsTest(); void ACLObjectsAndGroupsTest(); void ACLTest(); void NamesTest(); CPPUNIT_TEST_SUITE(PIXImporterTest); CPPUNIT_TEST(PIX_6_Test); CPPUNIT_TEST(PIX_7_Test); CPPUNIT_TEST(PIX_7_NAT_Test); CPPUNIT_TEST(ASA_8_0_Test); CPPUNIT_TEST(ASA_8_3_Test); CPPUNIT_TEST(ObjectsAndGroupsTest); CPPUNIT_TEST(ACLObjectsAndGroupsTest); CPPUNIT_TEST(ACLTest); CPPUNIT_TEST(NamesTest); CPPUNIT_TEST(FWSM_4_1_Test); CPPUNIT_TEST_SUITE_END(); }; #endif // PIXIMPORTERTEST_H fwbuilder-5.1.0.3599/src/unit_tests/PIXImporterTest/PIXImporterTest.pro0000644000175000017500000000023011733011756026547 0ustar sylvestresylvestreinclude(../tests_common.pri) TARGET = PIXImporterTest HEADERS += PIXImporterTest.h SOURCES += main_PIXImporterTest.cpp \ PIXImporterTest.cpp fwbuilder-5.1.0.3599/src/unit_tests/UDPServiceDialogTest/0000755000175000017500000000000011733011756023717 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/UDPServiceDialogTest/UDPServiceDialogTest.cpp0000644000175000017500000001350311733011756030356 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: UDPServiceDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UDPServiceDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/Address.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" #include "UDPServiceDialogTest.h" #include "StartTipDialog.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Interface.h" #include "IPServiceDialog.h" #include "fwbuilder/IPService.h" #include "fwbuilder/UDPService.h" #include "UDPServiceDialog.h" using namespace std; using namespace libfwbuilder; void UDPServiceDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); om = dynamic_cast(mw->getCurrentObjectTree()->parent()->parent()); QTest::qWait(1000); } Library* UDPServiceDialogTest::findUserLibrary() { Library *lib = NULL; foreach (FWObject *obj, mw->db()->getByType(Library::TYPENAME)) { if (obj->getName() == "User") { lib = Library::cast(obj); break; } } return lib; } void UDPServiceDialogTest::testDialog() { UDPService *service = UDPService::cast(om->createObject(FWBTree().getStandardSlotForObject(findUserLibrary(), UDPService::TYPENAME), UDPService::TYPENAME, "testUDPService")); om->editObject(service); UDPServiceDialog *dialog = mw->findChild("w_UDPServiceDialog"); QLineEdit *obj_name = dialog->findChild("obj_name"); QSpinBox *ss = dialog->findChild("ss"); QSpinBox *se = dialog->findChild("se"); QSpinBox *ds = dialog->findChild("ds"); QSpinBox *de = dialog->findChild("de"); TextEditWidget *comment = dialog->findChild("comment"); obj_name->clear(); QTest::keyClicks(obj_name, "TestUDPService"); QTest::keyClick(obj_name, Qt::Key_Enter); QVERIFY(service->getName() == "TestUDPService"); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (service->getComment() == "Test comment"); // check that it is not possible to set value more than 65535 se->setValue(65530); for (int i=0; i<100; i++) QTest::keyClick(se, Qt::Key_Up); QTest::keyClick(se, Qt::Key_Enter); QVERIFY(service->getSrcRangeEnd() == 65535); ss->setValue(65530); for (int i=0; i<65560; i++) QTest::keyClick(ss, Qt::Key_Up); QTest::keyClick(ss, Qt::Key_Enter); QVERIFY(service->getSrcRangeStart() == 65535); de->setValue(65530); for (int i=0; i<100; i++) QTest::keyClick(de, Qt::Key_Up); QTest::keyClick(de, Qt::Key_Enter); QVERIFY(service->getDstRangeEnd() == 65535); ds->setValue(65530); for (int i=0; i<100; i++) QTest::keyClick(ds, Qt::Key_Up); QTest::keyClick(ds, Qt::Key_Enter); QVERIFY(service->getDstRangeStart() == 65535); // check that range end change when range start is more se->clear(); for (int i=0; i<11; i++) QTest::keyClick(se, Qt::Key_Up); QTest::keyClick(se, Qt::Key_Enter); ss->clear(); for (int i=0; i<21; i++) QTest::keyClick(ss, Qt::Key_Up); QTest::keyClick(ss, Qt::Key_Enter); QVERIFY(ss->value() == se->value()); de->clear(); for (int i=0; i<11; i++) QTest::keyClick(de, Qt::Key_Up); QTest::keyClick(de, Qt::Key_Enter); ds->clear(); for (int i=0; i<21; i++) QTest::keyClick(ds, Qt::Key_Up); QTest::keyClick(ds, Qt::Key_Enter); QVERIFY(ds->value() == de->value()); // check that range end does not change if range start is less ss->setValue(0); se->setValue(0); for (int i=0; i<20; i++) QTest::keyClick(se, Qt::Key_Up); QTest::keyClick(se, Qt::Key_Enter); for (int i=0; i<10; i++) QTest::keyClick(ss, Qt::Key_Up); QTest::keyClick(ss, Qt::Key_Enter); QVERIFY(se->value() == 20); //same for destination ds->setValue(0); de->setValue(0); for (int i=0; i<20; i++) QTest::keyClick(de, Qt::Key_Up); QTest::keyClick(de, Qt::Key_Enter); for (int i=0; i<10; i++) QTest::keyClick(ds, Qt::Key_Up); QTest::keyClick(ds, Qt::Key_Enter); QVERIFY(de->value() == 20); qDebug() << "done"; // it sometimes hangs without this } fwbuilder-5.1.0.3599/src/unit_tests/UDPServiceDialogTest/main_UDPServiceDialogTest.cpp0000644000175000017500000000330411733011756031360 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_IPDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UDPServiceDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new UDPServiceDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/UDPServiceDialogTest/UDPServiceDialogTest.h0000644000175000017500000000241011733011756030016 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: UDPServiceDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef UDPServiceDialogTest_H #define UDPServiceDialogTest_H #include #include "ObjectManipulator.h" #include "fwbuilder/Library.h" class UDPServiceDialogTest : public QObject { Q_OBJECT libfwbuilder::Library* findUserLibrary(); ObjectManipulator *om; private slots: void initTestCase(); void testDialog(); }; #endif // UDPServiceDialogTest_H fwbuilder-5.1.0.3599/src/unit_tests/UDPServiceDialogTest/UDPServiceDialogTest.pro0000644000175000017500000000030011733011756030363 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = UDPServiceDialogTest SOURCES += main_UDPServiceDialogTest.cpp \ UDPServiceDialogTest.cpp HEADERS += UDPServiceDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/AddressRangeDialogTest/0000755000175000017500000000000011733011756024310 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/AddressRangeDialogTest/AddressRangeDialogTest.cpp0000644000175000017500000001310711733011756031340 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: AddressRangeDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AddressRangeDialogTest.h" #include "../../../../config.h" //#include "../../global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ObjectEditor.h" #include "FWBApplication.h" #include "FWObjectClipboard.h" #include "TextEditWidget.h" #include "fwbuilder/AddressRange.h" #include "StartTipDialog.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObjectDatabase.h" using namespace std; using namespace libfwbuilder; QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void AddressRangeDialogTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->startupLoad(); StartTipDialog *d = mw->findChild(); if (d!=NULL) d->close(); QTest::qWait(10); } void AddressRangeDialogTest::checkMessageBox() { QVERIFY(app->activeModalWidget()->metaObject()->className() == QMessageBox().metaObject()->className()); QVERIFY(dynamic_cast(app->activeModalWidget())->text().contains("300.300.300.300") || dynamic_cast(app->activeModalWidget())->text().contains("200.200.200.200") ); dynamic_cast(app->activeModalWidget())->reject(); } void AddressRangeDialogTest::editSelectedObject() { //NOTUSED QToolButton* newButton = mw->findChild("newButton"); ObjectManipulator* om = dynamic_cast( mw->getCurrentObjectTree()->parent()->parent()); om->createObject( FWBTree().getStandardSlotForObject( om->getCurrentLib(), AddressRange::TYPENAME), AddressRange::TYPENAME, "Address Range"); QTest::qWait(100); QTreeWidgetItem *item = mw->getCurrentObjectTree()->findItems("Address Range", Qt::MatchRecursive | Qt::MatchExactly, 0).first(); mw->getCurrentObjectTree()->setCurrentItem(item, 0, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); om->editSelectedObject(); QTest::qWait(100); om->editSelectedObject(); QWidget *address_range_dialog = mw->findChild("w_AddressRangeDialog"); QVERIFY(address_range_dialog != NULL); QLineEdit *rangeStart = address_range_dialog->findChildren("rangeStart").first(); QLineEdit *rangeEnd = address_range_dialog->findChildren("rangeEnd").first(); QLineEdit *objName = address_range_dialog->findChild("obj_name"); QVERIFY(objName != NULL); TextEditWidget *comment = address_range_dialog->findChild("comment"); QVERIFY(comment != NULL); objName->clear(); QTest::keyClicks(objName, "TestAddressRange"); QTest::keyClick(objName, Qt::Key_Enter); QVERIFY (dynamic_cast(item)->getFWObject()->getName() == "TestAddressRange"); QTest::qWait(100); comment->clear(); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClicks(comment, "Test comment"); QTest::mouseClick(comment, Qt::LeftButton); QTest::keyClick(comment, Qt::Key_Tab); QTest::qWait(100); QVERIFY (dynamic_cast(item)->getFWObject()->getComment() == "Test comment"); rangeStart->clear(); QTest::keyClicks(rangeStart, "1.1.1.1"); QTest::keyClick(rangeStart, Qt::Key_Enter); QVERIFY (libfwbuilder::AddressRange::cast(dynamic_cast(item)->getFWObject())->getRangeStart().toString() == "1.1.1.1"); QTest::qWait(100); rangeEnd->clear(); QTest::keyClicks(rangeEnd, "1.1.1.10"); QTest::keyClick(rangeEnd, Qt::Key_Enter); QVERIFY (libfwbuilder::AddressRange::cast(dynamic_cast(item)->getFWObject())->getRangeEnd().toString() == "1.1.1.10"); QTimer::singleShot(1000, this, SLOT(checkMessageBox())); rangeStart->clear(); QTest::keyClicks(rangeStart, "300.300.300.300"); QTest::keyClick(rangeStart, Qt::Key_Enter); rangeStart->clear(); QTest::keyClicks(rangeStart, "200.200.200.200"); QTest::keyClick(rangeStart, Qt::Key_Enter); QTest::qWait(100); QTimer::singleShot(100, this, SLOT(checkMessageBox())); rangeEnd->clear(); QTest::keyClicks(rangeEnd, "300.300.300.300"); QTest::keyClick(rangeEnd, Qt::Key_Enter); QTest::qWait(1000); } fwbuilder-5.1.0.3599/src/unit_tests/AddressRangeDialogTest/AddressRangeDialogTest.h0000644000175000017500000000227411733011756031010 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: AddressRangeDialogTest.h 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECTMANIPULATORTEST_H #define OBJECTMANIPULATORTEST_H #include class AddressRangeDialogTest : public QObject { Q_OBJECT private slots: void initTestCase(); void editSelectedObject(); public slots: void checkMessageBox(); }; #endif // OBJECTMANIPULATORTEST_H fwbuilder-5.1.0.3599/src/unit_tests/AddressRangeDialogTest/main_AddressRangeDialogTest.cpp0000644000175000017500000000332211733011756032342 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_AddressRangeDialogTest.cpp 2723 2010-03-16 17:32:18Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AddressRangeDialogTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new AddressRangeDialogTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/AddressRangeDialogTest/AddressRangeDialogTest.pro0000644000175000017500000000040611733011756031354 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = AddressRangeDialogTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += AddressRangeDialogTest.cpp \ main_AddressRangeDialogTest.cpp HEADERS += AddressRangeDialogTest.h fwbuilder-5.1.0.3599/src/unit_tests/instDialogObjectListTest/0000755000175000017500000000000011733011756024706 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/instDialogObjectListTest/test.fwb0000644000175000017500000035063411733011756026400 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established -m state --state ESTABLISHED,RELATED -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/instDialogObjectListTest/instDialogObjectListTest.cpp0000644000175000017500000005562311733011756032345 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogObjectListTest.cpp 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ================================ Tests implemented in this module: ticket 1089 * user clicks "compile" button in the topmost toolbar. The list should include all firewalls, but only those that require recompile should have "compile" checkboxes checked. * user uses main menu "Rules/Compile". This is the same function as the previous one * user opens Policy of the firewall "test1" and clicks button "Compile" in the toolbar right above rule set view. The list should include only firewall "test1" and checkbox "Compile" should be checked because it requires recompile * the same test as the previous one, but with firewall test2. This one does not require recompile and checkbox "Compile" should not be checked. * user selects firewall test1 in the tree and opens context menu, then clicks item "Compile". This is the same test as 3. * user selects firewall test2 in the tree and opens context menu, then clicks item "Compile". This is the same test as 4. * Select two firewalls in the tree (test1 and test2), open context menu and click "Compile". Should get a list with both firewalls, with checkbox "Compile" selected for test2 and not selected for test1. * all previous tests tested "Compile" function. This test should test first step of the "Install" function. * emulate clicking "Install" button in the main toolbar * check that the first page of the dialog has column of "compile" checkboxes and column of "install" checkboxes * check that "compile" checkboxes are checked according to the rules described above in this ticket Ticket 1153: * tests page1_5(), page1_6(), page1_7() should emulate opening context menu and clicking menu item "Compile" (see ticket #1089). Please add check that the menu item "Compile" is present and enabled * test page1_8() should also check that checkboxes in column "compile" and "install" are visible and enabled. Right now it only checks their "checked" state * test page1_8() should also test checkboxes next to the firewall objects test3 and test4 */ #include "instDialogObjectListTest.h" #include "unistd.h" #include #include #include #include #include #include #include #include "FWBApplication.h" #include "FWObjectClipboard.h" using namespace std; using namespace QTest; using namespace libfwbuilder; #define COMPILE_CHECKBOX_COLUMN 1 #define INSTALL_CHECKBOX_COLUMN 2 void instDialogObjectListTest::initTestCase() { new FWObjectClipboard(); mw = new FWWindow(); mw->show(); mw->loadFile("test_work.fwb", false); } void instDialogObjectListTest::openPolicy(QString fwname) { Policy *p = NULL; foreach (FWObject *fw, mw->db()->getByTypeDeep(Firewall::TYPENAME)) { if (fw->getName() == fwname.toStdString()) { p = Firewall::cast(fw)->getPolicy(); } } QVERIFY (p != NULL); QCoreApplication::postEvent(mw, new openRulesetImmediatelyEvent(mw->activeProject()->getFileName(), p->getId())); QTest::qWait(100); } void instDialogObjectListTest::verifyCompileCheckboxes(QTreeWidget *table, int items) { if (items != -1) QVERIFY(table->topLevelItemCount() == items); QTreeWidgetItemIterator it(table, QTreeWidgetItemIterator::Enabled); while (*it) { if ((*it)->text(0) == "cluster1") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Checked); } if ((*it)->text(0) == "test1") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Checked); } if ((*it)->text(0) == "test2") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } if ((*it)->text(0) == "test3") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } if ((*it)->text(0) == "test4") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } it++; } } /* * This function checks the state of checkboxes after firewall test1 has been compiled */ void instDialogObjectListTest::verifyCompileCheckboxes_2(QTreeWidget *table) { QTreeWidgetItemIterator it(table, QTreeWidgetItemIterator::Enabled); while (*it) { if ((*it)->text(0) == "cluster1") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Checked); } if ((*it)->text(0) == "test1") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } if ((*it)->text(0) == "test2") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } if ((*it)->text(0) == "test3") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } if ((*it)->text(0) == "test4") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(COMPILE_CHECKBOX_COLUMN) == Qt::Unchecked); } it++; } } void instDialogObjectListTest::verifyInstallCheckboxes(QTreeWidget *table, int items) { if (items != -1) Q_ASSERT(table->topLevelItemCount() == items); QTreeWidgetItemIterator it(table, QTreeWidgetItemIterator::Enabled); while (*it) { if ((*it)->text(0) == "cluster1") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(INSTALL_CHECKBOX_COLUMN) == Qt::Unchecked); } if ((*it)->text(0) == "test1") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(INSTALL_CHECKBOX_COLUMN) == Qt::Checked); } if ((*it)->text(0) == "test2") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(INSTALL_CHECKBOX_COLUMN) == Qt::Checked); } if ((*it)->text(0) == "test3") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(INSTALL_CHECKBOX_COLUMN) == Qt::Checked); } if ((*it)->text(0) == "test4") { QVERIFY(((*it)->flags() & Qt::ItemIsUserCheckable) != 0); QVERIFY((*it)->checkState(INSTALL_CHECKBOX_COLUMN) == Qt::Checked); } it++; } } QPoint findItemPos(ObjectTreeViewItem *item, ObjectTreeView *tree) { for (int h=10; hheight(); h+=1) { for (int w=75; wwidth(); w+=1) { if(tree->itemAt(w,h) == item) return QPoint(w, h); } } return QPoint(-1,-1); } void instDialogObjectListTest::closeContextMenu() { QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } menu->hide(); } /* * This function finds and activates an item with given name in the * context menu. If item is absent in the menu or is disabled, it * fails the test. */ void instDialogObjectListTest::openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText) { QTimer::singleShot(100, this, SLOT(closeContextMenu())); om->contextMenuRequested(findItemPos(item, tree)); bool found_menu_item = false; QMenu *menu = NULL; foreach(QWidget *w, QApplication::allWidgets()) { if (w->objectName() == "objectTreeContextMenu") { menu = dynamic_cast(w); break; } } QVERIFY(menu != NULL); foreach (QObject *act, menu->children()) { QAction *action = dynamic_cast(act); if (action == NULL) continue; if (action->text() == actionText) { QVERIFY(action->isEnabled() == true); action->activate(QAction::Trigger); found_menu_item = true; break; } } QVERIFY2(found_menu_item == true, QString("Item %1 not found in the context menu").arg(actionText).toAscii().constData()); } /* * user clicks "compile" button in the topmost toolbar. The list * should include all firewalls, but only those that require * recompile should have "compile" checkboxes checked. */ void instDialogObjectListTest::test_compile_1() { QAction *compile = mw->findChild("compileAction"); compile->activate(QAction::Trigger); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 3); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * user uses main menu "Rules/Compile". This is the same function as * the previous one */ void instDialogObjectListTest::test_compile_2() { QMenu *rules = mw->menuBar()->findChild("RulesMenu"); QAction *compile = NULL; foreach(QAction *itm, rules->actions()) if (itm->objectName() == "compileAction") compile = dynamic_cast(itm); QVERIFY(compile != NULL); compile->activate(QAction::Trigger); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 3); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * user opens Policy of the firewall "test1" and clicks button * "Compile" in the toolbar right above rule set view. The list should * include only firewall "test1" and checkbox "Compile" should be checked * because it requires recompile */ void instDialogObjectListTest::test_compile_3() { openPolicy("test1"); QTest::qWait(10); QToolButton* compileThis = mw->activeProject()->findChild("compile_this_fw"); QVERIFY(compileThis != NULL); QTest::mouseClick (compileThis, Qt::LeftButton); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); QVERIFY(table->topLevelItemCount() == 1); verifyCompileCheckboxes(table, 1); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * the same test as the previous one, but with firewall test2. This * one does not require recompile and checkbox "Compile" should not * be checked. */ void instDialogObjectListTest::test_compile_4() { openPolicy("test2"); QTest::qWait(100); QToolButton* compileThis = mw->activeProject()->findChild("compile_this_fw"); QVERIFY(compileThis != NULL); QTest::mouseClick (compileThis, Qt::LeftButton); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 1); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * user selects firewall test1 in the tree and opens context menu, * then clicks item "Compile". This is the same test as 3. */ void instDialogObjectListTest::test_compile_5() { ObjectTreeView *tree = mw->activeProject()->getCurrentObjectTree(); tree->expandAll(); ObjectTreeViewItem *test1 = dynamic_cast(tree->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *test2 = dynamic_cast(tree->findItems("test2", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); tree->scrollToItem(test1); // <<<<<<<<<<<<<< tree->selectionModel()->select(tree->indexAt(findItemPos(test1, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(test1); ObjectManipulator *om = mw->activeProject()->findChild("om"); openContextMenu(om, test1, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 1); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * user selects firewall test2 in the tree and opens context menu, * then clicks item "Compile". This is the same test as 4. */ void instDialogObjectListTest::test_compile_6() { ObjectTreeView *tree = mw->activeProject()->getCurrentObjectTree(); tree->expandAll(); ObjectTreeViewItem *test1 = dynamic_cast(tree->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *test2 = dynamic_cast(tree->findItems("test2", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); tree->scrollToItem(test2); // <<<<<<<<<<<<<< tree->selectionModel()->select(tree->indexAt(findItemPos(test2, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(test2); ObjectManipulator *om = mw->activeProject()->findChild("om"); openContextMenu(om, test2, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 1); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * Select two firewalls in the tree (test1 and test2), open context * menu and click "Compile". Should get a list with both firewalls, with * checkbox "Compile" selected for test2 and not selected for test1. */ void instDialogObjectListTest::test_compile_7() { ObjectTreeView *tree = mw->activeProject()->getCurrentObjectTree(); tree->expandAll(); ObjectTreeViewItem *test1 = dynamic_cast(tree->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *test2 = dynamic_cast(tree->findItems("test2", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); tree->scrollToItem(test1); tree->selectionModel()->select( tree->indexAt(findItemPos(test1, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(test1); tree->selectionModel()->select( tree->indexAt(findItemPos(test2, tree)), QItemSelectionModel::Select); ObjectManipulator *om = mw->activeProject()->findChild("om"); openContextMenu(om, test2, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 2); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * all previous tests tested "Compile" function. This test should test * first step of the "Install" function. */ void instDialogObjectListTest::test_install_1() { QAction *compile = mw->findChild("installAction"); compile->activate(QAction::Trigger); QTest::qWait(100); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == false); verifyCompileCheckboxes(table, 3); verifyInstallCheckboxes(table, 3); QTest::qWait(100); dlg->findChild("cancelButton")->click(); QTest::qWait(100); } /* * Select two firewalls in the tree (test1 and test2), open context * menu and click "Compile". Should get a list with both firewalls, * with checkbox "Compile" selected for test2 and not selected for * test1. Then click "Next" to compile, wait until done, then click * "Finish". Select the same firewalls in the tree and open instDialog * again, now both checkboxes should be turned off. * * This test changes "last_compiled" timestamp of the firewall object * test2 so it should run after all tests above because it changes the * state of the "compile" checkbox next to this firewall in the list. */ void instDialogObjectListTest::test_actually_compile_1() { if (QFileInfo("test1.fw").exists()) QVERIFY(QFile("test1.fw").remove()); ObjectTreeView *tree = mw->activeProject()->getCurrentObjectTree(); tree->expandAll(); ObjectTreeViewItem *test1 = dynamic_cast(tree->findItems("test1", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); ObjectTreeViewItem *test2 = dynamic_cast(tree->findItems("test2", Qt::MatchExactly | Qt::MatchRecursive, 0).first()); tree->scrollToItem(test1); tree->selectionModel()->select( tree->indexAt(findItemPos(test1, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(test1); tree->selectionModel()->select( tree->indexAt(findItemPos(test2, tree)), QItemSelectionModel::Select); ObjectManipulator *om = mw->activeProject()->findChild("om"); openContextMenu(om, test2, tree, "Compile"); instDialog *dlg = NULL; foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); QTreeWidget *table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes(table, 2); QTest::qWait(100); dlg->findChild("nextButton")->click(); QPushButton *finish = dlg->findChild("finishButton"); QVERIFY(finish != NULL); int timeout_counter = 0; while (!finish->isEnabled()) { timeout_counter++; QVERIFY2(timeout_counter < 600, "Compile takes too long (over 1 min) or button \"Finish\" " "is not enabled properly when compile is done"); QTest::qWait(100); } finish->click(); // Now select the same firewalls and open compile/install dialog again tree->scrollToItem(test1); tree->selectionModel()->select( tree->indexAt(findItemPos(test1, tree)), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent); tree->setCurrentItem(test1); tree->selectionModel()->select( tree->indexAt(findItemPos(test2, tree)), QItemSelectionModel::Select); openContextMenu(om, test2, tree, "Compile"); foreach (QWidget *w, app->allWidgets()) if (dynamic_cast(w) != NULL) dlg = dynamic_cast(w); table = dlg->findChild("selectTable"); QVERIFY(table != NULL); QVERIFY(table->isColumnHidden(COMPILE_CHECKBOX_COLUMN) == false); QVERIFY(table->isColumnHidden(INSTALL_CHECKBOX_COLUMN) == true); verifyCompileCheckboxes_2(table); dlg->findChild("cancelButton")->click(); QTest::qWait(100); QVERIFY(QFileInfo("test1.fw").exists() && QFileInfo("test1.fw").size()); QFile::remove("test1.fw"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogObjectListTest/instDialogObjectListTest.h0000644000175000017500000000414611733011756032004 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: instDialogObjectListTest.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTDIALOGTEST_H #define INSTDIALOGTEST_H #include #include #include "newClusterDialog.h" #include "upgradePredicate.h" #include "FWBTree.h" #include "fwbuilder/Library.h" #include "instDialog.h" #include "FWWindow.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" class instDialogObjectListTest : public QObject { Q_OBJECT const char *ssh_auth_sock; void openPolicy(QString fw); void verifyCompileCheckboxes(QTreeWidget *table, int items = -1); void verifyCompileCheckboxes_2(QTreeWidget *table); void verifyInstallCheckboxes(QTreeWidget *table, int items = -1); void openContextMenu(ObjectManipulator *om, ObjectTreeViewItem *item, ObjectTreeView *tree, const QString &actionText); void removeFiles(); private slots: void initTestCase(); void test_compile_1(); void test_compile_2(); void test_compile_3(); void test_compile_4(); void test_compile_5(); void test_compile_6(); void test_compile_7(); void test_install_1(); void test_actually_compile_1(); public slots: void closeContextMenu(); }; #endif // INSTDIALOGTEST_H fwbuilder-5.1.0.3599/src/unit_tests/instDialogObjectListTest/main_instDialogObjectListTest.cpp0000644000175000017500000000331711733011756033342 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: main_instDialogTest.cpp 2707 2010-03-10 18:22:19Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "instDialogObjectListTest.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" using namespace std; using namespace libfwbuilder; int fwbdebug = 0; FWWindow *mw = NULL; FWBSettings *st = NULL; FWBApplication *app = NULL; int sig = FWB_SIG; extern void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st); int main(int argc, char** argv) { app = new FWBApplication(argc, argv); app->setOrganizationName(QLatin1String("NetCitadel")); app->setApplicationName(QLatin1String("Firewall Builder")); build_app(argc, argv, &app, &st); QTest::qExec(new instDialogObjectListTest()); if (QFile::exists("test_work.fwb")) QFile::remove("test_work.fwb"); } fwbuilder-5.1.0.3599/src/unit_tests/instDialogObjectListTest/instDialogObjectListTest.pro0000644000175000017500000000052311733011756032350 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += testlib network gui TARGET = instDialogObjectListTest SOURCES += main_instDialogObjectListTest.cpp \ instDialogObjectListTest.cpp HEADERS += instDialogObjectListTest.h run_tests.commands = cp -f test.fwb test_work.fwb; \ ./${TARGET}; \ rm -f test_work.fwb fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/0000755000175000017500000000000011733011756025633 5ustar sylvestresylvestre././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootfwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/main_generatedScriptTestsIpfilter.cppfwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/main_generatedScriptTestsIpfilter.c0000644000175000017500000000344011733011756034651 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsIpfilter.h" #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include "../../../common/init.cpp" using namespace std; using namespace libfwbuilder; int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); init(argv); Resources res(Constants::getResourcesFilePath()); CppUnit::TextUi::TestRunner runner; runner.addTest( GeneratedScriptTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/generatedScriptTestsIpfilter.cpp0000644000175000017500000002327111733011756034211 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "generatedScriptTestsIpfilter.h" #include "CompilerDriver_ipf.h" #include "Configlet.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/IPService.h" #include "fwbuilder/Constants.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << std::endl; return false; } }; void GeneratedScriptTest::setUp() { Configlet::setDebugging(true); } void GeneratedScriptTest::tearDown() { } void GeneratedScriptTest::loadDataFile(const string &file_name) { /* load the data file */ UpgradePredicate upgrade_predicate; objdb->setReadOnly( false ); objdb->load(file_name, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(file_name); objdb->reIndex(); } void GeneratedScriptTest::runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name, const std::string &output_file_option) { loadDataFile(test_file); QStringList args; if (!output_file_option.empty()) { args << "-o" << output_file_option.c_str(); } args << firewall_object_name.c_str(); CompilerDriver_ipf driver(objdb); driver.setEmbeddedMode(); CPPUNIT_ASSERT_MESSAGE("CompilerDriver_ipf initialization failed", driver.prepare(args) == true); driver.compile(); // compiler should have created file generate_file_name QFileInfo fi(generate_file_name.c_str()); CPPUNIT_ASSERT_MESSAGE("Generated file " + generate_file_name + " not found", fi.exists() == true); } // I can check only certain parts of the top comment. Can't // compare against "golden" file because some parts of the comment // are variable, such as date, version and build number void GeneratedScriptTest::ManifestTest_1() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipf1", "ipf1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf1-ipf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf1-nat.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_2() { /* * output script name is set to ipf2-1.fw in the fw object. This * parameter is used by instDialog and passed to the compiler via * "-o" command line option. Calling compiler without this option * produces file with standard name. */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipf2", "ipf2-1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf2-1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1-ipf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1-nat.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_3() { /* * output script name is set to ipf2a in the fw object. This * parameter is used by instDialog and passed to the compiler via * "-o" command line option. Calling compiler without this option * produces file with standard name. */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipf2a", "ipf2-1"); QString res = Configlet::findConfigletInFile("top_comment", "ipf2-1"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf2-1") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1-ipf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1-nat.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_4() { /* * Compile ipf2 and ipf2a adding "-o" option as instDialog does */ objdb = new FWObjectDatabase(); QString option_o = QDir::currentPath() + "/ipf2-1.fw"; runCompiler("test1.fwb", "ipf2", "ipf2-1.fw", option_o.toStdString()); QString res = Configlet::findConfigletInFile("top_comment", "ipf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * " + option_o) != -1); QString ipf_file = QDir::currentPath() + "/ipf2-1-ipf.conf"; QString nat_file = QDir::currentPath() + "/ipf2-1-nat.conf"; CPPUNIT_ASSERT(res.indexOf("# files: " + ipf_file) != -1); CPPUNIT_ASSERT(res.indexOf("# files: " + nat_file) != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_5() { objdb = new FWObjectDatabase(); QString option_o = QDir::currentPath() + "/ipf2-1"; runCompiler("test1.fwb", "ipf2a", "ipf2-1.fw", option_o.toStdString()); QString res = Configlet::findConfigletInFile("top_comment", "ipf2-1.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf2-1.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1-ipf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf2-1-nat.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_6() { /* * remote ipf and nat files are configured as /etc/fw/ipf3-ipf.conf and * /etc/fw/ipf3-nat.conf in ipf3 */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipf3", "ipf3.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf3.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf3.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf3-ipf.conf /etc/fw/ipf3-ipf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf3-nat.conf /etc/fw/ipf3-nat.conf") != -1); delete objdb; } void GeneratedScriptTest::ManifestTest_7() { /* * remote ipf and nat files in ipf4 have spaces in the path */ objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipf4", "ipf4.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf4.fw"); // find manifest and compare CPPUNIT_ASSERT(res.indexOf("# files: * ipf4.fw /etc/path\\ with\\ space/ipf4.fw") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf4-ipf.conf /etc/path\\ with\\ space/ipf4-ipf.conf") != -1); CPPUNIT_ASSERT(res.indexOf("# files: ipf4-nat.conf /etc/path\\ with\\ space/ipf4-nat.conf") != -1); delete objdb; } // ************************************************************************ void GeneratedScriptTest::FwCommentTest() { objdb = new FWObjectDatabase(); runCompiler("test1.fwb", "ipf1", "ipf1.fw"); QString res = Configlet::findConfigletInFile("top_comment", "ipf1.fw"); // find string from the firewall object comment and compare CPPUNIT_ASSERT(res.indexOf("# Firewall object test1 comment") != -1); delete objdb; } // ************************************************************************ void GeneratedScriptTest::ActivationCommandsTest_1() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf1.fw"); CPPUNIT_ASSERT(res.indexOf("$IPF -I -f /etc/ipf1-ipf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_2() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf2-1.fw"); CPPUNIT_ASSERT(res.indexOf("$IPF -I -f /etc/ipf2-1-ipf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_3() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf2-1"); CPPUNIT_ASSERT(res.indexOf("$IPF -I -f /etc/ipf2-1-ipf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_4() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf2-1.fw"); CPPUNIT_ASSERT(res.indexOf("$IPF -I -f /etc/ipf2-1-ipf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_6() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf3.fw"); CPPUNIT_ASSERT(res.indexOf("$IPF -I -f /etc/fw/ipf3-ipf.conf") != -1); delete objdb; } void GeneratedScriptTest::ActivationCommandsTest_7() { objdb = new FWObjectDatabase(); QString res = Configlet::findConfigletInFile("activation", "ipf4.fw", 1); CPPUNIT_ASSERT(res.indexOf("$IPF -I -f /etc/path\\ with\\ space/ipf4-ipf.conf") != -1); res = Configlet::findConfigletInFile("activation", "ipf4.fw", 2); CPPUNIT_ASSERT(res.indexOf("$IPNAT -f /etc/path\\ with\\ space/ipf4-nat.conf") != -1); delete objdb; } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/.gitignore0000644000175000017500000000000711733011756027620 0ustar sylvestresylvestreipf2-1 fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/test1.fwb0000644000175000017500000030062411733011756027400 0ustar sylvestresylvestre established established -m state --state ESTABLISHED,RELATED established established established -m state --state ESTABLISHED,RELATED established -m record_rpc -m irc -m psd --psd-weight-threshold 5 --psd-delay-threshold 10000 -m string --string test_pattern -m talk fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/generatedScriptTestsIpfilter.pro0000644000175000017500000000054711733011756034230 0ustar sylvestresylvestreinclude(../tests_common.pri) QT += gui network HEADERS = generatedScriptTestsIpfilter.h SOURCES = main_generatedScriptTestsIpfilter.cpp \ generatedScriptTestsIpfilter.cpp TARGET = generatedScriptTestsIpfilter run_tests.commands = echo "Running tests..." && \ rm -f *.fw *.conf && \ ./${TARGET} && \ echo "OK" || { echo "FAILED"; exit 1; } fwbuilder-5.1.0.3599/src/unit_tests/generatedScriptTestsIpfilter/generatedScriptTestsIpfilter.h0000644000175000017500000000555411733011756033662 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GENERATEDSCRIPTTESTS_IPFILTER_H #define GENERATEDSCRIPTTESTS_IPFILTER_H #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Logger.h" #include #include class GeneratedScriptTest : public CppUnit::TestFixture { libfwbuilder::FWObjectDatabase *objdb; void loadDataFile(const std::string &file_name); void runCompiler(const std::string &test_file, const std::string &firewall_object_name, const std::string &generate_file_name, const std::string &output_file_option=""); public: void setUp(); void tearDown(); void ManifestTest_1(); void ManifestTest_2(); void ManifestTest_3(); void ManifestTest_4(); void ManifestTest_5(); void ManifestTest_6(); void ManifestTest_7(); void FwCommentTest(); void ActivationCommandsTest_1(); void ActivationCommandsTest_2(); void ActivationCommandsTest_3(); void ActivationCommandsTest_4(); // void ActivationCommandsTest_5(); void ActivationCommandsTest_6(); void ActivationCommandsTest_7(); CPPUNIT_TEST_SUITE(GeneratedScriptTest); // The order of tests matters because activation commands tests use // files produced in manifest tests CPPUNIT_TEST(ManifestTest_1); CPPUNIT_TEST(ActivationCommandsTest_1); CPPUNIT_TEST(ManifestTest_2); CPPUNIT_TEST(ActivationCommandsTest_2); CPPUNIT_TEST(ManifestTest_3); CPPUNIT_TEST(ActivationCommandsTest_3); CPPUNIT_TEST(ManifestTest_4); CPPUNIT_TEST(ActivationCommandsTest_4); // CPPUNIT_TEST(ManifestTest_5); // CPPUNIT_TEST(ActivationCommandsTest_5); CPPUNIT_TEST(ManifestTest_6); CPPUNIT_TEST(ActivationCommandsTest_6); CPPUNIT_TEST(ManifestTest_7); CPPUNIT_TEST(ActivationCommandsTest_7); CPPUNIT_TEST(FwCommentTest); CPPUNIT_TEST_SUITE_END(); }; #endif // GENERATEDSCRIPTTESTS_IPFILTER_H fwbuilder-5.1.0.3599/src/unit_tests/main/0000755000175000017500000000000011733011756020712 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/main/main.pro0000644000175000017500000000134711733011756022365 0ustar sylvestresylvestre# -*- mode: makefile; tab-width: 4; -*- include(../../../qmake.inc) OBJECTS_DIR = .obj MOC_DIR = .moc QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS CONFIG -= release CONFIG += debug INCLUDEPATH += ../../.. \ ../.. \ ../../libfwbuilder/src \ ../../libgui \ ../../libgui/.ui \ ../../compiler_lib \ ../../common DEPENDPATH += ../../.. \ ../.. \ ../../libfwbuilder/src \ ../../libgui \ ../../libgui/.ui \ ../../compiler_lib \ ../../common QT += testlib network gui TEMPLATE = lib CONFIG += staticlib TARGET = test_main INSTALLS -= target SOURCES += main.cpp run_tests.commands = echo "" run_tests.depends = build_tests build_tests.depends = all clean_tests.depends = clean QMAKE_EXTRA_TARGETS += run_tests build_tests clean_tests fwbuilder-5.1.0.3599/src/unit_tests/main/main.cpp0000644000175000017500000000411211733011756022340 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FWWindow.h" #include "FWBSettings.h" #include "FWBApplication.h" #include "FWObjectClipboard.h" #include "common/commoninit.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; extern void init_platforms(); // defined in platforms.cpp void build_app(int argc, char** argv, FWBApplication** app, FWBSettings** st) { Q_INIT_RESOURCE(MainRes); init(argv); init_platforms(); *st = new FWBSettings(true); (*st)->init(false); (*st)->setCheckUpdates(false); (*st)->setBool("UI/NoStartTip", true); (*st)->setIntroDialogEnabled(false); (*st)->suppressReminderAboutStandardLib(true); string full_res_path = Constants::getResourcesFilePath(); new Resources(full_res_path); QString qt_resource_dir = QLibraryInfo::location(QLibraryInfo::TranslationsPath); QTranslator qt_translator(0); qt_translator.load(QLatin1String("qt_") + QLocale::system().name(), qt_resource_dir); (*app)->installTranslator (&qt_translator); } fwbuilder-5.1.0.3599/src/unit_tests/Inet6AddrMaskTest/0000755000175000017500000000000011733011756023222 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/unit_tests/Inet6AddrMaskTest/Inet6AddrMaskTest.h0000644000175000017500000000322111733011756026625 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INET6ADDRMASKTEST_H #define INET6ADDRMASKTEST_H #include class Inet6AddrMaskTest : public CppUnit::TestFixture { public: void testStringToInetAddrExceptions(); void testIntToInetAddr6(); void testStringToInetAddr6(); void testStringToInetAddrMask(); void testInet6AddressOps(); void testUInt128ToInetAddr6(); void testInetAddr6ToUInt128(); CPPUNIT_TEST_SUITE(Inet6AddrMaskTest); CPPUNIT_TEST(testStringToInetAddrExceptions); CPPUNIT_TEST(testIntToInetAddr6); CPPUNIT_TEST(testUInt128ToInetAddr6); CPPUNIT_TEST(testInetAddr6ToUInt128); CPPUNIT_TEST(testStringToInetAddr6); CPPUNIT_TEST(testStringToInetAddrMask); CPPUNIT_TEST(testInet6AddressOps); CPPUNIT_TEST_SUITE_END(); }; #endif // INET6ADDRMASKTEST_H fwbuilder-5.1.0.3599/src/unit_tests/Inet6AddrMaskTest/Inet6AddrMaskTest.pro0000644000175000017500000000112211733011756027174 0ustar sylvestresylvestreinclude(../../../qmake.inc) QT -= core gui TARGET = Inet6AddrMaskTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app QMAKE_CXXFLAGS += $$CPPUNIT_CFLAGS LIBS += $$CPPUNIT_LIBS SOURCES += main.cpp Inet6AddrMaskTest.cpp HEADERS += Inet6AddrMaskTest.h INCLUDEPATH += ../../.. ../../libfwbuilder/src DEPENDPATH += ../../libfwbuilder/src LIBS += ../../libfwbuilder/src/fwbuilder/libfwbuilder.a run_tests.commands = echo "Running tests..." && ./${TARGET} run_tests.depends = all clean_tests.depends = clean build_tests.depends = all QMAKE_EXTRA_TARGETS += run_tests clean_tests build_tests fwbuilder-5.1.0.3599/src/unit_tests/Inet6AddrMaskTest/main.cpp0000644000175000017500000000265311733011756024660 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "Inet6AddrMaskTest.h" #include "fwbuilder/FWObjectDatabase.h" #include using namespace libfwbuilder; int fwbdebug = 0; //QString user_name; std::string platform; int main( int, char** argv) { //init(argv); init(); CppUnit::TextUi::TestRunner runner; runner.addTest( Inet6AddrMaskTest::suite() ); runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), std::cerr ) ); runner.run(); return 0; } fwbuilder-5.1.0.3599/src/unit_tests/Inet6AddrMaskTest/Inet6AddrMaskTest.cpp0000644000175000017500000002020511733011756027161 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Inet6AddrMaskTest.h" #include #include using namespace libfwbuilder; using namespace std; void Inet6AddrMaskTest::testUInt128ToInetAddr6() { InetAddr x1(AF_INET6, "::1"); uint128 x = x1.to_uint128(); InetAddr x2(AF_INET6, 0); x2.init_from_uint128(x); CPPUNIT_ASSERT(x2.toString() == "::1"); InetAddr x3(AF_INET6, "::8000"); x = x3.to_uint128(); InetAddr x4(AF_INET6, 0); x4.init_from_uint128(x); CPPUNIT_ASSERT(x4.toString() == "::8000"); InetAddr x5(AF_INET6, "::ff00"); x = x5.to_uint128(); InetAddr x6(AF_INET6, 0); x6.init_from_uint128(x); CPPUNIT_ASSERT(x6.toString() == "::ff00"); InetAddr x90(AF_INET6, "fe80::20c:29ff:fed2:cca1"); x = x90.to_uint128(); InetAddr x91(AF_INET6, 0); x91.init_from_uint128(x); CPPUNIT_ASSERT(x91.toString() == "fe80::20c:29ff:fed2:cca1"); } void Inet6AddrMaskTest::testInetAddr6ToUInt128() { InetAddr x1(AF_INET6, 0); uint128 x = x1.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "0"); InetAddr x2(AF_INET6, 1); x = x2.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "800000000000000000000000"); InetAddr x3(AF_INET6, 8); x = x3.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "FF0000000000000000000000"); InetAddr x4(AF_INET6, 16); x = x4.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "FFFF00000000000000000000"); InetAddr x5(AF_INET6, 64); x = x5.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "FFFFFFFFFFFFFFFF00000000"); InetAddr x6(AF_INET6, 128); x = x6.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); InetAddr x7(AF_INET6, "fe80::20c:29ff:fed2:cca1"); x = x7.to_uint128(); CPPUNIT_ASSERT(x.to_string() == "FE8000000000000020C29FFFED2CCA1"); } void Inet6AddrMaskTest::testIntToInetAddr6() { InetAddr x1(AF_INET6, 0); CPPUNIT_ASSERT(x1.toString()=="::" && x1.getLength()==128); InetAddr x2(AF_INET6, 1); CPPUNIT_ASSERT(x2.toString()=="8000::" && x2.getLength()==1); InetAddr x3(AF_INET6, 8); CPPUNIT_ASSERT(x3.toString()=="ff00::" && x3.getLength()==8); InetAddr x4(AF_INET6, 16); CPPUNIT_ASSERT(x4.toString()=="ffff::" && x4.getLength()==16); InetAddr x5(AF_INET6, 64); CPPUNIT_ASSERT(x5.toString()=="ffff:ffff:ffff:ffff::" && x5.getLength()==64); InetAddr x6(AF_INET6, 128); CPPUNIT_ASSERT(x6.toString()=="ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" && x6.getLength()==128); } void Inet6AddrMaskTest::testStringToInetAddr6() { InetAddr *sa1 = new InetAddr(AF_INET6, "::"); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "::"); sa1 = new InetAddr(AF_INET6, "::1"); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "::1"); sa1 = new InetAddr(AF_INET6, "fe80::20c:29ff:fed2:cca1"); CPPUNIT_ASSERT_MESSAGE(sa1->toString(), sa1->toString() == "fe80::20c:29ff:fed2:cca1"); InetAddr x6(AF_INET6, "64"); CPPUNIT_ASSERT_MESSAGE(x6.toString(), x6.toString()=="ffff:ffff:ffff:ffff::"); CPPUNIT_ASSERT(x6.getLength()==64); } void Inet6AddrMaskTest::testStringToInetAddrExceptions() { CPPUNIT_ASSERT_THROW(new InetAddr(AF_INET, "fe80::20c:29ff:fed2:cca1"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr("fe80::20c:29ff:fed2:cca1"), FWException); CPPUNIT_ASSERT_NO_THROW(new InetAddr(AF_INET6, "fe80::20c:29ff:fed2:cca1/64")); CPPUNIT_ASSERT_THROW(new InetAddr(AF_INET6, "fe80::20c:29ff:fed2:cca1/200"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr(AF_INET6, "fe80::foo:bar:fed2:cca1"), FWException); CPPUNIT_ASSERT_THROW(new InetAddr(AF_INET6, "1.2.3.4"), FWException); CPPUNIT_ASSERT_NO_THROW(new InetAddr(AF_INET6, 64)); CPPUNIT_ASSERT_THROW(new InetAddr(AF_INET6, 256), FWException); } /* * Note that our current implementation of address operations for ipv6 is very * limited */ void Inet6AddrMaskTest::testInet6AddressOps() { InetAddr x7(AF_INET6, "fe80::21d:9ff:fe8b:8e94"); InetAddr y6(AF_INET6, 64); InetAddr z1 = x7 & y6; CPPUNIT_ASSERT(z1.toString()=="fe80::"); CPPUNIT_ASSERT((~y6).toString()=="::ffff:ffff:ffff:ffff"); InetAddr z2 = z1 | ~y6; CPPUNIT_ASSERT_MESSAGE(z2.toString(), z2.toString()=="fe80::ffff:ffff:ffff:ffff"); InetAddr z3 = x7 + 1; CPPUNIT_ASSERT_MESSAGE(z3.toString(), z3.toString() == "fe80::21d:9ff:fe8b:8e95"); InetAddr z4 = z3 - 1; CPPUNIT_ASSERT_MESSAGE(z4.toString(), z4.toString() == "fe80::21d:9ff:fe8b:8e94"); InetAddr z5 = x7 + 65536; CPPUNIT_ASSERT_MESSAGE(z5.toString(), z5.toString() == "fe80::21d:9ff:fe8c:8e94"); InetAddr z6 = z5 - 65536; CPPUNIT_ASSERT_MESSAGE(z6.toString(), z6.toString() == "fe80::21d:9ff:fe8b:8e94"); InetAddr z7 = x7 + 2147483647; // 2^31-1 CPPUNIT_ASSERT_MESSAGE(z7.toString(), z7.toString() == "fe80::21d:a00:7e8b:8e93"); InetAddr z8 = z7 - 2147483647; CPPUNIT_ASSERT_MESSAGE(z8.toString(), z8.toString() == "fe80::21d:9ff:fe8b:8e94"); InetAddr x8(AF_INET6, "fe80::21d:9ff:fe8b:1111"); CPPUNIT_ASSERT(x7 > x8); CPPUNIT_ASSERT(x8 < x7); unsigned int dist = x8.distance(x7); CPPUNIT_ASSERT(dist == 32132); InetAddr x9(AF_INET6, "fe80::21d:9ff:fe8b:8e94"); CPPUNIT_ASSERT(x7 == x9); InetAddr x10(AF_INET6, "fe80::21d:a00:7e8b:8e93"); CPPUNIT_ASSERT(x10 > x9); CPPUNIT_ASSERT(x9 < x10); } void Inet6AddrMaskTest::testStringToInetAddrMask() { string sa; Inet6AddrMask *a1 = new Inet6AddrMask(); sa = a1->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="::"); Inet6AddrMask *a2 = new Inet6AddrMask( InetAddr(AF_INET6, "fe80::21d:9ff:fe8b:8e94"), InetAddr(AF_INET6, 128)); sa = a2->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="fe80::21d:9ff:fe8b:8e94"); sa = a2->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); CPPUNIT_ASSERT(a2->getNetmaskPtr()->getLength()==128); CPPUNIT_ASSERT(a2->toString()=="fe80::21d:9ff:fe8b:8e94"); Inet6AddrMask *a3 = new Inet6AddrMask( InetAddr(AF_INET6, "fe80::21d:9ff:fe8b:8e94"), InetAddr(AF_INET6, 128)); a3->setNetmask(InetAddr(AF_INET6, 64)); sa = a3->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="fe80::21d:9ff:fe8b:8e94"); sa = a3->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="ffff:ffff:ffff:ffff::"); CPPUNIT_ASSERT(a3->getNetmaskPtr()->getLength()==64); CPPUNIT_ASSERT(a3->toString()=="fe80::21d:9ff:fe8b:8e94/64"); Inet6AddrMask *a4 = new Inet6AddrMask( string("fe80::21d:9ff:fe8b:8e94/64")); sa = a4->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="fe80::21d:9ff:fe8b:8e94"); sa = a4->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="ffff:ffff:ffff:ffff::"); CPPUNIT_ASSERT(a4->belongs( *(a2->getAddressPtr()) )); Inet6AddrMask *a5 = new Inet6AddrMask(*a3); sa = a5->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="fe80::21d:9ff:fe8b:8e94"); sa = a5->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="ffff:ffff:ffff:ffff::"); a5->setAddress(InetAddr(AF_INET6, "3ffe:1200:2001:1:8000::1")); sa = a5->getAddressPtr()->toString(); CPPUNIT_ASSERT(sa=="3ffe:1200:2001:1:8000::1"); sa = a5->getNetmaskPtr()->toString(); CPPUNIT_ASSERT(sa=="ffff:ffff:ffff:ffff::"); } fwbuilder-5.1.0.3599/src/tools/0000755000175000017500000000000011733011756016725 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/tools/tools.pro0000644000175000017500000000102311733011756020603 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) win32 { QMAKE_RUN_CC = @echo QMAKE_RUN_CXX = @echo QMAKE_LINK = @echo } unix { QMAKE_RUN_CC = @true QMAKE_RUN_CXX = @true QMAKE_LINK = @true } macx { QMAKE_RUN_CC = @true QMAKE_RUN_CXX = @true QMAKE_LINK = @true } TARGET = tools win32:tools.path = $$target.path unix:tools.path = $$target.path macx:tools.path = $$target.path tools.files = fwb_install fwb_compile_all INSTALLS -= target INSTALLS += tools fwbuilder-5.1.0.3599/src/tools/fwb_compile_all0000755000175000017500000000357311733011756022001 0ustar sylvestresylvestre#!/bin/sh # # # Firewall Builder # # Copyright (C) 2003 NetCitadel, LLC # # Author: Vadim Kurland vadim@vk.crocodile.org # # $Id$ # # This program is free software which we release under the GNU General Public # License. You may redistribute and/or modify this program under the terms # of that license as published by the Free Software Foundation; either # version 2 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 General Public License for more details. # # To get a copy of the GNU General Public License, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # XMLFILE="objects.xml" # default fallback if -f option is missing DIR="." V="" LIB="User" # default library while getopts f:d:l:va opt do case "$opt" in a) all="yes" ;; v) V="-v " ;; f) XMLFILE=$OPTARG ;; d) DIR=$OPTARG ;; l) LIB=$OPTARG ;; \?) ;; esac done shift `expr $OPTIND - 1` test -n "$all" && LIST=`fwblookup -f $XMLFILE -lN /${LIB}/Firewalls | grep -v Firewalls` || { while test -n "$1"; do LIST="$LIST $1" shift done } for f in `echo $LIST`; do platform=`fwblookup -f $XMLFILE -a platform /${LIB}/Firewalls/$f` case "$platform" in iptables) comp="fwb_ipt" ;; ipf) comp="fwb_ipf" ;; ipfw) comp="fwb_ipfw";; pf) comp="fwb_pf" ;; pix) comp="fwb_pix" ;; \?) echo "Unknown platform \"$platform\""; exit 1 ;; esac echo echo "################ $f" $comp $V -f $XMLFILE -d $DIR $f; done fwbuilder-5.1.0.3599/src/tools/resolve_duplicate_std_objects.py0000755000175000017500000001126711733011756025405 0ustar sylvestresylvestre#!/usr/bin/python # # The purpose of this script is to find obejcts that normally belong # to the Standard Objects library but were copied to the user-defined # library thus creating duplicate IDs. Script finds such objects in # the specified data file and prints sed commands that change the IDs # to make them unique. The script does not modify the data file in any # way. # # If a copy of a duplicate object in the user-defined library is # identical to the object in the Standard library, it is removed. If # the copy has been modified, the id is changed to be unique and all # references to it are corrected. Obejcts are compared as text lines # regardless of the contents. # # This script does not use fwbuilder DTD and operates on xml files as # plain text, it can be used with files of old or different versions # regardless of fwbuilder DTD. import getopt import time import re import sys NEW_ID_PREFIX = '%s' % int(time.time()) generated_commands = [] def usage(): print '%s data_file.fwb objects_init.xml' % sys.argv[0] def command_to_delete(id): generated_commands.append("""sed '/id="%s"/d'""" % id) def command_to_change(id): new_id = '%s_%s' % (id, NEW_ID_PREFIX) generated_commands.append("""sed 's/id="%s"/id="%s"/'""" % (id, new_id)) generated_commands.append("""sed 's/ref="%s"/ref="%s"/g'""" % (id, new_id)) def main(): try: data_file = sys.argv[1] std_file = sys.argv[2] except IndexError,e: usage() sys.exit(1) std_objects = {} objects_of_interest = ['TCPService', 'UDPService', 'ICMPService', 'IPService', 'Network', 'Host', 'IPv4', 'IPv6', 'ObjectGroup', 'ServiceGroup', 'IntervalGroup', 'Library'] objects_we_never_delete = ['ObjectGroup', 'ServiceGroup', 'IntervalGroup', 'Library'] object_type_re = re.compile('<([^ ]+) ') object_id_re = re.compile('id="([^\"]+)"') object_ref_re = re.compile('ref="([^\"]+)"') object_comment_re = re.compile('comment="([^\"]*)"') # first, read standard objects and catalog all lines that have "id=" in them for line in open(std_file): line = line.strip() m = object_id_re.search(line) if m: id = m.group(1) std_objects[id] = line # now scan the data file, find all object definitions and compare for line in open(data_file): line = line.strip() m = object_type_re.match(line) if m: obj_type = m.group(1) if obj_type in objects_of_interest: m = object_id_re.search(line) if m: id = m.group(1) if id in std_objects: print 32 * '-' print 'Find duplicate object:' print 'Object in the data file:' print line print 'Object in the standard objects file:' print std_objects[id] # One of the typical cases is when only comment has changed file_line_no_comment = None std_line_no_comment = None m1 = object_comment_re.match(line) m2 = object_comment_re.match(std_objects[id]) if m1: file_comment = m1.group(1) file_line_no_comment = line.replace('comment="%s"' % file_comment, '') if m2: std_comment = m2.group(1) std_line_no_comment = line.replace('comment="%s"' % std_comment, '') if line == std_objects[id]: if obj_type not in objects_we_never_delete: print 'Objects are IDENTICAL' command_to_delete(id) else: print 'Objects are IDENTICAL but we cant delete' command_to_change(id) elif (file_line_no_comment and std_line_no_comment and file_line_no_comment == std_line_no_comment): print 'Only comments are DIFFERENT' print file_line_no_comment print std_line_no_comment command_to_change(id) else: print 'Objects are DIFFERENT' command_to_change(id) print 'cat %s | %s' % (data_file, ' | '.join(generated_commands)) if __name__ == '__main__': main() fwbuilder-5.1.0.3599/src/tools/rehash-ids.pl0000755000175000017500000000162611733011756021321 0ustar sylvestresylvestre#!/usr/bin/perl # # use strict; my $file = $ARGV[0]; die "rehash-ids.pl data_file.fwb\n" if ($file eq ""); my %ids; my $idCntr = time; open F, "$file" or die "Could not open file $file for reading"; while () { if ($_ =~ /id=\"([^\"]+)\"/) { $ids{$1}=$1; } } close F; while ( my ($k,$v) = each %ids ) { if (length($k)>20) { $ids{$k} = sprintf("id%d", $idCntr); $idCntr++; printf "ID=%s -> %s\n",$k, $ids{$k}; } } my $newfile = "$file" . ".new"; open F, "$file" or die "Could not open file $file for reading"; open W, ">$newfile" or die "Coule not open file $newfile for writing"; while () { if ($_ =~ /id=\"([^\"]+)\"/) { my $oldid=$1; my $newid=$ids{$oldid}; $_ =~ s/id=\"[^\"]+\"/id=\"$newid\"/; } if ($_ =~ /ref=\"([^\"]+)\"/) { my $oldid=$1; my $newid=$ids{$oldid}; $_ =~ s/ref=\"[^\"]+\"/ref=\"$newid\"/; } print W $_; } close F; close W; fwbuilder-5.1.0.3599/src/compiler_lib/0000755000175000017500000000000011733011756020225 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/compiler_lib/pixInterfaces.h0000644000175000017500000000216511733011756023206 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PIX_INTERFACE_PROPERTIES_HH #define PIX_INTERFACE_PROPERTIES_HH #include "interfaceProperties.h" class pixInterfaces : public interfaceProperties { public: pixInterfaces() : interfaceProperties() {} virtual bool parseVlan(const QString&, QString*, int*); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/AutomaticRules.h0000644000175000017500000000341711733011756023344 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __AUTOMATICRULES_HH__ #define __AUTOMATICRULES_HH__ #include "fwbuilder/Rule.h" #include #include namespace libfwbuilder { class Address; class Firewall; class Interface; class Library; class Service; }; namespace fwcompiler { class AutomaticRules { protected: libfwbuilder::Firewall *fw; libfwbuilder::RuleSet *ruleset; libfwbuilder::Library *persistent_objects; public: AutomaticRules(libfwbuilder::Firewall *fw, libfwbuilder::Library *persistent_objects); virtual libfwbuilder::PolicyRule* addMgmtRule( libfwbuilder::Address* src, libfwbuilder::Address* dst, libfwbuilder::Service* service, libfwbuilder::Interface* iface, const libfwbuilder::PolicyRule::Direction direction, const libfwbuilder::PolicyRule::Action action, const std::string &label, bool related = false); }; }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/freebsdInterfaces.h0000644000175000017500000000240211733011756024012 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FREEBSD_INTERFACE_PROPERTIES_HH #define FREEBSD_INTERFACE_PROPERTIES_HH #include "openbsdInterfaces.h" class freebsdInterfaces : public openbsdInterfaces { public: freebsdInterfaces() : openbsdInterfaces() {} virtual bool manageIpAddresses(libfwbuilder::Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/CompilerDriver_files.cpp0000644000175000017500000002374111733011756025050 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "CompilerDriver.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; /** * Determine output file name. If compiling standalone firewall, the * name can be enforced via -o command line switch in which case it * is stored in file_name_setting_from_command_line. If not, * determine automatically using firewall name. * * The name is determined as follows: * * - if file_name_setting_from_command_line is not empty, it is used * - if file_name_setting_from_command_line is empty, check firewall option * "output_file" and use it if it is not empty * - if it is empty, generate the name using firewall object name and suffix .fw * * If compiling a cluster, the name could have been enforced via -O * command line switch, in which case it will be found in * member_file_names. If not, determine automatically using the same * algorithm as for the standalone firewall (see above). * * This function also determines the name of the .conf file we should * generate. Used only by compielers that generate multiple * files. There is no cli switch to set this name, so the name is * taken from firewall option "conf1_file" or derived from * fw_file_name * * This function stores script file name in variable fw_file_name and * conf file name in conf1_file_name */ void CompilerDriver::determineOutputFileNames(Cluster *cluster, Firewall *fw, bool cluster_member, const QStringList &suffixes, const QStringList &extensions, const QStringList &remote_name_fw_options) { file_names.clear(); remote_file_names.clear(); assert(suffixes.size()==extensions.size()); assert(suffixes.size()==remote_name_fw_options.size()); foreach(QString ext, extensions) { file_names << ""; remote_file_names << ""; } QString firewall_name = QString::fromUtf8(fw->getName().c_str()); if (cluster_member) { // member of a cluster QString fw_id = objdb->getStringId(fw->getId()).c_str(); if (member_file_names.contains(fw_id)) { file_names[FW_FILE] = getOutputFileNameInternal( fw, member_file_names[fw_id], "output_file", firewall_name, extensions[FW_FILE]); } else { file_names[FW_FILE] = getOutputFileNameInternal( fw, "", "output_file", firewall_name, extensions[FW_FILE]); } } else { // standalone firewall file_names[FW_FILE] = getOutputFileNameInternal( fw, file_name_setting_from_command_line, "output_file", firewall_name, extensions[FW_FILE]); } FWOptions* options = fw->getOptionsObject(); if (suffixes.size() > 1) { // if we need to deal with conf files at all ... // skip item 0 since it is the .fw file for (int i=1; igetStr( opt_name.arg(i).toStdString()).c_str()); if (!name_from_option.isEmpty()) { // user provided a name for the conf1 file in the // firewall settings dialog. file_names[i] = name_from_option; } else { // special-case file names for the 2-d and subsequent conf // files: if we have the name for the first conf file from // fw option, use it as a prototype, otherwise use fw file // name as a prototype. This is useful when user specifies // the name for pf.conf file, this name will be used as a // prototype for anchor .conf file names instead of the fw // file name if (i >= CONF2_FILE) file_names[i] = getConfFileNameFromFwFileName( file_names[CONF1_FILE], extensions[i]); else file_names[i] = getConfFileNameFromFwFileName( file_names[FW_FILE], extensions[i]); } } // file_names at this point is like this: // file_names= ("ipf4.fw", "ipf4.conf", "ipf4.conf") // // qDebug() << "file_names=" << file_names; // suffixes are inserted right before the file extension, such as in // firewall-suffix.conf for (int i=1; igetName().c_str())) .arg(file_names[i]); } } // Determine remote file names using fw options, if any. If option // has not been specificed in the list remote_name_fw_options // (list item is empty string), or the option value is empty, then // guess using firewall_dir option and local file name QString fw_dir = options->getStr("firewall_dir").c_str(); if (fw_dir.isEmpty()) fw_dir = Resources::getTargetOptionStr( fw->getStr("host_OS"), "activation/fwdir").c_str(); for (int i=0; igetStr(remote_name_fw_options[i].toStdString()).c_str(); if (remote_file_name_from_fw_option.isEmpty()) { remote_file_names[i] = fw_dir + "/" + QFileInfo(fn).fileName(); } else remote_file_names[i] = remote_file_name_from_fw_option; } } //qDebug() << remote_file_names; } QString CompilerDriver::getOutputFileNameInternal(Firewall *current_fw, const QString &from_cli, const QString &option_name, const QString &fw_name, const QString &ext) { if (!from_cli.isEmpty()) return from_cli; FWOptions* options = current_fw->getOptionsObject(); QString name_from_option = QString::fromUtf8(options->getStr(option_name.toStdString()).c_str()).trimmed(); if (!name_from_option.isEmpty()) return name_from_option; else return fw_name + "." + ext; } QString CompilerDriver::getConfFileNameFromFwFileName(const QString &file_name, const QString &ext) { QString res; QFileInfo fi(file_name); QString path = fi.path(); if (path == ".") res = fi.completeBaseName() + "." + ext; else res = path + "/" + fi.completeBaseName() + "." + ext; return res; } /* * Replace ' ' with '\ ' in the string. * * DO NOT CHANGE WITHOUT EXTENSIVE TESTING OF THE POLICY INSTALLER ! * * This is used in different places to deal with generated files with * spaces in the name. This can happen if firewall object name has * spaces. This method of escaping the space is used when we generate * manifest line in the .fw file to find other generated files. The * same method is also used to generate command line arguments for scp * where spaces cause all sorts of problems, for example scp can't * find the file to copy or issues "ambiguous target" error when * remote file name has a space. Finally, the same method is used to * escape space in the file name before using it for the configlet * variable because this name is used in the shell script that we run * on the firewall. */ QString CompilerDriver::escapeFileName(QString fileName) { return fileName.replace(' ', "\\ "); } QString CompilerDriver::unescapeFileName(QString fileName) { return fileName.replace("\\ ", " "); } fwbuilder-5.1.0.3599/src/compiler_lib/CompilerDriver.cpp0000644000175000017500000013156311733011756023670 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #include // for chdir #ifndef _WIN32 # include #else # include # include # include #endif #include "CompilerDriver.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Rule.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwcompiler/Compiler.h" #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerDriver::CompilerDriver(FWObjectDatabase *db) : BaseCompiler() { fwbdebug = 0; filename = ""; wdir = ""; fwobjectname = ""; single_rule_compile_on = false; prepend_cluster_name_to_output_file = false; dl = 0; rule_debug_on = false; drp = -1; drn = -1; drr = -1; verbose = 0; have_dynamic_interfaces = false; ipv4_run = true; ipv6_run = true; fw_by_id = false; objdb = new FWObjectDatabase(*db); objdb->setIgnoreReadOnlyFlag(true); //objdb = db; persistent_objects = new Library(); persistent_objects->setName("Persistent Objects"); objdb->add(persistent_objects); workspace = new Library(); workspace->setName("Workspace"); objdb->add(workspace); prolog_done = false; epilog_done = false; have_filter = false; have_nat = false; start_current_dir = QDir::current(); } CompilerDriver::~CompilerDriver() { if (persistent_objects->getParent() == NULL) delete persistent_objects; else { if (persistent_objects->getParent() == objdb) { objdb->remove(persistent_objects, false); delete persistent_objects; } } if (workspace->getParent() == NULL) delete workspace; else { if (workspace->getParent() == objdb) { objdb->remove(workspace, false); delete workspace; } } delete objdb; } // create a copy of itself, including objdb CompilerDriver* CompilerDriver::clone() { CompilerDriver* new_cd = new CompilerDriver(objdb); if (inEmbeddedMode()) new_cd->setEmbeddedMode(); return new_cd; } bool CompilerDriver::configure(const QStringList &args) { QString last_arg; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-i") { fw_by_id = true; continue; } if (arg == "-v") { verbose++; continue; } if (arg == "-4") { ipv4_run = true; ipv6_run = false; continue; } if (arg == "-6") { ipv4_run = false; ipv6_run = true; continue; } if (arg == "-d") { // TODO: deal with UTF-8 in directory name idx++; wdir = string(args.at(idx).toLatin1().constData()); continue; } if (arg == "-D") { idx++; FWObject::setDataDir(args.at(idx).toUtf8().constData()); continue; } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } if (arg == "-o") { idx++; file_name_setting_from_command_line = args.at(idx); continue; } if (arg == "-O") { // parameter is ',' separated list of , // // All separated by commands, the id and file name just // follow one after another. idx++; QString member_files = args.at(idx); QStringList mf_list = member_files.split(","); QStringListIterator it(mf_list); while (it.hasNext()) { QString fw_id = it.next(); if (it.hasNext()) { QString file_name = it.next(); member_file_names[fw_id] = file_name; } else { QString err("Misconfigured -O option, missing file " "name component for ID %1"); abort(err.arg(fw_id).toStdString()); } } continue; } if (arg == "-xc") { prepend_cluster_name_to_output_file = true; continue; } if (arg == "-xt") { setTestMode(); info("*** Running in test mode, fatal errors are treated as warnings"); continue; } if (arg == "-xp") { idx++; bool ok = false; drp = args.at(idx).toInt(&ok); if (!ok) return false; rule_debug_on = true; continue; } if (arg == "-xn") { idx++; bool ok = false; drn = args.at(idx).toInt(&ok); if (!ok) return false; rule_debug_on = true; continue; } if (arg == "-xr") { idx++; bool ok = false; drr = args.at(idx).toInt(&ok); if (!ok) return false; rule_debug_on = true; continue; } if (arg == "-s") { idx++; single_rule_id = args.at(idx).toStdString(); single_rule_compile_on = true; continue; } } fwobjectname = last_arg; if (wdir.empty()) wdir="./"; return true; } void CompilerDriver::chDir() { if ( #ifdef _WIN32 _chdir(wdir.c_str()) #else chdir(wdir.c_str()) #endif ) { cerr << "Can't change to: " << wdir << endl; exit(1); } } /* * See #1994. We need to reset read-only flag on the firewall and up * the tree all the way to the root in order to let compilers make any * modifications they need. Note that this resets read-only flags in * the copy of the database this class works with. */ void CompilerDriver::clearReadOnly(Firewall *fw) { if (fw->isReadOnly()) { FWObject *p = fw; while (p) { p->setReadOnly(false); p = p->getParent(); } } } QString CompilerDriver::getAbsOutputFileName(const QString &output_file_name) { QFileInfo finfo(output_file_name); if (finfo.isRelative()) { // if fw_file_name is relative, it is relative to the // directory the program started in, or if wdir was defined // via "-d" command line switch, then it is relative to that. if (wdir.empty()) { QFileInfo new_finfo(start_current_dir, output_file_name); return new_finfo.absoluteFilePath(); } else { QFileInfo new_finfo(QDir(wdir.c_str()), output_file_name); return new_finfo.absoluteFilePath(); } } return output_file_name; } void CompilerDriver::commonChecks(Firewall *fw) { if (Cluster::isA(fw)) { Cluster *cluster = Cluster::cast(fw); // Check #1 : make sure output file names are different in member // firewalls set output_file_names; list members; cluster->getMembersList(members); for (list::iterator it=members.begin(); it!=members.end(); ++it) { FWOptions *fwopt = (*it)->getOptionsObject(); string ofname = fwopt->getStr("output_file"); if (ofname.empty()) continue; if (output_file_names.count(ofname) > 0) { QString err("Member firewalls use the same output file name %1"); error(cluster, NULL, NULL, err.arg(ofname.c_str()).toStdString()); } output_file_names.insert(ofname); } } } /* * This method performs series of checks for the configuration * consitency of clusters and cluster members as well as common * problems with interfaces, addresses and their combinations. There * are several possible levels of errors: * * - errors that can be worked around. Compiler makes minor changes * to objects and continues. These are not warnings though, the user * should fix these problems. Using Compiler::error() to report. * * - serious errors that should stop processing because generated file * will be incorrect or inconsistent. However it is possible to * continue in single rule compile mode because the error may not * affect the rule being compiled. Using Compiler::abort() to * report. Normally this method throws FWException() but in single * rule compile mode or in testing mode it records the error and * continues. * * - fatal errors that make it impossible to continue even in test or * single rule compile modes. To report call Compiler::abort() and * then throw FatalErrorInSingleRuleCompileMode exception. This * exception should be caught in CompilerDriver::run() (virtual * method) where recorded error can be shown to the user in the GUI. * */ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw) { QString current_firewall_name = fw->getName().c_str(); string host_os = fw->getStr("host_OS"); if (cluster) { // firewall is a member of a cluster. // Rely on the caller to make sure this firewall is really a member // of this cluster. Do not perform redundant check here. processStateSyncGroups(cluster, fw); // some initial sanity checks validateClusterGroups(cluster); } list all_policies = fw->getByType(Policy::TYPENAME); list all_nat = fw->getByType(NAT::TYPENAME); bool have_top = false; for (list::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { if (RuleSet::cast(*p)->isTop()) { have_top = true; break; } } if ( ! have_top ) warning(fw, NULL, NULL,"Missing top level NAT ruleset"); have_top = false; for (list::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { if (RuleSet::cast(*p)->isTop()) { have_top = true; break; } } if ( ! have_top ) warning(fw, NULL, NULL,"Missing top level Policy ruleset"); list interfaces = fw->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); string::size_type n; if ( (n=iface->getName().find("*"))!=string::npos) { /* this is a special 'wildcard' interface. Its name must end with '*', * it must be dynamic and should not have a child IPv4 or * physAddress object */ if (n!=iface->getName().length()-1) { QString err("'*' must be the last character in " "the wildcard's interface name: '%1'."); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } /* removed test to implement RFE #837238: "unnummbered wildcard interfaces" if (!iface->isDyn()) { QString errstr; errstr.sprintf(_("Wildcard interface '%s' must be dynamic."), iface->getName().c_str() ); throw FWException(errstr); } */ list l3=iface->getByType(physAddress::TYPENAME); if (l3.size()>0) { QString err("Wildcard interface '%1' should not have " "physcal address object attached to it. " "The physical address object will be ignored."); error(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); for (list::iterator j=l3.begin(); j!=l3.end(); ++j) iface->remove(*j); } } if (iface->isDyn()) { have_dynamic_interfaces=true; iface->setBool("use_var_address",true); list l3=iface->getByType(IPv4::TYPENAME); if (l3.size()>0) { for (list::iterator j=l3.begin(); j!=l3.end(); ++j) if ( objdb->findAllReferences(*j).size()!=0 ) { QString err("Dynamic interface %1 has IP address " "that is used in the firewall policy rule."); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } QString err("Dynamic interface %1 should not have an " "IP address object attached to it. " "This IP address object will be ignored."); error(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); for (list::iterator j=l3.begin(); j!=l3.end(); ++j) iface->remove(*j); } } if (iface->isRegular()) { // Regular interface (should have an ip address) bool no_addr_ok = false; if (iface->getOptionsObject()->getBool("cluster_interface")) { // cluster interface with failover type heartbeat or // openais may have no ip address. Other failover // types require an address. FWObject *failover_group = iface->getFirstByType(FailoverClusterGroup::TYPENAME); if (failover_group) { string failover_type = failover_group->getStr("type"); no_addr_ok = Resources::os_res[host_os]->getResourceBool( "/FWBuilderResources/Target/protocols/" + failover_type + "/no_ip_ok"); } } list all_addr = iface->getByType(IPv4::TYPENAME); list all_ipv6 = iface->getByType(IPv6::TYPENAME); all_addr.insert(all_addr.begin(), all_ipv6.begin(), all_ipv6.end()); if (iface->isRegular() && !no_addr_ok && all_addr.empty() && all_ipv6.empty()) { QString err("Missing IP address for interface %1"); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } for (list::iterator j = all_addr.begin(); j != all_addr.end(); ++j) { const InetAddr *ip_addr = Address::cast(*j)->getAddressPtr(); const InetAddr *netmask = Address::cast(*j)->getNetmaskPtr(); if (ip_addr && ip_addr->isAny()) { QString err("Interface %1 (id=%2) has IP address %3."); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()) .arg(FWObjectDatabase::getStringId( iface->getId()).c_str()) .arg(ip_addr->toString().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } if (ip_addr && netmask && netmask->isAny()) { QString err("Interface %1 (id=%2) has invalid netmask %3."); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()) .arg(FWObjectDatabase::getStringId( iface->getId()).c_str()) .arg(netmask->toString().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } } FWObject *parent = iface->getParent(); if (Interface::isA(parent)) { Resources* os_res = Resources::os_res[fw->getStr("host_OS")]; string os_family = fw->getStr("host_OS"); if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( os_family)); #if 0 // See #2103. All interface name validation checks should // be done in the GUI. QString err; if (!int_prop->validateInterface(parent, iface, true, err)) { abort(fw, NULL, NULL, err.toStdString()); throw FatalErrorInSingleRuleCompileMode(); } #endif string interface_type = iface->getOptionsObject()->getStr("type"); if (interface_type.empty()) interface_type = "ethernet"; string parent_interface_type = Interface::cast(parent)->getOptionsObject()->getStr("type"); if (parent_interface_type == "bridge" && interface_type == "ethernet" && int_prop->looksLikeVlanInterface(iface->getName().c_str())) { // if vlan interface is used as a bridge port, it // should be a copy of the top-level interface object // with the same name bool have_top_level_copy = false; for (list::iterator i2=interfaces.begin(); i2!=interfaces.end(); ++i2) { Interface *in = Interface::cast(*i2); assert(in); if (in == iface) continue; if (in->getName() == iface->getName()) { have_top_level_copy = true; break; } } if (!have_top_level_copy) { QString err("Interface %1 looks like Vlan interface and is " "used as a bridge port. This configuration " "is only allowed if this object is a copy of another " "top-level interface with the same name" ); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } } } } void CompilerDriver::setTargetId(const string &id) { fw_by_id = true; fwobjectname = id.c_str(); } Firewall* CompilerDriver::locateObject() { Firewall* obj; if (fw_by_id) { // fwobjectname is actually object id obj = Firewall::cast( objdb->findInIndex( objdb->getIntId(fwobjectname.toAscii().constData()))); //fwobjectname = obj->getName().c_str(); } else obj = objdb->findFirewallByName(fwobjectname.toUtf8().constData()); return obj; } /* Find rulesets that belong to other firewall objects but are * referenced by rules of this firewall using action Branch. * * Important: rulesets that belong to other firewalls may be marked as * "top rulesets", which means they should be translated into the * built-in chains INPUT/OUTPUT/FORWARD rather then into named chain * with the name the same as the name of the ruleset. However this * does not make sense if we want to jump to that ruleset from a rule * from a ruleset that belongs to the firewall we are compiling. If we * compile such "foreighn" ruleset as "top ruleset", then we do not * create chain we would jump to. To avoid this will reset "top * ruleset" flag of rulesets of other firewalls referenced by * branching rules of the firewall being compiled. */ void CompilerDriver::findImportedRuleSets(Firewall *fw, list &all_policies) { bool cluster_member = fw->getOptionsObject()->getBool("cluster_member"); int cluster_id = fw->getInt("parent_cluster_id"); list imported_policies; for (list::iterator i=all_policies.begin(); i!=all_policies.end(); ++i) { RuleSet *ruleset = RuleSet::cast(*i); if (ruleset == NULL) continue; // should not happen for (list::iterator r=ruleset->begin(); r!=ruleset->end(); ++r) { Rule *rule = Rule::cast(*r); if (rule == NULL) continue; // skip RuleSetOptions object RuleSet *branch_ruleset = rule->getBranch(); if (branch_ruleset!=NULL) { // qDebug() << "ruleset=" << ruleset->getName().c_str() // << "branch=" << branch_ruleset->getName().c_str(); map referenced_branch_rulesets; _findImportedRuleSetsRecursively( fw, branch_ruleset, referenced_branch_rulesets); map::iterator it; for (it=referenced_branch_rulesets.begin(); it!=referenced_branch_rulesets.end(); ++it) { RuleSet *branch_ruleset = RuleSet::cast(it->first); int counter = it->second; // qDebug() << " " // << "branch=" << branch_ruleset->getName().c_str() // << "counter=" << counter; if (counter > 1) { QString err( "Rule branches to rule set %1 which branches " "back to it, creating a loop"); warning(ruleset->getParent(), ruleset, rule, err.arg(branch_ruleset->getName().c_str()) .toStdString()); } if (branch_ruleset->isChildOf(fw)) continue; list::iterator it = std::find( imported_policies.begin(), imported_policies.end(), branch_ruleset); if (it != imported_policies.end()) continue; // Additional check: the rule set may be child of a // cluster this firewall is member of. If it is, it // has been taken care of in CompilerDriver::mergeRuleSets() FWObject *ruleset_parent = branch_ruleset->getParent(); if (cluster_member && Cluster::isA(ruleset_parent) && ruleset_parent->getId() == cluster_id) continue; branch_ruleset->setTop(false); imported_policies.push_back(branch_ruleset); } } } } if (imported_policies.size() > 0) all_policies.insert(all_policies.end(), imported_policies.begin(), imported_policies.end()); } void CompilerDriver::_findImportedRuleSetsRecursively( Firewall *fw, RuleSet *branch_ruleset, map &branch_rulesets) { // multiple rules in the rule set may branch to the same branch rule set map local_branch_ruleset_counters; int c = branch_rulesets[branch_ruleset]; branch_rulesets[branch_ruleset] = ++c; if (c > 1) return; // we have seen this one already for (list::iterator r=branch_ruleset->begin(); r!=branch_ruleset->end(); ++r) { Rule *rule = Rule::cast(*r); if (rule == NULL) continue; // skip RuleSetOptions object RuleSet *next_branch_ruleset = rule->getBranch(); if (next_branch_ruleset!=NULL && local_branch_ruleset_counters.count(next_branch_ruleset)==0) { local_branch_ruleset_counters[next_branch_ruleset] = 1; _findImportedRuleSetsRecursively( fw, next_branch_ruleset, branch_rulesets); } } } void CompilerDriver::assignUniqueRuleIds(list &all_rulesets) { for_each(all_rulesets.begin(), all_rulesets.end(), RuleSet::UniqueRuleIdsSetter()); } QString CompilerDriver::run(const std::string&, const std::string&, const std::string&) { return ""; } void CompilerDriver::validateClusterGroups(Cluster *cluster) { string host_os = cluster->getStr("host_OS"); Resources* os_res = Resources::os_res[host_os]; if (os_res==NULL) return; // check if state sync groups are of supported type list state_sync_protocols; os_res->getResourceStrList("/FWBuilderResources/Target/protocols/state_sync", state_sync_protocols); for (FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) { string state_sync_type = (*it)->getStr("type"); if (!isSupported(&state_sync_protocols, state_sync_type)) { QString err("State sync group type '%1' is not supported"); abort(cluster, NULL, NULL, err.arg(state_sync_type.c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } // same for failover groups list failover_protocols; os_res->getResourceStrList("/FWBuilderResources/Target/protocols/failover", failover_protocols); list failover_groups = cluster->getByTypeDeep(FailoverClusterGroup::TYPENAME); for (list::iterator it = failover_groups.begin(); it != failover_groups.end(); ++it) { FWObject *failover_group = *it; FWObject *parent = failover_group->getParent(); string failover_type = failover_group->getStr("type"); if (!isSupported(&failover_protocols, failover_type)) { QString err("Failover group type '%1' is not supported"); abort(cluster, NULL, NULL, err.arg(failover_type.c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } list l2 = failover_group->getByTypeDeep(FWObjectReference::TYPENAME); if (l2.size() == 0) { QString err("Failover group of cluster interface '%1' is empty"); abort(cluster, NULL, NULL, err.arg(parent->getName().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } } bool CompilerDriver::isSupported(list *protocols, const string &cluster_group_type) { bool supported = false; for (list::iterator supported_types=protocols->begin(); supported_types!=protocols->end(); ++supported_types) { QString str = QString(supported_types->c_str()); QStringList pl = str.split(","); if (cluster_group_type.c_str() == pl[0]) { supported = true; break; } } return supported; } QTextStream& operator<< (QTextStream &text_stream, const string &str) { text_stream << str.c_str(); return text_stream; } /* * Add indentation to each line in txt */ string CompilerDriver::indent(int n_spaces, const string &txt) { QString res = indent(n_spaces, QString(txt.c_str())); return res.toStdString(); } QString CompilerDriver::indent(int n_spaces, const QString &txt) { QString fill = QString("%1").arg("", n_spaces, ' '); return prepend(fill, txt); } /* * prepend each line in @txt with @prep, however there is no need to * prepend empty lines */ QString CompilerDriver::prepend(const QString &prep, const QString &txt) { QStringList str; foreach (QString line, txt.split("\n")) { if (line.isEmpty()) str.append(line); else str.append(line.prepend(prep)); } return str.join("\n"); } void CompilerDriver::mergeRuleSets(Cluster *cluster, Firewall *fw, const string &type) { list all_rulesets = cluster->getByType(type); for (list::iterator p = all_rulesets.begin(); p != all_rulesets.end(); ++p) { FWObject *ruleset = *p; FWObject::iterator i = std::find_if( fw->begin(), fw->end(), FWObjectNameEQPredicate(ruleset->getName())); if (i!=fw->end() && (*i)->getTypeName() == type) { FWObject *fw_ruleset = *i; /* * fw has rule set with the same name. See ticket #372 * for details. * * if member firewall has rule set of the same type and * with the same name as cluster and firewall's rule set * is not empty, cluster's rule set is ignored and warning * is ussued * * if matching firewall's rule set is empty, cluster's * rule set is used * * all rule sets from the cluster that do not have * matching ones in the member firewall are merged into * the firewall before compilation and used. * * Note that rule set object has two different kinds of * children: rules and RuleSetOption objects. Check if it * has any rules. */ int rule_cntr = 0; list::iterator it = fw_ruleset->begin(); for ( ; it!=fw_ruleset->end(); ++it) { if (Rule::cast(*it)!=NULL) rule_cntr++; } if (rule_cntr > 0) { QString err("ignoring cluster rule set \"%1\" " "because member firewall \"%2\" " "has rule set with the same name."); warning(fw, fw_ruleset, NULL, err.arg(fw_ruleset->getName().c_str()) .arg(fw->getName().c_str()).toStdString()); } else { fw_ruleset->clear(); fw_ruleset->duplicate(ruleset, false); fw_ruleset->setStr(".ruleset_owner", cluster->getName()); fw_ruleset->setInt(".ruleset_owner_id", cluster->getId()); } } else { // fw does not have rule set with this name FWObject *copy_ruleset = fw->addCopyOf(ruleset, false); copy_ruleset->setStr(".ruleset_owner", cluster->getName()); copy_ruleset->setInt(".ruleset_owner_id", cluster->getId()); } } } /* * 1. Iterate over all fw interfaces and check if they are referenced in a * ClusterGroup. * -> if yes then make copy of vrrp interface and set BASEDEV accordingly * 2. clear Policy, NAT & Routing rules of the firewall, then copy cluster * policy, NAT and routing rules. */ void CompilerDriver::populateClusterElements(Cluster *cluster, Firewall *fw) { if (cluster==NULL) return; #ifdef DEBUG_CLUSTER_INTERFACES cerr << "CompilerDriver::populateClusterElements " << endl; cerr << cluster->getPath(false, true) << endl; list cl_interfaces = cluster->getByTypeDeep(Interface::TYPENAME); cerr << cl_interfaces.size() << " interface" << endl; cluster->dump(false, true); cerr << fw->getPath(false, true) << endl; list fw_interfaces = fw->getByTypeDeep(Interface::TYPENAME); cerr << fw_interfaces.size() << " interface" << endl; fw->dump(false, true); #endif // int addedPolicies = 0; set state_sync_types; checkCluster(cluster); for (FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) { StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast(*it); /* For the state syncing cluster group, hierarchy looks like this: * Cluster->StateSyncClusterGroup->ObjectRef */ string grp_type = state_sync_group->getStr("type"); if (state_sync_types.count(grp_type) > 0) throw FWException("Several state synchronization groups of the same type in one cluster object."); state_sync_types.insert(grp_type); for (FWObjectTypedChildIterator it = state_sync_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { Interface *iface = Interface::cast(FWObjectReference::getObject(*it)); assert(iface); //processStateSyncGroup(cluster, fw, state_sync_group, iface); iface->getOptionsObject()->setBool("state_sync_group_member", true); iface->getOptionsObject()->setStr( "state_sync_group_id", FWObjectDatabase::getStringId(state_sync_group->getId())); string master_id = state_sync_group->getStr("master_iface"); string iface_str_id = FWObjectDatabase::getStringId(iface->getId()); iface->getOptionsObject()->setBool("state_sync_master", master_id == iface_str_id); fw->getOptionsObject()->setBool("cluster_member", true); } } // For VRRP references the hierarchy is as follows: // Cluster->Interface->FailoverClusterGroup->ObjectRef // get a list of pointers to all cluster interfaces. Can't use findByType() // and iterator because we'll be adding interfaces in the middle of the loop list cluster_interfaces = cluster->getByTypeDeep(Interface::TYPENAME); list::iterator cl_iface = cluster_interfaces.begin(); for (; cl_iface != cluster_interfaces.end(); ++cl_iface) { Interface *cluster_interface = Interface::cast(*cl_iface); FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( cluster_interface->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { Interface *member_iface = failover_group->getInterfaceForMemberFirewall(fw); if (member_iface == NULL) continue; assert(fw->getOptionsObject() != NULL); member_iface->getOptionsObject()->setStr( "failover_group_id", FWObjectDatabase::getStringId(failover_group->getId())); // per #971: cluster interface should inherit attributes // of the member interfaces: regular / dynamic / unnimbered cluster_interface->setDyn(member_iface->isDyn()); cluster_interface->setUnnumbered(member_iface->isUnnumbered()); cluster_interface->setUnprotected(member_iface->isUnprotected()); cluster_interface->setSecurityLevel(member_iface->getSecurityLevel()); copyFailoverInterface(cluster, fw, failover_group, member_iface); } else { // cluster interface without failover group // is this a loopback interface ? if (cluster_interface->isLoopback()) { /* Add copy of the interface from the cluster to the * firewall object so that when it is encountered in * the "intrface" rule element of its rules, it * belongs to the firewall and is therefore valid. */ Interface* new_cl_if = Interface::cast(fw->addCopyOf(cluster_interface, true)); assert(new_cl_if != NULL); new_cl_if->getOptionsObject()->setBool("cluster_interface", true); } } } mergeRuleSets(cluster, fw, Policy::TYPENAME); mergeRuleSets(cluster, fw, NAT::TYPENAME); mergeRuleSets(cluster, fw, Routing::TYPENAME); // finally need to remember cluster object ID so that compiler can later // associate it in rules with the firewall. // // The alternative is to find all references to the cluster object // in rules and replace them with refs to the firewall. That could // be done either in prolog or in a special rule processor. It is // _much_ cheaper to just remember cluster ID though. fw->setInt("parent_cluster_id", cluster->getId()); // return addedPolicies; } /* * Perform checks for failover interfaces and their addresses, add a * copy of failover interface form the cluster to the firewall object. * * This method assumes the following: * * - Failover interface owns its ip address which is different from * addresses of either firewall * * - address of the failover interface must be on the same subnet as * addresses of the firewalls (perhaps this restriction can be * lifted? Was originally implemented by Secunet folks like this) */ void CompilerDriver::copyFailoverInterface(Cluster * /*UNUSED cluster */, Firewall *fw, FailoverClusterGroup *cluster_group, Interface *iface) { Interface* cluster_if = Interface::cast(cluster_group->getParent()); assert(cluster_if != NULL); /* Add copy of the cluster interface to the firewall object * * While adding a copy of cluster interface to the firewall, make * sure it has new unique ID instead of a copy of the ID of the * cluster's interface object. If the ID is the same, * RuleElementItf::validateChild() finds clusters' interface which * is not a child of the firewall object and therefore is * rejected. */ Interface* new_cl_if = Interface::cast(fw->addCopyOf(cluster_if, true)); assert(new_cl_if != NULL); new_cl_if->getOptionsObject()->setBool("cluster_interface", true); new_cl_if->getOptionsObject()->setStr("base_device", iface->getName()); new_cl_if->getOptionsObject()->setStr( "base_interface_id", FWObjectDatabase::getStringId(iface->getId())); /* Set master property if interface is referenced * as master_iface */ string master_id = cluster_group->getStr("master_iface"); string iface_str_id = FWObjectDatabase::getStringId(iface->getId()); new_cl_if->getOptionsObject()->setBool("failover_master", master_id == iface_str_id); /* * cluster interface should "inherit" some of the attributes of * the member interfaces it represents. For example, if member * interfaces are marked "unprotected" or "dedicated failover", * should be the cluster interface. What else? */ new_cl_if->setDedicatedFailover(iface->isDedicatedFailover()); new_cl_if->setUnprotected(iface->isUnprotected()); fw->getOptionsObject()->setBool("cluster_member", true); } /** * Do something with state sync cluster groups. Find interfaces that * were placed in the group and store the name in the variable * "state_sync_interface" which is used later to associate policy rule * that should be added to permit state sync protocol with right * interface. For iptables we add rule to permit conntrackd, for PIX * we generate "failover" commands, etc. */ void CompilerDriver::processStateSyncGroups(Cluster *cluster, Firewall *member_fw) { for (FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) { FWObject *state_sync_group = *it; for (FWObjectTypedChildIterator grp_it = state_sync_group->findByType(FWObjectReference::TYPENAME); grp_it != grp_it.end(); ++grp_it) { FWObject *iface = FWObjectReference::getObject(*grp_it); if (iface->isChildOf(member_fw)) { member_fw->getOptionsObject()->setStr( "state_sync_group_id", FWObjectDatabase::getStringId(state_sync_group->getId())); member_fw->getOptionsObject()->setStr( "state_sync_interface", iface->getName()); break; } } } } /* * Verify that there is at least one Cluster interface and that all * have unique names and IP addresses. */ int CompilerDriver::checkCluster(Cluster* cluster) { assert(cluster != NULL); FWObjectTypedChildIterator cluster_ifaces = cluster->findByType(Interface::TYPENAME); if (cluster_ifaces == cluster_ifaces.end()) { /* No configured cluster interface found */ abort(cluster, NULL, NULL, "The cluster has no interfaces."); throw FatalErrorInSingleRuleCompileMode(); } for (; cluster_ifaces != cluster_ifaces.end(); ++cluster_ifaces) { string iface_name = Interface::cast(*cluster_ifaces)->getName(); const InetAddr* iface_address = Interface::cast(*cluster_ifaces)->getAddressPtr(); if (iface_address==NULL) continue; // cluster interface with no address FWObjectTypedChildIterator other_ifaces = cluster_ifaces; for (++other_ifaces; other_ifaces != cluster_ifaces.end(); ++other_ifaces) { if (iface_name == Interface::cast(*other_ifaces)->getName()) { QString err("Found duplicate cluster interface %1"); abort(cluster, NULL, NULL, err.arg(iface_name.c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } const InetAddr *other_iface_address = Interface::cast(*other_ifaces)->getAddressPtr(); if (other_iface_address==NULL) continue; // cluster interface with no address if (*iface_address == *other_iface_address) { QString err("Found duplicate cluster interface address %1"); abort(cluster, NULL, NULL, err.arg(iface_address->toString().c_str()).toStdString()); throw FatalErrorInSingleRuleCompileMode(); } } } return 0; } QString CompilerDriver::formSingleRuleCompileOutput(const QString &generated_code) { // in single rule compile mode just return the // result. Note that we do not return all_errors because // all compilers include errors and warnings with // generated code for each rule. Two exceptions: 1) // CompilerDriver errors need to be added on top, 2) if no // output has been produced by the compiler, we have to // show all_errors to the user because there could be an // error message explaining this. Combined output of all // compilers we assemble here may consist of a bunch of // empty lines separated by LF. Need to account for that. QString res = generated_code; QString res2 = res.split("\n", QString::SkipEmptyParts).join("").replace(" ", ""); if (res2.isEmpty()) res = all_errors.join("\n"); return res; } void CompilerDriver::getFirewallAndClusterObjects(const string &cluster_id, const string &firewall_id, Cluster **cl, Firewall **fw) { if (!cluster_id.empty()) { Cluster *orig_cluster = Cluster::cast( objdb->findInIndex(objdb->getIntId(cluster_id))); #ifdef WORK_ON_COPIES *cl = objdb->createCluster(); workspace->add(*cl); (*cl)->duplicate(orig_cluster); #else *cl = orig_cluster; #endif } Firewall *orig_fw = Firewall::cast( objdb->findInIndex(objdb->getIntId(firewall_id))); assert(orig_fw); #ifdef WORK_ON_COPIES *fw = objdb->createFirewall(); workspace->add(*fw); (*fw)->duplicate(orig_fw); if (*cl != NULL) { const map &id_map = (*fw)->getIDMappingTable(); map::const_iterator it; for (it=id_map.begin(); it!=id_map.end(); ++it) (*cl)->replaceRef(it->first, it->second); } #else *fw = orig_fw; #endif } fwbuilder-5.1.0.3599/src/compiler_lib/CompilerDriver_generators.cpp0000644000175000017500000001310711733011756026112 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include "CompilerDriver.h" #include "Configlet.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwcompiler/OSConfigurator.h" #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; extern QString user_name; QString CompilerDriver::printPathForAllTools(Firewall*, const std::string &) { return ""; } QString CompilerDriver::printActivationCommands(Firewall*) { return ""; } QString CompilerDriver::assembleManifest(Cluster*, Firewall*, bool) { return ""; } void CompilerDriver::assembleFwScriptInternal(Cluster *cluster, Firewall* fw, bool cluster_member, OSConfigurator *oscnf, Configlet *script_skeleton, Configlet *top_comment, const QString &comment_char, bool indent) { FWOptions* options = fw->getOptionsObject(); string platform = fw->getStr("platform"); string fw_version = fw->getStr("version"); string host_os = fw->getStr("host_OS"); string family = Resources::os_res[host_os]->Resources::getResourceStr( "/FWBuilderResources/Target/family"); bool debug = options->getBool("debug"); string shell_dbg = (debug)?"set -x":"" ; string cmd_dbg = (debug)?"-v ":""; string prolog_place = options->getStr("prolog_place"); if (prolog_place.empty()) prolog_place = "fw_file"; // old default string pre_hook = fw->getOptionsObject()->getStr("prolog_script"); string firewall_dir = options->getStr("firewall_dir"); if (firewall_dir=="") firewall_dir = "/etc/fw"; char *timestr; time_t tm; struct tm *stm; tm = time(NULL); stm = localtime(&tm); timestr = strdup(ctime(&tm)); timestr[strlen(timestr)-1] = '\0'; QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); script_skeleton->removeComments(); script_skeleton->setVariable("shell_debug", shell_dbg.c_str()); script_skeleton->setVariable("firewall_dir", firewall_dir.c_str()); top_comment->setVariable("version", VERSION); top_comment->setVariable("timestamp", timestr); top_comment->setVariable("tz", tzname[stm->tm_isdst]); top_comment->setVariable("user", user_name); //QFileInfo fw_file_info(fw_file_name); top_comment->setVariable("manifest", assembleManifest(cluster, fw, cluster_member)); top_comment->setVariable("platform", platform.c_str()); top_comment->setVariable("fw_version", fw_version.c_str()); top_comment->setVariable( "comment", prepend(comment_char + " ", fw->getComment().c_str())); script_skeleton->setVariable("have_nat", have_nat); script_skeleton->setVariable("have_filter", have_filter); script_skeleton->setVariable("top_comment", top_comment->expand()); script_skeleton->setVariable( "errors_and_warnings", prepend(comment_char + " ", all_errors.join("\n"))); script_skeleton->setVariable("tools", printPathForAllTools(fw, family)); script_skeleton->setVariable("timestamp", timestr); script_skeleton->setVariable("user", user_name); if (prolog_place == "fw_file") script_skeleton->setVariable("prolog_script", pre_hook.c_str()); else script_skeleton->setVariable("prolog_script", ""); script_buffer = ""; script_skeleton->setVariable("shell_functions", oscnf->printFunctions().c_str()); script_skeleton->setVariable("kernel_vars_commands", prepend((indent) ? " " : "", oscnf->printKernelVarsCommands().c_str())); script_skeleton->setVariable("configure_interfaces", prepend((indent) ? " " : "", oscnf->configureInterfaces().c_str())); // this really adds nothing for the most of the systems script_skeleton->setVariable("other_os_configuration_commands", oscnf->getCompiledScript().c_str()); script_skeleton->setVariable("activation_commands", printActivationCommands(fw)); script_skeleton->setVariable("verify_interfaces", ""); script_skeleton->setVariable("epilog_script", fw->getOptionsObject()->getStr("epilog_script").c_str()); } fwbuilder-5.1.0.3599/src/compiler_lib/openbsdInterfaces.h0000644000175000017500000000250411733011756024035 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENBSD_INTERFACE_PROPERTIES_HH #define OPENBSD_INTERFACE_PROPERTIES_HH #include "interfaceProperties.h" class openbsdInterfaces : public interfaceProperties { public: openbsdInterfaces() : interfaceProperties() {} virtual bool parseVlan(const QString&, QString*, int*); virtual bool manageIpAddresses(libfwbuilder::Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/linux24Interfaces.cpp0000644000175000017500000003003711733011756024245 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "interfaceProperties.h" #include "linux24Interfaces.h" #include #include #include #include using namespace std; using namespace libfwbuilder; bool linux24Interfaces::parseVlan(const QString &name, QString *base_name, int *vlan_id) { QList vlan_name_patterns; vlan_name_patterns.append(QRegExp("([a-zA-Z-]+\\d{1,})\\.(\\d{1,})")); vlan_name_patterns.append(QRegExp("(vlan)(\\d{1,})")); for (int idx=0; idx < vlan_name_patterns.size(); ++idx) { if (vlan_name_patterns[idx].indexIn(name) != -1) { if (base_name!=NULL) *base_name = vlan_name_patterns[idx].cap(1); if (vlan_id!=NULL) *vlan_id = vlan_name_patterns[idx].cap(2).toInt(); return true; } } return false; } /* * per #1856, OpenWRT uses "-" in ppp interface names, such as * "ppp-dsl". Also bridge interfaces can have "-" in their names. It * seems we should just allow "-" in names instead of cherry-picking */ bool linux24Interfaces::basicValidateInterfaceName(Interface *intf, const QString &obj_name, QString &err) { if (obj_name.indexOf(' ') != -1) { err = QObject::tr("Bridge interface name '%1' can not contain white space").arg(obj_name); return false; } return true; return true; } /* * Take original information about interfaces provided by the crawler * and try to arrange it into a tree or interfaces and * subinterfaces. Guess based on host OS, inetrface names and their * MAC addresses. Returns data in the argument @interface_tree */ void linux24Interfaces::rearrangeInterfaces(map &interfaces, list &interface_tree) { /* how to find vlan subinterfaces: if interface 1 has name with a dot and numbers after the dot, AND its MAC address is the same as MAC address of an interface 2 with the name matching the part before the dot, then interface 1 is subinterface of 1 and type of interface 2 should be 8021q Example of mixed configuration : Bridge: br0 -> eth4 Bonding: bond0 -> eth2 eth3 Vlans: eth1 -> eth1.100 eth1.101 eth1.102 bond0 -> bond0.200 bond0.201 bond0.202 eth0 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:96 bond0 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:AA bond0.200 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:AA bond0.201 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:AA bond0.202 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:AA eth2 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:AA eth3 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:AA eth1 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:A0 eth1.100 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:A0 eth1.101 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:A0 eth1.102 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:A0 br0 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:BE eth4 Link encap:Ethernet HWaddr 00:0C:29:F6:BE:BE */ // map mac addresse to list of InterfaceData objects. Note that // there can be several interfaces with the same mac address map > all_mac_addresses; // pass 1: group interfaces by mac address map::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i) { // loopback, tunnels and p2p interfaces have no mac address if (i->second.mac_addr.empty()) interface_tree.push_back(&(i->second)); else all_mac_addresses[i->second.mac_addr].push_back(&(i->second)); } // pass 2: for each unique mac address, create top level interface and // subinterfaces map >::iterator it; for (it=all_mac_addresses.begin(); it!=all_mac_addresses.end(); ++it) { if (it->second.size() > 1) { // several interfaces with the same mac address // // Can be: // eth0 and eth0.100, eth0.101 // eth0 and vlan1, vlan2 // bond0 and eth0, eth1 // br0 and eth0, eth1 list vlan_subinterfaces; list bond_subinterfaces; list bridge_subinterfaces; InterfaceData *vlan_parent_interface = NULL; InterfaceData *bond_parent_interface = NULL; InterfaceData *bridge_parent_interface = NULL; list::iterator intf; bool bonding = false; bool bridge = false; bool vlans = false; bool have_dots = false; for (intf=it->second.begin(); intf!=it->second.end(); ++intf) { if ((*intf)->name.find("br") == 0) bridge = true; if ((*intf)->name.find("bond") == 0) bonding = true; if ((*intf)->name.find("vlan") == 0) vlans = true; if ((*intf)->name.find(".") != string::npos) have_dots = true; } // assume that interface with a dot in names are vlan // interfaces such as "eth0.100". // But vlan interfaces can be "bond0.100" as well. if (!vlans && have_dots) vlans = true; for (intf=it->second.begin(); intf!=it->second.end(); ++intf) { linux24Interfaces::interface_type itype; if ((*intf)->name.find("bond") == 0 && (*intf)->name.find(".") == string::npos) itype = BONDING_INTERFACE; if ((*intf)->name.find("eth") == 0 && (*intf)->name.find(".") == string::npos) itype = ETH_NO_DOT; if ((*intf)->name.find(".") != string::npos || (*intf)->name.find("vlan") == 0) itype = VLAN_INTERFACE; if ((*intf)->name.find("br") == 0 && (*intf)->name.find(".") == string::npos) itype = BRIDGE_INTERFACE; if (bonding) { switch (itype) { case BONDING_INTERFACE: // interface name starts with "bond" and has no dot // like "bond0" (*intf)->interface_type = "bonding"; bond_parent_interface = *intf; continue; case ETH_NO_DOT: // interface name starts with "eth" and has no dot // like "eth0" // This is physical interface that is a member of bonding group (*intf)->interface_type = "ethernet"; bond_subinterfaces.push_back(*intf); continue; case VLAN_INTERFACE: { (*intf)->interface_type = "8021q"; parseVlan((*intf)->name.c_str(), NULL, &((*intf)->vlan_id)); //parseVlan(*intf); bond_subinterfaces.push_back(*intf); continue; } default: break; } } if (bridge) { switch (itype) { case BRIDGE_INTERFACE: // interface name starts with "br" and has no dot // like "br0" (*intf)->interface_type = "bridge"; bridge_parent_interface = *intf; continue; case ETH_NO_DOT: // interface name starts with "eth" and has no dot // like "eth0" // This is physical interface that is a member of a bridge (*intf)->interface_type = "ethernet"; bridge_subinterfaces.push_back(*intf); // special case: eth0 can be part of the bridge and // vlan parent interface // break from switch but continue the loop // continue; break; case VLAN_INTERFACE: { (*intf)->interface_type = "8021q"; parseVlan((*intf)->name.c_str(), NULL, &((*intf)->vlan_id)); //parseVlan(*intf); bridge_subinterfaces.push_back(*intf); // special case: vlan interface can be part of // the bridge and part of the vlan configuration // break from switch but continue the loop // continue; break; } default: break; } } if (vlans) { switch (itype) { case ETH_NO_DOT: // interface name starts with "eth" and has no dot // like "eth0" (*intf)->interface_type = "ethernet"; vlan_parent_interface = *intf; continue; case VLAN_INTERFACE: { (*intf)->interface_type = "8021q"; parseVlan((*intf)->name.c_str(), NULL, &((*intf)->vlan_id)); //parseVlan(*intf); vlan_subinterfaces.push_back(*intf); continue; } default: break; } } // if we get here, then interface was not covered by either // of the cases above. Just create it as top-level interface_tree.push_back(*intf); } if (bond_parent_interface) { for (intf=bond_subinterfaces.begin(); intf!=bond_subinterfaces.end(); ++intf) bond_parent_interface->subinterfaces.push_back(*intf); interface_tree.push_back(bond_parent_interface); } if (bridge_parent_interface) { for (intf=bridge_subinterfaces.begin(); intf!=bridge_subinterfaces.end(); ++intf) bridge_parent_interface->subinterfaces.push_back(*intf); interface_tree.push_back(bridge_parent_interface); } if (vlan_parent_interface) { for (intf=vlan_subinterfaces.begin(); intf!=vlan_subinterfaces.end(); ++intf) vlan_parent_interface->subinterfaces.push_back(*intf); interface_tree.push_back(vlan_parent_interface); } } else { // single interface with this mac, just create it as top-level interface_tree.push_back(it->second.front()); } } } fwbuilder-5.1.0.3599/src/compiler_lib/iosInterfaces.h0000644000175000017500000000266511733011756023205 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IOS_INTERFACE_PROPERTIES_HH #define IOS_INTERFACE_PROPERTIES_HH #include "interfaceProperties.h" class iosInterfaces : public interfaceProperties { public: iosInterfaces() : interfaceProperties() {} // simple name validation: does not allow space. Unlike this function // in the base class, permit "-" virtual bool basicValidateInterfaceName(libfwbuilder::Interface *intf, const QString &proposed_name, QString &err); virtual bool parseVlan(const QString&, QString*, int*); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/interfaceProperties.cpp0000644000175000017500000004460211733011756024754 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "interfaceProperties.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FailoverClusterGroup.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; bool interfaceProperties::parseVlan(const QString&, QString*, int*) { return false; } bool interfaceProperties::looksLikeVlanInterface(InterfaceData *intf) { return parseVlan(intf->name.c_str(), NULL, NULL); } bool interfaceProperties::looksLikeVlanInterface(const QString &int_name) { return parseVlan(int_name, NULL, NULL); } /* * common denominator interface name guess. Something like "eth0", * "foo0", "longname0", "name0.1", "name0:1". This is mostly intended * for Linux and BSD, even though it probably matches some Cisco * interfaces too. */ bool interfaceProperties::looksLikeInterface(const QString &name) { QRegExp basic_interface_name_pattern("^[a-zA-Z]+\\d{1,}(\\.\\d{1,})?(:\\d{1,})?$"); return (basic_interface_name_pattern.indexIn(name) != -1); } // simple name validation: does not allow space and "-" // However some platform permit space (procurve). bool interfaceProperties::basicValidateInterfaceName(Interface *, const QString &obj_name, QString &err) { if (obj_name.indexOf(' ') != -1 || obj_name.indexOf('-') != -1) { err = QObject::tr("Interface name '%1' can not contain white space and \"-\"").arg(obj_name); return false; } return true; } /* * While looksLikeVlanInterface only checks interface name format, * this method does more detailed check to determine if the interface * is valid vlan. In particular, it checks that given interface is * indeed a subinterface (parent is also interface) and its base name * matches the name of the parent */ bool interfaceProperties::isValidVlanInterfaceName(const QString &subint_name, const QString &parent_name, QString &err) { if (!looksLikeVlanInterface(subint_name)) { err = QObject::tr("'%1' is not a valid vlan interface name") .arg(subint_name); return false; } QString parent_name_from_regex; int vlan_id; if (parseVlan(subint_name, &parent_name_from_regex, &vlan_id)) { if (!parent_name.isEmpty() && parent_name_from_regex != "vlan" && parent_name != parent_name_from_regex) { err = QObject::tr("'%1' looks like a name of a vlan interface " "but it does not match the name of the parent " "interface '%2'").arg(subint_name).arg(parent_name); return false; } if (vlan_id > 4095) { err = QObject::tr("'%1' looks like a name of a vlan interface " "but vlan ID it defines is outside of the valid " "range.").arg(subint_name); return false; } } return true; } void interfaceProperties::getListOfAddresses(Interface *intf, QStringList &addr_list) { list addresses = intf->getByType(IPv4::TYPENAME); list ipv6_addresses = intf->getByType(IPv6::TYPENAME); addresses.splice(addresses.begin(), ipv6_addresses); for (FWObject::iterator j=addresses.begin(); j!=addresses.end(); ++j) { const InetAddr *iaddr_addr = Address::cast(*j)->getAddressPtr(); const InetAddr *iaddr_netm = Address::cast(*j)->getNetmaskPtr(); addr_list.push_back( QString("%1/%2"). arg(iaddr_addr->toString().c_str()). arg(iaddr_netm->getLength())); } } /* * we manage only addresses of vrrp cluster interfaces. * * We ignore addresses of heartbeat and openais cluster interfaces. * To ignore them, we pass list of addresses managed by heartbeat to * shell function update_addresses (defined in configlet * "update_addresses") as its second argument to make it ignore these * * This code assumes the name of the cluster interface is the same as * names of the corresponding interfaces of member firewalls. */ bool interfaceProperties::manageIpAddresses(Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses) { update_addresses.clear(); ignore_addresses.clear(); FWObject *fw = Host::getParentHost(intf); //FWObject *fw = intf->getParentHost(); Resources *os_res = Resources::os_res[fw->getStr("host_OS")]; assert(os_res != NULL); if (intf->isDyn()) return false; if (intf->isBridgePort()) return false; if (intf->isSlave()) return false; if (intf->isUnnumbered()) return false; // see #1506 string intf_name = intf->getName(); if (intf->getOptionsObject()->getBool("cluster_interface")) { if (intf->isLoopback()) return false; if (intf->isFailoverInterface()) { FWObject *failover_group = intf->getFirstByType(FailoverClusterGroup::TYPENAME); string failover_type = failover_group->getStr("type"); if (os_res->getResourceBool( "/FWBuilderResources/Target/protocols/" + failover_type + "/manage_addresses")) { getListOfAddresses(intf, update_addresses); return true; } else return false; } /* * if this is cluster interface with the same name as fw interface * (as happens in case of hearbeat or openais), skip it */ if (intf->getOptionsObject()->getStr("base_device") == intf_name) return false; } else { // regular interface. Lets see if there is cluster interface // with the same name. If there is and its failover protocol // is heartbeat or openais, we should ignore all addresses it // might have. getListOfAddresses(intf, update_addresses); list interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->getName() == intf_name && iface->getOptionsObject()->getBool("cluster_interface") && iface->isFailoverInterface()) { FWObject *failover_group = iface->getFirstByType(FailoverClusterGroup::TYPENAME); string failover_type = failover_group->getStr("type"); // some protocols do not like it when failover ip address // is managed outside their software if (! os_res->getResourceBool( "/FWBuilderResources/Target/protocols/" + failover_type + "/manage_addresses")) getListOfAddresses(iface, ignore_addresses); break; } } } return true; } bool interfaceProperties::validateInterface(FWObject *target, FWObject *intf, bool check_types, QString &err) { if (Interface::cast(target) && Interface::cast(intf)) { if (!Interface::cast(target)->validateChild(intf)) { // See Interface::validateChild(). Currently the only // condition when interface can not become a child of // another interface is when interface has subinterfaces // of its own. err = QObject::tr("Interface %1 can not become subinterface of %2 " "because only one level of subinterfaces is allowed.") .arg(intf->getName().c_str()) .arg(target->getName().c_str()); return false; } if (check_types) { // We check types when this method is called from a compiler string target_interface_type = Interface::cast(target)->getOptionsObject()->getStr("type"); if (target_interface_type.empty()) target_interface_type = "ethernet"; FWObject *fw = Host::getParentHost(target); //FWObject *fw = Interface::cast(target)->getParentHost(); QString host_os = fw->getStr("host_OS").c_str(); Resources* os_res = Resources::os_res[host_os.toStdString()]; list interface_type_pairs; os_res->getResourceStrList( "/FWBuilderResources/Target/subinterfaces/" + target_interface_type, interface_type_pairs); list interface_types; for (list::iterator it=interface_type_pairs.begin(); it!=interface_type_pairs.end(); ++it) { QString p = it->c_str(); interface_types.push_back(p.split(",")[0].toStdString()); } // Implement interface type checks here string interface_type = Interface::cast(intf)->getOptionsObject()->getStr("type"); if (interface_type.empty()) interface_type = "ethernet"; if (std::find(interface_types.begin(), interface_types.end(), interface_type) == interface_types.end()) { err = QObject::tr("Interface %1 (type '%2') can not be a child " "of interface %3 (type '%4')") .arg(intf->getName().c_str()) .arg(interface_type.c_str()) .arg(target->getName().c_str()) .arg(target_interface_type.c_str()); return false; } } } if (Cluster::cast(target) && Interface::cast(intf)) { // Note that @target may not be actually a parent of @intf at // the time of call to this function. We use this function to // validate operation of making @intf a child of @target. @intf // can have some other parent at the moment. FWObject *parent_interface = intf->getParent(); if (Interface::isA(parent_interface)) { string interface_type = Interface::cast(intf)->getOptionsObject()->getStr("type"); if (interface_type.empty()) interface_type = "ethernet"; string parent_interface_type = Interface::cast(parent_interface)->getOptionsObject()->getStr("type"); if (parent_interface_type.empty()) parent_interface_type = "ethernet"; if (parent_interface_type == "bridge" && interface_type == "ethernet") { err = QObject::tr("Interface %1 is a bridge port, " "it can not belong to a cluster") .arg(intf->getName().c_str()); return false; } if (parent_interface_type == "bonding" && interface_type == "ethernet") { err = QObject::tr("Interface %1 is a bonding interface slave, " "it can not belong to a cluster") .arg(intf->getName().c_str()); return false; } } } return validateInterface(target, intf->getName().c_str(), err); } /** * this method implements policy for the interface hierarchy, that is, * can given interface be a child of a cluster or a firewall or * another interface. */ bool interfaceProperties::validateInterface(FWObject *target, const QString &interface_name, QString &err) { if (Firewall::cast(target) || Host::cast(target)) { if (vlan_checks && looksLikeVlanInterface(interface_name)) { QString target_name = target->getName().c_str(); if (Cluster::isA(target)) { // cluster is allowed to have top-level vlan interfaces, // therefore we do not need to check the name of the // interface against the name of the parent. This is // signalled to isValidVlanInterfaceName() by passing // empty string as target_interface target_name = ""; } return isValidVlanInterfaceName(interface_name, target_name, err); } return true; } if (Interface::cast(target)) { string target_interface_type = Interface::cast(target)->getOptionsObject()->getStr("type"); // check vlan conditions as well if (vlan_checks && looksLikeVlanInterface(interface_name)) { // vlan interface can be a child of a bridge, in which // case its base name does not match the // parent. Perform other checks except this, pass "" // as parent name argument to isValidVlanInterfaceName() if (target_interface_type == "bridge") return isValidVlanInterfaceName(interface_name, "", err); QString target_name = target->getName().c_str(); return isValidVlanInterfaceName(interface_name, target_name, err); } // interface_name is not a vlan // regular interface can only be a child of bond or bridge if (target_interface_type != "bridge" && target_interface_type != "bonding") { err = QObject::tr("Interface %1 which is not a vlan can only " "be a subinterface of a bridge or bonding interface") .arg(interface_name); return false; } return true; } // target is not firewall (cluster) and not interface err = QObject::tr("Interface can not be a child object of %1").arg( target->getTypeName().c_str()); return false; } /* * Ticket #727 * * if type is ethernet and has vlan subinterfaces, not eligible * if type is vlan, eligible * if type is bridge, eligible * if type is bonding, eligible * if type is ethernet and interface with the same name is used for bonding, then not eligible * if type is ethernet and parent is bridge, then not eligible */ bool interfaceProperties::isEligibleForCluster(Interface *intf) { list subinterfaces = intf->getByType(Interface::TYPENAME); string interface_type = intf->getOptionsObject()->getStr("type"); if (intf->isBridgePort()) return false; if (interface_type.empty()) interface_type = "ethernet"; if (interface_type == "8021q") return true; if (interface_type == "bridge") return true; if (interface_type == "bonding") return true; if (interface_type == "ethernet") { Interface *parent_iface = Interface::cast(intf->getParent()); if (parent_iface && parent_iface->getOptionsObject()->getStr("type") == "bridge") return false; FWObject *fw = Host::getParentHost(intf); //FWObject *fw = intf->getParentHost(); list interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); Interface *parent_iface = Interface::cast(iface->getParent()); if (parent_iface == NULL) continue; if (parent_iface->getOptionsObject()->getStr("type") == "bonding" && iface->getName() == intf->getName()) { // @intf is used as a bond slave and can't be used for cluster return false; } } if (subinterfaces.size() > 0) return false; } return true; } void interfaceProperties::guessSubInterfaceTypeAndAttributes(Interface *intf) { Interface *parent_intf = Interface::cast(intf->getParent()); if (parent_intf == NULL) return; FWObject *f = Host::getParentHost(intf); //FWObject *f = intf->getParentHost(); // Resources* os_res = Resources::os_res[f->getStr("host_OS")]; // string os_family = f->getStr("host_OS"); // if (os_res!=NULL) // os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); QString err; if (looksLikeVlanInterface(intf->getName().c_str()) && isValidVlanInterfaceName(intf->getName().c_str(), intf->getParent()->getName().c_str(), err) ) { InterfaceData *idata = new InterfaceData(*intf); //parseVlan(idata); idata->interface_type = "8021q"; parseVlan(idata->name.c_str(), NULL, &(idata->vlan_id)); if (!idata->interface_type.empty()) { intf->getOptionsObject()->setStr("type", idata->interface_type); if (idata->interface_type == "8021q") intf->getOptionsObject()->setInt("vlan_id", idata->vlan_id); } delete idata; } else { if (parent_intf->getOptionsObject()->getStr("type") == "bridge") { intf->getOptionsObject()->setStr("type", "ethernet"); } if (parent_intf->getOptionsObject()->getStr("type") == "bonding") { intf->getOptionsObject()->setStr("type", "ethernet"); intf->setUnnumbered(true); } } } fwbuilder-5.1.0.3599/src/compiler_lib/CompilerDriver_compile.cpp0000644000175000017500000001220311733011756025365 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include "CompilerDriver.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Rule.h" #include "fwcompiler/Compiler.h" #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; bool CompilerDriver::prepare(const QStringList &_args) { args = _args; if (!configure(args)) return false; if (!single_rule_compile_on) { Firewall *fw = locateObject(); if (fw == NULL) { cerr << "Firewall or cluster object not found" << endl; return false; } } return true; } void CompilerDriver::compile() { if (single_rule_compile_on) { QMapIterator it(compileSingleRule(single_rule_id)); while (it.hasNext()) { it.next(); info("Firewall " + it.key().toStdString()); info(it.value().toStdString()); info("\n"); } return; } Firewall *fw = locateObject(); if (Cluster::isA(fw)) { commonChecks(fw); // compiling cluster. list members; Cluster::cast(fw)->getMembersList(members); for (list::iterator it=members.begin(); it!=members.end(); ++it) { info("\n"); info(" Firewall " + (*it)->getName() + " member of cluster " + fw->getName()); CompilerDriver *cl_driver = clone(); cl_driver->configure(args); cl_driver->chDir(); cl_driver->run(objdb->getStringId(fw->getId()), objdb->getStringId((*it)->getId()), ""); if (cl_driver->status == BaseCompiler::FWCOMPILER_ERROR) status = cl_driver->status; delete cl_driver; } } else { chDir(); commonChecks(fw); run("", objdb->getStringId(fw->getId()), ""); } } /* * Compile single rule and return generated code. Rule is defined by * its ID, this is sufficient to locate the rule, ruleset and firewall * objects. If ruleset belongs to a cluster, compile all members and * return code generated for all of them. Returned code is placed in * QMap where the key is member firewall name and value is generated * script. If the rule belongs to a firewall rather than a cluster, * returned QMap contains one item. */ QMap CompilerDriver::compileSingleRule(const string &rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; Rule *rule = Rule::cast( objdb->findInIndex(FWObjectDatabase::getIntId(rule_id))); if (rule==NULL) throw FWException(string("Rule with ID=") + rule_id + " not found"); FWObject *p = rule; while (p && Firewall::cast(p)==NULL) p = p->getParent(); if (Cluster::isA(p)) cluster = Cluster::cast(p); if (Firewall::isA(p)) fw = Firewall::cast(p); QMap result; if (cluster) { commonChecks(cluster); list members; Cluster::cast(cluster)->getMembersList(members); // this copy of CompilerDriver is not going to do any useful work and // does not need these. objdb->remove(persistent_objects, false); objdb->remove(workspace, false); for (list::iterator it=members.begin(); it!=members.end(); ++it) { CompilerDriver *cl_driver = clone(); cl_driver->single_rule_compile_on = true; if (inTestMode()) cl_driver->setTestMode(); if (inEmbeddedMode()) cl_driver->setEmbeddedMode(); result[(*it)->getName().c_str()] = cl_driver->run( objdb->getStringId(cluster->getId()), objdb->getStringId((*it)->getId()), rule_id); delete cl_driver; } } else { commonChecks(fw); single_rule_compile_on = true; result[fw->getName().c_str()] = run("", objdb->getStringId(fw->getId()), rule_id); } return result; } fwbuilder-5.1.0.3599/src/compiler_lib/AutomaticRules.cpp0000644000175000017500000000751411733011756023701 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AutomaticRules.h" #include "fwbuilder/Address.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Policy.h" using namespace fwcompiler; using namespace libfwbuilder; using namespace std; AutomaticRules::AutomaticRules(Firewall *fw, Library *persistent_objects) { this->fw = fw; this->persistent_objects = persistent_objects; ruleset = NULL; list all_policies = fw->getByType(Policy::TYPENAME); for (FWObject::iterator it=all_policies.begin(); it!=all_policies.end(); ++it) { Policy *policy = Policy::cast(*it); FWOptions *rulesetopts = policy->getOptionsObject(); if (rulesetopts->getBool("mangle_only_rule_set")) continue; if (policy->isTop()) { ruleset = policy; break; } } } PolicyRule* AutomaticRules::addMgmtRule( Address* src, Address* dst, Service* service, Interface* iface, const PolicyRule::Direction direction, const PolicyRule::Action action, const string &label, bool related) { if (ruleset == NULL) return NULL; /* Insert PolicyRules at top so they do not get shadowed by other * rules. Call insertRuleAtTop() with hidden_rule argument true to * make sure this rule gets negative position number and does not * shift positions of other rules. See ticket #16. Also, hidden * rules are not considered for shadowing. */ PolicyRule* rule = PolicyRule::cast(ruleset->insertRuleAtTop(true)); assert(rule != NULL); ostringstream str; str << rule->getPosition() << " " << label << " (automatic)" ; rule->setLabel(str.str()); FWObject *re; re = rule->getSrc(); assert(re!=NULL); RuleElementSrc::cast(re)->reset(); if(src != NULL) re->addRef(src); re = rule->getDst(); assert(re!=NULL); RuleElementDst::cast(re)->reset(); if(dst != NULL) re->addRef(dst); re = rule->getSrv(); assert(re!=NULL); RuleElementSrv::cast(re)->reset(); if(service != NULL) re->addRef(service); re = rule->getWhen(); assert(re!=NULL); RuleElementInterval::cast(re)->reset(); re = rule->getItf(); assert(re!=NULL); RuleElementItf::cast(re)->reset(); if(iface != NULL) { re->addRef(iface); // rule->setInterfaceId(iface->getId()); } rule->add(ruleset->getRoot()->create(PolicyRuleOptions::TYPENAME)); rule->setLogging(false); rule->enable(); rule->setAction(action); rule->setDirection(direction); // Use firewall object ID to generate uique ID for this management rule // to make it stable across different runs of the compiler rule->setUniqueId( ruleset->getRoot()->getPredictableId( FWObjectDatabase::getStringId(fw->getId()) + "." )); return rule; } fwbuilder-5.1.0.3599/src/compiler_lib/compiler_lib.pro0000644000175000017500000000175111733011756023413 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # # This library is separate from fwcompiler library because it has dependency # on QT include(../../qmake.inc) TEMPLATE = lib SOURCES = CompilerDriver.cpp \ CompilerDriver_files.cpp \ CompilerDriver_compile.cpp \ CompilerDriver_generators.cpp \ Configlet.cpp \ interfaceProperties.cpp \ linux24Interfaces.cpp \ openbsdInterfaces.cpp \ freebsdInterfaces.cpp \ iosInterfaces.cpp \ procurveInterfaces.cpp \ pixInterfaces.cpp \ interfacePropertiesObjectFactory.cpp \ AutomaticRules.cpp HEADERS = ../../config.h \ CompilerDriver.h \ Configlet.h \ interfaceProperties.h \ linux24Interfaces.h \ openbsdInterfaces.h \ freebsdInterfaces.h \ iosInterfaces.h \ procurveInterfaces.h \ pixInterfaces.h \ interfacePropertiesObjectFactory.h \ AutomaticRules.h INCLUDEPATH += ../libfwbuilder/src DEPENDPATH += ../libfwbuilder/src CONFIG += staticlib TARGET = compilerdriver INSTALLS -= target fwbuilder-5.1.0.3599/src/compiler_lib/pixInterfaces.cpp0000644000175000017500000000322511733011756023537 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "pixInterfaces.h" #include /* * http://www.cisco.com/en/US/docs/security/asa/asa70/command/reference/gl.html#wp1644971 * * hostname(config)# interface gigabitethernet0/1.1 * hostname(config-subif)# vlan 101 * hostname(config-subif)# nameif dmz1 * hostname(config-subif)# security-level 50 * hostname(config-subif)# ip address 10.1.2.1 255.255.255.0 * hostname(config-subif)# no shutdown * */ bool pixInterfaces::parseVlan(const QString &name, QString *base_name, int *vlan_id) { QRegExp vlan_name_pattern("([a-zA-Z-]+\\d{1,}(/\\d{1,})*)\\.(\\d{1,})"); if (vlan_name_pattern.indexIn(name) != -1) { if (base_name!=NULL) *base_name = vlan_name_pattern.cap(1); if (vlan_id!=NULL) *vlan_id = vlan_name_pattern.cap(3).toInt(); return true; } return false; } fwbuilder-5.1.0.3599/src/compiler_lib/Configlet.h0000644000175000017500000000520511733011756022312 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CONFIGLET_HH__ #define __CONFIGLET_HH__ #include #include #include namespace libfwbuilder { class FWObject; }; class Configlet { bool processIf(QString &stream, int pos); protected: QString name; QString prefix; QString file_path; QStringList code; QMap vars; bool remove_comments; QString comment_str; bool collapse_empty_strings; static bool configlet_debugging; static QString begin_marker; static QString end_marker; QString getFullPath(const QString &rel_path); QString getConfigletPath(const QString &configlet_name); public: Configlet(const std::string &prefix, const QString &filename); Configlet(const std::string &prefix, const std::string &default_prefix, const QString &filename); Configlet(libfwbuilder::FWObject *fw, const std::string &default_prefix, const QString &filename); virtual ~Configlet(); bool reload(const std::string &prefix, const QString &filename); void clear(); void setVariable(const QString &name, const QString &value); void setVariable(const QString &name, int value); QString expand(); void removeComments(const QString &comment_str="##"); void collapseEmptyStrings(bool f); /* * the following methods are used in unit tests */ static void setDebugging(bool f) { configlet_debugging = f; } static QString findGeneratedText(const QString &configlet_name, const QString &text, int nth=1); static QString findConfigletInFile(const QString &configlet_name, const QString &file_path, int nth=1); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/linux24Interfaces.h0000644000175000017500000000304011733011756023704 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef LINUX24_INTERFACE_PROPERTIES_HH #define LINUX24_INTERFACE_PROPERTIES_HH #include "interfaceProperties.h" class linux24Interfaces : public interfaceProperties { public: linux24Interfaces() : interfaceProperties() {} virtual ~linux24Interfaces() {} virtual bool basicValidateInterfaceName(libfwbuilder::Interface *intf, const QString &proposed_name, QString &err); virtual bool parseVlan(const QString&, QString*, int*); virtual void rearrangeInterfaces( std::map &interfaces, std::list &interface_tree); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/CompilerDriver.h0000644000175000017500000002534011733011756023330 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_HH__ #define __COMPILER_DRIVER_HH__ #include "fwcompiler/BaseCompiler.h" #include "Configlet.h" #include #include #include #include #include #include #include #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; class Cluster; class ClusterGroup; class FailoverClusterGroup; class Firewall; class RuleSet; class Interface; class Address; class InetAddr; }; #define FW_FILE 0 #define CONF1_FILE 1 #define CONF2_FILE 2 namespace fwcompiler { class OSConfigurator; class CompilerDriver : public BaseCompiler { QString getOutputFileNameInternal(libfwbuilder::Firewall *current_fw, const QString &from_cli, const QString &option_name, const QString &fw_name, const QString &ext); protected: QStringList all_errors; QStringList args; int fwbdebug; std::string filename; std::string wdir; QDir start_current_dir; QString fwobjectname; QString current_firewall_name; // list of file names we should generate. Items in the list are // as follows: [0] - the name of the initialization script (normally // the .fw file); [1] - the name of the confguration file (for // pf, ipfilter this is the main .conf file); [2] - the name of the // next conf file, if any; and so on. // // function determineOutputFileNames() fills this list QStringList file_names; // file names on the firewall with full path. Items should correspond // to items in the list file_name // // function determineOutputFileNames() fills this list QStringList remote_file_names; // I store file name provided via -o command line option here QString file_name_setting_from_command_line; // member_file_names is the mapping between member firewall // object ID and corresponding output file name. Can be // enfirced via -O command line option or determined // automatically using member firewall name. Used only when // compiling Cluster QMap member_file_names; int dl; int drp; int drn; int drr; bool rule_debug_on; bool single_rule_compile_on; bool prepend_cluster_name_to_output_file; std::string single_rule_id; int verbose; bool have_dynamic_interfaces; bool ipv4_run; bool ipv6_run; bool fw_by_id; bool prolog_done; bool epilog_done; bool have_filter; bool have_nat; std::map branches; libfwbuilder::FWObjectDatabase *objdb; libfwbuilder::Library *persistent_objects; libfwbuilder::Library *workspace; void determineOutputFileNames(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall *current_fw, bool cluster_member, const QStringList &suffixes, const QStringList &extensions, const QStringList &remote_file_name_fw_options); bool isSupported(std::list *protocols, const std::string &cluster_group_type); virtual int checkCluster(libfwbuilder::Cluster* cluster); void mergeRuleSets(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall *fw, const std::string &type); static bool isReachable(const libfwbuilder::Address* const subnet, const libfwbuilder::InetAddr* const addr); void clearReadOnly(libfwbuilder::Firewall *fw); /* Virtual methods used to compose generated script */ virtual QString printPathForAllTools(libfwbuilder::Firewall* fw, const std::string &os); virtual QString printActivationCommands(libfwbuilder::Firewall *fw); virtual QString assembleManifest(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member); virtual void assembleFwScriptInternal(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall* fw, bool cluster_member, OSConfigurator *ocsnf, Configlet *script_skeleton, Configlet *top_comment, const QString &comment_char, bool indent); void _findImportedRuleSetsRecursively(libfwbuilder::Firewall *fw, libfwbuilder::RuleSet *ruleset, std::map &branch_rulesets); QString getAbsOutputFileName(const QString &output_file_name); public: CompilerDriver(libfwbuilder::FWObjectDatabase *db); virtual ~CompilerDriver(); // create a copy of itself, including objdb virtual CompilerDriver* clone(); /** * Process command line arguments */ virtual bool configure(const QStringList &args); /** * Assign target object by its id */ void setTargetId(const std::string &id); /** * create right compiler objects and compile policy, nat and * routing rules for given firewall which can be a member of a * cluster. If firewall is standalone, @cluster_id is an empty * string. Cluster and firewall are defined by their string IDs. * In single compile mode rule ID is provided in @single_rule_id * and generated script is returned. For compilers that create * several files it is up to the actual cmopiler class to decide * what should be returned in the single rule compile mode. In * normal (not single rule) compile mode returned string is * undefined and should not be used. */ virtual QString run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id); virtual void commonChecks(libfwbuilder::Firewall *fw); virtual void commonChecks2(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall *fw); void copyFailoverInterface(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall *fw, libfwbuilder::FailoverClusterGroup *cluster_group, libfwbuilder::Interface *iface); virtual void populateClusterElements(libfwbuilder::Cluster *cluster, libfwbuilder::Firewall *fw); virtual void processStateSyncGroups(libfwbuilder::Cluster*, libfwbuilder::Firewall*); std::string indent(int n_spaces, const std::string &txt); QString indent(int n_spaces, const QString &txt); QString prepend(const QString &prep, const QString &txt); /* * Verifies that state sync and failover group types configured in * the GUI are supported for the given host OS. List of supported * protocols is taken from the os resource file. If unsupported * protocol is found, calls compiler->abort to abort immediately. */ virtual void validateClusterGroups(libfwbuilder::Cluster *cluster); /* * Use chdir to change working directory. In case of failure, exit(1) */ void chDir(); /* * Find firewall or cluster object we should process. */ virtual libfwbuilder::Firewall* locateObject(); void getFirewallAndClusterObjects(const std::string &cluster_id, const std::string &fw_id, libfwbuilder::Cluster **cl, libfwbuilder::Firewall **fw); void findImportedRuleSets(libfwbuilder::Firewall *fw, std::list &all_policies); void assignUniqueRuleIds(std::list &all_policies); virtual bool prepare(const QStringList &args); virtual void compile(); virtual QMap compileSingleRule(const std::string &rule_id); /* * if compilers produced empty string for the generated code, * this method checks if there were any errors and returns * them. If compilers generated output, errors should be * included in it because warning and error messages are * usually attached to rules. Errors are taken from the * all_errors member variable. */ QString formSingleRuleCompileOutput(const QString &generated_code); static QString escapeFileName(QString fileName); static QString unescapeFileName(QString fileName); static QString getConfFileNameFromFwFileName(const QString &file_name, const QString &ext); void setDebugRule(int dr) { drp = drn = dr; rule_debug_on = true; } }; }; QTextStream& operator<< (QTextStream &text_stream, const std::string &str); #endif fwbuilder-5.1.0.3599/src/compiler_lib/interfacePropertiesObjectFactory.cpp0000644000175000017500000000464311733011756027434 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "interfacePropertiesObjectFactory.h" #include "interfaceProperties.h" #include "linux24Interfaces.h" #include "iosInterfaces.h" #include "procurveInterfaces.h" #include "openbsdInterfaces.h" #include "freebsdInterfaces.h" #include "pixInterfaces.h" #include "procurveInterfaces.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Resources.h" #include using namespace libfwbuilder; using namespace std; interfaceProperties* interfacePropertiesObjectFactory::getInterfacePropertiesObject(FWObject *fw) { Resources* os_res = Resources::os_res[fw->getStr("host_OS")]; string os_family = fw->getStr("host_OS"); if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); return getInterfacePropertiesObject(os_family); } interfaceProperties* interfacePropertiesObjectFactory::getInterfacePropertiesObject( const std::string &os_family) { if (os_family == "linux24" || os_family == "openwrt" || os_family == "dd-wrt-nvram" || os_family == "dd-wrt-jffs" || os_family == "secuwall") return new linux24Interfaces(); if (os_family == "ios") return new iosInterfaces(); if (os_family == "pix_os" || os_family == "ios") return new pixInterfaces(); if (os_family == "openbsd") return new openbsdInterfaces(); if (os_family == "freebsd") return new freebsdInterfaces(); if (os_family == "procurve") return new procurveInterfaces(); // by default return object of the base class. It performs some // reasonable default actions. return new interfaceProperties(); } fwbuilder-5.1.0.3599/src/compiler_lib/procurveInterfaces.h0000644000175000017500000000403611733011756024252 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PROCURVE_INTERFACE_PROPERTIES_HH #define PROCURVE_INTERFACE_PROPERTIES_HH #include "interfaceProperties.h" class procurveInterfaces : public interfaceProperties { public: procurveInterfaces() : interfaceProperties() {} // simple name validation: does not allow space and "-" // However some platform permit space (procurve). virtual bool basicValidateInterfaceName(libfwbuilder::Interface *intf, const QString &proposed_name, QString &err); virtual bool parseVlan(const QString&, QString*, int*); virtual bool isValidVlanInterfaceName(const QString &, const QString &, QString&); virtual bool validateInterface(libfwbuilder::FWObject *parent, const QString &inetrface_name, QString &err); virtual bool validateInterface(libfwbuilder::FWObject *parent, libfwbuilder::FWObject *intf, bool check_types, QString &err); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/iosInterfaces.cpp0000644000175000017500000000357511733011756023541 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "iosInterfaces.h" #include "fwbuilder/Interface.h" #include #include #include using namespace std; using namespace libfwbuilder; bool iosInterfaces::parseVlan(const QString &name, QString *base_name, int *vlan_id) { QRegExp vlan_name_pattern("([a-zA-Z-]+\\d{1,}/\\d{1,})\\.(\\d{1,})"); if (vlan_name_pattern.indexIn(name) != -1) { if (base_name!=NULL) *base_name = vlan_name_pattern.cap(1); if (vlan_id!=NULL) *vlan_id = vlan_name_pattern.cap(2).toInt(); return true; } return false; } // simple name validation: does not allow space and "-" // However some platform permit space (procurve). bool iosInterfaces::basicValidateInterfaceName(Interface *, const QString &obj_name, QString &err) { if (obj_name.indexOf(' ') != -1) { err = QObject::tr("Interface name '%1' can not contain white space").arg(obj_name); return false; } return true; } fwbuilder-5.1.0.3599/src/compiler_lib/openbsdInterfaces.cpp0000644000175000017500000000361411733011756024373 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "openbsdInterfaces.h" #include "fwbuilder/Interface.h" #include using namespace libfwbuilder; bool openbsdInterfaces::parseVlan(const QString &name, QString *base_name, int *vlan_id) { QRegExp vlan_name_pattern(QRegExp("(vlan)(\\d{1,})")); if (vlan_name_pattern.indexIn(name) != -1) { if (base_name!=NULL) *base_name = vlan_name_pattern.cap(1); if (vlan_id!=NULL) *vlan_id = vlan_name_pattern.cap(2).toInt(); return true; } return false; } bool openbsdInterfaces::manageIpAddresses(Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses) { if (intf->isDyn()) { // We never manage dynamic interfaces on OpenBSD // But we should add them to the list when rc.conf output format is // implemented, just like it is now done for FreeBSD return false; } else return interfaceProperties::manageIpAddresses( intf, update_addresses, ignore_addresses); } fwbuilder-5.1.0.3599/src/compiler_lib/interfaceProperties.h0000644000175000017500000001017511733011756024417 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INTERFACE_PROPERTIES_HH #define INTERFACE_PROPERTIES_HH #include #include #include #include "fwbuilder/InterfaceData.h" class interfaceProperties { protected: typedef enum {BONDING_INTERFACE, ETH_NO_DOT, VLAN_INTERFACE, BRIDGE_INTERFACE, UNKNOWN} interface_type; bool vlan_checks; /* * collects all ip addresses of the interface (only direct * addresses, not addresses of subinterfaces) and fills the list * with string representation in the form "address/masklen" */ void getListOfAddresses(libfwbuilder::Interface *intf, QStringList &addr_list); public: interfaceProperties() { vlan_checks = true; } virtual ~interfaceProperties() {} void setPerformVlanChecks(bool f) { vlan_checks = f; } // simple name validation: does not allow space and "-" // However some platform permit space (procurve). virtual bool basicValidateInterfaceName(libfwbuilder::Interface *intf, const QString &proposed_name, QString &err); virtual void rearrangeInterfaces( std::map &interfaces, std::list &interface_tree) { // default rearranger: just copy the data std::map::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i) { interface_tree.push_back(&(i->second)); } } virtual bool looksLikeInterface(const QString&); virtual bool parseVlan(const QString&, QString*, int*); virtual bool isValidVlanInterfaceName(const QString &, const QString &, QString&); virtual bool looksLikeVlanInterface(libfwbuilder::InterfaceData*); virtual bool looksLikeVlanInterface(const QString&); virtual bool validateInterface(libfwbuilder::FWObject *parent, const QString &inetrface_name, QString &err); virtual bool validateInterface(libfwbuilder::FWObject *parent, libfwbuilder::FWObject *intf, bool check_types, QString &err); virtual bool isEligibleForCluster(libfwbuilder::Interface *intf); virtual void guessSubInterfaceTypeAndAttributes(libfwbuilder::Interface *intf); /** * for the given interface return list of its ip addresses that we * should manage using update_addresses shell function and list of * addresses we should ignore (as in the case of hearbeat or openais * cluster interfaces). Returns true if we should manage ip addresses * of this interface and false otherwise. Note that it is possible to * return true even when there are no addresses to manage, in which * case lists update_addresses and ignore_addresses are empty. */ virtual bool manageIpAddresses(libfwbuilder::Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses); }; #endif fwbuilder-5.1.0.3599/src/compiler_lib/procurveInterfaces.cpp0000644000175000017500000001027211733011756024604 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "procurveInterfaces.h" #include "fwbuilder/Interface.h" #include #include using namespace std; using namespace libfwbuilder; // simple name validation: does not allow space and "-" // However PoCurve permits space. What about "-" ? bool procurveInterfaces::basicValidateInterfaceName(Interface*, const QString &obj_name, QString &err) { if (obj_name.indexOf('-') != -1) { err = QObject::tr("Interface name '%1' can not contain \"-\"").arg(obj_name); return false; } err = ""; return true; } /* * The difference is that in ProCurve, vlan interfaces have names like * "VLAN 2". We should permit white space between "vlan" and the * number. It is unclear whether "vlan" and "Vlan" are allowed besides * "VLAN". */ bool procurveInterfaces::parseVlan( const QString &name, QString *base_name, int *vlan_id) { if (name == "DEFAULT_VLAN") { if (base_name!=NULL) *base_name = "vlan"; if (vlan_id!=NULL) *vlan_id = 1; return true; } // Procurve SNMP reports vlan interface names without space QRegExp vlan_name_pattern("(vlan|Vlan|VLAN) *(\\d{1,})"); if (vlan_name_pattern.indexIn(name) != -1) { if (base_name!=NULL) *base_name = vlan_name_pattern.cap(1); if (vlan_id!=NULL) *vlan_id = vlan_name_pattern.cap(2).toInt(); return true; } return false; } /* * In ProCurve, parent interface and vlan interface names have nothing * in common and can not be verified. */ bool procurveInterfaces::isValidVlanInterfaceName(const QString &subint_name, const QString & /*UNUSED parent_name */, QString &err) { if (!looksLikeVlanInterface(subint_name)) { err = QObject::tr("'%1' is not a valid vlan interface name").arg(subint_name); return false; } QString parent_name_from_regex; int vlan_id; if (parseVlan(subint_name, &parent_name_from_regex, &vlan_id)) { if (vlan_id > 4095) { err = QObject::tr("'%1' looks like a name of a vlan interface " "but vlan ID it defines is outside of the valid range." "").arg(subint_name); return false; } } return true; } /* * many switch ports can be part of the same vlan. It would be ideal * if I could make interface objects that represent switch ports as * subinterfaces of a vlan interface. Unfortunately this is reverse of * our normal model, where vlans are subinterfaces of ethernet * interface objects. Until I figure this out, there will be no * restrictions on ProCurve interface objects. */ bool procurveInterfaces::validateInterface(FWObject * /*UNUSED target */, FWObject * /*UNUSED intf */, bool /*UNUSED check_types */, QString & /*UNUSED err */) { return true; } bool procurveInterfaces::validateInterface(FWObject * /*UNUSED target */, const QString & /*UNUSED interface_name */, QString & /*UNUSED err */) { return true; } fwbuilder-5.1.0.3599/src/compiler_lib/freebsdInterfaces.cpp0000644000175000017500000000342411733011756024352 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "freebsdInterfaces.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" #include using namespace libfwbuilder; /* see #2032. About dynamic interfaces: - when we generate rc.conf file, we should add line "ifconfig_em0="DHCP"" for dynamic interfaces, so we should include them in the management list as well. */ bool freebsdInterfaces::manageIpAddresses(Interface *intf, QStringList &update_addresses, QStringList &ignore_addresses) { if (intf->isDyn()) { FWObject *p = intf; while (Firewall::cast(p) == NULL) p = p->getParent(); Firewall *fw = Firewall::cast(p); FWOptions* options = fw->getOptionsObject(); return options->getBool("generate_rc_conf_file"); } else return openbsdInterfaces::manageIpAddresses( intf, update_addresses, ignore_addresses); } fwbuilder-5.1.0.3599/src/compiler_lib/Configlet.cpp0000644000175000017500000002407011733011756022646 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "Configlet.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; /* * Switch to the special debugging mode if this flag is true. Used in * unit tests. This adds special comment lines to mark beginning and * end of the generated text */ bool Configlet::configlet_debugging = false; QString Configlet::begin_marker = "|||||||||||||||| Begin configlet %1"; QString Configlet::end_marker = "|||||||||||||||| End configlet %1"; /* * @filename is a name of the configlet file. The program searches for * it in resources directory, subdirectory configlets/@prefix. If * @filename is absolute path, the program tries to open file as * specified. */ Configlet::Configlet(const std::string &prefix, const QString &file_name) { name = file_name; reload(prefix, file_name); } Configlet::Configlet(const std::string &prefix, const std::string &default_prefix, const QString &file_name) { clear(); name = file_name; if (!reload(prefix, file_name)) reload(default_prefix, file_name); } Configlet::Configlet(FWObject *fw, const std::string &default_prefix, const QString &file_name) { string host_os = fw->getStr("host_OS"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); remove_comments = true; comment_str = "##"; collapse_empty_strings = false; name = file_name; if (!reload(os_family, file_name)) reload(default_prefix, file_name); if (code.size() == 0) qCritical() << "Could not open configlet file" << os_family.c_str() << "/" << file_name << "or" << default_prefix.c_str() << "/" << file_name; } Configlet::~Configlet() { } void Configlet::clear() { vars.clear(); remove_comments = true; comment_str = "##"; collapse_empty_strings = false; } bool Configlet::reload(const std::string &_prefix, const QString &file_name) { prefix = _prefix.c_str(); code.clear(); file_path = getConfigletPath(file_name); if (!QFile(file_path).exists()) return false; else { QFile file(file_path); if (file.open(QFile::ReadOnly)) { QTextStream ts(&file); do { QString line = ts.readLine(); code.push_back(line); } while (!ts.atEnd()); removeComments(); return true; } } return false; } QString Configlet::getFullPath(const QString &path) { if (QDir::isRelativePath(path)) return QString(Constants::getResourcesDirectory().c_str()) + "/configlets/" + path; else return path; } QString Configlet::getConfigletPath(const QString &configlet_name) { if (QDir::isAbsolutePath(configlet_name)) return configlet_name; QString home = QDir::homePath(); QString file_path; file_path = home + "/fwbuilder/configlets/" + prefix + "/" + configlet_name; if (QFile(file_path).exists()) return file_path; file_path = getFullPath(prefix + "/" + configlet_name); return file_path; } // ************************************************************************ void Configlet::setVariable(const QString &name, const QString &value) { vars[name] = value.trimmed(); } void Configlet::setVariable(const QString &name, int value) { QString val; val.setNum(value); vars[name] = val; } QString Configlet::expand() { // Need non-greedy matching so that if_re matches only one {{?var}} ... {{?}} // clause QRegExp var_re("\\{\\{\\$([^}]*)\\}\\}", Qt::CaseSensitive, QRegExp::RegExp2); var_re.setMinimal(true); // remove comments before processing {{$var}} and {{if var}} so we can // use these in comments QString all_code; if (remove_comments) { QStringList res; foreach(QString line, code) { if (line.startsWith(comment_str)) continue; res.push_back(line); } all_code = res.join("\n"); } else all_code = code.join("\n"); QString err = QObject::tr("Configlet expansion stopped by " "infinite loop protector. " "Check configlet syntax. %1").arg(file_path); int counter = 0; int pos = 0; while ((pos = var_re.indexIn(all_code, pos)) != -1 && counter < 1000) { QString var = var_re.cap(1); if (vars.count(var) > 0) { all_code.replace(QString("{{$%1}}").arg(var), vars[var]); } else { // template has a variable that has not been defined // remove '$' from the macro but leave it in place for debugging all_code.replace(QString("{{$%1}}").arg(var), QString("{{%1}}").arg(var)); } counter++; } if (counter >= 1000) qDebug() << err; counter = 0; while (processIf(all_code, 0) && counter < 1000) counter++; if (counter >= 1000) qDebug() << err; if (configlet_debugging) { all_code.push_front(begin_marker.arg(name) + "\n"); all_code.push_back(end_marker.arg(name) + "\n"); } if (collapse_empty_strings) { QStringList res; foreach(QString line, all_code.split("\n")) { if (line.trimmed().isEmpty()) continue; res.push_back(line); } return res.join("\n"); } return all_code; } /* * pos points to the position of "{{?var}}" in the stream */ bool Configlet::processIf(QString &stream, int pos) { QRegExp if_re("\\{\\{if {1,}([^}]{1,})\\}\\}", Qt::CaseSensitive, QRegExp::RegExp2); QRegExp endif_re("\\{\\{endif\\}\\}", Qt::CaseSensitive, QRegExp::RegExp2); if_re.setMinimal(true); endif_re.setMinimal(true); int current_if_pos = if_re.indexIn(stream, pos); if (current_if_pos == -1) return false; int current_if_length = if_re.cap(0).length(); QString current_if_var = if_re.cap(1); // look what is next, another opening if or closing endif int next_if_pos = if_re.indexIn( stream, current_if_pos + current_if_length); int next_endif_pos = endif_re.indexIn( stream, current_if_pos + current_if_length); if (next_if_pos != -1 && next_if_pos < next_endif_pos) { processIf(stream, next_if_pos); // the next if statement has been replaced, process current if // statement again return true; } if (next_endif_pos != -1) { int next_endif_length = endif_re.cap(0).length(); // current if statement starts at current_if_pos // and ends at next_endif_pos + next_endif_length int current_if_clause_length = next_endif_pos + next_endif_length - current_if_pos; QString body = stream.mid( current_if_pos + current_if_length, next_endif_pos - current_if_pos - current_if_length); QString replacement; if (vars.count(current_if_var) > 0) { bool ok = false; int f = vars[current_if_var].toInt(&ok); if (ok && f) replacement = body; } stream.replace(current_if_pos, current_if_clause_length, replacement); } return true; } /** * Set internal flag to remove comments from the produced script and * set comment string. By default comment string is "##". This means * we can still put comments with single "#" in templates and have * these comments appear in the generated script. At the same time, # comments marked with "##" will be removed. */ void Configlet::removeComments(const QString &_str) { remove_comments = true; comment_str = _str; } void Configlet::collapseEmptyStrings(bool f) { collapse_empty_strings = f; } /* * find n-th occurrence of the configlet with given name in @text. Count * from 1 */ QString Configlet::findGeneratedText(const QString &configlet_name, const QString &text, int nth) { QString begin_m = begin_marker.arg(configlet_name) + "\n"; QString end_m = end_marker.arg(configlet_name) + "\n"; int n1 = -1, n2 = 0; // find n-th occurrence int count = 0; while (count < nth) { n1++; n1 = text.indexOf(begin_m, n1); if (n1 == -1) return ""; count++; } n1 += begin_m.length(); n2 = text.indexOf(end_m, n1); if (n2 != -1) return text.mid(n1, n2 - n1); return text.mid(n1); } QString Configlet::findConfigletInFile(const QString &configlet_name, const QString &file_path, int nth) { QStringList res; if (!QFile(file_path).exists()) return ""; else { QFile file(file_path); if (file.open(QFile::ReadOnly)) { QTextStream ts(&file); do { QString line = ts.readLine(); res.push_back(line); } while (!ts.atEnd()); } } return findGeneratedText(configlet_name, res.join("\n"), nth); } fwbuilder-5.1.0.3599/src/compiler_lib/interfacePropertiesObjectFactory.h0000644000175000017500000000241611733011756027075 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INTERFACE_PROPERTIES_OBJECT_FACTORY_HH #define INTERFACE_PROPERTIES_OBJECT_FACTORY_HH #include #include "interfaceProperties.h" namespace libfwbuilder { class FWObject; } class interfacePropertiesObjectFactory { public: static interfaceProperties* getInterfacePropertiesObject(const std::string &host_os); static interfaceProperties* getInterfacePropertiesObject(libfwbuilder::FWObject *fw); }; #endif fwbuilder-5.1.0.3599/src/procurve_acl/0000755000175000017500000000000011733011756020251 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/procurve_acl/procurve_acl.cpp0000644000175000017500000001112411733011756023440 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include #include #include #include #include #include #ifdef _WIN32 # include #else # include #endif #include #include #include #include #include #include #include #include "CompilerDriver_procurve_acl.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Constants.h" #include #include #include #include "../common/init.cpp" using namespace std; using namespace libfwbuilder; using namespace fwcompiler; FWObjectDatabase *objdb = NULL; class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string &msg) const { msg.size(); // to make compiler happy about unused parameter cout << "Data file has been created in the old version of Firewall Builder.\nLoad it in the GUI to convert it to the new version." << endl; return false; } }; void usage(const char *name) { cout << "Firewall Builder: policy compiler for HP ProCurve ACL" << endl; cout << "Copyright 2010 NetCitadel, LLC" << endl; cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-tvV] [-f filename.xml] [-d destdir] [-o output.fw] firewall_object_name" << endl; } int main(int argc, char **argv) { QApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_procurve_acl *driver = new CompilerDriver_procurve_acl(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; delete driver; delete objdb; return ret; } catch(libfwbuilder::FWException &ex) { cerr << ex.toString() << endl; return 1; } catch (std::string s) { cerr << s << endl; return 1; } catch (std::exception ex) { cerr << "exception: " << ex.what() << endl; return 1; } catch (...) { cerr << "Unsupported exception"; return 1; } return 0; } fwbuilder-5.1.0.3599/src/procurve_acl/procurve_acl.pro0000644000175000017500000000154311733011756023462 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # include(../../qmake.inc) # # # PACKAGE = fwbuilder-procurve_acl-$$FWB_VERSION # # QMAKE_CXXFLAGS_DEBUG += -DPACKAGE="\"$$PACKAGE\"" # QMAKE_CXXFLAGS_RELEASE += -DPACKAGE="\"$$PACKAGE\"" SOURCES = procurve_acl.cpp HEADERS = ../../config.h !win32 { QMAKE_COPY = ../../install.sh -m 0755 -s } win32:CONFIG += console INCLUDEPATH += ../cisco_lib ../compiler_lib ../libfwbuilder/src DEPENDPATH += ../cisco_lib ../compiler_lib ../libfwbuilder/src PRE_TARGETDEPS = ../common/$$BINARY_SUBDIR/libcommon.a \ ../cisco_lib/$$BINARY_SUBDIR/libfwbcisco.a \ ../compiler_lib/$$BINARY_SUBDIR/libcompilerdriver.a \ ../libfwbuilder/src/fwcompiler/$$BINARY_SUBDIR/libfwcompiler.a \ ../libfwbuilder/src/fwbuilder/$$BINARY_SUBDIR/libfwbuilder.a \ LIBS += $$PRE_TARGETDEPS $$LIBS TARGET = fwb_procurve_acl fwbuilder-5.1.0.3599/src/common/0000755000175000017500000000000011733011756017055 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/common/commoninit.h0000644000175000017500000000014511733011756021402 0ustar sylvestresylvestre#ifndef COMMON_INIT_H #define COMMON_INIT_H #include void init(char * const *argv); #endif fwbuilder-5.1.0.3599/src/common/init2.cpp0000644000175000017500000000547711733011756020623 0ustar sylvestresylvestre #include "../../config.h" #include #if defined(Q_OS_MACX) || defined(Q_OS_WIN32) # include # include # include # include #endif #include #include #ifdef _WIN32 # include # include # include # include #else # include # include #endif #include #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include "commoninit.h" extern std::string appRootDir; extern std::string userDataDir; extern std::string argv0; extern std::string ee; extern QString user_name; using namespace std; using namespace libfwbuilder; void init_win() { /* * Note appRootDir is the path to the directory where fwbuilder binary * is installed (on Mac it is /fwbuilder3.app/Contents/MacOS. * On Windows it is c:\FWBuilder30, on Linux it is something like * /usr/bin or /usr/local/bin and so on. */ #if defined(Q_OS_WIN32) || defined(Q_OS_MACX) if (QCoreApplication::instance()==NULL) { int ac = 0; char **av = { NULL }; new QApplication( ac, av ); } QDir dir(QApplication::applicationDirPath()); appRootDir = string(dir.absolutePath().toAscii().constData()); /* On windows and mac we install API resources (DTD etc) in the * dir right above the one where we install resources for the GUI and compilers */ Constants::init(appRootDir); // if (respath == "") // { // respath = appRootDir + FS_SEPARATOR + Constants::getTemplateDirectory(); // QFileInfo fi(respath.c_str()); // respath = fi.canonicalFilePath().toStdString(); // to remove .. and symlinks // librespath = fi.canonicalPath().toStdString(); // dir one level up // } argv0 = QCoreApplication::applicationFilePath().toStdString(); libfwbuilder::init(); /* default directory where the user may want to save files */ #if defined(Q_OS_WIN32) userDataDir = string(getenv("USERPROFILE"))+"\\Documents"; #elif defined(Q_OS_MACX) userDataDir = string(getenv("HOME"))+"/Documents"; #endif #ifdef _WIN32 #define INFO_BUFFER_SIZE 32767 TCHAR infoBuf[INFO_BUFFER_SIZE]; DWORD bufCharCount = INFO_BUFFER_SIZE; bufCharCount = INFO_BUFFER_SIZE; if( GetUserName( infoBuf, &bufCharCount ) ) { #ifdef UNICODE user_name = QString::fromUtf16((ushort*)infoBuf); #else user_name = QString::fromLocal8Bit(infoBuf); #endif } user_name = user_name.replace(' ','_'); #elif defined(Q_OS_MACX) char *lname = getenv("LOGNAME"); if (lname!=NULL) user_name = QString(lname); else { struct passwd *pwd = getpwuid(getuid()); assert(pwd); user_name = QString(pwd->pw_name); } #endif #endif } fwbuilder-5.1.0.3599/src/common/common.pro0000644000175000017500000000067511733011756021077 0ustar sylvestresylvestre#-*- mode: makefile; tab-width: 4; -*- # # This library provides basic initialization function used in all executables, # including the GUI and all compilers # on QT include(../../qmake.inc) TEMPLATE = lib SOURCES = init.cpp init2.cpp HEADERS = ../../config.h commoninit.h INCLUDEPATH += ../libfwbuilder/src DEPENDPATH += ../libfwbuilder/src CONFIG += staticlib TARGET = common INSTALLS -= target exists(qmake.inc):include( qmake.inc) fwbuilder-5.1.0.3599/src/common/init.cpp0000644000175000017500000000242311733011756020525 0ustar sylvestresylvestre #include "../../config.h" #include #include #include #include #include #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Constants.h" #include "commoninit.h" // TODO: switch to QString std::string appRootDir; std::string userDataDir; std::string argv0; std::string ee; QString user_name; #if defined(Q_OS_WIN32) || defined(Q_OS_MACX) extern void init_win(); void init(char * const*) { init_win(); } #else #include #include extern int fwbdebug; using namespace std; using namespace libfwbuilder; void init(char * const*) { appRootDir = string(PREFIX) + FS_SEPARATOR + "bin"; /* On Unix RES_DIR and LIBFWBUILDER_TEMPLATE_DIR are absolute paths */ libfwbuilder::init(); /* need argv0 for built-in installer on unix and mac */ argv0 = appRootDir + FS_SEPARATOR + "fwbuilder"; /* default directory where the user may want to save files */ userDataDir = string(getenv("HOME")); char *lname = getenv("LOGNAME"); if (lname!=NULL) user_name = QString(lname); else { struct passwd *pwd = getpwuid(getuid()); assert(pwd); user_name = QString(pwd->pw_name); } } #endif fwbuilder-5.1.0.3599/src/libgui/0000755000175000017500000000000011733011756017040 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/longTextDialog.h0000644000175000017500000000225611733011756022142 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LONGTEXTDIALOG_H_ #define __LONGTEXTDIALOG_H_ #include "config.h" #include class longTextDialog : public QDialog { Q_OBJECT Ui::longTextDialog_q *m_dialog; public: longTextDialog(QWidget *p,const QString &txt,const QString <xt); ~longTextDialog(); }; #endif // __LONGTEXTDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FWWindow_wrappers.cpp0000644000175000017500000003014211733011756023173 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003, 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectManipulator.h" #include "FWObjectClipboard.h" #include "FWBTree.h" #include "FWBSettings.h" #include "RuleSetView.h" #include "FindObjectWidget.h" #include "FindWhereUsedWidget.h" #include "events.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Tools.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Library.h" #include "fwbuilder/FWObject.h" #include /* * Methods in this module are just wrappers and call the same method * in the topmost object of the ProjectPanel class (MDI subwindow). * * TODO: see if most of these methods can be called directly using * pointer to the ProjectPanel object. Remove most, if not all, * wrappers in the FWWindow class. */ using namespace libfwbuilder; using namespace std; using namespace Ui; /*************************************************************************/ bool FWWindow::saveIfModified() { if (activeProject()) return activeProject()->saveIfModified(); return false; } QString FWWindow::chooseNewFileName(const QString &fname, const QString &title) { if (activeProject()) return activeProject()->chooseNewFileName(fname,title); return ""; } void FWWindow::setFileName(const QString &fname) { if (activeProject()) activeProject()->setFileName(fname); } void FWWindow::fileProp() { if (activeProject()) activeProject()->fileProp(); } void FWWindow::fileSave() { if (activeProject()) { activeProject()->fileSave(); QCoreApplication::postEvent(this, new updateGUIStateEvent()); //prepareFileMenu(); } } void FWWindow::fileSaveAs() { if (activeProject()) { activeProject()->fileSaveAs(); QCoreApplication::postEvent(this, new updateGUIStateEvent()); //prepareFileMenu(); } } void FWWindow::fileCommit() { if (activeProject()) { activeProject()->fileCommit(); // reset actions, including Save() which should now // be inactive QCoreApplication::postEvent(this, new updateGUIStateEvent()); //prepareFileMenu(); } } /* * discard changes done to the file and check out clean copy of the * head revision from RCS */ void FWWindow::fileDiscard() { if (activeProject()) { activeProject()->fileDiscard(); QCoreApplication::postEvent(this, new updateGUIStateEvent()); //prepareFileMenu(); //prepareRulesMenu(); //updateGlobalToolbar(); } } void FWWindow::fileAddToRCS() { if (activeProject()) { activeProject()->fileAddToRCS(); QCoreApplication::postEvent(this, new updateGUIStateEvent()); //prepareFileMenu(); } } void FWWindow::load(QWidget*) { if (activeProject()) activeProject()->loadStandardObjects(); } void FWWindow::load(QWidget*, RCS *_rcs) { if (activeProject()) activeProject()->loadFromRCS(_rcs); } void FWWindow::save() { if (activeProject()) activeProject()->save(); } void FWWindow::loadLibrary(const string &libfpath) { if (activeProject()) activeProject()->loadLibrary(libfpath); } void FWWindow::fileImport() { if (activeProject()) { activeProject()->fileImport(); QCoreApplication::postEvent(this, new updateGUIStateEvent()); //prepareFileMenu(); //prepareRulesMenu(); //updateGlobalToolbar(); } } void FWWindow::fileCompare() { if (activeProject()) activeProject()->fileCompare(); } void FWWindow::findExternalRefs(FWObject *lib, FWObject *root, list &extRefs) { if (activeProject()) activeProject()->findExternalRefs(lib, root, extRefs); } bool FWWindow::checkin(bool unlock) { if (activeProject()) return activeProject()->checkin(unlock); return false; } void FWWindow::setSafeMode(bool f) { if (activeProject()) activeProject()->setSafeMode(f); } bool FWWindow::exportLibraryTest(list &selectedLibs) { /* VERY IMPORTANT: External library file must be self-contained, * otherwise it can not be exported. * * check if selected libraries have references to objects in other * libraries (not exported to the same file). Exporting such libraries * pulls in other ones because of these references. This is confusing * because it means we end up with multiple copies of such objects (in * exported library file and in user's data file). When user imports * this library and opens their file, it is impossible to say which * library an object belongs to. * * This is prohibited. We check if exported set of libraries has such * references and refuse to export it. The user is supposed to clean * it up by either moving objects into the library they are trying to * export, or by rearranging objects. The only exception for this is * library "Standard", which is assumed to be always present so we can * have references to objects in it. */ if (activeProject()) return activeProject()->exportLibraryTest(selectedLibs); return false; } void FWWindow::exportLibraryTo(QString fname,list &selectedLibs, bool rof) { if (activeProject()) activeProject()->exportLibraryTo(fname,selectedLibs, rof); } void FWWindow::fileExport() { if (activeProject()) activeProject()->fileExport(); } int FWWindow::findFirewallInList(FWObject *f) { if (activeProject()) return activeProject()->findFirewallInList(f); return -1; } /* * There is a problem with using QTextBrowser widget or QTextEdit in * read-only mode in that QT for some reason disables Ctrl-C and other * basic copy/paste keyboard shortcuts when these widgets are * read-only. When user hits Ctrl-C when one of such widgets is * active, the program tries to copy object instead of expected effect * of copying text from the QTextEdit. */ void FWWindow::editCopy() { QWidget *w = QApplication::focusWidget(); if (fwbdebug) qDebug() << "FWWindow::editCopy" << w; if (w->inherits("QTextEdit")) { dynamic_cast(w)->copy(); return; } if (activeProject()) { activeProject()->editCopy(); } } void FWWindow::editCut() { if (activeProject()) { activeProject()->editCut(); } } void FWWindow::editDelete() { if (activeProject()) { activeProject()->editDelete(); } } void FWWindow::editPaste() { if (activeProject()) { activeProject()->editPaste(); } } void FWWindow::toggleViewObjectTree() { if (activeProject()) { activeProject()->toggleViewTree(m_mainWindow->actionObject_Tree->isChecked()); } } void FWWindow::toggleViewEditor() { if (m_mainWindow->actionEditor_panel->isChecked()) { if (activeProject()) openEditor(activeProject()->m_panel->om->getSelectedObject()); else m_mainWindow->editorDockWidget->show(); } else m_mainWindow->editorDockWidget->hide(); } void FWWindow::toggleViewUndo() { if (m_mainWindow->actionUndo_view->isChecked()) m_mainWindow->undoDockWidget->show(); else m_mainWindow->undoDockWidget->hide(); } void FWWindow::insertRule() { if (activeProject()) activeProject()->insertRule(); } void FWWindow::addRuleAfterCurrent() { if (activeProject()) activeProject()->addRuleAfterCurrent(); } void FWWindow::removeRule() { if (activeProject()) activeProject()->removeRule(); } void FWWindow::moveRule() { if (activeProject()) activeProject()->moveRule(); } void FWWindow::moveRuleUp() { if (activeProject()) activeProject()->moveRuleUp(); } void FWWindow::moveRuleDown() { if (activeProject()) activeProject()->moveRuleDown(); } void FWWindow::copyRule() { if (activeProject()) activeProject()->copyRule(); } void FWWindow::cutRule() { if (activeProject()) activeProject()->cutRule(); } void FWWindow::pasteRuleAbove() { if (activeProject()) activeProject()->pasteRuleAbove(); } void FWWindow::pasteRuleBelow() { if (activeProject()) activeProject()->pasteRuleBelow(); } void FWWindow::newObject() { if (activeProject()) { activeProject()->newObject(); } } // ObjectManipulator::lockObject calls // mw->reloadAllWindowsWithFile(activeProject()) to update // other windows void FWWindow::lockObject() { if (activeProject()) activeProject()->lockObject(); } // ObjectManipulator::unlockObject calls // mw->reloadAllWindowsWithFile(activeProject()) to update // other windows void FWWindow::unlockObject() { if (activeProject()) activeProject()->unlockObject(); } void FWWindow::setupAutoSave() { if (activeProject()) activeProject()->setupAutoSave(); } QString FWWindow::getCurrentFileName() { if (activeProject()) return activeProject()->getFileName(); return ""; } RCS * FWWindow::getRCS() { if (activeProject()) return activeProject()->getRCS(); return 0; } /* * reset tab via callback because calling setCurrentPage from * ruleSetTabChanged causes recursive call to ruleSetTabChanged */ void FWWindow::restoreRuleSetTab() { if (activeProject()) activeProject()->restoreRuleSetTab(); } FWObject* FWWindow::getCurrentLib() { if (activeProject()) return activeProject()->getCurrentLib(); return 0; } FWObject* FWWindow::createObject(const QString &objType, const QString &objName, FWObject *copyFrom) { FWObject *res = NULL; if (activeProject()) { res = activeProject()->createObject(objType, objName, copyFrom); } return res; } FWObject* FWWindow::createObject(FWObject *parent, const QString &objType, const QString &objName, FWObject *copyFrom) { FWObject *res = NULL; if (activeProject()) { res = activeProject()->createObject(parent, objType, objName, copyFrom); } return res; } void FWWindow::moveObject(FWObject *target, FWObject *obj) { if (activeProject()) { activeProject()->moveObject(target, obj); } } void FWWindow::moveObject(const QString &targetLibName, FWObject *obj) { if (activeProject()) { activeProject()->moveObject(targetLibName, obj); } } ObjectTreeView* FWWindow::getCurrentObjectTree() { if (activeProject()) return activeProject()->getCurrentObjectTree(); return 0; } void FWWindow::findAllFirewalls (std::list &fws) { if (activeProject()) activeProject()->findAllFirewalls (fws); } void FWWindow::showDeletedObjects(bool f) { if (activeProject()) activeProject()->showDeletedObjects(f); } /* void FWWindow::select() { if (activeProject()) activeProject()->select(); } void FWWindow::unselect() { if (activeProject()) activeProject()->unselect(); } */ FWObjectDatabase* FWWindow::db() { if (activeProject()) return activeProject()->db(); return NULL; } QString FWWindow::printHeader() { if (activeProject()) return activeProject()->printHeader(); return ""; } bool FWWindow::editingLibrary() { if (activeProject()) return activeProject()->editingLibrary(); return false; } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/0000755000175000017500000000000011733011756024440 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/SNMPCrawlerThread.cpp0000644000175000017500000000560311733011756030375 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include #include #include "utils.h" #include "QThreadLogger.h" #include "SNMPCrawlerThread.h" #ifdef HAVE_LIBSNMP // #include snmp.h only after all Qt headers; see #2185 #include "fwbuilder/snmp.h" using namespace std; using namespace libfwbuilder; SNMPCrawlerThread::SNMPCrawlerThread(QWidget *ui, const QString &seedHostName, const QString &community, bool recursive, bool followP2P, int snmpRetries, int snmpTimeout, const std::vector *include_net) { this->ui = ui; stop_flag = new SyncFlag(); QString seedHostAddress = getAddrByName(seedHostName, AF_INET); InetAddr seedHostInetAddr = InetAddr( seedHostAddress.toLatin1().constData()); q = new SNMPCrawler(); q->init(seedHostInetAddr, community.toLatin1().constData(), recursive, false, followP2P, 0, snmpRetries, 1000000L * snmpTimeout, 0, 0, (include_net->size() > 0) ? include_net : NULL); } SNMPCrawlerThread::~SNMPCrawlerThread() { if (fwbdebug) qDebug() << "SNMPCrawlerThread::~SNMPCrawlerThread()"; delete q; delete stop_flag; } void SNMPCrawlerThread::run() { QThreadLogger *logger = new QThreadLogger(); connect(logger, SIGNAL(lineReady(QString)), this->ui, SLOT(logLine(QString)), Qt::QueuedConnection); q->run_impl(logger, stop_flag); emit finished(); deleteLater(); // mark this object for destruction on the next run of event loop } void SNMPCrawlerThread::stop() { stop_flag->set(true); } map SNMPCrawlerThread::getAllIPs() { return q->getAllIPs(); } set SNMPCrawlerThread::getNetworks() { return q->getNetworks(); } #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ProgressPage.cpp0000644000175000017500000002757111733011756030142 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "utils.h" #include "FWBSettings.h" #include #include #include #include #include #include "ND_ProgressPage.h" #include "SNMPCrawlerThread.h" #include "SNMPNetworkDiscoveryWizard.h" // #include snmp.h only after all Qt headers; see #2185 #include "fwbuilder/snmp.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" using namespace std; using namespace libfwbuilder; bool fwbdebug_nd = false; ND_ProgressPage::ND_ProgressPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_ProgressPage_q; m_dialog->setupUi(this); #ifdef HAVE_LIBSNMP crawler = NULL; connect(m_dialog->discoveryStopButton, SIGNAL(clicked()), this, SLOT(stop())); connect(m_dialog->logSaveButton, SIGNAL(clicked()), this, SLOT(saveLog())); #endif QTextCursor cursor(m_dialog->discoveryLog->textCursor()); normal_format = cursor.charFormat(); error_format = normal_format; error_format.setForeground(QBrush(Qt::red)); error_format.setAnchorHref("http://somewhere.com"); error_format.setAnchor(true); // weight must be between 0 and 99. Qt 4.4.1 does not seem to mind if // it is >99 (just caps it) but older versions assert error_format.setProperty(QTextFormat::FontWeight, 99); warning_format = normal_format; warning_format.setForeground(QBrush(Qt::blue)); warning_format.setProperty(QTextFormat::FontWeight, 99); warning_format.setAnchor(true); warning_format.setAnchorHref("http://somewhere.com"); } ND_ProgressPage::~ND_ProgressPage() { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::~ND_ProgressPage()"; disconnect(this, SLOT(logLine(QString))); disconnect(this, SLOT(crawlerFinished())); #ifdef HAVE_LIBSNMP if (crawler != NULL && crawler->isRunning()) { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::initializePage()" << "crawler is still runnig; stopping"; crawler->stop(); // crawler->wait(); // do not delete crawler thread object, we call deleteLater() // in SNMPCrawlerThread::run() to make sure crawler thread // object is only deleted after snmp crawler has finished and // thread terminated } #endif } #ifdef HAVE_LIBSNMP bool ND_ProgressPage::validatePage() { ObjectDescriptorList *objects = dynamic_cast(wizard())->getObjects(); if (fwbdebug_nd) qDebug() << "ND_ProgressPage::validatePage()" << "crawler=" << crawler << "isRunning=" << ((crawler) ? crawler->isRunning() : 0) << "objects->size()=" << objects->size(); if (crawler != NULL && crawler->isRunning()) return false; return (objects->size() > 0); } bool ND_ProgressPage::isComplete() const { if (crawler != NULL && crawler->isRunning()) return false; return true; } void ND_ProgressPage::crawlerDestroyed(QObject *obj) { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::crawlerDestroyed() obj=" << obj; if (obj == crawler) crawler = NULL; } void ND_ProgressPage::initializePage() { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::initializePage()"; ObjectDescriptorList *objects = dynamic_cast(wizard())->getObjects(); ObjectDescriptorList *networks = dynamic_cast(wizard())->getNetworks(); QString seedHostName = field("seedHostName").toString(); QString snmpInclAddr = field("snmpInAddr").toString(); QString snmpInclMask = field("snmpInMask").toString(); bool snmpRecursive = field("snmpRecursive").toBool(); bool snmpFollowP2P = field("snmpFollowP2P").toBool(); // bool snmpIncludeUnnumbered = field("snmpIncludeUnnumbered").toBool(); QString snmpCommunity = field("snmpCommunity").toString(); int snmpRetries = field("snmpRetries").toInt(); int snmpTimeoutSec = field("snmpTimeout").toInt(); QString seedHostAddress = getAddrByName(seedHostName, AF_INET); InetAddr seedHostInetAddr = InetAddr( seedHostAddress.toLatin1().constData() ); include_networks.clear(); bool limit_scan = false; if ( ! snmpInclAddr.isEmpty() && ! snmpInclMask.isEmpty()) { try { InetAddrMask in( InetAddr(snmpInclAddr.toStdString()), InetAddr(snmpInclMask.toStdString()) ); include_networks.push_back(in); limit_scan = true; } catch (const FWException &ex) { //TODO: do something usefull } } if (crawler != NULL && crawler->isRunning()) { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::initializePage()" << "crawler is still runnig; stopping"; crawler->stop(); crawler->wait(); delete crawler; } objects->clear(); networks->clear(); emit completeChanged(); // note that crawler deletes itself using call to deleteLater() after // underlying SNMPCrawler finishes its work. crawler = new SNMPCrawlerThread(this, seedHostName, snmpCommunity, snmpRecursive, snmpFollowP2P, snmpRetries, snmpTimeoutSec, &include_networks); connect(crawler, SIGNAL(destroyed(QObject*)), this, SLOT(crawlerDestroyed(QObject*))); connect(crawler, SIGNAL(finished()), this, SLOT(crawlerFinished())); crawler->start(); } void ND_ProgressPage::cleanupPage() { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::cleanupPage()"; disconnect(this, SLOT(logLine(QString))); disconnect(this, SLOT(crawlerFinished())); if (crawler != NULL && crawler->isRunning()) crawler->stop(); include_networks.clear(); } void ND_ProgressPage::stop() { if (crawler != NULL && crawler->isRunning()) { logLine(tr("Stopping network crawler process...")); crawler->stop(); } } /* * SNMPCrawlerThread emits signal finished() that should be connected * to this slot. We collect all the data here. */ void ND_ProgressPage::crawlerFinished() { if (fwbdebug_nd) qDebug() << "ND_ProgressPage::crawlerFinished()"; ObjectDescriptorList *networks = dynamic_cast(wizard())->getNetworks(); ObjectDescriptorList *objects = dynamic_cast(wizard())->getObjects(); logLine("\n"); logLine(tr("Network crawler stopped")); bool snmpDoDNS = field("snmpDoDNS").toBool(); if (crawler==NULL) return; set::iterator m; set discovered_networks = crawler->getNetworks(); map discovered_addresses = crawler->getAllIPs(); logLine(tr("Discovered %1 networks").arg(discovered_networks.size())); for (m=discovered_networks.begin(); m!=discovered_networks.end(); ++m) { ObjectDescriptor od; InetAddrMask net = *m; logLine(QString("network %1").arg(net.toString().c_str())); // if address in *m is ipv6, recreate it as Inet6AddrMask and // use type NetworkIPv6 if (net.getAddressPtr()->isV6()) { Inet6AddrMask in6am(*(net.getAddressPtr()), *(net.getNetmaskPtr())); od.sysname = in6am.toString(); // different from ipv6 od.type = NetworkIPv6::TYPENAME; } else { od.sysname = net.toString(); od.type = Network::TYPENAME; } od.addr = *(net.getAddressPtr()); od.netmask = *(net.getNetmaskPtr()); od.isSelected = false; networks->push_back(od); } logLine(tr("Discovered %1 addresses").arg(discovered_addresses.size())); int cntr = 0; map::iterator j; for(j = discovered_addresses.begin(); j!=discovered_addresses.end(); ++j,++cntr) { ObjectDescriptor od( &(j->second) ); od.addr = j->first; od.type = (od.interfaces.size()>1) ? (Host::TYPENAME) : (IPv4::TYPENAME); od.isSelected = false; if (od.sysname.empty()) { od.sysname = string("h-") + od.addr.toString(); if (snmpDoDNS) { QString hostName = getNameByAddr( od.addr.toString().c_str() ); if (!hostName.isEmpty()) od.sysname = hostName.toUtf8().constData(); } logLine( QString(od.addr.toString().c_str()) + " : " + od.sysname.c_str()); } if (snmpDoDNS && od.dns_info.aliases.size() > 0) { set::iterator si; for(si=od.dns_info.aliases.begin(); si!=od.dns_info.aliases.end(); ++si) { od.sysname = (*si); objects->push_back(od);; } } else objects->push_back(od); } emit completeChanged(); } void ND_ProgressPage::logLine(const QString &buf) { if (buf.isEmpty()) return; foreach(QString line, buf.trimmed().split("\n")) { QTextCharFormat format = normal_format; if (line.contains("Parser error")) format = error_format; if (line.contains("Parser warning")) format = warning_format; if (line.contains("SNMP error, status 2 Timeout")) format = warning_format; QString txt = line; while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r"))) txt.chop(1); if (format == error_format || format == warning_format) format.setAnchorHref(txt); QTextCursor cursor = m_dialog->discoveryLog->textCursor(); cursor.insertBlock(); cursor.insertText(txt, format); } m_dialog->discoveryLog->ensureCursorVisible(); } void ND_ProgressPage::saveLog() { QString dir; dir = st->getWDir(); if (dir.isEmpty()) dir = st->getOpenFileDir(); if (dir.isEmpty()) dir = "~"; QString s = QFileDialog::getSaveFileName( this, "Choose a file", dir, "Text file (*.txt)"); if (!s.isEmpty()) { if (s.endsWith(".txt")) { s += ".txt"; } QFile f(s); if (f.open(QIODevice::WriteOnly)) { if (fwbdebug) { qDebug("Saving crawler log to file: %d chars", m_dialog->discoveryLog->toPlainText().length()); qDebug("--------------------------------"); } QTextStream strm(&f); QString txt = m_dialog->discoveryLog->toPlainText(); strm << txt << endl; if (fwbdebug) { qDebug("%s",txt.toAscii().constData()); qDebug("--------------------------------"); } f.close(); } } } #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_SNMPParametersPage.cpp0000644000175000017500000000513011733011756031122 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "FWBSettings.h" #include "ND_SNMPParametersPage.h" #include using namespace std; //using namespace libfwbuilder; #define DISCOVERY_DRUID_PREFIX "DiscoveryDruid/" #define DISCOVERY_DRUID_SNMPCOMMUNITY "SNMPCommunity" #define DISCOVERY_DRUID_SNMPRETRIES "SNMPRetries" #define DISCOVERY_DRUID_SNMPTIMEOUT "SNMPTimeout" ND_SNMPParametersPage::ND_SNMPParametersPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_SNMPParametersPage_q; m_dialog->setupUi(this); QString s = st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPCOMMUNITY); m_dialog->snmpCommunity->setText((s.isEmpty())?"public":s); int i = st->getInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRETRIES); m_dialog->snmpRetries->setValue((i)?i:1); i = st->getInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPTIMEOUT); m_dialog->snmpTimeout->setValue((i)?i:2); registerField("snmpCommunity", m_dialog->snmpCommunity); registerField("snmpRetries", m_dialog->snmpRetries); registerField("snmpTimeout", m_dialog->snmpTimeout); } void ND_SNMPParametersPage::initializePage() { if (fwbdebug) qDebug() << "ND_SNMPParametersPage::initializePage()"; } bool ND_SNMPParametersPage::validatePage() { st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPCOMMUNITY, m_dialog->snmpCommunity->text()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRETRIES, m_dialog->snmpRetries->value()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPTIMEOUT, m_dialog->snmpTimeout->value()); return true; } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_setuppage_q.ui0000644000175000017500000002111011733011756027770 0ustar sylvestresylvestre ND_SetupPage_q 0 0 633 629 WizardPage This discovery method scans networks looking for hosts or gateways responding to SNMP queries. It pulls host's ARP table and uses all the entries found in it to create objects. Scan starts from the host called "seed". Enter "seed" host name or address below: Qt::AlignVCenter true 'Seed' host 6 Qt::Horizontal QSizePolicy::Expanding 211 21 true 0 20 Enter a valid host name or address. false 0 0 32767 20 0 Qt::Horizontal Qt::Horizontal QSizePolicy::Expanding 40 20 The scanner process can be confined to a certain network, so it won't discover hosts on adjacent networks. If you leave these fields blank, scanner will visit all networks it can find: Qt::AlignVCenter true Confine scan to this network: Enter network ip address as a standard dotted quad ("192.168.1.0"): Address: false Qt::Horizontal QSizePolicy::Expanding 271 20 Enter netmask as a standard dotted quad ("255.255.255.0") or bit length ("24"): Netmask: false Qt::Horizontal QSizePolicy::Expanding 271 20 false Qt::Vertical QSizePolicy::Expanding 20 255 seedHostName textChanged(QString) ND_SetupPage_q changedSeedHost() 165 101 316 314 snmpInAddr textChanged(QString) ND_SetupPage_q changedLimitScanConfiguraton() 208 237 316 314 snmpInMask textChanged(QString) ND_SetupPage_q changedLimitScanConfiguraton() 208 266 316 314 changedSeedHost() changedLimitScanConfiguraton() fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ChooseNetworksPage.cpp0000644000175000017500000000405611733011756031304 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "ND_ChooseNetworksPage.h" #include "SNMPNetworkDiscoveryWizard.h" #include using namespace std; using namespace libfwbuilder; ND_ChooseNetworksPage::ND_ChooseNetworksPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_ChooseNetworksPage_q; m_dialog->setupUi(this); registerField("networksToUse*", m_dialog->objectSelector, "objectsToUse", SIGNAL(selectionChanged())); } void ND_ChooseNetworksPage::initializePage() { if (fwbdebug) qDebug() << "ND_ChooseNetworksPage::initializePage()"; ObjectDescriptorList *networks = dynamic_cast(wizard())->getNetworks(); m_dialog->objectSelector->init(*networks); /* list objects; fill objects with data and call m_dialog->objectSelector->init(objects); */ } bool ND_ChooseNetworksPage::validatePage() { if (fwbdebug) qDebug() << "ND_ChooseNetworksPage::validatePage()"; return true; } bool ND_ChooseNetworksPage::isComplete() const { if (fwbdebug) qDebug() << "ND_ChooseNetworksPage::isComplete()"; return (m_dialog->objectSelector->count() > 0); } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_SelectLibraryPage.cpp0000644000175000017500000000310211733011756031062 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "ND_SelectLibraryPage.h" #include using namespace std; //using namespace libfwbuilder; ND_SelectLibraryPage::ND_SelectLibraryPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_SelectLibraryPage_q; m_dialog->setupUi(this); registerField("libIndex*", m_dialog->libs); registerField("libraries", this, "libraries"); setCommitPage(true); } void ND_SelectLibraryPage::initializePage() { if (fwbdebug) qDebug() << "ND_SelectLibraryPage::initializePage()"; fillLibraries(m_dialog->libs, mw->activeProject()->db()); for (int i=0; i < m_dialog->libs->count(); ++i) libraries << m_dialog->libs->itemText(i); } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_SetupPage.h0000644000175000017500000000334511733011756027074 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_SETUPPAGE_H_ #define __ND_SETUPPAGE_H_ #include "ui_nd_setuppage_q.h" #include class ND_SetupPage : public QWizardPage { Q_OBJECT; Ui::ND_SetupPage_q *m_dialog; QString last_error; int dns_op_id; bool seedHostOK; bool limitScanConfigurationOK; bool isSeedHostOK(const QString &s); bool looksLikeIpAddress(const QString &s); void displayStatusError(const QString &err); void displayStatusSuccess(const QString &err); void displayStatusNeutral(const QString &err); void showProgressBar(); void hideProgressBar(); public: ND_SetupPage(QWidget *parent); virtual ~ND_SetupPage(); virtual void initializePage(); virtual bool validatePage(); virtual bool isComplete() const; public slots: void changedSeedHost(); void changedLimitScanConfiguraton(); void dnsFinish(const QHostInfo &host); }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ProgressPage.h0000644000175000017500000000344011733011756027574 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_PROGRESSPAGE_H_ #define __ND_PROGRESSPAGE_H_ // for HAVE_LIBSNMP #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/InetAddrMask.h" #include "ui_nd_progresspage_q.h" #include class SNMPCrawlerThread; class ND_ProgressPage : public QWizardPage { Q_OBJECT; Ui::ND_ProgressPage_q *m_dialog; QTextCharFormat normal_format; QTextCharFormat error_format; QTextCharFormat warning_format; std::vector include_networks; public: ND_ProgressPage(QWidget *parent); virtual ~ND_ProgressPage(); #ifdef HAVE_LIBSNMP private: SNMPCrawlerThread *crawler; virtual void initializePage(); virtual void cleanupPage(); virtual bool validatePage(); virtual bool isComplete() const; public slots: void stop(); void saveLog(); void logLine(const QString &line); void crawlerDestroyed(QObject*); void crawlerFinished(); #endif }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_SNMPParametersPage.h0000644000175000017500000000236111733011756030572 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_SNMPPARAMETERSPAGE_H_ #define __ND_SNMPPARAMETERSPAGE_H_ #include "ui_nd_snmpparameterspage_q.h" class ND_SNMPParametersPage : public QWizardPage { Q_OBJECT; Ui::ND_SNMPParametersPage_q *m_dialog; public: ND_SNMPParametersPage(QWidget *parent); virtual ~ND_SNMPParametersPage() {} virtual void initializePage(); virtual bool validatePage(); public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ChooseNetworksPage.h0000644000175000017500000000240411733011756030744 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_CHOOSENETWORKSPAGE_H_ #define __ND_CHOOSENETWORKSPAGE_H_ #include "ui_nd_choosenetworkspage_q.h" class ND_ChooseNetworksPage : public QWizardPage { Q_OBJECT; Ui::ND_ChooseNetworksPage_q *m_dialog; public: ND_ChooseNetworksPage(QWidget *parent); virtual ~ND_ChooseNetworksPage() {} virtual void initializePage(); virtual bool validatePage(); virtual bool isComplete() const; }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_snmpparameterspage_q.ui0000644000175000017500000001135611733011756031704 0ustar sylvestresylvestre ND_SNMPParametersPage_q 0 0 604 539 WizardPage Enter parameters for SNMP and DNS reverse lookup queries below. (If unsure, just leave default values): Qt::AlignVCenter true SNMP query parameters: 6 SNMP 'read' community string: false number of retries: false timeout (sec): false 1 1 1 2 public Qt::Horizontal QSizePolicy::Expanding 190 20 Qt::Horizontal QSizePolicy::Expanding 250 20 Qt::Horizontal QSizePolicy::Expanding 250 20 false Qt::Vertical QSizePolicy::Expanding 20 199 fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_createobjectspage_q.ui0000644000175000017500000000262211733011756031454 0ustar sylvestresylvestre ND_CreateObjectsPage_q 0 0 624 513 WizardPage Adding new objects to library ... Qt::AlignTop true Qt::Horizontal Qt::Vertical QSizePolicy::Expanding 20 439 fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_CreateObjectsPage.h0000644000175000017500000000275511733011756030515 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_CREATEOBJECTSPAGE_H_ #define __ND_CREATEOBJECTSPAGE_H_ #include "ui_nd_createobjectspage_q.h" namespace libfwbuilder { class InterfaceData; class FWObject; }; class ND_CreateObjectsPage : public QWizardPage { Q_OBJECT; Ui::ND_CreateObjectsPage_q *m_dialog; libfwbuilder::FWObject* addInterface(libfwbuilder::FWObject *parent, libfwbuilder::InterfaceData *in, bool skip_ip_address_check); public: ND_CreateObjectsPage(QWidget *parent); virtual ~ND_CreateObjectsPage() {} virtual void initializePage(); public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/SNMPCrawlerThread.h0000644000175000017500000000410611733011756030037 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _SNMPCRAWLERTHREAD_H_ #define _SNMPCRAWLERTHREAD_H_ #include "../../config.h" #include #include #include #include #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/ThreadTools.h" #ifdef HAVE_LIBSNMP // avoid #include "snmp.h" since it conflicts with Qt, see #2185 namespace libfwbuilder { class SNMPCrawler; class SyncFlag; class CrawlerFind; }; class SNMPCrawlerThread : public QThread { Q_OBJECT; libfwbuilder::SNMPCrawler *q; libfwbuilder::SyncFlag *stop_flag; QWidget *ui; public: SNMPCrawlerThread(QWidget *ui, const QString &seedHost, const QString &community, bool recursive, bool followP2P, int snmpRetries, int snmpTimeout, const std::vector *include); virtual ~SNMPCrawlerThread(); void run(); void stop(); std::map getAllIPs(); std::set getNetworks(); signals: void finished(); }; #endif #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_progresspage_q.ui0000644000175000017500000000360411733011756030504 0ustar sylvestresylvestre ND_ProgressPage_q 0 0 609 537 WizardPage Process log: 0 true Stop Save scan log to file Qt::Horizontal QSizePolicy::Expanding 141 20 stop() saveLog() fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_chooseobjectspage_q.ui0000644000175000017500000000147311733011756031474 0ustar sylvestresylvestre ND_ChooseObjectsPage_q 0 0 599 514 WizardPage ObjectSelectorWidget QWidget
ObjectSelectorWidget.h
1
fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ChooseObjectsPage.cpp0000644000175000017500000000434211733011756031057 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "ND_ChooseObjectsPage.h" #include "SNMPNetworkDiscoveryWizard.h" #include #include using namespace std; using namespace libfwbuilder; ND_ChooseObjectsPage::ND_ChooseObjectsPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_ChooseObjectsPage_q; m_dialog->setupUi(this); registerField("objectsToUse*", m_dialog->objectSelector, "objectsToUse", SIGNAL(selectionChanged())); } void ND_ChooseObjectsPage::initializePage() { if (fwbdebug) qDebug() << "ND_ChooseObjectsPage::initializePage()"; ObjectDescriptorList *objects = dynamic_cast(wizard())->getObjects(); m_dialog->objectSelector->init(*objects); /* list objects; fill objects with data and call m_dialog->objectSelector->init(objects); */ } bool ND_ChooseObjectsPage::validatePage() { if (fwbdebug) qDebug() << "ND_ChooseObjectsPage::validatePage()"; QStringList *objectsToUse = dynamic_cast(wizard())->getObjectsToUse(); *objectsToUse = m_dialog->objectSelector->getObjectsToUse(); return true; } bool ND_ChooseObjectsPage::isComplete() const { if (fwbdebug) qDebug() << "ChooseObjectsPage::isComplete()"; return (m_dialog->objectSelector->count() > 0); } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_selectlibrarypage_q.ui0000644000175000017500000000356711733011756031514 0ustar sylvestresylvestre ND_SelectLibraryPage_q 0 0 559 452 WizardPage Select target library 6 0 0 Qt::Horizontal QSizePolicy::Expanding 71 20 Qt::Vertical QSizePolicy::Expanding 20 364 fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ChooseObjectTypePage.h0000644000175000017500000000273011733011756031202 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_CHOOSEOBJECTTYPEPAGE_H_ #define __ND_CHOOSEOBJECTTYPEPAGE_H_ #include "ui_nd_chooseobjecttypepage_q.h" #include "ObjectDescriptor.h" class ND_ChooseObjectTypePage : public QWizardPage { Q_OBJECT; Ui::ND_ChooseObjectTypePage_q *m_dialog; ObjectDescriptorList *objects; QStringList *objectsToUse; public: ND_ChooseObjectTypePage(QWidget *parent); virtual ~ND_ChooseObjectTypePage() {} virtual void initializePage(); void fillTypeChangingList(); void changeTargetObject(const QString &buf); public slots: void typeAddress(); void typeHost(); void typeFirewall(); }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_SetupPage.cpp0000644000175000017500000001631711733011756027432 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "FWBSettings.h" #include "ND_SetupPage.h" #include "fwbuilder/InetAddr.h" #include #include using namespace std; using namespace libfwbuilder; #define DISCOVERY_DRUID_PREFIX "DiscoveryDruid/" #define DISCOVERY_DRUID_SEEDHOST "SeedHost" #define DISCOVERY_DRUID_SNMPINADDR "SNMPInAddr" #define DISCOVERY_DRUID_SNMPINMASK "SNMPInMask" ND_SetupPage::ND_SetupPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_SetupPage_q; m_dialog->setupUi(this); hideProgressBar(); displayStatusNeutral(""); dns_op_id = -1; seedHostOK = false; limitScanConfigurationOK = true; m_dialog->seedHostName->setText(st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SEEDHOST)); m_dialog->snmpInAddr->setText(st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINADDR)); m_dialog->snmpInMask->setText(st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINMASK)); registerField("seedHostName*", m_dialog->seedHostName); registerField("snmpInAddr", m_dialog->snmpInAddr); registerField("snmpInMask", m_dialog->snmpInMask); } ND_SetupPage::~ND_SetupPage() {} void ND_SetupPage::initializePage() { if (fwbdebug) qDebug() << "ND_SetupPage::initializePage()"; } bool ND_SetupPage::validatePage() { st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SEEDHOST, m_dialog->seedHostName->text()); st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINADDR, m_dialog->snmpInAddr->text()); st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINMASK, m_dialog->snmpInMask->text()); return true; } bool ND_SetupPage::isComplete() const { return seedHostOK && limitScanConfigurationOK; } bool ND_SetupPage::isSeedHostOK(const QString &hostName) { if (hostName.isEmpty()) return false; QRegExp r = QRegExp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$", Qt::CaseInsensitive); //non wildcard last_error = ""; if (r.exactMatch(hostName)) { try { InetAddr(hostName.toLatin1().constData()); return true; } catch(const FWException &ex) { last_error = ex.toString().c_str(); return false; } } else { last_error = tr("Wrong IPv4 format"); return false; } } bool ND_SetupPage::looksLikeIpAddress(const QString &s) { QRegExp r=QRegExp("^(\\d|\\.)+$",Qt::CaseInsensitive); //non wildcard return r.exactMatch(s); } void ND_SetupPage::displayStatusError(const QString &err) { QPalette palette = m_dialog->seedHostErrorMessage->palette(); palette.setColor( m_dialog->seedHostErrorMessage->foregroundRole(), Qt::darkRed); m_dialog->seedHostErrorMessage->setPalette(palette); m_dialog->seedHostErrorMessage->setText(err); } void ND_SetupPage::displayStatusSuccess(const QString &err) { QPalette palette = m_dialog->seedHostErrorMessage->palette(); palette.setColor( m_dialog->seedHostErrorMessage->foregroundRole(), Qt::darkGreen); m_dialog->seedHostErrorMessage->setPalette(palette); m_dialog->seedHostErrorMessage->setText(err); } void ND_SetupPage::displayStatusNeutral(const QString &err) { QPalette palette = m_dialog->seedHostErrorMessage->palette(); palette.setColor( m_dialog->seedHostErrorMessage->foregroundRole(), Qt::black); m_dialog->seedHostErrorMessage->setPalette(palette); m_dialog->seedHostErrorMessage->setText(err); } void ND_SetupPage::showProgressBar() { m_dialog->DNSProgressBar->show(); } void ND_SetupPage::hideProgressBar() { m_dialog->DNSProgressBar->hide(); } void ND_SetupPage::changedSeedHost() { m_dialog->seedHostErrorMessage->setText(" "); hideProgressBar(); QString hostName = m_dialog->seedHostName->text(); if (dns_op_id > -1) { QHostInfo::abortHostLookup(dns_op_id); dns_op_id = -1; } if (hostName.isEmpty()) { displayStatusError(tr("Enter a valid host name or address.")); } else { if (looksLikeIpAddress(hostName)) { // seems to be an IP Address seedHostOK = isSeedHostOK(hostName); if (seedHostOK) displayStatusSuccess(tr("Address successfully verified")); else displayStatusError(last_error); } else { // it looks like a DNS name displayStatusNeutral(tr("DNS resolution in progress...")); showProgressBar(); dns_op_id = QHostInfo::lookupHost(hostName, this, SLOT(dnsFinish(QHostInfo))); } } emit completeChanged(); } void ND_SetupPage::dnsFinish(const QHostInfo &host) { dns_op_id = -1; QList list = host.addresses(); hideProgressBar(); //get the test result if (list.isEmpty()) { displayStatusError(tr( "host name not found")); seedHostOK = false; } else { displayStatusSuccess(tr("host name verified")); seedHostOK = true; } emit completeChanged(); } void ND_SetupPage::changedLimitScanConfiguraton() { m_dialog->limitScanError->setText(" "); if (m_dialog->snmpInAddr->text().isEmpty() && m_dialog->snmpInMask->text().isEmpty()) { m_dialog->limitScanError->setText(" "); limitScanConfigurationOK = true; emit completeChanged(); return; } if ( ! m_dialog->snmpInAddr->text().isEmpty() && ! m_dialog->snmpInMask->text().isEmpty()) { try { InetAddr a(m_dialog->snmpInAddr->text().toLatin1().constData()); InetAddr n(m_dialog->snmpInMask->text().toLatin1().constData()); InetAddrMask(a, n); m_dialog->limitScanError->setText(" "); limitScanConfigurationOK = true; } catch (const FWException &ex) { m_dialog->limitScanError->setText(ex.toString().c_str()); limitScanConfigurationOK = false; } } else { m_dialog->limitScanError->setText(tr("Incomplete network address / netmask")); limitScanConfigurationOK = false; } emit completeChanged(); } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ChooseObjectTypePage.cpp0000644000175000017500000000616611733011756031544 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "ND_ChooseObjectTypePage.h" #include "SNMPNetworkDiscoveryWizard.h" #include using namespace std; using namespace libfwbuilder; ND_ChooseObjectTypePage::ND_ChooseObjectTypePage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_ChooseObjectTypePage_q; m_dialog->setupUi(this); } void ND_ChooseObjectTypePage::initializePage() { if (fwbdebug) qDebug() << "ND_ChooseObjectTypePage::initializePage()"; objects = dynamic_cast(wizard())->getObjects(); objectsToUse = dynamic_cast(wizard())->getObjectsToUse(); fillTypeChangingList(); } void ND_ChooseObjectTypePage::fillTypeChangingList() { m_dialog->typeChangingList->clear(); qDebug() << objectsToUse; int idx = 0; foreach(ObjectDescriptor od, *objects) { if (objectsToUse->contains(QString::fromUtf8(od.sysname.c_str()))) { QString ins; ins = (od.interfaces.size()) ? QString("%1").arg(od.interfaces.size()) : ""; QStringList sl; sl << QString::fromUtf8(od.toString().c_str()) << ins << od.type.c_str(); QTreeWidgetItem *itm = new QTreeWidgetItem( m_dialog->typeChangingList, sl ); itm->setData(0, Qt::UserRole, idx); } idx++; } m_dialog->typeChangingList->resizeColumnToContents(0); m_dialog->typeChangingList->resizeColumnToContents(1); } void ND_ChooseObjectTypePage::typeAddress() { changeTargetObject(IPv4::TYPENAME); } void ND_ChooseObjectTypePage::typeHost() { changeTargetObject(Host::TYPENAME); } void ND_ChooseObjectTypePage::typeFirewall() { changeTargetObject(Firewall::TYPENAME); } void ND_ChooseObjectTypePage::changeTargetObject(const QString &buf) { QTreeWidgetItem* item = m_dialog->typeChangingList->topLevelItem(0); while (item!=0) { if (item->isSelected()) { int idx = item->data(0, Qt::UserRole).toInt(); (*objects)[idx].type = buf.toStdString(); item->setText(2, buf); } item = m_dialog->typeChangingList->topLevelItem( m_dialog->typeChangingList->indexOfTopLevelItem(item)+1); } } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_choosenetworkspage_q.ui0000644000175000017500000000147511733011756031721 0ustar sylvestresylvestre ND_ChooseNetworksPage_q 0 0 574 560 WizardPage ObjectSelectorWidget QWidget
ObjectSelectorWidget.h
1
fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_CreateObjectsPage.cpp0000644000175000017500000003436211733011756031047 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "events.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "platforms.h" #include "ND_CreateObjectsPage.h" #include "SNMPNetworkDiscoveryWizard.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/Resources.h" #include "fwbuilder/InterfaceData.h" #include "fwbuilder/Firewall.h" #include #include #include #include using namespace std; using namespace libfwbuilder; ND_CreateObjectsPage::ND_CreateObjectsPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_CreateObjectsPage_q; m_dialog->setupUi(this); } void ND_CreateObjectsPage::initializePage() { if (fwbdebug) qDebug() << "ND_CreateObjectsPage::initializePage()"; ObjectDescriptorList *objects = dynamic_cast(wizard())->getObjects(); QStringList *objectsToUse = dynamic_cast(wizard())->getObjectsToUse(); ObjectDescriptorList *networks = dynamic_cast(wizard())->getNetworks(); int lib_index = field("libIndex").toInt(); QStringList libraries = field("libraries").toStringList(); if (fwbdebug) qDebug() << "libraries=" << libraries; m_dialog->progressBar->setFormat("%v / %m"); m_dialog->progressBar->setMaximum(objectsToUse->size() / 2 + networks->size()); FWObject *last_object = NULL; string type, name, a; int counter = 0; foreach(ObjectDescriptor od, *networks) { type = od.type; // Network or NetworkIPv6 name = od.sysname; a = od.addr.toString().c_str(); Address *net = Address::cast( mw->createObject(type.c_str(), name.c_str())); assert(net!=NULL); net->setName(name); net->setAddress(od.addr); net->setNetmask(od.netmask); mw->moveObject(libraries[lib_index], net); last_object = net; m_dialog->progressBar->setValue(counter); qApp->processEvents(); counter++; } foreach(ObjectDescriptor od, *objects) { if (objectsToUse->contains(QString::fromUtf8(od.sysname.c_str()))) { type = od.type; name = od.sysname; QString platform; QString os; QString version; guessOSAndPlatformFromSysDescr(od.descr.c_str(), platform, os, version); a = od.addr.toString(); if (type==Host::TYPENAME || type==Firewall::TYPENAME) { FWObject *o=NULL; o = mw->createObject(type.c_str(), name.c_str()); o->setName(name); if (type==Firewall::TYPENAME) { if (os == "linux") { o->setStr("platform", "iptables"); o->setStr("host_OS", "linux24"); } if (os == "freebsd") { o->setStr("platform", "pf"); o->setStr("host_OS", "freebsd"); } if (os == "openbsd") { o->setStr("platform", "pf"); o->setStr("host_OS", "openbsd"); } if (os == "ios") { o->setStr("platform", "iosacl"); o->setStr("host_OS", "ios"); } if (os == "pix" || os == "fwsm") { o->setStr("platform", "pix"); o->setStr("host_OS", "pix_os"); } if (os == "apple") { o->setStr("platform", "ipfw"); o->setStr("host_OS", "macosx"); } if (os == "solaris") { o->setStr("platform", "ipf"); o->setStr("host_OS", "solaris"); } Resources::setDefaultTargetOptions( o->getStr("platform"), Firewall::cast(o) ); Resources::setDefaultTargetOptions( o->getStr("host_OS"), Firewall::cast(o) ); } if (od.interfaces.size()==0) { Interface *itf= Interface::cast( mw->createObject(o,Interface::TYPENAME,"nic1") ); if (od.addr.isV4()) { IPv4 *ipv4= IPv4::cast( mw->createObject(itf, IPv4::TYPENAME, a.c_str()) ); ipv4->setAddress(od.addr); ipv4->setNetmask(InetAddr()); } if (od.addr.isV6()) { IPv6 *ipv6 = IPv6::cast( mw->createObject(itf, IPv6::TYPENAME, a.c_str()) ); ipv6->setAddress(od.addr); ipv6->setNetmask(InetAddr()); } } else { if (fwbdebug) { map::iterator i; for (i=od.interfaces.begin(); i!=od.interfaces.end(); ++i) { InterfaceData *intf = &(i->second); QString str("Discovered interface %1: %2"); qDebug() << str.arg(intf->name.c_str()).arg(intf->mac_addr.c_str()); } } list interface_tree; std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(o)); int_prop->rearrangeInterfaces(od.interfaces, interface_tree); if (interface_tree.size() != od.interfaces.size()) { // Some interfaces have been converted to subinterfaces // Show warning QMessageBox::warning( this, "Firewall Builder", tr( "Some discovered interfaces have been rearranged in " "fwbuilder objects and recreated as subinterfaces to " "reflect VLANs, bonding and bridging configurations. " "The algorithm used to guess correct relationship " "between interfaces and subinterfaces is imperfect " "because of the limited information provided by SNMP " "daemon. Pelase review created objects to make sure " "generated configuration is accurate. " "\n" "\n" "The program expects MAC addresses of bonding, bridge " "and vlan interfaces to be the same. It is especially " "important to review and fix generated objects if you " "use MAC address spoofing." ), tr("&Continue"), 0, 0, 0 ); } list::iterator it; for (it=interface_tree.begin(); it!=interface_tree.end(); ++it) { InterfaceData *in = *it; // if this interface has subinterfaces, add even if it // has no ip address (last arg) FWObject *intf = addInterface( o, in, in->subinterfaces.size()!=0); if (intf == NULL) continue; list::iterator sit; for (sit=in->subinterfaces.begin(); sit!=in->subinterfaces.end(); ++sit) { InterfaceData *subint = *sit; addInterface(intf, subint, true); } } } if (!od.descr.empty()) { FWOptions* opt=(dynamic_cast(o))->getOptionsObject(); opt->setStr("snmp_description",od.descr); opt->setStr("snmp_location", od.location); opt->setStr("snmp_contact", od.contact); } mw->moveObject(libraries[lib_index], o); } else if (type==Network::TYPENAME) { Network *net=dynamic_cast( mw->createObject(type.c_str(),name.c_str()) ); assert(net!=NULL); net->setName(name); net->setAddress(InetAddr(a)); net->setNetmask(InetAddr(InetAddr(a))); mw->moveObject(libraries[lib_index], net); } else if (type==IPv4::TYPENAME) { IPv4 *obj=dynamic_cast( mw->createObject(type.c_str(),name.c_str()) ); assert(obj!=NULL); obj->setName(name); obj->setAddress(InetAddr(a)); obj->setNetmask(InetAddr(InetAddr::getAllOnes())); mw->moveObject(libraries[lib_index], obj); } m_dialog->progressBar->setValue(counter); qApp->processEvents(); counter++; } } ProjectPanel *pp = mw->activeProject(); QString filename = pp->getFileName(); QCoreApplication::postEvent(mw, new reloadObjectTreeEvent(filename)); QCoreApplication::postEvent( mw->activeProject(), new openLibraryForObjectEvent( filename, last_object->getId())); } FWObject* ND_CreateObjectsPage::addInterface(FWObject *parent, InterfaceData *in, bool skip_ip_address_check) { ObjectManipulator *om = mw->activeProject()->m_panel->om; bool includeUnnumbered = field("snmpIncludeUnnumbered").toBool(); if ( ! includeUnnumbered && ! skip_ip_address_check) { if (in->addr_mask.size()==0) return NULL; if (in->addr_mask.front()->getAddressPtr()->isAny()) return NULL; } QString obj_name = in->name.c_str(); Interface *itf = NULL; itf = Interface::cast( mw->createObject(parent, QString(Interface::TYPENAME), obj_name)); QString iname = om->getStandardName(itf, physAddress::TYPENAME, "mac"); iname = om->makeNameUnique(itf, iname, physAddress::TYPENAME); physAddress *paddr = physAddress::cast( mw->createObject(itf, physAddress::TYPENAME, iname) ); paddr->setPhysAddress(in->mac_addr); itf->setLabel(in->label); itf->setSecurityLevel(in->securityLevel); if (fwbdebug) qDebug() << "Interface=" << obj_name << "type=" << in->interface_type.c_str(); if (!in->interface_type.empty()) { itf->getOptionsObject()->setStr("type", in->interface_type); if (in->interface_type == "8021q") itf->getOptionsObject()->setInt("vlan_id", in->vlan_id); } else { std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(parent)); if (int_prop->looksLikeVlanInterface(obj_name)) { QString base_name; int vlan_id; int_prop->parseVlan(obj_name, &base_name, &vlan_id); itf->getOptionsObject()->setStr("type", "8021q"); itf->getOptionsObject()->setInt("vlan_id", vlan_id); } } if (in->addr_mask.size()==0 || in->addr_mask.front()->getAddressPtr()->isAny()) { itf->setUnnumbered(true); } else { list::iterator n; for (n=in->addr_mask.begin(); n!=in->addr_mask.end(); ++n) { const InetAddr *addr = (*n)->getAddressPtr(); const InetAddr *netm = (*n)->getNetmaskPtr(); if (addr->isV4()) { try { QString iname = om->getStandardName(itf, IPv4::TYPENAME, "ip"); iname = om->makeNameUnique(itf, iname, IPv4::TYPENAME); IPv4 *ipv4= IPv4::cast( om->createObject(itf, IPv4::TYPENAME, iname) ); ipv4->setAddress(*addr); ipv4->setNetmask(*netm); } catch (FWException &ex) { cerr << "FWException: " << ex.toString() << endl; } } if (addr->isV6()) { try { QString iname = om->getStandardName(itf, IPv6::TYPENAME, "ip"); iname = om->makeNameUnique(itf, iname, IPv6::TYPENAME); IPv6 *ipv6 = IPv6::cast( om->createObject(itf, IPv6::TYPENAME, iname) ); ipv6->setAddress(*addr); ipv6->setNetmask(*netm); } catch (FWException &ex) { cerr << "FWException: " << ex.toString() << endl; } } } } return itf; } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_chooseobjecttypepage_q.ui0000644000175000017500000000767211733011756032222 0ustar sylvestresylvestre ND_ChooseObjectTypePage_q 0 0 578 519 WizardPage Change type of selected objects: 6 Address Host Firewall Here you can change type of the objects to be created for each address discovered by the scanner. By default, an "Address" object is created for the host with just one interface with single IP address and "Host" object is created for the host with multiple interfaces, however you can change their types on this page. Qt::AlignVCenter true QAbstractItemView::ExtendedSelection true Object Interfaces Type addresTypeButton clicked() ND_ChooseObjectTypePage_q typeAddress() 104 487 288 259 hostTypeButton clicked() ND_ChooseObjectTypePage_q typeHost() 288 487 288 259 firewallTypeButton clicked() ND_ChooseObjectTypePage_q typeFirewall() 472 487 288 259 typeAddress() typeHost() typeFirewall() fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_SelectLibraryPage.h0000644000175000017500000000264011733011756030535 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SELECTLIBRARYPAGE_H_ #define __SELECTLIBRARYPAGE_H_ #include "ui_nd_selectlibrarypage_q.h" class ND_SelectLibraryPage : public QWizardPage { Q_OBJECT; Ui::ND_SelectLibraryPage_q *m_dialog; QStringList libraries; Q_PROPERTY(QStringList libraries READ getLibraries WRITE setLibraries); public: ND_SelectLibraryPage(QWidget *parent); virtual ~ND_SelectLibraryPage() {} virtual void initializePage(); QStringList getLibraries() { return libraries; } void setLibraries(const QStringList &l) { libraries = l; } public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/SNMPNetworkDiscoveryWizard.cpp0000644000175000017500000000461711733011756032354 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "SNMPNetworkDiscoveryWizard.h" #include "ND_ChooseNetworksPage.h" #include "ND_ChooseObjectsPage.h" #include "ND_ChooseObjectTypePage.h" #include "ND_CreateObjectsPage.h" #include "ND_DiscoveryParametersPage.h" #include "ND_ProgressPage.h" #include "ND_SelectLibraryPage.h" #include "ND_SetupPage.h" #include "ND_SNMPParametersPage.h" #include "FWWindow.h" #include #include using namespace std; //using namespace libfwbuilder; SNMPNetworkDiscoveryWizard::SNMPNetworkDiscoveryWizard(QWidget *parent) : QWizard(parent) { QPixmap pm; pm.load(":/Images/fwbuilder3-72x72.png"); setPixmap(QWizard::LogoPixmap, pm); setWindowTitle(tr("Discover addresses and subnets using SNMP")); addPage(new ND_SetupPage(this)); addPage(new ND_DiscoveryParametersPage(this)); addPage(new ND_SNMPParametersPage(this)); addPage(new ND_ProgressPage(this)); addPage(new ND_ChooseNetworksPage(this)); addPage(new ND_ChooseObjectsPage(this)); addPage(new ND_ChooseObjectTypePage(this)); addPage(new ND_SelectLibraryPage(this)); addPage(new ND_CreateObjectsPage(this)); QRect sg = QApplication::desktop()->screenGeometry(mw); QSize screen_size = sg.size(); #if defined(Q_OS_MACX) QSize desired_size(900, 700); #else QSize desired_size(800, 700); #endif if (desired_size.width() > screen_size.width()) desired_size.setWidth(screen_size.width()); if (desired_size.height() > screen_size.height()) desired_size.setHeight(screen_size.height()); resize(desired_size); } fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_DiscoveryParametersPage.h0000644000175000017500000000242011733011756031760 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_DISCOVERYPARAMETERSPAGE_H_ #define __ND_DISCOVERYPARAMETERSPAGE_H_ #include "ui_nd_discoveryparameterspage_q.h" class ND_DiscoveryParametersPage : public QWizardPage { Q_OBJECT; Ui::ND_DiscoveryParametersPage_q *m_dialog; public: ND_DiscoveryParametersPage(QWidget *parent); virtual ~ND_DiscoveryParametersPage() {} virtual void initializePage(); virtual bool validatePage(); public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/nd_discoveryparameterspage_q.ui0000644000175000017500000001073711733011756032740 0ustar sylvestresylvestre ND_DiscoveryParametersPage_q 0 0 627 583 WizardPage The scanner process can repeat its algorithm recursively using each new host it finds as a new "seed". This allows it to find as many objects on your network as possible. On the other hand, it takes more time and may find some objects you do not really need. You can turn recursive scanning on below: Qt::AlignVCenter true Run network scan recursively QFrame::HLine QFrame::Sunken Qt::Horizontal The scanner process can find nodes beyond the boundaries of your network by following point-to-point links connecting it to the Internet or other parts of WAN. Qt::AlignVCenter true Follow point-to-point links QFrame::HLine QFrame::Sunken Qt::Horizontal The scanner process normally ignores interfaces that have no IP addresses; checking this option makes it create such interfaces as "Unnumbered" Qt::AlignVCenter true Include interfaces with no ip addresses QFrame::HLine QFrame::Sunken Qt::Horizontal Analysis of ARP table yields IP addresses for hosts on your network. In order to determine their names, scanner can run reverse name lookup queries using your name servers (DNS): Qt::AlignVCenter true Run reverse name lookup DNS queries to determine host names false fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_ChooseObjectsPage.h0000644000175000017500000000237511733011756030530 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ND_CHOOSEOBJECTSPAGE_H_ #define __ND_CHOOSEOBJECTSPAGE_H_ #include "ui_nd_chooseobjectspage_q.h" class ND_ChooseObjectsPage : public QWizardPage { Q_OBJECT; Ui::ND_ChooseObjectsPage_q *m_dialog; public: ND_ChooseObjectsPage(QWidget *parent); virtual ~ND_ChooseObjectsPage() {} virtual void initializePage(); virtual bool validatePage(); virtual bool isComplete() const; }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/SNMPNetworkDiscoveryWizard.h0000644000175000017500000000270311733011756032013 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SNMPNETWORKDISCOVERYWIZARD_H_ #define __SNMPNETWORKDISCOVERYWIZARD_H_ #include "ObjectDescriptor.h" #include class SNMPNetworkDiscoveryWizard : public QWizard { Q_OBJECT; ObjectDescriptorList networks; ObjectDescriptorList objects; QStringList objectsToUse; public: SNMPNetworkDiscoveryWizard(QWidget *parent); virtual ~SNMPNetworkDiscoveryWizard() {} ObjectDescriptorList* getNetworks() { return &networks; } ObjectDescriptorList* getObjects() { return &objects; } QStringList* getObjectsToUse() { return &objectsToUse; } public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/snmpNetworkDiscoveryWizard/ND_DiscoveryParametersPage.cpp0000644000175000017500000000605011733011756032316 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "FWBSettings.h" #include "ND_DiscoveryParametersPage.h" #include using namespace std; //using namespace libfwbuilder; #define DISCOVERY_DRUID_PREFIX "DiscoveryDruid/" #define DISCOVERY_DRUID_SNMPRECURSIVE "SNMPRecursive" #define DISCOVERY_DRUID_SNMPFOLLOWP2P "SNMPFollowP2P" #define DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED "SnmpIncludeUnnumbered" #define DISCOVERY_DRUID_SNMPDODNS "SNMPDoDNS" ND_DiscoveryParametersPage::ND_DiscoveryParametersPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ND_DiscoveryParametersPage_q; m_dialog->setupUi(this); m_dialog->snmpRecursive->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRECURSIVE)); m_dialog->snmpFollowP2P->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPFOLLOWP2P)); m_dialog->snmpIncludeUnnumbered->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED)); m_dialog->snmpDoDNS->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDODNS)); registerField("snmpRecursive", m_dialog->snmpRecursive); registerField("snmpFollowP2P", m_dialog->snmpFollowP2P); registerField("snmpIncludeUnnumbered", m_dialog->snmpIncludeUnnumbered); registerField("snmpDoDNS", m_dialog->snmpDoDNS); } void ND_DiscoveryParametersPage::initializePage() { if (fwbdebug) qDebug() << "ND_DiscoveryParametersPage::initializePage()"; } bool ND_DiscoveryParametersPage::validatePage() { st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRECURSIVE, m_dialog->snmpRecursive->isChecked()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPFOLLOWP2P, m_dialog->snmpFollowP2P->isChecked()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED, m_dialog->snmpIncludeUnnumbered->isChecked()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDODNS, m_dialog->snmpDoDNS->isChecked()); return true; } fwbuilder-5.1.0.3599/src/libgui/memcheck.h0000644000175000017500000003175011733011756020773 0ustar sylvestresylvestre /* ---------------------------------------------------------------- Notice that the following BSD-style license applies to this one file (memcheck.h) only. The rest of Valgrind is licensed under the terms of the GNU General Public License, version 2, unless otherwise indicated. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- This file is part of MemCheck, a heavyweight Valgrind tool for detecting memory errors. Copyright (C) 2000-2008 Julian Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------- Notice that the above BSD-style license applies to this one file (memcheck.h) only. The entire rest of Valgrind is licensed under the terms of the GNU General Public License, version 2. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- */ #ifndef __MEMCHECK_H #define __MEMCHECK_H /* This file is for inclusion into client (your!) code. You can use these macros to manipulate and query memory permissions inside your own programs. See comment near the top of valgrind.h on how to use them. */ #include "valgrind.h" /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! This enum comprises an ABI exported by Valgrind to programs which use client requests. DO NOT CHANGE THE ORDER OF THESE ENTRIES, NOR DELETE ANY -- add new ones at the end. */ typedef enum { VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'), VG_USERREQ__MAKE_MEM_UNDEFINED, VG_USERREQ__MAKE_MEM_DEFINED, VG_USERREQ__DISCARD, VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE, VG_USERREQ__CHECK_MEM_IS_DEFINED, VG_USERREQ__DO_LEAK_CHECK, VG_USERREQ__COUNT_LEAKS, VG_USERREQ__GET_VBITS, VG_USERREQ__SET_VBITS, VG_USERREQ__CREATE_BLOCK, VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, /* This is just for memcheck's internal use - don't use it */ _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR = VG_USERREQ_TOOL_BASE('M','C') + 256 } Vg_MemCheckClientRequest; /* Client-code macros to manipulate the state of memory. */ /* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_NOACCESS, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Similarly, mark memory at _qzz_addr as addressable but undefined for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_UNDEFINED, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Similarly, mark memory at _qzz_addr as addressable and defined for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_DEFINED, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is not altered: bytes which are addressable are marked as defined, but those which are not addressable are left unchanged. */ #define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Create a block-description handle. The description is an ascii string which is included in any messages pertaining to addresses within the specified memory range. Has no other effect on the properties of the memory range. */ #define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__CREATE_BLOCK, \ _qzz_addr, _qzz_len, _qzz_desc, \ 0, 0); \ _qzz_res; \ })) /* Discard a block-description-handle. Returns 1 for an invalid handle, 0 for a valid handle. */ #define VALGRIND_DISCARD(_qzz_blkindex) \ (__extension__ ({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ VG_USERREQ__DISCARD, \ 0, _qzz_blkindex, 0, 0, 0); \ _qzz_res; \ })) /* Client-code macros to check the state of memory. */ /* Check that memory at _qzz_addr is addressable for _qzz_len bytes. If suitable addressibility is not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Check that memory at _qzz_addr is addressable and defined for _qzz_len bytes. If suitable addressibility and definedness are not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \ (__extension__({unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__CHECK_MEM_IS_DEFINED, \ _qzz_addr, _qzz_len, 0, 0, 0); \ _qzz_res; \ })) /* Use this macro to force the definedness and addressibility of an lvalue to be checked. If suitable addressibility and definedness are not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \ VALGRIND_CHECK_MEM_IS_DEFINED( \ (volatile unsigned char *)&(__lvalue), \ (unsigned long)(sizeof (__lvalue))) /* Do a memory leak check mid-execution. */ #define VALGRIND_DO_LEAK_CHECK \ {unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DO_LEAK_CHECK, \ 0, 0, 0, 0, 0); \ } /* Just display summaries of leaked memory, rather than all the details */ #define VALGRIND_DO_QUICK_LEAK_CHECK \ {unsigned long _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DO_LEAK_CHECK, \ 1, 0, 0, 0, 0); \ } /* Return number of leaked, dubious, reachable and suppressed bytes found by all previous leak checks. They must be lvalues. */ #define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \ /* For safety on 64-bit platforms we assign the results to private unsigned long variables, then assign these to the lvalues the user specified, which works no matter what type 'leaked', 'dubious', etc are. We also initialise '_qzz_leaked', etc because VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as initialised. */ \ {unsigned long _qzz_res; \ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__COUNT_LEAKS, \ &_qzz_leaked, &_qzz_dubious, \ &_qzz_reachable, &_qzz_suppressed, 0); \ leaked = _qzz_leaked; \ dubious = _qzz_dubious; \ reachable = _qzz_reachable; \ suppressed = _qzz_suppressed; \ } /* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it into the provided zzvbits array. Return values: 0 if not running on valgrind 1 success 2 [previously indicated unaligned arrays; these are now allowed] 3 if any parts of zzsrc/zzvbits are not addressable. The metadata is not copied in cases 0, 2 or 3 so it should be impossible to segfault your system by using this call. */ #define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \ (__extension__({unsigned long _qzz_res; \ char* czza = (char*)zza; \ char* czzvbits = (char*)zzvbits; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__GET_VBITS, \ czza, czzvbits, zznbytes, 0, 0 ); \ _qzz_res; \ })) /* Set the validity data for addresses [zza..zza+zznbytes-1], copying it from the provided zzvbits array. Return values: 0 if not running on valgrind 1 success 2 [previously indicated unaligned arrays; these are now allowed] 3 if any parts of zza/zzvbits are not addressable. The metadata is not copied in cases 0, 2 or 3 so it should be impossible to segfault your system by using this call. */ #define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \ (__extension__({unsigned int _qzz_res; \ char* czza = (char*)zza; \ char* czzvbits = (char*)zzvbits; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__SET_VBITS, \ czza, czzvbits, zznbytes, 0, 0 ); \ _qzz_res; \ })) #endif fwbuilder-5.1.0.3599/src/libgui/CompilerOutputPanel.cpp0000644000175000017500000001455211733011756023526 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "CompilerOutputPanel.h" #include "FWBSettings.h" #include "ObjectManipulator.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "CompilerDriverFactory.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwcompiler/BaseCompiler.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; CompilerOutputPanel::CompilerOutputPanel(QWidget *parent) : BaseObjectDialog(parent) { m_widget = new Ui::CompilerOutputPanel_q; m_widget->setupUi(this); } CompilerOutputPanel::~CompilerOutputPanel() { delete m_widget; } void CompilerOutputPanel::changed() { emit changed_sign(); } void CompilerOutputPanel::applyChanges() { } void CompilerOutputPanel::loadFWObject(FWObject *obj) { if (fwbdebug) qDebug("CompilerOutputPanel::loadFWObject obj id=%s", FWObjectDatabase::getStringId(obj->getId()).c_str()); m_widget->compiler_output_panel->clear(); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); list err_re; BaseCompiler::errorRegExp(&err_re); foreach(string re, err_re) { error_re.push_back(QRegExp(re.c_str())); } list warn_re; BaseCompiler::warningRegExp(&warn_re); foreach(string re, warn_re) { warning_re.push_back(QRegExp(re.c_str())); } QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); mw->showStatusBarMessage(tr("Compiling rule...") ); FWObject *p = obj; // use Firewall::cast to match both Firewall and Cluster while (!Firewall::cast(p)) p = p->getParent(); Firewall *fw = Firewall::cast(p); Rule *rule = Rule::cast(obj); CompilerDriver *dr = CompilerDriverFactory::createCompilerDriver(fw); QTextCharFormat format; QTextCharFormat normal_format; QTextCharFormat bold_format; QTextCharFormat error_format; QTextCharFormat warning_format; QTextCursor cursor(m_widget->compiler_output_panel->textCursor()); format = cursor.charFormat(); format.setFont(st->getCompilerOutputFont()); normal_format = format; normal_format.setForeground(QBrush(Qt::black)); bold_format = format; bold_format.setProperty(QTextFormat::FontWeight, 99); bold_format.setForeground(QBrush(Qt::black)); error_format = format; error_format.setForeground(QBrush(Qt::red)); error_format.setProperty(QTextFormat::FontWeight, 99); warning_format = format; warning_format.setForeground(QBrush(Qt::blue)); warning_format.setProperty(QTextFormat::FontWeight, 99); //m_widget->compiler_output_panel->clear(); if (dr == NULL) { // we have no compiler for this platform or unknown platform format = error_format; cursor.insertText( QObject::tr("Compiler for firewall platform %1 not found") .arg(fw->getStr("platform").c_str()), format); cursor.insertText("\n"); cursor.insertBlock(); return; } // run in test mode to prevent fatal errors from causing exit dr->setTestMode(); if (fwbdebug) dr->setDebugRule(rule->getPosition()); else dr->setEmbeddedMode(); try { QMapIterator it( dr->compileSingleRule(FWObjectDatabase::getStringId(rule->getId()))); QTextCursor cursor = m_widget->compiler_output_panel->textCursor(); while (it.hasNext()) { it.next(); QString dbg; if (fwbdebug) dbg = QString("(id: %1)").arg( FWObjectDatabase::getStringId(rule->getId()).c_str()); QString title("%1 / %2 / rule %3 %4\n"); cursor.insertText(title .arg(it.key()) .arg(rule->getParent()->getName().c_str()) .arg(rule->getPosition()) .arg(dbg), bold_format); foreach (QString line, it.value().trimmed().split("\n")) { format = normal_format; list::const_iterator it; for (it=error_re.begin(); it!=error_re.end(); ++it) { if ((*it).indexIn(line) != -1) { format = error_format; break; } } for (it=warning_re.begin(); it!=warning_re.end(); ++it) { if ((*it).indexIn(line) != -1) { format = warning_format; break; } } cursor.insertText(line + "\n", format); } cursor.insertText("\n"); cursor.insertBlock(); } } catch (FWException &e) { m_widget->compiler_output_panel->append(e.toString().c_str()); m_widget->compiler_output_panel->append("\n"); } QApplication::restoreOverrideCursor(); delete dr; } void CompilerOutputPanel::validate(bool* b ) { *b=true; } void CompilerOutputPanel::closeEvent(QCloseEvent *) { } void CompilerOutputPanel::resizeEvent ( QResizeEvent * /*UNUSED event */ ) { this->m_widget->compiler_output_panel->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); this->m_widget->compiler_output_panel->setVerticalScrollBar(new QScrollBar()); this->m_widget->compiler_output_panel->verticalScrollBar()->show(); } fwbuilder-5.1.0.3599/src/libgui/ObjectListViewItem.cpp0000644000175000017500000000535111733011756023264 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ObjectListViewItem.h" #include "fwbuilder/TCPUDPService.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include using namespace libfwbuilder; bool ObjectListViewItem::operator< ( const QTreeWidgetItem & other ) const { QTreeWidget * widget = treeWidget() ; if (widget==NULL) return false; int col = widget->sortColumn (); if (col==1) { FWObject *right = ((ObjectListViewItem*)(&other))->getFWObject(); FWObject *left = this->getFWObject(); TCPUDPService * rtcpudp = TCPUDPService::cast(right); TCPUDPService * ltcpudp = TCPUDPService::cast(left); IPService * rip = IPService::cast(right); IPService * lip = IPService::cast(left); ICMPService * ricmp = ICMPService::cast(right); ICMPService * licmp = ICMPService::cast(left); if (rtcpudp != NULL && ltcpudp != NULL) { int ls = ltcpudp->getDstRangeStart(); int rs = rtcpudp->getDstRangeStart(); if (lsgetDstRangeEnd(); int re = rtcpudp->getDstRangeEnd(); if (legetProtocolNumber(); int rpn = rip->getProtocolNumber(); return (lpn < rpn); } if (ricmp != NULL && licmp != NULL) { int lpn = licmp->getInt("code"); int rpn = ricmp->getInt("code"); return (lpn < rpn); } } return QTreeWidgetItem::operator < (other); } fwbuilder-5.1.0.3599/src/libgui/debugDialog.h0000644000175000017500000000222511733011756021420 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DEBUGDIALOG_H_ #define __DEBUGDIALOG_H_ #include "config.h" #include #include class debugDialog : public QDialog { Q_OBJECT Ui::debugDialog_q *m_dialog; public: debugDialog(QWidget *parent); ~debugDialog(); }; #endif // __DEBUGDIALOG_H fwbuilder-5.1.0.3599/src/libgui/linux24ifaceoptsdialog_q.ui0000644000175000017500000002727711733011756024321 0ustar sylvestresylvestre linux24IfaceOptsDialog_q 0 0 418 322 Linux: interface settings Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 :/Icons/Options:/Icons/Options Options Qt::Vertical QSizePolicy::Fixed 20 16 Qt::RightToLeft Device Type Qt::Horizontal 40 20 0 0 2 true Qt::RightToLeft VLAN ID 4095 Qt::Horizontal 140 20 Qt::Vertical 20 43 Enable STP Qt::Vertical 20 173 Bonding policy: balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb Xmit hash policy: layer2 layer3+4 Other parameters: Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() linux24IfaceOptsDialog_q accept() 316 472 20 20 buttonCancel clicked() linux24IfaceOptsDialog_q reject() 397 472 20 20 buttonHelp clicked() linux24IfaceOptsDialog_q help() 68 464 231 245 iface_type currentIndexChanged(QString) linux24IfaceOptsDialog_q typeChanged(QString) 287 196 286 261 bonding_policy currentIndexChanged(QString) linux24IfaceOptsDialog_q bondingPolicyChanged(QString) 268 126 208 160 typeChanged(QString) bondingPolicyChanged(QString) fwbuilder-5.1.0.3599/src/libgui/ProjectPanel_state_ops.cpp0000644000175000017500000002373411733011756024224 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com refactoring and bugfixes: vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "ProjectPanel.h" #include "FWBSettings.h" #include "RCS.h" #include "RuleSetView.h" #include "ObjectTreeView.h" #include #include #include #include "fwbuilder/Library.h" #include "fwbuilder/RuleSet.h" using namespace Ui; using namespace libfwbuilder; using namespace std; void ProjectPanel::saveState() { QString file_name ; if (rcs!=NULL) file_name = rcs->getFileName(); if (fwbdebug) qDebug( ) << "ProjectPanel::saveState " << this << "title " << mdiWindow->windowTitle() << "file_name=" << file_name << "ready=" << ready; if (!ready) return; st->setInt("Window/" + file_name + "/x", mdiWindow->x()); st->setInt("Window/" + file_name + "/y", mdiWindow->y()); st->setInt("Window/" + file_name + "/width", mdiWindow->width ()); st->setInt("Window/" + file_name + "/height", mdiWindow->height ()); saveMainSplitter(); m_panel->om->saveExpandedTreeItems(); m_panel->om->saveSectionSizes(); if (fwbdebug) qDebug() << "ProjectPanel::saveState " << "rcs=" << rcs << "getCurrentRuleSetView()=" << getCurrentRuleSetView(); saveLastOpenedLib(); if (getCurrentRuleSetView()) saveOpenedRuleSet(); if (fwbdebug) qDebug("ProjectPanel::saveState() done"); } void ProjectPanel::loadState(bool) { if (rcs==NULL) return; QString filename = rcs->getFileName(); // This function can end up being called recursively because some // of the operations it performs trigger various events such as // "visibility changed" or "show". if (loading_state) return; loading_state = true; if (fwbdebug) { qDebug() << QString("ProjectPanel::loadState filename=%1 isMaximized=%2") .arg(filename).arg(mdiWindow->isMaximized()); qDebug() << "mdiWindow=" << mdiWindow; qDebug() << QString("ready=%1").arg(ready); } if (!ready) return; if (!mdiWindow->isMaximized() && mdiWindow) { if (fwbdebug) qDebug("ProjectPanel::loadState show normal"); setWindowState(0); int x = st->getInt("Window/"+filename+"/x"); int y = st->getInt("Window/"+filename+"/y"); int width = st->getInt("Window/"+filename+"/width"); int height = st->getInt("Window/"+filename+"/height"); if (width==0 || height==0) { x = 10; y = 10; width = 600; height= 600; } if (fwbdebug) qDebug("ProjectPanel::loadState set geometry: %d %d %d %d", x,y,width,height); mdiWindow->setGeometry(x,y,width,height); } loadMainSplitter(); m_panel->om->loadExpandedTreeItems(); m_panel->om->loadSectionSizes(); loadLastOpenedLib(); loadOpenedRuleSet(); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug() << QString("ProjectPanel::loadState filename=%1 DONE dirty=%2 last_modified=%3") .arg(filename).arg(db()->isDirty()).arg(ctime(&last_modified)); loading_state = false; } void ProjectPanel::saveMainSplitter() { QString fileName ; if (rcs!=NULL) fileName = rcs->getFileName(); #ifdef TREE_IS_DOCKABLE // Save position of splitters regardless of the window state // Do not save if one of tree panel is floating if (!m_panel->treeDockWidget->isWindow()) { QList sl = m_panel->topSplitter->sizes(); QString arg = QString("%1,%2").arg(sl[0]).arg(sl[1]); if (sl[0] || sl[1]) st->setStr("Window/" + fileName + "/MainWindowSplitter", arg ); if (fwbdebug) { QString out1 = " save Window/" + fileName + "/MainWindowSplitter"; out1+= " " + arg; qDebug() << out1; } } #else QList sl = m_panel->topSplitter->sizes(); QString arg = QString("%1,%2").arg(sl[0]).arg(sl[1]); if (sl[0] || sl[1]) st->setStr("Window/" + fileName + "/MainWindowSplitter", arg ); if (fwbdebug) { QString out1 = " save Window/" + fileName + "/MainWindowSplitter"; out1+= " " + arg; qDebug() << out1; } #endif } void ProjectPanel::loadMainSplitter() { QString fileName ; if (rcs!=NULL) fileName = rcs->getFileName(); if (fwbdebug) qDebug() << QString("ProjectPanel::loadMainSplitter() filename=%1") .arg(fileName); QString h_splitter_setting = "Window/" + fileName + "/MainWindowSplitter"; QString val = st->getStr(h_splitter_setting); int w1 = 0; int w2 = 0; QStringList ws = val.split(','); bool ok = false; w1 = ws[0].toInt(&ok, 10); if (!ok || w1 == 0) w1 = DEFAULT_H_SPLITTER_POSITION; if (ws.size() > 1) { w2 = ws[1].toInt(&ok, 10); if (!ok || w2 == 0) w2 = mdiWindow->width() - w1; } else w2 = mdiWindow->width() - w1; if (fwbdebug) qDebug() << h_splitter_setting << ":" << w1 << "x" << w2; setMainSplitterPosition(w1, w2); } void ProjectPanel::setMainSplitterPosition(int w1, int w2) { if (w1 && w2) { QList sl; sl.push_back(w1); sl.push_back(w2); if (fwbdebug) qDebug("Setting main splitter position: %d,%d", w1, w2); m_panel->topSplitter->setSizes( sl ); } } void ProjectPanel::collapseTree() { QList sl; sl.push_back(0); sl.push_back(mdiWindow->width()); m_panel->topSplitter->setSizes( sl ); } void ProjectPanel::collapseRules() { QList sl; sl.push_back(mdiWindow->width()); sl.push_back(0); m_panel->topSplitter->setSizes( sl ); } void ProjectPanel::loadOpenedRuleSet() { if (rcs==NULL) return; QString filename = rcs->getFileName(); if (m_panel->om->getCurrentLib() == NULL) return; int id = st->getVisibleRuleSetId( filename, m_panel->om->getCurrentLib()->getName().c_str()); if (id > 0) { FWObject *obj = db()->getById(id, true); if (obj) { m_panel->om->openObjectInTree(obj); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::loadOpenedRuleSet(): checkpoint 1: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); openRuleSet(obj); last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::loadOpenedRuleSet(): checkpoint 2: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); } } } void ProjectPanel::saveOpenedRuleSet() { if (rcs==NULL) return; QString filename = rcs->getFileName(); if (visibleRuleSet!=NULL) { st->setVisibleRuleSet(filename, visibleRuleSet->getLibrary()->getName().c_str(), visibleRuleSet); getCurrentRuleSetView()->saveCollapsedGroups(); } } void ProjectPanel::saveLastOpenedLib() { QString filename = ""; if (rcs!=NULL) filename = rcs->getFileName(); FWObject* obj = m_panel->om->getCurrentLib(); if (obj!=NULL) { std::string sid = FWObjectDatabase::getStringId(obj->getId()); st->setStr("Window/" + filename + "/LastLib", sid.c_str() ); } } void ProjectPanel::loadLastOpenedLib() { if (fwbdebug) qDebug("ProjectPanel::loadLastOpenedLib()"); QString filename = ""; if (rcs!=NULL) filename = rcs->getFileName(); QString sid = st->getStr("Window/" + filename + "/LastLib"); if (filename!="" && sid!="") { if (fwbdebug) qDebug("ProjectPanel::loadLastOpenedLib(): filename=%s " "opening lib id=%s", filename.toAscii().constData(), sid.toAscii().constData()); int last_lib_id = FWObjectDatabase::getIntId(sid.toStdString()); if (last_lib_id > 0 && last_lib_id != FWObjectDatabase::DELETED_OBJECTS_ID) { m_panel->om->libChangedById(last_lib_id); m_panel->om->getCurrentObjectTree()->setFocus(Qt::OtherFocusReason); return; } } loadFirstNonStandardLib(); m_panel->om->getCurrentObjectTree()->setFocus(Qt::OtherFocusReason); } void ProjectPanel::loadFirstNonStandardLib() { list all_libs = db()->getByType(Library::TYPENAME); FWObject *first_non_system_lib = NULL; for (list::iterator i=all_libs.begin(); i!=all_libs.end(); ++i) { int lib_id = (*i)->getId(); if (lib_id == FWObjectDatabase::DELETED_OBJECTS_ID) continue; if (lib_id == FWObjectDatabase::STANDARD_LIB_ID) continue; if (lib_id == FWObjectDatabase::TEMPLATE_LIB_ID) continue; if (first_non_system_lib==NULL) first_non_system_lib = (*i); if ((*i)->getName()=="User") { first_non_system_lib = *i; break; } } if (first_non_system_lib) m_panel->om->libChangedById(first_non_system_lib->getId()); } fwbuilder-5.1.0.3599/src/libgui/IPv6Dialog.cpp0000644000175000017500000001774011733011756021461 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "IPv6Dialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" using namespace std; using namespace libfwbuilder; IPv6Dialog::IPv6Dialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::IPv6Dialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } IPv6Dialog::~IPv6Dialog() { delete m_dialog; } void IPv6Dialog::loadFWObject(FWObject *o) { obj=o; IPv6 *s = dynamic_cast(obj); assert(s!=NULL); dnsBusy=false; init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); /* * if this is an address that belongs to an interface, we can't move * it from library to library just like that. Only IPv4 objects that * belong to the standard group "Addresses" can be moved. */ if ( Interface::isA( obj->getParent() ) ) { showNetmask=true; m_dialog->netmaskLabel->show(); m_dialog->netmask->show(); } else { showNetmask=false; m_dialog->netmaskLabel->hide(); m_dialog->netmask->hide(); } /* catch exceptions separately so even if we have a bad address, we * still can show netmask */ try { m_dialog->address->setText(InetAddr(AF_INET6, 0).toString().c_str() ); const InetAddr *inet_addr = s->getAddressPtr(); m_dialog->address->setText( inet_addr->toString().c_str()); } catch (FWException &ex) {} try { if ( Interface::isA( obj->getParent() ) ) m_dialog->netmask->setText( QString("%1").arg( s->getNetmaskPtr()->getLength()) ); } catch (FWException &ex) {} //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->address->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->address); m_dialog->netmask->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->netmask); init=false; } void IPv6Dialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } IPv6 *s = dynamic_cast(obj); assert(s!=NULL); try { InetAddr(AF_INET6, m_dialog->address->text().trimmed().toLatin1().constData() ); } catch (FWException &ex) { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical(this, "Firewall Builder", tr("Illegal IP address '%1'").arg(m_dialog->address->text()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } if ( showNetmask ) { try { bool ok = false; InetAddr(AF_INET6, m_dialog->netmask->text().trimmed().toInt(&ok)); if (!ok) throw FWException(""); } catch (FWException &ex) { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical(this, "Firewall Builder", tr("Illegal netmask '%1'").arg(m_dialog->netmask->text()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } } } void IPv6Dialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); IPv6 *s = dynamic_cast(new_state); assert(s!=NULL); string oldname=obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); try { s->setAddress( InetAddr(AF_INET6, m_dialog->address->text().trimmed().toLatin1().constData()) ); } catch (FWException &ex) { } if ( showNetmask ) { try { bool ok = false; s->setNetmask( InetAddr(AF_INET6, m_dialog->netmask->text().trimmed().toInt(&ok)) ); if (!ok) throw FWException(""); } catch (FWException &ex) { } } else s->setNetmask(InetAddr(AF_INET6, 0)); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void IPv6Dialog::DNSlookup() { if (fwbdebug) qDebug("IPv6Dialog::DNSlookup() dnsBusy=%d", dnsBusy); if (!dnsBusy) { QString name = m_dialog->obj_name->text().trimmed(); if (fwbdebug) qDebug("IPv6Dialog::DNSlookup() name=%s", name.toAscii().constData()); dnsBusy=true; QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString addr = getAddrByName(name, AF_INET6); QApplication::restoreOverrideCursor(); dnsBusy=false; if (fwbdebug) qDebug("IPv6Dialog::DNSlookup() done"); if (! addr.isEmpty()) { m_dialog->address->setText( addr ); changed(); return; } if ( Interface::isA(obj->getParent()) ) { FWObject *host = obj->getParent()->getParent(); assert(host!=NULL); name = host->getName().c_str(); if (fwbdebug) qDebug("IPv6Dialog::DNSlookup() name=%s", name.toAscii().constData()); dnsBusy=true; QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString addr = getAddrByName(name, AF_INET6); QApplication::restoreOverrideCursor(); dnsBusy=false; if (fwbdebug) qDebug("IPv6Dialog::DNSlookup() done"); if ( ! addr.isEmpty()) { m_dialog->address->setText( addr ); changed(); return; } QMessageBox::warning( this,"Firewall Builder", tr("DNS lookup failed for both names of the address object '%1' and the name of the host '%2'.") .arg(m_dialog->obj_name->text()).arg(name), "&Continue", QString::null,QString::null, 0, 1 ); return; } QMessageBox::warning( this,"Firewall Builder", tr("DNS lookup failed for name of the address object '%1'.") .arg(name), "&Continue", QString::null,QString::null, 0, 1 ); return; } } fwbuilder-5.1.0.3599/src/libgui/newFirewallDialog.cpp0000644000175000017500000011705011733011756023147 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003-2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include "newFirewallDialog.h" #include "ObjConflictResolutionDialog.h" #include "upgradePredicate.h" #include "FWBSettings.h" #include "FWBTree.h" #include "events.h" #include "FWBApplication.h" #include "QDesktopWidget" #include "networkZoneManager.h" #include "ObjConflictResolutionDialog.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/BackgroundOp.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // must be the last for win #include "fwbuilder/snmp.h" using namespace libfwbuilder; using namespace std; #define NAME_AND_PLATFORM_PAGE 0 #define INTERFACES_MANUAL_OR_SNMP 1 #define CONFIGURE_INTERFACES_MANUALLY 2 #define CONFIGURE_SECURITY_LEVELS 3 #define CONFIGURE_NETWORK_ZONES 4 #define CHOOSE_FW_TEMPLATE 5 #define CONFIGURE_TEMPLATE_INTERFACES_MANUALLY 6 newFirewallDialog::newFirewallDialog(QWidget *parentw, FWObject *_p) : QDialog(parentw) { db_orig = _p->getRoot(); db_copy = new FWObjectDatabase(); db_copy->duplicate(db_orig, false); parent = db_copy->getById(_p->getId(), true); m_dialog = new Ui::newFirewallDialog_q; m_dialog->setupUi(this); possible_inside_interface_labels.push_back("inside"); possible_inside_interface_labels.push_back("GREEN"); possible_inside_interface_labels.push_back("green"); possible_outside_interface_labels.push_back("outside"); possible_outside_interface_labels.push_back("RED"); possible_outside_interface_labels.push_back("red"); possible_dmz_interface_labels.push_back("dmz"); possible_dmz_interface_labels.push_back("ORANGE"); possible_dmz_interface_labels.push_back("orange"); setControlWidgets(this, m_dialog->stackedWidget, m_dialog->nextButton, m_dialog->finishButton, m_dialog->backButton, m_dialog->cancelButton, m_dialog->titleLabel); nfw = NULL; tmpldb = NULL; snmpPollCompleted = false; q = NULL; unloadTemplatesLib = false; getInterfacesBusy = false; timer = new QTimer(this); connect( timer, SIGNAL(timeout()), this, SLOT(monitor())); connect( m_dialog->selectCustomTemplateLib, SIGNAL(pressed()), this, SLOT(browseTemplate())); connect( m_dialog->useStandard, SIGNAL(toggled(bool)), this, SLOT(updateTemplatePanel())); connect( m_dialog->useTemplate, SIGNAL(released()), this, SLOT(updateTemplatePanel())); m_dialog->useStandard->setChecked(true); m_dialog->templateFilePath->setText( Constants::getTemplatesObjectsFilePath().c_str()); updateTemplatePanel(); /* fill in platform. Since iptables is the most popular, start with * it. */ QString new_fw_platform = st->getNewFirewallPlatform(); /* if new_fw_platform is empty, the drop-down list will have empty * item which will be current. This is so only on the first run of * the program because it remembers chosen platform and uses it on * subsequent runs. */ setPlatform(m_dialog->platform, new_fw_platform); /* fill in host OS */ setHostOS(m_dialog->hostOS, readPlatform(m_dialog->platform), ""); setNextEnabled( NAME_AND_PLATFORM_PAGE, false ); //m_dialog->iface_sl_list->setAllColumnsShowFocus( true ); QTimer::singleShot(0, m_dialog->obj_name, SLOT(setFocus())); currentTemplate = NULL; this->m_dialog->interfaceEditor1->clear(); this->m_dialog->interfaceEditor2->clear(); this->m_dialog->interfaceEditor1->closeTab(); this->m_dialog->interfaceEditor2->closeTab();//->removeTab(0); this->m_dialog->interfaceEditor1->setExplanation( tr("Interfaces with the type set to 'Dynamic IP address' get " "IP address by means of DHCP or PPP protocol and do not " "require an address here. Interfaces with the type set to " "'Static IP address' have statically configured IP address " "which should be entered on this page. Interface can have " "several IPv4 and IPv6 addresses.") ); this->m_dialog->interfaceEditor2->setExplanation( tr("Here you can change IP address of the template interface " "to match addresses used on your network. " "Interface can have several IPv4 and " "IPv6 addresses.") ); this->resize(this->width(), this->minimumHeight()); int maxheight = (int)(app->desktop()->height()*0.9); if (this->height() > maxheight) this->resize(this->width(), maxheight); showPage(NAME_AND_PLATFORM_PAGE); } void newFirewallDialog::browseTemplate() { QString fileName = QFileDialog::getOpenFileName( this, tr("FWBuilder template files"), st->getOpenFileDir(), tr("FWBuilder template files (*.xml *.fwb *.fwl)")); if (fileName.isEmpty()) return; st->setOpenFileDir(fileName); m_dialog->templateFilePath->setText(fileName); updateTemplatePanel(); } void newFirewallDialog::useStandardTemplate() { m_dialog->templateFilePath->setText( Constants::getTemplatesObjectsFilePath().c_str()); updateTemplatePanel(); } void newFirewallDialog::updateTemplatePanel() { if (st->customTemplatesEnabled() && m_dialog->useTemplate->checkState()==Qt::Checked) { QString fileName = m_dialog->templateFilePath->text(); bool using_std = m_dialog->useStandard->isChecked(); m_dialog->templateGroupBox->setVisible(true); m_dialog->templateFilePathLabel->setVisible(true); m_dialog->templateFilePath->setVisible(true); m_dialog->templateLibExplanation->setVisible(true); m_dialog->templateFilePath->setEnabled(!using_std); m_dialog->selectCustomTemplateLib->setEnabled(!using_std); if (using_std) { m_dialog->templateFilePath->setText( Constants::getTemplatesObjectsFilePath().c_str()); } } else { m_dialog->templateGroupBox->setVisible(false); } } newFirewallDialog::~newFirewallDialog() { delete m_dialog; if (timer!=NULL) delete timer; #ifdef HAVE_LIBSNMP if (q!=NULL) delete q; #endif delete db_copy; } void newFirewallDialog::changed() { int p = currentPage(); if (fwbdebug) qDebug() << "newFirewallDialog::changed() page=" << p << "use_manual=" << m_dialog->use_manual->isChecked() << "use_snmp=" << m_dialog->use_snmp->isChecked(); if (p==NAME_AND_PLATFORM_PAGE) { setNextEnabled(p, !m_dialog->obj_name->text().isEmpty() && !readPlatform(m_dialog->platform).isEmpty() ); setHostOS(m_dialog->hostOS, readPlatform(m_dialog->platform), ""); QString host_os = readHostOS(m_dialog->hostOS); m_dialog->interfaceEditor1->setHostOS(host_os); m_dialog->interfaceEditor2->setHostOS(host_os); } if (p==INTERFACES_MANUAL_OR_SNMP) { bool use_snmp = false; #ifdef HAVE_LIBSNMP use_snmp = m_dialog->use_snmp->isChecked(); #else use_snmp = false; m_dialog->use_snmp->setEnabled( use_snmp ); #endif m_dialog->snmpIP->setEnabled( use_snmp ); m_dialog->snmp_community->setEnabled( use_snmp ); m_dialog->snmpQuery->setEnabled( use_snmp ); m_dialog->snmpProgress->setEnabled( use_snmp ); if ( use_snmp ) m_dialog->snmp_community->setFocus(); if (use_snmp) { getIPAddressOfFirewallByName(); } use_snmp = m_dialog->use_manual->isChecked() || snmpPollCompleted; setNextEnabled( 1, use_snmp ); } if (fwbdebug) qDebug() << "newFirewallDialog::changed() done"; } void newFirewallDialog::getIPAddressOfFirewallByName() { getInterfacesBusy = true; m_dialog->snmpIP->setText(""); QString name = m_dialog->obj_name->text().toLatin1().constData(); QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString addr = getAddrByName(name, AF_INET); QApplication::restoreOverrideCursor(); if (!addr.isEmpty()) m_dialog->snmpIP->setText(addr); else { QMessageBox::warning( this,"Firewall Builder", tr("Address of %1 could not be obtained via DNS") .arg(m_dialog->obj_name->text()), "&Continue", QString::null, QString::null, 0, 1 ); } getInterfacesBusy = false; } void newFirewallDialog::monitor() { if (logger==NULL || q==NULL) return; #ifdef HAVE_LIBSNMP if( logger->ready() ) { QString str = logger->getLine().c_str(); m_dialog->snmpProgress->moveCursor( QTextCursor::End ); m_dialog->snmpProgress->insertPlainText( str ); return; } if (q->isRunning()) return; timer->stop(); QString platform = readPlatform(m_dialog->platform); guessOSAndPlatformFromSysDescr(q->getDescr().c_str(), discovered_platform, discovered_host_os, discovered_version); if (fwbdebug) qDebug() << "Guessed version as " << discovered_version; map* intf = q->getInterfaces(); map::iterator i; this->m_dialog->interfaceEditor1->clear(); this->m_dialog->interfaceEditor1->removeTab(0); for (i=intf->begin(); i!=intf->end(); ++i) { InterfaceData* idata = &(i->second); if (fwbdebug) { qDebug() << "------------------------------------------------"; qDebug() << "id=" << idata->id.c_str(); qDebug() << "name=" << idata->name.c_str(); qDebug() << "snmp_type=" << idata->snmp_type; qDebug() << "ostatus=" << idata->ostatus; qDebug() << "mac_addr=" << idata->mac_addr.c_str(); qDebug() << "interface_type=" << idata->interface_type.c_str(); qDebug() << ""; } /* * some special treatment of discovered interfaces for Cisco ASA devices: * if mac address is reported as 00:00:00:00:00:00 or * 00:00:00:anything, this is usually some kind of internal special * interface and we can skip it. Examples: "_internal_loopback", * "Internal-Data0/1" * * This is different from how Linux reports mac address of a * loopback because Linux snmpd returns empty string for the * loopback mac address. * * The name of the interface reported by ASA is like this: * "Adaptive Security Appliance 'Ethernet0/0' interface" * * Need to strip all thie verbose description */ if (idata->ostatus) { guessInterfaceLabel(idata); if (platform == "pix" || platform == "fwsm") { if ( ! idata->mac_addr.empty() && idata->snmp_type == 1 && idata->mac_addr.find("00:00:00")==0) continue; QString name = idata->name.c_str(); name.replace("Adaptive Security Appliance '", ""); name.replace("Cisco PIX Security Appliance '", ""); name.replace("PIX Firewall '", ""); name.replace("' interface", ""); idata->name = name.toStdString(); } this->m_dialog->interfaceEditor1->addInterfaceFromData(idata); } } if ( this->m_dialog->interfaceEditor1->count() == 0 ) this->m_dialog->interfaceEditor1->addNewInterface(); delete q; q=NULL; #endif snmpPollCompleted=true; setNextEnabled( INTERFACES_MANUAL_OR_SNMP, true ); } void newFirewallDialog::getInterfacesViaSNMP() { #ifdef HAVE_LIBSNMP // need to protect from reentry because getAddrByName processes events if (q!=NULL || getInterfacesBusy) return; snmpPollCompleted=false; m_dialog->interfaceEditor1->clear(); string rcomm=m_dialog->snmp_community->text().toLatin1().constData(); if ( rcomm.empty() ) { QMessageBox::warning( this,"Firewall Builder", tr("Missing SNMP community string."), "&Continue", QString::null, QString::null, 0, 1 ); return ; } getInterfacesBusy = true; InetAddr addr; try { addr = InetAddr(m_dialog->snmpIP->text().toStdString()); } catch (FWException &ex) { try { QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString a = getAddrByName(m_dialog->snmpIP->text(), AF_INET); QApplication::restoreOverrideCursor(); addr = InetAddr(a.toAscii().constData()); getInterfacesBusy = false; } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", tr("Address of %1 could not be obtained via DNS") .arg(m_dialog->snmpIP->text()), "&Continue", QString::null, QString::null, 0, 1 ); getInterfacesBusy = false; return ; } } logger = NULL; m_dialog->snmpProgress->clear(); if (q!=NULL) delete q; q = new SNMP_interface_query(); q->init(addr.toString(), rcomm, SNMP_DEFAULT_RETRIES, SNMP_DEFAULT_TIMEOUT); timer->setSingleShot(false); timer->start(0); try { logger = q->start_operation(); } catch(const FWException &ex) { //do nothing } getInterfacesBusy = false; #endif } bool interfaceCompare(libfwbuilder::Interface *first, libfwbuilder::Interface *second) { return first->getName() < second->getName(); } bool newFirewallDialog::appropriate(const int page) const { switch (page) { case NAME_AND_PLATFORM_PAGE: case CHOOSE_FW_TEMPLATE: return true; case INTERFACES_MANUAL_OR_SNMP: case CONFIGURE_INTERFACES_MANUALLY: case CONFIGURE_SECURITY_LEVELS: case CONFIGURE_NETWORK_ZONES: return (!m_dialog->useTemplate->isChecked()); } return true; } void newFirewallDialog::nextClicked() { if ( currentPage() == CHOOSE_FW_TEMPLATE ) { if (m_dialog->templateList->currentItem() == NULL) { QMessageBox::warning( this,"Firewall Builder", tr("Please select template"), tr("&Continue"), QString::null,QString::null, 0, 1 ); showPage(CHOOSE_FW_TEMPLATE); return; } } if ( currentPage() == CONFIGURE_INTERFACES_MANUALLY ) if ( !this->m_dialog->interfaceEditor1->isValid() ) return; // FakeWizard::nextRelevant() finds next (in the numerical order) // page that is permitted by function appropriate() and returns // its number if (nextRelevant( currentPage() ) > -1) showPage(nextRelevant( currentPage() )); } void newFirewallDialog::backClicked() { if (previousRelevant( currentPage() ) > -1) showPage(previousRelevant( currentPage() )); } void newFirewallDialog::showPage(const int page) { FakeWizard::showPage(page); int p = page; if (fwbdebug) qDebug() << "newFirewallDialog::showPage page=" << page; // p is a page number _after_ it changed switch (p) { case NAME_AND_PLATFORM_PAGE: // we get here if user hits "Back" on page 4 (where they // choose template object) if (tmpldb!=NULL) { m_dialog->templateList->clear(); delete tmpldb; tmpldb = NULL; } m_dialog->nextButton->setDefault(true); m_dialog->obj_name->setFocus(); break; case INTERFACES_MANUAL_OR_SNMP: { // page 1 is where we choose to configure interfaces manually or via snmp m_dialog->snmpIP->setText(""); changed(); // to properly enable/disable widgets m_dialog->nextButton->setDefault(true); break; } case CONFIGURE_INTERFACES_MANUALLY: { if (!Resources::getTargetCapabilityBool( readPlatform(m_dialog->platform).toLatin1().constData(), "security_levels") ) { /* if chosen fw platform does not support security levels, * this is the last page */ setNextEnabled( CONFIGURE_INTERFACES_MANUALLY, false ); setFinishEnabled( CONFIGURE_INTERFACES_MANUALLY, true ); m_dialog->finishButton->setDefault(true); } break; } case CONFIGURE_SECURITY_LEVELS: { if (m_dialog->useTemplate->isChecked()) { showPage( NAME_AND_PLATFORM_PAGE ); return; } // Edit security levels fillInterfaceSLList(); setNextEnabled( CONFIGURE_SECURITY_LEVELS, true ); setFinishEnabled( CONFIGURE_SECURITY_LEVELS, false ); m_dialog->nextButton->setDefault(true); break; } case CONFIGURE_NETWORK_ZONES: { if (m_dialog->useTemplate->isChecked()) { showPage( NAME_AND_PLATFORM_PAGE ); return; } // Edit network zones fillInterfaceNZList(); setNextEnabled(CONFIGURE_NETWORK_ZONES, false ); setFinishEnabled(CONFIGURE_NETWORK_ZONES, true ); m_dialog->finishButton->setDefault(true); break; } case CHOOSE_FW_TEMPLATE: { // Show firewall templates setFinishEnabled( CHOOSE_FW_TEMPLATE, false ); setNextEnabled( CHOOSE_FW_TEMPLATE, true ); // load templates if not loaded if (tmpldb==NULL) { MessageBoxUpgradePredicate upgrade_predicate(this); tmpldb = new FWObjectDatabase(); tmpldb->setReadOnly( false ); try { tmpldb->load( m_dialog->templateFilePath->text().toAscii().data(), &upgrade_predicate, Constants::getDTDDirectory()); } catch (FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Error loading template library:\n%1") .arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); } } // nfw != NULL if user clicked Back on one of the subsequent // pages because we create firewall object when they click // Next on the page where they choose template ( see case // CONFIGURE_TEMPLATE_INTERFACES_MANUALLY below) if (nfw) { parent->remove(nfw, false); delete nfw; nfw = NULL; } list fl; FWObjectTypedChildIterator libiter = tmpldb->findByType(Library::TYPENAME); for ( ; libiter!=libiter.end(); ++libiter) findFirewalls(*libiter, fl, false); QString icn = ":/Icons/Firewall/icon-tree"; m_dialog->templateList->clear(); int n = 0; QListWidgetItem *first_template = NULL; for (list::iterator m=fl.begin(); m!=fl.end(); m++,n++) { FWObject *o = *m; /* Ticket #1492 requested the change to only show the user templates that match platform and host OS they choose on the first page of the wizard. Unfortunately this does not really work because most templates have platform and host OS set to "unknown". Either we have to maintain many almost identical templates to provide enough choices for all possible platforms, or we should not filter by platform. string platform = readPlatform(m_dialog->platform).toAscii().constData(); string host_os = readHostOS(m_dialog->hostOS).toAscii().constData(); if (o->getStr("platform") != platform || o->getStr("host_OS") != host_os) continue; */ QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } QListWidgetItem *twi = new QListWidgetItem; twi->setIcon( QIcon(pm) ); twi->setText( QString(o->getName().c_str()) ); m_dialog->templateList->addItem( twi ); templates[ m_dialog->templateList->item( m_dialog->templateList->count()-1 ) ] = o; if (first_template == NULL) first_template = twi; } m_dialog->templateList->setFocus(); m_dialog->templateList->setCurrentItem(first_template, QItemSelectionModel::SelectCurrent); m_dialog->finishButton->setDefault(false); m_dialog->nextButton->setDefault(true); break; } case CONFIGURE_TEMPLATE_INTERFACES_MANUALLY: { // Edit interfaces of the template object createFirewallFromTemplate(); setFinishEnabled( CONFIGURE_TEMPLATE_INTERFACES_MANUALLY, true ); this->m_dialog->interfaceEditor2->clear(); this->m_dialog->interfaceEditor2->closeTab();//->removeTab(0); this->m_dialog->interfaceEditor2->setCornerWidgetsVisible(false); QList interfaces; FWObjectTypedChildIterator intiter = nfw->findByType(Interface::TYPENAME); for ( ; intiter != intiter.end(); ++intiter ) interfaces.append(Interface::cast(*intiter)); sort(interfaces.begin(), interfaces.end(), interfaceCompare); foreach(Interface* intr, interfaces) m_dialog->interfaceEditor2->addInterface(intr); m_dialog->finishButton->setDefault(true); } } } void newFirewallDialog::getInterfaceDataFromInterfaceEditor( EditedInterfaceData &edata, InterfaceData &idata) { idata.name = edata.name.toStdString(); idata.label = edata.label.toStdString(); AddressInfo address; bool gotIPv4 = false; foreach(AddressInfo addr, edata.addresses.values()) { if (addr.ipv4) { address = addr; gotIPv4 = true; break; } } InetAddrMask *iam;// = new InetAddrMask(); if (edata.type == 0 && edata.addresses.size() != 0) { if (!gotIPv4) address = edata.addresses.values().first(); if ( address.ipv4 ) iam = new InetAddrMask( InetAddr(address.address.toStdString()), InetAddr(address.netmask.toStdString())); else { iam = new InetAddrMask( InetAddr(AF_INET6, address.address.toStdString()), InetAddr(AF_INET6, address.netmask.toStdString())); } idata.addr_mask.push_back(iam); } if (gotIPv4) { try { guessSecurityLevel( readPlatform(m_dialog->platform).toStdString(), &idata); } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", ex.toString().c_str(), "&Continue", QString::null, QString::null, 0, 1 ); showPage( CONFIGURE_INTERFACES_MANUALLY ); return; } } else idata.securityLevel = 0; } void newFirewallDialog::fillInterfaceSLList() { m_dialog->iface_sl_list->clear(); QStringList labels; labels << QObject::tr("Name") << QObject::tr("Label") << QObject::tr("Address") << QObject::tr("Security Level"); m_dialog->iface_sl_list->setHorizontalHeaderLabels(labels); int row = 0; foreach(EditedInterfaceData iface, this->m_dialog->interfaceEditor1->getData().values() + this->m_dialog->interfaceEditor1->getNewData()) { InterfaceData idata; getInterfaceDataFromInterfaceEditor(iface, idata); m_dialog->iface_sl_list->insertRow(row); QTableWidgetItem* itm; itm = new QTableWidgetItem(iface.name); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_sl_list->setItem(row, 0, itm); itm = new QTableWidgetItem(iface.label); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_sl_list->setItem(row, 1, itm); QString addr_str; if (iface.addresses.size() > 0) { AddressInfo addr = *(iface.addresses.begin()); addr_str = addr.address; } itm = new QTableWidgetItem(addr_str); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_sl_list->setItem(row, 2, itm); //itm = new QTableWidgetItem(QString::number(idata.securityLevel)); QSpinBox *widget = new QSpinBox(); widget->setMaximum(100); widget->setMinimum(0); widget->setValue(idata.securityLevel); m_dialog->iface_sl_list->setCellWidget(row, 3, widget); row++; } } void newFirewallDialog::fillInterfaceNZList() { m_dialog->iface_nz_list->clear(); QStringList labels; labels << QObject::tr("Name") << QObject::tr("Label") << QObject::tr("Address") << QObject::tr("Network Zone"); m_dialog->iface_nz_list->setHorizontalHeaderLabels(labels); NetworkZoneManager netzone_manager; netzone_manager.load(db_copy); int row = 0; foreach(EditedInterfaceData iface, this->m_dialog->interfaceEditor1->getData().values() + this->m_dialog->interfaceEditor1->getNewData()) { InterfaceData idata; getInterfaceDataFromInterfaceEditor(iface, idata); m_dialog->iface_nz_list->insertRow(row); QTableWidgetItem* itm; itm = new QTableWidgetItem(iface.name); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 0, itm); itm = new QTableWidgetItem(iface.label); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 1, itm); QString addr_str; if (iface.addresses.size() > 0) { AddressInfo addr = *(iface.addresses.begin()); addr_str = addr.address; } itm = new QTableWidgetItem(addr_str); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 2, itm); QComboBox *widget = new QComboBox(); netzone_manager.packComboBox(widget, -1); m_dialog->iface_nz_list->setCellWidget(row, 3, widget); row++; } m_dialog->iface_nz_list->resizeColumnToContents(3); } /* * this slot is connected to currentItemChanged signal of templateList * As a side effect, this slot is called when we clear templateList. */ void newFirewallDialog::templateSelected(QListWidgetItem *itm) { if (templates.size()==0) return; FWObject *o = templates[itm]; if (o==NULL) return; this->m_dialog->interfaceEditor2->setTemplate(o); currentTemplate = o; Firewall *fw = Firewall::cast(o); m_dialog->templateComment->clear(); QString s = QString("\n") + fw->getComment().c_str(); m_dialog->templateComment->append( s ); m_dialog->templateComment->scrollToAnchor("top"); bool haveOutside = false; bool haveInside = false; bool haveDMZ = false; list ll = fw->getByType(Interface::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { Interface *intf = Interface::cast( *i ); if (std::find(possible_outside_interface_labels.begin(), possible_outside_interface_labels.end(), intf->getLabel()) != possible_outside_interface_labels.end()) { haveOutside=true; m_dialog->intfOutsideLine->show(); m_dialog->intfOutsideText->show(); fillInterfaceData(intf,m_dialog->intfOutsideText); } if (std::find(possible_inside_interface_labels.begin(), possible_inside_interface_labels.end(), intf->getLabel()) != possible_inside_interface_labels.end()) { haveInside=true; m_dialog->intfInsideLine->show(); m_dialog->intfInsideText->show(); fillInterfaceData(intf,m_dialog->intfInsideText); } if (std::find(possible_dmz_interface_labels.begin(), possible_dmz_interface_labels.end(), intf->getLabel()) != possible_dmz_interface_labels.end()) { haveDMZ=true; m_dialog->intfDMZLine->show(); m_dialog->intfDMZText->show(); fillInterfaceData(intf,m_dialog->intfDMZText); } } if (!haveOutside) { m_dialog->intfOutsideLine->hide(); m_dialog->intfOutsideText->hide(); } if (!haveInside) { m_dialog->intfInsideLine->hide(); m_dialog->intfInsideText->hide(); } if (!haveDMZ) { m_dialog->intfDMZLine->hide(); m_dialog->intfDMZText->hide(); } } void newFirewallDialog::fillInterfaceData(Interface *intf, QTextBrowser *qte) { qte->clear(); QString s; s += "

* * @see antlr.CharQueue */ class ANTLR_API CharBuffer : public InputBuffer { public: /// Create a character buffer CharBuffer( ANTLR_USE_NAMESPACE(std)istream& input ); /// Get the next character from the stream int getChar(); protected: // character source ANTLR_USE_NAMESPACE(std)istream& input; private: // NOTE: Unimplemented CharBuffer(const CharBuffer& other); CharBuffer& operator=(const CharBuffer& other); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CharBuffer_hpp__ fwbuilder-5.1.0.3599/src/antlr/MismatchedCharException.hpp0000644000175000017500000000354711733011756024162 0ustar sylvestresylvestre#ifndef INC_MismatchedCharException_hpp__ #define INC_MismatchedCharException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class CharScanner; class ANTLR_API MismatchedCharException : public RecognitionException { public: // Types of chars #ifndef NO_STATIC_CONSTS static const int CHAR = 1; static const int NOT_CHAR = 2; static const int RANGE = 3; static const int NOT_RANGE = 4; static const int SET = 5; static const int NOT_SET = 6; #else enum { CHAR = 1, NOT_CHAR = 2, RANGE = 3, NOT_RANGE = 4, SET = 5, NOT_SET = 6 }; #endif public: // One of the above int mismatchType; // what was found on the input stream int foundChar; // For CHAR/NOT_CHAR and RANGE/NOT_RANGE int expecting; // For RANGE/NOT_RANGE (expecting is lower bound of range) int upper; // For SET/NOT_SET BitSet set; protected: // who knows...they may want to ask scanner questions CharScanner* scanner; public: MismatchedCharException(); // Expected range / not range MismatchedCharException( int c, int lower, int upper_, bool matchNot, CharScanner* scanner_ ); // Expected token / not token MismatchedCharException( int c, int expecting_, bool matchNot, CharScanner* scanner_ ); // Expected BitSet / not BitSet MismatchedCharException( int c, BitSet set_, bool matchNot, CharScanner* scanner_ ); ~MismatchedCharException() throw() {} /** * Returns a clean error message (no line number/column information) */ ANTLR_USE_NAMESPACE(std)string getMessage() const; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_MismatchedCharException_hpp__ fwbuilder-5.1.0.3599/src/antlr/ASTRefCount.hpp0000644000175000017500000000317711733011756021523 0ustar sylvestresylvestre#ifndef INC_ASTRefCount_hpp__ # define INC_ASTRefCount_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ # include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class AST; struct ANTLR_API ASTRef { AST* const ptr; unsigned int count; ASTRef(AST* p); ~ASTRef(); ASTRef* increment() { ++count; return this; } bool decrement() { return (--count==0); } static ASTRef* getRef(const AST* p); private: ASTRef( const ASTRef& ); ASTRef& operator=( const ASTRef& ); }; template class ANTLR_API ASTRefCount { private: ASTRef* ref; public: ASTRefCount(const AST* p=0) : ref(p ? ASTRef::getRef(p) : 0) { } ASTRefCount(const ASTRefCount& other) : ref(other.ref ? other.ref->increment() : 0) { } ~ASTRefCount() { if (ref && ref->decrement()) delete ref; } ASTRefCount& operator=(AST* other) { ASTRef* tmp = ASTRef::getRef(other); if (ref && ref->decrement()) delete ref; ref=tmp; return *this; } ASTRefCount& operator=(const ASTRefCount& other) { if( other.ref != ref ) { ASTRef* tmp = other.ref ? other.ref->increment() : 0; if (ref && ref->decrement()) delete ref; ref=tmp; } return *this; } operator T* () const { return ref ? static_cast(ref->ptr) : 0; } T* operator->() const { return ref ? static_cast(ref->ptr) : 0; } T* get() const { return ref ? static_cast(ref->ptr) : 0; } }; typedef ASTRefCount RefAST; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ASTRefCount_hpp__ fwbuilder-5.1.0.3599/src/antlr/MismatchedTokenException.cpp0000644000175000017500000001233511733011756024353 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/MismatchedTokenException.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif MismatchedTokenException::MismatchedTokenException() : RecognitionException("Mismatched Token: expecting any AST node","",-1,-1) , token(0) , node(nullASTptr) , tokenNames(0) , numTokens(0) { } // Expected range / not range MismatchedTokenException::MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefAST node_, int lower, int upper_, bool matchNot ) : RecognitionException("Mismatched Token","",-1,-1) , token(0) , node(node_) , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("")) ) , mismatchType(matchNot ? NOT_RANGE : RANGE) , expecting(lower) , upper(upper_) , tokenNames(tokenNames_) , numTokens(numTokens_) { } // Expected token / not token MismatchedTokenException::MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefAST node_, int expecting_, bool matchNot ) : RecognitionException("Mismatched Token","",-1,-1) , token(0) , node(node_) , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("")) ) , mismatchType(matchNot ? NOT_TOKEN : TOKEN) , expecting(expecting_) , tokenNames(tokenNames_) , numTokens(numTokens_) { } // Expected BitSet / not BitSet MismatchedTokenException::MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefAST node_, BitSet set_, bool matchNot ) : RecognitionException("Mismatched Token","",-1,-1) , token(0) , node(node_) , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("")) ) , mismatchType(matchNot ? NOT_SET : SET) , set(set_) , tokenNames(tokenNames_) , numTokens(numTokens_) { } // Expected range / not range MismatchedTokenException::MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefToken token_, int lower, int upper_, bool matchNot, const ANTLR_USE_NAMESPACE(std)string& fileName_ ) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn()) , token(token_) , node(nullASTptr) , tokenText(token_->getText()) , mismatchType(matchNot ? NOT_RANGE : RANGE) , expecting(lower) , upper(upper_) , tokenNames(tokenNames_) , numTokens(numTokens_) { } // Expected token / not token MismatchedTokenException::MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefToken token_, int expecting_, bool matchNot, const ANTLR_USE_NAMESPACE(std)string& fileName_ ) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn()) , token(token_) , node(nullASTptr) , tokenText(token_->getText()) , mismatchType(matchNot ? NOT_TOKEN : TOKEN) , expecting(expecting_) , tokenNames(tokenNames_) , numTokens(numTokens_) { } // Expected BitSet / not BitSet MismatchedTokenException::MismatchedTokenException( const char* const* tokenNames_, const int numTokens_, RefToken token_, BitSet set_, bool matchNot, const ANTLR_USE_NAMESPACE(std)string& fileName_ ) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn()) , token(token_) , node(nullASTptr) , tokenText(token_->getText()) , mismatchType(matchNot ? NOT_SET : SET) , set(set_) , tokenNames(tokenNames_) , numTokens(numTokens_) { } ANTLR_USE_NAMESPACE(std)string MismatchedTokenException::getMessage() const { ANTLR_USE_NAMESPACE(std)string s; switch (mismatchType) { case TOKEN: s += "expecting " + tokenName(expecting) + ", found '" + tokenText + "'"; break; case NOT_TOKEN: s += "expecting anything but " + tokenName(expecting) + "; got it anyway"; break; case RANGE: s += "expecting token in range: " + tokenName(expecting) + ".." + tokenName(upper) + ", found '" + tokenText + "'"; break; case NOT_RANGE: s += "expecting token NOT in range: " + tokenName(expecting) + ".." + tokenName(upper) + ", found '" + tokenText + "'"; break; case SET: case NOT_SET: { s += ANTLR_USE_NAMESPACE(std)string("expecting ") + (mismatchType == NOT_SET ? "NOT " : "") + "one of ("; ANTLR_USE_NAMESPACE(std)vector elems = set.toArray(); for ( unsigned int i = 0; i < elems.size(); i++ ) { s += " "; s += tokenName(elems[i]); } s += "), found '" + tokenText + "'"; } break; default: s = RecognitionException::getMessage(); break; } return s; } ANTLR_USE_NAMESPACE(std)string MismatchedTokenException::tokenName(int tokenType) const { if (tokenType == Token::INVALID_TYPE) return ""; else if (tokenType < 0 || tokenType >= numTokens) return ANTLR_USE_NAMESPACE(std)string("<") + tokenType + ">"; else return tokenNames[tokenType]; } #ifndef NO_STATIC_CONSTS const int MismatchedTokenException::TOKEN; const int MismatchedTokenException::NOT_TOKEN; const int MismatchedTokenException::RANGE; const int MismatchedTokenException::NOT_RANGE; const int MismatchedTokenException::SET; const int MismatchedTokenException::NOT_SET; #endif #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CommonASTWithHiddenTokens.hpp0000644000175000017500000000266211733011756024360 0ustar sylvestresylvestre#ifndef INC_CommonASTWithHiddenTokens_hpp__ #define INC_CommonASTWithHiddenTokens_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** A CommonAST whose initialization copies hidden token * information from the Token used to create a node. */ class ANTLR_API CommonASTWithHiddenTokens : public CommonAST { public: CommonASTWithHiddenTokens(); virtual ~CommonASTWithHiddenTokens(); virtual const char* typeName( void ) const { return CommonASTWithHiddenTokens::TYPE_NAME; } /// Clone this AST node. virtual RefAST clone( void ) const; // Borland C++ builder seems to need the decl's of the first two... virtual void initialize(int t,const ANTLR_USE_NAMESPACE(std)string& txt); virtual void initialize(RefAST t); virtual void initialize(RefToken t); virtual RefToken getHiddenAfter() const { return hiddenAfter; } virtual RefToken getHiddenBefore() const { return hiddenBefore; } static RefAST factory(); static const char* const TYPE_NAME; protected: RefToken hiddenBefore,hiddenAfter; // references to hidden tokens }; typedef ASTRefCount RefCommonASTWithHiddenTokens; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CommonASTWithHiddenTokens_hpp__ fwbuilder-5.1.0.3599/src/antlr/CharScanner.hpp0000644000175000017500000003263511733011756021616 0ustar sylvestresylvestre#ifndef INC_CharScanner_hpp__ #define INC_CharScanner_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #ifdef HAS_NOT_CCTYPE_H #include #else #include #endif #if ( _MSC_VER == 1200 ) // VC6 seems to need this // note that this is not a standard C++ include file. # include #endif #include #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API CharScanner; ANTLR_C_USING(tolower) #ifdef ANTLR_REALLY_NO_STRCASECMP // Apparently, neither strcasecmp nor stricmp is standard, and Codewarrior // on the mac has neither... inline int strcasecmp(const char *s1, const char *s2) { while (true) { char c1 = tolower(*s1++), c2 = tolower(*s2++); if (c1 < c2) return -1; if (c1 > c2) return 1; if (c1 == 0) return 0; } } #else #ifdef NO_STRCASECMP ANTLR_C_USING(stricmp) #else ANTLR_C_USING(strcasecmp) #endif #endif /** Functor for the literals map */ class ANTLR_API CharScannerLiteralsLess : public ANTLR_USE_NAMESPACE(std)binary_function { private: const CharScanner* scanner; public: #ifdef NO_TEMPLATE_PARTS CharScannerLiteralsLess() {} // not really used, definition to appease MSVC #endif CharScannerLiteralsLess(const CharScanner* theScanner) : scanner(theScanner) { } bool operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const; // defaults are good enough.. // CharScannerLiteralsLess(const CharScannerLiteralsLess&); // CharScannerLiteralsLess& operator=(const CharScannerLiteralsLess&); }; /** Superclass of generated lexers */ class ANTLR_API CharScanner : public TokenStream { protected: typedef RefToken (*factory_type)(); public: CharScanner(InputBuffer& cb, bool case_sensitive ); CharScanner(InputBuffer* cb, bool case_sensitive ); CharScanner(const LexerSharedInputState& state, bool case_sensitive ); virtual ~CharScanner() { } virtual int LA(unsigned int i); virtual void append(char c) { if (saveConsumedInput) { size_t l = text.length(); if ((l%256) == 0) text.reserve(l+256); text.replace(l,0,&c,1); } } virtual void append(const ANTLR_USE_NAMESPACE(std)string& s) { if( saveConsumedInput ) text += s; } virtual void commit() { inputState->getInput().commit(); } /** called by the generated lexer to do error recovery, override to * customize the behaviour. */ virtual void recover(const RecognitionException& , const BitSet& tokenSet) { consume(); consumeUntil(tokenSet); } virtual void consume() { if (inputState->guessing == 0) { int c = LA(1); if (caseSensitive) { append(c); } else { // use input.LA(), not LA(), to get original case // CharScanner.LA() would toLower it. append(inputState->getInput().LA(1)); } // RK: in a sense I don't like this automatic handling. if (c == '\t') tab(); else inputState->column++; } inputState->getInput().consume(); } /** Consume chars until one matches the given char */ virtual void consumeUntil(int c) { for(;;) { int la_1 = LA(1); if( la_1 == EOF_CHAR || la_1 == c ) break; consume(); } } /** Consume chars until one matches the given set */ virtual void consumeUntil(const BitSet& set) { for(;;) { int la_1 = LA(1); if( la_1 == EOF_CHAR || set.member(la_1) ) break; consume(); } } /// Mark the current position and return a id for it virtual unsigned int mark() { return inputState->getInput().mark(); } /// Rewind the scanner to a previously marked position virtual void rewind(unsigned int pos) { inputState->getInput().rewind(pos); } /// See if input contains character 'c' throw MismatchedCharException if not virtual void match(int c) { int la_1 = LA(1); if ( la_1 != c ) throw MismatchedCharException(la_1, c, false, this); consume(); } /** See if input contains element from bitset b * throw MismatchedCharException if not */ virtual void match(const BitSet& b) { int la_1 = LA(1); if ( !b.member(la_1) ) throw MismatchedCharException( la_1, b, false, this ); consume(); } /** See if input contains string 's' throw MismatchedCharException if not * @note the string cannot match EOF */ virtual void match( const char* s ) { while( *s != '\0' ) { // the & 0xFF is here to prevent sign extension lateron int la_1 = LA(1), c = (*s++ & 0xFF); if ( la_1 != c ) throw MismatchedCharException(la_1, c, false, this); consume(); } } /** See if input contains string 's' throw MismatchedCharException if not * @note the string cannot match EOF */ virtual void match(const ANTLR_USE_NAMESPACE(std)string& s) { size_t len = s.length(); for (size_t i = 0; i < len; i++) { // the & 0xFF is here to prevent sign extension lateron int la_1 = LA(1), c = (s[i] & 0xFF); if ( la_1 != c ) throw MismatchedCharException(la_1, c, false, this); consume(); } } /** See if input does not contain character 'c' * throw MismatchedCharException if not */ virtual void matchNot(int c) { int la_1 = LA(1); if ( la_1 == c ) throw MismatchedCharException(la_1, c, true, this); consume(); } /** See if input contains character in range c1-c2 * throw MismatchedCharException if not */ virtual void matchRange(int c1, int c2) { int la_1 = LA(1); if ( la_1 < c1 || la_1 > c2 ) throw MismatchedCharException(la_1, c1, c2, false, this); consume(); } virtual bool getCaseSensitive() const { return caseSensitive; } virtual void setCaseSensitive(bool t) { caseSensitive = t; } virtual bool getCaseSensitiveLiterals() const=0; /// Get the line the scanner currently is in (starts at 1) virtual int getLine() const { return inputState->line; } /// set the line number virtual void setLine(int l) { inputState->line = l; } /// Get the column the scanner currently is in (starts at 1) virtual int getColumn() const { return inputState->column; } /// set the column number virtual void setColumn(int c) { inputState->column = c; } /// get the filename for the file currently used virtual const ANTLR_USE_NAMESPACE(std)string& getFilename() const { return inputState->filename; } /// Set the filename the scanner is using (used in error messages) virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f) { inputState->filename = f; } virtual bool getCommitToPath() const { return commitToPath; } virtual void setCommitToPath(bool commit) { commitToPath = commit; } /** return a copy of the current text buffer */ virtual const ANTLR_USE_NAMESPACE(std)string& getText() const { return text; } virtual void setText(const ANTLR_USE_NAMESPACE(std)string& s) { text = s; } virtual void resetText() { text = ""; inputState->tokenStartColumn = inputState->column; inputState->tokenStartLine = inputState->line; } virtual RefToken getTokenObject() const { return _returnToken; } /** Used to keep track of line breaks, needs to be called from * within generated lexers when a \n \r is encountered. */ virtual void newline() { ++inputState->line; inputState->column = 1; } /** Advance the current column number by an appropriate amount according * to the tabsize. This method needs to be explicitly called from the * lexer rules encountering tabs. */ virtual void tab() { int c = getColumn(); int nc = ( ((c-1)/tabsize) + 1) * tabsize + 1; // calculate tab stop setColumn( nc ); } /// set the tabsize. Returns the old tabsize int setTabsize( int size ) { int oldsize = tabsize; tabsize = size; return oldsize; } /// Return the tabsize used by the scanner int getTabSize() const { return tabsize; } /** Report exception errors caught in nextToken() */ virtual void reportError(const RecognitionException& e); /** Parser error-reporting function can be overridden in subclass */ virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s); /** Parser warning-reporting function can be overridden in subclass */ virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s); virtual InputBuffer& getInputBuffer() { return inputState->getInput(); } virtual LexerSharedInputState getInputState() { return inputState; } /** set the input state for the lexer. * @note state is a reference counted object, hence no reference */ virtual void setInputState(LexerSharedInputState state) { inputState = state; } /// Set the factory for created tokens virtual void setTokenObjectFactory(factory_type factory) { tokenFactory = factory; } /** Test the token text against the literals table * Override this method to perform a different literals test */ virtual int testLiteralsTable(int ttype) const { ANTLR_USE_NAMESPACE(std)map::const_iterator i = literals.find(text); if (i != literals.end()) ttype = (*i).second; return ttype; } /** Test the text passed in against the literals table * Override this method to perform a different literals test * This is used primarily when you want to test a portion of * a token */ virtual int testLiteralsTable(const ANTLR_USE_NAMESPACE(std)string& txt,int ttype) const { ANTLR_USE_NAMESPACE(std)map::const_iterator i = literals.find(txt); if (i != literals.end()) ttype = (*i).second; return ttype; } /// Override this method to get more specific case handling virtual int toLower(int c) const { // test on EOF_CHAR for buggy (?) STLPort tolower (or HPUX tolower?) // also VC++ 6.0 does this. (see fix 422 (is reverted by this fix) // this one is more structural. Maybe make this configurable. return (c == EOF_CHAR ? EOF_CHAR : tolower(c)); } /** This method is called by YourLexer::nextToken() when the lexer has * hit EOF condition. EOF is NOT a character. * This method is not called if EOF is reached during * syntactic predicate evaluation or during evaluation * of normal lexical rules, which presumably would be * an IOException. This traps the "normal" EOF condition. * * uponEOF() is called after the complete evaluation of * the previous token and only if your parser asks * for another token beyond that last non-EOF token. * * You might want to throw token or char stream exceptions * like: "Heh, premature eof" or a retry stream exception * ("I found the end of this file, go back to referencing file"). */ virtual void uponEOF() { } /// Methods used to change tracing behavior virtual void traceIndent(); virtual void traceIn(const char* rname); virtual void traceOut(const char* rname); #ifndef NO_STATIC_CONSTS static const int EOF_CHAR = EOF; #else enum { EOF_CHAR = EOF }; #endif protected: ANTLR_USE_NAMESPACE(std)string text; ///< Text of current token /// flag indicating wether consume saves characters bool saveConsumedInput; factory_type tokenFactory; ///< Factory for tokens bool caseSensitive; ///< Is this lexer case sensitive ANTLR_USE_NAMESPACE(std)map literals; // set by subclass RefToken _returnToken; ///< used to return tokens w/o using return val /// Input state, gives access to input stream, shared among different lexers LexerSharedInputState inputState; /** Used during filter mode to indicate that path is desired. * A subsequent scan error will report an error as usual * if acceptPath=true; */ bool commitToPath; int tabsize; ///< tab size the scanner uses. /// Create a new RefToken of type t virtual RefToken makeToken(int t) { RefToken tok = tokenFactory(); tok->setType(t); tok->setColumn(inputState->tokenStartColumn); tok->setLine(inputState->tokenStartLine); return tok; } /** Tracer class, used when -traceLexer is passed to antlr */ class Tracer { private: CharScanner* parser; const char* text; Tracer(const Tracer& other); // undefined Tracer& operator=(const Tracer& other); // undefined public: Tracer( CharScanner* p,const char* t ) : parser(p), text(t) { parser->traceIn(text); } ~Tracer() { parser->traceOut(text); } }; int traceDepth; private: CharScanner( const CharScanner& other ); // undefined CharScanner& operator=( const CharScanner& other ); // undefined #ifndef NO_STATIC_CONSTS static const int NO_CHAR = 0; #else enum { NO_CHAR = 0 }; #endif }; inline int CharScanner::LA(unsigned int i) { int c = inputState->getInput().LA(i); if ( caseSensitive ) return c; else return toLower(c); // VC 6 tolower bug caught in toLower. } inline bool CharScannerLiteralsLess::operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const { if (scanner->getCaseSensitiveLiterals()) return ANTLR_USE_NAMESPACE(std)less()(x,y); else { #ifdef NO_STRCASECMP return (stricmp(x.c_str(),y.c_str())<0); #else return (strcasecmp(x.c_str(),y.c_str())<0); #endif } } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CharScanner_hpp__ fwbuilder-5.1.0.3599/src/antlr/CommonHiddenStreamToken.hpp0000644000175000017500000000162511733011756024143 0ustar sylvestresylvestre#ifndef INC_CommonHiddenStreamToken_hpp__ #define INC_CommonHiddenStreamToken_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API CommonHiddenStreamToken : public CommonToken { protected: RefToken hiddenBefore; RefToken hiddenAfter; public: CommonHiddenStreamToken(); CommonHiddenStreamToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt); CommonHiddenStreamToken(const ANTLR_USE_NAMESPACE(std)string& s); RefToken getHiddenAfter(); RefToken getHiddenBefore(); static RefToken factory(); void setHiddenAfter(RefToken t); void setHiddenBefore(RefToken t); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CommonHiddenStreamToken_hpp__ fwbuilder-5.1.0.3599/src/antlr/BitSet.hpp0000644000175000017500000000336611733011756020620 0ustar sylvestresylvestre#ifndef INC_BitSet_hpp__ #define INC_BitSet_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** A BitSet to replace java.util.BitSet. * Primary differences are that most set operators return new sets * as opposed to oring and anding "in place". Further, a number of * operations were added. I cannot contain a BitSet because there * is no way to access the internal bits (which I need for speed) * and, because it is final, I cannot subclass to add functionality. * Consider defining set degree. Without access to the bits, I must * call a method n times to test the ith bit...ack! * * Also seems like or() from util is wrong when size of incoming set is bigger * than this.length. * * This is a C++ version of the Java class described above, with only * a handful of the methods implemented, because we don't need the * others at runtime. It's really just a wrapper around vector, * which should probably be changed to a wrapper around bitset, once * bitset is more widely available. * * @author Terence Parr, MageLang Institute * @author
Pete Wells */ class ANTLR_API BitSet { private: ANTLR_USE_NAMESPACE(std)vector storage; public: BitSet( unsigned int nbits=64 ); BitSet( const unsigned long* bits_, unsigned int nlongs); ~BitSet(); void add( unsigned int el ); bool member( unsigned int el ) const; ANTLR_USE_NAMESPACE(std)vector toArray() const; }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_BitSet_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStream.hpp0000644000175000017500000000120111733011756021644 0ustar sylvestresylvestre#ifndef INC_TokenStream_hpp__ #define INC_TokenStream_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This interface allows any object to pretend it is a stream * of tokens. * @author Terence Parr, MageLang Institute */ class ANTLR_API TokenStream { public: virtual RefToken nextToken()=0; virtual ~TokenStream() { } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStream_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenStreamRetryException.hpp0000644000175000017500000000115111733011756024555 0ustar sylvestresylvestre#ifndef INC_TokenStreamRetryException_hpp__ #define INC_TokenStreamRetryException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class TokenStreamRetryException : public TokenStreamException { public: TokenStreamRetryException() {} ~TokenStreamRetryException() throw() {} }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_TokenStreamRetryException_hpp__ fwbuilder-5.1.0.3599/src/antlr/InputBuffer.cpp0000644000175000017500000000335411733011756021647 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/config.hpp" #include "antlr/InputBuffer.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** Ensure that the character buffer is sufficiently full */ void InputBuffer::fill(unsigned int amount) { syncConsume(); // Fill the buffer sufficiently to hold needed characters while (queue.entries() < amount + markerOffset) { // Append the next character queue.append(getChar()); } } /** get the current lookahead characters as a string * @warning it may treat 0 and EOF values wrong */ ANTLR_USE_NAMESPACE(std)string InputBuffer::getLAChars( void ) const { ANTLR_USE_NAMESPACE(std)string ret; for(unsigned int i = markerOffset; i < queue.entries(); i++) ret += queue.elementAt(i); return ret; } /** get the current marked characters as a string * @warning it may treat 0 and EOF values wrong */ ANTLR_USE_NAMESPACE(std)string InputBuffer::getMarkedChars( void ) const { ANTLR_USE_NAMESPACE(std)string ret; for(unsigned int i = 0; i < markerOffset; i++) ret += queue.elementAt(i); return ret; } /** Return an integer marker that can be used to rewind the buffer to * its current state. */ unsigned int InputBuffer::mark() { syncConsume(); nMarkers++; return markerOffset; } /** Rewind the character buffer to a marker. * @param mark Marker returned previously from mark() */ void InputBuffer::rewind(unsigned int mark) { syncConsume(); markerOffset = mark; nMarkers--; } unsigned int InputBuffer::entries() const { //assert(queue.entries() >= markerOffset); return queue.entries() - markerOffset; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/RefCount.hpp0000644000175000017500000000252611733011756021150 0ustar sylvestresylvestre#ifndef INC_RefCount_hpp__ #define INC_RefCount_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif template class ANTLR_API RefCount { private: struct Ref { T* const ptr; unsigned int count; Ref(T* p) : ptr(p), count(1) {} ~Ref() {delete ptr;} Ref* increment() {++count;return this;} bool decrement() {return (--count==0);} private: Ref(const Ref&); Ref& operator=(const Ref&); }* ref; public: explicit RefCount(T* p = 0) : ref(p ? new Ref(p) : 0) { } RefCount(const RefCount& other) : ref(other.ref ? other.ref->increment() : 0) { } ~RefCount() { if (ref && ref->decrement()) delete ref; } RefCount& operator=(const RefCount& other) { Ref* tmp = other.ref ? other.ref->increment() : 0; if (ref && ref->decrement()) delete ref; ref = tmp; return *this; } operator T* () const { return ref ? ref->ptr : 0; } T* operator->() const { return ref ? ref->ptr : 0; } T* get() const { return ref ? ref->ptr : 0; } template operator RefCount() { return RefCount(ref); } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_RefCount_hpp__ fwbuilder-5.1.0.3599/src/antlr/CharBuffer.cpp0000644000175000017500000000250011733011756021415 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/CharBuffer.hpp" #include //#include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /* RK: Per default istream does not throw exceptions. This can be * enabled with: * stream.exceptions(ios_base::badbit|ios_base::failbit|ios_base::eofbit); * * We could try catching the bad/fail stuff. But handling eof via this is * not a good idea. EOF is best handled as a 'normal' character. * * So this does not work yet with gcc... Comment it until I get to a platform * that does.. */ /** Create a character buffer. Enable fail and bad exceptions, if supported * by platform. */ CharBuffer::CharBuffer(ANTLR_USE_NAMESPACE(std)istream& input_) : input(input_) { // input.exceptions(ANTLR_USE_NAMESPACE(std)ios_base::badbit| // ANTLR_USE_NAMESPACE(std)ios_base::failbit); } /** Get the next character from the stream. May throw CharStreamIOException * when something bad happens (not EOF) (if supported by platform). */ int CharBuffer::getChar() { // try { return input.get(); // } // catch (ANTLR_USE_NAMESPACE(std)ios_base::failure& e) { // throw CharStreamIOException(e); // } } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/SemanticException.hpp0000644000175000017500000000152711733011756023045 0ustar sylvestresylvestre#ifndef INC_SemanticException_hpp__ #define INC_SemanticException_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif class ANTLR_API SemanticException : public RecognitionException { public: SemanticException(const ANTLR_USE_NAMESPACE(std)string& s) : RecognitionException(s) { } SemanticException(const ANTLR_USE_NAMESPACE(std)string& s, const ANTLR_USE_NAMESPACE(std)string& fileName_, int line_,int column_) : RecognitionException(s,fileName_,line_,column_) { } ~SemanticException() throw() { } }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_SemanticException_hpp__ fwbuilder-5.1.0.3599/src/antlr/CircularQueue.hpp0000644000175000017500000000631011733011756022167 0ustar sylvestresylvestre#ifndef INC_CircularQueue_hpp__ #define INC_CircularQueue_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include // out_of_range exception #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif // Resize every 5000 items // -------------------- vk -------------------------------------------- // 11/12/2008: extend the size to make sure large policy files are // parsed without resizing. Resizing causes crash because of call to // elementAt with idx+m_offset = -1 (call comes from TokenBuffer::LT). // I could not figure out why this happens so simpler fix is just to avoid // resizing. // -------------------- vk -------------------------------------------- #define OFFSET_MAX_RESIZE 1000000 template class ANTLR_API CircularQueue { public: CircularQueue() : storage() , m_offset(0) { } ~CircularQueue() { } /// Clear the queue inline void clear( void ) { m_offset = 0; storage.clear(); } /// @todo this should use at or should have a check // // -------------------- vk -------------------------------------------- // Fix for 64-bt systems. Originally argument was defined as // size_t idx; size_t is defined as unsigned integral type. This leads // to a crash when parser requests LT(0) at the very beginning of // the circular buffer because TokenBuffer::LT calls elementAt // with argument markerOffset+i-1, which is at that point equal // to -1. If idx is defined as size_t, it ends up equal to // 4294967295, which means we are looking past the end of the buffer. // -------------------- vk -------------------------------------------- inline T elementAt( int idx ) const { return storage[idx+m_offset]; } void removeFirst() { if (m_offset >= OFFSET_MAX_RESIZE) { storage.erase( storage.begin(), storage.begin() + m_offset + 1 ); m_offset = 0; } else ++m_offset; } inline void removeItems( size_t nb ) { // it would be nice if we would not get called with nb > entries // (or to be precise when entries() == 0) // This case is possible when lexer/parser::recover() calls // consume+consumeUntil when the queue is empty. // In recover the consume says to prepare to read another // character/token. Then in the subsequent consumeUntil the // LA() call will trigger // syncConsume which calls this method *before* the same queue // has been sufficiently filled. if( nb > entries() ) nb = entries(); if (m_offset >= OFFSET_MAX_RESIZE) { storage.erase( storage.begin(), storage.begin() + m_offset + nb ); m_offset = 0; } else m_offset += nb; } inline void append(const T& t) { storage.push_back(t); } inline size_t entries() const { return storage.size() - m_offset; } private: ANTLR_USE_NAMESPACE(std)vector storage; size_t m_offset; CircularQueue(const CircularQueue&); const CircularQueue& operator=(const CircularQueue&); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_CircularQueue_hpp__ fwbuilder-5.1.0.3599/src/antlr/TokenRefCount.cpp0000644000175000017500000000121311733011756022134 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/TokenRefCount.hpp" #include "antlr/Token.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif TokenRef::TokenRef(Token* p) : ptr(p), count(1) { if (p && !p->ref) p->ref = this; } TokenRef::~TokenRef() { delete ptr; } TokenRef* TokenRef::getRef(const Token* p) { if (p) { Token* pp = const_cast(p); if (pp->ref) return pp->ref->increment(); else return new TokenRef(pp); } else return 0; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/CommonToken.cpp0000644000175000017500000000152211733011756021642 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/CommonToken.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif CommonToken::CommonToken() : Token(), line(1), col(1), text("") {} CommonToken::CommonToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt) : Token(t) , line(1) , col(1) , text(txt) {} CommonToken::CommonToken(const ANTLR_USE_NAMESPACE(std)string& s) : Token() , line(1) , col(1) , text(s) {} ANTLR_USE_NAMESPACE(std)string CommonToken::toString() const { return "[\""+getText()+"\",<"+getType()+">,line="+getLine()+",column="+getColumn()+"]"; } RefToken CommonToken::factory() { return RefToken(new CommonToken); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/NoViableAltException.cpp0000644000175000017500000000230611733011756023431 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/NoViableAltException.hpp" #include "antlr/String.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif ANTLR_USING_NAMESPACE(std) NoViableAltException::NoViableAltException(RefAST t) : RecognitionException("NoViableAlt","",-1,-1), token(0), node(t) { } NoViableAltException::NoViableAltException( RefToken t, const ANTLR_USE_NAMESPACE(std)string& fileName_ ) : RecognitionException("NoViableAlt",fileName_,t->getLine(),t->getColumn()), token(t), node(nullASTptr) { } ANTLR_USE_NAMESPACE(std)string NoViableAltException::getMessage() const { if (token) { if( token->getType() == Token::EOF_TYPE ) return string("unexpected end of file"); else if( token->getType() == Token::NULL_TREE_LOOKAHEAD ) return string("unexpected end of tree"); else return string("unexpected token: ")+token->getText(); } // must a tree parser error if token==null if (!node) return "unexpected end of subtree"; return string("unexpected AST node: ")+node->toString(); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/TokenStreamBasicFilter.cpp0000644000175000017500000000160611733011756023760 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/TokenStreamBasicFilter.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** This object is a TokenStream that passes through all * tokens except for those that you tell it to discard. * There is no buffering of the tokens. */ TokenStreamBasicFilter::TokenStreamBasicFilter(TokenStream& input_) : input(&input_) { } void TokenStreamBasicFilter::discard(int ttype) { discardMask.add(ttype); } void TokenStreamBasicFilter::discard(const BitSet& mask) { discardMask = mask; } RefToken TokenStreamBasicFilter::nextToken() { RefToken tok = input->nextToken(); while ( tok && discardMask.member(tok->getType()) ) { tok = input->nextToken(); } return tok; } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/ASTFactory.hpp0000644000175000017500000001306011733011756021375 0ustar sylvestresylvestre#ifndef INC_ASTFactory_hpp__ #define INC_ASTFactory_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #include #include #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif // Using these extra types to appease MSVC typedef RefAST (*factory_type_)(); typedef ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ > factory_descriptor_; typedef ANTLR_USE_NAMESPACE(std)vector< factory_descriptor_* > factory_descriptor_list_; /** AST Super Factory shared by TreeParser and Parser. * This super factory maintains a map of all AST node types to their respective * AST factories. One instance should be shared among a parser/treeparser * chain. * * @todo check all this code for possible use of references in * stead of RefAST's. */ class ANTLR_API ASTFactory { public: typedef factory_type_ factory_type; typedef factory_descriptor_ factory_descriptor; typedef factory_descriptor_list_ factory_descriptor_list; protected: /* The mapping of AST node type to factory.. */ factory_descriptor default_factory_descriptor; factory_descriptor_list nodeFactories; public: /// Make new factory. Per default (Ref)CommonAST instances are generated. ASTFactory(); /** Initialize factory with a non default node type. * factory_node_name should be the name of the AST node type the factory * generates. (should exist during the existance of this ASTFactory * instance) */ ASTFactory( const char* factory_node_name, factory_type factory ); /// Destroy factory virtual ~ASTFactory(); /// Register a node factory for the node type type with name ast_name void registerFactory( int type, const char* ast_name, factory_type factory ); /// Set the maximum node (AST) type this factory may encounter void setMaxNodeType( int type ); /// Add a child to the current AST void addASTChild(ASTPair& currentAST, RefAST child); /// Create new empty AST node. The right default type shou virtual RefAST create(); /// Create AST node of the right type for 'type' RefAST create(int type); /// Create AST node of the right type for 'type' and initialize with txt RefAST create(int type, const ANTLR_USE_NAMESPACE(std)string& txt); /// Create duplicate of tr RefAST create(RefAST tr); /// Create new AST node and initialize contents from a token. RefAST create(RefToken tok); /// Create new AST node and initialize contents from a stream. RefAST create(const ANTLR_USE_NAMESPACE(std)string& txt, ANTLR_USE_NAMESPACE(std)istream& infile ); /** Deep copy a single node. This function the new clone() methods in the * AST interface. Returns a new RefAST(nullASTptr) if t is null. */ RefAST dup(RefAST t); /// Duplicate tree including siblings of root. RefAST dupList(RefAST t); /** Duplicate a tree, assuming this is a root node of a tree-- * duplicate that node and what's below; ignore siblings of root node. */ RefAST dupTree(RefAST t); /** Make a tree from a list of nodes. The first element in the * array is the root. If the root is null, then the tree is * a simple list not a tree. Handles null children nodes correctly. * For example, make(a, b, null, c) yields tree (a b c). make(null,a,b) * yields tree (nil a b). */ RefAST make(ANTLR_USE_NAMESPACE(std)vector& nodes); /** Make a tree from a list of nodes, where the nodes are contained * in an ASTArray object. The ASTArray is deleted after use. * @todo FIXME! I have a feeling we can get rid of this ugly ASTArray thing */ RefAST make(ASTArray* nodes); /// Make an AST the root of current AST void makeASTRoot(ASTPair& currentAST, RefAST root); /** Set a new default AST type. * factory_node_name should be the name of the AST node type the factory * generates. (should exist during the existance of this ASTFactory * instance). * Only change factory between parser runs. You might get unexpected results * otherwise. */ void setASTNodeFactory( const char* factory_node_name, factory_type factory ); #ifdef ANTLR_SUPPORT_XML /** Load a XML AST from stream. Make sure you have all the factories * registered before use. * @note this 'XML' stuff is quite rough still. YMMV. */ RefAST LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile ); #endif protected: void loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current ); void loadSiblings( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current ); bool checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& infile ); #ifdef ANTLR_VECTOR_HAS_AT /// construct a node of 'type' inline RefAST getNodeOfType( unsigned int type ) { return RefAST(nodeFactories.at(type)->second()); } /// get the name of the node 'type' const char* getASTNodeType( unsigned int type ) { return nodeFactories.at(type)->first; } /// get the factory used for node 'type' factory_type getASTNodeFactory( unsigned int type ) { return nodeFactories.at(type)->second; } #else inline RefAST getNodeOfType( unsigned int type ) { return RefAST(nodeFactories[type]->second()); } /// get the name of the node 'type' const char* getASTNodeType( unsigned int type ) { return nodeFactories[type]->first; } factory_type getASTNodeFactory( unsigned int type ) { return nodeFactories[type]->second; } #endif private: // no copying and such.. ASTFactory( const ASTFactory& ); ASTFactory& operator=( const ASTFactory& ); }; #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif //INC_ASTFactory_hpp__ fwbuilder-5.1.0.3599/src/antlr/LLkParser.cpp0000644000175000017500000000301111733011756021243 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/LLkParser.hpp" #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif ANTLR_USING_NAMESPACE(std) /**An LL(k) parser. * * @see antlr.Token * @see antlr.TokenBuffer * @see antlr.LL1Parser */ // LLkParser(int k_); LLkParser::LLkParser(const ParserSharedInputState& state, int k_) : Parser(state), k(k_) { } LLkParser::LLkParser(TokenBuffer& tokenBuf, int k_) : Parser(tokenBuf), k(k_) { } LLkParser::LLkParser(TokenStream& lexer, int k_) : Parser(new TokenBuffer(lexer)), k(k_) { } void LLkParser::trace(const char* ee, const char* rname) { traceIndent(); cout << ee << rname << ((inputState->guessing>0)?"; [guessing]":"; "); for (int i = 1; i <= k; i++) { if (i != 1) { cout << ", "; } cout << "LA(" << i << ")=="; string temp; try { temp = LT(i)->getText().c_str(); } catch( ANTLRException& ae ) { temp = "[error: "; temp += ae.toString(); temp += ']'; } cout << temp; } cout << endl; } void LLkParser::traceIn(const char* rname) { traceDepth++; trace("> ",rname); } void LLkParser::traceOut(const char* rname) { trace("< ",rname); traceDepth--; } RefToken LLkParser::LT(unsigned int i) { assert(this!=NULL); assert(inputState!=NULL); TokenBuffer &tb = inputState->getInput(); assert(&tb!=NULL); return tb.LT(i); } #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif fwbuilder-5.1.0.3599/src/antlr/ANTLRUtil.hpp0000644000175000017500000000320611733011756021135 0ustar sylvestresylvestre#ifndef INC_ANTLRUtil_hpp__ #define INC_ANTLRUtil_hpp__ /* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include #include #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /** Eat whitespace from the input stream * @param is the stream to read from */ ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is ); /** Read a string enclosed by '"' from a stream. Also handles escaping of \". * Skips leading whitespace. * @param in the istream to read from. * @returns the string read from file exclusive the '"' * @throws ios_base::failure if string is badly formatted */ ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in ); /* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace. * @param in the istream to read from. */ ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in ); /** Read a attribute="value" thing. Leading whitespace is skipped. * Between attribute and '=' no whitespace is allowed. After the '=' it is * permitted. * @param in the istream to read from. * @param attribute string the attribute name is put in * @param value string the value of the attribute is put in * @throws ios_base::failure if something is fishy. E.g. malformed quoting * or missing '=' */ void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in, ANTLR_USE_NAMESPACE(std)string& attribute, ANTLR_USE_NAMESPACE(std)string& value ); #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE } #endif #endif fwbuilder-5.1.0.3599/src/antlr/TokenBuffer.cpp0000644000175000017500000000411711733011756021626 0ustar sylvestresylvestre/* ANTLR Translator Generator * Project led by Terence Parr at http://www.jGuru.com * Software rights: http://www.antlr.org/license.html * * $Id$ */ #include "antlr/TokenBuffer.hpp" #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE namespace antlr { #endif /**A Stream of Token objects fed to the parser from a TokenStream that can * be rewound via mark()/rewind() methods. *

"; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += "
"; s += tr("Interface: %1 (%2)") .arg(intf->getName().c_str()) .arg(intf->getLabel().c_str()); s += "
"; if (intf->isDyn()) s += tr("Dynamic address"); else if (intf->isUnnumbered()) s += tr("Unnumbered interface"); else { const InetAddr *addr = intf->getAddressPtr(); QString addr_str = (addr) ? addr->toString().c_str() : ""; const InetAddr *netm = intf->getNetmaskPtr(); QString netm_str = (netm) ? netm->toString().c_str() : ""; s += QString("%1/%2").arg(addr_str).arg(netm_str); } s += "
"; qte->setText(s); } bool newFirewallDialog::validateAddressAndMask(const QString &addr, const QString &netm) { try { InetAddr(addr.toLatin1().constData()); } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", tr("Invalid address '%1/%2'").arg(addr).arg(netm), "&Continue", QString::null, QString::null, 0, 1 ); return false; } try { bool ok = false ; int ilen = netm.toInt (&ok); if (ok) { if (ilen < 0 || ilen > 32) { QMessageBox::warning( this,"Firewall Builder", tr("Invalid address '%1/%2'").arg(addr).arg(netm), "&Continue", QString::null, QString::null, 0, 1 ); return false; } } else { InetAddr(netm.toLatin1().constData()); } } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", tr("Invalid address '%1/%2'").arg(addr).arg(netm), "&Continue", QString::null, QString::null, 0, 1 ); return false; } return true; } void newFirewallDialog::cleanup() { if (nfw) { parent->remove(nfw, false); delete nfw; nfw = NULL; } if (tmpldb) { delete tmpldb; tmpldb = NULL; } } void newFirewallDialog::cancelClicked() { cleanup(); reject(); } void newFirewallDialog::finishClicked() { // getting focus to close table cell editor // see #1594 m_dialog->finishButton->setFocus(Qt::OtherFocusReason); if (fwbdebug) qDebug() << "newFirewallDialog::finishClicked()" << "currentPage()=" << currentPage(); if ((!this->m_dialog->useTemplate->isChecked()) && currentPage() == CONFIGURE_INTERFACES_MANUALLY) { if ( !this->m_dialog->interfaceEditor1->isValid() ) return; } if ( currentPage() == CONFIGURE_TEMPLATE_INTERFACES_MANUALLY ) if ( !this->m_dialog->interfaceEditor2->isValid() ) return; string platform = readPlatform(m_dialog->platform).toAscii().constData(); string host_os = readHostOS(m_dialog->hostOS).toAscii().constData(); st->setNewFirewallPlatform(platform.c_str()); if (currentPage()==CONFIGURE_INTERFACES_MANUALLY) fillInterfaceSLList(); if (currentPage()==CHOOSE_FW_TEMPLATE || currentPage()==CONFIGURE_TEMPLATE_INTERFACES_MANUALLY) { // Creating from a template if (nfw==NULL) createFirewallFromTemplate(); else changedAddressesInNewFirewall(); } else { // Create from interface list (obtained either manually or via snmp) if ( !this->m_dialog->interfaceEditor1->isValid() ) return; FWObject *o; o = db_copy->create(Firewall::TYPENAME); if (o==NULL) { QDialog::accept(); return; } o->setName( string( m_dialog->obj_name->text().toUtf8().constData() ) );//.toStdString()); parent->add(o); nfw = Firewall::cast(o); o->setStr("platform", platform); Resources::setDefaultTargetOptions(platform , nfw); o->setStr("host_OS", host_os); Resources::setDefaultTargetOptions(host_os , nfw); if ( ! discovered_version.isEmpty()) o->setStr("version", discovered_version.toStdString()); /* create interfaces */ foreach(EditedInterfaceData iface, this->m_dialog->interfaceEditor1->getNewData()) { QString name = iface.name; QString label = iface.label; bool dyn = iface.type == 1; bool unnum = iface.type == 2; QString physaddr = iface.mac; int sec_level = 0; string network_zone_str_id = ""; QList ltwi = m_dialog->iface_sl_list->findItems( name , Qt::MatchExactly ); if ( ! ltwi.empty()) { QTableWidgetItem *itm2 = ltwi[0]; assert(itm2!=NULL); int row = itm2->row(); QSpinBox *sb = dynamic_cast( m_dialog->iface_sl_list->cellWidget(row, 3)); assert(sb!=NULL); sec_level = sb->value(); } ltwi = m_dialog->iface_nz_list->findItems( name , Qt::MatchExactly ); if ( ! ltwi.empty()) { QTableWidgetItem *itm2 = ltwi[0]; assert(itm2!=NULL); int row = itm2->row(); QComboBox *cb = dynamic_cast( m_dialog->iface_nz_list->cellWidget(row, 3)); assert(cb!=NULL); int network_zone_int_id = cb->itemData(cb->currentIndex(), Qt::UserRole).toInt(); if (network_zone_int_id != 0) network_zone_str_id = FWObjectDatabase::getStringId( network_zone_int_id); else network_zone_str_id = ""; } Interface *oi = Interface::cast(db_copy->create(Interface::TYPENAME)); assert(oi!=NULL); nfw->add(oi); oi->setName( string(name.toUtf8().constData()) ); oi->setLabel( string(label.toUtf8().constData()) ); oi->setComment( string(iface.comment.toUtf8().constData()) ); oi->setDyn(dyn); oi->setUnnumbered(unnum); oi->setSecurityLevel(sec_level); // only set network zone if it is supported and is not empty. See #2014 if (!network_zone_str_id.empty()) oi->setStr("network_zone", network_zone_str_id); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(nfw)); if (int_prop->looksLikeVlanInterface(name)) { QString base_name; int vlan_id; int_prop->parseVlan(name, &base_name, &vlan_id); oi->getOptionsObject()->setStr("type", "8021q"); oi->getOptionsObject()->setInt("vlan_id", vlan_id); } if (iface.type == 0) { foreach(AddressInfo address, iface.addresses) { if (address.address == "0.0.0.0") continue; if (address.ipv4) { string addrname = string( QString("%1:%2:ip").arg(QString(m_dialog->obj_name->text())).arg(name).toUtf8().constData() ); IPv4 *oa = IPv4::cast(db_copy->create(IPv4::TYPENAME)); oi->add(oa); oa->setName(addrname); oa->setAddress( InetAddr(address.address.toLatin1().constData()) ); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) { oa->setNetmask( InetAddr(inetmask) ); } else { oa->setNetmask( InetAddr(address.netmask.toLatin1().constData()) ); } } else { string addrname = string ( QString("%1:%2:ip6").arg(QString(m_dialog->obj_name->text())).arg(name).toUtf8().constData() ); IPv6 *oa = IPv6::cast(db_copy->create(IPv6::TYPENAME)); oi->add(oa); oa->setName(addrname); oa->setAddress(InetAddr(AF_INET6, address.address.toLatin1().constData()) ); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) { oa->setNetmask( InetAddr(AF_INET6, inetmask) ); } else { oa->setNetmask(InetAddr(AF_INET6, address.netmask.toLatin1().constData())); } } } } } } // merge dbcopy into db CompareObjectsDialog cod(this); db_orig->merge(db_copy, &cod); db_orig->fixTree(); nfw = Firewall::cast(db_orig->findInIndex(nfw->getId())); if (tmpldb!=NULL) { delete tmpldb; tmpldb = NULL; } QDialog::accept(); } fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator_new_object_checks.cpp0000644000175000017500000000227111733011756026707 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id: ObjectManipulator_create_new.cpp 2747 2010-03-20 20:57:09Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "ObjectManipulator.h" using namespace std; using namespace libfwbuilder; bool ObjectManipulator::isObjectAllowed(const QString&) { return true; } bool ObjectManipulator::isObjectAllowed(FWObject*, FWObject*) { return true; } fwbuilder-5.1.0.3599/src/libgui/instDialog_compile.cpp0000644000175000017500000002242211733011756023353 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "instDialog.h" #include "FWBSettings.h" #include "FWWindow.h" #include "instOptionsDialog.h" #include "instBatchOptionsDialog.h" #include "events.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; bool instDialog::runCompiler(Firewall *fw) { if (fwbdebug) { qDebug() << "instDialog::runCompile"; qDebug() << "Firewall: " << fw->getName().c_str(); } // store pointer to the firewall so we can use it in // slot compilerFinished cnf.fwobj = fw; currentSearchString = tr("Compiling rule sets for firewall: "); currentFirewallsBar->setValue(compile_list_initial_size - compile_fw_list.size()); currentProgressBar->reset(); currentProgressBar->setFormat("%v/%m"); QTreeWidgetItem* item = opListMapping[fw->getId()]; assert(item!=NULL); currentFWLabel->setText(QString::fromUtf8(fw->getName().c_str())); m_dialog->fwWorkList->scrollToItem(item); setInProcessState(item); item->setText(1, tr("Compiling ...")); currentLabel->setText(tr("Compiling ...")); qApp->processEvents(); addToLog("\n"); addToLog( QObject::tr("Compiling rule sets for firewall: %1\n"). arg(QString::fromUtf8(fw->getName().c_str())) ); QStringList args = prepareArgForCompiler(fw); if (args.isEmpty()) return false; addToLog( args.join(" ") + "\n" ); // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); // Launch compiler in the background QString path = args.at(0); args.pop_front(); disconnect(currentStopButton, SIGNAL(clicked()) ); connect(currentStopButton, SIGNAL(clicked()), this, SLOT(stopCompile())); currentStopButton->setText(tr("Stop")); currentStopButton->setEnabled(true); setUpProcessToCompile(); if (!executeCommand(path, args)) QTimer::singleShot( 0, this, SLOT(mainLoopCompile())); return true; } void instDialog::stopCompile() { if( fwbdebug) qDebug("instDialog::stopCompile"); stopProcessFlag = true; disconnect(currentStopButton, SIGNAL(clicked()) ); currentStopButton->setEnabled(false); proc.terminate(); //try to close proc. QTimer::singleShot( 1000, &proc, SLOT( kill() ) ); //if it doesn't respond, kill it blockInstallForFirewall(cnf.fwobj); // to terminate whole compile sequence rather than just current // compiler process, clear the list. for (list::iterator i=compile_fw_list.begin(); i!=compile_fw_list.end(); ++i) { opCancelled(*i); blockInstallForFirewall(*i); } compile_fw_list.clear(); } QStringList instDialog::prepareArgForCompiler(Firewall *fw) { FWOptions *fwopt = fw->getOptionsObject(); QStringList args; /* * I should be able to specify custom compiler for firewall with * no platform (e.g. for experiments) */ string compiler = fwopt->getStr("compiler"); if (compiler=="") { compiler=Resources::platform_res[fw->getStr("platform")]->getCompiler(); } if (compiler=="") { QMessageBox::warning( this,"Firewall Builder", tr("Firewall platform is not specified in this object.\n\ Can't compile firewall policy."), tr("&Continue"), QString::null,QString::null, 0, 1 ); return args; // still empty list } /* * On Unix compilers are installed in the standard place and are * accessible via PATH. On Windows and Mac they get installed in * unpredictable directories and need to be found * * first, check if user specified an absolute path for the compiler, * then check if compiler is registsred in preferences, and if not, * look for it in appRootDir and if it is not there, rely on PATH */ #if defined(Q_OS_WIN32) || defined(Q_OS_MACX) if ( ! QFile::exists( compiler.c_str() ) ) { string ts = string("Compilers/")+compiler; QString cmppath = st->getStr( ts.c_str() ); if (!cmppath.isEmpty()) compiler=cmppath.toLatin1().constData(); else { /* try to find compiler in appRootDir. */ string ts = getPathToBinary(compiler); if (fwbdebug) qDebug("Checking compiler in %s", ts.c_str()); if ( QFile::exists( ts.c_str() ) ) compiler = ts; } } #endif QString wdir = getFileDir(project->getRCS()->getFileName() ); args.clear(); args.push_back(compiler.c_str()); QString qs = fwopt->getStr("cmdline").c_str(); args += qs.split(" ", QString::SkipEmptyParts); args.push_back("-v"); args.push_back("-f"); args.push_back(project->getRCS()->getFileName()); if (wdir!="") { args.push_back("-d"); args.push_back(wdir); } // Always pass "-o file_name" parameter to the compiler. If user // specified it in the "compiler" tab, then use that. If not, // compose it from the name of the firewall and extension // ".fw". This way we can properly encode file name for the // encoding and locale used on the system. Compiler simply takes // the name of the fw object from XML file and uses that for the // generated file name, but since the name in XML is encoded in // Utf8, the file name ended up in Utf8 regardless of the OS // encoding and locale. This caused problems, such as installer // could not then find file created by the compiler if fw name had // non-ascii characters. // If object being compiled is a Cluster, use -O instead of // -o. The parameter is a list of pairs: // member_fw_id_1,output_file_name_1,member_fw_id_2,output_file_name_2 // (all separated by commas) if (Cluster::isA(fw)) { args.push_back("-O"); QStringList name_pairs; list members; Cluster::cast(fw)->getMembersList(members); for (list::iterator it=members.begin(); it!=members.end(); ++it) { QString fw_id = project->db()->getStringId((*it)->getId()).c_str(); name_pairs.push_back( fw_id + "," + FirewallInstaller::getGeneratedFileName(*it) ); } args.push_back(name_pairs.join(",")); } else { args.push_back("-o"); // args.push_back(FirewallInstaller::getGeneratedFileFullPath(fw)); args.push_back(FirewallInstaller::getGeneratedFileName(fw)); } args.push_back("-i"); args.push_back( project->db()->getStringId(fw->getId()).c_str() ); return args; } void instDialog::compilerFinished(int ret_code, QProcess::ExitStatus status) { if( fwbdebug) qDebug("instDialog::compilerFinished " "exit code = %d exit_status=%d", ret_code, status); readFromStdout(); if (rejectDialogFlag) { rejectDialogFlag = false; QDialog::reject(); return; } if (ret_code==0 && status==QProcess::NormalExit) { opSuccess(cnf.fwobj); // mw->updateLastCompiledTimestamp(cnf.fwobj); QCoreApplication::postEvent( mw, new updateLastCompiledTimestampEvent( project->db()->getFileName().c_str(), cnf.fwobj->getId())); if (Cluster::isA(cnf.fwobj)) { list members; Cluster::cast(cnf.fwobj)->getMembersList(members); for (list::iterator it=members.begin(); it!=members.end(); ++it) { // project->updateLastCompiledTimestamp(*it); QCoreApplication::postEvent( mw, new updateLastCompiledTimestampEvent( project->db()->getFileName().c_str(), (*it)->getId())); } } } else { blockInstallForFirewall(cnf.fwobj); opError(cnf.fwobj); } currentProgressBar->setValue(currentProgressBar->maximum()); QTimer::singleShot( 0, this, SLOT(mainLoopCompile())); return; } fwbuilder-5.1.0.3599/src/libgui/blankdialog_q.ui0000644000175000017500000000137011733011756022167 0ustar sylvestresylvestre BlankDialog_q 0 0 638 215 QFrame::Box QFrame::Sunken fwbuilder-5.1.0.3599/src/libgui/AddressRangeDialog.h0000644000175000017500000000265611733011756022704 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ADDRESSRANGEDIALOG_H_ #define __ADDRESSRANGEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class AddressRangeDialog : public BaseObjectDialog { Q_OBJECT; Ui::AddressRangeDialog_q *m_dialog; public: AddressRangeDialog(QWidget *parent); ~AddressRangeDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // ADDRESSRANGEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/SSHCisco.cpp0000644000175000017500000003423211733011756021166 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "SSHCisco.h" #include #include #include #include #include #include #include #include #include #include #ifndef errno extern int errno; #endif using namespace std; SSHCisco::SSHCisco(QWidget *_par, const QString &_h, const QStringList &args, const QString &_p, const QString &_ep, const std::list &_in) : SSHSession(_par,_h,args,_p,_ep,_in) { 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: "; ssh_pwd_prompt="'s password: "; ssoft_config_prompt="> "; putty_pwd_prompt="Password: "; passphrase_prompt="Enter passphrase for key "; errorsInit.push_back("Permission denied"); errorsInit.push_back("Invalid password"); errorsInit.push_back("Access denied"); errorsInit.push_back("Unable to authenticate"); errorsInit.push_back("Too many authentication failures"); errorsLoggedin.push_back("Invalid password"); errorsLoggedin.push_back("ERROR: "); errorsLoggedin.push_back("Not enough arguments"); errorsLoggedin.push_back("cannot find"); errorsEnabledState.push_back("ERROR: "); errorsEnabledState.push_back("Type help"); errorsEnabledState.push_back("Not enough arguments"); errorsEnabledState.push_back("Invalid"); errorsEnabledState.push_back("invalid"); errorsEnabledState.push_back("cannot find"); errorsEnabledState.push_back( "An object-group with the same id but different type"); errorsEnabledState.push_back("cannot add route entry"); local_event_loop = new QEventLoop(); comment_symbol = '!'; } void SSHCisco::loadPreConfigCommands(const QStringList &cl) { pre_config_commands = cl; } void SSHCisco::loadPostConfigCommands(const QStringList &cl) { post_config_commands = cl; } void SSHCisco::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); } SSHCisco::~SSHCisco() { } QString SSHCisco::cmd(QProcess*, const QString &cmd) { if (fwbdebug) qDebug("Command '%s'", cmd.toAscii().constData()); sendCommand(cmd); //stdoutBuffer = ""; //proc->write( (cmd + "\n").toAscii() ); state = EXECUTING_COMMAND; local_event_loop->exec(); if (fwbdebug) qDebug("Command '%s' completed", cmd.toAscii().constData()); return stdoutBuffer; } bool SSHCisco::checkForErrors() { QStringList *errptr; switch (state) { case LOGGEDIN: case WAITING_FOR_ENABLE: errptr = &errorsLoggedin; break; case ENABLE: errptr = &errorsEnabledState; break; default: errptr = &errorsInit; break; } for (QStringList::const_iterator i=errptr->begin(); i!=errptr->end(); ++i) { QString line = *i; if ( stdoutBuffer.lastIndexOf(line, -1)!=-1 ) { if (fwbdebug) qDebug() << "Got known error message: " << line; emit printStdout_sign( tr("\n*** Fatal error :") ); emit printStdout_sign( line + "\n" ); stdoutBuffer=""; // terminate(); sessionComplete(true); // finish with error status return true; } } return false; } void SSHCisco::stateMachine() { if (checkForErrors()) return; if (fwbdebug) qDebug() << "SSHCisco::stateMachine() state=" << state << "(ENABLE=" << ENABLE << ")" << "(PUSHING_CONFIG=" << PUSHING_CONFIG << ")" << " stdoutBuffer=" << stdoutBuffer; switch (state) { case NONE: { if ( cmpPrompt(stdoutBuffer,QRegExp(pwd_prompt_1)) || cmpPrompt(stdoutBuffer,QRegExp(pwd_prompt_2)) ) { stdoutBuffer=""; proc->write( (pwd + "\n").toAscii() ); 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)) ) { stdoutBuffer=""; state=LOGGEDIN; emit printStdout_sign( "\n"); emit printStdout_sign( tr("Logged in") + "\n" ); emit printStdout_sign( tr("Switching to enable mode...") + "\n"); stdoutBuffer=""; proc->write( "enable\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)) ) { state=WAITING_FOR_ENABLE; stateMachine(); break; } QString fingerprint; //int n1,n2; if (stdoutBuffer.indexOf(newKeyOpenSSH)!=-1 || stdoutBuffer.indexOf(newKeyPlink)!=-1 || stdoutBuffer.indexOf(newKeySSHComm)!=-1) { /* new key */ bool unix_y_n = (stdoutBuffer.indexOf(newKeyOpenSSH)!=-1 || stdoutBuffer.indexOf(newKeySSHComm)!=-1); if (fwbdebug) qDebug("New host key message detected"); fingerprint = findKeyFingerprint(stdoutBuffer); QString msg = newKeyMsg.arg(host).arg(fingerprint).arg(host); stopHeartBeat(); int res = QMessageBox::warning( parent, tr("New RSA key"), msg, tr("Yes"), tr("No"), 0, 0, -1 ); if (fwbdebug) qDebug("User said: res=%d", res); startHeartBeat(); stdoutBuffer=""; if (res==0) { if (unix_y_n) proc->write( "yes\n" ); else proc->write( "y\n" ); break; } else { sessionComplete(true); // finish with error status return; // state=EXIT; // goto entry; } } } break; case LOGGEDIN: if ( cmpPrompt(stdoutBuffer,QRegExp(epwd_prompt)) ) { stdoutBuffer=""; if (!epwd.isEmpty()) proc->write( (epwd + "\n").toAscii() ); else proc->write( "\n" ); state=WAITING_FOR_ENABLE; } break; case WAITING_FOR_ENABLE: if ( cmpPrompt(stdoutBuffer,QRegExp(epwd_prompt)) ) { stdoutBuffer=""; if (!epwd.isEmpty()) proc->write( (epwd + "\n").toAscii() ); else proc->write( "\n" ); state=WAITING_FOR_ENABLE; break; } if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { emit printStdout_sign( tr("In enable mode.")); emit printStdout_sign( "\n"); state=ENABLE; // and go to ENABLE target in switch /* give classes derived from SSHCisco a chance to do * something before we switch to config mode. If is * SSHCisco class, the stateMachine method will simply call * itself and will fall through to the ENABLE state. */ stateMachine(); break; } 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(); if (cmd.indexOf("reload in")!=-1) state = SCHEDULE_RELOAD_DIALOG; sendCommand(cmd); //proc->write( (cmd + "\n").toAscii() ); break; } stdoutBuffer=""; if (backup) { /* the problem is that QProcess uses select and thus * is tightly integrated into event loop. QT uses * internal private flag inside QProcess to * specifically prevent recursive calls to * readyReadStdout (look for d->socketReadCalled in * kernel/qprocess_unix.cpp ). So, I _must_ exit this * callback before I can send commands to the process * and collect the output. */ QTimer::singleShot( 0, this, SLOT(PIXbackup()) ); break; } 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?")) ) { stdoutBuffer=""; proc->write( "n" ); // no \n needed break; } if ( cmpPrompt(stdoutBuffer, QRegExp("Proceed with reload?")) ) { stdoutBuffer=""; proc->write( "y" ); // no \n needed break; } if ( cmpPrompt(stdoutBuffer, QRegExp("SHUTDOWN")) ) { stdoutBuffer=""; proc->write( "\n" ); state = ENABLE; break; } if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) ) { // reload did not ask for confirmation stdoutBuffer=""; proc->write( "\n" ); state = ENABLE; break; } break; case EXECUTING_COMMAND: if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) ) { //QCoreApplication::exit(); state = COMMAND_DONE; if (fwbdebug) qDebug("Switching to COMMAND_DONE state; state=%d", state); if (local_event_loop->isRunning()) local_event_loop->exit(); } break; case WAITING_FOR_CONFIG_PROMPT: if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) ) { /* 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; } break; case PUSHING_CONFIG: if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt))) // config_prompt)) ) { // see SF bug 2973136 , fwbuilder bug #1347 // looks like if user hits Cancel to cancel install at just right // moment, the process can get killed when control is already // inside this block. Adding test for proc != NULL to be sure. if ( activation_commands.size() != 0 && proc != NULL) { QString s; do { s = activation_commands.front(); activation_commands.pop_front(); emit updateProgressBar_sign(activation_commands.size(),false); s.replace('\"','\''); if (!quiet) { QString rl=""; if (s.indexOf(QString("%1 Rule ").arg(comment_symbol)) != -1) rl = s.mid(7); if ( !rl.isEmpty()) { emit printStdout_sign( tr("Rule %1").arg(rl) + "\n" ); } } } while (stripComments && s[0] == comment_symbol); sendCommand(s); } else { /* activation_commands.size()==0 */ state = EXIT_FROM_CONFIG; emit printStdout_sign( tr("End") + "\n" ); // kick it so we get some output from the router and // continue the state machine if (proc) proc->write("\n"); } } break; case EXIT_FROM_CONFIG: if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { /* * Execute post_config_commands */ if (post_config_commands.size()>0) { stdoutBuffer = ""; QString cmd = post_config_commands.front(); post_config_commands.pop_front(); sendCommand(cmd); break; } stdoutBuffer=""; state = EXIT; proc->write( "exit\n"); } break; case EXIT: // emit printStdout_sign( tr("Terminating session\n") ); // terminate(); // state=FINISH; break; case FINISH: break; default: break; } } fwbuilder-5.1.0.3599/src/libgui/rulegrouppanel.ui0000755000175000017500000000272211733011756022451 0ustar sylvestresylvestre RuleGroupPanel 0 0 447 61 Form 2 2 2 2 20 2 TextLabel Qt::Horizontal 40 20 fwbuilder-5.1.0.3599/src/libgui/FWObjectSelectionModel.h0000755000175000017500000000253011733011756023506 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWOBJECTSELECTIONMODEL_H #define FWOBJECTSELECTIONMODEL_H #include namespace libfwbuilder { class FWObject; } class FWObjectSelectionModel { public: libfwbuilder::FWObject *selectedObject; libfwbuilder::FWObject *selectedObjectOld; QModelIndex index; QModelIndex indexOld; FWObjectSelectionModel(); void setSelected(libfwbuilder::FWObject *, const QModelIndex &index); void reset(); void save(); void restore(); }; #endif // FWOBJECTSELECTIONMODEL_H fwbuilder-5.1.0.3599/src/libgui/Images/0000755000175000017500000000000011733011756020245 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Images/fwbuilder3-72x72.png0000644000175000017500000002604211733011756023614 0ustar sylvestresylvestre‰PNG  IHDRHHUэГG pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХF!MIDATxкь|ipdх•хykО—/ї””)ЉД—ЊЄZ „ЪХ`жam‡gк Э8КУv4сqДлvO t‡н]І—љгv7ї€—і avА ЖБ уZUUWi­’”JЅrЯ|ћіЭхїœЊ…* tдЩˆŒRIЉЗœя~чм{ю}b!јџЏГПx0MѓœМїо{9ЯѓіјОПЧї§mОяg !НОяУї§”яћC„јОBdY.^yх• уууW_~љхЦrq’$]эѕмsЯ§§ввRџ‰'.’eyЇчyhпїAџпббI’@ъююv†††т‘HdыйРЙѕж[Џp€чќ№Щ'ŸД/и:лkvvіШВŒ‰‰ „УapзtЧSU•Џзы‚яћ!I’ iЊе*JЅJЅ<Я:;;ЁЊъiрмyчBШ—8Žћ(!„B*Зоzыз<єф“OЊ,@_§ъW#їо{opЕZ ЕZ љ|ž~+:>>~тž{юЬd2ТРРтё8LгФъъ*VVVЧБИИxЦ&‰у<ЯwTЋUДmЩ”яћїB>|лmЗ]їФOП ’eљ‰o|у{=Я{йї§WMг„iš№}?јLГй<чAmлЦЩ“'ЯјГчŸ^{{{aлі†-лтДgяИуŽсЧќ‚(.Šт$!$BЙої§ысћ>4MУддЧAЕZ=Їьеj5X–uжŸ?~яџћ5œ$IBЃбр …–——Ч‡2™ЬЙХєzНЎvuuЅкWеї}ˆЂˆ;vраЁCЈT*чˆђбй^„pGЧ‘t]G4E&“СоН{ЁiZљŽ;юИ rО§эoЧ?іБiууутккš`YV л;vьРŽэлёќѓЯ‹ч:hЉTТъъ*р _јBЄ•ьё<якЛюК+677‡••F„ тшЫї}і‚%iпїёШ#(щtљШGьббQNг4NQђЪЫ/2Я?ї,|„Ю(Ч™L›7o†a@†i(Š"ˆЂиlOBЁ.Кш"pЇФуqдj5 Аь:.Ь-ѓ У@г4|ч;пGFFpЫ-ЗрыџєЬЪЪвњіЉW6|6‰`ЧŽˆFЃэdЫјОgёxžчA–e„Уaxžг4Q(pша!ЬЭЭЁЃЃ ГŽK6›Н№ѓ BЧA­VУЩ“'QЉќžOТayxrr‚ р†nРuз]QсК.<ЯƒчyˆХbpFОяcaaљ|SSSX[[УккZА(ŠјŠrAGCr]–e&ѓёXёxpфШШВ žчaš&lл†iš0 уД-Ы‚mлАm У •$Тѓ<”ЫхрЖmћ$@Ÿќф'Сq\фдH:Řэшь ј‚о(§њyљОJЅЄыК|!(F6›лКs†a‚їщdм…l6‹l6‹ЎЎЎЗ}ОяЃЏЏсpІiТѓ<щс‡–/Иj%gЎ$Чq‚ ‚€ЎЎ xžnЎбhМ­ „рЮ;я„(ŠXYYA.—ѓ|№Ayф‘w€t*vкїnџРŸа‡?ќa|эk_SAˆЗЋ”aрx;ЖŽcзФn„BПЗ <Я{лЕЪwvvЖ&ŠbУ0ATONNОЃ`=2u“ч“OyžЗs] ˜\ЕІЮјОџ џ`6ŠхЮJв„Ў–eСВ, УРезмИ444$+Šвбўyзuџ`юi_„gŸ}–ЯfГЉT ŽуМјN‚ђњk?сyў‡lЧнэyоЉЂдХ0Ь„Ђ„я >1:Дxэ5я;+@ЎыўЧqћˆt‹™І MгњNž<‰P(фВ,ЛтyžщКn‰уИ*Яѓєvo‚ЊІmлvГйќЫЗsЌ 32€ы=ЯЛЃZkќgгДЧv`ЗQУ0H%“№|ЊЊavvКЎЫ,ЫfЯШA’$сРјжЗО5uЯ=їм&Šтw|пгƒqA …x–eћЧчy[LгЯѓp]їmфК.Lг4*•ЪŸ~іГŸ§н‘#GовяПјтЏЦЧљДiZЄыFdIB8,C’Bˆ$c’$cyyЊІсрЁC0M3и)T™Я™(~ѓ›п|њK_њв!У0ЎvŽуI яћ`Y6у8ќЁž6M!!ˆD"PхЅћюЛяџœяяџьљŸўн0ўFзŒKЭfтLŸ§P5•JЃ›‡№Ъo\;ЧqX&неех ФbБYŠЖ A‚G йГдBЛMKA8† P™L‰DЂvЎ‹}ъЉ'ю6tу#бhdLQ”.%FDQ DТа4F–ecxx„ kxщЅпРq№<ЁСОГ[Иžїшy”L&Y–1:: ЫВ Њ*Ње*TUE,Яѓp'Иq]зс8NIг7№<†a IX–ЯѓˆХbˆХbˆЧуˆХbe„гЎх{п{\4MѓЏдІњСbЉД]з3.yoO†‡‡qХ—ущЇŸХ /ќОяƒчy№<жHсy‰D ŠСіэ;дЭ›7џХ‰…™sфћ~<#›Э"лЪu]†Mг;CзѕгЂCEˆЂDЫВшээEН^РRŠЂкЖ€Чћп};Ж_c˜жY+Ќ]Н’Я‹ХтщоR6“Сјјtн@ЅZХ~јClкдщщixžVP8ŽC*•D"‘@gg:;;‘JЅNЇ§ѓоbЖmGщ dYF4…Ђ(E„Р–e†a@зuИЎD­Л!Аm шыыC.—ƒeYі?BUU'>ѓ™O——sЯ<ѓcФc1teКщъФЮлС2,фpЭІŠЕЕ5TЋ5ќ№_Žу‚HyГTЂЃЃ‹K+иЕkВй,вщ4тё8dY† `Y–иЖ}v€к“Вя~їЛбP(Дkш‰hШ&“ыЋ`лvPи:Žl/Z ъКŽp8Д…(ёћОa”ЫхєсУПWЏFЃЅхelнКМ ЂT*уЯўєПbпОПGamэœ Ќsi'вЉ’Љ4КЛЛ!I‡!Š"8Ž;gwкxрЌЎЎ&{{{7€C­ JКЇ*™(ŠTŽž˜ВЁИЅ[‘n=QQ.—‘Ых Њы •mлЖЁЗЇšЎceeO<ё$8ŽУŸм§ЧчЌывЉzzz‘JЇ‘ЩdL&‹Х ( Lг „‡^!ѕz•J…пДiгЙŠD"иВe 333ƒ'Ÿ|—]vЦЦЦ Ыr…eYЬЮЮbpppCAСa& fQ …‚МЉбh X,"—ЫAlлЖ‹EЦ0 ,,,рШ‘#ч-ЧшлД ље"FЗlХM7нЧq IRё4u]ЧСqфr9‹E$“I 1чAЫЫЫŒу8ьž={000€rЙŒщщi;v ™Lйl‰DFЗп~;жж 0 з]wюПџ~0 UUЁiLг„ЎыаuхrЭfkkkh6›HЇгHЇгAФ”ЫeчрСƒтЙЗРvщHcpp§§§шыыG:F"‘Ръъ*†‡‡—r]мrЙŒzНA iЎИт ъ"ИgкnЇ”NЇБВВТZ–Mгалл‹x<Žh4Š••dГYhš†Ѕх“xшсЯУ4M4ъ <єаџФ§їпЛяО–eЁйl"•J†‡‡!Š"’Щ$FFFАДД„bБИ!b†?WTЉTБeы(њpѓЭ7ƒ‚ŽŽDЃQPЮЌT*7QpJЅ}єQМјт‹ˆD"xєбGСВ,Nœ8A=tZІœ У‡‹єЦЈ|лЖ MгРВ,8ŽƒЊЊHЅјж7џѕzщt=ќі§нƒиКu+,ЫТтт"’Щ$t]‡eYp]еjхr9pкљi’Nšh4Š‹vюФра TЭФ 7м„щщiьйГ•J‚ мзИmлЈеjXXXРО}ћ044ˆ}Ÿџ,FF†Б’_BG:ˆхЭѓкb–euг ‚г4Сq"‘HАWWW‘ЩІPЏ7жеfi wџЩ‡рy^ jT!шгФ’уИ`Е)рєч’$С4MD#lо<‚-[ЧАmл6ttt N#‹! ЁP(€vDк­[ZзŸ‡яћˆD"шяяп9ЛЎ‹zНŽL6…FЃєячїѕЭшяPХЂЅхЊvЧŽCЙ\ЦФФQ…™œœФтт"nЙхDЃQH’QAћhэV/m‡—JЅ ЅЄ( ŠХ"–——БДД„П§ЛПЦcў jЕ4Mƒ Ќ EБXФмм.ОјbŒŽŽњ'OЬž Z­Ц\rЩ%…B˜ŸŸGЁP@?ЈьгrЂ}Иnк2В,kƒьгTу8†У0р8Ъх2!РииŽ=ъ ѓууу0 X–ЕAAŽ;лЖ!Ы2.НєRT*•@ X– XŽуP.—ЁЊj0[P.—ёžїМФ№№0jЕšwО}Б”išH$˜œœD>ŸGwwwАbѓѓѓA›Цuз[;4ё<Ђ(ЂZ­BгД лQЏзЁы:*• dYFoo/`ddFžчСВ,D"H’Y–^ =~Žу‚ЌМбh`jj —\rIРwЅR ЊЊ‚‚d2I§Ѕѕы&@Н^GГй ЎЕЋЋ Эf3 №<љР?tZсЭŸС"HваЇ5Ugg'Тс0xžGЃб@Й\ЦkЏНњ<ъЕ:ццч!ЫnЛэ6№<Ј^<m_s‡ххх 5M xЃНѓzjхЙ\ѓѓѓр8ѓѓѓxщЅ— Š"Оќх/op!Avoл6t]_чЈVДЋЊ(œчyрy>8_ЕZхЮ+‚<ЯлD JQ\oУг§Я0 dYFww7<ˆ§Пћ\зE8,ур7pљх—Y5ЧqА,k/бѓ}?(9h§cY У`hйтК.~ђ“Ÿ@г4\|ёХа4 ?ў8††ёйЯн‘‘aзЪˆDт'Б,‹rЙ ]з‰Dагг"Š>№СлpгM7 АZB($Уї}†W^yйl–=/€:;;‡чццРѓ<ККК Bp“<ЯC–e ‹aћіэЈT*ЈVЋB"‘ؘrUТіЃ‰`(‚чyX^^Ц‰'аззЧ?~GХииіьйƒH$У0№•Џ|хŒjTЋЊА, •JšІaxx###ЈеjШхrИўњыB№щЯќ%tЭРjОY–QЉд Š"ЎКъ*јОзuэѓ•љќФФVVV№мsЯA’$ЄR)tuuЁЛЛсpŠЂ ™LЂeВ#—ЫЁЇЇ'иїЎыn hj•аюЋЎыh6›AЙбггƒK/НdqэЕз" ]ЊR~яGOSЃ™™єєє`ddЫЫЫрyЋЋЋ „@Q\qХ8~|ЁPсp$XјX,†rЙ MгЈšž_ЉFQбппёёq‚€jЕБ Са&Е6(7йЖєуMгDЕZ 8Ј\.ƒeY(Š‚X,†d2 žчЁЊjРkБXŒ‚Рдj5ЄRЉ 3 #рБSеhЯž=С0]JМЎыЂЃЃІi"NCг4lйВљ|>˜ Ni(bЯд!>  X,&‚€!I†††Zю[ŠЂРї}‹EЄгi†Qсy^№5Н™d2‰d2‰W_}з]w4Mƒmл(ЊЊnр)Яѓ˜S­к–™ЖNиgP#ъKQžЃІœЊЊр8™L###ЈVЋЈVЋeL‘чyиЖBЁp~$­(Š@Й&xд8ЃVš‡Ус ‰!†a*‡QЉT@'aЉћШq\Авд\ѓ}—J%9rЭfs=ћ>‹б!‰fГ‰fГ‰p8ŒЁЁ!0 ƒFЃ\.ЗЁС@Фu],--A’$єєєœпгu=Fƒ) jjQcЋняЁ вСMкI QAѓЯѓ‚•Ѓ5%ljAа З, oМёšЭ&pэЕзbqqЯ<ѓL FЗп~+nИё?bnюtm=iUU===HЇгAВHyeй {Ї5ЁЎы0MЛvэBЅVСбкlП/жwфяKo ЧqнПўѕЏБyѓцРуyў4W‘J$šЬЕЫЗ ХХХыGGGЗ.,,рwПћ]pуэ&;ЕDY–ХБcЧ_з4MX–DeYAћ:бbš&JЅŠХ"ІІІ …АsчN8ŽУ0˜-[ЖlЈА†A2™ФБcгШхђpщt{їюE, B ˆ СЙшv—e###№Žуаl6КЎујёуAh‡B!Фb1lоМ–eaзЎ]КЎЛЁBЇљЭЋvяофFдSђŒЅЅЅv*Aq­„Rzс\xАс‚ ЙаЯКХЂэОL&“A__"‘–––066†zНŽхх“xј l0ЬОјХ/тSŸњT ћ™L&Ш;EСјј8Mы7ЈUЫp8LЃ(ˆФљљyШВŒЩЩIФb1˜І‰Z­EQ`л6Ђб(\зEГй ЖЏыКкЉаŸ7Ќ^^њ9цЊ А;uЌœа ђ!0.ЃЎƒси‹ЯЪAѕz=IŠЎfЛЕюьUHЦ№ЭЧ6f|ўa(ŠTвЉT ЖmœUЉT6јCTв)љГ, лЖ1??щщiŒŒŒръЋЏЂ‡nkЊtќЦu]hš†T*…ссaфѓyфrЙ@Љэbл6VWWё#ђЯКV…Zl ЇЛ‰X FM‡Ь(ЉЅф№GЄНѓ_7_f8ьѕћюЛхr9FЎvYЄ*`л6ђљ§боЂ‹рyrЙfffЈ^ЏžbЭЂZ­ЂVЋabb’$!ŸЯczz’$­ЅіЧЕђљ<!ШWр8`$ŽщТ%И[Зрy.‘^7žьи0ЃНННѓŠХ"žzъ)?~ЎыВ}ъ`чЉ†НžчƒЈhџ<ЭGкыГjЕŠŸџќчh4иН{w$ЖG.х˜ЃGbuu“““иЙs'*• –––‚ЯщКјч†a@–ed2T*‹EМj§€K3AˆТx p6дBR(!*Рѓ=„dёЮг"Јel‰›7oЦ–-[Ых№иcaгІMиКu+Aj­3fэъCA ЩЃaШчѓСХцѓy„УaLLL ЛЛЅR ЕZmпyž‡ееUаGЇnОљf”J%œ8qbCуц_ЖmC’$d2p‡RЉєрђk+0•bFfQG4Ыѓ№ЯѓЁH d)™C‹•фxxhг‡Ќ№€^yх•оббQ†Jh&“СФФnЙх–`‚ЃйlЂVЋЁZ-сС‡іЁ^k†й5з\ƒпўіЗЈеj(•J˜™™AБXD4У0‡У`я}я{!*•JаžІђЬВl`Ч:t;vьРЎ]ЛАџ~,..NMXi^Ѕ( Вй,xžЧЪЪJ`ЕRIЯ5IЩЩњ”‰((0* h5Ф!0*:tvv"‰&5РЊеjPišЌ8э~PЎЃлцЦoD4КЮsЫЫЫђЕЗІi"™LbttЕZ ЖmЃX,n К•e;юЏMYNjЄ’Ѓ <ЏЫѕ`6b—œj9\Jy9јЭšeд–єoW~эќЭ†-‹Х>Ї(J‚жUAнjЅаАЇЩтUW]…­[ЗЂ^Џcuu}}§ˆЧу „ Z­7A‹Qъ-SžЂђOk3Њtд™ГŽ@nФeСЖЃбUЏз‘L&ZYY œOКЈTХ\з5Ž=§єг/j^Єv ]c‘‹x™‹Tђњrљљ”ЙшЯѕnЛт/:urЬ3Шq5ПZEq[8ѕbкѓžіgЧhй100€ююn†ХХEєєєv%Vњ0^ћsTeкw iХЬЬ lbСлYХьЎyИ%сХ,† (‹А, щЎ&&&‚Ї„(шєјДутКЎqєшбWё‹_|'—Ы`H~aПX9PюдЩ€:в8ъњXOŸ›Tю†Z^^NP‡pjj “““ˆFЃСЩiБ}rƒчyH’„H$Y–0ЈsHЗУ0›•c5  Ь­LуDeC+™‡$ј)?RФ!цYtј›БЊёoсeЬч‡Ё‘:DKЦNсНрА^Ж,uffцх^xс[еjѕ0€•>@Фi€б‚Z­Є5HONЋцЧЧЧ9ЯѓvЭЭЭattБX GŽСддЎЙцЌ­­ЁГГsCk‡Ў\{aJgƒЈмЖІaрhПЌVЋamm Хb…BEi ђѕ&†ЗёyЌЯ€qFdрЖиа3(.ЉˆiTcЋ$ кXУыU`+ЗЊЊ6>|р™gžљGлЖЇф[лФnЛiЇфœЈ|+?йЦ0Œьћ>–——‘NЇбппI’0;;‹W_}šІAEd2 #•J}Ћўў~шКXЌд"-‹Аm;hшЉЊŠќђ—ы3„сp‚$ ќAБM2№рРq,|зƒыњр<œЧu$…8TНН)#йЃZXsо˜yуW?§щOџР\ ˜Ц)Рр­€r@ УьiЯt=ЯCЕZE2™D<Чрр``ЕRŸžž"фрСƒAОA —Ъ:§Œ$I…B8qт2™ JЅЪх2АЩ@X$р гАс<УСб]x:Ф…ЁU j‰$\ЫBЭ4 зC`uЖдјЭ Ч> зŠч­‚p>ДчLІ>mсp|MkЋЮЮЮР5ф8В,ox&ЌX,O?7 ”JЅ`цк/СS~|ЦƒНЬƒ‰,сЁk\ЫGXШМР‡­Ћ04^wnˆ€5Я!А\М"Є{nSЫџз~§&hїюнмХ_|@эdмўx  щ|ЛŒЗѓ§š~ŸЖŽЭŠШЄ%‚QфaЉ,ф8ЛnС!.ˆEрšb8„x2 OїQ*Ь!б…hGІiAЏX№B,8™/ѓ€§Ž€sZы9‘Ht0 ГѓlгЁgŠЌ7ГљAЧuр4ьMC `]dQ@TŽРа-№О†И"ƒуИj,ЯCIEР„XИєВ!$Тp-:uЅqАvШњўЛіМ˜$I;|пчкŸ<ѕКvкСy+ ­З›mИŽЯvA„—Q-Waз8Ќ­U $eРfЁ5 ˜ЅИ9œFuЕ зС3ФЫjzХ)ыWцŠџзvйзп5€*•J#™L–Y–MЗ'‡oв['Щ#рD!…яиа5<сaW,$]Pј„‡jЉ„z­У" X† Q`4,Dbз/ГNcЪ}РZ+ywЩДm{muuѕйЖнloŸ д;БХ|ЩAlœCyЁŽтBž XU $DDзaж4јІ_їсЊ.р3` ЃfРw|А< п'`EVтcŒC3оwѓ‘ЬЕjЕњЫВЬўўўџ …Ў ИіdЏН^zЋ[Œšf^І‰d2ЯДЁ&TГЏКў,—!Љ№Ž/@kXP‹<ЦGИ‹…я3 РГАu–fЃ>gМь6ШlЋ4xW2ЬъКЎ;vьhЁPи;::њžP(4)Ыr‡ MJ&щŒ•эі7­‰кпС$~нGyЁ Я№@D@ŠKА9…Е:lтA ЌWwс–хТcLАтzџЬslЈ%jбЊд8џ`Ёy'•kƒPэпПА{їn@@'€nEQњ†††.ŸюI&“IQЛiyAЂбAѓ*ыЇЪ>эЉЛ™šѕ8%т`;ъ­AtЏKУ<8№"ЫqЁ6l‹№$ФˆлkКV}Ъў[k‘ќЈія}эоН› ˆаЗ(ŠЉl6лL&3йlvДйlJсpИУq&•J%Z…"РА,‹Зm[p]—˜Іщ4 еu]Ї^ЏW У Жmћс>І7q‘ИјlS_q~ЉN{пѓ 2КœŸ#м_жKю3цВџc.ЪИ| №™|ЦВђоЋі*9 иЧЇsŸ7шА˜жcт!r ИЁхgѓ­яё­ЗиК`JžЋMe$IБV­ДжЊ*­ъši_iзlН)А­c9мєЭ)?ырншMЇлїяпOZ7ъЖVыLбЦЗnŒmнTЛmрЕ~—^л‰ўс€еw‡ф |—пскžс{ыУ—Ф'`8\ˆЗ<ЧƒяЗХќћќyУџ7”5ŒСУ1]VIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Images/network_zone_dialog.png0000644000175000017500000010151311733011756025017 0ustar sylvestresylvestre‰PNG  IHDRЩйФќ\ %iCCPICC Profilex­“ЯkAЧП› U,jЩMиC 6’&=Iк4‘и4†dыЯгfv“f7ыь&5СCў оz^ФЋˆ‡œDD"ˆт?рQ(ˆPЫњfзI<4xёСь|цё7яН’п Яы&8nРы—7д7oЉs_‘€‚4Є ц{ыЕZ…$3ьЧ'в’}L‹X3DГм œKэ˜ѓ‚›1ы‚w/ -˜й†Iќ€XуzН@ќ”xЁѓ СݘпАЖић™8уšHœ$^3-Ÿч‰-гgБˆѓЫqz?љ„ј<ѓ8эMО#^}Ё™l0."џЃЉяі2№ь9pvoъ[YЃt-ре™Љя ѕJIНѕ[ЙlN™чР‰Ÿaxp˜{ ё0<мУ#Ъ!љпc}>ˆДTˆђјз:Ў9Ž| ШЂt<Ч}‰TрёИF‹ Эћ4VvХC F>=D.'GмCrЇC—m~`Q5џлœnŸўUd‹єw›еЋ4/бјц5]В?h%З:ЅВdгим’<В UЩ-^ЊKОc\F1-wЇ!йыFwџЯYНх'š‘­_—zоЏяHОллšшMks’›л­ŠїХьхIўh` л0р#€пGRЃ’І{2.–В_ю ЯпXїБ.єМ!яДэ@]Їзhijйe45›Y]Хo§ЇЊщќ™9 pHYs  šœ IDATxьœЕЧgv^Ѕї"НK‘. EЄwІQЉХŠ" Ђ"@š"H“"H‘о{яНїн™љs9†ewooяnяи;&Ÿ§Ьf2ЩKђfцЭЫЫЫ/ЊaŠ,XА8`q  А”Zд‰NЇqъDдЫ[%-Ф:Œ+—ызbНZЋТИСЧ/[‹Дзлke h Њ;9~ђ^xœCХжПџкp8\3шЦ9г%аW.7ЕжЏшЧ›ЇЎЏ\3јзњѕдПу5Ї>w–3S’‡П ‰h›qу†зЬ‘M4юзќйRVў˜рЯ›іЪ Z­ŠZщќЮКUѕП†W‹зЛц|Љ†ГФгЦэлВ”qяžxN.]єJФ+Џ9}$: d6ЮѕšAымъсЫг›.жЄЎзœVbЄ8№јeЋўСЛŠ=ФОq_ШціЇS&ъѓf{яƒЎыћ(їюЙ_M™JалMцКч‘чсQ№ž;вЉЖ—‡œН#іcW•"Хе&-е)"MШ[cлfуGяп oй­Д˜т€Ёiz‡Іjзо!ікwАЕhЫ)ђбk}соЕзѕ‘Ÿx-т–.З|Q=Е?хсCЛ№_%aBЕCЗЈГЪ=фРу—­Ъё#J†LjHR‹=cћ“š='qуж-­wgБ\кЫ5ŒЭыIбл6цЈеЏf~№9%ЈŸS3e2О§JžšGДIЕЁ§ШiмИюЌQЮXЛŠИОhОіў@YОФYЉ„3W­]уќ9‘2a,?­k§‹8•СиК Ф8~єAТ#џњЛoёАGЊqіŒжт%:Ћ–жџ§GЄькЎѕшЄљ™ГT>gѕВЦЮmВАўѓїЮ ХјЙЉЦЦўНњGCŒѕkЕўНЩщйBYм:ЦЎ]UЎ]UГdЅ.IдКЃэЃ‘ЪНЛœr[ ПxhпшШЃхvз\лfыѕ_JуазDпДз;шЫ“хeйаuткР>њ?K‰k uЩю,šƒGTNЂˆмќ9Юšхн;ЬZєЏПрЕтѓ`І˜ьZЇjчЖК/‘шљŒщуFщ?|ЃuhF-ф4ю†vйу=5 >щnУу к„qF"[iг&щЇOšqvmуlгHпЗ[›5Эёt:§ђ%§шaGк}ч6ДO3›і§XgЋ†њо]"ЯщSЄsЊ§№ˆ„OAлјŸЃX.ђhЫ—8ЙђžШџіыкwcє“ЧЙг’Ў_Мр|ЋЛГi=qiи ш;МЉмяьлCћі+}пG‘ьк’\ѕ ЂЭйSвxyЩQЏє+—Е?~sфIЏŸ=ЃЏ_#ъ…р}Ю6-^"Ї6џЧ3yДЅ‹є]лх‹h3І˜”ѕ{їДoF;ъ?ЏŸ9эЕ…fN+ p4ЈЮнwщ+nж­[ВF§њ5GОŒки‘њБ#Ю7Л:m.wЭЕUзІOжF~ь|ѕEвѕЛwХƒ}ё‚o Tчќљ!ЮУЃяоAм‘?“і§зŽхx0є§{Х“ѓыOтRЉ|ŽђEЙЄ_П–mтxGЙТњ…ѓ\ѕ ЮЖЏ:^ЌЂ;\ђњŒ9Нх@с˜;K_§xPЇM"Їч[цIљЩLQ‚ЁлњП+œotфauЄK %bєЪeGњ„<ЃВyЮ—k№,ъNЇxoмpmГ”­Є№и! E$TЖњІ HхN‹(з†ПяьжжљЪ tT,ŽФO|Ј<%E?wVдx§’бйИ)d+O9ЂY›њГLq;".9S›’qLП "Г!ЕI?йš7Э QџoЕуй‚DœjkcFШlкФёtDЦУR~›ъlR—ИзКцДт1Эф)ђ‹ћхШ–Bˆ›ŠћђЫGЭ ВjЅ#cb§цMэС]sm’”­BЄ–ЮЏЭ›mЪVпДП:jW†ŽƒAUз6кпђё&.RЊ”вІќ(Ћ@˜Ъgй A™ˆlеЦіфq™тvD]W(7^Ÿ1d+b]ё{}Ым(?БЇb$ўиƒZЉЊНRUšСxYЋ›ўщћиА†9/Tkлэ[ъ изm§†h|“CGмЂдбУ>(ЈvЛZЙšБaЃlла1оЮ+7ЎЋљ ъуŽ*ЅЪЪzе •ЄI•‹Фi‰в2‘ЃёЭh%[уР~3ХŒ0PЋЦ-lMZЪDa4ШWPM‘RžЊ9s+Я+ )щ3в ‘˜,ЙrчџЦ‘CЦ–њ˜"‘)Л|EФ#ЧМЕ№}ьVBр9 &MЊЖhЇДh‡yژ1Yч ЕТsм>eЯfТъcЬ~х’КеD‰lвћѕ”?9}S  eяNaЄ2 Е^Cƒ‰MUUЋжU?Њ–{h•œO›гbj‰RfФsuїŽТsž5Л™(#Цц њћmSцЈ™…Ёƒр§уBІ,Ёз%i2хЮmпoYXЮ'ѕя1ЫVуў}-зSіелемyИЖЪU•ж•Ы””Љ”ћцƒjВdЄWЏ( љОG/ЄЄоП—š-єб‰ˆЅБnЕqј RьЕ`a\ д*еЉ‚ИБg—ЌЫ8sJg&VЫПзANйі]єЩБœЊ)S*ЯП`ŸєЛЌЦ8sZЩє@Ю†SГ­V]ЌЎњЈOхuпD]%J‰Е\EфЌ>lbшjЃцЂlС"ЦщSjТ"~pŸњly!ЈЊќчhŸ<лј{жЏ—}бПШd3нИvmРжЛŸ­ZM31МgLЕ=,(2Gє–™ŸРШcžЫb*%Qџъsi˜ZР?K•Ђ%”ЛЬYYSЙ%јНj•ŠѓФˆ…_8‡œjГ6JŠ”‚!" BЖўіЋZЈˆxЮ*T1&Œ•*€ZЋžБтoуФ1Qѕ‚?It}e*ЪšM-\ )$ЉKаgў MћˆБЪэ[Тљ1є'>ѕ9rŠWNј№> –} Л”%Њ>їМ1gR•ŸоГ“>іЁ€CB„Р%›-љ­3то]Іп•Б‚`Х'„‘аЊЦЩуTЋџ6•9Xёф<ИkсЕ…y0уЇoхе)ˆ‡vт7jЙJjКєJHuЕbЪкjзE}Oaё|ЕъC)љАоЌйеž}•ГЇ)?>LЄЉ=;)3ЋЛ›O,^ƒў>c^п2WъOrќБ[C„ѕНJ)ŒŽъeХs;;4“Umхr‘XОЈ#G*-tъ“Іb uЮ†ЫlЖio•)њ–7х\V„„ЭєЫЯ(Ј­X*ьЊчЮJ"ЮžЏ1НцЈU ƒНОc+‰То:ьнАЋЁsYФ…MYЏ?—щ"[у:аqћ1“@a˜ЋZкQ 3гeЂ,іжPK™ˆямц(šSD._rдyЮQ(+йАх™&Z.‰ЋЧŽˆєˆ{Ж04‹uˆ%0Ум&жRlєŽВ…L+ЙѓУ!тЩсЁ-ž[_Г’жИо5ГqвоjžbИпХ ЄјІ o\'r=,rОелН$ЂŸ:!*-’ƒЉ*gѓ::Jш\–О}‹Ь чВˆcџeТ ;iXAцп<žX9УцљŒacе>& вNчЛo ‚ооS™ч ?ЊєџБZDŽQnоP  3A†ЖIј ЂЎfЪЂІMg6’!Œš*Еyъ;e xM)зЏ*yђЛЖЧw]ОЏтІ=„-LMžмGNС Ьv(ЇOчѕЬ&|xяпГ“К…žеY)>8``"?|@I•ZЭ–У5›АubJЪ_HŒЩBƒы]sЭ^iџц'§­ю!%jэH)[ŸjЇз§%X -пдŠ—ВџО(М†йЎRђяЊ•З8р/Ьx˜pLёаЯDŸ=CtівEуп‘юЕ7‚‘&bŸБ$[љфкzѕUK—“-aU‰mќ/,ЪтдbЪ;œOЃZZЁA#Žƒ‹Ђ@ЅЯ˜Ќ”Гl!=д-_fGOм)‘~џžжЋГ3&Š$ўёћ4cЁ@DѕDЬ"Q_ќЪЃР4№&7^QИа€ЮBqpОPAŸњГ Ѕ{C$jZOŸџ€[Ю’yщЏ ю‚щХЁ ЖPу:њ?ЫИŠsўо‘ЭђXАpъ„W$-Q;އx\vj’ы…5++м€В<ЁЇ6œ5ЭЩS [Х14ˆВ[7Љ ›pfH!Kdџ' ZUлЦЮr…ЕaƒФ мЌк•8Šœ€cдЎ,”_‚’Ќu `},GЮЇє kНVф 1хЮ P Зgну tж+/ш‡hsf д•{ї\‰{тNiЭХGкљоѕоO(І†щ э‰хЃ? •ЖрO‡QЋ’6zИw..ž+ ‹РбШš\ДЧ+"Nн5+€nХJлrы–+5V%р†ЭЪ№h1BЃ+ ЪІGДаyqHyGвš=ƒ њІѕЂЂl)ЬѕЎЬБтСУW ,ЏаSfSyД’G™œŠXGАfЅX“Ик§ћЄsыХZ€Œ‰YVР*‘aѕ?тaцсoп” k-mР.žЭКЌH@88XтŒ{lЪGnМќеЋF\!ІМУљ„#[ѕuџJаЇБJѕA№Š;%dkЎ4aјi,bЁ=gЯHйъЫ‡•``ФI’њц `zEс ~€ЈMћE@zE$*’аBI И/жzЙRЃ#,E"uћбАыз]eЋђDЪVO$­7:ђ=БHЬ’­’С|4ВМBOљhЙЃђ3b…•гщќhЈ—Ёp—RЖ:_kIA}гЄ;пHœOЛс$sџоŸ№ђ%”­Kс@lи№~ђ`эHeлŽНuїIл‡_(цФН 1œЯC-неfџtОАєьЙ”џV›yМуNБвщйђaмYВ)iв*W/‡y€˜%†іL lZЏ\8g?Цв™A-Y† LњDhpў0Д*[Г6,#œ.Ј&lЈWРЙЇSoлHњsа[ЎЩaqWф!З‚žHZ+–<\аUц`‡ЂVRаq \ш)o- {vЅf|џЕ€Us1 c^JFC!жl/7Я[йВСXЕи ѕЉаKтВbŠБ![Eл 3 џЉiвђѓD\йBс|D„р чК0Wl<Хѓa†зeдр!ЫЩL6qЇТЎмЏ”и(Цх0Р70)dД9єЫ'dп~іЧигBHL•†šюД[О‚ц6D:К3P,сuСѕJЧbлЕ (3і§gэ3џ’5К푇\ЏyвД‡ˆ6Шp.Ќ§Ў%Ќxаr@<ЗЇOЪц…Рf6^џ=tkпnДь_&nќѕЧУ}e< 5T9аЇўЂьл-у&)+Cˆ%йj{k 1oЖБњё`mЧїзGРxdїМУљdЯ)хВ„Х2aќ1SP;АЏёCP5>к`PzХкЕљЁэOњФи‡@оА|аЪe a1[Ѕъ#а]НЁpйъдЃU<гЬžщotPRІіоГбfФЄ|тхKT!PFцѕЈE@Ÿ3fNэСxўœ№ˆ0;ЇOњN„—СJ є% @z —р ,ЁЇB —І$Nl_ЕХОn?Еi+а‡а_МVЄцШЅ”,c0ЗiГЉuнНБЃЩи’­5ыињжš7Гс'ŒГOыйtЕikcыfБчk…ЂJт$jѕZфБuьЦЬИГt~†3 R›ЅŒЕџ:+?У^›@O‚№fІ‹"oв{ttV+Ѓе(GНaЈХJj›Г1'^x_™љВЖЏ&А%"ЛTi‹й:uW‹—•U­]Oc{Œg Šнйъ5DібœsъЪƒ ЖhиЋV:XЎЖ7ћc§№к…йў›дD7[ДгЊ•ЁЕbзЌ’eєџѕ{˜/’1л{ Њ‚ыЈх+гrЏиЌIŸќЃіb>6^3X‰т€ŽОзklIA,NЪў=ZЯз0ц!Ј•-$цєЧŒАѕ|'М"ЦŽ­ (РеkЉ`ё ђ{Ѕ™…Р ?Л–ІЉ•Њ|B+ФbЕѕ“ГЂњž&О™зR˜лХ|hшЮWf@нJс' і:}ЪoаЬODag­G7€ѓEGЩ-ђ8і11гиWCфХy3щˆнeЎ]5OйЋW\Oe\ьSК;KиЉЗ.x–"ХЄ&vС нєEtwХЈСКKх”БГO7mіŒ№(С эчяž. і:М"Vzd9РоYŽOГЧя‚м/ѓ1O#}—ЧЩwYџЏ2Щ)ІМBЗвђП”•3ЪˆЋ8XЮЬIэ;ЛbFі;$іщзгжЛ/sP‘-ДљqhеЇOЖНоX|cэ VЉZЂ=› œўљ‡˜дзоАѕxЫмxЦ3Ї•)|к{vТ/лўыЇ1#E" ™йќU7ZIРОщ€ФЈ (y‹˜Ф’MРKЭбKbдЏ$I-wяи>Щ>ZD‚Ќ0цлkЏ+–(зЎиg-є-Xi;'ћЇЃэ+6"‹ЅЕФmђ ы_мhЫXЕe•Ївичџ ‚Up-{.Œ іy+,СkЯP\е[cAONEbа№ї™oДНё;|X/aдn=ЛЙшƒпЦ№m“ЛЂEŠU*юsР’­AtYl‚е?ЎfћАќЛBHX|б|ю’№Иœѕ ˜ўНРйБOœц6Йœ ЖZЃxœВLЖrБЏнЩ–tЯ!-krћО3^­ЈŒГpЗВНи :ь`i€}х–GЪВ œьпўЂukg;ЯАФzе”c‡элЪM[2ю;дD ;wэC>ŒNл№ївъV йqд$тJмжБЋVтivЎ`їют/aћпЇЖ:ѕ]ѓDГfНDpMзG~b,_bыё6ІX5IзЋVм“ “išЉe+к†%ŸgЯnЬВGKіgї\Ѓ…п%hUƒъŽNб˜?bЌ_Ћѕя­НоAѕ‘ш>uЋ‚ќD—Д}є–zЧ j§Š>ŽГfyWЬSі—зzwa]р‡Zгz€cсњЪ.‡ЎмУсф)фQІ‹=З4V4@+,gј`BкЇя -SF…}<ЈШ "њЂљ‹цyКњ‡C\ЈЬe+Eи€А бјvт4а—ž-Шсб ?‹т uoЇ?жўзJ[уцёГ“VЏЂЦ({oEП мIX@TМњ"д№0H%x­ВЏ/‹ыЧŽdџaJРLq… rщыdоЉovЈЛw—[{Ч *•э…Й$ c€}9{F›8”)§ТyQ№Й’l  *•Г]sЇnв @[сxЈ-]$нEI Uџ­@*&ь:QhQCпЖйQГ<а-b‡p`ЋB7т[ЛЁaБi6;„ЁџЛB …юЄ-)ptE* I8'Ђ§њ“№šЌXОЙх1 ЦDD€€д(чxЁ"‘˜ i T іЌюљšмГ:.vСjsЬq 6pАТkН”­BЄ–ЮЏЭ›mЪV$ˆФЄ Ђа,<ЋТцWЛ2—•J€ Ј§ј­€ЌTBЄxХ *•‚В ШVmм(!aY ёћї…ВjЦ чэызиф]fѓz Kј‡ЄЄЖhОзl2QЌP…€*ž5+h“'ЅEУ^Ыљr Y-7й*гхQЪVgЧц@ёБqЫхьаLGяŽХ –L§ф:gїіцЊ‡XЌ?ИЊŸУ™Еi“‚ЋYVk‚†!QгvXJM”Шіё(мјэ•ЊJВєwЯцТjaд% f…pЕ•Н;ХІ[†СRTcСŸLяАXPdƒЊDЉ0RŒСЧŒ0TрdЭЎ&H`9^ђŽ2l ƒ}VЧšй<#bD|§‹hХЅ[7…Y V]Яla)‰“А§ bіщю]3лCoЧP4,џ`to‡›™=#Жo~–ŽxЁВњVYЛJyР4ЯЬOЭjѓЖj§FИji•ŠлОžhЋV3рЕФ ‚:cš/йf-ВUy>N48Ю5ђђхЫ‡>sцЬЙsчnмИЂ!EŠ™3gЮ2eЪdЗлƒЙ__ЖТ[­КX]ѕQЌ…AM™RyўћЄпх)АќŠ аЧеЄIеЅє‰уС%AЮъУѕЏ6 5u…bP  ?‚+Œsы‚}ђlуяZП^іEџ*‡ZЖлЬ`оЅvLКія&?ШјШПАЬЮžnћdДš+7ŒЃGє~=иŒ М tб—ЋWьіВвIsнЇыQ€"5gncїNY“qјр#Uњ<LТfзv@g|f ќE аі>зkззЛЕQњБЕыј:AБOŸ>[ЖlYБbE ˆ=Bƒmгє}РIa9џ#Ќ“hpusпО}sчЮ]О|љЖmлЇyѓцMŸ>}† ’&MŠЕйlwюмAкž={–уХ‹ЙZЌXБ*UЊ<Шњc шcд ЅM@6€4–Ч0{ы†ЕbŸ0Ј0zЮќеёlAaіb F…A6t8†-•qН\Ž­њФй­­Юў+КюlXS›7‡ьŽRљРœ–ЅНыcjmвТрP,—D Р(!ЭО2ЇлQl+№L3њŒп}ЌжwВхb(а”и_рщt2. Џ&@8[бlXЫJsшш‡qрьо.B›  bЯ‚ѓчиС‘%™4;˜­Šх–kaю`ЙA…Щ“'ЗkзŽ7-WЎ\oš0н№Ь=pЪO,СЋWЏŽ3&wюмYВdсЦ§єгOџ§їпщˆТ‰'јvNœ8Б[ЗnЅJ•Ъ˜1#_SЄs№А1X$НъмS~;д2хеЮ=˜˜˜ x*ћ—п‘nТ‰8pљЪ‹ЙrЕтsJžќr‘ПTI’иўї‰PxэvЕV]pЙД†5ѕOпW{і• №<Šї/ПjІ‹бqн—…Y œ€OЈўёPБ1Qїі`Г _бGd9`TЙ* _ W Џˆ‚–7ƒЦмWБœ(’?„СŽЈ`L\ЧMи>wЉўйњgУBmЅF јjжЌ9a‚Р$%ќўћяuъдЩž={ыж­:DЪЭ›7ЛtщђєгO?ѓЬ3oОљц-XВаЪМyѓіюн›(Q"yР#nњћХbbp)­ќќѓЯшЇ ,јц›o6nмјЩ'ŸдЊU‹л!m4Yф)ЯЦаЁCЙуП§і/eљђхлЗoVaёXШ№8зјю0" лц/d.U2…•KЩ’љ(Шр]9t@x}fЮт#›ы%БOСн;јЙ&F?ŽХ@ЙtA EўUMŸ!<šЂ fШ^†`N7NŸЋF[еъбlg‰%Nž<йЊUЋeЫ–экЕkїюнiвЄЩ‘#яbєЋЏОzёХ§ѕз?ќpШ!-ZДИwя’ї§їпчэђЌКpсТ !9тy)j)ЂЇеЫ Сњ( eдЈYЅP0›4iТц;Ъ—2 Й~§њЗЁВŒZ|аМvэ–\lИO=ѕY‚ Э>ђGсRPи[НЖ[ЌЮтч˜zШЧ%СKT ^?иdХЫeoI68‚0Х>@›ѕ!XЉ9†}ђBRЭ’ЭіюЦШ”шЩV‡УбЉS'ФkАЕёn Ѕ2ФЛџ>Я=њlэкЕyhAётХПџў{dыќљѓ‘­бpHкГgвАnнК щfЭš…!йЪkР(яјёуд˜тРвŠ)чгСЂE‹˜њvXЌ›7oІeш­/ПT…Ь IDATЖaI`eЋ№ЈЛzеўся§ЗRхЗiѕъемSdqnі™œ9sЂNˆ Ж0АbъyД\РޘmЮ“'ЯрСƒ™%cІ‹Ч ?G§|žчЬ™3}њt Jџћпџ0ю‡„De|,sYcЊEшБp€ю DЫ`ЭKHУѓчЯЯ{Шф/qЦq тАФсG…Й rхЪ &ф)ч]e4GјьГЯd6оеWBƒ)XЮcћVсXmŸјћяП1Ёr;јАaЗaЌЭML—.Ї|)КrхJ>„ŒйљjЦœ`Ѕ"ОВЭš5cФƒˆфqТŽфЇ`Ѕ,КjѓцЭgЯžЭќХi<Ÿ§і~1*z+ќ’ФЬˆwкё(еМ1f$u.К]1.^`c1іEцx]aЪ`ї“бтЇŸ~ЪиŸ7„Dф)6~§њѕъеыыЏПЦІЦXЏiгІhЏЈ' х<ћXНU(ц§†кžЋцY‘•‚N:eЪ”‘#G"КvэZКtiІў;[P?Ѓ3Ђ7лПэАaУЪ•+‡ЂэfI0ѓxј+[с2"уцЉ$m&z­)Ў$КIONЭ—Ї2W:ЃэдњїТЯСўў№шзrъд)ІаO]I1ХD2дLФP@" ‘™гmH_&Wйn2І+Šsє™ТфЎŠЩ[*ЇqЎ 6˜‰VМh™vУО­6Тќ2CФВеІ˜0(ƒзGтfКЋHuћй‚`ЫfJRй0Sž‘vw†Ў‰nљƒ­;1нуЬ)­J)ТН‰Ќ˜ng4щГ ™ёч,ѕE“N|*ЮЫЮ”дИqуa`(O]ѓкєжсУ‡3?VВdšГзlfЂ/йjJO$)"•S‘‚еќЗ1БVћ_§5`Р€ЅK—bРАвpeЋЌІT…•(Цœ2јqвOџўћях —юоyˆBaMq7C‚„ ’$KZІ\™UЋЗjб*UЊTS)a‰ЄœхwћЕ–kоTN{BД9О|‰}њМЈё*>•B4nмяc&ЏЂ6‡wЙёЯ?џрu€ŒаІь]ЖК VSЊтpлэѕnЛїьn;Аc…:•гgIФ‰Л<ђПхїюоЛ{ћюKж.БhзКЃОUГFMl‚HU<CЅkиСšё '`ћ€Š‰mКуЕ5РМS,љг˜бЊSпж+мЕбfцxAСzѕеWqЅb§~ yЇ9їF,кЋouЪЛl…}ЇгЩ‘oе *VxБ]ƒюѕD ђЮЧ\ѓЖЌкдЅJћёпŽљЅ—ЅKт•'Œ M1WuPQжНeќѕ‡}ў 5kі jXŒ6†еЩZЪіЩПЋЅЪЦhEСLЬŽŒŽИž*˜ћый6>В5ТO ?ЯЋfŠйŠв*+$˜EАч…GKЧwЛtџ0 NХ,џFN<оЁlЫЏF…Н 'ЦDYdЋд]}ЪтЛєбУѕлwѓД!~tœ^АuоЅЕиЩ5жбƒ‡8l0“3mкД"EŠC{WрCНzѕX–Э*л№крEЖК VœзЈІщ=ъ№ЈО> Ќшн‚й XНіб=йŠ)@ЊЎШVТќёќ+5,СъЦОMk­ZЛŠЕ|‡рЖi9ш–-оœВлЎоМВ}‹}оŠ'\АrOmUkА‘ж№cћ–xs‹#ь~Ќ:tАЋd+wQ=й!<ОЙc˜ЦV„"йБlљВž_П^љ'6Нм Ошљ)+/QW ш­|“ј‚СРјЇЗŠ9œfѕе*е(Х1ЦмЛo(ї4хк}хšSЙхTющŠf(šЎ8 ё“qБиU%ФІаЛMс!GUIbW’…(Љˆ_ПєŠГНвTIšŒ}бm_~oЋ]/ЦX,„С‘C˜Ј`iPДг3>Љ 6єк–GdЋЌфCL [ Ш–!fЯ›У,|іФй9^Hœ,ЩьƒЅЫ$Ж/пђм‰Г N-3ѓИFўљcй‘=‡лxЭ51jё‘o}ілИi Я,OљTЊЈQ`Љ$Щ“оОu›o–V…іŠA@†ж ЄєџбЛД0WКЖ=,GЙr_9tS9sW9WЙtOЙъPЮмQNоVЎ9”% З"2Е"aS%Tв&TВ%U2$6ВщQВ'Ur%S’йХЦ•‘Ёч+/"U§uŽжІБђЮр€3ЧWХу€8Ь'ѓ‰Lџ8кѕ8ы[kЧŽўЪVФ+’‚ЃъЂК^Лz-}wЬќЛЗю|їПБƒО§_„=[JёG]о{1kѕ7juYіћп2Ч§њњSsFСTWЉцУ(‰„˜Ћ4ж(Г'іz{сАxMєыљЛЦтГЦјCFПmJ‡џ”л”q”й'”7)X}0ExуeeЪQх‹НJяMЂ Уv)“Žk/w04D#Аm„}ёjх№§е:Це+б дEAzdZ<Ј›ыžmНУЋі›™ ),фбkЩšеYЗxݘў#G§9жЬ0ёуяњdB…:•PшО:6Q’Ф9 фJž2љЅ3sЮ“%wжыЖoYЙ)CЖL—­ЇдЕЫз6џГФœљs.šњзч=>ޘ=cхњU—ўЖЄлѓч^xћЦ-Ў"=Q“БoЪŠюмКѓNУо'ј~хO %бы“S‡OЖшн uўй’ЅHіЯœe &ЯЋпўх˜Ж№љ]hњ№J V“q+bмНЋ3кVЁВZО2-7NзкОЊц+ –]Б9MTУ= сЅlПЊ,?ЇьКцзп9mˆ­Dm[!бŒH…ЋѓО6ѓл’ІLYН­yъA”Н%~„Ф6хЙ JйДFщ4J‘”Qдdй)н6эOЖ)дj”ГO§CюНІЯŸclXgјОЛ"Кѕ(NЛ37*ŠCUьмЙГwяос5јйŠt GТBšМ–diVї{ nбoг?Ь sОŸ•=_ŽOgŽЄpу цNќ}цюЙ‹~lпб>_єEр&JšxїЦ]ШйL93_П|mяцн{7эN›9]оbљ?}§CEU&mšёTњ4Jў8ІпHŒ OАr9ђхќxкчйђdџМз'œы8єрі§#ц|YАTa„кЖе[вeIŸ9W–ї~ўшьёГwoпAЖ6юо Ÿ&CZГm1‘Ÿš§P…Uh@Dhд‹Ё–Л“=|Рјє=-$}Юbуо}НsKVvкКПщžЭяѓ[NуяsЪП•ПN)ї#3ф/›јЪф7ЫO=ћН™ьТ>ЈVЫїmbН\lcцqX™tд< 7‚9bЩYёУ,л(‡R!­Q!mT$,А= ,ъ…‹iѕŸg ^І,єЮ­]SZuPђЗњ8rС›˜БзNiol4“-нр NiсUіˆl%RUЊЎЅ:^ЩZЭъLёгW}П`v€<.œ>fR5E9YфЦеыЎeЧЅЊ”оГqWОтљ‹–+~љм%+ЂV*Є'Gz"X)RЌМИ9y№И”­U^ЊЦ%“дњ%k‰пЛ{Ÿ#є­оnїѓ№‰ƒšѕ Iв№ЕЦЯжЕ—Јј ?ГHЬEЄо }ЉЗJюХ\u1GYи‡{[ЕW_T€J˜8#ЪvfЈ–ŸWў:­Ь?ЅDFЈ>ьNm›6jсpќ2ѓЗЯч ЩыєTЖlй\нƒв&ŠмHџТ=хлЪ”#JымЪ‹™ŒТЉЂbŠЕ5k­цЭЧЮZЪ­›Ъ§{РпыCћкЇЮ}иЗИяŠtтfлcЊеьћт{Ÿ‹Gь­Rѓ’ВеВс5 еЌзgoэоАkпц=фС …ёщ"yц^ 3їИ?Rek–?sє4 '…ЪсЗvбъГЧЮ”Џ%џSврl* q•rL*g‰$Mў"LЇ!]“$Oђѕ€Q[ЩџRЧW&ožёцяф)šяЗqгБ'P$ж‚T№]E*м‹ЕкU‘ёпjeѓzєmAНUT›Z(Š.ёяпRооЌќUСjv лЉe“}Џ?ѓЮ•їŠэАb!мt*у(}З*ГON=JЗ2E*ЖdWю‰'™Я•БjЙБCЬ1ФщРFгРBЧщ.ЖёlF€G№Е>Ш>"[e>)ЄМ№-)ž­^Ў|эŠLпЫlЅŸ/{xзЁѕЏлЕ~gЛg›є%ууˆ…рГ5ЪпКjs‘g‹"[7­и€KbЕ†еёјЈѓ{˜M>бfЗЁЎ’юZіiгВO[dєД/';юнo^ЌбЈ>Ÿ•Ўі,J+™'ћ22ЅжЂDуs'Уuыѕ$Е:.Н‹…`(ЅѕэЉмЙж$ьѕkZ­ŠFшV‘jо‰лЦЈ}ЪЈНЪmŸ˜€‹[з6Эіw/кћвTЧб!| †lgІKqDRМgNk‹‰я“юнзЦ<‹ЃVЭ3oУр,ŽЖ?АЭц3гЊU+0k|IмeыYі!7{ љ(Cп1ƒj5ЏѓEяOпmо7]цє]‡ OD$іа^uКЁfц/Q UКдhEK.\ІRвfNВmћuЌкА:Pƒ[і?sьtџБяц*;ŒЎЧ_ыwкCgтGпaУэўAcћŽД)нlє;# €Œ&;*06YЎz |‚Ч_A SдЮSŽ~X žD‰†`py˜шG ы‡•bШј€‹[v-їuЮпуќЏїOˆqRLж,|Ж[љэЄАžGЂ.–?FaіЯ\aAё­ѕk"A$(ГВзЮ… ‚ВiБк(lЌьч†ЦZЋV-п?‚' ЎXШХ^›W,@p7;|SqНzѓњMцЉ2чЬт:Ÿƒ;”?SіW/^Йxі"“W8ИвŒ0Žл@†l#[*BВО3<Ћ›1cћч0bТƒo{’$I fуŠ‹+N!Рщ+'މž&KŽе\­лаіZwЕ\%п}їМ:§„1d›_žže]SJЭщ1}ТCчзK2ЮМЪзПЬc”O˜5Ÿy•ЙЌпrюtнlcьcє>ѓz#јРŽ-ЃЄэеиЙMџ~Ќ1kšА^ %J…,§/ŠŽb@ъввЂE‹(7‡ЧnОМ qwш-[Ж`№ѓЯ?юzk„"Ь€гU–\Y]+EќЌdKюЉМEѓEAD2й…Rі%оgаЇ§Ђœ=-еЂ%lУПД8oџ~r+Œкx)‚е†ŽѓN—Ж{кdыtтчћgјS$ЪyNпQ6FоcU-ZТўхwіƒчmŸ c|АЖoб—-Žr3‚Ё ˆškжDKћž”­вnш;Зuе7"g›ѓM+VЎклuЖ>FЭѕtєkKІм>‘ШR`t9ЄGЧe/ “} …KзЂћ’Ћyђй‡eЋR=†Z;dёСjжЌК^@Њ[МxqгІMgЮœљўћяГѓ6ћoГ” tђфI"}ћінМY8‡Ќ\Й’ћ@А‘ЬЂE‹dэўљ'sі>ј№У_yх ˜PыпПџьйГё‹BЛD@›sEž~ ф›œ’І?Gv]lзЎ–нm{ѕъ…ѕёЪ‡;_a‰ZxэЪ%\і‡T\Я“Rc'œ4b385}жIuшŽd8XЧDНk9яА~ыёcХDя"KiRЙrхŽ;fЮœ9ВeнђГЪ‹эќЖoп.ЁŽцЯŸЯЖ†lOЭМ\‰C„хЄ`чЅ,zткЕk98q"“H'~њєi  YГfe„Е­[ЗўілoщвЅcSф2#›ж­[{Ѕ€Я–_ШbyР­mўœ–(Q‚Я0ƒѓцЭ;pр€зљ•‡zЋIбЗŒИrс2s8ŸtџРЬЯzџnе;šЇn‘е­tƒpЫс)KП^{Ў­зlGїn\ ўб}G^ЩWзЬpўдЙВітŸѕќиLi^ь•лї5/оhя–œbіЭ7Г1ё5r№рСќIbOuХstЩЃЬu№Ž(ЎP№чF”Mzѕј‰Sўф|ђ,XpФˆЬ’_Йy#Д7eШŒ>Ф{І"Iwяо§эЗпцЪ•‹МШа *Œ9’ј˜1c0G `тщ8~ќx“ђї›oОСЯTІ (бGЁжЉS'RЄкы•B›6mЛфyэЕзPM‚‘ŠАп3tелkA/Веk>ЗФЅ3эйДЫ-быщœ ПяX9ƒБW:^“ІHЦ5 ќЬ § чйЅ3›ƒ‚d)“ Ш‘y63› ,ŽО№ТЁ‰ЂjžєЛ5|Уж]д+џ­МОIМЦ\(—ќЦж›и3цЊˆs”лЗoЯ`›ЃLhџ;UЉR%f&qАЩŸ??ЅP'нЪ‚эO c№ž={ЂлЧBj*1/М№€9rШRxь N2‹^ІLR$5пdС(Љы‡~р3Ѓ'‘(Ъжз†vўЦGf'MКП7ГIс—јIиЊщcІl\О~ТАёў4Ї]йцвсєгз?ЄŠ"Ќ§яXБ5‹e/žЙ№f§7ЊЅ*пђ™ЦbAP{sEёЎе:˜ФЩпЗб› ,–!YЪфIS 49>”­8Щіўќэ‰PЕЬfЪ_2?(j§žыЖюNrvw‰d.žѓ­„чmї­Ю ЅЭ:ѕBLЪ№„6Ѕjђ+Л6Ќ;uсr@{ˆс~„Y#)гAбь "хuL q)™зBSцXНzѕчŸоœЃЯž§сRx2'OІ9ЙRѓM!šэЇ8ў—ьХР:ORск[=ГКІ4ьќъМŸчЮ§qіЫ™щР`ƒƒ5pќаєYвhњNЊДЉыДЊПjо?ež/[Нё пўoьО-{Š”-ЦВT.uжcч;ь!vЫlіN‰J%‡MњxУвџњ5~sњЎ?юоОЛrюrdnлўaжDpПЦ}2хЬRЇe=ГF–УЖyЇ}’dIкє С€т][ђЙвдИxъ‚r5+ЙХ›mRЄNС1хS)ЭВV$&8АiзLgЮ?_ІдGš‹Ž(~Й=†T=~SыПнОщJРhzж"S $Н—ююЙП—nКч№ЅзЎ];< ё#нœ8ђьЮџўї?К%”q1Џш1„63gЮ}ћі1rGЊb4`˜}– ›фцшщйNR|S№Z$В‰ 4€X3€Цw-Eй •~_ы­ДLr3ЦNkђF‹ Е…лy‹о­ўžБшХVѕ“$K VcvФміЕлP!Сj6№ъЅЋ[VmbСыёЧРВ5o,іЏжš>цзеѓW(Y№ўнћ@jЅN›{ЋЎщCZ I2`м`Г:"0ЗrНЊDžЋ/Ž„П&ЯcmщzГоыОFLХ:•Й$š+fŒ˜bЖ‚ЧJнЧ+'лuіђЕ?//]8oЁь9ї8R_М]ixсЖsш.ћпчypc‚љ“оЯЌ]оЖuзІѓЋЋђ!&Z<4Ы—/Пwя^f№db-9єHѓX\ЌЋhЧј@ƒ&жќЅK—2єfћПвЅKћ_QxЄ€ц&bDЎRЅŠџ=sтёš;wn Чˆ]ЏFQЖBЂx…gРёћf№˜bJHŠ WMмАѓ—Я&rъt8sЬэZbtљьЅhšЯT.•:]ъkЗхкэƒЇœ"Їi ЭњtЖЫч*АVI‹эЅГ&NzЁЋТяJŸ8ІюEПў…оАl=+Žn^НБfСЊЊ/WwЫгЇ ,№бؘЎ=Hшoк}Pн}АDмГхИš ео[‰и Всњ=чgћьгћ!Um6ЭžШеHХ[~†!JЁФ7мЙКcѓžЭcмгЯVХ‰lпџ=“ѕHНЖ–… ј [YЦ>еаgФ-QQPqДŠT]сQŽ2|˜ŒŠІlЅ=ј$HЧзЖE]ЖB0І…_N№`}jђTЩ‘•шЊ\ЁŠqНkM џЅl­нВ.š,ЈиhЏ…Ÿ- ирХ3‹RіZПнЫЎ‰Г vЪ–™*ДžњхŒnWЭгЭџlфeиЄOd Л€ќћВеlЯA–nнwDйw$mЪd% хIžђ^‚‡ю%a _Aя:ДялЦ№CЊ†втсiqМrмaЗkYы9BnЉwo^Пt~ѕоУО-ne­S\JYЉ…О†&СRoТаž sт%J0KЙ:™2ЫЯ$>є™уb|ŒоŠ<=zє(ОV&6J—а`g lž2H'Шг№(0{†ЧŒ+еdГlд"4ег—+ZВ•Н; ю2fРшg*—ЄMeЊ—[2}!†NтУ: F}§ЃоЛ{wю‘RuŠЇRЁHОѓеРД™в};єы•KРš!kЦ,ЙВ,›ЕЄf“кltˆ‰ xХgэ<ркIdqтЄIонŸ`ъДЌыЙ—ЬЬ,ж MkcК•Ї€ТМ^Гѓ[ЗБKИRГтБЬKзo-џo •&M”АагйŠЄЯ`KšтВ‘єЌ#сe))GНўSŽУvкќж;§э [УfHddЙ›TЛхМ}уиО“ЫNУ—Ыпђ‘Я'=UмЬp‘'t%0}"MŽŸ|ІЧЖ‰Ш;W‘G]ЌˆN^)№=6…utˆSŸ\PDмˆDзжЌgЫьyГЫБXЧwЛ\ЛtѕхмЕфЌuѕвЕЖ§;Qазу‡|-wФ"Ю†.ЈЎyŠф—Bб‰tмѕНіƒ[•|Еm™f‡vУBъжJyЪœXЙ*Ž~ћsЏWб”—ўЖИfг‡3 ХЪ—Hž2йЪЙ+Мц‰Мœђ§Œ­А‘ЗянпДч№т•ы.\rpЭ’д'ж—гU9])щхgSмЮ•TO“Pй“ ћ{;рВšиЎdLЌфOцЈтf…DЫЋ'žЙГWйЗjУђE —,џ{ѕЦ'ЮFSАЂ^aйw Xaы…pе$ђЮ;я vEШ–Јe0kЁјќСЂ)І•ph7Љс&ѕьГЯ†wеЬй3я8 р…C‚5Вэ †ќ˜› .ьж’‡8XШGœииУьУуЕУxчF  "@RQ‡ыЖлЗoоN”$‘яЏ7к%Г>ЩыжФ =e ИŒGx“р‚й=џqАx9ЇL™ткAМšљх^ž]юVŸ>}pђ:tЈkž@ХЭZ ШЫљыЏПђ%ЧЁФOухdlЕaƒ№ŠУMše9ІŸЖg ›{§Q+g)‰„dHxрFssЙ/xсЯ*xlhмtж˜BoЁ7оxCЎV@ч‘šf-ЬЁSDЖ/ЎD>EЕ”ЛоzНj68Rž(&…pˆTЉј™W—”с…g7-йъЩ“XM ў—3Vй|•94_вйчлŽcЙьЂї№№сУh(Ж2‘odНzѕ­ˆZsЮ ;99Ÿ/9‘Х|л>ћь3тLŠ`1Хх+?ћƒШ815чƒŠ-‚ˆзЋ2sdшЫ|*"[*~чG_algо;зЮFк&Ь8XSFў\>aЩi+UOSЉjЪroдъ‚SН,WЖњчх\цЄqЭЕxx/'šш і7&„/'цTYdрРчЯŸw­Тыы' ЎйžЬИ=Гƒл. &~‡GŽсР*эоНЛcЅЃЗk"ЅОўњkY„б‰D-13Vrьи1yŠ–ŠЄfJeJ%<Џš#СЌЉ5Q‘Ѕчђ3 Ћ…aŸз–GZЖJ*A‹ƒUщХЪK/­^vyѕтѓ+o^Нў§ћуhpœЦСzь/ЇзчЦ3ёОгї’Яq#хіG–РИ5UƒЉАM“[&ѕMЗЬœтl<ГOФ-RЄых=ГЙЅ %БДb7 `њт‹/Ш`жtєO?§„:ŒЅ[-Y(ЙХŠ“VQЯЋnФ§ЭZpH:5–VfƊФъ:ц№М^-ОгёГіъ!яЛT<ОЪЙ_Д(к[ƒыьё3рђІ`йЌПGЯЫн f,^N‚љ2_СŒЏ гP™2e2гЭˆ|9y‡™_B /Ї„6ѓxFx9Б ёrЂн`vРП‡R*хЩ0uUH<[9Z*O–чrІЏз(‰ЯЋL тдСJP”ѓЊщiЯ,%nЇЈЋЬ+’Ofѓхф>q№>˜о”ЅXŒФ-&Ž5Ј(Ьј—цT"f-<,<Ÿй3мЖИф:J”Фэ*Ђ0eўOл<ЭVQ з‹0aЄ,ЖЏ/‘^;€НЕV†ЊkюmЌпіЮ§wўЪЙg_6ћfљZхzџYуЇЏY№яŒqЕr§*@~аihžbљШ0Ђз' LнўћЬБSiVэu_-и`й•5ЎЅKеіѕкОVћr-ž]!qАЦќ2cіLїюм1ч+Ok”й7ь­SFўRђЙRЄ\ЙpхРі§=‡їyЉƒАшЧDˆўк­тцёrђкxЭƒ3–ыЫщ5["пЗ—“ ЎЕИОœne§9uъЦи Ї‡Я^эkъЧBA“'uђФ#ZV­їtи|аДыБ5Я?мHЄыТckDpTŒ`ХeТЋ{€йР‡zЋ›Ѓ%Їn)f B,VЈtсІ†-ŠнЖfkџЦo‚ќтCЛu*ВЇЎ\ђЭЎШR6~НФ”йж4ЯTyLšЎЕ˜јэцеHEBljЇR™ ЅвsзтˆЉВA˜9Kš”C^)_7Зјћ№цр!Ў%[ћѕы‡#ГлŠЪ‡lz{Фо*Ѕƒџ2ЌESьнМGR Pз%чWђ[xfљшљbЩ р`э\Зmћš­%*—,YЅŒ‰ƒѕt‘<Kц Љm–’pАІяœ Š68Xn—|œ>]јщKg/Гх#O/С7џYРzƒ‡TђЖзŸЭђyычѓfN<­ŠBK<›џЫVЯ5Ь—њ ПЁnЌcЕ+ чЃПн€йИuŠЙ  эP<"[#лI‰ƒ5уk1Д'H,0Sјƒ5х‹ŸHєФСBЅd•вў8€AW,2›8XФ]ƒ‰ƒХМџ…гјЙf#Ўi:[П№cѓСЛУЖ.sИЗВжiє9аІ6/”і›V•оjP>U2П чЂ_i)Ы•щгVЯRЏXхЌЩH6рЄ№rХШpВО ђЖb5 лwЖјz†ƒв`Х\ŽA Тnњ’­Ёz˜@ИОJ№р`ЩЎВgСsЩЪђы\Ѕ§ѕ+з?™!МUb(Ф9Ѕ&TK‹!nИ’-š.ёлГџќZО/WШ•QЬЎyАЉjе"Й>nYѕЛ–кKŸ­ЈœŸXvŒХfЫЋшgpЕr+р К’["Лј1Oэ–(OЃжЏЄ<™cў-Ъ{ЃzŒ+)|ЬXыШT!BUvъс\ч”g’:І8РС"АоЃKЗЎяŒXНQMИ€hBpАјоTO]qЪф)јп09Ы-й'јю?–o–ВD—,\І0Ь;†yдu иGq–Nт з<ь"‡чЙмUи58№@ бx3}И•И•Š№”чс№uЧ'Ўm:~qёЖУЏнŠАHlfрыX kКšХs•ШšІrЖЉљR5ќlR\РYЌЬЬŸЅLP+Яќ8ЯвNщ`^eeИР˘)f$j 0‹GaщWхЪ•СъЧG%ТЬё#ђ”ЗgdюЌŸ‚•Ž?œЫ’\К*G9џCЄHсТьЇт'Шџ„р`нЙЙ-9ЬˆŸМŠ0›”зђHf”ЊˆА”Ь€[OЄРŠу№Y ‘qŸŸUј“чI•0OЊєM ЇыR!ЯŽs7_МЙўайO=Fo­4)’V-’Гp–4yгЇx&cВŒIP[§el„НvЛkР>Мѕж[ИRсй&ыYqЙУЇЊsчЮb| JЬђхЫ%t’‡9>Јxh‘П\ЙrИyБpŽ9z\€’Р?„ХЌ&Њ/:2sж,Ѕ=iЫ}tk@„ ŽlяђhЁН‚‰…gX`˜Ш6&ІѓѓRцРв 4 <"ѕœ<ђЁІЄ­WЄp‘ЅгюЦtgт §u‹з(TIŽ™ЮRœЊ ђ=‘GhђŽIwtі:фБfvќUY )ЋУнIRFŒA z.Г™DаёTg‹—^zI:K’ˆъс†ЄхV—ЄР#^žJјjСД§*чќБeйIнjжЊкл ЪЗxЎXЁь’„ƒ†Ј<•ŸѓЅџtуwЮЭ+7юZЗЃхЭMй*9eHї!HЄАЗКќ№У™В №FЁЂЂШ№”№XАй–Vn)ВЋМЉ<%œJ№@Џ0wŒwмЊˆS”Цt‰дt™’*ќю]MЙща/мrмp€mдъфЈщн ›u x>mjаВэ*Š‘„v5ub{њЄ “и ЇpяНЧіЯча„МТ€хЙЖЦꛉ`BЂоb(РІЩ7е|БAзfсœ\ФЈ_ІЃRёЁ‚GgбїZLj1У`Йђ!g .Ÿvф,^„hV  ц/ж?w9ŒB|АџIќ0ЬтЬ‘А™ _>вљZ№idДaТ$E>EмeЋ)#2 дыОXїѓ/>џЂї№ЗПьЕjтSЉw­кICЦn|{r2Xkя3Šd)š,ГO`y0DїфнCƒ€Ъ2†<ьw2ЮдяžW˜Л КAмd!JВ{FФd\Ь~0œ”=@!EъЁfђ e"к)Ў]фЅуsШ;8 їдИ"#d18"Е)>№` ’Ш€PvЅ q–\cS& a1CБg&Ž(4Ё†чfMŒ SЇN§ђЫ/Б€Хм'“1F>NМЖlnЦp KќФŽЈЗи§#н0™jЗ#2˜CЖђwывmкW“;Vh…ыh,мА ­bЧКm­K6iнІ5:#Ц/˜#НАRЖъЦјцuЙfр“Ыѓ+уPЉŸЪ М“І™U.ZїцЮ•И2p,YВDЪGІЇ˜Ютё`§J(c|јkжЌ‘Фyщ$tŸFЦкЈЂhЏgXЅЮгM”YІщYу|тšЭ3ŽoŸv6Н-aКuыV:8†,>HžEЂŸN|ЦЊ&_a0n˜НР8€j@Кы­ДъмiDйJѕhц˜„АёM™іk§ь/ДэпБlЭђйђцH–"Y›}–Х–BмН}w§пkNљkћъ­Џ6z•чЅцH.ёР1X›теЕГрёАZф†9<%xэ˜8/МоЬ~№"dф…WTТм1Uиe&šQ˜?hLЎ5Zq8РыŠ a"З ЌЈRСФEЅ,WЎ\(wbRЎИ9м#№PžЧ%˜‹Ќ‹с3* Нљ:Ъ \ˆ`ыФ.ЩЈK+7кŸVХ\Ою@ ђ4bЏЄ›|!c1Иц‘уѓ€rŠвM@sgЃ >і|xјќ3уЧGТѓёŠмУW^ЊЭ4€ЂœЭxSEж+Gќ[ЩnLрkIрCŠ‚Рk‰Ђ.у|l7oп|њє™K.žB[НвO‰! BјТфЬ“3{ІleJ—с3ƒ"Я‚1O9ЦMф,У=>Bв>рІTŠІ+O*кPšˆi тМН<ВМЎЈв(>rз,ќ[‘žL%уАЬтц]eиХsЬ ŒrФUž`гhЈІZt\9€WЏ–АLGВ jMУŽL4qs0ˆKˆkOWJоD аІЎ: є;žnНkНСGŒа(M’ŠG]к [PPТk*^hЬдсХ]4_+xŽИGAф=eа[#М6D9н]ЖвДtК=В•Ё\GРУС‡”@ Ћ^frђвhЛRхоѓ(H*§Љd+rНž@љмDѓ!ˆ|Ё0ЈaЮФK.ЁЎвHѓЗ/ВHZfY+bq ж8РІG А<ИФ ЦЂгDЊjdдЎ]ЛАЂАе#ƒ9–о0Ж3?r‘"йЬ^d+­!№СсuEŒоLЧАђH„KМ™Cu\'"‰,+ŽтеT фHйJDкFЄŠŠЫеЧЈДЦO‚Њ цmјКcЫ ЊVY‰ipгз3ШЧ•0Ь#H!L[_)0ЇА5іY5Œ'Ь4ИкЌcК…Ўє™Ытbљˆ@ARа\G„щЄ.E ЄWVй+ђФЉ*Y#e+qњK уˆWЄЇьЛџ'I"еU™(9c–rхЏ pSтгѓ,Š—4yбЬо!ˆЄjш›jCЮЯkш.[i4c`ЫГ‹ррˆВFŠLDФpJLХйJЬЧˆь5їLкLёЪ &Рy„WRЖ’“"ёЃяAо XЭƒфДš рФ!*ŠBоe+„iК)bЄ”!•'›#ъ*СЏQЈ>˜‹HYЩVpфKCD*ЊШYЌ)\%HFsтMлр6^МщŽе‘xЩ/В•~J1!Х+в„SžfN1 RKСŠT •ЎaДзxУ#ЩyЄяR3…Ф‘ЊвJCˆ“B9уMїƒМ#0<>=lAЮmЋyQу€wй -_ф&BDОЄpA” _0p45VYБ|жуЧ ЄSц‘м@’r„&+ЬtЩ.Щы g,TdUaq ЪWЖB‘'Y)e ’Q"ЕTRИЪ%N9š!ЪЮ‚єWј@„#эЄят2<Шb™YcѕТ|љЩеZ­Ъ,D†Оd+tЄь@zJс‚0%ХЃ”ГВ.2‘G™зє—.Ш#^fDЊŒШЃфŒ™D+Ф`{|zиboVEБЩdЋlŠ”#RТ’‚”!.ƒg[IїLŒC)^ХЅф€yIžЦЁNХГІђЪЯ|<ы—ејФПdЋьАЇ@‰ыbдџiJUџ‹X9cŽмKЖЦ{-Ъс@$dЋg}–Фёф‰• РDeйŠB€Л ГВБаNЋŠ'™Р€>ЩŒАњ‡8рCЖ“*Xц—AКZ —ˆ€ fX uС=fЬi Я0LYDдЃGpЊЬAс#Є6ьaE&› €Xj^Е"ё†–l7Зђ ъВе‡= ДЎšј Xœв7п|г1УЦQ$йZ1ЧŽRHXЬŒгQйм :ШMD-U‘њ=ў$‚‡dŒ*<‹жЖу*#z$;R• l еАaCv[Ђ.€вх^dˆ†mлЖБi6)f бL)Ш);DА5$vj’W!Ќ"оЬlEтЂ5—О0VOт|лšC 5;„јc У.c_0=5gЛˆАЁdЧŽЩ В={VГЛ'qvj—ЙIа{4SIЪmo]PAЇM›†ˆD(#‚Љ‘эжdF(Г#ПВ GФ=т˜V‚:P5†N'oкД)J1v 3Г‰АdkќИOV/M>ќv |њр›Љ@ €gJk,"iјйgŸ‘ˆaдмИ Ёlв1З`™RОЗЫeЭмЦ Ь#LQWйсœэІ%ЭoП§k,ћEЃЩšЕX‘xУKЖЦ›[љu„AНй!#ф;зlш˜ЄЎ ю;ЂP^Ѕ"3›Чц)EX Ш^жhQ–СE3ЏЂеbZeSHvW#‘lhІ˜#0­ЪeHX6ƒB Kж,hEт ЌЙЌxs+Ÿ Žјж[QjЎћMЊЈ^йTНzuцФwя2fgЇRЏй\s?и.—DІЇ №‘ХД бŒ’‹•**№›йќƒц]ђѓaxћэЗ1#`Ѓ 3—[WтV<pР’­ёр&>q]№НцЏ€ДTH$нž={Єuе“_x0„G\В#‘ў§ћ{цqKЁ ˆNѕвЛs-ћ#X1кВ‘жеŸ~њ‰-žАНВ6›а м™+cПRш0s…ч;`ЃѓЪр4wk€uфА0/‚ќХѓцБ5›ўнзЖчЊЉХKњпUІўgЭšХ~Шў!'†Tp‡‘e^KЁл2ЙЯЅHэЎŒъ*ZЊыІLШMЙ)є (э^ыЕу+,{k|НГqЃ_ЦКеЦ№їДс*[\Ј Љ/7Q+Uak6п­їmЏ,ы\},ue8)Љ*kСЦZМxqЗЭ}žбmЭi1З<жiМч€eˆїЗ8Ј;ЈІLЉиC”лЗ”+—I?шэ_еrЇбк5бчЮ2Ў] ЏщQ“­сQГв-Ф"PbЂJ‹ц“Цую]хђE!=/_VЎ\Ršwnу—DКqц”тЋяEђЦ ё?ŽБt‘RЙjШД?C/И,йъЮы<ј8`ЩжрЛ'qМEЦЅ‹ЦК•CŒƒћC”ƒћ„Zšъ)хЉ4*IOЅUвЄU&R’&U'V2g1мvlM–\I™J}{­yл№8 Ву,FRWЌ№cЅ[№ЪKЖze‹•90%Ѕlй /]l,[ЄмЏ>WMЩ•G-SЮжЌЕ’З€š1Sxф і :%ХЖ *E‹лоЌжЈэ[Јq•ЉЇ№hњŸŽG ИFеЏ_ŸI'з‚•*UX€Љ|зФу>FXжЪЯ8`ЩжxvCcЛ;ЦХ ЦФoє‰у•LY‰ії>UЪVT§FGU&ФлSa/сl}Ј§ZњщлЫАп ў—ђ‘гЄFФG6ыв“РKЖ> w9Fњhœ;Ћ8и˜7[}ЅЉ}С*5ЗX …`_ИJ(Йщвћ_6P6€‚ђHэ ЙtэкŸ*рЌpŸ’эaБ?( )Г(–…шЙрЖ€ч‚VЭš5Эfу0€ЊыJаМdEž@X~OрMn—{їєЏ>з*WВdГoкoљM”+MQЫ””`EЂЗцеь?ШTуё ж*‰:uJœ81B“х›7o–йdешбЃY€$(`оМyШ_жqQ”,ТчŸЮв,–И4+В"O"ј[Ст€џа7­w”-фlљВ~8 %ЯџВЪ Д f ЈI:Ќˆ(ыќљѓœ‚ћЧDИ*ФAd=‘UЋV%L˜%^ФAW0`РЪBьЂъ>HАў-–MрIќ F­Яь3eŒўTŸ0Ю6ъ[л‹ ЂF$ Ѕeoum {НdЯž=}zaš`\ЯJVѓ*ФЌ А ™GђšћLš4 tС-[Ж`Љ0‹X‹–lЕžП8€uUыдBM”ШО|Ѓš9‹_eb,S lЎ dс?іVtO7GЋЬЋ>„&Риьe€6C† f~+bqX_Zы1ˆ˜Цњ5ZВЖšЕmП-xь‚U<Е>ё[#юЗшЄLйA€‹l^Рип[ЎGвdiвЄ Цv4xф‚ubqР’­ж3!єЩЕЖЏкFg{s€oЗгI*В{^ Ј™tŒх4ўќ Р€›eІ‡AЃЗRJ" šУЫiЅ?ŒіШИ'ЁЫШ/}и МЌь3џRs=<]>sц 0€ПќђKР›tэк5Ж\Э—/_|EоA‹`ЌqРВЗЦЋуXEЦ;zЗЖЦхKіХkдЇx~№„˜А ШоБ›!xzjЕ$юr Nк[Х„ѕЉq—щСпr1sерyі“ВЯZl‚юЁTЦ„M јя‹еТ8Ф8&[YaЉНо^+S@kPнЩё“їТуЕЯ~џЕXчю№rІK Џ\nІi­_ы5НЏМeє•ІѕыЉ7Цk`єœ™’<ќeHDл ?ІPМRsK'E_рDЪ-ЇчЉБoЗVЋ"^Vіq?‰5ЉСbТ+јziЕ(ns ŽЩV§ƒwћДoмВљ€§ЧщЦ”‰њМйоя{ ьЃмЛч~5e*}@o7™ыžGž‡GС{юHЇк^jrіŽќй]UŠW›ДTДниЖйјбћ7УwC‘ј|Зlя}j{ћ]п9уUlцšдЧиw@ПŒ IDAT Ћj‹>8ЧdЋrќˆ’!“ФЅW‹=cћ“š='н3nнвzwqЫЅН\УиМžНmcŽZ§jЦƒ=;%дŠЯЉ™2п~%OЭЃ кЄ‰ка~ф4n\wж(gЌ]E\_4_{ ˆ,_тЌTТ™K :чЯ‰” cљi]лш_|ФЉ ЦжMЮ—jЧ>Hxф_ї->ЖуH5ЮžбZМAgевњПџˆ”]лЕє/?s–ЪчЌ^жиЙMжўоYЁ?7еииПWџhˆБ~­жП79=[(‹Л ]з† в‡іГЯ^l{ЅЉле :ЕlAu;ЌЦxх@“­j§FЦИ‘Z—жњєЩР*лЊVWK”Ђcњлн]ЖЯZ ЖыЂ5Љg\ЙlћxщіБ•$IмznћdД>ъSуЬiзtдТE93ЩllZЏьмІџГLФ—ќЅfЩŠйWядТіб,ЋWвЅз{v—Юœж1VЄIЇ6 “P;ŒЖ^}еЙШрєпЇ3&лšЎ†nхЄНжR)\ЬОѕээAzћ&˜>С?5fNAцкgЬWГха? §ЏЙњшсЂъ~еќVŸљыCВЙžЖuщЁ№эщ3Рk ц|ƒcz“КЪжіeые"ю›”<Ш,џ17—,=Дк8€U1n§пЮ7::ŠdwЄKрlеPП|IПrй‘>Ё~ьˆьˆѓхкєЩКгщHЂ‡Ўў6;Ј}?–"œ:ПуьмJDZ5д~јЦ7A*wZ§єImјћЮnmЏМ@AGХтњО=кШMыIњњЙГЂЦызœУ9瑉ЮО=œCњ:PЈЇў,SмŽњ}ŽœЉЕSТˆмOП "OѕŸзищd§Gо 4ƒD§ПеŽg q6Њ­!ГiЧЫ~ЩSŽкoSMъŠˆЗšйdD?ЮQ2Џsh?Y…ле <ХБПaCq­`q h9ї|АдJUэ•ЊђUcМЌПеMџє}[‹Ж`€j/TћднОЅОPзїgЯжoˆVЎАq‹œGћ  кэjхjЦ†uŒВmC?жYЮ+7ЎЋљ ъуŽ*ЅЪЪКд СвW.^Ї%JЫDŽЦ7Ѓ•l9ŒћЭ3ТІ&b!iуЖ&-eЂ0ф+ЈІH)OеœЙ•‹ч•…”єi†H–џЮў#‡Œ-ѕ1#D"Svљ ŠˆG0Žykсњ2Л1ѕgл‚мрк3Kouх†NФ%й*0ъs=e_Н]"кй*WUZw4V.c Р3ь›Ъ1ЕqѕŠи2Фg@x!%ѕўНдlйEЦˆ(ЈUkˆId ­,ŒkZЅ:хˆ{vЩЊФжOI“)>іъы}€пзjW2ZДUѓц—™хQјІbЗKѓ…L rю ІO5јƒщ~Unmт‰’2•mрћR(‹ ЉиЪ[№Ї…+М о4KЖяНБZі€qЩо*ќJ•9бCћ™Є2ўYЊ-Ё мeЮjЬ+С1/ \QіhRUё GтSmжFI‘RP DDAШжп~U Ыu*T1&Œ%EЉUЯXёЗqтqcСŸ$zЎчQГfS CD IъАBг>bЌ0ЇВO_шє~%G.уЯпA|xPЫ>аЧ]ЪUŸ{о˜3Clчwї.v^}ЌА/? !!BрњзТ‡ЅтH йЪH0Ž4жjцЪИ$[ЙEіQуЭД™™Џз*URЅл+Ёњ}5ї,fЬЕŠХlКЋХKЂїЉеkiеJурѕо"эŸŽVBсх#Є№џіЎ,ЊЃ‹юлEЄwдˆb%X+и{4Ц‰&Fcb/иKЂшo‰5‰5‰Ц1С^bАФ;6ЌQРŽŠ€вwї?o/<ŸАР.ьТ–™oœ7sЇмѓжГwЇмсэM+kЎI34ХЖР•ЅймъS 9ќ™vjŽŸчвуді…LщЄщX яSўБПюБ“T^нCј“$'ѓKXУћgЕn(oзD:~J~;LЅc&укTy@5ЙП$>NќšэЩеo(љяК|Ф—œЦ#Ьoф˜ne{А №НА!‰0Оѓ-МСr7Z’œ$ё­=ЉRЮ№ysЗ6ЙК тŽ{ЮбIx,8QфА‚/I|.ЉZC<ž‚ћ*И”џ>И)ёісTоBѓцЁˆŽD)4Џ П‡7##{žDз#Ьл]Iц`ч1ЎZ +ЩNY_ ­0>nеJ=&lЊР#uŸ>}LU;І— РИе^"S!Р08ŒiŸ€СgЦЪЛ””7Чєр/TŠгІЇ)гЈј0ЛЕјдіхЗUP5эЫрŸЂХ`бtГіЭRCL ˜є„4rФ™Й iЮр‹Ѕ„№ˆХ4Œ=WІСkУXЂ1Зђ>Бj•чњ фЗ1Љ‚Ї›6Ў‘m? BХўН\%oЎцЋ;цдŠœ™UгKvєчсYА˜Pšхe#ЛѕTМ$Ѕ<{R>zˆХё‹‚LС‰МУVЬŸЉЬШфЪZ*SгdSg)_(ЦUк/k…›зpЬAКt52d5ї—§ќЋ|p_ќХЦ‰‚{)ДT PP*(q+b!!nDg]Z SJ€R‘@єHБбiЧЌWŒ~N@ЙcГђгўœџЋsPљсЅ\ПJвщэbrk~k‘_ЇОlуvЭхе лоУІ++ђY‡gYФ]Юк{~љНЎƒ?“m Ую]ўтзOaiо5I ,I4ŠGJ ЦF(zЄђ$Œ˜кіePђbЦ$C1СЯaЮS6сŠх J6˜вA€ўcЌˆ}ŠѓћђŸgvТџsЈ7p&@КШзЎШlZр‹V,O€Ьz>ђ=;В†є“ у3wmЭьм tжЄQђУ1В>~'гл9Гe€ќиajŠї9А{[fЛ&ŠЋ—3kx*Ч№u—,Ш9@|эdЭššљfEј:/˜ECЪєДцЛЎч“й ЮјЃЂтZœPЫЙЩ—>z_™>nY}К+".ЇMUЫqе/ЫхП­‘Џ\ЊИžYоVё,V(Х№ф?ЬугЃ3 ‚WИ JЕM‚CГВВ222RSSq.>‰‹‹У­б“'OЊ_пЯНœ3XІt>О%и+t„Іўѕ§ 5tЩЩЩiii@Wj%zщк‚ЬфMЃЗ[Й>_J6­Wn\Ы}ђЙ№-лGдТхœЇьKœ]ЙНЙА=јНЬg:uœџнЖЃђ`˜$ќ4~GcЋЌrы&щЈ‰ќщў&AВзс(-|Pq8_ыс‰S­ЪYSЅ_ –МQ™Кр§NmX-л}XМЁUЙњGхЁ}ИE’’"џЌЛД|EЎW_Ш+vnх]Эž<ІР4ТЮ\eя$0я q€UўEoxі’-Z7о№š(УНЊ9УІЎѓ‡ВВpЬБђТYI•jт9V ˜ žР‹ Цй >vrъj•Р'ђˆ‰aAЏDВ з)S&ямЙуУ^uц, ђЉътщeЋMЋЦN8<ŽIŠŠŒпКщhлЖЫF§љчlmmŽ……}ЛPlђPнЛ+•=Зт<Оlо"yŸюмля *W-Чщ,iлŽШ‘ЁмЪŸЛЧaїrp>“TŠљГPї+мћ=•ЇO 8CсЯ#œўWњћxрКuWЌ\Ц;ќД?пШаQв>Мџ@А0œћёОјмм)‡bХњевA#И МƒєЎмВIЂтVi№œ’ТH–o'ІT!я •(:{RК5ŒГВ’NQТх h1gиT БјЄ€ђШо‚К mз‰V Ў\Ѓ<1БТ4Н&&&~аН›_]›№УнЫйiдŠI1НЪ;рЏY‹Ъ“ІЕъп{SHШŒЈЈ({{{ z%-AЏŒ[Mт…W Sј)Ч5 фкv"ЏІ„|D)О›ƒu'ќс,Ќ2Vх›*+оюЛq…їc­T‚‘снJyђ8WН*U-ђK №ЎЇвR%p…•+мЛУ5Ші‰…#UЪИgTЮ5mžЈыЏLH*х$я—РЛ ˆ2˜<хѓj zћH.ŸчO”хЧRЌ]AЮrђŠђ/јAАXAЌјьууаиіЇЕяšБцBКя:аЗџ &|№ОlвггŒzB,—<{4CL[ёкЄгцРNT^О§ с#jоb‹›1ј“]{ лДSќj9p%яЫЊIx ї˜%рZЗ|P‘0|PIцјIqœlУ6щА1ђ #A=тf%Еќ”fчмОЩ5jšŽЯ&YЩ}•‰В<ƒфЊз„GAЅЪХO‘ўіZћъ8И„Л–ГЇ„Bх?ћ0_A-d9І_Јx5“­!!_бbбOнŠм )U~ўЖЋзЌЗbЪ•цLT_IЏ0LIgІ‹Ц˜Зb’.NрžŠWя# ?ќUžO!У[ЉЋ„яўwНExУт‚Zr^4ђAUс nФxЩуGЪпжˆq–vъ‚ы`0ђџЛіэсZЕЇRd"ЁŒИЈМrYАaљ1фqd…;$•Њ(wnсх7§Њ лЭЗ 6џјz€ƒWL4УfЧŽ4”(=PLŸ$э7№u)­Ÿˆ ФF+ш#::zїž]Іd›сZ7jŠfЮkЗlйвШШHfКšты-–N&Т­Р€0Ћ:ј™ДZQАLsІ)TюћР­№Х5UљЕ jСЛYQнЇЂЁ*ўћД9Š_ёОbsзѓSхХѓќДpаЇY9X Ыjь+oпT:|,Lцqѕƒ”~5C1j ЎАХl/жж ,ЖPWœРНј†ћVШЊ[EPыи…wŸЈ‹@F+Ь1и­X пМ9Дgяzц<T ёaЏК[ЖlЗ"+€ЦLзМ@™aŽŸ(јmсѓзG”29зg‰їѓ6ЂЁЊМ‘УџœМ…§ЄXѕ №ŽВ0ЁZtRž9!3”ЮЈdF†$ю™И†/snŸъ:™ РРT“‡rЂŒ””ь шеЋћМ%Э›ЗЌ"VЅџ=vgмА#lк†=жЊPFиЂ–™6В7M~(ч=ёљЈќTц иЂ^ЦЧГv 5wЋ`+u‡‹aтx=Њ$\€ПNЭ лй'ђSJл|ВМФ“­А[Х<Цv+m›2yy`ѓјЅт; [WэЧ2yѕ™‚љ!`:sљihXљY™ќ™дŸљXƒ М5эЗЊU,0~чbЁ!>юv ьАKk`ил›џjЋ€АЂKkHЌ_C@РdэVC7яАћ•ы; oОЁхˆэV[1‘Xјž0CгDџу&@†О~01mii VE€ѕЊџЮY†‹Г[ їн”тШШtЅ)Wp+бkЎё<ИџмžћкУnњ“ЧITдІще+ЬЭ%&<юоqmсм#Тcq“ЦьqЕ IHряЛ5V% }3a`ЃŒ Ѓ„`мZТ€Gw X^гДИCэаS^fЮžvPmQЎЬЭ›.OŸМ/WfбБŸ‘./Z]=е"nЅo#‚ŽЋž 6–fЗЫ›*щq‚јЗЊжP;gыuЋЮ]Пік)5œQšўе>П*ѓј~?wц?Ј™уGю ё~чЕk9л6№Їг'ясёэvЋzv[ФЉw‘Й}ЫЄW,;Pы{/‡џujЙтjФcфD\ŠAщІ {НПсЧХ'CсNt|зіЋњђЖ?нИўtФРm0œЛu\НcыU@ƒГB”€… Ѓ•€"ачŒ‘§kІ0n5г_€кФ ˆ)€2ШS[ЅћGuМ+;‡Lќ[\:џ›У чЉQЫнГМУьƒ‹s/gырP2Ео,WЙŠѓйSїџ=Y…ЃџDэнu#>>хј‘hdVЏсњћЅБУwЅЄdОеЕж™SїЛДљ%11-))Ѕc‡ямЛћІЬ"ћC›ђ2ууї6 фицeЫZŒЙћ№СШЁСAЯbSF и†*шnїіkѓfzЎџйB 1@#(cТвц†уVs{ущ+А*‘bЕ5ЫXЪBfuј{їЭcGЂЕ+ЯU­юК>ДзЦ­ŸИ{иЎ_охпКѕљhsv jQйкІЬ…s/_ŒyУлЩЮођвљGУyxйћеё\ЙќД„“ ЖfуGгfwˆKХdЕ\ЕКлљЃЭ>L<Єџ–Ћ—ŸЌњ­Ї@Иш:ѕя],+шWЌыёѓКЉ)ќ$Ц—CšќВсC0Л06=%€@SсФGУъЉ;жЌс#Рі ў;*Э_ец7˜ЎАLЇŒпKЛ0!ѓ(QЂ”xйЯ */žЇ‰ыZZZ4kYљќЙ‡~u=6Љћ$љBјC<ЖэP bЗo=УŽQwwž 5­„8ъv<Ќ]$КtЋхSе ‡іG"‘ž–…иТBыѕЛyGћ~Д tпяЫ†­лUE~г oќ‘М^cbU(Ц­zEл(gvЋQМІRЄРB"яP@ЉГО}ыќй‡Я?Bi™22{ћВЕќЪEDЅП№ыЃrеjгОкН;ЯэПаАB§†„нКїyЛŽ<Зтщƒћ/ввxЋ3ъvb7їьƒТvvќЌ‚&Nmckg2) “­ягПСПч‡ГАѓ›Е=`ќnпЬOн–J(ЋRыДT`мZ*АYЇ…’EЋЖUлuЊ.ЯТoa^Е–m|n\}zш@dј™­-ЧК2q тaџСФkнЮщЧю6hT1 aХc‡Ѓ1ТEц;яН‰=УlУФыїѓŽJe\—nОШЯ†n6|t3pєђE'вгхMъ,ž8zO‹жUњ~Щ{ШХДbtнДот‡^ф­Ўл‚ЈP tл)kЭ`мjШoטЦ6s^'№#…KКvџИЮ„рн§>ўГЈSfДGўлн|=ЫлПџж:№`z^Ўn6œїœёv+&SЮƒїД=jB‹ЎяљўБсRџооЛћќЛeнjд|ЭyvЊFŽkŽvцЯ>œ‘!Ÿ:ГУ­›ЯZ4XўѕИНh ,—aNЅтZ,Э(LжWK `gЊ]РЎФŽ"xiУж$UHHHРѕP=zєHRЮж\kЌя'ФЇVђvЂyXЊˆэPЮЮж…6ђьйЫЇ“Б † … ‹Ђ"у*TtдЖ–И…"Єq†"44дЭЭЭQрДХЦЦІlйВ№0 жН-Г*Ц‹€v\уе“МѓwЎƒƒўrѕЋ БЂŠ››-ўrеефQМиЅ‰МeŠ —GТš2иœ€!Мƒh‚‚02< i–P‹€Ђlјhj‘2LЦ­цёž™– †@Щ"РцJoж[ "€‰ушЈмo§F%GцMЕg]ё0Л•}Šˆ@lьKЌсŒВCЈѓў]кў"<цJ„§u3—л\…>тшWЧ+дŠнМ[ПцwџнŒ­W}! Р)Aeїoр uухuЊ.Зxсё'‰ŽzђЖgСѓvЙТЇŽиb… qzaUš#РИUsЌ˜Є&…Д3lЇx‡„VЏ8г№Э№GnЋ~ZrђшЁЈЙ3mXоЊёr\8 БбCwРI))э‚~ТaйЧ1‰=КўZоqF џ’c‡ЃPƒnЎPНsы•д2ЩїўрЗ?7^rьyК,kяРг+2БуuRHк‹]Pъ?{Agxo€XLЈЮ #Рц[uЉy5иo@Ѓпж]XП&ќГўќi( Мь9G§є.ю€љЌчя.Ў6=?ЉЗwї œзzЗ{mј{Нt!ІaуŠ8–Š"œ,8wњfEqXоš6ѓ^ЙўCxДњЄћЦГWƒSS2ўкyуqLвш‰-ЉqP0ŠАm—Юцt(БГГ змжж2x| 0ѕЈђE |9И вшОбbЁˆ%њ@€й­њ@еŒк”ЩИ…Kп™6yŸиG*ц:kкОS јЕДѕЯќQСЎФйж3'янИ _-‰‰щqq)И*Еuћj№вrђп{c'ЗТиї{д†[€Пїм”iiYыC{wь\iЙ\ёХЇ‚"П_оMŒ2ŒгЗоЎ…ИsзZI‰МwAGЧзœpеjЎ5kЙS,ЎЮв #РьVCjv 6 Ќдс­3ЇьoШЛ­B€чЊѓgџ№эQЄ33pфЊЪЮŽкДЏКkл5ИY j^йеЭ< _Ў˜НPГ–›pм ВKьгdдёЎьфъšэЎ]Н'[YYрцi>†ЮЮТ™Рщ“їп§РOш+i•*;ћЊќi ™,Саљ|<ѕз!kй€3ИVЙx>{QЫСб ЦlєгЏёw;fвц=Ÿ‰•†ї?Pфщї›{Уй МbпМл Q_ПrјэS$|ыf,X[\щjе]Я\iQF џ,ЙŠ„GXЏhъАjceТQж€>Ё`dA†%њF€qЋО6тіAR=ХЋссi?aJ›Ÿ—ž"БVm}ЖќПјќљ–% #ГiЉќМ:9[элћ_ЃІo4oYeУšpxУ‚жђaZюиТ_Ч+‘ЗтšхцVдЕББќі‡Ўsўїя%6Ÿ0ufћап/гjцg'ŽкаЈb—|Фu“­9\КщЕbи0n5ьїSJЃMPњЧЃV›<"ѓ˜tШsќз­ууRќЊ,№ѕž-CЕщPmцд§t#м`УЃ ќБТРDk˜% 6Aаƒњm ЊПДEУхи/кjћТšZ˜<і/ЕЅШФTяИЏZ}аe]o*8ЭМvх жђжUОЂlј MW]Гv цЫ_J)I'~АА++*2š€p}’“г­­Ы#W!3WтхЫŒшШјЪ>ЮЙWј]OP@_‚–) ‚Lэьр—ЫFрSеЌ?-`№ЪБъЦ­z‡иH;s+ˆМ KŠ4}€G0٘7‚Њ€")бЋ‘ЊЌvиБ’Ъ€є nБ Ж*rђЅЉдRлЫ4ЗšЯЛжBS"p%˜1(Є)+J‰XС&0Z3pГ Šv‰[‰|ЕшЬ€EЁ)+ ›№dКТhцP*LГB X364Н#РИUяo`SР›аƒ‹Ф ~Б мJFЋ iМŠ‹GN,‰ьIŠ#†ю V˜Ћ3ЃU KЦ­ьc "VтSp „ШХ€[‘ZŒVи­ V ЄZъл5Ж\ш Х 5ЬR(Žn…њSмЪŒVc{Зњ/уV§тkь­ƒS@.` R„(†Иц*й­ТBИ•XUЬ­тДБ 51TŠ)(€XX1ј ЂZ"V #д2eй8ѕ„лƒЅ'`MЄY0#1&bšTEŒ€х+J &n%IЈ IQ>‡^СЊаМ‰YЏєэ>%ЊE‚Šƒ[НšЬ 8Š0n-zfQWLЏрMbRŠAЌШ$ ХЦŽŽ@‘*Жф#^‘@ JX•ЋБПqнŽŸqЋnё4Эжˆ+СЁHLJ ,2)Ъ#гФ †xb2EšДFТФtgъЖ(t•œIDATЦ­ХAЯМъ‚@Ё0Б'ЋŠTГ#ЁH…ф…GЃKЋbи”@Œ@J с‘БЊбНм0ужйЄК Ц$B%ХВЩ5ч82UI/PЇјЭс‘r„X•ёšŒXžЅЭЦ­fў(–њљqh~љХъЌ”*“Š;Я›#.ei†!РИ•} †€ю`ГяКЧ”ЕШ`0ўVМ?]ukСIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Images/library_switch_screenshot.png0000644000175000017500000007066411733011756026252 0ustar sylvestresylvestre‰PNG  IHDRe  –ѕ uiCCPICC Profilexе–gTЩ†Ћ{rf†‡œГdЩqШ9‰Ъ0C†a2bfqз€ˆ˜а% ЎJ\"ЁE0aоAe] ˆŠЪэ‹ы9їюПћчVŸЎ~њ­ЏПЊЎpЮ ЙХуЅРbЄr3љюNŒ№ˆHю!Рi ,€4‹СsєїїџXопАёЖО0з?†§ї*'6ƒ ф4Чp2иЉŸAј+›ЧЯђPN&aT!Тт|d€W9~‰›…ГФ=‹1СЮHЬ№d‹I€шŒlv<’‡Œ 0тrЙ!lЧN`qц!Ќ—šš&фj„ЕbОЫџГX1пrВXёпxщ_/‘Ž]3x)ЌМХ—џe•š’…ЬзbЁ!5™›ты<%‘{’УrёZf^Ътš-ъБм eуыЗЬq|ЗРeцe:}ЧўСЫz~‚Гя2ЧfИ~Ы“ФђЎйb~~V`Ш2gdЙ.s~Bpи2sb]Ощq‰nЬe=1“љ­Џф4Џoc.Рx#˜#ф2nщ136YCœгxyќФј„L†#ВыbѕL.л@abd,\вџŸ"0€ˆœcq *ањШlšр€ЬЎ'№С ЌlRф€ААь•р08ъС p t€Гр"Иn€!p<0^‚№ЬC„ƒ(’” uH2,!;Шђ†Ё(ЇИPTm…J RЈ: 5@П@]аEш4 =€FЁ)ш є FСdXV€5`Cиv„Нр`x5ЇУљp!МЎ€kрfИОп€яТј%<‹(JЅŒвGYЂœQ~ЈHTŠк€*F•ЃjP-ЈnT?ъ6J€šF}Dcбt4­ЖA{ Cаlt:zzК]nGїЁoЃGб3шЏ FЃ‹БЦ01с˜xLІSŽЉХДa.cюbЦ1яБXЌ$VkѕРF`“АыА;АБ­иь0v ;‹УсdpК8[œŽ…ЫФсрšqpЗpуИx^ o‚wУGтЙј-јr|#ў<ў~?O#ЈЌ ~!А‹pœаMИI'ЬЉDMЂ-1˜˜DмLЌ Ж/п’H$’)€”HкDЊ $]%’>’idВ39ŠœEоIЎ#їпR( Š%’’IйIi \Ђ<Ѕ|Ё‹ˆ0E8"EЊDкEn‰М%ˆЊ‹:ŠЎЭ-=-zStZŒ І!ц,Цл V%ж%6"6KЅSЉ~дTъj#ѕu’†Ѓiа\iZ!ээmŒŽЂЋвщlњVњqњeњИ8V\Sœ)ž$^"~B|P|F‚&БB"T"WЂJтœ„@%Љ!Щ”L‘м%yJђžф'))GЉXЉэR-RЗЄцЄхЄЄcЅ‹Ѕ[ЅяJ’aШИЪ$Ыь‘щy"‹–е‘ Э‘=${YvZN\ЮFŽ-W,wJюЁ<,Џ#(ПNў˜ќ€ќЌ‚Ђ‚ЛOс€Т%…iEIEХ$Х2ХѓŠSJt%;ЅDЅ2Ѕ J/ GF Ѓ‚бטQ–WіPЮR>Њ<Ј<ЏЂЉЂВEЅUх‰*QеR5NЕLЕWuFMIЭG­@­IэЁ:AнR=A}ПzПњœ†ІF˜Ц6IMiMІfОf“цc-Š–НVКVжmЌЖЅvВіAэ!XЧL'AЇJчІ.ЌkЎ›Ј{PwXЃgЅЧеЋбб'ы;ъgы7щHxl1ш0xeЈfiИЧАп№Ћ‘™QŠбqЃGЦ4cOу-ЦнЦoLtLи&U&wL)ІnІM;M_Џа]ЛтаŠћft3ГmfНf_Ь-Ьљц-цSjбе#–т–ў–;,ЏZaЌœЌ6ZЕњhmni}Ъњ/}›d›F›Щ•š+cW_9fЋbЫВ=j+АcиEлБи+лГьkьŸ9Ј:pj&Е“›_99ёкœцœ­з;їИ \м]Š]]iЎ!Ў•ЎOнTмтнšмfмЭмзЙїx`<М<іxŒ0˜lfsЦгТsНgŸй+ШЋвы™ЗŽ7пЛліёєйыѓиWн—ылсќ˜~{§žјkњЇћџ€ №Ј xhXиDZдє>и)xW№Ѓ­ЌоPбаЈа†аЙ0—Ав0AИaјњ№В‰‘ИШаШкШйUЎЋі­2‹*ŠКЗZsuюъkkdзЄЌ9ЗVt-kэщhLtXtcєg–Ћ†5УŒЉŽ™a;ГїГ_r8eœЉXливи‰8лИвИЩxлјНёS і х г‰Ю‰•‰Џ“<’'Э%ћ%з%/Є„ЅДІтSЃSЛИ4n2З/M1-7m˜ЇЫ+т в­гїЅЯ№НјЕPЦъŒЮLqФи die§5šm—]•§!'4чt.5—›;Ї“З=o"п-џчuшuьuНЪ› Fз;Ў?КкГЁwЃъЦТу›м7еo&nNоќлЃ-Ѕ[оm лк]ЈPИЉpьїšŠDŠјE#лlЖў§cтƒлMЗиўЕ˜S|НФЈЄМфѓіŽы?џTёгТЮИƒЛЬwкнЭн}o§žњRji~щи^ŸНэeŒВтВwћжюЛVОЂќ№~тўЌ§‚ яŠЮjvј\™PyЗЪЉЊЕZОz{ѕмAЮС[‡ЕV8\rјг‘Ф#їКmЏбЈ)?†=–}ьљёау§?[ўмP+[[RћЅŽ['ЈЌяkАhhh”oме7e5M5G5p9бйЂпrДUВЕф$8™uђХ/бПм;хuЊїДхщ–3ъgЊлшmХэP{^ћLGB‡ 3ЂsИЫГЋЗлІЛэWƒ_ыЮ*Ÿ­:'qnзyтљТѓ ђ/Ьі№zІ/Ц_ы]лћшRјЅ;}}ƒ—Н._НтvхRПcџ…ЋЖWЯ^ГОжuнђzЧ ѓэfmП™§ж6h>и~гтfчеPї№ЪсѓЗьo]МэrћЪцw}яп Йw$jDpŸsђAЪƒзГЮ?кєѓИј‰и“ђЇђOk~зўНU`.87ъ2:№,шйЃ1іиЫ?2ўј<^јœђМ|BiЂaвdђь”лда‹U/Ц_ђ^ЮO§I§Гњ•жЋ39ќ50>3ўšџzсЭŽЗ2oыо­xз;ы?ћє}ъћљЙт2ъ?Z~ьџіib>ч3юsХэ/н_НО>^H]XрБјЌE/€Bj8.€7uP" @ьYђУ‹а’‡GXшх§ќђ’g^Œ7р˜a›ZЮЊдІ:ЁICl€MMПнˆ",qІ&‹‘ekвГА№f\4_ц+О”#О§|—|И0ZЌ€#xcЋ`яsQєХЯПЏўf5цtRбъ pHYs  šœ IDATxь]|TХжџoKяЁї$єЊ Š‘" ˆ‚XŸпГЁRЌ`{ііа' јЌЈМїьˆŠ Х‚ŠbA@:Єб[ Нn§Ю™нЛЙЛйнь&›,3љmn™vц?3чž93sFГz[Ž вI$B@Џ 0ЊgВr+Џ‰РYŠ€“!иlRP8Kл€,ЖDР‰€“!X­VX,сёшЃbяоНxјс‡ХѓўѓДiг“'OЦˆ#яОћЮ™ˆМ‘HB'C` AaŠДРL",, ‚ (ў\tѕ}h@!K!8w~ЃU+1›Э0™LXЙr%bccQ^^ŽяПџяПџ>иЯh4:УJ%аAРЩј‹o4šEЩЎИъZdэл…ММ<ФФФ)™п7mк *˜B@0иОСнM&т}UЄžЯlУКЋ1nаЧИтч_0Йу млф%tўu=&w*S… т­:ЎўИ‹GTИfBсZюРќJƒLзњЛтёTmјvJ{gўšЏgЃйкЋplкю:Ыз™Y7‚Ўџ{ЧƒыЯIЗ /їКГІПоpЪсo§;KщИёQ>ї С|ціqКг8wСоп §(ƒ“!pš,%Аыж­›шјaZ+"##‘••…””;v Эš5Уљ;УŠ~ќ3лtаb џх;ЗЮ~VПƒR(!ЉC'Rb:ZќH:  žщ(Ѓќ\“сpьT4Z~РƒЭў‰ŽUЪсппЇ‹/Нз­нOљДuFљaх;˜8ўU mАwњœыщFЛњn4Лyе_ЙЈ?›щоМЂ;F€˜њmЁЦЋJнЅUтh9ЬЖртэ^џ\Ўцџ7WZŒ‘кRЏhњ,ŸзXЕїИhAŽ-с[‡*8W“?ep2„тr3NšœI;|K:vьˆ?ўН{їЦщгЇ…џ‰гаGЦ9Уњsc !H§•””P>vхЅ{<ТИЧ єйп<М…ѓі>P:”№†фЎшѓб‡Xўи@ дXa0§€Я>О #žbœмИ”ЉžЏѓ!МћвЛИbЩ Œo^Ht1Mpѕ“ЯуГёЯcљu 1д\}§ж„ь уэж §ЧтуѓиЖ­НR=ЗKІ;иtŠE0ђї' ЛвРAFЃђЋЈЈ@bb"ZДh!Єƒž={"--Mш8И.ЋйБьA'Ьќ#žH‡џeщDšъ0aћоСп;5У9iєы1ПиД5ЪWпЋѓPћЉѓЛўП{спЯ\ЧК^ƒO№'ц]’ŒsйPkzv Fu_mp”э‡јјкёЄЕAЩWСFMŸ‚ЧЏ4УC?щžТ_џиїЕІQ“ѕ жюњЦ Жз‘‚г>Іч^dgлл уž§og]ѓоЏtyЊWf<џ›шЈoЊѓЇП >оUъŸ№ўЄџUйСоЖMwњ•zQ№ЊэUнn]кaЅЮЫ—Ÿ’†7Z ‰UЛВЂ<?~ЙЙЙ0`іэ뇧ћї н+kтtјMtЄ>ЉMСПЉ!+NЋu’Оч/хУ—~†ЫжхсЏЌь^`РќџьW‚зъъBGїY‚бp~џИtкОcЯoОi9–kЬ‚%3ю<ЙїSLР˜ѓ-…{fˆтUуЋйаcFїCFv–HcуКЅИlЬ0—є|с1tдЭXЕfНЏYПћЯ5т‹ йтљињa%&^[g1X щгскFИЭшlbчQ{н1ЎOПЉСKћNcћ7Я"іЩЩx?лЕŽНеЋh зїУWnѕЭuўшˆaAЧ›БPзїѕуёзGwЂ…Юц„IнљЅњйW]hз/ФМnŸ9щю"я‡3Гo”ќеm•Б>~ЫHЕ{;Vћ)Yqоh­ь…ZЭСZЖl)t œ+YZˆ:uИ@юЕ8sПЫЧЖьSтї<Цё А_еїкУЛ‘Ё§ /ŒHЬЃлфїА/§ ф­ыBЧю…тk,ђыџ юlyДšєЎЕUJLžhTЇY›ћжЃЦ#jеœАюЧОЌ~шнЖjО^ё !н9Лq’tыј —OЛк™жкuРUCЉЦЕљ4дАЗэB–Жj:M%НзІ‹ЮeKЛгЏоŒэ‡ээJСЯ[9Д‡VbеЎqЯЭЉUhUтжІ ъИJ§яљі)œѓй2l$ЁјЛчЅ~VюН•ACuбыЃЋpэвƒЮє”tƒquЩ?ќF\1ФоVеX кМј1 JоhuВoЌЅŸт<ˆввRtюмYшzѕъ…'Nˆѕ)4 “PV‰уыЪщ+NњНћНЮp#^пГƒhl,ЇЮУіуПW‡ѓvЏŽ_+њкУhЫ$lXЏСZ§DЬ#ёе ё0ЇˆИпэяŠŒєыpчS—РђяEиO_fuZЕЅяВюbХ†Х|‘ъKJxЭЮЎ˜šB гьZПzџ33+?2JўŒЅЇrhВvŠ ўъ№Ъ}0№VзЅ9mўuїhL]šСЗtpЉsOј+tx+ƒсƒЌi8љкhєNй„БKѓёBЄ5нЪ=_LˆW;™гщЫ§Йьžhu‘ $"+?N‡ффdЇBзЎ]ХAЏз;У)сЋЛЊ ЁЋ~ЏОG;Q+ў‡Н—p^ъєняеyЈ§8ПДпТ‚ŸiИB8[ђ>жи9А:Žњ^П6їCK6hёфэЁєВбhЋ3 дyyУC‰ЛцўgАmь(ДгЗХ%Ѓwbн;;]вЊ-}“І§+'OЧ/є5iбјњсс ьС{pБж( ›АќЧLЛжjёХПђ"{уTЉЗr€˜тиUы[AmЪ ФuOЏѕэЃЯу“ё?b m:ѕн„GшKЪ}a§rmР[”Y"рBѓцЭEY™94TfрŽ 3ƒКp‡ œQ}H6Юd.‡5,ЮљEВб–ъ№п!ЊC ДdЯбB#M-76№ВeЫ lкДI~с/=јЫq˜ЮЁ(,,DлЖmХюNŽУ  1›:˜Т8˜i№aЗчŸО№Ћ‹JЉMšLѓёSљ"‰ћВБќ—НАіМЩњђЂPAІьK г*G1aa УЉжCёsцўО§*ьЛWЃТД‚q2SiЬNa‚p=Вmаvэк‰:фsK›S˜_Й|Сtzцˆю‰*уЈКд!X*J`8јДХЧ`nvлRt@УОЯAŸ­эШ|И‚ ўzхZ~"СРmоМYXŒffРлИ•†ЮeфЏПуЮЯЬKќЅeРј№{vOl'ѓєJХјIFНcкиђ•…ЖІџИѓЯПЖ:Ќ7<‚єєe$ њQTІRГž$тЧ Œє+э|іІЏ@\іAGG")6нRТУЌТы Ў7>ˆ‡ Ќ+bfpєшQСаY*`+тЭq›S~uAЛзОV—:–єйпбз)š”ž;АхлwбQo@dЏ‹ IЂЕVђ#C-Срм0XBр“ЌYќWtќž7АДРЬ{gч0ь”И C/а?ft$оуЇ‘tю8„EХСFЪBQKЦm4(3йш†hТЁИ‚ оW(Ѕ—Ыдѕrь;і:­8qЄэšХ ‰ЊЁ–Е:и™™ѓpыž™;K\– И~йŸ%ЦЦтF \Й,СтPS гœEWЌ„…;I0ж!№WWp€ЮСŠчРЬ@“ѕ-ЂKіЃЈU;шЪŽ"Њ‚іQ˜Ы–v.ЩВЦXB!щМE:РѓВЉJZ§НcFР*šу1Аќa&РzўqИˆf7Ч уr№Я=-Зрgь‘%s…yGѓ‘а=‰M{rD2Ъ,dГŒЬрбЁИBƒЈ2вƒ(1cд‡ЁBƒтжƒyMЪэ’3J.kcsмйљшAVs=+Ь }ћіhеЊ•ЈK–YQз˜ЪЇ0О2нСІнЋ„P[3§‘_ЁЯн+BEѓў$Ћ&AK’3ƒ2Њ”ƒ' wќ0щшМ‡ІЉа2{*: ]ЩЕzю€хЏЊ№ЏQлdz999ЂnYbvЧЊ)nмб™vІ‡лžBДдЬ€л3ыВмлsMѓUтydЕе!0Бa‡~DxAє].€Е”Цл™ЋItm…№ТLЕщ€S9&Зсt†Ё6ЁЌ­›@ЏЅN[VMnДсАZ ќuЋНœРi№^PщшќЬРњrJXuNKЉ,ѕћ3}Ях9yђ„а G5г iœ†t#С"Љ;ƒС†hъ№б$@Dъ bјPB ›B­о>•JІђиqй›уй–XZтŽФЬ•ˆБББЂЮј}гІMEБx8СЎ!0ЦšЅS–Ю•>ШL€KВь˜Is8~ЯuЭ?хY Еi—BЉЈ$ЄОжT‡Р‡eЏExщшЛї-Ц MLТ)АЙy{тиV˜rNЂ•.a-кЃŒООКВBиє61Xш WBbяiшЂ[ЈIЊѕ=ХВSzM™zшQkТ‚˜@L„ћ3і`№˜‘hCe%)ЁŒ#qБ#iШР Ё’1`рgНI #rѓЕHЌ8‰ж‰‘Ш;HŒ™˜hmW‹PR,ѕq‡с!пѓЬбyч'ЪТ‹Я,eЧLУБЄРWю„ЌgRкH@™!pVV–VyЁгР bІ—iу{ОrЛU$7nƒ–зP0фВђŒ< Њiћє(!дT‡РcяWˆ(онЙCЁ‰2Cc";6ДˆFi\и_H@!Z†—!2)ЖІ­c)GIiѕ‹I2агQѓ^G]+‰zК MЗ*uьx ŽE €}1…ip]+сšЗ-ЁqyYƒэ(<Д),=‚“HŠ;ŒX-}I_`4ˆY†bКЬc ОђL+“Ь%hFR›бDGГQ§PZ‘!tЄ3Y2рТєГ˜%ЎCю@ќŽХrnЏ<ŒрїЌtфwЬ˜T'5ЁџWI‚•й<ЄazйБоŠWS2Уb§ПgfРtѓ=30ўq^lЧхb3„š: Ћ‰Otвn}†ы'х Эиhˆ!˜t(%Ў‡ЁЬк­ш\Hƒ™]|:IжО<š_ -ђŠrЏЃw‘$оbAR#Ўk5†сиЎ4эоyeUjS˜7хžЏќуЏяЁ0pO90c[—Ž^п^нАgћVФ&@тr”! aё:ъшT4|ˆ"ІРkxJ—B…Eфв2ДhfBД6 [vьCŽЄИ('#ЌKšƒ6AиЏ_?QvюTќеTyya;žŠdЧ‡Й<ЕМџ~СHвшдlЅcŠ@ѕ№ЇAYсЉ mИѓ3уЮЮŽ™3~ЯaЙЯpyјЮŒЌC‡‚pnЏЬ ИѓЯ_ч‘!(уЮ(Pg-<(ˆбhJ 1ђбб(-і(E‰­šЕюУщ­АžсXтг…Й\І\ ђЌeHв=†„$Zƒ<†РХЂ1 амCЏщ€]”WqТtvM<——ё#rФСх•}хдyК%ZБђБ"‘WD @ŠcMУs/<K?Y!V_ђsKњХRя7C уNNŒAЇ#Ц@Cˆ2+-7ZMŠHbшўЙeєЕМ€†{J;Ј)-g*з wz&№—ŸП˜ъКR˜з-3Цˆ;”Вb‘Ї*й ІР4ёwhfЬдx%-3-f№ќž™гЬвыAј=—•iчzу2q:,%q98Ќ?.Ј:юlšОгPђн‡ˆКˆжаТшвТ\ьйcD…І5’кvƒ.<М(ISž/ЎaХЈ УBЕ– Б‘‰ V˜ЋEE4{7}Ур‡Ё ŽБ‰гgpriYwђ6Б -<1њ‡Л2pЬ LtМ…˜MЫ#ƒџх•лЕям ИRЂу†ЯcуЫШFцКŸўРЦХЦўJ6Ё/gЌc™W$•УšшdmЃ­eEхbќzЖi_дП—БbљќЅ‰ЫЦ_Qo‹ИY2рiI– %ЃreёПФМ”НО$юМЌпPfEИёл,K ќžЅfv,E№›gRиq8ž]a&Рtѓ‡–u \Ю””aѓМАІ:юpІОЗУМu)№нD =­ˆгйЁ0‡”Б)‚!иJh# M/bs`.Щ%"hј@ШЇB•œЂ9вЗЃЌгDш/˜JKnэsщ~—ЪC@N_WM3 $EвЯBыRјДyfж0R€R8vЬ ĘЧJЯ4Фa9ކ†;ЬPИЌ еq#р“КЙ!oкКЛЖ§‰єє816цЦ”&ЪР_Ўы§GNІШ''в„‹в,j9kK—“;˜Л f мVXлЯŒї;јћ…­ M, (в’K\Giџ~ЮpЇW˜ЯЄА?sѓK ЌŒd†ЧŒDyЏЄщыjOСCˆšш8цfЖsўуvš–ћё;DіŒ”–‰4иУ-Gy—Kб‚gшd(+1k)эШ#№ywcnЩ)DгТнб}0wЛšў“ƒ&0m ŒтТЈƒлNЇ.“$ХkДZъшз•_Ф,Xzc Ё€т8њXћИМ!3ЅXЙЦ €ЇВі>Ž'рp6aЋЁђSйxњX­dф‚ЖЇ№мОћю;Xsў@з^У€8žњm˜в—Г6ŽcФЪ)АЂ[ЗnиБc‡ј8єьйSДкфW]\юиЬospчiSІwяоНтЫЯŒ‚:t‹˜fv,!АЄСЬ€%…@œcШр:зЌŒЈš8ўЂk{]GУЋўБ‘ч Eї6АьЩФё?—#6Њ”ОD$’“bбJb3ƒвТгˆЅž~|,=n‚эМ;ЁЇсEАœ"!hЃHыœlЃ/<ƒNѓЛ$˜I:аiIКЁ{хЋШ‚‘„•§I)Ъa9Nt1Hћš†`бVWщpЃbмаxЩšwЎг"ZЁШ u7|хЦФS^™ŽˆЏJЋ№chžшу?ТlНt Ив@ыŠж3•.E{їю-:Н'ІР~ўљЇшdчž{n@_л@ЫФз§kЎ0ўБŽƒПќМQ‹933ž•`I;?3ЯuЪЬžЏЬ4И-ћыМJЧhŸumь!0SАѕИ†VО‘.рЏябЉ/КД#%уЮt”а‰ЯжNЁЅнŽЦТ4н˜‡bњМ§Аі™+ ; 1ў–СЏpŠ˜ЯРb B*ˆ‰Ж!KџЌ\4Ј$Vfžє#…"Эгg)".м9dhшR‚ гЩгQќcЧ_n,ьИБ?˜)В6`а… hйћкvў+ЂВ%&љ4Ъуэѓј"Rˆ§cІРpwІРЬВџўТО(Бx—k]1GжpнАу<ИЭВtРяXRрgV0у`Z;uъфььJЇчїЪ™ы?ЊЭ#CрЏH0і2А2акm"ŒZ’Ыгз Кmtk[@’C.)‹Qvњ0ŒЙ‡ХRY[оињMЕ3ƒHвєй1чхЏ?ƒOR‚Ž{…Тˆї‰ IDATe/ |єНˆ>:*x]:ђђЫ/Ч’%KАчР D^4 ЋгэЛЦ8_ћ—RсАіЋ§ЫoЏ›MЉ$ йŽЧ'Ÿ~ŠтœCИёЦы|*Њ.qё”67Јшфжh}љƒиљA!КюY62Ц3Fс-ЎЇeшžb…о;ю€У‡–Жx‘K,9(вs]”˜‡щj‰“ѕЌ;`‰‡,‘ђPпѓ"&nзь/>^Дž‚3uХёьЯŒ(ЬAyяыЊљioЎЗНhWЗRMsA ­LД’ВQ]u˜`п3а ,;В6NстœŽТ‘ЋKЧЄМiІ18хыsє`іђ ЮkО1]/‚>m"Ъ“oЎг"44œ ўёGЃЖэІ&Р)y+Œ‚ЏL ПчнœМё‰Ї"yЕ%Пc ‚ЄЬ(XIъЎЈŽ‚ТYRЈ '€еEЙйiЊ‹œ*гd™ƒУљЫ‚‘з™HC)_›4Я}џ'‚fЅvvz&(:sy2 g‚ %onПjЧяy‰ћY!ъ05ЙЗЋ3=Фd‚<лб0ђ•D „№ШъJ‡Т8ЪЂIB­,yrЌржZOщЫwu‡€.}.О|1Вxэ‡ŸЎ&qќL:$‚iNўŒwо§y4†oLNЁ;чФo~бяQB`‚ЂGЄ№‡лfй: џFМšHє: Ы}„ƒІ†D—{нщ8ЖœŽuщЏмСнгVžkRG5e5ЇаZнеF3 Я?џМѓїь—щеE и_щP'm•кћ€ёг~§…§ЯЬћ™Д.ЇаL&Ѕза =Z~R…Ž@з!pCыЙњ*lЮћЉœЄuf'‹и‚oЇЅTIПо^wѕџуџ,ТЗi$ бѓŒіQіg&…З ~›WLЗcЈ wЩWЊ‡оњЊЃѕ—xOдвiж!я9ю“ГсМБ1з?0iЂ г6™+ЈSut>žjеЖfƒpы-45M7иŽгžr+Аd•уo‚D7ХaАѓѓ'=l/`uВџaРSЮІ†ь‚h/С+<!wЏBж(=ю˜БƒŽ ћоиb'ыІOђБЁјŠєђkM?<Еi=f[P< Ўя№0цўз5М§)АџжАЎшBkђ)Z›| Нh/:Ш?Љђ>0їŸ|ЃИ‚Јl3[ЌРх'рвŒХИиж˘ЩдБcŒ%ѓѕИmЖй#..82=ŸrЅЊš:Je€ЮМЏ OАз‘{іMAє џщm^y:eаpФ”ўьЄk№Ў#з[>оŠДСжпО‰ЃпГСћ0иlydпСŒЁЗN Ю_љ1ы1nœШ;яkяlтНEззп{%:žњKVžDЫ^ь$Ыiн&м‰ф o`Cа§Њ9И2СеŸrОЇ{љЅДУЭ1МVЇЏб$bаЄ)мЄ’AD ўqКЬКФџŠїкзУ0 WtІs8‰ОНс„=ецƒqчЭнБkХO8AєПўТ/hvб$ŒГ~х Ѓа5$@:МЕjЌ@tКЬНи:јJŒMuэ–Д.ш§ћ^dVš?vЃэ[Eb nЩ7bщMгБжВгэУZ“Э[s‹~Ÿ€eГ"жаы6<Œ]WцW†љ•€ЦФЮ˜pэR\KK<fч|Э7mf~/вчМKояŠG_Yў>tнЛјъbф k>ЧвПЧ(л7i dœ.Ќц—ЛoЂ}ШЅ VУрŒх —lы7$=‚ФdŽФˆЯЁi)Е ДŽvёЯнiOG}AЧ;ˆnF–†š/нŽ=ZAпД z$гђtkš5wо7wHЕŠП$;uG7ЭzфчUhхМЌ9ЇqЛАѓŸ;YГ’K=2n]kжќB qаЎЅuL›Жi2’-птУ—ОвŽ" ЙgІ–\иOл<‘L\?дюёдЯ‡  Kчl˜‡•Y3ЁЁљЋДэќ.˜эЈъ:€šико›.]Œќмё4јыІЇу…Ÿ;u ŠXЮy˜Цм‹ЇцПBŒkwOФ],љаGЦ­ЕЅЉОтзІŽд4zТ@ЭАдaыъоšмёЇжcчщЁAеЅ“;эфzѓk5i?ч!\IвЯѓžУ‡кюіaŠpfoМЗ =&Э˜(УUПnщЛ[ЕЗЌC БќО'MBФtŠа4Іd1VwйeшФч2Ј‹ся‡1Ф Я!yў7*Я пrcНшЏЉ*L*Š­ў"јzЖввOс4Љ˜0v+VнЛ лЦ].|іUЗД:‰ №F“šF8~A й.оК”EI+Р:т4ўИё ЛХ‘†=ŸЊX:^†‰ЦЊя9šсЗt!e(dуЊбЅaШ-~xgЙ‹fž•Šћ’›!ёФќф˜p8I˜œшм ]јJ гwQZ]ъvZ<­ещЃ<еЅa>љ;>пx \ю+˜ŠaMrpŒ ГГв0ˆЅv• ЪMлѕu^%„@з №x|hІ!ёQ' Ќ8ќіzЄЪБЖћбАруЃ3BJ;V<^мŸЦЬJ,R†m^Ш;ЕX X{Чѕš­}iд‘–CY–JЪРЧ:$…ћ\№їл\Цн,2я$хтœ“ьЉCyЄ•mЉUyЊ=N=§ЗiFbёЫн/ŒО{Y2Њ#Ў‡•У•ЈтЪљxУ€ѕъzД+Y“€ ‰яUЉШФ№xљNЂэŸ/8iДvŸˆ‡tаљжЁЄTќ'žЇ5vЅbGкіwвЮл пYAЧЮoš‘2Rэјk=A•О№Ѓ!Ъф[KBo“^=555t%‘HYYY^‘CЏаH‰Р釈T*ž}u.K,№Š€”МB#=$g>ugВФ3‡@ЇNsЫn$ЄЇ; DКНЏ‹G9dЈ TešzD€‰'fтэН/вфС:вO"PЯА4 ўљ“Н"AЈ™‚rЏјљ“‡‘C‘’с$u„€вy9yѕ} ™УrмšЦWŠ&‡ ђ*hфЈˆњ>bI !ДdX‰@!ронПіўdЋ–јо=Mвакш0 щ$†‡wh;ЕТ дq”w”LkБT=)&dX‰€DрЬ" t|5ѓPю?)д”šќ +УI$u„@ WM†вљеяјол{їpъg}~…њQоK$ѕ@M:n]б(gъ Y™ЎD " B#Ќ4IВD Ў ЁЎ•щJ!>з!ј2ЄаЫ*I–HЊAР+C№fbЉšєЄЗD@"аˆC†F\y’t‰@А !иˆЪє$ЏC†ЦR&УЬ[ Љ’N‰@ƒDРД№']RBpB!o$j%„“Й… Ѕж š:IœD q!р“!03ш”вЖA—ЈTEн‘G^P=Щ[‰€DР§‡!9>]<эю%žН2…xŒиP^T„”••AЏїZ$UHy+8;шк1й‡М>ЄzOLL ТУУЁ‘'Z{­pщqv#‹Јш\Џ „C`f­жГЎєНїоУБcЧPQ!Зxzmв#Єр>бВeKм|ѓЭЂ\‘‘‘ ѓZЦb,03№Фў§я#** їмsš4iтщ!%N:…>њЏПў:ІN*њ†FЋёZФ 1„HŽжеh Ÿ€ќќ|ЏDУ#77“&MчUZЊVE#u™†D a"””„nИѓцЭѓ‹@ЯВЕ_Q+Я/ЧГoлP\nЎ|YЧwl вdђпк‡epЪЫЫы˜2™МD с РэлНП}ЅжB~q9yЭŠO7š№јоЧ&С‚ˆm@цххЁИИ<Ћа[•paa!xŒфЭ1‘FeНЁ#п‡*ДљZ1„“…FМИФŠпv•#9FSчк§œœlЪаaў‡6D‡}{џпk.E8p‰‰‰"}–t:K^<эhЕZСњжЌzrОwЖaч?Š?ћ>ГпNKП~Џ9ГFXMчЏ‡EH*51€_лјjZфНDР1„ТR#žzЯ„­ћ,јлh "єсHmЃЁЮш™TX4()Д!уwРТз_ Ѓб(†}њєA›6mpњєi! 4S•ЈC‡`FСLС“уЮфЭOcћ3Я_‰œЦкT@<ЯйGслƒЏ˜уZk№UWгRлДj_M‹М?;№ѕtG `†РЪ‰з—AH‡шMR{Є^ƒцaZёХ6h,ЮЁТЬ ЈТŒt3§kЈЯуŽи­[7СЬf3 ƒ˜:t_OРгŽьяiкQ)ИWpˆVГЁ3RRИѓ6ŒР|Z mГfbСŒрЯ?€ўMGŸЇ6a‰љNє{bГ=IM?<ѓлLЗ.RФ5ЉOрСџкНnќ№4Œ$‰ c1F xЬ)yрТ'ƒйџЪ(пщ|њ7|px!.ѕП&†‚ƒМ6n|MѓTcM]Р сЅџ™ёЮf3šД/ЧЯЇ H.ж !:IVDФX‰9€:ЄN0 uфтrŽж"=ЗћOЋћO2wtVrGчЯв‚ЇŽЭяй?ЬЧТ Oё˜fW]{=ЎjBНљцѓтp)˜К№|~Џџў|†cША93ьоК5ї iёЗИsŠš_ЦŽ™Ї‘ѓВт§‚Х˜5Ќц3шJЬaѕ’\2оРhJ‹щh7Ѓњt4жu˜ц%ОdŽ*: /ЌOkкДi•’ѓ{omМJ`/fм)KJInF‰ЭŠF’Ќ6hKДˆЄm:ђз…a0ыQЂгРVNWЃEКфы§?%jЭš5Nryн’ЅЖѓxј№aсЮPЬРзITЬ,|­wшѕ8ѕ8•сл‡ьы€– §Щ!аRкTŽ‚гШ‡КьЗpѕЈрHth‹ПŠ­0џ0&ѕЫЁ<(LГVшmЉ@сЖПАƒоЯWоЋв*Ъ~ЇњtВЗzЯДHwі"Рч9ЈxсgOэ;::кofwп …!RƒЎЗ"і‚X„‘јЎЌ>Јд $ ˜ шIZ@ +X$?Pф7a<zоyч‰№мЩy“KЌ8TыдŽУ№цІъІеq<훇?ƒŒ]—anя•и№!Иаf‡‰™’%ћ]\7zЦЌлƒлkaЭ~з> ˜lіЮЩaјЯшˆуэ}EіˆјŸŽ{КЪГ'њхЛГ}ћіЁsчЮр+З‰кК€&ёј§іЫУp{-rv”AMѓ(Xc"`Š4ИќlњЪwц(R&’шяЏуЏ9wpž1р§Мі€‚кЙы ˜‰№ZїїJL(Y9шіГdН‹+žќољоt0{ЯэŒ6ЛxoиМћMZЛЄв †ЕЕ+/}ѓЖ1pќ”t•gmЋŽшђћj|Г"mux“щh[ЇzŒЏф#ЏUыђlУdЯž=ЮvыЉь0Š€%ю\БдёчмDыўcФЂѕ9ш5Ж)2ў,Рд64эшCŒ=ЧўУ3 EEv‰"33Эš5C.0ыxјр>†тї­[ЗіЙWу{ršV#0aЧtэъ№еїТœЏ>DkšVАЕћ?LНВ;&ѕјНцЎСЌvЃqIзgEРОW_ƒsIFВ‘„Рг‰Z#I z+)#­єL?ы<Лx:ъ†ч(†>Мх­”NЗjгБj/Єј+ЋФWђёTљN"PSjФ8Ø=юЙСŒђџšёйšтPZЬОžŒ1O+z"^mўФ‰b(РыRRRаБcGС,Ž?ю•ЧPМp‰Ујёу]ќјA‘Њx№ msмјпИбХ“% Л6р‰иё„тЉОWоџy‡яYr  1хЙbш“иБуЩЪ€тЮ‚ц.iVz+ёох-От_SоIЊ"Pч‚’e ў{Ъ_Г`щO<Їf ЄЏОђP…ѕмйy‹3џxЕЂ'ЇlѕєdмХ›„р)љN"pЖ!Pc A*žІОНЖ№Z'Ѕ$YхЪŸuЬщдJEї•ŠёІ›nё=1ŽЗЌBˆ|!h„вцƒв‹›Ч‡уб›ŒЄ[№Ё?Јƒі+іИqуD8OЬ€% VLВŽсаЁC~Ѕ'I;mлЖэžлП?.( 3jWѓс‚ЇЙSˆї†™ЇY†ффd,[Ж з\sаAxŠ+пIB юмюЙ§ћу‚ЦќЩьL†™2e ^}ѕU,XАРяНсg’^™ЗD АdРЇM›цWrg C`4ќХ/фd ‰@"рua@jЛVHїaЎ9БE’„<мЇ;Дёl€ яUB`‹DЬВmа ЕVQ—“WˆВгрI‡  &o%g-мЇy”ЋiЁJ8М2ТLЁ1м”жОАЌ,BeЫ;‰€žiѓх|2Žшi ЯW‚ѕэЇžLбNП 54ЙPпdЫќ$gpЪ•оœW‚ЗђНD@"КH†Кu+K&j‡ ЇфМѕљшбЃ^‡.Ї‡\&Žfух™МЯA:‰@cA€­‡7oоМЪЎ]wњya+нЗџЛ‡ѓѕЬVФxw№Ф‰E0ЅП№ifъ9ЭšэЇШЯ†эдЃq_IзЏ+6y#“З•Vl$…э pЄ“4&XСЧчš$Ч{ЗhДtщRa№чŠ+Ў№К™ЯŸ2Г]‘/ПќR*VіћАђЯ~Tol№ж3ЈЮЯ d‰Р™B€m~dь?ŒІ‰Б^IрнЙМ ŽЯ с_M]ЋV­„Еr>вїѓxsR‡р љ^"а`C@ќЏ 3рbp|N‡гѓх…„рЋвO"ъ№p8CbвЈ‘„Р']|љbdЩa{ЈЗEYО‚€ТjsѕЇ(^ТГ№ИХљk9ыв_Œ ]SЉ€”ЬС˜e‰@э№Фўју!9Ап‘#G№љчŸ;Ÿ=…ї‡Џ С2јlЮЫvой^AўБХИЄгdЌџj::й|CќЩX†‘HќC€;7+н‹-ТтХ‹Х{6xЫ-З8ŸнУђ3ЇSѓЪŠM›6‰sLию‡ЇАў0ЮЭ+Cа9:ЙzШАšO_Q;[*f/~ч8Є‰oЇd`њ }˜УѓЋ$U§>Ыf-3Noз•vIc”\@ЄFQо‡М@ЮлЏІEѕжЩЇN* џ№ЁFЬ М…ѓ—!xeC†г]Ž?чЏњ3№ОP—Й;KБ4qieЙ#oDІ­78Нй#+_[:ЭР7Їљ€DџwЋŒ-я$ ю|žVЭњл)нKцыBхРc–ииƒ>шнљьЯ‘n^%g*оxв=Œд9Ѓ оШpяќюЯу{њ-YВЗоzЋHŽяљч)œПљ…!~KGшмУД.8‡†ѓПЉОИR‡P=F2DуF@щ„ЪЕІЅсјž”„wнuцЮ‹9sцрЃ>B‹-№Ю;я`Ы–-УћC‡з!ƒПФГшџаu ˜ј.њ=Лыџxї'хЁ’РРЇАy![dVŽ„U<фU"њјг §A‚ЛуY…>}њˆЮпЋW/МќђЫ"п{ япгГW†Рг‹юŽ;џњЏьo•+? [DЪТEіїЬРЗљЌpuъ№ь#uЎјШ'‰€7 СнпНуѓ3;oЬРцф•!Иg.Ÿ%3‡€ЗNlŠ$C6Ђ2=‰@р/Л?_їъВѕ' (Ћ#DњK$5C@}!K 5§ё–gЖПPн‘nBB`#(Оl"д jK"pfрv]уvŒ#§=в­С[Lт§лFЋdЊk8вПq"ІЕVћец#љы^-_ј{Є[ƒgО )§$р" ?НСХSІ&hдH†аЈЋO/.^•Š‹^{+И9Щд$ƒРŒ)З{ЄХ+CраЯЙзc$љR" hМ<ѓТK^‰—CЏаH‰Р釈dg_ЫKМ" ‚WhЄ‡DрьC@2„ГЏЮe‰%^ С+4вC"pі! ТйWчВФЏH†рщс C/^рbUјжЏ]CЎЄћ;Т–…—ТТtз№~?э]ˆ‘ЗceѕЧ јЄ шŠ€dЎxШЇj`fаюЋk‘iu§4Џ„с2 њЭ?XMLђжЄтю_~ЦЬNе•!Ю >&Бљg‹EšI?3UгsЕЎУs{сГ’YhmЌ@… qo{Cњ?хS_ЧedVŸ›Œnйэа\іЖqЫ&М6š^ZГАhиmАН§#юъH6)НQу жФ†пЯ ^ёE$ЕŸn^ођ vіž…фyyЄж5Ќˆ џj%ХZ‹Мz6ƒ}6сЂ]Е oь‚.VГ‹ЉoKкЅИъм%јbuЅeŸЗїuСЮв2Tќ5ЛЏLbОж%уіндqиќЯн(++УžЧЖтЊщkэa,™X0|LŸ…ŸёЃЎИ{њ^Ьќы_И ќ6,Ы_ŒKmЎ4œMѕPлВњbе2_‘ЅпYˆ@ч.‡їДЉшеХ‹›я-ТY;ЯРcз/С—k\§Y:јфН p§ЅЉТЃ§ЌG1щнЯА :h3VсГ-ЗсŠбі8–БџFйкЛаEъуb№}‚ŸL1$ ЁРіН•%Ћа^€iеkўtј є ЧJTtЩpФ;Џ;Ккh˜с§ 0%–МŸ AM‚˜ŸLЊ#`3“Ўћ +_Y9жЇђhгПТВЭЗтQі!ƒжђvfj`cІ@3 Г _gщEлвMТЇE*Н№ЕРЖN*ўcvгбЃ)ЬЮfГŸ`,тЊвRќхЕіШ!Cэ1<{Rа^‚ћžќ W'LЂН(8+џЮ™ѓгИ0‰їVЌокє•‚YŒ#fст(­+n|Я.ЪЏѕЋІ!jє"dQ0kЇБ˜иїЌXkДћ^СХ”чїУ†]”С@РЇ„Р07–N"  аnіЈш< сQсЪ+мДМ?В+љ”—Зй–!*j,‰чсљ­ьJ@šЊ4Ьа8ЬŠ\ќ9VФvCDИзBz§ŸБюsЬŠ C'шHcdJ:ієН‡’Ÿф-ra@JОђZ;|29dЈИЁлtщb/VЯDŽЪЧЏc=.\Иаё’™нк2Аяg=:;4#1ПИѓQсјй“1ŠщпCœ)ЦГ Юxђ&XШ!CА”щјDррќЁˆ‰›€w_…БЉ•zŸ‘ЄgН# %„z‡ќьЬАэЌѕ(šЅ”•ЪНМ6$|2&TъRuIZ$u‹€2д-О2u‰@ЃBРЇ„™™йЈ #‰•Hj‡€O†аЙsчкЅ.cK$ З§ъ* }2*єіoЧо;Њ__:,ЏйъЛЈњ•[Џg;ђA-gї\†oСіо IDATђYьxТ† т-hЊзU!ІчШФЛ‚ТBq‹зп|P%Ќ|!д Х ^BjЉYvоc§ќ у0­nSб§Fп…()(ЯЬ(ў\#™‚‚‹МJъ ŸC†`g:шY "HkaЂНёjЇ0–26Ўtљё;f F:‰€D n№ЉT vжkБсNБlеѓžжMЋ?ЈВ`…пuHkтЩЩХ,СЎ™žDРзOЕЋ_аŸF?mgмБе?eh ~ЇОgB8ŒњЏ{ЃцkмЋAKхзфN|M›j8Ž9ыeŒU=ћJЧ_ПR]^ЅСЬo]Ыхo|%\АвQв“зкеGЈтчЋcUBјэ‡u8њз&L˜љ Ч1‰`ЃЏзмvоћ?ЎЅP=Y3вБ— vNЃэv&Ћ]"iqзуИюсЇёUv7:g6Sј››oхМa™ pЭЙГХ;Nfтg6М8œ:vіŒŸeТUЉїу‰wйЇвяЭкЕјGмhUчљS№l3”ЪeВiD\oiNœБ=+оЦЗп!ђ ящp>вIъ 0…œўљј§їпНвЯТ-фkвйЇ**ЪQV”‹Нћ#ecэŸ‚>"ЛЗo#€ў}/BBг–vC›%(--…ЩdrЦї”‘­уЅMќіБ№ЭŠћбNф5O‡ Їнќ2і и‰Љ'пРEЖеИПпGИdЋ ІYШђЯ+ИfРX—ѓ&†ГєАс~|pљ~ь+j§ЪiH}yІЗЇЙaкhќљOђ›ъ№ЛžЅoвЌЦ\iZ6ОВOmиw c`СOовq`Ф4K'Ј/jЭдЬ :ЂYBАЭЏДЬ[jДЁИь”“"c‘oПлŒ‚2уZЁW\ŒfPR~ e$^јоp•Š[жšp;YрIKp(/ЩVп›6bRыт kЃ=їЯхЄ;Л~С’J…mлD18œ^;юšмžт9њN]qюoЛEIЖЕЌХкoХ}‹ь~ІЫюХм оР>?гMМIаAж†МІЃЂS$џIъZ1„@˜—…%„Пщ-0Vиu™FЃQH,03ˆˆˆ@ЧЖ‰иЭo%''УTZ($f%%%А•й`$}BuЮ8ц5lЯMгe,Т §РЖщWмъа!XIФ7jьщќ<]‡)џsЄHУ‹ЩЯфNЇzЖdвАDЃсьitD‡ŽР^NгA›_iђ№ІštЊ+Їє—Z1V ВS&Mšф•>–є/ѓо1d(бBcˆt2ƒША$$З‰ТАѓ{‹4’’’PTT…TЄP­„Аn2zЏКл^Ж8!sкtLНaОЪЂ/s{Л„Р`}ЁŸLƒrсЗ-В€Чџ кAє9ОрWм“mEВрgsJЄкЖ;§tи‹t:žЬФс-ўЇщ3ЮH:‰@=#P§ЇжAЌ<ќъЏ —Ÿ7…"'Уkс•ПŠŠ  !03`IЁмЂСїПoПЌЌ,RфЩ€™K&R,*ё=^‡_‰яŽЦCпъ*УQ']ћўЄuАСЙs—щlАdьC†a†_bO‰ПюVѓvь!ЦСїJ8іuyжŽРШkоТ‹Џg‰оСћOЦечќ†єl жжў…ж™hfDЋ‡жёХVžМВWŽICžaхx}RŠbщt—пi2yовёYFŽ(D ЈзЭM_фW7Г!ЏМВ$3яМ sч>fмсYИsЧNфххЁM‡df№жWућѕ_UF–w‰@РЌyѓ_ cs“^Ж"\k И$ пX f ьюЛяiЁ@lж*бєеV$ƒЏ/ў’ф?‰@!рCі~ž‡žГЁЄаJS‰Z$*•fKп{OdvгЭ7ƒgJtBЭ&№Еˆ~[6ЎpS'јдЩ%Z)…ЏэƒD‘~РtЗЫrД(žЅsЙОš№_\Г№#МпцSмђоЇјЂЧrЬYіy•pюёфГ+މ‡ЇўЅД _§Ж^uО‘~‰@§ АlQ1RзХеа*Т0•ЬѓўKЯ >>‘‘‘boчЯKŸsssaх•I*7qіУЊ'y+8;ЈWB]CLЃЧњˆ3fИМѓє№иcyz-пIЮ:B†!,›_U(/ЗЯo^ќ>HwZє$вЅM"щ 4#snГhQЄюЌЋ}Y`‰€!У†H+!iЁЛHZІœfCЂƒD3`IсwZЂЬN gђќпЄ]ƒ‡c/Ф’ƒž§х[‰@( 2 AљЪГ4KПH’}”ŽЮS1aє#&РŒ€›іƒŒЏиЋP‰ыЋBѕЋ—Уpѓ9јrЅфОp’~aJчWKJG%DУ*D‘tАщ€(3ХХХ>kбІпЗ_кŠ”{.GЏхЫ‘э`$lUщкЫ^Ф;tоDЗћяAћЮm|?Sх^ ЇФѓ™™є”œABF‡ 0Л4@КbЧКlЪHэЮQ?@Xdr}уњdK'ƒ(КЋёBЇБhзUƒ7VЯТs—8ТUЅ/ЦРютvА­‚юѓ_ФcюУХ—OЦ‚ ’&.iMњnЧ=„ћЎoзФх“D !2 С“4Рz…Aƒy„[Y‡ еV/$^љuшE‡ю@}кЊеФЦˆtйЊвєэиlКсм;РƒŠ6c& зH’&fЬBцЊЭИт #D #r СEјљgј—,Yт|xнmЮ{_7<\јцѓићk{tЛп2мŠŽСѕкvhЏy ?ІwDЦЎq[ –‚ФЄWC@ dBuвРшбЃxkhIу‡ѓЧѕї?ю|чэ†‡ ЋУцaUй}N‘ŸѕЋWП!НХ4цn5N‹%џњ л'<шŒы=†є‘œyB†!МНжUјхЃJi`нКuиГgOДŸt=›ц'}8.Єн§‹K‡f§ž™щ#"yЕ{і<єЎи!‡ О‘’О aj@љыЏ8–Кtщт”К§CƒнOњЗZ VєР˜Y”šJм7“~рЊ‰уНёз+йxМj:ТЈ w M<т#_6<BŽ!mv:’_Gok‹ИHЧF„3‹ЛЬ]"а  !Џ\ƒАЈx”Tр№I ‰Бт№—АА0ф…Eу!гцСё"Љђo-Qе †РЧЎEшmТv"лVдыѕhgФ-W&уоЫЃЁ#FaiŽ§[ƒа jG!ЈgB†!бёёЧKэУ‹Х‚Ÿ™Б:?ы€ŸЗчСkЬ"!ž^H'xD dТЦ +~:lз№QюХж0l.1рњ—ŽcYvšЕˆEћЈ toAf“jрЄХЄ€&Ѓ4:B†!DшЌТј з€Ac›I‹F9ЮmЏE}Žс…ПЗD›ьеHљпаžиPeI‹IС%7RB†!X#l‚ p=X Ф†ыб3йŠ9W7Умq˜їZџќ$’6П№ЂhПќДY6 ‘‡џЊЖъЄХЄj!’Bazš^ŒŒˆћишIxИ]gРѕ~dЂ›ЖCDГTшк’Ц1сyГi šЌœ }бaŸеЉXLКˆ,& я:›,&Љ‚ГХЄЎl1Щ†]ŸMЦчd1‰MЅёŽШнl1‰œнbвЕ.;&U)Ш[‰@ƒA dBЧТєрФ“mѕ– ‘(N?„6tЈlищ]ˆ>ќ=єM:Сšў;ЬПН˜Iз` 1E\Ђ R˜#>+Фn1ЩоЁЙЃN[ŸЧ“юf‹Iфь“і ‹IМ#RБПј-[L+З@+˜ЩkУE d&ЭЙЕНх.Ђ0qа4s-" Ъ1ъXџx†ЕџFI;:™ЅeшГN‘1ХЃАшaMnюŒы~#-&Й#"ŸC‘ŠЈуЛQжВ;ЬЄ`Ќ'-&еЈ2Щ:GрЌ`<$(шuј)ˆІ QnхU" p вJEYЫ‰@`„Ќ„№лžRќY‚\s$иHJЉ 8‘_„ц6ЦžƒaНƒЏ7 zZ"а№9†_bТк_r‘Ok šЧ†!.ЏyG+`%УЭ4(а№тWјсЗ\ЬКЁcjЖКсUЅЄH"P{BŠ!”š3hвК тM&ФF‡Ю$ŸЋ›žŽфcуо ќбІvX4˜ћњМ0ЅЂ ЕGRІ BF‡Р†б~и˜ƒ6э’ 7ЂEЩa\ий€pS.žњq4KŠCŸN1Иb`$zб†Є‚bo‚—џwвЈZДdY„  2 aЫо"˜" Ј8pЩк+IqQЈЈЈ@zz:иЌл]l•…щуајƒТŸїрыНVќИ•Я_ѓэЄХ$пјHпа@ dТцУхByи4о„оt`ѓыЬxƒ3…ввR‹ћВ›pЯ ЩИіТ(”в^‡O*ЊЖ6ЅХЄj!’BaЙ–H”г m“ˆ‹ ЬРh4тјёу(((РюнЛ‘‘‘ЌЌ,ьпПŸV/— K+ ,4ѓА§˜oUŠД˜-]С/B†! фŸ.Ь@‘ xЈpтФ 1T`џ№№p!E№юF–š$ы 'ѓь'LОa“ќjK2P рЛ'4ЂцWhСІиЭd ‰ТСƒ‘ŸŸ/k‰‹‹УkЏН6­)~›‹Т`X‡sm87•,+ЌиuXƒщ@nd2bтuˆеqу•ЭсmР -&5Ђ I !У о“№Т]-h9ђQЌ9I+uMёу†rшW—гТ‚ЄШ0to…Іtь[›–f\3Ўeэc“‚в>e"ѕŒ@H1ЦŽw/>9Й.кR€/6ф#ѓdђK“a"ЅcВМоЁ•C.ŒРE^† СТ_ZL ’2њD ф‚оШsуС?щ$џЅЂџE–!%oH†р љ^"p"RCнOџ†ў“iUЊбrй?`ѓD•їђ…D@"рŠ@ш0„ђBС boћТЮ&64qQЭЛЖЁpё-а­zвЕфЊ'у?іРжЄ‹ъМ•œ„ C кДюˆщеšвЮкДІEBїтЗА…WU0ђЎЧ‚WюDи“]QБPкMr‚&oЮZB†!p Z3wсинзжIeкжNБolRR:ЋVлЕf/РџѕлЩob(WŒ4j’ЏŒ#P#R !eоы0лŠ ГЁ1ъa ЃM >œECK›щЗьІјˆEFѕФke6g‡џ~І—б!АЬкћŒ-=%še0–Р–› M^P’#Ў|яэЧa-%Ї}жлR|§Aюпђ†“p„‹_н…ћ+юЧЋ]Ѓѓ—ўoIw8ЗGЛ?ГЄСлЈХ/љNŽѓxЌзll1О…) •яu Ч9qz7ŒО Ѕ4ё=ЅщJ•|’ј‡@HIњBВX^ S5ыMа›эцееї ‹ђl3˜a6…ћDŠm)~vбDЌJЁ`Њс€ич№]я`Эі™„г“;ўзYœ’†џuю‰3№ЖO›y2‰ mˆхЭТ3ујцИb'"зrцc˜џ)~X8|"Ѕ^;ЦаpEaPўЄЩщH'Ј2X4Эa+,ЃэŒЙАІЁ€—ЋгТum|bdыд Нію@v5’|&т№4XGуЉmзcuOЧ!ўB,9ш9Іжі+цuЗ‡ы5ЫЌvFт:4нуЪg‰€;!ХLб4хX\[оiёГцžђ‰9Јž•{ОrXŽуЫYвКЂгOЫ№НлА€m%,ЉСƒы|ХЎъЇM™… Iм/Жaз'}0oъ‹™ЭpЛZp8ё+иˆльC•D§MГJDљB"р†@H1-KFV K`Ё“™јg&3ыќSю•їV cЂуо8Ž/Ч_рЩЯi0я\ЛВO Л~ZwЬ Ÿ‡;YtW9f )ІЪЏ9[\кBыи хпXЯ @•8Я //В‹ОтљђSЇ)я%ў R:жишДgЖКlБ˜Ћy;>Й)Lc„бЦ–”Hсh‰rъ|Хc§]iBЄ=VНAйЮ@žРhїчбћ>ѓ^ЦDыNB3ъ5МњMWFоo~^ЫЗЏeАu…‘}gг,ƒ†оНС‹VуЛ(2ьЪAupџіз„ƒЬТК8_iК”?аЌй~Šњ‰ кЙxКшЕЗ0qЦН~$б0‚„гК€ШчџDиё?]p\H z›}3.ЃтЬН0­VšаЭЯCйм~rЅЂŽМ†<ЫН„SnїXЮ’Иc“J‹*_J$е!2 AюEЈЎЊЅПD z|kдЊ/CH$!„€d!T™В(к" Bm”ё%!„@ШшИNЄХЄj™В(gаaвbвi@2гаB d‚Д˜Z S–цЬ 2 сЋ ‹Ilрњ>ГБнm‰`кšќй˜хЕЖ”T“jgš MC2*яkj­Љ&4Ш8Ё‰@H1„К˜Фл_ѓhmоЯЅ†Є­бЁйФdЉ!5ЫP“|UІк’'KFlзРнъ‘ћ.I!Ф pnƒVoVbПkу[ЅЩz’?;+E| ЋЖШфЋ вO" F Є[Lв’ХЄ‚TЁОКпЋŸmЅЇ`.іmwQ VuїТ’б#Д]љДнъб†ЋGД…yЭ;0…ЌБЅЅ‘у/ФюŒƒ"9о љ—ѕ7ЄяЕЇ~hп6tЙќZДaKHН?ԘіэЯ;ЩЂвы*MГyЂE0 ‡ѕ$о2­фщ)Ќ|'№„@H1Ж˜ФŒРTt’l ф‰ЋћНњY0Œђъ-&™Эdыv::m!оэfHбЌг’=;­UY=zw™АЁиfьu[ёБАƒА/УŒ_˜‚ЯW­KkWXqХс]“ЯUк@рmеЉ•ћГ<еЅxЇXOтa‘‰ЬГI'№в!АХ$]сnh*ђХюFe—Ѓћ•СяТ`Œїm …Уzз!АЏwЇX=тmаТб6цT2Д2:wчŸтОФњїњаIенpn_b ЧaџяНp‰Ъ~#[wžЖФŸЖK“EЏŽ™ШSлірzВШ4• bлt%SёQzH„C`ыGсl1Љ˜,&бvgў ŠŽOWхйYѓД%ZQ­Х$gјмЋG…ЮjPЦр›Х=Б§і+№TЧŽ8иџ}\ЈЧВ[&тiRRВ„ё$™N3/Ї!УBЛЕežYЈЮй­'ЭСXŸа,2 sœQ]\щ/Љ!C]XLЊiЉЮъбХ—OЦВћfC“кGшFгтЙ9Џa<і@N—Й™acЊ"ЌцэТ@ЋуБЪE­Ќт)_Hќ@ Є$„К˜фŽƒxГzФйxkэха1ДэмящДІЬ_њчŸˆбŠ•І ІркsЪЧŽГƒДžфљжЄХ$i1Щџж"C†вbRHTЃ,„D ю™!ƒД˜TїEцњ„”R1єЋK–P"PЗH†PЗјЪд% ЩUuIb%u‹@Шш&i1Љn‹L=є† -&…~k•%ЌsB†!H‹IuоVdg Ž!œињт;vCDL\Р№з…Х$…ˆƒ‹hермЪ#ЦгƒчT;xвкqЎя80я`|{Ф­аОљЋзг›‰zИa›Šu$iЩ@ђUPhp a[v:Д2бѓМ!hоКm@…­+‹I‚|}V•§"\Еo<в`<™Qћ|Њ}{Г7BйўСэk~ѕц-пK r–с‚ЁcАiУ:=И? АъТbwў7эзT;yувdА$ъсЇ„}…Ш№/І:m&(жXBxktЅE$NЯнŠ’пХ/ўBМ—Еѕš-FВЧ`?Ž^ZDRа’зК@рџл;ли(Š0Ž?G Фˆ№Ё`ЏB/‚‰‚ МдŠ€  ‘@ŒШK”h|УЄ!bЊbH"Œ&$€"Kг`рBˆЦm%bš4|ря „уzчѓьоьэmoЏлоЛ§Oвлнй™џlŸ™нчЗZ„ю=zвфsшј‘*КyU …оB&ˆIље?PхЄaфьŒЯЗWPЕ•ВЇq0ї""”Œn”ˆЂ$ЕУёнДЈЛ3гŽъїІMo4ав3[h,{=Ъ'т' E D$oRЕK- ‚дфОzбгЯО@ЛwnЅW.yЊ\ІˆI4tЄ1TАŸ„ ŽАo!šЛі-#x*.9оXHJщдюšh‘$оgѕšЅ(EўЎЁкпcюЮтЙиPХљE„t "ХДРZњаnAUQŒ@эС}ДИфu’ƒ—)bRЂВхŽоXЯ{f›{›;=JC†%JПЭЂє' MlйБ "’] ЌgB-{2L8VГŸ&M+іl D!&„˜ФЦDўТ—/q^іИZ—ЅЄ•c’…аЌyж]мžЮyGЯ ŸВ@Љ–БА]7(J<ЌЊёw-†8Ы?q–šcпd‘ЬceXQЦDЄЦ<{ ЌCі+ ЅA8yДšЦ?>ь7 M5Ы1IюЪ+JыЌI=9!щњЫdп­§Q €R%8…Б‘’Q”œsђИqqЯхTЫЈ7@DRJ`™)Д2Œ8Єня!dŠ˜$єтњЁЬ'Tє"n yсGл{в@ яючЇ EмTŒEФЁА;Ei8-9RЭEІ;KfQ@ъєA tў‘5lЦФт—єLзѕ’‚ KЫy›9oanР/HMЧхšZfщ8КpЬ„vgьŠЬLYСIDAT§бИ"КїкX …B”1ПЙ ЈЫVЦ|&)чг­}(XШЧxЦ$пЭэЎ)Їn‰аTоћQљЖИ4Ёp5аршVc€‡ ЅqЉЬHТ}”В*к^И“ЇѕТEf™Q@ЫIХЬTЙB(аš0­)„§PРG Р јЈБQU(аš93‡ 1ЉЕцЦ~(\м1 &%oiь…Шƒb’‡жF(аŠк‰IђЊВ|‰љ{%Іё†рWqЏ-Ћ]m]‚ˆдVХ>“ hgt#&)c`|–=њЊВёТбЌOщ šвоFgЅн‚|Р{ э•ЧЅQ-Ÿ2шDLJєYvс<Ќ’~i4[BŒF" ’м§_šЙŒ6Laџ& M/ўмђLT$Ѕ]GM'ІЃQХИМј˜MЩЫН (™с7uД4:“”тJю(7cё9иx#цЖьFA’цiўѕk ОЯЄwвТа^ЫˆˆGdMоšм?ж‰ЈIЪНй­ У€€Ђ”њr0ˆ]š Ђ 1IШHт\TПц{ђОЛyЗЗпЙн(H"i~ОIA’|fЬюD?U™ЗќѓU{(8ћХ8"’гmZQ“њ2:-Y (ivёfёщhkьФ$1^‚“"зйНщ2CQ.1vЭeiэуДСМф€UЎщэh‚IъўXD5#cрTEAc1Š'+УgшŸшpB/ЫОХ ЉЫНдиљ,е[(5{7j’[†‡фŸ‹ЈzdKceЯыPР‹кM*ЪIЇBL*bвM&&E"сМ зg^ЊИфoКпг*1IЦч#~žK ›gЉ#I&_]К–jЮђІœwg† ^пбтЉCиadј1Ѓљ:vЈР.|"чЌlEM’]ірV†Є1)JkŒфЦљ2Eij&<эхcн hйCа‰˜$Е;ŠHaехВqЛtс…Ё(wшЇ–Tацrs(ŒjЄ† ›ц­6‡ Ž' jОB‘œ5щxРНŒdхљуF-гЉ€v=нˆIђџс-ЩHдšQ]lRб‚ЯK6›M† Ѓп гŒb'и{3<Яˆš$фЅЛхеtЄ[.А$ƒІДн$A3%S[ќІЎ@р№щ‹м›ŽаФ~уr+п^AѓWНЗMчHJ­ыІпЈЫ…SLLК”˜В“юŽ'ЋшШSаYoœ[і*PYў­ZЙ,aДы!$з.Є#E?њvыk&/н чnkŠ#I\…8*RЏFj–P #ав шDLђк8šOвЧчцPйЙюєдхэўІлt4оэНRып~фЕ,Єƒ™R@Kƒ •е…˜фUјpоZПЮd&мƒЧbёцСгРЛ&4EЙN?ѕv>уќo*-cсЕ<Єƒ™P@Л9UI;1Iz ^‚“ђЎ7PрЮUˆbРQи“гЙ”МŒm=(xП7b’—ђНІQєЃ2uЛ3b˜Ъ”–б*–PрQ@Kƒ 1)­Œ~”‰ђ'№Њ€–CˆI^…єšЎ-„%Џy"H—кѕt#&ЅKh{>n„%{ЌCŽP@;ƒP8fBЛuі~ˆh\“Ц&%&‘˜,фc<ч–туУiйсилKђў‚=.Н‚7fZЅHМ”Ÿ>”Z[АєP@;ƒŠ, &ЅЂŽ…ќ‘\ФЄ\iIдЃ#аrRБ#AйPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPС!ЂPРЯ Р јЙѕQw(рPр?fѓь™&ЋIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Images/fwbuilder3.png0000644000175000017500000000714511733011756023030 0ustar sylvestresylvestre‰PNG  IHDRрw=ј pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХFIDATxкД•ЯOcUХ?їЕв(3PZ&•Ёƒ4,ˆ‚bЂNbТvЬФ8њш’нФРФ•Xш F6&f5.не@:!$BD† !ЖЕвїкїЛяѕЙ‚Œ…2иФ“мЭЭНпsя9ч~Џ‚€N,,,ƒƒƒЬЮЮВОО.VWWBЕ^ЏszzJ>Ÿ333‰ ­X,sТм™L†H$ТUКџ3^IАЖЖфr9ѕхЙ••• ‘HЈ7!ИR"г4P…X,F8Ц4Mъѕ:ЕZFЃaДлmкэvЈшІщццfДT*™щtI’ˆD"шКŽЊЊFБ, г4‡666šнъ\gђэЅЅ%Вй,–e166†ЊЊT*ъѕ:SSShš†ыКC@Г’Ÿ|ќсжнш'''o(Š‚ІiLOOS.—БLƒ­­-іііЮ#ћZ;џ™ •JЩЊЊ2??Я№№0Жm‚ххeЊе*еj•§§}RЉTЄЇ˜ !’Ц}љезWzе“DЅRiЊЏЏээmrЙОяP(Pг4‘$‰JЅ2еСффЄИ{ї.X–Хјј8бh”‘‘ђљ/=u6Юы^xIŠЅёxтэИ–у"Ањ(ЧўфDyбѕ›ДЂЩ{ƒШФЅ~„•ямO~3ђŽЛя‹qОыxЛeљъ*НF–RKŽq1Ѕfв—вј ŒЊЪЌC” pHYs  šœ IDATxэ|UіЧgо{I^: I  tDš€"‚ћК.VжЖ–-bYзКі]uEзКbйЕЌЎXEA)в;вCB)ЄїWчџœ0™МHўŸwЩgИsчмsям9П{ЪН3Oе4Mё'џјGрGРж2НЧуљЅ6энЛї`mђzН%%%rфЉwюЙчNŸ>нf; З–лђ_ѕ@Іe}љђхщщщЋV­кО};р€ЩGGGЇІІJaBBBŸ>}ЂЂЂУ†ъ_§ѕшбЃЧиХпUџvšFЮЛяО‚2щбЃ‡нnwЛнЅЅЅ………NЇ388ИЂЂЂИȘSŽ`ЉK—.ееец–*++Ÿ{юЙ?ўtЭ™3'""bъдЉ7нtShhЈ™ЬŸї@Чс–озддЩ_yх•ц[:уŒ3ўєЇ?EFFvъд 8………9`ƒй†ТщоН;pzѕеW*_|Б KєхшЋ˜˜˜7п|(dўŒ:юдыœwоygЯž=нКu  lˆУН•••5w‡hЁ}ћіљ(“ѕызƒ% тrЙ`~HРьќ#і[sЌќхўш@#P‡ф;//ЯbБdeeeffтЦP‚о : ІZsЗ №AФDЮ;я<ƒ‡Ьsssds|ќхўшX#PЏsk|ќ0#G„О_П~›7oЦЩiюЎ@^ šЧ‡Ь3Kј9ёёёссс€а‡Ьъ:uШAл|ўљч—^zщ AƒP; HТhCIC†Ќ\ЙВЙл$ЋеJ•нЕ ЄzъЉйййЙІ":GЊcТ5ЧЧ_юŽ5ѕ:-AH яџ†n?ј6„~7џЇŸ'&ЅњмUll,О>!5jaЊн~ћэЂЉPY(™О}ћ'8›ќќ| ˜ћ№ёŸњG ƒŽ@=rф МџўћЩЩЩПњеЏf=џLAAхhЙЊЊ*нРС†рфЪYвЁ„Ћb•UUUЁs6lиАџ~ˆ!€CJJŠ№iџGЭQЎИ­ъЇ=BЕj^ЗR]ЋZkO[UБ]ё<•Њ"НkAсЊ-ˆџ—PXуtW;šЖНƒƒlі@_ЙвyЊЈvКм^ЋEе{B"оTZЉ?—P{@`€ЕЖЌЅCaiUE•ЫdынЦ+"Оw№FP8;wю,+Ћso№я“’’а!,k^xс…ЏqlР Ё3h€­ЈЈˆZTСHлКu+zF\#ƒЗc„ц`ов]ЖЇkоoязжџЇ5=В\ўЕпEJоVЯgAo™њкgJk*ЖSšв,Я‹ƒѕљѕ;jџKєN6.Q”Ямёќ‡ЋšМ&ЩФи№ž‰QSNя5nhї&iZYјШьŸ–lШън-њн‡/–*ЙE—о;‡ќ“ЗŽ›0ТзjЬіхOжЮ[Ж{xпј—gœлјъБ”д#GФZtРo1=,4T -АБpсBРРUРУ‘r8rJ†Š@ˆfЈN’t‘ЋЧвWн1Lйљхќ§И~пЕчМэВaжZ[НCtОѕЌGŽy€НС…PqT”‹ѕeД•СйД@по.Y&=ЎGЕа+5ўT§jP„š6™џеаИˆџџ]zш†1iн:їхv{J+vх}А`Ћгэywў–шШЋ&0Ž(г/%ѓ vDЕN q=rЄ= !Щм|\\ЌеЊSsykђшvМ6єс„жTl'4ъ€KеˆФУvFNЕ^љПУ’§џ#Hюб;9кчОFJ38љwOЭC^цќАэЈ‘sу…ЕГ’їіqZc†БDcГYЛtщ*:A k;Энб”)S@ ЁC;lšЛ#љaG`PЯИ^IбЛВŠі,wИмAѕ’vиК‚ ў~Xl1Ча0Б,VkZJaУOГлыжaˆ r`ЫK †ЭvŒу‚ЏЕlй’ьь§р<""’EЯž=йMзЙsg”л12?ъъZй~яВYTЗ НNэRgœxзО­e.WЛВœ~Л–ЗХћ§#кўu–3І[NŸn4фн9_у/gƒRš­&UЛN€Aщ]OАъ_ZіjEЕX.zIЕд—SkЫ'œЊƒ.ЗдŠЦ%Яw)х9jъ™–!гŒB­4лЛњ -}БR’Љx\JDМгG|•кћ\еrј •СЇѕ™˜Шр]YŠЭjсOjэ=PђіМфЏ›rJD_јщџ,ЏrИЦœ’9И%„˜ (ƒFш‰!Т&f›QП5nLў№‡?Д†о $щл~йКbхЊвв2—“uб9:й9:куѕ”—WАuœЗлeV­[Щй э[І(G‰Іішˆ=Т“#k—ЛГ‹їх–b2Б:уъQgžкЭИz<2 Ъ BРyдРФЇnbз Zт—Œэsч пmкягшЂЕ›{Џ§ЋquГи>]/л{њѓпnйs№ЕЯз‘їYЬ6ЇJzфІБ‘aAТА9œOš4iьиБиlВЪ BШMX>]iљПгN;­г-SюкЕ“зр6oкœ—прn‹нК%—WTїNыБfэZzBЂW-ѓ<іЋкšйЭ2Ap[ƒœŸёї›aЃy=о…СƒЪ€ДЂEX'?щyk’т(гЖ…Ѓ“ѕšЌ[VћVА<ІЊњ$Šў‘ъZў6ќ-sЉrx>y(:|'6umЉBъИXZI–”Х‘E›цjuяЩ нмеЖ*ЧHЅШHичАРЛЎyнcsЭ БљŸЏЁdф€D6uєСwL=эІ'чUVЛ~\—yЮЈžцŠБBžМm\pPНŸй9тАEš­h …S=N`Б!Ут"C23•М”›№AAс&ёіuїюнW‘М ЏчЭ+))“T Q-q••UхххNЇ+%Ѕ;…ј3ЋWЏЁ ЅGjsX€ЭvЮ9ч4зФ1•G$)пQЊchђз[j~C‚т …? arfъ †*A‘ŠЃ'DЉCЮ$mх+`IЩнЌФ†Вж$Sд”3•а8і:шЇУoдЫЫs”Т]dGI–бфяаY§џZq† АжКЋ/?ЂГ{tDАQ…‡˜[X™‘[RPRНc_сДGПœ:ЁџWŽ4к<ƒ#Я3wKˆё5 XълНѓіЬBЃQ}ќq:aDŠQhdˆ„Ђ6™|sўНЬАЁŠЏL`БбІwяоBШ./~ВУЦ3f}L5„˜ЁaOšиoаH‚‘hШD;СјБ‡Є[Z зpЈ>ч“9 ,XПqcuЕяK;1;ГУmќјГОјтЋUЋVг(ш…П€йИOНї6[DD8 :ŒзцЬ—к*oНaAkжsZjЎS7еf7hЕТM !oyЎљR]>И“Žœв:U v?] Q\UКЋ#ШЩ\ЅŽœ№x9Е*ˆmяO:ьД„!zЦ”xtOwoŠ3•в}ЖМ_юŠKњэ”AЇєъв˜1Б{_љ!+ЏьУ…П ь;щДiŽН„эsKЊрƒ~k’[BL˜9ћrыобмМ;П ЖЂO­ˆP9Й…>х>17Ўњ"œАk“Ÿ I†А2(bA† Ф  +™*$‘i`Ц7  „ я>Ш4Т  B!žвО}XƒŸіyn^ОБŸK$Ђo=zЄЄвВВХ?ў˜œœХыB`FŒ#%‘‘Ф-bcуКvэЪЦmаn\mwke\пБТн’з6Мз„њ6шœКLиyЉІžЅ;єИ:Ѓ~ЏьR*ѓ{'ЅЫ@5GJV‰ Фш"8Ќ]Л–зГ}€aс„Ž2їУœЧыо­лœќ””дkЎНvтФ‰ЕйlHє Z їлИqу‚ јј3‡іžяд …NълaXi˜ДЭџc€Жюі_›ЏHИЬЛў]Ѕ"W ‰Q0Зj“? њWyаЛцM ФЃ9wšŒŒTЃuТ ЅћЕёџезЌ–Ъ”б=…ЛОŸРЊлK;Lё.N!~§ГuGзƒГ‡ЇP‘EЄ5І~aХKDИћfЖР,-IпѕУЋ‘7Хžїla§”›ЙV“љ:qG? >œ`рЙ'Ш+1e6†ё~шх—_Žy†>щеЋ{ /€„$p‰щŸS4yp"Щˆдж7A—`ЌЩЎ„†† юАЧ’“ЛЩ>4 7x№`іМXСА„%$§D›бћh е$ЯіYШH ц_^Q=qтd>` rаKДEыддqЄ д­№-E@uыm7 и/=cWBзdјЈ€ћармQ2жIy“Nѓ~uЛR],с2Нч!ъШли[­к}(и(ыЏmћ*УЩбЋ`ЁЅžхљщodиОY[ар`9ї)Џцб6~€УУF5§Z@Ј:hЊхМПщ›й6}\ѕа\Я Њэ Љž‰0Ь†і7яž~—œЅяbВУщ),е•;Љ/ŸаяжK†ўў™oŽЎMBо|f`ц+‹`Н’Ђ^Мkr“бчл3т”^qOМГ А­лQч_БнцŠI§Џ=wPlM7М“УЄ~§ѕзЃapа˜[иNH3&+§нКwyќБg˜ухЇž~фЯwпџьГЯ"И8-8§иc GтfфAŽШ4 †ˆўвЅKQh&::*11‰Яъ‚7Ќ2ъЂaОџў{>РK№Z0#]пДiЖ"14КёћпџžСyчГxё№yзнЗ—WТУуvяЛяОжмp{Ѓби:ЗE#TрЌP"XЗQУКNВOG—СYЁoэ2ШxГ@sVjЈ ЏGЧсбx<:`цIЈ-3Ї”™ž9ОWr4GѓеЃЫ;]žэ™[в р6ЈglR\/Б1Oє[<ёИ Аьƒvъв˜ЌЙ’S55дгNVуњёз˜ЙъЃСгДy Ё6о2hќЂСБ4„Хn†&744Щ%Уыwќ5yѕА… BxKQцг%šu€ЂdH№и@&|bЪЁћ ДPŽ7_K^MEl<№€оР?ЌєГˆЩUtхb‰‘‘ „€ЬQA“'OІш. ?@l­§ŒX%б1ŒГЮ:kйВe|РK—ќGџœ˜h€€PВl2rфHfzBjˆ5§иВe A32ˆ/’ $$Z БF;Qœ-4х Т ˆ>ˆBw‰†са0EЉˆ“?кPkhьFA,.‰ъSМњ—пШ t4œв+--њ“NЬ4@r‰L“P#$ЄWы mРПlйЪšYTPДsзЎаАа3Я<ЙЧKС т`JˆХ!йœТMš#—HЂgШH9Ц!Ъ …C Д,ZДшСWм9u!fХ@‚ N)ФœТ\h`Bп ЩDсNЬxљ[ё€Œ@ф Рc иpеA1ХэaC;5?Zѓ bl_ЖdkіH-DУР‰Р)јё$бЙD]D‚/ОјэDр#lСоЭЗм@ФlvnDD4} :эbАЁаи7@ыв%`vњЃ.Мјќ}™9ь)…!MїнwlQѕ?QџœШh€Ќ5–бBрAР€А‚оeЁ†0šluIKы#[`@В+B3 ЪTчЙ'q&˜^`€0ъoŽŸВ’}4|Щ:5ЕЛDЬ~ЗˆˆYСA=F'+ЊьРяЯT$Д hо›nООВМ*;3— D~~иц…9`F:‘ЃцoЫ? ƒm†@ачЭ›‡Pтcргdc; jр еєSˆAФQ`t ‚’ЁЪС!‰ ћDqтљ)жoXД3 ˜сЅ@ќ‡?оlŽ˜˜FH Œ1,:pHЧлІM;€"o§€j:†‰H<š(эRт–ў8‘#а9Ђ: №3Ш(“=rh"СH*ЮН@1Хѓ!O0и smqЪФO9F! RlєрСћ‡l9ƒ@‚4nRœŸˆF Ј#>ќœАВMшв~šнˆwZЇEjЋQуŽ€ДьŠ8"žє“A`мфюЄ.З ЃzDЌшQ*ђ“ —дen"1я+!fи™ћЬѓaҘcЅ‹IьsIN!@ |ЦYnЙ…Š<Ѓ;vp ,@ж$чZи`C*xи<~pТФНФ— јбvЌ5ю˜В+яН!aё БхтШœВ‹ х@- сД€” 1G8 ’Ш‹TIФŒƒиQШXˆAЯ›М„яРсЈQЃ}Ъi&№Ф 6”` n›$–_1D‚е?ќРьРŽ$sн;юИуВЫ.3—јф™Sо|ѓMІ)gФЎКъ*Т›ќжъo~ѓД4KР22ЏМђ 1OШ|Њј0lђ>ВUЗЩЋ•žГ•ЉЩЋRШдiў)X)”[n2<УXfс[nЙ…u9V8о{яНјwИK l@˜с6d~ТLбD”ЙŠ&Ь^ШBš1фfЪёdЈ‹zAšeЊ3A‚ ђ$ ђAЂƒ№лoПх­ “ˆ42сQK 9XБfŠ$БaуBрР нƒШ˜•PžЯЕ =Bт­я к•_эfт  w„5‹ Ъp‚™df,чпўіЗ\Нікk…ГЙJы:‘”XцL ќьЖ7>*fТ /М0mк4ірŸШnзЖ ‡Щ ё!-D yDœ ђ*Н‘YPц~Ф—Sx@/’HЈ€Ћ$jQfјEЗЏОњ яСЇn0=zфЃ?ИeЫц?LApˆŠЧ;Тjbмщ˜єР>аЎ€Œљ,!)acбЪ§йm8Rп|ѓ Лђ˜nМёF N8ѓ=­‡zШhтЏ§ыŒ3ŒS#ѓјуѓEЉbJ†НћюЛ™А6йИD!R%Ј@c32|№ЧџћпœŠ]Ф;|~ј!1ЦvётХO>љЄO˜'цРE]єйgŸI[ŒвЃ>J|eТ„ `O хCД7kмьДBЋ›/ЕU~цЬ™4ёїПџ]Lцм+ЎИ•%bгV­œ\> УМОdЩn ЭР@t…ф}Щц(…Тс9qbJxфH9%d8… тŽ ЃЪ0y1xЬXw( B‰{=юЋЏОЂk|ќъ•vэмƒЊЁpܘ10сЙŠеGЄ3Д‚ќёњђ7bФјЃs>лѓођšХSž{СЬ‰[von“ХFBІ_§ѕ… оzы­№Dяёьe@шЖ#ЗuУ 7`Эоџ§/a†!Ф\Кчž{ž{юЙx€S p;IDATйdByз]wЁ6y'Š‘!oЎЫo=ѕдSŒ6Њ-эS…лџѕЏЭѓЩ'Ÿ0 €‰†ъМ‚рВЫ‰‰џЖлn“Щ‹r`ѓЛп§8НікkЬ;˜тЦ%sЃЧ˜чF˜}˜`Ж]sЭ5>…їДcЭ |ЏZЕ Ы{иАaИЇ(ЖBŒФ&{оTcК‚ Й'‰љФT`xPЂ(HЈє!,40†ЌSˆ@ \ЉЙsП XzЬšѓ {рay‹Ку( !Џt3€GŽѓЃ7Q\јCбWžоОу.rЇчo{љуYЏоїцБ?Тхt>єkъх—_F@ЇOŸЮF–€YƒеќЌ]у†ш-уU<Є„ЃA€›ёщЇŸЎXБB|ю…ЎШ7В ž$ƒƒwи…)Іs–’С!Š&LѓГfЭbu oышс‡­ШzРеW_-=ЎH№O<С)7ˆНЭ^[щ’ћ‘Їyи9і†N.‡ШH3ПГ‹ї‚ZР"bВgrХnAo0шXф №№У €A6Ђ[PYИзˆ4 ‰Š иP т$Hpi …Ћœ2YBL-hz™84А•1B иpmиСќ‚ђи2ОхU4ЗтБ[ ј(Ь1'кeІ6ˆ)]"”‡ёFгфp?~<г“Ma…ЂВnОљfІ^ƒ€<ї‚ƒƒG!ƒЩ˜0dPШ8ц’УцйэŠ#ЮkK˜y4OzЫ1€gŸ}ЖTЇЋ’С^iL:=і˜”ŠР'i[ф ŒŒёд{ ” rD хNАP8ЬI8Љˆ(њyХRѓ›mџјЧ?+&дРрСtzŽ€Al6„†@ќ Р ‹”€д…b˜QЮ)цСC ЈШГJЬШlI%5…?gў”]–ыют.оQj Д*NХUъњE;2ЩkђБЁ7hZ.бI2”pœ:u*V. ПуЭLпd])ФЧРюbˆ dšБ’B† ƒ€ ^ Ž wЧДb”ЃCЎЛю:€a”˜3ќ+anB№§a€СUТбˆš ЭhŽІ9ŽŒЁGЁіЩДmтFGъ˜j•?ўИmл:Yм =У3Cњ\D‡сёЅsиZ1qбГ_ЏГэХ^х‘@лУb Т =O]0CuЌ)*’†Yœ#l1H№q VђМЉЂc Є„KCIs<]а‚>aо3{ВЗ VаCКа„‹дЙЖxUГ:’УУ:…8 n‹Е<Ћtѕж•#шблЃNє“F}8`˜бyt,yтЫxџxєЊISЭh› ирѓ ІDjсР@ё‘„М‘!y2F-”!Œ:,CЃЫs—)Ь(1gј8aЂУ2† EN1,1Шp мАФН 3ХsЃ„hс2m›јtц"6!"œy Дѕч?џЙm:‰мъч6:<KЬ),bВGEрK№zZxЯžН‰‰ё1Т Ь~ІdЄŸD!vњ‡ хТG.‘‡3C‰ Ѓ‰D‹т$Р™*—`E]И1aЃšвГі|Џ}šdБG$†„ЧиyN•иv5(20Иs`ЦŒcаПќх/м)НB4‰Hї рёvp›eЃiЂIмц™”№ё^€CТн1}`ЫЂedDЇ‰й&fxУчf Ђy}єООС–ŒЙ Аd|xLŒ-Ž OŠБТ^@НёЦТљљчŸ—ъ<д&Pds:”шO‚ТЭрO[Дnœš3Ь&XЫFЪЬЬ”Ћ8oF!Б5ь@тxХєƒXГ CgfиЁѓ ƒIРCЫCТА%x0bЖrd\tоlуЖtA ЦO…МŒ…p@жxбЬгŒ™щ‡`i$NQ5шwД<‘ ь=0Ђрƒ@F‹pƒеsцhPёЈ^4Ѓ%ШЪяа€QеnqTК›eћо_Žё‘0  Р ‡„щг`Шъ$Юц“QвBцЅ—^2Цьt&1ё3ЭŒйГgS—[ЦdХWA3pњєгOГюEгhrЄџЫ/П$~`nХ\‡Šљ/”о2PФж(AЋSћЌтjј@8  yj(sLkђЌNВGбЬœWж Д›ЫЩ3ш+#Iџ)Пф’KŒB2Œ&цЮЫНу†!4‡l№&ыУГуžжємІЦ№`СИƒ€ѓЮ1ЯЏWZђєляafy~жп|рQьdЋ[SPё№€4ЂЛ($RР zЃЁс*QTšc4!УDDJи‚ =—Hdр†p~/*јкжW ŽГCрЉ№дф:*sk:ѕ KЉ*rVяЏюTЗъЧўHаo?ЃЭЌцЯŸOДšž0S˜Ы[™ч~‰ LВаaдТkЋмЏ”0Й0ьШ=v—QhKЦ\…IJ—Pк 5ƒУаБ…`[3зeіAИёЛx > 2VpEС™Ћuqb.ъ‡UбGнФЩЊиРЯсap“и LZЌW№˜-Аš˜w™ђщ"Gф›GBžРЉиQ<'J˜c@O™Ѓ Ц"Туa–EтХЇ Љ…СМK=%с "lЩPސё\y№$ѓ  ЯЩЯq‡зTк9ЮЛfГxљФЃGГ‡В_шРŠЂРP[nЭўЊъЊ`]ŒŽ%!И$ƒswёЬ3Я`сl`Х`2+< “”‘'Cl“йк\в8oЎbЦЁfмˆ4Ў›\‰Jтя~з:К4щшъЖѓZѕШA,аШжВŽžAѕc”#С Д|YонSTP"oЖ0д:ZМ1Až7O…™#7—рЩ 8`(%xbВX„ БЛ  (‚(jёАЩS fPpHЪGtZ^хў k€ІЧlAŽќjG‰KsiФ <ю’ЎСYU— М<ја›ЖсшГw›§ ј l&hCЖэ&ЂНѕЊіЇ9ш –і™ЦZ$›ЩQ (Yц І1$Cхг9_yќСЧџј.:Ў#P‡"ŒШ%к%ƒ˜"хДJЦZTb}ЬМKŒ jl@ ЃœŒ.цЕ.>G 4”ƒМRЏтбzUчŽмыЩе2ь]s{Р„ЋQ10ЩƒCкЅb-}йTnВЮЭЪ,p‚lTб˜ŠЪ2ЬТюнR‰YрЧ)q,Fыq5?sџд!5‚Y…с*NФёхAD4I —M&uŽH0x€…є#хˆ/yL2б\% ь/Ш*Њ(ь|AˆjїлМqš7Т™ЎnеЂŠBЫГУЖgхюthе6G@oыЉVE_…'Ьi‹ХD4nНЂ KЪ!РЄЄt‰Žб=1 §Oд?'fєЈ4Rˆh"|Dф’B>рD “ф•№%Z0Hм“#Ј€­ЦР j‡# n yƒщРЪƒŠэућP›_ОrkŠKS Ў wЭwE–ў"]P„ЭfWeŽртШЕ`5ƒеC”ŽјЁc‚^.‘-RrbFЪпŠЬ# ыBјH?в‹Ќ#єј§( ТФ,Х IА”ˆАЌС‘)Ÿl§Їўho#`6тЎа3CЩШ”oРЩ€ ™–o@ЗгАжX№Ќё*6{чРЪƒ5ЎBЏу@ePч^>ЋaГŒтВ…№ЖЇ-0$Ј*ЗЦjѓb к‚Ќ^Зkxєˆo}SАхVќW§#pвGРBФ™јoРУР3РCўААЉЛMБЈ(ЇЛІЬIlРUшЖл‚C"ЂЛvц›TZХYЌUчАZфБX] QѕИ=іаРѓЦ^‡uвЧХпџД<bЭМmBјX<{u| 6ЃМev ЫkѓїЖ•эЈ.нQх­V\ХЛb Дj•Žš‡—У­bЧ™—Zа>ЅnіkЊlyі*NЭЌ:Їх&ќW§#аFРFФŒ}ў чћяП'юL0з_<~|}р„ иДЌvИ НжЩтЉі8Ћѕ]ЯоОmыqи^ШRSцЎ)+J`,єр}ЋM% цЊђœ7ЄGJ/трэa\ќ}№@Ы#`c†uz\ v…ёю+/ђ& a4ЂвLџ€,рФ(б3рd$CMA@ЂœOЅЗ<НJїsT[ЄеcеЪјB€ц% XЌ(­FsГ•”Эfk€ЇШQф q‡O›v}jэ ’xY-їле?'wъо EшA +3Р†Зsй@РЖќ Рƒо? ‡ Ш„A/‰j2ђ0]P*ю€-0’а™ХуђкЊьбСQЙЅYќІ‹ЧэеœоPhпKіZ5лŒkю9oт ‡7sќШ9Й2сoН5#арmj№`с_[ЮˆYГЇQДDл$2x œ€%dевˆ7p•’‚в§ЛŠї„…DŒ0њтs.Mые{УЖu/О=+#{яФ“'Œ™ˆNлА}ƒгс >hXZO§ЇЊ9&бš№гјGрЄŒ@ф=@њA‘Xh`‰ŒЁm8ќЄ\Œ:ŽIbb96Ж%œ(іžёцлsDqБЯޘˆ$šƒ0ЃЂ№ёkуј3э|šFNsFш‘uб*фt„^Žђ2AрСl#` D5Чг_юŽ8џ щг™„tJIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Images/fwbuilder3-256x256.png0000644000175000017500000020023511733011756023762 0ustar sylvestresylvestre‰PNG  IHDR\rЈfюiCCPICC Profilex…TЯkAў6nЉа"ZkВx"IYЋhEд6§bk лЖEd3Iжn6ыю&ЕЅˆфтб*оEэЁџ€z№d/J…ZE(оЋ(bЁ-ёЭnLЖЅъРЮ~ѓо7я}ovп rв4ѕ€ф ЧRЂil|BjќˆŽЂ A4%UльN$Aƒsљ{чиz[VУ{ћwВw­šвЖš„§@рGšй*Аяq Yˆ<пЁ)Чtпуиђь9NyxСЕ+=ФY"|@5-ЮMИSЭ%г@ƒH8”ѕqR>œз‹”зinfЦШНOІЛЬюЋbЁœNіНє~NГо>Т!Т ­?FИžѕŒе?тaсЄцФ†=5єј`ЗЉј5Т_M'ЂTqй. ё˜Ў§VђJ‚p8Ъda€sZHOзLnјК‡}&зЏтwVQсygодняEкЏ0  š HPEa˜АP@†<14Вr?#Ћ“{2u$jЛtbDБA{6м=ЗQЄн<ў("q”CЕ’ќAў*ЏЩOхyљЫ\АиVї”­›šКђр;Хх™ЙзгШуsM^|•дv“WG–ЌyzМšь?ьW—1ц‚5ФsАћё-_•Ь—)ŒХуUѓъK„uZ17пŸl;=т.Я.Ежs­‰‹7V›—g§jHћюЊМ“цUљO^ѕёќgЭФcт)1&vŠч!‰—Х.ё’иKЋ т`mЧ•†)вm‘њ$е``šМѕ/]?[xНF ѕQ”ЬвT‰їТ*d4ЙoњлЧќфїŠчŸ(/lрШ™КmSqяЁeЅnsЎПб}№ЖnkЃ~8ќX<Ћ­R5Ÿ Мv‡zш)˜г––Э9R‡,Ÿ“КщЪbRЬPлCRRз%зeKГ™Ubщvи™гnЁ9BїФЇJe“њЏёА§АRљљЌRй~Nж—њoРМ§EРx‹‰ pHYs  šœ IDATxьнИgUy/ў 3 ƒЬPfшu(вС"‚‚bCН1Цђ У§ћDџсoтUoМQc41эšФ'šл“k4&Б`;"Eь XР:щН—рџ~ж9п3{~œ3ѓ;eњYЯЌYkЏѕЎwН}­НіўэГйC=дЭІY ЬJ`г”Рц›&лГ\ЯJ`V$0wUbИїо{WеНбєН№…/мЖvBћ‡ЁС]QяњђO~ђ“wnc-чЯŸПБВ6Ыз€6ыї@Wзm(рдSOнЖˆпПx™WхсЃ<=КЪ9u}`• F™гІ…iЭгЉтНЇЪжoЋђвЪяЊ`ёѓбЖ Њ˜ ”КІEь*wгТ<Уƒ_іВ—RŽz`ЁхаJЮМc•{mОљШLyАDЪ`[Ўћ6лl3M ~˜zюК­ п‘лlГMwф‘G~ї‰O|тf}ьcЏэ›-f%АоJ`Нлќўяџў‘хL}Gч№Vѓ&Ф™.!gПЏ_|кцЭ›зvиaзžtвI?YМxё#яМѓЮmъкЎdƒLГ;€ RmS"zю^ѕЊWЭ)gzЂ\дЗrЮœ9 8XœЌ_іыИ]гзƒsєwщ;№Р—=§щOП|Ÿ}іYtЧw<хІ›nвх6`6ЭJ`Н—РZ ЏyЭkl•ЧœНЖюъѓњŽмЏ“žыaл?XŽ7~ІнЏ7V иe—]КпќЭпМvџ§їпВVќУЎНік1:_гщЗ~ыЗіЉ9^Xљ{•ЯЏѓ†ћзєœГј7> Ќё[€зПўѕ;–§V‰юЗЊ|zesC9іxЮ7^лЊ№ г˜aЪ­ЖкЊ{оѓžwзБЧ;ЗЫkЎЙІЛџў‡љоmOzв“ЖƒoІS9ОCЬзц­Fё#рЫ•?^љ3 nmŸR1{ 0%Бmƒжx8ћьГОљц›\d7жŠПљmЗн6ЗЖЩлTйнrЫ-нђхЫ‡ ЄЫљћ _OЪЩіэАУнж[omјJsєЏwлmЗ‡^№‚јС.)‡љчzФ#бœŒ=јрƒ-п}їн]ƒe ЖЎЛюКqƒТxНЊЖ… v;юИcлЊ;пnЛэК-ЗмВлyч›їкkЏIiг\їнw_ч‰У9чœг=№?›0ніЌg=kЦ@O;ўЎhxiЦ№пoЈ‹PС{+ф1хШУ/gРУeВБЖЌё3€{юЙчСЪœ|L†œH@рЄœГœq‹#Ž8Ђлb‹-:'ъu˜жэѕеW_н§з§з˜УХш•2\K–,iyћэЗяvп}їцєƒF|з]wuш8.МПўѕЏЛЋЎКЊmпЕЩv#2ZЏИтІ=кє_xс…н™gžйсgmЅНшEЏ,џЊxнv№вuфž~}”ОEUўЁ\ЛЗo­@р…й4+&58ЯxЩ}Г?‰ѓs`[ёvкЉлoП§КЃŽ:Њcфœм!›@Рqˆ=їмГлuз]Л:…o§№шчд_|qƒ3Ц–#Я;ЗСЦqьBтєш‘­ђЩ—^zikKXcѕЏщєтПиЃЯїя‹ЖyЭ9l=єѕ‚‚УŽ‚зT И20ГхІ+5–-[6”tСЙрРIм'юЪC9Є;њшЃ[7ЧОр‚ К|ф#нe—]ж]~љх­н˜dЛл~yІ’`Д&РK^ђo-ўEЭsz9яи)њWчќqі8cњuз•^Xp'U x[еџ~*g Ыь…жx˜h0ŒєЌєђ/~ё‹1№ tѕВл†vЫРЙ9zђрЊpЈ5ѕŠєK_њв§ы=ˆяз эNтаƒ%жњmhZUл`]{зтЏjЬIЯўѓ_є‰O|т††`іПMNk< ЛVђ§л†aЧЬ$Ч[SрCњаЭя~їЛч9,§еЏ~ѕ`=iиМ№бwќСыAGлoЇ~BС|ЗŸuЦg }H8“ђœХЕn%0txЯ{оГWЫsŠм kОxXВg: ;яš„[S hОљ}я{п}uіБхСМЙлŸ§ьgэƒ3K•“щ‡|О~yдЧ?ўёйAnBiЈ№ўїП^mM?QЦзЄоћоїо_ѕo—œОВ‚ТЏЦ“›Д™Nq‚™Ц; >sЏСанzы­}х+_iOŽ;юИюQzT;ѕT"|OЖФзxcz`ЏЊЌРž v6m:*”ѓџї2 #‰eдМО›wј[[…›Ћm,(ЈПђ•ЏМacлxИ&@LЯcЫ/}щKэЩF§ШЈ=†єHtTў3VіtzТЩ'Ÿ|RЊ~!4Ь–П† u"н^@Yё-Њў“фU…_-YВф‡7мpCsŽг­ћтu•ДЕТпO~ђ“&ГњнAл h ћeП>LПН_я=Нкgсl"iЈP;€Жѕ'“žБ4wнkлЇ‚Ч>žзgЌG}§<•GjVсu•8џк јє˜г;ž€д“ёиѕxmСNаоvy сь›„† ^всtS1АС1ŒXж.[ЭыG5эQпА ‡…[Dыкј№R“ї!0#?}ƒ2^]пDcъ§‰‘ч‰fг&!Ё@9ь/ъyќa$2žБ л>оик]ДїєНьwУЄuyЎАЎ€ї!=єа–эъААЂМт<žlЧk[•ЎїИЧ]3Œќga6 ъUк[8*ƒ4ЊUд ьxуГяОћvз_§и З*з“ЯФжЩjх€ыbPя4чЏЧƒ]§*БM;ГМ%N~Чр•шoМq,ЏJю‘П7ыѕы‘gЋўlпF%ЁРч>їЙƒN;эДџЊгьƒ!…дgЂєњn­@н7ПљЭŽ1Џ*eМ*˜5еЧСжE%?CNђіc~Tх—~ёш Щњ&a{(љМ^-pС‘X љ§еWŸ{юЙ;>х)O њйrРPрЇ?§щŽѕъЛѕSкэЪhF.9Оў‰њVею— №?јСJЏџfО”kѓзx™3хэЗпОN€љ9tџќУŠ/ЛuњљЯœU n­Жнvлі3ш8 §(*:№Ž†Г…тщЦ &ѓпўіЗœ0Žaš­lь*0˜z>|д§б}ЛŒщˆКЏ-+L *%ЁЅ>XЎЊЌ-­€_^rЩ%н•W>ќGkыrр^|]ьШЭmX?h›(YщхСdЇ% ~})@,ZДhйŸ§йŸэZђŸ ƒлШЏ‡Жѕ:№б/љЫZї ;еЪБ‡•™iя—§њ`_Ўћ0 єФOl?ЊH[сВeж 3ќŸwІаŸџљŸћ8Њї'^ZПв[h›oEМšL˜ˆmLіГjщеЏ~uWПиu]Ъt"ZgлзМ† !УНdъq\[ПУЏХљЪНВчФ§@аЏ?иŸЖрN,н<ћйЯюЮ?џќюьГПк-[ЖœЎГC@ЋџL€ПўыПі‹<E}N9іЩUїеŸЖmЬcгЩфэ—K—.mK€™˜;2WвS?їћfыП&ˆУЖђ]яzз.uhд=уЯИЉVŽ­ыдy~џ•ОѓїыЦs№СЖД–ЖЊю[mSЏМт—mћыО5AќкNANхї џїяЯхѕщ'–3Ћ7ђ•§КFз>z" :A§XЇѓZ№LІш"хLтžХЕўK`вK№УўАmътzќСzKэžКE˜[ЊЖbЬŒjАCг>Qн—{<фќ_ќ§юэћuX5ђѕ]8гЋрdдф…ЈU/9е=ѕмwОѓЏ(НYзў’Q9ќ.xŽ<ыhl ЌŸзiй‹Sh˜ЩЗ!=„7њ˜ŒwЋњ9щƒѕ)ьхЕCX^?aŸU:F՘‡ЉћІп!ѕЌћоћюэољз]јѓЧ$œеw№оx `bљЁ{dNn>ЛДЛGц$Хowјс‡Зgёк=~АьVА:эжUОgДžЖ МЗК:g5Иа8їяtSyМ[1 ЕЭІІbЈЖЇѕE™юk_ћкцПёП!ЬЉGyжŽрЖ:hко#*ŽдЗ-ѕŒOЛ•гŠя%—Я|њнЧ>њЕѕ]љу› Ў 3іТŠgщK–,iЇтЁi˜rU0уѕMЅ­?І_Їsзh—э\КЄ&›œ-'ИЬІMKSSиЊљб~Д;ыЌГ6Ћ?•Ей3ŸљЬэd•Ё>TПМЏо#˜я™3–2ЮjЖЯ>ћ<єШG>rГЫ.ћqїПkЛџыџzјЃ?cВЛа6еФиїиcіaѕё юaкW3lпxp§Ж~=tЅ 1СжХ-УdD'“; ПсJ`к`uўх/Й;яМѓКњГYнёЧПY§Хмљ~єЃ›3U0ИП‚С<С ўцCxРfЕњlіOяњ‡юычœ=ˆnЅыљlїt@нЃ :mѕŒ™(ѕщ”Ћ;йО>|ПŽVЗ+%Пі‚Пuр§ oњљf€—•&“ьрŸ “‘кЦ;c Б0&ЦјщOК?dё яZщч ЧџќYŸэўѓ?ў­~цКъзС/ЏG€ЬT€{єšП9NŸод'*Э=QпxэуЕM„c<иёкМїпГЯ*O>vN§Ё’џјЧэ­@Ю,0L6йдий3€Щ n‡ŸVшЏъ Wюзн[Ъc оѕЗbеЫ'н[пђІювK.Z„Ыы^wє6`RgœТnФЊЯаЅО“…~[ˆl[зƒ8ЊМЅЧб­юxpяЃЈ]tQлъ{AЪA >йЎ€ЌWѕ”"|Ѕ4wn"›єЭ–ПІbИS ˆъKщŠуІ§кѕзw–fшPхƒŽ<ўšЬc@‡Š}ьcWК/FлxN?и†Ј№8XЎЊovUз?9{н–xЫkЎЙЖняrЂ8–-2‡тdВŸШsЬ1н 'œаVWуН ф>кќ§—•єЁЭљ­ыа–:ўр•8ŠkйЋЪјсtЙOGƒU}Мd odЏєКЏUоћџЁ#sŽ7>m`ЬŸфZRN&и™…—*W тйrЃ–Р”@l%e ’#qeœ^ЁiчъвCе>™ДEѕшЮж8‰уЗђšЧЃIСС}Д­ЖУ1N*Ё7}ƒєілдћ ј“ёх#dсЧB>сwЇђNф}hЗ…Ч{p›?ѕ>ўЩдУƒ1ъвdXЭX|ЬІMKS &Ю‘ cŒ›бsN1РœЙЕM}hѕ‹”ЇчдЩИ$˜mшIн}Ж іє…цёЎЕоЏ#˜A8јW…ЃЕўC—dюЩ‹є(W XНpзэГ(зІтќ1МА ][?ыt m“:Ъ/xAЄ6р†Ў6РN Ц№н єщRя;№ъъc_7=шЗšO&b бщКЁ~vжu!)€8yп`њ?Xя;RЎ1;Кj ЫјмЙ[”БВеї† 7(oЛЌaS? ;fnу‘Р”ƒ“њ`МыfЎџr-H“нlБХмZс†#ySф9Јm“йИ•C^нЎЉ)mіПJУyг, ыЄє)ћ9§­ьСЏд>С…Рœ9У‘Ќ—ƒ&›&Г˜J€™,=ы <яеЇ=эi+‘цHžї >ыюяКі;zШ“Т1yЅЌ4гьХ†&i€‰ю;ЛzЎSNцЄ:sL&L%Рdž БLPž“ј‹<˜шРŽЪз„ЄЛњЯ2 "™Но %АЦ@ 2?(ЅЩ|д#c'њллриЪС0Я•њх"бWхћ'‚mп8%0у€1%Š,С@9•0oоCŸpўM1pфaЮI<ўѓЅ!;Ѕш+њдльѕЦ+у‰j<УђјiиДhбн>ВОнПгАCЦn9†А‘ ЋкМО8фћƒ)zzя{п;и5{НžJрЏxХД([у F*sэчИЋKлmЗЈ{дcŽЌ€ьН:аMОŸуGЖу€8ОWпћ7.y“ф&&€5bd:X_е-Р‚…лдŽьіфASV‡7Ѕ” рЌ$ЩiџO~ђ“ŽуЛчOp|UК/Ћ~=xfЫЩI`Ћ­Ж<ІžD§Џx№ИхЫX^_ПmМћѓљѕ)ЏЃŽ:І;шрCk•šо#щMеˆ#уЫ.ЛЌ“g2Ї\ѕщ:}›к”Aлъѕ#1џдx№хЫ–?pєwоНв[•%SЏАю0šЈђTѓаW‡ЛkWvu‡Ѕu§ЃЪп­ќбЛюКgЪЮ/уx"b'J§О~=LŽcdy[оМ-Л#:К;ќˆЧŽ}Гo~Взy F=йё*<йзŸoo/ZхЉIxпЩёчКЏЋК-ћˆіЧ?ўёŠй4„~№ƒ‹оXЋќ‹–-[~h9§”V­ђo`ю?šŸ6:э‡*0,ЏРp[хk+8\Дљf›_\ъНр№#§Э!H dиpfбн;ігъœЋo\—6cчжVѕШCщŽ~ќБC\Ч0хІМŠЙНђrO?ђJOoкjWі-Ч—@9ќЮ%зWзЖўфrњНЋ>ёЊ8>ŠЁ[Ы†љЇ?ѓ$ZљTŸmќкзЮ~hљђeЛ>§щЯМЎкІ•† /FџЂŒdNиЌ§zЈЏmr"ЃžЈ=„іћ}"ЛЄЖВZйЊVОЗОэwх9ѕ§§mѓG52vВхр!зdЧЯќк447O_ƒ’>r]_R~Oš§ЏIрћпћЮIЕЪПцўeЫ_NПpmŠ…^ъev ЖйЖлЇўЄПсгѓ—\rIћыP{юБлŒМЖНЪрm|я{пkМз ђšк"žTA`^п‘'L`F˜YБKJ{мhлќšcОЧƒ^Q§њ}5пMЕšпхєZP(Ч^RхŠcю>Ђ^]PМeщuЏеёd1ТњNе>eўСzЩќ%ѓПћб~4щ7јБпљЮЗ^^6~к}їнtmяWkc3ЩА­Нdњє§Тz ци:ИѕІцЗП§эюЪ+Џ ю3i7Ћ }џ§пџ§чЇžzълJ@oБНžЌsѕ‰юзћs ж ЮOџvГ}d‰—aпUљњЊ{ЃшЮrј*o_фzeбИИЪУл€ѕє?|Ќ‰МЪфЅLЙ-Ј—‚ў№MozгШ_kY­Ї8—ўъgѓnИсц?,ЛњюНїОыЯЎ|ШЕ†щёЁ‘77Зп~QћЖ|У_‰:їмs›гЛŽПЄœIВ†&-ƒљы*N(BNt=QЁ)СJ§kѕСыЈЁџпКЦяƒіЛvэywкаЇО)І8>оеЩЁ_V omхќїЦ7ОёЬMEFхє‹Šз“*ПАђгwмqбВЈUПЛЏlЈAЋГЇкЬИXтєvГ;юИSЗп~ћЕWж§™ї/|с эзšƒО1уDєN*д!б§ЇœrЪѓkЛx^y8ЃТPп‘{И[uU}ƒАЙvLŒ=`dNЯљhсќAх“џцoўцђ>ь†Z?чœГw^ОlљЋяЙїž“ы-МНЫ™WЁ›Пе#ъЗ-;їє_ќтЛ Fc+НБы[šr#ќрпќВ—НьŒ:4БxTv}#ёєЇ„OНЖŒяї6e`ћзкжDъгБ&№У99њ2ˆѓз‘{Ћ§ёџ№џpпšЂymр=ћЋ_>ЈžЭПЖЖрЯЉGХЛ<јркПЭГcЈРгэT_Y:єАƒЛz™­}[сЮ;oЏ? mїБ}lЬщз†LІ3ЧД€Щџх_ўх’гN;эШХ‹џВ^(й‹У et+9u Г_Ÿы~=mpЉїƒ€ыС4^л Ь†vо'Cwфfх—шСжЕNя{ллоЖA:џ—ПќХуk5ў“ЛяКчёЗпqЧv“‘ЧLСЮ+[~D­ќ;яМKw№Сwлд[yз]pСнвЅKл.ы%ЇМhІІ[kxf$ і_џѕ_xЧ;оqKnьхK3ОAЇU:T‰q‚O=Ѕ6F›лˆД+ЧKЋыoЬTкТУTЦNwЬDМ‡,љ)GЗћuŸњˆкЎnнd_‡]kѕХ–ёhœLлYg}юххєЇн~ћЋе~И?1™ †€u@ИэЖлtЛьВkwиa‡ЕŸRлкљЫ_n+>yГф!PЎw 3pVN>ЯѓM_›uЪщѓдЕ#[С9w‚•ЉяФ1і~œiWO&Аг-Ч›К8'?й`90DNƒфєq|Л0В.c^'N4Џƒэѕ|~Nё№ЬŸўьЏПњъkžpз]wЯЈmЮ7о5љ[щ-^мэЙчžн!‡в$oH~ц3Ÿi+~œ=хxx6ЄЖВU†28хЎЛюкžqzЉТ}“6ЇЎJЦ!2вДХЈ Бя|`лZCяПўи^ѓz] _J2P†я~=LЄ/oŒЬПmK`ђЗуШsыМfnкЮќл-!n’e9§Ж5фщ•OVнл|аЬfю*›Йѕ–лZYЁЛыЮЛК[oЛmL>“œn\p‹’WnыіЕН‰wаAЕэќ~№Млћїє<.’ ИqF@нknE  Q.XА ‚2NЫљŠ:˜Ъс”v‰YъпЄ-†ЏПяшiOЉCIx#Ї~ щ ЏJАJ2S œVzNOЦ‘§€у7} еЯсnъЯЗЖыŸўє'Ќ]спqЧO)~oП§v›-нБ,мfAЗнЖл6>№#oПнУoљ-&w–нqћ- АЉz аvžУ№SЋК-ы\Фсћљ<АѓGR/Нєвю}я{_ћc*фŸ< ь{г IDATЮ fF@9ё–”ЦЉ_0ХсЏ‡ЇDЗœ`!(И#fдЃЦ;ІЦпOƒз§ОѕЙŽюž##ЅОШ*}`Щ%NŸэ}пёГњы›виТщwхk=œqЦЧž_њ>§Ж[o|­р+Н”sУ 7>LEžБ лV0pО`СжЭ>ЖлNќђ ОУUоiЧ6іЖлno<НгnсжлZPИюњ‘ЯЁГЫ.Лt‡zhsz?Iї7Ю:ыЌі—”Ђ хњ˜шy›m>ДpС‚,Џ› g4д с‹R ЏЯкЮХˆ6чь1xчЮ Ќd2E9Йž1ШqˆГ Ьњ˜Тx\\Їžл$†ˆ_A•<” †‘ 'Wя_G^iSТSэ+о\YУТљЯџќїWесн)ѕWˆŽšь§ќmЗ-ЋљіюЊЋЏy•#aA- КE‹ЖяЖБxTНœЂСъ—НЉwр,Очtпњіїšглоћ"2ЇџјЧ?>іbNџa“­' Ÿз–ЈGžЅя{Ÿ§œџіG3EкŒ€2аљ1:Ц,ј&]œVCз?ž3јА`@)ŒлŽ@6ќq Bш;КzЎS‚5ЇЄьУДЦiў|JјУ_J|ЦБS'Wj—ШGЖТGŽi‹+г—’œЦЫЎ/™&Яу ?уу]TЏТўzLwr9§ОѕЃš‡П:оРIЖнxуMѕЇЭЦпФ,к~ћnѓz§v‹’ЧnЛяб=ч9ЯЎРY‡вwмн~Gџoџіo+͘CЖыkФМ–\{ФfяsцnбЭ/ћЏ…`FWЖ х ѓb !лоs^Тfш1ј8ŒВя GRк)иA `ƒл< [Š"]ƒQілРhƒ/)ѓkSO-кЧЋk“Сї8№сЏ­žkуа"у%ЋzhL№!їх:‘ГЇ=2RВh˜б@­ђнsї=Џ­m§sj+П озEкb‹Йѕ&оЂю€шѕЈGuЛэЖ[чфўŽ;nыЎПюъюня~ї˜ЬЩa}Mv3о5ЈЏ7}2Nћ;РZ зЯPIЖs `ЫјlхГ‚k‹#р.Ю•’cФI”ЙžЈžqqFpr”леСcŒВЭ ŸЄЬuwњ2Џ2И•Щƒэp$ы s“yHОцЧ‰'žи~чмЦ€M жudиЧЃ-лћ8{Ъ8}фŸёСЇЌ4r=RŸвџџіo<ІNуџзЭЗмrќѕзп№№К)aќ Џ58Ф;р€ЛЧ=юqmЗљУўАнЯлтгџџЯџ1yФky„[ч_›—­Hб'Їя;О:_Њr§ eРлХpŸКц(ƒЫщЫjЁ-ŽHъœ#NG LкSЗkяnƒ7ЇFuI)spЦ(э.ДЁ5gрƒ[Љ_ŸN–Д‡ЇДѕЏеЕУ!Х1wЌƒЋыЏП~L&­sрПШШqф†R{n‡r­­пЇztTлJpгNxљџћ/Їж­йЫЏПсЦЃы/ ЏєЙы ­р›xюх>њшц ѕЙКю#љH[ё#ѓШo 0#(-Œлз}§цsF:ЄOyдЩЧЪ‚є—ŽзЯPЖ=СGјJФчщЇ(ЗqRгЉыгЊЇ/ѕ8}`вЯщеэDЬЇ_тРъЦ›3јнZp ­њ‚K NЪ<ъxзрЄрUЯ8uЩ5ќ№8С{‚аФŠџСFN)уќhХ—rаёЕ^йТ'ЛЎМѕŠ™&Ўy)ЇzŸ^r{юe—§єХwн}зі7еYŽ­ЌэфЇКћюЛ_{яЈЃŽjђўЮwОгНџ§яoї`”Џ№ЗЖЩz>П,\ДhQ7ЗœžUчєl$€ž]+Ѓыбrэ€#šД+сVW ™__№k“ћєЅо‡\c ўЫu@}бЕэŒЬwњЏЭМpЧЉ•Щ‘iX}рS.Ѕv8Gi}Ф9ѕГTs~џћпя^їКзuyЬcјщЇџП{жЏмN9ј ƒŽЋіЊq[s~јЁ-7 њя†oьnМсЦкХмPѕ:ЋКЖ™LvŽО”ѓшG?КcЛwюы‡L{o&чi\lpётEЭ§h‰<“ћЮžzњ”tЊuњ1[ у™L3vXŽе>—ccpˆЧDП-Œ)"†d№вЈЁŽ•a–у‚,9’ФŠв*KЈър“аЦЬќњ‚ \ЎбЃŽ9pСƒŽаЋ.ѕЫ№ M6oв;ьац„ДУёЯМ‘ Zх8Ў•‘_`CWpІ„ЛњЖѕлtOZіЉ/ЭОяНя>ЂNэ_wгM7?Ѓ^Пн -gžљЯšыsU;VоЁлЙюГwйeчњmЧN†‹~љрƒjtћq_{эЕнuukS‡mЇpнu7Д3™1 еTœzяЗпўэ’p|ЗIпњжЗКњnAћM=ОТуjP­гnŸлsЯ=šн3ш,Nž’_єWћОгGз}§іјˆнЬTšvјєЇ?н њK_њвv}F BCx”‡ЉDЖДfСKњёх^ueœ–Глњ3bЦы$ЮN›RтќpїЧQ’ўДЉЃ~cСЇGЎС%kW—РІдцšтГ;щ?б—иО дбљР‘К>зЪдлФѕ_hщ_/ —-ЛяЄ{яНч5\pўуЏНіК…щя—7п|K=ОНЅЛќђŸі›ыЏ3яPo;vЛT0PЪ~єхsWЛэЖkЫ§‚œТ5з\лђѕu сšn$Џпz Я!žˆ‘йо{\чv#|)зчФžwкi‡њƒчvз\{]wќёЧзЃЪлЛqtЮЎЮфј€’>(дхшsPПкc_3!“i€3Ю8Ѓ=z)ƒ[ШY8bтЂЌёa6Lj‹0ТЌёЦDЪД)ЭЇ!8§œ7/йBJ‚ @рцЏПE Dƒ:|ЁЧu_РрТ“zјP\ПЎЭurшD:=e кЭ ŸzJ0с7ѕU]уSц ЌіДЅ\Кtщ~упxЕОЉ$oЮЩ?МЧюЛзoуwъv­BJЯ{ьБ{ЫvvxўьчОаœоіоwюПћняЖWpы€БёОІYЏ.й7}dГzй_>с-И ltЪЎ]Чс]Чжу№Jce|ѓјAЎћ:эзgB гоЅОќђЫМoчžБ%BFО2 Ѓ}AhЧ`„Ђ†с%$ЮШбƒлЕ•† ­юу“ŒёD ДPŠК`”еОO1€ƒ_ кiu-‡іды:ѕШh€пМIh‚ЭJ}JЉ_ЊУ›к•;8ЦЕ1`жD-)ёТљѓ˜ЧЖ•оћїy1ч†ыяюўъЏўЊб‚y}Nшуєœ{„V_їнЊйO\IЏlяn•,0tю:@=Ю­ўг–ыUЩЃЏћUС л7э`5хdЕэо#вˆ VЌPŒŽсFq-ы3† •кръ ֘\srBuЭљ E›ёRvСпыП8Ї4Ѕ р‚Œv ЮuJ0ЉїлЕщ“гžkМыЯ}cаŽ†"хZнx}§RЛЄ=ЅКLц–њeшQ‚1ЧšHx№ѕ[xЧsLsл{ям{A‡<џщ]яXSЏœœоNrN=ЖcW рь.й˜‡LейŒ[OзЦ9У ыи vѕООRW&Ѕž2э)'jOџdЫiЁє:]о†’E>Ц†йЄтcфъr_0ЉїЧсњ(C™3ŽEШpRR‚еЧЋУ`()8а&O (Э8ух8bц ­№hs­LЦЃКR_œ ­Ў N0ЙпрkЌve29ЄZТ‹>u p§”qЪа  3•№цOXy§жŸЇ Jюј@szsЃ1yІц]SxœQ,ЊWŠН‚чeYPиžДYј№Eњеckv2X§њЂыд•RЪСzыч?8g2M;xЄфwдХќ6˜aш˜ њ†G§ф:Т—#з^œ,ŽЄнЙƒёQ<С­=u;o,…Щ№Х‰еC/qъа\Цїћач Ќ6є‡‡дCOЎе“2FйЯцƒqMОЦуIRЯќxЫPƒKŸКБгIpzчОўXlчХМx\їЯџќЯнO~ђ“1оТуtцZcwиaqлВлжKt‡'Sќrlэt[KАЎСъ'_зФЖЩžш^П6ђLкW•&ЗЊ1Ћы›vАк:Н­ї№ї&,ЬЪI”@(Ž’ў0м†6l—zŒ—09†d,СЧР98 аІь'Ю\oМіАБњсдЎЎL2,ИўИўја­ LrЦѕiОрсh—2Я`{'=€ЯМъnгЎКъЊБЖрІєл>ћьл^Ъ9тˆ#кэ–•ўэo{;љЦ‡”rœыЦЯk—,YRКЙхdф)л!К&У82'svВ&[0`]V]›~edЂ=‰гžЖе•§ёЋƒLџД€?€`XЇКЛ\xс…э]эЌў!TЧе1ŽЋAШк%Bs V N]2N] Ÿ>0"Аљ(#B#ЧД›œ’2%u83NлxѓkCœRŸІжаћLhKГЖЬЅ О$эрCц ]С^=2ш_Ї8Т“лp^bМј&YщМwo{ялxОй`…їїыЎЛюК6Йф !yбШуЪ;ъћўри^6b qdђ‰C+ќБ5э`№JЎl.pкрPF—JСии НiŸЌМЂG?ЋїЇФJ O>йдf&M;xфВЫ.Уш˜c1R;ƒ8?ЁEHJ\`1J@ƒЉ›>С#И‚?FO1˜(n№њЬT†0ЎCvЉпЏNNв–і~<јIр~Акб†ієg^8Р„ŸЬзŸ#mЦєSјбяp“^|Хж<ГЊРщw/'ёrŽWqНЬтгзΘ“o4 cCIўŽп зпXчG—ЬG§–њJ‡vRЯFиЅЬQ“щFЂЇЌь`ШŽѕЧVЃђюлOdН‚O=cЬБ*yк=ћ€‰ЧьЭ]6<Ѓ ˜v DЛМ>›МЌОўГ…WBcМo~ѓ›лзU§z‹Qi—b„„ЁaŽ€"XзRJхРц‹0s‚‡е=И"TѓФщћИгE(e0цЫœцзz]›CŽ‚œЙVіaбl ЅjGйи№dŽДЉмЎеe0hKJљћщёеW_=v;ЦыбO}ъSЛќЧЬVzэwїнїhЪЪŠяEoф}х+_iК™;хJƒзУ 'ё{яНWћсЭїОїƒцЌ[oН Щ›Ь9Ѕgѕь‡гЛцдєBœОo;њРHєЁЎŸŒg{„DNВ1`СDЗєЅЯ<Щ<§YэНX”yроџ§н† З…3`ˆ4э š:Њ-ЪЇžzjлVљn:CФ$fм{К=АЊnŒ#BRbМЌЎ-I˜IкЅ(AIIL&8Иex2GЦїаЏOЪ(а5Ирr.s›+ МdžЬЯ l'С:4еgЌ`†~eœzxg;OйМ<5њfыrњšЉДТГІˆQФeDЕнœsўљч7ч>§єглЖхѓŸџ|3L‚aЈŒLTЗO§ХљUЧ\’0-’q’’bє%вЈ:J„vоЙчtпўж7К[nійЈ‘ŸЎ.\ИM­‹Л§YŸ›>јюqGзпo5уЂLѕЬgnј•’yЃ8Še,2хІ/ NЛk4+СРzЕУУАР“~s„Ÿр Ц€гo^Цы( GЛ9ф$‡YOyЪSк‹8АC;+#zЦ3žбVzgv ц я)ƒg}-ЩrЩ’НляцЯy6gŽуƒI=:'ВеЃrХ;}D}йks­Œр$;эtвO`Ь-ѕхКЂЅ”љ„ \G.uр*HУeсАгЎЙюŽ™(Ї8Й-~ p +Џ3†‰№?ўу?nDћ‡ЏДФ0jg ’љ †н{Ъ‚7Ч("ЪШћќAyЁ2gџ›Пњѓю‡—ОЅо•рnoљŠ+~е§•/–ѓПЛ;ђЈЃЛќ’zƒq‡1@œ’9Хrд8 ƒІМ]>tъ‹ ‰Ёƒ˜“Њ[uаnМљ™Сa ƒРS P;8ЮПqъц5—Ќ0НјХ/nwфыMЭ№#ўшG?к†dž”ƒxжЗkŸўВhьКы.%Ч‘ЗюШ0™ eзœŸ]‘!}&'и d &Я‘‡69mъьAП:й+щ-cp§Xє?šЂ3їѓœйэVкŒГ3>ќ№Ул.й5}гavД™OпLЅi[яМ­WОGVEЦ*В!олa/|с ›#8Ь№V˜ƒЉ$L‚'QЮЁсйUиxЭ8‘ZХЫ‚У{ўљ]5Іы~џNo[Ін*H7Nцз•/ОшћнеЕж/сК ЮџzїНя~Ћ;љ”пщŽ=юIc=q84™ƒБP ПыnnFЄOІP‰AИ6Vf ŽNЮO‰љaŒ>єк5щW7~œЖ tОІLŽdGяK›Мў3жsyЦ#УЧˆ.КшЂБ]˜аёы{IІћьГЄ- žеЧСщ"ŽЎЭ5‡ŽS“oкй <ЪД)Ѓ3ђб')e:Ј4y жц|вр8}€,zєkМdQАhJ7{aoto\?7 ўoкР_PaшE№ц„ЪИ:eѕГѕєEС€CИXZABєлoJH&`BвgkфšPс4VJ0ИікkКніиЕ{ЩS~ћaЂY\їOђЃ+H§Зч>ЗћEЭљ™O}ВћYА ѓƒx_јё'<Ѕ9;'фd•b9#З]ЄtpHМшCOxFš%uурa$J+Х2+|кЕqvp2К”qи‡1U ўт’П=/@*э р‰š?)uЅŒо !эЛЯ’n—тs›mFО „fђ”й §а~иYњ”r~*‘>зiwM.њр œ6зqT§крЅvтZ]ъЫЌk}VzNпбЉ eзь‡tžЂ§х_ўeУсПux’Ь%™зз’оѓžїЄ:ЅrкрYЯzV[yЪр7#œ.B"Dэ˜ 8ХqрЃ>К!(FЬ9ьтL‰в‡C{œ‹ђЎМтн“ŸrbkЛш{пя~іѓ_еЮуКRže,n?AнcнЛGА_З_ЂОњЕЏыОpж™>еќЩ3>вm_gЮаNш1ŽnоЬЧQ 'E—ЈCР—kќf›.H YМфрЯMo.8рC^xƒМR2†“чМФŽЪ\vWцЋŸї6њ2Ч ФˆєЫ№­Џ‰ž.XиїФуърјъЖА;%6"“‹…$М!}щ'S§к№-Hаi‹.Œu­ МzєO>ЉƒЃ?ВдgN ~з‚y’ЧЏо™`яЦfќ>uюхŠ%K–Д6ісў?)јs~INњІ[N;0ЈZЅїёЖkТ   сД6 Yй9ŠqњœvкЪ:ќаf ФРэ0РSК6А”M1ц9јƒ[лзОњеztђ‹юЖляj}ОxУ 7VPЙЙn9~QO!О]€­е#К“ž§œ6цsѕx`yїЙЯ|ВшЙЕ­ьpЧp(P=ПўѕЏ[АbŒшВЂу‹гЂ#Ц%выуЄЦE՘СIxŠб1"ЩˆЧSv9n}œЃX!–жNЩaв==œф ?<Œ‚‘—2_њŒYŸвюЛяжэ[ŽБэvлЗя,_~k;›ёЗй ™бЩш/N›lщ„ьй€О8'Yш‹m(eВЁЫŽШоИŒeWкSl7ѓ^ѕШгТ•tійgЗ>зєiЕgлhуєnsc§93з`›vmВyg2ЭH(!юDY„тъ:F %aєЃ3#&c‚Ы­DЦ9kpЋa<Ї“ЏОцзЛYїгЫ.ЏяП_пнtѓ­%›‘Uм2|JŽ{ўyж˜МЛV˜cZИЄ‚Ы•oИўкЖs*Аq(cЭN††§ш8~3OVpЋКqше/а1B™S'Xpt‡žюИ Hv@vC>”с6ШќЁ‹ђЭяZ‚Ÿ,НOИШ1Ћm]%‡xœ~ЇwsXє“ПЬi8,ZёJNJ‰ ёлЗ-pјг.Б;LrЇ3КЗ{ S‰l"зЦКŽ­mк”БaэGзь„Ю8Пы$AЫуnэsГК„?Ё#у\ыCGъщK{фіщ–гЃNВc_hкЄДХQДSА’№д s""ЅQ…qž>хъƒ‹3чoШнџНх$W7ОЧ|pЪЎб!Уї§я_мэБчnЕЅоЋїўѓџ)ZFўX)х<КZЩ!ЕЁWbœ№R,GеgeAЭч… cŸлF#…OŸ-<ЃРЋЇ$ЮAЬGt*Э)ЋЃGЦ‡9С УМц„SЛœFcœv]ЄvXм-]zeћшёЧŸ0цшŽЃгЋk2ЖусHxH ХЏk0јЕсйXu‰>Д‘}?АЏО|ьЄ2ЗБбq№Рe>ђ3Ž ѕС)slI;Z–,YвоuфэVщзС7§Бpt –­Јї“~seN}цЭмш3“iкР=mЕmUbsЪ>С00fBС0хБГЕІ ЌЅРk\Ы–Dн›k›/щзx9єќ№вЗppн%9Ps(C‰ ˆв№‚4šЭV]ЛП$+§іoџv;МБђƒ1^ЩвкЖУƒ6‘`„™K2Юјдёрš€—ЩBТgфh\фЃЯ8ЩМъЪ$ЮГЖвілoзюywЉ•ў ЏЙіњЦРH~hСŸ:ШF›;Рwф‚Yrn‹лqMGБђД2ƒЕђ КY\њМ›мш3r2l(эЎщнJOЏ}Y{dэŒfŸкбах‡>єЁіъД7љм6Z(Ž;юИюwїw[=ђЇK<уЏŸТЏЙ2__§1гЉO;LИ‘„bSG4І”№%Ъ‹ŠШщš0у,СPLKЃ†Ž .ѓfnуњ™шћх/—6јl]PcBЇ­gЬeuV7–б10ИрЦe‰єhV—аŠЩ8э” /уЦЃіAљhЯY‡>s€CWšргЎœkЅ,…oupЩ№ЏЩФ1­РК[нлoНѕ‚FкdsЫфžk%оДЩфJ>2§Ч&ш–3 +с)A1ќŽкcг>cCVћ1Л=šпœRpР‹&№цВгыРмглт 2ЮЉ~яї~ЏћT,Г~|Ю<ѓЬvШ§ЇњЇЭ^Œ‘ЧKјD>ЂWєЈЃI}&гД€ШWЦп> ТБ‹з§Эб”39јЂD‚љ9ˆ$r3c уЦej/Гnu}ф’ /yЄo…ИNРНЪР3,t3ДЃ›QЃбМцpMбЦ€‡<ƒBŸvќ'№†ёš^ЅvuNс“Œ—Р™[›vtIС—9ѕЃ!IП,i‡cІО9ф rк=K6лЖ9Шџ2=Цљћe`BXmй!zс'_}dцМ„L"№ ябX2ЁЏДѕ˜ ШmцеЌнC‚Ld †­szЋ>];Ь{лложў2‘Бв‚[з%}VwЬ_Џя>Кс‡ѓѓŸџbћn‚/ “{G7О’Ь…nМ™Я5žаќЁ'cІ[Nлœpжc1Ь„ё2†(“ƒ'вS a+Сj‡ŒЖ0­‚њ;}™Џ\сaŽрпЯ+ЦдРЎy…)Щj„6§JJ(5c№'QЌБСg‹с |ња.єŒВёLЎеesJЁGRЦ0д3_ц2FНє0 /‡zHЗч^{З•Mј…ŸRт!NЏ;љ(б ‡œёxЧsvb‚y•‚‚>ќВ rp­Яx‹‹Йр3Ц`ћIЛyЩМg№ЖјRфxПs1оnРЫl~лђ–ЗМЅU€йЙОˆ|Ъ)'wЯ}юsк|ЇФїѓžїмђ“Ы~С*rЩ|раЖЁ; -кф™Lг.лD!…`„2rŠHЛ:!zМE9Жл'К*9œDЉr”'xјЬй\PџE™q,єЄЎŒЧЂБ Ю<1TѓKVї1>4у\ъh—а˜m>ЃBЋ6xГk ‹Д‡ЙƒKЉ]КСЪкб™68e Ќ”6sФдУ?чО э IDAT/v§DПz№‘]{ГвтісИ У#XђwhћњзПОйЇЮч?џyнщџп+›}мyч] ~\oŸ^еоe˜[т>Єх‘GYјь.НфЧЭў=і–BГ:^$v–[ §јР+ћ№ xšџM;ј‘IЅБƒT"˜р”рdŒї…ю…r(ƒSƒЧ0!ЈУaœК!Œ'ŠзžL §zџК!јnt3^™сYQЬЭщЖNЗ+№qђ8+tŒйX4Ћ3и№EтцŠёgеЪіOЉпXѓE–ЦЉ+ЭпЧ…>зк“у$Й6n2 ќ>ћ,iЮ|ьБЧ5њбŒЎ8И2 Цu9c№„&%šРИ“vЅv‹ђЭ|ф8|Рk.ВХ{dc,'ЪvmЦ%qlv‡нœ>oчб›Рќ^XЋ?ƒзъhњѓ?swТ“oѓŸwю7šѓг:d;гЙѕbz:ј zпa›zE§ж67šњA /G;Л4Dїh$‡КнžбCœЩYCЄб+ ІнpeзQЅJB„'Р s }\SЎёЊФМ CЃP‚АЄЬЁоЦ<§КыСЄнhдzЌ4„6 еО4О\GAъn0ьŒаДЃ?ŒЫє›#<22Š—Ь!ЃK{VAАЦЂY]П1к\ЃНС —Же%јъoжуЬ§ъ'Ж;uŸјФ'кцшЭŒЏц“еЕ™C?žЭ•ы№wњС*eЩ.}ш&3МУЉЭ5}рŒХГЖрф\RlŠМ9|GПЄv3œоTуPўЩ<Щ\lѕo|c ,ц§лџ§—ѕфЧзoLЎщОјЅЏvwм~GЃ-р•ВtUН.8#ИњЊы/nc№”ћ ПцГДž$yuоТYѓЎг(Ї(Оu"=џdф”УРЧХ(Ц(ШЛьЭ№)Ш Мвї(NФyŒ‡“ !С%Й–иO” NІ„фўЕњ`J?МŸшœ@ пyЅР‰.F€.0њcИ`RO€@8IŸ[ N‹ЯьvG; p§- z8ŽљєЩq:єŸ~ђ kА}y йяЭўDщр2P;2лћаD—‘Йкщ'ѓ(]›Ќ~Дi—”к‚GZШ1 œЄ$ }ъСAЦd–‹F‰<д‡:`_нyчТœpЩvЁ^ЩЕХЗ АEэр!ы9ѓIJВєcЋМКћ{ПїЛЭљНiњйЯ~ОбeŽ8}П„Ni~щoЭmЮ$sDnцAЛšB ћ№ѓю™JгЖ+%а…€SQFА"`RтЬŒРЃЅЄŸ _fєУeHŒ™0 0 $‡Ї‘C83сЩi0qшЇЦiЮщ)EpdIŸ:#У\Š6л9|†^0фРсУ;оdŠЧkƒмдUЫиу к\ЃO_ц‘UxKnJ+Ÿ__&Ш’w?эЛя>н’Z9…ip$у”pЦ™ЭЫј$И]ƒг/Љ›?удг†'ђ1FЛkѕ88~ШЄŸ\ƒ“ё€…+AH?Н‘'љHоЎр7М Сщх_pyг2pJ8%;SAЭ­нH{еKdЇМффІгГЮќbгhЏ4&ДЭлrф€д<ки@’6ѓyьLoБW2іmFЙьq™Ч‰3•І8C­–!žР9?=Mx~–Ja`Ђ$ЪЄ\ЛЮТ9(„‘r6A@Л]‚Рx8"Ќ(hPр(kМa*ѕ&є3ЂlЭ9.ЅЛжЧ l9ВЈЬ­œŸ"бm‡Ри№ƒ^§qŽ’ŒШŠ,№Ђ]pРŸ:œкѕЋУ!уMц–Сœцs шё tKx†CкЛ~PДG§л-чU(§р5Юч0 ЫЦ іxEЃŒЅљРKъ’vВ0Џё hд]С‹ЇŒkƒы?4€K У1hEžѕ+‘НD_ц†л[™Чю’Ь9}ЖјЁMњрbЏt‘@wцБ —N§эS?ИјвZnlr‡#§К1pHd7к№ŒЮЄwМуЭОњВxС ^а~ƒVvSЋџУ4ЭrкР–БЛOdѕI)R@ѓхŽnuї\Ÿ1sŠ|ШЪj[I№žЏъ#(†E№H‚Ѕž1R_H­ЁўoМЌМœўŒII) œ˜Нцу„ŒCцLњб N2/`8ЖgŒб-„€be3\pњр4sрœ6™ВЩ ђ‘FZСуЭъэз—ЅћjЇЖхд6Мш‚_ПБx—9ЋvЅvє‡эъЦшG>Е™‹УвйыЧ:ѕС˜8(9Г1§=‘‘уЬIјі -6nйтСщ§АŒ<ЩЯ‹Zйк“5šб†Nc%АфЉMIПКvщIЧзЪKыДЎ8{JМіы Иї|d#й™%с•|бэ’E”ЭЧюK_Н‚` хД€ХVlћ§жŸуЛv;РxпWTіsVэСŠ•0'g(ъp1ЉA™ƒ‰а WfЉ–Qd<сЃеVиXЦe{ЈnѕАEG7zdŽВЄЖЮљ†›Йњ8?cС1xу•xƒ›Шv кdВ Fˆ|2txШŽqhуфцB8+ƒљ”рШ>Юž№„'4›л-ђ0z8Вy(uј2%>”`б@ц”Д%Љ›ž'№ЦFdŽ&mц•ШЬЕ1pї“>pњщEнмфХ™йо3Z}›’у vdlWIюфЩљxr нh4?Ч5Ю5рIB;y'Ѕя†ыostєЪƒЮЏm0-­лeїјцŒBЂIй”y№>њ&гДЅ–Рцœ—#|ЧьДгNkŸЄўњзПоРА(ГЖQŒœ)“RвG1А9Ё` 0–DVзAA6хЩЦЅnќ`УdцЯшВвp>†ˆVN.`1BДрO]ЛqаЮЌvcёI™`­жъц”ѕ“…vјє €ъ1,Ц"˜€бGюŒY dмœOџЈ>к<О шOvЁС­™–Lцр n%zŒuMўъJ†ІnўаIІц6†œш ПЁ јІ7rC‹9т\pСiœ>px…Kп`2Ќ~л{Œэ #й щ—Ђv‘‰[rqЫ†c•ьЧ|№т#іAпш2žѕMрщУwрR‚I=хр8ја!(ЩЁ]~,(флOh‹Ќ№§оїОЗ{Х+^б™r}к€АЫцrBf”œУ­С+_љЪЖŠŠФ 0N•едŸ#(ЛЅшM‚#ФЌ1’vFХŠPюМы–1ЦKGMIQjП„Ї­>˜(ŸЁ36 0ž8Їye4ЂgщhDжmŒJFŸ6Jvћ#(рз8Ис@;CгƒЃ`ѓщ—„&зn?Р3lИЩЧ<ЦСЫ9 н yКэТƒŸЋЌ<7sЯyУ‡Йр% ‹мтќJзц“ёЉ ЯV-cœШ+єы‹7uxŒC‡Йd<&\діоу/:3Nv6”Г ŸбрЌ˜фЇ cчУёћ<ъ“Csш77z#'xє рIГ™2!СЩиQЙŽ[ф њё!‹%Йšл'маЭOм$;Ёч‡бР)–г,ЂJЮ#пG'FEјƒНO<Б1ЬEpJх ЯЮA'rыР№д•pbо5…ƒwm чКЁїDkЮœЭЛНімНЛтЪ_?Ьй СЩЦЫƒ‰"Ь‡F)œЩЁ>Тр№ЄпъТP$NюрOК(‘ 8+МŒ‰‘€Чдg>§d†&фЖŽdЮ&Ždg‡1~˜b%t№ŠnќТc>уЭ‡ЏЌ~VИЕС9'0Ё1ЂЋopка)А„vuИ"S†|С'Eюxаo^tлѕр…>Е'qЦн#zёЂь=іиvŽA†>8›$P=а‹љЃВзG6"sгња%xр‹\5Вт ј›д—ƒ6KH?D–ф9Xўєчї^ЂУ;Y9y мб$ќЃIRЏё+N 4rкБ%Р9ŒŠ*†ƒ„ uIнуxžJHйЖ1xу)*+„ё„FQ”сОOЩР0ž Gю% FzіГžб`ЬwM}ЬЇСюКл‹5ї6G@иAekЎ8›рЃуˆ2ЃсјшЄ4<2.%|2d|шD#ЅТnђ0–aЛv;ЇБ <бЧИŒќ$0da,8‘hВгВ5я3Tраe.)xа УЁOсЩЁ1ќpjth'/c’сDƒ>‰уИONЃFкк4ZэL№ ж‘Ÿ>uђтœIьуыaД?7.Ш‘)БPєй…_рƒ.ШТbcЮN0јЯ•раˆoЅ6OЋJс\œ>eП ŽЭk’Ьх)™{~њ3YвЛ“ш&)Спd’`ўщ–гЖZЕ:oF9ŒDtЦ &šP%‚—("Qз“+€ћ~пQcј6TZ‡"LœёШ№УБ`сž чгOzfїуњЦЕ%`„№Щ‡Жb+еWёксІ@J2CЂѓ3T №РЈ8Хd{Юx|ииЊЊЃеx№ Џ~Щ5ƒт№кёЮ<žнЫhR’5Ї'0 †СЧH№€vA”мёƒ?ИрЅз`Рk єЇп№РбO1@4€ƒ_єD~№щУ њЭ ?{€г5œб5gрД’БЛ8ц˜cšѓ›C>…F>§<Мq&8аВДnгаОтјd–нIрщxwm>< U)rЯщЭ›МŽк:˜ŸсE.ще­љ Iф…/Ж™О™(ЇDВ:ќлœа ™`‚“P:& е5ЁkУXLqx}Œ‡гznЋ?  ;EA`С(њžТ3ђwоŽђ“›<‡гй[oНЅЛПœыЮ;F^хe№œpМДљцsк–QА2oˆу%ѓSИ@Ѕ?Лєђ“ŸlїœЩ!№ЬxєЕ bŒŒ>†˜РG4&+Ъ“žєЄf ˆ--cdpќёЧЗl<;r˜ ŽаЦбXєѕ“ЅљШџцфФœL;šсЫ­šлєВ9Д™п5ћ2^вF‡ЦŸF›Йтш§zк”§фжA "3В"4 LxФн&Ё˜,Pщ›‰rкрјР–‡xJfl%<Тe, EПŒa Q.aP:G# Ѕm У.#FЮ(V?хмtc=њкТvб{щ[Д3чУІ-ЗZPѓэкh†Яœ -ј@ў(-QžZ9hюяёM‰к!Ч†,8рЅnpЂ§’К-"“зОіЕ'_Zі“Sч(žЌш3?й’™Ђ…БЂ#4ЮH6`ѕЋKцfŒш—єУƒЖ)Z%F‡F Ю$n<р‹>cШ№с‰ $sƒгяQ0ž8Аvй|У8О-ОqИР+Щь єЇЪЎ2tЁI†<Р.)™К†ƒ.ш}јpvBv№›'; ЗWtЏ/)}ЙV’aпщћѕаš€’q%Ž1Н‘Кщ—œ”ш…'‰œШ_`Њ^f.M;”№v!У GХ<%$0(NKњ(†AsB (?Ћ<”/cЃ4B 8B!С:Eх$кЌїмSїцѓнzxQeф4џхД_`1є~"ш›oОЅл{ЩўэрўЬЧБеc#|C‚cˆБƒЏдСP"о88Yф` d/žсЖ VgЄŒ‚Уpuxd2Р'К™Ц(аjо8$Z№# %`И6ЦЕ~c$c№?'@›~cЩX[˜4аšŒ•єЁ §xЖ‚;— #sШцѓМл#JїїкШФ˜рЏq%ГјаЫAар–ЋŸЬ^2ЬТBОxЭjŠ/sKt"РУ‰Nу"ќ„Oќ%wоyЉŽ•№УЛЊ< 6}ј“б’ E~№%‘)šи€vђ˜ЩДВWLsЖ'!b”с()Б„JјŒбщЧЄvЬPž:X Ж220з˜зGQ`еГ€#p0Юš€жмFЈWпr}ƒ/Š5†3p0ŠЖ1=цдŽЇ–kЮР@3Ÿ ћr* …s1HЮc[ 'Gˆгс…HŒ нц$SТ 'У /эdG>d#СCЎœE:№ н\Ц0zуšдe4ЅO)›Чxумz‘С 1іqУc\єDЮЖјVzђu7йэЬ 'œаўB1‘%zrяSкїк$ЯШ_ѕЊWщВ%ї~ŠОёЏ/њРƒЙ" Ма?ўШЬШNр5/Xђ4œ~И%cМpfrбІмqЧ•ПAрёЙАu4АcАhmI`ш ]x+›Xяv#_6(Š9""g`LŒ(‚  CSr,O8†ссx‡Š3pFЄO2ц6A ˆcšлЪЃ7Z§хUЮaмй†q\§шБBЁЭNЋ• „УЊЧРрЏOЛ дnFЌ$<Ђ_Ÿm1P}x}JѓР›•Z]"t“9> sЃ2Ю5yРE&кр Ѓ3ЇЬ№ёzл$ѕ8В2­ц“8Б\ƒ­Щngќub?§&_ДКPџв—Од}њгŸ~иŠўШйЭ)W^yEїgіgн_ќХ_ДЙбe}ї‡M;šинсЯcYvI>evH>СЃЭœ.ВЕ0РЁпG@њЩxђ”ЩІ__МxQїшGVІїhCЖп~бШаRНd—iŒ…Э‚@ішBw?ЁmvRЕk^ЙГ8…њДwХј6§шш~#˜`C8Œ2CIк#xЦ”р@81иD?Ац­ ‹ˆ˜щŒƒЊ›“с2tNEhъкER8сsNNш“Sƒ‘9 „ftQ кбdувц|іW,< CИTG—`b%‡Яј6Др‘є™Ќ[#JGŸЙ№Т0бD†ŒF/С‡vќƒ5<Йщ3Z"KuйМ`ŒЅm`9LЦЗIъ?29œѓЌіо^‹УЃХoђЈЮзpщЧ‹.tЗswПћнэncŸіє+P<ЕЦ5XєwоmЗ{h$<іšPб' TєХЬ›qє` ;ƒс0В>ЈНЊNїn9|h0Eцш’ЅнvнЙ^ф9ИЪ‘_]’эОuА}дуŽj§~>Ь&ёLxasє€Vxѓ$rє›0рЫцжЛРv„pСР1рšЁЈcУdœ†yЪP2‚Я ЈЭ;8ŒЁ$Fщ$^0 l0pq6s‚Ёэy чZПъ^\Ђ„lЙc<”…ќ(Эх HАШЊbŽ8 <ъ I)81vу8.ќ <№3Џ„&Ћ 8cёi+Lf‚Ј3 ђЄtrбnю87|ЦщбУЋ n№щ‹ќЗvs’/ќфПљѕ“Ÿv8ШСu’~њђтMž†/ ˆOЎ'1єаџЂНЈ гЗДЩЁWњлП§люмsЯmuД>џљПйОЅч›zIззSOwшхIO:ЎцњisT|LdмOdТFЬ!ЈВ1zгцšю9К ЇКі№†/™НpzяV)КНщ*Рѕ}цSЏUжпІм­­єЛяОk“П~јvпsЏњуГOhm`јУŸtЗоr{Г]МфіŽЭ“?ЙЁMNђN=‚ї†`Тхя|ч;г=эrк;€rŽЃяй-B)•`?c'ˆ$FХиDUŽŽpn№ гxу!8%ЅZY­RŒ˜K;ЃЖѕ„PМ/Чeа№Ч ЃxєР‡~mрcdNіс6--ЙЖJу…SЂOрЃ@ЪьЬ–Ё&РЉЃIfx -xŠ3Ц!` \‘WvPd%“Л1ВКŒVlЅБ:&ш‹s„МС WвќС4^2ƒ}r9§‰ѕІЇРŠwє“M|2zы[пкJп!ѕ'ноќц7Дпж/_ў@9G9к/ЏЈ@Л‰:_АUЗя~ћvO8юиrЪК‹ОiУƒђэ'Л8A—,що|hБrг'~ёЊ.˜їežcБ_v@цeСJJvЁoхДYїєЇ=Йлq‡їјфИ`›mыяPњДиAcр?§щЯ‹Џ+КэыЯŸб1ЙЂ^?lЭ„d4$ЁЯ›ƒЮCиyщiХ a€ІQN;д|‘вvа[єd ˜Œ9Y”"sЬj‰0J‚‘с ]вDu8Е Œ^§qК–ТЭ!њУcœ УhњэJју”P@т|d>u‘:+лЪа,ы7.p№™јёGV9t#+:ТЛё ŽaтеМ‘‡зq§^#IPDЧQGеѓœŸРo^/$‘šЭŸ„ђг›о4іЖŸ/фОюўFУЅ—ќЈют‚ЙНб NДЬ{EЗxЧ‘Џїlѕˆ‘З)бŽО~ЂOВ1П[/‹ЛŠ­ zh#Г9НРeœ`A7‚… žG‚§љд Ms~јц—Ў—,йЇў ѕЃOњЩѕч?ћeсНЊ‚Яˆ^cѓш't€ГЭ7>№.y†œ•dСОиQйш с6Шщ§7эPL,` Уzf(у„KX`1Џ_тh UЄуърєц‘ујкF…бц`РЦ1hѓ€х ъpjœ№•ц`ЈЦЙ6ЦЕ1шV‚єs|F8ŽЮЙ­Hк8 šЩ.јC3кSWЪ™“ѓK`ШЪ5|xФ+zаbŒk25'кСЙж'€r ђ5ЏkЌрМД‚Дv2EјшƒьЩШЕ[ЮЌ„+эю‰­єO|тŸцчXЁ^4’К$Ѕі~№ƒcЮђЩ/ьўшеЏ*њюЎяGœ[Ћўв6:ЭЗRЎЖk~}UsT‡j—_і‹Б@е&§ЯNLцЄќj‡_xwлШ6mѓ:ЭFœЯј№ЫЩ…yј$уSj'гOўшЬв_]QЗ W4d7;эДsг ]нкА]m2ћqжaЕЯnБ9іRђ^ёlВ?ёыг%Ь[У=!Ає—P F(&†ЦИ ˜#Q”vJТ vЦ" 0N™Eнѓ€б'@xЕYi—+e€тc$цB“љkV†+šтЦ3FЎ=ЦЂQ€бЧi]ƒэѓхN%šUš>uJ&3ДЙŽl№ФѕуЅБ Г­і ™,бfЕ„ Ё-ъdЇžф№яЌГЮj—GѕиюUxzЃљГŸ=Ћў ыŠпг‡/x“k‚ю–’ЏDПкщьћ‰уrP;ЋwtŠуFя[8ђŒcЁW`Іcђ$K|’Ћ]­k|љuыWОђ•65љp~;—[ы/KџьgОЗ827{рШє 7=jCП`ƒV}x–ЬсЧ\v$фЏпm#ZбYЫl}&гД@ пЦ DU/Kp †@-–э–BЦtŒŒ€ |‚ЅTпР СX†l‡Сp Œ žbќк(Œтlѕ›'Ž O№ƒA68dЪ!hѓ2zЦ't^ЮЂЮР2†вЃqј ЭњћС}ка%3 лUДku†БsPFЭ8’ёњqpЙŽсrŽ_ эdцЗhє„>ПЮ4ќц"?|ћ†РSŸњдVТЁпЫ9ъф„F‰\'™ѓЁGvкo.Ањц7ДОГПњѕюкkЎkэ‘СxЅЅЮымвV[Щ1щ=яyOЃЩќvYœд†џєOџд@ШЮ#<Лїѓp‘ZсСJ™K›F2o=}Е“ћЛММѓ`Э7ђт–•Nxш^Ђ/№Kk oМJnгœи!Ур`'i^‰=yтОй;œЩ4эPЦT66ђ[jL"dТtŸ,‚R(ˆ‚ • 0O1^ЮС0ЇeLШ@ @;ч—(ŸRф(„а%Т‰Rx„РЬqh’Р8œa'"T†/ЁЊgœыšБVAИk.§Ёп`№GGМјf,RјаЏн80Ў)м5Ѕ›пъ ˆ œ Ÿ1КЭ2VнМI Э§Є–-Џ{№8idўЩѕјЮН'CF“н>И`‡OpЦЈGfЪОс–Д“ЇkВ–ŒMђgБ$їЪјRЖЙLh$#œо#2ѓ‘{ТsVсўxŽ/ |ЩцЇїdИёBп`ёУQ-‚ЄvК„ƒm“E НvІшHbЯє@є*Ј8tЭл„Ч\‚†1КЦ С<ъ3VXЮ1—`ЖJЄФ0С”Ч­ЅїРВЌ00ЦhтЂ v‚ФМ{)ТЕmRЦШРSœyеcи”@ЈЎ9  Ѕ4%кД4…d;ЩЬЇ#š,њЗшдЧёСУˆрOQЈі№dx\ЃOЉ-М(9ЙUC |оЊэ Хр'sИ–Ь6†!Xф†ё00+>9˜ср ~%:K9у ЃРІ—d~8$Иё… -`]+СVфa>4Œ—Щ'эъ#3Н"q&Џs,vb‡фў=шC™$i3'НБ#uЮЧv$%:C?x9}tЯ~рХ—Б’9ŒћБ}Ќ‡ЧЕРJоO` vЁ‚9НDш…ƒБ-rc—‚ йгЉ”л]АЦжИѕы  œ~Т#Ю†X†ъ\Рsф<#'LЪ(м_bŽЁл9ДВEЁ СQ g&\уЧ\pЙŽЌЦPe›пъLŒŠƒщЗуРц!є(л5EЃ=B76[9G9№s88УH2=фNјЭvxeњ8|‚ŠУАpщћъWПкx`$hгЪ™р›ЙUёОДn<‰I3'\$Мj—У#КЬ›ЈŸЙ“36ex ^с4ƒFУDiаЩIюї5šG#йH/}щKлVš#кйXэAD>RјTGНp>ŽЉD™JЦou~YТйРcЌqб]фk›ѓ9/№єCV{Ж™вUl’Œс•єƒgбwdk^єС‹/уf2­яSФZҘЯIc_ё%LŽˆp bЬ’Кoт”ЖpIˆakט1M„’U" Ьi8ЋN‘Ў%уРР /‡sђ-2 NœQ'q)ˆВ Ь#S$мъxB+КСHxR'ѓ0 sЋSкƒБ .uCСЖ™1X4рпъf^o1К="gsЃ§ЖХцBЗD6ЎсХ[‚U  љшƒ,к ’ЬрcLsФV|RПOЛkњJ2~0щ—lЎёъкЪ§кpsK КТ›е\iо8/\”.$В”ёJ`-RxƒŠ\ZЦ5ЧуDv”Џyуœp;Ÿ@›­Й] 'e№›‡ВрC™h€‡!ЂэЁњДШšД[Ё6ќ›Њ;TE#<ші‹;t›M‚^$–J?œц@ќ гќј+ЉƒCЙЦS2њC38В–є JМЉKhš(ЁўdИRWіЏqDGшФ+нJЦрЫќкѕЃ Э’:л3^Š>Е“,јб%йJ`щ;Xђ ОџŸК;вѓ8яФоРЬ``0Ит/QЄ.JдЕ"%KЖ$[Жф]ЏэЕзх*Л*•Jе:)'eЧI%Y—Svœ­J\*eН[N\ыK+YЖЎшВVЂ-JEё ppюc083фљ}У?јiJЁl6=егял§єгЯн§і{|Цх№V…tD&–рз_›чаCюxcJxШјŽ3НЃ]в‡Нƒ'}ЫV~”щХpў БСНŒMДй‡aзљ Х2с“G*“ f<pн‹aŠАq“SO$†‡)пБq -ь<0fv§ ^Цj, н %ИўшFПчЬЂрбEЩp [ ƒ+}аЋŸ:tR šСУЉоŒAЩіIŒk|wŒPАaъ8‘KŸЛ&;4h‡NєрбиЦсш Œ­r’vуЋгЧt$Хшш‰LЌ†рžЉRJН’ШбЕѓ—Jф,ЃAю>N]ЪЙ8ш­ј6†srPfLэdњёHцd‹wre јЄ4уA„uњY]/ой‘[~œп˜&8њб_VзœУ‹F%љ:†h€гЅžШ^и­6Да™64бЁеы2}7ХЏs}o„ЮШc˜ˆ&`Г+†SЂ%80у\”@iœœcЮж­№МPЂBR—Ї x9XЂ,ЧБa„J5“Ѓ—*ВСsp}рGјqjNh––Ьа”›[i”m\AQbtорТзcбJNV(ЦuЭ.є’1+Yл‰zuЦ‡§Цˆ‘‘'ђ`8C“Щ-Чi#s<ТIшч.ВбGrчwn|mh3ІXє1т—Jє‚8“чžЇ~.4у™ќ”њ9І3єы‡ŽžСа#њЩŠLё&ыУЉєЁ|а м’>фсr‘у[щ‹~р4ќрb›siŽŽр6X6›5.л‡—|ьˆЭ№<ƒe_кыВѓ?­K€RhЦщ ВбZІrl‚уќ„Ž№(™ё0<Г f-ГDh‚Ыœt <СЉы68 „OЋ/ZРPу №Л§Qлf#\Q†€fxєхЈЮСmNЂ‹УУЩpFFF:3Мё4хС%‹шр)‘0F8аХ1ŒсЩ5‰тбNŽУ0,7ё/˜™ЩШЦ’q$Чњ97&“se2К%:‘%|OŸ8„cДHњЊ—Œ“ОъёbМР:G™‘“dГ•-ЬMз №_+П@іUј Cу У9НЃ}шWвЗідGY“Пе™R‚ƒўдЁьdКсє2ћЃ ЗВ{6BvрcodeМюw№‹ЬщQN< Ч^Шˆ§ AЪŠРх_нЪ|ё1ШNыѕ§Лю@ gŠs1ZЩ9f1B!DŠ!J$tBЄТЧx•а$э„нm˜„%3@pЦ€“0+%’SхƒеЦБ#С֘.Cє…Нъс6…[ЂСЬЯ1бЧ lўщя\тєсO(аŒЮшрбсЂшЬо !| ‚xц@ш +†Ёњс†'ЋЊYјР3}kOr.EЎŒЯXhOuh­№€'№ŽСHшSO†ъ\ ЫeЈіЙџшЁЯqw†+чsћ—Œ…fre[фЏzђЄxРУEVрyМА ђTF‡њЪf_—}#фбhТ0‘Ѓгр7žvr2ЛAгмЄ,z“‘ ЩўйqщhŒШ^“Gž ЯДЯч№ѓ`RЪЙуОœsу]WјШG>ВЈjC6››ЙШK(˜ LЫ%эЮ бЬЯh…Pс%0`!†‡PѕJJ'lЧcЦŒ#q(uсЧЉWgєH„>phf r”ЋЏБ8$кГRa$\ъєE>ŒAйj\Ѕ Ц8ЦVобЯ@д”Ч €Б0040ЂШm8ј$В';†S{ъѕGЇЗПйщ‹.уЅŸq$|Ћ““рpŽћ Ўд œYэЄvДМTFГ6eq’nR0ЗZC#YЫ1œxЩо[DxЇCі%xФ ш$3zЯlЯ9›ГРm,ŽљƒU'€tЏD"уn‚е?єЊN‚ §№Ђ|й,МЃЕrВв№иvlžtЌ';/јУюцКŽЏ+”`WˆЌ"&Ц‰IBvn†х, Ц‹AЬЊг<ХЩ@ш2ИŽгS2a#Ю•1ЕСIЁ1z0` —Е60№PЂ~”Р!Д9'xє‹Ьш ,cЖВ1УУgМРтЭњРЫР84X†чвјxц№`$Д V”ЯШѕб_BŸ>ЦV—„O4‘”ВzЅ6IIЎф†grЭЊэd…>эЦ ^eњЇ œоцZV&њас;ыЕa_ўuўчўчОљGЦsЉ эЪЙ э*§XЩ9б /ў№Є=<УCю‘Žи[lЯ,r‹UтјxВb`№г…sђЮЄЗs%]Hф††$mЦ!ЇР ŸpЧіЩ~6 ш›<йOlŸпИduwэ…Щbv—ЎГМЎPL.ЧH˜BЌш‹QТvлLТ0т ‚Б`–гP Eъ/ЅЄD‚qN2Уƒ_Љ>эJэJЪfЌ28 <ЪPЂG} >BС`№D)f6`ƒ~NЇaxш‡K?њ*>eэ2ZЬ.]fr‚ЯyрcА№.F ‰ЁУГŒчxУ“уюЌ.АщœЦV/3ПррX‚SжOr‡ЧУ]ЪŒ‡.FъiOЗpеЛАЛ=7Ed• ЗуаМ|йpЛћMoш№NvIј`нф€NrЂ‹2Ež=UIЖŽ%§мuё •@Ж.ѕр mъаУFсdЦ5>Yi3ІѓђsоРщG>dЊ4~’>Цецšq#c“Ѕ…Ћr/zўг %„ 4Ь!^єхќ€YЧчќЌ^]G_u˜$0Щ9x…г1СЁƒе.uрСЊ3VрkЇ< ŸRС Ÿг3ДыӘЬ–x2XuJДЃе5КеMŒРђRr Џ?у€cDњ#†ІŸРa<э ЂрC.%:Рр‘С‡Є.IБрTЪъRя\вN№;6&2!tKрС0ђачE/KRєуCЖЪЙчž{:/ nx4XѕШpЮMє€у*sь|ѕ*ьxёKКƒ%ћwм{OšєE>єLfKэœ]ЃЕŠ/Л,СЋЖ|X4?єFЧфŽzŸq$|O_ђвцЌRњКиЄаLІрСZ§Б!К6ЖфЃйо ЌMЂ :ь”=UЪncЎ‘RjћЁвu­ŠщAgТŽЁŠЎŒ–€bЌ”&(‹а#HЪг'3Е~ъ’B Ъ0FwŠВРЫСe|уъoL‘VЩpŸв–съЁX̘б‚ч;чдŽgЩJЌЫД‘ њ•№JQ4Zdcv;5XY@ шIъс‹†G0СЯˆфШSНcМШњ;<G.‚x2УXМr’бrЈШЯюі˜э]њп K> ЄtvяњЧB'šz{{ъnЫЦvЫЭллк5ГŸћІу‘r€ЛоxW?ўн wddЄ3#вЁK$cЃK№1SтУјxpнЬёнMЁw—$ъ]І˜љЩBBWJ§УYс•шЏБ№xpŸЖшЄгЁўб-ГiЩ9ЇЖдOа‚CђжІU‰•g.Ѓ%Сt`QЛё–/пѓW'žЮГ*nУѓУІы %№зrxТр$˜Ѕкё™ €уЄOЦIvИЅШKњ8 YЃ?r&#єpzЮя˜ќф‘rК{jЖїнфC~`439Тщxnв6P|ЌЋЯgЏПa]­˜nш№nбт%ѕKM›лэЏОНC7O<БЃэнпйˆCЗёш…Œiu‰F&Б+КуP.Kа*@xж‚,Уйєcф™G7[5–zЧъ№ ’дЃEz’Шо9x0фХ†шNйD"иKFЇKјd“‰ўђХKкчДM;Н`щНџюuwЎ{њ‘пћяЋ+bцЙч†њЎt]  |ћƒ>иYЎ˜-i1Цp(‰ˆо №‰АšR;Сш‡INЁП6№СEъb1tЪ"hІXY‚пXЮ+ ž3Ё…bs‡qр ЯЁeї^Э ”i|їр Np–С9ZГ$:B3"М ЧјЎ—Ѕ8ВёЅа/`Щ+—Q 9ћ ъб‰FKxŒ\•Щx‰ѓ+б%СvN“х2œк-•-‡бŽ7йи~Јд \юшp2FLgЦ0žф-'uЦž›~іƒ?Uryёvй@ЩheЩьЮZіЯ>B<3sЅ^іљN{zЧГ`ENвH!Б&єй€ŒM Хfžыf;њxЕ" 7ЗЇщ"і’ЁLО2В€ЈюШЮШoьУ8x%7чрœГOЖеД Дfqє“„Ы|2§У?ќУN6— 6єЗњ“ŽЗўH;Н ~ъ|щPOп‰žїŽ?ѓоэџеТўbъ?Лpdкrr€аSжсї_\W(†WRƒр ОG€ˆ&XСc#РD?‘œp…АsЌaЪњS<|„…0ќ8юєбЎ”є5ЎLЉ *Œу%шp2Цvc˜••ЁЩ2 ,‡Ѕ)˜rрфаŒХВ_Ц‹ЬўŒтб#1Ђ(W]‚œўŒ‰уeFж†ѕ2КШєщ#УC.н‹>}ДKб#Фyа‹GПШ.фnЮ#цld‰ Мь<Чt“sуЪsчя/Нз/хмrыЭ=“РLLœ+'ЈЗŸ~Жјœ}ЂOЂoєтОКg{ђ6гЛ,CцјД VP O:і„Fпh$/r‹Ь]VшЫ&Дб›1ѕ'‘Нkз/:/їнw_‡ŽрgV&tђA7 ђЧ.с†ѓєЙSэџ:ђ{эђ@Н„ЖdИ]ЊЉžЋФНpтRЛљЎџЩЦџБm<МуфПššЊ%BџхЛЊлйБO_њзgїL!tж)ОOИЎPdЉDZќЇњЇM LTŒ>FKА˜d0”" €Х<сД’#СТЁ=ЦЄЭ9ХрЉ18=8Y? —СSЈcŠy-ЗраC!Ђ=ЁЃ’а— цZ’AРŸЭЦхiAМs}а„6—’ћьшУ›Ь`с1Yс›тKѕ9'tЃZгЎo Цq.ђC‹YS&OИ№ŒnŸ§6Ž>Вe(ЇЧ—qЌM<С-‡?МЁ#ЦяX†GŒv2&ѓЄїўфћ;rЪЙj>§єЮЖoяўrШSЃoэкuWэ€\Fk……/јбL‡>уќ’йѓЋ_§jG†`\KлМdYIrјf7Žе9–Œ‡і@^d‰2С9=ј№ž;ъŸ]›эM$Ц`w^eІ/8“ДБcЂЧ˜`žМјЭ6Џ>ДlI§тдžУmУ–­энџХЯЗ‡>їwэЬщzъВwўнC7 |ќђtљР…šєJW?8јіџъЬ/О€ћћы 5{Œ}шCъ|ќ3?cAAёfТ""А‰vЦAк0Gа'u“cNЭбJНsxoЦ#@Г<ƒ#SGˆAsNX%мJє„&8нŸЕ3ЋЭkЙŒA@0Ж РИа€>Г,хК,rlі1лИц эx‚ §ŒLŽЬє3&ШL ^№P.†‡vrTJpInс­X—(>Ъ@б.иЗlŒсAX‰ Œ)iг‡ќрŒS„>އ6№њ9їQN'I$ЭђчЯ_hп~ш‘вљьЦ,ў8,чзl‰lƒ_ž/xѓ›пмxёШљ­Цт@фl?CК­ ’„>up’Бs™ў\"i“Щ!Ћ3|у­њHhрш_{’Н"З№FjЙO&Ц6) dЩ.“Шг9;ф7ŽЇІЇкюOЖ5k7дхXн‚О2иЖМъі64<вжoЛЅнМЂ&†3'кŽo>кN?з–ЎYжд&сc?Нё—{џл§6§?П€_јоыБЊМЎPмЫи]#r O}™)Yњнп§нNєЭ*„Mx †` CŠSсF€ `ТRЪCw.Ѕ<Х(СXЊSŽvЮоmŠ€‡qE‡~œHЖŒФєБ2`№сK›хp6=8ƒ:{"fїš_Œ…BŸq’Б”‚eKоœЧpё` ’‘‘ЃОh–ЩR=xNc tъCžщoчžQЂŸЌпїОїuVѕWе‘#щSЉŸDf'\’~‚ОŒЈзOzРЫ кн‚o|уСvќиёzEі <>Бнз' ­ОЊђ!wW‚МкёGбxQрз5Йzt;Цр> ƒEk.“Œ'‰1‘‹фz§`чh9…]fЮТШ­H <мd?КB›яdl\)uŽбЉМє—28NП‰wљђь§rу˜0рJpByщЋЫ{ŽЯqщ‘L8Й‘ЧФ:І#Oђб›UИlкgЎlр4І@^№aз‡ЮШф‰W0к’Œэ§t’]xM с‹|с“шUЛz^є8ї|{nцБv`ІюТ ЗсyУ­o~=а6Y—укйоКўŸЈяœ:ићъзлЊk[пТСіќу{л•ЩЫэ†лъхБ хЎ‰ѕђ‰жPEЎnњjТЯu€RњЁb†)eЄ–<Пљ›ПйРПјХЋ‘ŽS VnЩp FР™8[ ŠсШ €0cФњKъРJъ7Ša Ž1šQ$б›‚-Зд#Н”nŒ,ћƒЇhМp*ЮaGрЅПцЮѕ3œ.#ŒЋŸйл’šaйрaYв1ИДtаюмxŽe8УЦ'"[ЧфЫH žа(аРЧƒVЅ1›N`­LŒ#7ОаЅЏЄфђŽ|”=c0f}уќшGљЃudЋЏр'ks‡…˜%ёЃЮXјЖi?‚L97YZЕ ИфЩцє#Д87™Ђl‹-€г—а{B7ЛKР#3э&4cкHD\ЦСCrGXѕЎLfl^ћЄРGIцєЅЌЭЙёаЁюьЙёvюЪxћжд—кўщm`БЗ\}ЯА&ЉгѕkЯe›.6W йПїPлЛkДн§Ё{ъgЩъхШёжЗ 6%ЏдўKс]8ДЈмuАp_^WdђqЮѓЃ_Я†)IЖiF‰Оћ7ц0 N§hЭHЄПыkС€Pр–‡ьXЧу46ъ(RНФЁ)†БqХ›‘sJFgU@!(кkcј< ЇП ЦˆE|8­nаe\М0(з§к&'аcРŸY>uш‰ќ8cf$ѕ№9‡‡sZ}ШxŠQ1І№ЋN?_cЖквOPЋВв'ј'‘…еŽ’Ѓq&ДлЙ™RДKњЪъаŠ.}ёAЮЩ†9WŽў~џїџj У‘д[ЉШdHўъа—qбтYAСц3XzF‡Rь;И oАœ“<№mМРЁ|аэdjEAЧ№ъ'icЋшЭJв*—^аЇ|кСыЋЮyш‡NmdsњьЉ6vv=ЕЋ-лДЊЭя)й™уу6'л›я}{;№\}utOЛу-ojћvеЗ%д/ѕЉŽЃ0Ntу ^у’l=>ЌіюD— UбKvd‰.nЬ3|№Ђ5mŽе+9ЎY•ќи№Jf6$э!‘_цј`ш§ЩXA™3ц2=љмМIэјФПОœзRоЅ„ОdфW‘а/СУ 9?Й[-+ќи+/Щх РNўl?hРgфЈtOф‡LфЦЎД;+O_ЊНБѓЕ4UЛ§‡ŸoУeџЗПўžЮѕџщuЉyО‚Ы‚zJімtmњ=йžпёTлћT}€tљPсžiыЖoj ж{#u‹№ШѓЧкаЪЅmтЬљњОйе6ОЋМЎPЬ,"L“ ‘Dь…с>Ё”cPXŠцDЂ8Ч#˜і IDAT‰RBg`к2†ЗЬxЇ6cІ еIJ™‚брXХ 8+\hpЎ †Тю7ъюЙчžЮyЎЭše+lњP$zсr ъ2!Юc,й2ž# ~xg8шЦ7чршЦfhaјњ >фe mъе1FШ% xr‚%“…ОкeIЉ™Ѓ$97[s2c‘њаЪ`cЌфh ИЩI›ф њF&œЬэЙ8Ї~.“оYwьцЃяSrюMўьЯўЌƒ›юр3†`A&dьn€K3;нъ79˜h"#ГГcSIТ}uї% чh‡O"єIЦДП@‡dD>ш"4Ÿ ѕ%‰МСœЄ„э—/еFѕt­В*_Јkњѕ7ЕЧњћіЎŸўЩжг[FнџP[ДdАmКqk;XwQ–дЖЇ.ДН;Gл№ЊemxѕЪк'oЛОГЋ­XЛМ.js{A'Ћ2ћПЩ:#Яў{‘ЂЎЪ—{XŒb€сb^]а}ЬIŽ ,Ыsg@?ЮЮX(ГHњІ?МВq8\Ч8ъSъЧЁЋz p,89g pJ‚G œхП @9œTВŒDйм ЁБ-џрV‡4Cўќч?пYљ˜!а^А`МZЯJ€‘Œz%b| ‹сЧiь~ƒуИLЪ5ГvЦ_јg€ф‹g}8+:еуK2ŽЏ-rFƒŸcМ#u№2єn#gМp*СЦ 9 =Dк,зЭі,9К|2“jƒ;уЃAА•РБ™№@F6і_ЮM_h ХфB6њ™ЩеЃ[Ъ8;+Av›!K4ZIXYќЩŸќIЇ^мйСЃŒ.Аh7ŽcѕŽ•№…eœ2ДЊ“cŸч.k—{НvМЌнzч­ёќі@э“,Ќ€0КГі1оzgЭь kїџ\[БfEлrыђЖnѓКЖrc­@.n‡ъђрйo?нf чщУЕ2Й|ye %ЬF#ЯIз з"ТФ„СpRFЁ-BQ&c˜beТг_4ЖМЪ­Jхx6ЏД[ВјмЄ ^BџіCЖo=јvфАgNu@-ђ%тЁЖisн;нАЉнИu[9Х‚ЋŠчœЙ“СЁ%у2NcКо­§Г7ЧC;Cb\97KpДЬиJ0шхЬшЃp‰Уу™1  9сŸЃСeѓ?6Вrщ"8щc"7}бBц™‘SgМ%чрєМ>рх$ЧœТЕЏD‡њЃЅ‡ §сM;Gу˜фЂ^6ыК§Ш)Щ“^Л?ЄiЬрфa\zс є’ ' к#Еš$3ђ 'zДф''іGЮЮСW+“УгI&4nі|ЌR›”В2бMшœбC.њEЦ№ц8~ЁЮББR&АŽхѓ“чкЎ+Ео‘ р5Ляпџl{юЉ=эдЁ“5“їЖхЋk5_— 5 ЖƒѕњјёгэјX]*ю?вF^ЕЕ­‡„јлЧкббKэ–7зЏQзЊ`с’EƒCЗY>ОcЪЂЛќЂТыфК@1Б(`Œžp0›hK†уЃŠ0(а,ЃdЄŒЯ*~Щ’‘‘с4u|цЬщіљЯ}КliџфŸў\ЛЁЎћЄ5ƒQтЪ=њH'8,XапЖnЛЉнћЎя,ЁoL4q Х8Ч‡6ЮЯ)“s‰ѕxЬŒШаД3PF.эњ1zF ?žтьŒдJТ,c9oEя дlgU7й &њ‰ ЃЌnуЧiЃuфIvн0сY;~Є8м ]›~`ѕ…G] й9zKKqthSя…у[Aщ›q.'№NМ'я$cDсOпW}р 3у’ [Pкщ'/Ю‰'й*эфм}MџБ}ЌC+zЕщ+›nэБiИ“р.ђХCdЂŸvѕ`rЎМR45SwEЎдёєЌLЬ;е>љп,~ЊvЎKжW*˜:ижmиоЖmпжžЈ_#О8UЗ€ыжxЙь<бVnXгоpя›лcїЭv|яKˆж;гоєЁmm`a=Uzьl[\ћЫюш{G€ПЈa9џїЄы Хhч.У!ˆ f„cЅфX&$‰@“cѕ`­[јъ9„q‹й’т8йЇ?ѕзэ?ѓг@О+­Јvљ5ЕIі“ј@л]J§є'џЖ^2yЂŽŸmяџЉЖ›nОЕƒ^)=Œ oш1ы2 зЇъЖlйrUБ–ЋŒN `м.3аШqѕд›5ё€nјГї Џ™,~8_fYc :Ё}‚ЇРCv1F§bhъСЧсхШъё‰Чr§сAЛОЦPЇoˆz§-Бнсœъd|sњ{юЉлSеЏœЮЌŒgЮn|МIј6GJztƒЃ“й‘}фlF†сHаiхыvvЈ?ZЕMВЬчј6 щЪ3zB9v'cЂ =љ‘ф8|рІ.OЕ/ћX;зSП10SђЌЇ /наі-yВM-ЈUNнђлSGНшЛrk_;КыЩЖ§u7е“ѕћгnЛлй†WжЪh`АxЊ‚nнћŸ?P^-˜lЋoZмЦЯж‹GSѕsЩџФСњ9ЙХэCEвG+3pA?К@ i13JЬ‡Y%8APВcY›ј"ЈЃМLЉoЮЕw'зE<їм3эЦm[;Ч>ќH{nзѓe”u‹ЄžXЙrEЫЪКў[пЖпДЕfўmэПќЭџК}сsџw‚OЖOўЭЧкЯ§ќ?kјщuшq™‰бl6gL йЅ‡хј YН РаМ…7hFO&ј€­‚G гВг1>рв‡ƒчd F]Œ[=œ5уT’%<њƒOzc + =њ  к#Oэ`3n8$ч цœЯЕ}їО–ЭЃЫ7Мк;p"4Тk€уrlA?№ dй8;xјРpbcЁ_)б• џіŒхмJ‹>СUŠ|]jКs'оџ§Zа-р72‹є‡[&?И’ЕЁ)эE7чGЧщЩ“эГЇџДщ?ъО6~тLщђL[6P œn“/ДU›VЗлпZ?Гџx›œ_ЋіљЕzЋo€.Zйєз3ѕЄ_я•CmY­~†WЎkGFwЗ-wnm—Ї.ЕБ]ћыEЁ U_ПQЯнуЩКУБh`{=ссЙnрХˆШJзЕ(ƒX,ъ3ŠYŠДLУ4AjSN”GX„“!Ž T{­ЄLк''Нќ0ыh_­Э’gŸннЮŒЯZOыYПјsВ‚Фюzє[ѕ‰зевєŽія{ЧА>ћщOЗПўи_еђ{CН‡>;Ѓ3Єz9Ђ{ЪŒ /f†УВ4ё•жГ\€Йі}=Н}5Ћз%вљ эє‰В­ГЗ6ЊчїеWšњkГxКfўz`ъJйУ…КeичЖcM—ЯЗн<йVЎЋЧы‰Р§Oш<МсU›кЪ‘U%“К-њм‘љУo™ї/Ž|њЪWtц2 $Пђ@ z EQсˆќЁžс!S4ЁJœF›c‚з— /‚TОTwсТьвvllvƒютХйНmЩЦ >у=ђШcmУЦъ–кІNј7џЧGкžнЯv–’1hЦh ‰жЬОњт‡Бrvmс_рcД”tнЏМёѕ‡зьšд™Эš6сEЖ,fЬфЊ,<№Сс\I~dm\r$k8”1jВ/е™рЉ;ЙЄсјfs)эžKзЭєfn8ащ8cЧЙ€ƒFДтG >A5c[%%с[L9‘ ЂПDVјС‡Ќ>єFžХ@Г~њ{m™А№Ѕ П нИœ€ ЮШлq™бdIуШЯxЧ;?[Ђьokж§аoєЕ3‡ъЫG[л‰cSэјхzХО–јK††лwмоN+:којwДСEѕУ%‡ы–mљK_ §сz№аs‡ь8Жe=яЉ)ї_ЙˆgW•ўŠW%ЬaЦШieBˆ3ЌњS)3VЃŠN„яpйIъ’G№Г‚žв'k™/ХшР]+‡Ž'ы3SР­uŸWBgхt T`]ЇGТ#ЧЬ§dуv–й1|ы+Ѓƒђ•pр7ЦХ1СУЧ0н%ˆœ2гrx†)Рт#EtЌ”УЃ1Щ…ё кЅшХxшДр7–~ p}єЃэШA=УФЬі6ієзŠ ACЁЇлIроxnЩхКдsФВНрШ ‘|ј cХйё kƒCPсє–њњƒЃ#ВЗRё 9РЃN 3–Оh’с’#›nК№64ъодХ—ŒvњиЛєЩжЛВ.ЛJg?ф}=—k%uКžБЙь2wВн§ЎzјйчлСтыЮЗмнжuў‚СEm`h ј‰6yvВmЌНЎ%Ыj3№dщ ZЛ­vš˜ZQд]sр€RќВ(Ž`(“а1ѕ …098Хq4mŒƒ€ŒЉч„ЉN)ЪшœМpžcТЏ:ЇpIЦ†CюДƒщЪшгЖgЯhЭI Гz9*Zёцv%Z9.\`РrT†NсшЧЋqЭ~рс`xŽCИШ-ђˆ3щЏ.Юc )Г+КdphŽŒsй ^˜єСЗёс2.њДлХз&q4xаЦ{œЩkЗ~хvЄ–вpъ оJќЈX№ˆюр мЦЂI№tœ%>™ ˜I№ТЃ?јй9sj4“œђ–Zо{*аѕ==Yц[Х#xєЕ‰6јsЫ/4сЌЄн˜#tс=Вг.ƒ%cєЩŽNlЃ;к™eѕZsџщыzЃofЂЏНё=omуЧы-Рњ JчqрЫэЩы;;žnЃOеKmЫ\V^i7мДБѓŒРЉЃgкБнѕфщжеmњJ=Ќvрy?лl)c0ы\/0ѕŠ@1Кœ1(І)BЩBŒ Ё-Nel0p` дq„KиIХЈsь^*Ѓžm{1Р‘œ~нeFp+б'ы‡/ސу8wœоЌŽ*ФHёЪ%}ёСРрХЏs8$ѕh„єгNvI›њ\N™ЩW™Р?8чшаžу№ъкРŸЬЕK жЪ>уЛ%цС'ЦЦŸUіпљпщРТх.ЧRїВй1:ё!сA2Ў~Ц$;r‹§фƒ$Рњgl:в‡LЌ†w$уflЁ+)йЈЄуТA6Rјl№j@&фƒАЦu.E“ўi—%эєŠO6зЅњ4пL]›я|Д=?љTX`тњош;sВ~xvЩлZoџђіјƒз‡SыGhЗжЦдІsџ’Кф<}Бэ{vД-­[ƒУkъ‹Tѕ8№ѓюnk6ЏnKVдЗ%ъХ ‹ћч/ЙЙ­:ЛsкG ~4 nѓМйNЌм‚вˆ,S~Ќ>ТWЧ‘RСІoњtуЯq‘ѓ2›NѕњЫŽЛЯSЏœ›аУHаFЉ СБх"Ek7sЁ–yŒhчЄњX†jcTŒOП$pxТ#G@gA8эŽѕƒC›Б9 XcЁ nй1|њ;8Ѓ žŒzрwœGq]oіD;\fPŽПdlдјЙ,up€“рBƒё"kt8G‡Б rњ’Ÿ•†s8дeѕзAXџРƒsїСŒŸЈоLюЮУО№…8§|іГŸэШ >ДАI4к_1{”ЩМКШУ8ше†^§’РtŸЃUŽу;ЦГ ятсСЖямžЖЇОiИtУЪЩ}УЋЗ‡юћћ68МИжнЌ;пrg=їПЈЦЈЧбkуpшЖeW^2ИИx~Oл§P­t.ЯkGіjЯеhѕ(ёТ S›ЯжЏЗo€м‰dЏxPBОQФЕTЄFЫ` ƒЁFрapœ ЌcJ•#\BзGrœ”cmн0iWТЇвфюуœЋ“чІрд–cєR6њ$Ч’z†&у›1K1"ч№€#‹д'808A@_0VIъd}аl ЧЦvŽ6§чМ VЛЄC(‘sМpўЯ|ц3™ž0ht8ОsNЉL шŽ.ЕщWuЦгЧБёаЄMc}фŸ™F†ъ<~{п}їud‡^|mЉU‰лŽV)dšl0cZ-8ц”йƒБџ`ЅЁohŒlбhmВуШ1%КЌˆШ|йћЙКб§uKnm*^\^oєеK:5цѕОбwј@Н§Ич@НА ^ђІиZШз~лтzuќh}т№‰КеwЄmЙ}{;КћpћњЧi‡w_jЗПЃ>ˆГЉ@[9дЮзКЁљы^ љEЇЊŠNxјс‡УЯK–ѕаN[˜/ЃZlЙчЇ—<b† ˆЙK>” J_ŠgDВЄ2œk‹№ЛŸ1ЏUзAђТПnЧ H§ЂTЧнчн§rœБЃЧyњh /јДs,F$ƒс;ЦKfqчh lмьzЮЗ–CЈƒSS=Мф1еi3KЊу`gЌаŒ^ь~щK_ържf)ЮA­nтDx†|RЦƒW{tЎ[Зр ЮБ>ркё†wuј<’|ЂLМьЮ$cVw)`SЯЕ|оŒуRFIOюрАMcЈg—фzсЦ›1ѕqŽЎрRЦжа”w рq;дУ] `ю2kойšІ†кEoєЬуп~сООош[ќУНбGFoНїm ый„zэї?ћўкoO<јx} hM{уНЕ=њХкЗ+{ЅИž>hїўЪЋыйњфнбГmљ’zcжs}—Зf2@ž]`ДћЃе№ВRН)uФF‹ЈhihЙf#FtЇt‰ Јл˜[Іœ($N _њRŒ,E“ўЅЎлHcOџюѓ+Џ•р4>œ2к3`ФдЅнxк8 YEžNЩЙ8V.рC[ЗёХ§•YEtгŒ>x%ѕсWЉœh œcpžмГwЮЁ<чyњРu8OŠу'8щ=ъ"+mбodЅРHžш6[Л~wKЌФ‰9НзѕеўщzhKРtŽў$є’­-Ўџ“ЙёёЂ~вN>ВЄD3ИюzД‘'IшђЂ”[“ЦаЂ?ƒ=?UoєѕеDИtYЛэ5ѕRб’žіЭЏxЃoQчО;ыОЅЋлžпћFптZТœѓFпфЙњ‹уѕXњтКyВnw—яNеЇе/ЋїBj?`lзО"Џ^ІЋ'}€‹/YелVoє$фhлЗcДC=рЕЌџе5ЕФљg™Џž/†јpљ2Ык9ћГ?ћГG&›/^Мёђ‡Ѕš[Hƒspірœƒ‰№еХ!^)1V6a< I†+9ŠrюјZ)§атnŠVТЭбpърrœЄ-Ћuf7чxg<’х7у‚?јд}‘—й–р7Žё•RјtЌў,Ёсж/Д1Ь|„-ЦЕ,іёЏ|х+WeЁ>Мшым8Ih‹CаrR/„vуУgg\Вƒ0.9<.ŒwАкМюьњ>Kj3НNНŽ,Ѓ/№УЃt/њб~Œ †Ми]ј ?xŸ>ЮсВ—`ЦWЂУ*ЪЪ)уƒ‡г}њwжѕvйнPНXv№йЖыщ=эфЁкˆЋ С•7дƒ=%4єз—|NЋ%ќ‘z^ррбZТз[ЈѕFп7>ёшwНб7ИД>ШВІЦПuK;АЌ=їфгml_},ЅјМхUѕЩЙz-и#Т+жЏЎK„:юэЏўkЕP—ЇО ДЌt9S—aKОщє?КДѕј?\њЖ^Шѕкб+L%МЫž_ћЕ_ы\хK+ъ|ЅХвЭ§cЫ1BЄIЩ№ЃŽA€ „ЊMв/)ТюЎKлl9Лl…nNпд;Ÿ›КaXFщ˜0кcЦЅ]uсS‰'ГУ`Œ tњ™§єуСN?eЦE#˜єa†~№нАЮ%%cїr‹š~ЉїЊЋ/4YЮOw‰oчш0np.єтAцˆЇРŒF N|ЂQ"“„еЂўpjѓ\Оч Жl™§^#ћ1ыУ‡ДР жъA^бƒfpъ^_0ЦЁЅs\ЦGƒўфм-'ѕ&1ŽOЋя?2ТЃc§ŽOŽЕ“WŽЖБžgкЅѓѕcЏѓњкŽoз‰FnnЏ}ѓkкиоe#Е<џаћкD­ g—№kлпѕжіШПбYТћ(ˆ%ќл~сЖњЦ_§œисёЮ}OжЪэ‰‡яoЛŸ9оVlhэЮЛожn~еЭmЊљ=Д{_н ›зі<ЙЋ=ђwЖ уЕщкS2яЋ`{ЊžQY4Xе—­W ѕ/ЛuрЗ*ќrЉ‚ƒufЎW Сц)ыя|gG‰ŸјФ':ї_ †ёйMvO™‚}\ >FNYpPŠ’ае9—RvNЎqžњ”pћZўdэзJнуХHєad9Gћ\8|Ёо8Ѓ03ъЯs}сeИГœўкcФh$“Є8}]jРЃNщ0Що˜ЮсЕ$~џћппyзѓЃЯ8Iш';юŒzИа ­{Ма'#4Ÿйо ‘уы+s*ГНЏўк гцЫA6ъШ_ш\рВЗ$ЈЩŽCKф‹Ц№o|‰|ЫњЁJ|РЁ>:5X{q|0.QЬјш0–ЄL†o|bМ}gњkэBo=ѕwњDлПsЂ]ЊЛСCЕэЖџ‰oЗ{ўёЛЫ.–Ж#їзb]PЊgD†}џaА–№{;гё’КЗty=]яА ­Јo2жЫ>—.ŒЖcЧЫЁ[[БiЈmU§M­"іеЪщo}{лѕшЮњh§*rнђ›пыЁБ™ЖљіЭmењњ„rќљѓъї,Ођh;БПюlЌ7P—MПГwЩМўщГWЬ–wЏ|PŒ/Ц<сЙ?ы§ьпўэпюЬ8ЎзDzэкŠz†Х%§ЙYD"3uрс >єKсNуТ')е[ж.ГЅ Вд Ъм–­ОџoEf9 4mŒўфn~д…c‡_уƒгŽn‰.ё›ўh’\зsžмЦгЧ5Д•Ёe>Gt›OАBПе žŒ~‰ншчо\ъh32.zёф\Ђ+ЧfwєƒЅ[ИУЗ жэP+VВAњCGЦP2<ЧЧЖ#НЃmВžх_uуъvчНЎ­eЋgїечЪЗЎoЫзЎnC;‡ы#Е„нпњzkПЕnщеВНžЯY~УЊ‚YYŸіЏ7љj ЙnуѕжeCНЭWOѕoЛОyК­м\›Еѕдп@O=ї№єhѕšW—лкбБњТБУmѓm7Е-ЗнкљЗэnляИЙ-шыoЏ}Яц " л™cЇ—ОnўЖљБ™х•€ъМ„ @DyLьAмY№бѕЬyЌ ŠЖмiСЛі‹гQT”’уЋSз]:ž›аEХ`sо]Ђ{nвžz%Х+сСŸіЬ ‡Ёig1 pYж3(_Œ‰/#VŸыTxЅ8ЄБЏ>ŽCC№™1eNн}™€^ч™ёяОћюœGx“р$ЋШY}Ц Œѓю”іа’6уIpтэf{Žй€ќЭј^Жк‰гkг-рбEnъгШ^еЙ`#Ё<~%ђг~иxчdчŽŒоніd&0§L\yвЌб&7–sјр‘ѕ9xІ~щЈxšЉзr/­Ÿ/Пu}[БnYmОеЧ_OзFљУ_ЏлuЇкГы,сяxу[лMЗзOЋзЛ+wя­%|§ДY}§чб/?д.ž­Oё8Пnѕ=iЄі•ЮжgшŽ\ЊН„КэZД\к:а–­YвњjЗџФ‘БЖМ~ `x]}ЖюРй6імСvrьhЛєhоЖhИоУЙPСГоDьКrgБѓ–№ѕтай‘JK"BrL@Ђ&cM?ќсwm’]‚\ IDATРn3… ZŒжгLЪ!(СЮД€ SимD RЪЙэЦ7†Lё96цм<З/њЯxВ‹LЩ–Ѓnxёь\xVœAqlpъаdіG3Йр7ЦФас#uJ0ъ”hb”фj9jѓ ^Y{fLxœћИлВ^†+(У‰МHс“УHкх$эs“v§чфЁTЧЉнВ„зпxфf‰Яё­D8–_2);2‡l№ы?<‘-с˜<%ђ1%њбц˜ѕг}‰…~зї###КшХФфњ>xє}ŽaьdmŽб|ЈРХ3ѕРжТžvшЩНэ™Џ>S;ѕѕЛ›k™ПayЭђѕлЁ™vѓkжЇК–Ж§ЛіДЛоњЖім#;kWПьЃѓ№Вз™Ыѕнџz“oC§NF9ўd=ФѓфзoчN_jkЗ,nЇŽMД3'ъ{ЋъЫRыЗ”ЎЊЧ€зЗЉ‰њHШђ›к_йгюџјУmнЖСz ф[ДљA‘3ЧjeTл9ž <б7ОЙФgSІЙ_q(Ё A!МЌŽБК/ъЖрЏџњЏwZдї*Ійˆ ЅмlЦ`mДp~qxіо €rс;чќЋс;Аш˜›C_w§œюгŽёeь8 žаAс Ш9уъžщ9CжGftpР+СЋœ7ŽЄ ]&Y8цјє•є3ЖO–їnщйoУ mўСљ:}’р}ЄО&ux d!Лќ№@Ї†KІ7mштќt+ ŒIш0fdЬq‰FЧЦ1К­ѕеЎžcЋOJ_2 /кщˆдС+Лќєq“Ž'й$мрѕ‡?МычZKјВ‰ўсvєрЖt­%|}ЛВшYОЉ>\ZKј'киЮZТзыНЧъЫ@ jcМО tёьLЛїŸОЋ-[ёP[_?џ53]СraНUYOžЌ=€њ‚pQ[_ :^Я Д{ўѕэ†›з—\zлЁ]…k_ййSѕA’ЅgŠХYУЊƒWJ!‹(Eю ЁЄNЩy”G‘œ‹‚(ьƒќ`Ї‚\3Z>RŽ ЯЕХЮeЫgя­S”єОїОЇгf6;ь2ы'ПЯћˆшь pFЉsqЋчА’c3šђљЖэ ›л–ЪWfъ'лњgк‰КояЋEя`щБoВ­кОЂ~5xM­4VЕЖnЎ…<зžњкЮкk ЫZСіѕчР'ЯўoTC?в+Х|?$PŽ•CPJЉЛЮ9xЩь/Q–"OR<#Ї,FNYfM9‰‚“ю}з;;Лл'Я^Л|_}ћЋђKFVЅkvFЧP%zšc+4Љџу?ўу lŒ‘сФАР0(2аF.1>mърХм>МaƒдRкЊI’­–ьЇР#ЁAјŒэмо…’!kK 2žz}C‹vѕ:duJ‰Ќl$mіая6nщПГЩчhЭЊVn`аŸcc%Чбр2–ђ’а­Џh“щY{hT‡w—N`%п+ЎяНеxп}їuV‘фч–(yШ№‘нO‡к…Vус•|•Цb;`“єq~jССъWЗbwh3Члђ5ѕ•Ќњ‰Џќ?§b;RПпзѓЉ‹mѕк5ѕ ПKл§ЪЗ%УпhыoйPŸё.{ЈW‡ЯЋŸЋЋO€,ЁƒZТя=^OяѕЗ7МчOяеяќЮсemллol'žЏ;jх№ЇЧNзœj‹V,Ќя<пљˆшЦ;Жtю§ЋŸ›™цƒѓjїЈVѕс™БS3Ч:џ?\ині§Ђ Їь:дOMo-Ѓњf І3uD‘By2сЦb\нe„Ј$ФршЎ‡N ‰”2Хq" :RЗ@NЖЋ< 6–Ш?Lъ­ЩАр†г1caаh3VŒТcДhBžаЯ{FЭюd(Ѓезэ`ГсЄdШ•ЪmS8тшЙ Šс h1ЖzєщЃžёКFFwфЦиГ’Ї/~а/сИ’єчјVшЃп=ЕФїЛпн TЌЧ‹]h7ЬЬ‘[№iC›qCgtЎ”аІ] 'šи’sМЃAН1ƒ—СYцлw ;NŸ6ЋРŒЯШ\&§Сшљ Њd‡ОиŸsєhCGвРЅњљДбњQињццњлзз5{o{ЭПЖ^иЉр§РУmy=€srпЩісўПЖякд6пБЉ^е­H-сOЊ}Ђњ–_Я`™њE елVдnНVМ|iнВ[RKј]эмЁГэі7пZ_Ў§Ј \—Ю•э•ўі>ЕП-Ќ[ŽžёФфTћж'hч'&лš‘кІ;ЗдEўќ &‡ыїыЫDЃ—>rс‰іѕЂй†Щ凈№№C€z фѕѕжЅАОn! a)Лƒ€ЂмюR}xИєMNлмВ{ущч%‹Гuяє№Xн~Ќ'Ви‘чЎ{k94PЪѕ3I+ЫљzыС‹юD‘'ъ’aхъuэ–[_н1"Лшf†~ŒСcŽЫd‚уС84ЦЩ9'ч0v›с”Р€wЎcђ‰,Рш›vFЪаЬH) hCЩс`ьh2fш4–v}д 6xцјhзЗ хrФRn{^(Š аeеІnžШJJ:а…'up+%ѕшˆЦN"c€!Cќ‡vєИеiE…^— іР$/ИЩR› @СУKŸЉ ]с šарY3oKнŠ[б;ђѕvК–л}ѕ“ОŸљ§/ЗщЫѕЭОѕ5т =mИ~Ћoh}§ьјЎњA9rџ•vл?В„ЏеiЭшыЗзЯ{•узќѕd`}qЧОњ1а}mќ№™6љм…ЖГМw~йяБн'л№њ…mлНЗЖћNдЪЁ~:ќФљ6АМvче;6W*@Наі<МЛž#({šž™ОxdъГ'О2§—EО[0„#њ[ВvŒёЛНЂj_*еcЄыњђўR^_„JI„AhнyЎСiЃЌ(__Ч”ЃL§ЕЪŒЅЭqŒдь*Qžыui‰ЧH)ќ_=к8Xшэц{Or_Лё2zє‡Я˜ЦвŸ\дIuŒNtKкУkъє,дщ‹vуЦ)ѕ”мmрјкэйи+в^Г;йdlѕјЎДEd`\АŽѕ^ѕKž`ržБР/YМЄ LеЛЧћNO,<яЋ#НCk†к’•ѕ;ŽЏ+Yз“x§ЕQ7ђІњŠЯwъw ъrсєСSu}^KјкxО–№GїoъоОzШчшhёrБ2КXߘLЬяш;?}yzэтЅ}mѓkWyМБѓЃ=ѕI№ёњєзєЅкd>Vяћзƒ,Љ_ФЎ rўbН }jъсщ“ѓОzь.|ІD^?5в Ўџœ@I/џIРrДo–`†а$HЉ>mкeТL}7lЇг џдЫрЂЄюіЇПsЧТPЂ  4+иРcŒq~FТЉаCqЁб:ЗtЄим^Є|чŒЌqрFœъB/8tKœAА'ы' НъГЗРрbќ`] 0№єCБ$ЮŒДI jЦVЇ>=§ЄдСС€‡_IПаeLЧрРќмЯ§\ч{yhsiтRРифЅниф Їdгбиd< (јбнrumЖЃПЄЌpзz/–l{gїBДЃ Ÿњ+%ДuыпББб‘Œ'§Oq|§СsTЫ|w80~|ДяЦ"tkюydКб(Ё!AHŸШ|єЎNчш’ёYдљT=вўX=”іБznхЙBkFeм yрТС+Ч&L=7urbзВз.xoЯќў}‹цѕ_К4Еqa}РsѓыVзoј•.‹Пyu>QёxTїьёњ5ЋshM;_Ћ†ѓ{g>vц;S_-œ„ze|чєб gя]4бРњ‹#‹6іоvёФєОё“_:йNйQлўeъ+[вИжЯ5ПctТ%њЁїЊCОЌP [O\„^ˆ:Щy”‘:чЩЉЛVЉoRŽ•нЧiWІ>†›Ж(žђаJyъ(=ДQА:†˜ЅЋM!J–cаŒаБYOН~1jч1Rxау\ЩёЯPУб‡бЂIа?УX2&узЯђэъc–е_ЇH€р09yaуЅKЕ„Пks{юСgъз{=\6oz^пР‘Ы—І‡.ž˜кљlЯwЦŸЙtџфС+Ѓ…‹#УOНS3rЯ…#mЯ™'.uЦЯЭ:uЭtлz9чьњКжq %ѓWнО №+Пђ+=ѕ…ŸХ„F(JB"H‚•ц >Ъщ.ЃЄN‡kќ‹Р•ssонэZuкSІ(Ti|nŽ…ЧŒ˜’Сш †QФшœƒ АpХЩЕЇM8e‰ёЩкˆ8Н1срЬIf0№qЮыиcД6ОdNірР8F'g5ћ –Чкн.Cу9Ц—q*ГoVЁA ~Ђ~žіјцcmт–БњYЩњ|—oбOЖгѓыкИюQ_ЊЯ^;Q4-Z}еЙёТГїОбglAIi“еѕЛU‰vђDЛэ№И.^†-0В„vЧ№$ЅMveъшС8ъdrб– НGGpjю‹–‹ѕШѓзОјХ/~ЂфЙЗš-Їe&wfш*-y9ƒлfмEчї_ЉђЪТкЊ]xeцТ…СMНwє.ъ>ємБ-чЧЯЎЎЈ11=1џлЇЛј…ЉSWŽOЉ%ћ”ОВр?ЧХ<ќЎе”ѓЫљ @[;ЧЪ‚nЧЄєyQpu"§Р@ d[ Ж|`60&†)r{˜…Ѕ “"јДwŸЇ.А)гПж1ќ)ћR%иnzr<爂/№ †‚“ ˜чqpэdсœг€# чfCNц8ЋŽAn`dFІM†.A…Ѓы'PРЩ983ч"oЗЛД hрxЪ$AйjAщr‚“{Ы’#јуfcЫjуG‡LmУ[ыe’{kЦ_uКЭ_pЅ-яЉызњYыЅѕ!Šsѕ­ЛГЇъЧ.ІNЖУ;к-gюn+чmшм}1Ž "™сб.с‹|<ъЮpx?>bе"xyŒ]Iб офœkƒлЙ2эЉO›smdŽG4dlђЫeZРщ/љ­ ѕЕ/љЫSќ,TйEcš]9‡“8ІКdЮ+ˆ№ƒЇŸšњцЙН—wXТЏОxCЯТžОѓ‡Ії_›Ћ;w™ЉTЧfo3‰РЩŒС_Ў6ŠW&ч]Ž“ы№{_хЫ oюŽу8УЄ<Ъˆ’:# !G њ$]5ЖЊPŸ%ЄъгЗЛ4оЫMнДu+[mi‡?x Я€ŽіЬрœІЏcN&“SVIйHдЮ УOfF†jЩK‚€ўœд­Mel8œ`ФЉсд_а0sКў'{0O8R'ˆpVЏцтU<ѕ.зV-\лЦŸыWн\{фŸгrоЬШ’sw;~ЖЖ§з_yюпŠWТ\ч6Г†yО>Ta%сc,hрdЦ‡gk=Ѓ>sWН†§ќю6us­Vз[…ѕ‰щ+–ЕуcmзsЯД “ѕnD=VOTџzbЊ:[ЯЬ/Ў—kfъ7зŒЖБ ћлЬо­ЏžŒГярЛ#[FкЎ‰ЇкЛяk{ЯюjS+ыseW–зO_lџvпПl›кmэЕУoЋ'къюЬМ‹Е>ўN{~ъЩvўJвЉщЖtfMЛЋчЧлВОUљDжNШ&v >:R/с\ШТБzчЕЩxЈџ3Е њJХёГГŸыo3sœ“БqВяqД.чЏцN;#Œ3 Г:‚Ь^™Св/˜nќ#e5џП—Оo(ЁОКВk˜ЮR_№AЌ4Цd6c. ь Ш#“оqЮ;•ѕbdJŠ3›9—ыч8)Чнјр‰At—ЉW—урIЉ^NkŒдu;}‚ZЦа‡Lœ[Тт•г’Xuф8K|0fgѕЦ0–YPтфЦЫўG†ЯЬЯqѕб7ч7.\t  ў=eWgъї kћїh=ыъ6тЕ2›}ЦЎ‘ЗЌm“яйзЮїд3ЗдЏнToжOQя<љxЛtИC§ѕжїЄЮŸЌнЊыH}ьђlэW/_QЛъѕшътЁZЕ VА[ДМ­ИiА=Гqw[?ysЛaС’vќтЖѓЩЧкюrшK}ч+0еWTюЏ_Эщ):ЯдW‚з^i{WэjGїюiƒѕrЫхzTЖеƒ03'Їкp§иХ‚К4љъюПlЏ™џюЖq`ћU@;™‘c’s2ЩО ЩфЩN*ИюЏЗ+?SнW}тјЎяГЙgЖŽуs~‘\‡/+žБrl%\Ъ јEМWўGO?(МžPeЩЅ€—Zlт0:BЭuЋЅЋcЦgsа2д3хvБѕ,Рw;,œІ>ЪJRЧШјнэЉгO оœw—9gїЙ:чЩЦ#g<Ѕідс} K]œлЙЬсЭђœ–#j<ƒхЈ‘‡ ‘Ѕ/X|˜э­$№кССЋ] МЅОе8ДHtpњLэЯ”ѓя=§\Л|БnoжГфƒ[k…ђЦsmбІzЧсФp;Зјh;3ЯeV /­ЈV† 0= IDAT-mѕiљЖџао .Ъ@]Џяi#ѕек 7lngkЮе|— езmъ– MœЏЛ#ѕBвхЁЖnэ†ВіёіѕНŸЎoк]j+gFъЎA­v–з•=gZНScе–’гЂХuGЉо‚[ЛnEыЏgлэ­чтзOпѕд—t7жћэѕд`}ћ~fjІэ\§ѕ6vђљvзЂ+%Ю>ЫЙ)ёOІА;z+Y\Љ/%=џьГЯўm9џеьбXK§k]у3@Ю:kTГNZЇЏ(ХЁ•нŽп,0нuџQPxу\jl№А•€Y‡#r~Yфe1Jї­Н+Ю{кfЈнУе>їœ:§Кћ8—“тЌ9“ЧБч–Sъ›€gМsу'‡чјх„џflС. }ŒS2“eНc3Оq8Зѓ№Мкє“+€Œ+ИР­^Ж/@иLЈŒэoѓ7зЖэъ2хlнбXZлбѕЃ’ƒ§}mйЭ‹кВ™MgšЎQ.\ж-Ќ_ЎЫ…ЕГ:єНћ'іЖ‘zЅѕЎ;юjЧŽn‡z?}^ЛeыmѕМСіxНЦ<МlИMœЎ[kчъЃšх:Оt;UOИ зЯc=}ЌПTЮyЊt>ПіNЮ_Јл™k:|_šЈрVЋољ5ё^ЊЏ=ђd[ЕnmнXаі?} ]Љoйm№‘ЬњиХ‚=mчsЖE——Ж­ юьШС„#‘/ч'њ"Џ 3ѕцтЁO~ђ“Y3џƒ6зёЛ—њ?JЧяа4чпџчŽ>‡žЋЇ?(tVWЁ_80еsаїо}ђ‰ё2>™a ‚EpFoз™Л4А2p˜втpp0xeœ-нАк(:NтмёK%э№(%ewююЧaЛ@ )Д)Л3ЧЫЪЌ„V™ $N‰wx•qbmњ„ЗуMЮѕМ €?xŒхјЩп1м‚,z:N_С6ЋˆўЕaЖЕ6њnЌрyЅ.Mjgpuэ?,фѕЅи‰™zРЇ~ГЏ№O^Њw ŠіУ'ЕЃ'ЖЭызЕEƒѕž{Эд[ъG'† зР™іЇЎY§J{{нТ[Еzm]ьќююrжЅУKлТK лўЃћкšњUкЫы€ыMЕщuъ3еЎчЇ*аœ;?бžyЊі<ъ[uCѕоћMЏнољVниў#э я{{ч’тT§І}ё9~Эш5wзO\zюP-‡fкоЩ`Ц—Щ‚мШ…J.—kЃsЯG?њбзdѕP‰;ї№3уw;ОHk№ŽjќћџSЧНRš_2д /ўд7‹^:™mЬ<љр"ч7{%PˆY‘Б2LЅыYŠѓу>‚a_СЋaьчpЮщвІдFщк_*hKŠуЋЫqк”ъДСЫЉrž:ЅzeŽ-Луl'Чoњаj)oІЋЏЄскЌ#2’ШEРS ;ќ§?эipdзuпO7аЕБя;f€йg83ЄDRi-Ž,/В'vЅ\ŽЪ•Фњ’фCRIЉ’J9•љЄ\qЊWЙRЖc;ЖlЉlЩЖdS’%‘—r8œ•ƒь;КБ7–:ПџžбcƒY86‡.ъсоwп}їнїњžsЯ=Ћњж$зїАы;ъ^mЕдЏ# =?™С Ї НќfљФžУЯђ№H[Qб_]bo^Гтh™”зкXп!Џа‡_'0Hпц ›Р™e~ŒqЂo03 Яч­ї[ЂВ4pГU\Vl ]e%о[я+ЄЈ\п„яЕ‰ƒљєЧ|“7yCчшћ_§№џ јМЫCIwDLвЧyТ­Mев$Vа оrЖ(QЁДеœа5ŸдОВ 4™QЏ €BeЩŠ5quˆ{,CIєУъ~ѕ>zОr*ЏЎ)з=Ъ•Ј•ћЕрџє Икч"ѕЏўМ/ыаћР”šrMFЩєМОRыYкшBŒоŸо[{ѕ­kBœzЖоCeЕSЮOбwг„рыšкщКОЕЪ~ш›ЖaКќІЈѕиЧ#ЖгjОВК@П„ŠЮGŸіbm$ь Ћu!Ўi‡Цњm.5eѓ‹’HПƒіy1лпжj]ќЎѕЭЖ0ŸТУЬB€ЦаQшшиo§ЈѕЖ“'ŠЁ0 ‹йЫcђ‹+Њ§К‰KПlз_э <м.%SdѕћѓmAћќ,šŒDЙЭfђьъ+WэfO!Е№oпќ<4ДZœ•?…ЭћЬР”UяЏ Ф‚C-JВО‘О-y†€3}X1~‘яy™ŸѓN+ОИ…јпчьУЪwEšœ:vJˆpвф…б(Џˆuˆ™Ѕ ЊUPз(­žM|?tЎI.=q15‘ѕ# шPђŠЋ:Щ'МCчJ~ЎЩЁvЪ0Ъu8 ‡ЧЎ1h|КІЖсУл+W]г8ЕjЋ?ЅЦЊs•Аэ 9ш=EЈЋ„ЦЏОєєm”ДЗ—Лx%т­Ј?йhuз5Н›юW.$щяЏ\‡( mtMHfЂЎЯжЋYрXь‹ аб/­т{у9Інц6Ц>ы8&ЅП,ћ}‘йыЈ Ÿ>LhїђKЏЅ§йѕСk–!dЗ—ЌЁІйV`іМu‘ˆЖx>FA(%бPпdC§з1cЋюЛ|ц лL(sjШжloВН`ЋбЉˆЕиїОDШЊ—TТћ—Ѕq›ЕjХЧДтѓ}ђA„№ †{б\ЌЏ ъM–r‹vѓТ6ъ‚ IЖБRЖXФжулnР_ъ…Šќ|з^>Ѓп™{"ѓдџЁќЯўѓМт{OЛ!€w1УгФSвdімD[ЩœИкѓ‹#ыTY‡€C@ЃC@%рr„ \HAbE‚фзЈhРЁеU§Iч@} pф=WЙG}y ДъИсЄыz–_Йъ№zOП_mєlеi|* ˆ• 8еЏоMїkмКц"<НЏоQLQЕS_zGЪеЧg?ћй lЗюS?BžЊзЁчЊЇ–дПОƒЎљеЯhA?+ўЌХђАK!ЌА@НХsѕNsѓГˆ№`"fжljн~ЦUrhodЅЏm€БОЖХN§АнКfgЮ~Ф€щ0?ueuMр“.ГВЈЌ­Гš†ZћЮ_ЧЪЪ ƒ6И‘Љ!UсМHБЮŒл›пИb…™Z{цgŸСьuЫ.Н№Кiлћ-jЌЮ-ЪЌЊЋвZ5[уС&оЛ‚pиƒ6pю”B„айуl3ˆ> уёт…s§—_ьћ]~ƒ>~G‰ѓќ"ѕ]GЄОО~lџСпЙjqсG=эŠ4сtф&еir†“Ÿ‡s‘ТIœX!QZЕTжфеЄvd ВX“XїjВъР(з$W* €йzHГMзДђjе8 ЊiЬzІЪj/R]’ =_N04&ЉвЊoнЋCїњГ•kзў[IзЕšы~••ы=UV;оE}jХWв8дV‡ЪzwѕЃБъќ‹_ќbpM€­s]гЊ. Cm”ысwВТPО’sŽс`y{„HГхШf]лЂЩT6АчGЗžБтФ%žXЭ;мH]юЙdWпКs0Ї'І’pЌиќђД:јЄ]ыэБƒ0Э:кЁr"ˆ§' M5uDЗ™АЖ}OиЪТ\0іљ)є†ибч‡:‰Z рШ3Gэќз.тУqbs~Ш~_Š|ЗEоam}Эоœ˜Г3qС&olиБЫX[•Вš2ЖЋ6Моџ]цСU^AŽфјBРŸЛтя>хniGАœU­ыN7k*i‚zђВrПЎk*ыˆcэт*œ!€ъGHAˆР–Hb”ІЉ„ч^Џ1ш™ЊeЂмЧ$$’§Ь™3З){nЎ~”4Ўобы•;pЋ`oюЧл рuЈН( •јКЧпEЙо]‘(,Н—€^яфH%џ1ь№Ÿ€ёƒщЗ…OЊ‚"Ж'Ћ|ЛЅњќ і„cЭьl&X$ ?6b0{"I€‰“G>l •Еl ж‘ыo№Лa6\Z‰Ј.J@ЪYKrРНња“6Ю =д‹Й2ШДїъ 5зЖZчгЧьќЋ/йїџЌЧ6 ШŸјd›§ф?ћ мГgьoчЛ6qeм>ѕЯ?eЧ?Е7Ÿ“~љсюччmлёЧOкаЕ^‚džCRGјуŸ;Žш2Kœ%ЋJРУPЎŠЌЌи‹@dП€oХч#мoк0щ>,афѓ|ЇŽHt-\ЗѕzЯН­VF‘ФZЙДb h…і§ЌV;ЈігB>С• !Љш~QЂœŠp wРбЙ‡ѓ›п †*jРЏћјМŸ sўљ;yž рjЎ:%ЕZяхЎw ы}Ќp•иЕ=‹Ка!Рз5%=зŸщuы1Dzг8ŒДЂBј/bJТэ/F[ЏТ:ЄWэPыaюVдтqњиШяxTбŒ‹l”UЏОr брЌ}ьЙ€˜ыmФ™\Цї: Dљ ^щыі5ОћvќGь]ўцOћmЃcеŽЩF^ob€шъꂉ›˜Жkg/В%YЖf"фTЗ'ЌэУЯВїŸДйёIЋмWi+Љ-›С!ц6ћћDM‚ш6хH3иJдц#VlфYƒxЫdћБi%ѕР{XЎ/эНН_“т>гР;4}{žћ €мz‡я ЗЫ-;Bаd`ˆ”АјJшe! G aЄ Вƒ#=п…ЪB:зГ§љžыЙкЇч^гЙƒ’žс[oчЙ€[‡QKЄКЪПœњаЙrЯU'D&jDЙКЈ‘яў хžМNчъ;оБ•Њщ@БІdž*—2ЫЖaЛФтЯkВІšV[X"ТаЬ”uДьуЦ"ЮЮСLу:]юВзl`d@ЯƒСWkƒ7)ЏЪmиЖЕДЖ[[гЄ}y WъY[YоАЪŠ|;z }MЧЌыD™#Т{ѕ…o[@Ўi,Т’PЂа(ЂОЖ­–8\jgџт%ћкџњЊu>жnO4кЦы‹ДЩ# FF-MV0Зњƒ№іе[>ПџмиQвJ HfœJ=НQŸ|uCћ1чьыуќрщУьЅЛ~;!€‡з{ O@ЏSn{Ї6ЙэТї„ћђВ&ЕVЋ|n[šaZIЕz Y(’рщКOїIz мћ№мŸууu€ђ\ЯWYyю!€UtИьuЪУ.'РPkUљЎ\@/О‚?Ыsѕщc чсq{лШi €žEтA8ЉйkHЖV­ѕXЁ•б1уj,Q„ ']ќ™й);љЌ­ЇБlLoйi€ИЊЂ„§џYОkБ^[bйMсŸp%e uе6vc/АЃV‡Ÿ€ њ{†э~ѓЫVSў]{юЇ?ŽЏЛ„=џЇ_"-"R„2е1Н1јА?NЄрѕѕЌ];3OФhі…ЋЖ)n!Р_УЛ‘ЙБid“ю!ФіЙЫDv"Z‹в_XХнufМŠ№иeU' џрŸО§=і€п'Ц}ц;"VКX|ђхNюsюv=ЗНњН—ДSПB :0У@ЇВVj!=УEcz–ізт5ј;yЎkЂ*„PМЮаŸЁ\ЋБј^чЯеЙЖ n•…ДœTeЁ-‹ъеЗпыЙъТЩŸф…ш ДB•,ђ;Œн›кzPmžœВ’#№XRQBG!fмDї‚uqГ•о2ќ Ђо[Ъ>ў уЪУАЇ8ŽтQyдRф3iohч}фщсуО ьK6:2 Љ љ]’o5hыmсsђл/ПfyьВлZj[нAЈ+ј ФМњЦ” іMкёO.кЅЏПiхшд=]cГxМ›Xd%—\yўbвІA<($BвГlГnЯgq„Щxq‹ЭтMh“ˆК]5:@_„mBK[щІЄ х&4/~‡hD#+ИйfЫV™љx~"Я,AЖ›’Не?<юЕќ.№ЙЯ}Ў@hж$л јюжёНоуэ<ЯэзыsЧЁs%ЯsягЙЖЮјгОйOЋћјМ>|~ЇВюЭНЖS]И_пiŒЛеiŒС8‰cћё§з ф-ує FEЃ8ќHЁS b8 А3нЅ|єё[lц‘c*бIРп|r`Э:ЕZ6Š,&Є%Q‘Ј 6Ъ#уЃ(l!‚‹з@УЁ/х‹~пMkЌ‹ к+§‹Z8єk6ЦЖ А5eєљз‰ЖМгn5Нb‰ВJћаAКw—к•oЗ Й#'л&в†й‘7є#Ь(*ЁсWеZe';-џ†•з•БMBrrб*›Ћэц7mi&mћNд#a@х„ЮSћ­ћёЃvљеKжў†uŸ8ј(8ѕЉvvEФд›/.?эš{qыЏІзлЃv›TwИі№ФODPЖyRРчшїхž{§NљНЖѕvЪНМSЛе…AИМл=ъЕл€Е DВ•ЯЪcе†ыVRWhе?)Э8˜žЩ”BсTTЗ&e7/Nккф1щ1 "6]€/#„дњfЕYЌща€-&&}?ЖЃxўй”h1[HЭ[9ЂР†К&BЋBc;Ш1šElX\PMи+\YујC””V§$!и†њњёД (ЖЃO#XЗ‚КR›†вXпZ'$і+Мй Пwеjл#іёЯџИхЧѓ­ЁЃ_хШєq‡о Ÿ‹Хb‚`цсА5Šv$яWлЛSрYТ_ObGœ˜Ж—Ї ~‰ЄЂDH`bЖ2yeйЧј-Ѕ§w‹гњЈўА№Иn#?уŒˆOьŒšœ;епЫЛщО№НсђNїпэКпуя€уѕЙЙЗЫ­”Ю§Рgх—ymчUpеq NC1 Ћръѓ9Б\!с ŠZАм+.БзП~rЛЦ6ВPs0§‰6ФўНА(-Уі`{35пТт‚Еяя†oГfдЖЏєлЅ7/вІМе-–ŠZ-…‰2&ФЩ‰>@ЬjQ^šЗКzШyHќЊš"Д§ІЌ”эTЬУг§˜Нј—пЖСaViЖ]0Ѕ(”Ј‘SPГ§д!ЫАEzхпТo@ЁНє­‹№ иNDд …АКˆю™2x+X”–ЖкЕ—†ьмЗЎ Œx4оBњh .ЬЮ щ@чЙиb;ПЁдеEьЅјpрч~ФћЙРЙА†ЏЋ>їчм)ПŸЖоGxЬсВ_”ѓлH EЖ6ьі‰;ŸЯJНМКŽ–] 2{VцЩiј2К‚ДЦn^|‹:іФ›[зažЭиOзXЂзцЈќVW5С%€ћч™Щ)ŽЌЂ0Gз0ф)-•3”D‹f‘РЃш€2шяУхRШ‰ЁˆlХf—Q№9hm]­65Я,AїwГЦіKЭЎкЗџє{( с›P@Ьаc Іжш!эцРуPэ-ЗО—z‹…ЮNІЬжй*t5k>QeM‡кlь­ Ј˜QЄЋФКпg=/  s0bћЙО џdfxг?Sgнm@§L^Ÿ ‚ІЮ‰И Ћ~-^:Д иKїё№СЪOЎr Дїqџ›цoюљN7оK›юлЉюƒќјЪB?‚ћзЌъ юЕˆtмˆжнњк ЗЫЌ–˜Р..YcS-%—­ћ№QK”ГzЗNњЕEМъєІZšН|Fi‡BBш\кHПHщ2VњYфg[h?bсWZУО{Эn"Ў[WŒ{Шя4>B„|ДuTt'XЛ№ЗакЙ=8€ #ђFЯ[Ж€ЛЌrЖrfnіp-aэGmЂчЂЋ0ќш'ЕaWзжЬ}ш€ЊЫPЊк.АО‹збyРќšEКАTњХжЪjўдsuЌшјќЧ}иўўf'%е0Ј\€as‘й&Ж@c&`.Е4’Hиў“‡ь—П№/ьљ?њ"г‚ДPмЮГё ФБyИњB"2˜ВŸ<вЯ‚ѕb \ЗŸбrЧlЂoоZŽwЂјC`“‘”•‚Hа\Јh)шыЌv_ЕюДСKvѕЅ^Ђц2 PNK/Ž~uщ78й[ѕпУœ№+G|^xRљ^Rуй­ЦnmдЧn) а^ЮЭwЛџQЙsАњ‹љ‡и­ДМФ˜еЦ тжїжUы<аi‡К0†4‡Љ‡КoтИФbѕѕ(лŒž-JQ—-ЬCыW^UЕxъYF2€‰э2dџ4LЕъ&Љ63Nd]Vљ"Ж ,cу_\п`y ™єђŠЕ ‰—ижАьшnB@кŠ8tСjqzdЩІnт8фS„ѓЊСоП Ѕ'Eai!Q„В0№вжvЄЦъ:Ѕ‰3"ЩЉqы;3a­GЋЌЛ€„l4ј[i•Ёk qat5bћ№ \R[ŒAЖ§“6}sЪц xR№ ф9)ВА№њци˜ЧUq0њ=$№ ѓY€/& l+BNўPШџ№`иУuЙхћE4Й§ш|Зk;Еъ4цр`K>л”ЖFДт к­ 7й(:§Х§9"Жуі‰Ÿў)Дс6эЪЙ7эмw_ЗO>ƒёЋѕиL з!lь+~*9Ц\ЬЪAзбЏŸce_й–ЈРЃ0/]RŒ>.Л60пЃ&\` вn}mнкOНџи!М§T@ЬСшЋБ‘kз‘,й`я„ulЗэU ‹ZKй лі§uћšm>…ћёy<ЁиsьйN(” Х$ШЊ*ЃФZЖ Н о5|ˆ‰оQKb[v`Ћ€sTHOHd CЌlŒO|шo)DyТZКушЄЖg__§Ящц5Є,M@‘{”с~S”Аџ‡5ѓрщn€М2№{=з(сѓйрNФoй|t ˜№'‹Б‚olЄQеMБїХИЌ рeс ‘–SiыЦ?Т:юО“XмЁQзpŒШНY<јтЭ'QQdO}ьi<с)зХќ‹XCs•M%rГУŸ&”Цр[§hтђki9№юлкбЪF‡"S жBDј•-ТuУ}oьhУihЦЎН1@l{Мј<ї˜mЁїџђзП‡п?b$`G<&ГhэЊ ѕ`?€ѕ_^MBќŠи\ФЇ`~ЁкуŽЌЧ'№d07ŒmOЦ#o№&‡gз­ІГжкoG 8Цv„X…ѓi[мј­єe{™ЮмњO`јљ’n#єз‹ЖSв‰пуы@ыЙЎ‡Ыоў~sѕNЙчсkЄВоC‡Hђl ŸКKѓ™мАњІFo8EцОя`‡ _ы фх,љдӘ‡4‡йЖАŒы-b ŽЌ\„hAЂ №чПѕ'ћUжокb]Ч Г_8Н а~хџ|нRSKжНПФn ШрЄ:а3€4чЇч­ Еп$ШGюСЋP­GНWF;НчЎк…яО џЁЫо`•ЯGЅ/IX"ЮŒт>‘]юТкŽэГ…ЉeШœŒ oXcW9zџPsˆОеmD8Fт‘šZД(ЂK›'.Ттš ^ДVŠйh6Г6ЕљѕЙяdў˜пж§ћ‰e”(€Нє_Р@ s“б{OЙ@>—яНЧн–2c-Ыb›7KЦ№з‡(ЎЉНр?ФО?ЯЏО…CТІёƒ  хј/6одШ4ЊЕИРЦV~zkЪ У6Чжl~wZ‹гж €ЦГEЖШо=П}„pa8сHн„П…š№"jޘыnјce.m[<+9™ДЉсY4Зmп1Vuфњklвщ ŽЪ№к‹v`Ђ8и*4t4cЉ7gзSv№CЕья F C0/&Kн|BЌњЅжvЂ”ћ‘2№ŒRьћKщk%ЕbХјўk<аdХƒ36й7eљеи1`-šІŸ…БЬЅэХШ sgжОJ‡ъT@ћ™ hexчъ@Х^Кћ0гмŒЏDЪ&ядзНдЉЭNэТЏsDс‹”wЊЫiђhœВwЗ ?€ш4С6Ш\w–§ў(\ўrШї&ышъ ‚оBиRPTž"VлжЮфх8]]B“nŸ}•ѓ–‚'Сo3пыыф(†CГД[Д“?n}ќЄ=§™“vутM_ Ж™M[\Цб&@ UŽЎЎШGёД рзjdЋ‘ЖчnZэЮ@bxтХј*Ї?Q]lЇ~ќIK ІРbn.ЁГ0ˆЁаќIDATр.+B§—@!У)ЄrœZF-/ЎР Ќ xЋK+6СQQщЦјр,žЪ2+EзйяџбzrKnП n{џ‘зŸН§?сН$1х˜Ўr/Лј РфžŸ+—Ё:лъЋ>dЅwЇsѕОю3ќ<•s“НъН|ЗмлzюэsЯНўя"ПгГnsџсРk_ž‰Џ[еI|ќСщŸgЯ?‰Б…Йd`ШДRHa*<Щ -ЬНЖŒoAмoЅSИƒIЧрiu7фѓ„‡Л~фЉЃ6p™pc˜їжДеўkiРN8ЧP2ТQktaФ* VзYЧЪНŒˆŽр pї иЇч#–гžОЄ*С‚0оPc§ˆю ЄДУcшФpюqЦђ№'G+ёх?Й€ˆЕХ€ђъꈋ_йˆЪ1dџ№х1ЋЌЋДЖУP)lm†„€0КуЖb|JŸ йПt}эК§ЭъЭэ2ЋйQ^uŽC QZ§ј)ўш%…]SњЬg>ѓž^^€H'эЁЖ@—Ф;_јiwЛЎЖїв&мчнЪзнвНДЙ[ялu№]Є ЇШіD–вђ[’€–yMUЌИ…жˆі\яЅaМњЌиBЯ ;ѕьSˆѕ&сХ™еsalІўѕамЋ`хтSЏяЕЫ(.ƒ|PўbП†eіфO?‰4 м.§эх ичš}ѓ ™x)Q€'ц­ыПV‚sdй,Ю,`/€шЏїjUEx–ƒrFэшГЯйW§;іЏ~џЃЖŽ#™Q\‡/cЮKћЬ H œКЖк€ыџЦ_ кxї˜5€D=wЪ…Р'PиŒїŽСƒиЖтк‚МХsМЕт‹ф—л/љќгЪПGњѓF№ ›ЎcЮњ-ќі}ФVˆРЫяѕaкЯNˆШмsЭЫžПзёО_їg‹ўCШб'Чx)(*fЊ‘Я7uЖсГœњ9+B”іє?8С}ШОsmа’Ќш †D‚˜уЈыРЛ№'ŽВяF:т8ў‰cёѓ8жЦY'Qб"ŒЃ“ПЇџ…п{ Њ#‹ф€Н?[)љTЕЖž{з Ї3Г}m’Ÿ ЅPхјuм\„RаBŒsW|Ю'qщнЧsъPЕ:ќїG аB$HhД Ф ˜@3UфVœ~v=ЁФ2_gлВ‰qOŒ‹ŒWЯ(Ў$€ЩbЊ†ˆгяŽ>}ЯЏЙКЗяч#<Œ$ *nъ&ДЏрqч €ѕ}AЅРНЄ\Ÿ‡Ыwъы^кьtЏўƒ є>ў G6R…!Ц4’бЫнve]ДlgŸбКOdu$ž§и‚ћьќ*$?кзњЌЕЛ кCШзoЄ%0яVьТп\Д‹пМ€O§*мƒ%lщFОUCц7ЖvF8чЯŸCЎ>‹xmЩ>§Џ"Ав+Р2ЏЖЙMР9Лє­ жџZ/ˆ‚€›exэAŒиАП”mЩ@ЫД з ў‚І`Ђљ%ьћg э36~mDƒ#иЖПГЧŸS=DЎ‰Zз"џг6t~и†/[ CАBГљ)мЃЦ |‹ЉHВ2ŠŸдmѓЛkŽ:рkСRК;)xЋноџ]О€€АЉ>В0э"Ž3ГЕЕѕз)WqIРy7u М[;яѓ~sяџ^яЛпіїкяУlчcTЎcЋœЧЃs3O’С Й KЈМ?zhŽ`q7ysм;n?ёKŸДžKoБ'Vл… ‚tЮЇ-CБlокЋmђўлаРŠЏћУЧьШ'OиwћћХаv№„}іп?gEе…С>hЫlЯл =ˆьоВžя_e5.F‡џ€ ]Б›gь№Ч†DБx‘Ѕ&@8 )­)љФQь™БбžA›Тa ьКc–h/˜b€miстš[`ƒ7сш(ŠC№ 0fЛ!фГ/c“xT—‰оА>lt є{Рџ&Ђ#QР/о N4ўўќџ#“В\S@э|нžыРяЙкц–u>vыoЗkWnкЉ.ЗЭЃrюcUЎCŒРlУЎЛіZ’|’ЦY{“]=wџћ TfWбр+ЖКFм—'97Ыž9=ћўЕ4љ$uшаxМЫіn'<зŠ[:cFёХ_ NBm?зћгЇƒш<›Dя}уЏžЧў€0e(н8лkƒo^{=з€FйfЬ`ЙзШžžЙ€Њq>CЏ?јъ‹€ &ЎŽЂИiн=алШ…Єuž>`ElMjQЦБHл‚jљhˆвџeыјPupїЮ^ЋУ(юПв [lQр дх5ЏужјжjЏќнсGх§€ŽУyЂДЧвЦ.†уЬѓјГћ5Ђе|‡–Ma "Шх 8@ћЄ~/пТћz/}|PюuР№oЩпVb †]ћб§(кl`D3fГЌіВА[ШK[Яй>хБШVЁ Н6hНч‡llШЌћt5Д6LТЅСЄ5эkˆвvљы—‘§У`‹Wй‡~Онџ‡Ї-БяАЕmЃcОз^ќпЕЙ!Ф…(UЉ‰tДD^z ˆSvѕ›з ћQ&; qVЌї{§V\‘РЛЯ~ТŽoл2:њ+ šZ"јЎ,­лрЙq”‘ŠэєЯ6 ;А "EЁ'80…ВХж`м†^ЧиhfгžјEЬ†O6У\х‰ž\CXRв–‚wNЏ•/S2 їпёя№C?Œyx‡ЎпU†w]М‡ŠПЯБю4!}XэЏФ]ЇU›ў(>їољ5b§§^ђЖŠАЈИЛЙTAюЧШ=Їпw%яOюЅ}И}Мн>рnзТ§М_eП@Д2k­Ч›ё–л†Œ–}ЃШрQ-€ Ч6m83ˆшJ0Њj­Д'#VV9˜тЖtЕрГoУњЮк&Ь=Q yсдЎЖЯ~сW,‹5сtП]§/Yяѓ,П4†J0P†ВжrtэqЮ žхa%HвDс‘Х!ю-M€Ru6i?rw]O№[х7Z’†uќ JќиќX“х„„ИЫЌфCчG!љБ`DcP,ЫEVp§•6$DMТмЗЂЉICHЅd‚c’›8*]MmЌЮM[57EјAq/=Ќ/р@WZ\WOлˆЗџK]]нЇ‰šѓOИ€щи-@u*@y@Оцфa`ЙwюЙЮ`•ыЯНэђpwjѓ(ећx•ылmtБnдnчцэь_ŽaŒЉ.{чъFьёсŠЗюВ/џ@+ШкЃ(ћ _ƒА ЭЙri’DуНёкU›О0i%ИрЉЈЉ„љжi=пщЗŸћOŸБЅбvљљ^ы}БпyFЭALmOж[у‘f4ћVlьъ„НўЅ7­Б\Uбx'WёD>–‚Љ^bм”aQ)+8њљћЭšЋGЕwCЂ5LyYСYНЇБ7икŒY ˆ ч[WY§YСЇ‚”DщHfЪЕеPхqп |РXBь+Ф‡сШbGšnТeKБpuэЫb˜№Лiaв5ŒЅŸѓ=!OЌ3СЫ‘€‚ъ6ˆDѓUm иќnЗŸ8o‹ЈBЂфSЪ?>СНcя”vЊWњ 'oЇм№ѕПяrюјфљzј…Ъ­НvФžўе'`АЁйag"c—gёяш™А}Яu[рМёZŸЭcПЏЙoМC/ОjЁЋбтсо0№‰ЃѓŸ„й'% ’ y Šйt H ЋжxMAмw"rr`oЂ+Pў”,ў mь…^БІc-ЖиHoB)сlђ@`[Ћ‘žе{‘яъbРАpчЩє ?То=;wю\іmЗ`ТВХFюTА/МСЕєЭ›7џ'юЖЛ Шљѓˆ !o%Mf…#Ї vЂ €•‡гNчЛкn§фі~ЮУ(?Œў}ќлЈНeЊ–‰€“АуЯžРСЦ1D€hёЅжэЕЏ\РаgЮвв,AN~ьй#(Я gи.94VnО№ж“–_‰->$|QC=zVшMЂѓ6„•~ЄЮЂ%qТ{M +ТŒМ,ё#аї­Ї:Ќjо‚ЗЖJ;‘єЋs0с0Э-BХЗКїcијїя:ћvЂ"уј3yзм‡PJB7рц™–hJ Ӿ՘ЕИ[Ѕu"Уэg …3йxИТ’7ˆ‡€ВR^>†јП4cХ5 V!Ÿ‡рћuT™Б‡ЋѓЏnў>П“˜вЫк– hjAвМмKщ мІ„д'ˆ@й‘€‚‘aТТ+ГXцРў!СЇ№Г/DЈ“П €WрTB.№8 ш^/+зНожЫсыjяЩлљљЃœ‡п!(ѓЉc [Ќ>…Lў•kп J}йУŸљJŸMі˜ў…’€16єжнИ|gpфр&SI[FOПЧ( 54Е№ 'а;b5нЕітoПји—[АЬzXЧšИєЮ"&,Ќ,„Ћ—…/0iз_@_ПйNtлќЭMЈЈ:~ь)DrEkьщY鉄тOj, ХВFэO6X=РЬѕ)ы{~е  ŽќŠ;ВUMŸ уѓсOa9ž›ˆюг€Љ3іKФ ˜!єyътЈ$oУˆ”ЛёхўЭ?пLf1‡ ИŽ4їјм|”цЬиn#ёлд€ЏўЪuHJ $ L,ŒМ„жр"GNDj Э§IxЯR_žрЂ< ˆ…””ћЙЪс{tнЯUіЄКpђ6^ячс6ЃЌqў]%ГVћояйк4FРeг‘jлїdЇ§иЏœДQtч#x оXA5Sй”eЖkeЕeь­Ѕf‹ДIСFnТў,явјї<;nэOu>й?gЅ xj,cѕХV AОK3Ž_ЖeVіЕЙZ„xb,E(цЄPш‰цЇЏŽ-ХM\‹F%™-С њ…˜€БЭ щn&Žля&ГOЎиѕяMXџ Н2‹2Шš‰ђф›ЧЖpь њеD*ШРѕ'h ЊЮIЌ 7б2”UрПof)r)}-ћ]ОЗЄQ~hО h!њС„тDЩџ[g{џяї М Јƒp Њ@H@XXЄY€ШKА"Lѕѕѕ cнƒ№ ž"Wl„џ8ЗїКкяОќїН+‰jP;GоРfЗ{НэУЪџЮŸ%њw” Ј Ищ~ПїИсŽА2'ч шЗ@Й…хq›„W{­іpЮ+‚}ѓЎВ№‡5]I`С7‹ЕпмШиСьќK7, Ъю|В& фїьŠ5ЂZk…WУ Н6НЪ> и9M'№епб8і™p,Е†SЕ6ќЪѕkšеŸ8ƒ#№–чcФК~ІЮbŒiКw;\~БŠзЋБ}Ршєе”U 1˜h.ЕЉЫS )?ўЪxnYQ†XхgњfYљЃ‡С))Ст4 §v4ЕxnуџђЛiеwрWйїџaЪ”ъНє0ОРŽ@‡ЖNш5 D Jж„’Ѓ@4Чqђvvvžбv^ ю’=eJ#˜юЮ!q91ЈѕЃm6‡#DK",,сaheŠ`žIєўл`bt”!ў ŒМ1уїfuќжќцYЈ}…Эiћы1ЛDQ€яР/*3 ќœюЅ‡§‚ .@~Я§О--а}:Ао)|ы`w(xШ œ‹R‚(РтАў№сУ'кккŽЁcа…hБЬ_ЋОЖaцa.%GTh<чіv#їZю=сысkсВTј\e!мКpНS;ЙmœrфЇX†rПЅ#ƒCЯиcxюЉ]ГШюdЄˆ!ќ$nГ:ђXэёœЫо_ф{Š6ѕ] јплЖ)‚eЁRЛ‚М~ѕрJtВ+ѓЋ[™ХlO<‘=Eн`Ч -шДnБkнS0ЫV‹рУўPтшЧх’ ь#iфD+sk6љ&Ћ8р­ŠР;DsАї`‡ъ_,Ћ0ѕšŸk|ў-с}xњъœ5žЎГ’њ’€УŸ`kВEП‘Ј UЃt„ѓ“Ѕ‘tптй­џЮв"™ПŽ?DўkйuѕїЙ@Лї%9eњ пЧЏп№}шTœ=?„xюHAЙB)AршбЃ]Ф%иЯ–Ё…-CTC5nЪхЇ№6ѓ0LаЯmрs ї\з”ќуz}n.РTч^ЮXяьсКpйл{чоЏ#е;PY Ј+^%*№ЪvДd#’‡ЦOС4ЫjŠm z 2?@іЦ#MV‰СЯЬ)ЌЇрІчГ Џр~ХkyбТёд•Хo,^Щœ‰UYaэSџЈИ*іу•MхбBю}}œеZV|2.ЧO2x90ДA4pіѓ оБ:З‘…'Б‚ЯОШЪТza%cФˆqd‹Р5єї70эM@UФJpў иFПŒ€%%H5ф)8ЩvЄРO-ZYNO—ВSЉяЏџз-TјЙиЋм>ДЕ№‹я$ŠѓЙD!7щ7{?г,є]Ж~8BPž‹ќмЏ9ЁЖЛЛЛ“mC+оŠZ@ ѕB Кп9ИМ^?ŒЮ‘†ЦызTж5?ч^яРъчД^Џ{ќйžћ5ЯuкљЙчЊѓkф[0RЇбГа‘$Д8*№xжgђЪEV*юŠх;/[RsЈ>ЮЛ<чцA–‹2ZCnЯ*ЯJƒЉV€јpю|r+=yem8њеЕЁэ^WфД€)[v8я@aЋ}GЊZКpzv-PкЉ=XCqЄRшY $[qAuQIХађФњЭuЌє2йэ Ж#YxљИЋЋ+;ёЬкf~уhœ- TEъњдHжъNVbя_0џ2˜ѓхaFЯЎіdџ 3Ÿc\"ћБ $6йіўї$ігЗ|?гШљњ9Ш@л„0u dрT‚ЪtЯw* 1Ш дVuљЇNъ‚B(AќX(В‚ЃўšАБ Ўу<ГИ‘ЩШ}’•tОгЁы^яeкм\эТ€Џѓм6єuРxf2?Eћъf9ц8_@Œ:B&К’oЉє~Ђ’тљ%‘ђТЦМцЬZ&ЏцxСщšЃнљёxDКђqШѕ|Дёццg'ћ’Ы%ЕётD]Y€][IїЇоијткФж§ˆ”ŸF@ЯPџ…EGэ—Kjь_–5”eбР[ТŒИ„PsЈd%X_Ю.ЯЅ—qЩеЗ>З}n#ЕнЧЏ™СNП0šŸ—‰ФВEyХбЫп&n—5чDрвЌ$_ƒЋ?! `-Е‘Э/‚уž6Г”ЙБ6Вu~+eŒCЋМ“sў}Ќњ&"§нЛBИОћћ™іР._?„ дЪчB*;R№\ѕ^vЄ sЙчоЮsны§eЖхЂ"L–ŠKU 4iDдiU ј„0Ћь@МБММ<щчмN“m­фыЈIOщœkYVѓхT*%nЖ3LEТъаЙ&Е‡sІfВЦ,u$ ОIАm*эЬo‹5o=+ЩЋЯ/Юk*Њ*,йMЭ]ZўЦТркHДФJЃ™шНsыSлУЌЬЮP№K”Іg:’ ˜Еѕбжт}іЋEеёOГ2чob­—Gj_ЫАКЇ7V2Щ•эўL2ћ:ŒКkшїk…аЬ9ќїE"ёH<Џи …*>W,3›й^П§,`Н{ИЌБ!ЉѕЇ1њ8}хї{ИtчЄпу§L{р>О~!h"њс!œчr.€ћѕpЎћ§м'zИO/‡ŸыeЯеFIчž|†љ„є‰Ю§šr?шuюeх^№kо—_ˆN@њƒ#bEy%VFє†вв§љ Њѓ[1–щI_-ГJŽ[Р$€АkUѕ#,Gз{щњžB,7П4RYд}2R=…•КМ‘ЅэЕШѕэеьФF#ФХэ9РWЯАЊ?=GяспЦћєёы;ъYў^žы}UVЎїw$  зЁsџ>о7U?Мщ}G`РЇu`S>|9р*з Ÿп­ЌўМї­s••TVђkž{OBŸРЊзфUђКpЎkсIž[іы>Щ§мŸЃ~5&НЇSСjЭЙ€UuљЈHЌ/3Ђ€F‡‘#T_Q§zGи№3єœ`ыA.ЁqшЊњP:ќ9zO>fЯ§ћъzјћ„ЫК_‡њзў&>VЊИгИѓяы“ШвsM2/+Ÿч–е{nПзЏщ|ЇђлеСVй'яЪ~=œ;PнЪсіъ[я C@( SОв˜еŸЏЂBсВ#…0`Yы/fGОМцяяЯаsдЏ?Ke!ЕгиHјс~ѕ|Ojыуіў§šПŸЮUVђoЁмЫоЮл иџэ!€ћџ…5С<…'лneЕПгѕмkоїNЙORП>Я-ЋMnЮ•Тѕvќпжd9g№з}ŒЪPОR;€ XUЇЄ>8УЙЏЄžПуYСЗО…ŠДъ3їxЛi ъ+ќ ZoЃмЧюeхўОw*пщКкџHЄ=№wћ3kR†Sј<\і6;ељЕ№dѕ:х^яЙ_Ы=їњ{Щ5?8€zНњ : яДšъYЛУпWЙžЮ§š?Ч^чоЇчTї*Ї№ѕp§^љэ/А‡іІТn_@@ИгсїРТ€ЎїђНц№žчочРьyюѕНѓј{р>кр-Й@Љѓ\@Ь=џќLМW~пРћ=€оOЖ7тН/№Уѓў?€f”šў‚<žIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Images/fwbuilder3-128x128.png0000644000175000017500000006102111733011756023754 0ustar sylvestresylvestre‰PNG  IHDR€€У>aЫ pHYs.#.#xЅ?v OiCCPPhotoshop ICC profilexкSgTSщ=їоєBKˆ€”KoR RB‹€‘&*! Jˆ!ЁйQСEEШ ˆŽŽ€ŒQ, Š иф!ЂŽƒЃˆŠЪћс{ЃkжМїцЭўЕз>чЌѓГЯР –H3Q5€ ЉBрƒЧФЦсф.@ $pГd!s§#ј~<<+"РОxг РM›Р0‡џъB™\€„Рt‘8K€@zŽBІ@F€˜&S `ЫcbуP-`'цг€ј™{[”! ‘ eˆDh;ЌЯVŠEX0fKФ9и-0IWfHАЗРЮ В 0Qˆ…){`Ш##x„™FђW<ё+Ўч*x™В<Й$9E[-qWW.(ЮI+6aaš@.Тy™24рѓЬ ‘рƒѓ§xЮЎЮЮ6ŽЖ_-ъПџ"bbуўхЯЋp@сt~бў,/Г€;€mўЂ%юh^  uї‹fВ@Е щкWѓpј~<п5Аj>{‘-Ј]cіK'XtРтїђЛoСд(€hƒсЯwџя?§G %€fI’q^D$.TЪГ?ЧD *АAєС,РСмС ќ`6„B$ФТBB d€r`)Ќ‚B(†ЭА*`/д@4РQh†“p.ТUИ=pњažС(М AШa!кˆbŠX#Ž™…ј!СH‹$ ЩˆQ"K‘5H1RŠT UHђ=r9‡\FК‘;Ш2‚ќ†МG1”ВQ=д ЕCЙЈ7„FЂ аdt1š ›аrД=Œ6ЁчаЋhк>CЧ0Рш3Фl0.ЦУBБ8, “cЫБ"Ќ ЋЦАVЌЛ‰ѕcЯБwEР 6wB aAHXLXNиHЈ $4к 7 „QТ'"“ЈKД&КљФb21‡XH,#ж/{ˆCФ7$‰C2'ЙIБЄTввFвnR#щ,Љ›4H#“ЩкdkВ9”, +Ш…ффУф3фф!ђ[ b@qЄјSт(RЪjJхх4хe˜2AUЃšRнЈЁT5ZB­ЁЖRЏQ‡Ј4uš9ЭƒIKЅ­Ђ•гhhїiЏшtКн•N—аWвЫщGш—шєw †ƒЧˆg(›gwЏ˜LІг‹ЧT071ы˜ч™™oUX*Ж*|‘Ъ •J•&•*/TЉЊІЊоЊ UѓUЫTЉ^S}ЎFU3SуЉ д–ЋUЊPыSSgЉ;Ј‡ЊgЈoT?Є~Y§‰YУLУOCЄQ Б_уМЦ cГx,!k Ћ†u5Ф&БЭй|v*˘§Л‹=ЊЉЁ9C3J3WГRѓ”f?у˜qјœtN ч(Ї—ѓ~Šоя)т)І4LЙ1e\kЊ–—–XЋHЋQЋGыН6ЎэЇІНEЛYћAЧJ'\'GgЮчSйSнЇ ЇM=:ѕЎ.ЊkЅЁЛDwПnЇю˜žО^€žLoЇоyНчњ}/§T§mњЇѕG XГ $л Ю<Х5qo</ЧлёQC]У@CЅa•a—с„‘Йб<ЃеFFŒiЦ\у$уmЦmЦЃ&&!&KMъMюšRMЙІ)І;L;LЧЭЬЭЂЭж™5›=1з2ч›ч›з›пЗ`ZxZ,ЖЈЖИeIВфZІYюЖМn…Z9YЅXUZ]ГF­­%жЛ­ЛЇЇЙN“NЋžжgУАёЖЩЖЉЗАхилЎЖmЖ}agbgЗХЎУю“Н“}К}§= ‡йЋZ~sДr:V:оšЮœю?}Хє–щ/gXЯЯи3уЖЫ)ФiS›гGggЙsƒѓˆ‹‰K‚Ы.—>.›ЦнШНфJtѕq]сzвѕ›Г›ТэЈлЏю6юiю‡мŸЬ4Ÿ)žY3sаУШCрQхб? Ÿ•0kпЌ~OCOgЕч#/c/‘W­зАЗЅwЊїaя>і>rŸу>у<7о2оY_Ь7РЗШЗЫOУož_…пC#џdџzџбЇ€%g‰A[ћјz|!ПŽ?:лeіВйэAŒ ЙAA‚­‚хС­!hШь­!їч˜Ю‘Юi…P~шжаaцa‹У~ '…‡…W†?ŽpˆXб1—5wбмCsпDњD–Dо›g1O9Џ-J5*>Њ.j<к7К4К?Ц.fYЬеXXIlK9.*Ў6nlОпќэѓ‡тт у{˜/Ш]pyЁЮТє…ЇЉ.,:–@LˆN8”№A*ЈŒ%ђw%Ž yТТg"/б6бˆиC\*NђH*Mz’ь‘М5y$Х3Ѕ,хЙ„'ЉМL Lн›:žšv m2=:Н1ƒ’‘qBЊ!M“ЖgъgцfvЫЌe…ВўХn‹З/•ЩkГЌY- ЖBІшTZ(з*ВgeWfПЭ‰Ъ9–Ћž+ЭэЬГЪл7œяŸџэТс’ЖЅ†KW-XцНЌj9В‰ŠЎл—и(мxх‡oЪП™м”ДЉЋФЙdЯfвfщцо-ž[–Њ—ц—n йкД пVДэѕіEл/—Э(лЛƒЖCЙЃП<ИМeЇЩЮЭ;?TЄTєTњT6ювнЕaзјnбю{Мі4ьел[Мї§>ЩОлUUMеfеeћIћГї?Ў‰Њщј–ћm]­NmqэЧв§#ЖзЙдев=TRж+ыGЧОўяw- 6 UœЦт#pDyфщї пї :кvŒ{Ќсгvg/jBšђšF›Sšћ[b[КOЬ>бжъоzќGлœ499т?r§щќЇCЯdЯ&žўЂўЫЎ/~јеызЮб˜бЁ—ђ—“Пm|Ѕ§ъРыЏлЦТЦОЩx31^єVћэСwмwяЃпOф| (џhљБѕSаЇћ“““џ˜ѓќc3-л cHRMz%€ƒљџ€щu0ъ`:˜o’_ХFW?мщ7/DРVWMНy3н=Зя9ПОѓsИ №ЗџzтПљ7џцІzž№}kkk№<ЧmћНчy№}Ўы"xž‡ рћ>§Ž њОЏzžз 7‚~пїгRAФ‚ @b=Ap йЙЯuнКЊЊЫЊЊ>Р Ѕх8’$Сu]ИЎЫЎЧї}м­bѓ<ПэГН  Ы8v Ђ(B”$Œ €чydГИЎ A 8ŽЯѓŽуv§Œ‡уxр8@№УД!Š[Яw]žчC‘%шКzЃ~ЧЯ&ОCŸQ0С,€]Чэт8n€ižчгЧЩAШОяѓ<ЯЃ#x&$Rњž”ЯВ,ШВŒћяПпўР>pс№сУ?рyž)€$I8yђ$ўнПћwј[Kі6-РžрyЧЯѓьgЎыЦ|п?рŽуŽx@„ažч•Аpwњђ}ŸPњ7Ќ! 9rФyєбGѕббQХqœЩХХEŸ4šчyшКŽџјџ#ГP;(СсŽ%Yј[QПM†Іiaсќ=AўЉeYУеjUжuІiТqfЊшAю€LД P‚ l™BQЧqа4 Ђ(2с+Š‚ћюЛЯŸœœфkЕZЊP(@3,`EQ№ъЋЏЂ^ЏCQцЖшВќЏ>Р№ €oј€љПћ]*ЯѓˆХbP…§ŒуИ{UU”eГГГE1№}Ÿ3Mѕzйlеj†a ‰ ЏЏCCCˆХbˆFЃˆЧуLиAР4M€išhЗлeЎыbrrRИvэ8ŽЛЩё<jЕŠK—.A’ЄmОРпс8юз8Ž›Y—uОўyGўРїџVќwaЧmлpA€у8“nЌ $‰‹FЃШd2˜™™СбЃGСq,ЫBЕZEЉTB>ŸЧккšЭ& У€ ЫВ`кэ6ъѕ:Ње*šЭ&TUХяўюяЂбhАч†‚ рєщгШчѓ$ Ч Ђ(ц8юзAјXЗK ХБ žц8юЇƒ ј џ€+Ћwx‚Яѓ ы:)СЖ\ЋеАККк‰veH’„ћяПџфŸќЌЎЎ"‹ЁЏЏ}}}HЇгˆХb$i[lРqA@EŽу VЋэЈ№№Ууcћ‚ €mл}ЏМђЪЗ*•JoБXмv}A xRІрЇ‚ xР/v\Уп*@ч!qїПAР8рTЋВ,ыКЎЃйlкЗKlл†mл(‹ьЧуqhšY–!xžЯѓ№}Ÿ™xњЂШ0 TЋUц.ТR–BЁ@С ўЪ+ЏpГГØ™™СњњњŽf8гш| A№g> р‡яn*јU€Nи“‚ ќЁ›dAАСщx<ўКeYZ­УШBt+у8,Ш{;]зQЉT ЫђMПSЯ=ї^}ѕUD"pЈЊъ]Нz?ќ0&&&Эfбrює@ѓ<яŸA№1ŽуМwу&{ž‡d2ўжьЧЊšІuџь )гё}:‚iQjxxžчС4MшК]зQ(ЖЙлЖYpїv дыuдjЕ€В‰оо^f шFŸЂ(J|uuэv<ЯЃеjС4Mцž(m•eВ,#bll В,у‹_ќbЄX,;œoїaš&Ž> Q`yоЋ›‚@Qƒ7оxCr]7ђЬ3ЯННН‘\.'8ŽУД8ЌсаСƒёс_јТПBЕZ ЖфЩнёЄаы 5 ‚ЕZ ХbЂ(Тї}ˆЂ|ъSŸт&''5]з<ШqмОя(‰ь{ќёЧбh40??ЯRгpбˆ0 г4rЙ"‘ˆP.—yUUп1ѓьyІЇЇ1Л{–ЙЭї ( NŸ>­fГY<ѓЬ3оƒ>шеj5.—Ыq–eqatŽ лнЛwУЖM|э/џ ѓз0Л{п?<§>•JAЖЊa‰D‚ЛwяF,ƒЊЊHЅR‰™™™g]зaчypzŸL&ƒоо^шКЮЊ•ЖmУѓМ›L0›тё8dYцvBпnќ‰DpябУ[јI(–z_A‘HХbПџћП/МќђЫxъЉЇќ}ћіyЎыђљ|žЋVЋœу8E*•ФЫ?|пњц_С0кАmЭfЃŸпvъ=ЯC,УШШвщ4+‘ p]’$…1е4ЭuЌzwaЩї}ЈЊЪ D™L˜eŸвX,ЦВ*ЛўЈ~_QЬнsDIzЯŸў;"TАЙrх VWWљЙЙ9ўЁ‡ іэл‡ЩЩЩРЖmюЦѕЋј“?ўїX\\€Ђ(ьц7Э›ЂоNŒQ155…ссaPрvЛъ!)R=$“ы˜4MƒІiр8ІibccЭfѓ&NCЋеЧq,ƒјQРВlьо=ссЁŽђя(˜у8(ŠY–Q(№ќѓЯs—.]ТсУ‡Ё("О№ќK›оyЧЎЗ"†„6<<Œ ‘Hl“nuѓ $ы Š";БЂ("#<ЯsP.—БББѓчЯc~~ЅR Оя#“Щ@Uеm%чvЛЭH%?Њ №}§шяялRrIФћс!ОѓF ‹iš(KPА Ќ |Щd2№|ŸS…‘H’$сcћ>јС"Хгї”rњОžчйЉŒD",§Ѓ:хћFЅR чЮу–––0??JЅг4™Ѕ‘ey[жаm:РїvA+ђћ[qа.†>ўQ ъ6пžч1ЌпЖmD"кM7Эл:mœэH&“8с#E"Гц 8ŽУNЛmл№}эvІiЂбh \.#ŸЯЃVЋЁнnЃеjС0 †ђ…­У6@Іњ„ƒзVЋЧqж№v€вр‘‘afЉxџ/CК‘РАЧFрGvz6A@TVЖ§дq,--A’$†С~Я7плa)›iš Э sщ{ВсXЁћк)/7 c›дыuшКЮ‚ЪЗЊA№№С<‚fЋУ0!М„Gш6eaJ—яћnqSdIDD!ќm&WUUЦмм]ZMd9Шœ‡eЇчоюsљнЇЙЗЗ7ИїОуœЂhЖaшМЂ(‚Ђ(ЧqЯѓb8ЏЂBЮ‹gYkKы.=;ŽѓŸv2t­§}hЕл№}я]ЛvŽуbqlїq?žєІєPзѕ-ЫњъГЯ>ћ#НїO?§ж_ѓ•Пјџ4žчŸr]ї1ЫvžrgŒФб)nоЄpaЁ‹ЂˆhTC,Чm5ЫЎЌЌ \.CзuЬLOњЂ("№ƒЗyžїяMг<ЎЊъп _РN– S|с;Чyž— мнu]йqœ”ыК~‡ S—бKшєw`х ]зџСГЯ>ћ7™ўЮoџЫQAŸьщIVUѕ#НН=3Жы\ гВ`š,Ыо>{ЁœЩВŒX,Šx<Žкmѓѓ ЈVЋаu}MўnЌе­Впuнh†#ТчEЙkгзех#№aYі”яћBXљoхЯЉЧбггƒt:нщ(ayy{їю†c;X]]C4КеcљNX@œНхЭL&“H$$Щ<ўRbЙ\f>NnX1vтњ`Ь`Ть)4M333Шхrл\ EЦ; >$|јО“јЪWў\“Dси'OЦuнOЭЯЯы†гД <lбmЁТJЌi††1>>d2 г4БЖЖ†ГgЯ"ŸЯуSŸxb'€#Tђn„ўfPНu_4M…ІjˆЦbа4Х7с8ЇT*addфQпїЧ1ŸJЇ™Ёлw=‰+Щ†СZЖКŸіхнA§kYt]Чааа6ѓšYY–™аuR\вQh >ѓ™Oёџ”э8~ ПЏo*“NsO=ѕА, ­f ѕzЙ|…B хr †avЦ.8ˆХbСдд4bБ CЧвв2666ЖЫ’$A|‹)­JDa#vЂбшЖЁ[tњ#‘s%ЅR‰ЕйНеbаMс8N’N0њƒtгУЇƒN5 ЖP(`bbŠЂА^=š"Bh—mл;BЕс–/пїajЕQЋе!м8B§$ј0у8дыѕ§=іСo•Ы•уЖm'lлЦйГч˜ђhš†ўў>єїїa` 33г8rф$QDЉTFГеF!_„Ќ(H&“hЕZИvэ:љђА{К[є3ЯЈЊŠСжж7алл‹§ћїC–х…N.lUю†‚wGш'A‚Ђ“FЬ jЗІ›ю Ї@щtЩd’)@иПгs)Š'7ЖaИІiHЅRлzУVЃ; Ч#ЧЁбhЬ\П>?УqлГЋУжыullltt‹088ˆ={ц0>6†ЃGЂ<\ЦњГ/ЁT*ЁйlnkB +ннFяAрu9ёxЩdЩdЉT ЅR УУ#˜˜˜`Šб-єюxз8Р У Dпїуa4­ћtR'OјФ‘ж“BЄR)єєє0V™њp3H8№ыv#єE]8бwлfЇL‚рб7›MНЉрt][МП4ЦЧЧ111Y–QЉT№ЕЏџ\зiYИpсRЉ"‘{пЗZЙЎлhЩD=щ4‰bБ"‘‰‰dYЦШШXгlxижNЉё]зЊеъ.T&@Ѕ{ІяN7ИЛќ €Ѕd4Ž” <Ц…nліЖщЂдбCжЇ[ыo•f†KЯЄD Ѕ`”^O~*•Тшш(ЦЧЧ‰DP­VqђфIфr9ж]DнDфњюVрсkЅG===H&“ЬЇЋЊŠh4Šh4 Q‘H$`š&›Дf‹НКSe:ˆd У0o;A^XXшйииРфф$ У`fŽ^†3ЩфвџУ•)ъ[’n“MZН.nџЂяУЪ@œоЋŽ.—Ы8wюђљ>ЄR)МќђЫИvэ:„}ћіappѕсэ4F†jжаl6рћ[.AU5hб(ьЮр$R†pŽKуЯЛп“юК.TUeZž=H GРЕZ kkkШfГУ‰'№ьГЯbppЉTŠ”ЙpсъѕњЖ–32яoUшdНTUE_o/њ AТЁC‡P(Аkз.цвHшд9>еa ŽiшДgГY\П~йl‘H{іьу8јєЇ?}g(‹wќ0‘H„{ф‘GpєшQ\О|ЏПў:Юœ9ƒЩЩIькЕ SSSeC˜”Ё‰оеJПіOџXІ€GІЗњ№H&“нg[&@7žrxžчYіЁЊъ›LЧа”АVЋ…Z­†fГ лЖбзз‡Я|ц3HЇгиммD,ЖUƒП~§:t]g+tђоj@іщВ,ЃПП[J–LnЫйщP Cзѕm)3НWин†­uН^Чњњ:жжж`л6ІЇЇqьи1єііТu]œ:uŠнŸл*РнАt}пчWVV0<<ŒŸј‰Ÿ€(Š(—ЫШfГX[[C.—ыЄN§C4eСЬЩ“Џ!глƒ_јХ_dTьЫ—.т‹ќу;пўўёџ?aff|ид‡…NYš+\,QЏзйP)ђ‘‘HуууУеЋW144„ЁЁ!lllРѓШВзѕоjЕАООŽХХE”Ыe9r—.]КГмЎfм9I‰ЋWЏЂ^ЏушбЃˆХbhЕZ`Р‹$Ilп‰ŒЫЮѓpм-z3=пЖэ­>;р8Р|&tQй.@Ъыi(UиœSк(Ы2Z­dYf–€ŠJЎРZ­Nž<‰FЃžžјОЉЉ)LMMapp§§§h4›HЅRƒыКЌЊІ]гЄ“pЅ’f†-‘$I,s*‹№<CCC8vьњћћсК. …666иgWпљЮw0==‰Ÿј‰'№Ѕ/§*• ›l‘E8ŽxЂЗЅь‹‹‹Иrх JЅіяпG}+++ј™Ÿљ™;+@4Ньž8q xх•WЯч188Žу088ˆd2ЩFЖЅгщmОдї<цїMУ€икVрhМi’y!Lж@Лн†(ŠPU•™OBНlлfпS€N?H№Є˜Жmу7о€eYФƒ>ЌЌЌј›ТШш(ўшш(zzzH$аззг4ЗMњ&ы†ЙУ™H$ТЦдцr9фѓy”ЫeЄгiьнЛЃЃЃLa—––˜Л[Сx№66ВимиЯѓ[СoЛ -"AD†ызр>z{{Б{їnœ>}=єs41§Ж аYЩvлч сбG…aX\\Фњњ:ŠХ"бггƒССALOOo+ЩВl S2 ЃуˆЂR<ŠЖ ; ERбh<Я#2 )=tгУ“FЉ`SЉTи0EQ022‚щщiŒQzХkРЊЏЏfШэPс‹O 4ЩB„ЕZ чЮC.—ƒ(Š0MŸ§ьg‘H$`жззсК.УТЬ R6:Ђ$ЂнnCзu№<ПEPiЕJDŽƒeлшыяУБcЧ‰DP.—СqšЭцŽШс-…{Ќбї}lnnbtt=іЧСЅK—RЏзБЙЙ‰ўў~ЄгiЌ­­mŠ‹F˜š‚ѕFКОй{ЎЫщт–yІ2(нtг4100Q‘Ых€BVAзuжG[Чh ЊЊЧСƒFйы666G)T8Њ)Ј:I.…`А4Mc&Оеjс…^Рљѓч166†'žx===јЦ7ОСFэіїїS/"; щt†aА˜хЭ 5ЎуЂнжСѓo.сА­ћ–щЭ 7# T*AEДZ-цŽ›Э&Тю(\:™З$–ou2рЅX,ВU-ггг8qтЪх2г<Тр5UCЋнРФф~ічžйђƒЅŒЖлveЫѓ|˜†‰l6‹ССAИЎЫЦЗ‚€+WЎ ‰ ›Эn[UCi(љFUUqрР lЯѓЬP0ий3Р8–emу0а@‰zНЮš0Т…ЯѓАДД„ЋWЏЂT*attŸњдЇ033У2™••†@&“Iдыu6™дЖэmLrWДdƒчx€lЧFЛн mBбсКИŽKрАх:›Э&KУщoо5p;FPчFЈсSGMг:Ј˜Mг088ШЖqp‡ZНIЁыmdњdњњ1зщ­EЖž31}$YFГйd7…|9™>Яѓ033УСžžeЇгiМђЪ+e“““lгˆЎыŒ‚FС•eY,ЕЄз=}œ‚Kr)Фi4 •JWЎ\СккEС§їпgžy<Яccc—.]B<g€ЅЧ•Je[і@АJЅMгњ™H$P(АЖО†™]Spl‡ХCІiЂбм‚ШЙнjЕXЁT*Бд—LџнPўХл­2щPТћi0Ѕ9’$БЩ›фЃ ˆ hYD:&]…moэ. l.ЯsX]]Уg>ѓSшыыeкMшy У`AІ,ЫьD1дВ,ЌЏЏЃZ­bjjj›u сw@TcфwЩ/г=Qэv—.]ТљѓчQ.—qша!<§єгиГgЎ^НŠ_џѕпРЫ/џ@€d*…Я~ц3ИџўcLб-ЫBЉTB:†išH&“E‘q IБЖЫall šЊ`;6&xžCјРишШ–ъ(1ШtџlлЦъъ*4MУ‹/ОјЃ!S‘ЄРŽ мЎУ‡OАІi2…ФVГ А`Чu]ЄR=иЕkLгd>ŸЂh`kп­ž)—ЫˆD",$Ѕ$0Ъ4MцgУ‘9eaГHJA ™eњ|ІiтТ… xљх—‘Эf144„{яНЏНі~с~еjПњЋПŠЏ~ѕЋx№ј1ќϐۘœœ‚$‰X]]gŒмpМаh4˜ѕЄйЧЙ\ŽЕлэоН###[жЏѓљ]з…$Š˜˜ХФФ<€ƒ‡"ЂF‘Ы1<4ТвпVЋ…zНŽo}ы[{іьщ ы ~$ HЮчѓгA “ЩА€‰ в№Œ]фcIYxžgц‘NњЫ/ПŒУ‡3tжЪЄIBЇh?ќ \œъїЄpєђБ#—-3хг4 ‰D‚m.ЋT*(‹eЃЃЃ˜ššB*•bƒА+• Z­&l+ƒнГЛ№s?їS8p`?†† Ы rйVзrЊЊЈVЋX^^FЉTТддvяо\Лv <№РлoэœnЁZ­ЊчЯŸGЅRС§їпD"СJЎDœ f 2aњTи/ЩВЬNzxBЗ(nхЕ1гк—x<Ю,ЁzD)'^ЅTќ)o!n}}—/_Цњњ:ццц˜›xѕеWБЖЖЫВpј№a<§єг˜žžfS@Љў.ўєOџЇNФПџ€ZЕ/}щЫ,ѕдлMЬхQЃ0 “…B­V љ|НННИїо{144„ P(P(˜ ˆFЃ˜›лƒˆ*avї,в™ ZЭ6цч—aвщ4vЭьB­VУыЏПŽ 0>>ŽуЧГЙT*ик№#eОя{===ц'?љIœ>}Я?џ<Ў^НŠC‡ЁеjБ†BяˆќI{†ЉЃ‡L№+fT8",<інї}Fи Œ€ќ\xЅ EжžчБXЎУЖmДZ-dГYмИqыыыС'?љI4 <џќѓАmcccxф‘G№аC!“ЩРЖmцzТмМbБˆЏ~ѕЋјЅ_њ‡№§Я=ї]ГЛP,qхЪ4 vэšІ1 Fї€”€I U>ŸGOOFFF077ЧшpKKKŒbF™‘$I[ѕ‚ЎИ‰p‘Vун6 ‚€“eYІАйlТ4ЭŽŸšcЇN:љfТР‹Х"cХ„‡IMkЯž=X__gcN‚ Рњњ:; [лЧЖ@ŽfГЩрP&!xФЋяыыcŒI’…ŒˆЁсАг!I’Щd(Дг„ѓp?5išІEƒА:йKЖз vыѕ:–——™ђ$“IкTЪ\ БH‰Ш} ЖXk||‚ рѕз_GН^G.—c`еU( яV Њ*YжzНŽЏ}эk7СзЗЏЊЊ@ Ыd2‰l6 MгаззЧЬNИЁ!мюUЏзЗoDQd'UE‹E4›MЈЊЪЈPduZ­4MYЊh4ŠSЇNсиБcшыыc–‚ [bеPi:мТia7/”‘‚зp?]збnЗYьЁы\wKэЮжRЊJвM'l}}!–ёвюžžFЙЇЮъZ­ЦЬ<6:P4,‘HАt˜OИeYјэпўmМњъЋ7Л€юєЊЋЬЙЎ+JHA™”Z5›M’i#єM|х+_СЧ?ўqЖаВЖЂY‚@ …УЏA@Н^gmPДšLЃыКXZZТммS"Zдыu c…zТНŠсчtЏ  s DQDГйФќќ<+ї`šГЖmУ0Ж n€ъt"М„н­Kїb”‘‘–V*\ЛvmЧЎЂpП5щ„ЛVЋaqqФwПћ]œ:u ЫЫЫX]]н9ЈзыЗ+ЋЊЊJtЃ’Щ$SBшhQ#eЁщ›лВ!}ФdЅр12@CQ‹EVк s)k4Ќ—Ш"tcЩ…{УЭЊaА(<ќ№УиП?‹K;Ї“”йGoccиПo/кёёIдM,/Ў!‘LВЪf.—C$СбЃG166пїqљђe6N'ГJ%AРš…;†ШКбТ ъ‚њшG?ŠX,†FЃЕЅuфэ5|wѓ/џ*:-ьi/zWоV- еO|ы[пт?єЁ1ГCЄCти…i`„KwGає{К`2БЕZХaоukЕZ,n 0†В€0кG>Њ”4ž .dъ‰шБББххeDЃQ”J%œ>}ŠЂршбЃјєЇ?vЃ‹Х"ћ;[Ќ] ’$т3?љ d2LЯL#–H V­уЬ™ №М У‰XСкк*z{{qьи1ŒЁнn#ŸЯГƒ”L&бnЗNAёЙ‹0ЉеЖm,//cqqšІсаЁCH&“xўљч!IVVVр™.7NулЦŸТŠшON==T?Э§Š^3rVЩ+ЖцН›ІЂŠ333Зƒ‚лŽур+_љ ‚ Р#<ТІo…oz˜]жи0— NJс(А‹D"ьдRъжггУPAMгXУ&Y‹ЮьBVjЗльдƒ†Ў%2…)—ЫИqу …vяоl6‹sчЮсРч>ї9$ шКŽЭЭЭmС")[$СЁC‡!ˆ">№иQ­жБКšEЉt‘}юvЛfГнЛwcяоНЌФ{іьY$“Iї„[о(eЃ;4Ъ–Њеj'а4№шЃ2ЋT(оŒ_l RЏс”№}Ш ‡ч>KoŒЎЯ\џѓZЅтu'{§ЋOыСЙm p;Дˆчyїјёу˜žžЦыЏПŽ^xЋЋЋ8x№ ццц066ЦЬV7;ЖлчSmЇš2ІiВ}šІСВ,$ иЖBЁРJя('%ЄekNС‚бjЕŠl6‹ххe”Ыe ууџ8ыХЇRm­VC>ŸgщYВp<Чё‘|/Н№ .\Иˆ'N —ЫГвu*•ТёуЧ177ЧJж+++ЬЩђжЄŠ7ШЧ“EЄX‹ЌmЋе‚$I˜˜˜Ршш(|пGЁPРњњ:Щ|‹PsЃvgЭсдбDбгЇЂВaТkЛНˆ ЇДбб9ПyуšŸ†чЎbЯѓЂ­V УУУxњщЇБООŽгЇOулпў6Оџ§яcffЛvэТфф$FFFЩd˜й‡ QпiwxbсšІaccƒхЏѕzЕ†еыuєїї#›Э"•Jm‹–)ЈVЋЌРВЙЙ‰ѕѕuжHљф“O"•JСu]цJЈЋ‰0RrgсВГ(Šшээe$жЭЭMT*$ <ќ№У8pрЧСхЫ—aYc АndMгиl#Тџ#‘УKg‹?™H$p№рAЄгiДZ-ЌЎЎВо Т|п‡яњX)/т/kПз„каŠGP­—бvки5„ъzZ"†ђJm@Ћ‰Зы ‚@%Кs˜››УСƒбnЗБККŠххeмИq‹‹‹ˆЧуФШШвщ4zzz‹ХXŒ‹ХаггƒrЅЙЃщфJbБVФ tžCcU‰;пnЗБООЮИКЎЃVЋБ›+Iqьи1\Иp§§§иН{7жжжXtžЊMеJ‚SУИЭёm4X]]Хцц&›$ђЬ3ЯрЕз^ƒeY˜ŸŸgюB’$Vw š•Ћ5MCЋеbA*•‚)њЧєє4ƒ‘)Г V„q8ŽНj аyєїŽc`hхlЅ|з—!ЩЦvЃВ^FЂ7Љеm;}яЈє‡Љ*G@ЦбЃGqьи1†ŠQ^N$‡jЕЪ:cЇЇЇ№Эo|†ЁУѓ|Фт ЬЮюF<ž`PВЂ(иммФаа4MУввƒMгdН‡ЭfйlѓѓѓьDyž‡L&ƒ]Лv!NГ›LОџъеЋьФPЯ<Б”’5O3 ЋoМёВй,њћћёшЃbпО}№}Хbйl{іьСрр …ЫŠ"‘Ђб(rЙcAЯЯЯcxxžчЁT*assбhЛwяЦФФЎ^Н EQАММŒbБИ­й„Uрpžор9>Ъэ"zFbаЂ<ЮПњ*T-ŠБЉ1Hš„™}ГЈoЖАx~‰оXJNђQЛтп]kЧqліда)!JбБЊЊшяяGxщЅ—pтФ‰­Чq1Пpэv CУ№М­>ПЅЅ%|уы_ХСУїсСуГˆЛ^Џ##ŸЯ3"e­VC<G?‹ћћћo“FСTЛн†eYЌnаQS0Ъ@ NёxŽурЪ•+ИvэLгФž={№Ь3Я`ppІibyyy[wЁp–e1аŒј|ƒƒƒЈT*pУУУЌN"Ы2>ŒL&]зБИИˆ\.‡d2ййMЈnЃГA€РšFW3p kњ‹ЇQЊф-kа*јXЙОЎМv …•"дX>яХЂв}vХКqЧљІбIђ<U—шдаMЅш3б[&рјЙ\ЇNƒ(JТСCїтшНїтїО№ЏHФёё'?Й-ЋˆЧушээeEН{їЂT*1кVјъѕњ6ZWŒ"ЎB8CЁIE“№яEAЃбРйГgБММŒx<ŽћяП„ЊЊpЫЫЫ,ƒ!І];Х24ГбhАXЃеjЁПП?ў8тё8jЕЎ_ПЮмe0Д5Џ­FЕz UћЌJ—aMШIьc@…ЩЕ‘юЯ "I0књ†&Бvх*в§1ˆ’ Нepbїј3ІЗbt‚Ÿ˜чyˆЧу,( ŸІюQёс6lЂˆЏ­ЎрХ^ъšp ŸўЩЇ№Г?ї9ќщџїЬэУЬЬ Z­тё8cаPeCT“'6-|"Є†GХ…7ƒuO #„‘fee 0M“““јьg?‹‰‰ X–…jЕŠRЉФмхыoюLtУ,jЖдAUUдj5жю=;;‹™™$“I\П~™ћ0НЎћОвЯ\лE-зФыЭчQ^ХDbЃЮbuс"В ЋАЭ:МР…iдс›2в™^$2zz{ рZDCiАњQˆш…‹вmGФtLŒptђЇсSг=њl{<ССqmT+•лЮ@ ŸЫabbb Ц MУ"CДtŠшћ0Ђv˜^пНЙŒЊqgЯžEБXФ‘#G055…={і0n?) a№с9}сє–jнšАљББ1X–ХвQVр0C™ж4MД[:ŠѕЎДN#7x™TёЈ„LK\(rОРmћ№ŒЂcН$…\–mCŠ№Ш  ]o#=–˜XC5 tрVCЂ:дЂaЪХУ§wФѓ§ТЭрWЯƒгiђмq>@GЭV“ЅŽФkЃ‰‘“bRHЅцx<ЮZТRƒ8є|КЖАЉЅЖБƒтСD"‘`гУšО Зr…\вћ™І‰љљy†ССAШВŒ'Ÿ|ЅR чЮлV# ФЛКїІin`ЎYVА žЧљоя!&E4ЂHФ9ll,ЃgМя@–4”s%Р P+W‘ш‰Ѓ]iТn™и{џ~,^Dја2 9в_ߘ›ўэ›C%I’Ў_П>^­Vё№Уo#FаM!LН{x$Чq@РGžУ­чЕёпœЅG Dо гO, ВТХrі›™RвыУЕ}xэЕзАДД„нЛw#‹!ŸЯ3l@г4цƒУ№4™fВdc+Š‚—_~бhSSS8zє(<ЯУ /М€zНŽ7nАљ„ tї4†•luu•еў{{{Сљєy ЪˆŠ™ЙУАtmгA1З‚ъFУSƒМ(Ђm4!Щі>Аg^x‰t‹qуд:†wѕ ’e)Щ ™›€H; €оєПўыПFЁPРO<={і0 їџпjЋРі‘-dвУб/ a Т#љ`*эRTO1љц№аpЛv.—У+ЏМ‚\.‡уЧуфЩ“lБtxШe˜Y*У0P,БЙЙ‰H$‚{яНћіэЌЌЌАED†UU• ЖшЎ~жB8A__‰—]ЯС’п5ŒТц"ђЋEьНїZ53CœХЫ_y,ŒЭMbpї0 У‚Ђ*PуQБ#}ˆ( е:—˜Tяm^i}Ф\.w+РЅR)ўщЇŸЦ‹/Оˆ?ќУ?Фмм{ь1ЬЬЬ ‹mƒщTnГиZ€xЫљСжГv”Дг м0FЇ3Lу"ЅВІї"ОџЙsч066†Яўѓ,Г ї _љdŠ7ˆ bЎ]Л†bБˆўў~<ђШ#˜žžFЋеТТТУ5КЩЎ4Iо“Ў›f%“IŒŽŽВžФХХEДš-(š‚ГюpЭ9 ѓ&fїяТўћahf WРё<ЮНtМ$z2(lцPЌфIШ‡у{№J\A,‘@9[CъžШЯхОпўWž”nЧ›Эf\Q|њгŸFН^Ч_џѕ_уџ№бппЃGВz@OO3ilˆЯšиn9!Ў@W§>ЌHс›Ff?< "Œ­FnrЙVWW1??FЃббQ|юsŸУ№№0ыЮЁзэДрŠ”ŒFоoll VЋaffŸњдЇ000€fГ‰‹/В5$‡З „Ї‚бпІд4q•˜ПЄШŽэЂhфpКѕ]ŒЭM@UФ{%Э6.Мќ:ЦFG Ъ ”ˆ†ZЎQфQ[l UЖАыўiДЪu(1}У И†‚ /^< |ФŒrЛл7‚в-›Cƒ hэv›››Ч/§в/ЁP(рњѕыИxё".\И€d2‰ёёqЬЮЮb``€Uўоь9фn= ъP”о=o˜ъіt*У) aч”nхr9lnn2—AдяЩЩIєїїoM.эЬж 7„ œIмИqЋЋЋ‚ЉT ?ѓ3?MгX­R?2яєh˜eбћwhh§§§№<QлТШqиІl{ VЃ…ѕ3W %cиœСд єїCMКpE œрc|nљЅ ДИŠx4†ък:інџx>“ЯŸСъхDт†ІЁыm^Ž Лл№_o5MВgF(в­зыЌї'ђ'‰DаjЕ№рƒb}}йl–Uг~№ƒ •ъAЊ'žу099Жу|€А ЁxDх2 ƒQЅh6ЁišЈеjЈT*(•JЌ7žjГГГD:F:f•ЕJЅТn0?с§Єl­V gЯžХњњ:вщ4}єQ слпў6,ЫТттт6ЗGЇ?\8Ђю`г4Y‡ŽЊЊ˜˜˜@oo/K3ЉБeЇeлrP3ŠHІz №<8ŽG2‘СхЋW CФр§)Шб(Z-з_YТтЅyD" ік‡д№ДX–@o6127€Щ§3(­зАqНм0 ў2N\__Пеж ittTЃ\•N[ЋеbKFFFpп}їaпО}ЬєRП%LуS“јйŸћY ”J[EЧЖЁD"P;ЇzaaбЮpˆ0Ѓ—hнЏНікЖ=К49ЄЏЏћїяЧЕkзH$pтФ fv[fn>Ÿg‚ЁŠtRЛGЯWЋUфr9ќйŸ§ЦЦЦ№йЯ~ЃЃЃl 7ЁФpЧ tЪЉшcš&Z­ЮŸ?ЯІˆбЦЕХХEV`ыNŸщ}Чщш(‹›а’@o2 ЯъоnсЩ_xW^;ЩaxŽŠОќ XF уїŒ@ф$шuМр!3’BЃоТЁяC-WУЦ|+WVQ}йў-cнПу Ш вЊЊўПЧЅШ—QšЊPзыuН*ŠТђwтъ-.-РЕ}ФтILЭЬ0ОЯёЈV+Hїіcзь,іяпЯ|њNЫ)эЂ.LRQ…†.mnnnуј„M?Ѓд•„nY*• ыO8qтxрЄгiЖкLrx‡сєА…VЋлЖ100€щщ­]B Аm›‘]ЃбшЖAсўGFWxєЕ&0ПЖ]№aы5Д+:ЎНxc{ЇРsь …ƒО­jѕB nй†ж#Ђžmсњы6 ыE4›z†3Ђ ьюѕ+ўŸn!/ю0ЈXŠХb‰D> K'б†ЫЈaZ5!p”v РїlnnЂ\ЎvnЮ–пммФ>ј!ЬЭЭБ™Лt=4ƒxдиAn ŒћS˜‚ј‰wxž‡X,†fГЩ"q (ЩD?~=і’‰$LгТЕЋзр>SЂ0у9<ўоŸ ZA`ll 333lvЯцц&t]G:f-ё#ТЈ&)†alkяt9ЏОњъ_}ѕе/ЏЎЎО з–йСг"n…jнo.ЕŸ“э~ЇсчМ–дД:ТхH€зЖгљзрпr\<ЯѓBН^?B­[ЖmЃT*a``€aтa7~ИЙ2\)МUŠ6пaх Л‚p+=К(˜І‰vЛL&ƒrЙМmкИaЌо[oы—.^ТыoМE‰`ђ№(PрсњэSPpз КАPЦBь‡ЈО>{GЃйФцZюн‡yх4Њмд|ЭZ Ў`AšPн8dQя&с“щ'Eo4жЙsч~№кkЏ}9ŸЯП  Мtn2Чq. @@еmћыnAЧ[ч[xskxњКs_Чqƒ­Vkіњѕы8rфFGG‘Яч‘Ых ы:†‡‡ЗMР oњ 3tУ“ЖК9З[3ЦпIHа”)Їп“y7 ƒm07ejHiYЎ”Хjn›љ Db њ‹@x  Лт!аbh6uДлр}nЂ†ь‘“А§Є!жЋт ^Уfb+жeLЩ‡ J1,6ЮЁlm"cс ѕ’r>Мmфъ-(‹њХ‹ПwњєщПЈT*ЏwJГdžН Ы„AрА8Žs:Я#”Эя(J7œынѕкИ.NрAт+++РддЊе*ŠХ"цччй\ђeсн=Ÿ?М§+м|I ЯNAfxQtИcˆИђєкfГЩ эv›Э *—ЫŒNMЪеnЗББЖЅЪ ”Ѕ,јОџ@@*ЅТзlФciD$•к&šy=Б4ж*ЋAЛж€ж…ѕчзО }5€Г0Ќ B”8Hs&JЅLЃ еSаŠфёbс/pЄ§єjƒИ7­]БXl}ѓ›п|юЬ™3_i6›Ї;ьм63ї.WјЁпyђУнNщ*Т$M][[CЛнЦ=їмƒ‰‰ єїї3фэфЩ“lонтт""‘[*н †Ѓцp!'мЖM­д4ў=Œ9P†@M4Е3œƒ&@˜DxiTЕZEЙT†Ўр7‘>ю#&Ч!КрUО`mc’ 'ЎA–9№œƒёБ1$Д­šzЋЖ5swbї0мq+W–QЬWЁ ‚ў!@Ђ›D#[EВ/ЫsX-_C‚ы$ХbБ~іьйя\П~§ЋэvћL'ПkСП›БkІўЁ№і.]зqщв%T*LOOcxxуууЌ[хфЩ“ЈеjЌnнзз‡x<Žёёqж#@н?;­_! |xc(e"4Œ’Р%Ђ^“"p‡ўў~\Мx—.]кж#Џ( FGС 8(ž8Ьlxp>рњRЉ“\ЯСfn У}HХRX[\@Ож‚$‰юEamОaРiј№‹ Ъ›:дL —`ъ:Ђ="&їŒЃQla`fvбФЦцFхвЕ пО|љђГЖmŸ оњq ~Ї@сp8‡'kP­VqљђeфѓyŒŒŒ`ppУУУ IЋзы(‹X]]eа-EуД2–€ˆШDзj5ЌЌЌАŽcЪџiІ>ATЏзыаuс д жзз‡……(Š‚mу^Ze›C—Є ИzvЇмkЛ&Ъх!Šсоь™й‡jЙˆЅљreЬLOƒDM"/ šЏЃД``xh/bb љьъ•"d!Šбй)4+&ЎПБŒёУШ7~№хГПцxЮЉŽрѕЮ‰ї№zˆЁ“9ТqмtwъF戆fГY4›M$“IЄгid2ЬЬЬррСƒЌЕЩ0Œm&˜цф†ЧДиЖЩЩI|§ы_Ч7X f…>‡ЧГЫВЬ–GGЃQЦ"z№Сa™Jх­!PХbѕЪV ЗДЗ„„Р#\ЎСS ј<,з@>_…kћЖ`sЕ…dД†Ё>мИвЦьўYМќЕ№ЁЯ‡Ї[ˆФ“ˆ ьХх3‘‰bёь"LЫФРl?|–щјЮkВh§ЎГ‹рyўЧq‘юfн[Ј(А ЏwЋеjа45BhšЦJФДс‹ ф№ŽрnТi8 Я 3eЩ%PЯ@ЅRСцц&JЅJЅк6ЬЖ.рё]Gk(jp–hCЦЧa‹6JХ2D(˜юУтвЋI"JQ-‚B6ЄкСщQœњсYDжЏЏ"Љѕ`ўy$UHВ(!–JA•Lˆ2р˜”ДtOrМЇ~й^Ф{ј!^Нz<Яcїюн‡ТФФnHwЇŸ…ыщ4Ю…„•'ЬЯ#вqўЉ‹&<Ц…puRТ№ЉћˆhVTі<žыУ—pїеСU%Kќ˜…рў*lзCћК…ўб z'4Xѕlп‡щИ†!AoкPг.l XZ]РЬь$QФвђ Іћ16а‡y ѕІm@‚4ЂAw-ј<‡vЙ%*`№`?‚€CГиЧWфј.щcѕЫі_НЇ Фш=|З/ъциw/v žоМ^ OЇ?Œђ…SС№*љ0BHAЄ,Ы№\–oСKкіЕЁФ†Œh†v)ŽхзЪ3 Юч рš"cзD‹‹KИrёкvгFO:…™Љ~Е <™ЧНэУЩo…$(h– D"*’2ЬVЕЭ6тi О)ї4ВЎœ<ЯuьWЁєѓї€G>ЬїЌtL{ŠчљУw{ђяЄ;§,<Ь!lAТЬœ№ЪјpЩ5ќoїž№нЖj@~DЧаФ8• ЊЭ""š€с‰,Њ!НW‚ї!CCЅX„эљšC`0ЄЂ)И^€fеF"E<$тНШ.ЖББX‡х1y4‰Ь`Ьj zЉ ЧlЂnй+uT7]ЌПі†їf0wќ6ЫXЮ­%9žS?xЯ*п™ЪНG’Є‘;M–ю^Ј|7 –wBќощ‡чy№с€ыuа74€Йƒћ G$№Žб3@4ЂЁ'–„,ѓP•\нЦЅзЯCьš…"Кœ6$С€Ре!Щ \;РбЧFВO/ѓ0Z.6 № BL…šŒЃ]sэ‹"’рАџб}˜88•Ћ9м8ЙъhќAрњ{крeYОчyщvГКн­сШН[ия–р™Ћё]ˆУ'Q-•Q+Uё№cРђќ"Рё5В b`hmГ\6 QŽ`|ržэРЊU‘ŠH8tрШеRљЭ*fЄQЬ^Ar fЙ­GƒЌH№|М ТЕђJбLeТu5x‚г2аМ`ўООрџч.џžU€ˆ,ЫGпŠџ/Ѕ2[Œтg"ПоФјє ’ЩЌЖ QPбЈ6 іˆѕЈ(мШТѓмwєA NтќK—Бxy ’dЂwИ—x Ђ(C”xBХЕjХєК‹є`ђk Я #З”‡еА‘HЧa6mDгъй66Ўl"VЕ жŸ7OћџЖSЄqоы љО/оЭІщ‚П,СMz—Nџ›>€6e•Эы˜о5ьвL—GІЏЕ\…Х +€"Gpсћѓ8m]Ррl?њЦR0Z-TЫ Д›:8СЦа=CX:Н ЯёJСs$КЦf ‘ˆŽXЃт€ ЂŒvХ„–Ž pВqНєZљKn_Pь(€џ^V@аjЕЮ„— н­мЩппŠ №Ž[рbЩ4‰ƒ027YхБreFUGuЅ…žО^dЦ2hж h5+Ј– ˆїFMІ E’ˆієBV€Ћ ЂIр АXByН…žЁ~єŽЦаЬШ^ЋСГЃa"šжэQс.МwС­тЅNйV/оЫ р7›ЭяUЋеоŽкЕг,н;eяњЩxќЈ…иСE@"–€чиШЏn@№yшM‘И†xJUm`ѕеE$” vяЛimx}Л?„cO|.ƒжКƒъЊ…ўБ1ДЫ&є†ŽЗАr~Єњ“X;еТшОqєOїcѓrэrЂЌ@HНЁН‡їСCш\]зDQмЋ(ЪPxч=7’$mcц†ћкiў^ї–ю0_ {–@їъеЗђюМqLЮPк!РoШ/цР ^@5пDnEG<ЎapА§Ciфп(blЯ.ьz`/8‡CDUPЩ­#;П‚Е‹Ы˜82Œќѕu(Šл№И€ ё0&’}"Г]ƒgйDбоJЋ8Ж пƒо^pПе1џњэˆя%№ЗVПбjЕЮATeVŽоhA‚ягэV€0Ы'\лЧРѕ`йј9щёbZ ’СЅQЫже4Ј1B›ƒНж€гАpшЉ{эIтТў!ъХl\ПŒzA‡ЌŠрpB€vЕл№аЗЋžчBыI@Џ8Ш]ЭЁžkB‰E`5(š€ЬDьЖзёQ?ч|Э.yЏ„ˆ—я  ‰AГнnŸjЗлЫ<ЯgdY ™N~З№УЃWwт О[ `›ŒhТ\c3#Gрё№]Cг#pLFЭФЦљ:bjНу=XЛД^Ж!ХD(щMEt0ьѕ<єŠ…Рц`V}ˆ Iхрš&кН3}АкmИŽ -ЁЂ&[w Hъљ&Њ—ГsЮшЪ7€ї‹ АикŽу,TЋеW›Эц‚чyŠ(Š}В,KtвЩ%„•`'›џ0њPЯѓ`›.ьž*аoBt}–ГИіУkU’*Т|дJMŒž†mиаЫ 8І)'№ˆ%П\€ ЅјђжIж ˜ЕJЫ-ˆ1 žУaхЕ*вГ1xŽЯВ!+ƒ oTрК>Ьšз,Н`|!pp [„ЮЦ{=њпI˜%ш˜ЏКeYзЪхђsЙмЕZ­рyЯѓ|L…&v„kнbИл7<џцВЎчРЌЙ0‚ЈЃв†лоšЅЃІTДЊьІ лВPЩWQЭщpvЫ†Ђ*p zЭ€’ж`4u№B€ЦZv“ƒмЋ‚зд–]єЮ&`4MHšŒРœЖЋщРЈ[аы&ЊЏ[ф”ƒчBЇпЦћфБгка c ЬN гp]w­^ЏПБККњтќќќ йlіjЁPЈtJЕQžч%R„pыTИИг-Мк­0;}žяяz.<+€Е!Рr,4Н2&žэ 8dЦ{с9.Ы‡š‰Ђн4>б2,>№|Tз›ЈЏ–сщд˜„дTžРqˆ2H*Q`6lXuбў(J7j0лԘˆжuяy§†їG6БХъ}_ј~–Снхs2€кљ7Цq\$ъээHЅRCуууЃщtzHQ”Є$I2> 2э$\Њ№…ІЛRHпЉЄSatMг4ZЭvЅiжыќTKЫм#E{4ХЕ}ЄЧ2р#Њљ*ъ%ЭEћХк)ћџсф@z(њїДД№ ž5ˆ#кЇЁ]j#94ѓЮZ5з2#9ЪK|&№Ё(izQ‡кЋ‚—€ЦFЫїмЫЭSюП<\А­–+яЃї6žЯwD€дQЙѓЅHI’д#BМЏЏЏ?‹ѕЪВм#BL„x,‹I’ЄH’ЄR§чy ‚jЇ ШtЧђ}Ÿ3MгpЧ2 CЗ,ЋщКnЫuнКу8eУ0 Žу4ƒ pƒ Р##їpуНGе‡гъA%&ЫыЏ–_ИF`r7ЊЬЏ6–:–-ЉNтПщ™Sў./`*9–р[EГY]hПnЌ_ѕн Р‰рј(7!ЦЙ}7pј‚gЙЈ‰]ѕжНZpЙ“ђ•Беœaу}ірозѓ!ЅBЪ!v§L YRaЋRЬK!wtJКгљВё&ЕЪэњїŒH‚CЏм‹))!*њВ{:№PPщœаvчu<‘“1-ѕрXŒ—uыС<<ф;ЯЅHžЎЅЭыb{ЛU№_›мb„ПџŸлс Ё›ш‡ўя‡ўЅяНаїд #ˆˆu„хtžgt„iwgH9ЅRxГгЦ =ЏЛл]з№О|pяёПџvnЌа$ hН;Єe|Wйж{? ѕ§ЄŸыП AОнЧџ?ѓLH1”@(IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Images/fwbuilder3-256x256-fade.png0000644000175000017500000011140711733011756024661 0ustar sylvestresylvestre‰PNG  IHDR\rЈfЮiCCPICC Profilexк“ЫkY‡Пъм  ДЏ^ —YH$”4">вIlЂБmЪD“ HЇњvw™›ъš[еqЩЦЅЮ0{ёБpсрТ…+н(|!ˆ{EмЈД‹ъtW№yV_§ЮЙПsЮ-.tкХ а) s~dœ\VNNMЫЯHБž.2tн0,ЦŠA љ&>>Сxиї§ќOЃЋКs`­„дћ’ ]шј д*“Sг 4>ˆs@кФњџ@z&цы@кŒ;C nЋмРD юnЕX‚NєV53 žгuЗ9Я@Зђ' uV…#MЖJХс@?XЏJjxшыzйл7 єЯЫfпDЬжF/9uФзљБ&Џѓgђ‡šž"ˆВЮ’8xdI?Qм_2`9ГЕАR{OWЧЦlщгеЁ|“™К3ќЉk.ŒХГЅю0…FссЃ№‘8фШвG€ЁFG…Тр2ћнJM!С’/ёy‰Суoъ($GШцYшm9HћЉ§Ц~l_ЖЏйЏ/fъ=эЬ‚9юЙ‹оQ@aZОЭlsІипЅЦ MХ\kЇ01ibКВ1гvr/МSчѓ[ЊDЇ>fP„Ьb№˜GЁ Q &К§шіњю™[ыкН‹›Чvп=ГьЎjпlЅZ[-џnз%Я+ёЇи$FХ€и{Ф^Б[ ‹БSŒЕNLруq…!ЄˆЦчrйџ[Њ%~kЄsЪWЦsЅ“ЫЪ‚Љ•=­OєщпŒЩЉiгtn„Аvk[ћр`жšХЖ„]oЁуA[ыЩРъKps›[7ѓMkЫК‘њ'ЊЇŒWЉFrГmo—ƒA •ѕнў^YдZЏRBiTЈЬМ*ѕ–ЗlŽ]КГаљЂбјАVќ_ўm4>]i4О\…Žчp[РМ§E?ІOфbKGDџџџ НЇ“ pHYs  šœtIMEлBˆТЂ IDATxкьНkЌeiZіЌћОŸsЊЊЋ/ž‹Л]уiА‡™ЁЦЦиШ F аФШЮFБ ƒqdйВ“ќ!ŠЂШ ­(?Аb"Mš(‘Є@3Э3Ь%t73=twUuUŸ:gпжѕћђcяwеГпѓ­Еї>—ЊSн{IЅЊ:зНзњолѓ>яѓzжZьЎнЕЛоž—ПЛЛkwН}ЏАэ“išО-nТK/НДg­НБС—~эЦ“Зњ§шt:;Ыx›\^[ №Ј8€—_~yР 1€ї-?ќ€ї,?іОхз`“вg‹ђhрЫЫј"€џюЦ/юРюzd3€Ыt}§ы_џVkэ{—§оЅ1?р]Їђ|žЗжр7љšхе№\шvЛŸ ^ЗлНЙ;^Лk—ly}упxŽŒќНоk­§РЖQњМРЭu?ЧZ пїбщtnŽFЃЏA№cЬЈпяяэJ€нЕЫZЎW^y%Аж~7ў3X­й(›ЂєбћL™BЇг)†Усзт8ОbŒљоЊЊЄ и]Лkчјњц7ПйUЦўнžчХлщ:ЃlrmŽd[Ї†!іііnЦqœcўjQєСНјт‹OјqŸ№ћ7nмШwЧyw]Кр›пќцc~tљчћБцЖJЙOkЈmпwквСї}ьээM{Н^hŒI џh4э_сЧ~yљЇЛќpрџ№[ўз7nМЙ+vзЅpGGGпR–х—ƒ ИРЏЊ*ЌЊjdŒAY–ЇFуЯл)A€ ZП6Š"ЛЗЗg=ЯѓѓЫЎ_Пўg2]~X†qUUeЧу1Іг)њ§>Кн.ЪВЌ1Žгр+”я№oќ{;“и9зѕїŸЗNОKз§у@ѓФ!АƒС)ўEQРsЧѓМЮэлЗg;“и9чuяоН=іиcŸ ‚рлŒ1гFфMвб^Џ‡8Ž‘ІЉг<ь рa9€m‘dвчд@ЌŒaAPмМyѓI;АsЭџюнЛпyхЪ•џ/ УыeYюoщЗq ab0д‚,ЫjУ{˜р"КЏНіZр#~jooo˜eђ<пё?m#ЮскЕkјњзПўфЮv`ЃЈrїюнП|ppp3I’WŠЂxWS4<ЋЇ. ‚ Рx<–ДїЁ€чх^§ѕС’Iљ1ЧbЧ‚ @ЏзCЏзCQШВь„pЩygЛkч6ОЪВФ;wžиппЧp8Мk­эчyоY—Ÿ&K‚I’Рї§кД8ЧУЎУ7НnоМЙ‡U5фя^їГEнШZ‹,Ыpяо=ŒFЃнЉн]ЯШ!=<вЯ—оџ[M„ew=B€ЏЂ(p||ŒёxŒnЗ+Р^,ЮРZыЧcnthЯ њО$INlк&ѕ>ЫМУiW’ЫЧ…Р#Ц/ЂЉгщД–0—Вр4€ЗЋvрЌx@Sэ+§ьщtŠ0 БПП[Зna>ŸŸцїlэ’$q. 9-?сЂВNщYо\~FUU˜ЯчЕКоyАKхwзCs|P]‡Ÿ7яpъмw Eб‰с˜гыyf ђuВћ Aсћ~,F,,H‘F—Х'ч…#Аƒо98ї‹?зПOс`2Щ&Џлї}єћ§•€gх'lыє’щ4Шџ%U_ўl/ЫВx6›едчu+бЮђwзю: d]+щ<"M’$‰ нRГAё||ЏзУ`0аFВZ<ълМi#—Й|cЬŠQЛкŠъ1м,Ы ЫPyшщ<Œј eЭи9€гЇ§z36њ6ЉЊM.пїkjЌ‰M_чyЊЊo%cm3”MF­Е/ЉЙsRЏЫОНЋ$:oьхДќ…Иsчz]eРYГ€MЉ1Іn)Вж Ж^SюТ+кVГ FлїŽ Љю_J˜џњюN­§GЌЕП`­§pY–УљЛљљО8ŽыхЏѓљEQ ŠЂъТ@ЇгСч?џyyQПр#žчХЇ}3kЎŽЕЖ жг_nКыyо”&џЂяћбІ‡ў2_ХVміН[k_№kђ'ђЖ6њызЏџДЕіяZkПГ,Ышa‰ jЃЯѓГйьТH[с‡фEЯѓўЙЕіŸ<Р;№TУNРЉЕі6€€‰чyoјОрyоmЯѓ\ѕ<я}—=2?ш2РЕ›СѓЩљ|ўЖS}ъЉЇтВ,?i­§1я­ЊЪ˜F/moйјЌў"l.мђ0§Wžч}ЕіћЮњ‚ЮсЭє=Я{ZВшќыюТ \u6њОWUѕkѓљќwпFFРGќ8€яУpРл ф ]•œЙa"ŽcXk‘ч9ЦуёFЫ_ІШќ˜чyџ€ї]–CНЛNwЯŒ1џf>Ÿџт[§=?іиcЯYkРwEёЄœфѕnМыQу#т$нv>Š"$IRЏŠ;::zЈМ‹№шРG|кZћОmС:зз^T9Бsю{ВМ/џ Рп{ §c~f тЕ*ёўH—cpЕЈй)Д9ё’$AY–ШВ ‡‡‡+ЬЬ‡y…Ї–Q+ЫВ,{DўocўЁЕіУyžя?Œз Ѕ@†H’A Ы2ЬfГz§ССС#woЯmиS…axXUеЛђЧН{їо’F‘ ЋIR0ЛJ>яˆRoЋˆя2іЖџ7‰ЈИю#џ›ўПрюУ|ЯЯcў1ц{Чуёе мЫqрgр:ШMРс[Ѕ~o2|M]u}SFХNгї§юƒz{{{џЉЕія”eљЁљ|Ое9Уuётй!„axТ9ˆг0Цд5ќ|>Џ#НHЅнЛwoХш/s` У__њц›oўмeЭ:ъРСї§:вoэфсЛЂнi6iIЌ‹4hmдЎяњнhCжtMšпцхЏTUѕŸc>^Uе3iš^Шd][zЮŒН(Š0Р єссс#cєеs>зC|оHk‡oj5ч™щЈMNРѕqЌpјMъНMБ~}›ЏыѕЖ}у6ШГDћ†{tЎРоооГжк_ЌЊъcГйь‰‡m0I’ зы! УZ йƒЛwятQИ8“б@.РЫщіљPK=Џ?ЖMНл4’Љ#'у вa8K*оцŒ6y}.Ѓ-ŠжZ ƒ{ШЎшП)рчr(жкНГ>чбhєзŒ1ПRUепšЭfћгXФыvЛ‚išтшшЈ&ц\П~§‘4z=ˆЄўi3€}WнЊ'ЉšjїгbMV2§ЕыЪWєnkЫmЛ­XкMвкк$kй4ЭwО#ћщвшвѓгEQ|ч|>я<,c‘дОгщ з[М1zZpzщbюvlbєъЯЅu:кыШп„ZЏsы2ўљмIp9ŠuрсКВЄ ЫXзПчжЈМЮMГ‡m Пэ№{žзпфA>ѕдS€яЗжўэ4MџУЂ(dНјУ0zщЯ‹бЯf3мЙsТl~:Cтќ›Œ~ёгїqX–ЦПдІЏƒдцz{ГqŠЂ@Y–ѕпђоФЃмУУУGŠ'Žq2™ ( ”eЙB\jRZгЖн*K~(рЗћЗёўїПO?§єpЏЫГёЭифMkУ”^ЏVk‚ЎЙѕїы:~@ЙЎkрЂ47E>БIЩuš+ЯѓONЇгŸ?эїEQkгѓ%Ž@œ€dЫLˆ8‹ЃЃЃz#д|>Ч|>ЧнЛwW2†G!кGQДђ,Г,[Aѕ[€М‡jєчъОх[О_ћкз`­нwHwЏ}37љZWD–Д_ЗUdшШ•1Д-ШмЖk KƒІŸеDhк4У8Э •GBЮq9–в€$IpхЪ•zьt:Х;w .gAM.—LЈЭшл2ИГ`eм|іГŸХеЋWa­НтJi›ŒЂ)§нд#ънеqЬ Љдh;|ыRt—#Z‡ p[д•%lЫTмvДњAЩЄ‹1tЛнbŽ(цмКuы‘‰ђbаzЪ’Я‘fЋъoгhП ~iРh4Тt: )j5еЕm,И&гУBЎэе`Ÿv›ДњјїКC[і"ЅЩІ­Щ6|`нк/—уК(ЃуИ6њ ъ‘Z‘ЫzЧ;оёШDz1zНйk–O0ђ|ЫYўR—Н^јР`Ф%@г›rlлЄ?’FЫї3кЪ `UU'І 5zЏ?Їу Ў(кж5а†й„ œv‘Щi;чщЄG/Fяyцѓ9о|ѓMЄiŠGэ’юЕЦ”ДёЛ”‚hЗ/Kіsf0ёХ/~ћиЧFMбѓ<l`ІSќІ”м1u4w€6Аn›TОЭ16•"ЎБhэєN Zžеш1чюнЛ'ŒўQHёЅ›бJЛŒ]gšФоvpэ‘v8<МTрёЧЧWПњеZuV‡чyu[n]Ыmл›вжж“CЎSч6 б•њo)7љzк6~ьТкœ€~bјyžo Š‘ Wк{ЧЧЧ\ЛNюAUUшvЛЕAЇiZOКкВMJKы \І›œƒM‚ЕЖvо‚iyчьqЯьђ<Ч+ЏМ‚NЇSc"Ž7oоЌЇЗšvžFМ sЅд цmЙ7%mК ^!NQ"ўКУЁйŒ|8]х‹0ю$нч ЩС`Н@Œ>ŽcФq\Џ^eѕ(Eњ8Žы.„^э%џ ? ыTŸЯ”ЮрЮу>YkыubzюaY†UЧЧЧ—ЧtЛ]|ћЗ;Œ1еССЪВФx<Ў39PгщДžъJ’Єе№7IqЙ~уƒЊ)Р›DЎMC' щarЉтъ’ЌУ36щ Ы@гlљр‡CtЛнК^gЃ—–Užч˜L&ЄФšМžГpЕя8ЭКјКžГн)кdvdн3d%Ќ<Я‘чљ #2‚š*Н$Л+GњЬ пяciјљЕkзeŽWЪ€,ЫъZ4IФqьфЏ3V§`Ф L&LЇгB2h"sф.Рf“TM x“VeS‹S І4ut6Ђ1QЛiв№}ƒСН^ЏциГC(Šiš>’ НІуrДnтрыЌ@;ф&АU—Œкшђcц"‹DХш9[а5Žу:Ј-ГЗќR9€Oњгxійgсy^$щKUUˆЂ?ўx}јЄE$71ЯѓкHљaЪŸЖєžЃЉ` Зnн:СQCя:ј>КНіїїы4А­–цѓhнучШ+ОЊ*јО_Ћ:;Б‰sРяAJˆu@сўў>:ЪВ’жЪuяоНG*­чK‚†ЋїоdєЎп%>ЛM‰ЇёW р9ўzЩŠЕѓЃ1Sc ŠЂИPќхЬрƒќ >ѓ™ЯрЃ§ЈЯŒ:™ќŠЂћћћ№}Y–a>Ÿ;gКх€чy^{h™:cЏ­S~k-юмЙИvэкr(%\"ЇU}ЃgГйТ9-3…йlŠƒƒ+шїћ-5љ8Ov5еш:эgATсH;пїWFhYоК­д^ЇгСёё1ЌЕшv˘ЯчЮ,уQЛxвpRЮ ђNƒ2ђ Л­#tqHжЅўв†еиŒ(D‹–КdЏ t=ГјТО€С`k­ЏЇђ$:3ђКПП_/VtyBŽњ’MА‘АќГgE888ЩDУa лэ`4"ЫђZ3Ю‹7яо…1І^ыЌ;m…е%бœХN]`— ZІL2о|У_ЇЉИ.ЉпБ—CГ‰‘Ы{x”"НK&žЯРІjЪќ|N к5q7\ќIёЕ6‚­t:„aˆлЗoЏДћж]Я?џ|§я_џѕ_ИрЃ§(>§щO/пзъMg џ—УЮћзфѓ’1ШЭrЅO ЂЩЯЩѓƒAINIkЧ"ПCHq#Ib\ПўŽЧ8::‚]ІУRsщЭ“„йрљЁ2Т/Эщ:ЇпКЌаЦяŠ№bRŠsœNЇў6CCы’ѓђiS IDAT0 PХJІФгv—Ц€фРж&8+а9,зЅы5iƒ№ІЁEЄВ,?ЁMч"љLЇгeЪпУh4Ф|>CžЏЊдшv›65!Рќњхa иЩ-аАOо‹ры@Пmg*.ƒбkŸ1—(ŠVЮЯп7mHвЯ\žk1žgщУћ*tљХš†rfЙ ИL™XxN№БЖшЃ‚КzЈтљѕП]#ДЋJ?fXqщ№џчѓљ2ъDіpчЮŒ<>Pќаф№Ъ‡УнIйmf€lюлЯfГњщMufbнМСC;hЫLІЊЊxе)<гrД^ЧЬуš[О_ў–LS~цЖ­:з%ЯNŸ)еЄL“нƒЎЩЭІпЛ)oрв8€пќЭпФЯ§мЯэm:дУ€Ю4fат,Ы pЂщРMѓіiš"ŽЃ•К_‹‘9ŠГa'$gVк5т8ИЦР3 ^{эB—uлгЅ;А 'aгЙѓО‚ Ј.пїыКО и“?МѓЏ)Хзe–vјrЏ9ђkуйЄOЯЪ…ЮKщ*s‡‡‡Ч5“/єћ}\Нzuх§ЌsL АЌбЏЖНр&б§PД!И|6ѓф9W6 mHп_эЭВ#’T_МНDyоjЬ—ˆ^ДЕлœ\сg›ƒбЖ}щДю4F/Ё…2š1]Dљ~vlа ИКЮ…ЬѕЗ‰РКF­5Ф%ъy^]зћОљ|Ž?џѓ?Чббб‰g^UŽ‘ч9žxт‰Ц…9ќš4оuЉK€ЇŸ~zXчЉјcjЯ)ЇЕ§љЛZeЦИ[2mй€Ы0ѕnŽд{рtSГлTƒ4sL;*­фъД>?ЌЫї§:{jыеЗ)ьАБjТЗЙ-ЫУ%ќТїЩе‘iZ"У(~Ўвv•20ЯsмКukЅГућ>FЃњ§ўrЦƒ1уёГйЌLт Eл‡kэЂpƒ3;€gŸ}hи:ыУе‡žЇхсЛРšuњMˆwS6А ШУ ’nК@@n6ѕŠлЂ‘+ZѓычTW—ыцЮЛ (F/јыp›–_шзцRLцьЫ5ў­ё#)С\8CБj€yM@сССA]nІiŠйl†›7oж%^†888Рh4ZЩ,%гмл!ЫђњЕЫ§ћјМЖS№@@Їг€НuuD{&лФqМВи“o”ŽЈmˆЎ6ђЖl`чСф9|МЉX?4љОІЭШњЁКHDк4 Ёn  ЉЏДэ8SтhОЮ!4•MнfeЧИnŽBЂЌ”qкщjВ—1I’дДi)w­Е˜ЭfxэЕзъпГЗЗ‡kзЎеб>MГКu+їЌзы"IbЄiЖђћšи.JјEdygvŸџќчёьГЯю5#ыЃ‰Ї”›ЮТ Œыn#џк8\FаDњpЅVЎячTG.QЄЦгЫ5ЦЫПпѕp]О Oq9XMК)уиЦш%Ъ‹X“оІњїЎїдЖўЬЅцЄлnš6ЭЮк•jžX9/”jЩ8tэ/Tѕз_Н~O<ёƒ>ŒБ˜LІ5Є‰A‹Œ)9ѕѕыGх[ўўјR9€х‹МЖЎаuП Й3. F“kјLЙЦj›ВM4i#Й$Шy>Ag-r№$ p6У‡@ЇЋЎ’л‘ mX'юpl@"}EИwя^]ѓѓиfХU[›В)КёP•юiчч*гtПžяЁќ[Œ>Žу•п5J^UnоМYпƒЇžz Н^EБgœH?ЫЂ(j Oƒ‡’ѓ”ч93\“KWXkџrQ'fВѕдЗмЄо0EЗмtdаsѕMkМЖЁ€ђО1ѓфimб5‰Ѕ ЅfzБ8Gљxг#нIp T4m^e™ІKв^зЄЏ6?MДoBллцшѕЙсgУNГ жІлJ{RЮ[UU+‘ЛiРk<зЄЋWЏЂзыЂ,ЋZ1Щ%[ЇŽœ]‰ђЎŒ @Э™аŠNКŒyшрЪ•+Уp(sЭeYж @lМђРtЪEВ,C’$NcbZpSнМ(мdPXizѓNQхс№4;+ноб(6g|А›xЎЖЇv’ђ$zШ§цKˆ+МЪЫ•выжšNг]НuзW7ІIV]#ѕ•зNQ~žдпќ3YBR|оUш$љЌŠ{vpА_Ѓћ.‡эz:cеe ПvэЈ{НžtZŠKх†У!|пЗ,y5ŸЯkДІеЪУŒуИЮ„%Ц-AЩ&В,;lBмpЌu)1|м’#ЏOцф№ШїЩїŠwз“Œђ7ЇД|и4ЦЁ3=NьrЌlѓљќDєЩ,=SЯ\”лЖ7.~Ўй]эЖЖВŒЫ(.t€Гx„ГжT\R|WТ%"Ÿ—ш/-Јт2~Wій$'Ћвј{іііj;ZЫ.— Ш3Я<ƒ$IВNЇƒЩdRз7eYb2™д5sЂ% •eYG~]‡‚=eлєдК]}mN€ЇY0B' wAwФ…8ТЦТ>д\2hЪ3G?.‡8 цŽГт–2э+‡:Š"єz=DQ”E‘№ыr‰dp–Уј‹kЧХSh#йшЊM‘q-ѕ&ЮXЮg*2n+IЕ\-6WдчЏ—џїћНК+АЮ№л№&= /яЕгщдB.В*]О.‚ЫЕќъ厘ЯчH’ћћћѕ‹а yЂO^ђq~@:'ЂchrM:џыЂПЇЄЙї‡М:[сЅŒKЦ1~ тЙИК_­ѕ\ Ц8s‘ясi31ќ$IVЂŸ№8BЛЖуД1иД!Л _“Ќ4Иц\q•КЄсЏeэ<1zynђl”u•!bш\Ющkёѓэ‰q_э ›g‘ЦуїЧБ8hXkkРчEОЮьВ,CЗл1˜NЇшvЛ888@–e˜NЇuš/oL€(y(<ЄСrЭЎCбдвi*жeM] ž>уњ]^S„хСШAВ n…ъƒС-@=Х™у ,˜"FЇЧhEP4х—Ÿ 8езб_ысkадeрœ…0ПCg?њ§mКEО MёЧ;N-Ѓ%їd>Ÿз™Z(Šb…Мхz}Z=к%9я*›Ђ~[РYМvq8ЎРІёŽчŸŸјФ'.‡јђ—ПŒяјŽяХ8XI’WЏ^­чи…%ЕГpЈ˜’­3ЎH#‡Л‰‹пЦ|лd ЦЕ9˜гjfў‰Gfƒae2O КкœЬFгЉПЋў‡Њ‡eф€ UЕгщА$п›PЇМЎˆMN–ГЎЯu*ЯŽHŒ–?ЏПзe(Rcы_2/+Y'gY‚+щЬ…3/О.a–MФj›вџ6EQM–{9›ЭъьmIЎлЈsѕаРђpGкЛЩЭЂhEV"Ї864й,$™ƒЄn=єУ‘пХгw›*ўКJС%ис0№'­L1>‰іQ­€„‘—,SvLт@ѕвМxЦшт,ƒЩVКC [“MвйMгsь€]ЮXЇњњkлpеџGGGЕD9;И~П_ЫЗНўњы+ŽB4 $sY%н&IяYє…Ы =wАЉёЛŒОipЉjjА,diъЌИ\‹A^}ѕUxžАnз—БФ+Чq\‹WJк&щ3[jК­Ј K&АxXЋ{4­Lp1УАmч ЦИц”Чq\0; ыЁ!mhœMp_^юІ ыH,?—%Т№“hяЊС]B-ЎЖSŸз­ьмt Wk!jОƒЮX(іјјИ~Н^ЏЦ0фйъх&L$Pp'ŸгЏAгИY„•пз:аѕ›О>ŸзjOZ2OG{зDфЅrO>љ$ЌЕžž]з”XŽтuЅ;Amр’ђqMЫ^›KGu+RЂ€ЄXльpЅYмѓцyp9авFc„Vъ`IйEB>ЮЦркvЬXƒцHtу6;нВrMК­3j–.oыЂhšЊы™ГCpe!r?чѓљ ЪmЇгAПпЏ'чИЎg#зQ’Ы яж#мх%Sа‹ќОM–ЪhУoЫ єkeьKZЬтЌ˜ьУŽєRЮ<§єгАжњ9нcУч(7AZkђщзЪ`Щ%љљrƒŒБ№}a`0ш/ШЊА(ЃМMдѓV—џ0uSjj­ьsttT#ЬьЕхџrљžhє™ЃПшŠ#'ЃM“6žц ИГЛ8ŠkРбхX\šŒ ш™vyіbЬrЙЛ3 0 ъŸ/и‘V™жŽMкЗ, #РŸUlгD- 2њНИ$ь71v—sp•RržљѕАCфзО ц;€'žx"боWўnzб,•%H wф1iEŒInZYЪ=Йћ{6ЙфgЕЕч$* јФN ŸНІЭъ5З3EQ&МњъЋЈЊ УсАnuЭfГ•ЬAwKиh›F‚›њкКжеX:+jг@tЉqэŸІ)цѓљ‰AЉыХwбРuyдмž3+LZЮ] L№.ї˜-ЉЊЫЌЋћз‘Ю\5~“У ГyЙ0ЯѓžрHЃЃЗЗ4Ž™€zЦ[зЮœњIшvЛѕƒсоЗž)пTйкЈyWю~П_ЇЬWЎ\YAћEQчЮ;+ЮBР^ЏЗвоLІHгt…гдегGу,“ѕ3цвCіY,ŸнхЪ|ппзш0ƒмVb‡Рw4ѕVГц8Х•ж—^СуФZУ_ŒW4 \@Є+эчšп•k@GО–‘[&-iрA(!B1EІКЦЅѕlгаNР%цЁС;}i_О6I ƒКЄњњзП^џnvЗoпЎyюžчaooУ€Ђн‚уБ 3їk-= жiМB^Ÿм[ІГTИ–јцgЭQ[ZЌM: OO l1ОРяQЗ€рsщА8ˆ€ВЎ C_ђОuYɘ€Н/м“eyш˜ќ#чEац ‚ жXf-еЅrQнШВ ГйlЙ€39№ЙвGNƒѕ nMрџѓ  OkщavŒ0лЎiС$~=к*e—B(‘V gŒPыwкг3ИчIumюjКжsLІу˜TХFЅ”˜уш/Sw‚тЫявЎбoоМY3јіііp§њcK†gЖваLШ,Ыk)-1mŒ|%ђsДчЅ-r/%Хg‰o%›“–`Уй_љyнngхМчyБтpЕцЯшзИ(z+иЩв9^.AЙб2Aоjйw›+§з§d­б/Ј-зњšъЫщ•ЎН]ббЕƒ@Ыaq -Ќ<Ц(ф=ЛІчєkф’‰Fy…žЈsQC]ЮBJ ž‘аЯƒK <ЯыК^ЇјУсА^ыХ$нїз­Б7п|Г6ў§§}<іиЕЅˆцфФ8Е~ЂЅ'+х]*:ЋgЇK#цdЇ(ŠšoЁYrџВ,ЋСjчKЭU‰О,ЫыŸ+8г~5ЈЧ’ДЖЅ=*їXЫЅащt}пGšІuD/ŠЂPбD]cы]€\шЕЮZ”;’>7 *rІаFТ`Ф\~/г€9ж5ЅfњЙZ€КUЇO~­M Kї@†Mt;N"пl6ЋЃ[UUЕ†ƒfч ‡C ƒкЁъѕXК}ЈГ€љ|^зБН^Џ6ўЃЃ#ч$`›–^S Qвg]j‰бЫ{GЂ…XЃg,tn`Ё}!яeAeOPUfЅЅ)ЯZЮ>[s‰ЄГyrYoнЊМ‡ъВ,;’j:ж‘І,KЏ ЂК_э’лж‡Hlќp-Žдб’Sv]Ыiš,џN-дЉqWŸ˜Ыўљ.„ ^о+%qtц1hW‚€Пцп)ŒЛЩdRƒ\%_yЙwк‘№§njWЈ—Џzž‡Ч|‰ьONъ&ZzЎЮDQ˜NЇ'8r]Лv­&ЉЎПkяЃ‹д$N^žiЗлE†˜Яг…бhДRШпРфkuДgЧЄ…I›$р.#p(ƒ/ћћћ(Š“ЩЄОЩ" &оTФиУ1…ж‰Й…ІХ$\”Iњ4aЦЕTBf­џяjjВMгkrh\%ŽцїkFƒ›каА6ЄŽ€УсNЇ6)зtM,F/ЯGœˆŽ№MNРе–g3†В,?‘žЗЉъшіІц8Ш‚VЙGнnН^wюмYЩBЄEлFdтпЅKSVѓe>‚ˆъйyђLєkа\Ъ—€Šk*№œ1РГ;cL%˜8=cд]”Ižчеi(Я†ыmЏ\kcгK:є г\yDњљ.…юKЛG“h8 Л6щlB; WКЫ5'KXq !™Gf>и‚аwЛнšmЇKAР{Н^M‡цоИЋEи6_рЂУЪ{’(Љ‘›hщYЛШ„"­‰J ˜iЦ#;юЦh@šŸ‹f 2ОУrёZ2N”8cv0Rz‰MHmЯф8ю^ЙФ_/b?рy€€БЙфдѕЅДјсJп;Mг::ЫClЂYjй*5ДЖiј7­мfZВ–іжJЗZRZƒњпк0јuiNX‘UгrˆлъAбіУ—ДWGmiaIЄ’іƒUыі 6‘ˆ\CР2 КЂ~›B<ў\‡ќZ{RЗgЙM+Y€>;mфэрV,уVЬyЋ Eк˜хwЩѓцГЖЩFЋ‡ньjO)"rШ‡Уa=с&YЃц‚юsєo+™…kщЃыъbю$0кЎ1-?Э‡G p$j[ќщ2~нrПф§M&“:5d‚‹+5•ŒAДхЄІз)О. 8кk­v„ы(šШHM—овл6Qчr>нnw…Z,˜‡‹Є)ъzЈщѕkЮJSй пЫkС%S”h/iЛр-:3дZ„\7Ы—Ž Лжv‰ЧЁЙ™Ы=5р!]ƒЅИш к-Ю@@ю$№№ŽЎЉuдfўЛDЁƒђСб-CN‡;N}xДJ­+ъ˘…zпœќ|‰ОђкЧуё‰Ь€‰6Y$‚sKKЇПыи‹Кщв#lгPдПcнЬњКЈя6DЏІKЩцкyає{ЙuЫЦ…oД!я<оэzюRзK–Т"5zЋД.wл€]§:/л,@‡СО)zBŽŒАљzНо ЉЙѕcТ гsѕЯv-м”šMЖЩязЃІвц'"б…™vђuœх№kфБ^жНукZN<ыРєa9фђš@%rHЃрZўП­Спж…iRкf щiчшљ™ГЎ_у2нZvё,\н!Е5ї_ž€’жZ ‡У’ІїЊё M>уgЖ|—+0ЦDBe4ЦдЕ'Гу\sъМЏŽе^ЅЖуЈЬыЖ\боЅ€Ѓ?ЯF)й‹CИ<тХхA ШЩ†Ќž&.5m4цR‚WЄЫЯЂДˆЎ?^8 qMїiбЖєНЉ—яŠє:[h’oЪ<šЂ~›aе_W”vэEфtžЃБ+kR–-чпЧё‰ќ5I’Ќd­:зыю$2ANŸГЖ%БГ JŠ<ŸЯk6GJVhЧРSƒ\‹Cˆ,ЉЏ–oв\oзL;?T˜fЌY~мr’ ЦЄуЭьCзƒ‹2<"йhАž}šІЕR2“ƒє<ƒkU–6nЭ=а|NпyVНiГ’fNъe(ы2€ЖL - pБ9umЎAЖ0 k6xнqвнЭ}рЙ.Лšœ–Ює\4myЮœpЖШ‚œЧЫ†‚`ъtKЋБВщAfcщTˆVG"Й‘zlX†”МР‚}:mgж–t(јsМRšф`ЩУ ‚ НzѕъJO—y,Щ|9uwœkП@[$жg.mђb.ХaвЎKџЗвдм­,ЬяYГ.wq)•фk'*ыэx7Є.коo›х™)9eY+“фHѕјr•жкH†hџkF›>ЌхЭВЊГї\4Mз:pЎѕuЪЪSoВ%GhšLyх‡Юƒ>RƒsЄtW{iА `'­8љœŒУjЊЏќ>‰X2”ЂхЦљpщ”pmzsвЕДЄIX?ЯОŽоІ8@“XŠt5щJ/-q­ZгпУsЂiРЮX;вM.Н`•п+ыIMтбt.[ —e‰^ЏW3Чєр„фHЮ‚Ќєўwз*lWЛHƒc↋$ЮKj8жХ ќЕќкиaˆ#г7zP‰е‡ЙЦдKQДPˆГж­кjBъ›Xvmб^гiхуВїЎmwc[дпdƒgеfНЦ\Ÿ5ž}П5ъЏ=x…8”Й0Їuћ&8Нgв—žcсrж#`AчŸќї)ƒїйР7ПљЭОяћžЄEzЬ”Ut™WЏeСxyЃієMtп&РЩЅЃоДДBK`KфтR€НЕж—” —ёv*<#Ё~ЙЯЅ”œХИє]ьУ6cbч!eNЇЩmНrv–šтЧqэl’ЁЌ3~Пvщ8Ш™рЬCЂЉK§—ЎдіrЏgГйŠњГdь„\Щuя\\ ~žђžФjзrтхбЈЊъ*ГїД&GFз 7О8­Р7г5mЗŽЄТи‚kS-gЌ'/<ц„Ќ#‡‹5џx_{oЩнз;$ЭgојУŽЌЉGмд‚kjъTоЏkTИЉІ•hя’њfХпУУУ­Р&'Р™ +ћшЎ^ёЭˆЛ=вqb,‡;DМдVпз„jгљгeЊ^фЪђeВP—ОŒ/ГK%rEГщX…‚ъ=€bывN]ЋъƒГ ]еU.ИZb,Цмqж§—tK§ФАєфЂ8 WЏ—ыyИ\)nгSS­н•ибђГаY_2PЄuЛнnНЭGRgІoƒ„aXS|ѕsе_’91й‹пїxЙƒЃѕ#xZў-?›Я‹ЌgJЎЋƒТNРEљжй‹нVJ9)п+s4s›QЮр /М ?ФРw}зwй‡т|пящк”t],=Mдqеy.”k!хІF Ч4y•ЙцkT]ВiŠ )зьbшR0—›гQMибЮLŽЄžЬRlZёех›Fw]"œ™p-ЭjBr?DL„X…ЄЄ‡Ѕкc№ы6]“’юBЇ/­я‡LдЩГ‘ ЃGoЕAUUU—$УсpeaIл™qu\§§ІLGwKxq­\*ЭЏ)Џ•ЋГ­~їЪ|:?`˜^xсдNрLњ ` IDAT (ŠЪCа)#Ї­%еТњsMыЉ]?ЯХ sэЕгвЫКЮвУ:ЙЙsР3kрё ‰<0ўZзzюІж“~ЏšyИ-м…HgAONЪяqЉўЦq\ЋўJVРЉГОыJAПy+“p):dEI—ЇјєСet›™ Њ(ŠzО‚SЮ5Ј…WлыКЖ%‘MЛ-†Уa ќё\~цГљffт0c” Пrќцј?P.€‘Œ@ЎMœТY3€їЬfГšЃЎеxѕN;Н?џн4ішк˜вRioЭ@‹^ѕХY ;#јLгДДx(HœœМo‰’zSЃвЬфCІ)Л<СшЂђЖEзІвH8)n•ёр —Ј ‡У:%еДиMŒ€ЏННН­^ЉwƒрўЧчѓДІ=k‰vi `'?GЂН€вђya—Вˆ'ЃюЎ€ЂлЩMипCрЪЎм‘ЌфіэлѕЯ5­sYUЦГ#c~р{јhY™і‡нwЮgйb*“Ј–•П7Щ ЮфЌЕзxbo0œаэгЕЎKnКi8УХNлDAoв›…%зТŒД‹qw:•:QZžz EоЃ<@‰аЅЉЛ< н†uшћаЖэXЯЕЫЧx$UœГP6 Q’чY–e-Фба6ИЎOВ $Iъя‹зjkQRІMkGЈŠш=[vJЙ uЈuЉ,1јз4ѕИnыd2YЉпйAёыt1$љЬcp4ЙыЁяЃ2ee`Њ NђqП3ЯЫ_ГжЬ=xп`œЮГџО*Ћ@ЕЮ œЩєzНзYё№№p…ЋЌ-kу7yL&—ИRЎЖљtЭчwБПЊЊZй+ ‘:Э“”‘yјEQд‹EхPJ”фeМїНiu6Їр\6АShу›ы>Дю–0uUžCЧ+-:мD7P|]~Дa/.`OпЧсpИВЄЊL­!F'†Я] ­qЧ1zН^’чyО"EЧ{ Иеъš2u‰Е49jзš+ ID0ОЇ.}EWлжƒ,_ Е,K™(N0К>ФєоRбѓўZњџжZжXcбщuўцєxњЩ-nsgreYООЗЗ‡ёxŒщtZз[l$.ФToка›њСšДŽфкУ. ззœih‚‡ќЌ4Mы&цјЫaсLўљišЎД›єAвбšuћu-эв tm’Џ”›иb[MП> BжP#ю2SсBГ›Rр&ЄўкЕk+ЛТ0@žѕ~žЌoРvœIЛQkšІЕtЗVmf>НPВu6ТQžйœМ9ŠGКЕse~kE˜0:ѓ<ЏяГЮЮ47FВjk-ЪЊЈя |I'H: ќРCUЬg3Te…0 рE>ŠЌј‘NПѓгiњ_ˆајРyaaUU 5ыKFfЋЊТэлЗ…НTOP­Sšijh#\ш›' 5+cš.b З–ќуЮ†єЗ5уO ^t“$Љœ0в‡š”Г ХИ„Hui$52Їѕђ}"*Ц?ъ™ xыBУлp—УT:]ьŒ8>>АиCacŒBЯjєћ}єћ§ксNЇгb;8qЄ‚нˆw:ЬD9rсƒvг3œ)ŠвЏœœ]JФšŽ^—ly ј< ВО˜ЪžE‡ШgвхYN’№pzHЁ`/.AA№ХfГйЪЯgB–ОЧM-0аФps) Г:sEѕ~nw1ЙHJJ1j1V6LvZЌЩє^qф:х–lпŸ8ЭtЕ6У0Ќе€XоЮХTmbЅ2ћаXƒ,OQTќХ"˜Њ‚Љ*Xcј’nŒ2­Pd9†{CxО‡Њ(ВЩžЗ”PPd9<Й ђХ"Рљf:M§Ю$I№дSO!Ы2LЇг•њK&œИ+Dž а@зšrфDН,џч1[Ž\ђ\ИIšІuН/iПd32ШtWЎ]Х№є2оiшZ†Ђ•{x(I"}[$€ƒƒƒкбItlš pЕ­јžh2RЛ \њY№ЮGљžлЗoЏ8.qЖН^Џž,eЁ юъєћ§њќˆЄœЦ&цѓyŠK9швKдй”їtнoбgЩЋЯ7сdИВкЪTЫч›#ŒТU9p§AE–ЃL ${ ђЬƒч{№щЌИ/qяЈЪbљ9АДёe!qўГ}зtгcУ0ФССЎ\ЙRh‰pAЭ9ˆ#`vзЖсЖ‚I?œ†j@‘з‰ ЂЬe€~Ю‘s”рqfiъRƒЙzW!їœЙ5чв>ф™ a‘Хq\g\Brq1ѕЊ2W&ХЮœГ1И:=:+`Т‹ШРЫћ—ЭЗ‹Ю@ˆW_}е9RЮЮQ—qr–XгЁгщд-O);Х@dQ‰ќ~§z$WƒЁ‚eЩYа kGC—Oš k­,`…чћ(ŠA зя`Ъ жXРѓQY‹lМШŠВ4Cњ€ткјKфypс4Gф.d ЏгDWъЮВ`"А \в&зAфнмžуўАfrЄвКўT#•••ЁAnƒ ЈЗѓм6ƒzЌj$гƒнnw%]ƒ‚^-Ÿзѓb$:ЪЪv™фУы"Г4ЕъtYХИ п_Џп… ш6ЄМТлЃш!@o"Ќš‡iDњHМБМkЩЇ‹выЂѓX“sbаŒU‰фgˆŸћѕ,X*‡чјјИюшеRoОљц‰х Z]FЗЇd2N№,bувXˆ†j§lКЧк49pнЎg˜U(ЉГЋФгЌRˆ‘/Е7ЭШњ9!-X…ѓкQъsсŠўRJYњц›oЎєїOЛАcнаVН‡Тїбщ%№ЬŽЇ№|y–ЃзыТ=иЙA…“a'D№| œпЯˆŠВ‚…НЖt“шЏЋЉ\Q‰п,Gcй "‘Г,ЫzС…klXпШйlVЯS3а'Ц#Р#ЇоLН2G‘~П_—ь,„Ї‘}.5єЪiп_ЗіЄУ Љ<ЏCзЛц\K*єsp ЕZL]™ oaуgГъ„`$NPЂ==Л.C№h "+Ч‰8.)ŸЄ|фР ЕНPЅ›%.єšЗГlъvmF*ЪяО‡"-–e -Б‘gј(Ы Ѕ-т2A‘˜ŽЇ(Ы Ib„|пя…QxЅ,Ъ1Яе <7а4ЖЎ‡Ь]Ž‚\“K+KsкЙf>>>FЧ888@ ЛЏЊ3‹йlVз qc8ЎGxИ„Бi)щ)?WЇгFоoЯ}}‰ттшЄ“РcУ|xљћЙвRVmвнZ•Іiy‡8,Нš\ƒVќsФYъ]xNƒС ^y-ї•iеЬ{з˜—4r_ИМ‹ЂЈnЛŠжэW‰фLЪ’ышшhхy Ž"ЯŒ—ЕДzл|SЛкƒёјEUР р-Вљљl†pIшšNІ(ŽЇАKїаєxIYС„qј=eQўЋ‹*:šPГ)jПIй Q[аЪЧŽŽŽАЗ7:љцТa лэ`4"Ыrеv4еФ•h5ž,ЫаяїыLAїщфcйpџ8+р!!Љkѕ„Бv­ЬвД‰­з6eЉ#c(ЎЌAŒ„E,фыƒ†Уa%хkфщьЋэlА;KЩicжŠI|яхїIъЎб|СR\ЛлЦЏ7ШвчжZ‹Y:…1їWžУz(MБ˜р1‹ўО5a`V.:~ов1Эч‚žєў…ч{€Ђ(DYU№НE‡ ,Jx~ Рџ Рbr№\3€Ž&MRU.u—MБƒЖєiQ ЦЫ1жДжSуѕa’њ'IŒызУёёGGG8Кwћилл;AZ‘:_ў/ЕЅдЌФ^вU.фuJ„’nуštЃi-ІвU\B|Е“i{ќAнYћOвц~П^ЏЗвХpmDжВqСз€~O уЁЩвє*5 ЪFdNѓЙ[ЄKгM4кЮЉ8’i:–‰ОХ=Њ |ј–*LQˆnЏ‹Ђ(яѓv<ЁП јz УЈІT'н` ВМ€Љ ‚(€чљ(ѓe+ао ^:я\3€ЊЊ:тkdй%ЁьbfчйТрЊх>НЩ ",Bˆ ІI6 iрН{їVаt=ž+8„№ѓЅcРщ9ƒ˜r˜Хip_OyёсхƒЎыR15иЇŽкД\ Ы№Xп‘u ъImЯГbјz‰Љ i{цš№ЃIжъcЪЛ 9У4Ÿ‡rXџOcЎђЕIpу?šўЩ‰ОИТ c*ВЦњСяёnТˆ#є€0ыіyQ№ФIL§њ|TUёЄяћ{֘)џ…^0ŒœкМђЪ+{к›s”wї6[c6qђрГ,_щ7QS…žйяї0 1ŸЯчŽqppАв dРˆ—ˆ0д5G 7ыА,škƒ—М/ОikXrMЄ5-оа2lm<^EІgй…ZЬzљtIŸ‰аЃи. @ЋхrЇE;ЮмєыэѕzЕ3–mKКeмЄэзєџMП,KЄy пї4Oє!ˆBkQх”ж#„ялБ€З˜Аж"ЅЃ~р!Яєс8‰k2QQX?JТOfѓќQpі Р3фtI?Ш&…к&ёгdЦšDЗI1ˆџ?ŸЯ—?ТhД‡;wю ЯГ]>^І9ьzЅY\ЛjЎЉ™њЫ"МЙˆЏkаЅrЌЖ&ЂTгУgѕcaшFЃša(ˆЛvИš\Ѕу"ZwO;"fNrdц:]о?3M…YШЂ1Рм љœkgeS‹y“Цeа‚ЩgN3бS–№ЂEзЃюг{ ЊТЂ,J FCјО‡Њ, Ёp1‚хHК|пџџtщќхlРй€Еv_{h!Ш•ђЙ(АЇ{ЋˆБKƒЭ• ,F{Ѓ:4ЦžPт!ІЩJ$ё}ГйЬЩGрД_я дф$–цвbЊLЁmкЄпŸkX…w/jirОWоOE+М|Сдr=;ўzшŠ_c›Њ.—IЬЄd­эEMXІѓ<Чt:­Q>Ў3 ~F\н$;`ATc *[-Ђљ)&њжXBјtр"-бйKPц *АxHчїщР>ЭŸ„Qkье&рдРѓМ=шсBгѕ4™^ђyZ'АИљжн4щEgїчВНрЇБМŒ1uZЯРЃоAрЂ-ыLCgMЯ]Џ€wб‹хšL&ЕЈŒќ|сШdпx<^љНšW!Ю›СTfs6-”i[oЮ*ФpbWБ пœлD_a,ЪdЇгС•+WVhНЎЈз„ ыe+U]uЕ+c`СNAЮŠ­ŠвŽ+УqЉЙц\`h[Йш’Y“IM1|—ЌwР*SЁЌŠ…ёeQ NєњŠЂŒEяjЖцГ9Ђ(Do0XMсє‡}јPМ0Р|6УlфY єбяѕащ$00щзШв хЄDU-И•ч-ўэ/зићAЦС/ч~ŠЩ@gq#Љ}dќН{їъ7ŸЯk]6QоЄЮ?K6аДјВэ ДНŽMіжkёKЎ?›J\;ж-раQЮЪŸУУУ†FЃ:ЮЪ.НЖьЇщўКК. ЗЫtд­…~П_IM&“z=–+ћb Г)3sНоЖчюRю•йс шcWч%+RXXT•AU•ѕаO‘ээ-hРKч`aˆевa€Ъ.$НВУo™=$KŠo–хш њШц)АфЉ Z‹И“ ŠјKnРl'АnВm['рJЇ]›b\hМўн,ЪЙЭСД-здЃЙLhaуУёL  iьЃэ4НWж'рЏ“ѕWЕeЩ(Гѕ$еwОV5j*]вdŒьЛ&;‘~Кq“аЇю§—e‰ЪXcE!њ§отyX /№&‚и‡? PL*yБЄwD \.Šб‚ЇS‹lРѓ=јж_8•4G†Аќ…АЛ Šb1ё˜$ т~„љб" _]н^Оя!/Ћ^‡7ђДјwX Љъ1U‘^zђЩ'1›ЭpяоНЪЇ€P"Ќ)7œїСŸ%pЕO3ПндVsEšІT’3žUаЊ2zўо•є{“УЉЉЗУgЭКВb[чщZІщr4B2bЖž–сr щьШEЯхVы:О„kњQYФ™r‰вЦтМяш ˜ЊЌ…јˆ;!‚*ЌEYV˜OSTї dY №аыїбщ,КfeZ.SјХЄ\ДьdюЇЊЬ?SЁ* ЪВ‚я/@ОЂXRХ—ч! C„q€*ЛQŒЧ“†с{0ЦТ_єя№EЯ’ ]K;%]J’яxЧ;0ŸЯВрz~›wШž€Г–ыt[JчкпчBёиу^?TA]ƒ<Ў5d:5—CЩ›f›6'%IRЗeХаšŒ\moгfuEBm<žчЁпяз\iущ9ФУCšgбD:r9WЙТћЈmЊялйšdЯФї<фYŽљt ‹( Dс"Е$ —g9zƒВyиEПA€ШZјI‚(^dж,‚ІЉ Ђ(@U-шУqт#N’…рMжCG˜O2LЦ„бВВœ#ЈŒ€П>Њв{7ю шЙъBY”ЉИЋWЏж“xђG_rРEŠI“8\рЯ&\€Іl`]Пк•žЛdВx„Xїњ5эj/ђя2O’qjяbUZkбыѕъЭ4MЫ4O“5}??s™фіš8pйь#}šШJM(<Я8ш•я.<Т5­яНˆУ#‘_зКхЇ.ч_—†ЕЊ–3&KбжЩžя! јA+ѓЫі]вYЄ№EY,v і"Ь)|Х№р!Œ"Œі†˜ŒЇШвlС q  зяb:Y|.NьЧЊ4H:1КнŒ%V чН‹љgЩКzYЂ‹.-YЊйэvёњыЏУZ‹С`pbЌTg ђ3Чуё %зu8…,ВI6а@6б—› WгW›J1mьZЫ`ЃOєєЅ—/WtљšAж-й„Ў,ЏAыJš/hўkЏН†ЃЃЃZ неIiZ’щ3g‘–ІRMoљс{ Пzнљ&ќuБžя/tј|oIНѕG1і{ цггёЖ(—)ќ§№g"ŠBQ€*ПŸТ ЋаУ"… 0/Ђ?ьТ‚Ћв,ПnЉMY”нбI-Q^Ђ\тA JИI€B“5˜мВПППТPcY№6ді>§s5…F+й‡ќэLж-Дф”T>OЇщ—yшўpг№ЩКV•HXЩвI^yЭrи›t;кꆛd ’ЁifЖЗ%ib/ЖeZ&Эеq9]qШ"х&S ђŒšЄд]Cjыц7ŠЂ„БКнюBЫo:‡Љ 2“/KЃВ}]IсƒAЫ(ŸN{5y3аЂg`qєц=$нdЙWг[Ш€еbxљЅa!Ž"„QˆИ!›e˜Яв…BЕ№|џ щ,§o@К€gЩ’І”лЦ5EЦцYyж…oŠЊƒС о#,7MDZw‰!‰gцUaЎhУЏчЮ;NšЌЋ­Щ4Ўћ"Тв‡ЎGL•qЙ"˜k.Ѓщы›@WWіtыж­:’ ЎЁйzТпзщёКдК ao]Л2‘ŽјQЁзые8ˆћh"ёыmЂ­Џь)АAф# bРЪe4Яѓ№ &у zƒFзіpяівYК єVН~“ёy–!NФС›%ыаGYT€ПрфОКУLi`* J"„qј@™–ШђyЖ.*я—ЮGEVќŠ16ХBpаžк|щK_ŠЃ(ъn2‚К)ЯкnМЁUwXjЉ,e+lXKчyБ!љаЗIaЙzзMXincшщПe3В8)С:т8Ц7Оё TU…+WЎд(Й8&зєœV&вYFгk\зdувџюt:ѕšqо{ПNŽ|гДкХkаN‹ŸЃА…ІЛXE>­32й†Ь[€XЃаЕЎ‹ŸoSЦv?ћЈ` Wљbм7 aС•ы(Г“у Т0|Ѓƒ!џ~ X˜вЂШяeQТ|єњ]јЫС Х–ЃЮR,дЂЌJ”ЙYLf‹Ь9I:№Пn!J)хСCY–&Я‹\•е+ђ%РœŠ№Ѕ/}щ/љОџ™%’Ибёsq IDATPO›UJпж+5уЃдт8ТBћ`;p‹JГЩј@АцПю№ђQ‰’ва#–‰МгСП&CагK4ѕ№‘k^РEбцlŠГ,йЅР 1ѕР—Ћ…Й sQg љчЩI~.œц АЧ^љ]МtЕMТ^Џ г OO”n№`*k*DIДшЛћЈЪХьE…(‹o|c‚Є“,ЧЊ)|U,˜z‹_ЕшDё}iљ,ЭP•КНрћЈЬbиШZƒ<Ыр>ђt!"2т5a„Є“,љљђŒ™Qе˜ЈI@[g_ќтŸ ‚р=Я‹ж!щM‘“AЁm~y`вг5рТњ@Яж[pDюЛгщЌє„Е‘АЛdИеГуЎv\эWOВЙŒCGKІ]k5цЖ_фЧxЉ8ДсpИвЦЋЇоTwFпћMСUщGО”fњЙ 6"%Шl6k”№’ SБЋг–ХшџпwК!К~€4[д§€ХНЛїV†b!Š|Йі[RјТР`‘ТB@Ъ‹z€ЇЌJTE k <пC‘/FŒЛНю2Ў–]‡ЅYv€вtбF„-+c~'Oѓџ РРl™TЫ `s№Ѕ/}щAќОчyбІTб6<`лНыѓl€т§9§зѕ?\Сd ”—О 6B#­­Wм„ АQpцЁыw­м„ъѓ=с{аFъa"—ќ,aыЩђN™њlЊЁ›F—л:(ꛈLСфїˆ№†№X"Ь%УцтrИj{ўЗžkаЂNВБї ьР.Œ~!пэС‡я{HzЩBЕЗjJсxо‚:l…Бжтиѓќ™ž№р!Nd­ЗшTŒБАЈрaQ2WІBUYc>o§ПѓЌјп/@  X:Ле0PŸё}ПГЮˆзЕикgЇЩ˜EЧB”кИˆ#В%Ђ]†­Щ)MЃmaщКq]Н5Че…pbјcšЊЌy .МBЯ$дъ?R шЙ}NЇYf|нtg›аŠvЯ->Ђш#‰ЫuzЏТЖЭИ2ƒ&jŒБeYО6Nџ (ђлQ§Э оk­эФ…ƒ‚ТhБЁЛZŽїZГšТk‘чXc„!Т0€-Ћу<ЭџЕчyqјпkŒљ :ѓYК”џџлћ–XйвыЌяю]uЮэлэNЛ;Ю:8ŠСIpф$-1рЁ(L2€ƒ!(Rƒ †ŒТ b)!@Cb” 8!аФФ1‰Бc'ŽэVlїѓо{N=іўk1XџПЯі­:{OwпюЎ-mнКuЊvэкЕзњзу[п‡Є•~‘‰o181ГЮDџ^Šљ'rЮ_pЏ8€uўOкWr‹ХтŒ1яоZэн<‚яAЗv•ng ЮqЕэYЁЋ HuћдtцГЛdКvQn]eєИ-рЭ —Л y­aЗ\sG0ч$hWг}Pз90ц"ъЎ]нŸ}8‰9ˆjзwj9 лўНPmйЉЈ7ЭEЬIs6фЋ#ї9љцќг0 ŸYЏзПBјУЌБ1ІƒПрœ}џfЕy† Ј-ъкašBј˜JЏA…Ѓƒ™!†јЪєPTxеXѓ­Jыл1ФoЬDяАс“!ХЃŸfрЬыœщyЪєyfО[ џtnќэїЖW\§џСыeањоyБы"b‡v…Љ#ЈЛњдѓуьDйХДЋ6/&Ея›sгя’гšw2ZƒЊчвwЕчф#ЛœС8ŽгьœFlо—п5X3ПFћj>эЕmU|ZљЎ:AšsО/ППЬpч)дЎ)Х]ьбѓЈhІЭ‡aјэеjѕГ!„ЯЃтЌщ)гK‘јsDќЮйП Р+­:€п+@8@MlдD%„ч‚$,бTЮљgcH+с:Ї˜_Ь™>Ѕ”:2FЃ1ц[‰шK)Іп"т;)"—м>”BпІЩљ7х<Я…ўзrJЉїЬWЗ}сџУѓ<ЌCихvѕ{ык oЮПУ.’в}+ЛzоћVЙ]цy'Ђ-ЦЭJкДТ­Ћ#i 3Z§Т6MкХ4Д7Ѕ!3Š4ЬЮ”bў.šйЏпo!–vзyљЎ‹@aWХь ЙЪpSIЯЦq?~zzњ‘ууZƒЃbGР’™SHї8г :eєSZыяO)П—гuчCxѕ3?FDЯ3ёяԘўeњB1фPœ‹ebЫ`C™>ŸTў3ЧbдЉьѕџcyяPзЖп}Ц% Е6(" ”^‹•§aъћ$Ъі б\ЕЙяЦпWј›‡ѓmtаЎ–5§ЈЋs§ab#ЎŠ8­ƒh;-ьzОЂо_-ЏлУжFZUT&мr&‘ЅвB[M‘юуlSЈ}Еš9 ЗЖMЋэ2ўЋFЯдзЭa™—MэнэзУF—С\/K.BЊэrLmU|ЮƒЗ Qж:ЄyЮкJcUЈmлѓп%7VCЭ9+šp.‚Б+ЌюњЎPKБhжAƒ8kЄпЭ™%_U heюгцлu]цL@ЕАЗ\.ЇяИk"яaЗ}мŽбебщ0 ПОZ­~.чќЧM}нЌЎuѕE1ЬЁйЗХ,,SLП‘Гњ=Ѕд‘6њнZ)—S~žˆПТЬCГjз№НіыsqК|†ХЁg5ьмьд8jvь2ўЋ:€яiWЦ–2КэЋюНЋ§e7РEŠ‹„w9‡‹Z[E"man_хzN[=я,Ь{§5hyЊбЗ*Hm‡Ѓ…XW‘Ь3ч^Уs‚БF ГЬ0lс–GJLвпЮ,НhЃЭ} Hu;999_Ў§ћууущКД§›Міс,іЅ@Dtw†œœ|”™_hЊчы&—m>]ПVГ‡ђКК’/,˜јƒ-eњ|cЄѕЕušчb1оъкЋ,ЭііyОШ№ЏуОНѕьѕ­7g.Њ\•oјтa"ˆЋpь]1ьКˆУЏХ Ь‘eћ4 jx?зІЏ!Ћ<дF(­ЃЈ†ОЋxйђд0|ГйЬ" ы{Aš‘R •AO8ЪsР ЪЙD€хЛfœ“ЋŸ]ПЮzk&ч3O}ф~yдs^г‰1О2Žу;==§^)aўМˆжўR‘ ž­ОБ‰6%=pЭ NЭыBЖЗy=5ћћи|coїiЛЬ№Џь”RпS эл:qЇП_~аˆр&СMмDWl™OюъЬ[…sБV<Г"ђкткМS0wDедпЉ=ў8ŽЈЇ=ŸЎ—щДq аFC+@[ƒ4FИЮ`&X­Al о\ ADšb}‘Y {• $SЦНгЛТWлЗnOщЭ\rXzш—‘Х^gъqо5I)НДнnџгzНў%wšг„њцвћ'П—ъяќЬVпжИЧbgЖ„ёhBјyOMdAWН?ЏjьзvZkрЯBўYЇЋц-•:–j­н[КŒŒbпTсЃВ]U'Оumx?яCЗ|zэБл•|^lмХ<4Џ7Ь9№ягЊ†ћœQзw2‹NmEЩжcuбš J ўD Z›Ђ^Ы…ї •Ж\.E#lЖФ$tжЖPYн;НkzϘФ^CŠH9Šœ ОыaДЙєкяг.˜Gn!„/У№ ›ЭцWУosќёЊEДЯ§ј ЯўјєќЎˆ тŒG7€šза|%ЃО1PŒQ/dЅћоEgUWІкŠšу^wПLхч:{е№џЊЉФeЧžЦЬ Ў>_ }зjоF[еа[тЬ6тh[~sИ*1ЩiˆаFСX#U аЦtЕѓ `Œ1a P\šм Ф™1Щд›œ‡№гiЅ …щ4Цq„бЮZVы•М€бЦ”6ІRbж€Јщj-<іœeVУ8Ѕ46л5:пУYwщ*ПЏPЂŸчЧqќ…эvћЋсЏї~˜сыcymu5‡O—…№Џ—С_з|А§OEbU-ДЖЗ<ЪL)cYcп/2є]АйЫ~ь‹ ЦзЩћ/3ю]ЬВћ†]цшЗ]Фmш;ЧМЗчП‹—`Ыэ‡fBŒAФfЕПqЦ€ЎQІbhЃ`mљ”b@&‚‚Ц0ŽpжР;‡œbЈB&їЖs"IН 2ctСе5щм тa*З@!РЈРwnŠ4 f™oяЛХ}u‚]ПCш""!ќб8Ž?? Уџ‚@cїхјm(ўPЋpѓ^nХ8o*tНР‡цOдRЂiлJsGPщОŒ1гИцЎJяЎ4с*NрЂ1у}Ћўeњu—­ј—…ќэPЭЎ:BлŸokѓkЙOщx—:Oэ дО~НюгŠЯFЅ…^)Ё цЄcЄтЯЬB*izPЮbќЮbБь‘bFˆBеї=”Ж›ЦXpЮШхк„qњjЃН<%q/Бp70 Рˆ cи АЮB%ƒ3`јТ…_щЮ•Rpжпзmи1I›ЭцЫїюнћpсу; ћZўЃjшф”RмRm6›i”v—Zю|юНЖœ*љE+7НЋVАOаёЊaпeŒЎW}§E,Дѓйё]ь1ЛКЛРEѓB[œSˆЗQEmщUЃŸЮЏЌјкœEžFЫ„19C) у‰ ŠB9†wNœяŒж L6[XФ<œF вџ!@‹Ъoч ‡=У1c Јб“[*c5КЎGŽ’І?v ZCЄД”ž„Е‘ш Ф”рЌ?Wѓ˜Сyѓ8ŽŸП{їюGRJПйє№w~›у?в†zћќF€жzQ €ћЖКкTƒn  5Žєввvm6Œу8!РvI<э‹ Ўћх/#Лмєйїў}§vЕžsЙЬзЪiЕ$Ї‡Z4]эTЈьЃЏ­О8Ѓ ДДєTAё‰a1r))…ˆˆщ+˜ cŒpж ху,М6ђ™Yc; Ы.—sБЮ!Чˆœ §В‡uFklЧQа,ІЬХ>ЧqŒXїЅхYdЏЗ‚ьКNR’!Yg%uй‘NQЧёѓлэіУ)ЅџгTєkŽ?М• џѕˆ>иД-.4Ќ фh™WчSyѓЙќЪ`R{Хѕ=:я&ьSћНnеўВ:СU)Ок|}.^йуЊБWД\{мV)hз A‹Еh#ƒ9eіМјЈ†Жb№гФ eh%ŒЕ““W]g ŒF"rŽх3ъpŽBч\чс:ƒ T*B№оcј’оЉZ 4]п2aЛ‘SDŽRQ‹ ;9œa=`FŒУc, яe>>ЇŒ"œ—кBЦs ‹ж:mЗлЯnЗлŸЩ9џю+~<ўѕРЕЊі•1ЖВъЬчылœЗ#o dЕO]oюŠbЋиsзe-ЁЋжЎТвГ мЮёзЙЂѕкzH;šЛ ;рœ›Ш.j;№ŒюьJ)аТ­ Eu.Ќ2rў@МR`",Ž:hпƒ3cFмF$J &X/0рq+ќ @CђK `qkэJДъZ-=fР{Ѓ-VЇ+Œ…ПmжеŸa„5l rfŒEvЮƒœb3IG!„№ћлэіпфœgЃЏ+œСjпВ†џƒ?јƒЏЙјаƒф#-Mv%МЌј€zѓжќК2Жс№|Џ!ю8Ž8===цVRЭVОљКсџe+}ћї]:э$п<ФЏбAЫRSЩ5лњH‹М}ћ6VЋе”*еЈa^cЉŸ;*DЉ&ЅgЏ•‚Ђ‚ vhф,<ђЬ$ВVФаE4УzЙ%ŒЗш|‡ИMиœlСTлVЊљ…ЕЦc-жwWPЦ Ц0с”жУˆѕj­5Žo ќwН^ƒQШXДеп:јЮСѕк)ЄсŒJmЖау8~nГйќ3ЖДѓ*dwзŠO‡џ€RъC{№ч]'къоFэШыœЭw—ж|5ЮqЯдМч^Е…›ЖЙZˆмnЗч?їuцŠ;s‡Sе<ВЙ +oЉИsчЮЙcЗ†>ЈЮIS—TСpНвn*Кqс­'вpж"—Ђ Vщџч,8оJ‹ЁƒНшвхŒХЂЧXХ@ˆсН›?P€q)Fє]?QQч”‘’8ŽЎыЫP’№чoжkDDXk@$н€œGфœРд#х„ѕщ1%0 aІБ” !…1ѓџ№2€ЛГ>ўС№жh­oCІoЌRйцАеы^o№љj7кї_TЁŸ[лCoџіФO`ЕZaН^_Hў [­ьKЇцдmD1:O‰žюг  Х?m& XCœѕdЬ"_ 8Wj,…@(…хQc5Š–”*EJФ$А8^ "jУ8HЛа/:Єг VЇ+0‹e‡Чоё83юНzŠn?~АYЏKEJlqЇљfЦ­[ЧаJ |X;(SОрЅтъxюС№o0јаk§Сm=`žяя qwЕЪкЂијyn^lмЅ0[Wі} Ѓіј­њpћїjаѓзЭŸПJб†єJKф-ЂїПЦ8§фЪјУ Ю2гЃ&yЈœ2ˆt%ЅДд]Ч"-Е]o‹фw„в€5rыѕ q&]Сz03†qD2–Ы%VЋ 4€~б!E™ єО|>eЄЁ`lсLТ/5ЂŒEцMА ]пСy;Н~sКEŠvaa џМвЪГhнM]ЭУі@k§Еоѓ(Žф^gѕž‡Я—!/›%ИЪаe‘У†1 `‹у#iф+Й{еЄЫЉJMЩф я–ЈTгІ‘кŠе˜ИЅrЦщЫ+QЙЅ2ЄЅНGЬˆaGDЛPiн.—KXg…`$КО‡в )nŠ"­‚VBKцxUx”МsУ(XТ)AШ‘б-zєG†е€сd( С‹e/‘EЪKчэ3aˆП @?їмs‡(рa@Aѕ}џ]Џwўџ0ŸwS†іЈ9АђelZkt ‹œ’ЬЩk [(КТXбq•LCњѓЬ"-ZЃ(зИы;hЅ0† c4œБ2ЋГMDаЬАZО § ъЗa…,T‹ˆхf%ь>лMр$Е…L„еЩЦht‹ЊѓnPŠcDŒR TV†…R"XoaЌAyj#ŸžЎ$‚гЊ8)ЅдЗј]œГ=lтB•sь;уОyƒz9шХZS*ћ€БІJЕ†sb›ѕVŠ|,…@]&ёtUYж )J Ђы:@Ю:ŒуˆMmi­n&€ CЪаZДыSЮАЕek-Иb;ЌЦб­#œо[!”Q^]fЊг8:Z‚(уєЮЅ56ї6HIV­ѕФў3н”Цbи иЌ7p^ŠНE6ЙД!­еШI}ЮШ6лƒ:€Цј-€g•UўAЧ›="дЋд.Ќрыs™#а­ˆHƒ-pж N>Dє‹\˜|mƒОL1!•‘a"Њ+ЈфтYl2ЄHшCЂ ‰Оыр;‡8Šgпї№о!'ЦщНS0Q1Q@iчхн]пУ8‹aГANкШHАuОs№]‡0Œce‚їУvЉDяЊК-КоcБшAм •њzœeът YA5ўN)ѕУeyу#eЕH—9"ТАн‚ˆAJфІ8F™А‚b c(2Sˆ&ђN]VP(%!З1Ш%тЗVXLТФ™ Œ•МЕаF#ХˆX0ќЮYt]k П%‹s™№TцёЧa€Щвт[,—Ѕ6SєёBœˆE€RLg1PJЂ†{|tŒЎs(ˆЄVA—о;„џ7“hЮ{џ~OОUŒшЭ(€iRuН-Œ:Р8 SGРƒa 0QЃѓХ%9ˆPЯС†nФF†aœЦ‚Е–yзu8*)€0“HSCІ ­sТгW>;хЇмвсЩw>‰ЛЏо RБO!LcХ1%,ŽbТ8ТRk†1$јОƒГЎD7Њm[рœƒя=Т0bЛ„Ы€Jып6У??Ќњяъъп+ЅО§ѕЪйw а"žђ­Э4P3n|яаѕ1„iфЗѓ)‰6CВB›sC *ўЄŠI†wŒA*mЪ‰w0F(чDѕ'KяП:пљBў XoSB QфЊ; ушe*ЮBm{‚wкJЄ ЕF у0ТweˆЋд7˜HјџДD]пј3 ƒ:]˜Ю&#яХ1ў#’ œРУ9б5[МсџСШрš•Аг|ПСНWOа/Иѕј1РŒэzФzН)LЭ,рœŸЁаї0RЁцЊD&‚„тK+5uЌ5ш=Д1 ”Ё­AEЧ/ŽОѓ Ѓaœ"!‚,Ь™&DgПш@TТ|ЃTчХAYl I ТJВ”3#РV Э5D5)% !ў“œђ—pFюqp7рŽМџ6і‡QzЫќ(ом>‰A”p?Чˆ‹pЮшЛ\Є”‚ѓВкцœ`ДЦтvИM1B+ы,Rдсёё‘ŒYЇз0 з Щœ2ЌЗ $)…їЬУV0љЫЃ%`sg#˜-S}FKL‡$ХAg1ЦP" • iIVШˆ)A%љ§Ч˜0l8oбuW2eфLџ"Чќ?q6§—Ц@)Е№7’ПЖє~r+STœ­`rЬqЇ0йРЊ`­LьЩ /+ћнO`…/d*ЦЫъЋ” №юНr"hНЎCFЁю.ƒQ9%№šЇQnсщœѓ…ixXиl6шКЎœ›ђ{­ЅхXв‡ЎыSЦvЛEN$SƒЦŸВЪ[ч Uсд[Ю$аaб"@ЪDџ1 сУ8cћЉ„žtИyЮ8cЬ3Žojѕ>8‚p ЅЧ-…6 уїш:?ЉњhЃ‡T nГY}8ЂяМфЬ1 P–!фH0…7jЏњЙTкxЙКД шЛ3&ЁL!њаFD;œїcD БРwrE,BРC‚х70]ћ.4хжˆЁбBъ#bˆ€512Lє)&ќj ёЃ8›Ќ‡A ("JкJўvt"Ь &х4rLˆ…Mи”sЬЖ[aг1ZЮћЉЕF)!ZI ыHQ#ІЪЫЃ%Ч=ŽŽ0Ѓ• ьˆ Њ!eІ)Ёœ1lGР ˆ7ТмЋ­Тбёb …iТ”3(›2СЉ kёY„@D0ж)HЮˆ1”тЇFуШDkdќANєгDєћђЪўSУ:џУ9Yuˆ^pЪЬЗ^kУ;D—9ђ яbТvНAДЮ{ФQˆ;ЗлЮћЉаЈАъ‘жbb,Ž;lVkиЎCпwXЏ6иlЖGaћ5N*ё’B€вЊ8•BVZ {ЮЙ ДГ\іˆ)#Ї­UAэ9ЃБ:Yјв(г}]чБX.Б>]J(]цњ5œw’§%њяDєŒѓК}cSќ;lщ&3fў]ЅдГr>џVФўя№ї‰ЈшBІД‚ыЦ!‚(#Ф„ЃхRР:1РшR(yvх/ЈДg/ ѓЧЗаNcИ'TgYЫ„ в@Nж ZDH™ЮАЦ9ƒ”§–GЧИ{ч.ољюЇD‘(T‘P&FlбоЌЗ!Р9~ЙN„‘8ЦBуІM щyœБќЖн‡аџ@U3sЮџеZћьƒ*њœСЭ­5eœXIсЭZИЮУX… Ъh,ouˆЃ Х”&'ˆСrЙЮ,–K1Ъ1”љ ­rJ8НГžъе98g Р ЧŒРcс\'”J_^Azј) . _tclфрh"‰!!У{Ѕe<Й Є=iѕ4Эe@Ь_ƒ3yэm“•нЗfŠIDATѓ@nиЄRMRJЯi­Kk§С›t‡џъЮLVз3ў~[ZtЋгњОЎMDпu8Йw (Av]гї‚ДГDŒѕjѕJ Z†ƒЄпye4жЇ+Є$У?Oћ,?їмsЕАmўFЬL!„j­§>kэ_gцх.№0ЮрЂї^ѕИoжnР9SЋ‘rB< %жUАЮ@kQ0КѓънЩr;№^ІъRJ6Т ”8ч:lз[<ёєmф1aГк–‚^’лNj’ЗXЌЄmh-в˜ЂTщCТ! 5@вa№}‡\$Х|YСcЄы:l6k™*LЙ†ЂЈћXЁ*+-J"iGj„,ЂЄ5аcњПŠѓŠО'№DuЫ%ЧЊN€j} Ѕєбœѓ'sCk§нDЄчђпЏGл№Q1єV­чFО‹RšњпшК‹уьв€6‚љwЮв,y}.mЖвŠЫ‰аu)ˆ‘/№е/Оc-‹Л} ФBšSF žc)ok1l‡3ж!m$\g.? LJiPPZ• FŠ™2Мїˆˆак5"*Rщ‚ Чур:/#>—х3сг9х_УYАm €7эМї\hСR“oеЈ ˜yBјQ­ѕ7;чўŠRъ;[…зЗ“3ИЩЯ%!д\.№ЫNhГc{Gr|Афа‹хЎw Dˆ1#Е UцэЕEЫЈ-&ьНƒ6BЭ] =фЗQш:Wњі0Њs“JSсэлnЗ L…!(У9(a; w`Fg{0$”ЏœЮI”’Ђ‹Джcn‚-eЈ’r0aЧјSХ№+h‹УрЯkxяЙ„|ЙqЉЉ жDДЧё1птœћ^cЬwQз:жИЯ9\'%hЪ[uSZM9ёxЇ ffЌW[еXіE!9œ1ъ0OЙО6ЮЛ €ТчNяHоЭ M%ЗЎœƒЦФБнАЦТ/ќ4§WХ8ЮDLъА€~rчбѕZ{Rќ[/ХžЋ,XJ“T˜ЎњJAЇŒ˜2 k* Є˜~ŽˆОŒГЁŸuЙїЊ8€^ЃM4@Гœ+'А-?ШiЮљ$чќiЅдSоћПh­§sZыЇцNрВUѓ­œу_uЋи~Ъ4Qgї}[З†ЂFLЊ( хТз'‚ФŒ˜фЇLQf№ЧaDЗшЧPкl ыєЙпЦ8ƒq(S„”ЄлPVџ*lbL)ж9 m Цa„6\&ЅNPG{‡э€aГ…uVF“•ž„IRL0Ц–t@ŠŠ1&D–є†С`цOх”?†3мџiуvbџпа№згЬœ5Е€ˆ3МРКќ8GЬ|gЧ/ујѓжкї9чОлZћ]Zы[ѓH@5ї‹œСe‘Т[эGg’.€ы}!Шё”\Ѕb‚ЬЎырœєеcЂ]ЦkcaўUZcиnС…^+Х„ŒыdИ''Aї)()z?‘‹(Ѕс;a;bЛйŠ/q`FП\L2]P *AРHшЧc-laB#€*ч< ыw-NэN ё_–Uџ‡Бп7ЮЬRj~€Z‹#8АААL)Н’Rњmџк{џчмЗcžБж~cu9чsz~Ежў<фЋЗ ™ ›.ЩjЈŒFŽQђџ†"œˆЦZ‹єVхє^Ў#х k*Ѓ. Їž|)CQq0!"бr‘C„Еg`S`Шо[iŽёŒЧgПлА RбЫP"и2eшМ(1ѓDFTёџђЪ‰rЂŸdт!У?'и1љw0ўзбЬ‡x ŒM•v /ћР"„№Rс9Нжњ‰ОяПнѓ>чмЗxЊоЕ(+‚ОRА+xдaЫWњЄЬ с{_0o А„\Н6(ƒ59Wb_QЪ)Њ@)‰‘Y+?m•_—МЅ[ h ДVH)cЪД AT…KєАXv€jp_ˆIb9, Ф Ћ~ЮArсД"Ъв`Њѕ СPћН‰2}jfќчfўІњ9€ Aj+Л/{WœA 'Ђ7›Э—ъsжкЇЛЎћ€їўO[kŸбZ?VB]ёU#|q™A_f\W•иОЪпЏЋ x‘ю`сœНWTrkЁNЎ‰DN5Ÿ–hЪ”Q]ХaŒBл™Щ9щ?њ4} ',П|чБYo&'’ЂыЄњЏ@9a,bž9Ы$!—А"ьсНP—/:„qDПш+Н§qбuШgRят”xъ&@NљГ9х6Цв„ў‡ТпЃтv8еDЕS`g0w е1t)ЅSJŸ]ЏзП гZ?ЖX,žБжўIkэзcоЉЕ~В№^Кюъ{UcпeД ˆ^іњ‹œУќН2ђ RJ)­Е2ЦИNјњK‘€zh=ёј+]0)AA}9ХќЫ)ІпаZѕЎsеXћ—”R:•cQЖЮNЦ]Q€Њƒ8c˜™ж9e•‰zЅ„СW†ˆСDBтЌд%Ъy™‰ѕGЦˆЕб“ 8ПBњ1w l?їfЁ>„ў˜˜зфR'{FЂ]œmіНNˆќzНў€_+Я9љџ”їў›ЌЕя-Žсi­ѕ“ќE†њ0aјU ў:+§EЮ™33ПШЬ/бЋDt™OaЌ3яГЮ>CDŠ™|чmхьC1РъŠЙJЋ9ч”~“24Їќik"Žу6|Ъ:ѓг9гƒљ[MQЊђхжZ@ \W$и334#х/цL$`x<ЇФ X€ПР“ж:Џ•мOа”bBШ]б1ёЯTV~њxŠщ_1ѓ—UПв}^ЧMР'>ё‰;`‰ Њ3ЈВc­CЈQ‚§ЛыБoFћœ],Яh­Œ1O+ЅзZпVJxМдО{D#Џь3юЋ<ЯЬ/HЬМbц;bˆє2НТЬїˆшyfЭoašHЩ+ЅnkЃпУЬЦyћgwпЌ”VЬЅt н_Ž1ЎД6KkЭ–С%њ\ёg(гqЦ ЫgxНqцo­џОЖfЂ#`­-@!ьШ9sЮДbцЯRІO0ёg$ЅаCЉ`ЁДњ:|€ї(­ў3)Ѕ?р+` чЬЊH–ƒСФєљœђ'™ј+8k+ЏšЊeћMW §пшzЯ›}шЦРg€ЦДA7NЁўЛЫQи™Уhїљ{Ms|cŒЙm­}В|WeŒy‡RъVѓ§‹lžzВ8}N бW›чŠ Dєdv‚™y•s~БIъ^ы&ЉI›ъПUивЬвЅEM›Œ5_Џњ VњiЅдЛЕбЗ•R/Ф~9ЅєМRъРѓЬќ eњR“OW(mnœL`Ё~ЏБцДжпЧЬVDB”UJ%0ЖФќ*3}Ž2џ&†™яЁсуWrї{Ѕд-Ѕ№ПФЬЙљNЕfд>оUHоЬђў+…ў№;€ ‚jvНЧ9˜‘УE{ћ>е<7плЯU;ЮeК.˜h“Сѓžš[ьФќёмдчИqеёѕГ}Ё”zL)ulyŸвњНЬќщ8ЦџЭЬ5lž›ЭоібUs=ЋƒY*­ž0V ОCпРР)˜џ€_!Ђ/1ё+8OЭ56чП‘ž9€]зЉ-"‡ВЧЗ[оџH8€7r+ъФиcŒjOдpе]]`ј˜|ЛчхІyцp#  яrsY+=KІжjMhЅ1s%ШŒU'04ЦеkыкЯЈ]›щ3pЭ1CsЬљ9ыЦу‚ыФ3œг}Н­Š~o{№Žaзџѕžе\_`фћЯ#ОфёE‘СEyv<нЄF~ дHЭVб8{м>7 аќЕ§ ќoшWкыгІVΊϘЦЖАіИ4ЛцŽ{Ўі8IЦлАнwpюpMcоїї]џпћ{ЭVы‹œТUœряўЛячг—NёсПїБЙc33­a6fЦйў›gQЦ}Fе\УyЪеюm­#Я>c—чЎkЮ;)v\ЇЗ-ЩчСМ~Ю;Œў:зƒ/yўмпц†.ч=wm}CЭ jДk5Нь #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class heartbeatOptionsDialog : public QDialog { Q_OBJECT public: heartbeatOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~heartbeatOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::heartbeatOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); virtual void toggleUseUnicast(); }; #endif // __HEARTBEATOPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/iosAdvancedDialog.h0000644000175000017500000000261411733011756022554 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IOSADVANCEDDIALOG_H_ #define __IOSADVANCEDDIALOG_H_ #include #include "DialogData.h" namespace libfwbuilder { class FWObject; }; class iosAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::iosAdvancedDialog_q*m_dialog; public: iosAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~iosAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); public slots: }; #endif // __IOSADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/macosxadvanceddialog_q.ui0000644000175000017500000003040311733011756024057 0ustar sylvestresylvestre macosxAdvancedDialog_q 0 0 389 237 MacOS X: advanced settings 6 0 0 0 0 Qt::Vertical QSizePolicy::Expanding 20 20 &OK true true &Cancel true QTabWidget::Rounded 0 Options 0 0 0 0 Generate ICMP redirects Qt::AlignCenter false Packet forwarding Qt::AlignCenter false No change On Off No change On Off No change On Off Forward source routed packets Qt::AlignCenter false Qt::Vertical QSizePolicy::Expanding 151 20 Qt::Vertical QSizePolicy::Expanding 20 20 Qt::Vertical QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 20 40 Path 0 0 0 0 ipfw: Qt::AlignCenter false sysctl: Qt::AlignCenter false Specify directory path and a file name for the following utilities on the OS your firewall machine is running. Leave these empty if you want to use default values. Qt::AlignCenter true 0 0 200 0 0 0 200 0 Qt::Vertical QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 20 40 tabWidget macosx_ip_forward macosx_ip_sourceroute macosx_ip_redirect buttonOk buttonCancel macosx_path_ipfw macosx_path_sysctl buttonOk clicked() macosxAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() macosxAdvancedDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/ruleoptionsdialog_q.ui0000644000175000017500000032420611733011756023471 0ustar sylvestresylvestre RuleOptionsDialog_q 0 0 1412 357 Rule Options for ipt 12 12 0 0 QFrame::Box QFrame::Sunken 1 0 0 12 12 0 0 QTabWidget::Triangular 0 General 12 12 Assume firewall is part of "any" for this rule only: Follow global setting On Off Qt::Horizontal QSizePolicy::MinimumExpanding 40 0 Normally policy compiler uses stateful inspection in each rule. Activating this option makes this rule stateless. Qt::AlignVCenter false Stateless rule Qt::Vertical 20 112 Logging 12 12 0 0 200 32767 alert crit error warning notice info debug 0 0 200 32767 Log prefix: false Log level: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false Qt::Horizontal QSizePolicy::MinimumExpanding 0 20 Netlink group (if using ULOG): false 1 32 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 limit 12 12 Module limit Qt::AlignVCenter true Rate (rule matches if it hits this often or less): false 0 0 99999 0 0 200 32767 /day /hour /minute /second Qt::Horizontal QSizePolicy::Fixed 40 20 Negate Qt::Horizontal QSizePolicy::MinimumExpanding 0 0 Burst: false 10000 Qt::Horizontal 886 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 connlimit 12 12 Module connlimit false Match if the number of existing connections is above this (translates into option --connlimit-above) false 0 0 99999 Qt::Horizontal QSizePolicy::Expanding 40 20 Negate Qt::Horizontal 168 20 0 0 per network with netmask of false 0 0 10000 0 0 bit false Qt::Horizontal QSizePolicy::Expanding 20 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 hashlimit 12 12 12 8 Module hashlimit false Name: false On some older systems this module has name 'dstlimit'. Check here if you need to use this name. Rate: false 0 25 80 32767 99999 0 0 0 25 200 32767 /day /hour /minute /second Burst: false 0 25 80 32767 10000 Qt::Horizontal 108 20 Mode: false 0 0 QFrame::NoFrame QFrame::Raised 12 2 0 2 0 srcip dstip srcport dstport Qt::Horizontal QSizePolicy::Expanding 40 20 QFrame::HLine QFrame::Sunken Qt::Horizontal Options below control size of the hash table and expiration time. They will be omitted from the generated script if set to zero. Qt::AlignVCenter true htable-size: false 0 25 The number of buckets of the hash table (omit this option in generated script if set to 0) 999999 htable-max: false 0 25 Maximum number of entries in the hash (omit this option in generated script if set to 0) 999999 htable-expire: false 0 25 After how many milliseconds do hash entries expire (omit this option in the generated script if set to 0) 999999 htable-gcinterval: false 0 25 How many milliseconds between garbage collection intervals (omit this option in generated script if set to 0) 999999 Qt::Horizontal 268 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 Tag 12 12 Tag service object: false Qt::Horizontal QSizePolicy::Expanding 615 81 0 0 100 80 9 Tag connections created by packets that match this rule (adds a rule with CONNMARK target) Qt::Vertical QSizePolicy::MinimumExpanding 609 108 Classify 12 12 Classify string: false Qt::Horizontal 928 20 Qt::Vertical QSizePolicy::MinimumExpanding 1105 169 Route 12 12 12 Qt::Vertical 20 17 0 0 500 16777215 0 0 QFrame::StyledPanel QFrame::Raised 600 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Option Route has been deprecated.</span></p></body></html> true Use Custom Action in combination with branching rule to create iptables command with '-j ROUTE' target. This works only if the OS running on your firewall supports this iptables target. true Change inbound interface to false Change outbound interface to false Route through gateway false 250 0 Qt::Horizontal 328 17 Qt::Horizontal 373 20 Continue packet inspection Make a copy Qt::Vertical 20 96 12 0 0 QTabWidget::Triangular 0 General 12 12 12 12 Normally policy compiler uses stateful inspection in each rule. Activating next option makes this rule stateless. Qt::AlignVCenter true Stateless rule Send ICMP 'unreachable' packet masquerading as being from the original destination Keep information on fragmented packets, to be applied to later fragments Qt::Vertical 20 100 Logging 12 12 Log facility: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 200 16777215 Qt::Horizontal QSizePolicy::Expanding 20 20 Log level: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 200 16777215 Qt::Vertical QSizePolicy::Expanding 20 30 Route 12 12 12 12 None Route through Route reply through Route a copy through interface false next hop false Qt::Horizontal 548 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 180 12 12 0 0 QTabWidget::Triangular 0 State Tracking Normally policy compiler uses stateful inspection in each rule. Activating this option makes this rule stateless. Force "keep state" to make the rule stateful regardless of the default. Available in OpenBSD 4.5 and later Prevent state changes for states created by this rule from appearing on the pfsync interface. Available in OpenBSD 4.5 and later States created by this rule are exported on the pflow interface. When this option is checked, the number of states per source IP is tracked Activate source tracking. 0 0 300 0 Maximum number of source addresses which can simultaneously have state table entries (max-src-nodes): Qt::AlignVCenter false 0 0 1000000 Qt::Horizontal 40 20 0 0 300 0 Maximum number of simultaneous state entries that a single source address can create with this rule (max-src-states): Qt::AlignVCenter false 0 0 1000000 Qt::Horizontal 40 20 Qt::Vertical 20 60 Logging 12 12 Log prefix: false Qt::Horizontal QSizePolicy::Expanding 301 20 Qt::Vertical QSizePolicy::Expanding 20 51 Limits 12 12 300 0 Maximum number of concurrent states this rule may create. Unlimited if set to zero (option 'max'). Qt::AlignVCenter false When this limit is reached, further packets matching the rule that would create state are dropped, until existing states time out. 1000000 Qt::Horizontal QSizePolicy::Expanding 101 23 Maximum number of simultaneous TCP connections that a single host can make (max-src-conn): Qt::AlignVCenter false 0 0 1000000 Qt::Horizontal QSizePolicy::Expanding 101 23 The limit of new connections over a time interval (max-src-conn-rate): Qt::AlignVCenter false 0 0 80 32767 1000000 / false 0 0 80 32767 1000000 sec false 0 0 overload table: false 100 0 flush global Qt::Horizontal QSizePolicy::Expanding 431 23 Qt::Vertical QSizePolicy::Expanding 22 41 TCP 12 12 Modulate state synproxy Use sloppy TCP state tracker for this rule Qt::Vertical 20 51 Tag 12 12 Tag service object: false 0 0 100 80 9 Qt::Horizontal 982 77 Qt::Vertical QSizePolicy::MinimumExpanding 108 112 Classify 12 12 Classify string: false Qt::Horizontal 948 20 Qt::Vertical 948 169 Route 12 12 None Route through Route reply through Route a copy through interface false next hop false 300 0 Qt::Horizontal 537 20 12 12 Fastroute Qt::Horizontal QSizePolicy::Fixed 40 20 Load Balancing: None Bitmask Random Source Hash Round Robin Qt::Horizontal 665 20 Qt::Vertical QSizePolicy::MinimumExpanding 553 139 2 2 QTabWidget::Triangular 0 State Tracking 12 12 300 0 Normally policy compiler uses stateful inspection in each rule. Activating next option makes this rule stateless. Qt::AlignVCenter false Qt::Horizontal 446 20 Stateless rule Qt::Vertical QSizePolicy::Expanding 20 184 Classify Packet classification can be implemented in different ways: Qt::AlignVCenter false true None dummynet(4) 'pipe' dummynet(4) 'queue' Pipe or queue number: false 80 0 999999 Qt::Horizontal 172 20 Qt::Horizontal 882 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 60 2 2 QFrame::NoFrame QFrame::Raised 12 12 These options are only valid for PIX running software v6.3 or later Qt::AlignVCenter true Qt::Vertical QSizePolicy::Fixed 20 16 completely disable logging for this rule 2 Log level: false Qt::Horizontal QSizePolicy::Expanding 51 20 2 Logging interval: false 600 Qt::Horizontal QSizePolicy::Expanding 51 20 Qt::Vertical QSizePolicy::Expanding 20 20 Compiler can automatically create a rule with mirrored source and destination addresses and service fields. This can be used to match "reply" packets using address and service parameters matched by this rule. The action of the mirrored rule is the same as that of this one. Firewall Builder recognizes the following services and creates "mirrored" versions as follows: true * UDP service: mirrored service has source and destination port ranges reversed * TCP service: mirrored service has source and destination port ranges reversed and "established" flag inverted. If TCP service used in this rule does not have "established" flag, the mirrored service gets it, and the other way around. This is designed to simplify creating ACL rules to permit "reply" TCP packets * ICMP service: ICMP echo request is recognized, mirrored service becomes ICMP echo reply. Other ICMP types are simply copied to the mirrored service * ICMPv6 service: like with ICMP, ICMP echo request is recognized and other ICMPv6 types are just copied * IP service: mirrored service is a copy true Add mirror rule Qt::Vertical 20 73 2 2 Qt::Vertical QSizePolicy::Expanding 20 40 There are no options for this firewall platform Qt::AlignCenter false Qt::Vertical QSizePolicy::Expanding 20 40 FWObjectDropArea QWidget
FWObjectDropArea.h
1
tabw0 ipt_assume_fw_is_part_of_any ipt_stateless ipt_logPrefix ipt_logLevel ipt_nlgroup ipt_limit ipt_limitSuffix ipt_limit_not ipt_burst ipt_connlimit ipt_connlimit_above_not ipt_connlimit_masklen ipt_hashlimit_name ipt_hashlimit_dstlimit ipt_hashlimit ipt_hashlimit_suffix ipt_hashlimit_burst cb_srcip cb_dstip cb_srcport cb_dstport ipt_hashlimit_size ipt_hashlimit_max ipt_hashlimit_expire ipt_hashlimit_gcinterval ipt_mark_connections classify_str ipt_iif ipt_oif ipt_gw ipt_continue ipt_tee tabw1 ipf_stateless ipf_masq_icmp ipf_keep_frags ipf_logFacility ipf_logLevel ipf_route_option ipf_route_opt_if ipf_route_opt_addr tabw2 pf_stateless pf_keep_state pf_no_sync pf_pflow pf_source_tracking pf_max_src_nodes pf_max_src_states pf_logPrefix pf_rule_max_state pf_max_src_conn pf_max_src_conn_rate_num pf_max_src_conn_rate_seconds pf_overload_table pf_flush pf_global pf_modulate pf_synproxy pf_sloppy_tracker pf_classify_str pf_route_option pf_route_opt_if pf_route_opt_addr pf_fastroute pf_route_load_option ipfw_stateless usePortNum pix_disable_rule_log pix_logLevel pix_log_interval iosacl_add_mirror_rule tabWidget ipt_connlimit_above_not clicked() RuleOptionsDialog_q connlimitAboveLabelChange() 868 105 566 162 ipt_limit_not clicked() RuleOptionsDialog_q limitLabelChange() 630 103 566 162 changed() connlimitAboveLabelChange() limitLabelChange()
fwbuilder-5.1.0.3599/src/libgui/SSHSession.cpp0000644000175000017500000005661211733011756021557 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "SSHSession.h" #include "instConf.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 # include #endif //#define STATE_MACHINE_DEBUG 1 using namespace std; const char *SSHSession::newKeyOpenSSH ="Are you sure you want to continue connecting (yes/no)?"; const char *SSHSession::newKeyPlink ="Store key in cache? (y/n)"; const char *SSHSession::newKeyVsh ="Accept and save? (y/n)"; const char *SSHSession::newKeySSHComm ="You can get a public key's fingerprint by running"; const char *SSHSession::fingerprintPrompt1="key fingerprint is"; const char *SSHSession::fingerprintPrompt2="Key fingerprint:"; SSHSession::SSHSession(QWidget *_par, const QString &_h, const QStringList &_args, const QString &_p, const QString &_ep, const list &_in) { parent = _par; host = _h; args = _args; pwd = _p; epwd = _ep; input = _in; quiet = false; verbose = false; closeStdin = false; error = false; endOfCopy = false; send_keepalive = false; session_completed = false; proc = NULL; retcode = 0; heartBeatTimer = new QTimer(this); connect(heartBeatTimer, SIGNAL(timeout()), this, SLOT(heartBeat()) ); newKeyMsg = tr("You are connecting to the firewall '%1' for the first time. It has provided you its identification in a form of its host public key. The fingerprint of the host public key is: \"%2\" You can save the host key to the local database by pressing YES, or you can cancel connection by pressing NO. You should press YES only if you are sure you are really connected to the firewall '%3'."); fwb_prompt=""; quiet=false; verbose=false; backup=false; incremental=false; dry_run=false; stripComments = false; wdir=""; script=""; backupFile=""; save_diff=""; diff_pgm=""; diff_file=""; } QString SSHSession::findKeyFingerprint(QString &buffer) { const char *fp = fingerprintPrompt1; int n1,n2; if ( (n1=buffer.indexOf(fp))==-1) { fp = fingerprintPrompt2; if ( (n1=buffer.indexOf(fp))==-1) return QString(""); } n1 += strlen(fp)+1; n2 = buffer.indexOf("\n", n1+4); return buffer.mid(n1,n2-n1); } void SSHSession::startSession() { proc = new QProcess(); retcode = -1; startHeartBeat(); if (fwbdebug) qDebug("SSHSession::startSession this=%p proc=%p heartBeatTimer=%p", this, proc, heartBeatTimer); connect(proc,SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout() ) ); connect(proc,SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr() ) ); connect(proc,SIGNAL(finished( int, QProcess::ExitStatus )), this, SLOT(finished( int ) ) ); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("latin1")); assert(args.size() > 0); QStringList arguments; QStringList::const_iterator i=args.begin(); QString program = *i; ++i; for ( ; i!=args.end(); ++i) { arguments << *i; //proc->addArgument( *i ); cmd += *i; } QStringList env; #ifdef _WIN32 env.push_back( QString("APPDATA=")+getenv("APPDATA") ); env.push_back( QString("HOMEPATH=")+getenv("HOMEPATH") ); env.push_back( QString("HOMEDRIVE=")+getenv("HOMEDRIVE") ); env.push_back( QString("ProgramFiles=")+getenv("ProgramFiles") ); /* NB: putty absolutely needs SystemRoot env. var. */ env.push_back( QString("SystemRoot=")+getenv("SystemRoot") ); env.push_back( QString("TEMP=")+getenv("TEMP") ); env.push_back( QString("USERNAME=")+getenv("USERNAME") ); env.push_back( QString("USERPROFILE=")+getenv("USERPROFILE") ); env.push_back( QString("HOME=")+getenv("HOMEPATH") ); env.push_back( QString("USER=")+getenv("USERNAME") ); #else env.push_back( QString("HOME=")+getenv("HOME") ); env.push_back( QString("USER=")+getenv("USER") ); #endif env.push_back( QString("TMP=")+getenv("TMP") ); env.push_back( QString("PATH=")+getenv("PATH") ); env.push_back( QString("KRB5CCNAME=")+getenv("KRB5CCNAME") ); env.push_back( QString("SSH_AUTH_SOCK=")+getenv("SSH_AUTH_SOCK") ); // emit printStdout_sign( tr("Running command %1\n").arg(cmd) ); proc->setEnvironment(env); if (fwbdebug) { qDebug("Launch external ssh client %s", program.toAscii().constData()); qDebug("Arguments:"); QStringList::const_iterator i; for (i=arguments.begin(); i!=arguments.end(); ++i) qDebug(" %s", (*i).toAscii().constData()); } proc->start(program, arguments); if ( !proc->waitForStarted() ) { emit printStdout_sign( tr("Failed to start ssh") + "\n" ); return; } if (fwbdebug) qDebug("SSHSession::startSession started child process"); logged_in = false; enable = false; configure = false; state = NONE; } SSHSession::~SSHSession() { if (fwbdebug) qDebug("SSHSession::destructor"); terminate(); if (fwbdebug) qDebug("SSHSession::destructor done"); } /* * this is redundant and wrong. Should just copy a pointer to instConf * object and use that instead of making local copy of each flag. */ void SSHSession::setOptions(instConf *cnf) { setQuiet(cnf->quiet); setVerbose(cnf->verbose); setBackup(cnf->backup); setBackupFile(cnf->backup_file); //setIncr(cnf->incremental); setDryRun(cnf->dry_run); setSaveStandby(cnf->saveStandby); setStripComments(cnf->stripComments); setWDir(cnf->wdir); setScript(cnf->script); setSaveDiff(cnf->save_diff); setDiffPgm(cnf->diff_pgm); setDiffFile(cnf->diff_file); // do not send comments to cisco and procurve devices // We used to provide an option for this on instOptions dialog but // it has been disabled. Possibly we'll re-enable it in the future, but // it seems wasteful to send comments to devices. Besides, Procurve // does not like it anyway. stripComments = true; } void SSHSession::terminate() { if (fwbdebug) qDebug() << "SSHSession::terminate this=" << this << "proc=" << proc << "heartBeatTimer=" << heartBeatTimer; // Ticket #1426, SF bug 2990333. If installation process generates // a lot of output and keeps the GUI busy updating buffers and // progress log display, it becomes possible for the user to hit // Cancel and place corresponding event in the queue after the // process has actually finished but before its signal "finished" // could be processed by the slot SSHSession::terminated(). This // causes problems because we disconnect this signal here so we // never process it anymore. Also, it looks like QProcess does not // change its own state to indicate it is no longer running if its // signal processExited has not been processed. This means that // even though the background process has finished and exited, // QProcess still thinks it is running. We try to send terminate // and then kill signals to it in this function, to no avail. In // the end, the program crashes trying to destroy QProcess object // which still thinks it is running. //qApp->processEvents(); stopHeartBeat(); if (proc != NULL) { if (proc->state() == QProcess::Running) { if (fwbdebug) qDebug() << "SSHSession::terminate " << "waiting for pending signal 'finished()', if any"; // this processes events and lets QProcess send signal finished() // in case user hit Cancel at just right time when background process // already exited but QProcess has not noticed this yet. proc->waitForFinished(100); } // If QProcess sent signal finished() while we were waiting in // waitForFinished(), the signal has been processed in // SSHSession::finished and proc has already been deleted. if (proc == NULL) { if (fwbdebug) qDebug("SSHSession::terminate proc==NULL"); return; } #ifdef _WIN32 if (proc->pid() != NULL) #else if (proc->pid() != -1) #endif { if (proc->state() == QProcess::Running) { Q_PID pid = proc->pid(); if (fwbdebug) qDebug() << "SSHSession::terminate " << "terminating child process pid=" << pid; emit printStdout_sign(tr("Stopping background process")); /* * on windows proc->terminate() posts a WM_CLOSE * message to all toplevel windows of the child * process. However, since our child process is a * console app (ssh client), this does nothing. Need * to use proc->kill() on windows right away to avoid * timeout. */ #ifdef _WIN32 proc->kill(); #else proc->terminate(); #endif if (fwbdebug) qDebug() << "SSHSession::terminate terminate signal sent," << "waiting for it to finish"; int time_to_wait = 20; for (int timeout = 0; proc != NULL && proc->state() == QProcess::Running && timeout < time_to_wait; timeout++) { // print countdown only if we've been waiting more than 3 sec if (timeout > 3) emit printStdout_sign( tr( "Background process is still running. " "Will wait %1 sec").arg(time_to_wait - timeout)); QString s = QString(proc->readAllStandardOutput()); if (!quiet) { s.replace('\r',""); emit printStdout_sign(s); } QApplication::processEvents( QEventLoop::ExcludeUserInputEvents,1); // check if proc is still running after we processed events if (proc != NULL) proc->waitForFinished(1000); } // proc can be NULL at this point if it had sent signal finished() // which we processed in the call to waitForFinished() above if (proc == NULL) { if (fwbdebug) qDebug("SSHSession::terminate proc==NULL"); return; } if (fwbdebug) qDebug() << "SSHSession::terminate " << "Reading last output buffers"; QString s = QString(proc->readAllStandardOutput()); if (!quiet) { s.replace('\r',""); emit printStdout_sign(s); } if (fwbdebug) qDebug() << "SSHSession::terminate done reading I/O buffers. Disconnecting signals"; disconnect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout() ) ); disconnect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr() ) ); disconnect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int) ) ); if (proc->state() == QProcess::Running) { if (fwbdebug) qDebug() << "SSHSession::terminate Still running, killing"; proc->kill(); } } delete proc; proc = NULL; retcode = -1; } } if (fwbdebug) qDebug("SSHSession::terminate done"); } bool SSHSession::checkForErrors() { return true; } void SSHSession::stateMachine() { } /* * signal wroteToStdin is connected to slot readyToSend. Can not send * next line in this slot because on win32 it emits the signal and * thus calls the same slot recursively, without exiting first. On * Linux and Mac it seems to exit and then emit the signal and call * slot on the next pass of the even loop. Since on win32 this does * not happen, need to schedule sending next line via single shot * timer instead of calling it directly. */ void SSHSession::readyToSend() { QTimer::singleShot( 0, this, SLOT(sendLine()) ); } void SSHSession::sendLine() { int n=0; while (input.size()!=0 && n<10) { string s = input.front(); s = s + "\n"; #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug("SSHSession::sendLine : %d lines to go -- %s", int(input.size()), s.c_str()); #endif input.pop_front(); stdoutBuffer=""; /* it is important that we use writeToStdin(QByteArray &) rather than * writeToStdin(QString &) because the latter performs implicit * conversion into local locale assuming the string is in Unicode. The * string in our case is actually in whatever encoding the firewall * script is written to the local filesystem, which may or may not be * UTF-8 but is definitely not Unicode. The conversion not only breaks * comments that were entered in UTF-8, it makes QProcess miscalculate * number of characters in comment lines using UTF-8 which in turns * breaks the script even worse because it glues consequitive lines * together. Apparently this has been fixed in latest versions of QT * 3.x but this is still broken in QT 3.1 which is shipping with * RedHat 9 and some other still popular distributions. Since we need * to support old QT 3.x, the code must work around this problem. */ QByteArray buf; buf = s.c_str(); proc->write/*ToStdin*/(buf); n++; } emit updateProgressBar_sign(input.size(),false); if (input.size()==0) { if (fwbdebug) qDebug("SSHUnx::sendLine - entire file sent, closeStdin=%d", closeStdin); endOfCopy = true; } } void SSHSession::allDataSent() { if (fwbdebug) qDebug("SSHSession::allDataSent closing stdin"); disconnect(proc,SIGNAL(bytesWritten(qint64)),this,SLOT(readyToSend())); #ifdef _WIN32 Sleep(2000); #endif proc->closeWriteChannel(); #ifdef _WIN32 Sleep(1000); #endif readFromStdout(); } void SSHSession::startHeartBeat() { if (fwbdebug) qDebug() << "SSHSession::startHeartBeat" << QTime::currentTime().toString(); heartBeatTimer->start(100); } void SSHSession::stopHeartBeat() { if (fwbdebug) qDebug() << "SSHSession::stopHeartBeat" << QTime::currentTime().toString(); heartBeatTimer->stop(); send_keepalive = false; } void SSHSession::heartBeat() { // if (fwbdebug) // qDebug() << "SSHSession::heartBeat begin" << QTime::currentTime().toString(); if (send_keepalive) proc->write("\n"); readFromStderr(); readFromStdout(); if (endOfCopy && closeStdin) { allDataSent(); endOfCopy = false; } // if (fwbdebug) // qDebug() << "SSHSession::heartBeat end " << QTime::currentTime().toString(); } void SSHSession::readFromStdout() { if (fwbdebug) qDebug() << "SSHSession::readFromStdout" << QTime::currentTime().toString() << "################ proc=" << proc; if (proc) { QByteArray ba = proc->readAllStandardOutput(); int basize = ba.size(); if (basize==0) return; QString buf(ba); /* regex to match minimal set of ANSI terminal codes used by HP Procurve * and Linux if shell prompt is configured to show colors. * * Matches ESC [ n ; m H (move cursor to position), ESC ? 25 l and ESC ? 25 h * (hide and show cursor) and a few others */ QRegExp suppress_ansi_codes( "\x1B\\[((\\d*A)|(\\d*B)|(\\d*C)|(\\d*D)|(\\d*G)|(\\?\\d+l)|(\\d*J)|(2K)|(\\d*;\\d*[fHmr])|(\\?25h)|(\\?25l))"); QRegExp cursor_next_line("\x1B\\d*E"); while (buf.indexOf(suppress_ansi_codes) != -1) buf.replace(suppress_ansi_codes, ""); buf.replace(cursor_next_line, "\n"); stdoutBuffer.append(buf); if (fwbdebug) qDebug() << buf.toAscii().constData() << "\n"; bool endsWithLF = buf.endsWith("\n"); QString lastLine = ""; // split on LF QStringList bufLines = buf.split("\n", QString::KeepEmptyParts); // if buf ends with a LF character, the last element in the list is // an empty string if (endsWithLF && bufLines.last().isEmpty()) bufLines.pop_back(); // if buf does not end with LF, last element in the list is // incomplete line of text if (!endsWithLF) { lastLine = bufLines.last(); bufLines.pop_back(); } if (bufLines.size() > 0) { /* * elements that are left in the list are all complete * lines of text. * * IMPORTANT: QT processes events when we emit signal * here. This means SSHSession::readFromStdout() (this * method) gets called recursively. If we print log lines * one by one, more log lines will be printed after the * first and they end up appearing in a strange order. * * See bug #465 */ QString s = pendingLogLine + bufLines.join("\n"); pendingLogLine = ""; if (!quiet) { s.replace('\r', ""); emit printStdout_sign(s); } } pendingLogLine += lastLine; if (fwbdebug) qDebug() << "SSHSession::readFromStdout" << QTime::currentTime().toString() << "calling stateMachine()"; stateMachine(); } if (fwbdebug) qDebug() << "SSHSession::readFromStdout" << QTime::currentTime().toString() << "---------------- end"; } /* * note: we set qprocess channel mode to "merged" but despite that * QProcess does not seem to merge stdout and stderr on Windows * (QT 4.4.0) * Will merge them here */ void SSHSession::readFromStderr() { if (proc) { QByteArray ba = proc->readAllStandardError(); if (ba.size()!=0) { QString s=QString(ba); if (fwbdebug) qDebug("SSHSession::readFromStderr buf=%s", s.toAscii().constData()); emit printStdout_sign(s); stdoutBuffer.append(s); stateMachine(); } } } /* * See #1699: * * on windows, when ssh session fails because of an authentication * failure or other error, we get two calls to this function: first * with parameter err=true when an error line has been detected * somewhere in the state machine by function checkForErrors() and * then one more time when ssh client process terminates and * SSHSession::finished() calls sessionComplete(). On Windows using * plink and pscp while talking to Cisco ssh client terminates with * return code 0 even when authentication fails. The first call to * sessionComplete() sets session status to "Failure", but since * return code from ssh client was 0, the second call to this function * resets status to "Success". Using flag session_completed to avoid * this reset and use the status set by the first call. * */ void SSHSession::sessionComplete(bool err) { if (fwbdebug) qDebug("SSHSession::sessionComplete err=%d", err); heartBeatTimer->disconnect(SIGNAL(timeout())); if (session_completed) { if (fwbdebug) qDebug("SSHSession::sessionComplete session is already completed"); } else { error = err; if (error) emit sessionFatalError_sign(); else emit sessionFinished_sign(); } if (fwbdebug) qDebug("SSHSession::sessionComplete done"); session_completed = true; } void SSHSession::cleanUp() { disconnect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout() ) ); disconnect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr() ) ); disconnect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int) ) ); delete proc; proc = NULL; } void SSHSession::finished(int retcode) { if (fwbdebug) qDebug("SSHSession::processExited proc=%p retcode=%d", proc, retcode); // background process has exited now, we do not need proc object anymore cleanUp(); //QString exitStatus = (retcode)?QObject::tr("ERROR"):QObject::tr("OK"); emit printStdout_sign(tr("SSH session terminated, exit status: %1") .arg(retcode) + "\n"); sessionComplete( retcode!=0 ); if (fwbdebug) qDebug("SSHSession::processExited done"); } bool SSHSession::cmpPrompt(const QString &str, const QString &prompt) { #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug("SSHSession::cmpPrompt: str='%s' prompt='%s'", str.toAscii().constData(),prompt.toAscii().constData()); #endif bool res = false; if (!str.isEmpty()) { res = (str.lastIndexOf(prompt,-1) != -1); if (!res) { QString s = str.trimmed(); res = (s.lastIndexOf(prompt,-1) != -1); } } #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug("SSHSession::cmpPrompt: res=%d",res); #endif return res; } bool SSHSession::cmpPrompt(const QString &str,const QRegExp &prompt) { #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug("SSHSession::cmpPrompt: str='%s' prompt='%s' (regexp)", str.toAscii().constData(),prompt.pattern().toAscii().constData()); #endif if (str.isEmpty()) return false; bool res=(str.lastIndexOf(prompt,-1)!=-1); #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug("SSHSession::cmpPrompt: res=%d",res); #endif return res; } void SSHSession::sendCommand(const QString &cmd) { stdoutBuffer = ""; if (!dry_run) { proc->write((cmd + "\n").toAscii()); } else { emit printStdout_sign(QString("[DRY RUN] %1\n").arg(cmd)); proc->write("\n"); } } fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator_ops.cpp0000644000175000017500000007120311733011756024052 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "events.h" #include "ObjectManipulator.h" #include "ObjectEditor.h" #include "ObjectTreeViewItem.h" #include "ObjectTreeView.h" #include "newGroupDialog.h" #include "FWObjectClipboard.h" #include "FindObjectWidget.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "FWCmdChange.h" #include "FWCmdAddObject.h" #include "FWCmdDeleteObject.h" #include "FWCmdMoveObject.h" #include "FWBTree.h" #include "FWWindow.h" #include "KeywordsDialog.h" #include "ProjectPanel.h" #include "ConfirmDeleteObjectDialog.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Library.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; /* * this method initiates automatic renaming of children objects if necessary */ void ObjectManipulator::autoRenameChildren(FWObject *obj, const QString &oldName) { if (fwbdebug) qDebug() << "ObjectManipulator::autoRenameChildren changing name " << oldName.toLatin1() << "->" << QString::fromUtf8(obj->getName().c_str()); if (oldName == QString::fromUtf8(obj->getName().c_str())) return; QTreeWidgetItem *itm = allItems[obj]; assert(itm!=NULL); if ((QString::fromUtf8(obj->getName().c_str())!=oldName) && (Host::isA(obj) || Firewall::cast(obj)!=NULL || Interface::isA(obj))) { autorename(obj); } } void ObjectManipulator::autorename(FWObject *obj) { if (fwbdebug) qDebug() << "ObjectManipulator::autorename obj=" << obj->getName().c_str(); if (Host::isA(obj) || Firewall::cast(obj)!=NULL || Cluster::isA(obj)) { list il = obj->getByType(Interface::TYPENAME); for (list::iterator i=il.begin(); i!=il.end(); ++i) autorename(*i); list obj_list = obj->getByType(StateSyncClusterGroup::TYPENAME); for (list::iterator i=il.begin(); i!=il.end(); ++i) autorename(obj_list, StateSyncClusterGroup::TYPENAME, "members"); } if (Interface::isA(obj)) { list subinterfaces = obj->getByType(Interface::TYPENAME); list ipv4_list = obj->getByType(IPv4::TYPENAME); list ipv6_list = obj->getByType(IPv6::TYPENAME); list pa_list = obj->getByType(physAddress::TYPENAME); list failover_list = obj->getByType(FailoverClusterGroup::TYPENAME); list attached_list = obj->getByType(AttachedNetworks::TYPENAME); if (ipv4_list.size() || ipv6_list.size() || pa_list.size() || failover_list.size() || subinterfaces.size() || attached_list.size()) { list vlans; for (list::iterator j=subinterfaces.begin(); j!=subinterfaces.end(); ++j) { Interface *intf = Interface::cast(*j); if (intf->getOptionsObject()->getStr("type") == "8021q") vlans.push_back(intf); } if (vlans.size()) autorenameVlans(vlans); for (list::iterator j=subinterfaces.begin(); j!=subinterfaces.end(); ++j) autorename(*j); autorename(ipv4_list, IPv4::TYPENAME, "ip"); autorename(ipv6_list, IPv6::TYPENAME, "ip6"); autorename(pa_list, physAddress::TYPENAME, "mac"); autorename(failover_list, FailoverClusterGroup::TYPENAME, "members"); autorename(attached_list, AttachedNetworks::TYPENAME, "attached"); } } } void ObjectManipulator::autorename(list &obj_list, const string &objtype, const string &namesuffix) { for (list::iterator j=obj_list.begin(); j!=obj_list.end(); ++j) { FWObject *obj = *j; QString old_name = obj->getName().c_str(); FWObject *parent = obj->getParent(); QString name = getStandardName(parent, objtype, namesuffix); name = makeNameUnique(parent, name, objtype.c_str()); if (name != old_name) { FWCmdChange* cmd = new FWCmdChangeName(m_project, obj); FWObject* new_state = cmd->getNewState(); new_state->setName(string(name.toUtf8())); m_project->undoStack->push(cmd); } } } void ObjectManipulator::autorenameVlans(list &obj_list) { for (list::iterator j=obj_list.begin(); j!=obj_list.end(); ++j) { FWObject *obj = *j; FWObject *parent = obj->getParent(); FWObject *fw = parent; while (fw && Firewall::cast(fw)==NULL) fw = fw->getParent(); assert(fw); QString obj_name = QString::fromUtf8(obj->getName().c_str()); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(fw)); if (int_prop->looksLikeVlanInterface(obj_name)) { // even though we only call this function if the type of // this interface is 8021q, need to check its naming // schema as well. We can't automatically rename // interfaces that do not follow known naming convention. QString base_name; int vlan_id; int_prop->parseVlan(obj_name, &base_name, &vlan_id); if (base_name != "vlan") { QString new_name = QString("%1.%2") .arg(QString::fromUtf8( parent->getName().c_str())) .arg(vlan_id); if (new_name != QString::fromUtf8(obj->getName().c_str())) { FWCmdChange* cmd = new FWCmdChangeName(m_project, obj); FWObject* new_state = cmd->getNewState(); new_state->setName(string(new_name.toUtf8())); m_project->undoStack->push(cmd); } } } } } FWObject* ObjectManipulator::duplicateObject(FWObject *targetLib, FWObject *obj) { if (!isTreeReadWrite(this, targetLib)) return NULL; // we disable copy/cut/paste/duplicate menu items for objects that // can't be copied or duplicated in // ObjectManipulator::getMenuState() but will check here just in // case if (AttachedNetworks::isA(obj)) return NULL; openLib(targetLib); FWObject *new_parent = FWBTree().getStandardSlotForObject( targetLib, obj->getTypeName().c_str()); if (new_parent == NULL) new_parent = obj->getParent(); QString newName = makeNameUnique(new_parent, QString::fromUtf8(obj->getName().c_str()), obj->getTypeName().c_str()); if (!isObjectAllowed(new_parent, obj)) return NULL; return createObject(obj->getTypeName().c_str(), newName, obj); } void ObjectManipulator::moveObject(FWObject *targetLib, FWObject *obj) { FWObject *cl=getCurrentLib(); if (cl==targetLib) return; FWObject *grp = NULL; if (FWObjectDatabase::isA(targetLib)) grp = targetLib; else { grp = FWBTree().getStandardSlotForObject( targetLib, obj->getTypeName().c_str()); } if (grp==NULL) grp=targetLib; if (!grp->isReadOnly()) { map > reference_holders; FWCmdMoveObject *cmd = new FWCmdMoveObject(m_project, obj->getParent(), grp, obj, reference_holders, "Move object"); m_project->undoStack->push(cmd); } if (fwbdebug) qDebug("ObjectManipulator::moveObject all done"); } /* * targetLibName is the name of the target library in Unicode */ void ObjectManipulator::moveObject(const QString &targetLibName, FWObject *obj) { list ll = m_project->db()->getByType( Library::TYPENAME ); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { FWObject *lib=*i; if (targetLibName==QString::fromUtf8(lib->getName().c_str())) { if (fwbdebug) qDebug("ObjectManipulator::moveObject found lib %s", lib->getName().c_str() ); moveObject(lib,obj); } } } FWObject* ObjectManipulator::pasteTo(FWObject *target, FWObject *obj) { map map_ids; return actuallyPasteTo(target, obj, map_ids); } FWObject* ObjectManipulator::actuallyPasteTo(FWObject *target, FWObject *obj, std::map &map_ids) { //FWObject *res = NULL; FWObject *ta = prepareForInsertion(target, obj); if (ta == NULL) return NULL; if (!isObjectAllowed(ta, obj)) return NULL; // we disable copy/cut/paste/duplicate menu items for objects that // can't be copied or duplicated in // ObjectManipulator::getMenuState() but will check here just in // case if (AttachedNetworks::isA(obj)) return NULL; if (fwbdebug) qDebug() << "ObjectManipulator::actuallyPasteTo" << "target=" << target->getPath().c_str() << "ta=" << ta->getPath().c_str(); QString new_name = makeNameUnique( ta, obj->getName().c_str(), obj->getTypeName().c_str()); try { /* clipboard holds a copy of the object */ if (obj->getRoot() != ta->getRoot()) { if (fwbdebug) qDebug("Copy object %s (%d) to a different object tree", obj->getName().c_str(), obj->getId()); FWCmdAddObject *cmd = new FWCmdAddObject(m_project, target, NULL, QObject::tr("Paste object")); FWObject *new_state = cmd->getNewState(); cmd->setNeedTreeReload(true); // recursivelyCopySubtree() needs access to the target tree root // when it copies subtree, so have to copy into the actual target // tree. FWObject *nobj = m_project->db()->recursivelyCopySubtree(target, obj, map_ids); if (new_name != nobj->getName().c_str()) nobj->setName(string(new_name.toUtf8())); target->remove(nobj, false); new_state->add(nobj); m_project->undoStack->push(cmd); return nobj; } Group *grp = Group::cast(ta); if (grp!=NULL && !FWBTree().isSystem(ta)) { if (fwbdebug) qDebug("Copy object %s (%d) to a regular group", obj->getName().c_str(), obj->getId()); /* check for duplicates. We just won't add an object if it is already there */ int cp_id = obj->getId(); list::iterator j; for (j=grp->begin(); j!=grp->end(); ++j) { FWObject *o1=*j; if(cp_id==o1->getId()) return o1; FWReference *ref; if( (ref=FWReference::cast(o1))!=NULL && cp_id==ref->getPointerId()) return o1; } FWCmdChange *cmd = new FWCmdChange( m_project, grp, QObject::tr("Paste object")); //cmd->setNeedTreeReload(false); FWObject *new_state = cmd->getNewState(); new_state->addRef(obj); m_project->undoStack->push(cmd); return obj; } else { /* add a copy of the object to system group , or * add ruleset object to a firewall. */ if (fwbdebug) qDebug("Copy object %s (%d) to a system group, " "a ruleset to a firewall or an address to an interface", obj->getName().c_str(), obj->getId()); FWObject *nobj = m_project->db()->create(obj->getTypeName()); assert(nobj!=NULL); //nobj->ref(); nobj->duplicate(obj, true); if (new_name != nobj->getName().c_str()) nobj->setName(string(new_name.toUtf8())); // If we paste interface, reset the type of the copy // See #299 if (Interface::isA(obj) && Interface::isA(ta)) { Interface *new_intf = Interface::cast(nobj); new_intf->getOptionsObject()->setStr("type", "ethernet"); // see #391 : need to reset "mamagement" flag in the copy // to make sure we do not end up with two management interfaces new_intf->setManagement(false); } FWCmdChange *cmd = new FWCmdAddObject(m_project, ta, nobj, QObject::tr("Paste object")); FWObject *new_state = cmd->getNewState(); // adding object to new_state is reduntant but // FWCmdAddObject supports this for consistency new_state->add(nobj); m_project->undoStack->push(cmd); return nobj; } } catch(FWException &ex) { QMessageBox::warning( this,"Firewall Builder", ex.toString().c_str(), "&Continue", QString::null,QString::null, 0, 1 ); } return NULL; } void ObjectManipulator::lockObject() { if (fwbdebug) qDebug() << "ObjectManipulator::lockObject selected:" << getCurrentObjectTree()->getNumSelected(); if (getCurrentObjectTree()->getNumSelected()==0) return; try { FWObject *obj; vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { obj= *i; FWObject *lib = obj->getLibrary(); // these lbraries are locked anyway, do not let the user // lock objects inside because they won't be able to unlock them. if (lib->getId()!=FWObjectDatabase::STANDARD_LIB_ID) { std::auto_ptr cmd( new FWCmdLockObject(m_project, obj, tr("Lock object ") + QString::fromUtf8(obj->getName().c_str()))); FWObject* new_state = cmd->getNewState(); new_state->setReadOnly(true); if (!cmd->getOldState()->cmp(new_state, true)) m_project->undoStack->push(cmd.release()); } } // Arguably, locking an object should not change lastModified timestamp // because none of the attributes that affect generated policy change. //QCoreApplication::postEvent( // mw, new dataModifiedEvent(m_project->getFileName(), 0)); } catch (FWException &ex) { qDebug() << ex.toString().c_str(); } } void ObjectManipulator::unlockObject() { if (fwbdebug) qDebug() << "ObjectManipulator::unlockObject selected:" << getCurrentObjectTree()->getNumSelected(); if (getCurrentObjectTree()->getNumSelected()==0) return; try { FWObject *obj; vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { obj= *i; FWObject *lib = obj->getLibrary(); if (lib->getId()!=FWObjectDatabase::STANDARD_LIB_ID) { std::auto_ptr cmd( new FWCmdLockObject(m_project, obj, tr("Unlock object ") + QString::fromUtf8(obj->getName().c_str()))); FWObject* new_state = cmd->getNewState(); new_state->setReadOnly(false); if (!cmd->getOldState()->cmp(new_state, true)) m_project->undoStack->push(cmd.release()); } } } catch (FWException &ex) { qDebug() << ex.toString().c_str(); } } void ObjectManipulator::deleteObject(FWObject *obj, QUndoCommand* macro) { bool firstAction = true ; if (fwbdebug) qDebug() << "ObjectManipulator::deleteObject" << "obj=" << obj << "name=" << obj->getName().c_str(); FWObject *object_library = obj->getLibrary(); FWObject *parent = obj->getParent(); FWObject *deleted_objects_lib = m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID ); if (deleted_objects_lib == NULL) { FWObject *dobj = m_project->db()->createLibrary(); dobj->setId(FWObjectDatabase::DELETED_OBJECTS_ID); dobj->setName("Deleted Objects"); dobj->setReadOnly(false); m_project->db()->add(dobj); deleted_objects_lib = dobj; } if (object_library->getId() == FWObjectDatabase::STANDARD_LIB_ID) return; if (obj->isReadOnly()) return; if (obj->getId() == FWObjectDatabase::STANDARD_LIB_ID || obj->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) return; bool is_library = Library::isA(obj); bool is_firewall = Firewall::cast(obj) != NULL; // includes Cluster too bool is_deleted_object = (deleted_objects_lib!=NULL && obj->isChildOf(deleted_objects_lib)); // ruleset_visible == true if 1) we delete firewall object and one of its // rulesets is visible in the project panel, or 2) we delete ruleset object // which is visible in the project panel bool ruleset_visible = ( (is_firewall && m_project->getCurrentRuleSet()->isChildOf(obj)) || (m_project->getCurrentRuleSet() == obj)); mw->findObjectWidget->reset(); QCoreApplication::postEvent( mw, new closeObjectEvent(m_project->getFileName(), obj->getId())); #if 0 // Remove object we are about to delete from the clipboard. // Sequence "delete then paste" is risky if the object is pasted into // a group or rule where only reference is added FWObjectClipboard::obj_clipboard->remove(obj); #endif try { if (fwbdebug) qDebug() << "ObjectManipulator::deleteObject" << "is_library=" << is_library << "is_firewall= " << is_firewall << "ruleset_visible=" << ruleset_visible << "is_deleted_object="<< is_deleted_object; if (is_deleted_object) { unselect(); FWCmdDeleteObject *cmd = new FWCmdDeleteObject( m_project, obj, QString("Delete object"), macro); if (macro==0) m_project->undoStack->push(cmd); return; } if (is_library && obj->isReadOnly()) obj->setReadOnly(false); if (is_library) parent = m_project->db()->getFirstByType(Library::TYPENAME); actuallyDeleteObject(obj, macro); if (ruleset_visible) m_project->closeRuleSetPanel(); } catch (FWException &ex) { if (fwbdebug) qDebug() << "ObjectManipulator::deleteObject:" << "catch: restoreOverrideCursor"; QApplication::restoreOverrideCursor(); QMessageBox::warning( this,"Firewall Builder", ex.toString().c_str(), "&Continue", QString::null,QString::null, 0, 1 ); throw(ex); } if (fwbdebug) qDebug("ObjectManipulator::deleteObject done"); firstAction = false ; } /* * Here we build set of dependencies for @obj, create command to * delete it and push it to the undo stack. */ void ObjectManipulator::actuallyDeleteObject(FWObject *obj, QUndoCommand* macro) { map > reference_holders; UsageResolver().findAllReferenceHolders(obj, m_project->db(), reference_holders); FWObject *deleted_objects_lib = m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID); FWCmdMoveObject *cmd = new FWCmdMoveObject( m_project, obj->getParent(), deleted_objects_lib, obj, reference_holders, QString("Delete object"), macro); if (macro == 0) m_project->undoStack->push(cmd); } void ObjectManipulator::objectMoved(FWObject* obj) { openLibForObject(obj); } void ObjectManipulator::groupObjects() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *co = getCurrentObjectTree()->getSelectedObjects().front(); newGroupDialog ngd(this, m_project->db()); if (ngd.exec()==QDialog::Accepted) { QString objName = ngd.m_dialog->obj_name->text(); QString libName = ngd.m_dialog->libs->currentText(); QString type = ObjectGroup::TYPENAME; if (Service::cast(co)!=NULL) type=ServiceGroup::TYPENAME; if (Interval::cast(co)!=NULL) type=IntervalGroup::TYPENAME; FWObject *parent = NULL; FWObject *newgrp = NULL; list ll = m_project->db()->getByType( Library::TYPENAME ); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { FWObject *lib=*i; if (libName==QString::fromUtf8(lib->getName().c_str())) { /* TODO: need to show a dialog and say that chosen library is * read-only. this is not critical though since newGroupDialog fills * the pull-down only with names of read-write libraries */ if (lib->isReadOnly()) return; parent = FWBTree().getStandardSlotForObject(lib,type); if (parent==NULL) { if (fwbdebug) qDebug("ObjectManipulator::groupObjects(): could not find standard slot for object of type %s in library %s", type.toAscii().constData(),lib->getName().c_str()); return; } newgrp = m_project->db()->create(type.toStdString()); newgrp->setName(string(objName.toUtf8().constData())); break; } } if (newgrp==NULL) return; FWCmdAddObject *cmd = new FWCmdAddObject( m_project, parent, newgrp, QObject::tr("Create new group")); FWObject *new_state = cmd->getNewState(); new_state->add(newgrp); vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) newgrp->addRef(*i); m_project->undoStack->push(cmd); } } static void doKeyword(vector objs, bool doAdd, const string &keyword, ProjectPanel *project) { vector::const_iterator iter; for (iter = objs.begin(); iter != objs.end(); ++iter) { FWObject *obj = *iter; FWCmdChange *cmd = new FWCmdChange(project, obj); FWObject *newObj = cmd->getNewState(); if (doAdd) { newObj->addKeyword(keyword); } else { newObj->removeKeyword(keyword); } if (!obj->cmp(newObj)) { project->undoStack->push(cmd); } else { delete cmd; } } } void ObjectManipulator::addNewKeywordSlot() { QString keyword = QInputDialog::getText(0, tr("Add New Keyword"), tr("Enter new keyword to add to selected objects")); keyword = keyword.simplified(); if (fwbdebug) { qDebug() << "ObjectManipulator::addNewKeyword: " << keyword; } if (!KeywordsDialog::validateKeyword(0, keyword)) return; doKeyword(getCurrentObjectTree()->getSelectedObjects(), true, keyword.toUtf8().constData(), m_project); } void ObjectManipulator::processKeywordSlot() { const QObject *qObj = sender(); if (qObj == 0) return; const QAction *qAct = dynamic_cast(qObj); QStringList list = qAct->data().toStringList(); if (list.size() != 2) return; if (fwbdebug) { qDebug() << "ObjectManipulator::processKeyword:" << list; } doKeyword(getCurrentObjectTree()->getSelectedObjects(), (list[0] == "add"), list[1].toUtf8().constData(), m_project); } void ObjectManipulator::addSubfolderSlot() { const QAction *qAct = dynamic_cast(sender()); if (qAct == 0) return; FWObject *obj = getCurrentObjectTree()->getCurrentObject(); assert(obj->getId() == qAct->data().toInt()); QString folder = QInputDialog::getText(0, tr("Add Subfolder"), tr("Enter new subfolder name")); folder = folder.simplified(); if (folder.isEmpty()) return; if (folder.contains(',')) { QMessageBox::warning(this, "Firewall Builder", tr("Subfolder cannot contain a comma"), "&OK", QString::null, QString::null, 0, 1); return; } /* See if the subfolder already exists */ string folderStr = folder.toUtf8().constData(); set folders = stringToSet(obj->getStr("subfolders")); if (folders.find(folderStr) != folders.end()) return; folders.insert(folderStr); if (fwbdebug) { qDebug() << "ObjectManipulator::addSubfolder: " << folder; } FWCmdAddUserFolder *cmd = new FWCmdAddUserFolder(m_project, obj, folder, tr("Add subfolder")); FWObject *newObj = cmd->getNewState(); newObj->setStr("subfolders", setToString(folders)); m_project->undoStack->push(cmd); } void ObjectManipulator::removeUserFolder() { ObjectTreeViewItem *item = dynamic_cast (getCurrentObjectTree()->currentItem()); if (item == 0 || item->getUserFolderParent() == 0) return; ObjectTreeViewItem *parent = dynamic_cast (item->parent()); assert(parent != 0); vector objs; for (int ii = 0; ii < item->childCount(); ii++) { ObjectTreeViewItem *child = dynamic_cast (item->child(ii)); FWObject *obj = child->getFWObject(); if (obj->getRO()) { QMessageBox::critical(this, "Firewall Builder", tr("Folder with locked object " "cannot be deleted")); return; } objs.push_back(obj); } if (objs.size() > 0) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); ConfirmDeleteObjectDialog confirm(this); confirm.load(objs); QApplication::restoreOverrideCursor(); if (confirm.exec() == QDialog::Rejected) return; } FWCmdMacro *macro = new FWCmdMacro(tr("Delete user folder")); QList children = item->takeChildren(); while (!children.isEmpty()) { ObjectTreeViewItem *child = dynamic_cast (children.takeFirst()); assert(child != 0); FWObject *obj = child->getFWObject(); if (mw->isEditorVisible() && mw->getOpenedEditor() == obj) { mw->hideEditor(); } deleteObject(obj, macro); } FWCmdRemoveUserFolder *cmd = new FWCmdRemoveUserFolder(m_project, parent->getFWObject(), item->getUserFolderName(), "", macro); FWObject *newObj = cmd->getNewState(); set folders = stringToSet(newObj->getStr("subfolders")); folders.erase(item->getUserFolderName().toUtf8().constData()); newObj->setStr("subfolders", setToString(folders)); m_project->undoStack->push(macro); } fwbuilder-5.1.0.3599/src/libgui/BlankDialog.cpp0000644000175000017500000000250011733011756021710 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "BlankDialog.h" using namespace std; using namespace libfwbuilder; BlankDialog::BlankDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::BlankDialog_q; m_dialog->setupUi(this); obj=NULL; } BlankDialog::~BlankDialog() { delete m_dialog; } void BlankDialog::loadFWObject(FWObject *o) { obj = o; } void BlankDialog::validate(bool *res) { *res = true; } void BlankDialog::applyChanges() { } fwbuilder-5.1.0.3599/src/libgui/debugDialog.cpp0000644000175000017500000001152511733011756021756 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "VERSION.h" #include "debugDialog.h" #include "RCS.h" #include "ProjectPanel.h" #include "FWWindow.h" #include #include #include #include #include #include "fwbuilder/Constants.h" #include "fwbuilder/FWObjectDatabase.h" #include using namespace std; using namespace libfwbuilder; debugDialog::debugDialog(QWidget *parent) : QDialog(parent) { m_dialog = new Ui::debugDialog_q; m_dialog->setupUi(this); /* * some variables used for remote debugging (so I can ask the user to * send me a screenshot of the "about" dialog and get the idea about * their environment etc.) */ m_dialog->debugText->append( QString("Path to executable: %1") .arg(argv0.c_str()) ); m_dialog->debugText->append( QString("Path to resources: %1") .arg(Constants::getResourcesDirectory().c_str()) ); m_dialog->debugText->append( QString("Path to locale: %1") .arg(Constants::getLocaleDirectory().c_str()) ); m_dialog->debugText->append( QString("Path to libfwbuilder data directory: %1") .arg(Constants::getDTDDirectory().c_str()) ); m_dialog->debugText->append( QString("appRootDir: %1") .arg(appRootDir.c_str()) ); m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( QString("standard objects library: %1") .arg(Constants::getStandardObjectsFilePath().c_str())); m_dialog->debugText->append( QString("standard templates library: %1") .arg(Constants::getTemplatesObjectsFilePath().c_str())); m_dialog->debugText->append( QString("user name: %1").arg(user_name) ); m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( QString("Path to rcs: %1").arg(RCS_FILE_NAME)); m_dialog->debugText->append( QString("Path to rcsdiff: %1").arg(RCSDIFF_FILE_NAME)); m_dialog->debugText->append( QString("Path to rlog: %1").arg(RLOG_FILE_NAME)); m_dialog->debugText->append( QString("Path to ci: %1").arg(CI_FILE_NAME)); m_dialog->debugText->append( QString("Path to co: %1").arg(CO_FILE_NAME)); m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( "RCS timezone setting:" ); m_dialog->debugText->append( RCS::getRCSEnvFix()->getTZOffset() ); m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( "RCS environment:" ); m_dialog->debugText->append( RCS::getEnv()->join("\n").toAscii() ); m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( QString("Current locale: %1") .arg(QLocale::system().name()) ); m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( QString("Versions:") ); m_dialog->debugText->append( QString(" Firewall Builder %1").arg(VERSION)); m_dialog->debugText->append( QString(" Data format version %1") .arg(libfwbuilder::Constants::getDataFormatVersion().c_str() ) ); m_dialog->debugText->append( QString(" Built with QT %1").arg(QT_VERSION_STR)); m_dialog->debugText->append( QString(" Using QT %1").arg( qVersion() ) ); m_dialog->debugText->append( QString(" Built with libxml2 %1") .arg(LIBXML_DOTTED_VERSION) ); #if !defined(Q_OS_MACX) m_dialog->debugText->append( QString(" Using libxml2 %1").arg(xmlParserVersion)); #endif m_dialog->debugText->append( "\n" ); m_dialog->debugText->append( QString("FWObjectDatabase index statistics:")); if (mw->activeProject()) { int s,h,m; mw->activeProject()->db()->getIndexStats(s,h,m); m_dialog->debugText->append( QString(" index size: %1 records").arg(s) ); m_dialog->debugText->append( QString(" hits: %1").arg(h) ); m_dialog->debugText->append( QString(" misses: %1").arg(m) ); m_dialog->debugText->append( "\n" ); } m_dialog->debugText->append( QString("QPixmapCache limit: %1 kb") .arg(QPixmapCache::cacheLimit())); } debugDialog::~debugDialog() { delete m_dialog; } fwbuilder-5.1.0.3599/src/libgui/FirewallCodeViewer.ui0000644000175000017500000000767711733011756023142 0ustar sylvestresylvestre FirewallCodeViewer_q 0 0 673 510 Firewall code viewer 14 75 true Firewall / ruleset Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 0 0 File: 0 0 Qt::Horizontal 40 20 0 0 Qt::Horizontal 40 20 Close Qt::Horizontal 289 20 pushButton clicked() FirewallCodeViewer_q reject() 337 475 447 408 fileSelector currentIndexChanged(int) FirewallCodeViewer_q fileSelected(int) 90 53 4 78 fileSelected(int) fwbuilder-5.1.0.3599/src/libgui/RuleSetView.h0000644000175000017500000002263511733011756021437 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003-2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef RULESETVIEW_H #define RULESETVIEW_H #include #include #include "fwbuilder/Rule.h" #include "ColDesc.h" using namespace std; namespace libfwbuilder { class FWObject; class Firewall; class FWReference; class RuleElement; class RuleSet; class Policy; class NAT; class Routing; class RuleElement; class RuleElementItf; class NATRule; class RoutingRule; } class ProjectPanel; class FWObjectSelectionModel; class RuleNode; class RuleSetModel; class SelectionMemento { public: SelectionMemento() { rule_id = -1; column = -1; } int rule_id; int column; }; class RuleSetView : public QTreeView { Q_OBJECT; public: RuleSetView(ProjectPanel *project, QWidget *parent); ~RuleSetView(); static RuleSetView* getRuleSetViewByType(ProjectPanel *project, libfwbuilder::RuleSet *ruleset, QWidget *parent); virtual void init(); virtual void initActions(); void selectRE(QModelIndex index); /** * selects rule element a reference 'ref' belongs to */ void selectRE(libfwbuilder::FWReference *ref); /** * makes specified column of a rule current. */ void selectRE(libfwbuilder::Rule *rule, int col); void selectRE(libfwbuilder::Rule *rule, ColDesc::ColumnType type); /** * makes specified rule element current and selects object in it. */ void selectRE(libfwbuilder::RuleElement *re, libfwbuilder::FWObject *obj); void makeCurrentRuleVisible(); void selectObject(int position, int column, int number); void repaintSelection(); void updateAll(); void updateCurrentCell(); void saveCurrentRowColumn(SelectionMemento &memento); void restoreCurrentRowColumn(SelectionMemento &memento); void unselect(); libfwbuilder::FWObject* getSelectedObject(); void moveRule() {} //This method is colled from the class ProjectPanel.cpp:944 void restoreCollapsedGroups(); int getColByType(ColDesc::ColumnType) const; virtual int rowHeight(const QModelIndex&) const; void updateWidget(); void setModel(QAbstractItemModel *model); void addToGroup(bool isAbove); void addRowMenuItemsToMenu(QMenu *menu) const; void addGenericMenuItemsToContextMenu(QMenu *menu) const; int selectedRulesCount() const { return getSelectedRows().size(); } public slots: void showContextMenu(const QPoint&); void insertRule(); void insertNewRuleOnTop(); void insertNewRuleAtBottom(); void addRuleAfterCurrent(); void moveRuleUp(); void moveRuleDown(); void removeRule(); void disableRule(); void enableRule(); void copyRule(); void cutRule(); void pasteRuleAbove(); void pasteRuleBelow(); void renameGroup(); void removeFromGroup(); void newGroup(); void addToGroupAbove(); void addToGroupBelow(); void setColorEmpty(); void setColorRed(); void setColorBlue(); void setColorOrange(); void setColorPurple(); void setColorGray(); void setColorYellow(); void setColorGreen(); void setRuleColor(const QString &c); void itemDoubleClicked(const QModelIndex& index); void editSelected(); void changeDirectionToIn(); void changeDirectionToOut(); void changeDirectionToBoth(); void changeActionToAccept(); void changeActionToDeny(); void changeActionToReject(); void changeActionToAccounting(); void changeActionToPipe(); void changeActionToCustom(); void changeActionToBranch(); void changeActionToContinue(); void changeActionToTranslate(); void changeActionToNATBranch(); void changeLogToOn(); void changeLogToOff(); void negateRE(); void revealObjectInTree(); void findWhereUsedSlot(); void deleteSelectedObject(); void copySelectedObject(); void cutSelectedObject(); void pasteObject(); void saveCollapsedGroups(); void updateAllColumnsSize(); void updateColumnSizeForIndex(QModelIndex); void updateSectionSizesForIndex(QModelIndex, QModelIndex); void updateObject(libfwbuilder::FWObject* object); void compileCurrentRule(); void updateSelectionSensitiveActions(); void setSelectedRows(const QModelIndex firstIndex, const QModelIndex lastIndex); protected: FWObjectSelectionModel *fwosm; virtual void mousePressEvent( QMouseEvent* ev ); virtual void mouseReleaseEvent( QMouseEvent* ev ); virtual void mouseMoveEvent( QMouseEvent* ev ); virtual void dragEnterEvent( QDragEnterEvent *ev); virtual void dropEvent( QDropEvent *ev); virtual void dragMoveEvent( QDragMoveEvent *ev); virtual QDrag* dragObject(); virtual bool event( QEvent * event ); virtual void keyPressEvent( QKeyEvent* ev ); bool validateForInsertion(QModelIndex index, libfwbuilder::FWObject *obj); void deleteObject(QModelIndex index, libfwbuilder::FWObject *obj, QString text, QUndoCommand* makro = 0); bool insertObject(QModelIndex index, libfwbuilder::FWObject *obj, QString text, QUndoCommand* makro = 0); bool validateForInsertion(libfwbuilder::RuleElement *re, libfwbuilder::FWObject *obj, bool quiet=false); bool validateForInsertionToInterfaceRE(libfwbuilder::RuleElementItf *re, libfwbuilder::FWObject *obj); QAction* createAction(QString label, const char* member, const QKeySequence &shortcut = 0); private: //this bool var is needed for starting drag when user moves the mouse //but not when he just clicks selected record bool startingDrag; QAction *compileRuleAction; QAction *removeFromGroupAction; QAction *newGroupAction; QAction *moveRuleUpAction; QAction *moveRuleDownAction; QAction *insertRuleAction; QAction *addRuleAfterCurrentAction; QAction *addToGroupAboveAction; QAction *addToGroupBelowAction; QAction *removeRuleAction; QAction *copyRuleAction; QAction *cutRuleAction; QAction *pasteRuleAboveAction; QAction *pasteRuleBelowAction; QAction *disableRuleAction; QAction *enableRuleAction; QAction *setColorEmptyAction; QAction *setColorRedAction; QAction *setColorBlueAction; QAction *setColorOrangeAction; QAction *setColorPurpleAction; QAction *setColorGrayAction; QAction *setColorYellowAction; QAction *setColorGreenAction; QMenu *popup_menu; libfwbuilder::FWObject *getObject(const QPoint &pos, const QModelIndex &index); libfwbuilder::FWObject *getObject(int number, const QModelIndex &index); int getObjectNumber(libfwbuilder::FWObject *object, const QModelIndex &index); void selectObject(libfwbuilder::FWObject *object, const QModelIndex &index); ProjectPanel* project; void addGroupMenuItemsToContextMenu(QMenu *menu) const; void addChangeColorSubmenu(QMenu *menu) const; void addCommonRowItemsToContextMenu(QMenu *menu) const; void setEnabledRow(bool flag); QModelIndexList getSelectedRows() const; bool isOnlyTopLevelRules(const QModelIndexList &list) const; bool isOneLevelRules(const QModelIndexList &list); void editSelected(const QModelIndex &index); bool switchObjectInEditor(const QModelIndex &index, bool validate=true); void addColumnRelatedMenu(QMenu *menu,const QModelIndex &index, RuleNode *node, const QPoint& pos); void changeDitection(libfwbuilder::PolicyRule::Direction dir); void changeAction(int act); void changeLogging(bool flag); void configureGroups(); bool showToolTip(QEvent *event); void resizeColumns(); void copyAndInsertObject(QModelIndex &index, libfwbuilder::FWObject *object); libfwbuilder::RuleElement* getRE(QModelIndex index); bool canChange(RuleSetModel* md); void insertRule(QModelIndex index, bool isAfter = false); libfwbuilder::FWObject* createInsertTemplate(ProjectPanel* proj_p, int id); void setActionState(QAction *action, bool state); }; class PolicyView : public RuleSetView { public: PolicyView(ProjectPanel *project, libfwbuilder::Policy *p, QWidget *parent); virtual ~PolicyView() {} private: }; class NATView : public RuleSetView { public: NATView(ProjectPanel *project, libfwbuilder::NAT *p, QWidget *parent); virtual ~NATView(){} }; class RoutingView : public RuleSetView { public: RoutingView(ProjectPanel *project, libfwbuilder::Routing *p, QWidget *parent); virtual ~RoutingView() {} }; #endif // RULESETVIEW_H fwbuilder-5.1.0.3599/src/libgui/FirewallInstallerProcurve.cpp0000644000175000017500000001622611733011756024724 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "FirewallInstallerProcurve.h" #include "instDialog.h" #include "SSHPIX.h" #include "SSHIOS.h" #include "SSHProcurve.h" #include "Configlet.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/XMLTools.h" #include #include #include #include using namespace std; using namespace libfwbuilder; FirewallInstallerProcurve::FirewallInstallerProcurve(instDialog *_dlg, instConf *_cnf, const QString &_p): FirewallInstallerCisco(_dlg, _cnf, _p) { } bool FirewallInstallerProcurve::packInstallJobsList(Firewall*) { if (fwbdebug) qDebug("FirewallInstallerProcurve::packInstallJobList script=%s", cnf->script.toAscii().constData()); job_list.clear(); Management *mgmt = cnf->fwobj->getManagementObject(); assert(mgmt!=NULL); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); if (pis->getCommand()!="") { QString cmd = pis->getCommand().c_str(); QString args = pis->getArguments().c_str(); job_list.push_back( instJob(RUN_EXTERNAL_SCRIPT, cmd, args)); inst_dlg->addToLog(QString("Run script %1 %2\n").arg(cmd).arg(args)); return true; } // 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; } #ifdef SCP_SUPPORT_FOR_PROCURVE if (cnf->useSCPForRouter) { QMap all_files; // readManifest() modifies cnf (assigns cnf->remote_script) ! if (readManifest(cnf->script, &all_files)) { QMap::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, "")); } #endif job_list.push_back(instJob(ACTIVATE_POLICY, cnf->script, "")); return true; } void FirewallInstallerProcurve::activatePolicy(const QString&, const QString&) { QStringList args; packSSHArgs(args); if (cnf->verbose) inst_dlg->displayCommand(args); SSHProcurve *ssh_object = NULL; ssh_object = new SSHProcurve(inst_dlg, cnf->fwobj->getName().c_str(), args, cnf->pwd, cnf->epwd, list()); /* * TODO: * the structure of scriptlets (command templates) for PIX and * IOS is nice and generic, it uses generalized "pre_config" * and "post_config" hooks in SSHPIX / SSHIOS classes. Need to * do the same for Unix firewalls. */ QString cmd = ""; QStringList pre_config_commands; QStringList post_config_commands; string version = cnf->fwobj->getStr("version"); string host_os = cnf->fwobj->getStr("host_OS"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); // installer configlets should be different for each OS, but if // some OS can use the same script, it will be placed in the file // under os_family name. For example: // for PIX configlet is in src/res/configlets/pix_os // but since fwsm and pix can use the same script and fwsm_os.xml // declares family as "pix_os", it uses the same configlet. Configlet pre_config(host_os, os_family, "installer_commands_pre_config"); pre_config.removeComments(); // test run and rollback were deprecated in 4.2.0. On Linux, BSD // and PIX rollback was implemented by rebooting firewall which is // too heavy-handed and it did not work on BSD at all. pre_config.setVariable("test", false); pre_config.setVariable("run", true); pre_config.setVariable("schedule_rollback", false); pre_config.setVariable("cancel_rollback", false); pre_config.setVariable("save_standby", cnf->saveStandby); replaceMacrosInCommand(&pre_config); Configlet post_config(host_os, os_family, "installer_commands_post_config"); post_config.removeComments(); post_config.setVariable("test", false); post_config.setVariable("run", true); post_config.setVariable("schedule_rollback", false); post_config.setVariable("cancel_rollback", false); post_config.setVariable("save_standby", cnf->saveStandby); replaceMacrosInCommand(&post_config); ssh_object->loadPreConfigCommands( pre_config.expand().split("\n", QString::SkipEmptyParts) ); ssh_object->loadPostConfigCommands( post_config.expand().split("\n", QString::SkipEmptyParts) ); Configlet activation(host_os, os_family, "installer_commands_reg_user"); activation.removeComments(); replaceMacrosInCommand(&activation); activation.setVariable("using_scp", false); activation.setVariable("not_using_scp", true); if ( ! cnf->useSCPForRouter) { activation.setVariable("fwbuilder_generated_configuration_lines", config_lines.join("\n")); } ssh_object->loadActivationCommands( activation.expand().split("\n", QString::SkipEmptyParts) ); runSSHSession(ssh_object); return; } fwbuilder-5.1.0.3599/src/libgui/instoptionsdialog_q.ui0000644000175000017500000003735611733011756023506 0ustar sylvestresylvestre instOptionsDialog_q 0 0 604 662 0 0 32767 32767 Qt::StrongFocus Install options false 0 0 32767 32767 QFrame::NoFrame QFrame::Plain <p align="center"><b><font size="+2">Install options for firewall '%1'</font></b></p> false 0 0 QFrame::NoFrame QFrame::Plain 0 0 500 50 QFrame::NoFrame QFrame::Plain 0 0 User name: false Qt::Horizontal QSizePolicy::Expanding 20 22 Password or passphrase: false Enable password: false Remember passwords for the duration of the session (passwords are never stored permanently). To enable this option turn it on in Preferences and configure user name used to authenticate to the firewall in the "advanced" settings dialog of the firewall object. Qt::LeftToRight Remember passwords Check this option if you want to install all remaining firewalls automatically using the same user name, password and other parameters. This only works if you use the same user name and password to authenticate to all these firewalls. Qt::AlignVCenter true 0 0 Perform batch install 0 0 false 12 Write configuration to standby PIX Store configuration diff in a file 0 0 0 0 Make a backup copy of the firewall configuration in this file: Qt::AlignVCenter true 0 0 Address that will be used to communicate with the firewall: Qt::AlignVCenter true 200 0 32767 32767 Dry run (commands won't be executed on the firewall) Quiet install: do not print anything as commands are executed on the firewall Verbose: print all commands as they are executed on the firewall Remove comments from configuration Compress script Store a copy of fwb file on the firewall Qt::Vertical 568 37 frame15 PIXgroupBox altAddressLabel altAddress batchInstallText batchInstall copyFWB quiet compressScript test stripComments verbose backupConfigFileLbl backupConfigFile saveDiff saveStandby 0 0 32767 32767 QFrame::NoFrame QFrame::Plain Qt::Horizontal 310 20 Install Cancel Cancel All uname pwd epwd rememberPass backupConfigFile saveDiff saveStandby altAddress okButton cancelButton cancelAllButton okButton clicked() instOptionsDialog_q accept() 262 702 20 20 cancelButton clicked() instOptionsDialog_q reject() 433 702 20 20 cancelAllButton clicked() instOptionsDialog_q cancelAll() 542 809 307 420 batchInstall stateChanged(int) instOptionsDialog_q batchInstallStateChange() 301 573 301 347 cancelAll() testModeToggled() batchInstallStateChange() fwbuilder-5.1.0.3599/src/libgui/LibraryDialog.cpp0000644000175000017500000001001211733011756022262 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "ProjectPanel.h" #include "FWBTree.h" #include "LibraryDialog.h" #include "FWBSettings.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; LibraryDialog::LibraryDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::LibraryDialog_q; m_dialog->setupUi(this); obj=NULL; //layout()->setSizeConstraint(QLayout::SetFixedSize); Qt::WindowFlags flags = windowFlags(); flags &= ~Qt::WindowMaximizeButtonHint; flags &= ~Qt::WindowMinimizeButtonHint; setWindowFlags(flags); connectSignalsOfAllWidgetsToSlotChange(); } LibraryDialog::~LibraryDialog() { delete m_dialog; } void LibraryDialog::loadFWObject(FWObject *o) { obj=o; Library *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->obj_name->setEnabled( obj->getId() != FWObjectDatabase::STANDARD_LIB_ID); // apply->setEnabled( obj->getId() != "syslib000" ); // comment->setEnabled( !m_project->isSystem(obj) ); color=obj->getStr("color").c_str(); if (color=="") color="#FFFFFF"; // white is the default fillColor(); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); m_dialog->colorButton->setEnabled(!o->isReadOnly()); init=false; } void LibraryDialog::changeIds(FWObject *root) { if (FWBTree().isStandardId(root)) root->setId(FWObjectDatabase::generateUniqueId()); for (FWObject::iterator i=root->begin(); i!=root->end(); i++) changeIds( *i ); } void LibraryDialog::applyChanges() { if (FWBTree().isSystem(obj)) return; std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); QString oldcolor = new_state->getStr("color").c_str(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); new_state->setStr("color", color.toLatin1().constData()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void LibraryDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void LibraryDialog::changeColor() { if (!isTreeReadWrite(this,obj)) return; QColor clr = QColorDialog::getColor( QColor(color), this ); if (!clr.isValid()) return; color = clr.name(); fillColor(); emit changed(); } void LibraryDialog::fillColor() { QPixmap pm(40,14); pm.fill( QColor(color) ); QPainter p( &pm ); p.drawRect( pm.rect() ); m_dialog->colorButton->setIcon(QIcon(pm)); } fwbuilder-5.1.0.3599/src/libgui/vlanOnlyIfaceOptsDialog.h0000644000175000017500000000316211733011756023733 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __VLANONLYIFACEOPTSDIALOG_H_ #define __VLANONLYIFACEOPTSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class vlanOnlyIfaceOptsDialog : public QDialog { Q_OBJECT public: vlanOnlyIfaceOptsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~vlanOnlyIfaceOptsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::vlanOnlyIfaceOptsDialog_q *m_dialog; bool cluster_interface; /** validate user input for different interface types */ bool validate(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); void typeChanged(const QString &new_type); }; #endif // __VLANONLYIFACEOPTSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/PrintingController.h0000644000175000017500000000434511733011756023055 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PRINTINGCONTROLLER_HH_ #define __PRINTINGCONTROLLER_HH_ #include "fwbuilder/FWObject.h" #include "printerStream.h" #include "ProjectPanel.h" #include #include class PrintingController { printerStream *pr; public: PrintingController(printerStream *_pr) { pr = _pr; } std::list findAllUsedByType( std::list &result, libfwbuilder::FWObject *obj, const std::string &type_name); int addObjectsToTable(std::list &objects, QTableWidget *tbl, int &row, int &col); bool addObjectsByTypeToTable(libfwbuilder::FWObject *parent, const std::string &type_name, QTableWidget *tbl, int &row, int &col); void findAllGroups(std::list &objects, std::list &groups); void printRuleSet(libfwbuilder::FWObject *fw, const std::string &ruleset_type_name, ProjectPanel *project); void printFirewall(libfwbuilder::FWObject *fw, ProjectPanel *project); void printLegend(bool newPageForSection); void printObjects(libfwbuilder::FWObject *firewall_to_print, bool newPageForSection); void configureQTableForPrint(QTableWidget *tbl); }; #endif fwbuilder-5.1.0.3599/src/libgui/carpOptionsDialog.h0000644000175000017500000000263611733011756022641 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CARPOPTIONSDIALOG_H_ #define __CARPOPTIONSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class carpOptionsDialog : public QDialog { Q_OBJECT public: carpOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~carpOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::carpOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __CARPOPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/pixosAdvancedDialog.cpp0000644000175000017500000001050411733011756023454 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "pixosAdvancedDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; pixosAdvancedDialog::~pixosAdvancedDialog() { delete m_dialog; } pixosAdvancedDialog::pixosAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::pixosAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); /* Page "General" */ data.registerOption( m_dialog->pix_set_host_name, fwoptions, "pix_set_host_name"); data.registerOption( m_dialog->pix_ip_address, fwoptions, "pix_ip_address"); /* Page NTP */ string host_os = o->getStr("host_OS"); if (host_os == "pix_os") { m_dialog->fwsm_ntp_warning->hide(); m_dialog->ntp_servers_group->show(); data.registerOption( m_dialog->ntp1, fwoptions, "pix_ntp1" ); data.registerOption( m_dialog->ntp1_pref, fwoptions, "pix_ntp1_pref" ); data.registerOption( m_dialog->ntp2, fwoptions, "pix_ntp2" ); data.registerOption( m_dialog->ntp2_pref, fwoptions, "pix_ntp2_pref" ); data.registerOption( m_dialog->ntp3, fwoptions, "pix_ntp3" ); data.registerOption( m_dialog->ntp3_pref, fwoptions, "pix_ntp3_pref" ); } if (host_os == "fwsm_os") { m_dialog->fwsm_ntp_warning->show(); m_dialog->ntp_servers_group->hide(); } /* Page SNMP */ data.registerOption( m_dialog->disable_snmp_agent, fwoptions, "pix_disable_snmp_agent"); data.registerOption( m_dialog->set_communities, fwoptions, "pix_set_communities_from_object_data" ); data.registerOption( m_dialog->enable_traps, fwoptions, "pix_enable_snmp_traps" ); data.registerOption( m_dialog->snmp_server1, fwoptions, "pix_snmp_server1" ); data.registerOption( m_dialog->snmp_server2, fwoptions, "pix_snmp_server2" ); data.registerOption( m_dialog->snmp_poll_traps_1, fwoptions, "pix_snmp_poll_traps_1" ); data.registerOption( m_dialog->snmp_poll_traps_2, fwoptions, "pix_snmp_poll_traps_2" ); /* Page Options */ data.registerOption( m_dialog->tcpmss, fwoptions, "pix_tcpmss"); data.registerOption( m_dialog->tcpmss_value, fwoptions, "pix_tcpmss_value"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void pixosAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void pixosAdvancedDialog::reject() { QDialog::reject(); } fwbuilder-5.1.0.3599/src/libgui/platforms.h0000644000175000017500000001456311733011756021231 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PLATFORMS_HH #define _PLATFORMS_HH #include "config.h" // among other things, utils.h defines list which we need here #include "utils.h" #include #include #include #include #include "fwbuilder/Rule.h" #include "fwbuilder/InterfaceData.h" namespace libfwbuilder { class FWOptions; class Firewall; class PolicyRule; class FailoverClusterGroup; class StateSyncClusterGroup; }; void init_platforms(); bool isUsingNetZone(libfwbuilder::Firewall *fw); bool isDefaultPolicyRuleOptions(libfwbuilder::FWOptions *opt); bool isDefaultNATRuleOptions(libfwbuilder::FWOptions *opt); bool isDefaultRoutingRuleOptions(libfwbuilder::FWOptions *opt); void setDefaultFailoverGroupAttributes(libfwbuilder::FailoverClusterGroup *grp); void setDefaultStateSyncGroupAttributes(libfwbuilder::StateSyncClusterGroup *grp); // using list of pairs instead of a map or QMap because maps are dictionaries // and do not preserve order of elements void getVersionsForPlatform(const QString &platform, std::list &list); QString getVersionString(const QString &platform, const QString &version); /* * Get list of supported state synchronization protocols for given * cluster host OS. This is used for the "type" in StateSyncClusterGroup */ void getStateSyncTypesForOS(const QString &host_os, std::list &list); /* * Get list of supported failover protocols for given cluster * host OS. This is used for the "type" in FailoverClusterGroup */ void getFailoverTypesForOS(const QString &host_os, std::list &list); /* * Get list of supported interface types for the "advanced" interface * options dialog. Returns list of string pairs, */ void getInterfaceTypes(libfwbuilder::Interface *iface, std::list &list); /* * Get list of allowed subinterface types for the given interface */ void getSubInterfaceTypes(libfwbuilder::Interface *iface, std::list &list); /* * Fill QComboBox widget with interface types */ void setInterfaceTypes(QComboBox *iface_type, libfwbuilder::Interface *iface, const QString ¤t_type); /** * this method is a collection of heuristics that allow us to assign * a reasonable label to the interface based on firewall platform, * name of the interface, its label and other parameters. */ void guessInterfaceLabel(libfwbuilder::InterfaceData *idata); /** * this method is a collection of heuristics that allow us to make an * educated guess about interface's security level based on the * firewall platform, name of the interface, its label and other * parameters. */ void guessSecurityLevel(const std::string &platform, libfwbuilder::InterfaceData *idata); /** * !!! returns a list of log levels that can be used to populate qcombobox * !!! widget. I do not see how log levels can be different for various * !!! fw platforms, but who knows. */ const QStringList& getLogLevels(const QString &platform); /** * like the above, except returns a list of log facilities. */ const QStringList& getLogFacilities(const QString &platform); /** * returns a list of Actions on reject (mapping list) * */ const QStringList& getActionsOnReject(const QString &platform); /** * returns a list of options for Route action * */ const QStringList& getRouteOptions_pf_ipf(const QString &platform); const QStringList& getRouteLoadOptions_pf(const QString &platform); const QStringList& getClassifyOptions_ipfw(const QString &platform); /** * returns a list of Limit Suffixes (mapping list) */ const QStringList& getLimitSuffixes(const QString &platform); /** * returns a list of screen names from the mapping list that can be * used to populate qcombobox. */ QStringList getScreenNames(const QStringList &sl); /** * finds screen name (i.e. string that can be localized) for the * internal item name s in the mapping list sl */ QString getScreenName(QString s,const QStringList &sl); QString getRuleAction(libfwbuilder::Rule *rule); QString getActionNameForPlatform(libfwbuilder::Firewall *fw, libfwbuilder::Rule *rule); QString getActionNameForPlatform(libfwbuilder::Firewall *fw, const std::string &action); bool getStatelessFlagForAction(libfwbuilder::PolicyRule *rule); QString getReadableRuleElementName(const std::string &platform, const std::string &rule_element_type_name); /* * convenience method that calls Resourcess::getPlatforms() and * converts the result to QMap. If @filter is true, * platforms marked as disabled in global FWBSettings are dropped. */ QMap getAllPlatforms(bool filter=true); QMap getAllOS(bool filter=true); QString readPlatform(QComboBox *platform); QString readHostOS(QComboBox *hostOS); void setPlatform(QComboBox *platform, const QString &pl); void setHostOS(QComboBox *hostOS, const QString &platform, const QString &os); void guessOSAndPlatformFromSysDescr(const QString &sysDescr, QString &platform, QString &hostOS, QString &version); QString findBestVersionMatch(const QString &platform, const QString &discovered_version); /* * Internal: Auxiliary function that copies elements from the list returned by * Resources::getResourceStrList() to the list of string pairs */ void _repackStringList(std::list &list1, std::list &list2); #endif fwbuilder-5.1.0.3599/src/libgui/ObjectListView.h0000644000175000017500000000351111733011756022106 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTLISTVIEW_H_ #define __OBJECTLISTVIEW_H_ #include #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; }; class ObjectListView : public QTreeWidget { Q_OBJECT ; libfwbuilder::FWObjectDatabase *db; bool startingDrag; protected: virtual QDrag* dragObject(); virtual void dragEnterEvent( QDragEnterEvent *ev); virtual void dragMoveEvent( QDragMoveEvent *ev); virtual void dropEvent(QDropEvent *ev); virtual void keyPressEvent( QKeyEvent* ev ); void mousePressEvent ( QMouseEvent * event ); void mouseMoveEvent ( QMouseEvent * event ); bool event ( QEvent * event ); public: ObjectListView(QWidget* parent, const char * name = 0, Qt::WindowFlags f = 0); void setDB(libfwbuilder::FWObjectDatabase *_db) { db = _db; } public slots: void sectionClicked ( int logicalIndex ) ; signals: void delObject_sign(); void dropped(QDropEvent *ev); }; #endif fwbuilder-5.1.0.3599/src/libgui/CompilerOutputPanel.h0000644000175000017500000000332711733011756023171 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILEROUTPUTPANEL_H__ #define __COMPILEROUTPUTPANEL_H__ #include "config.h" #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" #include #include class ProjectPanel; class CompilerOutputPanel : public BaseObjectDialog { Q_OBJECT; libfwbuilder::RoutingRule *rule; Ui::CompilerOutputPanel_q *m_widget; std::list error_re; std::list warning_re; public: CompilerOutputPanel(QWidget* parent); ~CompilerOutputPanel(); public slots: virtual void changed(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void closeEvent(QCloseEvent *e); protected: virtual void resizeEvent ( QResizeEvent * event ); }; #endif fwbuilder-5.1.0.3599/src/libgui/iptAdvancedDialog.cpp0000644000175000017500000002651211733011756023114 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "iptAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "Help.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; iptAdvancedDialog::~iptAdvancedDialog() { delete m_dialog; } iptAdvancedDialog::iptAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::iptAdvancedDialog_q; m_dialog->setupUi(this); obj=o; QStringList slm; string platform = obj->getStr("platform"); string description = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/description"); setWindowTitle(QObject::tr("%1 advanced settings").arg(description.c_str())); FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); if (fwbdebug) qDebug("%s",Resources::getTargetOptionStr( obj->getStr("host_OS"),"user_can_change_install_dir").c_str()); //QString s = fwoptions->getStr("ipv4_6_order") data.registerOption(m_dialog->ipv4before, fwoptions, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") <<"ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first"); data.registerOption(m_dialog->logTCPseq, fwoptions, "log_tcp_seq"); data.registerOption(m_dialog->logTCPopt, fwoptions, "log_tcp_opt"); data.registerOption(m_dialog->logIPopt, fwoptions, "log_ip_opt"); data.registerOption(m_dialog->logNumsyslog, fwoptions, "use_numeric_log_levels"); slm = getLogLevels( obj->getStr("platform").c_str()); m_dialog->logLevel->clear(); m_dialog->logLevel->addItems( getScreenNames(slm)); data.registerOption(m_dialog-> logLevel, fwoptions, "log_level", slm); data.registerOption(m_dialog->useULOG, fwoptions, "use_ULOG"); data.registerOption(m_dialog->cprange, fwoptions, "ulog_cprange"); data.registerOption(m_dialog->qthreshold, fwoptions, "ulog_qthreshold"); data.registerOption(m_dialog->nlgroup, fwoptions, "ulog_nlgroup"); data.registerOption(m_dialog->logprefix, fwoptions, "log_prefix"); slm=getLimitSuffixes( obj->getStr("platform").c_str()); m_dialog->logLimitSuffix->clear(); m_dialog->logLimitSuffix->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> logLimitSuffix, fwoptions, "limit_suffix", slm); data.registerOption(m_dialog->logLimitVal, fwoptions, "limit_value"); data.registerOption(m_dialog->logAll, fwoptions, "log_all"); data.registerOption(m_dialog->compiler, fwoptions, "compiler"); data.registerOption(m_dialog->compilerArgs, fwoptions, "cmdline"); data.registerOption(m_dialog->outputFileName, fwoptions, "output_file"); data.registerOption(m_dialog->fileNameOnFw, fwoptions, "script_name_on_firewall"); data.registerOption(m_dialog->assumeFwIsPartOfAny, fwoptions, "firewall_is_part_of_any_and_networks"); data.registerOption(m_dialog->acceptSessions, fwoptions, "accept_new_tcp_with_no_syn"); data.registerOption(m_dialog->dropInvalid, fwoptions, "drop_invalid"); data.registerOption(m_dialog->logInvalid, fwoptions, "log_invalid"); data.registerOption(m_dialog->acceptESTBeforeFirst, fwoptions, "accept_established"); data.registerOption(m_dialog->bridge, fwoptions, "bridging_fw"); data.registerOption(m_dialog->shadowing, fwoptions, "check_shading"); data.registerOption(m_dialog->emptyGroups, fwoptions, "ignore_empty_groups"); data.registerOption(m_dialog->localNAT, fwoptions, "local_nat"); data.registerOption(m_dialog->clampMSStoMTU, fwoptions, "clamp_mss_to_mtu"); data.registerOption(m_dialog->ipv6NeighborDiscovery, fwoptions, "add_rules_for_ipv6_neighbor_discovery"); slm = getActionsOnReject( obj->getStr("platform").c_str()); m_dialog->actionOnReject->clear(); m_dialog->actionOnReject->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> actionOnReject, fwoptions,"action_on_reject", slm); data.registerOption(m_dialog->useModuleSet, fwoptions, "use_m_set"); data.registerOption(m_dialog->mgmt_ssh, fwoptions, "mgmt_ssh"); data.registerOption(m_dialog->mgmt_addr, fwoptions, "mgmt_addr"); data.registerOption(m_dialog->add_mgmt_ssh_rule_when_stoped, fwoptions, "add_mgmt_ssh_rule_when_stoped"); data.registerOption(m_dialog->addVirtualsforNAT, fwoptions, "manage_virtual_addr"); data.registerOption(m_dialog->configureInterfaces, fwoptions, "configure_interfaces"); data.registerOption(m_dialog->clearUnknownInterfaces, fwoptions, "clear_unknown_interfaces"); data.registerOption(m_dialog->configure_vlan_interfaces, fwoptions, "configure_vlan_interfaces"); data.registerOption(m_dialog->configure_bridge_interfaces, fwoptions, "configure_bridge_interfaces"); data.registerOption(m_dialog->configure_bonding_interfaces, fwoptions, "configure_bonding_interfaces"); data.registerOption(m_dialog->iptDebug, fwoptions, "debug"); data.registerOption(m_dialog->verifyInterfaces, fwoptions, "verify_interfaces"); data.registerOption(m_dialog->loadModules, fwoptions, "load_modules"); data.registerOption(m_dialog->iptablesRestoreActivation, fwoptions, "use_iptables_restore"); data.registerOption(m_dialog->ipt_fw_dir, fwoptions, "firewall_dir"); data.registerOption(m_dialog->ipt_user, fwoptions, "admUser"); data.registerOption(m_dialog->altAddress, fwoptions, "altAddress"); data.registerOption(m_dialog->sshArgs, fwoptions, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwoptions, "scpArgs"); data.registerOption(m_dialog->activationCmd, fwoptions, "activationCmd"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText( pis->getCommand().c_str()); m_dialog->installScriptArgs->setText( pis->getArguments().c_str()); /* page "Prolog/Epilog" */ data.registerOption(m_dialog->prolog_script, fwoptions, "prolog_script"); QStringList prologPlaces_ipt; prologPlaces_ipt.push_back(QObject::tr("on top of the script")); prologPlaces_ipt.push_back("top"); prologPlaces_ipt.push_back(QObject::tr("after interface configuration")); prologPlaces_ipt.push_back("after_interfaces"); // bug #2820840: can't put prolog "after policy reset" if iptables-restore if (!fwoptions->getBool("use_iptables_restore")) { prologPlaces_ipt.push_back(QObject::tr("after policy reset")); prologPlaces_ipt.push_back("after_flush"); } m_dialog->prologPlace->clear(); m_dialog->prologPlace->addItems(getScreenNames(prologPlaces_ipt)); data.registerOption(m_dialog-> prologPlace, fwoptions, "prolog_place", prologPlaces_ipt); data.registerOption(m_dialog->epilog_script, fwoptions, "epilog_script"); data.loadAll(); switchLOG_ULOG(); if (!Resources::getTargetOptionBool( obj->getStr("host_OS"), "user_can_change_install_dir")) { m_dialog->ipt_fw_dir->setEnabled(false); //fwoptions->setStr("firewall_dir", ""); } string version = obj->getStr("version"); bool can_use_module_set = (XMLTools::version_compare(version, "1.4.1.1") >= 0); if (!can_use_module_set) m_dialog->useModuleSet->setChecked(false); m_dialog->useModuleSet->setEnabled(can_use_module_set); m_dialog->tabWidget->setCurrentIndex(0); } void iptAdvancedDialog::switchLOG_ULOG() { m_dialog->useLOG->setChecked(!m_dialog->useULOG->isChecked()); if (m_dialog->useLOG->isChecked()) m_dialog->logTargetStack->setCurrentIndex(0); else m_dialog->logTargetStack->setCurrentIndex(1); } /* * store all data in the object */ void iptAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); /********************* data for fwbd and install script **************/ PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); // find first interface marked as "management" const InetAddr *mgmt_addr = Firewall::cast(obj)->getManagementAddress(); if (mgmt_addr) mgmt->setAddress(*mgmt_addr); pis->setCommand( m_dialog->installScript->text().toLatin1().constData()); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData()); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void iptAdvancedDialog::reject() { QDialog::reject(); } void iptAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->prolog_script->toPlainText(), true, tr( "Script Editor" )); if ( edt.exec() == QDialog::Accepted ) m_dialog->prolog_script->setText( edt.text()); } void iptAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->epilog_script->toPlainText(), true, tr( "Script Editor" )); if ( edt.exec() == QDialog::Accepted ) m_dialog->epilog_script->setText( edt.text()); } void iptAdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Firewall platform: iptables"); h->setSource(QUrl("iptAdvancedDialog.html#" + anchor)); h->show(); h->raise(); } fwbuilder-5.1.0.3599/src/libgui/instDialog.h0000644000175000017500000001664111733011756021316 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INSTDIALOG_H_ #define __INSTDIALOG_H_ #include "config.h" #include #include "instConf.h" #include "fakeWizard.h" #include "instOptionsDialog.h" #include "FirewallInstaller.h" #include "ProjectPanel.h" #include #include #include #include #include #include #include #include #include "fwbuilder/FWObjectDatabase.h" #include "fwcompiler/BaseCompiler.h" class FirewallInstaller; class instBatchOptionsDialog; class QEventLoop; class QTextEdit; class QListViewItem; class QCheckListItem; class QPushButton; class QProgressBar; class QStringList; class QTreeWidgetItem; class QTextCharFormat; //class QCheckTableItem; namespace libfwbuilder { class Firewall; class Cluster; } enum BatchOperation {BATCH_INSTALL, BATCH_COMPILE} ; enum Page1Operation {INST_DLG_COMPILE, INST_DLG_INSTALL, INST_DLG_INSPECT}; enum WizardPageNumber {CHOOSE_OBJECTS=0, COMPILE_INSTALL=1 }; #define FIREWALL_NAME_COLUMN 0 #define COMPILE_CHECKBOX_COLUMN 1 #define INSTALL_CHECKBOX_COLUMN 2 #define LAST_MODIFIED_COLUMN 3 #define LAST_COMPILED_COLUMN 4 #define LAST_INSTALLED_COLUMN 5 class instDialog : public QDialog, public FakeWizard { Q_OBJECT; Ui::instDialog_q *m_dialog; instConf cnf; Page1Operation page_1_op; FirewallInstaller *installer; ProjectPanel *project; instOptionsDialog *inst_opt_dlg; bool compile_only; bool compile_complete; // proc is used to launch external oprocess, such as compiler or // user-defined installer script QProcess proc; QString fwb_prompt; std::list firewalls; std::list clusters; std::list compile_fw_list; std::list::size_type compile_list_initial_size; std::list install_fw_list; std::list::size_type install_list_initial_size; std::map opListMapping; std::list error_re; std::list warning_re; std::map compile_status; QString path; //path of the program to execute // QStringList args; //arguments for that program bool creatingTable; BatchOperation operation; int processedRules; int lastPage; bool stopProcessFlag; bool rejectDialogFlag; bool compileFlag; bool customScriptFlag; bool showSelectedFlag; bool finished; bool onlySelected; bool secondPageVisited; bool canceledAll; QTextCharFormat normal_format; QTextCharFormat error_format; QTextCharFormat warning_format; QTextCharFormat highlight_format; QPushButton *currentSaveButton; QPushButton *currentStopButton; QProgressBar *currentProgressBar; QProgressBar *currentFirewallsBar; QLabel *currentLabel; QLabel *currentFWLabel; QString currentSearchString; void fillCompileSelectList(); void setSelectStateAll(int column, Qt::CheckState); void fillCompileOpList(); void fillCompileUIList(); void fillInstallOpList(); void fillInstallUIList(); bool checkSSHPathConfiguration(libfwbuilder::Firewall*); //libfwbuilder::Firewall *findFirewallbyTableItem(QTableWidgetItem *item); void setSuccessState(QTreeWidgetItem *item); void setFailureState(QTreeWidgetItem *item); void setErrorState(QTreeWidgetItem *item); void setInProcessState(QTreeWidgetItem *item); bool checkIfNeedToCompile(libfwbuilder::Firewall *fw); bool checkIfNeedToInstall(libfwbuilder::Firewall *fw); QTreeWidgetItem *createTreeItem(QTreeWidgetItem* parent, libfwbuilder::Firewall *fw); void setFlags(QTreeWidgetItem* item); virtual void closeEvent(QCloseEvent *event); int findFilesToInspect(QStringList &files); public: instDialog(QWidget *p); virtual ~instDialog(); void summary(); void opSuccess(libfwbuilder::Firewall *fw); void opError(libfwbuilder::Firewall *fw); void opCancelled(libfwbuilder::Firewall *fw); QWidget* page(int n) { return m_dialog->stackedWidget->widget(n); } void displayCommand(const QStringList &args); bool runCompiler(libfwbuilder::Firewall *fw); bool runInstaller(libfwbuilder::Firewall *fw, bool installing_many_firewalls = true); QStringList prepareArgForCompiler(libfwbuilder::Firewall *fw); bool tableHasCheckedItems(); QString getActivationCmd(); void enableStopButton(); void disableStopButton(); void setUpProcessToCompile(); void setUpProcessToInstall(); bool executeCommand(const QString &path, QStringList &args); bool isFinished() { return finished; } protected: virtual void showEvent( QShowEvent *ev); virtual void hideEvent( QHideEvent *ev); bool getInstOptions(libfwbuilder::Firewall *fw, bool installing_many_firewalls = true); void prepareInstConf(libfwbuilder::Firewall *fw); void blockInstallForFirewall(libfwbuilder::Firewall *fw); void readInstallerOptionsFromSettings(); void readInstallerOptionsFromFirewallObject(libfwbuilder::Firewall *fw); void readInstallerOptionsFromDialog(libfwbuilder::Firewall *fw, instOptionsDialog *dlg); bool verifyManagementAddress(); void storeInstallerOptions(); void findFirewalls(); bool isCiscoFamily(); bool isProcurve(); void interpretLogLine(const QString &buf); public slots: void show(ProjectPanel *project, bool install, bool onlySelected, std::set fws); void compilerFinished(int ret_code, QProcess::ExitStatus); void installerFinished(int ret_code, QProcess::ExitStatus); void installerSuccess(); void installerError(); void showPage(const int page); void finishClicked(); void cancelClicked(); void addToLog(const QString &buf); void updateProgressBar(int n,bool setsize); void saveLog(); void inspectFiles(); void readFromStdout(); void selectAllFirewalls(); void deselectAllFirewalls(); void nextClicked(); void backClicked(); void mainLoopCompile(); void mainLoopInstall(); void stopCompile(); void stopInstall(); void tableItemChanged(QTreeWidgetItem * item, int column); void findFirewallInCompileLog(QTreeWidgetItem* item); void logItemClicked(QUrl); signals: void activateRule(ProjectPanel*, QString, QString, int); }; #endif fwbuilder-5.1.0.3599/src/libgui/FirewallInstallerUnx.cpp0000644000175000017500000001330511733011756023664 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "FirewallInstallerUnx.h" #include "instDialog.h" #include "SSHUnx.h" #include "FWWindow.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include #include #include #ifndef _WIN32 # include // for access(2) and getdomainname #endif #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; bool FirewallInstallerUnx::packInstallJobsList(Firewall* fw) { if (fwbdebug) { qDebug() << "FirewallInstallerUnx::packInstallJobList"; qDebug() << "cnf->user=" << cnf->user; } job_list.clear(); inst_dlg->addToLog(QString("Installation plan:\n")); Management *mgmt = cnf->fwobj->getManagementObject(); assert(mgmt!=NULL); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); if (pis->getCommand()!="") { QString cmd = pis->getCommand().c_str(); QString args = pis->getArguments().c_str(); job_list.push_back( instJob(RUN_EXTERNAL_SCRIPT, cmd, args)); inst_dlg->addToLog(QString("Run script %1 %2\n").arg(cmd).arg(args)); return true; } /* read manifest from the conf file */ if (fwbdebug) qDebug("FirewallInstaller::packInstallJobsList read manifest from %s", cnf->script.toAscii().constData()); /* * Note that if output file is specified in firewall settings dialog, * it can be an absolute path. In this case compiler puts additional * generated files (if any) in the same directory. The manifest in the * .fw file does not specify directory path so that the .fw file and * all additional files can be moved together someplace else. We take * dir path from the .fw file and if it is not empty, assume that all * other files are located there as well. */ // compilers always write file names into manifest in Utf8 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); //key: local_file_name val: remote_file_name QMap all_files; // readManifest() modifies cnf ! if (readManifest(cnf->script, &all_files)) { QMap::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)); inst_dlg->addToLog(QString("Copy file: %1 --> %2\n") .arg(local_name) .arg(remote_name).toAscii().constData()); } } else { inst_dlg->opError(fw); return false; } if (job_list.size()==0) { QMessageBox::critical( inst_dlg, "Firewall Builder", tr("Incorrect manifest format in generated script. " "Line with \"*\" is missing, can not find any files " "to copy to the firewall.\n%1").arg(cnf->script), tr("&Continue"), QString::null,QString::null, 0, 1 ); return false; } if (cnf->copyFWB) { QString dest_dir = getDestinationDir(cnf->fwdir); QFileInfo fwbfile_base(cnf->fwbfile); job_list.push_back(instJob( COPY_FILE, fwbfile_base.fileName(), dest_dir)); inst_dlg->addToLog(QString("Copy data file: %1 --> %2\n") .arg(fwbfile_base.fileName()) .arg(dest_dir).toAscii().constData()); } QString cmd = getActivationCmd(); job_list.push_back(instJob(ACTIVATE_POLICY, cmd, "")); inst_dlg->addToLog(QString("Run script %1\n").arg(cmd)); inst_dlg->addToLog(QString("\n")); return true; } // ************************************************************************ void FirewallInstallerUnx::activatePolicy(const QString &cmd, const QString&) { executeSession(cmd); } void FirewallInstallerUnx::executeSession(const QString &cmd) { QStringList args; packSSHArgs(args); args.push_back( cmd ); if (cnf->verbose) inst_dlg->displayCommand(args); inst_dlg->enableStopButton(); qApp->processEvents(); runSSHSession( new SSHUnx(inst_dlg, cnf->fwobj->getName().c_str(), args, cnf->pwd, "", list()), false ); } fwbuilder-5.1.0.3599/src/libgui/ClusterGroupDialog.h0000644000175000017500000000340711733011756022773 0ustar sylvestresylvestre/* * ClusterGroupDialog.h - ClusterGroup object view * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __CLUSTERGROUPDIALOG_H_ #define __CLUSTERGROUPDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include "fwbuilder/FWObject.h" class ProjectPanel; namespace libfwbuilder { class Cluster; } class ClusterGroupDialog : public BaseObjectDialog { Q_OBJECT; libfwbuilder::Cluster *cluster; Ui::ClusterGroupDialog_q *m_dialog; bool enable_master_column; void saveGroupType(libfwbuilder::FWObject *group); public: ClusterGroupDialog(QWidget *parent); ~ClusterGroupDialog(); private: /** flag to indicate that a reload of the obj takes place */ bool reload; /** * add fw/interface link icon to the fwMemberTree * * @param o fwobject to add a link for * @param set_background if true, a different background color is used */ void addIcon(libfwbuilder::FWObject *o, bool set_background = false); public slots: virtual void changed(); virtual void applyChanges(); virtual void validate(bool*); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void openClusterConfDialog(); void openObject(QTreeWidgetItem *item); void objectChanged(); void openParametersEditor(); }; #endif /* __CLUSTERDIALOG_H_ */ fwbuilder-5.1.0.3599/src/libgui/openaisOptionsDialog.h0000644000175000017500000000266611733011756023355 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OPENAISOPTIONSDIALOG_H_ #define __OPENAISOPTIONSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class openaisOptionsDialog : public QDialog { Q_OBJECT public: openaisOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~openaisOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::openaisOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __OPENAISOPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/pagesetupdialog_q.ui0000644000175000017500000001062111733011756023074 0ustar sylvestresylvestre pageSetupDialog_q 0 0 316 235 Page Setup start each section on a new page print header on every page print legend print objects used in rules Scale tables: false 1 200 Qt::Horizontal TextLabel Qt::Vertical 20 38 Qt::Horizontal QSizePolicy::Expanding 40 20 &OK Alt+O true true &Cancel Alt+C false false buttonOk clicked() pageSetupDialog_q accept() 20 20 20 20 buttonCancel clicked() pageSetupDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/instDialog.cpp0000644000175000017500000006132711733011756021652 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "instDialog.h" #include "ProjectPanel.h" #include "FirewallInstaller.h" #include "FWBSettings.h" #include "SSHUnx.h" #include "SSHPIX.h" #include "SSHIOS.h" #include "FWWindow.h" #include "instOptionsDialog.h" #include "instBatchOptionsDialog.h" #include "FirewallCodeViewer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwcompiler/BaseCompiler.h" #ifndef _WIN32 # include // for access(2) and getdomainname #endif #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; instDialog::instDialog(QWidget *p) : QDialog(p) { connect(this, SIGNAL(activateRule(ProjectPanel*, QString, QString, int)), p, SLOT(activateRule(ProjectPanel*, QString, QString, int))); m_dialog = new Ui::instDialog_q; m_dialog->setupUi(this); inst_opt_dlg = NULL; //project = mw->activeProject(); setControlWidgets(this, m_dialog->stackedWidget, m_dialog->nextButton, m_dialog->finishButton, m_dialog->backButton, m_dialog->cancelButton, m_dialog->titleLabel); setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint); list err_re; BaseCompiler::errorRegExp(&err_re); err_re.push_back("(Abnormal[^\n]*)"); err_re.push_back("(fwb_[^:]*: \\S*\\.cpp:\\d{1,}: .*: Assertion .* failed.)"); foreach(string re, err_re) { error_re.push_back(QRegExp(re.c_str(), Qt::CaseInsensitive)); } list warn_re; BaseCompiler::warningRegExp(&warn_re); foreach(string re, warn_re) { warning_re.push_back(QRegExp(re.c_str())); } QTextCursor cursor(m_dialog->procLogDisplay->textCursor()); normal_format = cursor.charFormat(); error_format = normal_format; error_format.setForeground(QBrush(Qt::red)); error_format.setAnchorHref("http://somewhere.com"); error_format.setAnchor(true); // weight must be between 0 and 99. Qt 4.4.1 does not seem to mind if // it is >99 (just caps it) but older versions assert error_format.setProperty(QTextFormat::FontWeight, 99); warning_format = normal_format; warning_format.setForeground(QBrush(Qt::blue)); warning_format.setProperty(QTextFormat::FontWeight, 99); warning_format.setAnchor(true); warning_format.setAnchorHref("http://somewhere.com"); highlight_format = normal_format; highlight_format.setProperty(QTextFormat::FontWeight, 99); currentSaveButton = m_dialog->saveMCLogButton; currentSaveButton->setEnabled(true); currentStopButton = m_dialog->stopButton; currentProgressBar = m_dialog->compProgress; currentFirewallsBar = m_dialog->compFirewallProgress; currentLabel = m_dialog->infoMCLabel; currentFWLabel = m_dialog->fwMCLabel; currentLabel->setText(""); connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()) ); // even though we set channel mode to "merged", QProcess // seems to not merge them on windows. proc.setProcessChannelMode(QProcess::MergedChannels); m_dialog->fwWorkList->setSortingEnabled(true); } /* * list fws is empty when user hits main toolbar button Compile or * Install or uses main menu Rules/Compile or Rules/Install. This list * has firewall objects to be compiled/installed when user uses * "compile-this" or "install-this" button or context menu items * "Compile" or "Install". */ void instDialog::show(ProjectPanel *proj, bool install, bool onlySelected, std::set fws) { canceledAll = false; if (isVisible()) return; lastPage = -1; installer = NULL; finished = false; page_1_op = INST_DLG_COMPILE; compile_complete = false; rejectDialogFlag = false; m_dialog->selectTable->clear(); this->project = proj; compile_only = ! install; m_dialog->warning_space->hide(); m_dialog->procLogDisplay->clear(); firewalls.clear(); clusters.clear(); compile_fw_list.clear(); install_fw_list.clear(); for (int page=0; page < pageCount(); page++) setFinishEnabled(page, false); disableStopButton(); if (!onlySelected) { findFirewalls(); } else { firewalls.clear(); clusters.clear(); foreach(Firewall* fw, fws) { if (Cluster::isA(fw)) clusters.push_back(Cluster::cast(fw)); else firewalls.push_back(fw); } firewalls.sort(FWObjectNameCmpPredicate()); clusters.sort(FWObjectNameCmpPredicate()); m_dialog->saveMCLogButton->setEnabled(true); } if (fwbdebug) qDebug() << "instDialog::show" << "firewalls.size()=" << firewalls.size() << "clusters.size()=" << clusters.size() << "install=" << install; if (firewalls.size()==0 && clusters.size()==0) { setTitle(0, tr("There are no firewalls to process.")); for (int i=0; im_dialog->batchInstall->setChecked(false); if (firewalls.size() == 1 && clusters.size() == 0) m_dialog->selectAllNoneFrame->hide(); else m_dialog->selectAllNoneFrame->show(); //m_dialog->batchInstall->setChecked(false); creatingTable = false; m_dialog->selectTable->setFocus(); m_dialog->selectInfoLabel->setText( QString("

%1

") .arg(tr("Select firewalls to compile."))); if (compile_only) { m_dialog->batchInstFlagFrame->hide(); setAppropriate(2, false); m_dialog->selectTable->hideColumn(INSTALL_CHECKBOX_COLUMN); } else { m_dialog->batchInstFlagFrame->show(); setAppropriate(2, true); m_dialog->selectTable->showColumn(INSTALL_CHECKBOX_COLUMN); } m_dialog->detailMCframe->show(); this->setVisible(true); // we just started, there is nothing to inspect in the workflow of // this wizard yet. This button will be enabled when compile phase is complete m_dialog->inspectGeneratedFiles->setEnabled(compile_complete); showPage(CHOOSE_OBJECTS); } instDialog::~instDialog() { if (inst_opt_dlg != NULL) delete inst_opt_dlg; delete m_dialog; } // ======================================================================== /* * main loop: use lists compile_fw_list and install_fw_list to iterate * all firewalls and do everything. */ void instDialog::mainLoopCompile() { if (finished) return; enableStopButton(); // first compile all if (compile_fw_list.size()) { Firewall *fw = compile_fw_list.front(); compile_fw_list.pop_front(); cnf.clear(); runCompiler(fw); return; } else { // Compile is done or there was no firewalls to compile to // begin with. Check if we have any firewalls to install. Note // that we "uncheck" "install" checkboxes in the first page of // the wizard on compile failure, so we need to rebuild install_fw_list // here. fillInstallOpList(); disableStopButton(); if (compile_only) { compile_complete = true; finished = true; setFinishEnabled(currentPage(), true); this->m_dialog->finishButton->setDefault(true); QStringList files; int n = findFilesToInspect(files); m_dialog->inspectGeneratedFiles->setEnabled(n != 0); } else { compile_complete = true; showPage(COMPILE_INSTALL); // setNextEnabled(currentPage(), true); // setFinishEnabled(currentPage(), false); // m_dialog->inspectGeneratedFiles->setEnabled(compile_complete); } } } void instDialog::mainLoopInstall() { if (fwbdebug) qDebug("instDialog::mainLoopInstall: %d firewalls to install", int(install_fw_list.size())); if (finished) return; enableStopButton(); if (install_fw_list.size() && !canceledAll) { Firewall *fw = install_fw_list.front(); install_fw_list.pop_front(); runInstaller(fw, install_fw_list.size()>0); return; } if (canceledAll) { foreach(Firewall *fw, install_fw_list) { this->opCancelled(fw); } install_fw_list.clear(); } finished = true; setFinishEnabled(currentPage(), true); this->m_dialog->finishButton->setDefault(true); disableStopButton(); } // ======================================================================== void instDialog::showPage(const int page) { // see #1044 Hide batch install label and checkbox once user moves to // the install phase, otherwise it looks confusing. if (page_1_op == INST_DLG_INSTALL) { m_dialog->batchInstFlagFrame->hide(); } QStringList tmp; m_dialog->inspectGeneratedFiles->setEnabled( compile_complete && page_1_op == INST_DLG_COMPILE && findFilesToInspect(tmp)); if (fwbdebug) qDebug() << "instDialog::showPage page " << lastPage << "--->" << page << "page_1_op=" << page_1_op; FakeWizard::showPage(page); switch (page) { case CHOOSE_OBJECTS: // select firewalls for compiling and installing { // if user returned to this page from "compile" page, assume they // want to recompile finished = false; compile_complete = false; fillCompileSelectList(); setAppropriate(1, tableHasCheckedItems()); setNextEnabled(page, tableHasCheckedItems()); m_dialog->selectTable->setFocus(); m_dialog->nextButton->setDefault(true); break; } case COMPILE_INSTALL: { // compile, install firewalls and inspect files, depending on // the value of page_1_op setNextEnabled(page, false); setBackEnabled(page, false); fillCompileOpList(); fillInstallOpList(); // fill install_fw_list if (compile_fw_list.size()==0 && install_fw_list.size()==0) { showPage(CHOOSE_OBJECTS); return; } if (compile_fw_list.size()==0) page_1_op = INST_DLG_INSTALL; m_dialog->stackedWidget->widget(1)->layout()->removeWidget(m_dialog->logFrame); m_dialog->stackedWidget->widget(1)->layout()->addWidget(m_dialog->firewallListFrame); m_dialog->stackedWidget->widget(1)->layout()->addWidget(m_dialog->logFrame); // Page 1 of the wizard does both compile and install // controlled by flag page_1_op. May be it would be less hacky if we // used sepaarte page for installs, but that page would look exactly // like the page for compile switch (page_1_op) { case INST_DLG_COMPILE: { if (fwbdebug) qDebug() << "Page 1 compile" << "compile_complete=" << compile_complete; // run full compile cycle only if we haven't done it before // User may click Back on the "Inspect" page, this should return // them to the "compile" page but not trigger full recompile. // Flag compile_complete is set in instDialog::mainLoopCompile() if (compile_complete) { // See #2037: enable "Next" button only if there is at // least one firewall that was successfully compiled. bool can_install = false; list::iterator i; for(i=compile_fw_list.begin(); i!=compile_fw_list.end(); ++i) { Firewall *fw = *i; if (compile_status[fw] == fwcompiler::BaseCompiler::FWCOMPILER_SUCCESS) { setNextEnabled(page, true); m_dialog->nextButton->setDefault(true); can_install = true; break; } } if (!can_install) setFinishEnabled(page, true); setBackEnabled(page, true); } else { mw->fileSave(); currentFirewallsBar->reset(); currentFirewallsBar->setFormat("%v/%m"); currentFirewallsBar->setMaximum(compile_list_initial_size); m_dialog->procLogDisplay->clear(); fillCompileUIList(); qApp->processEvents(); mainLoopCompile(); } setBackEnabled(page, true); break; } case INST_DLG_INSTALL: { if (fwbdebug) qDebug("Page 1 install"); if (install_fw_list.size() > 0) { currentFirewallsBar->reset(); currentFirewallsBar->setMaximum(install_list_initial_size); m_dialog->procLogDisplay->clear(); fillInstallUIList(); qApp->processEvents(); mainLoopInstall(); } setBackEnabled(page, false); break; } case INST_DLG_INSPECT: { QStringList files; int no_files = findFilesToInspect(files); if (no_files == 0) { QMessageBox::critical(this, tr("Error"), tr("No files were generated, there is nothing to show.")); return; } if (m_dialog->stackedWidget->count() == 3 ) m_dialog->stackedWidget->removeWidget(m_dialog->stackedWidget->widget(2)); FirewallCodeViewer *viewer; if (firewalls.size() == 1) viewer = new FirewallCodeViewer( files, QString("") + firewalls.front()->getName().c_str() + "", this); else viewer = new FirewallCodeViewer( files, tr("Multiple firewalls"), this); viewer->hideCloseButton(); viewer->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); QWidget *container = new QWidget(this); container->setObjectName("codeViewer"); QHBoxLayout *layout = new QHBoxLayout(container); layout->setContentsMargins(0,0,0,0); layout->setSpacing(6); QFrame *frame = new QFrame(container); frame->setLayout(new QHBoxLayout()); frame->layout()->addWidget(viewer); frame->setFrameShape(QFrame::Box); frame->setFrameShadow(QFrame::Plain); frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_dialog->firewallListFrame->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Minimum); m_dialog->progress_page->layout()->removeWidget(m_dialog->firewallListFrame); layout->addWidget(m_dialog->firewallListFrame); layout->addWidget(frame); frame->layout()->setContentsMargins(0,0,0,0); m_dialog->stackedWidget->addWidget(container); m_dialog->stackedWidget->setCurrentIndex(m_dialog->stackedWidget->count()-1); setNextEnabled(page, !compile_only); setBackEnabled(page, true); if (compile_only) m_dialog->finishButton->setDefault(true); else m_dialog->nextButton->setDefault(true); break; } } // end switch(page_1_op) break; } // end case 1: default: { } } lastPage = currentPage(); setCurrentPage(page); } /** * Finds files that were generated for the firewalls scheduled for * compile and fills the list. Returns number of files found. * */ int instDialog::findFilesToInspect(QStringList &files) { QList fwlist; foreach(Firewall *f, firewalls) fwlist.append(f); foreach(Cluster *c, clusters) { std::list cfws; c->getMembersList(cfws); foreach(Firewall *f, cfws) fwlist.append(f); } foreach(Firewall *f, fwlist) { /* * get full path to the generated file. The path is built from * the file name returned by * FirewallInstaller::getGeneratedFileName() and directory * path from the .fwb file. Note that we use the same * algorithm when GUI launches policy compiler, except there * the path is passed to it via "-d" command line option. */ QString mainFile = FirewallInstaller::getGeneratedFileFullPath(f); // QString mainFile = FirewallInstaller::getGeneratedFileName(f); if (!QFile::exists(mainFile)) continue; instConf cnf; cnf.fwobj = f; cnf.script = mainFile; QMap res; FirewallInstaller(NULL, &cnf, "").readManifest(mainFile, &res); foreach(QString item, res.keys()) if (QFile::exists(item)) files.append(item); } return files.size(); } struct CaseInsensitiveComparison : public std::binary_function { bool operator()(libfwbuilder::FWObject *a,libfwbuilder::FWObject *b) { return QString(a->getName().c_str()).toLower() < QString(b->getName().c_str()).toLower(); } }; void instDialog::findFirewalls() { firewalls.clear(); clusters.clear(); if (project) { project->m_panel->om->findAllFirewalls(firewalls); project->m_panel->om->findAllClusters(clusters); } firewalls.sort(CaseInsensitiveComparison()); clusters.sort(CaseInsensitiveComparison()); m_dialog->saveMCLogButton->setEnabled(true); } bool instDialog::checkSSHPathConfiguration(Firewall *fw) { if (fwbdebug) qDebug("instDialog::checkSSHPathConfiguration"); customScriptFlag = false; Management *mgmt = fw->getManagementObject(); assert(mgmt!=NULL); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); /* we don't care about ssh settings if external installer is to be used */ if ( pis->getCommand()=="" && ( st->getSSHPath().isEmpty() || st->getSCPPath().isEmpty())) { QMessageBox::critical(this, "Firewall Builder", tr("Policy installer uses Secure Shell to communicate with the firewall.\n" "Please configure directory path to the secure shell utility \n" "installed on your machine using Preferences dialog"), tr("&Continue") ); addToLog("Please configure directory path to the secure \n " "shell utility installed on your machine using \n" "Preferences dialog\n"); return false; } return true; } bool instDialog::isCiscoFamily() { string platform = cnf.fwobj->getStr("platform"); return (platform=="pix" || platform=="fwsm" || platform=="iosacl"); } bool instDialog::isProcurve() { string platform = cnf.fwobj->getStr("platform"); return (platform=="procurve_acl"); } /* * "uncheck" checkbox in the "install" column to make sure we do not * try to install this firewall. Used in instDialog_compile on failure. */ void instDialog::blockInstallForFirewall(Firewall *fw) { if (Cluster::isA(fw)) { list members; Cluster::cast(fw)->getMembersList(members); for (list::iterator it=members.begin(); it!=members.end(); ++it) blockInstallForFirewall(*it); } else { QList items = m_dialog->selectTable->findItems("*", Qt::MatchWildcard); QList::iterator i; for (i=items.begin(); i!=items.end(); ++i) { int obj_id = (*i)->data(0, Qt::UserRole).toInt(); if (obj_id == fw->getId()) (*i)->setCheckState(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked); } } } void instDialog::setUpProcessToCompile() { connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()) ); // even though we set channel mode to "merged", QProcess // seems to not merge them on windows. proc.setProcessChannelMode(QProcess::MergedChannels); proc.disconnect(SIGNAL(finished(int,QProcess::ExitStatus))); connect(&proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(compilerFinished(int,QProcess::ExitStatus)) ); } void instDialog::setUpProcessToInstall() { connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()) ); // even though we set channel mode to "merged", QProcess // seems to not merge them on windows. proc.setProcessChannelMode(QProcess::MergedChannels); proc.disconnect(SIGNAL(finished(int,QProcess::ExitStatus))); connect(&proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(installerFinished(int,QProcess::ExitStatus)) ); } /* * This method is used to launch compiler AND user-defined external * installation script. */ bool instDialog::executeCommand(const QString &path, QStringList &args) { // set codecs so that command line parameters can be encoded QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); enableStopButton(); QTime start_time; start_time.start(); proc.start(path, args); if ( !proc.waitForStarted() ) { QProcess::ProcessError err = proc.error(); opError(cnf.fwobj); addToLog( tr("Error: Failed to start program") ); addToLog(path); addToLog( tr("Last error:") ); switch (err) { case QProcess::FailedToStart: addToLog( tr("The process failed to start") ); addToLog(QString("PATH: %1").arg(getenv("PATH"))); break; case QProcess::Crashed: addToLog( tr("The process crashed some time after starting successfully.") ); break; case QProcess::Timedout: addToLog( tr("The last waitFor...() function timed out. Elapsed time: %1 ms").arg(start_time.elapsed()) ); break; case QProcess::WriteError: addToLog( tr("An error occurred when attempting to write to the process.") ); break; case QProcess::ReadError: addToLog( tr("An error occurred when attempting to read from the process. ") ); break; default: addToLog( tr("An unknown error occurred.") ); break; } addToLog( tr("Current state of QProcess:") ); switch (proc.state()) { case QProcess::NotRunning: addToLog(tr("The process is not running.")); break; case QProcess::Starting: addToLog(tr("The process is starting, but the program has not yet been invoked.")); break; case QProcess::Running: addToLog(tr("The process is running and is ready for reading and writing.")); break; } //blockInstallForFirewall(cnf.fwobj); return false; } return true; } fwbuilder-5.1.0.3599/src/libgui/physaddressdialog_q.ui0000644000175000017500000001172211733011756023433 0ustar sylvestresylvestre PhysAddressDialog_q true 0 0 746 208 physAddress QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Physical address (MAC): false 0 0 Qt::Vertical 20 70 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name pAddress obj_name editingFinished() PhysAddressDialog_q changed() 20 20 20 20 pAddress editingFinished() PhysAddressDialog_q changed() 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/WorkflowIcons.ui0000644000175000017500000001135311733011756022210 0ustar sylvestresylvestre WorkflowIcons_q 0 0 777 556 Form Qt::Vertical 20 210 20 Qt::Horizontal 40 20 120 120 PointingHandCursor Create new firewall :/Icons/firewall_64.png:/Icons/firewall_64.png 64 64 Qt::ToolButtonTextUnderIcon 120 120 PointingHandCursor Import existing configuration :/Icons/Import-big:/Icons/Import-big 64 64 Qt::ToolButtonTextUnderIcon 120 120 PointingHandCursor Watch "Getting Started" tutorial :/Icons/Tutorial:/Icons/Tutorial 64 64 Qt::ToolButtonTextUnderIcon Qt::Horizontal 40 20 Qt::Vertical 20 210 fwbuilder-5.1.0.3599/src/libgui/openbsdAdvancedDialog.h0000644000175000017500000000267611733011756023424 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OPENBSDADVANCEDDIALOG_H_ #define __OPENBSDADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class openbsdAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::openbsdAdvancedDialog_q *m_dialog; public: openbsdAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~openbsdAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __OPENBSDADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/PrefsDialog.h0000644000175000017500000000467311733011756021422 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PREFSDIALOG_H_ #define __PREFSDIALOG_H_ #include "config.h" #include #include "FWBSettings.h" #include "HttpGet.h" #include #include #include #include #include class QPushButton; class QTreeWidgetItem; class PrefsDialog : public QDialog { Q_OBJECT void setButtonColor(QPushButton *btn,const QString &colorCode); void changeColor(QPushButton *btn,FWBSettings::LabelColors colorCode); std::map colors; Ui::prefsDialog_q *m_dialog; HttpGet current_version_http_getter; QFont rulesFont; QFont treeFont; QFont uiFont; QFont compilerOutputFont; void changeFont(QFont &font); public: PrefsDialog(QWidget *parent); ~PrefsDialog(); QString getFontDescription(const QFont &font); public slots: virtual void accept(); virtual void findWDir(); virtual void findDataDir(); virtual void findSSH(); virtual void findSCP(); virtual void changeRedColor(); virtual void changeOrangeColor(); virtual void changeYellowColor(); virtual void changeGreenColor(); virtual void changeBlueColor(); virtual void changePurpleColor(); virtual void changeGrayColor(); virtual void changeIconSize25(); virtual void changeIconSize16(); virtual void changeShowIcons(); virtual void changeRulesFont(); virtual void changeTreeFont(); virtual void changeCompilerOutputFont(); virtual void checkSwUpdates(); virtual void checkForUpgrade(const QString&); virtual void objTooltipsEnabled(bool); }; #endif // __PREFSDIALOG_H fwbuilder-5.1.0.3599/src/libgui/ICMPServiceDialog.cpp0000644000175000017500000000700611733011756022740 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "ProjectPanel.h" #include "FWBTree.h" #include "ICMPServiceDialog.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include #include #include #include #include #include #include #include #include #include "FWWindow.h" using namespace std; using namespace libfwbuilder; ICMPServiceDialog::ICMPServiceDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::ICMPServiceDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } ICMPServiceDialog::~ICMPServiceDialog() { delete m_dialog; } void ICMPServiceDialog::loadFWObject(FWObject *o) { obj=o; ICMPService *s = dynamic_cast(obj); assert(s!=NULL); // if (ICMP6Service::isA(o)) // { // m_dialog->editorTitle->setText("ICMP6 Service"); // m_dialog->editorLabel->setPixmap( // QPixmap(QString::fromUtf8(":/Icons/ICMP6Service/icon"))); // } else // { // m_dialog->editorTitle->setText("ICMP Service"); // m_dialog->editorLabel->setPixmap( // QPixmap(QString::fromUtf8(":/Icons/ICMPService/icon"))); // } init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->icmpType->setValue( s->getInt("type") ); m_dialog->icmpCode->setValue( s->getInt("code") ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->icmpType->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->icmpType); m_dialog->icmpCode->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->icmpCode); init=false; } void ICMPServiceDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void ICMPServiceDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); new_state->setInt("type", m_dialog->icmpType->value() ); new_state->setInt("code", m_dialog->icmpCode->value() ); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/FWWindow.h0000644000175000017500000002473311733011756020726 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWWINDOW_H_ #define __FWWINDOW_H_ //#include //#include #include "RCS.h" #include "HttpGet.h" #include "printerStream.h" #include "ObjectEditor.h" #include "instDialog.h" #include #include #include #include #include #include #include class ObjectManipulator; class ObjectTreeView; class ProjectPanel; class QMdiArea; class QMdiSubWindow; class QPrinter; class QTabWidget; class QTextEdit; class QTimer; class QTreeWidgetItem; class QDockWidget; class QUndoGroup; class RuleSetView; class findDialog; class FindObjectWidget; class FindWhereUsedWidget; class CompilerOutputPanel; namespace Ui { class FWBMainWindow_q; class pageSetupDialog_q; }; namespace libfwbuilder { class FWObjectDatabase; class Firewall; class PolicyRule; class RuleSet; class Rule; class FWObject; class FWReference; }; #define MAXRECENTFILES 5 #define EDITOR_PANEL_EDITOR_TAB 2 #define EDITOR_PANEL_SEARCH_TAB 1 #define EDITOR_PANEL_OUTPUT_TAB 0 class FWWindow : public QMainWindow { Q_OBJECT; Ui::pageSetupDialog_q *psd; QMdiArea *m_space; QMdiSubWindow *previous_subwindow; instDialog *instd; HttpGet *current_version_http_getter; QString noFirewalls; QWidget *editorOwner; QPrinter *printer; libfwbuilder::FWObject *searchObject; libfwbuilder::FWObject *replaceObject; //int lastFirewallIdx; QStringList openDocFiles; bool auto_load_from_rcs_head_revision; QAction *recentFileActs[MAXRECENTFILES]; QAction *openRecentSeparatorAct; QAction *undoAction; QAction *redoAction; void clearFirewallTabs(); ProjectPanel *newProjectPanel(); void showSub(ProjectPanel *projectW); void attachEditorToProjectPanel(ProjectPanel *pp); QList ruleStaticActions; public: QVector windowsTitles; QVector windowsPainters; // Passwords are cached to this map if user enables remember password. // Key is QPair // and value is QPair QMap, QPair > passwords; ObjectEditor *oe; FindObjectWidget *findObjectWidget; FindWhereUsedWidget *findWhereUsedWidget; QUndoGroup *undoGroup; ProjectPanel* activeProject(); void updateWindowTitle(); void updateTreeFont(); void updateRecentFileActions(); void updateOpenRecentMenu(const QString &fileName); void updateGlobalToolbar(); void setupGlobalToolbar(); void enableBackAction(); public slots: void selectActiveSubWindow (/*const QString & text*/); void subWindowActivated(QMdiSubWindow*); void editorPanelTabChanged(int); void minimize(); void maximize(); virtual void search(); virtual void restoreRuleSetTab(); virtual void editFind(); virtual void toggleViewObjectTree(); virtual void toggleViewEditor(); virtual void toggleViewUndo(); virtual void helpContents(); virtual void helpContentsAction(); virtual void helpIndex(); virtual void help(); virtual void showReleaseNotes(); virtual void fileNew(); virtual void fileOpen(); virtual void openRecentFile(); virtual void clearRecentFilesMenu(); virtual void fileClose(); virtual void fileSave(); virtual void fileSaveAs(); virtual void fileDiscard(); virtual void fileCommit(); virtual void fileImport(); virtual void fileExport(); virtual void filePrint(); virtual void fileExit(); virtual void fileProp(); virtual void fileAddToRCS(); virtual void fileCompare(); virtual void editCopy(); virtual void editCut(); virtual void editDelete(); virtual void editPaste(); virtual void editPrefs(); virtual void importPolicy(); virtual void startupLoad(); virtual void helpAbout(); virtual void debug(); virtual void compile(std::set vf); virtual void compile(); virtual void install(std::set vf); virtual void install(); virtual void inspect(); virtual void insertRule(); virtual void addRuleAfterCurrent(); virtual void moveRule(); virtual void moveRuleUp(); virtual void moveRuleDown(); virtual void removeRule(); virtual void copyRule(); virtual void cutRule(); virtual void pasteRuleAbove(); virtual void pasteRuleBelow(); virtual void newObject(); virtual void lockObject(); virtual void unlockObject(); virtual void prepareEditMenu(); virtual void prepareViewMenu(); virtual void prepareObjectMenu(); virtual void prepareFileMenu(); virtual void prepareToolsMenu(); virtual void prepareWindowsMenu(); virtual void prepareFileOpenRecentMenu(); virtual void prepareRulesMenu(); virtual void cleanRulesMenu(); virtual void toolsImportAddressesFromFile(); virtual void toolsSNMPDiscovery(); virtual void checkForUpgrade(const QString&); virtual void projectWindowClosed(); void tableResolutionSettingChanged(int ); void activateRule(ProjectPanel*, QString, QString, int); void undoViewVisibilityChanged(bool); public: Ui::FWBMainWindow_q *m_mainWindow; FWWindow(); ~FWWindow(); RCS * getRCS(); void registerAutoOpenDocFile(const QString &file_name, bool load_from_rcs_head); void load(QWidget *dialogs_parent,RCS *rcs); void load(QWidget *dialogs_parent); void loadLibrary(const std::string &libfpath); bool loadFile(const QString &filename, bool load_rcs_head); void save(); bool checkin(bool unlock); int findFirewallInList(libfwbuilder::FWObject *f); QStringList getListOfOpenedFiles(); QMdiSubWindow* alreadyOpened(const QString &file_path); bool editingLibrary(); QString chooseNewFileName(const QString &fname, const QString &title); void setFileName(const QString &fname); bool saveIfModified(); /** * selects whatever is current in rules */ void selectRules(); void disableActions(bool havePolicies); void setCompileAndInstallActionsEnabled(bool en); void setEnabledAfterRF(); QString getCurrentFileName(); void setupAutoSave(); void findObject(libfwbuilder::FWObject *); void findWhereUsed(libfwbuilder::FWObject *obj, ProjectPanel *pp); bool exportLibraryTest(std::list &selectedLibs); void exportLibraryTo(QString fname,std::list &selectedLibs, bool rof); void findExternalRefs(libfwbuilder::FWObject *lib, libfwbuilder::FWObject *root, std::list &extRefs); void setSafeMode(bool f); void setStartupFileName(const QString &fn); libfwbuilder::FWObject* getCurrentLib(); libfwbuilder::FWObject* createObject(const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL); libfwbuilder::FWObject* createObject(libfwbuilder::FWObject *parent, const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL); void moveObject(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); void moveObject(const QString &targetLibName, libfwbuilder::FWObject *obj); ObjectTreeView* getCurrentObjectTree(); void findAllFirewalls (std::list &fws); void showDeletedObjects(bool f); // void select(); // void unselect(); QPrinter* getPrinter(); libfwbuilder::FWObjectDatabase* db(); QString printHeader(); static void printFirewallFromFile(QString fileName, QString firewallName, QString outputFileName); /** * show text string on status bar for 1 sec */ void showStatusBarMessage(const QString &txt); //wrapers for some Object Editor functions bool isEditorVisible(); void showEditor(); void hideEditor(); void closeEditor(); void clearEditorAndSearchPanels(); void openEditor(libfwbuilder::FWObject *o); void openOptEditor(libfwbuilder::FWObject *, ObjectEditor::OptType t); void blankEditor(); libfwbuilder::FWObject* getOpenedEditor(); ObjectEditor::OptType getOpenedOptEditor(); virtual void closeEditorPanel(); virtual void openEditorPanel(); bool requestEditorOwnership(QWidget *w, libfwbuilder::FWObject *o, ObjectEditor::OptType otype, bool validate = true); void singleRuleCompile(libfwbuilder::Rule *rule); void buildEditorTitleAndIcon(libfwbuilder::FWObject *obj, ObjectEditor::OptType t, QString *title_txt, QPixmap *pm, bool include_file_name); void showIntroDialog(); void addNewObjectMenu(QMenu*); void showNewObjectMenu(); protected: virtual void showEvent(QShowEvent *ev); virtual void hideEvent(QHideEvent *ev); virtual void closeEvent(QCloseEvent *ev); virtual bool event(QEvent *event); protected slots: void activatePreviousSubWindow(); }; #endif fwbuilder-5.1.0.3599/src/libgui/InterfacesTabWidget.cpp0000644000175000017500000001615411733011756023431 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "InterfacesTabWidget.h" #include "ui_InterfacesTabWidget.h" using namespace libfwbuilder; InterfacesTabWidget::InterfacesTabWidget(QWidget *parent) : QTabWidget(parent), m_ui(new Ui::InterfacesTabWidget) { m_ui->setupUi(this); clusterMode = false; clear(); connect(&newInterface, SIGNAL(clicked()), this, SLOT(addNewInterface())); connect(&delInterface, SIGNAL(clicked()), this, SLOT(closeTab())); newInterface.setIcon(QIcon(":/Icons/add.png")); delInterface.setIcon(QIcon(":/Icons/del.png")); newInterface.setToolTip(tr("Add new interface")); delInterface.setToolTip(tr("Delete current interface")); this->setCornerWidget(&delInterface, Qt::TopRightCorner); this->setCornerWidget(&newInterface, Qt::TopLeftCorner); this->cornerWidget(Qt::TopRightCorner)->show(); this->cornerWidget(Qt::TopLeftCorner)->show(); noTabs = true; } InterfacesTabWidget::~InterfacesTabWidget() { delete m_ui; } void InterfacesTabWidget::changeEvent(QEvent *e) { QTabWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } QMap InterfacesTabWidget::getData() { QMap res; for ( int i = 0; i < this->count(); i++ ) { InterfaceEditorWidget *w = dynamic_cast( this->widget(i)); if (w == NULL || w->getInterface() == NULL) continue; InterfaceEditorWidget *intEditor = dynamic_cast( this->widget(i)); if (intEditor != NULL) res[intEditor->getInterface()] = intEditor->getInterfaceData(); } return res; } QList InterfacesTabWidget::getNewData() { QList res; for ( int i = 0; i < this->count(); i++ ) { InterfaceEditorWidget *w = dynamic_cast( this->widget(i)); if ( w != NULL && w->getInterface() == NULL) res.append(w->getInterfaceData()); } return res; } QList InterfacesTabWidget::getDeletedInterfaces() { return deleted; } void InterfacesTabWidget::addInterface(Interface *iface) { if (noTabs) { this->removeTab(0); noTabs = false; this->delInterface.setEnabled(true); } InterfaceEditorWidget *w = new InterfaceEditorWidget(this, iface); w->setClusterMode(clusterMode); this->addTab(w, iface->getName().c_str()); } void InterfacesTabWidget::addNewInterface() { if (noTabs) { this->removeTab(0); noTabs = false; this->delInterface.setEnabled(true); } InterfaceEditorWidget *w = new InterfaceEditorWidget(this); w->setClusterMode(clusterMode); w->setHostOS(host_OS); addTab(w, ""); // deliberately create new interface with blank name setCurrentIndex(count() - 1); } void InterfacesTabWidget::setTemplate(FWObject* obj) { currentTemplate = obj; } void InterfacesTabWidget::clear() { while ( this->count() ) this->removeTab(0); this->addNewInterface(); } void InterfacesTabWidget::closeTab() { if (noTabs) return; int idx = this->currentIndex(); QWidget *w = this->widget(idx); Interface *iface = dynamic_cast(w)->getInterface() ; if ( iface != NULL ) deleted.append( iface ); this->removeTab(idx); delete w; if (this->count() == 0) { noTabs = true; QString text; if (!this->clusterMode) text = tr("This firewall has no interfaces. Add interface using button ."); else text = tr("This cluster has no interfaces. Add interface using button ."); QLabel *label = new QLabel(text, this); label->setAlignment(Qt::AlignCenter); this->addTab(label, tr("No interfaces")); this->delInterface.setEnabled(false); } } bool InterfacesTabWidget::isValid() { for (int i = 0; i< this->count(); i++) { InterfaceEditorWidget* w = dynamic_cast( this->widget(i)); if (w == NULL) continue; if (!w->isValid()) { this->setCurrentWidget(w); w->showError(); return false; } } return true; } void InterfacesTabWidget::setCornerWidgetsVisible(bool st) { this->cornerWidget(Qt::TopRightCorner)->setVisible(st); this->cornerWidget(Qt::TopLeftCorner)->setVisible(st); } void InterfacesTabWidget::addInterfaceFromData(InterfaceData* idata) { InterfaceEditorWidget *w = new InterfaceEditorWidget(this); w->setData(idata); addTab(w, idata->name.c_str()); } void InterfacesTabWidget::addTab(QWidget* widget, const QString& title) { if ( dynamic_cast(widget) != NULL || (noTabs && dynamic_cast(widget) != NULL)) { widget->setObjectName(title+"_widget"); if (!noTabs) dynamic_cast(widget)->setExplanation(explanation); QTabWidget::addTab(widget, title); } } void InterfacesTabWidget::setClusterMode(bool st) { clusterMode = st; for ( int i = 0; i < this->count() ; i++ ) { InterfaceEditorWidget *w = dynamic_cast( this->widget(i)); if (w!=NULL) w->setClusterMode(st); } newInterface.setVisible(!st); delInterface.setVisible(!st); } void InterfacesTabWidget::addClusterInterface(ClusterInterfaceData data) { InterfaceEditorWidget *w = new InterfaceEditorWidget(this, data); w->setClusterMode(true); this->addTab(w, data.name); } void InterfacesTabWidget::setExplanation(const QString& text) { explanation = text; for( int i = 0; i < this->count(); i++ ) { InterfaceEditorWidget* w = dynamic_cast( this->widget(i)); if (w!=NULL) w->setExplanation(text); } } void InterfacesTabWidget::setHostOS(const QString &s) { host_OS = s; for ( int i = 0; i < this->count(); i++ ) { InterfaceEditorWidget *w = dynamic_cast( this->widget(i)); if (w != NULL) w->setHostOS(host_OS); } } fwbuilder-5.1.0.3599/src/libgui/CommentEditorPanel.cpp0000644000175000017500000000450111733011756023275 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "CommentEditorPanel.h" #include "FWBSettings.h" #include "ObjectManipulator.h" #include "FWWindow.h" #include "FWCmdRule.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; CommentEditorPanel::~CommentEditorPanel() { delete m_widget; } CommentEditorPanel::CommentEditorPanel(QWidget *p) : BaseObjectDialog(p) { m_widget = new Ui::CommentEditorPanel_q; m_widget->setupUi(this); rule=NULL; } QString CommentEditorPanel::text() { return m_widget->editor->toPlainText(); } void CommentEditorPanel::setText(QString s) { m_widget->editor->setText(s); } void CommentEditorPanel::changed() { emit changed_sign(); } void CommentEditorPanel::applyChanges() { std::auto_ptr cmd( new FWCmdRuleChangeComment(m_project, rule)); // new_state is a copy of the rule object FWObject* new_state = cmd->getNewState(); new_state->setComment( string(m_widget->editor->toPlainText().toUtf8().constData()) ); if (!cmd->getOldState()->cmp(new_state, true)) m_project->undoStack->push(cmd.release()); } void CommentEditorPanel::loadFWObject(FWObject *obj) { Rule *r = Rule::cast(obj); rule = r; setText(QString::fromUtf8(r->getComment().c_str())); } void CommentEditorPanel::validate(bool* b) { *b=true; } fwbuilder-5.1.0.3599/src/libgui/ClickableLabel.h0000644000175000017500000000045111733011756022022 0ustar sylvestresylvestre#ifndef CLICKABLELABEL_H #define CLICKABLELABEL_H #include class ClickableLabel : public QLabel { Q_OBJECT public: ClickableLabel(QWidget *parent = 0, Qt::WindowFlags f = 0 ); void mousePressEvent(QMouseEvent *); signals: void clicked(); }; #endif // CLICKABLELABEL_H fwbuilder-5.1.0.3599/src/libgui/linksysAdvancedDialog.cpp0000644000175000017500000001177711733011756024023 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "linksysAdvancedDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; linksysAdvancedDialog::~linksysAdvancedDialog() { delete m_dialog; } linksysAdvancedDialog::linksysAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::linksysAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); /* * since v2.0.3 we do not need to know shell prompt on linksys. Will * remove the page completely when code becomes stable. */ m_dialog->tabWidget->removeTab( 1 ); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); /* set default prompts */ if (fwopt->getStr("prompt1").empty()) Resources::os_res["sveasoft"]->Resources::setDefaultOption(fwopt, "/FWBuilderResources/Target/options/default/prompt1"); if (fwopt->getStr("prompt2").empty()) Resources::os_res["sveasoft"]->Resources::setDefaultOption(fwopt, "/FWBuilderResources/Target/options/default/prompt2"); data.registerOption( m_dialog->linksys_prompt1, fwopt, "prompt1" ); data.registerOption( m_dialog->linksys_prompt2, fwopt, "prompt2" ); data.registerOption( m_dialog->linksys_path_iptables, fwopt, "linux24_path_iptables" ); data.registerOption( m_dialog->linksys_path_ip, fwopt, "linux24_path_ip" ); data.registerOption( m_dialog->linksys_path_lsmod, fwopt, "linux24_path_lsmod" ); data.registerOption( m_dialog->linksys_path_logger, fwopt, "linux24_path_logger" ); data.registerOption( m_dialog->linksys_path_modprobe, fwopt, "linux24_path_modprobe" ); data.registerOption( m_dialog->linksys_path_vconfig, fwopt, "linksys_path_vconfig"); data.registerOption( m_dialog->linksys_path_brctl, fwopt, "linksys_path_brctl"); data.registerOption( m_dialog->linksys_path_ifenslave, fwopt, "linksys_path_ifenslave"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void linksysAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void linksysAdvancedDialog::reject() { QDialog::reject(); } void linksysAdvancedDialog::setDefaultPrompts() { FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); m_dialog->linksys_prompt1->setText( Resources::getTargetOptionStr("sveasoft","default/prompt1").c_str() ); m_dialog->linksys_prompt2->setText( Resources::getTargetOptionStr("sveasoft","default/prompt2").c_str() ); } fwbuilder-5.1.0.3599/src/libgui/linux24AdvancedDialog.cpp0000644000175000017500000002113011733011756023614 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "linux24AdvancedDialog.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "Help.h" using namespace std; using namespace libfwbuilder; linux24AdvancedDialog::~linux24AdvancedDialog() { delete m_dialog; } linux24AdvancedDialog::linux24AdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::linux24AdvancedDialog_q; m_dialog->setupUi(this); obj=o; string host_os = obj->getStr("host_OS"); string description = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/description"); setWindowTitle(QObject::tr("%1 advanced settings").arg(description.c_str())); FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption( m_dialog->linux24_log_martians, fwopt, "linux24_log_martians", threeStateMapping); data.registerOption( m_dialog->linux24_accept_redirects, fwopt, "linux24_accept_redirects", threeStateMapping); data.registerOption( m_dialog->linux24_icmp_echo_ignore_all, fwopt, "linux24_icmp_echo_ignore_all", threeStateMapping); data.registerOption( m_dialog->linux24_icmp_echo_ignore_broadcasts, fwopt, "linux24_icmp_echo_ignore_broadcasts", threeStateMapping); data.registerOption( m_dialog->linux24_icmp_ignore_bogus_error_responses, fwopt, "linux24_icmp_ignore_bogus_error_responses", threeStateMapping); data.registerOption( m_dialog->linux24_ip_dynaddr, fwopt, "linux24_ip_dynaddr", threeStateMapping); data.registerOption( m_dialog->linux24_rp_filter, fwopt, "linux24_rp_filter", threeStateMapping); data.registerOption( m_dialog->linux24_accept_source_route, fwopt, "linux24_accept_source_route", threeStateMapping); data.registerOption( m_dialog->linux24_ip_forward, fwopt, "linux24_ip_forward", threeStateMapping); data.registerOption( m_dialog->linux24_ipv6_forward, fwopt, "linux24_ipv6_forward", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_fin_timeout, fwopt, "linux24_tcp_fin_timeout" ); data.registerOption( m_dialog->linux24_tcp_keepalive_interval, fwopt, "linux24_tcp_keepalive_interval"); data.registerOption( m_dialog->linux24_tcp_window_scaling, fwopt, "linux24_tcp_window_scaling", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_sack, fwopt, "linux24_tcp_sack", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_fack, fwopt, "linux24_tcp_fack", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_ecn, fwopt, "linux24_tcp_ecn", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_syncookies, fwopt, "linux24_tcp_syncookies", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_timestamps, fwopt, "linux24_tcp_timestamps", threeStateMapping); data.registerOption( m_dialog->linux24_path_iptables, fwopt, "linux24_path_iptables" ); data.registerOption( m_dialog->linux24_path_ip6tables, fwopt, "linux24_path_ip6tables" ); data.registerOption( m_dialog->linux24_path_ip, fwopt, "linux24_path_ip"); data.registerOption( m_dialog->linux24_path_lsmod, fwopt, "linux24_path_lsmod"); data.registerOption( m_dialog->linux24_path_logger, fwopt, "linux24_path_logger"); data.registerOption( m_dialog->linux24_path_vconfig, fwopt, "linux24_path_vconfig"); data.registerOption( m_dialog->linux24_path_brctl, fwopt, "linux24_path_brctl"); data.registerOption( m_dialog->linux24_path_ifenslave, fwopt, "linux24_path_ifenslave"); data.registerOption( m_dialog->linux24_path_modprobe, fwopt, "linux24_path_modprobe"); data.registerOption( m_dialog->linux24_path_ipset, fwopt, "linux24_path_ipset"); data.registerOption( m_dialog->linux24_path_iptables_restore, fwopt, "linux24_path_iptables_restore"); data.registerOption( m_dialog->linux24_path_ip6tables_restore, fwopt, "linux24_path_ip6tables_restore"); data.registerOption(m_dialog->conntrack_max, fwopt, "linux24_conntrack_max"); data.registerOption(m_dialog->conntrack_hashsize, fwopt, "linux24_conntrack_hashsize"); data.registerOption(m_dialog->conntrack_tcp_be_liberal, fwopt, "linux24_conntrack_tcp_be_liberal", threeStateMapping); data.registerOption(m_dialog->linux24_data_dir, fwopt, "data_dir"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void linux24AdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); if (!Firewall::cast(cmd->getOldState())->getOptionsObject()->cmp(fwoptions, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void linux24AdvancedDialog::reject() { QDialog::reject(); } void linux24AdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Host type Linux 2.4/2.6"); h->setSource(QUrl("linux24AdvancedDialog.html#" + anchor)); h->raise(); h->show(); } fwbuilder-5.1.0.3599/src/libgui/InterfaceEditorWidget.ui0000644000175000017500000002214711733011756023620 0ustar sylvestresylvestre InterfaceEditorWidget 0 0 434 359 Form Name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 25 Label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 25 Type: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Static IP address Dynamic IP address Unnumbered interface Qt::Horizontal QSizePolicy::Minimum 48 20 0 0 Add address Qt::Horizontal 228 23 50 IP Address Netmask Type Remove explanation text true 0 0 Failover protocol: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::Horizontal 298 20 0 0 Comment: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 0 40 16777215 70 name label type comment protocol addresses name textEdited(QString) InterfaceEditorWidget nameEdited(QString) 140 31 6 69 addAddress clicked() InterfaceEditorWidget addNewAddress() 289 456 289 238 type currentIndexChanged(int) InterfaceEditorWidget typeChanged(int) 139 123 4 168 addresses cellChanged(int,int) InterfaceEditorWidget addressChanged(int,int) 53 430 3 314 protocol currentIndexChanged(QString) InterfaceEditorWidget protocolChanged(QString) 102 309 5 278 nameEdited(QString) closeTab(int) addNewAddress() typeChanged(int) addressChanged(int,int) addressChanged(int,int,int,int) protocolChanged(QString) fwbuilder-5.1.0.3599/src/libgui/ClickableLabel.cpp0000644000175000017500000000031111733011756022350 0ustar sylvestresylvestre#include "ClickableLabel.h" ClickableLabel::ClickableLabel(QWidget * parent, Qt::WindowFlags) { setParent(parent); } void ClickableLabel::mousePressEvent ( QMouseEvent *) { emit clicked(); } fwbuilder-5.1.0.3599/src/libgui/tcpservicedialog_q.ui0000644000175000017500000006011411733011756023250 0ustar sylvestresylvestre TCPServiceDialog_q true 0 0 884 265 0 0 TCP QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken 0 0 Name: false 200 0 0 0 0 0 QGroupBox { margin-top: 0px; padding-top: 1ex; padding-bottom: 0px; } 2 10 4 0 0 0 0 0 0 U false TCP flags that must be set (see man iptables, option --tcp-flags) Settings: false 0 0 0 0 0 0 0 0 0 0 R false 0 0 P false 0 0 0 0 TCP flags that should be examined (see man iptables, option --tcp-flags) Mask: false 0 0 0 0 0 0 Flags: false 0 0 0 0 A false 0 0 S false 0 0 0 0 F false 0 0 Option "established" can be used if supported by the target firewall platform Established Qt::Vertical QSizePolicy::Expanding 172 70 0 0 QFrame::Box QFrame::Sunken 8 2 8 2 2 6 QGroupBox { margin-top: 1ex; padding-top: 1ex; padding-bottom: 0px; padding-left: 2px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; padding: 0 3px; } QSpinBox { margin: 0px; padding: 0px; } Source Port Range 2 2 QAbstractSpinBox::UpDownArrows 65535 QAbstractSpinBox::UpDownArrows 65535 Start: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false End: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QGroupBox { margin-top: 1ex; padding-top: 1ex; padding-bottom: 0px; padding-left: 2px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; padding: 0 3px; } QSpinBox { margin: 0px; padding: 0px; } Destination Port Range 2 2 QAbstractSpinBox::UpDownArrows 65535 QAbstractSpinBox::UpDownArrows 65535 Start: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false End: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::Vertical 20 40 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name ss se ds de urg_m urg_s ack_m ack_s psh_m psh_s rst_m rst_s syn_m syn_s fin_m fin_s established toggled(bool) TCPServiceDialog_q toggleEstablished() 46 246 20 20
fwbuilder-5.1.0.3599/src/libgui/MDIEventFilter.h0000644000175000017500000000034711733011756021776 0ustar sylvestresylvestre#ifndef MDIEVENTFILTER_H #define MDIEVENTFILTER_H #include #include class MDIEventFilter : public QObject { Q_OBJECT protected: bool eventFilter(QObject *obj, QEvent *event); }; #endif // MDIEVENTFILTER_H fwbuilder-5.1.0.3599/src/libgui/groupobjectdialog_q.ui0000644000175000017500000002530611733011756023430 0ustar sylvestresylvestre GroupObjectDialog_q true 0 0 934 245 0 0 Group 0 0 QFrame::Box QFrame::Sunken QGroupBox { margin: 0px; padding: 4px; } true 2 0 Qt::Horizontal 31 26 0 0 20 0 I true true true false 0 0 20 0 L true true 100 false 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 ArrowCursor Qt::Vertical QSizePolicy::Fixed 20 10 New Object Create New Object Create new object and add to this group :/Icons/newobject_25.png:/Icons/newobject_25.png false Qt::Horizontal 40 20 Qt::Vertical 20 18 250 0 250 100 true 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name ObjectListView.h iconViewBtn clicked() GroupObjectDialog_q switchToIconView() 20 20 20 20 listViewBtn clicked() GroupObjectDialog_q switchToListView() 20 20 20 20 newButton clicked() GroupObjectDialog_q newObject() 168 161 466 122 newObject()
fwbuilder-5.1.0.3599/src/libgui/RuleGroupPanel.h0000644000175000017500000000240611733011756022117 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include class RuleSetView ; class RuleGroupPanel : public QFrame, public Ui::RuleGroupPanel { Q_OBJECT public: int row ; RuleSetView * rsv ; RuleGroupPanel (QWidget * parent,RuleSetView * rsv, int row) ; public slots: void showHideRuleGroup(); public: virtual void mousePressEvent ( QMouseEvent * event ); virtual void mouseDoubleClickEvent ( QMouseEvent * event) ; }; fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator_tree_ops.cpp0000644000175000017500000006234111733011756025074 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include "listOfLibrariesModel.h" #include "ObjectManipulator.h" #include "ObjectEditor.h" #include "ObjectTreeViewItem.h" #include "ObjectTreeView.h" #include "FWObjectClipboard.h" #include "FWObjectPropertiesFactory.h" #include "FWBSettings.h" #include "newFirewallDialog.h" #include "newClusterDialog.h" #include "newHostDialog.h" #include "findDialog.h" #include "newGroupDialog.h" #include "FindObjectWidget.h" #include "AskLibForCopyDialog.h" #include "FindWhereUsedWidget.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "events.h" #include "FWCmdChange.h" #include "FWCmdAddObject.h" #include "FWCmdMoveObject.h" #include "IconSetter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DialogFactory.h" #include "FWBTree.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "ConfirmDeleteObjectDialog.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Host.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Interface.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Management.h" #include #include #include #include using namespace std; using namespace libfwbuilder; #define OBJTREEVIEW_WIDGET_NAME "ObjTreeView" /* * This method decides what should be shown in the columns 0 and 1 of * the tree for the given object */ QString ObjectManipulator::getTreeLabel(FWObject *obj, int col) { switch (col) { case 0: { QString name = QString::fromUtf8(obj->getName().c_str()); if (Interface::isA(obj)) { Interface *intf = Interface::cast(obj); QString label = QString::fromUtf8(intf->getLabel().c_str()); if (label.isEmpty()) return name; else return QString("%1 (%2)").arg(name).arg(label); } else return name; break; } case 1: return FWObjectPropertiesFactory::getObjectPropertiesBrief(obj); } return ""; } void ObjectManipulator::expandObjectInTree(FWObject *obj) { FWObject *o = FWReference::getObject(obj); if (fwbdebug) qDebug() << "ObjectManipulator::expandObjectInTree" << "o=" << QString::fromUtf8(o->getName().c_str()); //if (FWReference::cast(o)!=NULL) o = FWReference::cast(o)->getPointer(); QTreeWidgetItem *it = allItems[o]; if (it==NULL) { if (fwbdebug) qDebug() << "#### Tree node not found"; return; } expandOrCollapseCurrentTreeNode(it, true); } void ObjectManipulator::expandOrCollapseCurrentTreeNode(QTreeWidgetItem *item, bool expand) { QTreeWidgetItem *parent = item->parent(); if (expand && parent != NULL && ! parent->isExpanded()) parent->setExpanded(true); item->setExpanded(expand); for (int i=0; ichildCount(); ++i) expandOrCollapseCurrentTreeNode(item->child(i), expand); } void ObjectManipulator::expandCurrentTreeNode() { if (getCurrentObjectTree()->getNumSelected()==0) return; QTreeWidgetItem *item = getCurrentObjectTree()->currentItem(); expandOrCollapseCurrentTreeNode(item, true); } void ObjectManipulator::collapseCurrentTreeNode() { if (getCurrentObjectTree()->getNumSelected()==0) return; QTreeWidgetItem *item = getCurrentObjectTree()->currentItem(); expandOrCollapseCurrentTreeNode(item, false); } static ObjectTreeViewItem *findUserFolder(ObjectTreeViewItem *parent, const QString &folder) { if (folder.isEmpty()) return parent; for (int ii = 0; ii < parent->childCount(); ii++) { ObjectTreeViewItem *sub = dynamic_cast(parent->child(ii)); if (sub != 0 && sub->getUserFolderParent() != 0 && sub->getUserFolderName() == folder) { return sub; } } return 0; } ObjectTreeViewItem* ObjectManipulator::insertObject(ObjectTreeViewItem *itm, FWObject *obj) { if (FWReference::cast(obj)!=NULL) return NULL; if (Resources::global_res->getObjResourceBool(obj,"hidden") ) return NULL; if (Resources::global_res->getResourceBool( string("/FWBuilderResources/Type/") + obj->getTypeName() + "/hidden")) return NULL; ObjectTreeViewItem *item = itm; if (!obj->getStr("folder").empty()) { item = findUserFolder(itm, obj->getStr("folder").c_str()); /* If we can't find the user folder, put it under the system folder and get rid of the folder attribute */ if (item == 0) { item = itm; obj->setStr("folder", ""); } } ObjectTreeViewItem *nitm = new ObjectTreeViewItem(item); nitm->setLib(""); nitm->setText( 0, getTreeLabel(obj, 0) ); nitm->setText( 1, getTreeLabel(obj, 1) ); QPixmap pm; doSetObjectIcon(obj, &pm, 0); nitm->setIcon( 0, QIcon(pm) ); // nitm->setIcon( 1, QIcon(pm) ); if (FWBTree().isSystem(obj)) { nitm->setFlags(nitm->flags() & ~Qt::ItemIsDragEnabled); } else { nitm->setFlags(nitm->flags() | Qt::ItemIsDragEnabled); } nitm->setProperty("type", obj->getTypeName().c_str() ); nitm->setFWObject( obj ); allItems[obj] = nitm; // itm->sortChildren(0, Qt::AscendingOrder); return nitm; } void ObjectManipulator::insertSubtree(FWObject *parent, FWObject *obj) { ObjectTreeViewItem* parent_item = allItems[parent]; insertSubtree(parent_item, obj); QTreeWidgetItem *itm = allItems[parent]; if (itm==NULL) return; refreshSubtree(itm, NULL); } void ObjectManipulator::insertSubtree(ObjectTreeViewItem *itm, FWObject *obj) { this->m_objectManipulator->filter->clear(); ObjectTreeViewItem *nitm = insertObject(itm, obj); if (nitm==NULL) return; if (FWBTree().isStandardFolder(obj)) nitm->setExpanded( st->getExpandTree()); set subfolders = stringToSet(obj->getStr("subfolders")); set::const_iterator iter; for (iter = subfolders.begin(); iter != subfolders.end(); ++iter) { ObjectTreeViewItem *sub = new ObjectTreeViewItem(nitm); sub->setUserFolderParent(obj); QString name = QString::fromUtf8((*iter).c_str()); sub->setUserFolderName(name); sub->setText(0, name); sub->setIcon(0, QIcon(LoadPixmap(":/Icons/SystemGroup/icon-tree"))); } if (Cluster::isA(obj)) { for (FWObjectTypedChildIterator it = obj->findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); } if (Cluster::isA(obj) || Firewall::isA(obj)) { for (FWObjectTypedChildIterator it = obj->findByType(Policy::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(NAT::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(Routing::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(Interface::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); return ; } if (Interface::isA(obj)) { for (FWObjectTypedChildIterator it = obj->findByType(Interface::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(IPv4::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(IPv6::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(physAddress::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(FailoverClusterGroup::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); for (FWObjectTypedChildIterator it = obj->findByType(AttachedNetworks::TYPENAME); it != it.end(); ++it) insertSubtree( nitm, *it ); return; } for (list::iterator m=obj->begin(); m!=obj->end(); m++) { FWObject *o1=*m; if (FWReference::cast(o1)!=NULL) continue; insertSubtree(nitm, o1); } } void ObjectManipulator::removeObjectFromTreeView(FWObject *obj) { removeObjectFromHistory(obj); int current_lib_idx = m_objectManipulator->libs->currentIndex(); ObjectTreeView *objTreeView = libs_model->getTreeWidget(current_lib_idx); assert(objTreeView); objTreeView->clearLastSelected(); ObjectTreeViewItem *itm = allItems[obj]; allItems[obj] = NULL; if (itm && itm->parent()) { itm->parent()->takeChild(itm->parent()->indexOfChild(itm)); delete itm; } if (Library::isA(obj)) { removeLib(obj); } } bool FindHistoryItemByObjectId::operator()(const HistoryItem &itm) { return (itm.id() == id); } FWObject* ObjectManipulator::findRuleSetInHistoryByParentFw(FWObject* parent) { list::reverse_iterator it = history.rbegin(); for (; it!=history.rend(); ++it) { FWObject *obj = mw->activeProject()->db()->findInIndex(it->id()); if (RuleSet::cast(obj)) { FWObject *parent_fw = Host::getParentHost(obj); if (parent_fw != NULL && parent_fw == parent) return obj; } } return NULL; } void ObjectManipulator::removeObjectFromHistory(FWObject *obj) { if (fwbdebug) qDebug() << "ObjectManipulator::removeObjectFromHistory" << "obj:" << obj->getName().c_str() << "id=" << obj->getId() << "history.size()=" << history.size(); history.remove_if(FindHistoryItemByObjectId(obj->getId())); if (fwbdebug) qDebug() << "ObjectManipulator::removeObjectFromHistory" << "history.size()=" << history.size(); if (history.empty()) mw->enableBackAction(); } void ObjectManipulator::addObjectToHistory(ObjectTreeViewItem* otvi, FWObject *obj) { history.push_back( HistoryItem(otvi, obj->getId()) ); current_history_item = history.end(); current_history_item--; } ObjectTreeViewItem* ObjectManipulator::getCurrentHistoryItem() { return current_history_item->item(); } void ObjectManipulator::updateLibColor(FWObject *lib) { QString clr = lib->getStr("color").c_str(); QModelIndex index = libs_model->getIdxForLib(lib); if (index.isValid()) { QTreeWidget *objTreeView = libs_model->getTreeWidget(index); if (clr=="" || clr=="#000000" || clr=="black") clr="#FFFFFF"; QPalette palette = objTreeView->palette(); palette.setColor(QPalette::Active, QPalette::Base, QColor( clr )); palette.setColor(QPalette::Inactive, QPalette::Base, QColor( clr )); objTreeView->setPalette(palette); } } void ObjectManipulator::updateLibName(FWObject *lib) { QModelIndex index = libs_model->getIdxForLib(lib); if (index.isValid()) { QString newlibname = QString::fromUtf8(lib->getName().c_str()); libs_model->setName(index, newlibname); libs_model->sort(0, Qt::AscendingOrder); QModelIndex lib_idx = libs_model->getIdxForLib(lib); m_objectManipulator->libs->setCurrentIndex(lib_idx.row()); } } /* * Update tree item for the given object, including its name and brief summary * of properties. If @subtree=true, do the same for all its children as well. */ void ObjectManipulator::updateObjectInTree(FWObject *obj, bool subtree) { if (fwbdebug) qDebug() << "ObjectManipulator::updateObjectInTree" << "obj=" << obj->getName().c_str() << "subtree=" << subtree; QTreeWidgetItem *itm = allItems[obj]; if (itm==NULL) return; // first, update tree item that represents @obj. Its name or label // (second column) might have changed QString old_itm_text = itm->text(0); itm->setText( 0, getTreeLabel(obj, 0) ); itm->setText( 1, getTreeLabel(obj, 1) ); QPixmap pm_obj; IconSetter::setObjectIcon(obj, &pm_obj, 0); itm->setIcon(0, pm_obj ); //getCurrentObjectTree()->updateTreeIcons(); if (itm->parent()) refreshSubtree(itm->parent(), itm); // now if we need to update subtree, call refreshSubtree() if (subtree) refreshSubtree(itm, NULL); } void ObjectManipulator::clearObjects() { if (fwbdebug) qDebug("ObjectManipulator::clearObjects %p start",this); while (history.size()!=0) history.pop_back(); int N = libs_model->rowCount(); for (int i=N-1; i>=0; i--) { QTreeWidget *objTreeView = libs_model->getTreeWidget(i); if (objTreeView == NULL) continue; m_objectManipulator->widgetStack->removeWidget(objTreeView); // delete otv; removeLib(i); } libs_model->removeRows(0, libs_model->rowCount()); libs_model->addStaticItems(); current_tree_view = NULL; if (fwbdebug) qDebug("ObjectManipulator::clearObjects done"); } void ObjectManipulator::reload() { FWObject *current_lib = getCurrentLib(); FWObject *currentObj = getSelectedObject(); saveExpandedTreeItems(); saveSectionSizes(); loadObjects(); openLib(current_lib); loadExpandedTreeItems(); loadSectionSizes(); if (currentObj) openObjectInTree(currentObj); } void ObjectManipulator::loadObjects() { if (fwbdebug) qDebug("ObjectManipulator::loadObjects %p start", this); clearObjects(); FWObject *firstUserLib = NULL; list ll = m_project->db()->getByType( Library::TYPENAME ); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { FWObject *lib = (*i); if (fwbdebug) qDebug("ObjectManipulator::loadObjects %p lib %p %s %s", this, lib, FWObjectDatabase::getStringId(lib->getId()).c_str(), lib->getName().c_str() ); if ( lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID && ! st->getBool("UI/ShowDeletedObjects")) continue; if ( lib->getId()!=FWObjectDatabase::STANDARD_LIB_ID && lib->getId()!=FWObjectDatabase::TEMPLATE_LIB_ID && firstUserLib==NULL) firstUserLib = *i; addLib( lib ); if (fwbdebug) qDebug() << "ObjectManipulator::loadObjects" << this << "added lib" << lib->getName().c_str(); } if (firstUserLib==NULL) firstUserLib = ll.front(); openLib( firstUserLib ); if (fwbdebug) qDebug() << "ObjectManipulator::loadObjects done" << this; } void ObjectManipulator::addLib(FWObject *lib) { if (fwbdebug) qDebug() << "Object Manipulator::addLib lib: " << lib->getName().c_str(); ObjectTreeView *objTreeView = new ObjectTreeView( m_project, m_objectManipulator->widgetStack, OBJTREEVIEW_WIDGET_NAME ); QString newlibname = QString::fromUtf8(lib->getName().c_str()); int idx = libs_model->rowCount(); if (fwbdebug) qDebug() << "Adding at idx=" << idx; QPixmap pm; doSetObjectIcon(lib, &pm, 0); libs_model->insertRows(idx, 1); QModelIndex model_idx = libs_model->index(idx, 0); libs_model->setData(model_idx, newlibname, lib, objTreeView); libs_model->sort(0, Qt::AscendingOrder); // after sorting the row of the new library may be different from where we added it QModelIndex lib_idx = libs_model->getIdxForLib(lib); m_objectManipulator->libs->setCurrentIndex(lib_idx.row()); QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding); policy.setHorizontalStretch(0); policy.setVerticalStretch(0); policy.setHeightForWidth(objTreeView->sizePolicy().hasHeightForWidth()); objTreeView->setSizePolicy(policy); m_objectManipulator->widgetStack->addWidget( objTreeView ); m_objectManipulator->widgetStack->show(); objTreeView->show(); updateLibColor( lib ); connect(m_objectManipulator->widgetStack, SIGNAL( currentChanged(int) ), this, SLOT( currentTreePageChanged(int) ) ); connect(objTreeView, SIGNAL( editCurrentObject_sign() ), this, SLOT( editSelectedObject()) ); connect(objTreeView, SIGNAL( switchObjectInEditor_sign(libfwbuilder::FWObject*) ), this, SLOT( switchObjectInEditor(libfwbuilder::FWObject*)) ); connect(objTreeView, SIGNAL( deleteObject_sign(libfwbuilder::FWObject*) ), this, SLOT( delObj() ) ); connect(objTreeView, SIGNAL( objectDropped_sign(libfwbuilder::FWObject*) ), this, SLOT( openObjectInTree(libfwbuilder::FWObject*) ) ); connect(objTreeView, SIGNAL( contextMenuRequested_sign(const QPoint&) ), this, SLOT( contextMenuRequested(const QPoint&) ) ); connect(objTreeView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*) ), this, SLOT(selectionChanged(QTreeWidgetItem*))); connect(objTreeView, SIGNAL(moveItems_sign(ObjectTreeViewItem *, const std::list &)), this, SLOT(moveItems(ObjectTreeViewItem *, const std::list &))); ObjectTreeViewItem *itm1=new ObjectTreeViewItem( objTreeView ); itm1->setLib(""); itm1->setExpanded(TRUE); itm1->setFlags(itm1->flags() & ~Qt::ItemIsDragEnabled); itm1->setText( 0, getTreeLabel(lib, 0) ); itm1->setText( 1, getTreeLabel(lib, 1) ); itm1->setIcon( 0, pm); itm1->setProperty("type", lib->getTypeName().c_str() ); itm1->setFWObject( lib ); allItems[lib] = itm1; for (list::iterator m=lib->begin(); m!=lib->end(); m++) insertSubtree( itm1, (*m) ); objTreeView->updateTreeIcons(); // apparently sortByColumn does not work in QT 4.5, use sortItems objTreeView->sortItems(0, Qt::AscendingOrder); objTreeView->header()->resizeSections(QHeaderView::ResizeToContents); m_objectManipulator->filter->connect(m_objectManipulator->filter, SIGNAL(textChanged(QString)), objTreeView, SLOT(setFilter(QString))); } void ObjectManipulator::removeLib(FWObject* lib) { if (fwbdebug) qDebug() << "ObjectManipulator::removeLib lib=" << lib; QModelIndex idx = libs_model->getIdxForLib(lib); if (idx.isValid()) removeLib( idx.row() ); } void ObjectManipulator::removeLib(int row) { if (fwbdebug) qDebug() << "ObjectManipulator::removeLib row=" << row; libs_model->removeRows(row, 1); m_objectManipulator->libs->setCurrentIndex(libs_model->rowCount() - 1); //libs_model->reset(); } void ObjectManipulator::refreshSubtree(QTreeWidgetItem *parent, QTreeWidgetItem *itm) { if (fwbdebug) qDebug() << "ObjectManipulator::refreshSubtree parent:" << parent->text(0) << "itm:" << QString((itm)?itm->text(0):""); QScrollBar* scrollbar = getCurrentObjectTree()->verticalScrollBar(); // remember current scrolling position int y_pos = scrollbar->value(); /* * re-sorting parent tree item causes havoc. If I do not * collapse/expand it, I get strange glitches in display. */ parent->sortChildren(0, Qt::AscendingOrder);//(); if (fwbdebug) qDebug("ObjectManipulator::refreshSubtree expand/collapse parent"); /* * workaround for QT4 bug * http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=233975 * Affects QT 4.4.1 * * This has a side effect in that the tree loses its scrollong * position and scrolls all the way to the top. If the object * being edited was in the middle or close to the bottom, it disappears * from view. Call to scrollToItem() fixes this. */ parent->setExpanded(false); parent->setExpanded(true); if (itm) getCurrentObjectTree()->scrollToItem(itm, QAbstractItemView::EnsureVisible); scrollbar->setValue(y_pos); getCurrentObjectTree()->update(); } void ObjectManipulator::moveItems(ObjectTreeViewItem *dest, const list &items) { string folder; if (dest->getUserFolderParent() != 0) { folder = dest->getUserFolderName().toUtf8().constData(); } else { folder = dest->getFWObject()->getStr("folder"); } FWCmdMacro *macro = new FWCmdMacro(tr("Move objects")); list::const_iterator iter; for (iter = items.begin(); iter != items.end(); ++iter) { FWObject *obj = *iter; FWCmdMoveToFromUserFolder *cmd = new FWCmdMoveToFromUserFolder (m_project, obj->getParent(), obj, obj->getStr("folder").c_str(), folder.c_str(), "", macro); FWObject *newObj = cmd->getNewState(); newObj->setStr("folder", folder); } m_project->undoStack->push(macro); } void ObjectManipulator::addUserFolderToTree(FWObject *obj, const QString &folder) { ObjectTreeViewItem *item = allItems[obj]; if (item == 0) return; ObjectTreeViewItem *sub = new ObjectTreeViewItem(item); sub->setUserFolderParent(obj); sub->setUserFolderName(folder); sub->setText(0, folder); sub->setIcon(0, QIcon(LoadPixmap(":/Icons/SystemGroup/icon-tree"))); refreshSubtree(item, sub); } void ObjectManipulator::removeUserFolderFromTree(FWObject *obj, const QString &folder) { ObjectTreeViewItem *item = allItems[obj]; if (item == 0) return; ObjectTreeViewItem *sub = findUserFolder(item, folder); if (sub == 0) return; QList children = sub->takeChildren(); while (!children.isEmpty()) { ObjectTreeViewItem *child = dynamic_cast (children.takeFirst()); assert(child != 0); FWObject *obj = child->getFWObject(); if (mw->isEditorVisible() && mw->getOpenedEditor() == obj) { mw->hideEditor(); } delete child; } item->removeChild(sub); delete sub; refreshSubtree(item, 0); } void ObjectManipulator::moveToFromUserFolderInTree(FWObject *obj, FWObject *objToMove, const QString &oldFolder, const QString &newFolder) { ObjectTreeViewItem *parent = allItems[obj]; ObjectTreeViewItem *toMove = allItems[objToMove]; if (parent == 0 || toMove == 0) return; ObjectTreeViewItem *oldItem = findUserFolder(parent, oldFolder); ObjectTreeViewItem *newItem = findUserFolder(parent, newFolder); oldItem->removeChild(toMove); newItem->addChild(toMove); refreshSubtree(newItem, 0); } fwbuilder-5.1.0.3599/src/libgui/newClusterDialog.h0000644000175000017500000000427411733011756022473 0ustar sylvestresylvestre/* * newClusterDialog.h - new cluster wizard dialog * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __NEWCLUSTERDIALOG_H_ #define __NEWCLUSTERDIALOG_H_ #include #include "fakeWizard.h" #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; class ObjectGroup; class Cluster; class Interface; }; class newClusterDialog : public QDialog, public FakeWizard { Q_OBJECT; libfwbuilder::Cluster *ncl; libfwbuilder::ObjectGroup *fwlist; libfwbuilder::FWObject *parent; libfwbuilder::FWObjectDatabase *db; libfwbuilder::FWObjectDatabase *tmpldb; bool unloadTemplatesLib; QMap copy_rules_from_buttons; QMap visited; std::list firewallList; bool useFirewallList; QVBoxLayout *policies; QRadioButton *noPolicy; QSpacerItem *spacer; void copyRuleSets(const std::string &type, libfwbuilder::Firewall *src, std::map &id_mapping); void deleteRuleSets(const std::string &type, libfwbuilder::Firewall *fw); void createNewCluster(); public: newClusterDialog(QWidget *parentw, libfwbuilder::FWObject *parent); virtual ~newClusterDialog(); libfwbuilder::Cluster* getNewCluster() { return ncl; }; void setFirewallList(std::vector, bool select = false); void showPage(const int page, bool blank = true); protected: Ui::newClusterDialog_q *m_dialog; int previousRelevant(const int page) const; protected slots: virtual void finishClicked(); virtual void cancelClicked(); virtual void nextClicked(); virtual void backClicked(); virtual void changed(); }; #endif /* __NEWCLUSTERDIALOG_H */ fwbuilder-5.1.0.3599/src/libgui/PhysicalAddressDialog.cpp0000644000175000017500000000614111733011756023750 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "PhysicalAddressDialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; PhysicalAddressDialog::PhysicalAddressDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::PhysAddressDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } PhysicalAddressDialog::~PhysicalAddressDialog() { delete m_dialog; } void PhysicalAddressDialog::loadFWObject(FWObject *o) { obj=o; physAddress *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->pAddress->setText( s->getPhysAddress().c_str() ); m_dialog->commentKeywords->loadFWObject(o); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->pAddress->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->pAddress); init=false; } void PhysicalAddressDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void PhysicalAddressDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); physAddress *s = dynamic_cast(new_state); assert(s!=NULL); string oldname=obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); s->setPhysAddress( m_dialog->pAddress->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/clustergroupdialog_q.ui0000644000175000017500000002745611733011756023653 0ustar sylvestresylvestre ClusterGroupDialog_q true 0 0 1016 265 0 0 ClusterGroup 0 0 QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken 0 0 32767 32767 Name: false 200 0 0 0 true 0 0 32767 32767 Type: false Qt::Horizontal 135 20 0 0 0 32 Edit Protocol Parameters... Qt::Horizontal 40 20 Qt::Vertical 20 102 0 0 QFrame::NoFrame QFrame::Plain 0 0 0 0 0 300 0 300 100000 List of current members of this cluster. Double click on an entry to load it. false QAbstractItemView::SingleSelection Firewall Interface Master Status 0 0 200 0 32767 32767 Click here to manage member firewalls of this cluster group. Manage Members... Qt::Horizontal 97 20 0 0 CommentKeywords QWidget
CommentKeywords.h
1
manageMembers fwMemberTree itemActivated(QTreeWidgetItem*,int) ClusterGroupDialog_q openObject(QTreeWidgetItem*) 262 112 411 113 editParameters clicked() ClusterGroupDialog_q openParametersEditor() 152 303 450 190 manageMembers clicked() ClusterGroupDialog_q openClusterConfDialog() 20 20 20 20 changed() openParametersEditor()
fwbuilder-5.1.0.3599/src/libgui/FWObjectSelectionModel.cpp0000755000175000017500000000275111733011756024046 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FWObjectSelectionModel.h" #include "fwbuilder/Firewall.h" using namespace libfwbuilder; FWObjectSelectionModel::FWObjectSelectionModel() { selectedObject = 0; selectedObjectOld = 0; } void FWObjectSelectionModel::setSelected(FWObject * so, const QModelIndex &index) { save(); this->selectedObject = so; this->index = index; } void FWObjectSelectionModel::save() { indexOld = index; selectedObjectOld = selectedObject; } void FWObjectSelectionModel::restore() { index = indexOld; selectedObject = selectedObjectOld; } void FWObjectSelectionModel::reset() { QModelIndex index; setSelected(NULL, index); } fwbuilder-5.1.0.3599/src/libgui/ColorLabelMenuItem.cpp0000644000175000017500000000714711733011756023237 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "ColorLabelMenuItem.h" #include "FWBSettings.h" #include #include #include #include #include #include using namespace std; ColorLabelMenuItem::ColorLabelMenuItem(QWidget *parent) : QWidget(parent) { m_widget = new Ui::colorLabelMenuItem_q; m_widget->setupUi(this); setup( m_widget->noneBtn, "#FFFFFF", tr("no color") ); setup( m_widget->redBtn, st->getLabelColor(FWBSettings::RED ), st->getLabelText(FWBSettings::RED )); setup( m_widget->orangeBtn, st->getLabelColor(FWBSettings::ORANGE), st->getLabelText(FWBSettings::ORANGE)); setup( m_widget->yellowBtn, st->getLabelColor(FWBSettings::YELLOW), st->getLabelText(FWBSettings::YELLOW)); setup( m_widget->greenBtn, st->getLabelColor(FWBSettings::GREEN ), st->getLabelText(FWBSettings::GREEN )); setup( m_widget->blueBtn, st->getLabelColor(FWBSettings::BLUE ), st->getLabelText(FWBSettings::BLUE )); setup( m_widget->purpleBtn, st->getLabelColor(FWBSettings::PURPLE), st->getLabelText(FWBSettings::PURPLE)); setup( m_widget->grayBtn, st->getLabelColor(FWBSettings::GRAY ), st->getLabelText(FWBSettings::GRAY )); } void ColorLabelMenuItem::setup(QToolButton *btn, const QString &c, const QString &t) { QPixmap pm(8,8); pm.fill( QColor(c) ); QPainter p( &pm ); p.drawRect( pm.rect() ); btn->setIcon(QIcon(pm)); btn->setToolTip(t); } void ColorLabelMenuItem::colorClicked() { if (isVisible() && parentWidget() && parentWidget()->inherits("QPopupMenu") ) parentWidget()->close(); emit returnColor(color); // signal } void ColorLabelMenuItem::noneColorClicked() { color=""; colorClicked(); } void ColorLabelMenuItem::redColorClicked() { color=st->getLabelColor(FWBSettings::RED); colorClicked(); } void ColorLabelMenuItem::orangeColorClicked() { color=st->getLabelColor(FWBSettings::ORANGE); colorClicked(); } void ColorLabelMenuItem::yellowColorClicked() { color=st->getLabelColor(FWBSettings::YELLOW); colorClicked(); } void ColorLabelMenuItem::greenColorClicked() { color=st->getLabelColor(FWBSettings::GREEN); colorClicked(); } void ColorLabelMenuItem::blueColorClicked() { color=st->getLabelColor(FWBSettings::BLUE); colorClicked(); } void ColorLabelMenuItem::purpleColorClicked() { color=st->getLabelColor(FWBSettings::PURPLE); colorClicked(); } void ColorLabelMenuItem::grayColorClicked() { color=st->getLabelColor(FWBSettings::GRAY); colorClicked(); } fwbuilder-5.1.0.3599/src/libgui/ObjectTreeView.cpp0000644000175000017500000007026711733011756022441 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBSettings.h" #include "FWBTree.h" #include "FWObjectDrag.h" #include "FWObjectPropertiesFactory.h" #include "FWWindow.h" #include "IconSetter.h" #include "ObjectManipulator.h" #include "ObjectTreeView.h" #include "ObjectTreeViewItem.h" #include "ProjectPanel.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" #include "fwbuilder/Interface.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; /**************************************************************************** * * class ObjectTreeView * ****************************************************************************/ ObjectTreeView::ObjectTreeView(ProjectPanel* project, QWidget* parent, const char * name, Qt::WFlags f) : QTreeWidget(parent), m_project(project) { setObjectName(name); this->setParent(parent, f); setFont(st->getTreeFont()); QPalette updated_palette = palette(); updated_palette.setColor( QPalette::Inactive, QPalette::Highlight, QColor("silver")); // palette().color(QPalette::Highlight).lighter(300)); setPalette(updated_palette); setExpandsOnDoubleClick(false); setDragEnabled(true); item_before_drag_started=NULL; lastSelected = NULL; second_click = false; selectionFrozen = false; expandOrCollapse = false; Lockable = false; Unlockable = false; visible = false; /* * note about process_mouse_release_event * * we use mouseReleaseEvent event to switch object opened in the * editor panel (i.e. we open new object when mouse button is * released rather than when it is pressed). This allows us to * start drag without switching object in the editor. The problem * is that mouseReleaseEvent is received in this widget after the * d&d ends with a drop somewhere else, which triggers call to * mouseReleaseEvent which switches object in the * editor. This is undesired when the editor shows a group and we * try to drag and drop an object into that group. Flag * process_mouse_release_event is used to suppress object * switching when mouseReleaseEvent is called after * successfull drop. */ process_mouse_release_event = true; connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*))); connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(itemCollapsed(QTreeWidgetItem*))); connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(itemExpanded(QTreeWidgetItem*))); QStringList qsl; qsl.push_back(tr("Object")); qsl.push_back(tr("Attributes")); setHeaderLabels(qsl); //header()->hide(); header()->setDefaultAlignment(Qt::AlignLeft); header()->setResizeMode(QHeaderView::Interactive); showOrHideAttributesColumn(); setMinimumSize( QSize( 100, 0 ) ); setAutoScroll(true); setAutoScrollMargin(50); setAllColumnsShowFocus( TRUE ); setSelectionMode( ExtendedSelection ); setAcceptDrops( true ); setDragDropMode( QAbstractItemView::DragDrop ); setRootIsDecorated( TRUE ); setFocusPolicy(Qt::StrongFocus); connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(updateFilter())); // disable sorting, otherwise gui crashes when built with // QT 4.3.4 (discovered on Ubuntu Hardy). Crash happened when // second object was added to any branch of the tree. // // This causes crash with Qt 4.6 as well // // setSortingEnabled(true); } void ObjectTreeView::paintEvent(QPaintEvent *ev) { QTreeWidget::paintEvent(ev); } void ObjectTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const { // qDebug() << "ObjectTreeView::drawRow" // << "QStyleOptionViewItem.state=" << int(option.state) // << "hasFocus()=" << hasFocus() // << "isActiveWindow()=" << isActiveWindow(); // QWidget *fw = QApplication::focusWidget(); // qDebug() << "Currently has focus:" << fw; // this is a patch for #2475 // Looks like the state remains State_Active even when the tree view widget // loses focus (as long as parent window is active). QStyleOptionViewItem new_opt = option; if ( ! hasFocus()) new_opt.state &= ~QStyle::State_Active; QTreeWidget::drawRow(painter, new_opt, index); } bool ObjectTreeView::event( QEvent *event ) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = (QHelpEvent*) event; QPoint pos = he->pos(); if (st->getObjTooltips()) { int cx = pos.x(), cy = pos.y(); FWObject *obj=NULL; QRect cr; QTreeWidgetItem *itm = itemAt(QPoint(cx, cy - header()->height())); if (itm==NULL) return false; ObjectTreeViewItem *oivi = dynamic_cast(itm); assert(oivi!=NULL); obj = oivi->getFWObject(); if (obj==NULL) return false; if (obj->getId() == FWObjectDatabase::ANY_ADDRESS_ID || obj->getId() == FWObjectDatabase::ANY_SERVICE_ID || obj->getId() == FWObjectDatabase::ANY_INTERVAL_ID) return false; cr = visualItemRect(itm); QRect global = QRect( viewport()->mapToGlobal(cr.topLeft()), viewport()->mapToGlobal(cr.bottomRight())); //finally stretch rect up to component's width and even more //(it fixes bug with horizontal scroll) global.setWidth(width() + horizontalOffset()); QToolTip::showText(mapToGlobal( he->pos() ), FWObjectPropertiesFactory::getObjectPropertiesDetailed(obj, true, true), this, global); } return true; } return QTreeWidget::event(event); } void ObjectTreeView::currentItemChanged(QTreeWidgetItem*) { expandOrCollapse = false; } void ObjectTreeView::itemCollapsed(QTreeWidgetItem* itm) { expandOrCollapse = true; ObjectTreeViewItem *otvi = dynamic_cast(itm); assert(otvi!=NULL); FWObject *o = otvi->getFWObject(); if (o) { int id = o->getId(); expanded_objects.erase(id); } } void ObjectTreeView::itemExpanded(QTreeWidgetItem* itm) { expandOrCollapse = true; ObjectTreeViewItem *otvi=dynamic_cast(itm); assert(otvi!=NULL); FWObject *o = otvi->getFWObject(); if (o) { int id = o->getId(); expanded_objects.insert(id); } } /* * This method makes list selectedObjects flat. If user selects * several objects in the tree, and some of them have children, QT * puts all the children in the selected objects list even if * corresponding subtrees are collapsed. This method eliminates these * selected children objects. * */ std::vector ObjectTreeView::getSimplifiedSelection() { vector so = selectedObjects; vector so2 = selectedObjects; for (vector::iterator i=so2.begin(); i!=so2.end(); ++i) { for (vector::iterator j=i; j!=so2.end(); ++j) { vector::iterator k=std::find(so.begin(),so.end(),*j); if ( (*j)->isChildOf( *i ) && k!=so.end()) so.erase( k ); } } return so; } FWObject* ObjectTreeView::getCurrentObject() { QTreeWidgetItem *ovi = currentItem(); ObjectTreeViewItem *otvi=dynamic_cast(ovi); if (otvi==NULL) return NULL; return otvi->getFWObject(); } void ObjectTreeView::focusInEvent(QFocusEvent* ev) { QTreeWidget::focusInEvent(ev); QTreeWidgetItem *ci = currentItem(); if (ci) repaint(); } void ObjectTreeView::focusOutEvent(QFocusEvent* ev) { QTreeWidget::focusOutEvent(ev); QTreeWidgetItem *ci = currentItem(); if (ci) repaint(); } void ObjectTreeView::updateTreeIcons() { QTreeWidgetItemIterator it(this); for ( ; *it; ++it) { QTreeWidgetItem *itm = *it; ObjectTreeViewItem *otvi = dynamic_cast(itm); FWObject *obj = otvi->getFWObject(); /* We can have obj==0 if it's a user-create subfolder */ if (obj == 0) continue; QPixmap pm_obj; IconSetter::setObjectIcon(obj, &pm_obj, 0); itm->setIcon(0, pm_obj ); } update(); } void ObjectTreeView::startDrag(Qt::DropActions supportedActions) { QTreeWidgetItem *ovi = currentItem(); if (ovi==NULL) return; FWObject *current_obj = getCurrentObject(); /* User-defined folders can't be dragged */ if (current_obj == 0) return; if (fwbdebug) qDebug("ObjectTreeView::startDrag: this: %p current_obj: %s", this, current_obj->getName().c_str()); /* can't drag system folders in fact, I have to allow to drag system folders because otherwise QListView triggers highlighting of objects in the tree when user drags mouse cursor across them. This is weird behavior and there does not seem to be any way to turn it off. It happens close to the end of void QListView::mouseMoveEvent( QMouseEvent * e) (See code after they decided that they do not need to call startDrag()) if (FWBTree().isSystem(obj)) return NULL; */ QString icn = (":/Icons/"+current_obj->getTypeName()+"/icon-ref").c_str(); vector so = getSimplifiedSelection(); list dragobj; for (vector::iterator v=so.begin(); v!=so.end(); v++) { //m_project->check4Depends(*v, dragobj); if (fwbdebug) qDebug("ObjectTreeView::startDrag: adding object to drag list: %s", (*v)->getName().c_str()); // while obj is still part of the tree, do some clean up // to avoid problems in the future. Create // InterfaceOptions objects for interfaces because we'll // need them for various validations during paste/drop // operation. Interface *intf = Interface::cast(*v); if (intf) intf->getOptionsObject(); dragobj.push_back( *v ); } FWObjectDrag *drag = new FWObjectDrag(dragobj, this); QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } if (dragobj.size()>1) { QPixmap npm(32,32); QPainter p( &npm ); p.fillRect( 0,0,32,32, QBrush( QColor("white"),Qt::SolidPattern ) ); p.setBackgroundMode( Qt::TransparentMode ); p.drawPixmap( 0, 32-pm.rect().height(), pm); p.setPen( QColor("red") ); p.setBrush( QBrush( QColor("red"),Qt::SolidPattern ) ); p.drawPie( 16, 0, 16,16, 0, 5760 ); QString txt; txt.setNum(dragobj.size()); QRect br=p.boundingRect(0, 0, 1000, 1000, Qt::AlignLeft|Qt::AlignVCenter, txt ); p.setPen( QColor("white") ); p.drawText( 24-br.width()/2 , 4+br.height()/2, txt ); p.end(); npm.setMask( npm.createHeuristicMask() ); drag->setPixmap( npm ); } else drag->setPixmap( pm ); /* * This fragment returns selection in the tree back to the object that * was selected before drag operation has started. This help in the * following case: * * - open a group for editing (group is selected in the tree) * - left-click on another object in the tree, start dragging it * * at this point selection in the tree returns to the group, so when * user finishes d&d operation, the selection in the tree is consisten * with object currently opened in the editor panel. * * There is a problem with this however. If user wants to put an * object from a different library into the group, they have to switch * to that library before doing d&d. When they switch, ObjectTree * shown in the left panel becomes different from the tree in which * the group is located. When d&d finishes, the ObjectTree object * receives mouseReleaseEvent event. Since it is not the right * tree object, it can not properly restore selection and choses an * object that was previously opened in that tree, which in turn * changes the object opened in the editor panel. To make things * worse, this event is only delivered to the tree object on Mac OS X. * * */ if (fwbdebug) qDebug("ObjectTreeView::dragObject() this=%p visible=%d", this,visible); drag->start(supportedActions); } void ObjectTreeView::dragEnterEvent( QDragEnterEvent *ev) { ev->setAccepted(ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); ev->setDropAction(Qt::MoveAction); } static bool isValidDropTarget(QTreeWidgetItem *item, list &objs) { ObjectTreeViewItem *dest = dynamic_cast(item); if (dest == 0) return false; bool dragIsNoop = true; list::const_iterator iter; for (iter = objs.begin(); iter != objs.end(); ++iter) { FWObject *dragobj = *iter; assert(dragobj != 0); if (Interface::cast(dragobj) != 0 || Interface::cast(dragobj->getParent()) != 0 || Policy::cast(dragobj) != 0 || NAT::cast(dragobj) != 0 || Routing::cast(dragobj) != 0) return false; /* See if destination is a user folder */ if (dest->getUserFolderParent() != 0) { /* Dragged object has to match parent of user folder */ if (dest->getUserFolderParent() != dragobj->getParent()) { return false; } /* Are we dragging within the same user folder? */ if (dest->getUserFolderName() != QString::fromUtf8(dragobj->getStr("folder").c_str())) { dragIsNoop = false; } } else { /* OK to drag onto parent itself, or object that shares parent */ if (dragobj->getParent() != dest->getFWObject() && dragobj->getParent() != dest->getFWObject()->getParent()) { return false; } /* Are we dragging to a new place? */ if ((FWBTree().isSystem(dest->getFWObject()) && dragobj->getStr("folder") != "") || (dest->getFWObject()->getStr("folder") != dragobj->getStr("folder"))) { dragIsNoop = false; } } } return !dragIsNoop; } void ObjectTreeView::dragMoveEvent(QDragMoveEvent *ev) { /* Call the parent so that auto-scrolling works properly */ QTreeWidget::dragMoveEvent(ev); list objs; if (ev->source() != this || !FWObjectDrag::decode(ev, objs) || !isValidDropTarget(itemAt(ev->pos()), objs)) { ev->setAccepted(false); return; } ev->setDropAction(Qt::MoveAction); ev->setAccepted(true); } void ObjectTreeView::dropEvent(QDropEvent *ev) { // only accept drops from the same instance of fwbuilder if (ev->source() == NULL) return; ObjectTreeViewItem *dest = dynamic_cast(itemAt(ev->pos())); if (dest == 0) { notWanted: ev->setAccepted(false); return; } list objs; if (!FWObjectDrag::decode(ev, objs)) goto notWanted; /* Make sure the drop event is on an object that can handle it */ if (ev->source() != this || !isValidDropTarget(dest, objs)) goto notWanted; emit moveItems_sign(dest, objs); ev->setAccepted(true); } void ObjectTreeView::dragLeaveEvent( QDragLeaveEvent *ev) { QTreeWidget::dragLeaveEvent(ev); clearSelection(); } void ObjectTreeView::mouseMoveEvent( QMouseEvent * e ) { /* This stops highlighting of stuff in the tree when the user clicks and tries to drag something non-draggable. */ if (state() == DragSelectingState) return; QTreeWidget::mouseMoveEvent(e); if (e==NULL) return; } void ObjectTreeView::mousePressEvent( QMouseEvent *e ) { if (fwbdebug) qDebug("ObjectTreeView::mousePressEvent"); second_click = false; process_mouse_release_event = true; if (fwbdebug) { qDebug() << "ObjectTreeView::mousePressEvent :: currentItem=" << ((currentItem())?currentItem()->text(0):"nil"); qDebug() << "ObjectTreeView::mousePressEvent :: lastSelected=" << ((lastSelected)?lastSelected->text(0):"nil"); } lastSelected = currentItem(); QTreeWidget::mousePressEvent(e); if (e->button() == Qt::LeftButton) { startingDrag = true; } if (e->button() == Qt::RightButton) emit contextMenuRequested_sign(e->pos()); } /* * Two modes of operation of this widget: * * 1. this widget can intercept single mouse click and return * selection back to the object that was current before it. If user * double ckicks mouse button, then this reset is not done and new * object is selected. This is done using timer. * * 2. this widget can act as usual QListView does, that is, select an object * on a single click. * * uncomment the line that starts timer for mode #1. * * * we use mouseReleaseEvent event to switch object opened in the * editor panel (i.e. we open new object when mouse button is released * rather than when it is pressed). This allows us to start drag * without switching object in the editor. The problem is that * mouseReleaseEvent is received in this widget after the d&d ends * with a drop somewhere else, which triggers call to * mouseReleaseEvent which switches object in the editor. This * is undesired when the editor shows a group and we try to drag and * drop an object into that group. Flag process_mouse_release_event is * used to suppress object switching when mouseReleaseEvent is * called after successfull drop. * */ void ObjectTreeView::mouseReleaseEvent( QMouseEvent *e ) { if (fwbdebug) qDebug("ObjectTreeView::mouseReleaseEvent 1 this=%p process_mouse_release_event=%d", this,process_mouse_release_event); QTreeWidget::mouseReleaseEvent(e); if (!process_mouse_release_event) { // just do not switch object in the editor, otherwise // process this event as usual process_mouse_release_event = true; return; } if (fwbdebug) qDebug("ObjectTreeView::mouseReleaseEvent 2 selectedObjects.size()=%d getCurrentObject()=%p current object %s", int(selectedObjects.size()), getCurrentObject(), (getCurrentObject()!=NULL)?getCurrentObject()->getName().c_str():"nil"); if (expandOrCollapse) return; // user expanded or collapsed subtree, // no need to change object in the editor // Experiment: single click on the object in the tree should not open // it in the editor #if 0 if (selectedObjects.size()==1) emit switchObjectInEditor_sign( getCurrentObject() ); else { // user selected multiple objects // do not let them if editor has unsaved changes // if (mw->isEditorVisible() && mw->isEditorModified()) emit switchObjectInEditor_sign( getCurrentObject() ); else mw->blankEditor(); } #endif } /* * normally QAbstractItemView::edit starts in-place editing. We use * double click to open object in a separate editor panel */ bool ObjectTreeView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) { if (fwbdebug) qDebug("ObjectTreeView::edit"); if (trigger==QAbstractItemView::DoubleClicked) editCurrentObject(); return QTreeWidget::edit(index, trigger, event); } /* * sends signal that should be connected to a slot in * ObjectManipulator which opens editor panel if it is closed and then * opens current object in it */ void ObjectTreeView::editCurrentObject() { if (fwbdebug) qDebug("ObjectTreeView::editCurrentObject"); emit editCurrentObject_sign(); if (fwbdebug) qDebug("ObjectTreeView::editCurrentObject done"); } void ObjectTreeView::keyPressEvent( QKeyEvent* ev ) { FWObject *obj = getCurrentObject(); if (obj) { if (ev->key()==Qt::Key_Enter || ev->key()==Qt::Key_Return) { if (fwbdebug) qDebug() << "ObjectTreeView::keyPressEvent Qt::Key_Enter"; editCurrentObject(); ev->accept(); return; } if (ev->key()==Qt::Key_Delete) { emit deleteObject_sign(obj); ev->accept(); return; } } QTreeWidget::keyPressEvent(ev); } void ObjectTreeView::keyReleaseEvent( QKeyEvent* ev ) { QTreeWidget::keyReleaseEvent(ev); } void ObjectTreeView::itemOpened () { if (fwbdebug) qDebug("ObjectTreeView::itemOpened"); editCurrentObject(); } void ObjectTreeView::clearLastSelected() { lastSelected = NULL; } void ObjectTreeView::resetSelection() { if (lastSelected) { if (fwbdebug) qDebug() << "ObjectTreeView::resetSelection :: lastSelected=" << lastSelected->text(0); setCurrentItem(lastSelected); lastSelected->setSelected(true); } } void ObjectTreeView::itemSelectionChanged() { if (fwbdebug) qDebug("ObjectTreeView::itemSelectionChanged selectionFrozen=%d", selectionFrozen); if (selectionFrozen) return; /* in extended selection mode there may be several selected items */ selectedObjects.clear(); QList selected = selectedItems(); QList::Iterator it; for (it=selected.begin(); it!=selected.end(); it++) { QTreeWidgetItem *itm = (*it); ObjectTreeViewItem *otvi = dynamic_cast(itm); FWObject *obj = otvi->getFWObject(); if (obj == 0) continue; selectedObjects.push_back(otvi->getFWObject()); if (fwbdebug) qDebug( "ObjectTreeView::selectionChanged: selected otvi=%p object %s", otvi, otvi->getFWObject()->getName().c_str()); } if (fwbdebug) qDebug("ObjectTreeView::itemSelectionChanged completed"); /* now list selectedObjects holds all selected items */ } bool ObjectTreeView::isSelected(FWObject* obj) { for (vector::iterator i=selectedObjects.begin(); i!=selectedObjects.end(); ++i) { if ( (*i)==obj) return true; } return false; } int ObjectTreeView::getNumSelected() { return selectedObjects.size(); } void ObjectTreeView::updateAfterPrefEdit() { setFont(st->getTreeFont()); } void ObjectTreeView::ExpandTreeItems(const set &ids) { if (fwbdebug) qDebug() << "ObjectTreeView::ExpandTreeItems()"; QTreeWidgetItemIterator it(this); for ( ; *it; ++it) { QTreeWidgetItem *itm = *it; ObjectTreeViewItem *otvi=dynamic_cast(itm); FWObject *obj = otvi->getFWObject(); if (obj == 0) continue; if (ids.count(obj->getId())) itm->setExpanded(true); } } void ObjectTreeView::showOrHideAttributesColumn() { if (st->getBool("UI/ShowObjectsAttributesInTree")) setColumnCount(2); else setColumnCount(1); } QSet ObjectTreeView::resolveChildren(QTreeWidgetItem *parent) { QSet children; children.insert(parent); if (parent->childCount() == 0) return children; for (int i=0; ichildCount(); i++) children.unite(resolveChildren(parent->child(i))); return children; } QSet ObjectTreeView::resolveParents(QTreeWidgetItem *child) { QSet parents; parents.insert(child); if (child->parent() == NULL) return parents; parents.unite(resolveParents(child->parent())); return parents; } void ObjectTreeView::updateFilter() { if (filter.isEmpty()) return; setFilter(filter); } static bool filterMatches(const QString &text, ObjectTreeViewItem *item) { if (text.isEmpty()) return true; if (item->text(0).contains(text, Qt::CaseInsensitive)) return true; if (item->getUserFolderParent() != 0) return false; FWObject *obj = item->getFWObject(); QByteArray utf8 = text.toUtf8(); set keys = obj->getKeywords(); set::const_iterator iter; for (iter = keys.begin(); iter != keys.end(); ++iter) { QString keyword = QString::fromUtf8((*iter).c_str()); if (keyword.contains(text, Qt::CaseInsensitive)) return true; } return false; } static uint qHash(const QStringList &list) { uint ret = 0; for (int ii = 0; ii < list.size(); ii++) { ret += qHash(list.at(ii)); } return ret; } void ObjectTreeView::doExpandedState(bool save, QStringList &list, QTreeWidgetItem *item) { list.append(item->text(0)); if (save) { if (item->isExpanded()) expandedState.insert(list); } else { if (expandedState.contains(list)) item->setExpanded(true); } for (int ii = 0; ii < item->childCount(); ii++) { doExpandedState(save, list, item->child(ii)); } list.removeLast(); } void ObjectTreeView::setFilter(QString text) { if (filter.isEmpty() && !text.isEmpty()) { QStringList list; for (int ii = 0; ii < topLevelItemCount(); ii++) { doExpandedState(true, list, topLevelItem(ii)); } } else if (text.isEmpty() && !filter.isEmpty()) { QStringList list; for (int ii = 0; ii < topLevelItemCount(); ii++) { doExpandedState(false, list, topLevelItem(ii)); } expandedState.clear(); } filter = text; if (fwbdebug) qDebug() << "ObjectTreeView::setFilter " << text; list expand; for (QTreeWidgetItemIterator wit(this); *wit; ++wit) { ObjectTreeViewItem *otvi = dynamic_cast(*wit); if (filterMatches(text, otvi)) { (*wit)->setHidden(false); if (Firewall::cast(otvi->getFWObject()) != 0) { expand.push_back(otvi); } QTreeWidgetItem *parent = (*wit)->parent(); while (parent != 0) { parent->setHidden(false); parent = parent->parent(); } } else { (*wit)->setHidden(true); } } list::const_iterator iter; for (iter = expand.begin(); iter != expand.end(); ++iter) { QTreeWidgetItem *item = *iter; item->setHidden(false); for (int ii = 0; ii < item->childCount(); ii++) { expand.push_back(item->child(ii)); } } if (!text.isEmpty()) this->expandAll(); } fwbuilder-5.1.0.3599/src/libgui/procurveacladvanceddialog_q.ui0000644000175000017500000012731511733011756025123 0ustar sylvestresylvestre procurveaclAdvancedDialog_q Qt::WindowModal true 0 0 743 558 HP ProCurve ACL Firewall Settings false 0 Compiler Options 0 0 Output file name (if left blank, the file name is constructed of the firewall object name and extension ".fw") Qt::AlignVCenter true 300 0 32767 22 false 20 Compiler creates multiple access lists from the same policy, two for each interface: one for inbound and another for outbound. If the policy is written in a such way that no rule can possibly be associated with an interface, this interface gets no access list at all. Also, interfaces marked as "unprotected" never get access list regardless of how the policy rules are designed. Generate separate access list for each interface Compiler creates one access list and assigns it to all interfaces. Create one access list and attach it to all interfaces 0 0 Policy Compiler Options false false 20 If the option is deactivated, compiler treats empty groups as an error and aborts processing the policy. If this option is activated, compiler removes all empty groups from all rule elements. If rule element becomes 'any' after the last empty group has been removed, the whole rule will be ignored. Use this option only if you fully understand how it works! Ignore empty groups in rules Shadowing happens because a rule is a superset of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. Detect rule shadowing in the policy Always permit ssh access from the management workstation with this address: true false 0 0 300 0 32767 22 Qt::Horizontal 328 20 Qt::Vertical QSizePolicy::Expanding 20 170 Script Options 0 0 5 0 0 Clear all access lists then install new ones. This method may interrupt access to the firewall if you manage it remotely via tunnel. Qt::AlignVCenter true procurve_acl_acl_basic 0 0 Qt::ClickFocus Do not clear access lists, just generate commands for the new ones. Use this option if you have your own policy installation scripts. Qt::AlignVCenter true procurve_acl_acl_no_clear 0 0 "Safety net" method: First, create temporary access list to permit connections from the management subnet specified below to the firewall and assign it to outside interface. This temporary ACL helps maintain session between management station and the firewall while access lists are reloaded in case connection comes over IPSEC tunnel. Then clear permanent lists, recreate them and assign to interfaces. This method ensures that remote access to the firewall is maintained without interruption at a cost of slightly larger configuration. Qt::AlignVCenter true procurve_acl_acl_substitution QFrame::NoFrame QFrame::Sunken 0 11 0 11 Temporary access list should permit access from this address or subnet (use prefix notation to specify subnet, e.g. 192.0.2.0/24): Qt::AlignVCenter true Qt::Horizontal QSizePolicy::Expanding 120 20 0 0 199 0 500 32767 Qt::Horizontal QSizePolicy::Expanding 110 20 0 0 20 Insert comments into generated IOSACL configuration file Comment the code Insert comments into generated IOSACL configuration file Use ACL remarks Qt::Vertical 20 137 Installer Built-in installer User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 Instead of running generated configuration on the router line by line, installer can use scp to copy the file 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. true Copy generated configuration file to the router using scp File system on the router where configuration file should be saved if it is copied with scp. Examples: "flash:", "disk0:". Should end with a colon ":". If this input field is left blank, installer uses "nvram:": true Qt::Horizontal 398 20 External install script -1 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Prolog/Epilog 20 12 20 20 6 Qt::Horizontal QSizePolicy::Expanding 40 20 Edit The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 The following commands will be added verbatim after generated configuration Qt::RichText Qt::AlignVCenter true 0 Logging Generate logging commands Syslog 12 Syslog host (name or IP address): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false syslog facility: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false syslog level ('logging trap'): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QFrame::HLine QFrame::Sunken Qt::Horizontal QFrame::HLine QFrame::Sunken Qt::Horizontal The logging timestamp command requires that the clock command be set. Qt::AlignVCenter true Enable logging timestamps on syslog file Other logging destinations and levels: 12 Internal buffer Console Qt::Vertical QSizePolicy::Expanding 675 121 IPv6 The order in which ipv4 and ipv6 rules should be generated: Qt::Horizontal 40 20 IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::Expanding 20 20 OK Qt::AlignCenter false Cancel outputFileName separate_acls_for_interfaces one_acl_for_all_interfaces procurve_acl_ignore_empty_groups procurve_acl_check_shadowing mgmt_ssh mgmt_addr procurve_acl_acl_basic procurve_acl_acl_no_clear procurve_acl_acl_substitution procurve_acl_acl_temp_addr user altAddress sshArgs scpArgs use_scp filesystem installScript installScriptArgs procurve_acl_prolog_script edit_prolog_button procurve_acl_epilog_script edit_epilog_button generate_logging_commands syslog_host syslog_facility logging_trap_level logging_timestamp logging_buffered logging_console logging_buffered_level logging_console_level ipv4before_2 ok_button cancel_button textLabel3 tabWidget ok_button clicked() procurveaclAdvancedDialog_q accept() 584 703 371 366 cancel_button clicked() procurveaclAdvancedDialog_q reject() 689 703 371 366 edit_prolog_button clicked() procurveaclAdvancedDialog_q editProlog() 671 318 371 366 edit_epilog_button clicked() procurveaclAdvancedDialog_q editEpilog() 671 628 371 366 procurve_acl_acl_basic toggled(bool) procurveaclAdvancedDialog_q scriptACLModeChanged() 60 75 371 366 procurve_acl_acl_no_clear toggled(bool) procurveaclAdvancedDialog_q scriptACLModeChanged() 60 117 371 366 procurve_acl_acl_substitution toggled(bool) procurveaclAdvancedDialog_q scriptACLModeChanged() 60 207 371 366 editProlog() editEpilog() scriptACLModeChanged() fwbuilder-5.1.0.3599/src/libgui/findDialog.cpp0000644000175000017500000002431311733011756021607 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "findDialog.h" #include "ProjectPanel.h" #include "FWBTree.h" #include "FWBSettings.h" #include "FWWindow.h" #include "events.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; #define MAX_SEARCH_ITEMS_COUNT 10 findDialog::findDialog(QWidget *p, ProjectPanel *project) : QDialog(p), treeSeeker(), m_project(project) { m_dialog = new Ui::findDialog_q; m_dialog->setupUi(this); lastFound=NULL; lastTextSearch=""; lastAttrSearch=""; m_dialog->findText->setFocus(); } void findDialog::setObject(FWObject *o) { reset(); m_dialog->findText->lineEdit()->setText( QString::fromUtf8(o->getName().c_str()) ); } void findDialog::reset() { lastFound=NULL; lastTextSearch=""; treeSeeker=m_project->db()->tree_begin(); } void findDialog::findTextChanged(const QString &ns) { if (ns!=lastTextSearch) reset(); lastTextSearch=ns; } void findDialog::findAttrChanged(const QString &ns) { if (ns!=lastAttrSearch) reset(); lastAttrSearch=ns; } void findDialog::find() { if (m_dialog->findText->currentText().isEmpty() && m_dialog->findAttr->currentText().isEmpty()) return; if (m_dialog->findText->currentText() != m_dialog->findText->itemText(0)) { if (m_dialog->findText->count()>=MAX_SEARCH_ITEMS_COUNT) m_dialog->findText->removeItem(MAX_SEARCH_ITEMS_COUNT-1); m_dialog->findText->insertItem( 0, m_dialog->findText->currentText() ); if (fwbdebug) { qDebug("findDialog::find() : findText->text(0)=%s", m_dialog->findText->itemText(0).toLatin1().constData()); } } if (m_dialog->findAttr->currentText() != m_dialog->findAttr->itemText(0)) { if (m_dialog->findAttr->count()>=MAX_SEARCH_ITEMS_COUNT) m_dialog->findAttr->removeItem(MAX_SEARCH_ITEMS_COUNT-1); m_dialog->findAttr->insertItem( 0, m_dialog->findAttr->currentText() ); if (fwbdebug) qDebug("findDialog::find() : findAttr->text(0)=%s", m_dialog->findAttr->itemText(0).toLatin1().constData()); } findNext(); } bool findDialog::matchName(const QString &name) { QString s=m_dialog->findText->currentText(); if (s.isEmpty()) return true; bool res=false; if (m_dialog->useRegexp->isChecked()) res= ( name.indexOf( QRegExp(s) )!=-1 ); else res= ( name == s ); return res; } bool findDialog::matchAttr(libfwbuilder::FWObject *obj) { QString s=m_dialog->findAttr->currentText(); if (s.isEmpty()) return true; bool res=false; int attrN = m_dialog->attribute->currentIndex(); switch (attrN) { case 0: // Address { Address *a = Address::cast(obj); if (a!=NULL) { QString addr = a->getAddressPtr()->toString().c_str(); if (m_dialog->useRegexp->isChecked()) res= ( addr.indexOf( QRegExp(s) )!=-1 ); else res= ( addr == s ); } break; } case 1: // port if (TCPService::cast(obj)!=NULL || UDPService::cast(obj)!=NULL) { if (m_dialog->useRegexp->isChecked()) { QString port; port.setNum(TCPUDPService::cast(obj)->getSrcRangeStart()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); port.setNum(TCPUDPService::cast(obj)->getSrcRangeEnd()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); port.setNum(TCPUDPService::cast(obj)->getDstRangeStart()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); port.setNum(TCPUDPService::cast(obj)->getDstRangeEnd()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); } else { int port = s.toInt(); res |= (port == TCPUDPService::cast(obj)->getSrcRangeStart()); res |= (port == TCPUDPService::cast(obj)->getSrcRangeEnd()); res |= (port == TCPUDPService::cast(obj)->getDstRangeStart()); res |= (port == TCPUDPService::cast(obj)->getDstRangeEnd()); } break; } case 2: // protocol num. if (IPService::cast(obj)!=NULL) { if (m_dialog->useRegexp->isChecked()) { QString proto; proto.setNum(obj->getInt("protocol_num")); res |= ( proto.indexOf( QRegExp(s) )!=-1 ); } else { int proto = s.toInt(); res |= (proto == obj->getInt("protocol_num")); } break; } case 3: // icmp type if (ICMPService::cast(obj)!=NULL) { if (m_dialog->useRegexp->isChecked()) { QString icmptype; icmptype.setNum(obj->getInt("type")); res |= ( icmptype.indexOf( QRegExp(s) )!=-1 ); } else { int icmptype = s.toInt(); res |= (icmptype == obj->getInt("type")); } break; } } return res; } void findDialog::findNext() { if (m_dialog->findText->currentText().isEmpty() && m_dialog->findAttr->currentText().isEmpty()) return; if (m_dialog->findText->count()>10) m_dialog->findText->removeItem(0); if (m_dialog->findAttr->count()>10) m_dialog->findAttr->removeItem(0); FWObject *o=NULL; loop: QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); for (; treeSeeker!=m_project->db()->tree_end(); ++treeSeeker) { o = *treeSeeker; if( RuleElement::cast(o->getParent())!=NULL) { if (! m_dialog->searchInRules->isChecked()) continue; } else { /* if not in rules, then in the tree. */ if (! m_dialog->searchInTree->isChecked()) continue; } if (FWReference::cast(o)!=NULL) { FWReference *r=FWReference::cast(o); if ( matchName( QString::fromUtf8(r->getPointer()->getName().c_str()) ) && matchAttr( r->getPointer() )) break; } else { if (matchName( QString::fromUtf8(o->getName().c_str())) && matchAttr( o )) break; } } QApplication::restoreOverrideCursor(); if (treeSeeker==m_project->db()->tree_end()) { reset(); if ( QMessageBox::warning( this,"Firewall Builder", tr("Search hit the end of the object tree."), tr("&Continue at top"), tr("&Stop"), QString::null, 0, 1 )==0 ) goto loop; return; } assert(o!=NULL); /* found object. Shift iterator so it does not return the same object * when user hits 'find next' */ ++treeSeeker; if (FWReference::cast(o)!=NULL && RuleElement::cast(o->getParent())!=NULL) { m_project->ensureObjectVisibleInRules( FWReference::cast(o) ); QTimer::singleShot(200, this, SLOT(makeActive()) ); return; } if (Group::cast(o->getParent())!=NULL && !FWBTree().isSystem(o->getParent())) { QCoreApplication::postEvent( mw, new showObjectInTreeEvent(m_project->getFileName(), o->getParent()->getId())); QCoreApplication::postEvent( mw, new openObjectInEditorEvent(m_project->getFileName(), o->getParent()->getId())); QTimer::singleShot(200, this, SLOT(makeActive()) ); return; } if (fwbdebug) { qDebug("Found object: o=%p id=%s name=%s type=%s", o, FWObjectDatabase::getStringId(o->getId()).c_str(), o->getName().c_str(), o->getTypeName().c_str()); } QCoreApplication::postEvent( mw, new showObjectInTreeEvent(m_project->getFileName(), o->getId())); QCoreApplication::postEvent( mw, new openObjectInEditorEvent(m_project->getFileName(), o->getId())); QTimer::singleShot(200, this, SLOT(makeActive()) ); } void findDialog::makeActive() { activateWindow(); } void findDialog::showEvent( QShowEvent *ev) { st->restoreGeometry(this, QRect(200,100,330,140) ); QDialog::showEvent(ev); m_dialog->useRegexp->setChecked( st->getBool("Search/useRegexp") ); m_dialog->searchInTree->setChecked( st->getBool("Search/findInTree" ) ); m_dialog->searchInRules->setChecked( st->getBool("Search/findInRules") ); m_dialog->findText->setFocus(); } void findDialog::hideEvent( QHideEvent *ev) { st->saveGeometry(this); QDialog::hideEvent(ev); st->setBool("Search/useRegexp", m_dialog->useRegexp->isChecked() ); st->setBool("Search/findInTree", m_dialog->searchInTree->isChecked() ); st->setBool("Search/findInRules", m_dialog->searchInRules->isChecked() ); } fwbuilder-5.1.0.3599/src/libgui/ipcopAdvancedDialog.cpp0000644000175000017500000002117711733011756023434 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "ipcopAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "Help.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; ipcopAdvancedDialog::~ipcopAdvancedDialog() { delete m_dialog; } ipcopAdvancedDialog::ipcopAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::ipcopAdvancedDialog_q; m_dialog->setupUi(this); obj=o; QStringList slm; /* * Set dialog title dynamically to reflect description set in the * platform resource file. This is useful because the same dialog * is used for ipcop, endian and oneshield platforms. */ string platform = obj->getStr("platform"); string description = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/description"); setWindowTitle(QObject::tr("%1 advanced settings").arg(description.c_str())); FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); /* fwoptions->setStr("firewall_dir", "/etc/rc.d/"); fwoptions->setStr("admUser", "admin"); fwoptions->setStr("activationCmd", "/etc/rc.d/rc.firewall"); fwoptions->setStr("output_file", "rc.firewall.local"); */ //QString s = fwoptions->getStr("ipv4_6_order") data.registerOption(m_dialog->ipv4before, fwoptions, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") <<"ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first"); data.registerOption(m_dialog->logTCPseq, fwoptions, "log_tcp_seq"); data.registerOption(m_dialog->logTCPopt, fwoptions, "log_tcp_opt"); data.registerOption(m_dialog->logIPopt, fwoptions, "log_ip_opt"); data.registerOption(m_dialog->logNumsyslog, fwoptions, "use_numeric_log_levels"); slm = getLogLevels( platform.c_str()); m_dialog->logLevel->clear(); m_dialog->logLevel->addItems( getScreenNames(slm)); data.registerOption(m_dialog-> logLevel, fwoptions, "log_level", slm); data.registerOption(m_dialog->useULOG, fwoptions, "use_ULOG"); data.registerOption(m_dialog->cprange, fwoptions, "ulog_cprange"); data.registerOption(m_dialog->qthreshold, fwoptions, "ulog_qthreshold"); data.registerOption(m_dialog->nlgroup, fwoptions, "ulog_nlgroup"); data.registerOption(m_dialog->logprefix, fwoptions, "log_prefix"); slm=getLimitSuffixes( platform.c_str()); m_dialog->logLimitSuffix->clear(); m_dialog->logLimitSuffix->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> logLimitSuffix, fwoptions, "limit_suffix", slm); data.registerOption(m_dialog->logLimitVal, fwoptions, "limit_value"); data.registerOption(m_dialog->logAll, fwoptions, "log_all"); data.registerOption(m_dialog->compiler, fwoptions, "compiler"); data.registerOption(m_dialog->compilerArgs, fwoptions, "cmdline"); data.registerOption(m_dialog->outputFileName, fwoptions, "output_file"); data.registerOption(m_dialog->assumeFwIsPartOfAny, fwoptions, "firewall_is_part_of_any_and_networks"); data.registerOption(m_dialog->acceptSessions, fwoptions, "accept_new_tcp_with_no_syn"); data.registerOption(m_dialog->bridge, fwoptions, "bridging_fw"); data.registerOption(m_dialog->shadowing, fwoptions, "check_shading"); data.registerOption(m_dialog->emptyGroups, fwoptions, "ignore_empty_groups"); data.registerOption(m_dialog->localNAT, fwoptions, "local_nat"); slm=getActionsOnReject( platform.c_str()); m_dialog->actionOnReject->clear(); m_dialog->actionOnReject->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> actionOnReject, fwoptions,"action_on_reject", slm); data.registerOption(m_dialog->mgmt_ssh, fwoptions, "mgmt_ssh"); data.registerOption(m_dialog->mgmt_addr, fwoptions, "mgmt_addr"); data.registerOption(m_dialog->iptDebug, fwoptions, "debug"); data.registerOption(m_dialog->verifyInterfaces, fwoptions, "verify_interfaces"); data.registerOption(m_dialog->ipt_fw_dir, fwoptions, "firewall_dir"); data.registerOption(m_dialog->ipt_user, fwoptions, "admUser"); data.registerOption(m_dialog->altAddress, fwoptions, "altAddress"); data.registerOption(m_dialog->sshArgs, fwoptions, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwoptions, "scpArgs"); data.registerOption(m_dialog->activationCmd, fwoptions, "activationCmd"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText( pis->getCommand().c_str()); m_dialog->installScriptArgs->setText( pis->getArguments().c_str()); /* page "Prolog/Epilog" */ data.registerOption(m_dialog->prolog_script, fwoptions, "prolog_script"); data.registerOption(m_dialog->epilog_script, fwoptions, "epilog_script"); data.loadAll(); switchLOG_ULOG(); m_dialog->tabWidget->setCurrentIndex(0); } void ipcopAdvancedDialog::switchLOG_ULOG() { m_dialog->useLOG->setChecked(!m_dialog->useULOG->isChecked()); if (m_dialog->useLOG->isChecked()) m_dialog->logTargetStack->setCurrentIndex(0); else m_dialog->logTargetStack->setCurrentIndex(1); } /* * store all data in the object */ void ipcopAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt=(Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); /********************* data for fwbd and install script **************/ PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); // find first interface marked as "management" const InetAddr *mgmt_addr = Firewall::cast(obj)->getManagementAddress(); if (mgmt_addr) mgmt->setAddress(*mgmt_addr); pis->setCommand( m_dialog->installScript->text().toLatin1().constData()); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData()); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void ipcopAdvancedDialog::reject() { QDialog::reject(); } void ipcopAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->prolog_script->toPlainText(), true, tr( "Script Editor" )); if ( edt.exec() == QDialog::Accepted ) m_dialog->prolog_script->setText( edt.text()); } void ipcopAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->epilog_script->toPlainText(), true, tr( "Script Editor" )); if ( edt.exec() == QDialog::Accepted ) m_dialog->epilog_script->setText( edt.text()); } void ipcopAdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Firewall platform: IPCOP"); h->setSource(QUrl("ipcopAdvancedDialog.html#" + anchor)); h->raise(); h->show(); } fwbuilder-5.1.0.3599/src/libgui/ipcoposadvanceddialog_q.ui0000644000175000017500000010127611733011756024250 0ustar sylvestresylvestre ipcoposAdvancedDialog_q Qt::WindowModal 0 0 499 625 IPCOP: advanced settings QTabWidget::Rounded 2 Options Qt::Vertical QSizePolicy::Fixed 20 20 IPv4 Packet forwarding Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Horizontal QSizePolicy::Expanding 40 150 IPv6 Packet forwarding Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Kernel anti-spoofing protection Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore broadcast pings Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore all pings Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Accept source route Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Accept ICMP redirects Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore bogus ICMP errors Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Allow dynamic addresses Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Horizontal QSizePolicy::Fixed 141 21 Log martians Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false whats this text No change On Off Qt::Vertical QSizePolicy::Expanding 93 21 TCP 6 These parameters make sense for connections to or from the firewall host Qt::AlignCenter true Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Vertical QSizePolicy::Expanding 20 30 Qt::Horizontal QSizePolicy::Expanding 100 50 Qt::Horizontal QSizePolicy::Fixed 150 20 0 1000 30 0 10000 1800 No change On Off No change On Off No change On Off No change On Off No change On Off No change On Off TCP sack Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP window scaling Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP ECN Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP SYN cookies Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP keepalive time (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP fack Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP timestamps Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP FIN timeout (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Path Qt::Vertical QSizePolicy::Fixed 20 20 Specify directory path and a file name for each utility on your firewall machine. Leave these empty if you want to use default values. Qt::AlignCenter true iptables: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::RightToLeft :ip6tables ip: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false vconfig Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false brctl Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false ifenslave Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false logger: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false modprobe: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false lsmod Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false iptables-restore: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::RightToLeft :ip6tables-restore Qt::Vertical QSizePolicy::Expanding 20 60 Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true linux24_ip_forward linux24_ipv6_forward linux24_rp_filter linux24_icmp_echo_ignore_broadcasts linux24_icmp_echo_ignore_all linux24_accept_source_route linux24_accept_redirects linux24_icmp_ignore_bogus_error_responses linux24_ip_dynaddr linux24_log_martians buttonOk buttonCancel linux24_tcp_fin_timeout linux24_tcp_keepalive_interval linux24_tcp_window_scaling linux24_tcp_sack linux24_tcp_fack linux24_tcp_ecn linux24_tcp_syncookies linux24_tcp_timestamps linux24_path_iptables linux24_path_ip6tables linux24_path_ip linux24_path_vconfig linux24_path_brctl linux24_path_ifenslave linux24_path_logger linux24_path_modprobe linux24_path_lsmod linux24_path_iptables_restore linux24_path_ip6tables_restore tabWidget buttonHelp buttonCancel clicked() ipcoposAdvancedDialog_q reject() 395 447 223 239 buttonOk clicked() ipcoposAdvancedDialog_q accept() 314 447 223 239 buttonHelp clicked() ipcoposAdvancedDialog_q help() 47 447 223 239 help() fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/0000755000175000017500000000000011733011756023675 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/SelectLibraryPage.h0000644000175000017500000000262111733011756027410 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SELECTLIBRARYPAGE_H_ #define __SELECTLIBRARYPAGE_H_ #include "ui_selectlibrarypage_q.h" class SelectLibraryPage : public QWizardPage { Q_OBJECT; Ui::SelectLibraryPage_q *m_dialog; QStringList libraries; Q_PROPERTY(QStringList libraries READ getLibraries WRITE setLibraries); public: SelectLibraryPage(QWidget *parent); virtual ~SelectLibraryPage() {} virtual void initializePage(); QStringList getLibraries() { return libraries; } void setLibraries(const QStringList &l) { libraries = l; } public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/FileNamePage.cpp0000644000175000017500000000441511733011756026662 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "FWBSettings.h" #include "FileNamePage.h" #include #include #include #include using namespace std; //using namespace libfwbuilder; FileNamePage::FileNamePage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::FileNamePage_q; m_dialog->setupUi(this); registerField("fileName*", m_dialog->fileName); } void FileNamePage::selectAddressListFile() { QString s = QFileDialog::getOpenFileName( this, "Choose a file", st->getOpenFileDir(), "All files (*)"); if (s.isEmpty()) return; st->setOpenFileDir(s); m_dialog->fileName->setText(s); } bool FileNamePage::validatePage() { if (fwbdebug) qDebug() << "FileNamePage::validatePage()"; QString file_name = m_dialog->fileName->text(); QFileInfo f(file_name); if ( ! f.exists()) { QMessageBox::critical( NULL , "Firewall Builder", tr("File %1 does not exist").arg(file_name), QString::null,QString::null); return false; } if ( ! f.isReadable()) { QMessageBox::critical( NULL , "Firewall Builder", tr("Can not read file %1").arg(file_name), QString::null,QString::null); return false; } return true; } fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/HostsFile.h0000644000175000017500000000271711733011756025755 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __HOSTS_FILE_HH_FLAG__ #define __HOSTS_FILE_HH_FLAG__ #include #include #include /** * This class is parser for file in hosts(5) format * (e.g. /etc/hosts) */ class HostsFile { QString file_name; public: HostsFile(const QString &file_name) { this->file_name = file_name; } void parse() throw(libfwbuilder::FWException); // Returns all hosts found std::map getAll() { return data; } private: std::map data; }; #endif // _HOSTS_FILE_HH_ fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/SelectLibraryPage.cpp0000644000175000017500000000306011733011756027741 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "utils.h" #include "FWWindow.h" #include "SelectLibraryPage.h" #include using namespace std; //using namespace libfwbuilder; SelectLibraryPage::SelectLibraryPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::SelectLibraryPage_q; m_dialog->setupUi(this); registerField("libIndex*", m_dialog->libs); registerField("libraries", this, "libraries"); setCommitPage(true); } void SelectLibraryPage::initializePage() { if (fwbdebug) qDebug() << "SelectLibraryPage::initializePage()"; fillLibraries(m_dialog->libs, mw->activeProject()->db()); for (int i=0; i < m_dialog->libs->count(); ++i) libraries << m_dialog->libs->itemText(i); } fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/chooseobjectspage_q.ui0000644000175000017500000000232311733011756030243 0ustar sylvestresylvestre ChooseObjectsPage_q 0 0 696 475 WizardPage Choose objects you wish to use ObjectSelectorWidget QWidget
ObjectSelectorWidget.h
1
addFilter() removeFilter() selectAllResults() unselectAllResults() selectAllUsed() unselectAllUsed() addObject() removeObject()
fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/selectlibrarypage_q.ui0000644000175000017500000000371211733011756030260 0ustar sylvestresylvestre SelectLibraryPage_q 0 0 469 393 WizardPage Select library where objects should be created Object Library: 0 0 Qt::Horizontal 198 20 Qt::Vertical QSizePolicy::Expanding 20 308 fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/CreateObjectsPage.h0000644000175000017500000000227111733011756027362 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CREATEOBJECTSPAGE_H_ #define __CREATEOBJECTSPAGE_H_ #include "ui_createobjectspage_q.h" class CreateObjectsPage : public QWizardPage { Q_OBJECT; Ui::CreateObjectsPage_q *m_dialog; public: CreateObjectsPage(QWidget *parent); virtual ~CreateObjectsPage() {} virtual void initializePage(); public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/FileNamePage.h0000644000175000017500000000226611733011756026331 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FILENAMEPAGE_H_ #define __FILENAMEPAGE_H_ #include "ui_filenamepage_q.h" class FileNamePage : public QWizardPage { Q_OBJECT; Ui::FileNamePage_q *m_dialog; public: FileNamePage(QWidget *parent); virtual ~FileNamePage() {} virtual bool validatePage(); public slots: void selectAddressListFile(); }; #endif fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/CreateObjectsPage.cpp0000644000175000017500000000637411733011756027725 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "events.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "CreateObjectsPage.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include #include using namespace std; using namespace libfwbuilder; CreateObjectsPage::CreateObjectsPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::CreateObjectsPage_q; m_dialog->setupUi(this); } void CreateObjectsPage::initializePage() { if (fwbdebug) qDebug() << "CreateObjectsPage::initializePage()"; int lib_index = field("libIndex").toInt(); QStringList libraries = field("libraries").toStringList(); QStringList objects = field("objectsToUse").toStringList(); if (fwbdebug) { qDebug() << "libraries=" << libraries; qDebug() << "objects=" << objects; } m_dialog->progressBar->setFormat("%v / %m"); m_dialog->progressBar->setMaximum(objects.size() / 2); FWObject *last_object = NULL; QString name; QString addr; int counter = 1; while (objects.size() > 0) { name = objects.front(); objects.pop_front(); addr = objects.front(); objects.pop_front(); QString type; try { InetAddr(AF_INET6, addr.toLatin1().constData() ); type = IPv6::TYPENAME; } catch (FWException &ex) { } if (type.isEmpty()) { try { InetAddr(AF_INET, addr.toLatin1().constData() ); type = IPv4::TYPENAME; } catch (FWException &ex) { } } if (! type.isEmpty()) { Address *obj = Address::cast(mw->createObject(type, name)); assert(obj!=NULL); obj->setName(name.toUtf8().constData()); obj->setAddress(InetAddr(addr.toStdString())); obj->setNetmask(InetAddr(InetAddr::getAllOnes())); mw->moveObject(libraries[lib_index], obj); last_object = obj; } m_dialog->progressBar->setValue(counter); qApp->processEvents(); counter++; } ProjectPanel *pp = mw->activeProject(); QString filename = pp->getFileName(); QCoreApplication::postEvent(mw, new reloadObjectTreeEvent(filename)); QCoreApplication::postEvent( mw->activeProject(), new openLibraryForObjectEvent( filename, last_object->getId())); } fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/filenamepage_q.ui0000644000175000017500000000466711733011756027206 0ustar sylvestresylvestre FileNamePage_q 0 0 465 300 WizardPage Enter full path and file name below or click "Browse" to find it Qt::AlignVCenter true File in hosts format 6 Browse ... Qt::Vertical QSizePolicy::Expanding 444 181 browseButton clicked() FileNamePage_q selectAddressListFile() 409 73 199 149 selectAddressListFile() fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/ChooseObjectsPage.cpp0000644000175000017500000000510511733011756027731 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "ChooseObjectsPage.h" #include "HostsFile.h" #include "ObjectDescriptor.h" #include #include using namespace std; using namespace libfwbuilder; ChooseObjectsPage::ChooseObjectsPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::ChooseObjectsPage_q; m_dialog->setupUi(this); registerField("objectsToUse*", m_dialog->objectSelector, "objectsToUse", SIGNAL(selectionChanged())); } void ChooseObjectsPage::initializePage() { if (fwbdebug) qDebug() << "ChooseObjectsPage::initializePage()" << "file name" << field("fileName").toString(); try { HostsFile importer(field("fileName").toString()); importer.parse(); map imported_hosts_info = importer.getAll(); QList objects; map::iterator i; for (i=imported_hosts_info.begin(); i!=imported_hosts_info.end(); ++i) { ObjectDescriptor od; od.addr = i->first; od.sysname = i->second.front().toUtf8().constData(); objects.push_back(od); } m_dialog->objectSelector->init(objects); } catch (FWException &ex) { QMessageBox::critical( NULL , "Firewall Builder", ex.toString().c_str(), QString::null,QString::null); } } bool ChooseObjectsPage::validatePage() { if (fwbdebug) qDebug() << "ChooseObjectsPage::validatePage()"; return true; } bool ChooseObjectsPage::isComplete() const { if (fwbdebug) qDebug() << "ChooseObjectsPage::isComplete()"; return (m_dialog->objectSelector->count() > 0); } fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/createobjectspage_q.ui0000644000175000017500000000276711733011756030242 0ustar sylvestresylvestre CreateObjectsPage_q 0 0 400 300 WizardPage Adding new objects to library Qt::AlignTop true Qt::Horizontal Qt::Vertical QSizePolicy::Expanding 20 228 fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/ChooseObjectsPage.h0000644000175000017500000000240011733011756027371 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CHOOSEOBJECTSPAGE_H_ #define __CHOOSEOBJECTSPAGE_H_ #include "ui_chooseobjectspage_q.h" #include class ChooseObjectsPage : public QWizardPage { Q_OBJECT; Ui::ChooseObjectsPage_q *m_dialog; public: ChooseObjectsPage(QWidget *parent); virtual ~ChooseObjectsPage() {} virtual void initializePage(); virtual bool validatePage(); virtual bool isComplete() const; }; #endif fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/HostsFile.cpp0000644000175000017500000000472311733011756026307 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //#include "../../config.h" #include "HostsFile.h" #include #include #include extern int fwbdebug; using namespace std; using namespace libfwbuilder; void HostsFile::parse() throw(FWException) { QFile file(file_name); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) throw FWException("Can't open file '" + file_name.toStdString() + "'"); data.clear(); QRegExp comment("^\\s*#"); QRegExp hosts_line("^\\s*(\\S+)\\s+(\\S*)"); while ( ! file.atEnd()) { QString line = QString::fromUtf8(file.readLine().trimmed()); if (fwbdebug) qDebug() << "Line: " << line; if (comment.indexIn(line) > -1) continue; if (hosts_line.indexIn(line) > -1) { QString addr_s = hosts_line.cap(1); QStringList names = hosts_line.cap(2).split(","); if (fwbdebug) qDebug() << "cap(1)=" << hosts_line.cap(1) << "cap(2)=" << hosts_line.cap(2); try { InetAddr addr(AF_INET6, addr_s.toStdString()); foreach(QString name, names) data[addr] << name.trimmed(); } catch (FWException&) { try { InetAddr addr(addr_s.toStdString()); foreach(QString name, names) data[addr] << name.trimmed(); } catch (FWException &ex) { string err = ex.toString() + "\nIn line: " + line.toStdString(); throw FWException(err); } } } } } fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/ImportAddressListWizard.h0000644000175000017500000000216511733011756030647 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IMPORTADDRESSLISTWIZARD_H_ #define __IMPORTADDRESSLISTWIZARD_H_ #include class ImportAddressListWizard : public QWizard { Q_OBJECT; public: ImportAddressListWizard(QWidget *parent); virtual ~ImportAddressListWizard() {} public slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/importAddressListWizard/ImportAddressListWizard.cpp0000644000175000017500000000303511733011756031177 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "ImportAddressListWizard.h" #include "FileNamePage.h" #include "ChooseObjectsPage.h" #include "SelectLibraryPage.h" #include "CreateObjectsPage.h" #include using namespace std; //using namespace libfwbuilder; ImportAddressListWizard::ImportAddressListWizard(QWidget *parent) : QWizard(parent) { QPixmap pm; pm.load(":/Images/fwbuilder3-72x72.png"); setPixmap(QWizard::LogoPixmap, pm); setWindowTitle(tr("Import address objects from a text file in /etc/hosts format")); addPage(new FileNamePage(this)); addPage(new ChooseObjectsPage(this)); addPage(new SelectLibraryPage(this)); addPage(new CreateObjectsPage(this)); resize(700, 500); } fwbuilder-5.1.0.3599/src/libgui/starttipdialog_q.ui0000644000175000017500000001702211733011756022753 0ustar sylvestresylvestre StartTipDialog_q 0 0 529 403 Welcome to Firewall Builder :/Images/fwbuilder3-128x128.png false 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:28pt;">Firewall Builder %1</span></p></body></html> Qt::AlignCenter Qt::Horizontal 40 20 Version Qt::AlignCenter Qt::Horizontal 40 20 Qt::Horizontal 40 20 Watch Getting Started Tutorial Qt::Horizontal 40 20 QFrame::NoFrame QFrame::Plain 0 true Do not show this again Qt::Horizontal 18 17 Previous Tip false Next Tip false false false Close false true closeButton clicked() StartTipDialog_q close() 514 390 347 207 nextTipButton clicked() StartTipDialog_q nextTip() 435 390 259 133 prevTipButton clicked() StartTipDialog_q prevTip() 337 390 259 133 start_tutorial clicked() StartTipDialog_q showGettingStartedTutorial() 381 96 519 99 nextTip() prevTip() showGettingStartedTutorial() showSummary() fwbuilder-5.1.0.3599/src/libgui/pixAdvancedDialog.h0000644000175000017500000000600611733011756022561 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PIXADVANCEDDIALOG_H_ #define __PIXADVANCEDDIALOG_H_ #include #include "DialogData.h" #include class QWidget; class QSpinBox; class QComboBox; class QCheckBox; namespace libfwbuilder { class FWObject; class FWOptions; }; struct fixupControl { class QComboBox *switch_widget; class QSpinBox *arg1; class QSpinBox *arg2; class QCheckBox *arg3; QString fwoption; QString fixup_cmd; int page; // number of the notebook page in fixup_notebook widget bool active; // if false, then this fixup is not supported on the given // version of PIX OS fixupControl(QComboBox *s, QSpinBox *w1, QSpinBox *w2, QCheckBox *w3, const QString &o, const QString &f, int p) { switch_widget=s; arg1=w1; arg2=w2; arg3=w3; fwoption=o; fixup_cmd=f; page=p; active=true; } }; class pixAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; std::list allFixups; bool syslogDeviceIdSupported; Ui::pixAdvancedDialog_q *m_dialog; public: pixAdvancedDialog(QWidget *parent, libfwbuilder::FWObject *o); ~pixAdvancedDialog(); void setDefaultTimeoutValue(const QString &option); void updateFixupCommandsDisplay(); void loadFixups(); void saveFixups(libfwbuilder::FWOptions *options); int translateFixupSwitchFromOptionToWidget(int o); int translateFixupSwitchFromWidgetToOption(int o); void changeAllFixups(int state); protected slots: virtual void accept(); virtual void reject(); virtual void editProlog(); virtual void editEpilog(); virtual void defaultTimeouts(); virtual void regenerateFixups(); virtual void fixupCmdChanged(); virtual void enableAllFixups(); virtual void disableAllFixups(); virtual void skipAllFixups(); virtual void scriptACLModeChanged(); virtual void displayCommands(); }; #endif // __PIXADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/addressrangedialog_q.ui0000644000175000017500000001217411733011756023546 0ustar sylvestresylvestre AddressRangeDialog_q true 0 0 730 248 0 0 Address Range QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Range Start: false 0 0 Range End: false 0 0 Qt::Vertical 20 103 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name rangeStart rangeEnd
fwbuilder-5.1.0.3599/src/libgui/FWObjectPropertiesFactory.h0000644000175000017500000000405611733011756024266 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOBJECTPROPERTIESFACTORY_H #define __FWOBJECTPROPERTIESFACTORY_H #include namespace libfwbuilder { class FWObject; class PolicyRule; class Rule; } class FWObjectPropertiesFactory { public: /** * returns a one line property of the object for the second column of * the tree view */ static QString getObjectPropertiesBrief(libfwbuilder::FWObject *obj); static QString getObjectProperties(libfwbuilder::FWObject *obj); static QString getObjectPropertiesDetailed(libfwbuilder::FWObject *obj, bool showPath=false, bool tooltip=false, bool accentName=true, bool richText=true); static QString getRuleActionProperties(libfwbuilder::Rule *rule); static QString getRuleActionPropertiesRich(libfwbuilder::Rule *rule); static QString getPolicyRuleOptions(libfwbuilder::Rule *rule); static QString getNATRuleOptions(libfwbuilder::Rule *rule); static QString stripHTML(const QString &str); static QString getInterfaceNameExamplesForHostOS(const QString &host_os); }; #endif fwbuilder-5.1.0.3599/src/libgui/rcsfilepreview_q.ui0000644000175000017500000001777011733011756022764 0ustar sylvestresylvestre RCSFilePreview_q Qt::WindowModal true 0 0 508 488 0 0 RCSFilePreview true true 300 0 QFrame::NoFrame QFrame::Plain Qt::ScrollBarAlwaysOn false true true Revision Date Author Locked by QFrame::StyledPanel QFrame::Raised Tree View List View Qt::Horizontal 267 20 QFrame::HLine QFrame::Plain Qt::Horizontal 0 0 0 RCS log: Qt::AlignTop false 4 0 0 0 32767 80 QFrame::NoFrame Qt::Horizontal QSizePolicy::Expanding 111 30 0 30 true Open 0 30 Open read-only 0 30 Cancel RCSTreeView comment openButton openRO released() RCSFilePreview_q openReadOnly() 20 20 20 20 openButton clicked() RCSFilePreview_q openFile() 379 462 253 243 tree_view clicked() RCSFilePreview_q switchToTreeView() 66 301 253 243 list_view clicked() RCSFilePreview_q switchToListView() 160 301 253 243 switchToTreeView() switchToListView() fwbuilder-5.1.0.3599/src/libgui/TagServiceDialog.h0000644000175000017500000000260111733011756022364 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TAGSERVICEDIALOG_H_ #define __TAGSERVICEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class TagServiceDialog : public BaseObjectDialog { Q_OBJECT; Ui::TagServiceDialog_q *m_dialog; public: ~TagServiceDialog(); TagServiceDialog(QWidget *parent); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif fwbuilder-5.1.0.3599/src/libgui/colorlabelmenuitem_q.ui0000644000175000017500000001511111733011756023600 0ustar sylvestresylvestre colorLabelMenuItem_q 0 0 124 16 4 4 8 8 true Orange 8 8 true Green 8 8 true Purple 8 8 true Blue 8 8 true Yellow 8 8 true Gray 8 8 true Red 8 8 true No color redBtn clicked() colorLabelMenuItem_q redColorClicked() orangeBtn clicked() colorLabelMenuItem_q orangeColorClicked() yellowBtn clicked() colorLabelMenuItem_q yellowColorClicked() greenBtn clicked() colorLabelMenuItem_q greenColorClicked() blueBtn clicked() colorLabelMenuItem_q blueColorClicked() purpleBtn clicked() colorLabelMenuItem_q purpleColorClicked() grayBtn clicked() colorLabelMenuItem_q grayColorClicked() noneBtn clicked() colorLabelMenuItem_q noneColorClicked() fwbuilder-5.1.0.3599/src/libgui/TutorialDialog.h0000644000175000017500000000332211733011756022134 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef TUTORIALDIALOG_H #define TUTORIALDIALOG_H #include #include namespace Ui { class TutorialDialog_q; } class TutorialDialog : public QDialog { Q_OBJECT; public: TutorialDialog(QString tutorial, QWidget *parent = 0); ~TutorialDialog(); QString tutorial; QString css_stylesheet; QTextDocument *doc; QString getScenarioForPage(int page); QString getUndoForPage(int page); QString getResetForPage(int page); void runScenario(QString scenario); static void showTutorial(QString tutorial); protected: void changeEvent(QEvent *e); private: Ui::TutorialDialog_q *ui; int currentPage; void initializeTutorial(QString tutorial); static TutorialDialog *dialog; public slots: void previous(); void next(); void reset(); void showPage(int page); }; #endif // TUTORIALDIALOG_H fwbuilder-5.1.0.3599/src/libgui/ObjectIconViewItem.h0000644000175000017500000000373411733011756022711 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTICONVIEWITEM_H #define __OBJECTICONVIEWITEM_H #include #include #include #include namespace libfwbuilder { class FWObject; } class ObjectIconViewItem : public QListWidgetItem { libfwbuilder::FWObjectDatabase *db; QMap props; int ID; public: ObjectIconViewItem(QListWidget *parent) : QListWidgetItem(parent) { db = NULL; ID=-1; } ObjectIconViewItem(QListWidget *parent, const QString &text, const QPixmap &icon ) : QListWidgetItem(parent) { db = NULL; setText(text); setIcon(QIcon(icon)); ID=-1; } libfwbuilder::FWObject *getFWObject() { if (ID > -1) return db->getById(ID, true); else return NULL; } int getFWObjectID() {return ID; } void setFWObject(libfwbuilder::FWObject *obj) { db = obj->getRoot(); ID = obj->getId(); } QString getProperty(const QString &name) { return props[name]; } void setProperty(const QString &name,const QString &val) { props[name]=val; } }; #endif fwbuilder-5.1.0.3599/src/libgui/pixAdvancedDialog.cpp0000644000175000017500000010533211733011756023116 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "pixAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "CompilerDriver_pix.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; using namespace fwcompiler; pixAdvancedDialog::pixAdvancedDialog(QWidget*parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::pixAdvancedDialog_q; m_dialog->setupUi(static_cast(this)); obj = o; string version = obj->getStr("version"); string vers = "version_" + obj->getStr("version"); string platform = obj->getStr("platform"); // could be 'pix' or 'fwsm' QString s; QStringList logLevels; QStringList logLevelMapping; // logLevelMapping.push_back(""); // logLevelMapping.push_back(""); /* filling pop-down menu and pushing the same strings to the mapping * list at the same time so we could use translation */ s=QObject::tr("0 - System Unusable"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("0"); s=QObject::tr("1 - Take Immediate Action"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("1"); s=QObject::tr("2 - Critical Condition"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("2"); s=QObject::tr("3 - Error Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("3"); s=QObject::tr("4 - Warning Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("4"); s=QObject::tr("5 - Normal but significant condition"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("5"); s=QObject::tr("6 - Informational"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("6"); s=QObject::tr("7 - Debug Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("7"); /* do not need to translate syslog facilities, but will use the same * method just in case */ QStringList syslogFacilities; QStringList syslogFacilityMapping; syslogFacilities.push_back(""); syslogFacilityMapping.push_back(""); syslogFacilityMapping.push_back(""); syslogFacilities.push_back("LOCAL0"); syslogFacilityMapping.push_back("LOCAL0"); syslogFacilityMapping.push_back("16"); syslogFacilities.push_back("LOCAL1"); syslogFacilityMapping.push_back("LOCAL1"); syslogFacilityMapping.push_back("17"); syslogFacilities.push_back("LOCAL2"); syslogFacilityMapping.push_back("LOCAL2"); syslogFacilityMapping.push_back("18"); syslogFacilities.push_back("LOCAL3"); syslogFacilityMapping.push_back("LOCAL3"); syslogFacilityMapping.push_back("19"); syslogFacilities.push_back("LOCAL4"); syslogFacilityMapping.push_back("LOCAL4"); syslogFacilityMapping.push_back("20"); syslogFacilities.push_back("LOCAL5"); syslogFacilityMapping.push_back("LOCAL5"); syslogFacilityMapping.push_back("21"); syslogFacilities.push_back("LOCAL6"); syslogFacilityMapping.push_back("LOCAL6"); syslogFacilityMapping.push_back("22"); syslogFacilities.push_back("LOCAL7"); syslogFacilityMapping.push_back("LOCAL7"); syslogFacilityMapping.push_back("23"); FWOptions *fwoptions = (Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); /* Page Script */ bool f1=fwoptions->getBool("pix_acl_basic"); bool f2=fwoptions->getBool("pix_acl_no_clear"); bool f3=fwoptions->getBool("pix_acl_substitution"); bool f4=fwoptions->getBool("pix_add_clear_statements"); /* * If none of the new pix_acl_* options is set and old pix_add_clear_statements * option is true, set pix_acl_basic to true. * * If old option pix_add_clear_statements iss false, set * pix_acl_no_clear to true */ if (!f1 && !f2 && !f3) { if ( f4 ) fwoptions->setBool("pix_acl_basic",true); else fwoptions->setBool("pix_acl_no_clear",true); } Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); data.registerOption( m_dialog->short_script, fwoptions, "short_script"); /* Page "Compiler Options" */ bool outboundACLSupported= (Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/" + vers + "/pix_outbound_acl_supported")); if (outboundACLSupported) m_dialog->pix_emulate_out_acl->hide(); else m_dialog->pix_generate_out_acl->hide(); m_dialog->tabWidget->setTabEnabled(9,false); //Disable tab data.registerOption(m_dialog->ipv4before_2, fwoptions, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") <<"ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first"); data.registerOption( m_dialog->outputFileName, fwoptions, "output_file"); data.registerOption( m_dialog->pix_assume_fw_part_of_any, fwoptions, "pix_assume_fw_part_of_any"); if (XMLTools::version_compare(version, "8.3") >= 0) { m_dialog->pix_replace_natted_objects->setChecked(false); m_dialog->pix_replace_natted_objects->setEnabled(false); } else { m_dialog->pix_replace_natted_objects->setEnabled(true); data.registerOption( m_dialog->pix_replace_natted_objects, fwoptions, "pix_replace_natted_objects"); } data.registerOption( m_dialog->pix_emulate_out_acl, fwoptions, "pix_emulate_out_acl"); data.registerOption( m_dialog->pix_generate_out_acl, fwoptions, "pix_generate_out_acl"); data.registerOption( m_dialog->pix_acl_basic, fwoptions, "pix_acl_basic"); /* data.registerOption( m_dialog->pix_acl_alwaysNew, fwoptions, "pix_acl_always_new"); */ data.registerOption( m_dialog->pix_acl_no_clear, fwoptions, "pix_acl_no_clear"); data.registerOption( m_dialog->pix_acl_substitution, fwoptions, "pix_acl_substitution"); data.registerOption( m_dialog->pix_acl_temp_addr, fwoptions, "pix_acl_temp_addr"); data.registerOption( m_dialog->pix_include_comments, fwoptions, "pix_include_comments"); data.registerOption( m_dialog->pix_use_acl_remarks, fwoptions, "pix_use_acl_remarks"); data.registerOption( m_dialog->pix_regroup_commands, fwoptions, "pix_regroup_commands"); data.registerOption( m_dialog->pix_use_manual_commit, fwoptions, "pix_use_manual_commit"); m_dialog->pix_use_manual_commit->setEnabled(platform=="fwsm"); /* data.registerOption( m_dialog->pix_add_clear_statements, fwoptions, "pix_add_clear_statements"); */ data.registerOption( m_dialog->pix_optimize_default_nat, fwoptions, "pix_optimize_default_nat"); data.registerOption( m_dialog->pix_check_shadowing, fwoptions, "check_shading"); data.registerOption( m_dialog->pix_ignore_empty_groups, fwoptions, "ignore_empty_groups"); data.registerOption( m_dialog->pix_check_duplicate_nat, fwoptions, "pix_check_duplicate_nat"); data.registerOption( m_dialog->pix_check_overlapping_global_pools, fwoptions, "pix_check_overlapping_global_pools"); data.registerOption( m_dialog->pix_check_overlapping_statics, fwoptions, "pix_check_overlapping_statics"); data.registerOption( m_dialog->pix_check_overlapping_global_statics, fwoptions, "pix_check_overlapping_global_statics"); data.registerOption( m_dialog->mgmt_ssh, fwoptions, "mgmt_ssh"); data.registerOption( m_dialog->mgmt_addr, fwoptions, "mgmt_addr"); /* page Installer */ data.registerOption( m_dialog->user,fwoptions, "admUser"); data.registerOption( m_dialog->altAddress,fwoptions, "altAddress"); data.registerOption( m_dialog->sshArgs, fwoptions, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwoptions, "scpArgs"); data.registerOption( m_dialog->use_scp, fwoptions, "use_scp"); data.registerOption( m_dialog->filesystem, fwoptions, "filesystem"); data.registerOption( m_dialog->filesystem, fwoptions, "firewall_dir"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText( pis->getCommand().c_str()); m_dialog->installScriptArgs->setText( pis->getArguments().c_str()); /* page "Prolog/Epilog" */ data.registerOption( m_dialog->pix_prolog_script, fwoptions, "pix_prolog_script"); data.registerOption( m_dialog->pix_epilog_script, fwoptions, "pix_epilog_script"); /* page "Timeouts" */ data.registerOption( m_dialog->xlate_hh, fwoptions, "xlate_hh"); data.registerOption( m_dialog->xlate_mm, fwoptions, "xlate_mm"); data.registerOption( m_dialog->xlate_ss, fwoptions, "xlate_ss"); data.registerOption( m_dialog->conn_hh, fwoptions, "conn_hh"); data.registerOption( m_dialog->conn_mm, fwoptions, "conn_mm"); data.registerOption( m_dialog->conn_ss, fwoptions, "conn_ss"); data.registerOption( m_dialog->udp_hh, fwoptions, "udp_hh"); data.registerOption( m_dialog->udp_mm, fwoptions, "udp_mm"); data.registerOption( m_dialog->udp_ss, fwoptions, "udp_ss"); data.registerOption( m_dialog->rpc_hh, fwoptions, "rpc_hh"); data.registerOption( m_dialog->rpc_mm, fwoptions, "rpc_mm"); data.registerOption( m_dialog->rpc_ss, fwoptions, "rpc_ss"); data.registerOption( m_dialog->h323_hh, fwoptions, "h323_hh"); data.registerOption( m_dialog->h323_mm, fwoptions, "h323_mm"); data.registerOption( m_dialog->h323_ss, fwoptions, "h323_ss"); data.registerOption( m_dialog->sip_hh, fwoptions, "sip_hh"); data.registerOption( m_dialog->sip_mm, fwoptions, "sip_mm"); data.registerOption( m_dialog->sip_ss, fwoptions, "sip_ss"); data.registerOption( m_dialog->sip_media_hh, fwoptions, "sip_media_hh"); data.registerOption( m_dialog->sip_media_mm, fwoptions, "sip_media_mm"); data.registerOption( m_dialog->sip_media_ss, fwoptions, "sip_media_ss"); data.registerOption( m_dialog->half_closed_hh, fwoptions, "half-closed_hh"); data.registerOption( m_dialog->half_closed_mm, fwoptions, "half-closed_mm"); data.registerOption( m_dialog->half_closed_ss, fwoptions, "half-closed_ss"); data.registerOption( m_dialog->uauth_hh, fwoptions, "uauth_hh"); data.registerOption( m_dialog->uauth_mm, fwoptions, "uauth_mm"); data.registerOption( m_dialog->uauth_ss, fwoptions, "uauth_ss"); data.registerOption( m_dialog->uauth_abs, fwoptions, "uauth_abs"); data.registerOption( m_dialog->uauth_inact, fwoptions, "uauth_inact"); data.registerOption( m_dialog->telnet_timeout, fwoptions, "pix_telnet_timeout"); data.registerOption( m_dialog->ssh_timeout, fwoptions, "pix_ssh_timeout"); /* page Fixups */ allFixups.push_back(fixupControl( m_dialog->pix_ctiqbe_switch, m_dialog->pix_ctiqbe_port, NULL, NULL, "ctiqbe_fixup", "ctiqbe", 0)); allFixups.push_back(fixupControl( m_dialog->pix_dns_switch, m_dialog->pix_dns_max_length, NULL, NULL, "dns_fixup", "dns", 1)); allFixups.push_back(fixupControl( m_dialog->pix_espike_switch, NULL, NULL, NULL, "espike_fixup", "esp-ike", 2)); allFixups.push_back(fixupControl( m_dialog->pix_ftp_switch, m_dialog->pix_ftp_port, NULL, m_dialog->pix_ftp_strict, "ftp_fixup", "ftp", 3)); allFixups.push_back(fixupControl( m_dialog->pix_h323h225_switch, m_dialog->pix_h323h225_port1, m_dialog->pix_h323h225_port2, NULL, "h323_h225_fixup", "h323 h225", 4)); allFixups.push_back(fixupControl( m_dialog->pix_h323ras_switch, m_dialog->pix_h323ras_port1, m_dialog->pix_h323ras_port2, NULL, "h323_ras_fixup", "h323 ras", 5)); allFixups.push_back(fixupControl( m_dialog->pix_http_switch, m_dialog->pix_http_port1, m_dialog->pix_http_port2, NULL, "http_fixup", "http", 6)); allFixups.push_back(fixupControl( m_dialog->pix_icmperror_switch, NULL, NULL, NULL, "icmp_error_fixup", "icmp error", 7)); allFixups.push_back(fixupControl( m_dialog->pix_ils_switch, m_dialog->pix_ils_port1, m_dialog->pix_ils_port2, NULL, "ils_fixup", "ils", 8)); allFixups.push_back(fixupControl( m_dialog->pix_mgcp_switch, m_dialog->pix_mgcp_gateway_port, m_dialog->pix_mgcp_call_agent_port, NULL, "mgcp_fixup", "mgcp", 9)); allFixups.push_back(fixupControl( m_dialog->pix_pptp_switch, m_dialog->pix_pptp_port, NULL, NULL, "pptp_fixup", "pptp", 10)); allFixups.push_back(fixupControl( m_dialog->pix_rsh_switch, m_dialog->pix_rsh_port1, NULL, NULL, "rsh_fixup", "rsh", 11)); allFixups.push_back(fixupControl( m_dialog->pix_rtsp_switch, m_dialog->pix_rtsp_port, NULL, NULL, "rtsp_fixup", "rtsp", 12)); allFixups.push_back(fixupControl( m_dialog->pix_sip_switch, m_dialog->pix_sip_port1, m_dialog->pix_sip_port2, NULL, "sip_fixup", "sip", 13)); allFixups.push_back(fixupControl( m_dialog->pix_sipudp_switch, m_dialog->pix_sip_udp_port1, NULL, NULL, "sip_udp_fixup", "sip udp", 14)); allFixups.push_back(fixupControl( m_dialog->pix_skinny_switch, m_dialog->pix_skinny_port1, m_dialog->pix_skinny_port2, NULL, "skinny_fixup", "skinny", 15)); allFixups.push_back(fixupControl( m_dialog->pix_smtp_switch, m_dialog->pix_smtp_port1, m_dialog->pix_smtp_port2, NULL, "smtp_fixup", "smtp", 16)); allFixups.push_back(fixupControl( m_dialog->pix_sqlnet_switch, m_dialog->pix_sqlnet_port1, m_dialog->pix_sqlnet_port2, NULL, "sqlnet_fixup", "sqlnet", 17)); allFixups.push_back(fixupControl( m_dialog->pix_tftp_switch, m_dialog->pix_tftp_port, NULL, NULL, "tftp_fixup", "tftp", 18)); allFixups.push_back(fixupControl( m_dialog->pix_ip_options_eool_switch, NULL, NULL, NULL, "ip_options_eool_fixup", "IP options", 19)); allFixups.push_back(fixupControl( m_dialog->pix_ip_options_nop_switch, NULL, NULL, NULL, "ip_options_nop_fixup", "IP options", 20)); allFixups.push_back(fixupControl( m_dialog->pix_ip_options_rtralt_switch, NULL, NULL, NULL, "ip_options_rtralt_fixup", "IP options", 21)); QStringList allowed_fixups = QString(Resources::platform_res[platform]->getResourceStr( "/FWBuilderResources/Target/options/" + vers + "/fixups/list").c_str()).split(","); if (fwbdebug) qDebug() << "pixAdvancedDialog::pixAdvancedDialog allowed_fixups:" << allowed_fixups; for (list::iterator fi=allFixups.begin(); fi!=allFixups.end(); fi++) { if (fwbdebug) qDebug() << "pixAdvancedDialog::pixAdvancedDialog fwopt:" << fi->fwoption; if (fi->switch_widget!=NULL) connect( fi->switch_widget, SIGNAL(activated(int)), this, SLOT(fixupCmdChanged())); if (fi->arg1!=NULL) connect( fi->arg1, SIGNAL(valueChanged(int)), this, SLOT(fixupCmdChanged())); if (fi->arg2!=NULL) connect( fi->arg2, SIGNAL(valueChanged(int)), this, SLOT(fixupCmdChanged())); if (fi->arg3!=NULL) connect( fi->arg3, SIGNAL(clicked()), this, SLOT(fixupCmdChanged())); bool active = allowed_fixups.contains(fi->fwoption); fi->active = active; m_dialog->fixup_notebook->setTabEnabled( fi->page, active); } /* page Logging */ m_dialog->emblem_log_format->setEnabled( Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/"+vers+"/pix_emblem_log_format")); syslogDeviceIdSupported=(Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/"+ vers+"/pix_syslog_device_id_supported")); m_dialog->syslog_device_id_hostname->setEnabled(syslogDeviceIdSupported); m_dialog->syslog_device_id_interface->setEnabled(syslogDeviceIdSupported); m_dialog->syslog_device_id_interface_val->setEnabled(syslogDeviceIdSupported); m_dialog->syslog_device_id_string->setEnabled(syslogDeviceIdSupported); m_dialog->syslog_device_id_string_val->setEnabled(syslogDeviceIdSupported); data.registerOption( m_dialog->syslog_host, fwoptions, "pix_syslog_host"); data.registerOption( m_dialog->syslog_queue_size, fwoptions, "pix_syslog_queue_size"); m_dialog->syslog_facility->clear(); m_dialog->syslog_facility->addItems( syslogFacilities); data.registerOption( m_dialog->syslog_facility, fwoptions, "pix_syslog_facility", syslogFacilityMapping); m_dialog->logging_trap_level->clear(); m_dialog->logging_trap_level->addItems(logLevels); data.registerOption( m_dialog->logging_trap_level, fwoptions, "pix_logging_trap_level", logLevelMapping); data.registerOption( m_dialog->emblem_log_format, fwoptions, "pix_emblem_log_format"); QStringList interfaces; list l2=obj->getByType(Interface::TYPENAME); for (list::iterator i=l2.begin(); i!=l2.end(); ++i) interfaces.push_back( (Interface::cast(*i))->getLabel().c_str()); m_dialog->syslog_device_id_interface_val->addItems(interfaces); if (syslogDeviceIdSupported) { string s=fwoptions->getStr("pix_syslog_device_id_opt"); string v=fwoptions->getStr("pix_syslog_device_id_val"); if (s=="hostname") m_dialog->syslog_device_id_hostname->setChecked(true); if (s=="interface") { m_dialog->syslog_device_id_interface->setChecked(true); m_dialog->syslog_device_id_interface_val->setCurrentIndex( m_dialog->syslog_device_id_interface_val->findText(v.c_str())); } if (s=="string") { m_dialog->syslog_device_id_string->setChecked(true); m_dialog->syslog_device_id_string_val->setText(v.c_str()); } } data.registerOption( m_dialog->logging_timestamp, fwoptions, "pix_logging_timestamp"); data.registerOption( m_dialog->logging_buffered, fwoptions, "pix_logging_buffered"); m_dialog->logging_buffered_level->clear(); m_dialog->logging_buffered_level->addItems(logLevels); data.registerOption( m_dialog->logging_buffered_level, fwoptions, "pix_logging_buffered_level", logLevelMapping); data.registerOption( m_dialog->logging_console, fwoptions, "pix_logging_console"); m_dialog->logging_console_level->clear(); m_dialog->logging_console_level->addItems(logLevels); data.registerOption( m_dialog->logging_console_level,fwoptions, "pix_logging_console_level", logLevelMapping); /* page Options */ m_dialog->fragguard->setEnabled( Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/" + vers + "/pix_security_fragguard_supported")); m_dialog->route_dnat->setEnabled( Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/" + vers + "/pix_route_dnat_supported")); data.registerOption( m_dialog->fragguard, fwoptions, "pix_fragguard"); data.registerOption( m_dialog->route_dnat, fwoptions, "pix_route_dnat"); data.registerOption( m_dialog->resetinbound, fwoptions, "pix_resetinbound"); data.registerOption( m_dialog->resetoutside, fwoptions, "pix_resetoutside"); data.registerOption( m_dialog->connection_timewait, fwoptions, "pix_connection_timewait"); data.registerOption( m_dialog->floodguard, fwoptions, "pix_floodguard"); data.registerOption( m_dialog->nodnsalias_inbound, fwoptions, "pix_nodnsalias_inbound"); data.registerOption( m_dialog->nodnsalias_outbound, fwoptions, "pix_nodnsalias_outbound"); data.registerOption( m_dialog->max_conns, fwoptions, "pix_max_conns"); data.registerOption( m_dialog->emb_limit, fwoptions, "pix_emb_limit"); data.loadAll(); loadFixups(); updateFixupCommandsDisplay(); scriptACLModeChanged(); m_dialog->tabWidget->setCurrentIndex(0); } pixAdvancedDialog::~pixAdvancedDialog() { delete m_dialog; } /* * items in the switch_widget (QComboBox) | values in FirewallOptions object * | * Skip (item 0) | 2 * Enable (item 1) | 0 * Disable (item 2) | 1 * * this strange mapping is historical. * * ip options switch has the following items: * * skip * allow * drop * clear * * The last item is just added at the bottom and is mapped to FirewallOptions * value "3" * */ static int fixupOpt2Widget[] = { 1, 2, 0, 3 }; static int fixupWidget2Opt[] = { 2, 0, 1, 3 }; int pixAdvancedDialog::translateFixupSwitchFromOptionToWidget(int o) { return fixupOpt2Widget[o]; } int pixAdvancedDialog::translateFixupSwitchFromWidgetToOption(int w) { return fixupWidget2Opt[w]; } void pixAdvancedDialog::enableAllFixups() { changeAllFixups(0); } void pixAdvancedDialog::disableAllFixups() { changeAllFixups(1); } void pixAdvancedDialog::skipAllFixups() { changeAllFixups(2); } void pixAdvancedDialog::changeAllFixups(int state) { for (list::iterator fi=allFixups.begin(); fi!=allFixups.end(); fi++) { if (!fi->active) continue; fi->switch_widget->setCurrentIndex( translateFixupSwitchFromOptionToWidget(state) ); } updateFixupCommandsDisplay(); } void pixAdvancedDialog::loadFixups() { FWOptions *options=(Firewall::cast(obj))->getOptionsObject(); assert(options!=NULL); for (list::iterator fi=allFixups.begin(); fi!=allFixups.end(); fi++) { if (!fi->active) continue; string f = options->getStr(fi->fwoption.toLatin1().constData()); if (!f.empty()) { // "0" means "fixup" or "enable" in a pop-down menu (historical) // "1" means "no fixup" or "disable" in a pop-down menu (historical) int sw; int p1,p2; // two port numbers string arg3n; // option name bool arg3v; // option state (on/off) istringstream str(f); str >> sw >> p1 >> p2 >> arg3n >> arg3v; if (arg3n=="nil") arg3n=""; fi->switch_widget->setCurrentIndex( translateFixupSwitchFromOptionToWidget(sw) ); /* if values are 0 in the data file, we stick with defaults. Defaults * are preconfigured in the GUI */ if (fi->arg1 && p1!=0) fi->arg1->setValue(p1); if (fi->arg2 && p2!=0) fi->arg2->setValue(p2); if (fi->arg3) fi->arg3->setChecked(arg3v); } else { fi->switch_widget->setCurrentIndex(0); } } } void pixAdvancedDialog::saveFixups(FWOptions *options) { for (list::iterator fi=allFixups.begin(); fi!=allFixups.end(); fi++) { string name = fi->fwoption.toLatin1().constData(); int sw = translateFixupSwitchFromWidgetToOption( fi->switch_widget->currentIndex()); int p1 =(fi->arg1)?fi->arg1->value():0; int p2 =(fi->arg2)?fi->arg2->value():0; string on =(name=="ftp_fixup")?"strict":"nil"; bool ov =(fi->arg3)?fi->arg3->isChecked():false; if (!fi->active) sw=2; ostringstream str; str << sw << " " << p1 << " " << p2 << " " << on << " " << int(ov); options->setStr( fi->fwoption.toLatin1().constData(), str.str() ); if (fwbdebug) qDebug() << "pixAdvancedDialog::saveFixups()" << name.c_str() << str.str().c_str(); } } void pixAdvancedDialog::displayCommands() { m_dialog->pix_generated_fixup->setText(""); /* * need to copy information from widgets that control fixups into * firewall object's options, so that when we dump the database into * memory buffer, we get updated info * * This creates a problem however: since we save changes into the * actual object here, the undo/redo commands don't work later on in * accept() because we do not detect any changes and undo command is * not placed on undo stack. Need to save FWOptions object, save fixup * parameters into it, generate commands and then restore FWOptions * object back */ FWOptions *options = (Firewall::cast(obj))->getOptionsObject(); assert(options!=NULL); FWOptions *backup_options = new FWOptions(); backup_options->duplicate(options, false); saveFixups(options); CompilerDriver_pix driver(obj->getRoot()); driver.setTargetId(FWObjectDatabase::getStringId(obj->getId())); string inspectors = driver.protocolInspectorCommands(); m_dialog->pix_generated_fixup->setText(inspectors.c_str()); options->duplicate(backup_options, false); delete backup_options; } void pixAdvancedDialog::updateFixupCommandsDisplay() { displayCommands(); } void pixAdvancedDialog::fixupCmdChanged() { updateFixupCommandsDisplay(); } /* * store all data in the object */ void pixAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); saveFixups(fwoptions); // find first interface marked as "management" const InetAddr *mgmt_addr = Firewall::cast(new_state)->getManagementAddress(); if (mgmt_addr) mgmt->setAddress(*mgmt_addr); if (syslogDeviceIdSupported) { QString s,v; s=""; v=""; if (m_dialog->syslog_device_id_hostname->isChecked()) s="hostname"; if (m_dialog->syslog_device_id_interface->isChecked()) { s="interface"; v=m_dialog->syslog_device_id_interface_val->currentText(); } if (m_dialog->syslog_device_id_string->isChecked()) { s="string"; v=m_dialog->syslog_device_id_string_val->text(); } fwoptions->setStr("pix_syslog_device_id_opt",s.toLatin1().constData()); fwoptions->setStr("pix_syslog_device_id_val",v.toLatin1().constData()); } PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); pis->setCommand( m_dialog->installScript->text().toLatin1().constData() ); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void pixAdvancedDialog::reject() { QDialog::reject(); } void pixAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->pix_prolog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->pix_prolog_script->setText( edt.text() ); } void pixAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->pix_epilog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->pix_epilog_script->setText( edt.text() ); } void pixAdvancedDialog::setDefaultTimeoutValue(const QString &option) { string platform = obj->getStr("platform"); // could be 'pix' or 'fwsm' FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); string vers="version_"+obj->getStr("version"); if (option=="uauth_abs" || option=="uauth_inact") data.setWidgetValue(option.toAscii().constData(), Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/"+vers+"/timeouts/"+option.toLatin1().constData())); else data.setWidgetValue(option.toAscii().constData(), Resources::platform_res[platform]->getResourceInt( "/FWBuilderResources/Target/options/"+vers+"/timeouts/"+option.toLatin1().constData())); } void pixAdvancedDialog::defaultTimeouts() { FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); string vers="version_"+obj->getStr("version"); setDefaultTimeoutValue("xlate_hh" ); setDefaultTimeoutValue("xlate_mm" ); setDefaultTimeoutValue("xlate_ss" ); setDefaultTimeoutValue("conn_hh" ); setDefaultTimeoutValue("conn_mm" ); setDefaultTimeoutValue("conn_ss" ); setDefaultTimeoutValue("udp_hh" ); setDefaultTimeoutValue("udp_mm" ); setDefaultTimeoutValue("udp_ss" ); setDefaultTimeoutValue("rpc_hh" ); setDefaultTimeoutValue("rpc_mm" ); setDefaultTimeoutValue("rpc_ss" ); setDefaultTimeoutValue("h323_hh" ); setDefaultTimeoutValue("h323_mm" ); setDefaultTimeoutValue("h323_ss" ); setDefaultTimeoutValue("sip_hh" ); setDefaultTimeoutValue("sip_mm" ); setDefaultTimeoutValue("sip_ss" ); setDefaultTimeoutValue("sip_media_hh" ); setDefaultTimeoutValue("sip_media_mm" ); setDefaultTimeoutValue("sip_media_ss" ); setDefaultTimeoutValue("half-closed_hh" ); setDefaultTimeoutValue("half-closed_mm" ); setDefaultTimeoutValue("half-closed_ss" ); setDefaultTimeoutValue("uauth_hh" ); setDefaultTimeoutValue("uauth_mm" ); setDefaultTimeoutValue("uauth_abs" ); setDefaultTimeoutValue("uauth_inact" ); setDefaultTimeoutValue("telnet_timeout" ); setDefaultTimeoutValue("ssh_timeout" ); } void pixAdvancedDialog::regenerateFixups() { } void pixAdvancedDialog::scriptACLModeChanged() { m_dialog->pix_acl_temp_lbl->setEnabled(m_dialog->pix_acl_substitution->isChecked()); m_dialog->pix_acl_temp_addr->setEnabled(m_dialog->pix_acl_substitution->isChecked()); } fwbuilder-5.1.0.3599/src/libgui/metriceditorpanel_q.ui0000644000175000017500000000510611733011756023433 0ustar sylvestresylvestre MetricEditorPanel_q true 0 0 359 247 Script Editor true 0 0 64 0 64 16777215 QAbstractSpinBox::PlusMinus 255 1 Qt::Horizontal 258 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 spin_box valueChanged(int) MetricEditorPanel_q changed() 20 20 20 20 changed() fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator.h0000644000175000017500000004014011733011756022632 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTMANIPULATOR_H_ #define __OBJECTMANIPULATOR_H_ #include "config.h" #include "global.h" #include "utils.h" #include #include #include #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/ObjectGroup.h" #include "UsageResolver.h" #include class ObjectTreeView; class ObjectTreeViewItem; class QComboBox; class QPixmap; class QUndoCommand; class ListOfLibrariesModel; class ProjectPanel; namespace libfwbuilder { class Firewall; class Cluster; class Library; } class HistoryItem { ObjectTreeViewItem *itm; int objId; public: HistoryItem(ObjectTreeViewItem *oi, int id) { itm=oi; objId=id; } ~HistoryItem(); ObjectTreeViewItem* item() { return itm; } int id() const { return objId; } }; class FindHistoryItemByObjectId { int id; public: FindHistoryItemByObjectId(int i) { id = i; } bool operator()(const HistoryItem &itm); }; class ObjectManipulator : public QWidget { Q_OBJECT; ListOfLibrariesModel *libs_model; // std::vector idxToLibs; // std::vector idxToTrees; int previous_lib_index; QSet ids ; /* * this is where we keep information about user's object browsing * history. Even though latest versions of the GUI do not offer * buttons "Back" and "Forward", history is still used to * determine which rule set object to open when user double clicks * on a firewall. We want to open the rule set they looked at * last. This whole browsing history infrastructure might be an * overkill for the simple purpose like that, but I'll keep it * around beause I do not want to make drastic changes so close to * the release date and it may become useful again in the * future. Otherwise, we can get rid of it later. --vk 07/22/2011 */ std::list history; std::list::iterator current_history_item; int cacheHits; //libfwbuilder::FWObject *currentObj; ObjectTreeView *current_tree_view; int treeWidth; int treeHeight; bool active; QMenu *popup_menu; /* this is a reverse idex of all objects in all trees. We use it to * quickly locate given object in the tree and open it */ std::map allItems; ProjectPanel *m_project; int dedup_marker_global_counter; void buildNewObjectMenu(); ObjectTreeViewItem* insertObject(ObjectTreeViewItem *itm, libfwbuilder::FWObject *obj); void insertSubtree( ObjectTreeViewItem *itm,libfwbuilder::FWObject *obj ); QString getTreeLabel(libfwbuilder::FWObject *obj, int col); void showObjectInTree(ObjectTreeViewItem *otvi); void setObjectIcon(libfwbuilder::FWObject *obj, QPixmap *pm); void removeLib(int idx); void makeNameUnique(libfwbuilder::FWObject* p,libfwbuilder::FWObject* obj); void expandOrCollapseCurrentTreeNode(QTreeWidgetItem*, bool); /* find the name of the interface that was created last */ QString findNewestInterfaceName(libfwbuilder::FWObject *parent); libfwbuilder::FWObject* actuallyCreateObject( libfwbuilder::FWObject *parent, const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL, QUndoCommand* macro = 0); void extractFirewallsFromGroup(libfwbuilder::ObjectGroup *gr, std::set &fo); libfwbuilder::FWObject* actuallyPasteTo(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj, std::map &map_ids); void actuallyDeleteObject(libfwbuilder::FWObject *obj, QUndoCommand* macro = 0); void findWhereUsedRecursively(libfwbuilder::FWObject *obj, libfwbuilder::FWObject *top, std::set &resset); void refreshSubtree(QTreeWidgetItem *parent, QTreeWidgetItem *itm); libfwbuilder::FWObject* newLibrary(QUndoCommand* macro); libfwbuilder::FWObject* newHost(QUndoCommand* macro); libfwbuilder::FWObject* newInterface(QUndoCommand* macro); libfwbuilder::FWObject* newFirewall(QUndoCommand* macro); libfwbuilder::FWObject* newCluster(QUndoCommand* macro, bool fromSelected = false); libfwbuilder::FWObject* newClusterIface(QUndoCommand* macro); libfwbuilder::FWObject* newStateSyncClusterGroup(QUndoCommand* macro); libfwbuilder::FWObject* newFailoverClusterGroup(QUndoCommand* macro); libfwbuilder::FWObject* newInterfaceAddress(QUndoCommand* macro); libfwbuilder::FWObject* newInterfaceAddressIPv6(QUndoCommand* macro); libfwbuilder::FWObject* newPhysicalAddress(QUndoCommand* macro); libfwbuilder::FWObject* newPolicyRuleSet (QUndoCommand* macro); libfwbuilder::FWObject* newNATRuleSet (QUndoCommand* macro); libfwbuilder::FWObject* newAttachedNetworks(QUndoCommand* macro); public slots: virtual void libChanged(int l); virtual void switchingTrees(QWidget* w); virtual void currentTreePageChanged(int i); void expandCurrentTreeNode(); void collapseCurrentTreeNode(); void newClusterFromSelected(); void selectionChanged(QTreeWidgetItem *cur); void removeUserFolder(); void moveItems(ObjectTreeViewItem *dest, const std::list &items); /** * open object obj in the editor. Does not open editor panel * if it is closed. Asks FWWindow permission to own editor. */ bool switchObjectInEditor(libfwbuilder::FWObject *obj); /** * same as above but opens editor panel if it is closed. This is * an entry point for menu items 'edit', all 'new object' as well * as doubleclick */ bool editObject(libfwbuilder::FWObject *obj); /* * forget about currently opened object; close editor panel if it is open */ void closeObject(); void editSelectedObject(); void openSelectedRuleSet(); void contextMenuRequested(const QPoint &pos); /* * Internal: this method is used in actuallyPasteTo(). This * method checks if the target object is appropriate and replaces * it with parent if needed. Also does validation and shows error * dialogs if validation fails. Returns new parent or NULL if * validation fails. */ libfwbuilder::FWObject* prepareForInsertion(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); libfwbuilder::FWObject* createObject(const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL, QUndoCommand* macro = 0); libfwbuilder::FWObject* createObject(libfwbuilder::FWObject *parent, const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL, QUndoCommand* macro = 0); void newObject(); void createNewObject(); void newFirewallSlot(); void copyObj(); void cutObj(); void pasteObj(); void delObj(QUndoCommand* macro = 0); void dumpObj(); void compile(); void install(); void inspect(); void duplicateObj(QAction*); void moveObj(QAction*); void undeleteLibrary(); void groupObjects(); void openObjectInTree(QTreeWidgetItem *otvi); void openObjectInTree(libfwbuilder::FWObject *obj); void find(); void findObject(); virtual void lockObject(); virtual void unlockObject(); virtual void simulateInstall(); virtual void findWhereUsedSlot(); void addSubfolderSlot(); void addNewKeywordSlot(); void processKeywordSlot(); void makeSubinterface(QAction*); public: Ui::ObjectManipulator_q *m_objectManipulator; ObjectManipulator(QWidget *parent); ~ObjectManipulator(); void setupProject(ProjectPanel *project); void libChangedById(int id); libfwbuilder::FWObject* getNextUserLib(libfwbuilder::FWObject *after_this=NULL); std::vector getTreeWidgets(); void filterFirewallsFromSelection( std::vector &so, std::set &fo); QString getStandardName(libfwbuilder::FWObject *parent, const std::string &objtype, const std::string &namesuffix); QString makeNameUnique(libfwbuilder::FWObject* parent, const QString &obj_name, const QString &obj_type); void autorename(libfwbuilder::FWObject *obj); void autorename(std::list &obj_list, const std::string &objtype, const std::string &namesuffix); void autorenameVlans(std::list &obj_list); void reload(); void loadObjects(); void clearObjects(); /* Add/remove user folder from tree */ void addUserFolderToTree(libfwbuilder::FWObject *obj, const QString &folder); void removeUserFolderFromTree(libfwbuilder::FWObject *obj, const QString &folder); void moveToFromUserFolderInTree(libfwbuilder::FWObject *parent, libfwbuilder::FWObject *objToMove, const QString &oldFolder, const QString &newFolder); void reopenCurrentItemParent(); void insertSubtree(libfwbuilder::FWObject *parent, libfwbuilder::FWObject *obj); void removeObjectFromTreeView(libfwbuilder::FWObject *obj ); void addLib(libfwbuilder::FWObject *lib); void removeLib(libfwbuilder::FWObject *lib); void openLibForObject(libfwbuilder::FWObject *obj); void openObjectInTree(libfwbuilder::FWObject *obj, bool register_in_history); void openObjectInTree(ObjectTreeViewItem *otvi, bool register_in_history); void removeObjectFromHistory(libfwbuilder::FWObject *obj); void addObjectToHistory(ObjectTreeViewItem* otvi, libfwbuilder::FWObject *obj); ObjectTreeViewItem* getCurrentHistoryItem(); /* * searches history trying to find an object that has given * parent. Used to find which rule set of the firewall user * looked at last. */ libfwbuilder::FWObject* findRuleSetInHistoryByParentFw( libfwbuilder::FWObject* parent); void expandObjectInTree(libfwbuilder::FWObject *obj); libfwbuilder::FWObject* duplicateObject(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); void moveObject(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); void moveObject(const QString &targetLibName, libfwbuilder::FWObject *obj); // This method is called toprocess event objectMovedEvent. this event is // posted by FWCmdMoveObject after the object is moved from one // part of the tree to another, including when an object moves to the // Deleted Objects library void objectMoved(libfwbuilder::FWObject *obj); libfwbuilder::FWObject* pasteTo(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); void updateLibColor(libfwbuilder::FWObject *lib); void updateLibName(libfwbuilder::FWObject *lib); void autoRenameChildren(libfwbuilder::FWObject *obj, const QString &oldName); void updateObjectInTree(libfwbuilder::FWObject *obj, bool subtree=false); void updateCreateObjectMenu(libfwbuilder::FWObject* lib); ObjectTreeView* getCurrentObjectTree(); libfwbuilder::FWObject* getSelectedObject(); /** * this method opens given library in the tree */ void openLib(libfwbuilder::FWObject *lib); /** * returns pointer at a library that is currently opened in the tree */ libfwbuilder::FWObject* getCurrentLib(); /** * this method makes sure the system library is NOT opened in the * tree. If it is, it switches to the 'User' library. If one of * the user's libraries is already opened, it does nothing. */ void closeSystemLib(); void deleteObject(libfwbuilder::FWObject *obj, QUndoCommand* macro = 0); /** * select whatever object is current in the tree (used to restore * selected state of the tree item after it was unselected) */ void select(); /** * unselect whatever object is currently selected */ void unselect(); /** * controls whether "Deleted Objects" library is shown */ void showDeletedObjects(bool f); /** * checks if currently selected object can be locked. Note that * if its parent or any object all the way up to the library is * read-only, then the state of the current object can not be * changed which makes it not lockable. */ bool isCurrentObjectLockable(); bool isCurrentObjectUnlockable(); /** * get boolean flags that describe state of the menu items. * Can be used for both pop-up context menu and the main menu. */ void getMenuState(bool haveMoveTargets, bool &dupMenuItem, bool &moveMenuItem, bool ©MenuItem, bool &pasteMenuItem, bool &delMenuItem, bool &newMenuItem, bool &inDeletedObjects); bool getDeleteMenuState(libfwbuilder::FWObject *obj); void updateLastInstalledTimestamp(libfwbuilder::FWObject *o); void updateLastCompiledTimestamp(libfwbuilder::FWObject *o); std::list findFirewallsForObject( libfwbuilder::FWObject *o); void findAllFirewalls(std::list &fws); std::list findClustersUsingFirewall(libfwbuilder::FWObject *fw); void findAllClusters(std::list &fws); void loadExpandedTreeItems(); void saveExpandedTreeItems(); void loadSectionSizes(); void saveSectionSizes(); void setAttributesColumnEnabled(bool f); QAction* addNewObjectMenuItem(QMenu *menu, const char* type_name, const QString &text=QString(), int add_to_group_id=-1); void addSubinterfaceSubmenu( QMenu *menu, const std::list &top_level_interfaces); bool isObjectAllowed(const QString &type_name); bool isObjectAllowed(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); void reminderAboutStandardLib(); signals: void libraryAccessChanged(bool writable); }; #endif fwbuilder-5.1.0.3599/src/libgui/RuleNode.cpp0000644000175000017500000000546311733011756021271 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RuleNode.h" RuleNode::RuleNode(Type type, const QString &str ) { this->type = type; this->name = str; parent = 0; } RuleNode::~RuleNode() { qDeleteAll(children); } void RuleNode::add(RuleNode * node) { children << node; node->parent = this; } void RuleNode::prepend(RuleNode * node) { children.prepend(node); node->parent = this; } void RuleNode::insert(int pos, RuleNode* node) { children.insert(pos, node); node->parent = this; } bool RuleNode::isInGroup() { if (parent == 0) return false; return !parent->isRoot(); } bool RuleNode::isRoot() { return type == RuleNode::Root; } QString RuleNode::groupName() { if (isInGroup()) return parent->name; return QString(); } QString RuleNode::nameOfSuccessorGroup() { if (parent == 0 || isInGroup()) return QString(); int idx = parent->children.indexOf(this); if (idx < (parent->children.size() - 1) && parent->children[idx + 1]->type == Group) { return parent->children[idx + 1]->name; } return QString(); } QString RuleNode::nameOfPredecessorGroup() { if (parent == 0 || isInGroup()) return QString(); int idx = parent->children.indexOf(this); if (idx > 0 && parent->children[idx - 1]->type == Group) { return parent->children[idx - 1]->name; } return QString(); } bool RuleNode::isOutermost() { if (type != RuleNode::Rule) return false; return this == this->parent->children.first() || this == this->parent->children.last(); } bool RuleNode::operator==(const RuleNode &rn) const { if (rn.type != this->type) return false; if (this->type == Group) { return this->name == rn.name; } else { return this->rule == rn.rule; } } void RuleNode::resetSizes() { for(int i=0;iresetAllSizes(); } } fwbuilder-5.1.0.3599/src/libgui/pixosifaceoptsdialog_q.ui0000644000175000017500000001671711733011756024153 0ustar sylvestresylvestre pixosIfaceOptsDialog_q 0 0 418 322 PIX: interface settings Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 Options :/Icons/Options:/Icons/Options Qt::Vertical QSizePolicy::Fixed 20 16 Qt::RightToLeft Device Type Qt::Horizontal 40 20 0 0 1 true Qt::RightToLeft VLAN ID 4095 Qt::Horizontal 140 20 Qt::Vertical 20 43 buttonOk buttonCancel tabWidget buttonOk clicked() pixosIfaceOptsDialog_q accept() 316 472 20 20 buttonCancel clicked() pixosIfaceOptsDialog_q reject() 397 472 20 20 buttonHelp clicked() pixosIfaceOptsDialog_q help() 68 464 231 245 iface_type currentIndexChanged(QString) pixosIfaceOptsDialog_q typeChanged(QString) 287 196 286 261 typeChanged(QString) bondingPolicyChanged(QString) fwbuilder-5.1.0.3599/src/libgui/utils_no_qt.cpp0000644000175000017500000000653211733011756022112 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //#include "../../config.h" <- TAPIR: wasn't commented #include "global.h" #include "utils_no_qt.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #include #include #include using namespace std; using namespace libfwbuilder; /** * this method finds all firewalls in the tree and makes no * assumtions about tree structure */ void findFirewalls(FWObject *o, std::list &fwlist, bool skip_system_libs) { findByObjectType(o,Firewall::TYPENAME,fwlist,skip_system_libs); } void findClusters(FWObject *o, std::list &fwlist, bool skip_system_libs) { findByObjectType(o, Cluster::TYPENAME, fwlist, skip_system_libs); } void findHosts(FWObject *o, std::list &fwlist, bool skip_system_libs) { findByObjectType(o,Host::TYPENAME,fwlist,skip_system_libs); } void findByObjectType(FWObject *o, const string &otype, list &fwlist, bool skip_system_libs) { if (skip_system_libs) { if (o->getId()==FWObjectDatabase::DELETED_OBJECTS_ID) return; if (o->getId()==FWObjectDatabase::TEMPLATE_LIB_ID) return; } for (list::iterator m=o->begin(); m!=o->end(); m++) { FWObject *o1=*m; if (FWReference::cast(o1)!=NULL) continue; if (o1->getTypeName()==otype) fwlist.push_back(o1); else findByObjectType(o1,otype,fwlist); } } /** * Find reference to object in the group and return * pointer to that reference object. If no such reference exists, * return NULL. */ FWReference* findRef(FWObject *o, FWObject *container) { FWReference* ref=NULL; FWObject::iterator i = container->begin(); for(; i!=container->end(); ++i) { ref = FWReference::cast(*i); if (ref!=NULL && ref->getPointer() == o) { break; } ref=NULL; } return ref; } string strip(const string &s) { if (s.empty()) return s; string tmps = s; string::size_type n1,n2; n1 = s.find_first_not_of(" ", 0); n2 = s.size()-1; while (n2>n1 && isspace(s[n2])) n2--; n2++; return s.substr(n1, n2-n1); } string getPathToBinary(const string &pgm_name) { return appRootDir + FS_SEPARATOR + pgm_name; } fwbuilder-5.1.0.3599/src/libgui/carpoptionsdialog_q.ui0000644000175000017500000002165011733011756023444 0ustar sylvestresylvestre carpOptionsDialog_q 0 0 408 391 CARP protocol settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 CARP Parameters :/Icons/Options:/Icons/Options Qt::Vertical QSizePolicy::Minimum 20 20 true CARP password Qt::RightToLeft CARP password true true Virtual Host ID Qt::RightToLeft VHID 1 255 1 Qt::Horizontal 78 20 Advertisement interval (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 255 1 Qt::Horizontal 78 20 Master advskew Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 254 50 Qt::Horizontal 78 20 Default advskew Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 254 100 Qt::Horizontal 78 20 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() carpOptionsDialog_q accept() 316 472 193 137 buttonCancel clicked() carpOptionsDialog_q reject() 397 472 20 20 fwbuilder-5.1.0.3599/src/libgui/DialogFactory.cpp0000644000175000017500000003357611733011756022311 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "DialogFactory.h" #include "LibraryDialog.h" #include "RuleSetDialog.h" #include "AddressRangeDialog.h" #include "IPv4Dialog.h" #include "IPv6Dialog.h" #include "PhysicalAddressDialog.h" #include "DNSNameDialog.h" #include "AddressTableDialog.h" #include "AttachedNetworksDialog.h" #include "NetworkDialog.h" #include "NetworkDialogIPv6.h" #include "UserDialog.h" #include "CustomServiceDialog.h" #include "ICMPServiceDialog.h" #include "IPServiceDialog.h" #include "TCPServiceDialog.h" #include "UDPServiceDialog.h" #include "GroupObjectDialog.h" #include "DynamicGroupDialog.h" #include "HostDialog.h" #include "FirewallDialog.h" #include "ClusterDialog.h" #include "ClusterGroupDialog.h" #include "InterfaceDialog.h" #include "TimeDialog.h" #include "TagServiceDialog.h" #include "iptAdvancedDialog.h" #include "ipfAdvancedDialog.h" #include "ipfwAdvancedDialog.h" #include "pfAdvancedDialog.h" #include "pixAdvancedDialog.h" #include "iosaclAdvancedDialog.h" #include "ipcopAdvancedDialog.h" #include "secuwallAdvancedDialog.h" #include "procurveaclAdvancedDialog.h" #include "linux24IfaceOptsDialog.h" #include "secuwallIfaceOptsDialog.h" #include "vlanOnlyIfaceOptsDialog.h" #include "bsdIfaceOptsDialog.h" #include "pixosIfaceOptsDialog.h" #include "clusterMembersDialog.h" #include "linux24AdvancedDialog.h" #include "linksysAdvancedDialog.h" #include "freebsdAdvancedDialog.h" #include "openbsdAdvancedDialog.h" #include "solarisAdvancedDialog.h" #include "macosxAdvancedDialog.h" #include "pixosAdvancedDialog.h" #include "iosAdvancedDialog.h" #include "ipcoposAdvancedDialog.h" #include "secuwallosAdvancedDialog.h" #include "RuleOptionsDialog.h" #include "RoutingRuleOptionsDialog.h" #include "NATRuleOptionsDialog.h" #include "vrrpOptionsDialog.h" #include "carpOptionsDialog.h" #include "pixFailoverOptionsDialog.h" #include "conntrackOptionsDialog.h" #include "heartbeatOptionsDialog.h" #include "openaisOptionsDialog.h" #include "pfsyncOptionsDialog.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Resources.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include #include "ProjectPanel.h" using namespace std; using namespace libfwbuilder; BaseObjectDialog *DialogFactory::createDialog(QWidget *parent, const QString &objType) { if (objType==UserService::TYPENAME) return new UserDialog(parent); if (objType==Policy::TYPENAME) return new RuleSetDialog(parent); if (objType==NAT::TYPENAME) return new RuleSetDialog(parent); if (objType==Routing::TYPENAME) return new RuleSetDialog(parent); if (objType==Library::TYPENAME) return new LibraryDialog(parent); if (objType==IPv4::TYPENAME) return new IPv4Dialog(parent); if (objType==IPv6::TYPENAME) return new IPv6Dialog(parent); if (objType==physAddress::TYPENAME) return new PhysicalAddressDialog(parent); if (objType==DNSName::TYPENAME) return new DNSNameDialog(parent); if (objType==AddressTable::TYPENAME) return new AddressTableDialog(parent); if (objType==AddressRange::TYPENAME) return new AddressRangeDialog(parent); if (objType==Firewall::TYPENAME) return new FirewallDialog(parent); if (objType==Cluster::TYPENAME) return new ClusterDialog(parent); if (objType==StateSyncClusterGroup::TYPENAME) return new ClusterGroupDialog(parent); if (objType==FailoverClusterGroup::TYPENAME) return new ClusterGroupDialog(parent); if (objType==Host::TYPENAME) return new HostDialog(parent); if (objType==Interface::TYPENAME) return new InterfaceDialog(parent); if (objType==AttachedNetworks::TYPENAME) return new AttachedNetworksDialog(parent); if (objType==Network::TYPENAME) return new NetworkDialog(parent); if (objType==NetworkIPv6::TYPENAME) return new NetworkDialogIPv6(parent); if (objType==CustomService::TYPENAME) return new CustomServiceDialog(parent); if (objType==IPService::TYPENAME) return new IPServiceDialog(parent); if (objType==ICMPService::TYPENAME) return new ICMPServiceDialog(parent); if (objType==ICMP6Service::TYPENAME) return new ICMPServiceDialog(parent); if (objType==TCPService::TYPENAME) return new TCPServiceDialog(parent); if (objType==UDPService::TYPENAME) return new UDPServiceDialog(parent); if (objType==ObjectGroup::TYPENAME) return new GroupObjectDialog(parent); if (objType==DynamicGroup::TYPENAME) return new DynamicGroupDialog(parent); if (objType==ServiceGroup::TYPENAME) return new GroupObjectDialog(parent); if (objType==TagService::TYPENAME) return new TagServiceDialog(parent); if (objType==IntervalGroup::TYPENAME) return new GroupObjectDialog(parent); if (objType==Interval::TYPENAME) return new TimeDialog(parent); if (objType==RoutingRule::TYPENAME) return new RoutingRuleOptionsDialog(parent); if (objType==Rule::TYPENAME) return new RuleOptionsDialog(parent); if (objType==PolicyRule::TYPENAME) return new RuleOptionsDialog(parent); if (objType==NATRule::TYPENAME) return new NATRuleOptionsDialog(parent); return NULL; } QWidget *DialogFactory::createFWDialog(QWidget *parent, FWObject *o) throw(FWException) { string platform = o->getStr("platform"); string host_os = o->getStr("host_OS"); Resources* platform_res = Resources::platform_res[platform]; if (platform_res==NULL) throw FWException( (const char*)(QObject::tr("Support module for %1 is not available"). arg(platform.c_str()).toLocal8Bit().constData())); Resources* os_res = Resources::os_res[host_os]; if (os_res==NULL) throw FWException( (const char*)(QObject::tr("Support module for %1 is not available"). arg(host_os.c_str()).toLocal8Bit().constData())); string os_family = os_res->getResourceStr( "/FWBuilderResources/Target/family"); string dlgname = platform_res->Resources::getResourceStr( "/FWBuilderResources/Target/dialog"); if (platform == "iptables" && os_family == "ipcop") dlgname = "ipcop"; if (platform == "iptables" && os_family == "secuwall") dlgname = "secuwall"; if (dlgname=="iosacl") return new iosaclAdvancedDialog(parent,o); if (dlgname=="ipcop") return new ipcopAdvancedDialog(parent,o); if (dlgname=="ipf") return new ipfAdvancedDialog(parent,o); if (dlgname=="ipfw") return new ipfwAdvancedDialog(parent,o); if (dlgname=="iptables") return new iptAdvancedDialog(parent,o); if (dlgname=="pf") return new pfAdvancedDialog(parent,o); if (dlgname=="pix") return new pixAdvancedDialog(parent,o); if (dlgname=="secuwall") return new secuwallAdvancedDialog(parent,o); if (dlgname=="procurveacl") return new procurveaclAdvancedDialog(parent,o); cerr << "Firewall settings dialog for " << dlgname << " is not implemented" << endl; return NULL; } QWidget *DialogFactory::createOSDialog(QWidget *parent,FWObject *o) throw(FWException) { string host_os = o->getStr("host_OS"); Resources *os = Resources::os_res[host_os]; if (os==NULL) throw FWException( (const char*)(QObject::tr("Support module for %1 is not available"). arg(host_os.c_str()).toLocal8Bit().constData())); string dlgname = os->Resources::getResourceStr( "/FWBuilderResources/Target/dialog"); // string os=o->getStr("host_OS"); if (dlgname=="linux24") return new linux24AdvancedDialog(parent, o); if (dlgname=="sveasoft") return new linksysAdvancedDialog(parent, o); if (dlgname=="freebsd") return new freebsdAdvancedDialog(parent, o); if (dlgname=="openbsd") return new openbsdAdvancedDialog(parent, o); if (dlgname=="solaris") return new solarisAdvancedDialog(parent, o); if (dlgname=="macosx") return new macosxAdvancedDialog(parent, o); if (dlgname=="pix_os") return new pixosAdvancedDialog(parent, o); if (dlgname=="ios") return new iosAdvancedDialog(parent, o); if (dlgname=="ipcop") return new ipcoposAdvancedDialog(parent, o); if (dlgname=="secuwall") return new secuwallosAdvancedDialog(parent, o); cerr << "OS settings dialog for " << dlgname << " is not implemented" << endl; return NULL; } QWidget *DialogFactory::createIfaceDialog(QWidget *parent,FWObject *o) throw(FWException) { FWObject *h = Host::getParentHost(o); //FWObject *h = Interface::cast(o)->getParentHost(); string host_OS = h->getStr("host_OS"); Resources *os = Resources::os_res[host_OS]; if (os==NULL) throw FWException((const char*)( QObject::tr("Support module for %1 is not available"). arg(host_OS.c_str()).toLocal8Bit().constData())); string dlgname = os->Resources::getResourceStr( "/FWBuilderResources/Target/interface_dialog"); // add further dlgname support here ... if (dlgname=="secuwall") return new secuwallIfaceOptsDialog(parent, o); if (dlgname=="linux24") return new linux24IfaceOptsDialog(parent, o); if (dlgname=="bsd") return new bsdIfaceOptsDialog(parent, o); if (dlgname=="pix_os") return new pixosIfaceOptsDialog(parent, o); if (dlgname=="vlan_only") return new vlanOnlyIfaceOptsDialog(parent, o); cerr << "Interface settings dialog for OS " << host_OS << " is not implemented" << endl; return NULL; } QWidget *DialogFactory::createClusterConfDialog(QWidget *parent, FWObject *o) throw(FWException) { FWObject *objparent = o->getParent(); while (objparent && objparent->getTypeName()!="Cluster") objparent = objparent->getParent(); assert(objparent); string host_OS = objparent->getStr("host_OS"); Resources *os = Resources::os_res[host_OS]; string dlgname = os->Resources::getResourceStr("/FWBuilderResources/Target/cluster_dialog"); // add further dlgname support here ... if (dlgname == "basic") return new clusterMembersDialog(parent, o); cerr << "Cluster configuration dialog for OS " << host_OS << " is not implemented" << endl; return NULL; } /* * Create cluster group options dialog; dialog class depends on the * cluster group type. Argument is FWOptions object which is * a child of ClusterGroup object */ QString DialogFactory::getClusterGroupOptionsDialogName(FWObject *o) { FWObject *cluster_group = o->getParent(); assert(ClusterGroup::cast(cluster_group)!=NULL); string type = ClusterGroup::cast(cluster_group)->getStr("type"); FWObject *fw = o; while (fw && Firewall::cast(fw)==NULL) fw = fw->getParent(); if (fw) { string host_OS = fw->getStr("host_OS"); Resources *os = Resources::os_res[host_OS]; return os->Resources::getResourceStr( "/FWBuilderResources/Target/protocols/" + type + "/dialog").c_str(); } return QString(); } QWidget *DialogFactory::createClusterGroupOptionsDialog( QWidget *parent, FWObject *o) throw(libfwbuilder::FWException) { QString dlgname = getClusterGroupOptionsDialogName(o); if (dlgname == "conntrack") return new conntrackOptionsDialog(parent, o); if (dlgname == "pfsync") return new pfsyncOptionsDialog(parent, o); if (dlgname == "pix_state_sync") return new pixFailoverOptionsDialog(parent, o); if (dlgname == "vrrp") return new vrrpOptionsDialog(parent, o); if (dlgname == "carp") return new carpOptionsDialog(parent, o); if (dlgname == "heartbeat") return new heartbeatOptionsDialog(parent, o); if (dlgname == "openais") return new openaisOptionsDialog(parent, o); // Add more cluster group options dialog here return NULL; } string DialogFactory::getActionDialogPageName(Firewall *fw, Rule *rule) { string platform = fw->getStr("platform"); string act = getRuleAction(rule).toStdString(); string editor_page; try { editor_page = Resources::getTargetCapabilityStr( platform, "actions/" + act + "/dialog_page"); } catch (FWException &ex) { } return editor_page; } fwbuilder-5.1.0.3599/src/libgui/GroupObjectDialog.cpp0000644000175000017500000005762011733011756023121 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "events.h" #include "ProjectPanel.h" #include "FWBTree.h" #include "FWBSettings.h" #include "FWObjectPropertiesFactory.h" #include "GroupObjectDialog.h" #include "FWObjectDrag.h" #include "FWObjectClipboard.h" #include "ObjectTreeView.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/Group.h" #include "fwbuilder/Resources.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/FWObjectReference.h" #include "fwbuilder/FWServiceReference.h" #include "fwbuilder/FWIntervalReference.h" #include "fwbuilder/Service.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; bool compare_addrs(const InetAddr *one, const InetAddr *two) { if (one->isV4() + two->isV4() == 1) return one->isV4(); QString oneip; QString twoip; QList onenumbers; QList twonumbers; if (one->isV4()) { oneip = one->toString().c_str(); foreach (QString part, oneip.split(".")) onenumbers.append(part.toInt()); twoip = two->toString().c_str(); foreach (QString part, twoip.split(".")) twonumbers.append(part.toInt()); } else { bool ok; oneip = one->toString().c_str(); foreach (QString part, oneip.split(":")) onenumbers.append(part.toInt(&ok, 16)); twoip = two->toString().c_str(); foreach (QString part, twoip.split(":")) twonumbers.append(part.toInt(&ok, 16)); } for (int i=0; i < onenumbers.count(); i++) { if (onenumbers.at(i) != twonumbers.at(i)) return onenumbers.at(i) < twonumbers.at(i); } return false; } class GroupObjectWidgetItem: public QTreeWidgetItem { FWObjectDatabase * db; public: GroupObjectWidgetItem(QTreeWidget *parent, FWObjectDatabase *db): QTreeWidgetItem(parent) { this->db = db; } bool operator<( const QTreeWidgetItem & other ) const { int col = this->treeWidget()->sortColumn(); if ( col != 1) return this->text(col) < other.text(col); FWObject *otherobj = db->findInIndex(other.data(0, Qt::UserRole).toInt()); FWObject *thisobj = db->findInIndex(this->data(0, Qt::UserRole).toInt()); if (otherobj->getTypeName() != thisobj->getTypeName()) return thisobj->getTypeName() < otherobj->getTypeName(); if (IPv4::isA(thisobj) || IPv6::isA(thisobj)) { return compare_addrs(Address::cast(thisobj)->getAddressPtr(), Address::cast(otherobj)->getAddressPtr()); } if (Service::isA(thisobj)) { return Service::cast(thisobj)->getProtocolNumber() < Service::cast(otherobj)->getProtocolNumber(); } if(AddressRange::isA(thisobj)) { return compare_addrs(&AddressRange::cast(thisobj)->getRangeStart(), &AddressRange::cast(otherobj)->getRangeStart()); } if (Host::isA(thisobj)) { return compare_addrs(Host::cast(thisobj)->getAddressPtr(), Host::cast(otherobj)->getAddressPtr()); } return this->text(col) < other.text(col); } }; enum GroupObjectDialog::viewType GroupObjectDialog::vt = GroupObjectDialog::Icon; #define LIST_VIEW_MODE "list" #define ICON_VIEW_MODE "icon" GroupObjectDialog::GroupObjectDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::GroupObjectDialog_q; m_dialog->setupUi(this); obj = NULL; selectedObject = NULL; new_object_menu = NULL; listView = new ObjectListView( m_dialog->objectViewsStack, "listView" ); QStringList sl; sl << "Name" << "Properties"; listView->setHeaderLabels (sl); listView->setAcceptDrops( true ); listView->setDragDropMode( QAbstractItemView::DragDrop ); listView->setContextMenuPolicy ( Qt::CustomContextMenu ); iconView = new ObjectIconView( m_dialog->objectViewsStack, "iconView" ); iconView->setContextMenuPolicy ( Qt::CustomContextMenu ); m_dialog->objectViewsStack->addWidget(iconView); m_dialog->objectViewsStack->addWidget(listView); if (st->getGroupViewMode() == ICON_VIEW_MODE) m_dialog->objectViewsStack->setCurrentWidget(iconView); else m_dialog->objectViewsStack->setCurrentWidget(listView); listView->setSelectionMode(QAbstractItemView::ExtendedSelection); iconView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_dialog->iconViewBtn->setCheckable(true); m_dialog->listViewBtn->setCheckable(true); //listView->hide(); //iconView->show(); m_dialog->iconViewBtn->setAutoRaise(false); m_dialog->listViewBtn->setAutoRaise(false); connect( iconView, SIGNAL( currentItemChanged(QListWidgetItem*,QListWidgetItem*) ), this, SLOT( iconViewCurrentChanged(QListWidgetItem*) ) ); connect( iconView, SIGNAL (itemSelectionChanged()), this, SLOT (iconViewSelectionChanged())); connect( iconView, SIGNAL( dropped(QDropEvent*) ), this, SLOT( dropped(QDropEvent*) ) ); connect( iconView, SIGNAL( customContextMenuRequested(const QPoint&) ), this, SLOT( iconContextMenu(const QPoint&) ) ); connect( iconView, SIGNAL( delObject_sign() ), this, SLOT( deleteObj() ) ); connect( iconView, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(itemDoubleClicked(QListWidgetItem*))); connect( listView, SIGNAL( currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*) ), this, SLOT( listViewCurrentChanged(QTreeWidgetItem*) ) ); connect( listView, SIGNAL (itemSelectionChanged()), this, SLOT (listViewSelectionChanged())); connect( listView, SIGNAL( dropped(QDropEvent*) ), this, SLOT( dropped(QDropEvent*) ) ); connect( listView, SIGNAL( customContextMenuRequested(const QPoint&) ), this, SLOT( listContextMenu(const QPoint&) ) ); connect( listView, SIGNAL( delObject_sign() ), this, SLOT( deleteObj() ) ); connect( listView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*, int))); QString s = st->getGroupViewColumns(); int col0 = s.section(',',0,0).toInt(); int col1 = s.section(',',1,1).toInt(); if (col0 == 0) col0 = listView->width()/2; listView->setColumnWidth(0,col0); listView->setColumnWidth(1,col1); QString mode = st->getGroupViewMode(); if (mode==ICON_VIEW_MODE) switchToIconView(); else switchToListView(); connectSignalsOfAllWidgetsToSlotChange(); } GroupObjectDialog::~GroupObjectDialog() { delete m_dialog; } void GroupObjectDialog::iconViewSelectionChanged() { if (fwbdebug) qDebug("GroupObjectDialog::iconViewSelectionChanged()"); selectedObjects.clear(); for (int it=0; itcount(); ++it) { QListWidgetItem *itm = iconView->item(it); if (itm->isSelected()) { int obj_id = itm->data(Qt::UserRole).toInt(); if (fwbdebug) qDebug("obj_id=%d", obj_id); selectedObjects.push_back(obj_id); } } } void GroupObjectDialog::listViewSelectionChanged() { if (fwbdebug) qDebug("GroupObjectDialog::listViewSelectionChanged()"); selectedObjects.clear(); for (int it=0; ittopLevelItemCount(); ++it) { QTreeWidgetItem *itm = listView->topLevelItem(it); if (itm->isSelected()) { int obj_id = itm->data(0, Qt::UserRole).toInt(); if (fwbdebug) qDebug("obj_id=%d", obj_id); selectedObjects.push_back(obj_id); } } } void GroupObjectDialog::iconViewCurrentChanged(QListWidgetItem *itm) { if (itm==NULL) { selectedObject=NULL; return; } int obj_id = itm->data(Qt::UserRole).toInt(); FWObject *o = m_project->db()->findInIndex(obj_id); selectedObject = o; } void GroupObjectDialog::listViewCurrentChanged(QTreeWidgetItem *itm) { if (itm==NULL) { selectedObject=NULL; return; } int obj_id = itm->data(0, Qt::UserRole).toInt(); FWObject *o = m_project->db()->findInIndex(obj_id); selectedObject = o; } /* * used to add an object for paste and drop operations */ void GroupObjectDialog::insertObject(FWObject *o) { assert(o!=NULL); Group *g = dynamic_cast(obj); assert(g!=NULL); if ( ! g->validateChild(o) || g->isReadOnly() ) return; // see #1976 do not allow pasting object that has been deleted // note that we call insertObject() from dropEvent(), not only from paste() if (o->getLibrary()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) return; if (fwbdebug) qDebug("Adding object %s to the group %s", o->getName().c_str(), g->getName().c_str()); /* avoid duplicates */ int cp_id = o->getId(); for (int it=0; ittopLevelItemCount(); ++it) { QTreeWidgetItem *itm = listView->topLevelItem(it); int obj_id = itm->data(0, Qt::UserRole).toInt(); if(obj_id==cp_id) return; } addIcon(o, ! FWBTree().isSystem(obj) ); changed(); } void GroupObjectDialog::addIcon(FWObject *fwo) { FWObject *o=fwo; bool ref=false; if (FWReference::cast(o)!=NULL) { o=FWReference::cast(o)->getPointer(); ref=true; } addIcon(o,ref); } void GroupObjectDialog::addIcon(FWObject *o, bool ref) { if (Resources::global_res->getResourceBool( string("/FWBuilderResources/Type/") + o->getTypeName() + "/hidden") ) return; QString obj_name=QString::fromUtf8(o->getName().c_str()); QString icn_filename = (":/Icons/"+o->getTypeName()+((ref)?"/icon-ref":"/icon")).c_str(); QPixmap pm; if ( ! QPixmapCache::find( icn_filename, pm) ) { pm.load( icn_filename ); QPixmapCache::insert( icn_filename, pm); } QListWidgetItem *list_item = new QListWidgetItem(QIcon(pm), obj_name, iconView); list_item->setData(Qt::UserRole, QVariant(o->getId())); iconView->addItem(list_item); GroupObjectWidgetItem *tree_item = new GroupObjectWidgetItem(listView, m_project->db()); tree_item->setText(0, obj_name); tree_item->setText(1, FWObjectPropertiesFactory::getObjectProperties(o) ); tree_item->setIcon(0, QIcon(pm) ); tree_item->setData(0, Qt::UserRole, QVariant(o->getId())); listView->addTopLevelItem(tree_item); } void GroupObjectDialog::loadFWObject(FWObject *o) { obj = o; Group *g = Group::cast(obj); assert(g!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(g->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->obj_name->setEnabled( !FWBTree().isSystem(obj) ); listView->clear(); iconView->clear(); listView->setDB(o->getRoot()); iconView->setDB(o->getRoot()); iconView->setResizeMode( QListWidget::Adjust ); iconView->setGridSize( QSize(50, 40) ); switch (vt) { case Icon: if ( ! m_dialog->iconViewBtn->isChecked() ) m_dialog->iconViewBtn->toggle(); iconView->raise(); break; case List: if ( ! m_dialog->listViewBtn->isChecked() ) m_dialog->listViewBtn->toggle(); listView->raise(); break; } for (FWObject::iterator i=g->begin(); i!=g->end(); i++) addIcon( *i ); listView->header()->resizeSections(QHeaderView::ResizeToContents); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly() && !FWBTree().isSystem(o)); setDisabledPalette(m_dialog->obj_name); m_dialog->newButton->setEnabled(!o->isReadOnly()); // listView->setEnabled(!o->isReadOnly()); setDisabledPalette(listView); // iconView->setEnabled(!o->isReadOnly()); setDisabledPalette(iconView); init=false; if (FWBTree().isSystem(g)) { m_dialog->newButton->hide(); return; } if (new_object_menu) { new_object_menu->clear(); m_dialog->newButton->setMenu(NULL); delete new_object_menu; } new_object_menu = new QMenu(this); new_object_menu->setObjectName("GroupObjectDialog_newObjectMenu"); int add_to_group_id = g->getId(); list types_list; g->getAllowedTypesOfChildren(types_list); foreach(string tn, types_list) { if (tn == FWObjectReference::TYPENAME || tn == FWServiceReference::TYPENAME || tn == FWIntervalReference::TYPENAME) continue; if (fwbdebug) qDebug() << "Adding type" << tn.c_str() << "to the new object menu"; m_project->m_panel->om->addNewObjectMenuItem( new_object_menu, tn.c_str(), "", add_to_group_id); } m_dialog->newButton->setMenu( new_object_menu ); m_dialog->newButton->show(); } void GroupObjectDialog::validate(bool *res) { *res=true; if (!validateName(this, obj, m_dialog->obj_name->text())) { *res=false; return; } } void GroupObjectDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); string oldname = obj->getName(); string newname = string(m_dialog->obj_name->text().toUtf8().constData()); if (oldname != newname) { if (fwbdebug) qDebug() << "oldname=" << oldname.c_str() << "newname=" << newname.c_str(); new_state->setName(newname); } m_dialog->commentKeywords->applyChanges(new_state); set oldobj; set newobj; for (int it=0; ittopLevelItemCount(); ++it) { QTreeWidgetItem *itm = listView->topLevelItem(it); int obj_id = itm->data(0, Qt::UserRole).toInt(); newobj.insert(obj_id); } for (FWObject::iterator j=obj->begin(); j!=obj->end(); ++j) { FWObject *o = *j; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); oldobj.insert(o->getId()); } set diff; set_difference( oldobj.begin(), oldobj.end(), newobj.begin(), newobj.end(), inserter(diff,diff.begin())); /* diff contains objects present in oldobj but not in newobj - these objects were deleted from the group */ for (set::iterator k=diff.begin(); k!=diff.end(); ++k) { FWObject *o = m_project->db()->findInIndex(*k); // Note: FWBTree::isSystem() would not work for new_state because // it is not part of the tree and isSystem() relies on the tree path if (FWBTree().isSystem(obj)) { m_project->m_panel->om->deleteObject(o); } else { new_state->removeRef(o); } } diff.clear(); set_difference( newobj.begin(), newobj.end(), oldobj.begin(), oldobj.end(), inserter(diff,diff.begin())); /* diff contains objects present in newobj but not in oldobj - these objects were added to the group */ for (set::iterator k1=diff.begin(); k1!=diff.end(); ++k1) { FWObject *o = m_project->db()->findInIndex(*k1); if (FWBTree().isSystem(obj)) { m_project->pasteTo(new_state, o); } else { new_state->addRef(o); } } saveColumnWidths(); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void GroupObjectDialog::switchToIconView() { //if (vt == Icon) return; vt = Icon; if ( ! m_dialog->iconViewBtn->isChecked() ) m_dialog->iconViewBtn->toggle(); m_dialog->objectViewsStack->setCurrentWidget(iconView); st->setGroupViewMode(ICON_VIEW_MODE); } void GroupObjectDialog::switchToListView() { //if (vt == List) return; vt = List; if ( ! m_dialog->listViewBtn->isChecked() ) m_dialog->listViewBtn->toggle(); m_dialog->objectViewsStack->setCurrentWidget(listView); st->setGroupViewMode(LIST_VIEW_MODE); } // This method is attached to the context menu item "Edit" void GroupObjectDialog::openObject() { if (selectedObject!=NULL) { QCoreApplication::postEvent( m_project, new showObjectInTreeEvent(selectedObject->getRoot()->getFileName().c_str(), selectedObject->getId())); QCoreApplication::postEvent( mw, new openObjectInEditorEvent(selectedObject->getRoot()->getFileName().c_str(), selectedObject->getId())); } } void GroupObjectDialog::dropped(QDropEvent *ev) { if (fwbdebug) qDebug("GroupObjectDialog::dropped"); list ol; if (FWObjectDrag::decode(ev, ol)) { if (ol.size()==0) return; for (list::iterator i=ol.begin(); i!=ol.end(); ++i) insertObject( *i ); if (fwbdebug) qDebug("GroupObjectDialog::dropped ev->acceptAction()"); ev->setAccepted(true); // see comment in ObjectTreeView.cpp explaining the purpose of // flag process_mouse_release_event ObjectTreeView *otv = m_project->getCurrentObjectTree(); otv->ignoreNextMouseReleaseEvent(); } if (fwbdebug) qDebug("GroupObjectDialog::dropped done"); } void GroupObjectDialog::iconContextMenu(const QPoint & pos) { FWObject *o = NULL; QListWidgetItem *itm = iconView->itemAt(pos); if (itm) { int obj_id = itm->data(Qt::UserRole).toInt(); o = m_project->db()->findInIndex(obj_id); selectedObject = o; } setupPopupMenu(iconView->mapToGlobal(pos)); } void GroupObjectDialog::listContextMenu(const QPoint & pos) { FWObject *o=NULL; QTreeWidgetItem *itm = listView->itemAt(pos); if (itm) { int obj_id = itm->data(0, Qt::UserRole).toInt(); o = m_project->db()->findInIndex(obj_id); selectedObject = o; } setupPopupMenu(listView->viewport()->mapToGlobal(pos)); } void GroupObjectDialog::setupPopupMenu(const QPoint &pos) { QMenu *popup = new QMenu(this); if (selectedObject!=NULL) { if (selectedObject->isReadOnly() ) popup->addAction(tr("Open"), this, SLOT(openObject())); else popup->addAction(tr("Edit"), this, SLOT(openObject())); } QAction *copyID = popup->addAction(tr("Copy"), this, SLOT(copyObj())); QAction *cutID = popup->addAction(tr("Cut"), this, SLOT(cutObj())); QAction *pasteID = popup->addAction(tr("Paste"), this, SLOT(pasteObj())); QAction *delID = popup->addAction(tr("Delete"),this, SLOT(deleteObj())); copyID->setEnabled(selectedObject!=NULL && ! FWBTree().isSystem(selectedObject) ); cutID->setEnabled(selectedObject!=NULL && ! FWBTree().isSystem(obj) && ! obj->isReadOnly() ); // see #1976 do not allow pasting object that has been deleted FWObject *obj_in_clipboard = FWObjectClipboard::obj_clipboard->getObject(); bool obj_deleted = (obj_in_clipboard && obj_in_clipboard->getParent()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID); pasteID->setEnabled(! FWBTree().isSystem(obj) && ! obj->isReadOnly() && ! obj_deleted); delID->setEnabled(selectedObject!=NULL && ! FWBTree().isSystem(obj) && ! obj->isReadOnly() ); popup->exec( pos ); } void GroupObjectDialog::copyObj() { FWObjectClipboard::obj_clipboard->clear(); for(vector::iterator it=selectedObjects.begin(); it!=selectedObjects.end(); ++it) { FWObject* selectedObject = m_project->db()->findInIndex(*it); if (selectedObject!=NULL && ! FWBTree().isSystem(selectedObject) ) { FWObjectClipboard::obj_clipboard->add(selectedObject, this->m_project ); } } } void GroupObjectDialog::cutObj() { copyObj(); deleteObj(); } void GroupObjectDialog::pasteObj() { vector >::iterator i; for (i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i) { insertObject( m_project->db()->findInIndex(i->first) ); } } void GroupObjectDialog::deleteObj() { // make a copy of the list of selected objects because selection // changes when we delete items vector tv; copy(selectedObjects.begin(),selectedObjects.end(),inserter(tv,tv.begin())); for(vector::iterator it=tv.begin(); it!=tv.end(); ++it) { if (fwbdebug) qDebug("GroupObjectDialog::deleteObj() (*it)=%d", (*it)); FWObject* selectedObject = m_project->db()->findInIndex(*it); int o_id = selectedObject->getId(); for (int it=0; ittopLevelItemCount(); ++it) { QTreeWidgetItem *itm = listView->topLevelItem(it); if (o_id == itm->data(0, Qt::UserRole).toInt()) { listView->takeTopLevelItem(it); break; } } for (int it=0; itcount(); ++it) { QListWidgetItem *itm = iconView->item(it); if (o_id == itm->data(Qt::UserRole).toInt()) { iconView->takeItem(it); break; } } } changed(); } void GroupObjectDialog::saveColumnWidths() { if (fwbdebug) qDebug("GroupObjectDialog::saveColumnWidths()"); QString s = QString("%1,%2") .arg(listView->columnWidth(0)) .arg(listView->columnWidth(1)); st->setGroupViewColumns(s); } void GroupObjectDialog::selectObject(FWObject *o) { int o_id = o->getId(); for (int it=0; ittopLevelItemCount(); ++it) { QTreeWidgetItem *itm = listView->topLevelItem(it); if (o_id == itm->data(0, Qt::UserRole).toInt()) { listView->setCurrentItem(itm); break; } } for (int it=0; itcount(); ++it) { QListWidgetItem *itm = iconView->item(it); if (o_id == itm->data(Qt::UserRole).toInt()) { iconView->setCurrentItem(itm); break; } } } void GroupObjectDialog::newObject() { m_dialog->newButton->showMenu(); } void GroupObjectDialog::itemDoubleClicked(QListWidgetItem*) { openObject(); } void GroupObjectDialog::itemDoubleClicked(QTreeWidgetItem*, int) { openObject(); } fwbuilder-5.1.0.3599/src/libgui/clusterMembersDialog.h0000644000175000017500000001215311733011756023327 0ustar sylvestresylvestre/* * cluster members configuration dialog * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __CLUSTERMEMBERDIALOG_H_ #define __CLUSTERMEMBERDIALOG_H_ #include #include "fwbuilder/FWObject.h" namespace libfwbuilder { class Firewall; class Interface; }; typedef std::list t_ifaceList; typedef std::map t_ifaceMap; /** * @class ClusterMember * * @brief Simple helper class to store relevant info about cluster members. * * The ClusterMember class is used to store temporary data for the configuration * of potential cluster members of a specific cluster. */ class ClusterMember { public: /** pointer to firewall object */ libfwbuilder::FWObject *fwobj; /** list of pointers to all interfaces of this firewall */ t_ifaceList iface_list; /** mapping from iface name to interface pointer */ t_ifaceMap iface_map; /** selected as cluster interface */ libfwbuilder::Interface *iface_cluster; /** flag for cluster master */ bool is_master; }; typedef std::list t_memberList; class clusterMembersDialog : public QDialog { Q_OBJECT public: clusterMembersDialog(QWidget *parent, libfwbuilder::FWObject *o); ~clusterMembersDialog(); private: libfwbuilder::FWObject *obj; bool enable_master_column; Ui::clusterMembersDialog_q *m_dialog; /** host OS of current cluster */ QString host_os; /** platform of current cluster */ QString platform; /** list of all still available firewalls */ t_memberList available; /** list of cluster members */ t_memberList selected; /** flag to indicate selected table update */ bool table_update; /** init lists of already selected firewalls */ void getSelectedMembers(); /** * init lists of available firewalls * * For this type of cluster, a valid firewall must fulfill the * following criterias: * 1. host_OS and platform must match cluster settings * 2. the firewall must at least have one interface attached */ void getPossibleMembers(); /** update view of selected members */ void updateSelectedTable(); /** update view of available firewalls */ void updateAvailableTree(); /** * create a new cluster member object from fw pointer * * @param fw pointer to firewall object * @param cluster_iface pointer to selected cluster iface * @param master flag to indicate cluster master * @return pointer to new cluster object */ ClusterMember* createMember(libfwbuilder::Firewall *fw, libfwbuilder::Interface *cluster_iface = NULL, bool master = false); /** * swap firewall cluster member info from one list to another. * * @param from list to remove firewall from * @param to list to add firewall * @param fwname firewall name as identifier * @param iface optional interface to set as cluster interface * @param master optional: set master flag * @return true if successfully swapped, false if not */ bool swap(t_memberList &from, t_memberList &to, const QString fwname, const QString iface, bool master = false); /** * set master firewall status in selected list * * @param fw name of firewall to set state * @param checked status to set (checked / unchecked) */ void setMaster(QString fw, bool checked = true); /** * returns fwobject specific pixmap to caller * * @param o object to get pixmap for * @return object's QPixmap */ QPixmap getIcon(libfwbuilder::FWObject *o); /** update all views */ void invalidate(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); void availableClicked(QTreeWidgetItem *item, int); void selectedClicked(int row, int column); void masterSelected(int row, int column); void firewallAdd(); void firewallRemove(); signals: void membersChanged(); }; /** * @class PredFindFw * * @brief Predicate class to find firewalls by name * * PredFindFw can be used e.g. as parameter in find_if() function to compare * ClusterMembers in available and selected lists with a given fwname * specified by setSearchString(). */ class PredFindFw { protected: QString search_string; public: PredFindFw() {}; bool operator()(const ClusterMember *member) const { QString fwname = member->fwobj->getName().c_str(); return (fwname == search_string); } void setSearchString(const QString &string) { search_string = string; } }; #endif /* __SECUWALLCLUSTERCONFDIALOG_H_ */ fwbuilder-5.1.0.3599/src/libgui/FWCmdDeleteObject.cpp0000644000175000017500000001225211733011756022760 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWCmdChange.h" #include "FWCmdDeleteObject.h" #include "FWWindow.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include #include using namespace libfwbuilder; using namespace std; /******************************************************** * FWCmdDeleteObject * * This command really deletes the object from the object tree, it * does not move it Deleted Objects library. We use this command when * user deletes objects from Deleted Objects. * ********************************************************/ FWCmdDeleteObject::FWCmdDeleteObject(ProjectPanel *project, FWObject *obj, QString text, QUndoCommand* macro): FWCmdChange(project, obj, text, false, macro) { delobj = obj; delobj->ref(); parent = delobj->getParent(); if (text.isEmpty()) { setText(QObject::tr("Delete object")); } else { setText(text); } } FWCmdDeleteObject::~FWCmdDeleteObject() { if (delobj) { if (delobj->getRefCounter() <= 1) delete delobj; else delobj->unref(); } } void FWCmdDeleteObject::undo() { QString filename = project->getFileName(); if (delobj && !parent->hasChild(delobj)) { parent->add(delobj); if (fwbdebug) qDebug() << "FWCmdDeleteObject::undo()" << "delobj->getRefCounter()=" << delobj->getRefCounter(); QCoreApplication::postEvent( mw, new insertObjectInTreeEvent(filename, parent->getId(), delobj->getId())); QCoreApplication::postEvent( mw, new updateObjectAndSubtreeImmediatelyEvent(filename, parent->getId())); QCoreApplication::postEvent( mw, new dataModifiedEvent(filename, parent->getId())); if (mw->isEditorVisible()) QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, delobj->getId())); QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, delobj->getId())); } } void FWCmdDeleteObject::redo() { QString filename = project->getFileName(); QCoreApplication::postEvent( mw, new removeObjectFromTreeEvent(filename, delobj->getId())); QCoreApplication::postEvent( mw, new updateObjectAndSubtreeImmediatelyEvent(filename, parent->getId())); QCoreApplication::postEvent( mw, new dataModifiedEvent(filename, parent->getId())); if (mw->isEditorVisible()) QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, parent->getId())); QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, parent->getId())); parent->remove(delobj, false); if (fwbdebug) qDebug() << "FWCmdDeleteObject::redo()" << "delobj->getRefCounter()=" << delobj->getRefCounter(); } void FWCmdDeleteObject::notify() { } /********************************************************************/ FWCmdRemoveUserFolder::FWCmdRemoveUserFolder(ProjectPanel *project, FWObject *parentFolder, const QString &userFolder, QString text, QUndoCommand *macro) : FWCmdChange(project, parentFolder, text, false, macro), m_userFolder(userFolder) { } void FWCmdRemoveUserFolder::redo() { FWCmdChange::redo(); FWObject *obj = getObject(); QString fName = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); QCoreApplication::postEvent(mw, new removeUserFolderEvent(fName, obj->getId(), m_userFolder)); } void FWCmdRemoveUserFolder::undo() { FWCmdChange::undo(); FWObject *obj = getObject(); QString fName = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); QCoreApplication::postEvent(mw, new addUserFolderEvent(fName, obj->getId(), m_userFolder)); } /* We don't want to display the system folder after we remove a user folder, so we just swallow the notify. */ void FWCmdRemoveUserFolder::notify() { } fwbuilder-5.1.0.3599/src/libgui/CommentKeywords.h0000644000175000017500000000270711733011756022351 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CommentKeywords_h_ #define __CommentKeywords_h_ #include "fwbuilder/FWObject.h" #include class CommentKeywords : public QWidget { private: Q_OBJECT; Ui_CommentKeywords_q m_ui; libfwbuilder::FWObject *m_obj; QStringList m_keywords; void updateKeywordsLabel(); public: CommentKeywords(QWidget *parent = 0); void applyChanges(libfwbuilder::FWObject *newObj); void loadFWObject(libfwbuilder::FWObject *obj); void setReadOnlyComment(const QString &comment); signals: void changed(); public slots: virtual void keywordsClicked(); }; #endif /* CommentKeywords_h_ */ fwbuilder-5.1.0.3599/src/libgui/SimpleIntEditor.h0000644000175000017500000000321111733011756022261 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __SIMPLEINTEDITOR_H__ #define __SIMPLEINTEDITOR_H__ #include "config.h" #include class SimpleIntEditor : public QDialog { Q_OBJECT public: Ui::SimpleIntEditor_q *m_dialog; SimpleIntEditor(int minValue, int maxValue, int value, const QString &title); ~SimpleIntEditor() { delete m_dialog; }; int value(); //public slots: // virtual void loadFromFile(); }; #endif fwbuilder-5.1.0.3599/src/libgui/utils_no_qt.h0000644000175000017500000000423011733011756021550 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2007 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UTILS_NO_QT_H_ #define __UTILS_NO_QT_H_ #include #include #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWReference.h" /* Utility functions that do not depend on QT */ extern void findFirewalls(libfwbuilder::FWObject *o, std::list &fwlist, bool skip_system_libs=true); extern void findClusters(libfwbuilder::FWObject *o, std::list &fwlist, bool skip_system_libs=true); extern void findHosts(libfwbuilder::FWObject *o, std::list &fwlist, bool skip_system_libs=true); extern void findByObjectType(libfwbuilder::FWObject *o, const std::string &otype, std::list &fwlist, bool skip_system_libs=true); extern libfwbuilder::FWReference* findRef(libfwbuilder::FWObject *o, libfwbuilder::FWObject *p); // helper: strip whitespaces from the beginning and end of a string extern std::string strip(const std::string &s); extern std::string getPathToBinary(const std::string &pgm_name); #endif fwbuilder-5.1.0.3599/src/libgui/FirewallInstallerProcurve.h0000644000175000017500000000271711733011756024371 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FIREWALLINSTALLERPROCURVE_H_ #define __FIREWALLINSTALLERPROCURVE_H_ #include "config.h" #include "FirewallInstallerCisco.h" #include #include #include #include #include namespace libfwbuilder { class Firewall; } class FirewallInstallerProcurve : public FirewallInstallerCisco { Q_OBJECT; public: FirewallInstallerProcurve(instDialog *_dlg, instConf *_cnf, const QString &_p); virtual bool packInstallJobsList(libfwbuilder::Firewall*); virtual void activatePolicy(const QString &script, const QString &args); }; #endif fwbuilder-5.1.0.3599/src/libgui/ClusterInterfaceWidget.ui0000644000175000017500000001076111733011756024012 0ustar sylvestresylvestre ClusterInterfaceWidget 0 0 578 463 Form Name: Label: Comment: 0 0 0 70 16777215 70 Select firewall interfaces to use with cluster interface and choose its name. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Configuration of cluster interfaces depends on the failover protocol chosen on the next page. If the protocol creates its own new interface, such as <span style=" font-weight:600;">CARP</span> that creates interface <span style=" font-weight:600; font-style:italic;">carp0</span>, then the cluster interface object represents it and should have name <span style=" font-weight:600; font-style:italic;">carp0</span>. If failover protocol does not create new interfaces, such as <span style=" font-weight:600;">heartbeat</span> or <span style=" font-weight:600;">OpenAIS</span>, then cluster interface should have the same name as corresponding member firewall interfaces, that is <span style=" font-weight:600; font-style:italic;">eth0</span>, <span style=" font-weight:600; font-style:italic;">eth1.102</span>, <span style=" font-weight:600; font-style:italic;">vlan200</span>, and so on. In the latter case cluster interface is an abstraction used to define mapping between corresponding interfaces of the member firewalls and to provide place for the configuration of the failover protocol.</p></body></html> true name textChanged(QString) ClusterInterfaceWidget nameChanged(QString) 95 25 2 92 nameChanged(QString) fwbuilder-5.1.0.3599/src/libgui/pfAdvancedDialog.h0000644000175000017500000000304111733011756022362 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PFADVANCEDDIALOG_H_ #define __PFADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class pfAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::pfAdvancedDialog_q *m_dialog; public: pfAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~pfAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); virtual void doScrubToggled(); virtual void ltToggled(); virtual void editProlog(); virtual void editEpilog(); }; #endif // __PFADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/newclusterdialog_q.ui0000644000175000017500000003342311733011756023277 0ustar sylvestresylvestre newClusterDialog_q Qt::WindowModal 0 0 651 644 0 0 0 25 Sans Serif 14 75 false true TextLabel Qt::AlignCenter 1 0 400 50 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 161 37 < &Back false &Next > true false &Finish false &Cancel false 500 450 3 Enter the name of the new object Qt::AlignCenter false Select member firewall objects to use with the new cluster. One member firewall should be marked as master. You can choose to copy policy and NAT rules from the rule sets of one of the members to the new cluster later. true Firewall Use in cluster Master 0 Tab 1 0 Tab 1 Choose which member's Policy and NAT rules should be used to create Policy and NAT rules of the cluster. First, each member firewall object will be copied with the name "<firewall>-bak" (where <firewall> is the name of the member) for backup, then rules from the chosen member will be copied to the new cluster and finally all Policy and NAT rules will be deleted in both members. Backup firewall objects ensure that you do not lose your configuration and can always revert back if necessary. You can delete backup objects or move them to a separate library for archival later. true 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Cluster summary:</span></p></body></html> Name: 0 0 0 150 16777215 150 Firewalls used in this cluster Lucida Console Qt::Vertical 20 40 0 0 Master firewall: Cluster interfaces Lucida Console Qt::Vertical 20 40 0 0 Policy and NAT rules will be copied from firewall: 0 0 Click Finish to create this cluster. InterfacesTabWidget QTabWidget
InterfacesTabWidget.h
1
FirewallSelectorWidget QTableWidget
FirewallSelectorWidget.h
ClusterInterfacesSelectorWidget QTabWidget
ClusterInterfacesSelectorWidget.h
1
backButton nextButton finishButton cancelButton obj_name textChanged(QString) newClusterDialog_q changed() 275 68 7 35 changed() failoverProtocolChanged() selectedInterface(QTreeWidgetItem*,QTreeWidgetItem*) platformChanged() addInterface() deleteInterface()
fwbuilder-5.1.0.3599/src/libgui/ObjectTreeView.h0000644000175000017500000001230111733011756022067 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTTREEVIEW_H_ #define __OBJECTTREEVIEW_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include namespace libfwbuilder { class FWObject; }; class ProjectPanel; class ObjectTreeViewItem; class ObjectTreeView : public QTreeWidget { Q_OBJECT; QTreeWidgetItem *item_before_drag_started; QTreeWidgetItem *lastSelected; QItemSelection lastSelection; bool second_click; bool selectionFrozen; bool expandOrCollapse; bool Lockable; bool Unlockable; bool startingDrag; bool visible; bool process_mouse_release_event; std::set expanded_objects; std::vector selectedObjects; ProjectPanel* m_project; QSet resolveChildren(QTreeWidgetItem*); QSet resolveParents(QTreeWidgetItem*); QString filter; QSet expandedState; void doExpandedState(bool save, QStringList &list, QTreeWidgetItem *item); protected: bool event( QEvent *event ); virtual void dragEnterEvent( QDragEnterEvent *ev); virtual void dragMoveEvent( QDragMoveEvent *ev); virtual void dropEvent(QDropEvent *ev); virtual void dragLeaveEvent( QDragLeaveEvent *ev); virtual void keyPressEvent( QKeyEvent* ev ); virtual void mousePressEvent( QMouseEvent *e ); virtual void mouseReleaseEvent( QMouseEvent *e ); //virtual void mouseDoubleClickEvent( QMouseEvent *e ); virtual void mouseMoveEvent( QMouseEvent *e ); virtual void keyReleaseEvent( QKeyEvent* ev ); virtual void focusInEvent(QFocusEvent*); virtual void focusOutEvent(QFocusEvent*); virtual bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event); void startDrag(Qt::DropActions supportedActions); virtual void paintEvent(QPaintEvent *ev); void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const; public: ObjectTreeView(ProjectPanel* project, QWidget* parent = 0, const char * name = 0, Qt::WFlags f = 0); void freezeSelection(bool f) { selectionFrozen = f; } std::vector& getSelectedObjects() { return selectedObjects; } bool isSelected(libfwbuilder::FWObject* obj); int getNumSelected(); libfwbuilder::FWObject* getCurrentObject(); void editCurrentObject(); void clearLastSelected(); void becomingVisible() { visible=true; } void becomingHidden() { visible=false; } void updateAfterPrefEdit(); /* Under some circumstances, user may select several host or fw * objects so that their children objects are selected as well * (e.g. when shift-click is used). "Delete objects" or "group * objects" operations will work on all children objects, which leads * to unexpected results since it is not obvious to the user that * children objects were selected (since they are invisible). We need * to remove them from the list before we delete or perform other * actions. */ std::vector getSimplifiedSelection(); void ignoreNextMouseReleaseEvent() { process_mouse_release_event = false; } void ExpandTreeItems(const std::set &ids); const std::set& getListOfExpandedObjectIds() { return expanded_objects; } void showOrHideAttributesColumn(); public slots: void itemSelectionChanged(); void resetSelection(); void currentItemChanged(QTreeWidgetItem *cur); void itemCollapsed(QTreeWidgetItem *itm); void itemExpanded(QTreeWidgetItem *itm); void itemOpened (); virtual void updateTreeIcons(); void setFilter(QString); void updateFilter(); signals: // void showObjectInfo_sign(libfwbuilder::FWObject *); void editCurrentObject_sign(); void switchObjectInEditor_sign(libfwbuilder::FWObject*); void objectDropped_sign(libfwbuilder::FWObject *); void deleteObject_sign(libfwbuilder::FWObject *); void contextMenuRequested_sign(const QPoint&); void moveItems_sign(ObjectTreeViewItem *dest, const std::list &items); }; #endif fwbuilder-5.1.0.3599/src/libgui/StartTipDialog.cpp0000644000175000017500000001370211733011756022441 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "StartTipDialog.h" #include "startup_tip_url.h" #include "FWBSettings.h" #include "FWWindow.h" #include "Help.h" #include "fwbuilder/Constants.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; StartTipDialog::StartTipDialog(QWidget *parent): QDialog(parent) { setAttribute(Qt::WA_DeleteOnClose); setModal(false); http_getter = new HttpGet(); connect(http_getter, SIGNAL(done(const QString&)), this, SLOT(downloadComplete(const QString&))); m_dialog = new Ui::StartTipDialog_q; m_dialog->setupUi(this); QString pgm = m_dialog->program_name->text(); m_dialog->program_name->setText(pgm.arg(GENERATION)); m_dialog->program_version->setText(VERSION); QString locale = QLocale::system().name(); //"en_US"; QStringList paths; paths.append(QString(Constants::getResourcesDirectory().c_str()) + "/help/" + locale); paths.append(QString(Constants::getResourcesDirectory().c_str()) + "/help/" + "en_US"); m_dialog->textview->setSearchPaths(paths); m_dialog->textview->setOpenLinks(true); m_dialog->textview->setOpenExternalLinks(true); current_tip = -1; // preload tips that come with the package // we use separate Help() object for the tip of the day becayse it should // have different size and should not be persistent Help *h = new Help(NULL, ""); int tip_no = 1; while (true) { QString tip_file; tip_file.sprintf("tip%02d.html", tip_no); QString contents; if (fwbdebug) qDebug("Trying tip file %s", tip_file.toAscii().constData()); QString help_file = h->findHelpFile(tip_file); if (!help_file.isEmpty()) { tips.append("file:" + tip_file); tip_no++; } else break; } delete h; current_tip = tips.size() - 1; if (fwbdebug) qDebug("Have %d tips", tips.size()); first_run = st->getBool("UI/FirstRun"); } StartTipDialog::~StartTipDialog() { delete m_dialog; delete http_getter; }; /* * disconnect signal in case dialog is closed before http query completes. * This does happen in unit tests and might happen on slow machines or * slow internet connections */ void StartTipDialog::closeEvent(QCloseEvent*) { disconnect(http_getter, SIGNAL(done(const QString&)), this, SLOT(downloadComplete(const QString&))); } /* * Returns file name for a random tip */ QString StartTipDialog::getRandomTip() { if (tips.size()) { int n = rand() % tips.size(); if (fwbdebug) qDebug("Showing tip %d", n); return tips[n]; } return ""; } void StartTipDialog::run() { if (first_run) { showTip(0); st->setBool("UI/FirstRun", false); } else { if (http_getter->get(QUrl(STARTUP_TIP_URL))) { start_time = time(NULL); } else { if (fwbdebug) qDebug("Can not connect to the url %s", STARTUP_TIP_URL); showTip(getRandomTip(), false); } } } void StartTipDialog::downloadComplete(const QString &txt) { // Do not show dialog if download took too long (time out occurred) if (time(NULL) - start_time < 15) { QString tip; if (http_getter->getStatus()) { showTip(txt); } else { if (fwbdebug) { qDebug() << "Error connecting to the url " << STARTUP_TIP_URL; qDebug() << http_getter->getLastError(); } showTip(getRandomTip(), false); } } else { if (fwbdebug) qDebug("Suppressing startup tip dialog because download took too long"); } } void StartTipDialog::showTip(const QString &txt, bool new_tip) { if (fwbdebug) qDebug("Show tip %s", txt.toStdString().c_str()); if (new_tip) { tips.append(txt); current_tip = tips.size() - 1; } QUrl url(txt); if (url.isValid() && (url.scheme() == "file" || url.scheme() == "http")) m_dialog->textview->setSource(url); else m_dialog->textview->setText(txt); show(); raise(); } void StartTipDialog::showTip(int tip_idx) { if (fwbdebug) qDebug("Show tip #%d", tip_idx); showTip(tips[tip_idx], false); } void StartTipDialog::close() { if (m_dialog->donotshow->isChecked()) st->setBool("UI/NoStartTip", true); QDialog::close(); } void StartTipDialog::nextTip() { if (current_tip < (tips.size() - 1)) { current_tip++; showTip(current_tip); } else run(); // gets next tip, caches it and shows it } void StartTipDialog::prevTip() { current_tip--; if (current_tip < 0) current_tip = 0; showTip(current_tip); } void StartTipDialog::showGettingStartedTutorial() { int ab_group = st->getABTestingGroup(); QString url("http://www.fwbuilder.org/4.0/quick_start_guide_%1.html"); QDesktopServices::openUrl(QUrl(url.arg(ab_group), QUrl::StrictMode)); } fwbuilder-5.1.0.3599/src/libgui/findwhereusedwidget_q.ui0000644000175000017500000001106411733011756023761 0ustar sylvestresylvestre findWhereUsedWidget_q 0 0 895 199 0 0 Form1 0 0 Object: 0 0 100 80 0 0 Object is found in : 6 true true Object Used by Details Include children of the object in search. For example, if the object is a firewall, results will include all rules and groups using it, its interfaces and their addresses Include children Find FWObjectDropArea QWidget
FWObjectDropArea.h
1
resListView resListView itemClicked(QTreeWidgetItem*,int) findWhereUsedWidget_q itemClicked(QTreeWidgetItem*,int) 457 88 433 81 pushButton2 pressed() findWhereUsedWidget_q find() 76 178 447 99 itemActivated(QTreeWidgetItem*,int) itemClicked(QTreeWidgetItem*,int) find()
fwbuilder-5.1.0.3599/src/libgui/ipfAdvancedDialog.h0000644000175000017500000000274011733011756022540 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPFADVANCEDDIALOG_H_ #define __IPFADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class ipfAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::ipfAdvancedDialog_q *m_dialog; public: ipfAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~ipfAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void editProlog(); virtual void editEpilog(); }; #endif // __IPFADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/objconflictresolutiondialog_q.ui0000644000175000017500000001750311733011756025525 0ustar sylvestresylvestre ObjConflictResolutionDialog_q 0 0 850 436 Conflict Resolution 11 0 0 :/Icons/warning.png true false 0 0 There is a conflict between an object in your tree and object in the file you are trying to open. Choose which version of this object you want to use: Qt::AlignVCenter true Qt::Horizontal Current Object Qt::AlignVCenter true 0 0 5 Keep current object Qt::Horizontal QSizePolicy::Expanding 20 20 Always choose this object if there is a conflict New Object Qt::AlignVCenter true 0 0 5 Replace with this object Qt::Horizontal QSizePolicy::Expanding 20 20 Always choose this object if there is a conflict currentObj newObj currentAll useCurrentObj newAll useNewObj useCurrentObj clicked() ObjConflictResolutionDialog_q reject() 20 20 20 20 useNewObj clicked() ObjConflictResolutionDialog_q accept() 20 20 20 20 currentAll toggled(bool) ObjConflictResolutionDialog_q setFlags() 20 20 20 20 newAll toggled(bool) ObjConflictResolutionDialog_q setFlags() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/iosaclAdvancedDialog.cpp0000644000175000017500000003037111733011756023570 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "iosaclAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; iosaclAdvancedDialog::~iosaclAdvancedDialog() { delete m_dialog; } iosaclAdvancedDialog::iosaclAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::iosaclAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); string vers="version_"+obj->getStr("version"); string platform = obj->getStr("platform"); // should be 'iosacl' QString s; QStringList logLevels; QStringList logLevelMapping; logLevelMapping.push_back(""); logLevelMapping.push_back(""); /* filling pop-down menu and pushing the same strings to the mapping * list at the same time so we could use translation */ s=QObject::tr("0 - System Unusable"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("0"); s=QObject::tr("1 - Take Immediate Action"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("1"); s=QObject::tr("2 - Critical Condition"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("2"); s=QObject::tr("3 - Error Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("3"); s=QObject::tr("4 - Warning Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("4"); s=QObject::tr("5 - Normal but significant condition"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("5"); s=QObject::tr("6 - Informational"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("6"); s=QObject::tr("7 - Debug Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("7"); /* do not need to translate syslog facilities, but will use the same * method just in case */ QStringList syslogFacilities; QStringList syslogFacilityMapping; syslogFacilities.push_back(""); syslogFacilityMapping.push_back(""); syslogFacilityMapping.push_back(""); syslogFacilities.push_back("LOCAL0"); syslogFacilityMapping.push_back("LOCAL0"); syslogFacilityMapping.push_back("16"); syslogFacilities.push_back("LOCAL1"); syslogFacilityMapping.push_back("LOCAL1"); syslogFacilityMapping.push_back("17"); syslogFacilities.push_back("LOCAL2"); syslogFacilityMapping.push_back("LOCAL2"); syslogFacilityMapping.push_back("18"); syslogFacilities.push_back("LOCAL3"); syslogFacilityMapping.push_back("LOCAL3"); syslogFacilityMapping.push_back("19"); syslogFacilities.push_back("LOCAL4"); syslogFacilityMapping.push_back("LOCAL4"); syslogFacilityMapping.push_back("20"); syslogFacilities.push_back("LOCAL5"); syslogFacilityMapping.push_back("LOCAL5"); syslogFacilityMapping.push_back("21"); syslogFacilities.push_back("LOCAL6"); syslogFacilityMapping.push_back("LOCAL6"); syslogFacilityMapping.push_back("22"); syslogFacilities.push_back("LOCAL7"); syslogFacilityMapping.push_back("LOCAL7"); syslogFacilityMapping.push_back("23"); bool f1=fwoptions->getBool("iosacl_acl_basic"); bool f2=fwoptions->getBool("iosacl_acl_no_clear"); bool f3=fwoptions->getBool("iosacl_acl_substitution"); bool f4=fwoptions->getBool("iosacl_add_clear_statements"); /* * If none of the new iosacl_acl_* options is set and old iosacl_add_clear_statements * option is true, set iosacl_acl_basic to true. * * If old option iosacl_add_clear_statements iss false, set * iosacl_acl_no_clear to true */ if (!f1 && !f2 && !f3) { if ( f4 ) fwoptions->setBool("iosacl_acl_basic",true); else fwoptions->setBool("iosacl_acl_no_clear",true); } Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); data.registerOption(m_dialog->ipv4before_2, fwoptions, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") << "ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first" ); /* Page "Compiler Options" */ data.registerOption( m_dialog->outputFileName, fwoptions, "output_file" ); data.registerOption( m_dialog->iosacl_acl_basic, fwoptions, "iosacl_acl_basic" ); data.registerOption( m_dialog->iosacl_use_object_groups, fwoptions, "iosacl_use_object_groups" ); /* data.registerOption( m_dialog->iosacl_acl_alwaysNew, fwoptions, "iosacl_acl_always_new" ); */ data.registerOption( m_dialog->iosacl_acl_no_clear, fwoptions, "iosacl_acl_no_clear" ); data.registerOption( m_dialog->iosacl_acl_substitution, fwoptions, "iosacl_acl_substitution" ); data.registerOption( m_dialog->iosacl_acl_temp_addr, fwoptions, "iosacl_acl_temp_addr" ); data.registerOption( m_dialog->iosacl_include_comments, fwoptions, "iosacl_include_comments" ); data.registerOption( m_dialog->iosacl_use_acl_remarks, fwoptions, "iosacl_use_acl_remarks" ); data.registerOption( m_dialog->iosacl_regroup_commands, fwoptions, "iosacl_regroup_commands" ); data.registerOption( m_dialog->iosacl_check_shadowing, fwoptions, "check_shading" ); data.registerOption( m_dialog->iosacl_ignore_empty_groups, fwoptions, "ignore_empty_groups" ); data.registerOption( m_dialog->mgmt_ssh, fwoptions, "mgmt_ssh" ); data.registerOption( m_dialog->mgmt_addr, fwoptions, "mgmt_addr" ); /* page Installer */ data.registerOption( m_dialog->user, fwoptions, "admUser"); data.registerOption( m_dialog->altAddress, fwoptions, "altAddress"); data.registerOption( m_dialog->sshArgs, fwoptions, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwoptions, "scpArgs"); data.registerOption( m_dialog->use_scp, fwoptions, "use_scp"); data.registerOption( m_dialog->filesystem, fwoptions, "filesystem"); data.registerOption( m_dialog->filesystem, fwoptions, "firewall_dir"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText(pis->getCommand().c_str() ); m_dialog->installScriptArgs->setText( pis->getArguments().c_str() ); /* page "Prolog/Epilog" */ data.registerOption( m_dialog->iosacl_prolog_script, fwoptions, "iosacl_prolog_script" ); data.registerOption( m_dialog->iosacl_epilog_script, fwoptions, "iosacl_epilog_script" ); /* page Logging */ data.registerOption(m_dialog->generate_logging_commands, fwoptions, "iosacl_generate_logging_commands"); data.registerOption(m_dialog->syslog_host, fwoptions, "iosacl_syslog_host"); m_dialog->syslog_facility->clear(); m_dialog->syslog_facility->addItems( syslogFacilities ); data.registerOption( m_dialog->syslog_facility, fwoptions, "iosacl_syslog_facility", syslogFacilityMapping); m_dialog->logging_trap_level->clear(); m_dialog->logging_trap_level->addItems(logLevels); data.registerOption( m_dialog->logging_trap_level, fwoptions, "iosacl_logging_trap_level", logLevelMapping); data.registerOption(m_dialog->logging_timestamp, fwoptions, "iosacl_logging_timestamp"); data.registerOption(m_dialog->logging_buffered, fwoptions, "iosacl_logging_buffered"); m_dialog->logging_buffered_level->clear(); m_dialog->logging_buffered_level->addItems(logLevels); data.registerOption( m_dialog->logging_buffered_level, fwoptions, "iosacl_logging_buffered_level", logLevelMapping); data.registerOption(m_dialog->logging_console, fwoptions, "iosacl_logging_console"); m_dialog->logging_console_level->clear(); m_dialog->logging_console_level->addItems(logLevels); data.registerOption( m_dialog->logging_console_level,fwoptions, "iosacl_logging_console_level", logLevelMapping); data.loadAll(); scriptACLModeChanged(); toggleGenerateLogging(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void iosaclAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* options = Firewall::cast(new_state)->getOptionsObject(); assert(options!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(options); const InetAddr *mgmt_addr = Firewall::cast(obj)->getManagementAddress(); if (mgmt_addr) mgmt->setAddress(*mgmt_addr); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); pis->setCommand( m_dialog->installScript->text().toLatin1().constData() ); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void iosaclAdvancedDialog::reject() { QDialog::reject(); } void iosaclAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->iosacl_prolog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->iosacl_prolog_script->setText( edt.text() ); } void iosaclAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->iosacl_epilog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->iosacl_epilog_script->setText( edt.text() ); } void iosaclAdvancedDialog::scriptACLModeChanged() { m_dialog->iosacl_acl_temp_lbl->setEnabled( m_dialog->iosacl_acl_substitution->isChecked()); m_dialog->iosacl_acl_temp_addr->setEnabled( m_dialog->iosacl_acl_substitution->isChecked()); } void iosaclAdvancedDialog::toggleGenerateLogging() { m_dialog->syslog_controls->setEnabled( m_dialog->generate_logging_commands->isChecked()); m_dialog->other_logging_controls->setEnabled( m_dialog->generate_logging_commands->isChecked()); } fwbuilder-5.1.0.3599/src/libgui/DialogData.h0000644000175000017500000000651711733011756021213 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DIALOGOPTIONS_H_ #define __DIALOGOPTIONS_H_ #include "config.h" #include class QWidget; #include #include namespace libfwbuilder { class FWObject; }; class DialogData; class DialogOption { friend class DialogData; public: enum DataType { Unknown, String, Int, Bool }; private: QWidget *w; libfwbuilder::FWObject *obj; QString attr; QStringList mapping; QString override_str_val; int override_int_val; DataType dtype; DialogOption(QWidget *widget, libfwbuilder::FWObject *obj, const char* attr); DialogOption(QWidget *widget, libfwbuilder::FWObject *obj, const char* attr, QStringList mapping); void overrideValue(const QString &val) { override_str_val=val; } void overrideValue(int val) { override_int_val=val; } DataType type() { return dtype; } }; class DialogData { std::list options; void loadToWidget( DialogOption &dopt , bool override=false ); public: DialogData(); ~DialogData(); /** * destroy all registered options, prepare for reuse */ void clear(); /** * registers an option that is stored in object 'obj' as an attribute * 'attr' and controlled by widget 'widget' in the dialog. */ void registerOption(QWidget *widget, libfwbuilder::FWObject *obj, const char *attr); /** * like the method above, plus adds a maping between option value * rendered in the widget and value stored in the object * attribute. This is mostly used for combo boxes. Mapping is defined * by an array of strings in the following format: * * "Linux 2.4" , "linux24", * "IPFilter" , "ipf", * "Cisco PIX" , "pix", * NULL, NULL * * Odd strings correspond to the data in the widget, while even * strings define what is stored in the object (counting strings in * the array from 1). */ void registerOption(QWidget *widget, libfwbuilder::FWObject *obj, const char *attr, QStringList map); /** * sets value 'val' in the widget that corresponds to attribute 'attr' */ void setWidgetValue(const char *attr,const QString &val); void setWidgetValue(const char *attr,int val); /** * loads all options from their respective object attributes to widgets */ void loadAll(); /** * saves all options from their widgets to object attributes */ void saveAll(libfwbuilder::FWObject *new_obj=NULL); }; #endif fwbuilder-5.1.0.3599/src/libgui/ColDesc.cpp0000755000175000017500000000222511733011756021064 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ColDesc.h" #include "platforms.h" using namespace std; ColDesc::ColDesc() { this->type = Unknown; } ColDesc::ColDesc(const string &platform, const string &origin, ColumnType type) { this->origin = origin.c_str(); this->name = getReadableRuleElementName(platform, origin); this->type = type; } fwbuilder-5.1.0.3599/src/libgui/instConf.h0000644000175000017500000000370511733011756021001 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INSTCONF_H_ #define __INSTCONF_H_ #include #include namespace libfwbuilder { class Firewall; }; class instConf { public: bool quiet; bool verbose; int debug; bool incremental; bool dry_run; bool save_diff; bool no_gui; bool backup; bool stripComments; bool compressScript; bool copyFWB; bool saveStandby; bool batchInstall; bool useSCPForRouter; // use scp for cisco ios, pix and hp procurve QString pgm; QString wdir; QString diff_pgm; QString user; QString activationCmd; QString pwd; QString epwd; QString maddr; QString putty_session; QString sshArgs; QString scpArgs; QString fwdir; QString fwscript; libfwbuilder::Firewall *fwobj; QString fwbfile; QString script; QString remote_script; QString backup_file; QString diff_file; instConf(); QString getCmdFromResource(const QString &resource_name); void clear(); }; #endif fwbuilder-5.1.0.3599/src/libgui/openbsdadvanceddialog_q.ui0000644000175000017500000003623311733011756024226 0ustar sylvestresylvestre openbsdAdvancedDialog_q Qt::WindowModal 0 0 433 330 OpenBSD: advanced settings 11 2 Options Qt::Vertical QSizePolicy::Fixed 20 20 IPv4 Packet forwarding Qt::AlignCenter false 0 No change On Off Qt::Horizontal QSizePolicy::Expanding 40 20 IPv6 Packet forwarding Qt::AlignCenter false 0 No change On Off Enable directed broadcast Qt::AlignCenter false No change On Off Forward source routed packets Qt::AlignCenter false No change On Off Generate ICMP redirects Qt::AlignCenter false No change On Off Qt::Horizontal QSizePolicy::Fixed 231 20 Qt::Vertical QSizePolicy::Expanding 93 51 Path 6 pfctl: Qt::AlignCenter false 200 0 200 0 sysctl: Qt::AlignCenter false Specify directory path and a file name for the following utilities on the OS your firewall machine is running. Leave these empty if you want to use default values. Qt::AlignCenter true Qt::Vertical QSizePolicy::Expanding 20 40 Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Horizontal QSizePolicy::Expanding 40 20 Data Qt::Vertical QSizePolicy::Fixed 20 20 Specify directory where data files (e.g. run-time address table) are found on the firewall. Qt::AlignCenter true Data directory: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 200 0 Qt::Vertical 20 118 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true tabWidget openbsd_ip_forward openbsd_ipv6_forward openbsd_ip_directed_broadcast openbsd_ip_sourceroute openbsd_ip_redirect openbsd_path_pfctl openbsd_path_sysctl buttonOk buttonCancel buttonOk clicked() openbsdAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() openbsdAdvancedDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/newFirewallDialog.h0000644000175000017500000001055111733011756022612 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NEWFIREWALLDIALOG_H_ #define __NEWFIREWALLDIALOG_H_ #include "config.h" #include #include "fwbuilder/InterfaceData.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/InterfaceData.h" #include "fakeWizard.h" #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; class Firewall; class Interface; class Logger; class SNMPQuery; }; class QTreeWidgetItem; class QTimer; class QTextEdit; class newFirewallDialog : public QDialog, public FakeWizard { Q_OBJECT; Ui::newFirewallDialog_q *m_dialog; libfwbuilder::FWObject *currentTemplate; libfwbuilder::Firewall *nfw; bool snmpPollCompleted; libfwbuilder::Logger *logger; libfwbuilder::SNMPQuery *q; QTimer *timer; libfwbuilder::FWObjectDatabase *db_orig; libfwbuilder::FWObjectDatabase *tmpldb; libfwbuilder::FWObjectDatabase *db_copy; libfwbuilder::FWObject *parent; std::map templates; bool unloadTemplatesLib; bool getInterfacesBusy; QString discovered_platform; QString discovered_host_os; QString discovered_version; std::list possible_inside_interface_labels; std::list possible_outside_interface_labels; std::list possible_dmz_interface_labels; void fillInterfaceData(libfwbuilder::Interface *intf, QTextBrowser *qte); void fillInterfaceSLList(); void fillInterfaceNZList(); void getInterfaceDataFromInterfaceEditor(EditedInterfaceData &edata, libfwbuilder::InterfaceData &idata); void createFirewallFromTemplate(); void changedAddressesInNewFirewall(); void replaceInterfaceAttributes(libfwbuilder::Firewall *fw, libfwbuilder::Interface *intf, EditedInterfaceData *new_data); libfwbuilder::Address* replaceInterfaceAddressData( libfwbuilder::Firewall *fw, libfwbuilder::Interface *intf, libfwbuilder::Address *addr_obj, const QString &address, const QString &netmask, bool ipv4); void replaceReferencesToNetworks(libfwbuilder::Firewall *fw, libfwbuilder::Interface *intf, libfwbuilder::InetAddrMask old_net, libfwbuilder::InetAddrMask new_net); void replaceReferencesToObject(libfwbuilder::Firewall *fw, libfwbuilder::FWObject *old_obj, libfwbuilder::FWObject *new_obj); public: newFirewallDialog(QWidget *parentw, libfwbuilder::FWObject *parent); virtual ~newFirewallDialog(); libfwbuilder::Firewall* getNewFirewall() { return nfw; }; virtual bool appropriate(const int page) const; void showPage(const int page); //it was "selected(QString)" bool validateAddressAndMask(const QString &addr,const QString &netm); void getIPAddressOfFirewallByName(); public slots: virtual void changed(); virtual void getInterfacesViaSNMP(); virtual void monitor(); virtual void templateSelected(QListWidgetItem *itm); void browseTemplate(); void useStandardTemplate(); void updateTemplatePanel(); protected slots: void finishClicked(); void cancelClicked(); void nextClicked(); void backClicked(); void cleanup(); }; #endif // __NEWFIREWALLDIALOG_H fwbuilder-5.1.0.3599/src/libgui/printingprogressdialog_q.ui0000644000175000017500000000341211733011756024516 0ustar sylvestresylvestre printingProgressDialog_q 0 0 275 110 Printing Cancel Qt::Vertical QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 40 20 textLabel1 false fwbuilder-5.1.0.3599/src/libgui/FWObjectDrag.cpp0000644000175000017500000000675711733011756022024 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "FWObjectDrag.h" #include //Added by qt3to4: #include using namespace std; using namespace libfwbuilder; /***************************************************************************** * * Class FWObjectDrag * *****************************************************************************/ QString FWObjectDrag::FWB_MIME_TYPE="x-fwobject/pointer"; FWObjectDrag::FWObjectDrag(list ol, QWidget *dragSource, const char* /*name*/) : QDrag( dragSource ) { objlist=ol; QMimeData *mime = new QMimeData; mime->setData(FWB_MIME_TYPE, encodedData()); setMimeData(mime); } FWObjectDrag::~FWObjectDrag() { } QByteArray FWObjectDrag::encodedData() const { QByteArray a; //if (QString(mime)==FWB_MIME_TYPE) QDataStream stream(&a, QIODevice::WriteOnly); int n = objlist.size(); stream << n; for (list::const_iterator i=objlist.begin(); i!=objlist.end(); ++i) { FWObject *o = *i; stream.writeRawData( (const char*)(&o) , sizeof(FWObject*) ); } #if 0 a.resize( sizeof(FWObject*) * objlist.size() + sizeof(int) ); void *dst = a.data(); int n = objlist.size(); memcpy( dst, &n, sizeof(int) ); dst += sizeof(int); for (list::iterator i=objlist.begin(); i!=objlist.end(); ++i) { FWObject *o = *i; memcpy( dst, &o, sizeof(FWObject*) ); dst += sizeof(FWObject*); } #endif return a; } bool FWObjectDrag::decode( QDropEvent *ev, list &ol) { QByteArray rawdata = ev->encodedData( static_cast(FWB_MIME_TYPE.toLatin1()) ); ol.clear(); QDataStream stream(&rawdata, QIODevice::ReadOnly); int n = 0; stream >> n; for (int i=0; iaccept(); return true; } bool FWObjectDrag::decode( QDragEnterEvent *ev, list &ol) { QByteArray rawdata = ev->encodedData( static_cast(FWB_MIME_TYPE.toLatin1()) ); ol.clear(); QDataStream stream(&rawdata, QIODevice::ReadOnly); int n = 0; stream >> n; for (int i=0; iaccept(); return true; } Qt::DropAction FWObjectDrag::start(Qt::DropActions action) { if (fwbdebug) qDebug("FWObjectDrag::start"/*, action*/); return QDrag::start(action); } fwbuilder-5.1.0.3599/src/libgui/firewalldialog_q.ui0000644000175000017500000003527711733011756022722 0ustar sylvestresylvestre FirewallDialog_q true 0 0 927 284 0 0 Firewall 12 QFrame::Box QFrame::Sunken 0 0 250 0 350 16777215 QFrame::Box QFrame::Sunken 0 0 32767 32767 Name: false 1 0 100 23 0 0 32767 32767 Platform: false 0 0 100 26 0 0 32767 32767 Version: false 0 0 100 26 0 0 32767 32767 Host OS: false 0 0 100 26 0 0 Modified: 0 0 TextLabel 0 0 Compiled: 0 0 TextLabel 0 0 Installed: 0 0 TextLabel 0 0 200 0 32767 32767 Host OS Settings ... 0 0 200 0 32767 32767 Firewall Settings ... 0 0 215 0 215 16777215 Skip this firewall for batch compile and install operations Inactive firewall Qt::Vertical QSizePolicy::MinimumExpanding 203 67 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name platform version hostOS osAdvanced fwAdvanced inactive fwAdvanced clicked() FirewallDialog_q openFWDialog() 20 20 20 20 osAdvanced clicked() FirewallDialog_q openOSDialog() 20 20 20 20 platformChanged() hostOSChanged() changed()
fwbuilder-5.1.0.3599/src/libgui/linksysAdvancedDialog.h0000644000175000017500000000276211733011756023462 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LINKSYSADVANCEDDIALOG_H_ #define __LINKSYSADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class linksysAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::linksysAdvancedDialog_q *m_dialog; public: linksysAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~linksysAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); public slots: virtual void setDefaultPrompts(); }; #endif // __LINKSYSADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/printerStream.cpp0000644000175000017500000003602411733011756022410 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "printerStream.h" #include "RuleSetModel.h" #include "RuleSetView.h" #include #include #include #include #include printerStream::printerStream(QPrinter *p, float ts, float m, bool h, const QString &ht, PrintingProgressDialog *pd) : pr()//,metrics(p) { printer = p; table_scaling = ts; margin = m; printHeader = h; headerText = ht; ppd = pd; headerFont = QFont( "times", 10, QFont::Normal ); bodyFont = QFont( "times", 14, QFont::Normal ); headerHeight = 1.5; // 1.5 cm for header pageNo = 0; active = false; fromPage = 1; toPage = 9999; headerTimeString = QDateTime::currentDateTime().toString(); } bool printerStream::begin() { if( !pr.begin(printer) ) // paint on printer return false; active=true; pageWidth = printer->width(); pageHeight = printer->height(); if (fwbdebug) { qDebug("printer dimensions: %dx%d",pageWidth,pageHeight); qDebug("Margin: %.1f", margin); } dpiy = printer->logicalDpiY(); ymargin = (int) ( (margin/2.54)*dpiy ); // assuming printer's resolutions by X and Y axes are the same xmargin = ymargin; pageBody = QRect( xmargin, ymargin, printer->width() - 2 * xmargin, printer->height() - 2 * ymargin ); yHeaderHeight = int((headerHeight / 2.54) * dpiy); yHeaderLine = int(((headerHeight - 0.5) / 2.54) * dpiy); pr.setFont(headerFont); QFontMetrics fm = pr.fontMetrics(); QRect br = fm.boundingRect("Page 999"); headerTextBox = QRect(xmargin, ymargin + yHeaderLine - fm.lineSpacing() - 1, printer->width() - 2 * xmargin, fm.lineSpacing() + 1); headerBox = QRect(xmargin, ymargin, printer->width() - 2 * xmargin, yHeaderHeight); if (fwbdebug) { qDebug("dpiy=%d", dpiy); qDebug("yHeaderHeight=%d", yHeaderHeight); qDebug("yHeaderLine=%d", yHeaderLine); qDebug("fm.lineSpacing()=%d", fm.lineSpacing()); qDebug("bounding rect for the header text: l=%d,t=%d,w=%d,h=%d", br.left(), br.top(), br.width(), br.height()); qDebug("headerBox: l=%d,t=%d,w=%d,h=%d", headerBox.left(), headerBox.top(), headerBox.width(), headerBox.height()); qDebug("headerTextBox: l=%d,t=%d,w=%d,h=%d", headerTextBox.left(), headerTextBox.top(), headerTextBox.width(), headerTextBox.height()); } yPos = 0; pageNo = 1; QPaintDevice *dev = pr.device(); // lets table with width 1000 pixels be drawn 80% of the page width pixmap_scaling_ratio = float(dev->width()) * 0.8 / 1000 * table_scaling; return true; } void printerStream::end() { // according to QT docs, there is no need to explicitly call QPainter::end() // because its destructor does it // pr.end(); } int printerStream::getWorkspaceWidth() { return pageBody.width(); } int printerStream::getWorkspaceHeight() { return (printHeader) ? (pageBody.height()-headerBox.height()) : pageBody.height(); } void printerStream::beginPage() { yPos=0; if (ppd!=NULL) ppd->setCurrentPageNo(pageNo); if (printHeader) { if (fwbdebug) qDebug("Printing header for page %d (%d-%d)", pageNo, fromPage, toPage); QString page = QObject::tr("Page %1").arg(pageNo); if (pageNo>=fromPage && pageNo<=toPage) { pr.setFont(headerFont); pr.setPen(Qt::black); pr.setPen(Qt::SolidLine); pr.drawText(headerTextBox,Qt::AlignLeft,page); pr.drawText(headerTextBox,Qt::AlignCenter,headerText); pr.drawText(headerTextBox,Qt::AlignRight,headerTimeString); pr.drawLine(headerTextBox.left(),headerTextBox.bottom(), headerTextBox.right(),headerTextBox.bottom()); } yPos = ymargin+headerBox.height(); } } void printerStream::flushPage() { if (pageNo>=fromPage && pageNo<=toPage) printer->newPage(); pageNo++; } int printerStream::getTextHeight(const QString &txt) { if (txt.isEmpty()) return 0; if (printer->printerState() == QPrinter::Aborted) return 0; pr.setFont( bodyFont ); QFontMetrics fm = pr.fontMetrics(); int nlines=1; int i=-1; while ( (i=txt.indexOf("\n",i+1))>=0 ) nlines++; return nlines*fm.lineSpacing(); } void printerStream::printText(const QString &txt, bool newLine) { if (fwbdebug) { qDebug("printText -------"); qDebug("pageBody.height(): %d", pageBody.height()); qDebug("yPos: %d", yPos); } if (txt.isEmpty()) return; if (printer->printerState() == QPrinter::Aborted) return; pr.setFont( bodyFont ); QFontMetrics fm = pr.fontMetrics(); QRect br = fm.boundingRect(txt); if (getYSpace()=fromPage && pageNo<=toPage) { pr.setPen(Qt::black); pr.drawText( xmargin, yPos, printer->width()-2*xmargin, br.height(), Qt::TextExpandTabs | Qt::TextDontClip, txt ); } int nlines=1; int i=-1; while ( (i=txt.indexOf("\n",i+1))>=0 ) nlines++; if (newLine) yPos = yPos + nlines*fm.lineSpacing(); } void printerStream::printPixmap(const QPixmap &pm, bool newLine) { #if 0 QPaintDevice *dev = pr.device(); if (fwbdebug) { qDebug("printPixmap: width=%d height=%d", pm.width(), pm.height()); qDebug("printPixmap: printer->resolution()=%d", printer->resolution()); if (dev) { qDebug("printPixmap: device parameters:"); qDebug(" height=%d width=%d", dev->height(), dev->width()); qDebug(" logicalDpiY=%d logicalDpiX=%d", dev->logicalDpiY(), dev->logicalDpiX()); qDebug(" physicalDpiY=%d physicalDpiX=%d", dev->physicalDpiY(), dev->physicalDpiX()); } } #endif int target_w = (int)(pm.width() * pixmap_scaling_ratio); int target_h = (int)(pm.height() * pixmap_scaling_ratio); int pmYOffset = 0; while ( getYSpace()<(pm.height()-pmYOffset) ) { int yFrag = pageBody.height() - yPos; if (pageNo>=fromPage && pageNo<=toPage) { if (fwbdebug) qDebug("Print pixmap 1: yPos=%d pmYOffset=%d " "yFrag=%d target_w=%d target_h=%d", yPos, pmYOffset, yFrag, target_w, target_h); pr.drawPixmap(xmargin, yPos, target_w, target_h, pm, 0, pmYOffset, -1, yFrag); } pmYOffset = pmYOffset + yFrag; flushPage(); beginPage(); // resets yPos } if (pageNo>=fromPage && pageNo<=toPage) { if (fwbdebug) qDebug("Print pixmap 2: yPos=%d pmYOffset=%d target_w=%d target_h=%d", yPos, pmYOffset, target_w, target_h); pr.drawPixmap(xmargin, yPos, target_w, target_h, pm, 0, pmYOffset, -1, -1); } if (newLine) yPos = yPos + (target_h - pmYOffset); } void printerStream::printRuleSetView(RuleSetView *tbl, bool top_margin) { if (fwbdebug) { qDebug("printQTable ----------------------------------------------"); qDebug("Size: %dx%d", tbl->width(), tbl->height()); qDebug("YSpace: %d", getYSpace()); qDebug("yPos: %d", yPos); } int columnsWidth = 0; int i = 0; while (i < tbl->model()->columnCount()) { columnsWidth += tbl->columnWidth(i); i++; } RuleSetModelIterator it = ((RuleSetModel*)tbl->model())->begin(); RuleSetModelIterator end = ((RuleSetModel*)tbl->model())->end(); RuleSetModelIterator bottomIt; while (it.isValid() && it != end) { // Pages iterations int tblHeight = (int)( (float)(tbl->header()->height()) * pixmap_scaling_ratio); /* =================================================================== * Row height is screen pixels, getYSpace returns remaining * space in printer resolution units. Keep track of both to * resize pixmap * =================================================================== */ int pixMapHeight = tbl->header()->height(); RuleSetModelIterator pit = it; while (pit != end) { // Check if current index is collapsed QModelIndex index = pit.index(); QModelIndex parent = index.parent(); if (!parent.isValid() || tbl->isExpanded(parent)) { int nth = tblHeight + (int)((float)(tbl->rowHeight(index)) * pixmap_scaling_ratio); if ( nth==getYSpace() ) break; if ( nth>getYSpace() ) { // if it == pit then even single row does not fit on the page if (it == pit) { pixMapHeight = tbl->rowHeight(index); } else { --pit; } break; } tblHeight = nth; pixMapHeight += tbl->rowHeight(index); } ++pit; } bottomIt = pit; int left_hdr_w = 0; int top_hdr_h = 0; if (top_margin && tbl->header() != NULL) top_hdr_h = tbl->header()->height(); int tblWidth = columnsWidth + left_hdr_w; qDebug("Page %d -- tblWidth: %d tblHeight: %d", pageNo, tblWidth, tblHeight); tbl->resize(tblWidth, pixMapHeight); tbl->updateWidget(); tbl->scrollTo(it.index(), QAbstractItemView::PositionAtTop); printPixmap(QPixmap::grabWidget(tbl)); if (bottomIt == end) break; flushPage(); beginPage(); it = bottomIt; ++it; } } void printerStream::printQTable(QTableView *tbl, bool left_margin, bool top_margin) { if (fwbdebug) { qDebug("printQTable ----------------------------------------------"); qDebug("Size: %dx%d", tbl->width(), tbl->height()); // qDebug("Visible: %dx%d", // tbl->contentsRect().width(), tbl->contentsRect().height()); // qDebug("Viewport: %dx%d", // tbl->viewport()->width(), tbl->viewport()->height()); // qDebug("pageBody.height(): %d", pageBody.height()); qDebug("YSpace: %d", getYSpace()); qDebug("yPos: %d", yPos); } int top_row = 0; int bottom_row = 1; int columnsWidth = 0; int i = 0; while (i < tbl->model()->columnCount()) { columnsWidth += tbl->columnWidth(i); i++; } int rowCount = tbl->model()->rowCount(); while (top_row <= (rowCount-1)) { int row = 0; int tblHeight = (int)( (float)(tbl->horizontalHeader()->height()) * pixmap_scaling_ratio); /* =================================================================== * Row height is screen pixels, getYSpace returns remaining * space in printer resolution units. Keep track of both to * resize pixmap * =================================================================== */ int pixMapHeight = tbl->horizontalHeader()->height(); for (row=top_row; row < rowCount; ++row) { if (tbl->isRowHidden(row)) { // hidden rows count but do not contribute to table height continue; } int nth = tblHeight + (int)((float)(tbl->rowHeight(row)) * pixmap_scaling_ratio); if ( nth==getYSpace() ) break; if ( nth>getYSpace() ) { row--; break; } tblHeight = nth; pixMapHeight += tbl->rowHeight(row); } // if row < top_row then even single row does not fit on the page if (row < top_row) { row = top_row; pixMapHeight = tbl->rowHeight(top_row); } if (row == rowCount) row--; bottom_row = row; int left_hdr_w = 0; if (left_margin && tbl->verticalHeader() != NULL) left_hdr_w = tbl->verticalHeader()->width(); int top_hdr_h = 0; if (top_margin && tbl->horizontalHeader() != NULL) top_hdr_h = tbl->horizontalHeader()->height(); int tblWidth = columnsWidth + left_hdr_w; if (fwbdebug) qDebug("Page %d -- (%d-%d of %d rows) tblWidth: %d tblHeight: %d", pageNo, top_row, bottom_row, rowCount, tblWidth, tblHeight); tbl->resize(tblWidth, pixMapHeight); tbl->verticalHeader()->resize( tbl->verticalHeader()->width(), tbl->height() - tbl->horizontalHeader()->height()); tbl->horizontalHeader()->resize( tbl->width() - tbl->verticalHeader()->width(), tbl->horizontalHeader()->height()); // QTableView::scrollTo() makes row visible, but if there are not enough // rows below it, it appears in the middle of the table. This means the table // shows few rows that belong on the previous page, which is bad. // // tbl->scrollTo(tbl->model()->index(top_row, 0), // QAbstractItemView::PositionAtTop); int top_row_position = tbl->verticalHeader()->sectionPosition(top_row); tbl->verticalHeader()->setOffset(top_row_position); tbl->update(); printPixmap(QPixmap::grabWidget(tbl)); //,0,0,-1,pixMapHeight)); if (bottom_row>=(rowCount-1)) break; flushPage(); beginPage(); top_row = bottom_row + 1; } } fwbuilder-5.1.0.3599/src/libgui/FirewallInstallerCisco.h0000644000175000017500000000323311733011756023616 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FIREWALLINSTALLERCISCO_H_ #define __FIREWALLINSTALLERCISCO_H_ #include "config.h" #include "FirewallInstaller.h" #include #include #include #include #include namespace libfwbuilder { class Firewall; } class FirewallInstallerCisco : public FirewallInstaller { Q_OBJECT; protected: QStringList config_lines; virtual QString getDestinationDir(const QString &dir); virtual bool readManifest(const QString &conffie, QMap *all_files); public: FirewallInstallerCisco(instDialog *_dlg, instConf *_cnf, const QString &_p); virtual bool packInstallJobsList(libfwbuilder::Firewall*); virtual void activatePolicy(const QString &script, const QString &args); }; #endif fwbuilder-5.1.0.3599/src/libgui/DynamicGroupDialog.h0000644000175000017500000000470311733011756022736 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DynamicGroupDialog_h__ #define __DynamicGroupDialog_h__ #include "config.h" #include #include #include #include "fwbuilder/FWObject.h" #include "ObjectListView.h" #include "ObjectIconView.h" #include "BaseObjectDialog.h" #include #include #include class ObjectListViewItem; class ProjectPanel; class DynamicGroupDialog : public BaseObjectDialog { Q_OBJECT; Ui::DynamicGroupDialog_q m_ui; QStandardItemModel *m_model; bool m_reloadObjFilter; std::list m_loadedObjFilter; std::set m_loadedAllKeywords; void loadObjFilter(); public: DynamicGroupDialog(QWidget *parent); libfwbuilder::FWObject *getCurrentObj() { return obj; } public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool *); void addMatchClicked(); void deleteFilterClicked(); void gotItemDoubleClicked(QTreeWidgetItem *item, int); }; class DynamicItemDelegate : public QItemDelegate { Q_OBJECT; DynamicGroupDialog *m_dialog; public: DynamicItemDelegate(DynamicGroupDialog *dialog, QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; public slots: void comboActivated(int); }; #endif /* __DynamicGroupDialog_h__ */ fwbuilder-5.1.0.3599/src/libgui/PixmapFactory.h0000644000175000017500000000204211733011756021775 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include class PixmapFactory { public: PixmapFactory() {} static QPixmap getPixmap(const std::string &icn_name); }; fwbuilder-5.1.0.3599/src/libgui/InterfaceEditorWidget.h0000644000175000017500000000633311733011756023431 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INTERFACEEDITORWIDGET_H #define INTERFACEEDITORWIDGET_H #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include "InterfacesTabWidget.h" #include "FWBSettings.h" #include #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include "fwbuilder/StateSyncClusterGroup.h" namespace Ui { class InterfaceEditorWidget; } struct EditedInterfaceData; struct ClusterInterfaceData; struct AddressInfo { bool ipv4; QString address; QString netmask; }; class InterfaceEditorWidget : public QWidget { Q_OBJECT; public: InterfaceEditorWidget(QWidget *parent, libfwbuilder::InterfaceData* data); InterfaceEditorWidget(QWidget *parent, libfwbuilder::Interface *iface); InterfaceEditorWidget(QWidget *parent, ClusterInterfaceData data); InterfaceEditorWidget(QWidget *parent); ~InterfaceEditorWidget(); void setData(libfwbuilder::InterfaceData *data); libfwbuilder::Interface* getInterface(); EditedInterfaceData getInterfaceData(); bool isValid(); void updateColumnsSizes(); void setClusterMode(bool); void setProtocolIndex(int); void setHostOS(const QString &s); private: QTabWidget *tabw; QToolButton *addAddr, *delAddr; libfwbuilder::Interface *interfacep; Ui::InterfaceEditorWidget *m_ui; QMap > buttons; QMap > rows; QMap types; QMap fwaddrs; bool validateAddress(const QString &addr, const QString &netm, bool regular, bool ipv4); bool clusterMode; QString os, errorTitle, errorText; void setError(const QString &title, const QString &text); public slots: int addNewAddress(); int addNewAddress(QString address, QString netmask, bool ipv4 = true); void deleteAddress(); void nameEdited(QString); void typeChanged(int); void addressChanged(int, int); void protocolChanged(QString); void setExplanation(const QString&); void showError(); protected: void changeEvent(QEvent *e); void resizeEvent ( QResizeEvent * ); }; #endif // INTERFACEEDITORWIDGET_H fwbuilder-5.1.0.3599/src/libgui/FilterDialog.h0000644000175000017500000000542511733011756021564 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FILTERDIALOG_H_ #define __FILTERDIALOG_H_ #include "config.h" #include #include "fwbuilder/FWObject.h" #include "fwbuilder/Resources.h" #include #include class QRegExp; class ObjectDescriptor; enum {FWF_ANY = 0, FWF_ALL = 1}; enum {FWF_NAME = 0,FWF_ADDRESS = 1}; enum {FWF_CONTAINS = 0, FWF_IS_EQUAL_TO = 1, FWF_STARTS_WITH = 2, FWF_ENDS_WITH =3, FWF_MATCHES_WILDCARD = 4, FWF_MATCHES_REGEXP = 5}; class Filter { private: bool CaseSensitive; bool MatchAny; QVector addr_patterns; QVector name_patterns; public: Filter(); ~Filter(); void addNamePattern(const QString &s,bool wc); void addNameRegExp(const QRegExp &r); void addAddrPattern(const QString &s,bool wc); void addAddrRegExp(const QRegExp &r); void setCaseSens(bool b); bool isCaseSens (); void setMatchAny(bool b); bool isMatchAny (); bool testName(const QString &s); bool testAddr(const QString &s); bool test(const ObjectDescriptor &od); bool isValid(); void clear(); int getNamePatternsNumber(); int getAddrPatternsNumber(); QString getNamePatternString(int p); QString getAddrPatternString(int p); bool isNameWildcard(int p); bool isAddrWildcard(int p); Filter& operator=(const Filter& f); }; class FilterDialog : public QDialog { Q_OBJECT private: Filter * flt; Ui::FilterDialog_q *m_dialog; bool validate(); void update(); QString LastFile; QRegExp constructRegExp(int p); public: FilterDialog(QWidget *parent); ~FilterDialog(); void setFilter(Filter *); public slots: virtual void apply(); virtual void save(); virtual void load(); virtual void addPattern(); virtual void removePattern(); virtual void clearPatterns(); virtual void updateData(); }; #endif fwbuilder-5.1.0.3599/src/libgui/FirewallSelectorWidget.h0000644000175000017500000000354611733011756023633 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FIREWALLSELECTORWIDGET_H #define FIREWALLSELECTORWIDGET_H #include #include #include #include #include #include #include #include struct TableRow { libfwbuilder::Firewall* firewall; QTableWidgetItem* title; QCheckBox* use; QRadioButton* master; }; class FirewallSelectorWidget : public QTableWidget { Q_OBJECT public: FirewallSelectorWidget(QWidget *parent = NULL); ~FirewallSelectorWidget(); void setFirewallList(std::list, bool select = false); // pointer to firewall , master QList > getSelectedFirewalls(); bool isValid(); virtual void resizeEvent (QResizeEvent*); private: QMap boxrow; QMap radiorow; QMap rows; public slots: void usageChanged(bool); void clear(); }; #endif // FIREWALLSELECTORWIDGET_H fwbuilder-5.1.0.3599/src/libgui/FWBTree.h0000644000175000017500000000700311733011756020447 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWBTREE_H #define FWBTREE_H #include #include #include #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; }; class FWBTree { static QStringList standardFolders; static QMap systemGroupTypes; static QMap systemGroupNames; static QMap systemGroupPaths; static QSet standardIDs; static QMap copyMenuState; static QMap cutMenuState; static QMap pasteMenuState; static QMap deleteMenuState; void init_statics(); public: FWBTree(); bool isSystem(libfwbuilder::FWObject *obj); bool isStandardFolder(libfwbuilder::FWObject *obj); bool isStandardId(libfwbuilder::FWObject *obj); bool validateForInsertion(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj, QString &err); /** * returns boolean value that defines whether menu item "Copy" * should be enabled when object with a path objPath is selected * in the tree. By default menu items are enabled, so this method * returns True if object path is unknown. */ bool getCopyMenuState(const QString &objPath) { if (copyMenuState.count(objPath)!=0) return copyMenuState[objPath]; else return true; } bool getCutMenuState(const QString &objPath) { if (cutMenuState.count(objPath)!=0) return cutMenuState[objPath]; else return true; } bool getPasteMenuState(const QString &objPath) { if (pasteMenuState.count(objPath)!=0) return pasteMenuState[objPath]; else return true; } bool getDeleteMenuState(const QString &objPath) { if (deleteMenuState.count(objPath)!=0) return deleteMenuState[objPath]; else return true; } void getStandardSlotForObject(const QString &objType, QString &parentType, QString &parentName); libfwbuilder::FWObject* getStandardSlotForObject(libfwbuilder::FWObject* lib, const QString &objType); libfwbuilder::FWObject* createNewLibrary(libfwbuilder::FWObjectDatabase *db); QString getTranslatableObjectTypeName(const QString &type_name); QString getTranslatableNewObjectMenuText(const QString &type_name); static QList getObjectTypes(); static QList getServiceTypes(); }; #endif fwbuilder-5.1.0.3599/src/libgui/FWCmdAddObject.cpp0000644000175000017500000002533411733011756022253 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWCmdChange.h" #include "FWCmdAddObject.h" #include "FWWindow.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include #include using namespace libfwbuilder; using namespace std; /******************************************************** * FWCmdAddObject * * This command controls adding an object to another object. This can * be adding an object to a system group or adding interface to a host * or address to an interface and so on, where object itself becomes a * child rather than reference to it gets created. * ********************************************************/ FWCmdAddObject::FWCmdAddObject(ProjectPanel *project, FWObject *grp, FWObject *mem, QString text, QUndoCommand* macro): FWCmdChange(project, grp, text, false, macro) { member = mem; require_complete_tree_reload = false; if (text.isEmpty()) { setText(QObject::tr("Add object to group")); } else { setText(text); } } FWCmdAddObject::~FWCmdAddObject() { if (member->getRefCounter() <= 1) delete member; else member->unref(); } void FWCmdAddObject::undo() { // Remove object this->member from the group but do not delete it. // We still keep pointer to it in this->newState FWObject* grp = getObject(); grp->remove(member, false); if (fwbdebug) qDebug() << "FWCmdAddObject::undo() member->ref_counter=" << member->getRefCounter(); if (Firewall::isA(member) && project->getCurrentRuleSet()->isChildOf(member)) { // need to close ruleset view project->closeRuleSetPanel(); } QString filename = QString::fromUtf8(grp->getRoot()->getFileName().c_str()); QCoreApplication::postEvent( mw, new removeObjectFromTreeEvent(filename, member->getId())); QCoreApplication::postEvent( mw, new updateObjectAndSubtreeImmediatelyEvent(filename, grp->getId())); // see comment in redo() QCoreApplication::sendPostedEvents(mw, 0); QCoreApplication::postEvent( mw, new dataModifiedEvent(filename, grp->getId())); if (mw->isEditorVisible()) QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, grp->getId())); QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, grp->getId())); } void FWCmdAddObject::prepareStatesForRedo() { // newState should have the new group member. Add it to the group. // This member could have been added to the newState, if so, // remove it but increment reference counter. FWObject* grp = getObject(); FWObject *new_grp = getNewState(); if (member == NULL) { // Find new object among children of newState. member can be // NULL if FWCmdAddObject object is created before the new // object can be created. This is the case when we copy whole // subtree from one data file to another in // ObjectManipulator::actuallyPasteTo(). There we call // FWObjectDatabase::recursivelyCopySubtree which needs parent // object as a parameter, so we have to create newState before // new object is created. for (list::iterator i=new_grp->begin(); i!=new_grp->end(); ++i) { FWObject *co = *i; if (!grp->hasChild(co)) { member = co; break; } } } if (new_grp->hasChild(member)) { member->ref(); new_grp->remove(member, false); // and do not delete } } void FWCmdAddObject::redo() { prepareStatesForRedo(); FWObject* grp = getObject(); grp->add(member); if (fwbdebug) qDebug() << "FWCmdAddObject::redo()" << member->getName().c_str() << "-->" << grp->getName().c_str() << "member->ref_counter=" << member->getRefCounter() << "reload=" << require_complete_tree_reload << "editor=" << mw->isEditorVisible(); QString filename = QString::fromUtf8(grp->getRoot()->getFileName().c_str()); // updateObjectAndSubtreeImmediatelyEvent updates the part of the // tree where object we just added is attached. This rebuilds // subtree. However, if the object was copied from another data // file and dragged with it some other objects (as dependencies) // in other parts of the tree, rebulding the subtree is // insufficient, we need to reload the whole tree. The caller should have // set flag require_complete_tree_reload to signal that. if (require_complete_tree_reload) QCoreApplication::postEvent( mw, new reloadObjectTreeImmediatelyEvent(filename)); else { QCoreApplication::postEvent( mw, new insertObjectInTreeEvent(filename, grp->getId(), member->getId())); QCoreApplication::postEvent( mw, new updateObjectAndSubtreeImmediatelyEvent( filename, grp->getId())); } // when user clicks in the undo stack window, the program executes // all undo/redo commands up to the line they clicked on. This // means bunch of redo() commands can execute at once. All events // they posted, however, will be processed after that. If these // redo() commands added or removed objects in the tree, the tree // widget in ObjectManipulator gets updated after that has // happened and gets out of sync with object // tree. sendPostedEvents() should send events posted up to this // point to the receiver immediately, which in this case should // update widgets to keep them in sync. QCoreApplication::sendPostedEvents(mw, 0); QCoreApplication::postEvent(mw, new dataModifiedEvent(filename, grp->getId())); // post openObjectInEditorEvent first so that editor panel opens // this matters if the tree needs to scroll to show the object when // showObjectInTreeEvent is posted because vertical size of the tree // changes when editor opens //if (mw->isEditorVisible()) QCoreApplication::postEvent(mw, new openObjectInEditorEvent( filename, member->getId())); QCoreApplication::postEvent(mw, new showObjectInTreeEvent( filename, member->getId())); } void FWCmdAddObject::notify() { } /******************************************************** * FWCmdAddUserFolder * ********************************************************/ FWCmdAddUserFolder::FWCmdAddUserFolder(ProjectPanel *project, FWObject *parentFolder, const QString &userFolder, QString text, QUndoCommand *macro) : FWCmdChange(project, parentFolder, text, false, macro), m_userFolder(userFolder) { } void FWCmdAddUserFolder::redo() { FWCmdChange::redo(); FWObject *obj = getObject(); QString fileName = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); QCoreApplication::postEvent(mw, new addUserFolderEvent (fileName, obj->getId(), m_userFolder)); } void FWCmdAddUserFolder::undo() { FWCmdChange::undo(); FWObject *obj = getObject(); QString fName = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); QCoreApplication::postEvent(mw, new removeUserFolderEvent(fName, obj->getId(), m_userFolder)); } /* We don't want to display the system folder after we add a user folder, so we just swallow the notify. */ void FWCmdAddUserFolder::notify() { } /******************************************************** * FWCmdAddLibrary * ********************************************************/ FWCmdAddLibrary::FWCmdAddLibrary(ProjectPanel *project, FWObject *root, FWObject *lib, QString text, QUndoCommand* macro): FWCmdAddObject(project, root, lib, text, macro) { assert(FWObjectDatabase::cast(root)!=NULL); if (text.isEmpty()) { setText(QObject::tr("Add library")); } else { setText(text); } } FWCmdAddLibrary::~FWCmdAddLibrary() {} void FWCmdAddLibrary::undo() { FWObject* root = getObject(); FWObject* lib = member; root->remove(lib, false); QString filename = QString::fromUtf8(FWObjectDatabase::cast(root)->getFileName().c_str()); QCoreApplication::postEvent( mw, new removeTreePageEvent(filename, lib->getId())); // switch to another library QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, FWObjectDatabase::STANDARD_LIB_ID)); } void FWCmdAddLibrary::redo() { prepareStatesForRedo(); FWObject* root = getObject(); FWObject* lib = member; getObject()->add(lib); QString filename = QString::fromUtf8(FWObjectDatabase::cast(root)->getFileName().c_str()); QCoreApplication::postEvent( mw, new addTreePageEvent(filename, lib->getId())); QCoreApplication::postEvent( mw, new updateObjectAndSubtreeImmediatelyEvent(filename, lib->getId())); QCoreApplication::postEvent(mw, new dataModifiedEvent(filename, lib->getId())); // post openObjectInEditorEvent first so that editor panel opens // this matters if the tree needs to scroll to show the object when // showObjectInTreeEvent is posted because vertical size of the tree // changes when editor opens //if (mw->isEditorVisible()) QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, lib->getId())); QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, lib->getId())); } fwbuilder-5.1.0.3599/src/libgui/simpletexteditor_q.ui0000644000175000017500000000765411733011756023340 0ustar sylvestresylvestre SimpleTextEditor_q true 0 0 592 344 Qt::StrongFocus Script Editor 11 11 11 11 Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn Qt::Horizontal QSizePolicy::Expanding 40 20 OK true Cancel Import from file ... 0 0 QFrame::HLine QFrame::Sunken Qt::Horizontal editor inputFromFileButton ok_button cancel_button ok_button clicked() SimpleTextEditor_q accept() 20 20 20 20 cancel_button clicked() SimpleTextEditor_q reject() 20 20 20 20 inputFromFileButton clicked() SimpleTextEditor_q loadFromFile() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/LibraryDialog.h0000644000175000017500000000307411733011756021741 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LIBRARYDIALOG_H_ #define __LIBRARYDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class LibraryDialog : public BaseObjectDialog { Q_OBJECT; libfwbuilder::FWObject *obj; bool init; QString color; void fillColor(); void changeIds(libfwbuilder::FWObject *root); public: Ui::LibraryDialog_q *m_dialog; LibraryDialog(QWidget *parent); ~LibraryDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void changeColor(); }; #endif // LIBRARYDIALOG_H fwbuilder-5.1.0.3599/src/libgui/CommentEditorPanel.h0000644000175000017500000000303511733011756022743 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMMENTEDITORPANEL_H__ #define __COMMENTEDITORPANEL_H__ #include "config.h" #include "BaseObjectDialog.h" #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" class CommentEditorPanel : public BaseObjectDialog { Q_OBJECT; Ui::CommentEditorPanel_q *m_widget; public: CommentEditorPanel(QWidget *p); ~CommentEditorPanel(); libfwbuilder::Rule *rule; QString text(); void setText(QString s); public slots: virtual void changed(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif fwbuilder-5.1.0.3599/src/libgui/CommentKeywords.cpp0000644000175000017500000000525411733011756022704 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "CommentKeywords.h" #include "utils.h" #include "fwbuilder/FWObject.h" #include "KeywordsDialog.h" using namespace std; using namespace libfwbuilder; CommentKeywords::CommentKeywords(QWidget *parent) : QWidget(parent) { m_ui.setupUi(this); } void CommentKeywords::applyChanges(FWObject *newObj) { newObj->setComment(m_ui.comment->getText().toUtf8().constData()); newObj->clearKeywords(); foreach (QString keyword, m_keywords) { newObj->addKeyword(keyword.toUtf8().constData()); } } void CommentKeywords::loadFWObject(FWObject *obj) { m_obj = obj; m_keywords.clear(); set keywords = obj->getKeywords(); set::const_iterator iter; for (iter = keywords.begin(); iter != keywords.end(); ++iter) { m_keywords.append(QString::fromUtf8((*iter).c_str())); } QString comment = QString::fromUtf8(obj->getComment().c_str()); m_ui.comment->setTextDefault(comment, "Enter comment here"); updateKeywordsLabel(); m_ui.comment->setReadOnly(obj->isReadOnly()); setDisabledPalette(m_ui.comment); m_ui.keywordsButton->setEnabled(!obj->isReadOnly()); } void CommentKeywords::setReadOnlyComment(const QString &comment) { m_ui.comment->setText(comment); m_ui.comment->setReadOnly(true); m_ui.keywordsButton->setEnabled(false); } void CommentKeywords::keywordsClicked() { KeywordsDialog dialog(m_obj); if (dialog.exec() == QDialog::Accepted) { m_keywords = dialog.getKeywords(); emit changed(); } updateKeywordsLabel(); } void CommentKeywords::updateKeywordsLabel() { QString result; m_keywords = sortStrings(m_keywords); foreach (QString keyword, m_keywords) { if (!result.isEmpty()) result += ", "; result += keyword; } if (result.isEmpty()) result = "No keywords"; m_ui.keywordsLabel->setText(result); } fwbuilder-5.1.0.3599/src/libgui/secuwallifaceoptsdialog_q.ui0000644000175000017500000002720011733011756024615 0ustar sylvestresylvestre secuwallIfaceOptsDialog_q 0 0 347 438 secunet wall: interface settings Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 Options :/Icons/Options:/Icons/Options Qt::Vertical QSizePolicy::Fixed 20 16 Specify secunet wall advanced interface options below Qt::AlignCenter true Qt::Vertical QSizePolicy::Fixed 20 16 Qt::RightToLeft MTU 1 1500 1500 Qt::RightToLeft Options Qt::RightToLeft Device Type Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Minimum 20 20 Qt::Horizontal 40 20 0 0 0 true Qt::RightToLeft VLAN ID 4095 Qt::Horizontal 140 20 Qt::Horizontal 141 20 Qt::Horizontal 40 20 Qt::Horizontal 40 20 Disable at boot Disable ARP on this interface Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() secuwallIfaceOptsDialog_q accept() 316 472 20 20 buttonCancel clicked() secuwallIfaceOptsDialog_q reject() 397 472 20 20 buttonHelp clicked() secuwallIfaceOptsDialog_q help() 68 464 231 245 iface_type currentIndexChanged(QString) secuwallIfaceOptsDialog_q typeChanged(QString) 287 196 286 261 fwbuilder-5.1.0.3599/src/libgui/QThreadLogger.h0000644000175000017500000000276211733011756021710 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _QTHREAD_LOGGER_H_ #define _QTHREAD_LOGGER_H_ #include "fwbuilder/Logger.h" #include class QThreadLogger : public QObject, public libfwbuilder::Logger { Q_OBJECT; public: QThreadLogger(); virtual Logger& operator<< (char c) ; virtual Logger& operator<< (char *str) ; virtual Logger& operator<< (const char *str) ; virtual Logger& operator<< (const std::string &str) ; virtual Logger& operator<< (int i ) ; virtual Logger& operator<< (long l ) ; virtual Logger& operator<< (std::ostringstream &sstr); signals: void lineReady(const QString &txt); }; #endif fwbuilder-5.1.0.3599/src/libgui/UsageResolver.h0000644000175000017500000000427311733011756022005 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland Refactoring: Roman Bovsunivskiy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef USAGERESOLVER_H #define USAGERESOLVER_H #include "global.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include #include class UsageResolver { int search_id; static int search_id_seed; public: UsageResolver(); void findWhereUsedRecursively( libfwbuilder::FWObject *, libfwbuilder::FWObject *, std::set &, libfwbuilder::FWObjectDatabase*); std::list findFirewallsForObject( libfwbuilder::FWObject*, libfwbuilder::FWObjectDatabase*); void findAllReferenceHolders( libfwbuilder::FWObject *obj, libfwbuilder::FWObject *root, std::map > &res); /** * Post-process set of FWObject* returned by * FWObjectDatabase::findWhereObjectIsUsed to make it more * suitable for the user. Since findWhereObjectIsUsed returns * actual reference objects that point at the object we search * for, humanizeSearchResults replaces them with appropriate * parent objects. These can be either groups that hold * references, or rules, which are two levels up. */ void humanizeSearchResults(std::set&); }; #endif // USAGERESOLVER_H fwbuilder-5.1.0.3599/src/libgui/FWWIndow_single_rule_compile.cpp0000644000175000017500000000366611733011756025323 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com refactoring and bugfixes: vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "events.h" #include #include "FWWindow.h" #include "fwbuilder/Rule.h" using namespace Ui; using namespace libfwbuilder; using namespace std; void FWWindow::singleRuleCompile(Rule *rule) { if (activeProject()) { attachEditorToProjectPanel(activeProject()); QString title_txt; QPixmap title_icon; buildEditorTitleAndIcon( rule, ObjectEditor::optNone, &title_txt, &title_icon, m_mainWindow->m_space->subWindowList(QMdiArea::StackingOrder).size() > 1); m_mainWindow->editorDockWidget->setWindowTitle(title_txt); m_mainWindow->output_box->show(); m_mainWindow->editorPanelTabWidget->setCurrentIndex( EDITOR_PANEL_OUTPUT_TAB); m_mainWindow->editorDockWidget->show(); m_mainWindow->output_box->loadFWObject(rule); QCoreApplication::postEvent( activeProject(), new makeCurrentRuleVisibleInRulesetEvent(activeProject()->getFileName())); } } fwbuilder-5.1.0.3599/src/libgui/secuwallIfaceOptsDialog.h0000644000175000017500000000233211733011756023746 0ustar sylvestresylvestre/* * secuwallIfaceOptsDialog.h - Interface options dialog for secunet wall * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __SECUWALLIFACEOPTSDIALOG_H_ #define __SECUWALLIFACEOPTSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class secuwallIfaceOptsDialog : public QDialog { Q_OBJECT public: secuwallIfaceOptsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~secuwallIfaceOptsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::secuwallIfaceOptsDialog_q *m_dialog; bool cluster_interface; protected slots: virtual void accept(); virtual void reject(); virtual void help(); void typeChanged(const QString&); }; #endif // __SECUWALLIFACEOPTSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/WorkflowIcons.h0000644000175000017500000000254411733011756022024 0ustar sylvestresylvestre /* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: WorkflowIcons.h 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef WORKFLOWICONS_H #define WORKFLOWICONS_H #include namespace Ui { class WorkflowIcons_q; } class WorkflowIcons : public QWidget { Q_OBJECT public: WorkflowIcons(QWidget *parent = 0); void setUpSignals(QWidget *panel); ~WorkflowIcons(); protected: void changeEvent(QEvent *e); private: Ui::WorkflowIcons_q *ui; public slots: void libraryAccessChanged(bool writable); void openTutorial(); }; #endif // WORKFLOWICONS_H fwbuilder-5.1.0.3599/src/libgui/librarydialog_q.ui0000644000175000017500000001112011733011756022536 0ustar sylvestresylvestre LibraryDialog_q true 0 0 726 237 Library QFrame::Box QFrame::Sunken 350 0 350 16777215 QFrame::Box QFrame::Sunken 12 Name: false 200 0 0 0 Color: false 0 0 Qt::Vertical QSizePolicy::Expanding 185 121 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name colorButton colorButton clicked() LibraryDialog_q changeColor() 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/vlanOnlyIfaceOptsDialog.cpp0000644000175000017500000001143511733011756024270 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "vlanOnlyIfaceOptsDialog.h" #include "platforms.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "FWWindow.h" #include "Help.h" #include #include using namespace std; using namespace libfwbuilder; vlanOnlyIfaceOptsDialog::vlanOnlyIfaceOptsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::vlanOnlyIfaceOptsDialog_q; m_dialog->setupUi(this); setWindowModality(Qt::WindowModal); obj = o; FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject(); cluster_interface = (Cluster::cast(obj->getParent()) != NULL); setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj), ifopt->getStr("type").c_str()); // Using "type" control only for subinterfaces // and main interfaces of the firewall objects if (cluster_interface) { m_dialog->iface_type->hide(); m_dialog->iface_type_label->hide(); } else { m_dialog->iface_type->show(); m_dialog->iface_type_label->show(); } m_dialog->vlan_id->setValue(ifopt->getInt("vlan_id")); // special actions for different iface types // VLAN (8021q) typeChanged(""); } vlanOnlyIfaceOptsDialog::~vlanOnlyIfaceOptsDialog() { delete m_dialog; } /* * store all data in the object */ void vlanOnlyIfaceOptsDialog::accept() { // validate user input before saving if (!validate()) return; ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the interface object FWObject* new_state = cmd->getNewState(); FWOptions* ifopt = Interface::cast(new_state)->getOptionsObject(); assert(ifopt!=NULL); if (cluster_interface) { ifopt->setStr("type", "cluster_interface"); } else { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); ifopt->setStr("type", new_type.toStdString()); } ifopt->setInt("vlan_id", m_dialog->vlan_id->value()); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void vlanOnlyIfaceOptsDialog::reject() { QDialog::reject(); } void vlanOnlyIfaceOptsDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Interface Properties"); h->setSource(QUrl("vlanOnlyIfaceOptsDialog.html#" + anchor)); h->raise(); h->show(); } void vlanOnlyIfaceOptsDialog::typeChanged(const QString&) { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); // enable VLAN ID line edit for type VLAN bool enable_vlan = (new_type == "8021q"); m_dialog->vlan_id->setEnabled(enable_vlan); m_dialog->vlan_label->setEnabled(enable_vlan); } bool vlanOnlyIfaceOptsDialog::validate() { bool valid = true; QString combobox = m_dialog->iface_type->currentText(); QString type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); QWidget *focus = NULL; QString message; if (type == "vrrp") { // Both vvrp_secret and vrrp_id attributes moved to vrrpOptionsDialog ; } if (type == "8021q") { // VLAN ID must be set between 1 <= vid <= 4'094 // QSpinBox widget enforces these limits ; } if (!valid) { QMessageBox::warning(this, "Firewall Builder", tr("Input not valid: %1").arg(message), "&Continue", QString::null, QString::null, 0, 1); focus->setFocus(); } return valid; } fwbuilder-5.1.0.3599/src/libgui/bsdIfaceOptsDialog.h0000644000175000017500000000311611733011756022700 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BSDIFACEOPTSDIALOG_H_ #define __BSDIFACEOPTSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class bsdIfaceOptsDialog : public QDialog { Q_OBJECT; public: bsdIfaceOptsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~bsdIfaceOptsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::bsdIfaceOptsDialog_q *m_dialog; bool cluster_interface; /** validate user input for different interface types */ bool validate(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); void typeChanged(const QString &new_type); }; #endif // __BSDIFACEOPTSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/ClusterInterfacesSelectorWidget.h0000644000175000017500000000371711733011756025513 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CLUSTERINTERFACESSELECTORWIDGET_H #define CLUSTERINTERFACESSELECTORWIDGET_H #include #include #include #include #include class ClusterInterfaceWidget; #include "ClusterInterfaceWidget.h" struct ClusterInterfaceData { QString os; QString name; QString label; QString comment; QList > interfaces; }; class ClusterInterfacesSelectorWidget : public QTabWidget { Q_OBJECT public: ClusterInterfacesSelectorWidget(QWidget *parent = 0); ~ClusterInterfacesSelectorWidget(); void setFirewallList(QList); QList getInterfaces(); bool isValid(); private: QList editors; QList fwlist; QToolButton newInterface; QToolButton delInterface; bool noTabs; public slots: ClusterInterfaceWidget* addNewInterface(); void addInterface(const QString& name); void closeTab(); void clear(); }; #endif // CLUSTERINTERFACESSELECTORWIDGET_H fwbuilder-5.1.0.3599/src/libgui/filterdialog_q.ui0000644000175000017500000002013111733011756022361 0ustar sylvestresylvestre FilterDialog_q 0 0 527 407 Filter 11 6 0 6 Save Load Qt::Horizontal QSizePolicy::Expanding 96 20 Ok true Cancel Match false all any of the following: false Qt::Horizontal QSizePolicy::Expanding 51 20 0 6 48 32767 Add a new pattern + 0 6 2 Target Type Pattern Case sensitive Qt::Vertical QSizePolicy::Expanding 20 140 48 32767 Remove a pattern - combo table addButton remButton case_sensitive saveButton loadButton okButton cancelButton okButton clicked() FilterDialog_q apply() 20 20 20 20 cancelButton clicked() FilterDialog_q reject() 20 20 20 20 loadButton clicked() FilterDialog_q load() 20 20 20 20 saveButton clicked() FilterDialog_q save() 20 20 20 20 addButton clicked() FilterDialog_q addPattern() 20 20 20 20 remButton clicked() FilterDialog_q removePattern() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/longtextdialog_q.ui0000644000175000017500000000707711733011756022756 0ustar sylvestresylvestre longTextDialog_q 0 0 368 291 longTextDialog_q 11 Continue Qt::Horizontal QSizePolicy::Expanding 100 20 Qt::Horizontal QSizePolicy::Expanding 120 20 0 0 QFrame::NoFrame QFrame::Raised 11 :/Icons/warning.png true false 0 0 this is the error text true false dlgLongText closeBtn closeBtn clicked() longTextDialog_q accept() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/RuleNode.h0000644000175000017500000000330011733011756020722 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef RULENODE_H #define RULENODE_H #include #include #define MAX_COLUMNS 20 namespace libfwbuilder { class Rule; } class RuleNode : public QObject { public: enum Type { Root, Group, Rule }; RuleNode(Type type, const QString &str = ""); ~RuleNode(); Type type; QString name; //TODO This field is unused in real application RuleNode *parent; QList children; libfwbuilder::Rule* rule; QSize sizes[MAX_COLUMNS]; void prepend(RuleNode * node); void add(RuleNode* ); void insert(int pos, RuleNode* node); bool isInGroup(); bool isRoot(); bool isOutermost(); QString groupName(); QString nameOfSuccessorGroup(); QString nameOfPredecessorGroup(); void resetSizes(); void resetAllSizes(); bool operator==(const RuleNode &rn) const; }; #endif // RULENODE_H fwbuilder-5.1.0.3599/src/libgui/MainRes.qrc0000644000175000017500000006064711733011756021122 0ustar sylvestresylvestre Icons/back_25.png Icons/forward_25.png Images/fwbuilder3-256x256-fade.png Images/fwbuilder3-256x256.png Images/fwbuilder3-72x72.png Images/network_zone_dialog.png Images/logo1.png Images/library_switch_screenshot.png Icons/import_64_1.png Icons/inspect.png Icons/tutorial_64.png Icons/tutorial_64_1.png Icons/accept_25.png Icons/accept_64.png Icons/accept_16.png Icons/accounting_25.png Icons/accounting_64.png Icons/accounting_16.png Icons/rangeaddress_25.png Icons/rangeaddress_64.png Icons/rangeaddress-neg_25.png Icons/rangeaddress-neg_16.png Icons/rangeaddress-ref_25.png Icons/rangeaddress_16.png Icons/addresstable_25.png Icons/addresstable_64.png Icons/addresstable-neg_25.png Icons/addresstable-neg_16.png Icons/addresstable-ref_25.png Icons/addresstable_16.png Icons/network_25.png Icons/network_64.png Icons/network-neg_25.png Icons/network-neg_16.png Icons/network-ref_25.png Icons/network_16.png Icons/blank.png Icons/blank.png Icons/both_25.png Icons/both_64.png Icons/both_16.png Icons/branch_25.png Icons/branch_64.png Icons/branch_16.png Icons/classify_25.png Icons/classify_64.png Icons/classify_16.png Icons/cluster_25.png Icons/cluster_64.png Icons/cluster-neg_25.png Icons/cluster-neg_16.png Icons/cluster-ref_25.png Icons/cluster_16.png Icons/user_25.png Icons/user_64.png Icons/user-neg_25.png Icons/user-ref_25.png Icons/user_16.png Icons/compile_25.png Icons/continue_25.png Icons/continue_64.png Icons/continue_16.png Icons/custom_25.png Icons/custom_64.png Icons/custom_16.png Icons/service-custom_25.png Icons/service-custom_64.png Icons/service-custom-neg_25.png Icons/service-custom-neg_16.png Icons/service-custom-ref_25.png Icons/service-custom_16.png Icons/domainname_25.png Icons/domainname_64.png Icons/domainname-neg_25.png Icons/domainname-neg_16.png Icons/domainname-ref_25.png Icons/domainname_16.png Icons/deny_25.png Icons/deny_64.png Icons/deny_16.png Icons/failover-cluster-group_25.png Icons/failover-cluster-group_64.png Icons/failover-cluster-group-neg_25.png Icons/failover-cluster-group-neg_16.png Icons/failover-cluster-group-ref_25.png Icons/failover-cluster-group_16.png Icons/firewall_25.png Icons/firewall_64.png Icons/firewall-neg_25.png Icons/firewall-neg_16.png Icons/firewall-ref_25.png Icons/firewall_16.png Icons/host_25.png Icons/host_64.png Icons/host-neg_25.png Icons/host-neg_16.png Icons/host-ref_25.png Icons/host_16.png Icons/service-icmp6_25.png Icons/service-icmp6_64.png Icons/service-icmp6-neg_25.png Icons/service-icmp6-neg_16.png Icons/service-icmp6-ref_25.png Icons/service-icmp6_16.png Icons/service-icmp_25.png Icons/service-icmp_64.png Icons/service-icmp-neg_25.png Icons/service-icmp-neg_16.png Icons/service-icmp-ref_25.png Icons/service-icmp_16.png Icons/service-ip_25.png Icons/service-ip_64.png Icons/service-ip-neg_25.png Icons/service-ip-neg_16.png Icons/service-ip-ref_25.png Icons/service-ip_16.png Icons/address_25.png Icons/address_64.png Icons/address-neg_25.png Icons/address-neg_16.png Icons/address-ref_25.png Icons/address_16.png Icons/address6_25.png Icons/address6_64.png Icons/address6-neg_25.png Icons/address6-neg_16.png Icons/address6-ref_25.png Icons/address6_16.png Icons/inbound_25.png Icons/inbound_64.png Icons/inbound_16.png Icons/install_25.png Icons/interface_25.png Icons/interface_64.png Icons/interface-neg_25.png Icons/interface-neg_16.png Icons/interface-ref_25.png Icons/interface_16.png Icons/clock_25.png Icons/clock_64.png Icons/clock-neg_25.png Icons/clock-neg_16.png Icons/clock-ref_25.png Icons/clock_16.png Icons/clock-group_25.png Icons/clock-group_64.png Icons/clock-group-neg_25.png Icons/clock-group-neg_16.png Icons/clock-group-ref_25.png Icons/clock-group_16.png Icons/library_25.png Icons/library_64.png Icons/library-neg_25.png Icons/library-neg_16.png Icons/library-ref_25.png Icons/library_16.png Icons/log_25.png Icons/log_64.png Icons/log_16.png Icons/nat_25.png Icons/nat_64.png Icons/nat_16.png Icons/branch_25.png Icons/branch_64.png Icons/branch_16.png Icons/network_25.png Icons/network_64.png Icons/network-neg_25.png Icons/network-neg_16.png Icons/network-ref_25.png Icons/network_16.png Icons/network6_25.png Icons/network6_64.png Icons/network6-neg_25.png Icons/network6-neg_16.png Icons/network6-ref_25.png Icons/network6_16.png Icons/object-group_25.png Icons/object-group_64.png Icons/object-group-neg_25.png Icons/object-group-neg_16.png Icons/object-group-ref_25.png Icons/object-group_16.png Icons/dynamic-group_25.png Icons/dynamic-group_64.png Icons/dynamic-group-neg_25.png Icons/dynamic-group-neg_16.png Icons/dynamic-group-ref_25.png Icons/dynamic-group_16.png Icons/options_25.png Icons/options_64.png Icons/options_16.png Icons/outbound_25.png Icons/outbound_64.png Icons/outbound_16.png Icons/pipe_25.png Icons/pipe_64.png Icons/pipe_16.png Icons/ruleset_25.png Icons/ruleset_64.png Icons/ruleset_16.png Icons/reject_25.png Icons/reject_64.png Icons/reject_16.png Icons/back_25.png Icons/route_25.png Icons/route_64.png Icons/route_16.png Icons/routing_25.png Icons/routing_64.png Icons/routing_16.png Icons/service-group_25.png Icons/service-group_64.png Icons/service-group-neg_25.png Icons/service-group-neg_16.png Icons/service-group-ref_25.png Icons/service-group_16.png Icons/state-sync-cluster-group_25.png Icons/state-sync-cluster-group_64.png Icons/state-sync-cluster-group-neg_25.png Icons/state-sync-cluster-group-neg_16.png Icons/state-sync-cluster-group-ref_25.png Icons/state-sync-cluster-group_16.png Icons/folder_25.png Icons/folder_64.png Icons/folder_16.png Icons/service-tcp_25.png Icons/service-tcp_64.png Icons/service-tcp-neg_25.png Icons/service-tcp-neg_16.png Icons/service-tcp-ref_25.png Icons/service-tcp_16.png Icons/tag_25.png Icons/tag_64.png Icons/tag_16.png Icons/service-tag_25.png Icons/service-tag_64.png Icons/service-tag-neg_25.png Icons/service-tag-neg_16.png Icons/service-tag-ref_25.png Icons/service-tag_16.png Icons/translate_25.png Icons/translate_16.png Icons/service-udp_25.png Icons/service-udp_64.png Icons/service-udp-neg_25.png Icons/service-udp-neg_16.png Icons/service-udp-ref_25.png Icons/service-udp_16.png Icons/user_25.png Icons/user_64.png Icons/user-neg_25.png Icons/user-neg_16.png Icons/user-ref_25.png Icons/user_16.png Icons/lock.png Icons/neg.png Icons/neg2.png Icons/physaddress_25.png Icons/physaddress_64.png Icons/physaddress-neg_25.png Icons/physaddress-ref_25.png Icons/physaddress_16.png Icons/add.png Icons/apply.png Icons/back_32.png Icons/big-down-arrow.png Icons/big-left-arrow.png Icons/big-right-arrow.png Icons/big-up-arrow.png Icons/blank_2x16.png Icons/books1.png Icons/cancel.png Icons/close.png Icons/del.png Icons/down-arrow.png Icons/drag_object.png Icons/error.png Icons/firewall_64.png Icons/firewall_64.xpm Icons/floppy.png Icons/folder1.png Icons/generic.png Icons/host_64.png Icons/host_64.xpm Icons/info_16.png Icons/info_25.png Icons/key.png Icons/left-arrow.png Icons/newfile_25.png Icons/newobject_25.png Icons/newobject_32.png Icons/no.png Icons/ok.png Icons/openfile_25.png Icons/protect_host.png Icons/protect_net.png Icons/protect_net_and_dmz.png Icons/question.png Icons/redo.png Icons/ref.png Icons/right-arrow.png Icons/rules_druid_logo.png Icons/save_25.png Icons/search_25.png Icons/stop.png Icons/uncheck.png Icons/undo.png Icons/up-arrow.png Icons/warning.png Icons/yes.png Images/fwbuilder3-128x128.png Images/fwbuilder3.png Tutorial/getting_started/html/page0.html Tutorial/getting_started/html/page1.html Tutorial/getting_started/html/page2.html Tutorial/getting_started/html/page3.html Tutorial/getting_started/html/page4.html Tutorial/getting_started/html/page5.html Tutorial/getting_started/html/page6.html Tutorial/getting_started/html/page7.html Tutorial/getting_started/html/page8.html Tutorial/getting_started/html/page9.html Tutorial/getting_started/html/page10.html Tutorial/getting_started/html/page11.html Tutorial/getting_started/html/page12.html Tutorial/getting_started/html/page13.html Tutorial/getting_started/html/page14.html Tutorial/getting_started/html/page15.html Tutorial/getting_started/html/page16.html Tutorial/getting_started/html/page17.html Tutorial/getting_started/html/page18.html Tutorial/getting_started/html/page19.html Tutorial/getting_started/html/page20.html Tutorial/getting_started/html/page21.html Tutorial/getting_started/html/page22.html Tutorial/getting_started/html/page23.html Tutorial/getting_started/html/page24.html Tutorial/getting_started/html/page25.html Tutorial/getting_started/html/page26.html Tutorial/getting_started/html/page27.html Tutorial/getting_started/html/page28.html Tutorial/getting_started/html/page29.html Tutorial/getting_started/html/page30.html Tutorial/getting_started/html/page31.html Tutorial/getting_started/html/page32.html Tutorial/getting_started/images/0.png Tutorial/getting_started/images/1.png Tutorial/getting_started/images/2.png Tutorial/getting_started/images/3.png Tutorial/getting_started/images/4.png Tutorial/getting_started/images/5.png Tutorial/getting_started/images/6.png Tutorial/getting_started/images/7.png Tutorial/getting_started/images/8.png Tutorial/getting_started/images/9-1.png Tutorial/getting_started/images/9-2.png Tutorial/getting_started/images/10.png Tutorial/getting_started/images/11.png Tutorial/getting_started/images/12.png Tutorial/getting_started/images/13.png Tutorial/getting_started/images/14.png Tutorial/getting_started/images/15.png Tutorial/getting_started/images/16.png Tutorial/getting_started/images/17.png Tutorial/getting_started/images/18.png Tutorial/getting_started/images/19.png Tutorial/getting_started/images/20.png Tutorial/getting_started/images/21.png Tutorial/getting_started/images/22.png Tutorial/getting_started/images/23.png Tutorial/getting_started/images/24.png Tutorial/getting_started/images/25.png Tutorial/getting_started/images/26.png Tutorial/getting_started/images/27.png Tutorial/getting_started/images/28.png Tutorial/getting_started/images/29.png Tutorial/getting_started/images/30.png Tutorial/getting_started/images/32.png Tutorial/getting_started/images/new_button.png Tutorial/getting_started/stylesheets/style.css fwbuilder-5.1.0.3599/src/libgui/pixosadvanceddialog_q.ui0000644000175000017500000004135011733011756023732 0ustar sylvestresylvestre pixosAdvancedDialog_q Qt::WindowModal true 0 0 539 402 PIX Advanced Configuration Options 11 6 0 General 6 6 Set PIX host name using object's name Generate commands to configure addresses for interfaces Qt::Vertical QSizePolicy::Expanding 20 40 NTP NTP cannot be configured on FWSM, because it takes its settings from the Switch. Qt::AlignCenter true NTP Servers: 6 6 Server 1: Qt::AlignCenter false Server 2: Qt::AlignCenter false Server 3: Qt::AlignCenter false Preffered: Qt::AlignCenter false IP address: Qt::AlignCenter false Qt::Vertical QSizePolicy::Expanding 20 30 SNMP 6 6 Disable SNMP Agent Set SNMP communities using data from the firewall object dialog Qt::Vertical QSizePolicy::Expanding 20 40 SNMP servers 6 6 Poll Poll and Traps Traps Poll Poll and Traps Traps Enable: Qt::AlignCenter false 0 0 IP address: Qt::AlignCenter false SNMP Server 1: Qt::AlignCenter false SNMP Server 2: Qt::AlignCenter false Enable sending log messages as SNMP trap notifications Options 6 6 Change TCP MSS to Qt::Vertical QSizePolicy::Expanding 20 162 0 4096 10 1380 bytes Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 20 20 6 0 Qt::Horizontal QSizePolicy::Expanding 20 20 OK Qt::AlignCenter false Cancel tabWidget pix_set_host_name pix_ip_address ntp1 ntp1_pref ntp2 ntp2_pref ntp3 ntp3_pref disable_snmp_agent set_communities enable_traps snmp_server1 snmp_poll_traps_1 snmp_server2 snmp_poll_traps_2 tcpmss tcpmss_value ok_button cancel_button ok_button clicked() pixosAdvancedDialog_q accept() 20 20 20 20 cancel_button clicked() pixosAdvancedDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/ColDesc.h0000755000175000017500000000253011733011756020530 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef COLDESC_H #define COLDESC_H #include #include class ColDesc { public: enum ColumnType { GroupHandle, RuleOp, Object, Action, Direction, Options, Time, Comment, Metric, Unknown }; ColDesc(const std::string &platform, const std::string &origin, ColumnType type); ColDesc(); QString name; QString origin; ColumnType type; }; Q_DECLARE_METATYPE(ColDesc) #endif // COLDESC_H fwbuilder-5.1.0.3599/src/libgui/FirewallDialog.cpp0000644000175000017500000003200111733011756022425 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "ProjectPanel.h" #include "FWBTree.h" #include "FirewallDialog.h" #include "DialogFactory.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; FirewallDialog::~FirewallDialog() { delete m_dialog; } FirewallDialog::FirewallDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::FirewallDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } void FirewallDialog::loadFWObject(FWObject *o) { try { obj = o; Firewall *s = dynamic_cast(obj); assert(s!=NULL); init = true; QString platform = obj->getStr("platform").c_str(); /* fill in platform */ setPlatform(m_dialog->platform, platform); fillVersion(); /* fill in host OS */ setHostOS(m_dialog->hostOS, platform, obj->getStr("host_OS").c_str()); /* ---------------- */ updateTimeStamps(); Management *mgmt=s->getManagementObject(); assert(mgmt!=NULL); // FWOptions *opt =s->getOptionsObject(); m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->inactive->setChecked(s->getInactive()); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->platform->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->platform); m_dialog->version->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->version); m_dialog->hostOS->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->hostOS); m_dialog->fwAdvanced->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->fwAdvanced); m_dialog->osAdvanced->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->osAdvanced); // snmpCommunity->setEnabled(!o->isReadOnly()); // setDisabledPalette(snmpCommunity); m_dialog->inactive->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->inactive); } catch (FWException &ex) { qDebug() << "Caught FWException:" << ex.toString().c_str(); } init=false; } void FirewallDialog::updateTimeStamps() { QDateTime dt; time_t t; t = obj->getInt("lastModified"); dt.setTime_t(t); m_dialog->last_modified->setText((t)? dt.toString():"-"); t = obj->getInt("lastCompiled"); dt.setTime_t(t); m_dialog->last_compiled->setText((t)? dt.toString():"-"); t = obj->getInt("lastInstalled"); dt.setTime_t(t); m_dialog->last_installed->setText((t)? dt.toString():"-"); } /* fill in version */ void FirewallDialog::fillVersion() { m_dialog->version->clear(); list vl; getVersionsForPlatform(readPlatform(m_dialog->platform), vl); QString v = obj->getStr("version").c_str(); bool found_version = false; int cp = 0; for (list::iterator i1=vl.begin(); i1!=vl.end(); i1++,cp++) { if (fwbdebug) qDebug() << "Adding version " << i1->second; m_dialog->version->addItem( i1->second ); if ( v == i1->first ) { found_version = true; m_dialog->version->setCurrentIndex( cp ); } } if (!found_version && !obj->isReadOnly()) { // version configured in the object does not match any valid // version for this platform. obj->setStr("version", vl.front().first.toStdString()); fillVersion(); } } void FirewallDialog::saveVersion(FWObject *o) { QString pl = readPlatform(m_dialog->platform); list vl; getVersionsForPlatform( pl.toLatin1().constData(), vl); QString v = m_dialog->version->currentText(); list::iterator li = std::find_if(vl.begin(),vl.end(),findSecondInQStringPair(v)); if (li!=vl.end()) o->setStr("version", li->first.toLatin1().constData() ); } void FirewallDialog::platformChanged() { if (fwbdebug) qDebug() << "FirewallDialog::platformChanged()"; fillVersion(); QString platform = readPlatform(m_dialog->platform); setHostOS( m_dialog->hostOS, platform, ""); QString pl = readPlatform(m_dialog->platform); m_dialog->fwAdvanced->setEnabled( pl!="unknown" ); //changed(); } void FirewallDialog::hostOSChanged() { if (fwbdebug) qDebug() << "FirewallDialog::hostOSChanged()"; QString ho = readHostOS(m_dialog->hostOS); m_dialog->osAdvanced->setEnabled( ho!="unknown_os" ); //changed(); } void FirewallDialog::validate(bool *res) { *res = true; if (!validateName(this, obj, m_dialog->obj_name->text())) { *res = false; return; } // see #2011 - do not allow "/" in firewall object name if (m_dialog->obj_name->text().contains("/")) { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this,"Firewall Builder", tr("Character \"/\" is not allowed in firewall object name"), tr("&Continue"), QString::null,QString::null, 0, 1 ); blockSignals(false); } return; } } void FirewallDialog::applyChanges() { if (fwbdebug) qDebug() << "FirewallDialog::applyChanges()"; bool autorename_chidren = false; QString dialog_txt = tr( "The name of the object '%1' has changed. The program can also " "rename IP address objects that belong to this object, " "using standard naming scheme 'host_name:interface_name:ip'. " "This makes it easier to distinguish what host or a firewall " "given IP address object belongs to when it is used in " "the policy or NAT rule. The program also renames MAC address " "objects using scheme 'host_name:interface_name:mac'. " "Do you want to rename child IP and MAC address objects now? " "(If you click 'No', names of all address objects that belong to " "%2 will stay the same.)") .arg(QString::fromUtf8(obj->getName().c_str())) .arg(QString::fromUtf8(obj->getName().c_str())); if (obj->getName() != m_dialog->obj_name->text().toUtf8().constData()) { /* * when we open this warning dialog, FirewallDialog class * loses focus and obj_name lineEdit widget sends signal * "editingfinished" again. To the user this looks like the * warning dialog popped up twice (in fact two copies of the * same warning dialog appear at the same time, one exactly on * top of another). To avoid this, block signals for the * duration while we show the dialog. Note that documentation * does not mention that QObject::blockSignals() affects not * only the widget but all its children, but it seems to work * that way. Tested with Qt 4.6.1. See #1171 */ blockSignals(true); autorename_chidren = (QMessageBox::warning( this,"Firewall Builder", dialog_txt, tr("&Yes"), tr("&No"), QString::null, 0, 1 )==0 ); blockSignals(false); } if (fwbdebug) qDebug() << "Sending FWCmdChange autorename_chidren=" << autorename_chidren; std::auto_ptr cmd( new FWCmdChange(m_project, obj, "", autorename_chidren)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); Firewall *s = dynamic_cast(new_state); Management *mgmt = s->getManagementObject(); assert(mgmt!=NULL); string old_name = obj->getName(); string new_name = string(m_dialog->obj_name->text().toUtf8().constData()); string old_platform = obj->getStr("platform"); string old_host_os = obj->getStr("host_OS"); string old_version = obj->getStr("version"); new_state->setName(new_name); m_dialog->commentKeywords->applyChanges(new_state); s->setInactive(m_dialog->inactive->isChecked()); saveVersion(new_state); string new_version = new_state->getStr("version"); string new_platform = readPlatform(m_dialog->platform).toLatin1().constData(); if (new_platform.empty()) new_platform = "unknown"; new_state->setStr("platform", new_platform ); if (old_platform!=new_platform) { if (fwbdebug) qDebug() << "FirewallDialog::applyChanges() platform has changed" << old_platform.c_str() << "->" << new_platform.c_str() << "clearing option 'compiler'"; platformChanged(); FWOptions *opt =s->getOptionsObject(); opt->setStr("compiler", ""); // Set default options for the new platform Resources::setDefaultTargetOptions(new_platform, s); } string new_host_os = readHostOS(m_dialog->hostOS).toLatin1().constData(); if (new_host_os.empty()) new_host_os = "unknown_os"; new_state->setStr("host_OS", new_host_os); if (old_host_os!=new_host_os) { if (fwbdebug) qDebug() << "FirewallDialog::applyChanges() host_OS has changed" << old_host_os.c_str() << "->" << new_host_os.c_str(); hostOSChanged(); // Set default options for the new host os Resources::setDefaultTargetOptions(new_host_os, s); } if (new_platform.empty()) { QMessageBox::critical( this, "Firewall Builder", tr("Platform setting can not be empty"), tr("&Continue"), 0, 0, 0 ); return; } if (new_host_os.empty()) { QMessageBox::critical( this, "Firewall Builder", tr("Host OS setting can not be empty"), tr("&Continue"), 0, 0, 0 ); return; } if (old_platform!=new_platform || old_host_os!=new_host_os || old_name!=new_name || old_version!=new_version) { if (fwbdebug) qDebug("FirewallDialog::applyChanges() scheduling call " "to reopenFirewall()"); m_project->registerRuleSetRedrawRequest(); } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } updateTimeStamps(); } void FirewallDialog::openFWDialog() { try { QWidget *w = DialogFactory::createFWDialog(mw, obj); if (w==NULL) return; // some dialogs may not be implemented yet QDialog *d=dynamic_cast(w); assert(d!=NULL); d->setWindowModality(Qt::WindowModal); // d->open(); d->exec(); delete d; } catch (FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("FWBuilder API error: %1").arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); return; } } void FirewallDialog::openOSDialog() { try { QWidget *w = DialogFactory::createOSDialog(mw, obj); if (w==NULL) return; // some dialogs may not be implemented yet QDialog *d=dynamic_cast(w); assert(d!=NULL); d->exec(); delete d; } catch (FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("FWBuilder API error: %1").arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); return; } } fwbuilder-5.1.0.3599/src/libgui/newHostDialog.h0000644000175000017500000000560311733011756021764 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NEWHOSTDIALOG_H_ #define __NEWHOSTDIALOG_H_ #include "config.h" #include #include "fwbuilder/InterfaceData.h" #include "fakeWizard.h" #include #include namespace libfwbuilder { class FWObject; class Host; class Interface; class Logger; class SNMP_interface_query; }; class QTimer; class QTextEdit; class QTreeWidgetItem; class QListWidgetItem; class newHostDialog : public QDialog, public FakeWizard { Q_OBJECT libfwbuilder::Host *nhst; bool snmpPollCompleted; libfwbuilder::Logger *logger; libfwbuilder::SNMP_interface_query *q; QTimer *timer; libfwbuilder::FWObjectDatabase *db; libfwbuilder::FWObjectDatabase *tmpldb; libfwbuilder::FWObject *parent; std::map templates; bool unloadTemplatesLib; bool getInterfacesBusy; Ui::newHostDialog_q *m_dialog; void fillInterfaceData(libfwbuilder::Interface *intf, QTextBrowser *qte); bool validateAddressAndMask(const QString &addr, const QString &netm); public: newHostDialog(QWidget *parentw, libfwbuilder::FWObject *parent); virtual ~newHostDialog(); libfwbuilder::Host* getNewHost() { return nhst; }; virtual bool appropriate(const int page) const; void showPage(const int page); public slots: virtual void changed(); // virtual void selectedInterface(QTreeWidgetItem *cur); virtual void getInterfacesViaSNMP(); virtual void monitor(); // virtual void templateSelected(QListWidgetItem *cur); virtual void templateSelected(QListWidgetItem *itm); void browseTemplate(); void useStandardTemplate(); void updateTemplatePanel(); protected slots: virtual void finishClicked(); virtual void cancelClicked(); virtual void nextClicked(); virtual void backClicked(); }; #endif // __NEWHOSTDIALOG_H fwbuilder-5.1.0.3599/src/libgui/pixFailoverOptionsDialog.cpp0000644000175000017500000000554311733011756024537 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "pixFailoverOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include #include using namespace std; using namespace libfwbuilder; pixFailoverOptionsDialog::pixFailoverOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::pixFailoverOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); data.registerOption(m_dialog->pix_failover_key, gropt, "pix_failover_key"); data.loadAll(); } pixFailoverOptionsDialog::~pixFailoverOptionsDialog() { delete m_dialog; } /* * store all data in the object */ void pixFailoverOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void pixFailoverOptionsDialog::reject() { QDialog::reject(); } bool pixFailoverOptionsDialog::validate() { bool valid = true; QWidget *focus = NULL; QString message; // key must be set if (m_dialog->pix_failover_key->text().isEmpty()) { message = "PIX failover key field can not be empty!"; focus = m_dialog->pix_failover_key; valid = false; } if (!valid) { QMessageBox::warning(this, "Firewall Builder", tr("Input not valid: %1").arg(message), "&Continue", QString::null, QString::null, 0, 1); focus->setFocus(); } return valid; } fwbuilder-5.1.0.3599/src/libgui/IconSetter.cpp0000644000175000017500000000302511733011756021623 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "IconSetter.h" #include "FWBTree.h" #include "utils.h" void IconSetter::setObjectIcon(libfwbuilder::FWObject *obj, QPixmap *pm, int icon_size) { QString icn_alias; QString icn_sfx; switch (icon_size) { case 0: icn_sfx = "icon-tree"; break; case 2: icn_sfx = "icon-big"; break; default: icn_sfx = "icon"; break; } if (obj->getRO()) icn_alias = ":/Icons/lock"; else { if (FWBTree().isSystem(obj)) icn_alias = ":/Icons/SystemGroup/" + icn_sfx; else icn_alias = QString(":/Icons/") + obj->getTypeName().c_str() + "/" + icn_sfx; } LoadPixmap(icn_alias, *pm); } fwbuilder-5.1.0.3599/src/libgui/ObjectSelectorWidget.cpp0000644000175000017500000001034311733011756023620 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "ObjectSelectorWidget.h" #include "ObjectDescriptor.h" #include "FilterDialog.h" #include #include #include #include using namespace std; using namespace libfwbuilder; ObjectSelectorWidget::ObjectSelectorWidget(QWidget *parent) : QWidget(parent) { m_dialog = new Ui::ObjectSelectorWidget_q; m_dialog->setupUi(this); flt_obj = new Filter(); flt_obj_d = new FilterDialog(this); flt_obj_d->setFilter(flt_obj); } ObjectSelectorWidget::~ObjectSelectorWidget() { delete flt_obj; delete flt_obj_d; } void ObjectSelectorWidget::init(const QList &objects) { this->objects = objects; fillListOfObjects(); } void ObjectSelectorWidget::updateObjectsToUse() { objects_to_use.clear(); QListWidgetItem* item = m_dialog->objectList->item(0); while (item != NULL) { QString name = item->text().split(" ")[0]; QString addr = item->data(Qt::UserRole).toString(); objects_to_use << name << addr; item = m_dialog->objectList->item(m_dialog->objectList->row(item)+1); } } void ObjectSelectorWidget::fillListOfObjects() { m_dialog->objectResultList->clear(); foreach(ObjectDescriptor od, objects) { QString addr = od.addr.toString().c_str(); QString name = QString::fromUtf8(od.sysname.c_str()); if ( flt_obj->test(od) ) { QString item_text("%1 %2"); QListWidgetItem *itm = new QListWidgetItem(item_text.arg(name).arg(addr)); itm->setData(Qt::UserRole, QVariant(addr)); m_dialog->objectResultList->addItem(itm); } } updateObjectsToUse(); emit selectionChanged(); } void ObjectSelectorWidget::addFilter() { flt_obj_d->exec(); fillListOfObjects(); } void ObjectSelectorWidget::removeFilter() { flt_obj->clear(); fillListOfObjects(); } void ObjectSelectorWidget::selectAllResults() { m_dialog->objectResultList->selectAll(); } void ObjectSelectorWidget::unselectAllResults() { m_dialog->objectResultList->clearSelection(); } void ObjectSelectorWidget::selectAllUsed() { m_dialog->objectList->selectAll(); } void ObjectSelectorWidget::unselectAllUsed() { m_dialog->objectList->clearSelection(); } void ObjectSelectorWidget::addObject() { QListWidgetItem* item = (QListWidgetItem*)m_dialog->objectResultList->item(0); int i = 0; while (item) { if (item->isSelected() && m_dialog->objectList->findItems( item->text(), Qt::MatchExactly).size() == 0) { QString addr = item->data(Qt::UserRole).toString(); QListWidgetItem *item2 = new QListWidgetItem(item->text()); item2->setData(Qt::UserRole, QVariant(addr)); m_dialog->objectList->addItem(item2); } i++; item = (QListWidgetItem*)m_dialog->objectResultList->item(i); } updateObjectsToUse(); emit selectionChanged(); } void ObjectSelectorWidget::removeObject() { QListWidgetItem* item1 = m_dialog->objectList->item(0); QListWidgetItem* item2; while (item1!=0) { item2 = m_dialog->objectList->item(m_dialog->objectList->row(item1)+1); if (item1->isSelected()) { delete item1; } item1 = item2; } updateObjectsToUse(); emit selectionChanged(); } fwbuilder-5.1.0.3599/src/libgui/BaseObjectDialog.h0000644000175000017500000000315111733011756022332 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BASEOBJECTDIALOG_H_ #define __BASEOBJECTDIALOG_H_ #include "global.h" #include "fwbuilder/FWObject.h" #include #include class ProjectPanel; class BaseObjectDialog : public QWidget { Q_OBJECT; protected: libfwbuilder::FWObject *obj; bool init; ProjectPanel *m_project; public slots: virtual void changed(); public: BaseObjectDialog(QWidget *parent) : QWidget(parent) { obj = 0; init = false; m_project = NULL; } virtual ~BaseObjectDialog() {}; void attachToProjectWindow(ProjectPanel *pp) { m_project = pp; } ProjectPanel* getAssociatedProjectWindow() { return m_project; } void connectSignalsOfAllWidgetsToSlotChange(); signals: void changed_sign(); }; #endif fwbuilder-5.1.0.3599/src/libgui/platforms.cpp0000644000175000017500000012643211733011756021563 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "FWBSettings.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include #include #include #include #include "fwbuilder/Cluster.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Policy.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; QStringList emptyList; QStringList logLevels; QStringList logFacilities; QStringList actionsOnReject; QStringList routeOptions_pf_ipf; QStringList routeLoadOptions_pf; QStringList limitSuffixes; QStringList classifyOptions_ipfw; void init_platforms() { logLevels.push_back(""); logLevels.push_back(""); logLevels.push_back(QObject::tr( "alert" )); logLevels.push_back( "alert" ); logLevels.push_back(QObject::tr( "crit" )); logLevels.push_back( "crit" ); logLevels.push_back(QObject::tr( "error" )); logLevels.push_back( "error" ); logLevels.push_back(QObject::tr( "warning")); logLevels.push_back( "warning"); logLevels.push_back(QObject::tr( "notice" )); logLevels.push_back( "notice" ); logLevels.push_back(QObject::tr( "info" )); logLevels.push_back( "info" ); logLevels.push_back(QObject::tr( "debug" )); logLevels.push_back( "debug" ); logFacilities.push_back(""); logFacilities.push_back(""); logFacilities.push_back(QObject::tr( "kern" )); logFacilities.push_back( "kern" ); logFacilities.push_back(QObject::tr( "user" )); logFacilities.push_back( "user" ); logFacilities.push_back(QObject::tr( "mail" )); logFacilities.push_back( "mail" ); logFacilities.push_back(QObject::tr( "daemon" )); logFacilities.push_back( "daemon" ); logFacilities.push_back(QObject::tr( "auth" )); logFacilities.push_back( "auth" ); logFacilities.push_back(QObject::tr( "syslog" )); logFacilities.push_back( "syslog" ); logFacilities.push_back(QObject::tr( "lpr" )); logFacilities.push_back( "lpr" ); logFacilities.push_back(QObject::tr( "news" )); logFacilities.push_back( "news" ); logFacilities.push_back(QObject::tr( "uucp" )); logFacilities.push_back( "uucp" ); logFacilities.push_back(QObject::tr( "cron" )); logFacilities.push_back( "cron" ); logFacilities.push_back(QObject::tr( "authpriv" )); logFacilities.push_back( "authpriv"); logFacilities.push_back(QObject::tr( "ftp" )); logFacilities.push_back( "ftp" ); logFacilities.push_back(QObject::tr( "local0" )); logFacilities.push_back( "local0" ); logFacilities.push_back(QObject::tr( "local1" )); logFacilities.push_back( "local1" ); logFacilities.push_back(QObject::tr( "local2" )); logFacilities.push_back( "local2" ); logFacilities.push_back(QObject::tr( "local3" )); logFacilities.push_back( "local3" ); logFacilities.push_back(QObject::tr( "local4" )); logFacilities.push_back( "local4" ); logFacilities.push_back(QObject::tr( "local5" )); logFacilities.push_back( "local5" ); logFacilities.push_back(QObject::tr( "local6" )); logFacilities.push_back( "local6" ); logFacilities.push_back(QObject::tr( "local7" )); logFacilities.push_back( "local7" ); actionsOnReject.push_back(""); actionsOnReject.push_back(""); actionsOnReject.push_back(QObject::tr("ICMP admin prohibited")); actionsOnReject.push_back("ICMP admin prohibited"); actionsOnReject.push_back(QObject::tr("ICMP host prohibited")); actionsOnReject.push_back("ICMP host prohibited"); actionsOnReject.push_back(QObject::tr("ICMP host unreachable")); actionsOnReject.push_back("ICMP host unreachable"); actionsOnReject.push_back(QObject::tr("ICMP net prohibited")); actionsOnReject.push_back("ICMP net prohibited"); actionsOnReject.push_back(QObject::tr("ICMP net unreachable")); actionsOnReject.push_back("ICMP net unreachable"); actionsOnReject.push_back(QObject::tr("ICMP port unreachable")); actionsOnReject.push_back("ICMP port unreachable"); actionsOnReject.push_back(QObject::tr("ICMP protocol unreachable")); actionsOnReject.push_back("ICMP protocol unreachable"); actionsOnReject.push_back(QObject::tr("TCP RST")); actionsOnReject.push_back("TCP RST"); routeOptions_pf_ipf.push_back(QObject::tr("None")); routeOptions_pf_ipf.push_back("none"); routeOptions_pf_ipf.push_back(QObject::tr("Route through")); routeOptions_pf_ipf.push_back("route_through"); routeOptions_pf_ipf.push_back(QObject::tr("Route reply through")); routeOptions_pf_ipf.push_back("route_reply_through"); routeOptions_pf_ipf.push_back(QObject::tr("Route a copy through")); routeOptions_pf_ipf.push_back("route_copy_through"); routeLoadOptions_pf.push_back(QObject::tr("None")); routeLoadOptions_pf.push_back("none"); routeLoadOptions_pf.push_back(QObject::tr("Bitmask")); routeLoadOptions_pf.push_back("bitmask"); routeLoadOptions_pf.push_back(QObject::tr("Random")); routeLoadOptions_pf.push_back("random"); routeLoadOptions_pf.push_back(QObject::tr("Source Hash")); routeLoadOptions_pf.push_back("source_hash"); routeLoadOptions_pf.push_back(QObject::tr("Round Robin")); routeLoadOptions_pf.push_back("round_robin"); classifyOptions_ipfw.push_back(QObject::tr("None")); classifyOptions_ipfw.push_back("-1"); classifyOptions_ipfw.push_back(QObject::tr("dummynet(4) 'pipe'")); classifyOptions_ipfw.push_back("1"); classifyOptions_ipfw.push_back(QObject::tr("dummynet(4) 'queue'")); classifyOptions_ipfw.push_back("2"); limitSuffixes.push_back(""); limitSuffixes.push_back(""); limitSuffixes.push_back(QObject::tr("/day")); limitSuffixes.push_back("/day"); limitSuffixes.push_back(QObject::tr("/hour")); limitSuffixes.push_back("/hour"); limitSuffixes.push_back(QObject::tr("/minute")); limitSuffixes.push_back("/minute"); limitSuffixes.push_back(QObject::tr("/second")); limitSuffixes.push_back("/second"); } bool isUsingNetZone(Firewall *fw) { string platform=fw->getStr("platform"); return (platform=="pix" || platform=="fwsm"); } bool isDefaultPolicyRuleOptions(FWOptions *opt) { bool res = true; FWObject *p; PolicyRule *rule = NULL; p = opt; do { p = p->getParent(); if (PolicyRule::cast(p)!=NULL) rule = PolicyRule::cast(p); } while ( p!=NULL && Firewall::cast(p)==NULL ); if (p==NULL) { qDebug() << "isDefaultPolicyRuleOptions()" << "Can not locate parent Firewall object for the options object"; opt->dump(false, true); return true; } QString platform = p->getStr("platform").c_str(); // if (fwbdebug) // qDebug(QString("Options object type: %1").arg(opt->getTypeName())); if (PolicyRuleOptions::isA(opt)) { if (platform=="iptables") { res= ( opt->getStr("log_prefix").empty() && opt->getStr("log_level").empty() && opt->getInt("limit_value")<=0 && ! opt->getBool("limit_value_not") && opt->getInt("limit_burst")<=0 && opt->getInt("connlimit_value")<=0 && ! opt->getBool("connlimit_above_not") && opt->getInt("connlimit_masklen")<=0 && opt->getStr("hashlimit_name").empty() && opt->getInt("hashlimit_value")<=0 && opt->getInt("hashlimit_burst")<=0 && opt->getInt("hashlimit_size")<=0 && opt->getInt("hashlimit_max")<=0 && opt->getInt("hashlimit_expire")<=0 && opt->getInt("hashlimit_gcinterval")<=0 && opt->getInt("ulog_nlgroup")<=1 && opt->getStr("limit_suffix").empty() && opt->getStr("firewall_is_part_of_any_and_networks") == ""); } if (platform=="pix" || platform=="fwsm") { string vers="version_"+p->getStr("version"); if ( Resources::platform_res[platform.toAscii().constData()]->getResourceBool( "/FWBuilderResources/Target/options/"+vers+"/pix_rule_syslog_settings")) { res= ( opt->getStr("log_level").empty() && opt->getInt("log_interval")<=0 && ! opt->getBool("disable_logging_for_this_rule") ); } else { res=true; } } if (platform=="pf") { string version = p->getStr("version"); bool ge_4_0 = XMLTools::version_compare(version, "4.0")>=0; bool ge_4_5 = XMLTools::version_compare(version, "4.5")>=0; if (ge_4_5) { res = (!opt->getBool("pf_no_sync") && !opt->getBool("pf_pflow")); } if (ge_4_0) { res = res && ( opt->getStr("log_prefix").empty() && opt->getInt("pf_rule_max_state")<=0 && ! opt->getBool("pf_source_tracking") && opt->getInt("pf_max_src_conn")<=0 && opt->getInt("pf_max_src_conn_rate_num")<=0 && opt->getInt("pf_max_src_conn_rate_seconds")<=0 && ! opt->getBool("pf_keep_state") && ! opt->getBool("pf_sloppy_tracker") && ! opt->getBool("pf_synproxy") && ! opt->getBool("pf_modulate_state") ); }else { res = res && ( opt->getStr("log_prefix").empty() && opt->getInt("pf_rule_max_state")<=0 && ! opt->getBool("pf_source_tracking") && opt->getInt("pf_max_src_conn")<=0 && opt->getInt("pf_max_src_conn_rate_num")<=0 && opt->getInt("pf_max_src_conn_rate_seconds")<=0 && ! opt->getBool("pf_keep_state") && ! opt->getBool("pf_sloppy_tracker") && ! opt->getBool("pf_synproxy") && ! opt->getBool("pf_modulate_state") ); } } if (platform=="ipf") { res= ( opt->getStr("ipf_log_facility").empty() && opt->getStr("log_level").empty() && ! opt->getBool("ipf_keep_frags") && ! opt->getBool("ipf_return_icmp_as_dest") ); } if (platform=="ipfw") { //res= ( ! opt->getBool("stateless") ); res = true; } if (rule!=NULL) { PolicyRule::Action act = rule->getAction(); if (act==PolicyRule::Accept) { // by default, these actions are not stateless res = res && (!opt->getBool("stateless")); } else { // other actions are stateless by default res = res && opt->getBool("stateless"); } } // all rules are stateless for IOS ACL if (platform=="iosacl" || platform=="procurve_acl") { res = !opt->getBool("iosacl_add_mirror_rule"); } } return res; } bool isDefaultNATRuleOptions(FWOptions *opt) { bool res=true; FWObject *p; p=opt; do { p=p->getParent(); } while ( p!=NULL && Firewall::cast(p)==NULL ); assert(p!=NULL); QString platform = p->getStr("platform").c_str(); if (NATRuleOptions::isA(opt)) { if (platform=="iptables") { res = !opt->getBool("ipt_use_snat_instead_of_masq") && !opt->getBool("ipt_nat_random") && !opt->getBool("ipt_nat_persistent"); } if (platform=="pf") { // if "pf_pool_type_none" is undefined, then all others // should not be defined too because they all are set by // the same dialog // In this case consider options default. res = (opt->getStr("pf_pool_type_none") == "" || ( opt->getBool("pf_pool_type_none") && ! opt->getBool("pf_bitmask") && ! opt->getBool("pf_random") && ! opt->getBool("pf_source_hash") && ! opt->getBool("pf_round_robin") && ! opt->getBool("pf_static_port") ) ); } if (platform=="pix" || platform=="fwsm") { res = (! opt->getBool("asa8_nat_dns") && ! opt->getBool("asa8_nat_static") && ! opt->getBool("asa8_nat_dynamic")); } } return res; } bool isDefaultRoutingRuleOptions(FWOptions *opt) { bool res=true; // if (fwbdebug) // qDebug(QString("Options object type: %1").arg(opt->getTypeName())); if (RoutingRuleOptions::isA(opt)) { res= ( ! opt->getBool("no_fail") ); } return res; } QString getVersionString(const QString &platform, const QString &version) { list vl; getVersionsForPlatform(platform, vl); list::iterator li = std::find_if(vl.begin(),vl.end(),findFirstInQStringPair(version)); QString readableVersion = (li!=vl.end())?li->second:""; return readableVersion; } void getVersionsForPlatform(const QString &platform, std::list &res) { /* versions are defined here instead of the resource files so that * strings could be localized. We use strings that can be localized * only for iptables but define versions for all platforms here for * uniformity */ if (platform=="iptables") { res.push_back(QStringPair("", QObject::tr("- any -"))); res.push_back(QStringPair("lt_1.2.6", QObject::tr("1.2.5 or earlier"))); res.push_back(QStringPair("ge_1.2.6", QObject::tr("1.2.6 to 1.2.8"))); res.push_back(QStringPair("1.2.9", QObject::tr("1.2.9 to 1.2.11"))); res.push_back(QStringPair("1.3.0", QObject::tr("1.3.x"))); res.push_back(QStringPair("1.4.0", QObject::tr("1.4.0 or later"))); res.push_back(QStringPair("1.4.1.1", QObject::tr("1.4.1.1 or later"))); res.push_back(QStringPair("1.4.3", QObject::tr("1.4.3"))); res.push_back(QStringPair("1.4.4", QObject::tr("1.4.4 or later"))); } else { // we list supported versions for the following platforms in // corresponding resource .xml file if (platform=="pix" || platform=="fwsm" || platform=="iosacl" || platform=="procurve_acl") { QString lst = Resources::platform_res[ platform.toAscii().constData()]->getResourceStr( "/FWBuilderResources/Target/versions").c_str(); QStringList ll=lst.split(','); for (QStringList::iterator i=ll.begin(); i!=ll.end(); ++i) res.push_back(QStringPair(*i,*i)); } else { if (platform=="pf") { res.push_back(QStringPair("","- any -")); res.push_back(QStringPair("3.x", QObject::tr("3.x"))); res.push_back(QStringPair("ge_3.7", QObject::tr("3.7 to 3.9"))); res.push_back(QStringPair("4.0", QObject::tr("4.0 to 4.2"))); res.push_back(QStringPair("4.3", QObject::tr("4.3"))); res.push_back(QStringPair("4.5", QObject::tr("4.5"))); res.push_back(QStringPair("4.6", QObject::tr("4.6"))); res.push_back(QStringPair("4.7", QObject::tr("4.7 and later"))); /* add pf versions here */ } else { if (platform=="ipf") { res.push_back(QStringPair("","- any -")); /* add ipf versions here */ } else { if (platform=="ipfw") { res.push_back(QStringPair("","- any -")); /* add ipfw versions here */ } else res.push_back(QStringPair("","- any -")); } } } } } /* * ticket #58: move state sync types and failover types to resource files. * * Note: this function fills in list of QString pairs, each pair is * , * The second element in the pair is for QComboBox and is visible to the user. */ void getStateSyncTypesForOS(const QString &host_os, std::list &res) { Resources* os_res = Resources::os_res[host_os.toStdString()]; if (os_res==NULL) return; list protocols; os_res->getResourceStrList("/FWBuilderResources/Target/protocols/state_sync", protocols); _repackStringList(protocols, res); } void getFailoverTypesForOS(const QString &host_os, std::list &res) { Resources* os_res = Resources::os_res[host_os.toStdString()]; if (os_res==NULL) return; list protocols; os_res->getResourceStrList("/FWBuilderResources/Target/protocols/failover", protocols); _repackStringList(protocols, res); } void getInterfaceTypes(Interface *iface, list &res) { FWObject *fw = iface->getParent(); string host_os = fw->getStr("host_OS"); Resources* os_res = Resources::os_res[host_os]; if (os_res==NULL) return; list interface_types; if (Cluster::isA(fw)) { os_res->getResourceStrList("/FWBuilderResources/Target/interfaces/cluster", interface_types); } else { os_res->getResourceStrList("/FWBuilderResources/Target/interfaces/firewall", interface_types); } _repackStringList(interface_types, res); } /* * Return list of types of subinterfaces that given interface can have * * @iface an Interface object. This is not a subinterface, this is a * regular interface. This function returns list of subinterface types * this interface can have. * * @res a list of pairs of QString, each pair is , */ void getSubInterfaceTypes(Interface *iface, list &res) { FWObject *p = Host::getParentHost(iface); //FWObject *p = iface->getParentHost(); assert(p!=NULL); QString host_os = p->getStr("host_OS").c_str(); Resources* os_res = Resources::os_res[host_os.toStdString()]; if (os_res==NULL) return; FWOptions *ifopt; ifopt = Interface::cast(iface)->getOptionsObject(); string parent_type = ifopt->getStr("type"); // empty parent type is equivalent to "ethernet" for backwards // compatibility if (parent_type.empty()) parent_type = "ethernet"; QString obj_name = iface->getName().c_str(); list interface_types; os_res->getResourceStrList( "/FWBuilderResources/Target/subinterfaces/" + parent_type, interface_types); _repackStringList(interface_types, res); } void setInterfaceTypes(QComboBox *iface_type, Interface *iface, const QString ¤t_type) { bool this_is_subinterface = Interface::isA(iface->getParent()); list mapping; if (this_is_subinterface) getSubInterfaceTypes(Interface::cast(iface->getParent()), mapping); else getInterfaceTypes(iface, mapping); if (st->getBool("Objects/Interface/autoconfigureInterfaces")) { // #335 : if interface name matches naming convention for vlan // interfaces and vlan type is in the list that came from the // resource file, then leave only vlan in the list we return. // Note that if resource file says this subint can not be vlan, we // dan't return vlan type on the list even if its name looks like // it could be one. FWObject *p = Host::getParentHost(iface); //FWObject *p = iface->getParentHost(); assert(p!=NULL); QString host_os = p->getStr("host_OS").c_str(); QString obj_name = iface->getName().c_str(); Resources* os_res = Resources::os_res[p->getStr("host_OS")]; string os_family = p->getStr("host_OS"); if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( os_family)); if (int_prop->looksLikeVlanInterface(obj_name)) { QString parent_name = iface->getParent()->getName().c_str(); QString err; if (int_prop->isValidVlanInterfaceName(obj_name, parent_name, err)) { // iface can be valid vlan interface. Leave only vlan type // in the list if it was there to begin with. for (list::iterator it=mapping.begin(); it!=mapping.end(); ++it) { QString itype = it->first; QString rtype = it->second; if (itype == "8021q") { mapping.clear(); mapping.push_back(QStringPair(itype, rtype)); mapping.push_back(QStringPair("unknown", "Unknown")); break; } } } } } list::iterator it; int idx = 0; int unknown_idx = 0; int current_idx = -1; for (it = mapping.begin(); it != mapping.end(); it++) { if (it->first == "unknown") unknown_idx = idx; iface_type->addItem(it->second); iface_type->setItemData(idx, QVariant(it->first)); if (current_type == it->first) current_idx = idx; idx++; } if (current_idx >= 0) iface_type->setCurrentIndex(current_idx); else iface_type->setCurrentIndex(unknown_idx); } /* currently we return the same list for all platforms */ const QStringList& getLogLevels(const QString&) { return logLevels; } const QStringList& getLogFacilities(const QString&) { return logFacilities; } const QStringList& getActionsOnReject(const QString&) { return actionsOnReject; } /* * need to return mapping list for the parameter 'route_option' of * action 'Routing' regardless of the firewall platform even though * it only makes sense and is needed for pf and ipf. This is because * ActionsDialog is designed with widget stack and therefore must * always initialize widgets for all platforms. Worse, it always * saves all parameters into rule options object, regardless of the * platform. So, if we return an empty mapping list from this method * because platform is not pf or ipf while user is editing action * parameters for iptables, parameters for pf and ipf get saved * uninitizalized and unmapped. QComboBox::currentText() returns the * first item which goes straight into rule options object. This is * ok in English locale, but breaks XML if the item has been * translated and the program runs under national locale. Sigh. */ const QStringList& getRouteOptions_pf_ipf(const QString&) { return routeOptions_pf_ipf; } const QStringList& getRouteLoadOptions_pf(const QString&) { return routeLoadOptions_pf; } const QStringList& getClassifyOptions_ipfw(const QString&) { return classifyOptions_ipfw; } const QStringList& getLimitSuffixes(const QString&) { return limitSuffixes; } QStringList getScreenNames(const QStringList &sl) { QStringList res; for( QStringList::const_iterator it = sl.begin(); it!=sl.end(); ++it,++it) { res.push_back(*it); } return res; } QString getScreenName(QString s, const QStringList &sl) { QString res; for( QStringList::const_iterator it = sl.begin(); it!=sl.end(); ++it) { res=(*it); ++it; if ((*it)==s) break; } return res; } QString getRuleAction(Rule *rule) { PolicyRule *policy_rule = PolicyRule::cast(rule); NATRule *nat_rule = NATRule::cast(rule); string act; if (policy_rule) act = policy_rule->getActionAsString(); if (nat_rule) act = nat_rule->getActionAsString(); return act.c_str(); } /* * will remap names of some actions to make it clear what commands or * configuration language keywords they will be translated to for the * target firewall platform. This should help users who are familiar * with the platform. There are very few places where such mapping is * necessary, plus we need to provide for localization of the mapped * names. That is why action names are not stored in platform resource * files and are not pulled using Rule::getActionAsString. */ QString getActionNameForPlatform(Firewall *fw, Rule *rule) { if (fw==NULL) return ""; PolicyRule *policy_rule = PolicyRule::cast(rule); NATRule *nat_rule = NATRule::cast(rule); string act; if (policy_rule) act = policy_rule->getActionAsString(); if (nat_rule) act = nat_rule->getActionAsString(); return getActionNameForPlatform(fw, act); } QString getActionNameForPlatform(Firewall *fw, const std::string &action) { if (fw==NULL) return ""; string platform = fw->getStr("platform"); string name; try { name = Resources::getTargetCapabilityStr( platform, "actions/" + action + "/description"); } catch (FWException &ex) { } return name.c_str(); } /* * this function provides logic for the decision whether the rule * should be stateless by default. Currently it only depends on the * action, but may depend on the platform as well. * * actions Accept, Tag and Route by default assume the rule is * stateful. Other actions by default assume it is stateless * and set rule option accordingly * * See bugs #1676635 and 1671910 */ bool getStatelessFlagForAction(PolicyRule *rule) { PolicyRule::Action act = rule->getAction(); if (act==PolicyRule::Accept) return false; else return true; } /** * Returns translatable string - name of the corresponding rule element. */ QString getReadableRuleElementName(const string &platform, const string &re_type_name) { bool nat_intf_in = Resources::getTargetCapabilityBool( platform, "inbound_interface_in_nat"); bool nat_intf_out = Resources::getTargetCapabilityBool( platform, "outbound_interface_in_nat"); // The following map TYPENAME of RuleElement classes to readable // translatable names. if (re_type_name == "Src") return QObject::tr("Source"); if (re_type_name == "Dst") return QObject::tr("Destination"); if (re_type_name == "Srv") return QObject::tr("Service"); if (re_type_name == "Itf") return QObject::tr("Interface"); if (re_type_name == "When") return QObject::tr("Time"); if (re_type_name == "OSrc") return QObject::tr("Original Src"); if (re_type_name == "ODst") return QObject::tr("Original Dst"); if (re_type_name == "OSrv") return QObject::tr("Original Srv"); if (re_type_name == "TSrc") return QObject::tr("Translated Src"); if (re_type_name == "TDst") return QObject::tr("Translated Dst"); if (re_type_name == "TSrv") return QObject::tr("Translated Srv"); if (nat_intf_in != nat_intf_out) { // For some platforms I only show one interface column in nat // rules, in this case nat_intf_in and nat_intf_out have // different values. For example, for PF I hide inbound // interface and show outbound interface column. Columns title // should then be just "Interface" if (re_type_name == "ItfInb") return QObject::tr("Interface"); if (re_type_name == "ItfOutb") return QObject::tr("Interface"); } else { if (re_type_name == "ItfInb") return QObject::tr("Interface In"); if (re_type_name == "ItfOutb") return QObject::tr("Interface Out"); } if (re_type_name == "RDst") return QObject::tr("Destination"); if (re_type_name == "RGtw") return QObject::tr("Gateway"); if (re_type_name == "RItf") return QObject::tr("Interface"); // as of v3.0.x the following are not real rule elements (not separate // classes with names) but just attributes of corresponding Rule class. if (re_type_name == "Direction") return QObject::tr("Direction"); if (re_type_name == "Action") return QObject::tr("Action"); if (re_type_name == "Options") return QObject::tr("Options"); if (re_type_name == "Metric") return QObject::tr("Metric"); if (re_type_name == "Comment") return QObject::tr("Comment"); return QString(); } QMap getAllPlatforms(bool filter) { QMap res; map platforms = Resources::getPlatforms(); map::iterator i; for (i=platforms.begin(); i!=platforms.end(); i++) { QString name = i->first.c_str(); QString res_status = Resources::platform_res[name.toStdString()]->getResourceStr( "/FWBuilderResources/Target/status/").c_str(); QString status = st->getTargetStatus(name, res_status); if (filter && status == "disabled") continue; res[name] = i->second.c_str(); } return res; } QMap getAllOS(bool filter) { QMap res; map OSs = Resources::getOS(); map::iterator i; for (i=OSs.begin(); i!=OSs.end(); i++) { QString name = i->first.c_str(); QString res_status = Resources::os_res[name.toStdString()]->getResourceStr( "/FWBuilderResources/Target/status/").c_str(); QString status = st->getTargetStatus(name, res_status); if (filter && status == "disabled") continue; res[name] = i->second.c_str(); } return res; } QString readPlatform(QComboBox *platform) { return platform->itemData(platform->currentIndex()).toString(); } QString readHostOS(QComboBox *hostOS) { return hostOS->itemData(hostOS->currentIndex()).toString(); } /* * Fill combobox widget with items that exist in resources. * If second argument is not an empty string, make corresponding item current. * If it is an empty string, add an empty item on top to the combo box and make * it current. */ void setPlatform(QComboBox *platform, const QString &pl) { platform->clear(); // platforms maps platform name (pix) to readable name (Cisco PIX) QMap platforms = getAllPlatforms(); QMap::iterator i; // platform_mapping maps key (.) to pair // , QMap > platform_mapping; QStringList platform_keys; for (i=platforms.begin(); i!=platforms.end(); i++) { QString group = Resources::platform_res[i.key().toLatin1().constData()]-> getResourceStr("/FWBuilderResources/Target/group").c_str(); QString key = group + "." + i.key(); platform_mapping[key] = QPair(group, i.key()); platform_keys.push_back(key); } qSort(platform_keys); QStringList::iterator iter; int ind = 0; int cp = 0; if (pl.isEmpty()) { platform->addItem("", ""); cp++; } QString current_group = ""; for (iter=platform_keys.begin(); iter!=platform_keys.end(); iter++) { if (fwbdebug) qDebug() << *iter; QString group = platform_mapping[*iter].first; QString platform_name = platform_mapping[*iter].second; if (platforms.count(platform_name) == 0) continue; if (group != current_group) { current_group = group; #if (QT_VERSION > 0x040500) platform->insertSeparator(cp); // QT before 4.4.? does not support separator in QComboBox #else platform->addItem(""); #endif cp++; } platform->addItem(platforms[platform_name], platform_name); // note that if pl is "", then no real platform name will // match it and ind will remain 0, which makes the top item in // the combobox current. if ( pl == platform_name ) ind = cp; cp++; } platform->setCurrentIndex( ind ); } /* * Fill in "host os" combo box with list of os supported for the given * platform and make current host os item current. * * If platform == "", then use all known host OS but also add * empty item on top of the combobox and make that item current. * If os == "", make the first OS in the list current. */ void setHostOS(QComboBox *hostOS, const QString &platform, const QString &os) { hostOS->clear(); QStringList supported_os_list; if (!platform.isEmpty()) { Resources *platform_res = Resources::platform_res[platform.toLatin1().constData()]; if (!platform_res) platform_res = Resources::platform_res["unknown"]; QString supported_os = platform_res-> getResourceStr("/FWBuilderResources/Target/supported_os").c_str(); if (fwbdebug) qDebug("supported_os %s", supported_os.toLatin1().constData()); if (supported_os.isEmpty()) { // something is broken, we have no supported host OS for // this platform. Just add os to the combo box and return if (fwbdebug) qDebug("No supported host OS for platform %s", platform.toLatin1().constData()); hostOS->addItem(os, os); hostOS->setCurrentIndex(0); return; } supported_os_list = supported_os.split(","); int cp = 0; int ind = 0; QMap OSs = getAllOS(); QStringList::iterator os_iter; for (os_iter=supported_os_list.begin(); os_iter!=supported_os_list.end(); ++os_iter) { QString os_code = *os_iter; if (OSs.count(os_code) > 0) { hostOS->addItem( OSs[os_code], os_code); if ( os == os_code ) ind = cp; cp++; } } hostOS->setCurrentIndex( ind ); return; } // platform is empty int cp = 0; int ind = 0; hostOS->addItem("", ""); cp++; QMap OSs = getAllOS(); QMap::iterator i; for (i=OSs.begin(); i!=OSs.end(); i++) { hostOS->addItem( i.value(), i.key() ); if ( os == i.key() ) ind = cp; cp++; } hostOS->setCurrentIndex( ind ); } void _repackStringList(list &list1, list &list2) { list2.clear(); foreach(string p, list1) { QString str = QString(p.c_str()); QStringList pl = str.split(","); if (pl.size() == 1) list2.push_back(QStringPair(str, str)); else list2.push_back(QStringPair(pl[0], pl[1])); } } void setDefaultStateSyncGroupAttributes(StateSyncClusterGroup *grp) { FWObject *p = grp; while (p && Cluster::cast(p)==NULL) p = p->getParent(); assert(p != NULL); Cluster *cluster = Cluster::cast(p); Resources *os_res = Resources::os_res[cluster->getStr("host_OS")]; assert(os_res != NULL); list protocols; os_res->getResourceStrList("/FWBuilderResources/Target/protocols/state_sync", protocols); QStringList protocol_names = QString(protocols.front().c_str()).split(","); grp->setName(protocol_names[1].toStdString()); grp->setStr("type", protocol_names[0].toStdString()); } void setDefaultFailoverGroupAttributes(FailoverClusterGroup *grp) { FWObject *p = grp; while (p && Cluster::cast(p)==NULL) p = p->getParent(); assert(p != NULL); Cluster *cluster = Cluster::cast(p); Resources *os_res = Resources::os_res[cluster->getStr("host_OS")]; assert(os_res != NULL); FWOptions *gropt = grp-> getOptionsObject(); assert(gropt != NULL); string failover_protocol = grp->getStr("type"); if (failover_protocol == "carp") { gropt->setStr("carp_password", ""); gropt->setInt("carp_vhid", 1); gropt->setInt("carp_advbase", 1); gropt->setInt("carp_master_advskew", 10); gropt->setInt("carp_default_advskew", 20); } if (failover_protocol == "vrrp") { gropt->setStr("vrrp_secret", ""); gropt->setInt("vrrp_vrid", 1); gropt->setBool("vrrp_over_ipsec_ah", false); } if (failover_protocol == "heartbeat") { string default_address = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/heartbeat/default_address"); string default_port = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/heartbeat/default_port"); gropt->setStr("heartbeat_address", default_address); gropt->setStr("heartbeat_port", default_port); gropt->setBool("heartbeat_unicast", false); } if (failover_protocol == "openais") { string default_address = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/openais/default_address"); string default_port = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/openais/default_port"); gropt->setStr("openais_address", default_address); gropt->setStr("openais_port", default_port); } if (failover_protocol == "pix_failover") { gropt->setStr("pix_failover_key", ""); } } void guessInterfaceLabel(InterfaceData *idata) { /* * some firewalls report fairly regular names for interfaces through * their built-in SNMP agent. We can use this to assign labels * automatically. * * in PIX interfaces have names like "PIX Firewall 'inside' interface" * */ QString qs_name = idata->name.c_str(); QString qs_label; QRegExp pat1("Adaptive Security Appliance '(.*)' interface"); QRegExp pat2("Cisco PIX Security Appliance '(.*)' interface"); QRegExp pat3("PIX Firewall '(.*)' interface"); if (pat1.indexIn(qs_name) > -1) qs_label = pat1.cap(1); if (pat2.indexIn(qs_name) > -1) qs_label = pat2.cap(1); if (pat3.indexIn(qs_name) > -1) qs_label = pat3.cap(1); idata->label = qs_label.toStdString(); if ( ! idata->isDyn && ! idata->isUnnumbered && ! idata->isBridgePort && idata->addr_mask.size()!=0 && idata->addr_mask.front()->getAddressPtr()->toString() == InetAddr::getLoopbackAddr().toString()) idata->label = "loopback"; } void guessSecurityLevel(const string&, InterfaceData *idata) { InetAddrMask n10(InetAddr("10.0.0.0"), InetAddr("255.0.0.0")); InetAddrMask n172(InetAddr("172.16.0.0"), InetAddr("255.240.0.0")); InetAddrMask n192(InetAddr("192.168.0.0"), InetAddr("255.255.0.0")); idata->securityLevel = -1; string llbl = idata->label; for (string::size_type i=0; isecurityLevel = 0; if ( llbl=="lan" || llbl=="in" || llbl.find("inside")!=string::npos || llbl.find("internal")!=string::npos ) idata->securityLevel = 100; if ( llbl.find("dmz")!=string::npos ) idata->securityLevel = 50; if ((*(idata->addr_mask.front()->getAddressPtr()))==InetAddr::getLoopbackAddr()) idata->securityLevel = 100; if (idata->name=="Null0") idata->securityLevel = 100; if (idata->securityLevel==-1 && ! idata->isDyn && ! idata->isUnnumbered && ! idata->isBridgePort) { if (n10.belongs(InetAddr(*(idata->addr_mask.front()->getAddressPtr())))) idata->securityLevel = 100; if (n172.belongs(InetAddr(*(idata->addr_mask.front()->getAddressPtr())))) idata->securityLevel = 100; if (n192.belongs(InetAddr(*(idata->addr_mask.front()->getAddressPtr())))) idata->securityLevel = 100; } if (idata->isDyn || idata->isUnnumbered || idata->isBridgePort) idata->securityLevel = 0; if (idata->securityLevel==-1) idata->securityLevel = 0; } void guessOSAndPlatformFromSysDescr( const QString &sysDescr, QString &platform, QString &hostOS, QString &version) { QList pix_re; pix_re << QRegExp("Cisco PIX Firewall Version ([0-9\\.]+)") << QRegExp("Cisco PIX Security Appliance Version ([0-9\\.]+)") << QRegExp("Cisco Adaptive Security Appliance Version ([0-9\\.]+)"); QList ios_re; ios_re << QRegExp("Cisco Internetwork Operating System Software .* Version ([0-9\\.]+)"); platform = ""; hostOS = ""; version = ""; if (fwbdebug) qDebug() << "guessOSAndPlatformFromSysDescr:" << "sysdescr=" << sysDescr; list allowed_versions; QString version_from_sysdescr; foreach (QRegExp re, pix_re) { if (re.indexIn(sysDescr) > -1) { platform = "pix"; hostOS = "pix_os"; version_from_sysdescr = re.cap(1); } } foreach (QRegExp re, ios_re) { if (re.indexIn(sysDescr) > -1) { platform = "iosacl"; hostOS = "ios"; version_from_sysdescr = re.cap(1); } } if (fwbdebug) qDebug() << "guessOSAndPlatformFromSysDescr:" << "platform=" << platform << "hostOS=" << hostOS << "version=" << version_from_sysdescr; if ( ! platform.isEmpty()) version = findBestVersionMatch(platform, version_from_sysdescr); } QString findBestVersionMatch(const QString &platform, const QString &discovered_version) { list allowed_versions; getVersionsForPlatform(platform, allowed_versions); if ( ! discovered_version.isEmpty()) { QString version_fit; list::iterator it; foreach (QStringPair p, allowed_versions) { QString vers = p.first; if (XMLTools::version_compare(vers.toStdString(), discovered_version.toStdString())>0) break; version_fit = vers; } return version_fit; } return ""; } fwbuilder-5.1.0.3599/src/libgui/RuleGroupPanel.cpp0000644000175000017500000000321611733011756022452 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RuleGroupPanel.h" #include "RuleSetView.h" RuleGroupPanel::RuleGroupPanel(QWidget * parent, RuleSetView * rsv, int row) : QFrame(parent) { this->row = row; this->rsv = rsv; this->setupUi(this); setContentsMargins(3,3,3,3); showHideRuleGroupButton->hide(); connect(showHideRuleGroupButton, SIGNAL(pressed()), this,SLOT(showHideRuleGroup())); } void RuleGroupPanel::mousePressEvent( QMouseEvent * event ) { if (event->buttons() == Qt::RightButton) { rsv->firstSelectedRow = row; rsv->contextMenu(row,0,event->globalPos ()); } } void RuleGroupPanel::mouseDoubleClickEvent( QMouseEvent * event ) { rsv->firstSelectedRow = row ; rsv->renameGroup(); } void RuleGroupPanel::showHideRuleGroup() { rsv->showHideRuleGroup(this); } fwbuilder-5.1.0.3599/src/libgui/pfadvanceddialog_q.ui0000644000175000017500000027473211733011756023211 0ustar sylvestresylvestre pfAdvancedDialog_q Qt::WindowModal 0 0 700 600 700 16777215 pf: advanced settings false 20 Help Qt::Horizontal QSizePolicy::Expanding 331 27 &OK true true &Cancel true 663 0 0 Compiler Compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 22 0 0 Command line options for the compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 22 Names of generated files Initialization script name (can be full path): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 32767 22 PF configuration file name (can be full path): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 32767 22 0 0 (if left blank, the file name is constructed of the firewall object name and extension ".fw" or ".conf" depending on the format) Qt::AlignVCenter true Names of the files on the firewall false Initialization script and PF configuration file can be copied to the firewall machine under different names. If these fields are left blank, the file name does not change. true Initialization script name on the firewall 32767 22 PF configuration file name on the firewall 32767 22 false Accept TCP sessions opened prior to firewall restart 0 0 Shadowing happens because a rule is a superset of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. Detect rule shadowing 0 0 Modulate state for all stateful rules (applies only to TCP services) 0 0 If the option is deactivated, compiler treats empty groups as an error and aborts processing the policy. If this option is activated, compiler removes all empty groups from all rule elements. If rule element becomes 'any' after the last empty group has been removed, the whole rule will be ignored. Use this option only if you fully understand how it works! Ignore empty groups Preserve group and address table obects names in the generated pf configuration 9 9 0 0 Always permit ssh access from the management workstation with this address: 0 0 32767 22 Qt::Vertical 20 11 Scrub Qt::Vertical QSizePolicy::Fixed 20 20 Clears the don't fragment bit from the IP packet header. Clear DF bit Replaces the IP identification field of outgoing packets with random values to compensate for operating systems that use predictable values. Use random ID Enforce Minimum TTL: Enforces a minimum Time To Live (TTL) in IP packet headers. 0 100 1 Qt::Horizontal 328 20 Enforce Maximum MSS: Enforces a maximum Maximum Segment Size (MSS) in TCP packet headers. 536 10000 1460 Qt::Horizontal QSizePolicy::Expanding 140 20 QFrame::HLine QFrame::Sunken Qt::Horizontal Reassemble fragments 0 0 6 0 0 Buffers incoming packet fragments and reassembles them into a complete packet before passing them to the filter engine. In PF 4.5 and earlier. Buffer and reassemble fragments (default) 0 0 Causes duplicate fragments to be dropped and any overlaps to be cropped. In PF 4.5 and earlier. Drop duplicate fragments, do not buffer and reassemble 0 0 Similar to 'Drop duplicate fragments' except that all duplicate or overlapping fragments will be dropped as well as any further corresponding fragments. In PF 4.5 and earlier. Drop duplicate and subsequent fragments Statefully normalises TCP connections. Reassemble TCP Qt::Vertical QSizePolicy::Expanding 20 110 Options Limits reassembly pool: 0 0 maximum number of entries in the memory pool used for packet reassembly 0 100000000 10 5000 state table size: 0 0 maximum number of entries in the memory pool used for state table entries 0 100000000 10 20000 src-nodes 0 0 maximum number of entries in the memory pool used for tracking source IP addresses 0 100000000 10 2000 tables 0 0 maximum number of tables that can exist in the memory simultaneously 0 100000000 10 1000 table-entries 0 0 maximum number of addresses that canbe stored in tables 0 100000000 10 100000 Options Optimization: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false Optimize state timeouts. See man pf.conf for more details. Debug: Set the debug level, which limits the severity of log messages printed by pf(4). This should be a keyword from the following ordered list (highest to lowest): emerg, alert, crit, err, warning, notice, info, and debug. The last keyword, debug, must be quoted. These keywords correspond to the similar (LOG_) values specified to the syslog(3) library routine. State policy: States can be bound to interfaces or match packets on any interface. The latter can be useful in case of an assymmetric routing. Block policy: The block-policy option sets the default behaviour for the packet block action: drop Packet is silently dropped. return A TCP RST is returned for blocked TCP packets, an ICMP UNREACHABLE is returned for blocked UDP packets, and all other packets are silently dropped. drop return Qt::Vertical 20 308 Timeouts When a packet matches a stateful connection, the seconds to live for the connection will be updated to the value which corresponds to the connection state. Qt::AlignVCenter true 0 0 TCP 6 0 0 first 0 0 The state after the first packet. 0 100000 0 opening 0 0 The state before the destination host ever sends a packet. 0 100000 0 established 0 0 The fully established state. 0 100000 1 0 0 0 The state after the first FIN has been sent. 0 100000 0 closing 0 0 The state after both FINs have been exchanged and the connection is closed. 0 100000 0 finwait 0 0 The state after one endpoint sends an RST. 0 100000 0 closed UDP 6 first 0 0 The state after the first packet. 0 100000 0 single 0 0 The state if the source host sends more than one packet but the destination host has never sent one back. 0 100000 0 multiple 0 0 The state if both hosts have sent packets. 0 100000 0 Other Protocols 6 0 0 first 0 0 The state after the first packet. 0 100000 0 single multiple 0 0 The state after the first packet. 0 100000 0 0 0 The state after the first packet. 0 100000 0 ICMP 6 0 0 The state after the first packet. 0 100000 0 0 0 The state after an ICMP error came back in response to an ICMP packet. 0 100000 0 first error Adaptive scaling Timeout values can be reduced adaptively as the number of state table entries grows (see man page pf.conf(5) for details) Qt::AlignVCenter true Activate adaptive timeout scaling 0 0 adaptive start false 0 0 When the number of state entries exceeds this value, adaptive scaling begins. 0 100000000 0 0 0 adaptive end false 0 0 When reaching this number of state entries, all timeout values become zero, effectively purging all state entries immediately. 0 100000000 0 Qt::Horizontal QSizePolicy::Expanding 40 20 Fragments translates into 'set timeout interval' interval between purging expired states and fragments 0 0 translates into 'set timeout interval' 1 1000 10 Qt::Horizontal 206 20 translates into 'set timeout frag' seconds before an unassembled fragment is expired 0 0 translates into 'set timeout frag' 1 1000 30 Qt::Vertical QSizePolicy::Expanding 20 20 Installer 20 Built-in installer Directory on the firewall where script should be installed Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 A command that installer should execute on the firewall in order to activate the policy (if this field is blank, installer runs firewall script in the directory specified above; it uses sudo if user name is not 'root') Qt::AlignVCenter true 0 0 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 External install script 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Qt::Vertical QSizePolicy::Expanding 20 80 Prolog/Epilog 20 12 20 20 20 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOff The following commands will be added verbatim after generated configuration Qt::AlignVCenter true 6 Edit Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOff The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Insert prolog and epilog scripts false 0 0 in the activation shell script (.fw file) in the pf rule file (.conf file) Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Horizontal QSizePolicy::Expanding 410 20 Logging 20 12 20 20 20 Qt::Vertical QSizePolicy::Fixed 20 20 Log Prefix Qt::AlignCenter false Qt::Horizontal QSizePolicy::Fixed 70 20 Qt::Horizontal QSizePolicy::Expanding 130 20 Qt::Vertical QSizePolicy::Expanding 20 320 Fallback "deny all" rule should log blocked packets Script Qt::Vertical QSizePolicy::Fixed 20 20 System configuration and firewall initialization script format false Firewall Builder can generate system configuration and initialization script for PF in two formats: this can either be a shell script or a file in rc.conf format. Rc.conf format is only supported for FreeBSD. true shell script with extension .fw file in rc.conf format Enable auxiliary sections in the generated script Turn debugging on in generated script Configure Interfaces of the firewall machine Configure CARP Interfaces Configure pfsync Interfaces Configure VLAN Interfaces 0 0 Configure bridge Interfaces Add virtual addresses for NAT Flush pf states after reloading rules Qt::Vertical QSizePolicy::Expanding 20 230 IPv6 20 The order in which ipv4 and ipv6 rules should be generated: Qt::Horizontal 40 20 IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 pf_configure_carp_interfaces pf_configure_pfsync_interfaces pf_configure_vlan_interfaces pf_manage_virtual_addr pf_flush_states ipv4before buttonCancel buttonOk buttonHelp tabWidget compiler compilerArgs outputFileName confFileName fileNameOnFw confFileNameOnFw pf_accept_new_tcp_with_no_syn pf_modulate_state pf_check_shadowing pf_ignore_empty_groups mgmt_ssh mgmt_addr pf_scrub_no_df pf_scrub_random_id pf_scrub_use_minttl pf_scrub_minttl pf_scrub_use_maxmss pf_scrub_maxmss pf_do_scrub pf_scrub_reassemble pf_scrub_fragm_crop pf_scrub_fragm_drop_ovl pf_scrub_reassemble_tcp pf_set_tcp_first pf_tcp_first pf_set_tcp_opening pf_tcp_opening pf_set_tcp_established pf_tcp_established pf_set_tcp_closing pf_tcp_closing pf_set_tcp_finwait pf_tcp_finwait pf_set_tcp_closed pf_tcp_closed pf_set_udp_first pf_udp_first pf_set_udp_single pf_udp_single pf_set_udp_multiple pf_udp_multiple pf_set_adaptive pf_adaptive_start pf_adaptive_end pf_set_icmp_first pf_icmp_first pf_set_icmp_error pf_icmp_error pf_set_other_first pf_other_first pf_set_other_single pf_other_single pf_set_other_multiple pf_other_multiple pf_do_timeout_interval pf_timeout_interval pf_do_timeout_frag pf_timeout_frag pf_fw_dir pf_user altAddress activationCmd sshArgs scpArgs installScript installScriptArgs prologPlace prolog_script edit_prolog_button epilog_script edit_epilog_button pf_log_prefix pf_fallback_log generateShellScript generateRcConfFile pf_debug pf_configure_interfaces buttonOk clicked() pfAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() pfAdvancedDialog_q reject() 20 20 20 20 pf_set_tcp_first toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_tcp_opening toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_tcp_established toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_tcp_closing toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_tcp_finwait toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_tcp_closed toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_udp_first toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_udp_single toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_udp_multiple toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_icmp_first toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_icmp_error toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_other_first toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_other_single toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_other_multiple toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 pf_set_adaptive toggled(bool) pfAdvancedDialog_q ltToggled() 20 20 20 20 edit_epilog_button clicked() pfAdvancedDialog_q editEpilog() 20 20 20 20 edit_prolog_button clicked() pfAdvancedDialog_q editProlog() 20 20 20 20 buttonHelp clicked() pfAdvancedDialog_q help() 47 638 345 330 pf_do_limit_frags clicked() pfAdvancedDialog_q ltToggled() 156 100 349 299 pf_do_limit_src_nodes clicked() pfAdvancedDialog_q ltToggled() 156 154 349 299 pf_do_limit_states clicked() pfAdvancedDialog_q ltToggled() 156 127 349 299 pf_do_limit_table_entries clicked() pfAdvancedDialog_q ltToggled() 156 208 349 299 pf_do_limit_tables clicked() pfAdvancedDialog_q ltToggled() 156 181 349 299 pf_do_scrub toggled(bool) pfAdvancedDialog_q doScrubToggled() 20 20 20 20 ltToggled() fwbuilder-5.1.0.3599/src/libgui/RuleSetViewDelegate.cpp0000644000175000017500000005246311733011756023427 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBSettings.h" #include "RuleSetViewDelegate.h" #include "RuleNode.h" #include "ColDesc.h" #include "FWObjectSelectionModel.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Interface.h" #include #include #include #include using namespace libfwbuilder; using namespace std; //////////////////////////////////////////////////////////////////////////// // RuleSetViewDelegate //////////////////////////////////////////////////////////////////////////// RuleSetViewDelegate::RuleSetViewDelegate(QObject *parent, FWObjectSelectionModel *selectionModel) : QItemDelegate(parent) { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::RuleSetViewDelegate"; this->sectionModel = selectionModel; } void RuleSetViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paint"; QStyleOptionViewItem newOpt = option; QFont font = st->getRulesFont(); newOpt.font = font; RuleNode * node; if (index.isValid()) { node = static_cast(index.internalPointer()); } else { QItemDelegate::paint(painter, newOpt, index); return; } painter->save(); painter->setFont(font); if (node->type == RuleNode::Group) { paintGroup(painter, newOpt, index, node); } else if (index.column() == 0) { paintRowHeader(painter, newOpt, index, node); } else { paintRule(painter, newOpt, index, node); } painter->restore(); } /* * This paints the leftmost column in the rule set view (where rule * number appears) */ void RuleSetViewDelegate::paintRowHeader(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, RuleNode * node) const { Q_UNUSED(node); QStyleOptionViewItem newOpt = option; newOpt.displayAlignment = Qt::AlignRight; QItemDelegate::paint(painter, newOpt, index); painter->setPen( QColor("lightgray") ); painter->drawRect(option.rect); } void RuleSetViewDelegate::paintGroup(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, RuleNode * node) const { Q_UNUSED(node); //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paintGroup"; painter->fillRect(option.rect,QColor("lightgray")); QItemDelegate::paint(painter, option, index); } void RuleSetViewDelegate::drawIcons(QPainter *painter, QRect rect, const QStringList &icons) const { int x = rect.left(); int y = rect.top(); int iconWidth = 0; for (int i=0; idrawPixmap(x, y, pm); iconWidth = pm.width(); x += iconWidth + ICON_TEXT_GAP; } } void RuleSetViewDelegate::drawIconAndText(QPainter *painter, QRect rect, QString icon, QString text, bool negation) const { int x = rect.left(); int y = rect.top(); int iconWidth = 0; if (st->getShowIconsInRules()) { if (!icon.isEmpty()) { QPixmap pm; LoadPixmap(calculateIconName(icon, negation), pm); painter->drawPixmap(x,y,pm); iconWidth = pm.width(); } else { if (FWBSettings::SIZE25X25 == st->getIconsInRulesSize()) iconWidth = 25; else iconWidth = 16; } x += iconWidth + ICON_TEXT_GAP; } if (!text.isEmpty()) { painter->drawText(x, y, rect.width() - iconWidth - ICON_TEXT_GAP, rect.height(), Qt::AlignLeft|Qt::AlignVCenter, text ); } } void RuleSetViewDelegate::drawSelectedFocus(QPainter *painter, const QStyleOptionViewItem &option, QRect &rect) const { if (option.state & QStyle::State_HasFocus) { painter->fillRect(rect, option.palette.brush( QPalette::Highlight )); painter->setPen( option.palette.highlightedText().color() ); } else { painter->setPen( option.palette.text().color() ); } } void RuleSetViewDelegate::paintRule(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, RuleNode * node) const { QVariant v = index.data(Qt::DisplayRole); if (!v.isValid()) return; if (node != 0) { FWOptions *ropt = node->rule->getOptionsObject(); QString color = ropt->getStr("color").c_str(); if (!color.isEmpty()) { painter->fillRect(option.rect, QColor(color)); } else { if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.color(QPalette::Highlight)); } } } QStyleOptionViewItem new_opt = option; new_opt.palette.setColor(QPalette::Highlight, standard_highlight); ColDesc colDesc = index.data(Qt::UserRole).value(); switch (colDesc.type) { case ColDesc::Object : paintObject(painter, new_opt, v); break; case ColDesc::Direction : paintDirection(painter, new_opt, v); break; case ColDesc::Action : paintAction(painter, new_opt, v); break; case ColDesc::Time : paintObject(painter, new_opt, v); break; case ColDesc::Options : paintOptions(painter, new_opt, v); break; case ColDesc::Comment : paintComment(painter, new_opt, v); break; case ColDesc::Metric : paintMetric(painter, new_opt, v); break; default: QItemDelegate::paint(painter, new_opt, index); } painter->setPen( QColor("lightgray") ); painter->drawRect(new_opt.rect); } void RuleSetViewDelegate::paintDirection( QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paintDirection"; DrawingContext ctx = initContext(option.rect, true); // useEnireSpace=true QString dir = v.value(); if (option.state & QStyle::State_Selected) drawSelectedFocus(painter, option, ctx.objectRect); QString text = (st->getShowDirectionText())?dir:""; ctx = initContext(option.rect, false); // useEnireSpace=false drawIconAndText(painter, ctx.drawRect, dir, text); } void RuleSetViewDelegate::paintAction( QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paintAction"; DrawingContext ctx = initContext(option.rect, true); // useEnireSpace=true ActionDesc actionDesc = v.value(); if (option.state & QStyle::State_Selected) drawSelectedFocus(painter, option, ctx.objectRect); QString text = constructActionText(actionDesc); ctx = initContext(option.rect, false); // useEnireSpace=false drawIconAndText(painter, ctx.drawRect, actionDesc.name, text); } void RuleSetViewDelegate::paintOptions( QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const { DrawingContext ctx = initContext(option.rect, true); // useEnireSpace=true if (option.state & QStyle::State_Selected) drawSelectedFocus(painter, option, ctx.objectRect); QStringList icons = v.value(); // draw option icons vertically instead of horizontally #2367 // for options "Tag", "Classify" and "Route" the "icon name" actually // consists of the name of the icon, plus space and parameter int y = ctx.objectRect.top(); foreach(QString icon, icons) { QRect itemRect = QRect(ctx.objectRect.left(), y, ctx.objectRect.width(), ctx.itemHeight); QString parameter = icon.section(" ", 1); if (icon.contains("Log")) parameter = tr("log"); if (icon.contains("Options")) parameter = tr("(options)"); drawIconAndText(painter, itemRect.adjusted( HORIZONTAL_MARGIN, VERTICAL_MARGIN, -HORIZONTAL_MARGIN, -VERTICAL_MARGIN), icon, parameter, false); y += ctx.itemHeight; } } void RuleSetViewDelegate::paintComment( QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paintComment"; DrawingContext ctx = initContext(option.rect, true); QString comment = v.value(); if (option.state & QStyle::State_Selected) drawSelectedFocus(painter, option, ctx.objectRect); painter->drawText( ctx.drawRect, Qt::AlignLeft|Qt::AlignTop, comment); } void RuleSetViewDelegate::paintMetric( QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paintMetric"; DrawingContext ctx = initContext(option.rect, true); QString metric = v.value(); if (option.state & QStyle::State_Selected) drawSelectedFocus(painter, option, ctx.objectRect); ctx = initContext(option.rect, false); // useEnireSpace=false drawIconAndText(painter, ctx.drawRect, QString(), metric); } void RuleSetViewDelegate::paintObject( QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const { //if (fwbdebug) qDebug() << "RuleSetViewDelegate::paintObject"; RuleElement *re = (RuleElement *)v.value(); if (re==NULL) return; DrawingContext ctx = initContext(option.rect, true); int y = ctx.objectRect.top(); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o1 = FWReference::getObject(*i); if (o1==NULL) continue ; QRect itemRect = QRect(ctx.objectRect.left(), y, ctx.objectRect.width(), ctx.itemHeight); if (sectionModel->selectedObject == o1) { drawSelectedFocus(painter, option, itemRect); } else { painter->setPen( option.palette.text().color() ); } QString icon; if (!re->isAny()) icon = QString(o1->getTypeName().c_str()); // + "/icon"; QString text = objectText(re, o1); drawIconAndText(painter, itemRect.adjusted(HORIZONTAL_MARGIN, VERTICAL_MARGIN, -HORIZONTAL_MARGIN, -VERTICAL_MARGIN), icon, text, re->getNeg()); if ((sectionModel->selectedObject == o1) && !(option.state & QStyle::State_HasFocus) && !re->isAny()) { painter->setPen( QColor("red") ); painter->drawRect(itemRect.left()+1, itemRect.top()+1, itemRect.width()-2, itemRect.height()-2); } y += ctx.itemHeight; } } QSize RuleSetViewDelegate::drawIconInRule( QPainter *p, int x, int y, QString name, bool neg) const { if (!st->getShowIconsInRules()) return QSize(); QPixmap pm; if (FWBSettings::SIZE16X16 == st->getIconsInRulesSize()) { if (!neg) { pm = getPixmap(name, Tree); } else { pm = getPixmap(name, NegTree); } } if (FWBSettings::SIZE25X25 == st->getIconsInRulesSize()) { if (!neg) { pm = getPixmap(name, Normal); } else { pm = getPixmap(name, Neg); } } p->drawPixmap( x, y + RULE_ITEM_GAP/2, pm ); return pm.size(); } QPixmap RuleSetViewDelegate::getPixmap(QString name, PixmapAttr pmattr) const { string icn = "icon"; if (pmattr == Neg) icn="icon-neg"; if (pmattr == Ref) icn="icon-ref"; if (pmattr == Tree) icn="icon-tree"; if (pmattr == NegTree) icn="icon-neg-tree"; QString icn_file = ":/Icons/" + name + "/" + icn.c_str(); QPixmap pm; LoadPixmap(icn_file, pm); return pm; } QSize RuleSetViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { QStyleOptionViewItem newOpt = option; QFont font = st->getRulesFont(); newOpt.font = font; QSize res; RuleNode * node; if (index.isValid()) { node = static_cast(index.internalPointer()); } else { return QItemDelegate::sizeHint(newOpt, index); } if (node->type == RuleNode::Rule) { if (node->sizes[index.column()].isValid()) { return node->sizes[index.column()]; } res = calculateCellSizeForRule(newOpt, index, node) + QSize(1,1); node->sizes[index.column()] = res; // make sure cell height is equal to max height of all cells // in the same row. See #2665 QSize tallest_cell = QSize(0, 0); for (unsigned int c=0; c<=index.column(); ++c) { QSize cell_size = node->sizes[c]; if (cell_size.isValid()) { int max_height = qMax(tallest_cell.height(), cell_size.height()); tallest_cell.setHeight(max_height); node->sizes[c].setHeight(max_height); } } return res; } //Fix for older Qt versions where width of spanned column is taken into accoun res = QItemDelegate::sizeHint(newOpt, index); res.setWidth(20); return res; } int RuleSetViewDelegate::getItemHeight(QString s, int flag, bool text) { QSize iconSize = getIconSize(); QSize textSize = text?getTextSize(s,flag):QSize(0,0); return qMax(iconSize.height(), textSize.height()) + 2*VERTICAL_MARGIN; } QSize RuleSetViewDelegate::getIconSize() { if (st->getShowIconsInRules()) { if (FWBSettings::SIZE16X16 == st->getIconsInRulesSize()) return QSize(16,16); if (FWBSettings::SIZE25X25 == st->getIconsInRulesSize()) return QSize(25,25); } return QSize(); } QSize RuleSetViewDelegate::getTextSize(QString s, int flag) { QFontMetrics fontMetrics(st->getRulesFont()); return fontMetrics.size(flag,s); } QSize RuleSetViewDelegate::calculateCellSizeForRule( const QStyleOptionViewItem & option, const QModelIndex & index, RuleNode * node ) const { Q_UNUSED(option); Q_UNUSED(node); QSize iconSize = getIconSize(); int itemHeight = getItemHeight(); QSize result = QSize(50,itemHeight); ColDesc colDesc = index.data(Qt::UserRole).value(); QSize calculated; switch (colDesc.type) { case ColDesc::Object : calculated = calculateCellSizeForObject(index); break; case ColDesc::Time : calculated = calculateCellSizeForObject(index); break; case ColDesc::Comment : calculated = calculateCellSizeForComment(index); break; case ColDesc::Action : calculated = calculateCellSizeForIconAndText(index); break; case ColDesc::Direction : calculated = calculateCellSizeForIconAndText(index); break; case ColDesc::Options : calculated = calculateCellSizeForOptions(index); break; default : calculated = QSize(0,0); } result = result.expandedTo(calculated); return result; } QSize RuleSetViewDelegate::calculateCellSizeForComment(const QModelIndex & index) const { QString text = index.data(Qt::DisplayRole).value(); if (text.isNull() && text.isEmpty()) return QSize(0,0); QSize res = getTextSize(text, 0); if (st->getClipComment()) res.setHeight(0); return res + QSize(10, 0); } QSize RuleSetViewDelegate::calculateCellSizeForObject(const QModelIndex & index) const { RuleElement *re = (RuleElement *)index.data(Qt::DisplayRole).value(); if (re == 0) return QSize(0,0); int itemHeight = getItemHeight(); QSize iconSize = getIconSize(); int h = 0; int w = 0; for (FWObject::iterator j=re->begin(); j!=re->end(); j++) { FWObject *o1= *j; FWObject *o2 = o1; string o1ref = ""; if (FWReference::cast(o1)!=NULL) { o1ref = FWReference::cast(o1)->getPointerId(); o2=FWReference::cast(o1)->getPointer(); } if (o2!=NULL) { QString ot = objectText(re,o2); QSize size = getTextSize(ot,Qt::TextSingleLine); h += itemHeight; w = qMax(w,iconSize.width() + size.width()+ICON_TEXT_GAP); } } QSize res = QSize(w+HORIZONTAL_MARGIN*2,h); QModelIndex idx = index; return res; } QString RuleSetViewDelegate::constructActionText(ActionDesc &actionDesc) const { QString text; if (st->getShowDirectionText()) { text = actionDesc.displayName + (actionDesc.argument.isEmpty()?"":(":"+actionDesc.argument)); } else if (!actionDesc.argument.isEmpty()) { text = actionDesc.argument; } if (text.length() > 20) text = text.left(17) + "..."; return text; } QSize RuleSetViewDelegate::calculateCellSizeForIconAndText( const QModelIndex & index) const { QVariant v = index.data(Qt::DisplayRole); ActionDesc actionDesc = v.value(); QString text = constructActionText(actionDesc); if (text == "Undefined") text = "Both"; QSize iconSize = getIconSize(); QSize textSize = getTextSize(text,Qt::TextSingleLine); int h = qMax(iconSize.height(), textSize.height()); int w = iconSize.width() + ICON_TEXT_GAP + textSize.width() + HORIZONTAL_MARGIN*2; return QSize(w, h); } QSize RuleSetViewDelegate::calculateCellSizeForOptions( const QModelIndex & index) const { QVariant v = index.data(Qt::DisplayRole); QStringList icons = v.value(); // for options "Tag", "Classify" and "Route" the "icon name" actually // consists of the name of the icon, plus space and parameter int itemHeight = getItemHeight(); QSize iconSize = getIconSize(); int h = 0; int w = 0; foreach(QString icon, icons) { QString parameter = icon.section(" ", 1); QSize size = getTextSize(parameter, Qt::TextSingleLine); h += itemHeight; w = qMax(w, iconSize.width() + size.width() + ICON_TEXT_GAP); } return QSize(w+HORIZONTAL_MARGIN*2, h); } QString RuleSetViewDelegate::objectText(RuleElement *re,FWObject *obj) const { QString any_object_name = QString(tr("Any")); if (re->isAny()) { if (RuleElementTSrc::isA(re) || RuleElementTDst::isA(re) || RuleElementTSrv::isA(re)) return QString(tr("Original")); if (RuleElementRDst::isA(re)) return QString(tr("Default")); if (RuleElementRGtw::isA(re) || RuleElementRItf::isA(re)) return QString(""); if (RuleElementItfInb::isA(re)) return QString(tr("Auto")); if (RuleElementItfOutb::isA(re)) return QString(tr("Auto")); return any_object_name; } if (Interface::isA(obj)) { QString lbl= Interface::cast(obj)->getLabel().c_str(); if ( !lbl.isEmpty() ) return lbl; } if (obj->getName() == "Any") return any_object_name; else return QString::fromUtf8(obj->getName().c_str()); } DrawingContext RuleSetViewDelegate::initContext( QRect rect, bool useEnireSpace) const { DrawingContext ctx; ctx.iconSize = getIconSize(); ctx.itemHeight = getItemHeight(); ctx.objectRect = QRect(rect.left()+1, rect.top()+1, rect.width()-1, useEnireSpace?rect.height()-1:ctx.itemHeight); ctx.drawRect = ctx.objectRect.adjusted(HORIZONTAL_MARGIN, VERTICAL_MARGIN, -HORIZONTAL_MARGIN, -VERTICAL_MARGIN); return ctx; } fwbuilder-5.1.0.3599/src/libgui/FirewallInstaller.h0000644000175000017500000000645311733011756022644 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FIREWALLINSTALLER_H_ #define __FIREWALLINSTALLER_H_ #include "config.h" #include "instConf.h" #include "instDialog.h" #include "Configlet.h" #include #include #include #include #include #include #include #include class SSHSession; class instDialog; namespace libfwbuilder { class Firewall; } enum instJobType {COPY_FILE, EXECUTE_COMMAND, ACTIVATE_POLICY, RUN_EXTERNAL_SCRIPT}; class instJob { public: instJobType job; QString argument1; QString argument2; instJob(instJobType jt, const QString &a1, const QString &a2) { job = jt; argument1 = a1; argument2 = a2; } }; class FirewallInstaller : public QObject { Q_OBJECT protected: instDialog *inst_dlg; instConf *cnf; QProcess proc; // session is used when we run built-in installer SSHSession *session; std::list job_list; QString fwb_prompt; void runSSHSession(SSHSession *s, bool intermediate=false); QString getFullPath(const QString &file ); bool parseManifestLine(const QString &line, QString *local_file_name, QString *remote_file_name, bool *main_script); void executeExternalInstallScript(const QString &script, const QString &script_args); public: FirewallInstaller(instDialog *_dlg, instConf *_cnf, const QString &prompt) { inst_dlg = _dlg; cnf = _cnf; fwb_prompt = prompt; session = NULL; } void packSSHArgs(QStringList &args); void packSCPArgs(const QString &local_name, const QString &remote_name, QStringList &args); QString getActivationCmd(); void replaceMacrosInCommand(Configlet *configlet); virtual QString getDestinationDir(const QString &dir); void terminate(); virtual bool packInstallJobsList(libfwbuilder::Firewall*); virtual void copyFile(const QString &local_name, const QString &remote_name); virtual void executeCommand(const QString &cmd); virtual void activatePolicy(const QString &script, const QString &args); static QString getGeneratedFileFullPath(libfwbuilder::Firewall *fw); static QString getGeneratedFileName(libfwbuilder::Firewall *fw); virtual bool readManifest(const QString &conffie, QMap *all_files); public slots: void runJobs(); }; #endif fwbuilder-5.1.0.3599/src/libgui/SimpleIntEditor.cpp0000644000175000017500000000357511733011756022631 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "global.h" #include "SimpleIntEditor.h" #include "FWBSettings.h" #include #include #include #include using namespace std; SimpleIntEditor::SimpleIntEditor(int minValue, int maxValue, int value, const QString &title): QDialog() { m_dialog = new Ui::SimpleIntEditor_q; m_dialog->setupUi(static_cast(this)); if (!title.isEmpty()) setWindowTitle(title); m_dialog->spin_box->setMinimum( minValue); m_dialog->spin_box->setMaximum( maxValue); m_dialog->spin_box->setValue( value); } int SimpleIntEditor::value() { return m_dialog->spin_box->value(); } fwbuilder-5.1.0.3599/src/libgui/TutorialDialog.cpp0000644000175000017500000000701111733011756022466 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "TutorialDialog.h" #include "ui_TutorialDialog.h" #include #include #include "FWBApplication.h" TutorialDialog * TutorialDialog::dialog = NULL; TutorialDialog::TutorialDialog(QString tutorial, QWidget *parent) : QDialog(NULL), ui(new Ui::TutorialDialog_q) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint); #if QT_VERSION >= 0x040500 setWindowFlags(windowFlags() | Qt::WindowCloseButtonHint); #endif ui->contents->setOpenExternalLinks(true); dialog = this; this->initializeTutorial(tutorial); } void TutorialDialog::showTutorial(QString tutorial) { if (dialog != NULL) { dialog->initializeTutorial(tutorial); dialog->showNormal(); dialog->raise(); } else { (new TutorialDialog(tutorial))->show(); } } void TutorialDialog::initializeTutorial(QString tutorial) { this->tutorial = tutorial; doc = new QTextDocument(this); QString stylefile = QString(":/Tutorial/") + this->tutorial + "/stylesheets/style.css"; QFile f(stylefile); if (f.exists()) { f.open(QFile::ReadOnly); css_stylesheet = f.readAll(); doc->setDefaultStyleSheet(css_stylesheet); //ui->contents->setStyleSheet(stylesheet); } ui->contents->setDocument(doc); currentPage = 0; showPage(currentPage); } TutorialDialog::~TutorialDialog() { delete ui; } void TutorialDialog::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void TutorialDialog::next() { currentPage++; showPage(currentPage); } void TutorialDialog::previous() { currentPage--; showPage(currentPage); } void TutorialDialog::reset() { currentPage = 0; showPage(currentPage); } void TutorialDialog::showPage(int page) { QString filename = QString(":/Tutorial/") + this->tutorial + "/html/page" + QString::number(page) + ".html"; if (fwbdebug) qDebug() << filename; QFile src(filename); src.open(QFile::ReadOnly); QString text = src.readAll(); doc->setHtml(text); ui->contents->scrollToAnchor("top"); bool nextPageExists = QFile::exists(QString(":/Tutorial/") + this->tutorial + "/html/page" + QString::number(page+1) + ".html"); bool prevPageExists = QFile::exists(QString(":/Tutorial/") + this->tutorial + "/html/page" + QString::number(page-1) + ".html"); ui->next->setEnabled(nextPageExists); ui->prev->setEnabled(prevPageExists); } fwbuilder-5.1.0.3599/src/libgui/bsdifaceoptsdialog_q.ui0000644000175000017500000002403211733011756023546 0ustar sylvestresylvestre bsdIfaceOptsDialog_q 0 0 376 318 BSD: interface settings Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 :/Icons/Options:/Icons/Options Options Qt::Vertical QSizePolicy::Fixed 20 16 Qt::RightToLeft Device Type Qt::Horizontal 40 20 Set MTU to 1 9000 1500 Qt::Horizontal 147 20 Qt::RightToLeft Options additional arguments for ifconfig 0 0 3 true Qt::RightToLeft VLAN ID 4095 Qt::Horizontal 140 20 Qt::Vertical 20 43 Enable STP Qt::Vertical 20 173 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() bsdIfaceOptsDialog_q accept() 316 472 20 20 buttonCancel clicked() bsdIfaceOptsDialog_q reject() 397 472 20 20 buttonHelp clicked() bsdIfaceOptsDialog_q help() 68 464 231 245 iface_type currentIndexChanged(QString) bsdIfaceOptsDialog_q typeChanged(QString) 287 196 286 261 typeChanged(QString) fwbuilder-5.1.0.3599/src/libgui/FWBAboutDialog.h0000644000175000017500000000225711733011756021750 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ABOUTDIALOG_H_ #define __ABOUTDIALOG_H_ #ifndef ABOUT_DLG_BLANKS #define ABOUT_DLG_BLANKS #endif #include class FWBAboutDialog: public QDialog { Q_OBJECT Ui::AboutDialog_q *m_aboutDialog; void fillTheBlanks(); public: FWBAboutDialog(QWidget *parent); ~FWBAboutDialog(); }; #endif fwbuilder-5.1.0.3599/src/libgui/TextEditWidget.cpp0000644000175000017500000000512711733011756022447 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "TextEditWidget.h" #include #include TextEditWidget::TextEditWidget(QWidget *parent) : QTextEdit(parent) { modified = false; showingDefault = false; connect(this, SIGNAL(undoAvailable(bool)), this, SLOT(dirty(bool))); } void TextEditWidget::dirty(bool f) { modified = f; // if undo is available, the widget has some changed text. } void TextEditWidget::focusInEvent(QFocusEvent * event) { hasFocus = true; QTextEdit::focusInEvent(event); if (showingDefault && !isReadOnly()) { clear(); showingDefault = false; } } void TextEditWidget::focusOutEvent(QFocusEvent * event) { hasFocus = false; QTextEdit::focusOutEvent(event); if (modified) emit textChanged(); // newTextAvailable(); if (toPlainText().isEmpty()) { showingDefault = true; setText(defaultText); } } void TextEditWidget::setTextDefault(const QString &text, const QString &theDefault) { /* Sometimes the text area gets left in italics mode. */ setFontItalic(false); defaultText = theDefault; if (text.isEmpty() && !hasFocus) { setText(theDefault); showingDefault = true; } else { /* We can get a setTextDefault call when the object is being reloaded, but after focus has been set on the text edit field. If it's the same text we're setting (which it should be), we skip setting it so that we don't lose the proper place where the user clicked. */ if (!hasFocus || getText() != text) { setText(text); } showingDefault = false; } } QString TextEditWidget::getText() { if (!modified && showingDefault) return ""; return toPlainText(); } fwbuilder-5.1.0.3599/src/libgui/LibExportDialog.h0000644000175000017500000000257411733011756022251 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LIBEXPORTDIALOG_H_ #define __LIBEXPORTDIALOG_H_ #include #include #include #include class RCSFilePreview; namespace libfwbuilder { class FWObject; class FWReference; }; class LibExportDialog : public QDialog{ Q_OBJECT void init(); public: std::map mapOfLibs; LibExportDialog(QWidget* parent=0, const char* name=0, bool modal = FALSE ); ~LibExportDialog(); Ui::LibExport_q *m_dialog; protected slots: }; #endif fwbuilder-5.1.0.3599/src/libgui/projectpanel_q.ui0000644000175000017500000002641211733011756022412 0ustar sylvestresylvestre ProjectPanel_q 0 0 835 494 Form :/Images/fwbuilder3.png:/Images/fwbuilder3.png 2 Qt::Horizontal false 150 0 QFrame::NoFrame QFrame::Plain 0 0 0 0 10 20 16777215 16777215 20 0 QFrame::NoFrame QFrame::Raised 2 2 0 0 2 0 0 Insert rule Insert rule Insert rule ... :/Icons/add.png:/Icons/add.png 25 25 false QToolButton::DelayedPopup Qt::NoArrow Qt::Horizontal QSizePolicy::Fixed 10 20 14 50 false false Firewall / ruleset Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 20 20 Compile this firewall Compile this firewall Compile this firewall ... :/Icons/Compile:/Icons/Compile 25 25 false QToolButton::DelayedPopup Qt::NoArrow Compile and install this firewall Compile and install this firewall Compile and install this firewall ... :/Icons/Install:/Icons/Install 25 25 Inspect generated files Inspect generated files Inspect generated files ... :/Icons/Inspect:/Icons/Inspect 25 25 0 ObjectManipulator QWidget
ObjectManipulator.h
1
WorkflowIcons QWidget
WorkflowIcons.h
1
compile_this_fw clicked() ProjectPanel_q compileThis() 276 35 417 246 install_this_fw clicked() ProjectPanel_q installThis() 319 35 417 246 add_rule clicked() ProjectPanel_q addRule() 211 27 417 246 inspect_this_fw clicked() ProjectPanel_q inspectThis() 345 22 417 246 compileThis() installThis() addRule() inspectThis()
fwbuilder-5.1.0.3599/src/libgui/valgrind.h0000644000175000017500000070560211733011756021031 0ustar sylvestresylvestre/* -*- c -*- ---------------------------------------------------------------- Notice that the following BSD-style license applies to this one file (valgrind.h) only. The rest of Valgrind is licensed under the terms of the GNU General Public License, version 2, unless otherwise indicated. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- This file is part of Valgrind, a dynamic binary instrumentation framework. Copyright (C) 2000-2008 Julian Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------- Notice that the above BSD-style license applies to this one file (valgrind.h) only. The entire rest of Valgrind is licensed under the terms of the GNU General Public License, version 2. See the COPYING file in the source distribution for details. ---------------------------------------------------------------- */ /* This file is for inclusion into client (your!) code. You can use these macros to manipulate and query Valgrind's execution inside your own programs. The resulting executables will still run without Valgrind, just a little bit more slowly than they otherwise would, but otherwise unchanged. When not running on valgrind, each client request consumes very few (eg. 7) instructions, so the resulting performance loss is negligible unless you plan to execute client requests millions of times per second. Nevertheless, if that is still a problem, you can compile with the NVALGRIND symbol defined (gcc -DNVALGRIND) so that client requests are not even compiled in. */ #ifndef __VALGRIND_H #define __VALGRIND_H #include /* Nb: this file might be included in a file compiled with -ansi. So we can't use C++ style "//" comments nor the "asm" keyword (instead use "__asm__"). */ /* Derive some tags indicating what the target platform is. Note that in this file we're using the compiler's CPP symbols for identifying architectures, which are different to the ones we use within the rest of Valgrind. Note, __powerpc__ is active for both 32 and 64-bit PPC, whereas __powerpc64__ is only active for the latter (on Linux, that is). */ #undef PLAT_x86_linux #undef PLAT_amd64_linux #undef PLAT_ppc32_linux #undef PLAT_ppc64_linux #undef PLAT_ppc32_aix5 #undef PLAT_ppc64_aix5 #if !defined(_AIX) && defined(__i386__) # define PLAT_x86_linux 1 #elif !defined(_AIX) && defined(__x86_64__) # define PLAT_amd64_linux 1 #elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__) # define PLAT_ppc32_linux 1 #elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__) # define PLAT_ppc64_linux 1 #elif defined(_AIX) && defined(__64BIT__) # define PLAT_ppc64_aix5 1 #elif defined(_AIX) && !defined(__64BIT__) # define PLAT_ppc32_aix5 1 #endif /* If we're not compiling for our target platform, don't generate any inline asms. */ #if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \ && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \ && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5) # if !defined(NVALGRIND) # define NVALGRIND 1 # endif #endif /* ------------------------------------------------------------------ */ /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ /* in here of use to end-users -- skip to the next section. */ /* ------------------------------------------------------------------ */ #if defined(NVALGRIND) /* Define NVALGRIND to completely remove the Valgrind magic sequence from the compiled code (analogous to NDEBUG's effects on assert()) */ #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { \ (_zzq_rlval) = (_zzq_default); \ } #else /* ! NVALGRIND */ /* The following defines the magic code sequences which the JITter spots and handles magically. Don't look too closely at them as they will rot your brain. The assembly code sequences for all architectures is in this one file. This is because this file must be stand-alone, and we don't want to have multiple files. For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default value gets put in the return slot, so that everything works when this is executed not under Valgrind. Args are passed in a memory block, and so there's no intrinsic limit to the number that could be passed, but it's currently five. The macro args are: _zzq_rlval result lvalue _zzq_default default value (result returned when running on real CPU) _zzq_request request code _zzq_arg1..5 request params The other two macros are used to support function wrapping, and are a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the guest's NRADDR pseudo-register and whatever other information is needed to safely run the call original from the wrapper: on ppc64-linux, the R2 value at the divert point is also needed. This information is abstracted into a user-visible type, OrigFn. VALGRIND_CALL_NOREDIR_* behaves the same as the following on the guest, but guarantees that the branch instruction will not be redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a complete inline asm, since it needs to be combined with more magic inline asm stuff to be useful. */ /* ------------------------- x86-linux ------------------------- */ #if defined(PLAT_x86_linux) typedef struct { unsigned int nraddr; /* where's the code? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "roll $3, %%edi ; roll $13, %%edi\n\t" \ "roll $29, %%edi ; roll $19, %%edi\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { volatile unsigned int _zzq_args[6]; \ volatile unsigned int _zzq_result; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %EDX = client_request ( %EAX ) */ \ "xchgl %%ebx,%%ebx" \ : "=d" (_zzq_result) \ : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ volatile unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %EAX = guest_NRADDR */ \ "xchgl %%ecx,%%ecx" \ : "=a" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ } #define VALGRIND_CALL_NOREDIR_EAX \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* call-noredir *%EAX */ \ "xchgl %%edx,%%edx\n\t" #endif /* PLAT_x86_linux */ /* ------------------------ amd64-linux ------------------------ */ #if defined(PLAT_amd64_linux) typedef struct { unsigned long long int nraddr; /* where's the code? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { volatile unsigned long long int _zzq_args[6]; \ volatile unsigned long long int _zzq_result; \ _zzq_args[0] = (unsigned long long int)(_zzq_request); \ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %RDX = client_request ( %RAX ) */ \ "xchgq %%rbx,%%rbx" \ : "=d" (_zzq_result) \ : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ volatile unsigned long long int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %RAX = guest_NRADDR */ \ "xchgq %%rcx,%%rcx" \ : "=a" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ } #define VALGRIND_CALL_NOREDIR_RAX \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* call-noredir *%RAX */ \ "xchgq %%rdx,%%rdx\n\t" #endif /* PLAT_amd64_linux */ /* ------------------------ ppc32-linux ------------------------ */ #if defined(PLAT_ppc32_linux) typedef struct { unsigned int nraddr; /* where's the code? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned int _zzq_args[6]; \ unsigned int _zzq_result; \ unsigned int* _zzq_ptr; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ _zzq_ptr = _zzq_args; \ __asm__ volatile("mr 3,%1\n\t" /*default*/ \ "mr 4,%2\n\t" /*ptr*/ \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1\n\t" \ "mr %0,3" /*result*/ \ : "=b" (_zzq_result) \ : "b" (_zzq_default), "b" (_zzq_ptr) \ : "cc", "memory", "r3", "r4"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "cc", "memory", "r3" \ ); \ _zzq_orig->nraddr = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc32_linux */ /* ------------------------ ppc64-linux ------------------------ */ #if defined(PLAT_ppc64_linux) typedef struct { unsigned long long int nraddr; /* where's the code? */ unsigned long long int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ "rotldi 0,0,61 ; rotldi 0,0,51\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned long long int _zzq_args[6]; \ register unsigned long long int _zzq_result __asm__("r3"); \ register unsigned long long int* _zzq_ptr __asm__("r4"); \ _zzq_args[0] = (unsigned long long int)(_zzq_request); \ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ _zzq_ptr = _zzq_args; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1" \ : "=r" (_zzq_result) \ : "0" (_zzq_default), "r" (_zzq_ptr) \ : "cc", "memory"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ register unsigned long long int __addr __asm__("r3"); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2" \ : "=r" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ "or 4,4,4" \ : "=r" (__addr) \ : \ : "cc", "memory" \ ); \ _zzq_orig->r2 = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc64_linux */ /* ------------------------ ppc32-aix5 ------------------------- */ #if defined(PLAT_ppc32_aix5) typedef struct { unsigned int nraddr; /* where's the code? */ unsigned int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned int _zzq_args[7]; \ register unsigned int _zzq_result; \ register unsigned int* _zzq_ptr; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ _zzq_args[6] = (unsigned int)(_zzq_default); \ _zzq_ptr = _zzq_args; \ __asm__ volatile("mr 4,%1\n\t" \ "lwz 3, 24(4)\n\t" \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1\n\t" \ "mr %0,3" \ : "=b" (_zzq_result) \ : "b" (_zzq_ptr) \ : "r3", "r4", "cc", "memory"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ register unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ "or 4,4,4\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->r2 = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc32_aix5 */ /* ------------------------ ppc64-aix5 ------------------------- */ #if defined(PLAT_ppc64_aix5) typedef struct { unsigned long long int nraddr; /* where's the code? */ unsigned long long int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ "rotldi 0,0,61 ; rotldi 0,0,51\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ { unsigned long long int _zzq_args[7]; \ register unsigned long long int _zzq_result; \ register unsigned long long int* _zzq_ptr; \ _zzq_args[0] = (unsigned int long long)(_zzq_request); \ _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \ _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \ _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \ _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \ _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \ _zzq_args[6] = (unsigned int long long)(_zzq_default); \ _zzq_ptr = _zzq_args; \ __asm__ volatile("mr 4,%1\n\t" \ "ld 3, 48(4)\n\t" \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ "or 1,1,1\n\t" \ "mr %0,3" \ : "=b" (_zzq_result) \ : "b" (_zzq_ptr) \ : "r3", "r4", "cc", "memory"); \ _zzq_rlval = _zzq_result; \ } #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ register unsigned long long int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ "or 2,2,2\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ "or 4,4,4\n\t" \ "mr %0,3" \ : "=b" (__addr) \ : \ : "r3", "cc", "memory" \ ); \ _zzq_orig->r2 = __addr; \ } #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" #endif /* PLAT_ppc64_aix5 */ /* Insert assembly code for other platforms here... */ #endif /* NVALGRIND */ /* ------------------------------------------------------------------ */ /* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ /* ugly. It's the least-worst tradeoff I can think of. */ /* ------------------------------------------------------------------ */ /* This section defines magic (a.k.a appalling-hack) macros for doing guaranteed-no-redirection macros, so as to get from function wrappers to the functions they are wrapping. The whole point is to construct standard call sequences, but to do the call itself with a special no-redirect call pseudo-instruction that the JIT understands and handles specially. This section is long and repetitious, and I can't see a way to make it shorter. The naming scheme is as follows: CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} 'W' stands for "word" and 'v' for "void". Hence there are different macros for calling arity 0, 1, 2, 3, 4, etc, functions, and for each, the possibility of returning a word-typed result, or no result. */ /* Use these to write the name of your wrapper. NOTE: duplicates VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */ #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ _vgwZU_##soname##_##fnname #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ _vgwZZ_##soname##_##fnname /* Use this macro from within a wrapper function to collect the context (address and possibly other info) of the original function. Once you have that you can then use it in one of the CALL_FN_ macros. The type of the argument _lval is OrigFn. */ #define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) /* Derivatives of the main macros below, for calling functions returning void. */ #define CALL_FN_v_v(fnptr) \ do { volatile unsigned long _junk; \ CALL_FN_W_v(_junk,fnptr); } while (0) #define CALL_FN_v_W(fnptr, arg1) \ do { volatile unsigned long _junk; \ CALL_FN_W_W(_junk,fnptr,arg1); } while (0) #define CALL_FN_v_WW(fnptr, arg1,arg2) \ do { volatile unsigned long _junk; \ CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ do { volatile unsigned long _junk; \ CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) /* ------------------------- x86-linux ------------------------- */ #if defined(PLAT_x86_linux) /* These regs are trashed by the hidden call. No need to mention eax as gcc can already see that, plus causes gcc to bomb. */ #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $4, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $8, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $12, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $16, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $20, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $24, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $28, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $32, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $36, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $40, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ arg6,arg7,arg8,arg9,arg10, \ arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ "pushl 44(%%eax)\n\t" \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $44, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ arg6,arg7,arg8,arg9,arg10, \ arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ "pushl 48(%%eax)\n\t" \ "pushl 44(%%eax)\n\t" \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ "addl $48, %%esp\n" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_x86_linux */ /* ------------------------ amd64-linux ------------------------ */ #if defined(PLAT_amd64_linux) /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ "rdi", "r8", "r9", "r10", "r11" /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned long) == 8. */ /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ macros. In order not to trash the stack redzone, we need to drop %rsp by 128 before the hidden call, and restore afterwards. The nastyness is that it is only by luck that the stack still appears to be unwindable during the hidden call - since then the behaviour of any routine using this macro does not match what the CFI data says. Sigh. Why is this important? Imagine that a wrapper has a stack allocated local, and passes to the hidden call, a pointer to it. Because gcc does not know about the hidden call, it may allocate that local in the redzone. Unfortunately the hidden call may then trash it before it comes to use it. So we must step clear of the redzone, for the duration of the hidden call, to make it safe. Probably the same problem afflicts the other redzone-style ABIs too (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is self describing (none of this CFI nonsense) so at least messing with the stack pointer doesn't give a danger of non-unwindable stack. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ "addq $128,%%rsp\n\t" \ VALGRIND_CALL_NOREDIR_RAX \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $8, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $16, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $24, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 80(%%rax)\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $32, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 88(%%rax)\n\t" \ "pushq 80(%%rax)\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $40, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ "subq $128,%%rsp\n\t" \ "pushq 96(%%rax)\n\t" \ "pushq 88(%%rax)\n\t" \ "pushq 80(%%rax)\n\t" \ "pushq 72(%%rax)\n\t" \ "pushq 64(%%rax)\n\t" \ "pushq 56(%%rax)\n\t" \ "movq 48(%%rax), %%r9\n\t" \ "movq 40(%%rax), %%r8\n\t" \ "movq 32(%%rax), %%rcx\n\t" \ "movq 24(%%rax), %%rdx\n\t" \ "movq 16(%%rax), %%rsi\n\t" \ "movq 8(%%rax), %%rdi\n\t" \ "movq (%%rax), %%rax\n\t" /* target->%rax */ \ VALGRIND_CALL_NOREDIR_RAX \ "addq $48, %%rsp\n" \ "addq $128,%%rsp\n\t" \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_amd64_linux */ /* ------------------------ ppc32-linux ------------------------ */ #if defined(PLAT_ppc32_linux) /* This is useful for finding out about the on-stack stuff: extern int f9 ( int,int,int,int,int,int,int,int,int ); extern int f10 ( int,int,int,int,int,int,int,int,int,int ); extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); int g9 ( void ) { return f9(11,22,33,44,55,66,77,88,99); } int g10 ( void ) { return f10(11,22,33,44,55,66,77,88,99,110); } int g11 ( void ) { return f11(11,22,33,44,55,66,77,88,99,110,121); } int g12 ( void ) { return f12(11,22,33,44,55,66,77,88,99,110,121,132); } */ /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* These CALL_FN_ macros assume that on ppc32-linux, sizeof(unsigned long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-16\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,16\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ _argvec[10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-16\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,12(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,16\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ _argvec[10] = (unsigned long)arg10; \ _argvec[11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-32\n\t" \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,16(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,12(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,32\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)arg1; \ _argvec[2] = (unsigned long)arg2; \ _argvec[3] = (unsigned long)arg3; \ _argvec[4] = (unsigned long)arg4; \ _argvec[5] = (unsigned long)arg5; \ _argvec[6] = (unsigned long)arg6; \ _argvec[7] = (unsigned long)arg7; \ _argvec[8] = (unsigned long)arg8; \ _argvec[9] = (unsigned long)arg9; \ _argvec[10] = (unsigned long)arg10; \ _argvec[11] = (unsigned long)arg11; \ _argvec[12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "addi 1,1,-32\n\t" \ /* arg12 */ \ "lwz 3,48(11)\n\t" \ "stw 3,20(1)\n\t" \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,16(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,12(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,8(1)\n\t" \ /* args1-8 */ \ "lwz 3,4(11)\n\t" /* arg1->r3 */ \ "lwz 4,8(11)\n\t" \ "lwz 5,12(11)\n\t" \ "lwz 6,16(11)\n\t" /* arg4->r6 */ \ "lwz 7,20(11)\n\t" \ "lwz 8,24(11)\n\t" \ "lwz 9,28(11)\n\t" \ "lwz 10,32(11)\n\t" /* arg8->r10 */ \ "lwz 11,0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "addi 1,1,32\n\t" \ "mr %0,3" \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc32_linux */ /* ------------------------ ppc64-linux ------------------------ */ #if defined(PLAT_ppc64_linux) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned long) == 8. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)" /* restore tocptr */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-128\n\t" /* expand stack frame */ \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,128" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-128\n\t" /* expand stack frame */ \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,128" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-144\n\t" /* expand stack frame */ \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,144" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "addi 1,1,-144\n\t" /* expand stack frame */ \ /* arg12 */ \ "ld 3,96(11)\n\t" \ "std 3,136(1)\n\t" \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ "addi 1,1,144" /* restore frame */ \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc64_linux */ /* ------------------------ ppc32-aix5 ------------------------- */ #if defined(PLAT_ppc32_aix5) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* Expand the stack frame, copying enough info that unwinding still works. Trashes r3. */ #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ "addi 1,1,-" #_n_fr "\n\t" \ "lwz 3," #_n_fr "(1)\n\t" \ "stw 3,0(1)\n\t" #define VG_CONTRACT_FRAME_BY(_n_fr) \ "addi 1,1," #_n_fr "\n\t" /* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(64) \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(64) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(64) \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,60(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(64) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(72) \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,64(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,60(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(72) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "stw 2,-8(11)\n\t" /* save tocptr */ \ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(72) \ /* arg12 */ \ "lwz 3,48(11)\n\t" \ "stw 3,68(1)\n\t" \ /* arg11 */ \ "lwz 3,44(11)\n\t" \ "stw 3,64(1)\n\t" \ /* arg10 */ \ "lwz 3,40(11)\n\t" \ "stw 3,60(1)\n\t" \ /* arg9 */ \ "lwz 3,36(11)\n\t" \ "stw 3,56(1)\n\t" \ /* args1-8 */ \ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ "lwz 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "lwz 2,-8(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(72) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc32_aix5 */ /* ------------------------ ppc64-aix5 ------------------------- */ #if defined(PLAT_ppc64_aix5) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ /* These regs are trashed by the hidden call. */ #define __CALLER_SAVED_REGS \ "lr", "ctr", "xer", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" /* Expand the stack frame, copying enough info that unwinding still works. Trashes r3. */ #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ "addi 1,1,-" #_n_fr "\n\t" \ "ld 3," #_n_fr "(1)\n\t" \ "std 3,0(1)\n\t" #define VG_CONTRACT_FRAME_BY(_n_fr) \ "addi 1,1," #_n_fr "\n\t" /* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned long) == 8. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(128) \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(128) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(128) \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(128) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(144) \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(144) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ /* _argvec[0] holds current r2 across the call */ \ _argvec[1] = (unsigned long)_orig.r2; \ _argvec[2] = (unsigned long)_orig.nraddr; \ _argvec[2+1] = (unsigned long)arg1; \ _argvec[2+2] = (unsigned long)arg2; \ _argvec[2+3] = (unsigned long)arg3; \ _argvec[2+4] = (unsigned long)arg4; \ _argvec[2+5] = (unsigned long)arg5; \ _argvec[2+6] = (unsigned long)arg6; \ _argvec[2+7] = (unsigned long)arg7; \ _argvec[2+8] = (unsigned long)arg8; \ _argvec[2+9] = (unsigned long)arg9; \ _argvec[2+10] = (unsigned long)arg10; \ _argvec[2+11] = (unsigned long)arg11; \ _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ "mr 11,%1\n\t" \ VG_EXPAND_FRAME_BY_trashes_r3(512) \ "std 2,-16(11)\n\t" /* save tocptr */ \ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ VG_EXPAND_FRAME_BY_trashes_r3(144) \ /* arg12 */ \ "ld 3,96(11)\n\t" \ "std 3,136(1)\n\t" \ /* arg11 */ \ "ld 3,88(11)\n\t" \ "std 3,128(1)\n\t" \ /* arg10 */ \ "ld 3,80(11)\n\t" \ "std 3,120(1)\n\t" \ /* arg9 */ \ "ld 3,72(11)\n\t" \ "std 3,112(1)\n\t" \ /* args1-8 */ \ "ld 3, 8(11)\n\t" /* arg1->r3 */ \ "ld 4, 16(11)\n\t" /* arg2->r4 */ \ "ld 5, 24(11)\n\t" /* arg3->r5 */ \ "ld 6, 32(11)\n\t" /* arg4->r6 */ \ "ld 7, 40(11)\n\t" /* arg5->r7 */ \ "ld 8, 48(11)\n\t" /* arg6->r8 */ \ "ld 9, 56(11)\n\t" /* arg7->r9 */ \ "ld 10, 64(11)\n\t" /* arg8->r10 */ \ "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ "mr 11,%1\n\t" \ "mr %0,3\n\t" \ "ld 2,-16(11)\n\t" /* restore tocptr */ \ VG_CONTRACT_FRAME_BY(144) \ VG_CONTRACT_FRAME_BY(512) \ : /*out*/ "=r" (_res) \ : /*in*/ "r" (&_argvec[2]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) #endif /* PLAT_ppc64_aix5 */ /* ------------------------------------------------------------------ */ /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ /* */ /* ------------------------------------------------------------------ */ /* Some request codes. There are many more of these, but most are not exposed to end-user view. These are the public ones, all of the form 0x1000 + small_number. Core ones are in the range 0x00000000--0x0000ffff. The non-public ones start at 0x2000. */ /* These macros are used by tools -- they must be public, but don't embed them into other programs. */ #define VG_USERREQ_TOOL_BASE(a,b) \ ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) #define VG_IS_TOOL_USERREQ(a, b, v) \ (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! This enum comprises an ABI exported by Valgrind to programs which use client requests. DO NOT CHANGE THE ORDER OF THESE ENTRIES, NOR DELETE ANY -- add new ones at the end. */ typedef enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, /* These allow any function to be called from the simulated CPU but run on the real CPU. Nb: the first arg passed to the function is always the ThreadId of the running thread! So CLIENT_CALL0 actually requires a 1 arg function, etc. */ VG_USERREQ__CLIENT_CALL0 = 0x1101, VG_USERREQ__CLIENT_CALL1 = 0x1102, VG_USERREQ__CLIENT_CALL2 = 0x1103, VG_USERREQ__CLIENT_CALL3 = 0x1104, /* Can be useful in regression testing suites -- eg. can send Valgrind's output to /dev/null and still count errors. */ VG_USERREQ__COUNT_ERRORS = 0x1201, /* These are useful and can be interpreted by any tool that tracks malloc() et al, by using vg_replace_malloc.c. */ VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, VG_USERREQ__FREELIKE_BLOCK = 0x1302, /* Memory pool support. */ VG_USERREQ__CREATE_MEMPOOL = 0x1303, VG_USERREQ__DESTROY_MEMPOOL = 0x1304, VG_USERREQ__MEMPOOL_ALLOC = 0x1305, VG_USERREQ__MEMPOOL_FREE = 0x1306, VG_USERREQ__MEMPOOL_TRIM = 0x1307, VG_USERREQ__MOVE_MEMPOOL = 0x1308, VG_USERREQ__MEMPOOL_CHANGE = 0x1309, VG_USERREQ__MEMPOOL_EXISTS = 0x130a, /* Allow printfs to valgrind log. */ VG_USERREQ__PRINTF = 0x1401, VG_USERREQ__PRINTF_BACKTRACE = 0x1402, /* Stack support. */ VG_USERREQ__STACK_REGISTER = 0x1501, VG_USERREQ__STACK_DEREGISTER = 0x1502, VG_USERREQ__STACK_CHANGE = 0x1503 } Vg_ClientRequest; #if !defined(__GNUC__) # define __extension__ /* */ #endif /* Returns the number of Valgrinds this code is running under. That is, 0 if running natively, 1 if running under Valgrind, 2 if running under Valgrind which is running under another Valgrind, etc. */ #define RUNNING_ON_VALGRIND __extension__ \ ({unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \ VG_USERREQ__RUNNING_ON_VALGRIND, \ 0, 0, 0, 0, 0); \ _qzz_res; \ }) /* Discard translation of code in the range [_qzz_addr .. _qzz_addr + _qzz_len - 1]. Useful if you are debugging a JITter or some such, since it provides a way to make sure valgrind will retranslate the invalidated area. Returns no value. */ #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DISCARD_TRANSLATIONS, \ _qzz_addr, _qzz_len, 0, 0, 0); \ } /* These requests are for getting Valgrind itself to print something. Possibly with a backtrace. This is a really ugly hack. */ #if defined(NVALGRIND) # define VALGRIND_PRINTF(...) # define VALGRIND_PRINTF_BACKTRACE(...) #else /* NVALGRIND */ /* Modern GCC will optimize the static routine out if unused, and unused attribute will shut down warnings about it. */ static int VALGRIND_PRINTF(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); static int VALGRIND_PRINTF(const char *format, ...) { unsigned long _qzz_res; va_list vargs; va_start(vargs, format); VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF, (unsigned long)format, (unsigned long)vargs, 0, 0, 0); va_end(vargs); return (int)_qzz_res; } static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) { unsigned long _qzz_res; va_list vargs; va_start(vargs, format); VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE, (unsigned long)format, (unsigned long)vargs, 0, 0, 0); va_end(vargs); return (int)_qzz_res; } #endif /* NVALGRIND */ /* These requests allow control to move from the simulated CPU to the real CPU, calling an arbitary function. Note that the current ThreadId is inserted as the first argument. So this call: VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) requires f to have this signature: Word f(Word tid, Word arg1, Word arg2) where "Word" is a word-sized type. Note that these client requests are not entirely reliable. For example, if you call a function with them that subsequently calls printf(), there's a high chance Valgrind will crash. Generally, your prospects of these working are made higher if the called function does not refer to any global variables, and does not refer to any libc or other functions (printf et al). Any kind of entanglement with libc or dynamic linking is likely to have a bad outcome, for tricky reasons which we've grappled with a lot in the past. */ #define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL0, \ _qyy_fn, \ 0, 0, 0, 0); \ _qyy_res; \ }) #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL1, \ _qyy_fn, \ _qyy_arg1, 0, 0, 0); \ _qyy_res; \ }) #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL2, \ _qyy_fn, \ _qyy_arg1, _qyy_arg2, 0, 0); \ _qyy_res; \ }) #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ __extension__ \ ({unsigned long _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__CLIENT_CALL3, \ _qyy_fn, \ _qyy_arg1, _qyy_arg2, \ _qyy_arg3, 0); \ _qyy_res; \ }) /* Counts the number of errors that have been recorded by a tool. Nb: the tool must record the errors with VG_(maybe_record_error)() or VG_(unique_error)() for them to be counted. */ #define VALGRIND_COUNT_ERRORS \ __extension__ \ ({unsigned int _qyy_res; \ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ VG_USERREQ__COUNT_ERRORS, \ 0, 0, 0, 0, 0); \ _qyy_res; \ }) /* Mark a block of memory as having been allocated by a malloc()-like function. `addr' is the start of the usable block (ie. after any redzone) `rzB' is redzone size if the allocator can apply redzones; use '0' if not. Adding redzones makes it more likely Valgrind will spot block overruns. `is_zeroed' indicates if the memory is zeroed, as it is for calloc(). Put it immediately after the point where a block is allocated. If you're using Memcheck: If you're allocating memory via superblocks, and then handing out small chunks of each superblock, if you don't have redzones on your small blocks, it's worth marking the superblock with VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are detected. But if you can put redzones on, it's probably better to not do this, so that messages for small overruns are described in terms of the small block rather than the superblock (but if you have a big overrun that skips over a redzone, you could miss an error this way). See memcheck/tests/custom_alloc.c for an example. WARNING: if your allocator uses malloc() or 'new' to allocate superblocks, rather than mmap() or brk(), this will not work properly -- you'll likely get assertion failures during leak detection. This is because Valgrind doesn't like seeing overlapping heap blocks. Sorry. Nb: block must be freed via a free()-like function specified with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */ #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MALLOCLIKE_BLOCK, \ addr, sizeB, rzB, is_zeroed, 0); \ } /* Mark a block of memory as having been freed by a free()-like function. `rzB' is redzone size; it must match that given to VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak checker. Put it immediately after the point where the block is freed. */ #define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__FREELIKE_BLOCK, \ addr, rzB, 0, 0, 0); \ } /* Create a memory pool. */ #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__CREATE_MEMPOOL, \ pool, rzB, is_zeroed, 0, 0); \ } /* Destroy a memory pool. */ #define VALGRIND_DESTROY_MEMPOOL(pool) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__DESTROY_MEMPOOL, \ pool, 0, 0, 0, 0); \ } /* Associate a piece of memory with a memory pool. */ #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_ALLOC, \ pool, addr, size, 0, 0); \ } /* Disassociate a piece of memory from a memory pool. */ #define VALGRIND_MEMPOOL_FREE(pool, addr) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_FREE, \ pool, addr, 0, 0, 0); \ } /* Disassociate any pieces outside a particular range. */ #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_TRIM, \ pool, addr, size, 0, 0); \ } /* Resize and/or move a piece associated with a memory pool. */ #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MOVE_MEMPOOL, \ poolA, poolB, 0, 0, 0); \ } /* Resize and/or move a piece associated with a memory pool. */ #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_CHANGE, \ pool, addrA, addrB, size, 0); \ } /* Return 1 if a mempool exists, else 0. */ #define VALGRIND_MEMPOOL_EXISTS(pool) \ ({unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__MEMPOOL_EXISTS, \ pool, 0, 0, 0, 0); \ _qzz_res; \ }) /* Mark a piece of memory as being a stack. Returns a stack id. */ #define VALGRIND_STACK_REGISTER(start, end) \ ({unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__STACK_REGISTER, \ start, end, 0, 0, 0); \ _qzz_res; \ }) /* Unmark the piece of memory associated with a stack id as being a stack. */ #define VALGRIND_STACK_DEREGISTER(id) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__STACK_DEREGISTER, \ id, 0, 0, 0, 0); \ } /* Change the start and end address of the stack id. */ #define VALGRIND_STACK_CHANGE(id, start, end) \ {unsigned int _qzz_res; \ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ VG_USERREQ__STACK_CHANGE, \ id, start, end, 0, 0); \ } #undef PLAT_x86_linux #undef PLAT_amd64_linux #undef PLAT_ppc32_linux #undef PLAT_ppc64_linux #undef PLAT_ppc32_aix5 #undef PLAT_ppc64_aix5 #endif /* __VALGRIND_H */ fwbuilder-5.1.0.3599/src/libgui/AskLibForCopyDialog.cpp0000644000175000017500000000642111733011756023336 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "AskLibForCopyDialog.h" #include "FWBSettings.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include using namespace std; using namespace libfwbuilder; FWObject *AskLibForCopyDialog::askLibForCopyDialog( QWidget *parent, libfwbuilder::FWObjectDatabase *db, libfwbuilder::FWObject *curr) { AskLibForCopyDialog dlg(parent, db, curr); if ( dlg.exec() == QDialog::Accepted ) return dlg.getChoosenLib(); return 0; } AskLibForCopyDialog::~AskLibForCopyDialog() { delete m_dialog; } AskLibForCopyDialog::AskLibForCopyDialog( QWidget *parent, FWObjectDatabase *db, libfwbuilder::FWObject *curr): QDialog(parent), m_db(db), m_curr(curr) { m_dialog = new Ui::asklibforcopydialog_q; m_dialog->setupUi(this); loadObjects(); } void AskLibForCopyDialog::loadObjects() { list ll = m_db->getByType( Library::TYPENAME ); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { FWObject *lib = (*i); if ((lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID && ! st->getBool("UI/ShowDeletedObjects"))|| lib->getId() == FWObjectDatabase::STANDARD_LIB_ID || lib->getId() == FWObjectDatabase::TEMPLATE_LIB_ID) continue; int ind = addLib( lib ); if (m_curr == lib) m_dialog->libs->setCurrentIndex(ind); } } int AskLibForCopyDialog::addLib( FWObject *lib) { QString newlibname = QString::fromUtf8(lib->getName().c_str()); int N = m_dialog->libs->count(); int idx = 0; vector::iterator i1=idxToLibs.begin(); //vector::iterator i2=idxToTrees.begin(); for ( ; idxlibs->itemText(idx) > newlibname ) break; string icn=":/Icons/"+lib->getTypeName()+"/icon-tree"; //Resources::global_res->getObjResourceStr(lib,"icon-tree").c_str(); QPixmap pm; if ( ! QPixmapCache::find( icn.c_str(), pm) ) { pm.load( icn.c_str() ); QPixmapCache::insert( icn.c_str(), pm); } m_dialog->libs->insertItem( idx, pm, newlibname); // idx=libs->count()-1; m_dialog->libs->setCurrentIndex(idx); idxToLibs.insert(i1,lib); return idx; } FWObject *AskLibForCopyDialog::getChoosenLib() { int ind = m_dialog->libs->currentIndex(); if (0 <= ind) return idxToLibs[ind]; return 0; } fwbuilder-5.1.0.3599/src/libgui/listOfLibrariesModel.h0000644000175000017500000000462011733011756023271 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LISTOFLIBRARIESMODEL_H_ #define __LISTOFLIBRARIESMODEL_H_ #include #include class ObjectTreeView; namespace libfwbuilder { class FWObject; }; class _item_data { public: QString name; libfwbuilder::FWObject* lib; ObjectTreeView* tree; _item_data(const QString &_n, libfwbuilder::FWObject* _lib, ObjectTreeView* _tree) { name = _n; lib = _lib; tree = _tree; } }; class ListOfLibrariesModel : public QStringListModel { Q_OBJECT; QStringList top_static_items; QList<_item_data> items; public: ListOfLibrariesModel(QObject *parent = 0); void addStaticItems(); QString indentLibName(const QString &name, bool indent); // virtual QModelIndex index(int, int, const QModelIndex &p = QModelIndex()) const; QModelIndex getIdxForLib(libfwbuilder::FWObject*); libfwbuilder::FWObject* getLibrary(QModelIndex idx); libfwbuilder::FWObject* getLibrary(int row); void setData(QModelIndex idx, const QString &name, libfwbuilder::FWObject *lib, ObjectTreeView *otv); void setName(QModelIndex idx, const QString &name); ObjectTreeView* getTreeWidget(QModelIndex idx); ObjectTreeView* getTreeWidget(int row); virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex()); virtual bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); }; #endif fwbuilder-5.1.0.3599/src/libgui/clustermembersdialog_q.ui0000644000175000017500000003062211733011756024136 0ustar sylvestresylvestre clusterMembersDialog_q Qt::WindowModal 0 0 859 556 cluster member configuration Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 :/Icons/Cluster/icon:/Icons/Cluster/icon Cluster Qt::Vertical QSizePolicy::Fixed 20 16 Manage member firewalls for this Cluster. Firewalls are considered valid members if they have the same host OS and platform as the Cluster object. They also need to have at minimum one physical interface attached. Qt::AlignCenter true Qt::Vertical QSizePolicy::Fixed 20 16 Available Firewalls: Tree of potential cluster members. Select an interface to assign to the cluster. QAbstractItemView::NoEditTriggers false false QAbstractItemView::ExtendedSelection QAbstractItemView::SelectRows Firewall Interface Label QFrame::NoFrame QFrame::Plain false ... :/Icons/big-right-arrow.png:/Icons/big-right-arrow.png false ... :/Icons/big-left-arrow.png:/Icons/big-left-arrow.png Qt::Vertical 20 40 Selected as Cluster-Members: true Table of already selected member firewalls with their assigned cluster interfaces. QAbstractItemView::NoEditTriggers false false true QAbstractItemView::SingleSelection QAbstractItemView::SelectRows Qt::ElideMiddle false false Name Interface Master buttonOk buttonCancel tabWidget buttonOk clicked() clusterMembersDialog_q accept() 316 472 20 20 buttonCancel clicked() clusterMembersDialog_q reject() 397 472 20 20 buttonHelp clicked() clusterMembersDialog_q help() 68 464 231 245 fwAvailableTree itemClicked(QTreeWidgetItem*,int) clusterMembersDialog_q availableClicked(QTreeWidgetItem*, int) 514 249 352 237 buttonAdd clicked() clusterMembersDialog_q firewallAdd() 352 179 352 237 buttonRemove clicked() clusterMembersDialog_q firewallRemove() 352 210 352 237 fwSelectedTable cellClicked(int,int) clusterMembersDialog_q selectedClicked(int,int) 191 249 352 237 fwSelectedTable cellChanged(int,int) clusterMembersDialog_q masterSelected(int,int) 191 272 352 237 fwbuilder-5.1.0.3599/src/libgui/DNSNameDialog.h0000644000175000017500000000255611733011756021566 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DNSNAMEDIALOG_H_ #define __DNSNAMEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class DNSNameDialog : public BaseObjectDialog { Q_OBJECT; Ui::DNSNameDialog_q *m_dialog; public: DNSNameDialog(QWidget *parent); ~DNSNameDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif fwbuilder-5.1.0.3599/src/libgui/FWBTree.cpp0000644000175000017500000006643011733011756021013 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include #include #include #include "FWBTree.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Library.h" #include "fwbuilder/NAT.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Routing.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include #include #include #include "utils.h" using namespace std; using namespace libfwbuilder; QStringList FWBTree::standardFolders; QSet FWBTree::standardIDs; QMap FWBTree::systemGroupTypes; QMap FWBTree::systemGroupNames; QMap FWBTree::systemGroupPaths; QMap FWBTree::copyMenuState; QMap FWBTree::cutMenuState; QMap FWBTree::pasteMenuState; QMap FWBTree::deleteMenuState; FWBTree::FWBTree() { init_statics(); } void FWBTree::init_statics() { if (systemGroupPaths.size() == 0) { // Names of the standard folders should be translatable. // Function isStandardFolder() takes this into account. standardFolders << "Objects"; standardFolders << "Objects/Addresses"; standardFolders << "Objects/DNS Names"; standardFolders << "Objects/Address Tables"; standardFolders << "Objects/Address Ranges"; standardFolders << "Objects/Groups"; standardFolders << "Objects/Hosts"; standardFolders << "Objects/Networks"; standardFolders << "Services"; standardFolders << "Services/Custom"; standardFolders << "Services/Groups"; standardFolders << "Services/IP"; standardFolders << "Services/ICMP"; standardFolders << "Services/TCP"; standardFolders << "Services/UDP"; standardFolders << "Services/TagServices"; standardFolders << "Services/Users"; standardFolders << "Firewalls"; standardFolders << "Clusters"; standardFolders << "Time"; systemGroupPaths[Library::TYPENAME] = ""; systemGroupPaths[IPv4::TYPENAME] = "Objects/Addresses"; systemGroupPaths[IPv6::TYPENAME] = "Objects/Addresses"; systemGroupPaths[DNSName::TYPENAME] = "Objects/DNS Names"; systemGroupPaths[AddressTable::TYPENAME] = "Objects/Address Tables"; systemGroupPaths[AddressRange::TYPENAME] = "Objects/Address Ranges"; systemGroupPaths[ObjectGroup::TYPENAME] = "Objects/Groups"; systemGroupPaths[DynamicGroup::TYPENAME] = "Objects/Groups"; systemGroupPaths[Host::TYPENAME] = "Objects/Hosts"; systemGroupPaths[Network::TYPENAME] = "Objects/Networks"; systemGroupPaths[NetworkIPv6::TYPENAME] = "Objects/Networks"; systemGroupPaths[ServiceGroup::TYPENAME] = "Services/Groups"; systemGroupPaths[CustomService::TYPENAME] = "Services/Custom"; systemGroupPaths[IPService::TYPENAME] = "Services/IP"; systemGroupPaths[ICMPService::TYPENAME] = "Services/ICMP"; systemGroupPaths[ICMP6Service::TYPENAME] = "Services/ICMP"; systemGroupPaths[TCPService::TYPENAME] = "Services/TCP"; systemGroupPaths[UDPService::TYPENAME] = "Services/UDP"; systemGroupPaths[UserService::TYPENAME] = "Services/Users"; systemGroupPaths[TagService::TYPENAME] = "Services/TagServices"; systemGroupPaths[Firewall::TYPENAME] = "Firewalls"; systemGroupPaths[Cluster::TYPENAME] = "Clusters"; systemGroupPaths[Interval::TYPENAME] = "Time"; systemGroupTypes[Firewall::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[Firewall::TYPENAME]= "Firewalls" ; systemGroupTypes[Cluster::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[Cluster::TYPENAME]= "Clusters"; systemGroupTypes[Host::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[Host::TYPENAME]= "Hosts" ; systemGroupTypes[Network::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[Network::TYPENAME]= "Networks" ; systemGroupTypes[NetworkIPv6::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[NetworkIPv6::TYPENAME]= "Networks" ; systemGroupTypes[IPv4::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[IPv4::TYPENAME]= "Addresses" ; systemGroupTypes[IPv6::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[IPv6::TYPENAME]= "Addresses" ; systemGroupTypes[DNSName::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[DNSName::TYPENAME]= "DNS Names" ; systemGroupTypes[AddressTable::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[AddressTable::TYPENAME]= "Address Tables" ; systemGroupTypes[AddressRange::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[AddressRange::TYPENAME]= "Address Ranges" ; systemGroupTypes[ObjectGroup::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[ObjectGroup::TYPENAME]= "Groups" ; systemGroupTypes[DynamicGroup::TYPENAME]= ObjectGroup::TYPENAME; systemGroupNames[DynamicGroup::TYPENAME]= "Groups" ; systemGroupTypes[CustomService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[CustomService::TYPENAME]= "Custom"; systemGroupTypes[IPService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[IPService::TYPENAME]= "IP" ; systemGroupTypes[ICMPService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[ICMPService::TYPENAME]= "ICMP" ; systemGroupTypes[ICMP6Service::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[ICMP6Service::TYPENAME]= "ICMP" ; systemGroupTypes[TCPService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[TCPService::TYPENAME]= "TCP" ; systemGroupTypes[UDPService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[UDPService::TYPENAME]= "UDP" ; systemGroupTypes[TagService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[TagService::TYPENAME]= "TagServices" ; systemGroupTypes[UserService::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[UserService::TYPENAME]= "Users" ; systemGroupTypes[ServiceGroup::TYPENAME]= ServiceGroup::TYPENAME; systemGroupNames[ServiceGroup::TYPENAME]= "Groups" ; systemGroupTypes[Interval::TYPENAME]= IntervalGroup::TYPENAME; systemGroupNames[Interval::TYPENAME]= "Time" ; systemGroupTypes[Interface::TYPENAME]= ""; systemGroupNames[Interface::TYPENAME]= ""; systemGroupTypes[Library::TYPENAME]= FWObjectDatabase::TYPENAME; systemGroupNames[Library::TYPENAME]= "FWObjectDatabase"; standardIDs.insert("syslib000"); standardIDs.insert("syslib001"); standardIDs.insert("sysid0"); standardIDs.insert("sysid1"); standardIDs.insert("sysid2"); standardIDs.insert("sysid99"); standardIDs.insert("stdid01"); standardIDs.insert("stdid01_1"); standardIDs.insert("stdid02"); standardIDs.insert("stdid02_1"); standardIDs.insert("stdid03"); standardIDs.insert("stdid03_1"); standardIDs.insert("stdid04"); standardIDs.insert("stdid04_1"); standardIDs.insert("stdid05"); standardIDs.insert("stdid05_1"); standardIDs.insert("stdid06"); standardIDs.insert("stdid06_1"); standardIDs.insert("stdid07"); standardIDs.insert("stdid07_1"); standardIDs.insert("stdid08"); standardIDs.insert("stdid08_1"); standardIDs.insert("stdid09"); standardIDs.insert("stdid09_1"); standardIDs.insert("stdid10"); standardIDs.insert("stdid10_1"); standardIDs.insert("stdid11"); standardIDs.insert("stdid11_1"); standardIDs.insert("stdid12"); standardIDs.insert("stdid12_1"); standardIDs.insert("stdid13"); standardIDs.insert("stdid13_1"); standardIDs.insert("stdid14"); standardIDs.insert("stdid14_1"); standardIDs.insert("stdid15"); standardIDs.insert("stdid15_1"); standardIDs.insert("stdid16"); standardIDs.insert("stdid16_1"); standardIDs.insert("stdid17"); standardIDs.insert("stdid17_1"); standardIDs.insert("stdid18"); standardIDs.insert("stdid18_1"); standardIDs.insert("stdid19"); standardIDs.insert("stdid19_1"); // these can not be replaced with set because they // are effectively three-state: if the key is missing in the // map, the result is assumed to be "true", otherwise it is // either "true" or "false" depending on the map entry. copyMenuState[""] = false; copyMenuState["Firewalls"] = false; copyMenuState["Clusters"] = false; copyMenuState["Objects"] = false; copyMenuState["Objects/Addresses"] = false; copyMenuState["Objects/DNS Names"] = false; copyMenuState["Objects/Address Tables"] = false; copyMenuState["Objects/Address Ranges"] = false; copyMenuState["Objects/Groups"] = false; copyMenuState["Objects/Hosts"] = false; copyMenuState["Objects/Networks"] = false; copyMenuState["Services"] = false; copyMenuState["Services/Custom"] = false; copyMenuState["Services/Groups"] = false; copyMenuState["Services/ICMP"] = false; copyMenuState["Services/IP"] = false; copyMenuState["Services/TCP"] = false; copyMenuState["Services/UDP"] = false; copyMenuState["Services/TagServices"] = false; copyMenuState["Time"] = false; cutMenuState[""] = true; cutMenuState["Firewalls"] = false; cutMenuState["Clusters"] = false; cutMenuState["Objects"] = false; cutMenuState["Objects/Addresses"] = false; cutMenuState["Objects/DNS Names"] = false; cutMenuState["Objects/Address Tables"] = false; cutMenuState["Objects/Address Ranges"] = false; cutMenuState["Objects/Groups"] = false; cutMenuState["Objects/Hosts"] = false; cutMenuState["Objects/Networks"] = false; cutMenuState["Services"] = false; cutMenuState["Services/Custom"] = false; cutMenuState["Services/Groups"] = false; cutMenuState["Services/ICMP"] = false; cutMenuState["Services/IP"] = false; cutMenuState["Services/TCP"] = false; cutMenuState["Services/UDP"] = false; cutMenuState["Services/Users"] = false; cutMenuState["Services/TagServices"] = false; cutMenuState["Time"] = false; pasteMenuState[""] = false; pasteMenuState["Firewalls"] = true; pasteMenuState["Clusters"] = true; pasteMenuState["Objects"] = false; pasteMenuState["Objects/Addresses"] = true; pasteMenuState["Objects/DNS Names"] = true; pasteMenuState["Objects/Address Tables"] = true; pasteMenuState["Objects/Address Ranges"] = true; pasteMenuState["Objects/Groups"] = true; pasteMenuState["Objects/Hosts"] = true; pasteMenuState["Objects/Networks"] = true; pasteMenuState["Services"] = false; pasteMenuState["Services/Custom"] = true; pasteMenuState["Services/Groups"] = true; pasteMenuState["Services/ICMP"] = true; pasteMenuState["Services/IP"] = true; pasteMenuState["Services/TCP"] = true; pasteMenuState["Services/UDP"] = true; pasteMenuState["Services/Users"] = true; pasteMenuState["Services/TagServices"] = true; pasteMenuState["Time"] = true; deleteMenuState[""] = true; deleteMenuState["Firewalls"] = false; deleteMenuState["Clusters"] = false; deleteMenuState["Objects"] = false; deleteMenuState["Objects/Addresses"] = false; deleteMenuState["Objects/DNS Names"] = false; deleteMenuState["Objects/Address Tables"] = false; deleteMenuState["Objects/Address Ranges"] = false; deleteMenuState["Objects/Groups"] = false; deleteMenuState["Objects/Hosts"] = false; deleteMenuState["Objects/Networks"] = false; deleteMenuState["Services"] = false; deleteMenuState["Services/Custom"] = false; deleteMenuState["Services/Groups"] = false; deleteMenuState["Services/ICMP"] = false; deleteMenuState["Services/IP"] = false; deleteMenuState["Services/TCP"] = false; deleteMenuState["Services/UDP"] = false; deleteMenuState["Services/Users"] = false; deleteMenuState["Services/TagServices"] = false; deleteMenuState["Time"] = false; } } /** * returns true if object 'obj' is a system group. System groups are * those that hold other objects. Unlike user-defined groups, system * groups always contain only objects themselves and never contain * references to objects. User-defined groups, on the other hand, * always contain only references to objects. * */ bool FWBTree::isSystem(FWObject *obj) { if (Library::isA(obj)) return (obj->getId()==FWObjectDatabase::STANDARD_LIB_ID || obj->getId()==FWObjectDatabase::DELETED_OBJECTS_ID); if (FWObjectDatabase::isA(obj)) return true; return isStandardFolder(obj); } /** * returns true if @obj is a standard folder,e.g. "Firewalls", "Objects", * "Objects/Hosts" etc. */ bool FWBTree::isStandardFolder(FWObject *obj) { string path = obj->getPath(true); // relative path return (standardFolders.contains(QString::fromUtf8(path.c_str()))); } bool FWBTree::isStandardId(FWObject *obj) { return standardIDs.contains(FWObjectDatabase::getStringId(obj->getId()).c_str()); } bool FWBTree::validateForInsertion(FWObject *target, FWObject *obj, QString &err) { if (fwbdebug) qDebug("FWBTree::validateForInsertion target %s obj %s", target->getTypeName().c_str(), obj->getTypeName().c_str()); FWObject *ta = target; if (IPv4::isA(ta) || IPv6::isA(ta)) ta=ta->getParent(); err = QObject::tr("Impossible to insert object %1 (type %2) into %3\n" "because of incompatible type.") .arg(obj->getName().c_str()) .arg(obj->getTypeName().c_str()) .arg(ta->getName().c_str()); if (Host::isA(ta) && Interface::isA(obj)) return true; if (Firewall::isA(ta) && Interface::isA(obj)) return true; if (Interface::isA(ta) && IPv4::isA(obj)) return true; if (Interface::isA(ta) && IPv6::isA(obj)) return true; if (Interface::isA(ta) && physAddress::isA(obj)) return true; FWBTree objtree; if (objtree.isSystem(ta)) { QString parentType = systemGroupTypes[obj->getTypeName().c_str()]; QString parentName = systemGroupNames[obj->getTypeName().c_str()]; /* parentType or/and parentName are going to be empty if information * about object obj is missing in systemGroupTypes/Names tables */ if (parentType.isEmpty() || parentName.isEmpty()) return false; if (ta->getTypeName() == string(parentType.toLatin1()) && ta->getName() == string(parentName.toLatin1()) ) return true; return false; } Host *hst = Host::cast(ta); Firewall *fw = Firewall::cast(ta); Interface *intf = Interface::cast(ta); FWObject *parent_fw = ta; while (parent_fw && Firewall::cast(parent_fw)==NULL) parent_fw = parent_fw->getParent(); if (parent_fw && Interface::isA(obj)) { std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(parent_fw)); return int_prop->validateInterface(ta, obj, false, err); } if (fw!=NULL) { // inserting some object into firewall or cluster if (!fw->validateChild(obj)) return false; return true; } if (hst!=NULL) return (hst->validateChild(obj)); if (intf!=NULL) { if (!intf->validateChild(obj)) return false; return true; } Group *grp=Group::cast(ta); if (grp!=NULL) return grp->validateChild(obj); return false; } void FWBTree::getStandardSlotForObject(const QString &objType, QString &parentType, QString &parentName) { parentType = systemGroupTypes[objType]; parentName = systemGroupNames[objType]; } /** * this method finds standard system folder for an object of a given * type in a given library. This method implemented our standard tree * structure (the one that is created in the method createNewLibrary) */ FWObject* FWBTree::getStandardSlotForObject(FWObject* lib,const QString &objType) { QString path = systemGroupPaths[objType]; if (path.isEmpty()) return lib; QString level1 = path.section('/',0,0); QString level2 = path.section('/',1,1); FWObject::iterator i=std::find_if(lib->begin(),lib->end(), FWObjectNameEQPredicate(static_cast(level1.toAscii()))); if (i==lib->end()) return NULL; FWObject *l1obj = *i; if (level2.isEmpty()) return l1obj; i=std::find_if(l1obj->begin(),l1obj->end(), FWObjectNameEQPredicate(static_cast(level2.toAscii()))); if (i==l1obj->end()) return NULL; return (*i); } FWObject* FWBTree::createNewLibrary(FWObjectDatabase *db) { FWObject *nlib = db->create(Library::TYPENAME); db->add(nlib); nlib->setName( string(QObject::tr("New Library").toUtf8()) ); FWObject *o1 = db->create(ObjectGroup::TYPENAME); o1->setName("Objects"); nlib->add(o1); FWObject *o2 = db->create(ObjectGroup::TYPENAME); o2->setName("Addresses"); o1->add(o2); o2 = db->create(ObjectGroup::TYPENAME); o2->setName("DNS Names"); o1->add(o2); o2 = db->create(ObjectGroup::TYPENAME); o2->setName("Address Tables"); o1->add(o2); o2 = db->create(ObjectGroup::TYPENAME); o2->setName("Groups"); o1->add(o2); o2 = db->create(ObjectGroup::TYPENAME); o2->setName("Hosts"); o1->add(o2); o2 = db->create(ObjectGroup::TYPENAME); o2->setName("Networks"); o1->add(o2); o2 = db->create(ObjectGroup::TYPENAME); o2->setName("Address Ranges"); o1->add(o2); o1 = db->create(ServiceGroup::TYPENAME); o1->setName("Services"); nlib->add(o1); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("Groups"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("ICMP"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("IP"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("TCP"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("UDP"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("Users"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("Custom"); o1->add(o2); o2 = db->create(ServiceGroup::TYPENAME); o2->setName("TagServices"); o1->add(o2); o1 = db->create(ObjectGroup::TYPENAME); o1->setName("Firewalls"); nlib->add(o1); o1 = db->create(ObjectGroup::TYPENAME); o1->setName("Clusters"); nlib->add(o1); o1 = db->create(IntervalGroup::TYPENAME); o1->setName("Time"); nlib->add(o1); return nlib; } /* * return string that can be translated for the object type name */ QString FWBTree::getTranslatableObjectTypeName(const QString &type_name) { if (type_name == Library::TYPENAME) return QObject::tr("Library"); if (type_name == Firewall::TYPENAME) return QObject::tr("Firewall"); if (type_name == Cluster::TYPENAME) return QObject::tr("Cluster"); if (type_name == Host::TYPENAME) return QObject::tr("Host"); if (type_name == Interface::TYPENAME) return QObject::tr("Interface"); if (type_name == AttachedNetworks::TYPENAME) return QObject::tr("Attached Networks"); if (type_name == Network::TYPENAME) return QObject::tr("Network"); if (type_name == NetworkIPv6::TYPENAME) return QObject::tr("Network IPv6"); if (type_name == IPv4::TYPENAME) return QObject::tr("Address"); if (type_name == IPv6::TYPENAME) return QObject::tr("Address IPv6"); if (type_name == DNSName::TYPENAME) return QObject::tr("DNS Name"); if (type_name == AddressTable::TYPENAME) return QObject::tr("Address Table"); if (type_name == AddressRange::TYPENAME) return QObject::tr("Address Range"); if (type_name == ObjectGroup::TYPENAME) return QObject::tr("Object Group"); if (type_name == DynamicGroup::TYPENAME) return QObject::tr("Dynamic Group"); if (type_name == CustomService::TYPENAME) return QObject::tr("Custom Service"); if (type_name == IPService::TYPENAME) return QObject::tr("IP Service"); if (type_name == ICMPService::TYPENAME) return QObject::tr("ICMP Service"); if (type_name == ICMP6Service::TYPENAME) return QObject::tr("ICMP6 Service"); if (type_name == TCPService::TYPENAME) return QObject::tr("TCP Service"); if (type_name == UDPService::TYPENAME) return QObject::tr("UDP Service"); if (type_name == TagService::TYPENAME) return QObject::tr("TagService"); if (type_name == UserService::TYPENAME) return QObject::tr("User Service"); if (type_name == ServiceGroup::TYPENAME) return QObject::tr("Service Group"); if (type_name == Interval::TYPENAME) return QObject::tr( "Time Interval"); if (type_name == physAddress::TYPENAME) return QObject::tr( "MAC Address"); if (type_name == Policy::TYPENAME) return QObject::tr( "Policy Rule Set"); if (type_name == NAT::TYPENAME) return QObject::tr( "NAT Rule Set"); if (type_name == Routing::TYPENAME) return QObject::tr( "Routing Rule Set"); if (type_name == FailoverClusterGroup::TYPENAME) return QObject::tr("Failover group"); if (type_name == StateSyncClusterGroup::TYPENAME) return QObject::tr("State synchronization group"); return ""; } QString FWBTree::getTranslatableNewObjectMenuText(const QString &type_name) { if (type_name == Library::TYPENAME) return QObject::tr("New Library"); if (type_name == Firewall::TYPENAME) return QObject::tr("New Firewall"); if (type_name == Cluster::TYPENAME) return QObject::tr("New Cluster"); if (type_name == Host::TYPENAME) return QObject::tr("New Host"); if (type_name == Interface::TYPENAME) return QObject::tr("New Interface"); if (type_name == AttachedNetworks::TYPENAME) return QObject::tr("New Attached Networks"); if (type_name == Network::TYPENAME) return QObject::tr("New Network"); if (type_name == NetworkIPv6::TYPENAME) return QObject::tr("New Network IPv6"); if (type_name == IPv4::TYPENAME) return QObject::tr("New Address"); if (type_name == IPv6::TYPENAME) return QObject::tr("New Address IPv6"); if (type_name == DNSName::TYPENAME) return QObject::tr("New DNS Name"); if (type_name == AddressTable::TYPENAME) return QObject::tr("New Address Table"); if (type_name == AddressRange::TYPENAME) return QObject::tr("New Address Range"); if (type_name == ObjectGroup::TYPENAME) return QObject::tr("New Object Group"); if (type_name == DynamicGroup::TYPENAME) return QObject::tr("New Dynamic Group"); if (type_name == CustomService::TYPENAME) return QObject::tr("New Custom Service"); if (type_name == IPService::TYPENAME) return QObject::tr("New IP Service"); if (type_name == ICMPService::TYPENAME) return QObject::tr("New ICMP Service"); if (type_name == ICMP6Service::TYPENAME) return QObject::tr("New ICMP6 Service"); if (type_name == TCPService::TYPENAME) return QObject::tr("New TCP Service"); if (type_name == UDPService::TYPENAME) return QObject::tr("New UDP Service"); if (type_name == TagService::TYPENAME) return QObject::tr("New TagService"); if (type_name == UserService::TYPENAME) return QObject::tr("New User Service"); if (type_name == ServiceGroup::TYPENAME) return QObject::tr("New Service Group"); if (type_name == Interval::TYPENAME) return QObject::tr( "New Time Interval"); if (type_name == physAddress::TYPENAME) return QObject::tr( "New MAC Address"); if (type_name == Policy::TYPENAME) return QObject::tr( "New Policy Rule Set"); if (type_name == NAT::TYPENAME) return QObject::tr( "New NAT Rule Set"); if (type_name == Routing::TYPENAME) return QObject::tr( "New Routing Rule Set"); if (type_name == FailoverClusterGroup::TYPENAME) return QObject::tr("New failover group"); if (type_name == StateSyncClusterGroup::TYPENAME) return QObject::tr("New state synchronization group"); return ""; } QList FWBTree::getObjectTypes() { QList ret; ret.append(Firewall::TYPENAME); ret.append(Cluster::TYPENAME); ret.append(Host::TYPENAME); ret.append(Network::TYPENAME); ret.append(NetworkIPv6::TYPENAME); ret.append(IPv4::TYPENAME); ret.append(IPv6::TYPENAME); ret.append(DNSName::TYPENAME); ret.append(AddressTable::TYPENAME); ret.append(AddressRange::TYPENAME); ret.append(ObjectGroup::TYPENAME); ret.append(DynamicGroup::TYPENAME); return ret; } QList FWBTree::getServiceTypes() { QList ret; ret.append(CustomService::TYPENAME); ret.append(IPService::TYPENAME); ret.append(ICMPService::TYPENAME); ret.append(ICMP6Service::TYPENAME); ret.append(TCPService::TYPENAME); ret.append(UDPService::TYPENAME); ret.append(TagService::TYPENAME); ret.append(UserService::TYPENAME); ret.append(ServiceGroup::TYPENAME); return ret; } fwbuilder-5.1.0.3599/src/libgui/pixosAdvancedDialog.h0000644000175000017500000000266011733011756023125 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PIXOSADVANCEDDIALOG_H_ #define __PIXOSADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class pixosAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::pixosAdvancedDialog_q *m_dialog; public: pixosAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~pixosAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); public slots: }; #endif // __PIXOSADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/objectselectorwidget_q.ui0000644000175000017500000001540011733011756024132 0ustar sylvestresylvestre ObjectSelectorWidget_q 0 0 691 455 Form 0 6 QAbstractItemView::MultiSelection 6 Remove Filter Select All Filter ... Unselect All 6 -> <- Qt::Vertical QSizePolicy::Expanding 20 240 6 QAbstractItemView::MultiSelection 6 Select All Unselect All addObjButton clicked() ObjectSelectorWidget_q addObject() 345 28 344 227 objFilterButton clicked() ObjectSelectorWidget_q addFilter() 84 384 344 227 remObjButton clicked() ObjectSelectorWidget_q removeObject() 345 64 344 227 remObjFilterButton clicked() ObjectSelectorWidget_q removeFilter() 220 384 344 227 selAllObjButton clicked() ObjectSelectorWidget_q selectAllUsed() 469 420 344 227 selAllResButton clicked() ObjectSelectorWidget_q selectAllResults() 84 420 344 227 unselAllObjButton clicked() ObjectSelectorWidget_q unselectAllUsed() 605 420 344 227 unselAllResButton clicked() ObjectSelectorWidget_q unselectAllResults() 220 420 344 227 addFilter() removeFilter() selectAllResults() unselectAllResults() selectAllUsed() unselectAllUsed() addObject() removeObject() fwbuilder-5.1.0.3599/src/libgui/linux24IfaceOptsDialog.h0000644000175000017500000000322311733011756023434 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LINUX24IFACEOPTSDIALOG_H_ #define __LINUX24IFACEOPTSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class linux24IfaceOptsDialog : public QDialog { Q_OBJECT public: linux24IfaceOptsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~linux24IfaceOptsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::linux24IfaceOptsDialog_q *m_dialog; bool cluster_interface; /** validate user input for different interface types */ bool validate(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); void typeChanged(const QString&); void bondingPolicyChanged(const QString&); }; #endif // __LINUX24IFACEOPTSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/InterfaceDialog.cpp0000644000175000017500000004536211733011756022576 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "InterfaceDialog.h" #include "DialogFactory.h" #include "ProjectPanel.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "fwbuilder/Library.h" #include "fwbuilder/Interface.h" #include "fwbuilder/InterfaceData.h" #include "fwbuilder/Management.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Host.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; InterfaceDialog::InterfaceDialog(QWidget *parent) : BaseObjectDialog(parent) { netzone_manager = new NetworkZoneManager(); m_dialog = new Ui::InterfaceDialog_q; m_dialog->setupUi(this); /* seclevel->hide(); seclevelLabel->hide(); netzone->hide(); netzoneLabel->hide(); */ obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } InterfaceDialog::~InterfaceDialog() { delete netzone_manager; delete m_dialog; } void InterfaceDialog::loadFWObject(FWObject *o) { obj=o; Interface *s = dynamic_cast(obj); assert(s!=NULL); init = true; if (st->getBool("Objects/Interface/autoconfigureInterfaces")) { /* * guessSubInterfaceTypeAndAttributes() changes some attributes of * the object (mostly compensating for missing functions in * auto-upgrade scripts but also makes some guesses based on the * interface name, such as sets its vlan ID if its name looks like * it might be a vlan interface). Since we make changes in the * object here, do it before loading it into the dialog so that it * does not look like it has changed in applyChanges() even if the * user hasn't touched it, which causes new undo command to be * created out of nowhere. * * TODO: better way of course is to call * guessSubInterfaceTypeAndAttributes in places where user changes * something relevant in the interface to complement their changes * and right after the interface has been created. */ FWObject *parent_host = Host::getParentHost(s); if (parent_host) { // parent_host may be NULL if interface object is located // in the Deleted Objects library interfaceProperties *int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject( parent_host); int_prop->guessSubInterfaceTypeAndAttributes(s); delete int_prop; } } m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->label->setText( QString::fromUtf8(s->getLabel().c_str()) ); m_dialog->regular->setChecked(! s->isDyn() && ! s->isUnnumbered() && ! s->isBridgePort() ); m_dialog->dynamic->setChecked( s->isDyn() ); m_dialog->unnumbered->setChecked( s->isUnnumbered() ); m_dialog->dedicated_failover->setChecked( s->isDedicatedFailover() ); m_dialog->management->setChecked( s->isManagement() ); m_dialog->commentKeywords->loadFWObject(s); if (s->isBridgePort()) { m_dialog->regular->hide(); m_dialog->dynamic->hide(); m_dialog->unnumbered->hide(); m_dialog->management->hide(); m_dialog->unprotected->hide(); m_dialog->dedicated_failover->hide(); m_dialog->bridge_port_label->show(); } else { m_dialog->regular->show(); m_dialog->dynamic->show(); m_dialog->unnumbered->show(); m_dialog->management->show(); m_dialog->unprotected->show(); m_dialog->dedicated_failover->show(); m_dialog->bridge_port_label->hide(); } FWObject *f = Host::getParentHost(s); if (f) { m_dialog->advancedconfig->setEnabled(true); /* if parent is a host, hide firewall related settings */ if (Host::isA(f)) { m_dialog->management->setEnabled(false); m_dialog->unprotected->setEnabled(false); m_dialog->dedicated_failover->setEnabled(false); m_dialog->seclevel->setEnabled(false); m_dialog->seclevelLabel->setEnabled(false); m_dialog->netzone->setEnabled(false); m_dialog->netzoneLabel->setEnabled(false); // Can;t let user try to open "advanced interface settings" // dialog because Host does not have "platform" and "host_OS" // attributes but that dialog depends on them. m_dialog->advancedconfig->setEnabled(false); } bool supports_security_levels = false; bool supports_network_zones = false; bool supports_unprotected = false; bool supports_advanced_ifaces = false; try { // platform specific supports_security_levels = Resources::getTargetCapabilityBool( f->getStr("platform"), "security_levels"); supports_network_zones = Resources::getTargetCapabilityBool( f->getStr("platform"), "network_zones"); supports_unprotected = Resources::getTargetCapabilityBool( f->getStr("platform"), "unprotected_interfaces"); // OS specific supports_advanced_ifaces = Resources::getTargetCapabilityBool( f->getStr("host_OS"), "supports_advanced_interface_options"); // disable advanced options dialog if this is main interface of a cluster if (Cluster::isA(s->getParent())) supports_advanced_ifaces = false; } catch (FWException &ex) { } if (fwbdebug) qDebug() << "parent=" << f->getName().c_str() << "Firewall::isA(f)=" << Firewall::isA(f) << "host_OS=" << f->getStr("host_OS").c_str() << "supports_advanced_ifaces=" << supports_advanced_ifaces; /* if parent is a firewall or a fw cluster, it is more complex ... */ if (Firewall::isA(f) || Cluster::isA(f)) { if (supports_security_levels) { m_dialog->seclevel->setEnabled(true); m_dialog->seclevelLabel->setEnabled(true); m_dialog->seclevel->setValue( obj->getInt("security_level") ); } else { m_dialog->seclevel->setEnabled(false); m_dialog->seclevelLabel->setEnabled(false); m_dialog->seclevel->setValue(0); } if (supports_unprotected) { m_dialog->unprotected->setEnabled(true); m_dialog->unprotected->setChecked( obj->getBool("unprotected") ); } else { m_dialog->unprotected->setEnabled(false); } if (supports_advanced_ifaces) { m_dialog->advancedconfig->setEnabled(!o->isReadOnly()); } else { m_dialog->advancedconfig->setEnabled(false); } // disable interface options group if this is main interface // of a cluster. This applies to subinterfaces as // well. Current implementation can not generate configuration // code for interfaces and subinterfaces of member firewalls // from cluster interface or subinterface objects m_dialog->interfaceOptionsGroup->setEnabled(!Cluster::isA(f)); if (supports_network_zones) { m_dialog->netzone->setEnabled(true); m_dialog->netzoneLabel->setEnabled(true); netzone_manager->load(m_project->db()); int id = FWObjectDatabase::getIntId(obj->getStr("network_zone")); if (id==-1) id = 0; netzone_manager->packComboBox(m_dialog->netzone, id); } else { m_dialog->netzone->setEnabled(false); m_dialog->netzoneLabel->setEnabled(false); m_dialog->netzone->clear(); } } } m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->label->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->label); m_dialog->regular->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->regular); m_dialog->dynamic->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->dynamic); m_dialog->unnumbered->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->unnumbered); m_dialog->management->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->management); m_dialog->unprotected->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->unprotected); m_dialog->dedicated_failover->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->dedicated_failover); m_dialog->seclevel->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->seclevel); m_dialog->netzone->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->netzone); //apply->setEnabled( false ); init = false; } void InterfaceDialog::validate(bool *res) { *res = true; QString obj_name = m_dialog->obj_name->text(); // validateName checks for name duplicates if (!validateName(this, obj, obj_name)) { *res = false; return; } FWObject *parent_host = Host::getParentHost(obj); interfaceProperties *int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject( parent_host); QString err; /* * TODO: * See if basicValidateInterfaceName() can be rolled into * validateInterface() */ if ( ! int_prop->basicValidateInterfaceName( Interface::cast(obj), obj_name, err)) { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this,"Firewall Builder", err, tr("&Continue"), QString::null,QString::null, 0, 1 ); blockSignals(false); } return; } // validateInterface() checks validity of vlan inetrface name if (st->getBool("Objects/Interface/autoconfigureInterfaces") && ! int_prop->validateInterface(obj->getParent(), obj_name, err)) { /* * Here is the annoying part: if user entered interface name * that does not pass checks in interfaceProperties, this * dialog will pop warning dialog to tell them this every time * the dialog loses focus even if they did not change * anything. This happens when they click on any other part of * the GUI or even switch to another application. For example * this happens when user adds subinterface to an interface * with intention to make the subint a vlan. The new interface * object is created with default name, when they change the * name to, say, eth0 (and the parent is eth0), this causes * the error message to appear when they switch the focus. If * they switch to another application while cursor was in the * object name field, the pop-up appears as well. */ *res = false; // show warning dialog only if app has focus if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this,"Firewall Builder", err, tr("&Continue"), QString::null,QString::null, 0, 1 ); blockSignals(false); } } delete int_prop; } void InterfaceDialog::applyChanges() { bool autorename_children = false; list subinterfaces = obj->getByType(Interface::TYPENAME); if (obj->getName() != m_dialog->obj_name->text().toUtf8().constData() && ( obj->getByType(IPv4::TYPENAME).size() || obj->getByType(IPv6::TYPENAME).size() || obj->getByType(physAddress::TYPENAME).size() || subinterfaces.size() ) ) { QString dialog_txt = tr( "The name of the interface '%1' has changed. The program can also " "rename IP address objects that belong to this interface, " "using standard naming scheme 'host_name:interface_name:ip'. " "This makes it easier to distinguish what host or a firewall " "given IP address object belongs to when it is used in " "the policy or NAT rule. The program also renames MAC address " "objects using scheme 'host_name:interface_name:mac'. " "Do you want to rename child IP and MAC address objects now? " "(If you click 'No', names of all address objects that belong to " "interface '%2' will stay the same.)") .arg(QString::fromUtf8(obj->getName().c_str())) .arg(QString::fromUtf8(obj->getName().c_str())); /* see comment about this in FirewallDialog */ blockSignals(true); autorename_children = (QMessageBox::warning( this, "Firewall Builder", dialog_txt, tr("&Yes"), tr("&No"), QString::null, 0, 1 )==0 ); blockSignals(false); } std::auto_ptr cmd( new FWCmdChange(m_project, obj, "", autorename_children)); FWObject* new_state = cmd->getNewState(); Interface *intf = Interface::cast(new_state); assert(intf!=NULL); string oldname = obj->getName(); string oldlabel = intf->getLabel(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); intf->setLabel( string(m_dialog->label->text().toUtf8().constData()) ); intf->setDyn( m_dialog->dynamic->isChecked() ); intf->setUnnumbered( m_dialog->unnumbered->isChecked() ); intf->setDedicatedFailover( m_dialog->dedicated_failover->isChecked() ); // NOTE: new_state is a copy of the interface but it is not attached to // the tree and therefore has no parent. Need to use original object obj // to get the pointer to the parent firewall. FWObject *f = Host::getParentHost(obj); //FWObject *f = Interface::cast(obj)->getParentHost(); bool supports_security_levels = false; bool supports_network_zones = false; bool supports_unprotected = false; try { supports_security_levels= Resources::getTargetCapabilityBool(f->getStr("platform"), "security_levels"); supports_network_zones= Resources::getTargetCapabilityBool(f->getStr("platform"), "network_zones"); supports_unprotected = Resources::getTargetCapabilityBool(f->getStr("platform"), "unprotected_interfaces"); } catch (FWException &ex) { } if (Firewall::isA( f ) || Cluster::isA( f )) { if (supports_security_levels) new_state->setInt("security_level", m_dialog->seclevel->value() ); if (supports_unprotected) new_state->setBool("unprotected", m_dialog->unprotected->isChecked() ); if (supports_network_zones) { new_state->setStr("network_zone", FWObjectDatabase::getStringId( m_dialog->netzone->itemData( m_dialog->netzone->currentIndex(), Qt::UserRole).toInt())); // new_state->setStr("network_zone", // FWObjectDatabase::getStringId( // netzone_manager->getNetzoneIdByListIndex( // m_dialog->netzone->currentIndex() ) // ) // ); } intf->setManagement( m_dialog->management->isChecked() ); } if (!cmd->getOldState()->cmp(new_state, true)) { // Complement changes made by the user with our guesses, but // do this only if user changed something. if (st->getBool("Objects/Interface/autoconfigureInterfaces")) { // ticket #328: automatically assign vlan id to interface based on // interface name FWObject *parent_host = Host::getParentHost(obj); interfaceProperties *int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject( parent_host); int_prop->setPerformVlanChecks(true); int_prop->guessSubInterfaceTypeAndAttributes(intf); delete int_prop; } if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void InterfaceDialog::openIfaceDialog() { try { QWidget *w = DialogFactory::createIfaceDialog(this, obj); if (w==NULL) return; // some dialogs may not be implemented yet QDialog *d=dynamic_cast(w); assert(d!=NULL); d->exec(); delete w; } catch (FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("FWBuilder API error: %1").arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); return; } } fwbuilder-5.1.0.3599/src/libgui/procurveaclAdvancedDialog.h0000644000175000017500000000334311733011756024307 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PROCURVEACLADVANCEDDIALOG_H_ #define __PROCURVEACLADVANCEDDIALOG_H_ #include #include "DialogData.h" #include #include class QWidget; class QSpinBox; class QComboBox; class QCheckBox; class QProcess; namespace libfwbuilder { class FWObject; }; class procurveaclAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::procurveaclAdvancedDialog_q *m_dialog; public: procurveaclAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~procurveaclAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void editProlog(); virtual void editEpilog(); virtual void scriptACLModeChanged(); virtual void toggleGenerateLogging(); }; #endif // __PROCURVEACLADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/askrulenumberdialog_q.ui0000644000175000017500000000725611733011756023770 0ustar sylvestresylvestre askRuleNumberDialog_q 0 0 279 119 Enter New Position For The Rule Enter new position for selected rules: false 10000 Qt::Vertical QSizePolicy::Expanding 80 20 Qt::Vertical QSizePolicy::Expanding 80 20 Qt::Vertical QSizePolicy::Expanding 80 20 &Move Alt+M true true &Cancel Alt+C true true buttonOk clicked() askRuleNumberDialog_q accept() 20 20 20 20 buttonCancel clicked() askRuleNumberDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/DynamicGroupDialog.cpp0000644000175000017500000002627311733011756023277 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "DynamicGroupDialog.h" #include "events.h" #include "FWBTree.h" #include "FWCmdChange.h" #include "FWObjectPropertiesFactory.h" #include "FWWindow.h" #include "fwbuilder/DynamicGroup.h" #include #include #include using namespace std; using namespace libfwbuilder; DynamicItemDelegate::DynamicItemDelegate(DynamicGroupDialog *dialog, QObject *parent) : QItemDelegate(parent), m_dialog(dialog) { } QWidget *DynamicItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.column() == 0) { QToolButton *button = new QToolButton(parent); QPixmap pixmap; if (!QPixmapCache::find(":/Icons/neg", pixmap)) { pixmap.load(":/Icons/neg"); QPixmapCache::insert(":/Icons/neg", pixmap); } button->setIcon(QIcon(pixmap)); button->setProperty("row", QVariant(index.row())); connect(button, SIGNAL(clicked()), m_dialog, SLOT(deleteFilterClicked())); return button; } else { QComboBox *combo = new QComboBox(parent); connect(combo, SIGNAL(activated(int)), this, SLOT(comboActivated(int))); return combo; } } void DynamicItemDelegate::comboActivated(int abc) { /* Don't wait until we lose focus on the combobox */ emit commitData(dynamic_cast(sender())); } void DynamicItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { if (index.column() == 0) return; QString value = index.model()->data(index, Qt::EditRole).toString(); QComboBox *combo = static_cast(editor); combo->clear(); if (index.column() == 1) { if (value == DynamicGroup::TYPE_NONE) { combo->addItem("None selected", DynamicGroup::TYPE_NONE); combo->setCurrentIndex(0); } combo->addItem("Any type", DynamicGroup::TYPE_ANY); if (value == DynamicGroup::TYPE_ANY) { combo->setCurrentIndex(combo->count() - 1); } combo->insertSeparator(2); QList types = FWBTree::getObjectTypes(); foreach (const char *type, types) { combo->addItem(FWBTree().getTranslatableObjectTypeName(type), type); if (value == type) { combo->setCurrentIndex(combo->count() - 1); } } } else if (index.column() == 2) { if (value == DynamicGroup::KEYWORD_NONE) { combo->addItem("None selected", DynamicGroup::KEYWORD_NONE); combo->setCurrentIndex(0); } combo->addItem("Any keyword", DynamicGroup::KEYWORD_ANY); if (value == DynamicGroup::KEYWORD_ANY) { combo->setCurrentIndex(combo->count() - 1); } combo->insertSeparator(2); QStringList list; const set &keywords = m_dialog->getCurrentObj()->getAllKeywords(); set::const_iterator iter; for (iter = keywords.begin(); iter != keywords.end(); ++iter) { list.append(QString::fromUtf8((*iter).c_str())); } foreach (QString item, sortStrings(list)) { combo->addItem(item, item); if (item == value) { combo->setCurrentIndex(combo->count() - 1); } } } } void DynamicItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { if (index.column() == 0) return; QComboBox *combo = static_cast(editor); QString value = combo->itemData(combo->currentIndex()).toString(); model->setData(index, value, Qt::EditRole); } /*****************************************************************/ DynamicGroupDialog::DynamicGroupDialog(QWidget *parent) : BaseObjectDialog(parent), m_reloadObjFilter(false) { m_ui.setupUi(this); connectSignalsOfAllWidgetsToSlotChange(); m_model = new QStandardItemModel; connect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(changed())); DynamicItemDelegate *delegate = new DynamicItemDelegate(this, m_ui.criteriaView); m_ui.criteriaView->setItemDelegate(delegate); m_ui.criteriaView->setModel(m_model); m_ui.criteriaView->resizeColumnsToContents(); m_ui.criteriaView->verticalHeader()->hide(); QStringList headers; headers << "Name" << "Properties"; m_ui.matchedView->setHeaderLabels(headers); connect(m_ui.matchedView, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(gotItemDoubleClicked(QTreeWidgetItem *, int))); } void DynamicGroupDialog::applyChanges() { if (obj->isReadOnly()) return; FWCmdChange *change = new FWCmdChange(m_project, obj); DynamicGroup *newState = DynamicGroup::cast(change->getNewState()); newState->setName(m_ui.nameEdit->text().toUtf8().constData()); m_ui.commentKeywords->applyChanges(newState); list filters; int rows = m_model->rowCount(); for (int ii = 0; ii < rows; ii++) { QString type = m_model->data(m_model->index(ii, 1)).toString(); QString keyword = m_model->data(m_model->index(ii, 2)).toString(); string filter; DynamicGroup::makeFilter(filter, type.toUtf8().constData(), keyword.toUtf8().constData()); filters.push_back(filter); } newState->setFilter(filters); if (obj->cmp(newState, true)) { delete change; } else { m_project->undoStack->push(change); } m_loadedObjFilter = filters; } void DynamicGroupDialog::loadObjFilter() { DynamicGroup *objGroup = dynamic_cast(obj); /* We remove the rows instead of calling clear so the headers don't flicker. */ //m_model->clear(); while (m_model->rowCount() > 0) { m_model->removeRow(0); } QStringList headers; headers << "Del" << "Type" << "Keyword"; m_model->setHorizontalHeaderLabels(headers); const list &filter = objGroup->getFilter(); list::const_iterator iter; for (iter = filter.begin(); iter != filter.end(); ++iter) { string type, keyword; objGroup->splitFilter(*iter, type, keyword); QList items; items << new QStandardItem(QString()); items << new QStandardItem(QString::fromUtf8(type.c_str())); items << new QStandardItem(QString::fromUtf8(keyword.c_str())); m_model->appendRow(items); int row = m_model->rowCount() - 1; m_ui.criteriaView->openPersistentEditor(m_model->index(row, 0)); m_ui.criteriaView->openPersistentEditor(m_model->index(row, 1)); m_ui.criteriaView->openPersistentEditor(m_model->index(row, 2)); } QHeaderView *header = m_ui.criteriaView->horizontalHeader(); /* Try to force at least some minimum size, as the ResizeToContents doesn't always seem to work */ header->resizeSection(0, 35); header->setStretchLastSection(true); header->setResizeMode(0, QHeaderView::ResizeToContents); header->setResizeMode(1, QHeaderView::ResizeToContents); m_reloadObjFilter = false; m_loadedObjFilter = filter; m_loadedAllKeywords = obj->getAllKeywords(); } void DynamicGroupDialog::loadFWObject(FWObject *o) { DynamicGroup *objGroup = dynamic_cast(o); const list &filter = objGroup->getFilter(); if (obj != o || m_reloadObjFilter || m_loadedObjFilter != filter || m_loadedAllKeywords != o->getAllKeywords()) { obj = o; loadObjFilter(); } m_ui.nameEdit->setText(QString::fromUtf8(o->getName().c_str())); m_ui.commentKeywords->loadFWObject(o); FWObjectDatabase *root = obj->getRoot(); m_ui.matchedView->clear(); m_ui.matchedView->setDB(root); FWObject::tree_iterator tree_iter; for (tree_iter = root->tree_begin(); tree_iter != root->tree_end(); ++tree_iter) { FWObject *elem = (*tree_iter); if (elem == root) continue; if (!objGroup->isMemberOfGroup(elem)) continue; QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.matchedView); item->setText(0, QString::fromUtf8(elem->getName().c_str())); item->setText(1, FWObjectPropertiesFactory::getObjectProperties(elem)); item->setData(0, Qt::UserRole, QVariant(elem->getId())); QString icon = ":/Icons/"; icon += elem->getTypeName().c_str(); icon += "/icon-ref"; QPixmap pixmap; if (!QPixmapCache::find(icon, pixmap)) { pixmap.load(icon); QPixmapCache::insert(icon, pixmap); } item->setIcon(0, QIcon(pixmap)); m_ui.matchedView->addTopLevelItem(item); } } void DynamicGroupDialog::validate(bool *result) { } void DynamicGroupDialog::addMatchClicked() { int newRow = m_model->rowCount(); QList items; items << new QStandardItem("") << new QStandardItem(DynamicGroup::TYPE_NONE) << new QStandardItem(DynamicGroup::KEYWORD_NONE); m_model->insertRow(newRow, items); m_ui.criteriaView->openPersistentEditor(m_model->index(newRow, 0)); m_ui.criteriaView->openPersistentEditor(m_model->index(newRow, 1)); m_ui.criteriaView->openPersistentEditor(m_model->index(newRow, 2)); m_ui.criteriaView->resizeColumnsToContents(); QHeaderView *header = m_ui.criteriaView->horizontalHeader(); header->setStretchLastSection(true); m_ui.criteriaView->scrollToBottom(); /* How come insertRow() doesn't do this for us? */ emit changed(); } void DynamicGroupDialog::deleteFilterClicked() { QToolButton *button = dynamic_cast(sender()); int row = button->property("row").toInt(); m_model->removeRow(row); m_reloadObjFilter = true; emit changed(); } void DynamicGroupDialog::gotItemDoubleClicked(QTreeWidgetItem *item, int) { int objId = item->data(0, Qt::UserRole).toInt(); FWObject *o = m_project->db()->findInIndex(objId); if (o == 0) return; QCoreApplication::postEvent(m_project, new showObjectInTreeEvent(o->getRoot()->getFileName().c_str(), objId)); QCoreApplication::postEvent(mw, new openObjectInEditorEvent(o->getRoot()->getFileName().c_str(), objId)); } fwbuilder-5.1.0.3599/src/libgui/compileroutputpanel_q.ui0000644000175000017500000000154611733011756024040 0ustar sylvestresylvestre CompilerOutputPanel_q true 0 0 740 262 Script Editor 0 Qt::ScrollBarAlwaysOn fwbuilder-5.1.0.3599/src/libgui/SSHIOS.h0000644000175000017500000000244611733011756020227 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SSHIOS_H_ #define __SSHIOS_H_ #include "config.h" #include "global.h" #include "SSHCisco.h" #include class SSHIOS : public SSHCisco { Q_OBJECT; public: SSHIOS(QWidget *parent, const QString &host, const QStringList &args, const QString &pwd, const QString &epwd, const std::list &in); virtual ~SSHIOS(); virtual void stateMachine(); }; #endif fwbuilder-5.1.0.3599/src/libgui/InterfaceDialog.h0000644000175000017500000000305011733011756022227 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INTERFACEDIALOG_H_ #define __INTERFACEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include "networkZoneManager.h" #include #include "fwbuilder/FWObject.h" #include #include class ProjectPanel; class InterfaceDialog : public BaseObjectDialog { Q_OBJECT; NetworkZoneManager *netzone_manager; Ui::InterfaceDialog_q *m_dialog; public: InterfaceDialog(QWidget *parent); ~InterfaceDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void openIfaceDialog(); }; #endif // INTERFACEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/DialogData.cpp0000644000175000017500000002220711733011756021540 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "utils.h" #include "global.h" #include "DialogData.h" #include "fwbuilder/FWObject.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; DialogOption::DialogOption(QWidget *_w, FWObject *_o, const char* _a) { w = _w; obj = _o; attr = _a; dtype = Unknown; if (dynamic_cast(w)!=NULL) dtype=String; if (dynamic_cast(w)!=NULL) dtype=Bool; if (dynamic_cast(w)!=NULL) dtype=String; if (dynamic_cast(w)!=NULL) dtype=String; if (dynamic_cast(w)!=NULL) dtype=Bool; if (dynamic_cast(w)!=NULL) dtype=Int; } DialogOption::DialogOption(QWidget *_w, FWObject *_o, const char* _a,QStringList _m) { w = _w; obj = _o; attr = _a; mapping = _m; dtype = Unknown; if (dynamic_cast(w)!=NULL) dtype=String; if (dynamic_cast(w)!=NULL) dtype=Bool; if (dynamic_cast(w)!=NULL) dtype=String; if (dynamic_cast(w)!=NULL) dtype=String; if (dynamic_cast(w)!=NULL) dtype=Bool; if (dynamic_cast(w)!=NULL) dtype=Int; } DialogData::DialogData() {} DialogData::~DialogData() { options.clear(); } void DialogData::clear() { options.clear(); } void DialogData::registerOption(QWidget *widget, libfwbuilder::FWObject *obj, const char* attr) { options.push_back( DialogOption(widget,obj,attr) ); } void DialogData::registerOption(QWidget *widget, libfwbuilder::FWObject *obj, const char* attr,QStringList mapping) { options.push_back( DialogOption(widget,obj,attr,mapping) ); } void DialogData::loadToWidget( DialogOption &dopt , bool override) { if (dynamic_cast(dopt.w)!=NULL) { QComboBox *cbx = dynamic_cast(dopt.w); QString s = (override) ? dopt.override_str_val : QString(dopt.obj->getStr(dopt.attr.toLatin1().constData()).c_str()); int current_item = 0; if (!dopt.mapping.empty()) { /* * REMINDER: * Mapping is defined by an array of strings in the following format: * * "Linux 2.4" , "linux24", * "IPFilter" , "ipf", * "Cisco PIX" , "pix", * NULL, NULL * * Odd strings correspond to the data in the widget, while even * strings define what is stored in the object (counting strings in * the array from 1). */ int idx = 0; QStringList::iterator i1 = dopt.mapping.begin(); QStringList::iterator i2 = dopt.mapping.begin(); ++i2; if (fwbdebug) { qDebug("loadToWidget -- QComboBox dopt.mapping.count()=%d",dopt.mapping.count()); qDebug("loadToWidget -- QComboBox s=%s",s.toAscii().constData()); } while ( idx < dopt.mapping.count()/2 ) { if (fwbdebug) { qDebug("loadToWidget -- QComboBox (*i1)=%s",(*i1).toAscii().constData()); qDebug("loadToWidget -- QComboBox (*i2)=%s",(*i2).toAscii().constData()); } if (s== (*i2)) { current_item = idx; } i1++; i1++; i2++; i2++; idx++; } } else { // no mapping, just scan items and find current current_item= cbx->findText(s,Qt::MatchExactly); } cbx->setCurrentIndex( current_item ); } if (dynamic_cast(dopt.w)!=NULL) { QCheckBox *cbx=dynamic_cast(dopt.w); cbx->setChecked( (override)?dopt.override_int_val:dopt.obj->getBool(dopt.attr.toLatin1().constData()) ); } if (dynamic_cast(dopt.w)!=NULL) { QLineEdit *edit=dynamic_cast(dopt.w); edit->setText( (override) ? dopt.override_str_val : QString(dopt.obj->getStr(dopt.attr.toLatin1().constData()).c_str()) ); } if (dynamic_cast(dopt.w)!=NULL) { QTextEdit *edit=dynamic_cast(dopt.w); edit->setText( (override) ? dopt.override_str_val : QString(dopt.obj->getStr(dopt.attr.toLatin1().constData()).c_str()) ); } if (dynamic_cast(dopt.w)!=NULL) { QRadioButton *rbtn=dynamic_cast(dopt.w); rbtn->setChecked( (override)?dopt.override_int_val:dopt.obj->getBool(dopt.attr.toLatin1().constData()) ); } if (dynamic_cast(dopt.w)!=NULL) { QSpinBox *sbx = dynamic_cast(dopt.w); sbx->setValue( (override)?dopt.override_int_val:dopt.obj->getInt(dopt.attr.toLatin1().constData()) ); } } void DialogData::loadAll() { for (list::iterator i=options.begin(); i!=options.end(); ++i) loadToWidget( *i ); } void DialogData::saveAll(FWObject *new_obj) { for (list::iterator i=options.begin(); i!=options.end(); ++i) { FWObject *use_obj = (new_obj!=NULL) ? new_obj : i->obj; if (dynamic_cast(i->w)!=NULL) { QComboBox *cbx = dynamic_cast(i->w); QString s = cbx->currentText(); if (fwbdebug) qDebug() << "DialogData::saveAll() QComboBox" << i->w->objectName() << "s=" << s.toUtf8(); if ( !i->mapping.empty() && !s.isNull() ) { if (fwbdebug) qDebug("Remapping..."); /* * REMINDER: * Mapping is defined by an array of strings in the following format: * * char *mapping[] = { * "Linux 2.4" , "linux24", * "IPFilter" , "ipf", * "Cisco PIX" , "pix", * NULL, NULL * }; * * Odd strings correspond to the data in the widget, while even * strings define what is stored in the object (counting strings in * the array from 1). */ QStringList::iterator i1 = i->mapping.begin(); QStringList::iterator i2 = i->mapping.begin(); ++i2; while (i1!=i->mapping.end()) { if (fwbdebug) qDebug() << " (*i1)=" << *i1; if (s== (*i1)) { s= *i2; break; } i1++; i1++; i2++; i2++; } } if (s.isEmpty()) s=""; use_obj->setStr(i->attr.toLatin1().constData(), s.toLatin1().constData()); } if (dynamic_cast(i->w)!=NULL) { QCheckBox *cbx=dynamic_cast(i->w); use_obj->setBool(i->attr.toLatin1().constData(), cbx->isChecked() ); } if (dynamic_cast(i->w)!=NULL) { QLineEdit *edit=dynamic_cast(i->w); use_obj->setStr(i->attr.toLatin1().constData(), edit->text().toLatin1().constData() ); } if (dynamic_cast(i->w)!=NULL) { QTextEdit *edit=dynamic_cast(i->w); use_obj->setStr(i->attr.toLatin1().constData(), edit->toPlainText().toLatin1().constData() ); } if (dynamic_cast(i->w)!=NULL) { QRadioButton *rbtn=dynamic_cast(i->w); use_obj->setBool(i->attr.toLatin1().constData(), rbtn->isChecked() ); } if (dynamic_cast(i->w)!=NULL) { QSpinBox *sbx = dynamic_cast(i->w); use_obj->setInt( i->attr.toLatin1().constData(), sbx->value() ); } } } void DialogData::setWidgetValue(const char *attr,const QString &val) { for (list::iterator i=options.begin(); i!=options.end(); ++i) { if (i->attr == attr) { i->overrideValue(val); loadToWidget( *i , true ); break; } } } void DialogData::setWidgetValue(const char *attr,int val) { for (list::iterator i=options.begin(); i!=options.end(); ++i) { if (i->attr == attr) { i->overrideValue(val); loadToWidget( *i , true ); break; } } } fwbuilder-5.1.0.3599/src/libgui/ipservicedialog_q.ui0000644000175000017500000002570411733011756023100 0ustar sylvestresylvestre IPServiceDialog_q true 0 0 952 265 0 0 IP QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Protocol number: (0=any) false 255 Qt::Horizontal 40 20 DiffServ Use DSCP true Use TOS DSCP or TOS code (numerical, dec or hex): Qt::Vertical 20 34 6 0 0 QFrame::StyledPanel QFrame::Raised 2 2 IP options: IP service object that has this attribute turned on matches IP packets with any IP options present. Any options lsrr (loose source route) ssrr (strict source route) rr (record route) timestamp router-alert option 0 0 QFrame::StyledPanel QFrame::Raised 2 2 Fragments: all 'short' 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name protocolNum use_dscp use_tos code any_opt stateChanged(int) IPServiceDialog_q anyOptionsStateChanged() 441 64 421 150 changed() anyOptionsStateChanged()
fwbuilder-5.1.0.3599/src/libgui/instdialog_q.ui0000644000175000017500000005401411733011756022060 0ustar sylvestresylvestre instDialog_q 0 0 871 622 0 0 true 0 0 0 25 Sans Serif 14 75 false true TextLabel Qt::AlignCenter 0 0 1 0 0 Qt::LeftToRight 0 0 QFrame::Box QFrame::Plain 11 <p align="center"><b><font size="+2">Select firewalls to compile and install.</font></b></p> false true 0 0 QFrame::Box QFrame::Plain warning text goes here true warning text goes here true 0 0 QFrame::Box QFrame::Plain QFrame::Box QFrame::Plain 11 Qt::Horizontal QSizePolicy::Expanding 100 20 Select all Select none true QAbstractItemView::NoSelection Firewall Compile Install Last Modified Last Compiled Last Installed 0 QFrame::Box QFrame::Plain 11 Stop Qt::Horizontal QSizePolicy::Expanding 112 20 true false true Firewall Progress 1 0 QFrame::Box QFrame::Plain Firewalls: false 0 0 75 true firewall false 300 0 Qt::Horizontal 0 0 75 true current operation here false 300 0 Qt::Horizontal Process log 0 false Qt::Horizontal QSizePolicy::Expanding 131 20 Save log to file Inspect generated files Qt::Vertical QSizePolicy::Expanding 16 210 0 0 QFrame::NoFrame QFrame::Plain 0 1 0 400 50 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 40 20 < &Back false &Next > true true false &Finish true false &Cancel false saveMCLogButton clicked(bool) instDialog_q saveLog() 630 230 20 20 fwWorkList itemActivated(QTreeWidgetItem*, int) instDialog_q findFirewallInCompileLog(QTreeWidgetItem*) 40 69 20 20 pushButton16 clicked(bool) instDialog_q selectAllFirewalls() 43 493 20 20 pushButton17 clicked(bool) instDialog_q deselectAllFirewalls() 93 493 20 20 selectTable itemChanged(QTreeWidgetItem*,int) instDialog_q tableItemChanged(QTreeWidgetItem*,int) 389 319 389 288 procLogDisplay anchorClicked(QUrl) instDialog_q logItemClicked(QUrl) 706 264 778 269 inspectGeneratedFiles clicked() instDialog_q inspectFiles() 638 579 463 375 tableItemChanged(QTreeWidgetItem*,int) logItemClicked(QUrl) inspectFiles() fwbuilder-5.1.0.3599/src/libgui/RCS.h0000644000175000017500000001412511733011756017643 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RCS_H_FLAG__ #define __RCS_H_FLAG__ #include "config.h" #include #include #include #include "fwbuilder/FWException.h" class RCS; class RCSFilePreview; class Revision { friend class RCS; public: QString filename; QString rev; QString date; QString author; QString locked_by; QString log; Revision(); Revision(const Revision &r); Revision(const QString &file, const QString &rev=""); bool operator<(const Revision &r) const; bool operator==(const Revision &r) const; bool operator!=(const Revision &r) const; void operator=(const Revision &r); }; /* * this class just sets environment variable TZ on Windows if it is not set */ class RCSEnvFix { QStringList env; QString TZOffset; public: RCSEnvFix(); QStringList* getEnv(); QString getTZOffset() { return TZOffset; } }; class RCS : public QObject { friend class RCSFilePreview; Q_OBJECT; /* * RCSEnvFix object should be initialized in constructor of RCS so * it is created _after_ we complete initialization and assign * appRootDir because it needs appRootDir to set up PATH on * Windows. */ static RCSEnvFix *rcsenvfix; static QString rcs_file_name; static QString rcsdiff_file_name; static QString rlog_file_name; static QString ci_file_name; static QString co_file_name; static bool rcs_available; QString stdoutBuffer; QString stderrBuffer; QProcess *proc; QProcess *ciproc; bool ciRunning;; bool tracking_file; bool inrcs; bool checked_out; bool locked; QString locked_by; QString locked_rev; QString head; // head revision QString selectedRev; // selected revision bool ro; // if file is to be opened read-only QString filename; bool temp; // if filename is a temporary file QList revisions; /** * Retrieves RCS log. */ QString rlog() throw(libfwbuilder::FWException); public: RCS( const QString &filename ); virtual ~RCS(); static void init(); /** * returns head revision of the file */ QString getFileName() { return filename; } void setFileName(const QString &fn); QList::iterator begin() { return revisions.begin(); } QList::iterator end() { return revisions.end(); } void add() throw(libfwbuilder::FWException); /** * this makes RCS object "forget" about the file */ void abandon(); /** * tells whether the file associated with RCS object is in RCS */ bool isInRCS(); /** * RCS checkout. Returns true if successfull and false if file is * not in RCS. In case of error throws exception */ bool co(const QString &rev,bool force=false) throw(libfwbuilder::FWException); /** * checks out currently selected revision (set using setSelectedRev) */ bool co(bool force=false) throw(libfwbuilder::FWException); /** * RCS checkin. Returns true if successfull and false if file is * not in RCS. In case of error throws exception */ bool ci(const QString &logmsg =" ", bool unlock=false) throw(libfwbuilder::FWException); /** * Retrieves RCS diff. */ QStringList rcsdiff(const QString &rev="") throw(libfwbuilder::FWException); /** * checks if the working copy of the file is different from RCS * revision 'rev'. If rev is empty string, selected revision is * used. If no revision has been selected, the latest revision of * the default branch is used. * * This is essentially just a code returned by rcsdiff with all * its output ignored. */ bool isDiff(const QString &rev="") throw(libfwbuilder::FWException); /** * these two methods just return status */ bool isCheckedOut() { return checked_out; } bool isLocked() { return locked; } QString getLockedBy() { return locked_by; } /** * class RCS helps carry flag 'read-only' together with the rest * of the file info */ void setRO(bool f) { ro=f; } bool isRO() { return ro; } /** * flag 'temp' indicates checkout has been done into temporary file */ bool isTemp() { return temp; } /** * returns head revision of the file */ QString getHead(); /** * returns selected revision of the file. If the file has been * checked out, this is the revision that was chosen for checkout; * if the file is not in RCS, this method returns an empty string; * if file was not checked out, or a head revision was checked * out, this method returns the head. */ QString getSelectedRev(); void setSelectedRev(const QString &rev) { selectedRev=rev; } static QStringList* getEnv(); static RCSEnvFix* getRCSEnvFix(); public slots: virtual void readFromStdout(); virtual void readFromStderr(); }; #endif fwbuilder-5.1.0.3599/src/libgui/IconSetter.h0000644000175000017500000000215511733011756021273 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ICONSETTER_H #define ICONSETTER_H #include "config.h" #include "global.h" #include "fwbuilder/FWObject.h" #include class IconSetter { public: static void setObjectIcon(libfwbuilder::FWObject *obj, QPixmap *pm, int icon_size); }; #endif // ICONSETTER_H fwbuilder-5.1.0.3599/src/libgui/FWCmdMoveObject.h0000644000175000017500000000501211733011756022125 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWCMDMOVEOBJECT_H #define FWCMDMOVEOBJECT_H #include "FWCmdChange.h" #include #include /******************************************************** * FWCmdMoveObject ********************************************************/ class FWCmdMoveObject : public FWCmdBasic { libfwbuilder::FWObject *old_parent; libfwbuilder::FWObject *new_parent; libfwbuilder::FWObject *current_parent; libfwbuilder::FWObject *obj; QString oldUserFolder; std::map > reference_holders; protected: virtual void notify(); public: FWCmdMoveObject(ProjectPanel *project, libfwbuilder::FWObject *old_parent, libfwbuilder::FWObject *new_parent, libfwbuilder::FWObject *obj, std::map > &reference_holders, QString text=QString(), QUndoCommand* macro = 0); ~FWCmdMoveObject(); virtual void redo(); virtual void undo(); }; /*************************************************************/ class FWCmdMoveToFromUserFolder : public FWCmdChange { int m_parentId; QString m_oldFolder; QString m_newFolder; public: FWCmdMoveToFromUserFolder(ProjectPanel *project, libfwbuilder::FWObject *parent, libfwbuilder::FWObject *obj, const QString &oldFolder, const QString &newFolder, QString text = QString(), QUndoCommand *macro = 0); virtual void redo(); virtual void undo(); }; #endif fwbuilder-5.1.0.3599/src/libgui/networkdialog_q.ui0000644000175000017500000001372411733011756022577 0ustar sylvestresylvestre NetworkDialog_q true 0 0 949 258 0 0 Network 0 0 QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Address: false 0 0 Netmask: false 0 0 Qt::Vertical 20 113 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name address netmask address editingFinished() NetworkDialog_q addressEntered() 218 106 355 143 address returnPressed() NetworkDialog_q addressEntered() 218 106 355 143
fwbuilder-5.1.0.3599/src/libgui/InterfacesTabWidget.ui0000644000175000017500000000130111733011756023250 0ustar sylvestresylvestre InterfacesTabWidget 0 0 400 300 TabWidget Tab 1 Tab 2 closeTab(int) fwbuilder-5.1.0.3599/src/libgui/fakeWizard.cpp0000644000175000017500000001167511733011756021645 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "fakeWizard.h" #include FakeWizard::FakeWizard() { } FakeWizard::~FakeWizard() { } void FakeWizard::setControlWidgets(QWidget *_mainWidget, QStackedWidget *_stackedWidget, QPushButton *_nextButton, QPushButton *_finishButton, QPushButton *_backButton, QPushButton *_cancelButton, QLabel *_titleLabel) { mainWidget = _mainWidget; stackedWidget = _stackedWidget; nextButton = _nextButton; finishButton = _finishButton; backButton =_backButton; titleLabel = _titleLabel; cancelButton = _cancelButton; m_pageCount = stackedWidget->count(); QObject::connect( nextButton, SIGNAL( clicked() ), mainWidget, SLOT( nextClicked() )); QObject::connect( backButton, SIGNAL( clicked() ), mainWidget, SLOT( backClicked() )); QObject::connect( finishButton, SIGNAL( clicked() ), mainWidget, SLOT( finishClicked() )); QObject::connect( cancelButton, SIGNAL( clicked() ), mainWidget, SLOT( cancelClicked() )); for (int i = 0; i < m_pageCount; i++) { appropriates.push_back(true); backEnabled.push_back(true); nextEnabled.push_back(true); finishEnabled.push_back(false); pageTitles.push_back(QString()); } backEnabled[0] = false; nextEnabled[m_pageCount-1] = false; m_currentPage = 0; } void FakeWizard::setAppropriate(const int page, const bool value) { if (page >= m_pageCount) return; appropriates[page] = value; } void FakeWizard::setNextEnabled(const int page, const bool enabled) { if (page >= m_pageCount) return; nextEnabled[page] = enabled; if (page == currentPage()) nextButton->setEnabled(enabled); } void FakeWizard::setBackEnabled(const int page, const bool enabled) { if (page >= m_pageCount) return; backEnabled[page] = enabled; if (page == currentPage()) backButton->setEnabled(enabled); } void FakeWizard::setFinishEnabled(const int page, const bool enabled) { if (page >= m_pageCount) return; finishEnabled[page] = enabled; if (page == currentPage()) finishButton->setEnabled(enabled); } void FakeWizard::setTitle(const int page, const QString title) { if (page >= m_pageCount) return; pageTitles[page] = title; if (page == currentPage()) if (titleLabel) titleLabel->setText(title); } int FakeWizard::pageCount() const { return stackedWidget->count(); } int FakeWizard::previousRelevant(const int page) const { if (fwbdebug) qDebug() << "FakeWizard::previousRelevant(" << page << ")"; int prev_p = -1; for (int i = page-1; i >= 0; i--) if (appropriates[i] && appropriate(i)) { prev_p = i; break; } if (fwbdebug) qDebug() << "FakeWizard::previousRelevant: previous page" << prev_p; return prev_p; } int FakeWizard::nextRelevant(const int page) const { if (fwbdebug) qDebug() << "FakeWizard::nextRelevant(" << page << ")"; int next_p = -1; for (int i = page+1; i < m_pageCount; i++) if (appropriates[i] && appropriate(i)) { next_p = i; break; } if (fwbdebug) qDebug() << "FakeWizard::nextRelevant: next page" << next_p; return next_p; } void FakeWizard::showPage(const int page) { if (page >= m_pageCount) return; nextButton->setEnabled(nextEnabled[page] && (nextRelevant(page) > -1) ); backButton->setEnabled(backEnabled[page] && (previousRelevant(page) > -1) ); finishButton->setEnabled(finishEnabled[page]); if (titleLabel) { if (!pageTitles[page].isEmpty()) { titleLabel->setText(pageTitles[page]); titleLabel->show(); } else titleLabel->hide(); } setCurrentPage(page); stackedWidget->setCurrentIndex(page); } int FakeWizard::currentPage() const { return m_currentPage; } void FakeWizard::setCurrentPage(const int page) { m_currentPage = page; } fwbuilder-5.1.0.3599/src/libgui/tagservicedialog_q.ui0000644000175000017500000001035311733011756023235 0ustar sylvestresylvestre TagServiceDialog_q 0 0 688 199 Form1 QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Code: false 0 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name tagcode
fwbuilder-5.1.0.3599/src/libgui/RoutingRuleOptionsDialog.h0000644000175000017500000000370211733011756024166 0ustar sylvestresylvestre/* Copyright (C) 2005 Compal GmbH, Germany Author: Roman Hoog Antink Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ROUTINGRULEOPTIONSDIALOG_H_ #define __ROUTINGRULEOPTIONSDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "DialogData.h" #include "fwbuilder/FWObject.h" class RuleSetView; class ProjectPanel; class RoutingRuleOptionsDialog : public BaseObjectDialog { Q_OBJECT; DialogData data; QString platform; RuleSetView *rsv; Ui::RoutingRuleOptionsDialog_q *m_dialog; public: RoutingRuleOptionsDialog(QWidget *parent); ~RoutingRuleOptionsDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // __ROUTINGRULEOPTIONSDIALOG_H fwbuilder-5.1.0.3599/src/libgui/SSHUnx.cpp0000644000175000017500000002405311733011756020700 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "SSHUnx.h" #include #include #include #include #include #include #include #include using namespace std; SSHUnx::SSHUnx(QWidget *_par, const QString &_h, const QStringList &args, const QString &_p, const QString &_ep, const list &_in) : SSHSession(_par,_h,args,_p,_ep,_in) { normal_prompt = "> "; enable_prompt = "# "; pwd_prompt_1 = "'s password: "; pwd_prompt_2 = "'s password: "; thinkfinger_pwd_prompt = "Password or swipe finger:"; epwd_prompt = "Password: "; ssh_pwd_prompt = "'s password: "; ssoft_config_prompt = "> "; sudo_pwd_prompt_1 = "Password:"; sudo_pwd_prompt_2 = "[sudo] password for "; putty_pwd_prompt = "Password: "; passphrase_prompt = "Enter passphrase for key "; errorsInit << "Permission denied"; errorsInit << "Invalid password"; errorsInit << "Unable to authenticate"; errorsInit << "Sorry, try again"; errorsInit << "Too many authentication failures"; errorsLoggedin << "No such file or directory"; errorsLoggedin << "Cannot allocate memory"; shell_errors << "Syntax error:"; shell_errors << "No command .* found"; shell_errors << "Command not found"; shell_errors << "[fF]ile .* does not exist"; // some ifconfig errors shell_errors << "[iI]nterface .* does not exist"; shell_errors << "ifconfig: .*: Device busy"; shell_errors << "permission denied"; shell_errors << "interface name too long"; shell_errors << "cloning name too long"; shell_errors << "error in parsing address"; shell_errors << "can't set"; shell_errors << ".* malformed"; shell_errors << ".* failed"; shell_errors << ".* not allowed for the AF"; shell_errors << "internal error"; shell_errors << "unable to allocate .*"; shell_errors << "unable to get .*"; shell_errors << "unknown .* protocol"; shell_errors << "[iI]nvalid .* protocol"; shell_errors << "Can't assign requested address"; // some /sbin/ip errors shell_errors << "Object .* is unknown, try \"ip help\""; shell_errors << "Cannot find device"; shell_errors << "Error: an inet prefix is expected rather than"; iptables_errors << "'iptables --help' for more information."; iptables_errors << "'iptables-restore --help' for more information."; iptables_errors << "iptables-restore: line .* failed"; pfctl_errors << "pfctl: Syntax error in config file:"; pfctl_errors << "Syntax error in config file:"; pfctl_errors << "skipping rule due to errors"; pfctl_errors << "errors in queue definition"; pfctl_errors << "error setting skip interface(s)"; pfctl_errors << "errors in altq config"; route_add_errors << "Error: Routing rule .* couldn't be activated"; } SSHUnx::~SSHUnx() { } bool SSHUnx::checkForErrors(QStringList *errptr) { #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug( QString("SSHUnx::stateMachine: Checking for errors. Buffer='%1'"). arg(stdoutBuffer).toAscii().constData()); #endif foreach (QString err, *errptr) { if (stdoutBuffer.lastIndexOf(QRegExp(err), -1) != -1) { if (fwbdebug) qDebug("SSHUnx::stateMachine: MATCH. Error detected."); emit printStdout_sign( tr("\n*** Fatal error :") ); emit printStdout_sign( stdoutBuffer + "\n" ); stdoutBuffer = ""; sessionComplete(true); // finish with error status return true; } } return false; } bool SSHUnx::checkForErrors() { switch (state) { case LOGGEDIN: if (checkForErrors(&errorsLoggedin)) return true; break; default: if (checkForErrors(&errorsInit)) return true; break; } if (checkForErrors(&iptables_errors)) return true; if (checkForErrors(&pfctl_errors)) return true; if (checkForErrors(&route_add_errors)) return true; if (checkForErrors(&shell_errors)) return true; return false; } void SSHUnx::stateMachine() { if (checkForErrors()) return; #if STATE_MACHINE_DEBUG if (fwbdebug) qDebug("SSHUnx::stateMachine: state=%d",state); #endif //entry: switch (state) { case NONE: { if ( cmpPrompt(stdoutBuffer, ssh_pwd_prompt) || cmpPrompt(stdoutBuffer, putty_pwd_prompt) || cmpPrompt(stdoutBuffer, thinkfinger_pwd_prompt) || stdoutBuffer.lastIndexOf(passphrase_prompt, -1)!=-1 || cmpPrompt(stdoutBuffer, sudo_pwd_prompt_1) || cmpPrompt(stderrBuffer, sudo_pwd_prompt_1) || cmpPrompt(stdoutBuffer, sudo_pwd_prompt_2) || cmpPrompt(stderrBuffer, sudo_pwd_prompt_2) ) { stdoutBuffer=""; proc->write( pwd.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,normal_prompt) || cmpPrompt(stdoutBuffer,fwb_prompt)) { state = PUSHING_CONFIG; // start sending keepalive chars (just "\n", done in // SSHSession::heartBeat()) to keep session alive and to // force firewall to restore session state after policy // has been reloaded and state possibly purged. // // Disabled for SF bug 3020381 // We should really use ssh kkepalives instead. See // FirewallInstaller::packSSHArgs() where we add command lne // options to activate ssh keepalive. This does not work // on Windows with plink.exe that does not support these // command line options ! // // #ifdef _WIN32 send_keepalive = true; #endif if (!quiet) emit printStdout_sign( tr("Logged in") + "\n" ); if (fwbdebug) qDebug("SSHUnx::stateMachine logged in"); goto push_files; } if (fwbdebug) qDebug() << stdoutBuffer; QString fingerprint; //int n1,n2; if (stdoutBuffer.indexOf(newKeyOpenSSH)!=-1 || stdoutBuffer.indexOf(newKeyPlink)!=-1 || stdoutBuffer.indexOf(newKeyVsh)!=-1 || stdoutBuffer.indexOf(newKeySSHComm)!=-1) { /* new key */ bool unix_y_n = (stdoutBuffer.indexOf(newKeyOpenSSH)!=-1 || stdoutBuffer.indexOf(newKeySSHComm)!=-1); fingerprint = findKeyFingerprint(stdoutBuffer); QString msg = newKeyMsg.arg(host).arg(fingerprint).arg(host); stopHeartBeat(); int res =QMessageBox::warning( parent, tr("New RSA key"), msg, tr("Yes"), tr("No"), 0, 0, -1 ); if (fwbdebug) qDebug("User said: res=%d", res); startHeartBeat(); stdoutBuffer=""; if (res==0) { if (unix_y_n) proc->write( "yes\n" ); else proc->write( "y\n" ); break; } else { sessionComplete(true); // finish with error status return; // state=EXIT; // goto entry; } } } break; /* in this state we may need to enter sudo password */ case PUSHING_CONFIG: push_files: if ( cmpPrompt(stdoutBuffer, sudo_pwd_prompt_1) || cmpPrompt(stderrBuffer, sudo_pwd_prompt_1) || cmpPrompt(stdoutBuffer, sudo_pwd_prompt_2) || cmpPrompt(stderrBuffer, sudo_pwd_prompt_2) ) { stdoutBuffer=""; proc->write( pwd.toAscii() ); proc->write( "\n" ); break; } /* if (!quiet && !verbose) { emit printStdout_sign( stdoutBuffer ); } */ stdoutBuffer=""; if (input.size()!=0) { if (fwbdebug) qDebug("SSHUnx::stateMachine - sending a file"); emit updateProgressBar_sign(input.size(),true); connect(proc,SIGNAL(bytesWritten(qint64)),this,SLOT(readyToSend())); sendLine(); break; } break; /* we get to this state when previous ssh or scp command terminates */ case FINISH: if ( (proc->state()==QProcess::NotRunning) && (proc->exitStatus()==QProcess::NormalExit)) { emit printStdout_sign( "\n"); emit printStdout_sign( tr("Done") ); emit printStdout_sign( "\n"); delete proc; proc=NULL; state=NONE; break; } else { emit printStdout_sign( "\n"); emit printStdout_sign( tr("Error in SSH") ); emit printStdout_sign( "\n"); // terminate(); sessionComplete(true); // finish with error status proc=NULL; } emit sessionFinished_sign(); break; default: break; } } fwbuilder-5.1.0.3599/src/libgui/FirewallDialog.h0000644000175000017500000000320511733011756022076 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FIREWALLDIALOG_H_ #define __FIREWALLDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class FirewallDialog : public BaseObjectDialog { Q_OBJECT; Ui::FirewallDialog_q *m_dialog; void fillVersion(); void saveVersion(libfwbuilder::FWObject *o); void updateTimeStamps(); public: FirewallDialog(QWidget *parent); ~FirewallDialog(); public slots: virtual void applyChanges(); virtual void platformChanged(); virtual void hostOSChanged(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void openFWDialog(); virtual void openOSDialog(); }; #endif // FIREWALLDIALOG_H fwbuilder-5.1.0.3599/src/libgui/startup_tip_url.h0000644000175000017500000000200511733011756022446 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef STARTUP_TIP_URL_HH #define STARTUP_TIP_URL_HH #include "../../VERSION.h" #define STARTUP_TIP_URL "http://update.fwbuilder.org/tips/gettip.cgi?v="VERSION #endif fwbuilder-5.1.0.3599/src/libgui/LibExportDialog.cpp0000644000175000017500000000606711733011756022605 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWWindow.h" #include "LibExportDialog.h" #include "FWBSettings.h" #include "longTextDialog.h" #include "ProjectPanel.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Interface.h" #include #include #include #include #include #include #include #include #include #include #ifndef _WIN32 # include // for access(2) #endif #include #include using namespace std; using namespace libfwbuilder; LibExportDialog::~LibExportDialog() { delete m_dialog; } LibExportDialog::LibExportDialog( QWidget* parent, const char* name, bool ) : QDialog(parent) { setWindowTitle(name); m_dialog = new Ui::LibExport_q; m_dialog->setupUi(this); init(); } void LibExportDialog::init() { // resize( QSize(500, 450) ); m_dialog->exportRO->setChecked(true); m_dialog->libs->clear(); list ll = mw->activeProject()->db()->getByType(Library::TYPENAME); int n=0; string libicn; for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++,n++) { /*if (libicn.empty()) libicn=Resources::global_res->getObjResourceStr(*i,"icon-tree").c_str();*/ mapOfLibs[n]= (*i); QPixmap pm; QString icn = (":/Icons/" + (*i)->getTypeName() + "/icon-tree").c_str(); //QString icn = libicn.c_str(); if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } QListWidgetItem *item = new QListWidgetItem(QString::fromUtf8((*i)->getName().c_str())); item->setIcon(QIcon(pm)); /*m_dialog->libs->addItem(QIcon(pm), QString::fromUtf8((*i)->getName().c_str()), n);*/ m_dialog->libs->addItem(item); } } fwbuilder-5.1.0.3599/src/libgui/newGroupDialog.cpp0000644000175000017500000000311711733011756022474 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBApplication.h" #include "newGroupDialog.h" #include #include #include using namespace libfwbuilder; using namespace std; newGroupDialog::~newGroupDialog() { delete m_dialog; } newGroupDialog::newGroupDialog(QWidget *parent, FWObjectDatabase *_db) : QDialog(parent) { db = _db; m_dialog = new Ui::newGroupDialog_q; m_dialog->setupUi(this); fillLibraries(m_dialog->libs, db, true); // only read-write libs m_dialog->obj_name->setFocus(); } void newGroupDialog::accept() { /* create a group */ if (m_dialog->obj_name->text().isEmpty()) { app->beep(); return; } QDialog::accept(); } fwbuilder-5.1.0.3599/src/libgui/HostDialog.h0000644000175000017500000000255111733011756021251 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __HOSTDIALOG_H_ #define __HOSTDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class HostDialog : public BaseObjectDialog { Q_OBJECT; Ui::HostDialog_q *m_dialog; public: HostDialog(QWidget *parent); ~HostDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // HOSTDIALOG_H fwbuilder-5.1.0.3599/src/libgui/rulesetdialog_q.ui0000644000175000017500000001714011733011756022565 0ustar sylvestresylvestre RuleSetDialog_q true 0 0 824 260 0 0 Ruleset QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 1 0 200 0 16777215 250 Rule set: 0 0 250 16777215 false IPv4 IPv6 IPv4 and IPv6 Qt::Horizontal 130 20 Top ruleset true 0 0 0 0 16777215 16777215 Qt::LeftToRight false Table Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop false false mangle table filter+mangle table Qt::Vertical 20 26 0 0 CommentKeywords QWidget
CommentKeywords.h
1
changed()
fwbuilder-5.1.0.3599/src/libgui/UsageResolver.cpp0000644000175000017500000002434111733011756022336 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland Refactoring: Roman Bovsunivskiy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UsageResolver.h" #include #include #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Management.h" #include "fwbuilder/RuleSet.h" #include using namespace std; using namespace libfwbuilder; int UsageResolver::search_id_seed = 0; UsageResolver::UsageResolver() { search_id = search_id_seed; search_id_seed++; } /* * per bug #2412334, FWObjectDatabase::findWhereObjectIsUsed finds * only "direct" uses of @obj (i.e. it finds group @obj is member of, * but not other groups or rules the group is member of). However here * we need to find all objects that use @obj, including nested groups * and so on. This method is recursive wrapper around * FWObjectDatabase::findWhereObjectIsUsed() that does this. * */ void UsageResolver::findWhereUsedRecursively( FWObject *obj, FWObject *top, set &resset, FWObjectDatabase* db) { if (fwbdebug) qDebug() << "UsageResolver::findWhereUsedRecursively obj=" << obj->getName().c_str() << "(" << obj->getTypeName().c_str() << ")"; set new_obj_set; set resset_tmp_2; /* * findWhereObjectIsUsed() finds references to object 'obj' in a subtree * rooted at object 'top'. */ db->findWhereObjectIsUsed(obj, top, resset_tmp_2); /* * skip objects that are already in resset because they were found on previous * passes (recursive calls) */ set::iterator i = resset.begin(); for ( ; i!=resset.end(); ++i) if (resset_tmp_2.count(*i)) resset_tmp_2.erase(*i); /* * skip objects we have already seen to break recursive loops in rule branches */ for (i=resset_tmp_2.begin(); i!=resset_tmp_2.end(); ++i) { if ((*i)->getInt(".usage_resolver_seach_id") != search_id) { new_obj_set.insert(*i); (*i)->setInt(".usage_resolver_seach_id", search_id); } } resset.insert(new_obj_set.begin(), new_obj_set.end()); for (i = new_obj_set.begin(); i!=new_obj_set.end(); ++i) { FWObject *parent_obj = *i; FWReference *ref = FWReference::cast(parent_obj); if (ref && RuleElement::cast(ref->getParent()) == NULL) { // NB! We need parent of this ref for regular groups There // is no need to repeat search for the parent if it is // RuleElement because rule elements can not be members of // groups parent_obj = ref->getParent(); } if (fwbdebug) qDebug() << "UsageResolver::findWhereUsedRecursively" << "parent_obj=" << parent_obj->getName().c_str() << "(" << parent_obj->getTypeName().c_str() << ")"; // add new results to a separate set to avoid modifying the new_obj_set // in the middle of iteration if (Group::cast(parent_obj) && !RuleElement::cast(parent_obj)) findWhereUsedRecursively(parent_obj, top, resset, db); } } list UsageResolver::findFirewallsForObject(FWObject *o, FWObjectDatabase *db) { if (fwbdebug) qDebug("UsageResolver::findFirewallsForObject"); list fws; set resset; QTime tt; tt.start(); FWObject *f=o; while (f!=NULL && !Firewall::cast(f)) f=f->getParent(); if (f) fws.push_back(Firewall::cast(f)); findWhereUsedRecursively(o, db, resset, db); //FindWhereUsedWidget::humanizeSearchResults(resset); if (fwbdebug) { qDebug() << "UsageResolver::findFirewallsForObject" << "resset.size()=" << resset.size(); set::iterator i = resset.begin(); for ( ;i!=resset.end(); ++i) { FWObject *obj = *i; qDebug() << "UsageResolver::findFirewallsForObject" << obj->getName().c_str() << "(" << obj->getTypeName().c_str() << ")"; } } // whenever we find that a rule has been modified by the change in // the object @o, we record rule set it belongs to. We should scan // other rule sets to see if some rule somewhere might be using // one of the rule sets that changed as a branch. However in a // common situation where many rules of the same rule set are // affected, it won't make sense to search for the dependencies on // the same rule set many times. set modified_rule_sets; set::iterator i = resset.begin(); for ( ;i!=resset.end(); ++i) { FWObject *obj = *i; // We only want cluster (to pick up member changes) and rule elements if (Cluster::isA(obj)) fws.push_back(Firewall::cast(obj)); FWReference *ref = FWReference::cast(*i); if (ref && RuleElement::cast(ref->getParent()) != NULL) { obj = ref->getParent(); } Rule *r = Rule::cast(obj); if (r == NULL) r = Rule::cast(obj->getParent()); if (r && !r->isDisabled()) { f = r; while (f!=NULL && Firewall::cast(f) == NULL) f = f->getParent(); if (f && std::find(fws.begin(), fws.end(), f) == fws.end()) { fws.push_back(Firewall::cast(f)); } // check if some rule somewhere may use @ruleset as a // branch RuleSet *ruleset = RuleSet::cast(r->getParent()); assert(ruleset != NULL); modified_rule_sets.insert(ruleset); } } set::iterator i1 = modified_rule_sets.begin(); for ( ;i1!=modified_rule_sets.end(); ++i1) { RuleSet *ruleset = *i1; list other_fws = UsageResolver::findFirewallsForObject(ruleset, db); for (list::iterator fit = other_fws.begin(); fit != other_fws.end(); ++fit) { if (std::find(fws.begin(), fws.end(), *fit) == fws.end()) fws.push_back(*fit); } } if (fwbdebug) { qDebug() << QString("Program spent %1 ms searching for firewalls.") .arg(tt.elapsed()); qDebug() << "UsageResolver::findFirewallsForObject returns"; for (list::iterator i = fws.begin(); i!=fws.end(); ++i) { qDebug() << " " << (*i)->getName().c_str(); } } return fws; } /* * another wrapper around FWObjectDatabase::findWhereObjectIsUsed This * method finds all rule elements and groups that have references to * @obj and any of its children. The key in the map @res is object ID * and the value is a set of all Groups or RE that hold references to * it. */ void UsageResolver::findAllReferenceHolders( FWObject *obj, FWObject *root, std::map > &res) { set reference_holders; set res_tmp; root->getRoot()->findWhereObjectIsUsed(obj, root->getRoot(), res_tmp); foreach(FWObject* o, res_tmp) { if (fwbdebug) qDebug() << "UsageResolver::findAllReferenceHolders" << "obj=" << obj->getName().c_str() << "(" << obj->getTypeName().c_str() << ")" << "container=" << o->getName().c_str() << "(" << o->getTypeName().c_str() << ")"; if (FWReference::cast(o)) { FWObject *holder = o->getParent(); reference_holders.insert(holder); } if (Rule::cast(o) || Interface::cast(o)) reference_holders.insert(o); } int obj_id = obj->getId(); foreach(FWObject *o, reference_holders) { res[obj_id].insert(o); } for (FWObject::iterator i=obj->begin(); i!=obj->end(); ++i) { if ((*i)->getId() == -1) continue; if (FWOptions::cast(*i)) continue; if (FWReference::cast(*i)) continue; if (RuleElement::cast(*i)) continue; if (Rule::cast(*i)) continue; UsageResolver::findAllReferenceHolders(*i, root, res); } } /* * This method post-processes the list of objects found by * findFirewallsForObject to make them suitable for presentation. * First, it does deduplication. Event showObjectInRulesetEvent that * finds an object and highlights it in rules requires reference or * object itself as an argument. So, when parent is RuleElement, we * preserve the reference. But for regular groups we find and * highlight the group itself, so in that case replace reference to * the object with the group, which is its parent. * */ void UsageResolver::humanizeSearchResults(std::set &resset) { set tmp_res; // set deduplicates items automatically set::iterator i = resset.begin(); for (;i!=resset.end();++i) { FWObject *obj = *i; if (fwbdebug) qDebug() << "humanizeSearchResults:" << obj->getName().c_str() << " (" << obj->getTypeName().c_str() << ")"; FWReference *ref = FWReference::cast(*i); if (ref && RuleElement::cast(ref->getParent()) == NULL) { obj = ref->getParent(); // NB! We need parent of this ref for groups } else obj = *i; tmp_res.insert(obj); } resset.clear(); resset = tmp_res; } fwbuilder-5.1.0.3599/src/libgui/InstallFirewallViewItem.cpp0000644000175000017500000000215111733011756024311 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "InstallFirewallViewItem.h" using namespace std; using namespace libfwbuilder; InstallFirewallViewItem::InstallFirewallViewItem(QTreeWidget* parent, const QString& st, bool slt ): QTreeWidgetItem(parent, QStringList(st)) { showLastTimes = slt; } fwbuilder-5.1.0.3599/src/libgui/textfileeditor_q.ui0000644000175000017500000000623511733011756022760 0ustar sylvestresylvestre TextFileEditor_q true 0 0 592 344 Qt::StrongFocus Script Editor 11 Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn Qt::Horizontal QSizePolicy::Expanding 40 20 Save true Cancel 0 0 QFrame::HLine QFrame::Sunken Qt::Horizontal editor ok_button cancel_button ok_button clicked() TextFileEditor_q save() 20 20 20 20 cancel_button clicked() TextFileEditor_q reject() 20 20 20 20 save() fwbuilder-5.1.0.3599/src/libgui/IPv4Dialog.cpp0000644000175000017500000002001211733011756021441 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "IPv4Dialog.h" #include "ProjectPanel.h" #include "fwbuilder/Library.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; IPv4Dialog::IPv4Dialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::IPv4Dialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } IPv4Dialog::~IPv4Dialog() { delete m_dialog; } void IPv4Dialog::loadFWObject(FWObject *o) { obj=o; IPv4 *s = dynamic_cast(obj); assert(s!=NULL); dnsBusy=false; init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); /* * if this is an address that belongs to an interface, we can't move * it from library to library just like that. Only IPv4 objects that * belong to the standard group "Addresses" can be moved. */ if ( Interface::isA( obj->getParent() ) ) { showNetmask=true; m_dialog->netmaskLabel->show(); m_dialog->netmask->show(); } else { showNetmask=false; m_dialog->netmaskLabel->hide(); m_dialog->netmask->hide(); } /* catch exceptions separately so even if we have a bad address, we * still can show netmask */ try { m_dialog->address->setText( s->getAddressPtr()->toString().c_str() ); } catch (FWException &ex) {} try { if ( Interface::isA( obj->getParent() ) ) m_dialog->netmask->setText( s->getNetmaskPtr()->toString().c_str() ); } catch (FWException &ex) {} //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->address->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->address); m_dialog->netmask->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->netmask); m_dialog->dnsLookup->setEnabled(!o->isReadOnly()); init=false; } void IPv4Dialog::validate(bool *result) { if (fwbdebug) qDebug() << "IPv4Dialog::validate()"; *result=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *result=false; return; } IPv4 *s = dynamic_cast(obj); assert(s!=NULL); try { InetAddr( m_dialog->address->text().trimmed().toLatin1().constData() ); } catch (FWException &ex) { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this, "Firewall Builder", tr("Illegal IP address '%1'").arg(m_dialog->address->text()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } if (showNetmask) { try { InetAddr nm( m_dialog->netmask->text().trimmed().toLatin1().constData() ); if (!nm.isValidV4Netmask()) { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); // Do not allow netmask with zeroes inside. QMessageBox::critical( this, "Firewall Builder", tr("Netmasks with zeroes in the middle are not supported"), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } return; } } catch (FWException &ex) { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this, "Firewall Builder", tr("Illegal netmask '%1'").arg(m_dialog->netmask->text()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } } } void IPv4Dialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); IPv4 *s = dynamic_cast(new_state); assert(s!=NULL); new_state->setName(m_dialog->obj_name->text().toUtf8().constData()); m_dialog->commentKeywords->applyChanges(new_state); try { s->setAddress( InetAddr(m_dialog->address->text().trimmed().toLatin1().constData()) ); } catch (FWException &ex) { } if ( showNetmask ) { try { s->setNetmask( InetAddr(m_dialog->netmask->text().trimmed().toLatin1().constData()) ); } catch (FWException &ex) { } } else s->setNetmask(InetAddr()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void IPv4Dialog::DNSlookup() { if (fwbdebug) qDebug("IPv4Dialog::DNSlookup() dnsBusy=%d", dnsBusy); if (!dnsBusy) { QString name = m_dialog->obj_name->text().trimmed(); if (fwbdebug) qDebug("IPv4Dialog::DNSlookup() name=%s", name.toAscii().constData()); dnsBusy=true; QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString addr = getAddrByName(name, AF_INET); QApplication::restoreOverrideCursor(); dnsBusy=false; if (fwbdebug) qDebug("IPv4Dialog::DNSlookup() done"); if (! addr.isEmpty()) { m_dialog->address->setText( addr ); changed(); return; } if ( Interface::isA(obj->getParent()) ) { FWObject *host = obj->getParent()->getParent(); assert(host!=NULL); name = host->getName().c_str(); if (fwbdebug) qDebug("IPv4Dialog::DNSlookup() name=%s", name.toAscii().constData()); dnsBusy=true; QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString addr = getAddrByName(name, AF_INET); QApplication::restoreOverrideCursor(); dnsBusy=false; if (fwbdebug) qDebug("IPv4Dialog::DNSlookup() done"); if ( ! addr.isEmpty()) { m_dialog->address->setText( addr ); changed(); return; } QMessageBox::warning( this,"Firewall Builder", tr("DNS lookup failed for both names of the address object '%1' and the name of the host '%2'.") .arg(m_dialog->obj_name->text()).arg(name), "&Continue", QString::null,QString::null, 0, 1 ); return; } QMessageBox::warning( this,"Firewall Builder", tr("DNS lookup failed for name of the address object '%1'.") .arg(name), "&Continue", QString::null,QString::null, 0, 1 ); return; } } fwbuilder-5.1.0.3599/src/libgui/FirewallCodeViewer.cpp0000644000175000017500000000416611733011756023275 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FirewallCodeViewer.h" #include "ui_FirewallCodeViewer.h" #include #include #include FirewallCodeViewer::FirewallCodeViewer(QStringList files, QString name, QWidget *parent) : QDialog(parent), ui(new Ui::FirewallCodeViewer_q) { ui->setupUi(this); this->files = files; foreach(QString file, files) ui->fileSelector->addItem(file.split("/").last()); fileSelected(0); ui->path->setText(name); } FirewallCodeViewer::~FirewallCodeViewer() { delete ui; } void FirewallCodeViewer::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void FirewallCodeViewer::fileSelected(int idx) { if (pages.contains(idx)) { ui->pages->setCurrentIndex(pages[idx]); } else { QFile f(this->files.at(idx)); f.open(QFile::ReadOnly); QTextBrowser *browser = new QTextBrowser(ui->pages); browser->setPlainText(f.readAll()); ui->pages->addWidget(browser); pages.insert(idx, ui->pages->indexOf(browser)); ui->pages->setCurrentWidget(browser); } } void FirewallCodeViewer::hideCloseButton() { ui->closeButton->hide(); } fwbuilder-5.1.0.3599/src/libgui/FWObjectClipboard.cpp0000644000175000017500000000611111733011756023026 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000-2004 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "FWObjectClipboard.h" #include "FWWindow.h" #include "ProjectPanel.h" using namespace std; using namespace libfwbuilder; FWObjectClipboard* FWObjectClipboard::obj_clipboard=NULL; FWObjectClipboard::FWObjectClipboard() { assert(obj_clipboard==NULL); obj_clipboard=this; } FWObjectClipboard::~FWObjectClipboard() { clear(); obj_clipboard=NULL; } void FWObjectClipboard::clear() { if (fwbdebug) qDebug("FWObjectClipboard::clear size()=%d", int(size())); for (vector >::iterator i=ids.begin(); i!=ids.end(); ++i) { int obj_id = i->first; ProjectPanel *proj_p = i->second; assert(proj_p); FWObject *obj = proj_p->db()->findInIndex(obj_id); if (obj) { if (fwbdebug) qDebug("FWObjectClipboard::clear unref obj=%p (%s)", obj, obj->getName().c_str()); obj->unref(); } } ids.clear(); } void FWObjectClipboard::add(FWObject *obj, ProjectPanel * proj_p) { if (fwbdebug) { qDebug("FWObjectClipboard::add obj=%p (id=%d %s) proj_p=%p", obj, obj->getId(), FWObjectDatabase::getStringId(obj->getId()).c_str(), proj_p ); } obj->ref(); ids.push_back( pair(obj->getId(), proj_p) ); } void FWObjectClipboard::remove(FWObject* obj) { int id = obj->getId(); for (vector >::iterator i=ids.begin(); i!=ids.end(); ++i) { int obj_id = i->first; if (obj_id == id) { ids.erase(i); break; } } } FWObject* FWObjectClipboard::getObject() { if (ids.size()>0) { pair p = ids.back(); return p.second->db()->findInIndex( p.first ); } else return NULL; } FWObject* FWObjectClipboard::getObjectByIdx (int idx) { if (idx < int(ids.size())) { pair p = ids[idx]; return p.second->db()->findInIndex( p.first ); } else return NULL; } fwbuilder-5.1.0.3599/src/libgui/aboutdialog_q.ui0000644000175000017500000004060611733011756022217 0ustar sylvestresylvestre AboutDialog_q true 0 0 419 311 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 127 127 127 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 127 127 127 255 255 255 127 127 127 255 255 255 255 255 255 0 0 0 255 255 255 Firewall Builder true 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:28pt;">Firewall Builder %1</span></p></body></html> Qt::AlignCenter Revision: Qt::AlignCenter false 0 0 Using libfwbuilder API v Qt::AlignCenter false Qt::Vertical QSizePolicy::Expanding 20 20 0 0 Copyright 2002-2011 NetCitadel, Inc Qt::AlignCenter false 0 20 32767 20 QFrame::NoFrame QFrame::Plain -3 Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.fwbuilder.org"><span style=" font-family:'Lucida Grande'; font-size:13pt; text-decoration: underline; color:#0000ff;">http://www.fwbuilder.org</span></a></p></body></html> false 0 0 QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true buttonOk clicked() AboutDialog_q accept() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/SSHUnx.h0000644000175000017500000000304111733011756020337 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SSHUNX_H_ #define __SSHUNX_H_ #include "config.h" #include "global.h" #include "SSHSession.h" #include #include class SSHUnx : public SSHSession { Q_OBJECT; QStringList shell_errors; QStringList iptables_errors; QStringList pfctl_errors; QStringList route_add_errors; public: SSHUnx(QWidget *parent, const QString &host, const QStringList &args, const QString &pwd, const QString &epwd, const std::list &in); virtual ~SSHUnx(); virtual bool checkForErrors(); virtual void stateMachine(); bool checkForErrors(QStringList *errptr); }; #endif fwbuilder-5.1.0.3599/src/libgui/RuleOptionsDialog.cpp0000644000175000017500000004771111733011756023161 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "ProjectPanel.h" #include "RuleOptionsDialog.h" #include "RuleSetView.h" #include "FWWindow.h" #include "FWCmdRule.h" #include "FWObjectDropArea.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; RuleOptionsDialog::~RuleOptionsDialog() { delete m_dialog; } RuleOptionsDialog::RuleOptionsDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::RuleOptionsDialog_q; m_dialog->setupUi(this); m_dialog->pfTagDropArea->addAcceptedTypes("TagService"); m_dialog->iptTagDropArea->addAcceptedTypes("TagService"); connectSignalsOfAllWidgetsToSlotChange(); firewall = NULL; init=false; } void RuleOptionsDialog::loadFWObject(FWObject *o) { obj = o; firewall = o; // use Firewall::cast to match both Firewall and Cluster while (!Firewall::cast(firewall)) firewall = firewall->getParent(); platform = firewall->getStr("platform").c_str(); string version = firewall->getStr("version"); // build a map for combobox so visible combobox items can be localized QStringList route_options = getRouteOptions_pf_ipf(platform); QStringList route_load_options = getRouteLoadOptions_pf(platform); QStringList classify_options_ipfw = getClassifyOptions_ipfw(platform); Rule *rule = dynamic_cast(o); FWOptions *ropt = rule->getOptionsObject(); PolicyRule *policy_rule = PolicyRule::cast(rule); int wid=0; if (platform=="iptables") wid=0; if (platform=="ipf") wid=1; if (platform=="pf") wid=2; if (platform=="ipfw") wid=3; if (platform=="pix" || platform=="fwsm") wid=4; if (platform=="iosacl" || platform=="procurve_acl") wid=5; m_dialog->wStack->widget(wid)->raise(); m_dialog->wStack->setCurrentWidget(m_dialog->wStack->widget(wid)); QStringList logLevels=getLogLevels( obj->getStr("platform").c_str() ); m_dialog->ipt_logLevel->clear(); m_dialog->ipt_logLevel->addItems(getScreenNames(logLevels)); m_dialog->ipf_logLevel->clear(); m_dialog->ipf_logLevel->addItems(getScreenNames(logLevels)); m_dialog->pix_logLevel->clear(); m_dialog->pix_logLevel->addItems(getScreenNames(logLevels)); QStringList logFacilities=getLogFacilities( obj->getStr("platform").c_str()); m_dialog->ipf_logFacility->clear(); m_dialog->ipf_logFacility->addItems(getScreenNames(logFacilities)); QStringList limitSuffixes=getLimitSuffixes( obj->getStr("platform").c_str()); m_dialog->ipt_limitSuffix->clear(); m_dialog->ipt_limitSuffix->addItems(getScreenNames(limitSuffixes)); m_dialog->ipt_hashlimit_suffix->clear(); m_dialog->ipt_hashlimit_suffix->addItems(getScreenNames(limitSuffixes)); fillInterfaces(m_dialog->ipt_iif); fillInterfaces(m_dialog->ipt_oif); fillInterfaces(m_dialog->ipf_route_opt_if); fillInterfaces(m_dialog->pf_route_opt_if); data.clear(); if (platform=="iptables") { data.registerOption(m_dialog->ipt_logPrefix, ropt, "log_prefix"); data.registerOption(m_dialog->ipt_logLevel, ropt, "log_level", logLevels); data.registerOption(m_dialog->ipt_nlgroup, ropt, "ulog_nlgroup"); data.registerOption(m_dialog->ipt_limit, ropt, "limit_value"); data.registerOption(m_dialog->ipt_limitSuffix, ropt, "limit_suffix", limitSuffixes); data.registerOption(m_dialog->ipt_limit_not, ropt, "limit_value_not"); data.registerOption(m_dialog->ipt_burst, ropt, "limit_burst"); data.registerOption(m_dialog->ipt_connlimit, ropt, "connlimit_value"); data.registerOption(m_dialog->ipt_connlimit_above_not, ropt, "connlimit_above_not"); data.registerOption(m_dialog->ipt_connlimit_masklen, ropt, "connlimit_masklen"); data.registerOption(m_dialog->ipt_hashlimit, ropt, "hashlimit_value"); data.registerOption(m_dialog->ipt_hashlimit_suffix, ropt, "hashlimit_suffix"); data.registerOption(m_dialog->ipt_hashlimit_burst, ropt, "hashlimit_burst"); data.registerOption(m_dialog->cb_srcip, ropt, "hashlimit_mode_srcip"); data.registerOption(m_dialog->cb_dstip, ropt, "hashlimit_mode_dstip"); data.registerOption(m_dialog->cb_srcport, ropt, "hashlimit_mode_srcport"); data.registerOption(m_dialog->cb_dstport, ropt, "hashlimit_mode_dstport"); data.registerOption(m_dialog->ipt_hashlimit_dstlimit, ropt, "hashlimit_dstlimit"); data.registerOption(m_dialog->ipt_hashlimit_name, ropt, "hashlimit_name"); data.registerOption(m_dialog->ipt_hashlimit_size, ropt, "hashlimit_size"); data.registerOption(m_dialog->ipt_hashlimit_max, ropt, "hashlimit_max"); data.registerOption(m_dialog->ipt_hashlimit_expire, ropt, "hashlimit_expire"); data.registerOption(m_dialog->ipt_hashlimit_gcinterval, ropt, "hashlimit_gcinterval"); // in v3.0 attribute "assume fw is part of any" used to be a // checkbox and therefore stored as boolean in the rule // options. Old "on" maps to the new "on", which means old "True" // maps to "1". Old "off" maps to "use global" though. string old_val = ropt->getStr("firewall_is_part_of_any_and_networks"); if (old_val == "True") ropt->setStr("firewall_is_part_of_any_and_networks", "1"); if (old_val == "False") ropt->setStr("firewall_is_part_of_any_and_networks", ""); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("Follow global setting")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption(m_dialog->ipt_assume_fw_is_part_of_any, ropt, "firewall_is_part_of_any_and_networks", threeStateMapping); data.registerOption(m_dialog->ipt_stateless, ropt, "stateless"); data.registerOption(m_dialog->ipt_mark_connections, ropt, "ipt_mark_connections"); data.registerOption(m_dialog->classify_str, ropt, "classify_str"); // Route data.registerOption(m_dialog->ipt_iif, ropt, "ipt_iif" ); data.registerOption(m_dialog->ipt_oif, ropt, "ipt_oif" ); data.registerOption(m_dialog->ipt_gw, ropt, "ipt_gw" ); data.registerOption(m_dialog->ipt_continue, ropt, "ipt_continue" ); data.registerOption(m_dialog->ipt_tee, ropt, "ipt_tee"); FWObject *o = policy_rule->getTagObject(); m_dialog->iptTagDropArea->setObject(o); m_dialog->iptTagDropArea->update(); } if (platform=="ipf") { data.registerOption(m_dialog->ipf_logFacility, ropt, "ipf_log_facility", logFacilities); data.registerOption(m_dialog->ipf_logLevel, ropt, "log_level", logLevels); data.registerOption(m_dialog->ipf_masq_icmp, ropt, "ipf_return_icmp_as_dest"); data.registerOption(m_dialog->ipf_stateless, ropt, "stateless"); data.registerOption(m_dialog->ipf_keep_frags, ropt, "ipf_keep_frags"); // Route data.registerOption(m_dialog->ipf_route_option, ropt, "ipf_route_option", route_options); data.registerOption(m_dialog->ipf_route_opt_if, ropt, "ipf_route_opt_if"); data.registerOption(m_dialog->ipf_route_opt_addr, ropt, "ipf_route_opt_addr"); } if (platform=="pf") { bool ge_4_5 = XMLTools::version_compare(version, "4.5")>=0; m_dialog->pf_no_sync->setEnabled(ge_4_5); m_dialog->pf_pflow->setEnabled(ge_4_5); data.registerOption(m_dialog->pf_logPrefix, ropt, "log_prefix"); data.registerOption(m_dialog->pf_stateless, ropt, "stateless"); data.registerOption(m_dialog->pf_keep_state, ropt, "pf_keep_state"); data.registerOption(m_dialog->pf_no_sync, ropt, "pf_no_sync"); data.registerOption(m_dialog->pf_pflow, ropt, "pf_pflow"); data.registerOption(m_dialog->pf_sloppy_tracker, ropt, "pf_sloppy_tracker"); data.registerOption(m_dialog->pf_rule_max_state, ropt, "pf_rule_max_state"); data.registerOption(m_dialog->pf_source_tracking, ropt, "pf_source_tracking"); data.registerOption(m_dialog->pf_max_src_nodes, ropt, "pf_max_src_nodes"); data.registerOption(m_dialog->pf_max_src_states, ropt, "pf_max_src_states"); data.registerOption(m_dialog->pf_max_src_conn, ropt, "pf_max_src_conn"); data.registerOption(m_dialog->pf_overload_table, ropt, "pf_max_src_conn_overload_table"); data.registerOption(m_dialog->pf_flush, ropt, "pf_max_src_conn_flush"); data.registerOption(m_dialog->pf_global, ropt, "pf_max_src_conn_global"); data.registerOption(m_dialog->pf_max_src_conn_rate_num, ropt, "pf_max_src_conn_rate_num"); data.registerOption(m_dialog->pf_max_src_conn_rate_seconds, ropt, "pf_max_src_conn_rate_seconds"); data.registerOption(m_dialog->pf_modulate, ropt, "pf_modulate_state"); data.registerOption(m_dialog->pf_synproxy, ropt, "pf_synproxy"); // Tag FWObject *o = policy_rule->getTagObject(); m_dialog->pfTagDropArea->setObject(o); m_dialog->pfTagDropArea->update(); // Classify data.registerOption(m_dialog->pf_classify_str, ropt, "pf_classify_str"); // Route data.registerOption(m_dialog->pf_fastroute, ropt, "pf_fastroute"); data.registerOption(m_dialog->pf_route_load_option, ropt, "pf_route_load_option", route_load_options); data.registerOption(m_dialog->pf_route_option, ropt, "pf_route_option", route_options); data.registerOption(m_dialog->pf_route_opt_if, ropt, "pf_route_opt_if"); data.registerOption(m_dialog->pf_route_opt_addr, ropt, "pf_route_opt_addr"); } if (platform=="ipfw") { data.registerOption(m_dialog->ipfw_stateless, ropt, "stateless"); /* #2367 */ // Classify data.registerOption(m_dialog->ipfw_classify_method, ropt, "ipfw_classify_method", classify_options_ipfw); data.registerOption(m_dialog->usePortNum, ropt, "ipfw_pipe_queue_num"); } if (platform=="iosacl" || platform=="procurve_acl") { data.registerOption(m_dialog->iosacl_add_mirror_rule, ropt, "iosacl_add_mirror_rule"); } if (platform=="pix" || platform=="fwsm") { string vers = "version_" + version; if (Resources::platform_res[platform.toAscii().constData()]->getResourceBool( "/FWBuilderResources/Target/options/" + vers + "/pix_rule_syslog_settings")) { m_dialog->pix_disable_rule_log->setEnabled(true); m_dialog->pix_logLevel->setEnabled(true); m_dialog->pix_log_interval->setEnabled(true); data.registerOption(m_dialog->pix_disable_rule_log, ropt, "disable_logging_for_this_rule"); data.registerOption(m_dialog->pix_logLevel, ropt, "log_level",logLevels); data.registerOption(m_dialog->pix_log_interval, ropt, "log_interval"); } else { m_dialog->pix_disable_rule_log->setEnabled(false); m_dialog->pix_logLevel->setEnabled(false); m_dialog->pix_log_interval->setEnabled(false); } } init = true; data.loadAll(); m_dialog->pf_max_src_nodes->setEnabled( m_dialog->pf_source_tracking->isChecked()); m_dialog->pf_max_src_states->setEnabled( m_dialog->pf_source_tracking->isChecked()); connlimitAboveLabelChange(); limitLabelChange(); //apply->setEnabled(false); init=false; } void RuleOptionsDialog::changed() { //apply->setEnabled(true); m_dialog->pf_max_src_nodes->setEnabled( m_dialog->pf_source_tracking->isChecked()); m_dialog->pf_max_src_states->setEnabled( m_dialog->pf_source_tracking->isChecked()); bool enable_overload_options = ( m_dialog->pf_max_src_conn->value()>0 || ( m_dialog->pf_max_src_conn_rate_num->value()>0 && m_dialog->pf_max_src_conn_rate_seconds->value()>0) ); m_dialog->pf_overload_table->setEnabled(enable_overload_options); m_dialog->pf_flush->setEnabled(enable_overload_options); m_dialog->pf_global->setEnabled(enable_overload_options); iptRouteContinueToggled(); // #2367 BaseObjectDialog::changed(); } void RuleOptionsDialog::validate(bool *res) { *res=true; } void RuleOptionsDialog::applyChanges() { std::auto_ptr cmd( new FWCmdRuleChangeOptions(m_project, obj)); // new_state is a copy of the rule object FWObject* new_state = cmd->getNewState(); FWOptions* new_rule_options = Rule::cast(new_state)->getOptionsObject(); init = true; data.saveAll(new_rule_options); init = false; /* #2367 */ PolicyRule *policy_rule = PolicyRule::cast(new_state); if (policy_rule) { FWOptions *ropt = policy_rule->getOptionsObject(); if (platform=="iptables") { FWObject *tag_object = m_dialog->iptTagDropArea->getObject(); // if tag_object==NULL, setTagObject clears setting in the rule policy_rule->setTagging(tag_object != NULL); policy_rule->setTagObject(tag_object); policy_rule->setClassification( ! ropt->getStr("classify_str").empty()); policy_rule->setRouting( ! ropt->getStr("ipt_iif").empty() || ! ropt->getStr("ipt_oif").empty() || ! ropt->getStr("ipt_gw").empty()); } if (platform=="pf") { FWObject *tag_object = m_dialog->pfTagDropArea->getObject(); // if tag_object==NULL, setTagObject clears setting in the rule policy_rule->setTagging(tag_object != NULL); policy_rule->setTagObject(tag_object); policy_rule->setClassification( ! new_rule_options->getStr("pf_classify_str").empty()); policy_rule->setRouting( ! new_rule_options->getStr("pf_route_option").empty() && new_rule_options->getStr("pf_route_option") != "none"); } if (platform=="ipf") { policy_rule->setRouting( ! new_rule_options->getStr("ipf_route_option").empty() && new_rule_options->getStr("ipf_route_option") != "none"); } if (platform=="ipfw") { policy_rule->setClassification( new_rule_options->getInt("ipfw_classify_method") > -1); } } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void RuleOptionsDialog::cancelChanges() { //apply->setEnabled(false); close(); } void RuleOptionsDialog::connlimitAboveLabelChange() { if (m_dialog->ipt_connlimit_above_not->isChecked()) m_dialog->ipt_connlimit_above_label->setText( "Match if the number of existing connections is below this " "(translates into option ! --connlimit-above)"); else m_dialog->ipt_connlimit_above_label->setText( "Match if the number of existing connections is above this " "(translates into option --connlimit-above)"); changed(); } void RuleOptionsDialog::limitLabelChange() { if (m_dialog->ipt_limit_not->isChecked()) m_dialog->ipt_limit_label->setText( "Maximum average matching rate (negated) " "(translates into option ! --limit rate)"); else m_dialog->ipt_limit_label->setText( "Maximum average matching rate " "(translates into option --limit rate)"); changed(); } void RuleOptionsDialog::iptRouteContinueToggled() { if (m_dialog->ipt_continue->isChecked()) { m_dialog->ipt_iif->setCurrentIndex(0); m_dialog->ipt_tee->setChecked(false); } m_dialog->ipt_iif->setEnabled( ! m_dialog->ipt_continue->isChecked() ); m_dialog->ipt_tee->setEnabled( ! m_dialog->ipt_continue->isChecked() ); } void RuleOptionsDialog::fillInterfaces(QComboBox* cb) { QSet deduplicated_interface_names; list interfaces = firewall->getByTypeDeep(Interface::TYPENAME); for (list::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->isLoopback()) continue; deduplicated_interface_names.insert(iface->getName().c_str()); if (Cluster::isA(firewall)) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( iface->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { for (FWObject::iterator it=failover_group->begin(); it!=failover_group->end(); ++it) { FWObject *mi = FWReference::getObject(*it); if (Interface::isA(mi) && ! iface->isLoopback()) { deduplicated_interface_names.insert(mi->getName().c_str()); } } } } } QStringList sorted_interfaces; QSetIterator it(deduplicated_interface_names); while (it.hasNext()) { sorted_interfaces << it.next(); } sorted_interfaces.sort(); cb->clear(); cb->addItem(""); cb->addItems(sorted_interfaces); } fwbuilder-5.1.0.3599/src/libgui/libgui.pro0000644000175000017500000004212111733011756021035 0ustar sylvestresylvestre# -*- mode: makefile; tab-width: 4; -*- QT += network include(../../qmake.inc) exists(qmake.inc):include( qmake.inc) TEMPLATE = lib CONFIG += staticlib TARGET = gui INSTALLS -= target # This makes gcc compile this header file and store result in # .obj/fwbuilder.gch/c++. Generated Makefile will also add # "-include .obj/fwbuilder " to the command line for the compiler # for every module. There is no need to #include file fwbuilder_ph.h # in each module since it will be included by means of -include option. # PRECOMPILED_HEADER = fwbuilder_ph.h # control whether we build debug or release in ../../qmake.inc # CONFIG += precompile_header HEADERS += ../../config.h \ events.h \ FWWindow.h \ ProjectPanel.h \ BaseObjectDialog.h \ TextEditWidget.h \ utils.h \ utils_no_qt.h \ SSHSession.h \ SSHUnx.h \ SSHCisco.h \ SSHPIX.h \ SSHIOS.h \ SSHProcurve.h \ debugDialog.h \ findDialog.h \ listOfLibrariesModel.h \ longTextDialog.h \ newGroupDialog.h \ filePropDialog.h \ DialogData.h \ SimpleTextEditor.h \ SimpleIntEditor.h \ TextFileEditor.h \ FWBSettings.h \ FWBTree.h \ RCS.h \ RCSFilePreview.h \ FWObjectClipboard.h \ platforms.h \ global.h \ printerStream.h \ PrintingProgressDialog.h \ PrintingController.h \ FWObjectPropertiesFactory.h \ ObjectManipulator.h \ ObjectEditor.h \ ObjectEditorDockWidget.h \ FWObjectDrag.h \ ObjectTreeView.h \ ObjectListView.h \ ObjectIconView.h \ ObjectTreeViewItem.h \ ObjectSelectorWidget.h \ InstallFirewallViewItem.h \ DialogFactory.h \ HostDialog.h \ FirewallDialog.h \ ClusterDialog.h \ ClusterGroupDialog.h \ InterfaceDialog.h \ AddressRangeDialog.h \ AddressTableDialog.h \ IPv4Dialog.h \ IPv6Dialog.h \ PhysicalAddressDialog.h \ AttachedNetworksDialog.h \ NetworkDialog.h \ NetworkDialogIPv6.h \ UserDialog.h \ RuleSetDialog.h \ LibraryDialog.h \ CustomServiceDialog.h \ IPServiceDialog.h \ ICMPServiceDialog.h \ TCPServiceDialog.h \ UDPServiceDialog.h \ GroupObjectDialog.h \ ObjectIconViewItem.h \ TimeDialog.h \ ColDesc.h \ FWObjectSelectionModel.h \ RuleNode.h \ RuleSetModel.h \ RuleSetView.h \ RuleSetViewDelegate.h \ iptAdvancedDialog.h \ ipcopAdvancedDialog.h \ ipfAdvancedDialog.h \ ipfwAdvancedDialog.h \ pfAdvancedDialog.h \ pixAdvancedDialog.h \ pixosAdvancedDialog.h \ iosaclAdvancedDialog.h \ iosAdvancedDialog.h \ ipcoposAdvancedDialog.h \ linux24AdvancedDialog.h \ linksysAdvancedDialog.h \ freebsdAdvancedDialog.h \ openbsdAdvancedDialog.h \ procurveaclAdvancedDialog.h \ solarisAdvancedDialog.h \ macosxAdvancedDialog.h \ secuwallAdvancedDialog.h \ secuwallosAdvancedDialog.h \ secuwallIfaceOptsDialog.h \ vlanOnlyIfaceOptsDialog.h \ linux24IfaceOptsDialog.h \ pixosIfaceOptsDialog.h \ bsdIfaceOptsDialog.h \ clusterMembersDialog.h \ CompilerOutputPanel.h \ CompilerDriverFactory.h \ RuleOptionsDialog.h \ RoutingRuleOptionsDialog.h \ NATRuleOptionsDialog.h \ LibExportDialog.h \ PrefsDialog.h \ instConf.h \ instDialog.h \ FirewallInstaller.h \ FirewallInstallerCisco.h \ FirewallInstallerProcurve.h \ FirewallInstallerUnx.h \ newFirewallDialog.h \ newClusterDialog.h \ newHostDialog.h \ ObjConflictResolutionDialog.h \ ColorLabelMenuItem.h \ TagServiceDialog.h \ ActionsDialog.h \ SimpleTextView.h \ BlankDialog.h \ DNSNameDialog.h \ instOptionsDialog.h \ instBatchOptionsDialog.h \ FilterDialog.h \ FindObjectWidget.h \ FWObjectDropArea.h \ CommentEditorPanel.h \ MetricEditorPanel.h \ FindWhereUsedWidget.h \ ConfirmDeleteObjectDialog.h \ FakeWizard.h \ AskLibForCopyDialog.h \ FWBAboutDialog.h \ Help.h \ HttpGet.h \ StartTipDialog.h \ vrrpOptionsDialog.h \ carpOptionsDialog.h \ pixFailoverOptionsDialog.h \ conntrackOptionsDialog.h \ heartbeatOptionsDialog.h \ openaisOptionsDialog.h \ pfsyncOptionsDialog.h \ check_update_url.h \ startup_tip_url.h \ InterfaceEditorWidget.h \ FWCmdBasic.h \ FWCmdChange.h \ FWCmdAddObject.h \ FWCmdDeleteObject.h \ FWCmdMoveObject.h \ InterfacesTabWidget.h \ FirewallSelectorWidget.h \ ClusterInterfacesSelectorWidget.h \ ClusterInterfaceWidget.h \ FWCmdRule.h \ UsageResolver.h \ IconSetter.h \ TutorialDialog.h \ MDIEventFilter.h \ FWBApplication.h \ WorkflowIcons.h \ FirewallCodeViewer.h \ networkZoneManager.h \ KeywordsDialog.h \ CommentKeywords.h \ DynamicGroupDialog.h \ FilterLineEdit.h \ \ ObjectDescriptor.h \ QThreadLogger.h \ \ importAddressListWizard/ChooseObjectsPage.h \ importAddressListWizard/CreateObjectsPage.h \ importAddressListWizard/FileNamePage.h \ importAddressListWizard/SelectLibraryPage.h \ importAddressListWizard/ImportAddressListWizard.h \ importAddressListWizard/HostsFile.h \ \ snmpNetworkDiscoveryWizard/ND_ChooseNetworksPage.h \ snmpNetworkDiscoveryWizard/ND_ChooseObjectsPage.h \ snmpNetworkDiscoveryWizard/ND_ChooseObjectTypePage.h \ snmpNetworkDiscoveryWizard/ND_CreateObjectsPage.h \ snmpNetworkDiscoveryWizard/ND_DiscoveryParametersPage.h \ snmpNetworkDiscoveryWizard/ND_ProgressPage.h \ snmpNetworkDiscoveryWizard/ND_SelectLibraryPage.h \ snmpNetworkDiscoveryWizard/ND_SetupPage.h \ snmpNetworkDiscoveryWizard/ND_SNMPParametersPage.h \ snmpNetworkDiscoveryWizard/SNMPNetworkDiscoveryWizard.h \ snmpNetworkDiscoveryWizard/SNMPCrawlerThread.h \ \ importFirewallConfigurationWizard/IC_FileNamePage.h \ importFirewallConfigurationWizard/IC_FirewallNamePage.h \ importFirewallConfigurationWizard/IC_PlatformWarningPage.h \ importFirewallConfigurationWizard/IC_ProgressPage.h \ importFirewallConfigurationWizard/IC_NetworkZonesPage.h \ importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.h \ importFirewallConfigurationWizard/ImporterThread.h \ SOURCES += ProjectPanel.cpp \ ProjectPanel_events.cpp \ ProjectPanel_file_ops.cpp \ ProjectPanel_state_ops.cpp \ BaseObjectDialog.cpp \ FWWindow.cpp \ FWWindow_editor.cpp \ FWWindow_single_rule_compile.cpp \ FWWindow_wrappers.cpp \ FWWindowPrint.cpp \ TextEditWidget.cpp \ ObjectEditorDockWidget.cpp \ ssh_wrappers.cpp \ utils.cpp \ utils_no_qt.cpp \ SSHSession.cpp \ SSHUnx.cpp \ SSHCisco.cpp \ SSHPIX.cpp \ SSHIOS.cpp \ SSHProcurve.cpp \ debugDialog.cpp \ findDialog.cpp \ listOfLibrariesModel.cpp \ longTextDialog.cpp \ newGroupDialog.cpp \ filePropDialog.cpp \ DialogData.cpp \ SimpleTextEditor.cpp \ SimpleIntEditor.cpp \ TextFileEditor.cpp \ FWBSettings.cpp \ FWBTree.cpp \ RCS.cpp \ RCSFilePreview.cpp \ FWObjectClipboard.cpp \ platforms.cpp \ printerStream.cpp \ PrintingProgressDialog.cpp \ PrintingController.cpp \ FWObjectPropertiesFactory.cpp \ ObjectManipulator.cpp \ ObjectManipulator_ops.cpp \ ObjectManipulator_tree_ops.cpp \ ObjectManipulator_create_new.cpp \ ObjectManipulator_slots.cpp \ ObjectManipulator_new_object_checks.cpp \ ObjectEditor.cpp \ FWObjectDrag.cpp \ ObjectTreeView.cpp \ ObjectListView.cpp \ ObjectIconView.cpp \ ObjectSelectorWidget.cpp \ DialogFactory.cpp \ HostDialog.cpp \ FirewallDialog.cpp \ ClusterDialog.cpp \ ClusterGroupDialog.cpp \ InterfaceDialog.cpp \ AddressRangeDialog.cpp \ AddressTableDialog.cpp \ IPv4Dialog.cpp \ IPv6Dialog.cpp \ PhysicalAddressDialog.cpp \ AttachedNetworksDialog.cpp \ NetworkDialog.cpp \ NetworkDialogIPv6.cpp \ UserDialog.cpp \ LibraryDialog.cpp \ CustomServiceDialog.cpp \ IPServiceDialog.cpp \ ICMPServiceDialog.cpp \ TCPServiceDialog.cpp \ UDPServiceDialog.cpp \ GroupObjectDialog.cpp \ TimeDialog.cpp \ RuleSetDialog.cpp \ FWObjectSelectionModel.cpp \ ColDesc.cpp \ RuleNode.cpp \ RuleSetModel.cpp \ RuleSetView.cpp \ RuleSetViewDelegate.cpp \ iptAdvancedDialog.cpp \ ipcopAdvancedDialog.cpp \ ipfAdvancedDialog.cpp \ ipfwAdvancedDialog.cpp \ pfAdvancedDialog.cpp \ pixAdvancedDialog.cpp \ pixosAdvancedDialog.cpp \ iosaclAdvancedDialog.cpp \ iosAdvancedDialog.cpp \ ipcoposAdvancedDialog.cpp \ linux24AdvancedDialog.cpp \ linksysAdvancedDialog.cpp \ freebsdAdvancedDialog.cpp \ openbsdAdvancedDialog.cpp \ procurveaclAdvancedDialog.cpp \ solarisAdvancedDialog.cpp \ macosxAdvancedDialog.cpp \ secuwallAdvancedDialog.cpp \ secuwallosAdvancedDialog.cpp \ secuwallIfaceOptsDialog.cpp \ vlanOnlyIfaceOptsDialog.cpp \ linux24IfaceOptsDialog.cpp \ pixosIfaceOptsDialog.cpp \ bsdIfaceOptsDialog.cpp \ clusterMembersDialog.cpp \ CompilerOutputPanel.cpp \ CompilerDriverFactory.cpp \ RuleOptionsDialog.cpp \ RoutingRuleOptionsDialog.cpp \ NATRuleOptionsDialog.cpp \ LibExportDialog.cpp \ PrefsDialog.cpp \ instConf.cpp \ instDialog.cpp \ instDialog_ui_ops.cpp \ instDialog_compile.cpp \ instDialog_installer.cpp \ FirewallInstaller.cpp \ FirewallInstallerCisco.cpp \ FirewallInstallerProcurve.cpp \ FirewallInstallerUnx.cpp \ newFirewallDialog.cpp \ newFirewallDialog_from_template.cpp \ newClusterDialog.cpp \ newClusterDialog_create.cpp \ newHostDialog.cpp \ ObjConflictResolutionDialog.cpp \ ColorLabelMenuItem.cpp \ TagServiceDialog.cpp \ ActionsDialog.cpp \ SimpleTextView.cpp \ BlankDialog.cpp \ DNSNameDialog.cpp \ ObjectTreeViewItem.cpp \ InstallFirewallViewItem.cpp \ instOptionsDialog.cpp \ instBatchOptionsDialog.cpp \ FilterDialog.cpp \ FindObjectWidget.cpp \ FWObjectDropArea.cpp \ CommentEditorPanel.cpp \ MetricEditorPanel.cpp \ FindWhereUsedWidget.cpp \ ConfirmDeleteObjectDialog.cpp \ FakeWizard.cpp \ AskLibForCopyDialog.cpp \ ObjectListViewItem.cpp \ Help.cpp \ HttpGet.cpp \ StartTipDialog.cpp \ FWBAboutDialog.cpp \ vrrpOptionsDialog.cpp \ carpOptionsDialog.cpp \ pixFailoverOptionsDialog.cpp \ conntrackOptionsDialog.cpp \ pfsyncOptionsDialog.cpp \ heartbeatOptionsDialog.cpp \ openaisOptionsDialog.cpp \ InterfaceEditorWidget.cpp \ FWCmdBasic.cpp \ FWCmdChange.cpp \ FWCmdAddObject.cpp \ FWCmdDeleteObject.cpp \ FWCmdMoveObject.cpp \ InterfacesTabWidget.cpp \ FirewallSelectorWidget.cpp \ ClusterInterfacesSelectorWidget.cpp \ ClusterInterfaceWidget.cpp \ FWCmdRule.cpp \ IconSetter.cpp \ UsageResolver.cpp \ TutorialDialog.cpp \ MDIEventFilter.cpp \ FWBApplication.cpp \ WorkflowIcons.cpp \ FirewallCodeViewer.cpp \ networkZoneManager.cpp \ KeywordsDialog.cpp \ CommentKeywords.cpp \ DynamicGroupDialog.cpp \ FilterLineEdit.cpp \ \ ObjectDescriptor.cpp \ QThreadLogger.cpp \ \ importAddressListWizard/ChooseObjectsPage.cpp \ importAddressListWizard/CreateObjectsPage.cpp \ importAddressListWizard/FileNamePage.cpp \ importAddressListWizard/SelectLibraryPage.cpp \ importAddressListWizard/ImportAddressListWizard.cpp \ importAddressListWizard/HostsFile.cpp \ \ snmpNetworkDiscoveryWizard/ND_ChooseNetworksPage.cpp \ snmpNetworkDiscoveryWizard/ND_ChooseObjectsPage.cpp \ snmpNetworkDiscoveryWizard/ND_ChooseObjectTypePage.cpp \ snmpNetworkDiscoveryWizard/ND_CreateObjectsPage.cpp \ snmpNetworkDiscoveryWizard/ND_DiscoveryParametersPage.cpp \ snmpNetworkDiscoveryWizard/ND_ProgressPage.cpp \ snmpNetworkDiscoveryWizard/ND_SelectLibraryPage.cpp \ snmpNetworkDiscoveryWizard/ND_SetupPage.cpp \ snmpNetworkDiscoveryWizard/ND_SNMPParametersPage.cpp \ snmpNetworkDiscoveryWizard/SNMPNetworkDiscoveryWizard.cpp \ snmpNetworkDiscoveryWizard/SNMPCrawlerThread.cpp \ \ importFirewallConfigurationWizard/IC_FileNamePage.cpp \ importFirewallConfigurationWizard/IC_FirewallNamePage.cpp \ importFirewallConfigurationWizard/IC_PlatformWarningPage.cpp \ importFirewallConfigurationWizard/IC_ProgressPage.cpp \ importFirewallConfigurationWizard/IC_NetworkZonesPage.cpp \ importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.cpp \ importFirewallConfigurationWizard/ImporterThread.cpp FORMS = FWBMainWindow_q.ui \ compileroutputpanel_q.ui \ customservicedialog_q.ui \ ipservicedialog_q.ui \ icmpservicedialog_q.ui \ tcpservicedialog_q.ui \ udpservicedialog_q.ui \ groupobjectdialog_q.ui \ librarydialog_q.ui \ ipv4dialog_q.ui \ ipv6dialog_q.ui \ rulesetdialog_q.ui \ addressrangedialog_q.ui \ addresstabledialog_q.ui \ attachednetworksdialog_q.ui \ networkdialog_q.ui \ networkdialogipv6_q.ui \ userdialog_q.ui \ hostdialog_q.ui \ firewalldialog_q.ui \ clusterdialog_q.ui \ clustergroupdialog_q.ui \ interfacedialog_q.ui \ physaddressdialog_q.ui \ timedialog_q.ui \ rcsfilepreview_q.ui \ rcsfilesavedialog_q.ui \ iptadvanceddialog_q.ui \ ipcopadvanceddialog_q.ui \ ipcoposadvanceddialog_q.ui \ objectmanipulator_q.ui \ prefsdialog_q.ui \ pixadvanceddialog_q.ui \ pixosadvanceddialog_q.ui \ iosacladvanceddialog_q.ui \ iosadvanceddialog_q.ui \ procurveacladvanceddialog_q.ui \ simpletexteditor_q.ui \ simpleinteditor_q.ui \ textfileeditor_q.ui \ aboutdialog_q.ui \ libexport_q.ui \ ruleoptionsdialog_q.ui \ routingruleoptionsdialog_q.ui \ instdialog_q.ui \ objconflictresolutiondialog_q.ui \ newfirewalldialog_q.ui \ newclusterdialog_q.ui \ finddialog_q.ui \ ipfadvanceddialog_q.ui \ ipfwadvanceddialog_q.ui \ pfadvanceddialog_q.ui \ linux24advanceddialog_q.ui \ solarisadvanceddialog_q.ui \ freebsdadvanceddialog_q.ui \ openbsdadvanceddialog_q.ui \ macosxadvanceddialog_q.ui \ secuwalladvanceddialog_q.ui \ secuwallosadvanceddialog_q.ui \ secuwallifaceoptsdialog_q.ui \ clustermembersdialog_q.ui \ bsdifaceoptsdialog_q.ui \ colorlabelmenuitem_q.ui \ debugdialog_q.ui \ filepropdialog_q.ui \ askrulenumberdialog_q.ui \ newgroupdialog_q.ui \ newhostdialog_q.ui \ longtextdialog_q.ui \ linksysadvanceddialog_q.ui \ printingprogressdialog_q.ui \ pagesetupdialog_q.ui \ blankdialog_q.ui \ dnsnamedialog_q.ui \ tagservicedialog_q.ui \ actionsdialog_q.ui \ simpletextview_q.ui \ helpview_q.ui \ filterdialog_q.ui \ natruleoptionsdialog_q.ui \ instoptionsdialog_q.ui \ findobjectwidget_q.ui \ fwobjectdroparea_q.ui \ commenteditorpanel_q.ui \ metriceditorpanel_q.ui \ findwhereusedwidget_q.ui \ confirmdeleteobjectdialog_q.ui \ projectpanel_q.ui \ asklibforcopydialog_q.ui \ starttipdialog_q.ui \ vrrpoptionsdialog_q.ui \ carpoptionsdialog_q.ui \ pixfailoveroptionsdialog_q.ui \ conntrackoptionsdialog_q.ui \ heartbeatoptionsdialog_q.ui \ openaisoptionsdialog_q.ui \ pfsyncoptionsdialog_q.ui \ vlanonlyifaceoptsdialog_q.ui \ linux24ifaceoptsdialog_q.ui \ pixosifaceoptsdialog_q.ui \ InterfaceEditorWidget.ui \ InterfacesTabWidget.ui \ ClusterInterfaceWidget.ui \ TutorialDialog.ui \ WorkflowIcons.ui \ FirewallCodeViewer.ui \ objectselectorwidget_q.ui \ keywordsdialog_q.ui \ commentkeywords_q.ui \ dynamicgroupdialog_q.ui \ \ importAddressListWizard/chooseobjectspage_q.ui \ importAddressListWizard/createobjectspage_q.ui \ importAddressListWizard/filenamepage_q.ui \ importAddressListWizard/selectlibrarypage_q.ui \ \ snmpNetworkDiscoveryWizard/nd_choosenetworkspage_q.ui \ snmpNetworkDiscoveryWizard/nd_chooseobjectspage_q.ui \ snmpNetworkDiscoveryWizard/nd_chooseobjecttypepage_q.ui \ snmpNetworkDiscoveryWizard/nd_createobjectspage_q.ui \ snmpNetworkDiscoveryWizard/nd_discoveryparameterspage_q.ui \ snmpNetworkDiscoveryWizard/nd_progresspage_q.ui \ snmpNetworkDiscoveryWizard/nd_selectlibrarypage_q.ui \ snmpNetworkDiscoveryWizard/nd_setuppage_q.ui \ snmpNetworkDiscoveryWizard/nd_snmpparameterspage_q.ui \ \ importFirewallConfigurationWizard/ic_filenamepage_q.ui \ importFirewallConfigurationWizard/ic_firewallnamepage_q.ui \ importFirewallConfigurationWizard/ic_platformwarningpage_q.ui \ importFirewallConfigurationWizard/ic_progresspage_q.ui \ importFirewallConfigurationWizard/ic_networkzonespage_q.ui \ # fwtransfer stuff. # HEADERS += transferDialog.h # SOURCES += transferDialog.cpp # FORMS += transferdialog_q.ui # !macx:LIBS += -lQtDBus # workaround for QT += dbus not working with Qt < 4.4.0 INCLUDEPATH += \ ../.. \ ../import \ ../iptlib \ ../pflib \ ../cisco_lib \ ../compiler_lib \ ../libfwbuilder/src DEPENDPATH += \ ../import \ ../iptlib \ ../pflib \ ../cisco_lib/ \ ../compiler_lib \ ../libfwbuilder/src RESOURCES += MainRes.qrc win32 { # add "." to include path to make sure #include works when we # compile modules in subdirectories, such as # importAddressListWizard and other wizards. This seems to only be # necessary on Windows INCLUDEPATH += . } fwbuilder-5.1.0.3599/src/libgui/commentkeywords_q.ui0000644000175000017500000000427711733011756023163 0ustar sylvestresylvestre CommentKeywords_q 0 0 400 300 CommentKeywords 0 100 200 0 16777215 16777215 true 0 0 Keywords... true TextEditWidget QTextEdit
TextEditWidget.h
keywordsButton clicked() CommentKeywords_q keywordsClicked() 55 277 199 149
fwbuilder-5.1.0.3599/src/libgui/filePropDialog.cpp0000644000175000017500000001115211733011756022444 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "fwbuilder/FWObjectDatabase.h" #include "filePropDialog.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "PrintingProgressDialog.h" #include "printerStream.h" #include "RCS.h" #include #include #include #include #ifndef _WIN32 # include // for access(2) #endif #include using namespace std; filePropDialog::~filePropDialog() { delete m_dialog; } filePropDialog::filePropDialog(QWidget *parent, RCS *rcs) : QDialog(parent) { m_dialog = new Ui::filePropDialog_q; m_dialog->setupUi(this); // we have to get a reference to the printer // or we can create a new one ... m_dialog->fileLocation->setText( rcs->getFileName() ); if (rcs->isRO()) m_dialog->fileRO->setText( tr("Opened read-only") ); else m_dialog->fileRO->setText(""); time_t lm = mw->activeProject()->db()->getTimeLastModified(); QString s = ctime( &lm ); s.truncate( s.length()-1 ); // chop newline m_dialog->lastModified->setText( QString("%1 (%2)").arg(s).arg(lm) ); if (rcs->isInRCS()) { m_dialog->fileRev->setText( rcs->getSelectedRev() ); m_dialog->fileLockedBy->setText( rcs->getLockedBy() ); QList::iterator i; for (i=rcs->begin(); i!=rcs->end(); ++i) { Revision r= *i; m_dialog->fileRevHistory->append( tr("Revision %1").arg(r.rev) ); m_dialog->fileRevHistory->append( r.log ); m_dialog->fileRevHistory->append("\n"); m_dialog->fileRevHistory->moveCursor(QTextCursor::Start); } } else { m_dialog->fileRev->setText(""); m_dialog->fileLockedBy->setText(""); m_dialog->fileRevHistory->setText(""); } } void filePropDialog::setPrinter(QPrinter *p) { printer=p; } void filePropDialog::printRevHistory() { // Revision history printing: // // 1. setup printer properties // 2. create a stream // 3. split text from the QTextBrowser (fileRevHistory) into the lines // 4. send lines to the stream // //int pageWidth = 0; //int pageHeight = 0; bool fullPage = false; float margin; #if defined(Q_OS_MACX) || defined(Q_OS_WIN32) margin=1.5; #else margin=0; #endif int resolution = 150; bool printHeader = true; //bool printLegend = true; //bool printObjects = true; //bool newPageForSection = false; //int tableResolution = 2; // 50%, 75%, 100%, 150%, 200%, default 100% QPrintDialog printDialog(printer, this); #if (QT_VERSION > 0x030200) printDialog.addEnabledOption(QAbstractPrintDialog::PrintPageRange); printDialog.setPrintRange(QAbstractPrintDialog::AllPages); printDialog.setMinMax(1,9999); #endif printer->setResolution(resolution); printer->setFullPage(fullPage); if (printDialog.exec() == QDialog::Accepted) { int fromPage = printer->fromPage(); int toPage = printer->toPage(); if (fromPage==0) fromPage=1; if (toPage==0) toPage=9999; PrintingProgressDialog *ppd = new PrintingProgressDialog(this,printer,0,false); QString headerText = "Revision History:"; #if defined(Q_OS_MACX) printerStream pr(printer,1.0,margin,printHeader,headerText,NULL); #else printerStream pr(printer,1.0,margin,printHeader,headerText,ppd); ppd->show(); #endif pr.setFromTo(fromPage,toPage); if ( !pr.begin()) { ppd->hide(); delete ppd; return; } //QSize margins = printer->margins(); pr.beginPage(); // resets yPos QStringList sl; sl=m_dialog->fileRevHistory->toPlainText().split('\n'); for ( QStringList::Iterator it = sl.begin(); it != sl.end(); ++it ) { pr.printText(*it); } ppd->hide(); delete ppd; pr.end(); } } fwbuilder-5.1.0.3599/src/libgui/MetricEditorPanel.h0000644000175000017500000000363211733011756022567 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __METRICEDITORPANEL_H__ #define __METRICEDITORPANEL_H__ #include "config.h" #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" class MetricEditorPanel : public BaseObjectDialog { Q_OBJECT; libfwbuilder::RoutingRule *rule; Ui::MetricEditorPanel_q *m_widget; public: MetricEditorPanel(QWidget* p); ~MetricEditorPanel(); int value(); public slots: virtual void changed(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void closeEvent(QCloseEvent *e); }; #endif fwbuilder-5.1.0.3599/src/libgui/ObjectEditor.h0000644000175000017500000000645711733011756021602 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTEDITOR_H_ #define __OBJECTEDITOR_H_ #include "config.h" #include "global.h" #include "qdialog.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include #include class ObjectTreeViewItem; class QComboBox; class QMenu; class QStackedWidget; class ProjectPanel; class BaseObjectDialog; class ObjectEditor : public QObject { Q_OBJECT; QMap stackIds; QMap dialogs; libfwbuilder::FWObject *opened; int current_dialog_idx; QString current_dialog_name; QStackedWidget *editorStack; ProjectPanel *m_project; void disconnectSignals(); public: enum OptType{optAction, optComment, optMetric, optNone}; private: OptType openedOpt; void registerObjectDialog(QStackedWidget *stack, const QString &obj_type, const QString &dialog_name); void registerOptDialog(QStackedWidget *stack, ObjectEditor::OptType opt_type, const QString &dialog_name); void activateDialog(const QString &dialog_name, libfwbuilder::FWObject *obj, enum OptType opt); public: ObjectEditor(QWidget *parent); virtual ~ObjectEditor() {} void attachToProjectWindow(ProjectPanel *pp); QString getOptDialogName(OptType t); void open(libfwbuilder::FWObject *o); void openOpt(libfwbuilder::FWObject *, OptType t); libfwbuilder::FWObject* getOpened() { return opened; }; OptType getOpenedOpt() {return openedOpt;}; void load(); void purge(); bool validate(); int getCurrentDialogIndex() { return current_dialog_idx; }; QWidget* getCurrentObjectDialog(); public slots: void changed(); void blank(); signals: /** * the dialog class should have a slot that can load object's data * into dialog elements when ObjectEditor emits this signal */ void loadObject_sign(libfwbuilder::FWObject *); /** * the dialog class should have a slot that can verify data entered by * user in the dialog elements when ObjectEditor emits this * signal. The validation result is returned in variable "bool *res" */ void validate_sign(bool *res); /** * the dialog class should have a slot that applies changes made by * the user and saves data in the object. */ void applyChanges_sign(); }; #endif fwbuilder-5.1.0.3599/src/libgui/FWCmdAddObject.h0000644000175000017500000000501411733011756021711 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWCMDADDOBJECT_H #define FWCMDADDOBJECT_H #include "FWCmdChange.h" /******************************************************** * FWCmdAddObject ********************************************************/ class FWCmdAddObject : public FWCmdChange { protected: libfwbuilder::FWObject *member; bool require_complete_tree_reload; virtual void notify(); void prepareStatesForRedo(); public: FWCmdAddObject(ProjectPanel *project, libfwbuilder::FWObject *grp, libfwbuilder::FWObject *member, QString text=QString(), QUndoCommand* macro=0); ~FWCmdAddObject(); void setNeedTreeReload(bool f) { require_complete_tree_reload = f; } virtual void redo(); virtual void undo(); }; class FWCmdAddUserFolder : public FWCmdChange { QString m_userFolder; public: FWCmdAddUserFolder(ProjectPanel *project, libfwbuilder::FWObject *parentFolder, const QString &userFolder, QString text = QString(), QUndoCommand *macro = 0); virtual void redo(); virtual void undo(); virtual void notify(); }; /******************************************************** * FWCmdAddLibrary ********************************************************/ class FWCmdAddLibrary : public FWCmdAddObject { public: FWCmdAddLibrary(ProjectPanel *project, libfwbuilder::FWObject *root, libfwbuilder::FWObject *lib, QString text=QString(), QUndoCommand* macro=0); ~FWCmdAddLibrary(); virtual void redo(); virtual void undo(); }; #endif fwbuilder-5.1.0.3599/src/libgui/carpOptionsDialog.cpp0000644000175000017500000000537611733011756023200 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "carpOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include #include #include using namespace std; using namespace libfwbuilder; carpOptionsDialog::carpOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::carpOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); data.registerOption(m_dialog->carp_password, gropt, "carp_password"); data.registerOption(m_dialog->carp_vhid, gropt, "carp_vhid"); data.registerOption(m_dialog->advbase, gropt, "carp_advbase"); data.registerOption(m_dialog->master_advskew, gropt, "carp_master_advskew"); data.registerOption(m_dialog->default_advskew, gropt, "carp_default_advskew"); data.loadAll(); } carpOptionsDialog::~carpOptionsDialog() { delete m_dialog; } /* * store all data in the object */ void carpOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void carpOptionsDialog::reject() { QDialog::reject(); } bool carpOptionsDialog::validate() { return true; } fwbuilder-5.1.0.3599/src/libgui/DialogFactory.h0000644000175000017500000000401511733011756021740 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _DIALOGFACTORY_HH_ #define _DIALOGFACTORY_HH_ #include "BaseObjectDialog.h" #include namespace libfwbuilder { class FWObject; class FWException; class Firewall; class Rule; }; class DialogFactory { public: static BaseObjectDialog *createDialog(QWidget *parent,const QString &objType); static QWidget *createFWDialog(QWidget *parent,libfwbuilder::FWObject *o) throw(libfwbuilder::FWException); static QWidget *createOSDialog(QWidget *parent,libfwbuilder::FWObject *o) throw(libfwbuilder::FWException); static QWidget *createIfaceDialog(QWidget *parent,libfwbuilder::FWObject *o) throw(libfwbuilder::FWException); static QWidget *createClusterConfDialog(QWidget *parent, libfwbuilder::FWObject *o) throw(libfwbuilder::FWException); static QString getClusterGroupOptionsDialogName(libfwbuilder::FWObject *o); static QWidget *createClusterGroupOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o) throw(libfwbuilder::FWException); static std::string getActionDialogPageName(libfwbuilder::Firewall *fw, libfwbuilder::Rule *rule); }; #endif fwbuilder-5.1.0.3599/src/libgui/RoutingRuleOptionsDialog.cpp0000644000175000017500000000656711733011756024535 0ustar sylvestresylvestre/* Copyright (C) 2005 Compal GmbH, Germany Author: Roman Hoog Antink Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "ProjectPanel.h" #include "RoutingRuleOptionsDialog.h" #include "RuleSetView.h" #include "FWWindow.h" #include "FWCmdRule.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; RoutingRuleOptionsDialog::~RoutingRuleOptionsDialog() { delete m_dialog; } RoutingRuleOptionsDialog::RoutingRuleOptionsDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::RoutingRuleOptionsDialog_q; m_dialog->setupUi(this); } void RoutingRuleOptionsDialog::loadFWObject(FWObject *o) { obj=o; FWObject *p = obj; while ( !Firewall::cast(p) ) p = p->getParent(); platform = p->getStr("platform").c_str(); Rule *rule = dynamic_cast(o); FWOptions *ropt = rule->getOptionsObject(); int wid = 0; if (platform=="iptables") wid = 0; else wid = 1; /* if (platform=="ipf") wid = 1; if (platform=="pf") wid = 2; if (platform=="ipfw") wid = 3; */ m_dialog->wStack->setCurrentIndex( wid ); m_dialog->wStack->widget(wid)->raise(); data.clear(); if (platform=="iptables") { data.registerOption(m_dialog->routing_non_critical_rule, ropt, "no_fail"); } init = true; data.loadAll(); init = false; } void RoutingRuleOptionsDialog::validate(bool *res) { *res=true; } void RoutingRuleOptionsDialog::applyChanges() { std::auto_ptr cmd( new FWCmdRuleChangeOptions(m_project, obj)); // new_state is a copy of the rule object FWObject* new_state = cmd->getNewState(); FWOptions* new_rule_options = Rule::cast(new_state)->getOptionsObject(); init=true; data.saveAll(new_rule_options); init=false; if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/TimeDialog.cpp0000644000175000017500000002146411733011756021571 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "TimeDialog.h" #include "ProjectPanel.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Interval.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "FWBSettings.h" using namespace libfwbuilder; using namespace std; TimeDialog::TimeDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::TimeDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } TimeDialog::~TimeDialog() { delete m_dialog; } void TimeDialog::loadFWObject(FWObject *o) { obj=o; Interval *s = dynamic_cast(obj); assert(s!=NULL); init = true; // See #893 No need to show object attributes if the object is "Any" if (obj->getId() == FWObjectDatabase::ANY_INTERVAL_ID) { m_dialog->object_attributes_1->hide(); m_dialog->object_attributes_2->hide(); m_dialog->commentKeywords->setReadOnlyComment( QObject::tr( "When used in the Time Interval field of a rule, " "the Any object will match any time of the day or day " "of the week. To update your rule to " "match only specific " "service, drag-and-drop an object from " "the Object tree into the field in the rule.")); } else { m_dialog->cbStart1_2->setCheckState(Qt::Unchecked); m_dialog->cbStart2_2->setCheckState(Qt::Unchecked); m_dialog->cbStart3_2->setCheckState(Qt::Unchecked); m_dialog->cbStart4_2->setCheckState(Qt::Unchecked); m_dialog->cbStart5_2->setCheckState(Qt::Unchecked); m_dialog->cbStart6_2->setCheckState(Qt::Unchecked); m_dialog->cbStart7_2->setCheckState(Qt::Unchecked); m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); int fromH = obj->getInt("from_hour"); int fromM = obj->getInt("from_minute"); if (fromH<0) fromH=0; if (fromM<0) fromM=0; m_dialog->startTime->setTime( QTime( fromH, fromM ) ); int y=obj->getInt("from_year"); int m=obj->getInt("from_month"); int d=obj->getInt("from_day"); bool using_start_date = (y>0 && m>0 && d>0); m_dialog->startDate->setDate( (using_start_date)?QDate( y, m, d ):QDate() ); m_dialog->useStartDate->setChecked(using_start_date); // from_weekday is -1 for "All days" // m_dialog->startDOW->setCurrentIndex( obj->getInt("from_weekday") + 1 ); QString sFromWeekday = s->getDaysOfWeek().c_str(); if (sFromWeekday=="-1") sFromWeekday="0,1,2,3,4,5,6"; // Sunday is cbStart7 if (sFromWeekday.contains('0')) m_dialog->cbStart7_2->setCheckState(Qt::Checked); if (sFromWeekday.contains('1')) m_dialog->cbStart1_2->setCheckState(Qt::Checked); if (sFromWeekday.contains('2')) m_dialog->cbStart2_2->setCheckState(Qt::Checked); if (sFromWeekday.contains('3')) m_dialog->cbStart3_2->setCheckState(Qt::Checked); if (sFromWeekday.contains('4')) m_dialog->cbStart4_2->setCheckState(Qt::Checked); if (sFromWeekday.contains('5')) m_dialog->cbStart5_2->setCheckState(Qt::Checked); if (sFromWeekday.contains('6')) m_dialog->cbStart6_2->setCheckState(Qt::Checked); int toH = obj->getInt("to_hour"); int toM = obj->getInt("to_minute"); if (toH<0) toH=0; if (toM<0) toM=0; m_dialog->endTime->setTime( QTime( toH, toM ) ); y=obj->getInt("to_year"); m=obj->getInt("to_month"); d=obj->getInt("to_day"); bool using_end_date = (y>0 && m>0 && d>0); m_dialog->endDate->setDate( (using_end_date)?QDate( y, m, d ):QDate() ); m_dialog->useEndDate->setChecked(using_end_date); m_dialog->object_attributes_1->show(); m_dialog->object_attributes_2->show(); setDisabledPalette(m_dialog->obj_name); //setDisabledPalette(m_dialog->comment); setDisabledPalette(m_dialog->startTime); setDisabledPalette(m_dialog->useStartDate); setDisabledPalette(m_dialog->startDate); //setDisabledPalette(startDOW); setDisabledPalette(m_dialog->endTime); setDisabledPalette(m_dialog->useEndDate); setDisabledPalette(m_dialog->endDate); //setDisabledPalette(endDOW); enableAllWidgets(); //apply->setEnabled( false ); } init = false; } void TimeDialog::enableAllWidgets() { m_dialog->obj_name->setEnabled(!obj->isReadOnly()); m_dialog->startTime->setEnabled(!obj->isReadOnly()); m_dialog->useStartDate->setEnabled(!obj->isReadOnly()); m_dialog->startDate->setEnabled(!obj->isReadOnly() && m_dialog->useStartDate->isChecked()); m_dialog->endTime->setEnabled(!obj->isReadOnly()); m_dialog->useEndDate->setEnabled(!obj->isReadOnly()); m_dialog->endDate->setEnabled(!obj->isReadOnly() && m_dialog->useEndDate->isChecked()); } void TimeDialog::useStartOrEndDate() { enableAllWidgets(); changed(); } void TimeDialog::validate(bool *res) { *res=true; } void TimeDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); Interval *interval = dynamic_cast(new_state); assert(interval!=NULL); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); if (m_dialog->useStartDate->isChecked()) { new_state->setInt( "from_day" , m_dialog->startDate->date().day() ); new_state->setInt( "from_month" , m_dialog->startDate->date().month() ); new_state->setInt( "from_year" , m_dialog->startDate->date().year() ); } else { new_state->setInt( "from_day" , -1 ); new_state->setInt( "from_month" , -1 ); new_state->setInt( "from_year" , -1 ); } new_state->setInt( "from_minute" , m_dialog->startTime->time().minute()); new_state->setInt( "from_hour" , m_dialog->startTime->time().hour() ); if (m_dialog->useEndDate->isChecked()) { new_state->setInt( "to_day" , m_dialog->endDate->date().day() ); new_state->setInt( "to_month" , m_dialog->endDate->date().month() ); new_state->setInt( "to_year" , m_dialog->endDate->date().year() ); } else { new_state->setInt( "to_day" , -1 ); new_state->setInt( "to_month" , -1 ); new_state->setInt( "to_year" , -1 ); } new_state->setInt( "to_minute" , m_dialog->endTime->time().minute() ); new_state->setInt( "to_hour" , m_dialog->endTime->time().hour() ); QStringList weekDays ; if (m_dialog->cbStart7_2->checkState ()==Qt::Checked) weekDays.append("0"); if (m_dialog->cbStart1_2->checkState ()==Qt::Checked) weekDays.append("1"); if (m_dialog->cbStart2_2->checkState ()==Qt::Checked) weekDays.append("2"); if (m_dialog->cbStart3_2->checkState ()==Qt::Checked) weekDays.append("3"); if (m_dialog->cbStart4_2->checkState ()==Qt::Checked) weekDays.append("4"); if (m_dialog->cbStart5_2->checkState ()==Qt::Checked) weekDays.append("5"); if (m_dialog->cbStart6_2->checkState ()==Qt::Checked) weekDays.append("6"); interval->setDaysOfWeek(weekDays.join(",").toAscii().data()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/InterfacesTabWidget.h0000644000175000017500000000550511733011756023074 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INTERFACESTABWIDGET_H #define INTERFACESTABWIDGET_H #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include #include #include #include "fwbuilder/Interface.h" #include "fwbuilder/InterfaceData.h" #include "fwbuilder/FWObjectDatabase.h" #include "InterfaceEditorWidget.h" #include "ClusterInterfaceWidget.h" namespace Ui { class InterfacesTabWidget; } struct AddressInfo; struct EditedInterfaceData { QString name; QString label; QString comment; QString mac; int type; // 0 - regular, 1 - dynamic, 2 - unnumbered QString protocol; QMultiMap addresses; }; class InterfacesTabWidget : public QTabWidget { Q_OBJECT; public: InterfacesTabWidget(QWidget *parent = 0); ~InterfacesTabWidget(); QMap getData(); QList getNewData(); QList getDeletedInterfaces(); bool isValid(); void setCornerWidgetsVisible(bool); void setClusterMode(bool); void setHostOS(const QString &s); protected: void changeEvent(QEvent *e); private: Ui::InterfacesTabWidget *m_ui; QToolButton newInterface; QToolButton delInterface; QWidget newInterfaceWidget; QHBoxLayout newInterfaceLayout; libfwbuilder::FWObject *currentTemplate; QList deleted; bool clusterMode; QString explanation; bool noTabs; QString host_OS; public slots: void addInterface(libfwbuilder::Interface*); void clear(); void addNewInterface(); void setTemplate(libfwbuilder::FWObject*); void closeTab(); void addInterfaceFromData(libfwbuilder::InterfaceData*); void addClusterInterface(ClusterInterfaceData); void setExplanation(const QString&); virtual void addTab(QWidget*, const QString&); }; #endif // INTERFACESTABWIDGET_H fwbuilder-5.1.0.3599/src/libgui/vrrpOptionsDialog.h0000644000175000017500000000263611733011756022705 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __VRRPOPTIONSDIALOG_H_ #define __VRRPOPTIONSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class vrrpOptionsDialog : public QDialog { Q_OBJECT public: vrrpOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~vrrpOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::vrrpOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __VRRPOPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/FWWindow.cpp0000644000175000017500000015346211733011756021263 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003, 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "check_update_url.h" #include "../../VERSION.h" #include "utils.h" #include "utils_no_qt.h" #include #include #include "FWBApplication.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjectTreeView.h" #include "ObjectManipulator.h" #include "FWObjectClipboard.h" #include "FWBTree.h" #include "FWBSettings.h" #include "FWObjectPropertiesFactory.h" #include "upgradePredicate.h" #include "ObjConflictResolutionDialog.h" #include "ObjectTreeViewItem.h" #include "RuleSetView.h" #include "ObjectEditor.h" #include "PrefsDialog.h" #include "LibExportDialog.h" #include "findDialog.h" #include "FindObjectWidget.h" #include "FindWhereUsedWidget.h" #include "CompilerOutputPanel.h" #include "longTextDialog.h" #include "Help.h" #include "TutorialDialog.h" #include "MDIEventFilter.h" #include "FWBAboutDialog.h" #include "debugDialog.h" #include "filePropDialog.h" #include "instConf.h" #include "instDialog.h" #include "HttpGet.h" #include "StartTipDialog.h" #include "events.h" #include "importAddressListWizard/ImportAddressListWizard.h" #include "snmpNetworkDiscoveryWizard/SNMPNetworkDiscoveryWizard.h" #include "importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Tools.h" #include "fwbuilder/dns.h" //#include "fwbuilder/crypto.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Management.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Interface.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/FWObject.h" #include #include #include #include #include #include #include #include #include #ifndef _WIN32 # include // for access(2) #else # undef index #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern bool regCheck(); using namespace libfwbuilder; using namespace std; using namespace Ui; FWWindow::FWWindow() : QMainWindow(), // QMainWindow(NULL, Qt::Desktop), m_space(0), previous_subwindow(0), instd(0), editorOwner(0), printer(0), searchObject(0), replaceObject(0), auto_load_from_rcs_head_revision(0), oe(0), findObjectWidget(0), findWhereUsedWidget(0), undoGroup(0) { instd = new instDialog(this); m_mainWindow = new Ui::FWBMainWindow_q(); m_mainWindow->setupUi(dynamic_cast(this)); this->setupGlobalToolbar(); //setCentralWidget(m_space); psd = NULL; prepareFileOpenRecentMenu(); setCompileAndInstallActionsEnabled(false); // ProjectPanel *proj = newProjectPanel(); // showSub(proj); #ifdef Q_OS_MACX m_mainWindow->m_space->setViewMode(QMdiArea::TabbedView); #endif findObjectWidget = new FindObjectWidget( m_mainWindow->find_panel, NULL, "findObjectWidget"); findObjectWidget->setFocusPolicy( Qt::NoFocus ); m_mainWindow->find_panel->layout()->addWidget( findObjectWidget ); findObjectWidget->show(); findWhereUsedWidget = new FindWhereUsedWidget( m_mainWindow->find_panel, NULL, "findWhereUsedWidget"); findWhereUsedWidget->setFocusPolicy( Qt::NoFocus ); m_mainWindow->find_panel->layout()->addWidget( findWhereUsedWidget ); findWhereUsedWidget->hide(); // compiler_output = new CompilerOutputPanel(m_mainWindow->output_panel); // m_mainWindow->output_panel->layout()->addWidget(compiler_output); // compiler_output->show(); // Designer adds editorDockWidget to the child widget of the main // window and I can't seem to be able to get rid of this // intermediatery child widget (named "widget"). Reparent editor // dock panel. m_mainWindow->editorDockWidget->setParent(this); addDockWidget(Qt::BottomDockWidgetArea, m_mainWindow->editorDockWidget); m_mainWindow->editorDockWidget->hide(); oe = new ObjectEditor((QWidget*)m_mainWindow->objectEditorStack); m_mainWindow->editorDockWidget->setupEditor(oe); m_mainWindow->editorDockWidget->hide(); undoGroup = new QUndoGroup(this); undoAction = undoGroup->createUndoAction(this); undoAction->setShortcut(tr("Ctrl+Z")); m_mainWindow->undoView->setGroup(undoGroup); if (st->getShowUndoPanel()) m_mainWindow->undoDockWidget->show(); else m_mainWindow->undoDockWidget->hide(); connect(m_mainWindow->undoDockWidget, SIGNAL(visibilityChanged(bool)), this, SLOT(undoViewVisibilityChanged(bool))); redoAction = undoGroup->createRedoAction(this); QList redoShortcuts; redoShortcuts << tr("Ctrl+Y") << tr("Shift+Ctrl+Z"); redoAction->setShortcuts(redoShortcuts); m_mainWindow->editMenu->insertAction(m_mainWindow->editMenu->actions().at(0), undoAction); m_mainWindow->editMenu->insertAction(undoAction, redoAction); printer = new QPrinter(QPrinter::HighResolution); current_version_http_getter = new HttpGet(); connect(current_version_http_getter, SIGNAL(done(const QString&)), this, SLOT(checkForUpgrade(const QString&))); connect( m_mainWindow->findAction, SIGNAL( triggered() ), this, SLOT(search()) ); connect( m_mainWindow->editMenu, SIGNAL (aboutToShow() ), this, SLOT( prepareEditMenu() )); connect( m_mainWindow->viewMenu, SIGNAL (aboutToShow() ), this, SLOT( prepareViewMenu() )); connect( m_mainWindow->ObjectMenu, SIGNAL (aboutToShow() ), this, SLOT( prepareObjectMenu() )); connect( m_mainWindow->fileMenu, SIGNAL (aboutToShow() ), this, SLOT( prepareFileMenu() )); connect( m_mainWindow->toolsMenu, SIGNAL (aboutToShow() ), this, SLOT( prepareToolsMenu() )); connect( m_mainWindow->menuWindow, SIGNAL (aboutToShow() ), this, SLOT( prepareWindowsMenu() )); connect( m_mainWindow->RulesMenu, SIGNAL (aboutToShow()), this, SLOT(prepareRulesMenu())); connect( m_mainWindow->m_space, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(subWindowActivated(QMdiSubWindow*))); ruleStaticActions = m_mainWindow->RulesMenu->actions(); m_mainWindow->RulesMenu->actions().clear(); disableActions(false); ProjectPanel *proj = newProjectPanel(); showSub(proj); proj->setActive(); setSafeMode(false); // findObject->setMinimumSize( QSize( 0, 0 ) ); QWidget *tabbar= m_mainWindow->m_space->findChild(); if (tabbar) tabbar->installEventFilter(new MDIEventFilter()); } FWWindow::~FWWindow() { QList subwindows = m_mainWindow->m_space->subWindowList( QMdiArea::StackingOrder); foreach (QMdiSubWindow* sw, subwindows) { //ProjectPanel *pp = dynamic_cast(sw->widget()); sw->close(); delete sw; } delete m_mainWindow; } void FWWindow::prepareFileOpenRecentMenu() { for (int i = 0; i < MAXRECENTFILES; ++i) { recentFileActs[i] = new QAction(this); recentFileActs[i]->setVisible(false); connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile())); m_mainWindow->menuOpen_Recent->addAction(recentFileActs[i]); } openRecentSeparatorAct = m_mainWindow->menuOpen_Recent->addSeparator(); m_mainWindow->menuOpen_Recent->addAction(m_mainWindow->actionClearRecentFiles); updateRecentFileActions(); } void FWWindow::clearRecentFilesMenu() { QStringList empty_list; st->setRecentFiles(empty_list); updateRecentFileActions(); } void FWWindow::updateRecentFileActions() { QStringList files = st->getRecentFiles(); QMap file_name_counters; int numRecentFiles = qMin(files.size(), (int)MAXRECENTFILES); for (int i = 0; i < numRecentFiles; ++i) { QString file_name = QFileInfo(files[i]).fileName(); int c = file_name_counters[file_name]; // default constructed value is 0 file_name_counters[file_name] = c + 1; } for (int i = 0; i < numRecentFiles; ++i) { QString file_name = QFileInfo(files[i]).fileName(); int c = file_name_counters[file_name]; // if c > 1, we have two files with the same name but different path QString text = (c > 1) ? files[i] : file_name; recentFileActs[i]->setText(text); recentFileActs[i]->setData(files[i]); recentFileActs[i]->setVisible(true); } for (int j = numRecentFiles; j < MAXRECENTFILES; ++j) recentFileActs[j]->setVisible(false); openRecentSeparatorAct->setVisible(numRecentFiles > 0); } /* * Add file name to the "File/Open Recent" menu. */ void FWWindow::updateOpenRecentMenu(const QString &fileName) { QStringList files = st->getRecentFiles(); files.removeAll(fileName); files.prepend(fileName); while (files.size() > MAXRECENTFILES) files.removeLast(); st->setRecentFiles(files); updateRecentFileActions(); } void FWWindow::openRecentFile() { QAction *action = qobject_cast(sender()); if (action) { QString file_path = action->data().toString(); if (fwbdebug) qDebug() << "Open recently opened file " << file_path; QMdiSubWindow* sw = alreadyOpened(file_path); if (sw != NULL) { // activate window with this file m_mainWindow->m_space->setActiveSubWindow(sw); return; } loadFile(file_path, false); QCoreApplication::postEvent(this, new updateSubWindowTitlesEvent()); } } void FWWindow::registerAutoOpenDocFile(const QString &filename, bool load_from_rcs_head) { openDocFiles.append(filename); auto_load_from_rcs_head_revision = load_from_rcs_head; } ProjectPanel *FWWindow::newProjectPanel() { ProjectPanel *projectW = new ProjectPanel(m_mainWindow->m_space); projectW->initMain(this); return projectW; } void FWWindow::showSub(ProjectPanel *pp) { QList subwindows = m_mainWindow->m_space->subWindowList( QMdiArea::StackingOrder); bool windows_maximized = (subwindows.size()>0) ? subwindows[0]->isMaximized() : st->getInt("Window/maximized"); if (fwbdebug) qDebug() << "FWWindow::showSub" << "subwindows=" << subwindows << "current window maximized: " << int((subwindows.size()>0) ? subwindows[0]->isMaximized() : 0) << "settings: " << st->getInt("Window/maximized"); QMdiSubWindow *sub = new QMdiSubWindow; pp->mdiWindow = sub; sub->setWidget(pp); sub->setAttribute(Qt::WA_DeleteOnClose); m_mainWindow->m_space->addSubWindow(sub); connect( sub, SIGNAL(aboutToActivate()), pp, SLOT(aboutToActivate())); if (fwbdebug) qDebug() << "Show subwindow maximized: " << windows_maximized; if (windows_maximized) pp->setWindowState(Qt::WindowMaximized); else pp->setWindowState(Qt::WindowNoState); sub->show(); /* * for reasons I do not understand, QMdiArea does not send signal * subWindowActivated when the very first subwindow comes up. I * think it should, but at least QT 4.4.1 on Mac does not do * it. Calling the slot manually so that editor panel can be * attached to the current project panel. */ attachEditorToProjectPanel(pp); if (isEditorVisible()) oe->open(pp->getSelectedObject()); } ProjectPanel* FWWindow::activeProject() { QList subwindows = m_mainWindow->m_space->subWindowList( QMdiArea::StackingOrder); if (subwindows.size() == 0) return NULL; QMdiSubWindow *w = subwindows.last(); // last item is the topmost window // QMdiSubWindow *w = m_mainWindow->m_space->currentSubWindow(); // if (w) return dynamic_cast(w->widget()); // if (fwbdebug) // qDebug() << "FWWindow::activeProject(): currentSubWindow() returns NULL, trying activeSubWindow()"; // w = m_mainWindow->m_space->activeSubWindow(); if (w) return dynamic_cast(w->widget()); return NULL; } void FWWindow::updateWindowTitle() { if (activeProject()) { setWindowTitle("Firewall Builder " + activeProject()->getFileName()); } else { setWindowTitle("Firewall Builder"); } } void FWWindow::startupLoad() { if (st->getCheckUpdates()) { QString update_url = CHECK_UPDATE_URL; // Use env variable FWBUILDER_CHECK_UPDATE_URL to override url to test // e.g. export FWBUILDER_CHECK_UPDATE_URL="file://$(pwd)/update_%1" // char* update_check_override_url = getenv("FWBUILDER_CHECK_UPDATE_URL"); if (update_check_override_url != NULL) update_url = QString(update_check_override_url); // start http query to get latest version from the web site QString url = QString(update_url).arg(VERSION).arg(st->getAppGUID()); if (!current_version_http_getter->get(QUrl(url)) && fwbdebug) { qDebug() << "HttpGet error: " << current_version_http_getter->getLastError(); qDebug() << "Url: " << url; } } if (activeProject()) { activeProject()->loadStandardObjects(); activeProject()->readyStatus(true); activeProject()->loadState(true); } foreach (QString file, openDocFiles) { loadFile(file, auto_load_from_rcs_head_revision); updateOpenRecentMenu(file); } QCoreApplication::postEvent(this, new updateSubWindowTitlesEvent()); showIntroDialog(); QCoreApplication::postEvent(mw, new updateGUIStateEvent()); } void FWWindow::showIntroDialog() { if (st->isIntroDialogEnabled()) { // Show dialog inviting user to look at the "Quick start" // guide on the web site. QMessageBox msg_box; msg_box.setText("" "

Welcome to Firewall Builder

" "

Quick Start Guide

" "

" "There is a short online guide that provides basic information " "to help new users save time when first learning " "to use Firewall Builder." "

" "

" "In this guide you will learn:" "

" "

" "

    " "
  • Layout of the application windows
  • " "
  • Location of frequently used command buttons
  • " "
  • How to create and edit objects
  • " "
  • Where to find predefined system objects
  • " "
" "

" "" ); QPixmap pm; pm.load(":/Images/fwbuilder3-128x128.png"); msg_box.setWindowModality(Qt::ApplicationModal); #if QT_VERSION >= 0x040500 msg_box.setWindowFlags( Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint); #else msg_box.setWindowFlags( Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint); #endif msg_box.setWindowTitle(tr("Welcome to Firewall Builder")); msg_box.setIconPixmap(pm); msg_box.setInformativeText(tr("The guide will open in the web browser")); QCheckBox cb(tr("Do not show this again"), &msg_box); msg_box.addButton(&cb, QMessageBox::ResetRole); // is this role right ? QPushButton *watch_button = msg_box.addButton(tr("Watch the guide"), QMessageBox::AcceptRole); msg_box.addButton(QMessageBox::Close); /* Hack alert! Disconnect signals from the checkbox so that QMessageBox doesn't know when it gets clicked. We check it directly ourselves to see what state it's in when the user clicks "close" or "watch". */ cb.disconnect(); msg_box.setDefaultButton(watch_button); msg_box.exec(); if (cb.isChecked()) { st->setIntroDialogEnabled(false); } if (msg_box.clickedButton() == watch_button) { int ab_group = st->getABTestingGroup(); QString url("http://www.fwbuilder.org/4.0/quick_start_guide_%1.html"); QDesktopServices::openUrl(QUrl(url.arg(ab_group), QUrl::StrictMode)); } return; } if (!st->getBool("UI/NoStartTip")) { StartTipDialog *stdlg = new StartTipDialog(this); stdlg->run(); } } void FWWindow::helpAbout() { FWBAboutDialog ad(this); ad.exec(); } void FWWindow::debug() { debugDialog dd(this); dd.exec(); } void FWWindow::fileNew() { // if the only project panel window that we have shows default // object tree (i.e. its filename is empty) and has no unsaved // changes, then load file into. Otherwise create new project // window. ProjectPanel *proj = activeProject(); if (proj && proj->getFileName().isEmpty() && !proj->db()->isDirty()) { activeProject()->fileNew(); } else { std::auto_ptr proj(newProjectPanel()); if (proj->fileNew()) { showSub(proj.get()); QCoreApplication::postEvent(mw, new updateGUIStateEvent()); //prepareFileMenu(); //updateGlobalToolbar(); //prepareRulesMenu(); proj.release(); } } } void FWWindow::fileOpen() { QString dir; QMdiSubWindow *last_active_window = m_mainWindow->m_space->activeSubWindow(); QString file_name = QFileDialog::getOpenFileName( this, tr("Open File"), st->getOpenFileDir(mw->getCurrentFileName()), "FWB files (*.fwb *.fwl *.xml);;All Files (*)"); if (file_name.isEmpty()) { m_mainWindow->m_space->setActiveSubWindow(last_active_window); return; } st->setOpenFileDir(file_name); // Using absoluteFilePath(), see #1334 QFileInfo fi(file_name); QString file_path = fi.absoluteFilePath(); if (fwbdebug) qDebug() << "FWWindow::fileOpen():" << "File name: " << file_name << "Absolute file path: " << file_path; QMdiSubWindow* sw = alreadyOpened(file_name); if (sw != NULL) { if (fwbdebug) qDebug() << "This file is already opened"; // activate window with this file m_mainWindow->m_space->setActiveSubWindow(sw); return; } QFileInfo file_path_info(file_path); if (!file_path_info.exists() || !file_path_info.isReadable()) { QMessageBox::warning( this,"Firewall Builder", tr("File '%1' does not exist or is not readable").arg(file_path)); return; } if (loadFile(file_path, false)) { updateOpenRecentMenu(file_name); // reset actions, including Save() which should now // be inactive QCoreApplication::postEvent(mw, new updateGUIStateEvent()); //prepareFileMenu(); //prepareRulesMenu(); //updateGlobalToolbar(); QCoreApplication::postEvent(this, new updateSubWindowTitlesEvent()); } else m_mainWindow->m_space->setActiveSubWindow(last_active_window); } QMdiSubWindow* FWWindow::alreadyOpened(const QString &file_name) { QFileInfo fi(file_name); QString file_path = fi.absoluteFilePath(); if (fwbdebug) qDebug() << "FWWindow::alreadyOpened():" << "File name: " << file_name << "Absolute file path: " << file_path; foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList()) { ProjectPanel * pp = dynamic_cast(sw->widget()); if (pp!=NULL) { if (fwbdebug) qDebug() << "Opened file" << pp->getFileName(); if (pp->getFileName() == file_path) return sw; } } return NULL; } bool FWWindow::loadFile(const QString &file_name, bool load_rcs_head) { /* We always create new project panel, deleting the old one if it's the default (standard objects) one with no changes. Otherwise we leave behind traces of the old project panel. */ ProjectPanel *oldProj = activeProject(); ProjectPanel *proj = newProjectPanel(); if (proj->loadFile(file_name, load_rcs_head)) { if (oldProj != 0 && oldProj->getFileName().isEmpty() && (oldProj->db() == NULL || !oldProj->db()->isDirty())) { oldProj->fileClose(); } showSub(proj); } else { delete proj; return false; } proj->readyStatus(true); proj->loadState(true); return true; } void FWWindow::fileClose() { if (fwbdebug) qDebug("FWWindow::fileClose()"); if (activeProject()) { ProjectPanel * project = activeProject(); if (!project->saveIfModified()) return; // abort operation project->saveState(); project->fileClose(); // reset actions, including Save() which should now // be inactive QCoreApplication::postEvent(mw, new updateGUIStateEvent()); //prepareFileMenu(); //prepareRulesMenu(); //updateGlobalToolbar(); } if (fwbdebug) qDebug("subWindowList().size()=%d", m_mainWindow->m_space->subWindowList().size()); } void FWWindow::fileExit() { if (fwbdebug) qDebug() << "FWWindow::fileExit()"; bool window_maximized_state = false; if (activeProject()) { QList subWindowList = m_mainWindow->m_space->subWindowList(); for (int i = 0 ; i < subWindowList.size(); i++) { window_maximized_state = subWindowList[i]->isMaximized(); ProjectPanel * project = dynamic_cast(subWindowList[i]->widget()); if (project!=NULL) { if (!project->saveIfModified() || !project->checkin(true)) return; // aborted //if (!project->saveIfModified()) return; // abort operation project->saveState(); project->fileClose(); } } } st->setInt("Window/maximized", window_maximized_state); app->quit(); } void FWWindow::toolsImportAddressesFromFile() { if (activeProject()) { ImportAddressListWizard wiz(this); wiz.exec(); } } void FWWindow::toolsSNMPDiscovery() { if (activeProject()) { SNMPNetworkDiscoveryWizard wiz(this); wiz.exec(); } } void FWWindow::importPolicy() { if (activeProject()) { if (!activeProject()->m_panel->om->isObjectAllowed(Firewall::TYPENAME)) return; ImportFirewallConfigurationWizard wiz(this, db()); wiz.exec(); } } void FWWindow::showEvent(QShowEvent *ev) { st->restoreGeometry(this, QRect(100,100,1000,600) ); QMainWindow::showEvent(ev); } void FWWindow::hideEvent(QHideEvent *ev) { st->saveGeometry(this); QMainWindow::hideEvent(ev); } void FWWindow::prepareEditMenu() { if (!activeProject()) { m_mainWindow->editCopyAction->setEnabled(false); m_mainWindow->editDeleteAction->setEnabled(false); m_mainWindow->editCutAction->setEnabled(false); m_mainWindow->editPasteAction->setEnabled(false); return; } bool dupMenuItem=true; bool moveMenuItem=true; bool copyMenuItem=true; bool pasteMenuItem=true; bool delMenuItem=true; bool newMenuItem=true; bool inDeletedObjects = false; activeProject()->m_panel->om->getMenuState( false, dupMenuItem, moveMenuItem, copyMenuItem, pasteMenuItem, delMenuItem, newMenuItem, inDeletedObjects ); m_mainWindow->editCopyAction->setEnabled(copyMenuItem); m_mainWindow->editDeleteAction->setEnabled(delMenuItem); m_mainWindow->editCutAction->setEnabled(delMenuItem); m_mainWindow->editPasteAction->setEnabled(pasteMenuItem); } void FWWindow::prepareViewMenu() { if (!activeProject()) { m_mainWindow->actionObject_Tree->setEnabled(false); m_mainWindow->actionEditor_panel->setEnabled(false); return; } m_mainWindow->actionObject_Tree->setEnabled(true); m_mainWindow->actionEditor_panel->setEnabled(true); m_mainWindow->actionObject_Tree->setChecked( activeProject()->m_panel->treePanelFrame->isVisible()); m_mainWindow->actionEditor_panel->setChecked( m_mainWindow->editorDockWidget->isVisible()); m_mainWindow->actionUndo_view->setChecked( m_mainWindow->undoDockWidget->isVisible()); } void FWWindow::prepareObjectMenu() { if (!activeProject()) { m_mainWindow->newObjectAction->setEnabled(false); m_mainWindow->findAction->setEnabled(false); m_mainWindow->ObjectLockAction->setEnabled(false); m_mainWindow->ObjectUnlockAction->setEnabled(false); return; } m_mainWindow->ObjectUnlockAction->setEnabled( activeProject()->m_panel->om->isCurrentObjectUnlockable()); m_mainWindow->ObjectLockAction->setEnabled( activeProject()->m_panel->om->isCurrentObjectLockable()); } void FWWindow::prepareFileMenu() { if (!activeProject()) { m_mainWindow->fileCloseAction->setEnabled(false); m_mainWindow->fileSaveAction->setEnabled(false); m_mainWindow->fileSaveAsAction->setEnabled(false); m_mainWindow->addToRCSAction->setEnabled(false); m_mainWindow->fileCommitAction->setEnabled(false); m_mainWindow->fileDiscardAction->setEnabled(false); m_mainWindow->filePropAction->setEnabled(false); m_mainWindow->libExportAction->setEnabled(false); m_mainWindow->libImportAction->setEnabled(false); m_mainWindow->policyImportAction->setEnabled(false); return; } bool real_file_opened = (activeProject()->getFileName() != ""); bool in_rcs = (activeProject()->getRCS() != NULL && activeProject()->getRCS()->isCheckedOut()); bool needs_saving = (db() && db()->isDirty()); m_mainWindow->fileSaveAction->setEnabled(real_file_opened && needs_saving); m_mainWindow->fileCloseAction->setEnabled(real_file_opened); m_mainWindow->filePropAction->setEnabled(real_file_opened); m_mainWindow->filePrintAction->setEnabled(real_file_opened); m_mainWindow->libExportAction->setEnabled(real_file_opened); FWObject *lib = activeProject()->getCurrentLib(); bool f = ( lib == NULL || lib->getId()==FWObjectDatabase::TEMPLATE_LIB_ID || lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID || lib->isReadOnly() ); bool new_object_op_possible = !f; m_mainWindow->libImportAction->setEnabled(new_object_op_possible); m_mainWindow->policyImportAction->setEnabled(new_object_op_possible); m_mainWindow->addToRCSAction->setEnabled(real_file_opened && !in_rcs); m_mainWindow->fileCommitAction->setEnabled( real_file_opened && in_rcs && needs_saving); m_mainWindow->fileDiscardAction->setEnabled( real_file_opened && in_rcs && needs_saving); m_mainWindow->fileNewAction->setEnabled(true); m_mainWindow->fileOpenAction->setEnabled(true); m_mainWindow->fileSaveAsAction->setEnabled(true); } void FWWindow::prepareToolsMenu() { #ifdef HAVE_LIBSNMP m_mainWindow->SNMPDiscoveryAction->setEnabled(true); #else m_mainWindow->SNMPDiscoveryAction->setEnabled(false); #endif } void FWWindow::prepareWindowsMenu() { windowsPainters.clear(); windowsTitles.clear(); m_mainWindow->menuWindow->clear(); QAction *close = m_mainWindow->menuWindow->addAction("Close"); QAction *closeAll = m_mainWindow->menuWindow->addAction("Close All"); QAction *tile = m_mainWindow->menuWindow->addAction("Tile"); QAction *cascade = m_mainWindow->menuWindow->addAction("Cascade"); QAction *next = m_mainWindow->menuWindow->addAction("Next"); QAction *previous = m_mainWindow->menuWindow->addAction("Previous"); QAction *minimize = m_mainWindow->menuWindow->addAction("Minimize"); QAction *maximize = m_mainWindow->menuWindow->addAction("Maximize"); m_mainWindow->menuWindow->addSeparator(); connect(minimize, SIGNAL(triggered()), this, SLOT(minimize())); connect(maximize, SIGNAL(triggered()), this, SLOT(maximize())); connect(close, SIGNAL(triggered()), m_mainWindow->m_space, SLOT(closeActiveSubWindow())); connect(closeAll, SIGNAL(triggered()), m_mainWindow->m_space, SLOT(closeAllSubWindows())); connect(tile, SIGNAL(triggered()), m_mainWindow->m_space, SLOT(tileSubWindows())); connect(cascade, SIGNAL(triggered()), m_mainWindow->m_space, SLOT(cascadeSubWindows())); connect(next, SIGNAL(triggered()), m_mainWindow->m_space, SLOT(activateNextSubWindow())); connect(previous, SIGNAL(triggered()), m_mainWindow->m_space, SLOT(activatePreviousSubWindow())); QList subWindowList = m_mainWindow->m_space->subWindowList(); minimize->setEnabled(subWindowList.size() > 0); maximize->setEnabled(subWindowList.size() > 0); close->setEnabled(subWindowList.size() > 0); closeAll->setEnabled(subWindowList.size() > 0); tile->setEnabled(subWindowList.size() > 0); cascade->setEnabled(subWindowList.size() > 0); next->setEnabled(subWindowList.size() > 0); previous->setEnabled(subWindowList.size() > 0); QActionGroup * ag = new QActionGroup(this); ag->setExclusive (true); for (int i = 0 ; i < subWindowList.size(); i++) { windowsPainters.push_back (subWindowList[i]); ProjectPanel * pp = dynamic_cast( subWindowList[i]->widget()); if (pp!=NULL) { if (fwbdebug) qDebug("FWWindow::prepareWindowsMenu() pp=%p", pp); //if (pp->isClosing()) continue ; QString text = subWindowList[i]->windowTitle(); windowsTitles.push_back(text); QAction * act = m_mainWindow->menuWindow->addAction(text); ag->addAction(act); act->setCheckable ( true ); if (subWindowList[i] == m_mainWindow->m_space->activeSubWindow()) act->setChecked(true); connect(act, SIGNAL(triggered()), this, SLOT(selectActiveSubWindow())); } } } /* * returns list of file names (full canonical path) of the data files * currently opened in the program */ QStringList FWWindow::getListOfOpenedFiles() { QStringList res; QList subWindowList = m_mainWindow->m_space->subWindowList(); for (int i = 0 ; i < subWindowList.size(); i++) { ProjectPanel * pp = dynamic_cast(subWindowList[i]->widget()); if (pp!=NULL) { res.push_back(pp->getFileName()); // full path } } return res; } void FWWindow::activatePreviousSubWindow() { if (fwbdebug) qDebug() << "FWWindow::activatePreviousSubWindow()"; m_mainWindow->m_space->setActiveSubWindow(previous_subwindow); } /** * QMdiArea emits this signal after window has been activated. When * window is 0, QMdiArea has just deactivated its last active window, * and there are no active windows on the workspace. * * During the call to this method @subwindow is already current (equal * to the pointer returned by m_mainWindow->m_space->currentSubWindow()) */ void FWWindow::subWindowActivated(QMdiSubWindow *subwindow) { if (subwindow==NULL) return; if (fwbdebug) qDebug() << "FWWindow::subWindowActivated" << "subwindow=" << subwindow << "(" << subwindow->windowTitle() << ")" << "previous_subwindow=" << previous_subwindow << "(" << QString((previous_subwindow) ? previous_subwindow->windowTitle() : "") << ")" << "isMaximized()=" << subwindow->isMaximized(); if (previous_subwindow == subwindow) return; previous_subwindow = subwindow; ProjectPanel *pp = dynamic_cast(subwindow->widget()); if (pp) { QCoreApplication::postEvent(mw, new updateGUIStateEvent()); pp->setActive(); if (isEditorVisible()) openEditor(pp->getSelectedObject()); } } void FWWindow::attachEditorToProjectPanel(ProjectPanel *pp) { findObjectWidget->attachToProjectWindow(pp); findWhereUsedWidget->attachToProjectWindow(pp); oe->attachToProjectWindow(pp); } void FWWindow::editPrefs() { PrefsDialog pd(this); pd.exec(); } void FWWindow::editFind() { } void FWWindow::helpContents() { } void FWWindow::helpContentsAction() { } void FWWindow::helpIndex() { } QPrinter* FWWindow::getPrinter() { return printer; } void FWWindow::closeEvent(QCloseEvent* ev) { if (fwbdebug) qDebug("FWWindow::closeEvent"); if (activeProject()) st->setInt("Window/maximized", activeProject()->mdiWindow->isMaximized()); QList subWindowList = m_mainWindow->m_space->subWindowList(); for (int i = 0 ; i < subWindowList.size();i++) { ProjectPanel * pp = dynamic_cast( subWindowList[i]->widget()); if (pp!=NULL) { if (!pp->saveIfModified()) { ev->ignore(); return; } pp->saveState(); pp->fileClose(); } } } bool FWWindow::event(QEvent *event) { if (event->type() >= QEvent::User) { fwbUpdateEvent *ev = dynamic_cast(event); int obj_id = ev->getObjectId(); /* * TODO: * * db() returns pointer to the FWObjectDatabase object that * belongs to the current active project panel. If the event * was sent for an object that does not belong to the active * panel, the object @obj won't be found in this * database. Event has project file name as another parameter, * need to use that to localte right project panel instead of * just calling activeProject(). * * This happens when two data files are open and object tree * panels are detached. User can try to open an object from * file A by double clicking in the tree, while active panel * shows file B. See ticket #1804 "With 2 files open and * object trees undocked you cannot open objects from both * object trees" */ FWObject *obj = db()->findInIndex(obj_id); ProjectPanel *pp = activeProject(); if (fwbdebug) qDebug() << this << "event:" << ev->getEventName() << "object:" << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : ""); switch (event->type() - QEvent::User) { case UPDATE_GUI_STATE_EVENT: prepareFileMenu(); prepareEditMenu(); updateGlobalToolbar(); // do not return, let ProjectPanel process the same event as well break; case OPEN_OBJECT_IN_EDITOR_EVENT: { if (pp && obj) { openEditor(obj); // pp->editObject(obj); pp->mdiWindow->update(); } ev->accept(); return true; } case OPEN_OPT_OBJECT_IN_EDITOR_EVENT: { if (pp && obj) { openOptEditor( obj, dynamic_cast(event)->opt_code); // pp->editObject(obj); pp->mdiWindow->update(); } ev->accept(); return true; } case UPDATE_SUBWINDOW_TITLES_EVENT: { QMap short_name_counters; QMap short_titles; QMap long_titles; foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList()) { ProjectPanel * pp = dynamic_cast(sw->widget()); if (pp!=NULL) { // string returned by getPageTitle() may also // include RCS revision number. Compare only // file name, without the path and rev number // to make sure we show long paths for two // subwindows where file names are identical, // regardless of the RCS revision number. QString file_name = pp->getFileName(); // full path QFileInfo fi(file_name); QString short_name = fi.fileName(); int c = short_name_counters[short_name]; short_name_counters[short_name] = c + 1; short_titles[sw] = pp->getPageTitle(false); long_titles[sw] = pp->getPageTitle(true); if (fwbdebug) qDebug() << "Subwindow " << sw << "file_name " << file_name << "short_name " << short_name << "short_name_counter " << c << "short_title " << short_titles[sw] << "long_title " << long_titles[sw]; } } foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList()) { QString short_name = short_titles[sw]; if (short_name_counters[short_name] > 1) sw->setWindowTitle(long_titles[sw]); else sw->setWindowTitle(short_titles[sw]); } ev->accept(); return true; } case CLOSE_EDITOR_PANEL_EVENT: { hideEditor(); ev->accept(); return true; } case CLEAR_EDITOR_PANEL_EVENT: { clearEditorAndSearchPanels(); ev->accept(); return true; } } // dispatch event to all projectpanel windows foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList()) QCoreApplication::sendEvent(sw->widget(), event); event->accept(); return true; } //if (fwbdebug) qDebug() << this << "event:" << event; return QMainWindow::event(event); } void FWWindow::selectActiveSubWindow(/*const QString & text*/) { QObject * sender_ = sender (); QAction * act = (QAction*) sender_ ; QString text = act->text(); if (text=="[Noname]") text=""; if (fwbdebug) qDebug() << "FWWindow::selectActiveSubWindow()" << "text=" << text; for (int i = 0 ; i < windowsTitles.size();i++) { if (windowsTitles[i]==text) { m_mainWindow->m_space->setActiveSubWindow(windowsPainters[i]); } } } void FWWindow::minimize() { if (fwbdebug) qDebug("FWWindow::minimize"); if (m_mainWindow->m_space->activeSubWindow()) { m_mainWindow->m_space->activeSubWindow()->showMinimized (); st->setInt("Window/maximized", 0); QList subWindowList = m_mainWindow->m_space->subWindowList(); for (int i = 0 ; i < subWindowList.size();i++) { ProjectPanel * pp = dynamic_cast( subWindowList[i]->widget()); if (pp!=NULL) { pp->loadState(false); } } } } void FWWindow::maximize() { if (fwbdebug) qDebug("FWWindow::maximize"); if (m_mainWindow->m_space->activeSubWindow()) { m_mainWindow->m_space->activeSubWindow()->showMaximized (); st->setInt("Window/maximized", 1); } } void FWWindow::updateTreeFont () { QFont font = st->getTreeFont(); QList subWindowList = m_mainWindow->m_space->subWindowList(); for (int i = 0 ; i < subWindowList.size();i++) { ProjectPanel * pp = dynamic_cast (subWindowList[i]->widget()); if (pp!=NULL) { std::vector trees = pp->m_panel->om->getTreeWidgets(); for (unsigned int o = 0 ; o < trees.size(); o++) { trees[o]->setFont(font); } } } } void FWWindow::checkForUpgrade(const QString& server_response) { if (fwbdebug) qDebug() << "FWWindow::checkForUpgrade server_response: " << server_response << " http_getter_status: " << current_version_http_getter->getStatus(); disconnect(current_version_http_getter, SIGNAL(done(const QString&)), this, SLOT(checkForUpgrade(const QString&))); /* * getStatus() returns error status if server esponded with 302 or * 301 redirect. Only "200" is considered success. */ if (current_version_http_getter->getStatus()) { /* * server response may be some html or other data in case * connection goes via proxy, esp. with captive portals. We * should not interpret that as "new version is available" */ uint now = QDateTime::currentDateTime().toTime_t(); uint last_update_available_warning_time = st->getTimeOfLastUpdateAvailableWarning(); bool update_available = (server_response.trimmed() == "update = 1"); if (update_available && (now - last_update_available_warning_time > 24*3600) ) { QMessageBox::warning( this,"Firewall Builder", tr("A new version of Firewall Builder is available at" " http://www.fwbuilder.org")); st->setTimeOfLastUpdateAvailableWarning(now); } else { // format of the announcement string is very simple: it is just // announcement = URL // All on one line. QRegExp announcement_re = QRegExp("announcement\\s*=\\s*(\\S+)"); if (announcement_re.indexIn(server_response.trimmed()) != -1) { QStringList list = announcement_re.capturedTexts(); if (list.size() > 1) { QString announcement_url = list[1]; uint last_annluncement_time = st->getTimeOfLastAnnouncement( announcement_url); if (fwbdebug) qDebug() << "announcement_url=" << announcement_url << "last_annluncement_time=" << last_annluncement_time; if (last_annluncement_time == 0) { // We have an announcement to make and this user has not // seen it yet. st->setTimeOfLastAnnouncement(announcement_url, now); Help *h = Help::getHelpWindow(this); h->setSource(QUrl(announcement_url)); } } } } } else { if (fwbdebug) qDebug("Update check error: %s", current_version_http_getter->getLastError(). toLatin1().constData()); } } /* * This slot is called after one of the mdi windows is closed. This * is where the decision is made as to wether we should terminate the * program when the last MDI window is closed. Bug #2144114 "fwbuilder * exits if the last object file is closed" requests for the program * to continue after the last window is closed. */ void FWWindow::projectWindowClosed() { // if (m_space->subWindowList().size() == 0) QCoreApplication::exit(0); } void FWWindow::help() { Help *h = Help::getHelpWindow(this); h->setSource(QUrl("main.html")); h->raise(); h->show(); } void FWWindow::showReleaseNotes() { QStringList version_components = QString(VERSION).split("."); assert(version_components.size() >= 3); QString version_no_build = QString("%1.%2.%3") .arg(version_components[0]) .arg(version_components[1]) .arg(version_components[2]); QString file_name = QString("release_notes_%1.html").arg(version_no_build); // Show "release notes" dialog only if corresponding file // exists. QString contents; Help *h = Help::getHelpWindow(this); h->setName("Firewall Builder Release Notes"); if (h->findHelpFile(file_name).isEmpty()) { // the file does not exist h->hide(); } else { // I do not know why, but url "file://file_name" does not seem to work. // But "file:file_name" works. h->setSource(QUrl("file:" + file_name)); h->raise(); h->show(); //h->exec(); // Class Help uses attribute Qt::WA_DeleteOnClose which // means the system will delete the object on close. No // need to delete it explicitly if it was shown. } } void FWWindow::enableBackAction() { m_mainWindow->backAction->setEnabled(true); } void FWWindow::activateRule(ProjectPanel* project, QString fwname, QString setname, int rule) { // Find firewall object tree item FWObject* firewall = NULL; foreach(QTreeWidgetItem* item, project->getCurrentObjectTree()->findItems(fwname, Qt::MatchExactly | Qt::MatchRecursive, 0)) { if (Firewall::cast(dynamic_cast(item)->getFWObject())!=NULL) { firewall = dynamic_cast(item)->getFWObject(); break; } } if (firewall == NULL) return; FWObject::const_iterator i = find_if(firewall->begin(), firewall->end(), FWObjectNameEQPredicate(string(setname.toUtf8().constData()))); if (i==firewall->end()) return; RuleSet *set = RuleSet::cast(*i); if (set == NULL) return; QCoreApplication::postEvent( mw, new openRulesetImmediatelyEvent(project->getFileName(), set->getId())); FWObject *ruleObject = set->getRuleByNum(rule); if (ruleObject == NULL) return; QCoreApplication::postEvent(mw, new selectRuleElementEvent(project->getFileName(), ruleObject->getId(), ColDesc::Action)); } void FWWindow::undoViewVisibilityChanged(bool visible) { if(mw->isVisible()) st->setShowUndoPanel(visible); } void FWWindow::updateGlobalToolbar() { ProjectPanel* pp = activeProject(); if (pp) { list fws; if (pp->db() != NULL) pp->findAllFirewalls(fws); setCompileAndInstallActionsEnabled(fws.size() != 0); } else setCompileAndInstallActionsEnabled(false); } void FWWindow::setupGlobalToolbar() { setUnifiedTitleAndToolBarOnMac(false); if (st->getBool("/UI/IconWithText")) m_mainWindow->toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); else m_mainWindow->toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); setUnifiedTitleAndToolBarOnMac(true); } /* * This method constructs main menu "Rules" and enables or disables items * as appropriate. */ void FWWindow::prepareRulesMenu() { if (fwbdebug) qDebug() << "FWWindow::prepareRulesMenu()"; cleanRulesMenu(); ProjectPanel* pp = activeProject(); if (pp) { RuleSetView* rsv = activeProject()->getCurrentRuleSetView(); if (fwbdebug) qDebug() << "FWWindow::prepareRulesMenu() rsv=" << rsv; if(rsv) { if (rsv->selectedRulesCount() == 0) rsv->addGenericMenuItemsToContextMenu(m_mainWindow->RulesMenu); else rsv->addRowMenuItemsToMenu(m_mainWindow->RulesMenu); } m_mainWindow->RulesMenu->addSeparator(); m_mainWindow->RulesMenu->addActions(ruleStaticActions); list fws; pp->findAllFirewalls(fws); setCompileAndInstallActionsEnabled(fws.size() != 0); } } void FWWindow::cleanRulesMenu() { if (fwbdebug) qDebug() << "FWWindow::cleanRulesMenu()"; m_mainWindow->RulesMenu->actions().clear(); m_mainWindow->RulesMenu->clear(); } void FWWindow::showStatusBarMessage(const QString &txt) { statusBar()->showMessage(txt); // Keep status bar message little longer so user can read it. See #272 QTimer::singleShot( 1000, statusBar(), SLOT(clearMessage())); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); } void FWWindow::setCompileAndInstallActionsEnabled(bool en) { if (fwbdebug) qDebug() << "FWWindow::setCompileAndInstallActionsEnabled en=" << en; m_mainWindow->compileAction->setEnabled(en ); m_mainWindow->installAction->setEnabled(en ); m_mainWindow->inspectAction->setEnabled(en ); } void FWWindow::setEnabledAfterRF() { if (fwbdebug) qDebug() << "FWWindow::setEnabledAfterRF()"; m_mainWindow->compileAction->setEnabled( true ); m_mainWindow->installAction->setEnabled( true ); m_mainWindow->inspectAction->setEnabled( true ); } void FWWindow::selectRules() { if (fwbdebug) qDebug() << "FWWindow::selectRules()"; m_mainWindow ->compileAction->setEnabled( true ); m_mainWindow ->installAction->setEnabled( true ); m_mainWindow ->inspectAction->setEnabled( true ); if (activeProject()) activeProject()->selectRules(); } void FWWindow::disableActions(bool havePolicies) { if (fwbdebug) qDebug() << "FWWindow::disableActions()"; m_mainWindow ->compileAction->setEnabled(havePolicies); m_mainWindow ->installAction->setEnabled(havePolicies); m_mainWindow ->inspectAction->setEnabled(havePolicies); } void FWWindow::compile() { if (activeProject()) { activeProject()->save(); // if there is no file name associated with the project yet, // user is offered a chance to choose the file. If they hit // Cancel in the dialog where they choose the file name, // operation should be cancelled. We do not get direct // information whether they hit Cancel so the only way to // check is to verify that the file has been saved at this // point. if (activeProject()->db()->isDirty()) return; std::set emp; instd->show(this->activeProject(), false, false, emp); } } void FWWindow::install() { if (activeProject()) { activeProject()->save(); // see comment in FWWindow::compile() if (activeProject()->db()->isDirty()) return; std::set emp; instd->show(this->activeProject(), true, false, emp); } } void FWWindow::compile(set vf) { if (fwbdebug) qDebug("FWWindow::compile preselected %d firewalls", int(vf.size())); if (activeProject()) { activeProject()->save(); // see comment in FWWindow::compile() if (activeProject()->db()->isDirty()) return; instd->show(this->activeProject(), false, true, vf); } } void FWWindow::install(set vf) { if (activeProject()) { activeProject()->save(); // see comment in FWWindow::compile() if (activeProject()->db()->isDirty()) return; instd->show(this->activeProject(), true, true, vf); } } void FWWindow::inspect() { if (activeProject()) { activeProject()->save(); // see comment in FWWindow::compile() if (activeProject()->db()->isDirty()) return; this->activeProject()->inspectAll(); } } void FWWindow::addNewObjectMenu(QMenu *m) { QMenu *old_menu = m_mainWindow->newObjectAction->menu(); if (old_menu) delete old_menu; m_mainWindow->newObjectAction->setMenu( m ); } void FWWindow::showNewObjectMenu() { m_mainWindow->newObjectAction->menu()->popup(QCursor::pos()); } fwbuilder-5.1.0.3599/src/libgui/ObjectListViewItem.h0000644000175000017500000000423211733011756022726 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECTLISTVIEWITEM_H #define OBJECTLISTVIEWITEM_H #include "global.h" #include #include "FWWindow.h" #include "fwbuilder/FWObjectDatabase.h" #include #include namespace libfwbuilder { class FWObject; } class ObjectTreeView; class ObjectListViewItem : public QTreeWidgetItem { libfwbuilder::FWObjectDatabase *db; QMap props; QString lib; int ID; public: ObjectListViewItem(QTreeWidget *parent) : QTreeWidgetItem(parent) { db = NULL; ID = -1; } ObjectListViewItem(QTreeWidgetItem *parent) : QTreeWidgetItem(parent) { db = NULL; ID = -1; } libfwbuilder::FWObject *getFWObject() const { if (ID > -1) return db->getById(ID, true); else return NULL; } int getFWObjectID() {return ID; } void setFWObject(libfwbuilder::FWObject *obj) { db = obj->getRoot(); ID = obj->getId(); } ObjectTreeView* getTree(); QString getLib() { return lib; } void setLib(const QString &l) { lib=l; } QString getProperty(const QString &name) { return props[name]; } void setProperty(const QString &name,const QString &val) { props[name]=val; } virtual bool operator< ( const QTreeWidgetItem & other ) const; }; #endif fwbuilder-5.1.0.3599/src/libgui/bsdIfaceOptsDialog.cpp0000644000175000017500000001122511733011756023233 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "bsdIfaceOptsDialog.h" #include "platforms.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "FWWindow.h" #include "Help.h" #include #include using namespace std; using namespace libfwbuilder; bsdIfaceOptsDialog::bsdIfaceOptsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::bsdIfaceOptsDialog_q; m_dialog->setupUi(this); setWindowModality(Qt::WindowModal); obj = o; FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject(); cluster_interface = (Cluster::cast(obj->getParent()) != NULL); setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj), ifopt->getStr("type").c_str()); // Using "type" control only for subinterfaces // and main interfaces of the firewall objects if (cluster_interface) { m_dialog->iface_type->hide(); m_dialog->iface_type_label->hide(); } else { m_dialog->iface_type->show(); m_dialog->iface_type_label->show(); } int mtu = ifopt->getInt("iface_mtu"); if (mtu <=0 ) { mtu = 1500; ifopt->setInt("iface_mtu", mtu); } data.registerOption(m_dialog->vlan_id, ifopt, "vlan_id"); data.registerOption(m_dialog->iface_configure_mtu, ifopt, "iface_configure_mtu"); data.registerOption(m_dialog->iface_mtu, ifopt, "iface_mtu"); data.registerOption(m_dialog->iface_options, ifopt, "iface_options"); data.registerOption(m_dialog->enable_stp, ifopt, "enable_stp"); data.loadAll(); // special actions for different iface types // VLAN (8021q) typeChanged(""); } bsdIfaceOptsDialog::~bsdIfaceOptsDialog() { delete m_dialog; } /* * store all data in the object */ void bsdIfaceOptsDialog::accept() { // validate user input before saving if (!validate()) return; ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the interface object FWObject* new_state = cmd->getNewState(); FWOptions* ifopt = Interface::cast(new_state)->getOptionsObject(); assert(ifopt!=NULL); if (cluster_interface) { ifopt->setStr("type", "cluster_interface"); } else { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); ifopt->setStr("type", new_type.toStdString()); } data.saveAll(ifopt); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void bsdIfaceOptsDialog::reject() { QDialog::reject(); } void bsdIfaceOptsDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Interface OpenBSD"); h->setSource(QUrl("bsdIfaceOptsDialog.html#" + anchor)); h->raise(); h->show(); } void bsdIfaceOptsDialog::typeChanged(const QString&) { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); // enable VLAN ID line edit for type VLAN if (new_type.isEmpty() || new_type == "ethernet") { m_dialog->options_stack->setCurrentIndex(1); return; } if (new_type == "8021q") { m_dialog->options_stack->setCurrentIndex(2); return; } if (new_type == "bridge") { m_dialog->options_stack->setCurrentIndex(3); return; } // page 0 is empty m_dialog->options_stack->setCurrentIndex(0); } bool bsdIfaceOptsDialog::validate() { return true; } fwbuilder-5.1.0.3599/src/libgui/UserDialog.h0000644000175000017500000000250511733011756021251 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __USERDIALOG_H_ #define __USERDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class UserDialog : public BaseObjectDialog { Q_OBJECT; Ui::UserDialog_q *m_dialog; public: UserDialog(QWidget *parent); ~UserDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // UserDialog_H fwbuilder-5.1.0.3599/src/libgui/FirewallInstaller.cpp0000644000175000017500000006607511733011756023205 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "CompilerDriver.h" #include "Configlet.h" #include "FWBSettings.h" #include "FWWindow.h" #include "FirewallInstaller.h" #include "SSHSession.h" #include "SSHUnx.h" #include "instDialog.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include #include #include #ifndef _WIN32 # include // for access(2) and getdomainname #endif #include #include using namespace std; using namespace libfwbuilder; bool FirewallInstaller::parseManifestLine(const QString &line, QString *local_file_name, QString *remote_file_name, bool *main_script) { // generated IOS and PIX scripts use '!' as a comment which places // manifest marker at offset of 1 char from the beginning of the // line if (line.indexOf(MANIFEST_MARKER) == -1) return false; if (fwbdebug) qDebug("Manifest line: '%s'", line.toAscii().constData()); QString workline = line.split(MANIFEST_MARKER)[1].trimmed(); if (workline.startsWith("*")) { *main_script = true; workline = workline.remove(0, 1).trimmed(); } QString local, remote; int i = 0; for(i=0; itoAscii().constData() << "remote_name:" << remote_file_name->toAscii().constData() << "main_script:" << *main_script; return true; } /* * FirewallInstaller::readManifest reads manifest from the generated * script and applies logic to decide the path and name of all files * that will be copied to the firewall. Manifest format: # files: * local_file_name remote_file_name the '*' is optional and marks the "main" script, that is, the script that should be executed on the firewall to activate policy. The part '# files:' is manifest marker and must be reproduced just so. Parts are separated by one or more spaces. Remote name is optional, if it is missing, it is assumed to be equal to the local name. This provides for backwards compatibility with previous versions where manifest did not include remote name. Manifest can consit of multiple lines to describe multiple files, although only one line can have '*'. Installation process is controlled by several variables that the user can change in the "advanced" dialog for the firewall platform: Tab "Compiler": - output file name - script name on the firewall - for PF and ipfilter additionally .conf file name on the firewall Tab "Installer": - directory on the firewall where script should be installed - command that installer should execute on the firewall These variables have default values if input fields are left blank in the dialog as follows: output file name: the name of the firewall object, plus extension ".fw". For PF two files are generated: .fw and .conf; for ipfilter files .fw, -ipf.conf and -nat.conf are generated. script name on the firewall: the same as the output file name directory on the firewall: "/etc" command that installer executes to activate policy: installer runs script .fw If user enters alternative name in the "script name on the firewall", it is used when generated script is copied to the firewall. There are two input fields in the dialogs for PF and ipf where user can enter alternative name for the .fw script and .conf file. The name can be relative or absolute path. If it is a relative path or just a file name, it is treated as a file name in the directory specified by the "directory on the firewall" input field in the "Installer" tab. If the name is an absolute path, the directory entered in "directory on the firewall..." input field is ignored. If user entered alternative name for the script on the firewall, the command that installer should execute to activate it must be entered as well. If the alternative name was entered as an absolute path, activation command should take this into account and use the same absolute path. The command can start with "sudo " if user account used to copy and activate policy is not root. */ bool FirewallInstaller::readManifest(const QString &script, QMap *all_files) { if (fwbdebug) qDebug("FirewallInstaller::readManifest"); // Read generated config file (cnf->script), find manifest // and schedule copying of all files listed there. QFile cf(script); if (cf.open(QIODevice::ReadOnly )) { QTextStream stream(&cf); QString line; do { line = stream.readLine(); if (line.isNull()) break; QString local_name; QString remote_name; bool main_script = false; if (parseManifestLine(line, &local_name, &remote_name, &main_script)) { QFileInfo loc_file_info(local_name); if (!loc_file_info.isAbsolute()) { QFileInfo cnf_file_info(cnf->script); if (cnf_file_info.isAbsolute()) local_name = cnf_file_info.dir().path() + "/" + local_name; } if (remote_name.isEmpty()) { QFileInfo loc_file_info(local_name); remote_name = cnf->fwdir + "/" + loc_file_info.fileName(); } // This is the manifest line with "*", it marks the main script // we should run. if (main_script) { // Override directory variable if remote file name // is an absolute path. This is used later to // replace %FWDIR% macro // Override fwbscript as well // This is used later to replace %FWSCRIPT% macro // getDestinationDir() returns corrected directory // depending on the user (root/regular) and temp install // flag setting QFileInfo rem_file_info(remote_name); if (rem_file_info.isAbsolute()) { cnf->fwdir = rem_file_info.dir().path(); cnf->remote_script = getDestinationDir(cnf->fwdir) + rem_file_info.fileName(); } else { cnf->remote_script = getDestinationDir(cnf->fwdir) + remote_name; } } (*all_files)[local_name] = remote_name; } } while (!line.isNull()); cf.close(); if (cnf->remote_script.isEmpty()) { // manifest did not include line with '*' cnf->remote_script = getDestinationDir(cnf->fwdir) + cnf->script; } // Now that we have found the main script and know its // location (in case user provided absolute path for the // remote file name variable) we can update remote path for // all files QMap::iterator it; for (it=all_files->begin(); it!=all_files->end(); ++it) { QString local_name = it.key(); QString remote_name = it.value(); QFileInfo rem_file_info(remote_name); if (rem_file_info.isAbsolute()) (*all_files)[local_name] = getDestinationDir(rem_file_info.dir().path()) + rem_file_info.fileName(); else (*all_files)[local_name] = getDestinationDir(cnf->fwdir) + remote_name; } // make sure remote_name has '/' as a separator. If the program // runs on windows, QFileInfo may return path with native // separators '\' cnf->remote_script = QDir::fromNativeSeparators(cnf->remote_script); for (it=all_files->begin(); it!=all_files->end(); ++it) { QString local_name = it.key(); (*all_files)[local_name] = QDir::fromNativeSeparators(it.value()); } return true; } else { QMessageBox::critical( inst_dlg, "Firewall Builder", tr("Generated script file %1 not found.").arg(script), tr("&Continue") ); return false; } } bool FirewallInstaller::packInstallJobsList(Firewall*) { return false; } void FirewallInstaller::packSSHArgs(QStringList &args) { QString ssh = st->getSSHPath(); QStringList ssh_argv; parseCommandLine(ssh, ssh_argv); #ifdef _WIN32 args += ssh_argv; /* * putty ignores protocol and port specified in the session file if * command line option -ssh is given. * * On the other hand,the sign of session usage is an empty user name, * so we can check for that. If user name is empty, then putty will * use current Windows account name to log in to the firewall and this * is unlikely to work anyway. This seems to be a decent workaround. */ if (ssh.contains("plink.exe", Qt::CaseInsensitive)) { args.push_back("-ssh"); args.push_back("-t"); if (cnf->putty_session.isEmpty()) { args.push_back("-load"); args.push_back("fwb_session_with_keepalive"); } if (!cnf->pwd.isEmpty()) { args.push_back("-pw"); args.push_back(cnf->pwd); } } #else args.push_back(argv0.c_str()); args.push_back("-X"); // fwbuilder works as ssh wrapper args += ssh_argv; args.push_back("-o"); args.push_back(QString("ServerAliveInterval=%1").arg(st->getSSHTimeout())); args.push_back("-t"); args.push_back("-t"); #endif if (!cnf->sshArgs.isEmpty()) args += cnf->sshArgs.split(" ", QString::SkipEmptyParts); if (cnf->verbose) args.push_back("-v"); if (!cnf->user.isEmpty()) { args.push_back("-l"); args.push_back(cnf->user); } if (!cnf->putty_session.isEmpty()) { args.push_back(cnf->putty_session); } else { args.push_back(cnf->maddr); } } void FirewallInstaller::packSCPArgs(const QString &local_name, const QString &remote_name, QStringList &args) { if (fwbdebug) qDebug() << "packSCPArgs" << "local_name=" << local_name << "remote_name=" << remote_name; QString file_with_path = getFullPath(local_name); QString scp = st->getSCPPath(); QStringList scp_argv; parseCommandLine(scp, scp_argv); QString mgmt_addr = cnf->maddr; /* * bug #2618686 "built-in installer can not handle ipv6 management * address". If cnf->maddr is ipv6 address, it needs to be placed in * [ ] for scp (otherwise scp interprets ':' as a separator between * host name and port number). * Note that this is only necessary for scp; ssh takes ipv6 addresses * without [ ] just fine. */ try { InetAddr addr(AF_INET6, cnf->maddr.toAscii().constData()); if (fwbdebug) qDebug("SCP will talk to the firewall using address %s ( %s )", cnf->maddr.toAscii().constData(), addr.toString().c_str()); /* * It looks like if cnf->maddr is a host name, then InetAddr * does not fail but just creates address '::'. * InetAddr throws exception if it is given ipv4 address. * Only add [ ] if this is legitimate ipv6 address (not '::') */ if (!addr.isAny()) mgmt_addr = '[' + cnf->maddr + ']'; } catch(FWException &ex) { // Assume cnf->maddr is ipv4 or host name ; } #ifdef _WIN32 args += scp_argv; /* * See #1832. plink.exe and pscp.exe do not try to interpret target * host name as session name if they see "-load session_name" on the * command line. This means if user wants to use session, we can not * load session fwb_session_with_keepalive. */ if (scp.contains("pscp.exe", Qt::CaseInsensitive)) { if (cnf->putty_session.isEmpty()) { args.push_back("-load"); args.push_back("fwb_session_with_keepalive"); } if (!cnf->pwd.isEmpty()) { args.push_back("-pw"); args.push_back(cnf->pwd); } } #else args.push_back(argv0.c_str()); args.push_back("-Y"); // fwbuilder works as scp wrapper args += scp_argv; args.push_back("-o"); // "3" here is the default value of ServerAliveCountMax parameter // This way, overall timeout will be the same for ssh and scp args.push_back(QString("ConnectTimeout=%1").arg(st->getSSHTimeout() * 3)); #endif if (!cnf->scpArgs.isEmpty()) args += cnf->scpArgs.split(" ", QString::SkipEmptyParts); args.push_back("-q"); args.push_back(file_with_path); /* * bug #2618772: "test install" option does not work. To fix, I * put macro for the temp directory in in res/os/host_os.xml XML * elements root/test/copy reg_user/test/copy. That macro * is read and processed by getDestinationDir() * * Also note that pscp.exe supports "-l user" command line arg, * but unix scp does not. Both support user@target format though * and it works with sessions for pscp.exe */ QString user_spec; if (!cnf->user.isEmpty()) user_spec = cnf->user + "@"; QString target; if (!cnf->putty_session.isEmpty()) target = QString("%1%2:%3").arg(user_spec) .arg(cnf->putty_session) .arg(fwcompiler::CompilerDriver::escapeFileName(remote_name)); else target = QString("%1%2:%3").arg(user_spec) .arg(mgmt_addr) .arg(fwcompiler::CompilerDriver::escapeFileName(remote_name)); args.push_back(target); if (fwbdebug) qDebug() << "args=" << args; } /* * take next job from job_list and execute it. * * Note that this slot is called when SSHSession emits signal * sessionFinished. This happens outside of control of the * instDialog. If user clicked Cancel or Finish button (even though * Finish should not be active, but still), runJobs() should not * continue. Check for this condition using instDialog::isFinished() * */ void FirewallInstaller::runJobs() { if (fwbdebug) qDebug("FirewallInstaller::runJobs"); if (inst_dlg->isFinished()) return; if (job_list.size()==0) { if (fwbdebug) qDebug("FirewallInstaller::runJobs: job list is empty"); QTimer::singleShot( 1000, inst_dlg, SLOT(mainLoopInstall())); return; } instJob current_job = job_list.front(); job_list.pop_front(); switch (current_job.job) { case COPY_FILE: copyFile(current_job.argument1, current_job.argument2); break; case EXECUTE_COMMAND: executeCommand(current_job.argument1); break; case ACTIVATE_POLICY: activatePolicy(current_job.argument1, current_job.argument2); break; case RUN_EXTERNAL_SCRIPT: executeExternalInstallScript(current_job.argument1, current_job.argument2); break; } } /* * copyFile starts background process and returns. Process object * emits signal finished() which will be connected to slot * commandFinished(). This slot checks termination status of the process * and if it was successfull, it schedules call to runJobs() */ 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()), true ); } void FirewallInstaller::executeExternalInstallScript(const QString &command, const QString &script_args) { FWObjectDatabase *db = cnf->fwobj->getRoot(); assert(db); QString wdir = getFileDir( mw->getRCS()->getFileName() ); QStringList args; //args.push_back(command.trimmed()); args.push_back("-f"); args.push_back(db->getFileName().c_str()); if (wdir!="") { args.push_back("-d"); args.push_back(wdir); } args += script_args.trimmed().split(" ", QString::SkipEmptyParts); args.push_back(cnf->fwobj->getName().c_str()); if (cnf->verbose) inst_dlg->displayCommand(args); qApp->processEvents(); inst_dlg->setUpProcessToInstall(); if (!inst_dlg->executeCommand(command.trimmed(), args)) QTimer::singleShot( 0, inst_dlg, SLOT(mainLoopInstall())); } void FirewallInstaller::executeCommand(const QString &cmd) { QStringList args; packSSHArgs(args); args.push_back( cmd ); if (cnf->verbose) inst_dlg->displayCommand(args); qApp->processEvents(); QString path = args.at(0); args.pop_front(); inst_dlg->setUpProcessToInstall(); if (!inst_dlg->executeCommand(path, args)) QTimer::singleShot( 0, inst_dlg, SLOT(mainLoopInstall())); } // ************************************************************************ void FirewallInstaller::activatePolicy(const QString&, const QString&) { QTimer::singleShot( 0, this, SLOT(runJobs())); } /* * parameter intermediate: if true, then this session is part of the * set required to complete install on single firewall, such as when * we need to copy several files and then activate policy. If this * parameter is false, the session is final and installer terminates * when it finishes. This only applies to when session finishes * successfully. If session finishes with an error, we always * terminate installer. */ void FirewallInstaller::runSSHSession(SSHSession *s, bool intermediate) { if (fwbdebug) qDebug("FirewallInstaller::runSSHSession()"); session = s; session->setOptions(cnf); session->setFWBPrompt(fwb_prompt); connect(session,SIGNAL(printStdout_sign(const QString&)), inst_dlg, SLOT(addToLog(const QString&))); if (intermediate) connect(session,SIGNAL(sessionFinished_sign()), this, SLOT(runJobs())); else connect(session,SIGNAL(sessionFinished_sign()), inst_dlg, SLOT(installerSuccess())); connect(session,SIGNAL(sessionFatalError_sign()), inst_dlg, SLOT(installerError())); connect(session,SIGNAL(updateProgressBar_sign(int,bool)), inst_dlg, SLOT(updateProgressBar(int,bool))); session->startSession(); } QString FirewallInstaller::getFullPath(const QString &file ) { if (QDir::isRelativePath(file)) return cnf->wdir + "/" + file; else return file; } /* * This method builds and returns activation command * This method is used for all firewall platforms but PIX */ QString FirewallInstaller::getActivationCmd() { if (!cnf->activationCmd.isEmpty()) { return cnf->activationCmd; } FWOptions *fwopt = cnf->fwobj->getOptionsObject(); QString configlet_name = "installer_commands_"; if (cnf->user=="root") configlet_name += "root"; else configlet_name += "reg_user"; string host_os = cnf->fwobj->getStr("host_OS"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); // installer configlets should be different for each OS, but if // some OS can use the same script, it will be placed in the file // under os_family name. For example: // for linksys/sveasoft configlet is in src/res/configlets/sveasoft // but since linux24 and openwrt can use the same script, it is // located in src/res/configlets/linux24 (openwrt.xml file defines // family as "linux24") Configlet configlet(host_os, os_family, configlet_name); configlet.removeComments(); configlet.collapseEmptyStrings(true); // test run and rollback were deprecated in 4.2.0. On Linux, BSD // and PIX rollback was implemented by rebooting firewall which is // too heavy-handed and it did not work on BSD at all. configlet.setVariable("test", false); configlet.setVariable("run", true); configlet.setVariable("with_rollback", false); configlet.setVariable("no_rollback", true); configlet.setVariable("firewall_name", QString::fromUtf8(cnf->fwobj->getName().c_str())); configlet.setVariable("with_compression", cnf->compressScript); configlet.setVariable("no_compression", ! cnf->compressScript); // On FreeBSD where we can generate either shell script or rc.conf // file, installation commands differ. // // TODO: find more generic way to do this so that GUI installer does not // have to be aware of the differences in generated file format. configlet.setVariable("rc_conf_format", fwopt->getBool("generate_rc_conf_file")); configlet.setVariable("shell_script_format", ! fwopt->getBool("generate_rc_conf_file")); replaceMacrosInCommand(&configlet); return configlet.expand().trimmed(); } void FirewallInstaller::replaceMacrosInCommand(Configlet *conf) { /* replace macros in activation commands: * * {{$fwbpromp}} -- "magic" prompt that installer uses to detect when it is logged in * {{$fwdir}} -- directory on the firewall * {{$fwscript}} -- script name on the firewall * {{$rbtimeout}} -- rollbak timeout */ /* * TODO: it does not make sense to split remote_script and then * reassemble it again from the file name and cnf.fwdir. We should set * variable $remote_script and use it in the configlets instead, but * keep $fwbscript and $fwdir for backwards compatibility */ /* * remote_script is a full path, which in case of Cisco can be * something like "flash:file.fw". This means we have a problem with * QFileInfo that interprets it as path:filename on Window or just * file name with no directory path on Unix. As the result, fwbscript * becomes just "file.fw" on Windows and stays "flash:file.fw" on * Unix. */ /* * TODO: there must be a better place to fill cnd.fwscript than * this. All I need to do is fill it before calling summary() and * before launching installer that uses it in * FirewallInstaller::replaceMacrosInCommand() */ QString fwscript = fwcompiler::CompilerDriver::escapeFileName( QFileInfo(cnf->remote_script).fileName()); if (fwscript.indexOf(":")!=-1) fwscript = fwscript.section(':', 1, 1); cnf->fwscript = fwscript; if (fwbdebug) { qDebug() << "Macro substitutions:"; qDebug() << " $fwdir=" << cnf->fwdir; qDebug() << " cnf->script=" << cnf->script; qDebug() << " cnf->remote_script=" << cnf->remote_script; qDebug() << " $fwscript=" << cnf->fwscript; qDebug() << " $firewall_name=" << QString::fromUtf8( cnf->fwobj->getName().c_str()); } conf->setVariable("fwbprompt", fwb_prompt); conf->setVariable("fwdir", cnf->fwdir); conf->setVariable("fwscript", cnf->fwscript); conf->setVariable("firewall_name", QString::fromUtf8(cnf->fwobj->getName().c_str())); } /* * Returned directory path always ends with separator ("/") */ QString FirewallInstaller::getDestinationDir(const QString &fwdir) { QString dir = fwdir; if (fwbdebug) qDebug() << "FirewallInstaller::getDestinationDir: " << "destination directory=" << dir << "cnf->fwdir=" << cnf->fwdir; if (!dir.endsWith(QDir::separator())) return dir + "/"; return dir; } QString FirewallInstaller::getGeneratedFileFullPath(Firewall *fw) { /* bug #1617501: "Install fails after compile". The "output file" * setting that user enters in the "Compiler" tab of fw advanced * dialog can be either local or absolute path. */ QString generated_file = getGeneratedFileName(fw); QFileInfo gen_file_info(generated_file); if (!gen_file_info.isAbsolute()) { QFileInfo fwb_file_info = QFileInfo(mw->getRCS()->getFileName()); generated_file = fwb_file_info.dir().path() + "/" + generated_file; } return QDir::toNativeSeparators(generated_file); } QString FirewallInstaller::getGeneratedFileName(Firewall *fw) { FWOptions *fwopt = fw->getOptionsObject(); QString generated_file; QString ofname = QString::fromUtf8(fwopt->getStr("output_file").c_str()).trimmed(); if (!ofname.isEmpty()) { generated_file = ofname; } else generated_file = QString::fromUtf8(fw->getName().c_str()) + ".fw"; return generated_file; } void FirewallInstaller::terminate() { if (session != NULL) { session->terminate(); } } fwbuilder-5.1.0.3599/src/libgui/conntrackOptionsDialog.h0000644000175000017500000000275311733011756023676 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CONNTRACKOPTIONSDIALOG_H_ #define __CONNTRACKOPTIONSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class conntrackOptionsDialog : public QDialog { Q_OBJECT public: conntrackOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~conntrackOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::conntrackOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); virtual void toggleUseUnicast(); }; #endif // __CONNTRACKOPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/TextEditWidget.h0000644000175000017500000000265611733011756022120 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TEXTEDITWIDGET_H__ #define __TEXTEDITWIDGET_H__ #include class QFocusEvent; class QKeyEvent; class TextEditWidget : public QTextEdit { Q_OBJECT; bool modified; bool showingDefault; bool hasFocus; QString defaultText; signals: void textChanged(); public slots: void dirty(bool); public: TextEditWidget(QWidget *parent); virtual void focusInEvent(QFocusEvent *event); virtual void focusOutEvent(QFocusEvent* event); void setTextDefault(const QString &text, const QString &theDefault); QString getText(); }; #endif fwbuilder-5.1.0.3599/src/libgui/IPServiceDialog.h0000644000175000017500000000276311733011756022172 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPSERVICEDIALOG_H_ #define __IPSERVICEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class IPServiceDialog : public BaseObjectDialog { Q_OBJECT; Ui::IPServiceDialog_q *m_dialog; void setCodeLabel(); public: IPServiceDialog(QWidget *parent); ~IPServiceDialog(); public slots: virtual void changed(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void anyOptionsStateChanged(); }; #endif // IPSERVICEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FindObjectWidget.h0000644000175000017500000000542611733011756022373 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FINDOBJECTWIDGET_H_ #define __FINDOBJECTWIDGET_H_ #include "config.h" #include #include "ProjectPanel.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" class QRegExp; class ObjectDescriptor; class QWidget; class FindObjectWidget : public QWidget { Q_OBJECT; private: QString lastAttrSearch; libfwbuilder::FWObject *lastFound; libfwbuilder::FWObject::tree_iterator treeSeeker; std::list found_objects; std::list::iterator found_objects_iter; libfwbuilder::Firewall* selectedFirewall; ProjectPanel *project_panel; void _findAll(); void _replaceCurrent(); bool matchName(const QString &name); bool matchID(int id); bool matchAttr(libfwbuilder::FWObject* obj); bool validateReplaceObject(); bool inSelectedFirewall( libfwbuilder::RuleElement* r); virtual void keyPressEvent( QKeyEvent* ev ); public: Ui::findObjectWidget_q *m_widget; FindObjectWidget(QWidget*p, ProjectPanel *pp, const char * n = 0, Qt::WindowFlags f = 0); ~FindObjectWidget() { delete m_widget; }; void findObject (libfwbuilder::FWObject *o); void attachToProjectWindow(ProjectPanel *pp) { project_panel = pp; } public slots: virtual void enableAll(); virtual void disableAll(); virtual void objectInserted(); virtual void find(); virtual void findNext(); virtual void reset(); virtual void findAttrChanged(const QString&); virtual void findPrev(); virtual void replaceNext(); virtual void replace(); virtual void replaceAll(); virtual void replaceEnable(); virtual void replaceDisable(); void showObject(libfwbuilder::FWObject* o); void init(); void clear(); void firewallOpened(libfwbuilder::Firewall *f); void scopeChanged(); void objectDeleted(); signals: void close(); }; #endif fwbuilder-5.1.0.3599/src/libgui/userdialog_q.ui0000644000175000017500000001134511733011756022061 0ustar sylvestresylvestre UserDialog_q true 0 0 859 272 0 0 User 12 0 0 QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 User id: false 0 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 5 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name userid
fwbuilder-5.1.0.3599/src/libgui/ObjectIconView.cpp0000644000175000017500000001403211733011756022416 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "FWBTree.h" #include "ProjectPanel.h" #include "ObjectIconView.h" #include "ObjectIconViewItem.h" #include "FWObjectDrag.h" #include "FWBSettings.h" #include "FWObjectPropertiesFactory.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Resources.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; /**************************************************************************** * * class ObjectIconView * ****************************************************************************/ ObjectIconView::ObjectIconView(QWidget* parent, const char*, Qt::WindowFlags) : QListWidget(parent) { db = NULL; //setWindowFlags(f); setDragEnabled(true); setViewMode(QListView::IconMode); setSpacing(10); setAcceptDrops(true); //startingDrag = false; } bool ObjectIconView::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = (QHelpEvent*) event; QPoint pos = he->pos(); if (st->getObjTooltips()) { int cx = pos.x(), cy = pos.y(); //viewportToContents(pos.x(),pos.y(),cx,cy); FWObject *obj = NULL; QRect cr; QListWidgetItem *itm = itemAt( QPoint(cx,cy) ); QModelIndex ind = indexAt( QPoint(cx,cy) ); if (itm==NULL) return false; int obj_id = itm->data(Qt::UserRole).toInt(); obj = db->findInIndex(obj_id); if (obj==NULL) return false; cr = rectForIndex(ind); cr = QRect( cr.left() - horizontalOffset(), cr.top() - verticalOffset(), cr.width(), cr.height()); QRect global = QRect( viewport()->mapToGlobal(cr.topLeft()), viewport()->mapToGlobal(cr.bottomRight())); QToolTip::showText(mapToGlobal( he->pos() ), FWObjectPropertiesFactory::getObjectPropertiesDetailed( obj, true, true), this, global); } return true; } return QListWidget::event(event); } QDrag* ObjectIconView::dragObject() { QListWidgetItem *ivi = currentItem(); // currentItem returns NULL if the list is empty if (ivi==NULL) return NULL; int obj_id = ivi->data(Qt::UserRole).toInt(); FWObject *obj = db->findInIndex(obj_id); QString icn = Resources::global_res->getObjResourceStr(obj, "icon-ref").c_str(); list dragobj; dragobj.push_back(obj); FWObjectDrag *drag = new FWObjectDrag(dragobj, this); //QPixmap pm = QPixmap::fromMimeSource( icn_filename ); QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } drag->setPixmap( pm ); drag->setHotSpot(QPoint( pm.rect().width() / 2, pm.rect().height() / 2 )); return drag; } void ObjectIconView::dragEnterEvent( QDragEnterEvent *ev) { if (fwbdebug) qDebug("ObjectIconView::dragEnterEvent"); // ev->setAccepted( ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); QWidget *fromWidget = ev->source(); // The source of DnD object must be the same instance of fwbuilder if (!fromWidget) { ev->setAccepted(false); return; } if (!ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE)) { ev->setAccepted(false); return; } list dragol; if (!FWObjectDrag::decode(ev, dragol)) ev->setAccepted(false); for (list::iterator i=dragol.begin();i!=dragol.end(); ++i) { FWObject *dragobj = *i; assert(dragobj!=NULL); if (FWBTree().isSystem(dragobj)) { // can not drop system folder anywhere ev->setAccepted(false); return; } // see #1976 do not allow pasting object that has been deleted if (dragobj->getLibrary()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) { ev->setAccepted(false); return; } } ev->setAccepted(true); } void ObjectIconView::dragMoveEvent( QDragMoveEvent *ev) { if (fwbdebug) qDebug("ObjectIconView::dragMoveEvent"); ev->setAccepted( ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); } void ObjectIconView::dropEvent(QDropEvent *ev) { if (fwbdebug) qDebug("ObjectIconView::dropEvent"); // QListWidget::dropEvent(ev); emit dropped(ev); } void ObjectIconView::keyPressEvent( QKeyEvent* ev ) { if (ev->key()==Qt::Key_Delete) { emit delObject_sign(); } QListWidget::keyPressEvent(ev); } void ObjectIconView::mousePressEvent ( QMouseEvent * event ) { if (fwbdebug) qDebug("ObjectIconView::mousePressEvent"); startingDrag = true; QListWidget::mousePressEvent(event); } void ObjectIconView::mouseMoveEvent ( QMouseEvent * event ) { if (startingDrag) { startingDrag = false; QDrag *dr = dragObject(); if (dr) dr->start(); } QListWidget::mouseMoveEvent(event); } fwbuilder-5.1.0.3599/src/libgui/TutorialDialog.ui0000644000175000017500000001122311733011756022321 0ustar sylvestresylvestre TutorialDialog_q 0 0 720 632 Tutorial QLayout::SetMinimumSize Qt::Horizontal 40 20 0 0 100 0 Reset false 0 0 100 0 Previous false 0 0 100 0 Next true 100 0 Close false reset clicked() TutorialDialog_q reset() 340 619 241 271 prev clicked() TutorialDialog_q previous() 242 619 241 271 next clicked() TutorialDialog_q next() 438 619 241 271 pushButton clicked() TutorialDialog_q reject() 507 603 551 609 previous() next() reset() fwbuilder-5.1.0.3599/src/libgui/simpleinteditor_q.ui0000644000175000017500000000667211733011756023145 0ustar sylvestresylvestre SimpleIntEditor_q true 0 0 248 96 Script Editor 11 11 11 11 0 0 QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Horizontal QSizePolicy::Expanding 110 20 Cancel true QAbstractSpinBox::PlusMinus 255 1 OK true spin_box ok_button cancel_button ok_button clicked() SimpleIntEditor_q accept() 20 20 20 20 cancel_button clicked() SimpleIntEditor_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/interfacedialog_q.ui0000644000175000017500000003514511733011756023047 0ustar sylvestresylvestre InterfaceDialog_q true 0 0 1017 344 0 0 Interface 12 0 0 QFrame::Box QFrame::Sunken 12 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken 0 0 Name: false 1 0 200 23 0 0 Label: false 0 0 200 23 0 0 0 0 Security level: false 0 0 0 0 <p>Each interface of the firewall must have security level associated with it.<br>Security level can be any number between 0 and 100, 0 being least secure and 100 being most secure levels. Interface with security level 0 ususally serves Internet connection.</p> <p>Each interface of the firewall must have security level associated with it.<br> Security level can be any number between 0 and 100, 0 being least secure and 100 being most secure levels. Interface with security level 0 ususally serves Internet connection.</p> QAbstractSpinBox::PlusMinus 100 0 0 Network zone: false 0 0 0 26 <p>Network zone consists of hosts and networks that can be reached through this interface of the firewall. Subnet to which this interface is directly attached must be part of its network zone. Other subnets reachable by means of routing should alse be added to the network zone. <br> If network zone for this interface consists of only one subnet, you can simply choose that network's object in the pull-down below. If your network zone should include multiple subnets, you need to create an Object Group, then put all hosts and networks which are going to be part of the network zone into that group and finally choose this group in the pull-down below.</p> <p>Network zone consists of hosts and networks that can be reached through this interface of the firewall. Subnet to which this interface is directly attached must be part of its network zone. Other subnets reachable by means of routing should alse be added to the network zone. <br> If network zone for this interface consists of only one subnet, you can simply choose that network's object in the pull-down below. If your network zone should include multiple subnets, you need to create an Object Group, then put all hosts and networks which are going to be part of the network zone into that group and finally choose this group in the pull-down below.</p> Qt::Vertical 20 70 0 0 250 0 false <p>Check if this interface is used for management (SNMP queries, remote policy install etc.)<p> Management interface Skip this interface while assigning policy rules Unprotected interface Dedicated failover interface Static IP address Address is assigned dynamically Unnumbered interface 0 0 Bridge Port Interface Qt::AlignCenter Advanced Interface Settings ... Qt::Vertical 20 40 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name label seclevel management regular dynamic unnumbered advancedconfig clicked() InterfaceDialog_q openIfaceDialog() 428 232 428 133 changed()
fwbuilder-5.1.0.3599/src/libgui/pixosIfaceOptsDialog.h0000644000175000017500000000321511733011756023272 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id: pixosIfaceOptsDialog.h 1487 2009-09-23 17:00:48Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PIXOSIFACEOPTSDIALOG_H_ #define __PIXOSIFACEOPTSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class pixosIfaceOptsDialog : public QDialog { Q_OBJECT public: pixosIfaceOptsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~pixosIfaceOptsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::pixosIfaceOptsDialog_q *m_dialog; bool cluster_interface; /** validate user input for different interface types */ bool validate(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); void typeChanged(const QString&); }; #endif // __PIXOSIFACEOPTSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/AttachedNetworksDialog.h0000644000175000017500000000317311733011756023607 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ATTACHEDNETWORKSDIALOG_H_ #define __ATTACHEDNETWORKSDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; namespace libfwbuilder { class InetAddr; }; class AttachedNetworksDialog : public BaseObjectDialog { Q_OBJECT; Ui::AttachedNetworksDialog_q *m_dialog; void addAddressToList(const libfwbuilder::InetAddr *ip_addr, const libfwbuilder::InetAddr *ip_netm); public: AttachedNetworksDialog(QWidget *parent); ~AttachedNetworksDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // ATTACHEDNETWORKSDIALOG_H fwbuilder-5.1.0.3599/src/libgui/openbsdAdvancedDialog.cpp0000644000175000017500000000771011733011756023751 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "openbsdAdvancedDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; openbsdAdvancedDialog::~openbsdAdvancedDialog() { delete m_dialog; } openbsdAdvancedDialog::openbsdAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::openbsdAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption( m_dialog->openbsd_ip_sourceroute, fwopt, "openbsd_ip_sourceroute", threeStateMapping); data.registerOption( m_dialog->openbsd_ip_redirect, fwopt, "openbsd_ip_redirect", threeStateMapping); data.registerOption( m_dialog->openbsd_ip_directed_broadcast, fwopt, "openbsd_ip_directed_broadcast", threeStateMapping); data.registerOption( m_dialog->openbsd_ip_forward, fwopt, "openbsd_ip_forward", threeStateMapping); data.registerOption( m_dialog->openbsd_ipv6_forward, fwopt, "openbsd_ipv6_forward", threeStateMapping); data.registerOption( m_dialog->openbsd_path_pfctl, fwopt, "openbsd_path_pfctl"); data.registerOption( m_dialog->openbsd_path_sysctl, fwopt, "openbsd_path_sysctl"); data.registerOption(m_dialog->openbsd_data_dir, fwopt, "data_dir"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void openbsdAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void openbsdAdvancedDialog::reject() { QDialog::reject(); } fwbuilder-5.1.0.3599/src/libgui/WorkflowIcons.cpp0000644000175000017500000000533111733011756022354 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id: WorkflowIcons.cppТЎ 2786 2010-04-01 14:05:36Z a2k $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "ClickableLabel.h" #include "FWWindow.h" #include "ObjectManipulator.h" #include "ProjectPanel.h" #include "WorkflowIcons.h" #include "ui_WorkflowIcons.h" #include #include #include #include WorkflowIcons::WorkflowIcons(QWidget *parent) : QWidget(parent), ui(new Ui::WorkflowIcons_q) { ui->setupUi(this); } void WorkflowIcons::setUpSignals(QWidget *panel) { ObjectManipulator *om = panel->findChild(); connect(ui->newFirewall, SIGNAL(clicked()), om, SLOT(newFirewallSlot())); // global variable mw is null when this is running QObject *mainWindow = dynamic_cast(panel)->getWindow(); QAction *import = mainWindow->findChild("policyImportAction"); connect(ui->importConfig, SIGNAL(clicked()), import, SLOT(trigger())); connect(om, SIGNAL(libraryAccessChanged(bool)), this, SLOT(libraryAccessChanged(bool))); connect(ui->action_getting_started, SIGNAL(clicked()), this, SLOT(openTutorial())); } WorkflowIcons::~WorkflowIcons() { delete ui; } void WorkflowIcons::changeEvent(QEvent *e) { QWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void WorkflowIcons::libraryAccessChanged(bool writable) { ui->newFirewall->setEnabled(writable); ui->importConfig->setEnabled(writable); } void WorkflowIcons::openTutorial() { // if we want to show tutorial included with the package: // mw->showTutorial("getting_started"); // if we want to open the page with video tutorials in the standard browser QDesktopServices::openUrl(QUrl("http://www.fwbuilder.org/4.0/videos.html", QUrl::StrictMode)); } fwbuilder-5.1.0.3599/src/libgui/Icons/0000755000175000017500000000000011733011756020113 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Icons/self-neg_25.png0000644000175000017500000000230611733011756022630 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<hIDATxкДVmL[e~олкBa|И†Э€d†pЮЁ бПd,FЂ1™A ћ1Њ„Є Q—LЇdDP‚Ÿ‹ЩцŒ†ьЈ™ћ1AдM@Ђ€ƒ‚д"J)…іzЮЅe@iMH<Щ“лћОчœч=_ї­eџЗЈЗcTkягу !›}ш$H’xVР'„EB Сђк€М=’‚– кЃ0ƒJ@Ї‚№€>W@O{Aˆэ’ШЛuBѕ—WЦС ‘ ЁPtjНZ‚9Y N+Ё{вГ§t‘h’ДLТђHZ”%./чJЂЌ !Ж_ЊЧщнzЁбЊюЎIJl Ђ`˜DXg#ИЛШ0>}ж—ЙЧ^<р#ўЁW‰#” Ь-Ы>“AhSb8џЎeЦТФedЃћR3ќЮqЌХ’?€ѕЭЊЂhъ~ …ЄЅ8Ы{ј™ Пw\JЬЮЦœјю­ шU\PРOГ„ьV7"Y•‚™ў~ЈsгаѓiЦ†~Х=тcдJXWЂŒЖЛGj>Tr2fЉ{HКuюЎ?ŽXЄрPхЅЈv/`_”ЃЧScpђЭf…€ѕXпл=„Ѓ/МŒ™fмkдРHJТфЕ”1IЙЏk§Ћљєћ;Vтayу<ЕO‹ƒЩЋЅ{№%ff Ъ>ыБАншW§xшщrхф|' Ьэi/ОЗЛзHь†дд§IЎ—•aЬ‹ФВ р?Qл„ЉiƒВ" лЯ9ьИ:<‡Ю‘9ќь№Р>яƒлч_+|ТЭЯš]bt=55aнTик пZ—РЗЅЅaћygЮ@›™€??|Ю0хёу1S,ђj‡=к>+$ъЌћпЋ†.3^1и,ьxКэzDSNpхUь дMЋ ЬUЪѓnMr‡3pRCDЦ-‰~ЛxqK‚єœD8?> й3Їд#@нБBЧя™\Р7wмш д…HFxSуuсVS5вВтё№йГQ’їїš№Еэкј|иƒ+ПЛ12ЗŒerцXєУч—§фіЧаФџР$<8ољYLЖZ‘]§ІŠ‹1кжFАжеїgр]ыs№y”юYсС%\ тЦыђlžјЫGTђА;€Œx ђЋрžр†Х1’› ІcO^2юL}ЋГUDшвКYduЯз#рЃЌ':pтD3п_4нPшИъiіOЎlI`** [c=Фrњicћh$ЊККК8zОнgГ•wUU…)фгЇƒNнЎ5їwvnияш­чэЪЯOтn“TєжзŸъЖZЗ$ШБX8%Ѕьˆ†бЛЦ`ШлUPрт#ЅЫф‹FPМГ+љз7Kаољ•e3ЁЉЫj•[4НчЯЫМFаscЌП7ё~H—э‚КцMКk§HgХžкZЙЏЁ!С"жc§ nz$†XїПk/і šџЃ-ЕAн{‚КіhнѕЏзKBмњЏЮIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/protect_net_and_dmz.png0000644000175000017500000000347111733011756024650 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоgAMAБ ќabKGDџџџ НЇ“ pHYs  вн~ќtIMEб&%“ЬЖIDATxœэ›MoЧЧфŠ/тK$ОФЊhЂkФRР`“К€OQОЗ_ 5 јdh^|Rњ фЈC~€"Ÿм Ш-l@тЪё›E|].wwvfrXŠЂ,Љвr%Ќ›№ьaggfŸљЯѓ<3Г” Zє№ŠŒx”/˜ ЕQ3 jЂf*@дDЭT€Ј ˆš™Ј 8њ№рцЭ›ѕZ­6КЯd2sJЉњƒ~іE!Р<а/ИwяоВaЃћ+WЎ|jл6wяорў§ћ-­ѕМчyxžGЙ\І\.ЃЕF)€жўŽ9‹№фЩ“s16Д…bё‹П|ўљJ.—•5 Ње*Хb‘xNœ–––///џvgg‡Ц/Џгщ6шѕк8ЎякнсŒ‡‰{ИИСCxј№сктт"FƒWЏ^R(Pвшqqo9^рИќЖЩЙ& Ў*• RJff|gЊеjl=п:їžT˜Уe.hмяc_Рю8Œэd2й^\\фЭыmьЁы^Кt‰­-?/ŒЧ}чŠћqB-ƒнnwР‚bЉЬіі6щt)њ‡тОkЙI1DмЇ”lmmЌЉPX–еюѕz8ЖЭхЪeЖЗЗIЅRЧ<їŽ˜<юЧљйС“~П!BG7ёgЄЙJcЇŸ§[Ћ-П]h вHyU•…=z§йSГіл\Лњ‚ЭojMкXпgт:Ј‹цяњkW_Аєg+Wџф“рT€Ј 8ošЋњ‰ъмЖТ™YУ8ќХ"™”’‚|vЈ/#.'Z&ИџчВ33ЉыŸ\п˜wнDУ \зПЦqнФp<ъhѕъ6{­Йc;яtѓ'ŠV*tNltЙ… (ос3€ц*Ы{­ЙЏ_я”їсˆ“ДЫхЌлUО‡јбх€ Lˆк€ѓТ0дDч„@9 ЙЪж ЕВŸlЌ$—ГЈ~-Є‚ЪТ^рvF\R*tH%=fgm CЧ§Zаў'С—o.ЖС†ЁШЬкЧж+КфГж‰ћЄrПm‡^?sdU…иџє5Є0‡і$“bЙTш<$€сў>@ЦO<фГœфф™~Џѕ^рѓF>gQ*tЕљбф€I™ ЕQЉЗОмрж—“}Ш8/'СътwgкsЇУ\ЛњтдКoзЩЄэ3ПgœсaшџŠщEЭT€Ј ˆšЉQ5SЂ6 jІDm@дќ†OћЪЋKсIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/reject_16.png0000644000175000017500000000171611733011756022410 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<pIDATxкT“]h[eЧџяЧ9ЩЩщYš,э‰kЗlУ­йКQЕж Cб+EwсP72Хљ"(;ТQP+ QМ̘q+М…l“lжІUЛT3ЛЖINѓqr>^Ÿ6м/чц}~яџџЮУ”Rј_Б‹Я9 MѓT0ШЗUГ uхo=f\Ж††І7уп[nr?™щЪf?б“ЩсћzPЋ"\[ м&XmЗMлчь^њ*Кkwѕ& ?і\Ц8MЇУfNЙŒЙйK№к. .’:RB€Р*„ДК~ВЧ'>жwfkќ,гИ‘Щ|flщDAˆОžSЃуИћЭ“сЦУ‡Ћ­xМ"˜ЇЇvoхдфAb—ŽНx(>2ќЅаuЁмB:ŠЄз”_м=~| ‚…A€етBkyђУEН\к!jkн‰gИŒ[GЩŸpЎ•Q[Ђ|š-РuaULсЗŠdб'6nП=КэфлnЅ;QBшЊДx€s†lрд0›?™+ѓaUљ1RСШПY*m;ёњbрyыIk–•э=јtSaТиœ+• ЁчadьЯОђjН+Vdэ8Ѕћуїэ…з^.ЏУшQМб€|hё }'_ћ;оЄ& Ѕ„ˆF!щ5Б!Nr“рН6D ј9к‹'ићŸRTхЪѓН1 5)Щ9Ђiф]X5іBЄzZдќ эФSц[ЖёF-ѕ›їk‚ЂЄG…imнqЦ“ЉO$g˜aœf“_LбЕ›Mџ 0Й‰тЉh“EIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-udp_25.png0000644000175000017500000000362411733011756023362 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<6IDATxк”U lзўfі˜=Н^kЏЯ]ЏиФ& ŽН"Ѕ Š”І JЩ”6…(Ns%НЄ6J”ЃQsЈU€VЅЅ %B…л` 6ыЏН^яzЯYЯѓњЯnжЉЊк'Н™7яНџџоџ§пћ‡cŒНп;в§”EW‡еЙЭЈ3ІЇ.юЯ‡pgэš?^і]кЁŒѓ­ЙbŒZгыЧѕчїх[­еђћц‡„ш“)sв?шE ЬєЌš}яНu,ŸNЅSНЪX™SZ~œяЛ‹YЯ№1&ЅЄџiэѓ ŸБя№“к ІЎјЏ Љ@ЅЂbФœЪЄдЪX™Sš2v–етх^Сгk†8 уЇŸ>ŽŒœqё–н—_Т‡_џfCСгdjЪGЈЮ>єДY$гI­,ЫМJGп–Ёљ:{-6-yx2"FІbrxUзРŸ12wЕLБбаОзПŠP<:ьљ[aпt/J-ЅЭdZD=Д"˜9Z эЗчашs`‚FtнyGiэ*e-š бxѓфЏ‘B…ОЬм  КЦШDwK$Z3[p–ulP€ѓ Й7ЯёВХhzсTЙ(ћоќB~іА;ZwсГЏєЩќ- BAЮёw ь;›цЕjmШ… ЕЈBQh- qЭЎ7X—сьхўSЛїО№Wњ о вНІІУ§Э\7FЙ Ю€8сЩœGSe3І‚^”)дЬЈGы#ЉP§Сй}(*Д Й№‰Ђ‡е67^кѓќ›Я <з{цк7уфѓѕиЭ ћ69u_HірљЋ›С)'J69^Щ4Ўа5šРOзб FЂxЖю-x“S”G‡№mюкOя_еЦтяP@2љ{‚zpŠŽуѓёŽХ?ylX<‡h:„ыFЄGgƒбрq}cbчД4К@YGсFјЦНL „ТЫИЦ)ZkЊ‡њ№oсЧ ю_AŠ`іzŸpn<%­kЯ8ѕЙw‘іяІn;кџЯ~ џsђyљъЯF’чђЙhаТ2)ЃїШ]Щфvq"LŽхRиX!Lп ЁL$–Єx" J|хвнКОСЄlЫ(эОз?44W•о6ь›5E…ћџt=hˆXtв#—ўUЅ„aTєёїЭOЙWъT]†ЖsКРdп5ФgЧРfF`§а*W;8ŽфМDїNNй*ѕfAК =0ˆWj­шМ6 oZ†k&ЦрР•иѕ•мЫ_>СѕЁГШ‰•EлNDІп9 іeР{№_ЇlH€žфŸCz>~6m(й окЬŠ(]яТіє''рК2 DNЩœ“9Џј2їшЁлЋ—ЗcЭv'Д0OЄюНаD&‘ДVAП”„17™Tz œ>=‘жXRj †Ш<:[ь(ёіžЪ`.!ЃЩЎOХС`тI‚r­мКЃwЌ$ЮE`№ф#oƒЧ'yŠь€8Gа…K’rymФ'ЉЬЅ0Еј– М{ф1<^Wс.мwеР_lт˜žŠc,IѕKšS•8ъsЊЬ$ф Јд*№FcЬАzKњС_N*бŽ4ž†,†„ДпѓVцЊЙ‰'о‡Ž“В'ТР йo^ЉMоЛD“d3Uђ…БTБ№ШЧѓ2b~ ЁЮ–ѕтvYнtŸц ”l Б 8ŽWJyЛtјcžјLІiцю­ЃƒЈaРЉрeU@K5I‹dcжА$ЂBŠіЅQŠvPAŠњ‘œ*‘Iч й Wƒ+qЭTЭ5jїFЛЧ…oœlˆЪ$не$Ъbd№€zй№.ёSVXЗепЎE˜’›&Яi*ф4.ЌЪхAєбЩЩXљSЉl&r‚ШvЕНЦљйk??”ё%Р*m ‹ЊЊJjJHЁФЪ\8энZ=іУЂ–ѕZЬsЮтtulєЛЈ[DЁ“d TpK•?…шBІ“ўŒ$ўˆЗЙкљтђwЙ+t)к~Ћxr­љфКFV§Х%рsЛ §zж(zЅю%ЩPхкŠё> Т•Ћ}RKхЪqŠ’™"*|H}_"SоИЯpOеі[J§Ж;Ось<ссЖмЁнЊЧs}ЃјŠфнмXЦwR!KЂЋsTађkyщюV8“х@&5Х(GJj иBЅп†Ttz†ЪQVќ/”•џкŽнŸ}ЅŒ,V/^о‹ъ%6D)’3ЄЊYЪ‹Ћ%ƒЪ<§`QШ™д•ХўмЕ“ ‘ќЏwЖ!sƒєя-РФˆ)ŠFkG(и‰ШБЛHaы9iHU~л‹XЪ&ѓvџW$йv>iЧ|dќžXь; 3‚VЫ3йЕsR)’t‰V&o6џЗЉ6GA 4фIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/options_64.png0000644000175000017500000001001711733011756022624 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<БIDATxкф[kŒUџsfюо{Злнэ>ћмВЫЖ–ВнZњД€€bb!тќBє“Š&$~б` "Ф5Q>€ZEƒ(№y–@ЖДЅ-ЅКнvлн{яЯ9sЮЬцЮюонйDЃГ{2чЮыЮяџ~œЫЄ”Hooошеќn/ !С иьŸ3ќhЕюnџХлћŠ ЗW9ŠŠIKk@‡Ь›у7žђq=WнhіТŸЦ‹а$”Е ШъддМ шЯRНaЕЉŽ…Ч+ёљ žWsёgЉчšсмHc`Ўyhф4ю9q ‹ЏЋЁќdŠEєЖ{h-qћvЬ<пMуM}аЂRрс^m#ЛЯŽL?ЌЂ^ЌZUиk`Ь~YUЭkъEkzЏA`HUэe`ˆ`Ž+ соззіx6з:№zЏ№§‘“xцќ1Ќкрј{ уcF…"ZY(LAќ‚šŒХD0sъ‰ž—а$f/МдЊž€ѓ2И№~ЗўЁ5вм.Ё8-™zХiІЩ№…ЄОNџ;`5uцкЗ€54'У;jŠ(З<‰П­У9зZрPy•СЋh, Ѕ@ТЋYzؘћŒч–ъ=Q.ц €з цъ9%УqV=ЋŽж0Ё$тР™ œšЈ(&ЈQ™0Ђ(ЕĘыЙ>І8dЮ[еp{sоЊƒQE  %?ЦіmЎЂџк˜Ые1^+Ћ7- Љ$;HqЈ€›{ŠРОфC67х €_4ЂЪYAэЯ‚њ•p№lе€—Ќ• T`Рж,афѕнJ?cgАKеpžnњ2_*+Ѕ2GS'Ojb0Њ,п\Z‹эЭГ'гbяеИЯ•40cN!Щ—п|w|­ўr~Пžы{єž)q4Ÿ9ёxЎїњѓ§Oм]ЛО‡ўјX”ў›бФc‘—,&XL„‚r-ŠѓкЪГ'œЅVпЩДQ5ћй9b†ьћžxх мўш0ќЭl№…љР˜b(+0ˆЂ€ЇšуИ$œЇЃ `•”јЫy9lьѓДQб`‚"Ь™Ÿ?ј>ОігЏcХW*hjЯОІЙWт(—Wя( MЈ”ёKвбЄ †ol@ їГ&€5F csОІьУ-?Й[Gа68yрй: ёЖr?Ч*ŠZхХ^ђz№zh#ш)IёV(і…ŽJЄ1 ‘ХЏN"›џдˆCд &ˆŽш!(јuC‹ўЗ~y+њО8agnў‰cє%ŽЫЋ†[|Ќщ(bЈН€^ AФY’€ф| L­2Œг]|oB6 мљsыУніЛWvръ;ЏЦо#{161†ЌLѓСчФБEя kœќГРЕВ€­E\ЕД[•БВнЧ|хи”ЂŸ"H*0-ФIJ$vDжќаћИсўАэ[qВџ=%оїbџ‘}Јш„(68~ъSмЕc;z7LўiŽS ќарЂЎ">ПЄые^sО ј4zЩЯZЇЕ:ВAн>{<§zсa,љТ87JcИžњбгИdхХXавnП;RmПн†yN м#3СWwvbЭСcш/3|Nq}PEr%OZiЯš>&DМзƒЯ‰иєжФьсаѓчяУхлЎРS•ŸcнwЯЂwcJћѓŽMујѕЫПССcTо0aŽя>ММє–^d‚ЏэьТ•C—ЃПYр3ѓ§МЯЌШѓЉ9яg‰ 0РЅеџ jіœСЗпџ;іѕ}‚žЫ$ZћыЙЙhK€Wјооћ&u.Fпƒ;vм‰eWU –4јр~+6ЌИc-ЃG;e?тfJР4ю9 Юлaѓz' ЕJЂ 'осћ8ћ>mн{.­р1%нЗїяФSo<…оMIbэџ Ч™7лpйъKБ~№"\rоgбSф(Єѕйq81x6ч’aуїйK€­ршj"(iш/—pѓ‚A V›ё‡—OaїёАјт .”]|i€з^м‰зw§/яy}з$ЙџЩk G^RV~h3†—ЏХцU[0АpяК_иB“Љд—%уєЉ b^/ шзj‘1єдѓкTВБЙНлoМч^Ž7№ К .м:_Нј0ž}ѓYєЌЙђC†={ид!жє cуЪЭш=ХB)™8eYіHьщ9žс DCqћдPЋ˜rWќ…E-QО"FgБ€ХчЌХm­Зaxщ0~ёЬƒ8ћщ ,Л"6rKЖJяйѕ+ЄyѓHe?VQо№’еXзПNп„‹WЊ|?L[ЙЎСхљ2иђ,ro2iЃЪˆї\фgЃ}y§ЙЄ8жзНзoКwнpи[KŒQЃл‚U1xНэћ3GЫС>ЌX ƒq^пjЬ/ЯOF’Rf>žйžЯ]іžzdУс ииПч/Т…ŠНmН*kѕ2$Я“ ‡ХеоLт28‘˜*ЏZаћj ЛРШОЌK†JM%єї рю›юЦТCkъ ѕ~hб*œЗt.Pр—uїЁр7eg FHхЧЕƒ нy;wРd8еШуLбГbT@:ba•зTxI2dцъЏIZкЕ лП|Ъ пїGг^ /ЦšхУЪн)‹яg—ЊЄбcРзEŠг–ЛТЗ žЈпЁ.ђši$6Є)‡›ЁЌt[I'6оНыKVтЌбC}ЏVёеБqмwH`”XПїиПУБчvрe_@и"‹ЋKZК;K8bІDpКяŠ‚œЅ\Ђ•„АIG*ЖѕUЕАfд`ѕ"э%CSћЗхёZЈњ˜ЏˆжЇвз[jЭи2ъc@ExЫЫ (xзБрѕчюЎ2.Xл•Эu2289ЏЫЧxоP,аHCe—-JuЗЌаAKЩV‰ЌO6-љh§wК`яш8ЦИe->:Šžz'bфHV„‹ЮЇѓdІ—Ўи:ЫOЅ@Т >mрMшЁ^ТHъ*}ёћШдqC64ЋЄцмі"jJE ІG€$xw@И /OFsœзgypФюŽIƒЁйK€ЭWCЉ$Н9 z"f’КЁIp’еЅњyœЦћ)ПЮЈ+Є9ЧS•юЋЉ7­lА ЂПФFдќфX€ЗіŒтшHш Рт&hdдdX2уЄA*#‡ЛцЮЃBkWч<ЌЛ m­Ђ|Є<& ~"тy„ˆЙт€ *‚„…бАчїЦЎ“8rbМОXЋEх2MоQкZbјЈЬ.Эы|rф4^эp ^JBЄ Ÿ%ˆЪœЮ r­—_ДХ дЮŒCлўХ№ЎпgьЅšыйѕўшg.ТžaтМыЊу;nшСбуgS'%RQчѓm ќpфBЋ/ ˆVtиrЙ!Ь4%ё™є "[ъќwdљгрЉхчЉиŸЇBd‘гF}7ш*ФЦч“8Ћ?0aІя!hOСCбw.Э5ЮOК;—:5АъРѓЊ€ц>ЌŒќ<z3жx™Qбч„Ћ\Єц j ’FP b.T Аю%ˆжhASœЙЅ%!KђV‰(˜сБеЇр#щ`Щь;‚‰љ!ЇЗk}Є ЎЎ^BЯ2›Ѓ€gЦ0RчНqtЧxв=2j­фжф#YЪ-L˜Є9:• H4T 0эxъђxj `A Ѓg!ЂО6Ї;кх hќd*‘˜шОˆ9O‰Д№˜гЦH рх‰)ЇЩœИРДўЯХЦ8Of‚œDu)№dp–єLфєL’xп"Ј[ь0ЕЭЬ;HЛА*вej1ˆ‘„xЁЁф"щ1рХ‘b~рŠ•ЖT Ÿ} Ф x‘{gЬё”ЄFаFф4‚ДЫќђ9ј(,žЊe—є,™к&РгЈЧe1•qDШЕHŠЄЖ.••3 F–јO­:_ФВЇ%8яЅJтŽ0~цK†ˆћKИ19­шS;Ў7и›ˆрIџэ=’а8С#ю0GM0*^аf#‰ѕ3OіEЉa“Ќо`œfY ‘Œ^€'ЫуЎ70ћP8^‹H;ГQ1“ž‰Ѕwз2Кш9:ЧI,`С <с|Њ'ѕНи;фsƒˆ—ЄвvUƒ6€Oб›wъPO8ћќД‘C*:ЄirTљЁзS)ШeiЏ}њ33x“иšдp[‹špdYВbD[c˜Є–ЅЫЙћMU6HЬO9ељYvё#‘*ѓ†МŸж €ЌгIЌа˜Zєљ,WU3[‹Ф8Н"&Ї‰A3Х$ЖСп`QBЬ!ї'Е–7QмOT‘08a\юЯRв’ЫZРЉЅ*]%9zЏc(|UЏч–ѓ‘яч‰№ь\:ЦвЋы{ƒІŽщБ Л%.sеЉ2t)еd1Ež8 ёsЖxlИ GЁ—РЃ_}eцчq2УIHUxєљ‰Нx-ЗœЎsЄЅЗ–ƒОu#њЧeћ3”ВњђЂў(!ZЖт“ж– ^\дшЅBЇ“—У‚Š˜Ž е^—1F6С'Ц‘…ЊЏ+йЙ Ќ€ЄvвRц)№Эj_ВˆBcђХдJGy:HlnЏ<ФHŒRЮfєМˆЯг5QЛ ёš]ПдMOЇэ9Н€цvkhkц—BB”šBЉ`dщ Ш<н™м•ˆƒf Pччэqздpbљt— ђd§ю>‹>гk‚йрг{ёПОqќŸoџ`x/хw№ЪIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/protect_host.png0000644000175000017500000000343511733011756023343 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоgAMAБ ќabKGDџџџ НЇ“ pHYs  вн~ќtIMEб-™њ‡šIDATxœэšMoЧЧфŠ/тK$ОФ*iЂkдRР`“К€OQНЗ_  ффKƒфт“вoрЛќђ"Ÿм Ш-lРтЪёE|].wwvfzXŠЂ^hsЙ2hФќ{ий™gўѓ<ЯЬ, ѓEЏЙgчя цmРМY0oцЭB€y0oЬл€yГ4o&P^мМyГV­VGїЉTjE)UЛ{їюŸТvє6XъуЗoпо0 ctхЪ•Яlлцж­[мЙsЇЅЕ^ѕ<Яѓ(‹‹EДж(Ѕакп1G">|x!Ц† —ЯѓѕW_mf2™QYН^ЇRЉЯч‰FЃФуёбsг41MstуЦUЧqB „@)…”2ЌiSJ€\>ПQџф“ЭL&CН^s…Sј†Щ…& ю Ъх2RJ––|gЊVЋь=н;їžT˜Уe.hмaП…нqкёxМ]*•xѕВ=tнK—.БЗчч…ёИяМCq?NЈeАлэюИB/i4$“IЄшŸˆћЎх'ХqŸ<>PВЗЗАsцЅ€„РВЌvЏзУБm.—/гh4H$Ч<їŽ˜=юЧљХё“~П!Bg7ёSвмЂОпOM]ЎЙB№aёCк6Щd’VЋC2SРѕ|wзФpv=ЉPјћ…Ѓ2Ё4jдњљ$ф€\a™,s№уПЫ~їїБЧmŽ=Ђџb:яГ^Uцrэљї NƒОžњ+~z§1џўЯG'Ъ"€qтю,ЫHGўЫaы)ЋРюAuѓшY<&HФ}*­§Д ќ~šAМЋŸФ&тК1zfъЕя”ж~šКНїўЃшB€y0oBх€x\ЭX3еЅоrв!?—8+3 амтsрГBЎC!зyэЛж TЦ‰В^?EiэpblњѕтLъгuc8"изЂY=р/ЛOЊЇ ­A)ЃЊМvHЏПќЦЌ}škWŸБћ}5АQзЎ>c§oV НЭЬ!tPя*я}\0o.šц~ЂКА­pjйС0N~БˆЧ…И ›jЫˆЪ™–I#*СџЙljf`чгыV]7VwD зѕЏq\76\Я:Z­врАЕrnуnvЂh…\gbНгЫэ4Ь$@ў ОhnБqиZљюх~!pŽˆ1KНLЦšXЏЬ›їЇљйх€ ,˜З…aЈ™Ю r@s‹oЌAbѓ(йXI&cQм-$b‚ђkЮ“0Ђ’BЎC"юБМlcj<юЗƒЖ8 >uiД 6 Ejй>їНBЎK6mMЬи“Ъ§Кz§д™Uќтшгз`Рк‹BЎsB„ћ€ŒN<dгœјь™ўАѕAрѓF6cНёtzšŸM˜•…ѓ6`оМїN‚•вSэЙ1aHЎ]}иЈTвžКŸq†‡Ё ,XА`С‚ Ірџќpс™uIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/user_64.png0000644000175000017500000001233611733011756022115 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<€IDATxкд[ ]e•ўю~ял_яIw6’a  Щ”Э0Ђ”рŒ:*Ž23ZЃ#ЎŒZŽeс25LЁъЄЦAТ2хN9Ž‚$‰I€$в йК“ю~нoПяЎѓ§џНEqЊЦЁ“І‹У}яОЛќч;ч|чœџџЃФqŒ“ѕЗћіЫжjЙЎЫД\yЅjчivЎ›яЗcЏнŽмЦxиЌ‡n}3??КфіGt2ЦЄЬ4Л>ЙІ@eпovНнXќНа -S€Ђ[Щq„А]GD [U „Љ8Јy"lL>ЖІО}ЦзžЋП*xёГoИо( мb qЉй=ByГи] щPу\Фna} ~­‚Nu ­Ъ‚P!“~с[Уў­шd-9[…&”Ъ…щю№š@Їqœ№ЛпJ~ xMшQќ†є4”2Š'ЧgпњЬŸ—Ў˜uьМѕЌ•ёшоiЗŸZу”Бc"ЮЙќ­У№ @аJю•ј !jL'‰ъ #ёž8ОfлЮЅГТт(\M&WВv6Ћ$šLi,Е„яѓ?СЌўT* ЈгqУs^B~вcZ ˆkХ3@аx­žж МЄPt‘Ы2ъЁGбjž}t6pžТјЖeu$ж‹@ ?ODФtц}i,yAўцІБO‰SїРi|ЈSH@ЯэTрd 5W<сМйСQДŒ!›i/!Ў„0N“4(jE;€№X- ѓ2oў,ё€А(ьЁлZJЋQ„!UT(M–tЧˆ ~šіx^б“иw€Х”oцRЏjС0rа D­za–ЄСИJЫОаSѕ„ј„"ŠrLIaНHM8ёоœщk„ˆx§BІШ †€‘IŸы‘3Y1$Ђ8ЎŸђ4иёŽ=к/qл^Ткjњфщ. вДћ>-2lІѓ}œм+\?пG(V&ссv^Є їЇCДЬ–Rx'A@Лс&Oд”ФлЅ2ёqЪЅЁёВЅРёzƒЪ:E*пO/`ћЌ;‰7‰ДJ€;Э&щЂEZ;fqєс­ЩfъЪq‚cVUИБ$>NІЏQ’JбІђй*O1ѓ‰ћ‹пDŠ$ ЖFG@S„ЮцSР’ПV6uдЦВb“@LƒqМŒ(‰ЧL_'&K„ѕ­|ТќjzЏ V*п<8ŒкоabбŒ™z5+<рмћќЧHv?ŸЋ#“IщЊ§ПWІAрѕV.IyЙЙж—ѓ†QR'0џУ=‚ъ‹/ Ј“NмЫїžrŽM)>$jџІV/8Aдп#щяbв$S"ё БоG z“.Rдію(j/эЦф№Оcя› ѓqtћ)ыЃ DeЯa•›КЏz”М~GŽџMф|Ћ”ФНH{г3H>Љж!xc{Pйё<]П-ЮЎOп78d%м-fТы ƒБY!ЧПЅЌ–єгѓ€вњfтъržаNО —їиƘхZћеblы6T‡їŠy‡]т=щћN§ДјъУОпЕоў_ЁфЛ— ЂwХ|X…ЬёЏL+Сє(ЛCŠ˜рБы—“Hv‡“№&F0Оme'•DсѓЗTў›Гf]`е§СяœћцЮGyјЌ!?иЎeC(-8Њџбœ(*>€htDн/@GQEњuTw=‰gwЁ~`\м$”ПЪпёЊXйzƒ!ЁœSwП.ћФuoш}чGП’­o,;УјЩЌ і ]‰}ѓЏХЗŸ<Ѓћd˜§Г+‚0ўЊXKџ>вˆrз=nЌХЪ›?ŽSПF8ќ$r‡З r;тЩАу\ГˆZfЕв2xsЮ…НtњЮ}=іV—5№япнfХ§ŸїKЪ}Џ  ѕЏтсы”гп{ы™Иўтb’юі†‡CлGpз}‡№єу›БўЇ7#cыВ.2„А4ЖH ЭгhЧИэž<ёА,€D\7яН+ЗNПgу{ЌйЗ6HхХєЭ…ђЋ.Ÿ‹5чфф Я’ќТ‚‚ИR…Kыж]эŽŽmПиŽEѓљлММШумœ‚AžЛх­§˜ПМ,}х=ћяйм-џџ*?c№O,b^igtЌНЊs * ЬtEK­Х84вDЅ оV˜љ Xџ§mЄВY=%ЙNOZ“оАЌGУoš‹lYЮ˜rљЌс€M›6№§ъ{‚ёХЂ…qгЭKqЮ| fЗ.*eв іМT‡чЧxqП’?(bЫГЛёєцCИhхмžВЪtНn'Цk—:xjE лў{D$ЯПКєёсмс<=§ў›oОyжxРЧ(ЫЯ_гU+rв’Тp3Љ^ЎBLэмыЂ#&ьєLпќЮ–пšhУ#FЅcчh€Џўы><ЗщHђ[œЇЦСG>wчЁђЫЬБ:h}QјМV”§W­e,\пJ\_ДќGли7ъcџс@NЊ†IВxрЛP­uRiyzЩ$•ёНџХŽЃ[aZ>)єŒрmЦДЗ O;е hЗнщЅ*С­t졘5ў–UЙ, bпLпђдІУ>аТѓД~ЕUFhмІю§pЇХgкŸтяћ'#ќфз<њг§ьŠZ>TЇ Х<ЬяUmВЎ^џ­G6<Ркsаџlt '„cќзњa<љL-?YЅЂ…­;j88цЫј–жœy Ї…=Ќ ѓhћіх#“ЮЇ€ї}ОsnГ­FьjNwШСшД"мљЕи9cŠ ЫЎКА^'€л`шЩЋƒV]‚pщХѓАdqљ!‰ћ‡<мЕn‚Іx^ =Рю3aѕѕУYИірœc§†OЏ;ћТS @<2OЁ6h• (/ШЂд“tˆ-vь_њђЈ_ŒXбЭоЂTм#ƒЗШј5жјѕ–3_РйЫKš“luyщџБi“.pуЕCŒqяzЧђ„јj!nџЧч$qъz„љ Bє0ЌŠ%ф YvSbѕнж“NбP’:оЪ’  EС Т –tMЙQе`+ІЭБх€hД’кНщЉ№bЅЎ2.YS„i$•пнџє<ізz:–.ЪуV/Тx=Т3/Laє ЫkиЮ 08зA?я-чВt1Љu–Zg4бTQљДНЖ є‚œ%М€сјk”ў`зќ,ЋЛ Р.){њtЕ+Š4h†ƒ9$ШEЇЉrП_ГќrЫ$ТŒЙч† cПро‡іаƒx/­Пt![тzЛђ(g5РŠвV@х^AбWdЄc4IOиEЄЎ”uUН(mЧgОР4ueЙХЗeHBУЮ9ѓДTžЮq bbCUM8vgЏ(ЃTˆdсќ­o<-,‡Ks{1Aыяк[УјИ/ уЙ} Zш) •c‰~_tD‹LиSфх F2ib2<ŒЌMАQkЬЁaЮšбvи2е!Ђ­,ђ-2q†~ш‹Pir­(,ЃШxsЙaPЁО<Ю\жФЦпtаlщxтщ#Дф 2,†јб^ДШ Žсьгœ6T@Ў”E h0=…ѕBWd;-žпN]_IЗ E,Н=A’єЊ(hY8‹ў`уŒРXѓ„ли26…kBVwТ Йш“єџЊ*[;VeQКк'3ПjКKFnjJн_ЦДЈ\7\—t Д€cљsr(ГДВžXuzѕœJ]M—с0Н 'N$є t\šє€ 4P8у„aМ.тzрБЉiЖe,*8nНC9й%&,Ьhešвф?žш.;ш.ђЂ0Rх}ѓћUf ‹ѕОIоPe“3§Мј8™^‘>zŽя [a(цž‰Ђј'Ѕxц‡ŽЙ^єнv'j7ЦЋЌрY˜dЯ@œИyсиШEЇШ2eЭŸstг{2<нZеD‘ЋR‘ф9ЁиJNŽсБœPѕќ(=ВшЊЗсе,Фт6пѕу_4rвz‡НOдСpНIк=RA“MПЧ*PT…вJ"EQ™€ѕ)‰2*•ЕА`Ў‰щЙЂžRШМo ˆuЙ^ g‚)TЩN'–ЄЎЫ#Ѕ%„gГжAЛкЄЬыЃiю<ЉЭˆЕЖнTЉ*,№'G*Је=2’хАИлšщ ХрлЬыглЪГ ŒѓфпЕ\sњLV…КМЖNхФŠPЃЭЪ‘GqNХTйT#bхarЪEul ЕЊЈ+Ђ Œџ/oМЅ{взж}Nйzгg‚ыщцївк‹b‹=E„EGЦЗ(rл+GxZ,йлPIrЖƒk.11E–ГLюD•дфb‹$@DЩQ‚I0S 4&ыh0ьш}П&ыџѕцWўA[ц^‘Хбя§НњдŸ з2NПё пЋРoeр•sА™ЌeЏ@х-ЦЙ'KdvQzЋ.aрJЦяDYTš"ў#9/иL=@Ь $ JЧЛЮPXўg~§Э_^БiАђдЎџлдчўтѓИtМмСиНЁнiиК ‡„gчГ0,SV‰–ЈпХ?рQ!ZzОœ?$!ЖђG(ЩTp@SФО+ЈъŒѕ&oДЁИпю„_'ЗўУЏмT™5Ыупў4Ф чЛпљ™`™њђРy&ндžj‘јtй7идоДй 9F’ыu9­&ГErb4№|tШ†n[jGККЂэ†є„№БŽ}єЛŸQ6%KsГxƒФйзnМкБЕБb\c1№-Б>ШjF„‚шрtC•9_T"[DD!№‘вŽІПŽHy^ь1ќŒ|ЅЗЫxтЇїœуЯњ§ЧџqЭгƒр ЖЉЏ#ЋРщКІЊbs(вS!s§tк IЅaМ™7ђ(ўспЁvYлУ\д "PВХj ЕƒЋ%ќPE/П20<ќШШ№ѓ/ШuџЎ‡к‚lО ТjЩ/ I/€Сђћ0ސ\ЮШ€0ТџOTaЕф%Ц1Šџ!Юfdd бŒФVK$љ1ЫˆF0п гФVK`‘‹ќЈRЪ#&ˆ№F<ЭjFJjНб†е@€P З“'y“IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock_16.png0000644000175000017500000000165711733011756022233 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<QIDATxкTSOˆUџЭЬ›7“Mšl’в˜T[M[з­‹'Ћ,­‡"RЫRDб=дТ^O"єPЈэA№$ЋЅ*"HeС“"КˆДlw[’V˜tгM6нd6›љ—™y}Iщb|№яїч}пїcјп^>kНСLzJJЉћѕ1št –хvКЋ§Т wОўѕОя< xѓНe%Ї_LУD#Фл№б[wсј !шI2w<ПSГП šНw닇ZлsgЋ%ØјЙ4™ЉА`€w›(Ž3Є“"XЬаXрЪrˆПX­@D}qѕwяЖ}œ“ДХьГˆ4Ѓ}Бw*SQyЛgіQШЌ… чоG.ЋaВ’РБ4p0э>ђ ЯiYуЃ!V<ђjщ­ќюФ‹ЈЕ‘ёmСŸuјbХрь‘нѕf$ЂП~Cˆу'ЄЉн“w]7—|ѓљœ Cуџх(–nFјjСA'NРЬЅи§…kЫgFЋ\>ќчx˜6/KхёCё–ƒUОP2&іЊxЊУRm€Mš…ІlЕэCЧ=іуЇO5ЖУФз2GRњ‡Bв8);еїі}ž@3Uь)HkŽї“ ц~јјЩлЅёСйљЪЕЂJNSMyš‰r:тqNHa7­DЫb^ќэѓЪ7ќй6шž]Дzдv Ф^IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/big-left-arrow.png0000644000175000017500000000106611733011756023445 0ustar sylvestresylvestre‰PNG  IHDR++ю]bKGDНННiBеЈ[IDATxкэдЛK‚QЧёЏЏЏф%/н/v]"rl jkЋЂšњ#клƒ– ZjŽ psъ–bŠОЗѓДИD^2kЪœщ<ќ>A—WАЖWe!>‡e[mTДdekБщ_єkа_нќї| Lˆ)Т­Ѕ[EzTXtSoftwarexкsаPжєЬMLOѕMLЯLЮV0б3а3QАДа70б70TH.Ъ,.Љt(ЎЬ-H,ЩLЮзЫ/J|jљxіТ3zTXtSignaturexк3JLN427NВLNM4IN41KK6I2Ж4365I2LJNœй p‡Ž ёIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/dynamic-group_64.png0000644000175000017500000002116411733011756023714 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бхЪIDATxкф[ \еu=я§ЅзщžUiДЂ‘„$$БŒ,й8$Њ`CсSС…—2EЪ)Њь &ИтьTтЅœ ри)L•ƒлb1$˜€ 2Kd   vfыYzяПфоїўящЭŒzF‘ЪРгћн§ћї;чо{ю}яП/|пЧџч?сДёƒјѓЉm Ж–кjjдк';Бьл–:ВŠKКZЌgж%v=™~1sшџ6ЕЋЉнLmт^3’.ѕ€ѕ65“ЬАUяЅvš t+e𒈇ЁЦ}^§]6zчБПixІхуА:J-eKŸчЛдгџnVТ=Eх` nŸнMmЅіУ. 3\кxџHSЛ‹кэXфХаN  _ƒ ›є}I8wїќЕљЃŽ]“WoлАЈ5№< žI(UˆзЃc&У@Љ+JWђ(іujюй$€]§6eѕEhЦВДœМЖ3бГAхFяпЌƒ—/DЬHF"ф(IЂФ№ИCАђ%љ‚‡\СGЖш!ŸїP їЪ§&*{“ЈtЧїаoпM$<~6ИŠкїБP,B‡аё=бкЕ­_"ѓЮwГљŸFпХ­hŒ ,h’Xдb 1.!Щф65Е”В~йW—ЊT| ч|œШ8шЫxЩ%"уP9ђїXєњЪg‰ˆю‚CYМEоKрVQ| rbgмптџDМћбЕhMtЮ107%‘Ž хў*ю=ўšЏz!|˜R(BђŠ"!“Ѕр/’GWє!Ч< МGљЭє0іE"сЇ3!Рœ!ј$ЕmXl^…NC+Й|*Ѕ&Acь§цў…иwх:,"ЋЏœ+xла@_ƒw‰4зеяёuxŽт?МЄAчЗ /E!Bкав Е+А.ЩcАЕ’.эMќ$mФў–HИЛ^@ц ў ,Г.Т*kЬТ<КZАIшxхрoс‘пљ}Д7,o70ПQ*p%B^q§1№y р…C Ђњ њ‚!Ећёw]њэhD`ё\ 6щ†e:шoFоvяJЩіРм3E@Ечpnd%VкуA‡€Ї"ЁјVлW”иЭ!ыБЫ—iXEŠoŽsЖИK$T§кq‚Œщkр^€)єя№БiшжоdЊP1ЄƒоKG—ИЅМ/™ІŸЛўT$˜uК§X]‰Um‰ Ї"!ыaп‰NМў{—a ]sRƒЯ—=8(аŽOЂGBЧЄИG0 .фБPљŠ^iЅLЁEг&њ0•X@КТчє\<ТпПЎђ^ђЛє?< ѓ+c—тМиє '#мџБјu”к$bl!С<чvн*•ыWДаi4 œ е1shР?С@-Щ"‰* ’˜iJK8ќћDiцm=фп˜-ŽБЋpAЂ>ЫO|^Yp9bЗР0Љї(Љw)Hq и#ьі\ьhї<€Лки”*ПfQК и;H OеН™Є0+–Љ”>/ Ї;y/…Т DТ/Ї.…ЗgNўdcг•єягИОЭP4ѓhМ щюTЏŸ­ртMoУL%а`kёRж/ћћk‘ѓ ~:mVЄz<`cЧ§CидdЈЪDЉ‘д5}=–чзНЅ9(DуА (kя мЁЩŽчyWкТžЏƒм{†'‚В8Э=“І2A-ИRpшв@њi_щХ ˆ,*Рi+яI=@o];ЊœТѕП†Е XJЎ/ pмD УЌB RˆЉ_ћ9/Ž+4а‹Хy‰мž…аЅЛОаРй†9šPЧКчзŠІDшО&'‡jЯФ‘eW ižМЌPб#Ш"чТ˜WМ&˜Ёž‚€M+щпЏрќF Šѓ˜ д,QQ  чћŠ*z„remЉ? ѓыДіэ12\šЏіЪўBTЃФeя№Е‡•YD9ƒзА–хјьoѓ—i=р/qEЋMŠТ>TPЮŒ*RRr$xŸ'є€ЗТkW†ЧužЎky!ZŽ _‘`vauцx!цKSАБi5šь-XзL”EДћ 9;(ѕЅЃhэ;qђ€kеœŒ„I?›„іСк+‚^ ‰ р H ’wеСЗаЂк‹ФћDB"ahqgЄ]˜‹ѓ‹ше–“ ииЃAoСЊV" Ў ˜Rфъ$ъєGYXэ€?(tѕ)5ћЕє…Щ<рjЌljFCšЮ"Єd9{:,|в}мїіzgœoД— у.з8‹Ц ФMX=‡Ф+EжkїWрУ>ЩLHриu:ѓЪнЦ‡†s‘ђ‚-cll2дъэŠ;Ѕ5€ЕрkХЋNhВb\Б‰]›Я§Гч–оћp`ДsU†+k=р|Д'ДћG’:§ІюOYјLCТbж пОўc/їoКNŸ<ы$XѓЊ!›АДI[пфъЯдMеSЙџ HXУђ57<ИђѓOц~mŽиY!СЄ Ts%Ц†ѓ€љщРѕMmuЏŽЇТА"ŠыZЙњ3н?|cєiћЌ“ ЦНZи‰f>J}І­{ƒzг Ърщ„АNˆЬIуя7ўщњ›v§Ћ—{Щ:Ћ$ШДZ(ZzаРЅ­С+2Ђš0нфЇцвЕVGёw—п#7<їп‡†ў#‚Ъб:5g|' xyFH0RЪ:MГu(эє76#nХ>‹ƒw c‚ЎUѓ"žuL‹ƒщ30~*ІыусG'ў ~1ѓХмѓvЃЩ_[чРlѕЈZѓ(OгLqT №†Ip%§Мч{Љž(.4DЉ FЃГнAdUіЂŠšи ЩыЂкѓMСгm&здИ}E‚ˆЉБЕ™_.DZЁ@W“Ї р*аЅциA&АЌPш;?ž_чЊа$, kЇ‹+‡Џhњ ‘АЮЭˆEйч-ЮЫ+Ubфzщ­•Ѕ[чт’W!ZпƒнъЛIzЖHmp Ъ.Dё!~ўлˆo"vAВС­‹UгЇfskш%WПЌ-Ўм…AGЕА0z%jŽФ ТЎil кщ7†нЭtє&5О§§ЭмЕ‚•љŒИи'‘Іц?чћ2шѕ šРhЂvў6ј$шХџ…ојqФЏШŸšќ†МЂbdєЊBI VЭ ўIܘn†=Ж8rJ!ЌCеbдкА%№\šюˆ-”З5_BжьcЊ=Yъz„U€ќи}0Пz.ђХ#ћ‹$м^szMа‹+Ў\эУj9EбыŒ ВЙЊ•а“#і„jj”ЇOBRнЇZ€Wї’Ыфк†NЉL,І? МN(X[nCyХ—1єpЮkJрЈogЅZHёќœ@x…’AА„X07BB}Ў‰й“ ю‹!MрynО-yŽ\šX"k€зO—З’~ЧЄ”m‘‘"? у†›1ќГМacRќŠŠс0 ~/%VF0ѕh/Pс ъЋ&%ž  ђ2UbБмР–Џ7dHе- ;†h ёѕџcѓ(М›4Eњ%}0$риqœ O$dƒlЁТ 1F„Њ Ьš QЮМNр;AТЯЪnKЏ т]т4H (]Ч(T[b-hŠ7!Вс‡ŸCqWє$”g]š€э™~фЃ&№ЮЕ\ЪCЋм6„Cl|T-dfр ЧЫxдЎd фx€Г A*`B…€MуJЧббА-‰VиŸКйgЃ'­?КJ„пЌЎ5оФ‘ВL†>г‚+ з Ќ@X#B1œi8МWРŸ$Š—%—Шj\Ю†„МAз5Ш"І 2дМд|,n\‚дтУ4{Хбqреz§}+VjРЛƒd} ƒrFз \H‡Br< aHŒ›+дABoCEЇ;3пoфЫ†eяlHарЕјEЩњ+ЊHHF0?еж8еyW~…‘*x?'сfŒCуи-w9ЏœЈ @"XъТ@Œ…B˜”'$ЧТС &Nу4с$МХн‰BЅaЉЌ jqƒЎЋЌЅј“a"D„Iуi"-h!Ќ9н”фіР0ДќЕђ у–ФŽIяЁяФJЖ“Ы8УDB/…B>АЎYS&ЦšJF­0Їž5.рёЅЮŠXЛtЖ$X^Ѕ?2‹ З(yg”^ЇЃˆй” –ўхn[]_ѕР“ую :лќчлЎ“=Зn?[ ˆRид3!ЭlЃъ˜Ял ї€Ёђщm›Sн#'нШџ_ю\SАUJЬ љƒЄŽ=ЄЈСVЇЩБ вКEв>К ­Щ-П?‡Ё§•{.,%bsE5Т&ZћTž ђОЪ§књ6‹­Ю5їLУк ю q˜Д€KeOљ]хўМ‘Њ0йнся=аSўк9Й#бЏ>m |Ъ &1$ˆбvўx$JЙТЩ8ЦFШ!€ ƒpY’Ржь/УyъИїЙѓђVўтрІЏXtž <Э пfћЃћ Од3 оЃq8~Ey"УTќа{W„/їрЄw†( ј>њжя~Ђ(нK"љи^ј ђ†nТеEAяU†‚xC(ˆFp#%Ип[{o{GQyј€џЧЫ ђOxjћ[h§15Ÿ™'HЅќІrqvћ$!СШ!`h,‘чц+yšы9Кєe7e}њЁ7Љ–x­O†qп5%9ИмзѓјqgF‚ф9ОрyŸЁ€Ц)уlyjьL€?“&ИŽ?\Bй+Т;О Ѕу}]ѓЏgаїz_їo"mл€OКјТц6=z7џржФ(ўз4ƒ* šЫ‘лЧLMТyJ‘и?їэ ~•r№O——№о^АЕe*€ѕ“Р›$1a+u)Ћ7и Hб@Y9ѕqXxt!"зƒ,YПB†ёmp}kш&QœWпVYГuˆчъЏŸ{“L' Кг|XтŠ_›Xм/1Ÿ*Њ–’О { сaдіБЃгХыЙШ'§*№ъ–aoь:сV8TХДч_[оTёЩRV##-дšбiEкnЄPH*2sх,і юХžО]ш/ `h]тЉћ_6і#'с$ SэуЧЗ’'ќ8>G(Эcы .є№ѓЯ”Ћ м?pсOПгZљdOр2з оgU7|Sхі˜Х›ЎRЪђIъуAсcыzѓ=80В—Рї"{Ќ‚ЪžM9йАћw'н(WMЛMnwЁQЗ„ "Lxуњp“jпЮу'ž7ЎІЊ9™ЏЫe.MsT1cЋИO(k7FйњM*т4?сртЈ?п‹юЁ}84rйFvЛЎ1ј‘ы"ЛЖюž ќї,…в2ЇˆѕЫ>8до.vш?žтF V|iT.ЯЎŸ$№ьіL чќBі uср№~d2CШ"m:јёлЂ;ћї)w‚жAџ=ž;ŽеDТъ‚eya(ХЗЈЊŒPЦ@Ќ”ŽyВ~Šв1ПЅмЯ–?ž;†ЎСни?ќ.њ{1zШ!еЗo?Гїў3БYšЋњ{_ѕяЇИ§RЧЁ‹Bœ\Ÿ‡$TпЏћShBЕЪуTч+Ч'Х'Е7М™B’@ЇЌ&џIГШ‰цx*жпЭМЅЌŸ9–Gц5ЕщўѓЮЃХ‡Nљ№Cbz‚ТA3иФ%ЄIœOа—AуЉ–Šї˜W`г6ЖиѕЕъГѕљѓ2‰гбм!М“y‡Вншп—Ха.':ŸІzцgu=5f\7ЋЧexгсCEzоeЂЊўЈyHdЊьP{[\O …КA•= JsфєˆхЃ2Ž”йHр›‘ ‹'Щ ИчяdЉђ<œ=ˆюсНш>ўЗ‹няё3Dзј=u?67KјЏƒк§”ЎiЛ€jЂ%Ђn„—ŠЁu>ЅFe­L(wOšiuЬюЮ5@‰Ќ>HЉЉ'D)}Oзор­‘ј&?IFрgє8нщPы пn[/–Ж/k›žѕкгn/|опOvчќ.ЂЪтQ7ИQjqхќWq+Tлg1XьЃTз‡žƒм[Fс„Я+;ЗЮФъgš€№ёЙ[јйСцUbiЫj ЕDLJ‚іЋБЫsYЫiFР$ифQSжv<ešgЩъE'‘ќ(0А—^їљ/ѓФ†€?uZOŽž!jАИ™ЅbmsѓЙ\F':(kи'{Bи8˜ђ„њдГƒ4г,d+>ZТ№AЙУШњОЯ+9?рЌ3ђшь&`тCV7Љ§GдbTЎG["B­ЇФлp!ž#д‚tyФWГы|ПЫ§б`ўЮРŸ"рй3њь№ћHРФПЕA[AЇdMrƒы ц!ћЈэ њ)џˆгдџ 0xІ)юыU IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/newobject_16.png0000644000175000017500000000131611733011756023110 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<pIDATxк„SнKQ?wцЮь‡ГЮЎ›СEBZЩ@TЂНьƒі'„Нж_ BD>иƒєHєAјP/=є`lFVškЌd­ЎыЎ:ГюьЧьмл™IW­5ЮЬНчќюяўЮЙ„sџ1‚. St'бођЊбZUs7Д s0F:877эє|ќІ KŠ_ >і‡О,}r@lЁяkЩo–уѓYщˆж+EД=§ˆХЏqЋЭ9РЅXы ЩсKНЙйOJkЗ žэЎxŠЧN}3=ёmЕ”3Рљ3LЉy…тЏФuбуГ9ØmЎфЙ/ч!о ј›Я@йfYіsСkkW€Бр'Л&ИžЋьhбwOЯОz.AДъNœкШ/ЬyYЙмjяЂrфшbjєСБ= $J`шŽ3пMИџ0ЁѓQ5иvжbcR66VК-…:.SЊдƒ1ѕžз1 @х?ЌXоfц@mбмƒ‚ЇЯyHЉlS†бmccћюї‰nУ#‡e(`—гИGpЁщZgx\„тbфЦˆŠ МdюЬСа] Šг˜^bЯy mQD‘CцхЌ›\ЮЌ€ЅЏЄ†fЄ №cГLžСВС!БЮ…4ъH2юRК#ВO­Gс Ы‹\ŸŸ9„KO]€ў[“U-šz4,ЖŠЩ'sоПѕБŒ а—’…R&%њqщ]}зAЖ=h@ыЪјыз:ћ0і ’Œ#сєєЄхЬщUf•'jvATDd Кп8ЎƒŽcђ(ЦGмЖoЃ7oџ3Ъƒн`Лйэћ\xЮкoV#b сХIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address_64.png0000644000175000017500000000677111733011756022572 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< ›IDATxкь pеѕьюћф!1‰РO ‚”"€(‰Е#DІЇV-Ј?mБv*Pi;дZ•бV;VЧъ #DK Rˆж 4 BLh"П !ЩЫџѓўo?=gwŸММьn^>ЏHЫ9yћЙїм{ўчо=a$I‚џчЦ\fРeш2€Aр"ьЁрRћѓџUfаГс•‚ ^%~7сеZ„ъu ё/ TŒ hў2„}Я $ЉBaТ­&• ьъfўапŽИ вТ€йФ‡lcещ']ССВo›ZЬfѓTФх _ЕѕcWjSЇ Џ”ХјЉТ?Ђ(ЩзЂ ј xd kЏgЇЙЎŒу 6Ё™SLsГЕ_„ЗL&гњфU6Љ%oтЈ4РR'ށ б,Xј@BdТЧcСЫx„ѓУ"ёЉеth?Pдk™hdЯ+ЯММ>оЛМ8=дЖ ачСс–`уЛ0юФ>}лtЯфЪзЃў<>>А!wDJVQ–щСЙF№„UФ‰+ —dM ѕ•ДNЂwВJЫі-)„њm\…Xn'‰ЃŠw9DшшЁЫ.ЪїєŽц"т§HПяtBCп?(--§‘ТУ‰дXR–ьДЄ ъ,ˆŒDпљ‰іЋ;Iй­ЊЙхж‹jоэ Г`WдоЉ:Aš›!ѓc S „?эwBrrђc8_ЬX›€hЬŠHЊЈL”d{IЗ5@šBЖЭЋъNН|2#$Xz“ю™Ё91йўщs<ђРюуnшC†0:AяѓtxугЖlй’Еzѕъ} ИЈ1б€Dљ%NRёєd;шw“чЕ’IqlŠгsљ”О$э”Ж эњРХйййЙѓчЯП5%%enttє‹ХrгŠх‹ГЫo]›“ZSАя™8јжѓ ЩТёjL›6m‘šŒН$–’-{E‚nŸžH…Эf|†Mc˜@ЬrgїJђ—WRеЧу5ЫВн'ЫЫЫ›%GЊ^TTTŒ—л*++њвЪ”–ПдЃЛОГЭ@ЫюМ=ФєъЄ=ў„‡zЪЁTg’фt:%0ъЯъш]gl ЊЛŽŸЇч˜в[sXLР‡ oэ?Р$Ф yIЭ ?‰ŒB‘$ob†Бeб[qЃћNЂ$ea}X b8sј”H@O% IœrЭАК{QŒ’>ЫDьВф˜.„ДЦЙш<ГЊl"2бЭRУš њUV—ЕeќІћыывчт$в[ЗРА8.А!ŽЧјПМ\ш”ѓ=ШœjtЄе!Г4Tš’ вbѕИ(•`ЅwмRГйlO'%ХŸ7ЬFИЖЊUHџmО№WЕЩ&8ЙЏК /нсй 0 я€иЮ(јоИ/y`ЎYИМс оœИю*›Э="TлMМэЊXf%єкo_ЗЎ0Фƒ›с3€ ’є€wšм‡ощ+kd0t|маЖ§hv|№Соcxй„р }Ьh@pЮРsEۘТСЕ\uыВ•+пЂt`$ЧqЃ6†г7zЧrс!~Z"›я‰‚7_+ќH=zы [ gШ…‚9A– ‹ЌШАРCѓ-№з­oяYП~§ыјЈqЄ‡БІP;†ƒY АcШ€Х7˜ЬаRўQљя{{W~~>эўjFbћУіК&`ƒ(pc2Г' mщjњ=rфHEо+љ_}ѕе§,Zе“ )ь аu‚ygcЮю<>aТ„.м{ѕцоНя_х‘‘‘Ўй7’ЇЇŒЉS§u.zг.|єDЬЈДjєNp„@L%тsrr6рmЛСь+Н~XђЖ]K2ъ<``"Фh$Bњљƒ*љіЛЖ8Zс"Е5`ьЃ@`fЮ\!ќNp„y€‘щ|ѓ4Р`ЫЩlы‚ћАъ)Ў^n1лй‹ЏЃp‚—Žm‡Y `4.! ’ДžїёСбEЊ3ю’в#I2†у.!aацRвE’0d<юУŒc Ц}г№UbЙгЕ]5Н+к_t/}A'Ф[^Эeн НOЙс vэ8VJЉ.sMРАJЬoЇЕЕЕЉЧ­=wю\Ђгщ№ѕЅлЊUЋоУЫгˆЋ+№]ssѓOкккцtuuХђ9ФТ#UAпы111Œ–$љхМ эЩ?ю3MJ”ыЖ‹аи.рЄм{K$Ќ]Н=пILLAkL@<эПпmЋaU6ѓђšЈn‰Š7ЈѓЮt+<ћ=ЯЁЄЄЄe:xО–А‘єoЉi–ињ%9БЏЖ‰Pђ•-}ИЈ>ŽН-,ўл6з„e;vьИS'Iэё‚№Ž11Pз.Bљy\ДРkfe<ŸTђpо›НsчЮХИшўћХU^ЙHCТ5i ЂY€>//ŸпГ`ВВp№ŒN4ХоŽчЃ”(мw'Ѓ›TЕ”ОˆO-Vцk0[”п‚R/ЄЅЅ=Ђf‹Свр_4№H<@ЦДYЦФ Рх‡‚/<„ыa \DHюЩzn5ѕˆРсёЏЉ№”‡Š(ƒ"ЪЁ6Cг›z$АЃšЕ t”ЁžF‡іШмј МƒПг›yІль’ьЈЈNа„K›џ•m"ФЭЃH3^Wz#ЎЩLBСDZ"тu2жъ тттІЋaВgИ  R~e,—YзЩC?2СdбW˜tєОUUUчAЛXбcтрtT$;ГЭNuСЈf\ИЮ.0—58ЫE(IŒe‘9’&бšкаДkLааPпЂ'$ ЩоЩša‚NЗb_V”˜EюžmmлЖэЊmкьМЗ е]јжvOvЊ‡kё,3МџўћG5pžѓІšх59EFС]7Z АА№T’Н^яЎ?–rз№J‰МFЇЌi&И=ІЄzС‚OрэqRл (@ЂGѕ–OэqЩ*ЎWg?џZr’*ъ333ЧлЯњƒ)*BrЗ }’ЈЦЗСxЄpА$юT§Мyѓ~†ЗФЬžсFй АНБю+мГEцЊйzH#œk пЕ’ФђБh—ЊвЬ}n—ѓ‰_-Š€ŒЋMВ˜ЌёхЄ[р—wF@AAХю\>ї§јљepkЊY6`< Џ7УSйVиЛw/}>? ЕCК˜GŸ8q"Нщя\ж‰ЎЁэoж•,d]ЧBхёЫ6oоМэшбЃџФЎѕZy@`kiiyШjЕ>љyћјŒO8з+Aj KgpаrЊшЫэлЗяЩЫЫлЪ?c9ѕp566оmБX~^ыNШўИV^jwLх€k=YOФПјт‹яO5Ъ”џњаfЭЯЯПЋЂЂbgkkыW8ДfЭšgёy6Т”`Gc€‡Јˆ)))йдддTжзззSVVіх† Јвc Тuє_a:Иш}Tqq1T}Žщx?Ў­R%š’ŸT5Œ2FД†ЄA&Љ†'Ћъ\њд“Qo/`‚ЧЋ!ЪЌj…*<ЫЄЦљX•q„ЇWU{~Ф{PNƒB9)-žБФ5šэ№х‘Ы јmџ`ƒc]\AЖО9IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/accounting_64.png0000644000175000017500000000570511733011756023273 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< gIDATxкь[нGЏю™йн;п9NBЄHHNŒQ8™`EМR@т+" ! "B!о"ё˜Ї`H‰‰“˜„@ xрШФВsЙм'…ФоЏ™ІЋЛЊЋfnЯwо=і–8+Ээььмnџ~ѕйUЕЦ9ЗђУТ-ўШG]\~иО+еbщXeог€эh@bьк{ZѓўЮ@бђЯўШшчў#ВТSщŸm`<ЇЦэ*:J€ЪeпC>№Яƒј\љзЏб}x‘‹з№<МІ~ЏБ<Ул|On‰ŸчПcи…хŸh-Ьy O@біwЗ#иМ а›dA‰В,„€кЁРуўЯ€k>ŒОnЂ;Я–KŸUхВ–ё@ЩЯљчЙHK3pИ&D”Є %™JШnй†ЋЧ~г …†"€!?бШ 6 Ѓл&@ЧtДQ[mДyЃœ#ЩХЦKЯ’O1Ž#ђ†Ь”нЇDЧ hОРЋphHдMv,yl”$’Q„Ј”ААw&‰5 @ею“ф‘ 6ƒєўPBл=(ѕE€ќ•F‰ещ0jъЙ1“ІТaQa‘™ЄЗF9:mŸI§‡Ђў!ФѕјЎпUщp)џ ЪЇ418eoК†c„К‹€ ЂŽтЛњ№‘Z ђўжђ†бй-ўџЋА|є‡ЪqБ3ы‘d9—/%ЦГГућфќѓГ~S Р}3зоќѓЫ№УїЧd(ф#’эќиž9щЉњЕddдž|&5€њЦ?ў чџt’ЄоЇин/ѕы^] Rж7œйb‹нЄ"є~MТПЮœ‚s|1ЊtеWйs Д&ЅŠї.}іS3IТfpХ/ђMТПWЮРњ^ЮБ=яжЩHъпOІБє™УЩ]Я fTUи/Aуo'рЊ^№О§„;яЛПО3 vпијдђњR67ўж_YsпИŒп1№Ÿпš9 №‹Ђdоnњ„+чџ +П;I Ъ№Xњ%—*ЦрRСтC?lnпџ>ќИbЗ5Сlе№ Ь<јВiП‹wм9rDeЊЌ• УzЄ;ЬИЉr~‡yюяЋpём›ЛЬv#4jJЫ/ВЋI˜пЛŽ&ѕVP{ђДEЕqsХѕD*ЎЎ§хoювkkfЗH0лэ ‘_@zš„Й…yИыоC”—”,Њъ.ч WАФVЬyЈвьп[ћ§oнЅWWv…s3­1"Ё№‹ьk:ѓmИћwyИFвoЮеЙ‚ФeѕжžxL€7ПсZџЭ wщЬйЉ“`nЖ7H$ф~‘MBЋг‚ƒї ]ДЁza (:БВР/F№XqЦ:#f—о\œЗЎЕ“ЯЙы.˜ю[oM3Ns”HАь s-јш'P RVo{р­"a>V™uСѓщ†яРкKП„ЫЏЎLЭ1šIКУ:B жЋsб.рр}‡ЂtYъэ:#!ЁФЎћNv>МЎОє Иvсєп~чNТDНAO",Д*Љb„ŽЅŒ ;ЗХЃ}[$ рV™MN*П{?qч_„іоНSI›ѓшИжЫЎhKнƒhГгCЩwШ!цЊcуRUЧщтЦем™а4f‚dі;иWєGg/IОs€œ$ѕ&ŠуМСћ‚еЯСЮO'AЪЧ>в туюЯ!‚G (DнƒЪgRZO•%юХСъ ЯVWWзьДœ`>&xt~У&јЅGі ќiЈк\•иMНт›Zd=x§WЧръЪkSПQ@Р?њ(пC’ЇtзxkU%‰›*T?єЊеуЯР•ГgCеsš‰НIЩџЧ<№}dя 2HarIƒ7jќЇІ ~л&РћдіЖГї|эAIrВ9кфв9Ў5PxСПўТ1ўŒл №л"у<…К^Sђї<єPLm1цc˜Г…š07?єрOƒЫЇOяј-  $ЧЧ/ИжџёЧŸ"№˜миBкц,ybH•c ќњ‰ŸУхWNУn‚ПйэАHў›O…иnМУ3MЎ0Ѓ3Њ‹Ќzј• -­Пќ,\ЦеgRя€{]X~њћ[іšwЇTълœ] ѕG­šял‡Оќ%p^тmžUоR0T‚LLjвмъzПќєЖе Еаii€U ЦЧЧОњpДСЬŽїќЁшiтаwЮѕМNš'(aљЧ?кј]3Uэй~щЩяU7жŠzc5ИЏjG%УJ3ўF}џјЗќ]4ЉXХ“ЄЋ:xSŠixX>њГ];ŠќЪ>ій37>ш0€д˜ШтgZргˆЅG>ЫЯќfэБХˆL&цС%•1eНуЃKрTNƒL!ўЧѓЅЏК~нвц(eЙšEфƒ'TycеjŒцЊqНЄ$„аОяСђwП7&п9~sУУ”2аф†2FУ_ ЅLlT2jАЩЪ‘2‘tВH@Ўk№4ЗШuЧкВAЫкqmhКf’ЁŒ>%Шуp<ўЊ;@|UїсКзђ,:SЅАœР№m™HOзh0;ešМСjLІІS\‹%M2*‹)n"’ЫJHЕб ЅmšЌхџ6f†Мф™т4qЪ#ї’6UBХИ%{‹šФѓŠ<ОУъЯ#=Ќ™RДƒ,h„ФЮџ)ѕІ†ч})B3I$P™лZ‘~ъДDНјЂЎт™*–†џiЈzm“ЅДЪЈсMЋ'ЬэЄ&аJЩ]А/ж(Eх*юUб†СЩ(MRsž3n+№jќоЊAьQвNрAiЯ Њт*“Сcѓ*+„pѕёU—c№.SёпФ0Iін"ћn‹&hO3H,эLЉИŽ  67ЬЗ93сЄ(Њ#Чј ЅŽ n‚ЗВэ р3d хаиЖsU0ЩeћЬну$u?“ІУ­€Ћ%d АaŒ~\p)ЦчуЋh ІMћ&'с-Ыъ*o %mўQE.>Си†S3 `Nžxbœ%ЋЇжг­ъП<йš„­ іžХппф<ŽНTћ#эяІrѕSšl/ЎВХєK“rє.ИР’JъњZ# І№<5^&hФџrTЅ|Ё5ЪQщ_‘иКmКВI8О:ЮєЙNžp“”ЛzŸpУIj‚JН йhEZЁчѓSцф‡ •Ъ ЪFШвhЏkЧжœ§5AтєzŠ‡7Л“эпMї~9Кг!в–н–ъЮu†Из+=ў+РKk КDѓlIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp6-ref_25.png0000644000175000017500000000355211733011756024362 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe< IDATxк”U{lSчџ]п‡Џ‰ЗЧ&O'aМSшƒш *cZEUЊJekKи(B•ЊN“`“КVc­ыCjЗДгccДUкTi€ŽeA`усг 1Iœ8O;‰эыћиЙз RФўи>щ“я=ї|чw~ПsОcFгДЗЯ†ЄнЋ оТйglЂMfMlйŽЯhиМBшWTх]ŽхМКh5јxШЪD§LкбUtVVhяѕ БЯOЭЊ˜_оB%Nхg hЅ;†БЖV@ѓKь…`ПИъчЭ +$Žeфиќ’ѕ>КŸОіл†gжЯ4џц3ы޿Ϙ5lƒ–`лO'юžгWЎ…С_^Э‡Iсx,ˆ‚Xџќ[qtпШрЉ‡­Д-ˆNЉјэЩl N`Р“яЕ<'Ќ?п—1оuЛОєх./oГуБFГ2pьl œўQMфhТПТŒ%­/эЖйlјYфБMjјјB{АСLvг\ bг*Nєњ3ВЕcЊusЋGя"Ю1ЁМо,Ÿyушk$г?h‡и”уъЅв:јчжћ+ o<ЙВ8KEЎ(bёЪz3Ўп:}Ž.dwЁ3?А”|љ&И ОAŒь–ь3лл‚’ЪeЈЄ3сK‡Я\Имб:ЅЊ#Ђщ—Б$69ђrїWч•Чnmе;єЭяПSО&Аv—”‘мП<~шфБЮ?§ѕїопЖfыОа'‡*ЅeИнй’*ђе‰ів vAйтЄ2В<мўVвY^љуeСОC:CІњRnН:!˜НœгЙAєАVSFгŽ*#кŒ4)7Х/Ѕ"ф7C;9ИчѕMмдрчXѕ4ƒсДиMp‰(§іA•Ъx™”ЛMœвJ[s;Л:™ъ+yаЈхгз•qNfП<Ўj *TКфjB knђ.гйц\ј ыЧЪ'OтчќˆGЁ‚BЃy5 ѕАХAiM@NЭќSЖnсвAъЌV$јйМЯdaю0ЪИ 5Љ:ЦMѓЋ1­єјhqМО‡pџN?+Д№9ЄO7ƒ@Ъ+ƒЅ~01дwn1‹‘yGFяM џувR M{к йef)ГV_œУLSƒY&гЃiф}ыЪOНGХ_А[ZZH$иц`HŽ$|N­K“Сf›Ж6>ё7nы L—ЩN@QRgв,ЧТПPОЪYbњo'“IьиБуог1њЇ=E—Т Ўњ!•[ВйрЇйX^ПієЈ€a(4g^ЂѕЖОЄППcccшъъТіэл~LOг&ЩмѕФ(CAЭЙHФЊ Ѕ „бх™IDATxкtRMHTQўю}їНљwfќ+-ЉLkЁ-4J%"*Ђш‡A‹"h.кДˆ–­BЈMэ ‚J"Ь Э4H-J"r БFЇчЭ{їvюŒ3FОwю}œяЛп=чВ ЎPЩэбЅН„C lУ№Bчј•й‹щ™цЉЯьУбTћ\A ЁК"Л/дС’]бХѓѕ§ЯЋ л‰ЕЇTЭІ”ŠЮе(хАЂ:љ$Ѕh……„ФѕбоgWыњКН[гP9 iKиŸMЄ+—ЈЎpMѓђDоCышђyСsp‡TМslXЭŸЉ]ХМd–мй'С‘К_уP§)Т]Nd?-.Ѓ'тE­%rI72*ИХС= Lg‚Ј’ьKˆeuœ>ЛБ>а‰!Рca<<[гћbO›‰Ѕ"fЋ9нЂ­zА6X kјOуйдв=,:пMШŒ€Lš@ж3—ЌЩщьдТѓШХh ЂъgВуQvџ“§ƒЋСэj%ЉF€х*CбгϘЈ–КВI0Р€EWВЬВёЂ)€іщбњЦžЭЗ& uЩjјт2 wђцo_А#G]}ЂцЃќ%•DІ;<ЕЎr!ЪЗё˜2Ид{щ0Є‡ю&2Sі+н(UЎQм?5ЄкТbОMƒ d”гЅНнH›ШЩШk!ђБ<Љ4ыш fк"Эќ‹ЪП7:ЂTp&.Š?W’uˆ#0MП‚›ceй™ dtd\VLоЅЖWŠjщољii,Ÿf$RŸœїЌтн палiVр–Ÿ\мЗP.`џVHЧјKщцŸћБЅEІжˆbгi‘ Ќ-(SС,š7ў€˜– Г ™ГЎэJeиEгљC^,я›ХXЈЭ9hEKіЃVbгиBk*lj›žОѓщ>>їТѓ~ЯwоsžѓѓО€ˆ@ивДрГ ГЧ +АtчфО@B–вшŒйДб2 АМц6ќё~‡sbЋ=ї9Чї6‚}!Ÿ F№КеВ‰ПV~ТоЊЅa*yzœі!„EЂ#!œРuЭ#xЇтxќ žШn›ыщ%~Lšццј}J›фHˆяŸšџŸЖ4Џ?šшрFLшаЁŠх№ [Џ№Ч! тЌРіњ::{zаR[‹‘PˆŒ—>|ŸТ![?њ&&аTV†йYВзћžШq?lЧ]G3+Bbw_Ьщt ‡сxj*\эъš›xрЎр2LЕ5Тжв0ТpЯjm‘pчЫб!fЊTАГЖƒ< ”H МЄ„ nbƒOfd@žZMО§ЇsЏ\[жДВgoе(|і9ивэээ8œ”„C ОLNЦС„ЭЪТГ™J}ЪtќK4ьGЃјОЎŽ $ŒЄЄрђј89w№o(^@HЯ‡Сљ€ЭAЏ—ы-КН Ћf3ќлмь*}ІТпУ ‚dГ‘sм‹D№зф$ŽЪхlц1…-ее\%гЭЭђћбуwБ™щ†юоСš‘*$_u:4ІЇєЬˆј­VŒ„Уhзj9‘З••HГ"r§Mžзa…Б‰ гђѓсŒR Ї23Ё˜ЙвsEEZqbт…‚ЮNИик ‰R)Ш СэwqU›VЦ`cч/ї”+§33швы)ƒ†7 œХEtvwуn0ˆГK3\ ”™@ќПЦT œз“IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/info_16.png0000644000175000017500000000153211733011756022063 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ќIDATxкlSIhA}НŒIF3$“ЭLb†дK ’MqП)-"юxШўf07єСїКрЧ”мл_“B`OсѕSC–W3е;§#]ƒЭ§ ЂTФJ6NьХ™CНEр*ЌйидhпnJяBЄрјХљmЩюІЧЉсе xО„Х€ђЛ<|в_Єb ‡Hp&№ЅџьУЙРЋИjЅЦЧS ХсK`—VІF2Lлƒѕэ7иїљљ"%BAчк6r\gОc+WРЏ3=`dvйУЩНэHЖvуљы&о“x@’/$ ЩЩ8ДЭЊЎ+6tXEІ–Y.EJwсќ­,ЈPАŽš bfќVзЊ†ŽжXZЗэ5†н$њ‘фОк”Џ@йф˜Ы ЈDЅсг™оj~ефBЯѕмЪ2KЋM10JЃ@Q)Ju$)KЄQюLFg“Œйup‹gеjO.dL,T%frЅ€dJ8ŽŒRФ",Љђ!XK&jNиХ—*ЕgbўM^|Щs˜™y‚ *ЂGсH„ƒЂшtЯТNа}Љащš:џhшН[tЎ;Гј ъ†‰;“Є@bыІ $ъЇ.„dTРb‰ˆќЋ4‰ѓб(эŸiјaдяk}эЛДtŠwŸ"ж‘h{ h”Пиšє–ˆ|Ђj> шћˆ XОLjџіЉcЎдЮЊэ-qЅ9E_E \вmк!а‘ОŒ€7џЗс^(Н[оЄ}.вѕВѕ}ГdЩn8Г|џ0Н.јfjЗтЉIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/rangeaddress_64.png0000644000175000017500000000350711733011756023601 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<щIDATxкь[mlSU~n?ж}АКВaјQ&?Ц‡8у……€!?–hќ1Q4В,јЧ 1š˜ШH%QcpРQ† $ D‚+lШ&ьћ]ЗvkзЎН=ОїЎЅЛЗы-wы-r’7їоіœЇч}ЯзsŸгУ1ЦNFВ‡Щ*Шж-$Г‘%Ћ#с8n"ГЂЪFЇ)q„Ђ‘Ь„)‡3#‰ џxй›d[a;Л;0ъr €ЋрŸНє ЯѓŸчфф4N€„pВГГЕ]ЗcЈ{ЮK^…Н№ є~rр‰ѕрžЉ‚Ухй\XXx<в‚1WŒCх™0ЁP~ўˆ:o у‡ lЈОх“ ШЬ–ЌsYх™‚‚‚MTЮ+Х8Tо›ъPa o‚дbz`А ьіпє<dяT|р ђ ЎЕGŽй.лњŠqШyRœ„ ”Ѓ§Й@•sƒЙnп •ЭЬВВ&юYџ”””c<;GЏN РŠсюІJ€yдbЩJ‹W_7,Ыr*gž4ѓЋƒ“‚ш­ШЪѓєбD58о]Ѕ*m"Ы[›ЭжEхL18~•pR2ЁјYj• Ds[ІIВвŒŒЫ_cЧŽО;ё*сЄd0г’хb?oмэw*БHЅ VРкЗД­ДД”2тВсЈй›І|фЊ€“’ріŽњ*ЙѕЛˆЌ<5оrБ•ž[n^9ъыыЅќ7"Ы`4'R gц{@фІЇЇg‹ЩdzЯтi^ХœM@ˆ‹хq`NNžЗЕддддUWWџHYџ•сbъээMG < 6ГЌVы'MnЗ{ЈЉЉЉeчЮћшѓd‹Щ2Ѓƒ&T<ж”рD—Т™)у$aАОЎ YћSЈ˜ž}dCdž№d7еЫP„у фШ|І\7ЄlыކEpЈЏ•wƒФgС<Оyу ”-Y`rŠ(!œіЗє‘ч[а`тЄЂO•VНI§ŽчДўч‰KfќEzˆV[ѕAИЧI0оЬL/њА˜= ~Ф№rц‹”It…а|ІвљцМ{оыТчЏJщ|iпфtОО††•› c§}0ЭЮ‡%pё@жђЯ :}пxпL‚QC@дљМ]н{nьпOяњ~š4}}№лo ийЙ/nЦтO?УрЈ/ž^˜Ж˜ЯBЁŽІ; зщ(s#ЭMНњ8Я0E'#х-мД y_|O/LЫU@дљnЎѓљDггв‚‘‹з Ё ŒфЄ‘‚р§э8rnкхєТД €Јѓ9Юў.vћ УпЕVшc0R)Ёх…k†xO/ѕЕеšбљдšЁ@ изо†Ќќ|№ЗС Л$юљЫFы|#їC№ыŒЦVcІ cэv№на н^ТyсšЕКT3:ŸZuОЙ6 иq Ьq{|ЬK8/\Г_~M3:ŸZЋ€Јѓ1žw5Џ[п%+9ЫЦЛлљ/рњіЇMч›Š™’Э#ЈiПRfЏˆ:пЈп_ЙьРaЬ.+CЧ&9?Ћт˜Пњ~Іu>™ ЛЮ$Ћ!лfІЙбЊUв= :EєBЎўш*яё:0[+ВiЬЯкZ…гТzЁJ=@ž™>] bІ‰юd'€pDsЌVыћEEE/™ЭцGьv{WmmmУюнЛЁяўтџl :3M4бЫІАЬ=ю†Iщ…їе™ЉRж&ъ|dmaНPаљмБЮO#gQ™dЭIŸН],B.fвŒЮ/л reтu‚hfjШ0&ЦLЗV sХЉxФЬ€єIгТLгщХeZ˜i:`Z˜i:@˜/О\XY…мЅAч…ёШаs“'fкЌ7ЕэнЛїДРJяЇЈЯLSЙ1™ЈХ&™:ЮKƒОa]Џ<Я:K1ч–r6vЎ8qтjEEХ.ЪV­MШbЇcГэъяdWNз1Ѕ;йтюp:hwS1SЉшD™i:ёYfК wтYёtZL‚‰…У(эV™S„Дfъ? v‡Е^A5ўƒЏ7Ѕ4ёФNНЙ‹ uŠкп„иЉ0Щnчk‚ Jќ>НпА…d{[NББžkТ™ŠzВ7ШrЅ:Aь В“ŽчВx>cNJ'A9Б3бу62IŽVдq™!­G+HъИЄbFV"5Žл$…Ѓ…Јuм&)-ИЪc;Z€?•ЧvДЕŽл$…Ѓ…U щу6Tv8F%RŒЃ… жq›ЄpДФЗ‘УU‚ЃЉw(ч|6їb­Cd?’M:ZзŸAы йŽVz1Z"ћ#ѓ/f=З§^д~.hТBKЙ${/ešdІАl­žб4Т…ЕŽœшKbю‰MѕLz2ГlM“~ -Е(­Ї7AЂSУiЯ;›vЙЎR…w№Ђ_E}Е‚žG PF‚ОПЈ#a”ќ2>>^—]ЇшЉ3—u;ШuЕ™€ЏNшНІcdк@˜ pт)ЄЉЊХiёт›^аh,Œќc ,…б ‰ћЩ Ш"Д\O\ѓч:j(э}^`уЭ’{РхЩ4nЬˆ>ДьХ3mvиwУ@пѕ4JKKwУоћњрме”­ЕІJ… ocдр­ш››GР:…ЕоŸзЊЏVAkЧ0МBх"ˆК ЎP‹вr№і_Д;>oІNзљ5pХ\ЃРnИ6ЃоmX™р…C›]Ђ€Јь З—Ьk]OЁТЇиЎC”зg ЪсьвЃнRћ§ЉZяА–o…bћх,ИyзАг>[+{ё.ZЎ^eВ%YЉЄfuR,mZœНx`tж‚Яч{™4Ъ­6NwNЫHмТ45Њ˜Ž‚‹wеЂзBИyrџXД–k\;6PН2“f\ЃS!гЎ77'ќ8ЗљIЃ‚lŽЌqтneіЩЪЫZ(рBZœюQЊw.U,JЫ5&јœH цХѓЎ…уŽ3'luЋBЁP„4JчЕЊWjіЉС;ІуN(…vгтFЧG^$YШOљHсЎЪ…k‹гыГƒѕvuuБ“?Щ.“qЧЕ–ЊVСЛAч"–ЈъшшhпЕkзžжжж-MMMu~Пп “УУУсžžžщюююašГщНyЬ'Л‡ЬmТ’е*РМ3Шж;Udt‡€Є#:щЄзЄScFž;Ь%ЃЕѓiWтŒ‘Ю0Ё9GJТчквГR5пЕ$Д рwх§Bd9ўпАќVX$ @$ @$ @$ @XfзП ›ЫМзqэ†IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/folder_25_.png0000644000175000017500000000153011733011756022540 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<њIDATxкьVMhQžЩю&$ижЉ­U*ЕT…VМ "ЈGA(xї`OтЭ›(xъБGёрн№Њ<+ъ!PСX›ўиДЕI›нMvї3ЛyЭKšR*і"n2й7яgО7пћf7HDpаў; …[)нОЬіvљ“lЯO>‰ўd‚эsџдƒймј™ЭNыЫхЬтЃлућLт"л{тFБяцTЁыТш:а`‘@Г‰VT”KaцАB)2Д3јгЄОњёгсвгщSмъОt}Љђюерп>‹ž+“ х7Я†ф>ћ‡g^КЈ*ЦО’ЫєM‰hЗ~HuУм9n=…cїfњь^W!yЩBТа‘’>І’ПЩHт!Š\љ.Tg XЯЅЇяЎл’Uэл‡%{ќФQЅ˜-HЖnЯtPQ#]ёЉ%ЗБ‘оАѕтQU€јсZЩQЕ~ ађj0zюš—’Рq“šDЂіu;љњх5kЧу>‚Ÿѓ+м™jДYN“ч0ˆђйj50”Paf…MьэБFЃЦын* …ЈRŽуЫЯfTй ?рb`љњn ДЫѓСDыx‘ЧчZЕ€Х w­ Ш†rЗŽЋђJžS<Ћ8ЃˆAЬЃo­vDZЪЋВЅЃgДЧ—Ÿ5„<-ф]ИgтЕHR“д.Uƒ’:эо5v\Ч3бшXт€С…~-ƒ’\ѕЭ‡m—­;7/ѕ5Х„ўНFег3ˆŒр`ї(ЈoѓA$vs34DЮо ‚С3ˆгЖјikkœЊпЌDў& Q‰sЄ@ЋчРr i˜ЙяОiЩс!с=љ)УTOKєВясЁеq8ўu:т$УТЋф* ЩjиьљЬцKЂH@ЅЄlќ„БЈa‘6] ~tйƒ˜Ÿћ“œдИДЏŸ–Х xbюx0Г“X‡XIЩbDX•ŒB eЯH№ьЕъ9mЊфkњЯЩЯU’x3aЬQ`с #™|єekШ§е1ај%iу‘j‰3^`Бr>‰ŽˆzAuh4!м­L" ‘яОђсщПьs`ы)"TC(+Vћ\=tЛгC"в7HЪе­RW+fk0о;s9^ќїжП‚G2E2,щуЭLH5:œx§Рж§DдBžNš‰еД{czћлoƒс8—žсХ&6>ї)Ь2оŠžЎ•Dђ[йіђЫЋДQQШXЛі‚лQсїырsюьxПfЙзnG~iŽ _­CмЕпЈ эОhј=c(їпnї?JЄРВЄdnIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp-neg_16.png0000644000175000017500000000167211733011756024272 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<\IDATxкtRmLSW~ЮНЇН§М§Д­;А2Šsj:ƒs(ct[тGaћ1 ‚F?мў,YтŸeт4›1ЫЦp‹šИ,s&jЬтВј  ДЅ~ДД…тm)эmякšjт“œœ<'Яѓ>я{ђ’Ў'Б ‹­ЫмGю<ћ/vЁЎb#о.ЏУсЫБђ^/^ŽяЏ}‹еЮ5ˆЯ И1~хр^ёXљш‘№lњље-П|Ѕ\‰žvT—ЎСюпЖ#СЎ_€Н-АjmшшСHdо№0<ЗA-!шђўŠцЕЭh(п>8:3ДиЂЕРlб!О‹ўЩnh t:5ž€У{Юw1—IтЬРi0j#hg1+‹ Т^ŽЋWnж.кƒЪ‡н‚Ќ&ŽNџIT•U@ЉfЁаœє~ƒ?ќЇАГzh0˜”XтЈBgА+\•;šzъа7uЅХ рЬ„ійK qЉ\b-+їсќИАс,c5a3™ашмŽ>ѓ6Рj0cЉб­^—c5оZИeжWЁб(`выQbtтЇ ?~§aЋЛ•nАечк`рP•ЁЅфЎLw`НСЎЋŽзМіN“I6•ќrшЈ ,ЁHdq%ˆўїГ€—<Ž>њфŸёБвжЎХЭЋъ6Uк8ўЯоKчк:?>оџљ™F’MэХ<Ž€ј ›™DlдƒєФ@ Dgƒo<џм…ц<вЭeњ&–cЪмCR,‚Р_Нq‰№›ЉœЛХМh.ЧпЖП5щbs§}HzЇ@…„šHЂXєеpŠО˜\8сM‡ІюњW)|ввФgфGЫV1JўN6ыЫыŸ§A!žr™й.ˆSЁc‚ОЧPЮ(Qк.eХ"0ŠШ\ТзЄУџ ЮђT@ЖRДЃIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/state-sync-cluster-group_25.png0000644000175000017500000000233711733011756026037 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкДVЯoEўfvз?жБИMšЕATЈ€RŠˆP—†SФ*7NP)СЁ\ј *!!Žœ@ "бТЅ„TкЦ)Дj”пMЧБз^{gofз‘U.n#=Яz~МoоћОyЛ‚ˆ№7ЁA>њљsЖЗивlфкa4B№/ЖlW?.вйБу~7œ#Н) бP€Ї^Йк O=Х6ЪЖ7pќ ‹j3D% Ќћ!мЗ8ЏBЧ9˜жZcoЙmG‚|ЪA.Iа.Е'Сž%?Э졘љBB€AœН€Шіƒ2‰ˆ(=A“мG“ѓ7нcЭsЬuDќGOHR™аQ$- ›ћjœЎ>ŽdШшuѓDиє ‹5sŽH№д]цeУl5ГxЯѕэMБP*фЇгНRц т˜пЌ#уHHЌГSХ (ЂOДЃЫKXzв ЌDr/H'œ5ЃЄD№С5JNBГ)JV6!‘O8(2Шѓ,†^ЁЅIоп BlБ@.ЎјXЎЯ šЪ8f/$і'…о'–=JэџыrљЄ…~ЦьЯицє‘‹@ƒ%8]9Ч2ѓGїйЭY&­’ЊчП](УЁеОЄкTЦVvšшдшЬJьOKd{ШЕ 5pœ.ЫХІЗЭ!ХˆBtмјŸOчIFщРЅХИ:* kЕ%_™;ЃbtНЏЪBОUHc~d'‡ч{˜]јkх5МW4Чx+Ю=JТnыX˜ #dіaNъ#=–I•-ШЌ)sJІя5А~ьILŽП†ЉЁм­­уХYbцsœОЯўjёЅо, <Мџ'7 ?№…sиs/“ЮМB+-тЁM>с„ф#Я%г8”­рžПŠ•кMдE}§dщЖ5ЄОAЎ_ЂŒ“U™BнLИВьdЩR;ф2XСЩЁЙgЅoд3Кя;fџЎЫmрGЕ#h”ЖmхkъEв*}{/ 22Š[sСг&€QgжМє|БSНкz9^ЇП.ВВnяжЎЎпеgDчп~Жћ–МУv]іј GKјСгебюЦѕ2ЉГGЉљйКс? ;ˆє Нг—6IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/firewall-ref_25.png0000644000175000017500000000205411733011756023507 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЮIDATxкмUKoEўЊчБOvШ’lŒIД‘eyЏƒрр(п GK\|@ТВќ ТќЎмрbЫKH+B|X)т€d;Z‘HVВ{—}ЬЮLQн3cж ‚ШДTг3гнU§еїU713ўэІ№ДџO[?>Ј’ю>{W,#ЦY†@7„<с‹m‰}ѓб]~чLAДгфЧ‹чв д €vРhћP?vй•Ё—ХЦФЮDGИ^ЮЂх…8і^ˆЎє}вю‡а8/ЅЩњЉ{6)&HPL;(ЄкЅіDЄ cм~plЦŸv ФљGФ‘сЦ<ŸV…k š 9Тп­ЧqЌyŽЙщbќ№ХС@&4Š”Ѕ`KпŠгu^ e чž=ЦN›Н‚CЎLA'рšLЛ&і›ќГdЭцQŸпЁ›tнМZ@ШЭСqЯЧіA9Gс)WЁ#Nё?{f'” ­•(бAшѕnъž}q&šЙœБбаj5ABГ(J–vZtм• Џ‰ђ2CoK;SФдїC тЋ§і:,cЄQР ŒcёТt!EzэЕ9}BќНŠ) %‰YЪйт,с!rЂbш`ЎЄЋрXfќ•glŒ,“V%[еу_ьљ№УЁ•T† вђcћMƒН§}[*\Ш(”Х.g-(8N—eŒу щm3РHKDŠ7kб_hŸcнцы§БXyм9№ёkOсJŽ0œUpD’)‘d_Ю‡нЖ~џC­ќ№qПММŒщщiфѓљХюП™СЇї:Јф-)дHa]!"Ym@ШCР ыЪМпk†зэ?лЇгСьь,VWWO§wтТЙqЩA^Rb+>I™Сw­ѕ&Ѓ(%;VPјВЁ<МєШ)МГГƒУУCдj5ЬЬЬœЎмqжŽD  BчўyЉЁ›n””с'-›ЃщNlmmaaaѕz§ФщЦЦЦЧЧБИИhО?љЖkњЯю{xNxИ–S)фšZŠSІЅЌХAО6Aжзз177ЯѓI]ГйФццfђљžиTЫчёњ_Ќ…і#!ˆ№P’њx6­Qk"хQIйL-82ФOLL`ww7Њ зEЅR1ˆFGGБЖЖf ‰арnUIп=oˆН%6)VЫ_ЭНz^сѓ’c%вщ№№0—Ыeсээm^YYсЩЩIюїћœДD…g1C|"сЉЉ)TЋU4 ,--СЖэ'wЧ—J%ѓ!ˆL???ЁЁЁ'vЧгрећwэaNЗ§.РjдЏъуZMIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address_16.png0000644000175000017500000000113211733011756022551 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ќIDATxкЄ’ПOAЧП3;ЛЗЛмmИѕ=s=š;Ьig@-mlT ;ьќŒЅЖЦЦXYhдJ)№H, (ЩiС!Ф„“ƒ[лРБ?žГЫ™ žТ+цЭ|'ѓ™яЬ{Œˆаwif0єƒYЗ2ЇO>Z­,S8˜ТЙЏку­Fѓ^ёZБ:q;…нС"РЭЛsT(кК€ЪЋГьЮј йiBˆ3МоФ—5Ќ§pGъя‡^ю№hШі%0аo@7еX,’АSЧmўzбЁ)‡„{ьм ЄŽІ^`OФ ШлјЮ Kы!о}ј‰‘ ЩыnXУОЛѕЄ+­AЗдНч!ЂЁж№Pw -ŸbБ\ѕ№­СНЏ™тbЖдSPUЙПбъ xS^УgиXw\~шТmАNuУшеЧ4CHw„Й‰E0†оŽ€ШКоХС•**œyй3=9Ё2_зy-€пvј7@ОпH*qN˜’ІЊXоє ќ{р(Ф?#0&k-ВъH ^Ы—ši* 7§pЄпЪ-]Н"+1-ЫŽЅJclЛще‹ш№З ЭЮ6тF:LФ2Cхѓ2MЖЕб•Љсчћек­ƒI%—ƒШчЃљГƒhПАlюЬŸЖMДsЩ™™џM WЋб§‰П ЧZЯd IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/compile_25.png0000644000175000017500000000211211733011756022553 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ьIDATxкbd x љјјД™„џ§џїюџўѕы*Pюџ#d yK[;ЛR-]‡? Оyѓњџ‹gЯЮ<}ђфкчПUџў§; Јцй–А03Л'&ЇLQVUSЙpљУе+—oмОqН§чЯŸ;в˜‰ @€› 33“sJjкLEeUх#Ч1<МwяЮх ч€RGШ>abbrHHJ™В`пС яп`x§ђХ^r-`€zGЧЦNSUWW=pшУЃG”•”•d€r\дА„гвЪКZGO_dСУGРX˜™2((Ъ х…ЩЕ„J ВВВz_Мr•ѕёуЧ ъъj іЖЖ NŽЖ ооR—/]–ИџСa кo$[Œ{3ѓ™6vія>|~Д@€я•„˜ш‡я_??ЖБГcrswг;wюœФУ‡Žl‘ Ps]SѓџаЈ˜џІжЖџ•UUЗ“œ)PJˆЕУТCЖо}pѓџчЏў?xtїПНэ" И)v0}bЎgh4›“‡Wї?PрёН;Ыž>~ЄF)4,dj[g‹‡„˜$УлЗoт“иАежЗWљкk‹эФZfЉЉЃ{боХэϘ„Фl ŸM^1($pЫн‡Зў§ўщџ{7џyџџПŒнўџІЎ- 7~џgР……-PSО!;{–ХсEPанКsѕoѓёџ—нљїd‘Дэўџ†Žu-ј,a$1Ё:Эџ{N˜˜•DСX^ј?CИп!ЦН­ЋїЖд kАЖ=†‘ёkŸэл ўј–сюk†{Џџ3€и+692М§ч\hWкALŽЧ nМБ\"С}kпэНћЯpя-{ќі?УЊЭŽ ˜<Ы}-ѓz)В~zІКˆВ_п{о~†GяС>сG@­кьФ№™ЭПШг,gE–€РпL'!ж+‡nЮн їб]`а=~џŸaЭg†яœЙnFS)Вўфк 0]8zsаЂї р`ЛћŠЬ^ Дш'OH–Г~ЪLŠ,k)Всe8sтњь= п1€}sш+EkЗК0ќцOуќОn-E–€[xЙ%зп“ЇЎЯк ŒFАEї€>z ЦЕл\ADБ% pчDЧяЃчЎЭкLi с Я= œп6іRХНЩџп?нdЦўѓРљЋГЖѓЮ†I…{иОniњЮPBRŽG/‡аСлжьТ2vЕœЉџ>œіƒ;Д\ џџџŸж Р^хЫMлФbIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-custom_25.png0000644000175000017500000000304011733011756024074 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ТIDATxкЄVile~О9іъvЗ]лэEo)B)Zci@ ‰ќа’51№C%Ђи?BDбh01Ц$ *&D&HШ!жPЉБ6‚iKУБ-­ =Зэž3;;ѓљЮьЖХЕ‘7ћeЖћ|я§МяœsайУo—=ь_qSў GF˜љЧ+яšП<4„[eјзePхs‡УЁн юt:Ÿ7pџђv4mЊЭDEžpќУ.ыЂ)&ўhg#ГёІM‹I™>ЬŒœ№нЮЫ–І<ЧуЉЉф,CмаKшШrŠжЏ З,Xщп†OыѓЬ#ƒ“Ю8‰щЄЯЇюРа4 iЈœ—q› ТМ5ЮІ‹5ƒ“ИЇX‘šъœЅЭЦT$3‘ђ™`gуІОщцfыO;)xАs•ЁŸmGЩ’yДD2vJдЩе(’7/Д/\љд˜ЃŽ‚жoДЉaќoЋ]ЧЈ{`ЌЏmћ6cqгЋ](В мHL€ 0Ÿ =R…’кзXнъ͘Ћ9Ÿ žRƒКM*Ыє!k7Œњ0жŠyBЏ –So4ОЛ у§?Ђё†СnыЋРdžW`ГxъGRQ)&ЧЄц_ИЦ^<ПM€`QпІ‡ё†>h\L Gшю"цbFŒџ”МЂЗHљBЃ}>y9ђf‰pД ;);йЌ=| х#žOвяиќeDй+/ьRКZ %ЕS‡чљЖJqН\&8йŸЌšВ‘0Lя•48•Ц/>8ъ?†вВXОО6xoдŸїC‘ЬgэУРxа єёјСœЉ”ье$*УBЎb‹TРђє ЂѓЙ …C*Рc4\nJ“KхBCѓ4nЄšЧ­-;!ФbˆйнpљŠ(‹qРщ’Q@ ё ЉbvўGюО1Aі Л}k]Я‰9ЬџMƒ6dд‡nfc ЃЛ\хШKкФмŠ†tЭu*Uзqˆ’!++ъZњфiiЭі ™-#РсЖњcФ'ьЉ‘оњхь:Aђ5ЈСˆ‰‡­ZьБзˆз­E(3Ыю€Гoјњ)бкa:fэ]jVRн#Eшќ>€([=ЁYЂэKЭ–ьuМћ‡ЏЄTˆwЩЅм2hЋ’@Эі“М‚tŒ‚ }’C(дЈ‡PDkџњ2jї 2т!:Q†Љ4'Д^$“qВфѓ_r~G%ѓІ!ЊПш&гœЩfяє1"€‚žЗЅЂ“люq‰;Ї\D„sŠAѓAМW2Kг,#Э‰лNпUња™Jj"ЮЫ—О/zVл”Ф™д|&0Э3чЉє€DšЁю/*žhђ<д,#<DˆA mš,ŠиыЅЫd\$2dQT)Ъс~@у#zxєi1Пj+Оћ„ЄѓOЈd‡хRД T)‰]I~S.dЪ:QџVКtbњ;€тjsБRфФ&N[УEsBяhЩtєТEG]Џ<œ^!ˆЙkix*Ф85НOаЄрмТЫ\СыLb-ФК][YэщФЩTqј’DЌ+BŽ—јMЅЂwЂ‘є;9IЮb2ФXˆ2 ЂИр|&ŸчКЛZ›ЌGЊхZTs_JјЁLЮЋFЉ|еѕ:JъEєžыƒЁkgEoбcXYœziЭY„Ъ† ж…ˆцСР54b”Эе‰а„[—УV1‡ЛG,Мgjy№ж‰цœ‰%’ETŽ0в[oб pd@ƒwГ…Wѓ‘Є!Zš“МU§/щo–A&\"5IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/rangeaddress-neg_16.png0000644000175000017500000000050611733011756024341 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<шIDATxкbјД$сџнD&0Б€›.ЬRєїMчџŸЇгР@‚иФpa& ‹ЈsУƒвJ0Ф†бшb8Ь)шN%фt/|.Щњ}>УVFжџ іН$цџDћdЪ–џПХџ?`њbc3С@OQџТ06ЬЅ WТ\ wСЇтLАЭ bƒФФ’еўƒ0ŒЫЅ`3patчт4ЪBжˆb0yЅ›Nэ(IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/library-neg_16.png0000644000175000017500000000166111733011756023346 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<SIDATxк\SkH“Q~ОoпццЖVnšKmйХАa–b”Z?Ђ*”aw+)щfдŸЂњaфš™й ъGEQaQ–ifнhZ™kкJгхšцццtпіuО™]vрсРсyžѓ>яyХqF–l‡!+žр&† Џп0t'”@‡П-—ŠЄoХŒи\•/Љ>яЙЂ$ЕўXф‚šP:Ј‘ ЄЛ…ŠЅ"ЂІJURНtz–П }Ћрњ“жŸ{OZПФ}a—ъ‰ˆXAш:.9(ф xHЗ 9_i­СТXћ§—ээ‰+яy’здє]ЊЖ~!ЎЛЕЇmymŽ\јШ›ї*‹з1џхƒ9дАgRёIEЛФ?)ЊlлLfбь(IЏЫ7jх~“ЕцuO%љЙ@@`йЉ#=P]\u™гч‚тsyccE э˜-љёІХщл]ajА bќмф– ѓS;#@ У—zŽІ’’УЃмФЕХЗ N‚D,Єж.ЇV˜Цк — І;EE[RапоэВv*ƒB5ШяЬћŠ 4 `=ˆ#"№рp=ŒRVklTнњmpЖЕСчvCўЎІVю…ХМ†~i*љEkу§б^ЬЭЭЉ.ЬbjjЪn#!ZЎ"ц•х;ІўГS''_Wэ~љђЋшяяWkTЋUЏ\.џ.UЂhJп)nѓк]ЗkS‡~Тећ†mлјѕњоžЦаР)ХцЧ[7OМ§Э[О@ы]tэќь‹ьтшKтыЏОьЪЬsО€Ѕ[‹Шїг#ЧVžЧЗЏ§@%"ЂœЕ5ЧWЩд‘‘ѓдrЩОLžОк&:KЅWCOпм9~уЦu­-)В ™*Ж1u’b7qЖuаRlгб oќиШБэ-2Ul`B1gЪьь;’Цщ~qіЛkдLЃ˜єфЬбчдГ”УЛпЯЌЏ%s —.Н,6NК”"}:4ˆуЧХ•+уŸгЧвЗД<імЁlЏуЗј†!ъя…ы„dAqšЊпZmWLЖ‘з‡њЦƒOсєƒg№ХoŸ­wWЯG+ЊЛ::/ЫёНЈІ,фx$er–@Ц7эыFšгКиRћд6mk(ЖЫџ­н•ЩВг8yфœЂxњ№IxЁ‡O~љшџѓЄmŒRЧНjU_‚@OŸfuP  5e@удJбЊ9F€šп; ŒŸ%ещ%вюqkьЯМЎE œ[~™Њ ‚пё†тœ‚’нcrg\Q6;рСeћи˜$"ф-вюiud8A_I 2WР*д‹Jь}Sлcb^3Žsъ ‘ ŸA жyKУМ{к’Ё=“s0 ‹є ›h*ЭГр‘ы!YoмЉ–FŒ{Њ„MQlceŒŠsъ №Ћн06<”ыЯ—т ћRмкЦкMœмYJЦ5IЅŒ…žfDЄЪц% +ўиє%gf `0*еVМ)IHЦ#Aq,тЛH62nЄN„Q %PюŠЭгжOзЎ)ф$dУЧNь•0J…C (кЛ'Щn˜ <ЃЕ< ЬzŒР[Шtгfн5Я4ЯИmцЦѕФ$ф а„>‡ 0WѓЅъЁ8§Ђ[20йДЕфйкŸ•Іmd™ ›TКv\вф8u8–в‘$ЈЬ ј_XјyЌѕŠ'Ѕ’Šг/кЛПџГŸљ ”ю,чy8*{x ГМйE—яЁe ш#4kм{ šзтљ6wЪИ{(7и<0xЄ*ЉW=›§РWЫ єІЏ3PєЇ:gB&fЈЫ&)i|зŽK•еЙЖЪfЦ Œ№‰m6‰лВеzРр>!РЮєBн ?sхHŒг/кЛWШJ‡I€щЕЕо!pdП5&œЬЬGij]%бeДMа4о?O†xZьzIй’ a{Ћ—§2jŸЦ(№дАŠіюƒ=Рf‘39UЙ›Б$0š“6ЎзŒaYicб0c\Г‡уˆ]ГЅ@›ybUV є§Цv}зxЦхž(t}Яї@„Згb№dяP”wœюlБк4enЩ”VтjО“(щњљЖЭ6@CQœG8ћ НLетў>(‚ьkH][йьјє ZЙQЌ%R@бо=К^І‚ЬЇьїишР@Ѓ‡Ьd Y 8•g;?XЖ€їш7œ|~О†WЏ(™+;j|dCР§bћ”шJdШюнЎзп Ibџ4ДбU A }eGЫЖЖМ9hњ~OМ=С3ѓ%€ЏhНЬЭ*ЈЂTeч>eO $!2#žŠіюЩHцЪКњ&КќfO,x+u“7™cјо,xќƒ'UŒ;Ўek% "шўPѓТ>–к$“ЪС ˜дЛRoМУ/ЖE6˜y6ЖФYZk“ДѓыЋGОŸ„<ѓе uйШ IРZ \Ќѕ 8Е;_ЛJиEРž ˜дЛ^/6Ўс­ќZGlЗgЯ^іd} зƒ„=СG,u‚Я@WBБr/x pNN…ЬйСЃœš‡PДwœ* d{+rйяюdн5ЦЬеHB€­…\S€Л–}зH@рtJIіF {—˜=%&fјЭ•_ДwЎwїН§|ЃЪжй// šл“ywп˜cёZ|‡€ЂН{ўlёƒK?<ПJ іюС1QРK іюkпПїhЌеДяы“=ИИЩgЖ'viŽЏ9<ЌМQѓфд\ _ѓWхн№пeWкэі№я$ќфЩyј№сЖпY[[ћЂМBяСЊ}љŸЧЂЃ–ДZ­} `м?ЦУR/Њзыf‚8:оН”­вЖЖЖЌњпUŒzo177'gЯž5Nч+Пд№‚wŸ/%ђІп”‰Є|цMйдбЮгZюњд`ђcqы(ŠJ члWЏ^]џМsчŽ™XГђюѕ’ШХђЊМlШbКnГо@)”—–$‚—fЉхоЛ~­u†с"і—>йиијD||ћіэПLЄ€YxїЗЪmЙXY•sњ9j?В/(ЊеЊ ž-xпїwРШ~іw“Ћняуи[ZZК„’јо­[ЗОљьйГ??}њєПЫЫЫщЁ0 яўЖџ?Й(_JЕ…s :ї”ў`cЮrх[žќ\Њ"W?ЋT*rъдЉ Hјpaaс—8Ь7Д+(`Жо}ё‹e}ѕ_ђd™ОбhА“ялёнSЊ'ЛUСК1яl­;EŒ}њtyпkУВк+|іЗOДcЛєо$‹SЭ§:А17ўMќ$х7я^И6ЧЬЛNРчџь+ЫшкЕkп=ў<Льзgхн '`’/?ў<С ЗЮlVо§HpцЬ™€ СЯЪЛ юнЛЗP.—пОpсТЛыыы•/^є›—4# эcEyїЂu˜ппП_CОРˆќrПdН{Ѓ‘< Šъ›щФ?hчшнiT8ПUюнQF‡ђюVIŽСБ x№рСЗрЯ?№їщннЫQЯКВМЛьснЅлэЪццціъъъЧѕюE0V ЌЌЌќ `~пl6KђŠНћЬKрЪ•+єO‚щ{wћ3д№Л§МћЬ№шбЃOи ЄjђЌŽБфЌтёGЮщн_i<ьRdІІu]-ЏљђкрЯт&ЙdOpu”ўЯДšц‰N8!р„€C5СЃ<Ж&YF5зЗџь|в ^ў/РвQФђД_~IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/deny_25.png0000644000175000017500000000274411733011756022075 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<†IDATxкŒVKŒUНяSUн=нггнУ3DQ1ВвА1!†ш‚‰AQ‘шN#e%ЎмИRтТ•qЅ pЁ‰QTт$qСbHд№цгtїєЗККЊžчОЊn q‚“МyЏЊ^нѓю9чоjaŒЁеўŽяxjГ‰уgM=‰БEzюЌ“+vНЅЅЫQп?Сь9ѕVГ;ПZё_ _яйЕYj§ІbgФF[œ8&Г61­6љЭuZMZЉзЈбэЬЦJ} Аїљю•}ћнLі|&З-+9BХ!™žOqп'ућD§>б РPмiQЛZЅЅъ2-њўИћёлНСЩUANО~рPОPЂJ~œ”зйІ‘Ю S`К]Ћз Эў76^s&aRШDˆивBJ‘тНЉ6H&F`НђХ c #3369A2", " , c #879BC3", " < c #6E6E6F", " 1 c #164875", " 2 c #4F77AD", " 3 c #A3A3A3", " 4 c #B4B3B7", " 5 c #6A87B7", " 6 c #6C6C6D", " 7 c #A1A1A1", " 8 c #B2BCD6", " 9 c #9F9F9F", " 0 c #4A6287", " q c #26649F", " w c #9D9D9D", " e c #9B9B9B", " r c #656666", " t c #C1C9DE", " y c #999999", " u c #AAA9AD", " i c #6F737D", " p c #3E6EA6", " a c #A9A9AC", " s c #3D6EA5", " d c #989798", " f c #758EBB", " g c #979797", " h c #2B2D2D", " j c #748EBA", " k c #175D9A", " l c #165D99", " z c #DBDADD", " x c #949394", " c c #939393", " v c #A0ADCE", " b c #5C5C5D", " n c #919191", " m c #395876", " M c #8F8F8F", " N c #114673", " B c #8B8B8B", " V c #21629D", " C c #898989", " Z c #878787", " A c #505051", " S c #858585", " D c #396CA4", " F c #838383", " G c #547AAE", " H c #BAC3DA", " J c #C8C6CA", " K c #818181", " L c #4A4A4B", " P c #7F7F7F", " I c #7D7D7D", " U c #7B7B7B", " Y c #9DA8C4", " T c #7A797A", " R c #C0BEC2", " E c #797979", " W c #6081B3", " Q c #777777", " ! c #295173", " ~ c #1D609C", " ^ c #757575", " / c #737373", " ( c #EEEDEF", " ) c #727172", " _ c #6C7076", " ` c #717171", " ' c #888FA2", " ] c #899CC4", " [ c #346AA2", " { c #889CC3", " } c #393A3A", " | c #5078AD", ". c #7F7F82", ".. c #6B88B7", ".X c #6D6D6D", ".o c #6B6B6B", ".O c #E6E5E7", ".+ c #27659F", ".@ c #696969", ".# c #676767", ".$ c #72767F", ".% c #767779", ".& c #C3CADF", ".* c #656565", ".= c #AAAAAC", ".- c #2E2E2F", ".; c #737576", ".: c #636363", ".> c #636E84", "., c #616161", ".< c #5F5F5F", ".1 c #A5A4A7", ".2 c #A4A4A6", ".3 c #6D6F70", ".4 c #5D5D5D", ".5 c #A3A2A5", ".6 c #5B5B5B", ".7 c #A1A0A3", ".8 c #6786B6", ".9 c #595959", ".0 c #575757", ".q c #AFB9D5", ".w c #23639E", ".e c #555555", ".r c #556476", ".t c #9B9A9D", ".y c #535353", ".u c #90A1C7", ".i c #245E95", ".p c #969698", ".a c #4F4F4F", ".s c #959497", ".d c #949496", ".f c #435C78", ".g c #4D4D4D", ".h c #939295", ".j c #4B4B4B", ".k c #909092", ".l c #494949", ".z c #9CAACC", ".x c #C4C3C5", ".c c #8E8E90", ".v c #474747", ".b c #C3C1C4", ".n c #5B6775", ".m c #454545", ".M c #F6F6F6", ".N c #4672A9", ".B c #434343", ".V c #BDBDBE", ".C c #414141", ".Z c #F2F2F2", ".A c #A9B5D2", ".S c #3F3F3F", ".D c #B9B9BA", ".F c #8990A2", ".G c #366BA3", ".H c #8A9DC4", ".J c #EDECED", ".K c #3B3B3B", ".L c #818083", ".P c #6D89B8", ".I c #6C89B7", ".U c #EAEAEA", ".Y c #E8E8E8", ".T c #353535", ".R c #AFAFB0", ".E c #333333", ".W c #CBCEDC", ".Q c #315573", ".! c #96A6C9", ".~ c #ADADAE", ".^ c #E2E2E2", "./ c #C4CBDF", ".( c #6D7483", ".) c #4170A7", "._ c #ABABAC", ".` c #2F2F2F", ".' c #7890BC", ".] c #DFDEDF", ".[ c #2D2D2D", ".{ c #2B2B2B", ".} c #DCDCDC", ".| c #818286", "X c #292929", "X. c #D8D8D8", "XX c #536787", "Xo c #8499C1", "XO c #A1A1A2", "X+ c #6C778F", "X@ c #9F9FA0", "X# c #25649F", "X$ c #D2D2D2", "X% c #77787C", "X& c #666668", "X* c #9B9B9C", "X= c #CFCECF", "X- c #636465", "X; c #526372", "X: c #CECECE", "X> c #5E6E8B", "X, c #CCCCCC", "X< c #587CB0", "X1 c #959596", "X2 c #CACACA", "X3 c #5E5E60", "X4 c #C8C8C8", "X5 c #C6C6C6", "X6 c #908F91", "X7 c #2E67A1", "X8 c #C4C4C4", "X9 c #D5D4D8", "X0 c #8E8D8F", "Xq c #C2C2C2", "Xw c #565858", "Xe c #4773A9", "Xr c #8C8B8D", "Xt c #6383B4", "Xy c #C0C0C0", "Xu c #D1D0D4", "Xi c #8A898B", "Xp c #BEBEBE", "Xa c #ABB6D3", "Xs c #888789", "Xd c #878788", "Xf c #BCBCBC", "Xg c #868587", "Xh c #858586", "Xj c #BABABA", "Xk c #8B9EC4", "Xl c #B8B8B8", "Xz c #828383", "Xx c #537AAE", "Xc c #6E8AB8", "Xv c #B6B6B6", "Xb c #4A4C4C", "Xn c #B8C1D9", "Xm c #6A6E72", "XM c #B5B4B5", "XN c #B4B4B4", "XB c #7E7D7F", "XV c #B2B2B2", "XC c #888C96", "XZ c #7B7B7C", "XA c #B0B0B0", "XS c #444646", "XD c #98A7CA", "XF c #56729D", "XG c #74787F", "XH c #586674", "XJ c #AEAEAE", "XK c #424444", "XL c #4371A8", "XP c #5F81B3", "XI c #787779", "XU c #7A91BD", "XY c #135186", "XT c #ACACAC", "XR c #404242", "XE c #677286", "XW c #757576", "XQ c #AAAAAA", "X! c #BABABD", "X~ c #747375", "X^ c #A6B2D1", "X/ c #A8A8A8", "X( c #A5B2D0", "X) c #A6A6A6", "X_ c #A4A4A4", "X` c #A4A2A4", "X' c #A2A2A2", "X] c #6C6D6D", "X[ c #7C7D80", "X{ c #6B6B6C", "X} c #B3BDD7", "X| c #A0A0A0", "o c #B1B0B4", "o. c #9F9E9F", "oX c #9E9E9E", "oo c #676768", "oO c #9C9C9C", "o+ c #ADACB0", "o@ c #9A9A9A", "o# c #989898", "o$ c #5A7DB1", "o% c #597DB0", "o& c #969696", "o* c #949494", "o= c #DAD9DC", "o- c #D0D5E6", "o; c #929292", "o: c #2F68A1", "o> c #909090", "o, c #7C88A4", "o< c #5F6977", "o1 c #4A74AB", "o2 c #8E8E8E", "o3 c #9F9EA2", "o4 c #8196C0", "o5 c #4974AA", "o6 c #9E9EA1", "o7 c #6484B4", "o8 c #575758", "o9 c #8C8C8C", "o0 c #5A6772", "oq c #8A8A8A", "ow c #ACB7D3", "oe c #888888", "or c #868686", "ot c #8D9FC5", "oy c #CBC9CD", "ou c #848484", "oi c #386BA3", "op c #708BB9", "oa c #636D7E", "os c #828282", "od c #818081", "of c #808080", "og c #C6C5C8", "oh c #506689", "oj c #7E7E7E", "ok c #7C7C7C", "ol c #99A8CA", "oz c #767980", "ox c #7A7A7A", "oc c #787878", "ov c #7B92BD", "ob c #767676", "on c #BCBBBE", "om c #F1F0F2", "oM c #747474", "oN c #A7B3D1", "oB c #727272", "oV c #707070", "oC c #B6B5B8", "oZ c #3E5A77", "oA c #6E6E6E", "oS c #6D6C6D", "oD c #B5BED8", "oF c #6C6C6C", "oG c #B1B1B3", "oH c #6A6A6A", "oJ c #B0AFB2", "oK c #E5E4E6", "oL c #797A7C", "oP c #686868", "oI c #E3E2E4", "oU c #666666", "oY c #94A4C8", "oT c #646464", "oR c #5B7EB1", "oE c #636263", "oW c #646F85", "oQ c #626262", "o! c #A8A7AA", "o~ c #415C7D", "o^ c #185D9A", "o/ c #606060", "o( c #D2D6E7", "o) c #5E5E5E", "o_ c #5C5C5C", "o` c #D7D6D8", "o' c #5A5A5A", "o] c #4B75AB", "o[ c #A09FA2", "o{ c #8297C0", "o} c #585858", "o| c #9D9D9F", "O c #AFBAD5", "O. c #565656", "OX c #545454", "Oo c #526373", "OO c #525252", "O+ c #98979A", "O@ c #727478", "O# c #577CB0", "O$ c #3A6CA4", "O% c #4E4E4E", "O& c #718CB9", "O* c #FFFFFF", "O= c #6D7073", "O- c #4C4C4C", "O; c #194973", "O: c #7389B1", "O> c #FCFBFC", "O, c #8B8E97", "O< c #C5C4C6", "O1 c #9BA9CB", "O2 c #CAD0E2", "O3 c #F7F7F7", "O4 c #444444", "O5 c #7C93BD", "O6 c #BEBEBF", "O7 c #878789", "O8 c #404040", "O9 c #BCBABD", "O0 c #A8B4D1", "Oq c #BBBABC", "Ow c #EFEFEF", "Oe c #3C3C3C", "Or c #898FA2", "Ot c #807F82", "Oy c #B4B4B5", "Ou c #383838", "Oi c #B6BFD8", "Op c #E7E7E7", "Oa c #E5E5E5", "Os c #323232", "Od c #C5CCE0", "Of c #303030", "Og c #5D7FB2", "Oh c #5C7FB1", "Oj c #1A5E9B", "Ok c #A8A8A9", "Ol c #DCDBDC", "Oz c #D3D7E7", "Ox c #A3B0CF", "Oc c #DBDBDB", "Ov c #D9D9D9", "Ob c #A3A2A4", "On c #859AC2", "Om c #787C87", "OM c #D7D7D7", "ON c #4D76AC", "OB c #838B9F", "OV c #4C76AB", "OC c #6886B6", "OZ c #D3D3D3", "OA c #24639E", "OS c #9A9A9B", "OD c #CFCFCF", "OF c #506E9B", "OG c #CDCDCD", "OH c #3B6DA4", "OJ c #BEC6DC", "OK c #CBCBCB", "OL c #959496", "OP c #5F5F61", "OI c #949495", "OU c #939294", "OY c #385880", "OT c #C7C7C7", "OR c #5B5D5D", "OE c #CDD3E4", "OW c #909091", "OQ c #C5C5C5", "O! c #8F8E90", "O~ c #8C8C8D", "O^ c #565758", "O/ c #C1C1C1", "O( c #7E94BE", "O) c #BFBFBF", "O_ c #D0CFD3", "O` c #20619D", "O' c #496FA1", "O] c #BDBDBD", "O[ c #BBBBBB", "O{ c #848485", "O} c #214D73", "O| c #B9B9B9", "+ c #7A808F", "+. c #B7B7B7", "+X c #C8C7CB", "+o c #818082", "+O c #808081", "++ c #B5B5B5", "+@ c #48494A", "+# c #B3B3B3", "+$ c #2A66A0", "+% c None", /* pixels */ "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+% P P PoV.o.o.o.o.j.C+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+% P P P P.oob /oBO%.,o)o_oUor S FosXTXT % % %XTXTXTXT g+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+% PoFoVoVoVo/oFoFoMoM+%XvXlO|.YO3.UOaOcOMOGX2X5O/O]XlXv+# OXJXTXT % % %XTXTXTXTXT P+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%XKO/O/O/O/O/O/OMOMOpOpOw.Z.MO3O3O3.UOaOcOMOGX2X5O/O]XlXv+# OXJXTXT % % %XTXTXTXTXT P+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%XS hO/O/O/O/O/O/OMOMOpOpOw.Z.MO3O3O3.UOaOcOMOGX2X5O/O]XlXv+# OXJXTXT % % %XTXTXTXTXT.*+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%X]XwXR wO/O/O/O/O/OMOMOpOpOw.Z.MO3O3O3.UOaOcOMOGX2X5O/O]XlXv+# OXJXTXQX)X)X) 3XQXTXTXT.o+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%XbOROR nO/O/O/O/O/OMOMOpOpOw.Z.MO3O3O3.UOaOcOZXyXpXj $XQX/ 7o9oc ^O=o<.n.noZ mokX'XTXTXT.o+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%X-.3.3oPO/O/O/O/O/ODOTOZX:X8OQOTXA coqocO@.$ i iXEoW.>XXoh 0OFo$ONo]XLO$oi.+ qoB 7XTXTXT.o+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%Xz.;.; rO/O/O/o#.%.|X%O,XC ..FOrOB YX^olXD.u.H {O5ovO&..OCoRoR |o]XeO$O$+$ q VOo wXTXTXT.o+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%.c.c qX#Oj k k l l l l l l l l l l l.Qo#XTXT K+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%.*.*oE R R #O/XfokO:XU.P..XtoRo$OVo].)O$.G.+ q ~ k k l l l l l l l l l l l l.Qo#XTXT K+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%OXOXo8 4 4X~O/O/X|X>op...8oRoR 2o].NO$ D+$ qO` k k l l l l l l l l l l l l l.Qo#XTXTob+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%.K.K L 4 4X&O/O/XAoa.. 5OhoRXxo]o5OHO$X7 q.wo^ k l l l l l l l l lXY N !.QX;Xmo#XTXTO.+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%.EOs.- u uOt++O/O) _..XPoRO#o]o] sO$ > qX#Oj k k l lXY N !.QX;o0oB So#o@ wX|X' =XTXTO.+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%o9X u u.s nO/OD SXFoRo%OVo].)O$.G.+.i 1O} +X;o0oB So# e 9 3X_X/X/XT % % %XTXTXTXT.6+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+% u u.XO/OMX_ XoRO'OYo~.f.rXHoBoko#oO ; % OXN++XlXv+# OXJXTXT g nou =XTXTXT.o+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+% u u+OO/OMXNXGoBoko#oXXAXfX4ODX$OcOMOGX2X5O/O]XlXv+# OXJXTXTo2o* ;XT g KO..*+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+% FOeXB.c bO/OMODXyX:Ov.Z.MO3O3O3.UOaOcOMOGX2X5O/O]XlXv+# OXJXT K.oo)o'.0.@ S+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%.*.EO8Xh.6O/OMOMOpOpOw.Z.MO3O3O3.UOaOcOMOGX2X5O/O]XlXQoroQ.4.:O.oBo#o#+% SoBo9+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%oB.EOfO^+@O/OMOMOpOpOw.Z.MO3O3O3.UOaOcOMOGX_ok I.X*o|OL.7oCoGoGOy.= a a+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%.*o#o# Fo;o#o#o#o#o#o#o#o#o#o# ; ;o9OWOIXO.5+XX9Oom (oKoI zo=X9X9XhO-oo T.koJo+ u u a a+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%o9o#o#XpOPo6 u u.b :.JO*O*O*O>om (oKoI zo=X9X9XuX9ogogon -o u u a a+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%o#XpO7 a u u.b :.JO*O*O*O>om (oKoI zo=X9X9X9X9ogOU Pod.h u u a a+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%o9o#XpO7 a u u.b :.JO*O*O*O>.Oo`X=oI zo=X9X9X9X9Oq. ;+#+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%oV a u+%X0+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%", "+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%+%" }; fwbuilder-5.1.0.3599/src/libgui/Icons/key.png0000644000175000017500000000044611733011756021415 0ustar sylvestresylvestre‰PNG  IHDRѓџabKGDџџџ НЇ“ pHYs  вн~ќtIMEв§|дГIDATxœc`ŒШ)щџШќ'Яž22p2RвџяlэE‘Tё.&h#Lѓщ4eN%IIн@яbЌaГ`гpЅУ†сЧхѕ k=ЙАМ]њџ“gOQ Pё.fxќє ƒЌД мu{# ЭК л!.C1рЮж^Yi†;[{~\^Я№§оsЌЖsш"и(x:MEЁщЌЛX ``@„Хб8 ш…:=BXIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/both_25.png0000644000175000017500000000211211733011756022057 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ьIDATxкЄV]lUўю™нэўtЗ?P)а%t ‹БбbLD >H е'|№Ё>MєIѕСЄё'бтO11B4AЪдRЈ”JйHCл*Л;;эЬмыЙ3lУV‚;х&'Гwіоћя;чм3LJ‰ZFsї‰…ЏвїY^$ѓ*!FfзhQNЦ0ѕйя3<ЊU§Ÿ4‚чэЂї„9АщlХЙP nЩƒp%„Уќљ’=ƒG ƒљР†ЮPwhчFŠUћBxEуo%љО ЧƒM€‚ищ= ŽЋ3џ•?ˆ(yUѓЅLтЏЂ€tсГQ )‚џКKшFИ?ШЊЄ„k 8єоёŸ(&vYРЖExYUѓ‡3 ’$єJ9–7ЯdŽ@g-ZЎ‡мќXЄЗЯn~ikѓ“;ŸoAšфX›†M:м!ЉH2їІcyz§фЇgІ“uрњї}_OІG,ьxЎ—x6Їch|2€јŒйЯу?W„5їZЙŽQўv‘]>qіњrИs+2, т%HЮXwмЉл^ €­Дяжєдoї;ј ВМЃ#йwфягцАч…„_к}G,˜eРљsЬаЏHЧнпмyС:vZ|Х>№†,%}ŒЅ ‘Ђ§)0v’;бФCЂэ8Kd ЅhmЃ% ЗОЂsлMг]џЧЧКUžщŒтцЅ<ŠeqrжvЗD[swїš‰€I|%ЬЃ+яОЇоЏ{зH4ЁЛS ›§ЙЗ'л“mнXіЪ”Щ"sУ—двšж кr˜ЧГъp­~hѕ/7-kФО“ЈЏз№эcЭл' Ew;y8ЭЉТэS‰u+1žPŒПЄЈМMŒпc”q\!0Кrм+cˆ­рl"ДжџЛљQ ќВУdЙŽ 9МК=щ_ _ќZЦљ х9Ѓ аИžŒDбоЁВnкšвRЅ№fЪџ3dЙMАw‹€N4џžІrт ŒћњвzREЄЈ~Ђ}jЭ}rrПГgwЫЦw^o;xzИ„В`јхВK^SяHjОљД Ж—r?KЖšІGjQ]okGoOKž~њqђуіЎVŒЬP>($'ЉєЦ8œkџ ЕьяЪkФtтУг–Ј.ќQъ ŒМчюƒ(љи%‘x03|ЅћнcМHžЧU›еќЮЇGHppЌŽЯї‰™’tp‚ћ§\y­SЧЋ0и4ї†Q]§ОэŽ ŽЁСXаЛзRя8w‹>ˆNL*_!jL>xЯЏХŽ{нТ5OеZŒџ 0иE“$ШPyіIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-group-ref_25.png0000644000175000017500000000234511733011756024132 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<‡IDATxкД•mH[WЧџї5ЙILЂ‰šmОеЭХЊГШPмKW&CЈи­л‡Йcn~№ec8 FHЁащіС­аБ­ ИсXЋœЎ0ХI™Ѕ:ХК6Г ѓ%1šЦhnr“мЛso1ЋЏБТ8pяsЯЙџч<Яя<‡RџЗБ8ŸЊ>;ћŽbтыЋўЈСТ›Хˆ‚йYбw~c,К*ЖЯ]ЮџiЧЂƒюфнOџЪжЅ.Z3ŒЌРВЁе0Ы"‚aA–E€сАА ћ\ў%wрcяШѓžGљрьн,SFв/YХ6Ї"EВтFFЊ‚d3 EVААСшT(x$s#ѓУЁќЇ‰W]O'А?ї;Эл„ož*Б9ѕСв§^<›ЯƒS<8ю вьŠIЈ:. @\€ЩПєcŽЛБM]{ ‘W^Яz/='щeИМА…§xБD+p8—Ы…X,FfЩpиuhxгŠЬШ2|ПЙ@'пжгс,|=/0tЊ%ŠЂ'iА Ѕ§X–e"F0D А‰< zНmGѕK( ЫЦxЖQЃ‹li_‘SЭENбЦcGbH2ђš€$Ip/-Сяїcњіmа Cє0™Œ0&™‘—Ё@Кe2‹#L Д'І!žЕŒJ њeЄ)!œЪрqў–мnЈаp<ŽхРыxP4 9Eš P‚aPKђŽsВ‰iсQг˜о[C0ЅІ>F‡ЯЏ+Ш‰щp"Ч ГйŒііЏамм A гщˆМLЁФK?ŒizžЅЏјИЃ2ѓ =[ЈЌрЕЇј№ЄŒO^•Q_Кz/rВM№dЁћN Ю|v^ЋM]]ццц4Ž23ЏХЂф‹‹г5G6~О•ŽжжVДДДрТ…/4‘‰™(†o…`MбC@фЯИШa1НБ`ЦЭЊЊNтЛяП%Гшъ2ШВбБTЃ|).rXLЃ‡ž1A…Чјк.Џ!@›‘rФ&"ѕЬмѕ§ ‘DЦл№ЏqLЏпˆтмIvЪC˜tEАЦл!шXЌ{§уб Xuэыgт;QQ|xtttШ[|Њэ†щКФсЫв‰E ()YsћЎ’-Wo ьйъEQDmm-КККЖјwХ”4HЃE№†ХШ”g=zqш’Гc{vvˆЬЮЮbee###ЈЉЉAgggќ›Šiaa!Љ™ŠipSЯTWnњ~iŽŸ“ЩЩITTT ММmmmšohhЅЅЅшээеоїУ4сЭиз燆†­'m7Е6кГ†iXХ4ЧдџІћ^ЇjўЪЪЪДThХхyфццbzzNЇннн„((ŠТеПqm0L.ƒўп•бБ•7Hя“ІkqqQ{QІІІББyyyшяяз|›жеПb…`Z]gdщ§D[V­ВВp“ЋbЬВ[Йиг„5IMMХЙ2335gSSгеІƒ{ašА&l+ІЖћЖнEЛкП 64dЧй‚лIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/blank.png0000644000175000017500000000021411733011756021705 0ustar sylvestresylvestre‰PNG  IHDRФщ…cbKGDџџџ НЇ“ pHYs  вн~ќtIMEв * iIDATxœэС Т їOm7 н—cеIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/state-sync-cluster-group-neg_16.png0000644000175000017500000000172211733011756026603 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<tIDATxкt’L•UЧ?яyп{ЙиЎW,#Eд$`кЦ€‘+кhЋœє‡[6—У-mжVУ\ЋaтVвфƒy]­_nn$Д–.ХБ]МРн2P‘МљqПящ\Вж?э9ч9ЯyОпѓ}ЮyДЖRjY:лU‚юЖЏ‰k’˜JPcƒ%ёш‚џкЧEКЬsйIГы,Ч-u‹d2!У€`L.4&гфЪ0џн ˆ$eЉxЊMЧ­фMЃЄЩz‡цИPх|СЪЬЙхП1–фŽыDКУЎ[‘аЗћƒAЭSц C’h1jВ3џІ—’L‡†І==МФŠ‰–Кi7„!-k*–Hь3ВГ&Їцю-ХLwžуz_Х™)˜ъeз–яС]SGяз­DЏvтДЄXŽ›"lšи‹}ЂВ}ˆP0сЖJ;0ВЗ1ЕgэЫGI-нЯЏяŸІь•wpžjућзЊљЂКv—уp9бСaќжкЪѕ3gH„B8мnіоЯрЙ2vМDїСƒ,њ§ФWVЈИќ-§ц=ЃCМwwž‚yдu/Ѓrіь +‘`оыe~pp•шБЇŸЃчШ‘UАsг&Šч'›—kpхЭЦЬьm|лEѓь-В|yUѓ64T#U}КУБJ”Жy3*іMиKѓЅfфšЙ%l6……YјnЬЂ1ЗgќЧŽ5{Я_JY˜˜ 0:Šcs:Љlogrg˜IйKс“Йќв5DuљSдьЮ#?лХЕЁ›ˆЦ1ЙышwwњњŽџлa‰p˜™+WЈД?KІмˆгезЊЫ RKT™ UќVwїЇ?:D`d„Œќ|Џ­]-eЌ­cЧЈлјЁ,4е/sї–d—ї&ћцjЏшЕ.з‰њzVfgIЫЭЅЪуaлсӘ‘wИ7<Ь‚RVђњœПьЁdgёсhд6т›бHTыŠ‹Щ,-хОЯGEK **ъ•аЮ]'ONJѕ;г/ђHYФ"šќюŸ]?щŸJš ЊшRЦ‹З{{хhK‹rхЛIYь‰ŸO75Щh0(ЗОЙEК^MЗlЕBV~XўgSЯЉ‚цгщ 0cЊЂz’пТIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp6_64.png0000644000175000017500000001745411733011756023621 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<ЮIDATxкд{ ˜Uе•ю:УЇšЋ(ЊŠ™’0Јр‹Cl[ЂЦщЅЃAŸ>ЖšгяkЃ/ЦD55Ц mЂЂi1vcХH'Fe*Ššч[UwОїLя_gŸ[м*(‡фљй}ълпНїœ}ійkњзПі>%Y–EЧ8$ЇёaњнЏ№ѓ“њюKЧИяГїXъ1ЮЩh šлљn щNГ —œыjA_-‡І1‘Т{чЗщŒmŒџгџwЅcPьhWѕ{ДЧс,Їп[Œvк%hѕуД ­Eћ5кОQў'ДkFMš'ќкгЃ&}1кЕט7ї}mкЗаfKwОѓ1ˆік*чћHG…тхюZXєI”ЮZ4wВ‹NЈњю~єЃ‡|№AV‚ эzVв+яeы?8ЄQsA]Еѕ›фsKtњёnњЮWƒфQr?ѓzНЗ:ЯaOyу‡ЯФ•eR‰2П/nвЇћHмЗьŽ;юxы/О‡ŒŽ'+чюiб?јзпЧ’ўщ›М[~№ƒœ}џ§їџ|еkЉ•Б”5bЌžA““ Ј"ф—hЩqnКxЉМЊvЏЧуљžU єX!АА7faЪд3i|ЉLНžоЙ[Зn тZŒ…OfЌŸпЗ.A9hв)Ÿ’L&Вbcлi[іkФпG7>тёx„ŸфСЃЧ’eёќТ{ чђиcM…ЄБ`ЛЧPкЂ.hБkШ‚fќЙœ4}њtVРџО-C&zљ=nз1`B(‰ъkT‚Hѕр;V'ЈЌЌьЦЇžzЪkЋVСІС мЯЯкгfPIIЩ$]зѓ ˜ћQЛ1І УPЦ‹ bсмшћx.OМ–Ђ%K–мт„у1C€A‚›Жk РЊ†2з\sЭЄю!ѓыяУZхaй~`тўВSМ4ЃЄg ›ЭЦ+ЎšRїЛзSєрЫЉсзAaЗ_<ўXw" Бу3 эAˆѕ'L[й’ЛДxйВe•ЯмуŒЅ­9ћ;uXє“SA~ЌH@ЂgО]4| cаџ~dˆЖа†Яm;ЈбEѓ‹П„ЏьA=ђ1ЌЯNLНˆг^Иu*‡8щV:ёФЯ|€ЇЊ’mQ“N™щ!ЉgгО3f|ЇЁЁсЋ7_евГњ^Йp‰w„іy ,8гжА%ЌeR'@ГЙЯЪ•+OE—љЕщЧД~о†­SчЧъOXдиии^\\МТэvŸАѕ/ўўn.qя;‡tЊЎЎž[Уc…€ Ы<)ŽsЩyf$YОэ Nƒ)!<ЗЏ.єаwољ;Ию&Mгv>ёФo‡BЁћ/XфЅКr…V.їб#W‡Iю}ыН[oНus~lV. _TЄ"fїuи“›#Ыђщя4 Es+FЦШчVh0ЦЇќXlqмЋЅгщВœqЦї TоZ\я>ж§ОХ ЙЩъАж-hЕ~',ㆇq›PЉP{ѓўі-[Жl†ћЗYuN1ˆхWЋHпўђ­ОЎ“KплјЮЫї=rжYgнЫ4ѓ@Q(Аы†ХjЫeВ0 ~ЮЛ‡uЊЋЋ;BЬлпm’Т †Жi,џ'U3–5‡ЧJsьуР\l№uКЂ(ЧяGŠ}ПУCމ"Идp†:ct<ЌВHІh4кыї8$iј€Зм…X3 |ќќѓЯЗћє&DfaPšV­Bј б-еддд›ІY§^sŒЧZ3jzsпHзGАYп`ŒёxЌ|rO$Lмp…ŠюYŸŠЄсqљБLRiџў§­yЌS…ЎЦiХvРъšУЏeЋKN]ќ0kЃТOУa^ƒЃ8ХГ0eйXpм8ХN]љc_—A!Џт0ЩЯa!ˆиуofGЬ)йf} ~)MŒu ЧЄŸМQ1 OGKP8ЕуЪВpЊ‹іьйГпQаи (p›d№б‰gJЮ`’sохriмџ“[IyXeUЈфDLъ§f{эO(`јљгfмЇp>|olЎo LIŒ•‚ЪЗЗcЪСc]ЖиCg,Лч‡а­цlЬбРGu‘|дyєЗ'ВфюиЇRРцлТ#У _ЋVhЇ3ёЦ^“‚о#`5зИЯ(№Ы+Р6‚ЂJŸјрЉ §ъњщїO>Ж˜ѕWvЂOэ’“‹ЧEфч‚ї/m˜8С†ŒQzы–анN!УEШЊЅ?‹o?циЎОJ>зи/џ=}œbї=ўАдБЏйlЊVЁqр,џМмCOџюбЕз^{э=8}(YŸœИŽEr8)@–zA’vЬЊ ћoМ)8ї`Џљ§›^HгY ъg5Иn|ѕzзу>ŸяКeЄwБuй5ѓчˆ*6џћ„:еЮѓъVfќШ_›А|рBпˆы xРЉОлnљУњ_ўђ—ыpъуdГЦіѕh @~н|Brжц&cxВ–ЏЂњЎЛюšљ/7‡šO(‘Т3wt”AЗuЛtЛнёяUŸЗGЭ ˜PdЄТ~йŸЬ]ОOEšм№ЫЭ9œђзј; \__Яžз^Рl3,ДШ™BР–?.ђMr<````ѓЂ ђР 5Жdл8НJqžлМ:Хˆћ#;PpMaЯUMїAЦэNл…v­эЈl%\ф[оюОћючЮЈW(т?ТЬ^њШ w““џqщђ3›ўуj_ѓŸ?Йam–Ђщ#cLхлњ~ѓ›пєŒ›ућаЁC;чж(#Ючяknnnх>c0СсрІ(}жCў8"”oyxјс‡c.вю]1[q§й]ђ‡,]ѕbЎюokд—yџзчЋД~§њП0lŒ›ѓщG}д8ЅL>ŠѓѓЙІІІ4ЊВ‘Е чљџSЖk9M–FЄŸћ.l0?œR&шУ­?muюЫгJ|sпuз]їЛМ ЏГ{їѕѕ%'—ШGн;ЙDЂЎЎЎ&; Ю@.˜ЇLŸ—9 Л@}uзZ4AГbуvњ4•Ў\рЂеЋW3њюax”8Gy€bœў ЏM‚Rebcн“ЯPУзфЯюce__rМ:М9ГBЂзnљ ЯŸРУэээmWЮpн|юqЅЇnl2Љ)ёУ^‹Ъ%Њ@]Оl’L={ом{ЫЋз=њшЃРm<ЫK+#ЧЎJД{їюцT*ѕј• |пцд*"бЦЗЕЖЖ~Ш}pЯ‘4‹ѓN_Е|Šrъь*yјžW7Мњжg`ІG-Šц™`eOOЯwNUБX,цєСэЗпўGц>N:ЩГaпЫ/ПМbњєщWx<ž ЕЕЕг8а—ю_Лvэыїо{ячžЮ‚є3bl(g§š5kxеЖТ^нннН`pp0Œя}пќц7ŸХљ]Јё‹Pен€sхP”яЇ?§щsЏПўњF зеббё-Œ7EYЄ­­­їђЫ/ч•хq-њ7+Р9xЩ(ш|NёЮ{A!\№2ŸГРрwVŒй)‡oЇœТЈ№…cчћfœБhЇ+W@Iч™о‚ёs™Щa,ѕXїpiўї*ргU7жпВЁ3ЦБчE™ЊчЛЩ_Њ“'Єгo—ЩtђMEkўэxъ2Sхd№JMŽеz˜ZЛkiЦ“вЬYtгњпђHѕs(t§u4‡ IбЈшa|†Э …”ъ­&ХнA{Ÿьƒ5Мф _@fl%uЕ”QияиNуqе$_eфŒ KVю“žYмCRЂ†ЫЁШп=џŸ№/йй*БœхЧИЋŒOСЯљp&ТТЗО k‚ zІ^H‘иџЂlGU.ЄhяНdhЅƒkОFC{kЩ˜wЙEEЭKв 0пДъ(­џE{bфŸј$)О$5n^HЭнYђЉ{ЉШгMU%дЉДX=•)ОиKLBGVмwШOmэ'гL§VвšPє=‰Ђљшр(…vќi>T…jЊM/зыpПN’W‘TIG]н+Щя­EROPћю“ЈЙ=F.ѕOTZН–цtRЩdTM№2оЫPў (` ‘“aў”вбй4ы<‰|pузANшŸKЅЁ™TUюЁЊё˜)А/`7Ё—j+CЊ ‘dPXfjО’РДг eД,}XЛ‹’Ъ: ЅLв:BG6О(>g1ˆiР:wS2q2%rgSQф\*ž6ц}MЁКs0IXiцћHъM Šђ šЧaЂAг!`яЬ $*BpР”.So‚Ќ!ƒs|’™=IьWЩ`x"/‰КP?JфПцЗO*Шm %њS”ј+”ЙиCEea Ыa$ѓ pХЄо]›rYmЉЅY$ Щk.ѓ[ЪlЉS-AQS,Sь?гфЊUШ7Ы=МOЛЧџ№3ƒnRнsаОAуЊ*ЉъЂWc6PTВhюЗ!pЗјž…jD’Lкno[1›ТpL{0ў8(Е?FVWB<Ъоy1}R4ЖаъiОЪrэ•sjЙЙR”>.<<КЛ,h/ѓы“f’єœў|К/g oђjЌп:OO›/К 5Ь#z-ЗлeЊG§ў/ˆY‰И_“ЂРИmЈNPЈ7” L05Œ9X;нс[EvрЌ€'РЋmс‡@/5MПћ№{(Cц#Cr ŠЕкKчжЗь^œ~эЅЫЬLЪKˆЅЯъьLŸікЁожу}5ЎœvаМXзg+!ЩN- gšœ%›ŠЙ(зe<щqЋЯ'к2+рЁpщёƒѕB &XRyоТПOщоWH]AВ+HВ L'{Jy#SXн€Ащ>(Є ё%xš‰кяiHыVD8pЊsЩ$еТТž#ž<Є•ЙЕўЏЫб–(YхЯ‘бпѓ™ gЅ=Кj4јЇКipCк-ЛiZ єѕ)dФMВThnхЊSЄlwn ЅF‚75”ЅнE‘ВЦЬЏи@ў*aНАXїS•TYвIЕUiДЗ #яЕ‡ХBdž ЃЏ†la$~”@ )xJЯй;З.єѕ8­ЖD„FoЬЦЙЪDЮ‘&™­э—RWя^ЩHП*}œСШЅЙЮЅ”єД{žž4БФ+Eв™ьЁІФCŒcй;‰Д/љX * ЉеsFUv@zШгы:D!cћ‘zкщL‘Я#UК™ц~Й”f]™€ф№p@ЛЇ@’і?Eдј!ˆТ ХUUе4€Dуs >Г;Р#"^ˆМiO ЂФТљb/Y%г243гЃбЋоБдз1C№м/)n)KМ"„?ЎШЏXЮ‚ЈьGбdJЄї˜У g&ИЮi^Bњ Q})q_ф4џ{Ь Т”zї* CЎL/ЉЃЙ ЫЈў T#Ќ-9!аВžЌїž#sG#Ib™ƒёѕC$O‰’‚—dŠЉ„иХМРё"~iIg9чR™bˆžN@+РjћшuГ ˆfЃ?6мцysц5иxР9Ÿ‰Ѓ@џ;1вкВц EЎ‰Š§нТГь ?у„Ђ[ВЯim:љk<їЏhj?Ммƒ"чзвТjіz>ЃД&0РЌIRЙЯf|ж`ŽtLXžVnЈЫЎЕhжu %;%JпС9т{=NngY№Ќ)оиђђ†Ё^L}WXU4^Ъј~NIїЛљ—@Ž"Bб}БIоZ•BrˆвVzи+К“н”;Ќ“ сйЛXјШ?ј­%чŸ@Es]гЦ/Лl0FxС!:Е>б—Т ƒіуЌќћ‹І“ѓ-Лa]X4фOЖ'ИчWЇдyЫ;Щ7ОŸі%Љ§ ƒтр~ЄJЗ[ >ЇAŸЫy_Ц˜з1O7pЫrKa§`пWєОюЫС6+Чf‚%цХіЫV gRж[в 8všcЫВ›—/+NЬ Эгцгs’1Эb 4б•ћ№$Ќœes#WіSј_оп+oЕzMкr'бŽ{ŸM‚нйi…Ћ 2нЭŠtЧямБ5}*I'jIЧ­ˆj—•“ЗФMq ўN‘6]ЅЌC‡Uмc“"гNЗЌ@ђђ6RYЦ№гсЦЫhпЋџ6ІЦUV>п”е?иЖлйS2HУŸк МђАjЈСы[XКие“эЖіїяГьE)І юМW;[UAЪYЃKо{MЂ7Зfщ…Ÿultv\-rb€ЋчдїіšИ*жФљЙь œй!‚ JfеІЋJsяЇщнЇЉxЉЗЬuО”Ё@ЭFі%r„;)e ]ц_™ѓyНвкЗз*рXВж lJˆёЩ ЩŠR"ВPH€п Рd'MXE5UКMgmцЧљT5@ œ_ БЫ–ѓC‚ъqШѕ ЄJ ‚НuЇD={dЊ_ ‡ФђEAЁ}цфA`Gа+ш1[От!…sz–нМУ2rЭo6я@“VHEТњ:”š…Ћ@|€`€ ёўDуcюx[ТђЏJњ€`AЖћЇљSd6Ў9w[iСн]дЂ6cтѕMЎыYpfœ›ЋО^lь'€ІqœыЫыо†YBЈƒЯ`œ~„iѓм № 0А ЊьƒћЁи(Ѕ"џ63‘ф”эdЇФ-˜cЇСИќˆ^lЌЌšVF9ТыЮтjб‰JѕdIИ%)ЁxЈРП т˜c^‚ѕѕ.1ОоgŠsŠdЫwЉсY‹XЌQьB‡Orь3ЯgeQŠOќ2nузREnхпPd FќY_e*ŠќОMИ>{’ъЁ ^d"fЎє‹ы Ў,5сUЬ`ЋMœм:І еИzт‚ё`Š™"їГLћ)xe…‡Ьr^\1lсYW%„gжчeZ,V[8Ќ(%•ДђoО9.щД&uвmЭt2ћыiЮ•ƒё [пtB€НЂќ$ЂЅ(fКч;v‹> tNt9 l‡—ФQU vФŠ‰@ЁCШ нНГN™GЫ™vР Mў@Џ\Rћєие `ш);Йš…ЗW‰йcГќpЮFxЛkHЖI Sb=ŸЙ&нŽ5­ЫЂрDяsFƒymјѕh‹ЗƒІеUвьoJTЙX,|dѕe%№ЇНа kч{!Pњi1Бzь‚›чрђёVt%ох”4   ˆЩЄ#LшCпОДaeݘTШ *д2hHE%ы€'ЋЦT€ЇиНn0[‘ х$&>оЉ ПEŠxEŽ‹"Ž+—;і KМІ#ЎуМ:NAa№ЂD22п› JƒSЅЧбфг‰ъЮ–цU!##›ЮJH E№ЋaL‰]" т{ЙHb’4p@Ф|jцЩБќ<Їv(f0%p€ЧwЙLa3ŒђЂ)>$зNШЩ]Iђ†6Siqу˜ pћеяХЗfЪb'›€ž˜яJp*.;Іэ5Й|Кs”eЈ%В‘nгŸjЮ]хŸ&§˜ы ЁЕ”–г{W9vќgФ:ŸXр~1ІНй‚-mТхp>1ЯqЩx˜KtС!кp­<’ЂЪђ VДуi)nЊ1‹šо2Ч^ЫЙЕРО УжLЕчџXнVЦѕ=„7ЙAШt‹FЉsлІl—юl8fЪЪч)Й?{ЉWі’WтА8щ#й!РopŸ@ѕ!ЧЊЇp[кI‘–Ѓ,ЗwБШЖЖ ч^I*З*ШWFFЛa™eуwбщWџBљЦЙ;ЅЙSЃЌЪfЂ(†2Ѓџ‹цЈр~gЉву™Ћм-Йн'Ёќ=Яt\3@jKжŽsf„™]OёР#%Ъї1ЫЎ) •‡фЭ=­§BсESŸІјр?аЁч'Sй‰>лО…hjƒЩч€ўж/`U.љ˜ Fœѕ$mМШаp9Ы bс†R&UBdЖe9’L9Tоьn8wЏdaь–WˆЖЌѓП‡F–УАВЋLІ’C0ЌL9%Qžguь+z/R^Й"Xс€iJIщ9ѓ0ЭЫДцІy!НЁoЬJG–ў5gj?г:w‹”П@Н{ˆо] 4WA]1ЩцыЉMа8„ЊџGRт€ZЦЁ•HeВGx‡œЎ‚СјСшЫч8=В7“\')–уœЏPД}&э}i хRлЩ“IQеЂ"]~œTФК2;Я%ђMёќxhKњvw\‰*БNk5Ч;ŠФНћ6Ио€ЫчЊsз)Wч:єI @wЊѕв;йж‘‹RМ›!hЬjяЬtЄЈAyœЋд_FMёJrmїPIP‘и#d0ШqœУkэUс>`Б_>ЂШсм$–Я№ C%€чvtLЂэkОAZ)€:;›dШы;–Ф{6ВН0ТfФ|YЯj/ћ ŠЬ;кr5Ј+eвГК/ВаџАTm5'wТчДлЊўйёбМ№"md5%і€IEДѓ dэЬ2†U+_vБoМ$ež”tй"ьђьжмzо+м)jў}bЉk6аўИ™jЬ<щ”еPи ””Ъй`+ЋМ.˜іPkыDВdŸ:ЖВœ9%šЧVРіš–Ѓƒфё'}…ђщуžзЇюЌJ]№§нџKдњTКY”Ьšж Ы§IšZ7|џ8 зКь4(%гудwloы!^Ј/sП ѕ@ BЅl†Шн{‘Й:Œ 8Gir6+iЙЌlа?)^'pŽЅ]ˆОєEь 2–cˆШУ,eЕ˜BЇмEЁZсж €vi СЎЯ)дЯї"юbFŒZРВТяЉїАJнМ(8ZЋzГ+ћ(ў#ЦJА5џ|f‡‰єД9jˆѕ{W5аr2ЌX\АALC€@О,•Ш†—†•:&љ jУbЕ'Ц+Ђf’ќє"r?',Ж6€ђМ…š˜і:%К ?KZŽ'Ь;Ў8М!ZжЦШЛѓд§AЈЛ„@HP`ЎмЌ@c  {Щ[›9cBˆh!я§ВЫнжчfФpйЗEtœ$эS:NDц~ШіиXїКn№‘яє’œ9”nQD№Љю+ИЩ Єтт)mпѓѕл­YeУзя3gKRbнЩлzї17JЂzХ “@…=ЫcљйЋW аМКRKЬЂI€й=М{дУ3Ор>€ТaЇp<єЅЊМUUe‚}3хrљž{LЙцYB% G‡RpTУЙ›АЙшtzŽАБъ+Aм7Ÿ+aFЊiша†жЭ(NЛђЬХ~š<е:9“У­&xДK.-q_Ec  {ідeКW_ЌНУж~нъbмlZоnуС;~ …П)—џpХlД<Ы”VлСкЭЋG”ŠPЉхќy?tЅ˜&LLњумХуŽЂд"XY"јъWzAa–цяLЦњњёљљGOЖ”шЛ*яšЋ:и™Зи„2BўYщQ7ї—и#р—Щ‰Ы—УY‡cбPsГ^Аi›^Лuћ‹уЂ5DяŸL\xbrXТќ0‘Q\В”C‡mеMgХ`ОL 6^ј'єљEП9;Ўялg’( nЫіпOСюЅuХRd.6щœњ{ghзЃGр…Ђ"d[џVК„*~~}у_ (X,’&ЪIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/save_16.png0000644000175000017500000000125011733011756022063 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<JIDATxкtSAoAўfwvYP дтЁ‘zђf<щэ ‹Тп`џ*ТйэžО:†Е(AŸњіХ^ИƒжPС&‡6}Њ`g„ДaќЗж€gї%^ОŸќ#ањлТqWсч@сёіЌH$ŸЌбŽZБ,/ыЃ– ’.$QŠv№KСЕЕ4 Ђп$8I:€У§džОvАLкL@2Б’Ј…UYјмŠ ДЏ-§e‚k7uЉ€„Ѓ№Е#рђћF'мШ˜ON єЕћ€њ“šеŠюfW_Єo}™Љ‚k0s‚|.otm]g‚ЈsФ;ы~aџ0Р6Л;ч ц+a0F˜n}дНчqAØпpe’Њ_BoЦ‹ИМGoЬuў+РЃŒмљ[ьЦЌIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/reject_64.png0000644000175000017500000001410711733011756022411 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<щIDATxкф[ylзyџоЬо\žЂ(’т!™’,Ы#YОd[Rф3qZ#jзh‹Кm 'MбЂ@›9Šэ?qRNRДvƒ hbЗБ ;v-;Žэж–|PЗ(оЂШ%їоуѕїНyГ;ЛмЕ(En ”іЇ9vіЭћЎпwМЗтЋєџ‚v€Ж‚6†@} .PR?“-‚f@ч@'Ac Ѓ #ффBќЯУR^БП&D‡ § [#!ѓІж–ИЙІГzК;ЈЋ{-uvwQK{Eq"ЧЁR6зž]^nOЭЇ6...мr~q™—2”ЩВэМŠqƒ^=ЙцЭље\‹Џ^!`рm8|tok<КoЈП‡F6аUз’з>ьК$]GkШс{ў}‡лЁSЧNгщs“41Л@™BщE|ћ)аO1чwџOnЧсPШ4 іvoоўЁэДeџmYT!WzчВЪЈєЏ:AјЯHYНGR]Н{’о=q†&чS'lЧ}<ŽЙП§П" д‰УgСј}‡њFo>А—жюкId†єфјЭdyчБmЭДН‚qЉюз Р Р­^ЯNЯвkGЦшьєќт1<№=№К„.Sыwт№РаКюƒ7пЙ—іь!2 ќ‰{џ{–@B§ЏШЛщнЏ› Qр;AЅШЪ?ъЋыњзбЧћzшмјєшkoОї‰љХ=˜гЗ!„g/ /‘љ?ˆЧЂнИ{ћШюпљmЂXмћРІ-жАSеY–2юS№sўŠ№Ќ йŸŽwкАž††њщѕ7Ž|уН3Л0ЗoBџƒwу№љўžЎ‡яј{ю›ЁѕXЌ jв„љW§U1!aТU“•BŸћL п*Д@ЄЈaRЕОBpО{ї( іїќтWo~ ѓРнЏCVУ—БJц‡ёžПй62єШЇџт‹`ўᘿvј­TО0ojpЌ1ˆК{jrŸ|Ы Ц„ПžоnњЭнnlю{„чЪsО"PЬ ёWЛFЏОџž/=Bb]/Qk+Щp 60ЏZЭyѓ MЬА!ŸћќŠZЊчљ’c›н}ћ-єЁ-УїѓœW#уbfaџlчŽ-їэџУп'JДрІЇAщжUНŸ5ньъЎЕZљ]Б •тљ}З^OЃ›‡юуЙkзНl јќжMCїяџ“?іР. „'Yqї&ЎЯe№Мž\/Щё>74|MŠ—Рw›ЛF}ёŽћnЙžŠЅђ§ЧЦg8<~с’РhпРЛћOС|kЛ q•фЅђBЙ2„еЯ‚rџнRЂŒ”РQзˆпРNW)@&дЦиl’&пc‹ж КМП;?М‡–Ÿ|юa№2й,:„šХyuЗъ“%[•џJ’UГзŒ7KŸќћ6GpЄRЩЂ|О@Х\Œa[`G—§8cЬT6@М0ИсН<СдТ KЦп{§ЈёГчљxk”'„šdx\УŽ‘юлі’ˆХЊ>яVmXжи3\У;w№lЧщtžТ}TЬf)ВЃ6И"mmŠЧЉœN“](аЬс—(?9I™ЙYr3i2J% [E1Xд`СŠБpД ЊКI3№џzж­Ѕ[7ŒМђжёРлИ•К˜|v wэС]Ÿћ]ј}Т‹L>cL},kєуЫФСI:›Ї­заЦo"3%#T}elЭuм|шЗД{IJ;FЫЇNRn|œђS”]LQЈ\ 8>oч јŠ/ˆkPsеcрoзЮQ:7}срдќт+ИќлІрТ†sћ›ю:@"‘єR[?зh$ƒyК” ­BъgYSНk:iцщŸSы№jпАЁЙЕ^@ъкЖКЎЙ†\рD1•Ђ…wоЁЅЃG(sђ8вKд i…ED+Ф*ќ]Зуjš{сећ€=Oуђэfa№аЦСѕЃ§0Sу5ˆ1гœь(ц]YЉюЄO~2ЄЎНЯYьзqиjХЯф3OSnzкcОk „NєєарДэїЄCŸЁ№ŽДJа’-Љ€wиЪ0E5яhmєgыhИЏ‡›3‡Ијѓ @#XЯ‡ уаuw№4ЯД Йt•ЎвЎдU›"m •Я*р ˆЮ€šКтуЇщм“?Ѕмд”ѓRўЬH„њPp ќ4Еэ?@й–6Zv$•ИРєag4Кm31КwБТ>б‡zОчІ=*й‘ЬМ(eƒ ЇA3ЃОІѓ*МA‰Hˆ:Ђ!’уghќ_BЫgЯ’Ыc_  C)mCC4xЯGЈэЖ}”%)БKффjўzњzЉwmчfнИЉ @ЗБюнЖ{—NqEUлюJтј­Т˜O[…wПj ЎFLчьГ­ИурЦє/4џж[dхѓЭГЩ&ЎСРйПџУНv;eEˆ АKЎg яKxfЫU*;ОWѓLц]оаwЗФc_<№р^иу9ЙN]кVt<№™ЪЕЌтCа" Ж|; !1uќ8 ЫЅXwЗŠBˆUЪ@‰9PTъф ’Йr/_ъ? ”кЂ>TP@љиБSУ–эpD8сЛРўѕ}=‡ЉЕьxОЯnру€S=КЖrс 8rFчј ЉПWБЇ"!ЅХhCYЫ,б<ЂУф3ЯPсТ…еЃ ШіM›(yэЪЃЬ.тнЖlтћ БЏG…п§A ИuуЖ­U˜йГзL1У8кмЩХK‹BGЇтu`I?< •6јtKЉ@щ—_Ђ)DˆТќќъСBŒ "э€ИЩv*I/уtVи+ЋЭсС~ХГ/€бpШМiшЦ<цNU­ћ–рTяY6Yxf9оBуѓ‹”EŽ_*[Њƒ[§Ž­rўzь№-vFБ,р˜({B˜€5(KXЅ8ЁjЄHo/‘­YЎ~=уuэІСУФ<3я,€- ЋHд3ceіѓЏУѕ 0\€З\ГvќбC”Ц|SЉ%*@еЧЫќмЁJ;€XЮЗШю ŠУ2ЏVЙТЊ…Р€ийI‰сaВЕXЬЛš4*=\рˆЬуdr `kggGЅYбbєчћхb‰Вй ›Т0Уфі”X3EX‚эжTy^ю ђЕ$+m.€’№щИ]Іe-!ПJw`№l&ЪГ0šађŠf ШеФчm­<ФVР&^ЉсщИкФН pДМœРСБ\.RОPІP"ЁЬpрілiн=Ѕœ0i‚)B@ьn н@Цш „­ФTU Џ‘ Jђ”>ќ4ёѓ_•@;Бv---dqиuugшbрlяhу!6qєът6—юНЫ†EЇЌжіЬy5>‡Є0ЊКоoTљП‘, 5‰G)ЪЕ€J†d5}–uaвзЄЊњ\еC•EсeXюsвУ 2ЃЭBbДЃƒЬ–$Ysг‚ƒHcЈђ]яœењ!6stzbєЕіtcNzТ ›ЏЊФe‚ИЊ†їЬ™§‰…Аю€hЙLчŸ{–ъžGDD2'T=”ј=ЧU‚Šр<СšЬІ)ѕ‹чеsƒљhs!А’I  ВXŸ€[†Т ™$Иъ4јhzТPХ–ЌДф“mэЯяс9XЈ ччШ€е>РВ8‚ёќЯтиВD!G"Ÿ#3ŸЄЂЉ˜хsѓѓэn~Jйд| рдVИ‚lmš … УгР]w+цЮ#Ќ•fч(–ЯRІnb2ья*М:^б%ЄЌК›Vы9&Иmгђ{яајwПЋмhшž{МvžхОbazF=k/ФЩš…WсЙžэ­V бАЖ4,‡ygЬЄч/lь@ZЉUиŒ{oR|ДJT˜Um+nVМ_Œ€Б Іžxœђ“дj—(†!BРQпaжnцса!Q•Еэ”) K8ѓпQJКBx—–—ЩZИ ,ЦёMё++Vњ(„ЈD"Ц›ЅЅ4пžсrјЎіdЫіž§ІъКМЌэїq2УINкs"](FBўi“&‡ШФњѕ$ЬЉёsT^Xи^ДѕMж?иdжQH§Ч-2>Bhів2-a>GdHŸ=KгO=IБЅЕєLМG…=aдЌBKп:TыLвD*MKŽ{˜А3 яКzse5ЇОВ“Кљ)uЊlБёЕ^}ЕђїїЋх+B ‰у2Н”Z„ЪSЕЉVUc~ЃЏC бФш-MLЎ˜Ѓ…чŸЃ$м$цЭpH}GјћLГіЈ ЄгKю+ў„аЮ>ЕщкkЋ~у6ш.њцtцž<€,млGm(FŒњиDI_˜|iBа+AA“ЏёнК5FCY„ЁОЧBHŸ;GEФџђЩудŠXАІYЕ_ˆќ=Ю„пшuщ,аћ(cРб|Ор8–e†hМьхVЗМИЏЙЪhёПў“ж]=%й .вбaLˆww#”}LMрм@щccЖLqL,ЄцiT€Xњšї7Dh+с9F…—2њчNЄ(ЂI8й­ќ_7aСазО^š+IU;e ˜CŒПЇ-lЧYЦ•ДUEђкьЭЊmўЇOœЄ9oУх_ƒ,Co•хэЇOŸ9K6В.,R Sž›%kqœL9ЗЅђ{W‡Hž^ŒлмАŒYФсЩgŸЅ"„u)н]žp ЕУрwвцЄШЮ]”EЮ^ѓмс j_жi_QHћИiTЏYгHЮ„Ў“ђU“вL†З%гSў–л`EѓгХ…ХЯЭŽлмUЊ wmЋІDFюцФмхŽЃГџјCХќРw(PTетjЌЋHXNџО}*Г<ёG){єЈJcаЂiјО­™ж`шiпЈюOdPЩ!˜yЮ_РЧмщ3”БуЬыŠеaо{ћ5!?unтЯwtД{šП8R5cl>\SIЄЦљЗоЂSZvb…ад `ŒЖЗ+ПЌToЭЂKщўН{Щ‚ЕЦЛГcc bјЎЉS™ЁщљwEѕ‰ŽYm€(ЗаЉК›Гщ4|Њ|"ИЯИОІ}<•Э}rŽфhw$МЂВbу’єRgѕ ю"ЎO 0Y|§uZГgѕьоM­№qŽџ!” ІjJx!-ˆўТЋ,Уь$ƒ,мPсDvC™К№›2кї•ћLkСЈћx'пди1ZЖlоzџxг§МёV№иЙ\с]4tЅдI†єvqpЅeІЈpј%?z„Іћњ)Йy3ЕŽŒP;вf}-ННЊœѕ—УИ)Т%-‡Тќљѓ”Ÿ™Ё"РзlkЇЬлoЋОПфХZ j`3Д |ЭkсВPич+€Шя@Љ|zfŽЕџX§цъF;DО—“rЯщ|ср†xlе~ЌУ!щ„рoeThжвЅNЇ^Ыƒ;˜]k(9rЕoоB <•8Ѕ=sšђ(pJss t]|ЯрьЎф55eˆIk<Њ0]ˆ†>Вйѓ=юFcŒЃ/МHYЧљѓvб=BМыš7Я;юЎvЫiзцVпЈїiПюRИ ЋMЄ.й˜g‘œOX““ДјюЛДlQЋаJ;HД €m!5ьи”рДюF‘‰'ф•_(,ёР(ЏЭ[ш'Д0И.К rвš9rѕ~цІѕэF;ЪюунTМёxМl}k;оdд7#ХЪšЁв@^…gЊJ2 Н4-Нž"o‘C(rEЕРaR'3œц2г87СА­•Дж7y­щPИ UяOЛ„ПТ;yё„Ойl'yг}‚МЏŽ7/•йТ§ГFŸFј eEЈpЉЪXRхЌZЁ  :3jht75pОfZЇp€YЖ€ЇuEўЙŽ8ЊрпПњф“”wœЏНпђ‹э§њВ”ЇЪхћЏZM\ЏoЉЋ1}nј€… ЏљмфљŸЎЄВf•AьјЬ:щ1ДP8SЕгizэЧ?ІTЙќ(ѓpй{…ѕ–ѓ/Ї\їБгмКізи+-Љлќz!TŸSнzМЗ}-АэепыW~КWЩљuњЛ‚Д+пэЕќ\Ÿ5ЯЬ_Шчљ—$_ОиЖљ‹ю2Уу˜ы_.КюЃ'И2tWv‹šnL ~ю‡еЩ†ХNЈFћѓіeтЈ‚%˜t{лцP:5M/}џћ4ŸЯ?ЪsцЙ_‘L№@Рƒ/ЅЂяYх‡з#3iѓгЭрO\|аЋБ~CC?ЋЃ*œЪ3СъЯЧ›;7XюdQЕNНќ2НѓŽ[€Я_Ъ&V§‹=рxуёYЧ~ЈЫuGж3 бNЬ][€ЧЛЗ†(ДKˆгUѓ6ЬЦ}SЏF€*Љl\‘"дНљФ4ЛИpЪёаўƒљЩL]t›—юYЋ|А“щєW‰їsД‚рчОщkuU^ьДІ s*ж*МёъвФсУtцдIЪЛ*ЩљŸљбT OxЃ@ђ•sŽuп‚kЎ5Bдц7G$JЗашя УЇЪЕ / сˆ8ЏŸ~э5:sќeЪх#xг%§lюŠРЯyу1ёtVЪC9ЧњtмБЗА5tGVц 5KэuО/ ш§`ЪыBЋХS :Žg^§%Э"]Ю;іq<ёФхќpђŠ X@ёцcтŸђ$?‘З­{чlk_,ГEЌ‰ФєтŠ&3ИKУыі3аЖтsN”x ‹лrЗi˜ј"jƒъ dtПіOgЏИ‚§ИЇ№w˜ш Щ§Ћ|ыДUО) N#Мh у0хrќИбB‘ЈgцJп"’—|.KЙ|ђЅ"•xЦu8{ОЂ?ž^‘Эўџљќ 0/Ј‘пљљjIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/folder_64.png0000644000175000017500000001026011733011756022404 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<RIDATxкь[[Œ%ЧYўџъ>—ЙььdFыUжЮ:(k)„ a)†H8QˆЌD œ‡X‘"@'<РсƒЂ   @т(`VЂ Ђ8ŠeПХNЂФйяЬЮ§rюЇЋ~ўП.не}њœ™хЩвюбДКЛNuўПњўkе СќQp‡юp€ЛмрŽўЄГОМіXвфгиœo`’6ц$)ЂтЃбF{ЏРДЅиІM>rŸuс_utMfэпњюыўY/ААЋ,р6ч>Z€Iь=ŸA5\&|э%Б…ФЦФ'`ф^Юzпєzы!ў њ_lgџzыўЗП “@Ѓ*eR‰‚P9 sэY„ gљdŒїnк{3ъ}шв“Я}ёu ЯœЦџФЄљn5wўПю}ъыяшѓЬœ@^и$ сpТOœљ;a6ЁїнрфППФc™cсСKŸ|ў•зiќ ыћbsaуђЇžНŒ-жс5kМАLuT5‚Gз Ё/6,{џј_燛я&ЃwIП2( Њc Ќ)оMєш€ŸyеНGљC:#4G4ъkѕ eУ|\ўА№Ь•ЯъЮLxі•щќжљбкя§}ГёЦћxєш-їJЃ›}№ТOЈUfŸ"Р e{Oџ9шуCЏ"”їЅ xžЈhŽFЙMЮz4‰zё|ё1юѓ1 *xТ}ŽљќсЉZXјћљє"[ї••> ‹яz˜цЬИт5=хБ†іD5ŒDQўH!;м…Уg?so}'Ј……ш‘IaC›юwAэхп›сqє3Tf2–™пYgPvIэoCџ•o‡qŸцу1ЂŸ`нтЗйтПsсСїСъЃПУ x *эБj^В4ѓU0+уPhЧ˜ФБм€Sи'‡Ж3я~’UXЕ џН—`ћoПУяЕШ­/ёё~a=№з,ќGoќ)Xћјgј*„ЗП™xWS^ˆjT ЪŠЪ{гЁ'@Ј~‡uШд0бП?Ѓ€b’9яь2Ÿ€lч†tмтуQќЩoЋq/ЈљeXћнПЦъ •dЛ›АџЏO;/ў_b"ЅJ4Ѕ Ѓ&n *FnаъЖэЂ .ѕё6РЖ! ьV#!ЉœшZш?fЛЌ*XјљwСЪЏ§kп9ыЬv?ї)шПќМєќ;q|BfwѕбOВ№љйє:0ОyC"Ммпƒ*#OЅ—‹§lР  ?VhKU:Gюєvk4ˆхУF­mЌ5чЁћТЗ`япџŽAщ№}ї|єгђд |ќ&їT?ЫБ-ЭН§—ŒXЯ1}хяюРљ_љ0ДЏ>фэ€™NUšт OЃjIUўвOХьсЋ/ТЮ?ќ1t_|T{–пћ[ЬЫФgј8LQY§ЦуЏ§ЫSKНї‰У/ЦЗ^ƒdљ"4/_ЕnакK_š"шэи(IеўtкИg’>ЗY­+ocv?{ŸџSш<їUPsЫpўсЧ„)ПР,|8хxШq|kМљУGŽОvЃѕБkz,?ђРљ9–ЛAS„Ё3Mt6Ѓp ЋІ}(R1Ь#Pb/а~ы;р яџьџѓЇсшЫџЩв%щtŸ5з_ZgЙWЕ;иZ\TчVaѕ‡є’AЮŸцuъ C щзFГUтЖЕЪn&Фтй 'm'Яџќл_1Ѓ3ЭrФVRNl~Тjp/3aQRоѓяљ0ЄkїйШЪ@YaнKЎцкOXhœТš-Э`тt”(UХŠ'šЧ/Ур{пў^H8”Z‘Бйт-ыоXgšoљ9hнџ@!МDTК?-юŸ”PгдІBeЌnгH,р\4 ‡pў}=›М 54 šкBgˆLє9аЛ›Л–ѕdж€Mл­wd4йž]Ÿ ‡gљўilˆ)O5рбlWXюоІ,ŒoШpjдjIa&саŸяЭ†˜H К *mdzмKiФ v  >ЙDŽит нi>ПbЯРœМWЦ‘йцF­О9оoƒDЙdnr 6lМ>œg/ Йdj8fЏ!ХLсФlšR АbфЈVЎВХŠНЈ‘ЩLљОдбдД1§GкІЦ˜ЖъŸУДЩ ŒnЄœ4мФц{Н VŸ_І ЌOлBHHXЮ ЋS:ж{„щQ^*MИ7ЌЩЊXдE”Б ы{6p5рцм‰vЯ+ЮЈбО‘ої—{‡№ц6л,8mђѓЫŒ PŠyQa6hJG“ГMUi"•1ЇФ3(G€HхЂ„ФRДёЄ6Ѕ˜льГ\‚vТZ>КžњФa‹ЉqХ {ќШ)-A3-м еІЩиъBпx6ѓ–Я-(AG щ"лtk •пЧ(с‰Š-іOї6Я‘p˜l•HI{ЬH$Э%Ž טœл ыл<ј}И3Rѓ C­(ЫЌ$mъ™ЉЊ•Їrз Д6d˜Ц)ЙЊщIPlџА~і}­‚bЄщU™ВБр5ШіЗ:.МЇэЕ'П™yш–дВ“УЌuювиг5p/ЈЃ˜цЊzmМ=0…АЖpщAАІшѕ!–’ˆj ‘оkˆhpЎ\ŒКzйіzЯєфл|eˆF§ 6  o\ОЬН€Б FQ4ˆЇXџРr7ГТhћМЃ<к"ǘ0Z‘@,УЂ8ФХ3дI”]ЙЂGЕЊ-+v‡Ѓ­WЧfp".№Z@6мЄaЯЈ.KТˆЄ‘TТсŠбУXh)‘q_Q+И[KАСTЈJk AоЩйХвzNXfb^hЅ)љY;a„ўэ9YбъfћЗRЫPНЏ nŠ њxЗЁ’єОdФm$mЛЄE0Х"фzMRŽfаœЪŒэН3 ІR)ЎqqBђHЧ k„ЄX`Ј)Эc%X’1]‡;ЃlсСANMж m€и€ЃэyUЬ§,CkEcjшяg=ЏУЛьб^KџzMЮT˜Yђ4- [<ДQЄлUwЧбoxуЂYvѓќM‚КwВ(ПЩr^ЯрО;†PНуEЦh€J‰Ѕj@цѕзЗTФж"ЌБBg.mЖ@DГŽSŠЙ№nж)Ќ DЎЌ|V…Ў‚R™uЌж ЄЋЩЙF•8т]ё E6@o *l—YŸ7Йѓ€Ѕk˜,”КЕwWо'ЫLЫТŠP^ЫЌŠŠ№DТ3IMkф‚:`UИЪ}n3"СsжеСIй>†_UћеьІфљШžш/sРЈЗЭj3ъ­А@ыŒ\i|Ž;йglDЌ: эh>’A|бФ”CжЊnЦzєМTЖ‚БŒђЄТ’ ТraЄA%ў:Кп№lи +pР•Яj}§ёХ]ІёEнйы1UN˜ЮA"ТVУЖб€еКяЋE:šuSoˆтќНdBХ–"]Іbй-Ќ!фFOљ!*`VCоRЮјШ2ь_аЧ‡}ЗH‹ЏMю1њ5/ъƒ^ВД<АСŠѕ<‚]qэИГPŠлБ„|iі#ЋОн1?žu*fMХmЮЅAЙb„Л~‹hдкПƒEяe^жК-2[2Гу›уtqСˆВшa'UдЗ‚ƒ,7 ьRyЭ ж$)uГTJTтХRSJ`0Дй‹МIˆъЮ–ўš™1>ЌVщ‘ ˜љеeŽMj@ДewВmЂ7ЫгCžѕдŒШЎлYМжф%сh‚–.ъ­ш8VнYб.tЇ`АВД…КˆUl‹л˜a Ž9шШињh/uF<[Ÿ€„<@ЖЛЩž0cГ. ћ †)ЏаЧєёьзap2a ))DЦ Љ0~%–јИРVrƒ-‰дУ[Ќ‚_­)xзЩfЃYl ŒЗ~œѕZњZ Ь–М”>кnŠѓфАіаŒїРˆЉпLќЩ”Тf•оPж}ЪuVMEх‚л™ЯNђ’6’ЏюкёTСžx,ŠоCЙнnюrj†4ш-Й€M_ЏЗ,Pж9YАЮХdД~”ѕ>ѓюЎІ0ADб"V(ПАзyWѕСSж`Tb/ЙкHыЂ|…|œi#FЖпнUЛl>\ЋРNŠ–јE†і7фa;˜ЮTзъБЦ S.<ХžуdЪњnЈанЪњ^ˆЈК|lЉtђ9њ5AОиpkљLЮz/XВсFМщ'ђ$…Т мJuˆ$Лcу'жЕ”†Ёr&“ПFYl.њХзmГCЌ\cЅНђ[JљБTЁ2 ‹6 Јr›6Г,ШЕЩsOњфрЦУ„…п ћƒjT@&ЧЌ2[ж-юˆ]ж—yгяjЕыk%њW§rХN`ХŠWg6КЧвv<хѕл ŸЃ.э*к„…ЮяЫDJэA У2ЮnЧf|pаu&‰tыЖЪ2*Ѓk%;|yA†]H›‹аhs}8 т,ЊоєW28Єjв ЎЂ їIљН Q›ђmОМ%зСn7\jИЮЁ”3@YірщGŽkї7GЮC= .dН“^c~i1YX:‚еЕ#3шЕђˆ­ЉЩФR:›Ф>KТфB$žЦќН3щJEЋЈш{o3LІ('иjєБбаЊе4Ѓ­kЦfЋожЭрmzgмКњ3т/ гжЄZdЋ>…ЛУ‰M[!‚sˆx;fDyŸ˜`фЖТ5:С’Ž?Л{ фэXщЇ\ НБ`[Gz$ЦŒ} б8з2ИИhВН›ЉЯ[f2РЂ“ь..CЪ1Д9Зl—•!PЛ@ЮI%УSQ%AAЏKЬ$ŸYФЄ*ч{sађY…wГЯ.\ЖЩf9ьv[€ ŽќЛŸЊа}щЙЋнПйШ3зFѓpВ!37б–ВžЭGё<Ц4Gљ?(Ќ6Š ^яхќ5К]iжšЃ-k‡gУї* є/ji†§ЉT€G]2НCC§#cЯ{tйCœeW§ЫЮрK|ќ:щьЇЫ+Ь§ЈіŽ•‚$Tf2ŠЫН[узч0вcЅмН€”.ЎЕ\+[вВџ!mВѕMЙ{R™ХК>cС~o`Lџ˜Гз.8ее1kwЊ6 nЛќЩJ>–ѓv€W'-ОїЛA—CЛу$ЇЉ7‰ЪыМЦѕWAЧ=+јlЏ1t}EџэЕgˆqпnŸГЉ-ЯюˆSЗЎл%>ьHaЧ0FО+mј3іv/ЯрNћм§ЏБЛмр.wєчџцieХrIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/inbound_25.png0000644000175000017500000000122511733011756022565 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<7IDATxкьVпKQ>wfWtн\Y“а(ˆъ%#|ˆb{-‚ш­ˆ„^ƒž„ˆђ5№z4ˆо‚(%ˆ _=ДB%XфТ‚ -•ЎуЬюœгwFwБ2wtЧ—шТЧ;sч~ї;п9wЦˆmv3џ6ЩжLії[kэФЌЬŽљcBЌж.Ж\8Dsƒ/Љхb†ШњѕйQjЙ” њЕšU‹DМee&т…Ж6‰ЫAЯJVќѕХТ’z„_Ќ%l51wЙ)ИnИB5тИМЄшѓSП’JKЁљ@gнGчIЅu4bљEŸh$PRMˆ(Iv&AтhШ|bUфrнЦЋ Z”ЉdЬ„Н$FЭRЭ0W 7Ет=pТ’ьВm­ё†§{TF”’6Bъ|‘Щ`}‘jО-їѓРAрcиpН^‰Љ}Яv:~b5!eЛ;,јТ—Єvтфj>н]yчќjЕ<Й>WєoLМž"FКЦЈЎN›тšКъ ’@ХЁЗ:wИНQу{?|ZЛ;ЬЉКAд_іхС‡3:М…ё5єi=qЂњ2V0р&pnЕЂћл—бќџ[YOћ)Рž7 ЊT YIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ip-neg_25.png0000644000175000017500000000172611733011756023752 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<xIDATxкМT]H“Q~Пѓ§Z­мj+Ї)†‚ьЂЛu#„WWVtЃ]ф]?ЂLђЊ‹ ЩF^BLМЬljЖьЧDХ ХЦlЭЕUSлfлкО}sЖЙo6дzс№~я{~žѓМЯ{>F–e 6јfљцЬ|ДТвсž”%ЩўcДjhюsфкГз?ЭР@ŽMЬЌ|{ќbщk4ќћСW'&с/Цe>f1РќЏmетС’ъ˜sžЄ†Ојb:ЄЎFˆ„ј>Ÿќ8у*и[Ѕ–e.Nн№ ЛКЪ X8ŽFqsГxxТ‘WпмGчŠФрXёP1P~њ№УЩЗ—ѓaY|ЈEH&х„/(У„;CЯю о.+ŸnпЧЙž|иэwПрХ˜ЦЈ9Ÿˆ””ЅH3с “Pћ}яш˜[o( сˆ$eжb–УўАE№*„+АО&Ћ зяzІŸLЧЧ3BПž №mйœлЎлv‰‚`цБ`l./сЩ!‚Š”,Wо”CЅстЁsГ5ЄvюWWž)пвz­"ђсD7)м”ф GД;Џ­ — Ѕ§ИmцЁџљёЎМ@H‰}–ƒ,&Ы$№i1ђ‡нD/Тfёs№Q,ЗY5”ї;ЁLHЙИЌ№Y&ОМћj]xzє*lРr5С#@љТyЅaУІ(щљЕТ„`SЦ)$IШцžЧ1‚­aђћWм>vџ=§Ž­ФэФЫIй5м1uƒ|GCЉмFŒЩќ…џЅ!јF*§W*˜-Гi&аззzНž&еj5twwCooя–0ЁТkЕZЈЉЉЎЎ.hnn†ЦЦFЈЋЋ‡УБКPW5z ;“bя=ќ7О—Я<ЉЏЏ‡h4J6™LPXXааа@WЮњ‰3qeeцЬ Їs8Яиšљœr---Akk+И\.  ­­ <]ЄбЅ:}—އ]{8:hŒН†фtŠ˜ЬумM РbБ@ii)xН^ZОІІ& H™ дыБз‰и‹ЉИHУє2БœгѓkЛЋЇЇjkkСnЗCKKЫЊ&###`6›iwсš_РkK{‡qЭ‡šЌ;/[­VЙПП_6ЄeF#лl6:R,УfЦy'дрp1ІnoЦIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network6_64.png0000644000175000017500000001125611733011756022716 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<PIDATxкф[{p\хu?їЙя]ыaЩљ),лcФУБK“mC †iKi3ўSЦiщ$L‹;ЖdтLh §Ѓ-ЁmТ7Әi:!-ЖЁ”&Ф!jc#йВ­ЕlK–%YЯ•іuя§nчЛпЪыеЪ–ы•€Љрpя^эљюw~чѕ;ї Эї}ЊхЯюнЛkЛр<џ˜Е^Аж€~тBШуc=іБ6ќ‰'žјџЅ}Ю[”~ўш‡dыз}r6œуШ›ђт 5]# '!ІЉS8dвIзuyM@яяhЙbŸѓ€к<\Ёa3й&6ˆklДы в ъ0 чАBшАг~ Ызё/љ:РH0fИпзШƒ’‡=8OwШЖ Š2 Ъ}Ю;>Šнš†ŽMјРC“y.6*ЏЩk:і&<‹Ша€0pФ„Ф–у: M- б§юЌ"G—CˆВ Z4#@?WФяqЏXд$ЫвчіjehA[чАЧF]_†ЂŒfeЈГоu€Рћч”Ъ=Ъљ(фg^з@DYœЌЬQgYtŒћœ‡№Ўl3wо В@zGР8SчвА9‚оDй‚ ЉМ{Ј+Ђ,HиJœT$яыЫуђšўЬ}Ю{蹄ٛ@Ўѓ-ћна%К!дfЎ ЙDEСEдЇЩ<{†;A QЕq:;85\мSѓИ(’,Ќœеі9я``œэ‚wТщРљgЬ Р!ьѓpёTR№‚pчTA‘д4!MїОЭK .ЌјG: Ь9 МЭзe№њ ‚774n‹а…ГсqAYœфДRD‡ЛЦХSц]ŠB е|dСY d­pFдšЛ{о• ”ёМ[™СsНюbуS№єЄєzP<§’Чe1AMЌB ц6 O $b&El}Ц>ЭZ37ЏЂ rбжЉф­Ћƒ )Т”ƒ—йшЩМOй.™фб˜ !­ ‚І‚ у#р)Ÿ„Ф#…BњŒ}šЕцю;Пђ3xЯьЌ„ѓ, pЋ,"ФЇаЫ' ЈђE” фѓsмИl4ЏХп—ОгDp-ш\<аx(dkвћ1 똟)РќT/!ЁWЩP‹œЃQЦdЛдTžы2ВйcЌt№;&>Т hГ№‚#—ZіYИ c“0:7РgnЩ•ћ4kЭнЃ” цЯЄWцzž ‡їГ—MС—йѓŽяKfWDJИЪ"Д4ОЩxFˆoУ;вdJй НбHр§0rŸ‰‘eh3# жмНВH/rOіЕ›‘ 0`LNВXoвee‹‚щbЭ"ЎчЎњш§HР“žg[5 Ьћ…ЌњA}р{№О Ы Uп0 aLB‹m0hіP+ю^й‚o“м t“bГp&MyAЮч=Š@…љ|VzF#*WKр\х2хY‹ћ[јEи"x_GЈы2ь-ЎјЬAt-hХz@‰gD@­ЙЛ;c=ŠЇ œЙаLž‡‘yЭiW†sфЩЪ”ЅСГдю|І2>†h” Фxф‚€ћЙrJ RdЈ9wЏXЏМ2ˆyќ'C3 B_“­.№Ж.Gо’бЬћ 2f5ž=‚ёQГ и! ЂЈK“}ŸУžm`QeЈ5wїЊD)VV@ЈЃЪI/C]” Š1VшUAџ ЦQэŽ Ž)‰XЬўѓGз1_HТЇkGРrїjР7ЮсђhŽhŒ=Я…Э (­ЄIzРзйXНJР—ƒPђ|дђoУШƒ лl8IъkqKдƒяыA&\РЌpЃмНr=WoЦчIV{ЎръaЊcX XЈ &іgу•б›dИ‡йpK чnР]A‘#йxД šgD@­Й{eWЩРлNр§ТДзƒТЈXэ5A(Рй,>Œ&)a3Ј € У™5jЉ'ъYЂš=1ѓЩ•YkюnWЌїн/\7jJўч23њіqwSˆOФcёijЭнKГХч>џХOЦ›!ЏЦмнњ„DРejЬн‡љyАG!ЉІ|^ч 5И’g.O\ЅЙ}%0Ќ,Šд˜АhЉ9DЗй'–ЪfГ3п1T„p__8p`Ч_юЊM|„мнU;н&н™ЂЉЉЉЋРћNЇг–ŠN<7юБТ2в&&&d”?ЋЈім"‘Hа’%KD>ŸїЏвfІ—(еј+ј8pїdШЃs’RфPИЉ& wzZу‘ЖT\•ˆ ЎыъŽу„№qы#<’‡Ÿ}іYQж_m%|ЭсРQчтЊАPм=Ž­З…‡hЙ5FѕўС*ІbДДёfŠХbR)гЯйлЙ\ЮЧgtbн ‡УѕщE\ї2™Ь[O?§єькЕk?nЛ^н> ™„ŒB&дy^с›w_ЮR[dˆVъв@.ЦДxёbjii‘Ц[–%Чѕ€љЮЉaLNNJ@˜“иЖMЁPH "хW-ZtОћѕh4Ъ‘3ˆыG!!|>ЙЈŽСќ(ИћГ—кш4y`P„wCCE"ZНz5577г;нщдХ. †xнБіStгт г4Ѕб™ NЅR„bHO§Фxэф+CƒTЋkмкКmcћЪлкёнЗ!`kQ•p+хЬ…цюѕ]/бШP'ТЦй {6|ЧŽdЅLњжЋOЂdŽŒ_Є7:_ЃПоїMКїЖ_Їoќж_QІ'3н"Ž 6<Џхш™=…VЭбфбЅЬ=q†ўfџStЯ­їmи§РЗ7шEу, GАХсЊЬ7wх••яЖщfЯsиЏYГ†ОўУ]ђљз—ЃН‡ЉЃя(ц‹Œ|НѕТ;џ@Sшoяџ^т‡!c ь[Є.жsМЋ­­­зЙ-w]/yч’Л—œ*ЁбC:ђи(“ћWяЄG7>GGоџР]ЛОеXмдDЖi;С{NсоЙфГЖдѕfз§йляєnмИё<ђbŒйЁv=o‡їьйЃУа‡`№„ћчйышЋ>‡7кŠ6M–dј•›Й;гVN^ |žЙћЂМљрƒ2+ЛыЕ#:–П™)ђ_У? 3ЙуД1О•ю_ђUЪЕRЮ]ЗnпВК%‡@­у§аcRSРzЫ‘ŽѕаЕ*us˜Й3gЮ ДЖЖžнДiS/q:Ž9№ђЫ/п o?Уw–†fblгQІЈeШ(џ|y0вK“ f‚y 7аРYPъ ЫБ^ѓ€йлл+Nœ8сЁnј6l№—-[Ц 4œwrTkј)–<Феkn‚о˜–a_!шъаu;6‰{#кFV­Z5е‡}‚ЮqHїœиЛwяз єm5zJъ)дŸАвЌГ№'Њху,ы” ЅŠY˜ "U0Т4Žм'>>>„љž˜ј|DŠЦїХzFЮЩ….MбŠК•мОщ0‡§MЛ zЁббQ— 4€ЫB7‹u'*O„нj8њЇУkС‡~јelњ>Kqw ,љїЕјЮC ыББœ&%aяѓ‘aЃЖmлFлЗoЧФЌпŒu/!DuL†QˆЅ`Иj†їK<Т4фжУL„˜WA˜иD`dУ• бTЁjіе$ƒ)‡Ю)аЌkаббё*nИЈŠ’Wч№S 6`%і…№щђЧQ9Й~§њvt”-иєZžя|ќ-ћx_'Щ‰.ZG[зm3o]uЛ =їчП@љ–lg-фKjЮџ%H+tCeКtЃ˜УаН™PHИ&Iў9с<ўy{b—%Я<эшeOhтŠТj  u_€мл?опўwћŸ‘4—™І3Ciъ|Љ§^ТDG–fп диD89ЈМƒnѓЕtMВў8 МЏR з\ іk*ƒЙ†№$ж Т–йи f’§іgіяFk a”і)=дEЇ0бL SоЭбПњ'9б=їх=fгh•LчычЂћпya5КХ)ЄX3є†И .†KIHхlJ…у–;ђ"? “в9x„їНK\щeж†фу9б?a$мEdкќ<1Ю­6MfЬ' ‰R.ЌпIпМѕћtъдЉ‘›nКiLЈЌ{r.ʘ`yъсW/Lђк§~еГЃъ<Љ8@Jеў\ЗяиЋоЖx#ж_ЇЪ‰.{ԘLЇгƒ0ўтцЭ›sріЎV†2hz шѕLƒЉJнЉУњŒ?Щcјж­[Лб˜Ÿf:\€ƒЋеOи SиŠPb™–l‡ёP‚bh]ЉШ"HŠRс”<7<“65lFHЏЃІКf:нsš~њўOhД0J+жДP§тzвЭ€’ѓѓ~dЮRtљ­QŽ–G—гšЦVjЎkЂЎtэ;јЅGЛ)жЁ'у[;1 ‚єЉ‡1У @ ЭwЗM[ЖBS)5,€– 0 Еh‡(q+NКk(№гSN‹ќ№4‹H=ЁўŸWИTєŠђшyЏнe ќŒb’&ЦЧ)WШ‘Їcј2ТрMџўа>~9Іо2….,T иŠ –Пžж•X*=B*EЂЊUЦе1Ів&ЁжАЫъŠЃъ@QЙ(T~ч”фЫЮГъsAеЁ0ЫŒUКC ГєЌNIИ Œ„:šeХД Єdx9E%Ž2ж­Ћхkєџ`NУJ+ЖpМIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-neg_25.png0000644000175000017500000000321011733011756023332 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<*IDATxк”–{lSUЧПчоОЛВnэилyшp2I‚у-/‡H|gВL%<$ЬB%(Рё‡1‚4 F^_РдsРXЛvmзЎННЗїщЙ%#s+‹žЄЙЗчўЮяs~чїћ}я%šІсџ ЯІ)ѕ+Qv%њ­!вR‘s@ёіЕ†єёј|–ъЬ/cю›§Ожpщ&–цЬЪ†’ˆЁ3аžрЯ_3›MЯfmИёm›iBу)9{Џvїcшkbœ;т+dхD"Иs~уЬ/Еч ЬVАВщЖ 3TѕIбћз—mJ?—Cо™ŒЂ~O—юћO‘xЊЧмtŽь(yrCТМЄІч eŒiN@ˆš(дX­MjЬ—ˆ‡ЈЁж;‹uљCнљњпžХ/Ъ\ш sи(›}мЋ4ˆw@:СШНњUЅU†"&Р…ƒрМM`ТwaфƒZ4рk1ч<2;ЇцќoКOІgй‹ї|Х:њЫwРяэ •ГО!“•Ю›юDlVœ™.иг3`0Œи3Г bMПю№­-6Є„$%„Ž ѕMuЮZ{&рpVz\vрЬЃ–u Р`ВРьШ€рШGBc!š]`г\cЅрнн_ )вХѓg[ЧЁщьЃ8FЯЅ>dz д„U ^Ќ…zч7ШЂУЈ0 ŸJЗHŸЕ^Œf0f;њe2ˆѓA$T{vž1мєћ„.ШЃєЗєrѕњЪŒЂ"ф-м “ХFпЙЅбˆП\h‚!†kжJмjVбQw%+4ёˆњ’›LF№ц4†€чтэ§\бYzОЊЊђкЮ ,‹‰ћїcШќy@Lфурv[,ЌsVЂщІŠгoМASЅ@цyŒЉzИUOAўdЮˆ*H‚f$иMR‡АгТсяvэКwhдшібЃH{x \#GвRkФп'!;У†ДщЫqуZgЪЫ“€dГжз#!ВШЎ оИ˜Dj‚Ѓ,ўqЎю!mЪлѕ[nюП’Ў;јБЂ"y?lтpи,F8ЪVуњЯўф| k$з{ЏвhЮгhкaь№Р—AL§мПхЮКQavї‰йЌй\т9uЊщ^DŽcр.‚лП“ GO•lмˆ'Ївўё%ѓ#EМ№‡ує(cЃAЃий1‹­ЉЉљ)ЇД4Нˆ$ŠfќBѕIР EаЎІU‘E(`$Ie`NЅ„ИЈ0Ь^“)™[[8w|sI gзkkS^ -TфІгžБ™™ˆ)*"qZ U/iTцlav­Јь№Ё a'zm)1ІЛаzђфEѓщЭ›Q\> Z№8mLтPЉДо„Нэ@'Ѓ&AІВ#+šš–7ьd3†}ођм1s b­QБО pыШ‘^€Гgгч3ЁњЉіY^Ђ=!№эQX Жгъ8ЬєЫ#v.иF;џ‹ћRЏщMхˆ†ЯЇшCŸoјl†П2 |›XЄЅЂ7Mф5еž~К`гЪЪЄfЙVуОv9.<šEœ[ЖЌЯ7ЃўќкzŒД/ЈьtвžMX ЦЈ )œѕБёяvЗПВац-QДцЎ;Х§}і› PPV–t­і2HЮaяжЖ`д’;tmюЦЊŠюIяz§~rqЭšJб}@сЂйЧZЋGgk„Эee:Щ€ќ<™љiЌЁ+ђєШŠ_q5ђЭЦцЛБЪяmНє OЂAєКъruuЅХэFб’%ŸвџUT јY+†VНMж –Œ˜bЈ‘Э:ДІЎўЦБ‹Ѓ„@O­_ЏлnЃдмWEў#Рcє:сP\IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/both_16.png0000644000175000017500000000125111733011756022062 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<KIDATxкŒ“Яkд@ЧП3™dЛ›Эf­л-…-ўЈHЋЂєPЊѕр‹СCo ^<њ—xёа› ‚ oтAЄˆb‹ЕаCiБ‡Ђ`mыFкФнMšLf|YЋшЖ>xфСфћ™їЭ{aZkќ+N=N~е_,шм` Zi0Ю| qpr„iЉ!АG,о0ГgэY•+G'Z*4f>#mJшx@'шR”BдRP eЌЩо­vkƒlі!E§Л$@JТŸЕЃРЛT(Щ'aцЁЏlсP^C’(н–”фvbK?fн Y}so1ИќNГ1кЯсЪЉІ‰pi­БГВЎDхТђŸЪ$а0K–{Љ}ѓхЋœ{Ћч–#ŒИzвФУч!Y ‹‰/UlюНA'‘јкqђ(ˆF,ЗтŒчЭL0oХУдЃMšР™jЛ ,п+T$[ЌГ•‰YэИn^Ћb~)Рь Њ§bущPšŸŸеЅВ EhЩ"ы4œMЁнцJ ЗЏ ЄXјТaєК^]оЪй,ЧcXelљ™Нп‹>" a`ьД Ч5pК иИdа=;ЋыM{ќHЭ›^Ѓїй_;2:^Г6^Г[˜џ$а` зЄ” xіpбЙ8Ф…kЎu›–xqЗ–-}=Xmh[р9ŽДмг5ЙЩСЌЎгонDEЭyЪ€pЉ H(Fі иhсУœ€Q``$цt+Я›h;пpќŽX­iџ=Ymер[!иО?кZ%HLя/IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/translate_16.png0000644000175000017500000000137711733011756023134 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЁIDATxкTS=oAлнГYВGVфXˆ*а) - A‘‚Š_$SPбX Ђ&QЂXТ%MD“"iш(R’€EAйБ}gп}ŸМйГмiДыѕЮ›їоЬI’аБЛЛћ\ё4ŠЂћRЪ;Оя'ƒСр‡ыКч8;k6›_o$Ьvvvю–JЅЗйlv3ƒ‡Яу8&?h2™аh4ЂnЗыѕЏЏ?тќ еj§њ АЗЗwЏRЉ|Z\\м0M“ІS1ЁЩaRF”р уˆЎ~_Qчђђиqœз "Ѕ\.ПCѕ\.G†aш€Œ{)t˜ЪЄjЕJ•ЕЕMќ_ч\ЙВВђЩoђљМŒQ:ЁІ'1+d $5pЁP зqjGGGšŸAВЩtƒ д”9™Ѕќj&Ь@L%Љс>•WW§HЁb/ћў”иЯ,въЉЙ,A*€`?—%„ЄЅхeBё‡ UЎЮ IŒэ˜-c$%IКOПТ іЋX,Ў+Д(aъQktє…Шќ@ЧЬHT„VЅЅЁp"њ§~лѓ\M=|Вэ1,›\ЯЃˆ}@ŸTЦд`эйL+ЗzЪ~Ееx<>ZV­€JžыjкЌU)I kZY‘‰d53QЂЅ~Р€пFѕДгщx`B!Z8Ÿ6Š/›3зеlMї&yŽ3Хн3БППџХ[ЖeЭZ–КЌю+L&3Ш№jІ2†(fлісііі‰žD8}а Nzн^к.Pфжq%І+MЉ0Г^ЗKН^яЄИё1mmmнЦ МТї№ђжвђBБX <&ŽЕЧш Я‰ыxSЫ~FђћFЃбО0ъѕњTz АЈКЪт'†цЎŸ"ё˜взЯзБbŸži0IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/save_25.png0000644000175000017500000000240211733011756022063 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЄIDATxкЌVЭOU?gцЮ< хбхKБЈ˜`Д ]е„W&жИБюШ[р?@тV„С4кB\Tnc­БЂQБ†ФSKšА€оу}Ь{s§sgоP?‡ЬcюsЯяќ~чмs‡­ЕєАыЦ‡7№Ы–ёkЩй1ўвч#cОђк•§№ќќ<ctP­VO—ЫхŠХтхJЅBННН455EџцšŸПN;;Лфћ>yžЇsЅRЉcffІhdBиРљЙBЁ№ЩјјјХ 5кооІУУCњђіm‘czххЫЧЂЈBŒ†‡‡u<88HKKKя"аC!bƒЧѓљќЭБББбххeТГwїєаAў€ …<­|ї==sс‚А=!Ђ.гъъЊЮ­­­бффф‹‹‹:6XфƒжG ‘ћОЇ*—K%кннЅBО Цћћъ48ль$а"lLŒљ"mnnRšoƒE5€<ЗЕЕЅ”=у“$ZP !эээ!Ъ"ѕ єSўр€юўvЬ#M6'ЉcБ•|H•0жІiPщщiš››#і˜|Ш<Ле`pHћpќдшЈsЦ.O‰пz}ЩcT)SGЧiJ#d8PIЊ Ш>&M“к–В]YКuѓ‹.-8ющщ­#KY{< Уˆ\>шЅЅ,t,Ла?0рЄ‘ѕмBЁсRe57$єНF)зAdB™ˆ7лˆ‰ZЦѕa к$kЙю/НDєѓ Ÿ ŒВpё"BЖ‰гњL‹4Ўƒ7ї‚4­r фКЗвK?~њХ‘Ѕџz1ќ^z}†Ÿоеœ‘ЩL~њќQzчл‹єѓ1љ,ДE_ЇŒз’ІЌkqњŸшйsНѕМO#oч[Šш“р”OПlЧє:KˆШDAуYTOыЧUмš@Ѕ† 8&sЪљёN’KKиtІŽавKcRu– 'y&ьЊ/ЦcŒ$УЗВљьWЋ…T@<я$&žО ЛŒ2ш™ОYЧ"XТФЗˆдƒЕ‰D5KPЂS;ь3Xž1ЪфЁ‰їёВэlHоЗ–^|RЄb „…ф„)Љ00НA)‚dЗю[]—щ д”‰P“[˜dЮ5nCd+ШK&ХLш8ЭЩeUЊ„E•ЉRЕд.ŒaзжшV8V]™LFsт)H лŒЅАчћœШ•єЊXYФJв™ОZO˜шњ@§ЅФЄR rЙPPЙ єЯDwЖёп›yrЅœv„ЊШT8#Бc-Y_‚Ÿ–.ьZ•Dщш…g‰Gъєв€$J_г*уzЎ"љP rY*Х}§ЛЉмnпБП 9xКВYъЂLlt/Hдwv,Њ в!/i•ЩЛиК§QVИ+iѕ!8$ОhК:Гz>еAфРЙ~экНЉ\n4x`ш|ЇЇе%ŽuC&ЗKб &—I<‚ЈДсFєЕ1…YC#чGшНЋWsјfx?—Ыљ,Чыььl7Юљ?eУѕН:чЪд6}5u_NЯФДћЊ|ЭFL[ПЉG3@žXXXИЯїнѕ] 0ВучйЏЁtIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/undo.png0000644000175000017500000000036711733011756021574 0ustar sylvestresylvestre‰PNG  IHDRрw=јbKGDџџџ НЇ“ pHYs  вн~ќtIMEв .0„IDATxœc`Ѓ`XџфhbЂЅсФZ№ПпYŽЁСFf  ох(ЫРЭЪЬ№ѕї_†oПџ1|ўѕ—Ёїд bЭ ўї;Ы§яr”Ev§џb3‰џХf$љЏ%X њЃ-L5 `–`ˆQл\уД€иd: €цС3 F ѕ/AxYJIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/back_25.png0000644000175000017500000000144311733011756022031 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ХIDATxкДV;hTA=3яЗЋыFу%`?ˆhдЦJ1ŠUФ(˜Ц&Xиhao+EP БAPEдVHa,Œ‚‰‰I6Щ&ћ{oЦ3яуn–•ь&›ГїЭМ;чМ{я|Vh­БбЭю<6оЌяuт1пЊˆlвяqw­‘ˆевХHЏв<ŒЛ[g?vч›р]AjЏ"0@sПn8h[К(pцa:ААОТџGр ЭSТ=uЂ@у_л(B“4ЯР•s&3nэы\ ЋБqсIpœц5‘О1Д2“B4Ghш Je…™œŸ“™j$8Lѓвмvс8–2"z^M PХВFАшЃѓy‰P —цбqљЂРЬВТІД„GЁ”%р:2uЌHШжGfШ}_Ѓ@bб'‡ЦT^cz6€н7№Ћ7›‘oHиЙ§` Ѓ’›S™”EАŸbп№\ й–†`”V,D~јJ Й%…пs&I>БŒ(’o?*їјU;м#sвЃ„ЭхTЏ r4<[…бxVЫˆ0‡?Qњt˜ІŠ)љЂТ"3БX‘(И6kЃaгaј№ч“шкгяAqљс е—Lj8(щеE„›KJгЏnoЅ…8OY№m ЪRi3^ŽVkВ~яˆн{/e!т‰†Ф|eШ%Ђ%&теhjЂEнЂ#GЦІаМВБ­я{твCМ%vюоЅ!цNRQ+ŽZЇ•šfxldКzЌємьЅ9mŽђБ‘)и[ИŒc˜g;=ЛY'ьЛйxЌ#іЫV§нЦ/K"щНгк/ЗЧЦ2“ŒХуэ;VHќ™„§fпаІk…ЬQЯ~K—–љИ†{˜DяiЮхѕD№Џ65…oдЮ&‡eЩF\П/ˆСЕ\T­оёЯˆЁЖ_Z куњ‹Ѕ­$кбў 0ь 4В,IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network-neg_25.png0000644000175000017500000000163411733011756023373 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<>IDATxкДVKKQўюМЬKЩ’‚n€ћДХTJQJuе Л1nW.Ф•RАЁBбЌЂ;AФ+CЛщТ%&6цi&3s{ю$“šиЧРЩ™Чѓя|чž уœуЌнн]юїћЁicя˜І‰ЛЛ;щХЕeY-sGОЗЖЖЦф‰XаЫіїїљSѕѕuо|_ы‡n“элo04жМO–+ZИ)YШы(Tm8Діzї9к+дˆeлвћМ:HЃd6UЅГpk5ЎРуU№(r­ѓTrЉ,НШ]eЈлe“#_Б‘!|#Р0Sдр7\žBЏЧФЭfsюbARњ)И7Ж‚Ё †—ŠєЊKЕšй тѓљАААа•Щввщmе@еђФ$O@5•#aˆњƒ—ЂйМ в…Щe:-§ћЯпeн ВrŠEз;:Ъ–№DЁh 2= ZЊPЅlЗ{Q­T;Aœ†ИЦ€@Dыдwu…‚ ђ%ЎїНK•J'ˆЎЎ0 5Ф§Aыr%ЙTТфф й1­ЭFчLQ ‡ Њ*щЈШ–Яъuеj&5гь7o9Шй •x!Ÿ‚gB\jQŠ3AlllШ&iкъъЊЗ}{‰œ…”-ьuІCмŸ qЃ]Ф]^NДХ‚d’HЌTЗЗЗ”@їLђЗ…ОХ§њщ]л4€;c`vvЮ9lіiїЛК„ЉЉ—д‚Ю‰лsўѕВЭЭM‘ЉЇЭШt2Ѕ&JcЄрјјБXLЂ$“IЩыLцZŠ*šАaЂы‚T?,$H$Сєє4ііі0>>ŽЬЯЯЗ@///Ѕ Qл>щрЁPˆSцRЬt:-§ЩЩ сno<ўQыU.жЬjll gggE.—C<ЧХХ…[ОDя/BqЋЮe‡љССdpuu%=iФ‡‡‡Л2щ•љC“ ЉTJ>==х­вŸŸџY‡l6 в‹‹‹ MшћБDѓ~тЎшBwЛїЛВ~:…ВaѓПы—ќєЛAЁ?IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/object-group_25.png0000644000175000017500000000256711733011756023541 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкМVklTE>sл}tЛ}экаZкR Є­’–b 4Dє‡Љ!1Ј`Œ!&’Ј$ў ў"бHb"?LЃ ФФ ё•DЃ‘"ДД”ЅeЫЃ- ЖЛнnїюі>чсЬvYшФ8Щ—{ямsцЛчЬwЮ\Фƒ9Эyžg№ ЖвslђЃ|Э_Yфюе{йЮњ’;#бКПuigŽlS‹+wсtlЉ9|А6ЮнoлŒL?вўЪр7E\Vр+ќК­й†Iрl8Б„-LЗpГГƒЗ|”[77НКЗ ђБw ŸёtМ~ќ+ЬдИ#lЄ+, єы‹џhЌїТЦ'ЫЁЎ)8>ЁQzц*ЮШыjšиv_Є3Зфнѓ‘Œьkgžšе€TU“YZwћh0SEœ@dеВœL§Go лнЏ%2V‡ ‡н+Џ ХЉг?FФ4#SН`2žJžіŽlЙђ$—оёВe†ЁЗЭlŒm€Џ~љ…ВіŽ%з;xlЫ‚ѕ=ЧЁѕ§ЇwџˆЊЊСв—kПК Х žБXtьЧб…oёŽU?S—ъз>=ЕnтдZ”OPЬБ юƒ§и†єљЎшјБЮІЬаEpW­*YR[ =t(jЫЎ*ьšŠ+§уеП;y]ИЇ8Š67џТќю !($’XP]Ьд ˜‘_MCUні=|’B Й9hj flў1њДЄФяїmnyпІ•ПbЄ)Г(€EйМПEBm€GФlsЦH–1жr6˜C1`˜/& †As$БмЅЗKh 5в3$œР™š„LЄЦ ƒЃ'NJ#шxiєы:єEК”БЉ1T(EёzЌѓ7jЅЪK.їщLA ‘Л0=“FОЃ‘0|OС1ї xОэuп’ И”t œМЅоz†RхшfЯЮZсчѕьсЊlСєj}ˆDЌT–$IЈprA’є@7L\Ъ‰V]И™[нръEмАУа›д`дО иB*V дИЮŒ…џtыХ{AЗ !Д8бЭRщ€3œ('Ѓ їМŠмЉt!I~BмW>еХпУ–н8ђIWžпу‡šжР‚ƒ ”С(—ГM[зj2б‹њїBА4оTаэоH{n§/8оЫGТ(йРK{‹ZкvуФO­bѓ ~Ž Tr‚uй‚c'ŽфЃЎ[ПмЁШЎЄLьœŽДц^ярр8ЧыDЫKXR\:’•Яэ‰Б5”8-bЮдLР3eBЊ‚Ц7ЫТЖ*']‹ћ˜k"j%‘иynQЩЋ8Офј]ДУy{’#sФp‰ATaƒ<™2W+6(21WfЖTtFe—ЁЫЊiШTBВ8Ÿ~šурBн8OВь3kі›M4І1FМd›вџЖ[_с[Фхe„ЊS ЂСOЭ‚э^ЙЧŽСЧќšEвШч:IEXШ@ІЗtеЛрЙt$МG‚c^k’љ”")#ЙСШО№JSЊŸЩ$ЭМœЌT-ћЁIЂ?ЌZJк”ЦГ†­™*Ц&“$QХ БЉѓDШЕšу­‡!)X.фœU›w…zZ\‰…в™^gCЮюMŽ“ј(Лv_Чя,іMГўDŽЭ1йЮбЯёЗ.сQірщКcФs&"{Й(Хў$яЧљЎ‘ќ—у!љW€IŽ…ѕђtи‹IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/tag_64.png0000644000175000017500000001202311733011756021703 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<ЕIDATxкд[xTUк~Їdf’Щ„є $$BЏ"e ˆвTTXD`TС_WєWФ]]+ВVФUџEл*ˆTЅьŠ”‚ %НLкЬdњЬ~п;73ЩBxі<Я—Йхœ{язл‰ЬэvЃЃЧёrЙЯ)Ыеён5 ]T˜LЁŒЗз‡C&sСэV8-ЦўnЇ=УэАY-ЭuТхl‚\ž'в:›t­г€Я]Y—ѓ-J\ƒAыђ!†@—ЕIEHЦт§eъAv}Iм.w’BЁsйЬ šg'pб<›лn)v9…t~š ”рВ Лр#‚(‚юФљA2Eа0yАЎВS\ЂBJз2™\ЎI “kшдхDУ/_ёrЗлne БлЊЯдбљ9~$С!‚c"AŒL,•(!Хз\DЄCDЄгYЎƒLо› AЎ U†Чwщ+з$їƒ:> A‘aЬнђOўфЧ8&Žqс Щ] œ$Ј&hскЊ!ЯB0R@`Єcф*VЄNш.NˆДЁPwюMˆ'‚t5лжy‘wŠbО…`Гјищwє%HЄЕікВ..[SЉЩШ\fK‡хЊЉ€ЈУЬЅ‡Ів‰ФiRЅP'ЄГx HkieD$ъ2eјЛЊПzб‹<@Ќ#x"€=сoxŽ—шt'9ЌхzgcЭ/.Лe“@ ’ц9Ў•„МЪœ"=V‡Є‘‡є‰ю"вa1фДвDi‘хЬQ_ЮDо‡OŠъЕТpl[PФшYБІќŸКъ+и@АИ&P‰ў{Ep˜*vъc2Х#оС:ТWсAкэ‚Ыf!B„H ўЕе{˜u!ф}ˆ№a"VХv“[+ #ЦКNЛ5‘ЎžЯ\1њНѓџчН—Н№žQє3WІTЉbЇ=Žш›$НV7#mm‚У Gо’TК„>j%"дђЊ9Ж\ш-Sm0­•i’zЉm•E 07Цв5ѕљШЏы yvqАўk3F!ђ†ЙЋ‚фI/q|frФтЗUз!4ЃIE4ь5ч=jѓ%МVšKЊЅ)еtOJвЁъ0 ф™А‹ &ШШ’Чмњ0ШЗ їљьйЁаіШ уз!ЩЉP'&сь›ЏЖы7(Уу(vаjIЂ’HвТХиРжўР^Є%xЌўтЖ*zтbшLІВ~$Фг‘xзФм4К~ЁŽ‰ЛаІ|GѓЛќчŠ#("^FСTАLЎфј †эQ‹МНрђƒьEГYєW CԘйdс=вGс+ЮМ417N„&ž\^HбˆcЗЭ#|И„ЫД–я№џ1ЭЛ–*(uб*z7Q"шМv@~хрі7ђ‡АшЧпѕ,8Иё*k–‘ЃЧAK:яnБЖхшt§TяaџьХї>пђ=-зwŸчЙоЕЌrD…,HIoŠ#аЋ œзˆsџ\жЕхК~7в‡L“І™O%У†ˆa#ˆыrПu a‡њZ~h’ћ#сю5УнЅєьч[Ў˜S‰Шs Єр5šЎ}Ё $"ФЪЩ№ъ("d5шШц)лEhф<А€‰9—` щbІ<Ът$б?ѕфH$ЮИšЄЮD—В•A(нД‘cяEPT!FˆžДTИG‘Ž~Vц,7Љu()ЈљўoˆžМD K>D`I$Тъ–ыНШѓ6Žьrƒ(Д&IPл”*V‘э/9ЫБс[HLЂЫxУZЇЉ%oн‡ЎѓBЌ Ш}!)![5z є?эiE„˜лW‚b|!:єUЏСcg•"KёaА №*Ш ‹ЄЋн ріp4“р^6|QуџU\Z3qю‹"Фn@Hjwямѓ'‚Tˆ•‰кŸїњ ю6H6Ќm*t(”BŽсlj”СЩuдŠ5‚і5‚ЙмЯ†Г–рао™ˆ – пй,h’ЉбЮЛœ‰#GŽ†Ьž'СЎ/ОЄяacыЁ€5Згюх|c „Ј="AжЩбЌoqгž№„Л^УїјѕˆПm*T‘че§€О™‰0b4jьУщюDм'.8X5§'\MЅшњаW‚JјИjеUЩЩ§dаЯћLoOmЏбЭ†яп_B›šŠ№СCшœ—^ЋS)•9кєr4цќ„гkж]pОЎџФMŽвЯ>—Яd‚PyЋGЁbZ.oi”W€|ˆzЦЋ“2аeёz%уЪe]9Jп_„ЮџsщЂт’ИпrpФШ{гФ‹z#si e˜VŒ7џR.#ѕгвm{A–БЇ9}ѕ†žоQЛѓ=hвЕЋGЗ;bыkЬ9NЊgГN&€–˜Qц ІLОеш+"q?š~^сѕЌkq3ž’юYKѓ‰CђМЕњэ9,ЅЅА”•СiЕPŽц Г.‹`ј9f.k@Ш+ХxХкHМїeСх/Д6Ё`Х2`Ѓ ЄDЇЃИяv8 ?№Ё}7TK—к]Рe3 &) М\ H"x—‘Ѕx_›>ТЇŒѕдqqˆЮЬь8бчїfƒЃБN q_.\k*:ѓ™cАn`yХ юsФї([д Ш$t^єŽtЯaЈ!УЗяœ)HœЛƒ`oh€сФ 4;‹Ÿй='rС5пО†ІТУ, GФfIc{ЄУC –Užл–Г…ƒ N,ˆ‡6%СdќemпzГVlFYECРћ—N'ГŽУVЋGЦыyR№SїѓFиkK9 ЗˆщУ рхЈРzі/\ЧžИЄй№•PвЁCќ„‰ТGЕuќщѕТяmcz`цФоэТ§ІГga&У—Ир}Јв…kЖšsh8ДЦМŸ˜ћХRX§w†HќбOO>юВј=ЩчГИЌˆ˜1c(–Wа;[\OЌн% ?~x юŸpЮ%'Ёфю 'бtц AуЅмЃnяGФS|Ьж/~:ї/U^ц?QAиSКЈпё4dј"іhјd•сУoВЁ"тМќ№и6G&˜68HXhђђ`ЉЊDъ“;ЄRК1wЬ…ПВD2ТœКђmЖФ§­bI ‰s^ђЛWГ§mФ0ББYmXўЪnaођYC–ЈkSBФАрйmzЯG8šWоњЙее‚ш›KЫ(ќўш‚MhјхkВv№щQя .Z=nђ=„ž”[ќК7e­€&*Aaad[svэЇGuЊЉIАbжр€sm‡ЮbлС3ˆS#!2иE|ІтbвџsшЕю7Щ№еи$И=ŠELtЪ=єmJМк0‡[Э uB„ в,‚Ч€ў‡З;jx@–U5тХцОИd$T w›8o2Y№рK{„uOЯ†ИpЕп}УЉS0—” qў;PХvѓD%ф С”ї3ŸnbЗGмojSџр"м_ OянзhЎИАюџ@Ђ?n”ЇЌ@Џ|y/Lf;ю—†IУ’ќцдЌh0йЏkЕŽ‰VVcBџД(мwsКп:tœ&LчŠ‘<`ЂdјL'і §:>!2ьч6ЇоЙЯAО"іі•R„ХЃтгЇаtrД]: тйX|З§ЋX0bЋчmuљк§Иnўf|НЏШяzaqоиœ uэC# 'ф|я7ќ††љшБцпвїдњ‚Œп>иЊNГБлK№уХ _›$€ИџЃз№ХЭX%qŸ §Ўwм,6'ќз™Ь<ќЦAѕц DbЄк‹sЋАiwG‰!щ‘~ї|m?lмвCzјпГTV мЗееƒгooєщhЈ$uмбхэ%фO_R э<Шы|ВДЇШЭЈš _Хцеаu‹‡‚нSбqуqW‘ЇF`с­=ќц0r‹^й/Џœй‰ЭФйДч іЏ@„N…ЇfћЛTЮ*­z=ъsѓб{}ЅдiЊпџє?ЎчˆЏ†N+ Ж_jј„лkЁНЧ@л;S zHмєлпBФ€оdŒ]BМя 9EzЌлš'ˆ№_І‡ћЯycЫ •а'%KnO—Ў›ЌXЕсˆ№Žеї DИVсЗЮxњ,ŒgŠЩ } Ѕ.Ъ#i'РQ_)Єп4>#xИ_ЩMдм_'67бuй?(е jіљdј2‡BЮ рвyѓАG„'ЅaDЯHП9EхFМА1G8~eс Јdnщў_>ЩF™оŒНЂ1g\Вп:‡Љ ЃfRmЏLЉУl9›%ьЂу,˜љ—QЪ[ пEью(’цП!ЕД…(‹,­Г* ъ˜(A$[ТЎЃ8˜WƒˆPžМЛwЋћ­? ГЭ‰ЃЛ`8Ч{=ЋАыО*№HЭ‚­ж5•WЂўФ)dМ–/Х \oф ‡DŸлнМƒdqпvYmєчВсуZ6N—!ўісЋƒeиўk…@œПЮячwoХ{Ч„5‹oICПdп=ЋОжšZФнѕgЉзРЩ—ЪMyћјєK~ќхˆ~+ wZq\)‹НэЩаHUZ:O^ў9 5!(лНNГЙUsѓLЙ.ж?А!§ўп<›8WнеГ™8Ÿя;‡ƒљzђЌš™юЗŽ‹›V}- ЄџRЏЃ@ŠїЋџЙ–#>NvИiАяJ’*_xеœJ?xљѕ",пM†MEъЊэћн"”ќx …B9ъB‘]ўЙ- KРмqЅыœьЌи-<їйYаЊd~ыЌЕu0•”#хБoЅК8š(й! p‹ёўыmј.JzаYоQѕ:Zl•…8љp_”Ќ_"дњ|GќЬgі,Н?іoп [ƒ! ]`œ†уЏСл‹ћбЫмвѕеŸžDбŽЬ>Q˜>"оo ?Я\I Љw›„(амѓщ#ЈлУZŠУ Љг'у G+7HDXF?Н8ЌtsШ›37в“eљ46y_вќЕˆОU9UЈ9’ —ЭАrУbŸЃ‘ЮГO7ряЛŠЁRЪёкМ^~sн'ь#LЅ•HсИњ$BЇ ЭQ"—ЖŽіЊЊЮу"B!A:МŸ%нNбъ‰(znВ}љоњ–ёj.4}gтмwЛЮ м NЇЫ6ф †oЩфЎHUћнЗжеСpЖDЈђxл[ьы 9ЛЩ ъЮѕН-ЉSoj„лyuрCˆЗХО:Ї–.–‚мyБџыщИJэш„й/Pм№Œ†H”я?‡йP%ŠЋЭЈ$я•LБќжЎ~їx ‹ПЅІОйчг{Ќ•EфњЖrѕ‰}§.6|о5W:кМW˜МФx1BŒ64$ЄЃлc_JqЙяЈќќЁPžм Ё]ФP>љ‚е‰Н=Cќ›„xm~К>К !щУ=s Ђњ›W) нlёxЗ)cЅџ ›ГыъI@ iиAРлЭ8RДs!4Yo”Ў_ъэОH#nЦгH}ђ{ИcЧЂtя/АM~;ЛитїLај]Г5`*ЏFєдеђœшX‹sН>Ÿ пнnЭЬКР.БЋGB<Яіє|OIьMфў!б›KѓxwXч…o#fњsЈЮo€>ч7ЁШHКэ2|&Щ№EdЮ–|ОЅјєЛ6!Њ8бЩ|~€MRJ‘ь)И6nd (Z=…d(™kО#ц–eшљj64§gЁxз/0здy)hЂhЏ&ћ7t{b›”ч[Šs„ЗЉр[єHяЇLYеrэ5!€!о„ч?5Иvр2fяDю‚JQпѕ3’œPБ‘ьђР?(ѓ‹Eхс<8-6Ыь: ч*‘ќш—э;ЮSsА™a-Ѓ8aпЧ|Ъдж”I#ЕaЇhЧ@(”NМоHРr‚˜“ЃфE8Й|€а0ёс#f эщш4ю!”-ЁИЦВjXє аѕзœx‘:П§GNvИŸwR(qЕmЇhЧРЫ‰” Уv№&w#IО;џС Ћ—Е6’гŸBъупТ#qПщ/gIoŸч^я.%ыємЃmм+|ѕмрмc ЫbiZшW)B#‘B‰ThŸБ­ВH&”з•rёƒЫme­dŸЏoИОЛˆ^c <ђХ6џŸбiЌEс37тє_ІРQ_с7б7ŽАQРЃпё.#Я!оF1шЙЊC~•ŸПžeуіЛёШw‚ЫЌнЙ^ш(ћѕњHMЊЖ<Ы9ЁjTDРНwЫе&@‡§у$ЉЪЭ№ь(‹їr>хбЭBR%ья9њŠпœЯ>Ÿ ЦRэ;тЛфш A}G ЖиЌћœn—}МRˆЊЖќ™‘w‹Е§я;ъЛdзшŸЇ3Ф:ОАQ€Ы]\‹›П'BјЏ!@џqђ|ƒЗлќ<{јИЈљ"WЮ.QВў;Tр<ƒ{эќџУм-сMО_wєќG€—§ŽнЈ У!IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/host-neg_25.png0000644000175000017500000000221411733011756022652 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<.IDATxкœV9O$G}ечЬ0ЫЌР&Т1’% Щh…V–GЫXƒ„ ­M! pЮ6!ArцрР—ё0WЯбGљUuГгX—єдггепћоwU )%žБaНФKтŠИ!тIт$ё‚ш"r„KДЈUЂ§˜х677я1†\.‡L&лЖ!„аџЉы-Ђ(BГйDЃб€чyњўюZYYš$фУпОХsз]T0"ЂЩре лњЈуЇŽ’( ѕЭЋw я(жИЖёlв ЈДдZ ўЎѓњчЯ_"Lьj’ єM>kЁDWВЎ…ЯYТ’-%Яз$Nт`)?fќЛ 'g~AЩ‹pSїсЕIФ"lј,[шAZ‰яы›ž.І!žeмkGјP QoЋd›4Ьњvš’ЁvM8?№S9A”Ш6% ™сJ3BMЁ•xiЧЪYlАX}=нК2fЌФя„K˜fœЫВˆ‡ T2oМе–аžлN'ЌŠ@љ–u И]Ў“„Ыя(Ёё †RbнWRnD(в{_2,ЮЄ E)˜lСТa™ь!2†diЇТеkˆИ,Ч‚}‡D…Їь+KьjB…WНгх t“Ф$I“ *˜~ЛCђ‰]ƒБJ+isg…вbЮZ*‘|YbРЮ‹’ŽtЉ ›NZТDhЦŠш+Ÿso*'WЭf#іЪю(C<‰ NЈVjLЊQбЅ=*Ш1ўљŒ@6+єŸ!З25К”ќTŸмдk^ќОej# Њ,гѕПъ_њDh(K‡^dbdYТя-JЈŸJ|PЋзbя)YЭŸk ћЇСц2Э{yzx2L|3я(ФTa% 5‰Pݘ(с4еMђыою'ћуЋ_‚џ”ЊЊо чн„€„j’(r•Чr“ЯЙ1H•ээm bffWWWШчѓикквc~jj П}oъDt‡SƒеЃЎRW–"dящ<˜тюрL‘ `bb;;;X]]Хтт"ІЇЇqzzЊ7}§ЭЗБ СrВJПЅЇІ•ŽŸLљёЗдлЅ’ййY}ј(У###ТССцццєІТwЏєѓjЕњбЫЫЫKу‡їП‹ŒчШЕуPЊЋЪхЃCR*•АООŽББ1 ЃX,bccчччz“2~vv†ыыыф’(—Ыz Н~њмб;њћћБЖЖІ ...tј–——Е"нѕ•Š>^MVлэмзз‡ббQ,--Щ7ofф“$*Щ…B‡‡‡˜œœФююЎЮбооžоЄŠA-uж+8ŽУщh%&бглƒщBA>њ!ЁТАППљљyЂ……mьvœœЄЮsй9чS_:йlуууђшшH<є=ѕф7‘М-“џЙў`iИwgƒ ГIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp_64.png0000644000175000017500000001737411733011756023534 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<žIDATxкЬ[ xUеЙ]чЮCr3“H La”AЅŠS­TыD­ЕњдЖЖVmѕѕежчXkЕNЕ­ЕZEДЂДZA0 sШt3'7wžя[џйч†$ХЯž|ћЛїžГЯоћŸжПў}NДL&ƒCšбфШ јиЏяччѕи‡Ия‹џєXк!`b3ГйŒя)ЖЄб2}зŒы–>}гlqЖФ€О8Ф=fуwк;5Ш=Ÿ%ќ?=ж@hЦ€Г]бGЈgй3„KїщWРv5лlе}ЦЉg[Юі[Жќ-Ж+,Zќ(л3Цяьq>лU‡XЗє}‘m*л5lSŒ•ь3ŽmлSЦїЯU€Cnјйk7ЯЪЕч"cFхLЬ2ћ†лnЛэСx@”`eћЎ(щеO^ЉоPПЕћаьїЂЁЋ.› ЦŸŠ›Nљ8LЮ_9ŽyФSVнє—fЙ‹`6YсјэСv|чиџBІ 'ўтПXГВby*pobкжІ-џј•ы’~йe+жн|ѓЭЇнwп}ї>ўўoїD{њеhF @*‚Ч™‡ЙЃчсЂ™УivнcЗлœщ#Дхк+Эj Ж"•IъV+бЎЕOћ№УsxЭ/Тc{я|ѓ6$RqX8ЙнjG’§™ъ{ъ№шуйMТыџѕцѕ===–ѓЮ;яњ^xAЌ>Л3мС…y`2™KХаjУЧ1й6ѕЌеЋWdКиbПiŸ4oСк§яД@Їг9{Ы–-ЅbљžXщDПБЖЗnC‹Пбd"ыЪOWрЎПп&kЙkБjšі#žOg…,8єќ2…ьььЬсЭvqЛ`,xя]П§E‘‰;8q‹І"њН&“†P"€3?[цДиќііv}>ёЗн '?TœйlТІІрёxŽ…BnљЭу„ЕЕkєk›@ OVщА8KšЦљћогw-=іи*ALК{јЃ>ДšєOEЧЕqуЦ‰Ў]Кe ;ЅУ‰Cё Мў.Т…‰C'2№œPƒ…“J sтŸОvŠ‹‹Џ}њщЇ%МшЎšk)Z. ѓAЌ]XXX•L&н%фДэ­ŸєŽгЗЩ‘JЅЬК‡Kжk2eКOжђик‡pьБЧ^o„у!C@@-!/-Ÿ@wЄ‹'єSИђЪ+ЋZ-mђЎGIN) ?М\–-^й{cрВч/ФuТh]§ћјцјЫŽуWё 6г!Ќ/Šіp+:#mˆЄТYЇаfЮœyЪ†ЦuАZЌдtšќѕ˜?іdX;'L˜№Ѓ‰'~§‡з\7їU‹V^pдEАXЬНM1cЦŒS УsJїœЖ`3šƒMш‰usвЄоgётХѓиeњ6Б~ŸћћЖОGšйБК"иЛwoSAAСB›Эvд‡kжџdщЅЏїЛїЃІP^^>Зz b™mЃ†гКХфШЫЫ›џaУ{№Х:биЦ@Юžr>nНѕж?аuW'‰­Пџ§япЯЭЭНяќЉпФШЂ‘јЮьЋёфyЯТвшиxу7ЎеЧ&NДGZр 6Ђ0ЇqЮe2gАЃc›,n*э+ызТJыK“>йяжў‘IЄcНcљу톉H$В!ћё‚ ~ЩPYsмЈЙ‡Кпљ™`f?Г…Бl5щ1+чЉеъ­m›аЈЇызЃЊh4Мћ››ж­[З–юпHdMJŠa,П9!Ъ-o\њAЫ<ы)яl\КѕбSO=ѕ&ZІNъŽuађ \И# ЋЈрŒ>ЯяЈЌЌ<ŠBЙЋs[я‚чT,УIт2HєєŽMыЈŸсZtјuœйl>bwїЇ‡R€y0 Pљбv@г&ˆЄgnKИI?'q74Џ ]]]mД~›A’zzЫэќxРˆЕ…œ}ійzŸŽXЋŽ/ЁtеCЦыqЮМЭmы1|ј№ъt:]ОЉѕCXmjy“ЪŽРъ†Пї[Г€ЮњzhѕіhЋ>LŠћƒA!nLGШПћН[ђЂ™pяX3ЪСЎ]ЛВX7ЈњКšY) у 4"ЉХ”›e‡хU ГЙГE&Ы `Tќ™2˜—oЧ@0йƒ4/ЇЕ$ЦOв­Ÿ=vвђЙЖМм˜,кXУЌсЧт‰ЭПщЗ>ІdѕER!Dв}Ќ=ОэИsлOЊА UК’т~ь"і•evхlлЖm—Ё ЯP€ЭвЯTfh„ЙЯbхМеjMмџpхšц”hˆЉЩЌЇБЃЙЈM-ъ>ІхslžољЧNаћє]Фыыc™еXQ„БЕsУ rШX‹І| О{ЪKЁ;XТԘЖО 0хЙg}!sŸ{X XѓЭнDуХІЬ7ЁdjŒ…яыйIфіЮ3БdВоЧ6  аз`Еš>wт1уёрIЯтй?<ЗŒ˜ѕ8бa{@–}•Й‡ѕ;_и…уFž:Bœa …о>їг;BFАЇцП8aѓЁЦЦ6ЎhRяЙкр.фXs{W3DДCx@/V АйSKfъыОfкЭxцЩg—_uеUП=g1ыА0 є О+ЯJѕпёfЛ!ТЊњіџлТši{{vќф†ї.Х‚Ъ…зžЬіњ™?AЅAПБiнБzЯе‡vї›кY:ЕBˆ,SяЕ#Šgрžуžъw]4ОуІыn^ёаCНЬS2A0‹Y_Ш˜_зU6ћдu­Ћєп ‘НЄЉђлoП}в§ПыЮxmjOЉщкˆИХŠ†чѕігщї]N№yџ  *]ЃУdqЎP2xа:FчЧ' СЌlЖ№љ.WWW‹ч5ѕaЖQкфh_Р6}–d›ЩР€юююЕSKfѕЛЖЂўЯ8чœsЎXЙrх§їщ›Jюz­ёЙ~§FyЊqџ§її [м›ую[8Бпyib}HC!нeЯ+Жg&Л“2n6к'lЛйšйЪV‡Ѕ€ЌмyчKц—Ÿ‰<жийkk~[эЋП6їЄ9ЕЫNкPЗЊeХ]7nИОT[o XGЊуёЧo;HдэО}ћЖN-žyЦфG]]]ƒє\І> 0с‹ƒоб—?g=рс‡і[гі{ЮЌ\дяњђЦпу;ырк gW>Жчvt“ѕН~~е•XБb…T$эЧ–јєгOїVхVФљGё\mmэnщ3X- ЦЩžЯъ_ЃбЈбdГЁOњљѕ™eo•WнЏ4_К§ s' §*ќ[’;ЏОњъ?є* ЯuЎЃЃ#42gьAїŽЬ‡–––Z]}ЮїЧSяyѓПдњдбY#''Ї…дї‘›'>„™EЧВ^ЯЖyCNЧE#ЏХ /М шЛMШйРБ5cш"[™?—љПяЕJзXЩ2~щ3p?р9pоlњт , ќvсАХН›‘еЙгАdн_>ЮђgЗл§pSSSуy?ќс‚Вѓц­эќЋžwЗ`\ЮTл†тиЂSс§Ј{Ч~yУЫПћняўЬлМ—oš—8v‰}(jjjъТс№пqэuБ§|БН яМѓЮњ†††эв‡їє.NЮyќЉЙ%ЇЯ›р9Њїž7_|sЭ`Іo‹LАД­­э‚S™пяЯ!sњј–[ny…—їщ$Лъ|эЕзŽ7юRЛн>ЂЂЂbмюнЛыщвЫ—/ћž{юyУИЇЙOњщ76•ГbйВe’Wы)ь­­­3|>Ÿ‡п;.ЛьВчyўжјљЌъОЧs%T”ѓюЛя^ђілoПУсZМ^я5o:‹ВМЦЦЦіK.ЙDv–ЗѓZз?Ќу-Ѓу3e‘ЌєѕBйц36\ЦŽБX l№эАQѕЃяийОQc,7›нш*•WؘгбgќИAfтЫrЈ{Є4џgpxеMцy 3ШБmЉ хгmp%aЯMтЩM˜ѓƒ|јыЎС–ЇП‡tИ)Ъ•ˆ‹ZїЃЁѕЩL"ѕGmвфfќруф?2Ѕхп*Pіhљ`єrк8#Љk++zпLУВЎGюŒBXх0лМиёЧZУЛчЄ§‹бR_ ЫА1Цn­LСty*žЪБšЬПжž;І ю"VO—P‘O/ўўe2•dŒэУИOЅ>џЭ‡БОс]Z“б>цШѓ1o%Jgљае~R‰АgйЙшйQЋY*"UQЇ3:ќkщL%"ЩoЁЋЭзШ?Ть aякYЈkСiй|{+Ъ 8NЮ‘­d)>+ ќ›х7щћH2+юмчBcгLJоˆDн tmдаEяђнŒH`%ЖМ>nВœсхЦC/zК„=C\s˜5‹І EKыbИLъA4еК&?Ќ–зQTОЇ6ЃpЋ€ZzYH*ЛџєЃ!к1HЅяFЄk &ŸЅСI7~ћQц„Юi(Ъ„В;Ъ† {"Єигд‚еЂ+C+Э…–JQaб*ьЋћ6КЩД}3Ђ‰rœnZЛ!ѓЫШ Ї‘$6&:Ід— Гги ЂРf‚u8`C(8СјiШЯ;cЧтШsЭЈ<ƒ‹Є•&m"AЈ5У]`†+_эаJ˜$(@:­B@š‹!1$—сCNšаDІ'цЇ–Ž­љ:-H0ьyЏЊК0yШ§~НTsрЛь‰Ўo$^lЯŽ ”q.П(’J|hVw„07Юяќ\ОГзœ<Э# €Q Л;˜й'Юž$kІљ“‘ЏS‚_:Ч‹m*кХZVŠ2™ Wp5TTˆ“NЛŽЗЊяaRˆ–нбюіКcq%ŒФДJJЅvњ‘i Њ=}ЩdЉДSыђЯЪДе]žБця0Х-ЕАIЅЈюЇ%ŠsьXФeЯlaиvE№тЎ%|˜ысЕГ,%Оxc\жоїњ›~POgT:3›Ю‚Eћ!І\„ЩпхJ\r#…!˜щюa’Є]O{ЗSгдMХ•T†OdЬёs4?c[Ш#˜ђ єˆ@X%ёˆ\ž/p г5Gы{F1b&йxг1˜Ъh ПюfUХЕUŽW)T,ыцД,тlСИRTЁSžћК”Ф[Ј0НйЦ›с  ќОПwўњТйE ўœw­aы(Ь=жh1†VbкЌbT_J†+kkFдЏ@fуЄЗь…ж†IЃё“Л{`нг„qє„1є&†DГO kМг€HBNЛТ Ї=bžXВћsВgp (ЇчеpЬu еqХ:т??ОпEXБђ"šаДЌЎЌUћxД#ЪЬКЧˆтЬюЂyЛкR rx š7ќГgTъЉ­фHКыi”$E^жr$Боњ>Ат>Є?jзоЬ933ЭKIjпB0™xЁ ‚–ч"ѓъ)tRЂXA/И0="Ъњ*iNї*ћ„iїгƒо@&1ИDHz’ƒТ %ш-UЫ9IsG”ГИ–7v+ь‘–ѕQh8SЃЗѕ $Лчpa8іКЯ„lPЙИŠяЮO€е"M01QбІхт,Ч}Ч5пwyЙEЮ.žˆ(ЋЩЂхГ‹€VKKC+qъŒ/у‹#Щ›Ц–Є,'^•СфЋЭ5kˆ\OС|ŠЩНv#З‹Р"8Ча-!.N ЙувL†iQчНй6d_9ˆ=ГUГ+у7–ИkЎeкнLB64пЎџсП=Џ4Гчzх%Y%e1РQЪЫЕыJ§љRЧЂЙtУ}КLі§ХД‘ѓ3 КICДhЎU Iщž`›^Ж9ПЮaшоBгЊф.Ц—ЭІ_в гЊHžЂ`B ‰Д/‰Œ<йЖižфžŽг“­—m–Ъ+ѓpО-‹ŠE0тna2<hхsg—Gф#ЕrашWС`„НЃ=$)&˜рљж†sL;уувXw+Ах—ŒЯZХюDpiiNфКSщЮfUжtZ =/Ѓqn>*N,Ѓа†­бйЌвІе.Џ›(:lЖЈ{tR”жг­(“OЂ)ія]„oўiP0ч/yd’‹–ЈпYЊ+Šсх ”XuсDИeЇК;мŸ IŸ,шя 8ьژŽ~я я~УKП"ЈМЃRž^л (ц“*Oі§5#їŠ+Ž9зAаt#6!вfEАIг‹ЃИQпЋWY ЧЖXKМAв 8DŽYоЃЮСlЄСд№рЃšU3Р…LgК”рЂ‰ёсžЬА’Œ Љ‘'р FгёU$vэ*Š№rЏАDQ”№ 9guИщ№œЊjФS^–дщЌЮќx1•P5€Л„ pЈ2†6ЫЩЌJg™™*5 ЌЙUCл6ЊчвНшЂ|~Ž 'й.ЯЁ+ц8Œ”Хп YищEd˜&;`гдгиС@№6†еBAє^ыЧ”ТђD!вO0AшБœыgщwж &—*lяIЄф-t#dЉу2Њ№I)С…§In.;ŽМ€ XGф ђЦЯu’eЕЎз‰і<Ч™ ‡яРљ”yhнаЩ0ШсТЛЉ”!йЗ™ЉˆXF­рІИює  №=:ФХ‹ЇЋ8fз?ХђWЯ64Њ˜—CJфЭTŠ—ПЅz,Šo…Шo!Kz8PШЫ­Џ,gЌ“ 7ы…Ž-Б/<_”‘C-<™s’ЮN•л§’MЈŒ!ˆ?љыМ Ћ_Џ\_<ЩbSЁ ѓ ‰?.6ЧЅЎЅВL(‹Ш{SхюFŽjTєŠ;NQжСВёŸUТ *џ($75ЉѓdŠш+мгЉЦ‘pр§ЁX<ёЇЊ­кжЕU‹к~6EЎjL§Ж†КŽьаˆѕгFˆW” Ьe1гТ<я­Q}шFЏшr€@йD/ аэђЫ;ХфQЁ=Ь ­†іcF™`‹Їѕ!-)кхn7V<ѓ™DH\> j"М(O6@фЛзЈВДYЎ‰2ŒЊQ ]\ гщ’!9жЋ.&у§к[пѓbиЈRLЙLCщ1jу#ж­ЈЏ(A>ѕNZ3Ÿ<пAЪи/сWЛЧVNЇЫдd…e,Fю+@ …дyB`иЗ#’ЪФв~­Ф'4Ѓо—вђ _&ž<5ЈЦсхѕXH дюЇNЅŸыExqgI‡Iƒg„ЊHQкoЇаЦt2tХЌ‚›Ф|њуŽфPŒњ є4eiйJEcKŠТJЂEЁФV с!кІЃЊH’дН[Х|~tžьї*ф—XoЂb|a…§”4T—Ї—jyћL#мІа'!8rзЂЈ`я  `жљёS›Pмиƒ9‚ЌєL‹Іщќйš^#єMwЂ)$CДsх6ы…ЫП:wШ5Ёa%ЌЄ?aƒRхшёUћ|zF;• њ>@Xe ДhЂ.ЮѓБ.ѓш€ћeГ$Љ8D#Џ•ф…QZђFІЫћŒ‰4-’Ќ(F&§™[bЛYђ~#аВwQќЇ ОT›ФЕ+ IЅИlpзЛ:Ыг• ‘Ъ0ЫaЯгX](IЯВИd$WŸoЇBѕУ{Ÿ%БЋ+ЫІBРV Вўє&uрW„P‘ dтж ЄšR™tёАO№•+~cОјЬ­кД1]ˆЗД!эb1ј_4І"Жэш#FяИє(м9o”љƒ‘љА@RоŸщ€н4ц_wмпЂа__B„ТfXKЌ•Mж;ф}Э1Я рЋХО3h^ lМXљ ухyКђ~ш%^ [ˆьV '‰Fюh8‚Пѓ•Wˆ‡dЫYQp•RUŠ s~šHŸˆQ}Й%u˜xцэшŸAЋ>CI™9ŒGcbeqуЬQBбš%УхЅ‰7H8HБC”OS1KЈŒ# ~cfž!rсtчЯˆПPд=bLЩKhЇлlXq]~ZќšЮзУTFœBU‚ Uж5@LvхКeЬЊtжпPKЉs’Хђ `* @ѓ‹Ѕ2ft5MТŽWE<МіheTтnЏJ—ŸЅ€QЊќеwиїЄ1ИуБѕИ…5)НЌR—–!іi##М‰‚v“љUЮЊР[›Q5cnх}=Пх^0озRPІЉУѕFfXrLC­EЎbдВ–ЖnЖЃА’4[=#ШIœGЛдЎp0Ти/ЁG8ђUXш/9>04YВ›ŠёzЋАyйEЌрf‹)2фp)€LВ­&љмGdІTяЄ‚цM&2ЎЃК•г@ э Ј%СвѕИЬю7Ў|Œш?є""kaZзЦvеЮ/сй Фљ8l~ц,“Ѕ všмSbEn…rk@Н4Ірнз—ъ’{YпњS~дЗdрй”ƒі§x[ецƒ•ОKУІ”v Чѓ Ч‰рз Эz`~a‡СШ—єp4Ѕія­хV˜хйYL@,Сэоэ ћгр"У‹0xwЊ ЊТЃv{ќВ#šС…ЅH™:БgЯ<джfђf§бy„Шфtь3Mžљљџ#№n ыŠЩХŸC&уйС—Ђ€pZžЎ“Xl”’д„Е"ќЋЈ}w捘…Ъ‘”V вeТоzЕП/.+щ1Рќ–LwbмшUф§o#ф[ЗЋ……ЧЃИф(xы‹`umGqщSؘ7“Ž…џЗb|™Рк|шdZŸ-УEкrVCŒс(NфcпŽcPп8 ~}žkŠмNt5‡ф'Q4ф-ИŠоcќ4БjвЗѕмžUpO…ЙeAnђД8"hы”„КŠ5#$.˜ƒeš•Iнz—Ўћ>œ,щМћж Љs йTљљ—#з}4ZЛЭЦИ>§ЏшЈыжїњГџ{‘ёu1uОъPп]NИ№Eџ §џ' ќџ'РїЙ)Ѕ:oТIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cluster-ref_25.png0000644000175000017500000000254111733011756023364 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкЄUMh\UўЮ}oоќf’4M“ДІ?Љ2EЉh"TнDw‚›@7е…–Кш^h-Е ЗnКsЃ‹"B!„ЦP*Є„жESъP…–ŒэLД‰Щd~оМїЎпН3M“ZjФNюћЙя|ч|ч;gDk[Ÿцфsnя'd’Žјж;жЌ„ŠЯПЁ}ќЌяe; g)нWшѕ$ˆ"н\'JйB~кhќJ/<ы{лXqGЂW3*тy:t+ЭЎ—jиŸ”:о‘хБЪџёЩЫBБ %‚ДЇ,G†ŸЈCIйЫћйЕеrK?tDмZ xЄ›іэЇmбѕэ›щАъG*тйbеЗЎВъИƒoгЕ–ЦЮИjA[kщB=дIž1@meт2…ƒ=žЭЄ„шf6Й^ЯdФ'QКFИTh@1икsєs­HЄЫEа uзЖ@џЈ…Ž‚ы0LуАв„‘ЦЎ”Тю„ƒОИ€4сШNGњW€(ЌGaY‹Л-К.П“ЅЈ"ЙVЊc0хJc•еf”XЭ?bЂ+& HŸ'h№]БЁЕ2лгcжЯДhISSу'тЧќ€tyЉ˜‚бьсіАaiдШ3т_x}—‹ЛеЌjРšАFЅQ†ЎT^ьQH(ƒD-Д‡Ѓё†Y1a“­ЋЅІЧ–QІoіЅўЌG cэR8” Ю[мЉFИ]е}yrj њЕЁЈАЩPgў ю-ІRkEє &l? ёv‚іvg ѕБнiWbйLУb(єКeQЮЪ‚Lш†ЉMdйЖ’Ёr4цюT,H.ЋpЋЕ>ЛЅН'ыu:';ИНD{•6вЙ>HыЫЊ8Г\Въ cыі?ЉІ\;ђ˜џ`RbœaЇ tn3ШЙ[z•л{4ыь~єjиіy&':мЄ0“Eмш•{ЕC—Ё`GˆЁ€щуAScЉІ§lL<1EžяDПЮgПYdїe@•GklsУFЖЙne \ •ШўЉ‡Ђ с”HЈ‚OnhЃV;†l=6л… АЖЖЖх™YяэOт­нqеНКЦНpПЁБL­ЏњV‘’tEH­ДB$ž9 ыѕ:Ž;†‹/nyž&]й˜cЏїЙЫ:–VEЩŽОП€SЧдайLz`ii +++˜ŸŸЧддд–wЪє€hK—cMwФ:2€ЎЃmпˆŸпxyхЪŒуьйГіўылuЋ:уТƒ›І!Уœa1J’§‰ЛНP3зВdvvЧ‡яћџ Юдfqqб^чћвЕ­АŸWC\_},CЇv') ЯJy‚ [Аъš˜˜@ЁPhї„чaddФf4::Š™™d2І/V]<Ÿ@ЦiЯ­G”мхЩЏёї˜]ojuy9 т№!AОД™‹E `œMOO[ъЮŸ?ЙЙ9ИюVmЄмЖs…іT0мяeрHh6ˆЉI{*›ЖEТfMNN"—ЫayyйЪјIГОњЭЧЅb љr_З :b0šgцЇЌэђкFMњћћQ*•0<gф1дѓ ЦЯ3ћ|–WsЏБ[Л‰ž]S‚ЉљiŠ›E,,†Мt”u‰“БЖŠLтД]ŒЌa,МYь№L5Ÿœ›РЉИДl;jž$'Ѓ=1hЛ†ё~г4Щ.­Ф~АPQ2щT05?Sqqкcцš—Ъ%ŒwПnї4яzƒБkxpѓ^ЫсjеСƒцпж0ѓ.†ЙЬклѕЎQw†мНr‘Бˆ|ЯЅP.`fЋ|/mQШч{VоB.^ОФ[Wiњ?0+%д§Г˜Ѕ2ІY ^iђiy56-}Kз”рі§ыdвЉ@з”и:ЖёПж‰ъФџЖ~>ђо]”IIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/neg.png0000644000175000017500000000100711733011756021370 0ustar sylvestresylvestre‰PNG  IHDRФщ…cgAMAБŽ|ћQ“ cHRMz%€ƒљџ€шu0ъ`:—o—Љ™д’IDATxœbјџџ?­1@бм КX@tБ €№Iў'вџ„дNКќќ5ƒ$5љјРŸZ€ТЊQ‰эџ#ƒџНвRј4џјџAWћџнџК8еNK@š_ъh§Ÿ,#MѓџT 8HўšІњџOz:x- œС")ёџ…Ž&ЃY—ЛЃЅІ3Ѕ$ё@с я<) АkAИjPˆ?и`@т 5„т €ІPИƒ { Ф 8zЊ БФO"hQIdШѕ n-б  #Ц Ђ,Ш70 p$œ €ˆЖ С‚ŽX‹Џ d ‹dX€‚ю541k@LТ d 2)™тKоX1@aЕ–ё$SАЅ/‰є@сДTT€r2žd –9TrrтД €pЈ˜РWTЂ €№F<ЁА&V@•Ю)ХDKˆ.–], КX`‘yЩŽќ7IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/user-neg_16.png0000644000175000017500000000140511733011756022654 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЇIDATxк|R]HSa~ЮvмЮёgiюЬІ9Ъ4Б’•&%$’a š BPRQWuбUнvVаE7‘V–ф„§ИЁXг$-KнћaКэhkчьыœщ™3Љ>ояћxŸч}оŠйо;b^wgЈT§AПжx“ƒЇŽІ/ъЌо,7EШs†_ъЎь‰Lі<@{[S,žЦІЉT”r5SЩЩ=цЖ &іHФТ<=h нЛьњЎnАЕ'uа­НcqœrYсзc'Ње]Ъ;Pjb3wƒђЮKcP‡}Ш()ƒcŠ ­щ2il lKнŒљ\!|šM“xЃ О9 жќ€ОКђjаѓЫюЛ“€ЁХј'‰јAZ@@qхr_@xD~U|ќгŒ“—P”IУ”P^]n@Вў^–> •CєЧVч'eњWЭйжx2J™‚Оf$ц‡ђыЬLNжУ]Ж‚+6€Ђ“AЂ"{-Fд1Ј:wNGјіŽERР‰$гГ!hh W;їР˜Ÿ†yŸ%"!ЧVPb9…pDВ^3‹"ІњПрpЉъl\љџІPPoП.B%‘ІЅЈAKjі0Цw+ьJЬМ+>`пxIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/object-group-ref_25.png0000644000175000017500000000270611733011756024306 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<hIDATxкœVkLW>Г3Гь“]^[•‡А" FEА5гšјУЦє-щCIгд&˜Д5iZгФФЄќА&§СПjвZiгFЅšкš–кФ6`—\aQ,ЫВ;ЫьЮуЮэНГЫ–]Ÿѕ$_цЮsЯ7чояœc Цdмпу№П})Щу"яйПu$ЧќуЎcfщљбЙдО“wюU…Љхёб‹ F&щ›Є|ЦцžjxkшћьE5/ЫjћІЎЦБ8‚Ыо(LeъКИ]&JЅ;OrїшлГ W~РZœf$РˆЇUFсp V$p|@•AИк}{ђєБъш№50U ч,+sB/Г8~Эо"е8р<“%^9тkЂЫУйлj~ХvSBŒ‹E(8кІДИЧЂ`-­(rякO&5pддИеuК“L^†@œSхиэжmkшОƒѕеUЈ W `IД”ZИLMސŒАLO8БЌЊЭE’>*%"ђTI0 j1„Бb '@`аДџJ(D‹ B ЬЮ@дз“УЩЮѓйGЖ4њAЁпзЭMЬN€ЃЈ-— ”›I ]НSf(Ь‘и|Ћˆ9 ш$XŒъйˆЃзСяѓТЉ@N›ЊрЕКзљCЫСѕоафZЪ1Юgюію)Ѓы,ц§D•kTmЄм…ns*W˜B.лЬ}I„С˜Л !Z;pWŸЋЏ0CЩюШ^ш EР/пеfx•з3тSоПLЂѓ ˆTИ–{pXp(ЃС|фšю)ЦЁ=\7c`збqсІ-р<жлї9 §‹( Ђ<ЛйЅЕ[ Ad,ќDЮдЊwЌАHЬю?оЙ†Qюѓ5$уE№a*ЌЁHioчѓ\;яtž­Ѕs*9р—‰@ FH7$8нйžЪкНё90ЙТРC, :є9ХыЋM>оM0Hp…дI„cfAчЄJ™Hн}{*š%Ў+ПcН? ЊŠмyxadБKЁќ"FN-Ё•|…`€@JЋ“ЬЎйоо‚ ЄЭQ1ˆzЉˆXSд˜ˆИ™)ЦqГŸ-ю§=яHВ_I ЯšЛ_ћХbадд'NœH›ЦРЎwы›D`Kˆ ,iМЊjаdkюћ=1dNј§~ƒаееiЯ1сOt€Т>œЙv)ьќќƒ,•ЩРРДДДРаPъ3.\€КК:8pр€~Яf3a}`1ЬђvЬ"[(Ÿ ђ#IЮ;ЭЭЭ ЫїњвГёx<њX•UЌЦБСР1gЉйЋˆЪЕ„ љaпh\__ууу‰цo4‚лэж3ЊЌЌ„3gЮ€ЭfЂBАТ_•uц*ўЇи ђR2Ц{че“јжCIŠ‹‹AUU=XGG‡Оummmайй —иQJТО’ЖvMёšœžсIќрэš—шцЭ›aХŠzp*уy‚F[ENR01‚<ІсеЋWуХ‹ужжVLMQœi‰wС№$`ё_•љћФРиП ‡^1Ц-6ЗѕIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-neg_16.png0000644000175000017500000000151511733011756022773 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<яIDATxк|“KhQ…ЯЬмЬ#3I“&M+дЦЂ_ДWОŠ‚HъB\ˆдMЛ\‰;Aq!И’J}а"ИPh*TqЃЖКа­кФRв‡MNгNf&3sЄ6TQИp/ЬwЮ™џў—Ё”bU1­—2'ЉТЗs!qГПŠŠ™LAŸZzgџ(tNмлдћА"аvсK\ˆљЛBѕђ>"bќ0‘Ÿ+@7)tBч|˜ўf˜jZ{heѓчsЏwЮV:.Ѕ”њРг†ІH‚ZETЯЂО†"dA]ŠщЙ"оŽиxCы0kБ˜x=5hLj‡=‘нёŠх#вн -‘„ЈЈеrиО‰‡Ютъх‹ˆE%4%8ДGТ–Т4m ЕЭuЛЄЈ|НФВћ4œЊ]и‹tSУюе!Іi NУq/Ј‹КЈ€гЧBX[œƒњ< 6,—ъB‡‰ЏŠoч%Ž­ёйиЖžс˜2фКЎ'bBзuoO!№>H~?ЮˆB‘Tєт№юBЊФDA5БІбA@цЫАeYШЮЬ@г4|ўє ,ЧAE(Š 9ФЦz kHЃј›YA!ЪBЮ@•ТU\SЉfВY”ьѓœEA/№`XЎc#Јnœ/Ь.@^ї\эхи™LЦsž‡,ћ бйyГ J’T^‚—„чy”nŸ:Ы#@џЕїїгжжVЧi2йKGGПаБЏуєкэ;јж§šeJ–Ђ2 S™Ў•ѓррDЯq``Щd==нx7jЃЛoе ,У~ЦќrЋ@ЋХ††‡–џп‹\ъAС$ИrKѕЫ”€ЃЭ'HeІџ€K% b|x?ърё y6ˆъFкДк?–R?cЏљxˆЉ•ŸŒ'f›He%n7ŠюїZІŸ(ЭH‰Ѕ‹:ћЃЮШПнууЃ:ŒыЄ“}"? M“3ИKі zтŒЦž–hу ТIƒЩ_­œLнН тƒŒJVV—діБ qXyКЊУІ=щё‰›g,{Сы OoƒC CqBzЫ8qЫoК­хФ“žЧq{§Y_vM_‡БйUЂы‰YЌњГЗaчз+м§œEiM@*XO:п6ЙуgлмкРkІqrђа“Ъ=а гю|ш8Ч‚\]КŒAСэяП^†KЇЇрхќ:Ћ'НиЊ'Аяп’i@fН1ъЗЙ\$IRщўћžДлmˆХb:§Н+ џЖ'нDі#­еjЯч!NC(bяЬjЈЊѓ0ЛE`ЅRСp8ŒnЗ[ХС`‹Х"і‚t”+—(ŠFЁZ­ъЗYю€J7ьиГr ‚ѕz9№zНЬЁпя‡BЁNЇSU.Гбцa,“FЃСаЫJЅ$ №љ|P.—™ЮˆВя3a§І‰D @ЋеbclЗў!џ)Г77жЛХхrAГйЧУ”ЩdвдхћЂќ2жeхhѓ0bєKх~Ÿ4#<(§`m[OВюєшIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network6-neg_16.png0000644000175000017500000000101611733011756023453 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<АIDATxк”SЫJУ@=S'mSг)ИsгтZ§k?Р}Ћ аUСK REнЛA)‚nЌЕ(юŠUа$Е‘Ž7“iH/\nцfЮ93'7L •2GЩEЉTКвuЊЊ‚1цД`л6Z­Кн.ТСНšЅђ›Ž|>џЂX,‚“šшWkЗлВ.•ЛPу€EЂZ‚aDгFгРкЃ}_рQj…ТЊЌяФг&АžвIЊЊ[3IWШДL№(ЕЌiШžBN8 †Œъ3DvYXЩ1ŸbІijo” 9/ЄГDЈШU%""Йn(ž[acF„šaZВЇ%М#ЋB*п<9`ѓHˆGЉНxЄћЫоNИwЦ4ыёЪД,чПе,rw~a;чeЄ7™зGЬЬЮсєі8шmn—$Ејы;kыу“qЄ&<јиВ%0м“gєІ1ˆўѕ!\ŒшЉNV.vB&]AО;Л; zЕц§Гя’œBыOЃœs…ЯС?ђбўЖР&Шф“ ьATT+vП‡еНРƒzГжќ`5ŸьГ"6IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/addresstable_64.png0000644000175000017500000000622011733011756023567 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< 2IDATxкь[{pTеџЮ}эn6йMH ЂXk0ЪџЌ#эTД­uFmK‹ХQьCДЕеVgъдЉ­iщдт›J+N‡jhuАSŸЈ0G8wRЈђFБk@PХс(уЊ;VL0V7UmLUЫ‚БCЦ ‚Rв…3aЎC]]PЃBЃDД4Еx\4„Х5‰ЋNЈњoњžF ФQƒГXpŸ]{0ю_bќq•VФДоЈQ0\5Ёlз AMЁuсС$*Д!8:‰ТЧP№ DЁ‡Ђшя1UџMŸб‹ Џ#аМRfsРWЭНЩз№п[P lщ\џPAYuЬ3(UgPuдЈЦ8ъ™`—6!ЏћКhB]4@•D]ƒК‘.И6цŽйЭ=W94ч6ьn73Fё0†mд с5][а шSa)jшXъЧдњЭGSаr$e†XЬ4et+YЊY=хи•МЮ7ЛЁьм?ЌBьТЌЅ–c–ЮXPЂТcАŠ&€‚Š’Ё(ЩДȘFЧk‚Еа+oФZn{ˆfЎœ ј.ѓ еkФђЦ5|еЏ­Xфжbзx ЌЛ~ v_GJ”:\‰aС”dBi lЏpњ^\ЂBkz?Љ_ЭёиІ,†Џ5c эЯЭ:„Ш‘}4Н§УwбюЧ;=TйрБW@9ІIЮп€нВ’(€" œ4Ќ˜ЬNOЈ€PФ^Q,‹ЄШ˜№Ђžу31Р9š‘ZdЪuёћЊmпV“ю 9Џ5 8Z'АѓЌRqбаRѕ<­)ЩH[TЅэZ#:ўLб“)xh0дВ ЉёUV•У4ш06qо’ }Ъ—ЌъGЈХJЎ рАјI ПѓiЭH•šё.‚кwЂ‹&ZˆБ,Б}zЂІD шЫfѕGг]ѕБFŸ0Ф1 АФˆрКаY.UЈќh§• GVЙќ,*ЯFlqW –1@/DЌqаљhёccr`;О№ЗЁ№W-vчВ2–AIœhЅ:/щZРЊБLNєжЏЫ}fлЬЛ•—М7 Ы{мˆT/ји‹j1њ ,\јЩЮЕы X+6и ызM\шmЯў™8AЧt $Чžй+ЋaaЮЅW}нъ™‹7ЏЦр Z ,щРњuwj%X#`ў—ЙGЏvуМЕМNŸ‰!ЮŽињ]ЇШ=K•ŸВlP\(ц„OУ†ˆН%­юgюбkБ0=.рЌ@В0Г\ YжvPf\€qpи€бyмЩФњ%ЈѓMГ P ;Ц2tОёмAТљ‚@„ДэІJєа1И‚м?­.рY‡ Ш:O*|ьФКН=ш0Ќю6н_ь,р„Є Х+0Y`œ*AУђƒ_лЯйиџdО>6OsRtШž3-SLШ&ГWƒЉІЅ‡ХedВв уМВCбЬ*„JГWьjБ4…-ˆˆ`R(† Œ‡"ЎPЈлэˆn‚ТЦfИ ”“‹гЖ.6`’˜Ох03 ШdСЧЬpшH„hлГ|91Ђ€оЛЛRž[lы>š\ьВ.ѓƒiPb‡? Ѕ.™Щ.:XпЁ6ОsўёWйŸЈщойššЪљњЂIўDћЏш—йhцоЫіъ ш:дюефсхš<тзŒc> Ÿьоќ"v“цћЇе&ДЙМ /tбBПНхoфбoc"]р2юƒ•OрХ‹D00Ї.r iвЬЮ`|з™№dЋVvа>cmT3хФhі>џiЩS=щ9еcj3Тl„ ЯЊРј M}КЯєџœуБДШЩ>khƒ$Сф5i)€”Ъ/’hћўw7 IwN:Pa<ёЏшЊЎ>љ[Щ”ЖЬу"–ЙЩіћ6VўŒC …њ Ђѓю§c№{Њ—ЃnъžД`aдєлMU;ёYЬ‰зd] ƒ+QžNŸЦ„'Ÿ^ђўGтЯУЂv]™ŸW9­нв9ŸvHпxъљЁ­ ІЈ(ФoМ7нИЏ$Ž4VVsР њфХ]в5Я]йveZRџ‚Яп;].`*”ф[{Дѓ}ƒWя|-О?LШuK=pЮ"<^\Г8Ю@ё—mˆŠšМbЂШk•)хeН єжpШЫП Лє›PЬ„jQЊВьh?^Tг2R.ѕVѓњФ9С~нš@-ЉЉ“єИМ;џй=ЗјХП5E›{Ъ" CА{Сf˜ХЫ•7q~щкю] WxзЬ] шч‹ЃЊ~|ЯЊбЯoЛЗDŽЎЙЖZйfЄдxžщmaУšŒХ‰ -&иPјг4Є›оЬFљ IжЖwŸLCŸЦбя9—=ЏhoЄр+{,x)Š ;z фЃ|FvА™гј 8м4_Ј?Йs Члј+ЅX_Ђ][ХСoQЯБZLЭђ3[z?J@$(ƒŠ1…CИ,x%D:ЗЇњЗО™НФЮ№ЙzЕчй@[ "!g>qДўPѓЛэЩЎпН0бY6ЮUEQЗ|В'§'Eр]cD]"аœ„іН1zюї?јўIА>ЊЊНїТќˆ,'ooy; ‰aEЗчЪхl‘WвЁзi&iГрЅmОЗZBќ№јkˆєJ–|Ђ}t szuŽ9ž“Цksy.ютGЯ%ќœпјц/јNэљn№c”у?hIAЈѕе#ЉоЧў.Gп}_mЇuІТœЕ@vѓ_rh=!Тѓ–ЭНИf‘МXPEбZНЧ0иќњЧщЁwІ‡šžЧW?Щ(РŠ—џт§зсяЊ]В`ѕœ%nЈЈХ8…ш8ž‚ўДSсSН>ƒЏžШч3a˜;CЎђѓŸК’q/\OИY+дф‰іє№ЎwФР?w›“ р8б|зVf ђњ.мѕ3Тз|“АѕЊие“~i7*r—9сЬ"KГS€ЩЧSqAгЦuж:ТU-E>НRш}ЩOn2љє˜{к”` ֘+AŸЁEгч“йчєЧQ@vЖЁ|ќц‰V#цЮRN\‡хSnђq›|Т&ьe+>“V@Ё­@мŠХЋ`œљПУg№љVРџLK0ЭёчeШIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/ref.png0000644000175000017500000000053111733011756021374 0ustar sylvestresylvestre‰PNG  IHDR &ЮрqbKGDџџџ НЇ“ pHYs  вн~ќtIMEв 8'VL}цIDATxœ}ЭNУ0ЧŽгŸЄЈB…зс§Ђт€P‚ СM‚§y9Є.ьmЕЃ9,ќ›—Їg(%$œУ‘ЎбзЁкn—aдД<žЯЪІхG)8l6ї‡ж;$+В›JЫ"3™ЉXГЉIжчЩї0Вь}•Š €‚ЏЋ]™€d_ŸmГkілЕњр’є6OTa%$ !є}/ЉHуt]$G§‡(ЅH†ЁHEК\^яBRŠ1JЊыzGIѓ<_ПЃВp7GЮ9Циuн:K’™НwчаЖmUUу0ЌC}ђaПD­‘ДПРЂIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-group-neg_16.png0000644000175000017500000000156711733011756024134 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<IDATxкt“]H“QЧџяОuгіUiЫЌAЉАDІeHbСЌюМш" Н*Š CАќL‰%dс…”hYA%eжњРUkшЪЏВЖцк\ћpКНящ}wс…­Яѓ;џчљŸCB№П•sдxNЁ‘жJ„”"ьYЂ~yЦуYžeТбZЇaї —C§^ќЎ=›№ќ|>В3$H㘢цУ§сМ§"…7 jd!uqlё1]‘ДяаRеkфЩЈ8yѕѕ-pКX€™`шUм~AЙ оэ[2dWŠЕ"lоЈз*Ра &&& TЎaCŠš;@уС[q/ uHГ)…•š+&p8\№ћ§˜šњ ЅJЂ\ Ј­œ'Ї„Ž^˜п:m]Rѓ#4uК аю J'Чbp\Ћсх%X­6ˆDB(ЄB0Ы‰<*фr‘ЏННp}ќˆ}==0O; р-C*“ChљГ^мK—pЯdFKK3ЪFII)ц=IЈН)!‚ёюn|юш@4„DЉ„Ж­ ЗњњpdћvМ8{ОйYDXйЅ§ …0ќь)’“e0X KфЛљ­—™hЮБ18Ц(wз.ŒVUХŠeiiШЉЉСѕї*ьЯ•Ёє` ~Кфxl сѓFыЈъЮ9Іх„šcerjMƒ/‘Ф@Iщщ(dЯlЪ шЮЛЁ?И|RМ4F`јlЗф_|§тЇЌNД­­кэ˜Œ e2\Н пЦMјЭ*a–Єhъ•0|^иКр_ДмсиМ4уѕгМљзЏёЧbYБ2Ъіk}ђy{1љ=‘8ТŒппЩџЧs:!ЖчЯIf&Й!’Ќ,ђЌМ<ЖчbЄВ’ьvrЊyЦСYЙ:`ъш }M,™ƒиGGI$$oЊЋW u:ђУў Pхф@ЭNн;9‰ТЎ.Ь%j0gž@^Cы7“ѕHKпїjЙЯЄcћА`2сЁИЬЅПmW2š—™DюеˆЈяCCШЊЈ€H.ч^Ќ{5рЏД›ЊбIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/newobject_25.png0000644000175000017500000000224611733011756023113 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<HIDATxкЬ–]h\EЧџsяюн/7_Л›цУ`š6D &)QHгДЂT)ŠˆVTєA,т“Єа'щƒ"X_,ј"hпб M"$MTLLMЉiЬЖЩкЭ~dПюо;у™{wуnнMŸ8œ3ч7sЮ™™Ы„ЈВ1’ЊK›ВлльrлЭQЩ`с5fщ{>ХОJъ ’7IŽ1‡++Œм§^%y›ьЎччБJ9)™АŸф”тђНъЌЛ3мpјYxлї‘EGb~LO,]7ѓвxJк‘ќT„8Њиm+Щ’n_їˆVsпАсmюш„‘OЌ‚qј›Cš/0„єњЭьЦвBˆlgIцI^"™Љђ'SдUЈjЄЁџs7lуz"ј˜& јkСLjъCn-ИЯ\››Єy]$гВ*ЋрюОjџјэtфЛ‚f:ЖZџР‰Е;::ћ˜‹ Чс‡Т}ШFVзЧОŽ›Йl[hјЙрЃ'ыоzЪN|№№ФЮ! ФV*.=DОКпп3€дТЬЯ7П<Ч#пg"Е}ƒWj{„/|ђ‡lY>ђЬ>цаš…™/ЏЎП&Ы Ё МёJ7ъќ bIŽ?§<Ÿƒ0 xлЛz:NFцњя‹ёЫуцђЙг-u§G—‚?YЧ4їQ!эЇн9*—pSHEАV…S3э“Јg#O ‚Д+ииzшёЎФќ ЧA—ЮЉRUхЧW•!^By\ qЫeС  ђЫK˜n/ ›"OšЕ8œ$Lі+AœƒЮ„nŸ#ЎЇmЇ@ZBPŽ<9vк0K—фD&Yц ь’brз iŽЕЄАњ-/эXШoЏПkщlxюP38ЇўЈ‘ЮŒ‚ЯХь{–й7a<'p}C`%.а~ќ^$u “6 LИuqœB([цЦ R+Wщh…ЛЉ Ьэ%иЖpљ} <єŸ OŠœЧвс8ЧЕЈРљЩЉ ŠЧШБТЕъ -]гкг0E›„Ћ>`СЪ a*S•&ЇhЕБ •tŠc=%M›Д5Ў)Pд‚sVR VОrwРl„7д„\"†шЬј2 нЕyџНйё>pВ9rШн жО˜л§ЩлPysYКœ#“Ю$ЃГQкЕ|ЌaЛFЁ;э№(2<”ЄњŽtjЁ–Q=Q5эjра`Паsж–LržJ&6“W~Ё s\œвпЫТеs6 љJXa(„‚ЙU+<ХаМ0Є/ѓљЯ"šЧдѕЇoЭNОcъЙzjМ1=ЙIњs’Гt+ЬяњhЉt№Є3ІВ­ЗRq+eеЅXc/›JгљЅ3SчЧ{єЩB,Hє?_Ц"Ф.O{@•Vн*qfYсAšЋъ $0pЉТ-lѕхdлэЖчђ_!{ј$ТџњkхoўцЦ–Ћ•ЋIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/big-up-arrow.png0000644000175000017500000000060011733011756023130 0ustar sylvestresylvestre‰PNG  IHDRрw=јgAMA† 1ш–_7IDATxкэ•=N1FпŒз^Ѓˆ6 wq~ЮBє€6% g ‰*?{иЭz(@’,yвtЖч{Ы†%K>aяе§ыDєz={xМчЂNСZoP!ѓ$M”eйК‡Crё>p|ЖOгYdM9чШcDD >cЛЗгЊ |.0Г <'Л,ˆ1FT'Ž’Сккz+VŒЧdšсDqЮ1Ћ+3КЋыžю-ДXhѓˆŠ"ђ–ЅЌ_Р`ЅгaГЛѕ+F8ЭUD„”fіV.бнифhСšk0}žрœ’ч‘”uJxЩQЊКТHФ<Ÿ?Уявпм^ЃЂЈ Њ3„ыЛўЧNЋЩг„чiЩхЩе—чЩœGэ'Шђ?ј‡М7be!;HNњIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/compile_16.png0000644000175000017500000000124411733011756022560 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<FIDATxкbfdddЭЬЬФ№џџaaeЕ"~~ф?ўhќќљѓ-PЩ+,€ ™ѓїя?CCЃњјФ”M2rr Ÿ>К№ѓЧЯН@Љї ИЬ `ddT_Sп№пйгы/'gю-m­BWЯКCG1032§bea}Œ_+#Фл &;;ЛЁo@а‚ыЗяpˆ‹Š2dfЄВ|јј^ёњЕыK€вџБjgbf`bac`’‘•Ыѓ \{яўю—OŸž§§ул6AAž/sчЬtєіѕоTЫ‚Я,_Пzљіђ…s—ЮŸНћьйГE3fL[КdБ[l\ќжџчsёŠ^8sWс6C8Х%ЅІ(ЉЊmњI&hneЕјт•ѓ_Ж^|іџ№ћџџwџw›ЧŠfŠУcШрF7йЉљФљ˜е_џЯМњlˆŒэЎџшА@Ѓђ/3ѓзПў pїи/ƒЏяЏџed5biXОЩ•AоaЯ1ŽЫЬЇwўУHHш@Gє1ыу“o™o8§їј]†kOџ3,нрТ№ъ‡ю_=ЧАхxCјЛcФ GЦsіќџїяфПџџЭ˜€б6$Ъџџo[AFVbRлг#nŒв6Л€†џЯРh Дe]"ќі§&Ъч…џ4S]ЏЯоѓџ?аџџ,~§ЪРФј‡(`f#ћЙП7пўgfќДCр4Э‚ir”СА„ŠŸ”ѕЮџ2z%“A|€QО ЦаГТbIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/continue_64.png0000644000175000017500000001262211733011756022761 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<4IDATxкФ[{Œеq?чмЛын{їх]яzэ–ˆP‡Ј"<ŒлJ­1N()H­U)вVFj…‚HАхЊ…„Ti)-†ЊUњ MФqIеJI‹RRJRЗФа8vы$&іюо}Пї~Ї3чЬЬ™sБСVВц№нЧwПћЭЬof~3sЎѕо›Ы№ч`•`ЕТZCG\Ѕ#GŽ\SЋе~yqqёЊzН~eQЌЕ§ЅRЉŽэј§ЋЋЋ +++гpn4oТ:Ÿ§A{{ћї<јп№И Х7ыеуKњГ— л$<Ў5oМёFЯK/НД}~~~+ѕ+ єuЮЙk@hУБЅЅХ”Ыe 1pžYZZ „G…„#Мз€kў'муЫ№ЙomмИёХН{їЮ7)тчІМVЌіgžyцgЯžН„ј НEЁqЁА(4 Ь‚уТзf”А X^^6€–pd… ’pСЕ^‚яњ\уШ#<ђњхPФЛUZПVхЙчžл2<<ќQИйлрпУVЂ A№Иyњ`x`сœј~? WA}ѕ№И^7 0ў*c~С,,ФХЪ€ПТњGјЎУ‡њўЅ(сbРp/“oЗНікkWМњъЋ;СZП oB[[[Эš5kL ьЪ€ј‡зпW№Eњ.ў^~Gс№œF8сXауyPИ•™ HЁЯНы‹]]]O MМ%\ЌиЯбъ‡ОmjjъNАШЃаmІ нВІ,^жFKћ(ЁЉ…Х7ёЋ=ў+№ѕ"ОOЯ OР#ZОQoTЌ*ІЇЇЭЬЬLpКџЏРњќO<ёЭwЊ„‹UFі ЌоЇžzъSsssП–ўДv[[[А<Тž!nяx7hI†с^АР&Ђ‚џХHQM(AЗ№ЄŒее:ПhІЇІЬфф$ЛfŽЯСп_М%\H–ТОчиБcПtєшб{AыBлjЕj Mх[ ўь\Š,'жDЁёyQ" ,!Xкxyн(с-I‚Ў„жї>*/И*”23=J˜0sрE yўj—Chљъ+ЏМВљјёуЛAгПSЉT‚рxФ€‡xwкт,< ЋŽс1&tB#$Ъ]$7Q7сщFX!…BRPoдCАœ3уcу$џюэсЧ{ьЧo‡† )…ясЏ;yђфИ№‡;:: .„|^Ўb“еYаp“žЌІ”џŠЙFŸРЎ@qгdъ`m`|AзjФЬ"ЃЃ#І6:Ъ.ё$ц?%ќшэ‚лљ^aтФ‰нpsFШЃ№m`}Œјшч”`1пL-с†S]–њШЁТYŽb…J/|…;UxЊMз'є9<"Ёrq€[ДЗh)™ѕƒƒfpУxоŠч§!(трО}ћњ/Є€ђy^УhпЉюг Щпююю6Ј z%"8,XДЂЫ…дgХ|rLтњ da8ƒвМ!ЏHJёŒЎxˆџѓIqЎDёƒ\б5ЬР@xТНYSЦ:DlpуFГЎПЯ/ВŸйГgЯo]H–ќОЂ§•@4v‚Х7Ђх+еŠ1V}Љ2‘фkЋ2B“ХEkJ8“”Ъч8'яYѕžUБ…Ч@­Ы$<­–Ј„юžќЬћР•wэпППїB @Šл‰є‚Ч6$8h§Шьl$:–N>о *JQж.ЁЪolі+Ы ьЂ,ЛŸФЁx/#№=‡5œW…ћя bряcP`§бљ€ЧЪ /М№Ћрї;8Я#Нe†'ФDЅMOЦ4Y>ˆ$Ёл›$bЎЩV… D-'?Рje ’Ќ№‘PvуgБƒелЗЮЌ[ЗŽПњЮнЛw_ЋНTзђе‘‘‘@ {/Z§о ьЯ]РшЧqБМo‚‡а[мєЩцŽ (“Ў“4Єв,)%0PqЫј> ”Њб˜ж†,ч\ЎpG3-Я?џќЕPй§&зьšЯk_з<НyБи^ ­МDх}Ћ#Н”2^И)‰*хВ>4‡R`Mœ"WHЉ\ №яшь0}р Ч>ОwяоkДBC›pТ/ŠѕЉ”Э­œУ>S@цоЄ`СŸуІ•Ђ‡­.(№š’–ф3SXЪёьёy Jф:ЮС8атА(`МbмЁ(ќЉSЇњРїЗЁхQЭA )nŒтјОщ<вRžl†Œиf*тЇb‘š5JtЂGЫьR1PЃг#"9ЦДЕН’n?x№`….oк_~љхэPn^Яm+ЋЂRf§тАgOбм7ЙJоЋБ ђфэЖ‰41…&Ы@HŒай…X' /JP„‚ЇCWйжііqюfpїБ*@z~}OА6oWЩђщq*kЉ˜С*ЬYЩыMDЮћY(—\EћМДTiZGаWЄЋЙжЅƒ"ж ЎтAЯкž€‚ЈXП]›+++›ЙkЋA}.ksG'>хзL“+ЈHЈЏ‡ЫZЉџsš”„qkД9I2Љ@BЅ0AsЄIЃD”Фˆ2wwї№gЖтХKЗоzы-ЇOŸў>[эЈЦ}пcщ=ЃZ^&дъE ”Тд9>Щj•хНM$'Ѓб6Џ.ё| vЦeBЮЫШSќ\ ”уБdoз?тjЕке`yке,МЎЭUГВШ Э=М"ыѓ *ŒWAQEыs†`кД|S+D™нБ‚ТyQi‰"и,fC —Ј3ЄЎžюPжУy%`†з–чччЏфa…P]ъеEЅ{бrQ(сTЇFHс–VЌ‘C‡ІкСfncS-eВ6 ‹О:HЮІ QМУ5Y/сR0їЄhуAqO{Ђџ{xRУщЭЁХ­іС€я”zXI:кгџ2B”eИC$€Y&LЉџgТћŸ=Sj/жЇм™2…БЩ2”9ыb„”Єtяьъ2cЕfМЋЫ@ ж ш&авБ иВ ш]Š ™kўЃ`Ю3ЗАЪTUe~ѕ^uŽМ S„7ђ\zЊŽ№БqЄ2 ыЎ‚ЁBдв=Ш}врО,џ+aO-j‘ЧпЈАDiБ›уUСdђ§Є0щъјTџљTC‡Д‡PАf—qК7lUJЭ{ЦZcГЎ—я!Ž4l,єbлlАEз™! И B(’іТЉЋы š…7Y ;БПœFГЩ‹ф;т:СхЌЭzp—Щ}Де‰ЏrНuЉЖё^%:›ѕ+ƒŠ@ЮіJ{`Миљ*УEкXеƒEMогK}zbж#0ŠŠБ4#С‘П7qjDњXк„vЖЊQй:(3ф% ё|‘8 ыЈJ ŠёT”\F’Z еcЬƒяЌ”Љ.iЮКЌ,ћЕjDzнШ0О оDујšхХ‰P( B*ФџТИРŸK+­рд п[Ъ™5'Б E›Ђ~ъ/$єqЗšп/\lŸс8G№ М…2И‘*ЮкА 6дP()…Ч`‚ТXNдеЕ*Њ3”ы2 ёшЉžˆУЊЦhŠт<Ж‘ЯГе,5M„ “4Т‚иZ‹Ч№>рNšqА rN!F lРB& ›(‰  jN.WЇbsœіRqTаДІааЃ1&76СвJU˜КANžЫиК‚kъF YrV•6ЫV)_Х 3К"ќ c x”p=юШРшXђхБ‹"уфЭl-RQGP‹^хн8В‚TŠ7–žVѕрНŒј=Ё)X›{ƒYЎO|пŠ X‰QœŒ&F6Эqˆv*ў~ŠDш$юбAŸшшшXдC“Ќ"Їуb86”‹EZœъДt#ьь hЃHэsН_Р4ѕј‰ј№Žця}FWuFu‹„ zъ'ъ2Yз“ŠУе–—тЌ\>U-G8 RняcЪ бUMhTн.‚уЖ–F=ЄЖ"Т*B‚fBOъs.ЌOї˜ЌшiЅ6Ж(!"€Б•а’Dчяс i)nуv›0jk;Q†ЪшиииXb@iiy‰іѕБW‡а ЁDЎ‹‚тX:VgЅeХL?зТGŸu‰пЁѕB€knЇœŸ†А‰2GыЛюTљ‰нœЭІIГггf !ˆKооо7м=їмsоSУТќ|ŒкМЁR язС 8‹Ч…nГ k^ЋL"zЉ4цдhT1%ТГk&сmГ№ NЁiDчDиј^Œ %ыD‰ЖDќ?ЏуF ђџянuз]Ч\Єјі?P€……E bœХџAахexeйдAYѕzCzFѕџ$Ъ[Ÿёё4DOеŸЃ”&c7чВцЗМK6AоЈљЄ!%”(c`Ь№NЭ i-8\Tљџw еvuаЦПa˜›› ў№.( БхW@шUTРђjxŒ С žr%ћcкyЁhБзХJj€„ч%šЊМю,O‡*J.o—9nxКЕМ98xh•T{Ь™љ™Y3.€Fkooџ6ЪpеUW§+ПJ@џ‘@8sfXЋ+1П•nyЂСКˆ0Yvd1VŽ2› F(3Д)Т љЁ^ Q№чщ:b‰0NfS <ЪџЮж­[_€/ЬС _Gј‡}x pНБ|<ьр Ф!њ9ћociјJЙ${‡|Њч#6гœЃIPкТФЦI0u1њг(CЛ+$Ою„'X—7J1їOMLыC)ќ›nК }ЁС„ЎќЯ р‘ЬЬL‡ Hшuк•хЙ`)|6охёЇ‹ЊIQAёjЇЈч,пw‹а%E9†<0eсTpГjяЛуРIJœ˜ AўўЏППџЋh}F@dhhшu8љ+hхщЉiГŠ(TБТVхЉ•.ƒЅдŒ}ярVЌдАЃd-uЛ(H:ё&џМM­+›*œš …“ХВ4w‘Ёl`§#Лvэzw ы"P№eм~Š(˜›™‘|цuOOњиF`Ь>ьѕоkГоC<ьЩПySYмщ.БЪ ЮI{JЩEXaЎi‹k|Ќб?4AжŽЋœБžY<ќ№УИёјKhмŽ:K)ƒсhЌV–Ц>K[дГ…qФfі^Х‹’JY˜ТŒUR h]vd6ш\“ЇTЊ2ОЩIS‰[чРР‡!о%јћц=BAžЕkз> ЧBџЧ­Ј§u›оЋnY#‡XJОхЫЋ'ѓfxЮd.сU‰-“ ЯеЃо8Х-2О7Ь^#У#!ˆCоџњ7ој%8m…pЮMRўСЁ>Фо9Нџ7(Сzх^x~Ъёд„$8H$‘]†ЌhГЌ ”жЅ§‚й.’RВИ"”р”QB­;|ю}џЧ]]]_Их–[Ю’ќЙ ‡њ&\шs$№ccЕ|`ЃЖДХeГў]V8ђq]з [4№ŒъˆдcЋ,nŒv=:O 6#g‡q“uQЉTў(џ7Дх/ДM.ШёјууЎы?GhG$dЛ5 Ж\мЈ‘Е†f>О2йfRž{Т­4i_Pњœгу4vЕ%ЏV5gЮœ ­/ЈјўіОћюћ+xsёb [y€.> ЧПAю4ЄYDMzlиНed.ЏїїpфsвќаЈђЭRNŽ.C…о “Ђ~r+<жj5ѓггo†œ~џхЭ›7оš'ш‹CYЁ7ќЇ№јŽЌpВšры$ђЇRДy(aг8лЊ4Pшпи,ЈEhЅо˜Uгž4S3jfчљ7Oџ$ќВ„vгІMnпО§ДоПЋL8pрНТУ]јМoн:3А~}и8­ыsюр0O-,'MkRЗ'K_V?vвzы{o]Ы!к‡§С˜Н@јУ(ќŽ;^WQп_вo†іэлЗЪ~8?ЄЋЛ;lB„Д*:ЭtrMКq“\CУЗ™ј8•&›…жЂИ!‚y~td$Ф) xрѓwУ 7|іц›oFЫ/P'Я_Ў_9(Ÿ†#Ўї•[ZТ&Dм“[ЉTѓ†нФЈѓw“"Ж#Ш;UРшзтє‡к`J1ШV'@шкHЬѓ ќOЊеъюНїоП$Ÿ_>WаЛ?›s{іьЙ>їIxќQ|ЁR­šоО>p>ЈГ+”!JД5о„њ\ЪYчDIŽЋFсэš“RЌSH0сc‘&'ЦНХпAyћ|ggч“wп}ї эЯыѓ—эwƒ<№@/%м{{'Ќы№QИЉgmЏСпXkTE–SUMwjY5ћ{˜ыСgчgc3yЩ|hн…yУq ЗOУћ"@ў qќњХ ЉП Ÿ‡yфлУc\Wѓf+ŒИЅЋ VgЇ*[­ŒНcз† c§]˜›mЌY(ЮТЯчbчљўеЇwюмљ=xОDVџ™ўt6ћэУ§їп D`мy;Ќmњgtјƒ‹J%ьдФй…ЬђRшлckn‘кз<МХ~џ—СССЏрЧHш tХЯKйѕzшЁ*Dфс><ў7рЕ_У IйLnыЋ СЎТпУ л0fП&гЕ.!З”hЕ Iѕ~ЋZю оZнј“\М-$PМ‹Н^ѕQХj.бlMМ“‘yбЏЩ‹(eУ%<_XГ€Иі%|Ш„ы*В 8фИвi$ž1g“‘ІkЎЊ‡Џzќ<.Ж Y эЉK8 <e•L&JsІуц. Ы(˜уU‹t…LРСa˜рƒоSЪNђƒ_ѓ{ќ7Їё8Я ЄЃ`Ћ:киB^N)хI6KТ’e2|!~W ™Щ;–ˆ§Б1Щ4гЌМD8л‹ЇЈЄћњ9цqРсjk‘,kŠ-CBЋvЈА€rx6Ўф&›ЮљУƒc Ѕ˜УJпьo@иою@&$фbОЕ‡уЬЦйтќdлz,Ÿm)aЉ2ƒўРОS !!PќеЛ$dєYЁ0_ŒЫ s“vЊ†9‡„‘–sМ$ŒЛЖуа`yfи€w:™ЋI,сЃu ЌfЌpDРKsГ“ŽzЊј№i)—‹Мёќ Рв‹щД žs:>­Сг-g№З71kĘх[и˜ЭEСЛ]ад$x§Мuѓ–;ј:РC#5 Д#РПјяХš˜џ™u›љюбюХ/<о\."^БчKЪџ[z№ЏКLџ 0˜<0йj‘6ьУэ„’ѓІO’& œT2Ќ—557Eу|МСИ}VгŽЇЬ™3СЇЗ;h;<š2#mДdT7Jы˜ъ^ї†я<ўЩ‰LiєщЉJъЅЃуЏЯmе]ќwќ?ЪчПшDeю-(ЛЫwкр{­КZќщxœ,чbћ—яА}7гˆu чѕ™ИBSІ‡!Б“M­“Я#7јЖ™№ЧРIР…^)œцЉP$yPˆA!^у)v™+фMЂауйГ7§?ŸCы^Ф…1„п€8Šщ€7ЗAXNЄеЭЙbЌн|0(h„eЊёЄqХYzџ§љWjOМœGqtэ"ELИЌЅг‡LQZЏК*гQ”"Ы0ХRQYЏЉ.q[ЏQ/H‹ зеХЦWВ9ЫЃgжрЙ”•7ЛltвќO—ЅШЁ˜Сю‘Жёўy$’ сцЩ…G2{r`э@gПФњъ^Ќ-ЭicƒРLH!Ѓy}ЊКOД№dTе ˆpаy€оИC2 ЌмrцRWЭЖ™вЫtyЉТЄuŽЕї^“fhЏЦu,†ЗтГкЃЏ™ЭJZŽŽЧ†wђа}†ѕ<šїЬкј€ŠŒwBT­.Ћ}‡Џ˜ы­Hn3OгF&йцG™ Їg/љПЬы{&E`]‚Лќќ•ЎО2[љkЗJиKЌZДР8Жщ?ёў fŽЦNPkхѕъ)И…рbqxі=§He&рUњј[€Eю™zа0u‚IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network-neg_16.png0000644000175000017500000000076211733011756023374 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<”IDATxк„SЛNУ@œ ŽС‰%JК”ˆ–G дHЄ$u?р4љД| TИA‰:PрБфeя|vŽ`ШЪЋѕЎwfіD6‡НЫnЩd<п{žЧq „%ЄiŠщtŠ,Ы`šЅc›}Ѕ(Юf)ƒ–™яћАXе’$Qёє&ƒГ Ф,ък.aЫиlW;‚ћО`UЉ ‡—*~0OТ`o h68:yl5rЁ(Ž`UЉЕЃPеъМРu[‚ZNl1йн3сЂ+~†ЈEQTЊНГл ’дЮ2ЁЫ \•‰˜фс…PзЛ2ЖVЈ…QЌjЎ­GvH)?ОJА€Uг,dUЉНiвл3н‰|Эи?і*Šc&ЈP‹ywїK oъжрЫЋBЏ4}Щ0™LЬВтъїћѓ‹$‹;`ц{<ХЩёЭЁЄžyГ"ЭШ$люt<9’YЈнX•N(&2s4R%щюЕUО›^[ЛXЗД pоыбВт—r‘›JM№я)0hщљ-Рѕ•чL™dIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/right-arrow.png0000644000175000017500000000066611733011756023076 0ustar sylvestresylvestre‰PNG  IHDR rыф|gAMAБ ќabKGDџџџ НЇ“ pHYs  ’љЅtIMEа4[иB3IDATxœ•’=nТ@FпJNe,QгRJ#‘"`D89-%т XB\Q% ьžы@€Pd‹-О™їЭhfд~П—8ŽљЯ‹‹ƒс€€(P‚Ј "€Bё#Fо;œЕ А.жlЗ[FЃI’<ЎфœGƒсx82ŸЯY­VLЇSКYі7d­Хh €q†гщФnЗc6{gЙ\2™Lh6›ЗCW5–В,ЯСЂ(иl6МѕћфУЕZRЕч-кœuW€R я=Z[žЂyчАdЌЙ‚Z­уё˜Fурl~нž эеыuђ<Їгщ3ЃяЁ+*K^{=ВЌK\‹Яfwг0_!˜І)išї€бKЛЖ&\€Њі/ J.:rЉєёyѕыЏшѓЉ}"ВЎрN[/šIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address6_64.png0000644000175000017500000000700111733011756022643 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< ЃIDATxкьZ{pTх?wwГkВ!B—QХ4€3ЌкŠƒHe_EЊTХ)иЊZЇЪЕŒІЪ(ш0*FDоŠ Ц•WyЄцђРМ6Mі•}мНžsїлpГЙwйdCйŽ~™3йнћяоѓ;Пя|ч|пхdY†s3РМ§ћЯЁ˜PRcд їПтуИnв#}‰§6e#Х‚ђ(JОЮћQЁCЙŠѕ7ЃLF™Šr}œ6:QŠQjPŠP>ˆ Вѕ$Ў… o ь72vJ 3ddЃіб-ХŸ*Ž7pxљѓ?w?j*ьX№E5Яѓk­VЋЬиAђдGзЌЖW$‹ЪCIВ"~ц… ˆ’A1A)!€П”џž€Х _;ИќnА˜,pг,И&=ђGO…GnžчEqЭР—ЌKщўЎ|\hбxJ:ѓ$b&”MШ wG?њ§~ЋЧуЩ@Ш[r˜Mсў"Ў/ с€@ˆ|Hаpoа ^о nП w‚J<јќ^јЎц Ше2|rВўВыХДwцОЗЄaY[І$IoЅ­H;дзAcП‡­”яAШƒЛ(† І@ @:"c‰L^цХѓ6Š‘Qy]є+тМає бpјлРh7яЦ~МЃЈмƒ№пЯУЛ`^СƒАф‹?>„Ќ{ЁВВ2;Д 1C$цMQёЂ$04$р @Ÿ ЄeПUК’ Ь`Aay=ШМај yн†ЙЁНюЧпIOт$…i4Жж<пXќ1єO0{ёФчјѕq”@_1@TyRљLT&(д•Х. `'# ‚ь!x&і:1М­xu\аюk…жŽhѓЕрw'јEŽ/Pdъцy-yяШлPх?џ№ЉSЇ~‡ї3іB„(ёD]2Єыƒ(AGF№ =ъSМмС{УО64иŽ†7ƒнлŠДЗушРq§ х1Ц*†_ЪјАМQєw6lиг=XТ5Ї€@˜DeAFњeb€AЕ xѕ4(С­ќHuвЇ@Gžў?9хї№lўѓšEAАді=|yf7|ŠT'ЖшЕ#?‚Щ–НnнКi ,и­ZЮ{Ф€Hx•'§4янHбvєœЭ]FD>,†P ƒС ѕї2ёа84ЏIЧюm†–›"N tФ"ЬіэлПIJJКЫl6OФЉ”–ћgЬžVњѕщEГ‡<МsпТC=4ЛЫ=#х№…ј1c~ХђИƒ яcЋ}vRаЊwз)о#Ѓ Ц‹ p9’НиШyL—„w`DoFЃ)Абд т2HlЂ?‚—M2Ї ёГE$7\aa!-oы+**­šЕfљ=ыІъQо\ SFNЭfЙ‹7^мŒDхЪШ€е8—}Š!Fƒ 555йёk3žєxZВмМЃПЄ$CD4šлFœ6бRV9”Щния5dз#YCЦgFCЕZ:'--m(Ы\!о)аˆR…rх,Okr{ <‚ ’Р]Н(žJВr `№ќгрСƒ=—sPЎ;гZ6схТч Т^Ў;Е2n‚“JЯВe;n4ЋЃhѓ/мŒнаgР лр†qГЊjЫjЛ^ЋА—)‘§,QюMmhъpпяЯ/оѓЫ?.ш­XЈlд`€ž^qѓ1EЂЕh†‡л3y/Рž={ŽрЧ:Ж_єF§{dc”аmтЩ0ŠПб–ѕXжZЖ —И ˆЗIПVмБољчкЏ)^ЊVЏџO{`ь|x"{1|ќў'л–,YВњЁ7оПЂ1 7mњuП†щ#gCу {ЩМчoоБcЧn–Бњz;ц‹2ђP&]ђо9и/д8p t§k W­Zѕ9KгmЌj•/+ЁРХРNƒкzЙƒ'wЂџбДa9ЬынzыЦн%ЩЩЩОœ—&SЄoGБГџо_n'ю]Ћњ єn а^"?sцLкоn‰r{QЕЭЦOџ,KьЫx ˆ2ЂІТ8&ѓ|ЫŒнуmWъd)Ц)}Ÿ GбK8ЈVo‚tѕЄŠ}шšžžКды“8( а ‚FѕgЎл5==5z}j є5 QАщЧшL’Žч†ЃДЂ4Я§vRL•VЏД+д%“эL5Б*QŽмƒ J7ц)`ˆa4h,ƒК 0tgЮЦЉGщсioя1,gВѕ~+‚ВЊН‡L–u '[†iшnAйЦ6KЅоAC С,ЂЇl›_:PŸ љ‡­:тZPTV˜sЮVMЮ&˜:pь-Ѓ&ЭMЮЂ(О‰}kO›Ё Hі—цœi8-ЎfHЗІЭ=yц„krя"]М~Мзy€оЖ“гпчЃkzzjаxzŽЇѕ+п-|[9-&z69mАЏ|МёхrИoт§ѓ^}рѓоМaзЌŒŒŒ]~wЋЌђќТFGУЪЗїН ‚:ynuЗР…3еАъЋзсомYѓў>wХМ––EW9Цœ ъbа€3D Ыз!’$­\§ЭЁ“&ƒпз‚ВњяСуw+ВY M №жœuЯaџ}8ЎW­ћж7+№~Š~(ÕКІ х]:д]є]hі6vъ‚ъьР+Д^E IWЏЊ_SщмEж|%дgфШ‘Š7Ÿ*€ ч#†ПsэЅPмt:Иvр’0ІHŠь­ќ .x+oпДiгннzША~Ъw†АЎ`@ж˜(i>џi>Љ„$/ШLVЙ‹ЎкюXP3Ш2юё„цEКЖwыоƒД#сэnۘ1эЦД‰кћxiЙАщШЎS#FŒ :Ю9ZП’,fp[Ёв]rr’ ;{6—|ѓГSЌиЫву9‡j !Хb…6_3дx+ДюК\ЄЎ'&а[5•••?Я5оЙИЖЖ6Уыѕv9}ЉВйl ., сїѓv`?Сšк2єцЖЖЖў‚ t9О&у—-[іŠ€ѓvlC в“‚o’Ь§ДŸЇдq вггЧуЧ4—ЂЫWС геаl)й)vLКž˜cРшбЃЉцІЂ…Юо"O_$V’vDъ >œЖЊ(К[4І5ОЬЬLСdL*ЗіГŒk№U[vgEъœёNМvœ={Жž нД4ыИF58И60ІJКчУК=‚ЁЈщгкxˆіBšЧАUEРм>jњђwЪўAЮY4‚гvжи‡Ё`љЖƒ t1ЌЛІьUрM0Ї*/4ФЂbј•|U–;аdэ'ЩЂsўЁл ЬљяNPхˆ}ŽлЏž ППVчхх-ФЏ‡БфІ]д=в’хKъв”Ѕ~‰№І(=ЉЫя <ѓњЭCоАл”ЈM’„“',sЏ–чРЮ;?gл`сЅLЅ›ЏЌ=аMt~Чxњ[‹Хђьўр–мoэ[ кwЦЅцСœ!‹Р~˜/лАaУЖѕызoЦЎ•ЈчU'T1ы†Pю­ах Iј!TпЩšд'N,ЋЋЋ+vЙ\ŽтттВЅK—вЮяtJ єЇC•ЎФЄлуbш6By^yх•зЭfѓ'И|f№LэєpaI…т=ёіяsVЬƒnХђ=ЕшНюл п'ФWт#qHk&Žџ9Љ§™ў?СѕћРљ›L„IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/folder_16.png0000644000175000017500000000100611733011756022377 0ustar sylvestresylvestre‰PNG  IHDRѓџa pHYs  šœИIDAT8Ѕ“ЛJQ†чь-’MBФ Q$…јЉ‚/ри‰be#Š`ЋрЛhуиЄ†X(‘РnжdЏуЬœнAШВ—33чџц?gw"Т2‡ъЌ?ІыaшŠrз ђѓъWOžkнƒф†&/OkЃЧл§љЬХƒ= еиЖ..? @)†вИд7+Э™^&ЈТwPМпœvтЯa[‹сџЫZюFЦD§ <ЬЧС–ю}ђ-ŒЎ*!Ъ wEрё _okB2мF–№Я) iіb\pсЙИіКЋP7~lFЦУн‚іхёЎ-'БtЦџƒйЈ8я‡(9ћјЪk‡…Я> УРў§xѕхw№еЎ5Н’hР H™§еs.ыVx>Ђ-GХgЌ“Vљ0nжeПp9Нh5<пАё9ќYг0yђ,Йs!~Оќa5=nР.@#WдеYТg œо’бт3‘0‘WRˆтIг‘SIпэёР”7 Ÿ}АdР(//uL*Њсѓeu+МјвЫяШЫ•“ onxYЛв8•]О$Хч%>On>LZ9uНП|vт.`WD_FŸрФMљS/†nњЋСЋ%D ‚ЎЇ­NСдKœ|Q'ŸнёѕЄ€ОЄєA+ [_Ъ.ФшEB,jЂvb:ŽьCЌ§dzŽЂш=њЖ? ОБœя(чћКЯ|\‘§YсAЅС~Y™gљЬљˆuХqъгzф%bш Ж!ЋЌЦ%™хГ KHОxœјZ‰ЏкбPFЯыъ’|љнёѕр–#Њ'ŠGЁъВ›PP7;/В Ы3О\VQЅƒЯWT‘QЩЗ€јІ_=ЏbPТ‰2Н@jŠibХK‹Ћ2ђлљМЅе()mЫсічš’ЗWОгЦ\/хбРgvЯл#_Я# ёсЗ€ўђєеŒjюК.гсу0Ey}x- Ї—шЕЁPФ4Ѓз$6ТЯJЬ/f§„Іо8їХx|H-`еЊUˆD"„ж„№ON:хы8}—}Ю~M}ђgЉ{9йчАБКѓН:оИqЃу[пњ;юZbЂxк"ь\О†чЬUDѓ‰6RХ‡§%3НЈћ…Uчф^Yunчщ ВГOгП‡мŠzЇ†bЈ†ГяПŠPЌЦгЬяЩЮIƒЯ=™•’Љ‹TRЪт$ы“yfЮцАЦ„–~‰кkc№фgS5е§Ћ§0Жь Š& л[yйCl7“+|>„PIRx\’šSчнЭЉyї\&ЪtЏЂцеK1vž)„7;"а7m‡Бљ3ёrЬчХ”‹*љzŸEєВ„М!T€‘$eъЮ9чЙсКЧЂtОL”GЃщ‰…Ј[\ 5Caяm…ёПƒвФЋŒ…;9и‚lRѓxy“g=)aврЄє93mЎЗѓў§^=мŽSOЭУ™їN$СЈRlя€ўж‡ŽѓРVLdK;"a'C>‚щ†(ЎhЬ&Z>Р,`•œN”gішЏНїg$кŽЁcнRLМwd0л‚апо ГЙE'V˜GЎа‰р‘ОeШМ<щˆЪЧ№Vп=Nƒжj˜Nјъ†Г}>яЛтЧv!ўсЏQwї љœ?єѕ›`;њyIј\:Ž Р…f ьXP@ˆRs(,€_Х…ƒЦ>њUk]sКЪѕŠTžWŸіcwJUi•[™šSп=)ЛПН=5Зœ/я;б §MJяфчШіх“Р0ќ‡;а’ТjˆFbТx•h.e‚-ƒT€™7v уамsnlЁмKKv4[шм?~sп”\tІОё™§@ЅцМА<ЪўZ;авсТkЖwСаХѓёі&ѓњv ЊjŒc“јEЏІэ4щонР‰yЌ“ШжQZЕ “ЧˆћŒ†Cа7~$tсяШЮAАхQXŠUZЊЁэTT=bб5$ќё!ƒТђph аžЛ,ц#\ПUгSў‹ш›?хЬ`%ТяMM‡Шє“Т—•ihmN ЯЭ§Ч$|hjЃ› ићЙйC'W*#§zшЭП`ььvd•” §у0>ўRГ ЙEЦ…?y Œ`д#vЦЪЪXJјƒZU…—’№ЦєнЈ,эѕŽфь(ВЇ{ƒыV`мœ /›^П ЦЖI€#[пf[ЧїSФяд„RЄ№]ткnm ^ёЮEwТЪ2[@_S]ї+Ўц:жwކцѕSO№@n–Аšr*J(ј’№ЧHјHŒђ>aвkх?ѓLЧћžYУбГ”ЙbХ QЙKзL)Э]1ЊьaOƒќиK&МlT#n\=ŸЊ9ЦwFX_ѓXй+e‡кJ˜‘(ŒжŽь‹ з ‘Ž ѓЉ >%WОjсУxџхІсi‹[šŽДЧ…RчJpїЙ"Ў4Ў€h4*ˆї:::РЂќъЌу˜џмmщ"ыо•ТS гЮ-„з[B8МW яё˜” ј[e•Zsч“5яСсы ZiаФЪ•+{ШжœІ1[хшь'(Г7кŽBЋу—Э–s!Тѕ/m DІrж­šV>BќTGїGЩМY Yђ|BюунќW”џhщ№6E­э'ћі\КЏЫjMFљDBV{іh@ЦЩнШпџj–}? mл‘xe#%џ(XAŽЌшкƒˆ5‡pє@q’7ЫGХŽG8Є‹Н†млŸ…gвЌўŠ3ДAа:4RТr0ЃЪXe=ŽњЁq;Ъ;з bСљђќx3ЏзК‹SŽЯUJ‘>€Ў&ђљb-;‡”Jш/#[ŒœХЋ)6œƒєPa,ЕђіЕЬпmђІфˆљ†zT—n@ё%гфuŠђњЛmi‰Ye XY!Ьжvtž тиЁ.!|N.C4,Ё-+­!сŸƒV1nфім;АюцHЪЇtSwXвЏЂЖv;ŠО['…пЕњћлјcе`EyТТЧƒ8охl.•Гс€LsZѕ4ј=K0ИЂлt;"1Рžц2љЙГй™<Џc&6’№S$Рйњ%ŒOvŠjуЧH\OТ‡ŽpтˆLГљ ЁіЄ№.‚яжЇР|Й6+ќАlй2‘Оx*SiMU‚ЮxauƒЧжTс…Ѕ9(›uЁxkОъЦЎ§Ђюб&!r=Џяэјњxм)„oнзŽSMIсiх•№lцbЬОr9fлJdz,}З–ќ.62 рІnя ђчіжч˜€Ё‡[H5­њХ0šжƒљ§$|Dј|ѓ?кZЂЧW@юLš=ЛтЇ№ЬМ#gЌя“Ў(у‘9В АЏЎНm•Љдеe7†Pпё&Ѕ‘­†Тњtш{ї‚"пн†vП.|97ЧD( Ё-›ћиyѓ’–Хl1)Œ1˜_Œ  лfКР20Y/чѕI?€$2+gЕЇ Z‹p‡D‹^‚Жс`RЩ7ўlъ•т<іђчYщ6KФH*@wєэTVpЇ<щїVLрќѓoК•Jж\l|§I dJ`гЎ&@3FЮG0?X‹Xмф?8‚yгу”g$WX юД\іЛ!АгQ ИŸ§…ИЫr=э?peЅХиље^дŽ­DeE‘P‚V3уo(Фhњn*}>AјЊИ‡пkšЬе/d)џЗ0IїnpЮк№аїј Я;ЧсƒЪ*ьiЇ)>ЗnнKтМЭРЬ+–т‘?ќ K_'~УW8ЏЌ кœћЛр6hЅЕт{TіPўЎV_Ц@цRќˆY€еTСЯнТЖ+УеЈЋЋC—^‰†ƒy63fRАтš4aE|SД0ЌеgЖ80BiавК‰з^{=уuž›эmn™ЋMlкє_ёвjЮj‹)!ЕДћ-!Ѕ™ЋДgзС§fp`EџtСYв? 2l (S4Hф§,Йћc&у„‘lž6СŒд}JpL›А‘Ћz;R0{№cЖЌРlІn5|ueРЫД9ЂЌ‚9,D5\в7TFP=яГдЪYyлйLсŠQ."Mмt™ЕЕТжЊ#yЎЎk#щzПШ|n­ОaА”ЋHehТЬeР4’A.=JРЅ%c€щШ–{|ƒ.рОfЯvhьœc)o kкЌCГYцp А‘=—V Дѓ)9дœЪуVqЃЎIСT,QСбђ}–^оkG›ь›Е'€Ћ%Ў‚”=b[A“›ЖђgЫєЕ Й6…HWАZьњШ(€#ЛLЁ3кУќXFџД ыSK=CG–T’U,еPVХяхе&'ЩлПбя№™ŸŸз-:ДЬмL[[bю>Ё‘ТV1ѓvŸчПџ5M=ЙqЊЇ6PљbФу1A™оmШа‘Э‰Щ“'ЃММ\єтКџы КљO%PfЁMЧ‚]qЮп :Ы[dEEEЈЌЌtu­яŽЮљСбc'Ф_вЪЫЫЮуу­;ьЇбСXРNu№воРŽЯv!žЖ‚ЗЖњёЩЖ/№і›ѕіщ Ц"zЧО†=Рщ[6xjјл€-рљ5oJ*сл8xSq)Щ№yOLЌŸПђФп#Њ:Э?BД ђяѓ;{cўППzѓš/ђЅпIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address_25.png0000644000175000017500000000145711733011756022563 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<бIDATxкмTMLA~3ћз ˆ†ЊЋB‚A с 1ѕBєBbћн Š05—јёnјзъІЖѕ:2zuў1ǘчОŠ6х\}[ЪыУ-зr(e_б+л(%@)@†ЧГжС›ЖСIG iWЏOt…†.wьEB‹ €( –ШбјДфшЧчЛ7ЁnЫ 67.Ш)5ЏкІПЈo;є,Й№F“ŠОє9zкЭ–ЉЅ35yХF1*}ш`:Vє@ ўлєUѓzмЕшМА†ь,p ” l…У`NK xv;п_„Юѓп@7l’‘ŽMЛoт) Л6wќfгИ%ЌёЃeH›2œZ FœŠЂиЫ­:M uj*к*Њ!гšЩL’Ѓцћa2~}Ю+ƒ|чіBeˆ@“‘л'њА;Гёx,аЮ@нЎ О OЬќхCш eгse­ЊЌЯ/“Bžc§@(ŠІёO•Љyhйѕ23ŠС”š~ЪЄY*'1збгp–э@чйНјZœЋmВ–(41q~s$.Ж‡dЛЃ08И4,Б`ЯN@ЋLЭy7yсчРf˜‡gЁТ-рќu˜J‡kЭ!p*moъ7›`9 ъŒTUдƒ—(ДJz%ƒYЇ\pЁ Oе ‡ѕ Бєсd гє/ёГ,“Ÿ›ыhюѕNШу.шЭFмєFpМВ•РДHˆ эЎ€œїшhxф%™Q+Gœ‚є…“PЋd‚ЩхЗœ­ы™Рd} 6эа oFЭfюђЗ‘Оь4оюAQA&ƒ’АыћŒ™E t^­uк ˆShŽшpN€ŒržCЭB]Є"йЫ8уoйЖSз#)'ы’цНšЊЋ€ТЬC•цФЃIі^ NœЛБЃ‡`тcљˆДКбu­ƒ7l‡kяFќœБ ŸœˆР”#нХ”\5\~ЂMЂŽИKвqЛe”ХcВUљlŽ*=oŒnшI pи 1‚Ъ™ь'ђrRэРћг˜ŠŸGьv+Њ:X];н€^F–M^Ц‘т?­VmAєшTмšђеђkШ™`ЭЩъp§•"mўDsђЂ7Њ­CѓŽїЉДPЪ„ПЊЁ[!иg­Aыїу3Ы&дд”1ИЈ@~БЌ˜чoДСр‹єь%p$Сw……B—g™єžH­žfуЪ EГ^ІЫЌ2НЕЗoЎќHЊMрЁ7ЁыђAt8ЇрЕ[3pЭMODЯТsЎ oiѕ>JЅъцm ;*BЩ)}Wљ~NM› ь@ ђЧ2"xEђМѕ㘚ˆЖ7J5_g7ТSf ŸЎtQБ1ш=Aш§A8F­˜ŠаЄ4ћУ M<’ўѓžиušVXy њиZуИХѓ-“žEѓСmbьБ2&Ѕd\uвЅ‹мjєѕ)ЪЊ†ЅXМАс6Т‘X"ZœmьЯЏRj~>ѓ№Cщ% ˜Лф-tё ]Ѕ/]є[Nžл "b”ЊяЊ~­‡їOЏPše•5LЬBыk|wkРž–пhFS&­Кˆн)g%(+ПŒAш‰ямПVНтž/cџŠa§њCс-ћЏ&.еx Ј)>=Е5%IЕЙhЇњф[п&E&‡;ФНQЮRўiМїЩBпž'З 9гђљ3O“RЌРС*`ы1†QNФ'eƒ?STЗRк„DEЊA6їрjбѕР ї‰6Цqп БЃ8Ц мO -~4йЕXGэeЩїqкy=ЯŽзЖ-ўW$вxqK%В‹ZeUЃTЏТЗ;KХ5вкЊЬNЪъњrЅэў/(m8Щ+ ЩIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address6-neg_25.png0000644000175000017500000000207111733011756023411 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<лIDATxкЌTmh[U~Ю§HoжdБ-Ќиn:й”впj6?ай"ъŸЕјЋMЁСm Ђ?ЊХЏA№GQлJePZГ4t]7Б2q`Efе6ЖлŠ‰Щвв$НЭ^Я9їІkXг\u/œœ{Я›ћ<яyžїFD0šѕУяw~№xМњЩ+яfߘ“MlџЩЎў!иС6€яџсЏшєxpз3+—˜)B“пъžІЙѕŸŸf vyfјв$cк}W{MЕЦж1›šСЌя'T6™Gу_юо§BњЪ„ВYЉ Фи­в^‚Ј”­)йыѓЩ?ІчЯч/Џ\\&4Ј1}ќњxѕыŽHАЂZЃ ‰ˆМbbi-†™ЦFŸ=№]р7эъч7ЋRгюou7—їНщЃхHДBеyf"›Ямк ГWCИ‘O 1ыMђзœXЫ…)х~^C5шЌЂ3Ћ0'$јєхS`šxіbяЧšdN#Сe!™p\•ђЉ\ОЪНОcš‘тџ'фг•ѓŽITCxРЙ€XˆYxтkМHNЛŽ0…роgюЛЇ-хыŠJШ,›!grq`ЕТЊRHЇБцЖHЊ—Йж’А9 ЇЊЮ<ќfrШёN„‘В“ЁлJЊуФ„є/XЩ]гџdВC€Ьw$ѓїjИёdrђ_yRF>WиI{-uб7t№хд Uь@eМеs–Š5œ‘иеKOl™,KЙцbвhсƒА‘Пwww*хђkkkзФ~%ВББёќРРРE€!ДWq &JМнІјoьЁ)фШгJДв’NїIБX”БББ ј›Ÿšš:™€ ђ бKШ…qd"4 ##GЂ(ЃŽlђsЄ{S~Jž—|aфuјКРcz||ќ…СССЯР"K™Т5ЗвD‰k†EdАШгБ#€ч*@Љ”ЄрЋ\*=ЕНН§ ЗАј4Ћˆњ› @@нaр&ж<їA2”(–вАŒeUцОP(H>—;лj6')зЋDИdЧ ц:СФ‰gЩФб‹uЬ{e™h'U=q‚ЬЮћpt†”щиD!N——Рх…ЮШЩ,0тŠ€r‘ €шƒчѓyA3Ÿѓ!гI.АD=Б ЦGhAш;tE юПgбz*O%yё,5sŸЩdѕœ|dx†L”aт%вx €}™~A‡ї2dMP6цTћО‘,Ѕ}0ач)јhž КМFDžsШˆшзРu|Лн1нЮ({Ѓ‡ІwT,`>QЁ]ЬЗRЉtрWЋе;y”KЮ@pВri ƒУрФЧз‘aЬмh7Ђ W^ ъIѓшˆяњprЃ^ЏŸ-;eCч-9j6MDЪiMг І’р’(чœв(t<ˆЦѓ 2оTљ‰ѓ†ƒMЧћZЕjdJ†Ks`ДчњЇДЭ‡fЪ=G ћёљРСдќГ\.Ÿс”†”ЋWA|э˜o$Ѓ|кu{Ь‚Fу/Ќ]SKKKwAыЪЦt,чЂчшади$W™|Qs_л„ЧžeW—vђa KЇнўfqqqGйF‹ОЦт‡ѕ†“G'Sз‚›Q>х0IЕ ktЦьjxˆЁЊ~Х™ЫЩц#ЙљЂ\)пaвoчФфCЧrАЃ}гˆІšДK8ЭЩХd?ИџTж—ѓѓѓ;<ЇЇЇпС(ј|dttЂ02’hoЭЗ}‘в–QD”@,ьээ}:77wљиgќьььhЬљ|!?Y,>!УйŒa`Ѕ‚Г”oЋШЗ`ТЄ59@^ƒK333Wћk…O4~OЗw3йьй].—•ССaIїЇM7sZЗ›ЖŸЕк-Ш§-Ž~ЗџзOЂј…Ят2 РѓШЭ+hї#Аь>п„ЄПСО_XXИuœŸЁ˜†UЌŠКIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/ruleset_16.png0000644000175000017500000000046211733011756022614 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<дIDATxкbќџџ?%€™“[@”i O`„s@.сј˜ќџФЈZА>&tгпф3ƒёМѓџ˜˜˜00^/ „o?§ЫРЫСРРХЮ@и€yС?8йИV^§УРЧcd Т€ЄЕk6ХџfзЦtрПџˆє’u0/pу…ЙA?~edрВA^рх@$Џƒz!R/  oџчX, {ƒ‘ИЄŒ XМpћЫ_ТˆL„(Ja4џb,фмHNfbЄ4;&k~фCaВIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/error.png0000644000175000017500000000371411733011756021757 0ustar sylvestresylvestre‰PNG  IHDR00Wљ‡gAMAБ ќabKGDџџџ НЇ“ pHYs  вн~ќtIMEа ЮAIIDATxœэ˜Я‹dWЧ?чмћъїЋющЩd˜0 ™D% Lмб•ш" YЙЩТ•ќФ?@0 —й1+qЇ‚ EC Qаdтh2™aœLЯtWwНUяЧ=.оЋWн“инѓ#ˆиЊЋоЛїћ=ч{ю=чРЉкЉкЉкџАЩЃ\ьkgіе8тйAK‘#іŠ%3иЎjо+ЮKо˜/јѕот‘ь§а‹<бsів…1/n ˆn–5ГЙAiPЗЯ™N”FЊd~9KљЩvВ{ЛЌЗў+Оw1ЖяŸrmИYГ:P"дЕ5АW&;GЄ €ЊЂ' Фёкі>Џоо{ ,євgFо^љд”ЯzхE`'XчmC@ , М ^ЄйЪDЈMpкlЏЊDWѓŠнмсЦВМ/LїMрЙž§ьгьЦЕЂfnP[Г’!`Р,#uєUZ№‚IЛeKІBpвvЂЬЋРnмснlyb\z?рŸDіѓK›м\ў^TЬ‚Q˜ЌЉAO)“ф€Dšg"ЇФЮБ0cЏЊЉŒюЗ2MА67hЂ*Œдqy:<лБžzћЦИЧ­Ъ(Z-WРЌ X‰ЁW†yF‘$ј8юˆљ6Эq)lxO%ТnUГЌCIEBл#7rТтЩУxўЬы•‘икѓŠрu‘jє€ОFJЋH‚ЈВщCЇЄђ–E:Чњ[1ЂЉ2ŽOGЪШGрЙIлЅQЯ|gЬцЅцCж№7Lмњs)рAЂтЖUJ]ЅXхРƒ•BQй"08œ[ЏЙѓ—Œїб\xч8пыq5]з‹Ш Ь`ѓ’o/Ћ#Р[оФQ—)e‘аф§Fо"ЏФcЌоEхЬ3cPзШH„ЭшhKрŒWfо‚)тЇј№юџеw•P)й<#тЮЭŸCT;№СУuВ&‘;пБŠДIZ€od2‡hЃЙ†ЋфЃ‘ ‰„Џ
wQ[ѓмНRв;Ќ“@||шЄ1„$ЋЛЄw*є{ŽЊ†ЊдхCаhмyџъDЈLШъš›‹Ѓ +Ё?$KОљXAјлЋNђфЁЉ§G~З;ѓ‹dо%bnM†ЮuЅD_•Ъ ЇŠЪ6&MbЪДqDmPbм-*ў‘fG&СБје,ыК)=T}6r8%ьUl>Ї6ƒЯ д‘›БSU kk$СЋB{Л—iJ4™tbV>Шџѓљbя-+ysОDл…k“Х\tт^[ЩЬчиhr ;Ж|DŒ[EйD%"Š6ЙЭъЊ-в7žPšqЛ(јгlў№^Л;Їяš ƒгІ~сžHŒМЇc ŠЈ"у …­žГ>тlЏЧаiлр4еЊt OГ^ ф§!W’Œыљё“‹xs?—пЬRЂжЫ5‡СЏN)DШKzNёвШЫ њосWщъ Uз•х˜ээѓіэm^ПГћдIАИЁљсЙUднf5‡e„ƒЖШЭ(“”оtŠ—&"№ђаЛC2Qj3ђкИž/јніГЂќч#%№ђЛdaUV№Б‘ЊvЩ FcvŠъP3MБ–‡F§XИОX№ЦWцщ‰›њћžJ<=ьйЗ/>ЮVфˆd H;/гЭыРh:eЇЌ,rоz&афШМ МŸхќўЮ.œэВc€sНш­Юo^ўќdDПэgWРєžP^НЩ„wI вм5PcЗЊИ2Яx}ћ.dї?n| +ћвVl_?ЛСФ{zN‰dE†Cї4нY™&д&,-0++n- ўК—№лэЦёPVіХ‰]оsaаgф^Е#ЎXэœt{UХПя&)oю<и8ё =+;зяНuО]>ElDŽ‘kN›Ќь—лEЩ‡ЫтЇw–Х rпS;ЕS;ЕSћџЕ† œQNЪБbIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/host-neg_16.png0000644000175000017500000000111511733011756022651 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<яIDATxкœSKnл0Rѕ›IŽвmрEаК)мРH7^{SРлЌКэ2ЙDЯб#XЉЫNdQ"йGб ЗM ”<ѓц=™Е{ы€pBШ bїЎ%la=ќГ˜ЯчVJ‰ ч9в4cl_ЎPлЖ(ЫЋе Zk/Р9Чd2СџЌйlб7№ёцЄ`шkЛїЦЊ5xЌ –›їыeЅaШMёѕ]чJ4Mгв$DфШОћ ‰Мm }.•СJЕхˆj5цЧ ГыEF!BpЅ[W™HkнЯ-UЏ9*#g!ŽвoHЄ ЎCйmТHB Жи*‹ВеX*†в0ДB Ž2ŽгLњFЙЕR~šБ$Kd›~Jj~Љ9™…€QМMˆœѓюјPз тОXtHTdљ<HXАиbDЎ†гЬ‘J†ЖНРЖК§л1}Ћ1"ыЧ)p{2щf‹/cЫЫ+Ÿ47ѕaxњ§їOђеlžžМ@tУЇ[ччяЧњЄ2Цwљ0h…ЊЊžГўй­ёјЌл;LЇгd˜lЇуFЧїm/WQX,„ззŸ+7ЗмбЙцЙžСХХэСнКЛЛ}qг^=bџКPПb-щj4х‰IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tag-neg_25.png0000644000175000017500000000345611733011756024117 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<аIDATxк”V PTчўюо{їХ.Ыю ,ЫKDEт‚СдWPCSL#™дhгcSGбJ2ЅщLД4#БiЧ“4Lщ4uZЋILІЂ&ОŠ†V –ЧTЋ!XТSЫТВЫ>иНїяЙ‹Бi›F{fЮмџПїџЯwочrWжpјЄ'žIќq qё$ё8ёЯ‰пџќ ѓАŒЏ"сЫ]]ЋJгЭ(ќ­J­_!šmЂhЖCДЄ и=шk;7Тdщ&…Ÿ–оJ949„Лъ?_€J›š[e˜НєцЂ2бВќihЙЌЉpŸћ}Ѕ.УiPщŒisW‹ёŽo™ŒЛ‚-0Ю+ўЎ49]к}шЉн€СУ?ЄАіcгТе&Žч‹ yЫUœ ^NчMџYСыsVGќ^­uх6 Ÿxц, Œ‰†эAьќGг}з.Ј,EOх%<ђЌ учнŽлНƒpЂvƒ1яЁ•ъјT„н˜Иt †t;тfeС’Ёџв›˜ъBhАоЖГаeЭOЁk‹я„ЌА› K_šrїsцeфЂЗЋДd>Шџр4zшR’a[\ˆX‹Њб‹Є@= s–*ИтžA4Щ3ЗklYvу}Хpџхt1™PiѕрД1Q ŽжКT\m7[P‚РgWУtѕђн@„лV,L(}ncxlІEk0pр9ЄЏ)JЃУt%1e пЭј&JыбЗЖџсјзЕ[^‡ЯDУИ_Њ(™Хпв‹РoZ‘LPqг Ђ!wй‹’пc]љ †П ызцAˆГ*r‰ўUCr0ˆ‘ж6dU§CЇ>œўвљжPN­†‡N/Вoѕ#ЬхчwMN!жaBЫ\ТОаДЛОCѕА:> ‘ёAxZоХdкдОл/аќ‰змQ—}дkЩ6„Ч‡pжŸ'~h]WЇƒЮ ŒfƒfuSš?јT:iTГMy6 #ndэдp—ЪєРуdO‘ їJІY€й$ff<щЯ PЋ…Ф(ˆеjХЊUЋАoп>фччЃЖЖeeew@›оње ѓЪgŠ–ŠKЅOLК›ДзвгjЄї3Ј.H“p†e3IЎ‰Ж•Э›7#HеЌV@ьv;NŸ>ђђђ(ШћOќ={‡|' * €4.ЪЅ)@э"эуcТєэН+zЦ0ьђJ›ВЌќg9 шИ“ььl444 33ЃЃЃ(--ESSSЄђ;шДc§ M4В"ЮРC…Ї&Йл-VC@^*Шђ7ТB‘§GЈлјo]иbБ КК: 000u_UUUдЂhLТxўљнGлф–‡ щЈoЉЩk(UћFзЂщл5ЂX&bа/мџB—єХфauuuLЁ3gЮА 0 ztўќyХJvƒ‚Ё№Ь=сœmЇиP}ЗЬ.ћdЖГQf†jЦ–џŽ…_ќ€Бт}Œ%ќLfqЛ"›ѓГ~/—Ы…њњzlйВ}}}ЈЈЈ ?‹џ=ќ*ЗgЗvpKТаНBЎPЁЇw?zч‘Мbƒ†Л>;пQГžѕп™ИїR'ЄЭŸГяр’)иїпђЂаЊУ&ЃGіob•ЪЗ­ћЙJeЯхlъ‹їџ)РгeКИмяМIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/generic.png0000644000175000017500000000155011733011756022236 0ustar sylvestresylvestre‰PNG  IHDR$0yGиbKGDџџџ НЇ“ pHYs  вн~ќtIMEв +3.АЩѕIDATxœН˜лnф †й‰Д]U}џЗл^uЗнЎ4бtrї‚2!`9LЉ5№Х6Ж‰РIЉhЯ|NbыD3ŽзУ`”j їРмCЋЪ-#НПrЉ{С1E‘eŽZ†q‹[Oњ0сџ. U”ЗŒ€DСЄЦ;јh­Ѓ`€и2ьh! Е%ЖХ"PIЬМН§ЫB„RJAЪŠ]> TРУ0$я].—ХЙœEY 5IOЉ*yЏišьќ,ак LЉ` eќОKу tЌ…QЊС8v№{,м”fЅc{mВ%2йЗuНЦkЩ=0ЦŒXо%О^_џFзDIЁœ/пгš Ѕ\• я;дѕ”›•jlІ^JzяяџёєєФ.bŒ  дЖ.ІЎ ,#BJE< Џ-Съфм—zЦbPsZЦЁыКЬј8Z65hœ|x­5žŸGзc˜hСe€MS~eЮ-нЊ~8nВ"п~м‚:­№-ђ ™`–›3 аeзk"4ZїiЋ3В.kš&‚YЛћl—nЬ2@$ЕшіTА H/ИХR9­кіncnП%sжh1†ТLўVUК9sZkAШoРЫнw”2.‹ЫAЉ ЖІ…,Pјр‹i­Ѓц+UЛVЭхƒnqYKTUХ6јЦ†A/ЎQpr%ё­Tz:wœЎЊъЋёOяЮ 8зmUЮх…,дЧG!NЇгэс.а‰lы~Дж Ђ›5ГЧ хіЃTЎMёЎ$,бї=ъšЯ_эG‰тV7e"JТЬŸЖQZѓX:Nоіs‰Yщ№kмв@ ыŒЃa—пФY&Мц`{_Ђiдu hлљ’bhZŒїССŸѓ№№О+wXшИмфkPлЖxyљƒЎыаЖэзƒѓљ<щхЊ№zЈƒђ'џ] \Ьi­q>Ÿёјј €ЭCwšKˆyўс‹%Ц2Эн“nEО Јф~њN}аbПшW•IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/newfile_25.png0000644000175000017500000000117411733011756022563 0ustar sylvestresylvestre‰PNG  IHDRѓ7uQgAMAЏШ7ŠщtEXtSoftwareAdobe ImageReadyqЩe<`PLTEatГu‚ВgлфђЇМзтщѕХгъ_ŠЦКЮл“ЊЩЬиэалюŸАеВФуНЭшЙЪцєіћШеьъяїдо№ŠІжЎРс_lžРЯщИЬЖЧхвочЇКо Ш‚‘П–Љбˆљžѕ tRNSџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ\\эvIDATxкb——gGy  7— 8Ÿ$ЏЈДДB €аexс2–Щ№exЄ8$`2“aуу—•–cecс„ЪD†[Mœ_’WZFHŠ&@P.6qв2Ќ@) А"2ЈIZ†QLŒQ–,@`fЈ&iN  #D € 2`M|М<ВŒŒ0=‘iJIŠђШЩШpBd,У “љIZZ,@pˆа2~~А @AdрR 9>ˆ @e„`R 96qˆ @AdРRP9AA <@1033“А0X@^ €2ЌЌ@Y Œ0DD €€2ђь@!Vˆ> bŠD€PІЊ €Pe@њX!2L6MDD„‰ Ž!І1X†HCT €@2`6ь\Јi—‘‡ШШУdф dŒ%ўЧ••IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/dynamic-group-ref_25.png0000644000175000017500000001152211733011756024460 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бхЈIDATxк”–ilTUЧџo™737fКPшbiЕ-L‹ДЪ&†,крM?hЌ!њˆє›11§р'՘(4>(‰KАЄ(l$­P"K‹жN•в….t›Ю0ы{яzо›ЖtZy““ћцоwЯяœsЯ9яqlƒїИь$kH%Љ ‘Ьдq|МКџрpн№XТ}ё”o“-Б;)рю1“МBђ:I)2у<2O}КхНоЗ—_‹-s'4“bцc7N=Rх/*КюВ™d/2й x ФКфъ+MW‡ьОЕЅ+Рхl r‰8У†юяёы§8‰`?эћŽ`‘{AіМ•МЗ$TрД nїјu№Й'6ЎлЌС*ёƒІ20ZGЎїОNєірcMУG›Q(ЮьFОщCф ,(ЄэŽ^i“žYЕquЃфеdHC4ЊASшI*gpXѕъ„Ch–ощmБYъ œЉ6BTd,ŒJrvBУбёšˆГ:jџwJC(œ(К'$ oxВЧBДХ2‡ЌЪЦ/иv&бC Я ч)+’ФqрqЇDhк!ŠЩQсp-КЬ6Ъ4єO1ŒQДƒњ1ЉIЙIїSt6УA  HЋЃzT эoNg#xУZž >w)ђфT€>šˆ+NRф8Ј<&pњѓœ˜*њњx˜!$)0љІђIs-y“Цу1—KZVцL+RA[нЧДёƒж0KЉР/€ЬˆE!/BССKЪе=)GбВ•XтV,І‚rЬЈДŸЯ]m?п>єЎЬИЙмФлLyЎŸ‡йВEф™… [2Я ‰еЎмтјЉЌFr‰‰>1Uс@z8oB?ŒЕЂ*šЫ„ЬŒdFI”Yj|aiл`ކ*Ю(ы;VьПЄHUЂWЄRД›TlДW№а9dХСЅЉГл—q_$B‰ЩШb‹ƒЌ&QТЗo2>йc#eбm/l=wd‘ъi~QuЗ3Ы€Sдмўєџy“ъxЪ.˜r’††ŽЛШrЪ!!NцXѓ€4ђ(NѕУІnrŠxибЖфц“Žѕж,ѓy‰B^Ф kb!7Tџ:!аКrс#АTЬ›рєuќЯ‹mЯТОРїЛKЃЯЫЫyЃЅh”кЦHЩkвУ=АЖŠ2кiF0ЦRфаЁCƒ)sЦх$>ГФ*х<ЪŠ0GТ ,9’&б$ ;7Žђ—<Ю1]3эъцogq„кi]]н‚љ~^ћчя-WJOBцƒв(qйСW.Сœџ=Єшž\\щээХиикккP[[›ВЖSŽd8 y№"f!3 ‰МpЅЙaЯ€ЧЫСœq’iX?˜ГГ ВЃЃЛvэBggчЌвжжVTVVЂООојџћеeїђд}чН”шg)ћйШДg!’ˆ"Ю&Ё9Яuƒ9Щp555ЁІІ&0sщgгооnмЛЄˆь–'гЃ…Š8лž<ч%ўјЋp{@ЕЗ‘4‚NЇЊЊ }}}†"I’PPP`‹‹‹бииY–Љq(;*^hz6Qwжя&СkЮF‰k гТе‘Ћјц№§9oXNџђ)5eЭзрр а•544ЁлЗoNžAўв)xЫŸБёітQUnЄ,QWi‚БmеyжМ^иср[!x;Dи 0{u2RђэЧ‡J0н†–Щ*HrЭEИ+!=Ї)Š“І†>‹эЄhm0CWн;ЪНRЁu`++1v„PЩ ЏІіЈмFme ‘‚д .м…ъЎRЭћ„ЦУUш№ыCћMЮЯN ђКƒ{жШ‚ќ]хл“qктТEI{з†Ъ%ЛжїЌБŽ"p$|‡рmбŸ+іЙž' 2fЮФqэ —)0рЗ%ў'H+AZy Зя”0nNсqхVU№BЈlД>ўў1a%§Ѓ‹MgЏО,Сq]\-!Pђ}Б•~рž—81maўє-и­яx^yЛкBPдзB— Kb›(›Св›—};џ• Krьdќ`˜юgdВ4%IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/pipe_64.png0000644000175000017500000000216211733011756022070 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкфV[hUўЮ\’Н_’lК›Ў t›R/ !>XыЄE‹њ$ ЂЈјдDСk|)}SЁј,TЁи ЖM%­„цjL›l’nЖIvЗЛ;{›ййџ3Л‘m,­к ‚3|3Г{цџОѓџчћЯ.Г, џі!мF,kс–‡є‰Yл ‚еТэ‰М§ю;ћ=nїЗЫЕЯсt8:‹Ќ ЕZэЛз_}эФ o ŸъээХ]бэ‚eyІi{~Л4џ2 wм,щ/”ЧмНkЖ‘HO(ПпZMУb"‡•+Щ;З&н]]‘wуккRЉffgАДœрУц-Ых<иqУAѕˆЮhŒїŸ‹жІa@е4‚Š*AзыЖH;Хн<“­/абGXЖ§Ю ЪD#ђbЉЕRХˆ|#ОEqŸЖХX7ь>kŽжw›ƒЮ`(3<:ђ0 Ъ‚м„rЙŒjЅ‚ЯrŸРх•Тp›­…-ofв"чЯ-ЇlО,ЧŒїЛx Ю. /КЁcCY‡Ђс &бШЂЬkцo›ёѕушіtуоиіэ| ћwУ!9‘(,PБM‚@W5SCЂx ?­ЦфЦJJd'~|сЌэBŽЁЁ!/#;Pх[UUm‹њtШВMєбЉёмрГpuИБRXBБЎи"Э+?(5 8Ÿ>‡_ђћHМЗ‚t:‹S“(‹q^ІчEQD.ŸGWwЗэ .РёPl/4Ѓ†Ќ’СXrд&ЌгйМъtз›wV‡!4ѕю€щ*RYjКŸзK№=-еыѕGxЉЋ)D"И\.І Y’pfў Рщх“˜ЯЯС`,В pRЌa6EУ+T d2фiв€Ж Р^‰іdГYътuЌІVQ!kJ$РMјхичшщ}?,}o“A$гˆм&&‰б2ЪС“Јў&=гНЊ‹˜ 2qЛЧvЦрѓљ,‰HдZвCЁѕ`^ŠmCв" ELew]wэsї›ifl–Љœя;s.?Юœ9B ­Н„(ЯњяіџGеgѓbSйJЁдX 6elхŸ™OЬ††ЇјMџ”Ш/эОЎ >3П4'ыN+Q‰/нqР ТЙЄJGŽcЯцqvщ&'T іTятСЇУTйE›rёЉcчˆ№—­:Ож€<§#КР›ъ†I>vn FЃЮс 1VУP_їEЧ4Р Д)[Гvт"учqnyжз” сЮAД_HƒL7ЦЖдA,F5@,џdLž™й XВь сњ~dЪŒЖ–V§е}aDJаосяЄw/:„ЗС+ˆ„Gdœщ Э‰А9И+Yщ`!ЇsoЊrб˜iaіл 0xЖ#4иІЕ 8xн1FTo#œRЎg`‡ZEFу5$š*‘яhЊLЦоВэ}С[˜‰Х(Сxяg;4Ъ{КPu5нРПДЈХ+Вj,­Ц~в3ЇїaїЩaK$ћ є.Щ… FЬY ЅљoяЇ–зd№<“яЬє TВ)Z уЖ%NUІ˜r+6їОьЖt7™85ЦпŠ•мЛџ˜q›ZЩ_iWРЗVЗНRWs&ѕачГТ‘SУUKюPwБЛ“48I™,ж/гsЉoZКжЙфЯФџ*jˆцYдњ+Вжd}/пX1эЮљ-Рм$bеу_П(IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface_25.png0000644000175000017500000000224511733011756023072 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<GIDATxкДVKlE}=;о_ж^oloќСDЫD‚Їœ‚"Ÿ|тт'ФЁмA‚"Ž  љŒqˆƒA‘!P9!АБЩўСопЬюЮЗ{Јъй]МБrЪІW5Г==SЏЋъUU‹(Šа›qеЄKъ€Є[ Ў‰о ЃЅМŸ$зuЃ‡ ’,IždфЃѓKзпyя‡ыќпшБ%Щ–пїaY6?/<  ЛЬq\XЖХЯћuLђЏхЂЇ&N>B.СБС‚–бС! SaШK RЬ1;3‹ЩСI(њ…Q€@љ№dЎtс)К+~DЂ\pŠв№%B(!‘KЅ1œIa(“ЄЛ‰Н 2™ŒŽ•)фŽb|`*’xu}{?~кйсШЬ87šG$>"ЅDyEBwƒц’§$ш""э0aD4‚йlVышP˜wЮ‹ №Ф'з *ћw7Бsў,фыo!ŠН%QКТ BфŠтiAœŠX1у0bс!„шёBOПк_DўTžUяxp‰-.эŽ­>%№з/d•СРQЌ,ЁbхlQ ЅшW:ZwМЪ$2IO…0Iyšp(Cv[FѓЇ>гя0e›j{UЌџЖ‹'pД%ƒ{gЯtХЄДфТ}дUдš5 œnрюN u›(р8СѓˆВ–…••U8{Јз“p\ї>абA{џhъЅ7aЏ{H=Ља”uИЙlY†%ЋиќЎ‰ ?‚My№Ччіл6Brcгij€••<6cЁ\Щb{{ћ>w…Э8&FьЋYGщZ ћі>NCЯ)Ђl€P†XЛтФЫ‘)P.—АЕЕ…{ыbccЛЛџ`ВSЖp8&BХykeьў яXƒт ђ“ЭЫFgЩчЕy…Л_HH%Бјь ЌЎобЕj­•ћёЅIIѕЗЕ…FHх !5{”bшŒФжїФ,СŒ’8ё ЇQШ4pСќЦ)‰ўд<-b,SдŒ;иB4HЅ^FйэЧЛгч@2™„R”љ” RЪјƒgbJJrДALкойСЭ[ЗqыХ9M[AY‰8YВ[й…џ3•‘у.О^ИЂ•% Њ †>гDВ/‰d:…T*Љ7бGѓёbЙ#YќњБТ@VЂ:"a г†ќР‡’ђћЫІЦžџъbФ;фф2ћLx–›цl +fбр$i4Э>2@РŸ—є§Uю#“-yќ…+ssœ;œй]q™шз.§tэ!KF"Ž'ЙУ'КzžЇkгЩщi,§і{ћsІ ч*k&R!Aœ.›‹7066Š\.‡РЋсAнŸуХувЅЫX^^>Ђи9ƒКbи] п,,ˆ‡h)m:7/зщ€TDO+эж{ш бЫг [тЕгŽЄљ(ŽDВЅœС‚Vlєѓџю3'TˆHвIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/options_16.png0000644000175000017500000000125111733011756022621 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<KIDATxк|SMkQ=oОgšФІ6mK‹Ѕе…ˆ…‚]ˆ"Bi]‚њ\Š…7B]‹.ЛpсТЅ"–тBpх˜… *X0B„$гdf2яy&SЇе\о›7їœs?оJ)МЛh(ќgUЄРc мћЧmцQW>іЭŸƒY…Іы­_PэdиТЫŸ5ЌTПbЏЉЃ||а5zKд^ъс2{џA|Ћ" AгBЕюужML^ˆБѕФDqЊ \ gѕУ@Ј$ОžmZ˜›žУЕ›Ї`Я(Н(рЮь8юy‡сgid#м}џ•ъm˜ЕO,Ђ~р#&оŒрйќ<Ч:БЁъ'Pa—Ц!gСѓв:6ьhМТeožIŒ4’(}ћœ.m‡ …ВвАКД‚гцјпжЎЎaЪ`ШLІMKЮ4сіG CЁЏуѓ§ы8пnЂд˜ЦицCж›Ы"Ш&х‘$—’єЅmсфQ–M‰ЅЈШ–ё‡N5Жі-Ošс |T6К@WB ’Ф,”&ˆеpі A6•эBjК=€ ю ю(КБзuрИ+ясеђUwЉ')шжt!СŠK™дYѕn5ƒjAюе-юІ>р№Nv#$Г‘tЉЗqз ўШЇ`ЛC‚vE@?%уэ–Шє.!HкW!`›…Ей-A ь‡еЊZZь–Gcў9Нї†`Q@ѓщиЮ0"чьЕЅСпЬЧ<чп ЛЙ…ЫЈОуIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/install_16.png0000644000175000017500000000146311733011756022601 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<еIDATxк„RKOQўюЬ:г дVyHРЈ Œb‚!„н˜`4QЃn4К0&Ўн™ИђE(1DЃд€ AС UА”VmБi;ЏыP$F@=Ћ{П{ЮwПяœCcXю=}ыРЙў:‚ ‚ЎŠяЏд:/эLыРLФn  јЎ‰Щ6юџЋСRzš€™цЪ=iн!ЎЫ[G9ydE)Kш`q RBБ џIqУhG›ˆ,9š-’(абeЛ@ЗUlЈ\2хШп„‚z }gЇОЕЪ—€џ‚ЙРLkia.лплОœХ/ƒЖц20‹€Ѕ јlјvоОyялїО™%ЅbsЎ“y Wё2І]FCЬIOЭNсjўšё™$ЭaЩ 5л•Жч2@–…ЈнЦ‚hйV\|іrчрнNЃyGЧZМ0дBдЁ+?ОEНŽЩћї0Бt*дЭсЈ5v+cкО{ёО4ЗPй{CЃЊg$mыЇgžЯ,?‚кп‡јZ‹Уb ВьŒsђfq)Oїи.EБ†Ї”ЩŠщТ4šлU4kпАуG<aQf„:cKg6ь*вYй#вкˆ'ЮdдЧ XЕЊ)^T‚а_ˆшЙDКзюUY Ї97|“žЄЗž.ы6Hё1z7]%•Dq’#рЅL’љђпІ ўйуХВJЦ,"Rƒачоѓ[ŸuАч0 Лiseе ўћфё,ж+О!й}}œ_ŠЧЃ@HЙ]@д‘њbѕMѓ9Лs' ‰Ѕ“ЁKТЛ.ЁХKљsˆЇ%Й#нSа9У:HЮkЎоЅТ=і‡M№Ї(љ7ў‹Х„\ьъо№ЛƒОшw”уч^іФ 0’–?UЖЯ)IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tcp-neg_25.png0000644000175000017500000000374511733011756024133 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<‡IDATxкŒU PTзўюн{ї ЛШВЎWJQФдi*$Uу‹Fmm}hZ­šІiMj2vH™Ј“'V:’DуЃ M2R`b-–щTEAMЃђ&РюЛ ЛмнЛїіП—Ъ„fІг;sюџœ{ОяќчџЮw˜њЮrЗЏ џ§и-IHдйч&Цл74tнZ{Ѓѕ:žšє’ЬЮw5Ќцњп[jO…СQџOJШиЛLџ %ЅO8+ЋcЬ[vЩ{ЊоњЩŽ;‘Ÿѕ,VРёUћbѕЕП(чЅk‡—ф\}P3ђП2ібšcHв§щŒ-гЪЈK|DТЮvЭЦы‹vbMЮZp:`5}•xѕЊ=€SЗŽ"wђ\ЕOп[]Œžаз9˜`ldn>|кP†cL!сПЙ`6У:хљч&џјЯgЏGCЫщ›ІЫИ:?}!ЪюХ4WJ ŽИЇЦLПВуœSЈNфt2&:Цƒцv\^ Юt†šСБœKIlЩФТф3fНЙ’бZ3э}›Л›jznR,#7=wZОRВНxnвМwWЄЎ=Ѓ— hwЄi;хм^Е:šыВO@W_—pљo’pЮшLњ*д]Œ –L:Sа#tQ Ф›-$Щ›<&Й9ulš[’ЅqTx?OYїј›ёўbШfГр'Y/ ььЉЫ†G‘ш,џI‰2P@•Џђф%/„Ž’ОюЏЦђ)ыSOОVЖэdгСЭ_іпЦšд­PHІ%gсхЉЛеџgйђ„Ыѕ—jпћd_…ўQ$ЪЉ$”–@n8ЃbУTGж”њ@5*њKг'š3гЗ ЋpГіM№&Р*ЧС!Ml+ПrК|ўЧ‹ЮвP7ЕjСQ5Qі]еВR“<’‰?ш?М-c7Ќq|аUŒїWB0ј№ѓŒх‡МjБѕВdZtуєKюьД­ѕЉc”zєQ‹Њ П 9n5€у‡Хжeуэи”ђl|:{kК+m'мeО gѕы=bК5x9Б‹–И-]Ђ‹gЎšЈLlџќtЌгhрbxў‡.џзЂАdЩя ЦТѓАŽЬ„0В<œI‡Ї}vX žЎўS#ЉщіќЧŸљђХ§…^EŽећjЗХ›уПџЗ›_Д†+іšЯ-X7.ž>wФsЇ†OбEac"€ї!ѓСP4а+АЮЬз™Љ‹џr“’д7jMЩqLІ(‰Ž1жє_ћУ†Щm>y‹aЋЌ мŸ™Ю<їГyГќ)ѓ“/2шОƒ`Ч=Рз c€RТъmExHЇзћ"‰љКБiWT’Ioћ™ёqь†y“Иw4,xIfД§AY{щ~игтл­1ќ;A*oэw%уЛ?њплр‚ŸќЎ›Hzл›ЌЊГpS&Q0dћ  ^ KT-5{EЫ‚t§К53tёОŒК}!РЂcєZ6С’іэGq’ГЇу‰u.h›ъ Tопpќ82ŸІ’w *-6ŒAlyKDsбіЋД™уЙ-+ІiчйcXгЧџ уlƒЯ€eQ†ЃЦ•sfІЎxйЉкТW—!yxЂXŸф"UвzЃt‡шˆа"p ЌСМ];збШЦъёў/ѓєЏ-ШрЧ\ИЦюЊPЄЭ/љмAId:§ZВqэЌГЛ†їilі{ЊКŠŠŠ044Є+$NЇчЯŸЧЦU’WSŸNšSЄћ.Й‡7бJцEuішм=@ЎвOЄ"чŽ С šФ”&и’Œд$55UUUpЙ\№zНШЯЯЧЕkзT’†Ѓoš™b-@k06…zhлЂdQrdиЖ•:DЈVн~u—MњЮGЦМqыеTБУ]VЋ{іьAnn.:;;еmRZMM v>ћјюѓпizюrŒ–q ЮТBІеKЄІЊ‘Вд0A ђа і*2f5šIŸСP]Xy:tЋWЏFee%–-[†уЧЋ5:qт„КЧcЗл OўVвй_cъ…D2 У^ЙT~мН…@ї„Ї•ˆЃаШb š‘ћDyy<œ;w›6mB{{;6oо žчП%eж5“˜F"Бh{ GDT^+њ{_џr)ьŒо|O“4y2хŽGѓўЏs"џu!3д‡Д3рnš‹c#є1х˜iйЎŽнЦ ђaVмЈыїп 75ї­Џ,лIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/both_64.png0000644000175000017500000000650711733011756022076 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< щIDATxкд[klеўю}и^ЧŽ_БуWš'С…@bC PЈŠDЁJUQЁ њЃŸ•ZЉRѕGUўTjEв‡hЋ>„@Ј ЊДTTPQ[;%!„@ќŠэјЏ_Л3Зчм{fvжvтаDЮюJЧГЖgЧsОѓяœsя8aŒСzМїПu­.uY7йŸЎХХ(ЏW'й+d-d>й3W{A]FЮЗ‘Н*Gьїd_.kŒОѓJгЇE"ПU'oг‡Ё``}УF_”„X)ї%?њay1€œЏчoPž‡ЦжVьи邆†jў5ƒ№sЗ;лX”5чМ"Ї•Gо{r,Ї Чjщ№2Y—і4vьjGOWnй•ТУ_ъDsГЁ’ьЛ_yЮqŽДuо:"+Ш!ію+ОвЛvЗЃ›œпГ3…] Д7'№•:QWWХЇлs§ёsЗZpbk‰Иvf)ѓе—ШіѓяюjЧm7UcWg›ъ=xфШЬœСйЮЎ6Є*вќ1Ы–ќшG] ˜і$Т„D™Є9Яy§<йНьќО}јlЗsОЎЦУќb€Ячqєƒ%œьї1:cодLђЧ›X/rCgI/tф4ƒQ ЮГВ?Ртегг{zjА{Kеmе}x"Р‰ў<о>›ЧЉСŽgŒQ­ПHбД‰9ЉEну‘wтЈ’*вˆDC™[Ж€›#z}^zŒдѕ€ѓ§I~SзRM­Е˜˜Юуьљ%џШй89М”ВЄіЃ3†ЩІ€@Йh[ЇЉфkiTФ>Lž.BцmHЃz_ЇЋдc§QFъu‡YщŸ П™Й€>ВхЏšЧЛPS3 дђЮh8=Taт3кeŒ’Шф|dп€qўrїёАє­'ї’§ˆЌ­UŸ?џюМKфє\ž7Q;ыœ—њH)Ё• :Ъё9{Є?t~„5є2‡5срz№йЖЕDЈ2иv›йEƒEŽ|BG*1ћ=Ї„–ЩѕAи!Џ эщsч*З BяЧž=Zk‚ьќœж|уœДQGфLaічпkY)\У ЃЄ‹бЊшw%Рф7=RњBsYс)€K ]XўŠ>!ŒˆiFй0›цs4(Ѕ€#ЙIƒh-P^ž*ЄKЙ1 Kpў’.Ъ&Ђt!ђ6(%:1 Р(”I§Й јZ†(п…і^(„a”ХУИ“œ:( AJ—<ёцyWI.ЏˆЖˆ›R1V‡и­ &z8%@ ˆўд{ЊША Fއ€ип›"'-sА „х|‚=ЛkЕ‰иCж'5џ’')Ё/ _2\#ЊQ*ЈТиМЌ(ЄMX6QFU`>0nЙK#жэ™ˆўё8D#ЛAE) dЧшJиєшоeЭѕ•OБПk§VwDХHtŠђLEcVX–љ‘?ЧвhжѕК?јЬŠПйџг/Л3 7РЉbСЪkUјYШ­–•КxiЄжWЌОq9F€›РЭŒяJнUWЎ,EађУRdфЧvaЃ8{јšЋ5%Х)‹Ўє§€јћ˜6,яB МOГj\€ я>`bjнМ/BИ3|3a’љ#BUШ[{~BЦј1WЙ1ЛЪ‹Ў’E’"AT…)~)}iАWg@о1Р!]Мj`И6iёŠ—™… Ž.Ў1PбЭЃФ0bF­оЁiO§_ЉVт,Л<ldeоbЪl’ЃAAœ,[^Е)є$WЮŠD LСqиnoљkјW}W-Є+tхJ8}pУЪ1ѕywЌd‡(ь„5*Ц‚cЃвпˆ+Ї&J=Г2тQНNЏO\MŠДАТюЮa6іНVЁЪ*2E`EP>KАЧ8s/ЕVPЄЕ‹>W$Є9AЮмВeЅ\J„Š]@V<•|ыє жЕ@BДdB­(Œ›–іžcDHoж W –‰ UУB˜U‡”’`}b‘n~aбиt@D}Ё{(ŒayДЂXœЖЪ„‘ХВ\Ш$oкGerЮ-TJ’‘Й=ќ™-w1šyИ*Ѓ.=Ѕ•,еIЇјМLgH 8кœъ‘˜IdbУ‹5ГЌгŒвФЌ:Ѕ•,uЪњ“ lEа…Ž0RТцE›+:Mkгђa@Z!—3дКpM)D;Ѓ/Э‘Ж=s‘а‡кaѕBЊЦѕ€7,ž†l­5ЇзPШх•CIх–œLЫgmѓЄpšK—&^8ЖДЦ}§†ьЧыРkђЧž^ыфЏ?о…49›"‡Њш“ф№<гYк=Ѓ\ muСжymYenюDі˜нЕiYуЯ№CаOЌw ќnЧдюлёІхЖѕиИgrЂ<4CЙпжDR6ekшћ•иЌлУчіиFŸyфЛc83ј‰‡ЬЭ2<…‹šдм".9ъРsdЩж]~ Зwў$oZ~œёА§і&дU{р‡Џ€К…$}"Ciа\Ѓ1›Ѕ–иї11Рї }€‘AЪэШШ,nѕР+ŒП€?5‡ьбўаљП‘=КžЮcЅ>уd?ф7ŒсиЛРO™46зiT№“tя|lЬh4 RTиiJVwуЖбБЅ.š4?9cзИЬOdЩљs˜э‚ўIіU\~3sнЊРТ„ƒЇŽPф5ОpOcиЭX WQВ$k)џ—4ЦЇ sEріжDу aydБ ц0rР­6oрeРыQV-@4‰1 ~Юяћz‡ёђ04цcnžЇ@—ъ)bЦЦ*…кJ…LJЙЎ0я€А,HXрЬПHЮŸpчИес5ћoœП^e№’˜@јОшzџ3hAр}_zwуRЁ–@ЈЯ(TЇ НБ;БЃŸ]ФТ™AћєНо!ЛПКч†iN’@@јŽT{{oіNуќxоjgC:ЉаВQc[‹‡ŽFjJ—0ЧЩ§аљ`a ‹ЙЧV€їШЬьйuч7W—n'јMжrј‘#}ƒ6ЏякWƒцzЯ>ХйЬВВzб|œ 09%ЫbZ–Оx.№sШ GЮѓПlмWyуЮ^S€э™J”Т_jѓ‹<бѕѕр­Зg06щлшrUр;š<ДвБ6Ѓь`dз™ ‹yфЮ‡Юѓу1ŸKяи1d—ХlЕ ТWЅ €€Рхщk\Ћ„^с_Н38u.GН@`еПЕAЃЋ3Нлинž д№ЈS$Э#чs9О ?ГszЫіўx‰ D/J€\Ћ_уђuфШ^я›Хщў<&g|TвpАusЗlOсЦN%…ХG8чטіЩЖmяБњ‡ТШ Б`јe€€0/5ћ0ƒpъФ ў{м№Б­5TИ<ОbK МЩiŽ|ЂљS'ИщБi H _Fу00KгтƒєіrЈћєЉAJуЬd+амрйўр/яЧффŸ>Ыjя5nyЧ.š2&ЧvЉЬЪ%Увe@ UВQњЬщAєž˜УбгKxюЏ§eПmgї {и–FЉ6њ~иЌЌјЯћИІъŽЦ‡‡qц§LLXчY/Ђsоˆ–њ… „=Jћ|Н5@5мёце^ƒџ•ѕuИџачŠёте\tН6FЎХbдзv9F=Ъфu­žщ—tрLxeєњŸ§r.hюЁ'IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/routing_25.png0000644000175000017500000000177711733011756022632 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЁIDATxкМVmˆLQ~Ю;_ллВыЛ5ѓ‹‘P–?+‰ˆRШкZŠ|%E-Ъ6љЁ%ЖЅѕУЗкВЖжbЭ*kэІ§0ЛЬАfьЧЬм{їœЛ3Л“™š‘œ:н;чžочМЯѓМяЦ9ЧШQВэ@тТ_ŒЋзЮБ„›лЗючџb Х‰ЧU“фfЃŽ'ƒjЌ `Б00ЦЁˆwšЊ˜*ƒžŠ•о™ЙGЁ§“­ЦK ’ŸЭ0#Ÿa‚kdж =}СD6˜ ‚Ž’”ОЄ 6І€ і*eР щš\зюqМljЃ5 jQЬЉаЬr:PрqЇЂ‡ћNСœ2'"ъ/xЯІЈg##‰ Bг4шКУ0Pћф™Ь8-щSrф3ЊG1V/D[П7ў­Вц6КB<Ў‰JЌB;•Ѕt[RqЄ‰КaїЮRŒuхт}sІn‚\”Н№~"š SpЂJЕp8ˆ.w К”d‹AЌђR5:ОњА,g zjr­ОО•хћpіШœ:Д ЁіX>З]MoDAЄŸIЫвУЪePqњ˜шbŒ™WŒšЛЋ—5LO,У#КТ$шSo7xrуС[}A4~ў Ц ,Z2M:OCш&hЅ ђыg/ЎœDE‡цH7­ohжЮЦКэиЖ%%Pђ:qхaэСKf=P5‹*ПйŠЂv„Е…ѓ„1„nЙ+LЇљ;e+бuŽСС>pъмаЅ“VЬ—ћbЕ#œW{ыaft…zИUБ@~Пххх())‘пЊЊЊP]§6! ISf™АьёXwМNVo‘GСЬ|і‡Ыžvsи‰:їhS‡ ŽIж4+ўлЯК>bУт)'„А<зц,„nє#7тЧыэh%Ћ‹ЪЯЮvЂpіЌє3щ§цУХНE8 &T~uѓuŒ[Чу.šэП“ФhщƒŒžрЦБћпёЎлˆdqй8s9ZjЬ"§B=єЙOƒн8(ŠMEfšD‰ЎЮЈљT”.Єh…пђŽQ,о::ѕ)†GmžЕCt=Жсw>М5хе›фшJџrАџёПыЗтЄф˜ќNЩIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/physaddress_64.png0000644000175000017500000000556711733011756023500 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< IDATxкьZ pTеўююонl^В$…bj0Hcл):Ž­‘Њ‘ig,ъX;0-кŽуPGk; LБ3Б#ЈSЋЅHGФPQЇ<,T@Эbx$$!$Y’ьf7йM6ћ~м{њп›M ЩюцоЭƒUМ3пьЭцžяќчПџљџsОГc —ѓХцŽур=СD˜Iш&8С6CЏБ:y"mHХ<сJТjТ-„й„FТЛ„J‚—кА vРИй жY„‡лЋЊJ|;ь0LЭƒщІ2.њ— /feeUO mјєlИЄЙS@—[Р”l Jчђ(š)ЊВAt„uўkEг+Џс4`ˆиэ57!ко†?[‰k7ќ=рЪiгІН/ѕ;ЮmАїŠлЊќEћ{pє‰А8tИ,+5рЩђlY&‚ЇgЇ-_Ž)[^=”ŸŸПœкјЧйW‹"к6UzЁЁ).вWumQдwDс 2 tѓуb=6оUdƒFЁ ’чзXок Ъћjkс§ќ8рюNŒ‚Їxr‚џПя#Ыв|ыЮ;—ЊрWlУsQЦAЋуам%тt‡ПРAУk еїуPCО+й SиЙ–Pо}ф0tzбюnыы „A§Ъo^њдЫї€чпл0wю‚Ъ]DŸA ?фјЄф-x)щџч-ј;Šn|Tо‹‹ЫpЮя?КбћЉmЫh9`ЙВ …QMІQSф 'x)Дд™^УХmГhЦЦЦК5$уVaћŒЅKmЛжне?чу ^њЬМччиН{їЧ’уЦ1d~4_Бњhоы š„Ає^‘ JЋ€фц&ю“?ЙСf,ы<иХƒ_Жчж=йRVVЖ†к#xЦЉ Ш6PцwџЎ2 ‡8bДУйx+ІŸQdƒвZїBЁЕзПёІ.Y=ЧF >{ѕ#Ш}љMьйГчCzОi г%л јз>ѕг ”ЮжЩ ‚‹єјУэЪm<“ У/›Эі Ых:бѓЦ?XЧНwАіт9Ьѕ`9 \Хіюн{fѕъеЯвcХ„LЅ}ЄjУо†({fˆ=єNmЊ Г“6AЕ Њ;—"’m6›џtАњ0ыpXYMMMэњѕыЗвїЫз2bЯMˆ†каоо^cЕ9йcЉи ($Њ љїЯ‹ААчЮ–Ти.Ќ—р‹%Ќqн $ЉbЙГчotJ]^8їЬЕ6шЦ`WTc ѕ‘„ўиЅИЄн€‹зчќ}A-СЈIPIhІТъВŸBўTlар2ПОuРЗИЬ/нзСШбDбEљшщ‘ЕаŒqE“]П*”л_kр&й+Š l<ЏБ8)‘(ŠЦ#%шІэyРEл$Z Ь*EhъucEгиВ(Š^k>yFE;B-ЅБ`/˜зF_rФwoїƒп лэS$Šъ&Ъш rц ˆbnЁI@г_CКъСz[ЩKДђ5€ц§`\мѕkOЯ4кn№ыTdQеoгыЄА––р=-`]gщя0ЅCОп”ЇЇs+EПN…YД'WаmИЬ}Ёџ^t†0я™у8ŠћEбЬoŠx‘BєYi№^07НљHмСЫŸAkЪЂЈ~Zn>Ў4 V^R=є”Jе ч,@OкЁТуa kќaZОЦœ"цГі’&>|№Т”yŠDQ]МкzІтгБСoZ[уШo‰8ЏЈбўXйЋбїХxЄЄ$І*ŠЂ№ЖMЈў'Y+…>Э 1xFаф-ЦюўІXЌ­‡j–œыl€нmG^vО7ї&,œUЂДЖхњL8\wАЄоZЎ>LY&”Эћ>Э*•y233ЋеDРPQ”JŸ›§g азње <—ПfћuŠDQЩrmЕіvTМz№e„Ѓ!й ЛЛЭŽ&ДЙ.рЎяЦ†ћžGР“єаSцБQ~љЃ"Dнž.XК[­ИГt%6Ўњы “FЅмђНпя_“)іНТ>‘†е4тЭs3–€+XŠgўМaыsЯ=ї5БHб“ЬW‹ЂиієюЧЉ# •YЇкПDmЧ)xƒˆЌ?Z—ЏР–ђз“8^ФŠQk=&{М!/9#JN‰^ФCэ§J0\5 š|'K™ЋˆвШ4˜Оћ?iЌнБcGхЖmлоЁGЯc”УQЩо6o{Њкr F}&ъlЇpЌљТBxФУћж}†ѓЧ-їЌZЕъ=i!•ЊЩГљТqЊL<Ь–у8m§Š„сo2 RMPњ"Ыl6?^PPp7Їз,Њ>sGї}ќвцЭ›? џIyЧ›џЃЎЫ?ы8 ž’IoЄч=u`ЦeФ‘‹РwNП‰ŠзХ;p”yŽЖDІ! Ў€­~ВСУУ%уQsFр]МxёFњм’ЗъZЇtVюмењ|"Q4aЦІЙZh ЕРdЬƒ3м… я†>'ўУgz?Z[‡Ў—yТЭШзРБB4ЁзЋцIIец№)‹Ђ: зКЌC‘5аLЉв .‹оZ‚"uуœ›ежФ“››Ud Ж —sA›-&,vIxŠЂЃь7R–пЅЙЛ§жЙЫ@Й:2\Š€xXYј‹DŽТ ГРЇы†>Љ№LОиB^Ы™р~ршЭЈu1шE6lЭskС мЇ“еж!<е§ ’$­žgR…)њ‚акЭ‹пBйU7C—Хd№Д4РЊљ`Sщіб‡№,6SL•gr#`xm=йUZхм…–РYe—Ё|Цoс<V\[;;;ѓ(]L–4wбc___o*‡žjxЇлOЇ?|“J[.Ск@*OWФ6H)zв›MШCэ„бі“%ЫщежRОhPуТ3с2гЅўЕјh§OД.yIF’$@]^ЮTd№RЊР5CжѕЉшˆІ™SЏ‚Іџзd†pў=XќчхN’Ц']P~ФВœžСjG}o C|67ДŸШюSxЄФ“ПХ”ж@=fъц =и„h†zCjЂŒZžtp@PSђЇцu[сжиe1E еbJJ<щ0Є,И§ЖЙwРСZ6x`ШсRSRтI—*S– жmІяФBJ<1…кz†=Ђš']GcbЪYL.ЄЈe”ѓЄгJPؒˆW OZэдŠ)IxѓЄUЈS№Ъ“–˜lY—ѓѕHН1rеР%.IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address6_25.png0000644000175000017500000000157311733011756022650 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкЄUOHaпќйm]W;$bжŠ]ър1ЊU Тьb„A‡ ˆE<ДвЅ ьlGЬCAt Вq Њеь$"Ibј'„6csЧqswwПО?3Й[ЎŽЛОљц{yПї~яНoЦ”ѓr+’+:€6SЊЋ bЦєf@tWu&ˆюј‘<Ьпк“к ТGA˜П’…Dbп€k]—ТHxњ є‡ЩnИq•ыШ—@wržY§ŸЕЩ№rдЉэд{aьлBЖ‚I4RД.ddЭпШlфІW'сKj ; uѕ№ћoя"йTиQкєА$\'ящь~DTГюДR№Њ5gЭ4ЯaН‹шћvЯYYHy™ЩI&|7`d*КDŽ1Вц kыKЦQС *<8Ч™ф2ЙtШЛј0шЙќœЉL’ЃaыН}7%E#AaШъоyЧ ЯПz0ЁЌE–фJАh§ЭЋзkn)эHРрЉ7ы]ЅJ1Є—ЭaG ”4бM–ЬЉ“,y0+|ѕq№!зFk„П УтPѕЋcї’Ž3‘=V'Q@7Š "РєX3тђbўц‰ІWRj3iѕ=еDRxдьнm-6с8вЃѕŠ4‘&1x“VG:БЂg5Бhт VS БBг: б™ѓТšАш‰ъШЊеб‚АСtqчТ?Гф„:–ЌL˜sХ"цCjMП}_vŸы?3f;O5єјмXm$є&Ш@ -Ѕ.њY€™dJ•ˆѓмццТlЄ*Bэы‰”šOЯƒзїщмwCeГs4єЖЈЄ_š1kЂЗD…Eђміђk‡6Жcо–Ђ|›e\pCГ!њ?йЋlЧћN5) Ф–йNyїоуф Š˜EmeбхTЪСlR‰О[N6žцнј `0tђFє?[I5iяoУцоsо04&Zшœ bЖђkт€Џ2Aаїи–­ф9БЎ&„žVвТЃХlЉ#34”ЄIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/close.png0000644000175000017500000000031511733011756021725 0ustar sylvestresylvestre‰PNG  IHDRрw=јbKGDџџџ НЇ“ pHYs  вн~ќtIMEв +цg˜ZIDATxœэ‘; CСћпY'хS`1†7™Fкˆšц ІЂIњХH„hяtf,hБѓHРЯЁ7АТL*+‚цЃ NCЗ в`›А E|мI‡oб4ГЃП†5МIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-neg_25.png0000644000175000017500000000243311733011756023640 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<НIDATxкДVKL\UўюЬ0ЏN Ьа)BБЁ6Е FБ БЉ кtеЄ‰ ‰/Œ+FšАд " уRSXАtAZ75@m%!MгкІеV( TЃ 30яћ<чјŸs„6UёoЮœЙ7џwўяџўsа„и™qХG-–>ьм№”‚я&DJ#яйA/!L('ь§ььнkѕ|wM~їьp&ўR•–e!›ЭЩп+џ’”Lз dsYљћnU“ђw"тйк#џ‰! a_EЅBuE ••‡РG> )’xyЇNžB]E8§9Т†Э-˜Ќƒ09Э\‡%м€ Žfƒy,ЏЎ1DAT…ˆ…ќ4ћАzNG(RЕR$•‘(jід€ †ЗчЎcѕћ/7wИїф{јЄКB“є‚‚’х9f­™дIЃM(С4€FkлЖ‡UŒM ЫЫ‡’ ў‹ЋрыI8Ы Hœ=ію‚г[ Љ[LлMRФ›5hф)!KIrhšЖФtLѕ’;h‚єфЖZЅя›0Ш-эNf[uLУo“”•G 7˜—ЛСeF%–Fп$1˜ЎbЛO%Й$СC|ŽFРпxЙ9g8Š,#’BŽ­!ЫвX-ЂжШQќђCюУ’БЈСддіŸЬbm=ŒЅЅЅ‡фrŠnM<Ў йbЉЋ)$sIєЮљњр9ЦА;А с8ž Х•уЖ^!>ВŸZнРЭЧЗямžs-ЩH.Yа9i)‘Р7oсfKПВ­F])4ЗЩd``555hkkУЪЪ "‘њћћ бв₉ЎР_ц‡?@ @Гп2ZзФуˆь уіч{Т щН й*rZ‡e[рŒ§E‹Хpњєi ЂЇЇнннhmmХффЄzijfF–№zН A"єљЪ( жyF{П"я‘Кž~§rПьййŠЄННI 766ЂЖЖcccшшшP$БhЬ­'Щa‘]MгTgг‘У‡qїЇŸ7T‘Ж‘Н*#ы2žэ’шŠd}}ННН8~ќ8ъыы‘JЅаззЗщѓL:НMcЮЙš/^М„{їюm%Q„œ)IlubЈ›KDЃQ144$фH$jОpс‚ Œ„{Йnљ{\іž'МњrsГxсш‹B~W$###*№јјИhjjУУУj=11ё$$~B”p€а@xЉ„%W2™Фшш(:;;•D]]]фžВ'НЅ\цFлŠ}ЎЉЮљ‡A;еўХџ]ZЩ­№nм 0Ц:БUХи"IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/classify_64.png0000644000175000017500000000712211733011756022751 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< єIDATxкм[{p\UўЮНЛЩ&›mšg“”О’6ДаNЁ RЉ"„ЁŠƒуcьтшјe|"8 ƒ€ŒЪјDЧqЦQЧQф!ЦfдЖЖаGкДišцЕйїюНїј§ЮНЗmВйMR83Пœ›ЛЛwяї§žчwю*ћ}˜ЫXKљe'eпl.рќAc!‡5‡ЯnЂ6ЫгˆЦbШeГpД‡˜e@‰jВ9D"d…tкШоBnц 8ј/pКWŽќЙЫзэw6u"‰"яца7r{џCЃЏ!уЅаЕ1‚]YЄ wЯR[;HТяyxУўуЧC[Я;MчіТЩd+рœU[ ]p Е†eлP<ЭчЁS)иќ?Цѓn2‰СƒcGЋ#€ряфtЋЩyk7`m—O@w{7”ЅрxœHЧС‘зp`d†вЧyДY^ЕIqшs™o$|e–$МŸ$ќšwМ№зПд]НОu>јpиМЧs]hZ…Љ…G2”чAЙlZ„"š2A ™ŠЋ јяС_аЛб_П|к–Д№š^/>hd?ŽOє#э&'С["<ю|ыЄЛ}9А†йњэ‡8Ншq юк ;d#DА–M€Л&lР+‡ jkŽыс…eЎƒНt)j[[+Ћм‚нGхџsзє_ЮЌl]iBнУЩ“ш=€У{ц :{ xRцјœ+Ž>kы'KиЩŠ-@ю~@b.•‘ђD ~„єЈ}7—ƒCГЫа/O+pшї3jЂQ8йlE2ќ†brУжM—аk:КбБДУh^РkЅ1‘‹c(yƒЉcHт№,ї №*јѕv…О' Rх)љ СЏчtхЊІ–еОv­ †Ы 'зъц Ш";<З'Œt g"aцšІ&фФf @nLЂюUТю;ЗМ=ЫzАЊ}5ЃгпМP.Q?™ŸРDai' m{шTр‹Ч=7(zTЫНП/Ј%vP23€ясt—eYящъьmмv–єt#72Š›PHІŒцsЃЃШ ž€K ћw Љ4•f#{ryКH9Ф4ЅѓЫАe§ft5waYSг\3Т!МЋF§ з4DыCы6ž‡†і6†‡‘9r9Kэ˜ђ ‰СІLЊгLZn–8„m žS@!—Жj ъњi3їъ;ЈЏЉCоЫ#žEМЏžм#‰CˆчGЪ‚?єXйЕ…ф‰э,†N–жoЇ&ol5„{7n@Kw7ИШ@Іџ(Э}и#—ў/iQ4ЏЕDШŠп,s†ŽбuЇ*„$B dЪUпg№љ•їњ>~ЁЦXnЧG1œ2Џ№G(џ)C‚|џ-%š—8єUЪ{›ъ#сѓW-GЌЙ ^<ŽСЇћѓ xёlEД’Ю$6 rЮR&VN’ дєЋС[Ъ•ТЬ pК9UHЂ†ї–Ш›Р'šw+kіСј3ху–ТН”ЏQnlйЕНЭЈЋ У%pбr~ш$<њК EМM;˜=dэ“`Д.ж |„Ћвх№t#MBЁ%ШyYЄœИяY^YŸЏr4PОDљ@kиЎнмд€њzці,Э;УRw| ^" ›ЊŒЂQ/ШƒE№ДŽгЌAЮ[zŽФsЌНУŠO‚LР воtрUЈ*№ээ|­Ѕjзе‡ЕЉСtЪфt$€пАA $ЄI№J•Зq ш9rИР(„uг№$эЁвjыШІЦZ,хE$r{Ьщ`mЏ˜зэР}а:А‚S­A•€—PЇњ›х5ОЩвjŽ.@ЌœfA‘e)ЪuЪƒЏТn“ЉN!ВЉFЃ•FЋ•e‚œˆ:|Y•hZMa bю9ўа>xЉДФ"ЄŒД•ž›LфЧШj7(|P|%.Рј0ЇwЕйˆn ј6љ\ž^и3‹ЩуЩTрлЇ€Ч™жрr>JёLЉ§_Jї€‡zЙйжЙСЌ—1ѕu,($јYхСWhВ@^ёаdљ[„fЂf•є#zЉпŸn . КЧ=sЉ/>CЙLм‹$Ф\5Ч–XЪ@ТЇ АМ щСWbписмФЉяЅœ2N•eЬ•B@fVОљZЛјкiØњЋŽB?—T§Ы’кY№ЁчH@idМ$K_*ЭіfЏьŠ;YkЕїЩДš?IТi` Њ”_Јо“ОцwQ>GрЯ–T–п ЋјœЊk.ПіЏ|•uР†cŽк§Dк'­h gh|’пЄКп•W8ь˜БGТŠє Іш'ќ0Ј8'f4ѓО+е§пTм3€WеBi Џ<‘ЦцЋЃфt”НSRžFsнз„ )ЕПH O–iЊќ„eЖ;k ЈФчKСЯ‚г|:юЈ—Oњœ=5HлtСї;ІвйOљ&хщ :K?ЋЄ#4MИцrгЋМ5;d\|ТUЯ?–ТЅзF=„‚bЧ "ОЈpЭўе‚ŽіŠiиŸЮњЦH5š7ЧsйuЖЙъІ,8вч› ‚T7Ѓ§_ѓ}тѓs_U Јќ ёіaW=ѓHЪКтКЈ_йМœЕDћў`аА}ЌuыsvЕ=ЦйY@•р•љлF\ѕєŸR6вьїž ўЗRЁ{mgніўzЊJтuйлПjЬХЏxжv:}Аj|ДфѕsƒŽжЖщr}YЫжzaP`jЊє­ПЄќ-hйџП]wЩГв`НŽђ<хЪ™­ГЖ€E0vЮрВ[ƒЎіѕ•Жм…ємчЪOC;кЬ}пmЎъѓ ‚Цd—H6H8ўHЙiјљЫм>W§ѓgeи~0•оbы‡3;З[ќ§Ъ`SчГЪ\SыГ)Sїхе)$ЬvЌ[Тл._WќїЃд№їч5 ž­a€—0лБВ3„е]6.Оt’„O‘„;Ћ ‚ZызѕЩ&орgžЋоњMcБХF$ЌHkŒžпƒƒЛШщ[љqЦƒo/ж,pѓ|\фЎЏmFˆюГЄСТjZB5RГ{^–uю HјщЂLƒ­7mfєЧd&ˆX~[—ЋnдXўџQ– КHcDё˜RУу:…њ_"5ўr9ЬзКZmиR•2 z^іўЫXТHB’$—џDˆі]$ŸіL!“w1Сy4сaYв6юcЌh‰YІ0ZжЬРиB:Ћqи^ƒс>C‚,ž.—VкТ`Љ’•хЉюpъК“PrN|М@Ћ'јtЮУ№08ю!VkЁ}‰b&рЙбB=нcU‡ќ –59|H‘4.[$AU“ ˜ ЧѕуУч“ъCЦ’–1}‰э6Z(ђАTЎ Oy$l52ƒ}вCје"pœІлъ,Ёє3Žј{žЏ'ќЂR4ћtNcU{KVДлއ№šŸхЉ” ƒ}ыљ AЮŠU …1ЃIйМI+XH`|ц)ѓЛiœlЇь[ј~€ДЯ0$K`thюЩЌgЉM R,)мѓ#h˜јWG0Oъy'Ёјю гц`\уП1рЅQ"uР‹Х~РТСРЮ y†ƒч—rг9ОЉДZtp6HџчОв–кУEЭ/Š–of^О|щ5Эb %‹*™“/ь-Ох“˜цw m?‡k\3ўч]+ %–јЧ‹Џe~ДБрMб ђŒЕЪ#ЎВ#:е,ЅЏф7џXO.Ÿхм№яўešЂMзm ^cБѓдютхяЦ ПSXј шЏ…ІŒ•Ф„ЩK§DZCёдQС4ЯОР,I(]T=2 ўСРяQ Q ЮŒ=КлВЬпиYщW.Иєп§ТМ\ЧЫЩ“‹x ў1*о-Ж№цВ7ИUl‹Н™КўZTЙ1њf!`_АИ‰ЯцУџ`ћЉйЛ їКIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp6-neg_16.png0000644000175000017500000000200511733011756024347 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЇIDATxк4‘mL•ЧЯлНя‚МППM"@ „…$[ж\Tk5]Q ›)J[}jЭЭ)J”Њ8?XШж r L)ŒЎ\С7сђv/м{Йїсои:лй9л9џџ9ч„жл^Ixѕ V?8iЌ§йДIЩ>#Х™;6ШIQи›$sэгьN/§cnо(T‘#Я~ўpN#2иЇ№єU+ЊQ ­зAў…кom,­{ˆ‘јф;сA"ІIёyнŸnё`BCŽ“/]ƒ.о+ѓЃќРœyb1.#Loп-1ЗюehZУ?P$(@bCƒЃЉ .=Жпw"n$UdS€Д8™;CН}‡2 ьђ‰жЩ fЬTЊЏ€ъ#rуO7]f7я—њ" :88X&#б@з˜Fооw+ЯоД34ЛEbŒLrЌЬІ$Ђч‚eU т•ЖъpЖп”“Ђd $ŠtЁZ\дѕl’*’-1ГЎP˜(sWПлЊ‹чЏƒнКр сз:j›kЎ‹ŸцЌбё}ЧЉкЇёВЎўыYц,c§љ3ЗљћЭ—(Ж№ЂўД‰ь‰ш@аYГ x(›/]тŸњz4Л5$„зъъИ;ѕћoщЫ>E=gЮ`˜РНБAй­8:/рчкРёdˆ§ЋџОе“{]XіŽ\ЙТШхЫl[цЉSФ––вЗ ~єџИ8rЯŸ'вsmњ’э)њ4AДЛDcЙdyg)єУу_цm9XL&њћyмоŽca€„ŠššˆпњУы1§hёK~NVэKВбeCrYg•ЈєЏФ^­{Я+ѓХф_МHRy9^gчХпŸ‚†b#ˆ}пlљ”|`§v9Q ‚зхL№Ю ~/ŠnйЗФя(ѓїюБ2:ЪџІщMwwуJ(†мЗeьk)X‚ †аXDеI’%iсъZKВIтNUkccЅІsј0+f3‹8-Т*>C-:ынWё,Ю.Бх§HˆЮК 76ђы‰и&' HJтPs3Х--dедьl2жкКCN|(nМv/кђђ q9З№ ˜wggš“C`r2EњKЧЕ–І‘ЏЫrЯ#ѓфI|ТУ‰((гO-SТЊ ХЈZ„х) уШ1%%Ч$ЃБcip˜#G>ށњч{к`ПšўluѕЈoTщ••аrьVІOЃ"Ÿљ‹ѕЅ9\ў`7Џv„'mоŸIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/physaddress_16.png0000644000175000017500000000106111733011756023456 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<гIDATxк”“K(DaЧЯН3lPJfЪšС…МBЦc˜­ y—Ааˆš…………вX EQl”А ˆ…GВ!%y6хЃ†iц˜ѓ™{ћf\ЪПўЗџ§}sЯwЯљю"йenЦP3S–Иdmцj_’~Щёщ“ћшBZТаXY GЇ`лЗƒЄ§€œлЌuА}ь‘I8:lˆЉзе%xЏ,šаУ~` ,%Ї сКсMЅ zD.P`n„ЅўQ9‡Ъ‘и~`ЗRзФЪ |Ÿšz’CћчM3ряƒVЪМ]S5x^+2Sf6Южа8TШL™ #;Кtш{лЦ[+BLь]юŒЌи}йЪ$%ЦЄRКї~qњ‚†'-(Бh}иЭ­,ЧЊПсZPš}H%t~Џ6Ђѓ7њ}рїДЛЖ!Ѕ|7v,№ЧH%5\U1РФпvхяЉЩПяЙV}цл<_Чђс"4фЇСжХ&{byй:ЈšЈ@ЪђAIeУЬЭIЛуœЏ0лИ Ћ0˜`Ю6^WXؘ4c‡ЇїG№x=2[Мš†gїЫА”vCмm&ИХ™НŸDBдЇ–х/_V˜–~ёЉIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/log_25.png0000644000175000017500000000240111733011756021705 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЃIDATxкœVkL\EўцЮОЗАЅ‚ДЖ.ЉжЄЅ‰гЊ15ё‘Ј?Ф”*Pm“VcгDаšЦš#iЌЖ1D-ˆќ`ы3‘дX`1ВА< XžЫ.Лt_м‡3swв ­=›й;swч|3пљЮ™!šІaБПP"^ž(эGїa7*Ќ/#HnСЇE­Ќј_Xї#JЌ8Q6€юїjё•ѕEHЊ˜ћue9ЙЦ!Yи^кѓІ–ДЩкэZл.ЂMќr\SТAmЌz›‡{[ХяЁs‹ёŒЗ~nNbўU>ЅХ;`+С_чšаоб‘а3т§Фшњ/ СJOљ166њЖGb1ФXS…яdމЄ™``)+W‚R Вq;фG^ƒДz`ЖоОЮч?MЯ)RZV|Kњz6$XЪ A$‰" Bбь€k'тж4HЃЃ€- Ш\ щђ((ћD hцј|8"—рrЙn$ЁЎЎбh‘HсpX<“mvv–§'.žВ, š8ї bў+Ъ)Д?wL&ЌRЃ˜6Б;ШЫ{–Ы‚}œ"Б•Kb&5™игГй ЅЂЯр훆‡OюІоЗj’MK5‘й ЇƒгPUЎ•eF!зЃ‡H •)хР ѕљТbGr§Ю}|m a'ВпиŠОcm]† 33WpЦэ”pеpкxу§ф;UUMМЅв(о_эСЦУРžЕJKдГ tG@(~4q8ь((,d4Бњљ•szЈxšЬЌЯ(’Л~Чј—ХИћШc09зAўЙкХAєѕF ­•ХdпУ№C/š ;$ ˆƒё№јикП‡е[{Ž>Эшq@ўс7 0‹!(D;НщNыюЮЎ˜БК‚С ЊЋЊцдУA9- •”ПВfс*}кxЪЏ?чvЯљ)xЄ{QДСЛ{Y ;WЌРўЏ&rA0Їˆ+Œ~іл}А;cX[№(дžqhѕ(N zš&‘U\Ž?*ћPяuђ„vЪяgN•­ššpГыњ=Ш*{jk/аvВгŽš'qGIRяпT–\?ŒзЯ?т++iеM!%чV„ЯvТ64ŒсA–mWТјxd*ЗхнxЦsК<ЉŠйТЮjЕ@lDЮŽ4 }‘}Pƒ,Vд зGј&ѓЎџWЛFF.3ЙšDуЖeK•з ЙАЁ@ ZkўFк@#2ŠOТ’’.”ЈK^7ѓН“/ƒј&'ёnYЉЈФb%LОnї455!77їЌпЙЫPГE8'‹Š№љ|iљЄЏYƒS•п ›Э*r„ЇLK‹‡бfдёЪN˜ИsƒУ[OЋѓUн„Ћ Ђ4Вo–ˆ„шu‹pЙщE q~ŽЅф*ЊЎ9:Œ^Nљ|ТљТЉІћL”’l˜пЩR@† Зede‰)DгСNOтL:]fKƒш?hњѕKœ- ЩŸѓL -И”кrЗ•›1Ѓл Yюоu3ftяњO€D‹„РбяIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/ruleset_25.png0000644000175000017500000000137611733011756022621 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe< IDATxкМVНkAŸЙлЛ{ 6ZYZлк›П@Бѓ+ ~Є2Q ›(ˆ…•(D1F$…ˆD и1"bАPKБДѓо}Ў3ЛЗїюнЛ{оIpaђюіvч7ПљЭьЅ”P“'ч†'ўa,?ЙƒC bьє‰YЙ#ѓ“ћU‘<нL`— lЧАmD ?“ 6рвЏха3ъ5­пыŒњЋйГСБй!gгф3+ 4ˆEAрШз1 >EГяж Є/—cXО1Н^њ§>A ,Š"ˆу’$4MсХыЗЭAА" ЩЋїUЊŒ9Жf+RG0KYСЕЄTpjыЃычr&ѓїžФТЧ<™аœI’|КЋЪPy&GSзКJx]ТРЦЛ"uiѓv•:CэLB‰š?ѕ• qАa ќЧЙ\9ЎФУP ЮЦ‚ГБјkoо5gЇЃЬЮп\б§aksЙODіЬsЂeКЂHJ wgф%kЌћrНX“YЪZЄkc&R:идd6эНp{UыbщЈЙ„ЗhCпRšw9ФvщтšЇ†‡„™Фtб‹ЭЮH*Я€ЅYЫЦmвST‹nўўj*‚‹Л‡КлW!џђјк›ЇыwXжDТТњw№H`˜tb№ГwХN0wйœЩЯо№bєьЁyфkŸЗД’w~шc›ёёБ ?Ÿ\клнјЅ"юИƒѓЭќ­у­ЊI.mR9’YIsЎЩLф†wЈЈ9ѓмЫпWO…0}РsU›Џ|У~ [h"+ж>|ЈTu2сљйZxeЂžX5Ш5:…:•бoўH {Zt<ХЃнсЈ.#жzщCЈј%6Ц7ЖНOц иЮџуџЎ? =&‡люiъЄIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tcp_64.png0000644000175000017500000001574011733011756023365 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<‚IDATxкф{ ”Uе™юwЮя­y ц ™Aˆ(Bz‰­bŒ+JтаЦ&jЂ§вОtLьhлОNд˜NкHЇ&њ@b"ЮAДDТP%U E дpkМUwЯћўГoAUI/˜GжzіКїьsЮоћŸОџћї9Ѕ†џŸ?кЉ iкi8з <“5žjgЄ^ѓ%~­љ жї$л‹#њцЇЧZЩ–=Єoњњ_œdœ3™лЎљхЯT‡LG&BБ:кбьB˜ПSFjдћxЭaА/ЋЈЈшШШؘݡЏ„ћ/о|№mМVЛ 5~hŽID0­d:юИф[И~ц еЉTъ Їгљ;^ogЛЌЁћШыїЎ‡EЗšsvКрѕЗУё#™JТрПЅ3БxТ,›№wытёјYYYеgЂыX1G„ю x‘4цфŸtдЂЙЏ Сh‰Tbд"§ш9иwОЧуёQЗѓО‹ЋОЯХw ’Œ@ЗшаtЭќЎѕжрыП†uЛž[Ию–ѕ ћН§AёЇЂЂЂH"GœMзuD“Q*ПŸxk+O„Ћn|kЋŸРЊ97­zhй;vьh™7o^Ыщ„гЯ,ЮL_1'ˆі#˜ЪАpсЇjр}^Џ7{ܘ1џpИыа’ЗыпрНAЂ~*ЧGa"\1ьž›оЧVѓЗхюпќц7ns‘š‡.ЛN›ујЕЂМ‘sОИчПёы??љ*ю{i:{ˆ‹Щ‚;ќ­f Фњй“р‚œАrвбš„P"‘А&ДФПл§,Ф’2Ž7аŽюГЪgajЩ4КЖ6ьОЗъ_EНџРЅѓчЯџћH$Ђ‹"ХIоˆљсњЂђN6яЏЖ?ь1йЋзЌY3ъжГЫбhєyЛнўхЁчФRз=Нтјё†[^ХТБ‹‡нПuыжщњЛŽZнЙ­с]фЙѓMїMІRИoй№ЗкЋzŸо]tџп1Ч<Žz3ПŒЛfќѓ;ќљ˜‘|ѕЕއqДчОБшnЬ.›sќк7ъ6сю—џ‘о90l=GЖ5ЎОљц›ЫУФhrž‘|ќёЧkxрё—_~љœЪЪЪyыж­[-ЪБZ-Ч›п{яНё{!лliЫ—/ПmЦŒKп<ј c>ŒЮ`ZZ№§Я?ˆ?Ў{хѕiгІ}ЕЌЌьђЮ=їўі†п!з“{|МЗПŽђђђMMMтСX€8дŽі@ЋщIїнwпу6›m‘Ьsž1ўйЏ/Мsиz>jў'N\ТхЛN%뙈 -Zd ѓgЃ@ЦŽ–jиl–šЄ ;љs?ЕHwч3ІдuзЂ8Гд\јљESаvАЃёž{юљi2™мЮkњ—.]z  Э^1хЊ[ћ›Б|т ЬЏМ|№A5]7˜iКТО Н‘Ns ЙЙЙ^†з>™+ >ЛаГјцџкўш‰ѕ08ІяdѓŸ•јIЅ7††ЧP ф3ЋОћD ІЎpЛ‰фзп€к}Е5<з ТЪ7 њгя-њw+=ѕнwп­ћЩ/К{ѓцЭяНњъЋ9r_{ …cxJ`!>Э,3ЗЎОvиzWЈ щАœЕЧТЁП)ЏЭn=#›YOы'Д(Щ$9CчNЦ+‡_пK\ё ‚юМ=''ч&ё6…ŠЌXБ""n\гЕ]/‚) oI™sнrЫ-_Ё]%иH[ВЎцЉaы™R4ћwhHя3QРЇRу089жц~z-І%„˜зЙнnЩё‘“АЕ(П:F`T(iФNљ‘тVЋ†ЧЖ?€L{жєС‹ъ{jЭь0t=Ÿ+_ˆњэw>:й<Ÿ‰tКиPы'3­vЫАы˜у“ЇГЬЏK ERžХLЩG§?uсаЕ|џтсЃ­;vянЛї0Уg­€‘юm˜–д`ц'ЎYќпЭяm_>dЦтщЎ;•8†Ё№цŒОЛр‡0ъœ5ЫЏ\ў0… &ў:!0Т†‚ра~aggrн;з˜”.x.e{Zквѕ“}'›kфЇШ]ŠbOЎ›x ќћbћЏМrХC’НйzG`зg#В€>ФВCњЗЬ.šџЏы­=~nЯN,XА@ #ЫаћEјЕћџу[{Л?Цч+W>ОœэЭ•ћ~I$aф\\ќ[Ь(јмёуоооžžпЫы^оB.ђ‚L“Ц’Фщф8 дFЭCњїŒЯО`иuЕО]ИlьеЂћћ‡ yimџnД„рЉњЧЬЖiХžе аВ?=—ЎGyфЅtŒЇвТ†иФkg"ќй‡Р(<`АџкЗчј6.лЙobофiрЊїяЯуDСў­ЊЊъ‰'R&зєэšyŒТо;6ѓ|tvvЖeФ“ЯhSЇЕkїьIœv_ГЉƒ_ХЯ >3с:>Нœ6FўвЛ|†ДаАБ>њУм‹+ˆ#еѓафТe­CŽУ‹т<Ž‹s1'“RДќ (@гЭЭ$ќфЦ nk]„Љ‰{oš‹о]zwа;|пEиџ:іО6В ђRйр=єtЫ&>jN‹fеДtxoƒлYСЄ@kЭ|4ЕРf} љЅПЧ”™эШЋb>9J/ ЪХп‚ Ѕ!к$S?DИw:І]ЃСE7~‡еcsЯ,фgNEqЁХeТЎЌnSд‚Эj*C+Ъ„–LRa‘qhhњ*њXјТDтQdИ<Дv‚–—‘J!Ѕђ:zђ(РтJƒ5Ж8шŽ~;‚EФЎ@NіUШ8ГЏЗ ђJ.’VšК›ЩўЈž\ м9ВЉ Т$NR)вм ‰1L$]G(ЁЃ+Ѓ? # —–ŠЮз|=VЄŽьWЬu€Žyиб†šПekЧ1рiв‘лц—ŒŠ9з€(’JќЏэикФтѓћїѕнИcљДЭЊv3KO|aЊЌu–9цwЦОF!~Љ ;Ќі™Lh7ЃЄИХ“Ws5TT“Юњ' ьUПCэ@?iA$hКНiХhL #1э JЈдžХŒ${%S.­w`žбйtЛaЫЉгcжЃА[#№ŒЈАUGA†ЋИьЯu0l{УXА[ тzxюФќ/_Вcм63Зzьнџ Ќ%ЃЋп‚Їd<Ѕd1У(LHХ0ЦhэpoQйAВ†‡ž@Џ6…я'Uдт uмЭуўДИаѓЌа+2eіФіšсЭЏЌJEBNxВU(§п„€xB›wЗaЦМrФоoФ—шWИM՘JаЙШ‹>щФ3єЪѕŸд`e"…ЗЈŒ_Ќ‹Ѕ%-ыSDјнwНŽФР­аm8/Њj№iГƒX`ЭTVORиp7'bхhЃdС­ŒїpJ-PТARuBН!Ыq"њњуіxЯWєоц^…/"йгyЦ kFЈ•mіЋ'n†нiХЦiХаrШЫФч?ЦЅщХJ^П’"§‹y/П7ЦqЧ“бuĘїй"хЕЃЂ8LС3LСЄr{=•Gщ ^чDЩ ТТ фЉ•AOщфљ(я“Šг‘ny*4КLьа‹SЬ9кИTKышшЊг’сЗЕб ‚8­Ч_еТѓ<ы› Э8Ч–qЮ464snlАeQ!3KX%бc“б ТКЕИБЯёГfr\цлъ7T:ГшзРЊнƒYЫѓ1эNЎФ-7Rт€…ю"I:ј,Ћ‚OЈiъЁтŠ *хSsќЯяш^ђf†lЇФ8=ТRDI<"“§ЙN}KЄЙПŠ3еЧлЮбPLНqїОАЏPЈш ›гВˆБbJQy\'н НJт-T˜yй&XацGщуъљёх~]іЗВВн€МЬ+a‹ ,ЏГц`в­Ј\Y[K‡@ѓ&Л^Djяh=!ш"Ÿ8д}|/єЩчг&а›э>%Ќ"і ‹И "8\….Gи2ЅА†ЃЮ’шJщy5s;Cѕќё_И w‰€"ЌXy ‰›@ZжTж–†о#mFБХєQœХ“Пф`gђчЈ,ЏAћЮџ‹цVšЉ­p6нѕ J’"Џй9’Xї~lzЉЛL ЗpNƒcІx*Aэ[‰КЮЙД<™Э‚0œP€(V‰<\˜“a­ŒE5—g‹cђЌŸаƒо‚]"$=ЩIсJz+/>wо{‰ВАФКїЧJ`щ“47Ѓ˜ЧЕМuHaДAO…†bаЕyЏDЂoV…г}&Ÿ`ƒ&ШХT|їьЖў )‚‰NEыйђnёR`€Ви=B yї†Є-щА)ž! cIƒ§щ8ЭvЗ"+їIДн ћђЧŽЎ’JxaiЎУpX5“BˆщЪfКћ6гј‘ж^˜aІІmЕнТ"Ќ˜DOртQЅDБ|yЖR’/‰– Kwэ@и{)Њ.г?ЄQZмн|HRщЏa#Sх)QЁх*Ъš$fЇ<X—N„~ЩЭŒqjџН„8ƒP@ l^і"г]EAщОP$}Н—Ууi!ШюЁћŒЎІЛ‡ЉФkžНž+CŸ/Ђћш6 пХ#+п 3Н(**2‰‘р9‚Љљ8mЊя?Л_мўј5фх9'Иx<ЌЌ&‹–я^кQ2Рh ZЁЫd|†/†ЌO,LZ/[c`к7,Жk›‚љ9’{щм.‹рУД„Иl(‘‹ію[b”iзcкw}f0LЯяСИ‹*у7–ИkV3эю!!+Щq˜Ч"ќW—‡П­МdPIƒр +хe:LЅўр%чЊХtУ s:c№5ƒT:ч њHC§ДhІM Nšž`ŸSВЮ^кWYњъƒhн’„ŸœРЭјВлтKtйв/ ќ Є| †]ЫJю^‘шіоBЖY4*ЌЬЦ—DhYМ(PЌ(‚L “сСO+_QQрМ$_?P!ЭgŒЎ dЄЈ`BжM;ЏгыcчЇА§A`яŸGЛСЅЅ8‘OшnTЅ;ЛMYгe…6‰ЁЭИ>—Т™g‡ŸжшiWiгЦ Ѓi:lБЊ{LR”2г­(N]Š' ‘ЄGVЁўэчFUsў‹?пŽФЊєЛƒTW!ТЫг)БъЪ)№ШNu_h8’k1@>.ЇCгАcўћwhxяЃ(6Бў §є‚iE Ф{т‹uD‚ж&.РP…OR .ьOrsёХфС&"g€7њйзC–хнa+ўfЪ+OП†ъS”Eыщ†.†AоGЅŒIo:‰7ЅРJз Š›ыIЊпк1мvлЧЬсцЗXў;Љ˜—”Ш{Ј”6K ,єX'о ‘c!Kf8PШлmј=cLАмb:"ДФО№|QFЕ*Ќy‡r}ё$Ћ]…‚Щ+$ўИи З:Ъ2Ў,хЂJ=IŒ­jUtѕУЇЌ)‚ Цџ цRљІArwЋъ'SDwHрс5Ž„яFcёч.dгЦxЋЧ­ъМђн“0ѓЋrщ:ВC#жOЅC@МЂp>А˜ХLѓ|[КF€юМK]і([щ%~К]NБbGЂ˜l*ДŸ™С›ж~4]&ћйb)ГFHIŠv{КєМŠчOI„ФхAM„хЩˆќnKзƒДYЮ‰2вUЃЙІгЧdижмLЦ{ѕцЛкPVU„щџ Ёhкјˆі)ъ+JosЃ“жЬ!ЯwR b^PЛЧ6NЃЫћ[дdyХ,щмS€ Њ1В…Р№кюpвˆІДBOŒlа‚f_RЫЩ{™xђєЈ ˜—wУJЁісв*Гя8Т‹;K:LЄyF(~ЂŠЅM ёъ…6ІСеѓrџEŸ™Dр%ЈЙRйBЭŸЂ„‹Б?кЋb^]АQ6KŠCуЙТьŠ п2zлžзТсc@ЋљvЗa„0тяFn[bЩћEЧ‘ЉDёяЕј’з"Ќ(@ $•тЦZр?о3YžЉQˆT†ƒŒŽlХбBЬьE—ЇlSрчЋWЈоŸ6†е1єНКtŠ4вЪВЋАчЊl`>Б|ЫNS„ŠХˆЌтHЖ&TAй~\Оњ?-7_ЕO›5ЁБŽND#Н,†"#ŸЄщ#7D(lчќуыnНџkI•хУБ9'А@Rо:zуN`љFњu=с‚ў‚ќ"ж`-Q-›Ќ›ъфuЩ ЯУя;ІѕкЗЛ^џухКr#L„/­Dv ‹D#s<<Ч9Ъ+ФCЫYQp;•2Ўs~ŠHR}™…M˜rU6џ~h“ЎTRg№x\Ќ,n|ї"%”МŠcMЛМ4ё )vˆђ)*цE*c6Сo"CУ"Т3#„oœуКŸј№Ј€Ђщ 7 ‹nГsг tљ1шаLОЂ2bjве$/ je]Ђ;”w˜–БЈвY№CJHщ“є(о“ НШm@,eXал:uЏ,D,ДŽHХTтЁ6•.OЅ€Њ\UўšЛ?Мvй<ќЫјWжќEєВJH\Zv†xM'сПPа>2ПЪyXНЏуц–сAоїё {OруНš‚­нОH[xЎ5C/БхЛ p”ЕДmy• ‹д3BѓЏHl*Ю#НjWИ›fьв#œ9*,Ь—‘\ š“,йCХДЕУž_a=аыьhT‘!Ї[ьh m5Щч‰4NНЪИ~•ТЉKѓнШeVјС'p1Н=Сlб$xхD =у›ЭОє.ёˆ'іŸ?ќ]qп›škŸќMCД8З$ЇЌрK†џШœlЖёйЬ"тжв:w‘юS5}›къšNК€ ,“сa ІЫj*ЬзЇ&ЕШцДь †hi Cw™)жTV:кMgўxќ3ћьќ7 e ŒwЊ1p0­2Ыš5ЙЌ Бш7ЩїoBеœ,xJвЃ!•њvН|д@d&UяЂ‚–LІ0Ў#кK€i!іјеƒ’@Љf \ьаЧWў’шџ˜EФ …i];лšњs№lPb|œ‰іц,нк MžUhCf…rk@Г4Ір}iЎ/)д-їВОH ЙУ@жю t5ZбцU›Tц. o˜^дŒЌ?pќ П>hЖѓ ; „ЯбУбЄкПЗ•к`‘ggЙ 0Б8Дя“ьOƒ› /ЬtвVЏ*ЈŠ,Ел3 ;ЂЉ мx IН‡/СбцёМ& йN‹љш Ъзхsо@wSŸЙ珘џћz™:пuhю.ЧнgњЮдџу,№7ќљ? џд™ŒПК IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/deny_16.png0000644000175000017500000000150611733011756022070 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<шIDATxкd“;hQ†џћ˜йнIЂYЭ’MD (D$h+6"V–6Ц€ЏBcicЃі‘b!DlJDQБA‰‰М–$›™lfчqч^Я$:ьйЙ;;ч;џЮНЬƒM›И|ёџezHEбaYpїЄa3[џўm:^[nсЮрмтї- ›оЫс+ЗЧƒИ+šMАЦєFIЃпЏcЁЖдhўљ ўЦƒ-€ЩGcх…wo'::ЛJк@љ>ВР‡і‚!‰a(f––№miс1ВьєЅ0ЩИЅЬПy}ПКЛg ­фф Аи;ГkZzрJў]UєW;Oq)Џџё|длоўЌsg…ы8†Іjz=€жI~„!‘4…а Rg0™ТЋЉйДiЬ^NЭ9ы Щ•ѕKЩІТˆЅ ИЪРГ )‘Є„“зuазUqt‘Њ!UeфS)ђšфžY€~MvШ– €сд4шкQЦЇкЪ ЩYE Г~Љš­ЬЈYœT@йћoY`ад-RЂЅЛЛWІы Jvr*ШŸ ж жъ0ѕ:Dк„ˆ *Ј‚э$}вЌhЄ?;ѓ#эс=де|Tйr fu…*Цаљ4Є+!)Iце9,Ы7Є'JОЪ„v˜ПМ|ЎƒЊХyˆ(‚$ЃyAњr,В@ЧwDоЬU-р2=СFЋ•’яїЇ —д,™+epIЎtЉb’K%ZЛХ"эQ'З№"4J—+љЙ…к‡8Љ)šГJр4:nrRЪ_AQ,@x%ЬК­H ошЩ'O?ц;БЅZžVйјŒ=vГX%6Иgзка…"> SŠ??08tэпУ„‘іжЋg7z ЂX%ЯлKЖЂ‡ШkEbNЖ„ІН§іё‡c7щѕј?€НFЛ*}FЉAг1:О}ŽWввѓОКmл^•їэ9vїо$Ні7щЇЩL_‡њIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/drag_object.png0000644000175000017500000000144211733011756023065 0ustar sylvestresylvestre‰PNG  IHDR$0yGиbKGDџџџ НЇ“ pHYs  вн~ќtIMEв +agЏIDATxœе™ПŠт@ЧП†)RЄйлƒШСVБ0 їrlБXхж78иgі 4Х•Љ‚Хr„МРТ.БX+!ЈЈ ),ЖsUтпе™ЩDМЄ F?™љ}?3‰(E!i‘ыUEєТ fЕњ”Cˆ ЅLХ TЦШь|џ5С@—€.0ёРDб \ ˜ @iз§гЌЂгyЅ‰| 摉ущС9УахёL“ІЉ0 šІb2Ѓн~†9 $вР”&аuѓљ aШ›2Чq0™ŒЧS4›M,—Х’˜Џe"0„ЈхЌe—єЬЙRЖJBTЎ#+J“‰:ЉЂ($=52Ю3žž~<Яƒeе№њњMS1ХИПџ…с№–UУ|>CЃёОпGЋѕ€^ЯEЛ§ШЌBT‘Ла4–Uƒу8љЙљ|†8žЂби§,Џ“˜WJ,—ŸАэњЮyЯѓЗЗпЅ8щ$P pwїQ4Рd2FЋѕаѕЭ][V УсЧx!') Iзы•Ду§§-эvнtН^ЅнЎ›. цk…Єg›њ’Хмд”&У–U˜fЕаzЊ˜šк0tŒF1lЛгЌЂзssP`уœ}ѓ“ }ИЌб}ПЯѓ№ђђQ4@6{$пяУЖы\{$!eХтЃ „uŠЙGЈl1‰њПd{(;‹ЗИ=TvќЙŸэїуяћ§t;тEт/єВ!ƒг45'уЯњˆT(іY}џ$9ќёsS,P:”‰б:ŽVgЊŒh;Е-ЮXMЋЖŠC–mРblZо”&aC йlВйlvГ{пžЛ ŒџЉgц›няћЮwЮљ§Юуr–eНмUwј\qА',ВЬeMЯк{Л+тЩБЇN^Г§9№™ 2\%A`f’x5 №TOЉ˜"•НшYU2С‹хќ %Иќœ#ћ‰}Ь2…2ЁG„O=BP%ЁxіRBFƒЭ ‚щ~*Š&ƒлvЕмћOЖёЧУ6:"˜š‰Ђš%v’=>№+уbбBоH[Qu˜Цх4=RŠъ<НОzЯUŽЗ{G‚ƒ91Ќцлпј†‰tœвŸЂ5EMсЋ[eВ…‚шњ{!AДлžўр8 9Z=‡_gzТъvбGˆёф$ЌBЭdЫŒЖL^vy):‡a˜єоJCI{iСFрђ)Кsx1їB%~ Tt’ыNtŒб7ЁœЩ!ёћВзk’Цt§ИG€3ydНƒр‡|ˆv^ы§ œЙЋiыfшФ]z Ј]NМSЮ’”шФе‚q–Й$х‡r2ЫššЂ"дќ<ГЦљ=ЩюьЎŠњŠЙ™eчyЭaBNљ‘ѓ&сИ€І*Б­snП5}S@ќˆ –—%„t†Œ2Bт&ЊІ‰Ц$9еYмPfЖ хЕ(­ьчzuЋŸ)ЊЊh)ыЌZ$…ѕю"D?ыПVRW$OІŠuEѓѓШCŠЛњж-ИrЈЊ%ў‰2ƒЊЩв ˆ4*њ5–‚rќ(ŒЪљЏКОTНэЦg8?…]Э,6•J<9uPИGЫŽЌхммw'†’tЛˆyљcnMїeїЗ:$~-ЏЌ\ŠйuєŽr`R5ЅЇ‰.rЄJфиЩWmzt њ*1—ЦСѕй…џ*~5џЃЗїзБКХЈ™WŽiBršЊjœђRлd`V“€ГА&aкiСМkТУ7‘ќЏТG–&`rн˜жМъ—ЁЩuЩD+RЎ  [ЯЩžЈPYџ=4ZУ7о§_HђђЉD.еŒј@|СG!РRп“љЛsJTjЂПњŸЯџ-РЧ!?a >IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/failover-cluster-group-neg_16.png0000644000175000017500000000143311733011756026317 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<НIDATxкЄS]HSa~ЖЭх6gЮ2K]+Ѓ\кd2]Ы Є Q‹XxSN%дA ”‰"е…‘$x†QЈ5bЪЬ?œЖЉљГœksѓш™юœЏуЪюГ^јјxпїyžяy?!џдA›Ќ-dyyТ#S8ž<%.HУc}#Т‘№o кJС?имMгЊ*м9i†ѕТ+М§ZŒО7’ПE—гn ѕјtSeXxžЯ§имЄБBД>АhQМvƒyёкЦn$хˆqЕыш#fм‹]ЧRу3”п6Ѓ&ї юЦqЫЏСЉяь†RАКС@d’Ы-Ў–ЦЦА "уцXY%ЌЎЦњш(‚ггШЋyБT I‚ЪЙ9œ0‘Bдмжfсb1јNјGFлкТЁœтxsиу<3љЕЕЩж –l‚‹,€ љ 2ШUK!анЯ#ЮЇ8ыъ0йоТВёH{ƒj5Œќ]’x?пЕGSСygA’Ш(ЋЦŠ­ТЩХ ˜Fѕ(ln†ЦdсИxГX.‡Сfƒ2=„D5Zt ьъ эid•Uђ ёЧR" ZЯ5ј†‡уZї#ЖНЅў~$d^ЗЛч A8ˆh8Š]п<и ?ˆPŠюо‚oh+*ёzЁЬЮ†JЇƒЇЗS`yЋ ъыС/„CКLЃнуЅLј•&'[f3h~Џ Š:;Ё­ЊЫ0Xs8pЙт™-Џ@x№%dъ,!ЛBxf‘(ПЪЊќ|ЄъѕиpЛaДлqЬh4ѓ|ћ.64Ьоo==H3@ АˆEс‰q€й‰}–žЇъоџрYRВ:4D&ьvўHю}я?y.фv—еJЂС Yi*l˜ њт­IщZЕs›Н‚НК_ KCњxв6дIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/user_25.png0000644000175000017500000000271611733011756022113 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<pIDATxкŒVklTUўЮНћьОЛлюnл-uiњВ•RZJiy‰!JЌ Ф€"QCŒ џљУЈ!…јŠAL@ў%Dˆиb+ˆ? Д tщћЕяїюНзЙ—‚@Ж“ЬЮЙїЬЬ7sцЬмe’$с~КuЫoоыМЛ,NжoїgЕэ5Њ^ЃDю/ФЇ~( _9BћЃВвјЦях5/nzРЇ Йi‰Pд№UEuMЅЙiSy›!ЅbШ\=нКtЊqhдД]ŒŒя^єYџoВђЙ_:f9р~Ётй=&ђРYѓMuѓтЊќ5;™ЊМа[РєfhЪЂ y=Ћ˜_Pг:ў}Яъ:й =єcnЉЄТ>bЩшzХmezЇˆMвљ СA D2:AУ0ИKQЁ2Х“т>й>Ÿ2ыИ4|єŽT1dРo4:Ќ@‚Еф!NВL9‹А­&Лк›mЧпЯЃˆчЬDQсожѕШ™!gr?л—ќюОіJ@ЩВКН{ŸkY—Xик)ЩtрЛR"%(ыЂх]RуЫ—"%Ћ.xюЗичЌТŸљЖFХ1иOЉ;тqЉЎ€Ÿoo$ŽЫзBјЕsBб>З“qчyѕ'•Ш,LД&вRtyЕ5kЕЈ>ЪЊ8sџЇѓ•Н“gЧyЖgJЙб2щчрѓ%ыНЯ\<8gЌ ХІЃbЪйжеЪH›‹+wћRЩDІ@8 ?БвOZ{K)'d„-жѓ ›пьKьxЛ™-ЊУЖГzЭjVюъQіZиYYf„УЊAэж””;сєX JЬ^њTї9e"5сžБкЊХ.y‚ЁБОK_ћы—ЙЁеpXзъDлЎЫЈЎ-„›f›‰‰Ј|Жš€DЧоЃКЙ€иyяH‹z"ЪУАЂЩ…P НŽУЖ ЅЈЏВ KbUc!†ІMАџu/ЬyМ2'ЉDрi21ABpи­” ф‰&иЕh‚п›„BНџŒЂЯ—F4&"‘”Pь4"#0xмF„b"є>•§ОЋгH„cёŠyњsђ]їЌь|žчЄCj­кждрцжЖцЃРF500„ЩщИ?‹PTФѕ5Ѓ_ GвQњѓёъ™Џў$љœ@fжVЛYмŸЮВMfƒшЄЂJc:-“t:pй,[ЃжЋЋВ}rp_љ™ gђŸѕWШ)РЂ`IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/domainname-ref_25.png0000644000175000017500000000201411733011756024006 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЎIDATxкЌU=HdWўюћ7;Ђ’ЪF‚„Є0кmБ І’e*! ‚ADТІбй€l,УV+kЋИBX‰J ЕвТ бЮТш˜бљ}37чœч›™ерЮА9№qю}їqПsю9їЛJkL,BсBœ$ј„n j q „„(С%фiТ5!EШпЗG‡™™™;L†a "‰РЖm(ЅфћЅR йl™LщtZцЗmjjJ I‘~ёЕкэˆј0J„,о5С6fЪџх//+™”ŠE™|§ъOФ\‰+ЎmдLъћџф|\х424О&єы(оь+$~б—IЬГpAЁxЎ…zLY:gр"]ч&РЂяW‘Цw)QГ.‚‹t Щывy"Ђ&ЬJАl%GъћСОF@RIуІi}oПџЙЂП“яЎJШk“6ЖадрТ‹8p][ W№ aб4ž§№LГ ОўKпдѕgЂ8:9;+№ЛЛЛ€§њњКŒŽŽdW ТšX†дСАПББЩЩIœŸŸc``ЧЧЧBРуЖЖ6дkœI“Ё‚nАœ “ўў~ёsssBР///coo===u“pJŸM>џQjђнrRŸД&"wvvъ‰‰ 777ЫZјO-ж$žЭf„аД+ї#Œ˜Г 3 }НІjQб5+ь”j[\\D__bБX%Ф/чsщ$XbŽBC№шZ8Ії 9ъ$рЇ‡&†ž<Съя+ъ?ŠUuhhшnDЄ|Жc’ь˜ˆEžЯ1DFlKбEUt1Y…ЈЁшЦWЩJЕœœ ‘H`{{ƒƒƒXZZ*Џ§ё R dI- $Л&mDœ >—dёОpо"988Рјј8Ы?mmmЁЋЋ ггг2я{ќš”UrRNVЋJUUе˜TLqT…dmm ЃЃЃШчя>pЉT ћћћ2ўъбУђїГГ3lnnтљo{*b5rЅ6ч7хѓˆQщЎююnœžžo­уШхуŒкллБКК* Р….KЪххЅэЮЮŽЊЉ…[[[хќxГ••9КййY‰4д3&~fyюКЎ<ЯЩф%цчпЈћdЅмТНННшшш@<ЧТТB™ 4~ыœ­Mрu“аидˆoŸ>еїо“––9cЮˆmllьw\їѓ<UB“ИЊКё:l—:э_лцэЬЕx1lIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cluster-neg_25.png0000644000175000017500000000275311733011756023366 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкЄ• lEЧџ3ЛЗwзЧѕA–ŠЅP@Z1ЈE "F@›01iР€@ „†jЅЁЄДD‰•&аšV"FЂ‰ `„bЂ‚)"m•xH$БЅGЁ`ЛіzНЧюŽпl-ЏžаФЙ|З{ГпЬoч{ќOBрqЃ2Uгe•SA‚Sa]ˆд~З NѓШ6l˜hє†Р&йBSФиЈЩXЂ =lˆФAЮп  ‡ЊаkЪ {У †)0:Ž#гЁ`”Т„йi s;Txюш№і›†_0u’EV$ї#ћъaШмБ Š)LДv`œKCЮТB8ВЇЂх@ZЏtBа‡˜hМE:AFi !Ъ#хIЃъƒЬЩS—›љ›ІЇL›FХпƒŸvУЄЄ†Lа7t —gу0(ЫЖз!JСЖ6Lž;чОќ-ž‹˜3ZEGРхA œPŽ˜Ї0ЎLIящџЁ5нS[‹+G"яхШ›?ОцуpP:љ–[БhkЉЉќфъешnjKЫ{Сы\kЧ,эІИ8fЄpМЪ‘A' › $EђєІMтB}§НЦSМДw/њl}8ќСFЪЌЯmЎг“Ѓ ъЯыжAЦ]џЉ6Р–?Щ<ѕQ1wй c@ВСу&•3чq™™Ф_n 7JŒ&bqх |aE=bфы3ђf~F=Вй ŸyњDЗй}аk„щ1OЕГNvіыzЁuіЁЅЂbXUЭлЗA—@\/УЉ5k†=~ЧЬ(+k лr2џ}Zg]пП8иƒЌ:?YМRђ!ў 4yХ ќЙLВёcэVјќО34•CжяВQЗP•вЩ–Ф’vВ I№8rVUсц…[1AБ ]hkи ПпO•D•H§3`0СЈœЉА ЮЁ—{„SњKбƒбяGћл‘>uђЋЋ Я#Y‰hм]ŽŽ?Ў…nP­пŽAC0ЇЪX†“БЈЧ]Хhю ‰Ш-‹ћѓmШ-н‹K– уШ‘a€lšЯ™3 Л7О…йIaфК5ЋЛ9Е“Œбw]:Hu )PЈ„юЎуˆЎОЮп Уіц6\?ч CЮwќ~‹оЋ!=“;‰ЬRf TR)jї ЦЛ№кЄ4Ќпљ тo ќRRђШpЩчвЯЕv7ЮњИд'KЧ$аЮџЈ”щў…^š.&ЌйžПpІДtиІYшеН`qeУ&ѓЂwќаЩЇSШј3Y№ЌЛz ЃIHIЕб01!Ѓ№ŒС† ущКЙЕЊЊШ‘–†iХХюk#йСЛкіь) ѕє`млЫО§fЫЪл]m-3h~YBvЄIЏOњKюxвI:@€+2‡Эa§_NњЯяdp9ЧZŽ5ў…Ф^сx‘уБї9бnŽѓ9Юх8“c6ЧvŽ-/ћxжћР‹s|дЧ[Юq:ЧNŽ­>огљwE˜b\ШёšѓюёљGоcђјŽм{рэсјЬIт}Ѓї=№Фчїn8SEР9>'^ь=TСЫЏча;P…ЂHЏcVwЏmЦ’yб‰ѓяk[НёЦ‘пЏz',БЪws\ о<ѓr{zЪ70ž5 Ыho тќГ8gYуФw~ъ_пxМ”w…xГaKлі1’6а?\C$DМ”†sWФёЁs’пy”уѓу'“?чИЦ0ќhн~Л)Ю6 ‰…В…нЫ8мW…^ЕёWŸž†лЎяB рђЯƒŸ~‡ ПФqо1Nюі{ћ0FЃЛкƒoУ+U,\sI+ўч­Ї V&&}х;р­ЮЬф мёУc8дЏO‰їс5IмљХYhNрЇзхях€ПтјЗ"ўці˜ЬЦЙЇ„qњТЄІ…‘Ў}ƒ5МєТ^ye6й`Щi1С!7ˆ?wмз:#`сЉQ\№Ё4wEPЁŸЦJњkтKSИъњ™\y2иŠјт‡ ќhлЮѕFн€|ˆ+мdйОuO:[5ЌfX^№‘6J–ƒQтѕеЈs“Ицѓs‹)8и[v/&OЬOеуxнx_Ны(т1+No$^+ЂЉ Ъ<пХгmX] ИцжSбвЂadЌцЮOрqНџž†wN6xВЎLКkbЬъ aЭЙM0C!W60šЏ#[ЊЁXЉЁŸГЛєКSрXћЭ(Ж2eYYёуЋтWWkuїwхA6obWjсВ8LЧ†IМ<ёЦђ5ф 5шz НК‰КЫХ[џЛ4Жь*rОвВћ?ПЖZ­MЬПоEž† Мe+ФsмљeЫ&Цˆ•+жPжыш-дqюЧ;]Мg_ЧКѕcЂ.&k5ѓКЉАЦ%Љ Д6АhA UЫFЕfbМXGпx§щ229хВНRХa^lоќl^фС'†™26'c~АZбдФŸч7f]МUЋЈsЂ“ёњвЄѓ:JФЋяhОŠгF]МŸ?9Ыr\<]ЏŸп ›<МЫ]У'№њЧuŽ М PХ‘‚ŽUk›`ѓМ_>3BЧ;ФДжNv€:щѕbёGфW˜LšHЉ(ъ‡…lGЦЊЮё}н‚E  цhЦоyl陇^ГЁJвйї^йx‚Hg,_ƒ!г™ХЊ…cФ;ъу•ъІ;1Ч•Zц„Бч,Жэ.LрЙэс =kЅИо#:fw‡ˆHФ:q~uтй>žїЇd:РРŽ?ф]тiЪR_Я8': Э%–“dЃŠ‘Bу%ƒЯu ]Fў%zлрЊL ‹'E!љ1OGгUT˜б”ŠEфfёyЎШѓ9™'uhЄфцс(ёŽљxeЯё!ХЌdoŒRІУba)х$žн*вЮм>:VF…И“ёФќLтй“xн’e/›“TUILх€Ž9Qжхў!†ч ‚}#Ed˜Ћ™'Ы•t|ВОђVы*=l"’м алљWwдrW~ЄХ-Mти‘cU49шЯъфт1d+5ЫЭ_œМ)I–]<‹xpПыXFоOUQУSZР›_ї˜„:!CМtЩЧГœу уZШŠC<УD4tKЃІ:…I’љ-иХБКЛ#ˆ­Л‹иМЩFЏ”цъYЈdVЧ3~rз!ої9.бtw„˜6J…То[Ой_ЇvQ,žоD'мйя`яX:ёъФЋd;Ю›Kс;@?Џ3ьт•‹…Нў%_чИH”Нз˜r=ћнљwšŸє–6РVриКXЦEJЅK&sпdќјѓ‰ ZgшООЙ„ЄЌ"-Ѓ(HЅDЂrЩЪ#A1д—…eKh‰sVІмшШlіёDП€пьт­†UТД‘x%тSЏx˜К?ф’ƒсžЂ‹Зbi“q}ž41П‹ЮKКЉѕтѓEЈ†…tЎь‘^йŸ_W|\…x§лs.оЪeMnДŒхЗNю';@(Й­ЫШўžзфцююWlœj@Е\EUї†`џ*ЫV0Џb№їjб‚$цЮˆ!—ЭНі–_>4IЮт/Џš†Г#ЎЎШя IS]Ц8ю„&GАЄ`tSЩЭ­yЇ&А`nŠ…тРЕ7џтaIХ3>~A ЇЭŒИЋ>К+ˆv-DЮЉт1O:@ЋЪHo-ћxIœНœ5ЭЪПйѓаф9Qня ЁлfcўьП сРfЉB­r AGAc-Œ`Џ†ёэТHhk‹съ+f#U00”~JKœ)rЬ ^ју|ўО"KИы+sд8Ёqƒ›5tIIФх *ЭЈЉ!<Тизš›ЃФ›хт =Ћ5.ё№.њё‘ М{Пq*RMSE*ЩЭ2:­$’JЙ#bЇj}­Š:I9жФ•—ЭDCTХўƒН?џЩ“Хљ?e/РPЙІD9ќOп?Š<иƒBФ6ъ.™иЬ'с?™YyV>va7fLСЊg6нјХч>ЃХЯ$Fuт"T^/1”Я;pTЧп~s?^#Эsы.3 <ЧeAЖ/iУ'.сЪaЩЮmОс OZKЌ8o=ПrСРH_јЇƒxўхQиФГФќHЦŽхIHБђsNmТ'/ŸгfG!YЙ7nќтњЋ9?W!Ž=х~§љќЙ ™у<њє ЖnЯ .Ъ Н<Н3Š%ЇЇ0NZ›5” cnўЪon4,”уцD˜ёBГ)‘я!о‡DYЛя‘<ѓТ0ўp G‚Ћ!QаоСYЫ[БdQmФЋVвПіэ—nЭГП^ŠѓЛл0э+оЃПсќ†Аg_…5Lн`[˜ѓkЦY+Zˆ`$dоxш‰]Зmк›м!)‘Ђш2‰уLщЖЖ8іђйZ–§jЭY‘/™ЎœMsˆR"„†ЊJЈU §;їєоwїCЧV#ГGљеВпТк'bя[ќо—Xк”lXAS4^‚ьDyƒЅ<|ьСўAЯї•PЧ'+ŒЏПобпžљп[њRЕю4ЛxдЂCx‚Œœ_@Б*}§ƒПњкwЖнЉFf IJИ87б MщŸ)Ѕ]O,ЛВRЉ_`9в9ХВЉъК) хїіdЖ~ыЛлW"33Вк(€uпxgŠэ(iяг+1FЏЊTЭкЖВ„“ц‹ЕьШXЁ‡cчп{эGYН}@жšѓ~иO8ѓёЖЎ;Ѓ#pnЌVЭЕ6”Ѕ\ЌDЁhЧв…žбёТЮ'žыљх†mЮ>%и–4?яd0Йф Н šjЭ=!$LпЃ†џњН6$%џЛxСIx–Sї‡ѕ.ЮœŒ'љš?“ц7ЯœŒ7сѕ=ім&.nN2іDЕaНXЧ?ТyUВxіЄ?YЂз]уmЮХ‰8—šК§Ћ€Ѕ6 ФЃi[};іЖЛ€{n`оЏЋ :эuD;JhhуR'и†GŒuЎЖЮІВвЯзYЏlF Œjзј<;ф’.іыНїу|ŸЏBт|dz@nR!w5ы4sгюUњ O^cW+!Dу^*НŸЊуЦ ‡ЧњOOдћ*г(]Ј4Hю iQ}ьК#лŠ}v}иz ЈЉ”ŽU/c„Ў—Н{Œo>ЦhаЎЄђˆM†п}ьY˜…ыXђb8Ѕц”э+ъ Й@m№VнЂБњ82ЬќЇ‚НРѓ§>4ХKQђиPI]Œ†Цр›‘œ7Rš‘ОVЮєeрД< +=њО зЄ=Іj-ˆЬб[ЏkВ†ujй7ЌР*кpTzaшVЄкH§2г4/ГJlMЪš ШШŠДЮžPЁб ЎР>ЎиШOкаж4„Ўv†Ч\УЫ JК@Ђa5F‚Щs V ЋьёGЫitPaЄŒђsЖш,‘<цЎ&/5Ц .wШэ6kŽ4гюИУcћ$KNz7(№ЪDР\‚Šє3m™к8sF…Wв‡E„к’0аЪ;\ЧUрН/……T:˜$DEnж­іZVњnp,p жіу0Џœ)ђЅPЅПХв šБшЮ$ТуŒ‚y@ь\Wv~кK%Щ4ˆвqэ­Рє@ŒЯГљ\лAСЪy„(DNБт % <ž СЩV•j_~3faаРsЁЉ•ЃЭ@‰0yЂк“Š&е8IЎ‰ гЛ74Жц­І‘ј^‚9j'9ЛLzфчЂL3J`цЌŽЬ“Ѕ‰Џќ—=і'Qйђ)45\Œ@5…ЮІn,]™ТМыhаtoЕ%?њž‚Гѕaи;A"ЫТ0.Оy0yvђќS sML‰ЁœgЌ'ь™†› Тp„ƒW„ƒКВ eœр>ХЬOЭ R‡ЧPяЉЁ<­ЙЄ<$MЧ­vЋиЦЖQ І$\GX,­rPrUнoч qLэV`—‚в› 0Ž1 Ze—ьœƒР Х}э№Z’цoGˆTа$ї˜qЬDdz№;—И”К<Ш&чM-nшоЊ‰I‹ч э`Э†дvŸ“ЋУф„хЙ-–Кі/,ОEAyH‚~ ЫyтH|7шзvaА0œ09B4Џb&14~гŽNЉў6Ък–IЛWoB™§…™Ё. rtG?#хдšPiМˆ.a|ќЃћœЫЯ@фLЉkЛќхђ€K†yrDˆbШјњ/тц†aЬНœуМЙYcћЁ+8 Л›ЋЫmxз-7Дхuюќ~G{1В9ўч,Љ ",•šц1О(ƒс€'ђD N(šœ'‰›МхhRЃй3~‘9>ђ_Љ6лІV‚MіUтЉь”Iz6jŽћУPрИeNЌЌѓЦѓТу$ФЊ Ђ "ДyЊ8GLТЉ;ЎFАŠ хџ~л>љ5gЬЦІo;ю`~ёд[V„#Иj9!wk^Йгоj†UH+з8вœАыA3ЪЃр =ш•ЭSЉцЫaEѕОуŠ"л-ЗТЩpЗˆЋVG]ƒ§Я§tJLkk{ИИЁfОёњnГЯ‚СniЃё.ЫsUЃ‹Д8тЮiЖi‡ь‚эВНXPY›ˆjOjШ1•ЋВOm}AТЫЏе№шРр‹^ИИННO‚ТsЂЫSЃ„ЃJpю'C˜yqлаXJGeзиКпп‹FIМЙ-Ў+ЂA”A1…-ГъЪU%ЪЙБyїк)@ЏЅ—Ы1™4\іQ ФпдNJJС mf !A~‹ЎYŒrƒ0жёŒ$)ЅФeЯ!doKтdgžr?ІЗ›Ўœu•ŸЈЇ†зD[ж!/wХЪEhAЧ4жњГДœ!!>љc…Aѓж0Фй$Щђ‰˜ч}ЁЩcфq_]ШcБђ FHQФ.ЪГЬEЄ“Є)IАwCЋ ]&%Ме7щ„:йЌБ=JЦ' Ž“˜˜я{{їЃ.Žž™ѕTўКxі*›шEэvtO-j3YєЉНœ€w[єѕТpЁўDmnџuIА—Д_"›y,M•7ђ:gIЃzЄSшИD‡7йBЮ‹ FrA™R9Ь№‹ёѓ,в:БYNG”EЩіЋS”ц&ЃідeА(пc&­кчІP‡gМ(т‘83ЪшЋСЬ{п­‘LОЗ Z`‘ѓWпі>7Чmя˜"Йі]mcЎS NWмFGЙ/tОpFŒ­јŒ h0[рtкЋэВќЖџэU Сј‹>.Є(ыћы^ш‹HR5/\]Сk3н‹xŸ—DgixQ%lGдТŒY§S:РR­›fЌшЄъ Ђ`{Е_8С&БˆР‰ДaЗˆЭЫ5^иhЃёBѕ…„,іv[D:8”]љixI@Z{Dљх^ЌF22K>'!I!$vhФъл~ ˆЈh9 XУff˜u~pЗwŽ КSЮѕфr‘D9Р()В7HД{ъH8&N‡цЧХЭk~›\фЈ{Ё‚ЄAcrSзЯІюEЦ3eПV уџ71‚Ћfнexїдй1B вГљ\?bКЙf ;ˆЭ=l-А?ŸХН}ЁAЬэnУты%Д­ђ6>ФvИОТ тйншфj&ЈѓC4Јчoћ\ьзђХ~шšh|Рoi B,—=Œ89aœчŽы–SГ RKДN5Ј /gI‰ІЧ)НяŸвСЄіxЎPИЌоP—„№ ЭЁјMˆŸ˜]/yЊьDTЙыJhё9Ћгі–и”(Ч—GОЌ’€tjjВє4Ь:шОа[iБ+dU=Х&юXЯUг“ФбH"пM’Iйƒ^Ю'КМћ…AљХœш˜\Хуи$Т^.ЪЏЄxђАмuJT.я*#д№*š“‡Іt€QПT|­š*dГЋmIOŽ.з<'ј—›гюžмDЙѓ@gЈMВ—"#vЄв[П12WКн§Сš`hЃт+ЪŸˆ0бхИљ_ѕіљмŠ N{˜ю>@ХЋТацžquЏeМœy)№Ји,1= qŒŸЕФ+hkYяd&щњ1 JHц,{zЧžzKЌЎЩ}WXG…‘ŽрWœgд§Нјщ™4Rя3Pй[GaНŽкА ћРхЛтLдЉ| vuH!$‰šЮ4g\ zф—лOVџ…Ззч.CpвŒќ–и§‘ƒт‰ ‘ZвЋЎЗ'n/Jž вTO|А,ЧNuюТљ7нЅ|і’вв9ж(jе ›Ёъ‰ЗпЖ!Bо ЎQFƒK•”4э,ЖП—к~Ј‹ PйTsѓ\(Тъ.БsƒŒHЩ-‹VСqЛAdшђљебўДч№ФœŸЁ˜ћ(?2 Љ%іRŒmп,ao0ыbЪпщ^ƒUбђ 5її|’tљЂŠуэЌpа2Г‚}Ќ&2Щ–ZzЕ—ь“bї= lКЪ[­om‡Х R2šЮlрТЪЈ+Ѕ– U'bХcЩkQщDs4Œ YГ5aЂЙѕDš_aў Аp{ьhуKˆЄ–@n%ЩэA\кюmŒžфуч!]Хjъ”КВvˆmZ€E=T~™Ёћ{„йв ўвsгt$7Ђ!zFВ :™зг—џуНYwЏтbNNмХy‚ымйEоїџР§Я_‰§Їўƒ;рџ0О€IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-udp_64.png0000644000175000017500000001570611733011756023371 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<hIDATxкф[ xTхЙўЮ9ГO2й’@й ИKmWЈ–ZЉŠ ЕRЕиж­^ы­ЫЅкZЕкКєкћ Ѕ WЎ傆-m’L2Щdіѕœћ~ч?“MBAМЕЯНЃџ3™3чќчџояћоя§ў3HšІбџч—щxN’$iаяОnЕЖуYЏщ.Мo њZlŒЏcw1ŽѕZkœЄЏŒг1nУcKa]1МG1МL Цžрљ‡eœЗљўЗю­ЩДfR8ІЉхЇбi…гя|јс‡Ÿ~ъЉЇbЦЉw5яќєю7~кsэеЇЭЃѓЫОљг‚‚ЧцњЎѓ"ГbІP,DююfтЯо—Щ8VЏбйУgъз9‹ГйlwiblЌcбвmY˜T“ƒЮсВgбј’ §ц0€9ЙРЋЦlфIjЖSYАœкЅі‰›7oЮРwiВ§бnкxd}ЯE3FœCэЖіIYYYёn|зъ ‹bЁЎH'эkЏЅЯм;ЉЅлMБTL__ћь†пг#—=vGwww>РџŽЇ &Ж=XƒzЬ9ж|ОZŸу•yЫяшъъ2чффќŒЃхhFЩ'–pE“QђЧК)‘Š“зыЭР"­§Я!RЙgШˆ,"+‘H˜8]y$ЕcђG}X4ЂWжњ]JшЖ?ЄеоИЎЃЃуПІNjъЧ;ЧеKОK~­{с›oОyšрЩР7k 4ы#Ž›ЦуqiфШ‘жщbТвC–%J&“ВЊЊ:_%е„>O[А…:ТmX|з`ёrџыxмўкЭдoОцбG§жО}ћєЕJђёЯмј5jдOŒ:9ZCnjш>B„ЁQЋV­ŠєyeVz†,ЫНщ‡TdЯД…ZЈ%иDO|ћYЊћEЕ> ЯУ!zщъeT‘_бяњ6?CUUUЗ.]КT7@Хщ9ђ3ѓiУТO{ц8xŸ›цNНІпѕ›7Pnn.“gжIаДН0>Ф ^‘ŽF˜&“в38Œ—Ъžѓ„ZЉйпЈƒЈС˜ЛяОћЗИц ŒI…с’?ЌМ~MПыWюYF•••пкДiSOGžЇчшŽvбšL&гЅ|§Ы‹_ЙіБK~Ъqцє\ПпЛ—ђѓѓЫpiцIг"Ј51„ЁJ’rєњЫ9oђщ!#™Щ‘IЮl$OИ uБ8ўј Їь˜2eЪэйJюВ+'}Пп›6аѕз_>Ю‘ _Яq5‚|WЉTЊ–Џ_А`СБ}Bщ„~з/лI `.Х›e=пњ–—žћРч13cФУ‰ y"-JљI“RњЙДFeыљ9учі›у“цTQQq Ејb]=sЈpФ€ы HykИљhШ_Z іœlQz‘ž=Њf0[LЯуHФдEд ž$ MХ!œЭ*ћТЁPШ†9ДH*д;‡"l ƒСsQі3[~;Ќ=ккs}IцPъььєыєqВєASПЙvиІЃЇзr k€зL F&ФATь‘’ЬВ/Ь2Ъ•„4žžу`ї^њеž{*iUђyИ_ЯљОз^P}!mнКu/гЧЩ0Р+щзДХUњћцыъtвь<ц~Qд'вsЄчlХ$їЬxЂ]о­ƒЎ1У’Iп?ŸnЗp>vŸ4–О^щГјОЧ9Ќћ~ъ*#їЗgђфЩ_3№мЃЭqЌ{q}xюб^Ns&=}С_hЫћл6Ќ\ЙђƒЏ€Ош*}МвїИ4 † ?ixЇффрkž;pŽц|>ё Џvа{qmяћнРз№ьSЈуŠѓшГПўёх—_ў 08тЋу€іX M(<Ћ€эш{<]ћ~ЖZ­1‹ХbхPјнQцЎ№DšћчВe1б…IіЮ1>*§цЌў iSSS{CCCѓуї>ЕцйgŸ]ƒCŸct­b(ѕЅYeУИщТЈddЩ0=Z{=bXј3д šіфРяŽEГ7ЗЏэw^uіhZБkѕСK.ЙЄB1ѕFџНџўFH]nП›г‚ЫhЮ‚Fи‡Ћ' ГѓАЎЄG 9Dscщ–-[nЌЉЉy,ЯJkСъЦWњyЏo˜ЫВ4шwЋ/к1‘їBЩРМлою9ЯaЪ jЧијœЖсОћю;е]њ;ЁіL( Дур—йP9!ДƒsЋЏРxёауD•с_А€СТЛоjzeжЇОњ3.g нuз][СЊbЄ@zpмyчтњР‘рўO?щXwЯ-›fѕ;чŒ!чqc=~ўљчЙŽwішcх+ˆ€šJь™лG>BcГ'Ёwя;2!@~ˆХ7|ьйљШ#Ќ4XXч€c]—•™#що1Oг‘<›QЦѕ-cŠм{ž"џsS€Ый+ц=ИpoСІЩœяatu‘ƒКЧђ,ХTfA~‡ж­оИщŠ+Ўј5.cЪ%lэ)ЎIџўvqGeN${gЎwЭŸзЌЛљц›ŸСЁнь§љлgr[|vСE3GЛ&ычц[‹щНWпћШи§rЛЪЧЛ):`‡жі_XXX8 ч ‡У1ЏзыЋЏЏo|юЙчV/_ОœvˆУŸIR/ѕѕF"‘YmmmЙБXЬrД{­_ПўГ‡zˆЏmРps9у^*§НлэОХуёLAƒ“Х5оМyK ;ПЬЖј— oєdƒЗХЬ†иˆч,вЗaТ<ŠБ5Хc02Hс16CЎ…яы4юIFЭчћ%џй|ѕFіЌЉdŠ…yIВf&щOчЪtцэйфЏП…vОtЉсJСЮ0kGЈБэOZ"ѕЂ4v\‹є“ЧР|рїŸ‰у€“6Вѕуд‹лЦ!д:wСojŠŸС“™SsЩd+!ХтІк;€МЌЎ+Hѕп@­ љфr>‡VsyŠфљЉx*У,+k/Oї3hЬ<љ'ЂWџ * ˜вŒxƒ#ъ—'СЏ№–xcузС›PЌжъяP–џs—SQ:лCЉФЧtpхъЎ-#ГТ[d™Њщх@RЕrŠ$ЏЁNŸ/’bбЁ5Tп#ЛЉ–В­mTœ‹šŠŒ #ЋR)n@ўрНmŽЊd"ЖЮAMЭgвиф]”ЈŸJл$ъм‚ш№нK‘РкљіrBљ -ьDЄ3 €W%›"™$iЕЖн@[ŠzšwOЃњf?™MoS^Щk4fB хVAŠF”…xsс_!њЪщtJЉRЄѓT7K";ТјƒчPМ)/s,XЉИ”ћ`а*ˆ^ f“†T”IR*РЂ•TW#uЁOёEŠ&b”awТл­R^ЇЬАJIpeЉ#ЇОЛQ `Ађ, žIСј…”u)хŒA“ц(T~1 /нNTpX!gŽBŽlБЫi’HА)РУ”(DВB…“2ЕIыNj‡]Rcг$ŸзD*УšЕJд—фLюїiљю>;2Ич–&(mD7L%šQATŒ{љH€јћMєaGˆЮŽуoМПЖЏƒnЙ šZ*rˆЊv‹ж‚ ‰.ЫkЈЯyO$}фЇfXШd™€Тy- ).Ђb›б7a5*„›Nќ) n‡б~wCNDCzиы^ŒХ…1œгV€0 z§ЄЕEпЫU+ЅкЅNцЉŸЏ™ГkхИщ0YИs”N\ CrчgXi.–}Z+вЖ3BЏюяЦ‡Б|7‹трsŒУЌ?ЪўтмлGєм Шћ•arйBЮ’ eйђ'Ј AŒqx; nеЋ†‘€Јжя†Ф‚дIёЙŸЛЃ$%4о/%9зDrY&ЏР’мДћєШћЋцЊбАœY"•N$8vЗбћлн4Оf(ХзЁ+ц;t`єd,rњ^НˆЈ|uяnšTщ]€ёBџGK0ш0<ЉМЊ‚сЗSЄ} %§з‘lЮ a1APЊQЮ­рSІ№z ЦF:pЃVф?@АжЃEОGTБ@N.uМе^†hpѕ>ЎTКљ–„їjЙГЁ“Д‚e”ђzŽіf4I{ј —&z№}ВиLДr\1Iй6”ї@я§‡кЅC4чЯF„№ёГq}'оWЦгМуЬ *‚jсБЖ—ŠЈ(З…ЪŠ#0вe}КСGuйvъэŸš(gŠ<‹LвOhтy4юVЌФСТ№€‚pC$э нd~koѓ‚„@*CЧ ч№>яБаЈ Y6Aˆ,ra!”8"2q<ЧFZWT‰6tW!cЦZєžm0Šс wаxrxO.ЁU0*–sx–тСИ*зЮЉ‰ъ:-L?jŽFф+фPЩѓ>~еєМoОœЕаEaѓї(7ѓb2GѓЉ4Зœ&жфгЈы`аPсmЩH†еЄm[FъЮC$yУ$Гap~ђ@7ЩУ;I=‘PhBJДј„БЦя(’аS 'ЛUp…нQЦд’f­U’нƒs@ "o7цм„T™Џ3ўвS ш66e/WУб„N„Яъ`­­ыу‹=b8Х™7sП'ѕ •нM-[FгЇ–ыЅ­`ТѕBL ‘ТЭ‹#ЮѕЖ DЋŸ ѕ“vшмSУœ*ОJ}x@цЇC9e№<™…І1’„Ш^а[%,Ь†ˆˆFQIт1Щю\k=ёIDаЛЄ%€D$й`моьГ†б­wЭц\gуоќ\ЬЧИЬ/&ЊСZо= И‡G:аpœф&wлХ”ь: +Ѓ3!|FїЊAфт"ПНŸ}ј4Љ @ЫYШ^ЖгlБ8YjќK мР№Єе,x€uРŸЙ vyšхh&WЮГдrјC2уX^ХрА‘aщyU4Ћщ0w?\$eНмн2~Јй‹3євєбža]4 ‘€ХcDіќа,’/EЫЯлЖ…"mчPеЙхŠЌщ_ >PУЂќе­DЉ<Ф-*I9BВІРйЊS!гy#Hžq-rшŽ(ЯP8( 6Г.0ЂHWШ8ŽцPWчљфt6‚dwа€]Є~ м-ˆГ^š•!ˆЯР>іŒoGсЪггŒBmTTTЄ #цh§AМYћ‹ŸTBOœеђФ,шr+šœ^-žˆЏёЂљН„v 0І’T`зŸц‹S –GЄLч.аhм ЕHЙ†љ„8тk­FmgƒйpЬЁ{‚C6œЬЁ–ŽыДb*•ЂіпRШВЕяоA?8–ь ЪщeBёqs^Г77Ђью€ ’mе?Гё7Ю,во!Ђ$ Rš|^ІUѕ—+lsЯFfшЗг[kM<ЋPаeш‚ РЃ™f1I$ЅG‚eJIи4щМВ—zЉk_ˆšзІ(Mр@~Y,‚ёЙ кЭщ_ N$Iѕ%IуЇгЩ•<иqQВЃmдfб JА<‹ЎdЃyё {‘ ш†ТЃМдеЋ ЫQС@’tН€lšQ aз.Ъ!ЯзВJd XW№1ГЭ‰€Ч­*‡-ІЁХI]ЮъЪ_ІЂp`6qf YeUTЃ TJ0œшЃ%ђь‘iдй/DA,Ÿ!в‰’d 3lFЩТgЄ,YEP˜ВXЄўOd’рУp ЊйЬш=о #9 Xх1 |sЫc>ЦоOЫяtŒ+мРб“Р\ш#К(dЊЧ4бјЄ„сЌўИ6Ÿ]ЌsqaЧМPYm[taE_СФЈ@ЙC-њDЙрТаŽ4ШРТЛJЁБщФбтЫшœ07ЧЉ ˆяЙB'нpУ‘ЧЈсњ;{ўGг‰Ж6‰œчЗШ;ŠŸЙfyЬРq40 ќ™Х’ž0rОљзыP‚CНбaЃ9їYч3@ЙтŒ›xНЂЖћA$лŸƒмЗqkи"BŸ#ЩdЉ ы Ю?,6У!Оrg™‰aQ%ЮUT5 НiбЗ„7йАtўЇA˜ №'$ЙНY‡RЄŽА Рƒ^1ЇЎХт‰?Ÿ3Ъ,ЖmЌœыЙџLЪsŒЂ 7J”ƒасіОjЄGEС4ЂГбЬДЂЮЛw‹s˜ш†Эr9ЂlF”vйХB10YД•ЁЭ@?fДЩŒИЊї*—h‡Г]Ю-[rL!Ф!Ÿ&56žСу ўлmєiйЬп1FзЈЇЇР~ЌхtYa†yСЕPМ—Н››JЋŠшды%*:]l|ФК„єeј]пш„7ГЁѓm0Јч%ќbїиŒ›ХђFqГмb&ЃіЧ!†BbŽ,08З#’вbЊ_*pЦЁj№ЅЄьмзС'‹ :^пвDГA„в“pТ9UњБ†чpцr˜4tF8блE2hеpо>–j2tSMЮЯ9˜HIЁЊѓС  OѓЎџР™[’A E–ФfслЊQб$БHъ: r>B…uВп-˜ŸsНРјТ‚x~Г™N^Џ†еRVN\6Ь)‡> ‘-s#ххTЛoЇќІn:“IžН"АС^aЈОе‚ Э#Œ‹уxЌSф<:ро,I б„я ВТTT№Ўжщ^"E"M @І„*вТЄЉЧм;€–ї;жCcСтї5њRЮk6–`qЇИrб#ыt•ЇƒР€pg˜V„dЭ’а]ХIЏ.ЈИdDЅ[ŸoŸ`ѕnУІ>?8Oя ББ:X‘–Q є'5)уW/’T(Z\Cп TsJSѓK?ЃѓoњrэЅЛЄ‰еoѕP,к‰f(:№ЇBђР ы™6~xэu“щW3Ћ”+В{Й€KоЫˆЦ­ Р.8ѓ§†і7 іgцчБz‰МЩКК–ПYН„ОУTїЊF-mћ бšЇ‘/KЪGHg(Ž6иf7Cй!42‡cТaјœ-Ђ‚#$нЮ2@Ќ!,ЅВˆ4д|LŸˆОЬ‚zsi­4э~’F],ЌдŽуё8{™Ујі3…Q№fЩy œмь€хUГ `Lљ@j(l<*BфЊ)іћС1)ъQ]Аœк6[W!_H­~Iзыa€‡QЃ.ƒ!ЙЉE…weˆlбЁ{F­3ѓЗ|ŒЫ#GCvЩE’ќь)MЁЮцБTЛъ Їw5Іb€xР-ЪхБЈЪэЏОћƒsПQM‹ўИ…ў=ЂЌœ тц!œу"ќ9 э‚ђ+Џ)Ѓ›vЕPхдRzз}Вtg/_ п7ТPПжмс‹К#SMђsž#ŸЃ—6яАRn9hКxFЈџыГШѓhЇиюFћˆ[ЖH §ЇevСЬHЩ•ьдјz%эXy5њFrЂЯŽХ„В9СoЋq=O<Qєђњ-?|Хn:/ЯA9Ј Пмы!;ЪлP-ъ™\6кШјqƒЯи%№ЋмoМ—gмѕWЩО+ЦVœ3$Л4џJ-pш*мl’ѕ™ѕ"œж<<л  w‰žŸ[lu : ,щa m5ѓu‰›ђПP1ёО`ФJЄЩvНФъ`йЌ?ёЧу'§књQуZв>иHў§Q’Ъ]&зшв*ŠЧ~ Н UMq‘sˆБ1Ѕoл ЂЭu`vF4%z|;šy*бфuFЗ`AЄо€xPLкƒ‹­~yxљСўO’оDЄ= яZ0ьћž r.@Ѓ‘Хš%›а›яchXЄ%уCАs9<•ђйTW{:54U‘IŸх(Ѕ<Їј{f')Џ№}rф­Gў4ЃjжЗѕœЎЕфШŸ@Jk!HneIЛЩщ•­џRАteoF & 0к43ŠК-ДЁЛьhщмuQГЗj*Bййѓ)г9кК*E^ђuдwщ{§B с_'Jчп ъЛЫ ЧрŠчd~&їљѕ? !šй;МэУIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface_16.png0000644000175000017500000000074011733011756023070 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<‚IDATxкЄS=KУP=ЉiФЄ„ю]D‹Иш"ˆЂЮ?@ьт TpQœЄˆCб_ [Ч*b—ъъpG%Х•1ib“4y&-1‰шаіРуСх{Я=ї]Š‚^@wKЬžžQъК2MУВХгсхPW=NC’Ѕv ЃiЊуъ EQ‚№WLыNЎш?1!Чˆё Еuзы tMѓ8фxіMсќYуu:@*•ЁщDё;Ъд›TM…i™(ЎёА–oЧ –ыСу9Сг €/YУ0`йpЮ>бЈ§iњРѕГЈVЊ­З†ТrЫHЪн…йљ9‹ХlRь˜oGˆeйЪ+"іwїЈѕT ЩEђQЋy-Є7З:њMšmІaž‚N1œ!ЮDЈ^зљ[€зCЊrъzIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/ruleset_64.png0000644000175000017500000000352511733011756022622 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<їIDATxкф[НЋEŸ3ЛЯ#Xh›вПA +ё?‹ъSё+ *јёЂX(! М $1…ZББQ "ЦТЮRБА№ЃPy&яэн9ЮЬžГ{vю~пЛ{яM&LfvяЮюžпљ>ГQеЕЧ}сv;ь题эZmV3ЖdћГ/ŸП^wQмr“їj3›Іw‡&кx„'ХЂоJ/On MЌoS›пюh“[КХ}\§йјqлЎмо[#‚U;(ЏC…љEЮюЪпндћuрзчїгє›]ƒ4‚vї?*(жКvbkdД.ˆŒшсђ…н1HЪ$8/v(Џƒ†г}Q‚&Ž'“€;eoy,Ю8яŽŽ;€Hcю“,Ч„HЂš(бє;ƒ†4G]Ї`;ЪЦ-MЂhВ‡3ёLИ"тM(ќЦP\ѓŽХœ&Ћ…Н™“6уOCЃ№,ZБE@ЬH˜pљтЫn Ѕ •У)U А ЂнHЕйœЮЬдЙгЇTšІ*I?Юf3?ђм“ЛШдюœыю˜ЧpюжЉ/јq:ˆrнƒЧ=ЄС2 ŽcЫKФ$АћPkб0Ѕв^<ћ^9МoруЁу^хlз;АлхyЖ…єуЬрHpтˆjэкшрјёЮюs%уWeЯ]ќЌв Жјс#'7ЁїqЎЗб–Ж> &‹ˆЌыѕLlёИBн,n’МiEй0‘(ўЂАw/ПЕg#6,…­x’<8Фž!..&ƒ%РБ†^‚Ч™ й\p/€yЃ эР*$…hЋy‚+у~BŒSхЁD}Щб§5Œй –ˆХrЦЇБe§—@™ъAЪЋp^pU`‚Œi`n!.ќ;;ЁUН$„“ѕTћ‚Чпh_ўчщDН§вЅ„‡“9—‰OUTхByўХеяV І‡ЪP†Чй^‘UЎ1tŸ­БФшt,PLИ$˜GIlЗ›РX„сnЛKРыч/g€T‡жuMжЮ'9іŸжEсЈ(ЊUAq~й€Д(ђuœШjaОЋbѓК'гB]Џ?{ъdЩ№БMі ЌњИvщѓЏМ;UФСqР$PEДдяК’з\ЖДh!#ШXЗЧ;fJГ$И4˜гb>–.бѕ#SBLX бYyaОЊ<Ў ч}Гп^MTкРxЮ\јДє[8AщzЃ–еО‘GiaьbЙ!ЃГ›Л1vЯа0_ДM$PіHлVЌМ/X9CRСЃ*М@^УЌ–сЫi*ЇќŒUФŽЈ”ИЬ†кАЛ#"­жћ—Ыю”Cd“эьфu~Э.v™"*‚нЇТ;ш%х§0хL%O‰…]tзЄ CЅ‚ы3UpX ]ЮE[Jq…ћ3jЙ[кУН€”СHOАЩЮЛ1•ЩЙЯˆЃ­.OЖsrйФ+ŠŠ@цžwлїЂПy:QЯ?x"ЗьlщЋм^з…ЩaћхПD„ц#Ч3z~д1HЌИ-Б&_—-+о_.)ЛСю‘`SZ[ЧеЎ Lž ]'аCaT{_џюw|"aёyŒќ&Qёс…&гuq”^у7guv­иs€ƒ„ш‘ zуe2ї†ТшauУрпУ~—#ј™ћяjдї+?фxУ_€c ‚xЕ9˜pcфFвЏšŠFеZz95`ѕXœ_N дQtл,Н'ЉЬ&’#Тфѕ@ШіЧ's,4•g"QЙё†Ю_јіo{>3‚@Ÿе9ЃІХ'vЅ:8AR]DЈц?›\L‘­qЁ” %ˆ$…Юk(ПЇ У^i4ЇЉŠ/№}€xсLЯQ!Й#Уљ;!‡Eч“SQјРYL€‘‹$GvЩJSQ<2Њ_Ui­$ Ћ№PЧ2(, Ъ”ГD ˆA|ЈU[`XUѕ О.j+њBdч“эжkЎьЉЇю;>ЗЉбіv0Й§z8\”{ш%5k ыK—XќВ&ЉшВfЅ!шэ_Лac(љ~ŸфhўцИH†"J|Њ’!]J†”H†Vр‡EOеe3U ‡Ь=yяі`QПіGšEБц5`ЪЁоFp}эптnpЩ‚R+!yŠPЪ  —-€§‡}Ъы“ЁмH‘rЂы№Сї‡ўќ–Юvq8’Цџі(ЈN”ж-ИYZo и} ОЉИх%  €ƒ›€ЦƒET`пvџGИтoq7­}ИЏ'пБ§ю #ќ/л/йўZгEџ 0п хfh›eIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/branch_25.png0000644000175000017500000000247111733011756022370 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<лIDATxк”V[lUўЮЬNwЗЛЅJЙД6)Ѕ ЉrЉABRМЄJэ‹$LєAш“М„ФKBуMPIŒђт"Ky RАЅкŠілЅ{™НЬхџ3ГЛЖuл“ќ{fЯ™љПџџОџ?3LЉЃДўвє…#дёУ<› тibbуыД“Ь˜NЋd,ŽСƒATt“ ~АjІŸJВчШ>ЫтЩ‹ЌDш7 С\чШЮЂcЧЋРрЩv •тH'8F_RXаЦFсSыЯsн“%lXЗoAЩ"X„,LŽУ™y‚цћгюБLЫАЊєLœяYЧгТ&fЯD:fЙ`1'gF,Ћйc3язЪ‹k…Н-bšчŒё{џfвN,i ЭN›Ша%‹eЎcXTБЂТЕoR@p †ЛГ9qžѓеЏEЊЃwEQаsjh$Е—›"4Ћ№ПuPмшЭ ”ЇEЂ ‰ш;H'ŒЄ Sч0‰w;юЇџRZuхKМ?ŸОи §n~M R,‘AYЕEĘVке„ЇЇGЉhzсDRоАVКЄc—І,UёŒX€unИNЫˆМ~Й‚цM^D&mtєШј•ƒЗђ ЏШJŠgDз)YТ…ˆIлфиNлŽsаuM)Уі-^T”(D%Ч—пЧ‰Jвќњ9ю! ђdЮeРXТщ№B٘“аЪ‚ UKT—Ј(жќŠ›сБг:&Fщyž< Аќ8УˆKз†ŠG1\mЕ)Kъ ѓ,uўРб$<ƒлшџoN“]ЫФдќЬlЊ рЋs zЛoЪЅoЈ„-к:Dќf41Ш—P3ф ѕTUЎ‘ЉŒN@™ЁЩН‡+ŸюjlёOKќЦ€ўц{‡ящНў@вp‘<М&зЅO‘!Ъћš-З„лМЉH’шH&У„щ:œвсЙёэйахKзfЅ4ФnЪТp6 HќtdК.%Ђ‘dЏЂ€ЂСi:9d5=М?тєƒ4AНaнбЭхy.–п/•4y(d"[Тi}Ц‘Њ­С@ЈЊцfЂN‰џаЏ ЊдiюWиˆЃƒ””'ІœТfbњ+§5А“Ї‰юjЅQOию^Х‡лœ Ллш„=‘Ѓn,cљ{лЛzcЃ1ДЌюЯЁ›ЯњМžwUЏZНЊВ убqŒХЦœѓ‰л ЁЮ4| /ИЁ*њuY­ЪЫkпљž9НДДЦђŸрl=АmнVМДЙЅј+vm­NХЩШGЯZ№/ѕТв5y+Ь(›пщ‹цЂpux—šZН›:.tЕуыСЃ0L *Ќ-ЎЃђfN‰—mї 9–ІцЄwЩdqЛ`‰Es}§:${ДЇMГъ аљKОИј9RFЭkір!Ѕ &ѕуН д‚ xxхХ;ЧwЭчŸ;…“Ї.ѕ№ +iItпјЗ‚zћъпЦšh‚О…PЕ -Н‡fЪœA “—o['l…‡U}ќж>=зŠ3?ТЇљХБ}ЧїP wЬщ‘œп SwScЎвўГaњс1VУЖu­šџ§Шp-еgN-сџ™§{Щ,U4лў\Aў`)ŽpЈИ>5ЮIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address6-ref_25.png0000644000175000017500000000211111733011756023407 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ыIDATxкЄU_h“W?їћ“|Y“VHWлAYР=эƒЌЖтЈT}QФaЋ-’#{иЦ ‚> К>е‡>И>hБОЌ,ЦRАж,‚("“V J[з€YЄД_“Ќљл\я=їћкD›імояžгžпяќЮЙЗ„R кQѕQG€ЭЇ‚6/LfŸъdћЖs@№€8Вљџѕk;KџH*РьщUиЬќ№§Љ“~" ^П‰п–&№юГg„ШbI|gчШђS˜жћуcU};%.Р&™f"BL 2 œ)Y‘2ЊюŠх2ЙтГхЧ№<ѕˆ}м'ўџўќєч­@S “Ѕ)2PА[§*ь;vюwцza?BuUС‡ђћ8Ч‰SЬiыJˆQ…RR ГЂ’‡зй9И§d,ЪŽ“lЭfƒT_‰f‘5 В&ШYЎЄ(х!SL—м Q\€7‘ъ%vЬšўЊЯ]чMgЄ(Ќ&Њf-ƒм|9ФфЁLВjЈћCЦ"“dйжь]ўaЧZ‘(8` „‹&лйR…tЊ&€ХЦoџ\Ф–ѓт Ќ- Џ†ЖпкгЛ4hЙеaLtˆ ЌL!d6ІF N@њ_ЧXz1мЫF§ƒzЂh‚5~л сге ~щг/ШМ™А!ЩŠ!‘Œ‰ДbАЧž2 cŒЙЯFАбМDЖ–ММ'Шž%р‰Œўpп9^L›H.Нs—,ƒ№ФŠQ &зŒKdЃт’Зпdiѕ=|хл™$мjmihEш№LЈ,vЛчN+‚dѕT№ее$˜YJ–МX(ЬНшлжЧу+ Љ`Љ<—Ч/ђ­ѕ“Я(TзQ<ѕLTŒ)lbАаЭў‰Х_˜љи‹l;р :)вЂJTC~ќЙ/]УУУL&Ы|ZіBTŠm8#щt:;;+6ђЇCПђ-Дђ†„bЅqЎ#ЂuІѓѓѓ022§§§авв‚пт.‘5Й\~}\їІ{ь{‚њђP)І˜ЩЇЇЇСчѓA$Y ‡УаддННН№1† уууаееЙ\юН_рН™ššЊ˜€n’œЎџџкмм бh6› ъыыБЂЦЦFрt:п•Ћэ›†§“Ѕ}0яЩF1ёxЯ“чс{•boIЂgЧ›П*IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/import_64_1.png0000644000175000017500000001470311733011756022671 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бх IDATxкд[iŒХўЊЛчX{wэ]яb›А˘Уи€ИqˆС„+&Й "D(BБ‚Є@Ž?(B ‚  HБ љ pX7 Gb;С`ˆУi{Ны™{КЋђЊК{ЖІЇgІчиzєTег=нѕОїНЃЊ{˜ѕЖ‹nxpИдаK…E+>-лєŸ6ЈvјЪGйфЕK:К–бш`Љџs/ђЉR^nІi)IнuшєZЌЮў§!˜Љњўp‰‚Сш‹Р§„жњ}ю&Дяѕ§ зYu^|šЭ *Ъ_НDhш#mWъоЬ&Мz?‹WЩз+ц€ MXwœ@ЈOŒ+BXL“hІш] WЈ?(оФЏCcCŒŒъY hЄ|pЧCЈБl0€˜АkпL,YйTё(єmŒз|—ПНдЪ‚HјDEея|ЎUЂї=соїъ<џЗої•х.mN№аЋwс7_О<ж‚t=дЃМ+ЂbqG„К(ет_žНw>ѕ ;Ж–Ў#šоП'.р„ЄГ*&а7UгWя8ДЖQЩъ[ыЖ-?С}/пQ•я›Хœzo-гЃЛp RžŠ ]ЋsЎЙGиЬЎ‰хЫN 7?r5žиzOе9œзfŽšRY4П~G а+єUŸђ‹rБŒRК;фЅса}m2$]з.cЯьюџЕCЏЛF№зЧоИ›žЙNэ/Р—Ž;ЋFV#WЮ’Ь~еЎ^‰Ё Я8э“л_Дс4PЉ|б.`Ж8‹T.…нэ—ДP jY –ЏB ъмївMјы+ПRЛЋ'VbэЊ“q8MrQкГLSYˆQО”­IЎ Œ ѓ'Ћ„OЁТ"ЭZЙЌMЉos[YГЅ4lQBЖlЖW лКџ‡•Ё!9šђ›žйˆЇЖmR>>0œРšUЧтѓcЇЂрфsВ0 “ љ1дћВ5д>kёЁЌД8nР’Ÿ/ Oю•.Я`І8…щќfrћ[€ћ4š’RR™—№‡П]Ž—w> іЧЦFqђЧcщР2LwЋѓЄяKЊTњЩЇЯ†!Сp‘-S @ЕQ•—з“О.(“8”BЪЂˆЯaЖœЦЌBЦI![ЪЖЯ€FжїЗ‚Сm}“внsш‹ѕaс2`щL CƒHЅЇ‰цIѕ%2јХˆі1ъЧŒИb‹ЅZSБР”CT%ЋrQ фюkŽАЉp"wŠdѕЌ ЌЉтŒ’}…=˜)э%&Є.Z/„^ЛјЖt•ЩяСO^‚gЖbaВ#c1,Xl‘E8оNoWЪJху^ѓкЄе‡8)э‹+`$.#LхЬEAЙ‡юѓъЃќНЌЂ|С) C>/Kъ§ХiъЇ0]к‡Д&ЗЫP Ж;d@0Ч{§}™їpыучa*§.,ЫФрИ 6р $LВN ™т~Ѕ”Tоd1ьтЪђ $ ŠRфї&Г”тђ7в hі--.ИAQQŸDЅ8В~СЩSАЫ2ќR*гdЉ_рy”шSvкœ е[р№о-ЎЇвv'Ь8УаЁ%ˆ@NШ’˜ЮI ВЁC-‰ ~–Wж)kSŸ*A‹fC†j-Яђ† }LХˆкршЈРGyž\Рv\”x‘\!Oю˜Ї8PVћф ЅEЮк`€єs›‰+ЮИЗ?qВDЛЉРШb dЪBs'Fœ”pт†RЄШI1b увпНрЇЮ5ђ#П3МщF-- 7тл‚CiЯЎ+Ш>СЂ>мpшї'l9™3Z@ЦGдTwСm|ЩIИ~УгТy˜ЮО‡НлMpGМ_TосjрŽ7зТ“Jrm G1G2Ц}?‰)шќєЈЙŸ7нv<7pѓ€зЇ ЪЫЩЌœ™)ИЬ6_а=ЙЈ/Ѓƒ+qнW&Б|ёjАћ_JГtKЈ…“Zb2Е4‹h %†ЩН}ЧВL[‰c5Гл(*)“8RэГЂ:Ющ<ШпƒЎЇюЁЎэог—–№c€#+яЫтcјёњILŒœЄJцн[ фІф#}_yПe #F'б  Z  Ѕ€ЛяЈcмД•‚ RœЋжDЖ‚Ž :Gž/ лСЛŽЏИФш„­,GїХ‡Аём-XЕќ,„m&вU–0,—’rPaVщЄYЮє€SЧ}ршИiz§Њы2OМыЉуў9Ђ}ZгшУїЯ|'ЎИX]cя LПcx { ЈVSBК„BЬУ=ЦЄRўОЩ* Щ>ѓЎчŠj€њъкf›ЫтМЭ‰ЃДvщЉw#†ёь›wbп[ NЩРђcИ6Џ)К™ ŠkОЌсЃRљ­бkќэТ“~‡…‰<ёЯ›А—^f8hS њюи…ІЗРЖ-єb›7ЪYGпˆЏЏЙCхѓє‡ Лž3•Ђ†Ÿ dІ0\+ѕ@љёжёюмuЭ!W`A|ї<В{Kxч +NЗKК•‚!k{­ЪЛљ’Ю^{шUwъ›9aTVLЊЖxу^Ћ tQŽ<ш|ЊAмъG~šaчЄ…rоЕМ\6ŒюнЗЂЄbSLkЫ:}J”ƒGзQ†и‚фRgокbЁFЅ0ъж}чъŸ.ен–х‹Ч•gNЊТI2рm!;ХЊйщ=*љСr­ЖЖ§ѓ У СЮњ;–.: vб!§ОJНvЎ?—Ž]х;`ўЄ?Б”bТ*з‚SћіЄйД6oе|хУшIаl‹[CјЮicѓ‹—bЧЧW-Фtc{eSЌГ:`>р‹EЅѓ%_иŒу&.ыzьЪKR=йЈH:џФ?"I“ЉпКН'їэрeщљлО|єoqјвѕ=Йo$X АшХ61zFG а}л%ЎхРxYЕOnKЉBЂБ "Ч*ЧЌыа’Љw_Ы­<^А5…Ят–Lџї `Y{ ˆх>>НoцЭv^|ж—c–ce?:­бyџ`Orвб7~ IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-custom_64.png0000644000175000017500000001466711733011756024120 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<YIDATxкь[ ”Tе™ўялjяъЅzЁЁ[ЖйDQ$*jŒ{0FŽKЧИcs’™‰K2Ч$fЂ™$cіe&‰QtLp  ‚2(ВЩЊlнMя{uuuэo›яЗi'rЂф$VŸKUНzїнћoпџ§џ{зuщяљЅапљы#ќН+@ћ ]Ѓ #PThFžBvт!xcчŒХшЧшХШ§?stŒ(F=FЃЇ8Ч}9ЈXиqч`|уdŒmaМˆ‘сН1‡…ƒqЦйEaіb<Б#u”9МЧZŒ+1>qbqЮГХЕxчX…טи‚Ї`|ЅЙЧКrу>“š{lЊŠ*tЦIMЌД“ЩdОU^^оrˆUBxћ,ЦЭыо.ЬnъЖЉoШІвАBs&ъ4mЌѓЈmл?…B›™(*їЖ7›ЬГоj5Љ#юP4(hЦ :6‰V˜Іљгp8ќТБzРБ(€-ПШВнЅЫпШглэ–wp0хPkŸ кДјЬнqi†чUVVЎЦlХ;zЮƒKVg(oI;ї&jщ•s.šуЃ{Ў Svx`ц<‡9*ЮњвPЦљо’еYJЛdУЮXЇ­пІvŒЙ“uњіg"deњ.ЏЉЉљУˆї|а ри}ќ/f.L;daS-М Рцr&aЃ.]6зG_НМ№<„YŒ5bі}џв)WќLoЕYДЛУЂTЮЅ‘-œ?г o/ЖжФbБK1'ˆ9}џіtŠ4Ј<ыющДМu2yыB!6бГ|єЭOхWWUU]V ‡їЅхЌцўnћЂža,iіѕ8Дљ€M]I—ВŽ WЄ ­иnROЖєВЅK—^hYжэЯnЮ“хт7MPSŸC;: ˆ-Hбя|kіXд‘Ž.|ъЉЇ.Тœkжэ-0Т‘‹uоюВigЇMЩ‘Х Ї*Єљzљm“6ЖGЯ]П~§­Ч‚iЧЂ€kжbc ДnЙжwp义ƒC7фћГohъдЉ7oiБ §ІT*uеІf9g(ыR{Т!хˆ9#ыЌи–ЇкккыБЗ№‡‘ЇД'\JС%Лр6ЌcјХQO| @wѓхГ‡’щњžTФЏ”–'žstнящuЈl~йL( вš(#…[Г№тшыьыwЉЌЌlJ1M&>HpКйQUOkАhJаŒбhzЯž­ееељ` ка›‚трЊa1ъœН{їv ƒX•бŠГ8Фиkx1JВ›y‚F--ЭЬ?|t0Кќіœ“4ШЩXєС’Ц(у“Г zєбG_NЇгO/hа(Aвˆ{Žнбц\8CЇхЫ—ЏZ~Ц$н['уˆQЯчqЩЩ­XБb§ћ №к„2{щќЩpžQт˜Чгuъo\ПяЁ‡ZГrхЪ_9Ч ёU 9pi р;ЪœsІh”яzГљС\uяНї>М№Dъ+т„ЈGŸsюTB‰ЭЭwоyчSила‡Q 8x§ь+чћшКy†gнїЮ`ИўtƒюњИ–-[ЖфІёюЛяюЩe3Зэ~šSЏy љŸwљ,ƒюОРOЯ>ћ,чѓ§ЋV­В-ѓsпОЬOkаН8rЮй'ъєЅ…>zц™gžЧœнE&љС1СC9їЦ'yяЫњj>ѓJГC;Ћ3Њ:g‚B{оxqыwОѓGжЎ]ћGœк<ТѓЛККnєљ|_маW2чЕ›к†\jˆ)tщI*um{iзу?ОtЩ’%OтдЦ‘œоккњIУ0Ом˜‹-\еh{€зtў$•дюMЭ,ќ<№[ЦЯcсоЩю8ЪЫ‡xНdчЮџгнн}рOњгъ[oНѕ›8ОЃю( Ф oоМљыэээ[“Щdbыж­ЛюКыЎŸтјE0ќХѓ\ЗnнmmmR‡БоžЂаL~јїCчМ™ŽйŽ#ць%Eˆ’йї(RДтљбb”+ІЏ4†§sТХ9ўтœЁЂл[J-0Šўъ^X9ќЗи?ќЈ%іQKьУxuП~„кБlи5А9ˆяРA ˜™ЋPэ\ƒ‚5>aбыџ­а‚/•RВхѓДmЩфd*Що™( 3юjыљkкˆщ3К(fXTCЅr5Шњ#DЫWš•#Jёѕ+ѓЏФ–з@t$еР№•“ц?ŸK=Ѕс'_ЩЇЩIоDн­1ЪeЄ№м№‰z›”[№ѕѓЎЂ–syь ЋђѕtIZm ‰(‡ФbкђГщxЗфђЭ‚@mЏРšШfОЩWQ4y+х;ыЉz^‚т}п#л|і/]LCЛыPr§+уŽŠЊ(Тqы)k§Х{“џ„OSуkѓЈЅ'Om7•њzЈІ,JЩРУИƒrDІ7ЫsFБ†Спš‚доБ€І[w’йr*Х7 Šo Š'ОJйсhлŠЙвTW+‚…иЖk‘№ЋBb uїмDAќ9E;OЇ–Ž$щк ЊЈ]FгfuQљDА вh72ŽПb>йЮПS6>“f,Ј zљ—рРГЉ"2j*}T3–+(аЋ8Ќ-шšЇ Q!aЃМŒч&PSЫЭ4и AГ*хЬ<…!XЛ›въrŠdВРЯ,„Žbp\z…ЄТqw6(Z@ЉТХTНœЪhЮb•ъ/Х&aЅщ[ˆ*›U •Љ,ХU†‰ir)&C€G!QAј( e,…њRфйфкNўt‘аШ`јЂЯyћ`=BфУОЭэ˜№Юžё—ШPъu(sОJc%TЂ”PЮЭп:дЗc№еBо<Ы5СЇ‡”evЗѓyuІшвЪUвЪJў1KzJЦABМ+ј+єwТЪЛY С7а˜šjЊ9…hъmгэDГџ їШЯ™.^дFЙДчіžѓ) ЧДзЅ$ЩэNЩЅ˜БкN@Ф“ѓмо–[\НtЗRаšЩаЌ#ГТŸ•|– лсы‚VшДД“&Ћ`=™э/xТ;и‹tYYчiнжJјŠ~з0tG{їЕЗќˆш—7!ю—f(4f…jSЉЦ„˜ФЧ”РX€ЕГО Ÿeк Среž№C(5R5г’пћё}(GћQ Ѕ\#Ѕ.ТвжњѓГЋžЛЮЩeќŠЪPz?! tAЙ~sUS_лЩqzСмя\m™Љ‹еЇЏ9 %ИŠЃ:gКэG|†іdЊ=wK+ЊXъŒмэ Ё˜Ћ†vУb=KЊЉКМ‹ъjВ<ь юкв) №Сђ№ чšШvZтGхIP”ЇєтwОЫТS_qд•ЫашKzиЁд8Ш9b‚гжq-uїэvі%ё^ риїnт™њх”sД’ уы@М2$.du hЁžЖ\ЏuЁ}`%hP0@ˆћ…Л&?(~тыг›(bo=И€щЪtІ*‹H_ІйTаŒ/`'(щmxPсю™эD{—5О&‰0Aq5UDуІЁ(Цћ$МчЗG 3D§™ф g$Qbˆрx™ŸмСœškšˆˆ™ю3щ%џh )!ъя“D№„ŒчTCфЙяЇрЯ‚+КИО›—жT‚пYНЮAsв€GќЮi^BVТЎ?—z0К0ј‰]ЮЇK(Гщ*\Jz.FcЫыiіМMЙ“жХh}žмЭOГ­‘€XaС`|kп)“тЄL=ž0о„шJHaeqА0НP`С)р“X№eеi•ЛЩѕэV­Ёб1 ""дйнG…§yJЩ“’R/ЦбNƒ{ЊxQFž"lЄVХ'шU?п€^№“•*PќPVЫ<Ѓ­к’€Ш,% С‹ќ№ˆ\1]Ш‹@hoъьТƒV’kŽЎ85(ЖюЗ†1NŽЎPNtОP?m,МЌжбё7И?Ey˜Co,ŽСвЦDђ;M№ ФIуJpuiм И —в„СиXy?Qљдwи rп;ˆ^§ 9qЏPЂŒ.7†Шb„˜bN_rEKњt:xЗ•ргeBКmХ9б`•”§‚Кš_%Ч*ЦЎŽлq~ЏЮ‹”ˆB“#T"J(щ&НшY™ Т^K Ч›m6S4фzнлЌ“+Ђ16Ђ‚ АlЊ)кОqю‚ ”эYHЯT1ЋQšнёРЩШєзДЉВ‘лT№4‰E60л [œз@Ъй7 Ц›ˆо†—фŠ™”Xg^PєЂ.hБ‚ŠЧ2Й2ŒŸOЁPРj+мgtФѓёћmУY4kЮ48ч3ёaи˜$ГaPЅx8р$\вЧЋоgk cЄїЫŸ…wЬlЗ(8Юїƒ+š;—ћPфМУХЭЌДošпуДf0РМCЂ2р1>7Q V*mэмл]šё9•в]‚ВџС’ё\_1ЗГР,8ЎснЖіCМŒUF]§7К54VфџAicгЁ=ФУдп“œрЏг(ЂD(ыfzEOК‡ ,в <{ Н,шžyх)T:+„аu<ќђpРУ!`„ЂЫќЦяЂжYpУАЗœзVseПд)К.cРрNXшrуYлѓcnmF›s^Царž4uЌБiœ ˆTiё9 tIђи†-ьР мr QbэяПФъяљGАЭъб™`Йs5ПЅн4@ЯЁМ+я4рxiŽ-Ыn^ynYjvdŽ9—Юt&и .ЁƒSљо„[p=Ž`У•ƒTђЕ-Л•7м>‡жпGДэЛˆЯfЩюМДТŠ€еLwѓ2нКДf@#qњ9Ў8yq)е[Iўrƒ†A‚КdкдJљ"цлШvБNрwгkyC™ OА„Єзбž—UcЊЋŸ~5oНЙaЇє(ќ™јѓR„їPVLѓцUЬз{ѓ=юо=.Ѓ=T1FМZR %,Q9Ї˜tЭцU‚^y#OO}ŸЈsЕtЏЖ/‚ kŽЋ5e Њ„[ћeьВх‚ v r§<ЉR@pЂЕї ънЅа”Грт№‚a |iXjŸ9yиіKzЬ–/…‡јрEHсœžJЃ‚`Ы6 Iq…(•жЗ „аЌЄ&Фі˜я5ў—1мžr}'kТ”,Шsџ,ПЫЬЦ• чn7+йЂ1^ЄV­ЯФp]Я‚3ћум\ѓ1№€` `?4х{я`y=АKЕџwИЮТtœмl2!=ЈXUР§ТPь ”RUl:Б7Ѕ9eГSт–…œбгрАђKЋЬОЉІ!F’ТsњуWщi!ЪєцЩИЅ)ЅњOе€ ОлФ%0ЧМ€ѕ­ny}Ћп‘ЧTсЩw­э[†XЇz…фиgžЯЪЃF <0 s{(ПхЧ2c0тЯјSQфї вѕй“4C†‚Ч+яŽ5…ƒђїW–Іє*fАЕ!›ЦOlUЖfп6ўдБ`>J:2їГ ;NАЪGN%7WlOx–AЏ†№ЬњќL‹eЗ…УСSZЭЊfщbaГ6сžZ@eС)4ыfAe BмЁaы;Х`ЏЈ<ш,3нШѓ;х9 t'œ-щђ0€В^2Œк ДFВ#VL Bfшщ“ ˜/–ЩУйeІ`ЈO)Џ{lєj 0œЉs5 ян b…sVСCxядˆт‘ІФ zо Э–kfЗKсёў'ьiЮэQрзЖњ;ЉЁОšf~VPѕ|йјрv8S_VП{NXГ<пjpž™”эsюрђУmшЪ!М^,i@гiy(0Ё?СЯеиnоIŠЪPlPЅж„-JЫ—OUО2cy"™МЂ)&>ўЩ ПЅ ;ь\q\щьи+˜юzšЧqmŒŠ:ТцІD::7xЪ‚SЅЧаФѓ‰ъ/––цЎ“ŒяиЉˆœ%)Б!JD<—‹$&IƒћdЬ—жЩћЩN‰ќМЇ(&‘‘8Рззu@иЃ<-ЂeMJн !%Н#MўШkTQж8ЊŒ vз№ЙXrppрш)ЁЙ†TBБтђbкыЩЄЛЂ  ­\‘!ву3-…[‚ т~Ў/<„63RXNьa\хxёŸ“}>/#АРђš^ #Г Z1M WРё|\Ц<Ч%рn–X’CДуЗЪh†Њ+WКёЮЧD6лдpIФ,jzзН%V0Ь}РОЋьює`­я_нЗзфњТ;< dЖеЄЬ[JЎЬRОлЂbћРУ'уŽф‘о›ПжЏјЩ/ИCg!}Є;%ј%іHT*C;ф1‚‘Ў ы)Ы!`”Щlрiл.оy’Pš$_Н&йЖыФЦю ѓoћ‘zУхлХьЩqV/хsqCЙ#E~WCИпы;KэѕЭV†q:ЪпENбе9dжчН8gF˜лaRјlE}Лˆ6= 4WEнIсёѕЬЋа8„šђIR^Е\‘V"•)>щr–* уЃ/уєШоPZFJѕ0 я1RWЅxЧtк§м™TШl%_.C5'эы”щђН !же™#,PP`’яўЁѕйЏу”jT‰ѕfЋЌ 8оQ$іЇїРѕѕ€^oдЋЗ:­ @їiSФЦќvW†ыOѕПA“nG"з™=U +cєŠ`Œš‡ЋIпъЃђz ў8/(Р ЧqЏѕКТ§Р,bПr2Di‘s“lŸ1>0`!C5„u;;'ажЅзC6 ЁЮЮч%ђ%РŽІ'Иz*ў9QчVоќCЊШm4ЯгТj™пШwYшМрЯD­л’оŸ бNЗJ|бё1§№"ѓ№kRђ‡•ві§Тнžg Ћ)S:6vЕ;мx-HЪ‘Kшо vyvkН›С ЗЫšOЇluЭкŸt*BІ;OЫj(,%e и*їГ>jkOЎ№BЧSVqOЉ–бАu\ыЛƒфяпFК„FвЧwћНса;+‡J}ШчMп"j[•О&KfгьƒхVˆЩѕ“СїOЂ’:нKƒ"-™ЇО}`{o4qЃТйВЦпz Ё›*ГFЯnЄ@Ў‡%œЃŠt8”ЈY%лєOЫGŠЏAЅ+‰>v<ю 2–cˆШHb—Šж Ь@ЁSЉSЄNК5 WC№С"зчфЙˆЛЄЄVАЌ’-aъ; Qgп ”œ?kЪЎоЬъ~ —<ƒы?Ѕ z€:В>ГУTі8нЕeџ^ЏZN„ЫЊBˆ™аС}Ш—‚‚`xYXЉsМŸ_W"Л=Iюˆ:i вгd+Дџ9дм: ч”PдЏzЗЮГ‹ў&eЦiПџџ9unЫxŠq‹ юЕъŠїŽ‹2YQ?~!J\šŒТ?GЭЏŒЅЕЯЯЃњёUз•Q6ЎPcЋья}2={џCb€NœДМџeJ'–R(X‹p8›b•ЇPgkщСЗ(V§0ЙъV™Ѓ>rм‘9шЈЭЧЬ€ѕ1\lвП tN#†OЅ˜YJMЛчSkћDJ"шЃСБT PЈYUjQEе* Vќ/тЇP‡Wc‡JжP06‹дю*€м.ŠŠфЯЪЦш_е3B#EА5Г КA ЖešŽЄюOПз]G”tMkЉc`2…,•–оB‘ащд3ЈвXФѕИЙ/RЫ зыynлM№]œеФXЧ2›A•ёќ%”ќш1Й№‘ўц^џ'Рѓ*•№ЦIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-custom-neg_25.png0000644000175000017500000000310211733011756024642 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<фIDATxкЄV{lSeџнGпннжnы6Љф)["LP2#&‚a &Ц„G”Б ‰ СhTќCCL&ŒТдd.$‹[˜Мъ\Lф!УcХБŽ=кБѕ}{{ячЙЗэ†”ШIon{пw~ч;чwЮ-c kЛліЄБХ5ЛŽДqкз?ьZїх‘~мnПЬE<џмl6Ы‚[,–„9чЕcб†щщЈˆ™Z>юдjІс г8—vr'ОhУ кLN‹œ№]tœуИ,1У&3‡г1UA$ІРfєЇ1 з=шЧП нЯвЗ4NV0FQh?ЫЌ*ЫШ№ЇI"cAhЋюФЃ„sЃЩУЩьЃ$zЄкvЦЅмЈj&’БHйXАwтк~<‡рЩ^ЪнКќЪгP Аd*тYј§Ьљіќь‡Н„/ћП8} k…зTАџІkNv Уы‹ы‹"У]—і~К}K|рћ“БXlЧƒр\Fыі’U.Ц”`J^*ѕ‚Ÿу„ ЖвZ]›‘юКЛp‡MМxуƒм5ИњгoАmѕБвƒПќћGI\OДу~­ПіГ­p?ZŒЎіF$" ˆ‡-L #qѓrЃijе{"й№wuИN}#gšёПНv6SѕЬ@рzNяпˆ‹6cш/аF–ЫŽи0Ш1с]к=І„†$о=§Mnцs{1вnђйё` йЇХ"ЁTR rЏк  ВgЦR!їЪ]ЄRjoхЖИе§*WrшЛHm}ёб§ 4gКю†К‘ˆK“yDvN­6M:ЭƒзЅoT‚x[щSЯ'ћд&Z;Гr•j„O\Qމљ|ЅiБ4Нг…X№:ф`Аащ ZюЉх'6щ|„ž›at–‚ 9‚ямЮxчЉQК @В|ЃGXm(х-\WFЇS5v5ŽGdE~g3JJчcоjŒV0oЄТє!1О–щOЗ|ZЅЎl'8KђFв#‹”†ЉLТ&бХх)У$ч3дTЄBБ"ŒЈ`vРШФ‡јйы6ЁВ–rеkЄл>AФd‡еQHЇИXВDрЉ§‚§’•џ‰}О#Рœќ.ЧRы+Т8Юћ5‰фS…|сЂ`тМr)y Ѓ0~ТьTЮJUg QoГ…­s^hЋЗњДгб0ЬvН>jtи”єnW.gЭфЦFкН­hk6І˜ЌъёšŸy]EпmzЮ%хAЬ]йЋmV„nRєzљЏƒЩ­nŒ§Ё7N]]šššрrЙRiЗуаЁChhhHЭ“‚…AН)виWЈS6Bƒ“HNn(Щ”ВЦЙ%рђ&аЬbЄ бЉ“фццbётХ8pрЪЫЫБ{їn,_О|”є]1яыЏ*^3#IЙ eѓ^L6’lOZi””\"0“K‘j ФTYQ‹ЪwъSИІІF›_КcФэvЃЅЅkзЎеI^*yцEБb…€СKT`š2rdK’uPЂдˆ")ХFr‘„‡‰4)*Rtр,ѓ"ЗркhM&NœˆжжVx<TWWЃН=5jТпОZo+žЕ нT 2э Ѕ‹дФ(eМЊƒLЕъBъ8Ѕ`кжЇŠWgjЊНqЖ:lлЖ UUUшээегЄ]mmm…BxIХГБж$aр’ШЙBŒЫсuг;сPъœа$OЕ‹ ё /Cг3є~ЧО}ћАbХ =zK–,СсУ‡ѕеззЇBqwпД<џф[ЊЩЕ œm*Щ4dNŸŽ6—Ў*ЈGќнDЌ@`IО Bц$zMќ~?š››Q[[‹žžЌ_Пƒс.)ѓžйDРu"$gуЦ53dR”бксЁMžšK [Р™э SоРtц§Kt?}ТN.{}ŸKR:У З9…kaЮjРьœ:vVЪG"6‚9уЗяџ[€›pnКƒДЩIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/firewall_16.png0000644000175000017500000000117011733011756022733 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<IDATxкФS=oAœЗЗОГѓqЖ“8!!")P‚„„‚"”Hќ jJ*hљДќ„@MЂЄ„@HDDba"чlŸ}Лћ˜ГhE іюiwOГГѓцНUХy†С9‡}В!O9пЏE˜ЊE2rЊ3=‡#ЏcђчŒ%‘GФ ‹ AЅч4Ы}А<]wŠЛџJа&‘„Э S&pMАэ ьЕћXДsMr”Ию™#jн9Ь`D0›Бювзkr‰ћЇйIЁЧ‘ˆэ;н!ЄЮxЩxe7Z5dDž:ЬFуУ5+ша$ ЯэЭ~Ёh%І€ RlМж˜уCфжђъЕF(ц' –ЊfЅуж\$­Њаuрэ/‡§^№'*жоYžŠ‚ьЖXIcв(ŽшмkЙK”љА}P`ГБ Їoє%vЅыяаL"І,M\dCXQXЃјШ›>;мžЗјšyœв‹NЎ ˜KDг„ЎvњюЭбР­’ЌњК=ŒйІь‹’uЬWІ ЎІ2&ц_В€O™: Ы”Ў—ЮѓMй…[.р^Яљ­я=П@ь,ѕgŸG•Д‚ВйАX,3,K yМ~v—‘t†г5Ц Цх?ы5Fs=5 е}“џў7ў`CэяЮh6ЪIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network6_16.png0000644000175000017500000000115111733011756022704 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe< IDATxкŒSMhAў&NšнИЩ†ŠB[ь%ЗjЮъЉBыЯСSСDФ‹‡Д‚žФCN^МPDћ{Q(Х› QzPkЕёVŒBни‘ŒofŒэJ}№xГпЮћО7пЮ2Ѕ(lЪ2%зѕz§…ыКАmŒ1 AJ‰vЛnЗ‹орa-Rю‰Р­-‰jЕŠнЂVЋ“šкЎжщtL=5г…нј$ъdњ…§УОpѕ Ѓ}?С“д&'ЇL§N<jvГ@ЮЂj5oBžя'Љ=aА4poF71фэ 1OdЯW.•Ф”чyБк7Ъ 5щЦY"tЈ)P%""yЙІнд› jТѓ цdТ‘me”_жЭ <ORћ’.L„;œі—Wžяы vЊљфюё'qџй rзг&зО~Фс#GБќіqŒMпЉЃЃЧдПТЙЦUљ^VUžКf„q­І™Ѓ1ѕНРјјў'Xx•бh4"L ”J%Ќу./\0р››яp OV–1qїДСš7VZбUЦzЋešё !`Yx1~§чшёQў’"žрЬйs fЭ084€ЪЁ ЎМКˆвHВУi|x$АyKѓzБXbісƒ˜›6ЉЭѓђ6Lэj‚ž`{jwu.6чdДІЯhОТRs^EиъЦћп Ьdь˜дєIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tcp_16.png0000644000175000017500000000202311733011756023350 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЕIDATxкd’klSeЦŸї\кгЎ-]Чи:ЖvА•A‘Шш.:tqu:УLˆEe 11&у"QПˆхƒЦb0т BFt"‚&0ЇЬ1lJ…нкuЌ[зuэiЯi{^OQ?љ&ЯЧчїќпчџ'ŸїЁоаup,€bkУvLЧУ8ёЧ1д9№˜Л G~§#гУШЯЫЧГЕл $г5ЫЗWіЫпQЪЩй~єР?}WmЦy_7>ќх=,/rудй›Хё/сА:ёƒП19ŠЮ{іюбв:4I\лŠ/й­Хo5ј)Ж­~ої‰ї}Wcuіx^šT‚nQ/Тl№T§фћуЗ4–i2хŒ(ˆ№шMЫЪЊ]kёRŒL4”7Тi­@VŒcџ•№&Ўр™кœЙєЭЯš™Ы‘ƒЮ@‰N1ЪЭL Ў(uуBь$V˜mПмŒГЃЧ`+4aпкwб§xцЧ•“ЛwžжМqќK‘Н6‹Х%wЕ‰OУ—щСЋўM(6•ЁБdЎe.b‰Х…sћZƒоёўo5ЯŸџMУvƒЖPЊТcј…ŽзбД№ ўŠHДOЩ"ш?_}ѓшьgНSТ}зXEwa­‹Ё 2œ5ЗItОŒз г$2ІaўЙƒџНЃЯЊЊVTЂIFкОЙ ыG6Н‚i Dkт3!Єeќ-Р†Иe<ˆЗIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/yes.png0000644000175000017500000000137511733011756021427 0ustar sylvestresylvestre‰PNG  IHDRрw=јbKGDџџџ НЇ“ pHYs  вн~ќtIMEв /с 1РŠIDATxœэ•MOaЧ-ЯvŸn[Xd””C­MƒLŒ‘D|IŒGПW?‚'уЗ№ŽФ ŠИЇ™zxAУD5ы8;ЊцБы•Љ”іXY\УљАпDDгF2œ~vƒћ3Oll`;_H†:Ўо k™љŽНш„­@тQ•чяф˜Оћг0Й4Z$“Щ {z рњ.I]ЂЈazБŠ™Ш9E˜ІЮЃЇїъfd ‡N Ђi:Uџ0В жхs-t@ФEXИ=‰й;€ Ѕ‰ќЃ‘JUQaэ4H ЇŒ_ЕŽѕCџЭ­5жKыьЋ}дožЏŽui$0ЧЃYœВжЇSѓЋlWЖиЎlUнЈБYВљQ-сљопI €ьи+ићYkœЊˆЁЇ(UJОТmьБ[)Sё*„Е&ОпРдMђУ“и_WЛc`/;ф/–p)у6іPЊŠч{-“ЫЄ†НъtšAleоѓзЬДDUzъ^т(ЙкЏћšН)ЌўaЄдP^їs!bqO `ia gg›žКFйsq+ЛШZ I€œ™%лW Ћчa’7Гs‘еGЖ(h1ћЪД$‹dЊ$Ch@ь(љPя(Ђ?†Rѓo~нЅШMn{‹Ќb†Щтвƒ–qв+9„чжxёќ".коЂN'7qAіІХDa‚с }4м8Џ_ЮvџoџAа КŽ=“ŽђђлГСомIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/rangeaddress-ref_25.png0000644000175000017500000000113711733011756024345 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкДVAKQžY7Ovё"ˆр№ш%Аƒ7^‚ЈЈФ^ЊCGљ2#J№l<є ‚.*иЁH<-vŠ™|зогнеЕќ`ич~oц›7+іnvЈћp МлАОUBvЏпюZЦсeWЁсћ9}?RЏ#цЬьbNL™АсиЬ`[П$dѓњЈЌЮoЇgRнХ{Ћ˜#ˆѕЗЊщВZІŠ„Џ{.‚U`;Ÿ6Щщgщд‰1џ?H3qkДщBїЁѓ‰аэ#$i€­–bAќ7IЕVC?>€šц‚Ї…—Œљ‹@?9"VjӘ/EдdYHZ~!ПŠZЊˆHк}ћiНvёŒГƒЮЄ\г-W.—AзuЙзп‰еe‹EJЅRвГё:гs0я|ЭДлm* фїћ)N/D2oR ёуFЃЙ\Z­–”f €|>Щd’kтdж….‡|=ЕZ 2™ єћ§йіiSЏзчОhтx&БX :рvЛ! ёŒ"‘TЋU№x<Ѓ€“LьО§f1ЎI0ф„Уaj6›TЉT(г`00еDќіыWжџ ŒиЄ…‰DЃQа4ЗБЊЊіэŠ6УGˆqЏзЫQFќšЭfЙрѓЯ„Эˆbшd.ЋЩїБР“ЊсчIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/host-ref_25.png0000644000175000017500000000214511733011756022660 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxк”V;H$YНЏъUUWwэ2‘‰‰`АiЖС‚Иб2А‰,; "&цƒЬ€Ь.n"›ьЄ‚Щ" ЪВ‘N0‰ТbЯаиmлеѕ{юЋъЯtЛN{сPѕЊЊяЙŸѓюkЁ”ЂLžU ФРWˆHlрPŠ€€Д€&>ц€ЃЃ­­­!&У0ЈX,RЁP ЫВHЁŸёЕƒ4MЩї}jЗлфyž^кЦЦ†а$ ^О}ѓ†FЕСˆИ)рЃx-Р2‰ОAўя~}зЫ$MНјiћ•ƒjї19–12i+К bКЕqпТѕуo/(Щ§j’8‰ѕЂьJКE(Ў#щ)&Є"tыEšФЮLтИ$Ъ?5cЊЭ'мz)е[y!ˆ Тv”’Д„.iїgEzQ)йdb$ч^˜вчfB­›mТ1єm ђJэ˜КqQѕѕ„вR(‹=аtС”Эі‘‰=Ц,a_ЙЦ ‘ЉAк’Ќ.O#bOYh‚ЫЫП)9‚Ц@b‚Ф3 {$Я)їk V§™„јђ аГ€‰ГcьМ4п‘2CR˜”˜YFˆяёm_OЊОпЮЂВz$ьшГЇш_LЈ юл˜Ш†Ћ ШLPѕ/ЙЎа|Šжh)E}‚є‰o~поўЊl_ќqпыЙшY!ƒ лXKƒ48б(oМ‘ЭѕvwwЉйl~ёŒЭВ-ВЧБЈЏc%†Є"$ыp?б4)3(С›1ю‘ OеЅЅЅс‘meвuБйЪpЬjbйђсцsгCxЏљ(#ї•~ЛККЂZ­FЇЇЇДИИH{{{нwџlІдƒR gЌ,о.рг}0Хрр ЙИИ ѕѕuКММь~trrBГГГДЙЙЉз?О|I “UE>,yZieЊќ№ьо+н7ЅDф№№VWW) ‡8юЭљљЙОџсћяКЯonnшјј˜^џѕ( щ<ИnО™]yO}[0КgЗš››ЃыыыьЌЕmšššвMOOгСС•Ыe}.//SG(FC—іььLŒђAMNNъњБГ§§}]КЉЬ‡“ЌЌЌh>fyэ8Ž>žыѕНџчџ’u%ЬЖАА@333T­VЕŒхРДфГžСйZ€дBReМBПМzЅ§#111ЁkЬБ­­­ АБт:ЉЮсž›ыК4??ЏŽŽŽФƒхљDG.OДџ |А я@їїIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tcp_25.png0000644000175000017500000000372511733011756023362 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<wIDATxк”V PTзўюнЛOvY`y-Ы*ЫŠ<&ˆЏ4QЦІвЈ­ZІi“ЊкЉІІMG'Щ4Іu’ж6SЃ­ЕˆMg|хeЌˆБ* ВМГX`—нхюуоўwЗaB:гiЯЬн;чœ{ўя~џџ}џ]ІmЄUtLкёх‘ІOGЊ2myjbкЮ{ћжжлX9o%вЕІ—dЌьіЭўцг~о7ыљyЩљ‡уПЎњ1MiП(Fї˜Cя<'ОјоЁџйїеX_ќ0Ž6ОŠS?]‹WщЃыЛ*žќАцXuХѕ{зfž—іомђGЄ+36/}za-…?aЫ-хxfэlЉи N |‹ювМŒжзќ*ълOЂjўђшšДИё œЯ*dr +mюЬY?&ёзŽш4КmWѓХfѓ“ й0џБзYє(8кЊЅ{Ў2џњyЁсŸ'БаRŒзjNИŠt%MћЄ€ЫЖErJйЦ9 ГУGkпЇF}рXЮ"›’НЭ|NЋвОЫШ…–ђGї>‡­ЙУy‡ц"ЊђЊа5ай[їкоƒЫгзМєhЮжs*Qг!u„paАоДїНPвYKZьуіIŠ+џ"gЊ‘…MЩ™OPъDАЇŒѓђvš‰Z=A3Ї˜ћr2r]‚(dRс=rbэєєс7]Ѓ =6 ыЏв48 DЉџ7%b •ювXa~J"}лгˆкТ9Її7ь9m;њTїФЧи’ГШBs1~Pє|єљ2У ўjл•ц#oН|žІžY RŠЂ Ф@AA.6GТEЦтТ6o#ЮOМ‘—­-Ш;жSсSŠŸB$‰ 0 йƒg›Юœ}рk/в–ƒЎaКќГj"х=ЊeЉ&qт пslOўѓHJауїіƒ8аГМzпЫ?€АOь•Ћ-ЖJтжЖžyвЕ(ww[NŠTqК"б п'9юVƒ“ЧФf7Шг№ыГ0Шг1тОf7n4ќЩе0™ѕ~™sз%ї‰ИvпuTФЏњZћэяDж•~3[:8tљLМIЃцtrљз,žЯТ|uѕЯСћт1клcAќQŒ1*†ƒ[OМќЮ >дDK}Rж$96ОмМ'Q›XyуЮСѓ‡уж-ЏЉMШЬЧшИ+4кuMnUF``BРX/ймˆxнбБ”їЛз€ARИ“ЮoXЂЎ™Ї˜D:Щ ф›ўAЙщдД€) 3шaв>—W)pEбq!іRk– $FР0ЌдOŠФЎwOБ”џЮ UFkkHљ*њž1HTЖ0(1S/SАаЩХ)IѓрН §#’ЌŒз•Kr2!BAффN]"523˜ф,JГHFфRЙЪ,ьЯ 1ŒаGЎІ„RJ^ вK­"їлЦ€4‰=ПЙUН8БсBЪŸА.‹5Й *Д{(ђijKдIВši …RХг  ]оП‘MЕVВ†єW˜n2Х}?›ЪиЕRwsебќvƒ эpTYЁјА‰~с/нйћyMІu3Z€ +e’‚EHMb(Ц(DХ Q*№-WI_№ІfEці™.,§lYчшqbї S;4ЪD5~ив‡f’wё‚4ЖQšаъыњ” v%Ып_ŠЌ<.кqRгеHN@AыЁаЇ"фЕ/FO~:rМб(3mхПŽЋkcэџђН<.oQЬѓRс%&‘ЊFЉ.ж’L%2иZ!ŽѕAˆ„>’щЃjю№ “џuА–R7ІоP<яЉ"6 Э&мu№\­ …­fTкЛВєљћP ~юџbmA#І=KсВ•@o|*нY”ъїFїю№)’‰Ъf}~џ%РЮ :x‰цIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/failover-cluster-group_16.png0000644000175000017500000000120011733011756025540 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<"IDATxкЄSAhA}Л;™ЄЛлЦhk‘Fл(*TDьQ,m/bOšЊ ˆтС<)B%ЇЂЏzы­‚(xADbБ661†h[jвнЭfГ›н7 4 "Х80|˜™џў{очcјŸEZMœК{‡хr9№-W&ЎGžјN№-i˜И USыњcм?Џ шКомƒФ#Z‹ЧOZkg™iБ)БїBЉ‹E–i6ЊЩНSЗ`gвHмŸЦСb§J№іБQ“Ъ(x- wVФ{k Vп™љї_ЈV •sЫ[0œюƒМН§чaЏЄ0№n;ХШвž@•vb"о$сЦ3Š=B |X‚Џ'РV52Кдb pdŒcы›И^ѓлM6ШафдOXE ик 7ыhGјЬќИo08ѕ!ŽСC‡Ы ™(DкЮгGQNЮaщхs˜§ЛА{0 .рo8ёѓ†T(C3A)…(ЖA’%„™ЧасЈ+о+œZ€Љ†PYќ!дЦѓ •ЧnџаШ0SВ$У…ч-oFŽјŒќ2є/e8JsБM’l}ў!СЭЈ>[“Л8ў‡›„WKмтWKЫкВ‰еъЇЄ’џ…Т|ѓy LЃњтъйТг™›Ќbэ`O9т9ЃlйoћHќЩвЦщKmѕfƒЎcG™Ыц}{Џu__хЄ1і[€П›й|9Ь=IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/folder-neg_25.png0000644000175000017500000000236611733011756023160 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<˜IDATxкМ–LSWЧЯ}яЕД*‚8)cd“1мА€Щм#ћУ0‘9Ybœ ќБ ў—E!3#d.\т–щћK3Ш$F"‘ ˜‘Y7БPЕ"ƒЎД”ўzПюющXБhЖlоцєоої}чsя9чн>B)…џЛq№кcёw8›˜„~ГяMп(џ Вž™yuэС‘јќ\w,Ё8хŠ›lЎЩџ‡›иШЌ!щl`KЎЊO,Юqѕ„k ‘К МT%ž#qI*”р…а(Ќ`ŸХ"ђ ]Kš9бВ– 3B ЏVмŸЛа‘і_чbEйŽ{ЎюSщ№š‡>5}e‘@љƒRљ– с5Bд:Ч d „K"TВШ„zЂ‚g€лМQ:Ц7”чŸ4~tZwхГяŸCЧ'?ЛŽ€чŠBЅY ’@r1[sК кБŽ ЭиЉ>§•RЂњoQ&)aзЉжЪN Ь _WмЯf†ЭяЏhњ–џ­­Х8~\X[ўайNqq}ЁЕr+Зj­VсТž=@dŸO(mz ЈћВЌJгj(SЁP"‚hЛƒUЕ‚/_‘нє{{{и…л˜ГKyО„P—™y’˜C.ЙBk§С*єVWиІ!ржqO–•u†Д4Јggпؘ=0>JИxЃ1*YшрЇšАvŽ \Ъ6­ъѓ1@%лј€ѓ@Єс§дkЇЊЯЊзЧ<ћXя€2чТœ{Иœ—в/67?Т[ЯLМq—жzfoаT/&=мћ§ тŽ~њeўb#‚VЏЩ{'cДgJИT_џаѓЏўьє/ЂU§r†!ˆŠьtВпІb Бqš5ЙSЩU_ъnžJxjЫ–и ОY!~г-•йSŽЯлBp7СмhБHљжюёƒ#?і74<рЌДЅJw)qiы8[wwд5лЙs ЯнШпЌfgМ[сSР?‘ BZ№)FЛ&ч˜ьХђcr­Е•ьл`*ауф‡МГ&~ѕCџоН1Ћ-#s\g[—§c„‹uuє˜FeцУ‡йK =ЪLЯ~іјч—jё~жк№­g9УЏЃ§Ы" „ї…Еy‚dЁ№—§ћщѕ#Gb–‚P‡њА6ыaДПИ "\gйdкIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/host_25.png0000644000175000017500000000203711733011756022106 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<СIDATxкЌVЛrфDН§4š™Е—"и˜€”Р№'”kI‡6dЃ]Ш ?`@@dƒ=Л^<3zK-5чvkWЊГWЁЊSКћмsюэлжZкс€€А pчz‚xЬ€) €Ш€Јя$9::кŠFJIгщ”&“ A@BїппЂы:*Ы’ŠЂ <Янѓцuxx(I‹—п=yBЛ^›БуPТМ  ѕшњ§гAIзЖюсыџ y$щMj( фЮЄЦXZW†вЪRпюў№ Е§КŽФДЦ=ЬcM7%Ž4нчк’­$нф# ћ[cF$g|•кŸЊ{мф-Г†ђD(ТЂщHТYjЬXIгИ‡§YHJŠЯыŽ^'-euч NЈяPPiauЄ\тгŒrB]/[Н—ЄE†зeG)ЃъЃ МriTпўžЄйDy%Э`—PЪч@k мNРЩ\ц-%•p‘с`+plq()š ŠТоЎfP‚ќЩJєЖ’UббDпXиn$]0Ѕ@В ћHaБK=ВыЁОtЈ)и a{V Џ$)ИЅ&и^ž3‹эDЄ›йдЩ#ъз•№jЌЄЦШ5*ЄBЮ*N$&s!ьМЎп‘ь!H-ЕЪ+BЌxБЃœ,ЪВ№Q /є:ЗєwNT™бЦ„vыA™ )ќŸOХБpЖŠдИRjFћd™ЅЙŸЏ•[Є€ЪBџ+ы0щ?ђ€…bє`тЃ„Cћќ зГЙџ^XВ5>ЫnБ МАшЌЖЉœq<кљg{#ХЗжГŠЭуї›п:7•9Ѕd?}ѕТђс”$ЩЛqWWWtvvFпўњЛР—Ѓ(№VђsљёDо~ќўђ•|ыд;іgЯ:??ЇыыыўВДZ­\zќбнчŽxп‡ФЩЩ‰ЭВŒ...шђђ’ЊЊr|ЬђёE‘;ž—Ы=ў“И7ЩёёБ]ЏзФрzч…<оЭМЛŠ@Т ^,єѓЫ—bg’ƒƒЫІiъ>јb8ЯэЈђ†Йqгl6ЃггSq/ЛўЏы_к"Уљ"`НщIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/failover-cluster-group_64.png0000644000175000017500000001205011733011756025550 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<ЪIDATxкф[yŒ]чU?w}ћь3vfМлqвИ‰œ4,!ЄЁaQi‘hЁP–ПЉEV*A­ Ђ* "щ‚*Ё4 Љš4IcЋБMœкЎ3vьёdіyћ{w§јѓнћ–йlg!‰{GŸПыћоНѓпй~ч|w Ѕ]_ЧS6ўЩ`01F’йMОрcT0VxЖщњ;Ьz;ЦЎd.%Ÿз0ц0.ђЎG,Œ|Ђљ]O<?ти6Ек-ZX\Єѓ.аЙW^ЁGўщз>Юж`^ЇрІаl5Щѓ=j{U*UК<;K‹"БŠAћ:€­`ДV­Q Јйjбвђ-,,P­Т!€Fљ;з+,WЃXЉVФќыѕ:ЭЭЭS­Z•sўŒПs=‚РБР-—Ыd&­–Wi~дjдl6)Быz sДкmŠуXќПsБ ‚>Є~ Žd>j #2M“,г’ёn<rк9>A‡vюІНљжўsXpТЮP1WЄЌ“}WPЪхiИ0 †(ы2 ЎвьŒЬ…lђƒxPщ] @1›ЃЁТ0”8%2хЋ ыjчм}јЎ“kehr 9ЖC\3DQD1~”Š)R‘О‡уœ?сs>гsиU(їё,Ÿуšт;ŒHЎ)Я4ѕџ•Ё0"ЙFf,џ—йTˆцŠb+–й0 Фp|?Мея)ЪЛ&eLк^0iАdрzwl @bђŽЭ>cќрС|Ж Г и гЁ\&п‰ Œ mїdM Ю`БХ4Нелuj‡m ЁQкaZИ7TcˆХРd-ƒ Mђ9NEуИcfЅТNH>@ю–ЏВuШ]JЎЇїЫј\tЅо„,ршРбўoТЎRсћЦB˜:@7 OR)[Є•њ ;CЇ/П,96-БcЫyпAКЯ“яЊч|‹еЎ)нхiъ›`Žхt5s‹ П5ЧD"ўрЮƒthз!›џбй'С4VhЈ4FћvоAуХ ::§<].Я@ѓŽI пOfОšЦб8G'з• СKь0+IDо@рюѕ#u­є ж<џ№UФ.сoй}ˆюнq€шщЯЫт`.Dэ2ЉЫG‰Nќ §аЭа‘їџ6}ёщ‡щћ ЇЁтDЈDУЄ…уQ›UF$юЧј=Zv[E#ЗЊџпа{„Q(ЫфшŸFћl&Kїоrбзўцт’8ьтiRх RdрBгп€OЗщШЎвK—ў—lзш˜iW‡YЖJОGДi‡ъJюqЧFaC*†!Q ІЯЉѕон`UЧУBBhюБzžд"м@љˆœŽ ‹LВ|’вxv@jїсћХ’˜Ї6 tJиТ|ПЂс{Рът­lлm@К0^|К№ƒS7]x6с§*ЉЪE}ЮBƒ|P.з9W Яг‘=яЃf9 •gЋЂр)Šš+K15че_ыЗŒЎ'w}8u™ЗКl\wАЯ‡2B9чt3ЬЬА: сыЄšKXWАЁ№2Зgiяі}дnzЄ€)Y@Яньа6аxз}RpдКЯЎ оltХРA3Ÿ3Kѕ е˜яšНkЏБ‚†ігЉ3Їр*>йy№E(Юc7`$aQ˜žв9@Х]TGдО(П6цoYГ7vHЇРФxa'_=Iїпt?тР9gBXј|Ц]'МТ0GаSЧ>CFЮдšяц­#е~"ИЁ:`­рдaК-w7M8“›|№Œ8ˆћ‚#Ч)nr,-/гЬђjB`Оу fƒѓ/~8ђšžћоГtџ/=Dtщ[p… н —ŽDxcь0}ѓј+taiš&і ˜qчGчyб8ИПтУМ_ъ §Y%’Й€йоLЃ™m4<4,ы‘ Ѕњƒ$ƒЬЭŽв@‘ Ѕ,Йм"uћZ+Кf4 f ОђЬПбGјЉ>GT;З^јэїБэЇщёЧЂтDLЧддˆ;fЭ0РЉ(ŽB$BЙЪslъ"ЉжŽфw:AсcЕВ”Гs”ƒ•qіJ-ВW6~Ў —dтZ­Vؘ+’/!…Џј  #u-Рбs/чПћРЏа{œyR+Чж !‘1q}ѕЉcє_Я=HЃLљ‘<љ-~)J2ŠЂfьСŒ§а НаЃто€"А ЖTš€! ШіBЅRЉчЕaњИ/шЁкzБˆG–‹ы>]К4CЏМ2M ‹4З№<яѕРкf `”љ\Grє‰ Чщи™шШо;щі}?A;vь SgOбП?њYдЇЉ8:@…b^ќк‡ Л ыc‘>ЬТ0\ѓШ№ёЙс рЕР=ЬљЁИIН^“ЎЎя{їљш<џФgШ=§ нїћёieяh~~ž–––ЈМКJc?щ^ГФ’umЏ}•zH,›іБ‹/аЗЯ~[R] ,АОБ}уdЃчp-cиž˜"зAд’EAяьhTŸŽ A-€ыў0дщwц ТƒЁ&SА$ѓеяв7+Г}ыЭšя~цяi47A ї.š4w‰ЄdНžаЕtтО|,Љ Bк9‹ђіMW€ŽYPh ƒ…ѕ#˜/L‘ЏЗЃ&€ёuCСЏщщ:У cёw~zХ}є™ч‘gўŽь п";єћжЩM}ЖL/вй иœЇŸkў§lжЄЅ&я—wрƒЩз{ш‰Єф[0(Isš+БЇMœ€Ва k‚ћ>>WвхбdИCŠвМѓ‰ЛИлЃш`=Єп<а /КŸЯЃ>й^iЂихpl  ѕ˜цИkЮБmz™шЯП@“ІKoЁЏ;?ВaghS0В‘СоЂEЮ“мЭп ДџnљMЬоoS;h xC2#нTШюФ pŠKсђЫZX9=4дІ{CrЃўVЪ[49ъPж1ж-›Ёи*В}DїЭ­„Дк2“lXсОеує[tœЊШXџ94N_’MqCзGiDНћїюъќЦC;Б„d›Ж‘цœ.‰QR%Šж! ‘РŽIыˆьЈЮёэ›КпЗzN~#@ўƒ I;%ћє2Ы Щёm›Шї7DTМ†!&wfZіЩЕF3 ЙЙ:iаЧ&љЬ+OўъoќхЦ.РѕПhпаDІѓ‹ЕА№"hФТBјP›ЛјЗРg…фd"jU•hМБаЕ–ќTЌŸЬ7щ§+eт~m‡r4ЕweK…Є5ft`–G =0 0вaЩ\ЗhџnнB[žY KчqкWАК4ЌЎф7х   M‡Л]%2€†›~Cz€!#внмtp“C"8ЉNe)ю”0ЙŸYjї§о?pЧNX8XІ‚хРЎmЬўkдVк_Tд Z6sŒЎ%ˆAћPвhЁHЃћЖSаЌггOžЃБLЯ>ќВ мъц0ЈД@6u&(L\Xы­ %ОРЧвЖ7%­щg@IS“ЏеК=джr‹N`’ к.­;(ЪА\Q1йѓша„y‹%и> ’Њ4јЅ7гу?ОЎ9Щt6OxЋж"†і1ž-л–юяБuМ§ŽgкаТaJТФL+C1ЫЕrbШЁ‰RDm|tЙŒ€ъыrИНднјфŒ5ˆpCAQж5ѕs­t7ЃШ%(&{Mы-€IL=[-WЪИзІсссuТЇ‚ІѓfнлЭv{:VРђОЄсшŽь"@l`aYИ,–А2_‹iЎЁМgPб`ІГЉБ^xЧI(i7@QЖЮќžBЃкЌJX^^–eŒ€(5§5ЭЫTxžcKuLQk;)œфs[‰ХА­ю‚yŸСЪыкоЏk Жьц€ы—L ПГЅ№vя}Вљgђ№ЖЎZA[ПPФђrП-‚uцЯ™УФ/тРh$зtIяєFВЫФ VKя5Ъl™Вqк9xvNkо‡?ƒ\iЂC[‚авVТѓО'Etё{8к& Г@ѕ_ы ѕўьOUgЃd ,Œј:ђ3g‡ЄДяIM…}q"ОD/vbЂ|xаXІŽўU€А…№i№уУцЯўЯ;мЪ…ќЖр7ќ–XКaђu•ДЙ5жЎ –bšІue)/Šщ/гY^ЄWеnА[\SЕtиLx75џAmўВŸAШлyіы`эJŽђНZj!A #Щ>:BєL~[k%ЪЫk6wEвћ7ож4кЭkгчќЯчLЭ)K&\!Жj[Ÿ†~БpS peё:ѕ‰Г@JСЕя0Тус8qѓ3 [/–нхБp‚ЋйљйHxёWЇОТ@ROdЅбЧ вDц1Ќ+XРђЪŠТЁС­їзXлІ‘Ь эЎпI}nšzЦš}^<3akйС$јWg› ЯsфччёsљŠle 0^1ЌЎЎRГб _ќ.эмЙ“JХR'nЕџv5;КЊСD‹l9‰ЩzЭ 6 шйŠ MЎ:Т‹љЇЬТч4зОahвХ™їm @кч—‹g0Ÿ<~Bкг*~ѓvk§ОдЌ„d9ќ]ЮЊn0фдъy1y1ВЋˆr3&;ŒуxƒY†5Э{”,xnX›П“єиZ"SЬП/ ntT!<їиыеšЄТЗn:Б‰NИ†4'@™ 0jW17<аƒXмЩrКэnУт—БИQхА[4ФRўyXП0ЩЯф~]BЬЌЭ‰PzМ№ьsoщћr'?цЈNKsЙЁЉБBЭя‡Yj/ƒWдЙСK|qГe3&qѓъДЎF& фGy’Ф6…Hq^У†ь.9 йkŸр,Є:MбwШŸЬ№ЂL=GHT=   .bЇ’шAЃYЪdD9{№‹EН ŸwГH{ рљˆђЁ;F1, BЮ[МЫ#Q)В]нvЇфеŸЗщqџЄЧGхzˆ1ЪбЩФШEњ†Ÿ†а\AбgKи`УГ“ѓС№@Є2Ѕ Ъ L‘ЪТ5r KŽнАYЇ тСDVPFћRЊПэ  аЪKчШ*! € Ш€Л–рЊќЖ |•{ќL­7Ћœ$эIУ>Ÿs7 PlV!†ƒ xeXФ xVM@xл8ё‹ц't hіЉcTи9I#З Љ=0€f",Ї4WчqюљЩЕњzr$9?Ѓ9šяЅъЗY8M>7у *пŸЇЈЦVрН}ўrќ9€РНСпQ~{O§ќЋдИ4KѓЯћiфр˜ФP’"ЙŠcтp-/'a^ЎkHnч€Ъ=ТИ­їŒиe"E­х%ЊN_ЄђщѓV`~‹мёЉлwТ_Žˆ§фГцЇщюHWCvа№ЭЛЉxУˆz>,У7№šЬ„шФз^ш0ШRьpКуQ?№cЊ^œЇђйKд^Z†1 ЬgпQhЈј л}аxЇ§щ,Рј]ї0vIП#3XЂ‘›Іhxя(8Lлї4_9Њ­щŽ$•Ÿ kЗуЪ|нЌ\*SѓЕ АьыŠЛМ*> “ћыл Ок}чћњЗУтfL 0~вт]зƒЛFidџ•Ц tтбяШwoћШT[ЌгЪХЊ^ZIvˆъЈтѓИїo{дџЋ*ЋЗcгwнЎ ŒпЧє 2™vš3Ѕ,y5НЕfЙ6ъІАwctџ|%я_мњHmnЫОнp М†у6ŒПСИoЧ]н'0ў˜IцzSє|А`ш‚AMЗˆ?BњOeўZ„чуџЂаšf+вIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/addresstable-neg_25.png0000644000175000017500000000163611733011756024341 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<@IDATxкМVэKSQЮНлн УЉ+ёeЂ9ˆВbŸR‹Bшы~4IbЄЅPE}“}PВ |!Т2† ЅЃІBр а­ЭюHГШ—ннžsЖ{w'лœR8;<ЯsЮѓ;ПчwЮЙ#В,УПn:њcn~ћ8Ю@’W œяAŸ“№|Џ:“Є‡ЦГG„љыž№Lѓ§‚A€у7м'-„#№фб"‚Aі–›З,њ8“c—єR4јU—Ћю•_šЛiЌ)„ŠƒЩШЎ ŽђF`{э—T\kц•§ДŸpœВЛ8ћqепtzo&иxXBЅ,t”БG$`уѓЗхедŽБŒgьжч ЪКуЕаабў,ЋАO‡4KH`s'A›?(СЯ­D†рт‚яhП+S •Щјќ–2P~Ѓ‚ЯDN'Ш™|ї&tЪ‰ŒДd™й#ЧДЊАUXЌWуTЛ Кь‰іжыމI48z!)pEƒ8›™g›x‘I>а4—,W&т'жCС4"сƒ3ЁхЪЪ„ƒ/яО.G^ЋI2љ@šА]ЃРœ† ХвR%, QA—Q0Є„зPЁ єЖzКrы2ю:­z}ђ9ПСDк–МГ єЭ‚јVмKG|œ_Пь}я  ёЭЄя їROНМWЇѓhПюК#кRsгхъяя‡ЪЪJpЛнFЁЈЈњњњРh4‚гщЬЋ‰vчY*LЦЦЦКЯч“m6›<88ШlПпП/&J\aСђ+ %%%ђ№№0›АВВТЦ‰‰ ЙККzп š9l a?„0$Ће SSSPWWБX Z[[!0ЦeMoж4/Б)пiђ-]yŒsмJUввR№x<рrЙ 3}АtаееЁPЪЏEд$ё`pZW_пЂБПЃmвЦёЎЦе[@EІ“““ажж###`Злatt”ХMf=˜ŽъXg6ŽХдgжи4ŽОœ—QE@  ГГPшююЦۘ^P^#Јя8‹ЖEHн\|@чЈmHv`ЖЖeh’ЏЁ&гsЫЁž[ќ$PIsХЩџјпѕG€!zмЉMсэXIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/dynamic-group-neg_25.png0000644000175000017500000001164011733011756024456 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бхіIDATxк”–ilTUЧџoэMg)эtK Zш HAvCBRА`1лˆ!1`‚њ­š4~№“JL0кj0| † ’š–64hE0иEЖiЁeКOg}‹чН)Е ё%'їЭ{Юяžu†бж;ё”ЧNВšфy’e$RBЎž. и50”p_ўЩЗЉэ#БЙ №O0n"yƒd?I2тЌvЯ4~*јRћGЗЋЖмŠхКЊ ›ии§ьѓwšCОSаѕ ›I>E†Жщ2b]іОвk-7юй}[‹6‚YЛ}‚IФcИ?Јeіw,VXярPKzЧ yф’QЬrpЋ@‚ЎpЪ[Н5=цз 7Vlž„…Дт ЊdІ3№.ћobЭЅК”Ђл7Б`Ÿhh.ШA‡ЧQА “:кё^ыЫ—o\BМ ЉˆFUЈВ:i@%ƒхoŽ8И6ёƒлэ6 >$аФУR#D…РЌ@NюŽЈјqИ,т,кџW 'rBƒJEKї1mžФ Г$‚сKЖƒcЃИI ЏgЉ*’Ф0Ÿр ЇHhврљф*3ИЭЕ5q Cэ =MJR&щ}<Ўa`BХѕ>}dеQфH§нЉjkм–eїРч.BО4 ЏqљQŠ…e qŒ~ •сg‹ў§pXCH”!јЦ ШђNђЦЪbƒ‹‡йК Х9S†Йй 4[мЭъ№QKћŸQŽ}ђ@є(rљ * ”Ї{тGan1ВгЇ ѓГA9&”и/ц­А_ќѓ^ЕЄ13=xˆЕiђ#iК}&ѓj’gfjlбєPИH,ПйбДЄLtё##‰;ќlƒs€єprщ =kx…7-с2<ЩŠЉВ”јЃГШS4ДьœМюъвкNY\ЩЇѓдCЪѕЪ$Р.—FyШŒƒБ*гjœЫx/ф!Ч$ˆtcГƒnM"‡?|В†—4FЗПКхТЉT%­­Bqw,вЬ}N^u‹јЫіЬ&ХёЂr’ vбЭЉnИX4†8]Ч’XЩЃ8ѕ6ўx“ЧsŽŽьЩ­Žu–Lгz)[&/bа-i!7”юЕми/ yWСМlњВњЬРємЁRЕRлf(ѕ1Й™ZС о_g›{%Ѕ8С+$+š‘†!њšрй§>"Нˆїъѓерй“bтКіsч$bф5HЩЃ•ŠBxЈ)i”Ё;’јв+‘ђу#clkЩ•@МР!+/џы?`т4CM‡є№/ЗMўA} œ>0чЬзО-n†`еоПчЋ‹н)œ1ѕG5:šF yiх-HЕЅ"з/тZСoLЌw 8сВбёЕЕЕhll„Чу1%IТБcЧаааД4@qoPHУЫ‚х“Ž=н‘МpY]№и=HЃЩlђмЂbаsо€ЄІІЂЌЌ GށпяЧсУ‡QQQ1 7мяЖ‡CПЏW\–єdЈf‚8ъ ›™ЊЯ‘… {&"rqmЊѓBВc яйГ‡&kд0ЌCВГГбммŒН{їUЫ&Ќ> ЎT§7D3 `ц#p&dйВя\IДЁэЪUŒ…яБіазРуДЎЏз‹жжV`hhлЖmCGG‡aФпšЬ!ђƒ•1о9MDК) ЯК–У›ђ n оРw'ЮaЂ;чmѓЏgП OT#\nЗеее ППп_UU•с‘1ЄgФ:LМ‹ЩŒ,{6Šвќ˜яєЂчn7Оo;…БСр{БіГŸы€щQ_SSƒЪЪJДДД ММuuuFŽъыы 3Тѓ4юDѓЈЬКУŸОi&ЮužG]§ЩўраЮDуШЁG~уƒС šššАoп>ьпП‚ LКзЁBOИЩЮа> у€ЄЅA3увнышК8Іџ7Ojwnщœ<щсv Š–•$ѓ†qœ ђLШ‰ю„’hЃ§Vљ„˜Kџ_Аl?ъgт0IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cluster_25.png0000644000175000017500000000256311733011756022616 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкЄVMk\e~Ю{ямљЬЬ$išІж4imŠЅвкж*Vё\Й\ЙrсRмXФ.м ўнЎФ…B?]ˆ…а*ДKЅД6&Mњ‘&“™;_їоуѓОї&-ХNо™{пї<ч<ч9чŽЈ*ўщ:1+syЋшЁRєЄЉŽД"м†їПЄНƒ—?hƒˆМ_Я %‰J+вf'N|"д"ХЫŠСз@М'ЩС“p/њn–CL•ЫЭwbTЙ­ёП@zфeюfFхР8Ž,У=ЂNe’пOoDhЎїuЭёУHчИЅF;CћбК2;VD“zОйь9€Ђ/hєЁљ!П ћŠБМщCЫ Жc-’ЯwyМFxb ˆЯfъЫЄХЈ1›йсРfФ;IЙ'8ЕаxbыЄЇЛњ‰ШЈыPМ6фв­0і |aZ‡Ў NлK; Fѓв„cл<+˜$.о‹АаJтuњзњ@чvUМDœ_ncw5 ”т.ЋНDŸg]”ФФЉЅ>Ц 2:Ќ#ыDЉєЎћY/ихклДЂ­mЩ‡$tвЁ‰“2іcŸ(0Z%ŠЫŒјЗЕЯnїqНcƒЕЙнQА&и–­цEV{zd3“-Й?Y7(ƒEШЭ,nђ -јJу›?BиОй]6ИнN@Ц№јСОЊ8p~ХЕf‚+Mш#рз сШDЩЉЈСWК :\ћL%ь'.“з]6уЇ­(>МиŠЧy{”5Ј}vЕ—Ћц`LuJŒlZ9[ї?mеЄVШЁš'ПŽѕ”УOgЏЅ}68sr^пЫшЕћFшg?{фаz{Bн˜сЃсНU“ЩЫЁ~!vv}0+њвt Ьv‹7лt†7NФК<0l,–лzтЃy=‰џp9ї”6‹Ме-зfF—ЅтŽK…ЅсNWС({еœмb‹}i-оѓxц3|“5]/NU ­3[ƒF7ТЏwк(ч †и|m:НзSP)ŽIdџfk&А…І"ЯppкU#:Ѓfv}ЌXЕ:ФRwа:­9Ьф(ХPс–—в'§(!`‚я—КXlЋkD+Y;уbGЗ хkЯЩbЈ…­9ЗиD-яaŒ˜ceŸЮRк8"œ“‰Р‚ЄЋšѓмѓЃ>іV=GЋaЈіљЗ‹8}xжЦЅїЇpГ;[кшсСїУYіD•”m+N\Ž‘’уЅН`у№œi€Иеw”§#ЎЖ[ ЏLWЗдєУЦK6+Ыћj7ЦеѕWж2QИ}iŒsw"Ќumc х,Ыq АOбgSЮќ,їALVу\ЄДL’дщŠчкNvA№йчПs†•=6jЊАŸWc\XН€=ЫфYu/p#ыА9У^ШёiEg]вв:lвagT№:О#‡Š—ЮЏMЪЌЎsœ\оPди§lF|Зйэћ7ЧЪЊуР­vь*zo$k|—А&тj13$-Ц”ќдљfv–ћIіа4чйxAй Ж&щtЖюфс_+ьўI.Чh/d6ѓ№kКТ”vБ3tњcйНСвŒч №ЫšтаˆСW TšЂ.ƒ~=>›ОJ{š6ž ЬQЫdљ lч mFщ$оS1xу\,џфo€‹YжЏгžЇэБ‰N•EžтЌћњЯX8V№—ЇœM<Я@‚IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/question.png0000644000175000017500000000242611733011756022474 0ustar sylvestresylvestre‰PNG  IHDR00Wљ‡gAMAБ ќaЭIDATxœэ˜]lUЧ3ћСtЛЫкnљhY-)m4@$)IEР МдuгQ_,Ђ$ФаВлФ7Љ&$Ц‚AxаА‰$ЦR)H%ЂE)ZЈхch-ЅэvfлBЛнёaйщv…йЭў“Эо9їмЙџџsЯœЙC9фC&РуqзкПќ^6{^СЄћhЉЦОрJfћ$цчsђьy‘?Ў(|јyGКџ+РзfLl† р|јEJ—<—ДИJaTFОzUwъ“Ягэ:u;~Hљиœэфй аЦNд?ЮP/@\…hћ”—ЛypЦziџэ"Ї:ию2…ƒнш@Ч]ЋЊБ)ђ“Ѓp)ЬЁжoм`Na/ЌђCЌ›вYхШзМ,_Ж@`ЗлWЦуё“FydЃ^kйџ&5е+’!#яcЯсn6}єг4Ї]яWѓіKЩ ЇЙџ&_n'Д'Й/М^o™Ђ(— ђxм‹j*]рY‘Ж ђтГUЋоpЂmнЛЭЇљЙ{ђŽ€PYъея‹Х–сaX€ЊЦ:ї€ќR"wџ:|ѕњЧ_]ћ;Zф![Вk<:MD šІ-в4ЭCƒ–ЭН7Ё7L{чАnЏ^ПёxэSѓ…B‰P(4Љw8}ЩGrхЛ{еєл ‡УaAгД‡iУ*їмгž"h‚ шяЦ#Ш‘)~=зGєЖ ƒFyЮB)yФ‡eњz2W3EJЊJ‹нрœv(ДwГћPЗюлааpа(УЪŸпѓ nЋwn~Џл‰*Ъч'-уQњFљфЫNнЩч+<І‡мТшИи‚Ср=@’Є5@Ы7ЭЯАzХbфqˆœ`m§QнOmыыыыЋЊЊRХоCУ№&MMM‰Lc(JмО}Л`нŠ’dЊыСEы™HšЇ.,,јŒЏ>˜WІуѕњРТНЏе.ЅИb ‰и%Ђ1б‘1ъЖючк  №mQQб[Ље Ѓ oтР^џ,о‚9Ф•.”h„I›—cЇ:SфЃ6ЧŒф!ЛК/ѓ8qКМУ+С­ ‰ІЯОПг+4oйђо3ШƒEЯŸyЇ•м"чКЎЄКЎкэŽn—3ЋИO‡!ФмЂ<АчqаTф}ѓžлО§ƒЖlВN&,y}7бѓ~ѓЩr_„#]жЩ„%O h„ўЁ_`"F—Ќшv‡sЦ 3Wп*h%%%ZMMЭє Aм эАЉ:%ЪШфЭKЖgЛtЛ(Š‹‰ЛъПЌ`Щ{ЧLˆЋШкшMяЬЮBж€фБbЦщƒАDРŸgС„BпР(‡[{вЛ†я3Ф0ЌиТвК#,UZBe™A7566ю6{"KВpАI’єtЪАmлЖ6+&ВК&г?ќЭњˆЩ!‡ўGјNвц_Ъ?IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/nat_25.png0000644000175000017500000000211411733011756021707 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<юIDATxкЌ•MˆEЧџе]=§5ГйЙЙ*YЂˆ"(о<Š^ѕb.AёцСƒЂрЩ‹xС…рСƒh"Aє ёД xQXЂш%‰нhмe'ыfvњЃЊЛЪеЬЌЌœ†и3њшЊїёЋzЏ…ЕѓчйЇ_ќgp‹Я‡­‰y_ўћхЏыЯмВеЧЮ1HsЏО†hљNB@а!гТш v.M л*ІЉЦhїw̘ІТѓ7Ž=jЄ О§ я[кЖ.`ЉhоЂ–T,8цbe`“ vА[&ик!ŒАиHиЃ‚dˆ­‰„UєД6Ј&4Ў кŠA9Љ0*TtЄ1шaˆ|9іN.6(Ф'ылЈЊ eYЂ( пЮEk Ѕ”o›ІeРж \x2чўА›‘AдтхSФЅ‰Hъ q•Œ‚a9t<zС–чЃ•z4n cБиˆLB4мД5ЊаRAKUЉаcУж8lЕѕ­т†&№Y‰\Xi\\4.>јєВGRзЕЧцФѕчsЦаXлzqЙцЦчŸМ“ D4ВVx§…ћg(ˆD•<\‡ŒуКє‚Z1*їО!VMiАГН™†н"QTВљч *жФХEhxg# Вы?nТb Ч‡Зѕ%dж—Ь$і&жЮ~?Л=GфАИўЛMЬTПЧƒ РйЯО€ќasšCџ‰‹ž e…їN?BФа(УgxЭшЊ}\§ђlœќY є#ДфMЃ—ЎFO‰їзщЁЛIћ{х4ЏГ˜•аЋ—~іŠ&oЮkЛ”%8qянўLѕ_ŒœщП…_>ЛЛЛ^мЭš?‚Е, CШЏžђmERzЙ№ѕЗ~џт3Ё'зх ВS‘љ=є6Ѓєщэ –cщЌO\. ‡-%6ІnзцNft=iЁY•+ЉЁЉI'DA#*у+CсЮ„mк 1шЧ8ОzМлэŠnБu —зї8ќ"Ђ˜Ѓ‰уI’’љм›ч>іNvТOрС7ў Š)ІЅ„hR‡ 8Ц(–й.ЇТЃЫc‹ŒЈj „+KЋpУ зз.Саˆ!ІИкAC&а‰Іёšš'œЫXоФЙrЧJЗŒwЕGнј Wжѕˆœєz=#MS/Y–Ёпя{Щѓќл+ЇпёN.ў2r‘о…‡ољ<шЭИ†9QхrЦўЎifЬ•XКќЗ7-ѕСЭОŒгТНЕЎlА5О€јљi-qсЎяZeDЗ/Ѓ[tђср@бЌ<љЦ Ч•ХИјнеЏC МUюя№бњщн—№? 03жАђ–цIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-group_25.png0000644000175000017500000000314311733011756023722 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкД•mlSeЧџЯ}юKлuэVЖВів• a:Ђ№QŒ?˜ F%&†81Ѓ‰‰T0Ц|’EƒcP^#@PЦ&р6иК9кumз—{л{ŸЧгЭ&%$оєц6їхœѓџŸпy&ЅФџ}АЉ’ьщВрLzЧLдџ‡іг vѕŒШё€[ЎžTњ^tк№пIд)o*€Т ЄАIQаy9Ž!DІ•Qа4ћсвЈшНkл8k;u3JІLђй9 žCѕвж<аїЩDH Fs Є;,!Ун#ЂІhcРћo)‰І`NкDg{U} ‰m?9HфкBtЮ0нЋР‘%ГfЭЭ$QІКй^‹=‡ЕM[N0ќ:(ђ ъ ”1щЂВ2дЏXVЦ"Acєfьš2ЩP=ЧЏд g€wшжCЭzкАр9ћDПѓх-'!џЛЌтDѓёp3рsЁЂ?‰%сг<@­0ˆЏСГЗŒ№{GqѕС&д_&3,HцЉщt^'U'$вІь!лжп]m^исyѓ9\9ў:ђЉƒN.љ2o]6 ƒ*9К•кЅQeъЦw_—я~zVЌ0Т›чЁфHUб! xЉ*Т‹ ЛППcї*Еї8G:ћTУ-uЯіш фйјлHd}ЈЌ;…PkVfjЛ…­Уём’МўВэ,А§,†“2a: -оTƒНИЙФNИ+мpyС\х0|•+бћуIЇч№7в(3nІ5‚ЕœЋ„$Zь?]­хѕNBhХ!БKФyІ-xр“‘дќћШЎ%^{ЏnЏЂgGОИgсfФ.W€T”Ў—щњ•G2зP0-Ј.WЊœѓ˜Qл|LаBгэЄБ‰)ЂгNˆ!z7ЗƒѓCKЊЉ€^­Fyz”ІћЁ#<ŒЛŸю‡˜†цІ)+yN[ЈЪзНфЉ Кo:­Kc~=џЁ9}TЕ.89Y­‡љ­^qГA!54|! )У"&kПŠїЁЎ~ю_†юь;ыШ6hщ( •3сn]Œ‘*)&O_ЬmиšПЈ‚cŽДаЉNgUNRТќй†0%д2+СМ$SЊ JЧКNмћ"с–КіAк%›Eж№ТЙ1РMlA…xJXММњcяЂРЈЂ•Ћ=ky3r'‹(ŽСЋ”‹Lg&ЃwЅ%QUаyecЧЄчБмѕИЪЁ”•e<ѓŸ:Њ>іVДЄ AЉ?"—4ьXпfчRy›тdd-BŒSˆМ„с=F ПJ}гиDм+k<џљ*L ШЇщЄЅ@ѓ@mY$дЖe!\јvВ€в\PO 0šBЛM^<АCЕВKЋ“ѕ&"+ƒ"%щЃтСрЄ$Mdˆy_‰{тИzš‚>ŒЧ|„)ЄЉ-Срњ+‰mC-ЇЉA^§Š{7YцЅ@ф?їRhЩДRяœQРDЯ;jшр†Л^šч­hрЇ+jr"Ш6'LкHх5шПE?:S#yaхsВaўћмїˆnцOлЭLaцє\к“K с‹лŸ\ю[ИNCz'‚Ь Œ*іћщe Ю †2ЊЪNвЬаЪZ”1'–W7mfЕГіЋЮ˜мJ–эбъpLфбdўBtфА6CбHuØмЉvязh#ЌPzВЬ!š$­7š“biн)LŠшэ…S3wЏgхт=“ыGМr5 O#ЯQгћ‹Ž ХЋМ*Mld*;Dд}ј:k=š?јХЏwЋD]~т›ЌT}fМ4Ь„.%Ыjрй)M+œЯўЯ7X…џq^>qБ§оЂЖмy uГƒ'%gˆЊ8йiw0ЃЃяgШQZœтю=ŽХ бnП7м|Т ж…ёЂПЛ@›<ЭЧ5$H^@„-e.oЏЙmZeє_ї“)™8ЮBdЧ=ˆѕЕУzЎђ]ш№ЏŸxvЮЊF†h~EсяŸџ)Рx’ТжS3вIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/self-ref_25.png0000644000175000017500000000204611733011756022634 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ШIDATxкДVЯoE}3Л^{ЇˆЖу‚"YA†‡(ЂŠАrA9p‰Ф)мЂœшСЁНT‰SЂrŠ‚ЈP …ЄJnP]CT’иЭ:оУ›йЕcЗH­м0вчеŒwоћОїО[(Ѕ№{MŸ—Хз|МЭxCcd$Є”РqБ`xŒ/WЏmЋСH8>b8 +ŸШ%k d,ˆVlD.Пћ$ 1(‰Эы~Kс#›’HБ”Œ-ркх 9GтЇкёрrqЄЮ;šDw_Ю!ЂJк^­•ЄjBˆ~OЈБ™h§žТЯF]‘rЌг5ij‰’2I§‡ёчžK‰Ѕ/о’—|r>Фиu-ё•зк—ВТɘИ2bсРWЈ>ш7>ЭіЈїyЏ4-ОТ}\‹ŒСП5bo~їŒўЊk,ЬйШгИб!›й‡Ј“ќНKCаrv:ЬfKN–†Ѕ‘GƒњDљљŸЈ ЄГЪ­˜еNрN3ФЧ%7ж^WЅbуйxа M RŸ™фйЉфM ўў‹Жyса^x5'Qp…йЌЗ‘@3$Щ!t[к\%LеZZ”&c“сVэ!кL˜™_б$зoу+ЭіщЏAя­єЇxд>LЧ“р/ЉнЏЪУsD№SўђLkш_К=zн///cffЙ\ЎЛІЏ‰—YM№и­ ГлeмLтЧылъюЏzЯѓ077‡еееОuмууу; HАэЇОQ{GЕZU‹‹‹*ŸЯЋйййюzЇтAЂKВЙЙЉ*•Šя‰‰ ЕООўL$FЎ ЬЯЯЃнn?VfЃбxІŸ_cќфф$іііт+Тq066†ŒcmmЭ4€6žY‰A‰TБX4в”J%ЕЕЕЅVVVддд”ђ}џL<‘‰)†mzzхrѕzKKKАmћLў­’‘‘3aEцЙАА€BЁpf‰Н0ŸдыyђЏ‡<=В"Ќ>IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/nat_64.png0000644000175000017500000000623411733011756021721 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< >IDATxкм[MЈ%G>ЇКя{3q&Yh0ў0[DDQт*q“…Qt"Ф":D тF,дјƒŽF%ўlL@Dн ЂЛ йФˆ †‰Ю›їоНнuЌѓW}КяŸ73}сх5U]Uн]чд9ч;чT?$"Идяу;{ВTп-хL) Žз/—ђH)ŸњЩЯОБЉIэђmцЯ_ВЕухhИ>ъќўЬБЂўя{Ф›МьxзпЋ.7и^ѕcс•јЛjИм§аЋсЎ—ЮСє,ЄнSЅП<Ђ)‚BYЕ­2Ћ6Ад—ЁО˜$Ў;™G}ЇзФ§]щЪкЯѓ€ДOю-§=пЗ‚М:ъ–хоC У‹кцО2Fe^zг{`чп‚ћю\йP\%PЪн/џ^ЗzКмйjiZРІ)…Џ›ЁПp ™kЕр EЕmХњБJЪПЪQ~?УќјŒRчgž€хЏ>Sз9›Мaї%€нзРmяМГt–Eёю•EШ.–ФLКГ§JwВь”ЇrMНЖeЌь$я.tк/Лп­t\ЄBkш*-}ЃэU yY#Qэ’<ћ… eЯўхШЖЊ=ŠH]Ф^я8ИYыХMe—Шt=Ћ$PЇjРз^SВХ3qЅMмNLm)Ќ.НЬбyЈcЬЬLv_ѓsUX2цГєёv3ё] iЇ­s6Рж1-t5ЄN—tgyБЅŸѕVдT‡Iˆ-і‚EaЦ(уGКw*’…bшD`HЅ‡щћYпW, M1Шн5Сѕ‘%@ЌОаЪ†ЮЫuчъŽ'%™№<0вIF8Pч‘KB3<ƒ9Узf,ХfАИ/ЪќЂ[g€-‚‰Ь`њ›tGб˜PЖ sв*Ф йюgT&№т9њLќ…8'ŠЅ‡Hэ…Œgcž]ЃЋПŠmDБMкŽ =№§GŸ‚НННbЬ{)]зеклЋеЊŽ{лЧМГLОцšћИі~Џc[5Dћ~wІ5ЦЯ)Љeѕ А.`Zттbћr‘чQ=Sd2Кб:o8Rх,U јф‡пІV8ЛЗЗ2Я­гv6€}юыЌfмя:ѕћы˜ћњ,А>ъэbtГљ}ѕ6зз9— ј."Џ „e5bе[Kе8Њ~7КMЌЛ}€:Б …ШЖQ[вћѓiЈйцєњ~qИ’_йіЙ`e@GFЈˆЗ@Ё:3bхХ(‚a8ћ Fx6Є0ШФЦ АSгˆ4HmHч%VЃІJЂJan?П H›$€ЬНѓн6тЙ&'\˜@FHЏŒiідЃCЌ’ЬЦоUъЎдM‡ š/€чВ: lC\Ьхф=ЋФ‡šР˜ЬЫC]0š—в ЊHRІ!0Бъ LH ‘Щ| fXoL`Е)ъ@{(яРьСгŒFp“ ˆЂћЌїSн&S‡ІЉ6Сv9Ћ}@h$ЄUМw'ЊQ&Л+,С+Vfˆ `&є4„сГЊ@‹ІЙЊРзОѓ'888ЈИЭ8Ю8=Хњ)цЧyާ\K&Гє{qмŸBЉC УъcŸИЅњРОЮљ$ яЌƒF„NрэHL,‘0n3Qqžc=šM&Qqмћ mС С$ Џ~Р—яПKё:bГхЂ_ xпwг—ъ#–/%ђ [ІЈWŒgЕ![цЈЗЈSžйЉ‘ьz‹>qK]ВъЄ„oTзиŸ š!ьнO@‹ъ\чQГG…Ю*‘ћY ъ†ђ}M;И^ЬHGœЬЩ,s…A˜Ж$†jеi€BKАaС0Т€щъиrs„Ч’œB[!VpžŒIIѓ‚ТоmCUMД D•`IїKЖ §р'ЋГ#„С[6(Дмž8<`!1;=ьЛ•РТЩњ”GќћЩ' aLЂaфš`РXra™цёЕo>ВЄЃHђ|BрО%КLќ]Ћ›]тЄ™iKнТ чЯёX%Њњ‚ѕЭ№мdФ ’"‰иЄЗПя§t]чќБ@љнџЅ_ТсссZ8­ПЃ‚ˆ!CDŸу(P!’єkG‡cПўсoSо0яšътКЙl@€A‡Р)СSf8Ё›Bцu1Ьc>k.LМ0k‚НЎ3пh ‹ 6рЁ?dзYгтž“i?дНtАр6ОМЊЉѓчџ­ЈРSї<‹F=_^XSЄЎMjыZ a6žYZ;q3„эЬСUжTŒrR?Рu5+фIЭ9Ро">Щ {:< Sђr_В2‘хWіm‘ƒ'эЖА „ћr|§l0иїсјн аУS0ЌgТЊ`P)Pи‰rЎДMЅгсџDЇћŒhd С Щ5nAžoOУэЫЇсљŸ?Ќ=-Ѕ6€Dп9еu(ъ‚ЋCщЫ|ЈЩю.jZ@Eр'J/пђіъTƒќ­ˆŠАxЏг\~s–ЫoОўЕ8=фшЬчЯХЇg]ЮЋ=ШEЄѓСіK}xњƒ"тЫ fфQTЩФ1ёЯМу+c‚ЭЛэ.Х&FыœЭ~БН~}ыАXќ§мG —ЫЅЄМїїїЅЭОз1Ў’ЂП!ГћчвОЇB[УљAk{д7…>o/ЪB~ё‡ѓƒ7>З+мYрХ6‰Оxётˆpnћ€у$6ЦѓSтœ(Ў#"сБpџюююXBц†œlгNпї(ь3Ь“ZњЬžj€ЦAcѕŽу7cvЉwИн@mяHЛњ||QњЩЎнH:жŠW‚›ж9›ьл9Јф(KйяHЌ7gіZKbP`Ќг„!8Ц’uНЇѕN6П„[”€ ‡ЖЫIНƒЌФ'9УЗр 'ЉЋ€Ш•фрPу$йœ`|=5|Б9Л\\ъ"ZћъЅ6ЂУЎk˜,%˜|5ЮYŽшZ“gd 0†лJŠv*НEЗрсpW=JіМ…'˜єС@t§ ŒHaчыМxs2sK@і474Ђэ“щЯСmлˆ88;бщ‰і"†Ž$dbOІЊЖ!Ю6|§ќы+ЬХ8~ i^;ь1ФЕm;‚3Оц~‹sќкяэ“'OТз№уэЁ€gФ’%8"ЎG|їЧР 5ЬїyWC|‹ `Gh+6 ѕƒq{зƒЯщW*ќЙ jьޘЭип.фы•Šѕ‹В3‹€§\v[П(`ОчЮГакѕ"фZГ?ўЮ1fў>Р­zІ!YtЄлсLеS{ŒNєq…я)8 6Џ1:В аФ`Q4V1 “МЩ% mЃЗ4§F™їu#ИГAœH@нх&фJmG%yЌќЫqŒуж§œHA”ŠЪHУьžр”qwяЏNуЙiЛb„ЎMАv яoc"$:QsС(УD“ЄmiИЬ—і4N-Nq~S^p=иŠмdžјь­k? ]#d9Д1tMл\МЭ5‡9ЏЙ84њ3O:gјъl@Т5›хЧггcУл‘AоПуXєѓНD+њiУ:ч; вћюoО(и,Йњђтжbzѓч[Чw”k?acвпЊАkэŠћ!`~ѓna›ЕIЃЯnЩњGШk(@АY‰'(рamš(u vЃ†уП‰˜@`r‰лЩГ,Нfс6„ЌžИtынЄzX\Я№д“Sbœ1rЭgН8ф <Уди!kЬЄIRe+6 ОЎЗoЃ›)јзюіЉ_ЏпIзУ ˆЃф‰Qњ%’”ЃАz›ЕиЁИD 6Юа›щRыМбiёt4ёђoЉтЏЃЯ*Уђ&ЌЯƒ Ђ­ы<ВМџ-Gк)8Ж,хђьЛ{ЏBRg2‚ЏДп•Аў——Чї'їЎ‡чJ9ЫП}яsЧ•_О`ЖщоRn;f„џЇ”Ÿ–ђХЫMњПlK”—ІRLоIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/tag_25.png0000644000175000017500000000261711733011756021710 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<1IDATxкЌViPSWў$/!B‰ ‹*Ћ"Љ VAаКNЅг:NkiЕЎLЧepЃXeŠ]ДжJ-.­:жБњCFБU)CЋш8Z—Ъ"UЖHHТbBX’зѓ`SЊ€3Н3_юЫНчœя,їžїŽуpч-Мфр‘„X‚„Fа9 …žrГЈїТ‹9ЂЄi:!ŒK$Ћ ‘i'IeУУ№фLDž>ѓлjюЃ§dы/gЧEq›XF,=ЋŸх>&2m$Xя ˜.€сќЗћь–Ц‚F0цœУfYBђH­и9ьŒUƒcWD ]uЎƒМ`̘…v}9 чіЖtЋ?'Я ЅЖЧК=ђАY’юˆ1`ђЪŸRГEГ ЦKYh8Бцќ#p‘КC:єу\щАqRъ4’Ў­šеvkє'ЗСob$†F”mž„a~&7]O“#9$чхПќ@EТGћšнbVаZSП$Є<оmxиژдY Џ Ф 9r9\X=ЊП™IpД{рЧЧЙК{С#4ЭH‡„јYJ G“‰Т>гE"ЦUМЧяН]ЌЕђе!ž#G€KРА,фA№‰LЗёhяbдпŒ‡is`Ћ.,$Š75š,SN_=hT$j&BAЙf‰@,э аЌ‡рјY<вЂжАVм€ЧXЁю3њЌ Eс+VљЇx/мcо!Ат&ШЕa0єУёBџЫu)а$QKбpч>”СpиžђЋ§~“fоG›њЩ№Ÿ9™R$эВ&сй3OУ7•”Q}ІcаЈ(”ЇLБгrъ I(ЉВрˆ•ЊиЈ=šхјHМ}џэy 5 †mm0о+G№ŽC0]Ю†ЕєZ \яЋ&Љ>oo[ЫЎЃ!7^Џ†ƒ‘P X7šн„ˆК№ЯџЦт2ЈbW‚RŒњГЛ›ЩЦ—/МŒХR*vœЧј8дл„!sfУХM†гpЅФ 6лмЎlю""rk­OыZЁ~#Ц_ПGћ“ŠяшіW>—„ддфЖy/мJ7;bїvШУ& їZђnTaьшДt0HЩИ ЭBѓ]|Ѕ їУѓuqя(zG’Є™ЛЮŸЯu§™PFFЁгUŒ‚[UHZ> ž*v§p!Z?L‰%DвTT ‘*ђ№yЈЅШ;[Œј>ж›ЄЇ№ќЭNTЭ\-ДeD(d#Р1ОјфM:= ~ЪЙ‰v*єъ„hъє аŸџAŸ^Fcс)Дќ™{ŠrŸwT{H>ѓy'Uт ўФЌЯћ Œд ЊЩS…гУЄ№ јБ[зQ6_Н ўR“DUЦG­ДИЃЏ7?вЋв—<0…w|2FІТf`Ё[ЗЭХEТMзj‡Bсх)мvЛ!џw(Ї%PБ3`{tw?EЁы$—ђ9ЉюшЦЏЌЕД>М‰€5‡1"љLшP}8–‡DЦ эФtЕО‹wB$WЃсТ~щяыГѓяјлёŒ0w?~,K™jo)ЪчјaОr’+Iдr5Ys9sоzЎ|ћ a§qzGВяїш:Уйцœ„Іђ+wХsЖкRЎЃё WŸГ›г}шУЕмН$€і/=`Р$NТ яНЋ(Џ9ВŽˆє\›О‚уvЎ,љu;эMў_HКїн k‹–ље7\ЬфŒ—Гљ(ВћбyіЬМфw—www#L#Tє%мѓ™ѕЗ(ъДXЉМIяIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/redo.png0000644000175000017500000000037411733011756021556 0ustar sylvestresylvestre‰PNG  IHDRрw=јbKGDџџџ НЇ“ pHYs  вн~ќtIMEв -4ƒ~E‰IDATxœc`Ѓ`XƒџФ(bЂЕ%ЄZ№†}lТВ ZТH‚С .af \l lьЌ œЌ ?ОџfX7s?NГXˆ1м%ЬŒaЯЊSpС tG†?Пџт5œX№пмU4(тXФЈf81в- д J“)UU‚bPX2 FvВЯ''\N9ЮIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tag_16.png0000644000175000017500000000156211733011756023344 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<IDATxкtRiHгa~ўЧnїпцЎt+™ІhfiEefЅH ˆВOбёЁƒш ": H;ОEeв‡*+ДEб53:ЈVй6sk›лммџx{%Š2{р§№ўоПчљНЯУB№'>X\І+Ќ<Фх˜ЇЧД УСЗ>ЕmТСЂу=wшГˆQ`џММXХ `иN^А-уMЗœŠо&тp'‘Ѕ‹§эћ&c №]LЮ–ъѕжОѓ-0–зBу,œCO‘~Ъ\Ћ"f›hЫжб˜_+PіRG§ічй?ЇЪМ„4”ЦPR cY 4љS@ЄЌп^ЗеѓпtžŠ‹ъМ‰œ№ТTRŒмЪ 8ІЛОйŠь7?8ƒйђп(ћZWгЩђШЭ6и*ЪСЭДJ F ЬXJuBіДwwžФгдАМyЊ“ѓі~$р6ШЗњТ™З(ƒіMп+$œ|JˆФEˆ]]p4ьРгGОdЋeo>Чbb,ƒEЁцiyTAњЬч”ж\чЋ9ti Е+ЅFХуiИ_0~Q3тОNФZ…т0аЄbЖ œR L:RЌgф:Vэ(˜Ххф‚ЗфС“bТ8 цOsСо€ЦU„Xn)МЎ>!Ы2є*РidЁSq5‡I\ЃЁчqц“ЏЪЖЄХоŽtЧ9hU „Њ HіоCїŒЃиuC!6Н.wѓ|dˆсу`0CХNієo}k49e5GLsVихдwа№ щž‡S§ pЙвЖj|HСжх‡)”Bƒ Мђˆх‡ыл„Њ†fџГ‡Qfн9лу>рZ/P‘є Rлш iњOнЉO2yТ<_ЩŒЖЖ$nцUJыЖ~?Ј)GZЂYбRkрь}}зЯl+q0ЗўQ0‚Mdu8Љ,феьšцj˜ѓЌ@2Mh€з х‚ј~ЖG5ћиzDјБвЕeЎа^йxVyŠrm‰,СюfИвР мМZ5№9ЦЈGТ6І‚ЗђЯкоvbeиІ@Ы3"^‹ vjTц№фL# Žєќ`.TDg}ƒHIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-sub_25.png0000644000175000017500000000346311733011756023664 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<еIDATxк„Vil\еўо2Ы=БgБЧ!všИ†`Ѕ 5uЊЕRд*ˆ–$ UЩŸ6b‘к$‚Ўќ ‹ 4ŠвDќiTк"ƒ’”@œ€%СŠРЮCтн“ёьѓіћnЯ}c‡4Rе7>Кямх|яœѓs-ЅЮbљ™;мКК§ ј?эћхsЏVём@ Gі6c…іщіѕЛn9NKьњНж1tь\ч|7ЩФє—^$y–Є•фЏ?ЎзŸ­Ъщ,oдтЅšЧ=Я›є<Ж—ѓSI”$Ж$QЅ8єћн}я›ПйѕbyХОъјѓ Љвз:•р‹'љЃўБ„ЛОИ#бЛНХZжчŠЮЛЈš{^ЊЂџпVЌ)"oэH$ЛŠебЁ†АжH1M&~|ш” к‹Ни4|л€сЎx\ HGdШДk~q*щ!­ЎћяДvцSЗ­ g?яЏa&пИ#Wjию0жC7“tЪ“wцm Ќ)hŽЩиПГ ‡wХpyінГЊКЂH0l#юƒ6дuEЌр}›ТјУƒХђяж ‘~fЬЊД|ЇЂыљVrbм–п{W.јиСгЏ82dЃ=оожA.х<$bЩі‰‚­Ёю‰Xя=7Ј8›9;МŽЦpTё=Ќ™ефСCУ?нѓєOа"\ѓOмЦ“пдагЁвAoO0dе=Њ!нєEV"Ж$@пaL‹жзв-ifЏФ^1яq5-хr…ЬKэђB•яййgт•†нпуў;фЖƒЗ7ЫdTТT•C ДІgu@#]Vъ9сœbhNііN2яЪ…<)Ъ–iЃ\) f9е€37Ж)pщрOоВqbмЃмHИ3­Ѓ+!ћЩНp…cз1 АHЯњ^@KeЋ"@лї‡йю^dfFpafЗi=ўѕЩQЌlkGOъvdц†Бiѕ,Tц08~-‰К;:‘ыoE6›Хўv ‘'HeЫYLTЧ1VХцПџ пzў84S‡’›ЧєўЧ№—яэ„nVс†,МrbЖkavь".o+йШLНАDВГ­Б‡‚ФˆBьRШјM‡A ЉH…€xS#<з„Ы]‘`LRВU˜Ž 5Ј ўе цоЕ j­Ћ‚zˆˆh!Ъ•LЁЌї-Š’‘HЋ˜0™ёE{#у„BКуЋс.2Ю‰=‡HЅ+yDSЂщПэzЩпcл6єZ Ѕ+E\ъy#CcЈ=‘вZJ0g‰Y_€ е<ђf#žъ~БІ&ƒArвƒKm1V?pK’ŒТ%Z#&ЭЬЮтќ‡Cј№ОƒbњЃvУщCќђИЮ=[ШТ~Ч†еiтЕSО1EQЈmˆ>%# Њ‚†CQЁ‰оžJ!кС…}š" Х$C9ALKxАcWAœЪЫzЃxя{ЕП ОPTЊPa•-THоУB|p’0ЊдЛDeл}Œ2y†nAО•ВAм!п=ЕяNQ;ЂЮˆHЗ%9BєƒЯljчє‹D"Ђ`Х]RЯ'…У&КZ–‡Ц›КЛ1ќбЧЫ,"‹’( CDЧЄ:u]]к! Y:џС9ЄгmˆFЃpЌјџј—HфK<'NМ‰‘‘‘хiQotKqЂ/XФSМА "ьЙЏ рЇ№ъУ—зŒзП/ыіRЭQI№ˆi\™ћ9XrN–зIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/reject_25.png0000644000175000017500000000315511733011756022407 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкŒ–ilTUЧЯНїmГwІЫt™NhSАЂ•а@„$$Ђ ~!Ф/ЦШ"1HHH$.Œ ‰%ˆD‰ФF4–ФaГTAЈ”mfZfш6эt:Ы[ЎчОз! C№%7яЭ›;чw–џ9wчt\іTS]Я2U]B(Ьр `š~>==aцr >я33cП[™ЬБЅ“йјƒьJ3нkк˜ЫНQ К™ІЮbЊŒgОДLАђyрSS`хІ@OпstфЂ5>z˜”ŠКЦГЩ‡BzзН№’R[ћІ -мn Œ˜XХ№R /щ@LпРs90&'РˆЧСЙнcŽ|В [ьЙлІtї‡ѓы7lqЧboЋѕсFцrЁ шxŠ@)NˆН0uћ{ъв€i (š†ЯЛ Б‘ ~еџшdёШ}ОW6ЌwЕDЗЛ"‘ч№"GЃq к ј aЮн~Цd0ЏЄцf0(tшІўЮe›˜›5нќБv]ЛiкЂе74Ш>ŸmŒы–mгЮ)>„VЌRššМruЕWž,%тcйЧ5§ЦЕFZіAUE"Р …Н8Нљj€]œ3aкцvmТ=!@qЛa5БР–…љB.пЂEхЈеhДJ,п’ЅPИєїРш—{ы`*ымNUhK Ь№jžLМˆл?ЄgЛзЬ•Мžgd —— —я ‹’EuXџрнŠђдц=вZПsW†ižЌаˆˆJђy@5[8џќ`5S*БnЩуnЁŠ‚)вmйwБlw’;wTБЊ`4ДqѓpR$B,%\r0艑­ ”I‹Љ,л)сBIXl(свQЎe˜n80ь‘Сm[+‚”жЖvЕЕѕ:E‚P"AuЪс0HЊђ$•\Z“$GЊХ’ №/^œjкДХŽHDУEOЬдIдшжж7*‚\ЫV–(jœaTЌКЄpx!UjЊФ/цэІ“kk=т]dћ•œHАF6dЦРLЅ љмъћ rk[’ €‘6(У )-Б˜„#ТиH\b3’хЈyЏЇќУШЎї!ёкЋ`eГ` Їpœ@aггp3†–ыщ;ZЌБ._pЛ€ MЂШјьѓKХk46;ШЄZрvOp03™Ќ Ъ?nоЛkžФ”щЈ гFQГCЭUа˜Ш8cm8=DJ…(11эЙЌг;Ѕњра #ВгbыRМђOцПЉh§Гп0nй†Z•DўQЗЗcеіуЗ_“LХ1#šЃ šŠГOКINЧЂћЕКК О…]@eF:J3“БУпG*7о6#S1<e6ˆJ20&цš3ч.”fY_Q’Я71зz"Х(ѕѕAсф‰HцаоJhbl€ Т:Šт2Э’дэцётн+ъ дчъёœ"чТЁŒќэQP”ВШЅЌHг‘ЃЧЎkѓ;;*СFкыб{ЩI ‚D3A3Ÿ‰ˆx?)VгЉб›и пёбaTЬ†g€„ ŠywъщхбЉoО>S RгŸBяUœUzюѓћ€@U@ƒAlHїЌчєUъŒbы 5ŸЉх4хІS`НфыѕЎtзМ+Й=ЛЯъНgёа2Œѓчn•Ž:ЫUЬ' хдј(уаPЕœТшінs2ізxVЁё:ŸйEsF<ЃЂИN1qЮЁчB9˜  F@А6ыЦХ M@vb'йsш 8GsЕфz(ЗоCќEИˆЦТhPЊЂ'LAb‰œ3—ъ€а(У3HDAALтhњД И"Ў9cЅ#”№mњ‰rЇDЖd…эBKЮ™aGƒ]-"ёњјЋ„l{!7Е‹ьўbїCџ­м В&ЊH/SFзbtко УЂЙ4їLаА(r•э§ Tв/xF>оwщ§%*_уЭо(Іm9жЧЕм‰іBˆx=ъѕ ‚лгъ:Mх(љќлKВѓЏ­щkЮ430зIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface_64.png0000644000175000017500000000730411733011756023076 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<fIDATxкь[IŒ\Gўпв{ї,ЖgbлƒЧ$1С &D РRФ‘S— Žqу""qс—мТ!A) ˆƒ ШYхXФqbb;Ж3ёЬиГЛїюЗUёџUНїКЇ=‹ЧЖф1=ЊЉъЗu§пПџUЯ’RТќqЗIЧшŸ…ЭСfЇz[_ t‹Јп‚0ёDW[[Q ­!6[›Зp4С%lУиЖщ>ЋЯё5lЫдoElЭy"z'Ж=КЏшѓ lГи.mQРPдœпѓЏзХЫз…NЗѓ №йф$œПp^ўУOž!iАЗЈdД;m№|КžЕZf._†BKХАЛ… )иоЈ7 Шаюt`qiцччЁQ#лщš­ б•ЧVЎеk,ўЭffgч QЏѓ˜Юб5[HљџlЕZЫВсjѕ*ЬЭ#ДлфYJœ­ @ќщtЛ „`§ятиG[ARџ…щ“{кхЄРЖmpl‡лэј*”`їи8м=пМџЁTќГD8сц \(C>“П-ЈŠ0Zк†@Œ@>KС`АN psм—ђ%*уƒ*З%х|FJЃШФ!d"P]љЌтx![€Ї} ВNЖсƒВ™dм PкEІQЧ"Љc"c:CcЉ>Lzђ}дѓy<&щ+тcвТgкъЛД$Жˆ-ј;їЖDk.A8‚{ЫЦœЧСkёЯBmЕј: ХЌ ;r6ь,й0\Б№xвV@‹|ЦЭъ„ъ3‚Х|‰ћ,@jБ3PШcл@КnЪk"тILлk@Гл„nи…9j#wˆоJ cБФ Ш Д.r’Ц8dŽSbŽ=1UPšN'аwѓЅ$|—фуц~•їZšWђxŒВd§‡Pџm”+C|O„#ЂїпГО0z7TђeXn.УЙйГpfцПьcM•IHСуžЦ„$Яуk-™Џ2лОъ?AНq2 Їqьbсяч(0Фи}ю9;ц>8ї:FЫ0Rйћv?cхqxџт{0SFЮЪVhРКЏ{:jl€P…K—LЈЄЂ S:/’œ7Щ6ФyњЃ'Ъˆ ]ФФ?8qžиЕрЭxr(.н*Ш™ї>ќ#|ѕў'с№w/Ољ|:F%4QšУ ˆЃжИ,!Œ€еAќE;[ л’ЗжЄ?aђ4ЩњkŸЯхс‰xэ—(.Y`…]8В:‰@!9TЁ‹џDюТс=п‡Ї>7kХbš№pdK}Р5‹ДkЉЧzje<ТРP8 CЂ€EŸ\MъЫUx'"чQ=Ў~rе@њh93 €Єѓ!ЗЧфnF)2Ќ_Fт› л‹8Џ` ёмw/Уоћ ліH“Н€ъяВ 8žЈGЎ8З€воhM@F< ˆХf v В5—ˆ}ж]I<к ЙNŸ=Њтƒ[tО“s`iГШ‘žT>@Š„ “кcхћmОuƒ‚5wА DЪj  ‰њќљвД/’ЯDbQчsйФKlііУpьФoС*иŠѓ‰/PА ї5с–Œc€~ТїЫC№•Тc0žЙ›m“q†Dq$;EEŽХЅ%˜^š„жA4Ьlв XфёŒ!ЭщнOо#?|`ъпЈ “‰б3Moэ8oœМ“‹aќоэ Іˆџ”ŸgŽcь/ЩЦPмЯљ…:EкPRьРL„їУім]0:2Ъѓa%{$LХŽЪPJ•<œщ€|И_Š6 €Š8Т ЏОѕWxњЩчAџ=@уќJтw>ж]пƒЃЏ< хёи[RKФbM0 RˆB$Тt•zaЋ$Љбј73‚‰гЩCС-@ЅŒМ—‘Ш4mєм,Њ$Ўѕz Ќй2јb]xp}(У‡мАŒ (о?œcўЧіџШЬ\>‰h-њ/АЦ‡П;їgPГЊPмVПCЯЂ@ ДG‘ {(Ц~ш3а^шAyo‘А mЉЕ†0з ”Z­žзEбї Рћ‚TЈўSSгpсТE˜Ÿ_€бСчyзq›$€PІБВф щ'OТ‰ГЧс№оЏСУћО Лvэ‚гчNУпўќ;ЬЮ@yћ”ЪEжk А‘Б>Nв|&†ј˜–ч-Ÿot  ~Шjвl6ИЊыћїљС@ЫO@ЭЭЭСтт"TЏ^…ЏkЃ–СўQхіJW!Ф’hŸИtо>ї6Л: 9ѕэи7.цтdсЪ6зcQЄм ˆ:<)ф;)4/F PIх§aЈмяє[Ъ„BL‰ен‡вЈ:Arœ‡з@˜’etD?fW…DКŠ9вЭ,У-ˆPф6"жP|Qщx7j#0О*ˆ ёk{*Я№BСњNO#б>'Ўq}~оИQ6ОфЭ6cгФ„NЙX,аnNХ №”ˆЈƒD4@œ :ч%WyT0EЦяуxќQЊіHЎQХЎ\‡sп@ш|MАtАaŒ`:iсБінtm€D{ЈпП=яwЁt<В!Йm‰+$u"ШХ™ˆpёДЪ Рˆy\†3œе­ПМeTƒs2Жb“„ьћ-ц‘žPLИTКJ2би dр“GX‘ђёЬ}]S„TЎб_4™ПuН”E†№*ЗFЃ9Pєщм•+W`iq MZ/mЪџ™ћ–ж%‹+xŒ ˆX$>TтЮњэЂсsBШф"шд%sМ5ŸHKёЁDТGюSЂN"П№qoRdԘˆšžž‚%ŒђhL‹ƒ$–жќhэoQД9”и[Ќу'UЩв ‡л~‹k€6‚+G ЊЙІБX Ѕу З ‰XЇХ{іИRc'ъUјєгѓьўfЏЬВ4ˆўHŸэћ~’ї;АY@n„Ь ЖІ8!u P(p!Ўw‚ы~€–о”НA—І ™!ЩEM:жœOjF@gˆ–Щ aeŠ|eяY” t&ЃuеЌœ€сoD› Š”Ад˜ьщwЋ‹\ШНL<Ћзј…ЎюŠ”ўRјЇjњ ЅN‡MSDЇ}њіC‚­>зјymW}{–œѕ]{ZЕГ+Й–еHЫЙŒ—ю‚иiH` Ÿda•ДИЄЭФ{-&О‰$€Є‚цВЖцМдм‰ЗMЕWh ZЬФUˆСˆc|Sрд=Ш›ЖRсІУ_Sg}Ц€фљќ3yЁ",ЪИ(–OћZЙТAOрbŽ=ѓвxќТw^XцєTЎ†Ц­Z­СќТ<|~щœ8ђвЕн? Њ%Ќ€e.za„ідDШљVЛЎуB&“Сl ГВbQ[Xќ#ƒ"6}ьПx}епрG1eff.MM™Н=+юЛ!ыmoўQзЧ„ЄЮХкTрКŒСбЃGWL’д%^<ЁЅ:”ЈиКњъИ.W—hЕˆЄЫЂхw|ІыиёyкСс86пЏЦŽ:‡зц|ПS’гj4Voн 0@AL3пd}­жЊ8FGGŠ(M2™]“ГжрИнRFdХљўh€haD.№тkFмХРg%ДЧ$&а…>А‚n>ѕvэєˆm@dDПЏxi&JНpЬšnФm8ёyWВФp<€R`ы’!Є­ВP’М†ю•Ж’†NЇMф>ѕзTПYь]6|ДЁˆшЅz[+ФŸ<‡ЂK†бвЧLьNБaУЋLZЌmMнCDкК1PЉstLъ…д<кž.N1в!uПнА6Ё1ѕ?ЕV<хЙ_џJЦ %}№ФIз‘sф,5ОŽsњ(ьБ†јs?й­яi\ZЈ­TbЯCПсП­Aэ1к 9іЧ|ыЙwојщ†%`CЫMІ@mь€.sЋXMZcЧ+M§ЫSl&lm8БЇ­­t}ŽJьиš›БBt]єЏБ‘Ё$+ŸЎс ‰ ЕPъ:KW~uJL`EЉ‘\ …ЛоbБ„У‰СЛЅ˜РЇЅ6^SВnQPd§Іэ‡RСў=Ч}кšЊГЪ§UtHz_Љ”atd†‡*Њьзo!KЫЫlG††W__cCfХЭ%ko%zЏЄРbтyїˆ•ьѓш]*K _Й\‚сЪQ.OЯ@ЛеюйрxK "CЛе‚>јьоН*хЪšb‹ёњ*M”˜о9ЂoQіРцc”tъдuORьaЊL1Gэ+#Н.ШїRЁaћS'?фЊŒ7жЅ]Ё•ZРфњзћXѓNORLUЅz­5Ь)ZШPк. ъЭ‘hUшFЊБ7ы v…ЗЩG€z/ЈK<$)&FДjдIьежКЋpќwoЧ§r’—Ђ–ˆјZЕ ДkМй[N[ЂkЖтnqН1ЫRŒФзЋЕўышНЁšЕѕ^œамQЏЮІAX;ЏЙгпПупњŸ"“і™o1aЈIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/accounting_25.png0000644000175000017500000000150411733011756023261 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<цIDATxкМVПkAўvvoя——#ё4‘ Ђ­tA€bЏ6Šˆ‚ПB* БбF+ [ё/ˆЅіbD›be#"EcL+hЁ—рЛйз„Р+qВIŠqЦХ{Ќ~Йef@эИ хжЇЪќ’œ W"3іŠBЎ<Љ5*Ћž@п€q_–БА}Iо›оЭЫщLk1S'LЂMWРдЃoъzњj[~‰œџёпѕG€Ф1=†FѕЁIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-custom-ref_25.png0000644000175000017500000000267411733011756024662 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<^IDATxкЄVmleџ]яњоЎВбЎ[В1 †m‚A$МљfBєЫ˜AЧ$j0&іХ? šQL0&‚–Хd:В ™к,FхЅƒF‹eэК•Ў]лЛ^яЮџ]_f7•њфкчї<џпџ§ EQ@ыЈВ\ŽАФUљ;aдЏПяя§тыў,3?mЯѓŸ™L&ё~pГйќВJЂИ6yБckС*bf€гŽkUQёэœ)(YŠяиПŽ.г‡Q-'ќ#Ÿ†3 cчŠЬщtЎшœІH‘%Є2ЌfVлЭЈИІAs^КЏœФНH’’шОR<Y13'ЂЁЎ@’Z4B=ЕOЮ”‚Еˆ“иJ$šЅъu…ЩЋ‘хЂ%‹–*‹Ц.Хећ*y!eИJrŒbзыь…”ЭBЩх-~tНПўvйыЌh ўтџХщы‚šxЕ ŽOЯbЯЙБ8!^;”ŠћЏћј№A~цлs™LцƒћС™b­лъwW+ŠДŠД2zv–aXŸегЃеf*јЩ2МвЪ]zЗj&8ˆ$.tŸёœјyЎRЗє~‰Єњ /ў­Dz>=„UдСя@6е~СЌ ШN_0Ў}ЊBЊГўБъѓ_‰ХfМЗжё!Ъž ˜ЛU‹буАnЧˆ§Z АWл‰ƒюWŸ)tЋZпbкž=†љ0˜еW@ЩЙАdрjY“ѕтЙ_Š*IЦ„и•К€шЇ*ЁJНгљом Ž Г‹Aј*Еѕ$0Ђч ЈЪДК‹‘хВЩ4/Кжю4ж6ъ гJп %№Ж–/чТђ ma,LЇœRОЫоЮpN]ЇБ™Xпё#“И1шЭф^=ЕќjРZIu>Oћ&\шXНƒ ]:ТŸws‚O‚œVœ†Ж[яб™™лLy9#Ћь д8 rTЉ˜u ЁоГ›К`А@ ŒAјўє‰В+ъ`n}ИR(П*\`ЬЙЉœо!2‹ƒроЂ№IŠyZЫ‘tъUHЉxЃ ЯZp7ПCaЃevPwЬ А;ŸУ“žбFuй:yђ$’Щdй^Љз% ејiА еК`щxўЗѓPHѕŽ†`Вiљ‘гqc.8,]ЗЗщўЪbj.tuu-Ђ&hЉБЗ€[НYцкЖеРїMоVЏх„z‰І/ЉцŒmЪес/—‘ƒAЬЭЭСыѕbзЎ]х ѕ Y }‰Z€5V mІrZ)—/ћ  ЊЬЪ‡hf)TœЋ4 }>іэ뇉‰‰’ЮббQДЗЗЃЏЏ/П‘Ш› щqPљP(бБлyх"yXE<ѕLšдЮG2В(dсйpD#FOOВ4р–Šš›+WЎф№1RЩ+tQЩVRвЄ”ЃyeЅP%)Œq"ЭqQIHяa]MTЙojееббЉЉ)MС`@ccЃцбš5k088›ЭІОс œz ЈmR“CсКK7ХМGjпˆдё‘„БГм-Ÿ[žЎы.Њхdzz:?$Iйааіюн‹ццfŒŒŒh{E‘щї"№#Н82jьhƒЊ)AžЈу=k b Иdј1Lкнe$ХнКu+ZZZ‰DД2ц8Ў,tВБz7k 2'”ДГыркЄЁ˜ в! Ќ’ђБХ{šЇг‰p8ŒњњzmГЗЗwfQC;0уHŠ˜Кi‚H,AФcЏ!q~#UиЦd›`нП‰V%TњKєŸ:ўмv—В5р Ќ‡Ѓц˜ь§hwа\œШRuј№њ*luzrІЭHэ‘ОдNцќQ:w>”‘Ђ"’1TТhQ+aEDБ~іуГNяћњй+^ЖŠpю‰ŽDeђЋсhмpлЮwwТьЏатЇеЊЊН>SЋрїWAUdaA Mэ‘d…Бs”п=yйdŽ0ш !%Ф#ЄˆКQFnВЎЗGнњ‘‹ч|/mсшX4–Ї€ВПзqє~щ›;ЎРлоеЈЩЉЕК•щ5#|UБЯ;ARkѕ$+FVЖьЁ„зQ†.” Р’d1вhКa a”эХшёНOЌœїМdмЂ!w‰C)сЗ) ьяYјЫMЭOЂџYOнѕ)TЇзђБЛ. ›XФЉоЙРDсХСЁЫ~ ?ШЈЭ{шЙЭ.DћP Ѓ]ш„ЉFхЌ~эВО/œж”-ЂпІ„C)`‚№w§їогЖН^Q­ШГ5й ЈLЋ_БL_xёш“рQjб€ч:L ыФ cњXŸ'ќО#F o*єФЃ>w5|NДП с0ŽnFсsЭтckџђž Ї?s8%LЂ$| ПuGјi„ќшыѕйuЈЁх^Ѕ„asQ''<В|Œ'ёxŒ#bЫ0ДLп“П5ŸITд]A„™–sЧ#ТнЋ[Ф„„сt:D’њ‘Џ}Ю*ЁYRТbœЌQђy‚§т ›ZџTЏЪГ{њhЬEЫЃП{ТBЌ№ЩtЪ„‡ŽЦ"шюjBbу8ЦpОfjOе ЊŸBр3F‰BVаСБwДђ^ЁІ7@4*!жјнbb4Ща]’F эfLфјгЫzЏBwxС"9ПС;Hœї,лї<ГБљЩzUM–Ÿ <”`oСФ‚Ї(x„PФXЭhш­vЁDаЈрЈХікa =Q*žjШ gЧ0­П лvАq;rТsCрЯoКЮŒб!iЎšЯuЃЙТtњўёХЋКї‘??oкVЋr=ЙИЉSzЫ^]™8яB8„№(ШЬў1ь‡@E,ИЮ2Kz’АаIS,j’„щ%№ŽwМЎНіZFA’рїqbалыё<ЭR.†2~^ЪˆъЏЧpкЂ6М~i šэF_мc;ЦЁ‰a34c<дxФtХ‹jUФЛ з<ѓЁ'GWBaЫ i.ћў-wя9 Ћ­ 0оCufxШќB”ЎvЁŽ`Т“ч Ž фC;I3RIBаNђE1+ ‰ЭбЙСœ9sQH{_j„tˆaE"Сап›Ež7+†wО C Нu?4ї‡€QZXcФ…&ц­Ў†аЏ@T­RXФДYПѕуџњвkJЅН(78j{GЂїVyLЕsћ)5ЉIА'њH0М‘№3ађОLxrškx:MXxgёШ яЌ3"вќqgœёš-P*’Д ›Ž?H|ДЪ"ELэKсќзbM€жo?ЗBLДА@‚ Ѕ•бAДQ]T@„UЂрИс§ё{ЫЙІДТWoНwшLdЫ7rUGЙ=f|ЊDѕ.щHЧCžp_ }>шВХ ‘YШ&) %ББ~3Єы N EŽЭя zH‰iŽ уN‰EžƒAƒЖH[8'†e Qб(4Б~€њЦїЃ"’ŒП”I­Ц oЙ№§Wl<У!РХќъаОшm_NЏbI`UчOш‰)gВЗУlO„G“ЅIв„3Ћ„$‰эа† щiždNРPЉQRn~Ѕэ˜h љ+!D$\hI4ЄJкП3XхvУ–рœU +<н˜eжїё‹pw‹ГН†vЖтЬQ`‚%EŸm@ЙЄяёнћФtT€Ўq(ёд„n4нХ Ю0eјSьwLOўFJˆ“дfe‘žCœАа•%˜ c!с„TxЁЎЌт L$АїйK“18…ЙЈaŠsпœкЌI"K$ъУ№uœcсoОч–цњ<4j Щœ_коvопЇ+*РS&ЕНџўСЖm[Й™Бwя^XА`!\єЇoБёНАМt“2с,М2.‘s€cџ’я%xљ=žbЩ Бфwѕg> Я?џ@ї—QP„CYzžШЅ№їйЯ}ЮђpфЖЁИoT›МCЛ’ХZ‚ыJзЂ#-n;ХЉKђL“"д25F[‚CŸK€ЈJЃˆ`RXc%јјl„vАgЁNd—G ‡vQ3јйElyЕЪ…Б~тЈТ”Ќ9#ЫœЄд$b+ˆЮ=п‡Џ|хЋАrхЅ8YnПэ6ИјтїСгЯ<У“5‚+ЃР6Ђя рS5хS$xєЅ­4*р||ZrD"$аЙТЈХЯB]I iлHq;Ю“*hЭš>QYНТ‹Ž;‡ЛЧzчЯвtf< sо+Њ:i‘ J1\йјэy>\rЩ%pѓ-п„ЅK—ТЮ;сВU—Тч?џЯЬ1HУЫSi'АВ|bЇрХWhЩ ю­AЅц­ІљВžJdжѕ˜ХKд†иH>бfц˜_p6HДаM№X fАu—2љНЋчlLvUš˜TТrŒg…Ш‰О-T>yњ~бЂEpгЭЗР‡>єaFУwо я~з;сO<СU%2ЮN™Ўа1ѓиB РїUћ*ˆA‹ЮјЗ@nxtŽЅ<НЯ7ЪZEЎG–ЯТQЬцАшIRњRS  bЌ ЈПqЛos|[аXЁе„|]ц‰гŽuу"Њ ­RЎoR]V^К юњўнАlйrиБc|№ƒ€Я\§ Лa d‰G„ыZТЅylй‘Еѕ+„Ж‚\РGR†ЄАdb§Їф5{мЃQ”mюFТ]ГЄљАЩєh_C}i№ы­UиЖЋ–ЧіrЖWЖАp!аs—EЦg-š—БJцьNП/8сИ љрђЫ/‡jЕ wм~;œў›сч?bЙЅдШ+Jу/lG#mХŠ%­ѕVЁТжЇ­”ЪksžFŒ |эЏV_Пє1Ъ Ђ(ЩžЂН6кnТАG% Фh}r6*$>a:„ЈЄчЖзѓдЕЃT)ѓyяъ€RtЪЩCWбеaЗАV%nXЕjмsЯНpъЉЇТž=ЛсвKWТžЁЁBйТ8Ђ(5OžCс+ ?s€ЃAŸ8 ъјгP  ‡юunyг{БIю}rKШH>НыeюЈ"=@4Е——Љж<нgžд†™ƒI^нх“r<§-ŸMvDщw%‹bЩ(Эq 0Ё-XАюўСjИщ?ПС.rЬьйЖžмЏд%2кŸСЯж†Цпћj˜я Л„.L'˜Eјg8ЈˆBќYЎ€…ѓЋЋ7mmŸЕL З9ˆSџNLЋ+ Јз~тL€чvУ†­ И`њИЕК,ЅŸх PцU›В0wЙBžкк$*'8QB’(oеЊЫьo'<™Эќ\mУ 1њ>FЃ^PШўвюp}Mо… -žŠuvЏ[а_9яF‚‰ZЛ›аA2 “Bј06hsЇАЯ§№ё>иЙЏ’їё„œмЛ+—Д2ЏыY! Šў_IIв–Зю{А<ЮM$фdJ4—юм›СЃѕ‰№њjьћЬјдv‰Pš€Œ"žђмƒ?њъВё\мљвњNф кЛЬљ<Џ­Q1DMM -Сђ9Ќ„'ŸЏчЄd ]0К(Л‚t[f‹0ЉЌР хФЂЉR•„B‘vгээ!‹цм‚п?Г16ТіAPѕ лГр`ї2смбњшдйŽТ~ЗTђCГя|ёЄЕн(НVQCB*Ђ“а:ѕвЃš?•o|p}žоR+ Y„F%T Q ƒŽ3\4“ra:М\mсі%˜5Ф,'?zоЏЗФ№ј/ЛЬќAЏйХТТ›5)"ГŸŸЄњ>ДўКђтЈгlvѕ-˜М…аyešџИ!Ђ3S%’Z+g-р›ПККvкеeN0ЖшnŸЬ!~Э5WУgџсГЦ-\6чb[шnŽ3TыаMCћ2Иэў3~eЦT[;И>ЄАЪг,Мц^І~сЫф§€yoюз/}"ŒВ;ЈШkЃклG™н6ЗN&Їі€Пt6CёЊЏѕТњMAž—ѓ%Špg:ЛХ я7mк›7oЪRЌќˆ0•ЉY1KlЄФ_mŽрпncс§)}L|^юzЅ§ ˜RЇ­6Я]ќŽоxЪкƒ*Р)ЁлЭўгоК­Z[іC4JЛ>DОУ“•AЛБŽџфйbўу{5И§С*М2Tbбy‘$Jk…?ы|ŒД!cМvI-fў‘;‡3ИчЁ6[žвZo МоКu'лєкXžКзmГ‘ ЛзlGш„Я§__>„™сш /wvCї…!$]m…7]тВ’:vј+N`%мїЈ‚+o рž‡=ŒЩ–TЙЁ!ѓF–Э­Й5@^RЫмЖšд(Пп3’Со/м< <šzaяЃ№nЋnОћ63ыIГ)њ0rиЮ0ЬnМћЫKїL–WlŸь–Їnм8уФUAЋЕDFLmи…З+вœ‹jjо Зеус&<ћ’€ŸВлС8пц0оЋ0§њ]з-Нцhф9jX%ќ .Уёn~HЃ C“B–ІА(-# рЄmBУ Аџ`Єl,І0Ц›'l!и\оGxP'ЧS:Џъ6Ё)n(’`%ЛЃе ЋЏ?хЎЃ•хwR€UеЦ—рјkЇђУЈg0ЅМ) H`Тn{—™ЩЬЄл &Ÿ'тTТ‘™ц$…m^R'—Ю}лЯБ–ЇХNДК“+`eЗ“œ;т8ЛюG_[6єЛШё;+ ЄˆS№@лOпƒуD~(ХzкЎNY2КlдђUZЛђh ]ьюfW *Юњ7uqЉ~їS#И—†9:№ƒ%-м‹ЗkrnџџЎ€’"NFKО ЛMџІт(ВКЌUqј Ъ%cкуšžУY–€Р Pa Ќ’ lŽмкі]+жЃр`ђѕНŸ|cљњпЧМі‡ћ™іњЧъЕЊ<'|Тє је УmEWфы‰†еЅВФgЯyѕЦєэSDХ|ж:Ьёжр3юsœпзчїЎ€ЩŸ?zћњ30? “Є%ˆэ…(ї\3Qј~TB[д :(џ(ІТфЧ;ёЗ—а6#xžBˆ?і‡œпџ 0.4wП§ ИЏIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/routing_64.png0000644000175000017500000000736711733011756022636 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<™IDATxкь[ tEўЊ{Ў\“H AC‚$€ЂШЂx ШУuёDET4Šxр…њМe]TˆЂQdAV№фЁЯХˆЎЛ (ЈЈˆAH $™0IцъЉ­ЊюžЉ™LР$fн~еЉЎЎЎџЏџјўПjЅ­]W]q[ЋžeхJV^W•ХЌмјТ‹O6ЗжЩrAJ9px^Š1wr Ц€ЫЭЦХУŠz&НцэEbРСФк†УџJ:˜˜ќЁ/K[_XђЕІ‹†ЪŠ…РТXЈlT˜ЖЂз Пбџ‰6€Šš˜mŠбW~OД‘аx*‘њ„ЦгŸЃП1>бпщnэd(Ц‡ТЗ™„˜Dš§xЁˆj“ў?‡D˜DЖ‘C%I6§гvіІE5VDZBHLb(k'І@*­Q" cJŠйW1B:ЎУmf}~Yеч0‚ŠI‘аJ‹џŒ%ЇцФi+ЫGУ„™R"jљ§hЃ%˜HЅ{?и7ЌjxтGЇ)шš|№wЋнР6эи’Iv%ЄF$Ž „ Ыд5™`с{рЁзў ЋХ Яƒ Ц|ЗЄјIŒv Њм4Мвe1L.њДЅЊШj$Є‡Ф‰jШрбђ+­@AAvx? •!ХЪ,5ЏйW*WRќъ‰i?;—Dђ41й‘ˆTјќјi‘ZЭю‚чЫЃMLЇ2@О>[іŠŠŠФНCMDš’‰o‚š'вЪq“e0р“хЏтwоІiЂƒAQј=ЮxЛйЦџ6kљ^ŒlДНЕzmЛdлНˆaсЉ4~%Z“бХ–%`ƒцcЁ˜Ђї~кЉ€({7 8щмЩŒрšїW#AMBGTЮ€@ Оi:Ѓ†ž==OЛ4šјЌU rЉ„аЄњЃдЎ($<кo_кЬ€sЊ§$$ ZCbfдdи3‘HRЁywЕ ЮS6‡˜tNJxђYIіФAц7zРдA\иf|]БЏВv+#†љDNќЪoоGzz’,)ШrtGuу.4{"V†А/Н§Ejїз"фzЏС№уФ‚СшW0 >кBг~“СPЗєllлГ KVП†”Є$фчфЁ{—\ŒpЬ‚‚єBцчwakУїDЄѕ$јМb9ОиИЭ5€ћgЄПy]ѓрeъ!cвй"йќЗSкlїz21џІчqуш›и •‘…a§†1ˆlgƒYаУйЙЩ=™1ДъFаЋ>СŒ>)=MРэcІр™IsЁ&Ђ9a_[Н }к•C,.цс6е8№фЕOС™шDIй,TЙЊ0ъИQш•UUЕЂ{J2™AмеД šD_љšѕ Іžћ &ž}6еQјДp4 DЊ8'ОМb ыЋ oўP4F•tаД™мы5В•]ЯьмC—Э@‚-3–NЯДњdїE^ZNШ>nsЃЮЛGLЪ[ЯолbЧп.y}Ќ}qЯфbдззGј|~oтгчѓТЏбЃG#kpW<ђњ МzЧЌzѓМёЦтй[ЏŸmfˆЗdv Інq/’’qпЫS™ЏзqA“„ўYƒрjЎУЦšЏPчЊ‡g;СЬq!WыE‹СыѕF€ьШјТ<IŽ$TTWркgЎС’;—Š1ЪЪЪтЋцМx=јТ)јhХУn…3С‰) oХыKqZџг0ЄзŸ0Ђї9Lџ >§щ+<]<ЇМ лY4xѓcЃC™bXŠYsџnо8€їs˜туЏ^‡3)5ћЋ1aЮxyЪЋИљžћрЅˆП qUќЉ†тЬAХxЮžˆžЛ+П^‰€ц‡г‘Š/ПоˆЇŠŸХЦŒrІѓf4IЂє<™и%‘ˆ„ ‰Š9R,ю€оšœŠЧ ЧВOЪ0‘IТЂ[_„3-ЗнLh?Œ`(Ј…иܘ0Є№RМpK&Ю-ЦзЏ€&aўѕ б;oЄ оm4FЂЃw:С„'ЏhEъ(lVЖVmE~vO Ъ?IA V|Й’1|піЌ щ,‹‡ DЉBЈ5p&1PѓЯЩ‹1ы_cкEї"ПЧ”зъ\R †™VŸвpЖˆЏћ+НŒмLЌР‚ƒ+'RЌЉHЕЇ‹К чQ8!0lŠ'ї=EŒБj§‡˜<яFЬНaЌід8H@PBTп ЅЖXѕг>ŠмœГёЦД?c'гwБђ$Мђ1мœtЅчГиƒ8•dи2qЄ- щŽLЄZгйšА)‚ мc,__†лŸw\5Ё“ yлЗŸО >Ÿ/dХх"Л4ѓяX§ЬВbХ 1Ўптaо„Рh†Ы[‹JW9ЈŸIMР‘іl“^„‚ŒОL*вN-< ћм5xщуХp0xўдФRXTK|Œ пЭx>:Ž—][Д_v{С`8VVlTO,~жh€Н ]6њнh№ИАЏqЖьн„юЮ<v(˜pFбpЈ|XєсBЃиёФ5s:п ђ)ŸskЉnIX„{‹кPфАW‘2ЛŠnd@Ў`3Nƒ{YЄYэођšŸPлИEЇC‘Ÿе gіК§uXОюэЮe@H" `Є•ЄRЎDPjŒЁшЎPмJЩžGœ)’ (–_šъдŸяЏscУŽяБ№ІХ\42~@(,ж: ‘bNjђ„ъ:o2L•ˆ?‚­њЗMkqД хЏIcPЉfžA hpіж`KбПхuБаК*sXdzъёчРХ ІSщtФШм„’ЄC$й7W—HлZŠЙЅfKшІ Хт+–Ењн[оџfJ>˜œЁЬMжю­ЬОr6Ц Л\їДј+^,м Ч~ПMMM"Bу…GoІ›ŒycЅЙy9rdDК;"тp`ќ—СВ–РпؘіŠ—> пf?\gP)gиЩљMš—ItssГ šзœpоЮKДП6lŠ‹‹Б`СЌZЕЊEјћо{я…];Vф= Yюў˜6цXЖ[qї=wуќI“у j†qуЂ}ЩCoТЏщіŽcyЭTуАƒbЄДћta+зАO”•р’ћёPЪ2fСЉиeц!0яЏЊМ/5W‹ЂРр*“СюGы^ЋЯгiЗœПћ1'Ч7-ю3tћnъ)-нV…УX•˜оB7}2 ўИzюЕЈЌЏ@ХžrМ2e ŽNэ…ћiKы#V †$№\$ЯDэѕ ЛrЁэeA›SŒ<ƒ+J€2М! .”J՘U?FрєСу1§ЊRьбэ }ТE"š†\Ÿ ьt#hv­ФюѓT тGі… †\€œюGтЪ9Ьzз|ŠМTУЁRкYJаТХVНкУЄ.hfTЈДwоОЭБ63€ЏИY"VaWШoe+ЈЎz—ЭОA‹ч =У GР™˜‚u•kQCwbЏZЫŸ‡•+bЫrgoД™бG`Ѓ§Є\[*–тъЇ& !Щ†ГŽ‰СН† )! ?ьйˆOЖЏФ–њя<ЂѕЮИц™ЋАiЫrфЇ’pPeŽло]Яxd„fќЅKФv5Зњ3gЮФЗЭ‰Иэљ[v„Ѓ…ЂЃРbQБЃОŸU~„пnѕЉvg.аdптв (8;?џwнuZ;УнЮџЎєвјэ Щ œnнКaжЌY GqуМыб7Џ7ЦŸ>^oГZ™БУUŽJїVUП ^gƒТН{П:LœR “QZZŠœœœпцо ЬˆћпЎі‡як\9А Пљ(ў>џЄ9S‘ЬФНЎБy퐘Лв„Јt—УOš#ˆWЌњŽПW3šq§мы0}мУXЛa-іГ…AхXBр)UЎчеЊHЛU@nHK$иМыGlЉк‚‹†ŽлWќРдъ ŸЂЩяЦcOТцкЈjк!ˆчYA0+ лlз@›{,й 6giиДѓЌљa5Ž/К Оп˜аЈф—€šFŠѓћіУ‚› Т…n1&№Ь№ПX†ЧŠеwiћ"ˆчRрsS\}f1Ў5)Єпђђ“f›нa\дт˜aдщ(o%ТЯфtС:›€А„ъ‡цш›ёГho/мСњФ+іp lЋЫ‚нMTПГЉжˆ4Z ќ+КЧЋ€™ццLаЬ8пЬБUф*АЧГ Х“xž#а‚šб_O3ŒЌJ~УFвцUТ бОЛ1рfшm'(Cœ ™xСUzOC>ї@h 8Е•N… x№ЌФОйМŸ:u*&0Шм„к@4‹Wђ$тy”(zџyOСœ9s~Сї[’ZщЃ‡@bL(жфМAQ/рАb‹$^1TрP^–ŽXПщџiŽј€Њ„Бд`хч3AU–Tˆ… Ÿ}„жdРЄћKpЮ”йТђƒиІRCТ8@•Оcж­EƒЄљфо§Ђp”ЂУQЂmЂdЙ8C6VSŒ9e*І^8э яђЬац:)ЏG#“ІD2†б?3!ф2@Ъ…GЭ„ч >мФšЪАЈЪщ/ўkU‚И%2ЛCт$џџеX[_ИoИхwХ€?МŒП;ЂѓY?Т•~‹{И] ;Т€Л$яV23ТїБВˆЃђuњŸџЇиа ы­IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/folder-neg_16.png0000644000175000017500000000144311733011756023153 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ХIDATxкЄRKHTQўюcюuЬїƒr˜FЄ„@D “$ -кЉДihdЙ„ЪEjјРQФjeД)Ъ‚"Еh!хk&#ЭaФtrFGЧyмЧщмы$-Ђ^ј8чžяўпџ§п= !Лyјя9mНLaћ ‹тіП˜љ*6žЎоФsWFїœ8эDФацЧ‘дŸХџ1pP |rКkпЭњe(~0 t IœчL)Сэ1)AFoЫcБсъQiХeеv•kJ‚љюГУЦё$0.‘№‚Кн†6Г9DхёŒЫ$фP№лУ\ œ7ЎEГЉѕvLио‰Џ+8E8k$!‘U}њAŽС5j‡J/q+гщ"ЩЋ(”S}Ћ Ћ!нСtW&ZZ omј˜ˆ‚І&#у Л †БкJјцц љ§8ѓђЏК^ЩД=РRЊЄ d–—#шvcІЛ3==`E%%ТXm•^l2›qЈІвТ YёxѕС€ƒž<‚ЦїрhЁцfКГŽО>нQЌХ‚"z–Кз)I3OdDB`ФXpBђ }KcУ‹S Ю‡ a-+QUНи`2ЁА­ )ёv)8v_RIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/outbound_16.png0000644000175000017500000000061311733011756022766 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<-IDATxкbќџџ?%€‰Ыcxm`!Є99J L3ђЪ12212Мк!Mœ @šТ4Д•Yќ|4ў~єŸ‰‰8/€4{ИЊ1XшБ3іgб!€•O‚ Хщ@гTіоdѓцРЭКуHа0 ”Ьs‚i<6жН>УзЭ…жТ˜Sс‘DAЮ§мZэнo5q“а4~)cХ§MЗгЖ}ь[oxcjЩ`–zцЮ9Іl#Ќ*D–z9ѕI\$BP|<Ž„%‘„ˆZ:6Ц&mlx‚рѕ Bф.жaлы№6p*lТ8^“(Щ‹ЗkІ,~0"єјЌлЭЉ{K+RHьŒ&ЙZ"С‘ћнў…И„'/с’HЪ”šp’Їh ДOuч8{IU№0'…ѕкqљКу&a9$=$7т)йг^OOAlz>q‚ žЇ>XКУЗоХEBRDТЇˆEBХ"q-ny<ЏшEЂйZqwћНМўзhё`м}"EBвХФ„E‚`еhГўхF$`JMАРˆw8ЋBabHиdщ"5XxB‚œШ™$ЁвŠ@€e1Fp:‘vy§d‡YZћwx=™Х И4д:лLж{žа^"FќуНŒПи ХƒТ+Fgg'x<ХоIьHI}>TVVТiй!›Э.— TTTœ Ъ–fГЊЋЋСbБ(.dffBcc#”——CњэбaйQ;ўЗG€Іxьž :—ЊKЏзCUUC^mL&SЈГГK"ћћVыі‘C~Е№рЙ"]ѕѕѕQŽу 77WZыt:0P[[+с4 iчiHЯЉdO#УфяъЛн.ЕZ ]]]Rъккк ЗЗџ~c…‹Y\4ЩЮqŒЏpсЮЅР9AА*к+H"%ZZZ yyyапп/•Бœ€имЇя284ќ,% 4ЁŸЩЯ=VTT$fddˆMMMЄDžчХƒ)DЦщјП іm”•H)ћIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-udp_16.png0000644000175000017500000000202111733011756023350 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ГIDATxкd“mL[uЦŸџ}ыННЅ/ДуmИЋ.аd dИ„-ЇB&Ытм&Q"a&.ё‹K\4ћВЬ}1йбh “@дГl’‘7aйŠ2$+Фы(}ЅЗЗ-НmяпЛЯžф|;чwžѓфђэєз”! NxO^˜XПTf/G,ХЬъ}˜]MнаЉŽ!п дЌŠК2/ZЊ@bЭ­ЅЇ]wˆїJ5e ‹щsoџ№fйK•БYЦІD^ЯУl2ЃїхГxЄЇъЯрцУы8ъyWкЏо*;у>Щ;eЛ,HeTjsHeV›„O_џ #]Ѓи"AЌ$ќЈоUоC§АЛ%,ЇaЈіpp‚C‡‰!ЯІЩЮ‚“ty "шЦ fИ\2ˆ)”Цљщx*Ћ№ŽЇЗfЦюžq)9ЭЄ–%MOaЗZРШY„ѕ5јbЗ‘’"pлœиYbЧЕЖ1ќмў;ЂЫщСž/ЛО3IЎгs7CƒјшязPTTŒжђрЧацр‰€wїѕЃЦВщРfBыОАџѓŸБ_Œц˜‘ ‰jA:—œТtтWд[Ž не…лёQ,І|Аs.tИњвИ—‡gJ?5№X˜{ЄЋЬХІЩK3ŠfюДˆ–ї&цџ-њ~r=pё-яlѓЩX_x^ ј+ЯС*Ъ§і JдU82aPЩƘcЭЧˆаR{8pљ\ ўСZ Aў›i"їNYю~ЕуXƒ№ч(єПЦ€ЛaN‡Р2†z’о&Іу\s{ђуўfЁѓQXЧфЊЋrsќŽœ.НрЌщіЗ9cУШO~EsЮЊˆЉd•YWLH&@ЕT˜Џh\cь"9P[Т–O,хuЯІ%žшВ@0ОfсoЬmOцСйœщ•FЖoƒ`Л’ц‡8‰‡МЁPДzx&ЃQ›ЊQЈЉЌR'Ќ›\Ѕ{a}ЈlрNTA 6РQ0Z„хXцЉЂћFfГ›f(ш‘”Ž&N‡nь§Ак9Р{ЗЇ1Zд Ћ‘(х„RZw‚ *єr`+џx5N/­ЦѕЧ,ПMz‚‚яGТфТЇImЃŒjШЮw—MSфcБ8_sшx1ЪbјIАKгY­€g€Йыj§Ъpќš/$ЖАIЖ’Лx“!Б5ЦJ)ўУ} КўЬi7“‰u#Мr ћ…м'­ ‹gЁF7Ыт?œ]S’ХIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/search_25.png0000644000175000017500000000360511733011756022400 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<'IDATxкTVil\х=oЗЧvМ;ёиcgБ…Д `’RЂЊPPЁU”VT*!їG?јQP•"Њ&ЉJXК%uвTЁ)M)­lк"šКŽЗx‰›q/БЧлёЬМНї=kьјгПo>ОsЯЙїнkЦї}|мб_УРПN[6gšИOФ”{X–“,лиЖп†…$EžѓoчЬlЇ( ч^ў;ЫВ7xqEŽЃпx ŸиŽƒцрAЫq]пї<љіттЅЅбчeMч{КЏЁЋЋџа‚ыБp‰Фѕ\м=s‰D}Ќ.QS5”GСюХШ“ЌХ < M А ƒќb%чџzЅy>=їbbcхїR3iДњУUп†ЫрTЖЧУu(л&d)( ƒoсK_о…†њZЈЊи­iЪз<уС§Š,@з5xžІ†Вe% ѓщGЋ7”Сm;њАћ^‚ЦЪu ЖЫ“l–уУЖ#ŽeadK+f/М‚љљ47mivћУа’тьТbKR$Ммю}Џs]ы'ЅeЅяМѕ>ф§?„Јh(,3Р‹Є„c 9Že<8^KЦgЋяХєХP\RNЙ’8–хxў ЕLЫA}Мl6ГД'5vії'Q№РГˆЦ4TХuш]a`ЈŸšJ Ї@fЁЈ эuфіПŠою.ŠWD:НјœчyДKVy!‚ХgГйu’ЄуЦџЦ oj@ЌТ€iћа–ž€I6хшIAazЮІ3†ьЃя‹W № F7?KgЃрoc4UлYмБxзsрћrfŽ"цЁЫ Њ nѕrК4'њ!Ё$ˆШбљLЪ†%0"d˜œ‡ЪUеUAG"ЕB"Egf&…u%%0y‰FmК ]J—г^""“rh П+‚€Љ€ˆœ T…QУ|aаwDЂйžž/АsчnTь( jђaб;qƒ ™а"rSDЈ,8 UQQпoЅ(СTёxК:;QXЄ:")МS ‹ъ]§]!Г3<5B A —CР„ˆвО@Щƒ Ё‰ЖЮ~Eс(ёГ‚–"dЪs€PЩЎЛjFњzЛO єѕ>%EšЋtiS9DŠXЄZДI‘MVEBEЫЪBыш)“-хKXПыa\ИаŽЂXt::ЈЎ;ќбЃБcџМиžžœ˜„чšXш™ ;Ш{‘!*!PЇKyY] jKn uЕ…Nb!vwlolU5iD7фБBђYћя?Ÿ˜{ѕќљЭЋ§C8‹}уHdTErž,т‡6F)˜„9ƒЭ ХшыMтнwфѕю—d•;эzc;9фк•—+(њХhrФxяѕщУпLunолњЖшЌoпІ[§еVЌЫ=chk;‹ўОALNŽЁЂВš:ьŒЈN]zA6sYƒ\Г#Щwlgi>=ee3Љ?pр‘зюкВлд4ю)э„У?x‘нєТQи !›ЗЎэд9˜YAK 1ЅXQYUSГВЌм*ˆЯ{>ГH]и-)ЋAiEуoЏєUџ[З—B]џФЛ[y?ѕг#оРёVЦкФџхЃЉ…Г№|"’е•ЩцQЫv—ьS§кDТЫхВђєд-fv6eёwу™nчVНЗž›MЦ!W>aчгCGih3мЦчЎ\ОММ!ћжз5ЂМЂzЭ иJ“Ю/**ЬD.}v‘J[ 65ыюйЛЃАLєўHжP•п‚А—^фOЩ1бдŠ]ЂЄ†SЃАЈ+Г,‹Е‹ZЉВi2в\GMМЦzПУПˆІЧОб5R7nv “ќr7?#$ЂW€™зŽЏ(бT}х*—њ­ЩQЈЦК•Г М9‘”xддОњраИECь?>љќoЇщБG?џя™?яіл‹ѓU%‘uЪ}аVHш_œ51 їЂb}=Xn3YхaCMъ ›”.&oaАё/ n`††њ.?ЕяёЏЗџыTћ§шX~Љш#•\MМ(ŠkHšs3уАry0~5№4л-В*_і Ы†›Йщq\8w‚§юУЯ}1ЌЗ<+hЛŸi_n\>‹џ 0~В88ћOIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/info_25.png0000644000175000017500000000306411733011756022065 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<жIDATxк„U]lUўцwџЛЛєhm,!@ˆJеcDc&$šhb Цут‹‰"Фyї]њњ ёA… @‹ AЅШmщ—нэюьььЬНžsgЖ@Аq’ГwvюНч;ч;пЙW“RbЅgяўПжгє?л!7Ч,­/™0ГГ ^iсОWhxтŠчcDyzђьіё•ќhџђЮ'з曆іЁžЖпаbfПо‘„–O@K[Ж‰ZЅ‰вœ‹вxХ[%8ЅЦ˜Ј4†u];F`“џ ђСсяЦWЇІгЦ&Ћ/ #ƒ %Ў/б№Бl”šє­ъ 5Ь\žч#СTљШЬљЁ_WљшШЭГ§™CЙОLgЌ‡Ђ;o™Фд№%шš†ћ”Iцэ­№#А€Цr]`zЌˆтп‹1Гєйь…Ёя!€ї:кŽvnШuФГ6„ ЧAdфФ>O?еŽTкЦн)Ч_CцЭ‚Ръ ‰щЛUЬ§1S№Ї+ћFwœdп:џМшњ†toц`{І#•ГaДB`|С&сz=нTк1ДЅ <З ­‘Ѓзžе)фњѓfWцpЧаШкeDм8А*gnHv%діыгO@FЪQ‘ЮЭЛXЊшыŽсыЃ•sIВ!ˆŒжкšDз@–eь$7ћ]ЄЄ=НЩS}лЛ{лђ!MM6кдЂB{aMЊ…,žƒKё—žв$ J- Е‚a`гЄМ{ПO\ŽЗЧЄ:ю5f/ЩU9фь•r щC)HeХ‘vх‘оГ V“Š­ Q&<ЩtЩ‚(Ѓ\{ѓ1sГыxЛLњМMЫЧ•Lыз!tЪЪi*™R&'џDbЬП­KФIІ–fpPЋЬйEЏŒŠŸOЄЬ0’–tƒЌк*ŽФэB7ЦŽ Ћ;€*Q%‰6гf~Ё‚с ДЗб-кx}Сœ+6яиѓn^ЗRaSЩ0uІЊDЮ‹UЧЅїJ€Є­гМP}*” i­$#ŠBK•u0ЋГ`:NpЅ8^ЬtІ”nЎR˜Џ дщ№у A3Є1“6C+fur. ЗQЩXD5 /ju^zEЏ7ФљХ1ц j2ЂЅ(1QDЩз##ПЩЃРэIЗ…eі‡|85ŠPm5‡—ŽšдсЇЋХЦЕЉ;еM^:IнІ‹Ј‹[TД1УukЌКО|ЌШш|- ѓPsЙƒЏвЬ§жЉ­wНВ;<{e5Ъ& ƒ0 Ј›НЯХфю&K$,с“MS –Ё- EeвŒњЌ%хr‰О5бI<Ё‡Љу[Пю4 Ха9m”sЁВ)Ÿ8‡/?ФдМ‡t*<Ѓ/Ÿн Œ§ЩкWjQYтњ\ Уt?ИOжМxqЗо™љЦ\зљЄ–IrЅ)’їХgh hБGЮ•fZ0тq$ž}šaЋHUъuˆћх‚Ќзд}ђ?н;Gп2:лОвЛ2FW6<ЂњHКЙ|‡ю/ˆhс‹BƒnšT#<њЫЊE•œO р{іљ?=/ŒюЖ:лг!ЙCяЩCO%№,№ЈŠDhвq!ЪeІьiнˆ+‚№sр‹6џyюuФь}0Э:бЇ%шVДmuРw‚л€ чвq”ŠИШ\ИїАЏAZаGУ.Rы•h Н№gВВ7їЫ”UД‚ќ+РЁ`@ іoIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/user-ref_25.png0000644000175000017500000000267111733011756022665 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<[IDATxкŒV{LSgџн{Ыm -хбвђ(2D(L&*((ъФ…-ЦЙ™MйLдХ-‚ЫтF3§o,Ы4,[іШ^йt>ўа-‹Ш˜›GЂ1QAд х] њІЅїюєЂ (вфмѓнѓїљЮw/#Š"ІCW—}jэ:ЈМЬєЇ•ьЖOШЗ$ФСцxEX`лр§1Эuч$эF„Ќ[KТеЏn›aS†иPЮXіM~aQAbйfF–ЛтИЁіІВБJћеЛЗuпђЯю§Омиe€ЭqЬЁ/њЎpх SJѕF–ЗPjР(Сч,…nхF&ЁnБWЎџЉyџ†тˆBАяtl'нЃ -„ЂЪ№Fz“ЏдяеЏpіcD=Уdб…„єlфѓ}j_@8бŸ№XЃœD•‹ч<“TЦ nЋJ›јЩ SN|ЄЁуф„ŒљШqr&дЉ*ШWЖœ}?ž р‹™‰‚„ё„В€-WЎŽdЬmїћ]Ђ“я rЈ1@QМЦьдU[охнаЧЮd|Т+QцбЛ?EюЄ0vбХ%в:DќŒч89˜D§? $ю||&ЖMbЂDхTЎбxmwРуzZЅŽВё(€IAъSB ei‡ЏЃNИ+ТЖАEБяr:$Дйœр8цœkdŒЂЅШ9ъGбГŠ€в—QFTўС&Иz-PЫќg#њ5Yци™Ј5)ˆŒ'‡0ќŽоЯmЪмW†э&M––PL,ON([з:eї1іА6ѕ }бЯVєD9afOМЖЂej}1{ГјЪPJжЗ™,TeЈЁдЉ)ъдˆ юОQ иуЛуњ;З/92?ж5ЏŠ=ёџ …"+gŽ}№ЮW†–ЫџFarЛДгсШСѕё—aЈ,љ№ШG;Эѓо‘LІcjљ_hэtp—ю8Є, ЗД2Ќ1 iЋ[ФћсшKыŒЕfБєЕюЌѕWгѕgлŒjќХя‹d,ƒd†GЉk}naПКXЧXЏTР2рУЭЛcјЕeX’эП\ŽT r•чцKDЦ0Œ8Ÿ€-ђјšї)Pќ‰wщк(6­5Hч@Й –gIюІыѕYОo.ь\%;qтмnї ž4“7†У„Pš'9ƒдŠl6 oŸйЯyц$~ПЛvэŠтW,I–hAŽ к$‹w\CVžzЃ‚ШЄf?зњр‰™L‡žžDЬf3jjjfьm\“9Ят…еzTжнDст4ЄгнІfМXHŽэСSнŠ':Й}ћ6ЊЊЊP^^ŽЃGJМццf”••сќљѓвЛRСbчцl”˜4zX_šЃ 0(щћуђSѕЩ/­ sN|cc#jkk ЃRєцж­[вzнюkИќuž}ГoПž‹t-BD/€”ЎШa‡:zѓцЬф№сУSxž‡ЩdšЌ}AкккpрРIсGWГ"ŽEUi2є‰,є*5!Q }DAPЭщdpPњ€JЅ’JSWW‡E‹ЁЉЉIт=†};žBйЖЋxЏ6‰ёœtOR‹РбсcТ"œ§vШХу‰GXњЫЈЎFQQЌVЋtŒeВ™ЗNІ^…P˜1]…1ЏЗW€ЧGHДГнПЫыЫ_ м3gOt:†††`4%цоН{ЃH3@пЎOŽ” Н+ Ћ}cїЛНАXьЂЫє$(ЙЗNз/§=ъ–>~џ–Мє'вА‘arFT(РNLp=|Іи”ќq§ЁМ ЯжћW€mъHS -бшIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tcp-ref_25.png0000644000175000017500000000354211733011756024131 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxк”UmPTч~ююніƒ‘e—eљXд&bi$mbTbSR“ЖBbMХ&A㝣ݘNœФ5“™Llг1MДDaвŒD‚Б"b3Uб•аVљXXиeaYvй]ю~млsяFЦ-§бо™wяОч}пѓМч9Я9—щЛ"Иg\јЯ'Ы`‚Q•UiLЯкnw]ЋНтИŒŠ€Ig9(—Щ/9мнт‚Iћ‹J§ЁњW4хEwFж˜§ŸО*јlџ=ыіbSйЃ8вљ>јъИdKU$ћГѕ=›VW\Мua~ПИіўж?СЄЪўёНЯЏh&Sь6ˆlMюММa/ЖVд‚U?ЅЗ8/'ћяКпТЩkЧБviЅdзu6b"<^!WKВюž?Т ўlo†^ЃЏ#Пš;/,+^ДќёЧ–nљ§у+ŸKK5єЖЉŠ/>TИЭ_ЧŠм2МГљ˜ЇTПЊkЯУф№лuвAV% Я|шЌѓHЭЛ`S€Б№X›+–’Wg=­Sык9 дєrvл'Ўв\РкТЕшsмxщн•І>QP{Z-hьЂSwдOFNZvЖ *:››ЕЎiз љUм ТZ6Ыc–Х9с…эPщШX@Ћв†&9Эt<ЯOY3­Cй6/№9”xП‚Ђž№сэОFЩQF†O•=ц3'Яг4’Ђ2|E :птSe]}йп‰šхл š~нМЋi№Шsџ№]Чж‚ˆ +ЌexБє5iyFwОї\ї›nЅЉ? DЄHЁ”ф”aѓXѓTо}V&&Ъю'Nœ@ HВ}Ct„ ф/ГrШДкYMyЭvгЋN1:ЉУЋЉ№(й|ШЇŠyпˆџS_*ћo7‡УЈЋЋ[И0ыЁEт1Lх@кg ячйв‡ЭА’И€иšХт`(ЙдOJ…Оі€8LMMЁЇЇ[ЖlI^$Эƒ#ЪЬ%IVN'рБ‘œ,ˆ“кTњtjdV0‹—€%`VС™[ьv;аппŸфзbБ`пО}ЈЎЎ†0ќ7Ђ‚’#€СЏ(є?-‡к!‡HТ,њœчЅšq†љ№lљї:U{{;vьиH$В€!17зЏ_OLцМ gQЂЬИˆšх!DNй9jнDU€hєв%XOœ m—ѓ‘aК%ER^^Ž‘‘ЩRЉD^^žQQQZ[[ЁгщˆcBг6 ;_LбE-Jˆ&кv”ФЅяНлюв9ФMЫозTх<3п ХŸёёqi":kkkC}}=l6:::$лэ‡џ{KПˆA':OjђS$1њQАJƒ‘Њпѕ-мд›’@nKtнКuXЖlмnЗ$c–e“ЈуUYOƒбzСp€:lз9тњ#ры›qpє˜tаІ8ф%Эi—ЯOФŸЬЬLИ\.X­VЩИsчЮвrWsh*FnЉЅ”|о—р?_A ћ>ЃжѕЫMKї Dpо>їџUќ_з3ш˜1чПžСU0˜ЕОЋ ЛЅ WЙLDЈˆЪг’єoЃ§№–иjIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/accept_25.png0000644000175000017500000000350211733011756022366 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<фIDATxкŒVklWўцЮзЮюьЎ7^Ї~$6qh QŠPB•mLiЅ>"ЁЄ-Ѕ Ѕ- BP@"љ?ШŸ>~Q)”JU“‚@.ЎјAIZХфUлmNЦyјmЏпо]{wggцчŽI…Qйбй;ћ:п=чћЮwW УЗzм§мЎѕ"ї"и„Сз›bКЬхs‹гХщЎWЙT Њч„o_*м*ђП@ўЭƒы9уUй Эр!B EЎjˆeЗˆ|)ќRѓ XZ,} М№ЊЂ'АБOyќw=aж­ИеІъ LcPёЫp… 7Ј Š <с!P|,{Ьf0•›Eqк=!ЊxЁrд{ы– OОzрGNм9ф$“Yнд ( Ъ~‰(D•€€(Њц”§(TМyLNи№ТЕъ"ЙG§Ž›yљШ$3‡3™L­i˜бю]пc Цh7 { (Pщ=mщ/уОњwёЦа1˜Ћћ`Фдж‘ў™#ќ;Jо9ќЛЬЭфгЃПнw{ТJќ$“ЮдкV\х” ДCтA‘ЩiЅo*^ЫИнљ<О^џNџѕЦоЯa_уЗЁ—-4ЎZЦЯІZЕ{–€>‰щБІRщMІeBЅ " /Pj…  Š фШU†ЏмжŽО WаннƒžžФ‘@PŒаФš5Ydšє{™Тžˆ@іМєаC7в •кРр…^ѕл—='Р’‡ђ’ ЄЎ†X#VЋ шыЛУАаввŠ% №Љ•ДяЄ‘ЦкuYЖњ8Uг$№ 7x“TQ•Є‘JQ ]јDoHа3Y]ˆ-™mўч(rЙt]C[[z†ЯƒK5ъJФc]ЖЉлŒšЊн#лЕU№ "Z*IЊЧ%%%Е$šэRG@rŠ}ЇжЊУуNєііТu+TE3ЬŒ†їЦЮ‚'шІ 3Ф8ъ’ yЛ‹S;>Њ"J.й–miЖ›БГv7DYрNg3:‡:0Œа@и”мŒ‰ы“ч[ЖlЦ…‘n”ЕЌ˜Ф ­TтЊZC|ЙщЊж ИВ(ЏЬXЦЖьvМц^{ѕІњgёШКАЋiтžaSќ‹Иxё"JЅъыы‘ЉЏСХ‰n`$U!+с‘BkjтШФ3Ÿс:7‚бРIRЃy ˜››C>ŸЧЩ“'БЫл…НО‰ыХ~,ŽqцЬ‹EьиБяХщЩ“H9Жр0 & м„npdК4Ых'ђХJnX^БŒА‚sSЇАsзNdГYЬЮЮтјыЏуУг§hozщФјј8RЉ6ЖнЗ>ъDl%OщБІTQЦ b“хqŒЬЬsrд!ЃЌЄ5S‰І™(Сй…wрZ.і=ВЯ?їn\Л†cЙ)tuuaddХlЗoпŽыKW1XН g-ФЉMкŠШ!f*рхЉ3№‡еи6k+З•6ЧБЩ)‚HЊ‹ў,КЇЛP)Uё­Џ=ƒЫ—/c”’ђјО‡d2‰§OюGЧ‡ЧQˆхр4ъ0:tm… Щ‹\K9ХqœPѕ/ёŒPН‡l,RФиђ цН)мХЧЫ—hРžКџЛИ|сЕiхrЛлл‘нPƒЮ?ТnRЏ%’ЎЮ5h„ЭСЮ‡GUkЋ1_ЉИ_е’";N $ tfаа‘˜ЂщДPЧнЯ```ЩTO=§4оМкmN“ŽXœУаєHU4|Q~žcъуpРsƒ_EVяќР>ф4ђ_;­!TЎќл e_‰'ђ2e™у^ѓQДgїD2ю?‡7x+YH#ЉЩвVЈ&›~ŸыНR9в}ИїpdѕtЌ8]Н›зАv{ѕŠЅгЉЙЎJeГ”Рлх?сФGo@4Д[›’'d›@VСй *­ХЩ У•ѓјЪ'ч‰<2эƒцѓ…б E‹ГuVš*3#?e‚&XFžЄ&8вi–MŠВ‰GгЂе+Њ˜НZЋ–ТЯџЂ{№ПNFу{|Џ]ЫŽdжГжx#ђ(‘({-UЃsкН4ІGї:ЃСS щQ(MqЬ уs•_žњй?^Йх?hнЧ,ёlz-kOЗЈА3+`ˆЊE oЎ:' JsƒўЛnIМјЮOOu|ъПyЂщЊО_З•o$ыљFЇN…“еO1 Y‡(P &МЅiхš_fІŸОмѕѓг7ўЏПD7‰яЧж+пC€w‰_ Е…ЊЈЁX Vh\џ€кдMdџ­ч№{зo•ч_ wёр‡н/pIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-udp-neg_25.png0000644000175000017500000000364511733011756024134 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<GIDATxкŒU lчўfwggіђњ^€НБ)5VŒги„@ёRЁ(СŠT PХF)”P 9H‹вF%ЄЈ"J’r(’CIм@ ХvZъ†ƒэкпо]яс=fggІofГЈUе‘ўнџ|пћпћої3ŠЂМнкзќМOEašsƒ…ЗФЛЦ;ЯјЃ>,)XњћюЩжЋ§фW–ЗЃѕ7 У|•м—ќ в ‘“’ћ[лгмK4Tд9сњ#ХКг с€Кяpзыj№5gы+_РЙПmЁ#бћ@И”„сo@”o@ю™7Œ)aЦЃ@UК…бЎр}зgкzIк"\яўъ{о}щ$ Нї‚4/WхК6нŒІУщ ;ћЄx0П уоБIqЈЁЙk(ˆОт?ЙO =еŽВдGК%ЧY,Юvс•у/иqsWы—ЗЏ ‘Эj3ї‚œЈ-|жеkС‹ЗžЃœBR[ИDгЎиMќИk%­0Pˆ;8ˆ1Яш8хБћ:wЫП8SБL Н§}@‘’u‚э&0*CбаБ+Ё†MНсvу>TЅе >`Йю z?7-ŒlŸfCV•ZƒЉ›CcJиуѓ/bŽгZeO1 MћP:Ы•И~ !”ї6Ў}HV.O€pO1†іwК^ ю/—йбкбмsшЃЗћ'ю\ЛuМП†шY>єкIДŒ}zœŸgЕКŠ˜0Ќ…х‚п’Ч ~EŠŽ0EIEЄ Wах—юслКожlH€h’АћДmNš­L’ФМЬє’]!)eўH€й \šўзкX\e?~цyзУМўѓВчогyђ6BюA(wћ`OСЈ–ЖwБЈ@uЧћХь’j.o~ЋВр3/UЗљё†7ѕ:АВТ}aХxЙ7цtЧGвmь›AAnђ9чтсЕŸaйf'РdІшЫРX'0u‡В!&Ђ_hёhшzмœљ”FсOмОъ[ќЦ \š?Ђ m0Žщ`чt™МQ—ˆШтѕ˜[ў–ntТh†впЁљ]АQФвцРTJԘMЊ-%Œ)>gэЂўRЦЎљ•ѓ лж,2>юАщ,ј2†O:˜X:AbP2џpIfeёšŸцkRpћ фїRй{Ё1ŸуЄК!Ѕ•`ЊN :“u‡Б*ЗK—Ту№Юќ+ЋJиЌ?їФАяbDШўЉАgˆЯ#р0FЮсLАRЂ+v]€о ‡Юb™1/ўA‹ЁњЕQЭ0ш<9сŸ€іqёЉўƒв-лƒЬ,ŸџЧWДЯktTnпЮщˆ=Р‡ЛЉмn€ТРЃЯNЂЗХŒO>­y’[а1bЊ§юЋ2чxŒХ Y}IЊ[/Mgю^ =Jn`Y‚^‰‹эдпїhЙнnœ?[ЖlСШШЖnн –eџƒЪ:g%0]єіІ`И‡W o>яЯИђ(1ь1†ЗішsО§2J•бфЙџЋN”П<СЬnФr)˜ъімz№ЖTкwhkэBb?ЇЦю=џoR>>‰/=IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ipv6-ref_25.png0000644000175000017500000000305111733011756024222 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЫIDATxкŒVkLWўюЬь vYPAW€V㌘ДЦІjЂm0MДmlДбдR…двЄЕбДђЃibЂёgуЂI5ж”jBСRĘbB5ж`Xг•ЪCV\А ћdп;Зgfэ†&юIююмsяžяœя|їЮ2C­Д‘щЬЕ уё`‡О=бЛ‰б{ Њ1х›A›вG|Цћ}бЁ_аУ{’x–I РћЛоnbpъьyјyzŒлtЅѕћ4Е!(п4wјюРюНе4y9ћxбv320AM.ˆЅ2WВ$”) зтŠEbђ]п-ќМ fHbб[ўІ‰‹ѓg")gГœЅGE—4рEКЊоЦэOkаPЫІЭ%й…[у/) ˜–њw‘џыgWТRUHџЉ„L–тxAчэЫNšіаŽvpoШ="9DЃ–\Ц•ШB9œђ›Ћ~йЧŽMЃГўьХ–O%Ѓ—’тHњГ‡3Й№їiЂ‡e9(iеЬ­fk]эл_ј™ё5&p˜lqл’нА(T "Gx2оžˆвzб@CЇѕDgдh“L\m|о*X˜>V­ сЩр=їѓЪЯЉŒ+б™RJRMк‚hdЬсw uщœLU~`КžvЌ&ЉoуBѓ_€Я}ќъ %?иZ)КВ(жЗ7).эX D2jYЋЯ†zЪчНi=Uошm• DF"‰bй]~t•Лћмјi&†/ "LY:О§a$Сн!Б…|96+nЌ(D<U€Rй+Š™ЅIбUŸžAаuЙXюсЧJѓ№•}яM‡№CЎ &3­Y yfУŽО1ќqэ~ВнЂчuЯ%Й) KNС™F—AыкЇдГ зЊ ХPЕЁЭoЌ^]l.‡9LP^ž0@€HЪ0ХdюИŸs}(КAН-”Р’IRƒSH ЌUЇ6›6yУўFУ :ˆЊ#1ˆeР<Šс# #э]’ЏЇ5СzgRщЧeќ2“XRс^щŸУЇЕ‹§ cƒС€~ПO–eEAЗлeyy™Ђ(Јыšнн]bŒTUEY–TUEUUдuM]з8чІ€ДФЇ‚?П?€жjZ—93?ќсйооРУkЏН65/k-Н^……zНEQащtШѓœеееЙIфyN]зьяяOlЗVШУ‚Нl;Щh]тLќьg?у|№ƒС€'OžАЗЗGŒя=Щ{snъэ~2™`ŒСZ;Н_{нсIZk !`Œ™šЖˆ€жŠ<У‡Њh (ЩŒD…ЊіФCЎМјљЯN№ŽЅС"=ЄЎыc‘miЗХХE–––ŽœЗООЮpИЯў^ьйГŠЊœр}Џо94zˆ e8sћЃ?’YСeU‚R†Ш~t-я­+,-t1‘фкк=:;KƒНn/1pˆФц„ЮђŒnЗ({Л;t:ЦyЮж“Ч€"F>0юsчоC&у’Њ*qBYVT•ЃіŠ‹‚R{ЅЊcr)(Й„ч#•‹”>МRљШАŽ,Ч‡|эšcyа…€С`РооЃбh-ОWЎ\сЮ;cXX\Єг0lŠП5[[л”UMDЉЪ+н^ВЎ‰dЁr#6_ФљЮ\\PBш"д!R…ˆї$!]Єv5ХТ UэЈ%тmЄжH­O@ХАПћ•Уv)"c(ŠтlАyѕ*ЗnнB€ѕ иппg8RУaЩюю>§ХU.]КТxRт}c0.рƒ%„ˆњHn2+IXЈœЃЎuˆ8Ј] їч#Й !Pћ@]GJWМ'z%„d1D|ˆ„ LJ%D8х€я|ч;Мџўћ ЪЦЦїюнукЕklnncЄшtxэъuоќЪзŒЈjOYЛ$dэ’іы@щрC і‘">‚кlз|ŽQ–щј)IџШ0/:№јёcŠ"чЦѕыьььАГГ3evApЕg8qp0т`4b<)™LJ&eIYVLšXяМЧћ€ ".$їp!т]ѓнМИ xё>рCФљ˜ОХ5Р„ЈŒъ@ gC`ЮBќтПріэлмКu‹моyїŠ"'4D(@PMZt> сч“ЮœO“M“@Б(4ч'0|LBКЦМ]ˆ œШьx ‰;KA Z\P”Г•2s|ќёЧМїо{гАіщЇфэЗПЮ`А4‹ы!&|+pЃAз˜Иk4˜іŠk4пс0|c >&АвцїкИ@ˆ„и^Ѓа_сЮ“}ЎЎwшt:Џ€ызЏsётХiжхC`yх §fъl‚jАj…љКЄЉЉ&НOЧZM†0ОqVѓ>ЦC@DBPBlЌ)ДDиœыС.Ўqїсg\]ЄпыНКн.яОћ.>ФУ§ћїY[]сoП ‘В,1"hдЉIЗuŸ‡ЉPЭїЈ_' iЕXЗnбиКЧœ+„ЦфcФG%Хy€Ц@n ЦШ™œрHxѓЭ7SЪi лллЌЎЎrсќўчЏ~Хіі6нn"ЩD[œŸšДoИсАп'BгФъэїC–рёЉЬ\BЭ+uTТqRœa‰—/_цмЙsœ?žызЏу]`}}›eŒF#ЌЕЈ†TХM}^БјŒБ“P-I6Œя“ )"ш”хЇЎ’Жыиš~B_ѕ8Р[oНE–eЌЌЌ№Эo~“пќіЗ\}у ЌЕЮЌaJ|qЦ32дщНкз џEЪo'"rЊžРБ‰ацц&+++\X_ЇА–ЩdŒЂ“rm4т\•&ь#Сœї„ЦœCЇцыSБтC˜њs›'„9†MhЂ@У ,?Ы2юпПl5њвыŽћБ­пE„qUБЛ?Єп_Рк DИКnШ­ }3Nsў]Ч–ёу! ZkP\ŒдSв›хЇѕћ~ПЊѓЕ€~ПsŽ#ьэюrqm~ЗK]зt{D<ЃёAЪљD‚спћ8ѓ§чˆЮ…Yшѓ1LCодк|р” ыТЉ“ЂcшvЛьээБГГC]зTЮExВЕХўў+—7ШMрю;DЄ‰е-ућЄсЇцэ}œZˆ‹„ж˜ ­к\—ާўЩиллc8ВЛЛЫh4b2sљЪЃё>Єпыa дѕИ!МУцL"ТЇVрrœЖQ 4Ф™€‰MЈsм—шД=СcИpсТДF”eIЏЗ€їёxLždжУym^ПзЉЙЛІё~Z 5!Гew7чїqъїЇ ymГІЊќŸќE|ћлпцёуЧlmm1ЉЊ я<­KŠ1‰hЌ кdws~п =№hо(г‹3Wё' ќ –h œ *c3l–3 – KЇу€ЖХыКžіз\]уъzкэЭlЦЙхEВэ]žэь’[;ЋъеГчpjЫ,уk*<•:š”!Š!6zQ„@ЊBU Ј†Uџ€ЮюCоМБDЁ%ЃЇИб>ƒ0dяЮяјУЏЩСўЦZЪбў№;Њсоoџ“ЮѕЏы‹ЈšŒсСAZРpŽNQаk@жVЮБPьђйућЌ_О:по7йœœ*9Ž@­ž’œ Ј ”(ЅRА~NЕƒЊeA+Ю…m†cЮЧЇ„B'dRVТс€ѕЛчио*в™.ю=bы}ЬќќЇFЎС9ЦЛлP—а[Фvz'`RеxWs0NЕ5,1йкнgѕќEЫлИmGm—ЉlI­J•е„ё.q2DCЄПї !цŒЂАT>%їћФБ~a‚lЈАЁФcШдГшYШqЌЩ…ЋŽžѕ,јcmТrГ|BЯEЂ‚YЧ`ФїЖчd‘.јќЁsяіЏOц‹ }>ЙГЧA­№­%GЏ0DIў:І %…n&SЂmyM\а|$3а1JЏ‚SfМ€?№ 1FіwŸН€џќяў-ёй2UСёŽТ nШї=…А‘М ˜,Ѓ30tDA c{фMќъˆвЫрoыŒ€eЉ#,чѓy§сŽžeјтр'M+|ЌBфф-QКЂ*LтщвzіАgьнЮ\р”ЅGV™чЁЕЕ ЂЁŽЄ5;M‚G=)ЮѓCО#zњЩОьОЂˆ(/iqфѓ0]›V˜яќэ‡гcs,.-}ЉхЙ!ЭУ'^Юlў„Y*’…ŽbКЇ‘у7{h+ Ќu”Ј:Зи;я.У Љ {E8є­в1ЪИ™l&ѓжєВЧжEћ1*œя@nвчZ!Дs>4"‰wкы,Щ…E•боЮєМ9.оќ:O?њ5pК— ^(‰yS•0/Д2#ЦЃŸggЖ:ѓFорьЈ№щиRХyW0РD…§ L_гСd‹ЫЫ<ќУmўє§Sр9–ж.МДœ<ЉQДBФfтЊ0єТ8……г1(=x!’bњаšЌe;ЄЙз3ЕH{z1В­†­h1Й*ЂкИ\кїlњMFšsљЦлќуё/ЙќцзІs@ŒaвdфpŒ>$аaK› {ЖЂТVmRђсqmˆжpЗ‚­ZА•ТX QdJBFОPE4ЂЄWaTг~`]"…ƒВдКDTa9‡ЎIР/цЪ Ÿ5SŒР8П=ШXX=ЯЗўй_Ю)k€+_љSj›с›˜­Ѕ›iha’WQ8ˆ)ё;б`˜‘^kъ6F,L„JŠЙРŠD:КF),ZX.„*РЇcC4Т;‹ŽŽQњЧ4yчёœџз‡BНB„Тбe•9:§EЌР/ŸхTbžKвЈ˜†$UuъЇ9ŠŠ‰r-Џшg†хЌ}Hф\'БёЫхР y ^”ѓнHЯ=D#žЯ?§шШБ9V7^чъ[я№єоqУ]BUЃšВ=­вЗJЯ(}щYX4Jз&-}>БќЭ$чЯV h<Т'‘У ``_Э+ DЊ ј% [ЧŸ`эђfJr‡OйЄфм‚PˆВT(…I Hkц03siВFš„ЉtP|‰—pU“{ 2и~5шЙћЕщ#-БиЌТоXP6ћ^d!S Ѓt$M0k’ #ГXme›jѓQxс‹''Ÿ,)фНŠ!$7єоsџупЮ;2гЏќљ_u:)ƒ23ѕЙэљa$i§ЌЩžшJФЋАчЯюJRиrЂ*СЯї›PєštЪбXCT~IЭЕѕўBžмс4ѕƒ<—g‡ЖŽUКF!‚ЋЋЙыŽxj^tићЅжс аGOTзП№’@Є4зš„9tKгиYЫAF`ьšP+Œ ‚Sa?І=ЖцюGПсЦЛ>Нз6ЎПEД_І #ѓD37q9L ГоKЌ!BхRv˜ХШŽmŠыУд€pRšVGaŒfA&Н-т5%a6*^ЁRЁ@щ.V/^™›пК ƒdЪёd&иF+Љ@ARбб3щтнкLС†”п+0ŽГvVЉGj‡е&A№Qљ]U№iВКкC.q* bг?dˆвБJ!А$‘Ь@?‡A–ВD!ЩђЌ6<эіјЦ_|чхX›aD:a)SЌ™з^Ћ9адЦj+Н]—иуQ-ќЗНєКъФ Й$“>ЈG`’@Э-(Вb 58W(6Vђ˜i„`ь„OJУЂUоь{–ђtmFšoa„Тъ4іšTЕuŒIрЪЭЗ1ж\ъЬЖ•ж$Ѕ UЊ5†2&•Q\hNё!еaxр,Ы6pЙщZMnЁŠmЌ'7JGRэ‘KJЎ‰ –ѓљ6›žљРКFYяТr–JпУЭгЊщ^ ЩЪŒІ%їЧŸ}ЬХk7_ @n-œЅЅ’В Bэ›тHRЖ#"` +ЉGз) гH.а•Р…NЂб №_їК\+_щ{Кг'Юд1пK„ЈBћт[yL>оЕŠ ƒЁŒ…—є•фž‹yъ•ЃсмёcИИyƒъв&ПљшoшWћЌЪ “Дд1)ЄtM c h~+ьсMйЫьсmЅxм№$ЃљtН5œ6ЙёQˆ'ш kѓЧDЯгћŸsээП?=v,o|уp~}ƒН;ЗG%'{WчИ‡їˆTQ:пg8Ышˆ2СЄЅ5ЃФ(GКM0Ы їŽЧїцŽПДdY9ПЮаfpЦзЌM9_2фа9цїЌЉIŒIIзА6г†oЮKсrЖxRFAќe‚sЩrjѓхВТЙћˆR6IЪс rюœfuжЬŒqжlўeH‘ЅŠ ˆЯЦ†­:УсРƒя,аэ/рB ”гы“gЊ‘ЕХE–ж.ž€ зnђЛю.NhпШ}Qvx\+Q­є%В2&!ХшvНЁЖm† ‰$wjСд!e€™Э№cг%ыvЉЂ Ы9чЛ–ж6XНp‰Ђ(№ЮqсЗиxуOpе„Ђлcѕв&‹чж@••зŽЬёЅ,­o`;ЄдiтsxвБљ>Яh5•0L|"Ћ{•хў$ŸЈЁЮКиМHЙ…)01Š) yѓЖWПгcѕЪUeэѕЌО~aАržK7ОЪњkз_&ТŽ—`ЌЅŽ†q4TйkњƒmСqСR+ь‘SфA•]ЩЩВ,ѕsCжЩШŒ№Ѕ0X^[чЋ_џч_ПŽчж7И|уkИЊЄг[`эЪе3 vвёR.]ЛЩтЪ ѕёВК €Бщ%„ х•U6._ХxЧкъEn|ѓМЃ?8Чх_EQV.\aщќХ—=цџщ/њїљ_ўЇџ@VtИ№њ(ЪЙ WXЛМљk~чуџTСC“6аIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cluster-neg_16.png0000644000175000017500000000166611733011756023370 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<XIDATxкlS[l”EўЮЬлюв]ЛlЫfCQ(šr3-Љ!”ŠQ•іЩMƒ[ЂF#˜и&bЂI+Eє‰X%˜`ˆ•ŠVЉ›mм^Šшк Нь.іђя™q–Фв“ЬУЬœљцћЮљŽ&ЅФНёо#ќ!QЎЙžГЎt„@ŸЪ|цо\†e‚UІЦЌXа4‚]ГЪƒmЏв*uT+ЌVY)W[Р☭`BS .йžа1ФLYQpМЯ ЧШ№#Ь, QeJУМыУіŽriLфн8 OˆDQ€;ОŒ-+Сё…(]Ь,К0дWЗц=ќЙрSо•Jžd[Ѓ\[i‚,N Ž†ЊєЃ-­ыуЗRКЗ[ўўѓwЖBœБMOД`Чsm˜КpЩoО€Њ'тBО(Tмg‹ЊˆЏ~5\SсEѕЬgчДg?њZOlЈхŠmўuБЙБПМе‰Ъ=Џ Жч{Щ“’ЉVд„ Q“ASО/:šъьФьаœ\OvбЩ+вІЭдпоŽ™dЙбQ4}иsѓњ™.*…zЮ•fФ }Ўˆ)mms3ьщiŒœ8‘ž0гФ§MMшлПwnм@hѕjд:„К•MЮ ЯтP]ЅўЩёNС‘зшЇ—ъфЖу—1xф†ЛЛ!}мВр-.bEu5дйдDŸHю№ ЎœW *|)#rўueЏйЗГ§чиуŸE~l sщ4„ыB…№˜btsќ{Ь}Ÿж‡9YP^@ЙЁ^ Љй>’Ь2tФъї"{ѕъ]­џ‡ЗД„П/]B]ы›азnFЬj# —(й_ЙМ”ЖШЯO.3WDa|сuыиЕ ЙсaLТž™A§Л'qхЗ1|›E•E(ИЪЫ:aЮ‘yK$rtр№a,d2XБf vž:…mm№mЗ0›J!Џ˜=ѕZ;њY["ЌмuЧƒ’Y-Z[‹•[Ж 01†Ў.ŒЅћўJwМhЖ}™Њ”ž‡ыННЈЊЏЧ­ф№дЈЁТme$ƒнт”–hl|š›цљ’ЛwПбѓrгёвMfфзmŠЩЕВxРщ}NкyБjg%ќcKрє ?§O€ыKqnNw~lIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/state-sync-cluster-group_16.png0000644000175000017500000000155011733011756026033 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe< IDATxк|SKh\UўЮуоЙ™LM'5NRЕЭД ™бжД‹Ф” ‚,tб]w.ЄИqЃPК+” >и…PqсBqеК’ˆ"ƒэ`š›fššЧdЦЙsчЮ}п’JнЄЮНчўЧї}џwХGёЂ1˜В$f2 рХ@3AU | `ж№ЃC „|B;Ÿ[qnLајB*Œp€ъБw BШМњ aVIьЙФЅ‚ЂчЛmtи ѕШpТтv]Ј„TџАHbщПœџы˜š-X|пf)є0М?+R’аычњDцu“Z[^(ЖjКkПьtlešПп§ЉRГуqZ…jA7LvЫ!ыHЉ‘иmPО /ёI%Ж–šŒY уxFїe4w;*~Œ’р…l +Ы5Бэ'ИSq1иЎ1$ыQ"§$-qИ&0ЇooјLшN)ІхЧKећЙ{Z"УДnœšьЧof їV70ЄсЬЯУлt9клF“Яdа‘’ ;пeС‹ЌК.і Мšu№щв:=ч†ѓX§Ї„їяЯсђшSАЙјќЄMLxWHухоУ#ИЖСY;@GћFђG0XшТVXB-ЌсЏпЋ(-n"—=]іc’BˆCИРЗї<иь’Э жc№цлЧqѓћ[јѕvJ‡и^waYђљю.<€і"3ЯH†X/‡h[,< „ˆv=јlяœыFНуу+_сЕгЧqtИŠ›ќQ,э‚1Гk‘Ю˜шЛјŒŸа‰‡xК9Џ\‡сб&FǘќŽь&v­с -ЛВЦћцЃo~&Xг" ŒJїЫNЕка‚ƒзЫ.­ll‰“#;^бiOŸK-МuWџ8wK ;œrCWз>Ьојe1Ѕ•zвoТ>ЗSWПОў]цщ}цЅ#Ї ЄФЪђƒотЛщэ­Њš(L. ЂНшЗ„њфќgе зоЫЄSiјQ“Мf]МrlМќЦдйqmYыџ 0гu[…УЧbIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp-neg_25.png0000644000175000017500000000376411733011756024276 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<–IDATxкŒU pTхўюо{woВ›}&й$›з ЩЦ&›Д’ъШCХ:EЖ0VieP+ƒ гmЉmh Fœд8R‰€E’(!j"ФФШkГфЕIv7}олsя’ 3щєюќГї?їќч;ч|чќ‡‘$щЯuЗj~iŒШ6йзim„UБЯ’Ќд;9ŠЅ+КЃbД‚cЙ YєІ! ЦТўцЎ‘NY„’Ьљћ~ ЕмХд“eЪFŠ>ѕї IЗ“yw‘фї^ЋmПЌМЫ2y9іцHMЎFiJO^o|њšд?вwtGе г2љЙїœМв^Ж(gU2"ЇXдBСкSуЊЋkќыhЙ'КPQџGФє$EЗyА<Їўщ•žАђYMЬsйFЖ5 Џ<њ*VЏР„фХщЦурф|<€kНѕq“*/Ж–=‡%Љ+Z,њDiLueХ@т0а2ђ-L:SvЋЗ j’IєS@ШFNjVх>йЛѓс]ЖЄз9Д 7B‰„з‘8р;Јu–:УGWЊ.}зеќ—З~VQ“ХЬ|Oжгžйb@Д 4Ÿ€F ,Ь{ˆЮФ"су$є…Л№‰ылЦWфЮLg,M‚Є(ШсЉ†ЌFыYЖй­F­Бgnn‰Gж“(N-DУ:TuSt‹вјЦ[{эФŸšївNB"9єѓћжOШЉюГ)яmўF,*^ьЬЫШwьњfЫгЖјll+иx0Л уЕЪЪІд˜ иTк 3 ёВѓme_hМ?Xѓэч_NGЂ&…’фRЈѕўкѕv8о~ЂЭ]sCЧБТЖгЮЈВтЋ‘&‚Ѕ§Н aŽЄuŸјьиЉ‡Ю”]$ёР]N%дС!OчЮТƒ >ьННяєl'ќjі.LqЧЊ%8’œрЕ 'эв‘юFŒ[žхУЮь{ŸDWiЕВЛwяЖВМ4oŽЉ MзП?[šіш­uГ~oLШ5сѕмгјЁ­ГђZЂЩ”?ЧX†lmвЕYXf]ƒкН зz`U„<Н=Wo|yНщтYЏ(ШфШ з3ЂЦн>ђХГиtІннViKШКЏ)‘lAGяžЃ{ПttЧпsгѓўЕ*ћ)ўЮ‡GНё§ОŽ яњF9Gh<_œDЎG„БХaЊіЄoШ™1P10|EސЁF…f)Ѓж%­6чЯ~f†Ю\ЌгЧы_ѕјЦ nѕЖьє T]ћЊнЁ‰ЖqїЖ§K8ЏЛsŸfап i№68§ЗCєіƒg€шpТtZС+Yѓ—ыыъым7}LІQЕiq.w€U%F=:!Љ/Е‡†К†".sР+ЛGэ˜ѓфПёр&;|}@F!‰€ћ&‘z›P‚@œA$0ўu$>qЉR]žˆaЩlaУКЙ“wRBCW#“€AЃJдЊDпЄјжAь-C†ГlАЫЅ(u4 Xѓx_/BІtФ,Fzc€ђв'ƒ‰‹єDxC˜НhљэЌy™мЖеEъХж•і_…№ЩЭ т(v•ŠA0Ъ`4ўЉљ‰ѓfЎ~СІДё—!~Lчї`’іBŠ*–ќ†€€J?јƒЊ8нѓъ…ЉЭ*Н€wЗ— /-Щч“>m aп…ЩpOєNˆ†rЌЅ>АЊ’ЦjWКQ БЙ,ЧBЅеŽХ—ˆЃšШ`ЧСh[Т˜иЩџ§фьѓBшŸгЈўљ"рjЅЯ‡ыћб^1 š-arbЈR8ˆЈм|’tCiЦУ‡уьйГАZ­ŠQN‡“'OЂВВRй{ЦЂL"8§@jE–яx=ЅeBMБих•`ЂЖЯ“˜MwžKV@, –-[†#GŽРщtтаЁCXГfЭ4шFсќХуїЭ#B•3F§•3Ÿю–PЎсaWЬ8GIБ€@&9тgм3)†ƒ^1ЭљŽR]хххŠaФfГЁКК›7oV@^Ьi^”2ПœХ` 0бO)!r“Эtя4nЙ‘GЫяF 4Т Fƒ›ифœXRnMs2sцL\ИpvЛЫ—/G}}НrѓФ›U9цUшnвrHBi‹ŽаIJ™Šё&Ўњ}6\B4Хq,О,}УЇЄнfГћїяGii)мnЗ’&yежжТяїуw§x їйv …cдL*Œ$ђ^Єj#ŽdWCdjœ;>,—БŠes?‚94&ƒ(œTTT`экЕ8ў}Zё$5ы†+nеO^5жgРh‡!R™њiАз]ЮHѓИ=Š ›ЁnŽ‚•"aєоdЇ"Q8ТЙsчАeЫИ\.lнК<ЯџW)Ћьѓ€i†?ЌGЯ-сˆмxнў |—P…=ЬКV6%o' ЄоЉsџWŸHŸ?ТLošBЉ”ŽЙь(†!u3„„JЬ3<Џ|k &!4щE‰1tяљџ0*ы+г‹№œbIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cert_druid_logo.png0000644000175000017500000001465011733011756023773 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоgAMAБŽ|ћQ“ cHRMz%€ƒљџ€шu0ъ`:—o—Љ™д3IDATxœbјџџ?.LРХЬ@ЬЅA˜ˆй€˜Šй b,HjazЉАљ €pzžТ@і8Ь OђБ<K1?sA1/ѓ1'$@XP‚*›ˆРШ€ˆmyЬˆ[x.птƒ@<ˆ €иˆ…XJ @ѕp0 ‚*Љ›ˆРŒФЖт@ќ‹‹CшПˆђ ЋЈџъNџЙ9E@€№5 žФŽ@, Фт@,Ф‚ ˆ€€e Š›ˆš€œзUx Пbeцўяр˜§ПМёфџЪ–+џ{fљ_з§фVщБџASўыыљџgfbYіˆБЫБ,‹1 В 4 ШN иќ@д XВPь]caaџo яџПЉѓЬџ5;ўќ?|њџџгWўџ?sљџџ'ўџ_ЕѕџџЮ™_ўWwПљ=чПaшV  о;@ DEHЊ€Ѕvh 0aИ€Ь jВч€xШЎдŒ%џWmџџџќЕџџпќџџгчџџ?в@ќФўњџџЕ;џџЯ^љѓ~ѓлџхнŸџЧЅ,ќЯЯ'Вј=зБ.Ћ1@R„0Z œ Аљ €( F$Ь ФxИ„џз§_БхџџsW žyідѓ Рј№щџџw ђ№Щџџ3—}џŸпєђiчЇџiyлўЫJыУЪ‡v жb-H–A XvЃ(ˆ)ц7 ўсцžџЩ†џџO]ќџџЭ;ˆ‡_П…Ап~€xўу'§wќџ?˜RЋžўЯm|їПЊѕжMuОq&Б6Ы1@R(АйHЌ&Бљ €( &(V{„хўЗѕ_љПѕРџџ'/ќџєьџџ;ўџПaїПџ+Зќ§Пvчпџ;§ћ8їц4eс 0Е4Mўј?ЎјсџьЦЗџ ЊN§ggх9тЇБ)4@)Te‚ FVR6?5”Уџћ“ўцџџЗ`нЮџчЌњ§Пwю—џЭ“?ќЏы{џПЁџ§ёџ„љпў/^џчџ!`Сјш$•м}єџџТЕПџgз?џ]pџaЫлџ‰щKўГГsВˆниˆе #Јv€U‘DЅl~ J ќИVLTхћ„лџWэќџщІПџћц~ћ_зџўyЧыџ]oў7L|і|§`@qmп;`-№ѕџВMў?їџџ…ЋџџoйїЈюУџ˜Ђћџу‹ѕљoirШHЃЩˆXˆE -HXV +ˆ’`‚(6^ЋkкџŸЗъпџыўўяЦ0ШгE­ЏўWЋ9g ›^ќOЏ~ŽсвЖзџы&Мћ_ P€€RЪж§џСxт‚oџг€ъТsяўЯiњј?9kѓn.~cЮ3@ЊGHэ*@Yд|&*`ѓ#@QАŽM3#Ыџ№ЈЎџ‹6=є<ШУ%mЏў—uОўŸTішПSдхџ~Љ7€йсгџЛ§_ОљЯџЊž7џ‹д<щУџЦIяџO^ј(ўїџŒЅ?ў—ЕП—QљїџWї|ўяюYўŸR+,bW Жd€T 6ЈATˆЭDn0"…њ .NџE;џЯ]ћџлДР˜Vi Я?ўoш{њПkмхџ€е2јєTђ§_бљр‡џSџ?cйO`вї?Йќёџ0`*ШЌ}ёПОчсQaEƒюq $+€jH­РЩ@DS›ˆм€%PШп”•бћ?mсG`вџLђРМххџ„в‡џ-Я§7№>§Пiтлџ—oќљџшщџџ?ЁФЅџ—wО§п:хуџжЉџїЭћіПHgз?gƒј’џ+{?џ72 9шW0@:W ~Ј@ЅЂЪl~ RжъcZj˜м–Pцc`5LЮ•РМТž зўЋ:ўя›rиўџњПyЪ—џНГAЅџїџЧЮўћи |љ‡N}џ_гћю 4кЇ}њ_lEцп§Ќr^џŸrа?HKд_pb}HїZQDjР<ЂAа$ ўхцVјюъПр}.АAŠ=‹рsџU€ZљXэ}џп=чЫџŽŸџЗMa``ЬљњътЏРљёџАXБљзџіщŸžџN eР,Wєї€йсЩџђІЋџyЙDa…a2ћ0@Ъ ДT€ГГ„ЭDJРz{ аПњЏЅу,јОы§?р&яЦ=ПIїўcпSџuм›ИЯџї“5Ји Х]3?џяš щŸ€ёщ'0`:g|W• 6ЈPeЅ”ŠЧрH,}єПЖїЭћЃ>q4и3@ЪPЇ T-ТZˆXЧАљ €ˆ XЬƒ€5_™чшRђПcъ[`вџ ьс§ћџчЯџџ‹ж}џяŸv˜їO§7€E-/€m‚Џџ{€) {ау3?AШ†aP€tqqлЫџMРиo™ђXОўŸV PPнћщjЮ2Xс"d€%ˆ- €оW€ЅTx `ѓ#@ єбPєŠ‡[т 0OіЬў,Д~ѓяћџ;џљџї/(О§їMОѕпШчєcП3РЊю%PЭWp #cP єГ,E€T}ЖL§n TS@fэгџ1 Fбƒџ%ўзwпјohќŸƒMфИ_@|ˆз0@šЪ “ЂФЩ€V0bѓ#@АLyž“Sфnй`ў єРwpŒж›Й[їџЇ€% )РШч8@)”пAЩTИС’;8€й  š*@фљv јњ]џРUa^УѓџБ…їС) ЏdЮЗџнгп§ЯЏ<њп7ЈуПšК,E|тh (@№ў6?1 NШyЋџЙGџ ї(злј›іўњџѓч`k№+0@)рф]Ярж_7АЉ'ѕ„Ab0 oвР*ёјљ?џgЏќNёРъ4љЭ/РvіЮ§Ly?€їэѓФзџѓЪќ—•39і$лБЄf€ЅXзЋˆPР’Hxтœџќ‡{DƒШ3 ”Š§РŒ[@њд“РиŸ 8H*ј ”щ:˜@$9xтяџ„’ЧџэТ/ќЗ Н№?$ы.А–јќ)АзИz;0ЕSРВu_џkhXƒћˆK m{ Эd\Y €ˆ 6x ˆœ Ќ€)`"ц@эwаˆЈђx34P@eD30Ж:€Э[PчІІч-x Єu D,к ) ФЩЅ“ќ`9о}іџл„žї –mњ ЬfџџЏйёџџц§џџOŸїрПД”&ЌqTФI Юhрд@ТDLp@ •Чњ†џ'МЗйaЩ%&Cд”…”Iі=8U€Ф@t=h ˆ&ОwAђ u ,‘пјќtсУџGЯќœnЖ-J) ьТФkџ;YhУ.ˆчA4і8iЦЭџтЂЪ Чž@2ZC§€5 1ЊF@ ŒГjjюџы{Ÿ;5_!)ъy0= ’Сž§ьC<]  ‡AbП‡cПЎџ-ИбR Ќ2A]щ'/ ЃЦkЖ§ў]№рП-0šюц= Z‚AY”ІЬК§_\LфиГ@\Fj  b AXœQз№ўпаї˜oП€= Š9PL7AGu`а4 Ћ0OтЂ‘ Жяэџ ш*`pшєŸџS—ўз(йuOС†yћыvўџП˜&@gT1@Z…x €H MMŸџѕ=Я1ўžќa!(Ÿƒ“34@š&"RВЧ‘=СoСBялџЅmЏР#E ВфйЕ; ž_ЛћkсeРУџв’Аn2( #ШD@ *дч>ЃЁ LН/Р}zxщ-дcцб&( Gї8L 8љCљ Ю(`)д!šЌяaБЂa(лўџ_пМч?'xа4х^‚V ШЊˆ”8ЋL§/ж—џэS?СтqDŒ7A=мe7ЂyО Z {Т~ Я Yš8џ+иѓ+ЗB0ˆ N@Му№џџЩi“`Ђ@\ФqаZKŸ˜ ’ ˜@Yд˜€АвйуШќ&Д‘џ!ž‡ёabWЋЭ `ЫoЪТяРvТѓ ќђќz`mАЉYг`01 ˆс2PCHZ•cЭDL€ђЈcБEB\џYѓm№r#Ыќѕ 4hl… zJ€б ЈюyѓЪЂяџзlGx 2`;0вВІ#@>4@-A]ЈЛљё@ fh!ъVNacхљŸ_}˜О‚/ЭHљV4!|˜f €ЌV€<* A0uёїџыъў5PЯƒ№ЎЃџџgхЭhљ Ј)ЭYmъТУж"ЊsЌ~ b” :AfфT6GП[p-А†Д ƒ%yфh„ŠЃWƒА<SЋрШѕІ-љkЁU Ј5ИeяџџQ-А˜ Ф9@ФvаšK y8 €ˆ P6ш™‘]~ œ`§X =ц‘ С,Бђ0:о@И xѓ:4РU дѓ МшљЅkп§зеr9є%wq6‡2 zƒ’„ €дѓ№ШЉ8lЗE”ќ“?BEˆ†Ќ5і4Z€%uH§HіШ…"( Yс J €%§ѕРи€їџѕtм`]с6 ЮтШШlв6€еDLР2vТR@'0 Р&1@Mд&x` кHИ%іпCЋЙЗ`ЯУЊарШxSж@ ‚|РЈбЫX‰м†ЕAU!,ж"Ї`ђŸПєљ3cи б|h jжРЦaЭ`œ) €АBKRЎтЏРpљЭЦЦ§_YХљDќ’џЕ=Я€№щы4а4јg”ц1Жl€>KШ…!( €RР‚ЕПQjPьƒznЎ™Аи‡%P€к Fr6cŒеDL `…–Є ќ$-aA Žе@ќdЎ €вчЪџ1ikџWЖнџп9ѓяџ–Љ_С%<юf0j*@Ў !eТ` @”чaeРіCџџздm­Л-§KЁљ41š,Ež`ХDL0CГ(9кж hИ дс­мZ -…џ€ь—Зўя6щIУѕџнsџџo›љМ8[ь#7‹U DДИ 0‹жџДѓг7ѕвaљџ”nџƒ–дц2@†УAН@фq”Eиќ@Фd&h2ЅЈс Ž†%4П Ч HKT=й%!ЁїпЪ>џПјŒџ…uWџЗЭјЌ1>!ЅDˆ\њУЪP€RРЂѕПСeИхЗюэ55№јШЌ0(K‚AЁБoЩ€h‚&GйЬ1€œ @y дИЗƒ: њдѓђ€:д-b€ЌцzФџ˜™иџѓ ЪџЗЖ-ќŸZАуСk'Bъ"ˆМƒ@ 05,о№чџІ=‚/%m*,пb€ДќЊ ulЩ (ЛТV’т]@ФlQЌk P_дкв…„=4 @-1P д(Љ†Ц(0ОqpўWPpјoeW№?Ћќ8АХlKLџѕПaвg№;r™ -Д-Л|ЄЯјЯЉѓAћ Іq Єъ:h Д””їХPg…ё@ШЉ ТEj™дbаД4ЈluD\ )3QаРшт@|ˆАГђџЗЖ/ј›Бщyы#`іvБgўЇиX(06ьћџбЪџХDРcџ u@\ЬЉїAі€кў ’TF 0 ђ>С"Dl l…, Ё)дїУƒ†Яє‘R(v@ЭSањ>PAЕэуџcd`ў/Џh§па$іtЪZ`Ћгщ?ЩџУџЮйПўO˜qэПІК ,щЏƒzО ЈP;`+G‘“>Ц’9l~ RШЫf`* A#/ BR)U€Ъ #h СЪ P-yЭф‚кя›јШ}ььќџеЕ|ўћO§Ÿ^|мЩВw/Œњ Ф; Uh (п‡1@ a#hРУЊ=œЋFБљ €H єР€lб4ЎT*™AБjЃл0 jHы ф!P‰к3є‘щ7hЫ зFFFакР аР*ƒЊ•1А|Џ t‚ЋЧБљ €( X Р,CN ‡РR…0д BдAAЮ" Vh ”*@1 */@ЕhxkdйЫzD]Ÿѕ<(%<Иђ=V€ЭDi` X@ —А,jЂ"gPЧTƒВˆ'"‹„A=ЫЉчA4hАУъyи6иŠqXОЧЙ^›ˆк€ШЕЖ‚ z”ŒaЕry*сAЈду ”@ЉˆАudЏ Zz@ Џ1ePi j­ВЈ:EЮ" ђTИВ‰9”6‚ŠƒRŽ4ЛШАљ €шШАР@.8AљV‹€’6Ј№yVJУVƒ‚фAЩyY,й;Fˆо€ Ае"Ад Рy”MФ 4(pЋ@Iо?ˆЭ4€ А,›pCiиќlЋ=Щ›ЊБљ Р ўО#МIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/state-sync-cluster-group_64.png0000644000175000017500000001234511733011756026042 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<‡IDATxкЬ[iŒ$хy~О:КЊЯ™йeіbwYМ‰YŽХ`lЃЫ‘эXŠc'ТФЂ$Rђ#Brђ#Q"ч…E –"9ёD–q~D@Р Џw!v—cYvwЮОІЛыњђМ_UuWїєЬ.зЮішыъЎњЊъ{ŸїzоЗz”жНўў#Ъ=йХ~GЁфXаА„bзB.GˆюWŽ!д›]фЉЭжўG‡дmЖТ?pиœц86њќмL€з8žг žˆ,œ@Œ@Š"DNLXPЧGїЕчбџW Qзэ~<[k($fЫ‰й>йїщЭі+\ѕ`ќў@с›ЛЉ}ЗdeЈ9€ЯФанI цBЬњ8bОѕјЖФq,J№пМєзA;R<&ЁbЭбюяGчЫ3*z7ТЫіъ‡оc(ј 7џТёKU7улKщјќžбМ‡Я*DВ(Ђ є#шN=ˆ ŽЌ•Ÿ9-сbCorнЧЙяюЛзл…—юl„w(|ВСМсќMЮЭAw&„П‰›9цх;ЭћЪР—і­Gю3;SрrјєаЄЁ=ЇT'†%ъЅ•`вv‚Ѓ1&иЯ9ЗђкнЕЗpOв@kЋ„—ЯNAxŠŠG9fѓ}zЭ…™Q.|ўњфМ3kљќэS + Я?Ekј`% |чТыw)Мžt?ЙF ПˆЯ‹љяђ€ƒ5р@%нgN*h^ё‹Uи7\Xс3-gzо7RјЇзuв №—pwьв-оЧз'wZ ?f“/jЩŒ3}р‡S–(БЪГœдв\утB-(ДCm<ўЉЪ,€@ъŽЂ\„4З™№z2ьЈиXЉЁj+aˆWŒdіК<Ц3ХЗњѕгЫщ˜|‰ЉK-бЈіV…Y3 .qиLјu`ЉTRцєЄ^Вmj9ѕ‰lС Џ"Ё8ƒьћl {bЛэ;j g+pџќEЈїФ6^o–в9n3сз}VЃЙХEШMПwVЃ™Љp5ОЊlМСнK ЖН+ˆ-,wŽэYУSxoœ(”@Ю#qаѓtЄЛыъ sЁЭ„_ra%Ъ_kŠ№иPx=fZљЭž\V‚4 Hкd­J=#жB†ˆОФ ЫЭчy‰v™E–d1O›˜КРG8ѕбЏЦ+YсїИЕ,tН5Д1‡hxгyођqЪ§qCУЇ П. ОеIЯФкn тФw,хйЪЂyІб–†"V&№PуЪ0Ћ”ЉqkzјŒ6 ™кUVИЖ1дŒЪsѕБg›ДŠ‡ŸЛMdj }\ъЃќ|Ы*Mk‰•ƒAХХY)К”‹'™ЎЯf‰)Ц,лзт­уэxхL К,хМ‡di€рчvиН™ ˆ}‚а‹уaЫЕ[ЂХVсмW‘ZŽBт џgQуљІЦИМœ‚1Шhw˜u™šЦ­ј9’ћiЈ]зVЉffY–ЮgТi<ы4yaЊ ф,йm5NЄQХFHД‚хL’#z 0ЋVОЭ-(ЬŠ'бњ,ЙnYGкy…щGJ|‰Г{KІY$Щ:Ы<ЙD+ъФщ5‹ТŠ15•МкJ9*#dTaЈyТ|Ќ|Ёšѕ}šтФt‹н ЄмlоŽ№У€˜[pУОЮ*L5КfоЁЖќаŒ”ыFi|sЌд•ўsq\ј ITZO-‡ЕЉљщoыQ&’у3иSххЛІeЎ†1РЫZшВ_gіџЖ„Ÿp)U`›КX~ –TrОcч€ЄV*-НIсГ`›ЧИВс˜FG/LЂ^к т§RoШњ4Й6ЭK>лї(;ЪєфuŽ*“Д7У+Я”$wЇA*sЩЁэLшaJХx-Ё2]ML2‘[м?ц’zЬ%'…?УрБГbwuТ’вKy“nєY^яt7esЅД~ШƒiЮ3Ч] оRгЛ=ХH>ŒаEр чM’'ЙcœQaq‰‘˜#(5NМ—TѕЛмїbCmяІЖЃ›гхuyђF­Ћs7к"=ъ>с-ZйМцќ>Чмy§…[ю3_PJ[IЮFm$d‘жЖЦЛAжxЃhЕѓЈ>…MІ:йпфлПбячЮзgэдe8щІm ЏШ6Х”]xњ˜шЄаБ6rdїЉCнт`і=|Šдš`?ЧJѓY^cžLщУэзуВŽpt%67­И*bФЖш‹V–яЕ<џgОWОхйХЬЁЧ&чўмqƒм#Ž6Jv2ьз>х“МИh[ЖIпЉаƒ†`Ьa5g€`ЖesІЬЕhUЖ–•‚Љ?ЇБ'‰Q9рфТ р?ьW-7Z'ƒ ЉeкЁvšVyС@kTZ*Б2Ѕ ДfŒЃСRn1эш‘а“фчЗќd+ЅgЪЗ№KЃ3ˆxŸ#ЉюЅіш‰­&йщA ’Gm№Rээјt q”Р:ТЋ=qoЎтчЏtї3в:рЭ^—sœнвg60<‚XУ щ{И/Ѓ™,ЃЏЂ›ДБx'›Б‹ts/Mјю€йjsІН^чИgbпйъ•YЬкјu^њР)wH—hќnЈ+/гџЏ•u|ц-уЛ%зEDс?CvH ъЯХxuэc'beџ]€+g:иѕ4сЈЩ,aѓfддŒ1§€ТЗЂЌ†‹$M‹hsžўї&ž:еCдvlLИњГeZ“‹юk/2ћп.г^ЏeЃјњ_ЄЩ&Г \Яq:ФС№fі„И№]‘• ЇSЗjФЦœ ЎO?уф_HЭ[ИѕЇ—ањхs,ЮfQ‹€Aв#‡hТ{А‰ЧвAЛ? яGЈцкMЫЖiQ)аOЪFf~WБzO˜іZ›јў|6ŠЏУєнчmГА’!(š>МFsЖИMвЪЩЧlЬŒЦМбяус8/uБnWўЖOВётпАH“Ѓ4;B§Уы‹ЌF'mЖ‰КЭ@х—ш>^™T\H™яч}§й њЧ_ЛЭ1 1f™и4Щˆфhхy=Ѓuƒ…ЙЗ9t$Фё…'ПКfb€ЬŸgаьЮ` ›ТЩN+LйК.-­ФиQЊ0sѕ†sЫQnRbз“#xШjЭЁ36ZaHЙЩј„уЗ>НЏeљTeŠ/ яШЏ;iўUjПR*Г ЗоFьб‚ы8ЈX XИ&•1Qe­ёщ 1С!˜S„ЗшЭПLэWНЊБ‚ ъŽї;Я„[€сэŒОу3]F(‡ОЩу–Ž‡нž AИсХїХТЪд|ЭЋСcМqtJИ&нР™№б‹€Mѕac5ЄКaлАН\мѓА‘№ВЕ\EшšWЁT-@жh;&шЖe E†KЕЩ§Ћ R-FkqƒЄ№Г•Э@иLxљQГј}нЏЃьвџ­˜ќЫ!рДЫЙtpш6‚˜i9(7шКL‚0`Š№Ђ\cYГъWxнК‰eI— ЪМg;ot%[ €<ˆ%žђPчBkƒ Y_‡7J‹LЗ„тљ“Т[&њлFш†з0АD­›чЊbі;ЖГѕY з mg‘Љ•ЊЦ\…ЮЩ`XћOaЬж Ÿ?ёћ†OЈё’эšћTэ*у‚_Œ[ €•q_г_ЉБJP!'шš`a=aќw7EсSѓOSŸ€)nUr< э1ШГї(Е† .А…1 ЗЫЇZЉn\AЊ;!Gyе*‰!шh„-К@Ё›,&АYcГZ†]gQСЄ=ОВчПŸ)гян*l—БТ€ч№м8ТZ/Bs­Хо"к§6Px.rqp~Uнi`iњтCM,ˆАџЦ.?а@ЌъЌйщУ,’ХЄдЄ0C)“{ќгCВkQxЉїЫв+єв|Ћ!‹dщ2…rЎaPщ уЗqцХ%Ќt–iQYѕE z@ бљr?ш8§Jˆ…WЛxщёUьНБ‚ЫЏЋЁVЎСUОщЉ‹p§X*FѓXgШ $•1Ѓi–дЪ1? `Ц@'ћС`ФsК.ФъЙ.NПмТЉЃm4W;ш=4ЪыЖЬrИ ъDпёЇƒ…Рm>К†Ÿ<жФЮCeь>ьcvЏGjУюмФ1eГ­еX-'AdбЧЕ/Я Btš4їу5о%kш“=eMв>џЏІnЖ‹ЈKсП^ ЦяSЋw2бэ—\-Ѓ:чbўАƒЦхБTˆ@zQŒcпLSСЕwИ†рHcХŽнЄџFЩъœPhН›DFш„B?Kџjp_tџєdt §л/8ФЭпŒ_ euTіЋѕЦA`юj ЗЦбoЄM“kюАБі&аz™BŸФф$"ВNNђмoіП~ чљЯuЉўп3СјnюЄ {ђєYš!ЮўƒЭі˜Ѓ#џЮёуwЪ^љ/šпъœЙp:ВХHP<ЯKž/ќ5в‡.“1KžR=ТqcЫѓяŒ]њ_,ЛьѓmP№wuџџ`чПsѕ!wIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-group_64.png0000644000175000017500000001616611733011756023736 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<IDATxкф{ ]хuцїпћюлз^д{ЋЛ%!Д! a,#^FЖх‡/ё`L{&$™LRSŽ=БуЉЩTт8qт ™„Є l2.ŒСv№*Г,„BBKKНїыхѕызoПяо;пЙџ6$cgІЋмЊЫыwяэїўsЮwОѓѓ_”чyјeў1№KўѓKя€РљЃгy§j*`ЁœX–@ё}ЦіЖСhС§ћsМ6†є{жр3ŸzwUjќоcлРЬˆїBРѓ~ЇћJѕдPЛB‚+yю0yиЙин 4\р‡#њsНw9р5ттЊ\шё, Ѓ36ЅёЖsой№0о(у+K6O/т@Ў 3Ь{dФ(wГ]qя •&&b5ФЂ№0Гт№zHєgфц'ёољ­јуѓuЌщ Ђ<<‡-gцQЙ`c Ђс4žЗТЁУшP9oМ+Л€jћŸ4pUЎ„,ќ?ђфŠv€}љЕ\AE$лі,ё?<W$ƒРзG‘™Ц:ЃА3 ju;гЅдl эOVЫFx.‡[_=Ё‘jA<\СЇ˜^йџ ѕ†`г€G˜Уё0Ж№‰HЗнаŽЮozm‹зАквАBtШB•Ц7€:!рђ32]@)ЋАЫ-И`5ЂnYЈЈbuбћ§9ЅЪ+в‡sР,сšЁaлZЫD№жОtОЋx#=СHяя6ѓїс%`Œї:B’tJ‘Žhд4Б…ш(7IЇ”ЕSŒ'АJOрWУv§T­%xqn+Щ‘№ž|њЈƒИpэ2A'25эIŽфhЌœsyЎ-$шŸ#šAž&”ˆKl0MƒыN_r?ЛЏ™ ЊЙr(УVаЧмЈЏЦЮŽќкž.Єєj†д2Ј8DЄ|яœ‡Б9Љ@w‹‡-н ›;™ L“‰ Э%Ёˆ5"Š%б.…rбS• {Јти]Ўc­,Ф,ьГ‚јPЧ*миЙ-ћ6 і‰ѕ@Ѓ›eŽOгћNrА4&L)_уbжl`fƒ…ыw( fЩ%vYыQсˆџ>ž!BшНЈ\пZѕШbЮЛXR+ŒZ"ј\џ*\Н‚7“Щ{И№$љŸчтЂ&Иї ~–7Зђ5‰ш˜š№0<ЈаЃБ jqS!хmQ-І–цбhMЈт=ЁпЌ: щР sРXWПЉС;‡4d%Ї+Ж.‹Gећ^фMѓМЖЮdd=x”ƒk‰]W1ЖрлыkЕeё?BўR*{_єrшЋеWb!FYлGЩ№}NІ ѓЬ§гŒ ХO ђЈёzІ7рмК7лзŽшйE4ŸBˆŒgФљœЇћBЕЄѕ€Wїи/xtžœОd˜XeтР#Мы›+ЇnРўЬaИПѕ  б Sg~‰€М­amВ štЮ†{{Ђ8Šœ/ p&Uohі—šА|~єбр—WёяˆŠ"ІuшуіЏОˆ{WT $ъИ=ZУуs pчъ:ќUG ѕ_о;42Ь4Йjъэ]RyeГaTh–<9D*Gcš) ’ци@ФШ!UeTrH­(|сўWнЦ‰ж4ѕЃ…ŽDП…†мH- H*вЅE цѕуд_гѓƒЙDуљїˆ„ѕ‘дТЃEƒ:бвX@ЁBLw FVИјRаФэ]ЌѕжаDШ сZжї[h4 ›' ѓИћЏб„­МvŽя+DM2Ќ“#§A] (Aƒтk™\P#ЧЈŠ‡Ю5jЉ'3+Ъƒјј[ћјРjТ–‹ž&ƒWК Цљ^Ю_E9{<ЏЯЗвие„јy""Ч{SQџR:K|_ЊiіЗљ{~ЅF8ЬVЂсжzЦз6ЖЈV”оГNП†а+k#+žNзжНТfІС•М>ЯїМgЂЄЋDo\;Њтh4Щ‘2'А'а]ЇшНЛЭXvоXh ЋПaЋ}aE9 CцкўbCЯ$QmЅ4Л—x,ёКЧїЋ“:їgk:Пщ”ьИV‚!f:‰™о^|f|X=˜ЂЪ‡и Кџj№FIѕоЇЈиў‘|kL+н в‡xUP1ЯШ‚–”Ѕч‡2„,]2YеKug ХљбЏН]=иJg,сVLќkкўЦ0™Ч‘{цБ9Ык~r„L-Э оѕэ:ђBf)žы A ]"‹4ХіtфЅц—щ˜$Й€$Цч&.ЂЪsЗEЭрНПmдџЫV№LpЎ€?xюeї–мEч&#cІJa#ђ­XЦwлzцWs›†оSд§3L‹ЖˆFtwьџNВC 5РRj˜/Л{юИя{јmЅПO4N-оh џЗг(ŒќGмѓхЛр–л}!SйЛ„Бьп{ЖsŸкДy mС’ЌЃыoNмGнјИŽ ў™Vђћчs@%†яіAиK-™Dф:•ˆ§–]ііЬ••UъцHxсХYр{ўyн"›Єѕ€нtDГNIŠ”4*Є™ШчŒЬфЌseфЃЧЮbqF(љ>И…;0=кцCF~d’ВњЉ­юtъNм2Ь?SІ1у+ђѓr‡%5жmОњуѕ‹‹з•сЊzx.TпiяРкXXэZ…%ЂHR|„uќiЖУйWј%\ЗKО~ ^ћ§+вP“М~a’XвT0фxыв‹Юg‡ŽО smvўяЯу”§cœј,žщƒEe5eІe†rН~’ЭЏ"7S@tр>_Т…gwa$[C$pщPTXбˆ?Оі‡Џ›1Оa4сюA {w„0ГФх…`ˆ&’eЭ/1КсV$ьЯeујј$b—ІАzjAЯж!1с5n‡е ?‰ГЌѓ'Пq›Ўь‹Ќ—'Е&H2uоoZ˜kяСš ЬNЯa_ФФѕ”ПынJ-|Sщ?Ќ1йгЛM!r№УџIЮoCkb:лCшьб]S!Ї5ВД›2eюHP-9ŠъjУ#ХГ ЯкQЕkˆGbŒі4Jц7‘(ЛўЂ2‰u~~ќњ&O’ыfn~ пŸYDюм0оТяйКPРŽь,364{}Ћ^70€CН12ЙxGpьљыvGžlnпoЂ?Щ(m: Д_4ۘˆІѕ–RyQo*КЭжQŽ(SbY7d,+†ЬъНEžƒˆrkзЊќ|. #”zФ_ИшыL~ЭЛƒЏўnђ_‘R­јc:ѓКвmI$$Њ^wxЧёљсеGЪ•ЪЕЭ,ОуЬ:ПžЯ КИ2›Х&ЗŽО–>мюАМdяшСЃ#6Šэђхй`GЬиА?~x/КЮt ѓь›?Це0WKл~‡їdѕяe™А\аJE:Š1ў ‘NшbН/Р›.jс Еиq#*WихЭŒмщYщ3F=pС@уѕDј…€s +уeо›і2/vќФWЌ—fЪ; ™ѓз§™п;эЂћЭЬŽ›ђmЕуЛЏэ~eцш\Ѓh•џ$В9ш+ТуМэд™ЭРŸ!унVЦЮЛ#ж]„Гаp›.’3 ъу:Ѓ]a•ЉАъdIƒЫŒЅ5“/є!†јлSв=о…*ƒaˆZPRs+СЦЁ“зегЃˆ\sЭŒLЊˆZхgs€ВЦЇ'Ÿ=;~a кrЌБа—Šу{Ь„ђ$ юж=f–ГЃ4]§‡ЈќкјФєк”§}е{^ѓaГ4ш"#i>шТБЂ2ћ=4 ЗУАтX]г%]‘ќ„Шž„ŽКУEWцhш4ѓŸ]Uˆъk‚љ^qu7vЙдYTб §Щ‹v[аžџ‘ЭСkЮќЬЯфЫ ŒVTЕ/К!ˆќСВiЫїКMЂе„CѕцшuFУъ7U5[лoзь§NQf9цюЈЬІzШEѓ1œѕpЩь #˜§r:ZІазYЁсqпpЯбъ<˜дћш5"Ё!RЂРЧбАі+щ€˜ю™I<ў†Ѓ%S•цбзЂScЖрs‡бщВёTƒюиФћ1={F9•GеПфГЙбуі}ш|хќ=цf/<8аGсU†zЛ ”СЃЮЂЧрxўˆGя+cѕш`’ьџеŽjЮў•Т7nћЩЮЊЇЫ™i@@§'lЛЙ›C‹‡(А]“p/3iЮ~™bс4ЛЋ3ЋиNndЯЭз5|­НФv”•!ж„(йRY %A„lCeТ№ЊfutqШn`SШЦЃсх3b˜›ЩСŒ’PcйћЭ yЗi:lќ ЖА ЫЫЋщhQV—ћLГ ЯжЯхu)г‚’FощšћЧТŸЅnˆОэ”ћО$ЪGnCKb?ЌjzZњБmWжпNƒzuДU3FП я…рОtŠDlˆa ~ум"Œ59Ў жML‰ЉМ6жЯзц|žЉ †#в[P‘PХми~^шŒйX\ž*ЩщYдЯзPъЊ!ъDПkЗКЗКЋhсi2сUFя§9D‚СŠ/ЮЊОbПЪr.аЯ6ЎЈсЅАзšЖюЦКо“˜:ђŸёІ§~ikпNИО“љ:Є?P&$’ыY’фЗџюѓГ>б›В—ШЯqyЉQЌ#@0 ^Шє1ђ$ЯдЈn=э†VybQŒ( U™Ждk*{"Дaл‰ ƒ№ьх@PЃ?б3Цћ0Ћ>\эЉоКzc7QNеЭшXќЗpžD*Kъѕ№#b3s’ВŽЈPl@м?IЪ#ЫИё \Rћ1ИА› ыУ›џˆ,НA,Ья“\]чїќ рЉ/СН“Н)aІ[AO‹‚1žЯјЈ6#)=Е№€ПЛЂє{)ƒ‹E-GSб $3Љ‹OСтЙжх љ?_Ю~Чэsї mkYћUЏрЇ@і`ѕГ m(зo9Ў ВйђыV›lЬ…˜УЗЭДеиgoм}•ь КQЁu ПЕЩвwсЗЌЫп№УРQТžŽQЭE9л‘tпКЦž3Ч‡—Ÿб›хbsЈа*ЪЂD‡7ФAЭsхj Й}ˆХЦHVЧќ=љхаАП*•Н[ЏйшѓAЩ-љТ‡РЦќѓиуLƒU†Яnоƒ5`њП{ќ.%}JЕ™Šьsхœ=о@Д7єчяН8q€К<„Ž]?бтvEGM-Џ9кХЃ~­к#Отѓђu4И`c]ЛИё6џЅ)…ЪявАМG—'+h>|$†K/.њ СCSsЗ{шQеШP оМўЇЁщsГCсОFЏђ**ВЅ,ъ—аxA—ŸzWд{ѓПЛщ­1ІЎыѓ—|2\$G„ЊSіgПšj\OЦ§ЏѓŸLѕšЛ!Mш ,œdt‹z—E^q|$wt—WяЫ"к_РТй2&žpАDMeЉ 5уKŒXZф …–\'‰›МхUВq~юп4цВџžѕЛcй‘X5Yy‡М–МIЯEЭЋщжwкёЫœDV`žЙ!‘_Нbn;оTtжyB„Ў<іб“йор,ЪQ$?uєŒёœ7ытач€—ў„љyQЋ;ПЌИZNцEюжtЙ Z:š*КkїzjЫ-iєюЩ мF‘"h~J—M+Є7%DЫ›гь=~њУK+РH8Q\К№МђшW–uРњЎu?(>]s_<ЌŸRЃКƒЭ~iЃё>Ы3ЊщMБј[кoHЬзf­sѓg•влџь‡/ЃZK #ЎYЙjиИэ…Чž|Ў†Џџ)0љИ†‹пл7IP<']žП9`h™лI%Иі–0ZЎŒАьњYKЪoŽъЭўоl>x(Й-п+h2(€ˆ›l™О\5c\ћєRЯŸМaY,™…wДѕЖ|Фˆt эГП РL§D;™m&>§ЈD­‡Ÿљ†Т ”%7ˆБž6ZHReЪ`PBіvфЁСеїЂЗГсЫY_љЙњa!щbэ„uXчЎD.J КЛXыw™,• Х рщЯ)Ьœ2Аўz.–(X"ЫЇукћЂЩуфŽxXЫc‰|š E,сRž ™СJ-K‚#/M"Дўtшш7ш„:й,й#у“чHLЬїП=ЗQžЈЈаU4Д ђс_‘W]йЌ>гЏн^EЋХр€Е€бРрщЦЧᆋњ“кмљъ’рШŒ~”l‰чцЉђВ‡ЙJuўЋќœy–а^НXy˜HМ›$”(•#„_œŽ] SV5Ї_‚І’§ъѓ|ˆбмLЬ]жБZєСbДєюЎumЈC/хO~взФPžЉЁArЋЉj(Вг"74јоA EїŠбoLыЯoЬЙњœЉ|ћоя„ОС\Їь5§FGNJю‹ЮgФйŠмЌ7 dˆ(Е]žА:њ—КbуoўЗ"EYпkш ’Сц3x†F”ьЯХЃњzБЌ7"ќ)-аs004ЖЌJnљWvѕPu†Ppuэ'И$NtUnЛ WпxБСъ ёЂњТ"‹ѕДEвСЫЁdVЬЏDЖZъ†‹СOŽ`72бѕињQ…Ь=V’шЛЭTД_ \Яffšu~ђЄОGˆnѕ-——H”DЩ{ƒtЇVGт˜КШЪе$(Ю“™СR]яллЎOвˆЦf–Оћ—яЅуFГV‹ёўџP!ˆЅЋКЯ№ў­ У1"‰…є\Ож/6ќ\ГЇ=ФТ8нOЄ6Ф№7ЃсIЌыяР–(t\ЇЕ-}Х ђъ:ЭєzиЩћlJР:KЃ%[J„ќв˜&К–N=hє™КЎ Qђ)rТяЋ8^Э-ЈіXjаФhоQщ–o’Oю]жщЖфљBс†zЂю Ÿ№ZŠп4ХŽ €ађЩнвd'ЈЙыKhЙЮѓ.“}„#C‰RjGє“PХ­ KwahаџNi[­jХж'”Е#Њ -‰-‘dП +M’ˆЄ…s:чг}ў34(Ljц—5Mа1љВцљ|ЫrI„# ЪC*•6њVЧŒв‰Т‰gбšЙА|3џFёhљІgЎrI$=лдNhv\~Nћ3ЙЫхЎщ:#аbшЩКбђH§Юш:ѕGв_ј -ЯУ‰БRўaвхјљ_еs>П"ˆСѓњ3§9@ѓ1R1ДuЃ6ЎЮѓЕœЮyЩK!РKszЋI4Ф8ЏЕЇЪшh?шх&яW•Ъ8 0РdЮВЇїмхїgдЬЉP ИпШ;2ƒЩЯc‹Жєї4о•ƒFVFm”OзQ8XAmКёъѓ‹ТnйЛ\џUщlэ§a#ŒА’ MЯ<'.&5љх_бЌОи F єS+jЖФbЌяЌ N`FWплŽ.}~C?ф‹ЏЮ„уЙm='Аяca~јнЧеЖЕ9ж jе›Ёъх€-;Y(,MЖЊ lk̘4Ѓз42іnъRЪ‡j~ž‹"ЌžАп""ъд§NСѓЛAфшђ„ёьЬиМvxzэ§XЪП УЁmЋТiŠБc‡€­ь †іzНbp@Z>QƒЉц| I’>_Tёj;+ ЄS;ш€)Иу5Щ$зHД7ОћŒђјйЃпнћzЛ—i‡eЋЭ@Ы5 –ЂЫЈЖЈWџч:`–%ЏндЊpСuUI=р^ТіъX}•—щяМJъЭБ?ЈЛіŸк“MИЅкПŽйSР‘oпFЯ­ТtAљzНќ”~>n§{фiщ&ЉU›В2*ktHЪ5L-0„?„}хœ”GAC:Ѓc ЊP—šo"7Б gy3ъхcUЫш\ œ›дхђ_r@€ЙnnЙЌZ†вџ}ђаь і˜­ЖешЖGuO љЮ&q&К>јIBoСŠX§С~ѓcѕЩЦ ачыеѓЕуЭ§8ёŸ~–†М‰Й|uВВ37КЌжh..uР:BK?YџMМ/Њ $'yNдЂЮj1GЌ0їлзАBЄ›šz|&ќ <Р/’44cќоЩЩA{јC4d 1ійђВˆЁpTьr0HpJКЇцПХDўСzЅў`*ЙЂzДАЯŠ’F>[›j„SЛЂЅКН‘вqb.†“о*ѕ›.…&Šьзімk _t‘ЦёѓЪ;.Oж:3]щžЖ[НЅ яЇHйЎЊyЫпШ Ќх˜yЊ№Июљ_™дЃЎ-dћ+w2eКЙђRГ­–чjшЄrн'[CFZЊ„066ЯˆјЉу;ЋЙ&iІ–sРБобš$wљџ=‹›§'хч_s}нOяЌќДе?ѕћ‘џŒ=A—>Ћ[fлžeфОЋжіЏЅоПЩ>Ы/ƒЊЄ•ž”ОsT{Я Ы R?}!=ў і-L•Ж КjdЯАJwИЄщœ]Єы?x`VŒЖЖSdџ’пНJpJ'oљlŽўьЯЂшGТXˆ,p•F`†œСFЇнBЂOУZаoiјBSыK Ъп2я NЃTYЩЃqЬ^ `2+{ZѓWl=елв1‡xђ[ќќЏг) >Ё^ў~Q‡ХŸqcфіушљНеMЖb3Ћb>‰йLа…sЌ—­ Q*М Ѓ4Щ2i3ъ}I=э)ШDд-!Їрѓ8~/.ŽЎс=IЄТІПu^Љ7 ›Џљ;ъџЛ1љRY?Щн$qTзм;јџт€r*BєІЗГХЅЈ)ЋE2ќ#Ијdžўі.єаб—A%gрТЈžяGCК<.Q‡7мy\Бц ъўЂ”Бh7гaккЏЦфh+ЌшiДuм Я<ЦfЂќЯ>ђ‹zDц#€НyзfFŸ‡ЧEуO‘KЬсhГг>sFЧ‡P`вЇЂ=hE#kЎJ7аКъ1D[Фќ™`4сїиБфˆЖm…9НŠ$w )uсJѓ),Ќ0ˆt•hV(uЃdэ0л4‹E=\z’а}Жt“УOcb~-тС вщ;‘ˆ]‹ь‚‰цuяŽяcndСŸѕ_~>нЫЫ.ЮуЎ›э(–U<Ы-ы—§Ÿџ? јkтAћУ]ьIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/library_16.png0000644000175000017500000000147011733011756022575 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<кIDATxкlS]HTA>3їџ^u]wГХ1гА5Д,Єzˆ )"BABпЄ # |Hњyё!‘Ј^%‰$‹,аД2 Št5Wзиl+uнuяКїЮ4WRмЕ3пљц;3ч J)ЌGв%"‡Ё‹aCuЈuЕ;‘€7ЩZЮhЂ6*ѓђФгКžЂОъwЖ›Ѕ}wв+zщ€жhW„Id єљšSsтЪ=UfУс \gџдтеЖIS пПььQф,Ѓ*))qЏ%ZДF2ФnПn4ˆxўСч+ЈщYqзі.=zсaњsЩ:?2‘~ђ•зU=\eхёqѕШРпxгœлвfѓ)fnЦн‹{љSхЪТr,Ѕцњ˜ЗwфOE“т †‘oхФ Јv DЇ€t—KTА_А^Vџж6;ЏЋ’Mƒь#юq.I#ž'vЬqАE@б"1Š, ‚ЬЬs-Ÿ—EBб їŸЂEgFІГА"Eзмr(ї •“1(‹ №™)y$ьЧkŒЫJ—= уФ>`ŠJ2ŽGРГњiВ)Š$Боjl(іOуƒѕƒhиЖq[ @’†“uАZУщVEƒ*ttyљ€?ДRQ[ъ1Б@жp‚%Uте “0Š3MŽ "І5pEeо\дˆЦ–C1“БЭря№ЖИˆ žС+œ‰~щ’„Сž*!Ыѕ€Њˆ@С\јБэМ7фbo­ъБцФo,c"/§_§л™ПT›Ф[o ŠЌлКOЬ~œ/ uŒЛ1T›" х Чћпaкlъš wйЎB9яl8Јыц{Ж}њп%xvў 0mя"c@>ьМIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/queue_16.png0000644000175000017500000000060611733011756022255 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<(IDATxкœ“СJУ@†џY[дmэ­6P}ˆ\„іюЭsѕбдЛрM}‡<‰AЄавЄщ:лнMšИ ‰{кя›fIJ‰=!ј/џчРŸя%%њсќ%эДPЫЙ j™Н6šЌ9Жц№9РДФЬ<\uWј—љКk†иfцщ›QЭьu `kОзцЈ†љю6а€fCрЦTч-рgђє)›ЎЫ<{ѓ)­ u|-€w~)y"'zч,УeN‰[…hSрЬ”Ќь$MвmNjQњmd:k&НD6Šц@бЗF“HŽ_S4чўТ>z• ’я\)~нЦА@П§f‹IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cancel.png0000644000175000017500000000070611733011756022051 0ustar sylvestresylvestre‰PNG  IHDR‰ bKGDНННiBеЈыIDATxкэ”=‚0Х_ƒq2оСн‘‘ФАЩЮЦмМƒw q+[уФц@ТLlˆ‘…tЋ 4Hi\ѕ%šЖПОџы№WOВmЖqM3гd'8{ОiЁМјћб1uQbГXŽn–…‘бЖ HšРаЅЬТ‚WИ>ю“€J=— VМž8оr šЏЫJ‰‹Fk‡ВС\@-ќ6WkU3L№jjЃР№švЮpкy€§Вk@ЩтDС’œЉЙhА]­Ї;Ќ‹Rƒ эaи^`>ш“€Інd-|.гыљZЎуѕиf€mи…дEzTXtSoftwarexкsаPжєЬMLOѕMLЯLЮV0б3а3QАДа70б70TH.Ъ,.Љt(ЎЬ-H,ЩLЮзЫ/J|jљxіТ3zTXtSignaturexк3HL16А43H233JЖ43JK447ЖH57J66H42Hˆ$Q”Я;IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/warning.png0000644000175000017500000000263011733011756022267 0ustar sylvestresylvestre‰PNG  IHDR00Wљ‡bKGDџџџ НЇ“ pHYs  вн~ќtIMEв /eГp%IDATxœэ˜KoU†ŸsЮŒsЕ“дЮЅЄ!а$%N“Ж‚--RY Tт",иЁQЕ JT– д?€+ЖЌX !$›н‹.Е)mвBг\кму™3‹ёФv'ОEbсw•ёœЬї>пхЬБЁЎКъЊЋЎџЛ–GRrэpЛьЧГѕ~<4_ЋGS2™БLyТ•южšCь+Рj:)З3–ы–uКЭЙM5…и7€ЕtRfa2` Sp$fjgпV€–Ч6Lx|Pc€vЧpЖЃvU舕‘ЄLf,§аgї †ŽуQŠ˜‚уMnЭbе`%”ћОp3“Kђаыаw:ќл ЃјИГ6]s€5рf& A€“_8ˆЃ8~1ЬМ xТ5МoЈЂІQыЬљ‡_uђf6žP›U8вX}+ерС–жщ=-X+LмѕБVOqьb.dŸkЏВ 5XHЇ$j€БІц†оXрЭO9їљ2mƒ*X‘0š‘*ЋP€ЅєЙыЬd[ 1 ?^Ы3р:pѕ/oѓоб ЙОъs у‰ЪЗеšЌˆцŽ—3џќWaVППšСЗ0џК;rылУАˆ;†tƒSqьЊVF’ђЗАhC€cяЧlmd$| h‡Y$ 9z!|/єХ*ЏBеџј0™БˆRФгЙJша“šƒIНi Ћ0šс ЋPР\:%wММСН”3!žт™ў№z Wc"šшО(FЯчТїИ/UP…Š–г)™ЕТƒьрŠRД ЦџsТG)И7+ј6їЙHUAЃh7šnSYŠ*XE1™Б"JqђЫТь<|ТнŸЕL?Дц#žgУ(nŒ1кш–U…Šв)™ёцќQŠнЭСЬјкZ"hVлЬ ŠDо,pžmn(ЫKEŠ)Яnю"брц›d4d<ш?Xј=@Ш­;ЏFС!ЗМa. ЪўЌ-м­цб<7ьrъDŒŽИЂП;o u |†’Žf<б\r• e?RльhрЪ{qК:4‡К oНиМуѓЂЕcйYˆ;†СЦвЋPжи/ЄSrЯўXїУ —œmљ{=lк­йЯ_џћG>˜ѓ-П,­ёѓткžўЪЊ€‡тnоyg/ѓ Kg.Я1ўсцэЎцEƒgТЃvЛ1є8ЅUЁd€…tJўЕВyжНdvк|CŸ~НЬ­iЫф=Ы7?­5ЉёPіЄЊ§ .G›ї>j— `•f:ПїŸ*žЭH—Д††˜ЂЅQ]ЕYb ћN:ŒІзйћŒ’fѓВ?єŽ‹жŠь.ZдаgяЦpЙќv g_iоumЄУЏeЗfЃщ-aK-iˆgFКфњКЯДЗНѓЏ{NiSŠX8-аіДFЉв_3w#У§п`ўмо№љюб2ы™Ђ>Kš”)Я2эY,…%л ѓЯЏHо§ТЮ_/jїнIЃH:†'cы™ЂоJјіб:>=ЎƒЋ I)Fс(M“VДh…Јp)fЈѓбuмhКі˜ƒ’пZkhUащhZД&i шt514F…П6И*WЇИж4n=Jч3я‰Аd&6<~X\%‚Н–ѕ"‹ vS‹VtНй<шќ"џYP™‚Яa)ц­хОgkА“JЊVA@ЏU”ЊJA‹eОЎКъЊЋЎšш?ѓ˜bAIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/addresstable-ref_25.png0000644000175000017500000000160111733011756024334 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<#IDATxкМVпKSQџоsЗ; У[В‡;d ЃUтƒlšљтSњ”LBRQџEoQO§ 4ah>HŒPЋiрKВРAэRmК‘Жb5ЗнОчюўœS/B}сpјžsюїѓ§|?чЧeDQ„m qєМ{„ Ђ P)ЯfЃчnти%†eяi+Е.аq‚[‹э<јКдsзШd2099Љ(fwZдОЩaЛCчcГуиОЛЫщtB:Ъˆкиииj-ndWАч9љ&Р t•њ6љМ‚фяљ‘ х2+*jВHп8,‡Њ,>ЩБkз-3Ь3џуПыЏ<” “pєКIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/user_16.png0000644000175000017500000000152711733011756022112 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<љIDATxкlS[HTaўЮюбНЈЋЖgНЄІЋ]L-oli"B&E]$‹nDНѕєкCoQ>DЈeЁFНDe™тf)ІIFmнu/ь}—уЙќГКЖ ќЬ0Ь|3пЬќ!ВМhнѕ|PЩL…[•{Y-јwnM›г ;3э!еСпЗЪ;Й‰Ююgh9М'OcY *jš(­Жгtј„QГЅHаР4ѕ"УїђіYлweгxKB+}ЈЫЫ‹ž`8ђD•юt^YБQЃ_Ъ9 ќ6CЩКОЎѕZB'ž4&ŽGгўv`qћ#z5ЯюжЄHИжз7@` Ё+­§ca—гФЈi!ц$œФ'%C<(CЉ<  Bа+<ќeТі)щiгŠBŸпfxЉът‚фрdФŸЯр§1!Уї7g ЧŠQб-0Ея#њхš“:;Г#5CГЩА6­8&ПСoŽ„œОѓГoЬЮЁm+)ШВффЬwкš/\†žКАE“Ю;P(0nЋ§Zш9)ЏЫХ–јJШolЦ­њ8уIвз *зяž-l" GКžл‰еЫCнiМ8н.ЧJ1БМи М!1СюBFЃіŠШ yцю*мяsРщсі-тњеѕquHT™hћq3ШЩRхђŸsЄм›…Ѓ;2ё _Ђ@KЮYЏњ­HcŸ8lь9ы@­mХ$ЩV(qMфФд‚š5ИћШ‚ +bWCођ`lд‡ђCсАВCтЉИKдЇ+ЫЌ l{љЉJ˜*вХhqЏз‚яpYXДШE]‘еЧ+agЏХ,В+ШЗ$$IџтЬБBLЭ0:сУ…Ж|дoNAОHЁљVр)†˜Tqпы№iN€:)О–SЂdѓNг’Вї ЊŠGў;DyКUћыНaz@!•сЅn‚aВ’ЄMSиP Ю}zs“% №G€ЈuUvyWџIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network6-ref_25.png0000644000175000017500000000231711733011756023463 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<qIDATxкœV[LUўfvfіОPR"ЄК”РSicЏФR“ЦGд`зД$€OдISё'D“>( Я D &О iRcр(ЛыvИьюмŽџ9ЛCgY@№O~ЮpЮœџђ}п9Г c џaccc™p8 EQ IјУ0ЫхФшŸЗ,kпЧѓЪ1С%ђШBЁzzz№lxxји$TP"‘„ TFGG™Іi№љ({$‚h4ŠX,&Њх&Ы23ХГъз ј$˜6CЮ`а-iC‚юHАHП„ЊАŒšЈ‚АVиo˜&dpp№Xђцч * hд>ADt"#mЫи•˜Ÿкg‚” "‹бW@ љМAЄЙЄVGUЇ˜ч˜sR“[тлЇ!K№dЈ“ %ЪћЄCŒКЋ JЈ ѓ‚ВЭм$9Тл4KHЕ Cг Te ѓMнйоџыŽŠ]‹ДYІ(&шcгйP ­2!eŽВ{Y(NQ9^RѓŽOЈця”Ї:C…^Hђ№–zъsВГЗEUЕ2R7іH1; ЩЌ:е ьь ЋыІуўIІg‰јT‰№@РW<’$Яг4ЭR'љЂ<НЄfˆ‡”- RmЊAПѕ=Ю„dдrR‰/Š/пЊФШШˆPЁыCCCAOЌР*l%ЙѕДŒдN@ъН{ ЙпО§jkkEŒt:­ЊЊZц(‘ч8яф)™gњЉIэЊџ ^\D0Фя?-р~з'hЏП$КљѕЩ/­ŸЭ|œg(мEŸОљyЇTlыDцоa7П~ OцЊЁN_b8ŸК?ј™J„EkƒkВЛйыи&йzчИuwПƒххeш’З~Ј‡­Щ‡UЬ‘H$Ъц''нommў- PRЩЇСwиZY’ееUЄR),..Rхн—љћЮСыё+і…Ш5ж˜М!8q?_iМ†WЂзс]cм–––XGGЋЋЋ+ёЖЖ66==ЭёbуупђW‘џIž"7и LмГГГшыы+љ”КЦЙЁФsoян;4\ц њbvИЄњЋзХ3­срšPW{{;жжж з мx<Ž••477cjjJ|И<{Hрrќ*&џ˜иWWХЫLРBъ*SžЛ&8Y__/№`333шяяGSSцццФœkуя>LМщюwЅК>Nѓт]‰vvvЂЅЅ›››BЦќзЩѓCS Єc~‡зD”ъъjlll ЁЁAL –І>њцЕs‘Иxчљdeъкч$щсф'~”†WЩЯ“Ÿ%uжМіЏ7…Z•# hОIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/physaddress_25.png0000644000175000017500000000106011733011756023455 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<вIDATxкbќџџ?­КРч’Ќџ[YсФ'dˆˆхБ šкSџУ0Ÿ€ЂфdМ…хџп’єџ вџŸdgўтЃЋAЧZSў—Ь§Цтб/ўƒјШђ,И\їmСlИGA>B–+бš€Ёž“‡™aхё "ЌrX-љЗxdyL{џџЭ•бџНбдƒ‚шр“џ Вl`ў+B–иЇ2ььТG]lŽzЭg˜Ш0wс|$О#о8aБd5‚q-nА‰31ааХFXfOQЧ›^ЮЙЩˆKюѓвФџЏї.‚ѓEуxЃч3bФ О8 ?w™ўџћВуџя‹џ^`іФЇYœќ{skђc:|їрЯiЮџŒd@4ˆ“Ф'‡ўџИIрXT0zLuњobІЪ№§-#УЬ]sl”эЖgэ‡'Ш`\rЄФ <3.К0g0р“@ N<и8NVо› ,/А‡>9bK•{CлNs Ф‡|rdхrБy‹…вd‹+“";€,Ÿ€’rлЮ&”`ЕUЖgФ%G–%ј’669Šrќт Г‰’#лPв†T”„хШŠxR“=#=к]IGЉ“ЫNБiIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/domainname-neg_16.png0000644000175000017500000000104211733011756024003 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ФIDATxкœSЫNТ@=Sк\ъ№n n qMJ\ht…;%К€•‰И‚•Ц•;…ўю ?р'P#%ZІЮЖЄ"‰Ц›œЬм™о3їqЪ|пЧŒ-J,IЄ%є№Ь“ј”p$>тыЭfгчœ#‘H NУ4M0ЦfIAyž‡~П^Џ‡Щdhš†JЅ‚џXН^‡Аyё Ў3DoгЙРиŒо?=<ŸЎ`yяBfу\ЎЊЌtзuU€Й` ) †OgЪ'"-l‚6хYbcpЇюwЗяƒDX O0ˆ@юOібэv‘ЩdаnЗQ(аjЕp}{ŽЋ›Гi Ллh†С•c$9tь)8—ЫЁбhРВ,Е–JЅЙ}аFуqJŠCш†кgГYѕ:–Ыeдj5иЖ=ŸрЭщЈЭ$С1Ÿ^P ‘TЋUхSѓŒ… Ÿk;[Їяrœ"ђГЂ]ђ•TIy_Щ,kЉT‘RгB}ИюУсpЊѕСdљќšђ В‘ ёЌ‰‡ZЇХЕ‘Dц8:Ž„ƒУУ#’Ш(Ž(XXыЗ—#ПXДiЧў­ЧЧіч)H"ілОƒ—йезЉ™OIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/continue_16.png0000644000175000017500000000137711733011756022763 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЁIDATxкTS=oAлнГYВGVфXˆ*а) - A‘‚Š_$SPбX Ђ&QЂXТ%MD“"iш(R’€EAйБ}gп}ŸМйГмiДыѕЮ›їоЬI’аБЛЛћ\ё4ŠЂћRЪ;Оя'ƒСр‡ыКч8;k6›_o$Ьvvvю–JЅЗйlv3ƒ‡Яу8&?h2™аh4ЂnЗыѕЏЏ?тќ еj§њ АЗЗwЏRЉ|Z\\м0M“ІS1ЁЩaRF”р уˆЎ~_Qчђђиqœз "Ѕ\.ПCѕ\.G†aш€Œ{)t˜ЪЄjЕJ•ЕЕMќ_ч\ЙВВђЩoђљМŒQ:ЁІ'1+d $5pЁP зqjGGGšŸAВЩtƒ д”9™Ѕќj&Ь@L%Љс>•WW§HЁb/ћў”иЯ,въЉЙ,A*€`?—%„ЄЅхeBё‡ UЎЮ IŒэ˜-c$%IКOПТ іЋX,Ў+Д(aъQktє…Шќ@ЧЬHT„VЅЅЁp"њ§~лѓ\M=|Вэ1,›\ЯЃˆ}@ŸTЦд`эйL+ЗzЪ~Ееx<>ZV­€JžыjкЌU)I kZY‘‰d53QЂЅ~Р€пFѕДгщx`B!Z8Ÿ6Š/›3зеlMї&yŽ3Хн3БППџХ[ЖeЭZ–КЌю+L&3Ш№jІ2†(fлісііі‰žD8}а Nzн^к.Pфжq%І+MЉ0Г^ЗKН^яЄИё1mmmнЦ МТї№ђжвђBБX <&ŽЕЧш Я‰ыxSЫ~FђћFЃбО0ъѕњTz АЈКЪт'†цЎŸ"ё˜взЯзБbŸži0IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/domainname_25.png0000644000175000017500000000173111733011756023241 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<{IDATxкМV;O\WўЮ}юѓ‚ћЄ qA’q [)vcv™ФR,ˆг8”Q(м™ТђЃAјЁ8Iќј. pН{я>юc23w—нрGv%'#}:їоѓ™3ѓЭ"Т;Ьcœb”%†Яh0"FШMќ‹9333ЏБX–…RЉ„BЁзuaŒбџЩкF–eЈзыЈеjˆЂHџ>iгггFIR~јУЭ›шеNžH‘1ъ ‡Цpm`ˆуПѕу­N$YšЊsсч№-ќUMрЛVЯЄIBЈ4T„ћ!Џы?}ŒДЕЏ’$iЂЮ@бСЅш;шЧŒC †…ƒ(VЏuР4IКHтœёU`АdїEpe8 cDM&‚A-ЮрИFSš$н‘ФБ:ƒeЖezкБDеŽЌНіm_]МЄŒWmв•_šџIu9AЅЊdЕдЦ6gыьНo^HЏrK ФЭ7рч+з DIXЄбф&Џq/нљмЦљ/Юсїпžч*\oжu“ћ_ZЏЋ-хЋЈlТ=ЫЊz*+Љ:aсёЇЖ9)œIЗ gјфгЯTГEŒlЬ– piIќ€XY)–™%њDаЪдг˜.ŸєuЂЋщžŒŸdњЉp№)Љр‚ЮОКO2œ‚ 8~ogg+++јўёšсw ТэЛy*e•™ђQЁ“™шњЃѓК.Lэіэ›››илл;юєЃЃ#8мSі6wЬлfќтт"…aˆ­­-looЃбh(ŒYПОяыx><<Тќќ]г7Щьь,U*bВБрX˜Фуйя3‰\№юю.>x`z&%9aЕZе ђЂ3ЯЉЋђ:п‹E”Ыeб<гWКоЇYјьoЭя&Т+cќIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ipv6-neg_25.png0000644000175000017500000000310311733011756024215 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<хIDATxкŒU PTUўюоЛьВАЌˆ( ˜Љ†!5ЦБœmK3MMC‘ ehвqm˜СШQ,uLЭВ)ŸˆљЌЄф%"0AоЙАьВя=§ї.k"Іќ3џо{Ю=чџўџћўs–SЬ^уфžѓ@ЦЌњ\З ИjЎВ…№Š!‰р '>98‡єc5t X$+“Щњ•v<Я`эВЅЩœ иџ]tщкЋЪљђаѕkœsяt™јЄёэю[Јь*InЫѓШˆеmТ L&%зˆыЫ\ЬV&SІ\ЏЬ$яRЗXLGUw ЊѕЅрvŒ\ЌKn=1єГС€b`W–.z$tС &8lxѓ•+§‚ˆдyыУJ)игЪg'cECmЛ“хhщЁ3ЧH\CэЏvcEО Ы nП\.вЁЁ}ieщщ OЋшi%ЏnЦІ3V8&„Ј0\# YЩНЈ’N=Ь~ž˜r#ЛФПEUКc‡yъж­љУЃЃ5r•*ъСхЫџ 0-- э р<Ѓщlˆ„šxiMЮ5э@grнFћф­Ш—*qUфIЃ/ŽНwъд€ 0эиXѓPвDŽ@ЯЪЩhћу>Tэ=б@ЭсдЦ`aPpv‘О Љ’>ёewUvіŠŠ={žZEWM 4ў>˜њz~(Fi ц‰ЁїДPї˜zјёJЪлгCЗEЙ ƒBnc/$ќ™”єL=ЯŸЧ˜б>X№vЪ[Ѕ–Ѕc ((BX'С{ˆ66eНQь Ž1F2!Ѓ233сzrђ€ С11Июм€љP­мˆќ&ч•яыХ`%РeJа~Їн7к‡П7k4ъшГьђнЛi3РХyВГЯњоaeь–ССўВ8XaЗƒEю5Гˆ]†C5$ŽЫљEjѕйТдд™NOOЧФЄЄ}єЇž:=аcˆzRгХ‹§жˆcЇ юSfРL7УЂ/З‚ЧC#ј†VсфьpшЅ[Xпиј,€фnnFв,Цt†‘P’вo­ИПО‘sмъ€ьZГЋlр­•mјяSЄЋ 5ѕIŠВE­ФіvЙ86ZйЁЧЉїНЩzRђXви –1z+ нХrцf!г% JX›KЖmKPњњ"bуЦG‘1J)TU…ОяœsLЇSќЭчsˆБ€O_" cnџпZ@‹]kБЎ ЗTгУ›еЗw•шК.ф™DтˆО?ш)јаYh:VкЂв@ы8вŒJMyˆё@ТЕФ‰„$ŸкјЬДЅж§>Pі–ЃБi!q•GxE €b…”qиШ$†ˆКос ”щБж Ъ2!P& WЧѕ…@ еФ^ДZЛ™ЦD‰hгGQёыžcЧ\L рuFС%ktЌmЋ!WПТІb4DyC 6вF,u˜ЋЫŒсК№С )Ѓw#РbSЉАQVbgќJœnPe•:!ъorр2eH)˜{п`oЭОЈ€яф‹uPяїЛКЦЭЭ{BЕAiж?>=#Ij^š&•ЪєaбuMг€б›ћ–žъ'TИX,œзФшГй,;UЖЧё­cЯ юю>ЛЇ{™Ннпсg јрііЃ{ кЩl=<ќјkвže№ћ#РYсьтЮ‘”IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/folder_25.png0000644000175000017500000000151311733011756022402 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<эIDATxкьV;lA=Ÿэи"R„„€‚"%-B‚ )=Љ‰*eJDAЯGЂFHд h,QBœиФ$Šrінњv˜йНѕ­?‘qіЎgvчцэМ™ЙГ@D8ьKќ; Ћ7=+_Іёњ7і‹4žzџШKї?чЯя 2ŒЊѕќцУ[ѓ т"З 2MByќЦвъ№…3;€-€„A!,›"S=‘Sи„7Œ”Xа'Ѕ~џ§‡Бк“хг$Ю0Ž\КViМy9ѕЗs1zeqЃўъщ4ƒм#§СЬЪ‹@Ј†s.sЙК["Vџе:x#Аvћz‘ЄG ВqќюЪИ4P›цF 0ф5Ђ’ОfЧЈ€BpЙв/SЙSє6—яьјUјљ]ХŸ?yL)Љ­Е“ЎЪNvdTуL#`r=€Ж‹ *хЊeV{Л–Uс`ЛeL„ ‚Fз"ІD Ћ[й)ЖYпжЗH-0Ш~МWЯa3 Ѕcp+ШPсF%RьЮžxMq<~тF]ћчi/nьNb‹ЈŠZtИX;Сda’=(Ь*йЭ’ИЭ Л*јqBеЗJтSж_MЉf9wWв9Yѕ<БфWћчi[Щv%ЈнAзЩњjДUТkk/?%ђ{ЮFR“еђКШ_ејN•р€Žшяn[šs Ф‘I`ПьŸAОгF‘ (<РАй|кnї@OёЁcяIš'80Ьўd“Ы BJКlгЃ‹rЂт>Jи…2/‡NѕŠЎ}лщPTОъми?ƒ”YС(UЋ– ››іЅГУ?—(B‡&§ul 7jПRђЇЮZ2ƒЌёЪѕŠ&…{ЦIЇKі<ЙАч82: ”’rьŸAVidќйЊЎˆ’6DFЁyўhN г|щqСэЮ$ТЄqљ~ъ7–_=Я3ьпОДѓ,Фџ+Й~ 0H‘=DьЌрIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-neg_25.png0000644000175000017500000000335511733011756022777 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкŒV]ŒW=3їЮиуп]яЏэlBвІовЈ,}!i‘}hAdлР ˆ$тЁк$% x ЈDaoМ„P‘D‰Ј ‰@ЭUўPкЄЉlWХIvльnМоэЕНіЬx~љюѕfU Uщz|Чзч|пwЮwя№0 ёQзјѓяlЇŸПшљсN?‰hЪHЬрщхŠSЏЌ:s'˜v<\ ‚№еХПюœџ0Œў]з |ЩзПwc;gЪ7е„ўe%ТЗЈ§1(Н”„†@чh7]дWlдч[ЈЭжaж;Х й9­ЊЪяˆlёcI&~ќюўh6ёУD‚=ЌЄСвДФіBt+leлдЁдЌаuQ„m<ЊЋ)Ÿл.•„MЇХ"aбЛwяb…„А*#пбoйсahМ (ШФwI IђƒTjg2 I+.wuЙъ4šMЖ  бšbŸ ЋBM(ЪЄ8Ѓ ЈahЕл8qќ8*еŠзєю„4Џ6Щt"Ж#Ёд•šћўъ='D]aXZЖdЉцччЅ]™"В`Dдљщф$ ЃЃјљфЯ№л—_†mZ2}=ГйE2J$"3A—dN5MКFЛ)i‰†AqЮСт и–%3eeхЁˆcё8žyіќђЅ_!J™}ы№сriLУєM* ЎSRTщiE6ФЧ\Йr…JЂK‘5M—„RpКзk5фђ9вуі‚_Њ`)Bѓ(iЛИпВŸ“лЪqЊёљѓч144$Aф§гЇOумЙsrЮз јКƒtЁ .L’Эчe)Uš_ЙNeOѕ#7ХPдУ@ZН=бЎJ’ОО>ьоНЇNТииŽ=ŠН{їnъD SКЎKЖ^џЎ…^~Љ…Ппб0˜K!’ C ^yуŸ~OzlbbBvД$yŠютХ‹8pр€$ЅYˆШЅгЄuЙЬ`–JtѕЭ&ЎЯqЄгЄ‚аЄГЧ ІщыIёъ.ќDЬЬЬ`||›7oFЕZХЁC‡P,Л$й јCŒЮ’tRCЅЎтЗ<ќљЊ‰?^mс}3xš2ЃЭвsр­™%пВ~tщфЃзжЗ;„™LGŽСО}ћP*•Ых055%‰DCfПі/6ГCg …ъЏ=1фВ єѕF@/`Ж ЯДJvЫzqъз;Nо7ŽдфиБc’рђхЫиГgЮœ9#5:{іЌ\Ф†zЁ?‡ўШ6h;пО<ŸEЌП‡lL„ЎƒpЕFGГљЖгЖОћAiœnwWpсТ›Я‹ВYcNSЦшH%ѕЌih–Džэ„•r5иSЎ[ eУpСzДр?ќшM‹ЋћћНкFРŸ~ї•гЛЛ’+gLKœмоfЭM˜:щ6ІЩітЃz№VyПaH„йnHЛ‡нЭ§CюуЛvЛw58улўЌovњМЙ3г_Ш7™iЫ„БVвЄ(……ЃfЄ% "C'ђŠ`pшршxV}ђ+~HžQЉтWЗюДйМНіѓ'nYzпAы€“Юyy^яЬдšН™ЏЖЗXљTB'+— +J[фУ№ €Нm {њњѓЦkјW…*.%‡ќВKЎбhб+МБЅvћллkџДўŽe›*œyо++—жДцаYщЃВ)в-IВZ“d4Сx`ћ'Ч‡ё ё(Ж[ўгЦРіrHt„ь„‚Cnб‘диКУ~юеЗ*?~ќц%wјѓПйxбБ‹sЋ{:“гВy“’эВр†=?и`ь[рсШy.{syў%Ї‡iL@AД7ј?|0(ифжШAŠ ИЯНZўЧ~Бшgд+/|эЫЪЏюlMфš:R”Ф2ГЧUV ьи <"@кw"2ŒˆL,?аHJYщй{ЇH€Яc5ВЧN‰тГJ?Кїпўј€8€#тВц+К;a|Wš’2’њ^Ц3фнС 9иИ]№(‘№Ј)сЂ„4ЃН&–iH‘{ВxПFE;A•ВNFжЄ0iСM ухМŒ$ЩHЉбHС+>ѓRёяп SъЮљЯ}ІљкCІЅІхЇУјщY2™э' иЎ‘ињˆzвЈQwsA^Џ—П~кДiuwїа‚ і*oьЬвp1Až†дШЄIяl’ ŒШb6 †сиQ›‡нЕ/Пџф­Kў{тѕЉ2ў„ПzБoЩaЙ5œѓ{DžŸјŠЋдd–ЉЗs7ѕД„‚`л‹EDМLЎыaЙф8Ў<яэЃcцэЁЋD•С_Ђ1ДD;Ђb-ЂŠЏ“ ЧDЩЕфЬю#њ2k–œѕ|я'в >7sйЁ3“G сСuиKфKЬІLвЁŽŽЂяЧ‡rŒгAђУѓЫ/џ;ЪхrДrхJrGЮщ ciК.Я?ЄD f•iэkYкВЮ&ЋЋ‰Ќюb@‡‘Hт\јЎыш9‡Є.Т)ЮŸRp“Г 7ћйД!lo6Y’—ѕŸOWЉЃЉ€F&hDл|ђЅш›•>ЏНХЬIЧвIх4ћ ь/"ђ.ЕfЫq6Ш<п$ј0RŒуˆђљ<-\Иˆ–/?ž|%e‘Фш(BыŒu=’—9ЈhДхЭ~Ђ9г˜1№{h"ЭіД‚ЯХYœœvю†‡ЂНХ#MŽn*ЫyялиŽІ11оѕTNЛqфКˆћp;DЅC“%—СqGёr…ИћЋсРРžЖ %мRм9Љр‘іs’?9aidхвхБAмЙzЛЋТШЖцЂŠ$ž;ˆœчЈˆ†ЁŠ8LWЉ!љюЧбїКвуHзк‘!и~бtхъсŽsœѕY{>Ђ]/э" ЉBŠЄamЦ1)WЉ‚tjЧђЕЉIu@g›ЕЂГ=1з@DДŒЅњyRm­‡^=ЃйbМЫ f0Б…@oœс+Pі”'ŽРЊўЃ„S `(Р!&ТG^;IWmжЂоˆž~ГBхZH•8пгŽEЉ].хвЦ"LЁЧO*tЖZŸ—y>ƒ‰.aJO[ЩоUЁъ˜O]Й1ауZю*јћ~ љm#ТD†ЁЮЕŸQ@qсdУк ёКёїи`1ž_ƒC vˆaтЈгїОbPuOТmCbМє1mUQ žI…Ђ2жŽ1'і %'kœ34ъТу%wй2ЦГL<ЖарnДСфРћMoAѓZ_ovшpUдѕи]ъ5DйЊ ДКёЪ`ŽКœC ЏŒ7G=vџЌ7œbШ>tž„– vНPд˜єШЙQТвћЬ§irXЩљТё­ћ­фR‰вЃ‰J•Nzeч.ЪY§4ЛЋЊrлЈ#РЯ}гT9УŸ–iЦЮRŸQiРЂAё€ ЧaEŸdі[ЪЌH‘bя3>ВъJЮЉЧЗ~<%‡СЙ R„‡фu+Vr Ц$*F>;‹ ЅNкд?@3лЉЃ9’(Вq’Ьp2hЦЦ›lМЉ`ЯFГӘ`џ§—7‰qѓ HітеЋщўЕeВС=šiЁюумр'MqKыGrOuЫ—ц?PЩaвntЛћRrъ#+ьб‚К '˜GЅlv.эмгLeЛŸцbЧ 8тІ"=#~ЮЦ3йщuьс€ЇžzRžŽŽЪZ}щeдš7hбб`ИŸб€CцCРѓPp=­^})нџ}є­o~‹yфaЩwMxР”ˆзPя ††2QЁR RˆК F‚–dgб&уŠ+ЎиЫИЕ/ВшАь™Э­Ѕ9ђХœZ]Щ(SЦАЉЇu'Ќ5”6:Ф‘dV­К€ЖoпN}}}ˆTЗДЛJэ ЅяччЭpFwїDДsSТˆœJЁ]f…X—’Ъх2 `ШˆO zM:ъЈЅШѓгiУ†—щ†n mлЖвђхЫ…#8т ЅЯџѓї6кЈгкed.6QЉTbnцѕ'њЇEЩй]LбЦЭjšз7~yѓ-ДfЭeєњoаіmлU$ЬЎњFРц~D?“ЂŒЅSШ№”ъЛЬЕаW-Kл{>˜•œeѕ8р3GrљSž 2,•Šдее)авхF\pпSŽШщЮfс—b:‹ЊЮћђб›–TѕO“’34bаk ФX†xo_/]Кf Эž=W^уя“vЙПiz =)‹sŸ:Pп&п…GЩЂ{іR„>JОыеЗZzИЎš(MБП@?wЬ `КEЩЖ|\ЙА/ќdлђ^pаƒќbёƒ |š”œmƒšДнШ_1†Є TФ9љ_›^{лЇФЬidъѕЋ?hзйxћFьnлKў4)9УР{‹OЫ`јŠф jЃК‘пј6&Эж&DИё„ Z4;^tчнзљлН№.%GЎЬВёChFЦ|šsШˆяЙ*њlЈЪѕ@ wРьF‚Яю•щк&(9F пёЖў{]†XVrќлкч!вftЪЦYЩq<ь пѓЦVЯC')г FП}МЇ„ 7 ‘ŸNќѕf|‘0ф}—+ИЌ:…ыjvxЭ{Ў хГЦBN–аR2VД}ГЛс*Цw}!­ ^в ’ГcШNЙхžНН@iБrJЖцХp­>“qоƒTƒЊƒН†лkЕ№Dџѕї8 ›1fѓ'BЬюьщ—™ќџšOЪœ‚7ч5Ћ75Л*‘?JЮ‹ЏtіхЃд†ХШd(неLЬ_†Nу•‹Uт9ХFфЃбJ-ИіЮkИ§}яЁД rЃњ |­ОR&Ћ:;v€DочШWбр Џ№š‚Мљ‰*9HЭъЬSае†sqkЁ O„ёA H-#ђиЃу…ЃхJpеЏЏ9тЊ}о&g™Z“ЯэтAРœNн-cДnн:*#Jh!‹ХpТ‰‚НaМЪE1ў“QrШьhХwЉ|‘’Ы)Т4P№8PЎm‡ёљЋ>№>AxдRаz†яFqЋъгЦE]щяяGяНŽ=іИИьhq]'БqL’cшЊє†>Œз#‘МнŠ ТГIчслU„ї›=ђіНQВj.ІЅ$‹—ZœŒЋT#ЩёЅK—QЁP@ЧЕ‡–.9*&8яК._'Зњѓ)Ur№™ѕGtЂZGoEЎь~іМ№зиіЕя&М}: XіKљЌ™ Н0гEсqБ™r9ЂлšЈЗЗWR Zй˜Гe•ЇЮђš”%#&КЉTrрнн6žђ(љіZЈxРїУлюџљЂЛ?ж­В…R08Н#ъPіXАРУЩш щўИЊ^{МДiq~+8›qўЋИ`еЊЉSrРN&ЂЮЅ{к€1њ‰JнћјЭKўИ2П4‹Ѓя-6|La§І%ОЄ•LвжЁЄР™ллqе%nb4Uо’уацHЏќкзщ–[oЅщгЛiѕъKшЪўFF†cшŠфsЊtжчѓoF}ЗšввЇQ§’XјH6Ђm@СЪ•№tьwљУ7.^Е?Ц70Z ^F—t–[‚WушѓЊ†m~'ЂучzRж3'^“г&діёЮЎN~ѓц)%чЎЛюЂkЏ§­_Пž.ЙфњтЯœ`А&БрY NŽЂфД) MРЄЇGžш’ШёзўЧв+'уzІ `pиљŸR5 Ъš†ЂЋЂfЕ{ZЩЦљЛuу“œkpѕNЎохХЯ™х.у‹™tі9gгwоE3gB^ИŠ.Ој"”дТˆ;G|Ž•œжŽ4eЇЗP‘O%0ф’фѓuvЦњЩК +и9ш>=ИлйT.TоS#ЦзМˆŠNDЃfš6О“iРоˆЩЏэFJФ@кZниЋб1ucв•œIuРžgŽЗw Й•‚т@Ѕ(AЂˆ2фЮяЁj”ЄћŸы˜@~Ц„ЮЯуŒz ѕцЧœ0Фѓћ%gХiЇ5”5FтДћžWr8ї : h|ЯCЂфLЊјб?шўfЌш•‹C5*іWЈ‚Tt4ЄКЌЎVziKn qяЮћT—WЏJmR•œIwР›§ф;Ю=5i№N‘ c.UœPFccс ВКэБކЁFмў*IZkфr#-8ђвЧыОЁqЌ+9вз+%Чx—’ЃTмX@sі>JЮЄ;€[ћэKOuЈBЃoЂWc!пИw=ћZ’ю}&'FjqћkФ— BЏ;FЇЧ”Ю9чtы-7ЧВ•.ѕ^з'(9шјxњг&(9Q{›Œ$2гѓ{їЁфL‰ўј№БlыwnAMco “ЛЃи˜ цмКo]Šn~ 'mАV‡?ч8щ Бє%фЦBА>>7( +l(Gu%ч/‚х[В"cБ’#jыћPrІьІњ‡мС.q‹ў)ю›Cd&0цRв‰щ‡Я }ў zў…7iгuА0 oœЩk4ђ_и+™Zuv$yЎ gL†’3eиљфq[{>ЗюЇиLO0XZ@ 8aAЗLdJ'ˆШ[вGЃoюЂ‡^Ѓg_iй|ЂѓЮRšžКWх8_saжHф1S^Ÿ %gВћМ]Оcљкoт№#ЌncfY‡ve“J*fэЅoVЖьЂДЋюЫŸ?ЧЂ%ѓtОћŠVЎH6.Zўъ›тJšТЧ‡ўСDŒ„еXG№ЄhєДaЕ*u†ѓYFUХІІ\тŽдenPЖ(0в05$yn€сl<78<ш$и„кo<%чs@ьОНќОu@˜Лl јš]y!@щт46DЉЗF|­_гтзљgФwfE”Т<нёEнA“ГJЮ'ъ€и Гqј6ж_cѕˆфеœ!ƒ/BД`VШІ•сме‘*c†(Уhft%j&иpŽzр’х:впГ’cь‡’ѓ‰;`‚#NЦсыX_…mБўMF.-ŒžNŠ|­!зЭЃi€*`мŒ Zкdш‰ŒHА&РJ}l%ч€9`‚#N@>ŸТЗљ}Œt{ёm0šЉЫлuѕч-|-/a†fвуoР;Ÿ№їSЩ9р˜рˆЂx\*Љmк‘VBŸЧЬЩЕЃ fаOTaџ О Оyй@ЌЯ5щ˜ЬЉnџ'РˆšёYП|IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-ref_25.png0000644000175000017500000000321211733011756022772 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<,IDATxк”V[lUўfцЬюЮvvЗлvk/TДJ–›7‹ Сд(}! *ЄЂ№ & &ОљDЌ\BтƒŠј€BŒT”[Й$XЁ–"RBKЫЖнню}fgfgќЯiЛсѕ$џюЬ™™яћ/пџЯHžчс^kMGпКќœSё–V\o_•к‚‹Œ%­Lrв,[nЏхрЄыzнз]:t7Œ†e'!нф•w/ЮaŠєІЌћ^’ќlЖм„е щ*\C1g#3n"3T@њJЅLЙпЭ•П–eщ+"ЛўЏ$o|єз†@ГўЎ+ѓдЖ”ˆ.нb:ЪЊFбСІН‚ $‡‹HœKР*UNVFГŸ$Ž/;|3ц-$[>ЙМ-2;єam[(цo"яiЯШк(N(Ž—`$M…Хd8мp^ДžцCжp‘И˜Fz 5XЙ‘ьФВ§wСЦ†і№gБxmC B.P-BOІ0+ц БNFm˜A 0”J6Ц'-\Жqn ‚ЫFШ-e7Ў0о›ДGsЩžх]U’з>Мox(ђ}ыœp<дЄСГ=˜зsˆsxАUAЈ†j1эЬŒS’$~‘Ю”qъМяњƒ`mu0=УІ19˜>aхзбˆЬoеЪлuЕ,lдР7Ш ,Њ/рБЙA„tŸ@”Ш …ž]НšЂtQЉps 1<Г"„—уYєП“.дІZЈЊВB–БуГѕя Ьmš|бп‚LтzЯrПЋоOWјЩMбL‘Ыd/ЌjDІ0Ї“[ЃšЃ`YcЉы~} ги,’+ЬМP&š™ ˜wgŠ`*CSРфцŒId yјќЪZ,R“№ВфrRQцЋLzšЃ=)EBІЅ”‰Йu.tЊ'рРœ„/г4166—вtўќD\!]G^ƒp(Œh8Œgž сєАf„›+-enХ›ч‘ вОMЭ’АЫ І‰‰’HON rлВЁ0ЦXЖ ЏP„U.#“ЫТs$T2>ШБ:HAЋєqІ0ЉХг R”•6IIŠц`–eaxxXDРНfŠ"DРTN@І0*0ƒЂЊєЏŠНјƒ М"u(5+|>ž„v№Щс нlк”j4нЬ#сС8(<ї щŽЎ575AeS€œŒ AЂ Е‘Rmх)"jХФd‘ЧRV6—shlй2уs‚V’šЇI"p…"р šІЁP,bЯюнHІ’\ѕM™ ЄѓTŽ„@џМШЎi (ЉЊгџА~юъiИйіэл‡|>Ыžh*ђ8XSƒЕ/ЎХŽЮЯ ШокВЅš.UQб;`AІ‚K\”%’ВŒ^љn†7оБЯыхЃb2ЊC4Хы›6ЁsчЂј\—‡+8лGтЁЁ aЩB(ШЮоA244„T*…žžЌ[Зю–klZA>^"тЄЭ­­T3™ЮЛzL”У hi рО€ƒXDОЋSА€ОО>lнКUаcЧŽaётХиО}ћT$…Ш=›–0?&Q(”Іo*рь5-ašКTїR ІъюџхЋ'Ў ’У‡cѓцЭЂ/n_М6.\ЈІK(MH—‰ЎPŠŽœЩЁg!мЁH№ˆРpм^:м;=‰р-YВD4нŒЗэээ"Ђx<ŽƒBЇбСчеo'ўDKЃЩЌŒП ќќ% §ƒЌšшѕ:еm хЩТhЙPкіуžGОЋ’ДЕЕ‰!ШС8 Rзйй‰ююn‘’™‰†о56$ЪПЌљЁебвЌЃ>ъ}d@1IВ%cд,кЙpoЕ–7ПˆVгЛbўќљœЫx† ЊЎэpЉ“AYІg‚šD2–„ї|~Жћ‡W6?%‚§З†џФb1бн<"О:::ю рK.гь‘hЖбwЋX№Л$ŠЬRМ+Ž[сЉйshзТСлŸћ_џЊSє•RO –вƒЪЕАЮњ5П|FQЄŸКП|єЪНžћG€˜і•h7ў‚IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/check.png0000644000175000017500000000033611733011756021700 0ustar sylvestresylvestre‰PNG  IHDRH-бbKGDџџџ НЇ“ pHYs  вн~ќtIMEв *rtЄЉkIDATxœ­‘QР CЫYя’юGЂ|HіФM1BЇвД5’„ЄcœPŒШЈ“œЙѕ’`fпДО%жЦ{‘ъ%ЕжŽƒЫЦYt йп?Ўњ‰$S›д’9™б0ЯrЇ „[OЉЗ”]}Ѕžzе‰Ј UIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/floppy.png0000644000175000017500000000046111733011756022133 0ustar sylvestresylvestre‰PNG  IHDR є–вbKGDџџџ НЇ“ pHYs  @ОсAtIMEв++h*R4ОIDATxœ‘Ы ‚P†ПSA.rYЋ …Dœзёс|wО/рЮh!cfгЂ,SЛљУРaц|s5€ђŸЖЃ?€еRUі"Ј*ЊЪA9Hге—fюэщ;eYІzЃjл˜zІVЖŽŒ1ѕsз™Љ( ђ<џФЯ'=™Оi9d{22C йЄэ‰у˜0 Бжb­Хѓ<|пo~ЙєVЊЊ зuqi‡ЯJQ‘$ AЫВгFИXѓМі/ЖИ`ьkm`• лIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tag-ref_25.png0000644000175000017500000000317311733011756024116 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкœUiLTWўоМ7Ы›e6Р)ШтŠВд­­—tБ6VkЕ1D ЖдЅЉЦкXыSлSг%iZЗhЌ+Ц–J)Ж+jЂAA‹ ˆƒ0ТАЬРlяЭы™AmpЗ79Щ›sя=пљюљЮІzƒ'ЌHВAdЃЩf‘щЩ6‘•н=0rПџБИGК№†LЯjУ7Ј“ВѓTƒRЭђ№XЙЧzнюИXОW…’ш{Чяr,ѓ{z[Ÿ”%їЈ Џ[ѓжЦb…!>{3•-Л>ZN эМ8O•ІI›XMўSžцКЏщјcЉШц$IњŒщЋљјсАl]лўЯбЙ!.›ітсGш†х2 Ї˜DЧCўNgXg|yЅОэ№ч3‡CєњаVВ aц-ѕД6Ьж$ч S—Ш5ЧGаёdВГЯФ„2j˜ZјІЯо‚žs?C›0Ё)f„'*бwn'DggŒЧVЏpдT€7ŽЅ+уžФDv@ˆ&uТaЙ‹8лю5ˆ?:P0J5јиDЫ„>м YЧп”@)Дiдt-ї™@X^ϘžaЄ§эрУh'BІRSб5A †Ољ8кkЎAŸ‘Wу];џд5! !9ГзЊтваВ}цфAІT’„ўN’Ÿp^Ћ'€рТЁcзЊНG^ЏS| gЗПuѕ‰KѓRXЋZ|GU’s„dЌ&є“ШWW…Зљ†œрB ИдщwЛqћl Ьk~AыЏпјі'lјыЌgШV% ^-—^ЛхЄі>v}ЏzSЮ ‚ЯщљяЙђ"f|№ЖаeCї™CшOУжC—р8œОк“—эС'ыМx †МwсыjEEп0yЅaў–PМVш” ТДЪйUœўѓКxTЇђ‡E‰Ё§ :ѕs™ыBŸŸ­А§ДІљ pќМ™ЃУвюСБЊ›HLŒ†Чо‰оІ&/FлЉУ›Zˆ)Iа†ё€@Œ;]BєƒWБbhsДёdНg"У ЭЎ•‰јв{ЛоЦRDMŸ —ЯЩ/сЧ}U˜<.if#ўљx5тŠОЇюЗЂYŽ–ФWPз4uѕ?h­hА‘К“Р:ћ€^p>B)Ь 0Щ Y>1‚‰ЫLlЖ€UЋёRюHЄ5УYпMњ‹рFыkPš…3MЖwуЋ"J.И(Йўbћ 5R ˜B˜ІhрcpЇМOГn§P dЮGЙƒїJDєКDшnЄХЈТЁЅAг“v'Ѕ}б_`9]ЋI=nФКШhТјp •Є›AH,…‚‹МзёЕЕЕ(..F]]нН •••ШЪЪТњѕыћ™PA;нРи’%Ѕзм мьTХ †Цб+dиh‡Ыэѓ{Ч'`KЄЌЌ №zНЈЎььl455) ˜Эц Ѓ””=zZ­ У`uЙ„,bЊ• !)И~FЅ$ 5ф’>ˆaлСхќтSиjЕ‚•––ЂААЩЩЩ(//њюЎƒ5ў3Е­$2e`LP`'З:HЎ$[БКq;РL[7fэ>&zРО+бiгІ!==Asм}œ‚akЗЌВЫ‰H•T›Ыdš LJWYO]ю• €ѕQ2ьЃб›Э“Щt=@+Ы$ГwїЂіl=3озхСъ`oXhДЌмscISДJІ.еШЎоВ@jО{я™:ўŠрgŠЖ31Tь1V2 <ђu*и–/- ьncŒЄЌюKЄ њW€яђwй,&;IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/firewall-neg_25.png0000644000175000017500000000236511733011756023511 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<—IDATxкМVЫO\Uџћš™Т№œ DЋ5ЕЈacв7šFиvИфУЂ W’Œ увА`%Б‘?41,”hKЌ4&е –€У@yѓОїчмY˜­іNчЮНч|ПЧї}gJ)ќп—…Чp=чјцЃФE_с5$”РвjKOЧP’rЊВЪёЌяЕЩ.) K?+’…ЧчzзJј№'gфЙp—-№з\лˆфіљnqг!—М4–o”Q~ЛћC%CГ(IrМYчс“Ћ pЏ$€@ткk>ƒќšjЗQљо!ќœпУKANѓўgvU9яQ…ZЫC•$„MvЭ Aщ/ж(qфУлТ=(Ћg—З‘S В2л•Kуд_yЈмџїЌh№юШ<ЯEєIWЖофѓ†тVрофВƒтПJ<—гьЯyЁС"Ь‘&gР6ѓawP†ИxеRИ(љО|f™Л Tиг>И"œ5И•Wи) lсt%psПŒb*‹§@`Ыwљ§е‘јоŽaУ)"Я@ў1ˆxџ"PБюHЉЎ?дm!%еЧ9‰і*ЮDЬД‘ЬHVГ ­qF•Л%ј™ВкуHб€Л uн(iˆYЦ"ЫицCђЯ”YєqFN1_ieжsТоа4PK•о/рXАЂ№žH•фЛЫщМњЬ9n{чиЁГИ)Ы&ie€j7 zš@†йX9RЈgnх КЊt3ђc1`cд‚g чЩ*ќb@Жr шМG8тLHФ лкЎ0Ж…2yв]ю‘ˆююMЊ{Н)TІБП €<_оЭh8ЈB ТФ7U—ЊоЈ> -[„-А’‘HГЌЙ5ž0хмбъ•љx$ЇIT9a5КtAн9re)7rђЊЉцfЛbW”›~> $аcmгƒ€иэи/)lp^кcpВўzSбaд4zŠD€'tm“1х |+*gнCЏпАŒMЃNaž№J­0ЙкakВŠАGzІѓК`9J*П{ЫїŒ’‰‰ 477ЃПП›››ˆЧуG4Eoo/- ћЦЂ:WTЩ(D’ЖЕWщfSЦ Цјт>•(гШтфїЄООннн˜œœDgg'ЦЦЦазз‡d2i”ЬЇхк\ZоЄ5пэ˜Ъы9рUh;eх˜Д)тАэ’T–х)пj”  P(˜РЄЅЅГГГ4 Tђ2mЈн*рТ pЙ{f&­.Qеy&НЕжCMТ…зDe žQ‘й-ШhбWмž9ЩIGGцччбжж†єєє`qqб€|№<ФпхJŸFммШ9Щљ)цeкжЮœ\’7>ОЇ>=БЋЎЎЃЃЃ •JћFFFŒЂ‡ўv ”4Х ?Pн sѕ%С>g.fјњЋгkеєєДвзммœъъъRSSSцћТТ‚ O…G&'ллл˜™™Саажзз1<< зuџГ$Юд'd#фO018рmHаm;JЕч)hddфˆ+’Y3й@ЮЌјv@Щ# ёxRЉ,..Т№№pХ5CЫƒI,фL459—uЭšubhБx іжOВЁк –——arrVVVЪI ЏЏТсАЌDЫIŠ"”I ЂіОpХ[KеlЦд@З ’ ѓѓѓ0:: …BсH‹јо,--ЩЄzО’Eр<~АќиЉU UУ!IжDt?$ цѕzЁЋЋKT …`nnъыыХ)Ю>дЪdtNЇuЪ­ƒK•`AyК{aѓaИ—œЇHGG”J%‘lvvVДnzzЂб(ЈЊjН[ИоЂЧz1Š…ДЗЗc Р‰‰ ф#‰`2™DїLG8‰ˆЅЕЖЖ H^ууу џо‰уœxZ; ШO?L"‡Ј"IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/library_25.png0000644000175000017500000000255611733011756022603 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкДVklTEž™{чЮ}ь–KЁb[ћ€–BБА‰€в%жH“–Ц„G$(ёQ+&šˆŠŠФ„‰”D*СЄЦЈI-P6RлX Ќ­ЅЅ/KпЛ{яо{Ч3ЛнЄђижNrrgwЮœя~ч|sцbЮ9њПОD{E‰чŸ VVrfScIьOŸЯ‡уm’яЕЉpQBјMпpЉmДНђƒЖ!Ÿ™Ÿ˜›‘5ъяqл‰_xEУ(1YCПž.uƒW6—?Ж јvПяЮќVѕIЛ;fЂДдЂB#}9ыpŸ?цяўW~ю ")Щ*EШJDЊfїНpАaљ—?ЄдзМНz(J9R{уќЁг}ѓэА›tџк(EЁнDw!4я§О- ИVн’ТЈhYЧlќкГ,гd Žd[Т\Ж0ЬЦX22g ‘%.l‰ЮЙБ‘e&ЦNџ†%Ф)K•mJќ  2YЉА†BЁЅЗїcчН…§X“гїі}Я=Я}ЮsЮЙ%†aРџ§!гAф2сQў™h…h›.Зlпєx<фQ7q;ˆRР^аУK 6а "'ОІъЊМ6sнЭыоВффц(+ˆд§вћ7њў “$\^@{…!ЬV‹`щлВЌрAiўЮEЯ:ŸЫїQCY…ч>ВЪlЙЊBTбs(2'Ы‡‚ahрЧЫѓ7ЋК68в 'ŸŸКинѕйё–дююфДl‡эвютЌфзиžnmm…‡Ѕ/‘Щ‚СˆЦˆ>J:2цgФ~ћјђВшЈЌ~rјRпйпƒNAŒёonє4ПЗ=#wž•Kž|ЏЯЙяйqщ$^–а,"ГС‡iЂ+c1<ї}ЎЦЬ7Ы\l1ЛЦхh;ЕЯУц.IЩBŸМЩ7\nь,џВ=ахКS]ЮСЎ{Ѓ†Њ=ZxA&j“!ќзЫzфЩШЗЙз Ÿ_”?няЇ‹}W+Ощд‡ЂрxЖLЩЬиЁƒ)У ƒYтРbсРjсЂШ€EfТ"ВXM` P‚!y~Ÿ/kЯъX [gЁtEžчтМ­V’ЌМi C@фЦPВЁСЄрЕ›Kп_Љgя'УъU’ЛmюєћsbТKФŸІЮJYP$8–‚єо~vНёЦSлГДХ'їК-]Ј= ’zАњЪМHD=ŠЧ{*Њђ#ъГMЦKtѓцЭрvЛЁЉЉЩ,уЩёtaЃтб€9qќVАГcРŽ…ћОШ?У9І!€Љ‘n$‚иэv№ћ§рp8ЬЭввв€ёщЉ*ZreUЋ40mЇнzрЋМa:}”*ее'ћœџxйЖœЅKџиыЕn6|§šы? К1"џюƒЮEIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/options_25.png0000644000175000017500000000226211733011756022624 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<TIDATxкЄV[hUўЮ™33;Г[­bmk+­‘Ђ(%DЋ )"E‹ˆQ тхE|ёС/э“ˆˆт‹ОљbAŒ’6ˆHAд‡…ЋS(DЄ/•nQZJ’НЭЬёћЯ™Ф]qЇˆіЬэћЮї§—‰ВжBŽљ‡_ќ‡угBс\с‹Ајзћуг™’_3xqѓо)DЖyЖНЬX‚эЗa3FПуЃшё~/§мТьЦsИ0\Йs ИטpцZсьбжp‡Hт-;5ОkЖ‘ ЯШ:ЫnuWwлШ{|ž/уу]Œэ-pў„Сe›ыD"x—rН.MЂ‚FvФŒ=ёЊл\РZУ„‘ бќ~ЭLbл­:њДЛІ “ЈЮ‹зй6D‚Œws€/Z;В‚кXЦмтq<2=‰ЋnГHЎАјёЯ`ЉCЖ€;"\кї‡&Щ}њюj.41џ M‡Џ‰Чпz ›nБД8љŽЦдщKАrћVОУћђ ‹РF+Б9“J‚Џўќ{žНѕkzЬ№одaк]ЧJу,ж ѕЕТs‹1^МыrЊ…Э?TMПyЎЋьъr^Y<†dk&ЌБџ§8е:…ЋяГhS8ђєgјщ…}‹”'rэ$CgRЂ,|xэx{пPG@tџILьocщДТі`'vM@[!WА ЎЫмŒ")њ+Ў'ЄToо~оМч ~o*,ŸЮ-(ќёСбзцœ:k Џ"НB)–јbJкЎЅ'X_и}§n|pЦ):У<Ь>из@숕ЊZГ‹D†’Еq­ЂŠФ;у”ќ6ѓКлэzЂhьqeнјrп2gЎМнюuЉТˆ"‚+уЃŠФюН{pсkŸ`6Уuы5ЋVщ?ЯисНзVIo™#Ў*aV‡оЁй’eсYpзŠ'Н#ЙЖeЕr<рЁЩМg[ш‰Б­VUТ2ќ@у/сFDє9фЫaФБЧФ rHzrмћя,* †ЎЪ‰LX„(H–ы„EbqЇAТF1,TDлЅkbЪћIдЊ•x‹ g‘;Ї]JYg‘Ќ­+]БŒ§#6 )ѓрЌJ I’ ЛмЬЂџЙЯ‡'Rr к_s)ЋжРХЊд+1‰/€‘$,;/ПtзЋJn[З+]вЭ€SкTйхЖЌœeо‹еoВfщ*WОžLЏі…ћw9ЉR"Qр•уU+5№UѓЙ‘ч\туЄTњu˜zU•$2ƒ’Ј$Бkпѕ7 AљБ!$iн'Zђе=QTVТh$ЮЎуЯмHK"зсšўkZ#™ZЪОcПдкh”UЊ‰ROЂ+ЦŠ›Gi‚Gп} шѕ]їЛNF9>ЄTйЊє^dђŠЂ0ёУВ8? ћўяКиБњз_ 2ŸжЇыЌчIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tag_64.png0000644000175000017500000001533711733011756023354 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<IDATxкь[xeК~gN?9''Н'ЄQB MБVtЫ* qз~НЛіkйХuеu]]нk/Ј‹ЋЎ,шК"Šz -=$9INЩщeюћЯLBXБ\Хђ<{чyОч sцLўЏНпћ}џ m8KBѕ‹IЎcуlYцѓњијр…жhG]iднXїДš•dЂŠr„F!ЩЩ`Œё| o"Qж‹пѓ9т\юїh“.ўЯџЎ‡tИ аЯB\й’2R6[182&Qб’d4”eЮ)K1ЅхЩ1o[2жQŸT’IŸ з'‚о]ќЭ ” ”§”Аў8%ЦuFї:‡Yi?В(C)GR&PБa’нUdЩhЕ•…%Пq'КW.AЂЇKN}2d9C‰Ч2x5e<хЪ2ЪЇ”і^gс{8Œ‡Aщог#('PŽ чsЭ9Ѕ[йhЄTM†НтX ‡ Аc5іПp+Ђэћ<МяUЪѓ”nЪY”YL‹JkV2м38юwП*Эo$Cў=є~ь'iн3ПЄ\%™ЌЅжТСFсiћРёА—ƒ9З†”4ѕЦPн4§e!Ђю†Fўѓ"ЪŠ~щїљ8”фуБЎц)жЂЁу‰ФŽПыъ ?9ЬЃмm+­ЖeN_ћ ‰АфU@Ж:ЈKHшŽS’шzџ ЁМИpЕPў_DcьЂ.ЂїWB’ђ=х1OлQLЃxн}8СЏїПcјцЧ[ лŠ=ŒЬ—€†€’ˆ#XЛ›ЯБ`ѓ<Јсјж/S=MywФУЯBШЁŒ R#кQ/ h2ІfфПѓ)†я#фя М™џI)Ы:щRи+ЧЋзлWaћ/‹аќјpŸƒе@ч C№XMХ§_ѓјхЬ{E’СцЬсП єJ€ŸRLЇœчu"в>_Нр[ПœŠЯGСЙ P|бЅШ9qІ 2‘єЈС›§мђ5Я.W’qаћ083Ф‚R^sўd @ячђуWВХž’sњС`зТМюž3{ъHw$Ь™™Э& *Рs;lFіЎH`‚*‡>Ю6gУV6 FgІ]2ZЪy-§Ї (SГNМ ŽсЧЉ:п †sиH5м5Qш}H€ ™,H;jЎИU„єm›/ЙРŠC`ћkСФsУŽС‘i’ŒІ"С/tžёу€‹ЦЫ­%#yТ/ДђЖЏЏоŽŒЃUУМW 'RAЯ–дћ„2Ї],NЯЃ<Ељ—ѓвБDŠч/фbMё9Фс3NМН‹ЇЃќFЭBQ!_vАO` e@тпI}"їEщєќ˜)pйй‘™г/VPУxХУDќёH)Џ р%ОђЧЎбŒEСО;f џќ{сu‚ЮЂ•)#е^!TПяќ U6ЈПЁёV…П~Рј Н/КЛ_ @аx§F.ђ(]ј‹ЏUОЯеЃ`JuТSГm/оЈ+пЏЩ#pкKЫ`Э/€9+‘ж]j ез™њЏГ†2м—фЭЙU'ећяў2'MВ’њЅЁЈУ6 T•d4rшВdЖРЗiЁ кD)1оg0 +ЙО–XўоŸЩEЮ‘г:іTё-Chї 8‡T1YупJdƒсЂ„C№mй„ИЧЩŒ&тA'єIPтM*/Ќ~)Љ)wі-0Кr 8z§НgЁ№ЌЙ0иlЌz‡wMžšЯмЗUеƒL­+-ЂJТ§cTK)г&Юю>їлFъАсH)+гМyHG‡ъ§’Ћ_†1-Ђ#є~њЊHƒz~НіPƒ˜я:Ю3~ №-ДфUJЙsoы>ї›wЁdо|ЕЌ)‰У‡G‚9 хєОsФq*Съ^љŒк]ђXJйўCGР-ЌKЅЙgнЄ’”>р›4ІћAо_ЕО o[†џ^4чž<ќ[-$диџŽэ|ЯFQиЙ ž5сПж{ь юЋјэ’=/с„А‹ЈŒ‰““О.<уў5–8ђQ3t‹ˆhPи5”ry‹?ігdЦ/щ!cЗ|…ш§“ј1Ч5n&пЙZnЎў+ТЛоAц™gЊ-nя ЧpЧcЋбэ aXyЦAп}г#2їз#тvУRTХ рЃїŸEИqk [§RрјыŽмП“=XШЗ#ŒH—M8‰ŽHкуrР$ЫЕZРФЬHЁVВШЄЦЬ“q­тJНƒіфWD•6ћ`zйЇ]Ѓжсd$ 2ОЂ3Я`Rђў_—oСЪЯpї•Ч`$ №UИАyw2Rm(Ь9˜ењwю@0є/utООЯп„уЛJR2МЕqњƒьsš{A;A@дƒ ВdV!žЬdEMЪ~љN‡Œ`Фss)ц "’ >Ѓ qЕ‡ЄтJќ›ЅР[2І-$№MV/tМёЄV 5/ї 7ДљqыУaТˆ|œ3}рWzП~П3.}чX…ЛЏ˜r =^†ў”\ОT-{бі}№Ќzh<дœ5qљsБISЃЕШ6Sq;ћFС‹dB%qjШъёсє/ъЫ2БВ9€к1ІЫZЋЋГŠб\ЮЭЮпЕѕhФR’ОԺΘЫ_&8яьлЕЏ]‹ŽзюФ€sч~СЛЗ?њ1К|aм4oвь†Џєў­F,žФ)KњюKD"№зж"идŒ”ЁSеЁŠgЭ №юјяЮ7??р–E>*m.˜ђ\ZшbšTФl•`Э‘%zНЂБз‘0_ИЧƒдŽNЄ†Јs:‘[bФSCвсsв€fуз€Ч ќ6Џј’GXуSЕВGрЫž4F‹љ пZл€Ѕ+jqбЉCpLunпw{šНЬ?ЅyЮО?ДьуzМКr/ўcfеAїЦ:;спНЏU›Ћрžu№|ќъSтуyЦ6)ѕШ|тo)ХL­ЛHzЂbц’\y’иT0D}(jjA‘:ˆЈ7Є'Hв`юАя*.Иƒ1uFљP їgрK;ŽЧїіьОw‘yтŒƒТЛ'У]Яе ЫeХ чUї}чч_8эКЗ0Њ2O^7&ЃЌоћЛgжсоDˆооКРз ki5A/К?|сЮ˜Ї\ƒЉУG Ц… žхчO:ЉМŸЪЧtоOh5#5pбІQFH$Шыд0(аO2 вЈЇДH.„'УŠхћќ§[Џ~TXg|ВйAюЌUoФ§nД>}%ВЧЅ'•ƒhьЃЏoУКX|бфЄšњЎџўйтB~vT1LRRНіШkлАaw'ю\8йNcпНњz›[ШјіiРWГ\ЊЪ‘=с LЫ3ЁšЋЪЕвН’ЖBD+ф‘@eЃqM!ŒEmЬбТ@(—,Аvy1ў“]ёkуFfЉї _ьDkV)ІЛіЪ#Да_v?Ѕ%0ЛœЊзzeg}юxnІЩЧь)Х}з?ло†^йŽS'сє …ъЕ=Mмљќ&ЬW€Y“‹њю “ёљwя%у{…]_ "Э;р]ћw(3’чЃ+Е­TВ•Ъјшi/ЙЌэЙ,6‹–Ч„Ub4B!dФУкўБф”‘R Уž!,кКэгФдЕ›cѓ >и-=#ёƒSрhЪХжтaЄGО]ŸРЛђ!ф7х VwOk.р3†Ѕ‚цVёЧ"сDX&qћ’M00Йn?xпѕ[žЊQПЛщь*эZ2gЩkFЈ­ŽЊ)*№y?О+р˜z!<•“UOчйЈ0Eв#кг ТPF; БЅ™˜а!€PїЄPœАfKpИtrдkОйœL*gеuЁYљКЯ„ЖўИŠЭŽЋ`одцCЇFэ6>T†’<`Ў.’,†ќЅ3+0Ж2ЕяЛЅ4рƒmИэќa(gЬŠыЏЏmСk7уЪгЂКЬйwo˜dЧ[ЛCиЃюЊ+HŠЋa™2В=]н^ігXuєь^JЅGFB*W<(FсП#T8а”4 ~@cXE”Є№ї™‰хёIJ†ЄŠнЕБЙВЂlСа†Г }8#у˜љpŽœоЇЈh{ыя;m~‚Œ‘C`rjФe\y*Пb ‘Tба‰G“;„›Ÿй‚qгБш„ъѕNЂетПnGIЖWŸ^бwo"eшз! 1є‹g›лEОщjAъЌ‹ЯЃЮвZXГ_` єй. ЛUeЧpg•“ъЬљJ№Б[kщАˆІИ‰щ!fFBљhXУ‹MCў`kBЗ…Гh•t$-}MТюЎ>•ЊЋAСМ{a-ЩdХˆ%=ъШЋщЙ_#НЊЮђШDГŽНhОГб #Cџк3+`5(ъѕ‡—яСŽ&?žИbвl’v/lйOiУАЧіЋuЊgѓћ*№9ЊO€cТй“хˆљѓРг5 кї/М2,ЋHшickЋ‚ЖJ#ЦUH(ЁwїQqLлƒUgEI­FкšђЂтyЛteHM#+ЌoJ eGw?4\2Tz) fDліVwЏ|Z%Южтс*Аœ€ДI\˜лƒЎ—УdЗТи‹BК”хиАрј"”ѓ“љ…э~\ѕиV;"7žUЁQgоѓїРГs/Š.ћ›КCэЈCлЫ‹‘‘vђе0—ŽF7•XЭЎџОO4Ќцo<4ЈPAnтK"ЮD pфH(Є’,У!я АG€™KД;Д!uРK-ЃhЭN“’gјsaЉЁЙ,GЦiљЊР>ід№s6 Б^ММPїћгй‡ПЂо`ЩЙч>€жеŸС]Г•‹kрЈ‹У,СBяGЂ1мЖДVУ[f—Cu‰п' з=ЄjawУІЊЭŽчуUАЕ9Ц‘'Ћ:юЁrїn RЕкˆЅPJ7hЦf# gЫ0W˜‰M›0%-д{‡e‚їє†ЩCє6CБ˜А`њїЕpЗј&ЌrПmщ—ј!КРпvЎ‰6ќщчт'ФК[Д]Щч`ј3~иЦ,@ЫЪu№зЗЈг ўвдФG;пŠ˜Яп …щF,Пn$LЭэЛ–…рЋkBСТЧaЩЋDмл†Ў"цnDЪ„9А”ŒTБ‹ З†Ѕ-FЅLЉWRMfdЅ PтG6†ч–HёуВЁ_@іGуD3i2k (‚.Тg…КшŠЖXЯЬѕtcAЗ?yГЩЇŒЖ…0рCEi„O)Syz%ми№РhИя\Е1‡•\БЎnDыš№эmb=УТЇ /Д!W0>}ƒ4авСšпе7PѕozOДКА: 6ŸЂЧЎ(w\И™•˜AЂ*ŸрПг‡šЂcGXіГяЉџАm+Z]гE,\p‚ИЮE_`аБMќ6N\ˆ{$| KКI%ЃuwьgЁФllш7š гїыћwOxзН†}w§ ­Япи;ЄDжI—cрн› •ЮDы'›fЈ+bTІKАЃ ž=xWњЪLИaГ:UŠYœH›zщj–рFˆSƒffaЭ‹ТТЋ‚ .H;RВь(Œ*pД‘мгХЇт.ЋŽќМЯbе бЫлд-ЪЄФшjzHЩАьк\/§т­]xтХi„mb6H9-юmЏmхwиu§Е„Љ Y0… ўˆмѓФўu[бЕmA/J/ФрнлŒbіљЂД ЦзѕЯgаY[ƒНUsс9C#]"d“§rй )o†H#2WТ4Зi3‹с 9Jнр#Шy‹Ќ ИпЌO€dХoi’ЈИ1MRЏЩjщ7 ЋENлН]нˆ§цлуb7†ђ†ў*м]єЄЯэгбќфUˆьп­о“~єЯ1ќi/lc/Є!ЖСГЛ‘nПОЦ№ўЧъ`eKоŒdhЬФ“šчХЇШхl†pЊ]Яœ„ЦьRI|ІхA"%–&dЉUBzg Ѓѓ€Lz|QоbвТ_”№САЫђЯy4Неs?ІЇ‚0„g_E|žS Œцч С\4•[ТГC%ŸѓбѕфњФiя_ЊiJOw УxTЮ/#Ї“ŒЛ‡i/Љ…ѕЅл’;ŠxюАН(I#ˆ]›YgЫs”xє†ж%зVћ>}­ѕЭъ+ВL“@4ЉЌ:іvлЅ“ГЄ)єn •ђPЋPBѓ~XЧсС"*2Ё+†!"єН4ŒиUєJсЃrщ6Эєlє~$Іw‡њдXЄ‘P>ф†№Л/=_BТ )фA(Я!=ЯцєхУљІhЏ!ўF#ЌГ2ЩыыяkДžЄжќT^!?N:­PЛW 6У ]’ZПв_*ЅмAЪR4ЃєаЕ їO:iŒЈF€2юнQKdL“ѕ Њєк/&Gёnv~rЊ9ЂZ^V\%=ГІла. )"М7`?x0jќ>ўГ„~lб›+TЌDvOгпнЂбщР‹Œ“7ЗВь•‘хjy/єЬOlk™И$ЇAѓЄЪ4ќBOR+›}ящKЯdщ БьљЩ@Щ– іdЯШ4ѓКs†Iэ3ƒ–0:ъZЯ[bпъ`‰[Кг‹Ф;Л1+nDКЛMbЎЕž=ЕX#BТдMYK“о­М˜>ЯXєk;DxѓОŒlў6(#ьQ5Iчv2ў§:,wаЦœGN&‰SЗіьмvџ iё6эSBЁцшАЩyЖ,“Э[єѕlёs˜ЛGqщf-ЧlaЪ45юŸcб˜ЌЩmК‘Dэ7и$5t’ьж5ЪЧ5ћР РС0A#ˆъa5ќРˆЇ Юn1(лC\щ–ŠмќДSіqFДGо”Ь=ЌщizЈ‹wТъЙрMЌљЌэMэ9ЖЪEРИJ …ЂЗ%ЯЯ:яѓiDGВHФƒфv#'аƒa!нуъŒA7ž/ў@ЕлH’+BS u ф 3-S*-LA†Шg_L>.v=Akm бqІK'Я7Qс‚*`™ЛCд3Ќ[:ЕИx)]ŒрГeЊ§з ЂdŸлТgн1ќ6€КЃЋ&.Ђ"!;j3Lш*Ъ€"jО№Јi1SЈЅзИаАx7J mu— /тѕˆехТдn…q'#ƒЗ:QA‘ЯЖЄ"aЫTZгR•зmfiULзPвЩ”GRљ"@mл…HыLIќŒАŒœpЦПД+xyН_ktœљZ‰Ѕ0$vНиI=>knУ№ЎК[сd›+™ѕљ)oВ Tк6ЎШp_c'оlŽЃНwЬоЋГH#~Œ Bц УЮHСр< щ ТЬсk}ўцfŒЩuСX‘ћxiKV7+…‘^“ц8У;тE,5 ГqIA…FЅн†бљ…O РЧяSrQSфТRЃ„wzЌ№ ч№П,§­б• šVeРМf7Т. VдБ<6еу8%ilbFьїЃЌm?yMfkЬbOEWF>‹Г№О5[и n‰‘Л 4Z:Іv0:ьC4г…WLihь6ъь?!ˆLЮЭXv3Ї‰…Щ@>ц%sogй‘`Xн eО†Г pR~:f4Ийо@*УћБ>м<ЮЮ$Ё•ЩUт"диќаJRџЮ‡Œѓуџ №яn€џ`™1ѓZQr7IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/up-arrow.png0000644000175000017500000000065211733011756022400 0ustar sylvestresylvestre‰PNG  IHDR rыф|gAMAБ ќabKGDџџџ НЇ“ pHYs  ’љЅtIMEб КXЈЗ'IDATxœ…’Нn1„?#о€–G€з‹%R’“HAA$ZjЄ;С яј~RјŽПe$KЛжŽg=ЛюrЙдY–! ѓo†їѓ†7УЬу}W+ЊЊb8аыѕžhuго&“ eYR–%ГйьI(ід›ы$aЗћОжьї{ЖлэЧq5Т98NŒЧуцЋ7, ђsMpбN›ЭчsŽЧуsЗЄiJ’Ќ›,>штpS6›/ђsŽC&‚&CuUбяїё&$ЕЄ ™тє›№fЈНoЖEYcDу{§jШэuу^7Яs>–KŠ"B$Є@(DR@УСYрфTлѕŽšd IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-tcp-neg_16.png0000644000175000017500000000166511733011756024132 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<WIDATxк\SmlSU~ЮНЗээзmm7і эSDуЦШ–0ў`А03Ѓ"К!Ф?NќЃјТзˆ1уˆYцHФ@€ lFСЖГ-vнZnлно{{ИЗЩ’Т›М9yOђ<ЯћМч=фЇ'hрё}pЌХЧЭ‘џGяпЇафmF{CN\?Žp"ЛХŽ ]Шчфзы7От—~Ї”“д)ќD0ёkН‡ У8rљъ+pІЏ`Uќrћ$МЎ:œњ‘–&бГєЋ­šZЗ–YЎcўšm5ЎЊН?п§]Џmў!pШз2Џ[пјцоh>ж`5Yсpђј`Щ‡Аѓˆ‰џj8ЬеRа +oТ Р$PЬ5Я—e’№Эœƒ№h(мьiAk6TЋˆC_ ТGн8wѕь% ЬщLŒйhІФXБIx<П;ПЖгЇ1cЖАђ“kЫб9…ВrпЖюЧР;З Fхг[ŽѕќЊaХ"–o2ЁЬщD•ЛzaGнzдЙ=ј:ИF­Ћ–ъЗPсvуeЇПэX71qьГШЛ-VJЊ1{бRЖ”№0щйф§oЮhУћ5_ТkѕЁЕ|lxj_Zэљљv›ёLhЮЌЭ:Ё”ЂяNМM–ЅMН7уžxЎ"ЙЊ§я.f—оИд›Ў …ѕѕ­LњўEиb~ИGяi6 'ЩO%•v10lkяjV-_фФхG,ОП™oКsхТЩ•UмВWлп&ЬЃAШ§С•WТрАУсp 56nb-GЁ:ЩQ<ц0№iЇ?'CтьvАf\х<М*ЫVN“ Š’І…J}аm”Цt}юzœ"Q)HэB#бі•Е№(ИPbQ&Чv-h]AЅЇ•9Bф0„ek‘O>Е›эФђЂжž˜Ь™W?)~€хiАђŸšo6ЂНUJwЅ]$ASуˆў1”ЁDhуŒІAцEpЉ‘Ѓ[vODE†tлЉр$2œ˜ЕЊ(е{yюEхRDpя™x8В„а&њп?\F5ю#,Л€1 З й”гћ\кvim(Ћ•‰'‡E1b8“‹rмqZPЊС№Q)щvр™62_ЋNуIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp-ref_25.png0000644000175000017500000000355511733011756024277 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxк”U{lSчџ]ћњлёƒ<œ—c‡œ88 ЩB+ ƒ)­JЩTбV•fEн-bЃг*жiˆŒnыTZP7ZДI-­Dh*ыВ…Ei)С‚РвnIIРЄ<œ˜8&‰‰пОwч^cDФўи>ыШї;п9чїчЧ№<џŽуVЯnR‹Ёd‡ZЉNH%в]ФлрћАЙВy"Щ%ГRж$ШVUA5’ Ўr!ŸXЈ/nјѓЭчќвЫlА O›џ„зМЬђлШћ§}G.ˆпO лЁR~`ВŸOЫ є›Дёžљщї^9Ля>OXъ T№j–Ј+Y •JЙВђй“[qeВЯЎ};ˆмЁqя})9^”ђіCЦЪПsйеЉ ЋHн\Аa1šёЫ'~…цšf„x?кћ?+ЪTd@ єMѕf„%~МдИMљЭ7ВДйќчГUWЇ@T И1џ5 ƒХщ€œx<§DВQšoЦSжmSћ7(ЬyХЙ~ˆžШ4d ИN Й†Чfлї№—ЫgЯ_zїЭЧŽї˜™я r ’[–Ѕƒ'9ŽгCBЁж—Џ#”'В гёqќ}ђtсЮПnљіb{ D‘Щ‹‚{ђL€‘FНёNYсJЇ^­w­БжЯ rТjЬU"ийБЂlu‘ЪЬ40УсC‡pСћ)ВщBлWЕЄТЅШBЌ2V‹пУС~lЌљЎНмTa;№яжg UьЉ<…xдвˆўХ‹"Y(4†L–{Uq^ЕїUњoG{Оўт›іDNѕЙ зђјгx^Бyzин‹ЮЛ ЙАї/#1ЏЧWѓ=ЈЪ­‚”і‚dAe‰‚‰?;qrнЧнФžЙ—Ftе{wvlе[ˆ*8t{'ŽК^Іа0xqхЄs'•ѓАхи!S3АeйiЯ Џ0RЙ•Ieёпќлˆu…Ш)=x№ Q*уыj јђfЧ†‚'nэ(ћI…Ni€UWзЌэјfxь*5d_ЖСPQЋo„E]Ž"ЕO[ “ыQHпЪ>Œeе(зксКrэв—н~Ž›!žЁ2z}3?яўgђЉЖ-Фќц/НknЈXл‹Чђ|rјѓ3Žг—п~ёЙ­ [і9?=МB—UАI—U„qG{$ЇиІдXсvœBбђUˆФ OзБАоМтзіС‘У‚‡›Й&чћЫtЦm&]vƒ:эўD,TыѓнќElюьХxрœ;^tяyН‰ѕЛЯaЭ3 c #973D0D", " , c #903E10", " < c #6581AF", " 1 c #C44C0B", " 2 c #ADADAD", " 3 c #903C10", " 4 c #C5AB9D", " 5 c #496FA4", " 6 c #916349", " 7 c #7F93B8", " 8 c #184A8B", " 9 c #BC4B0D", " 0 c #302F2F", " q c #ABABAB", " w c #BB4B0C", " e c #873B11", " r c #BB490C", " t c #7F858D", " y c #803A14", " u c #A7846F", " i c #863910", " p c #A9A9A9", " a c #793B17", " s c #7E3A12", " d c #7F3813", " f c #607BAA", " g c #B2480D", " h c #295795", " j c #A7A7A7", " k c #929499", " l c #B2460D", " z c #7D3811", " x c #753913", " c c #BDA595", " v c #42679D", " b c #215497", " n c #265592", " m c #996D54", " M c #A9450E", " N c #734832", " B c #B2907D", " V c #743512", " C c #40659B", " Z c #77492C", " A c #A3A3A3", " S c #A7430C", " D c #446495", " F c #878F98", " G c #A0420F", " H c #6B3413", " J c #A1A1A1", " K c #9F420E", " L c #6E86B1", " P c #A34308", " I c #6D86B0", " U c #6B778D", " Y c #9F9F9F", " T c #974110", " R c #8E8D8B", " E c #6B84AE", " W c #963F0F", " Q c #9D9D9D", " ! c #963D0F", " ~ c #5F5153", " ^ c #4E70A2", " / c #174C8D", " ( c #285CA1", " ) c #335C98", " _ c #C24C0C", " ` c #9B9B9B", " ' c #325C97", " ] c #315C96", " [ c #C14A0B", " { c #8C3C0F", " } c #BFBEBB", " | c #685E69", ". c #999999", ".. c #7F3C16", ".X c #843D11", ".o c #853B12", ".O c #8B3A0E", ".+ c #2F5A94", ".@ c #B9490D", ".# c #B8490C", ".$ c #CDCCCC", ".% c #979797", ".& c #B8470C", ".* c #798FB5", ".= c #124688", ".- c #6C717A", ".; c #4369A1", ".: c #82390F", ".> c #833710", "., c #004594", ".< c #ABA8A4", ".1 c #5D7BAA", ".2 c #959595", ".3 c #0B346A", ".4 c #7B3812", ".5 c #8F5C40", ".6 c #AF460D", ".7 c #643623", ".8 c #96A0B7", ".9 c #7A3611", ".0 c #939393", ".q c #5B77A8", ".w c #BAC3D7", ".e c #596A85", ".r c #723713", ".t c #A6450E", ".y c #235392", ".u c #723513", ".i c #A6430E", ".p c #814725", ".a c #713512", ".s c #919191", ".d c #A5430D", ".f c #B8C1D5", ".g c #C6C6C5", ".h c #693614", ".j c #215190", ".k c #3C639A", ".l c #E1D6CF", ".z c #8C9BB7", ".x c #AFB3B5", ".c c #20518F", ".v c #8F8F8F", ".b c #898E93", ".n c #9BABC9", ".m c #8698BB", ".M c #6084BA", ".N c #9C400E", ".B c #8D8D8D", ".V c #4B4049", ".C c #704328", ".Z c #335E9B", ".A c #8C8B8C", ".S c #C84D0B", ".D c #8E3E14", ".F c #8B8B8B", ".G c #943D10", ".H c #6882AE", ".J c #B0AEAC", ".K c #983E0A", ".L c #6782AD", ".P c #415F8B", ".I c #97A7C5", ".U c #B0ACAC", ".Y c #7C93BB", ".T c #793F1D", ".R c #898989", ".E c #BF4C0C", ".W c #724020", ".Q c #6680AC", ".! c #913B0D", ".~ c #4A6EA1", ".^ c #BF4A0C", "./ c #95A5C3", ".( c #893C0F", ".) c #8A3A10", "._ c #878787", ".` c #BE480B", ".' c #BCBCBB", ".] c #823B12", ".[ c #804E31", ".{ c #536C96", ".} c #B6490D", ".| c #823912", "X c #858585", "X. c #B6470D", "XX c #104689", "Xo c #494F54", "XO c #B29483", "X+ c #803910", "X@ c #9AA3B4", "X# c #838383", "X$ c #758DB4", "X% c #CAB7AB", "X& c #783812", "X* c #758BB4", "X= c #AC460D", "X- c #AD440E", "X; c #783612", "X: c #5979A9", "X> c #A57F69", "X, c #818181", "X< c #773611", "X1 c #4B4C4C", "X2 c #A3B0CA", "X3 c #64575E", "X4 c #495475", "X5 c #889CC0", "X6 c #6F3513", "X7 c #A1AEC8", "X8 c #A4A2A0", "X9 c #7187B0", "X0 c #CBD2E4", "Xq c #6E3312", "Xw c #A3A29F", "Xe c #A2410D", "Xr c #9B4210", "Xt c #97684E", "Xy c #1E4F90", "Xu c #A2A09E", "Xi c #39619A", "Xp c #5473A4", "Xa c #1D4F8F", "Xs c #B4BDD4", "Xd c #A1A09D", "Xf c #9A400F", "Xg c #1C4F8E", "Xh c #9F7963", "Xj c #7B7B7B", "Xk c #ECE4E0", "Xl c #A09E9C", "Xz c #375F98", "Xx c #8296BA", "Xc c #1B4D8D", "Xv c #7A4121", "Xb c #9F9E9B", "Xn c #B79C8B", "Xm c #8196B9", "XM c #C64D0C", "XN c #1A4D8C", "XB c #9C3F07", "XV c #C54D0B", "XC c #D0BFB4", "XZ c #E4E3E2", "XA c #AEAEAD", "XS c #9E9C9A", "XD c #926449", "XF c #C54B0B", "XG c #194B8B", "XH c #AB8772", "XJ c #8A3C13", "XK c #98999E", "XL c #777777", "XP c #2D5A98", "XI c #BC4A0C", "XU c #11488D", "XY c #667284", "XT c #7B3C18", "XR c #757575", "XE c #9B9897", "XW c #3F4040", "XQ c #627EAB", "X! c #DCCDC3", "X~ c #873A10", "X^ c #71819C", "X/ c #456A9F", "X( c #737373", "X) c #824D2C", "X_ c #90A1C1", "X` c #B3470D", "X' c #838386", "X] c #8C5E43", "X[ c #7E3711", "X{ c #763A13", "X} c #43689D", "X| c #717171", "o c #7D3710", "o. c #0C4488", "oX c #275692", "oo c #A6A6A5", "oO c #763813", "o+ c #AA460E", "o@ c #A3B0CD", "o# c #757F8C", "o$ c #7F8182", "o% c #885C3F", "o& c #753612", "o* c #5F5D5C", "o= c #A9440D", "o- c #A4A4A3", "o; c #6D3714", "o: c #A9420D", "o> c #65789A", "o, c #6D6D6D", "o< c #A1430F", "o1 c #A0430E", "o2 c #6F87B1", "o3 c #A1410F", "o4 c #A6420A", "o5 c #6C3313", "o6 c #5375A6", "o7 c #A0410E", "o8 c #6B6B6B", "o9 c #6C85AE", "o0 c #8296BD", "oq c #9CAAC6", "ow c #6F7986", "oe c #97400F", "or c #696969", "ot c #5171A4", "oy c #5071A3", "ou c #5E6572", "oi c #676767", "op c #183C6C", "oa c #C34D0C", "os c #C4CCE0", "od c #335D97", "of c #174B8C", "og c #8E3D10", "oh c #DDCFC7", "oj c #ADB9D0", "ok c #883C14", "ol c #9B9A9A", "oz c #325B96", "ox c #DCCFC6", "oc c #7D92B8", "ov c #16498B", "ob c #A1A8B7", "on c #9A9A99", "om c #7C92B7", "oM c #ACB7CF", "oN c #C1AA9B", "oB c #BA4A0D", "oV c #8B3B0D", "oC c #15478A", "oZ c #B94A0C", "oA c #DACDC4", "oS c #7B90B6", "oD c #144789", "oF c #CECDCC", "oG c #8A7365", "oH c #B9480C", "oJ c #395B89", "oK c #BFA899", "oL c #B8460B", "oP c #703B1A", "oI c #CCCBCA", "oU c #B0470D", "oY c #7C3712", "oT c #5D7AA9", "oR c #0B448A", "oE c #4D6896", "oW c #B0450D", "oQ c #7B3711", "o! c #8C9FC0", "o~ c #743814", "o^ c #949493", "o/ c #5C78A8", "o( c #733813", "o) c #5B78A7", "o_ c #7D492A", "o` c #8B9DBF", "o' c #5D5D5D", "o] c #A7440E", "o[ c #723612", "o{ c #3F649C", "o} c #713611", "o| c #235291", "O c #723412", "O. c #225290", "OX c #12407D", "Oo c #713411", "OO c #5B5B5B", "O+ c #889BBC", "O@ c #A5420C", "O# c #E1D5CE", "O$ c #9E410F", "O% c #AD8D7A", "O& c #693313", "O* c #E0D5CD", "O= c #9D410E", "O- c #9E9EA0", "O; c #8D8C8C", "O: c #575757", "O> c #C94E0B", "O, c #735641", "O< c #6983AE", "O1 c #C3AEA0", "O2 c #754122", "O3 c #555555", "O4 c #734120", "O5 c #6781AC", "O6 c #8C3D11", "O7 c #76849D", "O8 c #C04B0C", "O9 c #96A6C3", "O0 c #9D745D", "Oq c #4B6DA1", "Ow c #8A3D0F", "Oe c #8B3B10", "Or c #BEBDBC", "Ot c #4A6DA0", "Oy c #BF490B", "Ou c #98989A", "Oi c #703F1D", "Op c #8E3C09", "Oa c #B74A0D", "Os c #2E5995", "Od c #515151", "Of c #2D5994", "Og c #693E20", "Oh c #B7480D", "Oj c #6F3D1C", "Ok c #804D30", "Ol c #114789", "Oz c #82726A", "Ox c #2C5993", "Oc c #B6480C", "Ov c #7C3915", "Ob c #753A18", "On c #BBB9B9", "Om c #473A3A", "OM c #4F4F4F", "ON c #778EB5", "OB c #BCC6DB", "OV c #7A828D", "OC c #9A9592", "OZ c #E5DBD5", "OA c #838282", "OS c #793712", "OD c #758CB3", "OF c #AD450D", "OG c #AFB3C1", "OH c #783711", "OJ c #713814", "OK c #4A4654", "OL c #723615", "OP c #783511", "OI c #5978A8", "OU c #AC430C", "OY c #956C55", "OT c #18417C", "OR c #703613", "OE c #5876A7", "OW c #484452", "OQ c #703413", "O! c #A4420E", "O~ c #7F4625", "O^ c #6F3412", "O/ c #7F7E7E", "O( c #5676A5", "O) c #9CACCC", "O_ c #948F8C", "O` c #673514", "O' c #A3A19E", "O] c #3A629A", "O[ c #73330C", "O{ c #456291", "O} c #B5BED4", "O| c #A17A64", "+ c #5D6977", "+. c #573022", "+X c #474747", "+o c #9A3F0E", "+O c #7B7A7A", "++ c #454545", "+@ c #98A8C8", "+# c #94654A", "+$ c #C64E0B", "+% c #923E10", "+& c #C64C0B", "+* c #79401F", "+= c #9D7660", "+- c #B69B89", "+; c #434343", "+: c #913C0F", "+> c #926348", "+, c #ADADAB", "+< c #88888A", "+1 c #BD4B0C", "+2 c #414141", "+3 c #647FAC", "+4 c #BCBDBD", "+5 c #795236", "+6 c #637FAB", "+7 c #CDBCB0", "+8 c #93A4C3", "+9 c #883B10", "+0 c #BC490B", "+q c #883910", "+w c #476BA0", "+e c #643B28", "+r c #3F3F3F", "+t c #627DAA", "+y c #803A12", "+u c #778EB8", "+i c #91A2C1", "+p c #B4480D", "+a c #46699F", "+s c #453A3B", "+d c #45699E", "+f c #3D3D3D", "+g c #7F3811", "+h c #0E4589", "+j c #90A0C0", "+k c #EEEEEE", "+l c #B3460C", "+z c #7E3810", "+x c #6E7E98", "+c c #56372E", "+v c #773913", "+b c #295593", "+n c #07448C", "+m c #0D4388", "+M c #285592", "+N c #773713", "+B c #717070", "+V c #7A4B2D", "+C c #ECECEC", "+Z c #AB450E", "+A c #763712", "+S c #97A0B3", "+D c #AB430E", "+F c #A5A5A3", "+G c #4D362F", "+H c #909095", "+J c #753511", "+K c #4C5670", "+L c #393939", "+P c #EAEAEA", "+I c #8E9093", "+U c #5576A7", "+Y c #A1440E", "+T c #7088B1", "+R c #A2420F", "+E c #BAA190", "+W c #6D6C6C", "+Q c #D4C4BA", "+! c #9FADC8", "+~ c #E8E8E8", "+^ c #A9AFBE", "+/ c #653515", "+( c #A1400E", "+) c #3E5276", "+_ c #6C3212", "+` c #653315", "+' c #A0400D", "+] c #9EABC7", "+[ c #814320", "+{ c #353535", "+} c #9F400C", "+| c #8D99B3", "@ c #734526", "@. c #5272A4", "@X c #919AAD", "@o c #983F0F", "@O c #5172A3", "@+ c #696868", "@@ c #E4E4E4", "@# c #1A4C8E", "@$ c #9E9D9C", "@% c #355E98", "@& c #973D0E", "@* c #5070A2", "@= c #65432C", "@- c #903E11", "@; c #9D9D9B", "@: c #345E97", "@> c #888A8D", "@, c #4A6FA6", "@< c #78787A", "@1 c #7F95B9", "@2 c #C44C0C", "@3 c #95A6C8", "@4 c #AFBAD1", "@5 c #8F3E10", "@6 c #313131", "@7 c #C34C0B", "@8 c #E2E2E2", "@9 c #8F3C10", "@0 c #9C9B9A", "@q c #823E17", "@w c #174A8B", "@e c #7D93B7", "@r c #164A8A", "@t c #863D11", "@y c #E0E0E0", "@u c #3D3A4A", "@i c #6D3D20", "@p c #2D2D2D", "@a c #853910", "@s c #713C1A", "@d c #5F7BAA", "@f c #A4B3D0", "@g c #B1480D", "@h c #5E7BA9", "@j c #DCDCDC", "@k c #7C3811", "@l c #8DA0C0", "@z c #B0460C", "@x c #42679E", "@c c #7B3810", "@v c #7C3611", "@b c #8D9EC0", "@n c #743913", "@m c #41679D", "@M c #784B2E", "@N c #5F5E5E", "@B c #292929", "@V c #0A4388", "@C c #8C9EBF", "@Z c #DADADA", "@A c #255592", "@S c #743713", "@D c #A8450E", "@F c #733712", "@G c #40659C", "@H c #79360E", "@J c #A8430E", "@K c #C8C8C5", "@L c #76492C", "@P c #5D5C5C", "@I c #D8D8D8", "@U c #235390", "@Y c #723511", "@T c #899CBC", "@R c #6B3614", "@E c #3E639A", "@W c #6B3414", "@Q c #9F420F", "@! c #6A3413", "@~ c #D6D6D6", "@^ c #8B8E93", "@/ c #9F400F", "@( c #E0D4CC", "@) c #3F5370", "@_ c #D4D4D4", "@` c #898C91", "@' c #755742", "@] c #9D3E0D", "@[ c #9AA9C6", "@{ c #C3C0C0", "@} c #888A90", "@| c #DED2CA", "# c #A3ABBB", "#. c #D2D2D2", "#X c #AEBAD3", "#o c #6C7685", "#O c #943D0E", "#+ c #993E09", "#@ c #754021", "## c #D8DEEF", "#$ c #933D0D", "#% c #8B8989", "#& c #4D6EA2", "#* c #555454", "#= c #C14C0C", "#- c #873D15", "#; c #164A8D", "#: c #D0D0D0", "#> c #8C3C10", "#, c #BFBEBC", "#< c #913D0B", "#1 c #7B93B8", "#2 c #793D1B", "#3 c #AEACA8", "#4 c #834E32", "#5 c #14488B", "#6 c #8A94A9", "#7 c #2F5A95", "#8 c #7E3C16", "#9 c #525251", "#0 c #843B12", "#q c #8A3A0E", "#w c #B8490D", "#e c #B7490C", "#r c #515050", "#t c #798FB6", "#y c #833911", "#u c #124689", "#i c #CCCCCC", "#p c #B7470C", "#a c #788FB5", "#s c #6F3C1B", "#d c #A8B4CD", "#f c #7B838D", "#g c #8D3907", "#h c #778DB4", "#j c #516A92", "#k c #86380A", "#l c #CACACA", "#z c #5C4A47", "#x c #04448F", "#c c #8B9EC1", "#v c #E4DAD3", "#b c #793611", "#n c #03428E", "#m c #C8C8C8", "#M c #7B4A2A", "#N c #AC440B", "#B c #5977A7", "#V c #919192", "#C c #E2D8D1", "#Z c #5877A6", "#A c #C6C6C6", "#S c #5C697F", "#D c #703512", "#F c #693615", "#G c #A5410E", "#H c #703312", "#J c #3C639B", "#K c #683614", "#L c #205190", "#P c #5675A4", "#I c #A3410C", "#U c #A43F0D", "#Y c #6F7A8B", "#T c #C4C4C4", "#R c #747B86", "#E c #3B619A", "#W c #484847", "#Q c #81573D", "#! c #0E4E9C", "#~ c #9C400F", "#^ c #8598BB", "#/ c #673213", "#( c #1E4F8E", "#) c #4F72A7", "#_ c #7F97BF", "#` c #5E7598", "#' c #C2C2C2", "#] c #7B7B79", "#[ c #6882AF", "#{ c #C74D0B", "#} c #C0C0C0", "#| c #8A8B8B", "$ c #734222", "$. c #6782AE", "$X c #8F8A86", "$o c #6682AD", "$O c #8C3C13", "$+ c #BEBEBE", "$@ c #7C5138", "$# c #4B3D40", "$$ c #6580AC", "$% c #95A5C4", "$& c #5A6F94", "$* c #ADACAA", "$= c #BE4A0C", "$- c #7D8592", "$; c #8F3B0C", "$: c #943C07", "$> c #7B4F37", "$, c #893A10", "$< c #BCBCBC", "$1 c #81868C", "$2 c #486CA0", "$3 c #813D12", "$4 c #943A07", "$5 c #A8B6D0", "$6 c #96979A", "$7 c #476A9F", "$8 c #813912", "$9 c #BABABA", "$0 c #2B5894", "$q c #B5470D", "$w c #466A9E", "$e c #803911", "$r c #0F4689", "$t c #CBB9AD", "$y c #B9BAB9", "$u c #2A5893", "$i c #9BA3B6", "$p c #85380C", "$a c #295692", "$s c #7B4C2D", "$d c #AC440E", "$f c #A7A4A4", "$g c #773612", "$h c #A3B0CB", "$j c #AB440D", "$k c #B6B6B6", "$l c #3D659F", "$z c #6F3714", "$x c #79482B", "$c c #879CC0", "$v c #7289B2", "$b c #6E3713", "$n c #7189B1", "$m c #6E3513", "$M c #B4B4B4", "$N c #74340F", "$B c #6E3313", "$V c #7087B0", "$C c #A2410E", "$Z c #8D8F91", "$A c #B2B2B2", "$S c #9A4210", "$D c #928E8C", "$F c #5473A5", "$G c #D3C3B8", "$H c #5373A4", "$J c #8B8D8F", "$K c #B89E8D", "$L c #99400F", "$P c #5273A3", "$I c #B2BDD3", "$U c #B0B0B0", "$Y c #375F99", "$T c #9E3F0A", "$R c #1B4D8E", "$E c #365F98", "$W c #983E0E", "$Q c #8196BA", "$! c #C6CEE0", "$~ c #C54D0C", "$^ c #B0BBD1", "$/ c #AEAEAE", "$( c #C44D0B", "$) c #903D10", "$_ c #7F94B8", "$` c #ACACAC", "$' c #873E11", "$] c #426DA7", "$[ c #823B16", "${ c #BB4A0C", "$} c #4F6175", "$| c #A1A6B5", "% c #AAAAAA", "%. c #863A10", "%X c #913A07", "%o c #834D2E", "%O c #607CAA", "%+ c #A8A8A8", "%@ c #5F7CA9", "%# c #BFC6D9", "%$ c #B2470D", "%% c #7D3911", "%& c #B2450D", "%* c #014492", "%= c #43689E", "%- c #A6A6A6", "%; c #B1450C", "%: c #564C47", "%> c #656F7A", "%, c #B0450B", "%< c #BDA495", "%1 c #004291", "%2 c #4D3731", "%3 c #BCA494", "%4 c #753613", "%5 c #41669C", "%6 c #255491", "%7 c #A4A4A4", "%8 c #743612", "%9 c #40669B", "%0 c #A8440D", "%q c #733611", "%w c #6C3714", "%e c #6C3514", "%r c #A2A2A2", "%t c #262625", "%y c #6B3513", "%u c #735949", "%i c #A0410F", "%p c #A5420A", "%a c #9F410E", "%s c #818B9C", "%d c #A0A0A0", "%f c #58433F", "%g c #9CAAC7", "%h c #6B85AE", "%j c #9BAAC6", "%k c #9E9E9E", "%l c #714426", "%z c #6B83AE", "%x c #194D8F", "%c c #888B8F", "%v c #AFBBD3", "%b c #903D13", "%n c #A89C94", "%m c #224D84", "%M c #9C9C9C", "%N c #4E6FA2", "%B c #C24D0C", "%V c #D1D1D0", "%C c #C3AC9E", "%Z c #9B9C9B", "%A c #4D6FA1", "%S c #325B97", "%D c #DCCFC7", "%F c #9E745C", "%G c #8D3B10", "%H c #9A9A9A", "%J c #7D5235", "%K c #305B95", "%L c #853C12", "%P c #14498A", "%I c #C0AA9B", "%U c #AAB7CE", "%Y c #989898", "%T c #B84A0C", "%R c #843A11", "%E c #B8480C", "%W c #5F7CAC", "%Q c #833A10", "%! c #124788", "%~ c #B7480B", "%^ c #314B6B", "%/ c #82380F", "%( c #997057", "%) c #8D3806", "%_ c #AF470D", "%` c #BAB9B6", "%' c #1A569D", "%] c #AF450D", "%[ c #7A808B", "%{ c #7A3711", "%} c #69361E", "%| c #C9C9C8", "& c #858FA3", "&. c #B1917F", "&X c #5B78A8", "&o c #723813", "&O c #AFB3BF", "&+ c #5A78A7", "&@ c #929292", "&# c #754A2D", "&$ c #4C4B4A", "&% c #A6440E", "&& c #A6420E", "&* c #8C8F96", "&= c #713412", "&- c #3D649B", "&; c #889BBD", "&: c #215290", "&> c #703411", "&, c #879BBC", "&< c #C7B2A5", "&1 c #B5B3B1", "&2 c #163F78", "&3 c #8799BC", "&4 c #20508F", "&5 c #926A50", "&6 c #8699BB", "&7 c #C4C3C3", "&8 c #A14209", "&9 c #2F60A1", "&0 c #683113", "&q c #9C3F0E", "&w c #C2C1C1", "&e c #944010", "&r c #8C8C8C", "&t c #233C67", "&y c #933E0F", "&u c #4D6FA4", "&i c #744122", "&p c #C0BFBF", "&a c #85898F", "&s c #8A8A8A", "&d c #6781AD", "&f c #973D09", "&g c #96A6C4", "&h c #8B3D11", "&j c #BF4B0C", "&k c #888888", "&l c #4A6DA1", "&z c #8A3B10", "&x c #4C5257", "&c c #496DA0", "&v c #B59786", "&b c #94A4C2", "&n c #8A3910", "&m c #E8DFD9", "&M c #22599E", "&N c #BCBBBB", "&B c #2D5995", "&V c #868686", "&C c #505151", "&Z c #2C5994", "&A c #433941", "&S c #B6480D", "&D c #6E3D1C", "&F c #B5480C", "&G c #004497", "&H c #813811", "&J c #104589", "&K c #2B5793", "&L c #848484", "&P c #B5460C", "&I c #768EB5", "&U c #CBB8AC", "&Y c #A5B3CC", "&T c #783912", "&R c #793713", "&E c #7C4B2D", "&W c #3D3B3B", "&Q c #758CB4", "&! c #A6806A", "&~ c #828282", "&^ c #A4B1CB", "&/ c #AC450D", "&( c #493733", "&) c #703814", "&_ c #773511", "&` c #873603", "&' c #808080", "&] c #6F3613", "&[ c #B5B5B4", "&{ c #10407F", "&} c #6F3413", "&| c #5676A6", "* c #7188B0", "*. c #CBD3E4", "*X c #808BA1", "*o c #7E7E7E", "*O c #CBB1A2", "*+ c #5574A5", "*@ c #663514", "*# c #7C7C7C", "*$ c #39609A", "*% c #386099", "*& c #9A3F0F", "** c #1C4E8E", "*= c #7E563C", "*- c #376098", "*; c #81411E", "*: c #993F0E", "*> c #D2C0B6", "*, c #C0C1C2", "*< c #924011", "*1 c #7A7A7A", "*2 c #D1C0B5", "*3 c #7B879C", "*4 c #1B4C8D", "*5 c #AFAFAE", "*6 c #9F9D9B", "*7 c #93654A", "*8 c #C54E0B", "*9 c #8195B9", "*0 c #1A4C8C", "*q c #913E10", "*w c #EAE3DE", "*e c #8095B8", "*r c #8B3D14", "*t c #E4E2E2", "*y c #AEADAD", "*u c #605150", "*i c #787878", "*p c #CFBEB3", "*a c #903C0F", "*s c #8F3C0E", "*d c #82878F", "*f c #767676", "*g c #637FAC", "*h c #883B11", "*j c #637DAC", "*k c #563F2F", "*l c #627DAB", "*z c #747474", "*x c #617DAA", "*c c #91A2C2", "*v c #383E43", "*b c #803813", "*n c #B3480D", "*m c #44699E", "*M c #727272", "*N c #7E3811", "*B c #DDDCDB", "*V c #B2460C", "*C c #8EA0BF", "*Z c #B1460B", "*A c #43679D", "*S c #0C4388", "*D c #275592", "*F c #A6A5A5", "*G c #707070", "*H c #794B2D", "*J c #AA450E", "*K c #F1EBE8", "*L c #A5A5A4", "*P c #784B2C", "*I c #F0EBE7", "*U c #7A7F87", "*Y c #656C79", "*T c #6D3814", "*R c #743511", "*E c #6E6E6E", "*W c #A8430C", "*Q c #6D3614", "*! c #72370F", "*~ c #76492A", "*^ c #87593E", "*/ c #2F5386", "*( c #23446D", "*) c #78340B", "*_ c #A1420F", "*` c #39629D", "*' c #6C6C6C", "*] c #A0420E", "*[ c #8C8E92", "*{ c #744728", "*} c #6E86B0", "*| c #B3BED6", "= c #9EABC8", "=. c #6B3212", "=X c #6D86AF", "=o c #252323", "=O c #6A6A6A", "=+ c #724526", "=@ c #734327", "=# c #973F0F", "=$ c #724326", "=% c #885435", "=& c #686868", "=* c #5070A3", "== c #9D9D9C", "=- c #91654B", "=; c #4F70A2", "=: c #7484A2", "=> c #7D3F1D", "=, c #4E70A1", "=< c #C34C0C", "=1 c #865233", "=2 c #335C97", "=3 c #174A8C", "=4 c #D1D0CF", "=5 c #8E3C10", "=6 c #9B9B9A", "=7 c #325C96", "=8 c #6E4122", "=9 c #ADB8D0", "=0 c #315C95", "=q c #7C8496", "=w c #863D12", "=e c #AAABAC", "=r c #747677", "=t c #BA4B0D", "=y c #7C91B7", "=u c #7B91B6", "=i c #723E1C", "=p c #C0A99A", "=a c #8C6146", "=s c #B9490C", "=d c #989797", "=f c #626262", "=g c #5F7BAB", "=h c #6E7E9C", "=j c #537BB3", "=k c #698CC2", "=l c #7C3A12", "=z c #5E7BAA", "=x c #3D68A4", "=c c #969595", "=v c #606060", "=b c #7C3812", "=n c #CBCAC9", "=m c #B0460D", "=M c #05448E", "=N c #5D79A9", "=B c #8690A3", "=V c #8C3704", "=C c #5C79A8", "=Z c #80370C", "=A c #733913", "=S c #8F9298", "=D c #7A3610", "=F c #094388", "=G c #4B6794", "=H c #A7450E", "=J c #3F659C", "=K c #A7430E", "=L c #235391", "=P c #C8C6C6", "=I c #723512", "=U c #3E659B", "=Y c #929191", "=T c #02408B", "=R c #713511", "=E c #3E639B", "=W c #5B3323", "=Q c #6A3614", "=! c #3D639A", "=~ c #908F8F", "=^ c #E1D6CE", "=/ c #5A5A5A", "=( c #C5C4C3", "=) c #8F8F8E", "=_ c #9E400F", "=` c #A3410A", "=' c #9D400E", "=] c #C4AFA1", "=[ c #953F10", "={ c #99A9C6", "=} c #7C411F", "=| c #943F0F", "- c #989AA4", "-. c #8C8B8B", "-X c #565656", "-o c #6982AE", "-O c #8E3E13", "-+ c #943D0F", "-@ c #8C3E11", "-# c #74787A", "-$ c #C04C0C", "-% c #8C3C11", "-& c #8D634A", "-* c #5C4F52", "-= c #4B6EA1", "-- c #72401F", "-; c #71401E", "-: c #9FA7B8", "-> c #8B3A10", "-, c #2F5A96", "-< c #7E3C17", "-1 c #4A6CA0", "-2 c #525252", "-3 c #8A3A0F", "-4 c #703E1D", "-5 c #833B12", "-6 c #814E31", "-7 c #893A0E", "-8 c #B7490D", "-9 c #2E5895", "-0 c #2D5894", "-q c #868585", "-w c #B7470D", "-e c #505050", "-r c #7F4E2F", "-t c #788FB6", "-y c #823911", "-u c #114689", "-i c #BBBAB9", "-p c #2C5893", "-a c #B6470C", "-s c #E6DCD6", "-d c #844B2A", "-f c #4E4E4E", "-g c #768DB4", "-h c #BBC5DA", "-j c #6B7C9C", "-k c #8B3706", "-l c #CAB7AA", "-z c #AD460D", "-x c #AE440E", "-c c #AC440C", "-v c #A7A4A2", "-b c #4D688F", "-n c #5877A7", "-m c #486594", "-M c #703513", "-N c #4A4A4A", "-B c #A4430E", "-V c #6C7993", "-C c #B5B4B3", "-Z c #A4410E", "-A c #8B7D76", "-S c #5675A5", "-D c #673614", "-F c #B3B2B1", "-G c #3A619A", "-H c #1E4F8F", "-J c #9B400F", "-K c #8498BB", "-L c #1D4F8E", "-P c #B1B0AF", "-I c #1C4D8D", "-U c #A09E9B", "-Y c #81401D", "-T c #8296B9", "-R c #C74D0C", "-E c #7D553A", "-W c #80401C", "-Q c #444444", "-! c #C64D0B", "-~ c #D1BFB4", "-^ c #8C3E14", "-/ c #D0BFB3", "-( c #A5AAB7", "-) c #913D0F", "-_ c #EAE2DD", "-` c #89898B", "-' c #8B654B", "-] c #BEBEBF", "-[ c #7E3E1A", "-{ c #424242", "-} c #893E11", "-| c #9C3B06", "; c #777776", ";. c #833D15", ";X c #6480AC", ";o c #ACACAA", ";O c #BD4A0C", ";+ c #A9B6D2", ";@ c #7F5032", ";# c #404040", ";$ c #637EAB", ";% c #883A10", ";& c #8F6045", ";* c #92A3C2", ";= c #AAAAA8", ";- c #803B12", ";; c #949799", ";: c #B4490D", ";> c #95959A", ";, c #466A9F", ";< c #3E3E3E", ";1 c #91A1C1", ";2 c #EFEFEF", ";3 c #2A5894", ";4 c #A9A8A7", ";5 c #949599", ";6 c #B4470D", ";7 c #85380D", ";8 c #B3470C", ";9 c #773A13", ";0 c #44689D", ";q c #0D4488", ";w c #EDEDED", ";e c #285692", ";r c #A7A6A5", ";t c #773813", ";y c #763612", ";u c #EBEBEB", ";i c #AA440D", ";p c #B5B6B6", ";a c #DBD9D8", ";s c #A5A4A3", ";d c #753611", ";f c #784A2B", ";g c #6E3714", ";h c #A9440C", ";j c #503828", ";k c #B6C1D8", ";l c #383838", ";z c #7089B1", ";x c #A0AEC9", ";c c #E9E9E9", ";v c #A1430E", ";b c #7087B1", ";n c #1E5192", ";m c #EEE8E4", ";M c #5A453F", ";N c #A1410E", ";B c #57697E", ";V c #6C3312", ";C c #D8D5D5", ";Z c #363636", ";A c #48648D", ";S c #744627", ";D c #5373A5", ";F c #1C4F90", ";G c #5273A4", ";H c #624533", ";J c #98400F", ";K c #5271A4", ";L c #343434", ";P c #E5E5E5", ";I c #983E0F", ";U c #263C65", ";Y c #898B8E", ";T c #5071A2", ";R c #784121", ";E c #7E401D", ";W c #355D98", ";Q c #323232", ";! c #C44D0C", ";~ c #5A7198", ";^ c #E3E3E3", ";/ c #5A80B9", ";( c #345D97", ";) c #C34D0B", ";_ c #7F94B9", ";` c #184B8C", ";' c #8F3D10", ";] c #865132", ";[ c #8E3D0F", ";{ c #9C9A9A", ";} c #303030", ";| c #873E12", ": c #7E92B8", ":. c #7D92B7", ":X c #C2CADD", ":o c #16498A", ":O c #473D40", ":+ c #863C11", ":@ c #00367B", ":# c #CFCFCC", ":$ c #913C08", ":% c #BA4A0C", ":& c #2E2E2E", ":* c #BA480C", ":= c #556D93", ":- c #CECDCB", ":; c #B9480B", ":: c #7D3B12", ":> c #4A3A39", ":, c #D9CBC2", ":< c #2C2C2C", ":1 c #DDDDDD", ":2 c #B1490D", ":3 c #A7A8A8", ":4 c #CCCBC9", ":5 c #B1470D", ":6 c #B1450D", ":7 c #7C3711", ":8 c #5D7AA8", ":9 c #8D9FC0", ":0 c #82360D", ":q c #DBDBDB", ":w c #909398", ":e c #7B3710", ":r c #743813", ":t c #AF450B", ":y c #5C78A7", ":u c #8C9DBF", ":i c #255492", ":p c #282828", ":a c #7189B5", ":s c #8B9DBE", ":d c #A8440E", ":f c #D9D9D9", ":g c #245491", ":h c #8E9196", ":j c #99918D", ":k c #6F89B3", ":l c #A7420D", ":z c #8D8F95", ":x c #723411", ":c c #262626", ":v c #D7D7D7", ":b c #A1A2A2", ":n c #9F430F", ":m c #878C99", ":M c #9F410F", ":N c #7A4526", ":B c #002E67", ":V c #8298BF", ":C c #9FA0A0", ":Z c #9BAAC7", ":A c #DFD3CB", ":S c #222222", ":D c #D3D3D3", ":F c #C4AEA0", ":G c #953E0F", ":H c #99A8C5", ":J c #DDD1C9", ":K c #A98975", ":L c #D1D1D1", ":P c #86898E", ":I c #4D6FA2", ":U c #555554", ":Y c #C14B0C", ":T c #646566", ":R c #1E1E1E", ":E c #8C3B10", ":W c #305B96", ":Q c #747579", ":! c #7F3D17", ":~ c #7A3A1C", ":^ c #B4B9C5", ":/ c #2F5995", ":( c #454A62", ":) c #843A12", ":_ c #13478A", ":` c #CDCDCD", ":' c #2E5994", ":] c #B8480D", ":[ c #8FA1C5", ":{ c #798EB6", ":} c #A8B5CD", ":| c #ABA9A5", "> c #CBCBCB", ">. c #004495", ">X c #B6460B", ">o c #AF470E", ">O c #365788", ">+ c #A6B3CB", ">@ c #AE470D", "># c #C9C9C9", ">$ c #5F6C82", ">% c #793711", ">& c #A0B0CF", ">* c #CAB6A9", ">= c #723814", ">- c #AD450C", ">; c #E4D9D3", ">: c #5A78A8", ">> c #5978A7", ">, c #0E3064", ">< c #AC430B", ">1 c #919292", ">2 c #939DB5", ">3 c #B6B5B3", ">4 c #713413", ">5 c #3D649C", ">6 c #A5420E", ">7 c #AA4309", ">8 c #3763A0", ">9 c #703412", ">0 c #807E7E", ">q c #5776A5", ">w c #A4420D", ">e c #C5C5C5", ">r c #683514", ">t c #A4A19E", ">y c #3B629A", ">u c #002C6A", ">i c #A3400C", ">p c #A84107", ">a c #1F508F", ">s c #3A6299", ">d c #8E8E8F", ">f c #9C410F", ">g c #1E508E", ">h c #C3C3C3", ">j c #6A85B1", ">k c #736964", ">l c #9B3F0E", ">z c #865538", ">x c #8497BA", ">c c #828A97", ">v c #944011", ">b c #C84E0C", ">n c #C74E0B", ">m c #933E10", ">M c #703E29", ">N c #2C3C5D", ">B c #8A8A8B", ">V c #3A506E", ">C c #BFBFBF", ">Z c #AEADAB", ">A c #6581AC", ">S c #783E1D", ">D c #7C5038", ">F c #BE4B0C", ">G c #BDBDBD", ">H c #82878D", ">J c #403A49", ">K c #777675", ">L c #BE490C", ">P c #94A4C3", ">I c #BD490B", ">U c #643D27", ">Y c #868687", ">T c #BBBBBB", ">R c #476B9F", ">E c #87390E", ">W c #2B5994", ">Q c #B5480D", ">! c #7E4D30", ">~ c #91A2C0", ">^ c #B4480C", ">/ c #B5460D", ">( c #803811", ">) c #0F4589", ">_ c #B9B9B9", ">` c #2A5793", ">' c #295792", ">] c #8E939C", ">[ c #B3460B", ">{ c #783913", ">} c #7C4B2E", ">| c #AC470E", ", c #0E4388", ",. c #8E919C", ",X c #07448B", ",o c #748CB4", ",O c #B7B7B7", ",+ c #773712", ",@ c #ECECEB", ",# c #AB450D", ",$ c #B14409", ",% c #7A492C", ",& c #6F3814", ",* c #AB430D", ",= c #763511", ",- c #79492B", ",; c #728AB2", ",: c #B7C2D8", ",> c #7F4827", ",, c #B5B5B5", ",< c #15529C", ",1 c #718AB1", ",2 c #A8430A", ",3 c #BBA190", ",4 c #B3B3B3", ",5 c #8E8E92", ",6 c #6D6C6B", ",7 c #764728", ",8 c #A1420D", ",9 c #6D3212", ",0 c #EEE7E3", ",q c #5C6978", ",w c None", /* pixels */ ",w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w@Z$9>C#' .*EX(X(*M+{@6;Q@p:S:p:<@B:R.2,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w#.#m> #T.0X#&~X =&-Q+f-{:c:<+L;Z@6;e#A$+$k . 2 j A%r%r Y `%H%H `. %Y%H `%H%H%H%H%H p-2&L,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w,w-Qo'%Y%d%k%k%r% $A$<>#:D:v:1;P+C,w+C@@@8:q:D#i>e>C>_$M & q%+%7%r%d Y Q%M%H%H. . . . . %--X.R,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w.R@6-Q%H$<$k$k>_#':`@~@j;^+~,w,w,w,w,w+P@y:v#:>##'>G,O$A$/% j A J Y%k%M `%H%H. . . . . %--X&s,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w$MX1;<:&.F$9$A$A,,$+#m:L@I@y;P;u,w,w,w,w;c@y:v#:#l>e>C>_$M & q:3*F;4*L;sX8XwXdO'>tXuol. . j-X&L,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,wo,#W&$%tX >T$A$A,,$+>#@_:q;^;u,w,w,w,w,w,w,@XZ*B=nOr%`&1.J#3:|.*Y+ $},q+I@0. %7or*',w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w+O#r#*=oOA>T$A,4$y.g%|=(oI=4oF:-:#:4 }:bOu#V*[.b$1*U#Row#oXY>$#S.e#j-b;A.PoJ>O*/%m%^:P@;. J*foi+C,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w=c@P@N 0&s>G,4XAO-$6;;$Z+HXK:w>],.:m>c& *X*3O7X^=h-jo>#`;~.{=GO{ D@,.;$l*`.ZXP h b*(>H ;. JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w$M@+ $++*#$U$koo,5- &O-($|obX@.8>2+|.z+@@3:[X5o0.Y+u:a>j <%WX:o6&uX/ C#E *%K&K%6;nop t*6. JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,wX|+Bo'=v%M$9o-;5:^##X0osOB;k%v$5o@.n+8o!&3*9=y-gX9%z;X@d#B;G=,>R v#J$Y 'Ox n&:;F.3#f-U. JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w=/>K>0OM.F>Go-;>OG*.%#.f$I=9>+;x@[&b*C&;XxocON,1o9.Q f&+Xp%N&c*A@E*%%S-9;e.j#(%x:BOVXl. JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w$k&r@po* R:U&k>G;s k+^$!.wXsoj#dX7:Z$%X_@T>x: #t,; I&d*x=C*+=;-1*m=UXiodOs$a=L-HXN#;>uo#Xb. JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w@~@p;};}&W#%=f.F>G+F=S# :XO}@4:}X2oq&g;1o`#^;_#tX**}.H;$:8>q@OOq+a%9O] :-,;3%6>aXc@rOl:@;Bo^=6 JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w-Q+;+;XWon,6O;>G*L:h-:-h$^%U&^+].I;*@C&6*e=uX$+T-o+3%@#Z$P%A>R v.k$Eoz-p:i#L-I 8%!+m#n>V+<@$ JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w*zOOo'-{$*XE=c,,;r:z$i,:oM&Y+!:H>P@lO+Xm@e&I$n E.Q%O>>Xp%N$2X}=!*-=7-0*D&:-L;`oC+m@V=T@)>B== JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w%Y*M*z-N#,@{-.%r;=&*+S*|#dX7%j./+jO+>x:..*,; I$.+t:y*+@*Ot*mo{*$od:'+bo|Xa*0#5+h@V@V=T@)>B== JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w$A&~&ko8On;C.v.%+,@^@X#X$h%gO9;1:s-K 7:{OD L.H*j=N&|otOq+d@G-G;W#7>`.yXy@#ov-u=F@V@V=T@)>B== JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w:f&V. %k.B,w&@X,-P@}#6;+= .I*c:u.m@1=u&Q$VO<*g=zOE$H:I+w@x#J$Y ]>W@A.c$R=3#uo.@V@V@V=T@)>B== JXLor,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w.v$A+4 J*t=~>Y-F%c=B@f={+8:9&,$Q#1&I;z%h>A=g>:;D ^&cX}&- + '&BoX&:-Lof:_;q@V@V@V@V=T@)>B==%rXR=O,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w 2>h#.$f;a=)&k-C@>%s>&$%+jO+>xoc-t,; I.L*lo/-S=*&l*m=J-G;(:/$a@U#( -#5$r@V@V@V@V@V=T@)>B==%-=/*i,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w p>h:D Q> . &@&[-`=qO)+io`-K 7:{,o*}.H;$oT&|;KOq$w%5>y@%:W>`=L>a*4:o&J@V@V@V@V@V@V=T@)>B==%-=/&~,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,4$+:L.s&N.U;{*5>1$->~@b.m$_oS&Qo2-o+6@h-n@.#&$7@m#JXz=0$0:i&4-I@w#uo.@V@V@V@V@V@V=T@)>B==%-O:.R,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w>T &#}.F;p*y-q J;o*d=:#c-Tom#h* E.Q%Oo)$F=;-1;0=E*%=2Os+M&:XgXGoD, @V@V@V@V@V@V@V=T@)>B==%-O:.R,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w$`%r$U&'$`@K#]&k>3&a+x$c@e#a,; I$o+t&X#P;T.~+d@G>s@:.+>'@U>gXN%P>)=F@V@V@V@V@V@V@V=T@)>B==%-O:&s,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w#'.s YXR%7%V; *o-i@`-V:V#t,o*}#[XQ:8O( @-=;,%5>y@%%K$u:g>aXc@rXX@V@V@V@V@V@V@V@V@V=T@)>B== j#9X',w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w*1&s=& Q.$*f*o.'$J U#_&Q;b-o*g.1-n@.:I+w@m.kXz ]&Z n#L** 8.=*S@V@V@V@V@V@V@V@V,X%1 %;Y:C=eXo:j,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w*zXjo'=d=P*iX,&p%Z#Y=X$v E$$@dOI$F ^&c%=>5*% )Of;eO.-L /XUoR+n=M=M#x%*%*.,>.&GOX>,ou$XO_OC%:oGX!XC XX%XOXH B@|,w,w,w", ",w,w,w,w,w,w+Wo,&C=Y&wO/#|&7>Z%[$&:kO5+t.q+U#) 5$]=x>8&9 (&M%',<#!XUOT&{&2;U&t>N>J@u&AOm+s+c+. N>D$>$@@i#@=%;]=1%o#2&R+*&v,w,w,w", ",w,w,w,w,w,w:T=v-Q>d-].Ao$.x*, F:==k.M;/=joyoE-m+KX4+):(OKOW.V$#:O:>%2&(+G=W.7%}oY.|;7Op#+*)@H+},2o4%p;h+Z M M M M*J&%;. m,w,w,w", ",w,w,w,w,w,w*G&x*v=r-v$D>k-A%nOz*u |X3 ~-*#z;M%f>U+e>M:~ d*b:0#g$::$.K P&8=`>7,2-c%,@z>^;O%/$g>^-!@7@7oaoa=<=<=<=<@2XI-O+#,w,w,w", ",w,w,w*> 4*O%u*k;j;H@'O,@=.C-6;ROP>(=Z&`=V%)$4XB*!O[>p,$:t:t>-;6:*%E$=+$XVXVoaoa=< _ _#= =-7.9oU#=>F>F>F>F>F>F>F>F&j.#-%>z,w,w,w", ",w,w,w.[-<$[>($poV#k-k%X#<&f-|$TO@><#N;8%E%EOy.S=A#H&S$~ _ _ _#=-$-$.E>F>F>F>F>F>F>F>F>F _#q#D>@ _>F>F>F>F>F>F>F>F&j=s.G&i,w,w,w", ",w,w,w*T:G%0o=%&OhOh:Y#{-!XV$($(;) _ _#=-$-$.EO8o~&0:5#=>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F#= >>ro+ _>F>F>F>F>F>F>F>F&j${@/O4,w,w,w", ",w,w,woP&q-$;!#=-$-$&j>F>F>F>F>F>F>F>F>F>F>F>FO8 z ooU#=>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F#=#U*Q M _>F>F>F>F>F>F>F>F&j${:M--,w,w,w", ",w,w,w#4$):%&j>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F&j e#/.6#=>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F#=>i$b%i$=&j>F>F>F>F>F>F>F>F+1o]-4=^,w,w", ",w,w,w.5@-:%&j>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F&j*hO&&&>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F-$*Z&o=[ r#=-$-$-$-$-$#=#=#=oa=t&D:A,w,w", ",w,w,w+>.o.#&j>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F&j+%#D#~${&j>F>F>F&j&j&j&j&j&j&j-$-$-$#=#=&jXV;9>m&F#w&S&S&S&S+p%_oUoUX`*J#s+Q,w,w", ",w,w,w:K#8.#&j>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>FO8*&.a-J${O8O8O8O8&jXIXI${.#.##e+p+p+p@g@gOF$C.r-y&y#>;%$,$,->-y%8$g$g+N a#M,3,w,w", ",w,w,wXn:!.#&j>F>F>F>F&j&j&j&j&j&j&j&j&j&jXIXIXI=#>9=5:5Oa>Q*n;:&/o7O$$L {:E$,+A$g$g+/*@>r#K&=&]o;,&@So&;yOH>%%%+zo OLX]>*#v,w,w", ",w,w,w$KOb.}O8>F>F;O;OXI${${${:%oZoZ#w#w&S*_+R=_$e;g.a#b:7;d%y.h@R@Ro;;gOR=R#D.aOQ>4o[=DX+.: ,$W@&&&-x+DOh;! _ _;!oB.D%(,w,w,w,w", ",w,w,w$GOj gXI w+l:l>6.N-)+:.)*N@kX&-D.h=Q%wo;;g.a=Ro&@Y:x&_@v#yOe.!@]$d#G.>$8oW#p#=#=#=#=#=-$-$-$&j&j&j&j>F>F>F-$Oh$O m,w,w,w,w", ",w,w,woA=i;y$zo;o;o;o;o;$mOQ-MO^o5o5o5@WX6$;*:@J@JOUXI&j>F>F>F>F>F>F>F-$+p+q%R$(>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F-$.#;[+V,w,w,w,w", ",w,w,w O=-o_@s%e@W@! H,+&H.)#O='o:%;${>fOJ-$+1>F>F>F>F>F>F>F>F>F>F>F>F-$Oc+9X{XV>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F&j${#~*H,w,w,w,w", ",w,w,w,w*7..*s@/#GX`.@%T:%${${XI;O>F${#~&).&>F>F>F>F>F>F>F>F>F>F>F>F>F&j r=[ xXV>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F&j${#~;f,w,w,w,w", ",w,w,w,w 6Ov%$;O;O>F&j&j&j&j>F>F>F>F$=,*;gX->F>F>F>F>F>F>F>F>F>F>F>F>F&j r=[@n [>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F&jXI+';S>;,w,w,w", ",w,w,w,w+--W>Q-$>F>F>F>F>F>F>F>F>F>FO8:5o;X->F>F>F>F>F>F>F>F>F>F>F>F>F&j;O='&) l&j>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>FO8%_=+O#,w,w,w", ",w,w,w,w%3-Y>Q-$>F>F>F>F>F>F>F>F>F>F-$ g@Ro7>F>F>F>F>F>F>F>F>F>F>F>F>F>F#=@D$z:6&j>F>F>F>F>F>F>F>F>F.E-$-$#= _ _ _>n#e=$%D,w,w,w", ",w,w,w,woNO4 g-$>F>F>F>F>F>F>F>F>F>F-$+p%4;I>F>F>F>F>F>F>F>F>F>F>F>F>F>Foa>|%w$j%B#=oaoaoaXVXV-!#{O>Oy&P>/%]>w-Z@/*qO6.WoK,w,w,w", ",w,w,w,w:,%l@g#=>F>F>F>F>F>F>F>F>F>F-$>Q:7;I>F>F-$-$-$%Boaoa$(XVXV#{.SXF.`-B#D+o-w:6O!O!*_=[=|og.X$3::>{+vo(&]O Xq#/,9O2-~,w,w,w", ",w,w,w,w.l=+.6O8>F>F>F>F>F>F>F>F&j-$oaoB@k@9#{#{-wX.-w;i=K.i>foe=|-@;|=w;-;t;V>=>{oOOQ+J*R&>&}XqOoOH*N i&z&e+Yo1;v%a%G,-,w,w,w,w", ",w,w,w,w>;;S$C;O-$-$%Boa$(XV-!+&>L$q l$C zX<$'$' s-5;- VO o[+_+_=.=.o}%q>%-3>EOwXr$S>f K*] !.uX[Xe@z*V>X:;.^XV;!$~#=:M;f,w,w,w,w", ",w,w,w,w,w*~:M 1;OoHoW:d*_Xf>v-@:+ s.4,=*R$N-5-5+y#F&T=5 W;J #>l.N,8*W S-coL>[%~-!XVXV;!$~&j@k%.-8XM#=-$-$.E>F>F&jXI+(*{&m,w,w,w", ",w,w,w,w,w$s%L T-}.]:7oQ@c:e=b=l#0&h*< W-J#IoHoH-aOJ@o>IXVXV$~$~$~;!oaoa%B-$#=#=>F>F>F>F>F+$%%OS%_ _>F>F>F>F>F>F>F&jOF=+@(,w,w,w", ",w,w,w,w,w&5-'Og@F@t@5 WO=.dOF;6:* [#{-!XV;!-$-$-R=A-JXI&j>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F$~@k=I-z _>F>F>F>F>F>F>F#=:2%l:A,w,w,w", ",w,w,w,w,w:J*I#Q.O+0O>XV;!;!%B-$-$.E>F>F>F>F>F>F=<:r*a.#.E>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F;!$e$B+Z _>F>F>F>F>F>F>F-$@g$ &U,w,w,w", ",w,w,w,w,w,w,wOY i%$#=>F>F>F>F>F>F>F>F>F>F>F>F>F _ z$,>Q-$>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F>F;!X~+`=H*8-$#= _ _ _ _=<$~Oh>S+E,w,w,w", ",w,w,w,w,w,w,w&!ok%$#=>F>F>F>F>F>F>F>F>F>F>F>F>F _+9Oe>Q-$>F>F>F>F>F>F>F>F&j&j.E-$-$-$#=#=>b:EO`@Q:];6=mX=-zX=@D.t=H:n.T+-,w,w,w", ",w,w,w,w,w,w,w u@q%_#=>F>F>F>F>F>F>F>F>F>F>F>F>F _.(%Q+p#=&j-$-$-$-$#=#=&j:%${=s&S&S+p:5:5X`@a@R+gXJ-^ y=}-d,> Z+5*=-E=a:F,w,w,w", ",w,w,w,w,w,w,w%F&j&j&j&j&j&j-$-$-$-$-$&j>F#$%{,#oB-8>Q g g@g>@>o M@oXf-+X~*r#-=>.p:N$x;@-&XhX>O|Xn*p-l-/#C;m,0,w,w,w,w,w", ",w,w,w,w,w,w,w$tX),#=<$=XIXI${oZ=s.#.}.}.}*n*nOF G&nX;@5 3%G:)-[+[Xv=@&#@L@M%J%J*^O0%F&.O1=]*2*w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w,w+7>}o< 9OF;No3-J;'%bXJXT*;;E=8=+@ ,7,%&E*P>!Ok;&O%oN%I-/-_OZXk,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w,w", ",w,w,w,w,w,w,w-so%@ROjOj-;O4Oi-rXtXD+==p c&ЋЌА’dЩФѕэ„/ЃбCmždЕfR?‹њгРXѕ'R$јИИў‡ LуZфМЯФ X›ПЊІbwЭNxээ№‡U&*жŸ}уЋм…ТС%KеРБЃвySVf‰бэўо–ѓДтЛRйщ‚qј0ЫНšZŠ&Ib7Еe\ѓжSцNТКќѕE _ќ^ŽћZнH/”аqЦХn-oЏђбж7(жОВ)”:ЩЖЯ‘m6 дв‚ДХАŽЫAл7Ч ієŒ•˜`<Ь(Юsž™…ecC‘%ќе{ ѕО‹P(НљкZЁТ4Ь5@^лЌЋЃНўЂуLžЎиЊЎВиГG##ъэB№v3ФT'КЊЮP\Т-wЌчБyХžyЉЅsK='.м2гэС­'ЂЬ‰„%rЦЃІ*5ќXя/j’ŸuHк…Ї#УшЩEфвЎCSупП5F0Nчm6œšз!ЅцiЇNМ{\?{ИфГ•[<љ[бО Х‚NdJЗ дщ;™Л^8ѕб|–n“ј‡NØaцS#ˆе]†аэƒчHQ0н hННа€LI6?Њы›Ё:ˆ&Œы$<й&e "А‰ Ѓ-к$:Zg+ЂMd˜A ЃЦс‹ P9Bt?t"Ž[’Сђ(ЩэX VžШх‚œ,РОЯEчdœ!Mд …iMхaђ @ѓDаIDšBSуjБ6AБ№GHКYK":d3OЈы!’VrџЅ~ЁЂ#Т FE 4іЋь>э)'‚­4ї&q_г zь'џ aЪщDЩ bьIO0HsпЫSš_&ї›ЩШ[7ЌЂ5ЬЃPЕSлФвкNЇ-ЌЄmћ_^]I$ч ›\5’2} Ђ?і*}UпKШG|Р• ЛzтЛпБ'ˆn„§С8/іЉЬзmzтлc6Піuцкэв™бВsйЇ…д‘`твЁ$GюП=t‚вfm>фuО>Б@{69D"EžэЂх†І’5лšf!7вx†ЗvFЇ~.m~ чџѕг]O_;1з7˜@)і=ˆщYWЛŠ?иwg_ЭЏzZи9ЊЌ""ŠІо~@Т”Э™.EзЦуж–ПрЦє 8% ў7н"’чЌц!{т bwZщscqЄгНž"ЙMapШTЄ45ЪёљQ?ъышЁŽїМЯ1bЧ=бIмы’yQu5p _љX˜-!#E@$Єag™]wщчE ­Ј"cƒЁЏLЗ AЄ дЏѓrьЉŒ М:”атš%VШЇ.™ƒ$К'ƒЁЏh њQш)бA Ѓё•ЛіТnQKЅ mћ=БRaЪTS’,PЁі‘†o8rьЦH%,YCЯ‰н*vЪ0сZ7Ї‹r-йЊї‚‰=Ц‚ёзжУf•~:SцY=uMWУPеЅзХфЧ­ЩO:&ђ? vє€ЩRЉy$aю^|з;TO|GЏ/))J kпџK–`Všщiшеќс|eђИЋœдЇбкџRзРПOr2'Ђ2А'‚—ЭEЙWѕмА>1ќ-РUлЅ І —IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/back_16.png0000644000175000017500000000074111733011756022031 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ƒIDATxкЄSНJУ`=7iњƒ‘QщR]эрЄ8‰Žn}_ s_@_@\ХG(ИЙщ*J)UЌ§I›цѓцћRhЅBЈ_2мм›sюЙ'7$„РŽіWС.еХТIСs "А•o'І=ˆРާЃ’…кSo +9A.Л8?ЖЁы„яоУ€kгУМAКƒзw!R№цvg‡+Ш.щHЇŽcРL“$›œЈY&w=Ÿ3LWїфВ&jЎ|FƒЭ$Ы99“`RК2+фЮ_Н^k„зї‘$• ‚Ќkmu910:c‘жЌ Ž )‚СH ы‡№‡’RyЉX;Щ(™rTСq‘c~OЊ"тљ)C}Ѕ P^ІњЭЇ(”-Y ЬzћЇrq@ђЉЏьп$Е{е[ЮDмЫfВЯxpФђ /UOьV6№\ѕАSY'ЅHФU_тйЧЕS}v‘~ЏrћБ@ § I€sWy‘ѓ#Р№gЋ]нb9IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cluster_64.png0000644000175000017500000001313411733011756022615 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<ўIDATxкм[kŒ$зU>їVU?цН3;ћВwз^{уїьФФфХ#!R ˆ ‚?(BљУТ@ J‚”РOŠDD„‰Ф $ђ# В!Ž[&ЦNМ^ПжоxзЛГЯyьЬєtOзуђ}їбUегkяFm”][еееUїœ{ЮwОsЮи#яЦіЇЗЋ/i‘?ˆЕL4"‘V$yVШЦv!'"-Џф…lсеiQШВRђђЅTž}pU–ОЋХœ(ФрZёp[ВЯўДр6|Р0 <ЗvФžWЮy=ЗчЊr^П'œчў~5n@№)ўR‰ќ>„Žnžy`—ШЛxћї—•єrОмP2щуф\Oњ8.oGВж1q!ШpЊп—Їг љцgЊЗо сyяXсяУсkи˜ŠEю™љј>‘D•ї№Х|ЅЉ_кPВ’RFЖ3‘›"›-Ќ„З|Їў™ЃЊЗ№<ЧlљЂ№<љдЩ;ŸЏ)ИђТ+7˜;ЇЭ@1ЫЉ’‹л"кF:™Ј3[2—dуŸљp>VРпПЮПќКФБ3ˆjCj ЇжИ <8 сn…ЃЬ$Ѕ ЧuŒєё‹"{šFо­фЙ5c–КВЬч§ЭыяdЉзfЩйU1fЬЗЂхѕД˜ФXŠD‹‚ +šђfЦссПТЭЦЋы"]‰ј#я эNošљ„‡Оьgх­e\[>„#cU@ф…ˆЕ2ѓ-Э ˜{Žr*ž\xЉ \Cd@(йЪŒCXŒК№ј`џIdl*vЅ1c€ВЖГ г8Ѕ4 ќькл '%№Ьfa1"И…qЎaЬ,ю\†q!–wyг3—|F,hcqC|ˆ‹Ъ ySн‚ыЫlЩK‘‘™HЖqнLчВебВі“* З\€BЉЪЎУ,zE„kџЎРW№ѓ0АW7DNnŠj(Й љGПТ(‰[вMp<ч{…ЖЧ”ЋШ‰џ\–7яŸБђ]†"ШXАбЯсуЦвИ^jŠfЌ,+р1ђЪ‰J0і\+3А€зС^Z72л Ю*ZЩ$;I‹ bЖrs,сcVox]"Эdщ}srŸЏk6)/ЧЙ<ЉšrЮW"НdMV_^Щ{]оsчЎШŒUдXЁxztO‰ђ‚I e‹”˜цЎ•K~ЦзvШџG‘‡vkYHŒНт<ЩеЎ†;‡.t˜ЩNaт\2ЗІŒЎИ‡яТѕJш`ЛНТyO–ћSђƒ4—WUC2FнckљЦЊ€“БЅИinŠЃЬ ЇњјаM]4АРЁ С)Аё~’™RvjWSяЇИ‡ќ!їnBQ\9ЛK<Bl‰ьkkћЌТ)hю1Б–2щEH}&ЩјЯ|щkcƒ1†…YŽДvq^yПЫr5РЦˆ]AаСЈтШХJКЦ&ЏР рџіyМжЮ7œяFэШНѓ5pŠУ U{кЪFšс8OeM'ƒdJэj(5г7Вд5ВЗЅŽФc‚exу НŸƒJ3qLp›œQ%]HxtZ Ж•2:TЄвКPЮЎ­УVћІšДš†vŸЉ,Оƒ˜1—€yыЊ&Qм6ём#3š“_^Р~Ъг\уNђcПѓy/Ц~FЇqљя”чю;ђŸ~rЪ еЌ ldt!БжДч^оv~agо0WV!с}ФŸm|Йр!ŽœЦ Ќ XB\ {ЮЬЋŠQхUУ!ЃBьн(0 78„ДzŠzfйШБ5#ї#еFвe]‡~M­є]ъMМйТё ?ЬJмН+˜фi‡ЋЮur+,ˆM>)YUЦћ1gЙЁтEў$ИFˆк+,С˜гM‚ЏЯРЕXs4од#=6i19•їТч7КjyŽ=ючŽwW+ГI3m'­пRРIh$ѓхлЃйaE–3x+ В‘ƒ 1ŽR‡ч„w4™[Фхu*юDзу“SŒU7ЯФжЧСW‹Ќ0VGi‘лc”kЦUcфр)Ф k…ьJˆQY,,HfЮjЂ ˜ВИв‡Ž=qRЂЉК+к-ОњД]”ТѓнotŠ№еUђуŽТЫБЕG)РВr ilЊ+Љt>w.7Ђ”ф4˜Ћ(&У Œ‘№QєЯзЎВ!+іƒЫ<z БќdЇŠБ0:ЄRцЁŒнM–SјŽe5 ;ЙYЮ<№ @и*Ч ЮЕЗ‚ ќE€D/3™њ“лvLфЏуЅЯwу1|Ж‡s [NaІіxІх$тTŸ Ъ2Щ@9SМЅ{Ы|ќ,^t0ђшљ—ЦЗ ф~~%—Дьo+7Ду|›ТЅWZkȘy`ыaпЮ}š,юY6Цї7ДA~š$@JіЗlёеО—ŠšˆŒ:X яџЦйТ™†i]кЪ—‡-рБџ-ЭЭЕ-I+–iаќ&?гWђiвLМХК`V‘ЧВ S?Ож/&9#ЄЂжФНц œD>ЖŠMoОЮЯ•žpщ3Џa–d Тžл2ђТW/˜‰\‘…Ъ U‡_ЇЋf}ЮСZЁ”Й„ютЌg_л=џ"ТСnh‡ŠU0‘ €Yь_ЧўЫZЙ—,4мўШ2Ьч‚Š „Ш™› iыт№nЄђяйJ Eд D&˜$уё 4šDЎ^ }˜+†јBЕКХ.ќoїДмLОжw3§ўgЮ™MРФ%b -х,чBG‘гўhђœLКЪnќ>-J™b_Фќ6іХрЧЁ­п<ИsЖ~iЏЉUп*•]ѕшEeЫ_Yсиуя&зcжAФx:Œ9@с•1РџўjьчгS_52žохy_B”ЧXi1‰vїfхBрХžУ™-‘cыю}YеБ?JЋ >чЕ!~•ДpћљE’AЙћŸЮ(Yн6ФHLVЛЬ сЉОQЬ—шЈvT‚W[СJ"W<БЕSхR -RЦ|]ž;…%ЊЌ/R9ћлNГ‹ўХu–Смld„ч ОrвЪ-SЎ@ЩkІТдЊЁGUaъ!А$@Ц"ї#”ќ2ѕхmГ СІпм4ъЭMћE šХЈ›‘ ЦЃНjКY64[DW5еpŸЉ4 3bТXЬ€„ТЇђх6{нЛ”ЄЈ—“XAЮїѓ0›^й9ыд,2^Й}Š)ЋУЉФ\ёФц?.)›ФP˜юuЬ ŠdЅј[Y.Я‘Бтж мњkЉм їPЙхfŽ3hЩБ–AВ|Юн.f2ум‡fп‚Ѓ!т$R‰UhС3rEг[k/оиОLЉE˜…"wy|TЈ6OпюУЏŸ^qћ№жє ЌгНт}toiБЬ™(“ПЫЙтџ5šДvў|?> ‚MѕAzрzуХ>\†ХNѓО—7$zЕc„š"VАёПйгТо!:Е\S T^ЋИхElЄЙљчX{•AыХt#Š0ЫŽc)oо мX.Э=З1АLLfя™–Е$ьœ”&WЏчv*чOqзЅтр5“іqJ~ ЧŸѕљгnDˆ‡/єЬТ[[s1цсZypTѓ‰кW0ПХЁ бGœВ^nŽіЖђlѕЏЙќбРБsѕ 2дѕСlY›Ъ!эЭL™юLЈшєZЗЅЪљьпЊЄнG`Q“Id‡ѓ~Мч‰мфНцЯ-їeъј†ЗЄIГЂœkMAp:ю7ШyіэŠГјZђ{SЩщCОэ2€IIя)щ~ѕП$ћь?q„Бeѓ /йŸяЯюTЯБж І9C ТјиН~’ќЉЪjБ]™RИЗ~ЧљˆZўБ ЎгKгMŒ|QEђ./lГ„ѕR-+%ЧlЩ“|œp=%а#Ч@ОкmВЩьzEl†Š=іГиџuТ CЛjУТЫU…75V,р‰Ыb“F†Mе$nО-‰ёCйtсёЪЛ8j-цлUqЅEМђЛƒцвЕ•ё*Z5рнE qЁ)mОБGхDRViuЅ(a•`! П‚мž№‰§J^йpi+…gЖvзLе2\,?ОрL]ІVTЂРеАђШЅ5ŒЪ$A9Fа€ xхѓАж'ŠH.јР”C+ƒчfY=П.Ц2яІШBћ_>aЖG–ё*ІЎ"Ђ.8e@ю0ЛЖ~)›Ÿ'Дэ\…•м@=У"Фу—ŒM[ї~š/йbUx {лДЊЙKЅmН*yђRw=Ш1цc2&№ѕюЁ}2cсˆюWКŒБПИЖ-o$-›YЇˆћЋ M9†G|gЄ|хСЬЪАœ•БЄХJNСВœї †ЧСЊ‹JЫк–œ|cЃхS`*рR2RNZЬџ—ЃОЎ”zЯЮZЧ‹(Ц–ЗЩošв;~УЩZBОLKK]с‡Ўe нŠ˜Џeh ПЕхмu‚шNеѕTLhЌ6цлU|в­№Y Г“‹ЧЃH 7%*ТЋЁ™Љ‡Ф*0ЁбQ Ÿ!ВАоh-Чu‘њЪS—Yї3‚ЌЮ;)ШЖЗчдW™Ј0жЙV€UпрNЁТ›ч–.zсhW–T;PЁГЊ’:FЊЮ-VнЙТCKнr†ЩQ$ІІ0]Qжps#UхвІКwЯйzР УгѕХ тKюпMфП ƒО€8Й +кєЅђЊ№•dL WБЌо\ЯB;+˜)ЖД @›њ)_Мl(тBЁBW[[еœс:„зWщіpg Џятр™mŸtщVЉшм—гХW“cэ\щп.з…7ЁPdvЎИ‹ƒ?МтUŽ7–zюоЉШ–Нe=sГMVШvзyЭП0ƒDŒТ.#p5XЫ)(€2 ЬZљХт! бЎІЌJ}›U-ft-ЃЬАЮЮ†ЩSшкьP9тГЋщ>vХ%<Œљќ‹’ЩЈ—ЪБzоЏВФЩЛ[]ЇЗFQЉlЦв•иƒ`˜Œ=гЄ№ІXфmы…ЗŸЄRјPC1КЮќLmѕ†Б@J)ХF’qэfЙ№kц’—2Бйю˜vюФЫpЫfчYЄv<І>T“ .їн~Іы€•с8tГЎЅ~ПИšлAN$*bkјЂіёоа<яU+еŒЊ~cj“wОД"Г#юч•Nrhњ)]Z\ъу§ m#7M–k‰Rќˆ Ijœљп§pMфйеr с5-ьђ+UŠдФWњF…YHиЗKФ0kcД}ПМЭЕаŒВTR ;І’:$?eџЮ?hvBt­зWW&Y-Цфѕg2Мr@ ќS›|хzў~ФЙР‡Бџ~џ^жеБГХойЭTfкB.gГ8УU†k ,ТьђнрЪ‹-Ѕw%Ђ|ъlЗ№СZNрзќњ:”Р0e™v=Б˜Mv{sQЌCž3хќ’–ЮдаЪQТЋЋќ]аачюѕ*`дvЪяеэqыХМ—‹Ќ  лБыФ]ПуЙ7жГAЩЭњ<…XI%њњ)ЛЂЌигTХс б{[Fћ–ЗA^aі4DO6Њк(џgд–V4p/†kМ9ŒкЖ†>ПрїъvzTйП{u*„–#ЎNЫ  –K]ŸъxфЗЎ$ ёнаzЌЛ*IŠЃSЂo˜А9•uЛАє>Qѕ№wкiќИ.фуoзљŸоо}ЖНч Тт\iЦїїіSqPЪlQ1џиSпЛ(Л& ПЪ]жќ‹гчжjыŽи{IайџM И–эАЗ†яыСўIьV”g„УкнЪуHwП Œk\>сНSkьџТ–xwщњ|ˆЫњ~ЯcNГЅи§U™SР/@јП–орџ—эnьЛс6Зb_ƒ№пМ–§ЗŒ—…KpїBNIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/object-group_64.png0000644000175000017500000001263111733011756023535 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<;IDATxкф[yŒ]чUџ}wПї-ГzЦ[gпkBSŠ“V‚ІTB  $DY$PEЄаJˆ?‚„ЈЊЊt“ jЋ–Š BA„"EЄm'…–Ж‰S7vbЧуёŒg{ћЛяЎќЮwп›yo<O2Nдgzы§ю9ПsЮя,їŽЪѓ?ЮuЕ˜>ђЬы=дчъ.?{пЎЮoэVcПfl+рхwxњЕžђK\яяПўcЎяF~у 0Њ(nесzј эљ.Ў“§}п?єљ_бƒRЎчЙоuUB яrђЯrнИХO2ЎЙтzrѓ—ЬmыŸчњM.oшГІ­ rgЩцпG\прњ†ЦЫo8T~K=Kіz).) зЫ‡ЫЖт ъ/rн,ђmHЊ"#Ј:†_С6ы4‘u[q6эгтz”@<8ДOОkЈє– бlU93хЈЪhћ ­ K­<Ъr\, 2=ќЩяЫ>3ї?ћ™,Ы‹Џƒ‘ѕ\?KK…RУцєМ,эƒ1$ЂHЅЫдЯгїщб\< zјИ–вž0XфYо[І/Нcš@фЎ ЫшŸђ™ˆЉ0кНˆЏЛyД№Эђ,ŸсЅgюSле4ќІDХoКчўк%|ДšЭoёйф{Уъ[Иo&b т@iУ,РP[gнЄоСъS'рL—0yч^8eBižo ъ+”yУюƒЁњР\2ЃЦ1O2)tЉЌ(ну lЮЎaхј…vкKԘ7SсŽ Ёv­‹c_ћ!ЪгИы:x%z“ЭCнВј-_ †НIЩ!ђMiŽ4ЄЖнѕИѕЏПсљeЄтГhЙ…oœТŠ•ЂzчdїЬ"MХщ Ž‚я*”œ йZ№*LЅ;мКЩч:A8wЖЙя. ГиpРР“sCаSљ "Зп:ss 4ZБоЈЕмФ‰Џ?OƒšёЬ]зйГ‡я- ХmžУ! С0тМТ iJЗЉ]T5њБJЅЊj’8CoЙU_BœYˆ+Чє*Ќта;`vŸIJ1С}+мкTEšmpћZHš_qђш {Ÿ•+Кэ[юй ФД\ai‘жYщѕZюH8Ићя+М™€ЌэrYЅТэS*7Љ|бвОѕmдNЭeяž{ЪАМ“oНŽAWэфN'АЂйЗнщЬќєO^@nШКM\xіПАєНуqЧіFЩ „‰сИ<‡•бQXаdJ3<йжє Љ$WiГСМоаEtЮ==‡sGчroкW9­и[ вкЏ5*ЈB‘0 *LррК‚’TОW;h†t˜ АВТ•5Уg$&р†§†PВКP‹БиШt‘“Х‰sў™c8џьБм›Ї€)zЕцˆ€Тиcž ЏЬdœгЉ‘uѓК+UAХЩ{Ј#OzB'*\щБreyJyTкВu…ЁЎ^’EШ­яГ^Ё“­'ЎЫs€ЊЉЂцflфљт13ncІ’:!w>WЫбŠђBРхкˆ€UІѕ}ЅžcЌW-"ˆMЫИJмаьвдVe‰ыаšгёЊМз(D &ЈЏњХгEЪ›\A@рT#зЉrGшRТ&Г+Л`№Илo>.–а#чн8i›кХIхsћql•J?gлТьVRX+ rlW˜ђ[H/і ђИ”ђђlpЯ7uќ{Ф)ьЉз0amjf™E­lW:g˜­ јЭ˜;Дз@ys#MJ|zЎXž.ъKсBїЩВmSrОщќ—Rо$Итa>k‰2упсk‹шЦhl_иvВX>b<'aПаСЖ Œ€ДYyг"jКЈЃє1~WБ€1Š’йЮzљK(Џ˜% M~ЌJ†Юr.3гeАNС§ “o€Šг7c9>jїy к—Pок@—ЖФ ШЄ] ЩАЖQоr ХХњ>у_ЖtШ5Ž]d `хЏ”Ги“0Ш/'\ВРfх‡`ZаФMсЫРяa щ0ХхAиJyeжv=БО‰Š€<#еdVБefƒiXЖ=вƒk ‚W!AQЭх;sб-•ЗЌДАЬeaъNQЧK6арe@иJyћщњ.ЩЏR6tАЉДЁ‡”L‰ТІк!HтЦ<ЋУ ю5ђАIљ!аТѓ#›•hЅ …m2Шь@М Pџв lЉМ&?a~юWR:§ ЯЄT>в†`єiH]љЅ,Cк1–ЗоX?D;ѓ‚­”З‡C>WНРб–ЉАVКЌ bitRЄИ„ЫЭЖ$zЫКЏКHzm†їЌ.ў9з_АЋЛуу =nвiRЯА ц—noŠЭйžI“ёO1R*WTЅ]Ъ2DMz’_n$&хdсœEOToP.?Г‹‰…‘=>… ЪVSЦllSO­5ё№џžУK-’рЦю{Ъмў2ёД12-Юњм1АФ€•ў8ЭЋ˜ПžЉ0 аžOа|…GТЮcЫ˜uaEїЂЄ>УЄrmЕ‰jЙ О€Dg‰z2Вdl‡мЃaЅ•ЁE^ъO„ђm= 'ГЎ>’=љ4Г ћrЇЇZ…TиААK M|њ[?Р'Оџ"ЮДУЁЈQ˜ИеХфѕ-ц2c]AQ8cЬІ\Т БбУ„ЁЫ<Э8—e№3ЕŸЉђоЅ_№Q_<Уc{ˆœЃ4FЇ(yЩівєиŒѕŒчъхм‘ЧQёОk:hU,ЬзАVб‹Гѕzнкb$ўP‘УbЬэ;(]Г“wп„ъC”Дгo†$Ѕ9xјшї†ЂEaќvSw9pM—oгзя-ЖеbaQzТР ­ДЅ•жУОPфЗI&юл%Ѓ[ЈьkЃэСЉиGF?ЙSїсЮЗеДХ3e˜Ъ"ЅЊЎŒ ЩњЭЅЫ'kX}qЭZ„.ГUЅdоuI8ќXі)Йр™чйУyjНrэГѓX|цћтFLоrІ_о|ѕIІWЇЈџ Фдс3Зf$ЦЂ’єШФcіJv…`јА•Ѓ•V}.xˆxEœEZсnкF;iвZ!-кФђЪ*цОSBcс-_vЫpйќXЙYдJН9аs=ЁЬжгG;nъjo юх@И”ђzШС O”.Л= аd+gеhZ:ІЛWУ–Ж)…IЊс8: sНЫАђ–eъИЏxј6уŸ][!NO0Ќ7УРdБ(nъGОЩЉ\ЮКƒ“‹•уjЯ"˜%цўВ[б< ‚“;фŸчlЎЗЏ.zјЫЖ—D^Ё х^€Nвb‰›ЭЖі„су7+ohі7ЕвUvЃB€RtщёЖ єч–iН98@ЛЋ+є€€mГИk3ЉГФэ­їў[0т)_ŸФ}е#ДИcкњ<%ГD^№†9р*аП LТРЫЏДXЌ кš \ BŽL`F”/мПH}І„•cЙTк%ињZЅі†+P \!xЁЩЉьTt(Hw'Хб ФЕrФ †РахХh9гWsи-УЌ—ЄZіЪїЦh§’V^R­)sJіМтўoš4ЈYм((пbsулt[w­ЄЁ;НИУђw•­r3з§,Ут zизi\i BeЏc_і‘Ађ-_XФЫ"еИџ›‡ ЙЁ-UaЋыvЧЬЗ6#}…]‡I‰›œеў@Љtаа‘…ЈЧ ‘иА%V˜tѕ Џ˜.•ьВюЅТАў@пзbdњ9gЧ—4)`VыЪрЃž" z0™*н!пщ. яЛœ0tliгЦ$&h}/-AЕфЂ,k€В‰мeHБKgWтЏ]v€Rˆ`cmpи…-юM—pIZS“UфS“pѓMЙrGH“ќ"тtбcЫTзУL0}х)L;UјЉ ‡fЮИщДzшЪ]Ѕ$з(ŽЎ>šЭ“Џk [^Ҙ›jж.U}xe‹ЎJЋѕ&tЛˆѓHОŠKbЃ шДGтѓ]WЧ§˜ЯИЗKњя"ь€„gёи4AЇ› оibЙЛŒfи$№vSю ыW”žЧlM_|МŽхC ЎНЇ‡ЊHU…=;c˜MВИt•–”ЪPкф.џхНМ.ЪKПя3ЗK/!љ>U1btаеїѓX#A/hЁх5Б№т жZЋєЈvSю €фŸѓO)tЃ№аќЩKЇл8ёѕорР]e”§2lхщВ(Ів17Z jIeЬh9[jeщ‹БЬђЗYё'1aк&p1jк˜ЉЙч›ЈзZшF]T§ъ]Лѕ€+ђgsтF*ђIrћ{ УА%EйДтьm>інэaќ KЮѕьЏЕљLRL2џBЂИ§ЗYн;„ŠЙ^ž€Ы•;вЛ&–OEДx›tђ8‰}ђNHрŸЄw§aѓ+WЏ:›Рј •zˆ`\+@Ш*MииsЗ…ъ-rWRŒˆМ!sУ>WЄ‚;Дu#ƒ3ЕГ№ЌcД^VhœK5ЧШє—JЫ„ћл”їЃНJОzЅф}Уўp’@шщ1Сx€%ЋЅЏј№_ѕF`тіоОЯџM14ЙуAs@у%*§ ж‹œLTЮГWxьчТЧтьжнЄlуOјєй?HŸЮ˜О‰МЈИХ]ѕNр?=оі]џУѕПo-М‘Вэ!Тз№x зЧИ~f ^os=їШxw} ~ДQьчPм=ўHпЅe§*ŠПFћхзЂќџGиъ!ЗEЏїрнz€њqџѓљџ`;1сг_ДщIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-neg_16.png0000644000175000017500000000071611733011756023642 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<pIDATxкЄR=KУP=ЉЉJЕПЁ‹htqvQФС‚bм:ј DФЁшшЄ[ХЅŠ…иЅ–ЂƒПA\5СˆJ;˜6ЁяхЫМ„Д‰4ы].яёЮyчžs9лЖёŸтцOŽmY–јgž‡хˆчуыБfиŸ?‚вTМІsмŸ ДG ЊЊ†=n†нžй ;БS;šл[-”.Їђ‡0ФgЬЕјЈ2#PY~УЎКJ) гŒNСџЩЏЯЏ(Ъ7ЎŠзŽФ12йТоAh„ ќrКŒЛJэv;DРм‹LaЖђ‚ƒ(‰žЖзMТ?ŸŽж@ h0-Ѕв-ž6‹юЊSXОьБ ’‰ЏЦ“Igi†06’@§НŽчsO№DМщйёр7˜UэўСSdYށMд \l_r[й,V3kЖ$шЅ`ei9rУˆcІЎыž‰Q8=’`2=eГDњІаРЏЕ Зq\iЧIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/install_25.png0000644000175000017500000000256011733011756022600 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкЌVYlTUўюrюЬэLЇC‡ЉЖMA(ћRhhQ#K Aћ11š(T–јQMxqсcDЃуƒ(! " -Si E#‹,ЅTЉPвi™ЮL—™;w9ўчЬДP,KOђЯНs—џћПя_ЮU8чИsЏiТ]‹уоKЙѓOOѓтQвяуЁ­5H}м,#–Є>iFс‹аїе)ћо~ћбnЛ;1q†Hƒƒ gda0В)„ШŒ ќСRцЁЩчŒ˜OЂ№!‚€с!ЬЫvb;ќhЧэWПЛoпчЉšНЋv{ЎmїУm[\ЋњМю9їь]kЏНvUYYkёїќбј;џdVћзь§нrБкс•zŘ —_ЩxQKМя"Е/SћњЊ‡Рє†'ядFд^Єіь= vТcOŸ,ПG–ЁL$яEЭf`­пFЗм?іЕn;ќьЎлž_ФчЋдŠдў{ѕ9@еЉб­жP ХАšœ@В†Ž•qз9С…—bЇЈЛ…†ЏP+S{~u Щd8РŒІЦЧJeн1аПHі Aw„}ЋBчc г"'Q8є.\xЎћŽIДhSW'yї? уGоїяK!тЅЅAUsM1и|Ќ‚Œ†?яЖ-кRгMПuЮG(џ'й.ђMоё№FЖ­ ‡Я‘QџЙj:@Љ*56КцЗJŒзоp сЖ6ьЃЩ}ю‘њegДVŽХ…I_ЗЦо=kёЮ Ї>ONјъъq@o ŽмуbЯ†ЙРИPPDŒаДoлЄЈШpkЌ €‚f‘]Ёщўўr„§я_‹RAуФё1>§,9!GлЯPHФwКJwRSU‡зP'c №hА П‰fЇ ИЖH4ЩПYЂœЕНќЇ5иНgSИєoдО!ŽИ[Ј&=я{ŸсMћ–c>ыzмRdВЄc—RpѕХ“ЗˆЊ5пНѓW(”k}eЁ~o?šDІЇ_ЛLП11’>JHhЌ|-Р 8g8ЈІ8Aˆ‘‘РћQНЭ+№љФПюФЃ[ђшяб wє—5іэщЧЛw4§ Е—Щ ХЛkЎЗmDНЬНnH Ј8IМЏLжsї> &‡,6~nа§ЌmQ д œ ZEцъХМІFЇКщэJє˜2Е~ъэr^Ё‡.ф#z"йžЭH(– tmd]†œаыpтј%ж!ЂЋџCN8DH˜_AXp`гhp(nрTщтП.!ˆ`>ˆцшZЫu s€еЌ&H(ЫО@ƒZœS%рЬ7,fjSѓѓуs7f ІIKTjЌ9˜Щ!ФБ›Ш OОЛЛп3тˆVŠЇŸ’zWœї6oЉЧ9ц žВN9T2RЧ"‘cЯŒ=CЁAo—\?h1мК“йŒZнBS@gh?CЊ3ВŒ ‹оК‡БžB`MI#лЋ‹<ифѕоON0f'O^тlГ—Nџœœp€0ЙbА$n8ЌeƒsŽ-3):ЧPўЗ:'Ё‘uŽBЮь tбŸ._BШ~Ї­k"ІcП@=лG‘=_Б˜э1„О.…BF!ŸU(8"ьzЌŒ…кЮy“e:П&'ьg^&T}ь“сVх|=`ЅЗUЮЕПžs<рпмGСЃ€ &"€їDфрЊш\ЈЃ”l-!Уi'–МnЈВ3* И3…ёiƒоЂB/9aЈOc}„H{NиMNАv.œ{“ОovвS~Ipy™h%aрїsu‹–Ђи;YwЌ]“sLЫ $ыЂо†Р&U6rlыu‚Ѕc* …=~‚8aŠœ6FЧЅœТ@IЁ:Й[‡( Ъ][‡#J%ФК@HˆуŒjOQ]2вЫ-gЈЫ &ч{е†Ќ ЮI9ХпW s6Љ˜9Лž7^"[A„‘Жm)O˜qьГ†Ѕ˜™Ѕp˜cTЗD •ЊХ№ …FO„-У ыBЫ0ЦЧЦЈёVz WDћ—фЮѕЎ'‘NмЋ9ЧьЮ.4и!Y}Ы‡‰KЬ‘ЯсмћhEмыЮЪЖУ Є{Љl1ZAїеšWІ€Ъ‚С ЁУФlн@ЁAШX?aгњ+<зЦСмІвЂ :ЇE Jбї#Mп‹рЕЌ‚BдОчmвЛэІxL!Ќ!с!зM2аяIДйBх1~г•р$;qŒ?В‚ХPІ-wЌEцњдч[ЫaZxУ>DчМтДІмm’”А}bЄh%„Ј’яЖЧќ№d­cЄГœё7ИчЃ5ZїсЫЗLG,‘ў—”ёd‡Ќ$k–Й­і€Љђѕ§R{(?ЛІH†А,Ÿђ:Р)"ыбF јакфиЪЕвЛ6ћ:BKаЦ7Ч.З ’wf§–3^[XЏЊnv@цщХЦ(д=ЁЙоЭ„_іpчL[ Id!Фs }W~‹8{пБфё€ЪщQrW{‘ q€i6аMŒхžЯn|ЧyЎїъжњe!РZ“pAВхТ(д {щ}Їdb%_љјЇŠЭg—hџтЙъ§,љ5L­Žњ‰ёoАдЭ?ДmдЦЌ9RzAй;sРіOЕsr`фѓ/ж+ЄбНл“Б<еыS.ЎЕ“ЛП}ћe_VІ!vЇР™i;fмdђ3IњJвŒя[­§*~”˜P†Jџцм[*,?РУDћњ@…мЎ:пAЩL\<Н€ъY2>viрГ}ёб‡ЏВ“ТЪ Cjп‘™KŠv!žњq'ђ‚$UЉъ­УЙ! šю9ЦЬ!SxkЈ€8ўНШGHх|сд—йј…п:да‡u єј#“< Ђ’˜OmEЛнЉј!Œ­;CЧСRћч*нF–•saœЮхnщ­(гйƒжЖQг1YbЄ24СЙR YI{съЈќ_bќoЈ*яо1cТ”U\:Л ŽМSt5‹d :ІЎмБd”$‹#LZХЅB.90т' ШРGК,N0Ж…s'џRк/ијžНV™'ДіуŠViч0Ђ]dxу™[зBdОэяюRнєn1ZІиљљž ‹6mђD@ђMЂ;ЄЅŸ|пыпЩvNQЪќ›oќЉ=ЭіШв’Ъ’в ‰%œlКrkЃСШО; ь­А)]Тz‘—Ј}RЊЛе]Їд[’›ф‰І h%е†0роз’†ьMYЦ!&5MЖˆЯ7ЅžБЬЯ’U”л)i[‡Ьv†M |І;x$РxAD,лј%; ;ъCУдА`В Лд™Ъ6}э&t:З1‡ЊЗл§ќ—Wr‰Щ’Pв=d$# у IЇ># †CЗ Жє‚4—fU[hЉЛЖŠц.8 œщuИHпНвVB†Љ§ :H0t j>@шЯ­ЁїЈЮ'!€vпaМ’L{Ёeƒh‘Дј 8 ;л‹&енкdCдЭq/\dежtf мурд‘ZиїVc=Y"СV9ЪЪЗщu›"И ŒR(јСŸПёЖљћ…•&МЗrРaљБпю†O?ѓIфЃ"rК€ЎЈLNшBНЕр‡Е"_„ilФA О˜8JЪeCwчŸ_эјКŸЩp+018в‹;ЖЃПаяjџЩоrОŒMН›‘QYзzs§шЯbЪђš:O9љњAнŠ  ьi—ђЁЪkQ…x§З МДR"g)№5јхЇ_™И4ƒБтulпѕКВш.tгў л/eК1дЕsнГАГуеыду1dш>!EmлRйiYеЁЅNЈOPО?šџc‘ЗёjqРэ’ЏНuЋ.џrс^ћУ)dukKыБЁМ ‚Є2(dŠ,ЎУКЎa"Х>З^и Mљ3I‹eh09зžLB§†яЭ§…6ћ! Їѓш+ ИVЮєј6И§Ж•Ь‘Ђ1L—љS?’shУСе7ўmЇЦШ _^РяŽУ_§!ЎЬ\!XЧINчшЫїcААж9еЁm/ IрЯHˆщ\ГЬœт!l„1Мы?€™{%„оV€’>+'ŽŸТсз‰+ГcnТ‚Я0Tоˆm`sяV'’Ќє|0>Ф|МЬžІ}хL†ыїГќ s§БcЏ'Fзиїи>lшй€bЖ‹Шqи gеIЭзч1^їK[T{к›Бp.1žЧэї<‰ЋжЏš_єjёUC€  –мќ}„F@к ’Ћ3Ž;ŽУgўgЏŸСфТ$КВ%l|џ8М;з=ŽЁв0ц/6Wuс—Ÿn•уŽЅhЫp№§€д‡п<%лD3рјќПфФvоIш/IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-group_16.png0000644000175000017500000000156511733011756023730 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<IDATxк|S]h\E=пЬНwяnкnvг4жцЏ 5&ћ`Sl4Vє!hЁОjэ‹и‚`U іAPдЇіЁBŸЄ ‚‚Ѕтci‹&Uжкjм–Ўнn77ћП›Э§™љ”Є ЬсЬœsО!fЦПјђ №Л‡DԘјЙˆgГ7йiњќю`yIŒs/Hмk-ЉЏMїi`Юx@8ЋE‘цуB"oŽ„З ˆЕфГ,Кk>^žьуйъŠоbKъбЁr›_mtxwР:G†ёцѓSxцфpБЊЊл’P‚€@S кz'un6аiљ\в™Лla86К@ЉIћŒ5ГУЇџ+А1№gxb byЩ‚ ­Ў?vwћЅЃБ“т­Tа~QіяќХK€Š@k[xђC5V_еяЬŒиOџ‡2AЊx=з<Нх§"Њ7њрЗzu%нˆўШNќ˜вќ ^LA-щ!fТ‚>АБ5]ш’Ї6x­ОьыЩг]3уЩУїК%а_ Р,р-BзnуЩKЁLЬZANAИєЖLб~aЕр;д:#е}›zПоб™ёСї О§zс ФжH+‘ь3яЅЁœBи4чlГAN#,q[$Œ+AЉБ{іОб~ќЕНШЯƒЯуˆЄG›|X1 Р+ЯNoЫ[ВGТt|я™Ы ‘0Ё\2{€Nш1WWшвr™,чѕOžЕLњGUKсѕŠnёWфв­N\Ћ Ÿt‹алOЛS-3Г>`GЦ;#ЊTЊішCg`ЛeЫ4іљВYѓFь'0Ў}^^<сџіGО3œ•s^ јѕœЁ]%Њ5Зл1w™*y$жвјј Щби кНЂSy^ю)ЙЛi ]щyДЪE„>ў`Vk*ђхЕIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ipv6-neg_16.png0000644000175000017500000000173411733011756024225 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<~IDATxкlS]L›e~ОПўЎi‹ЖRjЧЈu[M˜ЫСušEp7tdQ/1˘dё…,Q“ WcˆsKЪ€h2Ч‡N$ckГŒТvС2W eљJY[JПя;~э… '9yOžїœч=яyо—iш|џ—Œ’}ОoАЧПУБч№Ё§Џ4БЫ<еєЊ<<{=КzыN‰ЃяДтIуЕW0>~šсx +шv›žЭк™,Ÿ›хв–iVoKЌк’iEГPЃцO<ПkhsBв•…–ф˜;"Ÿ:ѕБйъ)Ф‹œ•s"\‰ T/­у ŽЇ˜ižџЃГПwt@JЇЁГX№uл=єОyѕХG## #HFЃШЅRЈ2^ЈЃbXзJJq™єДлРШ~~g €xS]]˜ъюVUаЂКККђvуёBq‘г яЩ“И–!Ы€Aр`3В*Ъ4”s3Dє‚zњФшщгШwCjЇг:2К\№ЉXPzОЯЎМъбnБки:кЄП8”#љ0Щ ž—ЮœAйБc E) EEЈ:wїKkpiŒ•пѕщ“Хли -ш4@N!зxŒ.ч TuKУУЇЇџ—GЪdА сHЩ_IЁќŸ$LЯй€§NРl`!pЧ+’”[ ‡qчФ ЌЯЮТфvУZQшЕk…ЙШй,кZZ0*йБ*6 ћ‰ 1M^;s удыpP PŸЧCБЁ!ЪЅгtЗЙЙ€х}аяЇDŽhbCЁяЂ =ѕIіЏкЏkDRР[їюEёО}X›™/„нчkVo№гжж$Ixип[UzG!§c–“(х5B|>СhђџЊ ўX8L“С вЊ#ЯЌЎЛ334vі,eE‘uгеВvВWœЇкУ_а3љœМџ'РйЇћъQфIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp_25.png0000644000175000017500000000375111733011756023523 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<‹IDATxк”U{PTчџнЛwьВь.ЫУнvqdQи1>Š":I*Ћ“ДNЌЃMLšdlšŒI&VkкІ­ŽЭУIgЊЩŒ68iljЊЭФX‘*тЃA Š.P–vич§zюнрј_лoчЬо{ю9пяћзЧ1ЦоmОнє#ƒЦ‡ЉpЃNЃK(xХ3Є[šЂЎЌўnRLBОdZхж $bY8>ббш•TXTАј]УO…"AЬ,ЛЩY–п‚@Xњ‹{јZš ]:л}F~–t’Иv;йеў66c'Щ/ўО‹љC|љи їtвКпOыЋfй——5 P•Іь‰УыpЁП O,љ6’ Nѕс@Ы~Єь˜lлсoƒRP­<яm‚BђUЇN.эсШЕуЕG^GНЇS,„#m@>*ЕДИ4а’6Э‡№\Э6mКіsТ ,ЪYUУћ}Л№Вkяњ›ƒ-81ђъm›pя0*`Љ}9ЎšPžSНпb†™ ынO:\нXѓЉ‡ПЩ 'SѕŒіn/ QЭ8vпй‚}о)4ž-о™м)T Ўl7”:.Г›о9ВaпF*ЗJ…2ўыЦ_~DЊ $Š;wц*”ЌЊвTƒЋ—ЛŽЏА>r{cбK J xЃфnньmЅ†М”e2•VkраЭEžЮŽяфn‚Ae„ž5—МШ-ЊРм 7МО>wљъЧCЂ8L ŒЃЪѕ‡_КtѓbrэЎ5ЧIyыїЯНg_\КфщXz~џГяŽ­[Мц…ЮOїЬ1˜­Ћ ц<є5‰dИ4щж 6џ yГч!O$|ŸП3mДЯљЙЛН{ФPКŽSхйjыVnГёњЅёіБЌЦсI>zІПcЋ—ь&IІŸѓA!4x 7p№u‚љя@˜Ђџnˆ!”ѓ"‰!]Ї Бмв5Э-Э2Hу5Ј>щРыvn`0!Т9fGЯD”нY`у^;§$зŠ†ЬBT>і%–=Yˆё!H@ MСD`А’z‡PЂ@šŽ@"2љЏ„6ЋNиаŒL!{•›—;vС gз0:%u2 Љ› Л|IkћЏ6˜—яЎЦвЭ…R)ВžVD›B9>€˜)ieЕ@` (IFИД„7Ё4Ф%вё<dѕŒ1̘D`ZФ|‹>m:OЭ$кХЊ­ x ˆNб№:ёд^№““˜ЄЮдfZ€Љ1 FŠ…ž:cмUшГпNЏЮх=Vь?Е?œ ѕОsОюЇ—РoNчX МpŒЪ6Pd9цH…Bс˜&“P №:]XЛh§YaЭЮЙб@ 4TчЁ!ˆSAuТпѓVђІ~>Oqяќч]РЂЎ!џяVЊbЋKTa‘AдгРЃНа7ЋП8""ьЇє“„фЮŠЋEaўCД–:€4†•фФ’р8^лѓйѕЯѓџŽX‚О“nѕl:ˆCї( ЅЁZ‘xђŠ‡^ЩТˆR(Ђ€ЅŒХЅŸ bнbЉсЅ7QлчƒЫrP˜щjP 9BЕЏXЉЉHзz(ЄI:T­ŽЁ‡Цтхfж§хО‹u Lы‘˜GёЃўr.ІИХ %zЌ?Еyœš @КЇ('!пДЦPАpпщgoОt"yл7 fЫa(ЪgШЫb(ШЂ ЅЈB‰С љ}gzVЉЃ |TžtхцdГ‹ˆ:•Ќ6dSЈb$аDЬŸŒN}ЯqVѓцYћЙ.jŠe? [ŸZЉПPыbљ'Џsјь|+œPЕєТœџм5ћ•Ј6ЯЙw[Ћ“"I›%ЉšX<Х(NЩŒS(|уˆЖžFr–ыЖ&oѓЬ]/Oс‹uОюal;зУ­яЂк”†ŸЖіт<•wЙ+—oвЦƒ†щЦ†^ЕŠ_ЩGПUG1љQDЊІ№„4)Ц4Ž“4і 9ˆO -@wщ,ЬЁq03Vўы:ѓmљ/qъvБPьnF~I&ˆЩЊЊЪ‹г“„ЭЃ@ЯW`ЃН“ё+ ƒхQЌАмcђП.ОАj "з‰xМЗ5ˆ•і.‚c ?Г„*lЇIяTЬšЛel`Цяџb"ЏЋ1 "у сяёР`йJwяЧЈ2ќDўжЭFŒšh‘1vПћІБ.югeQyIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ip-ref_25.png0000644000175000017500000000277411733011756023761 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<žIDATxкŒVklUўцБЯюƒRZЖ@Ы+mЁ D ­–ЄD сaаDдє‡Q,1PдTEHќaјaдФ€†D‰ЁЕfA)PhEФ№иJ Ѕе–Ѕ]к.л}ЭЮЮŽчЮЖА›šИ7Н;wЮм9п9чћЮr5k!9šЊzЦ:kкgеt.р bЧŒњрІўєЁЪЪїc]ЋЏ"Ч!rPП}IЧs8t№&ГЕƒуюhЈlтЩЦѓфœ&[Гыэћ*zGRMЎu—їœЉк“ ЯТуsЦe ‹dЃ‰x<.†Уї”И’Кu?…ўёD‡ђЇ—4Йжўў^N™АA`б>B`+Р"/Д(ч^t г-*cР^l?9Э‚Z‘sЮsОBіOџ7ŽТ( – —‘JŠж~)OgpP/!аO<Уў№ЧFƒ™Н“#':‘ф[IтГ4К„њЏKК•ЇьyГЌ „Ш!љvnФ“уŸЎ'(.‹“˜ЦQД\+\ЏWМмЛ… Р1ЧVКbkЙŸф+2kЭФ`фг$g ƒ1эШЕДРЮ м,6љЩы•c=?њЯ=q0Зr‘o–О fЈ‹йЬižЦћ’ф2ОX6B­rXёŒ^ЌiЧЩx(БбwЁ Б‰Sj4ј†ро8 “8џЉЧ ы?‰yRMѕJgТcшс/|ЇVeїУсњ}јѕЗ—ря=Dф}вДE3ZŸKŽпе„ШX3ђK.Ёи­@ЇAŒ&̘MМСФOg8я<4_яЦВЭятžˆъ`Ÿmб“Ї&GўVєwmVЅ€ЬЯuРЭ]і%&FX3r˜ŒйˆhШц ‰шR”зОƒ•ЯюM@ХzђђIя$ЭшР2ƒжЊEЬ3Д яЙїB-иЉСM9Є.Юti rІьS-{ћ §M<аЫфвrQ9i{&MшЕ7•ŸЇрЛv о}ж%&ЂŠчђaЏюCŽ(vеRкРйЯЏэgыИDЖжН6ќљУ[(yьYЌЎ_ЃкР%ШчО!фC",юuР{9=Eр,ЩЁЄСЉш‡oЎЇЉ—(’(анѕш›P#ФM6XK—BtК€р=`‚ІХ „Чdи З`Эќ_x§eMЫšGށ$IYЖI:ЈTн?“(H,yyakѕ чХgіљXvD`Ж‘ŠMЩбЯд[іхќE‹ХАmлЖщТЃє0D“ео БМ6%.пX ok:жЌ4•И$зЂiЙі—чЛi ƒƒƒGWWъъъВ’ц!SЩŠн”‘BNMHЃeHФчBMІХ`'Е”€›Е€:]#mˆEтдћ^ЏшщщyшГЃЃUUUhnnN’tN†я‹Ÿ„~B‰шРнДs…2, €xTFn'ќБ”"'PКъ€тёxАsчN$‰ibммИq#}Ї9ъO;,"ЩЮ$ЂфTŒ“„ЉT•1H IqT•ЃЏ E‹PрКЃЋЋККCCCКЃбˆE‹щUTT ЅЅ6›Mяhэшv`ЮbF•‹šOSвБОQ"€?љвЈЎЪo­OЭЋєљЅ1<<Ќп0gmmmhhh@YYNŸ>­л~ШЎяТРХ$ДЋHM!Ъ$Iы„‘€0:‹ J#ЃЯюЪ™’ш† PYY ПпЏЫXХЌвЅLГ_—@Š€%:‹:ЮP­O7ћTШ`l+ДЄŸWШњ2bdd%%%КqзЎ]гєˆVз Iq`шŽYџœ­ƒоFшl )l=gЖѕЎ%{рж|™џ3фоёэ›8\K#Z…б•pя€й~UЮнњ†Ћr!дDе3ВєЏ‚K2 —JaIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/inspect.png0000644000175000017500000000150411733011756022266 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<цIDATxкМVmHSQ~юЎІSЧќ@Ь4Г L2™™к5 Э Т– F§‘„"„RHˆk˜P`еЯ~T†жА(u"§АA+*ѓЃЄ0г577нНчvяеЬбНЙб ‡sяsЮyžѓоїœ‡Kq‡Х1TAЛ>Db KЙ‚Шя6XЎрќѓ< М’[qvјžF№юП IŽ(B $9ˆ§Щ?5( L:Т‚LЕAnЬлaY(ТїyD@,­О‰p vќОG"Т\!šкуЛЮ‚ Ч™0^}ŽЮ~5ЎЗЦ sхЄфИBzw ЖзŽ9ˆШф2tM"&Дўзn˜љг2œИ’ы”BмœУЩСI”ˆм<Т7ЅЌHcs;К{отцхJlHM@uэ]p<€я(ЉЧЯЉiўХ—1ЅњѕˆкƒТУ‘8л‘Mе8ŠX3TЩС*zTVФ2i{]q6ђ5)0™G0<ј W[ а•фˆc?,JбЇ!$;ЧЕСи™„-{UH/T!Б ё{TAЪaВ5щ3„<ЭZўsИА*6\Ф–ЋёсљtѕНGгэЇhьжТЊŽ€.ЦшзYЬ3˜˜&n<Œ!В"щ)qЈПіp1ўќ}tЭ†љгTЙЩ€}‡аcLуN Чc%+’—‘$іх5wаѕъ#ђ2“ХЌŸМxеZЪŒипАV‹P .§'2;gЖ’5ЩMOФН†2XЌvmKхŸ.œЎДе|‘ѓSХ9IQ4Wє"„зgl4*sа\‹ѓЇСкK9—B'ZЭbЋlžЗiЬє^єъžм2ЎAэУh;љ YŽ ~g`d€$!€Т™ўџћTќ‡с/PгџŸ@ в 4фЯЇŸ LŒL ?@Т €АК”МСЮkќ МП ›?|gјђх'XЭчЏ?Р4@auШЙшрзЛoX] @˜.†##УПџ‚lџўь3У?`x|ј№•сѓ7ˆЭ_ОA\@`v7sžЁ™ѕ‚ˆ FJГ3@€ў^ЋТСQfяIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/user-neg_25.png0000644000175000017500000000301311733011756022651 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<­IDATxкŒUiLTWўо{Г2Ь ЬА hи*uTЌ[ЋЦPiЕuMc 4ЕёŸ‰С&˜˜єGг6Fbmь’‚uKДкˆдjБЕ`БZџˆ‚F@d™}fо{НяЁ8=ЩyчО{Я9п9їмs/Хѓ<ІS_Ÿcjь9`z>L &Yі8Ђђ*•y,#SА§7Ж“<їN’ѕЇ‚вш–Qy§л[_№)AlZЮІ,љ6'П W[М™’d—€ћщОRьОsЙШњTГ‡ѓŽю[кић› |Н­u–zц„„ЁІ˜P:Lпч—,ЫгЏЏЁ$ ЪЅ”R Yцb$–lЂrц'.єЫM?§Б]Ё`0a=Єпy€0Џ6П—Oх(Mщ€œьŸp n"}cФЃЊф фШЌš@ˆ;(иG}ЃГ@fm—ŒёMJ …˜-jc<$]rт!@,& ФY€'ЄBcPCўxЌМумЇqd13Q€9ŽА$dЯ–kЄ@ˆ8ѓЮ^Рё€ШžЩд™Ё(\‡”є УŠЊ:™Іи™„Ѓ~QRЯўyIф.ВРЌ‡,Иx2ސљ” €TJ›ˆааŽЈЛMМDЇеŠRNЖЫgьљ<ЏЈ5qG|< `R‘дIЅ'Y:Ип WэІш‚и…їИœ"лэ.0 uо3ю&б’ШR†DO‡H М„dDЖџщx ‘Я іяЄuЦЮDЃгChO,‚ЮС&Л2ћ-е˜#O—f$$&ZF@HЖž{ф”=„ћq?ь>Y/эљJАЯP<™BЭьxciЧдјjЦ*rЬтЪ#њДяRݘЏNб@™Ј!J{рЕк0ьˆы—ѕl_t*вљможЙ"vЧџЇ>7Юљьуу—GZ—ЪџB~BЗИrлсJ˜Ы-ŸзЙЛѓЅw†Щt6,џ]=NІ§žSЬ2ПЊы ye'—TжС tЄљ Гт8хЕNОшн;оД57гЇлЯє9Ћ№W(а( Iн№rћ5…‰дшR pїПtŒ‰КCз—c<ѕМlхљ—%2 ФсчтƒМяЕќјhМNђETBk{Эз.ДˆВ§–M<б)чЉ00ВdWм>њПAЂ,яЗћИАЉМsI8ТoKЭU?яK1œž 8‹§$Ї`(Э йЛ§ХzN+КјкЌ[X|ќbPцкƒZg"Ђ„чXОЃ=ЊЬнљы э•dFdы4 NЉžЯ“ŒBЩхBMˆu);$LŽdoѓї%гМC ЛаšЙѕЕЙЅ@;vБИЊD8*яqEj/|­piРоГ џѓˆЮлј@ХгФIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-custom-neg_16.png0000644000175000017500000000155311733011756024652 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe< IDATxк|’KhSA†Я™;їцц][5 *hD­Jh­XХPu!ˆтжтB7•Š ˆ‹ЊЈИ№…тFС.Ф7(bЃ–JЅКш3ЅІiЊMLкЄЙI“мЧ87Ж=pИs>цŸ9gў Œ10Г|§GfІ’ео{ы>јxZgииЯќu^W„фъgи@({”3šтŠњvжаф‡Y6_щƒБНёnУОeР эж€Щ9{оаДЬDœѕ›l#…щ(dTM е AЈс zNЋ0Э*‹lJ-v<Э–`Пf€_@№жОcZ&(вgT–?YвНьdО_U "})Шђ ЄтsІЊСпL|ТйЃb:AЄ+‰ЫйЬ$™~єћБ>Ж&/8wiЭ wАiЗOo9ЌEt4rAє;рЭ‡z\уj…E"ЌВвo>ДHЙ}ћЛg№u›ЏкœГ}ўзЊraђРиpфкЉЁІWє†IЎ‹™ _Ш" д5ДOЭМЩ“ЖogG…Гћѕ%ћМЅы1%6RА+ня ‰‘oнЂнqЋЊѓоUѓzМkчђяљЁЭ‰бшAГ%ЎГ‡s‹FfЗОмs…ЗўŽеП–Рр€а'0†: ю‡ЉМšЮыl—љЌ+8eЦnUе!ЭBќaМvхVK$›ЬœДдVaЁ/щ­@Ыч‚лсЗл ЉhТ"им,§„^СыbˆŸнšN8ПRž-Љvš†D,š$eGˆЙбєЕ4fъћЫ RЃ€м%\АZB ‚`“С№–NаІ%ЃЇ‹6"bQTњ5ЃfЎQ kЫ(ŒЇV'кb „”ёЉЈХхyњЧЅb3дЗ—јУмёЏЌŒK% ђІ3УаЕJ–vђЗИtœ№Учrс€ІBўKф‚IШє*@•Ќ™Іљ.єшп7—ށ.яљ‰Сp<ЬжБ‘šбЅ‹(ЋˆеѕйШІКŠћџчТШБj Ы$w€пNЈфб mCѓQŽш9хџэс—?‡œДёˆ{IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/state-sync-cluster-group-neg_25.png0000644000175000017500000000267511733011756026613 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<_IDATxкДV}LUeџsю\И\.aЈ$~•љСЧZ1YЋpжtБЪ)•‹rхдˆJcc–!47›ЅтH0›љ‡Td~1Глшk DЈр”–WA с~q/їумЗч9оK ш[яіœї}ŸїyŸпy>Я‘„јП‡Žeѓ%ž*‰о$Š%&ЄpƒžЕЕ~|AЌ™+22eФШ†UРЋ xCЏ eЭ#š#,œb‚'†+$ачc˜ц ™т †СvNŽ‘”ос‰љ6j ,1z$X%k’HГL+›нЅ'$ˆ~" rtЁjiБбžВuHУ 5Б’žтїбQЬqŽФgWљYЈЃ<СV:š=wYЩ’T“„DНDqшї tzE A/H>Uд“иlЂ!т)tчМ3( (Q\HУщbJоxЏ\€ні-\ўкћ}ˆгЫIкGJеА`7jžЬ|Ў“ЪР`э№їuR‚0eЂІYьpЪU–к|NФ2ШУнЕ.ідлaMO‡)ЮћО8EБXœxŠП–Т.”Rж}чP"лк`ШLEызUшљы"ЊІX{‹dЃФїдnЏPЪк…ФЏГюкЊЊ ) <ˆйEŸ› )‚$ЭN‚дТИщЖр—еЋ!TщызуХТbјOюCИЋ]{™кюBЊC%ZЪ‡уDћоН‘jИzь&?ГгrŸЦ'Žсњ 79}юЛЛрt˜№ыкЕ[g mщЈ-ЇДDЙь sЄKˆSмrп.ЏMSЇŽЩ V№[a!Ќj^ЊЈŸjeю†=№Йт4~ :јўwqfd&&!AĘn ]^#Й@ЗB‚ВЯfKQŒЦьžККQHЗ,šѕl>r_Ю‡:Јг,РmŘНmt‹qќьW№ЈvФ›8NY`‹ №S–aс5ёовјMУащЦ™-[юШї9ЋVЁуаЁ;ј  5‡[wЁЃя |Pђє(8sе?"їСEЌ“П4œ?эйвœž јтэуn ™fф•РпйCмMЄњќ\вђŸ—ёкы#ЅlзкЪЄfї#й+пВаrЛЌ(EЇ7oОk%/мО/ФЁюь‡ШšуС'Ж@фФеKuАRSЅй;rЅiŽ-ЂiSfIЩї3–-€љюWцї6Ньu9Ф %„ьEЗTф>!УN)яѓQ‹ }юАЦЇŠwŽ€Ќ ИоvДWW/ПrєшИ ЬO<вЅчЉjЧр}њ–~ЋмтL:јlˆТсё е9$ ‹$mРп‹*(њЃИјžЯguNк–u`š№1а{‹й/§йk’ЮпАJЭзбм’‚S# Р_ТJЊјqвђђЦš}|`RйМЯдMь„UЈЮ‘фВУьwA zџmтМиyОВВЈОЄфe9;v`щ‘#Е<п>X>уw‡Й2П&!>† У$;єїЫ7еƒ9/ KTVYa6Ÿ8]Z:.@Fqq -зІфф$Ьцьk6лоgMЯ‰3fЭCc§!$Ѓb„УqVЭєѕˆT),[Yо,{ККюPBYчу™їуYФїЇ%ЇAѕKnWS№б†а“‘џ€YЁУbЄƒˆъ†вRБ_Џзшмюн‚yDБДG”xЯ|>ЪђНš“е"cУ|Ё,S!буD:"0ёїŠлЪLТкиДukQLr2ЗябŒ‘$йЩI2мпЧ**j.u_кГ`§\g$О|gpєВџ0:А•rL№УIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/firewall_64.png0000644000175000017500000000705211733011756022743 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< ЬIDATxкьZ[ŒGНUн=3;ЯЎэxзkЧkчEФIP‚ђBP$H (Dќ№Х?|!$Ђ Є(т/ПљA@>Bт3‚x$€@‰тX82 БлЛkя{gчен—sЋЊЛЋgggЧ1ALЏjњU]]їд}œ{{3гџѓІЦŒ0` Р€1cЦ йž{@Eџnб\ЈЈjbв”іcJ"MmŠањдzъѕљХ‘|яѕx шЧhК…a@ЏЅDgб^х”ўkz‡ъ @qLq˜ДYЃжй7Јѓ ЂT ŒлzŒ№(‘МšIQjішшЎЩ>ПЦЃЎ+К§…фЃТЛgАњQEMDЈ†жKˆ[ ЅН”LФЬ-СO?KhЇт”ў„Ё_‹BкˆюїSD§АO[Е>mtцhѓл“*ў0ТЫўЮ__c ј$vЯЃ}Ycщ&#Ђл=\є{qA@ X&ХA oІФнрШ\qŒn)&лЧ§5Ьћm\ћ;Ў§ЌzˆоњV \Ѕ№щ§ђў#žЭ@„ПЛаЪ9дŽN}§шvфО0cЫру\ЅIНДЈдfBZ–ZB[vГp˜&ћ)ЭЁЯУЛЕu‘žM›Дўп^ŽCOxˆJ/ЁMeз~pз•ЉQ&|Ж=rKj-Ч?_бJ—ЉЊХNHC>QODЏ^xўТѓ  dŠтїрщ;ЮЭ ы#([q‡†˜ая/)кш3эЧ§ЯЯ(3Щ› ZpТм(сyаLзК,R“JБZ)\М‚' ЖХ1<)Жнƒ]џuйЖСMT]œhJuc]AјB3Yшz‡QТoг­ЌЄˆщщоJ`•­MИ ЇE\y?ЕЭЦ@•Ѓ’;BДnъ4 эЁ=хI\Яm”№лЂ@ўлЕbТ\МЈt)cј™нk•!Э$ё кaСйBŒ”0)}|‡шazL`gсe>њŠ ƒsxь`eo09qsэЏ*:Rзtыd@Е@х§xРKу$Ђ:™йй]Sи!Ъ\к ŸсЮе{%LМе U0(z,Nш‰džю R:h:œ4$4нHЉЙPЇш‡џ$uML`сyTА1Вn”№лŽUбзŸ„Мєw L­иtН9bzZє./СйЦАЎ^ЂiЙЅшдс-zхЛ'ш<Р‰ћтШ‘cЄ!Еk)mJі§;ЏЬ„F ПЭdТŠ3”?=DxкQx.ЉVіВ—/­єlА 'ЛGђб0Dъˆџ€Аи=Š!6&dIЋВёЉ—pу5t}щЉє/—x%mьЕІVu‹6hХљKт•€м>TјQDˆaПi-дЊ( ѕД”MYpqˆк Ў•ЗтЪі“Н№„гЋЉс_šUtzƒ€"ќЁ EŸlngiЇжс8ћ#3w?6ЙИT‚c‰ЪŒсaEдчXЄ 39 hСІP,]™[™_'žtОJщR—zŸ™К™_ @fЫПЯWЗщŠqx‘hŠЖІ‚U Ш .}„5ОЙ’вZm‰ыГрюпо–ИОЗjЏ\J 9“hД7В‹!Єжч$ˆ8)ђsB7шН‰oЉЎfƒы юфэ“С‹CM`д.Ц^Т1gСё•‡G sМi™9Œам*jиG˜ЁбM­6ШЪKt8бМ:сvЌВY„Н@Й с7tіŒr§BъТV*яЋBк:Nч`Z YRQ№˜э њ§65т(.iРsFь{}эxОМEтЙЈa7БёžIШББ_6Ћ”EЬLЂ.ZЃ #lQVr&!ћaТПпbКи)ђ“[іЊ2Н‘“? bЂj0д91$(Е/–ф0 U%ђ”йјћY}1“  k}ЪUUš„ЦьYY})ЌДаoЁУEюЬKќOфххжa+3†„t#|!j84Fj2с•ъhЛ* UбЯчlњrn>к{Ж‚YXЭ@`Bxс_.3НБЦ4]%:2aСш:пвwUІ5cV8Žх}l мИВ+3Gsа ŸгxмfМhЈ d,м€*„i”_ёAѓ4gФ%РДVЖЯ4Јя’'Yѕ)sїPdЖђJІ)ў%qя–Hs$kщчДh3БcњТ{٘тaTјнuЫQс!у:Вxm Mъg'ЪШяmˆеѕЋAH™к|сs‡шEŸ ЬЛ Scfj]+€`$]7‹†ŸP[SњЭхВ№€„mа’ АЩљУЉos „фд"Ъ$ЫЫŽLЩ\х> ъJшrў сLJyl“§є;OXьrЪѓabЕTJzƒТЛЈŸљц275CSшhїгИmЋAxŸЕfЌ•л€zЩqр™ЧDЈL=@ЖE,™„НIŒ< O8e9?9“ЬW1pBч!•ЪЙ„rk5 05dЩ$Йd’ƒТЯУyЬдƒ;JHHЋ†Чƒ0№TWЪ_эиЦt^дmЩybYщѕžНFЪCЄВЄ‹ ŠUДeq7РЉ+Ќeї{OЄДдœ‘ŸpэДпAјќнž№‹эд˜г;kё{Ч'У>m/‰љ$ЈXŠЌ2~‚š-|ˆm-тG&~{S(ГьP@Z“8яТYVIrО”.Д ХЌšЁQˆіU‹т$щjЯN\оНГмX‡—™фШ•їќP&М5ЉRБљNƒЁ††С|@.q‚<Ї—Џ­ЇЮњ ЧїaТ6“ПШ=м‚ДЫ]2пкIj8soГPSQ§НaЁ‘чƘ~u^ЂВШšЂУ‰ЭЛD`ЖТGYTyЈЫ#ЫхŽ№ P\мJњ76‚^^ фО№%{р>K#чeђ‘оюрФqЊ9ЖІэŠ\qq\ќЦ…ŽэлШ0D$ГкТ збoЯйdr™Ÿі€p„™Б Ь)У•­~qёPбОЊe™3Эxfйœ№Z Џіјž|Л–йй y’7&Ž Ыф…јьЋZOЎй„Gbў§ћЌКgл€И-˜я [tФЩ™ТbG4Фњ(ЕXS’o&CЧ4ExіП‡њ~oЇ2’Ь<ђ j F—™чB#AƒЁ.{^lВЇэ*›=nь„М‰ЭЌ|оkЭIBЌ„лKу|›ЭОяBЕАСЅžmяЗ­cŠЏY;еЯJМЙ’˜Iж#УckиЂvёžхћ?тНЊ…ЄЊ9ИT0йMјB‹x[мOœ–dЁЫŒЅ ыЛxd‚щјGО”№2NSЈqьž{}•ше РЈmа š\fЃЯсZUЖ @_е#bЩФ&0лs>щ6МРR‘vИz8љсЂо`я'q!B>2Ю Р6чЄ<І„зƒе‚P,B;’e*}СоlЃ=ч? thђaЇŠnB>п”а–хr&‹Уз–Y)Ћ ЕKnW>XSz_DЪЅЮlj ЪjNЦ-2чЉМ"ДьPjPxЕCœW^mР<УхZЉvрЯЎљлЦ§ ?Њ-=P>…іYœ4ХCЛ"кJЈ{kЃј"­IgЊЄd…фS›ЬA>ŽЈ˜kJшj#ђŠЌT„ВВ9 ~А†Быw РАэкГзŽЙ&й+Ђ8С"щћsтЗФ,aM­ечњичщuW'ІЄ&šCF(TАc%uШд‘`IyЋ9p~\ЪT™‡ ? €„ЗЗ?(УЖГЎљлпdоЎЩvкуш4йыЗ`>їBрЪzœ—лŒЭ‹Ы} ž?Ы"x:]UщБ:щ™ыР}KD^Сгв{*хв5ѓЮЋпї8У4оН лЖЮпpЭпN`ЂЗ)e\ШК"šƒvŸјЉЏ )3V.Д9<лržп˜)Фwэ1цТЅЗ5HЉ›œЪ˜!ЅБh€№œГˆŸв)}qЧ’zђ.EзyЋ8ѓщ:ї‹&kJM41ЏY LІžњ‡ŽњццЫ ЩMtYŸС“џX-}ќЁІчšсљWВs"`m нŒі5Д<№DŠД] Ђ Um[пІђ?.Aј“Л…Су6шo„ ўдE#сMђo}пФвн­Ј†AЅюѕ\УWŸ>Э'w§?СЉ\Эv7к 0›[бV!ќ/Чџ,=` Р€1cЦŒ0 М§G€~ŽfŽ\cKIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/apply.png0000644000175000017500000000070411733011756021747 0ustar sylvestresylvestre‰PNG  IHDR‰ bKGDНННiBеЈщIDATxкc`D‚џPŒ˜Ш1lѓЁх =0ƒ)6свэS ŸоЅŽWЇЏnћ_аAВ—qjxїщ5УГЏIsХЂНѓўWL/A7єымBМЎУщТgяŸ1ˆ Л–сѕћч]‡Э@ЦŠ†Šщ%pCуЪМVMйЫРРРРH’ a@@T€!Г5_ˆ›ЈАcФ#їПcM Уƒkgў§ћЯ0Ћa!=x]ї:+;+УЫЧяКŽ —a@ZYaумC]G,јŸйš†7Љe(5 frСTIАбё EzTXtSoftwarexкsаPжєЬMLOѕMLЯLЮV0б3а3QАДа70б70TH.Ъ,.Љt(ЎЬ-H,ЩLЮзЫ/J|jљxіТ3zTXtSignaturexк3O1Г0Ж4K411ГHГH2532ЖH33N140NI6NK……w/ўoAIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/down-arrow.png0000644000175000017500000000066411733011756022726 0ustar sylvestresylvestre‰PNG  IHDR rыф|gAMAБ ќabKGDџџџ НЇ“ pHYs  ’љЅtIMEа3мЇц1IDATxœm‘НnТ0…?7нH$$6+Re Ъа‚˜ЏЩЪƒа…w`(-(Оз&ю„ђw$Kіѕ=WЧŸЭnЗ ыѕяЮyTU‡ѓŠwU‡Њ№:№ѓ{РфyОї{œ*VБk-VЉіЩ-Vх Р0!№Pu9 №\W7_އ#тЪiNЂ‚ЊŠ‚4MЋNS™‚aЛнВZ­8NEqЕоЦc:i &ЁŒ‡ Ьf3Z­ж]ВfГI–Њ“(M!@’$,—ЫѓE­щtJ#nдГSЈњFYFПџr6єz=†Ус?ЋxZ,DQDEЬчѓŠє.AwЛ]о'МїДлDьЕЏІgnпёљЕzЅ_ЦЛљд8NHтјЉФT!7+№єxžГJ> IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/tutorial_64.png0000644000175000017500000001500611733011756022777 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бх \IDATxкь[wlЫџю|66јР=РGдgŠM J€Їˆ*HhBDDГј шQB5 Eб;„ Gy4c\wрaƒqЗяn3П9ЯВ7З{>lxc}онйй§~ѓе™9“Ђ(є53}ххW~р+/ќ;>кO\waє;FсŒBП0^“E3:Хш'T|ЈШ @IiСh;Ѓˆ/tАл1Цh(ЃбŒbU (9nѓ–€Њ§m8еjо’ƒ~œчЄ%SfТЪˆ&[~~D Џƒй,tњрЄЭЄйвЕ'™L&veвМFqН6ЙV!œ0™ч‘§I­?Дз{—^бДWиЙIљPїсiжяMЏэЇуЛ”њгПшчЭЁ^Сѓ@_DkH(wьF&Гйѓs)/-‘ _П"{QИsсYбљовŠтвRЁQЄОщ\CЦМЏ5ˆъ…PНі%k“0њ&М=@us­ Ј†!ПсТ›—єŒВтбˆmщ\Ьf3ЇвЮЫRg2ЁЮ$еŸ{K|фMюЃ5#,žŠГп‘ЕЎjзД№',U˜;t8(7х)ьш`„Р‘#YЪyYъXGь ІЮјмлц!іz иrsШЇАРEЃ,.*TђpQжллЁш2бГgOъаЁ5oоœš5kFКГmл6:vьиg‚=?Ч=rЕ–ŒlХ.‹#˜]П~=eggгЕkзшфЩ“єђхKоQћіэ9 ‘‘‘ъыnмИabeРэ™'˜ьЋ&UћС`nзЎ]ДfЭЮИЌпѕызЇI“&бйГgiа AќЙДД4ѕўчІњЙp(ЊFˆбmиА.]КD'NœPыФ§=zа’%Kx›SЇNёgЅЄЄ№ы‹/Кˆюwп}ЧŸА rgzbОbХ ъж­эпПŸЖnнЪЏЃЃЃЙx—.хІ рp тсќˆ˜˜кИq#-\ИаE1r(—/_Vыр"…шщ:МФГgЯјQд=zєˆ?гЈQЃrГ FXd @ЇFPaКц`:УѕSыК ы0ŽcЈp5Т^Шq„аџгЇOsц… ……‡‡ыкŒrq‘Š'#Ш%@ыEчЮ#>F|\пО}y1mк4ѕщщщќˆРШ(l†@4‰  Ц№еЋW. •oœрЩ :„  1tЈ6ѕуЧчтЯуеКuk>’K—.Uпpd@tфШZДh—ž1cЦ№ˆQV›ааPЪЬЬ$‹ХђIдСЫIQER‡.:uтŒУ.Шz~ћіmѕy„Юђ§YГfQЕjеx Дjе*Ђl8qmg!ыЇŒМі AwW&:ЗZiйВetыж-кГgn`ƒeШ!КЪсУ‡еz9CРшћљљQ5ШззїЃ@0Šн!‡Cзˆб”)SИWЏ^~јa=СЌlьтттј=€Ѓ8Ч}$OѕъеуЁ3$ЖBфŠЦGЏ_ПцяР‡?}њ”оПЯГЯТТТЗ ЅЛAЛ‹ Р‹ZЕjХG|оМy\пaщз­ћ+MЋnА#д:F&OžЌо_ЗnЏ‡$,^̘зс~nn.fрРмкl6ЎААH$т‘Џн \“ˆЗoпв„ \f^RRRйшЇђ™­wРёТ… ќ9H`VdŽ(WЎ\ЁјјxънЛ7нПŸ0ю1‚{†sчЮёЖ9//л ŒтъеЋiфШ‘TPP№ЩМƒХS $NJJЂффdƒi-w‰ШqяоН†Љ0дцрСƒ.ї!цˆФћa@{x‹^НzбЈfЭš\BœRуeШnI)#ярMЦ'зƒСттbѕу! ˆ>ВQa%ƒрnѓ=lЈ€uЧD)6ZЏFб3FH•E_s{љ’Жђк‹(ѕёCђёM§‡€DќЫLMf lфЧєЅ0/—тўжПвvwўqп;]аЁЫ lШР49РРЄˆ`гhh;8мJЃкdISўDoRЩєю,]Д€kј—§цЪ` T ЊE9L‡Ѓваг{Œ.6aAЬнMœ8‘Џ`ыvЏtяо/мlоМ™к*7щižƒ‚ЋUЕНqк І ™)ЩЄхYxќ€р:}r§ =џљпOga:цУ:ХƒFфЃž[4GЯЯx~“ф№#mЕZщшбЃ4ў|ОX3uъTЎџsчЮЅ›7oђvиЮ7}њtВі\DП_ј#=NЗqЕЮЯ~OI‘нЦ#Т;тGZ0‡бп rršЄЦЧЈrЫ‡My,ЁcЩЌnнК|uhџ]Jпи—Т›ЋЁ і‡€d@u2_<ЃиИhэ‹ŸзяШnЮ.љUоZЏ’јV0k•&Lyэж9-Ш7&‡оcGk‘Т Ж•5 *KЏЕЙvШЃ—ŒАbטϊŸ;Oѓ ЃHё• і!œmђoѓРvu§ЭБJfсku†е™:ДcXѕч'вnнъвjвЂE ž >œjX3bЬцfщІ‚Зь9o.1цoTЌ_QԘP>иnRЖlй2ШSћЈЈЈ h7cЦ fОьJ^^ž‚ТRbў<уЯzЯY>з9DFF.Љ_П~ЦŒ™D3Khв<ЕgЊR <…Ш&ХЃбoєTрГ);vьXUжб*S%Й€vYžEџџ+ЪZ˜wxйІM›уЬ`žKHHи o𑑁ирŸЁЁЁ‰†Ч—DлЗoРF_aёОТ$A5jдЪииX‹Qћ/юЇГЬ Мзf‰,lЮ ГЕџЏНY9œ`‰дIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/tutorial_64_1.png0000644000175000017500000001440411733011756023220 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бх ZIDATxкь[PYўFГ.ТЩЉk:Kж ш™ЏЬ9`Y†2œ–9Лы­gі,ЕФ*ѕЪгSЋДъ\у­й3g,P1ž ае}њPhh(5iв„rssщЭ›7,€ЋПП?UЉR…^П~MїюнЃШШHJOO/SиžЙ@”}›IеҘЊWЏNcЧŽЅЁC‡вЃGшмЙsC6RбБcG ЁaУ†бхЫ—щјёу”““SІ’р‹`гI>0ВtщRJJJЂE‹б‹/ь Ѓв&|ј№.^МШŒCJ&L˜@ДcЧЏД иёш,ЌH—`pђsЕ>ЕѓСƒгš5kш№сУД`СŠuљL+‹`ы{љђ%­ZЕŠNŸ>M .Є^НzЩЎеNn“![У f;@є6љy—.]hюмЙ<ћwяоЕ‰aiМУ‰'(!!/^Lyyy­[У)еtXрŠш‘„ЦгЪ•+i§њѕtћіm]їЋIŽ>Є]ЛvбДiг(((HЗ$hЋА Xlz‚AшСгг“VЌXA'OžЄГgЯ– Dg мИqƒ.]КDгЇOчїшС‰(А`УУЂ„!C†АЛлО}Л.†Е‚pша!ђѓѓЃюнЛ+Ўе*ЎT@(fКD]  СjCTсЖє2Ќи€ЃGвРmЬiA‡Шн EэлЗgŸЃхЮS| зЎ]ЃЊUЋR`` f4I€`‘l@‰аBXXы)fI‹Л,-љљљєрС~ŸœqW h,Š АшЁuыжtџў}ЭqТЇ€GЭ›7w`мšН€РFа>д BУ† 9Žз,•D–ЊŒЋ )dёЗ8м§G&Ї7b, Ш}}}2ЎA‡4лй= H 9cA ›|2pЕˆfkСF‡@PАWЕДИ$\->т;њ1+ШцдB\„БуЦЃызЏs\ј^o=ЁrхЪдЕkWънЛ7Ћjоооv!ЛоЂŠбU Єі W ^G˜zыж-&Шœ:uŠCd)жZOhкД)ѕяпŸКuыFЯž=c7[ЃF ~& !$б]eIG6hqH†”"хL0И6mкЈŠюЧЉ~§њСЩЃ8gb§9r$ЇСЫ–-ЃддTЮ+`d1ы-ZД WЏ^)т§*р`Ahсђх+œzњє)=ўœ‹*˜iHЄA.ЉѕъеЃЅKПЃFб† и&9@AO6шZЏддсЧїёK0H5wІР(J^сссlаP/ФЌ зЈuыжБј3†ЏѓђђЂyѓцQЅJ•и‹ШНЮ!ИЧ№№бЊ*рZD dЖYJљZ%ЁАА€О§і;q†ібуЧODЭв Aƒ˜aDoGŽЁбЃGs\ђ3fЬрkЖlйТbсТ.žТxfffвЭ›79Ч1b-_Оœ] ЄF“oпОхвлкЕkХdЉŠ:hŠŠM€`яьEm DGGб?ќ…vюмСх+$-0`(yП{їŽЊUЋЦF 3)‰),: оЖmлИŠ`щрСƒєфЩюЧьЃ>Џ"Uх’Š6ў|ЖЛwяЖштђšц8Р Xœ Bx0Ә%ˆѕВeІŸ~њ'џ?88˜Нj†sцЬaŽrtЬТ•,LОIfХH‚""6p|Аqc„Ј™QIєыдЉУв`PLГ0–а{Hў‡ іх0Е` умИq#Чjk‘ђ:Ї Ю\ 1ƒ3yђd6beˆьЬ™3YWЅ—;v”gїћяџD‘‘7Х\рРЈЈ(~ўћїяљћеЋWљЃбШ (Ј&ЃъW7qтD~ОZeY Jшв;еЋЭFEADй –№зSІLсh b WЅ\й•^'^џGQєлГwРlIњЅ1,†дЊU‹ $BiИO4kж,–хBŠ2„жZВзЄфЦ`ЦфmіьйLЅi№џ ЕБiЊєkXСвБ4ц˜ Ъf %)хКМЛ5~Ч}ХЧвь/pvю m5A^!9aEW­_OА$х!!ЁДoп>^C@ђѓ)Ыpюњ4Bюm€ЋІ'l §Нh4p u~иИПв,Уi[rгPЁА3)pEZ%!<|ћќЉSЇЊ†нe- Юьši€Т|И№ждА0>–z-RЫЕЮvГy8šG ј ьмЙ“ZЖlЩх1ЈСЈQ#KЕЉYспЙ рЭˆССPHЛ,Ъв&$;’Џ^Н†-v—jŒЅ]šWПжCUьv‰™‹ ­[>е}mYƒ˜˜(swIVзјy@( u,vк Р{Чr2>0žžF2QСЏ‚–jsY€ ЕЂ’mrљr№‘žœD‚йD^•+SAnХnэ]юЖŒgЄў—фх.Ž`bтCђp"p^Б\pВЃ› (——b9^Кl}ЗшМлQ1ђьFƒц{y1cЅnˆQ|ЃsЄУвхEС К‰ рYПP-]PrцŒGW+xНmqeйрCцРў‘[€аёѕX"ƒ™ыJ”ью­?=иЮ5"œoљ .ё>ѓx“ЉЅаdЩ{EПУоeю {nн[Vš„ ЋU ЭvјЕ†WŠ?Zј[ЩutyЛРИФ8ћkОЦшЌ7Ѓ”ъ>юRРЙі3ЩЯМƒ=82`осQ?JОј.:dAќIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock_25.png0000644000175000017500000000335511733011756022230 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxк„V]lW=sяйн™й{ЗkoЌФ бК$аRШOЂ•ДH ˆx$J@} TТЈІТ0КВќЗЃ‹їТ>6х^$_ќЮмAС•o2CћЌ’{йp JN‡bЈ5nлCsнAsБƒЦ|Нf6lїЯ3Іќ–Ш–џ/ЩзјЏгЩућ†СTЧ2р™BZтјњ>veц:P_ъЂіV n/˜ VZ“ЕзŽНњNЬw‘œ™МѕLfЏљlvЬ,$J=Эй-н нѕьК›ВpƒŸдZIDЙ4"]CЫQ›k qcГЌnoэѕcоCB_оo§ЌPЩ'3Н•.Œњ&і|ѓ YK@O єzжЗ\м^ђ№жЗ’EАб ь~„е…жgjUoЅ§t}њјх]’Џ>{Г2| ѓЧђAЋb–tD^gЙJЊё2‡™&-v‚y;(E‰?бhіqѕК—gScy8Ув?иЊ6^їжЖП@Dw™\Њ'љЗѓYQIuШ Š u№аD ІЁХˆ NЇƒO>ёe"ф№‘1Nž0ёЙJ ГЏ­bu+„ZЪBUљ ЦpZтГ/}їЦDТвN%Ъ&EчдzЈлxп^}W+§8ёѓ Ѓ9'ДЯ|ЂˆoяЃuГŽv/€2’ƒH'N“ЛЦ­yRшbйЮЖГйРО!ЁwС}п *3~{(48EјщgёˆZGдВСв)€ѓїЋByLЂ}TЩ%c›і6LфCЄ$Р’D^Žу`mm !•щњѕkDФІa mЄa™r–…“šxу•Ф™ЧH!lїŽŠ0ˆŒШŠ6yп#‹і(1p( vˆjЕъhlmХфžы !8\ЯCдщТэїбlЗљ ‚ІVШCIщвЅ .”бHАЩQnУ!'ёX‚ЙЎ‹ЅЅЅ8Ер<6P% .H`ЎЊtWуЙЪ8GдЅJ›š&‹А_$5fДиёЈ$Дб4Z,3‘Н{ї.ж‰@ Ы8љŽ~)• Š $“пc‚˜„Ѓ\ЄRЛл”QDZ‰ИГАЕMЗеnћд6€VhЫ>AW6Ё,“Bрœ2 КЎЃгэтмѓЯЃОYСUm0bBzоl“ш.E7†bы яЮж†ƒОЁЉpЌЎйqЉcЛrEfС‰hђуЩIT&&№мфO№в‹/ТщйqкNfѓЫd”D"Ю’*ыѕ‚™uSв-5йЊ‹Йй98Жg Ы$Ы—‡"NЅгxъдSјљ/$eі­3gvЫЅr37\0\‘ІЄЈв3мкїЕ!ъЈЇвrиД#мž^A>нDжФn bIDЉ—FwA:Є‰ьУGŽрёЧC6›‰змZ №Л?ЗсCH&9ДэT%<ЫHу+FnѕNvBЧђ№^М9g ,‹Iƒ€Ѕ‹ФŽƒ4ЉЭKв‘r9.%ЃчЫгTvkЃЅ$Hњ(dи­B^§+›џЫGм–sО6ГЯ#W•s˜jсвV]Н*яZœ…$р;ѕиXъЅтї—:јћ‚ŠтЈ…L0Уt5МpѕКЭН /љЖ?еЏ6ˆˆЌ7^ФХ;eœUЧв†—JъЁэdЂЊƒ!ПWIшsкИ|С*f‘р TзFш‡3дi^xзy2њБЋ'YС<+Ц“њŽьY ŒДWqфРCћ4Œ5д[ џІњ_ПщЦFqгУ0† ЪŠ:ЎчЂПеYщwzЯМrю/Пчd|рФєчyСњ)+šћy1CЛ–ўкТFaЋ‹АзЇГЦƒBѕgzz6…бCЙш%мщСяй+NЧўбХГ‡_Ичё+ЏвЃг'•Мљкђ'X)GнT7–DёiJџ9ЃџЫш J–“ћ§ЎдєZдwžћгЏ_ИяџŽ7Œr|р$Д/3•R3ip" Iр6l@o‰РE^ѓiP+тб< Yšs}ИњпxЪџzя’Ž<4M9NЧгУДtœідАiЄј‚eˆY=Соф\Йtх7œПЮхмя*ŽЅIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/failover-cluster-group_25.png0000644000175000017500000000256411733011756025556 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкДUklUўюЬюЬNйэvлmYZaV@Ќ`‚ Ц"‰ j№—&ŠЏD‰„№‹DbŒ1СФ„ФёФT$†јт  ЁІCв––юnЛГЛѓžЙž;гVŠ1AФ;9sgцNЮwПsОs.уœужŒƒ н’dЉ‰99БP•pы†LVG–&k~gWwзЖэ?u‰ч[ "|MВЩ8Ž]Џˆя™џD!3M zEпS1qO?ф л§'„dBУЬ†LhЙ†&d2№=O,i!HKКыжЎУь†йшђИ 7p`ћ,п‚а˜p8Y`С…Й№%\і0I5ЌІЂIShŽatЗ MгТ\… ™d#Zы[pOѕРшўЇvиМі9ьШЅС™€чф”дб,бЛ/тФшЦx0&q0zw]uuuЁиЄ3БsБ(цН{СXоp?wmџЬfpа_>ŠПzА].…Ђe#MqсXрD&cl:ˆэйсOб §qŠgр†oуН6,R‹EЛlГ+†~&V’ц‘39 ",b42YƒS –o†ОЃU@цG ‰1rž "• 2Ћуг№!YЃVCytчѓпNХˆщš!‘ƒ [жLЫIБл‚у9(зЦQ6ЪЈ_UCя@• IР4‰‡m“du==gaЖЂZU`Zжu ž&эЦ$‚'7ЁвgCm`јUXЩ"*~ К?Žў}ђŽŒG3 xad9Д+лa]<EA–РЮ~> жc`РИ.\žхDФ™ТЂUQЈP3ЋhZd]lš3/&УŒѕЭ№+ЃˆѓвЉЅр–N9№сГKf.ьХ†Й$ЄНKІх„Qнъn …мUи3k”c‡єџр"Зx>GмӘQ‚у–б–U!56бО(— Жa#yрLшѓВIўс‹—Ї@п†OEuEПŒšGэ@іCѕ’‡І5>.GЪ"†Vџ)ф7oХЏm ћШcЂxч\tЎXЁvFО:ц"Ль м“ž‘^Т5V-ЁdЅ№ъ‚HззCQU>е‚яћ‘;'$yhИkcў6rHb<о…Ц?Са™(ЯiFюіхh_ў0˜’РHwї_9†s„кHоТ7{„ЮdYІ~ C’$Фc1(qJBХ§Bс–!4KJЗ0ыŽ@ћvєНї&к>ˆ–…Д[”ƒРЙF]•ЯА|Оќњ+^#­‹тŠХcАuzl;a“ ЁbФa‘ГtZjzZŠЋр ™}„ХјНЇgЊHt…Н‡˜Ш’ѕrбЄЊTЇf%!wМ„ъЙгQg8нЅж/Z5лJЁTиЦпA~9qГfхL&i“eќгСЬIо‚qБеОГh‡пНё’\:yZЎ uѓƒЙіoЯјо-*ЯоЗЕKчк˜EъЖ<}мЪем­ъЌ6<сжAМ84Щ јЧ Чо+žлж>"zz”hБцкLMЅ ЄуЪБУ %бu3 б6Ÿ7ЕlмПo™ј6ѓЎЛЃу‚Т8r*’-Kh{Г;vgV?оu3с чРsтЄN)ЇУ/MЎ35ё~МЅѕУќ+oїIк смПQз€LЧпRL3IОЊЕwžЫoнi]svё?5€ї$;ИIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/blank_2x16.png0000644000175000017500000000017711733011756022475 0ustar sylvestresylvestre‰PNG  IHDR<ЈЎДbKGDџџџ НЇ“ pHYs  вн~ќtIMEв МB IDATxc`\јб)IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/tag_16.png0000644000175000017500000000140511733011756021702 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЇIDATxк|“{HSqЧПw›wюњB䉉–Є0fKВ—e"$hD$a aІI–Q Rє_0{‚КђбŠPўс#0 2-СHџpM3•љh)щœ9ѓ1эзЙВЩѕРчўюНчœя9їw‡ы:ХaлIЄИ8DЬ…DшŒЋuBцОYk†tЩг-gd 1 œT№ЧTы›ѕгГчќЬ#rŸ 2Ф8Щze)99ђЪЋ,>d+7ёІЬБKS™Nѓbњ’|ъ8…ЄQ UлwscЯЏAК№“я+~ЎьzOvhwXц]еЖЂz_ŠIXW€Њ_ŽбЖЋ­є№ їA FXк0љN' N-ˆЕРЩxЮеХjJІхsўƒЕЙj8/9‰ЈК7 vуKŒRWі_пХ№Dё"[гРCuЕ9Р\‘ хxHъ”б3ž—CўgN… ŠШЫѕVu@еїGфщгg­р‡сЋЧ{Šх•q2X:{ œЦžЕћаnЦ_з‡ЁiVЗЏФИsПЭ]†+ъPЊ|д-Љk•Šfa'@h\EM ‘ЄRшбzlOтЪ•~$“I< Іёнф)ˆВ™‰\й’ьKѓSсFЙY‰јrД{{"“Щ џј дз7 ŸЯЃwчлИe BR8ЉќC.4еE^/‹r‡˜F•[бжСtmщ Ўўrл:;бОc fCT|ˆƒ$ 9Š|У–я%I§ŸHм˜фQŠwсь†ЫИ§г]Ќл’РЕз‘Ъ€ЩœP)їо%пБTЌцOчюъEs@›ГРeОф€md…џбёњF№†Є’:*фхfюpј89qЂbхј‘зщљєЯбfє,‹3ШєMLђ!•H rЪеЯ=рЩMŽйyŠ^ЂbхХЭeјЉСбъ6ЌjBБчŠЖVЎ—€їyбжp€€ч_ж•Aіl%‡э&НЗшl%m‘.Ц(~Ї8GрщХїŸ 0§юˆЄU<шчIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ip_64.png0000644000175000017500000001241311733011756023201 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<­IDATxкд[ pevўК{zNнвX—хCЖ1ОА—У&› Х‚C…Ѓ8Š%€a!ЩR•–­Ѕ’"ЕЉ"ЛЫfйьН›ЅbŽ=XАc‚1) ˜cmc| ВeI–d]–f4šбtЯбGоыПeЩђŒ|”$WКєзєLŸяњоїоџKВmлРOcgп$ ДI’tAзб{OШѓeW~п7ЯhІёВЛ?ZјЇiчКГwЂqЦVпІ1†Ÿ†„Iо$W“ыšКŒw~ПKGР+AѕHPH5Вћјкr7­єtЋЊ:‡ЮзG]tулњМгq 6ІtJ2РВlgпВ“FжДa˜pяgВ4HќЌЪRХA ы†-ЮVIГѕœ8)Fp#љБА агГт\ЖvŒЌ­S\Пѕж[Ў[Зю–5kж\]__П: ­№zН—пvѓѕыолјшњyЧўgыЗKБЈN=УђЃЧžІ,цЮћ.i›x`•r,g$aСTVЄ'vaUЅпhЫqНЩЪJ2Вglч=cЛюOзгО,Ы‘Hd_CCCзhЫБЋяиБуCк}ўШ‘#пјўНѕOпќ§Xоmь2pХв2ЮAкФ+РЉ(ы‚жPJ V@Ш'Г˜9Ў7и•ћу#ТЇяц~“СЭДZZZŒQТлЃˆ џž e|—є{їТщъb4зж5`ƒј@uŽT<1 `СO XNЊbЁй9e9о`:+ю21VЁ:{Я0сс3T* ЎЋiš'Г:>). wЯƒѓќ;БC>ЊNŽшХ{-Цщ‚ŒГeиЭy˜У"JBЩ)tЮƒБЪ„HŠ"х=цжђф`ЅГdVd~i›S’"і%9oMb9ЉSєйzTйшфtѓœоc5чкЃН)/Ÿ&Ї.IƒЎЫц$ї“–сsO/uGі—џѓ@Юјзв‡Iј_>ГMsxAОИbŽЄMчЌвѓUПl>-чГЪ№1х,Vыээ}|кДвБ§†e4fэ1—ўЫ є™ї>М]ZуСО­MGi759Е€„ќ$ЗљЎлпn@šyэЭm_а—/NяЃН&КbšzЭS —oЋ.–БИbpшКo~sл96n.РЦБє8рЫwнСІ3Ц>хьБ§ѕu~МљцkЛiї }вB Ÿ *уx€2rOФЖМNС,ЅЉчІ{я§г‰lЧsHуИ'“•Щ~nXСwo т?оЖнmН NZрœ­\@ тc“сЗ-їтО5^ќvуЏ7?ёФ?ЅŸк'књc"И ,ƒВ]ПРCCEwУі†ЏнљыWЖlйТепБ‰Ž§мi0_Œƒв8YрВЫjЯKнsјsзЎ]‡_јс–Я>ћьœ,hєИ {вЧБА2`“џИЇЄЄ$J%p&п=6m§ !шЫž|’‘žSФ§д&šј\^ АRYјѕыз‹Оіѓ,dfд˜TЁЯ›œхчЎхћОњ\В'з9л6„FxѕсWeдЌ№"X.Iў"УўЭ:W§} тm‡C/< K Уфі2нђпfGGяsvж|^ZДИ^EРќ;€†ч-яPс,ч шД§g6—L|}й9e ХWПŠ—ѓ}?Н“ОЂ[aХ@O{Š‚тщЋрtp0КУkЛэTщA№yРша9WА7нs:w>„tз TЎŠй>ѓ >{эO8Жљv 6жA% Њ^! Ѕъ-{tуkˆžŒ#8ыy>‰цVЁ­7€Ї%О^T•ARŠІ‹>§czЮХвђ8˜ВлХЭвYяmo^':ЏB_уШЖ­Dє бН@4і$єФ›8ДmBгk2pkRтЉ(Њ3ќŠф‘Єjєє>€ П2е ‡WЃ­3еГ х5џ…KЛQVФZ ]’gXbRгрhНхїi Lы{аЃKАјf r`ч/‰іD–ЁМpЊТ>Tев›’[ЧЃм ї8Ъ* !™&),5-m0@QгЄВiBd$•-(д,”I й' ШH„ђz@ю{ќqЭЇ^ u_…ЎnР`ёz”Ю›‡хЗ+˜q#Н$Yiб~ мЊ TЊ XТB.<ШYwтТ ƒ …ФДBТ‚bЭб7{а„m" YщеR,тE€с+~]фcЌгŸžђYњlїИ”чZŸяRЈИеU•ЈКX№užj’T№-ћG:ЇWьkнT4ЉЄуіŽг! ЧД”Pэ#ц‡н3$:ЏЌyг Hбј*ћdлƒЖZв(g<­№zŒБ@(ѕ€\cМ5 вИзIgxŠу G6kUяEЈf…•€ПТ™!с т>ВЖN‰@ы }тC2й)Dž@^э?†tбМфя§є}0‰;JЄЙЬЙЎЅѓЛЏбп~§n+Ѕљ*Ё”'кЄ<pЗѕsыw{кНяMёћ Ћ˜™@aЙѕŽАРS(Ќn’Аz?)„Ј„JJ№Ея:IыUFR*CЊ#o(ђdжСl…7ЙGŽЖGa‡_†99NK gЭчЙŽЩч €3ЮйєB%*ЫКQWЅ“рŽрЖ)œв[$ђkzgШв 0Щ<АсRR)A#O99gЎ]Ѕs}юЈ+ЁбwАCЎВHївlЋЃѓ.єє5JІОCЪЁ€ус „[цч†j>Жуяsї|ЬЁзЮPж.ЈШ]Ї,(—ёЪЫЛ0ќœбURф›с‘ўЫОRŽХп 7!’c’Ј„ ЙЛі)•B/ЭŸS9Da"з­šL_ачњL:(3ћ ђ<]BD‰=Ђ~/ѕУH)ЉіСzŠ˜EО,vјs) онzЩ ŸђhGGGXгДгf_Z{zzyф‘—xgЌцШ=ЁBэфŠh4ZlЦi|хЛ<ѕдSЏq)ћЂђx:ін‰c_мˆDЊѕе3АlUцпGMж–мhп ћ“—aj†б Г`d|Ѓiђœ(ф—Uц•н1!ЌуrєЩ3: ,8>ŸЎ, 7Ті5*Ц`n ˜3gзмпrчоЦЮОXnIškхккZnU1Ёїх˜Д`Ÿж›о{%Еѕtя{ WЎœсЄЖ№rrз(^‰Єи– Žѕо­ЯТњИЯz…фрul2†2№Ш2(­#ЫxЗг ˆьe,Qˆьч'HЅx†7-Bяњ,ћyаvий<ѓbzJ?пЦ]fœЕUubяƒhнџНXОє4PЖ@ь,AaЫˆјŽ4Л~Ћ™ЌL&‹)zIї&УЩт 1 Єkтє%х>вЇ `ŠЬ ря >ƒCфItNqАEЅП@wы.Јє[љЌќY`вЖулgAя­D§uЪ—аS]”fwgБ4‘ўZ6ћ›yщЄRM&aЖRрљГyЏН—‚Ај‚М$MЮЈ еŒXаРJхе+Ш§MK•b њe„BВЧЂёд( e'бк9#œ8ЋЯЛ‰Я(Z+1РД)pŸЫР –ч…MЯuccёп*HvKа'Сb‚ёЕ>7bY`<эЎжђ“xšQŠюўћь*дJЉРП#щн7КЗ85 ˜О†h­ь@„=<‹j ^ЏЈ“uЩЂ…Њxёˆюx‚wE­†ХзFЈU1p$„О§$њRКKє Фч4ШzфЕ8 ˆŒ )ЫЙНФ=ЏTdыџЊюэїT."v5ВдOžЬО-IdХТюя‡ОOёй*и ЮУ"ЋХ˜юІEКѓЊТšЄеkmщВлKPw]ў2/D‚"н"mЊJi—+Œ,Oу)nлQ ќ2œ•Ÿ)3ˆуЭwуШŽsSсЩмЪ.ћ u?ол“ЦЋ?КоСЉЉgЫAцт\хQхы„…‡F1СЙЗћ 4C05њIC’SeмњžїYxй]кЪоРiБА@Ё’йуЬо(!Ђс=‰"||xнд+@R~Š`н§˜=s#ІWu˜/GЫŠ ІьБЫ– ’5е”ыW)”*%xџ;N~&cў5фўф Bљ’N+Ѓ`60ы+$0•Р‘ˆШэqBљ§?ƒё_бuЄАіНТѕй“<^ Џ й(мQЧ‡ИВЬ ЏJ“jB&fеwLН|оП&*ї‘’XКAB)!юаАѕ-7и+ТЋkн{(Яwч0аЭМVахe'yI‚jƒ’*СŽX1ХЄаAЊ{ћІн29A#c95‚Х<6ъ“Ыъ^šzЈіc˜ЕИKю—PЙF4>в‚њВјгit’5KˆчћI *:/K0CЉQ-тхX$P‡К2^uKPФdR쁘0ЁŸЮэзM;mХЅp(CŠWа3Ѕ’В-„'Ї^ŠQњ/3n–Ю’PfJ06ƒ•  EЄ A‰UЂˆъ+%Š$&IM"цKЈ`žяШЯБоIЉiјўЊjЖYšЕI*.m‘ыf†фdCўТP^к|@/šе„АУ}tЎrœјO‰>Ÿ“Xрˆдщh"[А х …pњ=u;1’Рум,1‡8AЧТХ*УлэhзK’ЎŸ єа- К^sž3х (Њ№ЅHvЩ‘ћЦŽRŒПKЌ€ЛР\dв#эcі gЅ–"„W дdП№V€г8Бм>‰р%љbYXŒјКmK jфхЗў‡rХ'ˆSV‰PйœІ{r14fŽujP2ї%$b7Ёх•zT,•№9‘БƒЛЅTдпHŠ˜.М€іpЩЧlАиэИ щрE ЇЪYVs/)fv%ьL7ЌiŽ$K. ЗyЎo”lКwћ›Рюyч–Ї( „_EпgРО­w’ЫOCO\rјКЖ‹,JBЭџKЄЬЕ”АЎЬVї яpўeEЅ3у—ЮВt]xCI)фЪЄx†sО‚hч"4Оў%dДƒ№Ѕ4TЭšКDКМ( Pќ‘ qЛГ?–ъвWz фjЕ”Э дП’Ю 0ШqœЇЂЂ+мOЈ“ы‡чP† p”Нnv ˆaрџ9№K‘bККfурц{Јш@ˆъьtZ!Pь”+ HеI(ѕ)qвOгŒaUЅе%Еwи‰цЛˆЄ,—R1е™a—gЗцqђb…ŸŠšџH—hu-!ДПt%…L НЙлœb.#%ileїu::fС–Nш8ЪrYџPлEPИЩT)›э#Ыm“цޘK|џRеЉN”’‚щqъk"ЖЗЇ…^\3Eп@ѕ@…JХ‘5z)ru˜U U‘gƒ"E—+*>#єOžжн ЂдАИњb(€ ёqJD№Цщ-eЯIјHEa…uТ­в˜pЙ>Їа _KѕmмŒЃНЧFбўєї Ћ—ччзpДБЄВEЏб§_%Ѕ 8€:ќ|f‡CњEђSєяеJ=YБtZШБ,ш@“ŸиŸ„ ЅHЌдuDЌпЏ+нž8wD­$‚иSŽриБЕhmŸCчЁиЏ8SчzЦ@Рп"/От7ФџŽЎCšЃ˜с>хbHvч.Š4RБС?ПžJ\"5š4Hџ:ZпЋХћ[WaЦ,*ыJЁGe4З‹ў~а'вc‚*УŠр’9яяп‰dl3BС ‡kQО]эхФ>GEхFиЪA*&Дœ+C.Z<хT›W/&ыгАщ%НЛ“У+Q‘-AKуДŸЈGœ‚О8X‹ђPQBЭi%ЪЇН`љ?Tu:mНPбЛV,…в3@ю3K‡сзEcє|зM>њЩТš:Qн ЁЖŸЪ4•’К?љЙю‡PIзеђ>:#sQреQRђ CЋб;  –тzњŠџEл€гыLˆўbQJя€БŽeЮqОЋщЄ‰њ'фџЏлџ 0До§м(_H IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/self_25.png0000644000175000017500000000164311733011756022064 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<EIDATxкьVЯkTWўЮНofо›$ŠбдЄёGЛ$і‡+!4`ЅK7нvзџ@џ]дmџ ‚Ћ‚Ыn\tQ‚ P,SHL$QŒб ™q’™8яолямї&NJa@)Х 'УЛяня;чћЮy/BРЛ^яa§H’A]ž’kќ9ЭјL1Rc˜юV5XmЦUЦХцТ`$\п1Њ ;‘ ъDЉ[Aj!ќЙс3оЛP† JЦSБЯ:OѕŠA…ЅЄ‰ K І †ЋПЏn .WeД*P]_†ЇJ: ‘нžPуxЁњэСKу™TЊінУЃОW&ЉќППoE~ўёKѓyГЏ‡‹™•i*юН9V—ъЁš`fЬbЃАМљ6ЁлOZШyЙэ<њgл–еD’,СZЧ…„оY#ГARk>ЪЌ 8HuЎсБМЕƒx\ЌQ˜5З;ЙЧЉCіе’ш‘>iЄЏ’ЎC:YзЪ!ылmЇYxT#ЁР1==tюуааJbФ“FKvМСsјmЅ…Ѓ#•ш/ЫёнЦЬЊЬ)ЩљЩ$іT[eјЋщ0ЛкХё![—Ъ‡Єj PЭ\ZчРМhчhl;œы‘Јtьq‚rpxaz›Сƒ­[N˜•ЂЂœ,ЯЖVлыŒfзЧ§›KЭH&Eь6ОЦSяQŽWˆ–№ї|4xўur}Ёѕ;Ц"ЮЦJ˜НУЩП>6•Гзa [ђЬ‰хQа.QюПђ;@šUJДЃu8СRЫсћYЁНV уйxйqБЃ3Sўі*љBСП9œФ]рфˆр“aƒЩLтa=š{AЫ‘фЁƒЖuЎц‰UЋДš”’БЩpwuo˜03Ÿ)IщЭ”цi_ŸLэзŽ*25Ё0XЅЉ'ЅСм{Щ—дтkОV(чˆрo]xоŽ­ЁўшUrOя+v†”š,$в7ЧB“€›OЪќiОгџШupГeмЙ2Vњ§ќо˜ЖaЉхё)%&эs"ПрМ0Iє%Ј™­1ю2~U@‚Ээљ{ђ схл#6Јсq’ZŒ%Ц-Ц/evэA?Zђс‰џЩп uu`FрPIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/pipe_25.png0000644000175000017500000000216211733011756022065 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкфV[hUўЮ\’Н_’lК›Ў t›R/ !>XыЄE‹њ$ ЂЈјдDСk|)}SЁј,TЁи ЖM%­„цjL›l’nЖIvЗЛ;{›ййџ3Л‘m,­к ‚3|3Г{цџОѓџчћЯ.Г, џі!мF,kс–‡є‰Yл ‚еТэ‰М§ю;ћ=nїЗЫЕЯсt8:‹Ќ ЕZэЛз_}эФ o ŸъээХ]бэ‚eyІi{~Л4џ2 wм,щ/”ЧмНkЖ‘HO(ПпZMУb"‡•+Щ;З&н]]‘wуккRЉffgАДœрУц-Ых<иqУAѕˆЮhŒїŸ‹жІa@е4‚Š*AзыЖH;Хн<“­/абGXЖ§Ю ЪD#ђbЉЕRХˆ|#ОEqŸЖХX7ь>kŽжw›ƒЮ`(3<:ђ0 Ъ‚м„rЙŒjЅ‚ЯrŸРх•Тp›­…-ofв"чЯ-ЇlО,ЧŒїЛx Ю. /КЁcCY‡Ђс &бШЂЬkцo›ёѕушіtуоиіэ| ћwУ!9‘(,PБM‚@W5SCЂx ?­ЦфЦJJd'~|сЌэBŽЁЁ!/#;Pх[UUm‹њtШВMєбЉёмрГpuИБRXBБЎи"Э+?(5 8Ÿ>‡_ђћHМЗ‚t:‹S“(‹q^ІчEQD.ŸGWwЗэ .РёPl/4Ѓ†Ќ’СXrд&ЌгйМъtз›wV‡!4ѕю€щ*RYjКŸзK№=-еыѕGxЉЋ)D"И\.І Y’pfў Рщх“˜ЯЯС`,В pRЌa6EУ+T d2фiв€Ж Р^‰іdГYътuЌІVQ!kJ$РMјхичшщ}?,}o“A$гˆм&&‰б2ЪС“Јў&=гНЊ‹˜ 2qЛЧvЦрѓљ,‰ ЕƒeЛЖmЉ>O(ЁŠBЬrо7bŒ‡Чт›7'КЮ•упR\зЭыЉ!~Њ)Эў€o1LГгTЖ`uyРVй0%dЇќ?ђ/€кPUй !%`™ЪНКtЬПєхнo~Ы(№Ъ`E…НEcinХŒ?CЪрЅоЧ“юtDŽГоjOЋЛB•\š ГŽ€З_rFп$џ=-Сѓ„ ncн‰­чDѓўЦ‡ў€йpЖлЗPэP•РхЅПЦбeŸ˜ЯЯXо??-ЊЩш№Рбwз=Ы}GЙ™;У­ў„ЙяЗ ЈвГћ/€2@ї2DGуO7Д­<лщНDlтbњ'Єцjсѕзbц‘˜ьšћ'кEљ№PШеЪt7…ъbL/“ДшФnЌ?АмІ>гƒ ”эt4(мО&Ю<h6œћ8й;3,l‘Ш% CЃяЇFЪŠ‰‰ŽБ}[aцЁІ|ЌЅžNЉи’Ін ОZЙ-wm9‘лћ?™WWnbсЪƒииVžћАюЅЊЦЈkЭŽ :ѕХ…LТЬ…ь%›їPЇd‘žŸЧф@Щ))ћ+_wя:™ІоЈš KžYŠ™ЏGРDO?Њ—5 й„К& иЂРH5J0рѓKд,‚0…9[xqЁ ѕыЖУу’уђ@т@>”ф›˜њ#FО,ZїкQШDnйНОгRфYЛйš•В‹€jAV<žPWl{U9H є˜№˜Ь 2SЛHz[DУІ0If–Њ.=Jт“šм=œ-tœ‚Аэ_Iза|ќ8"c‡ф•‚—кЁWДР[9€llЅ"~ 0г>D.О§!УIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/back_32.png0000644000175000017500000000132211733011756022023 0ustar sylvestresylvestre‰PNG  IHDR DЄŠЦgAMAЏШ7ŠщtEXtSoftwareAdobe ImageReadyqЩe<`PLTETУˆEЛ‚9ŘdЫГ™хsІЛЉяЄ{зW‘Њˆн–iЏf™ЅŠГУЛѕk ЊЊЊz)­ЗИЖv!ЉБЄЙ~7Єh›pЃ}.Аm `–y&ЌЗЖРžqб~0Бz-Ђnz tRNSџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ\\эЬIDATxкb'ˆ‡ИИ,„@иH Ш2AVRRтLŒŒ6@aQР*дЯШ• bЌB`§ P€BUРЭ‡g†ЊQ  љPyЈ€BRР-*!ГŸYFFHB‚U^ €в|ѓ™Рњeийй9YЄхЂ€›!Я•чdaaу•– ˜ˆ<Ь~ Ј;D98$yф9=€м"ЧССЧ*VСТђ„š`€nхрed`кЪ/(@шiьQnI!F Д  <@aІj~a~.In 1~~ €Ах  [xф8$! {ЮЛЂ €pхM С ˆPю ‚  ŽЄSјHАћ—IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/deny_64.png0000644000175000017500000001411311733011756022071 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<эIDATxкФ[kЌ]еqžЕі>я{юНОЦБСv0и˜"РЄMдR (M "4jVа6qƒ Ё•‚’TЊЊќhhеђƒђ ЁR) Є…@!4i@jZРŽm66~€_їњм{о{­ЮЬšѕ87< XЩ5›}Ю>ћьНgц›™ofжQжZ8 З З2nйг–§фoўњФщ—^<Ё?3sь`nюш~ЋЕФ ‹p›0Уaнš№кЖ(Xc^ЧяlЅ^жYЖБмў’џ{с9=TqЋ§јЋWДoУњsњ~|иэ~Dч9(ЗВЪ Ђ””Ц/(ШQр\gPЊ”Y)EЏ нV КГЁлыCЇл6*Ёƒђ#Jx#Х)Ѕ~ŒїњaVЋ=pйћзEМWѕkИеŸўЋЏ}dџЦ_œ?…§ F‹’ЕЋ(`Х8Јрщ ЅјYо’•CoQlё^,n0шуО‹[ц†}hсБƒјљ4TЫlFeм‹їКgнєьѓяG ‡Њї\|ЛњђОП|гнw]Œа§ ZqUVЉ@ЗzV‚ЊUx зІ‡&щЕ{x|T _ѓ{ВЌWnК@‹їћhu:Хoѕ:Ј„>ьGЭ‰‹рХžУэŽњтХЗ_КѕЕ§яE ‡Њячdѕц_Оќьй;.С§x^ЏC­VG?аPз9”вJ“И^(Јu–#ЁxOязCЇ(ќ\YQЪ€ЮХЯфЈ„ЂЂпCщТоnі ’Z§ЛРї7Й3xьн*сP@HЎу6ѕшкKПдйЛчJѕЦвЪXЅ*дапs~Д,Д”‚€D@Џœ2РаэAуQУя)•(8ЙэЭlкЈŒн+v!*њM/тЏЛВW\џn”№v PВь'З<јРЪяПoЙ?.5›jЌ9c• &ч‡х?†Й{p+BУ<СMЂ>ЦТ“„аAзбжЙ _]‚aPpл%Tt`/КЦŽоі!"№~єџ€ЈМfнжžУЁВ|c§woћаіЧt%>јЇ+“аЌTaЌжрHŽауHЮJgј†ДЗ,[]ЂxVŽyt„x€чkй3zŒS€5ђкHФ Іг…юаFсЗЗл№jЗЯчс3}Гае—З:ЏОоN$ќф†;n_ГуЉЇЎ*†УO6ІІ`|lœЂ4GXЗV"Є–eм…є.рAЏI8мЁЩ| Hƒ%+У:4Xс@tmr D2Hˆˆ-э.єај§лГrљЈ„­ямо*р5Ж<єрЪзžќЯ+‘|ВБ`L4š {].чљn9žЎULє?џояCPˆ~EџSѓи”O•Z>pЧм‰| яЃ3ЭDJcж„3мŽЉзрјZјžћghЏпА ЙшэПХ1Šі 1е]Ž9wlёGШзKЧмш!9вћ\0QU‚7ѕИSIТцs@Ђ'Ј/vrџ)AšіЧcЄ@з2™‚хрRюІNКУb-tЛ№азо њO\БюВўlыѓеЉ…01> cѕшЊS€FЫљ§ШгGЋЮПЗє/ ћ&ˆРЋWљѓіЏвуЈ~&|ЖQ › XŽйieНТdЫsеЕ•ьŠwЃ€ъг_џъй§ћ.ЊLNЊ&^Дž#ї!ШKŽOЁ8eћЮL*uƒTxКц›ш3РBЉDhН'ЙЛd]]Љ2лЈСЪj‰” ё”+Ўoж>ѕv PтїcэW ЩЙ+БЃš ЂхЧ€щmP€ŸЖ. YЩЪ1 ЌJ6№{>ЭŽЉиkq *‹…Жѓо'ё€•ІœУpL*Ѓ№HЩ0dŽA%,FЅр37ьїПxуТ‰ЉЗSQмцЦЛўхbЄЄЇWЧЧ1ееёК%3/ИMŸW•*!?*œcƒ™,D%јzРKFBК<%VI  ‡M…і ŒJftЂ"4Rr…VнbE%‡Вця|n0;ћ…ЗRэыЯў§еП…~^y|Dos†Ш"V‚’ž|{(сN™ф)­A”rКQžXY”эм-ЂЦ4$йРЦрСзІятsы2*ЁZ…ЅЕ2+Aў.ЙЎQ99YZЫ7іoкјйЌT>І†ЏŽˆ~я‹Ÿ›…єЗљЂ†IˆWŒТћ…ЗgЃќH ”sŽЂSЋуч: _G'ш PРЎWqkРŠБL”8hŸ‚YэТљ ѕ”žљЛožŒ%э'rєЁj–CV8і tƒАС™рћ6 ТDIƒ#Sfb+ L TJ(ЕR6ZеЧяїёШЧŠ%ШphФЌR‚ TЦ)+ИЬuС š'І р†Цў ыЯAЭ-Ћ`ОЏх%їдЦYŠшmZД8†7ЊfqЁˆ‘яљŽ”М|Ь+С‰ЋDАi№єU*РУЧ?т!.68NЂ•”HЌRЛЊжAaVXоЈТd…9ЬёEПžП%) ЖыПКАw№рщ9њ A?ЯЄРс†EЌЮЯ/œ^‰а6БІ 1СYжїшzЮњ3 јР(ж#‹’0љА>„дЂЉИv Тx ‘,e(з8Ђр(T)ЙС9п^ЖЄNJЈН№[Я,zНS2Lwe€ЄВ Т‹5ЂпЧ8P8с БМИ‰ЗМCФђJтƒW†ж>(б‹tЌsq†9]Я[?со5FИ!gЦЈPјЃ*—*W{Fozњ,Џ€:жїПЭЌюЪТOйŸC3Œœ/t|Q#аwяEIЦU„ЊилТ!€!˜ВфЕі№ш|YЙJл‡Jж‚ŽшQ"Єќ@іZ“ЛX ЫUјf„%ŽбЭЮ ЭСмм‡шфВ`QJxэќпЁливбё0ЗфЯIf`Ыгq№qƒ,YPM„~aƒuAwќ@вр”%&ЧДЗ|Ш0т.руYj$J 7 ю4РiŒ€чoЙљ„џItАdcр2ЁЎ— kp_Юк n3С=”Xп)Щ#РЗII’‚‚эЮ™Oе(ћƒOШl\Œ%Š m*uЄT\JcZ$NC Р`ˆe2)№ЃЗЎ<њдќРцЭЧ#Эеe<‰@жЮ чЊ Kоa$8Z“ФŠШРzИєщОgBеЧOIŸгЃйё)’љXЁиMќWИIЂШUtЌ1љЩr\iq bГ "˜*чАw0Шљ'ч}{WO”МъY8Вžг м;0З`=/8ЃzX‰јў‘"{6ш:Ф,IЗžЈˆ o8ќ+д+Ћ~ЉV|‘i2^QNuЭ$*`йсёљ еZFЏJжiЯA\;Ћ‹uјЃ4?ћ\^8Ву§œЌ­ј˜•V— AQЭЃЯ–ёыОЯЃћ8sЛ@iгHˆDтCЉN‰Сд<Ž `Д€тX!Х`JœЌѕ ЅШељАл]L˜GТh~45ЏЙс•`Нп‚ьвW`Ѕчdђ­,A‡є"Ќ/–М%m№aп i‘Ј0c ЅF:*ёTž\b фаЌ!Cь ЫѓЂл]HпЮД]]PpЃ3aБAx+˜4-|фїˆ`aСѕњХU‚ЫЅyz+хnr]-ЄS’Š|СК@g9рyйPIшЄПІЄmфмСЫ%.„.€U2ф5К™>2Чт I~QЦ<Щ№*&7Џ9amRўoH6ЄM &>яBтЦѓЪ>ћPЫ\KqШ}ж}ІT@'ƒ_;:cЅŠdЄeœ&b@ юрыDA Г@yHt&sДv=Ук9ЇўОП1шžО'ьЬB†м!Є6~hї№EŒшС…Ј­нчўОKГї…>ю 75ЖCчŠЦИnrp?oEцў–#;ЧDЋ!кЋХт„оЬэ­­%`вЬ žз2zОzNЃъ -a№ц ыšVЉ4…2дJwш1AIпяYxу!Є№ЌЏЖпMТ’Х 7ЄŒЂ™YJЂзОлЄќљНЖЮтЄ4Г`ž'„p“”ц,ИД№xŸЛ8Ь+76ЧЈпFR36ФЃTHЕД mЏДs „љЙЦx_ОюQс‡Ъ“%T0Џ lаы8*эІ8ьяVцL}CYm\,ЬBXa|ž1f:F}фŠbe#ЯedвфЉЁŽ9В›ї зцй&LїggЧњ•Ўšи‚вћѓаw>явVheI>їJQОc„аVdщ~-ны9ˆгlћЩWћ|вёе‚=Ўш’юoш2ёDЪЃƒ^иdў Єѓ„џ†‚cZшкєл†§tŽп(кэeНъ,7Œ’jэH'з2ыRRюЊрЃPБ. KS›‚ ?РщK1еm1rпчГIK\IPЛч HaЄАЮwOh`7ТШwG8еr\Œ4з7nŠА›"пSюбLЁ2јp}џЄuЫ†6’њђ8uMЇ‹С­я:єЛЁ:ŒdHŠыІ(ьЮЁ”ŒAtЌj”јМђbыŽ9"”4JјН mN? ‡@–ДЛЂaV*MЌvфјтeZ@ЫR ЊQFІ[vЄ01№mЄO@œСњеduc“Е{юQШ•’JЯwz@ъ52P>­Š№WY€7{eЈњtЈљКr~ Р ‚]]сT@K”žWЋ[А *o&8tP ІдCЈ#Dщ#Ц€ДwюЉoA>оыѓfPhЭС­\AЅФЩwг™ŸMшЋpuЅb™ы_‡Fgш…Љб~ kЬrц_фŒIЇЅfѓХМОhбѓ­mЏэ~7ы Ah’—нЪ­€~ст§1G[MгŒž,оq0Бъ ƒdФeEP65=LК9ZХ^_l‘ChŽИр(№—4ЈНјй€/ М›њŠџл‡9ЭЩЦу+Vl ёјиЗ–ё˜Юђ-­СтЩIШ  Ѕ/рo.щŠR›!Ё1Њ[‰ю4ЂV… §;ЅчўДŸЇ…ХљйfHЎЅ{“yЫыЬQ^э&Я\кJРCэ -ОŽй8BKSИ’4NћMГјyЋGkŒžНtЫіпЯ]рW?-†ƒЕP %Œ€2Ї3]ЮCLЋ2`ЎћЖ+ƒюР†žъJYŠ{v–ЛR…~ОГ ЇЊ  YlxJ˜ ЂЫKZˆŠ‘FjL‰vЄ(Ђkя•X–•+?ЃHТ!жOГГбв]huк0ŽСа i­КЈ”й90sСЖ;‘ЈФ!HŸ3щ=дC№wOтu№iсј$њГ`™’|ЏCз7Ц-НB%ЎЇFP‚ сщЁЋYЊSOГь„€ЃNћнЧqџє#њ ЏбC!л(pЋfzЬЬ4(М!сiŽ5aЪ (RH24Бa -В$Ю/oƒ'Mœ`n.)Д–•”I‹иб]З@C†Жќ>ЁСY|MŠкdŽšж˜ў~vвЅ_|"(рмЛю™Х € ˜aјsс"ѕ~QHQdƒ кЏT:€TЁРRН iн]З%–оО’СGœzЋgЂ(Й (d˜ЫyS”2‹Тя8ы—GзЌ§R‹rbюЇ˜ўНЛoпŸДћНећкŽ"bDB}•ŽЎJЦ’ѓ'ЙD••Ÿй ƒА~Кcbg&іэ…šzŸжТў<уѓ%m:4ˆ‹ј ‘јь&'ј’@Ды‚™№•ЩUЋ"ыЗ~$R`D\ќq‚}˜жцzŽЗГ№ОЩ&9F"КM†&4OгС„VЉП'MMМ†іt7Yќр-щ‚›Ž–чeBzbqу­эз&ЛkИ BХнA Ј; зюCы?№щ{я_яW Ї+D,~x7-?CСїRŠу–З44S„ +ЗЄЛ nѓ§ў8нMrpввцЎ?[ц|]'б_kяЂў\G!СЛБжLіzžпчЉџkиbLї˜ћoœXЙђ>мќCщt§§кЏгТу;ЩOіP< К<ЃbуC|=п—П>ѕйД тЙ€ ­„)Ї8ЅCS3іўSтC>ь“Zи'сЃ›HCЛѕK6wћ][ЛФ\БмЛчмНїч;Kж\Жќvмп?@ыПŽљОы­отБЊвЩ’—р >%ЩyZЅ9й†8Р'Y *ЎB AаџгЃ0AЮч~ь5цPlEЫїА:Э*•‡W_xбxчО(рMIй?нАiŸЮѓ›/M# vQ‰ыЃМяаиб>ŸwйAЯ+D@šОˆv|_K]ПЖP…" s ”Zg"|Цуo'x.э/ŸВ€Š-Н^oїЉє}ЕБdЩmОђ/w‰ь›! ќ­›ž} /~FiГ QАг˜0єѓ;ЊnыFів щO%•ŠV1ƒ(› 8mDѓ!Щ‚ЅM™Ÿт] Ы:^AшПвAшїzІК`Сw>ѓo>šZўэ–ЩБЄWЬvЏЧ(ќdхэw&DzЇ•a#)ВaхИYВAYмШ” ’ђuэ{:&< ]$‘И _p(Š4šЎИ­oрЅй ‘Ы”ЧЧџљќGП ?шЊBи.OL\ƒћ[h9њ6Œ ЛЅЉЁG–­иъЌ_Р н#кб2ъR2ИД1KxЈ“њ>ЎдI Œ9??™gq пv$;›Qј67єћЛ;џsзтецњцPРŠXћкю=:ЫО‰інњі+ШЃЗvЮ*Ю tZz&q@Ыg^qк=дќ…Qю€ŽцЦ†NT\=6oс nЏ ˆчаjwIјя/;§ŒkN]wХіDxћnРOEЋ­‘|o|K№V›ћt“e0a)k:ЪRЄЭ8Ыr P ЮŸяыдЪЪwOŒ2&i/ўЕб=зЃезOЗaЎ5Kа{–ž~ЦеЇ§эе№у.Зояo†nXа<Тєћ_Сь№a!ТoyIУ‘Y NГћ&Pеnэ лBЊRŽр№1!4Ы/ЮБЩУHsy~Џ‰пlы`wЋУnзTЦЧo]ѕйѓЏ=хВudљЖoзЏЦє?еJ—уžЖуJјЫА[Šлdц›:,_LѓРТ яЂvц:;о%Н…еž’т˜ељзžрч-ЂЗф’!tК=њЁеЖъддmја#7ŠЯїо,шŽŸЭщы›Еп+†УЕ(шљ$l…"%‰[3SЧsІT–ЌK}ŸХ€гšНмGu5Œ^“nnЎw ‘HТjŸЮ=Ћ˜F7‰ 3ЌдЇ Э0ZЃ„‚QQ ЛhNХ'№rјšЖžjъмчй­„зм*рЪЂX*=СьBГ +фœЌ›oќ/0™ќл9уUЮœнkл%4pЌ JЌЌ яРжVEХк ’гЋАЖЮEТlхmП›gС›АŒљЋPѕѓіtА н`Rк)Fcёяlл™FPr+вЧg*w„€-RA}DХ№j:†#0Xјђ,”И 4NЉ šQ ƒ"‡bZЈу ъ›S№ъC0Š z іЫ{м_z~гї}]дe>тдюvМОюЖ^рЉVG9ѕд_nЌ=4я‹}кvЌхэиАЧ• Є‚сдфУе˜kyјтиy№,љ№Є“ц{:`9iSђ//мШЅ4Рruѓе5Зх7J‡!šЭ&І™у8рD““Д tмЛˆ цŸ VaЩ’XБ–KРёЃ{рYДVыHЧoв Ји^JEŠ"Žхb ђ|<‹Vё\ЫSƒ‹UФPqa™Ф^%Ћ юЏ‹œчy э‹М@Eъ=YДЈ(І’‰<НIфЭД\ЊЭЙ4зѓuЮ*˜' ЉЩЯяЊ˜чŒxэгˆ^э››ˆ{Ц:›•чћ$AѓiК›[IЁL}г[#§cq–ћYДћЛ1RЇгIЕVЃбˆimwgfJЅўАЄfV9M]ЧѕЭ-Œ$ЉШфщРeЗЫвЋŒ~?ю.EЋеVqц8њbщ4/ЮC6ЙЮ‰@Џї"ГhѕКб2MЕ0щж —Гф”'3H›z.fДэоСЌ ˆ$IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/outbound_64.png0000644000175000017500000000325311733011756022774 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<MIDATxкь[[k\UўЮ%sIf’6Iу4ев@ЏЖБ—HлŒ…‚$БˆmјЂ ˆjСWA№A„> > ^@„Š T|Eќт/Pz Б6Щ\ЯeЮё[ћœ3‰ufв&M:s2;,і>3g&ѓ­ѕ­oЏН&б|пЧV:Жјш: ы€ЎЖі0з§/hk}щлД эНѕќ~їЊџpАЦq’v™– §Jћe+ЅРэ›МŒ+Д›їKCІЬчœЦLУ„ЁА+'Nр{Ь<€Дjoи%N/Ъ:0ѓ'ЯGOMѓЙwb8ЮщCY=2†‰НOb|ЯШ?žnЙЬ{&cщKsњ––ЮЄ2˜>>ƒўо,z˜гЧІ0:ДSn3Dxя@№1э€Ўщ˜91ƒсьzЬxОŸ?Яч/ЊkŽнД/cхFєeNЏЪzbп„ЂЂ'Ё€ЛžЃ,•HтЬб:ћgioХТП—гgВХЉ§Їа—ъ(ђЖkЁъTPВŠXЌ. лз‹‘сСшЅаŽuД>ц}&HcŠЙžIg МSГaЙU”*w0Зt7Џ!еЏУHЈ-0ж ™Nf€(ў1ˆg'g120‚ѓМцз”Ъv ‹•Ьчpcсц 7Qr шв”“D3Bэш<0њЂ<п3ŽсaЄ)^Qп­ `-сvi^EО4‡ЂГЧЗa$}Є—ыТW"§шМ(љWВиќЁIdТМЏyЎЂО€ПSОљТn—чQv‹ЈС…ІГЂЄ%Й&—7УB6ДПоsw й“Фд‰)юї§0 CЉН]ГPqЫ(T%њ+№QфММ:ВЬ( ƒЄzлLTCtоЇMJоŸ9ђrлrGј№рњŒ~­Š’MеЇ№-TџAAР{6єРХфZgYАmŒзС'ЌW‘mыFšгЛВоПk?vНЉ^шКІРKє•ђSќ–ьХ ђžEРэW‚цЦОw§`t)ЌкЯŸ‹ђ~0ЛgЧЯ"ЫRз$ѕ=‰~X№(8э%• ОVk >xLCfЙ?\џUR%ŽЕ#|NЪйщуSиžйЎЖ<>Ъ_#„ъЂўeЗФЙLЗ8Lђжрu3Xв`ІыН„++z mсЁНаO_РЃ;Co2Эмеx‰|4[^Ї ›ГЗ"њ­РЫc"†#GЕH&C­yј ѕЯDцмФ3и9˜C:ЫМзыТЧјSхЙxи^…оrєWЏf^Ї†˜^ъz Нƒsе?вбШ9СgRYШ7mŽы bWUХ'дL"oћ<Нv_рЃ4<єхў“vЛжыm­п впsКаъž7g_ЃаљJќ жnЎуVё:ЗПEІ€Л*ј?^ѕГI3uЦНЪлЬž`H})z~hqлюOПћbќЅggUюЊ ˜ DшЉЧюќ_Д?Vљ8Oг~кTауПqz.j`6jŠђёзх(МhнQѕ€P_РЋ­љO™hIћpќH{уA5d7Ќ+мjXЕ ОII$pЭƒЯшKЩUrОЃкт­†lw^"/тЇ€*ДМи8с ЯWy–НђcњMСыБriЏœЮŠіZ@-Њю/ r^W€к{ЃмМfЦШэ!$ˆ{Aѕm>V)р+хWчЂЈ2РŒv‚џƒU ддЁЧSЮЈыh@˜ РЧlt‚“уЎРБєV]_)†š€U DеŸ”О†Id2xXбk^гуФ8ССG_n}"H˜~C№ъ9јqб—цЈо кˆрЪрn№›ЉN6Owс2 <•~вDНj>^) IџЧRЪ/Т'`н|ЌDP 0(§Оt‚Дhh>V ќw4‹кяsm+hQ/  ј˜=*@…№ƒн@ЎЅ‚VруФ﹘R ИЁњѕSa3№БJрЋЏ / Eѓ*р;Ю­ўА1Јљ§e€ї~3 o<ZЋ}#№š#Ќ |ЌА№Бb@;ƒп”]рїO<ДѓиH|р›ѕŒт†3Дћ“[|tаu@з]lщёЏ–SK}„ЦНWIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/firewall_25.png0000644000175000017500000000165111733011756022737 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<KIDATxкьVЫnG=ЗК{оЬиcp‚ƒБXи H@By,’m–‘иFЪ_E|ŸР 6l@vHH$ cG–cЦуyvїхмъlВ"FDбвэВІКЯЉsЯЉj‹Њтm_џУѕў„vћuNl8Чњ…Ufi%„Є)аMС;bжЌ;gчѕч‘ш№‡##%щ&@;QДcИПКZрдчЌYжЮHŒс‹§Дњ)šБbЅ—ЂЫq@)эA гЙЏ$СГюЮЂ8T‚F)BНЈ0HC1УWš~~Ќ IєFЦ'^‘їЦпОšŠB@5e‰шп™џJ"ЖћдiВ­ІЂ8„[yЛFЉфЃŠ`$њЄXэ)žДЕ_ЄРGаIє›amђЗ€ям}>аг JгЗыЛƒuЄš)0šНЎvPv:§ЇЏXыћ•ШPэ\У™@ФHфT7Imд˜`ЬЬd9ФŠЅе“ЄўЅЌYк(D˜'Щ— COиВ Ь‰Ъ NI˜ткrKхœ˜ єL•=EБїdЉ­Ѕ—Цп\jЁQ 0NЮёjHАЁˆЫC`dЖЋ~ўшюГѕРЗеqЉ6i)FœxƒсЮ№$­~тkyЃэНђИM@‡=e‡§ЌЩJgФyЛ_š/@ќњ E‰Œ"л"ќ§tн'‰эРѕ'›˜Ј˜ЊЯ6cЌѕ<|žрў:Ж’'йoЎЦXя9|RЈ8DŒd‘@ž‹mћ[ЖH\ю‰ѓY[ІидщZрCбlœ;џ Cа€5KиэЕЗжЖ`яR<]w ўШ:щI.sУEœЁщєе'-ѓaи{9oЏoіEЈБ%Ёг—-ГюОюНЙы)д/Еssюм93їќцœ™9У‚€gS~S—–HиуZћИУ)СГ+R"":"‘_j6эМhІпЯBm…М1ј|> ;Јо№@д4d,ыСАc˜ъУdє­[Ѕву'§'‚VЅFДо JŒ>C*И@€vЉEH”. K,A‚>†9>=›Дg^`]р}ž‘Уˆ§?˜ЎrЋьљјxˆЇO ЁњЎЋ=`д3Р{\BФэяS:tхя†рr€'МAˆЎ>MбяŸp@ :"jвFHh›ъih,§ЯбtіЎхГщТНЂДN8bљbвLЮ}Ц Еz"тџ%=`R…"_)[ЖŒxš-ё„yв#r%ф{њћ‘ЕkWлQШcНЅ#—ŠŽ‘HЊтSк’ ї{žИЛ„ПєwЂеЮЅКЏIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-sub-neg_16.png0000644000175000017500000000171211733011756024426 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<lIDATxк\“LдeЧ_пя}ћССЙƒfƒAJс@LЂ46fMZl53WИАв6˜k‹jђO":ІŽtЎM›Šk5фGR’‡уL3р“ BфшјбwпћёємYЎѕlЏgћ>яч§ў>ŸЯіAdЄ]2 Љ“”Iк$Х’O$пnўд'_!=t9n‘gж„W‘›sf>6гtњ/<о(5хжщш ph‡§VfЈє^ ѓчbГ оЉJЅfƒ‰=v идuUЇXчiiќ}&FЖ4ИяХ‰ ›ŽЋJHdЇиџuХЈМ}A•зЬ[Љ1щc_Ё’–Њ’bVX ЩђŒОUixeЃ™цwгБйTСЙГx^НЦѓZ ‹h•oёго! в˜xЭШсУмьшHО(-7— yіХœ NЙщщю% ЁН)ЋQmdr˜з.у›Н#Н^юœ9“4m6Ъф\n?чE <УўЗTЭ QщЌazpПл§Pˆ./3езЧ‡YДкОуГШiŠПкђPз#:ёX -p*ШДЫХРŽїXђxАQRТxggВ/Бp˜ѕ{іpг{п=Ÿь“H—аuuИЕ•яЗmKšгђђxси1^<~œ5ѕѕЩ‹ЗNœрЧК:,fы‚onnљdэ—JЄ3Ў$zId”–’YVFz~>ЯЫ†eWT|ЌY,…ы›š(оЕ ‹гIVy9EEE-ЛыЌџ–ND"$FyГзхУm‰щЛџяЋчЧЦФѕ}ћDияOhŽџhЎzBфф>.ў`ƒ-Р0k#дIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network6-neg_25.png0000644000175000017500000000240611733011756023457 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЈIDATxкœV[HeUўіѕм&5;УŒ3RСМ8Sщ4M6Є3hLаƒMTJОЈНˆ8Z’ BDЁЬ€=ЈHŠЁƒаЈсCаSНD=Ј”žs:sМœЫОЌўЕЮйzЬМѕУwійkэѕ_Оя_ko‰1†#,oxx8цѓљ Њ*$I_“NЇ‘L&Хе1>nšцlлуъ!Ю%B1сДзыESSўѕѕѕ„ёDœj_џєWшЊ$Ђ‹Ь <йДic+e#Кi"Мa žА`гšѕсJQнAA„3й@šiYbаыбртAВ”Y iиH@ …^yHЁеССAІы:…Ђћ§ƒ"[nВ,“3Cќз\:TE‚a1$г qгB4-!nK0Љ)ќ. …>E>=Г>mPЙ“ЖЖЖCХ›Ÿ_Ьt‰[Їђ‰"њ‰“QKЦ–ФР\TО(№PП,ЎJ†-ЄRi5ыШѕ‘€&јуœs.jx]fffаииˆББ1дееa||5йV<A!+…”вRьml`Ж­ ГээрДZ-*ТXEEЈYŸ˜ˆєъjL>oE<ѓ‘В:НђL:І†уyГЫVwсс3Ш>6ЇІА>>ŽХО>јжз™œŒѓ­­ˆм™DиPL:!фы aїВ'A\˜СЛŠГСТЇ3ЏУя==Ёэhєzф77УљeН,‰ ˜я`Т\ |sћїŠENTx Šчш(\ssП 1EЋ8}ЋЋ 9K?DyX”h“ЄаKЬС8†&ц ‘ƒAъДй0\Y ЯТЂRS›™‰љообёВ2œЋЏ‡Юd*aБѕOд>Z,єIB}ЄбаюД4ъЁAЏ—ОЏЉ еTєГ3GпЈяoБYY0fgcлn‡йj…ЩlЎaМ}9 _Љ$…f—ŸЏЎ5КoиKБУfЃ3VЋКЪ?иOИэvњЁБ‘њ].ѕ›a?Пђ~Жtx<гIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network_25.png0000644000175000017500000000155311733011756022624 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe< IDATxкМ–Ыnг@†џ'Nв‹ €ти№ -HЅBЈB}ˆ6нt]Љ›J­`“ Vє PW/+–аІ%u.Žo3œ'%Н$uS‰#LbeЮ?чџŽЅnˆЉzНоє<B0Ц їDQ„^ЏgжAшыI’œЇ”в\cŠ3Ъ”OJЅVWW1IlmmбѕAнО§№Ž`FнœœR6J$:ЁФi;AЃУRHкs\nК%RЁ|кВ“45KE-вЗ,%^,Х€Iœ‘sЁтp‹Ъ.7{ф‘*х3ЪG};Eмїн)иАIDЗшЈp+NzдEШHзГ1[В0EBF„(vvv”у8А,R/—QЉTP­VЭiupЮЉXlолТbˆS…^Єр')N#_2$4хУЌЧ1W№œlЧКШкккXx‡‡пВ)qjŸ,ЂŸ`œІІ  дОЬI ЬЭjen! #‚к/4€zПb?ЭuэЙ†к86пI-йгЄNš$Z ЬUЈRwгE†9O 0ЩфT Dzфw_€š€Уq2Tyў›L—­–љьKDЏД™S№Шњ*йtЏLЛ .mхфTšн"К„ьOЮ0дPZfj~žЄ8ђІќLфгЂ}ыћЄнэBиЖsъЏ.ML[ЁX№щ ЂнЦќќ 3Žчw2НgФг&рЎ[Р`xу§ћG"Ž#uіЧsj“8œЄЬ@Mщ ўтgЬ”8jЈФ‹jу§в4ЖЗЗЭrssГ8д„ЪЈ"уЃ+Pџф€КО^ЊгA­ЖьээђKBЭ3џжPП|7єPЬrƒgЭђђŠмпџТ.€yЕєZMo–Wє‚rM˜uTŠA]XxI#''‚š'ФССWўЏYSУјHPUЈyDиu?ZU]†Њу:Јц‘НaЋжnЬr‹85 ЊŽ+Psˆ`А)ю7rвю†“у?Ф9ј;[rM †хјпuчј+РY5{!Ÿ."0IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-ref_25.png0000644000175000017500000000234511733011756023645 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<‡IDATxкДV]Hde~ЮЬ8;ўЬЊуІMбf(vЗ xЕ‚А tQdEДЗ‹Зv’uA7й оQŠБ†˜™„ЫКьЊ$JЃКљ—:ъЬ™™ѓћгћ}чЬЌc‹ldя№žsОя;МЯї>яѓ~g$лЖq>6уЃKр„не‡ѓ3Мœ<т:ЗЌчAМфaђJђкЯoЎм}џƒŸюђgЯ9gтw3ˆъКŽLFцѓбџ$Ф)S9УчЫEM*пŠиM Эџ ! ЁЎ**ќRU5ЂбF0гфK!ЋŒсZћ5ФЋтАшgк K‡ЦђP™ ЭЂЛЅ@ЗЩ-T˜’цбa{MXC$DM(€ъŸю>ьпR …D­H4rѕѕАl†77юaњЋтkлпС'—*aKоІ $y‹œю3Ю“DЩ„I У@81Šц;ч‹рЙЁ;АŽ`&ЗА{ѓиляСЖ-z‹!ЕhB3LDEьЊ‰4eѓР‡ƒРqn’$•‚hІ&^rŒіgŸ–!FЧkTR‹JЛуйжДIјѓ6eхсРЖЬk9СyF.JЁб‹ *SDlg•3$иhТGСƒ€—вфдёЬhќiузт.й|.‡єў1жŸ§ОDEХPD&МoМ\R“дŠ нд‘Ю#OЃтjvгШЪ$E!@šF’ЭdHЌBiиG6ы‡ЂЊЇ@LEэЃ‹XЏП yCCрy y–…IAf‡ШАcl§GƒnCІ>јэЙO†I4ц•МH$xК=ƒУЃ0vvvNбeцšx2љ,RwR8SВЈ~Щ"Щ0™‰ѕяL\ю–`ћ$ІАНН‡`ssЩф_ˆ-—.*šЈЮ§ЯЮlЖп‡+пж!ў А>nсСГю]Йее5>NЛНљgMNїЃЃЃшъъB$ђшeЎ KЂцѓ0\~ƒЗIШчС-пЧ№Д1”.рХp O…bBq'c>іЈWЈ˜зЏ_ЧјјxЩќ—/Ь€]М 9RвЮю.цБ№кА­D]iKN3>V]лккB*•ТммКЛЛ166V\[\\@ р‡пяGY™ѕБ"ТјuаBE˜сИ–!SCJЋБ :,ЦJAVVVаллKќЎƒЮЮЮЂЕЕbœX[ƒзы рѓ•QєqF{Ÿсп‘ИыЯМњѓ№0яойЂЧ'''бййYP0Y–БММ,žCAч‹ЊiЭgQW[‹]WІdМ§yЏђШФ(Єˆ"@њћћсЂ *š›cПЉЉ ѓѓѓшыыуЃУ#ф(И’Ы‹ћффXZZ: "јо4bˆCtэээ9пRгФФ„ nhhSSSDЩЃВ}18(ЁђH–яUUŠ G%юшш@KK ІЇЇ122R№ЦЋœwПѕьі/ЖўHˆ(ЕФm2™D<Г===џ ‰ц>ы. 8L$б9Oh”ёtЭHЎZ ю-dјЗ W1­І§ ЋIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/pipe_25_.png0000644000175000017500000000222411733011756022223 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<6IDATxкфV[hUўЮ\’НяцВ›&M“в4!A*– [ћЂbA‹/’RZАH|ЄФѕEЌj[PŒ`CМ4БЅiв`’цžl6f“Эnі2Гs;ўgм@JЋЖ‚рРЧџЯœ™џћ/п9ЛŒsŽћ’юс[VТ]/хf›Д М„{#yу­7Ÿ ј§Gќ>пзль)їLr№ўbБxщх—N}s_Hvдьш‰ХbиUП‘ ЈЊкЊыzышјиIZ.ЛS5Ъ_hћaЫоНЈ!’ъhсpХЂŽЩЉfчцяпLЊ*+%ЁЦD"x<Ž›#71=3%–ЛЖЫћJйmЕ Fk\MМјшЏЭŽmCгu‚†С0L—ds њюЮ•lВЊПџ 8 ‰1иT‰NСзГYhљЮ)Ÿс|зLіЙёєІЯјmї‰ШZ єlВЇ\к-љRђч‡MUšЫхPШчё^ЊснЯќ#›d-m“јŸ•”‚ ПМЄ”—еŽЖЖаU= o…ƒŽУА ќžYBF_Gu+`щW-z7М)y1#ёLДХb4Ш ‚ B=!zДћн~Žq,тїK5U!щС–:щpыs nЁ?ў#ВfзБj,сVfkЙ,Rƒ ХJЙmvіУ‹ЏR АBX$Є Жє№№йуF x ЉіТ“-ЯРЋx1žgdIЂІ;”ІŽ™ь8њ“—1’D:•‡2vчuЛ*hoo2’у‘L&ѓЕІiЎDУ‘ЪT:гѓŽю>еЙЬ4UqI:I8Г]ы0 y'ƒЋщ> чњ1њ0ѕі,–——q}шВыы]ЂMВ,#ЕЖ†ЪЊ*WA‚@рБІшVЋZWњ(Є›™p$“М"ИАG6ШЗPhФ’/Cme(BС !єЌbšцAQE|1ŽккZј|>иŽUQа;ж‹§Эћа;гƒ‰єoрŠ &гЂёчУцкЧ;цВнз–xdё"Џ(‹ЦzЎ@‹ыёѕїv–ёЯ B™лњЬR!5Lа$м,TБ™ O^~Х?ЄѕšІЭЕЦЩ § Рыл2ЌДbЩMmЫкEІOО3Ћxш"ѕМИлЇўёmŸ<5gСЛ чИžЗŒмНj`3—хэ(oЃ&йнлБ§Fqњ2пГъОн†\ЏЊ,жзњ ŒЄ A4 дiЗ[З,чvk•џЌFЄšРq…(”e aNB“ <Kr$RfГ›ŒІчhNФp3Ј ЩŒзSюдЪ0VHі<Ёёё Јc`"p 4Bѓй_Ÿн(њкNЏЫ›ЛЯE‚%f<(зяњЏSнж“њ,$,6aœ&жџ КЁ5Џ]x‚;QЙВм7Ц}`u‰И tлPзN_g1D^Ўбо>(i’з9Њ{lВ’ŒїtТфл@‘ЈќцPFўіКb˜АM€]ivш@5tЩЄ |ŽM%E| ЄH€КдXj>еA˜+кv% т”|Жf цччУ†  ЉЉ ќ~?444@uuu†tМ:‰Yˆ‰1aLіaєуd‘^–ћЏ7cmm-$ C1'ёzНажжлЗoO]N!„!Ю4%•ХZ‚ ‚DЈd‘Быz%Šц!ъGФэШJJJXoo/у- БŠŠ 65&nJС^/_цO[Н||J†и†№ё+c6цrЙ\АgЯ№љ|044d˜ЏООо8QКyxыQW>ъQпФЧ‡ˆ—‡}RyМOіяп555pцЬиИq#477>jii™šЧC”kсЅЂСй№фж{ЂП4œ>}ъъъ`ppvэкВœЙќ@;–‰Lqџi‰HЖф™с4ЦШљяњG€Xx3иєIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/big-down-arrow.png0000644000175000017500000000070011733011756023454 0ustar sylvestresylvestre‰PNG  IHDRрw=јgAMA† 1ш–_wIDATxкэ”НnA…П™й]'Mx GH‰ˆxо€:-eZ$%o!бф!вD !d тЕзёЮЮzччR8 Вў)в ŸЉцяžsfюНАУеГ.EQќ™h­бZуНџч1†ЖmWЦы%јќхŠƒƒGфYNž€cттђœfa‰1рќ‚rrУxќ“ГгЗїЦЫњœЫhєA6 Х„КЃщWB€рŽrRrvњЎWlЦœkф{ьћh­p]Z pЎ]љКo#„ †УCЌГ‚ˆ ”BЉЅа"еЌтѕ‹їЋžКŸр7j{KHžDBdId”СЄœz^ЏЭЂuъјшлдˆI™Ъа’ёуцz­њЬngјасƒЧЈŒЊЊАѓfЃ:и„@tHPL'SоМќАV§Ъ,њ1FfѓŠЮяSNJlmЄъхгХGyўъ™Вщ%Н Уѕј;mг=hякJ§жvис^ќЭ0Ў8и-ш™IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/domainname_16.png0000644000175000017500000000103211733011756023233 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<МIDATxкœSЛNA=ГЬBАд^ш­ˆ_‰Ба#БЕСRДV$киЈŸ жќ€1| ? †•BtwgМ3ЫъŠФDOrrяLfЮ}ЬІ”Т ‰KФ ‘Oї|тˆи'ОЦѓvЛ­„H$Шd2HЇг`ŒЭŠBђ}Ўыb8"‚PРВ,T*ќѕz<*`яќ‚3DБѕО”РЛ/1~“Œ|м7VБ|№Iйє/зLVмѓбE vЎ-9­E$mиD^Џ‡nЗ‹С`€NЇc"iѕ"ЂАma;)РEш;Žƒ|>VЋ…bБhlЉTšŸвIНЁ4*wŽ:МuTDЉl6kќrЙќЭЦЁзжsџЩ 1ФЇ0]‰ Z­šuЁP˜›КЦqЅБnЦч —Ы•№cF6ЗЖеБГ[R|<a}}=Кž4ЉŸЪc4`6чXXH"šTЦЌщ|Hxо;&“  щœтѓcоЇйl*nФZ­–ŠOЖжб­cs>ŽŽŽез9˜ШggЇжŒ~ьR]_hšZЌo77зпК87ƒПрC€B O[ S\IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ipv6_25.png0000644000175000017500000000270611733011756023456 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<hIDATxк”UklUўюЬьЮLЛлmЁo(ДZ -BGŒРb FPЈQ+СˆјhSˆ‚ !’а№гє‡ХD‰фK„!HJ,БTњ Ѕ”тв}tК;ЛГ;з33[С_]OrwvЮ9п9пљю&зIЫ™ЫS2nh~w кт7’хЂœЛ Ж1ыЪрмв1њКdа.И€žWS˜Ш$ р­ѕ/70h9t‘}С6eЕЋbѓŽ‰ЮЌ+нw†ЏЃ#tЕaјTіў’Е‘Fd`‚\:Kgne+HД(StWШ;”ац№UќЉ]“S˜ђRЄсоБI;2‘ЌРуYŽгcЃK№Wѕ…­kЗ4“ЋKЎc#žђlQ­ё”•€:=Вžќ{&Ў„ЅЋЉ„Ь” мїтфЕStлFЋ'ючЁш@|ЇЈpˆŠ“\Ц•˜‚нŒ§ф—Ёˆ˜мяЬ вm|мŸ=ећЁЄ„()ŽT$Л'c#$z8Q–ƒђVб.p”ьl}ѓУ›Šš”g™РЁ–eг6РkQ%ˆБaуDF VыE™–Ыщ‰Kqh“Tn7>o.МЬЈБ…№ятш;˜їгœнС–Œ+qЉi%Y€ЊГ!*Œ€9"Й˜­ v[=бќѓIъ+њЙаи‹oc[XЧ™P4ѕNэLq(‹b}q…твѓKƒHŠ“Е§_NЃЇ}Ё+О–Ъ­ЁFбЊ@d$’8Њn№]sиp)€ЦјXЁfЙјк;z’Ђтnђх”љpyv -nЅГЗ3N“тк>7ƒръuГдlућ*ђ№iЧ=М9ХwЙ*Tэye†<МюR?~;+uТыцѕOхЙi K2ЇрЬЁKvzcї)§_p;UEЈ^VЦfЋЊ€••№фQ‚IЪ+)Њ"Іr#|яХюј2{ZX%еВƒ+щdvЊГ›Mr=}Б$Du‘DU0‰b„ HЁgЇхЛiO№]œяд‹ЅxHѓї}щГЛдќ7“ЩоЎ§Йћ-Аh@ѓ/ясžЃxo^)ž{}*ЌЦ^рhНЧ цТT_+fЊŒа™Ѓ\M(єP… №‰IƒqЮ'”рžѓh"~?_љИMNv[ŽЇ0KСыжQ]’…bŸ„Лb­Њ* !^рСъуяђsB&:яa§МbњP†:QѕѓMЂŠИђf к‹Of§КЋVєRџŠ–Ctпзˆ:н”{$›w6чd2ЛЇ?8 -@œGH’ЃM К|†ФыЊЅвГЗœб*ЅAьГAЭRDЬ9нХeВj1пF4Е“ў%€š|fє­r1x‡5T’JcфЗz5m0‹Є;#пR‘З[*”2yЅ…}ік|,J]AX2н™ƒaрvаQдd/U<•&бiі ІfbщtШdqЖ?_Б‡ъЪјi:'‰”ХНе ?‡У Нcэ §AмŒІъ›,і‘МЛ3!zП=г7Р"Њ"зУ‘M rKщ™L@ЃдГkН №xв}—Jš?ќќNdд‡ІІc{ўa^юFJЅІ{Г(0“;HЎ$[ƒЊъ§лЊЬ…{QiСЮ#ЌјсЈЯРж№Ё†5ЪіеЭЉЊсАp!ЄЁP! уэ@ѓY†…eH>S щB70–рHB4(ёŒлЂ2a$<†Ž+нlЉбљhЛ}6њBhјцw,!aЌєШЌsVјб|pќНŒN|Wъс3od%дьCЃX8YEНWСї­ѕќ}kos++ e…ПкФОџˆ+шni&IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/routing_16.png0000644000175000017500000000077511733011756022627 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ŸIDATxкЄSЯKAўf-‰DЪ5ЂџЁSзў€ ˆь"•ВVє‚њC‚.uZС[Јt‰Ю]:EyŒЈS`BPH?мigvGW]!ъƒYоМ}ѓоїНyC8чјˆ?‘йуФБ!џм№rс•–Y< ­C"H,ce—џY7VžгT"цЃNа”ж—ЖтГЛ^дЫ.#™УpzHњ …’ЩЄЃŠxХXoa„œЪлы&єq\НžclўC&4 ЕZ Њ_ЄƒO‚]с8Ъ›И~ЛФр(СS h–Lг” 4M гeDBМ„ЁU1—ЫIŒЙд•кfр3nу.п€eлЅŽ<ЋТН›CoейЏ’еІЗ@d_ФЭUЙgЇНX­џcR٘зюі•ЙІ)ђЧћ$0С_№#РйŸЫpzбIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service_16.png0000644000175000017500000000167311733011756022576 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<]IDATxк\S[hUўЮœЙяЮfЏYг4гДДD)…вF RˆTEБХ ЖХъK# RAФZЊјЄт›`_DЂHQ}ёЅЂХVZ IЛ‰ЭnЖЛГ‰йнЩюЬьЬ9=RЅчіпћ8чxpк_Н•к\+?7uї§C^щмюеђдC'ДЋОЌ‚lnў?Vо}Uюпћo­MЫšіBІp­UЌЭпtB†ѓŒCЇѕЫ}Ÿз іЙсџ*ŸаНв_oЄї§ ёикYјЊЊ@і€s]{хлѓ  Y7~ІљЧI8в–чОзПіДЬіgЭёg(ЩРм{rя#€<в ІЎA%8тU чIдХ}‚•cЄW‰%#ЂYqћ.Ђт BgШ< Ъ$1PГn—)ЗВ4!—/‹ЮЈ“g_INМdШй`…п`_z МКŒ€НŸ‚iхwUXw\PMљQ‰ЇgdцmМiь2ПМŒИТ@(Ые[C3ЛIp_‰УгCЬьbsщГ6ТП—@tэF§ђкŸWОйЈkЎUУxўєрЮ[8RywŸшm<5€ШwsЁНј8МD–'#Iыбщ'hаšыri—јУЁЄЧ Lи шПїџхœхЏШЁIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-group-ref_25.png0000644000175000017500000000277011733011756024501 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<šIDATxкДU]LSg~ЮOЯiKilЅhСR ЦŒ?нд8LдdzБe‘ьЪсЬдl1&,™fqWЛXВ™]y5ЗlгlA/ЦЦ‚8ЇЂAL4ŠvŠ@€Rjш§я9поЖгŒР…#йIОДч;чМяћ<яѓМЧУџ}‰‹mўђˆg€;HЭЋP§WšлSшrћXЌ\ЧоYcсЧ.=$њzњФ“ˆ<РsХѓшxР48*J(h”ћуQPнА’ћdM7Иd$?м ˜w:аО}5tЗ&с 4&8ЙvfшS+Г9ь„ё%%б№XMЁcНЫЧB go+%U4Y5+ <k8žЊ|‘$ќb›ыЋ№ѕхƒxЏЖђW79 MЉЩ-6јЫK8ІЅВцЈ_ў8ѓ;,r№EшZ4Щtюѕо9`я:)§КSŠ**TНфT@QY§Эqхч%'!ў‡гйBѓБЧ ЕX6†ƒ’z ЪШЄƒ,Ф—мј­58™є˜Шx­'ЉщДЪtљЂ)цЖ”рјFsЪ… ŸžТШ‘Œ\Rс„Цн^ШTЩѕ3д. Рё‹'yј”}ў§]ѕј‡рlА€OЊЌB‚ш›ММ8ЏЎoн…6qє†€hќ$DYЧ$§›ЙртN„тF”йamЬ"=З8]SЁЬo бšЬaмO„œН |wоЉ0 Ѕu†HтyаŽDш'ш–щ 5€г–B6–Н…б[Šћj7“KaхЫ@ХjpuїЪРH-ЙEЋ„j%ЄjВгj—цš,Нпј"-›‰Ўжr=>њТі/Х}ч7mнТЩ~№tˆxшї1§ЮPy34L* QЋd-kїЩUЮ~Б€…м­DqŠуеŽ\HІwа)И?нjІF5•ќў Йћѕk‚їC}Х 5HЬsNZъЈЪМЎG‰S-$у šKГ&Сsџtjжѓ†˜v)PЬ,й…vM5ЏуІ8ЁJцЃv0fW§ЌъbРв[ѕ6Мкn‡ЄDњкYhЂdЪVAзи Ь*І—бN—›ЬiLYЎˆёХ.–Šщ0мхќ‡PтqЄdєеk!šШќсiЂ–ЮDŽ ЄQjо‹э5— ЯћЏsчЮ!‹Элћ' ЙД<ќ;Q_R2ЇoyћКИя3O@HљўЈ‰Аœѓ}Љ<*mZT]ЩdXј`ЮOЃДhhєыЖЉbгn+\П Шћ‚zІ€#Д›иƒо$™˜˜@0ФРРкккц?$Э#M”Y ™Gˆљ$Ї•Pr(ˆЁДŒdkЗ|5™‘6DЫs3К\.;v nЗћyЬўў~477ЃГГГИ‘KšЇtВlІ™CЊ SЃCSХрYBXA Ra Aa#ОЄšMgPНщt!Ioo/>ŒL&Г€Ё|o†††Š7Љ№ZЪ2TL%DUŒh SвœшWв‰C‚Х1†ŠЪ'uЕДД`rrВG’$джжеззЃЛЛ9šЃыќAšŽŽ|sˆЎYњ2[D”%1di4јЂH^Rй№­~ЧЊіySиыѕnђСzzzpфШ8Nєѕѕіž]ъЎŒнЬ%ѓмбЉ)JHrє?Cg€b‚dВ@ŒЭlРHiхМ$Я$Кkз.444Рчѓd,ŠѓчЇ*Џx\I*%ŽЩдД+ФѕEšЈ# в4ЖtЉ –ЫТуцzГйŒ™™иlЖТцбЃG$(TdoІм0bY#&ŸhA‡<љcсPЂWЗТvrZƒ[Ј|щ™чйwџЭёюсp?cE*К ўБѕ0Yп‡ЖД ЭІу…юЅЭШ‰Z–ЭSап 6~э–TЗIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/lock.png0000644000175000017500000000113011733011756021544 0ustar sylvestresylvestre‰PNG  IHDRѓџagAMAБ ќabKGDkk;т(0Ц pHYs  ’љЅtIMEб *8` 2ХеIDATxœu’СjQ†П;IЇДгI˜Щ@u#R7юAЊ]ш[є њЎмшNBUФ•‚›‚­‘ в…т+HK3Iš;ЭML2^“N3ЭфТsОУw†_h­Йў\зеОяр8ЭfSЬ k­х8ŽRЫq}}>Nœз3f”цЈІъbњ!єфЌєс”~МрўНœ>?АэLO„„aдoі@рѕЫчњэ‡јў Ju „s!‹0 cLЦdiЩ&Пт2ЉU]}pдY€žвnŸq|ќ…\Ў€eА,›oћ lлaѓё3Ъх[\\HЄl!e‹ў ВєFtхŸ)ИРЏŸПйЉяH…[ЊP,–cИлm1˜,0"ƒ+љ| [–ЭЛRАКZ!Ўрƒ!ІЙУЙ\ЯЛЩ“ЇЂkkt:g1,х•AівР4o`YƒјŒс_СчO{<|ДIЁhиЂŸ8Ё7"c,ЧАч­ГSХтЂ @co?Gџ’9ЈUKњ§ЧžЗŽ”mЄlq№НСщщ З7* x{ћMІDkе’ЈПћš.ПЗЖ^07‰гЏVuЕR!Њ?FѕУIQj<ёџКU–L“џKIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/forward_25.png0000644000175000017500000000147111733011756022576 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<лIDATxкДVAkA~3;›Mkb›ЖаЈh/кƒXЏŠEбƒŠ^jEќ=yа‹ѕVO‚Ђ < "xEЁ"zА…–ккRл4эfwчљЭf7й„jcM†}ЬМ7я{ѓоМ7#˜™ZнTзўёЌы]нiDXў‡ЗAWpW=XovŸAЗБУѓoћЌЁƒ“;бu4@Щv чыўqГмE{ћMgшl+bBН=6;Аb†)аX3&Й}п7|†‡NW=їш™йФ“ˆбЋSWЇy{О@нŠœ”$ бH}ŠнКЏc ЃzS984ХЛviGоЁЮЌЂtJ%ХК@њ4P šЩѓ˜nŒ–ЬєЏшC“йљ€f LsEІU л"ЇЭЂіŒЂьfЛ†2Y;ќŸnWdCЦШњАІЏ-–ŒM/ˆ8Y_"FсNЖчќžmЩ)Ъwйд‹Оs“Є6G’ВЩhG,fXыCЁЦ-iZv™ŠАЌR@ЫЋрW4]Ms_r=ўйлmQ.,(ІMy’–4M—ЪЄ™кRйVь6КФѓ5љЦ5`%O“ыУp“ы›y"пфK‹ИпЇТ{бГДЌя*ГXv8фAй‚TРb…айp­”qњ3ќo|/ЫЋ9Œ‡fE @al!>ˆ'Gyёу…kN‚UxШsщђddЕЮЕEBpѕ4БйžaЪYб|\K&‡I: :ŒрOD NMkгХКcаXА:єutЦ fЭщ}3U>QйTEqeЈ2ЬInI˜‘Ќ„ŸoNЦЧїјю‘mcceО MўsИоWКоK€џk.-cLRИ‘…‰R„%Ко5Е@&LšŸРы?Ш^ПёN Р9аѓ–”њшќ@3@†AO[љИlЎ‘F-w§`)::ъЫ;(zIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/log_16.png0000644000175000017500000000132111733011756021705 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<sIDATxкŒ“KHqЧПѓžнq‹"ЃP6#KˆJ"BЄ­)бвуињ(ˆP+Ы“xШ:DAа)pС:є>mtoЛД†aK…жКЏйн™й™щПГ*ћРш?цїцћљ=–eaХz|ƒ–2гaН8зh§Ы/еаX>Н]з­ŽгЧ™ћmпЏ іЌњУ#§Ћ~п@З§эŠŽEЩqЛы‘мј ћю˜ (rэsД`Сѓ<ИКї№ЖѓH&фRI9  H$HЅdШВŒlVЊЊа4 Іi ЮрqПyњЈЦКф eЫ2бжоVЌРX–ЫqоЮ‚ч|ик]ЛсаS\<јѓQ ŸЯуеЫзvфL&EQlгu†a kнgММ5‹QdУ_YpmЈxOzI)X†)F-D7U„œСЁ‹ѕрцЁ|ћ…ЩO5иЮDЖT јЧ§ШхTbК]ЗKтlУ<<Нu`Bsˆ/(˜ ЛА“§.45Z@GчљN’@г Иш,ўLоCыЉM ІО`i)щ яиxr;ЈQBХ4MЧшЭ[ˆХЂfтщшq4n6‘|B6&#н†–ћёvј.Ьё`ѕe9kƒWС‘кК/љ0вчAsѓpыїТыё!OЎН†‘Ча!0 ŽŒ/2CRй Ъ}ЎІVЛЙ4]\ойЙj€Iц?66Q!IЄ'$ЇбщДХЅ€=І§ЄK4нAjљN–Љ   F_2[Г„d<†ˆT!‡œЊйЃT”•єD„ ЄЉ2UXлв?џqќЉџЏФ+КZГљœIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/addresstable_25.png0000644000175000017500000000141711733011756023567 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<БIDATxкМV[kA>3{IЄзK‚ ˆVKŸŒЕ§’', ј ЂџТЗв‚oV)єEЁпTдV4JЁJQh@дІн ЕŠНd3ž3›ЭnвmГ­УЮЙЬљЮ7g.Ы„Алˆб§њpžD lЅЭ7gЎЃюб„šЂ€ ш, }іТЯ2,ZЬ/T2F†'ЯХN;ѓŽФ ЃПяoaGF™ "2XYw1ЈMф,јЕZЎбNT№ўО[‚€ЊLЦ&зq  хA)ЕШn€Mƒз'Ё:;FoЁ%ЋІЗpYЋpW8П8SЂкѕЈўз'k:—ХdMЗ ю0€wŠLт‰?“­@]&!n/—ѓЃ K_–-†$pѓLhЙ|™pјќі[~ўљЉЈЭDS5‘YcЙ‡ aiЁЪш0ъЁJс=T„N{анЕАZАnЗjš}РN0БжЌtfx:Iувj)M_Мв^<˜JhiХж5{N€.ШэєЫ—nŠ ­т jГo„—‰7s_†;ЭФБ;,Јѓнx ‰—ѓ2Nс8цё{„ЏcЪъэxЗmђxіТ=єI9@ШwЕНН:Б”ЫНDЙз#oлŽIіn8'­TљJ1&РЬДULо!EGfіл$эш/Ш„+ЫЌ™”}усˆnŸvє43‡ЂZ劘%YЏо7в.§m…IіHH&%“Шњџ­ у8юб!нAOMўЩЮўЧз_IœЊъѕ9ж8IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/physaddress-neg_25.png0000644000175000017500000000201311733011756024223 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<­IDATxкДU[HTQн3:SFO№F–hjjbP–вЛB1?"Ѕdшˆтр SIH„%ƒ“c&Žтc ѕ+#“$­Дђ‘~”Ÿ”T :)%ОNgпюНЭЬНЮјг…5чюНз>kЮочœ+!„Рџ~ЄжŽYu*y.‘ё@ло$ЮЁmКНj'Xp%цЈGВЌN&3ЪdвЙЮ mЭБ†Ÿ!Q—™ИХ~#h›ЧWћwП* ќBqEц1ЕПNРwкшЕэѓАеY&ˆ‰ŠЌKшЏ—ЩŒdQТ†p$V|,QЫэ;хŒ§УžШ1еhд,lѓъЧЉЩЭћЁЌВмЬ>iГ'\/ћиэ…XoФќмюђ ШЅˆYуЎŒaљk!cЙ|)2КnмPl яшшPƒ\ž=Ž‚„+ њсššДщО>8˜“Г…КюS иTЁЫ)jЫЬ$%21Ќ_O†ЊЋIiГ‘`ЙЬAуШеcyШЧ<ЬŸ{–EFЅ<~>JА(МЯШ`8р••HвуФЖ?zєs0пдTHVц^ХЯF2[ТYœ“ юю–+[^†жфd|MЃЅq %KНwЋЊваqѓѓ—ІПв7oX™z+К§Єn)qX[PKRNЌ№ь­'ac‹Œm-€yСЭУŸЏ‹ЬњЛСET$ч ‘DЅyy'ац >ёё0h4 ќœ}Н>ћ8qfВЙŠЙœО›bЫ%МШйЇШ‘а и~ќв$*dK€ТФљн’|Щїв‰ш-\9TЗ[В ћШ8”›kSуœэ—iMW}ж™l№š:ођ`hш;R.СюЈ(Q2њƒTЊ'єUГVІ\ИEйCц@}Q‘ЂMЉ\5!LЇƒ€дT\I:-Я’­ЩЙв9ВxДuі№aу *2GLїIФxи~%єА8бQлЇз+кU*й#<ЦўP­Оœм%mХ >}ŽzgФоŽД;ЗxЖЏэещDчхС™ККч8Z?Шїh…ШР(ШuїЃР=рхяFZ[кЃе*:4Q}J%жўŽbB˜в>ч1уЧп$щмјИ-нEПq\Mѓ]6КZјjG ьGдьюИvП№zђѓ™›{Х]ь ь„~Œs\ЬЋя}JКЧ>№bы№‚œк№ФфЎьlв[P *`-„<фГ\O{_Ь? )JІ> >НIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/stop.png0000644000175000017500000000144011733011756021605 0ustar sylvestresylvestre‰PNG  IHDRрw=јbKGDџџџ НЇ“ pHYs  вн~ќtIMEв -1–ф7­IDATxœэ”Ыk”W‡Ÿї|3ѓ‘xI'iL˜8.2г@ЩДЉhBqг•k/ƒCї§,„‚ „ŠЛДЅ--Б-˜ Š Х…и`bц–™oЎ™ѓ}ч;Ї‹€2#уЊPќmпУѓœЫ{^xŸџ}dШEЮEJOžq`­cпšЗ2оZTрИЗКJvjšБє€P+—йпйспџdѕюRžЧѓnЇ/k Рwke…ѓKKLNNbТc GEЈШЕZlќpŸ<рсцOк­#<5xїТљЅeNe2XР8‹v1ЁГH"0жR8ЛЬ xЖкWDм­›7™šЩjMЈ5љљљУЂ<Х'‹‹д‚€8•d:;Ытg‹ЬŽКЁžЇГYLbТ…BиZ …OQJ‘ЯхрТЅ‹T‚™ _ž[ТoШ(a<ЦD![›xžGWkцђљ7їнэлЬdg‘”Oњд4Б;r€ў_)Ђn‡ЦQOŸ=CJё77ШхцЈWЪ8c0Кзж_ ŠИ{жЂМ$"ŠѓyЂP"ТчgЮви+cuHЇPЏU{zsАѓтхэmЂf“љ\%‡=§hcRТх+—‰-Zх2ѕj•>7д_;Kёѕk‚WЛшR‰­п~%АЙЖ† #~Йї=ЃтёЭззш5ъдЊіJ%ДА~ДlЪwп^ПСиxšБ‰QЧбЉ?y‚fЅBдnЁ›Mў~љ’эн]юўє3uлGx‰AЁДWdtd„ ZRЌЅW-ЁлкA€юѕиZZг6QЮ РGОяJёееЋЬdfp6&ъP-yЕWЄжhp}Ж‰йєЛЭЂgжї]R)’J‘@оŒ…^ly~аŠё>џ]ў+SХ?Ћ}IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/protect_net.png0000644000175000017500000000347611733011756023161 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоgAMAБ ќabKGDџџџ НЇ“ pHYs  вн~ќtIMEбА;6ЛIDATxœэ›MoЧЧфŠ/тK$’ŠTв$Dзˆ Є€С&uŸЂ|oП@ШЩ—ЩХ'ЅпР@Ž:№шGˆ|r{( ЗА ˆ+ЧoTёuЙмнй™щa)ŠzЁ%reЌ›№ьaggfŸљЯѓ<3Г” \єр h˜/˜ Жa3 lТf&@и„ЭL€А ›ЙА Cuppыж­jЅRоЇRЉЅTѕў§ћ њЂЗ!Р"P-И{їюšaУћЋWЏ~bл6wюмроН{M­ѕЂчyxžЧввKKKh­QJ ЕПcŽD"<~ќјRŒ ,@.ŸџъЫ/ОXЯd2УВZ­FЙ\ ŸЯF‰ЧуУчІibšц№ўцЭ›‹Žу „@R )ePг.D rљќZэЃж3™ ЕZэќ'xђф –eс8ЮФmгщ4јожšИёИR.377Чоо^n†ИЎ‹ыК(ЅB ЅDkЭЮЮBЪх2+++DЃQЊе*јЁЖф(—ЫTЋWa—ЃtЛ]cњp–-ЫтщгЇьяя#ЅФcžFГ…T OЧши4Ч‹№кєcоt=ц–?@iј­љˆлKKDЃ—Зx@zr3NкjyсУ‡dпЫ ЄKтy IАњЫ›шЌ‹хxh­ёlДжє]‰зwА{…œТ‘ лВh;‚–AA, bі1 `šнGхR™WЏ^Ы&њЫчh­БliЙh­ivl<Љp„Фr<к=џ™'][аЕB*”ж4њ~nш ‰--/ˆЕgШ—vЖЗЭn—t*=,Kg†ƒ2-FЛ–‹'Ri:=ПЌg \Яёv_ ДЦё$=зeЃяЂДF(MgPжtŽ–УЫbj*•ЪWWWзџёЯ‡|јсЏйкк>гZгюњЎk;ісŒ›Zk„Їш fМ3˜qЉ|!КЎР‘ЅЁ9Јwˆч]ЎL-€a[пџ ЅŽfІгsjрк/0^ ЕІеѓ]ЛяJњЎПоЗ3юHEЧёнvr0уњ-}:œ:ЌЎЎ>Z[[ћУооЕпм нiаэЖp\пЕ;ƒї№і<рСƒ›Хb‘Z­ЦЫ—/Шхr(щєЌИЗoтИ|нфв ’Зњ§>ЅR )%ssО3U*vŸэžŠ{O*ЬС27iмbП…нqZёxМU,y§ЊŽ=pнххevw§М0їэw(юG Д v:-Wђ…%ъѕ:Щd)zЧтОcЙGI1@м'”ьююlЊ4!А,Ћеэvql›+Ѕ+дыu‰Т1ХН#ІћQ~qtрЄзыAРƒРщMќilPлыЅџM]ЉКB№ўвћДк-’Щ$Эf›dІ€ыљюЎ5ˆСьzRЁ№ї ‡eBiдАїГHШ>ЙТ*2Ybџ‡}~—§іo#[yD+џйХМ#ШVxQ™ѓепE€8uкјz:@шmјёmўѕя_+‹ЦБЛгЬg љЭg,;ћ•ѕУgё˜ ї=ЈИђу&№ћ‹ т]§$6зб5SoЌS\љёТ§§ь?ŠЮл€А ”тqA6cMеvšvѓI‡xќь]тДL%@cƒOO Й6…\ћu­~ЉŒceн^ŠтЪСи6йє›ХїNзсˆЩОMыоyZY;Yhѕ“HyUЅ•КНљsГіIЎ_{ЮЮw•‰К~э9ЋЕ&клL“ъ]хgŸg„mРeги`ЂŸЈ.m+œšw0Œу_,тqA!.ШІћѕeDхTЫЄ•рџ\vaІ`ыул‹ЎЋ9"†ыњз(Ў,ƒЇ­ZЎsа\8Гѓv';VДBЎ=ЖнЩхі"L%@ў3>hlАvа\јіе^aт>cšv™Œ5Ж]‰ѓї'љЩх€I™ Ж—…aЈЉЮ х€Ц_Y§ФњaВБњ’LЦЂ4ёk!”оp‡•rmqљyУPЃqП9i'СЏ—‡л`УPЄцэ3ыrВiklЦWюЗmгэЅN­*рЏ‡ŸОњ§$цРžx\ЌrэL DАПбБg‚lКŸ>г4п›јМ‘ЭXчžNOђ“Щг2 lТ&TnНЭэЏЗУ4aђ$X.ўpЁ=w"&0 ЩѕkЯЯ­{ВN*i_ј=Ѓ CџWЬўk,lf„m@иЬл€А™ Жa3 lТцЬфZ7IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/rangeaddress_25.png0000644000175000017500000000065311733011756023575 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<MIDATxкbќД$сџыН‹`@д9ށ7z>#ˆ§yi"N9’РнDІџпtўџy:эџЇљfџA| `a|rЄ`&ИmŒPŒ р“# ,љЧœџйСР чЅ•(сŽЬЦ%G@\aJn\Р0 В…ї’˜џ3ааТхш…ѓЉ8ѓџ8ёЉn ШрптŒџŸ 0§?ЩЦ Жˆ–0с GFFЊE žиЂ%vХЉ ;_23œћРФ№њ'#˜O ј\’ѕ+#+ƒј(Ž Ш`wёП`‡=ўЮІНџџ†‡7 КёuА­/чмd„Бa—fAGtœёˆЫŒЄbBљ‹š9WIAQФ*ы”ц§eФёЄ˜Aј@–O№е§ифШ{XнџyюvLŽВ$ЬˆЇ№A’ЃЬ’џxŠ8$9В"žдv@€цЏќjp3ЬIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ip_25.png0000644000175000017500000000263011733011756023176 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<:IDATxкŒVmlSU~Ю§шзж–1(нc :6  CGј$5&ŒCˆХ !"šƒ? ?Œš0!ёƒˆС!–(Œˆ ›0vVК•ЎН§ИНННОЇвўтžєьžОНч}Юћ>ЯћžБкŽžЅХ €Ёы‘žŽ“:zš˜,mdмXьоЇ8tUћ~фьЂ‹09$Fы_nѕ3aяž+мvŒ5oи8Ы/MШ9MОцЯыwtєќоev oпjDрЧD‘;ceшйh"›ЭJŠrKЫj…kw Ž YZžlѕ{—ўОХT$ќ(ђгоGр+РO>йЎмјЌw7™ЎQcЮ:чсщKš:%:˜{ЊћEВђРH_Є0x4Ќ,”­#Щ=ёP1…@xˆ+х}‹U€lу{LrR$’|kyмg–ЦйA JŽ!x9ЃЏъ={е$Ч„Ј ѕК9тЩё‘Ы9ІUp’1–С;зћъЬu§ЋИ\ѕеsзЖ8…qОRЃ™.г ВE(‘\6dKЩ‘З­ж)ШЕ>~>…ёчŸћЏў9љшsщ"п<|Q*SЗйJ<Ф’Щˆт|ёhbџ&КTE Dы8Уя а2л1pЦЬи1=Mє­И Ћ8ѕ%ЉG.ъП‰m\Meљ*E"`шлŸ‡-ЈЌ‡}ыwтзs/ вЙдЛЄiЛaqЌЩо4ФдШˆЅ\Ј™vu> ЊRБXER%ёВU.sоГЗЇПк„й+пС­^ {Ю)іb№єЂеUГСГ+ѕdL|лXУь/06Ь‹‘`ЕT:ф ’\Щrщ6ДtОљOО'€™ЫЋQUCz'iІяі ДжэКh›`ФУЋ§g:СЛЛчЊИмЅLщ”фЪ.€w‘IќC<а іёHЫžвіD+цотi$>eЗОД;лзэ•ri-pa_oб‡šвќiŒСюЯ.этыl’l];ЊёзС71mоj,Zп ‹ЦрyЈ'П†œ#W3vп2рn˜o.M—ЬžЪЫn†ё` §h ъgяBыr:Iшћ њwЏCOЅЕVУбиЩэтЗ€1šv7 ŒЈpN^…%гLѕ…XшyLЧcЄі@Љъ;JЂ БTU)Ž…Яœ’žкцб!€­œьB:nЭG?еЏ9ч˜Љѓpр-J”ZA‚&ЯНRKgAšГЂН]Ѕ№Крѕ`шФ%Й–ЌsŒПп˜ŽњЉ.rЭCMrPŠH#ЇV’ᇑЫ6@Я—Фр$ЕеN›дD•n6$d ф\ьCtЌkGžњЄr˜ёŠ2NDЧn–œka-dуЄ2r;Щ45‡ЦЛЭ4/м†ЙЋEDщцLGJ=$й‰ФCšœJY’0Ѕ*IiŒh^Šъjњб3cЕоц@ё[\љyBчњd ДщT|ЅЬAiєдrХ A Ё{gqЌ}ќ№Иj`$—ёgіoВZ„Ѕ‚КИM-Д8(šтH& œ…€нАИ=а’У` Э‹‡’УЅ;оЬhнЖЏYМН`ђXU ’i’zбщу@рpe@‡ъFBМ­@4ђТНbХЭhvЭэРњд\Кa+^ЇGёиf$К;HaЫ™­њЊшmн ŸўџSпНђўњRЎйФDчУ]З6чДЛ7ЛЈNІдŽaс„\љіџцьcЪ‹IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/library_64.png0000644000175000017500000001330211733011756022575 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe<dIDATxкф[yt\хuџОЗЬЎi4#Щж‚mйлXоHƒŒO–„4P’аІ-ЭJјƒ“8аs’fiNГ‘š6'[%›i Ќ!иœВ„€С1b[Ш‹,Ќ]#ЩЃй—З~_я§о{#0[2эщ;ч;oж7яўюНПћЛїНЁœsђџyЃo€Шч}sq-АJЅ[вл€rІјИѕ™žK’D(ЅbyХю%xўЏ•[–ТGџжeАжнrё­Л^|ёХC№јЫЛvюdтћшиїXЕчИw~HМwѓЭ7ПНМйэћњПl„нА> kЁћВеž—Y“\wОeY!ЦиGзЌYГcџО}іџ™8йіђ}aфн№№JbУrB]lЬvљV|WфBu^dоЊƒн=љжЖ6 <м*ЫђВ›7BjъЯэоmТЧљџюP~‡нЅnxЃёяН(НгПсшЪ№ЊКd$Й6_ЋЏ'ё8‰D"Kt]o)‹хjЙќ\.—›ЊohXњЎ ВЂ'œйГgOщ%`t‡k№ЅЎбЕ-I›Ž^ Ќ]>^,RП4ЮoЃу`t,%сH„„C!тѓљˆmлuљ|ўЊёTЊ3“ЩќwЉTЊš>_€#‡B!sw№wў~ш‰ƒДЧZП§БHџл РJXtзъ™o,$юRж‡–,‰„"KРш% ЄŽХxž€AФFƒw)"9*№8™L*Ш:јќКl.g—+Ѕ]ЧЫ“R&kEwП”ИВеМЛќХ" уєїxђёс‹lнКugФoК К%№kАЎƒесН.Йʘ/э^­Ќ5цZ—‡Cс8MъСгИ№qŒFoћ§~ЂШr­Pw?ГZ@И“Њ^/VŠЁGžяWя||TJЅZ|p–ќкЭй#WЏo[ „Щ jnшююоЉщz lА`aq@0Ќ›nК‰ЭџЛЏТR§$]J–ZЃ\ $ƒЩЎ`0ЈЋЋЦтТЧ№š№4†7zН Gфхp&œ№вдўo{ьЮиф№ŠХщ‘UЁBб/5дЊК.OuЕžКfнфжіЖљ­ЩDB‡ŠС&&'o9Ќiš O;^„§qXЙЯ}юsеY`Э-ч?RC›$*‘5ў іХ'Ћ!dE>ЃС@ ЖTUF ƒНu*FЉч'{ў#sЧ“ћжYS›JiН$rѕср№?\е8кЪ_jZ–ДН­ РAЌL6kŽ§ є|јJxdVЗaЯ >mšfiћіэ|VxЧwW?P€P5с;j]6ЖћКѓ?ОБЅЅEx[„Џ+„Мu2@ЩїНДяŸљqk__л"9їnB­ЂЧЫMm]иsљЪмM‰DСEоР}љ~ љEaYzzjJЮfГœ—”šВЄпэеЬ{Ÿе ЋЛ'п;Оkл‘3&AUV…Г L•"`AC~cЗБ_Д]^3[I/ѕќєwцv<г{Оx“TйN‚Ёa›(,W)ѕ\П…:_v3TˆŽЦЦ2Рqсј2XS…$pŠПЙЙЙ†e2Йъp*њю}yщр ПтI]kжзg­ `ФА'RD"ObuЯаЫЛ?Еі31№_Н1ЮЪ=Љю—Оўш=m§ѓVШЙm„Вї?x[f'ЎXпЛІeьZ(w›‘?š’‹„6@вDЯc:ЩЎ”~MјШ/=“~њЖ_­;nШ†ЩЉЊHМБ^5RЧu?pЫБY-ƒЎ<'ФЂѕKфxpbуГщgі]D6­FМTЈ˜хУП|ўўь=ЯЎГ3›6IкЇoЋZЎ=nОјб Д&ПR^ о^”H,&‰DТЉчшqЏDzњџѕЖюОТCŸИЅ'jvc*c†[ћт [ђ[ой’Й§зН `жu•М8Ё2EїЯНHјфкызLђ‰—n}ђБŽ‘с…чЩ…­2>т І*jhjьЏз‡їЗ…'Џ†ВјžXД$›šjO`ХUс ŒЦmЧcЉпјХРBгbэХ ;wQG„\ГyСx{gcIЗэЫIvХрёЙBhМ‚{ЌКœ0FТwz~˜–Foи”:є1т йдWШ-iЁ{Џ<7Н6№-!Д8би)М]!ЃЈ РлєFуіѕŸїяјљЎд* эеU-_к-Ќ_п6Zп\_Ъ@б;’>ЁБхК=—JA\ АW1єЖTкЁVN!SHЪс|d]пСшЫуёfв „†ТШѓЖŠFЛх№›ёwп:ќа_ЮŸєГЖjАѓК–Ч3ы.h=ЌTГ!}iN‹!U „™$ŽGmNTхsе P…nУЏш­2-­,ИjqcьœDМkб"F:::„6€zv‚<еІ›Ќџъ/ъHU;ЫЛЦЇJlѕЪФё5kцПlћќf^'$•сД §bйЄDу- ЅTHУ‘pЛСіpmЂL}СtQ^qпЮCŸ]шƒžFюђJиЉЖЉ‚ЕїЊ/ЊРw6 ŒU†‚ŠuсњІбe+šвQэ ’J™‘ВM ф;б˜c8?1H|АPS—АхS„и™@_'(XQѓлй1]яhЉшЁК[я7њЇrхnћtєƒ˜Вџѕ‰ЙwDлyн7ћтšЮb­7јѕKЖД .XœЬЊœЅŠа#X6бl‰шLBъ!І  ‰0oR„сЯЇ+.ЮЯFœP&ePt!+PFt­TWЊлуѕaђЭпАОЯМпюH”З"HŠѓгОPИћkџ9|Ўeѓ…Uƒ/km U.ЧМcm‰\Кh“TЩ&%№8€B,hН,š"ЮF–j“1‘ъœИмtЖ"ЏdT†–)ь/Њ–^ЉVЊ ›зХјл‚м7\xђіэЩфяžgн;ЯЌdŒwUtОlљ’XaлцжофќњвD‰‘T‘‘ь‹N€Дрiˆo[`ЉDъ#ŒŸО ‰485 žq 8ƒЫ“DVќ6џ„^/шFГ"Ы/yџ—'ХLN’Џ_ЯМgkћСH<ЂeЋœŒBЈчРшМ†b є>,vКЈ@нwOcт’ѓ>xн'#o.”3ёК$ЙЦЫє q–ађuёЊQе &ˆфѓНГЋ>ћЩ-сAП9 вzЌHHQЧ~Ъ$7Є„`rgN@…ЧёGб.т ‹нЧŒz" ‚sё)т”о чщДˆOђ!u—ОдЕГ€”№еЕp*Ы>§№Ѕm“XРœ3оF—AO Ч‘рИцN8ƒцGуЏЃќ іTМЦ…C "“xпЏ8@бЙрaЭx х ?nеu›SЋбрŠХ…€Љ‚ЛБœyѕ[Т0fР\FPачN {žNt~ž3ЭRa’Џ.`„TŒ7Bg›œаЧƒАT\ЕyhП $†}И‘; ЄxйВїJKm0аFЃ wsл uє42=Š9ц‚Ь%чШB~ЃЧeч\t]Wг§“–nЊ ѓ JТoњЁThMЬ2р `(ш%*Р`цkQ[Й сlТЫ‚Ч`5ДЊœКЬ-D“ Іф—С]’ЗЩ9ЖCtnžSЗжc4LeЄwЌ%ŸЪ5HŠlЂ!Эя—™ zKuН?G)рx#@Vœ’Љђ`7ЪXЮ$››`Иn0f€€A2@ИŒ9п“]DnK8tq"œУ^С/рgё5цF€„фh)c‡'›ЇFЇ)‚RоЕ2YМr[Л>R‘*ЧуШвЅFцЇ`"…К•РO[ФZU“ŒлXэЊ№МЭDд‹lp"€OЇ’‚ŒЕЬ1[lл}OіТŸ1yЄ Oх’ЬfBрЎъj*мxэ"жею ИN3Ћ Б*Ъ1ЅЙ(ƒјЫш}Eqц?—lo‹иšMєВСeƒйvаt r Ѕ\’1RьZљСФW]š6Vx^Ј=L/[:2‘œЬ4й6C˜Шђѓ‹7§M'лМ4EdL­ў Ћ<;РВŠь–Ш“ё™Dаћh4r.’Ÿ I•5(ё‹TKWќŒ)*чВBEГˆDЄ€[|h)ЈЙZЃтx˜ЂсˆЅ}=р=нВЅc=ЉфpпT“mйј6YxNДє…П?зкК"УясљьБ3є˜у%bрјqK&­щ‡йBn.кдг (O)йRж51&3AС(…Ћ>‰*p–Њт{і2D‹‰‰ю\сv8Эѓ>МІYL:М?еи{`МХаСpxПЃЕЎrѓuKєwwEbЊьдб§ЃVюA0|Є@4$ ~/Ј,M“+•Шьvƒрw0Тш@xЃAT Yб‰bbВ3 G‰њЩѕКk<ю‘Ђ%sz–@УбТiя‰јўЦšЋeCДŒmбъіПэЌОЗЋ.цWi_;4nц8 хИ†_,g*aйЏиЁњАЎ@dЊЉхО4›)`к&зЙ…й„ЧЧ`< ,ˆŒЈ]цN•@у§Pзаh@с“ФsYІnЋъ”9tg>SѕwwOХЦFŠЄТЖЖКЪеЉНoM4 †ёїћ&ЭтCћЋуЏЄэ*Кxj,ЬФŸb7/HфдFРgВЋg• Ы`Ѓ 2о (` 3Ev]’Ѕ„„? 0ь= |Š\ѓŽSІ№ЋЁ bЗЕз•ЃQŸНЕ+цЛbU]CЬOЬFВVљЗ*ЉžЃŒъ85”kщŸj24[ „UГsAДo ›@šд)ЇЮ1‚ЅГ7)eЛЈСp<c-EФЎ0Bž92ЇТћП Р уaOЉ+PМ‘"œ$жЉv437H1)€'?VАЫOе'їECГЄ‘ўLbl ›д5г‡Пг6/l^џЁNНЅ9 DШш`С Ev.!H50K€шІFЄ У ХЇfДTшП:ОŠи‹|w[ш™В2ШЮkм“Yљ…+н;i”Ы%K:v№xгБоtв˜Ј‰Ц ўйvлКbСЊЭ}Yn0G>S,В7  ый@3ЋЬF • ф ” DkЅ ŸћРћ€Ou@№ћ™"ˆЯвкаBH{š#–жxe(o—+K:|`"yА;4 K\“‹EкЇЎYPЙњЂЦhHЅuаKА#iV~њ˜™ЮдRхZЧ("Ыыf­@єnЮ=€Л„В“f %"R PjЦУsъD^(•М›Пœ<­IaH6ЖœўщЙ‘–‘сb”YЖЫз\ж^МvscCcX;& vuз35”ч=/њDŒEžЎ,ђ\щ€rŒОЖ іћ%D $EПЫоХЭZgщ! &!‘4c CЋZе­.œМіЂ††љ1Eм`•Ћ2уЉ^}Ђ{мЪCџAEЂгзъІН/ЛуА71}?M%(бщžќе­‚Œ$Ј`HёђŸК(PdЏэѕŒ-Бd‡PЏ]зœYuy+йИРз.ЎXмонЇMюа3Ј#QgxbЧБTt‚UЗЉЊЕьt–…'bошТi рDРLУE И@Ш4TД Žзˆз"Р%•ЌgмЬBТP,ЛЛ'f< В\вM644Ў}xјЁ­œUє э*Nu8уЏЙ*"tJaЌŠыyЗ#D< ьщ'OЩЗPgЊк"Ј;ЃŒNяуЁЕІ˜яшubYЪУ Е(‰;Sг9уюўБъ'ŽякVšM7U 6™дI[H&Жп!0Т^ЅTG ŸаcШŠШЋЌЎё6Vbгеg?8іFа<уьh ЏѓS26Rˆ<јшP‹a2…q^ъЎ|ЌїžЭП™‹Kc;a5СК07nJЬЊsV…ˆ5ŸЙГlЇіŠЅЏцyYœМИZCkЅ›{wТзЊЁ'A=pИл3`:T4ЊŒЬЄgvO$ўt`*ŽŸЫ—Ќ=§c•AШМ•ˆ~+мс.М'ј7…Дyх…щX"Ь:q^т ХёМ3B›!™gVSъIbч ^ёЯ]Б%J‘TU”8ЏW‹КЧ#ѓA2ћсћцрxѕћЙёkЇУYЇC‚Ткы!H‡–c/•IЂеw8iУeхфЅˆz„(‰[аФ@#JvЙ€b(РБа№0ш‹нS ЯОpˆŽKšaєUЎz№т—N—ДOЗ <k=Ќ]F•-язkBƒ—ќ%F_ЃŸмaЅаяЮы|ZHчRr–6ЎŠ$‘S~uяРМLV`)œШшПHU? DW=“Њu&epж&XїC›ИХЎлKxс/tХNqЧaєTWЬФе^юvЧœт„ŒŸ@у%№‚ЋхŠ'/вКяш џіm/ЫŸПqХ@}}›y?wiŒ{єнK&ш~йэˆ†єЄцџѕУCэЙ‚cMъ_9xзІoЯКp›Эƒ?rЩ.ЈЧHйQћюПщЌтM=ЏЗyWMЙCј!€7žн3бјƒ_]4•5|šЮњŽWо1ЦЯ:И)эб ЖŒN™‘/џѓ‹K&RyхюБТ риЇZ4дџтш9>=бlCщKчŸ*w >pё~2G›4К„ лЏЄ3vш[ЗZ<<”ёЭЬgpС‰OxžžЉш-?:ДјиP9ЦgF&ЕїuџjуЇЮ”хп\†„`ЬŸ eјЮПYrєhКvœьоЭAm&нqз+ѓvя`‡a0Й\Еž<:\>яи}[!gaЃs§псфeODъBЪ. З?Еъc>{*kњoнОь•€ObпљљБŽЩŒю‡N‘AѓљО{З|œХž?OС _ў/0јо,qщ9св`ЊЦЫ„–ЭMхЭЋFоz˜œхž­2xљ Ё€єIxHЪЏiВGѓeыfHƒМ =лŸ ZЮІ eћЋ…ВyЯиУ—ь#oуі? >Њ‚|‘zЁIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp_16.png0000644000175000017500000000203511733011756023515 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ПIDATxкd“YLTwХЯџя{‡™a6іu€A ЖbБ5VmiгˆmЄ`bл>єЅО4жЄMћаХh5JЦиt Dг6q” ŒlВЬ0Cgcюм™ћяэsПф{§ЮЩя|‡œЙѓ=у(‡зži§rha№јЕБ>4•яХWОјэsддbknNпўѕЮDф0ю>К‘бZ§И9зд‰Iп82-Yu?ОНN ƒgQWд€ї~iƒ/ВŠKКz:‘aЪФ_ѓ˜\‡Ч7Сљ?С;VBачљ ЯwрАЋml*8ў”Уф@šУŒeМїaДR˜Э„ т ѓфd ?^5и(`кР†А†ђnоМЗЛЄж+ђsP\™ЛˆЪвrш $СEЯзшыЦбКїAaŠТjзЃ"ПWVЮЂКvѓлэM мEQnœкFMK(Щ)уšЂ‚ЮšcИк2бg§•fЄйiЗуuч;SO<‡‘aMУ[-L ЕљѕиUмˆвŒ2ь mNœя?їе›ЇZOёЭ™‡4љ)Ѕш,<›ы=hДЖЂяVџЯ=НПн.dasjЬМсM†‘-bљI€‡,ћ—>~4Sие}?иВsџСХzляУзЏžщ=vnъгЫ%TѕU…1$–ЇС!Ф#PцGС­ЯNљ8ё%ЂлaSнФЩіЄ[х1<Уиb(V'ŽsФ2даpр…эЪ=7иƒkр2‹С…V€DЁб8[ј/†КŽюађxUм˜”gКIШH7HevЙ3ЖuЏЩДъFтіiІи>1Ћ8•&‚"BA09тђЖЭR‹DЊ+ВИм“ UИЈ^ ЊAGp}Ю(єŽЌ С›эI§юі 5XbtаХclёa7Џ`X 24ККgцpœ!‘ƒ•КљхэiйeHндhєўq"И ˜­Я@у2ЧsєIPИ4$ЏЄ№@ReкыЊШЂцn^*{Зdа)Р–g)и5i)5ь[cМюЩЎ|…_В“‹ы‰ЧГійl@}ЬLьг/ 9p™PХлJ*ЖYAУšm`Q-П? ”жїBжx­Z0эВЁxџщ WЭИVЅ]Ѓ\\їМ‹ПџQTНBжCљ‚(љˆNBA˜–ёџЦнІЊЈH:н№ЗС;ѓ2(чARљRj Ж!„з– ШјW€ЩX‚ e2єШIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-group_25.png0000644000175000017500000000236711733011756023364 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<™IDATxкД–h”uЧпїќ~юžнн~œ5w“M7нšIiйH"pL[§!§‘ўa’ФbAL!м‚hфj`dRQa,H IЦ#E-гrз7Змэєvwлѓ<їќьћ<ЫsMлЭE_јїЧ=пзчЧыћyЮcл6ўяхЙOˆЇeOќ%[тЖгAaЅ7РљнF<ЎЄ&GЇ/З”Ў‘Ѓu_-ђђ[ПGљ2owАТЗFН•CvBœГ!3 В4‹Б?е\*–ўRЯО‘ь_—И/ШЮ=ƒ•REбЗ•сZ[гQ|sЅ6B~ ЖeclBЧЙ+~В#HhFњGћдыщVJ:ЯS…%kЄИАјaЭšp­ Ћ(O'ёHжN ѓ](+бX[„цѕ"V)cвг(_y\,ёэwž]фщч*З–W=…Xс\OЌPфЫЉˆХb0M“ќЪBЄ„Ч+[‚XЊO ѕ} TШї‚ Ж.ТИэœHSЅ екуlYх Ы2ВйihфЛ(Аx§ХД<щ…M3ŒЩ1;œ3’вМMm ЕJ*‡%ЫLљ8 iЦoм@:ЦoWЏ‚Ђi I>јŠќX^aC;/У#yWЛчƒ4ш_5U9&pNЃqњЌ…2[ХІ:pУИ1>G–cС2,8žƒ‡Ђ`™ЪТ€-чр ByШ\MыWJw4Ю€&šzˆІ)šЧОяlT™<šЊќ№ћ§шъzmmmE<ЯйœEP`›3цRГ5-_јІq}ф™Ѕ LН}ЯЎШтЕомlaћЃгh’ЈŠJHT4рФЕ5иѕvЇл›mлЖaddФ…А$ЁQ'(PДTВM3‘(z.”ЃЃЃэээ8pр  љeШ@пСb"єŸѓХj:0цЧљ!ЭЭqфуHр ŽV•iT†)ГдgЮCЋЉсaб{‘'ЊpИtЭФўЃd)?Š—E@ыZяа`ъ‹|у™€АhMЏв^єœQp9І#У•@”L%г—hK{•Xkх3с%FЪ$U$:§ррр?4\sюжtJcёn/™ФJMз3уЉу$х–“<4v[*2Ѕ‚д‘DoЬ”(“ &сѓyѓš:‡;šКЊ’Œ8Žƒ3[щ ˆЩœЂŸML([O\бњѕ{ѕзg_ Ы“RЙсИŒDb‚ьrС*+ЃшмЛЗІ‰+GЊJћКЋ›~8\ћ 9юЎБюB&Ш 'i3јьд$Ює]'кдйСPЛwжtОхB”„r(>Ђ—iяїCГЗўNig“ђвД d*vЋGŽO~N­­С_CЧ$ќ1*’rЄс‚;* i:я;;ќXŸ; ЃJдCGKзYS9ЌвGЩЅdбP#€Lm Цэ;šђ3šВв<лЂ‚ПЧKєюѓј}[(ЇЛг*Œщ1ФеQBЄ šЌžЂL}ч\‹ЙН–lўѕyJ`vp"џАMБ!“ќ#)ЂЩo^ЁLЃ›XєщН,šђ_жмяЕў`mП‘JtЧ\гIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/route_25.png0000644000175000017500000000270411733011756022270 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<fIDATxкœV lSU>яОћњѓк­ыЯкmвmlќ3` 2œ тЂ  ˆ€1DDИИB4!Fb9bb$‹ы †EС‚Тт8Qœc]ЗЕыўКіѕч§\п}?ъ(f/yisя9пЙяœя|ч2„xи3їт"эїЪОsFЮЌї[ђ­fЂ…з3LВG џањЊC/yЈЭћY'Šƒ!ХЃР9hžOяc˜t—Т<пЧ)\Rѓ œЕјЛњsи8ыс8(UіяцмћЏC<`С ёAЄ@<ЮаeвнУAWPŸ &ѕ—AЧШQ0ЄГNЦ"™!щVЯ€"ji–Ѓ]v rJ`RеD_‘6ћЉi%9 І—:CБ1Лƒ§іЮ РzBMFˆ‡ф§D†ЏT ,ж'Ч”.‚˜%—n5ЉћЩѓE^v;гV МшаRЦc€thЋЧœIџF*œ”AŒіy{%1ОњЗŽ›ЯЈ†СH–хЏ)Њ’"ž’ (’Ин1kъц”щJ_Лsфи,€ЁbТ‰*PШщЄ'|љ^кV:‹дчЭ,pИ_{њUшш…†яO%†ЉШ{н>вЩCч…y 4Эѕы|љ^ˆgЊшђ0 BыB_nЅaБaЙoёžЅЫяЎбWWžь+ШW1зѓпžFЪ?yЙћЯЧЯЊ{цэЈѕЇ8wз(ОJ 2rкь"EI›˜Sh-™<зŽWЈœ…{Є К“/й-ѓћлы;ќПn<ОѓыМ‚1Њ{ќHR`WХnЛПЯgНхk9Іт=—8оuƒb0i›–ƒапрf0s1oЂл§ц‚-аш”ЯпіЪ!!H’J†‚Ќ;З§Їfы }iN™з!8x'ѓЬ„26з•УвњнљУч#™Я[—љАавЭА:ЏЃаьЎ\Z fž‡$щfsm6 ƒФЧ ѕ”uT‚P™Ё*€dˆHтnHЗMŠѓ‘ђЁ;t;тUёЫ0b3ънюќЂŠвEаёУ77ы!‚ƒ`TUУAРРЩ@ѕjTŠЋыTfТ‚`ДЎ ^… ­?Т‹yЋ`Cщ№$Юљ|mѕˆФЦй§Н"|yѕ3jГIjWЫZгбЊQA-ˆЖЎюSЛa{IѓЇ8тR|lv­o™™?a]Еw­hw8хС>j1бСт0PХ-ˆІФЊPRЃ2 ЉbšEВAУяЧƒ[ЪvЌ;лfoaloННŸю5Yжц Rш$цй %Ёь—“b“ŠУjДuуyЪ.7Тцz‘Ђ‡ДрrTЁюq0LC™еqO =кA›”ЧŽхƒЕWьлЊЂŒmыЛЊ‰Šƒd мŠ8і€’”ц%ыЭї›1d%Ј2xЧ=6ЕЈxмЄРŒмљыv­zччВыG§’§мЊН>щpЃ"Ълг\[‚ТRuќЇЌdL*ЎAUЫќ/Y•‹(Х3 œEk—#ЫъЊіЈunW‹OОŠЁO‚р“ >}‚oBБ(>‚ј KХHuiБ6ЕЕІP(F”І1‰i’ЭGwГйН3ўЮЬмнЩ&эfw“мьРьЬо;ЛwЮoЮяœ3gv…жšіs:tша @ухШ‰ѕnѕЂls~Yд…ЭЬœмжќ‚ћ:ъ'лќŽOQпlЅј­VБcg_"с ")HHЊiЁ~ш“ЈЖцšА§†nЖ…-@+ѓjфуWWл’эAx­lKЋex—Ђ)]#ў“ƒt@Ÿ„ш x5Хгƒ ,m ‚$g+›ЙЙM\яю4‚VШњ HО ы/xŽ˜дA-жƒ`VТћш{hyёЫ!#hЌ:е_Ѕф‰JЂ-ёG"e]#zMИXLP‚!mAˆ˜ MA ХќЮ&ј:JhнšзіŒ~x Су‚œGˆ$ж‚ CЋв]ѓ"хжQ кЏ@уAжЛ1ђTф)`ћŠьЊГ4ў4№=v‡ћ‚еО‚Ф<Ю„СZРъ§AсоY АFiрEЫкПІАЮѓЖY‰ш`7Cbc„3† ’r› P@ЊˆQ vыГЦ ЎЏЊќ7ЦPG‚ жR@)7ИAJЌКФшћU <”5„‘O‰Q0V;@Љнх§’Ѓа6f7шiЗAŠъgƒиV{eѓ@>о'w{N№Ш‰/Ѓyo‹aƒk)А1&†О7МŒƒёъЌ^ХГ.o1—цGN^i€†ЯёрoбМЖй˜ирѓег ЯЕЕ}Д1Hоз+щ™IЧzt GR"ŽлИџй‡Ѓ[M#…њ v>јфЪCƒf%+Ч]џkыРGfq,ћЁ>IЯішшAI§н‚К“’т1 N<†н!ЦЎBФЙœІ‹šR`цP_„№SлЁ@УЙ<˜OmЯА S‹&›kђj}kŽЧTшюlаійђЧ0 N‡AVгСФљšG†ќ=йЂІЉБХPx.o Nmзl+љЎЃ9gl] №V™ їЌаО=G5Б‘‘уВMў-а№7усЃ‡P‡›a›‘}ње!Е„ ЪO‚а6'œ€Д]> Ш—vBОK‹ёg Мђщ2]њъo&„ яBuœaЩдJњ‰4WŸU> ЎwAтЄoепsqE X.­hњёЛ *fŠќœeGЛенРŒЈ\ М)dЖМ№їМ7Aд“`О[ №ЅЕЇЊ еЯkКўkšвуKсsЮ‚vš43{Хбta‰tЉИ!aМƒР}МжЏž€}hД#е{Ї?nN†пТ_lv дь є9ЧQвЙ4Ё6!&yх\Л=Ђю˜Ѕ€'­с[-iš] шњуюhюЁОгŠHАйА?mИЊЪEИ5Т'‰Уїєr_RWœЬuVџgrŠRЉi*d яљ‡RЇАњљН—‰Њ=Рœ‹Уyю"Ш‰[с@„СHј,М)—wkt‰fЧ+?{ТЕj/аЊC˜KЈчC{РМїyхЛˆŽіKё1НIИ@Ј?ЧџрW5ЅJtяv%ОљТоЪЭP+OЁ˜ГwyљUvкЌє1ФњЧ9фэGЬЯ!o‚ЯЌы+їsK]К–D‰€хbQе?•Їг)Н^4IA Я=ЦYћМЮ2&“ ћ§žёлч,QяsŒuЎFоэvЬf36›O зyGХSUŒ-+_М/–|ЌV\.—š:ЅтЉzŒГ…‚ЕJžч„!д’Мњk%Ÿы­НfГЩрu@š$ЬчsЖлэ5ЩЉCK^ю=OЮYюOЛнf41iЕZ„P-кГжэй_мыvЛtž;dйšB1“ќ0тQ4Lƒ—~юПЦИšхх>HDЂ…ТіxУг$СxUЊЁМХЋР ­pužoбЦЪЄ”СaIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/newobject_32.png0000644000175000017500000000143311733011756023106 0ustar sylvestresylvestre‰PNG  IHDR DЄŠЦgAMAЏШ7ŠщtEXtSoftwareAdobe ImageReadyqЩe<`PLTEf‹ЦЕШцDDD_qЏЧды”Ўбђ9хыѕ“““чo$эTкуђњќ§ўuƒГйŒŽЊУг Елњ у‚*ˆ˜ТэёљЋРсОЮшЮкэеп№џfї#пчѓНЭнмИХО{;– tRNSџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ\\эIDATxкb'ˆ`( VF11A`q ФРРШ.))СТ".ЮT)ŽЁ €ФИAВ`i1AqI4Qе/Ш*.)+РŠЂ €@ $8˜8€  dedYQTXDˆЌЈаd7AЌ@œGЈBI@ШHР<4GF’EVЩVіP… ЋˆŸˆˆƒL@АKBŒgcхc>>„€™ tD XI@Mњь  ?yyAv ) n ММB@ + `\ˆJJ‚]T! TŠ7$GH77TPЈBHZš‹‹‹Ќ €@ фЄЄЄф$$$„xQpr ЫЫHPXJR‚—SА<@№@Hb*€‚+р†Њт$ФР Юr?7аЉв@WHKАHААђСШH(;;ЛŒŒ 7и! k Ф фхЌЎ‚[’W*Ќ p€( ˆ АIn Ap@|)@P(Jd$! фA ЎЂЌ†Іˆ…Da@I@10‚“ CR@ X\@10cpФ@(ћ—0IлЯёIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-sub_16.png0000644000175000017500000000151711733011756023662 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ёIDATxкœ“]hg†Ÿ™ЬььџІ1ў i$Ц JЈ–TcЌкŠŠЉа*СаJлJяzбоД ѕBє"ˆ--X0*XhзZŠ5СќМХкŠ(ЄЅ1Ѕd]нmВ›ьюьью|=Лыв+}сц;пyпsЮїЭ ”BИFј•pBјp­№Kсjс'ТŸw~–PЇч•эиГљlФќe­&%ёЙR|пЉІbEК7јXзlrt(У@_„Cб Ыщ _ЭѓoкХkС[]Кл-&ЎE `лйЋЃ7^сэx‰e"И5ут*˜МSФV>ПŽ-ЫТ5:“A35ВмMщbp­\БiЙСпГ.‘ZP@Чуе˜Зe<ГКжEА§E/о ъL%]ъъЁw~кё{ЦеЯyXзj1rЋH,­а-?.ГВgZ–Ogz.MAі–жмKоCїš^>&у.3s.mMнk=,Ў“VЩaJхZщ >Ђ‹БЫрХ<WyиКв`t|­voHХгŒM•*_m1Мђ!›s{VбжiЌеHх снŒb›ˆУ]л_СXАи2сдwiыzЩK?ВсјЗŒМlВІБ —Џkј[Rgyhв |tЖпp35”oœЛ@aтkТ/Eh &™•–GŸ=Тy™_5P1—ЪOЧјсћ(S;Ўбю}žTMКj VьоуpfџЪВЗЧ)‡јчЄŸkcшм0Жmcь‘ƒ5L4MЛopЛоp˜>&Ђcе№ŠwВїNѓЌчxhАћзЯйдб §'8Х<ђщRrKDЃ?qЃчЛjМрр–JUƒ›п(ўzfšм|Чƒпя#  C! Ѓ†€х'1“Јф–бlЮу8F!ъ–Чeѓж-Y'ям –ЋuPyU.ЉT*ŸH&W ОyТПЗЗ—Л^S…ВСƒФОїоїѓШЫa …ЪпШг ЅuЅ*пШ ЄiK”BœНIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-neg_16.png0000644000175000017500000000200211733011756023330 0ustar sylvestresylvestre‰PNG  IHDRдЏ,ФtEXtSoftwareAdobe ImageReadyqЩe<ЄIDATxкL“kL›eЧяЅ}ЙДeРИ”$&Ўb–e 1Р ё– e‰Ц cYTLFЂЮЛ›ћ2Hœ˜EьУјтbœFйf4Ђ˜Ш”/‹ŽЫ&wJBяo[К`<Щљіœџ9чї?ћы{№КС5ЉЙPTƒ_Ъ„§pћїw№ЏїF|kMŠуёyД$шяХ’ŒJ<$‘1˜ївв(mmЮ™XN­жЎззу™œ$,ІЉљКCLз#<‰ ћU+Žќ|A-Ќ­%АМЬHg'#]]Шš†§РЎ74Ф‹MЙЙ8šš`ш ˜RX! ыЈЋ BDЭTZ3Zs^?Е7тїуКqƒЅСAІ{z№/-aЮЯЇЂЃƒћlbїщ_Dї „C‚Сr єycљ%ŸЊDѕWд№Ѕ--јцч™Иx1ОŽСdЂЌ­ ЛMи7ёh^qlтdЩё{ы•…“ЄeOˆc6~Хъ]Xe;t1бLo/![5ЄлС(‰ ЪЦ~х™ŠKTц ‘чіЩбšжКЙщзq ‘RTDсЁCФ"‘8—?УWј&иЪŸdaЏЫСmsіv#љж™3ќVWЧЦдц‚*Яcџљѓ77ЧŒuwгффˆIмШžЭMaЕК- ІяоЭЮ={XЇМНьtW„О7”’“эФэ-&YeepЧЙ(…”ЋJўОwqФfўАUUT4эђŠг‰­єс“t=эd}ЖDYЊkиѕкЉŒ$Ћ•Хz [)~чД(ёПјW€Аž€XлЫIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-group-neg_25.png0000644000175000017500000000323211733011756024470 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<š7ё?ЈEёБЎ(ЕcСH!‘НN КА‘;м69=oсŸ\ˆН…@7‰Œ_,YžrGсЩœИюsaїт щЛyƒ\Л+ў№спљюе!ЙqЉR†В2,2„ 0В—l™w[ъЕSuючј$ЛC_џйщ+“и%7==Ѕ{І‹ЊДAš$ЯwMDѓŸe–œЄёШп’и:&VдBЭYЌтQmЌђ/оўї0ђуЧШЇїBБ9„цм`ЦТBNGп@<]ŠђК 4аgш`sTќІП‘?нBЇЄŽЁž%КжxœиГЙђъ­@јѓНыmї†€ј?fPRхF6ш$OьvсЕRq]ЊiкЧ–=ѓ.І'С_.‡ Kš“–ІTЫѕVœЋЦ8яЕ""Хьи$WHУЦmтŠЈoћуZм§m[&юаєНoЂ …R"ŸгЁиэг†oI‡­КёЌTєЕ+‰§ж$џЮœф}Дv)sВ6žЇђ7­“JЅдfk$”Озn#›A.PЩJsšї-\ CžWэа|ѕdЕLЛђvn№Д_бПЗР3ЂR ЪлдzЩСТ,Dй€S…S„ „ђˆЈў4ъыG]§*<Б-Э 1|њWG &Ч/Џ…Ѓi pВ|і)ѕ9Ь;ІZf(DУЁЃSЉbVB ї­ žPќDZ€Й)MЁ,”Zг‰ЖФyь?љЄti›NO€ВИ8ШїyЊ^‰ќ”œвх’Ъ?ЛWyb’ъ“оёlrО(/`ЖЬ7Œ)ЮI‡˜ЦrŒж ] "ЏЩх‹Zg9ЗˆЊСу’Ы5у\БёŒвёњX!;€2АЛ‹њ№LТfF†џdн(YЦfwўяс?рТR{ ?Е§œTtб'П%Ÿ_ъš“XЙu Cgœ˜‰е FНВ WtТаatтjБ­:t}}}ЈЊЊ*uЛншююFooя§’•T>S№<єШџ”UЈl+E*вHvЊeЮšЁЄ№жU,ЂmDЛЊјŠ ^Џэээ8|ј0š››q№рAlоМљ>ш›Ж@OwЫЫv˜:Uх]КО~<ё50КХтс:Hё€B*tЊt,Ы }šW7П]ЌјэлЗ#—Ы@jjjpќјqьиБЃВЕўщч”–-2"t/gІˆ’$й–,KŠ Ђ’# “SdсšJФв3П–}Ёax§Зюkваа€ƒAФb1tttрќљѓE™c/ѕИj—?QКmЋC…Ђ‹м$ ­ZžеС ­І’а/|ЫПє}чъкmДzЧƒЦЧЧ‹єэлЗЏ˜QaИ sOіXчяљЅоѓ>gBPPœм”ЄLLњœЇ‹Ц*ƒVцƒ’š| C%ў@КККАeЫœ8qызЏЧбЃG‹ѕєєЬЎЊplxђUnЋњ˜+N6Mй€Г_'>ЅЖ=dAЇ‰вMЧ-ШТ40іНќ@ЋFЃшяяЧЮ;‡Бkз.ЈЊњп7\А•и RF)юмВƒўIP}Œ"яDђєJrиZfw_—§?{Mbь_ћЊNФ—ыи§/Wђф’#2м‚ВРиKzбZЖЛјлeНљь4V,ШџћўŸˆёЎЅt€aIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/nat_16.png0000644000175000017500000000047211733011756021714 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<мIDATxкbќџџ?%€ЦHˆ- ЩЄ‹'0Ђ$J3а2LРР,fМš5І§Хюd 9§VЭз3™p‡2јyЪ“сџЇЏ џО1ўџх УПЯпž=ј@œьfл)sСп;QлП|cИЗt/qбˆ nѕЎР&џЇ0 ^ѕ /7ƒ(ƒЄƒ” #У’BF ~FЖ_я ЛрT‘^'ЃЇ\ Ьzо2№№0ˆ\РЯР tДа@Ьњ‹ˆX8U"L™ HЭ\,Ив8Б€‘вь `ЌЗNуKТIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/search_16.png0000644000175000017500000000163211733011756022376 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<сыя Кыz `‡Д іњЭJ'{ašл}YŒKЖГ8э7f’њ5U‘?:Е’:w:[ЦоОјіКъyЮk!S9§љЅUљЇП'с#&&HГˆƒС-фšgё˜yœс=цћџ(cЮМnшo.ŸџYо’rЫŒAтУ}‡РVє.з‚Ј}u‰,~єЬD<ВN)§Сп…№šН№Ћcvу9ЬэKjн>Fiu‡žђ>lˆ>ЎўQ >Ёi' Cћбп%а~п1AСУ)(М%Тјшp@НхЁбц EGW™СЭvћ§\Ле˜туХ`р œЛ&b˜ŠЪ Ыёљы,ЉmC@uh*<ЂAЂ.щXЖФПяж NЯ.яOXшn‘ЙwАЙю#%!M„Q*я *`лm7lFz‚p І3sѕѕыЋЧfR™@ЫВМ;…ѓe (T€* №{]а<˜ТБЛпЅгЉїƒF0бajЕVЏ!l†ЭІгhT:аM•Ш’ъŸeL)RcЮzюj>џРЋё‰hSVDЈš1Л№ШаW …лџVjЙx8h„|Еч@Бm„Љ‹Rq ПЙИ§сйw^p[#"Eqc[Ѕ„'ŸZѓ<єњ6—ЅY~ж GђБёё”ЫЏ\њЋвВъ›'OМu|х—+ж3‰Я"ЙЯн'јјндН€Bxэbx`‘P aд œжјТьєЅЧќФУGІс_; !ќЦœ'EзШmОцIК КЎЛїdГnb2Љ„BЩэcБЫ‰Lх]ˆ~rўј3Ћpэйл{cЈB’dF%кgŒЋкџєTЁ6–_лфтВѓіН#`зы їCUuY:КљхВ>V( Ž_BьљГ#%wTРƒa„Цј:кЈЗјтЉпшСЩЁ’ъ'/Уkџ 0.YrBбЌIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/state-sync-cluster-group-ref_25.png0000644000175000017500000000253311733011756026607 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<§IDATxкДV_HdUџsяЬ8ЃЮшИКюŠЫFb+ 3ЗЖ(ї!d)a Є‚Lz1„•ьЉ— _ŠаЗ№ЁLl#!Г•m[]5З”5uДuœ™;sgюНЇяœЙ3ЋЋP ]јюЙ~п9пяћѓћЮШ„јП]Оњ™\>%y‡ФO":˜уiє†E2KrыЃ9ёіБ@ЄгМт\GKл€a x$-МdzœЄфx ЁљT‰Œƒ=K`гtІ5KЉY2Яъ"ІmЄWл|&yє H—в#ЯœОЦ–ї”=ьe Яq@xўУVЉоЈ7ћŒєx5ЪЦЯ<дПЋџЦБьГлk0ЩЎхТоW ™…OуаiMИх*ЇLj eF}и2V ‘ z˜—Ж e‹Iкі0I’t™‰eХ"Ъž*з gƒpD.йƒ=гТ­Š=Ѕ^Ž9нЩlgT$,ŸmcˆЫ‰ „ЕЄmGЎТ"gФ™г~›’­ ФQ‡rХ’NC^цф"C эaIgœ –Еtp}нФZJЩ,Б•cђ"и “чиš!Š џi-OC%aVыф,п‡œю’@‚yЉ\AІьOTшhjЊЌœB•іЏз,XЖъЁ–Ÿ ’ШиJжуьчши=ƒrœ№sœ"9аР%А[.M‰p`jе•A ˆ™ЌjќїЏ„Я•п­$q2 ГвА‘ДАmкjfl]žK‘—Т~мЉЏFKнyІЉХББЛїw“iТ1:ŠОGгѓCE}ЈDSЅв™P{vЉ$WЃil6=†іѓЏуJMўJnт—•)дІlЉ|Ÿќ–ЅЁокf8k1|№ЋhV паРyШs5њЊ˜–ыCОВљ-œBЌžіљQ[К‡ЈСzђ.Rlх•{(6‚Ynм3q-,TР}л8Чіп[џєhЏ/ПСёэƒэи(ѕ—тН %ˆ„ЗЁ§ЁукIЕЏНУОјЬAп^Ън]\IУУУhkkCIIЩОЭuбІj\lЇSŽкЊ‰Чтюo^вБ]N—ЊЃptšq*•Bggч‘й˜лЅYЭЦSBь„,4]ЬЙxўЧ2БŠŽЊ@6уŽвгФЧЌЌЌ brr‡@bЅј=ZСno…йЭ­rўs,ШЅžˆ˜HЄ„Kв`PˆёУЗ№ьь,zzzАААP0NLL ЉЉ ]–XФAбZ4VЦFNПdВЛ 0OЖFxБEъKббQtuu!“ЩŠ<cffцZаU'DДГдеdУŽ-Š*oˆЅе0ŒИъћћћ ^ЏѕѕѕъЛЎЎгггшээ-€ШR$зD Оь”3?7Д ‹)C€яzЊxдІь,[ЁхŠD"ъЩІ‘‘UКССAŒAзѕ™­~e?%зђ&§І ЊYfŽuVZpЎ3GрЯнліsЄ:CвuџчзЅpkk+1>>ŽЁЁЁCnц2ЭЙж“*Я”ЂЖЩт‰[йн}ђџ€ыж—bЙPЎЪЪJeЉ­­Ukww7jjjŽbАŒfоНТЊЄТ˜Я6+кЯg/гђ.ЩГ$Ÿ“,ыЏнџЅ§/ЯŽPћdѕм€ЉcийoЄl№Зд e§IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/openfile_16.png0000644000175000017500000000142411733011756022731 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЖIDATxкŒSнK“q~~яоwгЙ.™•цR†!bb A™‰RђТшбˆъшвЋ‚ВшІВ„$"К‰ .‚ LК гRгеќhnmsя6чЖw{?~ЭYЂ™йяъќ8чyЮУ9Я!”Rьє\—TыБОЂ^1ё>25RНчОLXќЧKЎЧСk•B0PЭdвf'№rkSp№bZ&пc;ŸЩƒќЋЗDpštўŸ Т}'Ю‚CCњŠgxА“ЪКН0ЗŸˆЁ ”лЂ pїѕпЈOw ѕneіе …ЫwOXХьцу2Ю‰Т RbГ‚@_54tx•№яў›vЊБ5!Y^‡хёШt<‡ЁЎŠJю *’Щ”&i2ОFК~АT6ЯшіpХ%Љ5g/,„дљ…1чWьšz джУяž$fC”X”ШўЅ аЕС2Ђ:oFWsвЃ.)Ж@\ФyЦ+I…О%YуO ЕЗ@ЇfСВ&ј}Q šˆПжЯ(б hœЇP—МpL80љй,cфРd! )„Q—VcСR@dЕ~н<,ёŽк‚/јщtЭЯ‰L‘лщCnЁрєX%—т1ЈH)–“ЉСЩѕѕпQБЖšіUВъФХ.!Z“bjюvŠц\ыШ№2ѓЊP2мuc'˜x++|Jv”2я^YЂeE§Ъ—ѕ-ьО'ЏJ"‹—u4ЇхŠГЖВдњцѕЋдœDШёТžYАL‚ЊFпEІПС[| a†жkey~цHu HЙІСD§ipЊsIсCхгFЬ&'цн–вJ\]5mѓФЉbбr J&ЦH"AЫї?RО§щVВн5ККЙT‚ЌнCHВxЌЬў­nл[тŠ5C'Ф9S™HГйG:щЦыќ)РrD­=ъHњIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/cluster_16.png0000644000175000017500000000146411733011756022615 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<жIDATxкlSMoG}ен;3Л3Жзы/ШBb$, . х‚”HQnќЂrЪH9N‘r"aё!E‘C0иСАы§šЏюЪч†мRIнгеЏъНz#ЊŠзwэ3gаŸo‰Tuа§JЫp“™з>Ь58b‰`-v&YIу(mЗ\b0Ÿ:ЙќI*Чx2&з8“&{=Љ$Џƒ3bАkoXbk1’В x%Р†М= K„9Œ+м\XАZžЊу"ъњE€-НЎIЁє! ‹ oЇ"–z1ЎБ=ё2Ј”єд|Жdнr IЌР}ѓЉeЉяНьХVœєь&™Uђн'ПРњ?ёx|јIŠA’pДDaџщE8п„UЏƒы@р3_KЎвS€Є€SZH ЈTs0lБpXдДв}7@Lг|нŠ Œ†КзЃэЏ‚ѓ2з‹~qkћ?‡YC†ЈцЁ.ђЙ3ш/}‘Gї’|ZS#)Ш’„*С8Žƒnйшъ|s’ўЩШ^ˆЪшš]G%FФ UВƒѕк\˜Ы ?.@‰8xЗШcM*Š2CФЂрb`тœ]kдм@(ќѓЮНЇџЖR'sО_ъ B‡M€їумEЬœ}=э*Ў„s%нлЂБm0ъ$eŠOYCh=в–d&Ђ!™ЙњђЮ…]_[йIЙА4vЯ(ЩW+7^†Œ>ѕ[D -Б8І.]CЯњMo“ЛвЦ[Џ ЎЙжЭ_сXік}Дй7ЅЪsQ ІT5ї’љдPЩпIЫІћŸћч!г>іrгІЖй” Vi‘МDlТњ:l>№ ™П–,eц8пFЩГ#­їъWEж^ІЧk —6Щ‚zvіз>Єћщ7“DсёЅЬ‚_hЏЩPЇ]ХЛЁP”Д*6Ў[Нyт}’:§ФЦБq0}n_/м…‘и<BCђхE† щd;Жр)yЧcxіЛї ^YЦРУлШйIJЇH‘шг ”fоХт•4˜e#&s(jКзМЫ~Mn-Фшш(Тс№ѕ!GNы~єѓ`‘60Гмœ<5ЉV€У\д ”Ы„FМk‘1˜яЉpjѕSЗэxУ0Аuыж[юs­ v\Щ…&,п$ЎК€ZОc‰ p–˜kџ‚‹І^ )ђљpы„pЫвќ>Ž™™™• 'NœРцЭ›БgЯžf`‹оЈБ= е‚ ЄЋ+ад4\лЉ*Cїэќ`вgЧФf3=z###7о?4MУддTѓC–4Эƒх–7Р–ъp u”j"Й‡c™ѓлn‘й{йН{З7ЛќЭŸЁЁ!џ§рр N:…]ЛvљŸ‹|к‘}Јќы?4Q9X‹UВK0ŠKhаp+wѕ‹7C|Й2™цџЯM‡іЅлП?Ž;F?)зЫбп#I*Nzz’е]б•…kгhU8rhщВnЂЁЗn yпТУУУиАaŽ?ŽмhfбŽ|йдEfвЎœљИZ)­“%ž/LЏT+rзКч;ПѓФ‹,њ Є­­ йl===ўЭэлЗп №Ќ]­Ђf6JСіОнЂг(ЪЬъm[ŸД4Е?”ьz>7щЄКуЙџ­~юzнMЧŸyL@kџњяЉWЯ§шnўЋ§W€лƒзсŸ№IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/host_64.png0000644000175000017500000000656611733011756022124 0ustar sylvestresylvestre‰PNG  IHDR@@ЊiqоtEXtSoftwareAdobe ImageReadyqЩe< IDATxкь[MЏUНuЛл/  (bd‰„Ф2ЭlВ›?€4ћYА„%ќ Ж#БŒ4?‰Ÿ€P„ШЬ" D„—їќьОЗІNUнvћЙуg?g†ФQ?лmЛћжЉSЇ>КCЬžх=р9Яx_|ёХ3…ФЇŸ~JxŽсдхE?>ћьГ?ЄБŸўљžoѓ&фœџ№ йX/сYЧч7я‡,ћY~‡ч6х0o9Ьц9ДrАœ9@I*Q’мЪgђyjCXшgи<Дt+ч`ћЧічђYїIїZUсYџШk 1RЈ+ гq.Lb88ЈУХiFM”ЕD§эBжs$ы|8kУ?џ~u-Ь7jР2G-Žи‘eDQN>–E2Ѓє”u&)†Ф0œФАJA e Ћ`Ќ€р›йЬ=_,зЄ@Ш Б$9ГЎЃЊˆЈа„$рЗђ"Ыў,{кМrъmШƒр„)›?№ Ю8iMДg=yNŽЬX\–ХUЌь`KуА‘9;—Гƒt_пpcщ>r u=H]qщœ0я8„™<7тRUv0ЖЯzољQжд@œЈфЛU%Џ8цJЖ$^С>RPдИQъ2Й'ВIУJ)э S:u ˜ЁLbj{XFR+a˜q^AX.X$YW”р0Х0–з`iЖ%lЧ€!X1\XЫФ;\MъНЌŒШКЌд*,ZПAѕ,БХ/ =)гN d‰Vіл–У"…юЗ™рmя'ёјв‘#YѓjmAЮ<6luXŠбОВ'ЦD!љ р 7svcі!{д‹Х`ЁљмxžXтн)КGгАЎэ9ЋrНXБg3Q ’ЕбЈиѕY„Nт Hч`БfЭ иО ЏЬpP}.чB|ЯРТГ‹ŠqP#ƒЧМhn`љоBо'ЩЉf‡њip“†€ N5ВUЌZvfvЌРМf8+Хaє|žФpVяЗђ…6yбЬcьŽЪ>8(ъњРПh,ЫѕeЮЛ1 ЊЂІИЈыДg4‚АE%D—џ=@РЙГЊ6‡1јX<}В0Ъ/Yc?ївš.+9ѕГšь8˜rЉ+<nѓiэУІТЩLЕ *оv]рАь"Ч–k6g3E•,)…Ѕ’—bHюkТq4йC"X †XVЅёGАёЬ:РЮh:ЏF#ЎrQзѓЪ‚I0t‡зaќёяYеЯ Œ‡и! тfœ)ў*Ѕ0аИ‡їНЖвJе‹ЄЂ)[…@A.GCМЖ?p#D(СpљЈУЖX˜зsIН–|–ЧЁ0,­,(aG "Љ›Ј@єsNiї,рФWЃ §wa™кHд5ЅС№“…Q>ЙјSd†7€€} +СHіT(`Ca"•рЅiЅ ьй>u€R н•юl7и(,DlКУј b?БЅ(›пз€[Aй]й>DђT#5шыp0ЉТС8* І+іlь†РViq)аvA…(/#b§xaiЎ[Ÿ+Ч–№gƒа[јWБ‚цm№T ŸLЃЖШг‘„@­‚uЌл”ТC ађЖаL;Hѓњ,•xЕЯН8GŠј бEnBш 08g\СјФш ВMХћcЁвСцлB)dAъšq g3яйнБ4шЧШыВOыtю•ЮозЊіPб€Јj‘WцнЅk‡+яFв™Тл“Q b!QЫgа NКH;†€…(ѕЈЗідcЦЫ– Ѕ|(tк@]ЊB.Б09[ъВy{K]’m!thdх=xџ‚аџТ8šїe€A€ЖИЉЗфG0 дћy^вCдNфz>ЁКГJŽЕ55Mаљ›бZтЂ№AЧзZ&эіL;иA Жxo|SUš№ХлЕm&РxxМzшМТ_oЉУCQ ж–s„фьhƒQžGМЗ:' g…}g‘MaЌn№vk=іУp§~ ]%˜Л.Й„O @ЃЭ‘ўšк6аєЗv8(`УvpЎ„Л‰м0иPеЭd”O2<пѓtЋŒ moapлZ]Ъ№4— ;S,щkњ б—xlыиKлTdъБД]кхQЗk‡рЂƒиc^!щЄ&штXŸeѓ!Fл}FсЄѕpРўd-kі&]ІіфЅЌ‡ Yг[ ›G€ъЁљxl‚з4>њ"ђьМє&MJU\СнCРеК„/Wщ—ане~Ў”Жiь‚ ”yGuъZкь­Д6_>TеsW~‚жXрЏ |$Б>"5ў`L"xШѕЂќђ Šƒp;~‘ЪєŒM?v .Epьэч‚QжТx‹}Фѓ1u=g,ё•](х)Šё‘ђдxc„ІЎR/їъvѕю ХQЖ”OТШIэFЃкг6зЏƒўз!іЫфWC ,ќr—–ўœFŠЈ X9Я?w(ЦaX™|B\ЎmRI‘ўу-A`kюu%J{Ё0ŒUЃUќЌфE@ аžЃМ­ЩŒЏм№шkЄnЄbЈАO7Ш&n№єoѓœЊ>ŒO=ЏSіГ#TйИ “нБ8m–žŸ(нKМ[eзxМЧ€Їъ"іф!йЏiRo$V.@l+‚ ят%о;Б˜GШЫ+–+sї]@аЊВч(|IL#осёim`Œ5КЖ)5т@DЯL(вbWД•leS&Єрљтє…оўт( G7w87еЗёxЙ2ы-№9@шO№0!ПГz^ n|$ЏЅ­{›Кбe$ВTщУaяЫфЧк{\9>ћ‘?ђЭR›/Ž>wŒn Оыџќ—ПЎ‘œ{4я2K?ЯrX ‡г—GжЃ…ЪэЊkћVјHCїКб†Я–oњЏ™зCѕ™ПStя›Ѕ_xс…Е}яОћnИ~§zxчwєр‡‡‡ч:іэлЗУЭ›7У/ПќB)ЅA ?x№`Џѕзћ"cМ!‹_,RРдсз_=зБПџў{=жx<`>Ÿ?vь @…Je@lр™ƒП=€пы9€N7Ÿ:№№(иFЃ‘TuЭрwЖ}Рћх^Ушя€Щd^}ѕе№ђЫ/‡7п|3LЇSЅ/ŽPи6-ѕ+Ml`ЈяЬŸў9=Ж{›їрвЅKсЪ•+сэЗпяНїžО.ЦпН{WуАе.wnртХ‹сЅ—^RњClqЌŸ~њ)мЛw/мП??}Ў]Лоџ§№ж[oщ‚eБ­xМ‚зшTфžёs"zd-Ч"9F#л‰0 ї"@љёЧˆЇвнoМXІЮkЁ'Сxёz–А €тKcёМ?й №М рЧуУ+ЏМ’х\YозC)ј‰pѕЊоŠо a8aСXЈx-і ;эщ[•Ў%Ўєт‹/Цз^{эпwюмy§ЉBп|ѓЭ]ЁцхйlІ†_О|YiПЩЈНЌџ_ ЊА ЈўѓЩ'ŸМўФјњыЏяЩo/ƒо 9bтї$Ћ’!ЄJ ЗnнК§бG§щ‰№х—_2<€”Зђб–œeLЉР"МGЪЫўПN№љп3 NСZ+ќ№Усу?Іџ97nм`Ф8*Н‡–JІ"МвLЎїnЉ?0ƒ1•Œнh:ѕЛф[Г:Vе1ЁІIА№ЋЏОЂ'Іx|№С‹й–ОЂhˆЌэ[й>”—п>jп}їнгэџпџ`hбЕŽў“1IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-udp-neg_16.png0000644000175000017500000000166011733011756024127 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<RIDATxкtQhe~ОЛЫх.wЩ]“Ћm“ж1W-д-`‘­Sа:JkWиPіУ:КЂГА§Ё"2Eџ‘ЁUŠЂhСЖУў!"ƒ­LЖСьXSД 6ŽЕnЉIIв&Ы5wЩв\юѓ"LВ||МЯѓМяѓ~фЫ™Я)C<>јжзО?R›‘53˜‹ЭТУKкѕ"ljуtdFЩРŽPOДvAd=нСчД‹$<вJYТbц•_‡&ї…vnщФђњRIXЖлƒсЧNр…Љ#8м1€ГПAO[FњGЯ‡ъ2ў€П&У,TЉ!H.јo>§6І†ОEŽ$БЌGбz †?Е^ФRс8S‡дq| 7CЊнˆЈВрDМEAxл‰рІI n ІА†7fŽЁmЫ6<п6ŒѓsгWpІ”ФІлхнЋP}2Љ„5{‘ь˜т:ъ•›TLьЦ7§—Y*ŒћxhЬ1ШsGкNрlz//іТыѕЃЛy?ˆтtъ}ИСіуxPnGKЁv2WyчфЃ‘ђЦgŽјІs6Инў^.3њ9tШ]hЖЁ3аЏ @х4єkGaк:њY˜eЕ4ЮU:xЉсЋрhьSђгЕЙН$њeeшђт eтJ<ёjпУ‘н[E-ћ]5тv?єШSФg•ўqkQ0ЉeKх|ЉBА“х]MяЖ]=ЋІ,›x ijAо~=ryю>#жбЕЇЗN^]$ХЏOТCЫ№+ФJYЃHXQ9GœџƒяцM<L`§Н'aU˜ m4О,qz ™tЊАСЈЏ3U"Ѕw{мЉЯЬЎRш Šѓ­Эaž€cY; ЂТ•KтЊDBШПЂкЛŠEBЪ7слs›йМWєO†Г#[LЙ}ўщЛ"дŠЋ(_uzЦFw*бyШ‚ъФ/ќlRтычxїUц^qmœ•/^ЙНЌ2J ѓИ}=3j€3 Ё–ќ0КЩнлЙ6ё>ИЕДв)Фш.њї"gVјЫю`Dп/vAŸЏђџлA-юд.-dXЗвŸЦњ †sћ)ЧQл ‚т ЅBь%џ0о!`ї_ЉКцIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/neg2.png0000644000175000017500000000103711733011756021455 0ustar sylvestresylvestre‰PNG  IHDRѓџasRGBЎЮщbKGDџџџ НЇ“ pHYs  šœВIDAT8Ы“=oгP†лRеHЈОБT)Бн…тиQшoЁR%2U€дЅ HCГP&ФТрЧ00Си4‘jšD5іЫ@>Ыщ.їœѓъмћМЧ’Ф<Xќ; €НИьSLnlŽ\—ШuWЕ’tkKкяъ,№5*ŽžдЦI[ГnЂd{[’Д˜€ЩнНКс|/ЌšDЯїBњЯ`6уwОJл€ѕ}:ххUŠfЇ,Ђg~“7f‡ŸyŽчиœ^Ѕ|ЙН§ћХOќ†FqЄQщ­п”$=6Ў†qK_[4Š#јЕgZ ъyuњ |Кsh\&yЮЎуp:ђ1M)в* ,EЮ‚&™рWžsЯЖy§уšƒKЪЈэ*VS kйќyrSй\% ƒКс}fЦqp,84.§0Јє‰]FuњЄYЦЎу№j0фХХ%НКЉYxкlhЗє-zЈQщxNЁ˜Ц-Н ƒ5 K'Ž“іFT’tь7—ˆ‹Ž] ЬК‰n:БŽ „бхMIDATxк\SkˆWўцЮL’ЙйI&Л›ИЦЄћЌcmi­лК•@З”‚RhЁT*”BБE[ЁPњЃ§W‹њG‹XС.еmЁŠыжЗшŠYБывЎЏь#ЩОвlВIцхЩ”ки чо;0ч;пїнsлЖёd%эЯPМLС‹ъљаŽђmпкБyпŸЯужб^ЄQГЄšd?эQlfDާљўј _{‚^Пj›‚@ЩЅT ћpАXРœ‰R5Mp$нЁEиˆ kƒыЇішGјšm>ЅыШЮ™(ц-ш9†tв…G—љсR ; $џЦvaЉ{#кщdŽ[;ГuнњВ‹гeЄ2TЊ`B/YАu RtbЦмЬўPЧ§"v3Мбє,A|€х>РуЦT9„СMК3cbtЮvxZs12ƒ^Ѕ+€ˆHзъƒ=XйFƒъ4wLbНzѓwх*3'ƒ5/“^бљf^r4­ёуяXуGуЬ™3kЪ ž+žз8аПR8Ы|­HkEDбH;Ёou4Ž6hнHƒZMЭsбђmЦѓ™цyNЭцєЇŸ~Ч3`@ЖлЈ}ˆ‘q[Й OC;вФyСБi…tpџC€€Б­xmG]x†5нЭ<хГЬŠэлRX“юЌSž5”яC ЦЦМ"ФЯ" 43чf3С`оJBЕќ‚Ѓс@pСЩAБ1СšMIOЩPЯ“ЧdHzsB?bŽ.˜љ g™Ф\$ІFЦѓ?Ђїѓ"4ьЪFяК<@Y0 ‚ƒюа:„ŸIёл‰77EѓіюҘИр5Kљ‚'Л Й‡ йЋБ‹u‚5K…Dщ’єB’ђЉ˜7иe€ 9П“9'ZКЇV@€№№О xq/œїјUbb vэ‡мJ2е$EŸВ(05NаE„ЕG]…м~9 @pB‚ѓk :Z–y­лz}№щѕ_BdXšј` „m%Hˆ8#ljЂћ­1Kј"tЄџRAш…6ХонIHƒрнЬSоџћЯ4qчoД~Я8}їрМ рžРЊ Є Ё3РІЂg‚c#‰€АgШbгт‰C+œFАAж^hU|Є$љёП‹чˆ*jЧkTl'=ЭBOg$­kbџ:Ќ9MѕwzzћЯ4ћѕПB_}§ЧЙ$*Ќ 1ЭЮZЧъАAЃ„Fлš:мАb,`yls€јй'Ÿ’џюќy9џђѓT" ЫX‰!ћ”еб_ЯџšўёљоєRСљZИАњR!д1Т——ДУД'NШИgЯž}e}.Іёёѓ†5v^ћ žгѕЉzДљЗЈ”ZЛє&Њzy~ 8юнЛ'-уууХѕэлЗщХ‹rНkз.iёИqуFq]ОПj№Ž(x|;$>|ИјююнЛ"юяпППИПoп>КuыVLљ›xХv†lQЧГЕfЫQбcGŸ+k№ђхЫ•s™ ‘)§кG+ жљЁU2aъ­(ъ@ˆЧёуЧ+‚і йN|ЇџлеХх—“Jеƒ`J=zДbл v!v”П]ePіЪ р‡•2Uh„!- )ЭŸ;wЎђlЅрМx'8Ÿ9ЄЕеLЋЌЩ .Tю—i^ 1VЅЄ"э ТвZE3œЪЮє­- шЦ+їЂƒ+ƒУ"о] і/H]>ДŠ щcU9=G>?•W;@§іzЖЊУ  "<г>.hfђЙѕSК,dџГеЂ}‘ѓЃ~\Јў/Ÿ^ё{ƒ_uO/ІYрџuMЅ,<жђ|япќ}§ХяпјХаМЉАЌуY№iжќDъh2c Xi|…јл?љ-эќёoŠН=gK p-Л8ЖzЏwеN…т&QK;^гѓвk{l€ЖHжљmьH5QЅтsƒфнDћцЋу>cеЊЈY‹Г]KgОПU~§рЃ йЎ~іЉ*3МЖ*ŒyЅRЂfЭГж'Кьќ‚№ЦХJO/’;>G†хDmйъPїŽEŽpV‰/—ЁВлfEp>wpfAEp>‹а H“_oЁ€Ѕе3YYЌКАЇЉJЋлИБи!,ЁхЩ дї6`{;–•КћR@ЪRтЯК™P+q4кєix0кКсЋдАHЁЅ"DR7дEвцяХ‚+ИiжП1тjw‹j7G!8ъw“ЉwzО<wfC™l ”…Wа0П:вrЂyИJђRъ кuП8iь *чbqиЯРХЪъVvŽ'KБz№о`MY|"Хіs(_йž<‘jn‰ ˆР*”Х…ў(h:Z•mmхџО Gдјэs˜j‡a'ЬлЙtPкSt~ЯћиRCй і?5kYw–њ6RшГ-<њЮЋћpЮ.ќ"oѓK о]->аЪЊџојс9$w%š‘E9šћч<ŠЈЦ0Š7е\Rnnњ]сЃъЏг•гєКgНхЭkь"Э› г?дА&А~§њтzЯž=tша!кН{Зt:99ЙЌ>>|HWЎ\ЁчЯŸ+cЬ@ OLL Wz5Ѕu%оbђY–qг —/_.ЋЯ;wюH_эv›@šІЏЏ*Д0Ÿ={FгггєЊџЖyh•ВкЬЬЬ+bhPэС„yВ9k<жaccc§&`KТЇJЉyslюKqMn]f@кехў§ћDЗл}% SŸ™š6˜ž ТѓЄlЇгQ% ŠњЃ‹IŠъ 2h>8РњdсiЫ–-–§‚хп А&‹Ќ+РеЋWsжW˜0&ЪZгeСњ5]aQЉkŒŒЋкАaƒоО}ћ?~ќСЃGФ,V€ызЏ?ajОЧšWађЖmл„іƒ„:cуО™jЧŽя3Žs…Џ”ОqЎ]Лі”5є^ЖчЗwU  aLія3  РŽo,ОxёЂƒM"фѕ§ЅEэВd!abОŠу7B^,буё?8:еŸ{А9HЎ€-љcЧŽЉзР‘#Gl™оддTЬ]MUФU“sзnІ\0ƒ0‰яЬЁUпw&ДfЕЌ*eB “`ФЅK—дkg@нqрРa™§a\ODТsњ’л‡|љхBѓЛyѓцЪЎпєуџ ЅАzжѕЙuIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/domainname-neg_25.png0000644000175000017500000000210711733011756024006 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<щIDATxкЌVIOdUўюkjЋWАY…№и`LGˆC€DЋ;К`X€Ё7 ƒ,Z6&uaD­‰˜tBŠ€АА‚}/`E( ЈёMž{^Uu5t•z’Џю­щ|ї;ї Oxž‡Ь м"„ !‚IШв„!IШу%ІMOOПРЂ( BЁt]‡‚?“kЎы"›Э"“Щ NѓћЋ6>>.˜ФЁ/?ŸœDЅvѕD2.!k“4‚Ў5ЄџсŸ)q‡7|ѕSСЩЅ SW*&Еm9—9кЇhн}є&œ‚_&Б›7‘ †%hjЈЦ„цСЫ)HЄ-&1 tlЛŒФђџLкˆ†дЊig) щ<A cЙаtС!Еэr%–Х›hи€ЊˆŠœЇѓ.ўJ:HххeЋфИmd= ЕЉђХYЖѕ,‘\Ий*д@'Р§я щтЩШk а“s•Ё*9з}Х@є–с+БЪТЅЊўhšF CќіхЕЇ—|Е€п Џ?§і•іьЏŸмЛЯЩЈ)Š ŸX@ђzџжжж†ээm$ ttt`ooёУуo№§_WZ""сgƒfhа $kkkХщщ)z{{йёюю.я›ššP­Q6+UѓCзггУыммHЧ‹‹‹ЌJ*Њš$›Эј1з5†4щTI52dХ}MM Њ'I]І}’B­xbIPTV\Ћ5ёсG1ячŸc nСІlvy€џлДфХ%o2ŽŠ?Rд{оz„ыš?5^ШZЅ’@ˆŠ/bњ+х d'Ё&<y†jiіmяПг‰хј’п…—–žpыОЩ,Чc•д5uфъqw„‚AЊИк8ЫŠQОЬЮЮЂОО}}}8::B$СЬЬ Я“ююnмщ|ЄPЂЮъYrfЩўф3“e‹ВНЧЊ=O†††јдEлййџЅХ5 />Ё”чуПАПLмŒи3FWIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/addresstable-neg_16.png0000644000175000017500000000105711733011756024336 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<бIDATxкbќџџ?%€DˆЛ^дўїчяЦГDtЇПНў№?#3#3#аVNЖ9?о}iз дКw ХF DэЯќ/ЭRa˜ЗќУ Œђ‘їџ„ 1АА02ќgbb˜ЙыУЯЇo>ОјєњЈхz 0В03ЈЪs0prБ‚y$x„ј˜x9ЗПїOШє}—%PB‰a]BьJАš‹'0‚ ˆ;ŸћПёдџ†QWўƒјUoўЧЗ>БљтcђџcPqЈ ˜^§Я№ћ/$@еeXnмcdPНвaЫqjBlмй@лQНР ЌY‡2|ќњ—СkъW†Џ_ў2№) 0pŠrd2\Цд„ ˜РфрfЁ9љY>>|Я У# SrВ+рšўуТ„Т€ Э \|˜э0—Рbn###\ˆё‘Z0Ђ$$ тџШ6#kЖ8ЪрЃВ Юпr' Ц }sмj Š0ЭШ†ˆGП`јsї.P1ЃˆхБџЬВВ Œllp1&l6#{G@„Х+|B,(b,Шa€тI(џЭЩ šкї Тzя/оПbРФ)ЭЮЕ)§m$ЬIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/rangeaddress-neg_25.png0000644000175000017500000000114111733011756024335 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<IDATxкДVПKBQ>їЉMЉФt Ёџ piihШС]‰ŒJЪССџў…ЬШ“›%МЁЭ%‚жhH‚4Т†гЛ‡Ў=Ыw}š~pИїМƒїЛї|ч/ыЖ№ѕњз6a>œc|ў^ŒšЦЦТcTС^ћЛЗ{иЩ­ їu7YlSњlьл†AГ€”Ќƒџт;Яѓгбё@оsГиX0цп,Ї“j!Ьn$ЌoлfYьмМКјН8<Р+цРћœ|фўдOr vќTО,(x3gCюO§$ƒwƒMMErЦйЌ&wAkйрюMз.#п „–Т~kЩxЮў О№КкЃ=07№ГŸoћяЈ;ЫФк:}`b.`іэoЃГЌЩФхjЊАдF•h'ЙOх.ŒћЦ8‘d2ЌT*ЈЊ*-ъt:БP(`Й\ЖD2ЊS&‚С dГYHЅRH$ C­V“ffXЏ3~[:ыѕB—ЫE;чh44VЋUєљ|в“Xэм}Mќ~?жыu"hЗлL5сяОˆ0юЫbDтvЛ1ŸЯAГйЄ‘kфѕz‡’џћпЯЭп"F%œNЇ!‰€Іi … X,’FЅRI^ЎLв| 1^Oш@,]ˆЧурp8,м I‹3Ԙ•NЈЇaрЫоcУb_ ]3щŠLG€GIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-group_16.png0000644000175000017500000000154311733011756023357 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<IDATxкt“ILQЧџ3ѓf:mЇЖЊВ՘ FБ.ШnT\ˆЂЦИŒЦЃ—4šЈ(bтХ›ЫСФуAŒ&‚Ј`B@+еˆR–V%] ­ХNЇqЪƒ)_ђ./пї{я§ОяQЊЊbЎXЙЛЏйъ0Кx–В&І$ъgDQІІ’УJ"х МЋ|’ЩЁцnьmЏXЦЖlЎ`PVЪCЏKуЛ7ŠŽW!є|5"чЎk+YZё‘ЕЦ‡лЋhфлUˆ3N?ŠЋWo"дnЯКMЧШ’эєтRЁmу:E€=з %­РуёРfЕeE§@8žЦѓ]+ ŸЧ9ЭgcЯЋ˜˜"‹ahШ‹X<[ŽЕN*Ј’й,Јя9М аиfГАFNSЇю1iлЪтXUњ ™Ї&’|>?8Ž…еШBIшХ›zлЗTZЊVа(v0 “QяbшшJC’ШMмЧ›Ўзий䄆†­ј=e‚ы.ЏвЋїї_Ј)зЕьк@PО„ ДШ†цГ'‘gcаXkТžК$‚!ћтc8sЖосa˜Э†щ!H˜™.6VЅА0Bо<;вЉ4мn7"‘ˆ&, Uv#Q<}/ро9'ъыk№нoРРа_АjЊ9ˆKŠy˜E)­иые„EёёгWˆЂIлP4Ÿ eё3Ь#8ЂGW_юoRЛПГт™ž”(ƒžІcЃуїЭHЕXL`Y–сШIFы^aш„/N\ђwЎ”Щ#cс”2№y‚Ю1Ы…&Aгvэо‹–sЇg…MDxp:Ђ v”3џЗœ’оюўbЂ` ЫтрСCГҍ깄ўˆєєxЖ™!R\vНьeuы—+`Еs,гщD]]5F~ ј0(azZveЬЬAnхЛkv‹rЙz…‚ЕKi,^Ha,РТфёv@Aџ—DFиљ9™а ћ(Тм „.Qф4­гГЊUdУЩПRЋчХšлs}љ “4?NF qIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/accounting_16.png0000644000175000017500000000133411733011756023262 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<~IDATxк„SMkQ=w2“OЇM5†ДU+~P1mAD*.]ЈнЙзRњм*ЎtЁ[Е q!YЁ+бVьFѕ+Є!ЖI;Щ$3Яѓ&QЉњрЮ{ѓо}чž{яyЂ”Тћ#%+shFЌTЯ…ъЖ9wЁЄGс ‚иX}ёуЗ—­~~цŸџІНЦЮйqРiРH”є™Бƒ@чћpѓ„“П48 ь=Lв TJEПЕ”л-z˜‚FŽЎ.œё ћДSћƒ~WŠO16џx„чUšП( ЊUА|-эMЬž2Œ } ЇЙ†ђГ—tѓй~ І9” $э5ыwNо_›tрu(нжgFЅˆ,nБ•ˆФ.Ÿgr)`€DвG›Хэ5Бzяюuо]шгбˆPa&-JљZQ2йД Š+Щ”l$Г<ЗY›ŒXв‹(Z<ˆЧш<аЗИнЗ(AbД(eр‘х6YЖY†юz­ЦO)ѓЊWo‹ofєkУ ^ єЌ_ЁьёНшgю9,—?-/§V'Y)IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/addresstable_16.png0000644000175000017500000000113311733011756023562 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<§IDATxкbќџџ?%€DˆЛ^дўїчяЦГDtЇПНў№?#3#3#аVNЖ9?о}iз дКw ХF DэЯќ/ЭRa˜ЗќУ Œђ‘їџ„ 1АА02ќgbb˜ЙыУЯЇo>ОјєњЈхz 0В03ЈЪs0prБ‚y$x„ј˜x9ЗПїOШє}—%PB‰a]BьJАš‹'0‚ ˆ;ŸћПёдџ†QWўƒјUoўЧЗ>БљтcђџcPqЈ ˜^§Я№ћ/$@еeXnмcdPНвaЫqjBlмй@лQНР ЌY‡2|ќњ—СkъW†Џ_ў2№) 0pŠrd2\Цд„ ˜РфрfЁ9љY>>|Я У# SrВ+0\РЩУ ІйЙ€ІБВ2Мњў›“щ 6gcИ€‘з,џ@СЪЮЩШРєяPŒ‹‹™йШ.ХиТђ|ВЏnОѕgffМР~~§]цЏ/П_sВ32|УюF”„$byЬШ> }sмj ˜Ъ*ИЮ-wТеБ@9G˜eeйиўмНЛj\ Є Ј˜hшtuL0уј„XDXQˆ1˜ єо_М Фа аОGŠ#Ѕй Р“‘нЬ}Г9IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/inbound_16.png0000644000175000017500000000065011733011756022566 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<JIDATxкЄ“СJУ@†џй$­VЋ Šа›ъЁѕ*ј,о}Ÿ@|Aё оДz*шХŠѕ$ž6KВЛЮЖJ75ЅsЩ$пўћЯ2Ц`”ђ]gЗn2Љяѕmњ`keЏ†˜1ф ˆ€@Ёux—O­I­б–Qа0i”ћ ЖBžМJ‘№щЌР мЗY€Х2@EмR#ѕp цЧi$Ÿ’V"†S0с„EУ 4T[!e%CŠT+д5PYCЅъ “p%эЁбТE=ијШ€/й|юKЂШŠыљхnя;X =ьжЦМНРŸЋRю5ZˆѕЄ\ZХщй#ЈМLКуШ‚5qPЯl^›Asѕwў`]rМQяqа%IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/custom_25.png0000644000175000017500000000076711733011756022453 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<™IDATxкь”ПNAЦwюA+Mд+Œ•Ёk#ЖZ K+ZžЧ‡Аѓ L ДаТDаhaФ­р№Инѕ›=v=QJLHюТољЭь737wЄЕѓО<ёW!Rˆ,ИёЫЖЯБ5ђр­u@жžСwА=А]=НОь<ъгёˆ3vР7> жм[ŽпЌЖЕb~<сVМ П˜#№z­Y#~Ф™gёр!xък5ІfХБёP ­$[‘х1Г„ј 5\+UZrёqjл†kНэ*1N8€Š§’ЉёXxaˆєDЯˆ xвaуexь‘чuГјдU),У2љўcЯ”ЁFНцЅИOыљJmМ1GІЋvx8žХЩHЙј5W ї~cџJЫ$:Э2іKЅ~ў!ўС?мєˆn.:НYёСїœб‘PКЁЄ,›ПЩјо_.ѕэ„ќтŸЩј+L‰•`iЉNРЗђёn„ГiiE(БтZDдGПo‰Ј—M˜žцярwр/м2~ШfВўˆw".уyНŒХЗЋY\‘/mк пHвRIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/outbound_25.png0000644000175000017500000000120311733011756022762 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<%IDATxкь–ЯkAЧПoіGмTЉФF …VjСŠ”ZЊ‚QЉП Ф*‚ ^џСЋ=z-x*ЅоD№ЧЕт-е‹EPlš˜еl[LЖу{л]єАбЄЛіфƒ/Л›}3ŸљЮфЭ,i­ёЏCab[ fм]ЧšхwВюГЎГжтОМ,Дiж _XxА3kŒїќ~' ~–Ыƒ*Ї2]мбmг ё+ђђxŸoђЕ"Tж„;<ЛЋУИsёL††Л1qzђ9kzпиЋCќК‘Т€оŒ­f #(œшСЧЪžЮaЅRЗjЋўC~пТ8†ЂG}NюќЙ^h"МXЌУ7 ™Ѓƒ’вУšeIœм;И?;zљв”AЈЎk,•5(Ѓ@;œБ!Щ9ХКЛUШ ^‡ЉС#}P<ђ‹Ы>ъ|G ‹а1yXroБЎЖ ЖЅАђюž>y5_ЃXкЈŒИY}ќо|1j3У:аr1rМaэ-Wы(Оѕш›зјzr(qљЛ€-ŠrwџжюG;NЄš].8wщйБЊьЁЫ5@‡kAзА`нАVмfЛ€йj1~ЈmК Ш…­’э]qQZGАиА` Œв‡ИšЇHF/SЦ­ШJЩ‰ьЦйЩ‘роЃpєУX06єЯщфNфЏ„8ЮЭ_€дІ+‚(;Јі­AЂ6е–ЯQŠћˆ9џ4ёєЗ“‘ў­Д?6uК03KIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/clock-group-neg_25.png0000644000175000017500000000262511733011756024130 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<7IDATxкД•{LSwЧПїблоо––hG€Г) г‘ЭL№іШb&jтЬt€е9LќGЃёцІ!&Юd5›#гр’ЭdТ&‹( нht2ZŠЅ•ьЦюOЗ!#Ч ЛeѓxLїїCч‡eІuŸ&ьSrŸ ђЦтœU–\})œ˜ƒ>Ь-вРdф рt:‰DHTж45Њ–‘„Зй :UXЮ[хOQИJŽgшtC…/а`*Жq4%  DQФшш8$rЭkTиД2 чk!3,сиuџUWqёт'’ŸAcї{ƒx./НРХ*• VЋ‚ ржЭ› †4ащњиВdHПŠ tк™qˆxѕеэлЉ……˜К|y1‘i[\І‚‘3ДI Ю_Œ"Cр“%0ОУxg'ŒЉFR…NЭЂiD#ad˜Y ‚2Rуъ–Э›ћїƒ"џˆиGло-6н’ш˜LяŒ€!2ЅˆLWМ™Іх .ЌZ™TTИq#†Эf˜L&А,ЕZM`ФЙ(dйObўQ.uЙКZўэР‡€ц:Ь+Ч€Ы3!SЃ1ЯтbUU З‚ѕыб]Tƒ!фЉбј“ˆкгQPZо=№Э ­ЭЬ|шE+(свЗАч 1™NbIPLЩЗйlЈЋЋUвq;ŒЫз0š4рКoЦэЕЕђN&)kС‘#ш&ЧaBѓкЕ“жgэм nщZh(/X ХgŸ{IsF>тЌќхЫiЇ oьV5ec]cуcГЈ9сETfq§і5Œ`”N)Я &$5нюі~Ћф0‘cћЉ!пъ—T)Ьщz$Њ(€y{ –ж BжjP5;€Ng#\x5‹1яzXє—;єbџD3F8F8льEnхzМКkWR€ВžНf Кя РчёcLRa™Ф~()qyЯM/Œ&šq,@hУ!є м‡ЈХекŠ?Яœ™Ш]ДЙpКAQ ”йЊ(O0№ž ?дх ОtдЎ4Г<щ{вг#чвЌYађИ}ьXB€bЪѓЬвRdЏ|wšћHяp€_rw™&Ћ>v\#.ёЦВвTˆM'qeгІЄЧЅЌїoРt[:в3ј ™&…THrƒEЪНx$! ЇЌ,!(Ћ§$vWЄЫљ™tУ!Фї†ОEFЫЄХйЕŘsќxьїQSтŸo;JЋГ“[]2ГDЏoњyЫ–„€ры+pНkй ц!#+}чЯ?Ѓмs‚іKIЩАRрc+ыэMИVИяьє ro жнE{ў +zŸ“Д’Ѓ­­–А(ЮrЕДLшEыОпPз7ЂRыYCŠ:ЪёбнoЩтЙУљљf}МЂфШŠїь9H.• ;јX ™]yЪќККc‡мQ_/+зФye<ъЪse]‰SтФ*љHц 0•пoРы;IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address6-neg_16.png0000644000175000017500000000120211733011756023404 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<$IDATxк”RЯKa~Оo~эюьЈэЄQ‹„щš§"Ђ_даЁB(Њ[d'‹^=D‡ш„ вEƒЄ"(ˆE„‡<‘ІЄљ+зЭвн™мy›oжYЦнэр яї~ѓРћ|Я3Œˆ`œMэaЩЅ‘ќxЁ#б|хо {@Œq0ЮРрfЌ‡ЋiћцЎS7О _ьFȘ 8пw‰v&ZбћЁун_иѕ.к\‡$) йСгб~LЬdž=c х‡ dq$k“H56"2ѕС}­)фr MўfўYнМ:КWoƒž—ƒтб01їЈИT'Гxѕё-к\hя99pЬ]мёH­ЯAЎYByљ ц–g1—3`;ЖОžyяж˜W#ЗфXсИyDm“Ѕ(м•š пГЋєІXS[авмСЅ;Є˜Прќ‘ Ф8$n 3&УўЌ6ќМ?ЕPЁ@Hз рЏ˜:‰§š€yoчЊыlZ=7]( ьOT(№=`тЉу2ƒgPj pГQФqtв3hк… ‚ƒjU$№NYбМЬ ŠwUsеЖтSџoz7иKžеЅ%уšBЂБ с?я”БmЗŠX“‚БЁ,ŸОЬо?щЁ0VŒ‘жs”ѕђФнЊ8whн\Л $ZмƒcМ”Їїг @ЬTЩƒ`9LRюСђэ<цUѕ X H6Ќ Њ9D,ˆKМŽ1Рў 0Šд№qћj ŠIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/uncheck.png0000644000175000017500000000024111733011756022236 0ustar sylvestresylvestre‰PNG  IHDRH-бbKGDџџџ НЇ“ pHYs  вн~ќtIMEв . хЁх.IDATxœcd``јЯ@`"G Œёџ?q322RfуЈЦсЁ‘‘оižMѓK7IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/log.png0000644000175000017500000000247211733011756021407 0ustar sylvestresylvestre‰PNG  IHDRФщ…cgAMAБŽ|ћQ“ cHRMz%€ƒљџ€шu0ъ`:—o—Љ™дХIDATxœbјџџ?2ŽќO)F7 YsŒ0 BєžНЄƒŒ т5ВќS:th‡7П_0чDwЃЊ^{oЌЕ™ˆИ;Ь ЊŠ1DфAD‡™Џot @цт …@$5,ƒYT=$рЗ[ЕЩ^`^ц‡МЁюFU!3/ДжBDРнafPе ;03цœ "Œ1 "8ШѓEЖdБ Р@Щ’Q”!ГPP}УHT)§јл,pgпOBHwЃЊЮ#>ЩLЌЕpwЎ%шH&!&&Ь ЊJщїоDф"w М–М|љlЩƒўпО}ХX,љbѕъеџ,X№іьйџW­Zѕ54(d +Ш\€"Щ’ызЏЃ(h@AЕrхЪџ“'єџ?ўџCIЩџ+……ќН}A–pЬ Ђ,(NЎ^НњџТ… џOž< І+VќŸ;Зђ}ЋяџтŒВџЯъъўџ§яусВ„d.@Œ“gЯž§єш8тA) d Ÿ“ђџeЫ–§_Г&˜@dўП{,єТ”Ьџѓ šџ_ ўыых В„d.@сЕфЭ›7џŸ?N]  Лyѓ&ићїяџПtщR Eџџ§§џџ аСЧYўппЦѓJKќџ%sч~ і„Ч @сЕфэлЗ№МђЩХ‹С>XЙr:0ђэZ„џџ і},џПnуўПiA 8ј€yчKDHХ(™nл6Ш6ћџџ0ќor‚Уџнсџл—‚Ы*PB RЏA ЈХ€ТАфe&P‘БgO50и”џџџ.№џџyvp№<и іѓšщџ9Nm УAƒ(_ЬW(–Š% ђd8Ш€уЧ“ўџњ%ёџџ;`ђ<Ъ Жрќj—џлЖnЛ”AA†‚R У ƒ Х€BБ”ь@нЅ•aдѓ˜‚шc0•SР ќи6ј ЬѕŸ‰у30џМ@Ж €P,YDэЖ@€†n ОoRIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/rangeaddress_16.png0000644000175000017500000000045411733011756023574 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<ЮIDATxкbјД$сџнD&0Б€›.ЬRєїMчџŸЇгР@‚иФpa& ‹ЈsУƒвJ0Ф†бшb8Ь)шN%фtx€­8ѓџ0БaHД ПХџ?`BŒF‚(žЂў„al§Й$ыџVFV0Бсa€ю˜XВк†БqЙ”ч’mЏјВ S1ШfQџЙ`|˜TDАCi.$1ИТмэI`Х!Ќџй‚™џ#Т 1ВZ8 ЬЉ"МB юЉz o˜0\œ§ гЏР(еKхЌ&X-HH/ HфЯy7—3p §gррХ§? @щсЫ†{п.3\Нy…СFРˆМ\џХ§0А‘Пwww*хђkkkзФ~%ВББёќРРРE€!ДWq &JМнІјoьЁ)фШгJДв’NїIБX”БББ ј›Ÿšš:™€ ђ бKШ…qd"4 ##GЂ(ЃŽlђsЄ{S~Jž—|aфuјКРcz||ќ…СССЯР"K™Т5ЗвD‰k†EdАШгБ#€ч*@Љ”ЄрЋ\*=ЕНН§ ЗАј4Ћˆњ› @@нaр&ж<їA2”(–вАŒeUцОP(H>—;лj6')зЋDИdЧ ц:СФ‰gЩФб‹uЬ{e™h'U=q‚ЬЮћpt†”щиD!N——Рх…ЮШЩ,0тŠ€r‘ €шƒчѓyA3Ÿѓ!гI.АD=Б ЦGhAш;tE юПgбz*O%yё,5sŸЩdѕœ|dx†L”aт%вx €}™~A‡ї2dMP6цTћО‘,Ѕ}0ач)јhž КМFDžsШˆшзРu|Лн1нЮ({Ѓ‡ІwT,`>QЁ]ЬЗRЉtрWЋе;y”KЮ@pВri ƒУрФЧз‘aЬмh7Ђ W^ ъIѓшˆяњprЃ^ЏŸ-;eCч-9j6MDЪiMг І’р’(чœв(t<ˆЦѓ 2оTљ‰ѓ†ƒMЧћZЕjdJ†Ks`ДчњЇДЭ‡fЪ=G ћёљРСдќГ\.Ÿс”†”ЋWA|э˜o$Ѓ|кu{Ь‚Fу/Ќ]SKKKwAыЪЦt,чЂчшади$W™|Qs_л„ЧžeW—vђa KЇнўfqqqGйF‹ОЦт‡ѕ†“G'Sз‚›Q>х0IЕ ktЦьjxˆЁЊ~Х™ЫЩц#ЙљЂ\)пaвoчФфCЧrАЃ}гˆІšДK8ЭЩХd?ИџTж—ѓѓѓ;<ЇЇЇпС(ј|dttЂ02’hoЭЗ}‘в–QD”@,ьээ}:77wљиgќьььhЬљ|!?Y,>!УйŒa`Ѕ‚Г”oЋШЗ`ТЄ59@^ƒK333Wћk…O4~OЗw3йьй].—•ССaIїЇM7sZЗ›ЖŸЕк-Ш§-Ž~ЗџзOЂј…Ят2 РѓШЭ+hї#Аь>п„ЄПСО_XXИuœŸЁ˜†UЌŠКIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/add.png0000644000175000017500000000111511733011756021347 0ustar sylvestresylvestre‰PNG  IHDR00Wљ‡tEXtSoftwareAdobe ImageReadyqЩe<яIDATxкьZСJУ@-Im-Zѕ*єoъб›ž”о„іш­_рнCsEOŠчBёт—(A1m m“fзн˜BЃВл”ьh†I л—7Г;Г)aŒfЩrAИПйkфЅррЈЗзэПЌKЕk›ЋЖ’ун–ћ€Š„9T?9mРЦv!жЇ?Ыѓ‹:wОЩoћ‰1 €іэeЈФРфCHE(e›j,УРЬЂ€ŸJ#!4bcЧ@#ќˆ§7!”T ЅB, Ёdј4bг.ЇЯИк!ПБєсОФ‚ЙFтЈxH0Ÿд\ЁЖц&ѓ/Їэъ~ЕМЙГ„Ф cg ЃFŽыљbЩ„BЩрjJЭу \шмuП-ЇэW†я“•вю }Ў+Ъ_Ќ&~: ™Ѓ2Дъ€Џ&^>Ђ№љЋ!„žБЃьwc:/5W—њ |…с/ИШ/G‹XНЧ'qDX–Њs9и­TЄyюѕTУеš9П@3T`mХ~` в>ZœѕVВ§€6Ї_о0љŽL—ГбД—п Рїц>c  Ксg€aРОаhДˆ=I–ЦtЫЌпШЬМбїмЉхN<щнсихЪыьЯ€хфS€ŒK>NjHЅIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/failover-cluster-group-ref_25.png0000644000175000017500000000265111733011756026325 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<KIDATxкДU[l”EўўэоўВЫvлmY[KЁД+ iХA$iв(јЄDQkЂЄ!%ёˆ#‰ ‰ >(ёС `”ІIЉЕ† За„CэюnЛЗџ~ёЬќtг->hФгœ:gfЯw.пЬЖmуСШ9/}ЄС{cроBж…'EЄХЄ!вђŽ О}№ЧAіџƒaОВ kš†t:УьсџDd%“eщLšйƒnі НАЊж§'„€_ФŠ’0зhIТс:˜†С–DRЊ@лŽ6T—TУЂ?УжЁ[TS‚b*P--šMj)аЁРt˜. v‘K0№љ}(Н4К1{J†(ŠМW$(EхђJXЖ‰GЧlпљЫwМŠЂ!иƒЗЩ)Бб"ЅбEs“еI `ѓ‚ .Эu]Gqq1їс^pЦ"g‹ `ѕЧчaЭХaLЧ0qtЬ—п„m[ДЫDт’U7 S)*Ж ˆS6sЬpe"B!ˆjЈ|“#ŸMѕДt>›QЁ[ŠŽeй"`ђ7ЪЪХ€mЧY‘E‰NFїPЮ`D1eюлYeЄІтЏ3р&ч~rРZiМp<ѓУu_ё=ŒВR.‡дьY”ќЃbД ХЕt'ој––ŒqƒзыEmm-ЯЈЁЁgЮœс`'‚#ћ|vф‰эШнЙI%“р+ јp &~юAtЫ6[ЯІ…мє8—4x`'&žLMM99ыююFgg'ъыыблл[Р0ž…e^ˆœƒ<CЄЉСЪjЇбlMW_0ˆp}#дФ, – Кп–­­­hllD__Nœ8Зл}_љфiњС+žВŠН}н›™mХc›œч‚Ъ8sqШ)‘_ќо_]w*МэЙA^ЎІІ&LOOcџў§8pр z+–,*Ÿ[†ц!уz—лC оШяѓљ?ёTTЋщњpд%.cб›џъФ/YcЯпF ЎЂЛтšѕ7jо:Ђ,zЛьПQ’˜*еg4IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address-neg_16.png0000644000175000017500000000115511733011756023325 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<IDATxкŒ’ЯOAЧПoіGwKлаЕ€жTЃхвbЊ7ѕшХ“9x№т oўЦ#М/†Ф“1ѕЄ‰8@I<QМP„˜XЛн@нуьЖlжЅ пУМ™яЬћЬл}Cœs \šђw<їVю䉇?W8I $ і]}ДгhN”Џ–kгЗгˆŠ|РЭЛKМT60љd‹ЏЮаЩundШРсэ‡m|~_ЧЦwktmvјeРќ!?РрqZR ЬJ)#Эpд`ЏWM>grй:rів‡г/S$qkЏ№mгУдЛ_НК~џFfФБvїdUh%žйъ kGЫсY­йјв ЧюЉIљbОвWRБПеъxSнР'иД\\~`СjКШœь…оЏЋК,ЊуXš^њЛќвЕ&ЕЃ')0—MфOїd…Mcѕl~NЇТНё§zJ b")hŠ‚л6T}umюa_"бk™Ct `Зl0с%“\WФЭœwPЛн5>х’ТљЭБеєр игkъ^€џ˜ˆ(4wз"ўЁА‚HR;tnvїмињмШѓмpѕМ˜ЯD=’bЩОЄBrБшOŸuЌ™ИЧК”2†ŒомпЏ/юЩбфx%цќrр•Ў е:ч+ТћѕьТџќФ? @івo‘†IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/dynamic-group_25.png0000644000175000017500000001162111733011756023706 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe< @iTXtXML:com.adobe.xmp „бхчIDATxк„–[lUЧџgn;ЛГлюnЛавв–ZАЁ М"BН„"hx0ё…DQ0c№‚FbL@D”(M,U”"ТMRЪН ЅЅлНЕ{™у73 ЅX`’g2=ћ§Юw=Уј\?žp…HcI^’IЪŠОiъјe€žYЬ@тIЄGМї’IГIcвІЋp_ЄQoŽ- пЇš+“‰Œ;U`qtаšУЄ Э=lŒтЩ вћЄЅ˜ {с1ыёcѕБэWЛЧП2~њ9%Pl‚б‚tš#fшЙЮpОUэКн]єњ[]~Фк§ч˜,д‚ ыШоT№ю_л;ћš^›ƒ2бXŽ(инПьNщыzбM2zkРР@м@2ХЩFŽњА`СJRpЯB}ђЄџC­&PXШC€БFTSЩФ•$ћOтZЊZIШ&.† ’ фВV™ ”qЄ8НГXBU фX-[aloсUМ\тЧх@ђ ЎJP„ŒЁАEЩВЮcLР$6К,  И_ Ћd{1yS`AЪ Щ/ЂzрR‡!ЄPEo§Ю3Аг•ГъiЄБЧƒФђgIг-H)<ОBeбШИ|Тќ2šі…fњN_њGЯІxAя•m™qЩЪƒ СЭЁLJZЙžb§Wƒ[sСGMЭ, ќ~ЩЉ“LьxњрŠУ;џhoЉЋїЬЪYM’<ХRІv%1ЃА\ШвуяЂЌЈLHзЋhџЕЖŒД=.\48J%†9М^—/Š—Ж* Х-нk7o:ѕб]Нjл"}ЮЏ‹=ѕэAfЅЯ(nз!жЖ<)ўОD ЎъЗ Š9Q\_ЉЊЅЗ0wšn˜Ѓ,)Фђ M„шчZCє њMнЧћћK[\ах“‹Щ_j ЩSExkШ}— Ђ’1Х-•шмыЗBђЃEМ‰XИ=н4БhŒЇ{1 Ию—В­r(•Я kгDПьЃИ‹LАЖЪ Q>fдСП`k`АЭшчIЛcЄ!Ўfѓl‡Гs_PHвŠF‚\bUŠLP#“У‚ш„УЩДF‘diХЈiРэOфhбužtё^3юыќћ\WјђП”iše…е€ПЦЩ‘J'9w"›Cœё€Є1тˆA•ђФcƒ4Зм}K7ЂvB~ЂŽ;У‘Ћ_Ћй?Бл@К— HQ-ЋV„TŽO‡ …ЪsЯ ЋтEhД‘ЕХ.AˆЮ”SgФsdљћ{o_?ИВЛ6HБлэ;wН:nPnШo)r}8pе8$ыn­ŒМ†Ух"/‚ž ќю†r1tЖК !]ІƒщыЩ‹ўSИ_рmqС8ЗАГУЛщє5уyСf”‰сH_нИ5АЫ“ѕMX&Ъ‚ЬaNйY;їQ‚Jh#дG;:0tНўЎфъйOTюѕ<‘ŠЃ/а­…LhnЮ"” )ХИЋxžр)Ќq ›ф ЉУɘ†j­uСйHf“иЖЕ%— —}Ц2ЁO2m-™Q_Нп”@ЉИ7WЏd!ЛU$СmмŽЏ"((QЧЁЦ_KЅEѓБ щН?УпГYпУ3#OFЮGњKе-6о›КRP%Эй5ЯC8=ЫP1F.G…{"t:SŽ?‰+'z[ш7kpэџgќC<ШMЗЕЄUхѓY™Џ‚ІЊJ ЇQ/rnТkщТ™цю„aT-иH€;Ѓ}•Œ ЩƒЄќ‘М<і—0Ц<"••,ЪYњ]"KŸВ>H{ }д'б#!Р(џЈ$UлЧ‚3тЄыЄЫd<ўЄяЎџкZ^tоsц?IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-udp-ref_25.png0000644000175000017500000000343611733011756024135 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<РIDATxк”UklеўfwvgМя:СыGpќŠqьэвЄёІA ŠšMд4@iЗЉCi 4UQSЄЖ* ‚ЊRCЈкXHiDkšЪ $ ШЫ6qƒлыјБ^{=Лы™нйyѕЬLжФ ?к+нн;чм{О{О{юwУ0^ m №ATU?ъхНjџd_G2+рюЪ МћlЗ9ЮЗ5хkсuћ~Я0Ь…ќМ|Ћ,ЊBiaй‹ўoqЯвЇaкфвОЇYуОУ[ŒЄ˜ќXQ•ˆ96mfЫѓНќРRумрCVфОЬзйћ–141ј}ї§`Љ›ёс0бXpК€Д”ђ+šТšcгf6s\]R‰_мџKьћЦ Iќ№oпƒІkЕ—aЭЫћ$јCї+№{ їбR_>Cжњ) Щ<Ssn]зNžО=† BіšВJlЏп1ž’R“ѓzВщЭЫo`hюj‰ЙЦEѓžЛчyЂ t џ=и3Aq x -]B]Xсќ -P ЯР}cЎŒsq2ят/UW6™ОД"Ы њшзHЩB0І"ма Ђk”–№‹2qћ…`V` œБџŒCx’IG Œго€9яpџ &љжfw7яЧ[ž8GKВ‹@ИB;№ Ц 7йнЌЛPbИj‚Pю€?‡O[ў†ЂЕ8хТПМўь_ш3q3Шй Ы[УŸЬХг[=+Ui—АzйL&&bRbR3ЭŽЌH)ТŠЗgŽbI0€5СЏЪ”%ЧљД„Тјљ‘g=uљЇ‘O?џ$J1ЏSŸПфшіЊ]сом9IчXХн8ЛMw4m4ФWL-Oа^ЦЌc1+ўщŒxќ‰Aщ"вЊ€жЂmPGМчщФћ™і)ydВжр6Ф/G' iVHЎe'Щз<АlзoP+EOp сƒХBЬ\ыс.FyЫ&„{€a/ОжПŸjџыдCЇ/œК@щwRЬ+W oЃђ\7—N MёNМs„_юѓ…k ОЊurв[ЮНпZC@‰D,ЩbFK'dЧВUјžўзфo?jƒX’№Гc~ЇУЕвЩЈЫмћс о)jŽ§ШžžћЯŽœ*ЛўёP[x=я|гГё1†Ÿ‚ћтЬ(Œщ!xЄ8мцеND‘ЫЪtяјЄjx+Џ‹X ѕПM1ѓн•%Žп1И9ЇУЃыџбhnz:Ѕ_//r͘–ѕуQЁКыwœЦЦ'Ћ‘šbtŒиз‰> ~NC ЈќФ9ЈYёМъЙэ6|x#Гj`}ћoцKуѓ>МІтz 8BЉ,B‚Єz™ya3*жн… WУэ1мљьыpЅЦ‘+КЋЈ0цЦm@ÆУcЊ+ 0 U№?4#›&Ю% џ$ДŽ}аDY*/ЯђАR‘ 9ag2?#У_ќMДVОc ЄIйЭ§иБcHЇг‹l7`ˆŽ ќ Nж ‡з;яiyфћрЏЦЭьЪ€ЇšNNA—NПЄ]ѕЏv|йŽ3™ vэкuЋc>NNт1“ДЄ€Нc“ЮЎОЗ }oл0%лE’eh`шpIЂWŸu§ѕh4ŠййYtwwcчЮ‹2]b™(+[E)”)ЏЃrZMЕ…Ю_,­s[нtRsbѓыћњњаооŽ…˜‘HЭЭЭ8x№ mPЉrцЇкЛmёш зэр eИ”Ь—RЂАЩXFWф–7НltuuaЯž=ШхrЗ0džMooЏ§‘%Э“bvР=Kш$ Ъ’рzЭWhTeуš,=щ еciщU]---Г•жэFMM•Q}}=:;;сѓљˆcв­Ž'€ђZ[ћД9ZЉи)T ŠHї&Йч]hЅG=›o<ПQыL&''­3иЩ“'Бwя^деесдЉS–-пєOwcјFЦфŽ TM)ЪDЅqЮMР’ўиєдW0ш/]’/б­[ЗЂБББXЬ*c–eQЇs%ё& ›O#Iuф]тњ)м ™Ѕ`]ƒгPŒї9=ZХХ՘ššBEE…elkkЛРкQu30§єіblˆ‡BИ=Q‰Ÿ uцkTaї0МoРYКђ9Ќ2ЦѓыўПџо} .хЪM5!>|eЛСћЃ9№”5сЂ\Œ]Ђ–рЂ њЏЩRŒš$lIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-group-neg_16.png0000644000175000017500000000143211733011756024470 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<МIDATxкtR[HTQ]ћм3gЦM‰ЅЅЅVT(ѕє (,ш#ШшЏ"‚ˆО,Бˆž?Dєg§љгOіВ+•,gЦчшŒ3wц:ћ:н”›и‚ЭaС^‹}ік$„РКЁxtњo“8о?!œщМш\W†ˆDoNKX n'rHчБЩ.s†ŒС™гIзMq—IˆX-кRf'ЯћQ’Ьу\У*Б?‘1W:$*бйјœИ˜ЪŠ]XџДдрЪЉэ8њАb2a$Њ0ЊIхФЈb9ƒО0‘BVЩCђЙЩlЌt0‹Ѓи DгtH5рЗZоZГЪ\жРуРкс8АЗ,–A`ћ'еЕё…‹вSЬУ4Џђуљс№њWо пЇкОRгf5ЭкИйVЌьїJO}3ЪЊўъЋЉ“MОл[Жж2~„>Уќг‹ddйМ–ЮтW`nК&•в1ц’ъШй rЋ3ј§№к=g6з_"mАщgэрС |>ШбИKђ|жŽ!№є„^ЃЉЈБŽш‹гъzї Їцхrёщh&ХJ.ЬЧhпƒwѕмЧA†U5: \’"šйпЖUдi!јwЗBMШ3 %(ГйЈЫ_жНуRq'ј: оgPБЪcђ,„Ќ"9šуС5­мщњШьc/˜, ђр|g.2шђпњћ•Фм€ЎdМ$tНђЦ€ЪэтЅ“Пќzb8Вг;ФшO>g8o’$5А"џW3#ї-^Ђ}l;wЌX­ш‰щ{ŠaмU&8$LНвЪ} ”Я„лј+Р&ФEЪЦk_ќIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-sub-ref_25.png0000644000175000017500000000340111733011756024426 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЃIDATxкŒVklзўцБЛ3ыХЦію/ЕMŒЛiD…TbЂ)jE”GуHIŠ~ HCЅH)FЅЄ(?њLš   ќ Ј)-)&N€ЄŽ8еIР 66NŒэѕ[~ь{gvvfnЯ568•кkЯœћ8пœsОsЎ…вŸMрц;ZВ"ДyrџcаОпМі^ђ•зšS8БЋKеЏ7­оўнiЩZМ7s†х[&СлI28зЗ§­јв}Ѕёv›ЎxdсrТ§жYіѓЇпŒсў;]uоtесVый›њXдЦхIЁё$N~‘)ШїŠЪ§ЊhВЗ3OQ‹Ё€DЩЃm‡Ящ НhЈїТ чЁѓ4sщЩ%@ёŠiзјЬdв=jNwоiэТз&ОЗв…iиs2…‘й% гБМMYЫЊ%€’ 1ЁГŠYPT …"іoЩЧбэИ1њYЛ,ЯH4C+v@ѓrКФ繉u ўќt4ўмC*Tв/єe!KE%вкj@М‡œX%.Q„ЃояI‡šЏfБћ ': „ŠCљ.wЄк†П ŒиPѓrž№5ў^ћэ=э]ЋшЉј$ЧУ”ž :мѕЫЦнџњUѓpџт!/mTQ[.гA ч-Lh+jeBКn’(y ƒJŽ'м˜ъЫ­••Z:ёŠяхѓ6c>=Ѓ#Oy!$N&Yу–&яv[иљ#OжЙШm ŠdT@8Щ ИJJGг€JК(хrТУеЖPЈЏoВœНЫ‹$ђ$*ftёDœƒŠС<\Ј^&СЄƒ/ЗhА)7ю+MЃЪ/:ЩН2ХА§L.…'ž<sžИЩhЬАЗ-‹1 (ѓKX[!сgџщ/.*†ešМTМ2РўђтZзњži†KуjШ№šRgП:ƒ@БЛжзугАМЪ/рэ њ”IvЁ‚ц/лрУ+%œИtЅk<Ак-ŠˆЪAd ЫГщеŸшЯ?ќ<*§+‘шњп4НЂФЪМРВgў€бЛъб3в+#ИїŽејфњi,_Bm№^єŒuaнŠb21†Жг(ђ{pWyІO–`bbћпhш$OœˆO`09€ОH/жџ§зјёыBегІЧ1МџEќѕЇ[ж“0=Мл2УЬ`ДяnЌы†)ш Ep#PQˆ’‚ЅPФѓ ---иКuЋУХƒч†ЧйЩџчaQИxBSФЄ‘бQ\юшDЧ‡(ПєKэ†уœђXьЩž={цмn7*++ЊЋЋqъд)ј|>466ЂГГ*4ОЧхr# Т—чХ•}6ђНЂ q?1ЭoУША-kd||мQИБццf't@kk+dy!m=зЏC’$G… zЏlЃЩ"–^ [m „ЌсwШучін7їс–ИP™T7ЂІІ“““oрCU”м ™ …1‰’@ЃMŒq‹М0ЈЊЉ QHГ9Дc%@›y3+++sЖoлЖэ[|Df#sЄД‘ЫхЧшююОЙЬлнRŒ(Ц"’хS,"8Tј?y,н|]МД…(ѕtЏ w“мёРƒЛ_HRЁ^щxѓРч–+ЁЪIсЇIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-icmp6_16.png0000644000175000017500000000176111733011756023610 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<“IDATxкd’Yl”UЧџwљ–™.УЬtc t:SŠq†BJЋ‹ A0МЉ1>QŒІEћbёХ˜И$< Qˆ % Цжр1ЈTšZY ”Ѕгђu†vіoОхzћьMNЮMюџœsяяЩ?цЃ;ЛьЧZпЃ&ЖЌг№d\Хсoђh*hkц8vЖˆЎ5 %Kз-( №мFЬhш=4™Дбрїl|уhКFpђ|Ж*шћ2‹TЮE(РаџUu>Šб„›Г2цќ=eƒззr"02VЦ+л*АЋ#91e4ЦjЅИ.ШЬ ŒпЕQYMсЋbШлРŽe™OџQ]:`:…I€5ПŽŸПјDLХВ ŠU!й\ežАoQЁ{ tХзZ™ААgЋ”ШbПŸ#V1rнЦ#mЛїѕ0>у М‚#В’УdQЙ'2sрхЇtœ|­ (тѕђšzкU|tСФћчLDk(b!†ŸІZCKš•>‚JYlIрMu Ч†мїй›ƒ|sЫ $/mPёћ›šЮќvќhWјХНаZGQ%с2*‡Zѕ•г3Y“d6<0œј6њЮhЏєŸ)ыoЎњЛC'&ъЗ]ЗЧіьMАї ”ѓАюŒƒ-Lп˜gкГDн%Дп7ШkH•p`Э  (ЗыіyWo?§nЗuqтЪї` Аь` Z(Sm_БпзЏ6гgŠWи†ШS/ё:&|ыЃ›8эЛ}UwЏСО№ЉА‚бymyЄšк й „™7”ЦЮiЮ‚tQH…=чf”f6хfФZ—Кѕ‹’К­И/ш№-{3Ш*Uƒd!ЪЅ&qoь8wЫТ#щoœыpёАШ це˜бІy“эHШr ЉƒЃАEц>рѓ\€–Mi+gЌjЋ‹n'ѓнЩЙЬЭ t“pўѓЧFжљУ€•j‚xаJђ§ p™ё: ­}OzˆƒNї­kЮ[nNœ#:™}HѕИЮЅСeд2^ ёN?h & ищH:§@Y§ј(zŠSљ9„)ЎЪИ,›§Ф'жеЩ#цП7n#уЌЌБќѓГ‰ц sd!ЛJбєy’О­‚P!=ўпxUrt%Ј|--ІїРИЕ”MТБо†^нŠРeфRIX&ў`RдzюˆxIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service_25.png0000644000175000017500000000336511733011756022576 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<—IDATxк”V}Œu~~ѓЙГ_ЗЛЗwЛїбkЗw…kVџ jŠ’bJе@%&DMKД4 ‚’`$І[‰b$ЉбI8”†ЪT„iДBzз–ыЕНоWїіvwціcfwfwО|g7^jC ќ’Щlv~Пїyпчyоw†љОВ–ліV]+оТ<q…EДжdы>ш ћ тЁлгn,{'K_Ъ~хйЏќќЫЏJэњнщЁИM•тŠiЬOO)=‰Л2‡/䋇wK˜}нЩ3Н Вј№шДЫёлљдА–из<%ѕ|bф֘ЌDЇЯдЁ^<эикв_˜štuэѓ|S{m№7­c dёРРL||зxђГ_…}ъаšЎ—ЪMpRЂhжпщеKЈ\>чUѓsŒз‹Œ R2ѓшРГKЧЏ Rјйо/XЋsПOMьŠіьўаж]…зXg7C‚ЛK žM8&ъj њТ№ъdGї~h)ДqћГO<ФфЎ­`р›“'Фд-eЧA @n'kЎsЇ„dЂJu  ЫHїgMѕ!2И…)МЛQПpъ™то$XЂkœh([ ь‘†Bˆg€Ф%КтY =J;=p”€ CIіЁ™ƒ MOcь3ЖvхhOXwв;BЬP‡M‰х>ѕ@ђЮ)QТбA„ћч#№.ОЛе—…|лC`щЭ@ў )р”ЄВŒF ІЫ!ŠК^Лѕџ@кэіKvbtOdx+њюи.ШМYщˆk=wЬDM…"јPKSШеžDьоCD_ŒіXDЅ‡$ЁA`ЧЁišЋёM7}k$џгЛATіl~ќ $б ЋAЖ`А_8€ ‹ф’”˜‡ї*<6gуЈѓ Фl .Ъы СХЙ-0ЧђхHє‡Nџc]Џ0›“2$t$е0(]ФљщwБЁ?FтJ˜Љ‰ўј.э›„й"*[$>e AЂ§H/#ЬкˆGBЬoVЎќњz%ѕЕђоі}VН dШш№^DL‘а“HтЬЅelиКу]rWо|ћ…П=цЋ—9ЖzЎKйЕШЕ%„`‡ГšVzІ§эёZЇ’žЗџБєЯуmїЏGЛ6uл] ,m›(р%јЎaы——яjЋЫщZa‘ыЃAКЙ&щW$ъd е–ЫёЉHnЎ.ќЎ2ќшЫїIЂ№@ЙАвК“U‹š09 E‘Qг˜пЖiч’%uњЭдФН€Я“†q!Š%. ПцЪ№yЂР&ž\ЯКюzуsЬm[їH‘hЗ “Вг pl'RяН‰Zў2єЕ2Ьc`VULмџ]№FБKmœšЄ УЈhЈY>U/№tлЭЙjgЌ\ydфyiгЭћћяћЩGT—Јєj'ˆя0ДgўЏrB">ї pХ | HЅ @ЕЌќдхмŠž˜`ƒеvНшЦ‰}JЊхвўm?Ц‚ІC%пW-q rБyлNкѕiтŸў[=KtRцУ( рјU VУ‚U5ЁР+“€/sёaihЋ|ДwrН§ ёˆгˆGТ{ЬEr\аdыѕ…O—[ыŽл+,У.зWњ^4ёЦІ_•Оqѕ˜ъКk0їJщФ‘–Г|ЮŸ~Ј…Ў…}š]<ЙM Ђ1œ џШЂє‚вS" "а5#p`CПѕрег{Х.ˆ˜xм^š:9їм~'юTЋўї_ч+н6 ВѕƒN‹Rиј6щр‘Ѓl…шсзl›ю”Щr ГћЎИьї^П( м^ЯsЗ Божзд9}–^бч>”a/,ЃђЗIшЏ…1= П‡m8X+ЊdЦ2њc2ze_АKѓї_ ВЎIц—j‰Fb‰~ўxщЁСOъК5kгc&Уе 0оy Б@dз№ђgOВ–/њ!Eс2JЏТQGЏ7m9yћК W/пѓћz9UчgC§ьЂЩ~z BеэІШьуњхЉ›5ЃЖ%$ёќš,ГІб0Bƒ[ž:†Ќ u ЯюC {hcЫ№љх†ЏЏ>3Lљ§„сп?†ƒGИжI‡3ёђƒе,кШ@, Jѓ”03˜yш3ќљ§aѓЌН RF2 џќe8>љ(У/F bЃ—™ УпNпМцKу.?†Я?™W~|§4рУПП ?Пќdјћћ/X‘Цъ‹`zЎŒУї_?ўќљ ї@БдЛm3|Ї 3М{љ‘сЯЏ? ПП30ќјєспЏ`Йу.F =Зn30Мўєс7а9Y~‚хˆ%fІУџ я0ќкњчїo†Пџ3ќќ№шˆ–{ЮС]№ ш‚_@—}ў§,€*G„a|’їENнФЂжcЧ@юx+7s0:ыйС]œPП‹ ЇФдrЦ„ёнъš'€XўОџС№ягoˆ`@Трћ' ј/ˆ_П§`ŠCbяыЏŸ Пџќaјє b@Бќ{ї‹спgЈ К€щЦЊ ?€^ј Ф!ЯШ№ШN Ў‹хЭ гqСgˆ ОХ‚]№їъw†ŸŸA@Тр'аіџ&CудLА ~p>ѓь‚П_0?bрZx,ј_[…с0Jџџ…ф“ЄG'Рt70ыГЇƒйi3МС4@Бќ§tў? Bf†ч>ЪРѓспCИfXшƒШ љб@яН&ђ,@, ŒСšAрЭ]P@A9Ра‡wHiџЛа;”|@Œ”fg€lИEFm0€яIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/service-ipv6_16.png0000644000175000017500000000153511733011756023455 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<џIDATxкl“KHTQЦПѓИїЮŒщ4ц8fSffщДЈ…=ˆДАZhBЋ"ЃН6EдІ‚VбЂЈЌ ˆ  [„D/‰А0 Д‡ ЉЄНfrfœЋЮЫыЬНЇ3ЕГћ_ўч~|пwЮ!Ў}žБŒХ­Џ7ЮŸиАЖnн1Ъ(Q8G<7_ =њљЄoYвtBянuг‹k.ЧЅ0YJ/ІŠЃж=Я(#Я‚,]<@Н|–V>`Љ?ых|p:€ b ІPЙ L64 йИГу\CЫмЧ-Џ=ц„л, ћВюжzи&#fd*@ЯшйЮшм}w'*їB.Ÿk‹ъЩ1fЙЁ‘Њˆ€?щяH;! 3cŽ+#(ZEšоPš§лrаJваŸ.шђЏојдРUЕP  (#$ПN‡!г0z“яgу#ў‡›‚чПФp`щElOцЁыў(ѕфL `Њёзх€:ˆЖWnїмœЎвqѕkнс|'М ƒДУЂЧЉˆ Њ0Л8s(@(• $QИƒѓBЖђ№ЦЦlžВ€З2І`8Џ”VФRV…л)j]ФldZMСrkд­ЅB‰лђ"4Œ—TчЂEЯНЌSP‚}MT?ь7qџƒ Љ@цDЁr…бЩu!ФСœэФЅE%hк€џц[`O[N,,ЮЦж/вŠњТT“všп–ЯБ6qЛd#ID“Yс‡?ј(ѓpsџ>MAе84‡ ŒMŠŠОАИEэЏ gx Сб4P[ ,-ЅPѕkюjP7№ИЈДј­…SЯ№bY9жye уYР”#™р”чНіRш_FШБ@)yfk!–—яОГњЙJЗэ]‹™ГgЩŒhР`ў6Охт++•іѓ;ФЈ-рHкфЋhлyЭъћ­Г–Ф”РЩvbдљ MРЯU%њ}ŒЈџ…ЯцПощ{Т;6Iw‡и:™Х`жТё"uХxsЕY„ѓ3ž=>‚Уd№IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/address-neg_25.png0000644000175000017500000000172611733011756023331 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<xIDATxкМT]H“Q~Пѓ§Z­мj+Ї)†‚ьЂЛu#„WWVtЃ]ф]?ЂLђЊ‹ ЩF^BLМЬljЖьЧDХ ХЦlЭЕUSлfлкО}sЖЙo6дzс№~я{~žѓМЯ{>F–e 6јfљцЬ|ДТвсž”%ЩўcДjhюsфкГз?ЭР@ŽMЬЌ|{ќbщk4ќћСW'&с/Цe>f1РќЏmетС’ъ˜sžЄ†Ојb:ЄЎFˆ„ј>Ÿќ8у*и[Ѕ–e.Nн№ ЛКЪ X8ŽFqsГxxТ‘WпмGчŠФрXёP1P~њ№УЩЗ—ѓaY|ЈEH&х„/(У„;CЯю о.+ŸnпЧЙž|иэwПрХ˜ЦЈ9Ÿˆ””ЅH3с “Pћ}яш˜[o( сˆ$eжb–УўАE№*„+АО&Ћ зяzІŸLЧЧ3BПž №mйœлЎлv‰‚`цБ`l./сЩ!‚Š”,Wо”CЅстЁsГ5ЄvюWWž)пвz­"ђсD7)м”ф GД;Џ­ — Ѕ§ИmцЁџљёЎМ@H‰}–ƒ,&Ы$№i1ђ‡нD/Тfёs№Q,ЗY5”ї;ЁLHЙИЌ№Y&ОМћj]xzє*lРr5С#@љТyЅaУІ(щљЕТ„`SЦ)$IШцžЧ1‚­aђћWм>vџ=§Ž­ФэФЫIй5м1uƒ|GCЉмFŒЩќ…џЅ!јF*§W*˜-Гi&аззzНž&еj5twwCooя–0ЁТkЕZЈЉЉЎЎ.hnn†ЦЦFЈЋЋ‡УБКPW5z ;“bя=ќ7О—Я<ЉЏЏ‡h4J6™LPXXааа@WЮњ‰3qeeцЬ Їs8Яиšљœr---Akk+И\.  ­­ <]ЄбЅ:}—އ]{8:hŒН†фtŠ˜ЬумM РbБ@ii)xН^ZОІІ& H™ дыБз‰и‹ЉИHУє2БœгѓkЛЋЇЇjkkСnЗCKKЫЊ&###`6›iwсš_РkK{‡qЭ‡šЌ;/[­VЙПП_6ЄeF#лl6:R,УfЦy'дрp1ІnoЦIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/network-ref_25.png0000644000175000017500000000202311733011756023367 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<ЕIDATxкЌVЯKIўЊЛКЇgzf4aЭЎАВ ˆрmA< ^ {nŒЛ‹wёfЬХГрEHь^<{X7Gёр5,јˆ`r zбшИ“žбžўYћЊІ[Цq4АоTOЭдћоћОWo† !№ыY[[ЋйЖ Ю9cg|пGГйTkjr? УkуXэѓ{‚3ђoЩ …fggё5ЖММ|/ˆј^&’VћЫяяarІаUцф2Y?ŒqщХИh„8Џpм19[SенR"џ!2Т(R›…МœI(‹ Ф№Рёc|"ц<ЁСЪы(Zš:пR&џ‘М?Ё“ яfЮ€A В„PV@ы!PmRž7цАl :zHP‚|uuU˜І ]'єbЅR хrYe+Mг4 Јg#g‚ы A$аєœ0Т…ЯрФ !5E1Ч№аж№ЈФa›­ѓ~€Ы їŠїіэ?­.БL*Ÿ(Ђ‡ФИˆ4\2‘ЃђmрAžŠšZѕ[№<ŸDMЅЂі• ХЇк—œKQЯЯдw"н„KєдЈ’yКГЪT]ožс‘-ђDr$R&ё7D ЁС4[RЙФљ)‘зыъНИ хJ‡5Šb6Q_&šО)НƒEG5b*j]ИW.xœtNЛЈ^ЌЋЎљP№бшqZ VŒ/О'Ћ+pУ0o‰zrEг8wu8”o4№јёOЊЏo2=3вг С-+‡Дyг’ћ#|И.Uт%эй.jtЈFL‰QNх/<(hјNŠJzQlМ~в‹••е…Љ/--хлŠ-UёѓГЗD§7ƒЈЯŸ/ЖХ‚Њ`qё…ћъеK­МіЩљbQп§ё[лPl ЙtжLO?‹пМљ›uj#ВzЇ§<§L.(.rЕох<бэЖЙЙ‰JЅЂ&РѕH&Юgf~Н%jVЛ•сњњК˜ššКБ—|ЯJœœœ€*R›ѓѓѓ]J/ бэљsВыс“­ ПJјџpЗœI[ЧцIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/pipe_16.png0000644000175000017500000000126511733011756022070 0ustar sylvestresylvestre‰PNG  IHDRѓџatEXtSoftwareAdobe ImageReadyqЩe<WIDATxкЄSKhQ=яЭ›d’ЖMлБЖF1Є,nZИ\Њ .7ХЕ….…Кv/ЎьB]ј€QдEi]DIЅјЗкѓБ‹&“I5ŸI3пє#(Š…\8\ИяМ{yчмG\зE;СўupхъЬ)Пп? Я$iЩВьkгSSwн`_пЌ,ЫЃQШ]rьk6;ЫЫ ‡ћПФ# ŽŠŠЂр`$ГйD!™”ўњ„Р”яЗBуњxMytўIi П_У4‘ЮЄ‘^ЮМоС)еžєЫоt"PalтСј0c fЃет*юйЗ#ŒВчаЫПžР ^rˆљrо7д7)Uu\z8‰ЯkЫ(UK›фP`Я0OщmМ. ’JЅюSJŠЂШbЗЦŽuwі`єа(.žМ€ZЋ†/ыŸ`:5,iМ|ё–cсЦјЭьHяHеЖэdqqQчЛ…Bx_~‡ЛЏя`њє4Кќ(ќШС!6lXЈX’ХyЬ—ŸamСBтмSф … ырQ6 „УaL9ЅWAН^Чs5еFM˜hRЖ`ЁХ6анбCа!I(%AfšІ jA€\,bюУдЊŠ…яq8ЂЭсРѕmH(WЋкЄXQWоІLедКІirў[Џj$є8ŽŸˆbнЎlIЬ}ЁdЫ.ЪMЂMРqМЁќАЮД\V+Џн†QбR|$8р [ЩСvзšKЇEрxЙFрšdг‘’Ў|>ŸNЄЫ"йо>‡УГщэ.ўP€[onЎmЛП‘ЂЭј)РЫ‘п ]ИIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/interface-sub-neg_25.png0000644000175000017500000000333111733011756024425 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<{IDATxк„U PUеўЮ9їТ§сТфІРŒОRбўE ­™Іl_eJcV–MХЋї*”bLŸЭГ)4K1Їg>+$б„B™qДFŠЉ0E{ёxЙ?чо{юЯ9ЛЕЯ…7Ÿз[wжн{­ЕзўЮZ{­Н…є'њ1JНћгВOtтџ­лДэ љЭmG}Ј)Е!бќsСEs‘IП6XЯ€ŒgР[Oмй=ЁЙˆЗЇяfQк=^о^+3ђeg;‚Ьэ㘲i]šІ–2vЪLGœ0Тq’Ћэнѕ‡Я)oэѕ$~pм›SЌAШЯА{cіžd/Ў~пм?ч'Xќ3+OЈkFх^—†o‰@V6|"уШљ`Т‹xo†=eІKюhГšЬI€@l)Ђ*O) ЕXЕи‚{Dџ*˜,"DZеwЃ’cЭQYŸ“эЬЯм:Уˆ!иxФ‡gќЊ!ЗЕ ЌЊй0‡8Sє*,гLf ЖЛž™‚§E Иіы7ЭУˆ$  $ы жЈ,qЎИЫ„їVЛИ=.\Эќ н’азп‡];ж\ф˜BХБ]оёqњ_э Ітэ‹ѕ§~?|>™мИtЉюШ d™ЮPQјіz`aY‘Q{ё(ќ…yШнКѕЏynџїŠT”}њ:ZіїС+{сv УщМііvцsx===фR єЯ;.х_8ˆ'V?ЌsЫбY[; kљrє,™…Wўё,R |HІЋˆoонн_ЎuЂЋЋ §§˜ŽИџђв42РЇ!-ˆGg­‚сШЙI8q}овЅиTјwџѓ„"aДмйŠŽŽЫ:€лхŽ.уЦјqпŒ’…З=Ž”†+8ћђЫ˜.nЯлБ{ЗnGљ•зP#nИPE|Ќй–TЄ›Sy]Tж&Бђ—e/"эихI2–-›hv‚ЇŸЧ]ѕEалX0Eхq‘lšз6ˆц’’ ›-|чX рXВчЦй›‹‹uћc+Wт“Q7ЈpЅЈ№и‚v*щpкH_ ?”—ГѓЅЅ“ј-DѕЁCxhљŸaћюЛ @ЃеvkqёzрL=Ѕщ^JNC)ќ`Сар NŸмв"ЪT“ѓѓбии“Щ„ЦІ&ђђt§xёŸNUтЉ'Іћ~…z$т*јE:ФщKЦxs ЊЊ НН}щсс_tАКЎœœ1@мЏ{б">нУћ˜^)F%Ц†ƒ$ЬUl˜ŸЩЛ9+*†Ј•`лјž%ЩЁ„ЧƒЄƒ_D‚ЛœЧЏbОЌD9ЋC@гхpjпПn›м ‚ъЫšh"ш%џ”]af4PYеŠeИлМ?оЫ.Ё˜б„№n?ЬЅ(Й„УМcXфУ<~эД;hcsuЌю њх TZДŒLХф Ёaпњ`№?ttшkЭЯQЂФ8RДЪэvE|DŸПg—Ѓ|i7яўk_и Ш‹У^§†с „‚;йы(u•RБЃ˜,š…Š.ЎlT]Д‚j‹ъш„ЅџŒR8a Ќ„а8баџLвtN џЮ—"ђBŸрщGž‰qя[§“оњјM:>дOЁpXШЊБtЮхTуКŒjБˆFФœQ=Бgсћј^7/…№KšyСћиќО€ясЯŽTР0р%ЮbZYКŠškк)аРx?щ‘`Тt6Š‘^v—0uѓ…]|ЏO–, №"3љО“‡Чx’ —RТ‹PB$Ђ?љсЇн5бhTBЭu-фДКh]u3љУ>ѕЙi80$p@$dв(я9;г{|‹;јЧч‰;ЩЫd0,… Р§\ІКL,ся<н …NwїїаЁўїЉћдaЅb[ 5ЏXO+7бW*[ЩЁ—‘Ї_џ&џціљ„Oѓк.зЈ-…–)NЩТохi+ЁЗЛЏ‡оьyƒ>8DУоaЊpUб7ЗакђV=„џП"…?“MV“k|8з1рЄЖdъ. %|ШцњНp$ђьРЙГэтF†AmѕэвCєЗЗџA>`?_ОŸП;™ЅKЧз†Еzy<Б \Ъyб?рщQфѕ`8EнpЉяЯЃ„^ОпwЙі9pzpА ‚Ÿ9KG?ыЅАљ3Эп fxЯё˜Уfз†љв‚ёЅт‡:O€йСгcх%eŽ WtЏЩEv8Сг-бЈёя‘QѕТ?ЮзюЫTјє> ˆЌbY™k—2dј‡пцio‘гUzuыfQб™‚лЭЮR”0Шг­С`фЕP(ђ{~џ3ОЮAV3АFЌѕm› k‡ R–…ЧўС5<=iЕZ*Zз4Sk}U-Ћ"—нЉљ‚ўнќї6™˜Т,р/R”€КўЦKlКIЖ BЄПрдЈ>нУ„i˜яw› Ц)№ћ;ГќhO/:ьі†ЎuдБІ“ж]ЖŽ…wб™бгєЬћЙxаXЂqV'KЗ(‡nнф™ѓ—шi(0“Ј˜бэсв?ШЯpfˆ+ш&ЁИ†нVnЙ nX&-ј И Ф аU_е@МQЂњJSQ/Evc‹AAšJœОйMДвт|ш)ш1fф*јEPl`™@ДЎс6'5pЧWW6‹ъз Ќ„Ї‰ŒgЙџЁ‰ЇgmVkЫњЦV!|Cuƒ<]„Wсѕб8щЈO`љ)нK‘q!xˆ‹ЏЈ&SейЌLRеit—5PБ&{wT0Щ еГlxПˆЪмҘп#ИРэR{Й]v›M”ој`7з -HУШD2ЧРъx:Р‚ЖзедR{C;Е\оТІn;с‡Ї.айё:=~‚мў!ђБа&яДb1ХŽ›Z”пѓgeІ№3„ШTIЪн$…DOДКGw rќ"(6АL ZР5Ќ*]#'@pJяc‘I7ЁAf™oслтЫy<ЏijW}mu6^IЕMBјЃ’ѓуgЩpгаф ]єNžр0љ к)DUф^Хqсe–щ. ZiБOfЬи7Р,БаOў OXˆ–‹“Cnqtw4ж4бXЃGм 5Їсч‘‰АМ}vЛѕъЊђ j_гAWЎщЂЪ’Jš ORџХOЈїтQі}N“lюІ‘;-…L4y$ Ÿ,DvААпC1pKАLCƒ‚kмтшЊ\VIЋЛDѕ‰ŒkЋ9 яУ#њјЗ7Ќ(gгчВДКДš<ўњdЈ‡Ž|JgНМуSЄA5&P&Т/Ю’3Љ9O ,lCј:2ˆ–ЉаЄ€л@œ] Ѕ7ЊOїˆА†><тЁP8bљјxяЏяИžТбuŸћ€>|Ÿ&ТcxУ1с…€ГЉЋљ„_Œ@АЉДp%PЪwУьТрЗБы]˜eщъѓ!,4жОрњУ+{яМљкщєX,аaЇ5mqТ/†чW,ЉхjfJ0јˆp gX&лI‡]wььq0цЈј€з7a{љэƒЛ*/wjc!Ю)МВаІыюХXˆ–AЯy:к}2Ž82'в &‘ћ}РВРЩРіВ5ќPGŠ№ђ ЯŒЁФњybV9O?_ечТ>•щЖйєsЬщчjБ~†jЮVXІСуcqЎс~Шg’Rї8ќN/EcДЕЊ™5фšо]џ0‘Л‡3ЏFQ…вQ#цДтgЎPšRщwŸТь‹’QžQлуА”?Щ(Ѕxe№IнЈо(4а2.gaFр ДCS zмhєVРБI€ШЖ<№ыeмН};tћ&‘C1ў…XОt9Г.фЇЦB№ѕє вм€[ˆaш—aьjzљH#…ЉZ,*ЇФ9УКЯЎ Й‡sОНИ2[ТжgIЭ6†[Б4ЩQ|3ѕ2vБаѓH.цH:.Г'ZнЅdъ-‰ƒqKŽЩ VnCKГЮЦЧ№Wj9=‡Ьl“,єЮїnеб…h›="G[hиєB0\PI:“УыЧ;qeшVУ TБ„l2ЪTз?ŽФмЎў|—Y;кvкŽ]іЭ\ьђ^ЎЕ>џСLЙЏЗ§'^ФБўƒ<—ЪЃЇ'hМіЦЋМЁЅeзюёWkŸМз№щH8ЯЮ|Џ4iыгЫ)ƒ„‰ PYеЙZ0ИІFйх“PчДъЛ}ŽGи{іI?žњ,rjЭЪ;>/­љК—Ь‰Жl;Rй$м„CБ-т87xŒРГАьжОёэzПщОё њ˜я д1_ф g‘ Ђ<Ђ’Ш#ŽдЩ+TXА;мG^yџшƒ…ClљЬc=eэі—ПDˆќЧэЉ%x*›‚KюNц†+ƒBБЖFmпИ2#ЙNk^tLyЋƒ> *OЬK)SЪшцЈ%Vh=ЈЁц—Щ3H„ #ЪэЋГ'аƒ‹UЎуо[|ЈВџƒМс§РТw|яѕЧ–Џпѕъэф~—tf;‘kЯС%—ч4g=‚HŸSVh„VJ№Œ2tЬ3ЈБ*Ф8і?ЮК~’Тю7=‹ž˜n*мЈQц`\`eTМ2†T1ДЗ ЏAчсcq7ў RТОЗїМЬъЭЯЭџхŽWОDyЩ„ьdлГHe’H8qЅ€˜CЙ^ъh šˆ!)@яЅTBбt.iЯ“F(бМFІ_’_*…ъ-пŠЯuШыN)'ƒДKƒРxтм$&.L žтћŠ?%Ѓннq[nвћ)Р}cŒі]OџњчЗ’ћ~jjЧTЄsiњbL(!CmљшMЄ&ŒидЉ?Š“P—ЯЛŸэОoП§6ъ:&NюТЬйГАwd7мxŽz!šeКТ5ї g"Ь™В€0‡Јєаох“рЖьЭЉХ‡+/М—„‰§Ё§œОбОkЉ›ойо‰t6­ŠЧ€žЕ~Ј)ЉЪе HУа€•44РТз[A>-…Оš7OiŒ>ЖЌыTќчй+ёју?Рї§žЮ6”u|bюКы.мМєNмЛсNT'!’,{'y…8а}&wр–ќБЦ‚zPПОѓ‹э‡џW~јпAa(nю‰З~x-UcчЗЇлЮЄщІdyЁŽљЛ­DЈFА`јщv|О "f/„AuТЦЖ‹?˜љGјЭЛПСу?јПњ„3ѕZ[он‚ћюПSВSё ї ш(ej е)9Nр˜”qdкшœKоSІћlБVќГїЪМMџї5їžAѕњЇлSDrHјX2ІД•п–г‡6Sћ:]…–с- "Л7у"lІ ћаhЦМPB„˜‘љй…XГf5Йs`˜eSЃНЛ{БyЧФ="ЇEr|Я„ЁКоAŒТ!ЮЕ‰“Ф„ L˜Eњuщ›ЫZŸЈЕ–Яь8К§ Ъsг)ЂИ)ъ8н№№ѓ*‘BУЯПёQћЁa€ЁU„ѕ?-~8.% a­ЇБЇ?ѕ“эЯckЯжŸ PбU­—IpКЖСЮЅCSЅLђR"AH(Іe i'Isi;AЩqЅЦЋїVOьоеї,ЃЪю’1Mo™ŠЊBУт”ae>ќˆЉaS!!Z06О[,Ё9яЫG0РeЙ@6о†3&Ÿ‹—зОŒб‘Q­H“mXH.ЖКІuЁ­­нx…с BЇL­HЉ<7цЦеhыL kfТfАЋ:Θ[вЊеаиzИч2Вј ЖО*nZnЌш­)jSОjЋ[іц+ўюУoёЫя|S šb'l$у‚ААbќуЄЮгo$БўеѕЭТJX№…*О.Y€D<сђ„Ѓ%WЪPŠ•Z!$l\8)5и ВŠУ,ЂŒђi љпь}Ѓ‹ŠœѓйњЪѕ№щ˜Rё (ЋG[ы ЁЦƒаd›юZX€ђ -ЄdЃ&bФ0/˜v16nќ7є=f№Іљœ†ЛІvaётХ82а‡cХC”H'lrшЦ‹%kqCЦ‚l.NxSЪЁgОь„ЏLMku‘ўЯkп]Qѓj'Х\НИŒЧB›пТбЕ[b>3JаћV1ЖЂѓАКФх№RБЯїP!Ё2?Зs2нxс…Mj…QЎa…ЎФьљГ0ЉkvьпŽВK)0C 0.Ѓ\˜„.LFaЗчЌРЪm;j˜˜фяМ`Дž1ЖІ [“В#kйZнtt`&TЌ‚”`ЊSгfп*Ѕ…J9ё<д uМљњQš CD%w:—СЂe‹шсvнŽFЊ 'GzŒыŠIкѓЃRC˜”ЫКv•cФ›;Ї&qФЁRкЋ9яюй'ЛЛŽэ\De­tй§cˆP›ƒRЅБА•ЄZ‚ƒ(эБkKсšsjaEB7GИйa9‚Fў0K У7‹SЛЮТЋ/ЌЧШШHTј( ръбXП{ў8|§еCР4n * (з_gEЬP†щ„Ќ€r]dЛ\4NЉVZцч0zъЊРИ4 @БЎŽ[тbZиaзL;/˜q ޘzх\§х~М~`=6lЄ‚Ь3М@ЗЕ„ЪЌy•'аз/i?]b о|ѓM%ИRНЭ§єŠХ]Ь[8эй6МйГѕTnƒŸhRpбДОДяeTsЋJ‘ё€8"25†\k‘Kдw†NWDmjЛ,УЕКeoЁ%.A`њњз/Пг33№ќѓЯуѕ ЈZ›ˆsЯ;з,ПѓіЮЧSЛ~ˆFВЎАХцˆаtƒ-А1m=gъ…иДivюиљ[ ,Ж ƒпТahdЧіp3”ђ\šЖcъ‹&Ы4a >  сЁ}‚‡azІИ[шVе)ЪUeГЧЭšw|-`№рт™—т„ьLќЯћяGяž^uMџБ~ЂЏлpўEчcхgW*ЏxzяOPMК Лдэ.яŸƒйЉn<Аіјžy‡ЂпаH>Ћ{N˜2omй€’;FрGMŠШЭЧ o5Ђэ-PQDЦх0ШД“"b Ю3Y]Š9Й:—В юд~нlh4љ=чЂЮБzѕjьоН[u€й3№‚F€—жМЄвбg>ѕ'Є„:ž>№c42„Ž­Е№œnЯž|!Žіkђ~“їCsmXВьDT*eьюп?SCŒrПŠ}GŒoІHD–ІHsN і‰ з–B*rх0ЭЅќžуz?ыЉ*.­ OЙ}Ѓ Zz6aГƒCЛ›Щm}ЯttBn‡гў‹ЯОЈђэ—_‰ŠWСъО'фъ&еj m‹MРђ ЇуЩ§†‡PЋз"ђућšYNяžŽщгЇakяь/ь„з9FщŒ€зз‚Њщ6ш”' шi7ІУКNЪ[TЮqТ’к’ є:\Њ§г .bБ&їГM9ЮƒŠГMjlPœ‘}~w7vякmR]щ‚зыu<ѓд3`1\ўЉЯ T+bн№s№ВЂЎъћ;N(ЛXЗvђљ<< Рx+ ‘IbюЂ9Ъ7ю~Gq€ОР–УБPъr–ГЁiž’Ње–эЭMИZ%Њз ‘HФŠББ§ДЋЇЂХє%хц"{‚а}5лЪђ ош.VˆнФФЮ#Р[Лv-J…ЂiZХпЧЄэ=AѕErСJ^ХЫЃЯЂ‘.#NwіЄxm§zьмОCсEЋј§МБxщbь:А{FЖС›S†L™Ў’Jб&ЭЁ–й +ЄQ ЁдчбрЈНO%Ѕиš&”DYЫLok^]ѕэ}˜‰ ХўЬD†!0z:ЫSлзН‚Ž‰јмuŸƒKVL(ыqхHТА”Ke|ыG№Ъ†uИіьыqzђ|GŠ˜•šтsёГŸў еjЕZ-RўЮюх 0Ѕs26їў•tЮЂЖ)[њЪ(ОЕwъцŒЭ.zfrЕ†**ЈET§2JAcх1ŒUѓф•ЅВ3yХЄ›=пk‹gICЎюФлœZŠ+ZиŸЁВ…Ц(ЦFђИєД?RљИgѓVќ№, U%ЁЪх2 љ6Ќп@df*Ў8o%vянƒsg]ˆRoпYѕЩƒих­ё˜І|NTѕ"Ѕа7eЭSаeЏ„Бњ(ђ” ѕ<Ъ~FQ­сён йќэ[w`ћБЭјћ{юУЙŸ<'ђ ~DЅГ^Eжl`81‹–/Т гNРЖƒ[PŠ “ѕ ќxЖWъѓ5=чjс„оgс5‹ЌWяЃСЧbц<х}OŠџw~tуOЖАп1|ƒ Q­H@HідаЅ,Ч+‚—І,ќJ^ђiQcFЇšЬ)ЇфГЧ№7oоŽН#;ёџ№OЪ­a8nž$ˆbSћgл„N?ы4 yьъяз^…лЎЋ>EuЅЁ’ІуЃч„джu…cТЄЉXiЅŽа ЌєыPKИ‰ЗTK’ўyЄWYх|rrrq^}СЫжjdљЙ{БAЂ‘W–/’ы7‚šВ|`…WŒ„DЂXЪС_oј2†jxфЁG(ЅЭkvx[ŠweMеЋз`6ё\,ь^€нЖcЧЇиw(яГћГ5ЕkЛF{L[_ яяhы!ќY…Ќ_8ІЋнЖTћk,Лђ€sЛЯ[Kлзъ”’*ybeAE­л+ycJш1В|‘ЌЮЧй;l/O .-A"UнњBвЧБЬмЙіRu€UџМ sЮ5“ЃЭХGЂej#‘IрфГNUжыщл„FЖLюOХKB[з1]O ~жЕэgމїF9вnчшi42ј[~ўѕы"P,щ„_0…-S(Tй=bplѕкАb}е ЌТƒЫ\лхiS.ЗДМ‘Њcй}И§…ы‘щHbеwVсѓ7]Л’ТКОРщsІcЩ‰'т@_/њk!:=ФВ$Ќ# Ы“QюWяЅЦƒЈ-кfЭ€дыŒъБ> шщxцХWмT`HВ=Џ —Ь=C иЩы№ ƒd}7іЖ<ЏПi0ъЦІGйвїњ}41*єd…HћшMnТ]/о€C›qнUџKЯ\вœ”7˜РЉoщiKайቇƨœEl‚YbЋ„lДІыK]яЉ—9ЖКr~/]“\Œ’(*эїvOю^ЭжЗ žbппьЁ›=Хœ 8XSы№TJф"C„&ЮэФІЁШMКŒ–FdKцО}oz3~~јˆw8јкзў ч\z–f•Цњm“rXМ|1 ХQьн…АЃ7Ыm:эњš}~ €zцCZђcвЂcНDwŒзИЈ9Ш€*вв‰ЬГO~сЇ=vzы"Љ0Яќ˜—ŸVŠuЅ*kЬ,p3цлфDKHгъ6JbnЎ88‡ y‚Ь†шMlТУПў;ˆL€›oМ7§ѕЊллее…ѓ.>'/>ћŽьХ@xnХiЪQЎnQ] i];Ši@А5жh)cж5ŒюU ŠroŸ?iў“PsЪк][—Щ)CцnIџWŠ“ћb ЙЙЩ.Ј8дF=6aЛЎ‘7ше]LUuЙЊуWеMjaДƒD5ƒЅСй89}ЮžЖюъСіwwр’?Мƒ#§јёkтPn2Ÿˆw:jEЙТБЋХd”›+ЧЄYufX!lЇXwЦ‘ђUХШиВ‰ь7_ПћЭћш‚š АuвФЬЮ™экvЃц]Q>FЊgщdЈ,š"$ˆЪgШРЬC™p19›3G=UFOѕ AяЦ˜‘˜‡I :АэРoАцэХБX/SЉаЩ:Ъ{„]gкZŠ8WЗыьжжК? ›•b€^Ђљ•ч§_\}ЦЪhЎ„Я…’Ђ§Жь%T =DšюЮLкЛhžVнЬЬШк†Є‘ЁВ…ЪѕЖhБ.Ьн™j Љbо0]T–ЊЏшХkHMЃt8Y"жцЈzФКЕŽmC…Э>šбB~dЫRКƒядаЗНТГ@ћЇwLПу™лž{Ž—>hЅЈВuццф­хџШЂuЬs›цКi#лr\OЖЬЩI“ЂЄ‘Ы*ыqЉэ‘@ юэiy^"–&С“зЎ4Б,Ѓ8vLlУ,’Д^aAб†ˆЎ~vићN ХZ1˜ž№—ўb-/“+їџ@Јmі–дН„œw№dЧ<‰Ь ДX[6чрфјЊЋ‰жš~Zh+""2|27? НЯVЖdFЕБ-§5 аДж,Щ7-1Uра>}›ъїАЏZwћ/ПJ‡ ќќZ*kћпa{Њ§~к~ЧЋШг—–њšгUЭЙОРRy=I)eЫan‰gJЌDWЄpLŸ_ŠІ@†*KcнжHTЅК:Јs‡ї8МЕ†Бb™уўЧWžійŒлзё ZпK‘"њўсшi§КхїеЃ{Bі‡бjЎр 9HГшI Fžaждš№б]%)[чѓš“ТLfDгэŠ]š.”эP™—іlЫ{pWˆУ[­В№?П`СїпњЩлЖў^?˜˜јх sKЕвнєзѓэкfQHЬ•ˆgu?fГІІˆтпў.Ш"Зхѓ\дrЂшšЕЛZ‰n хіВyŽ "|^НHТяіаOЃ\/ѓ‚ˆŸЌXИтўo~цo{ZP?ќHПъИ-7‘2УWˆ#|…•Ÿž$б1G";н] Ђeq‚‘лКцЇsNK9Ы4U54„U†jYn‹ бy–є8šўђ}ЦŽ„ЄT7аWFЕQ к’mпНтд+ИљЂ[аѓпя7ПыЏЦdђІи­ДхБ@уl‰іYЩ b\А"њщ\„Вл­(/ "ргр6­nгKб[qА—Ъx*оШ8:3Ўљђѓ›˜ЏЕцћѓgs2{sъb/єn ‡Н’8йNa1“1CЊ}…ювЬЧ)a„vtug–Вq_ЯшиquИРЂПcМЁIkы„хc‡ Ox4\чЯхэѓќЫБŸнђ4/†ЎМ_ЬlПœuћ ƒХС?#\ИŽо/g‹Їк%rг%кІQhL–&4tdЋi,уš ‘UMGG+РmV}мЮЂWeˆЊЙc@ОЯGqTЯ^бГя zћфUЇ_§}rљУ&ЭyVјњЫQu=фrŠНЋЎЂї •01A ђDJШLШL”КЉi„з1пŒm‹JI6DшU%ІXrQ(іS!ю…цЇuс^*пW/˜МрЩяўщЃяpЃзX§џыOgЧ1ЧЩ_юZRn”?MŠИŒ:_F+6%RTлgЈNгHЖQШd]$2т зaC"Ј xD‹б~”‚8пМ —ВЎћYќхХгЏ!СЗЁыш‚џ(ŒћОх__šй7Иї"њо$џ9МŒ”Ё–2DejKкГП@БЪj§ ‚РЛёwБфЏ:RnК№ ыVžqЭX Ѓ >ъ/Щ?v7фђЏ/99_Ю/­ћѕ…єО›IOЅmm3Кч–IјQГўИ›8œŒ%їпCЕћЖ?џа#hуИќОVo§ћ АЬѕO*iгAIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Icons/openfile_25.png0000644000175000017500000000236011733011756022731 0ustar sylvestresylvestre‰PNG  IHDRФщ…ctEXtSoftwareAdobe ImageReadyqЩe<’IDATxкФ–[lUЧџsнnwКнvwЛЖ—pUc­—(Di@‚‘‹1F#1Ѓ‰Фб}QŒ|@ С€ˆјв˜ЦЊсfЁ,”–vі2лйЫьЬ9s<лДЖXPˆ'™‡93ѓ§Юџџ}ч›#0ЦpН‡p= ЙuГ5{~­[Јм‹з`О3iї/qНмљKsз2Иeгf?рЊ“ЧІџ b}ђєQkЧ3Л‡Ж.cўщmDIд)Рuџ|&_ѕj?\куŸБИQŠŒŸfm]ж Q№ЪV‹Оєљ2c=œ4 …@=ќ;%ЙЭѓ“Олf5Ъ *С€OФНќ@K`С“дsњ\цфз((ŽЁd№ƒХ{скВўмžЖK€MѓNљяœлЌмX/ПъФƒБмS]oУH:)Išш}дf^‰C(dљ жGЫsUѓžеХъ:˜kgІC/ЉЫml;эЛcnB™”РсЛ05кчt|3‚жр•‹ЩЊЄ1&ЈЅЂЈШвeьВЖ=–гкVшr<1HxјХАЙyQ‡ЏхО„:эь;t цЁЉї МжШИXЩDFUЩЏ8$uAѕЬŒdШ.6B‰Йюоlѕ’—u9І^ŒqЩБ jžXеЪ­УўИYѕЁ&}Ъ] Ёщ! }§Љ,ЂzЅ\URЉMвiПP“цЮ’ьы“ŽW?В:$ЧCаJ‹+gёнЁ_MEh№$”лчCдЊ*ЁZBS5єѕёї,ЃВ0ПXЅ•ЈбячDёьœ&7Žи X`Фц€2* ~сШм0y˜Ычєzў~qјНъ`~EBї™ €]фUЇjRmЄРcУ Ќ”Ћ%НINуг"џИrАїРqУKЬф6Л`NЯЛ№œђZГаƒAƒu8гkѓШ<уR@ЁЄ~mY7оzДп=oq*fт‹]эЈЊ‡pг=p‡я`Щ€КybД5{ЙГrUсб0[!щMЏЈMяQaDuХ7‘†Ьњ•§dРхKаБhvнЛбеОЅR Жmƒf“'ў_Пд<о—*Щ7{NЂШу#UДјУЎЫЦќ3fжФ WGМќОcpЯШNИЄЛ“CЭб€g§м.ў5ЩWЌфтПбЭўІ!ЈqоН|пфсф 8<сMaŸ—npE­Оюm3šџьUCЈЧK8ƒёЭu,вМдOт„mcЎъ ‘\)Š‚zЙЕЅэnкс зхДвѕ”Ф ЦZvzтџ~$њћјC€ЇY]ћ)БёѕIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/RuleSetDialog.h0000644000175000017500000000271611733011756021722 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RULESETDIALOG_H_ #define __RULESETDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWOptions.h" class ProjectPanel; class RuleSetDialog : public BaseObjectDialog { Q_OBJECT; std::string platform; libfwbuilder::FWOptions *fwopt; Ui::RuleSetDialog_q *m_dialog; public: RuleSetDialog(QWidget *parent); ~RuleSetDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // RULESETDIALOG_H fwbuilder-5.1.0.3599/src/libgui/filepropdialog_q.ui0000644000175000017500000001516311733011756022725 0ustar sylvestresylvestre filePropDialog_q Qt::WindowModal 0 0 402 578 File Properties true true Location: false 0 0 location false RO false Time of last modification: false lastModified false QFrame::HLine QFrame::Sunken Qt::Horizontal Revision Control: false Revision: false 0 0 rev false Locked by user: false 0 0 lockedBy false Revision history: false true 100 16777215 Print Qt::Horizontal 40 20 100 16777215 OK true fileRevHistory bt_print bt_OK bt_OK released() filePropDialog_q close() 20 20 20 20 bt_print released() filePropDialog_q printRevHistory() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/AttachedNetworksDialog.cpp0000644000175000017500000001071611733011756024143 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 201 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "AttachedNetworksDialog.h" #include "ProjectPanel.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Interface.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Inet6AddrMask.h" #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; AttachedNetworksDialog::AttachedNetworksDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::AttachedNetworksDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } AttachedNetworksDialog::~AttachedNetworksDialog() { delete m_dialog; } void AttachedNetworksDialog::loadFWObject(FWObject *o) { obj=o; AttachedNetworks *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->addresses->setEnabled(false); // always read-only setDisabledPalette(m_dialog->addresses); Interface *parent_intf = Interface::cast(obj->getParent()); assert(parent_intf); m_dialog->addresses->clear(); FWObjectTypedChildIterator k = parent_intf->findByType(IPv4::TYPENAME); for ( ; k!=k.end(); ++k) { Address *addr = Address::cast(*k); addAddressToList(addr->getNetworkAddressPtr(), addr->getNetmaskPtr()); } k = parent_intf->findByType(IPv6::TYPENAME); for ( ; k!=k.end(); ++k) { Address *addr = Address::cast(*k); addAddressToList(addr->getNetworkAddressPtr(), addr->getNetmaskPtr()); } init=false; } void AttachedNetworksDialog::addAddressToList(const InetAddr *ip_addr, const InetAddr *ip_netm) { QString name("%1/%2"); QString itm; if (ip_addr->isV6()) { itm = name.arg(ip_addr->toString().c_str()).arg(ip_netm->getLength()); } else { itm = name.arg(ip_addr->toString().c_str()).arg(ip_netm->toString().c_str()); } QList items = m_dialog->addresses->findItems( itm, Qt::MatchExactly); if (items.size() == 0) m_dialog->addresses->addItem(itm); } void AttachedNetworksDialog::validate(bool *result) { if (fwbdebug) qDebug() << "AttachedNetworksDialog::validate"; *result = true; AttachedNetworks *s = dynamic_cast(obj); assert(s!=NULL); if (!validateName(this, obj, m_dialog->obj_name->text())) { *result = false; } } void AttachedNetworksDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); AttachedNetworks *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName(string(m_dialog->obj_name->text().toUtf8().constData())); m_dialog->commentKeywords->applyChanges(new_state); if (!cmd->getOldState()->cmp(new_state, true)) { if (fwbdebug) qDebug() << "Pushing FWCmdChange to undo stack"; if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/iptAdvancedDialog.h0000644000175000017500000000277311733011756022564 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPTADVANCEDDIALOG_H_ #define __IPTADVANCEDDIALOG_H_ #include #include "DialogData.h" namespace libfwbuilder { class FWObject; }; class iptAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::iptAdvancedDialog_q *m_dialog; public: iptAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~iptAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); virtual void editProlog(); virtual void editEpilog(); public slots: virtual void switchLOG_ULOG(); }; #endif // __IPTADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/macosxAdvancedDialog.h0000644000175000017500000000266711733011756023264 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __MACOSXADVANCEDDIALOG_H_ #define __MACOSXADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class macosxAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::macosxAdvancedDialog_q *m_dialog; public: macosxAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~macosxAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __MACOSXADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FilterLineEdit.cpp0000644000175000017500000000347211733011756022415 0ustar sylvestresylvestre/**************************************************************************** ** ** Copyright (c) 2007 Trolltech ASA ** ** Use, modification and distribution is allowed without limitation, ** warranty, liability or support of any kind. ** ****************************************************************************/ #include "FilterLineEdit.h" #include #include FilterLineEdit::FilterLineEdit(QWidget *parent) : QLineEdit(parent) { clearButton = new QToolButton(this); QPixmap pixmap(":/Icons/neg2"); clearButton->setIcon(QIcon(pixmap)); clearButton->setIconSize(pixmap.size()); clearButton->setCursor(Qt::ArrowCursor); clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); clearButton->hide(); connect(clearButton, SIGNAL(clicked()), this, SLOT(clear())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1)); QSize msz = minimumSizeHint(); setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2), qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2)); } void FilterLineEdit::resizeEvent(QResizeEvent *) { QSize sz = clearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); clearButton->move(rect().right() - frameWidth - sz.width(), (rect().bottom() + 1 - sz.height())/2); } void FilterLineEdit::updateCloseButton(const QString& text) { clearButton->setVisible(!text.isEmpty()); } fwbuilder-5.1.0.3599/src/libgui/clusterMembersDialog.cpp0000644000175000017500000003674411733011756023676 0ustar sylvestresylvestre/* * cluster members dialog implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "clusterMembersDialog.h" #include "global.h" #include "utils_no_qt.h" #include "FWWindow.h" #include "Help.h" #include "FWCmdChange.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/ClusterGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; typedef std::list t_fwList; clusterMembersDialog::clusterMembersDialog(QWidget *parent, FWObject *o) : QDialog(parent), table_update(false) { m_dialog = new Ui::clusterMembersDialog_q; m_dialog->setupUi(this); setWindowModality(Qt::WindowModal); // assign clustergroup object obj = o; FWObject *parent_host = Host::getParentHost(obj); host_os = parent_host->getStr("host_OS").c_str(); platform = parent_host->getStr("platform").c_str(); // if empty, retry with parent of parent (interface level) if (host_os.isEmpty()) { FWObject *parent = NULL; parent = obj->getParent(); if (parent == NULL) { throw FWException("clusterMembersDialog: parent is NULL!"); } parent = parent->getParent(); if (parent == NULL) { throw FWException("clusterMembersDialog: parent is NULL!"); } host_os = parent->getStr("host_OS").c_str(); platform = parent->getStr("platform").c_str(); } string type = obj->getStr("type"); enable_master_column = Resources::os_res[host_os.toStdString()]->getResourceBool( "/FWBuilderResources/Target/protocols/" + type + "/needs_master"); if (!enable_master_column) m_dialog->fwSelectedTable->hideColumn(2); // prepare lists of firewalls (selected, available) getSelectedMembers(); getPossibleMembers(); // init views updateAvailableTree(); updateSelectedTable(); } clusterMembersDialog::~clusterMembersDialog() { // clear member lists for (t_memberList::iterator it = available.begin(); it != available.end(); it++) { delete *it; } available.clear(); for (t_memberList::iterator it = selected.begin(); it != selected.end(); it++) { delete *it; } selected.clear(); delete m_dialog; } void clusterMembersDialog::getSelectedMembers() { // read in master interface id std::string master_iface = obj->getStr("master_iface"); for (FWObjectTypedChildIterator it = obj->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { // get fw and interface pointer from interface reference Interface *iface = NULL; iface = Interface::cast(FWReference::cast((*it))->getPointer()); assert(iface != NULL); Firewall *fw = Firewall::cast(Host::getParentHost(iface)); //Firewall *fw = Firewall::cast(iface->getParentHost()); // determine master std::string iface_id = FWObjectDatabase::getStringId(iface->getId()); bool master = false; if (iface_id == master_iface) { master = true; } // create ClusterMember object ClusterMember *new_member = createMember(fw, iface, master); if (new_member == NULL) { qWarning() << "clusterMembersDialog: could not create new " "cluster member"; return; } // attach to selected list selected.push_back(new_member); } } void clusterMembersDialog::getPossibleMembers() { t_fwList fwlist; mw->findAllFirewalls(fwlist); Firewall *fw; for (t_fwList::iterator it = fwlist.begin(); it != fwlist.end(); it++) { // does host_OS and platform match? fw = *it; if (fw->getStr("host_OS").c_str() != host_os || fw->getStr("platform").c_str() != platform) { continue; } // does the firewall provide at least one phys. interface? FWObjectTypedChildIterator iface_i = fw->findByType(Interface::TYPENAME); if (iface_i == iface_i.end()) { continue; } else { // previously selected? skip PredFindFw pred; pred.setSearchString(fw->getName().c_str()); t_memberList::iterator it = find_if(selected.begin(), selected.end(), pred); if (it != selected.end()) { continue; } // valid member, add to member list ClusterMember *new_member = createMember(fw); if (new_member == NULL) { qWarning() << "clusterMembersDialog: could not create new " "cluster member"; return; } available.push_back(new_member); } } fwlist.sort(FWObjectNameCmpPredicate()); } void clusterMembersDialog::updateSelectedTable() { table_update = true; m_dialog->fwSelectedTable->setRowCount(selected.size()); QTableWidgetItem *item = NULL; int row = 0; for (t_memberList::const_iterator it = selected.begin(); it != selected.end(); it++) { // only insert new QTableWidgetItems if none has been set, update text // if selected member text changed. item = m_dialog->fwSelectedTable->item(row, 0); const char *new_text = (*it)->fwobj->getName().c_str(); if (item == NULL) { item = new QTableWidgetItem; item->setText(new_text); item->setIcon(QIcon(getIcon((*it)->fwobj))); m_dialog->fwSelectedTable->setItem(row, 0, item); } else if (item->text() != new_text) { item->setText(new_text); } // Column "Interface" item = m_dialog->fwSelectedTable->item(row, 1); new_text = (*it)->iface_cluster->getName().c_str(); if (item == NULL) { item = new QTableWidgetItem; item->setText(new_text); item->setIcon(QIcon(getIcon((*it)->iface_cluster))); m_dialog->fwSelectedTable->setItem(row, 1, item); } else if (item->text() != new_text) { item->setText(new_text); } // Column "Master" item = m_dialog->fwSelectedTable->item(row, 2); Qt::CheckState state = (*it)->is_master ? Qt::Checked : Qt::Unchecked; if (item == NULL) { item = new QTableWidgetItem; item->setCheckState(state); m_dialog->fwSelectedTable->setItem(row, 2, item); } else if (item->checkState() != state) { item->setCheckState(state); } row++; } m_dialog->fwSelectedTable->resizeColumnsToContents(); m_dialog->fwSelectedTable->horizontalHeader()->setStretchLastSection(true); table_update = false; } void clusterMembersDialog::updateAvailableTree() { QTreeWidgetItem *fwitem; m_dialog->fwAvailableTree->clear(); for (t_memberList::const_iterator it = available.begin(); it != available.end(); it++) { ClusterMember *member = *it; fwitem = new QTreeWidgetItem; fwitem->setFlags(Qt::ItemIsEnabled); fwitem->setText(0, member->fwobj->getName().c_str()); fwitem->setIcon(0, QIcon(getIcon(member->fwobj))); // add interfaces for (t_ifaceList::const_iterator it = member->iface_list.begin(); it != member->iface_list.end(); it ++) { QTreeWidgetItem *ifitem; ifitem = new QTreeWidgetItem(fwitem); ifitem->setText(1, (*it)->getName().c_str()); ifitem->setIcon(1, QIcon(getIcon(*it))); // add label (if non empty) string label = (*it)->getLabel(); if (!label.empty()) { ifitem->setText(2, label.c_str()); } } m_dialog->fwAvailableTree->insertTopLevelItem(0, fwitem); } m_dialog->fwAvailableTree->resizeColumnToContents(0); m_dialog->fwAvailableTree->sortByColumn(0, Qt::AscendingOrder); m_dialog->fwAvailableTree->expandAll(); } ClusterMember* clusterMembersDialog::createMember(Firewall *fw, Interface *cluster_iface, bool master) { if (fw == NULL) { return NULL; } ClusterMember *new_member = new ClusterMember; new_member->fwobj = fw; new_member->is_master = master; if (cluster_iface != NULL) { new_member->iface_cluster = cluster_iface; } list interfaces = fw->getByTypeDeep(Interface::TYPENAME); interfaces.sort(FWObjectNameCmpPredicate()); list::iterator iface_i; for (iface_i=interfaces.begin(); iface_i != interfaces.end(); ++iface_i) { Interface *iface = Interface::cast(*iface_i); new_member->iface_list.push_back(iface); // init interface mapping table new_member->iface_map[iface->getName().c_str()] = iface; } return new_member; } bool clusterMembersDialog::swap(t_memberList &from, t_memberList &to, const QString fwname, const QString iface, bool master) { // move selected fw from 'from' to 'to' member list PredFindFw pred; pred.setSearchString(fwname); t_memberList::iterator it = find_if(from.begin(), from.end(), pred); if (it == from.end()) { // not found return false; } ClusterMember *member = *it; from.erase(it); member->iface_cluster = member->iface_map[iface]; member->is_master = master; to.push_back(member); return true; } void clusterMembersDialog::setMaster(QString fw, bool checked) { for (t_memberList::const_iterator it = selected.begin(); it != selected.end(); it++) { if (QString((*it)->fwobj->getName().c_str()) == fw) { (*it)->is_master = checked; } else { (*it)->is_master = false; } } updateSelectedTable(); } QPixmap clusterMembersDialog::getIcon(FWObject *o) { QString icn_file = (":/Icons/" + o->getTypeName() + "/icon").c_str(); QPixmap pm; if (!QPixmapCache::find(icn_file, pm)) { pm.load(icn_file); QPixmapCache::insert(icn_file, pm); } return pm; } void clusterMembersDialog::invalidate() { // update views updateAvailableTree(); updateSelectedTable(); // disable <--> buttons, user needs to re-select m_dialog->buttonAdd->setEnabled(false); m_dialog->buttonRemove->setEnabled(false); } void clusterMembersDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); FWObject* new_state = cmd->getNewState(); bool master_found = false; t_memberList::const_iterator it = selected.begin(); // remoive all existing references and add new ones list all_refs = new_state->getByType(FWObjectReference::TYPENAME); for (list::iterator it=all_refs.begin(); it!=all_refs.end(); ++it) new_state->remove(*it); // add selected interfaces as objref to cluster member group for (it = selected.begin(); it != selected.end(); it++) { new_state->addRef((*it)->iface_cluster); // set master interface ref id if ((*it)->is_master) { master_found = true; std::string masteriface_id = FWObjectDatabase::getStringId((*it)->iface_cluster->getId()); new_state->setStr("master_iface", masteriface_id); } } if (!master_found) { new_state->remStr("master_iface"); } emit membersChanged(); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void clusterMembersDialog::reject() { QDialog::reject(); } void clusterMembersDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Cluster-Member Management"); h->setSource(QUrl("clusterMembersDialog.html#" + anchor)); h->raise(); h->show(); } void clusterMembersDialog::availableClicked(QTreeWidgetItem *item, int) { // activate addButton if a specific interface has been selected if (item->text(1).isEmpty()) { m_dialog->buttonAdd->setEnabled(false); } else if (!m_dialog->buttonAdd->isEnabled()) { m_dialog->buttonAdd->setEnabled(true); } } void clusterMembersDialog::selectedClicked(int row, int column) { if (fwbdebug) { qDebug() << "clusterMembersDialog: selected (" << row << ", " << column << ")"; } // activate removeButton if (!m_dialog->buttonRemove->isEnabled()) { m_dialog->buttonRemove->setEnabled(true); } } void clusterMembersDialog::masterSelected(int row, int column) { if (!table_update) { if (fwbdebug) { qDebug() << "clusterMembersDialog: master is (" << row << ", " << column << ")"; } QList itemlist; itemlist = m_dialog->fwSelectedTable->selectedItems(); if (itemlist[2]->checkState() == Qt::Checked) { setMaster(itemlist[0]->text()); } else { setMaster(itemlist[0]->text(), false); } } } void clusterMembersDialog::firewallAdd() { // get selected firewall / interface QList itemlist; itemlist = m_dialog->fwAvailableTree->selectedItems(); // interface should not be empty if (itemlist[0]->text(1).isEmpty()) { qWarning() << "clusterMembersDialog: iface is empty, not adding"; return; } foreach(QTreeWidgetItem *itm, itemlist) { // move selected fw to selected member list QString fwname = itm->parent()->text(0); QString iface_cluster = itm->text(1); if (!swap(available, selected, fwname, iface_cluster)) { // swap failed, this should not happen! qWarning() << "clusterMembersDialog: swap failed for firewall " << fwname << ", interface: " << iface_cluster; return; } } // invalidate view invalidate(); } void clusterMembersDialog::firewallRemove() { // get selected firewall / interface QList itemlist; itemlist = m_dialog->fwSelectedTable->selectedItems(); // move selected fw to available member list QString fwname = itemlist[0]->text(); if (!swap(selected, available, fwname, "", false)) { // swap failed, this should not happen! qWarning() << "clusterMembersDialog: swap failed for firewall " << fwname; return; } // invalidate view invalidate(); } fwbuilder-5.1.0.3599/src/libgui/asklibforcopydialog_q.ui0000644000175000017500000000355411733011756023755 0ustar sylvestresylvestre asklibforcopydialog_q 0 0 221 127 Copying Object will be copied to library: 0 0 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok buttonBox accepted() asklibforcopydialog_q accept() 248 254 157 274 buttonBox rejected() asklibforcopydialog_q reject() 316 260 286 274 fwbuilder-5.1.0.3599/src/libgui/TagServiceDialog.cpp0000644000175000017500000000623711733011756022730 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "TagServiceDialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; TagServiceDialog::~TagServiceDialog() { delete m_dialog; } TagServiceDialog::TagServiceDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::TagServiceDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } void TagServiceDialog::loadFWObject(FWObject *o) { obj=o; TagService *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->tagcode->setText( s->getCode().c_str() ); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->tagcode->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->tagcode); init=false; } void TagServiceDialog::validate(bool *res) { *res=true; TagService *s = dynamic_cast(obj); assert(s!=NULL); if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void TagServiceDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); TagService *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); s->setCode( m_dialog->tagcode->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/ObjectListView.cpp0000644000175000017500000001500011733011756022435 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "FWBTree.h" #include "ProjectPanel.h" #include "ObjectListView.h" #include "ObjectListViewItem.h" #include "FWObjectDrag.h" #include "FWBSettings.h" #include "FWObjectPropertiesFactory.h" #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; /**************************************************************************** * * class ObjectListView * ****************************************************************************/ ObjectListView::ObjectListView(QWidget* parent, const char*, Qt::WindowFlags f) : QTreeWidget(parent) { db = NULL; setWindowFlags(f); /*setColumnWidthMode(0, QTreeWidget::Maximum); setColumnWidthMode(1, QTreeWidget::Maximum); setItemMargin( 2 );*/ setFocusPolicy( Qt::StrongFocus ); setFocus(); header()->setClickable(true); header()->setMovable(false); setSortingEnabled(true); sortByColumn ( 0, Qt::AscendingOrder ); connect(header(), SIGNAL(sectionClicked (int)), this, SLOT(sectionClicked (int))); } bool ObjectListView::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = (QHelpEvent*) event; QPoint pos = he->pos(); if (st->getObjTooltips()) { int cx = pos.x(), cy = pos.y(); //viewportToContents(pos.x(),pos.y(),cx,cy); FWObject *obj=NULL; QRect cr; QTreeWidgetItem *itm = itemAt(QPoint(cx,cy - header()->height())); if (itm==NULL) return false; int obj_id = itm->data(0, Qt::UserRole).toInt(); obj = db->findInIndex(obj_id); if (obj==NULL) return false; cr = visualItemRect(itm); QRect global = QRect( viewport()->mapToGlobal(cr.topLeft()), viewport()->mapToGlobal(cr.bottomRight())); //finally stretch rect up to component's width and even more //(it fixes bug with horizontal scroll) global.setWidth(width() + horizontalOffset()); QToolTip::showText(mapToGlobal( he->pos() ), FWObjectPropertiesFactory::getObjectPropertiesDetailed(obj, true, true), this, global); } return true; } return QTreeWidget::event(event); } QDrag* ObjectListView::dragObject() { QTreeWidgetItem *ovi = currentItem(); // currentItem returns NULL if the list is empty if (ovi==NULL) return NULL; int obj_id = ovi->data(0, Qt::UserRole).toInt(); FWObject *obj = db->findInIndex(obj_id); QString icn = (":/Icons/"+obj->getTypeName()+"/icon-ref").c_str(); //Resources::global_res->getObjResourceStr(obj, "icon-ref").c_str(); list dragobj; dragobj.push_back(obj); FWObjectDrag *drag = new FWObjectDrag(dragobj, this); //QPixmap pm = QPixmap::fromMimeSource( icn_filename ); QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } drag->setPixmap( pm ); drag->setHotSpot( QPoint( pm.rect().width() / 2, pm.rect().height() / 2 ) ); return drag; } void ObjectListView::dragMoveEvent( QDragMoveEvent *ev) { if (fwbdebug) qDebug("ObjectListView::dragMoveEvent"); ev->setAccepted( ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); } void ObjectListView::dragEnterEvent( QDragEnterEvent *ev) { if (fwbdebug) qDebug("ObjectListView::dragEnterEvent"); //ev->setAccepted( ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); QWidget *fromWidget = ev->source(); // The source of DnD object must be the same instance of fwbuilder if (!fromWidget) { ev->setAccepted(false); return; } if (!ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE)) { ev->setAccepted(false); return; } list dragol; if (!FWObjectDrag::decode(ev, dragol)) ev->setAccepted(false); for (list::iterator i=dragol.begin();i!=dragol.end(); ++i) { FWObject *dragobj = *i; assert(dragobj!=NULL); if (FWBTree().isSystem(dragobj)) { // can not drop system folder anywhere ev->setAccepted(false); return; } // see #1976 do not allow pasting object that has been deleted if (dragobj->getLibrary()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) { ev->setAccepted(false); return; } } ev->setAccepted(true); } void ObjectListView::dropEvent(QDropEvent *ev) { if (fwbdebug) qDebug("ObjectListView::dropEvent"); emit dropped(ev); } void ObjectListView::keyPressEvent(QKeyEvent *ev) { if (ev->key()==Qt::Key_Delete) { emit delObject_sign(); } QTreeWidget::keyPressEvent(ev); } void ObjectListView::mousePressEvent(QMouseEvent *event) { startingDrag = true; QTreeWidget::mousePressEvent(event); } void ObjectListView::mouseMoveEvent(QMouseEvent *event) { if (startingDrag) { QDrag *dr = dragObject(); if (dr) dr->start(); startingDrag = false; } QTreeWidget::mouseMoveEvent(event); } void ObjectListView::sectionClicked ( int logicalIndex ) { sortByColumn ( logicalIndex, Qt::AscendingOrder ); } fwbuilder-5.1.0.3599/src/libgui/ClusterDialog.h0000644000175000017500000000265711733011756021764 0ustar sylvestresylvestre/* * ClusterDialog.h - Cluster object view * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __CLUSTERDIALOG_H_ #define __CLUSTERDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "utils.h" #include "fwbuilder/FWObject.h" class ProjectPanel; class ClusterDialog : public BaseObjectDialog { Q_OBJECT; Ui::ClusterDialog_q *m_dialog; void resetSingleClusterGroupType(libfwbuilder::FWObject *grp, std::list &allowed_types); void resetClusterGroupTypes(); void updateTimeStamps(); public: ClusterDialog(QWidget *parent); ~ClusterDialog(); private: /** flag to indicate host os, platform changes */ bool config_changed; public slots: virtual void applyChanges(); virtual void platformChanged(); virtual void hostOSChanged(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif /* __CLUSTERDIALOG_H_ */ fwbuilder-5.1.0.3599/src/libgui/pixfailoveroptionsdialog_q.ui0000644000175000017500000001127111733011756025045 0ustar sylvestresylvestre pixFailoverOptionsDialog_q 0 0 319 376 PIX failover protocol settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 PIX Failover Protocol Parameters :/Icons/Options:/Icons/Options Qt::Vertical QSizePolicy::Minimum 20 20 true PIX Failover Key Qt::LeftToRight Key: true Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() pixFailoverOptionsDialog_q accept() 316 472 193 137 buttonCancel clicked() pixFailoverOptionsDialog_q reject() 397 472 20 20 fwbuilder-5.1.0.3599/src/libgui/FindObjectWidget.cpp0000644000175000017500000005657011733011756022734 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "FindObjectWidget.h" #include "FWWindow.h" #include "FWObjectDropArea.h" #include "FWBTree.h" #include "FWBSettings.h" #include "ObjectTreeView.h" #include "RuleSetView.h" #include "ObjectEditor.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "events.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/MultiAddress.h" #include "fwbuilder/Interface.h" #include "fwbuilder/AddressRange.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; #define MAX_SEARCH_ITEMS_COUNT 10 class FindAndReplaceError : public FWException { public: FindAndReplaceError(const string &err) : FWException(err) {} }; FindObjectWidget::FindObjectWidget(QWidget*p, ProjectPanel *pp, const char * n, Qt::WindowFlags f) : QWidget(p,f) { project_panel = pp; m_widget = new Ui::findObjectWidget_q; m_widget->setupUi(this); setObjectName(n); replaceDisable(); m_widget->srScope->setCurrentIndex( st->getInt(SETTINGS_PATH_PREFIX"/Search/Scope")); m_widget->findDropArea->setHelperText( tr("Drop object you want to find here")); m_widget->replaceDropArea->setHelperText( tr("Drop object to replace with here")); connect(m_widget->findDropArea, SIGNAL(objectDeleted()), this, SLOT(objectDeleted())); } void FindObjectWidget::keyPressEvent( QKeyEvent* ev ) { if (ev->key()==Qt::Key_Enter || ev->key()==Qt::Key_Return) { if (fwbdebug) qDebug() << "FindObjectWidget::keyPressEvent Qt::Key_Enter"; ev->accept(); find(); return; } } void FindObjectWidget::findObject(FWObject *o) { if (fwbdebug) qDebug("FindObjectWidget::findObject"); show(); m_widget->findDropArea->insertObject(o); } void FindObjectWidget::enableAll() { m_widget->useRegexp->setEnabled (true); m_widget->findAttr->setEnabled (true); m_widget->attribute->setEnabled (true); } void FindObjectWidget::disableAll() { m_widget->useRegexp->setEnabled (false); m_widget->findAttr->setEnabled (false); m_widget->attribute->setEnabled (false); } void FindObjectWidget::objectInserted() { FWObject *o = m_widget->findDropArea->getObject(); if (o == NULL) return; // disableAll(); // see #1757 QString n = QString::fromUtf8(o->getName().c_str()); m_widget->findAttr->blockSignals(true); if (m_widget->findAttr->count()>=MAX_SEARCH_ITEMS_COUNT) m_widget->findAttr->removeItem(MAX_SEARCH_ITEMS_COUNT-1); m_widget->findAttr->lineEdit()->setText(n); m_widget->findAttr->blockSignals(false); reset(); } void FindObjectWidget::reset() { lastFound = NULL; lastAttrSearch = ""; found_objects.clear(); } void FindObjectWidget::clear() { m_widget->findDropArea->deleteObject(); m_widget->replaceDropArea->deleteObject(); lastFound = NULL; lastAttrSearch = ""; found_objects.clear(); } /** * This slot is called when user deletes an object from the "find" * drop area. See #1785 */ void FindObjectWidget::objectDeleted() { m_widget->findAttr->blockSignals(true); m_widget->findAttr->lineEdit()->setText(""); m_widget->findAttr->blockSignals(false); } /** * This slot is called when @attribute or @findAttr fields change * (that is, whenever user changes attribute they want to match or type * in the input field to change the value) */ void FindObjectWidget::findAttrChanged(const QString &ns) { if (ns!=lastAttrSearch) reset(); lastAttrSearch = ns; m_widget->findDropArea->blockSignals(true); m_widget->findDropArea->deleteObject(); // for #1757 m_widget->findDropArea->blockSignals(false); } void FindObjectWidget::find() { if (m_widget->findAttr->currentText().isEmpty() && m_widget->findDropArea->isEmpty()) return; if (m_widget->findAttr->currentText() != m_widget->findAttr->itemText(0)) { if (m_widget->findAttr->count()>=MAX_SEARCH_ITEMS_COUNT) m_widget->findAttr->removeItem(MAX_SEARCH_ITEMS_COUNT-1); m_widget->findAttr->insertItem(0, m_widget->findAttr->lineEdit()->text()); if (fwbdebug) qDebug("FindObjectWidget::find() : m_widget->findAttr->text(0)=%s", m_widget->findAttr->itemText(0).toLatin1().constData()); } findNext(); } bool FindObjectWidget::matchID(int id) { if (m_widget->findDropArea->isEmpty()) return true; int s_id = m_widget->findDropArea->getObject()->getId(); return s_id==id; } bool FindObjectWidget::matchAttr(FWObject *obj) { if (!m_widget->findDropArea->isEmpty()) return true; QString s = m_widget->findAttr->currentText(); if (s.isEmpty()) return true; bool res = false; int attrN = m_widget->attribute->currentIndex(); switch (attrN) { case 0: // Name or label { QString name = QString::fromUtf8( obj->getName().c_str() ); QString label; if (Interface::isA(obj)) label = QString::fromUtf8( Interface::cast(obj)->getLabel().c_str() ); if (m_widget->useRegexp->isChecked()) { res = (name.indexOf( QRegExp(s) )!=-1 || (!label.isEmpty() && label.indexOf( QRegExp(s) )!=-1)); } else { res = (name == s || (!label.isEmpty() && label == s)); } //res= ( name == s ); break; } case 1: // Address { if ( ! m_widget->useRegexp->isChecked()) { AddressRange *ar = AddressRange::cast(obj); if (ar) { const InetAddr &inet_addr_start = ar->getRangeStart(); const InetAddr &inet_addr_end = ar->getRangeEnd(); // if address entered by the user has /NN perfix length or // /255.255.255.0 netmask, do not match it to address ranges if ( ! s.contains("/")) { int af = AF_INET; if (s.contains(':')) af = AF_INET6; InetAddr addr = InetAddr(af, s.toStdString()); res = (inet_addr_start == addr || inet_addr_end == addr || (inet_addr_start < addr && addr < inet_addr_end)); break; } } } Address *a = Address::cast(obj); if (a!=NULL) { const InetAddr *inet_addr = a->getAddressPtr(); if (inet_addr) { QString addr = inet_addr->toString().c_str(); if (m_widget->useRegexp->isChecked()) res = ( addr.indexOf( QRegExp(s) )!=-1 ); else res= ( addr == s ); } //res= ( addr == s ); } break; } case 2: // port if (TCPService::cast(obj)!=NULL || UDPService::cast(obj)!=NULL) { if (m_widget->useRegexp->isChecked()) { QString port; port.setNum(TCPUDPService::cast(obj)->getSrcRangeStart()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); port.setNum(TCPUDPService::cast(obj)->getSrcRangeEnd()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); port.setNum(TCPUDPService::cast(obj)->getDstRangeStart()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); port.setNum(TCPUDPService::cast(obj)->getDstRangeEnd()); res |= ( port.indexOf( QRegExp(s) )!=-1 ); } else { bool conversion_status = false; int port = s.toInt(&conversion_status); res |= (conversion_status && (port == TCPUDPService::cast(obj)->getSrcRangeStart())); res |= (conversion_status && (port == TCPUDPService::cast(obj)->getSrcRangeEnd())); res |= (conversion_status && (port == TCPUDPService::cast(obj)->getDstRangeStart())); res |= (conversion_status && (port == TCPUDPService::cast(obj)->getDstRangeEnd())); } break; } break; case 3: // protocol num. if (IPService::cast(obj)!=NULL) { if (m_widget->useRegexp->isChecked()) { QString proto; proto.setNum(obj->getInt("protocol_num")); res |= ( proto.indexOf( QRegExp(s) )!=-1 ); } else { bool conversion_status = false; int proto = s.toInt(&conversion_status); res |= (conversion_status && (proto == obj->getInt("protocol_num"))); } break; } break; case 4: // icmp type if (ICMPService::cast(obj)!=NULL) { if (m_widget->useRegexp->isChecked()) { QString icmptype; icmptype.setNum(obj->getInt("type")); res |= ( icmptype.indexOf( QRegExp(s) )!=-1 ); } else { bool conversion_status = false; int icmptype = s.toInt(&conversion_status); res |= (conversion_status && (icmptype == obj->getInt("type"))); } break; } break; } return res; } /* * Walks the whole tree and fills found_objects list */ void FindObjectWidget::_findAll() { treeSeeker = project_panel->db()->tree_begin(); for (; treeSeeker != project_panel->db()->tree_end(); ++treeSeeker) { FWObject *o = *treeSeeker; if( RuleElement::cast(o->getParent())!=NULL) { if (m_widget->srScope->currentIndex()==3) // scope == selected firewalls { if ( !inSelectedFirewall(RuleElement::cast(o->getParent())) ) { continue; } } else if (m_widget->srScope->currentIndex()==0) continue ; // scope == tree only } else { /* if not in rules, then in the tree. */ if (m_widget->srScope->currentIndex()>1) continue; // scope in (firewalls only , selected firewalls) } FWObject *obj = o; if (FWReference::cast(o)!=NULL) { FWReference *r = FWReference::cast(o); obj = r->getPointer(); } if (matchAttr(obj) && matchID(obj->getId())) { // If object we have found belongs to the deleted objects lib // but this library is hidden, don't show it. if (obj->getLibrary()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID && !st->getBool("UI/ShowDeletedObjects")) continue; // Note that if o is a reference, we should add reference // to found_objects found_objects.push_back(o); } } } /* * Group::duplicateForUndo(), which is used in FWCmdChange::redo() and * undo() breaks FWObject::tree_iterator because it adds or removes * objects to groups. To work around this problem, we fill list * found_objects on the first call to findNext() and then just iterate * over items in this list later. */ void FindObjectWidget::findNext() { if (fwbdebug) qDebug("FindObjectWidget::findNext"); if ( m_widget->findAttr->currentText().isEmpty() && m_widget->findDropArea->isEmpty()) return; if (m_widget->findAttr->count()>MAX_SEARCH_ITEMS_COUNT) m_widget->findAttr->removeItem(0); FWObject *o = NULL; // if scope is "policies of opened firewall" then we need to get // pointer to the currently opened firewall object RuleSet* current_rule_set = project_panel->getCurrentRuleSet(); if (current_rule_set) selectedFirewall = Firewall::cast(current_rule_set->getParent()); else selectedFirewall = NULL; if (fwbdebug) qDebug() << "selectedFirewall: " << selectedFirewall; loop: if (found_objects.size() == 0) { QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); _findAll(); QApplication::restoreOverrideCursor(); found_objects_iter = found_objects.begin(); } if (found_objects_iter == found_objects.end()) { reset(); if (m_widget->srScope->currentIndex()==3) // scope ==selected firewalls { if ( QMessageBox::warning( this,"Firewall Builder", tr("Search hit the end of the policy rules."), tr("&Continue at top"), tr("&Stop"), QString::null, 0, 1 )==0 ) goto loop; } else { if (fwbdebug) qDebug("widget that has focus: %p",mw->focusWidget()); bool r= ( QMessageBox::warning( this,"Firewall Builder", tr("Search hit the end of the object tree."), tr("&Continue at top"), tr("&Stop"), QString::null, 0, 1 )==0); if (fwbdebug) qDebug("widget that has focus: %p",mw->focusWidget()); if (r) goto loop; } return; } o = *found_objects_iter; ++found_objects_iter; assert(o!=NULL); lastFound = o; if (fwbdebug) { qDebug() << "Found object: o=" << o << "id=" << FWObjectDatabase::getStringId(o->getId()).c_str() << "name=" << o->getName().c_str() << "type=" << o->getTypeName().c_str(); } showObject(o); } bool FindObjectWidget::validateReplaceObject() { if (m_widget->findDropArea->isEmpty()) { QMessageBox::warning( this, "Firewall Builder", tr("Search object is missing.")); return false; } if (m_widget->replaceDropArea->isEmpty()) { QMessageBox::warning( this, "Firewall Builder", tr("Replace object is missing.")); return false; } FWObject* findObj = m_widget->findDropArea->getObject(); FWObject* replObj = m_widget->replaceDropArea->getObject(); if (findObj==replObj || findObj->getId() == replObj->getId()) { QMessageBox::warning( this,"Firewall Builder", tr("Cannot replace object with itself.")); return false; } bool obj_1_address = Address::cast(findObj)!=NULL || MultiAddress::cast(findObj)!=NULL || ObjectGroup::cast(findObj)!=NULL; bool obj_2_address = Address::cast(replObj)!=NULL || MultiAddress::cast(replObj)!=NULL || ObjectGroup::cast(replObj)!=NULL; bool obj_1_service = Service::cast(findObj)!=NULL || ServiceGroup::cast(findObj); bool obj_2_service = Service::cast(replObj)!=NULL || ServiceGroup::cast(replObj); if ((obj_1_address && obj_2_address) || (obj_1_service && obj_2_service)) return true; QMessageBox::warning( this,"Firewall Builder", tr("Search and Replace objects are incompatible.")); return false; } void FindObjectWidget::replace() { if (!validateReplaceObject()) return; if (lastFound==NULL) { find(); return; } if (lastFound->isReadOnly()) { QMessageBox::critical(this, "Firewall Builder", tr("Can not modify read-only object %1") .arg(lastFound->getPath().c_str())); return; } _replaceCurrent(); } void FindObjectWidget::replaceAll() { if (!validateReplaceObject()) return; reset(); /* * replaceAll() may potentially make many replacements. Check read-only * condition early if possible to avoid popping many error dialogs. */ if (m_widget->srScope->currentIndex()==3) // scope == selected firewalls { RuleSet* current_rule_set = project_panel->getCurrentRuleSet(); if (current_rule_set) selectedFirewall = Firewall::cast(current_rule_set->getParent()); else selectedFirewall = NULL; if (selectedFirewall == NULL) { QMessageBox::critical(this, "Firewall Builder", tr("Please select a firewall object")); return; } if (selectedFirewall->isReadOnly()) { QMessageBox::critical(this, "Firewall Builder", tr("Can not modify read-only object %1") .arg(selectedFirewall->getPath().c_str())); return; } } findNext(); // fill found_objects and position to the first found one int count = 0; try { for (found_objects_iter=found_objects.begin(); found_objects_iter!=found_objects.end(); ++found_objects_iter) { lastFound = *found_objects_iter; _replaceCurrent(); count++; } } catch (FindAndReplaceError &ex) { } QMessageBox::information( this, "Firewall Builder", tr("Replaced %1 objects.").arg(count)); } void FindObjectWidget::_replaceCurrent() { FWObject *o = lastFound; FWObject *p = lastFound->getParent(); if (p==NULL || o==NULL) return; if (FWReference::cast(o)==NULL) return; if (p->isReadOnly()) { QMessageBox msg_box; msg_box.setWindowModality(Qt::ApplicationModal); msg_box.setWindowTitle("Find and Replace Error"); msg_box.setText(tr("Can not modify read-only object %1") .arg(p->getPath().c_str())); QPushButton *btn_continue = msg_box.addButton( QObject::tr("Continue"), QMessageBox::AcceptRole); QPushButton *btn_stop = msg_box.addButton( QObject::tr("Stop"), QMessageBox::RejectRole); msg_box.setDefaultButton(btn_stop); msg_box.show(); msg_box.raise(); msg_box.exec(); if (msg_box.clickedButton() == btn_stop) { // interrupt "replace all" operation throw FindAndReplaceError("Attempt to modify read-only object"); } return; } FWObject *replace_object = m_widget->replaceDropArea->getObject(); std::auto_ptr cmd( new FWCmdChange(project_panel, p, QObject::tr("Replace object"))); FWObject *new_state = cmd->getNewState(); new_state->removeRef(FWReference::cast(o)->getPointer()); // check for duplicates -------- if (RuleElement::cast(new_state)==NULL || !RuleElement::cast(new_state)->isAny()) { // avoid duplicates int cp_id = replace_object->getId(); FWObject *oo; FWReference *ref; list::iterator j; for(j=new_state->begin(); j!=new_state->end(); ++j) { oo = *j; if (cp_id==oo->getId() || ((ref=FWReference::cast(oo))!=NULL && cp_id==ref->getPointerId())) { // replacement object is already a member of this // group or rule element. Do not insert it again to // avoid duplicates. Also check if new_state is // different from old_state. It can be the same if // original object was not a member of the group so // the call to removeRef() above did nothing. This // happens when user hits Replace, then hits it // again without finding next. if (!cmd->getOldState()->cmp(new_state, true)) project_panel->undoStack->push(cmd.release()); return; } } } new_state->addRef(replace_object); if (!cmd->getOldState()->cmp(new_state, true)) project_panel->undoStack->push(cmd.release()); } bool FindObjectWidget::inSelectedFirewall( RuleElement* r) { FWObject *f=r; while (f!=NULL && Firewall::cast(f)==NULL) f=f->getParent(); if (f==NULL) return false; return selectedFirewall==(Firewall::cast(f)); } void FindObjectWidget::replaceEnable() { m_widget->replaceButton->setEnabled (true); m_widget->repNextButton->setEnabled (true); m_widget->replaceAllButton->setEnabled(true); } void FindObjectWidget::replaceDisable() { m_widget->replaceButton->setEnabled (false); m_widget->repNextButton->setEnabled (false); m_widget->replaceAllButton->setEnabled(false); } /** * Show object that we have found in the tree or in rules but retain focus * so that user can find next one by just hitting Return on the keyboard. */ void FindObjectWidget::showObject(FWObject* o) { if (fwbdebug) qDebug("FindObjectWidget::showObject o: %s parent: %s", o->getName().c_str(), o->getParent()->getName().c_str()); FWReference* ref = FWReference::cast(o); if (ref!=NULL && RuleElement::cast(o->getParent())!=NULL) { // found object in rules QCoreApplication::sendEvent( project_panel, new showObjectInRulesetEvent( project_panel->getFileName(), ref->getId())); return; } if (!FWBTree().isStandardFolder(o) && Group::cast(o->getParent())!=NULL && !FWBTree().isStandardFolder(o->getParent())) { QCoreApplication::sendEvent( mw, new showObjectInTreeEvent(project_panel->getFileName(), o->getParent()->getId())); return; } QCoreApplication::sendEvent( mw, new showObjectInTreeEvent(project_panel->getFileName(), o->getId())); } void FindObjectWidget::init() { m_widget->findDropArea->deleteObject(); m_widget->replaceDropArea->deleteObject(); } void FindObjectWidget::firewallOpened(Firewall *f) { if (f==NULL) return; selectedFirewall = f; m_widget->srScope->setItemText( 3, tr("Policy of firewall '")+f->getName().c_str()+"'" ); } void FindObjectWidget::findPrev() { } void FindObjectWidget::replaceNext() { replace(); findNext(); } void FindObjectWidget::scopeChanged() { st->setValue(SETTINGS_PATH_PREFIX"/Search/Scope", m_widget->srScope->currentIndex ()); } fwbuilder-5.1.0.3599/src/libgui/RuleSetModel.cpp0000644000175000017500000013646311733011756022125 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include #include #include #include #include #include #include #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Interface.h" #include "FWBSettings.h" #include "RuleSetModel.h" #include "FWObjectPropertiesFactory.h" using namespace libfwbuilder; using namespace std; //////////////////////////////////////////////////////////////////////// // RuleSetModelIterator //////////////////////////////////////////////////////////////////////// RuleSetModelIterator::RuleSetModelIterator() { row = 0; model = 0; } bool RuleSetModelIterator::isValid() { return model != 0 && row>=0 && model->rowCount(parent) > row; } bool RuleSetModelIterator::hasNext() { if (model->rowCount(parent) - 1 > row) return true; return (parent.isValid()) ? (model->rowCount() - 1 > parent.row()) : false; } bool RuleSetModelIterator::hasPrev() { if (row > 0) return true; return (parent.isValid()) ? (parent.row() > 0) : false; } RuleSetModelIterator& RuleSetModelIterator::operator= (const RuleSetModelIterator& it) { model = it.model; parent = it.parent; row = it.row; return *this; } RuleSetModelIterator& RuleSetModelIterator::operator++ () { QModelIndex index = this->index(); if (model->hasChildren(index)) { parent = index; row = 0; } else { row++; if (row >= model->rowCount(parent)) { if (parent.isValid()) { row = parent.row() + 1; parent = parent.parent(); } } } return *this; } RuleSetModelIterator& RuleSetModelIterator::operator-- () { row--; if (row < 0) { if (parent.isValid()) { row = parent.row(); parent = parent.parent(); } } else { QModelIndex index = this->index(); if (model->hasChildren(index)) { parent = index; row = model->rowCount(parent) - 1; } } return *this; } bool RuleSetModelIterator::operator== ( RuleSetModelIterator& it) { return (parent == it.parent) && (row == it.row); } bool RuleSetModelIterator::operator!= ( RuleSetModelIterator& it ) { return !this->operator==(it); } QModelIndex RuleSetModelIterator::index() { // qDebug() << "RuleSetModelIterator::index() row:" << row; return model->index(row, 0,parent); } //////////////////////////////////////////////////////////////////////// // RuleSetModel //////////////////////////////////////////////////////////////////////// RuleSetModel::RuleSetModel(RuleSet *ruleset, QObject *parent) : QAbstractItemModel(parent) { root = 0; this->ruleset = ruleset; initModel(); } void RuleSetModel::initModel() { //if (fwbdebug) qDebug() << "RuleSetModel::initModel"; if (root) delete root; root = new RuleNode(RuleNode::Root,"root"); int row = 1; QHash groups; RuleNode* node; RuleNode* group; QTime t; t.start(); for (FWObject::iterator i=ruleset->begin(); i!=ruleset->end(); i++, row++) { Rule *r = Rule::cast( *i ); if (r == NULL) continue; // skip RuleSetOptions // rulesByPosition[r->getPosition()] = r; node = new RuleNode(RuleNode::Rule, QString()); node->rule = r; if (r->getRuleGroupName().empty()) { root->add(node); } else { //Add rule to group QString groupName = QString::fromUtf8(r->getRuleGroupName().c_str()); if (!groups.contains(groupName)) { group = new RuleNode(RuleNode::Group, groupName); groups.insert(groupName, group); root->add(group); } else { group = groups.value(groupName); } group->add(node); } } //if (fwbdebug) qDebug("Model init: %d ms", t.elapsed()); } int RuleSetModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) return 0; RuleNode *parentNode = nodeFromIndex(parent); if (!parentNode) return 0; return parentNode->children.count(); } int RuleSetModel::columnCount(const QModelIndex &parent) const { Q_UNUSED (parent) return header.size()+1; } QVariant RuleSetModel::data(const QModelIndex &index, int role) const { switch (role) { case Qt::DisplayRole: return getDataForDisplayRole(index); case Qt::UserRole: return getColumnDesc(index); case Qt::DecorationRole: return getDecoration(index); default: return QVariant(); } } QVariant RuleSetModel::getDecoration(const QModelIndex &index) const { if (!index.isValid()) return QVariant(); if (index.column() != 0) return QVariant(); RuleNode *node = nodeFromIndex(index); if (!node || node->type != RuleNode::Rule) return QVariant(); if (node->rule && !node->rule->isDisabled()) return QVariant(); QVariant res; QString icn_file = ":/Icons/neg"; QPixmap pm; LoadPixmap(":/Icons/neg", pm); res.setValue( QIcon(pm) ); return res; } QVariant RuleSetModel::getColumnDesc(const QModelIndex &index) const { //if (fwbdebug) qDebug() << "RuleSetModel::getColumnDesc "<< index.column(); QVariant res; if (index.column()>0 && index.column()<=header.size()) { res.setValue(header.at(index.column()-1)); } return res; } QVariant RuleSetModel::getDataForDisplayRole(const QModelIndex &index) const { //if (fwbdebug) qDebug() << "RuleSetModel::getDataForDisplayRole"; RuleNode *node = nodeFromIndex(index); if (!node) return QVariant(); if (node->type == RuleNode::Group) { return getGroupDataForDisplayRole(index,node); } else if (node->type == RuleNode::Rule) { return getRuleDataForDisplayRole(index,node); } return QVariant(); } QVariant RuleSetModel::getGroupDataForDisplayRole(const QModelIndex &index, RuleNode* node) const { //if (fwbdebug) qDebug() << "RuleSetModel::getGroupDataForDisplayRole"; int first = node->children.first()->rule->getPosition(); int last = node->children.last()->rule->getPosition(); return (index.column() == 0)? QString("%1 (%2 - %3)") .arg(node->name) .arg(first) .arg(last) :QVariant(); } QVariant RuleSetModel::headerData(int section, Qt::Orientation orientation, int role) const { //if (fwbdebug) qDebug() << "RuleSetModel::headerData"; // too chatty if (orientation == Qt::Vertical) return QVariant(); if (role != Qt::DisplayRole) return QVariant(); if (section>0 && section <= header.size()) return header[section-1].name; return QVariant(); } Rule * RuleSetModel::findRuleForPosition(int position) const { for (FWObject::iterator i=ruleset->begin(); i!=ruleset->end(); i++) { Rule *r = Rule::cast( *i ); if (r == 0) { continue; } if (r->getPosition() == position) { return r; } } return 0; } Rule * RuleSetModel::getRule(QModelIndex index) const { if (!index.isValid()) return 0; RuleNode* node = nodeFromIndex(index); if (RuleNode::Rule != node->type) return 0; return node->rule; } QModelIndex RuleSetModel::indexForPosition(int position) const { Rule * res = findRuleForPosition(position); return (res == 0)?QModelIndex():index(res, 0); } QModelIndex RuleSetModel::index(int row, int column, const QModelIndex &parent) const { // if (fwbdebug) // qDebug() << "RuleSetModel::index(int row, int column, const QModelIndex &parent)" // << "row=" << row // << "column=" << column; if (row < 0 || column < 0) return QModelIndex(); RuleNode *parentNode = nodeFromIndex(parent); RuleNode *childNode = parentNode->children.value(row); if (!childNode) return QModelIndex(); return createIndex(row, column, childNode); } QModelIndex RuleSetModel::index(QString groupName) const { if (!groupName.isEmpty()) { int row = 0; foreach(RuleNode *node, root->children) { if (node->type == RuleNode::Group && node->name == groupName) { return createIndex(row, 0, node); } row++; } } return QModelIndex(); } QModelIndex RuleSetModel::index(int row, int column, QString groupName) const { // if (fwbdebug) // qDebug() << " RuleSetModel::index(int row, int column, QString groupName)"; QModelIndex parent = index(groupName); return (parent.isValid()) ? index(row, column, parent) : QModelIndex(); } QModelIndex RuleSetModel::index(Rule *rule, libfwbuilder::RuleElement *re) const { // if (fwbdebug) // qDebug() << "RuleSetModel::index(libfwbuilder::Rule *rule, int col)"; int col = columnForRuleElementType(re->getTypeName().c_str()); return index(rule, col); } QModelIndex RuleSetModel::index(Rule *rule, int col) const { // if (fwbdebug) // qDebug() << "RuleSetModel::index(libfwbuilder::Rule *rule, int col) " << col; if (col < 0 || rule == 0) return QModelIndex(); QModelIndex parent; QString groupName = QString::fromUtf8(rule->getRuleGroupName().c_str()); if (!groupName.isEmpty()) { QList topLevel = root->children; int row = 0; foreach (RuleNode * node, topLevel) { if (node->type == RuleNode::Group && node->name == groupName) { parent = createIndex(row, 0, node); break; } row++; } } RuleNode *parentNode = nodeFromIndex(parent); int row = 0; RuleNode* child = NULL; foreach(RuleNode *node, parentNode->children) { if (node->type == RuleNode::Rule && node->rule == rule) { child = node; break; } row++; } if (child == NULL) return QModelIndex(); return createIndex(row, col, child); } int RuleSetModel::columnForRuleElementType(QString typeName) const { // if (fwbdebug) // qDebug() << "RuleSetModel::columnForRuleElementType(QString typeName)"; int col = 1; foreach (ColDesc cd, header) { if (cd.origin == typeName) break; col++; } return col; } int RuleSetModel::columnByType(ColDesc::ColumnType type) { // if (fwbdebug) // qDebug() << "RuleSetModel::columnByType(ColDesc::ColumnType type)"; int col = 1; foreach (ColDesc cd, header) { if (cd.type == type) break; col++; } return col; } RuleNode* RuleSetModel::nodeFromIndex(const QModelIndex &index) const { if (index.isValid()) { return static_cast(index.internalPointer()); } else { return root; } } QModelIndex RuleSetModel::parent(const QModelIndex &child) const { RuleNode *node = nodeFromIndex(child); if (!node) return QModelIndex(); RuleNode *parentNode = node->parent; if (!parentNode) return QModelIndex(); RuleNode *grandparentNode = parentNode->parent; if (!grandparentNode) return QModelIndex(); int row = grandparentNode->children.indexOf(parentNode); return createIndex(row, 0, parentNode); } RuleElement * RuleSetModel::getRuleElementByRole(Rule* r, string roleName) const { return RuleElement::cast( r->getFirstByType(roleName) ); } bool RuleSetModel::isEmpty() { return root->children.size() == 0; } Firewall* RuleSetModel::getFirewall() const { FWObject *f=ruleset; while (f!=NULL && (!Firewall::isA(f) && !Cluster::isA(f))) f=f->getParent(); // f can be NULL if user is looking at deleted ruleset which is a child // of the library DeletedObjects return Firewall::cast(f); } void RuleSetModel::insertRuleToModel(Rule *rule, QModelIndex &index, bool isAfter) { QModelIndex parent = index.parent(); RuleNode *newNode = new RuleNode(RuleNode::Rule, QString()); newNode->rule = rule; if (index.isValid()) { RuleNode *node = nodeFromIndex(index); int idx = node->parent->children.indexOf(node); if (isAfter) idx++; emit beginInsertRows(parent, idx, idx); node->parent->children.insert(idx, newNode); newNode->parent = node->parent; emit endInsertRows(); } else { emit beginInsertRows(parent, 0, 0); root->children.prepend(newNode); newNode->parent = root; emit endInsertRows(); } QModelIndex newIndex = this->index(rule); rowChanged(newIndex); } Rule* RuleSetModel::insertNewRule() { Rule *newrule = getRuleSet()->insertRuleAtTop(); initRule(newrule); QModelIndex index; insertRuleToModel(newrule, index); return newrule; } Rule* RuleSetModel::insertNewRule(QModelIndex &index, bool isAfter) { if (!index.isValid()) return insertNewRule(); RuleNode *node = nodeFromIndex(index); int pos = node->rule->getPosition(); Rule *newrule = isAfter?ruleset->appendRuleAfter(pos):ruleset->insertRuleBefore(pos); initRule(newrule); string groupName = node->rule->getRuleGroupName(); newrule->setRuleGroupName(groupName); insertRuleToModel(newrule, index, isAfter); return newrule; } Rule* RuleSetModel::insertRule(Rule *rule, QModelIndex &index, bool isAfter) { Rule *newrule = 0; if (index.isValid()) { RuleNode *node = nodeFromIndex(index); int pos = node->rule->getPosition(); newrule = isAfter?ruleset->appendRuleAfter(pos):ruleset->insertRuleBefore(pos); initRule(newrule, rule); string groupName = node->rule->getRuleGroupName(); newrule->setRuleGroupName(groupName); insertRuleToModel(newrule, index, isAfter); } else { newrule = getRuleSet()->insertRuleAtTop(); initRule(newrule, rule); QModelIndex index; insertRuleToModel(newrule, index); } return newrule; } void RuleSetModel::insertRule(Rule *rule) { Rule * targetRule = ruleset->getRuleByNum(rule->getPosition()); if (targetRule==NULL) { ruleset->add(rule); if (isEmpty()) { QModelIndex index; insertRuleToModel(rule, index); } else { RuleSetModelIterator it = end(); --it; QModelIndex index = it.index(); insertRuleToModel(rule, index, true); } } else { QModelIndex index = this->index(targetRule); ruleset->insert_before(targetRule,rule); insertRuleToModel(rule, index, false); } ruleset->renumberRules(); } void RuleSetModel::restoreRule(Rule *) { } void RuleSetModel::restoreRules(QList rules, bool topLevel) { // qDebug() << "RuleSetModel::restoreRules(QList rules)"; int pos = rules.first()->getPosition()-1; int last = 0; Rule* pivotRule = 0; QModelIndex pivotIndex; //The very top rule should be inserted BEFORE others if (pos < 0) { Rule* rule = rules.first(); pivotRule = ruleset->getRuleByNum(0); ruleset->insert_before(pivotRule, rule); pivotIndex = index(pivotRule, 0); if (topLevel && pivotIndex.parent().isValid()) { pivotIndex = pivotIndex.parent(); } insertRuleToModel(rule, pivotIndex, false); pivotRule = rule; last++; } else { pivotRule = ruleset->getRuleByNum(pos); } pivotIndex = index(pivotRule, 0); // We need a toplevel index if (topLevel && pivotIndex.parent().isValid()) { pivotIndex = pivotIndex.parent(); } for (int i=rules.size()-1; i>=last; i--) { Rule* rule = rules.at(i); ruleset->insert_after(pivotRule, rule); insertRuleToModel(rule, pivotIndex, true); } ruleset->renumberRules(); } void RuleSetModel::removeRow(int row,const QModelIndex &parent) { removeRows(row,1,parent); } bool RuleSetModel::removeRows(int row, int count, const QModelIndex &parent) { //if (fwbdebug) qDebug() << "RuleSetModel::removeRows " << row << " , " << count ; if (count < 1 || row < 0 || (row + count > rowCount(parent))) return false; RuleNode *parentNode = nodeFromIndex(parent); int lastRow = row + count - 1; beginRemoveRows(parent,row,lastRow); for (int i = 0; ichildren.at(row); if (oldNode->type == RuleNode::Group || ruleset->deleteRule(oldNode->rule) ) { parentNode->children.removeAt(row); delete oldNode; } else { //TODO: May be we need some othe action in this case qWarning() << "Failed to remove rule"; break; } } endRemoveRows(); return true; } void RuleSetModel::moveRuleUp(const QModelIndex &group, int first, int last) { RuleNode *groupNode = nodeFromIndex(group); if (groupNode->isRoot()) { if (first == 0) return; if (root->children.at(first - 1)->type == RuleNode::Group) { addToGroupAbove(first, last); return; } } else { if (first == 0) { removeFromGroup(group, first, last); return; } } int pos = first - 1; QList list; removeToList(list, group, first, last); for(int i = 0; i< list.size(); i++) { ruleset->moveRuleUp(list.at(i)->rule->getPosition()); } insertFromList(list, group, pos); } void RuleSetModel::moveRuleDown(const QModelIndex &group, int first, int last) { RuleNode *groupNode = nodeFromIndex(group); int childrens = groupNode->children.size(); if (groupNode->isRoot()) { if (last == childrens - 1) return; if (root->children.at(last + 1)->type == RuleNode::Group) { addToGroupBelow(first, last); return; } } else { if (last == childrens - 1) { removeFromGroup(group, first, last); return; } } int pos = first + 1; QList list; removeToList(list, group, first, last); for(int i = list.size() - 1; i>=0 ; i--) { ruleset->moveRuleDown(list.at(i)->rule->getPosition()); } insertFromList(list, group, pos); } void RuleSetModel::removeToList(QList &list, const QModelIndex &group, int first, int last) { emit beginRemoveRows(group, first, last); int count = last - first + 1; RuleNode *parent = nodeFromIndex(group); for (int i=0; ichildren.at(first); parent->children.removeAt(first); } emit endRemoveRows(); } void RuleSetModel::insertFromList(const QList &list, const QModelIndex &group, int position) { int first = position; int last = position + list.size() - 1; emit beginInsertRows(group, first, last); RuleNode *parent = nodeFromIndex(group); for (int i=list.size()-1; i>=0; i--) { parent->children.insert(position, list.at(i)); } emit endInsertRows(); } bool RuleSetModel::isIndexRule(const QModelIndex index) { if (!index.isValid()) return false; RuleNode* node = static_cast(index.internalPointer()); if (node == 0) return false; return node->type == RuleNode::Rule; } void RuleSetModel::changeRuleColor(const QList &indexes, const QString &c) { QModelIndex i1 = index(indexes.first().row(), 0, indexes.first().parent()); QModelIndex i2 = index(indexes.last().row(), header.size() - 1, indexes.last().parent()); foreach(QModelIndex index, indexes) { if (!index.isValid()) return; RuleNode* node = nodeFromIndex(index); if (node->rule==0) return; FWOptions *ropt = node->rule->getOptionsObject(); ropt->setStr("color", c.toLatin1().constData()); } emit dataChanged(i1, i2); } void RuleSetModel::changeGroupColor(const QModelIndex index, const QString &c) { if (!index.isValid()) return; RuleNode* group = nodeFromIndex(index); if (group->type != RuleNode::Group) return; foreach (RuleNode* node, group->children) { if (node->rule==0) continue; FWOptions *ropt = node->rule->getOptionsObject(); ropt->setStr("color", c.toLatin1().constData()); } groupChanged(index); } void RuleSetModel::renameGroup(QModelIndex group, const QString &newName) { QString newGroupName = findUniqueNameForGroup(newName); RuleNode* groupNode = nodeFromIndex(group); //Set new group name for all children of this node. foreach (RuleNode* node, groupNode->children) { node->rule->setRuleGroupName(newGroupName.toUtf8().data()); } groupNode->name = newGroupName; rowChanged(group); } void RuleSetModel::rowChanged(const QModelIndex &index) { nodeFromIndex(index)->resetSizes(); emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), header.size()-1,index.internalPointer())); } void RuleSetModel::groupChanged(const QModelIndex &group) { RuleNode* groupNode = nodeFromIndex(group); QModelIndex i1 = index(0,0,group); QModelIndex i2 = index(groupNode->children.size() - 1, header.size()-1, group); emit dataChanged(i1, i2); } QString RuleSetModel::findUniqueNameForGroup(const QString &groupName) { int count = 0; bool exactNameExists = false; QRegExp rx("^(.*)-(\\d+)$"); foreach (RuleNode *node, root->children) { if (node->type != RuleNode::Group) continue; QString name = node->name; exactNameExists = exactNameExists || (name == groupName); if (rx.exactMatch(name)) { QString nameSection = rx.capturedTexts().at(1); QString countSection = rx.capturedTexts().at(2); int curCnt = countSection.toInt(); if (nameSection == groupName && curCnt>count) count = curCnt; } } QString uniqueGroupName = (exactNameExists)? groupName + "-" + QString::number(++count):groupName; //if (fwbdebug) qDebug() << "uniqueGroupName" << uniqueGroupName ; return uniqueGroupName; } QModelIndex RuleSetModel::createNewGroup(QString groupName, int first, int last) { //if (fwbdebug) qDebug() << "RuleSetModel::createNewGroup" << groupName << first << last; QString uniqueGroupName = findUniqueNameForGroup(groupName); RuleNode *group = new RuleNode(RuleNode::Group, uniqueGroupName); // remove selected rules emit beginRemoveRows(QModelIndex(), first, last); int count = last - first + 1; for(int i=0; ichildren.at(first); group->add(node); root->children.removeAt(first); node->rule->setRuleGroupName(uniqueGroupName.toUtf8().data()); } emit endRemoveRows(); // Add new group after the selected rules int groupPos = first; emit beginInsertRows(QModelIndex(), groupPos, groupPos); root->insert(groupPos, group); emit endInsertRows(); return index(groupPos, 0, QModelIndex()); } void RuleSetModel::removeFromGroup(QModelIndex group, int first, int last) { if (!group.isValid()) return; RuleNode *groupNode = nodeFromIndex(group); if (groupNode->type != RuleNode::Group) return; //if (fwbdebug) qDebug() << "RuleSetModel::removeFromGroup " << groupNode->name << first << "-" << last; /* if items touch bottom of the group or we are going to move all items from the group then we will insert them after the group node one level up, Else we will insert them before\ the group node. */ int count = last-first+1; bool moveAllItems = count == groupNode->children.size(); bool insertBefore = first == 0; int insertPosition = (insertBefore || moveAllItems)?group.row():(group.row()+1); // Remove nodes from the tree emit beginRemoveRows(group, first, last); QList moving; for(int i = first; i<= last; i++) { RuleNode *node = groupNode->children.at(first); node->rule->setRuleGroupName(""); moving << node;; groupNode->children.removeAt(first); } emit endRemoveRows(); QModelIndex rootIndex = group.parent(); // if all Items were moved from the group then group should be removed as well if (moveAllItems) { emit beginRemoveRows(rootIndex, group.row(), group.row()); root->children.removeAt(group.row()); delete groupNode; emit endRemoveRows(); } emit beginInsertRows(rootIndex, insertPosition, insertPosition + count -1); // Insert rows to calculated position. int pos = insertPosition; for(int i=0; iinsert(pos++,moving.at(i)); } emit endInsertRows(); } QString RuleSetModel::addToGroupAbove(int first, int last) { RuleNode *targetGroup = root->children.at(first - 1); moveToGroup(targetGroup, first, last); return targetGroup->name; } QString RuleSetModel::addToGroupBelow(int first, int last) { RuleNode *targetGroup = root->children.at(last + 1); moveToGroup(targetGroup, first, last, false); return targetGroup->name; } void RuleSetModel::moveToGroup(RuleNode *targetGroup, int first, int last, bool append) { //if (fwbdebug) qDebug() << "RuleSetModel::moveToGroup " << targetGroup->name << first << last << append; // Remove nodes from the tree QList rules; emit beginRemoveRows(QModelIndex(), first, last); int count = last - first + 1; for(int i=0; ichildren.at(first); rules << node; root->children.removeAt(first); node->rule->setRuleGroupName(targetGroup->name.toUtf8().data()); } emit endRemoveRows(); // Add rules to the group int row = (append)?first - 1:first; QModelIndex targetGroupIndex = createIndex(row, 0, targetGroup);; emit beginInsertRows(targetGroupIndex, (append)?targetGroup->children.size():0, (append)?(targetGroup->children.size()+count-1):(count-1) ); for(int i=0; iadd(rules.at(i)); else targetGroup->prepend(rules.at(count - i - 1)); } emit endInsertRows(); } void RuleSetModel::setEnabled(const QModelIndex &index, bool flag) { if (!index.isValid()) return; RuleNode *node = nodeFromIndex(index); if (node->type != RuleNode::Rule) return; //if (fwbdebug) qDebug() << "RuleSetModel::setEnabled " << index.row() << "->" << flag; if (flag) node->rule->enable(); else node->rule->disable(); rowChanged(index); } void RuleSetModel::deleteObject(QModelIndex &index, FWObject* obj) { RuleElement *re = (RuleElement *)index.data(Qt::DisplayRole).value(); if (re==NULL || re->isAny()) return; // int id = obj->getId(); // if (fwbdebug) // { // qDebug("RuleSetView::deleteObject row=%d col=%d id=%s", // index.row(), index.column(), FWObjectDatabase::getStringId(id).c_str()); // qDebug("obj = %p",re->getRoot()->findInIndex(id)); // int rc = obj->ref()-1; obj->unref(); // qDebug("obj->ref_counter=%d",rc); // } re->removeRef(obj); if (re->isAny()) re->setNeg(false); rowChanged(index); // if (fwbdebug) // { // qDebug("RuleSetView::deleteObject re->size()=%d", int(re->size())); // qDebug("obj = %p",re->getRoot()->findInIndex(id)); // int rc = obj->ref()-1; obj->unref(); // qDebug("obj->ref_counter=%d",rc); // } } bool RuleSetModel::insertObject(QModelIndex &index, FWObject *obj) { // if (fwbdebug) qDebug("RuleSetModel::insertObject -- insert object %s", // obj->getName().c_str()); ColDesc colDesc = index.data(Qt::UserRole).value(); if (colDesc.type != ColDesc::Object && colDesc.type != ColDesc::Time) return false; RuleElement *re = (RuleElement *)index.data(Qt::DisplayRole).value(); assert (re!=NULL); if (! re->validateChild(obj) ) { if (RuleElementRItf::cast(re)) { QMessageBox::information( NULL , "Firewall Builder", QObject::tr( "A single interface belonging to " "this firewall is expected in this field."), QString::null,QString::null); } else if (RuleElementRGtw::cast(re)) { QMessageBox::information( NULL , "Firewall Builder", QObject::tr( "A single ip address is expected " "here. You may also insert a host " "or a network adapter leading to " "a single ip adress."), QString::null,QString::null); } return false; } if (re->getAnyElementId()==obj->getId()) return false; if ( !re->isAny()) { /* avoid duplicates */ int cp_id = obj->getId(); list::iterator j; for(j=re->begin(); j!=re->end(); ++j) { FWObject *o=*j; if(cp_id==o->getId()) return false; FWReference *ref; if( (ref=FWReference::cast(o))!=NULL && cp_id==ref->getPointerId()) return false; } } re->addRef(obj); rowChanged(index); return true; } void RuleSetModel::getGroups(QList &list) { list.clear(); int row = 0; foreach(RuleNode *node, root->children) { if (node->type == RuleNode::Group) { list.append(createIndex(row, 0, node)); } row++; } } RuleSetModelIterator RuleSetModel::begin() { RuleSetModelIterator it; if (root->children.isEmpty()) return it; it.model = this; it.row = 0; return it; } RuleSetModelIterator RuleSetModel::end() { RuleSetModelIterator it; if (root->children.isEmpty()) return it; it.model = this; it.row = root->children.size(); return it; } bool RuleSetModel::isGroup(const QModelIndex &index) const { RuleNode* node = nodeFromIndex(index); return node != NULL && node->type == RuleNode::Group; } void RuleSetModel::resetAllSizes() { emit layoutAboutToBeChanged (); root->resetAllSizes(); emit layoutChanged (); } QString RuleSetModel::getPositionAsString(RuleNode *node) const { return QString::number(node->rule->getPosition()); } ActionDesc RuleSetModel::getRuleActionDesc(Rule* r) const { ActionDesc res; res.name = getRuleAction(r); Firewall *f = getFirewall(); if (f) { res.displayName = getActionNameForPlatform(f, r); res.tooltip = FWObjectPropertiesFactory::getRuleActionPropertiesRich(r); } else { res.displayName = res.name; res.tooltip = ""; } res.argument = FWObjectPropertiesFactory::getRuleActionProperties(r); return res; } int RuleSetModel::getRulePosition(QModelIndex index) { Rule* rule = 0; if (index.isValid()) { rule = nodeFromIndex(index)->rule; } return (rule == 0)?0:rule->getPosition(); } void RuleSetModel::objectChanged(FWObject* object) { /* * See #2373 * * Signal dataChanged() is connected to the slot * RuleSetView::updateAllColumnsSize() that just calls resizeColumns() * and does not do anything different depending on the model * index. Can just call it once using different signal. QModelIndexList relatedIndexes = findObject(object); if (fwbdebug) qDebug() << "RuleSetModel::objectChanged" << "object=" << object->getName().c_str() << "relatedIndexes.size()=" << relatedIndexes.size(); foreach(QModelIndex index, relatedIndexes) { emit dataChanged(index, index); } */ emit layoutChanged(); } QModelIndexList RuleSetModel::findObject(FWObject* object) { QModelIndexList list; RuleSetModelIterator it = begin(); RuleSetModelIterator end = this->end(); while (it != end) { QModelIndex index = it.index(); RuleNode* node = nodeFromIndex(index); if (node->type == RuleNode::Group) { ++it; continue; } Rule* rule = node->rule; // iterate through columns int column = 0; foreach(ColDesc colDesc, header) { column++; if (colDesc.type == ColDesc::Object || colDesc.type == ColDesc::Time) { // try to find the object RuleElement* re = getRuleElementByRole( rule, colDesc.origin.toStdString()); if (re->isAny()) continue; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *obj= *i; if (FWReference::cast(obj)!=NULL) obj=FWReference::cast(obj)->getPointer(); if (obj==NULL) continue ; if (object == obj) { list.append(this->index(rule, re)); break; } } } else if (colDesc.type == ColDesc::Action) { PolicyRule * pr = PolicyRule::cast(rule); if (pr != 0) { if (pr->getAction() == PolicyRule::Branch) { if (pr->getBranch() == object) { list.append(this->index(rule, column)); } } else if (pr->getTagging()) { if (pr->getTagObject() == object) { list.append(this->index(rule, column)); } } } } } ++it; } return list; } void RuleSetModel::copyRuleWithoutId(Rule* fromRule, Rule* toRule) { if (fromRule!=NULL && toRule!=NULL) { int oldPos = toRule->getPosition(); toRule->duplicate(fromRule); toRule->setPosition(oldPos); } } //////////////////////////////////////////////////////////////////////// // PolicyModel //////////////////////////////////////////////////////////////////////// void PolicyModel::configure() { supports_logging = false; supports_rule_options = false; supports_time = false; string platform; if (getFirewall()) { platform = getFirewall()->getStr("platform"); try { supports_logging = Resources::getTargetCapabilityBool( platform, "logging_in_policy"); supports_rule_options = Resources::getTargetCapabilityBool( platform, "options_in_policy"); supports_time = Resources::getTargetCapabilityBool( platform, "supports_time"); } catch(FWException &ex) { } } header << ColDesc(platform, RuleElementSrc::TYPENAME, ColDesc::Object) // 1 << ColDesc(platform, RuleElementDst::TYPENAME, ColDesc::Object) // 2 << ColDesc(platform, RuleElementSrv::TYPENAME, ColDesc::Object) // 3 << ColDesc(platform, RuleElementItf::TYPENAME, ColDesc::Object) // 4 << ColDesc(platform, "Direction", ColDesc::Direction) // 5 << ColDesc(platform, "Action", ColDesc::Action); // 6 if (supports_time) header << ColDesc(platform, RuleElementInterval::TYPENAME, ColDesc::Time); // 7 if (supports_logging && supports_rule_options) header << ColDesc(platform, "Options", ColDesc::Options); header << ColDesc(platform, "Comment", ColDesc::Comment); } QVariant PolicyModel::getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const { QVariant res; QTime t; if (index.column() == 0) { res.setValue(getPositionAsString(node)); } else if (index.column() <= header.size()) { int idx = index.column()-1; switch (header[idx].type) { case ColDesc::Action : res.setValue(getRuleActionDesc(node->rule)); break; case ColDesc::Direction : res.setValue(getRuleDirection(node->rule)); break; case ColDesc::Options : res.setValue(getRuleOptions(node->rule)); break; case ColDesc::Comment : res.setValue(QString::fromUtf8(node->rule->getComment().c_str())); break; default : res.setValue(getRuleElementByRole(node->rule, header[idx].origin.toStdString())); } } return res; } QString PolicyModel::getRuleDirection(Rule* r) const { PolicyRule *policyRule = PolicyRule::cast( r ); QString dir = policyRule->getDirectionAsString().c_str(); if (dir.isEmpty() || dir == "Undefined") dir = "Both"; return dir; } QStringList PolicyModel::getRuleOptions(Rule* r) const { QStringList res; PolicyRule *policyRule = PolicyRule::cast( r ); FWOptions *ropt = policyRule->getOptionsObject(); if (policyRule->getLogging()) res << "Log"; if ( ! isDefaultPolicyRuleOptions(r->getOptionsObject())) res << "Options"; FWObject *firewall = r; // use Firewall::cast to match both Firewall and Cluster while (!Firewall::cast(firewall)) firewall = firewall->getParent(); string platform = firewall->getStr("platform"); if (policyRule->getTagging()) { FWObject *tobj = PolicyRule::cast(policyRule)->getTagObject(); if (tobj) { if (platform=="iptables") { res << tr("Tag %1%2") .arg(QString::fromUtf8(tobj->getName().c_str())) .arg( QString( (ropt->getBool("ipt_mark_connections"))?" (conn)":"")); } else res << tr("Tag %1").arg( QString::fromUtf8(tobj->getName().c_str())); } } if (policyRule->getClassification()) { QString par; if (platform=="iptables") par = ropt->getStr("classify_str").c_str(); if (platform=="pf") par = ropt->getStr("pf_classify_str").c_str(); if (platform=="ipfw") { if (ropt->getInt("ipfw_classify_method") == DUMMYNETPIPE) { par = "pipe"; } else { par = "queue"; } par = par + " " + ropt->getStr("ipfw_pipe_queue_num").c_str(); } if (!par.isEmpty()) res << tr("Classify %1").arg(par); } if (policyRule->getRouting()) { res << "Route"; } return res; } void PolicyModel::initRule(Rule *new_rule, Rule *old_rule) { //if (fwbdebug) qDebug() << "PolicyModel::initRule"; PolicyRule *newrule_as_policy_rule = PolicyRule::cast(new_rule); if (newrule_as_policy_rule) { FWOptions *ruleopt = newrule_as_policy_rule->getOptionsObject(); newrule_as_policy_rule->setLogging(supports_logging && st->getBool("Objects/PolicyRule/defaultLoggingState")); switch (st->getInt("Objects/PolicyRule/defaultAction")) { case 1: newrule_as_policy_rule->setAction(PolicyRule::Accept); break; default: newrule_as_policy_rule->setAction(PolicyRule::Deny); break; } switch (st->getInt("Objects/PolicyRule/defaultDirection")) { case 0: newrule_as_policy_rule->setDirection(PolicyRule::Both); break; case 1: newrule_as_policy_rule->setDirection(PolicyRule::Inbound); break; case 2: newrule_as_policy_rule->setDirection(PolicyRule::Outbound); break; } ruleopt->setBool("stateless", ! st->getBool("Objects/PolicyRule/defaultStateful") || getStatelessFlagForAction(newrule_as_policy_rule)); } copyRuleWithoutId(old_rule, new_rule); } bool PolicyModel::checkRuleType(libfwbuilder::Rule *rule) { return rule->getTypeName() == PolicyRule::TYPENAME; } //////////////////////////////////////////////////////////////////////// // NatModel //////////////////////////////////////////////////////////////////////// void NatModel::configure() { supports_actions = false; supports_inbound_interface = false; supports_outbound_interface = false; string platform; if (getFirewall()) { platform = getFirewall()->getStr("platform"); try { supports_actions = Resources::getTargetCapabilityBool( platform, "actions_in_nat"); supports_inbound_interface = Resources::getTargetCapabilityBool( platform, "inbound_interface_in_nat"); supports_outbound_interface = Resources::getTargetCapabilityBool( platform, "outbound_interface_in_nat"); } catch(FWException &ex) { } } header << ColDesc(platform, RuleElementOSrc::TYPENAME, ColDesc::Object) // 1 << ColDesc(platform, RuleElementODst::TYPENAME, ColDesc::Object) // 2 << ColDesc(platform, RuleElementOSrv::TYPENAME, ColDesc::Object) // 3 << ColDesc(platform, RuleElementTSrc::TYPENAME, ColDesc::Object) // 4 << ColDesc(platform, RuleElementTDst::TYPENAME, ColDesc::Object) // 5 << ColDesc(platform, RuleElementTSrv::TYPENAME, ColDesc::Object); // 6 if (supports_inbound_interface) header << ColDesc(platform, RuleElementItfInb::TYPENAME, ColDesc::Object); if (supports_outbound_interface) header << ColDesc(platform, RuleElementItfOutb::TYPENAME, ColDesc::Object); if (supports_actions) header << ColDesc(platform, "Action", ColDesc::Action); header << ColDesc(platform, "Options", ColDesc::Options) // 7 << ColDesc(platform, "Comment", ColDesc::Comment); // 8 } QVariant NatModel::getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const { //if (fwbdebug) qDebug() << "NatModel::getRuleDataForDisplayRole"; QVariant res; if (index.column() == 0) { res.setValue(getPositionAsString(node)); } else if (index.column() <= header.size()) { int idx = index.column()-1; switch (header[idx].type) { case ColDesc::Action : res.setValue(getRuleActionDesc(node->rule)); break; case ColDesc::Options : res.setValue(getRuleOptions(node->rule)); break; case ColDesc::Comment : res.setValue(QString::fromUtf8(node->rule->getComment().c_str())); break; default : res.setValue(getRuleElementByRole(node->rule, header[idx].origin.toStdString())); } } return res; } QStringList NatModel::getRuleOptions(Rule* r) const { QStringList res; if (!isDefaultNATRuleOptions(r->getOptionsObject())) res << "Options"; return res; } void NatModel::initRule(Rule *new_rule, Rule *old_rule) { //if (fwbdebug) qDebug() << "NatModel::initRule"; NATRule *natRule = NATRule::cast(new_rule); if (natRule) natRule->setAction(NATRule::Translate); copyRuleWithoutId(old_rule, new_rule); } bool NatModel::checkRuleType(libfwbuilder::Rule *rule) { return rule->getTypeName() == NATRule::TYPENAME; } //////////////////////////////////////////////////////////////////////// // RoutingModel //////////////////////////////////////////////////////////////////////// void RoutingModel::configure() { //if (fwbdebug) qDebug() << "RoutingModel::configure"; supports_routing_itf = false; supports_metric = false; string platform; string host_os; if (getFirewall()) { platform = getFirewall()->getStr("platform"); host_os = getFirewall()->getStr("host_OS"); try { supports_routing_itf = Resources::getTargetCapabilityBool( host_os, "supports_routing_itf"); supports_metric = Resources::getTargetCapabilityBool( host_os, "supports_metric"); } catch(FWException &ex) { } } header << ColDesc(platform, RuleElementRDst::TYPENAME, ColDesc::Object) // 1 << ColDesc(platform, RuleElementRGtw::TYPENAME, ColDesc::Object); // 2 if (supports_routing_itf) header << ColDesc(platform, RuleElementRItf::TYPENAME, ColDesc::Object); if (supports_metric) header << ColDesc(platform, "Metric", ColDesc::Metric); header << ColDesc(platform, "Options", ColDesc::Options) << ColDesc(platform, "Comment", ColDesc::Comment); } QVariant RoutingModel::getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const { //if (fwbdebug) qDebug() << "RoutingModel::getRuleDataForDisplayRole"; QVariant res; if (index.column() == 0) { res.setValue(getPositionAsString(node)); } else if (index.column() <= header.size()) { int idx = index.column()-1; switch (header[idx].type) { case ColDesc::Metric : res.setValue(QString::fromUtf8(RoutingRule::cast(node->rule)->getMetricAsString().c_str())); break; case ColDesc::Options : res.setValue(getRuleOptions(node->rule)); break; case ColDesc::Comment : res.setValue(QString::fromUtf8(node->rule->getComment().c_str())); break; default : res.setValue(getRuleElementByRole(node->rule, header[idx].origin.toStdString())); } } return res; } QStringList RoutingModel::getRuleOptions(Rule* r) const { QStringList res; if (!isDefaultRoutingRuleOptions(r->getOptionsObject())) res << "Options"; return res; } void RoutingModel::initRule(Rule *new_rule, Rule *old_rule) { //if (fwbdebug) qDebug() << "RoutingModel::initRule"; copyRuleWithoutId(old_rule, new_rule); } bool RoutingModel::checkRuleType(libfwbuilder::Rule *rule) { return rule->getTypeName() == RoutingRule::TYPENAME; } fwbuilder-5.1.0.3599/src/libgui/NetworkDialogIPv6.cpp0000644000175000017500000001327111733011756023026 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "NetworkDialogIPv6.h" #include "ProjectPanel.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Inet6AddrMask.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; NetworkDialogIPv6::NetworkDialogIPv6(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::NetworkDialogIPv6_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } NetworkDialogIPv6::~NetworkDialogIPv6() { delete m_dialog; } void NetworkDialogIPv6::loadFWObject(FWObject *o) { obj=o; NetworkIPv6 *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->address->setText( s->getAddressPtr()->toString().c_str() ); m_dialog->netmask->setText( QString("%1").arg( s->getNetmaskPtr()->getLength()) ); m_dialog->commentKeywords->loadFWObject(o); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->address->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->address); m_dialog->netmask->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->netmask); init=false; } void NetworkDialogIPv6::changed() { //apply->setEnabled( true ); emit changed_sign(); } void NetworkDialogIPv6::validate(bool *res) { *res = true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res = false; return; } NetworkIPv6 *s = dynamic_cast(obj); assert(s != NULL); try { InetAddr(AF_INET6, m_dialog->address->text().toStdString() ); } catch (FWException &ex) { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical(this, "Firewall Builder", tr("Illegal IPv6 address '%1'").arg( m_dialog->address->text()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } bool ok = false; int range = m_dialog->netmask->text().toInt(&ok); // Do not allow netmask of 0 bits. See #251 if (ok && range > 0 && range < 128) { return; } else { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical(this, "Firewall Builder", tr("Illegal netmask '%1'").arg( m_dialog->netmask->text() ), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } } void NetworkDialogIPv6::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); NetworkIPv6 *s = dynamic_cast(new_state); assert(s!=NULL); string oldname=obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); try { s->setAddress( InetAddr(AF_INET6, m_dialog->address->text().toStdString()) ); bool ok = false; s->setNetmask( InetAddr(AF_INET6, m_dialog->netmask->text().toInt(&ok)) ); if (!ok) throw FWException(""); } catch (FWException &ex) { /* exception thrown if user types illegal m_dialog->address or * m_dialog->netmask */ } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void NetworkDialogIPv6::addressEntered() { try { QString addr = m_dialog->address->text(); Inet6AddrMask address_and_mask(string(addr.toStdString())); if (addr.contains('/')) { m_dialog->address->setText( address_and_mask.getAddressPtr()->toString().c_str()); m_dialog->netmask->setText( QString().setNum( address_and_mask.getNetmaskPtr()->getLength())); } } catch (FWException &ex) { // exception thrown if user types illegal m_dialog->address } } fwbuilder-5.1.0.3599/src/libgui/newClusterDialog.cpp0000644000175000017500000002713311733011756023025 0ustar sylvestresylvestre/* * newClusterDialog.cpp - new Cluster wizard implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "newClusterDialog.h" #include "global.h" #include "utils_no_qt.h" #include "utils.h" #include "platforms.h" #include "upgradePredicate.h" #include "ProjectPanel.h" #include "DialogFactory.h" #include "FWBTree.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Library.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include #include #include #include #include #define FIREWALLS_PAGE 0 #define INTERFACES_PAGE 1 #define INTERFACEEDITOR_PAGE 2 #define POLICY_PAGE 3 #define SUMMARY_PAGE 4 using namespace libfwbuilder; using namespace std; newClusterDialog::newClusterDialog(QWidget *parentw, FWObject *_p) : QDialog(parentw), ncl(NULL), fwlist(NULL), tmpldb(NULL) { parent = _p; db = parent->getRoot(); useFirewallList = false; m_dialog = new Ui::newClusterDialog_q; m_dialog->setupUi(this); setControlWidgets(this, m_dialog->stackedWidget, m_dialog->nextButton, m_dialog->finishButton, m_dialog->backButton, m_dialog->cancelButton, m_dialog->titleLabel); m_dialog->obj_name->setFocus(); this->noPolicy = new QRadioButton(m_dialog->page_4); this->noPolicy->setChecked(true); this->spacer = new QSpacerItem(10, 1000); this->m_dialog->page_4->layout()->addWidget(noPolicy); this->m_dialog->page_4->layout()->addItem(spacer); noPolicy->setText(tr("do not use any, i will create new policy and NAT rules")); showPage(0); } void newClusterDialog::changed() { int p = currentPage(); if (p == 0) setNextEnabled(p, !m_dialog->obj_name->text().isEmpty()); } newClusterDialog::~newClusterDialog() { delete m_dialog; } void newClusterDialog::setFirewallList(std::vector data, bool select) { m_dialog->interfaceSelector->clear(); firewallList.clear(); typedef QPair fwpair; foreach ( FWObject *fw, data ) firewallList.push_back(Firewall::cast(fw)); m_dialog->firewallSelector->setFirewallList(firewallList, select); } void newClusterDialog::showPage(const int page, bool blank) { FakeWizard::showPage(page); int p = currentPage(); if (fwbdebug) { qDebug("newClusterDialog::selected p=%d", p); } switch (p) { case FIREWALLS_PAGE: { if (blank) { m_dialog->firewallSelector->clear(); m_dialog->firewallSelector->setFirewallList(firewallList, true); /*else { list fwlist; mw->findAllFirewalls(fwlist); m_dialog->firewallSelector->setFirewallList(fwlist); }*/ } setNextEnabled(FIREWALLS_PAGE, !this->m_dialog->obj_name->text().isEmpty()); setFinishEnabled(FIREWALLS_PAGE, false); m_dialog->nextButton->setDefault(true); break; } case INTERFACES_PAGE: { if (blank) { m_dialog->interfaceSelector->clear(); QList firewalls; typedef QPair fwpair; foreach ( fwpair fw, m_dialog->firewallSelector->getSelectedFirewalls() ) firewalls.append(fw.first); this->m_dialog->interfaceSelector->setFirewallList(firewalls); } setNextEnabled(INTERFACES_PAGE, true); setFinishEnabled(INTERFACES_PAGE, false); m_dialog->nextButton->setDefault(true); break; } case INTERFACEEDITOR_PAGE: { if (blank) { if (this->m_dialog->interfaceSelector->getInterfaces().count() == 0) this->showPage(POLICY_PAGE); this->m_dialog->interfaceEditor->setClusterMode(true); this->m_dialog->interfaceEditor->clear(); this->m_dialog->interfaceEditor->setExplanation( tr("Depending on the failover protocol, cluster interface " "may or may not need an IP address. VRRP, " "CARP, heartbeat interfaces should have their " "own unique IP addresses different from the member firewall " "interfaces. Other failover protocols such as the one used in " "Cisco ASA (PIX) firewall do not require additional IP address." "
" "
" "List of available failover protocols depends on the firewall " "platform." ) ); while (this->m_dialog->interfaceEditor->count()) this->m_dialog->interfaceEditor->removeTab(0); foreach (ClusterInterfaceData iface, this->m_dialog->interfaceSelector->getInterfaces()) { this->m_dialog->interfaceEditor->addClusterInterface(iface); } } setNextEnabled(INTERFACEEDITOR_PAGE, true); setFinishEnabled(INTERFACEEDITOR_PAGE, false); m_dialog->nextButton->setDefault(true); break; } case POLICY_PAGE: { if (blank) { foreach (QRadioButton *btn, copy_rules_from_buttons.keys()) { btn->close(); delete btn; } copy_rules_from_buttons.clear(); QList > fws = m_dialog->firewallSelector->getSelectedFirewalls(); this->m_dialog->page_4->layout()->removeItem(spacer); for ( int i = 0; i < fws.count() ; i++ ) { QRadioButton *newbox = new QRadioButton(QString::fromUtf8(fws.at(i).first->getName().c_str()), m_dialog->page_4); newbox->setObjectName(fws.at(i).first->getName().c_str()); this->m_dialog->page_4->layout()->addWidget(newbox); copy_rules_from_buttons[newbox] = fws.at(i).first; } this->m_dialog->page_4->layout()->addItem(spacer); } setNextEnabled(POLICY_PAGE, true); setFinishEnabled(POLICY_PAGE, false); m_dialog->nextButton->setDefault(true); break; } case SUMMARY_PAGE: { QFont *monospace = new QFont("Lucida Console"); if (!monospace->exactMatch()) { monospace->setFixedPitch(true); monospace->setStyleHint(QFont::SansSerif, QFont::PreferAntialias); QFontDatabase fontdb; foreach (QString family, fontdb.families(QFontDatabase::Latin)) { if (family.startsWith(".")) continue; if (fontdb.isFixedPitch(family, "normal")) { qDebug() << family; monospace->setFamily(family); break; } } } this->m_dialog->firewallsList->setFont(*monospace); this->m_dialog->interfacesList->setFont(*monospace); this->m_dialog->clusterName->setText(this->m_dialog->clusterName->text() + this->m_dialog->obj_name->text()); QStringList firewalls; QList > fws = m_dialog->firewallSelector->getSelectedFirewalls(); QString master; for ( int i = 0; i < fws.count() ; i++ ) { if (fws.at(i).second) master = QString::fromUtf8(fws.at(i).first->getName().c_str()); firewalls.append(QString::fromUtf8(fws.at(i).first->getName().c_str())); } this->m_dialog->firewallsList->setText(firewalls.join("\n")); this->m_dialog->masterLabel->setText(this->m_dialog->masterLabel->text() + master); QStringList interfaces; foreach (EditedInterfaceData iface, this->m_dialog->interfaceEditor->getNewData()) { QString str; if (iface.type == 0) str += tr("regular "); if (iface.type == 1) str += tr("dynamic "); if (iface.type == 1) str += tr("unnumbered "); str += iface.name; if (iface.type == 0 && iface.addresses.count() > 0) { if (iface.addresses.count() == 1) str += tr(" with address: "); else str += tr(" with addresses: "); QStringList addresses; for (int i = 0; i< iface.addresses.values().count(); i++) { AddressInfo addr = iface.addresses.values().at(i); QString addrstr; if (i > 0) addrstr.fill(' ', str.length()); addrstr += addr.address + "/" + addr.netmask; addresses.append(addrstr); } str += addresses.join("\n"); } interfaces.append(str); } this->m_dialog->interfacesList->setText(interfaces.join("\n")); bool doCopy = false; foreach (QRadioButton* btn, copy_rules_from_buttons.keys()) { if (btn->isChecked() && btn != noPolicy) { QString fwname = QString::fromUtf8( copy_rules_from_buttons[btn]->getName().c_str()); this->m_dialog->policyLabel->setText(this->m_dialog->policyLabel->text() + fwname); doCopy = true; break; } } if (!doCopy) this->m_dialog->policyLabel->setVisible(false); setNextEnabled(SUMMARY_PAGE, false); setFinishEnabled(SUMMARY_PAGE, true); m_dialog->finishButton->setDefault(true); break; } } } void newClusterDialog::finishClicked() { m_dialog->nextButton->setFocus(Qt::OtherFocusReason); createNewCluster(); if (unloadTemplatesLib) { delete tmpldb; tmpldb = NULL; unloadTemplatesLib = false; } QDialog::accept(); } void newClusterDialog::cancelClicked() { QDialog::reject(); } void newClusterDialog::nextClicked() { m_dialog->nextButton->setFocus(Qt::OtherFocusReason); if (currentPage() == FIREWALLS_PAGE) { if (!this->m_dialog->firewallSelector->isValid()) return; if ( this->m_dialog->firewallSelector->getSelectedFirewalls().count() == 0 ) { QMessageBox::critical( this, "Firewall Builder", tr("You should select at least one firewall to create a cluster"), "&Continue", QString::null, QString::null, 0, 1); return; } } if (currentPage() == INTERFACES_PAGE) { if (!this->m_dialog->interfaceSelector->isValid()) return; } if (currentPage() == INTERFACEEDITOR_PAGE) if (!this->m_dialog->interfaceEditor->isValid()) return; if (nextRelevant(currentPage()) > -1) { showPage(nextRelevant(currentPage())); } } void newClusterDialog::backClicked() { if (previousRelevant(currentPage()) > -1) { showPage(previousRelevant(currentPage()), false); } } int newClusterDialog::previousRelevant(const int page) const { if (page == POLICY_PAGE && this->m_dialog->interfaceEditor->getNewData().count() == 0) { return INTERFACES_PAGE; } else return FakeWizard::previousRelevant(page); } fwbuilder-5.1.0.3599/src/libgui/MetricEditorPanel.cpp0000644000175000017500000000506411733011756023123 0ustar sylvestresylvestre/* Firewall Builder Routing add-on Copyright (C) 2004 Compal GmbH, Germany Author: Tidei Maurizio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "global.h" #include "MetricEditorPanel.h" #include "FWBSettings.h" #include "ObjectManipulator.h" #include "FWWindow.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; MetricEditorPanel::~MetricEditorPanel() { delete m_widget; } MetricEditorPanel::MetricEditorPanel(QWidget *p) : BaseObjectDialog(p) { m_widget = new Ui::MetricEditorPanel_q; m_widget->setupUi(this); //spin_box->setMinValue( minValue); //spin_box->setMaxValue( maxValue); //spin_box->setValue( value); } int MetricEditorPanel::value() { return m_widget->spin_box->value(); } void MetricEditorPanel::changed() { emit changed_sign(); } void MetricEditorPanel::applyChanges() { rule->setMetric( value() ); } void MetricEditorPanel::loadFWObject(libfwbuilder::FWObject *obj) { RoutingRule *r=RoutingRule::cast(obj); if (r==NULL) return; rule=r; FWObject *o = r; while (o!=NULL && Firewall::cast(o)==NULL) o=o->getParent(); assert(o!=NULL); m_widget->spin_box->setMinimum( 0); m_widget->spin_box->setMaximum( 255); m_widget->spin_box->setValue( r->getMetric()); } void MetricEditorPanel::validate(bool* b ) { *b=true; } void MetricEditorPanel::closeEvent(QCloseEvent *) { } fwbuilder-5.1.0.3599/src/libgui/commenteditorpanel_q.ui0000644000175000017500000000246111733011756023613 0ustar sylvestresylvestre CommentEditorPanel_q true 0 0 643 217 Comment Editor Panel 500 0 TextEditWidget QTextEdit
TextEditWidget.h
editor textChanged() CommentEditorPanel_q changed() 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/vrrpoptionsdialog_q.ui0000644000175000017500000001275211733011756023513 0ustar sylvestresylvestre vrrpOptionsDialog_q 0 0 369 259 secunet wall: interface settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 VRRP Parameters :/Icons/Options:/Icons/Options Use IPsec AH protected VRRP true Qt::RightToLeft VRRP Secret true true Virtual Router ID Qt::RightToLeft VRID 1 255 Qt::Horizontal 140 20 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() vrrpOptionsDialog_q accept() 316 472 20 20 buttonCancel clicked() vrrpOptionsDialog_q reject() 397 472 20 20 fwbuilder-5.1.0.3599/src/libgui/linux24AdvancedDialog.h0000644000175000017500000000272711733011756023274 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LINUX24ADVANCEDDIALOG_H_ #define __LINUX24ADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class linux24AdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::linux24AdvancedDialog_q *m_dialog; public: linux24AdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~linux24AdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); }; #endif // __LINUX24ADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/udpservicedialog_q.ui0000644000175000017500000002363511733011756023261 0ustar sylvestresylvestre UDPServiceDialog_q true 0 0 922 239 0 0 UDP QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Qt::Vertical 20 150 0 0 QFrame::Box QFrame::Sunken 2 8 8 QGroupBox { margin-top: 1ex; padding-top: 1ex; padding-bottom: 0px; padding-left: 2px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; padding: 0 3px; } QSpinBox { margin: 0px; padding: 0px; } Source Port Range 0 2 Start: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QAbstractSpinBox::UpDownArrows 65535 End: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QAbstractSpinBox::UpDownArrows 65535 QGroupBox { margin-top: 1ex; padding-top: 1ex; padding-bottom: 0px; padding-left: 2px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; padding: 0 3px; } QSpinBox { margin: 0px; padding: 0px; } Destination Port Range 0 2 Start: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QAbstractSpinBox::UpDownArrows 65535 End: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QAbstractSpinBox::UpDownArrows 65535 Qt::Vertical 20 40 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name ss se ds de
fwbuilder-5.1.0.3599/src/libgui/instOptionsDialog.cpp0000644000175000017500000001531511733011756023222 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "instOptionsDialog.h" #include "instConf.h" #include "fwbuilder/Firewall.h" #include #include #include #include #include #include #include #include #include #include #include "FWBSettings.h" #include "FWWindow.h" using namespace std; using namespace libfwbuilder; instOptionsDialog::instOptionsDialog(QWidget *parent, instConf *_cnf, bool installing_many_firewalls) : QDialog(parent) { m_dialog = new Ui::instOptionsDialog_q; m_dialog->setupUi(this); cnf = _cnf; this->m_dialog->cancelAllButton->setVisible(installing_many_firewalls); int fw_id = -1; if (cnf->fwobj) { // Note cnf->fwobj == NULL during batch install fw_id = cnf->fwobj->getId(); } QString username = cnf->user; bool savePassEnabled = st->getBool("Environment/RememberSshPassEnabled"); if (savePassEnabled && !username.isEmpty()) { m_dialog->rememberPass->setEnabled(true); m_dialog->rememberPass->setChecked(true); QPair passwds = mw->passwords[qMakePair(fw_id, username)]; m_dialog->pwd->setText(passwds.first); m_dialog->epwd->setText(passwds.second); } else { m_dialog->rememberPass->setEnabled(false); m_dialog->rememberPass->setChecked(false); } m_dialog->pwd->setEchoMode(QLineEdit::Password); m_dialog->epwd->setEchoMode(QLineEdit::Password); m_dialog->uname->setText( cnf->user ); m_dialog->test->setChecked( cnf->dry_run ); m_dialog->backupConfigFile->setText( cnf->backup_file ); m_dialog->saveDiff->setChecked( cnf->save_diff ); m_dialog->saveStandby->setChecked( cnf->saveStandby ); if (!cnf->putty_session.isEmpty()) m_dialog->altAddress->setText( cnf->putty_session ); else m_dialog->altAddress->setText( cnf->maddr ); m_dialog->quiet->setChecked( cnf->quiet ); m_dialog->verbose->setChecked( cnf->verbose ); m_dialog->stripComments->setChecked( cnf->stripComments ); m_dialog->compressScript->setChecked( cnf->compressScript ); m_dialog->copyFWB->setChecked( cnf->copyFWB ); // If we have user name, bring focus to the password input field // if we do not have user name, focus goes to the user name field if (cnf->user.isEmpty()) m_dialog->uname->setFocus(); else m_dialog->pwd->setFocus(); // "batch install" checkbox moved from instDialog to instOptionsDialog m_dialog->batchInstallText->setEnabled(installing_many_firewalls); m_dialog->batchInstall->setEnabled(installing_many_firewalls); m_dialog->batchInstall->setChecked(false); QString fwname = QString::fromUtf8(cnf->fwobj->getName().c_str()); m_dialog->dialogTitleLine->setText( QString("

")+ tr("Install options for firewall '%1'").arg(fwname)+ QString("

") ); QString platform = cnf->fwobj->getStr("platform").c_str(); string version = cnf->fwobj->getStr("version"); if (platform=="pix" || platform=="fwsm" || platform=="iosacl" || platform=="procurve_acl" ) { m_dialog->copyFWB->hide(); m_dialog->PIXgroupBox->hide(); } else { m_dialog->epwd->hide(); m_dialog->epwdLbl->hide(); m_dialog->PIXgroupBox->hide(); m_dialog->test->hide(); // dry run option } /* hide anyway, diff does not work for pix 6.3(3) */ m_dialog->saveDiff->hide(); m_dialog->stripComments->hide(); m_dialog->compressScript->hide(); m_dialog->PIXgroupBox->adjustSize(); //m_dialog->generalOptionsBox->adjustSize(); m_dialog->mainBox->adjustSize(); adjustSize(); if (fwbdebug) { QSize sz = sizeHint(); qDebug() << QString("instOptionsDialog: sizeHint: %1x%2") .arg(sz.width()).arg(sz.height()); sz = minimumSizeHint(); qDebug() << QString("instOptionsDialog: minimumSizeHint: %1x%2") .arg(sz.width()).arg(sz.height()); QRect bfr; bfr = m_dialog->titleFrame->geometry(); qDebug() << QString("instOptionsDialog: titleFrame: top=%1 bottom=%2") .arg(bfr.top()).arg(bfr.bottom()); bfr = m_dialog->buttonsFrame->geometry(); qDebug() << QString("instOptionsDialog: buttonsFrame: top=%1 bottom=%2") .arg(bfr.top()).arg(bfr.bottom()); } //resize( minimumSizeHint() ); //adjustSize(); //dlg->setFixedHeight( dlg->minimumSizeHint().height() ); } void instOptionsDialog::savePassword() { int fw_id = -1; if (cnf->fwobj) { // Note cnf->fwobj == NULL during batch install fw_id = cnf->fwobj->getId(); } if ( m_dialog->rememberPass->isChecked() ) mw->passwords[qMakePair(fw_id, m_dialog->uname->text())] = qMakePair(m_dialog->pwd->text(), m_dialog->epwd->text()); else mw->passwords.remove(qMakePair(fw_id, m_dialog->uname->text())); st->setBool("Environment/RememberSshPass", m_dialog->rememberPass->isChecked()); } instOptionsDialog::~instOptionsDialog() { delete m_dialog; } QString instOptionsDialog::getUName() { return m_dialog->uname->text(); } QString instOptionsDialog::getPWD() { return m_dialog->pwd->text(); } QString instOptionsDialog::getEPWD() { return m_dialog->epwd->text(); } void instOptionsDialog::cancelAll() { this->done(-1); } void instOptionsDialog::batchInstallStateChange() { if (m_dialog->batchInstall->isChecked()) { m_dialog->altAddress->setText(""); m_dialog->altAddressLabel->setEnabled(false); m_dialog->altAddress->setEnabled(false); } else { m_dialog->altAddressLabel->setEnabled(true); m_dialog->altAddress->setEnabled(true); } } fwbuilder-5.1.0.3599/src/libgui/SSHPIX.cpp0000644000175000017500000002075011733011756020566 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "SSHPIX.h" #include #include #include #include #include #include #include #include using namespace std; SSHPIX::SSHPIX(QWidget *_par, const QString &_h, const QStringList &args, const QString &_p, const QString &_ep, const std::list &_in) : SSHCisco(_par,_h,args,_p,_ep,_in) { } SSHPIX::~SSHPIX() { } void SSHPIX::stateMachine() { if (checkForErrors()) return; if (fwbdebug) qDebug() << "SSHPIX::stateMachine() state=" << state << "(ENABLE=" << ENABLE << ")" << "(PUSHING_CONFIG=" << PUSHING_CONFIG << ")" << " stdoutBuffer=" << stdoutBuffer; switch (state) { 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(); if (cmd.indexOf("reload in")!=-1) state = SCHEDULE_RELOAD_DIALOG; sendCommand(cmd); break; } stdoutBuffer=""; if (backup) { /* the problem is that QProcess uses select and thus * is tightly integrated into event loop. QT uses * internal private flag inside QProcess to * specifically prevent recursive calls to * readyReadStdout (look for d->socketReadCalled in * kernel/qprocess_unix.cpp ). So, I _must_ exit this * callback before I can send commands to the process * and collect the output. */ QTimer::singleShot( 0, this, SLOT(PIXbackup()) ); break; } 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 EXECUTING_COMMAND: if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) ) { //QCoreApplication::exit(); state = COMMAND_DONE; if (fwbdebug) qDebug("Switching to COMMAND_DONE state; state=%d", state); if (local_event_loop->isRunning()) local_event_loop->exit(); } break; case GET_ACLS: if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { QTimer::singleShot( 0, this, SLOT(getACLs()) ); } break; case GET_OG: if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { QTimer::singleShot( 0, this, SLOT(getObjectGroups()) ); } break; case CLEAR_ACLS: if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { QTimer::singleShot( 0, this, SLOT(clearACLs()) ); } break; case CLEAR_OG: if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { QTimer::singleShot( 0, this, SLOT(clearObjectGroups()) ); } break; case EXIT: break; case FINISH: break; default: SSHCisco::stateMachine(); break; } } void SSHPIX::PIXbackup() { if (fwbdebug) qDebug("SSHPIX::PIXbackup "); bool sv = verbose; verbose = false; emit printStdout_sign( tr("Making backup copy of the firewall configuration")); emit printStdout_sign( "\n"); cmd(proc, "terminal pager 0"); if (state==FINISH) return; if (fwbdebug) qDebug("terminal pager 0 done"); QString cfg = cmd(proc, "show run"); if (fwbdebug) qDebug("show run done"); verbose = sv; if (fwbdebug) qDebug("state=%d", state); /* if state changed to FINISH, there was an error and ssh terminated */ if (state==FINISH) return; if (state==COMMAND_DONE) { ofstream ofs(backupFile.toLatin1().constData()); ofs << cfg.toAscii().constData(); ofs.close(); backup = false; // backup is done state = ENABLE; } proc->write( "\n" ); } void SSHPIX::getACLs() { if (fwbdebug) qDebug("SSHPIX::getACLs "); bool sv=verbose; bool sq=quiet; verbose=false; quiet=true; QString sa = cmd(proc,"show access-list"); QStringList showAcls; showAcls=sa.split("\n"); verbose=sv; quiet=sq; /* if state changed to FINISH, there was an error and ssh terminated */ if (state==FINISH) return; if (state==COMMAND_DONE) { for (QStringList::iterator i=showAcls.begin(); i!=showAcls.end(); i++) { // if (fwbdebug) qDebug("%s",(*i).ascii()); if ((*i).indexOf("access-list ")==0 && (*i).indexOf(";")==-1) { QString an=(*i).section(' ',1,1); if (an!="cached" && currentAcls.indexOf(an)==-1) currentAcls.push_back(an); } } state=GET_OG; } proc->write( "\n" ); } void SSHPIX::clearACLs() { if (fwbdebug) qDebug("SSHPIX::clearACLs "); emit printStdout_sign( "\n"); emit printStdout_sign(tr("*** Clearing unused access lists")); emit printStdout_sign( "\n"); QString ca; while (currentAcls.size()!=0) { ca=currentAcls.front(); currentAcls.pop_front(); if (newAcls.indexOf(ca)==-1)//newAcls.end()) { if (fwbdebug) qDebug("clear access-list %s",ca.toAscii().constData()); cmd(proc,QString("clear access-list %1").arg(ca)); /* if state changed to FINISH, there was an error and ssh terminated */ if (state==FINISH) return; } } state=CLEAR_OG; proc->write( "\n" ); } void SSHPIX::getObjectGroups() { if (fwbdebug) qDebug("SSHPIX::getObjectGroups "); bool sv=verbose; bool sq=quiet; verbose=false; quiet=true; QString sog = cmd(proc,"show object-group"); QStringList showOG; showOG=sog.split("\n"); verbose=sv; quiet=sq; /* if state changed to FINISH, there was an error and ssh terminated */ if (state==FINISH) return; if (state==COMMAND_DONE) { for (QStringList::iterator i=showOG.begin(); i!=showOG.end(); i++) { // if (fwbdebug) qDebug("%s",(*i).ascii()); if ((*i).indexOf("object-group ")==0) { QString ogn=(*i).section(' ',1,1); if (currentObjectGroups.indexOf(ogn)==-1)//currentObjectGroups.end()) currentObjectGroups.push_back(ogn); } } state=CLEAR_ACLS; } proc->write( "\n" ); } void SSHPIX::clearObjectGroups() { if (fwbdebug) qDebug("SSHPIX::clearObjectGroups "); emit printStdout_sign( "\n"); emit printStdout_sign(tr("*** Clearing unused object groups")); emit printStdout_sign( "\n"); QString ca; while (currentObjectGroups.size()!=0) { ca=currentObjectGroups.front(); currentObjectGroups.pop_front(); if (newObjectGroups.indexOf(ca)==-1)//==newObjectGroups.end()) { if (fwbdebug) qDebug("clear object-group %s",ca.toAscii().constData()); cmd(proc, QString("clear object-group %1").arg(ca)); /* if state changed to FINISH, there was an error and ssh terminated */ if (state==FINISH) return; } } state = EXIT_FROM_CONFIG; emit printStdout_sign( tr("*** End ") + "\n" ); proc->write( "exit\n" ); } fwbuilder-5.1.0.3599/src/libgui/freebsdAdvancedDialog.h0000644000175000017500000000270211733011756023372 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FREEBSDADVANCEDDIALOG_H_ #define __FREEBSDADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class freebsdAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::freebsdAdvancedDialog_q *m_dialog; public: freebsdAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~freebsdAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __FREEBSDADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/RuleOptionsDialog.h0000644000175000017500000000352711733011756022623 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RULEOPTIONSDIALOG_H_ #define __RULEOPTIONSDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "DialogData.h" #include "fwbuilder/FWObject.h" class RuleSetView; class ProjectPanel; class RuleOptionsDialog : public BaseObjectDialog { Q_OBJECT; DialogData data; QString platform; RuleSetView *rsv; Ui::RuleOptionsDialog_q*m_dialog; libfwbuilder::FWObject *firewall; public: RuleOptionsDialog(QWidget *parent); ~RuleOptionsDialog(); void fillInterfaces(QComboBox *); // #2367 public slots: virtual void changed(); virtual void applyChanges(); virtual void cancelChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void connlimitAboveLabelChange(); virtual void limitLabelChange(); virtual void iptRouteContinueToggled(); // #2367 }; #endif // __RULEOPTIONSDIALOG_H fwbuilder-5.1.0.3599/src/libgui/objectmanipulator_q.ui0000644000175000017500000001351211733011756023443 0ustar sylvestresylvestre ObjectManipulator_q true 0 0 240 441 0 0 Tree of Objects 0 Filter: Library: 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Object libraries</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Library <span style=" font-weight:600;">&quot;Standard&quot;</span> holds predefined</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">collection of service and address objects</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">that ships with the package. Library <span style=" font-weight:600;">&quot;User&quot;</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">is where you create your own objects.</p></body></html> false true Item1 Item 2 false 0 0 0 0 0 0 69 69 69 FilterLineEdit QLineEdit
FilterLineEdit.h
widgetStack currentChanged(int) ObjectManipulator_q currentTreePageChanged(int) 20 104 20 20 libs activated(int) ObjectManipulator_q libChanged(int) 119 38 119 220 libChanged(int)
fwbuilder-5.1.0.3599/src/libgui/IPServiceDialog.cpp0000644000175000017500000001770111733011756022523 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "IPServiceDialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ServiceGroup.h" #include #include #include #include #include #include #include #include #include #include "FWWindow.h" using namespace libfwbuilder; using namespace std; IPServiceDialog::IPServiceDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::IPServiceDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } IPServiceDialog::~IPServiceDialog() { delete m_dialog; } void IPServiceDialog::setCodeLabel() { if (m_dialog->use_dscp->isChecked()) { m_dialog->code_label->setText( tr("DSCP code or class:")); } else { m_dialog->code_label->setText( tr("TOS code (numeric):")); } } void IPServiceDialog::loadFWObject(FWObject *o) { obj=o; IPService *s = dynamic_cast(obj); assert(s!=NULL); init = true; //apply->setEnabled( false ); // See #893 No need to show object attributes if the object is "Any" if (obj->getId() == FWObjectDatabase::ANY_SERVICE_ID) { m_dialog->object_attributes_1->hide(); m_dialog->object_attributes_2->hide(); m_dialog->object_attributes_3->hide(); m_dialog->commentKeywords->setReadOnlyComment( QObject::tr( "When used in the Service field of a rule, " "the Any object will match all " "IP, ICMP, TCP or UDP services. To update your rule to " "match only specific " "service, drag-and-drop an object from " "the Object tree into the field in the rule.")); //m_dialog->comment->setReadOnly(true); //setDisabledPalette(m_dialog->comment); } else { m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->protocolNum->setValue( s->getProtocolNumber() ); m_dialog->any_opt->setChecked( s->getBool("any_opt") ); m_dialog->lsrr->setChecked( s->getBool("lsrr") ); m_dialog->ssrr->setChecked( s->getBool("ssrr") ); m_dialog->rr->setChecked( s->getBool("rr") ); m_dialog->timestamp->setChecked( s->getBool("ts") ); m_dialog->all_fragments->setChecked( s->getBool("fragm") ); m_dialog->short_fragments->setChecked( s->getBool("short_fragm") ); m_dialog->router_alert->setChecked( s->getBool("rtralt") ); string tos = s->getTOSCode(); string dscp = s->getDSCPCode(); if (!dscp.empty()) { m_dialog->use_dscp->setChecked(true); m_dialog->code->setText(dscp.c_str()); } else { m_dialog->use_tos->setChecked(true); m_dialog->code->setText(tos.c_str()); } setCodeLabel(); anyOptionsStateChanged(); m_dialog->commentKeywords->loadFWObject(o); m_dialog->object_attributes_1->show(); m_dialog->object_attributes_2->show(); m_dialog->object_attributes_3->show(); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->protocolNum->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->protocolNum); m_dialog->any_opt->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->any_opt); m_dialog->lsrr->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->lsrr); m_dialog->ssrr->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ssrr); m_dialog->rr->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->rr); m_dialog->timestamp->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->timestamp); m_dialog->router_alert->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->router_alert); m_dialog->all_fragments->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->all_fragments); m_dialog->short_fragments->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->short_fragments); m_dialog->use_tos->setEnabled(!o->isReadOnly()); m_dialog->use_dscp->setEnabled(!o->isReadOnly()); m_dialog->code->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->code); //anyOptionsStateChanged(); } init = false; } void IPServiceDialog::changed() { if (fwbdebug) qDebug() << "IPServiceDialog::changed()"; setCodeLabel(); BaseObjectDialog::changed(); } void IPServiceDialog::anyOptionsStateChanged() { bool any_opt_state = m_dialog->any_opt->isChecked(); if (any_opt_state) { m_dialog->lsrr->setChecked(false); m_dialog->ssrr->setChecked(false); m_dialog->rr->setChecked(false); m_dialog->timestamp->setChecked(false); m_dialog->router_alert->setChecked(false); } m_dialog->lsrr->setEnabled(!any_opt_state); m_dialog->ssrr->setEnabled(!any_opt_state); m_dialog->rr->setEnabled(!any_opt_state); m_dialog->timestamp->setEnabled(!any_opt_state); m_dialog->router_alert->setEnabled(!any_opt_state); changed(); } void IPServiceDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void IPServiceDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); string oldname=obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); new_state->setInt("protocol_num", m_dialog->protocolNum->value() ); new_state->setBool("any_opt", m_dialog->any_opt->isChecked() ); new_state->setBool("lsrr", m_dialog->lsrr->isChecked() ); new_state->setBool("ssrr", m_dialog->ssrr->isChecked() ); new_state->setBool("rr", m_dialog->rr->isChecked() ); new_state->setBool("ts", m_dialog->timestamp->isChecked() ); new_state->setBool("fragm", m_dialog->all_fragments->isChecked() ); new_state->setBool("short_fragm", m_dialog->short_fragments->isChecked() ); // router-alert IP option has only one defined value - "0". All other // values are reserved atm. RFC 2113 new_state->setBool("rtralt", m_dialog->router_alert->isChecked() ); if (m_dialog->router_alert->isChecked()) new_state->setInt("rtralt_value", 0); IPService *ip = IPService::cast(new_state); if (m_dialog->use_dscp->isChecked()) { ip->setDSCPCode(m_dialog->code->text().toUtf8().constData()); ip->setTOSCode(""); } else { ip->setTOSCode(m_dialog->code->text().toUtf8().constData()); ip->setDSCPCode(""); } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/newgroupdialog_q.ui0000644000175000017500000000740011733011756022746 0ustar sylvestresylvestre newGroupDialog_q 0 0 314 156 1 1 0 0 New Group Library: false 7 0 0 0 Group Name: false This operation will create a new group and put selected objects in it Qt::AlignVCenter true 55 20 Expanding Horizontal Create a group Cancel obj_name libs applyBtn cancelBtn cancelBtn clicked() newGroupDialog_q reject() applyBtn clicked() newGroupDialog_q accept() fwbuilder-5.1.0.3599/src/libgui/NATRuleOptionsDialog.cpp0000644000175000017500000001426711733011756023524 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "NATRuleOptionsDialog.h" #include "RuleSetView.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "FWCmdRule.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Rule.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Resources.h" #include "../cisco_lib/ASA8TwiceNatLogic.h" #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; NATRuleOptionsDialog::~NATRuleOptionsDialog() { delete m_dialog; } NATRuleOptionsDialog::NATRuleOptionsDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::NATRuleOptionsDialog_q; m_dialog->setupUi(this); init=false; } void NATRuleOptionsDialog::loadFWObject(FWObject *o) { obj = o; FWObject *p = obj; while ( !Firewall::cast(p) ) p = p->getParent(); platform = p->getStr("platform").c_str(); string version = p->getStr("version"); Rule *rule = dynamic_cast(o); FWOptions *ropt = rule->getOptionsObject(); // m_dialog->editorTitle->setText(QString("%1 / %2 / %3 ") // .arg(QString::fromUtf8(p->getName().c_str())) // .arg(rule->getTypeName().c_str()) // .arg(rule->getPosition())); int wid = 0; if (platform=="ipf") wid=0; if (platform=="ipfw") wid=0; if (platform=="pix" || platform=="fwsm") wid = 3; if (platform=="iptables") wid=1; if (platform=="pf") wid=2; m_dialog->widgetStack->setCurrentIndex(wid); m_dialog->widgetStack->widget(wid)->raise(); data.clear(); if (platform=="iptables") { data.registerOption(m_dialog->ipt_use_snat_instead_of_masq, ropt, "ipt_use_snat_instead_of_masq"); data.registerOption(m_dialog->ipt_nat_random, ropt, "ipt_nat_random"); data.registerOption(m_dialog->ipt_nat_persistent, ropt, "ipt_nat_persistent"); } if (platform=="pf") { data.registerOption(m_dialog->pf_pool_type_none, ropt, "pf_pool_type_none"); data.registerOption(m_dialog->pf_bitmask, ropt, "pf_bitmask"); data.registerOption(m_dialog->pf_random, ropt, "pf_random"); data.registerOption(m_dialog->pf_source_hash, ropt, "pf_source_hash"); data.registerOption(m_dialog->pf_round_robin, ropt, "pf_round_robin"); data.registerOption(m_dialog->pf_static_port, ropt, "pf_static_port"); } if (platform=="pix" || platform=="fwsm") { if (libfwbuilder::XMLTools::version_compare(version,"8.3")>=0) { m_dialog->asa8_nat_dns->setEnabled(true); m_dialog->asa8_nat_auto->setEnabled(true); m_dialog->asa8_nat_dynamic->setEnabled(true); m_dialog->asa8_nat_static->setEnabled(true); data.registerOption(m_dialog->asa8_nat_dns, ropt, "asa8_nat_dns"); NATRule *nat_rule = NATRule::cast(rule); ASA8TwiceNatStaticLogic twice_nat_logic(nat_rule); // set asa8_nat_auto to True if none of these are set yet if (!ropt->getBool("asa8_nat_dynamic") && !ropt->getBool("asa8_nat_static")) { ropt->setBool("asa8_nat_auto", true); } data.registerOption(m_dialog->asa8_nat_auto, ropt, "asa8_nat_auto"); data.registerOption(m_dialog->asa8_nat_dynamic, ropt, "asa8_nat_dynamic"); data.registerOption(m_dialog->asa8_nat_static, ropt, "asa8_nat_static"); // update text label of radio button asa8_nat_auto QString rule_state_auto; switch (twice_nat_logic.getAutomaticType()) { case ASA8TwiceNatStaticLogic::STATIC: rule_state_auto = "static"; break; case ASA8TwiceNatStaticLogic::DYNAMIC: rule_state_auto = "dynamic"; break; } QString button_txt = tr( "Automatically detect NAT type \"static\" or \"dynamic\". " "This rule is currently set to type \"%1\""); m_dialog->asa8_nat_auto->setText(button_txt.arg(rule_state_auto)); } else { m_dialog->asa8_nat_dns->setEnabled(false); m_dialog->asa8_nat_auto->setEnabled(false); m_dialog->asa8_nat_dynamic->setEnabled(false); m_dialog->asa8_nat_static->setEnabled(false); } } init = true; data.loadAll(); //apply->setEnabled( false ); init=false; } void NATRuleOptionsDialog::validate(bool *res) { *res = true; } void NATRuleOptionsDialog::applyChanges() { std::auto_ptr cmd( new FWCmdRuleChangeOptions(m_project, obj)); // new_state is a copy of the rule object FWObject* new_state = cmd->getNewState(); FWOptions* new_rule_options = Rule::cast(new_state)->getOptionsObject(); init = true; data.saveAll(new_rule_options); init = false; if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/conntrackOptionsDialog.cpp0000644000175000017500000001000111733011756024212 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "conntrackOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include #include #include using namespace std; using namespace libfwbuilder; conntrackOptionsDialog::conntrackOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::conntrackOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); FWObject *p = obj; while (p && Cluster::cast(p)==NULL) p = p->getParent(); assert(p != NULL); Cluster *cluster = Cluster::cast(p); Resources *os_res = Resources::os_res[cluster->getStr("host_OS")]; assert(os_res != NULL); string default_address = os_res->getResourceStr("/FWBuilderResources/Target/protocols/conntrack/default_address"); string default_port = os_res->getResourceStr("/FWBuilderResources/Target/protocols/conntrack/default_port"); string addr = gropt->getStr("conntrack_address"); if (addr.empty()) gropt->setStr("conntrack_address", default_address); string port = gropt->getStr("conntrack_port"); if (port.empty()) gropt->setStr("conntrack_port", default_port); data.registerOption(m_dialog->use_unicast, gropt, "conntrack_unicast"); data.registerOption(m_dialog->conntrack_address, gropt, "conntrack_address"); data.registerOption(m_dialog->conntrack_port, gropt, "conntrack_port"); data.loadAll(); toggleUseUnicast(); } conntrackOptionsDialog::~conntrackOptionsDialog() { delete m_dialog; } void conntrackOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void conntrackOptionsDialog::reject() { QDialog::reject(); } bool conntrackOptionsDialog::validate() { try { InetAddr( m_dialog->conntrack_address->text().toLatin1().constData() ); } catch (FWException &ex) { try { InetAddr(AF_INET6, m_dialog->conntrack_address->text().toLatin1().constData() ); } catch (FWException &ex) { QMessageBox::critical( this, "Firewall Builder", tr("Invalid IP address '%1'").arg(m_dialog->conntrack_address->text()), tr("&Continue"), 0, 0, 0 ); return false; } } return true; } void conntrackOptionsDialog::toggleUseUnicast() { bool onoff = m_dialog->use_unicast->isChecked(); m_dialog->conntrack_address->setEnabled( ! onoff ); m_dialog->conntrack_address_label->setEnabled( ! onoff ); } fwbuilder-5.1.0.3599/src/libgui/ClusterInterfaceWidget.h0000644000175000017500000000462211733011756023623 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CLUSTERINTERFACEWIDGET_H #define CLUSTERINTERFACEWIDGET_H #include #include #include #include #include #include #include "global.h" #include #include #include #include #include #include #include #include class ClusterInterfacesSelectorWidget; struct ClusterInterfaceData; #include "ClusterInterfacesSelectorWidget.h" Q_DECLARE_METATYPE(libfwbuilder::Interface*) namespace Ui { class ClusterInterfaceWidget; } struct InterfacesList { QVBoxLayout *layout; QTreeWidget *list; QLabel *label; libfwbuilder::Firewall *firewall; }; class ClusterInterfaceWidget : public QWidget { Q_OBJECT public: ClusterInterfaceWidget(QWidget *parent = 0); ~ClusterInterfaceWidget(); void setFirewallList(QList); bool setCurrentInterface(const QString&); ClusterInterfaceData getInterfaceData(); bool interfaceSelectable(libfwbuilder::Interface*); bool isValid(); protected: void changeEvent(QEvent *e); private: Ui::ClusterInterfaceWidget *m_ui; QMap lists; ClusterInterfacesSelectorWidget *cisw; QString os; QMap roots; QHBoxLayout* interfaceBox; public slots: void nameChanged(QString); }; #endif // CLUSTERINTERFACEWIDGET_H fwbuilder-5.1.0.3599/src/libgui/rcsfilesavedialog_q.ui0000644000175000017500000001131711733011756023410 0ustar sylvestresylvestre RCSFileSaveDialog_q true 0 0 381 194 Log record for the new revision true Do not ask me anymore, always check files in with empty log 0 6 20 20 Expanding Horizontal Check file &in Alt+I true true &Cancel true 7 7 0 0 32767 32767 Checking file %1 into RCS false 5 7 0 0 Log record for this revision: false rcslog nolog buttonOk buttonCancel buttonOk clicked() RCSFileSaveDialog_q accept() buttonCancel clicked() RCSFileSaveDialog_q reject() fwbuilder-5.1.0.3599/src/libgui/ActionsDialog.cpp0000644000175000017500000001753011733011756022272 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "ActionsDialog.h" #include "FWWindow.h" #include "FWObjectDropArea.h" #include "DialogFactory.h" #include "FWCmdRule.h" #include "fwbuilder/Library.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Firewall.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; ActionsDialog::ActionsDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::ActionsDialog_q; m_dialog->setupUi(this); m_dialog->iptBranchDropArea->addAcceptedTypes("Policy"); //m_dialog->iptBranchDropArea->addAcceptedTypes("NAT"); //m_dialog->iptBranchDropArea->addAcceptedTypes("Routing"); m_dialog->iptBranchDropArea->setHelperText("Drop rule set object here"); m_dialog->pfBranchDropArea->addAcceptedTypes("Policy"); //m_dialog->pfBranchDropArea->addAcceptedTypes("NAT"); //m_dialog->pfBranchDropArea->addAcceptedTypes("Routing"); m_dialog->pfBranchDropArea->setHelperText("Drop rule set object here"); m_dialog->natBranchDropArea->addAcceptedTypes("NAT"); m_dialog->natBranchDropArea->setHelperText("Drop NAT rule set object here"); connectSignalsOfAllWidgetsToSlotChange(); }; ActionsDialog::~ActionsDialog() { delete m_dialog; } void ActionsDialog::loadFWObject(FWObject *o) { obj = o; setRule(Rule::cast(o)); } void ActionsDialog::validate(bool *res) { FWOptions *ruleopt =rule->getOptionsObject(); *res=true; if (platform=="iptables") { /* * http://www.netfilter.org/projects/patch-o-matic/pom-extra.html#pom-extra-ROUTE * says: * * "Note that --iif, --continue, and --tee, are mutually exclusive." */ string iif = ruleopt->getStr("ipt_iif"); int cont = ruleopt->getBool("ipt_continue"); int tee = ruleopt->getBool("ipt_tee"); if ( (int(!iif.empty()) + cont + tee) > 1) { *res=false; QMessageBox::critical(this, "Firewall Builder", tr("'Change inbound interface', 'Continue packet inspection' and 'Make a copy' options are mutually exclusive"), tr("&Continue"), 0, 0, 0 ); } } } void ActionsDialog::applyChanges() { std::auto_ptr cmd( new FWCmdRuleChangeAction(m_project, obj)); // new_state is a copy of the rule object FWObject* new_state = cmd->getNewState(); FWOptions* new_rule_options = Rule::cast(new_state)->getOptionsObject(); if (platform=="iptables" && editor=="AccountingStr") { QString rn = m_dialog->accountingvalue_str->text(); /* rule name for accounting may contain only alphanumeric characters * and no white spaces or spec. characters */ if (rn.contains(QRegExp("[^a-zA-Z0-9_]"))!=0) { QMessageBox::information( this,"Firewall Builder", tr("Rule name for accounting is converted to the iptables\nchain name and therefore may not contain white space\nand special characters."), tr("&Continue"), QString::null,QString::null, 0, 1 ); return; } } data.saveAll(new_rule_options); Rule *rule = Rule::cast(new_state); if (editor=="BranchChain") { RuleSet *ruleset = RuleSet::cast(m_dialog->iptBranchDropArea->getObject()); // if ruleset==NULL, setBranch clears setting in the rule rule->setBranch(ruleset); } if (editor=="BranchAnchor") { RuleSet *ruleset = RuleSet::cast(m_dialog->pfBranchDropArea->getObject()); // if ruleset==NULL, setBranch clears setting in the rule rule->setBranch(ruleset); } if (editor=="NATBranch") { RuleSet *ruleset = RuleSet::cast(m_dialog->natBranchDropArea->getObject()); // if ruleset==NULL, setBranch clears setting in the rule rule->setBranch(ruleset); } if (!cmd->getOldState()->cmp(new_state, true)) m_project->undoStack->push(cmd.release()); } void ActionsDialog::tagvalueChanged(int) { // QString buf; //!!! buf.setNum(m_dialog->tagvalue_int->value()); //!!! m_dialog->tagvalue_str->setText(buf); } void ActionsDialog::setRule(Rule *r) { rule = r; FWObject *o = r; while (o!=NULL && Firewall::cast(o)==NULL) o = o->getParent(); Firewall *f = Firewall::cast(o); firewall = f; FWOptions *ropt = rule->getOptionsObject(); string act = getRuleAction(rule).toStdString(); if (firewall) { // firewall can be NULL if rule set is in Deleted Objects library platform = firewall->getStr("platform"); editor = DialogFactory::getActionDialogPageName(firewall, r); } if (fwbdebug) qDebug() << "ActionsDialog::setRule" << "Action: " << getRuleAction(rule) << "editor: " << editor.c_str(); QStringList actionsOnReject = getActionsOnReject( platform.c_str() ); m_dialog->rejectvalue->clear(); m_dialog->rejectvalue->addItems( getScreenNames( actionsOnReject ) ); branchNameInput = NULL; data.clear(); data.registerOption(m_dialog->accountingvalue_str, ropt, "rule_name_accounting"); data.registerOption(m_dialog->divertPortNum, ropt, "ipfw_pipe_port_num"); data.registerOption(m_dialog->custom_str, ropt, "custom_str"); // REJECT action: data.registerOption(m_dialog->rejectvalue, ropt, "action_on_reject"); QWidget *w = m_dialog->NonePage; if (editor=="Reject") { w=m_dialog->RejectPage; } else if (editor=="AccountingStr") { w = m_dialog->AccountingStrPage; } else if (editor=="PipeArgsIPFW") { w = m_dialog->PipeArgsIPFW; } else if (editor=="CustomStr") { w = m_dialog->CustomStrPage; } else if (editor=="BranchChain") { w = m_dialog->BranchChainPage; RuleSet *ruleset = r->getBranch(); m_dialog->iptBranchDropArea->setObject(ruleset); data.registerOption( m_dialog->ipt_branch_in_mangle, ropt, "ipt_branch_in_mangle" ); } else if (editor=="BranchAnchor") { w=m_dialog->BranchAnchorPage; RuleSet *ruleset = r->getBranch(); m_dialog->pfBranchDropArea->setObject(ruleset); } else if (editor=="NATBranch") { w = m_dialog->NATBranchPage; RuleSet *ruleset = r->getBranch(); m_dialog->natBranchDropArea->setObject(ruleset); } m_dialog->widgetStack->setCurrentWidget(w); data.loadAll(); } fwbuilder-5.1.0.3599/src/libgui/PrototypeDialogClass.cpp0000644000175000017500000000432611733011756023664 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "PrototypeDialog.h" #include "ObjectManipulator.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Prototype.h" // should be an include file for the object type #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; void PrototypeDialog::loadFWObject(FWObject *o) { obj=o; Prototype *s = dynamic_cast(obj); assert(s!=NULL); init=true; fillLibraries(libs,obj); obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); comment->setText( QString::fromUtf8(s->getComment().c_str()) ); apply->setEnabled( false ); init=false; } void PrototypeDialog::changed() { apply->setEnabled( true ); } void PrototypeDialog::validate(bool *res) { *res=true; } void PrototypeDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); new_state->setName( string(obj_name->text().utf8()) ); new_state->setComment( string(comment->text().utf8()) ); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/openaisoptionsdialog_q.ui0000644000175000017500000001177111733011756024160 0ustar sylvestresylvestre openaisOptionsDialog_q 0 0 402 282 openais protocol settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 openais Parameters :/Icons/Options:/Icons/Options Address: Qt::Horizontal 60 20 Port number (udp): 65535 Qt::Horizontal 120 20 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() openaisOptionsDialog_q accept() 316 472 20 20 buttonCancel clicked() openaisOptionsDialog_q reject() 397 472 20 20 fwbuilder-5.1.0.3599/src/libgui/SimpleTextView.h0000644000175000017500000000262111733011756022143 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SIMPLETEXTVIEW_H_ #define __SIMPLETEXTVIEW_H_ #include "config.h" #include #include class SimpleTextView : public QDialog { Q_OBJECT private: public: Ui::SimpleTextView_q *m_dialog; SimpleTextView(QWidget *parent) : QDialog(parent) { m_dialog = new Ui::SimpleTextView_q; m_dialog->setupUi(this); }; virtual ~SimpleTextView() { delete m_dialog; }; virtual void setText(QString s); virtual void setName(QString s); public slots: signals: }; #endif fwbuilder-5.1.0.3599/src/libgui/vlanonlyifaceoptsdialog_q.ui0000644000175000017500000001435611733011756024650 0ustar sylvestresylvestre vlanOnlyIfaceOptsDialog_q 0 0 310 268 Vlan interface settings Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 Options :/Icons/Options:/Icons/Options Qt::Vertical QSizePolicy::Fixed 20 16 Qt::RightToLeft Device Type true Qt::RightToLeft VLAN ID 4095 Qt::Horizontal 92 20 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() vlanOnlyIfaceOptsDialog_q accept() 316 472 20 20 buttonCancel clicked() vlanOnlyIfaceOptsDialog_q reject() 397 472 20 20 buttonHelp clicked() vlanOnlyIfaceOptsDialog_q help() 68 464 231 245 iface_type currentIndexChanged(QString) vlanOnlyIfaceOptsDialog_q typeChanged(QString) 287 196 286 261 typeChanged(QString) fwbuilder-5.1.0.3599/src/libgui/global.h0000644000175000017500000000265311733011756020457 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GLOBAL_DEFS_ #define __GLOBAL_DEFS_ #include "../../VERSION.h" #include #include class QString; class FWBApplication; class FWWindow; class FWBSettings; extern FWBApplication *app; extern FWWindow *mw; extern FWBSettings *st; extern std::string appRootDir; extern std::string userDataDir; extern std::string argv0; extern std::string ee; extern int fwbdebug; extern QString user_name; extern int sig; #ifdef NDEBUG # undef NDEBUG # include # define NDEBUG #else # include #endif #endif fwbuilder-5.1.0.3599/src/libgui/iosacladvanceddialog_q.ui0000644000175000017500000013264111733011756024046 0ustar sylvestresylvestre iosaclAdvancedDialog_q Qt::WindowModal true 0 0 743 600 IOS ACL Firewall Settings false 0 Compiler Options 0 0 Output file name (if left blank, the file name is constructed of the firewall object name and extension ".fw") Qt::AlignVCenter true 300 0 32767 22 false 20 Compiler creates multiple access lists from the same policy, two for each interface: one for inbound and another for outbound. If the policy is written in a such way that no rule can possibly be associated with an interface, this interface gets no access list at all. Also, interfaces marked as "unprotected" never get access list regardless of how the policy rules are designed. Generate separate access list for each interface Compiler creates one access list and assigns it to all interfaces. Create one access list and attach it to all interfaces 0 0 Policy Compiler Options false false If the option is deactivated, compiler treats empty groups as an error and aborts processing the policy. If this option is activated, compiler removes all empty groups from all rule elements. If rule element becomes 'any' after the last empty group has been removed, the whole rule will be ignored. Use this option only if you fully understand how it works! Ignore empty groups in rules Shadowing happens because a rule is a superset of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. Detect rule shadowing in the policy Use object-group statements (requires IOS v12.4(20)T and later) Always permit ssh access from the management workstation with this address: true false 0 0 300 0 32767 22 Qt::Horizontal 328 20 Qt::Vertical QSizePolicy::Expanding 20 170 Script Options 20 12 20 20 0 0 20 Insert comments into generated IOSACL configuration file Comment the code Insert comments into generated IOSACL configuration file Use ACL remarks Group IOSACL commands in the script so that similar commands appear next to each other, just like IOSACL does it when you use 'show config' Group similar commands together Qt::Vertical 20 70 0 0 12 -1 Clear all access lists then install new ones. This method may interrupt access to the firewall if you manage it remotely via IPSEC tunnel. This is the way access lists were generated in older versions of Firewall Builder for IOSACL. Qt::AlignVCenter true iosacl_acl_basic Qt::ClickFocus Do not clear access lists and object group, just generate IOSACL commands for the new ones. Use this option if you have your own policy installation scripts. Qt::AlignVCenter true iosacl_acl_no_clear Qt::Vertical QSizePolicy::Expanding 20 20 "Safety net" method: First, create temporary access list to permit connections from the management subnet specified below to the firewall and assign it to outside interface. This temporary ACL helps maintain session between management station and the firewall while access lists are reloaded in case connection comes over IPSEC tunnel. Then clear permanent lists, recreate them and assign to interfaces. This method ensures that remote access to the firewall is maintained without interruption at a cost of slightly larger configuration. Qt::AlignVCenter true iosacl_acl_substitution QFrame::StyledPanel QFrame::Sunken 11 Temporary access list should permit access from this address or subnet (use prefix notation to specify subnet, e.g. 192.0.2.0/24): Qt::AlignVCenter true Qt::Horizontal QSizePolicy::Expanding 120 20 0 0 200 0 120 32767 Qt::Horizontal QSizePolicy::Expanding 110 20 0 0 0 0 0 0 Installer 4 Built-in installer User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 Instead of running generated configuration on the router line by line, installer can use scp to copy the file 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 works for IOS v12.4 or later and is much faster than running configuration line by line. true Copy generated configuration file to the router using scp File system on the router where configuration file should be saved if it is copied with scp. Examples: "flash:", "disk0:". Should end with a colon ":". If this input field is left blank, installer uses "nvram:": true Qt::Horizontal 398 20 External install script -1 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Qt::Vertical QSizePolicy::Expanding 20 20 Prolog/Epilog 20 12 20 20 6 Qt::Horizontal QSizePolicy::Expanding 40 20 Edit The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 The following commands will be added verbatim after generated configuration Qt::RichText Qt::AlignVCenter true 0 Logging Generate logging commands Syslog 12 Syslog host (name or IP address): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false syslog facility: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false syslog level ('logging trap'): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false QFrame::HLine QFrame::Sunken Qt::Horizontal QFrame::HLine QFrame::Sunken Qt::Horizontal The logging timestamp command requires that the clock command be set. Qt::AlignVCenter true Enable logging timestamps on syslog file Other logging destinations and levels: 12 Internal buffer Console Qt::Vertical QSizePolicy::Expanding 675 121 IPv6 The order in which ipv4 and ipv6 rules should be generated: Qt::Horizontal 40 20 IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::Expanding 20 20 OK Qt::AlignCenter false Cancel outputFileName separate_acls_for_interfaces one_acl_for_all_interfaces iosacl_ignore_empty_groups iosacl_check_shadowing mgmt_ssh mgmt_addr iosacl_acl_basic iosacl_acl_no_clear iosacl_acl_substitution iosacl_acl_temp_addr iosacl_include_comments iosacl_use_acl_remarks iosacl_regroup_commands user altAddress sshArgs scpArgs use_scp filesystem installScript installScriptArgs iosacl_prolog_script edit_prolog_button iosacl_epilog_script edit_epilog_button generate_logging_commands syslog_host syslog_facility logging_trap_level logging_timestamp logging_buffered logging_console logging_buffered_level logging_console_level ipv4before_2 ok_button cancel_button textLabel3 tabWidget ok_button clicked() iosaclAdvancedDialog_q accept() 20 20 20 20 cancel_button clicked() iosaclAdvancedDialog_q reject() 20 20 20 20 edit_prolog_button clicked() iosaclAdvancedDialog_q editProlog() 20 20 20 20 edit_epilog_button clicked() iosaclAdvancedDialog_q editEpilog() 20 20 20 20 iosacl_acl_basic clicked() iosaclAdvancedDialog_q scriptACLModeChanged() 20 20 20 20 iosacl_acl_substitution clicked() iosaclAdvancedDialog_q scriptACLModeChanged() 20 20 20 20 generate_logging_commands toggled(bool) iosaclAdvancedDialog_q toggleGenerateLogging() 359 55 359 359 fwbuilder-5.1.0.3599/src/libgui/DiscoveryDruid.cpp0000644000175000017500000024144011733011756022510 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005, 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "events.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DiscoveryDruid.h" #include "ProjectPanel.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include #include #include #include #include #include "fwbuilder/HostsFile.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/Inet6AddrMask.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" #include "fwbuilder/dns.h" #include "fwbuilder/snmp.h" #include "fwbuilder/Logger.h" #include "FWBSettings.h" #include "ObjectManipulator.h" #include "FWWindow.h" #include "networkZoneManager.h" #include "IOSImporter.h" #include "IPTImporter.h" #include "PIXImporter.h" using namespace std; using namespace libfwbuilder; DiscoveryDruid::DiscoveryDruid(QWidget *parent, bool start_with_import) : QDialog(parent) { init = true; discovered_fw = NULL; m_dialog = new Ui::DiscoveryDruid_q; m_dialog->setupUi(this); setControlWidgets(this, m_dialog->stackedWidget, m_dialog->nextButton, m_dialog->finishButton, m_dialog->backButton, m_dialog->cancelButton, m_dialog->titleLabel); QTextCursor cursor(m_dialog->discoverylog->textCursor()); normal_format = cursor.charFormat(); error_format = normal_format; error_format.setForeground(QBrush(Qt::red)); error_format.setAnchorHref("http://somewhere.com"); error_format.setAnchor(true); // weight must be between 0 and 99. Qt 4.4.1 does not seem to mind if // it is >99 (just caps it) but older versions assert error_format.setProperty(QTextFormat::FontWeight, 99); warning_format = normal_format; warning_format.setForeground(QBrush(Qt::blue)); warning_format.setProperty(QTextFormat::FontWeight, 99); warning_format.setAnchor(true); warning_format.setAnchorHref("http://somewhere.com"); dm_method = new QButtonGroup; dm_method->addButton(m_dialog->dm_fromfile,0); dm_method->addButton(m_dialog->dm_importdns,1); dm_method->addButton(m_dialog->dm_usesnmp,2); dm_method->addButton(m_dialog->dm_import_config,3); connect(dm_method, SIGNAL( buttonClicked(int) ), this, SLOT( changedDiscoveryMethod(int) ) ); connect(m_dialog->dnsfromlist, SIGNAL( clicked(bool) ), this, SLOT( changedNameServer() ) ); connect(m_dialog->dnscustom, SIGNAL( clicked(bool) ), this, SLOT( changedNameServer() ) ); connect(m_dialog->nameserverlist, SIGNAL( editTextChanged(QString) ), this, SLOT( changedNameServer() ) ); connect(m_dialog->nameserverline, SIGNAL( textChanged(QString) ), this, SLOT( changedNameServer() ) ); thread = NULL; timer = new QTimer(this); prg_timer = new QTimer(this); unBar = NULL; unProg = 0; connect(prg_timer,SIGNAL(timeout()),this,SLOT(updatePrg())); setDiscoveryMethod_file(); flt_obj = new Filter(); flt_obj_d = new FilterDialog(this); flt_obj_d->setFilter(flt_obj); flt_last = new Filter(); flt_last_d = new FilterDialog(this); flt_last_d->setFilter(flt_last); flt_net = new Filter(); flt_net_d = new FilterDialog(this); flt_net_d->setFilter(flt_net); assert(mw->activeProject()->db()); fillLibraries(m_dialog->libs, mw->activeProject()->db()); m_dialog->libs->setEditable(true); m_dialog->libs->lineEdit()->setText(mw->getCurrentLib()->getName().c_str()); m_dialog->DNSprogress->hide(); m_dialog->DNSprogress_2->hide(); #ifndef HAVE_GOODLIBRESOLV m_dialog->dm_importdns->hide(); m_dialog->snmpdnsparameters->hide(); #endif #ifndef HAVE_LIBSNMP m_dialog->dm_usesnmp->setEnabled(false); #endif restore(); importPlatformChanged(m_dialog->import_platform->currentIndex()); showPage(CHOOSE_METHOD_PAGE); setNextEnabled(CHOOSE_METHOD_PAGE, true); if (start_with_import) { m_dialog->dm_import_config->setDown(true); setDiscoveryMethod_Import(); setAppropriate( CHOOSE_METHOD_PAGE, false ); // show the first page of the "import policy" track of the wizard showPage( IMPORT_CONFIG_PAGE ); setNextEnabled(IMPORT_CONFIG_PAGE, false); cancelButton->show(); } prg_timer->start(100); init = false; } void DiscoveryDruid::nextClicked() { if (nextRelevant( currentPage() ) > -1) showPage(nextRelevant( currentPage() )); } void DiscoveryDruid::backClicked() { if (previousRelevant( currentPage() ) > -1) showPage(previousRelevant( currentPage() )); } void DiscoveryDruid::finishClicked() { if (current_task == BT_IMPORT && discovered_fw != NULL) { if (selectedPlatform() == "pix" && currentPage() == NETWORK_ZONES_PAGE) { // read and configure network zones list all_interfaces = discovered_fw->getByTypeDeep(Interface::TYPENAME); list::iterator it; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *iface = Interface::cast(*it); string network_zone_str_id = ""; QList ltwi = m_dialog->iface_nz_list->findItems( iface->getName().c_str(), Qt::MatchExactly ); if ( ! ltwi.empty()) { QTableWidgetItem *itm2 = ltwi[0]; assert(itm2!=NULL); int row = itm2->row(); QComboBox *cb = dynamic_cast( m_dialog->iface_nz_list->cellWidget(row, 3)); assert(cb!=NULL); int network_zone_int_id = cb->itemData(cb->currentIndex(), Qt::UserRole).toInt(); if (network_zone_int_id != 0) network_zone_str_id = FWObjectDatabase::getStringId( network_zone_int_id); else network_zone_str_id = ""; } // only set network zone if it is supported and is not // empty. See #2014 if (!network_zone_str_id.empty()) iface->setStr("network_zone", network_zone_str_id); } } QCoreApplication::postEvent( mw->activeProject(), new expandObjectInTreeEvent( mw->activeProject()->getFileName(), discovered_fw->getId())); QCoreApplication::postEvent( mw->activeProject(), new showObjectInTreeEvent( mw->activeProject()->getFileName(), discovered_fw->getId())); QCoreApplication::postEvent( mw, new openObjectInEditorEvent( mw->activeProject()->getFileName(), discovered_fw->getId())); } QDialog::accept(); } void DiscoveryDruid::cancelClicked() { QDialog::reject(); } DiscoveryDruid::~DiscoveryDruid() { save(); delete flt_obj; delete flt_last; delete flt_net; delete flt_obj_d; delete flt_last_d; delete flt_net_d; delete m_dialog; delete dm_method; } const char * DISCOVERY_DRUID_PREFIX="DiscoveryDruid/"; const char * DISCOVERY_DRUID_DISCOVERYMETHOD="DiscoveryMethod"; const char * DISCOVERY_DRUID_FILENAME ="Filename"; const char * DISCOVERY_DRUID_DOMAINNAME ="Domainname"; const char * DISCOVERY_DRUID_USELONGNAME ="UseLongName"; const char * DISCOVERY_DRUID_NAMESERVER ="NameServer"; const char * DISCOVERY_DRUID_DNSTIMEOUT ="DNSTimeout"; const char * DISCOVERY_DRUID_DNSRETRIES ="DNSRetries"; const char * DISCOVERY_DRUID_SEEDHOST ="SeedHost"; const char * DISCOVERY_DRUID_SNMPINADDR ="SNMPInAddr"; const char * DISCOVERY_DRUID_SNMPINMASK ="SNMPInMask"; const char * DISCOVERY_DRUID_SNMPRECURSIVE ="SNMPRecursive"; const char * DISCOVERY_DRUID_SNMPFOLLOWP2P ="SNMPFollowP2P"; const char * DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED="SnmpIncludeUnnumbered"; const char * DISCOVERY_DRUID_SNMPDODNS ="SNMPDoDNS"; const char * DISCOVERY_DRUID_SNMPCOMMUNITY ="SNMPCommunity"; const char * DISCOVERY_DRUID_SNMPRETRIES ="SNMPRetries"; const char * DISCOVERY_DRUID_SNMPTIMEOUT ="SNMPTimeout"; const char * DISCOVERY_DRUID_SNMPDNSRETRIES ="DNSRetries"; const char * DISCOVERY_DRUID_SNMPDNSTIMEOUT ="DNSTimeout"; const char * DISCOVERY_DRUID_SNMPDNSTHREADS ="SNMPDnsThreads"; const char * DISCOVERY_DRUID_IMPORRT_CONFIG_PLATFORM = "ImportPlatform"; void DiscoveryDruid::restore() { int i; QString s; //Restore from settings dm_method->button(st->getInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DISCOVERYMETHOD))->setChecked(true); changedDiscoveryMethod(dm_method->checkedId()); //m_dialog->filename->setText(st->getStr( // QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_FILENAME)); //m_dialog->domainname->setText(st->getStr( // QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DOMAINNAME)); m_dialog->uselongname->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_USELONGNAME)); //m_dialog->nameserverline->setText(st->getStr( // QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_NAMESERVER)); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSTIMEOUT); m_dialog->dnstimeout->setValue((i)?i:2); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSRETRIES); m_dialog->dnsretries->setValue((i)?i:1); m_dialog->seedhostname->setText(st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SEEDHOST)); m_dialog->snmpinaddr->setText(st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINADDR)); m_dialog->snmpinmask->setText(st->getStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINMASK)); m_dialog->snmprecursive->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRECURSIVE)); m_dialog->snmpfollowp2p->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPFOLLOWP2P)); m_dialog->snmpincludeunnumbered->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED)); m_dialog->snmpdodns->setChecked(st->getBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDODNS)); s=st->getStr(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPCOMMUNITY); m_dialog->snmpcommunity->setText((s.isEmpty())?"public":s); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRETRIES); m_dialog->snmpretries->setValue((i)?i:1); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPTIMEOUT); m_dialog->snmptimeout->setValue((i)?i:2); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSRETRIES); m_dialog->snmpdnsretries->setValue((i)?i:1); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTIMEOUT); m_dialog->snmpdnstimeout->setValue((i)?i:2); i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTHREADS); m_dialog->snmpdnsthreads->setValue((i)?i:5); m_dialog->import_platform->setCurrentIndex(st->getInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_IMPORRT_CONFIG_PLATFORM)); } void DiscoveryDruid::save() { // Save to settings st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DISCOVERYMETHOD, dm_method->checkedId()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_USELONGNAME, m_dialog->uselongname->isChecked()); if (current_task==BT_DNS) { st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSTIMEOUT, m_dialog->dnstimeout->value()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSRETRIES, m_dialog->dnsretries->value()); } else { st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSRETRIES, m_dialog->snmpdnsretries->value()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTIMEOUT, m_dialog->snmpdnstimeout->value()); } st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SEEDHOST, m_dialog->seedhostname->text()); st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINADDR, m_dialog->snmpinaddr->text()); st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINMASK, m_dialog->snmpinmask->text()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRECURSIVE, m_dialog->snmprecursive->isChecked()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPFOLLOWP2P, m_dialog->snmpfollowp2p->isChecked()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED, m_dialog->snmpincludeunnumbered->isChecked()); st->setBool( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDODNS, m_dialog->snmpdodns->isChecked()); st->setStr( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPCOMMUNITY, m_dialog->snmpcommunity->text()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRETRIES, m_dialog->snmpretries->value()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPTIMEOUT, m_dialog->snmptimeout->value()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTHREADS, m_dialog->snmpdnsthreads->value()); st->setInt( QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_IMPORRT_CONFIG_PLATFORM, m_dialog->import_platform->currentIndex()); } void DiscoveryDruid::dnsFinish(QHostInfo host) { QList list = host.addresses(); unBar->hide(); if (userIsTyping) { //abandon the test result if (current_task==BT_DNS) { changedNameServer(); } else { changedSeedHost(); } } else { //get the test result if (list.isEmpty()) { QPalette palette = errMessage->palette(); palette.setColor(errMessage->foregroundRole(), Qt::darkRed); errMessage->setPalette(palette); errMessage->setText( "host name not found"); isSeedHostOK=false; } else { QPalette palette = errMessage->palette(); palette.setColor(errMessage->foregroundRole(), Qt::darkGreen); errMessage->setPalette(palette); errMessage->setText( "host name verified"); isSeedHostOK=true; } nextButton->setEnabled(isSNMPInclNetOK && isSeedHostOK); } } void DiscoveryDruid::changedSelected( const int &page ) { if (init) return; switch (page) { case READ_HOSTS_FILE_PAGE: // Reading file in hosts format { setNextEnabled(page, false); changedHostsFileName(); m_dialog->filename->setFocus(); break; } case IMPORT_CONFIG_PAGE: // import config { m_dialog->obj_name->setFocus(); setBackEnabled(page, true); setFinishEnabled(page, false); break; } case IMPORT_DNS_ZONE_PAGE: // Import DNS zone { changedDomainName(); m_dialog->domainname->setFocus(); //setNextEnabled(page,false); break; } case NAME_SERVER_PAGE: // Name server { if (page>FromPage) getNameServers(); disconnect(timer,SIGNAL(timeout()),0,0); connect(timer,SIGNAL(timeout()),this,SLOT(checkHostName())); changedNameServer(); m_dialog->nameserverline->setFocus(); //setNextEnabled(page,false); break; } case SNMP_DISCOVERY_PAGE: // Network discovery using SNMP { disconnect(timer,SIGNAL(timeout()),0,0); connect(timer,SIGNAL(timeout()),this,SLOT(checkHostName())); isSeedHostOK=false; isSNMPInclNetOK=false; changedSeedHost(); changedInclNet(); m_dialog->seedhostname->setFocus(); break; } case NETWORK_SCAN_OPTIONS_PAGE: // Network scan options { m_dialog->snmprecursive->setFocus(); //setNextEnabled(page,false); break; } case SNMP_PARAMETERS_PAGE: // SNMP and DNS reverse lookup queries parameters { checkSNMPCommunity(); m_dialog->snmpcommunity->setFocus(); break; } case BACKGROUND_PROCESS_PAGE: // Background process (import from hosts and from config file) { m_dialog->discoveryprogress->setValue(-1); m_dialog->discoverylog->clear(); m_dialog->discoveryStopButton->setEnabled(true); m_dialog->logSaveButton->setEnabled(false); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100); setNextEnabled(page, false); cancelButton->hide(); setBackEnabled(page, false); disconnect(timer, SIGNAL(timeout()), 0, 0); connect(timer, SIGNAL(timeout()), this, SLOT(updateLog())); timer->setSingleShot(false); timer->start(1000); startBackgroundProcess(); break; } case CHOOSE_NETWORKS_PAGE: // Networks { fillListOfNetworks(); fillNetworks(); backButton->setEnabled(false); nextButton->setEnabled(m_dialog->networklist->count ()>0 || Objects.size()>0); break; } case CHOOSE_OBJECTS_PAGE: // Objects { if (Networks.size()==0) setBackEnabled(page,false); fillListOfObjects(); fillObjects(); nextButton->setEnabled(m_dialog->objectlist->count ()>0 || m_dialog->networklist->count()>0); break; } case ADJUST_OBJECT_TYPES_PAGE: // Adjust Object type { setBackEnabled(page,true); fillTypeChangingList(); break; } case TARGET_LIB_PAGE: // Target library { break; } case CREATE_OBJECTS_PAGE: // Objects creation ... { setBackEnabled(page,false); cancelButton->hide(); createRealObjects(); setNextEnabled(page, false); setFinishEnabled(page, true); finishButton->setFocus(); break; } case NETWORK_ZONES_PAGE: // Network zones for PIX { setBackEnabled(page, false); cancelButton->hide(); setNextEnabled(page, false); setFinishEnabled(page, true); finishButton->setFocus(); fillNetworkZones(); break; } default : {} } FromPage = page; } void DiscoveryDruid::startBackgroundProcess() { switch (current_task) { case BT_HOSTS: case BT_IMPORT: { m_dialog->discoveryprogress->setMaximum(100); m_dialog->discoveryprogress->setValue(0); m_dialog->discoveryprogress->setEnabled(false); m_dialog->discoveryStopButton->setEnabled(false); break; } case BT_DNS: case BT_SNMP: { m_dialog->discoveryprogress->setMaximum(0); m_dialog->discoveryprogress->setValue(-1); break; } default: {} } switch (current_task) { case BT_HOSTS: startHostsScan(); break; case BT_DNS: startDNSScan(); break; case BT_SNMP: startSNMPScan(); break; case BT_IMPORT: startConfigImport(); break; default: {} } } void DiscoveryDruid::browseHostsFile() { QString s = QFileDialog::getOpenFileName( this, "Choose a file", st->getOpenFileDir(), "All files (*)"); if (s.isEmpty()) return; st->setOpenFileDir(s); m_dialog->filename->setText(s); } void DiscoveryDruid::browseForImport() { QString s = QFileDialog::getOpenFileName( this, "Choose a file", st->getOpenFileDir(), "All files (*)"); if (s.isEmpty()) return; st->setOpenFileDir(s); m_dialog->import_filename->setText(s); } void DiscoveryDruid::updatePrg() { if (unBar!=NULL) { unBar->setValue(unProg++); } } void DiscoveryDruid::getNameServers() { // this is not supported anymore since all resolver functions // have been removed from class DNS m_dialog->nameserverlist->setEnabled(false); m_dialog->dnsfromlist->setEnabled(false); m_dialog->dnscustom->setChecked(true); } void DiscoveryDruid::setDiscoveryMethod_file() { m_dialog->processname->setText(tr("Hosts file parsing ...")); current_task = BT_HOSTS; for (int i=0; iprocessname->setText(tr("DNS zone transfer ...")); current_task = BT_DNS; for (int i=0; iprocessname->setText(tr("Network discovery using SNMP ...")); current_task = BT_SNMP; for (int i=0; iprocessname->setText(tr("Import configuration from file ...")); current_task = BT_IMPORT; for (int i=0; ifilename->text()); thread->setTargetWidget(this); thread->start(); } void DiscoveryDruid::startConfigImport() { if (thread!=NULL) { delete thread; } QFile cf( m_dialog->import_filename->text() ); if (cf.open( QIODevice::ReadOnly ) ) { QTextStream stream(&cf); QString s = stream.readAll(); cf.close(); std::string *buffer = new std::string( s.toLatin1().constData() ); //if (fwbdebug) qDebug(buffer->c_str()); // count lines, gather some general stats on the config file. std::string::size_type pos, n; pos = 0; int line_count = 0; while ( (n=buffer->find('\n', pos))!=std::string::npos) { line_count++; pos = n+1; } m_dialog->discoveryprogress->setMaximum(line_count); // need to pick right platform string based on // m_dialog->import_platform->currentItem() string platform = selectedPlatform(); // // ConfigImport "owns" buffer - it is deleted // in destructor of ConfigImport // thread = new ConfigImport(buffer, platform, m_dialog->obj_name->text().toStdString()); thread->setTargetWidget(this); thread->start(); } else { QMessageBox::critical(this, tr("Discovery error"), tr("Could not open file %1").arg(m_dialog->import_filename->text())); setBackEnabled(currentPage(),true); } } string DiscoveryDruid::selectedPlatform() { string platform = ""; switch (m_dialog->import_platform->currentIndex()) { case IMPORT_IOS: platform = "iosacl"; break; case IMPORT_IPT: platform = "iptables"; break; case IMPORT_PIX: platform = "pix"; break; } return platform; } InetAddr DiscoveryDruid::getNS() { string ns; if (m_dialog->dnscustom->isChecked()) { ns=m_dialog->nameserverline->text().toLatin1().constData(); try { return InetAddr(ns); } catch (FWException &ex) { /* perhaps not address but host name */ list addr; try { addr=DNS::getHostByName(ns); } catch (FWException &ex) { return InetAddr(); } return addr.front(); } } return NameServers[m_dialog->nameserverlist->currentText()]; } void DiscoveryDruid::startDNSScan() { // this is not supported since all resolver functions have been // removed from class DNS } InetAddr DiscoveryDruid::getSeedHostAddress() { if (fwbdebug) qDebug() << QString("DiscoveryDruid::getSeedHostAddress(): Seed host name %1"). arg(m_dialog->seedhostname->text()); libfwbuilder::InetAddr seed_host_addr; if (!m_dialog->seedhostname->text().isEmpty()) { try { QString a = getAddrByName( m_dialog->seedhostname->text(), AF_INET); if (fwbdebug) qDebug() << QString("DiscoveryDruid::getSeedHostAddress() address: %1"). arg(a); return InetAddr( a.toLatin1().constData() ); } catch(const FWException &ex) { } try { seed_host_addr = InetAddr( m_dialog->seedhostname->text().toLatin1().constData()); return seed_host_addr; } catch(const FWException &ex) { } } return seed_host_addr; } void DiscoveryDruid::changedDomainName() { if (m_dialog->domainname->text().isEmpty()) { nextButton->setEnabled(false); } else { nextButton->setEnabled(true); } } void DiscoveryDruid::changedNameServer() { userIsTyping=true; isSNMPInclNetOK=true; if(m_dialog->dnscustom->isChecked()) { nextButton->setEnabled(false); QString s=m_dialog->nameserverline->text(); HostName=s; if (s.isEmpty()) { timer->stop(); m_dialog->DNSprogress_2->hide(); QPalette palette = m_dialog->nameserver_error->palette(); palette.setColor(m_dialog->nameserver_error->foregroundRole(), Qt::darkRed); m_dialog->nameserver_error->setPalette(palette); m_dialog->nameserver_error->setText("Enter valid host name or address."); nextButton->setEnabled(false); return; } if(isInetAddr(s)) { timer->stop(); m_dialog->DNSprogress_2->hide(); QString rs=testInetAddr(s); if (rs.isEmpty()) { m_dialog->nameserver_error->setText(" "); nextButton->setEnabled(true); } else { QPalette palette = m_dialog->nameserver_error->palette(); palette.setColor(m_dialog->nameserver_error->foregroundRole(), Qt::darkRed); m_dialog->nameserver_error->setPalette(palette); m_dialog->nameserver_error->setText(rs); nextButton->setEnabled(false); } } else { unBar=m_dialog->DNSprogress_2; unBar->show(); timer->setSingleShot(true); timer->start(1000); errMessage=m_dialog->nameserver_error; userIsTyping=false; QPalette palette = errMessage->palette(); palette.setColor(errMessage->foregroundRole(), Qt::black); errMessage->setPalette(palette); errMessage->setText("DNS resolution in progress..."); unProg = 0; } } else { timer->stop(); m_dialog->DNSprogress_2->hide(); m_dialog->nameserver_error->setText(" "); nextButton->setEnabled(true); } } void DiscoveryDruid::typedCustomNS() { if(!m_dialog->dnscustom->isChecked()) { m_dialog->dnscustom->setChecked(true); } } bool DiscoveryDruid::isInetAddr(const QString s) { QRegExp r=QRegExp("^(\\d|\\.)+$",Qt::CaseInsensitive); //non wildcard return r.exactMatch(s); } QString DiscoveryDruid::testInetAddr(const QString s) { QString res; QRegExp r=QRegExp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$",Qt::CaseInsensitive); //non wildcard if (r.exactMatch(s)) { try { InetAddr(s.toLatin1().constData()); } catch(const FWException &ex) { res=ex.toString().c_str(); } } else { res="Wrong IPv4 format"; } return res; } void DiscoveryDruid::changedHostsFileName() { QFile f; f.setFileName(m_dialog->filename->text()); if (f.exists()) { setNextEnabled(currentPage(),true); } else { setNextEnabled(currentPage(),false); } } void DiscoveryDruid::changedSNMPOptions() { } void DiscoveryDruid::stopBackgroundProcess() { if (fwbdebug) qDebug("stopBackgroundProcess bop=%p isRunning=%d", bop,(bop!=NULL)?bop->isRunning():-1); if (bop!=NULL && bop->isRunning()) { addToLog("Terminating task. Please wait..."); bop->stop_operation(); m_dialog->discoveryStopButton->setEnabled(false); } } void DiscoveryDruid::addNetwork() { int count = m_dialog->networkresultlist->count(); int upd_max=(count > 10)?count/10:1; int updc=upd_max; int t=0; QProgressDialog pd(tr("Adding objects ..."), tr("Cancel"), 0, count,this); QListWidgetItem* item=(QListWidgetItem*)m_dialog->networkresultlist->item(0); int i = 0; while (item) { if (item->isSelected()) { QString k=item->text(); if (!Networks[k].isSelected) { Networks[k].isSelected=true; m_dialog->networklist->addItem(item->text()); } } i++; item=(QListWidgetItem*)m_dialog->networkresultlist->item(i); if (updc--<=0) { pd.setValue(t); qApp->processEvents(); if (pd.wasCanceled()) { break; } updc=upd_max; } t++; } nextButton->setEnabled(m_dialog->networklist->count ()>0 || Objects.size()>0); } void DiscoveryDruid::removeNetwork() { QListWidgetItem* item1=m_dialog->networklist->item(0); QListWidgetItem* item2; while (item1!=0) { item2=m_dialog->networklist->item( m_dialog->networklist->row(item1)+1); if (item1->isSelected()) { Networks[item1->text()].isSelected=false; delete item1; } item1=item2; } nextButton->setEnabled(m_dialog->networklist->count ()>0 || Objects.size()>0); } void DiscoveryDruid::setNetworkFilter() { flt_net_d->exec(); fillListOfNetworks(); } void DiscoveryDruid::removeNetworkFilter() { flt_net->clear(); fillListOfNetworks(); } void DiscoveryDruid::addObject() { int count = m_dialog->objectresultlist->count(); int upd_max=(count > 10)?count/10:1; int updc=upd_max; int t=0; QProgressDialog pd(tr("Adding objects ..."), tr("Cancel"), 0, count,this); QListWidgetItem* item=(QListWidgetItem*)m_dialog->objectresultlist->item(0); int i = 0; while (item) { if (item->isSelected()) { QString k=item->text(); if (!Objects[k].isSelected) { Objects[k].isSelected=true; m_dialog->objectlist->addItem(item->text()); } } i++; item=(QListWidgetItem*)m_dialog->objectresultlist->item(i); if (updc--<=0) { pd.setValue(t); qApp->processEvents(); if (pd.wasCanceled()) { break; } updc=upd_max; } t++; } nextButton->setEnabled(m_dialog->objectlist->count ()>0 || m_dialog->networklist->count()>0); } void DiscoveryDruid::removeObject() { QListWidgetItem* item1=m_dialog->objectlist->item(0); QListWidgetItem* item2; while (item1!=0) { item2=m_dialog->objectlist->item( m_dialog->objectlist->row(item1)+1); if (item1->isSelected()) { Objects[item1->text()].isSelected=false; delete item1; } item1=item2; } nextButton->setEnabled(m_dialog->objectlist->count ()>0 || m_dialog->networklist->count()>0); } void DiscoveryDruid::setLastFilter() { flt_last_d->exec(); fillTypeChangingList(); } void DiscoveryDruid::setObjectFilter() { flt_obj_d->exec(); fillListOfObjects(); } void DiscoveryDruid::removeLastFilter() { flt_last->clear(); fillTypeChangingList(); } void DiscoveryDruid::removeObjectFilter() { flt_obj->clear(); fillListOfObjects(); } void DiscoveryDruid::selectAllResNets() { m_dialog->networkresultlist->selectAll(); } void DiscoveryDruid::selectAllNets() { m_dialog->networklist->selectAll(); } void DiscoveryDruid::selectAllResObjs() { m_dialog->objectresultlist->selectAll(); } void DiscoveryDruid::selectAllObjs() { m_dialog->objectlist->selectAll(); } void DiscoveryDruid::fillNetworkZones() { m_dialog->iface_nz_list->clear(); QStringList labels; labels << QObject::tr("Name") << QObject::tr("Label") << QObject::tr("Address") << QObject::tr("Network Zone"); m_dialog->iface_nz_list->setHorizontalHeaderLabels(labels); NetworkZoneManager netzone_manager; netzone_manager.load(mw->activeProject()->db()); list all_interfaces = discovered_fw->getByTypeDeep(Interface::TYPENAME); list::iterator it; int row = 0; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *iface = Interface::cast(*it); m_dialog->iface_nz_list->insertRow(row); QTableWidgetItem* itm; itm = new QTableWidgetItem(iface->getName().c_str()); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 0, itm); itm = new QTableWidgetItem(iface->getLabel().c_str()); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 1, itm); QString addr_str; const InetAddr* addr = iface->getAddressPtr(); if (addr) addr_str = addr->toString().c_str(); itm = new QTableWidgetItem(addr_str); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 2, itm); QComboBox *widget = new QComboBox(); netzone_manager.packComboBox(widget, -1); m_dialog->iface_nz_list->setCellWidget(row, 3, widget); row++; } m_dialog->iface_nz_list->resizeColumnToContents(3); } void DiscoveryDruid::fillNetworks() { ObjectDescriptor buf; m_dialog->networklist->clear(); bool f=false; QMap::iterator i; for(i=Networks.begin(); i!=Networks.end(); ++i) { buf=i.value(); if (buf.isSelected) { m_dialog->networklist->addItem(new QListWidgetItem(i.key())); f=true; } } nextButton->setEnabled(f); } void DiscoveryDruid::fillObjects() { ObjectDescriptor buf; m_dialog->objectlist->clear(); bool f=false; QMap::iterator i; for(i=Objects.begin(); i!=Objects.end(); ++i) { buf=i.value(); if (buf.isSelected) { m_dialog->objectlist->addItem(new QListWidgetItem(i.key())); f=true; } } nextButton->setEnabled(f); } void DiscoveryDruid::fillTypeChangingList() { ObjectDescriptor buf; m_dialog->typeChangingList->clear(); QMap::iterator i; for(i=Objects.begin(); i!=Objects.end(); ++i) { buf=i.value(); if (buf.isSelected) { QString ins; if ( flt_last->test(buf) ) { ins=(buf.interfaces.size())? QString("%1").arg(buf.interfaces.size()):""; QStringList sl; sl << buf.toString().c_str() << ins << buf.type.c_str(); new QTreeWidgetItem( m_dialog->typeChangingList, sl ); } } } m_dialog->typeChangingList->resizeColumnToContents(0); m_dialog->typeChangingList->resizeColumnToContents(1); } void DiscoveryDruid::loadDataFromDNS() { // this is not supported since all resolver functions have been // removed from class DNS } void DiscoveryDruid::loadDataFromFile() { m_dialog->objectresultlist->clear(); int t=0; HostsFileImport *himport = dynamic_cast(thread); assert(himport!=NULL); int count = himport->hosts.size(); if (count > 0) { int upd_max=(count > 10)?count/10:1; int updc=upd_max; QProgressDialog pd(tr("Prepare objects ..."), tr("Cancel"), 0, count,this); vector::iterator i; for(i = himport->hosts.begin(); i != himport->hosts.end(); ++i) { if (i->type.empty()) { i->type=IPv4::TYPENAME; } i->isSelected=false; Objects[i->toString().c_str()] = *i; if (updc--<=0) { pd.setValue(t); qApp->processEvents(); if (pd.wasCanceled()) { break; } updc=upd_max; } t++; } } } void DiscoveryDruid::loadDataFromImporter() { ConfigImport *confimp = dynamic_cast(thread); assert(confimp!=NULL); Importer *imp = confimp->getImporterObject(); if (imp!=NULL) { Firewall *fw = imp->finalize(); qApp->processEvents(); // to flush the log if (fw) // fw can be NULL if import was uncussessful { discovered_fw = fw; ProjectPanel *pp = mw->activeProject(); QString filename = pp->getFileName(); //pp->m_panel->om->reload(); //pp->m_panel->om->autoRenameChildren(fw, ""); QCoreApplication::postEvent(mw, new reloadObjectTreeEvent(filename)); if (mw->isEditorVisible()) QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, fw->getId())); QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, fw->getId())); // Open first created Policy ruleset object FWObject *first_policy = fw->getFirstByType(Policy::TYPENAME); if (first_policy) QCoreApplication::postEvent( mw, new openRulesetEvent(filename, first_policy->getId())); } } } void DiscoveryDruid::saveScanLog() { QString s = QFileDialog::getSaveFileName( this, "Choose a file", st->getOpenFileDir(), "Text file (*.txt)"); if (s.isEmpty()) return; st->setOpenFileDir(s); if (s.endsWith(".txt")) s += ".txt"; QFile f(s); if (f.open(QIODevice::WriteOnly)) { if (fwbdebug) { qDebug("Saving crawler log to file: %d chars", m_dialog->discoverylog->toPlainText().length()); qDebug("--------------------------------"); } QTextStream strm(&f); QString txt = m_dialog->discoverylog->toPlainText(); strm << txt << endl; if (fwbdebug) qDebug("%s",txt.toAscii().constData()); if (fwbdebug) qDebug("--------------------------------"); f.close(); } } void DiscoveryDruid::startSNMPScan() { #ifdef HAVE_LIBSNMP bool use_incl=!m_dialog->snmpinaddr->text().isEmpty() && !m_dialog->snmpinmask->text().isEmpty(); if (use_incl) { try { InetAddrMask in( InetAddr(m_dialog->snmpinaddr->text().toLatin1().constData()), InetAddr(m_dialog->snmpinmask->text().toLatin1().constData()) ); include_networks.push_back(in); } catch (const FWException &ex) { //TODO: do something usefull } } libfwbuilder::SNMPCrawler *q = new SNMPCrawler(); q->init(getSeedHostAddress(), m_dialog->snmpcommunity->text().toLatin1().constData(), m_dialog->snmprecursive->isChecked(), false, m_dialog->snmpfollowp2p->isChecked(), 0, m_dialog->snmpretries->value(), 1000000L*m_dialog->snmptimeout->value(), 0, 0, (use_incl) ? &include_networks : NULL); m_dialog->discoveryprogress->setMaximum(0); unBar = m_dialog->discoveryprogress; bop=q; try { logger = bop->start_operation(); if (fwbdebug) logger->copyToStderr(); addToLog("Collecting data ..."); disconnect(timer, SIGNAL(timeout()), 0, 0); connect(timer, SIGNAL(timeout()), this, SLOT(updateLog())); timer->setSingleShot(false); timer->start(100); } catch(const FWException &ex) { delete q; q=NULL; } #endif } void DiscoveryDruid::loadDataFromCrawler() { #ifdef HAVE_LIBSNMP SNMPCrawler *q=(SNMPCrawler*)bop; Objects.clear(); Networks.clear(); set::iterator m; set discovered_networks = q->getNetworks(); if (fwbdebug) qDebug() << QString("got %1 networks").arg(discovered_networks.size()); for (m=discovered_networks.begin(); m!=discovered_networks.end(); ++m) { ObjectDescriptor od; InetAddrMask *net = *m; if (fwbdebug) qDebug() << QString("network %1").arg(net->toString().c_str()); // if address in *m is ipv6, recreate it as Inet6AddrMask and // use type NetworkIPv6 if (net->getAddressPtr()->isV6()) { Inet6AddrMask in6am(*(net->getAddressPtr()), *(net->getNetmaskPtr())); od.sysname = in6am.toString(); // different from ipv6 od.type = NetworkIPv6::TYPENAME; } else { od.sysname = net->toString(); od.type = Network::TYPENAME; } od.addr = *(net->getAddressPtr()); od.netmask = *(net->getNetmaskPtr()); od.isSelected = false; Networks[od.sysname.c_str()]= od; } map t = q->getAllIPs(); if (fwbdebug) qDebug() << QString("got %1 addresses").arg(t.size()); m_dialog->discoveryprogress->setMaximum( t.size() ); m_dialog->discoveryprogress->setValue(0); int cntr = 0; map::iterator j; for(j = t.begin(); j!=t.end(); ++j,++cntr) { m_dialog->discoveryprogress->setValue( cntr ); ObjectDescriptor od( (*j).second ); od.addr = (*j).first; od.type=(od.interfaces.size()>1)? (Host::TYPENAME):(IPv4::TYPENAME); od.isSelected=false; if (od.sysname.empty()) { od.sysname = string("h-") + od.addr.toString(); if (m_dialog->snmpdodns->isChecked()) { QString hostName = getNameByAddr( od.addr.toString().c_str() ); if (!hostName.isEmpty()) od.sysname = hostName.toLatin1().constData(); } addToLog( QString(od.addr.toString().c_str()) + " : " + od.sysname.c_str()); } Objects[od.toString().c_str()]=od; set::iterator si; for(si=od.dns_info.aliases.begin(); si!=od.dns_info.aliases.end(); ++si) { od.sysname=(*si); Objects[od.toString().c_str()]=od; } } #endif } void DiscoveryDruid::fillListOfNetworks() { m_dialog->networkresultlist->clear(); int t=0; int count = Networks.size(); if (count > 0) { int upd_max=(count > 10)?count/10:1; int updc=upd_max; QProgressDialog pd(tr("Copying results ..."), tr("Cancel"), 0, count,this); QMap::iterator i; for (i=Networks.begin(); i!=Networks.end(); ++i) { if ( flt_net->test(i.value()) ) { m_dialog->networkresultlist->addItem(new QListWidgetItem(i.key())); if (updc--<=0) { pd.setValue(t); qApp->processEvents(); if (pd.wasCanceled()) { break; } updc=upd_max; } } t++; } } } void DiscoveryDruid::fillListOfObjects() { m_dialog->objectresultlist->clear(); int t=0; int count = Objects.size(); if (count > 0) { int upd_max=(count > 10)?count/10:1; int updc=upd_max; QProgressDialog pd(tr("Copying results ..."), tr("Cancel"), 0,count,this); QMap::iterator i; for(i=Objects.begin(); i!=Objects.end(); ++i) { if ( flt_obj->test(i.value()) ) { m_dialog->objectresultlist->addItem(new QListWidgetItem(i.key())); if (updc--<=0) { pd.setValue(t); qApp->processEvents(); if (pd.wasCanceled()) { break; } updc=upd_max; } } t++; } } } void DiscoveryDruid::customEvent(QEvent *event) { int evtype=(int)event->type(); if (evtype == ProgressEv) { ProgressEvent *e = (ProgressEvent*)event; m_dialog->discoveryprogress->setValue(e->value); } else if (evtype == DoneEv) { cancelButton->show(); timer->stop(); disconnect(timer,SIGNAL(timeout()),0,0); updateLog(); m_dialog->logSaveButton->setEnabled(true); // actually create objects switch (current_task) { case BT_HOSTS: loadDataFromFile(); break; case BT_IMPORT: loadDataFromImporter(); break; default: break; } thread->wait(); QString er = thread->getError(); delete thread; thread=NULL; switch (current_task) { case BT_HOSTS: if (Objects.size()>0) { nextButton->setDefault(true); nextButton->setFocus(); nextButton->setEnabled(true); backButton->setEnabled(false); } else { backButton->setEnabled(true); nextButton->setEnabled(false); } break; case BT_IMPORT: { // if imported PIX, need to show one more page to select network zones if (selectedPlatform() == "pix") { setNextEnabled(currentPage(), true); setFinishEnabled(currentPage(), false); } else { setNextEnabled(currentPage(), false); setFinishEnabled(currentPage(), true); finishButton->setFocus(); } break; } default: break; } } } void DiscoveryDruid::updateLog() { if (fwbdebug) qDebug("DiscoveryDruid::updateLog"); if (current_task==BT_HOSTS || current_task==BT_IMPORT) { QString buf; if (thread!=NULL) { while(thread->Log->ready()) { buf = thread->Log->getLine().c_str(); addToLog(buf); } } } else if (current_task==BT_SNMP) { if (monitorOperation() > 0) { //m_dialog->discoveryprogress->setValue(prg++); } else { timer->stop(); disconnect(timer,SIGNAL(timeout()),0,0); if (fwbdebug) qDebug("Crawler finished"); loadDataFromCrawler(); cancelButton->show(); FWException * ex=bop->get_latest_error(); if (ex!=NULL) { QMessageBox::critical(this, tr("Discovery error"), ex->toString().c_str()); } if (Objects.size()>0 || Networks.size()>0) { if (Networks.size()==0) setAppropriate( 8,0); nextButton->setEnabled(true); nextButton->setDefault(true); nextButton->setFocus(); backButton->setEnabled(false); } else { nextButton->setEnabled(false); backButton->setEnabled(true); } m_dialog->logSaveButton->setEnabled(true); delete bop; bop=NULL; unBar=NULL; m_dialog->discoveryprogress->setMaximum(100); m_dialog->discoveryprogress->setValue(100); m_dialog->discoveryStopButton->setEnabled(false); } } else if (current_task==BT_DNS) { if (monitorOperation() > 0) { //m_dialog->discoveryprogress->setMaximum(0); //m_dialog->discoveryprogress->setValue( // m_dialog->discoveryprogress->progress()+1); } else { timer->stop(); disconnect(timer,SIGNAL(timeout()),0,0); loadDataFromDNS(); cancelButton->show(); FWException * ex=bop->get_latest_error(); if (ex!=NULL) { QMessageBox::critical(this, tr("Discovery error"), ex->toString().c_str()); } if (Objects.size()>0) { nextButton->setEnabled(true); nextButton->setDefault(true); nextButton->setFocus(); backButton->setEnabled(false); } else { nextButton->setEnabled(false); backButton->setEnabled(true); } m_dialog->logSaveButton->setEnabled(true); delete bop; bop=NULL; unBar=NULL; m_dialog->discoveryprogress->setMaximum(100); m_dialog->discoveryprogress->setValue(100); m_dialog->discoveryStopButton->setEnabled(false); } } } void DiscoveryDruid::addToLog(const QString &buf) { if (buf.isEmpty()) return; foreach(QString line, buf.trimmed().split("\n")) { QTextCharFormat format = normal_format; if (line.contains("Parser error")) format = error_format; if (line.contains("Parser warning")) format = warning_format; if (line.contains("SNMP error, status 2 Timeout")) format = warning_format; QString txt = line; while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r"))) txt.chop(1); if (format == error_format || format == warning_format) format.setAnchorHref(txt); QTextCursor cursor = m_dialog->discoverylog->textCursor(); cursor.insertBlock(); cursor.insertText(txt, format); } m_dialog->discoverylog->ensureCursorVisible(); } void DiscoveryDruid::changedSeedHost() { m_dialog->seedhosterror_message->setText(" "); userIsTyping = true; errMessage = m_dialog->seedhosterror_message; HostName = m_dialog->seedhostname->text(); if (HostName.isEmpty()) { timer->stop(); m_dialog->DNSprogress->hide(); QPalette palette = m_dialog->seedhosterror_message->palette(); palette.setColor( m_dialog->seedhosterror_message->foregroundRole(), Qt::darkRed); m_dialog->seedhosterror_message->setPalette(palette); m_dialog->seedhosterror_message->setText( "Enter a valid host name or address."); isSeedHostOK=false; } else { if(isInetAddr(HostName)) { // seems to be an IP Address m_dialog->DNSprogress->hide(); timer->stop(); QRegExp r = QRegExp( "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$", Qt::CaseInsensitive); //non wildcard if (r.exactMatch(HostName)) { try { InetAddr(HostName.toLatin1().constData()); QPalette palette = m_dialog->seedhosterror_message->palette(); palette.setColor( m_dialog->seedhosterror_message->foregroundRole(), Qt::darkGreen); m_dialog->seedhosterror_message->setPalette(palette); m_dialog->seedhosterror_message->setText( "Address verified"); isSeedHostOK=true; } catch(const FWException &ex) { QPalette palette = m_dialog->seedhosterror_message->palette(); palette.setColor( m_dialog->seedhosterror_message->foregroundRole(), Qt::darkRed); m_dialog->seedhosterror_message->setPalette(palette); m_dialog->seedhosterror_message->setText( ex.toString().c_str()); // need to return focus to the input field in case of error //m_dialog->seedhostname->setFocus(); isSeedHostOK=false; } } else { QPalette palette = m_dialog->seedhosterror_message->palette(); palette.setColor( m_dialog->seedhosterror_message->foregroundRole(), Qt::darkRed); m_dialog->seedhosterror_message->setPalette(palette); m_dialog->seedhosterror_message->setText("Wrong IPv4 format"); isSeedHostOK=false; } } else {// it looks like a DNS name isSeedHostOK = false; QPalette palette = m_dialog->seedhosterror_message->palette(); palette.setColor( m_dialog->seedhosterror_message->foregroundRole(), Qt::black); m_dialog->seedhosterror_message->setPalette(palette); m_dialog->seedhosterror_message->setText( "DNS resolution in progress..."); unProg = 0; unBar=m_dialog->DNSprogress; errMessage=m_dialog->seedhosterror_message; m_dialog->DNSprogress->show(); timer->setSingleShot(true); timer->start(1000); } } nextButton->setEnabled(isSNMPInclNetOK && isSeedHostOK); } void DiscoveryDruid::changedInclNet() { setNextEnabled(currentPage(),false); m_dialog->confineerror_message->setText(" "); bool use_incl=!m_dialog->snmpinaddr->text().isEmpty() && !m_dialog->snmpinmask->text().isEmpty(); if (use_incl) { try { InetAddr a(m_dialog->snmpinaddr->text().toLatin1().constData()); InetAddr n(m_dialog->snmpinmask->text().toLatin1().constData()); InetAddrMask(a,n); m_dialog->confineerror_message->setText(" "); isSNMPInclNetOK=true; } catch (const FWException &ex) { isSNMPInclNetOK=false; m_dialog->confineerror_message->setText(ex.toString().c_str()); } } else { if (!m_dialog->snmpinaddr->text().isEmpty() || !m_dialog->snmpinmask->text().isEmpty()) { isSNMPInclNetOK=false; m_dialog->confineerror_message->setText(tr("Incomlete network specification.")); } else { m_dialog->confineerror_message->setText(" "); isSNMPInclNetOK=true; } } nextButton->setEnabled(isSNMPInclNetOK && isSeedHostOK); } int DiscoveryDruid::monitorOperation() { QString buf; bool fl; if (fwbdebug) qDebug("monitorOperation bop=%p isRunning=%d", bop,(bop!=NULL)?bop->isRunning():-1); fl=false; while( logger->ready() ) { buf= logger->getLine().c_str(); if (buf.endsWith('\n')) buf = buf.left(buf.length() - 1); addToLog(buf); /*if (fwbdebug) qDebug("monitorOperation appending the following buf: (1)"); if (fwbdebug) qDebug(buf.toAscii().constData()); if (fwbdebug) qDebug("----------------------------------------------");*/ fl=true; } if (fl) { return 1; } if (bop==NULL) { return 0; // BackgroundOp has been disconnected } if (bop->isRunning()) { return 1; } // send signal "completed", argument is 0 if ok and -1 if error FWException *ex=bop->get_latest_error(); if (ex) { buf= ex->toString().c_str(); if (buf.endsWith('\n')) buf = buf.left(buf.length() - 1); addToLog(buf); /*if (fwbdebug) qDebug("monitorOperation appending the following buf: (2)"); if (fwbdebug) qDebug(buf.toAscii().constData()); if (fwbdebug) qDebug("----------------------------------------------");*/ // completed(-1); // this sends signal to another widget } else { // completed(0); // this sends signal to another widget } return 0; } void DiscoveryDruid::checkHostName() { if (!HostName.isEmpty()) { userIsTyping=false; QHostInfo::lookupHost(HostName, this, SLOT(dnsFinish(QHostInfo))); } } void DiscoveryDruid::checkSNMPCommunity() { if (m_dialog->snmpcommunity->text().isEmpty()) { m_dialog->snmpcommunity_message->setText(tr("Empty community string")); setNextEnabled(currentPage(),false); } else { m_dialog->snmpcommunity_message->setText(""); setNextEnabled(currentPage(),true); } } void DiscoveryDruid::changeTargetObject(const QString &buf) { QTreeWidgetItem* item=m_dialog->typeChangingList->topLevelItem(0); while (item!=0) { if (item->isSelected()) { Objects[item->text(0)].type=buf.toLatin1().constData(); item->setText(2,buf); } item=m_dialog->typeChangingList->topLevelItem( m_dialog->typeChangingList->indexOfTopLevelItem(item)+1); } } void DiscoveryDruid::selectAllLast() { m_dialog->typeChangingList->selectAll(); } void DiscoveryDruid::unselectAllLast() { m_dialog->typeChangingList->selectAll(); } void DiscoveryDruid::typeAddress() { changeTargetObject(IPv4::TYPENAME); } void DiscoveryDruid::typeHost() { changeTargetObject(Host::TYPENAME); } void DiscoveryDruid::typeFirewall() { changeTargetObject(Firewall::TYPENAME); } /* * Guess OS from the sysDescr string returned by the host. Returned OS * name is always lower case one word, such as "linux", "ios" * * Examples of sysDescr strings: * * IOS (tm) 3600 Software (C3620-IK9O3S-M), Version 12.2(13), RELEASE SOFTWARE (fc1) * Linux guardian 2.4.20 #2 Wed Nov 17 11:49:43 CET 2004 mips * Linux crash 2.6.24-22-server #1 SMP Mon Nov 24 20:06:28 UTC 2008 x86_64 * Apple AirPort - Apple Computer, 2006. All rights Reserved * Cisco Secure FWSM Firewall Version 2.3(4) * Cisco PIX Firewall Version 6.2(1) * Cisco Adaptive Security Appliance Version 8.2(0)227 */ QString DiscoveryDruid::guessOS(const string &sysDescr) { QStringList elements = QString(sysDescr.c_str()).split(" "); QString first = elements[0].toLower(); if (first == "cisco") { if (elements[1].toLower() == "adaptive" && elements[2].toLower() == "security" && elements[3].toLower() == "appliance") return "pix"; if (elements[1].toLower() == "pix") return "pix"; if (elements[1].toLower() == "secure" && elements[2].toLower() == "fwsm") return "pix"; } if (first == "darwin") return "macosx"; if (first == "apple") return "macosx"; return first; } FWObject* DiscoveryDruid::addInterface(FWObject *parent, InterfaceData *in, bool skip_ip_address_check) { ObjectManipulator *om = mw->activeProject()->m_panel->om; if (!m_dialog->snmpincludeunnumbered->isChecked() && !skip_ip_address_check) { if (in->addr_mask.size()==0) return NULL; if (in->addr_mask.front()->getAddressPtr()->isAny()) return NULL; } QString obj_name = in->name.c_str(); Interface *itf = NULL; itf = Interface::cast( mw->createObject(parent, QString(Interface::TYPENAME), obj_name)); QString iname = om->getStandardName(itf, physAddress::TYPENAME, "mac"); iname = om->makeNameUnique(itf, iname, physAddress::TYPENAME); physAddress *paddr = physAddress::cast( mw->createObject(itf, physAddress::TYPENAME, iname) ); paddr->setPhysAddress(in->mac_addr); itf->setLabel(in->label); itf->setSecurityLevel(in->securityLevel); if (fwbdebug) qDebug() << "Interface=" << obj_name << "type=" << in->interface_type.c_str(); if (!in->interface_type.empty()) { itf->getOptionsObject()->setStr("type", in->interface_type); if (in->interface_type == "8021q") itf->getOptionsObject()->setInt("vlan_id", in->vlan_id); } else { std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(parent)); if (int_prop->looksLikeVlanInterface(obj_name)) { QString base_name; int vlan_id; int_prop->parseVlan(obj_name, &base_name, &vlan_id); itf->getOptionsObject()->setStr("type", "8021q"); itf->getOptionsObject()->setInt("vlan_id", vlan_id); } } if (in->addr_mask.size()==0 || in->addr_mask.front()->getAddressPtr()->isAny()) { itf->setUnnumbered(true); } else { list::iterator n; for (n=in->addr_mask.begin(); n!=in->addr_mask.end(); ++n) { const InetAddr *addr = (*n)->getAddressPtr(); const InetAddr *netm = (*n)->getNetmaskPtr(); if (addr->isV4()) { try { QString iname = om->getStandardName(itf, IPv4::TYPENAME, "ip"); iname = om->makeNameUnique(itf, iname, IPv4::TYPENAME); IPv4 *ipv4= IPv4::cast( om->createObject(itf, IPv4::TYPENAME, iname) ); ipv4->setAddress(*addr); ipv4->setNetmask(*netm); } catch (FWException &ex) { cerr << "FWException: " << ex.toString() << endl; } } if (addr->isV6()) { try { QString iname = om->getStandardName(itf, IPv6::TYPENAME, "ip"); iname = om->makeNameUnique(itf, iname, IPv6::TYPENAME); IPv6 *ipv6 = IPv6::cast( om->createObject(itf, IPv6::TYPENAME, iname) ); ipv6->setAddress(*addr); ipv6->setNetmask(*netm); } catch (FWException &ex) { cerr << "FWException: " << ex.toString() << endl; } } } } return itf; } void DiscoveryDruid::createRealObjects() { ObjectDescriptor od; string type, name, a; int t=0; m_dialog->lastprogress->setValue(0); m_dialog->lastprogress->setMaximum( Objects.size()); QMap::iterator i; for (i=Networks.begin(); i!=Networks.end(); ++i) { od=i.value(); if (od.isSelected) { type = od.type; // Network or NetworkIPv6 name = od.sysname; a = od.addr.toString().c_str(); Address *net = Address::cast( mw->createObject(type.c_str(), name.c_str())); assert(net!=NULL); net->setName(name); net->setAddress(od.addr); net->setNetmask(od.netmask); mw->moveObject(m_dialog->libs->currentText(), net); } } for (i=Objects.begin(); i!=Objects.end(); ++i) { od = i.value(); type = od.type; name = od.sysname; QString os = guessOS(od.descr); a = od.addr.toString(); if (od.isSelected) { if (type==Host::TYPENAME || type==Firewall::TYPENAME) { FWObject *o=NULL; o = mw->createObject(type.c_str(), name.c_str()); o->setName(name); if (type==Firewall::TYPENAME) { if (os == "linux") { o->setStr("platform", "iptables"); o->setStr("host_OS", "linux24"); } if (os == "freebsd") { o->setStr("platform", "pf"); o->setStr("host_OS", "freebsd"); } if (os == "openbsd") { o->setStr("platform", "pf"); o->setStr("host_OS", "openbsd"); } if (os == "ios") { o->setStr("platform", "iosacl"); o->setStr("host_OS", "ios"); } if (os == "pix" || os == "fwsm") { o->setStr("platform", "pix"); o->setStr("host_OS", "pix_os"); } if (os == "apple") { o->setStr("platform", "ipfw"); o->setStr("host_OS", "macosx"); } if (os == "solaris") { o->setStr("platform", "ipf"); o->setStr("host_OS", "solaris"); } Resources::setDefaultTargetOptions( o->getStr("platform"), Firewall::cast(o) ); Resources::setDefaultTargetOptions( o->getStr("host_OS"), Firewall::cast(o) ); } if (od.interfaces.size()==0) { Interface *itf= Interface::cast( mw->createObject(o,Interface::TYPENAME,"nic1") ); if (od.addr.isV4()) { IPv4 *ipv4= IPv4::cast( mw->createObject(itf, IPv4::TYPENAME, a.c_str()) ); ipv4->setAddress(od.addr); ipv4->setNetmask(InetAddr()); } if (od.addr.isV6()) { IPv6 *ipv6 = IPv6::cast( mw->createObject(itf, IPv6::TYPENAME, a.c_str()) ); ipv6->setAddress(od.addr); ipv6->setNetmask(InetAddr()); } } else { if (fwbdebug) { map::iterator i; for (i=od.interfaces.begin(); i!=od.interfaces.end(); ++i) { InterfaceData *intf = &(i->second); QString str("Discovered interface %1: %2"); qDebug() << str.arg(intf->name.c_str()).arg(intf->mac_addr.c_str()); } } list interface_tree; std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(o)); int_prop->rearrangeInterfaces(od.interfaces, interface_tree); if (interface_tree.size() != od.interfaces.size()) { // Some interfaces have been converted to subinterfaces // Show warning QMessageBox::warning( this, "Firewall Builder", tr( "Some discovered interfaces have been rearranged in " "fwbuilder objects and recreated as subinterfaces to " "reflect VLANs, bonding and bridging configurations. " "The algorithm used to guess correct relationship " "between interfaces and subinterfaces is imperfect " "because of the limited information provided by SNMP " "daemon. Pelase review created objects to make sure " "generated configuration is accurate. " "\n" "\n" "The program expects MAC addresses of bonding, bridge " "and vlan interfaces to be the same. It is especially " "important to review and fix generated objects if you " "use MAC address spoofing." ), tr("&Continue"), 0, 0, 0 ); } list::iterator it; for (it=interface_tree.begin(); it!=interface_tree.end(); ++it) { InterfaceData *in = *it; // if this interface has subinterfaces, add even if it // has no ip address (last arg) FWObject *intf = addInterface( o, in, in->subinterfaces.size()!=0); if (intf == NULL) continue; list::iterator sit; for (sit=in->subinterfaces.begin(); sit!=in->subinterfaces.end(); ++sit) { InterfaceData *subint = *sit; addInterface(intf, subint, true); } } } if (!od.descr.empty()) { FWOptions* opt=(dynamic_cast(o))->getOptionsObject(); opt->setStr("snmp_description",od.descr); opt->setStr("snmp_location", od.location); opt->setStr("snmp_contact", od.contact); } mw->moveObject(m_dialog->libs->currentText(), o); } else if (type==Network::TYPENAME) { Network *net=dynamic_cast( mw->createObject(type.c_str(),name.c_str()) ); assert(net!=NULL); net->setName(name); net->setAddress(InetAddr(a)); net->setNetmask(InetAddr(InetAddr(a))); mw->moveObject(m_dialog->libs->currentText(), net); } else if (type==IPv4::TYPENAME) { IPv4 *obj=dynamic_cast( mw->createObject(type.c_str(),name.c_str()) ); assert(obj!=NULL); obj->setName(name); obj->setAddress(InetAddr(a)); obj->setNetmask(InetAddr(InetAddr::getAllOnes())); mw->moveObject(m_dialog->libs->currentText(), obj); } } m_dialog->lastprogress->setValue(t++); qApp->processEvents(); } m_dialog->lastprogress->setValue(Objects.size()); ProjectPanel *pp = mw->activeProject(); QString filename = pp->getFileName(); QCoreApplication::postEvent(mw, new reloadObjectTreeEvent(filename)); } void DiscoveryDruid::importPlatformChanged(int cp) { if (fwbdebug) qDebug("DiscoveryDruid::importPlatformChanged(): %d",cp); switch (cp) { case IMPORT_IOS: m_dialog->import_text->setText( QObject::tr("Firewall Builder can import Cisco IOS access lists " "from the router configuration saved using 'show run' " "or any other command that saves running config. The name " "of the created firewall object, all of its interfaces " "and their addresses will be configured automatically if " "this information can be found in the configuration file." ) ); break; case IMPORT_PIX: m_dialog->import_text->setText( QObject::tr("Firewall Builder can import Cisco PIX and ASA " "configuration saved with 'show run' command. " "The name of the created firewall object, all of " "its interfaces and their addresses will be " "configured automatically if this information can " "be found in the configuration file." ) ); break; case IMPORT_IPT: m_dialog->import_text->setText( QObject::tr("Firewall Builder can import iptables rules " "from a file in iptables-save format. Firewall " "name and addresses of its interfaces need " "to be configured manually because iptables-save " "file does not have this information. " ) ); break; } } //---------------------------------------------------------------------- ObjectDescriptor::ObjectDescriptor() {} ObjectDescriptor::ObjectDescriptor(const ObjectDescriptor& od) { have_snmpd = od.have_snmpd; descr = od.descr; contact = od.contact; location = od.location; sysname = od.sysname; interfaces = od.interfaces; MAC_addr = od.MAC_addr; dns_info.name = od.dns_info.name; dns_info.aliases = od.dns_info.aliases; addr = od.addr; type = od.type; isSelected = od.isSelected; netmask = od.netmask; } #ifdef HAVE_LIBSNMP ObjectDescriptor::ObjectDescriptor(const libfwbuilder::CrawlerFind& cf) { have_snmpd = cf.have_snmpd; descr = cf.descr; contact = cf.contact; location = cf.location; sysname = cf.sysname; interfaces = cf.interfaces; MAC_addr = cf.found_phys_addr; dns_info.name = cf.name; dns_info.aliases = cf.aliases; } #endif ObjectDescriptor::~ObjectDescriptor() {}; ObjectDescriptor& ObjectDescriptor::operator=(const ObjectDescriptor& od) { have_snmpd = od.have_snmpd; descr = od.descr; contact = od.contact; location = od.location; sysname = od.sysname; interfaces = od.interfaces; MAC_addr = od.MAC_addr; dns_info.name = od.dns_info.name; dns_info.aliases = od.dns_info.aliases; addr = od.addr; type = od.type; isSelected = od.isSelected; netmask = od.netmask; return *this; } // ================================================================ WorkerThread::WorkerThread() : QThread() { Log = new QueueLogger(); } WorkerThread::~WorkerThread() { delete Log; } void WorkerThread::setProgress(int p) { ProgressEvent *event = new ProgressEvent(); event->value=p; QApplication::postEvent(Widget,event); } void WorkerThread::done() { DoneEvent *event=new DoneEvent(); QApplication::postEvent(Widget,event); } QString WorkerThread::getError() { return last_error; } void WorkerThread::run() { done(); } // ================================================================ HostsFileImport::HostsFileImport(const QString &f) : WorkerThread() { file_name = f; } void HostsFileImport::run() { *Log << "Discovery method: " << "Read file in hosts format. \n"; map > reverse_hosts; HostsFile *hf; /* * read hosts file here */ hf=new HostsFile(); last_error=""; setProgress(10); *Log << "Parsing file: " << file_name.toLatin1().constData() << "\n"; if (!file_name.isEmpty()) { try { hf->parse( file_name.toAscii().constData() ); } catch ( FWException &ex ) { last_error = ex.toString().c_str(); *Log << "Exception: " << last_error.toAscii().constData() << "\n"; delete hf; done(); return; } reverse_hosts=hf->getAll(); delete hf; setProgress(50); *Log << "Loading the list ...\n"; /* * convert map format */ hosts.clear(); map >::iterator i; int count=reverse_hosts.size(); int t=0; for (i=reverse_hosts.begin(); i!=reverse_hosts.end(); ++i) { ObjectDescriptor od; od.addr = (*i).first; od.sysname = ((*i).second).front(); hosts.push_back( od ); setProgress(50+(t++)*50/count); } } *Log << "done.\n"; setProgress(100); done(); } // ================================================================ ConfigImport::ConfigImport(string *b, const std::string &p, const std::string &fwname) : WorkerThread() { buffer = b; platform = p; this->fwname = fwname; } ConfigImport::~ConfigImport() { if (imp) delete imp; if (buffer) delete buffer; } void ConfigImport::run() { *Log << "Discovery method: Import firewall configuration.\n"; std::istringstream instream(*buffer); imp = NULL; if (platform == "iosacl") imp = new IOSImporter(mw->getCurrentLib(), instream, Log, fwname); if (platform == "iptables") imp = new IPTImporter(mw->getCurrentLib(), instream, Log, fwname); if (platform == "pix") imp = new PIXImporter(mw->getCurrentLib(), instream, Log, fwname); // add other platforms here when available if (imp) { try { imp->run(); } catch(ImporterException &e) { last_error = e.toString().c_str(); *Log << e.toString() << "\n"; } } else { *Log << "Can not import configuration for choosen platform\n"; } done(); } void DiscoveryDruid::objNameChanged(QString) { m_dialog->nextButton->setEnabled(!(m_dialog->obj_name->text().isEmpty() || m_dialog->import_filename->text().isEmpty())); m_dialog->nextButton->setDefault(true); } fwbuilder-5.1.0.3599/src/libgui/utils.h0000644000175000017500000000764711733011756020367 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UTILS_H_ #define __UTILS_H_ #include #include #include #include class QObject; class QWidget; class QMenu; class QComboBox; class QListWidget; #include #include #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWReference.h" typedef std::pair QStringPair; // a predicate used to compare first string in pair // use with find_if class findFirstInQStringPair { QString str; public: findFirstInQStringPair(const QString &d) { str=d; } bool operator()(std::pair &_d) { return (str == _d.first); } }; class findSecondInQStringPair { QString str; public: findSecondInQStringPair(const QString &d) { str=d; } bool operator()(std::pair &_d) { return (str == _d.second); } }; extern QAction* addPopupMenuItem(QObject *res, QMenu* menu, //it was a Q3PopupMenu object const QString &resourceIconPath, const QString itemName, const char* member, const QKeySequence &accel = 0); extern void fillLibraries(QComboBox *libs, libfwbuilder::FWObject *obj, bool rw=false); extern void fillLibraries(QListWidget *libs, libfwbuilder::FWObject *obj, bool rw=false); /** * this is a convenience method that checks if the object tree is * read-only and shows appropriate error dialog. This method is * there so we don't have to repeat the same code in each object * class dialog. */ extern bool isTreeReadWrite(QWidget *parent, libfwbuilder::FWObject *obj); /** * this function checks if the name of the object 'obj' is a duplicate * by scanning all children objects of its parent and comparing their * names. It shows pop-up dialog letting user know if the same name * was found, and returns false. It returns true otherwise. */ extern bool validateName(QWidget *parent, libfwbuilder::FWObject *obj, const QString &newname); /** * returns a copy of the string str, enclosed in quotes if it contains * whitespaces */ extern QString quoteString(const QString &str); extern QString getFileDir(const QString &file); extern void loadIcon(QPixmap &pm, libfwbuilder::FWObject *obj); extern void setDisabledPalette(QWidget *w); extern QString getAddrByName(const QString &name, int af_type); extern QString getNameByAddr(const QString &addr); extern QString wordWrap(const QString& ,int); extern void LoadPixmap(const QString &path, QPixmap &where); extern QPixmap LoadPixmap(const QString &path); extern QString calculateIconName(const QString &_icn, bool negation); extern void parseCommandLine(const QString &cmd, QStringList &argv); QStringList sortStrings(const QStringList &list); /* * @icon_size: 0 - small (16x16) , 1 - medium (25x25), 2 - big (64x64) */ extern void doSetObjectIcon(libfwbuilder::FWObject *obj, QPixmap *pm, int icon_size); #endif fwbuilder-5.1.0.3599/src/libgui/startwizard_q.ui0000644000175000017500000002243411733011756022302 0ustar sylvestresylvestre startWizard_q 0 0 440 283 0 0 0 25 Sans Serif 14 75 false true Qt::AlignCenter 0 0 0 0 0 Aharoni 24 <b>Firewall Builder N.N.N</b> Qt::AlignCenter true Do you want to open existing project file or create a new one? Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 40 20 Create new project file Qt::Horizontal QSizePolicy::Expanding 40 20 Open existing file Qt::Horizontal QSizePolicy::Expanding 30 20 0 0 0 0 File name: %1 false Activate Revision Control System for this file (if you do not do this now, you can always activate it later) Qt::Vertical QSizePolicy::Expanding 20 60 Let the program automatically open this file when I start it next time (you can activate this option later using Preferences dialog) 1 0 400 50 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 40 20 < &Back &Next > false &Finish false &Cancel openFileButton newFileButton rcsBtn autoopenBtn newFileButton clicked() startWizard_q newFile() 20 20 20 20 openFileButton clicked() startWizard_q openFile() 20 20 20 20 startWizard_q selected(QString) startWizard_q selected(QString) 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/TimeDialog.h0000644000175000017500000000266311733011756021236 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TIMEDIALOG_H_ #define __TIMEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class TimeDialog : public BaseObjectDialog { Q_OBJECT; Ui::TimeDialog_q *m_dialog; void enableAllWidgets(); public: TimeDialog(QWidget *parent); ~TimeDialog(); public slots: virtual void applyChanges(); virtual void useStartOrEndDate(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // __TIMEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/check_update_url.h0000644000175000017500000000176711733011756022525 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CHECK_UPDATE_URL_HH #define CHECK_UPDATE_URL_HH #define CHECK_UPDATE_URL "http://update.fwbuilder.org/update_checks/check.cgi?v=%1&uuid=%2" #endif fwbuilder-5.1.0.3599/src/libgui/PhysicalAddressDialog.h0000644000175000017500000000272511733011756023421 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PHYSICALADDRESSDIALOG_H_ #define __PHYSICALADDRESSDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class PhysicalAddressDialog : public BaseObjectDialog { Q_OBJECT; bool showNetmask; Ui::PhysAddressDialog_q *m_dialog; public: PhysicalAddressDialog(QWidget *parent); ~PhysicalAddressDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // PHYSICALADDRESSDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FWCmdChange.h0000644000175000017500000000530111733011756021256 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWCMDCHANGE_H #define FWCMDCHANGE_H #include "FWCmdBasic.h" /******************************************************** * FWCmdChange ********************************************************/ class FWCmdChange : public FWCmdBasic { libfwbuilder::FWObject *oldState; libfwbuilder::FWObject *newState; bool rename_children; bool first_time; protected: virtual void notify(); public: FWCmdChange(ProjectPanel *project, libfwbuilder::FWObject *obj, QString text=QString(), bool rename_children = false, QUndoCommand* macro = 0); ~FWCmdChange(); libfwbuilder::FWObject* getOldState() {return oldState;} libfwbuilder::FWObject* getNewState() {return newState;} virtual void redo(); virtual void undo(); }; /******************************************************** * FWCmdChangeName ********************************************************/ class FWCmdChangeName : public FWCmdChange { protected: virtual void notify(); public: FWCmdChangeName(ProjectPanel *project, libfwbuilder::FWObject *obj); }; /******************************************************** * FWCmdLockObject * * This command locks or unlocks object ********************************************************/ class FWCmdLockObject : public FWCmdChange { protected: public: FWCmdLockObject(ProjectPanel *project, libfwbuilder::FWObject *obj, QString text=QString()); virtual void redo(); virtual void undo(); }; /******************************************************** * FWCmdChangeOptionsObject ********************************************************/ class FWCmdChangeOptionsObject : public FWCmdChange { protected: virtual void notify(); public: FWCmdChangeOptionsObject(ProjectPanel *project, libfwbuilder::FWObject *obj); }; #endif // FWCMDCHANGE_H fwbuilder-5.1.0.3599/src/libgui/ConfirmDeleteObjectDialog.cpp0000644000175000017500000000663511733011756024545 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include "definitions.h" #include "ConfirmDeleteObjectDialog.h" #include "FindWhereUsedWidget.h" #include "ObjectManipulator.h" #include "FWWindow.h" #include "FWBTree.h" #include "UsageResolver.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Resources.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Library.h" //#include #include #include #include #include using namespace std; using namespace libfwbuilder; ConfirmDeleteObjectDialog::ConfirmDeleteObjectDialog(QWidget*p) : QDialog(p) { m_dialog = new Ui::ConfirmDeleteObjectDialog_q; m_dialog->setupUi(this); } ConfirmDeleteObjectDialog::~ConfirmDeleteObjectDialog() { delete m_dialog; } void ConfirmDeleteObjectDialog::load(vector objs) { if (objs.size()==0) return; vector::iterator i; for( i=objs.begin(); i!=objs.end(); ++i) { findForObject(*i); } } void ConfirmDeleteObjectDialog::findForObject(FWObject *obj) { QPixmap pm0; loadIcon(pm0, obj); map > reference_holders; UsageResolver().findAllReferenceHolders(obj, obj->getRoot(), reference_holders); set simplified_holders; map >::iterator it; for (it=reference_holders.begin(); it!=reference_holders.end(); ++it) { foreach(FWObject *o, it->second) { if (o == obj || o->isChildOf(obj)) continue; simplified_holders.insert(o); } } int itemCounter = 0; foreach(FWObject *o, simplified_holders) { QTreeWidgetItem *item = FindWhereUsedWidget::createQTWidgetItem(obj, o); if (item==NULL) continue; m_dialog->objectsView->addTopLevelItem(item); itemCounter++; } if (itemCounter==0) { QStringList qsl; qsl << QString::fromUtf8( obj->getName().c_str()) << "" << tr("Not used anywhere"); QTreeWidgetItem *item = new QTreeWidgetItem(m_dialog->objectsView, qsl); item->setIcon(0,QIcon(pm0)); } m_dialog->objectsView->resizeColumnToContents(0); m_dialog->objectsView->resizeColumnToContents(1); } fwbuilder-5.1.0.3599/src/libgui/TCPServiceDialog.h0000644000175000017500000000267711733011756022314 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TCPSERVICEDIALOG_H_ #define __TCPSERVICEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class TCPServiceDialog : public BaseObjectDialog { Q_OBJECT; Ui::TCPServiceDialog_q *m_dialog; public: TCPServiceDialog(QWidget *parent); ~TCPServiceDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void toggleEstablished(); }; #endif // TCPSERVICEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/ClusterGroupDialog.cpp0000644000175000017500000002747211733011756023336 0ustar sylvestresylvestre/* * ClusterGroupDialog.cpp - ClusterGroup view implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "ClusterGroupDialog.h" #include "utils.h" #include "platforms.h" #include "events.h" #include "ObjectListViewItem.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "DialogFactory.h" #include "vrrpOptionsDialog.h" #include "FWCmdChange.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; ClusterGroupDialog::~ClusterGroupDialog() { delete m_dialog; } ClusterGroupDialog::ClusterGroupDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::ClusterGroupDialog_q; m_dialog->setupUi(this); obj = NULL; reload = false; connectSignalsOfAllWidgetsToSlotChange(); } void ClusterGroupDialog::loadFWObject(FWObject *o) { obj = o; ClusterGroup *g = dynamic_cast(obj); assert(g != NULL); init = true; // disable manage members if host OS does not support clustering. // Parent is either 'Cluster' or 'Interface', call getParent() approprietly FWObject *parent = obj; while (parent && !Cluster::isA(parent)) parent = parent->getParent(); if (parent == NULL) { throw FWException("ClusterGroupDialog: parent is NULL!"); } cluster = Cluster::cast(parent); string host_os = cluster->getStr("host_OS"); // Sanity check // Failover type could be wrong if user changed host OS of the cluster string type = obj->getStr("type"); list possible_cluster_group_types; if (StateSyncClusterGroup::isA(o)) getStateSyncTypesForOS(host_os.c_str(), possible_cluster_group_types); if (FailoverClusterGroup::isA(o)) getFailoverTypesForOS(host_os.c_str(), possible_cluster_group_types); enable_master_column = Resources::os_res[host_os]->getResourceBool( "/FWBuilderResources/Target/protocols/" + type + "/needs_master"); if (enable_master_column) m_dialog->fwMemberTree->showColumn(2); else m_dialog->fwMemberTree->hideColumn(2); bool acceptable_failover_type = false; for (list::iterator it=possible_cluster_group_types.begin(); it!=possible_cluster_group_types.end(); ++it) { QString t = it->first; if (t == QString(type.c_str())) { acceptable_failover_type = true; break; } } if (!acceptable_failover_type && possible_cluster_group_types.size()) obj->setStr( "type", possible_cluster_group_types.front().first.toStdString()); m_dialog->obj_name->setText(QString::fromUtf8(g->getName().c_str())); m_dialog->commentKeywords->loadFWObject(o); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); QString grp_type = obj->getStr("type").c_str(); m_dialog->type->clear(); int cp = 0; for (list::iterator i1=possible_cluster_group_types.begin(); i1!=possible_cluster_group_types.end(); i1++,cp++) { m_dialog->type->addItem( i1->second ); if ( grp_type == i1->first ) m_dialog->type->setCurrentIndex(cp); } // init link icons, master firewall is colored m_dialog->fwMemberTree->clear(); string master_iface = g->getStr("master_iface"); for (FWObject::iterator it = g->begin(); it != g->end(); it++) { FWObject *o = FWObjectReference::getObject(*it); if (Interface::isA(o)) { if (master_iface == FWObjectDatabase::getStringId(o->getId())) { addIcon(o, true); } else { addIcon(o); } } } if (!Resources::getTargetCapabilityBool(host_os, "supports_cluster")) { m_dialog->manageMembers->setEnabled(false); m_dialog->manageMembers->setToolTip( QObject::tr("Feature not supported by host OS '%1'").arg(host_os.c_str())); } else { m_dialog->manageMembers->setEnabled(true); m_dialog->manageMembers->setToolTip( QObject::tr("Click here to manage member firewalls of this cluster group.")); } m_dialog->fwMemberTree->resizeColumnToContents(0); m_dialog->fwMemberTree->resizeColumnToContents(1); m_dialog->fwMemberTree->resizeColumnToContents(2); m_dialog->fwMemberTree->resizeColumnToContents(3); QString dlgname = DialogFactory::getClusterGroupOptionsDialogName( ClusterGroup::cast(obj)->getOptionsObject()); if (fwbdebug) qDebug() << "ClusterGroupDialog::loadFWObject dlgname=" << dlgname; m_dialog->editParameters->setEnabled(!dlgname.isEmpty()); init = false; } void ClusterGroupDialog::saveGroupType(FWObject *group) { QString host_os = cluster->getStr("host_OS").c_str(); list possible_cluster_group_types; if (StateSyncClusterGroup::isA(obj)) getStateSyncTypesForOS(host_os, possible_cluster_group_types); if (FailoverClusterGroup::isA(obj)) getFailoverTypesForOS(host_os, possible_cluster_group_types); QString grp_type = m_dialog->type->currentText(); list::iterator li = std::find_if(possible_cluster_group_types.begin(), possible_cluster_group_types.end(), findSecondInQStringPair(grp_type)); if (li != possible_cluster_group_types.end()) group->setStr("type", li->first.toLatin1().constData() ); } void ClusterGroupDialog::addIcon(FWObject *o, bool master) { FWObject *iface = o; assert(Interface::cast(iface)!=NULL); FWObject *fw = Host::getParentHost(iface); // FWObject *fw = Interface::cast(iface)->getParentHost(); // because iface can be subinterface bool valid = cluster->validateMember(Firewall::cast(fw)); QString iface_name = QString::fromUtf8(iface->getName().c_str()); QString fw_name = QString::fromUtf8(fw->getName().c_str()); QString iface_icn_file = (":/Icons/" + iface->getTypeName() + "/icon-ref").c_str(); QString fw_icn_file = (":/Icons/" + fw->getTypeName() + "/icon-ref").c_str(); QPixmap iface_pm; if (!QPixmapCache::find(iface_icn_file, iface_pm)) { iface_pm.load(iface_icn_file); QPixmapCache::insert(iface_icn_file, iface_pm); } QPixmap fw_pm; if (!QPixmapCache::find(fw_icn_file, fw_pm)) { fw_pm.load(fw_icn_file); QPixmapCache::insert(fw_icn_file, fw_pm); } ObjectListViewItem *item = new ObjectListViewItem(m_dialog->fwMemberTree); int col = 0; item->setText(col, fw_name); item->setIcon(col, QIcon(fw_pm)); col++; item->setText(col, iface_name); item->setIcon(col, QIcon(iface_pm)); col++; // note that if enable_master_column==false, this column is hidden // but we still need to create an item in this column. if (master) item->setText(col, tr("Master")); else item->setText(col, tr("")); col++; if (valid) { item->setText(col, "OK"); item->setToolTip( col, tr("Firewall %1 can be used as a member of this cluster").arg(fw->getName().c_str())); } else { item->setText(col, tr("Invalid")); item->setToolTip( col, tr("Firewall %1 can not be used as a member of this cluster\n because its host OS or platform does not match those of the cluster.").arg(fw->getName().c_str())); item->setBackgroundColor(col, QColor(255, 0, 0, 100)); } item->setProperty("type", iface->getTypeName().c_str()); item->setFWObject(iface); } void ClusterGroupDialog::changed() { if (fwbdebug) qDebug() << "ClusterGroupDialog::changed()"; if (!reload) BaseObjectDialog::changed(); } void ClusterGroupDialog::validate(bool *res) { *res = true; if (!validateName(this, obj, m_dialog->obj_name->text())) { *res = false; } } void ClusterGroupDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); ClusterGroup *g = dynamic_cast(new_state); assert(g != NULL); QString oldname = obj->getName().c_str(); new_state->setName(string(m_dialog->obj_name->text().toUtf8().constData())); m_dialog->commentKeywords->applyChanges(new_state); saveGroupType(new_state); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } /* * This method is connected to the "Edit members" button and opens dialog * where user chooses cluster member firewalls and interfaces */ void ClusterGroupDialog::openClusterConfDialog() { try { QWidget *w = DialogFactory::createClusterConfDialog(this, obj); if (w == NULL) { return; // some dialogs may not be implemented yet } QDialog *d = dynamic_cast(w); assert(d != NULL); // connect obj changed signal //connect(d, SIGNAL(membersChanged()), this, SLOT(objectChanged())); if (d->exec() == QDialog::Accepted) { // modal dialog, dialog saves data into the object // update object tree (if members have changed, the object // properties summary text may have to change too) mw->activeProject()->updateObjectInTree(obj, true); // reload object to reflect changes in members loadFWObject(obj); // mark as modified changed(); } delete d; } catch (FWException &ex) { QMessageBox::critical( this, "Firewall Builder", tr("FWBuilder API error: %1").arg(ex.toString().c_str()), tr("&Continue"), QString::null, QString::null, 0, 1); return; } } void ClusterGroupDialog::openObject(QTreeWidgetItem *item) { ObjectListViewItem *otvi = dynamic_cast(item); assert(otvi != NULL); FWObject *o = otvi->getFWObject(); if (o != NULL) { QCoreApplication::postEvent( mw, new showObjectInTreeEvent(o->getRoot()->getFileName().c_str(), o->getId())); } } void ClusterGroupDialog::objectChanged() { reload = true; loadFWObject(obj); reload = false; } /* * this method is connected to the "Edit protocol parameters" button * and opens dialog where user edits state sync and failover * (heartbeat/openais/vrrp/carp/conntrack/etc) protocol parameters. */ void ClusterGroupDialog::openParametersEditor() { FWOptions *gr_opt = ClusterGroup::cast(obj)->getOptionsObject(); QDialog *dlg = dynamic_cast( DialogFactory::createClusterGroupOptionsDialog(this, gr_opt)); if (dlg) { if (dlg->exec() == QDialog::Accepted) { // modal dialog, dialog saves data into the object // update object tree (if protocol type has changed, the // object properties summary text may have to change too) mw->activeProject()->updateObjectInTree(obj, true); changed(); } delete dlg; } } fwbuilder-5.1.0.3599/src/libgui/SSHIOS.cpp0000644000175000017500000000646411733011756020566 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "SSHIOS.h" #include using namespace std; SSHIOS::SSHIOS(QWidget *_par, const QString &_h, const QStringList &args, const QString &_p, const QString &_ep, const std::list &_in) : SSHCisco(_par,_h,args,_p,_ep,_in) { normal_prompt=">$"; fwb_prompt="--**--**--"; enable_prompt="#$"; pwd_prompt_1="'s password: $"; pwd_prompt_2="Password: "; epwd_prompt="Password: "; ssh_pwd_prompt="'s password: "; ssoft_config_prompt="> "; putty_pwd_prompt="Password: "; passphrase_prompt="Enter passphrase for key "; errorsInit.clear(); errorsInit.push_back("Permission denied"); errorsInit.push_back("Invalid password"); errorsInit.push_back("Access denied"); errorsInit.push_back("Unable to authenticate"); errorsInit.push_back("Too many authentication failures"); errorsLoggedin.clear(); errorsLoggedin.push_back("Invalid password"); errorsLoggedin.push_back("ERROR: "); errorsLoggedin.push_back("Not enough arguments"); errorsLoggedin.push_back("cannot find"); errorsEnabledState.clear(); errorsEnabledState.push_back("ERROR: "); errorsEnabledState.push_back("Type help"); errorsEnabledState.push_back("Not enough arguments"); errorsEnabledState.push_back("invalid input detected"); errorsEnabledState.push_back("Invalid"); errorsEnabledState.push_back("cannot find"); } SSHIOS::~SSHIOS() { } // IOS state machine needs to be able to deal with // "reload in ... " command void SSHIOS::stateMachine() { if (checkForErrors()) return; switch (state) { case SCHEDULE_RELOAD_DIALOG: if ( cmpPrompt(stdoutBuffer, QRegExp("System config.* modified\\. Save?")) ) { stdoutBuffer=""; proc->write( "no\n" ); break; } if ( cmpPrompt(stdoutBuffer,QRegExp("Proceed with reload?")) ) { stdoutBuffer=""; proc->write( "y\n" ); state = ENABLE; break; } break; case PUSHING_CONFIG: if ( cmpPrompt(stdoutBuffer, QRegExp("Destination filename [.*]?")) ) { stdoutBuffer=""; proc->write("\n"); // accept default file name } else SSHCisco::stateMachine(); break; default: SSHCisco::stateMachine(); break; } } fwbuilder-5.1.0.3599/src/libgui/dynamicgroupdialog_q.ui0000644000175000017500000000772311733011756023611 0ustar sylvestresylvestre DynamicGroupDialog_q 0 0 934 269 Form QFrame::StyledPanel QFrame::Raised Name: Match Criteria: Qt::Horizontal 40 20 Add Match Qt::Horizontal 40 20 Matching Objects: 1 0 0 commentKeywords frame CommentKeywords QWidget
CommentKeywords.h
1
ObjectListView QTreeWidget
ObjectListView.h
addButton clicked() DynamicGroupDialog_q addMatchClicked() 159 235 466 134
fwbuilder-5.1.0.3599/src/libgui/secuwallAdvancedDialog.cpp0000644000175000017500000002272611733011756024142 0ustar sylvestresylvestre/* * secuwallAdvancedDialog.cpp - secuwall advanced host OS dialog implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "../../config.h" #include "global.h" #include "platforms.h" #include "secuwallAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "Help.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; secuwallAdvancedDialog::~secuwallAdvancedDialog() { delete m_dialog; } secuwallAdvancedDialog::secuwallAdvancedDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::secuwallAdvancedDialog_q; m_dialog->setupUi(this); obj=o; QStringList slm; string platform = obj->getStr("platform"); string description = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/description"); setWindowTitle(QObject::tr("%1 advanced settings").arg(description.c_str())); FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); data.registerOption(m_dialog->logTCPseq, fwoptions, "log_tcp_seq"); data.registerOption(m_dialog->logTCPopt, fwoptions, "log_tcp_opt"); data.registerOption(m_dialog->logIPopt, fwoptions, "log_ip_opt"); data.registerOption(m_dialog->logNumsyslog, fwoptions, "use_numeric_log_levels"); slm = getLogLevels(obj->getStr("platform").c_str()); m_dialog->logLevel->clear(); m_dialog->logLevel->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> logLevel, fwoptions, "log_level", slm); data.registerOption(m_dialog->useULOG, fwoptions, "use_ULOG"); data.registerOption(m_dialog->cprange, fwoptions, "ulog_cprange"); data.registerOption(m_dialog->qthreshold, fwoptions, "ulog_qthreshold"); data.registerOption(m_dialog->nlgroup, fwoptions, "ulog_nlgroup"); data.registerOption(m_dialog->logprefix, fwoptions, "log_prefix"); slm=getLimitSuffixes(obj->getStr("platform").c_str()); m_dialog->logLimitSuffix->clear(); m_dialog->logLimitSuffix->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> logLimitSuffix, fwoptions, "limit_suffix", slm); data.registerOption(m_dialog->logLimitVal, fwoptions, "limit_value"); data.registerOption(m_dialog->logAll, fwoptions, "log_all"); data.registerOption(m_dialog->compiler, fwoptions, "compiler"); data.registerOption(m_dialog->compilerArgs, fwoptions, "cmdline"); data.registerOption(m_dialog->assumeFwIsPartOfAny, fwoptions, "firewall_is_part_of_any_and_networks"); data.registerOption(m_dialog->acceptSessions, fwoptions, "accept_new_tcp_with_no_syn"); data.registerOption(m_dialog->dropInvalid, fwoptions, "drop_invalid"); data.registerOption(m_dialog->logInvalid, fwoptions, "log_invalid"); data.registerOption(m_dialog->acceptESTBeforeFirst, fwoptions, "accept_established"); data.registerOption(m_dialog->bridge, fwoptions, "bridging_fw"); data.registerOption(m_dialog->shadowing, fwoptions, "check_shading"); data.registerOption(m_dialog->emptyGroups, fwoptions, "ignore_empty_groups"); data.registerOption(m_dialog->localNAT, fwoptions, "local_nat"); data.registerOption(m_dialog->clampMSStoMTU, fwoptions, "clamp_mss_to_mtu"); slm = getActionsOnReject(obj->getStr("platform").c_str()); m_dialog->actionOnReject->clear(); m_dialog->actionOnReject->addItems(getScreenNames(slm)); data.registerOption(m_dialog-> actionOnReject, fwoptions,"action_on_reject", slm); data.registerOption(m_dialog->mgmt_ssh, fwoptions, "mgmt_ssh"); data.registerOption(m_dialog->mgmt_addr, fwoptions, "mgmt_addr"); data.registerOption(m_dialog->add_mgmt_ssh_rule_when_stoped, fwoptions, "add_mgmt_ssh_rule_when_stoped"); data.registerOption(m_dialog->addVirtualsforNAT, fwoptions, "manage_virtual_addr"); data.registerOption(m_dialog->configureInterfaces, fwoptions, "configure_interfaces"); data.registerOption(m_dialog->iptDebug, fwoptions, "debug"); data.registerOption(m_dialog->verifyInterfaces, fwoptions, "verify_interfaces"); data.registerOption(m_dialog->allowReboot, fwoptions, "allow_reboot"); data.registerOption(m_dialog->iptablesRestoreActivation, fwoptions, "use_iptables_restore"); data.registerOption(m_dialog->altAddress, fwoptions, "altAddress"); data.registerOption(m_dialog->sshArgs, fwoptions, "sshArgs"); data.registerOption(m_dialog->scpArgs, fwoptions, "scpArgs"); data.registerOption(m_dialog->activationCmd, fwoptions, "activationCmd"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText(pis->getCommand().c_str()); m_dialog->installScriptArgs->setText(pis->getArguments().c_str()); /* page "Prolog/Epilog" */ data.registerOption(m_dialog->prolog_script, fwoptions, "prolog_script"); QStringList prologPlaces_ipt; prologPlaces_ipt.push_back(QObject::tr("on top of the script")); prologPlaces_ipt.push_back("top"); prologPlaces_ipt.push_back(QObject::tr("after interface configuration")); prologPlaces_ipt.push_back("after_interfaces"); // bug #2820840: can't put prolog "after policy reset" if iptables-restore if (!fwoptions->getBool("use_iptables_restore")) { prologPlaces_ipt.push_back(QObject::tr("after policy reset")); prologPlaces_ipt.push_back("after_flush"); } m_dialog->prologPlace->clear(); m_dialog->prologPlace->addItems(getScreenNames(prologPlaces_ipt)); data.registerOption(m_dialog-> prologPlace, fwoptions, "prolog_place", prologPlaces_ipt); data.registerOption(m_dialog->epilog_script, fwoptions, "epilog_script"); data.loadAll(); /* Now set sane values after loading data */ /* secuwall supports currently only LOG, not ULOG */ m_dialog->useLOG->setChecked(true); switchLOG_ULOG(); m_dialog->useULOG->setEnabled(false); m_dialog->tabWidget->setCurrentIndex(0); } void secuwallAdvancedDialog::switchLOG_ULOG() { m_dialog->useLOG->setChecked(!m_dialog->useULOG->isChecked()); if (m_dialog->useLOG->isChecked()) m_dialog->logTargetStack->setCurrentIndex(0); else m_dialog->logTargetStack->setCurrentIndex(1); } /* * store all data in the object */ void secuwallAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd(new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); /********************* data for fwbd and install script **************/ PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); // find first interface marked as "management" const InetAddr *mgmt_addr = Firewall::cast(obj)->getManagementAddress(); if (mgmt_addr) { mgmt->setAddress(*mgmt_addr); } pis->setCommand(m_dialog->installScript->text().toLatin1().constData()); pis->setArguments(m_dialog->installScriptArgs->text().toLatin1().constData()); if (!cmd->getOldState()->cmp(new_state, true)) { project->undoStack->push(cmd.release()); } QDialog::accept(); } void secuwallAdvancedDialog::reject() { QDialog::reject(); } void secuwallAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->prolog_script->toPlainText(), true, tr("Script Editor" )); if (edt.exec() == QDialog::Accepted) { m_dialog->prolog_script->setText(edt.text()); } } void secuwallAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->epilog_script->toPlainText(), true, tr("Script Editor" )); if (edt.exec() == QDialog::Accepted) { m_dialog->epilog_script->setText(edt.text()); } } void secuwallAdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Firewall platform: iptables"); h->setSource(QUrl("secuwallAdvancedDialog.html#" + anchor)); h->show(); h->raise(); } fwbuilder-5.1.0.3599/src/libgui/MDIEventFilter.cpp0000644000175000017500000000053311733011756022326 0ustar sylvestresylvestre#include "MDIEventFilter.h" #include #include #include #include bool MDIEventFilter::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::Wheel) { event->accept(); return true; } else { return QObject::eventFilter(obj, event); } } fwbuilder-5.1.0.3599/src/libgui/ProjectPanel_file_ops.cpp0000644000175000017500000014001711733011756024015 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com refactoring and bugfixes: vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "events.h" #include #include #include #include #include #include #include #include "fwbuilder/Constants.h" #include "ProjectPanel.h" #include #include "FWWindow.h" #include "RCS.h" #include "filePropDialog.h" #include "FWBSettings.h" #include "RCSFilePreview.h" #include "FindObjectWidget.h" #include "FWObjectClipboard.h" #include "upgradePredicate.h" #include "ObjConflictResolutionDialog.h" #include "LibExportDialog.h" #include "longTextDialog.h" #include "FWBTree.h" #include "ObjectTreeView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "memcheck.h" #define LONG_ERROR_CUTOFF 1024 using namespace Ui; using namespace libfwbuilder; using namespace std; bool ProjectPanel::saveIfModified(bool include_discard_button) { if (fwbdebug) qDebug() << "ProjectPanel::saveIfModified()"; if (db() && db()->isDirty()) // if (db() && db()->isDirty() && rcs && !rcs->getFileName().isEmpty()) { QString message = "Some objects have been modified but not saved.\n"; message += "Do you want to save "; message += rcs->getFileName(); message += " changes now ?"; if (include_discard_button) { switch (QMessageBox::information(this, "Firewall Builder", message, tr("&Save"), tr("&Discard"), tr("&Cancel"), 0, // Enter = button 0 2 ) ) // Escape == button 2 { case 0: save(); break; case 1: // discard db()->setDirty(false); break; case 2: // cancel return false; } } else { switch (QMessageBox::information(this, "Firewall Builder", message, tr("&Save"),tr("&Cancel"), 0, // Enter = button 0 1 ) ) // Escape == button 1 { case 0: save(); break; case 1: // cancel return false; } } } return true; } QString ProjectPanel::chooseNewFileName(const QString &fname, const QString &title) { // when file open dialog is created using static function // QFileDialog::getSaveFileName, its behavior is different on // Linux and Mac (did not check on windows) // Native dialog usd by Qt on Mac automatically adds .fwb suffix // to the file name user enters if it does not have any suffix. It // checks for the conflicts with exitsing files _after_ the suffix // has been added. On Linux dialog created by the static function // QFileDialog::getSaveFileName does not add suffix and checks for // conflicts using the name without one. Since I used to add // suffix here but did not check for the conflict again after // that, it was possible for the user to enter name with no suffix // and that way overwrite old file without warning. Will avoid // static fucntion and instead build dialog manually and use // setDefaultSuffix() to enforce suffix. QFileDialog fd(this); fd.setFileMode(QFileDialog::AnyFile); fd.setDefaultSuffix("fwb"); fd.setFilter(tr( "FWB Files (*.fwb);;All Files (*)" ) ); fd.setWindowTitle(title); fd.setDirectory(st->getOpenFileDir(fname)); fd.setAcceptMode(QFileDialog::AcceptSave); QString fn; if (fd.exec()) { QStringList fileNames = fd.selectedFiles(); fn = fileNames.front(); QFileInfo finfo(fn); if (finfo.suffix().isEmpty()) fn += ".fwb"; st->setOpenFileDir(fn); } return fn; } void ProjectPanel::fileProp() { if (rcs!=NULL) { filePropDialog fpd(this,rcs); fpd.setPrinter(mainW->getPrinter()); fpd.exec(); } } bool ProjectPanel::fileNew() { if (fwbdebug) qDebug("ProjectPanel::fileNew()"); QString nfn = chooseNewFileName( st->getWDir(), tr("Choose name and location for the new file")); if ( !nfn.isEmpty() ) { //if (!saveIfModified() || !checkin(true)) return; if (!systemFile && rcs!=NULL) fileClose(); // fileClose calls load(this) else loadStandardObjects(); visibleFirewall = NULL; setFileName(nfn); save(); setupAutoSave(); loadFirstNonStandardLib(); QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); } if (fwbdebug) qDebug("ProjectPanel::fileNew() rcs=%p rcs->getFileName()='%s'", rcs, rcs == 0 ? "" : rcs->getFileName().toAscii().constData()); return (rcs!=NULL); } bool ProjectPanel::loadFile(const QString &fileName, bool load_rcs_head) { if (fwbdebug) qDebug() << "ProjectPanel::loadFile fileName=" << fileName.toLocal8Bit() << "load_rcs_head=" << load_rcs_head; RCSFilePreview fp(this); bool hasRCS = fp.showFileRLog(fileName); // class RCS automatically selected head revision when it opens // file and reads RCS log. User can choose different revision // using RCSFilePreview. If they do, RCSFilePreview::getSelectedRev() // returns selected revision. However if they do not choose, or // dialog is never executed, getSelectedRev() returns head. // if load_rcs_head == true, we do not run RCSFilePreview dialog // which meand it will return head revision automatically. int dlg_res = QDialog::Accepted; if (hasRCS && !load_rcs_head) dlg_res = fp.exec(); if (dlg_res!=QDialog::Accepted) return false; if (!saveIfModified() || !checkin(true)) return false; if (!systemFile && rcs!=NULL) { if (mw->isEditorVisible()) mw->hideEditor(); reset(); } //try to get simple rcs instance from RCS preview RCS *new_rcs = fp.getSelectedRev(); //if preview cannot give RCS, //get a new RCS from file dialog if (new_rcs==NULL) new_rcs = new RCS(fileName); if (new_rcs==NULL) return false; try { new_rcs->co(); if (loadFromRCS(new_rcs)) { if (new_rcs->isTemp()) unlink(new_rcs->getFileName().toLocal8Bit().constData()); st->setOpenFileDir(getFileDir(fileName)); return true; } } catch (FWException &ex) { return false; } return false; } void ProjectPanel::fileClose() { if (fwbdebug) qDebug("ProjectPanel::fileClose(): start"); if (mw->isEditorVisible()) mw->hideEditor(); if (!saveIfModified() || !checkin(true)) return; reset(); mdiWindow->close(); mw->setCompileAndInstallActionsEnabled(false); if (fwbdebug) qDebug("ProjectPanel::fileClose(): done"); } /* * slot that is called by a timer if user turned on auto-save feature * using controls in the Preferences dialog. Need to save only if data * was modified (flag "dirty" is set). */ void ProjectPanel::autoSave() { if (db() && db()->isDirty() && rcs && !rcs->getFileName().isEmpty()) fileSave(); } void ProjectPanel::fileSave() { save(); } void ProjectPanel::fileSaveAs() { if (mw->isEditorVisible()) mw->hideEditor(); /* we need to save data into the current file before we save it into a * new file, provided we do have current file if (!systemFile && rcs && !rcs->isRO() && !rcs->isTemp() && !rcs->getFileName().isEmpty() && (!saveIfModified() || !checkin(true)) ) return; */ /* need to close the file without asking and saving, then reopen it again */ QString oldFileName = rcs->getFileName(); QString newFileName = chooseNewFileName( oldFileName, tr("Choose name and location for the file")); if (!newFileName.isEmpty()) { db()->setDirty(false); // so it wont ask if user wants to save rcs->abandon(); if (rcs!=NULL) delete rcs; rcs = new RCS(""); setFileName(newFileName); save(); mw->updateOpenRecentMenu(newFileName); } } void ProjectPanel::fileCommit() { save(); if (!checkin(true)) return; rcs->co(); } /* * discard changes done to the file and check out clean copy of the * head revision from RCS */ void ProjectPanel::fileDiscard() { if (QMessageBox::warning(this, "Firewall Builder", tr("This operation discards all changes that have been saved " "into the file so far, closes it and replaces it with a clean " "copy of its head revision from RCS." "\n" "All changes will be lost if you do this.\n"), tr("&Discard changes"), tr("&Cancel"), QString::null, 1 )==0 ) { /* need to close the file without asking and saving, then * reopen it again */ QString fname = rcs->getFileName(); db()->setDirty(false); // so it wont ask if user wants to save rcs->abandon(); /* do everything fileClose() does except do not close mdiWindow * because we'll need it again to reopen the file into */ if (mw->isEditorVisible()) mw->hideEditor(); if (rcs) delete rcs; rcs=NULL; FWObjectClipboard::obj_clipboard->clear(); firewalls.clear(); visibleFirewall = NULL; visibleRuleSet = NULL; clearFirewallTabs(); clearObjects(); /* loadFile calls fileClose, but only if file is currently * open, which it isn't because we reset rcs to NULL */ loadFile(fname, false); } } void ProjectPanel::fileAddToRCS() { if (!saveIfModified()) return; if (rcs && rcs->isCheckedOut()) return; try { if (!rcs->isInRCS() && !rcs->isRO()) { rcs->add(); rcs->co(); QMessageBox::information( this,"Firewall Builder", tr("File %1 has been added to RCS.").arg(rcs->getFileName()), tr("&Continue"), QString::null,QString::null, 0, 1 ); } } catch (FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Error adding file to RCS:\n%1").arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); } QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); } void ProjectPanel::fileImport() { resetFD(); QString fname = QFileDialog::getOpenFileName( mainW, tr("Choose a file to import"), st->getWDir(), "FWB library files (*.fwl);;FWB Files (*.fwb);;All Files (*)"); if (fname.isEmpty()) return; // Cancel - keep working with old file FWObject *new_lib = loadLibrary( fname.toLocal8Bit().constData() ); loadObjects(); m_panel->om->openLib(new_lib); } void ProjectPanel::fileCompare() { resetFD(); QMessageBox initial_question( QMessageBox::Information, "Firewall Builder", tr("This operation inspects two data files (either .fwb or .fwl) and finds conflicting objects. Conflicting objects have the same internal ID but different attributes. Two data files can not be merged, or one imported into another, if they contain such objects. This operation also helps identify changes made to objects in two copies of the same data file.

This operation does not find objects present in one file but not in the other, such objects present no problem for merge or import operations.

This operation works with two external files, neither of which needs to be opened in the program. Currently opened data file is not affected by this operation and objects in the tree do not change.

Do you want to proceed ?"), QMessageBox::Yes | QMessageBox::No); initial_question.setTextFormat( Qt::RichText ); if (initial_question.exec() != QMessageBox::Yes) return; QString fname1 = QFileDialog::getOpenFileName( mainW, tr("Choose the first file"), st->getOpenFileDir(), "FWB files (*.fwb);;FWB Library Files (*.fwl);;All Files (*)"); if (fname1.isEmpty()) return; // Cancel st->setOpenFileDir(fname1); QString fname2 = QFileDialog::getOpenFileName( mainW, tr("Choose the second file"), st->getOpenFileDir(), "FWB files (*.fwb);;FWB Library Files (*.fwl);;All Files (*)"); if (fname2.isEmpty()) return; // Cancel st->setOpenFileDir(fname2); MessageBoxUpgradePredicate upgrade_predicate(mainW); FWObjectDatabase *db1; FWObjectDatabase *db2; FWObject *dobj; try { db1 = new FWObjectDatabase(); db1->load(fname1.toLocal8Bit().constData(), &upgrade_predicate, Constants::getDTDDirectory()); dobj = db1->findInIndex(FWObjectDatabase::DELETED_OBJECTS_ID); if (dobj) db1->remove(dobj, false); } catch(FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Error loading file %1:\n%2"). arg(fname1).arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); return; } try { db2 = new FWObjectDatabase(); db2->load(fname2.toLocal8Bit().constData(), &upgrade_predicate, Constants::getDTDDirectory()); dobj = db2->findInIndex(FWObjectDatabase::DELETED_OBJECTS_ID); if (dobj) db2->remove(dobj, false); } catch(FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Error loading file %1:\n%2"). arg(fname2).arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); return; } try { // CompareObjectsDialog is just like ObjConflictResolutionDialog // except it always returns 'accepted' and keeps record // of all object differences so we can print report in the end CompareObjectsDialog cod(this); db1->merge(db2, &cod); list report = cod.getReport(); delete db1; delete db2; ostringstream str; str << cod.getNumberOfConflicts(); QMessageBox mb( QMessageBox::Information, "Firewall Builder", tr("Total number of conflicting objects: %1.\nDo you want to generate report?").arg(str.str().c_str()), QMessageBox::Yes | QMessageBox::No); if (mb.exec() == QMessageBox::Yes) { // save report to a file QString fn = QFileDialog::getSaveFileName( this, tr("Choose name and location for the report file"), st->getOpenFileDir(fname1), tr( "TXT Files (*.txt);;All Files (*)" )); if (fn.isEmpty()) return; // Cancel st->setOpenFileDir(fn); if (!fn.endsWith(".txt")) fn += ".txt"; if (fwbdebug) qDebug() << QString("Saving report to %1").arg(fn); QFile report_file(fn); if (report_file.open(QIODevice::WriteOnly)) { QTextStream report_stream(&report_file); for (list::iterator i=report.begin(); i!=report.end(); ++i) { report_stream << *i; } report_file.close(); } else { QMessageBox::critical( this,"Firewall Builder", tr("Can not open report file for writing. File '%1'").arg(fn), tr("&Continue"), QString::null,QString::null, 0, 1 ); } } } catch(FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Unexpected error comparing files %1 and %2:\n%3"). arg(fname1).arg(fname2).arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); } } void ProjectPanel::fileExport() { LibExportDialog ed; list selectedLibs; map::iterator i; int lib_idx = -1; do { if (ed.exec()!=QDialog::Accepted) return; QList selitems = ed.m_dialog->libs->selectedItems(); for (i=ed.mapOfLibs.begin(); i!=ed.mapOfLibs.end(); i++) if (selitems.contains(ed.m_dialog->libs->item(i->first))) selectedLibs.push_back(i->second); lib_idx=ed.m_dialog->libs->currentRow (); if (lib_idx<0 || selectedLibs.size()==0) { QMessageBox::critical( this,"Firewall Builder", tr("Please select a library you want to export."), "&Continue", QString::null,QString::null, 0, 1 ); return; } } while (!exportLibraryTest(selectedLibs)); FWObject *selLib = ed.mapOfLibs[ lib_idx ]; QString path = st->getOpenFileDir() + QString::fromUtf8(selLib->getName().c_str()) + ".fwl"; resetFD(); QString fname = QFileDialog::getSaveFileName( this, "Choose a filename to save under", path, "Firewall Builder library files (*.fwl)"); if (fname.isEmpty()) return; if (QFile::exists(fname) && QMessageBox::warning( this,"Firewall Builder", tr("The file %1 already exists.\nDo you want to overwrite it ?") .arg(fname), tr("&Yes"), tr("&No"), QString::null, 0, 1 )==1 ) return; st->setOpenFileDir(path); exportLibraryTo(fname,selectedLibs,ed.m_dialog->exportRO->isChecked()); } bool ProjectPanel::exportLibraryTest(list &selectedLibs) { /* VERY IMPORTANT: External library file must be self-contained, * otherwise it can not be exported. * * check if selected libraries have references to objects in other * libraries (not exported to the same file). Exporting such libraries * pulls in other ones because of these references. This is confusing * because it means we end up with multiple copies of such objects (in * exported library file and in user's data file). When user imports * this library and opens their file, it is impossible to say which * library an object belongs to. * * This is prohibited. We check if exported set of libraries has such * references and refuse to export it. The user is supposed to clean * it up by either moving objects into the library they are trying to * export, or by rearranging objects. The only exception for this is * library "Standard", which is assumed to be always present so we can * have references to objects in it. */ QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); list externalRefs; for (list::iterator i=selectedLibs.begin(); i!=selectedLibs.end(); ++i) findExternalRefs( *i, *i, externalRefs); QApplication::restoreOverrideCursor(); if (fwbdebug) qDebug("LibExportDialog::accept externalRefs.size()=%d", int(externalRefs.size()) ); /* * if externalRefs.size()!=0, then there were some references pointing * outside of the libraries we export. Some of these references may * point at other libraries we export, lets find these. */ list externalRefs2; for (list::iterator i=externalRefs.begin(); i!=externalRefs.end(); ++i) { FWObject *tgt = (*i)->getPointer(); FWObject *tgtlib = tgt->getLibrary(); if (std::find(selectedLibs.begin(),selectedLibs.end(),tgtlib)!=selectedLibs.end()) continue; externalRefs2.push_back(*i); } if (externalRefs2.size()!=0) { QString objlist = ""; QString s = ""; for (list::iterator i=externalRefs2.begin(); i!=externalRefs2.end(); ++i) { FWReference *robj = *i; FWObject *selLib = robj->getLibrary(); FWObject *pp = robj->getParent(); FWObject *tgt = robj->getPointer(); FWObject *tgtlib = tgt->getLibrary(); if (fwbdebug) { qDebug("LibExportDialog::accept tgt: %s pp_type: %s lib: %s", tgt->getName().c_str(), pp->getTypeName().c_str(), tgtlib->getName().c_str()); } if (std::find(selectedLibs.begin(),selectedLibs.end(),tgtlib)!=selectedLibs.end()) continue; if (RuleElement::cast(pp)!=NULL) { FWObject *fw = pp; FWObject *rule = pp; FWObject *ruleset = pp; FWObject *iface = pp; while (rule!=NULL && Rule::cast(rule)==NULL) rule=rule->getParent(); while (ruleset!=NULL && RuleSet::cast(ruleset)==NULL) ruleset=ruleset->getParent(); while (iface!=NULL && Interface::cast(iface)==NULL) iface=iface->getParent(); while (fw!=NULL && Firewall::cast(fw)==NULL) fw=fw->getParent(); s = QObject::tr("Library %1: Firewall '%2' (%3 rule #%4) uses " "object '%5' from library '%6'") .arg(selLib->getName().c_str()) .arg(fw->getName().c_str()) .arg(ruleset->getTypeName().c_str()) .arg(Rule::cast(rule)->getPosition()) .arg(tgt->getName().c_str()) .arg(tgtlib->getName().c_str()); } else { s = QObject::tr("Library %1: Group '%2' uses object '%3' from library '%4'") .arg(selLib->getName().c_str()) .arg(pp->getName().c_str()) .arg(tgt->getName().c_str()) .arg(tgtlib->getName().c_str()); } s = s + "\n"; if (fwbdebug) qDebug() << s; objlist = objlist + s; } longTextDialog ltd( this, tr("A library that you are trying to export contains references\n" "to objects in the other libraries and can not be exported.\n" "The following objects need to be moved outside of it or\n" "objects that they refer to moved in it:"), objlist ); ltd.exec(); return false; } return true; } void ProjectPanel::exportLibraryTo(QString fname,list &selectedLibs, bool rof) { QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); FWObjectDatabase *ndb = db()->exportSubtree( selectedLibs ); QApplication::restoreOverrideCursor(); if (rof) { for (list::iterator i=selectedLibs.begin(); i!=selectedLibs.end(); ++i) { FWObject *nlib= ndb->findInIndex( (*i)->getId() ); if (nlib && nlib->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID) nlib->setReadOnly( true ); } } try { xmlSetCompressMode(st->getCompression() ? 9 : 0); ndb->saveFile( fname.toLocal8Bit().constData() ); } catch (FWException &ex) { /* error saving the file. Since XMLTools does not return any useful * error message in the exception, let's check for obvious problems here */ QString err; if (access( fname.toLocal8Bit().constData(), W_OK)!=0 && errno==EACCES) err=QObject::tr("File is read-only"); QMessageBox::critical( this,"Firewall Builder", QObject::tr("Error saving file %1: %2") .arg(fname).arg(err), "&Continue", QString::null, QString::null, 0, 1 ); } } void ProjectPanel::setupAutoSave() { if ( st->getBool("Environment/autoSaveFile") && rcs!=NULL && rcs->getFileName()!="") { int p = st->getInt("Environment/autoSaveFilePeriod"); autosaveTimer->start( p*1000*60 ); connect( autosaveTimer, SIGNAL(timeout()), this, SLOT(autoSave()) ); } else autosaveTimer->stop(); } void ProjectPanel::findExternalRefs(FWObject *lib, FWObject *root, list &extRefs) { FWReference *ref=FWReference::cast(root); if (ref!=NULL) { FWObject *plib = ref->getPointer()->getLibrary(); if ( plib->getId()!=FWObjectDatabase::STANDARD_LIB_ID && plib->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID && plib!=lib ) extRefs.push_back(ref); return; } else { for (FWObject::iterator i=root->begin(); i!=root->end(); i++) findExternalRefs(lib, *i, extRefs); } } /** * Load library or several libraries from an external file. Return * pointer to the last new imported library. */ FWObject* ProjectPanel::loadLibrary(const string &libfpath) { MessageBoxUpgradePredicate upgrade_predicate(mainW); FWObject *last_new_lib = NULL; try { FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(libfpath, &upgrade_predicate, Constants::getDTDDirectory()); FWObject *dobj = ndb->findInIndex(FWObjectDatabase::DELETED_OBJECTS_ID); if (dobj) ndb->remove(dobj, false); set duplicate_ids; db()->findDuplicateIds(ndb, duplicate_ids); map id_mapping; for (set::iterator it=duplicate_ids.begin(); it!=duplicate_ids.end(); ++it) { FWObject *obj = ndb->findInIndex(*it); assert(obj!=NULL); int new_id = FWObjectDatabase::generateUniqueId(); obj->setId(new_id); id_mapping[*it] = new_id; // cerr << "Duplicate ID: " << *it // << " " << FWObjectDatabase::getStringId(*it) // << obj->getPath() // << endl; } ndb->fixReferences(ndb, id_mapping); int new_lib_id = -1; // check for duplicate library names FWObjectTypedChildIterator it2 = ndb->findByType(Library::TYPENAME); for (; it2!=it2.end(); ++it2) { QString new_name = m_panel->om->makeNameUnique( db(), QString::fromUtf8((*it2)->getName().c_str()), Library::TYPENAME); (*it2)->setName(string(new_name.toUtf8())); if ((*it2)->getId() != FWObjectDatabase::STANDARD_LIB_ID) new_lib_id = (*it2)->getId(); } MergeConflictRes mcr(this); db()->merge(ndb, &mcr); delete ndb; last_new_lib = db()->findInIndex(new_lib_id); } catch(FWException &ex) { QString error_txt = ex.toString().c_str(); if (error_txt.length() > LONG_ERROR_CUTOFF) { error_txt.truncate(LONG_ERROR_CUTOFF); error_txt += "\n\n" + tr("(Long error message was truncated)"); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load file %1.\n" "The file has not been loaded. Error:\n%2"). arg(libfpath.c_str()).arg(error_txt), tr("&Continue"), QString::null,QString::null, 0, 1 ); } return last_new_lib; } /* * Load standard library objects */ void ProjectPanel::loadStandardObjects() { if (fwbdebug) qDebug("ProjectPanel::load(): start"); editingStandardLib = false; editingTemplateLib = false; MessageBoxUpgradePredicate upgrade_predicate(mainW); resetFD(); try { // need to drop read-only flag on the database before I load new objects if (objdb) { objdb->destroyChildren(); delete objdb; } objdb = new FWObjectDatabase(); objdb->setReadOnly( false ); mw->showStatusBarMessage(tr("Loading system objects...")); // always load system objects if (fwbdebug) qDebug("ProjectPanel::load(): sysfname = %s", Constants::getStandardObjectsFilePath().c_str()); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); if (fwbdebug) qDebug("ProjectPanel::load(): create User library"); FWObject *userLib = FWBTree().createNewLibrary(objdb); userLib->setName("User"); userLib->setStr("color","#d2ffd0"); objdb->setDirty(false); objdb->setFileName(""); createRCS(""); //setWindowTitle(getPageTitle()); QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); loadObjects(); setupAutoSave(); time_t last_modified = objdb->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): done last_modified=%s dirty=%d", ctime(&last_modified), objdb->isDirty()); } catch(FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Error loading file:\n%1").arg(ex.toString().c_str()), tr("&Continue"), QString::null,QString::null, 0, 1 ); } } bool ProjectPanel::loadFromRCS(RCS *_rcs) { resetFD(); editingStandardLib = false; editingTemplateLib = false; bool forceSave=false; // use this flag to force 'save' operation if file should be renamed MessageBoxUpgradePredicate upgrade_predicate(mainW); assert(_rcs!=NULL); rcs = _rcs; try { /* load the data file */ systemFile = false; clearObjects(); if (objdb) { objdb->destroyChildren(); delete objdb; } objdb = new FWObjectDatabase(); // need to drop read-only flag on the database before I load new objects objdb->setReadOnly( false ); // always loading system objects mw->showStatusBarMessage(tr("Loading system objects...") ); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); // objects from a data file are in database ndb mw->showStatusBarMessage(tr("Reading and parsing data file...")); FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(rcs->getFileName().toLocal8Bit().constData(), &upgrade_predicate,Constants::getDTDDirectory()); time_t oldtimestamp = ndb->getTimeLastModified(); /* loadingLib is true if user wants to open a library or master library file */ bool loadingLib = editingLibrary(); if (fwbdebug) { list ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { qDebug("* Found library %s %s in the data file", FWObjectDatabase::getStringId((*i)->getId()).c_str(), (*i)->getName().c_str() ); } } /* if user opens library file, clear read-only flag so they can edit it */ if (loadingLib) { list ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if ((*i)->getId()==FWObjectDatabase::STANDARD_LIB_ID) editingStandardLib=true; if ((*i)->getId()==FWObjectDatabase::TEMPLATE_LIB_ID) editingTemplateLib=true; (*i)->setReadOnly( false ); } } mw->showStatusBarMessage(tr("Merging with system objects...") ); MergeConflictRes mcr(mainW); objdb->merge(ndb, &mcr); ndb->destroyChildren(); delete ndb; objdb->setFileName(rcs->getFileName().toLocal8Bit().constData()); objdb->resetTimeLastModified(oldtimestamp); objdb->setDirty(false); if (fwbdebug) { qDebug("* Merge is done"); list ll = db()->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { qDebug("* Library %s %s in the data file", FWObjectDatabase::getStringId((*i)->getId()).c_str(), (*i)->getName().c_str() ); } } /* this is a hack: 'Standard' library should be read-only. I * have too many files I already converted to the new API/DTD * and I am too lazy to convert them again, so I patch it up * here. * * However, if I am editing standard library, it should not be * read-only. */ FWObject *slib = objdb->findInIndex(FWObjectDatabase::STANDARD_LIB_ID); if (slib!=NULL ) { if (fwbdebug) qDebug("standard library read-only status: %d, " "editingStandardLib: %d", slib->isReadOnly(), editingStandardLib); slib->setReadOnly(! editingStandardLib); } /* if the file name has an old extension .xml, change it to .fwb and * warn the user */ QString fn = rcs->getFileName(); QFileInfo ofinfo(fn); if ( ofinfo.suffix()=="xml") { if (fwbdebug) { qDebug("Need to rename file: %s", fn.toAscii().constData()); qDebug(" dirPath: %s", ofinfo.dir().absolutePath().toAscii().constData()); qDebug(" filePath: %s", ofinfo.absoluteFilePath().toAscii().constData()); } QString newFileName = ofinfo.dir().absolutePath() + "/" + ofinfo.completeBaseName() + ".fwb"; bool needToRename = true; /* need these dances with symlinks to fix bug #1008956: * "Existing .fwb file gets overwritten if has wrong * extension" */ QFileInfo nfinfo(newFileName); if (nfinfo.exists() && ofinfo.isSymLink() && ofinfo.readLink()==newFileName) { // .xml file is a symlink pointing at .fwb file // no need to rename needToRename = false; } if (needToRename) { if (nfinfo.exists()) { /* .fwb file exists but .xml is not a symlink * .fwb is a separate file with the same name. * * tell the user we need to rename old file but * the new file exists, then ask them to choose a * new name. If the user chooses the same name and * agrees to overwrite the file, just use this * name. If the user hits cancel, tell them they * need to choose a new name and open "file save" * dialog again. * * Show the first dialog only once. If user hits * Cancel, they see shorted version of the dialog * and will be presented with "save file" dialog * again. */ QMessageBox::warning( this,"Firewall Builder", tr("Firewall Builder uses file extension '.fwb' and\n" "needs to rename old data file '%1' to '%2',\n" "but file '%3' already exists.\n" "Choose a different name for the new file.") .arg(fn).arg(newFileName).arg(newFileName), tr("&Continue"), QString::null,QString::null, 0, 1 ); newFileName = chooseNewFileName( fn, tr("Choose name and location for the new file")); if (newFileName.isEmpty()) { QString oldFileName = ofinfo.absoluteFilePath() + ".bak"; rename(oldFileName.toLocal8Bit().constData(), fn.toLocal8Bit().constData()); QMessageBox::warning( this,"Firewall Builder", tr("Load operation cancelled and data file reverted" "to original version."), tr("&Continue"), QString::null,QString::null, 0, 1 ); loadStandardObjects(); return false; } nfinfo.setFile(newFileName); } rename(fn.toLocal8Bit().constData(), newFileName.toLocal8Bit().constData()); QMessageBox::warning( this,"Firewall Builder", tr("Firewall Builder uses file extension '.fwb'. Your data" "file '%1' \nhas been renamed '%2'") .arg(fn).arg(newFileName), tr("&Continue"), QString::null,QString::null, 0, 1 ); } fn = newFileName; } rcs->setFileName(fn); db()->setFileName(fn.toLocal8Bit().constData()); //setWindowTitle(getPageTitle()); //QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); mainW->disableActions(m_panel->ruleSets->count()!=0); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): load complete dirty=%d " "last_modified=%s", db()->isDirty(), ctime(&last_modified)); } catch(FWException &ex) { QString trans = ex.getProperties()["failed_transformation"].c_str(); QString elem = ex.getProperties()["failed_element"].c_str(); if(!trans.isEmpty() || !elem.isEmpty()) { QString msg = tr("Exception: %1").arg(ex.toString().c_str()); if (!trans.isEmpty()) { trans.truncate(LONG_ERROR_CUTOFF); msg+="\n"+tr("Failed transformation : %1").arg(trans); } if (!elem.isEmpty()) { elem.truncate(LONG_ERROR_CUTOFF); msg+="\n"+tr("XML element : %1").arg(elem); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load data file.\n" "The file has not been loaded. Error:\n%1").arg(msg), tr("&Continue"), QString::null,QString::null, 0, 1 ); } else { // this was not XML error, perhaps permissions or other // filesystem problem QString error_txt = QString::fromUtf8(ex.toString().c_str()); if (error_txt.length() > LONG_ERROR_CUTOFF) { error_txt.truncate(LONG_ERROR_CUTOFF); error_txt += "\n\n" + tr("(Long error message was truncated)"); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load data file.\n" "The file has not been loaded. Error:\n%1").arg( error_txt), tr("&Continue"), QString::null,QString::null, 0, 1 ); } // load standard objects so the window does not remain empty loadStandardObjects(); return false; } db()->setReadOnly( rcs->isRO() || rcs->isTemp() ); // clear dirty flag for all objects, recursively if (!forceSave) db()->setDirty(false); mw->showStatusBarMessage(tr("Building object tree...")); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); loadObjects(); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); mw->showStatusBarMessage(tr("Indexing...") ); db()->reIndex(); setupAutoSave(); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): all done: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); return true; } bool ProjectPanel::checkin(bool unlock) { /* doing checkin only if we did checkout so rcs!=NULL */ QString rlog=""; if (systemFile || rcs==NULL || !rcs->isCheckedOut() || rcs->isTemp()) return true; if (rcs->isDiff()) { // if the file hasn't changed, do not need to ask for the comment if ( ! st->getRCSLogState()) { RCSFileSaveDialog_q fsd; QDialog *fsd_dialog = new QDialog(this); fsd.setupUi(fsd_dialog); fsd.checkinDialogTitle->setText( QString("") + tr("Checking file %1 in RCS").arg(rcs->getFileName()) + QString("") ); if ( fsd_dialog->exec()== QDialog::Rejected ) { if (fwbdebug) qDebug() << "RCSFileSaveDialog_q user hit Cancel"; delete fsd_dialog; return false; } bool empty_rcslog = fsd.nolog->isChecked(); if (empty_rcslog) { rlog = ""; st->setRCSLogState(true); } else rlog = fsd.rcslog->toPlainText(); delete fsd_dialog; } } /***********************************************************************/ try { if (fwbdebug) qDebug("about to check the file in"); rcs->ci(rlog,unlock); if (fwbdebug) qDebug("done"); } catch (FWException &ex) { QMessageBox::critical( this,"Firewall Builder", tr("Error checking in file %1:\n%2") .arg(rcs->getFileName()).arg(ex.toString().c_str()), tr("&Continue"), QString::null, QString::null, 0, 1 ); } /***********************************************************************/ return true; } void ProjectPanel::save() { if (fwbdebug) qDebug("ProjectPanel::save: rcs=%p rcs->isRO=%d " "rcs->isTemp=%d rcs->getFileName=%s", rcs, rcs->isRO(), rcs->isTemp(), rcs->getFileName().toLocal8Bit().constData()); //undoStack->clear(); if (!rcs->isRO() && !rcs->isTemp()) { try { if (rcs->getFileName().isEmpty()) fileSaveAs(); // eventually calls this method again else { /* editingLibfile is true if user edits a library or master library file */ mw->showStatusBarMessage( tr("Saving data to file %1").arg(rcs->getFileName())); bool editingLibfile = editingLibrary(); /* **************************************************************** * * REMOVE THIS * * or may be not. The savings of not storing standard objects in each file * are minimal but this code seems to be leaking too * ****************************************************************** */ //if (st->getDontSaveStdLib()) // this is now default if (false) { list userLibs; list ll = db()->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if (fwbdebug) qDebug("ProjectPanel::save() lib %s", (*i)->getName().c_str() ); /* skip standard and template libraries unless we edit them */ int id = (*i)->getId(); if (id==FWObjectDatabase::STANDARD_LIB_ID && !editingStandardLib) continue; if (id==FWObjectDatabase::TEMPLATE_LIB_ID && !editingTemplateLib) continue; if (fwbdebug) qDebug(" add"); userLibs.push_back( *i ); } QApplication::setOverrideCursor(QCursor( Qt::WaitCursor)); FWObjectDatabase *ndb = db()->exportSubtree(userLibs); if (editingLibfile) { /* exported libraries are always read-only */ list ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if ((*i)->getId()!=FWObjectDatabase::STANDARD_LIB_ID && (*i)->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID) (*i)->setReadOnly( true ); } } ndb->resetTimeLastModified( db()->getTimeLastModified() ); xmlSetCompressMode(st->getCompression() ? 9 : 0); ndb->saveFile( rcs->getFileName().toLocal8Bit().constData()); delete ndb; QApplication::restoreOverrideCursor(); // reset "dirty" flag only after we actually save the data // fixes #389 db()->setDirty(false); // and reset actions, including Save() which should now // be inactive QCoreApplication::postEvent(mw, new updateGUIStateEvent()); //mw->prepareFileMenu(); } else { QApplication::setOverrideCursor(QCursor( Qt::WaitCursor)); xmlSetCompressMode(st->getCompression() ? 9 : 0); db()->saveFile( rcs->getFileName().toLocal8Bit().constData()); QApplication::restoreOverrideCursor(); } } } catch (FWException &ex) { QApplication::restoreOverrideCursor(); /* error saving the file. Since XMLTools does not return any useful * error message in the exception, let's check for obvious problems here */ QString err; if (access( rcs->getFileName().toLocal8Bit().constData(), W_OK)!=0 && errno==EACCES) err=tr("File is read-only"); else err=ex.toString().c_str(); QMessageBox::critical( this,"Firewall Builder", tr("Error saving file %1: %2") .arg(rcs->getFileName()).arg(err), tr("&Continue"), QString::null, QString::null, 0, 1 ); } } } fwbuilder-5.1.0.3599/src/libgui/NATRuleOptionsDialog.h0000644000175000017500000000311311733011756023155 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NATRULEOPTIONSDIALOG_H_ #define __NATRULEOPTIONSDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "DialogData.h" #include "fwbuilder/FWObject.h" class RuleSetView; class ProjectPanel; class NATRuleOptionsDialog : public BaseObjectDialog { Q_OBJECT; DialogData data; QString platform; RuleSetView *rsv; Ui::NATRuleOptionsDialog_q *m_dialog; public: NATRuleOptionsDialog(QWidget *parent); ~NATRuleOptionsDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // __NATRULEOPTIONSDIALOG_H fwbuilder-5.1.0.3599/src/libgui/pixosIfaceOptsDialog.cpp0000644000175000017500000001131611733011756023626 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id: pixosIfaceOptsDialog.cpp 1586 2009-10-13 05:05:03Z vadim $ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "pixosIfaceOptsDialog.h" #include "platforms.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "FWWindow.h" #include "Help.h" #include #include using namespace std; using namespace libfwbuilder; pixosIfaceOptsDialog::pixosIfaceOptsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::pixosIfaceOptsDialog_q; m_dialog->setupUi(this); setWindowModality(Qt::WindowModal); obj = o; FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject(); cluster_interface = (Cluster::cast(obj->getParent()) != NULL); setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj), ifopt->getStr("type").c_str()); // Using "type" control only for subinterfaces // and main interfaces of the firewall objects if (cluster_interface) { m_dialog->iface_type->hide(); m_dialog->iface_type_label->hide(); } else { m_dialog->iface_type->show(); m_dialog->iface_type_label->show(); } data.registerOption(m_dialog->vlan_id, ifopt, "vlan_id"); data.loadAll(); // special actions for different iface types // VLAN (8021q) typeChanged(""); } pixosIfaceOptsDialog::~pixosIfaceOptsDialog() { delete m_dialog; } /* * store all data in the object */ void pixosIfaceOptsDialog::accept() { // validate user input before saving if (!validate()) return; ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the interface object FWObject* new_state = cmd->getNewState(); FWOptions* ifopt = Interface::cast(new_state)->getOptionsObject(); assert(ifopt!=NULL); if (cluster_interface) { ifopt->setStr("type", "cluster_interface"); } else { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); ifopt->setStr("type", new_type.toStdString()); } data.saveAll(ifopt); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void pixosIfaceOptsDialog::reject() { QDialog::reject(); } void pixosIfaceOptsDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("PIX Interface"); h->setSource(QUrl("pixosIfaceOptsDialog.html#" + anchor)); h->raise(); h->show(); } void pixosIfaceOptsDialog::typeChanged(const QString&) { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); // enable VLAN ID line edit for type VLAN if (new_type == "8021q") { m_dialog->options_stack->setCurrentIndex(1); return; } // page 0 is empty m_dialog->options_stack->setCurrentIndex(0); } bool pixosIfaceOptsDialog::validate() { bool valid = true; QString combobox = m_dialog->iface_type->currentText(); QString type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); QWidget *focus = NULL; QString message; if (type == "8021q") { // VLAN ID must be set between 1 <= vid <= 4'094 // QSpinBox widget enforces these limits ; } if (!valid) { QMessageBox::warning(this, "Firewall Builder", tr("Input not valid: %1").arg(message), "&Continue", QString::null, QString::null, 0, 1); focus->setFocus(); } return valid; } fwbuilder-5.1.0.3599/src/libgui/AddressTableDialog.h0000644000175000017500000000275411733011756022676 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ADDRESSTABLEDIALOG_H_ #define __ADDRESSTABLEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class AddressTableDialog : public BaseObjectDialog { Q_OBJECT; Ui::AddressTableDialog_q *m_dialog; public: AddressTableDialog(QWidget *parent); ~AddressTableDialog(); void updateButtons(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void browse(); virtual void editFile( void ); }; #endif fwbuilder-5.1.0.3599/src/libgui/ipcopAdvancedDialog.h0000644000175000017500000000301211733011756023065 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPCOPADVANCEDDIALOG_H_ #define __IPCOPADVANCEDDIALOG_H_ #include #include "DialogData.h" namespace libfwbuilder { class FWObject; }; class ipcopAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::ipcopAdvancedDialog_q *m_dialog; public: ipcopAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~ipcopAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); virtual void editProlog(); virtual void editEpilog(); public slots: virtual void switchLOG_ULOG(); }; #endif // __IPCOPADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/debugdialog_q.ui0000644000175000017500000000441211733011756022166 0ustar sylvestresylvestre debugDialog_q 0 0 494 280 Debugging Info 0 6 20 20 Expanding Horizontal &Close Alt+C true true debugText buttonOk buttonOk clicked() debugDialog_q close() fwbuilder-5.1.0.3599/src/libgui/HttpGet.h0000644000175000017500000000301211733011756020564 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef HTTPGET_H #define HTTPGET_H #include #include #include #include #include class HttpGet : public QObject { Q_OBJECT; private: QHttp http; QUrl url; QBuffer strm; bool status; QString last_error; QByteArray contents; int request_id; public: HttpGet(QObject *parent = 0); bool get(const QUrl &url); QString getLastError() { return last_error; } bool getStatus() { return status; } QString toString() { return QString(contents); } void abort(); signals: void done(const QString &res); private slots: void httpDone(int id, bool error); void fileDone(); }; #endif fwbuilder-5.1.0.3599/src/libgui/FirewallInstallerUnx.h0000644000175000017500000000273411733011756023335 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FIREWALLINSTALLERUNX_H_ #define __FIREWALLINSTALLERUNX_H_ #include "config.h" #include "FirewallInstaller.h" #include #include #include namespace libfwbuilder { class Firewall; } class FirewallInstallerUnx : public FirewallInstaller { Q_OBJECT void executeSession(const QString &cmd); public: FirewallInstallerUnx(instDialog *_dlg, instConf *_cnf, const QString &_p) : FirewallInstaller(_dlg, _cnf, _p) {} virtual bool packInstallJobsList(libfwbuilder::Firewall*); virtual void activatePolicy(const QString &script, const QString &args); }; #endif fwbuilder-5.1.0.3599/src/libgui/ObjectDescriptor.h0000644000175000017500000000410411733011756022455 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTDESCRIPTOR_H_ #define __OBJECTDESCRIPTOR_H_ #include #include "fwbuilder/InterfaceData.h" #include "fwbuilder/dns.h" #include #include // avoid #include "snmp.h" since it conflicts with Qt, see #2185 namespace libfwbuilder { class CrawlerFind; }; class ObjectDescriptor { public: bool have_snmpd ; std::string descr, contact, location, sysname ; std::string type; bool isSelected; std::map interfaces ; std::string MAC_addr ; libfwbuilder::HostEnt dns_info ; libfwbuilder::InetAddr addr ; libfwbuilder::InetAddr netmask ; ObjectDescriptor(); ObjectDescriptor(const ObjectDescriptor& od); std::string toString() { std::ostringstream ost; ost << sysname; //if(interfaces.size()>1) // ost <<" [" < ObjectDescriptorList; #endif fwbuilder-5.1.0.3599/src/libgui/FWObjectDropArea.cpp0000644000175000017500000001515011733011756022627 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "events.h" #include "FWObjectDropArea.h" #include "FWObjectDrag.h" #include "FWObjectClipboard.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleSet.h" #include #include #include #include #include #include //Added by qt3to4: #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; FWObjectDropArea::~FWObjectDropArea() { delete m_objectDropArea; } FWObjectDropArea::FWObjectDropArea(QWidget*p, const char * n, Qt::WFlags f): QWidget(p) { setObjectName( QString(n) ); setWindowFlags( f ); m_objectDropArea = new Ui::FWObjectDropArea_q; m_objectDropArea->setupUi(this); object=NULL; helperText = tr("Drop object here."); } void FWObjectDropArea::paintEvent(QPaintEvent *) { int w=width(); int h=height(); QPainter p(this); QPixmap bufferpixmap; bufferpixmap = QPixmap( w , h ); bufferpixmap.fill( Qt::white ); QPainter tp( &bufferpixmap ); tp.setBrush(Qt::black); tp.drawLine(0,0,w-1,0); tp.drawLine(w-1,0,w-1,h-1); tp.drawLine(w-1,h-1,0,h-1); tp.drawLine(0,h-1,0,0); tp.fillRect(1, 1, w-2, h-2, Qt::white); if (object!=NULL) { QPixmap pm; QString icn_file = (":/Icons/"+object->getTypeName()+"/icon").c_str(); if ( ! QPixmapCache::find( icn_file, pm) ) { pm.load( icn_file ); QPixmapCache::insert( icn_file, pm); } tp.drawPixmap( ((w-pm.width())/2), (h/2)-(2+pm.height()) , pm ); QString t=QString::fromUtf8(object->getName().c_str()); int t_x=2; int t_y=2+h/2; int t_w=w-4; int t_h=h/2-4; tp.drawText( t_x, t_y , t_w, t_h , Qt::AlignHCenter|Qt::AlignTop|Qt::TextWordWrap, t ); } else { QString t = helperText ; int t_x = 2; int t_y = 2; int t_w = w-4; int t_h = h-4; tp.drawText( t_x, t_y , t_w, t_h , Qt::AlignHCenter|Qt::AlignVCenter|Qt::TextWordWrap, t ); } tp.end(); p.drawPixmap( 0, 0, bufferpixmap ); } void FWObjectDropArea::insertObject(libfwbuilder::FWObject *o) { if (object!=o) { object=o; update(); emit objectInserted(); } } void FWObjectDropArea::deleteObject() { object=NULL; update(); emit objectDeleted(); } void FWObjectDropArea::contextMenuEvent (QContextMenuEvent * e) { QMenu *popup; popup=new QMenu(this); QAction *sitAct = popup->addAction( tr("Show in the tree") , this , SLOT( showInTreeObject( )) ); QAction *editAct = popup->addAction( tr("Edit") , this , SLOT( editObject( )) ); popup->addSeparator(); QAction *psAct = popup->addAction( tr("Paste") , this , SLOT( pasteObject( )) ); popup->addSeparator(); QAction *dlAct = popup->addAction( tr("Delete") , this , SLOT( deleteObject( )) ); sitAct->setEnabled(object!=NULL); editAct->setEnabled(object!=NULL); dlAct->setEnabled(object!=NULL); psAct->setEnabled(FWObjectClipboard::obj_clipboard->size()>0); popup->exec(e->globalPos ()); delete popup; } void FWObjectDropArea::dropEvent( QDropEvent *ev) { if (fwbdebug) { qDebug("FWObjectDropArea::dropEvent drop event mode=%d", ev->dropAction()); qDebug(" src widget = %p", ev->source()); } list dragol; if (FWObjectDrag::decode(ev, dragol)) { if (dragol.size()>0) { insertObject(dragol.front()); } } } void FWObjectDropArea::dragEnterEvent( QDragEnterEvent *ev) { list dragol; if (FWObjectDrag::decode(ev, dragol)) { if (dragol.size()>0) { FWObject * o = dragol.front(); bool ok = false ; if (acceptedTypes.size()==0) ok = true ; for (int p = 0 ; p < acceptedTypes.size(); p++) { QString type =o->getTypeName().c_str(); if (type==acceptedTypes[p]) { ok = true ; break ; } } if (!ok) { ev->setAccepted(false); return ; } } } ev->setAccepted( ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); } void FWObjectDropArea::pasteObject() { vector >::iterator i; for( i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i) { FWObject *co= i->second->db()->findInIndex(i->first); insertObject(co); } } void FWObjectDropArea::showInTreeObject() { ProjectPanel * pp = mw->activeProject(); if (pp!=NULL) { QCoreApplication::postEvent( pp, new showObjectInTreeEvent(pp->getFileName(), object->getId())); } } void FWObjectDropArea::editObject() { ProjectPanel * pp = mw->activeProject(); if (pp!=NULL) { if (RuleSet::cast(object)!=NULL) QCoreApplication::postEvent( pp, new openRulesetEvent(pp->getFileName(), object->getId())); QCoreApplication::postEvent( mw, new openObjectInEditorEvent(pp->getFileName(), object->getId())); QCoreApplication::postEvent( pp, new showObjectInTreeEvent(pp->getFileName(), object->getId())); } } void FWObjectDropArea::mouseDoubleClickEvent(QMouseEvent *) { if (object!=NULL) editObject(); } fwbuilder-5.1.0.3599/src/libgui/solarisAdvancedDialog.cpp0000644000175000017500000001032311733011756023765 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "platforms.h" #include "solarisAdvancedDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; solarisAdvancedDialog::~solarisAdvancedDialog() { delete m_dialog; } solarisAdvancedDialog::solarisAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::solarisAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption( m_dialog->solaris_ip_forward, fwopt, "solaris_ip_forward", threeStateMapping); data.registerOption( m_dialog->solaris_ip_forward_src_routed, fwopt, "solaris_ip_forward_src_routed", threeStateMapping); data.registerOption( m_dialog->solaris_ip_forward_directed_broadcasts, fwopt, "solaris_ip_forward_directed_broadcasts", threeStateMapping); data.registerOption( m_dialog->solaris_ip_respond_to_echo_broadcast, fwopt, "solaris_ip_respond_to_echo_broadcast", threeStateMapping); data.registerOption( m_dialog->solaris_ip_forward_directed_broadcasts, fwopt, "solaris_ip_forward_directed_broadcasts", threeStateMapping); data.registerOption( m_dialog->solaris_ip_ignore_redirect, fwopt, "solaris_ip_ignore_redirect", threeStateMapping); data.registerOption( m_dialog->solaris_ip_forward_src_routed, fwopt, "solaris_ip_forward_src_routed", threeStateMapping); data.registerOption( m_dialog->solaris_path_ipf , fwopt, "solaris_path_ipf"); data.registerOption( m_dialog->solaris_path_ipnat, fwopt, "solaris_path_ipnat"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void solarisAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void solarisAdvancedDialog::reject() { QDialog::reject(); } fwbuilder-5.1.0.3599/src/libgui/ObjectTreeViewItem.cpp0000644000175000017500000000537011733011756023251 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "ObjectTreeViewItem.h" #include "ObjectTreeView.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include #include #include using namespace std; using namespace libfwbuilder; ObjectTreeView* ObjectTreeViewItem::getTree() { return dynamic_cast(treeWidget()); } QVariant ObjectTreeViewItem::data(int column, int role) const { if (column == 0 && role == Qt::FontRole) { QFont item_font = QTreeWidgetItem::data(column, role).value(); FWObject *obj = getFWObject(); Firewall *o = NULL; if (obj!=NULL && ( getProperty("type")==Firewall::TYPENAME || getProperty("type")==Cluster::TYPENAME)) { o = Firewall::cast( obj ); } if (o!=NULL) { bool mf = !o->getInactive() && (o->needsCompile()) ; item_font.setBold (mf); item_font.setStrikeOut(o->getInactive()); return QVariant(item_font); } else return QVariant(item_font); } return QTreeWidgetItem::data(column, role); } static int getRank(FWObject *obj) { /* User-defined folders are first */ if (obj == 0) return 0; if (Interface::cast(obj) != 0) return 5; if (Policy::cast(obj) != 0) return 2; if (NAT::cast(obj) != 0) return 3; if (Routing::cast(obj) != 0) return 4; return 1; } bool ObjectTreeViewItem::operator<(const QTreeWidgetItem &other) const { const ObjectTreeViewItem *otvi = dynamic_cast(&other); int rank1 = getRank(otvi->objptr); int rank2 = getRank(objptr); if (rank1 == rank2) return text(0).toLower() < otvi->text(0).toLower(); return rank1 > rank2; } fwbuilder-5.1.0.3599/src/libgui/FWBApplication.h0000644000175000017500000000232111733011756022011 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWBAPPLICATION_H_ #define __FWBAPPLICATION_H_ #include class FWBApplication : public QApplication { Q_OBJECT; int timeout; public: FWBApplication(int &argc, char **argv) : QApplication(argc, argv) {} virtual bool notify(QObject *receiver, QEvent *event); public slots: void quit(); void delayedQuit(); }; #endif fwbuilder-5.1.0.3599/src/libgui/ClusterInterfaceWidget.cpp0000644000175000017500000002344611733011756024163 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ClusterInterfaceWidget.h" #include "FWBSettings.h" #include "ui_ClusterInterfaceWidget.h" #include #include using namespace libfwbuilder; using namespace std; ClusterInterfaceWidget::ClusterInterfaceWidget(QWidget *parent) : QWidget(parent), m_ui(new Ui::ClusterInterfaceWidget) { cisw = dynamic_cast(parent); m_ui->setupUi(this); interfaceBox = new QHBoxLayout(); this->layout()->addItem(interfaceBox); this->layout()->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Minimum)); } ClusterInterfaceWidget::~ClusterInterfaceWidget() { delete m_ui; foreach(InterfacesList list, this->lists) { delete list.list; delete list.label; delete list.layout; } } void ClusterInterfaceWidget::changeEvent(QEvent *e) { QWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } void ClusterInterfaceWidget::setFirewallList(QList firewalls) { foreach ( Firewall* fw, firewalls ) { os = fw->getStr("host_OS").c_str(); QVBoxLayout *layout = new QVBoxLayout(); //qFindChild(this, "interfaceBox") interfaceBox->addLayout(layout); //this->m_ui->interfaceBox->addLayout(layout); //create label with firewall name QLabel *label = new QLabel(QString::fromUtf8(fw->getName().c_str()), this); layout->addWidget(label); // create object tree QTreeWidget *list = new QTreeWidget(this); list->header()->setVisible(false); layout->addWidget(list); // create firewall item in tree QTreeWidgetItem* firewall = new QTreeWidgetItem(list, QStringList() << QString::fromUtf8(fw->getName().c_str())); roots[list] = firewall; firewall->setIcon(0, QIcon(":/Icons/Firewall/icon-tree")); // interfaces and subinterfaces creation FWObjectTypedChildIterator iter = fw->findByType(Interface::TYPENAME); for ( ; iter != iter.end() ; ++iter ) { Interface *iface = Interface::cast(*iter); //if (iface->isLoopback()) continue; QTreeWidgetItem *ifaceitem = new QTreeWidgetItem(firewall, QStringList() << QString::fromUtf8(iface->getName().c_str())); ifaceitem->setData(0, Qt::UserRole, qVariantFromValue(iface));//QVariant(QVariant::UserType, iface)); ifaceitem->setIcon(0, QIcon(":/Icons/Interface/icon-tree")); ifaceitem->setDisabled(!interfaceSelectable(iface)); if (!interfaceSelectable(iface)) // works only for elements which does not have child elements ifaceitem->setFlags(ifaceitem->flags() & ~Qt::ItemIsSelectable); else ifaceitem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); FWObjectTypedChildIterator iter2 = iface->findByType(Interface::TYPENAME); for ( ; iter2 != iter2.end() ; ++iter2 ) { //if (iface->isLoopback()) return; Interface *subiface = Interface::cast(*iter2); QTreeWidgetItem *subitem = new QTreeWidgetItem(ifaceitem, QStringList() << QString::fromUtf8(subiface->getName().c_str())); subitem->setData(0, Qt::UserRole, qVariantFromValue(subiface));//QVariant(QVariant::UserType, subitem)); subitem->setDisabled(!interfaceSelectable(subiface)); subitem->setIcon(0, QIcon(":/Icons/Interface/icon-tree")); if (!interfaceSelectable(subiface)) subitem->setFlags(subitem->flags() & ~Qt::ItemIsSelectable); else ifaceitem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); } } list->topLevelItem(0)->setFlags(list->topLevelItem(0)->flags() & ~Qt::ItemIsSelectable); list->expandAll(); // add data to map InterfacesList newlist; newlist.label = label; newlist.layout = layout; newlist.list = list; newlist.firewall = fw; lists[fw] = newlist; } } bool ClusterInterfaceWidget::setCurrentInterface(const QString& name) { string label; bool setLabel = true; int gotItems = 0; foreach(InterfacesList list, this->lists.values()) { foreach(QTreeWidgetItem *item, list.list->findItems(name, Qt::MatchCaseSensitive | Qt::MatchExactly | Qt::MatchRecursive)) { Interface *iface = item->data(0, Qt::UserRole).value(); if (iface == NULL) continue; if ( item == roots[list.list] ) continue; // skip firewall object if ( interfaceSelectable(iface) ) // interface is good for use in cluster { list.list->setCurrentItem(item); gotItems++; if (label.length() == 0) label = iface->getLabel(); else if (label != iface->getLabel()) setLabel = false; break; } } } if (gotItems < this->lists.values().count()) return false; this->m_ui->name->setText(name); if (setLabel) this->m_ui->label->setText(QString::fromUtf8(label.c_str())); return true; } void ClusterInterfaceWidget::nameChanged(QString newname) { cisw->setTabText(cisw->indexOf(this), newname); } ClusterInterfaceData ClusterInterfaceWidget::getInterfaceData() { ClusterInterfaceData res; res.os = os; res.name = this->m_ui->name->text(); res.label = this->m_ui->label->text(); res.comment = this->m_ui->comment->toPlainText(); foreach(InterfacesList ifacelist, this->lists.values()) { QTreeWidgetItem *item = ifacelist.list->selectedItems().first(); Interface* iface = item->data(0, Qt::UserRole).value(); FWObject *parent_fw = Host::getParentHost(iface); res.interfaces.append(qMakePair(Firewall::cast(parent_fw), iface)); } return res; } bool ClusterInterfaceWidget::interfaceSelectable(Interface* iface) { libfwbuilder::Cluster cluster; // cluster.add(iface, false); cluster.setStr("host_OS", os.toStdString()); Resources* os_res = Resources::os_res[os.toStdString()]; string os_family = os.toStdString(); if (os_res!=NULL) os_family = os_res->getResourceStr("/FWBuilderResources/Target/family"); auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( os_family)); QString err; bool res = true; if (st->getBool("Objects/Interface/autoconfigureInterfaces")) res = int_prop->validateInterface(&cluster, iface, false, err); if (res) res = int_prop->isEligibleForCluster(iface); if (fwbdebug) qDebug() << "interface" << iface->getName().c_str() << "can be used in cluster:" << res; return res; } bool ClusterInterfaceWidget::isValid() { // this->lists is QMap where // InterfacesList contains information about object trees and // labels in this widget. Map this->lists is filled in // setFirewallList() from the list of firewalls (new InterfacesList is // created for each firewall) foreach(InterfacesList ifacelist, this->lists.values()) { // get selected items of object tree - QTreeWidget pointed by // ifacelist.list QList items = ifacelist.list->selectedItems(); if (items.isEmpty()) // nothing is selected in one of interface lists { QMessageBox::warning(this,"Firewall Builder", tr("Some of the cluster interfaces do not have any " "member firewall interface selected"), "&Continue", QString::null, QString::null, 0, 1 ); return false; } if (roots.values().contains(items.first())) { // firewall is the item selected in one of interface lists QMessageBox::warning(this,"Firewall Builder", tr("Please select interface of the member firewall " "rather than the firewall object to be used " "with cluster interface"), "&Continue", QString::null, QString::null, 0, 1 ); return false; } if (!interfaceSelectable(ifacelist.list->selectedItems().first()->data(0, Qt::UserRole).value())) { // selected interface item can not be used in this cluster QMessageBox::warning(this,"Firewall Builder", tr("%1 can not be used as cluster interface.") .arg(ifacelist.list->selectedItems().first()->text(0)), "&Continue", QString::null, QString::null, 0, 1 ); return false; } } // at least one item is selected in all object trees and it is not firewall object return true; } fwbuilder-5.1.0.3599/src/libgui/ipfwAdvancedDialog.cpp0000644000175000017500000001370111733011756023261 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "ipfwAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; ipfwAdvancedDialog::~ipfwAdvancedDialog() { delete m_dialog; } ipfwAdvancedDialog::ipfwAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::ipfwAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); if (fwbdebug) qDebug("%s",Resources::getTargetOptionStr( obj->getStr("host_OS"),"user_can_change_install_dir").c_str()); if (!Resources::getTargetOptionBool( obj->getStr("host_OS"),"user_can_change_install_dir")) { m_dialog->ipfw_fw_dir->setEnabled(false); fwopt->setStr("firewall_dir",""); } if (fwopt->getStr("add_check_state_rule").empty()) fwopt->setBool("add_check_state_rule",true); data.registerOption(m_dialog->ipv4before_2, fwopt, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") <<"ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first" ); data.registerOption( m_dialog->ipfw_add_check_state_rule, fwopt, "add_check_state_rule"); data.registerOption( m_dialog->ipfw_check_shadowing, fwopt, "check_shading"); data.registerOption( m_dialog->ipfw_ignore_empty_groups, fwopt, "ignore_empty_groups" ); data.registerOption( m_dialog->ipfw_fw_dir, fwopt, "firewall_dir"); data.registerOption( m_dialog->ipfw_user, fwopt, "admUser"); data.registerOption( m_dialog->altAddress, fwopt, "altAddress"); data.registerOption( m_dialog->sshArgs, fwopt, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwopt, "scpArgs"); data.registerOption( m_dialog->activationCmd, fwopt, "activationCmd"); data.registerOption( m_dialog->ipfw_manage_virtual_addr, fwopt, "manage_virtual_addr"); data.registerOption( m_dialog->ipfw_configure_interfaces, fwopt, "configure_interfaces"); data.registerOption( m_dialog->ipfw_debug, fwopt, "debug"); data.registerOption( m_dialog->compiler, fwopt, "compiler" ); data.registerOption( m_dialog->compilerArgs, fwopt, "cmdline"); data.registerOption( m_dialog->outputFileName, fwopt, "output_file"); data.registerOption( m_dialog->fileNameOnFw, fwopt, "script_name_on_firewall"); data.registerOption( m_dialog->mgmt_ssh, fwopt, "mgmt_ssh" ); data.registerOption( m_dialog->mgmt_addr, fwopt, "mgmt_addr" ); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText(pis->getCommand().c_str()); m_dialog->installScriptArgs->setText(pis->getArguments().c_str()); /* page "Prolog/Epilog" */ data.registerOption( m_dialog->prolog_script, fwopt, "prolog_script" ); data.registerOption( m_dialog->epilog_script, fwopt, "epilog_script" ); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void ipfwAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); pis->setCommand( m_dialog->installScript->text().toLatin1().constData() ); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void ipfwAdvancedDialog::reject() { QDialog::reject(); } void ipfwAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->prolog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->prolog_script->setText( edt.text() ); } void ipfwAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->epilog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->epilog_script->setText( edt.text() ); } fwbuilder-5.1.0.3599/src/libgui/RCSFilePreview.h0000644000175000017500000000400111733011756021775 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RCSFILEPREVIEW_H_ #define __RCSFILEPREVIEW_H_ #include #include "RCS.h" #include #include #include class RCSViewItem : public QTreeWidgetItem { public: RCSViewItem(QTreeWidget *parent) : QTreeWidgetItem(parent) {} RCSViewItem(QTreeWidgetItem *parent) : QTreeWidgetItem(parent) {} virtual bool operator<(const QTreeWidgetItem &other) const; }; class RCSFilePreview : public QDialog { Q_OBJECT Ui::RCSFilePreview_q *m_widget; RCS *rcs; QString current_file; std::map rcsComments; bool RO; RCSViewItem* addRevision(Revision &rev, QTreeWidgetItem *parent_item); public: RCSFilePreview(QWidget *parent); ~RCSFilePreview(); RCS* getSelectedRev(); bool showFileRLog( const QString &filename ); public slots: virtual void openReadOnly(); virtual void selectedRevision(QTreeWidgetItem *itm); virtual void openFile(); virtual void switchToTreeView(); virtual void switchToListView(); virtual void closeEvent(QCloseEvent *event); }; #endif fwbuilder-5.1.0.3599/src/libgui/routingruleoptionsdialog_q.ui0000644000175000017500000001135711733011756025101 0ustar sylvestresylvestre RoutingRuleOptionsDialog_q 0 0 562 161 Routing Rule Options 0 0 QFrame::Box QFrame::Sunken 1 12 12 QFrame::NoFrame QFrame::Plain 12 12 If installation of this routing rule fails, just carry on Qt::Vertical QSizePolicy::MinimumExpanding 20 0 12 12 QFrame::NoFrame QFrame::Plain 2 2 No options available for routing rules of this firewall platform false Qt::Vertical QSizePolicy::Expanding 20 50 routing_non_critical_rule routing_non_critical_rule toggled(bool) RoutingRuleOptionsDialog_q changed() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/filePropDialog.h0000644000175000017500000000260311733011756022112 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FILEPROPDIALOG_H_ #define __FILEPROPDIALOG_H_ #include #include #include #include "config.h" #include class RCS; class QPrinter; class filePropDialog : public QDialog { Q_OBJECT Ui::filePropDialog_q *m_dialog; public: filePropDialog(QWidget *parent, RCS *rcs); ~filePropDialog(); void setPrinter(QPrinter *printer); private: QPrinter *printer; public slots: virtual void printRevHistory( ); }; #endif // __FILEPROPDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FWBApplication.cpp0000644000175000017500000000411111733011756022343 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWBSettings.h" #include "FWBApplication.h" #include "FWWindow.h" #include "fwbuilder/FWException.h" #include #include using namespace libfwbuilder; using namespace std; void FWBApplication::quit() { if (fwbdebug) qDebug() << "FWBApplication::quit()"; timeout = 0; if (mw->isVisible()) mw->hide(); if (st->getCheckUpdates()) { QTimer::singleShot(100, this, SLOT(delayedQuit())); } else delayedQuit(); } void FWBApplication::delayedQuit() { if (fwbdebug) qDebug() << "FWBApplication::delayedQuit()"; QApplication::quit(); } bool FWBApplication::notify(QObject *receiver, QEvent *event) { try { return QApplication::notify(receiver, event); } catch (const libfwbuilder::FWException &ex) { cerr << "Caught FWException: " << ex.toString() << std::endl; QCoreApplication::exit(1); } catch (const std::string &s) { cerr << s << std::endl; QCoreApplication::exit(1); } catch (const std::exception &ex) { cerr << ex.what() << std::endl; QCoreApplication::exit(1); } catch (...) { cerr << "Caught unsupported exception" << std::endl; QCoreApplication::exit(1); } return false; } fwbuilder-5.1.0.3599/src/libgui/FWObjectDrag.h0000644000175000017500000000347511733011756021463 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOBJECTDRAG_H_ #define __FWOBJECTDRAG_H_ //#include //Added by qt3to4: #include #include #include #include namespace libfwbuilder { class FWObject; }; /***************************************************************************** * * Class FWObjectDrag * *****************************************************************************/ class FWObjectDrag : public QDrag { private: std::list objlist; public: static QString FWB_MIME_TYPE; FWObjectDrag(std::list ol, QWidget *dragSource = 0, const char* name = 0); ~FWObjectDrag(); virtual Qt::DropAction start(Qt::DropActions action = Qt::CopyAction); QByteArray encodedData() const; static bool decode( QDropEvent *ev, std::list &ol); static bool decode( QDragEnterEvent *ev, std::list &ol); }; #endif fwbuilder-5.1.0.3599/src/libgui/RCSFilePreview.cpp0000644000175000017500000002035011733011756022335 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "RCS.h" #include "RCSFilePreview.h" #include "FWBSettings.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWException.h" #include "fwbuilder/XMLTools.h" #include #include #include // #include #include #include using namespace std; using namespace libfwbuilder; bool RCSViewItem::operator<(const QTreeWidgetItem &other) const { int col = treeWidget()->sortColumn(); QString col_txt_1 = text(col); QString col_txt_2 = other.text(col); if (col==0) // column 0 is revision number return (XMLTools::version_compare( col_txt_1.toStdString(), col_txt_2.toStdString()) < 0); return (col_txt_1 < col_txt_2); } RCSFilePreview::RCSFilePreview(QWidget *parent): QDialog(parent) { if (fwbdebug) qDebug("RCSFilePreview: constructor"); m_widget = new Ui::RCSFilePreview_q; m_widget->setupUi(this); connect( m_widget->cancelButton, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( m_widget->RCSTreeView, SIGNAL( itemActivated( QTreeWidgetItem*, int ) ), this, SLOT( accept() ) ); if (st->getRCSFilePreviewStyle()==1) m_widget->list_view->setChecked(true); else m_widget->tree_view->setChecked(true); m_widget->RCSTreeView->setAllColumnsShowFocus( true ); m_widget->RCSTreeView->setSelectionMode(QAbstractItemView::SingleSelection ); m_widget->RCSTreeView->setRootIsDecorated( FALSE ); // m_widget->RCSTreeView->sortByColumn( 0, Qt::AscendingOrder ); if (fwbdebug) qDebug("RCSFilePreview: constructor done"); rcs = NULL; RO = false; } RCSFilePreview::~RCSFilePreview() { if (fwbdebug) qDebug("~RCSFilePreview() rcs=%p", rcs); // if (rcs!=NULL) delete rcs; st->setRCSFilePreviewSortColumn(m_widget->RCSTreeView->sortColumn()); } void RCSFilePreview::openReadOnly() { if (rcs!=NULL) rcs->setRO(true); RO = true; accept(); } void RCSFilePreview::openFile() { accept(); } void RCSFilePreview::selectedRevision(QTreeWidgetItem *itm) { if (itm == m_widget->RCSTreeView->topLevelItem(0)) return; QString rev = itm->text(0); assert(rcs!=NULL); rcs->setSelectedRev(rev); m_widget->comment->setText( rcsComments[rev] ); if (fwbdebug) qDebug("RCSFilePreview::selectedRevision : %s", rev.toAscii().constData()); } bool RCSFilePreview::showFileRLog( const QString &filename ) { if (fwbdebug) qDebug("RCSFilePreview::showFileRLog filename=%s rcs=%p", filename.toLocal8Bit().constData(),rcs); current_file = filename; m_widget->RCSTreeView->disconnect( SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); m_widget->RCSTreeView->clear(); if (rcs!=NULL) delete rcs; rcs = new RCS(filename); if (rcs->revisions.size()==0) { QTreeWidgetItem *itm = new QTreeWidgetItem(m_widget->RCSTreeView); itm->setText( 0, tr("File is not in RCS") ); // addToRCS->setEnabled(true); m_widget->comment->setText(""); return false; } // addToRCS->setEnabled(false); QTreeWidgetItem *rootItm = new QTreeWidgetItem( m_widget->RCSTreeView ); rootItm->setText( 0, filename.right( filename.length()-filename.lastIndexOf("/")-1 ) ); rootItm->setExpanded(true); rcsComments.clear(); QList::iterator i; QList itemList; QList::iterator ili; RCSViewItem* latest_revision_item = NULL; RCSViewItem* latest_date_item = NULL; string latest_revision = "1.0"; QString latest_date = ""; for (i=rcs->revisions.begin(); i!=rcs->revisions.end(); ++i) { rcsComments[(*i).rev] = (*i).log; RCSViewItem *itm = NULL; if (st->getRCSFilePreviewStyle()==1) { // List style itm = addRevision(*i, rootItm); itemList.push_back(itm); } else { // tree style if ((*i).rev.indexOf(QRegExp("^[0-9]+\\.[0-9]+$"))!=-1) { itm = addRevision(*i, rootItm); itemList.push_back(itm); } if ((*i).rev.indexOf(QRegExp("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"))!=-1) { QString branch_root = (*i).rev.section(".",0,1); for (ili=itemList.begin(); ili!=itemList.end(); ++ili) { if ((*ili)->text(0) == branch_root) { QTreeWidgetItem *br = *ili; if (br!=NULL) itm = addRevision((*i), br); } } } } string itm_revision = (*i).rev.toStdString(); if (XMLTools::version_compare(itm_revision, latest_revision) > 0) { latest_revision = itm_revision; latest_revision_item = itm; } // This relies on the date string in the rcslog output // being in sortable format. This is so for the "C" or "en_US" // locale, but I am not sure about other locales. if ((*i).date > latest_date) { latest_date = (*i).date; latest_date_item = itm; } } m_widget->RCSTreeView->expandAll(); m_widget->RCSTreeView->sortByColumn(st->getRCSFilePreviewSortColumn(), Qt::AscendingOrder); // connect signal before setting current item so that // selectedRevision gets control and updates rcs log panel connect( m_widget->RCSTreeView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectedRevision(QTreeWidgetItem*))); RCSViewItem* show_item = NULL; if (m_widget->RCSTreeView->sortColumn()==0 && latest_revision_item) show_item = latest_revision_item; if (m_widget->RCSTreeView->sortColumn()==1 && latest_date_item) show_item = latest_date_item; if (show_item) { show_item->setSelected(true); m_widget->RCSTreeView->expandItem(show_item->parent()); m_widget->RCSTreeView->setCurrentItem(show_item); m_widget->RCSTreeView->scrollToItem(show_item); } // resize after parent of the current item was expanded m_widget->RCSTreeView->resizeColumnToContents ( 0 ); m_widget->RCSTreeView->resizeColumnToContents ( 1 ); return true; } RCSViewItem* RCSFilePreview::addRevision(Revision &rev, QTreeWidgetItem *parent_item) { RCSViewItem *itm = new RCSViewItem(parent_item); itm->setText(0, rev.rev); itm->setText(1, rev.date); itm->setText(2, rev.author); itm->setText(3, QString(" ") + rev.locked_by); return itm; } void RCSFilePreview::switchToTreeView() { st->setRCSFilePreviewStyle(0); // 0 for backward compatibility if (!current_file.isEmpty()) showFileRLog(current_file); } void RCSFilePreview::switchToListView() { st->setRCSFilePreviewStyle(1); if (!current_file.isEmpty()) showFileRLog(current_file); } RCS* RCSFilePreview::getSelectedRev() { if (fwbdebug) qDebug("RCSFilePreview::getSelectedRev rcs=%p",rcs); return rcs; } void RCSFilePreview::closeEvent(QCloseEvent *event) { if (fwbdebug) qDebug("RCSFilePreview::closeEvent"); st->setRCSFilePreviewSortColumn(m_widget->RCSTreeView->sortColumn()); QDialog::closeEvent(event); } fwbuilder-5.1.0.3599/src/libgui/TextFileEditor.h0000644000175000017500000000266111733011756022111 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ADDRESSTABLEEDITOR_H__ #define __ADDRESSTABLEEDITOR_H__ #include "config.h" #include class TextFileEditor : public QDialog { Q_OBJECT; QString file_name; QString original_data; public: Ui::TextFileEditor_q *m_dialog; TextFileEditor(QWidget *parent, const QString &file_name, const QString &title=""); ~TextFileEditor(); // load data, return true if successful bool load(); protected: virtual void closeEvent(QCloseEvent *ev); public slots: virtual void save(); }; #endif fwbuilder-5.1.0.3599/src/libgui/confirmdeleteobjectdialog_q.ui0000644000175000017500000001150711733011756025112 0ustar sylvestresylvestre ConfirmDeleteObjectDialog_q 0 0 527 494 16777215 1522 Firewall Builder 0 0 Groups and firewall policy rules shown in the list below reference objects you are about to delete. If you delete objects, they will be removed from these groups and rules. Qt::AlignVCenter true 0 0 Deleted objects are moved to the "Deleted objects" library. You can recover them later by moving back to the user's library. However if you delete an object already located in the "Deleted objects" library, it is destroyed and can not be restored. Qt::AlignVCenter true 0 0 500 200 16777215 550 QFrame::NoFrame QFrame::Plain true 16777215 500 QAbstractItemView::NoSelection Object Parent Details Delete Cancel objectsView pushButton1 pushButton2 pushButton1 clicked() ConfirmDeleteObjectDialog_q accept() 20 20 20 20 pushButton2 clicked() ConfirmDeleteObjectDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/libexport_q.ui0000644000175000017500000001321211733011756021726 0ustar sylvestresylvestre LibExport_q 0 0 578 502 5 5 0 0 Export true 11 6 7 7 0 0 QFrame::Box QFrame::Sunken 11 6 5 0 0 0 This will export a library to a file which can later be imported back into Firewall Builder Qt::AlignVCenter true QAbstractItemView::ExtendedSelection New Item Make exported libraries read-only Choose libraries to be exported: Qt::AlignTop false Qt::Vertical QSizePolicy::Fixed 20 20 7 5 0 0 QFrame::NoFrame QFrame::Sunken 11 6 Qt::Horizontal QSizePolicy::Expanding 41 20 Ok Cancel okButton clicked() LibExport_q accept() 20 20 20 20 cancelButton clicked() LibExport_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/objecteditor_q.ui0000644000175000017500000000534411733011756022402 0ustar sylvestresylvestre ObjectEditor_q true 0 0 202 119 5 5 0 0 Firewall Builder true 0 6 0 6 Qt::Horizontal QSizePolicy::Expanding 20 20 &Close Alt+C true true 200 0 QFrame::StyledPanel QFrame::Raised buttonOk clicked() ObjectEditor_q accept() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/ipcoposAdvancedDialog.cpp0000644000175000017500000001745111733011756023776 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "ipcoposAdvancedDialog.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "Help.h" using namespace std; using namespace libfwbuilder; ipcoposAdvancedDialog::~ipcoposAdvancedDialog() { delete m_dialog; } ipcoposAdvancedDialog::ipcoposAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::ipcoposAdvancedDialog_q; m_dialog->setupUi(this); obj=o; string host_os = obj->getStr("host_OS"); string description = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/description"); setWindowTitle(QObject::tr("%1 advanced settings").arg(description.c_str())); FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption( m_dialog->linux24_log_martians, fwopt, "linux24_log_martians", threeStateMapping); data.registerOption( m_dialog->linux24_accept_redirects, fwopt, "linux24_accept_redirects", threeStateMapping); data.registerOption( m_dialog->linux24_icmp_echo_ignore_all, fwopt, "linux24_icmp_echo_ignore_all", threeStateMapping); data.registerOption( m_dialog->linux24_icmp_echo_ignore_broadcasts, fwopt, "linux24_icmp_echo_ignore_broadcasts", threeStateMapping); data.registerOption( m_dialog->linux24_icmp_ignore_bogus_error_responses, fwopt, "linux24_icmp_ignore_bogus_error_responses", threeStateMapping); data.registerOption( m_dialog->linux24_ip_dynaddr, fwopt, "linux24_ip_dynaddr", threeStateMapping); data.registerOption( m_dialog->linux24_rp_filter, fwopt, "linux24_rp_filter", threeStateMapping); data.registerOption( m_dialog->linux24_accept_source_route, fwopt, "linux24_accept_source_route", threeStateMapping); data.registerOption( m_dialog->linux24_ip_forward, fwopt, "linux24_ip_forward", threeStateMapping); data.registerOption( m_dialog->linux24_ipv6_forward, fwopt, "linux24_ipv6_forward", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_fin_timeout, fwopt, "linux24_tcp_fin_timeout" ); data.registerOption( m_dialog->linux24_tcp_keepalive_interval, fwopt, "linux24_tcp_keepalive_interval"); data.registerOption( m_dialog->linux24_tcp_window_scaling, fwopt, "linux24_tcp_window_scaling", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_sack, fwopt, "linux24_tcp_sack", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_fack, fwopt, "linux24_tcp_fack", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_ecn, fwopt, "linux24_tcp_ecn", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_syncookies, fwopt, "linux24_tcp_syncookies", threeStateMapping); data.registerOption( m_dialog->linux24_tcp_timestamps, fwopt, "linux24_tcp_timestamps", threeStateMapping); data.registerOption( m_dialog->linux24_path_iptables, fwopt, "linux24_path_iptables" ); data.registerOption( m_dialog->linux24_path_ip6tables, fwopt, "linux24_path_ip6tables" ); data.registerOption( m_dialog->linux24_path_ip, fwopt, "linux24_path_ip"); data.registerOption( m_dialog->linux24_path_lsmod, fwopt, "linux24_path_lsmod"); data.registerOption( m_dialog->linux24_path_logger, fwopt, "linux24_path_logger"); data.registerOption( m_dialog->linux24_path_vconfig, fwopt, "linux24_path_vconfig"); data.registerOption( m_dialog->linux24_path_brctl, fwopt, "linux24_path_brctl"); data.registerOption( m_dialog->linux24_path_ifenslave, fwopt, "linux24_path_ifenslave"); data.registerOption( m_dialog->linux24_path_modprobe, fwopt, "linux24_path_modprobe"); data.registerOption( m_dialog->linux24_path_iptables_restore, fwopt, "linux24_path_iptables_restore"); data.registerOption( m_dialog->linux24_path_ip6tables_restore, fwopt, "linux24_path_ip6tables_restore"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void ipcoposAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void ipcoposAdvancedDialog::reject() { QDialog::reject(); } void ipcoposAdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Host type IPCOP"); h->setSource(QUrl("ipcoposAdvancedDialog.html#" + anchor)); h->raise(); h->show(); } fwbuilder-5.1.0.3599/src/libgui/BaseObjectDialog.cpp0000644000175000017500000000607511733011756022675 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "FWObjectDropArea.h" #include "BaseObjectDialog.h" #include "CommentKeywords.h" #include #include #include #include #include #include void BaseObjectDialog::connectSignalsOfAllWidgetsToSlotChange() { QList all_dialog_widgets = findChildren(QString()); foreach(QWidget* w, all_dialog_widgets) { FWObjectDropArea *da = dynamic_cast(w); if (da) { connect(da, SIGNAL(objectDeleted()), this, SLOT(changed())); connect(da, SIGNAL(objectInserted()), this, SLOT(changed())); continue; } QLineEdit *le = qobject_cast(w); if (le) { connect(le, SIGNAL(editingFinished()), this, SLOT(changed())); continue; } QCheckBox *cb = qobject_cast(w); if (cb) { connect(cb, SIGNAL(stateChanged(int)), this, SLOT(changed())); continue; } QRadioButton *rb = qobject_cast(w); if (rb) { connect(rb, SIGNAL(toggled(bool)), this, SLOT(changed())); continue; } QComboBox *cmb = qobject_cast(w); if (cmb) { connect(cmb, SIGNAL(activated(int)), this, SLOT(changed())); continue; } QSpinBox *sb = qobject_cast(w); if (sb) { connect(sb, SIGNAL(editingFinished()), this, SLOT(changed())); continue; } QTextEdit *textEdit = qobject_cast(w); if (textEdit) { connect(textEdit, SIGNAL(textChanged()), this, SLOT(changed())); continue; } CommentKeywords *ck = dynamic_cast(w); if (ck) { connect(ck, SIGNAL(changed()), this, SLOT(changed())); continue; } } } void BaseObjectDialog::changed() { QWidget *s = dynamic_cast(sender()); if (fwbdebug) qDebug() << "BaseObjectDialog::changed() from " << s; if (!init) { emit changed_sign(); } } fwbuilder-5.1.0.3599/src/libgui/vrrpOptionsDialog.cpp0000644000175000017500000000601611733011756023234 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "vrrpOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include #include using namespace std; using namespace libfwbuilder; vrrpOptionsDialog::vrrpOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::vrrpOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); data.registerOption(m_dialog->vrrp_secret, gropt, "vrrp_secret"); data.registerOption(m_dialog->vrrp_vrid, gropt, "vrrp_vrid"); data.registerOption(m_dialog->vrrp_over_ipsec_ah, gropt, "vrrp_over_ipsec_ah"); data.loadAll(); } vrrpOptionsDialog::~vrrpOptionsDialog() { delete m_dialog; } /* * store all data in the object */ void vrrpOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void vrrpOptionsDialog::reject() { QDialog::reject(); } bool vrrpOptionsDialog::validate() { bool valid = true; QWidget *focus = NULL; QString message; // vrrp secret must be set if (m_dialog->vrrp_secret->text().isEmpty()) { message = "VRRP Secret field can not be empty!"; focus = m_dialog->vrrp_secret; valid = false; } if (!valid) { QMessageBox::warning(this, "Firewall Builder", tr("Input not valid: %1").arg(message), "&Continue", QString::null, QString::null, 0, 1); focus->setFocus(); } return valid; } fwbuilder-5.1.0.3599/src/libgui/fakeWizard.h0000644000175000017500000000514511733011756021305 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FAKEWIZARD_H__ #define __FAKEWIZARD_H__ #include #include #include #include #include class FakeWizard { protected: QWidget *mainWidget; QStackedWidget *stackedWidget; QPushButton *nextButton; QPushButton *backButton; QPushButton *finishButton; QPushButton *cancelButton; QLabel *titleLabel; int m_currentPage; int m_pageCount; std::vector nextEnabled; std::vector backEnabled; std::vector appropriates; std::vector finishEnabled; std::vector pageTitles; int nextRelevant(const int page) const; int previousRelevant(const int page) const; public : FakeWizard(); virtual ~FakeWizard(); void setControlWidgets(QWidget *_mainWidget, QStackedWidget *_stackedWidget, QPushButton *_nextButton, QPushButton *_finishButton, QPushButton *_backButton, QPushButton *_cancelButton, QLabel *_titleLabel = NULL); int pageCount() const; int currentPage() const; void showPage(const int page); void setCurrentPage(const int page); void setNextEnabled(const int page, const bool enabled); void setBackEnabled(const int page, const bool enabled); void setAppropriate(const int page, const bool value); void setFinishEnabled(const int page, const bool enabled); void setTitle(const int page, const QString title); virtual bool appropriate(const int) const { return true; } /*virtual void backClicked(); virtual void nextClicked();*/ }; #endif fwbuilder-5.1.0.3599/src/libgui/FWCmdMoveObject.cpp0000644000175000017500000002215111733011756022463 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWCmdChange.h" #include "FWCmdMoveObject.h" #include "FWWindow.h" #include "FWBSettings.h" #include "events.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Library.h" #include #include using namespace libfwbuilder; using namespace std; /******************************************************** * FWCmdMoveObject * * This command controls moving an object to another place in the * tree, including different library. List of pointers to FWObject * passed to constructor is used to remove all references to this * object. This is done when object is deleted by moving it to the * "Deleted objects" library. If the list is empty, no references * will be removed. * * Unlike in FWComdAddObject, the object @obj always belongs to the * tree, either in its old place or in the new place. There is no need * for us to delete it in the destructor. * * This command should only operate on moving objects from one place * in the tree to another but within the same data file * ********************************************************/ FWCmdMoveObject::FWCmdMoveObject( ProjectPanel *project, FWObject *old_p, FWObject *new_p, FWObject *o, map > &reference_holder_objects, QString text, QUndoCommand* macro) : FWCmdBasic(project, macro), oldUserFolder(QString::fromUtf8(o->getStr("folder").c_str())), reference_holders(reference_holder_objects) { old_parent = old_p; new_parent = new_p; current_parent = NULL; obj = o; if (text.isEmpty()) { setText(QObject::tr("Move object")); } else { setText(text); } } FWCmdMoveObject::~FWCmdMoveObject() { } void FWCmdMoveObject::undo() { obj->setStr("folder", oldUserFolder.toUtf8().constData()); if (new_parent->hasChild(obj) && !old_parent->hasChild(obj)) { new_parent->remove(obj, false); old_parent->add(obj); current_parent = old_parent; } if (fwbdebug) qDebug() << "FWCmdMoveObject::undo() obj->ref_counter=" << obj->getRefCounter(); if (reference_holders.size()) { map >::iterator it; for (it=reference_holders.begin(); it!=reference_holders.end(); ++it) { int obj_id = it->first; foreach(FWObject *o, it->second) { FWObject *cobj = project->db()->findInIndex(obj_id); if (cobj) o->addRef(cobj); } } } notify(); } void FWCmdMoveObject::redo() { obj->setStr("folder", ""); if (!new_parent->hasChild(obj) && old_parent->hasChild(obj)) { old_parent->remove(obj, false); new_parent->add(obj); current_parent = new_parent; } if (fwbdebug) qDebug() << "FWCmdMoveObject::redo()" << "obj: " << obj->getName().c_str() << "(" << obj->getTypeName().c_str() << ")" << "obj->ref_counter=" << obj->getRefCounter(); if (reference_holders.size()) { map >::iterator it; for (it=reference_holders.begin(); it!=reference_holders.end(); ++it) { int obj_id = it->first; foreach(FWObject *o, it->second) { FWObject *cobj = project->db()->findInIndex(obj_id); if (cobj) o->removeRef(cobj); } } } notify(); } void FWCmdMoveObject::notify() { // This command should only operate on moving objects from one // place in the tree to another but within the same data file QString filename = project->getFileName(); // QCoreApplication::postEvent( // mw, new reloadObjectTreeImmediatelyEvent(filename)); if (Library::isA(obj) && FWObjectDatabase::isA(obj->getParent())) { // library was undeleted abd moved from Deleted obj library to root QCoreApplication::postEvent( mw, new removeObjectFromTreeEvent(filename, obj->getId())); QCoreApplication::postEvent( mw, new addTreePageEvent(filename, obj->getId())); QCoreApplication::postEvent( mw, new updateObjectAndSubtreeImmediatelyEvent(filename, obj->getId())); } else { QCoreApplication::postEvent( mw, new removeObjectFromTreeEvent(filename, obj->getId())); QCoreApplication::postEvent( mw, new insertObjectInTreeEvent(filename, current_parent->getId(), obj->getId())); } QCoreApplication::postEvent( mw, new dataModifiedEvent(filename, old_parent->getId())); QCoreApplication::postEvent( mw, new dataModifiedEvent(filename, new_parent->getId())); FWObject *new_obj = NULL; if (current_parent->getId()==FWObjectDatabase::DELETED_OBJECTS_ID) { if (Library::isA(obj)) { // See #1740 // looks like the object that moved into Deleted Objects is // another library. Show Deleted Objects library if it is enabled. // if (fwbdebug) qDebug() << "Moved library to Deleted objects" << "old_parent=" << old_parent; if (st->getBool("UI/ShowDeletedObjects")) new_obj = current_parent; // should be "deleted objects" lib else { // new_obj = old_parent; // this does not work! new_obj = project->m_panel->om->getNextUserLib(obj); if (new_obj == NULL) { // no user libraries left, show "Standard" new_obj = old_parent->getRoot()->findInIndex( FWObjectDatabase::getIntId("syslib000")); } if (new_obj == NULL) new_obj = old_parent->getRoot()->front(); if (fwbdebug) qDebug() << "FWCmdMoveObject::notify() new_obj=" << new_obj; } } else new_obj = old_parent; } else { new_obj = obj; } QCoreApplication::postEvent(mw, new openLibraryForObjectEvent( filename, new_obj->getId())); // post openObjectInEditorEvent first so that editor panel opens. // This matters if the tree needs to scroll to show the object when // showObjectInTreeEvent is posted because vertical size of the tree // changes when editor opens if (mw->isEditorVisible()) QCoreApplication::postEvent(mw, new openObjectInEditorEvent( filename, new_obj->getId())); QCoreApplication::postEvent(mw, new showObjectInTreeEvent( filename, new_obj->getId())); } /****************************************************************/ FWCmdMoveToFromUserFolder::FWCmdMoveToFromUserFolder(ProjectPanel *project, FWObject *parent, FWObject *obj, const QString &oldFolder, const QString &newFolder, QString text, QUndoCommand *macro) : FWCmdChange(project, obj, text, false, macro), m_parentId(parent->getId()), m_oldFolder(oldFolder), m_newFolder(newFolder) { } void FWCmdMoveToFromUserFolder::redo() { FWCmdChange::redo(); FWObject *obj = getObject(); QString fileName = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); QCoreApplication::postEvent(mw, new moveToFromUserFolderEvent (fileName, m_parentId, obj->getId(), m_oldFolder, m_newFolder)); } void FWCmdMoveToFromUserFolder::undo() { FWCmdChange::undo(); FWObject *obj = getObject(); QString fileName = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); QCoreApplication::postEvent(mw, new moveToFromUserFolderEvent (fileName, m_parentId, obj->getId(), m_newFolder, m_oldFolder)); } fwbuilder-5.1.0.3599/src/libgui/procurveaclAdvancedDialog.cpp0000644000175000017500000003142411733011756024643 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "procurveaclAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; procurveaclAdvancedDialog::~procurveaclAdvancedDialog() { delete m_dialog; } procurveaclAdvancedDialog::procurveaclAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::procurveaclAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); // As of 4.1.0 we do not support scp install method for Procurve // I could not figure out how to copy configuration to the switch // even when "ip ssh filetransfer" command has been executed and scp // seems to work - I ran into problems with file permissions that // I could not resolve. This will remain a low priority TODO item. // See also commented out code in FirewallInstallerProcurve.cpp m_dialog->SCPgroupBox->setEnabled(false); string vers="version_"+obj->getStr("version"); string platform = obj->getStr("platform"); // should be 'procurve_acl' QString s; QStringList logLevels; QStringList logLevelMapping; logLevelMapping.push_back(""); logLevelMapping.push_back(""); /* filling pop-down menu and pushing the same strings to the mapping * list at the same time so we could use translation */ s=QObject::tr("0 - System Unusable"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("0"); s=QObject::tr("1 - Take Immediate Action"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("1"); s=QObject::tr("2 - Critical Condition"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("2"); s=QObject::tr("3 - Error Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("3"); s=QObject::tr("4 - Warning Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("4"); s=QObject::tr("5 - Normal but significant condition"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("5"); s=QObject::tr("6 - Informational"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("6"); s=QObject::tr("7 - Debug Message"); logLevels.push_back(s); logLevelMapping.push_back(s); logLevelMapping.push_back("7"); /* do not need to translate syslog facilities, but will use the same * method just in case */ QStringList syslogFacilities; QStringList syslogFacilityMapping; syslogFacilities.push_back(""); syslogFacilityMapping.push_back(""); syslogFacilityMapping.push_back(""); syslogFacilities.push_back("LOCAL0"); syslogFacilityMapping.push_back("LOCAL0"); syslogFacilityMapping.push_back("16"); syslogFacilities.push_back("LOCAL1"); syslogFacilityMapping.push_back("LOCAL1"); syslogFacilityMapping.push_back("17"); syslogFacilities.push_back("LOCAL2"); syslogFacilityMapping.push_back("LOCAL2"); syslogFacilityMapping.push_back("18"); syslogFacilities.push_back("LOCAL3"); syslogFacilityMapping.push_back("LOCAL3"); syslogFacilityMapping.push_back("19"); syslogFacilities.push_back("LOCAL4"); syslogFacilityMapping.push_back("LOCAL4"); syslogFacilityMapping.push_back("20"); syslogFacilities.push_back("LOCAL5"); syslogFacilityMapping.push_back("LOCAL5"); syslogFacilityMapping.push_back("21"); syslogFacilities.push_back("LOCAL6"); syslogFacilityMapping.push_back("LOCAL6"); syslogFacilityMapping.push_back("22"); syslogFacilities.push_back("LOCAL7"); syslogFacilityMapping.push_back("LOCAL7"); syslogFacilityMapping.push_back("23"); bool f1=fwoptions->getBool("procurve_acl_acl_basic"); bool f2=fwoptions->getBool("procurve_acl_acl_no_clear"); bool f3=fwoptions->getBool("procurve_acl_acl_substitution"); bool f4=fwoptions->getBool("procurve_acl_add_clear_statements"); /* * If none of the new procurve_acl_acl_* options is set and old procurve_acl_add_clear_statements * option is true, set procurve_acl_acl_basic to true. * * If old option procurve_acl_add_clear_statements iss false, set * procurve_acl_acl_no_clear to true */ if (!f1 && !f2 && !f3) { if ( f4 ) fwoptions->setBool("procurve_acl_acl_basic",true); else fwoptions->setBool("procurve_acl_acl_no_clear",true); } Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); data.registerOption(m_dialog->ipv4before_2, fwoptions, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") << "ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first" ); /* Page "Compiler Options" */ data.registerOption( m_dialog->outputFileName, fwoptions, "output_file" ); data.registerOption( m_dialog->procurve_acl_check_shadowing, fwoptions, "check_shading" ); data.registerOption( m_dialog->procurve_acl_ignore_empty_groups, fwoptions, "ignore_empty_groups" ); data.registerOption( m_dialog->mgmt_ssh, fwoptions, "mgmt_ssh" ); data.registerOption( m_dialog->mgmt_addr, fwoptions, "mgmt_addr" ); /* data.registerOption( m_dialog->procurve_acl_acl_alwaysNew, fwoptions, "procurve_acl_acl_always_new" ); */ /* Page Script options */ data.registerOption( m_dialog->procurve_acl_acl_basic, fwoptions, "procurve_acl_acl_basic" ); data.registerOption( m_dialog->procurve_acl_acl_no_clear, fwoptions, "procurve_acl_acl_no_clear" ); data.registerOption( m_dialog->procurve_acl_acl_substitution, fwoptions, "procurve_acl_acl_substitution" ); data.registerOption( m_dialog->procurve_acl_acl_temp_addr, fwoptions, "procurve_acl_acl_temp_addr" ); data.registerOption( m_dialog->procurve_acl_include_comments, fwoptions, "procurve_acl_include_comments" ); data.registerOption( m_dialog->procurve_acl_use_acl_remarks, fwoptions, "procurve_acl_use_acl_remarks" ); /* Page Installer */ data.registerOption( m_dialog->user, fwoptions, "admUser"); data.registerOption( m_dialog->altAddress, fwoptions, "altAddress"); data.registerOption( m_dialog->sshArgs, fwoptions, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwoptions, "scpArgs"); data.registerOption( m_dialog->use_scp, fwoptions, "use_scp"); data.registerOption( m_dialog->filesystem, fwoptions, "filesystem"); data.registerOption( m_dialog->filesystem, fwoptions, "firewall_dir"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText(pis->getCommand().c_str() ); m_dialog->installScriptArgs->setText( pis->getArguments().c_str() ); /* page "Prolog/Epilog" */ data.registerOption( m_dialog->procurve_acl_prolog_script, fwoptions, "procurve_acl_prolog_script" ); data.registerOption( m_dialog->procurve_acl_epilog_script, fwoptions, "procurve_acl_epilog_script" ); /* page Logging */ data.registerOption(m_dialog->generate_logging_commands, fwoptions, "procurve_acl_generate_logging_commands"); data.registerOption(m_dialog->syslog_host, fwoptions, "procurve_acl_syslog_host"); m_dialog->syslog_facility->clear(); m_dialog->syslog_facility->addItems( syslogFacilities ); data.registerOption( m_dialog->syslog_facility, fwoptions, "procurve_acl_syslog_facility", syslogFacilityMapping); m_dialog->logging_trap_level->clear(); m_dialog->logging_trap_level->addItems(logLevels); data.registerOption( m_dialog->logging_trap_level, fwoptions, "procurve_acl_logging_trap_level", logLevelMapping); data.registerOption(m_dialog->logging_timestamp, fwoptions, "procurve_acl_logging_timestamp"); data.registerOption(m_dialog->logging_buffered, fwoptions, "procurve_acl_logging_buffered"); m_dialog->logging_buffered_level->clear(); m_dialog->logging_buffered_level->addItems(logLevels); data.registerOption( m_dialog->logging_buffered_level, fwoptions, "procurve_acl_logging_buffered_level", logLevelMapping); data.registerOption(m_dialog->logging_console, fwoptions, "procurve_acl_logging_console"); m_dialog->logging_console_level->clear(); m_dialog->logging_console_level->addItems(logLevels); data.registerOption( m_dialog->logging_console_level,fwoptions, "procurve_acl_logging_console_level", logLevelMapping); data.loadAll(); scriptACLModeChanged(); toggleGenerateLogging(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void procurveaclAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* options = Firewall::cast(new_state)->getOptionsObject(); assert(options!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(options); const InetAddr *mgmt_addr = Firewall::cast(obj)->getManagementAddress(); if (mgmt_addr) mgmt->setAddress(*mgmt_addr); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); pis->setCommand( m_dialog->installScript->text().toLatin1().constData() ); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void procurveaclAdvancedDialog::reject() { QDialog::reject(); } void procurveaclAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->procurve_acl_prolog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->procurve_acl_prolog_script->setText( edt.text() ); } void procurveaclAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->procurve_acl_epilog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->procurve_acl_epilog_script->setText( edt.text() ); } void procurveaclAdvancedDialog::scriptACLModeChanged() { m_dialog->procurve_acl_acl_temp_lbl->setEnabled( m_dialog->procurve_acl_acl_substitution->isChecked()); m_dialog->procurve_acl_acl_temp_addr->setEnabled( m_dialog->procurve_acl_acl_substitution->isChecked()); } void procurveaclAdvancedDialog::toggleGenerateLogging() { m_dialog->syslog_controls->setEnabled( m_dialog->generate_logging_commands->isChecked()); m_dialog->other_logging_controls->setEnabled( m_dialog->generate_logging_commands->isChecked()); } fwbuilder-5.1.0.3599/src/libgui/utils.cpp0000644000175000017500000004135111733011756020710 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FWBSettings.h" #include "fwbuilder/dns.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Library.h" #include "fwbuilder/Resources.h" #if defined(_WIN32) # include # include # include # include # include # include #else # include # include # include # include #endif #include #include #include #include "FWBTree.h" using namespace std; using namespace libfwbuilder; QAction* addPopupMenuItem(QObject *res, QMenu* menu, const QString &resourceIconPath, const QString itemName, const char* member, const QKeySequence &accel) { string icn; QPixmap pm; //int itmID = -1; QAction *act = NULL; icn = Resources::global_res->getResourceStr(static_cast(resourceIconPath.toLatin1())); if(icn!="") { // pm = QPixmap::fromMimeSource( icn.c_str() ); if ( ! QPixmapCache::find( icn.c_str(), pm) ) { pm.load( (":/"+icn).c_str() );//fromMimeSource( icn.c_str() ); QPixmapCache::insert( icn.c_str(), pm); } act = menu->addAction( pm, itemName , res , member, accel ); //insertItem } else act = menu->addAction( itemName , res , member, accel); //insertItem return act; } void fillLibraries(QComboBox *libs, libfwbuilder::FWObject *obj, bool rw) { bool standardObj = false; bool templateObj = false; bool deletedObj = false; QString lib=""; if ( ! FWObjectDatabase::isA(obj)) { FWObject *libobj = obj->getLibrary(); assert(libobj!=NULL); lib = libobj->getName().c_str(); standardObj = (libobj->getId()==FWObjectDatabase::STANDARD_LIB_ID); templateObj = (libobj->getId()==FWObjectDatabase::TEMPLATE_LIB_ID); deletedObj = (libobj->getId()==FWObjectDatabase::DELETED_OBJECTS_ID); } libs->clear(); list ll = obj->getRoot()->getByType( Library::TYPENAME ); ll.sort(FWObjectNameCmpPredicate()); int n=0; int cn=0; string libicn; for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if (libicn.empty()) libicn=(":/Icons/"+(*i)->getTypeName()+"/icon-tree").c_str(); if ( (*i)->getId()==FWObjectDatabase::STANDARD_LIB_ID && !standardObj) continue; if ( (*i)->getId()==FWObjectDatabase::TEMPLATE_LIB_ID && !templateObj) continue; if ( (*i)->getId()==FWObjectDatabase::DELETED_OBJECTS_ID && !deletedObj ) continue; if (rw && (*i)->isReadOnly()) continue; if (lib==QString((*i)->getName().c_str())) cn=n; QPixmap icon; icon.load( (libicn).c_str() ); libs->addItem(icon, QString::fromUtf8((*i)->getName().c_str()) ); n++; } libs->setCurrentIndex(cn); } void fillLibraries(QListWidget *libs, libfwbuilder::FWObject *obj, bool rw) { bool standardObj = false; bool templateObj = false; bool deletedObj = false; QString lib=""; if ( ! FWObjectDatabase::isA(obj)) { FWObject *libobj = obj->getLibrary(); assert(libobj!=NULL); lib = libobj->getName().c_str(); standardObj = (libobj->getId()==FWObjectDatabase::STANDARD_LIB_ID); templateObj = (libobj->getId()==FWObjectDatabase::TEMPLATE_LIB_ID); deletedObj = (libobj->getId()==FWObjectDatabase::DELETED_OBJECTS_ID); } libs->clear(); list ll = obj->getRoot()->getByType( Library::TYPENAME ); ll.sort(FWObjectNameCmpPredicate()); int n=0; int cn=0; string libicn; for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if (libicn.empty()) libicn=Resources::global_res->getObjResourceStr(*i,"icon-tree").c_str(); if ( (*i)->getId()==FWObjectDatabase::STANDARD_LIB_ID && !standardObj) continue; if ( (*i)->getId()==FWObjectDatabase::TEMPLATE_LIB_ID && !templateObj) continue; if ( (*i)->getId()==FWObjectDatabase::DELETED_OBJECTS_ID && !deletedObj ) continue; if (rw && (*i)->isReadOnly()) continue; if (lib==QString((*i)->getName().c_str())) cn=n; QPixmap icon; icon.load( (":/"+libicn).c_str() ); QListWidgetItem *item = new QListWidgetItem(icon, (*i)->getName().c_str()); libs->addItem(item); n++; } libs->setCurrentRow(cn); } bool isTreeReadWrite(QWidget *parent, FWObject *obj) { if (obj->isReadOnly()) { QMessageBox::warning( parent, "Firewall Builder", QObject::tr("Impossible to apply changes because object is " "located in read-only\npart of the tree or data " "file was opened read-only"), QObject::tr("&Continue"), 0, 0, 0, 2 ); return false; } return true; } /* * compare names as QString objects to catch non-ascii names */ bool validateName(QWidget *parent, FWObject *obj, const QString &newname) { if (newname.isEmpty()) { // show warning dialog only if app has focus if (QApplication::focusWidget() != NULL) { parent->blockSignals(true); QMessageBox::warning( parent, "Firewall Builder", QObject::tr("Object name should not be blank"), QObject::tr("&Continue"), NULL, NULL, 0, 2 ); parent->blockSignals(false); } return false; } FWObject *p = obj->getParent(); for (FWObject::iterator i=p->begin(); i!=p->end(); ++i) { FWObject *o1= *i; // Another hack: we need to be able to create policy and nat // ruleset objects with name "ftp-proxy/*" for PF. Allow // objects of different type to have the same name. if (o1 == obj || o1->getTypeName() != obj->getTypeName()) continue; if (QString(o1->getName().c_str()) == newname) { /* * when we open this warning dialog, the dialog class * loses focus and obj_name lineEdit widget sends signal * "editingfinished" again. To the user this looks like the * warning dialog popped up twice (in fact two copies of the * same warning dialog appear at the same time, one exactly on * top of another). To avoid this, block signals for the * duration while we show the dialog. Note that documentation * does not mention that QObject::blockSignals() affects not * only the widget but all its children, but it seems to work * that way. Tested with Qt 4.6.1. See #1171 */ // show warning dialog only if app has focus if (QApplication::focusWidget() != NULL) { parent->blockSignals(true); QMessageBox::warning( parent, "Firewall Builder", QObject::tr("Object with name '%1' already exists, " "please choose different name."). arg(o1->getName().c_str()), QObject::tr("&Continue"), NULL, NULL, 0, 2 ); parent->blockSignals(false); } return false; } } return true; } QString quoteString(const QString &str) { QString res; if (str.indexOf(" ")!=-1) res="\""; res+=str; if (str.indexOf(" ")!=-1) res+="\""; return res; } QString getFileDir(const QString &file) { return QFileInfo(file).dir().path(); } void setDisabledPalette(QWidget *w) { QPalette pal=w->palette(); pal.setCurrentColorGroup( QPalette::Active ); pal.setColor( QPalette::Text, Qt::black ); pal.setCurrentColorGroup( QPalette::Inactive ); pal.setColor( QPalette::Text, Qt::black ); pal.setCurrentColorGroup( QPalette::Disabled ); pal.setColor( QPalette::Text, Qt::black ); w->setPalette( pal ); } QString getAddrByName(const QString &name, int af_type) { list results; try { results = DNS::getHostByName(name.toAscii().constData(), af_type); } catch (FWException &e) { if (fwbdebug) qDebug("utils::getAddrByName: DNS lookup error: %s", e.toString().c_str()); return ""; } try { if (results.size()>0) return QString(results.front().toString().c_str()); } catch (FWException &e) { qDebug() << "utils::getAddrByName: Can not convert address to string"; qDebug() << e.toString().c_str(); } return ""; #if 0 QHostInfo a = QHostInfo::fromName(name); QList alist = a.addresses(); if (alist.empty()) return ""; return alist.front().toString(); #endif } QString getNameByAddr(const QString &addr) { /*QHostAddress ha; ha.setAddress(addr); Q3Dns qry( ha, Q3Dns::Ptr); QStringList nlist = qry.hostNames(); while (qry.isWorking()) { app->processEvents(200); } nlist = qry.hostNames(); if (nlist.empty()) return ""; return nlist.front();*/ QHostInfo a = QHostInfo::fromName(addr); return a.hostName(); } QString wordWrap(const QString& s, int maxchinline) { int chcount=0; int lastwdpos=0; int linestart=0; bool fl_wd=true; /*unsigned*/ int pos=0; QString res=""; QChar ch; for ( ; pos < s.length(); pos++,chcount++) { ch = s.at(pos); if (!ch.isLetter() && !ch.isNumber()) { fl_wd=false; } else { if (!fl_wd) { fl_wd=true; lastwdpos=pos; } } if (chcount>maxchinline) { if (fl_wd) { if (linestartgetTypeName()+"/icon-tree").c_str(); LoadPixmap(icn_file, pm); // if ( ! QPixmapCache::find( icn_file, pm) ) // { // pm.load( icn_file ); // QPixmapCache::insert( icn_file, pm); // } } void LoadPixmap(const QString &path, QPixmap &pm) { if ( ! QPixmapCache::find( path, pm ) ) { pm.load( path ); if (pm.width() == 0) qDebug("pixmap load failed: %s", path.toAscii().constData()); QPixmapCache::insert( path, pm ); } } QPixmap LoadPixmap(const QString &path) { QPixmap p; LoadPixmap(path, p); return p; } QString calculateIconName(const QString &_icn, bool negation) { // if _icn has white space, use only the first word QStringList icnl = _icn.split(" "); QString icn = ":/Icons/" + icnl[0] + "/icon"; if (negation) { icn = icn + "-neg"; } if (FWBSettings::SIZE16X16 == st->getIconsInRulesSize()) { return icn+"-tree"; } return icn; } void doSetObjectIcon(FWObject *obj, QPixmap *pm, int icon_size) { QString icn_alias; QString icn_sfx; switch (icon_size) { case 0: icn_sfx = "icon-tree"; break; case 2: icn_sfx = "icon-big"; break; default: icn_sfx = "icon"; break; } // note that we do not have "locked" version of large icons if (obj->getRO() && icon_size != 2) icn_alias = ":/Icons/lock"; else { if (FWBTree().isStandardFolder(obj)) icn_alias = ":/Icons/SystemGroup/" + icn_sfx; else icn_alias = QString(":/Icons/") + obj->getTypeName().c_str() + "/" + icn_sfx; } LoadPixmap(icn_alias, *pm); } QString _getNextToken(QStringList &args) { QString a; while (args.size() > 0) { a = args.front(); args.pop_front(); if (!a.isEmpty()) break; } return a; } // reassemble quoted strings from the list of tokens, possibly // recursively if there are quoted strings inside. The first token is // assumed to be " or '. Pops all processed tokens from the list but // leaves the rest in it. QString _parseTokens(QStringList &args, const QChar closing_quote='\0') { QString a = _getNextToken(args); if (args.size() == 0) return a; if (closing_quote != '\0' && a.endsWith(closing_quote)) return a; if (a.startsWith("\"") || a.startsWith("'")) { QStringList res; QChar closing_quote = a[0]; res.append(a); while (!a.endsWith(closing_quote) && args.size() > 0) { a = _parseTokens(args, closing_quote); res.append(a); } return res.join(" "); } return a; } /** * parse command line for ssh or scp given by user in the global * preferences dialog. The challenge is to be able to handle situation * when the program is installed in directory with a whitespace in the * name, so we can't just split the string by a " ". * * Recognize the following constructs: * * /path/to/program/program -arg1 val1 -arg2 val2 -arg3 "value 3" * * everything before the first "-" is considered executable name * (possibly with full path) * * word that starts with "-" or "/" preceded by a space is an argument * argument may have an optional parameter * parameter may be quoted using double or single quotes */ void parseCommandLine(const QString &cmd, QStringList &argv) { int first_arg = cmd.indexOf(QRegExp(" *-")); if (first_arg == -1) { // no arguments argv.append(cmd.trimmed()); return; } QString program = cmd.mid(0, first_arg).trimmed(); if (!program.isEmpty()) argv.append(program); QStringList args = cmd.mid(first_arg).split(QRegExp("\\s+")); // QString::SkipEmptyParts); // splits like this: // ["", "-arg1", "val1", "-arg2", "\"value", "2", "\""] while (args.size() > 0) { QString t = _parseTokens(args); // remove quotes from quoted strings if ((t.startsWith('\"') && t.endsWith('\"')) || (t.startsWith('\'') || t.endsWith('\''))) { t = t.mid(1, t.length()-2); } argv.append(t); } } static bool stringsCompare(const QString &a, const QString &b) { QString aLower = a.toLower(); QString bLower = b.toLower(); int result = aLower.localeAwareCompare(bLower); if (result == 0) { return a.localeAwareCompare(b) < 0; } else { return result < 0; } } QStringList sortStrings(const QStringList &list) { QStringList ret = list; qSort(ret.begin(), ret.end(), stringsCompare); return ret; } fwbuilder-5.1.0.3599/src/libgui/ProjectPanel.cpp0000644000175000017500000007763711733011756022156 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com refactoring and bugfixes: vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include #include #include #include #include #include #include "fwbuilder/RuleSet.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "FWBSettings.h" #include "FWBTree.h" #include "FWObjectPropertiesFactory.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "RCS.h" #include "RuleSetView.h" #include "findDialog.h" #include "events.h" #include "ObjectTreeView.h" #include "FWObjectClipboard.h" #include "WorkflowIcons.h" #include "FirewallCodeViewer.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Ui; using namespace libfwbuilder; using namespace std; void ProjectPanel::initMain(FWWindow *main) { mainW = main; mdiWindow = NULL; treeReloadPending = false; // mdiWindow changes state several times right after it is opened, // but we call saveState to store splitter position and its geometry // when state changes. Flag "ready" is false after ProjectPanel is created // and until FWWindow decides that ProjectPanel is ready for operation. // Do not load or save state if flag ready is false. ready = false; int total_width = DEFAULT_H_SPLITTER_POSITION; int total_height = DEFAULT_V_SPLITTER_POSITION; if (mainW) { total_width = mainW->width(); total_height = mainW->height(); } setMainSplitterPosition(DEFAULT_H_SPLITTER_POSITION, total_width - DEFAULT_H_SPLITTER_POSITION); loading_state = false; oldState=-1; main->undoGroup->addStack(undoStack); fd = new findDialog(this, this); fd->hide(); m_panel->icons->setUpSignals(this); } void ProjectPanel::reset() { undoStack->clear(); delete rcs; rcs = NULL; firewalls.clear(); visibleFirewall = NULL; visibleRuleSet = NULL; clearFirewallTabs(); clearObjects(); FWObjectClipboard::obj_clipboard->clear(); } ProjectPanel::ProjectPanel(QWidget *parent): QWidget(parent), // , Qt::WindowSystemMenuHint|Qt::Window), mainW(0), rcs(0), systemFile(true), safeMode(false), editingStandardLib(false), editingTemplateLib(false), ruleSetRedrawPending(false), objdb(0), fd(0), autosaveTimer(new QTimer(static_cast(this))), ruleSetTabIndex(0), visibleFirewall(0), visibleRuleSet(0), lastFirewallIdx(-2), changingTabs(false), noFirewalls(tr("No firewalls defined")), m_panel(0), undoStack(0) { if (fwbdebug) qDebug("ProjectPanel constructor"); m_panel = new Ui::ProjectPanel_q(); m_panel->setupUi(this); m_panel->om->setupProject(this); m_panel->toolbar->hide(); undoStack = new QUndoStack(this); setWindowTitle(getPageTitle()); if (fwbdebug) qDebug("New ProjectPanel %p", this); connect(m_panel->topSplitter, SIGNAL(splitterMoved(int,int)), this, SLOT(splitterPositionChanged(int,int))); } ProjectPanel::~ProjectPanel() { if (fwbdebug) qDebug() << "ProjectPanel::~ProjectPanel()"; undoStack->clear(); if (rcs) delete rcs; if (objdb) delete objdb; delete m_panel; if (fwbdebug) qDebug() << "ProjectPanel::~ProjectPanel() done"; } QString ProjectPanel::getPageTitle(bool file_path) { QString default_caption = tr("Untitled"); if (rcs) { QString caption; if (file_path) caption = rcs->getFileName(); // full path else { QFileInfo fi(rcs->getFileName()); caption = fi.fileName(); } if (rcs->isInRCS()) caption= caption + ", rev " + rcs->getSelectedRev(); if (rcs->isRO()) caption = caption + " " + tr("(read-only)"); if (caption.isEmpty()) return default_caption; return caption; } else return default_caption; } void ProjectPanel::restoreRuleSetTab() { if (fwbdebug) qDebug("ProjectPanel::()"); m_panel->ruleSets->setCurrentIndex(ruleSetTabIndex); m_panel->toolbar->show(); } void ProjectPanel::loadObjects() { m_panel->om->loadObjects(); } void ProjectPanel::loadObjects(FWObjectDatabase*) { m_panel->om->loadObjects(); } void ProjectPanel::clearObjects() { m_panel->om->clearObjects(); } void ProjectPanel::clearFirewallTabs() { if (fwbdebug) qDebug() << "ProjectPanel::clearFirewallTabs"; m_panel->ruleSets->hide(); while (m_panel->ruleSets->count()!=0) { QWidget *p = m_panel->ruleSets->widget(0); m_panel->ruleSets->removeWidget( m_panel->ruleSets->widget(m_panel->ruleSets->indexOf(p))); delete p; } m_panel->rulesetname->setText(""); m_panel->ruleSets->show(); ruleSetViews.clear(); } void ProjectPanel::closeRuleSetPanel() { if (fwbdebug) qDebug() << "ProjectPanel::closeRuleSetPanel"; clearFirewallTabs(); visibleRuleSet = NULL; } void ProjectPanel::ensureObjectVisibleInRules(FWReference *obj) { if (fwbdebug) qDebug() << "ProjectPanel::ensureObjectVisibleInRules"; FWObject *p=obj; while (p && RuleSet::cast(p)==NULL ) p=p->getParent(); if (p==NULL) return; // something is broken // p is a pointer to RuleSet object @obj belongs to if (p != getCurrentRuleSet()) openRuleSet(p); getCurrentRuleSetView()->setFocus(); getCurrentRuleSetView()->selectRE( obj ); } RuleSetView * ProjectPanel::getCurrentRuleSetView() { return dynamic_cast(m_panel->ruleSets->currentWidget()); } void ProjectPanel::reopenFirewall() { if (fwbdebug) qDebug("ProjectPanel::reopenFirewall()"); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::reopenFirewall(): checkpoint 1: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); if (ruleSetRedrawPending) return; int currentPage = m_panel->ruleSets->currentIndex(); SelectionMemento memento; RuleSetView* rv = dynamic_cast(m_panel->ruleSets->currentWidget()); if (rv) rv->saveCurrentRowColumn(memento); last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::reopenFirewall(): checkpoint 2: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); // since reopenFirewall deletes and recreates all RuleSetView // widgets, it causes significant amount of repaint and // flicker. Disable updates for the duration of operation to avoid // that. m_panel->ruleSets->setUpdatesEnabled(false); changingTabs = true; clearFirewallTabs(); last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::reopenFirewall(): checkpoint 3: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); if (visibleRuleSet==NULL) return ; for (int i =0 ; i < m_panel->ruleSets->count (); i++) m_panel->ruleSets->removeWidget(m_panel->ruleSets->widget(i)); m_panel->rulesetname->setTextFormat(Qt::RichText); updateFirewallName(); last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::reopenFirewall(): checkpoint 4: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); RuleSetView* rulesetview = RuleSetView::getRuleSetViewByType(this, visibleRuleSet, NULL); if (rulesetview) { m_panel->ruleSets->addWidget(rulesetview); last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::reopenFirewall(): checkpoint 5: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); m_panel->ruleSets->setCurrentIndex(currentPage); m_panel->toolbar->show(); rv = dynamic_cast(m_panel->ruleSets->currentWidget()); rv->restoreCurrentRowColumn(memento); changingTabs = false; mainW->updateGlobalToolbar(); m_panel->ruleSets->setUpdatesEnabled(true); m_panel->ruleSets->show(); } } int ProjectPanel::findFirewallInList(FWObject *f) { vector::iterator i; int n=0; for (i=firewalls.begin(); i!=firewalls.end(); i++,n++) { if ( (*i)->getId()==f->getId() ) return n; } return -1; } void ProjectPanel::updateFirewallName() { if (visibleRuleSet==NULL) return ; QString name; // mw->buildEditorTitleAndIcon(visibleRuleSet, ObjectEditor::optNone, // &name, NULL, false); // name = "" + name + ""; FWObject *fw = visibleRuleSet->getParent(); name = QString("%1 / %2") .arg(QString::fromUtf8(fw->getName().c_str())) .arg(QString::fromUtf8(visibleRuleSet->getName().c_str())); m_panel->rulesetname->setText(name ); } void ProjectPanel::openRuleSet(FWObject * obj, bool immediately) { //mw->blankEditor(); visibleRuleSet = RuleSet::cast(obj); if (immediately) redrawRuleSets(); else registerRuleSetRedrawRequest(); } void ProjectPanel::selectRules() { // `unselect(); RuleSetView* rv = dynamic_cast( m_panel->ruleSets->currentWidget()); if (rv) rv->setFocus(); } void ProjectPanel::unselectRules() { bool havePolicies = (m_panel->ruleSets->count()!=0); /* commented this out so that when I hit "Edit" in the object's pop-down * menu in a rule, ruleset wont lose focus when object editor is opened. * If rule set loses focus, the object's background turns from "selected" color * to white and user loses context (which object is shown in the object editor) */ if (havePolicies) { RuleSetView* rv=dynamic_cast(m_panel->ruleSets->currentWidget()); if (rv && rv->getSelectedObject()!=getSelectedObject()) { rv->clearFocus(); } } mainW->disableActions(havePolicies); } void ProjectPanel::editCopy() { if (fwbdebug) qDebug() << "ProjectPanel::editCopy() isManipulatorSelected()=" << isManipulatorSelected(); if (isManipulatorSelected()) copyObj(); else { if (m_panel->ruleSets->count()!=0) { RuleSetView *rsv = dynamic_cast(m_panel->ruleSets->currentWidget()); if (rsv) rsv->copySelectedObject(); } } } void ProjectPanel::editCut() { if (fwbdebug) qDebug() << "ProjectPanel::editCut() isManipulatorSelected()=" << isManipulatorSelected(); if (isManipulatorSelected()) cutObj(); else { if (m_panel->ruleSets->count()!=0) { RuleSetView *rsv = dynamic_cast(m_panel->ruleSets->currentWidget()); if (rsv) rsv->cutSelectedObject(); } } } void ProjectPanel::editDelete() { if (fwbdebug) qDebug() << "ProjectPanel::editDelete() isManipulatorSelected()=" << isManipulatorSelected(); if (isManipulatorSelected()) deleteObj(); } void ProjectPanel::editPaste() { if (fwbdebug) qDebug() << "ProjectPanel::editPaste() isManipulatorSelected()=" << isManipulatorSelected(); if (isManipulatorSelected()) pasteObj(); else { if (m_panel->ruleSets->count()!=0) { RuleSetView *rsv = dynamic_cast(m_panel->ruleSets->currentWidget()); if (rsv) rsv->pasteObject(); } } } void ProjectPanel::setFileName(const QString &fname) { systemFile = false; rcs->setFileName(fname); db()->setFileName(fname.toLatin1().constData()); //setWindowTitle(getPageTitle()); QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); } //wrapers for some ObjectManipulator functions FWObject* ProjectPanel::getCurrentLib() { return m_panel->om->getCurrentLib(); } void ProjectPanel::updateObjectInTree(FWObject *obj, bool subtree) { m_panel->om->updateObjectInTree(obj, subtree); } FWObject* ProjectPanel::createObject(const QString &objType, const QString &objName, FWObject *copyFrom) { return m_panel->om->createObject(objType, objName, copyFrom); } FWObject* ProjectPanel::createObject(FWObject *parent, const QString &objType, const QString &objName, FWObject *copyFrom) { return m_panel->om->createObject(parent, objType, objName, copyFrom); } void ProjectPanel::moveObject(FWObject *target, FWObject *obj) { m_panel->om->moveObject(target, obj); } void ProjectPanel::moveObject(const QString &targetLibName, FWObject *obj) { m_panel->om->moveObject(targetLibName, obj); } FWObject* ProjectPanel::pasteTo(FWObject *target, FWObject *obj) { return m_panel->om->pasteTo(target, obj); } ObjectTreeView* ProjectPanel::getCurrentObjectTree() { return m_panel->om->getCurrentObjectTree(); } void ProjectPanel::findAllFirewalls (std::list &fws) { m_panel->om->findAllFirewalls(fws); } void ProjectPanel::showDeletedObjects(bool f) { m_panel->om->showDeletedObjects(f); } void ProjectPanel::select() { m_panel->om->select(); } void ProjectPanel::unselect() { m_panel->om->unselect(); } void ProjectPanel::clearManipulatorFocus() { m_panel->om->clearFocus(); } void ProjectPanel::copyObj() { m_panel->om->copyObj(); } bool ProjectPanel::isManipulatorSelected() { return m_panel->om->getCurrentObjectTree()->hasFocus(); } void ProjectPanel::cutObj() { m_panel->om->cutObj(); } void ProjectPanel::pasteObj() { m_panel->om->pasteObj(); } void ProjectPanel::newObject() { m_panel->om->newObject(); } void ProjectPanel::deleteObj() { m_panel->om->delObj(); } FWObject* ProjectPanel::getSelectedObject() { return m_panel->om->getSelectedObject(); } void ProjectPanel::reopenCurrentItemParent() { m_panel->om->reopenCurrentItemParent(); } void ProjectPanel::lockObject() { m_panel->om->lockObject(); } void ProjectPanel::unlockObject() { m_panel->om->unlockObject(); } void ProjectPanel::setFDObject(FWObject *o) { fd->setObject(o); fd->show(); } void ProjectPanel::resetFD() { fd->reset(); } void ProjectPanel::insertRule() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->insertRule(); } void ProjectPanel::addRuleAfterCurrent() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->addRuleAfterCurrent(); } void ProjectPanel::removeRule() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->removeRule(); } void ProjectPanel::moveRule() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->moveRule(); } void ProjectPanel::moveRuleUp() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->moveRuleUp(); } void ProjectPanel::moveRuleDown() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->moveRuleDown(); } void ProjectPanel::copyRule() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->copyRule(); } void ProjectPanel::cutRule() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->cutRule(); } void ProjectPanel::pasteRuleAbove() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->pasteRuleAbove(); } void ProjectPanel::pasteRuleBelow() { if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return; getCurrentRuleSetView()->pasteRuleBelow(); } bool ProjectPanel::editingLibrary() { return (rcs!=NULL && ( rcs->getFileName().endsWith(".fwl")) ); } void ProjectPanel::createRCS(const QString &filename) { rcs = new RCS(filename); systemFile = true; } RCS * ProjectPanel::getRCS() { return rcs; } /* * This slot is connected to the "add rule" button in the mini-toolbar * at the top of the rule set view */ void ProjectPanel::addRule() { if (visibleRuleSet==NULL || getCurrentRuleSetView()==NULL) return ; getCurrentRuleSetView()->insertRule(); } void ProjectPanel::compileThis() { if (visibleRuleSet==NULL) return ; save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; set fw; Firewall *f = Firewall::cast(visibleRuleSet->getParent()); if (f) { fw.insert(f); mainW->compile(fw); } } void ProjectPanel::installThis() { if (visibleRuleSet==NULL) return ; save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; set fw; Firewall *f = Firewall::cast(visibleRuleSet->getParent()); if (f) { fw.insert(f); mainW->install(fw); } } void ProjectPanel::inspectThis() { if (visibleRuleSet==NULL) return; save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; Firewall *f = Firewall::cast(visibleRuleSet->getParent()); set fwlist; if (Cluster::isA(f)) { std::list cfws; Cluster::cast(f)->getMembersList(cfws); foreach(Firewall *fw, cfws) fwlist.insert(fw); } else { fwlist.insert(f); } this->inspect(fwlist); } void ProjectPanel::inspectAll() { ObjectManipulator *om = this->findChild(); list fws; om->findAllFirewalls(fws); set fwset; foreach(Firewall *fw, fws) { if (Cluster::isA(fw)) { std::list cfws; Cluster::cast(fw)->getMembersList(cfws); foreach(Firewall *f, cfws) fwset.insert(f); } else { fwset.insert(fw); } } this->inspect(fwset); } void ProjectPanel::compile() { if (mw->isEditorVisible() && !mw->requestEditorOwnership(NULL,NULL,ObjectEditor::optNone,true)) return; save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; //fileSave(); mainW->compile(); } void ProjectPanel::compile(set vf) { if (mw->isEditorVisible() && !mw->requestEditorOwnership(NULL, NULL, ObjectEditor::optNone, true)) return; save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; //fileSave(); mainW->compile(vf); } void ProjectPanel::install(set vf) { save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; mainW->install(vf); } void ProjectPanel::install() { save(); // see comment in FWWindow::compile() if (db()->isDirty()) return; mainW->install(); } void ProjectPanel::inspect(set fws) { if (fws.empty()) return; QMessageBox messageBox(this); messageBox.addButton(tr("Cancel"), QMessageBox::RejectRole); messageBox.addButton(tr("Compile and Inspect files"), QMessageBox::AcceptRole); messageBox.setIcon(QMessageBox::Critical); set needCompile; foreach(Firewall *fw, fws) if (fw->needsCompile()) needCompile.insert(fw); if (!needCompile.empty()) { QString text; QStringList names; foreach(Firewall *fw, needCompile) names.append(fw->getName().c_str()); if (needCompile.size() > 1 && needCompile.size() < 5) { QString last = names.last(); names.pop_back(); QString firewalls = "\"" + names.join("\", \"") + "\" " + tr("and") + " \"" + last + "\""; text = tr("Firewall objects %1 have been modified and need to be recompiled.").arg(firewalls); } else if (needCompile.size() == 1) text = tr("Firewall object \"%1\" has been modified and needs to be recompiled.").arg(names.first()); else { text = tr("%1 firewall objects have been modified and need to be recompiled.").arg(needCompile.size()); } messageBox.setText(text); messageBox.exec(); if (messageBox.result() == QMessageBox::Accepted) { this->compile(needCompile); } return; } QStringList files; QSet filesMissing; Firewall *first_fw = NULL; foreach(Firewall *fw, fws) { if (first_fw == NULL) first_fw = fw; /* * get full path to the generated file. The path is built from * the file name returned by * FirewallInstaller::getGeneratedFileName() and directory * path from the .fwb file. Note that we use the same * algorithm when GUI launches policy compiler, except there * the path is passed to it via "-d" command line option. */ QString mainFile = FirewallInstaller::getGeneratedFileFullPath(fw); // QString mainFile = FirewallInstaller::getGeneratedFileName(fw); if (QFile::exists(mainFile)) { instConf cnf; cnf.fwobj = fw; cnf.script = mainFile; QMap res; FirewallInstaller(NULL, &cnf, "").readManifest(mainFile, &res); QStringList current_files = res.keys(); foreach(QString file, current_files) { if (!QFile::exists(file)) filesMissing.insert(fw); else files.append(file); } } else filesMissing.insert(fw); } if (!filesMissing.isEmpty()) { QString text; QStringList names; foreach(Firewall *fw, filesMissing) names.append(fw->getName().c_str()); if (filesMissing.size() > 1 && filesMissing.size() < 5) { QString last = names.last(); names.pop_back(); QString firewalls = "\"" + names.join("\", \"") + "\" " + tr("and") + " \"" + last + "\""; text = tr("Can not read generated files for the firewall objects %1. You need to compile them to create the files.").arg(firewalls); } else if (filesMissing.size() == 1) text = tr("Can not read generated files for the firewall objects %1. You need to compile it to create the files.").arg(names.first()); else { text = tr("Can not read generated files for the %1 firewall objects. You need to compile then to create the files.").arg(filesMissing.size()); } messageBox.setText(text); messageBox.exec(); if (messageBox.result() == QMessageBox::Accepted) { this->compile(fws); } return; } if (files.empty()) return; QString viewer_title; if (fws.size() > 1) viewer_title = tr("Multiple firewalls"); else viewer_title = QString("%1").arg(first_fw->getName().c_str()); FirewallCodeViewer *viewer = new FirewallCodeViewer(files, viewer_title, this); viewer->show(); } QString ProjectPanel::printHeader() { QString headerText = rcs->getFileName().section("/",-1,-1); if (rcs->isInRCS()) headerText = headerText + ", rev " + rcs->getSelectedRev(); return headerText; } void ProjectPanel::registerRuleSetRedrawRequest() { if (!ruleSetRedrawPending) { ruleSetRedrawPending = true; //redrawRuleSets(); QTimer::singleShot( 0, this, SLOT(redrawRuleSets()) ); } } void ProjectPanel::redrawRuleSets() { ruleSetRedrawPending = false; reopenFirewall(); } void ProjectPanel::aboutToActivate() { if (fwbdebug) qDebug() << "ProjectPanel::aboutToActivate " << this; } void ProjectPanel::showEvent(QShowEvent *ev) { if (fwbdebug) qDebug() << "ProjectPanel::showEvent " << this << "title " << mdiWindow->windowTitle(); QWidget::showEvent(ev); // we get this event when MDI window is maximized or restored // loadState(); // visibilityChangedForTreePanel(true); } void ProjectPanel::hideEvent(QHideEvent *ev) { if (fwbdebug) qDebug() << "ProjectPanel::hideEvent " << this << "title " << mdiWindow->windowTitle(); QWidget::hideEvent(ev); } void ProjectPanel::closeEvent(QCloseEvent * ev) { if (fwbdebug) qDebug() << "ProjectPanel::closeEvent " << this << "title " << mdiWindow->windowTitle(); if (!saveIfModified() || !checkin(true)) { ev->ignore(); return; } saveState(); fileClose(); mw->updateWindowTitle(); //QCoreApplication::postEvent(mw, new closeEditorPanelEvent()); QCoreApplication::postEvent(mw, new clearEditorPanelEvent()); QTimer::singleShot( 0, mw, SLOT(projectWindowClosed()) ); } QString ProjectPanel::getFileName() { if (rcs!=NULL) return rcs->getFileName(); else return ""; } void ProjectPanel::splitterMoved(int , int) { } void ProjectPanel::resizeEvent(QResizeEvent*) { } void ProjectPanel::registerTreeReloadRequest() { treeReloadPending = true; QTimer::singleShot(0, this, SLOT(reloadTree())); } void ProjectPanel::reloadTree() { if (treeReloadPending) { m_panel->om->reload(); treeReloadPending = false; } } void ProjectPanel::registerObjectToUpdateInTree(FWObject *o, bool update_subtree) { if (fwbdebug) qDebug() << "ProjectPanel::registerObjectToUpdateInTree()" << "o=" << o->getName().c_str() << "update_subtree=" << update_subtree << "updateObjectsInTreePool.size()=" << updateObjectsInTreePool.size(); if (updateObjectsInTreePool.find(o->getId()) == updateObjectsInTreePool.end()) { updateObjectsInTreePool[o->getId()] = update_subtree; QTimer::singleShot(0, this, SLOT(updateObjectInTree())); } } void ProjectPanel::updateObjectInTree() { if (fwbdebug) qDebug() << "ProjectPanel::updateObjectInTree()" << "updateObjectsInTreePool.size()=" << updateObjectsInTreePool.size(); while (updateObjectsInTreePool.size() > 0) { map::iterator it = updateObjectsInTreePool.begin(); FWObject *obj = db()->findInIndex(it->first); m_panel->om->updateObjectInTree(obj, it->second); updateObjectsInTreePool.erase(it); } mdiWindow->update(); } void ProjectPanel::registerModifiedObject(FWObject *o) { if (fwbdebug) qDebug() << "ProjectPanel::registerModifiedObject " << "lastModifiedTimestampChangePool.size()=" << lastModifiedTimestampChangePool.size() << "o=" << o->getName().c_str() << "(" << o->getTypeName().c_str() << ")" << "id=" << o->getId(); FWObject *modified_object = o; /* * a bit of optimization: the purpose of registering modified * object here is to update "last modified" timestamp in the * firewall object it belongs to. One of the frequent cases is * when @o is rule element because user made some change to * it. Massive find and replace operations can cause waves of * registrations of rule elements, all of which belong to the * same rule set. If I register rule set instead, there will be * just one object to register. */ if (RuleElement::cast(o)) { while (RuleSet::cast(modified_object) == NULL) modified_object = modified_object->getParent(); } if (lastModifiedTimestampChangePool.find(modified_object->getId()) == lastModifiedTimestampChangePool.end()) { if (fwbdebug) qDebug() << "ProjectPanel::registerModifiedObject " << "Add object" << modified_object->getName().c_str() << "id=" << modified_object->getId(); lastModifiedTimestampChangePool.insert(modified_object->getId()); QTimer::singleShot( 0, this, SLOT(updateLastModifiedTimestampForAllFirewalls())); } } void ProjectPanel::updateLastModifiedTimestampForAllFirewalls() { if (fwbdebug) qDebug() << "ProjectPanel::updateLastModifiedTimestampForAllFirewalls" << "lastModifiedTimestampChangePool.size()=" << lastModifiedTimestampChangePool.size(); if (lastModifiedTimestampChangePool.size() == 0) return; mw->showStatusBarMessage( tr("Searching for firewalls affected by the change...")); //QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100); QApplication::setOverrideCursor(QCursor( Qt::WaitCursor)); set firewalls_to_update; while (lastModifiedTimestampChangePool.size() > 0) { set::iterator it = lastModifiedTimestampChangePool.begin(); FWObject *obj = db()->findInIndex(*it); lastModifiedTimestampChangePool.erase(it); if (fwbdebug) qDebug() << "Modified object: " << obj->getName().c_str(); if (FWBTree().isSystem(obj)) continue; list fws = m_panel->om->findFirewallsForObject(obj); if (fws.size()) { Firewall *f; for (list::iterator i=fws.begin(); i!=fws.end(); ++i) { f = *i; if (f==obj) continue; firewalls_to_update.insert(f); } } } if (fwbdebug) qDebug() << "Will update " << firewalls_to_update.size() << " firewalls"; for (set::iterator it=firewalls_to_update.begin(); it!=firewalls_to_update.end(); ++it) { Firewall *f = *it; // when user locks firewall object, this code tries to // update last_modified timestamp in it because it // depends on itself. Dont. if (f->isReadOnly()) continue; f->updateLastModifiedTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(getFileName(), f->getId())); list clusters = m_panel->om->findClustersUsingFirewall(f); if (clusters.size() != 0) { list::iterator it; for (it=clusters.begin(); it!=clusters.end(); ++it) { Cluster *cl = *it; if (cl->isReadOnly()) continue; cl->updateLastModifiedTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(getFileName(), cl->getId())); } } } QApplication::restoreOverrideCursor(); } void ProjectPanel::toggleViewTree(bool f) { if (f) m_panel->treePanelFrame->show(); else m_panel->treePanelFrame->hide(); } void ProjectPanel::setActive() { undoStack->setActive(true); } void ProjectPanel::splitterPositionChanged(int,int) { saveMainSplitter(); } fwbuilder-5.1.0.3599/src/libgui/ActionsDialog.h0000644000175000017500000000371611733011756021740 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ACTIONSDIALOG_H_ #define __ACTIONSDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include "DialogData.h" #include #include "fwbuilder/FWObject.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Resources.h" namespace libfwbuilder { class Rule; class Firewall; } class QLineEdit; class QComboBox; class FWObjectDropArea; class ActionsDialog : public BaseObjectDialog { Q_OBJECT; private: libfwbuilder::Firewall *firewall; libfwbuilder::Rule *rule; std::string editor; std::string platform; QLineEdit *branchNameInput; DialogData data; FWObjectDropArea * BranchChainArea ; FWObjectDropArea * BranchAnchorArea; FWObjectDropArea * TagIntArea ; FWObjectDropArea * TagStrArea ; public: Ui::ActionsDialog_q *m_dialog; ActionsDialog(QWidget *parent); ~ActionsDialog(); public slots: virtual void applyChanges(); virtual void tagvalueChanged(int); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); void setRule(libfwbuilder::Rule*); }; #endif fwbuilder-5.1.0.3599/src/libgui/FWWindowPrint.cpp0000644000175000017500000002510711733011756022272 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include #include #include "FWWindow.h" #include "FWBSettings.h" #include "PrintingProgressDialog.h" #include "PrintingController.h" #include "ProjectPanel.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; void FWWindow::filePrint() { if (!activeProject()) { if (fwbdebug) qDebug() << "There isn't any selected subwindow"; return; } int pageWidth = 0; int pageHeight = 0; bool fullPage = false; float margin = 0; float table_scaling = 1.0; bool print_header = true; bool print_legend = true; bool print_objects = true; bool newPageForSection = false; int tableResolution = 100; FWObject *firewall_to_print = NULL; FWObject *current_ruleset = activeProject()->getCurrentRuleSet(); if (current_ruleset) firewall_to_print = current_ruleset->getParent(); else { // no ruleset is open in the right panel firewall_to_print = activeProject()->getSelectedObject(); } // Need error dialog if (!Firewall::cast(firewall_to_print)) return; if (!st->getStr("PrintSetup/newPageForSection").isEmpty()) newPageForSection = st->getBool("PrintSetup/newPageForSection"); if (!st->getStr("PrintSetup/printHeader").isEmpty()) print_header = st->getBool("PrintSetup/printHeader"); if (!st->getStr("PrintSetup/printLegend").isEmpty()) print_legend = st->getBool("PrintSetup/printLegend"); if (!st->getStr("PrintSetup/printObjects").isEmpty()) print_objects = st->getBool("PrintSetup/printObjects"); if (!st->getStr("PrintSetup/tableResolution").isEmpty()) { tableResolution = st->getInt("PrintSetup/tableResolution"); // for backwards compatibility, convert resolution from an index // in a table to float 0..1.0 // Previously values were from the following list: // 50%, 75%, 100%, 150%, 200%, default 100% int old_res[] = {50, 75, 100, 150, 200 }; if (tableResolution <= 4 ) tableResolution = old_res[tableResolution]; } QDialog dlg; psd = new Ui::pageSetupDialog_q(); psd->setupUi(&dlg); connect(psd->tableResolution, SIGNAL(valueChanged(int)), this, SLOT(tableResolutionSettingChanged(int))); psd->newPageForSection->setChecked(newPageForSection); psd->printHeader->setChecked(print_header); psd->printLegend->setChecked(print_legend); psd->printObjects->setChecked(print_objects); psd->tableResolution->setValue(tableResolution); if ( dlg.exec() == QDialog::Accepted ) { newPageForSection = psd->newPageForSection->isChecked(); print_header = psd->printHeader->isChecked(); print_legend = psd->printLegend->isChecked(); print_objects = psd->printObjects->isChecked(); tableResolution = psd->tableResolution->value(); st->setBool("PrintSetup/newPageForSection", newPageForSection); st->setBool("PrintSetup/printHeader", print_header); st->setBool("PrintSetup/printLegend", print_legend); st->setBool("PrintSetup/printObjects", print_objects); st->setInt("PrintSetup/tableResolution", tableResolution); st->getPrinterOptions(printer, pageWidth, pageHeight); table_scaling = float(tableResolution) / 100; //printer->setResolution(resolution); printer->setFullPage(fullPage); if (fwbdebug) qDebug() << "Running QPrintDialog"; QPrintDialog pdialog(printer, this); pdialog.setWindowTitle(tr("Print configuration of %1") .arg(firewall_to_print->getName().c_str())); #ifndef Q_OS_MACX pdialog.addEnabledOption(QAbstractPrintDialog::PrintPageRange); pdialog.setMinMax(1,9999); pdialog.setPrintRange(QAbstractPrintDialog::AllPages); #endif if (pdialog.exec() == QDialog::Accepted) { if (fwbdebug) qDebug() << "QPrintDialog finished"; int fromPage = printer->fromPage(); int toPage = printer->toPage(); if (fromPage==0) fromPage = 1; if (toPage==0) toPage = 9999; showStatusBarMessage(tr("Printing..." )); PrintingProgressDialog *ppd = new PrintingProgressDialog(this, printer, 0, false); QString headerText = mw->printHeader(); #if defined(Q_OS_MACX) printerStream pr(printer, table_scaling, margin, print_header, headerText, NULL); #else printerStream pr(printer, table_scaling, margin, print_header, headerText, ppd); ppd->show(); #endif pr.setFromTo(fromPage, toPage); if (fwbdebug) qDebug() << "Printer resolution (dpi):" << printer->resolution(); if ( !pr.begin()) { ppd->hide(); delete ppd; return; } PrintingController prcontr(&pr); prcontr.printFirewall(firewall_to_print, activeProject()); if (print_legend) prcontr.printLegend(newPageForSection); if (print_objects) prcontr.printObjects(firewall_to_print, newPageForSection); ppd->hide(); delete ppd; pr.end(); if (printer->printerState() == QPrinter::Aborted) { showStatusBarMessage(tr("Printing aborted")); QMessageBox::information( this,"Firewall Builder", tr("Printing aborted"), tr("&Continue"), QString::null,QString::null, 0, 1 ); } else showStatusBarMessage(tr("Printing completed")); } else { if (fwbdebug) qDebug() << "QPrintDialog cancelled"; showStatusBarMessage(tr("Printing cancelled")); } st->setPrinterOptions(printer,pageWidth,pageHeight); } delete psd; psd = NULL; } void FWWindow::tableResolutionSettingChanged(int ) { if (psd) { QString res_lbl = QString("%1 %").arg(psd->tableResolution->value()); psd->tableResolutionLabel->setText(res_lbl); } } class UpgradePredicate: public XMLTools::UpgradePredicate { public: virtual bool operator()(const string&) const { cout << "Data file has been created in the old version of Firewall Builder. Use fwbuilder GUI to convert it." << endl; return false; } }; void FWWindow::printFirewallFromFile(QString fileName, QString firewallName, QString outputFileName) { if (outputFileName=="") { outputFileName = "print.pdf"; } if (firewallName=="") { return ; } if (fileName=="") { return; } if (!QFile::exists(fileName)) { qDebug() << "Input file does not exist"; return; } FWObjectDatabase * objdb = new FWObjectDatabase(); UpgradePredicate up; QPrinter *printer = new QPrinter(QPrinter::HighResolution); try { objdb->load(fileName.toLatin1().constData(), &up, Constants::getDTDDirectory()); } catch (...) { qDebug() << "Could not read input file"; return; } FWObject* obj = objdb->findObjectByName(Firewall::TYPENAME, firewallName.toAscii().data()); if (obj!=NULL) { int pageWidth = 0; int pageHeight = 0; bool fullPage = false; float margin = 0; float table_scaling = 1.0; bool print_header = true; bool print_legend = true; bool print_objects = true; bool newPageForSection = false; int tableResolution = 100; if (!st->getStr("PrintSetup/newPageForSection").isEmpty()) newPageForSection = st->getBool("PrintSetup/newPageForSection"); if (!st->getStr("PrintSetup/printHeader").isEmpty()) print_header = st->getBool("PrintSetup/printHeader"); if (!st->getStr("PrintSetup/printLegend").isEmpty()) print_legend = st->getBool("PrintSetup/printLegend"); if (!st->getStr("PrintSetup/printObjects").isEmpty()) print_objects = st->getBool("PrintSetup/printObjects"); if (!st->getStr("PrintSetup/tableResolution").isEmpty()) tableResolution = st->getInt("PrintSetup/tableResolution"); table_scaling = float(tableResolution) / 100; st->getPrinterOptions(printer,pageWidth,pageHeight); //printer->setResolution(resolution); printer->setFullPage(fullPage); printer->setOutputFileName (outputFileName); int fromPage = 1; int toPage = 9999; QString headerText = fileName; //mw->printHeader(); printerStream pr(printer, table_scaling, margin, print_header, headerText, NULL); pr.setFromTo(fromPage,toPage); if ( !pr.begin()) return; PrintingController prcontr(&pr); prcontr.printFirewall(obj, NULL); if (print_legend) prcontr.printLegend(newPageForSection); if (print_objects) prcontr.printObjects(obj, newPageForSection); } else { qDebug() << "Error: can't find firewall " << firewallName; } } fwbuilder-5.1.0.3599/src/libgui/BlankDialog.h0000644000175000017500000000254311733011756021364 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BLANKDIALOG_H_ #define __BLANKDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class BlankDialog : public BaseObjectDialog { Q_OBJECT; Ui::BlankDialog_q *m_dialog; public: BlankDialog(QWidget *parent); ~BlankDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif fwbuilder-5.1.0.3599/src/libgui/pfAdvancedDialog.cpp0000644000175000017500000005143111733011756022723 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "pfAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "Help.h" #include "FWCmdChange.h" #include "CompilerDriver.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; pfAdvancedDialog::pfAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::pfAdvancedDialog_q; m_dialog->setupUi(this); obj=o; QStringList slm; string version = obj->getStr("version"); FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); if (fwbdebug) qDebug("%s", Resources::getTargetOptionStr( obj->getStr("host_OS"),"user_can_change_install_dir").c_str()); if (!Resources::getTargetOptionBool( obj->getStr("host_OS"),"user_can_change_install_dir")) { m_dialog->pf_fw_dir->setEnabled(false); fwopt->setStr("firewall_dir",""); } // see #1888: we now support rc.conf format for the output // Set variables for backwards compatibility for users who configured // custom name for the output .fw script before. if (!fwopt->getBool("generate_shell_script") && !fwopt->getBool("generate_rc_conf_file")) { fwopt->setBool("generate_shell_script", true); } if (!Resources::getTargetOptionBool(obj->getStr("host_OS"), "rc_conf_format_supported")) { fwopt->setBool("generate_shell_script", true); fwopt->setBool("generate_rc_conf_file", false); } m_dialog->generateShellScript->setEnabled( Resources::getTargetOptionBool(obj->getStr("host_OS"), "rc_conf_format_supported")); m_dialog->generateRcConfFile->setEnabled( Resources::getTargetOptionBool(obj->getStr("host_OS"), "rc_conf_format_supported")); QString init_script_name = QString::fromUtf8( fwopt->getStr("output_file").c_str()).trimmed(); QString conf_file_name = QString::fromUtf8( fwopt->getStr("conf1_file").c_str()).trimmed(); if (!init_script_name.isEmpty() && conf_file_name.isEmpty()) { conf_file_name = fwcompiler::CompilerDriver::getConfFileNameFromFwFileName( init_script_name, ".conf"); fwopt->setStr("conf1_file", conf_file_name.toUtf8().constData()); } data.registerOption(m_dialog->ipv4before, fwopt, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") <<"ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first"); data.registerOption( m_dialog->pf_log_prefix,fwopt, "log_prefix"); data.registerOption( m_dialog->pf_fallback_log,fwopt, "fallback_log"); data.registerOption( m_dialog->pf_do_timeout_interval, fwopt, "pf_do_timeout_interval"); data.registerOption( m_dialog->pf_timeout_interval, fwopt, "pf_timeout_interval"); data.registerOption( m_dialog->pf_do_timeout_frag,fwopt, "pf_do_timeout_frag"); data.registerOption( m_dialog->pf_timeout_frag,fwopt, "pf_timeout_frag"); data.registerOption( m_dialog->pf_do_limit_frags,fwopt, "pf_do_limit_frags"); data.registerOption( m_dialog->pf_limit_frags,fwopt, "pf_limit_frags"); data.registerOption( m_dialog->pf_do_limit_states,fwopt, "pf_do_limit_states"); data.registerOption( m_dialog->pf_limit_states,fwopt, "pf_limit_states"); data.registerOption( m_dialog->pf_do_limit_src_nodes,fwopt, "pf_do_limit_src_nodes"); data.registerOption( m_dialog->pf_limit_src_nodes, fwopt, "pf_limit_src_nodes"); data.registerOption( m_dialog->pf_do_limit_tables, fwopt, "pf_do_limit_tables"); data.registerOption( m_dialog->pf_limit_tables,fwopt, "pf_limit_tables"); data.registerOption( m_dialog->pf_do_limit_table_entries,fwopt, "pf_do_limit_table_entries"); data.registerOption( m_dialog->pf_limit_table_entries,fwopt,"pf_limit_table_entries"); // Prepare mapping for pf_optimization: slm.clear(); slm.push_back(""); slm.push_back(""); slm.push_back(QObject::tr("Aggressive")); slm.push_back("aggressive"); slm.push_back(QObject::tr("Conservative")); slm.push_back("conservative"); slm.push_back(QObject::tr("For high latency")); slm.push_back("high-latency"); slm.push_back(QObject::tr("Normal")); slm.push_back("normal"); m_dialog->pf_optimization->clear(); m_dialog->pf_optimization->addItems(getScreenNames(slm)); data.registerOption( m_dialog->pf_optimization, fwopt, "pf_optimization", slm); // Prepare state_policy combo box slm.clear(); slm.push_back(""); slm.push_back(""); slm.push_back(QObject::tr("Bound to interfaces")); slm.push_back("if-bound"); slm.push_back(QObject::tr("Floating")); slm.push_back("floating"); m_dialog->pf_state_policy->clear(); m_dialog->pf_state_policy->addItems(getScreenNames(slm)); data.registerOption( m_dialog->pf_state_policy, fwopt, "pf_state_policy", slm); m_dialog->pf_state_policy->setEnabled( XMLTools::version_compare(version, "3.5") >= 0); // Prepare block_policy combo box slm.clear(); slm.push_back(""); slm.push_back(""); slm.push_back(QObject::tr("Drop")); slm.push_back("drop"); slm.push_back(QObject::tr("Return")); slm.push_back("return"); m_dialog->pf_block_policy->clear(); m_dialog->pf_block_policy->addItems(getScreenNames(slm)); data.registerOption( m_dialog->pf_block_policy, fwopt, "pf_block_policy", slm); m_dialog->pf_block_policy->setEnabled( XMLTools::version_compare(version, "3.5") >= 0); // set debug combo box slm.clear(); slm.push_back(""); slm.push_back(""); slm.push_back("emerg"); slm.push_back("emerg"); slm.push_back("alert"); slm.push_back("alert"); slm.push_back("crit"); slm.push_back("crit"); slm.push_back("err"); slm.push_back("err"); slm.push_back("warning"); slm.push_back("warning"); slm.push_back("notice"); slm.push_back("notice"); slm.push_back("info"); slm.push_back("info"); slm.push_back("debug"); slm.push_back("debug"); m_dialog->pf_set_debug->clear(); m_dialog->pf_set_debug->addItems(getScreenNames(slm)); data.registerOption( m_dialog->pf_set_debug, fwopt, "pf_set_debug", slm); m_dialog->pf_set_debug->setEnabled( XMLTools::version_compare(version, "3.5") >= 0); data.registerOption( m_dialog->pf_check_shadowing,fwopt, "check_shading"); data.registerOption( m_dialog->pf_preserve_group_names, fwopt, "preserve_group_names"); data.registerOption( m_dialog->pf_ignore_empty_groups,fwopt, "ignore_empty_groups"); // data.registerOption( pf_use_tables, fwopt, "use_tables"); data.registerOption( m_dialog->pf_accept_new_tcp_with_no_syn,fwopt, "accept_new_tcp_with_no_syn"); data.registerOption( m_dialog->pf_modulate_state,fwopt, "pf_modulate_state"); data.registerOption( m_dialog->pf_scrub_random_id,fwopt, "pf_scrub_random_id"); data.registerOption( m_dialog->pf_do_scrub,fwopt, "pf_do_scrub"); // radio buttons // the following pf_scrub options are available in PF <= 4.5 data.registerOption( m_dialog->pf_scrub_reassemble, fwopt, "pf_scrub_reassemble"); data.registerOption( m_dialog->pf_scrub_fragm_crop, fwopt, "pf_scrub_fragm_crop"); data.registerOption( m_dialog->pf_scrub_fragm_drop_ovl, fwopt, "pf_scrub_fragm_drop_ovl"); // pf_scrub_reassemble_tcp is available in all versions data.registerOption( m_dialog->pf_scrub_reassemble_tcp, fwopt, "pf_scrub_reassemble_tcp"); data.registerOption( m_dialog->pf_scrub_use_minttl, fwopt, "pf_scrub_use_minttl"); data.registerOption( m_dialog->pf_scrub_use_maxmss, fwopt, "pf_scrub_use_maxmss"); data.registerOption( m_dialog->pf_scrub_maxmss,fwopt, "pf_scrub_maxmss"); data.registerOption( m_dialog->pf_scrub_minttl,fwopt, "pf_scrub_minttl"); data.registerOption( m_dialog->pf_scrub_no_df,fwopt, "pf_scrub_no_df"); data.registerOption( m_dialog->pf_fw_dir,fwopt, "firewall_dir"); data.registerOption( m_dialog->pf_user,fwopt, "admUser"); data.registerOption( m_dialog->altAddress,fwopt, "altAddress"); data.registerOption( m_dialog->sshArgs, fwopt, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwopt, "scpArgs"); data.registerOption( m_dialog->activationCmd, fwopt, "activationCmd"); data.registerOption( m_dialog->pf_manage_virtual_addr, fwopt, "manage_virtual_addr"); data.registerOption( m_dialog->pf_configure_interfaces, fwopt, "configure_interfaces"); data.registerOption( m_dialog->pf_configure_carp_interfaces, fwopt, "configure_carp_interfaces"); data.registerOption( m_dialog->pf_configure_pfsync_interfaces, fwopt, "configure_pfsync_interfaces"); data.registerOption( m_dialog->pf_configure_vlan_interfaces, fwopt, "configure_vlan_interfaces"); data.registerOption( m_dialog->pf_configure_bridge_interfaces, fwopt, "configure_bridge_interfaces"); data.registerOption( m_dialog->pf_debug,fwopt, "debug"); data.registerOption( m_dialog->pf_flush_states, fwopt, "pf_flush_states"); data.registerOption( m_dialog->compiler,fwopt, "compiler"); data.registerOption( m_dialog->compilerArgs,fwopt, "cmdline"); data.registerOption( m_dialog->generateShellScript, fwopt, "generate_shell_script"); data.registerOption( m_dialog->generateRcConfFile, fwopt, "generate_rc_conf_file"); data.registerOption( m_dialog->outputFileName, fwopt, "output_file"); data.registerOption( m_dialog->confFileName, fwopt, "conf1_file"); data.registerOption( m_dialog->fileNameOnFw, fwopt, "script_name_on_firewall"); data.registerOption( m_dialog->confFileNameOnFw, fwopt, "conf_file_name_on_firewall"); data.registerOption( m_dialog->mgmt_ssh,fwopt, "mgmt_ssh"); data.registerOption( m_dialog->mgmt_addr,fwopt, "mgmt_addr"); data.registerOption( m_dialog->pf_set_tcp_first, fwopt, "pf_set_tcp_first"); data.registerOption( m_dialog->pf_tcp_first, fwopt, "pf_tcp_first"); data.registerOption( m_dialog->pf_set_tcp_opening, fwopt, "pf_set_tcp_opening"); data.registerOption( m_dialog->pf_tcp_opening, fwopt, "pf_tcp_opening"); data.registerOption( m_dialog->pf_set_tcp_established, fwopt, "pf_set_tcp_established"); data.registerOption( m_dialog->pf_tcp_established, fwopt, "pf_tcp_established"); data.registerOption( m_dialog->pf_set_tcp_closing, fwopt, "pf_set_tcp_closing"); data.registerOption( m_dialog->pf_tcp_closing, fwopt, "pf_tcp_closing"); data.registerOption( m_dialog->pf_set_tcp_finwait, fwopt, "pf_set_tcp_finwait"); data.registerOption( m_dialog->pf_tcp_finwait, fwopt, "pf_tcp_finwait"); data.registerOption( m_dialog->pf_set_tcp_closed, fwopt, "pf_set_tcp_closed"); data.registerOption( m_dialog->pf_tcp_closed, fwopt, "pf_tcp_closed"); data.registerOption( m_dialog->pf_set_udp_first, fwopt, "pf_set_udp_first"); data.registerOption( m_dialog->pf_udp_first, fwopt, "pf_udp_first"); data.registerOption( m_dialog->pf_set_udp_single, fwopt, "pf_set_udp_single"); data.registerOption( m_dialog->pf_udp_single, fwopt, "pf_udp_single"); data.registerOption( m_dialog->pf_set_udp_multiple, fwopt, "pf_set_udp_multiple"); data.registerOption( m_dialog->pf_udp_multiple, fwopt, "pf_udp_multiple"); data.registerOption( m_dialog->pf_set_icmp_first, fwopt, "pf_set_icmp_first"); data.registerOption( m_dialog->pf_icmp_first, fwopt, "pf_icmp_first"); data.registerOption( m_dialog->pf_set_icmp_error, fwopt, "pf_set_icmp_error"); data.registerOption( m_dialog->pf_icmp_error, fwopt, "pf_icmp_error"); data.registerOption( m_dialog->pf_set_other_first, fwopt, "pf_set_other_first"); data.registerOption( m_dialog->pf_other_first, fwopt, "pf_other_first"); data.registerOption( m_dialog->pf_set_other_single, fwopt, "pf_set_other_single"); data.registerOption( m_dialog->pf_other_single, fwopt, "pf_other_single"); data.registerOption( m_dialog->pf_set_other_multiple, fwopt, "pf_set_other_multiple"); data.registerOption( m_dialog->pf_other_multiple, fwopt, "pf_other_multiple"); data.registerOption( m_dialog->pf_set_adaptive, fwopt, "pf_set_adaptive"); data.registerOption( m_dialog->pf_adaptive_start, fwopt, "pf_adaptive_start"); data.registerOption( m_dialog->pf_adaptive_end, fwopt, "pf_adaptive_end"); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText( pis->getCommand().c_str()); m_dialog->installScriptArgs->setText( pis->getArguments().c_str()); /* page "Prolog/Epilog" */ QStringList prologPlaces_pf; prologPlaces_pf.push_back(QObject::tr("in the activation shell script")); prologPlaces_pf.push_back("fw_file"); prologPlaces_pf.push_back(QObject::tr("in the pf rule file, at the very top")); prologPlaces_pf.push_back("pf_file_top"); prologPlaces_pf.push_back(QObject::tr("in the pf rule file, after set comamnds")); prologPlaces_pf.push_back("pf_file_after_set"); prologPlaces_pf.push_back(QObject::tr("in the pf rule file, after scrub comamnds")); prologPlaces_pf.push_back("pf_file_after_scrub"); prologPlaces_pf.push_back(QObject::tr("in the pf rule file, after table definitions")); prologPlaces_pf.push_back("pf_file_after_tables"); m_dialog->prologPlace->clear(); m_dialog->prologPlace->addItems(getScreenNames(prologPlaces_pf)); data.registerOption( m_dialog->prologPlace, fwopt, "prolog_place", prologPlaces_pf); data.registerOption( m_dialog->prolog_script, fwopt, "prolog_script"); data.registerOption( m_dialog->epilog_script, fwopt, "epilog_script"); data.loadAll(); doScrubToggled(); ltToggled(); m_dialog->tabWidget->setCurrentIndex(0); } pfAdvancedDialog::~pfAdvancedDialog() { delete m_dialog; } void pfAdvancedDialog::doScrubToggled() { string version = obj->getStr("version"); bool f_old_reassemble = m_dialog->pf_do_scrub->isChecked(); bool f_reassemble_tcp = f_old_reassemble; if (XMLTools::version_compare(version, "4.6")>=0) f_old_reassemble = false; m_dialog->pf_scrub_reassemble->setEnabled(f_old_reassemble); m_dialog->pf_scrub_fragm_crop->setEnabled(f_old_reassemble); m_dialog->pf_scrub_fragm_drop_ovl->setEnabled(f_old_reassemble); m_dialog->pf_scrub_reassemble_tcp->setEnabled(f_reassemble_tcp); if (!m_dialog->pf_scrub_reassemble->isChecked() && !m_dialog->pf_scrub_fragm_crop->isChecked() && !m_dialog->pf_scrub_fragm_drop_ovl->isChecked() && !m_dialog->pf_scrub_reassemble_tcp->isChecked()) { m_dialog->pf_scrub_reassemble_tcp->setChecked(true); } } void pfAdvancedDialog::ltToggled() { m_dialog->pf_limit_frags->setEnabled( m_dialog->pf_do_limit_frags->isChecked()); m_dialog->pf_limit_states->setEnabled( m_dialog->pf_do_limit_states->isChecked()); m_dialog->pf_limit_src_nodes->setEnabled( m_dialog->pf_do_limit_src_nodes->isChecked()); m_dialog->pf_limit_tables->setEnabled( m_dialog->pf_do_limit_tables->isChecked()); m_dialog->pf_limit_table_entries->setEnabled( m_dialog->pf_do_limit_table_entries->isChecked()); m_dialog->pf_timeout_interval->setEnabled( m_dialog->pf_do_timeout_interval->isChecked()); m_dialog->pf_timeout_frag->setEnabled( m_dialog->pf_do_timeout_frag->isChecked()); m_dialog->pf_tcp_first->setEnabled( m_dialog->pf_set_tcp_first->isChecked()); m_dialog->pf_tcp_opening->setEnabled( m_dialog->pf_set_tcp_opening->isChecked()); m_dialog->pf_tcp_established->setEnabled( m_dialog->pf_set_tcp_established->isChecked()); m_dialog->pf_tcp_closing->setEnabled( m_dialog->pf_set_tcp_closing->isChecked()); m_dialog->pf_tcp_finwait->setEnabled( m_dialog->pf_set_tcp_finwait->isChecked()); m_dialog->pf_tcp_closed->setEnabled( m_dialog->pf_set_tcp_closed->isChecked()); m_dialog->pf_udp_first->setEnabled( m_dialog->pf_set_udp_first->isChecked()); m_dialog->pf_udp_single->setEnabled( m_dialog->pf_set_udp_single->isChecked()); m_dialog->pf_udp_multiple->setEnabled( m_dialog->pf_set_udp_multiple->isChecked()); m_dialog->pf_icmp_first->setEnabled( m_dialog->pf_set_icmp_first->isChecked()); m_dialog->pf_icmp_error->setEnabled( m_dialog->pf_set_icmp_error->isChecked()); m_dialog->pf_other_first->setEnabled( m_dialog->pf_set_other_first->isChecked()); m_dialog->pf_other_single->setEnabled( m_dialog->pf_set_other_single->isChecked()); m_dialog->pf_other_multiple->setEnabled( m_dialog->pf_set_other_multiple->isChecked()); m_dialog->pf_adaptive_start->setEnabled( m_dialog->pf_set_adaptive->isChecked()); m_dialog->pf_adaptive_end->setEnabled( m_dialog->pf_set_adaptive->isChecked()); } /* * store all data in the object */ void pfAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); pis->setCommand( m_dialog->installScript->text().toLatin1().constData()); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData()); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void pfAdvancedDialog::reject() { QDialog::reject(); } void pfAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->prolog_script->toPlainText(), true, tr( "Script Editor")); if ( edt.exec() == QDialog::Accepted) m_dialog->prolog_script->setText( edt.text()); } void pfAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->epilog_script->toPlainText(), true, tr( "Script Editor")); if ( edt.exec() == QDialog::Accepted) m_dialog->epilog_script->setText( edt.text()); } void pfAdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Firewall platform: pf"); h->setSource(QUrl("pfAdvancedDialog.html#" + anchor)); h->raise(); h->show(); } fwbuilder-5.1.0.3599/src/libgui/RuleSetModel.h0000644000175000017500000002202111733011756021552 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef RULESETMODEL_H #define RULESETMODEL_H #include #include #include #include #include #include "RuleNode.h" #include "ColDesc.h" namespace libfwbuilder { class Firewall; class RuleSet; class RuleElement; class Rule; class FWObject; } class RuleSetModel; //////////////////////////////////////////////////////////////////////// // RuleSetModelIterator //////////////////////////////////////////////////////////////////////// class RuleSetModelIterator { friend class RuleSetModel; public: RuleSetModelIterator(); bool isValid(); bool hasNext(); bool hasPrev(); RuleSetModelIterator& operator= (const RuleSetModelIterator&); RuleSetModelIterator& operator++ (); RuleSetModelIterator& operator-- (); bool operator== ( RuleSetModelIterator& ); bool operator!= ( RuleSetModelIterator& ); QModelIndex index(); private: QAbstractItemModel *model; int row; QModelIndex parent; }; //////////////////////////////////////////////////////////////////////// // ActionDesc //////////////////////////////////////////////////////////////////////// class ActionDesc { public: QString name; QString displayName; QString tooltip; QString argument; }; Q_DECLARE_METATYPE(ActionDesc) //////////////////////////////////////////////////////////////////////// // RuleSetModel //////////////////////////////////////////////////////////////////////// class RuleSetModel : public QAbstractItemModel { Q_OBJECT public: QList header; RuleSetModel(libfwbuilder::RuleSet* ruleset, QObject *parent = 0); ~RuleSetModel() {delete root;} int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex &parent) const; QModelIndex index(int row, int column, QString groupName) const; QModelIndex index(libfwbuilder::Rule *rule, int col=0) const; QModelIndex index(libfwbuilder::Rule *rule, libfwbuilder::RuleElement *re) const; QModelIndex index(QString groupName) const; QModelIndex indexForPosition(int position) const; QModelIndex parent(const QModelIndex &child) const; bool isEmpty(); bool isGroup(const QModelIndex &index) const; libfwbuilder::RuleSet* getRuleSet() {return ruleset;} libfwbuilder::Firewall* getFirewall() const; libfwbuilder::Rule* insertNewRule(); libfwbuilder::Rule* insertNewRule(QModelIndex &index, bool isAfter = false); libfwbuilder::Rule* insertRule(libfwbuilder::Rule *rule, QModelIndex &index, bool isAfter = false); void insertRule(libfwbuilder::Rule *rule); virtual void initRule(libfwbuilder::Rule *new_rule, libfwbuilder::Rule *old_rule = NULL) = 0; void removeRow(int row,const QModelIndex &parent); bool removeRows(int row, int count, const QModelIndex &parent); void renameGroup(QModelIndex group, const QString &newName); void removeFromGroup(QModelIndex group, int first, int last); QModelIndex createNewGroup(QString groupName, int first, int last); QString addToGroupAbove(int first, int last); QString addToGroupBelow(int first, int last); void moveRuleUp(const QModelIndex &group, int first, int last); void moveRuleDown(const QModelIndex &group, int first, int last); void changeRuleColor(const QList &indexes, const QString &c); void changeGroupColor(const QModelIndex index, const QString &c); bool isIndexRule(const QModelIndex index); RuleNode *nodeFromIndex(const QModelIndex &index) const; int getRulePosition(QModelIndex index); libfwbuilder::Rule * findRuleForPosition(int position) const; libfwbuilder::Rule * getRule(QModelIndex index) const; void setEnabled(const QModelIndex &index, bool flag); virtual bool checkRuleType(libfwbuilder::Rule *rule) = 0; void deleteObject(QModelIndex &index, libfwbuilder::FWObject* obj); bool insertObject(QModelIndex &index, libfwbuilder::FWObject *obj); int columnByType(ColDesc::ColumnType type); void rowChanged(const QModelIndex &index); void groupChanged(const QModelIndex &index); void getGroups(QList &list); RuleSetModelIterator begin(); RuleSetModelIterator end(); void resetAllSizes(); QString findUniqueNameForGroup(const QString &groupName); void restoreRules(QList rules, bool topLevel = true); void restoreRule(libfwbuilder::Rule* rule); void objectChanged(libfwbuilder::FWObject* object); protected: libfwbuilder::RuleElement *getRuleElementByRole(libfwbuilder::Rule* r, std::string roleName) const; void insertRuleToModel(libfwbuilder::Rule *rule, QModelIndex &index, bool isAfter = false); int columnForRuleElementType(QString) const; QString getPositionAsString(RuleNode *node) const; ActionDesc getRuleActionDesc(libfwbuilder::Rule* r) const; void copyRuleWithoutId(libfwbuilder::Rule* fromRule, libfwbuilder::Rule* toRule); private: libfwbuilder::RuleSet *ruleset; RuleNode *root; // QHash rulesByPosition; void initModel(); QVariant getDecoration(const QModelIndex &index) const; QVariant getDataForDisplayRole(const QModelIndex &index) const; QVariant getGroupDataForDisplayRole(const QModelIndex &index, RuleNode* node) const; virtual QVariant getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const = 0; QVariant getColumnDesc(const QModelIndex &index) const; void moveToGroup(RuleNode *targetGroup, int first, int last, bool append=true); void removeToList(QList &list, const QModelIndex &group, int first, int last); void insertFromList(const QList &list, const QModelIndex &parent, int position); QModelIndexList findObject (libfwbuilder::FWObject* object); }; //////////////////////////////////////////////////////////////////////// // PolicyModel //////////////////////////////////////////////////////////////////////// class PolicyModel : public RuleSetModel { public: PolicyModel(libfwbuilder::RuleSet* ruleset, QObject *parent = 0) : RuleSetModel(ruleset, parent) {configure();} void initRule(libfwbuilder::Rule *new_rule, libfwbuilder::Rule *old_rule = NULL); bool checkRuleType(libfwbuilder::Rule *rule); private: bool supports_time; bool supports_logging; bool supports_rule_options; QVariant getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const; QString getRuleDirection(libfwbuilder::Rule* r) const; QStringList getRuleOptions(libfwbuilder::Rule* r) const; void configure(); }; //////////////////////////////////////////////////////////////////////// // NatModel //////////////////////////////////////////////////////////////////////// class NatModel : public RuleSetModel { public: NatModel(libfwbuilder::RuleSet* ruleset, QObject *parent = 0) : RuleSetModel(ruleset, parent) {configure();} void initRule(libfwbuilder::Rule *new_rule, libfwbuilder::Rule *old_rule = NULL); bool checkRuleType(libfwbuilder::Rule *rule); private: bool supports_actions; bool supports_inbound_interface; bool supports_outbound_interface; QVariant getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const; QStringList getRuleOptions(libfwbuilder::Rule* r) const; void configure(); }; //////////////////////////////////////////////////////////////////////// // RoutingModel //////////////////////////////////////////////////////////////////////// class RoutingModel : public RuleSetModel { public: RoutingModel(libfwbuilder::RuleSet* ruleset, QObject *parent = 0) : RuleSetModel(ruleset, parent) {configure();} void initRule(libfwbuilder::Rule *new_rule, libfwbuilder::Rule *old_rule = NULL); bool checkRuleType(libfwbuilder::Rule *rule); private: bool supports_routing_itf; bool supports_metric; QVariant getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const; QStringList getRuleOptions(libfwbuilder::Rule* r) const; void configure(); }; #endif // RULESETMODEL_H fwbuilder-5.1.0.3599/src/libgui/ipcopadvanceddialog_q.ui0000644000175000017500000013020411733011756023677 0ustar sylvestresylvestre ipcopAdvancedDialog_q Qt::WindowModal true 0 0 726 710 0 0 ipcop advanced settings false 0 0 0 Compiler 12 12 12 Compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 22 0 0 Command line options for the compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 22 0 0 Output file name (if left blank, the file name is constructed of the firewall object name and extension ".fw") Qt::AlignVCenter true 32767 22 rc.firewall.local true QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Horizontal QSizePolicy::Maximum 30 150 0 0 Assume firewall is part of 'any' 0 0 Accept TCP sessions opened prior to firewall restart 0 0 Bridging firewall 0 0 Detect shadowing in policy rules 0 0 Ignore empty groups in rules 0 0 Enable support for NAT of locally originated connections Default action on 'Reject': false Qt::Horizontal QSizePolicy::Expanding 72 20 QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Horizontal QSizePolicy::Fixed 30 50 Always permit ssh access from the management workstation with this address: 0 0 32767 32767 Qt::Vertical QSizePolicy::Expanding 20 20 Installer Built-in installer Directory on the firewall where script should be installed Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 250 0 /etc/rc.d/ 0 true User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 250 0 admin 0 true Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 250 0 A command that installer should execute on the firewall in order to activate the policy (if this field is blank, installer runs firewall script in the directory specified above; it uses sudo if user name is not 'root') Qt::AlignVCenter true 0 0 250 0 /etc/rc.d/rc.firewall 0 true Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 External install script 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Qt::Vertical QSizePolicy::Expanding 20 100 Prolog/Epilog 6 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 The following commands will be added verbatim after generated configuration Qt::AlignVCenter true 6 The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Edit Qt::Horizontal 40 20 Logging 20 6 use ULOG use LOG 0 0 10 log TCP seq. numbers log IP options use numeric syslog levels Log level: false log TCP options 0 10 1500 cprange false 1 queue threshold: false netlink group: false 1 32 Qt::Vertical QSizePolicy::Expanding 20 16 0 0 QFrame::VLine QFrame::Sunken Qt::Vertical 0 0 Log prefix: false 32 Logging limit: false 10000 0 0 Activate logging in all rules (overrides rule options, use for debugging) Qt::Vertical QSizePolicy::Expanding 20 40 Qt::Vertical QSizePolicy::Expanding 20 16 Script 6 These options enable auxiliary sections in the generated shell script. Qt::AlignVCenter true Qt::Horizontal QSizePolicy::MinimumExpanding 40 20 Qt::Horizontal QSizePolicy::Maximum 30 120 Turn debugging on in generated script Qt::Vertical QSizePolicy::Expanding 20 200 Verify interfaces before loading firewall policy IPv6 The order in which ipv4 and ipv6 rules should be generated: IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 Qt::Horizontal 40 20 Help Qt::Horizontal QSizePolicy::Expanding 351 27 &OK true true &Cancel true tabWidget compiler compilerArgs outputFileName assumeFwIsPartOfAny acceptSessions bridge shadowing emptyGroups localNAT actionOnReject mgmt_ssh mgmt_addr buttonOk buttonCancel ipt_fw_dir ipt_user altAddress activationCmd sshArgs installScript installScriptArgs prolog_script edit_prolog_button epilog_script edit_epilog_button useLOG useULOG logTCPseq logTCPopt logIPopt logNumsyslog logLevel logprefix logLimitVal logLimitSuffix logAll verifyInterfaces iptDebug ipv4before cprange nlgroup qthreshold buttonOk clicked() ipcopAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() ipcopAdvancedDialog_q reject() 20 20 20 20 useLOG toggled(bool) ipcopAdvancedDialog_q switchLOG_ULOG() 20 20 20 20 edit_prolog_button clicked() ipcopAdvancedDialog_q editProlog() 20 20 20 20 edit_epilog_button clicked() ipcopAdvancedDialog_q editEpilog() 20 20 20 20 buttonHelp clicked() ipcopAdvancedDialog_q help() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/FWCmdRule.h0000644000175000017500000002202511733011756021002 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWCMDRULE_H #define FWCMDRULE_H #include "FWCmdBasic.h" #include "RuleSetView.h" #include "RuleSetModel.h" #include "FWCmdChange.h" #include #include namespace libfwbuilder { class RuleSet; class RuleElement; class Rule; class FWObject; } /******************************************************** * FWCmdRule ********************************************************/ class FWCmdRule : public FWCmdBasic { protected: libfwbuilder::RuleSet* ruleset; RuleSetView* getRuleSetView(); RuleSetModel* getRuleSetModel(); virtual void notify(); public: FWCmdRule(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, QUndoCommand* macro=0); virtual void redo(); virtual void undo(); virtual void redoOnModel(RuleSetModel *md)=0; virtual void undoOnModel(RuleSetModel *md)=0; }; /******************************************************** * FWCmdRuleInsert ********************************************************/ class FWCmdRuleInsert : public FWCmdRule { int position; libfwbuilder::Rule * ruleToInsert; libfwbuilder::Rule * insertedRule; bool isAfter; public: FWCmdRuleInsert(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, int position=0, bool isAfter=false, libfwbuilder::Rule* ruleToInsert=0); ~FWCmdRuleInsert(); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleDelete ********************************************************/ class FWCmdRuleDelete : public FWCmdRule { int row; void copyRules(QList &rules); protected: QList rulesToDelete; public: FWCmdRuleDelete(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, QList &rulesToDelete, QUndoCommand* macro=0); ~FWCmdRuleDelete(); virtual void redoOnModel(RuleSetModel *md); virtual void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleDeleteFromGroup ********************************************************/ class FWCmdRuleDeleteFromGroup : public FWCmdRuleDelete { // int ruleId; // int row; // libfwbuilder::Rule* deletedRule; // QList rulesToDelete; public: FWCmdRuleDeleteFromGroup(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, QList rulesToDelete, QUndoCommand* macro=0); // void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleColor ********************************************************/ class FWCmdRuleColor : public FWCmdRule { QString newColor; QHash oldColors; QList ruleIds; public: FWCmdRuleColor(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, QList &rules,const QString &newColor); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleRenameGroup ********************************************************/ class FWCmdRuleRenameGroup : public FWCmdRule { QString oldName; QString newName; public: FWCmdRuleRenameGroup(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, QString oldName, QString newName); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleRemoveFromGroup ********************************************************/ class FWCmdRuleRemoveFromGroup : public FWCmdRule { libfwbuilder::Rule* firstRule; libfwbuilder::Rule* lastRule; QString groupName; public: FWCmdRuleRemoveFromGroup(ProjectPanel* project, libfwbuilder::RuleSet* ruleset, libfwbuilder::Rule* firstRule, libfwbuilder::Rule* lastRule, const QString groupName, QUndoCommand* macro=0); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleNewGroup ********************************************************/ class FWCmdRuleNewGroup : public FWCmdRule { libfwbuilder::Rule* firstRule; libfwbuilder::Rule* lastRule; QString groupName; public: FWCmdRuleNewGroup(ProjectPanel* project, libfwbuilder::RuleSet* ruleset, libfwbuilder::Rule* firstRule, libfwbuilder::Rule* lastRule, const QString groupName); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleAddToGroup ********************************************************/ class FWCmdRuleAddToGroup : public FWCmdRule { libfwbuilder::Rule* firstRule; libfwbuilder::Rule* lastRule; bool isAbove; QString groupName; public: FWCmdRuleAddToGroup(ProjectPanel* project, libfwbuilder::RuleSet* ruleset, libfwbuilder::Rule* firstRule, libfwbuilder::Rule* lastRule, bool isAbove = true); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleMove ********************************************************/ class FWCmdRuleMove : public FWCmdRule { int firstId; int lastId; bool direction; // true - up, false - down; void move(RuleSetModel *md, bool direction); public: FWCmdRuleMove(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, int firstId, int lastId, bool direction=true); void redoOnModel(RuleSetModel *md); void undoOnModel(RuleSetModel *md); }; /******************************************************** * FWCmdRuleChange ********************************************************/ class FWCmdRuleChange : public FWCmdChange { libfwbuilder::RuleSet* ruleset; protected: void prepareRuleSetView(); void selectAffectedRule(); virtual libfwbuilder::Rule* getRule(); public: FWCmdRuleChange(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, libfwbuilder::FWObject *obj, QString text=QString(), QUndoCommand* macro = 0); virtual void redo(); virtual void undo(); virtual void notify(); }; /******************************************************** * FWCmdRuleChangeAction ********************************************************/ class FWCmdRuleChangeAction : public FWCmdRuleChange { public: FWCmdRuleChangeAction(ProjectPanel *project, libfwbuilder::FWObject *obj); virtual void notify(); }; /******************************************************** * FWCmdRuleChangeComment ********************************************************/ class FWCmdRuleChangeComment : public FWCmdRuleChange { public: FWCmdRuleChangeComment(ProjectPanel *project, libfwbuilder::FWObject *obj); virtual void notify(); }; /******************************************************** * FWCmdRuleChangeOptions ********************************************************/ class FWCmdRuleChangeOptions : public FWCmdRuleChange { public: FWCmdRuleChangeOptions(ProjectPanel *project, libfwbuilder::FWObject *obj); virtual void notify(); }; /******************************************************** * FWCmdRuleChangeRe ********************************************************/ class FWCmdRuleChangeRe : public FWCmdRuleChange { int position; int column; int number; protected: virtual libfwbuilder::Rule* getRule(); public: FWCmdRuleChangeRe(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, libfwbuilder::FWObject *obj, int position, int column, int number, QString text=QString(), QUndoCommand* macro = 0); virtual void notify(); }; /******************************************************** * FWCmdRuleNegateRE ********************************************************/ class FWCmdRuleNegateRE : public FWCmdRuleChangeRe { public: FWCmdRuleNegateRE(ProjectPanel *project, libfwbuilder::RuleSet* ruleset, libfwbuilder::RuleElement* ruleElement, int position, int column); virtual void redo(); virtual void undo(); }; #endif // FWCMDRULE_H fwbuilder-5.1.0.3599/src/libgui/FWCmdBasic.cpp0000644000175000017500000000432311733011756021450 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWCmdBasic.h" #include using namespace libfwbuilder; FWCmdBasic::FWCmdBasic(ProjectPanel *project, QUndoCommand* macro):QUndoCommand(macro) { this->project = project; } FWObject* FWCmdBasic::getObject() { return getObject(obj_id); } FWObject* FWCmdBasic::getObject(int id) { return project->db()->findInIndex(id); } bool FWCmdBasic::mergeWith(const QUndoCommand *other) { if (fwbdebug) { qDebug() << "FWCmdBasic::mergeWith(const QUndoCommand *other) other=" << other; qDebug() << "cmd:" << other->text(); } const FWCmdTerm* term = dynamic_cast(other); return term != 0; } bool FWCmdMacro::mergeWith(const QUndoCommand *other) { if (fwbdebug) { qDebug() << "FWCmdMacro::mergeWith(const QUndoCommand *other) other=" << other; qDebug() << "cmd:" << other->text(); } const FWCmdTerm* term = dynamic_cast (other); return term != 0; } void undoAndRemoveLastCommand(QUndoStack* undoStack) { if (fwbdebug) qDebug() << "undoAndRemoveLastCommand(QUndoStack undoStack)"; undoStack->undo(); if (fwbdebug) qDebug() << "count:" << undoStack->count(); if (undoStack->count() == 1) { undoStack->clear(); } else { FWCmdTerm* cmd = new FWCmdTerm(); undoStack->push(cmd); } } fwbuilder-5.1.0.3599/src/libgui/FWCmdDeleteObject.h0000644000175000017500000000364511733011756022433 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWCMDDELETEOBJECT_H #define FWCMDDELETEOBJECT_H #include "FWCmdChange.h" /******************************************************** * FWCmdDeleteObject ********************************************************/ class FWCmdDeleteObject : public FWCmdChange { libfwbuilder::FWObject *parent; libfwbuilder::FWObject *delobj; protected: virtual void notify(); public: FWCmdDeleteObject(ProjectPanel *project, libfwbuilder::FWObject *obj, QString text=QString(), QUndoCommand* macro=0); ~FWCmdDeleteObject(); virtual void redo(); virtual void undo(); }; class FWCmdRemoveUserFolder : public FWCmdChange { QString m_userFolder; public: FWCmdRemoveUserFolder(ProjectPanel *project, libfwbuilder::FWObject *parentFolder, const QString &userFolder, QString text = QString(), QUndoCommand *macro = 0); virtual void redo(); virtual void undo(); virtual void notify(); }; #endif fwbuilder-5.1.0.3599/src/libgui/instDialog_ui_ops.cpp0000644000175000017500000012630211733011756023223 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "instDialog.h" #include "FirewallInstaller.h" #include "FWBSettings.h" #include "FWWindow.h" #include "InstallFirewallViewItem.h" #include "instOptionsDialog.h" #include "instBatchOptionsDialog.h" #include "FirewallCodeViewer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/StateSyncClusterGroup.h" #ifndef _WIN32 # include // for access(2) and getdomainname #endif #include #include #include using namespace std; using namespace libfwbuilder; void instDialog::enableStopButton() { currentStopButton->setText(tr("Stop")); currentStopButton->setEnabled(true); } void instDialog::disableStopButton() { currentStopButton->setEnabled(false); } bool instDialog::checkIfNeedToCompile(Firewall *fw) { return (fw->needsCompile() && !fw->getInactive()); } bool instDialog::checkIfNeedToInstall(Firewall *fw) { return (fw->needsInstall() && !fw->getInactive()); } QTreeWidgetItem* instDialog::createTreeItem(QTreeWidgetItem* parent, Firewall *fw) { QTreeWidgetItem* item; QStringList sl; sl.push_back(QString::fromUtf8(fw->getName().c_str())); if (parent) item = new QTreeWidgetItem(parent, sl); else item = new QTreeWidgetItem(sl); QString icn_filename = (":/Icons/" + fw->getTypeName() + "/icon").c_str(); QPixmap pm; if ( ! QPixmapCache::find(icn_filename, pm)) { pm.load(icn_filename); QPixmapCache::insert(icn_filename, pm); } item->setIcon(0, QIcon(pm)); item->setData(0, Qt::UserRole, QVariant(fw->getId())); // Mark cluster members // If parent!=NULL, new tree item corresponds to the cluster member item->setData(1, Qt::UserRole, QVariant(parent!=NULL)); // it is useful to know how many members does this cluster have. If this is // not a cluster, store 0 list members; if (Cluster::isA(fw)) Cluster::cast(fw)->getMembersList(members); int num_members = members.size(); item->setData(2, Qt::UserRole, QVariant(num_members)); // item->setCheckState(COMPILE_CHECKBOX_COLUMN, checkIfNeedToCompile(fw)?Qt::Checked:Qt::Unchecked); // if (!compile_only) // item->setCheckState(INSTALL_CHECKBOX_COLUMN, checkIfNeedToInstall(fw)?Qt::Checked:Qt::Unchecked); return item; } void instDialog::setFlags(QTreeWidgetItem* item) { int obj_id = item->data(0, Qt::UserRole).toInt(); Firewall *fw = Firewall::cast(project->db()->findInIndex(obj_id)); QTreeWidgetItem* parent = item->parent(); time_t lm = fw->getInt("lastModified"); time_t lc = fw->getInt("lastCompiled"); time_t li = fw->getInt("lastInstalled"); QDateTime dt; if (fwbdebug) { qDebug() << "instDialog::setFlags" << item->text(0) << "parent=" << parent << "fw=" << fw << "Firewall::isA(fw)=" << Firewall::isA(fw) << "lm=" << lm << "lc=" << lc << "li=" << li << "compile_only=" << compile_only; qDebug() << "fw->needsCompile()" << fw->needsCompile() << "checkIfNeedToCompile(fw)=" << checkIfNeedToCompile(fw); } // need to skip the secondary cluster members if platform only // allows installations on the primary (e.g. PIX). Note that // platform attribute must be the same in the cluster and member // firewalls objects. See #998 string platform = fw->getStr("platform"); bool install_only_on_primary_member = Resources::getTargetCapabilityBool( platform, "install_only_on_primary"); Cluster *cluster = NULL; FWObject *master_interface = NULL; if (parent) { int obj_id = parent->data(0, Qt::UserRole).toInt(); cluster = Cluster::cast(project->db()->findInIndex(obj_id)); if (cluster) { FWObject *state_sync_group = cluster->getFirstByType(StateSyncClusterGroup::TYPENAME); // use state sync group to find which member firewall is // master. This is only needed for platforms that install // only on master (PIX at this time) if (state_sync_group) { string master_id = state_sync_group->getStr("master_iface"); for (FWObjectTypedChildIterator grp_it = state_sync_group->findByType(FWObjectReference::TYPENAME); grp_it != grp_it.end(); ++grp_it) { FWObject *iface = FWObjectReference::getObject(*grp_it); if (FWObjectDatabase::getStringId(iface->getId()) == master_id) { master_interface = iface; break; } } } } } // Real firewalls get checkbox for install if (Firewall::isA(fw)) { bool checked = false; if (!compile_only) { checked = checkIfNeedToInstall(fw); if (cluster) { // override if checkIfNeedToCompile() is true for the // parent cluster. if (checkIfNeedToCompile(cluster)) { checked = true; } } item->setCheckState(INSTALL_CHECKBOX_COLUMN, checked?Qt::Checked:Qt::Unchecked); // If this platform requires installation only on // the master, disable and uncheck checkbox for the standby. if (install_only_on_primary_member && master_interface != NULL) { QString txt = item->text(0); if (master_interface->isChildOf(fw)) { // Master item->setText(0, QString("%1 (master)").arg(txt)); } else { // Standby item->setText(0, QString("%1 (standby)").arg(txt)); item->setCheckState(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked); item->setFlags(0); } } } if (cluster==NULL) { // we are adding firewall that is not cluster member, it // needs "compile" checkbox checked = checkIfNeedToCompile(fw); item->setCheckState(COMPILE_CHECKBOX_COLUMN, checked?Qt::Checked:Qt::Unchecked); } } int num_members = 0; // Clusters only get checkbox for compile, and only if they have members. if (Cluster::isA(fw)) { list members; Cluster::cast(fw)->getMembersList(members); num_members = members.size(); if (num_members) { bool checked = checkIfNeedToCompile(fw); item->setCheckState(COMPILE_CHECKBOX_COLUMN, checked?Qt::Checked:Qt::Unchecked); } } dt.setTime_t(lm); item->setText(LAST_MODIFIED_COLUMN, (lm)?dt.toString():QString("Never")); dt.setTime_t(lc); item->setText(LAST_COMPILED_COLUMN, (lc)?dt.toString():QString("Never")); dt.setTime_t(li); item->setText(LAST_INSTALLED_COLUMN, (li)?dt.toString():QString("Never")); } /* * The following color and font manipulations are subject to QT bug * http://trolltech.no/developer/task-tracker/index_html?method=entry&id=212207 * * This requires QT 4.4.1 or 4.3 */ void instDialog::setSuccessState(QTreeWidgetItem *item) { QBrush b = item->foreground(1); b.setColor(Qt::darkGreen); item->setForeground(1,b); item->setForeground(0,b); QFont f = item->font(1); f.setBold(true); item->setFont(1,f); item->setFont(0,f); } void instDialog::setFailureState(QTreeWidgetItem *item) { QBrush b = item->foreground(1); b.setColor(Qt::darkRed); item->setForeground(1,b); item->setForeground(0,b); QFont f = item->font(1); f.setBold(true); item->setFont(1,f); item->setFont(0,f); } void instDialog::setErrorState(QTreeWidgetItem *item) { QBrush b = item->foreground(1); b.setColor(Qt::darkRed); item->setForeground(1,b); item->setForeground(0,b); QFont f = item->font(1); f.setBold(true); item->setFont(1,f); item->setFont(0,f); } void instDialog::setInProcessState(QTreeWidgetItem *item) { QBrush b = item->foreground(1); b.setColor(Qt::black); item->setForeground(1,b); item->setForeground(0,b); QFont f = item->font(1); f.setBold(true); item->setFont(1,f); item->setFont(0,f); } void instDialog::opSuccess(Firewall *fw) { if (fwbdebug) qDebug() << "instDialog::opSuccess fw=" << fw->getName().c_str(); compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_SUCCESS; QTreeWidgetItem* itm = opListMapping[(fw)->getId()]; if (itm) { itm->setText(1,tr("Success")); setSuccessState(itm); } currentLabel->setText(""); } void instDialog::opError(Firewall *fw) { if (fwbdebug) qDebug() << "instDialog::opError fw=" << fw->getName().c_str(); compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_ERROR; QTreeWidgetItem* itm = opListMapping[(fw)->getId()]; if (itm) { itm->setText(1, tr("Error")); setErrorState(itm); } currentLabel->setText(""); } void instDialog::opCancelled(Firewall *fw) { compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_ERROR; QTreeWidgetItem* itm = opListMapping[(fw)->getId()]; // itm can be NULL, for example when we install to PIX cluster // where we skip one of the members if (itm) { itm ->setText(1, tr("Cancelled")); setErrorState(itm); } currentLabel->setText(""); } void instDialog::nextClicked() { if (currentPage() == CHOOSE_OBJECTS) { page_1_op = INST_DLG_COMPILE; showPage(COMPILE_INSTALL); return; } if (currentPage() == COMPILE_INSTALL && (page_1_op == INST_DLG_COMPILE || page_1_op == INST_DLG_INSPECT)) { // clicking "Next" on page 1 (compile/install) changes // contents of the same page page_1_op = INST_DLG_INSTALL; showPage(COMPILE_INSTALL); return; } } void instDialog::backClicked() { if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_COMPILE) { // clicking "Back" on page 1 in mode "compile" returns to page 0 page_1_op = INST_DLG_COMPILE; showPage(CHOOSE_OBJECTS); return; } if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_INSTALL) { // clicking "Back" on page 1 in mode "install" changes // contents of the same page. Ideally, I would like to be // able to move back from "install" mode to "compile" mode // without recompiling everything. This is impossible in the // current implementation because we reuse the same widgets on // the page. This will be possible when "install" becomes its // own page of the wizard. // page_1_op = INST_DLG_COMPILE; // showPage(COMPILE_INSTALL); return; } if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_INSPECT) { page_1_op = INST_DLG_COMPILE; showPage(COMPILE_INSTALL); return; } } void instDialog::inspectFiles() { page_1_op = INST_DLG_INSPECT; showPage(COMPILE_INSTALL); } void instDialog::prepareInstConf(Firewall *) { if (fwbdebug) qDebug("instDialog::prepareInstConf"); } void instDialog::storeInstallerOptions() { st->setValue(SETTINGS_PATH_PREFIX"/Installer/savediff",cnf.save_diff); st->setValue(SETTINGS_PATH_PREFIX"/Installer/saveStandby",cnf.saveStandby); st->setValue(SETTINGS_PATH_PREFIX"/Installer/dryrun" ,cnf.dry_run); st->setValue(SETTINGS_PATH_PREFIX"/Installer/quiet", cnf.quiet); st->setValue(SETTINGS_PATH_PREFIX"/Installer/verbose", cnf.verbose); st->setValue(SETTINGS_PATH_PREFIX"/Installer/stripComments", cnf.stripComments); st->setValue(SETTINGS_PATH_PREFIX"/Installer/compressScript", cnf.compressScript); st->setValue(SETTINGS_PATH_PREFIX"/Installer/copyFWB", cnf.copyFWB); } void instDialog::summary() { QStringList str; str.append(QObject::tr("Summary:")); str.append(QObject::tr("* Running as user : %1").arg(user_name)); str.append(QObject::tr("* Firewall name : %1") .arg(QString::fromUtf8(cnf.fwobj->getName().c_str()))); str.append(QObject::tr("* Installer uses user name : %1").arg(cnf.user)); // print destination machine address or name correctly, taking into // account putty session if any if (!cnf.putty_session.isEmpty()) str.append(QObject::tr("* Using putty session: %1").arg(cnf.putty_session)); else str.append(QObject::tr("* Management address : %1").arg(cnf.maddr)); str.append(QObject::tr("* Platform : %1") .arg(cnf.fwobj->getStr("platform").c_str())); str.append(QObject::tr("* Host OS : %1") .arg(cnf.fwobj->getStr("host_OS").c_str())); str.append(QObject::tr("* Loading configuration from file %1") .arg(cnf.fwbfile)); if (cnf.save_diff) str.append(QObject::tr("* Configuration diff will be saved in file %1"). arg(cnf.diff_file)); if (cnf.dry_run) str.append(QObject::tr("* Commands will not be executed on the firewall")); if (fwbdebug) { str.append(QObject::tr("--------------------------------")); str.append(QObject::tr("* Variables:")); str.append(QObject::tr("* fwdir= %1") .arg(cnf.fwdir)); str.append(QObject::tr("* fwscript= %1") .arg(cnf.fwscript)); str.append(QObject::tr("* remote_script= %1") .arg(cnf.remote_script)); } str.append(""); QTextCursor cursor = m_dialog->procLogDisplay->textCursor(); cursor.insertBlock(); cursor.insertText(str.join("\n"), highlight_format); } void instDialog::fillCompileSelectList() { if (fwbdebug) qDebug("instDialog::fillCompileSelectList"); Firewall *fw; Cluster *cl; QDateTime dt; creatingTable = true; m_dialog->selectTable->clear(); list working_list_of_firewalls = firewalls; for (list::iterator i=clusters.begin(); i!=clusters.end(); ++i) { cl = *i; QTreeWidgetItem* cluster_item = createTreeItem(NULL, cl); m_dialog->selectTable->addTopLevelItem(cluster_item); list members; cl->getMembersList(members); for (list::iterator member=members.begin(); member!=members.end(); ++member) { createTreeItem(cluster_item, *member); working_list_of_firewalls.remove(*member); } cluster_item->setExpanded(true); } for (list::iterator i=working_list_of_firewalls.begin(); i!=working_list_of_firewalls.end(); ++i) { fw = *i; QTreeWidgetItem* fw_item = createTreeItem(NULL, fw); m_dialog->selectTable->addTopLevelItem(fw_item); } QTreeWidgetItemIterator it(m_dialog->selectTable); while (*it) { setFlags(*it); ++it; } /* ticket #1305 * check if any of the firewall objects are members of clusters but * the clusters are not requested for compile */ QString warn1( tr("You are trying to compile policy for a firewall object that is " "a member of a cluster, however you requested compilation of only " "this member firewall and not the cluster it belongs to. Assuming " "firewall is standalone and not cluster member. Rules and parts of " "the script specific for the cluster configuration will not be " "generated.")); QStringList warn2; list all_libs = project->db()->getByType(Library::TYPENAME); foreach(FWObject *lib, all_libs) { if (lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) continue; list all_clusters = lib->getByTypeDeep(Cluster::TYPENAME); foreach(FWObject *_cl, all_clusters) { if (std::find(clusters.begin(), clusters.end(), _cl) == clusters.end()) { Cluster *cluster = Cluster::cast(_cl); assert(cluster); foreach(FWObject *fw, firewalls) { if (cluster->hasMember(Firewall::cast(fw))) { warn2 << QString(tr("Firewall '%1' is member of cluster '%2'") .arg(QString::fromUtf8(fw->getName().c_str())) .arg(QString::fromUtf8(cluster->getPath().c_str()))); } } } } } if (!warn2.empty()) { m_dialog->warning_message_1->setText(warn1); m_dialog->warning_message_2->setText(warn2.join("\n")); m_dialog->warning_space->show(); } creatingTable = false; for (int i=0; iselectTable->columnCount(); i++) m_dialog->selectTable->resizeColumnToContents(i); setNextEnabled(0, tableHasCheckedItems()); //m_dialog->selectTable->resizeRowsToContents(); } void instDialog::displayCommand(const QStringList &args) { QStringList a1 = args; for (QStringList::iterator i=a1.begin(); i!=a1.end(); i++) { if ( (*i)=="-pw" ) { i++; *i = "XXXXXX"; break; } } QString s=a1.join(" "); addToLog( tr("Running command '%1'\n").arg(s) ); } void instDialog::updateProgressBar(int n, bool setsize) { if (fwbdebug) qDebug("instDialog::updateProgressBar n=%d setsize=%d",n,setsize); if (setsize) currentProgressBar->setMaximum(n); else currentProgressBar->setValue(currentProgressBar->maximum()-n); } void instDialog::finishClicked() { finished = true; accept(); } /* user clicked 'Cancel' */ void instDialog::cancelClicked() { if (fwbdebug) qDebug("instDialog::cancelClicked()"); finished = true; if (proc.state() == QProcess::Running) { if (fwbdebug) qDebug() << "instDialog::cancelClicked killing background process"; rejectDialogFlag = true; proc.kill(); } if (installer != NULL) { if (fwbdebug) qDebug() << "instDialog::cancelClicked killing installer"; installer->terminate(); delete installer; installer = NULL; } QDialog::reject(); } void instDialog::showEvent( QShowEvent *ev) { st->restoreGeometry(this, QRect(200,100,780,500) ); QDialog::showEvent(ev); } void instDialog::hideEvent( QHideEvent *ev) { st->saveGeometry(this); QDialog::hideEvent(ev); } void instDialog::saveLog() { /* * We use QTextEdit::append to add lines to the log buffer, each append creates a new paragraph so QTextEdit::text returns only contents of the last paragraph. Need to reassemble the whole text adding text from each paragraph separately. */ QString logText; logText = m_dialog->procLogDisplay->toPlainText(); QString s = QFileDialog::getSaveFileName( this, "Choose a file", st->getOpenFileDir(), "Text file (*.txt)"); if (s.isEmpty()) return; st->setOpenFileDir(s); if (!s.endsWith(".txt")) s += ".txt"; if (fwbdebug) qDebug( "Saving log to file %s", s.toAscii().constData() ); QFile f(s); if (f.open( QIODevice::WriteOnly )) { QTextStream str( &f ); str << logText; f.close(); } } /* * Adds one line of text to the log * */ void instDialog::addToLog(const QString &buf) { if (buf.isEmpty()) return; foreach(QString line, buf.trimmed().split("\n")) { QTextCharFormat format = normal_format; list::const_iterator it; for (it=error_re.begin(); it!=error_re.end(); ++it) { if ((*it).indexIn(line) != -1) { format = error_format; break; } } for (it=warning_re.begin(); it!=warning_re.end(); ++it) { if ((*it).indexIn(line) != -1) { format = warning_format; break; } } /* See sourceforge bug https://sourceforge.net/tracker/?func=detail&aid=2847263&group_id=5314&atid=1070394 * * QTextEditor::insertHtml() becomes incrementally slow as the * amount of text already in the QTextEditor * increases. Compiling ~10 firewalls with few dozen rules * each slows the output to a crawl on Windows. Keeping each * line in a separate block makes it much faster. */ QString txt = line; while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r"))) txt.chop(1); if (format == error_format || format == warning_format ) format.setAnchorHref(txt); QTextCursor cursor = m_dialog->procLogDisplay->textCursor(); cursor.insertBlock(); cursor.insertText(txt, format); } //m_dialog->procLogDisplayList->addItem(txt); m_dialog->procLogDisplay->ensureCursorVisible(); //qApp->processEvents(); } void instDialog::interpretLogLine(const QString &line) { if (fwbdebug) qDebug("instDialog::interpretLogLine %s", line.toAscii().constData() ); QStringList words = line.trimmed().split(" "); if (fwbdebug) { for (int i=0; i=0) { bool ok; processedRules = words[1].toInt(&ok); if (ok) currentProgressBar->setValue(processedRules); if (fwbdebug) qDebug("instDialog::interpretLogLine set progress bar current=%d", processedRules); } else { if (words.first().indexOf("processing")>=0) { currentProgressBar->reset(); bool ok; int totalRules = words[1].toInt(&ok); if (ok) currentProgressBar->setMaximum(totalRules); processedRules = 0; if (fwbdebug) qDebug("instDialog::interpretLogLine set progress bar max=%d", totalRules); } else { if (words.first().indexOf("Compiling")>=0) { //currentLabel->setText(line.trimmed()); currentProgressBar->reset(); } else { if (line.indexOf("Compiled successfully")>=0) { //currentLabel->setText(line.trimmed()); currentProgressBar->setValue(currentProgressBar->maximum()); if (fwbdebug) qDebug("instDialog::interpretLogLine set progress " "bar to max"); } } } } QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,1); } void instDialog::readFromStdout() { char buf[2048]; int read_status = 0; while ((read_status = proc.readLine(buf, sizeof(buf)))>0) { if (fwbdebug) { qDebug("instDialog::readFromStdout: read_status=%d buf=%s", read_status, buf); } addToLog(buf); interpretLogLine(buf); } } void instDialog::selectAllFirewalls() { if (fwbdebug) qDebug("instDialog::selectAllFirewalls"); setSelectStateAll(INSTALL_CHECKBOX_COLUMN, Qt::Checked); setSelectStateAll(COMPILE_CHECKBOX_COLUMN, Qt::Checked); tableItemChanged(NULL, 0); } void instDialog::deselectAllFirewalls() { setSelectStateAll(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked); setSelectStateAll(COMPILE_CHECKBOX_COLUMN, Qt::Unchecked); tableItemChanged(NULL, 0); } void instDialog::setSelectStateAll(int column, Qt::CheckState select) { QTreeWidgetItemIterator it(m_dialog->selectTable); while (*it) { int obj_id = (*it)->data(0, Qt::UserRole).toInt(); FWObject *o = project->db()->findInIndex(obj_id); bool cluster_member = (*it)->data(1, Qt::UserRole).toBool(); int num_members = (*it)->data(2, Qt::UserRole).toInt(); Qt::ItemFlags flags = (*it)->flags(); if ((flags & Qt::ItemIsUserCheckable) != 0) { // firewalls only get checkboxes for install, if (column == INSTALL_CHECKBOX_COLUMN && Firewall::isA(o)) (*it)->setCheckState(column, select); // Cluster gets checkbox for compile. // Cluster should never get a checkbox if it has no members. // Firewall that is not a cluster member gets compile checkbox if ((column == COMPILE_CHECKBOX_COLUMN && Cluster::isA(o) && num_members) || (Firewall::isA(o) && !cluster_member)) (*it)->setCheckState(column, select); } ++it; } } void instDialog::fillCompileOpList() { compile_fw_list.clear(); QTreeWidgetItemIterator it(m_dialog->selectTable); while (*it) { if ((*it)->checkState(COMPILE_CHECKBOX_COLUMN)) { int obj_id = (*it)->data(0, Qt::UserRole).toInt(); FWObject *o = project->db()->findInIndex(obj_id); compile_fw_list.push_back(Firewall::cast(o)); } ++it; } compile_list_initial_size = compile_fw_list.size(); } void instDialog::fillCompileUIList() { if (fwbdebug) qDebug("instDialog::fillCompileUIList"); m_dialog->fwWorkList->clear(); opListMapping.clear(); Firewall * f; InstallFirewallViewItem * item; list::iterator i; for(i=compile_fw_list.begin(); i!=compile_fw_list.end(); ++i) { f = (*i); item = new InstallFirewallViewItem( NULL,//m_dialog->fwWorkList, QString::fromUtf8(f->getName().c_str()), false); item->setData(0, Qt::UserRole, QVariant(f->getId())); m_dialog->fwWorkList->insertTopLevelItem(0, item); opListMapping[f->getId()] = item; } m_dialog->fwWorkList->resizeColumnToContents(0); m_dialog->fwWorkList->sortByColumn(0, Qt::AscendingOrder); } void instDialog::fillInstallOpList() { if (fwbdebug) qDebug("instDialog::fillInstallOpList"); install_fw_list.clear(); QTreeWidgetItemIterator it(m_dialog->selectTable); while (*it) { if ((*it)->checkState(INSTALL_CHECKBOX_COLUMN)) { int obj_id = (*it)->data(0, Qt::UserRole).toInt(); FWObject *o = project->db()->findInIndex(obj_id); install_fw_list.push_back(Firewall::cast(o)); if (fwbdebug) qDebug("fillInstallOpList: Install requested for %s", o->getName().c_str()); } ++it; } install_list_initial_size = install_fw_list.size(); } void instDialog::fillInstallUIList() { if (fwbdebug) qDebug("instDialog::fillInstallUIList"); m_dialog->fwWorkList->clear(); opListMapping.clear(); Firewall * f; InstallFirewallViewItem * item; list::iterator i; for(i=install_fw_list.begin(); i!=install_fw_list.end(); ++i) { f = (*i); item = new InstallFirewallViewItem( NULL, QString::fromUtf8(f->getName().c_str()), false); m_dialog->fwWorkList->insertTopLevelItem(0, item); opListMapping[f->getId()] = item; } m_dialog->fwWorkList->resizeColumnToContents(0); m_dialog->fwWorkList->sortByColumn(0, Qt::AscendingOrder); } void instDialog::findFirewallInCompileLog(QTreeWidgetItem* item) { if (fwbdebug) qDebug("instDialog::findFirewallInCompileLog"); m_dialog->detailMCframe->show(); qApp->processEvents(); QString fw_name = item->text(0); m_dialog->procLogDisplay->moveCursor( QTextCursor::End ); m_dialog->procLogDisplay->find(currentSearchString + fw_name, QTextDocument::FindWholeWords | QTextDocument::FindCaseSensitively | QTextDocument::FindBackward); } void instDialog::tableItemChanged(QTreeWidgetItem*, int) { if (!creatingTable) setNextEnabled(0, tableHasCheckedItems()); } bool instDialog::tableHasCheckedItems() { QTreeWidgetItemIterator it(m_dialog->selectTable); while (*it) { if ((*it)->checkState(COMPILE_CHECKBOX_COLUMN) || (*it)->checkState(INSTALL_CHECKBOX_COLUMN)) return true; ++it; } return false; } /* * getInstOptions() fills attributes of the cnf object */ bool instDialog::getInstOptions(Firewall *fw, bool installing_many_firewalls) { if (fwbdebug) qDebug() << "instDialog::getInstOptions() begin" << "cnf.user=" << cnf.user << "cnf.maddr=" << cnf.maddr << "fw=" << fw; cnf.fwobj = fw; readInstallerOptionsFromSettings(); readInstallerOptionsFromFirewallObject(fw); if (inst_opt_dlg && inst_opt_dlg->m_dialog->batchInstall->isChecked()) { // in batch install mode we use the same dialog to fill cnf // without showing it to the user again readInstallerOptionsFromDialog(fw, inst_opt_dlg); } else { // In non-batch mode installer options from the dialog // overwrite options set in the fw object itself. if (inst_opt_dlg) delete inst_opt_dlg; inst_opt_dlg = new instOptionsDialog(this, &cnf, installing_many_firewalls); int resultCode = inst_opt_dlg->exec(); // 0 - rejected // 1 - accepted // -1 - cancell all clicked if (resultCode == -1) { canceledAll = true; delete inst_opt_dlg; inst_opt_dlg = NULL; return false; } if (resultCode == QDialog::Rejected) { delete inst_opt_dlg; inst_opt_dlg = NULL; return false; } readInstallerOptionsFromDialog(fw, inst_opt_dlg); inst_opt_dlg->close(); // do not delete the dialog because we may need to get data from it again if // in batch install mode. //inst_opt_dlg->deleteLater(); } if (fwbdebug) qDebug() << "instDialog::getInstOptions() end" << "cnf.user=" << cnf.user << "cnf.maddr=" << cnf.maddr; return verifyManagementAddress(); } void instDialog::readInstallerOptionsFromSettings() { if (fwbdebug) qDebug("instDialog::readInstallerOptionsFromSettings"); fwb_prompt="--**--**--"; cnf.save_diff = st->value(SETTINGS_PATH_PREFIX"/Installer/savediff").toBool(); cnf.saveStandby = st->value(SETTINGS_PATH_PREFIX"/Installer/saveStandby").toBool(); cnf.dry_run = st->value(SETTINGS_PATH_PREFIX"/Installer/dryrun").toBool(); cnf.quiet = st->value(SETTINGS_PATH_PREFIX"/Installer/quiet").toBool(); cnf.verbose = st->value(SETTINGS_PATH_PREFIX"/Installer/verbose" ).toBool(); 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(); } void instDialog::readInstallerOptionsFromFirewallObject(Firewall *fw) { if (fwbdebug) qDebug() << "instDialog::readInstallerOptionsFromFirewallObject" << "fw=" << fw << QString( (fw) ? QString::fromUtf8(fw->getName().c_str()) : ""); FWOptions *fwopt = NULL; if (fw) { fwopt = fw->getOptionsObject(); string platform = cnf.fwobj->getStr("platform"); string host_OS = cnf.fwobj->getStr("host_OS"); cnf.user = fwopt->getStr("admUser").c_str(); QString standard_management_addr; // Note that Host::getManagementAddress() scans interfaces and // finds one marked as "management" and takes its address. // It does not use Management child object. const InetAddr *mgmt_addr = cnf.fwobj->getManagementAddress(); if (mgmt_addr) standard_management_addr = mgmt_addr->toString().c_str(); else standard_management_addr = ""; QString aaddr = fwopt->getStr("altAddress").c_str(); if (fwbdebug) qDebug() << " standard_management_addr=" << standard_management_addr << "aaddr=" << aaddr; if (!aaddr.isEmpty()) cnf.maddr = aaddr; else cnf.maddr = standard_management_addr; cnf.putty_session = ""; #ifdef _WIN32 /* * See #1724. There is a problem with pscp.exe and putty * sessions. Plink.exe accepts session name in place of the host name * on the command line, but pscp.exe does not. We ask user to enter * session name in the "alternative name or address to use to * communicate with the firewall" input field in the "Installer" tab * of the firewall settings dialog and then use it in place of the * host name in the command line for pscp.exe and plink.exe. This * works with plink.exe but breaks pscp.exe which interprets it as a * host name and fails with an error ""ssh_init: Host does not exist". * * Will try to determine if what user entered in the "alternative host * or address field" is a session name and use different command line * for pscp.exe * * * HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\ */ QSettings putty_reg(QSettings::UserScope, "SimonTatham", "PuTTY\\Sessions"); QStringList sessions = putty_reg.childGroups(); if (fwbdebug) { qDebug() << putty_reg.fileName(); qDebug() << "found " << sessions.size() << " putty sessions"; foreach(QString key, sessions) { qDebug() << "putty session " << key; } } if (sessions.contains(aaddr)) { if (fwbdebug) qDebug() << "Found matching putty session" << aaddr; cnf.maddr = standard_management_addr; cnf.putty_session = aaddr; } #endif /* * if user requested test run, store firewall script in a temp * file. Always store it in a temp file on linksys */ QString s; /* user_can_change_install_dir */ bool uccid = Resources::getTargetOptionBool( host_OS, "user_can_change_install_dir"); if (uccid) s = fwopt->getStr("firewall_dir").c_str(); if (s.isEmpty()) s = Resources::getTargetOptionStr( host_OS, "activation/fwdir").c_str(); cnf.fwdir = s; /* * Generated files should be saved in the same directory where * the .fwb file is located, except if user specified full path * in the advaced settings dialog. */ cnf.script = FirewallInstaller::getGeneratedFileFullPath(fw); // cnf.script = FirewallInstaller::getGeneratedFileName(fw); cnf.remote_script = ""; // filled in FirewallInstaller::readManifest() cnf.fwbfile = project->db()->getFileName().c_str(); cnf.wdir = getFileDir( project->getRCS()->getFileName() ); cnf.diff_file = QString(cnf.fwobj->getName().c_str())+".diff"; cnf.diff_pgm = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/diff").c_str(); cnf.diff_pgm = getPathToBinary( cnf.diff_pgm.toAscii().constData()).c_str(); #ifdef _WIN32 cnf.diff_pgm = cnf.diff_pgm + ".exe"; #endif cnf.sshArgs = fwopt->getStr("sshArgs").c_str(); cnf.scpArgs = fwopt->getStr("scpArgs").c_str(); cnf.useSCPForRouter = fwopt->getBool("use_scp"); cnf.activationCmd = fwopt->getStr("activationCmd").c_str(); if (fwbdebug) { qDebug("platform: %s", platform.c_str()); qDebug("host_OS: %s", host_OS.c_str()); qDebug("user_can_change_install_dir=%d", uccid); qDebug("firewall_dir='%s'", fwopt->getStr("firewall_dir").c_str()); qDebug("management address: %s", cnf.maddr.toAscii().constData()); qDebug("cnf.fwdir='%s'", cnf.fwdir.toAscii().constData()); qDebug("activationCmd='%s'", cnf.activationCmd.toAscii().constData()); } } } void instDialog::readInstallerOptionsFromDialog(Firewall *fw, instOptionsDialog *dlg) { if (fwbdebug) qDebug() << "instDialog::readInstallerOptionsFromDialog" << "fw=" << fw; QString adm_user; FWOptions *fwopt = NULL; if (fw) { fwopt = cnf.fwobj->getOptionsObject(); adm_user = fwopt->getStr("admUser").c_str(); } cnf.batchInstall = dlg->m_dialog->batchInstall->isChecked(); cnf.dry_run = dlg->m_dialog->test->isChecked(); cnf.backup_file = dlg->m_dialog->backupConfigFile->text(); cnf.backup = !cnf.backup_file.isEmpty(); cnf.save_diff = dlg->m_dialog->saveDiff->isChecked(); cnf.saveStandby = dlg->m_dialog->saveStandby->isChecked(); /* Alternative address: - first, check dialog. User could have overriden it using dialog - then check firewall options, user could have set it in the "Install" tab of firewall settings dialog - last, if all overrides are empty, take it from the management interface - ignore alternative address if in batch mode */ if ( ! cnf.batchInstall) { QString aaddr = dlg->m_dialog->altAddress->text(); if (!aaddr.isEmpty()) { /* alternative address can also be putty session name. In any case, * leave it up to ssh to resolve it and signal an error if it can't be * resolved ( Putty session name does not have to be in DNS at all ). */ cnf.maddr = aaddr; if (fwbdebug) qDebug() << "alternative addr:" << aaddr; } } // user name set in the dialog overrides that set in the fw object // But the dialog user name input field can be left blank, in which // case we use the one configured in the object if (!adm_user.isEmpty()) cnf.user = adm_user; if (!dlg->m_dialog->uname->text().isEmpty()) cnf.user = dlg->m_dialog->uname->text(); cnf.pwd = dlg->m_dialog->pwd->text(); cnf.epwd = dlg->m_dialog->epwd->text(); cnf.quiet = dlg->m_dialog->quiet->isChecked(); cnf.verbose = dlg->m_dialog->verbose->isChecked(); cnf.stripComments = dlg->m_dialog->stripComments->isChecked(); cnf.compressScript= dlg->m_dialog->compressScript->isChecked(); cnf.copyFWB = dlg->m_dialog->copyFWB->isChecked(); dlg->savePassword(); storeInstallerOptions(); } bool instDialog::verifyManagementAddress() { /* check for a common error when none or multiple interfaces are marked as * 'management' */ if (cnf.maddr.isEmpty() && cnf.putty_session.isEmpty() && cnf.fwobj) { int nmi = 0; list ll = cnf.fwobj->getByTypeDeep(Interface::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { Interface *intf = Interface::cast( *i ); if (intf->isManagement()) nmi++; } if (nmi>1) { QString err = QObject::tr("Only one interface of the firewall '%1' " "must be marked as management interface.\n") .arg(QString::fromUtf8(cnf.fwobj->getName().c_str())); QMessageBox::critical(this, "Firewall Builder", err, tr("&Continue") ); addToLog(err); return false; } if (nmi==0) { QString err = QObject::tr( "One of the interfaces of the firewall '%1' " "must be marked as management interface. " "To set the management interface, double click " "on the interface of the firewall that you will " "connect to and check the box called Management " "interface in the Editor panel") .arg(QString::fromUtf8(cnf.fwobj->getName().c_str())); QMessageBox::critical(this, "Firewall Builder", err, tr("&Continue") ); addToLog(err); return false; } if (cnf.maddr == "" || cnf.maddr == QString(InetAddr::getAny().toString().c_str())) { QString err = QObject::tr( "Management interface does not have IP address, " "can not communicate with the firewall.\n"); QMessageBox::critical(this, "Firewall Builder", err, tr("&Continue") ); addToLog(err); return false; } } return true; } void instDialog::logItemClicked(QUrl data) { QStringList parts = data.toString().split(':'); if (parts[0] == "Error") return; if (parts.size()<3) { if(fwbdebug) cout << "Wrong error message clicked" << endl; return; } emit activateRule(project, parts[0], parts[1], parts[2].toInt()); } void instDialog::closeEvent(QCloseEvent *) { if (fwbdebug) qDebug() << "instDialog::closeEvent"; if (proc.state() == QProcess::Running) { if (fwbdebug) qDebug() << "instDialog::closeEvent killing process"; proc.kill(); } if (installer != NULL) { if (fwbdebug) qDebug() << "instDialog::closeEvent killing installer"; installer->terminate(); delete installer; installer = NULL; } } fwbuilder-5.1.0.3599/src/libgui/PrintingController.cpp0000644000175000017500000004375211733011756023415 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "RuleSetView.h" #include "FWBSettings.h" #include "FWObjectPropertiesFactory.h" #include "ProjectPanel.h" #include "PrintingController.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Interface.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/RuleElement.h" #include #include #include #include using namespace libfwbuilder; using namespace std; QString legendList[] = { Firewall::TYPENAME, QObject::tr("Firewall"), Host::TYPENAME, QObject::tr("Host"), IPv4::TYPENAME, QObject::tr("Address"), IPv6::TYPENAME, QObject::tr("Address"), AddressRange::TYPENAME, QObject::tr("Addres Range"), Interface::TYPENAME, QObject::tr("Interface"), Network::TYPENAME, QObject::tr("Network"), ObjectGroup::TYPENAME, QObject::tr("Group of objects"), CustomService::TYPENAME, QObject::tr("Custom Service"), IPService::TYPENAME, QObject::tr("IP Service"), ICMPService::TYPENAME, QObject::tr("ICMP Service"), ICMP6Service::TYPENAME, QObject::tr("ICMP Service"), TCPService::TYPENAME, QObject::tr("TCP Service"), UDPService::TYPENAME, QObject::tr("UDP Service"), ServiceGroup::TYPENAME, QObject::tr("Group of services"), Interval::TYPENAME, QObject::tr("Time Interval"), "", "" }; class pixmapOrText { public: QString text; QPixmap pixmap; pixmapOrText(const QString &t,const QPixmap &w); }; pixmapOrText::pixmapOrText(const QString &t,const QPixmap &w) : text(t), pixmap(w) { } list PrintingController::findAllUsedByType(list &result, FWObject *obj, const string &type_name) { if (RuleElement::cast(obj)!=NULL) { for (list::iterator m=obj->begin(); m!=obj->end(); m++) { FWObject *o=*m; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if (o->getTypeName()==type_name) result.push_back(o); } } if (RuleSet::cast(obj)!=NULL) { for (list::iterator m=obj->begin(); m!=obj->end(); m++) { if (Rule::cast(*m)!=NULL) { for (list::iterator n=(*m)->begin(); n!=(*m)->end(); n++) { if (RuleElement::cast(*n)!=NULL) { findAllUsedByType(result,*n,type_name); } } } } } if (Firewall::cast(obj)) // cast matches Firewall and Cluster { FWObject *ruleSet; const char* const child_types[] = {Policy::TYPENAME, NAT::TYPENAME, Routing::TYPENAME, NULL}; for (const char* const *cptr = child_types; *cptr; ++cptr) { for (FWObjectTypedChildIterator it = obj->findByType(*cptr); it != it.end(); ++it) { ruleSet = *it; findAllUsedByType(result, ruleSet, type_name); } } result.sort(); result.unique(); } return result; } int PrintingController::addObjectsToTable(list &objects, QTableWidget *tbl, int &row, int &col) { int added =0; string icon_path="/FWBuilderResources/Type/"; QPixmap bfr(32,32); QPainter bfrp(&bfr); for (list::iterator i=objects.begin(); i!=objects.end(); ++i) { if (Address::cast(*i)!=NULL && Address::cast(*i)->isAny()) continue; if (Service::cast(*i)!=NULL && Service::cast(*i)->isAny()) continue; if (Interval::cast(*i)!=NULL && Interval::cast(*i)->isAny()) continue; if (col>=tbl->columnCount()) { col = 0; row++; tbl->insertRow(row); } string type_name = (*i)->getTypeName(); QString icn = (":/Icons/"+type_name+"/icon").c_str(); QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } bfrp.fillRect(0,0,32,32,QColor("white")); bfrp.drawPixmap(4,4,pm); tbl->setItem(row,col, new QTableWidgetItem(QIcon(bfr), QString::fromUtf8((*i)->getName().c_str()))); QString descr = FWObjectPropertiesFactory::getObjectProperties(*i); QString comment = QString::fromUtf8((*i)->getComment().c_str()); // collapse paragraphs //comment.replace("\n\n", " "); //comment.replace("\n", ""); //comment.replace(" ", "\n"); tbl->setItem(row,col+1, new QTableWidgetItem(descr)); tbl->setItem(row,col+2, new QTableWidgetItem(comment)); //tbl->item(row,col+2)->setWordWrap(true); added++; if (fwbdebug) qDebug("objTbl: row=%d col=%d '%s'", row, col, (*i)->getName().c_str()); col = col+3; } return added; } bool PrintingController::addObjectsByTypeToTable(FWObject *parent, const string &type_name, QTableWidget *tbl, int &row, int &col) { list objects; findAllUsedByType(objects, parent, type_name); int added = addObjectsToTable(objects, tbl, row, col); if (fwbdebug) qDebug("Objects table: type %s, added %d", type_name.c_str(), added); if (added) { if (col!=0) { row++; col=0; tbl->insertRow(row); } return true; } return false; } void PrintingController::findAllGroups(list &objects, list &groups) { if (fwbdebug) qDebug("findAllGroups: arg1 size %d", int(objects.size())); for (FWObject::iterator obj=objects.begin(); obj!=objects.end(); ++obj) { if (fwbdebug) qDebug(" %s",(*obj)->getName().c_str()); FWObject *o = *obj; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if (Group::cast(o)!=NULL && std::find(groups.begin(),groups.end(),o)==groups.end()) { groups.push_back(o); if (fwbdebug) qDebug("Add group %s to groups",o->getName().c_str()); findAllGroups(*o,groups); } } } void PrintingController::printRuleSet(FWObject *fw, const string &ruleset_type_name, ProjectPanel *project) { FWObjectTypedChildIterator j =fw->findByType(ruleset_type_name); for ( ; j!=j.end(); ++j ) { RuleSet * ruleset = RuleSet::cast(*j) ; QString name = QObject::tr("Policy: "); name += ruleset->getName().c_str(); pr->printText("\n"); pr->printText(name); RuleSetView *ruleView = RuleSetView::getRuleSetViewByType( project, ruleset, NULL); ruleView->setSizePolicy( QSizePolicy( (QSizePolicy::Policy)7, (QSizePolicy::Policy)7) ); ruleView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ruleView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ruleView->setMaximumHeight(pr->getPageHeight()); ruleView->restoreCollapsedGroups(); if (fwbdebug) qDebug("Viewport: %dx%d", ruleView->viewport()->width(),ruleView->viewport()->height()); if (fwbdebug) qDebug("Size: %dx%d",ruleView->width(),ruleView->height()); pr->printRuleSetView(ruleView); delete ruleView; } } void PrintingController::printFirewall(FWObject *fw, ProjectPanel *project) { if (Firewall::cast(fw)==NULL) return ; string platform = fw->getStr("platform"); string version = fw->getStr("version"); string hostOS = fw->getStr("host_OS"); QString readableVersion = getVersionString(QString(platform.c_str()), QString(version.c_str())); pr->beginPage(); // resets yPos pr->printText(QObject::tr("Firewall name: %1").arg( QString::fromUtf8(fw->getName().c_str()))); pr->printText(QObject::tr("Platform: ") + platform.c_str()); pr->printText(QObject::tr("Version: ") + readableVersion); pr->printText(QObject::tr("Host OS: ") + hostOS.c_str()); const char* const child_types[] = {Policy::TYPENAME, NAT::TYPENAME, Routing::TYPENAME, NULL}; for (const char* const *cptr = child_types; *cptr; ++cptr) { if (fwbdebug) qDebug("******** %s", *cptr); printRuleSet(fw, *cptr, project); } } void PrintingController::printLegend(bool newPageForSection) { if (fwbdebug) qDebug("******** Legend"); if (newPageForSection) { pr->flushPage(); pr->beginPage(); // resets yPos } else pr->printText("\n"); pr->printText(QObject::tr("Legend")); pr->printText(" "); QTableWidget *legendTbl = new QTableWidget(1,2); configureQTableForPrint(legendTbl); string icon_path="/FWBuilderResources/Type/"; int row = 0; int col = 0; QPixmap pm; QPixmap bfr(32,32); QPainter bfrp(&bfr); for (int i=0; !legendList[i].isEmpty(); ++i,++i) { if (row >= legendTbl->rowCount()) legendTbl->insertRow(row); QString type_name = legendList[i]; QString objName = legendList[i+1]; if (type_name==CustomService::TYPENAME) { col++; row=0; } if (fwbdebug) qDebug("Legend table: row=%d col=%d %s %s", row, col, type_name.toAscii().constData(), objName.toAscii().constData()); QString icn = ":/Icons/"+type_name+"/icon"; QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } bfrp.fillRect(0,0,32,32,QColor(Qt::white)); bfrp.drawPixmap(4,4,pm); QTableWidgetItem *itm = new QTableWidgetItem; itm->setIcon(QIcon(bfr)); itm->setText(objName); legendTbl->setItem(row, col, itm); row++; } legendTbl->resizeColumnToContents(0); legendTbl->resizeColumnToContents(1); for (int i=0; irowCount(); ++i) legendTbl->resizeRowToContents(i); QSize sh = legendTbl->sizeHint(); legendTbl->resize(sh.width(),sh.height()); if (fwbdebug) qDebug("legendTbl size: %dx%d", legendTbl->width(),legendTbl->height()); pr->printQTable(legendTbl, false, false); } void PrintingController::printObjects(FWObject *firewall_to_print, bool newPageForSection) { if (fwbdebug) qDebug("******** Objects"); if (newPageForSection) { pr->flushPage(); pr->beginPage(); // resets yPos } else pr->printText("\n"); pr->printText(QObject::tr("Objects")); pr->printText(" "); bool haveObjGroups = false; bool haveSrvGroups = false; QTableWidget *fwObjTbl = new QTableWidget(1,3); configureQTableForPrint(fwObjTbl); QString descr; int row = 0; int col = 0; addObjectsByTypeToTable(firewall_to_print, Firewall::TYPENAME, fwObjTbl, row, col); for (int i=0; icolumnCount(); ++i) fwObjTbl->resizeColumnToContents(i); for (int i=0; irowCount(); ++i) fwObjTbl->resizeRowToContents(i); QSize sh = fwObjTbl->sizeHint(); fwObjTbl->resize(sh.width(), sh.height()); pr->printQTable(fwObjTbl, false, false); pr->printText(" "); QTableWidget *objTbl = new QTableWidget(1,6); configureQTableForPrint(objTbl); row = 0; col = 0; addObjectsByTypeToTable(firewall_to_print, Host::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, Network::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, NetworkIPv6::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, IPv4::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, IPv6::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, AddressRange::TYPENAME, objTbl, row, col); haveObjGroups = addObjectsByTypeToTable( firewall_to_print, ObjectGroup::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, IPService::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, ICMPService::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, ICMP6Service::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, TCPService::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, UDPService::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, CustomService::TYPENAME, objTbl, row, col); haveSrvGroups = addObjectsByTypeToTable( firewall_to_print, ServiceGroup::TYPENAME, objTbl, row, col); addObjectsByTypeToTable(firewall_to_print, Interval::TYPENAME, objTbl, row, col); for (int i=0; icolumnCount(); ++i) objTbl->resizeColumnToContents(i); for (int i=0; irowCount(); ++i) objTbl->resizeRowToContents(i); sh = objTbl->sizeHint(); objTbl->resize(sh.width(), sh.height()); pr->printQTable(objTbl, false, false); if (haveObjGroups || haveSrvGroups) { if (fwbdebug) qDebug("******** Groups"); pr->printText("\n"); pr->printText(QObject::tr("Groups")); pr->printText(" "); list groups; list objects; findAllUsedByType(objects, firewall_to_print, ObjectGroup::TYPENAME); findAllGroups(objects,groups); objects.clear(); findAllUsedByType(objects, firewall_to_print, ServiceGroup::TYPENAME); findAllGroups(objects,groups); for (FWObject::iterator obj=groups.begin(); obj!=groups.end(); ++obj) { QTableWidget *objTbl = new QTableWidget(1,6); configureQTableForPrint(objTbl); row = 0; col = 0; list groupMembers; for (FWObject::iterator j=(*obj)->begin(); j!=(*obj)->end(); ++j) { FWObject *o = *j; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); groupMembers.push_back(o); } int added = addObjectsToTable( groupMembers, objTbl, row, col); if (fwbdebug) qDebug("Group %s: added %d group members", (*obj)->getName().c_str(),added); if (added == 0) { objTbl->setItem(row, col, new QTableWidgetItem(QObject::tr("EMPTY")) ); } for (int i=0; icolumnCount(); ++i) objTbl->resizeColumnToContents(i); for (int i=0; irowCount(); ++i) objTbl->resizeRowToContents(i); pr->printText((*obj)->getName().c_str()); pr->printQTable(objTbl, false, false); pr->printText("\n"); } } } void PrintingController::configureQTableForPrint(QTableWidget *tbl) { tbl->resize(pr->getWorkspaceWidth(), pr->getWorkspaceHeight()); tbl->setSizePolicy( QSizePolicy( (QSizePolicy::Policy)7, (QSizePolicy::Policy)7) ); tbl->setShowGrid(false); tbl->setFrameStyle(QFrame::NoFrame | QFrame::Plain); tbl->horizontalHeader()->hide(); tbl->verticalHeader()->hide(); tbl->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); tbl->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } fwbuilder-5.1.0.3599/src/libgui/ipcoposAdvancedDialog.h0000644000175000017500000000272711733011756023443 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPCOPOSADVANCEDDIALOG_H_ #define __IPCOPOSADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class ipcoposAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::ipcoposAdvancedDialog_q *m_dialog; public: ipcoposAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~ipcoposAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); }; #endif // __IPCOPOSADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator.cpp0000644000175000017500000016307511733011756023202 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils_no_qt.h" #include "platforms.h" #include "events.h" #include "listOfLibrariesModel.h" #include "ProjectPanel.h" #include "ObjectManipulator.h" #include "ObjectEditor.h" #include "ObjectTreeViewItem.h" #include "ObjectTreeView.h" #include "FWObjectClipboard.h" #include "FWObjectPropertiesFactory.h" #include "FWBSettings.h" #include "findDialog.h" #include "newGroupDialog.h" #include "FindObjectWidget.h" #include "AskLibForCopyDialog.h" #include "FindWhereUsedWidget.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "FWBTree.h" #include "FWWindow.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Routing.h" #include "fwbuilder/TagService.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; HistoryItem::~HistoryItem() {} ObjectManipulator::~ObjectManipulator() { delete m_objectManipulator; delete libs_model; } ObjectManipulator::ObjectManipulator(QWidget *parent): QWidget(parent), current_tree_view(0) { m_objectManipulator = new Ui::ObjectManipulator_q; m_objectManipulator->setupUi(this); setObjectName(tr("Object Manipulator")); libs_model = new ListOfLibrariesModel(); m_objectManipulator->libs->setModel(libs_model); m_project = NULL; treeWidth = -1; treeHeight = -1; active = false; current_tree_view=NULL; previous_lib_index = -1; // used in duplicateWithDependencies() dedup_marker_global_counter = time(NULL); popup_menu = NULL; // buildNewObjectMenu(); } void ObjectManipulator::setupProject(ProjectPanel *project) { m_project = project; } vector ObjectManipulator::getTreeWidgets() { vector res; for (int i=0; irowCount(); ++i) { QTreeWidget *objTreeView = libs_model->getTreeWidget(i); if (objTreeView == NULL) continue; res.push_back(objTreeView); } return res; } void ObjectManipulator::showDeletedObjects(bool f) { try { FWObject *dobj = m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID); if (fwbdebug) qDebug("ObjectManipulator::showDeletedObjects f=%d dobj=%p", f, dobj); if (dobj==NULL) { dobj = m_project->db()->create(Library::TYPENAME); dobj->setId(FWObjectDatabase::DELETED_OBJECTS_ID); dobj->setName("Deleted Objects"); dobj->setReadOnly(false); m_project->db()->add(dobj); } QModelIndex idx = libs_model->getIdxForLib(dobj); if (fwbdebug) qDebug("ObjectManipulator::showDeletedObjects idx.row()=%d", idx.row()); if (f) { if (idx.isValid()) return; addLib( dobj ); openLib( dobj ); } else { if (!idx.isValid()) return; QTreeWidget *otv = libs_model->getTreeWidget(idx); if (fwbdebug) qDebug("ObjectManipulator::showDeletedObjects otv=%p", otv); assert(otv!=NULL); m_objectManipulator->widgetStack->removeWidget( otv ); removeLib(idx.row()); } } catch(FWException &ex) { /* we get exception if file is opened read-only and there is no "deleted * objects" library yet */ } } QString ObjectManipulator::getStandardName(FWObject *parent, const string&, const string &namesuffix) { QStringList names; FWObject *po = parent; while (po!=NULL) { names.push_front(QString::fromUtf8(po->getName().c_str())); if (Host::cast(po)) break; po = po->getParent(); } // names.push_back(QString::fromUtf8(parent->getName().c_str())); names.push_back(namesuffix.c_str()); return names.join(":"); } void ObjectManipulator::currentTreePageChanged(int i) { QWidget *w = m_objectManipulator->widgetStack->widget(i); switchingTrees(w); } void ObjectManipulator::switchingTrees(QWidget* w) { ObjectTreeView *new_otv = dynamic_cast(w); if (!new_otv) return;//assert(new_otv) if (current_tree_view!=NULL) current_tree_view->becomingHidden(); new_otv->becomingVisible(); current_tree_view = new_otv; } /* * Make the name of the object @obj unique across all children of the * given @target object. If this object is an interface, use pattern * and increment the number until the name becomes * unique. For all other types use pattern - * * This method has ugly side-effect: if @obj is an Interface, this * method needs to check its type. To do that, it calls * Interface::getOptionsObject() which creates options object if it * does not exits. To do initial options configuration, it needs * access to the parent. We call Interface::getOptionsObject() in copt * and startDrag methods to make sure interfaces have options objects * before copy or drag operation starts to avoid this problem here. * * In case of copy/paste or d&d of an interface, the naming * conventions are dictated by the platform of the new parent firewall * rather than the old one, which in this case is either or * its parent. So we'll use @target to get proper interfaceProperties * object which will do checks for us. */ void ObjectManipulator::makeNameUnique(FWObject *target, FWObject *obj) { Interface *intf = Interface::cast(obj); if (intf) { // check if this is vlan subinterface. We should not change // names of those if (intf->getOptionsObject()->getStr("type") == "8021q") return; // one of the typical usage patterns is to create vlan // interface "eth0.101" and then immediately try to copy/paste // it to under br0 to make it bridge port. In this case // interface eth0.101 won't have type "8021q" just yet because // the user did not open interface "advanced" settings dialog // to set its type and VLAN ID. Users assume that if its name // is "eth0.101", then it must be vlan interface. We should // follow this assumption too. Also, check for names "vlanNNN" // as well. // QString obj_name = QString::fromUtf8(obj->getName().c_str()); FWObject *fw = target; while (fw && !Firewall::cast(fw)) fw = fw->getParent(); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject(fw)); if (int_prop->looksLikeVlanInterface(obj_name)) return; } QString newname = makeNameUnique(target, QString::fromUtf8(obj->getName().c_str()), obj->getTypeName().c_str()); obj->setName(string(newname.toUtf8())); } QString ObjectManipulator::makeNameUnique(FWObject* parent, const QString &obj_name, const QString &obj_type) { int suffix = 1; QString basename = obj_name; QString newname = basename; if (fwbdebug) qDebug("ObjectManipulator::makeNameUnique parent=%s obj_name=%s", parent->getName().c_str(), obj_name.toStdString().c_str()); if (obj_type == Interface::TYPENAME) { QRegExp rx("([a-zA-Z-]+)(\\d{1,})"); if (rx.indexIn(obj_name) != -1) { basename = rx.cap(1); suffix = rx.cap(2).toInt(); } } /* * Check if there is another object with the same name. Note that * FWObject::findObjectByName() searches in depth, but we only need to * scan child objects of the first level. */ while (true) { if (fwbdebug) qDebug("ObjectManipulator::makeNameUnique newname=%s basename=%s suffix=%d", newname.toStdString().c_str(), basename.toStdString().c_str(), suffix); FWObject::const_iterator i = find_if( parent->begin(), parent->end(), FWObjectNameEQPredicate(newname.toStdString())); if (i==parent->end()) break; if (obj_type == Interface::TYPENAME) newname = QString("%1%2").arg(basename).arg(suffix); else newname = QString("%1-%2").arg(basename).arg(suffix); suffix++; } return newname; } static void addKeywordsMenu(ObjectManipulator *om, QMenu *menu) { QMenu *keywordsMenu = menu->addMenu(om->tr("Keywords")); QMenu *addKeywords = keywordsMenu->addMenu(om->tr("Add")); addKeywords->addAction(om->tr("New Keyword..."), om, SLOT(addNewKeywordSlot())); addKeywords->addSeparator(); QStringList addList; const set &allKeywords = om->getSelectedObject()->getAllKeywords(); set::const_iterator iterz; for (iterz = allKeywords.begin(); iterz != allKeywords.end(); ++iterz) { addList.append(QString::fromUtf8((*iterz).c_str())); } addList = sortStrings(addList); QStringList data; data << "add" << ""; foreach (QString add, addList) { QAction *act = addKeywords->addAction(add, om, SLOT(processKeywordSlot())); data[1] = add; act->setData(data); } bool allLocked = true; QMenu *removeKeywords = keywordsMenu->addMenu(om->tr("Remove")); QSet toRemove; foreach (FWObject *obj, om->getCurrentObjectTree()->getSelectedObjects()) { if (obj->isReadOnly()) continue; allLocked = false; const set &keywords = obj->getKeywords(); set::const_iterator iter; for (iter = keywords.begin(); iter != keywords.end(); ++iter) { toRemove.insert(QString::fromUtf8((*iter).c_str())); } } if (toRemove.isEmpty()) { removeKeywords->setDisabled(true); } else { data[0] = "remove"; foreach (QString str, sortStrings(toRemove.toList())) { QAction *act = removeKeywords->addAction(str, om, SLOT(processKeywordSlot())); data[1] = str; act->setData(data); } } if (allLocked) { keywordsMenu->setDisabled(true); } } void ObjectManipulator::contextMenuRequested(const QPoint &pos) { if (popup_menu == NULL) { popup_menu = new QMenu(this); popup_menu->setObjectName("objectTreeContextMenu"); } else popup_menu->clear(); /* in extended selection mode there may be several selected items */ ObjectTreeView *objTreeView = getCurrentObjectTree(); if (objTreeView == NULL) return; QTreeWidgetItem *item = objTreeView->itemAt(pos);//clicked item if (fwbdebug) qDebug("ObjectManipulator::contextMenu selectedObjects.size=%d", getCurrentObjectTree()->getNumSelected()); ObjectTreeViewItem *otvi=dynamic_cast(item); if (otvi==NULL) return; // happens when user clicks outside an item FWObject *obj = otvi->getFWObject(); if (obj == 0) { assert(otvi->getUserFolderParent() != 0); QAction *action = popup_menu->addAction(tr("Delete"), this, SLOT(removeUserFolder())); /* The user-defined folder doesn't get counted as a selected obj */ if (objTreeView->getNumSelected() > 0) { action->setEnabled(false); } popup_menu->exec(QCursor::pos()); return; } if (!getCurrentObjectTree()->isSelected(otvi->getFWObject())) openObjectInTree( otvi, true ); //if (currentObj==NULL) currentObj=otvi->getFWObject(); FWObject *currentObj = getSelectedObject(); if (item->childCount() > 0) { if (item->isExpanded()) popup_menu->addAction(tr("Collapse"), this, SLOT(collapseCurrentTreeNode())); else popup_menu->addAction(tr("Expand"), this, SLOT(expandCurrentTreeNode())); popup_menu->addSeparator(); } QAction *edtID; if (currentObj->isReadOnly()) edtID = popup_menu->addAction(tr("Inspect"), this, SLOT( editSelectedObject())); else edtID = popup_menu->addAction(tr("Edit"), this, SLOT( editSelectedObject())); if (RuleSet::cast(currentObj)) popup_menu->addAction(tr("Open"), this, SLOT( openSelectedRuleSet())); QMenu *duptargets = NULL; QAction *dupID = NULL; QMenu *movetargets = NULL; int moveTargetsCounter = 0; if (!Interface::isA(currentObj) && !physAddress::isA(currentObj) && RuleSet::cast(currentObj)==NULL && !Library::isA(currentObj) && !FWBTree().isStandardFolder(currentObj)) { duptargets = popup_menu->addMenu( tr("Duplicate ...") ); movetargets = popup_menu->addMenu( tr("Move ...") ); connect ( duptargets, SIGNAL ( triggered(QAction*) ), this, SLOT( duplicateObj(QAction*) ) ); connect ( movetargets, SIGNAL ( triggered(QAction*) ), this, SLOT( moveObj(QAction*) ) ); /* we add " ... to library ..." submenu to the "Move " menu item only * if user did not select a library, or if they selected several * objects. Method moveObj knows that library should not be moved * into another library. */ bool libSelected = (getCurrentObjectTree()->getNumSelected()==1 && Library::isA(getCurrentObjectTree()->getSelectedObjects().front())); FWObject *cl = getCurrentLib(); vector::iterator i; int N = libs_model->rowCount(); for (int row=0 ; rowindex(row, 0); FWObject *lib = libs_model->getLibrary(idx); if (lib == NULL) continue; if ( lib->getId()==FWObjectDatabase::STANDARD_LIB_ID || lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID || lib->isReadOnly()) continue; dupID = duptargets->addAction( tr("place in library %1").arg( QString::fromUtf8(lib->getName().c_str()))); dupID->setData(row); // can't move to the same library if (lib == cl) continue; // skip current library if (!libSelected) { moveTargetsCounter++; QAction* mact = movetargets->addAction( tr("to library %1").arg( QString::fromUtf8(lib->getName().c_str()))); mact->setData(row); } } } if (Library::isA(currentObj) && currentObj->getParent()->getId()==FWObjectDatabase::DELETED_OBJECTS_ID) { popup_menu->addAction( tr("Undelete"), this, SLOT(undeleteLibrary())); } popup_menu->addSeparator(); QAction *copyID = popup_menu->addAction(tr("Copy"), this, SLOT(copyObj())); QAction *cutID = popup_menu->addAction(tr("Cut"), this, SLOT(cutObj())); QAction *pasteID = popup_menu->addAction(tr("Paste"), this, SLOT(pasteObj())); popup_menu->addSeparator(); QAction * delID = popup_menu->addAction( tr("Delete"), this, SLOT( delObj() ) ); popup_menu->addSeparator(); QList AddObjectActions; if (getCurrentObjectTree()->getNumSelected()==1) { bool addSubfolder = false; if ( (Firewall::isA(currentObj) || Host::isA(currentObj)) && ! currentObj->isReadOnly() ) { AddObjectActions.append( addNewObjectMenuItem(popup_menu, Interface::TYPENAME)); } if ((Firewall::isA(currentObj) || Cluster::isA(currentObj)) && ! currentObj->isReadOnly()) { AddObjectActions.append( addNewObjectMenuItem(popup_menu, Policy::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, NAT::TYPENAME)); } if (Interface::isA(currentObj) && ! currentObj->isReadOnly()) { Interface *iface = Interface::cast(currentObj); FWObject *h = Host::getParentHost(iface); //FWObject *h = iface->getParentHost(); bool supports_advanced_ifaces = false; try { /* * ignore raised exception; this just means that the host_OS * option is undefined for this target (e.g. for a host). */ supports_advanced_ifaces = Resources::getTargetCapabilityBool (h->getStr("host_OS"), "supports_subinterfaces"); } catch (FWException &ex) { } /* * check if this interface can have subinterfaces. Show "Add Interface" * menu item only if host_os has attribute "supports_subinterfaces" * and if parent interface (currentObj) has the type that can have * subinterfaces. Also, cluster interfaces can't have subinterfaces * and only one level of subinterfaces is allowed. */ if (supports_advanced_ifaces && Firewall::isA(currentObj->getParent())) { list subint_types; getSubInterfaceTypes(iface, subint_types); if (subint_types.size()) addNewObjectMenuItem(popup_menu, Interface::TYPENAME); // popup_menu->addAction( // tr("Add Interface"), this, SLOT( newInterface() ) ); } AddObjectActions.append( addNewObjectMenuItem(popup_menu, IPv4::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, IPv6::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, physAddress::TYPENAME)); /* * Add menu item to let user add AttachedNetworks object * to an interface, but only if this object does not exist yet. * * Actions added to AddObjectActions are * enabled and disabled all together based on the decision * made in getMenuState() (argument newMenuItem). But we * should always allow the user to add AttachedNetworks * object to an interface. */ FWObject *att = currentObj->getFirstByType(AttachedNetworks::TYPENAME); if (att == NULL) addNewObjectMenuItem(popup_menu, AttachedNetworks::TYPENAME); // Check if we should add menu item that creates failover // group. if parent is a cluster, allow one vrrp type // FailoverClusterGroup per Interface only FWObject *parent = NULL; parent = currentObj->getParent(); if (parent != NULL && Cluster::isA(parent)) { QAction *failover_menu_id = addNewObjectMenuItem( popup_menu, FailoverClusterGroup::TYPENAME); // QAction *failover_menu_id = popup_menu->addAction( // tr("Add Failover Group"), this, // SLOT( newFailoverClusterGroup() ) ); failover_menu_id->setEnabled( currentObj->getFirstByType( FailoverClusterGroup::TYPENAME) == NULL); } } if (Cluster::isA(currentObj) && ! currentObj->isReadOnly()) { AddObjectActions.append( addNewObjectMenuItem( popup_menu, Interface::TYPENAME, "Add cluster interface")); // allow multiple state syncing groups per cluster // Rationale: these groups may represent different state syncing // protocols that can synchronize different things. AddObjectActions.append( addNewObjectMenuItem( popup_menu, StateSyncClusterGroup::TYPENAME)); } if (currentObj->getPath(true)=="Firewalls") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, Firewall::TYPENAME)); } if (currentObj->getPath(true)=="Clusters") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, Cluster::TYPENAME)); } if (currentObj->getPath(true)=="Objects/Addresses") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, IPv4::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, IPv6::TYPENAME)); } if (currentObj->getPath(true)=="Objects/DNS Names") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, DNSName::TYPENAME)); } if (currentObj->getPath(true)=="Objects/Address Tables") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, AddressTable::TYPENAME)); } if (currentObj->getPath(true)=="Objects/Address Ranges") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, AddressRange::TYPENAME)); } if (currentObj->getPath(true)=="Objects/Hosts") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, Host::TYPENAME)); } if (currentObj->getPath(true)=="Objects/Networks") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, Network::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, NetworkIPv6::TYPENAME)); } if (currentObj->getPath(true)=="Objects/Groups") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, ObjectGroup::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, DynamicGroup::TYPENAME)); } if (currentObj->getPath(true)=="Services/Custom") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, CustomService::TYPENAME)); } if (currentObj->getPath(true)=="Services/IP") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, IPService::TYPENAME)); } if (currentObj->getPath(true)=="Services/ICMP") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, ICMPService::TYPENAME)); AddObjectActions.append( addNewObjectMenuItem(popup_menu, ICMP6Service::TYPENAME)); } if (currentObj->getPath(true)=="Services/TCP") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, TCPService::TYPENAME)); } if (currentObj->getPath(true)=="Services/UDP") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, UDPService::TYPENAME)); } if (currentObj->getPath(true)=="Services/TagServices") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, TagService::TYPENAME)); } if (currentObj->getPath(true)=="Services/Groups") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, ServiceGroup::TYPENAME)); } if (currentObj->getPath(true)=="Services/Users") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, UserService::TYPENAME)); } if (currentObj->getPath(true)=="Time") { addSubfolder = true; AddObjectActions.append( addNewObjectMenuItem(popup_menu, Interval::TYPENAME)); } if (addSubfolder) { QAction *action = popup_menu->addAction(QIcon(":/Icons/SystemGroup/icon-tree"), tr("New Subfolder"), this, SLOT(addSubfolderSlot())); action->setData(currentObj->getId()); AddObjectActions.append(action); } popup_menu->addSeparator(); QAction *findID = popup_menu->addAction( tr("Find"), this, SLOT( findObject())); QAction *whereUsedID = popup_menu->addAction( tr("Where used"), this, SLOT( findWhereUsedSlot())); findID->setEnabled( !FWBTree().isStandardFolder(currentObj)); whereUsedID->setEnabled( !FWBTree().isStandardFolder(currentObj)); } popup_menu->addSeparator(); popup_menu->addAction( tr("Group"), this, SLOT( groupObjects() ) ) ->setDisabled(getCurrentObjectTree()->getNumSelected()==1); addKeywordsMenu(this, popup_menu); if (Firewall::cast(currentObj)!=NULL || (ObjectGroup::cast(currentObj)!=NULL && currentObj->getName()=="Firewalls")) { bool canCreateCluster = true; if (getCurrentObjectTree()->getNumSelected() > 1) { foreach( FWObject *obj, getCurrentObjectTree()->getSelectedObjects()) { if (!Firewall::isA(obj)) { canCreateCluster = false; break; } } } else canCreateCluster = false; popup_menu->addAction( tr("New cluster from selected firewalls"), this, SLOT( newClusterFromSelected() ) )->setEnabled(canCreateCluster); popup_menu->addSeparator(); popup_menu->addAction( tr("Compile"), this, SLOT( compile())); popup_menu->addAction( tr("Install"), this, SLOT( install())); popup_menu->addAction( tr("Inspect"), this, SLOT( inspect())); } if (Interface::cast(currentObj)!=NULL) { popup_menu->addSeparator(); FWObject *h = Host::getParentHost(currentObj); list top_level_interfaces = h->getByType(Interface::TYPENAME); top_level_interfaces.sort(FWObjectNameCmpPredicate()); addSubinterfaceSubmenu(popup_menu, top_level_interfaces); } popup_menu->addSeparator(); QAction* lckID = popup_menu->addAction(tr("Lock"), this, SLOT(lockObject())); QAction* unlckID = popup_menu->addAction(tr("Unlock"), this, SLOT(unlockObject())); lckID->setEnabled(isCurrentObjectLockable()); unlckID->setEnabled(isCurrentObjectUnlockable()); if (fwbdebug) { /* keep this for debugging */ popup_menu->addSeparator(); popup_menu->addAction( tr("dump"), this, SLOT( dumpObj())); } if (getCurrentObjectTree()->getNumSelected()==1) { edtID->setEnabled( !FWBTree().isStandardFolder(currentObj)); } else edtID->setEnabled(false); bool dupMenuItem = true; bool moveMenuItem = true; bool copyMenuItem = true; bool pasteMenuItem = true; bool delMenuItem = true; bool newMenuItem = true; bool inDeletedObjects = false; getMenuState( (moveTargetsCounter>0), dupMenuItem, moveMenuItem, copyMenuItem, pasteMenuItem, delMenuItem, newMenuItem, inDeletedObjects); if (dupID) dupID->setEnabled(dupMenuItem); copyID->setEnabled(copyMenuItem); pasteID->setEnabled(pasteMenuItem); cutID->setEnabled(delMenuItem); delID->setEnabled(delMenuItem); // can not move object if can not delete it if (movetargets) movetargets->setEnabled(delMenuItem); QList::iterator iter; for (iter=AddObjectActions.begin(); iter!=AddObjectActions.end(); iter++) (*iter)->setEnabled(newMenuItem); // if (inDeletedObjects) movID->setText( tr("Undelete...") ); popup_menu->exec(QCursor::pos()); } /* * Add menu item "Make subinterface of ..." and submenu with list of * top level interfaces. */ void ObjectManipulator::addSubinterfaceSubmenu( QMenu *menu, const list &top_level_interfaces) { QMenu *submenu = menu->addMenu( tr("Make subinterface of...")); int submenu_items_counter = 0; list::const_iterator it; for (it=top_level_interfaces.begin(); it!=top_level_interfaces.end(); ++it) { Interface *intf = Interface::cast(*it); bool skip_interface = false; foreach(FWObject *obj, getCurrentObjectTree()->getSelectedObjects()) { if (obj == intf) { skip_interface = true; break; } if (!intf->validateChild(obj)) { skip_interface = true; break; } } if (skip_interface) continue; if (intf->isLoopback()) continue; // can not add interfaces to a read-only parent interface if (intf->isReadOnly()) continue; QString itf_name = QString::fromUtf8(intf->getName().c_str()); FWObject *parent_fw = Host::getParentHost(intf); std::auto_ptr int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( parent_fw)); if (int_prop->looksLikeVlanInterface(itf_name)) continue; QAction *a = submenu->addAction( QIcon(":/Icons/Interface/icon-tree"), itf_name); a->setData(intf->getId()); connect( submenu, SIGNAL(triggered(QAction*)), this, SLOT(makeSubinterface(QAction*))); submenu_items_counter++; } submenu->setEnabled(submenu_items_counter != 0); } bool ObjectManipulator::getDeleteMenuState(FWObject *obj) { if (obj->isReadOnly()) return false; QString objPath = obj->getPath(true).c_str(); bool del_menu_item_state = FWBTree().getDeleteMenuState(objPath); // can't delete last policy, nat and routing child objects // also can't delete "top" policy ruleset if (del_menu_item_state && RuleSet::cast(obj)) { Firewall *fw = Firewall::cast(obj->getParent()); // fw can be NULL if this ruleset is in the Deleted objects // library if (fw==NULL) return del_menu_item_state; list child_objects = fw->getByType(obj->getTypeName()); if (child_objects.size()==1) del_menu_item_state = false; } return del_menu_item_state; } void ObjectManipulator::getMenuState(bool haveMoveTargets, bool &dupMenuItem, bool &moveMenuItem, bool ©MenuItem, bool &pasteMenuItem, bool &delMenuItem, bool &newMenuItem, bool &inDeletedObjects) { inDeletedObjects = false; if (m_project->db() == NULL) { dupMenuItem = false; moveMenuItem = false; copyMenuItem = false; pasteMenuItem = false; delMenuItem = false; newMenuItem = false; return; } dupMenuItem = true; moveMenuItem = true; copyMenuItem = true; pasteMenuItem = true; delMenuItem = true; newMenuItem = true; FWObject *del_obj_library = m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID); FWObject *current_library = getCurrentLib(); if (getCurrentObjectTree()==NULL) return; // delete, cut and copy menu items will be enabled only if all // selected objects have the same parent (so user can not select // an interface and one but not all of its addresses for deletion, // see #1676) FWObject *parent = NULL; vector so = getCurrentObjectTree()->getSelectedObjects(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { FWObject *obj= *i; QString object_path = obj->getPath(true).c_str(); if (parent == NULL) parent = obj->getParent(); else { if (parent != obj->getParent()) { delMenuItem = false; copyMenuItem = false; } } if (AttachedNetworks::isA(obj)) { dupMenuItem = false; moveMenuItem = false; copyMenuItem = false; pasteMenuItem = false; newMenuItem = false; continue; } copyMenuItem = copyMenuItem && FWBTree().getCopyMenuState(object_path); pasteMenuItem = pasteMenuItem && FWBTree().getPasteMenuState(object_path) && FWObjectClipboard::obj_clipboard && (FWObjectClipboard::obj_clipboard->size()!=0); delMenuItem = delMenuItem && getDeleteMenuState(obj); delMenuItem = delMenuItem && current_library != NULL && current_library->getId() != FWObjectDatabase::STANDARD_LIB_ID; #if DISABLE_PASTE_MENU_ITEM_IF_PASTE_IS_ILLEGAL if (pasteMenuItem) { /* * We used to enable Paste menu item only if object can be * pasted. The problem with this is that there was no * indication why Paste operation was not allowed. Since * we call validateForPaste during actual Paste operation * anyway, it is more user friendly to let them try and * actually see the error if it fails. */ vector >::iterator i; for (i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i) { FWObject *co= m_project->db()->findInIndex(i->first); if (co==NULL) { continue ; //QString s2 = obj->getTypeName().c_str(); } QString s3 = obj->getTypeName().c_str(); QString err; bool validated = FWBTree().validateForInsertion(obj, co, err); pasteMenuItem = pasteMenuItem && validated; } } #endif dupMenuItem= (dupMenuItem && ! FWBTree().isStandardFolder(obj) && ! Library::isA(obj) ); inDeletedObjects = (del_obj_library!=NULL && obj->isChildOf(del_obj_library)); dupMenuItem = dupMenuItem && !inDeletedObjects; // can't move system objects or libraries moveMenuItem = moveMenuItem && ! FWBTree().isStandardFolder(obj) && ! Library::isA(obj); // can't move interfaces unless parent host object is also selected if ( Interface::isA(obj) && std::find(so.begin(),so.end(),obj->getParent())==so.end()) moveMenuItem = false; // can't move ip addresses if parent is interface if (IPv4::isA(obj) && IPv6::isA(obj) && Interface::isA(obj->getParent())) moveMenuItem = false; // can't move physAddress objects moveMenuItem = moveMenuItem && ! physAddress::isA(obj); // can't move read-only objects moveMenuItem = moveMenuItem && ! obj->isReadOnly(); // can't move libraries unless in deleted objects if (Library::isA(obj) && ! inDeletedObjects) moveMenuItem = false; // can't move if there is only one user-defined library in the tree // but we dont care about number of libraries if this will become // 'undelete' operation if (!haveMoveTargets && ! inDeletedObjects) moveMenuItem = false; newMenuItem= (newMenuItem && ! obj->isReadOnly() ); Interface *intf = Interface::cast(obj); if (intf && (intf->isDyn() || intf->isUnnumbered() || intf->isBridgePort()) ) newMenuItem = false; } } bool ObjectManipulator::isCurrentObjectLockable() { FWObject *currentObj = getSelectedObject(); return (currentObj && !currentObj->getParent()->isReadOnly() && !currentObj->getRO()); } bool ObjectManipulator::isCurrentObjectUnlockable() { FWObject *currentObj = getSelectedObject(); return (currentObj && !currentObj->getParent()->isReadOnly() && currentObj->getRO()); } void ObjectManipulator::filterFirewallsFromSelection(vector &so, set &fo) { Firewall *fw; ObjectGroup *gr; Cluster *cl; for (vector::iterator i=so.begin(); i!=so.end(); ++i) { cl = Cluster::cast(*i); if (cl != NULL) { list members; cl->getMembersList(members); // display warning if no firewalls could be extracted for a cluster if (members.size() == 0) { QMessageBox::warning(this, "Firewall Builder", QObject::tr("No firewalls assigned to cluster '%1'"). arg(cl->getName().c_str()), "&Continue", QString::null, QString::null, 0, 1 ); continue; } fo.insert(cl); continue; } fw = Firewall::cast(*i); if (fw!=NULL) { fo.insert(fw); continue; } gr = ObjectGroup::cast(*i); if (gr!=NULL) { extractFirewallsFromGroup(gr,fo); } } } void ObjectManipulator::extractFirewallsFromGroup(ObjectGroup *gr, set &fo) { set oset; m_project->db()->findObjectsInGroup(gr, oset); set::iterator i; for(i=oset.begin();i!=oset.end();++i) if (Firewall::cast(*i)) fo.insert(Firewall::cast(*i)); } FWObject* ObjectManipulator::prepareForInsertion(FWObject *target, FWObject *obj) { if (fwbdebug) qDebug("prepareForInsertion %s --> %s", obj->getName().c_str(), target->getName().c_str()); FWObject *ta = target; if (IPv4::isA(ta) || IPv6::isA(ta)) ta = ta->getParent(); if (Library::isA(target)) ta = FWBTree().getStandardSlotForObject(target, obj->getTypeName().c_str()); QString err; if (! FWBTree().validateForInsertion(ta, obj, err)) { QMessageBox::critical( this,"Firewall Builder", err, "&Continue", QString::null, QString::null, 0, 1 ); return NULL; } return ta; } void ObjectManipulator::editSelectedObject() { if (fwbdebug) qDebug("ObjectManipulator::editSelectedObject"); ObjectTreeView *objTreeView = getCurrentObjectTree(); if (objTreeView == NULL) return; if (objTreeView->getNumSelected()==0) return; FWObject *obj = getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; // do not edit system folders (#1729) if (FWBTree().isSystem(obj)) return; if (RuleSet::cast(obj)!=NULL) { // Open rule set object in the editor if it is already opened // in RuleSetView. If we just opened it in RuleSetView, check // if the editor is visible and if yes, open the object in the // editor right away. See #1331 if (m_project->getCurrentRuleSet() == obj) { QCoreApplication::postEvent( mw, new openObjectInEditorEvent( m_project->getFileName(), obj->getId())); } else { QCoreApplication::postEvent( m_project, new openRulesetEvent( m_project->getFileName(), obj->getId())); if (mw->isEditorVisible()) QCoreApplication::postEvent( mw, new openObjectInEditorEvent( m_project->getFileName(), obj->getId())); } } else QCoreApplication::postEvent( mw, new openObjectInEditorEvent( m_project->getFileName(), obj->getId())); } void ObjectManipulator::openSelectedRuleSet() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj = getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; if (RuleSet::cast(obj)!=NULL && m_project->getCurrentRuleSet()!=obj) QCoreApplication::postEvent( m_project, new openRulesetEvent(m_project->getFileName(), obj->getId())); } bool ObjectManipulator::editObject(FWObject *obj) { if (fwbdebug) qDebug("ObjectManipulator::editObject"); if (!mw->isEditorVisible()) mw->showEditor(); return switchObjectInEditor(obj); } bool ObjectManipulator::switchObjectInEditor(FWObject *obj) { if (fwbdebug) qDebug("ObjectManipulator::switchObjectInEditor"); if (obj && fwbdebug) { qDebug("obj: %s", obj->getName().c_str()); FWObject *edt_obj = mw->getOpenedEditor(); if (edt_obj) qDebug("in editor: %s", edt_obj->getName().c_str()); } if (RuleSet::cast(obj)!=NULL) { if (obj!=m_project->getCurrentRuleSet()) { m_project->openRuleSet(obj); } } if (!mw->isEditorVisible()) return false; if (!mw->requestEditorOwnership(this, obj, ObjectEditor::optNone, true)) { if (fwbdebug) qDebug("Can not get editor panel ownership"); return false; } if (fwbdebug) qDebug("Open object in editor"); mw->openEditor(obj); // opens object in the editor //currentObj = obj; active = true; if (fwbdebug) qDebug("ObjectManipulator::switchObjectInEditor done"); return true; // successfully (re)opened obj in the editor } void ObjectManipulator::closeObject() { //currentObj = NULL; if (mw->isEditorVisible()) mw->hideEditor(); } void ObjectManipulator::selectionChanged(QTreeWidgetItem *cur) { if (fwbdebug) qDebug("ObjectManipulator::selectionChanged"); QTreeWidget *qlv = getCurrentObjectTree(); if (qlv==NULL) return; ObjectTreeViewItem* otvi = dynamic_cast(cur); if (otvi==NULL) return; FWObject *obj = otvi->getFWObject(); if (obj==NULL) return; if (fwbdebug) qDebug("ObjectManipulator::selectionChanged obj=%s", obj->getName().c_str()); FWObject *o = obj; //if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); if (history.empty() || otvi != getCurrentHistoryItem() ) { mw->enableBackAction(); addObjectToHistory(otvi, o); } //currentObj = obj; active = true; update(); if (fwbdebug) qDebug("ObjectManipulator::selectionChanged done"); } void ObjectManipulator::openObjectInTree(ObjectTreeViewItem *otvi, bool register_in_history) { openObjectInTree(otvi->getFWObject(), register_in_history); } /* * I could use default value for the parameter register_in_history, * but that caused problems when this method was used as a slot */ void ObjectManipulator::openObjectInTree(QTreeWidgetItem *item) { ObjectTreeViewItem *otvi = dynamic_cast(item); openObjectInTree(otvi, true); } void ObjectManipulator::openObjectInTree(FWObject *obj) { openObjectInTree(obj,true); } /* This method is called from the GroupObjectDialog when user double * clicks on the object in a group, so first we should check if this * object is shown in the tree and if not, find and open it. */ void ObjectManipulator::openObjectInTree(FWObject *obj, bool /*register_in_history*/) { if (fwbdebug) qDebug() << "ObjectManipulator::openObjectInTree" << "obj:" << ((obj)?obj->getName().c_str():"NULL") << "id:" << ((obj)?obj->getId():0); if (obj==NULL) return; openLibForObject(obj); //raise(); FWObject *o=obj; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); ObjectTreeViewItem *otvi = allItems[o]; // this changes selection and thus calls slot slectionChanged showObjectInTree(otvi); if (fwbdebug) qDebug() << "ObjectManipulator::openObjectInTree" << "libs->currentIndex=" << m_objectManipulator->libs->currentIndex(); updateCreateObjectMenu(obj->getLibrary()); if (fwbdebug) qDebug() << "ObjectManipulator::openObjectInTree: done"; } void ObjectManipulator::openLibForObject(FWObject *obj) { // if obj is Library, its getLibrary() method returns itself. If // this library has been deleted and is now in the Deleted Objects // library, getIdxForLib() is not going to find it. if (FWObjectDatabase::isA(obj->getParent())) m_objectManipulator->libs->setCurrentIndex( libs_model->getIdxForLib(obj->getLibrary()).row()); else { FWObject *parent = obj->getParent(); FWObject *lib = parent->getLibrary(); // see #2648 if a library was deleted with all of its // contents, then it is possible that variable lib may point // to such deleted library, which is located inside of the // "Deleted Objects" library. if (lib->getParent()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) lib = m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID); m_objectManipulator->libs->setCurrentIndex( libs_model->getIdxForLib(lib).row()); } } void ObjectManipulator::showObjectInTree(ObjectTreeViewItem *otvi) { if (fwbdebug) qDebug("ObjectManipulator::showObjectInTree"); if (otvi==NULL) return; ObjectTreeView* otv = otvi->getTree(); if (fwbdebug) qDebug() << "ObjectManipulator::showObjectInTree" << "current_tree_view=" << current_tree_view << "new_otv=" << otv; // otv->raise(); m_objectManipulator->widgetStack->setCurrentWidget(otv); otvi->getTree()->clearSelection(); otvi->getTree()->scrollToItem(otvi); otvi->getTree()->setCurrentItem(otvi); otvi->setSelected(true); // otvi->getTree()->setFocus(Qt::OtherFocusReason); } void ObjectManipulator::libChangedById(int obj_id) { for (int i=0; irowCount(); ++i) { QModelIndex idx = libs_model->index(i, 0); FWObject *l = libs_model->getLibrary(idx); if (l == NULL) continue; if (l->getId() == obj_id) { libChanged(i); m_objectManipulator->libs->setCurrentIndex(i); return; } } } FWObject* ObjectManipulator::getNextUserLib(FWObject *after_this) { QString sid2 = "syslib000"; QString sid3 = "syslib001"; FWObject *lib = NULL; if (after_this != NULL) lib = after_this->getLibrary(); for (int i=0; irowCount(); ++i) { QModelIndex idx = libs_model->index(i, 0); FWObject *l = libs_model->getLibrary(idx); if (l == NULL) continue; if (l == lib) continue; QString sid1 = FWObjectDatabase::getStringId(l->getId()).c_str(); if ( sid1 == sid2 || sid1 == sid3) continue; return l; } return NULL; } void ObjectManipulator::libChanged(int list_row) { if (fwbdebug) qDebug() << "ObjectManipulator::libChanged list_row=" << list_row; previous_lib_index = list_row; QTreeWidget *objTreeView = libs_model->getTreeWidget(list_row); if (objTreeView == NULL) { if (fwbdebug) { qDebug() << "There is no object tree widget associated with this row"; qDebug() << "Scanning all rows:"; for (int i=0; irowCount(); ++i) { qDebug() << "Row" << i; QTreeWidget *objTreeView = libs_model->getTreeWidget(i); FWObject *lib = libs_model->getLibrary(i); qDebug() << "lib=" << lib << "objTreeView=" << objTreeView; } } return; } ObjectTreeViewItem *otvi = dynamic_cast(objTreeView->currentItem()); if (otvi == NULL) { if (objTreeView->invisibleRootItem()->childCount() > 0) otvi = dynamic_cast( objTreeView->invisibleRootItem()->child(0)); else assert(FALSE); } showObjectInTree( otvi ); QCoreApplication::postEvent(mw, new updateGUIStateEvent()); return; } void ObjectManipulator::updateCreateObjectMenu(FWObject* lib) { bool f = ( lib == NULL || lib->getId()==FWObjectDatabase::TEMPLATE_LIB_ID || lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID || lib->isReadOnly() ); bool new_object_op_possible = !f; emit libraryAccessChanged(new_object_op_possible); // m_objectManipulator->newButton->setEnabled(new_object_op_possible); QAction *noa = (QAction*)(mw->findChild("newObjectAction")); noa->setEnabled(new_object_op_possible); } FWObject* ObjectManipulator::getCurrentLib() { int idx = m_objectManipulator->libs->currentIndex(); if (idx == -1 ) return NULL; FWObject *lib = libs_model->getLibrary(idx); return lib; } ObjectTreeView* ObjectManipulator::getCurrentObjectTree() { return libs_model->getTreeWidget(m_objectManipulator->libs->currentIndex()); // return current_tree_view; } void ObjectManipulator::openLib(FWObject *obj) { openObjectInTree(obj->getLibrary(), false); } void ObjectManipulator::newObject() { // m_objectManipulator->newButton->showMenu(); buildNewObjectMenu(); } void ObjectManipulator::select() { FWObject *currentObj = getSelectedObject(); if (fwbdebug) qDebug() << "ObjectManipulator::select()" << "currentObj=" << currentObj << ((currentObj)?currentObj->getName().c_str():" [unknown] "); if (currentObj==NULL) return; m_objectManipulator->libs->setCurrentIndex( libs_model->getIdxForLib(currentObj->getLibrary()).row()); // TODO: I forget why do we need flag "active", check this. ObjectTreeViewItem *otvi = allItems[currentObj]; if (otvi) { active = true; } if (fwbdebug) qDebug("ObjectManipulator::select() done"); } void ObjectManipulator::unselect() { FWObject *currentObj = getSelectedObject(); if (currentObj==NULL) return; for (int i=0; irowCount(); ++i) { QTreeWidget *otv = libs_model->getTreeWidget(i); if (otv == NULL) continue; otv->clearSelection(); } active=false; } list ObjectManipulator::findClustersUsingFirewall(FWObject *fw) { list res; list all_clusters; findAllClusters(all_clusters); list::iterator it; for (it=all_clusters.begin(); it!=all_clusters.end(); ++it) { Cluster *cl = *it; list members; cl->getMembersList(members); if (std::find(members.begin(), members.end(), Firewall::cast(fw)) != members.end()) res.push_back(cl); } return res; } void ObjectManipulator::findAllFirewalls(list &fws) { if (fwbdebug) qDebug("ObjectManipulator::findAllFirewalls"); list fwlist; findByObjectType(m_project->db(), Firewall::TYPENAME, fwlist); for (list::iterator m=fwlist.begin(); m!=fwlist.end(); m++) fws.push_back(Firewall::cast(*m)); } void ObjectManipulator::findAllClusters(list &clusters) { list cllist; findByObjectType(m_project->db(), Cluster::TYPENAME, cllist); for (list::iterator m=cllist.begin(); m!=cllist.end(); m++) clusters.push_back(Cluster::cast(*m)); } void ObjectManipulator::simulateInstall() { if (fwbdebug) qDebug("ObjectManipulator::simulateInstall"); if (getCurrentObjectTree()->getNumSelected()==0) return; Firewall *fw; vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { fw= Firewall::cast( *i ); if (fw!=NULL) { fw->updateLastCompiledTimestamp(); fw->updateLastInstalledTimestamp(); } } } FWObject* ObjectManipulator::getSelectedObject() { QTreeWidgetItem *cur = getCurrentObjectTree()->currentItem(); if (cur) { ObjectTreeViewItem* otvi = dynamic_cast(cur); return otvi->getFWObject(); } return NULL; } void ObjectManipulator::reopenCurrentItemParent() { QTreeWidgetItem *itm = getCurrentObjectTree()->currentItem(); if (itm) itm = itm->parent(); if (!itm) return; itm->parent()->setExpanded(false); itm->parent()->setExpanded(true); getCurrentObjectTree()->scrollToItem(itm, QAbstractItemView::EnsureVisible); getCurrentObjectTree()->update(); } void ObjectManipulator::loadSectionSizes() { for (int i=0; irowCount(); ++i) { QTreeWidget *objTreeView = libs_model->getTreeWidget(i); FWObject *lib = libs_model->getLibrary(i); if (lib == NULL || objTreeView == NULL) continue; objTreeView->header()->resizeSection( 0, st->getTreeSectionSize( m_project->getFileName(), lib->getName().c_str(), 0)); objTreeView->header()->resizeSection( 1, st->getTreeSectionSize( m_project->getFileName(), lib->getName().c_str(), 1)); } } void ObjectManipulator::saveSectionSizes() { for (int i=0; irowCount(); ++i) { QTreeWidget *objTreeView = libs_model->getTreeWidget(i); FWObject *lib = libs_model->getLibrary(i); if (lib == NULL || objTreeView == NULL) continue; st->setTreeSectionSize( m_project->getFileName(), lib->getName().c_str(), 0, objTreeView->header()->sectionSize(0)); st->setTreeSectionSize( m_project->getFileName(), lib->getName().c_str(), 1, objTreeView->header()->sectionSize(1)); } } void ObjectManipulator::loadExpandedTreeItems() { if (fwbdebug) qDebug() << "ObjectManipulator::loadExpandedTreeItems()"; for (int i=0; irowCount(); ++i) { if (fwbdebug) qDebug() << "i=" << i; ObjectTreeView *objTreeView = libs_model->getTreeWidget(i); FWObject *lib = libs_model->getLibrary(i); if (lib == NULL || objTreeView == NULL) continue; set expanded_objects; st->getExpandedObjectIds(m_project->getFileName(), lib->getName().c_str(), expanded_objects); objTreeView->ExpandTreeItems(expanded_objects); // there is no need to resize columns because call to //loadExpandedTreeItems is usually followed by the call to loadSectionSizes //objTreeView->header()->resizeSections(QHeaderView::ResizeToContents); } } void ObjectManipulator::saveExpandedTreeItems() { for (int i=0; irowCount(); ++i) { ObjectTreeView *objTreeView = libs_model->getTreeWidget(i); FWObject *lib = libs_model->getLibrary(i); if (lib == NULL || objTreeView == NULL) continue; st->setExpandedObjectIds(m_project->getFileName(), lib->getName().c_str(), objTreeView->getListOfExpandedObjectIds()); } } void ObjectManipulator::setAttributesColumnEnabled(bool) { for (int i=0; irowCount(); ++i) { ObjectTreeView *objTreeView = libs_model->getTreeWidget(i); if (objTreeView == NULL) continue; objTreeView->showOrHideAttributesColumn(); } } void ObjectManipulator::findWhereUsedRecursively(FWObject *obj, FWObject *top, set &resset) { UsageResolver().findWhereUsedRecursively(obj, top, resset, this->m_project->db()); } list ObjectManipulator::findFirewallsForObject(FWObject *o) { return UsageResolver().findFirewallsForObject(o, this->m_project->db()); } fwbuilder-5.1.0.3599/src/libgui/ssh_wrappers.cpp0000644000175000017500000002527011733011756022272 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "../../config.h" #ifndef _WIN32 #include #include #include #include "FWBSettings.h" #include #include #include #include #include #ifdef HAVE_SIGNAL_H #include #endif #ifdef HAVE_PTY_H #include #endif #ifdef HAVE_LIBUTIL_H #include #endif #ifdef HAVE_UTIL_H #include #endif #include #include #include using namespace std; extern FWBSettings *st; extern int fwbdebug; static struct termios save_termios; static int ttysavefd = -1; static pid_t pid = 0; #ifndef HAVE_CFMAKERAW static inline void cfmakeraw(struct termios *termios_p) { termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); termios_p->c_oflag &= ~OPOST; termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); termios_p->c_cflag &= ~(CSIZE|PARENB); termios_p->c_cflag |= CS8; } #endif #ifndef HAVE_FORKPTY #include #include #include //#include #include /* fork_pty() remplacement for Solaris. * ignore the last two arguments * for the moment */ int forkpty (int *amaster, char *name, void *unused1, void *unused2) { int master, slave; char *slave_name; pid_t pid; master = open("/dev/ptmx", O_RDWR); if (master < 0) return -1; if (grantpt (master) < 0) { close (master); return -1; } if (unlockpt (master) < 0) { close (master); return -1; } slave_name = ptsname (master); if (slave_name == NULL) { close (master); return -1; } slave = open (slave_name, O_RDWR); if (slave < 0) { close (master); return -1; } if (ioctl (slave, I_PUSH, "ptem") < 0 || ioctl (slave, I_PUSH, "ldterm") < 0) { close (slave); close (master); return -1; } if (amaster) *amaster = master; if (name) strcpy (name, slave_name); pid = fork (); switch (pid) { case -1: /* Error */ return -1; case 0: /* Child */ close (master); dup2 (slave, STDIN_FILENO); dup2 (slave, STDOUT_FILENO); dup2 (slave, STDERR_FILENO); return 0; default: /* Parent */ close (slave); return pid; } return -1; } #endif int tty_raw(int fd) { struct termios buf; if (tcgetattr(fd, &save_termios) < 0) { qDebug("Can not switch terminal to raw mode, tcgetattr error '%s'",strerror(errno)); exit(1); } buf = save_termios; cfmakeraw(&buf); // this used to use TCSAFLUSH, but that caused stall which I did not // completely understand. Apparently there was some data in the output // buffer at the moment when we try to switch tty to raw mode, but I // could not figure out where this data comes from and why it could // not be written to the tty. Anyway, this caused semi-random stalls // in the installer because whenever it called fwbuilder -X, the child // process would block in this place and stall installer. I had to // switch to TCSANOW to fix. if (tcsetattr(fd, TCSANOW, &buf) < 0) { qDebug("Can not switch terminal to raw mode, tcsetattr error '%s'",strerror(errno)); exit(1); } ttysavefd = fd; return 0; } int echo_off(int fd) { struct stat statbuf; if (fstat(fd,&statbuf)!=0) return 0; struct termios stermios; if (tcgetattr(fd, &stermios)<0) { qDebug("Can not turn terminal echo off, tcgetattr error '%s'",strerror(errno)); exit(1); } stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); stermios.c_oflag &= ~(ONLCR); if (tcsetattr(fd, TCSANOW, &stermios)<0) { qDebug("Can not turn terminal echo off, tcsetattr error '%s'",strerror(errno)); exit(1); } return 0; } ssize_t writen(int fd,const void *vptr, size_t n) { size_t nleft; ssize_t nwritten; const char *ptr; ptr = (const char*)(vptr); nleft = n; if (fwbdebug) qDebug("need to write %d bytes",int(nleft)); while (nleft > 0) { if ( (nwritten = write(fd,ptr,nleft )) <= 0) return nwritten; if (fwbdebug) qDebug("%d bytes written",int(nwritten)); nleft -= nwritten; ptr += nwritten; } return n; } #ifndef strndup char* strndup(const char* s,int n) { char *tbuf = (char*)malloc(n); if (tbuf) memcpy(tbuf,s,n); return tbuf; } #endif void catch_sign(int sig) { if (fwbdebug) { cerr << "Wrapper caight signal " << sig << endl; cerr << "Child process pid " << pid << endl; } if (pid != 0) { int stat; kill(pid, SIGTERM); int timeout = 0; pid_t cp = 0; while ( (cp = waitpid(pid, &stat, WNOHANG)) == 0 && timeout < 10) { if (fwbdebug) cerr << "Waiting for pid " << pid << " to finish" << endl; sleep(1); timeout++; } if (cp == 0) { if (fwbdebug) cerr << "Timeout, child process is still running. Killing it." << endl; kill(pid, SIGKILL); } } exit(1); } void ssh_wrapper( int argc, char *argv[] ) { bool ssh_wrapper = false; bool scp_wrapper = false; const char *arg[128]; int i; QStringList new_args; for (i = 1 ; i $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INSTOPTIONSDIALOG_H_ #define __INSTOPTIONSDIALOG_H_ #include "config.h" #include class instConf; class instOptionsDialog : public QDialog { Q_OBJECT; private: int delta_y; instConf *cnf; public: instOptionsDialog(QWidget *parent, instConf *_cnf, bool installing_many_firewalls = true); ~instOptionsDialog(); void savePassword(); QString getUName(); QString getPWD(); QString getEPWD(); Ui::instOptionsDialog_q *m_dialog; public slots: void cancelAll(); void batchInstallStateChange(); }; #endif fwbuilder-5.1.0.3599/src/libgui/iosAdvancedDialog.cpp0000644000175000017500000000506611733011756023113 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "iosAdvancedDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; iosAdvancedDialog::~iosAdvancedDialog() { delete m_dialog; } iosAdvancedDialog::iosAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::iosAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwoptions=(Firewall::cast(obj))->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); /* Page "General" */ data.registerOption( m_dialog->ios_set_host_name , fwoptions, "ios_set_host_name" ); data.registerOption( m_dialog->ios_ip_address , fwoptions, "ios_ip_address" ); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void iosAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void iosAdvancedDialog::reject() { QDialog::reject(); } fwbuilder-5.1.0.3599/src/libgui/SSHProcurve.cpp0000644000175000017500000001217011733011756021730 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "SSHProcurve.h" #include using namespace std; /* * HP "normal" prompt looks something like this: * * ProCurve Switch 3500-24> [ * * Enable password prompt also uses ansi codes: * Password: [?25h[?25h[?25l * * once in enable mode, the prompt looks like this: * * ProCurve Switch 3500-24# ^[[24;1H^[[24;26H^[[24;1H^[[?25h^[[24;26H * * but we clear all ANSI sequences in SSHSession::readFromStdout() */ SSHProcurve::SSHProcurve(QWidget *_par, const QString &_h, const QStringList &args, const QString &_p, const QString &_ep, const std::list &_in) : SSHCisco(_par,_h,args,_p,_ep,_in) { normal_prompt = "> *$"; enable_prompt = "# *$"; // matches config prompt too epwd_prompt = "Password: *$"; hp_greeting_prompt = "Press any key to continue *$"; pwd_prompt_1 = "'s password: $"; pwd_prompt_2 = "Password: "; comment_symbol = ';'; errorsLoggedin.push_back("Unable to verify password"); } SSHProcurve::~SSHProcurve() { } // Procurve state machine needs to be able to deal with // "reload after ... " command void SSHProcurve::stateMachine() { if (checkForErrors()) return; switch (state) { case NONE: /* * Procurve prints a full page greeting right after it accepts user password * and provides prompt "Press any key to continue". Press "any key" to * proceed. */ if (cmpPrompt(stdoutBuffer, QRegExp(hp_greeting_prompt))) { stdoutBuffer=""; proc->write("\n"); break; } else SSHCisco::stateMachine(); break; case SCHEDULE_RELOAD_DIALOG: if ( cmpPrompt(stdoutBuffer, QRegExp("Do you want to save current configuration [y/n]?")) ) { stdoutBuffer=""; proc->write( "no\n" ); break; } if ( cmpPrompt( stdoutBuffer, QRegExp("System will be rebooted at the scheduled time .*Do you want to continue [y/n]? ")) ) { stdoutBuffer=""; proc->write( "y\n" ); state = ENABLE; break; } break; case PUSHING_CONFIG: if ( cmpPrompt(stdoutBuffer, QRegExp("Destination filename [.*]?")) ) { stdoutBuffer=""; proc->write("\n"); // accept default file name } else SSHCisco::stateMachine(); break; case EXIT_FROM_CONFIG: if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) ) { /* * Execute post_config_commands */ if (post_config_commands.size()>0) { stdoutBuffer = ""; QString cmd = post_config_commands.front(); post_config_commands.pop_front(); sendCommand(cmd); break; } stdoutBuffer=""; state = EXIT; // Use command "logout" to log out from enable mode // instead of exit, which exits to normal mode. proc->write( "logout\n"); } break; case EXIT: if ( cmpPrompt(stdoutBuffer,QRegExp("Do you want to log out [y/n]?")) ) { stdoutBuffer=""; proc->write("y\n"); // accept default file name state = FINISH; } break; default: SSHCisco::stateMachine(); break; } } /* * for some reason ssh session to a ProCurve always finishes with * return code 255 */ void SSHProcurve::finished(int retcode) { if (fwbdebug) qDebug("SSHProcurve::processExited proc=%p retcode=%d", proc, retcode); // background process has exited now, we do not need proc object anymore cleanUp(); QString exitStatus = (retcode)?QObject::tr("ERROR"):QObject::tr("OK"); emit printStdout_sign(tr("SSH session terminated, exit status: %1"). arg(retcode) + "\n"); // Consider return code 0 and 255 a success, this is different from SSHSession // sessionComplete(retcode!=0 && retcode!=255); if (fwbdebug) qDebug("SSHProcurve::processExited done"); } fwbuilder-5.1.0.3599/src/libgui/newfirewalldialog_q.ui0000644000175000017500000010424411733011756023423 0ustar sylvestresylvestre newFirewallDialog_q Qt::WindowModal 0 0 650 590 650 590 Creating new firewall object :/Icons/Firewall/icon-tree:/Icons/Firewall/icon-tree 0 0 0 25 Sans Serif 14 75 false true TextLabel Qt::AlignCenter 500 450 2 Name of the new firewall object: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Choose firewall software it is running: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Choose OS the new firewall runs on: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 20 QFrame::HLine QFrame::Sunken Qt::Horizontal Use preconfigured firewall templates Firewall Builder comes with a library of standard template firewall objects, however you can compose your own library of templates and use it to create new firewall. true Use standard template objects Use custom template objects Select custom template library file Using template library file: 400 0 Qt::Vertical 20 1 0 Next step is to add interfaces to the new firewall. There are two ways to do it: using SNMP query or manually. Adding them using SNMP query is fast and automatic, but is only possible if firewall runs SNMP agent and you know SNMP community string 'read'. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Qt::Vertical QSizePolicy::Fixed 20 20 10 12 Configure interfaces manually true Use SNMP to discover interfaces of the firewall Qt::Horizontal QSizePolicy::Expanding 40 20 Discover Interfaces using SNMP SNMP 'read' community string: Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 140 20 Qt::Horizontal QSizePolicy::Expanding 40 20 Firewall IP address: 0 0 'Name' corresponds to the name of the physical interface, such as 'eth0', 'fxp0', 'ethernet0' etc. 'Label' is used to mark interface to reflect network topology, e.g. 'outside' or 'inside'. Label is mandatory for PIX firewall. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 Tab 1 9 In order to be able to build firewall policy properly, Firewall Builder needs information about 'security level' of the firewall's interfaces. Interface that connects it to the Internet is considered 'insecure' and has security level '0', while interface connected to the internal network is supposed to be 'secure' (security level '100'). Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Qt::AlignCenter true Qt::AlignCenter true QFrame::NoFrame QFrame::Sunken 0 true true Name Label Address Security Level Firewall Builder uses Network Zones to determine network topology. Each firewall interface must have a Network Zone configured. The Network Zone of an interface represents the set of IP networks that would be the source IP address of traffic arriving inbound on an interface. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true If you do not set the Network Zone now you can update the Network Zone configuration after the firewall has been created by double-clicking on the network interface of the firewall object and then selecting the desired object from the Network Zone dropdown list. true :/Images/network_zone_dialog.png Qt::AlignCenter 0 150 QFrame::NoFrame QFrame::Sunken 0 true true Name Label Address Security Level 0 0 0 250 210 QFrame::StyledPanel QFrame::Sunken 0 0 20 20 QFrame::VLine QFrame::Sunken Qt::Vertical 0 0 16777215 55 QFrame::Panel QFrame::Raised Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff :/Icons/firewall_64.png false false 0 0 20 20 QFrame::HLine QFrame::Sunken Qt::Horizontal 0 0 16777215 55 QFrame::Panel QFrame::Raised Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff 0 0 20 20 QFrame::VLine QFrame::Sunken Qt::Vertical 0 0 16777215 55 QFrame::Panel QFrame::Raised Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff Choose template object in the list and click 'Next' when ready. You can change interface names and their IP addresses on the next page. Template firewall object comes with basic policy and NAT rules that implement policy described in its comment. If you change IP addresses of its interfaces, policy and NAT rules will be automatically corrected to reflect this change. However you should always inspect the rules and adjust them to suite your security policy. Template objects are designed to be a starting point, a way to jump-start your configuration and most likely require changes to be useful in your environment. Qt::AlignVCenter true 200 0 250 16777215 'Name' corresponds to the name of the physical interface, such as 'eth0', 'fxp0', 'ethernet0' etc. 'Label' is used to mark interface to reflect network topology, e.g. 'outside' or 'inside'. Label is mandatory for PIX firewall. true 0 Tab 1 1 0 400 50 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 161 37 < &Back false &Next > true true false &Finish false false &Cancel false InterfacesTabWidget QTabWidget
InterfacesTabWidget.h
1
obj_name platform hostOS useTemplate use_manual snmp_community snmpQuery snmpProgress templateList intfOutsideText intfDMZText intfInsideText templateComment obj_name textChanged(QString) newFirewallDialog_q changed() 99 58 20 20 platform activated(int) newFirewallDialog_q changed() 102 58 20 20 use_snmp toggled(bool) newFirewallDialog_q changed() 70 76 20 20 snmpQuery clicked() newFirewallDialog_q getInterfacesViaSNMP() 102 88 20 20 templateList currentItemChanged(QListWidgetItem*,QListWidgetItem*) newFirewallDialog_q templateSelected(QListWidgetItem*) 32 126 20 20 newFirewallDialog_q rejected() newFirewallDialog_q cleanup() 324 294 324 294 cancelClicked() cleanup()
fwbuilder-5.1.0.3599/src/libgui/ipfwadvanceddialog_q.ui0000644000175000017500000007525511733011756023550 0ustar sylvestresylvestre ipfwAdvancedDialog_q 0 0 818 565 ipfw: advanced settings false 11 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true 0 Compiler Compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 32767 0 0 Command line options for the compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 32767 0 0 Output file name (if left blank, the file name is constructed of the firewall object name and extension ".fw") Qt::AlignVCenter true 32767 32767 Generated script can be copied to the firewall machine under different name. If this field is left blank, the file name does not change. true Script name on the firewall 32767 22 Qt::Vertical QSizePolicy::Fixed 20 20 0 0 Add rule to accept packets matching dynamic rules created for known sessions on top of the policy (action 'check-state') 0 0 Shadowing happens because a rule is a superset of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. Detect rule shadowing in policy 0 0 If the option is deactivated, compiler treats empty groups as an error and aborts processing the policy. If this option is activated, compiler removes all empty groups from all rule elements. If rule element becomes 'any' after the last empty group has been removed, the whole rule will be ignored. Use this option only if you fully understand how it works! Ignore empty groups in rules Always permit ssh access from the management workstation with this address: 0 0 32767 32767 Qt::Horizontal 40 20 If you use the option to automatically add a rule to permit ssh access from the management workstation, another rule will be added to permit reply packets going back to the same address. This is necessary to automatically recreate dynamic ipfw rule for the ssh session used to manage the firewall after all ipfw sets are flushed and loaded with new rules. Use this option to permit ssh access from a trusted machine or a subnet that should be as narrow as possible. true Qt::Vertical QSizePolicy::Expanding 20 40 Installer Built-in installer Directory on the firewall where script should be installed Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 A command that installer should execute on the firewall in order to activate the policy (if this field is blank, installer runs firewall script in the directory specified above; it uses sudo if user name is not 'root') Qt::AlignVCenter true 0 0 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 External install script 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Qt::Vertical QSizePolicy::Expanding 20 20 Prolog/Epilog 6 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 The following commands will be added verbatim after generated configuration Qt::AlignVCenter true 6 Qt::Horizontal QSizePolicy::Expanding 40 20 Edit The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Script Options 6 Qt::Horizontal QSizePolicy::Fixed 40 70 Add virtual addresses for NAT Configure Interfaces of the firewall machine Turn debugging on in generated script These options enable auxiliary sections in the generated shell script. Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 20 230 Qt::Vertical QSizePolicy::Fixed 20 20 IPv6 The order in which ipv4 and ipv6 rules should be generated: Qt::Horizontal 40 20 IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 tabWidget compiler compilerArgs outputFileName ipfw_add_check_state_rule ipfw_check_shadowing ipfw_ignore_empty_groups mgmt_ssh mgmt_addr buttonOk buttonCancel ipfw_fw_dir ipfw_user altAddress activationCmd sshArgs installScript installScriptArgs prolog_script edit_prolog_button epilog_script edit_epilog_button ipfw_debug ipfw_configure_interfaces ipfw_manage_virtual_addr ipv4before_2 buttonOk clicked() ipfwAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() ipfwAdvancedDialog_q reject() 20 20 20 20 edit_epilog_button clicked() ipfwAdvancedDialog_q editEpilog() 20 20 20 20 edit_prolog_button clicked() ipfwAdvancedDialog_q editProlog() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/ipfwAdvancedDialog.h0000644000175000017500000000274711733011756022736 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPFWADVANCEDDIALOG_H_ #define __IPFWADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class ipfwAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::ipfwAdvancedDialog_q *m_dialog; public: ipfwAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~ipfwAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void editProlog(); virtual void editEpilog(); }; #endif // __IPFWADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FWBAboutDialog.cpp0000644000175000017500000000270311733011756022277 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWBAboutDialog.h" #include "fwbuilder/Constants.h" #include "../../VERSION.h" FWBAboutDialog::FWBAboutDialog(QWidget *parent): QDialog(parent) { m_aboutDialog = new Ui::AboutDialog_q; m_aboutDialog->setupUi(this); QString pgm = m_aboutDialog->titleLbl->text(); m_aboutDialog->titleLbl->setText(pgm.arg(GENERATION)); m_aboutDialog->revLbl->setText(VERSION); m_aboutDialog->apiLbl->setText(""); ABOUT_DLG_BLANKS; setWindowTitle(QString("Firewall Builder: About...")); adjustSize(); }; FWBAboutDialog::~FWBAboutDialog() { delete m_aboutDialog; }; fwbuilder-5.1.0.3599/src/libgui/FWBSettings.h0000644000175000017500000002031511733011756021351 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWBSETTINGS_H_ #define __FWBSETTINGS_H_ #include "../../VERSION.h" #include #include #include #include #include #define SETTINGS_PATH_PREFIX "/" GENERATION #include class QWidget; /* * startup actions. I know, enum would be better, but QComboBox * operates with integers and it is much simpler to just store item * numbers in preferences. */ #define LoadStandardObjects 0 #define LoadLastEditedFile 1 class FWBSettings : public QSettings { public: enum LabelColors { RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE, GRAY }; enum IconSize{ SIZE25X25, SIZE16X16}; private: QSettings *uuid_settings; QSettings *ssh_timeout_setings_object; bool first_run; QString getLabelColorStr(enum LabelColors c); public: FWBSettings(bool testData = false); ~FWBSettings(); static QString getApplicationNameForSettings() { return "FirewallBuilder" GENERATION; } void init(bool force_first_time_run=false); void save(); bool isFirstRun() { return first_run; } QString getWDir(); void setWDir(const QString &wd); QString getDataDir(); void setDataDir(const QString &dataDir); QString getOpenFileDir( const QString &existingPath = ""); void setOpenFileDir( const QString &d ); int getInfoStyle(); void setInfoStyle(int s); QString getGroupViewMode(); void setGroupViewMode(const QString &mode); QString getGroupViewColumns(); void setGroupViewColumns(const QString &mode); int getStartupAction(); void setStartupAction(int sa); int getExpandTree(); void setExpandTree(int sa); int getMergeLibs(); void setMergeLibs(int sa); bool getObjTooltips(); void setObjTooltips(bool f); int getTooltipDelay(); void setTooltipDelay(int v); QString getLastEdited(); void setLastEdited(const QString &file); int getInfoWindowHeight(); void setInfoWindowHeight(int h); bool getRCSLogState(); void setRCSLogState(bool f); int getRCSFilePreviewStyle(); void setRCSFilePreviewStyle(int style); int getRCSFilePreviewSortColumn(); void setRCSFilePreviewSortColumn(int col); bool getAutoSave(); void setAutoSave(bool f); bool getCompression(); void setCompression(bool f); bool getDontSaveStdLib(); void setDontSaveStdLib( bool f); bool hasKey(const QString &attribute); QString getStr(const QString &attribute); void setStr(const QString &attribute, const QString &val); bool getBool(const QString &attribute); void setBool(const QString &attribute, bool f ); int getInt(const QString &attribute); void setInt(const QString &attribute, int v ); QStringList getList(const QString &attribute); void setList(const QString &attribute, QStringList &list); bool haveGeometry(QWidget *w); void restoreGeometry(QWidget *w); void restoreGeometry(QWidget *w, const QRect &defaultGeometry); void saveGeometry(QWidget *w); bool haveScreenPosition(const QString &wname); QPoint getScreenPosition(const QString &wname); void saveScreenPosition(const QString &wname, const QPoint &p); QString getLabelColor(enum LabelColors c); void setLabelColor(enum LabelColors c,const QString &s); QString getLabelText(enum LabelColors c); void setLabelText(enum LabelColors c, const QString &s); QString getSSHPath(); void setSSHPath(const QString &path); QString getSCPPath(); void setSCPPath(const QString &path); bool haveSSHTimeout(); int getSSHTimeout(); void setSSHTimeout(int value_sec); void getPrinterOptions(QPrinter *printer,int &pageWidth,int &pageHeight); void setPrinterOptions(QPrinter *printer,int pageWidth,int pageHeight); QString getAppGUID(); bool isReminderAboutStandardLibSuppressed(); void suppressReminderAboutStandardLib(bool f); bool isReminderAboutDataDirSuppressed(); void suppressReminderAboutDataDir(bool f); enum IconSize getIconsInRulesSize(); void setIconsInRulesSize(enum IconSize size); bool getShowIconsInRules(); void setShowIconsInRules(bool showIcons); bool getShowDirectionText(); void setShowDirectionText(bool showText); QFont getRulesFont(); void setRulesFont(const QFont &font); QFont getTreeFont(); void setTreeFont(const QFont &font); QFont getUiFont(); void setUiFont(const QFont &font); QFont getCompilerOutputFont(); void setCompilerOutputFont(const QFont &font); bool getClipComment(); void setClipComment(bool); bool getCheckUpdates(); void setCheckUpdates(bool); uint getTimeOfLastUpdateAvailableWarning(); void setTimeOfLastUpdateAvailableWarning(uint v); uint getTimeOfLastAnnouncement(const QString &announcement); void setTimeOfLastAnnouncement(const QString &announcement, uint v); QString getTargetStatus(const QString &platform, const QString &default_stat); void setTargetStatus(const QString &plaform, const QString &status); QString getCheckUpdatesProxy(); void setCheckUpdatesProxy(const QString &proxy_line); void getExpandedObjectIds(const QString &filename, const QString &lib, std::set &ids); void setExpandedObjectIds(const QString &filename, const QString &lib, const std::set &ids); int getTreeSectionSize(const QString &filename, const QString &lib, int section_index); void setTreeSectionSize(const QString &filename, const QString &lib, int section_index, int size); int getVisibleRuleSetId(const QString &filename, const QString &lib); void setVisibleRuleSet(const QString &filename, const QString &lib, libfwbuilder::FWObject *ruleset); void getCollapsedRuleGroups(const QString &filename, const QString &firewall, const QString &ruleset, QStringList &collapsed_groups); void setCollapsedRuleGroups(const QString &filename, const QString &firewall, const QString &ruleset, const QStringList &collapsed_groups); QStringList getRecentFiles(); void setRecentFiles(QStringList &list); QString getNewFirewallPlatform(); void setNewFirewallPlatform(const QString &platform); QString getNewClusterFailoverProtocol(); void setNewClusterFailoverProtocol(const QString &protocol); bool getShowUndoPanel(); void setShowUndoPanel(bool); bool getIconsWithText(); void setIconsWithText(bool f); int getABTestingGroup(); void setABTestingGroup(int n); int getStartsCounter(); bool isIntroDialogEnabled(); void setIntroDialogEnabled(bool f); bool customTemplatesEnabled(); void setCustomTemplatesEnabled(bool f); private: QFont getFontByType(const char*type); }; #endif fwbuilder-5.1.0.3599/src/libgui/iosaclAdvancedDialog.h0000644000175000017500000000327311733011756023236 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IOSACLADVANCEDDIALOG_H_ #define __IOSACLADVANCEDDIALOG_H_ #include #include "DialogData.h" #include #include class QWidget; class QSpinBox; class QComboBox; class QCheckBox; class QProcess; namespace libfwbuilder { class FWObject; }; class iosaclAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::iosaclAdvancedDialog_q *m_dialog; public: iosaclAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~iosaclAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void editProlog(); virtual void editEpilog(); virtual void scriptACLModeChanged(); virtual void toggleGenerateLogging(); }; #endif // __IOSACLADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/events.h0000644000175000017500000003430611733011756020523 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWBUILDER_EVENTS_HH #define FWBUILDER_EVENTS_HH #include "global.h" #include "ObjectEditor.h" #include "ColDesc.h" #include #include /* Custom event types. QEvent::registerEventType is only available starting QT 4.4 but we have to support QT 4.3 for Ubuntu Hardy so need to allocate types manually for now. Event types are defined as increments above QEvent::User */ enum EVENT_CODES { DATA_MODIFIED_EVENT , UPDATE_OBJECT_IN_TREE_EVENT , UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT , UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT , UPDATE_OBJECT_EVERYWHERE_EVENT , UPDATE_LAST_COMPILED_TIMESTAMP_EVENT , UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT , SHOW_OBJECT_IN_TREE_EVENT , SHOW_OBJECT_IN_RULESET_EVENT , SELECT_RULE_ELEMENT_EVENT, INSERT_OBJECT_IN_TREE_EVENT, REMOVE_OBJECT_FROM_TREE_EVENT, ADD_TREE_PAGE_EVENT, REMOVE_TREE_PAGE_EVENT, RELOAD_OBJECT_TREE_EVENT , RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT , OPEN_RULESET_EVENT , OPEN_RULESET_IMMEDIATELY_EVENT , RELOAD_RULESET_EVENT , RELOAD_RULESET_IMMEDIATELY_EVENT , MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT, OPEN_OBJECT_IN_EDITOR_EVENT , OPEN_OPT_OBJECT_IN_EDITOR_EVENT , CLOSE_OBJECT_EVENT , OBJECT_NAME_CHANGED_EVENT, OPEN_LIBRARY_FOR_OBJECT_EVENT, UPDATE_SUBWINDOW_TITLES_EVENT, UPDATE_GUI_STATE_EVENT, EXPAND_OBJECT_IN_TREE, CLOSE_EDITOR_PANEL_EVENT , CLEAR_EDITOR_PANEL_EVENT , ADD_USER_FOLDER_EVENT, REMOVE_USER_FOLDER_EVENT, MOVE_TOFROM_USER_FOLDER_EVENT, }; class fwbUpdateEvent : public QEvent { QString data_file_name; int object_id; QString event_name; public: fwbUpdateEvent(const QString &file_name, int obj_id, QEvent::Type event_type, const QString &ev_name) : QEvent(event_type), event_name(ev_name) { data_file_name = file_name; object_id = obj_id; } QString getEventName() { return event_name; } QString getFileName() { return data_file_name; } int getObjectId() { return object_id; } }; class dataModifiedEvent : public fwbUpdateEvent { public: dataModifiedEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + DATA_MODIFIED_EVENT), "dataModifiedEvent") {} }; class updateObjectInTreeEvent : public fwbUpdateEvent { public: updateObjectInTreeEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + UPDATE_OBJECT_IN_TREE_EVENT), "updateObjectInTreeEvent") {} }; class updateObjectAndSubtreeInTreeEvent : public fwbUpdateEvent { public: updateObjectAndSubtreeInTreeEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT), "updateObjectAndSubtreeInTreeEvent") {} }; class updateObjectAndSubtreeImmediatelyEvent : public fwbUpdateEvent { public: updateObjectAndSubtreeImmediatelyEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT), "updateObjectAndSubtreeImmediatelyEvent") {} }; class updateObjectEverywhereEvent : public fwbUpdateEvent { public: updateObjectEverywhereEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + UPDATE_OBJECT_EVERYWHERE_EVENT), "updateObjectEverywhereEvent") {} }; class updateLastCompiledTimestampEvent : public fwbUpdateEvent { public: updateLastCompiledTimestampEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + UPDATE_LAST_COMPILED_TIMESTAMP_EVENT), "updateLastCompiledTimestampEvent") {} }; class updateLastInstalledTimestampEvent : public fwbUpdateEvent { public: updateLastInstalledTimestampEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT), "updateLastInstalledTimestampEvent") {} }; class showObjectInTreeEvent : public fwbUpdateEvent { public: showObjectInTreeEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + SHOW_OBJECT_IN_TREE_EVENT), "showObjectInTreeEvent") {} }; class showObjectInRulesetEvent : public fwbUpdateEvent { public: showObjectInRulesetEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + SHOW_OBJECT_IN_RULESET_EVENT), "showObjectInRulesetEvent") {} }; class selectRuleElementEvent : public fwbUpdateEvent { public: ColDesc::ColumnType column_type; selectRuleElementEvent(const QString &file_name, int obj_id, ColDesc::ColumnType ct) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + SELECT_RULE_ELEMENT_EVENT), "selectRuleElementEvent") { column_type = ct; } }; class insertObjectInTreeEvent : public fwbUpdateEvent { public: int parent_id; insertObjectInTreeEvent(const QString &file_name, int p_id, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + INSERT_OBJECT_IN_TREE_EVENT), "insertObjectInTreeEvent") { parent_id = p_id; } }; class removeObjectFromTreeEvent : public fwbUpdateEvent { public: removeObjectFromTreeEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + REMOVE_OBJECT_FROM_TREE_EVENT), "removeObjectFromTreeEvent") {} }; class addTreePageEvent : public fwbUpdateEvent { public: addTreePageEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + ADD_TREE_PAGE_EVENT), "addTreePageEvent") {} }; class removeTreePageEvent : public fwbUpdateEvent { public: removeTreePageEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + REMOVE_TREE_PAGE_EVENT), "removeTreePageEvent") {} }; class reloadObjectTreeEvent : public fwbUpdateEvent { public: reloadObjectTreeEvent(const QString &file_name) : fwbUpdateEvent(file_name, -1, QEvent::Type(QEvent::User + RELOAD_OBJECT_TREE_EVENT), "reloadObjectTreeEvent") {} }; class reloadObjectTreeImmediatelyEvent : public fwbUpdateEvent { public: reloadObjectTreeImmediatelyEvent(const QString &file_name) : fwbUpdateEvent(file_name, -1, QEvent::Type(QEvent::User + RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT), "reloadObjectTreeImmediatelyEvent") {} }; class reloadRulesetEvent : public fwbUpdateEvent { public: reloadRulesetEvent(const QString &file_name) : fwbUpdateEvent(file_name, -1, QEvent::Type(QEvent::User + RELOAD_RULESET_EVENT), "reloadRulesetEvent") {} }; class reloadRulesetImmediatelyEvent : public fwbUpdateEvent { public: reloadRulesetImmediatelyEvent(const QString &file_name) : fwbUpdateEvent(file_name, -1, QEvent::Type(QEvent::User + RELOAD_RULESET_IMMEDIATELY_EVENT), "reloadRulesetImmediatelyEvent") {} }; class makeCurrentRuleVisibleInRulesetEvent : public fwbUpdateEvent { public: makeCurrentRuleVisibleInRulesetEvent(const QString &file_name) : fwbUpdateEvent(file_name, -1, QEvent::Type(QEvent::User + MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT), "makeCurrentRuleVisibleInRulesetEvent") {} }; class openRulesetEvent : public fwbUpdateEvent { public: openRulesetEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + OPEN_RULESET_EVENT), "openRulesetEvent") {} }; class openRulesetImmediatelyEvent : public fwbUpdateEvent { public: openRulesetImmediatelyEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + OPEN_RULESET_IMMEDIATELY_EVENT), "openRulesetImmediatelyEvent") {} }; class openObjectInEditorEvent : public fwbUpdateEvent { public: openObjectInEditorEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + OPEN_OBJECT_IN_EDITOR_EVENT), "openObjectInEditorEvent") {} }; class openOptObjectInEditorEvent : public fwbUpdateEvent { public: ObjectEditor::OptType opt_code; openOptObjectInEditorEvent(const QString &file_name, int obj_id, ObjectEditor::OptType opt) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + OPEN_OPT_OBJECT_IN_EDITOR_EVENT), "openOptObjectInEditorEvent") { opt_code = opt; } }; class closeObjectEvent : public fwbUpdateEvent { public: closeObjectEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + CLOSE_OBJECT_EVENT), "closeObjectEvent") {} }; class objectNameChangedEvent : public fwbUpdateEvent { public: QString old_name; QString new_name; bool rename_children; objectNameChangedEvent(const QString &file_name, int obj_id, const QString &_old_name, const QString &_new_name, bool _rename_children) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + OBJECT_NAME_CHANGED_EVENT), "objectNameChangedEvent") { old_name = _old_name; new_name = _new_name; rename_children = _rename_children; } }; class openLibraryForObjectEvent : public fwbUpdateEvent { public: QString old_name; QString new_name; openLibraryForObjectEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + OPEN_LIBRARY_FOR_OBJECT_EVENT), "openLibraryForObjectEvent") {} }; /* * This event is processed by FWWindow class and updates titles of all * ProjectPanel windows. */ class updateSubWindowTitlesEvent : public fwbUpdateEvent { public: updateSubWindowTitlesEvent() : fwbUpdateEvent("", -1, QEvent::Type(QEvent::User + UPDATE_SUBWINDOW_TITLES_EVENT), "updateSubWindowTitlesEvent") {} }; /* * This event is processed by FWWindow class and updates all menus and * toolbar buttins */ class updateGUIStateEvent : public fwbUpdateEvent { public: updateGUIStateEvent() : fwbUpdateEvent("", -1, QEvent::Type(QEvent::User + UPDATE_GUI_STATE_EVENT), "updateGUIStateEvent") {} }; class expandObjectInTreeEvent : public fwbUpdateEvent { public: int parent_id; expandObjectInTreeEvent(const QString &file_name, int obj_id) : fwbUpdateEvent(file_name, obj_id, QEvent::Type(QEvent::User + EXPAND_OBJECT_IN_TREE), "expandObjectInTreeEvent") {} }; class closeEditorPanelEvent : public fwbUpdateEvent { public: closeEditorPanelEvent() : fwbUpdateEvent("", -1, QEvent::Type(QEvent::User + CLOSE_EDITOR_PANEL_EVENT), "closeEditorPanelEvent") {} }; class clearEditorPanelEvent : public fwbUpdateEvent { public: clearEditorPanelEvent() : fwbUpdateEvent("", -1, QEvent::Type(QEvent::User + CLEAR_EDITOR_PANEL_EVENT), "clearEditorPanelEvent") {} }; class addUserFolderEvent : public fwbUpdateEvent { public: QString m_userFolder; addUserFolderEvent(const QString &fileName, int objId, const QString &userFolder) : fwbUpdateEvent(fileName, objId, QEvent::Type(QEvent::User + ADD_USER_FOLDER_EVENT), "addUserFolderEvent") { m_userFolder = userFolder; } }; class removeUserFolderEvent : public fwbUpdateEvent { public: QString m_userFolder; removeUserFolderEvent(const QString &fileName, int objId, const QString &userFolder) : fwbUpdateEvent(fileName, objId, QEvent::Type(QEvent::User + REMOVE_USER_FOLDER_EVENT), "removeUserFolderEvent") { m_userFolder = userFolder; } }; class moveToFromUserFolderEvent : public fwbUpdateEvent { public: int m_objIdToMove; QString m_oldFolder; QString m_newFolder; moveToFromUserFolderEvent(const QString &fileName, int objId, int objIdToMove, const QString &oldFolder, const QString &newFolder) : fwbUpdateEvent(fileName, objId, QEvent::Type(QEvent::User+MOVE_TOFROM_USER_FOLDER_EVENT), "removeUserFolderEvent"), m_objIdToMove(objIdToMove), m_oldFolder(oldFolder), m_newFolder(newFolder) {} }; #endif fwbuilder-5.1.0.3599/src/libgui/clusterdialog_q.ui0000644000175000017500000002603211733011756022563 0ustar sylvestresylvestre ClusterDialog_q true 0 0 917 262 0 0 Cluster 12 QFrame::Box QFrame::Sunken 12 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken 0 0 32767 32767 Name: false 1 0 200 23 0 0 32767 32767 Platform: false 0 0 0 26 Qt::Horizontal 129 20 0 0 32767 32767 Host OS: false 0 0 0 26 Modified: 0 0 TextLabel Compiled: 0 0 TextLabel Installed: 0 0 TextLabel Qt::Vertical 20 34 0 0 215 0 215 16777215 Skip this firewall for batch compile and install operations Inactive cluster 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name platform hostOS inactive platform activated(int) ClusterDialog_q platformChanged() 20 20 20 20 hostOS activated(QString) ClusterDialog_q hostOSChanged() 20 20 20 20 changed() platformChanged() hostOSChanged()
fwbuilder-5.1.0.3599/src/libgui/NetworkDialog.h0000644000175000017500000000264411733011756021770 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NETWORKDIALOG_H_ #define __NETWORKDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class NetworkDialog : public BaseObjectDialog { Q_OBJECT; Ui::NetworkDialog_q *m_dialog; public: NetworkDialog(QWidget *parent); ~NetworkDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void addressEntered(); }; #endif // NETWORKDIALOG_H fwbuilder-5.1.0.3599/src/libgui/findobjectwidget_q.ui0000644000175000017500000003033311733011756023234 0ustar sylvestresylvestre findObjectWidget_q 0 0 933 221 Form1 0 0 Find object 0 0 100 80 9 Name or label IP Address TCP/UDP port Protocol number ICMP type true Use regular expressions 0 0 Replace object 0 0 100 80 9 0 0 Scope for search and replace : 4 Tree only Tree and policy of all firewalls Policy of all firewalls policy of the opened firewall Qt::Horizontal QSizePolicy::Expanding 100 20 Find Next true true Replace Replace all Replace Current && Find Next Qt::Horizontal QSizePolicy::Expanding 110 20 Qt::Vertical QSizePolicy::MinimumExpanding 75 1 FWObjectDropArea QWidget
FWObjectDropArea.h
1
attribute findAttr srScope replaceAllButton replaceButton repNextButton findButton findDropArea objectDeleted() findObjectWidget_q enableAll() 20 20 20 20 findDropArea objectInserted() findObjectWidget_q objectInserted() 20 20 20 20 findButton clicked() findObjectWidget_q find() 20 20 20 20 findAttr activated(QString) findObjectWidget_q findAttrChanged(QString) 20 20 20 20 findAttr editTextChanged(QString) findObjectWidget_q findAttrChanged(QString) 20 20 20 20 attribute activated(QString) findObjectWidget_q findAttrChanged(QString) 20 20 20 20 replaceButton clicked() findObjectWidget_q replace() 20 20 20 20 replaceAllButton clicked() findObjectWidget_q replaceAll() 20 20 20 20 srScope activated(int) findObjectWidget_q reset() 20 20 20 20 replaceDropArea objectDeleted() findObjectWidget_q replaceDisable() 20 20 20 20 replaceDropArea objectInserted() findObjectWidget_q replaceEnable() 20 20 20 20 repNextButton clicked() findObjectWidget_q replaceNext() 20 20 20 20 srScope activated(int) findObjectWidget_q scopeChanged() 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/AddressTableDialog.cpp0000644000175000017500000001576111733011756023233 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "ProjectPanel.h" #include "AddressTableDialog.h" #include "TextFileEditor.h" #include "FWBSettings.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; AddressTableDialog::AddressTableDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::AddressTableDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } AddressTableDialog::~AddressTableDialog() { delete m_dialog; } void AddressTableDialog::loadFWObject(FWObject *o) { obj=o; AddressTable *s = dynamic_cast(obj); assert(s!=NULL); init = true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->filename->setText( s->getSourceName().c_str() ); m_dialog->r_compiletime->setChecked(s->isCompileTime() ); m_dialog->r_runtime->setChecked(s->isRunTime() ); //BrowseButton->setEnabled(s->isCompileTime() ); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->filename->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->filename); updateButtons(); init = false; } void AddressTableDialog::updateButtons() { m_dialog->editButton->setEnabled( ! m_dialog->filename->text().isEmpty()); } void AddressTableDialog::validate(bool *res) { *res=true; AddressTable *s = dynamic_cast(obj); assert(s!=NULL); if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void AddressTableDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); AddressTable *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); QByteArray cs = m_dialog->filename->text().toLocal8Bit(); s->setSourceName( (const char *)cs ); s->setRunTime(m_dialog->r_runtime->isChecked() ); updateButtons(); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } static void doReminderAboutDataDir() { if (st->isReminderAboutDataDirSuppressed()) return; QMessageBox msgBox; msgBox.setText("The file you selected is inside the " "'data directory' global preference. The path of the " "file has been converted to use the variable %DATADIR% " "so that expansion will happen properly within rules."); msgBox.setWindowModality(Qt::ApplicationModal); msgBox.setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | #if QT_VERSION >= 0x040500 Qt::WindowCloseButtonHint | #endif Qt::WindowSystemMenuHint); msgBox.setWindowTitle("Data directory conversion"); QCheckBox cb("Do not show this again", &msgBox); msgBox.addButton(&cb, QMessageBox::ResetRole); msgBox.addButton(QMessageBox::Close); msgBox.setDefaultButton(QMessageBox::Close); msgBox.setIcon(QMessageBox::Information); /* Hack alert! Disconnect signals from the checkbox so that QMessageBox doesn't know when it gets clicked, and treat it like an "OK" action. */ cb.disconnect(); msgBox.exec(); if (cb.isChecked()) st->suppressReminderAboutDataDir(true); } void AddressTableDialog::browse() { // build a dialog that will let user select existing file or enter // a name even if the file does not exist QString s = QFileDialog::getOpenFileName( this, tr("Choose a file or type the name to create new"), st->getOpenFileDir(mw->getCurrentFileName()), tr("All files (*)")); if (s.isEmpty()) return; st->setOpenFileDir(s); QString dataDir = st->getDataDir(); if (!dataDir.isEmpty()) { QString dataDirPath = QFileInfo(dataDir).canonicalFilePath(); QString filePath = QFileInfo(s).canonicalFilePath(); if (filePath.length() > 0 && filePath.startsWith(dataDirPath)) { int truncateLen = dataDirPath.length(); if (dataDirPath.at(truncateLen-1) == '/' || dataDirPath.at(truncateLen-1) == '\\') { truncateLen--; } s = filePath.replace(0, truncateLen, "%DATADIR%"); doReminderAboutDataDir(); } } m_dialog->filename->setText(s); // assign focus to the "file name" input field so that it // generates signal editFinished when user clicks // elsewhere. We use this signal to call changed() which in // turn calls applyChanges() to save data m_dialog->filename->setFocus(Qt::OtherFocusReason); updateButtons(); } void AddressTableDialog::editFile( void ) { QString filePath = m_dialog->filename->text(); if (filePath.startsWith("%DATADIR%")) { QString dataDir = st->getDataDir(); if (dataDir.isEmpty()) { QMessageBox::critical(this, "Firewall Builder", tr("Data directory setting is blank " "and path contains %DATADIR% variable")); return; } filePath.replace(0, 9, dataDir); } TextFileEditor editor(this, filePath); if (editor.load()) editor.exec(); // its modal dialog } fwbuilder-5.1.0.3599/src/libgui/CustomServiceDialog.cpp0000644000175000017500000001502511733011756023462 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "ProjectPanel.h" #include "FWBTree.h" #include "CustomServiceDialog.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include "FWWindow.h" using namespace libfwbuilder; using namespace std; CustomServiceDialog::CustomServiceDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::CustomServiceDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } CustomServiceDialog::~CustomServiceDialog() { delete m_dialog; } void CustomServiceDialog::loadFWObject(FWObject *o) { obj=o; CustomService *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); /* fill in m_dialog->platform */ m_dialog->platform->clear(); int cp=0; QString default_platform = st->value(SETTINGS_PATH_PREFIX"/CustomService/Platform").toString(); QMap platforms = getAllPlatforms(); QMap::iterator i; for (i=platforms.begin(); i!=platforms.end(); i++,cp++) { // cerr << "m_dialog->platform: key=" << i.key() // << " data=" << i.data() << endl; /* * here i.key is m_dialog->platform m_dialog->code ( "ipf", "ipfw", * "iptables", "pf") while i.data is human readable name ("ipfilter", * "PF" ) */ platformReverseMap[i.value()] = i.key(); m_dialog->platform->addItem(i.value()); if (default_platform=="") default_platform = i.key(); if (default_platform==i.key()) m_dialog->platform->setCurrentIndex(cp); string platform_code = i.key().toStdString(); allCodes[i.key()] = QString(s->getCodeForPlatform(platform_code).c_str()); } fillDialogInputFields(); QString protocol = s->getProtocol().c_str(); if (protocol == "") protocol = "any"; m_dialog->protocol->clear(); m_dialog->protocol->addItem("any"); m_dialog->protocol->addItem("tcp"); m_dialog->protocol->addItem("udp"); m_dialog->protocol->addItem("icmp"); m_dialog->protocol->addItem("ipv6-icmp"); bool standard_protocol = false; int proto_index = 0; for (; proto_index < m_dialog->protocol->count(); ++proto_index) { if (protocol == m_dialog->protocol->itemText(proto_index)) { m_dialog->protocol->setCurrentIndex(proto_index); standard_protocol = true; break; } } if (!standard_protocol) { m_dialog->protocol->addItem(protocol); m_dialog->protocol->setCurrentIndex(proto_index); } int af = s->getAddressFamily(); if (af == AF_INET6) m_dialog->ipv6->setChecked(true); else m_dialog->ipv4->setChecked(true); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->code->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->code); // do not make "platform" widget disabled when object is read-only // to let the user flip between platforms to see the configuration. See #2669 m_dialog->protocol->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->protocol); m_dialog->ipv4->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ipv4); m_dialog->ipv6->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ipv6); init=false; } void CustomServiceDialog::changed() { if (!init) { QString pl = platformReverseMap[m_dialog->platform->currentText()]; allCodes[pl] = m_dialog->code->text().toUtf8().constData(); } BaseObjectDialog::changed(); } void CustomServiceDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void CustomServiceDialog::platformChanged() { init=true; fillDialogInputFields(); init=false; // changed(); } void CustomServiceDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); CustomService *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); QMap platforms = getAllPlatforms(); QMap::iterator i; for (i=platforms.begin(); i!=platforms.end(); i++) { QString platform = i.key(); QString code = allCodes[platform]; s->setCodeForPlatform( platform.toUtf8().constData(), string(code.toUtf8().constData())); } QString protocol = m_dialog->protocol->lineEdit()->text(); s->setProtocol(string(protocol.toUtf8().constData())); int af = (m_dialog->ipv6->isChecked()) ? AF_INET6 : AF_INET; s->setAddressFamily(af); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void CustomServiceDialog::fillDialogInputFields() { QString npl = platformReverseMap[m_dialog->platform->currentText()]; showPlatform = npl; st->setValue(SETTINGS_PATH_PREFIX"/CustomService/Platform", showPlatform); m_dialog->code->setText(allCodes[showPlatform]); } fwbuilder-5.1.0.3599/src/libgui/hostdialog_q.ui0000644000175000017500000000742711733011756022066 0ustar sylvestresylvestre HostDialog_q true 0 0 748 214 Host QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 MAC matching Qt::Vertical 20 98 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name MACmatching
fwbuilder-5.1.0.3599/src/libgui/pfsyncOptionsDialog.h0000644000175000017500000000265611733011756023220 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PFSYNCOPTIONSDIALOG_H_ #define __PFSYNCOPTIONSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class pfsyncOptionsDialog : public QDialog { Q_OBJECT public: pfsyncOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~pfsyncOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::pfsyncOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __PFSYNCOPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/networkdialogipv6_q.ui0000644000175000017500000001522311733011756023400 0ustar sylvestresylvestre NetworkDialogIPv6_q true 0 0 718 258 0 0 Network 12 12 0 0 QFrame::Box QFrame::Sunken 0 0 350 16 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Address: false 200 0 0 0 Prefix length: false 0 0 0 23 Qt::Vertical 20 104 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name address address editingFinished() NetworkDialogIPv6_q addressEntered() 199 116 333 130 address returnPressed() NetworkDialogIPv6_q addressEntered() 199 116 333 130 changed()
fwbuilder-5.1.0.3599/src/libgui/StartTipDialog.h0000644000175000017500000000330011733011756022077 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __STARTTIPDIALOG_H_ #define __STARTTIPDIALOG_H_ #include "config.h" #include "ui_starttipdialog_q.h" #include "HttpGet.h" #include #include #include #include class StartTipDialog : public QDialog { Q_OBJECT; HttpGet *http_getter; QStringList tips; int current_tip; time_t start_time; bool first_run; void showTip(const QString &txt, bool new_tip=true); void showTip(int tip_idx); QString getRandomTip(); virtual void closeEvent(QCloseEvent *event); public: Ui::StartTipDialog_q *m_dialog; StartTipDialog(QWidget *parent = NULL); virtual ~StartTipDialog(); void run(); public slots: void downloadComplete(const QString&); void nextTip(); void prevTip(); void showGettingStartedTutorial(); virtual void close(); }; #endif fwbuilder-5.1.0.3599/src/libgui/SSHProcurve.h0000644000175000017500000000263311733011756021400 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SSHPROCURVE_H_ #define __SSHPROCURVE_H_ #include "config.h" #include "global.h" #include "SSHCisco.h" #include class SSHProcurve : public SSHCisco { Q_OBJECT; QString hp_greeting_prompt; public: SSHProcurve(QWidget *parent, const QString &host, const QStringList &args, const QString &pwd, const QString &epwd, const std::list &in); virtual ~SSHProcurve(); virtual void stateMachine(); public slots: virtual void finished( int code ); }; #endif fwbuilder-5.1.0.3599/src/libgui/keywordsdialog_q.ui0000644000175000017500000001431011733011756022745 0ustar sylvestresylvestre KeywordsDialog_q 0 0 626 387 Dialog All keywords 1 0 QAbstractItemView::NoEditTriggers QAbstractItemView::ExtendedSelection 10 10 Qt::Vertical 20 40 0 0 Add >> 0 0 << Remove Qt::Vertical 20 40 1 1 QAbstractItemView::NoEditTriggers QAbstractItemView::ExtendedSelection Current keywords Qt::Horizontal 13 20 New Keyword: 0 0 200 0 0 0 Create Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() KeywordsDialog_q accept() 248 254 157 274 buttonBox rejected() KeywordsDialog_q reject() 316 260 286 274 fwbuilder-5.1.0.3599/src/libgui/networkZoneManager.cpp0000644000175000017500000001003111733011756023357 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "networkZoneManager.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Library.h" #include "fwbuilder/ObjectGroup.h" #include using namespace libfwbuilder; using namespace std; NetworkZoneManager::NetworkZoneManager() { } void NetworkZoneManager::load(FWObjectDatabase *_db) { db = _db; netzones_object_names.clear(); netzones_id_to_index.clear(); netzones_index_to_id.clear(); int n = 0; netzones_id_to_index[0] = n; netzones_index_to_id[n] = 0; netzones_object_names.push_back(" None "); ++n; netzones_id_to_index[FWObjectDatabase::ANY_ADDRESS_ID] = n; netzones_index_to_id[n] = FWObjectDatabase::ANY_ADDRESS_ID; netzones_object_names.push_back(" Any "); ++n; /* TODO: try to make this widget show object with appropriate icon */ list libs = db->getByType( Library::TYPENAME ); for (list::iterator l=libs.begin(); l!=libs.end(); ++l) { FWObject *library= *l; FWObject *o1,*o2; if ( library->getId()==FWObjectDatabase::DELETED_OBJECTS_ID ) continue; o1 = library->findObjectByName(ObjectGroup::TYPENAME, "Objects"); assert(o1!=NULL); o2 = o1->findObjectByName(ObjectGroup::TYPENAME, "Groups"); if (o2==NULL) { if (fwbdebug) qDebug() << "NetworkZoneManager::NetworkZoneManager():" << "missing Groups group in " << FWObjectDatabase::getStringId(o1->getId()).c_str(); continue; } for (FWObject::iterator i=o2->begin(); i!=o2->end(); ++i) { netzones_id_to_index[(*i)->getId()] = n; netzones_index_to_id[n] = (*i)->getId(); netzones_object_names.push_back( QObject::tr("Group: ")+ (*i)->getName().c_str() ); ++n; } o2=o1->findObjectByName(ObjectGroup::TYPENAME,"Networks"); if (o2==NULL) { if (fwbdebug) qDebug() << "NetworkZoneManager::NetworkZoneManager():" << "missing Networks group in " << FWObjectDatabase::getStringId(o1->getId()).c_str(); continue; } for (FWObject::iterator i1=o2->begin(); i1!=o2->end(); ++i1) { netzones_id_to_index[(*i1)->getId()] = n; netzones_index_to_id[n] = (*i1)->getId(); netzones_object_names.push_back( QObject::tr("Network: ")+ (*i1)->getName().c_str()); ++n; } } } int NetworkZoneManager::getListItemIdexByNetzoneId(int id) { return netzones_id_to_index[id]; } int NetworkZoneManager::getNetzoneIdByListIndex(int idx) { return netzones_index_to_id[idx]; } void NetworkZoneManager::packComboBox(QComboBox *combobox, int current_netzone_object_id) { combobox->clear(); combobox->addItems(netzones_object_names); for(int idx=0; idx < combobox->count(); ++idx) combobox->setItemData(idx, QVariant(netzones_index_to_id[idx]), Qt::UserRole); combobox->setCurrentIndex( netzones_id_to_index[current_netzone_object_id] ); } fwbuilder-5.1.0.3599/src/libgui/SSHCisco.h0000644000175000017500000000401211733011756020624 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SSHCISCO_H_ #define __SSHCISCO_H_ #include "config.h" #include "global.h" #include "SSHSession.h" #include #include #include #include class QEventLoop; class SSHCisco : public SSHSession { Q_OBJECT; int nLines; int ncmd; protected: QEventLoop *local_event_loop; QStringList newAcls; QStringList currentAcls; QStringList newObjectGroups; QStringList currentObjectGroups; QStringList pre_config_commands; QStringList post_config_commands; QStringList activation_commands; char comment_symbol; public: SSHCisco(QWidget *parent, const QString &host, const QStringList &args, const QString &pwd, const QString &epwd, const std::list &in); virtual ~SSHCisco(); virtual bool checkForErrors(); virtual void stateMachine(); QString cmd(QProcess *proc,const QString &cmd); void loadPreConfigCommands(const QStringList &cl); void loadPostConfigCommands(const QStringList &cl); void loadActivationCommands(const QStringList &cl); }; #endif fwbuilder-5.1.0.3599/src/libgui/FWCmdChange.cpp0000644000175000017500000002030511733011756021612 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWCmdChange.h" #include "FWWindow.h" #include "ColDesc.h" #include "RuleSetView.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Rule.h" #include "events.h" #include #include using namespace libfwbuilder; using namespace std; /******************************************************** * FWCmdChange ********************************************************/ FWCmdChange::FWCmdChange(ProjectPanel *project, FWObject *obj, QString text, bool _rename_children, QUndoCommand* macro): FWCmdBasic(project, macro) { setObject(obj); rename_children = _rename_children; first_time = true; FWObjectDatabase* db = obj->getRoot(); if (db == obj) { this->oldState = new FWObjectDatabase(); this->newState = new FWObjectDatabase(); } else { this->oldState = db->create(obj->getTypeName()); this->newState = db->create(obj->getTypeName()); } bool was_clean = (db->isDirty() == false); // Note: if obj is a group that holds references to other objects, // duplicateForUndo() increments reference counters in those objects // and subsequently raises "dirty" flag in the database. this->oldState->duplicateForUndo(obj); this->newState->duplicateForUndo(obj); if (was_clean) db->setDirty(false); if (text.isEmpty()) { setText(QObject::tr("Edit ") + QString::fromUtf8(obj->getName().c_str())); } else { setText(text); } } FWCmdChange::~FWCmdChange() { delete (oldState); delete (newState); } void FWCmdChange::undo() { if (fwbdebug) qDebug() << "FWCmdChange::undo()"; FWObject* obj = getObject(); try { obj->duplicateForUndo(oldState); } catch (FWException &ex) { qDebug() << "FWCmdChange::undo() caught FWException: " << ex.toString().c_str(); } notify(); } void FWCmdChange::redo() { if (fwbdebug) qDebug() << "FWCmdChange::redo()"; FWObject* obj = getObject(); try { obj->duplicateForUndo(newState); } catch (FWException &ex) { qDebug() << "FWCmdChange::redo() caught FWException: " << ex.toString().c_str(); } notify(); } void FWCmdChange::notify() { if (fwbdebug) qDebug() << "FWCmdChange::notify()"; FWObject* obj = getObject(); QString filename = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); if (oldState->getName() != newState->getName()) { // objectNameChangedEvent event triggers actions, such as // automatic renaming of child objects. This should only be // done once, even if we have the same data file opened in // several project panels. // // Use sendEvent to make sure event is processed right now and // is not postponed. This is important when this command is // executed as part of a group undo/redo (when user clicks in // the undo panel). If this command is posted to event queue, // it is executed after bunch of objects are deleted and may // need to operate on one of them. // if (first_time) { QCoreApplication::sendEvent( mw->activeProject(), new objectNameChangedEvent( filename, obj->getId(), QString::fromUtf8(oldState->getName().c_str()), QString::fromUtf8(newState->getName().c_str()), rename_children)); first_time = false; } } QCoreApplication::postEvent( mw, new updateObjectEverywhereEvent(filename, obj->getId())); if (mw->isEditorVisible()) { QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, obj->getId())); } QCoreApplication::postEvent( mw, new dataModifiedEvent(filename, obj->getId())); } /******************************************************** * FWCmdChangeName ********************************************************/ FWCmdChangeName::FWCmdChangeName(ProjectPanel *project, FWObject *obj) : FWCmdChange(project, obj, QObject::tr("Rename object")) {} /* * Command FWCmdChangeName is used in ObjectManipulator::autorename() * functions that rename children objects when the name of a firewall * or its interface changes. This command should not open object it * renamed in the editor. If it does, the object in the editor changes * when user renames fw or interface. This is especially unexpecred if * renaming was triggered by them changing the name of fw or interface * and then hitting Tab. User expectation is that keyboard should * switch to the next element in the dialog, even if some side effects * do happen. Changing the object in the editor looks confusing. */ void FWCmdChangeName::notify() { FWObject* obj = getObject(); QString filename = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); // when object's name changes, its position in the tree changes // too to keep the tree sorted. Need to update the object // everywhere, as well as its parent's subtree. QCoreApplication::postEvent(mw, new updateObjectInTreeEvent(filename, obj->getId())); QCoreApplication::postEvent(mw, new reloadRulesetEvent(filename)); QCoreApplication::postEvent(mw, new dataModifiedEvent(filename, obj->getId())); } /******************************************************** * FWCmdLockObject * * locking object creates problems with virtual method * FWObject::shallowDuplicate and the same virt method in derived * classes because they make object read-only and then try to modify * it. It is easier to have specialized command that just sets or * clears read-only flag and does nothing else. * ********************************************************/ FWCmdLockObject::FWCmdLockObject(ProjectPanel *project, FWObject *obj, QString name) : FWCmdChange(project, obj, name) { } void FWCmdLockObject::undo() { FWObject* obj = getObject(); obj->setReadOnly(getOldState()->getRO()); notify(); } void FWCmdLockObject::redo() { FWObject* obj = getObject(); obj->setReadOnly(getNewState()->getRO()); notify(); } /******************************************************** * FWCmdChangeOptionsObject * * This command is used to change failover or state protocol parameters * (CARP, conntrack, heartbeat, vrrp, pfsync, openais) ********************************************************/ FWCmdChangeOptionsObject::FWCmdChangeOptionsObject(ProjectPanel *project, FWObject *obj) : FWCmdChange(project, obj, QObject::tr("Edit protocol parameters")) {} void FWCmdChangeOptionsObject::notify() { FWObject* obj = getObject(); QString filename = QString::fromUtf8(obj->getRoot()->getFileName().c_str()); // obj here is a FWOptions. We need to select its parent in the // tree and redraw it in the rule set panel. To do so, using // obj->getParent(). Note that parent object hasn't changed, so we // send showObjectInTreeEvent rather than // updateObjectInTreeEvent. QCoreApplication::postEvent( mw, new showObjectInTreeEvent(filename, obj->getParent()->getId())); QCoreApplication::postEvent(mw, new reloadRulesetEvent(filename)); QCoreApplication::postEvent(mw, new dataModifiedEvent(filename, obj->getId())); } fwbuilder-5.1.0.3599/src/libgui/attachednetworksdialog_q.ui0000644000175000017500000001360211733011756024453 0ustar sylvestresylvestre AttachedNetworksDialog_q true 0 0 949 258 0 0 Network 0 0 QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Qt::Vertical QSizePolicy::Expanding 20 5 The list of addresses in this object is updated automatically and represents subnets attached to the parent interface. true Qt::Vertical 20 48 QFrame::StyledPanel QFrame::Raised QFrame::NoFrame QFrame::Plain 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name obj_name editingFinished() AttachedNetworksDialog_q changed() 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/conntrackoptionsdialog_q.ui0000644000175000017500000001236511733011756024504 0ustar sylvestresylvestre conntrackOptionsDialog_q 0 0 387 276 conntrack protocol settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 :/Icons/Options:/Icons/Options conntrack Parameters Use unicast address for conntrackd Address: Port number (udp): 65535 Qt::Horizontal 117 20 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() conntrackOptionsDialog_q accept() 316 472 20 20 buttonCancel clicked() conntrackOptionsDialog_q reject() 397 472 20 20 use_unicast clicked() conntrackOptionsDialog_q toggleUseUnicast() 196 50 193 137 toggleUseUnicast() fwbuilder-5.1.0.3599/src/libgui/FWWindow_editor.cpp0000644000175000017500000002772311733011756022631 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003, 2006 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "events.h" #include #include "FWBTree.h" #include "FWWindow.h" #include "FindObjectWidget.h" #include "FindWhereUsedWidget.h" #include "RuleSetModel.h" #include "RuleSetView.h" #include "platforms.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Library.h" #include #include #include #include #include using namespace libfwbuilder; /* * when ProjectPanel is created, it sends bunch of stateChange events * which lead to calls to ProjectPanel::changeEvent() method. This * method checks if editor is visible and contains modified data. Since * we create default ProjectPanel object in the constructor of * FWWindow, the first call to ProjectPanel::changeEvent() comes when * object editor has not been create yet. This is why we need to check * for oe != NULL here and below. */ bool FWWindow::isEditorVisible() { return oe != NULL && m_mainWindow->editorDockWidget->isVisible() && m_mainWindow->editorPanelTabWidget->currentIndex() == EDITOR_PANEL_EDITOR_TAB; } void FWWindow::editorPanelTabChanged(int idx) { if (idx == EDITOR_PANEL_EDITOR_TAB) { ProjectPanel *pp = activeProject(); if (pp) { oe->open(pp->getSelectedObject()); } } } /***************************************************************** * there are too many functions that open, close and hide editor panel. * TODO: need to get rid of redundant ones */ void FWWindow::showEditor() { m_mainWindow->objectEditorStack->setCurrentIndex(oe->getCurrentDialogIndex()); m_mainWindow->editorPanelTabWidget->setCurrentIndex(EDITOR_PANEL_EDITOR_TAB); m_mainWindow->editorDockWidget->show(); // editor } void FWWindow::hideEditor() { closeEditorPanel(); } void FWWindow::closeEditor() { m_mainWindow->editorDockWidget->close(); // editor } void FWWindow::closeEditorPanel() { m_mainWindow->editorDockWidget->hide(); // editor } void FWWindow::clearEditorAndSearchPanels() { findWhereUsedWidget->clear(); findObjectWidget->clear(); if (oe != NULL) oe->blank(); } void FWWindow::openEditorPanel() { } void FWWindow::openEditor(FWObject *obj) { if (FWBTree().isSystem(obj)) return; attachEditorToProjectPanel(activeProject()); /* * See #1060 when user finished editing one of the input fields * (QLineEdit) in the object editor and hit Tab, focus moved to * the next field but its contents did not get highlighted as * usual, but instead cusror was positioned after the last * character. This happened because FWCmdChange::notify() reloaded * contents of the editor. We can't avoid doing this because we * have to update the editor when user cycles through undo/redo * operations. It is hard to detect when redo() is called for the * first time when user just finished editing something (and even * if that was possible, what if they execute undo or redo some * time later while looking at the same object in the * editor). Will detect situation when editor is reloaded with the * same object and restore focus on the same input field. If this * field is QLineEdit, will also select contents to emulate * correct behavior when user moves between input fields using * Tab. */ QWidget *current_focus_widget = QApplication::focusWidget(); bool reopen = (getOpenedEditor() == obj && current_focus_widget && m_mainWindow->editorDockWidget->isAncestorOf(current_focus_widget)); QLineEdit *line_edit = dynamic_cast(current_focus_widget); bool restore_line_edit_selection = line_edit != NULL && line_edit->hasSelectedText(); if (fwbdebug) { qDebug() << "FWWindow::openEditor " << " obj: " << " " << obj->getName().c_str() << " " << obj->getTypeName().c_str() << " reopening in the editor: " << reopen << " current_focus_widget=" << current_focus_widget; } QString title_txt; QPixmap title_icon; buildEditorTitleAndIcon( obj, ObjectEditor::optNone, &title_txt, &title_icon, m_mainWindow->m_space->subWindowList(QMdiArea::StackingOrder).size() > 1); QSize old_size = m_mainWindow->objectEditorStack->size(); m_mainWindow->editorPanelTabWidget->setCurrentIndex(EDITOR_PANEL_EDITOR_TAB); m_mainWindow->editorDockWidget->setWindowTitle(title_txt); m_mainWindow->objectTypeIcon->setPixmap(title_icon); m_mainWindow->editorDockWidget->show(); // editor oe->open(obj); m_mainWindow->objectEditorStack->resize(old_size); // #2465 If the object we are about to open in the editor is a // firewall and if a ruleset visible in RuleSetView belongs to // another firewall, switch ruleset to the ruleset of the new // firewall which we looked at last time. // FWObject *parent_fw = Host::getParentHost(obj); if (fwbdebug) qDebug() << "parent firewall:" << parent_fw << QString((parent_fw)? parent_fw->getName().c_str() : ""); if (parent_fw != NULL) // this includes Cluster { RuleSetView* rsv = activeProject()->getCurrentRuleSetView(); if (rsv) { RuleSet* current_ruleset = NULL; RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (parent_fw != current_ruleset->getParent()) { FWObject *old_rs = activeProject()->m_panel->om->findRuleSetInHistoryByParentFw( parent_fw); if (old_rs == NULL) old_rs = parent_fw->getFirstByType(Policy::TYPENAME); if (old_rs != NULL) QCoreApplication::postEvent( activeProject(), new openRulesetImmediatelyEvent( activeProject()->getFileName(), old_rs->getId())); } } } if (reopen) { if (fwbdebug) { qDebug() << "FWWindow::openEditor " << "New widget about to get focus:" << current_focus_widget; } if (current_focus_widget) { current_focus_widget->setFocus(Qt::TabFocusReason); if (restore_line_edit_selection) line_edit->selectAll(); } } } void FWWindow::openOptEditor(FWObject *obj, ObjectEditor::OptType t) { attachEditorToProjectPanel(activeProject()); if (fwbdebug) qDebug() << "FWWindow::openOptEditor " << " obj: " << " " << obj->getName().c_str() << " " << obj->getTypeName().c_str() << " option: " << t; QString title_txt; QPixmap title_icon; buildEditorTitleAndIcon( obj, t, &title_txt, &title_icon, m_mainWindow->m_space->subWindowList(QMdiArea::StackingOrder).size() > 1); QSize old_size = m_mainWindow->objectEditorStack->size(); m_mainWindow->editorPanelTabWidget->setCurrentIndex(EDITOR_PANEL_EDITOR_TAB); m_mainWindow->editorDockWidget->setWindowTitle(title_txt); //m_mainWindow->editorDockWidget->setWindowIcon(title_icon); m_mainWindow->objectTypeIcon->setPixmap(title_icon); m_mainWindow->editorDockWidget->show(); // editor oe->openOpt(obj, t); m_mainWindow->objectEditorStack->resize(old_size); if (fwbdebug) qDebug() << "FWWindow::openOptEditor done"; } void FWWindow::buildEditorTitleAndIcon(libfwbuilder::FWObject *obj, ObjectEditor::OptType t, QString *title_txt, QPixmap *pm, bool include_file_name) { QList subwindows = m_mainWindow->m_space->subWindowList( QMdiArea::StackingOrder); QMdiSubWindow *top_subw = subwindows.last(); // last item is the topmost window ProjectPanel *top_pp = dynamic_cast(top_subw->widget()); QStringList editor_title; FWObject *o = obj; Rule *rule = NULL; FWObject *ruleset = NULL; while (o) { if (Rule::cast(o)) { rule = Rule::cast(o); editor_title.push_front(QString("rule #%1").arg(rule->getPosition())); } else editor_title.push_front(QString::fromUtf8(o->getName().c_str())); if (Library::cast(o)) break; if (RuleSet::cast(o)) ruleset = o; o = o->getParent(); } if (include_file_name) editor_title.push_front( QString("[%1]").arg(top_pp->getFileName())); else editor_title.push_front(" "); // to force '/' in front of object path *title_txt = editor_title.join(" / "); if (pm) { FWObject *obj_for_icon = obj; if (ruleset) obj_for_icon = ruleset; if (rule && t == ObjectEditor::optAction) { QString icn = ":/Icons/" + getRuleAction(rule) + "/icon-big"; LoadPixmap(icn, *pm); // in utils.cpp } else doSetObjectIcon(obj_for_icon, pm, 2); // big icon } } void FWWindow::blankEditor() { m_mainWindow->editorDockWidget->setWindowTitle(""); oe->blank(); } FWObject* FWWindow::getOpenedEditor() { return oe->getOpened(); } ObjectEditor::OptType FWWindow::getOpenedOptEditor() { return oe->getOpenedOpt(); } void FWWindow::findObject(FWObject *o) { if (activeProject()) { attachEditorToProjectPanel(activeProject()); findWhereUsedWidget->hide(); findObjectWidget->findObject(o); m_mainWindow->editorPanelTabWidget->setCurrentIndex(EDITOR_PANEL_SEARCH_TAB); // search tab findObjectWidget->show(); m_mainWindow->editorDockWidget->show(); } } void FWWindow::search() { if (activeProject()) { attachEditorToProjectPanel(activeProject()); m_mainWindow->actionEditor_panel->setChecked(true); findWhereUsedWidget->hide(); m_mainWindow->editorPanelTabWidget->setCurrentIndex(EDITOR_PANEL_SEARCH_TAB); // search tab findObjectWidget->show(); m_mainWindow->editorDockWidget->show(); } } void FWWindow::findWhereUsed(FWObject * obj, ProjectPanel *pp) { if (fwbdebug) qDebug() << "FWWindow::findWhereUsed findWhereUsedWidget=" << findWhereUsedWidget << " project panel: " << pp; attachEditorToProjectPanel(pp); findObjectWidget->hide(); m_mainWindow->editorPanelTabWidget->setCurrentIndex(EDITOR_PANEL_SEARCH_TAB); // search tab findWhereUsedWidget->show(); findWhereUsedWidget->find(obj); m_mainWindow->editorDockWidget->show(); } /* * TODO: deprecate this */ bool FWWindow::requestEditorOwnership(QWidget*, FWObject*, ObjectEditor::OptType, bool) { if (!isEditorVisible()) return false; return true; } fwbuilder-5.1.0.3599/src/libgui/FWCmdBasic.h0000644000175000017500000000354011733011756021115 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FWCMDBASIC_H #define FWCMDBASIC_H #include #include #include #include "ProjectPanel.h" #include "fwbuilder/FWObject.h" class FWCmdMacro : public QUndoCommand { public: FWCmdMacro(QString text) : QUndoCommand() {setText(text);} int id() const {return 1;} bool mergeWith(const QUndoCommand *other); }; class FWCmdBasic : public QUndoCommand { int obj_id; protected: ProjectPanel *project; public: FWCmdBasic(ProjectPanel *project, QUndoCommand* macro = 0); int objectId() {return obj_id;} void setObject(libfwbuilder::FWObject *object) {obj_id = object->getId();} libfwbuilder::FWObject* getObject(); libfwbuilder::FWObject* getObject(int id); int id() const {return 1;} bool mergeWith(const QUndoCommand *other); }; class FWCmdTerm : public QUndoCommand { public: FWCmdTerm() : QUndoCommand() {setText("Terminator");} int id() const {return 1;} }; void undoAndRemoveLastCommand(QUndoStack* undoStack); #endif // FWCMDBASIC_H fwbuilder-5.1.0.3599/src/libgui/FWObjectDropArea.h0000644000175000017500000000454411733011756022301 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FWOBJECTDROPAREA_H_ #define __FWOBJECTDROPAREA_H_ #include "config.h" #include #include "fwbuilder/FWObject.h" #include #include #include #include #include #include class QWidget; class QPixmap; class QMenu; class QContextMenuEvent; class QDropEvent; class QDragEnterEvent; class FWObjectDropArea : public QWidget//Ui::FWObjectDropArea_q { Q_OBJECT; private: libfwbuilder::FWObject *object; QVector acceptedTypes ; QString helperText ; protected: void paintEvent(QPaintEvent *ev); void contextMenuEvent (QContextMenuEvent * e); void dropEvent( QDropEvent *ev); void dragEnterEvent( QDragEnterEvent *ev); public: Ui::FWObjectDropArea_q *m_objectDropArea; FWObjectDropArea(QWidget*p, const char * n = 0, Qt::WFlags f = 0); ~FWObjectDropArea(); libfwbuilder::FWObject * getObject(){return object;}; void setObject(libfwbuilder::FWObject * o){ object = o ;}; void addAcceptedTypes (QString type){acceptedTypes.push_back(type);}; bool isEmpty() {return object==NULL;}; void setHelperText(const QString &text) { helperText=text; } virtual void mouseDoubleClickEvent ( QMouseEvent * event ); public slots: void insertObject(libfwbuilder::FWObject *o); void deleteObject(); void pasteObject(); void showInTreeObject(); void editObject(); signals: void objectDeleted(); void objectInserted(); }; #endif fwbuilder-5.1.0.3599/src/libgui/newHostDialog.cpp0000644000175000017500000004660211733011756022323 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include "newHostDialog.h" #include "FWWindow.h" #include "ObjConflictResolutionDialog.h" #include "upgradePredicate.h" #include "events.h" #include "fwbuilder/Library.h" #include "fwbuilder/Host.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/BackgroundOp.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Constants.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // must be the last for win #include "fwbuilder/snmp.h" using namespace libfwbuilder; using namespace std; #define OBJECT_NAME_PAGE 0 #define SNMP_PAGE 1 #define MANUAL_PAGE 2 #define TEMPLATES_PAGE 3 newHostDialog::newHostDialog(QWidget *parentw, FWObject *_p) : QDialog(parentw) { parent = _p; db = parent->getRoot(); m_dialog = new Ui::newHostDialog_q; m_dialog->setupUi(this); setControlWidgets(this, m_dialog->stackedWidget, m_dialog->nextButton, m_dialog->finishButton, m_dialog->backButton, m_dialog->cancelButton, m_dialog->titleLabel); nhst=NULL; tmpldb = NULL; snmpPollCompleted=false; q=NULL; unloadTemplatesLib = false; getInterfacesBusy = false; timer = new QTimer(this); connect( timer, SIGNAL(timeout()), this, SLOT(monitor()) ); connect( m_dialog->templateUseCustom, SIGNAL(pressed()), this,SLOT(browseTemplate())); connect( m_dialog->templateUseStandard, SIGNAL(pressed()), this,SLOT(useStandardTemplate())); connect( m_dialog->useTemplate, SIGNAL(released()), this,SLOT(updateTemplatePanel())); m_dialog->templateFilePath->setText( Constants::getTemplatesObjectsFilePath().c_str()); updateTemplatePanel(); setNextEnabled( OBJECT_NAME_PAGE, false ); m_dialog->obj_name->setFocus(); m_dialog->interfaceEditor->clear(); showPage(0); } void newHostDialog::browseTemplate() { QString fileName = QFileDialog::getOpenFileName( this, tr("FWBuilder template files"), st->getOpenFileDir(), tr("FWBuilder template files (*.xml *.fwb)")); if (fileName.isEmpty()) return; st->setOpenFileDir(fileName); m_dialog->templateFilePath->setText(fileName); updateTemplatePanel(); } void newHostDialog::useStandardTemplate() { m_dialog->templateFilePath->setText( Constants::getTemplatesObjectsFilePath().c_str()); updateTemplatePanel(); } void newHostDialog::updateTemplatePanel() { if (m_dialog->useTemplate->checkState()==Qt::Checked) { QString fileName = m_dialog->templateFilePath->text(); bool using_std = fileName == Constants::getTemplatesObjectsFilePath().c_str(); m_dialog->templateFrame->setVisible(true); m_dialog->templateFilePathLabel->setVisible(!using_std); m_dialog->templateFilePath->setVisible(!using_std); m_dialog->templateUseCustom->setVisible(using_std); m_dialog->templateUseStandard->setVisible(!using_std); } else { m_dialog->templateFrame->setVisible(false); } } newHostDialog::~newHostDialog() { delete m_dialog; if (timer!=NULL) delete timer; #ifdef HAVE_LIBSNMP if (q!=NULL) delete q; #endif } void newHostDialog::nextClicked() { if (nextRelevant( currentPage() ) > -1) showPage(nextRelevant( currentPage() )); } void newHostDialog::backClicked() { if (previousRelevant( currentPage() ) > -1) showPage(previousRelevant( currentPage() )); } void newHostDialog::changed() { int p = currentPage(); if (p==OBJECT_NAME_PAGE) { setNextEnabled( p, !m_dialog->obj_name->text().isEmpty() ); } if (p==SNMP_PAGE) { bool f; #ifdef HAVE_LIBSNMP f = m_dialog->use_snmp->isChecked(); #else f = false; m_dialog->use_snmp->setEnabled( f ); #endif m_dialog->snmp_community->setEnabled( f ); m_dialog->snmpQuery->setEnabled( f ); m_dialog->snmpProgress->setEnabled( f ); if (f) m_dialog->snmp_community->setFocus(); f = m_dialog->use_manual->isChecked() || snmpPollCompleted; setNextEnabled( SNMP_PAGE, f ); } if (p==MANUAL_PAGE) { /* if (m_dialog->iface_dyn->isChecked() || m_dialog->iface_unnum->isChecked()) { m_dialog->iface_addr->clear(); m_dialog->iface_addr->setEnabled(false); m_dialog->iface_netmask->clear(); m_dialog->iface_netmask->setEnabled(false); } else { m_dialog->iface_addr->setEnabled(true); m_dialog->iface_netmask->setEnabled(true); }*/ } } void newHostDialog::monitor() { if (logger==NULL || q==NULL) return; #ifdef HAVE_LIBSNMP if( logger->ready() ) { QString str = logger->getLine().c_str(); m_dialog->snmpProgress->moveCursor( QTextCursor::End ); m_dialog->snmpProgress->insertPlainText( str ); return; } if (q->isRunning()) return; timer->stop(); map* intf = q->getInterfaces(); map::iterator i; for(i=intf->begin(); i!=intf->end(); ++i) { InterfaceData* idata = &(i->second); if ( idata->ostatus ) { guessInterfaceLabel(idata); this->m_dialog->interfaceEditor->addInterfaceFromData(idata); } } delete q; q=NULL; #endif snmpPollCompleted=true; setNextEnabled( SNMP_PAGE, true ); } void newHostDialog::getInterfacesViaSNMP() { #ifdef HAVE_LIBSNMP // need to protect from reentry because getAddrByName processes events if (q!=NULL || getInterfacesBusy) return; snmpPollCompleted=false; string rcomm=m_dialog->snmp_community->text().toLatin1().constData(); if ( rcomm.empty() ) { QMessageBox::warning( this,"Firewall Builder", tr("Missing SNMP community string."), "&Continue", QString::null, QString::null, 0, 1 ); return ; } m_dialog->interfaceEditor->clear(); m_dialog->interfaceEditor->removeTab(0); getInterfacesBusy = true; InetAddr addr; QString name=m_dialog->obj_name->text().toLatin1().constData(); try { QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); QString a = getAddrByName(name, AF_INET); QApplication::restoreOverrideCursor(); addr = InetAddr(a.toAscii().constData()); } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", tr("Address of %1 could not be obtained via DNS") .arg(m_dialog->obj_name->text()), "&Continue", QString::null, QString::null, 0, 1 ); getInterfacesBusy = false; return ; } logger=NULL; m_dialog->snmpProgress->clear(); if (q!=NULL) delete q; q=new SNMP_interface_query(); q->init(addr.toString(),rcomm,SNMP_DEFAULT_RETRIES,SNMP_DEFAULT_TIMEOUT); timer->setSingleShot(false); timer->start(0); try { logger = q->start_operation(); } catch(const FWException &ex) { //do nothing } getInterfacesBusy = false; #endif } bool newHostDialog::appropriate(const int page) const { int p = page; if (fwbdebug) { qDebug("newHostDialog::appropriate p=%d",p); } switch (p) { case OBJECT_NAME_PAGE: case TEMPLATES_PAGE: return true; case SNMP_PAGE: case MANUAL_PAGE: return (!m_dialog->useTemplate->isChecked()); } return true; } void newHostDialog::showPage(const int page) { FakeWizard::showPage(page); int p = currentPage(); if (fwbdebug) qDebug("newHostDialog::selected p=%d",p); // p is a page number _after_ it changed switch (p) { case SNMP_PAGE: changed(); // to properly enable/disable widgets m_dialog->nextButton->setDefault(true); break; case MANUAL_PAGE: { setNextEnabled( MANUAL_PAGE, false ); setFinishEnabled( MANUAL_PAGE, true ); m_dialog->finishButton->setDefault(true); break; } case TEMPLATES_PAGE: { m_dialog->finishButton->setDefault(true); setFinishEnabled( TEMPLATES_PAGE, true ); /* load templates if not loaded */ if (tmpldb==NULL) { MessageBoxUpgradePredicate upgrade_predicate(this); tmpldb = new FWObjectDatabase(); tmpldb->setReadOnly( false ); tmpldb->load( m_dialog->templateFilePath->text().toAscii().data(), &upgrade_predicate, Constants::getDTDDirectory()); } list fl; FWObjectTypedChildIterator libiter = tmpldb->findByType(Library::TYPENAME); for ( ; libiter!=libiter.end(); ++libiter) findHosts(*libiter, fl, false); QString icn = QString( Resources::global_res->getObjResourceStr(fl.front(), "icon-tree").c_str() ); m_dialog->templateList->clear(); int n=0; for (list::iterator m=fl.begin(); m!=fl.end(); m++,n++) { FWObject *o=*m; QPixmap pm; if ( ! QPixmapCache::find( icn, pm) ) { pm.load( icn ); QPixmapCache::insert( icn, pm); } QListWidgetItem *item = new QListWidgetItem( QIcon(pm), QString(o->getName().c_str())); m_dialog->templateList->addItem(item); templates[ m_dialog->templateList->item( m_dialog->templateList->count()-1 ) ]=o; } m_dialog->templateList->setCurrentItem(0); m_dialog->templateList->setFocus(); break; } } } void newHostDialog::templateSelected(QListWidgetItem *itm) //void newHostDialog::templateSelected(QListWidgetItem *cur) { //QListWidgetItem *itm = cur; if (fwbdebug) qDebug("newHostDialog::templateSelected "); FWObject *o=templates[itm]; assert (o!=NULL); Host *fw = Host::cast(o); m_dialog->templateComment->clear(); m_dialog->templateComment->append( fw->getComment().c_str() ); m_dialog->templateComment->moveCursor(QTextCursor::Start); bool haveOutside = false; bool haveInside = false; bool haveDMZ = false; list ll = fw->getByType(Interface::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { Interface *intf = Interface::cast( *i ); QString nam = intf->getName().c_str(); QString lbl = intf->getLabel().c_str(); if (lbl=="outside" || nam.indexOf(QRegExp(".*0$"))!=-1 || nam.indexOf(QRegExp(".*0/0$"))!=-1 ) { haveOutside=true; m_dialog->intfOutsideLine->show(); m_dialog->intfOutsideText->show(); fillInterfaceData(intf,m_dialog->intfOutsideText); } if (lbl=="inside" || nam.indexOf(QRegExp(".*1$"))!=-1 || nam.indexOf(QRegExp(".*0/1$"))!=-1 ) { haveInside=true; m_dialog->intfInsideLine->show(); m_dialog->intfInsideText->show(); fillInterfaceData(intf,m_dialog->intfInsideText); } } if (!haveOutside) { m_dialog->intfOutsideLine->hide(); m_dialog->intfOutsideText->hide(); } if (!haveInside) { m_dialog->intfInsideLine->hide(); m_dialog->intfInsideText->hide(); } if (!haveDMZ) { m_dialog->intfDMZLine->hide(); m_dialog->intfDMZText->hide(); } } void newHostDialog::fillInterfaceData(Interface *intf, QTextBrowser *qte) { qte->clear(); QString s; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += "
"; s += tr("Interface: %1 (%2)") .arg(intf->getName().c_str()) .arg(intf->getLabel().c_str()); s += "
"; if (intf->isDyn()) s += tr("Dynamic address"); else if (intf->isUnnumbered()) s += tr("Unnumbered interface"); else { const InetAddr *addr = intf->getAddressPtr(); QString addr_str = (addr) ? addr->toString().c_str() : ""; const InetAddr *netm = intf->getNetmaskPtr(); QString netm_str = (netm) ? netm->toString().c_str() : ""; s += QString("%1/%2").arg(addr_str).arg(netm_str); } s += "
"; qte->setText(s); } bool newHostDialog::validateAddressAndMask(const QString &addr, const QString &netm) { try { InetAddr(addr.toLatin1().constData()); } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", tr("Illegal address '%1/%2'").arg(addr).arg(netm), "&Continue", QString::null, QString::null, 0, 1 ); return false; } try { bool ok = false ; int ilen = netm.toInt (&ok); if (ok) { if (ilen < 0 || ilen > 32) { QMessageBox::warning( this,"Firewall Builder", tr("Illegal address '%1/%2'").arg(addr).arg(netm), "&Continue", QString::null, QString::null, 0, 1 ); return false; } } else { InetAddr(netm.toLatin1().constData()); } } catch (FWException &ex) { QMessageBox::warning( this,"Firewall Builder", tr("Illegal address '%1/%2'").arg(addr).arg(netm), "&Continue", QString::null, QString::null, 0, 1 ); return false; } return true; } void newHostDialog::cancelClicked() { QDialog::reject(); } void newHostDialog::finishClicked() { int p = currentPage(); if (p==TEMPLATES_PAGE) { QListWidgetItem *itm = m_dialog->templateList->currentItem(); FWObject *o=templates[itm]; assert (o!=NULL); FWObject *no = db->create(Host::TYPENAME); no->duplicate(o, true); no->setName(m_dialog->obj_name->text().toUtf8().constData()); mw->activeProject()->m_panel->om->autorename(no); nhst = Host::cast(no); } else { if ( !this->m_dialog->interfaceEditor->isValid() ) return; FWObject *o; o = db->create(Host::TYPENAME); o->setName(m_dialog->obj_name->text().toUtf8().constData()); if (o==NULL) { QDialog::accept(); return; } nhst = Host::cast(o); /* create interfaces */ foreach(EditedInterfaceData iface, this->m_dialog->interfaceEditor->getNewData()) { QString name = iface.name; QString label = iface.label; bool dyn = iface.type == 1; bool unnum = iface.type == 2; QString physaddr = iface.mac; Interface *oi = Interface::cast(db->create(Interface::TYPENAME)); oi->setName( string(name.toUtf8().constData()) ); oi->setLabel( string(label.toUtf8().constData()) ); oi->setComment( string(iface.comment.toUtf8().constData()) ); nhst->add(oi); if (dyn) oi->setDyn(true); if (unnum) oi->setUnnumbered(true); oi->setSecurityLevel(0); if (physaddr != "") { QString addrname=QString("%1:%2:mac") .arg(m_dialog->obj_name->text()).arg(name); physAddress* pa = physAddress::cast( db->create(physAddress::TYPENAME)); pa->setName(addrname.toUtf8().constData()); oi->add(pa); pa->setPhysAddress(physaddr.toLatin1().constData()); } if (iface.type == 0) { foreach(AddressInfo address, iface.addresses) { if (address.address == "0.0.0.0") continue; if (address.ipv4) { string addrname = string( QString("%1:%2:ip") .arg(m_dialog->obj_name->text()).arg(name).toUtf8()); IPv4 *oa = IPv4::cast(db->create(IPv4::TYPENAME)); oi->add(oa); oa->setName(addrname); oa->setAddress( InetAddr(address.address.toLatin1().constData()) ); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) { oa->setNetmask( InetAddr(inetmask) ); } else { oa->setNetmask( InetAddr(address.netmask.toLatin1().constData()) ); } } else { string addrname = string( QString("%1:%2:ip6") .arg(m_dialog->obj_name->text()).arg(name).toUtf8() ); IPv6 *oa = IPv6::cast(db->create(IPv6::TYPENAME)); oi->add(oa); oa->setName(addrname); oa->setAddress( InetAddr(AF_INET6, address.address.toLatin1().constData()) ); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) { oa->setNetmask( InetAddr(AF_INET6, inetmask) ); } else { oa->setNetmask( InetAddr(AF_INET6, address.netmask.toLatin1().constData())); } } } } } } if (unloadTemplatesLib) { delete tmpldb; tmpldb = NULL; unloadTemplatesLib=false; } QDialog::accept(); } fwbuilder-5.1.0.3599/src/libgui/iptadvanceddialog_q.ui0000644000175000017500000016126311733011756023372 0ustar sylvestresylvestre iptAdvancedDialog_q Qt::WindowModal true 0 0 1054 628 0 0 iptables: advanced settings false Help Qt::Horizontal QSizePolicy::Expanding 351 27 &OK true true &Cancel true 0 0 0 Compiler Compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 300 25 32767 22 0 0 Compiler command line options: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 25 32767 22 0 0 Output file name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true 300 25 32767 22 Qt::Horizontal 40 20 If output file name is left blank, the file name is constructed of the firewall object name and extension ".fw" true Script name on the firewall: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 300 25 32767 22 Qt::Horizontal 40 20 Generated script can be copied to the firewall machine under different name. If this field is left blank, the file name does not change. true QFrame::HLine QFrame::Sunken Qt::Horizontal 0 0 Assume firewall is part of 'any' 0 0 Detect shadowing in policy rules 0 0 Accept TCP sessions opened prior to firewall restart 0 0 Ignore empty groups in rules 0 0 Accept ESTABLISHED and RELATED packets before the first rule 0 0 Enable support for NAT of locally originated connections Drop packets that are associated with no known connection and log them 0 0 This adds a rule on top of the policy with iptables target TCPMSS and option --clamp-mss-to-pmtu. Generation of this command is version-dependent and also depends on the setting of ip or ipv6 forwarding in host settings dialog. Clamp MSS to MTU 0 0 Bridging firewall Default action on 'Reject': false Qt::Horizontal QSizePolicy::Minimum 72 20 Compiler will automatically generate rules to permit ICMP6 packets used in IPv6 Neighbor Discovery after the rules that accept ESTABLISHED,RELATE and before the rule that drops packets in state INVALID. Add rules to accept IPv6 Neighbor Discovery packets to IPv6 policies Use module "set" for run-time Address Table objects (module is only available in iptables v 1.4.1.1 and later) QFrame::HLine QFrame::Sunken Qt::Horizontal Always permit ssh access from the management workstation with this address: 0 0 32767 32767 Qt::Horizontal 40 20 Install the rule for ssh access from the management workstation when the firewall script is run with the "block" command Qt::Vertical QSizePolicy::Expanding 20 20 Installer 6 Built-in installer 6 Directory on the firewall where script should be installed Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 250 0 User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 250 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 250 0 A command that installer should execute on the firewall in order to activate the policy (if this field is blank, installer runs firewall script in the directory specified above; it uses sudo if user name is not 'root') Qt::AlignVCenter true 0 0 250 0 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 External install script 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Qt::Vertical QSizePolicy::Expanding 20 100 Prolog/Epilog 6 6 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 The following commands will be added verbatim after generated configuration Qt::AlignVCenter true 6 The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Edit Insert prolog script false 0 0 on top of the script after interface configuration after policy reset Logging 6 20 true false 20 12 use ULOG use LOG 0 0 log TCP seq. numbers log IP options use numeric syslog levels Log level: false log TCP options 0 1500 cprange false 1 queue threshold: false netlink group: false 1 32 Qt::Vertical QSizePolicy::Expanding 20 16 0 0 QFrame::VLine QFrame::Sunken Qt::Vertical 0 0 Log prefix: false 32 Logging limit: false 10000 0 0 Activate logging in all rules (overrides rule options, use for debugging) Qt::Vertical QSizePolicy::Expanding 20 40 Qt::Vertical QSizePolicy::Expanding 20 16 Script Qt::Horizontal QSizePolicy::Fixed 30 20 0 0 Load iptables modules Qt::Vertical QSizePolicy::Fixed 556 18 If debugging is turned on, the script will run with shell option "-x" that makes it print every command it executes. Warning: this produces a lot of debugging output. true 0 0 Turn debugging on in generated script Qt::Vertical QSizePolicy::Fixed 556 18 Managing interfaces and addresses 0 0 Verify interfaces before loading firewall policy 0 0 Configure Interfaces of the firewall machine Clear ip addresses and bring down interfaces not configured in fwbuilder 0 0 Configure VLAN Interfaces 0 0 Configure bridge Interfaces 0 0 Configure bonding Interfaces 0 0 Add virtual addresses for NAT Qt::Vertical QSizePolicy::Fixed 556 40 Generated script can load rules one by one by calling iptables command line utility, or activate them all at once using iptables-restore. In both cases you just run the script with command line parameter "start" to activate the policy, the script will use iptables-restore automatically if this checkbox is on true 0 0 iptables-restore replaces firewall policy in one atomic transaction Use iptables-restore to activate policy Qt::Vertical QSizePolicy::Expanding 20 200 IPv6 6 The order in which ipv4 and ipv6 rules should be generated: IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 Qt::Horizontal 40 20 tabWidget assumeFwIsPartOfAny acceptSessions acceptESTBeforeFirst dropInvalid logInvalid bridge actionOnReject shadowing emptyGroups localNAT clampMSStoMTU ipv6NeighborDiscovery mgmt_ssh mgmt_addr add_mgmt_ssh_rule_when_stoped ipt_fw_dir ipt_user altAddress activationCmd sshArgs scpArgs installScript installScriptArgs prolog_script prologPlace edit_prolog_button epilog_script edit_epilog_button useLOG useULOG logTCPseq logTCPopt logIPopt logNumsyslog logLevel logprefix logLimitVal logLimitSuffix logAll loadModules iptDebug verifyInterfaces configureInterfaces clearUnknownInterfaces configure_vlan_interfaces configure_bridge_interfaces configure_bonding_interfaces addVirtualsforNAT iptablesRestoreActivation ipv4before buttonHelp buttonOk buttonCancel cprange qthreshold nlgroup buttonOk clicked() iptAdvancedDialog_q accept() 757 700 20 20 buttonCancel clicked() iptAdvancedDialog_q reject() 843 700 20 20 useLOG toggled(bool) iptAdvancedDialog_q switchLOG_ULOG() 45 66 20 20 edit_prolog_button clicked() iptAdvancedDialog_q editProlog() 822 329 20 20 edit_epilog_button clicked() iptAdvancedDialog_q editEpilog() 822 633 20 20 buttonHelp clicked() iptAdvancedDialog_q help() 30 700 20 20 fwbuilder-5.1.0.3599/src/libgui/findDialog.h0000644000175000017500000000356511733011756021262 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FINDDIALOG_H_ #define __FINDDIALOG_H_ #include "config.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class findDialog : public QDialog { Q_OBJECT; QString lastTextSearch; QString lastAttrSearch; libfwbuilder::FWObject *lastFound; libfwbuilder::FWObject::tree_iterator treeSeeker; bool matchName(const QString &name); bool matchAttr(libfwbuilder::FWObject* obj); ProjectPanel *m_project; public: Ui::findDialog_q *m_dialog; findDialog(QWidget *p, ProjectPanel *project); void setObject(libfwbuilder::FWObject *o); ~findDialog() { delete m_dialog; }; public slots: virtual void find(); virtual void findNext(); virtual void reset(); virtual void findTextChanged(const QString&); virtual void findAttrChanged(const QString&); void makeActive(); protected: virtual void showEvent( QShowEvent *ev); virtual void hideEvent( QHideEvent *ev); }; #endif // __FINDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/Help.h0000644000175000017500000000357411733011756020112 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __HELP_H_ #define __HELP_H_ #include "config.h" #include "ui_helpview_q.h" #include "HttpGet.h" #include "global.h" #include "FWWindow.h" #include #include #include #include #include #include class Help : public QDialog { Q_OBJECT; QStringList paths; QByteArray window_geometry; Qt::WindowFlags flags; bool load_links_in_browser; HttpGet *http_getter; bool delayed_open; public: Ui::HelpView_q *m_dialog; Help(QWidget *parent, const QString &title, bool load_links_in_browser=true); virtual ~Help(); void setSource(const QUrl &url); QString findHelpFile(const QString &file_base_name); void setName(const QString &name); virtual void closeEvent(QCloseEvent *event); virtual void hideEvent(QHideEvent *event); virtual void showEvent(QShowEvent *event); static Help* getHelpWindow(QWidget *parent); static Help* help_window; public slots: void downloadComplete(const QString&); void show(); }; #endif fwbuilder-5.1.0.3599/src/libgui/instDialog_installer.cpp0000644000175000017500000001502111733011756023715 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "CompilerDriver.h" #include "FWBSettings.h" #include "FWWindow.h" #include "FirewallInstallerCisco.h" #include "FirewallInstallerProcurve.h" #include "FirewallInstallerUnx.h" #include "events.h" #include "instBatchOptionsDialog.h" #include "instDialog.h" #include "instOptionsDialog.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; bool instDialog::runInstaller(Firewall *fw, bool installing_many_firewalls) { cnf.fwobj = fw; cnf.maddr = ""; if (fwbdebug) qDebug() << "instDialog::runInstaller: built-in installer" << fw->getName().c_str() << " cnf.user=" << cnf.user; if (!getInstOptions(fw, installing_many_firewalls)) { QTimer::singleShot( 0, this, SLOT(mainLoopInstall())); this->opCancelled(fw); return false; } // args.clear(); /* need to save settings so that if the user just changed ssh/scp, the * wrapper will pick changes up */ st->save(); summary(); if (checkSSHPathConfiguration(fw)) { setTitle( 1, QObject::tr("Installing policy rules on firewall '%1'"). arg(QString::fromUtf8(fw->getName().c_str() ))); currentSearchString = tr("Install firewall: "); currentFirewallsBar->setValue(install_list_initial_size - install_fw_list.size()); currentProgressBar->reset(); currentProgressBar->setFormat("%v/%m"); QTreeWidgetItem* item = opListMapping[fw->getId()]; assert(item!=NULL); currentFWLabel->setText(QString::fromUtf8(fw->getName().c_str())); m_dialog->fwWorkList->scrollToItem(item); setInProcessState(item); item->setText(1, tr("Installing ...")); currentLabel->setText(tr("Installing ...")); qApp->processEvents(); addToLog("\n"); if (fwbdebug) qDebug() << "instDialog::runInstaller:" << " cnf.user=" << cnf.user; if (installer!=NULL) delete installer; if (isCiscoFamily()) installer = new FirewallInstallerCisco(this, &cnf, fwb_prompt); else { if (isProcurve()) installer = new FirewallInstallerProcurve(this, &cnf, fwb_prompt); else installer = new FirewallInstallerUnx(this, &cnf, fwb_prompt); } if (!installer->packInstallJobsList(fw)) { QTimer::singleShot( 0, this, SLOT(mainLoopInstall())); return false; } currentProgressBar->setValue(0); disconnect(currentStopButton, SIGNAL(clicked())); connect(currentStopButton, SIGNAL(clicked()), this, SLOT(stopInstall())); installer->runJobs(); } else { opListMapping[fw->getId()]->setText(1, tr("Failure")); setFailureState(opListMapping[fw->getId()]); addToLog("Firewall policy installation failed\n"); QTimer::singleShot( 0, this, SLOT(mainLoopInstall())); } return true; } void instDialog::stopInstall() { currentStopButton->setEnabled(false); disconnect(currentStopButton, SIGNAL(clicked())); stopProcessFlag = true; // likely unused proc.terminate(); // try to close proc. QTimer::singleShot(1000, &proc, SLOT(kill())); //if it doesn't respond, kill it if (installer != NULL) { if (fwbdebug) qDebug() << "instDialog::stopInstall killing installer"; installer->terminate(); delete installer; installer = NULL; } // to terminate whole install sequence rather than just current // process, clear the list. for (list::iterator i=install_fw_list.begin(); i!=install_fw_list.end(); ++i) opCancelled(*i); install_fw_list.clear(); setFinishEnabled(currentPage(), true); } void instDialog::installerFinished(int ret_code, QProcess::ExitStatus status) { if( fwbdebug) qDebug("instDialog::installerFinished " "exit code = %d exit_status=%d", ret_code, status); // run readFromStdout() and processEvents() to make sure all // events that pass output from the external installer script have // been processed. Otherwise the output from the next installer // pass in batch install mixes with the tail of the output from // the previous one. readFromStdout(); qApp->processEvents(); if (ret_code==0 && status==QProcess::NormalExit) installerSuccess(); else installerError(); } void instDialog::installerSuccess() { opSuccess(cnf.fwobj); // project->updateLastInstalledTimestamp(cnf.fwobj); QCoreApplication::postEvent( mw, new updateLastInstalledTimestampEvent(project->db()->getFileName().c_str(), cnf.fwobj->getId())); currentProgressBar->setValue(currentProgressBar->maximum()); addToLog("Firewall policy successfully installed\n"); QTimer::singleShot( 1000, this, SLOT(mainLoopInstall())); } void instDialog::installerError() { opError(cnf.fwobj); currentProgressBar->setValue(currentProgressBar->maximum()); opListMapping[cnf.fwobj->getId()]->setText(1, tr("Failure")); addToLog("Firewall policy installation failed\n"); QTimer::singleShot( 0, this, SLOT(mainLoopInstall())); } fwbuilder-5.1.0.3599/src/libgui/ObjectEditor.cpp0000644000175000017500000003066111733011756022127 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "ObjectEditor.h" #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "BaseObjectDialog.h" #include "FirewallDialog.h" #include "InterfaceDialog.h" #include "DialogFactory.h" #include "FWBTree.h" #include "ProjectPanel.h" #include "FWBSettings.h" #include "GroupObjectDialog.h" #include "ActionsDialog.h" #include "MetricEditorPanel.h" #include "CommentEditorPanel.h" #include "ObjectManipulator.h" #include "Help.h" #include "events.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Host.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Interface.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Rule.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include using namespace std; using namespace libfwbuilder; #define OBJTREEVIEW_WIDGET_NAME "ObjTreeView" ObjectEditor::ObjectEditor( QWidget *parent): QObject(parent), opened(0), current_dialog_idx(-1), current_dialog_name(""), editorStack(dynamic_cast(parent)), m_project(0), openedOpt(optNone) { /* * To add a dialog for the new object type: * * - In Designer: * - create new dialog, inherit from QWidget, e.g. class FooDialog * - add new page to objectEditorStack in FWBMainWindow_q * - drop QWidget into this page * - promote this widget to class FooDialog, include file FooDialog.h * - set name of this widget to "w_FooDialog" * - add grid layout to the stack page, set all margins to 0 * - Add call to registerObjectDialog() here using name "w_FooDialog" */ registerObjectDialog(editorStack, Firewall::TYPENAME, "w_FirewallDialog"); registerObjectDialog(editorStack, Interface::TYPENAME, "w_InterfaceDialog"); registerObjectDialog(editorStack, UserService::TYPENAME, "w_UserDialog"); registerObjectDialog(editorStack, Policy::TYPENAME, "w_PolicyDialog"); registerObjectDialog(editorStack, NAT::TYPENAME, "w_NATDialog"); registerObjectDialog(editorStack, Routing::TYPENAME, "w_RoutingDialog"); registerObjectDialog(editorStack, Library::TYPENAME, "w_LibraryDialog"); registerObjectDialog(editorStack, IPv4::TYPENAME, "w_IPv4Dialog"); registerObjectDialog(editorStack, IPv6::TYPENAME, "w_IPv6Dialog"); registerObjectDialog(editorStack, physAddress::TYPENAME, "w_PhysicalAddressDialog"); registerObjectDialog(editorStack, AddressRange::TYPENAME, "w_AddressRangeDialog"); registerObjectDialog(editorStack, Cluster::TYPENAME, "w_ClusterDialog"); registerObjectDialog(editorStack, FailoverClusterGroup::TYPENAME, "w_FailoverClusterGroupDialog"); registerObjectDialog(editorStack, StateSyncClusterGroup::TYPENAME, "w_StateSyncClusterGroupDialog"); registerObjectDialog(editorStack, Host::TYPENAME, "w_HostDialog"); registerObjectDialog(editorStack, AttachedNetworks::TYPENAME, "w_AttachedNetworksDialog"); registerObjectDialog(editorStack, Network::TYPENAME, "w_NetworkDialog"); registerObjectDialog(editorStack, NetworkIPv6::TYPENAME, "w_NetworkDialogIPv6"); registerObjectDialog(editorStack, CustomService::TYPENAME, "w_CustomServiceDialog"); registerObjectDialog(editorStack, IPService::TYPENAME, "w_IPServiceDialog"); registerObjectDialog(editorStack, ICMPService::TYPENAME, "w_ICMPServiceDialog"); registerObjectDialog(editorStack, ICMP6Service::TYPENAME, "w_ICMP6ServiceDialog"); registerObjectDialog(editorStack, TCPService::TYPENAME, "w_TCPServiceDialog"); registerObjectDialog(editorStack, UDPService::TYPENAME, "w_UDPServiceDialog"); registerObjectDialog(editorStack, TagService::TYPENAME, "w_TagServiceDialog"); registerObjectDialog(editorStack, ServiceGroup::TYPENAME, "w_ServiceGroupDialog"); registerObjectDialog(editorStack, ObjectGroup::TYPENAME, "w_ObjectGroupDialog"); registerObjectDialog(editorStack, DynamicGroup::TYPENAME, "w_DynamicGroupDialog"); registerObjectDialog(editorStack, IntervalGroup::TYPENAME, "w_IntervalGroupDialog"); registerObjectDialog(editorStack, Interval::TYPENAME, "w_TimeDialog"); registerObjectDialog(editorStack, RoutingRule::TYPENAME, "w_RoutingRuleOptionsDialog"); registerObjectDialog(editorStack, PolicyRule::TYPENAME, "w_RuleOptionsDialog"); registerObjectDialog(editorStack, NATRule::TYPENAME, "w_NATRuleOptionsDialog"); registerObjectDialog(editorStack, AddressTable::TYPENAME, "w_AddressTableDialog"); registerObjectDialog(editorStack, DNSName::TYPENAME, "w_DNSNameDialog"); registerOptDialog(editorStack, optAction, "w_ActionsDialog"); registerOptDialog(editorStack, optComment, "w_CommentEditorPanel"); registerOptDialog(editorStack, optMetric, "w_MetricEditorPanel"); //registerOptDialog(editorStack, optRuleCompile, "w_CompilerOutputPanel"); registerObjectDialog(editorStack, "BLANK", "w_BlankDialog"); // BaseObjectDialog *w = new BaseObjectDialog(parent); // stackIds["BLANK"] = editorStack->addWidget(w); // dialogs[stackIds["BLANK"]] = w; } void ObjectEditor::registerObjectDialog(QStackedWidget *stack, const QString &obj_type, const QString &dialog_name) { BaseObjectDialog *w = qFindChild(stack, dialog_name); if (w==NULL) { qDebug() << "Dialog widget missing for the object type " << obj_type << " Expected the following name for the dialog object: " << dialog_name; } assert(w); int dlg_id = stack->indexOf(w->parentWidget()); stackIds[obj_type] = dlg_id; dialogs[dlg_id] = w; } void ObjectEditor::registerOptDialog(QStackedWidget *stack, ObjectEditor::OptType opt_type, const QString &dialog_name) { BaseObjectDialog *w = qFindChild(stack, dialog_name); if (w==NULL) { qDebug() << "Dialog widget missing for the option " << opt_type << " Expected the following name for the dialog object: " << dialog_name; } assert(w); int dlg_id = stack->indexOf(w->parentWidget()); stackIds[getOptDialogName(opt_type)] = dlg_id; dialogs[dlg_id] = w; } void ObjectEditor::attachToProjectWindow(ProjectPanel *pp) { if (fwbdebug) qDebug() << "ObjectEditor::attachToProjectWindow pp=" << pp; m_project = pp; QMapIterator it(dialogs); while (it.hasNext()) { it.next(); it.value()->attachToProjectWindow(pp); } } QWidget* ObjectEditor::getCurrentObjectDialog() { if (current_dialog_idx >= 0) return dialogs[current_dialog_idx]; else return NULL; } QString ObjectEditor::getOptDialogName(OptType t) { return QString("OptionDialog_%1").arg(t); } void ObjectEditor::activateDialog(const QString &dialog_name, FWObject *obj, enum OptType opt) { disconnectSignals(); current_dialog_name = dialog_name; current_dialog_idx = stackIds[current_dialog_name]; editorStack->setCurrentIndex(current_dialog_idx); connect(this, SIGNAL(loadObject_sign(libfwbuilder::FWObject*)), dialogs[ current_dialog_idx ], SLOT(loadFWObject(libfwbuilder::FWObject*))); opened = obj; openedOpt = opt; load(); //show(); connect(this, SIGNAL(validate_sign(bool*)), dialogs[ current_dialog_idx ], SLOT(validate(bool*))); connect(this, SIGNAL(applyChanges_sign()), dialogs[ current_dialog_idx ], SLOT(applyChanges())); connect(dialogs[ current_dialog_idx ], SIGNAL(changed_sign()), this, SLOT(changed())); } void ObjectEditor::open(FWObject *obj) { if (stackIds.count(obj->getTypeName().c_str())!=0) { if (fwbdebug) qDebug() << "ObjectEditor::open obj=" << obj << QString((obj)?obj->getName().c_str():"") << QString((obj)?obj->getTypeName().c_str():""); activateDialog(obj->getTypeName().c_str(), obj, optNone); } else blank(); } void ObjectEditor::openOpt(FWObject *obj, OptType t) { if (stackIds.count(getOptDialogName(t))!=0) { if (fwbdebug) qDebug() << "ObjectEditor::openOpt obj=" << obj << QString((obj)?obj->getName().c_str():"") << QString((obj)?obj->getTypeName().c_str():"") << "t=" << t; if (Rule::cast(obj)==NULL) return; activateDialog(getOptDialogName(t), obj, t); } else blank(); } void ObjectEditor::disconnectSignals() { disconnect( SIGNAL(loadObject_sign(libfwbuilder::FWObject*)) ); disconnect( SIGNAL(validate_sign(bool*)) ); disconnect( SIGNAL(applyChanges_sign()) ); if (current_dialog_idx>=0) dialogs[current_dialog_idx]->disconnect( this ); } void ObjectEditor::purge() { if (fwbdebug) qDebug("ObjectEditor::purge"); activateDialog("BLANK", NULL, optNone); openedOpt = optNone; } void ObjectEditor::load() { emit loadObject_sign(opened); } void ObjectEditor::changed() { QWidget *s = dynamic_cast(sender()); if (fwbdebug) qDebug() << "ObjectEditor::changed() from " << s << "isVisible()=" << s->isVisible(); if (!validate()) { // change is not good, reload data into the editor to clear and reset it. load(); return; } emit applyChanges_sign(); if (!s->isVisible()) { /* * Pass focus to the ProjectPanel that is active at the moment * to avoid switch described in #2335. Do this only if editor * panel is invisible because we get changed() signal in other * cases too, such as when user uses Tab to switch between * input fields or clicks outside the editor. */ ProjectPanel *pp = mw->activeProject(); if (fwbdebug) qDebug() << "ObjectEditor::changed() pass focus to active ProjectPanel" << "pp=" << pp; if (pp) pp->setFocus(Qt::OtherFocusReason); } if (fwbdebug) qDebug() << "ObjectEditor::changed() done "; } bool ObjectEditor::validate() { if (fwbdebug) qDebug() << "ObjectEditor::validate()" << "isVisible()=" << getCurrentObjectDialog()->isVisible(); bool isgood = true; emit validate_sign( &isgood ); return isgood; } void ObjectEditor::blank() { if (fwbdebug) qDebug() << "ObjectEditor::blank()"; purge(); } fwbuilder-5.1.0.3599/src/libgui/fwbuilder_ph.h0000755000175000017500000000753211733011756021675 0ustar sylvestresylvestre #include #include #include #include #include #include #include #if defined __cplusplus #include "definitions.h" #include "global.h" #include "utils.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Address.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/BackgroundOp.h" #include "fwbuilder/Constants.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/InetAddrMask.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Library.h" #include "fwbuilder/Logger.h" #include "fwbuilder/Management.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/Tools.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/physAddress.h" // QT #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // STL #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif fwbuilder-5.1.0.3599/src/libgui/QThreadLogger.cpp0000644000175000017500000000345011733011756022236 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "QThreadLogger.h" #include #include #include using namespace std; using namespace libfwbuilder; QThreadLogger::QThreadLogger() : Logger() {} Logger& QThreadLogger::operator<< (char c) { emit lineReady(QString(c)); return *this; } Logger& QThreadLogger::operator<< (char *str) { emit lineReady(QString(str)); return *this; } Logger& QThreadLogger::operator<< (const char *str) { emit lineReady(QString(str)); return *this; } Logger& QThreadLogger::operator<< (const std::string &str) { emit lineReady(QString(str.c_str())); return *this; } Logger& QThreadLogger::operator<< (int i ) { QString s; s.setNum(i); emit lineReady(s); return *this; } Logger& QThreadLogger::operator<< (long l ) { QString s; s.setNum(l); emit lineReady(s); return *this; } Logger& QThreadLogger::operator<< (std::ostringstream &sstr) { emit lineReady(QString(sstr.str().c_str())); return *this; } fwbuilder-5.1.0.3599/src/libgui/macosxAdvancedDialog.cpp0000644000175000017500000000660311733011756023611 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "macosxAdvancedDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; macosxAdvancedDialog::~macosxAdvancedDialog() { delete m_dialog; } macosxAdvancedDialog::macosxAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::macosxAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption( m_dialog->macosx_ip_forward, fwopt, "macosx_ip_forward", threeStateMapping); data.registerOption( m_dialog->macosx_ip_redirect, fwopt, "macosx_ip_redirect", threeStateMapping); data.registerOption( m_dialog->macosx_ip_sourceroute, fwopt, "macosx_ip_sourceroute", threeStateMapping); data.registerOption( m_dialog->macosx_path_ipfw, fwopt, "macosx_path_ipfw"); data.registerOption( m_dialog->macosx_path_sysctl, fwopt, "macosx_path_sysctl"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void macosxAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void macosxAdvancedDialog::reject() { QDialog::reject(); } fwbuilder-5.1.0.3599/src/libgui/ObjConflictResolutionDialog.h0000644000175000017500000000621411733011756024614 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJCONFLICTRESOLUTIONDIALOG_H_ #define __OBJCONFLICTRESOLUTIONDIALOG_H_ #include #include "fwbuilder/FWObjectDatabase.h" #include namespace libfwbuilder { class FWObject; }; class ObjConflictResolutionDialog : public QDialog { Q_OBJECT bool alwaysCurrent; bool alwaysNew; protected: QString current_filename; QString new_filename; QString current_objname; QString new_objname; QString current_properties; QString new_properties; QString defaultLeftButtonText; QString defaultRightButtonText; bool richText; void saveGeometry(); QString makeBold(const QString &str); public: Ui::ObjConflictResolutionDialog_q *m_dialog; ObjConflictResolutionDialog(QWidget *parent); virtual ~ObjConflictResolutionDialog(); virtual int run( libfwbuilder::FWObject *o1, libfwbuilder::FWObject *o2); public slots: virtual void closeEvent(QCloseEvent *e); void setFlags(); protected slots: virtual void accept(); virtual void reject(); }; class MergeConflictRes : public libfwbuilder::FWObjectDatabase::ConflictResolutionPredicate, ObjConflictResolutionDialog { public: MergeConflictRes(QWidget *p) : ObjConflictResolutionDialog(p) {} virtual bool askUser(libfwbuilder::FWObject *o1,libfwbuilder::FWObject *o2) { int res=run(o1,o2); return (res==QDialog::Accepted); } }; class CompareObjectsDialog : public libfwbuilder::FWObjectDatabase::ConflictResolutionPredicate, ObjConflictResolutionDialog { std::list report; QStringList report_attributes; int num_conflicts; int column_width[4]; void writeColumn(std::ostringstream &sstr, int column_num, const QString &txt); public: CompareObjectsDialog(QWidget *p); virtual int run( libfwbuilder::FWObject *o1, libfwbuilder::FWObject *o2); void clearReport(); std::list getReport(); int getNumberOfConflicts() { return num_conflicts; } virtual bool askUser(libfwbuilder::FWObject *o1,libfwbuilder::FWObject *o2) { run(o1,o2); return QDialog::Accepted; } }; #endif fwbuilder-5.1.0.3599/src/libgui/NetworkDialogIPv6.h0000644000175000017500000000273411733011756022475 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NETWORKDIALOGIPV6_H_ #define __NETWORKDIALOGIPV6_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class NetworkDialogIPv6 : public BaseObjectDialog { Q_OBJECT; Ui::NetworkDialogIPv6_q *m_dialog; public: NetworkDialogIPv6(QWidget *parent); ~NetworkDialogIPv6(); public slots: virtual void changed(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void addressEntered(); }; #endif // NETWORKDIALOG_H fwbuilder-5.1.0.3599/src/libgui/ObjectIconView.h0000644000175000017500000000343211733011756022065 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTICONVIEW_H_ #define __OBJECTICONVIEW_H_ #include #include namespace libfwbuilder { class FWObject; class FWObjectDatabase; }; class ObjectIconView : public QListWidget { Q_OBJECT ; libfwbuilder::FWObjectDatabase *db; bool startingDrag; protected: virtual QDrag* dragObject(); virtual void dragEnterEvent( QDragEnterEvent *ev); virtual void dropEvent(QDropEvent *ev); virtual void dragMoveEvent( QDragMoveEvent *ev); virtual void keyPressEvent( QKeyEvent* ev ); void mousePressEvent ( QMouseEvent * event ); void mouseMoveEvent ( QMouseEvent * event ); bool event ( QEvent * event ); public: ObjectIconView(QWidget* parent, const char * name = 0, Qt::WindowFlags f = 0); void setDB(libfwbuilder::FWObjectDatabase *_db) { db = _db; } signals: void delObject_sign(); void dropped(QDropEvent *ev); }; #endif fwbuilder-5.1.0.3599/src/libgui/FWObjectPropertiesFactory.cpp0000644000175000017500000014307011733011756024621 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils_no_qt.h" #include "utils.h" #include #include #include #include #include #include "FWObjectPropertiesFactory.h" #include "platforms.h" #include "DialogFactory.h" #include "FWBTree.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/DynamicGroup.h" #include "fwbuilder/FWException.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Group.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Interval.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include "fwbuilder/physAddress.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Cluster.h" #include #include #include using namespace std; using namespace libfwbuilder; /* * This method returns brief summary of properties, guaranteed to be 1 * line of text */ QString FWObjectPropertiesFactory::getObjectPropertiesBrief(FWObject *obj) { QString res; QTextStream str(&res, QIODevice::WriteOnly); FWObject *parent_obj = obj->getParent(); try { if (Library::isA(obj)) { if (obj->isReadOnly()) str << "(read only)"; } else if (IPv4::isA(obj)) { str << IPv4::cast(obj)->getAddressPtr()->toString().c_str(); if (parent_obj && Interface::isA(parent_obj)) { str << "/"; str << IPv4::cast(obj)->getNetmaskPtr()->toString().c_str(); } } else if (IPv6::isA(obj)) { str << IPv6::cast(obj)->getAddressPtr()->toString().c_str(); if (parent_obj && Interface::isA(parent_obj)) { str << "/"; str << QString("%1").arg(IPv6::cast(obj)->getNetmaskPtr()->getLength()); } } else if (physAddress::isA(obj)) { str << physAddress::cast(obj)->getPhysAddress().c_str(); } else if (DNSName::isA(obj)) { str << DNSName::cast(obj)->getSourceName().c_str(); } else if (AddressTable::isA(obj)) { str << AddressTable::cast(obj)->getSourceName().c_str(); } else if (AddressRange::isA(obj)) { AddressRange *ar=AddressRange::cast(obj); str << ar->getRangeStart().toString().c_str(); str << " - "; str << ar->getRangeEnd().toString().c_str(); } else if (Firewall::cast(obj)) { if (Firewall::cast(obj)->needsCompile()) str << " * "; QString platform = obj->getStr("platform").c_str(); QString version = obj->getStr("version").c_str(); QString readableVersion = getVersionString(platform,version); QString hostOS = obj->getStr("host_OS").c_str(); str << platform << "(" << readableVersion << ") / " << hostOS; } else if (Host::isA(obj)) { const InetAddr *addr = Address::cast(obj)->getAddressPtr(); if (addr) str << addr->toString().c_str(); else str << "(no ip address)"; } else if (Network::isA(obj)) { Network *n=Network::cast(obj); str << n->getAddressPtr()->toString().c_str(); str << "/"; str << n->getNetmaskPtr()->toString().c_str(); } else if (NetworkIPv6::isA(obj)) { NetworkIPv6 *n=NetworkIPv6::cast(obj); str << n->getAddressPtr()->toString().c_str(); str << "/"; str << QString("%1").arg(n->getNetmaskPtr()->getLength()); } else if (ClusterGroup::cast(obj)!=NULL) { ClusterGroup *g = ClusterGroup::cast(obj); str << QObject::tr("type: ") << g->getStr("type").c_str(); } else if (Group::cast(obj)!=NULL) // just any group { Group *g=Group::cast(obj); str << g->size() << " " << QObject::tr(" objects"); } else if (Interface::isA(obj)) { Interface *intf = Interface::cast(obj); // trigger late initialization of options object // if its read-only or part of the read-only tree, I can't help it. if (!obj->isReadOnly()) intf->getOptionsObject(); str << intf->getLabel().c_str() << " "; QStringList q; FWObject *parent = Host::getParentHost(intf); //FWObject *parent = intf->getParentHost(); if (parent) { bool supports_security_levels = false; bool supports_network_zones = false; try { supports_security_levels = (!parent->getStr("platform").empty() && Resources::getTargetCapabilityBool( parent->getStr("platform"), "security_levels")); supports_network_zones = (!parent->getStr("platform").empty() && Resources::getTargetCapabilityBool( parent->getStr("platform"), "network_zones")); } catch (FWException &ex) { } if (supports_security_levels) { QString str; str.setNum(intf->getSecurityLevel()); q.push_back(QString("sec level: %1").arg(str)); } if (supports_network_zones) { int id = FWObjectDatabase::getIntId(intf->getStr("network_zone")); if (id > 0) { FWObject *nz_obj = obj->getRoot()->findInIndex(id); if (nz_obj) q.push_back( QString("network zone: %1") .arg(nz_obj->getName().c_str())); else q.push_back(QString("network zone: not configured")); } } } if (intf->isDyn()) q.push_back("dyn"); if (intf->isUnnumbered()) q.push_back("unnum"); if (intf->isDedicatedFailover()) q.push_back("failover"); if (intf->isBridgePort()) q.push_back("bridge port"); if (intf->isSlave()) q.push_back("slave"); if (intf->isUnprotected()) q.push_back("unp"); if (!q.empty()) str << q.join(","); } else if (IPService::isA(obj)) { str << QObject::tr("protocol: %1").arg(obj->getStr("protocol_num").c_str()); } else if (ICMPService::isA(obj) || ICMP6Service::isA(obj)) { str << QObject::tr("type: %1").arg(obj->getStr("type").c_str()) << " " << QObject::tr("code: %1").arg(obj->getStr("code").c_str()); } else if (TCPService::isA(obj) || UDPService::isA(obj)) { int sps,spe,dps,dpe; sps=TCPUDPService::cast(obj)->getSrcRangeStart(); spe=TCPUDPService::cast(obj)->getSrcRangeEnd(); dps=TCPUDPService::cast(obj)->getDstRangeStart(); dpe=TCPUDPService::cast(obj)->getDstRangeEnd(); str << sps << ":" << spe << " / "; str << dps << ":" << dpe; } else if (TagService::isA(obj)) { str << "Pattern: \"" << obj->getStr("tagcode").c_str() << "\"" ; } else if (UserService::isA(obj)) { const UserService* user_srv = UserService::constcast(obj); str << "User id: \"" << user_srv->getUserId().c_str() << "\"" ; } else if (RuleSet::cast(obj) != NULL) { QStringList attrs; RuleSet *rs = RuleSet::cast(obj); if (rs->isTop()) attrs.push_back("top ruleset"); if (rs->isDual()) attrs.push_back("ipv4/ipv6"); else { if (rs->isV4()) attrs.push_back("ipv4"); if (rs->isV6()) attrs.push_back("ipv6"); } attrs.push_back(QString("%1 rules").arg(rs->getRuleSetSize())); str << attrs.join(" "); } else if (Interval::isA(obj)) { } } catch (FWException &ex) { cerr << ex.toString() << endl; } return QString::fromUtf8(res.toStdString().c_str()); } /* * More detailed list of properties, still one line, no fancy * formatting and no HTML. This is used in object group list view and * for printing. */ QString FWObjectPropertiesFactory::getObjectProperties(FWObject *obj) { QString res; QTextStream str(&res, QIODevice::WriteOnly); FWObject *parent_obj = obj->getParent(); try { if (IPv4::isA(obj)) { str << IPv4::cast(obj)->getAddressPtr()->toString().c_str(); if (parent_obj && Interface::isA(parent_obj)) { str << "/"; str << IPv4::cast(obj)->getNetmaskPtr()->toString().c_str(); } } else if (IPv6::isA(obj)) { str << IPv6::cast(obj)->getAddressPtr()->toString().c_str(); if (parent_obj && Interface::isA(parent_obj)) { str << "/"; str << QString("%1").arg(IPv6::cast(obj)->getNetmaskPtr()->getLength()); } } else if (physAddress::isA(obj)) { str << physAddress::cast(obj)->getPhysAddress().c_str(); } else if (DNSName::isA(obj)) { str << QObject::tr("DNS record: ") << DNSName::cast(obj)->getSourceName().c_str(); } else if (AddressTable::isA(obj)) { str << QObject::tr("Address Table: ") << AddressTable::cast(obj)->getSourceName().c_str(); } else if (AddressRange::isA(obj)) { AddressRange *ar=AddressRange::cast(obj); str << ar->getRangeStart().toString().c_str(); str << " - "; str << ar->getRangeEnd().toString().c_str(); } else if (Firewall::cast(obj)) { QString platform = obj->getStr("platform").c_str(); QString version = obj->getStr("version").c_str(); QString readableVersion = getVersionString(platform,version); QString hostOS = obj->getStr("host_OS").c_str(); QDateTime dt; time_t t; t = obj->getInt("lastModified");dt.setTime_t(t); QString t_modified = (t)? dt.toString():"-"; t = obj->getInt("lastCompiled");dt.setTime_t(t); QString t_compiled = (t)? dt.toString():"-"; t = obj->getInt("lastInstalled");dt.setTime_t(t); QString t_installed = (t)? dt.toString():"-"; str << platform << "(" << readableVersion << ") / " << hostOS; } else if (Host::isA(obj)) { const InetAddr *addr = Address::cast(obj)->getAddressPtr(); if (addr) str << addr->toString().c_str(); else str << "(no ip address)"; FWObject *co=obj->getFirstByType("Interface"); if (co!=NULL) { physAddress *paddr=(Interface::cast(co))->getPhysicalAddress(); if (paddr!=NULL) str << " " << paddr->getPhysAddress().c_str(); } } else if (Network::isA(obj)) { Network *n=Network::cast(obj); str << QString("%1/%2") .arg(n->getAddressPtr()->toString().c_str()) .arg(n->getNetmaskPtr()->toString().c_str()); } else if (NetworkIPv6::isA(obj)) { NetworkIPv6 *n=NetworkIPv6::cast(obj); str << QString("%1/%2") .arg(n->getAddressPtr()->toString().c_str()) .arg(n->getNetmaskPtr()->getLength()); } else if (ClusterGroup::cast(obj)!=NULL) { ClusterGroup *g = ClusterGroup::cast(obj); str << QObject::tr("Type: ") << g->getStr("type").c_str() << " "; QStringList members; FWObjectTypedChildIterator j = obj->findByType(FWObjectReference::TYPENAME); for ( ; j!=j.end(); ++j) { FWObject *obj = FWReference::getObject(*j); if (Interface::cast(obj)) { FWObject *fw = obj->getParent(); members.push_back( QString("%1:%2") .arg(fw->getName().c_str()).arg(obj->getName().c_str())); } } if (members.size() != 0) { members.push_front(QObject::tr("Members:")); str << members.join(" "); } } else if (DynamicGroup::cast(obj) != 0) { DynamicGroup *objGroup = DynamicGroup::cast(obj); str << QObject::tr("%1 filters").arg(objGroup->getFilter().size()); } else if (Group::cast(obj)!=NULL) // just any group { Group *g=Group::cast(obj); str << QObject::tr("%1 objects").arg(g->size()); } else if (Firewall::cast(obj)) { } else if (Interface::isA(obj)) { Interface *intf = Interface::cast(obj); QString label = QString::fromUtf8(intf->getLabel().c_str()); if (label != "") str << QObject::tr("Label: %1").arg(label) << " "; QString intf_type = intf->getOptionsObject()->getStr("type").c_str(); if (intf_type != "" && intf_type.toLower() != "ethernet") str << QObject::tr("Type: ") << intf_type << " "; QStringList addr; FWObjectTypedChildIterator j = obj->findByType(IPv4::TYPENAME); for ( ; j!=j.end(); ++j) { addr << getObjectProperties(*j); } if (addr.size() != 0) { if (addr.size() > 1) addr.push_front(QObject::tr("Addresses:")); else addr.push_front(QObject::tr("Address:")); str << addr.join(" "); } } else if (IPService::isA(obj)) { str << QObject::tr("protocol: %1").arg(obj->getStr("protocol_num").c_str()); } else if (ICMPService::isA(obj) || ICMP6Service::isA(obj)) { str << QObject::tr("type: %1").arg(obj->getStr("type").c_str()) << " " << QObject::tr("code: %1").arg(obj->getStr("code").c_str()); } else if (TCPService::isA(obj) || UDPService::isA(obj)) { int sps,spe,dps,dpe; sps=TCPUDPService::cast(obj)->getSrcRangeStart(); spe=TCPUDPService::cast(obj)->getSrcRangeEnd(); dps=TCPUDPService::cast(obj)->getDstRangeStart(); dpe=TCPUDPService::cast(obj)->getDstRangeEnd(); str << sps << ":" << spe << " / "; str << dps << ":" << dpe; } else if (TagService::isA(obj)) { str << QObject::tr("Pattern: \"%1\"").arg(obj->getStr("tagcode").c_str()); } else if (UserService::isA(obj)) { const UserService* user_srv = UserService::constcast(obj); str << QObject::tr("User id: \"%1\"").arg(user_srv->getUserId().c_str()); } else if (Interval::isA(obj)) { } } catch (FWException &ex) { cerr << ex.toString() << endl; } return res; } QString FWObjectPropertiesFactory::stripHTML(const QString &str) { // note that str may contain multiple lines // separated by
and/or '\n' QRegExp htmltag1 = QRegExp("<[^>]+>"); QRegExp htmltag2 = QRegExp("]+>"); QRegExp htmltd = QRegExp(""); QString res = str; res = res.replace(htmltd,": "); res = res.remove(htmltag1); res = res.remove(htmltag2); return res; } /* * Nicely formatted list of properties, HTML. This one is used for the * tree tooltips. */ QString FWObjectPropertiesFactory::getObjectPropertiesDetailed(FWObject *obj, bool showPath, bool tooltip, bool accentName, bool richText) { QString str; FWObject *parent_obj = obj->getParent(); QString path = obj->getPath().c_str(); path = path.section('/',2,-1); if (obj->getId() == FWObjectDatabase::ANY_ADDRESS_ID || obj->getId() == FWObjectDatabase::ANY_SERVICE_ID || obj->getId() == FWObjectDatabase::ANY_INTERVAL_ID) { return "to modify this field drag and \ndrop an object from the tree here"; } if (showPath) { str += QObject::tr("Library: "); str += QString::fromUtf8(obj->getLibrary()->getName().c_str()) + "
\n"; if (!tooltip) { str += QObject::tr("Object Id: "); str += QString(FWObjectDatabase::getStringId(obj->getId()).c_str()) + "
\n"; } } if (FWBTree().isSystem(obj)) { QString object_path = obj->getPath(true).c_str(); if (object_path == "Objects") return QObject::tr("This system folder holds objects that represent IPv4 and IPv6 addresses and networks"); if (object_path == "Objects/Addresses") return QObject::tr("This system folder holds objects that represent IPv4 and IPv6 addresses"); if (object_path == "Objects/DNS Names") return QObject::tr("This system folder holds objects that represent DNS A records"); if (object_path == "Objects/Address Tables") return QObject::tr("This system folder holds objects that read IP addresses from external files"); if (object_path == "Objects/Address Ranges") return QObject::tr("This system folder holds objects that represent IPv4 and IPv6 address ranges"); if (object_path == "Objects/Groups") return QObject::tr("This system folder holds objects that represent groups of IPv4 and IPv6 addresses, networks and other groups"); if (object_path == "Objects/Hosts") return QObject::tr("This system folder holds objects that represent hosts or servers that have one or more interfaces"); if (object_path == "Objects/Networks") return QObject::tr("This system folder holds objects that represent IPv4 and IPv6 networks"); if (object_path == "Services") return QObject::tr("This system folder holds objects that represent IP, ICMP, TCP and UDP services"); if (object_path == "Services/Groups") return QObject::tr("This system folder holds objects that represent groups of IP, ICMP, TCP and UDP services"); if (object_path == "Services/Custom") return QObject::tr("This system folder holds objects that represent custom (user-defined) services"); if (object_path == "Services/IP") return QObject::tr("This system folder holds objects that represent IP services"); if (object_path == "Services/ICMP") return QObject::tr("This system folder holds objects that represent ICMP and ICMPv6 services"); if (object_path == "Services/TCP") return QObject::tr("This system folder holds objects that represent TCP services"); if (object_path == "Services/UDP") return QObject::tr("This system folder holds objects that represent UDP services"); if (object_path == "Services/Users") return QObject::tr("This system folder holds objects that represent user names"); if (object_path == "Services/TagServices") return QObject::tr("This system folder holds objects that represent tags"); if (object_path == "Firewalls") return QObject::tr("This system folder holds objects that represent firewalls"); if (object_path == "Clusters") return QObject::tr("This system folder holds objects that represent firewall clusters"); if (object_path == "Time") return QObject::tr("This system folder holds objects that represent time intervals"); } if (Library::isA(obj)) { switch (obj->getId()) { case FWObjectDatabase::STANDARD_LIB_ID: return QObject::tr("A library of predefined read-only address and service objects that come with the program"); ; case FWObjectDatabase::DELETED_OBJECTS_ID: return QObject::tr("This library holds objects that have been deleted. You can undelete them by clicking right mouse button and using menu item 'Move to ...' to move them back to another library"); ; default: return QObject::tr("A library of user-defined objects; this is where you create your objects"); } } str += QObject::tr("Object Type: "); string d = Resources::global_res->getObjResourceStr(obj,"description"); str += QString(d.c_str()) + "
\n"; str += QObject::tr("Object Name: "); if (accentName) str += ""; str += QString::fromUtf8(obj->getName().c_str()); if (accentName) str += ""; str += "
\n"; try { if (IPv4::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += IPv4::cast(obj)->getAddressPtr()->toString().c_str(); if (parent_obj && Interface::isA(parent_obj)) { str += "/"; str += IPv4::cast(obj)->getNetmaskPtr()->toString().c_str(); } } else if (IPv6::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += IPv6::cast(obj)->getAddressPtr()->toString().c_str(); if (parent_obj && Interface::isA(parent_obj)) { str += "/"; str += QString("%1").arg(IPv6::cast(obj)->getNetmaskPtr()->getLength()); } } else if (physAddress::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += physAddress::cast(obj)->getPhysAddress().c_str(); } else if (DNSName::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += QObject::tr("DNS record:"); str += MultiAddress::cast(obj)->getSourceName().c_str(); str += "
\n"; str += (MultiAddress::cast(obj)->isRunTime())?QObject::tr("Run-time"):QObject::tr("Compile-time"); } else if (AddressTable::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += QObject::tr("Table file:"); str += MultiAddress::cast(obj)->getSourceName().c_str(); str += "
\n"; str += (MultiAddress::cast(obj)->isRunTime())?QObject::tr("Run-time"):QObject::tr("Compile-time"); } else if (AddressRange::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; AddressRange *ar=AddressRange::cast(obj); str += ar->getRangeStart().toString().c_str(); str += " - "; str += ar->getRangeEnd().toString().c_str(); } else if (Host::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; FWObjectTypedChildIterator j = obj->findByType( Interface::TYPENAME); for ( ; j!=j.end(); ++j) { str += (*j)->getName().c_str(); str += ": "; str += getObjectProperties(*j); str += "
"; } } else if (Network::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; Network *n=Network::cast(obj); str += n->getAddressPtr()->toString().c_str(); str += "/"; str += n->getNetmaskPtr()->toString().c_str(); } else if (NetworkIPv6::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; NetworkIPv6 *n=NetworkIPv6::cast(obj); str += n->getAddressPtr()->toString().c_str(); str += "/"; str += QString("%1").arg(n->getNetmaskPtr()->getLength()); } else if (ClusterGroup::cast(obj)!=NULL) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; ClusterGroup *g = ClusterGroup::cast(obj); str += QObject::tr("type: %1
").arg(g->getStr("type").c_str()); FWObjectTypedChildIterator j = obj->findByType(FWObjectReference::TYPENAME); for ( ; j!=j.end(); ++j) { FWObject *obj = FWReference::getObject(*j); if (Interface::cast(obj)) { FWObject *fw = obj->getParent(); str += QObject::tr("Group member %1:%2
"). arg(fw->getName().c_str()).arg(obj->getName().c_str()); } } } else if (DynamicGroup::cast(obj) != 0) { DynamicGroup *objGroup = DynamicGroup::cast(obj); str += QObject::tr("%1 filters
\n").arg(objGroup->getFilter().size()); } else if (Group::cast(obj)!=NULL) // just any group { if (showPath && !tooltip) str += "Path: " + path + "
\n"; Group *g = Group::cast(obj); str += QObject::tr("%1 objects
\n").arg(g->size()); int n = 0; list ll = *g; ll.sort(FWObjectNameCmpPredicate()); for (FWObject::iterator i=ll.begin(); i!=ll.end(); ++i,++n) { if (n>20) // arbitrary number { str += "       . . . "; break; } else { FWObject *o1=*i; if (FWReference::cast(o1)!=NULL) o1=FWReference::cast(o1)->getPointer(); str += QString(o1->getTypeName().c_str()) + " " + QString::fromUtf8(o1->getName().c_str()) + "
\n"; } } } else if (Firewall::cast(obj)) { // Note: Firewall::cast(obj) matched Firewall and Cluster QString platform = obj->getStr("platform").c_str(); QString version = obj->getStr("version").c_str(); QString readableVersion = getVersionString(platform,version); QString hostOS = obj->getStr("host_OS").c_str(); QDateTime dt; time_t lm=obj->getInt("lastModified"); time_t lc=obj->getInt("lastCompiled"); time_t li=obj->getInt("lastInstalled"); dt.setTime_t(lm); QString t_modified = (lm)? dt.toString():"-"; if (lm>lc && lm>li) t_modified=QString("")+t_modified+""; dt.setTime_t(lc); QString t_compiled = (lc)? dt.toString():"-"; if (lc>lm && lc>li) t_compiled=QString("")+t_compiled+""; dt.setTime_t(li); QString t_installed = (li)? dt.toString():"-"; if (li>lc && li>lm) t_installed=QString("")+t_installed+""; if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += ""; str += QString("\n"; str += QString("\n"; str += QString("\n"; str += QString("\n"; str += QString("\n"; str += QString("\n"; str += "
Platform:") + platform + "
Version:") + readableVersion + "
Host OS:") + hostOS + "
Modified:") + t_modified + "
Compiled:") + t_compiled + "
Installed:") + t_installed + "
"; } else if (Interface::isA(obj)) { FWObject *parent_host = obj; QStringList short_path; //short_path.push_front(QString::fromUtf8(obj->getName().c_str())); do { parent_host = parent_host->getParent(); if (parent_host == NULL) break; short_path.push_front(QString::fromUtf8(parent_host->getName().c_str())); } while (Host::cast(parent_host) == NULL); str += QString("Parent: %1
\n").arg(short_path.join("/")); Interface *intf = Interface::cast(obj); str += "Label: "; str += QString::fromUtf8(intf->getLabel().c_str()); str += "
"; FWObjectTypedChildIterator j = obj->findByType(IPv4::TYPENAME); for ( ; j!=j.end(); ++j) { str += getObjectProperties(*j); str += "
"; } string intf_type = intf->getOptionsObject()->getStr("type"); if (!intf_type.empty()) { str += "Interface Type: "; str += intf_type.c_str(); if (intf_type == "8021q") { int vlan_id = intf->getOptionsObject()->getInt("vlan_id"); str += QString(" VLAN ID=%1").arg(vlan_id); } str += "
"; } physAddress *paddr = intf->getPhysicalAddress(); if (paddr!=NULL) { str += "MAC: "; str += paddr->getPhysAddress().c_str() ; str += "
"; } QString q; if (intf->isDyn()) q=" dyn"; if (intf->isUnnumbered()) q=" unnum"; if (intf->isBridgePort()) q=" bridge port"; FWObject *p=obj; while (p!=NULL && !Firewall::cast(p)) p=p->getParent(); if (p!=NULL && (p->getStr("platform")=="pix" || p->getStr("platform")=="fwsm")) { int sl = intf->getSecurityLevel(); q=q+QString("sec.level %1").arg(sl); } if (intf->isUnprotected()) q=q+" unp"; if (q!="") str += " (" + q + ")"; str += "
\n"; if (showPath && !tooltip) str += "Path: " + path + "
\n"; } else if (CustomService::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; CustomService *s = dynamic_cast(obj); bool first=true; map platforms = Resources::getPlatforms(); for (map::iterator i=platforms.begin(); i!=platforms.end(); i++) { string c=s->getCodeForPlatform( (*i).first ); if ( c!="" ) { if (first) { str += ""; first=false; } str += QString("\n") .arg((*i).second.c_str()).arg(c.c_str()); } } if (!first) str += "
%1%2
"; } else if (IPService::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += QObject::tr("protocol ") + obj->getStr("protocol_num").c_str(); } else if (ICMPService::isA(obj) || ICMP6Service::isA(obj)) { if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += QObject::tr("type: ") + obj->getStr("type").c_str() + " " + QObject::tr("code: ") + obj->getStr("code").c_str(); } else if (TCPService::isA(obj) || UDPService::isA(obj)) { int sps,spe,dps,dpe; sps=TCPUDPService::cast(obj)->getSrcRangeStart(); spe=TCPUDPService::cast(obj)->getSrcRangeEnd(); dps=TCPUDPService::cast(obj)->getDstRangeStart(); dpe=TCPUDPService::cast(obj)->getDstRangeEnd(); if (showPath && !tooltip) str += "Path: " + path + "
\n"; str += ""; str += QString("\n") .arg(sps).arg(spe); str += QString("\n") .arg(dps).arg(dpe); str += "
source port range%1:%2
destination port range%1:%2
"; } else if (TagService::isA(obj)) { str += QObject::tr("Pattern: \"%1\"").arg(obj->getStr("tagcode").c_str()); } else if (UserService::isA(obj)) { const UserService* user_srv = UserService::constcast(obj); str += QObject::tr("User id: \"%1\"").arg(user_srv->getUserId().c_str()); } else if (Interval::isA(obj)) { } } catch (FWException &ex) { cerr << ex.toString() << endl; } if (richText) return str; return FWObjectPropertiesFactory::stripHTML(str); } /* * Do not translate literals 'pipe', 'queue', 'divert' below, these refer * to actual ipfw parameters and should not be localized. */ QString FWObjectPropertiesFactory::getRuleActionProperties(Rule *rule) { QString par = ""; if (rule!=NULL) { QString act = getRuleAction(rule); FWObject *o = rule; while (o!=NULL && Firewall::cast(o)==NULL) o=o->getParent(); if (o==NULL) return ""; Firewall *f=Firewall::cast(o); string platform=f->getStr("platform"); FWOptions *ropt = rule->getOptionsObject(); string editor = DialogFactory::getActionDialogPageName(f, rule); if (editor == "None") return ""; if (PolicyRule::isA(rule)) { switch (PolicyRule::cast(rule)->getAction()) { case PolicyRule::Reject: par = ropt->getStr("action_on_reject").c_str(); break; case PolicyRule::Accounting : par = ropt->getStr("rule_name_accounting").c_str(); break; case PolicyRule::Custom: par = ropt->getStr("custom_str").c_str(); break; case PolicyRule::Branch: { FWObject *branch_ruleset = rule->getBranch(); if (branch_ruleset) par = branch_ruleset->getName().c_str(); // ropt->getStr("branch_name").c_str(); break; } case PolicyRule::Pipe : if (platform=="ipfw") { par = QString("divert ") + ropt->getStr("ipfw_pipe_port_num").c_str(); } break; default : {} } } if (NATRule::isA(rule)) { switch (NATRule::cast(rule)->getAction()) { case NATRule::Translate: break; case NATRule::Branch: FWObject *branch_ruleset = rule->getBranch(); if (branch_ruleset) par = branch_ruleset->getName().c_str(); break; } } } return par; } QString FWObjectPropertiesFactory::getRuleActionPropertiesRich(Rule *rule) { FWObject *p=rule; while (p!=NULL && !Firewall::cast(p)) p=p->getParent(); if (p==NULL) { qDebug() << "FWObjectPropertiesFactory::getRuleActionPropertiesRich(): " << "Can not locate parent firewall for the rule:"; rule->dump(false, true); return ""; } string platform=p->getStr("platform"); QString act = getActionNameForPlatform(Firewall::cast(p), rule); QString par = getRuleActionProperties(rule); QString res = QObject::tr("Action : %1
").arg(act); if (!par.isEmpty()) { res += QObject::tr("Parameter: %1").arg(par); } return res; } QString FWObjectPropertiesFactory::getPolicyRuleOptions(Rule *rule) { if (rule == NULL) return ""; QList > options; PolicyRule *prule = PolicyRule::cast(rule); FWObject *o = rule; while (o!=NULL && Firewall::cast(o)==NULL) o = o->getParent(); assert(o!=NULL); Firewall *f = Firewall::cast(o); string platform = f->getStr("platform"); FWOptions *ropt = rule->getOptionsObject(); if (platform!="iosacl" && platform!="procurve_acl") { if (ropt->getBool("stateless")) { options << qMakePair(QObject::tr("Stateless"), QString("")); } else { options << qMakePair(QObject::tr("Stateful"), QString("")); } } if (platform=="iptables") { if (prule) { if (prule->getTagging()) { options << qMakePair(QObject::tr("tag:"), QString(prule->getTagValue().c_str())); } if (prule->getClassification()) { options << qMakePair(QObject::tr("class:"), QString(ropt->getStr("classify_str").c_str())); } } if (!ropt->getStr("log_prefix").empty()) { options << qMakePair(QObject::tr("Log prefix:"), QString(ropt->getStr("log_prefix").c_str())); } if (!ropt->getStr("log_level").empty()) { options << qMakePair( QObject::tr("Log Level:"), QString(getScreenName(ropt->getStr("log_level").c_str(), getLogLevels(platform.c_str())))); } if (ropt->getInt("ulog_nlgroup")>1) { options << qMakePair( QObject::tr("Netlink group:"), QString(ropt->getStr("ulog_nlgroup").c_str())); } if (ropt->getInt("limit_value")>0) { QString arg; if (ropt->getBool("limit_value_not")) arg = " ! "; arg += QString(ropt->getStr("limit_value").c_str()); if (!ropt->getStr("limit_suffix").empty()) { arg += getScreenName(ropt->getStr("limit_suffix").c_str(), getLimitSuffixes(platform.c_str())); } options << qMakePair(QString("Limit value:"), arg); } if (ropt->getInt("limit_burst")>0) { options << qMakePair(QString("Limit burst:"), QString(ropt->getStr("limit_burst").c_str())); } if (ropt->getInt("connlimit_value")>0) { QString arg; if (ropt->getBool("connlimit_above_not")) arg = " ! "; arg += QString(ropt->getStr("connlimit_value").c_str()); options << qMakePair(QObject::tr("connlimit value:"), arg); } if (ropt->getInt("hashlimit_value")>0) { QString arg; if (ropt->getBool("hashlimit_value_not")) arg = " ! "; arg += QString(ropt->getStr("hashlimit_value").c_str()); if (!ropt->getStr("hashlimit_suffix").empty()) { arg += getScreenName(ropt->getStr("limit_suffix").c_str(), getLimitSuffixes(platform.c_str())); } options << qMakePair( QString("hashlimit name:"), QString(ropt->getStr("hashlimit_name").c_str())); options << qMakePair(QString("hashlimit value:"), arg); if (ropt->getInt("hashlimit_burst")>0) { options << qMakePair( QString("haslimit burst:"), QString(ropt->getStr("hashlimit_burst").c_str())); } } if (ropt->getBool("firewall_is_part_of_any_and_networks")) { options << qMakePair(QObject::tr("Part of Any"), QString("")); } } else if (platform=="ipf") { if (!ropt->getStr("ipf_log_facility").empty()) { options << qMakePair( QObject::tr("Log facility:"), QString(getScreenName(ropt->getStr("ipf_log_facility").c_str(), getLogFacilities(platform.c_str())))); } if (!ropt->getStr("log_level").empty()) { options << qMakePair( QObject::tr("Log level:"), QString(getScreenName(ropt->getStr("log_level").c_str(), getLogLevels(platform.c_str())))); } if (ropt->getBool("ipf_return_icmp_as_dest")) { options << qMakePair( QObject::tr("Send 'unreachable'"), QString("")); } if (ropt->getBool("ipf_keep_frags")) { options << qMakePair( QObject::tr("Keep information on fragmented packets"), QString("")); } }else if (platform=="pf") { if (prule) { if (prule->getTagging()) { options << qMakePair(QObject::tr("tag:"), QString(prule->getTagValue().c_str())); } if (prule->getClassification()) { options << qMakePair(QObject::tr("queue:"), QString(ropt->getStr("pf_classify_str").c_str())); } } if (!ropt->getStr("log_prefix").empty()) { options << qMakePair(QObject::tr("Log prefix:"), QString(ropt->getStr("log_prefix").c_str())); } if (ropt->getInt("pf_rule_max_state")>0) { options << qMakePair( QObject::tr("Max state:"), QString(ropt->getStr("pf_rule_max_state").c_str())); } if (ropt->getBool("pf_keep_state")) { options << qMakePair( QObject::tr("Force 'keep-state'"), QString("")); } if (ropt->getBool("pf_no_sync")) { options << qMakePair(QString("no-sync"), QString("")); } if (ropt->getBool("pf_pflow")) { options << qMakePair(QString("pflow"), QString("")); } if (ropt->getBool("pf_sloppy_tracker")) { options << qMakePair(QString("sloppy-tracker"), QString("")); } if (ropt->getBool("pf_source_tracking")) { options << qMakePair( QObject::tr("Source tracking"), QString("")); options << qMakePair( QObject::tr("Max src nodes:"), QString(ropt->getStr("pf_max_src_nodes").c_str())); options << qMakePair( QObject::tr("Max src states:"), QString(ropt->getStr("pf_max_src_states").c_str())); } if (ropt->getBool("pf_synproxy")) { options << qMakePair(QString("synproxy"), QString("")); } if (ropt->getBool("pf_modulate_state")) { options << qMakePair(QString("modulate_state"), QString("")); } }else if (platform=="ipfw") { ; }else if (platform == "iosacl" || platform == "procurve_acl") { if (ropt->getBool("iosacl_add_mirror_rule")) { options << qMakePair( QObject::tr("Add mirrored rule"), QString("")); } }else if (platform=="pix" || platform=="fwsm") { string vers = "version_"+f->getStr("version"); options << qMakePair(QObject::tr("Version:"), QString(vers.c_str())); if ( Resources::platform_res[platform]->getResourceBool( "/FWBuilderResources/Target/options/"+vers+"/pix_rule_syslog_settings")) { if (!ropt->getStr("log_level").empty()) { options << qMakePair( QObject::tr("Log level:"), QString(getScreenName(ropt->getStr("log_level").c_str(), getLogLevels(platform.c_str())))); } if (ropt->getInt("log_interval")>0) { options << qMakePair( QObject::tr("Log interval:"), QString(ropt->getStr("log_interval").c_str())); } if (ropt->getBool("disable_logging_for_this_rule")) { options << qMakePair( QObject::tr("Disable logging for this rule"), QString("")); } } } if (prule) options << qMakePair( QObject::tr("Logging: "), (prule->getLogging()) ? QObject::tr("on") : QObject::tr("off")); QStringList res; res << ""; QList >::iterator it; for (it=options.begin(); it!=options.end(); ++it) { QPair p = *it; res << ""; } res << "
" + p.first + "" + p.second + "
"; QString html = res.join("\n"); if (fwbdebug) qDebug() << html; return html; } QString FWObjectPropertiesFactory::getNATRuleOptions(Rule *rule) { QString res; if (rule!=NULL) { res=""; FWObject *o = rule; while (o!=NULL && Firewall::cast(o)==NULL) o=o->getParent(); assert(o!=NULL); Firewall *f=Firewall::cast(o); string platform=f->getStr("platform"); FWOptions *ropt = rule->getOptionsObject(); if (fwbdebug) qDebug() << "getNATRuleOptions: platform: " << platform.c_str(); if (platform=="iptables") { if (ropt->getBool("ipt_use_snat_instead_of_masq")) res += QObject::tr("use SNAT instead of MASQ
"); if (ropt->getBool("ipt_nat_random")) res += QObject::tr("random
"); if (ropt->getBool("ipt_nat_persistent")) res += QObject::tr("persistent
"); } if (platform=="pf") { if (ropt->getBool("pf_bitmask")) res+=QObject::tr("bitmask
"); if (ropt->getBool("pf_random")) res+=QObject::tr("random
"); if (ropt->getBool("pf_source_hash")) res+=QObject::tr("source-hash
"); if (ropt->getBool("pf_round_robin")) res+=QObject::tr("round-robin
"); if (!res.isEmpty()) res += ","; if (ropt->getBool("pf_static_port")) res+=QObject::tr("static-port
"); } } return res; } QString FWObjectPropertiesFactory::getInterfaceNameExamplesForHostOS(const QString &host_os) { Resources *os_resources = Resources::os_res[host_os.toStdString()]; if (os_resources == NULL) return ""; string os_family = os_resources-> getResourceStr("/FWBuilderResources/Target/family"); if (os_family == "linux24" || os_family == "ipcop" || os_family == "openwrt" || os_family == "dd-wrt-nvram" || os_family == "dd-wrt-jffs" || os_family == "sveasoft") return "eth0, eth0.100, vlan100, br0, etc"; if (os_family == "openbsd" || os_family == "freebsd" || os_family == "macosx") return "en0, fxp0, vlan100, etc"; if (os_family == "ios" || os_family == "pix_os") return "FastEthernet0/0, etc"; if (os_family == "procurve") return "vlan 10, a1, b1, etc"; return ""; } fwbuilder-5.1.0.3599/src/libgui/RuleSetDialog.cpp0000644000175000017500000001661211733011756022255 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "RuleSetDialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Host.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/FWException.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Policy.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; RuleSetDialog::RuleSetDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::RuleSetDialog_q; m_dialog->setupUi(this); obj = NULL; platform = ""; connectSignalsOfAllWidgetsToSlotChange(); } RuleSetDialog::~RuleSetDialog() { delete m_dialog; } void RuleSetDialog::loadFWObject(FWObject *o) { obj = o; this->setEnabled(!o->isReadOnly()); RuleSet *s = dynamic_cast(obj); assert(s!=NULL); init = true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); // ipv4_6_rule_set QComboBox: // 0 - ipv4 // 1 - ipv6 // 2 - dual int idx = 0; if (s->isV4()) idx = 0; if (s->isV6()) idx = 1; if (s->isDual()) idx = 2; m_dialog->ipv4_6_rule_set->setCurrentIndex(idx); m_dialog->top_rule_set->setChecked(s->isTop()); FWObject *fw = o; while (fw && (!Firewall::isA(fw) && !Cluster::isA(fw))) fw = fw->getParent(); // if rule set object is in DeletedObjects library, it does not have parent // firewall if (fw!=NULL) { platform = fw->getStr("platform"); fwopt = Firewall::cast(fw)->getOptionsObject(); FWOptions *rulesetopt = s->getOptionsObject(); if (platform == "iptables") { m_dialog->top_rule_set->setToolTip( QApplication::translate("RuleSetDialog_q", "On iptables \"top\" rule set goes into \n" "the built-in chains INPUT, OUTPUT,\n" "FORWARD; if this flag is unchecked,\n" "rules go into user-defined chain \n" "with the name the same as the name of \n" "the rule set.", 0, QApplication::UnicodeUTF8)); if (Policy::isA(obj)) { // if this attribute is absent, we consider it False, so for // backwards compatibility the rule set is considered // filter+mangle rather than mangle only. m_dialog->iptables_only->show(); bool f = rulesetopt->getBool("mangle_only_rule_set"); m_dialog->ipt_filter_table->setChecked(!f); m_dialog->ipt_mangle_table->setChecked(f); } else m_dialog->iptables_only->hide(); } else { m_dialog->iptables_only->hide(); } if (platform == "pf") m_dialog->top_rule_set->setToolTip( QApplication::translate("RuleSetDialog_q", "If this flag is unchecked, rules go \n" "into anchor with the name the same as\n" "the name of the rule set.", 0, QApplication::UnicodeUTF8)); if (platform == "iosacl" || platform == "pix" || platform=="fwsm") m_dialog->top_rule_set->setToolTip( QApplication::translate("RuleSetDialog_q", "If this flag is unchecked, generated\n" "access list will not be assigned to\n" "interfaces with \"ip access-group\"\n" "command. The name of the rule set will\n" "be used as a prefix for names of\n" "access access lists generated for it.", 0, QApplication::UnicodeUTF8)); if (platform == "ipf" || platform == "ipfw") m_dialog->top_rule_set->hide(); else m_dialog->top_rule_set->show(); } init=false; } void RuleSetDialog::validate(bool *res) { *res = true; if (!validateName(this, obj, m_dialog->obj_name->text())) { *res = false; return; } // Do not allow ':' in the rule set names because this character is // used as a separator in error and warning messages QString pattern("([a-zA-Z0-9_-+=@%^]+)"); // branch (anchor) names for PF may end with "/*" if (platform == "pf") pattern = "([a-zA-Z0-9_-+=@%^]+)(/\\*)?"; QRegExp rx(pattern); if (!rx.exactMatch(m_dialog->obj_name->text())) { *res = false ; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this, "Firewall Builder", tr("Rule set name '%1' is invalid. Only '[a-z][A-Z][0-9]_-+=@%^' characters are allowed.").arg( m_dialog->obj_name->text() ), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } return ; } } void RuleSetDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); RuleSet *s = dynamic_cast(new_state); assert(s!=NULL); FWOptions *rulesetopt = s->getOptionsObject(); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); switch (m_dialog->ipv4_6_rule_set->currentIndex()) { case 1: s->setV6(); break; case 2: s->setDual(); break; default: s->setV4(); break; } s->setTop(m_dialog->top_rule_set->isChecked()); if (platform == "iptables" && Policy::isA(s)) { rulesetopt->setBool("mangle_only_rule_set", m_dialog->ipt_mangle_table->isChecked()); } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/iosadvanceddialog_q.ui0000644000175000017500000000701511733011756023362 0ustar sylvestresylvestre iosAdvancedDialog_q Qt::WindowModal true 0 0 597 188 IOS Advanced Configuration Options Qt::Horizontal 151 20 OK Cancel General 0 Set router name using object's name Generate commands to configure addresses for interfaces Qt::Vertical QSizePolicy::Expanding 20 40 ios_set_host_name tabWidget ios_ip_address ok_button cancel_button ok_button clicked() iosAdvancedDialog_q accept() 20 20 20 20 cancel_button clicked() iosAdvancedDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/PrintingProgressDialog.cpp0000644000175000017500000000504611733011756024210 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "PrintingProgressDialog.h" #include #include #include #include #include #include PrintingProgressDialog::PrintingProgressDialog(QWidget *parent,QPrinter *p,int nPages,bool disableCancel) : QDialog(parent) { m_dialog = new Ui::printingProgressDialog_q; m_dialog->setupUi(this); connect( m_dialog->Cancel, SIGNAL( clicked() ), this, SLOT( abortPrinting() ) ); printer=p; setNPages(nPages); m_dialog->text->setText(""); if (disableCancel) m_dialog->Cancel->hide(); } PrintingProgressDialog::~PrintingProgressDialog() { delete m_dialog; } void PrintingProgressDialog::setCurrentPageNo(int n) { if (totalPages) m_dialog->text->setText(tr( "Printing (page %1/%2)" ).arg(n).arg(totalPages)); else m_dialog->text->setText(tr( "Printing page %1" ).arg(n) ); m_dialog->progressBar->setValue(n); QApplication::processEvents(QEventLoop::AllEvents,50); } void PrintingProgressDialog::genericProgressIndicator(int n,const QString &txt) { m_dialog->text->setText(txt); m_dialog->progressBar->setValue(n); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,10); } void PrintingProgressDialog::abortPrinting() { if (printer->abort()) m_dialog->text->setText( tr("Aborting print operation") ); else m_dialog->text->setText( tr("Cannot abort printing") ); } void PrintingProgressDialog::setNPages(int n) { totalPages=n; m_dialog->progressBar->setMinimum(0); m_dialog->progressBar->setMaximum(totalPages); m_dialog->progressBar->reset(); //m_dialog->progressBar->setTotalSteps(totalPages); } fwbuilder-5.1.0.3599/src/libgui/SimpleTextEditor.h0000644000175000017500000000252511733011756022462 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SIMPLETEXTEDITOR_H__ #define __SIMPLETEXTEDITOR_H__ #include "config.h" #include class SimpleTextEditor : public QDialog { Q_OBJECT public: Ui::SimpleTextEditor_q *m_dialog; SimpleTextEditor(QWidget *parent, const QString &txt, bool enableLoadFromFile=true, const QString &title=""); ~SimpleTextEditor(); QString text(); public slots: virtual void loadFromFile(); }; #endif fwbuilder-5.1.0.3599/src/libgui/secuwallosAdvancedDialog.h0000644000175000017500000000357111733011756024146 0ustar sylvestresylvestre/* * secuwallosAdvancedDialog.h - secunet wall advanced host OS settings dialog * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __SECUWALLOSADVANCEDDIALOG_H_ #define __SECUWALLOSADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class secuwallosAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::secuwallosAdvancedDialog_q *m_dialog; public: secuwallosAdvancedDialog(QWidget *parent, libfwbuilder::FWObject *o); ~secuwallosAdvancedDialog(); private: /** validate user input */ bool validate(); /** * validate a given IP address * * valid: 192.168.1.1 * * @param addr address to verify * @return true if valid, false if not */ static bool validateAddress(const QString &addr); /** * validate a given IP address / netmask * * valid: 192.168.1.1/32 * valid: 192.168.1.1/255.255.255.0 * * @param addr address to verify * @return true if valid, false if not */ static bool validateNetwork(const QString &addr); static bool validateNetworkOrAddress(const QString &addr); protected slots: virtual void accept(); virtual void reject(); virtual void help(); void additionalChanged(int state); void buttonBrowseClicked(); void buttonOpenURLClicked(); }; #endif // __SECUWALLOSADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/ClusterInterfacesSelectorWidget.cpp0000644000175000017500000001414411733011756026042 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ClusterInterfacesSelectorWidget.h" #include using namespace libfwbuilder; using namespace std; ClusterInterfacesSelectorWidget::ClusterInterfacesSelectorWidget(QWidget *parent): QTabWidget(parent) { connect(&newInterface, SIGNAL(clicked()), this, SLOT(addNewInterface())); connect(&delInterface, SIGNAL(clicked()), this, SLOT(closeTab())); newInterface.setIcon(QIcon(":/Icons/add.png")); delInterface.setIcon(QIcon(":/Icons/del.png")); newInterface.setToolTip(tr("Add new interface")); delInterface.setToolTip(tr("Delete current interface")); /* this->setCornerWidget(&delInterface, Qt::TopRightCorner); this->setCornerWidget(&newInterface, Qt::TopLeftCorner); this->cornerWidget(Qt::TopRightCorner)->show(); this->cornerWidget(Qt::TopLeftCorner)->show();*/ noTabs = false; } ClusterInterfacesSelectorWidget::~ClusterInterfacesSelectorWidget() { this->clear(); } void ClusterInterfacesSelectorWidget::setFirewallList(QList firewalls) { while ( this->count() ) this->removeTab(0); fwlist = firewalls; set interfaces; foreach ( Firewall* fw, firewalls ) { foreach( FWObject *obj, fw->getByTypeDeep(Interface::TYPENAME) ) { Interface *iface = Interface::cast(obj); interfaces.insert(iface->getName()); } } set usedInterfaces; foreach ( string name, interfaces ) { int used = 0; foreach ( Firewall* fw, firewalls ) { foreach( FWObject *obj, fw->getByTypeDeep(Interface::TYPENAME) ) { Interface *iface = Interface::cast(obj); if (iface->getName() == name ) { used++; break; } } } if ( used == firewalls.count() ) usedInterfaces.insert(name); } foreach(string name, usedInterfaces) this->addInterface(QString::fromUtf8(name.c_str())); } ClusterInterfaceWidget* ClusterInterfacesSelectorWidget::addNewInterface() { if (noTabs) { this->removeTab(0); noTabs = false; this->delInterface.setEnabled(true); } ClusterInterfaceWidget* widget = new ClusterInterfaceWidget(this); widget->setFirewallList(this->fwlist); this->editors.append(widget); this->addTab(widget, tr("New interface")); return widget; } void ClusterInterfacesSelectorWidget::addInterface(const QString& name) { ClusterInterfaceWidget* widget = addNewInterface(); widget->setObjectName(name+"_widget"); if (!widget->setCurrentInterface(name)) { this->removeTab(this->indexOf(widget)); this->editors.removeAll(widget); delete widget; } } void ClusterInterfacesSelectorWidget::closeTab() { this->editors.removeAll(dynamic_cast(this->widget(this->currentIndex()))); this->removeTab(this->currentIndex()); if (this->count()==0) { noTabs = true; this->delInterface.setEnabled(false); QLabel *label = new QLabel(tr("This cluster has no interfaces. Add interface using button ."), this); this->addTab(label, tr("No interfaces")); } } QList ClusterInterfacesSelectorWidget::getInterfaces() { QList res; foreach ( ClusterInterfaceWidget* editor, this->editors ) { if (this->indexOf(editor) != -1) res.append(editor->getInterfaceData()); } return res; } void ClusterInterfacesSelectorWidget::clear() { QTabWidget::clear(); foreach(ClusterInterfaceWidget *editor, editors) delete editor; editors.clear(); fwlist.clear(); } bool ClusterInterfacesSelectorWidget::isValid() { // this->editor is a list of ClusterInterfaceWidgets // each of them contains data about one cluster interface foreach (ClusterInterfaceWidget *editor, this->editors) { // all cluster interfaces should be valid here if (!editor->isValid()) return false; } // checking if one firewall interface is used in two different cluster interfaces foreach(ClusterInterfaceWidget *editor1, this->editors) { foreach(ClusterInterfaceWidget *editor2, this->editors) { if (editor1 == editor2) continue; // skip checking interfaces for same editor QPair iface1, iface2; foreach(iface1, editor1->getInterfaceData().interfaces) { foreach(iface2, editor2->getInterfaceData().interfaces) { // compare pointers to interfaces selected in two different tabs if (iface1.second == iface2.second) { QMessageBox::warning(this,"Firewall Builder", tr("Interface %1 of firewall %2 is used in more than one cluster interface.") .arg(iface1.second->getName().c_str()).arg(iface1.first->getName().c_str()), "&Continue", QString::null, QString::null, 0, 1 ); return false; } } } } } return true; } fwbuilder-5.1.0.3599/src/libgui/ipfAdvancedDialog.cpp0000644000175000017500000001750511733011756023100 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "ipfAdvancedDialog.h" #include "SimpleTextEditor.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; ipfAdvancedDialog::~ipfAdvancedDialog() { delete m_dialog; } ipfAdvancedDialog::ipfAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::ipfAdvancedDialog_q; m_dialog->setupUi(this); obj=o; QStringList slm; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); if (fwbdebug) qDebug("%s",Resources::getTargetOptionStr( obj->getStr("host_OS"),"user_can_change_install_dir").c_str()); if (!Resources::getTargetOptionBool( obj->getStr("host_OS"),"user_can_change_install_dir")) { m_dialog->ipf_fw_dir->setEnabled(false); fwopt->setStr("firewall_dir",""); } m_dialog->tabWidget->setTabEnabled(6,false); //Disable tab data.registerOption(m_dialog->ipv4before_2, fwopt, "ipv4_6_order", QStringList() << tr("IPv4 before IPv6") <<"ipv4_first" << tr("IPv6 before IPv4") << "ipv6_first"); data.registerOption( m_dialog->ipf_log_or_block,fwopt, "ipf_log_or_block" ); data.registerOption( m_dialog->ipf_log_body,fwopt, "ipf_log_body" ); data.registerOption( m_dialog->ipf_check_shadowing,fwopt, "check_shading" ); data.registerOption( m_dialog->ipf_eliminate_duplicates,fwopt, "eliminate_duplicates"); data.registerOption( m_dialog->ipf_accept_new_tcp_with_no_syn,fwopt, "accept_new_tcp_with_no_syn"); data.registerOption( m_dialog->ipf_ignore_empty_groups,fwopt, "ignore_empty_groups"); data.registerOption( m_dialog->ipf_return_icmp_as_dest,fwopt, "ipf_return_icmp_as_dest"); data.registerOption( m_dialog->ipf_nat_raudio_proxy,fwopt, "ipf_nat_raudio_proxy"); data.registerOption( m_dialog->ipf_nat_h323_proxy,fwopt, "ipf_nat_h323_proxy"); data.registerOption( m_dialog->ipf_nat_ipsec_proxy,fwopt, "ipf_nat_ipsec_proxy"); data.registerOption( m_dialog->ipf_nat_pptp_proxy,fwopt, "ipf_nat_pptp_proxy"); data.registerOption( m_dialog->ipf_nat_irc_proxy,fwopt, "ipf_nat_irc_proxy"); data.registerOption( m_dialog->ipf_nat_ftp_proxy,fwopt, "ipf_nat_ftp_proxy"); data.registerOption( m_dialog->ipf_nat_rcmd_proxy,fwopt, "ipf_nat_rcmd_proxy"); data.registerOption( m_dialog->ipf_nat_krcmd_proxy,fwopt, "ipf_nat_krcmd_proxy"); data.registerOption( m_dialog->ipf_nat_ekshell_proxy,fwopt, "ipf_nat_ekshell_proxy"); data.registerOption( m_dialog->ipf_fw_dir,fwopt, "firewall_dir" ); data.registerOption( m_dialog->ipf_user,fwopt, "admUser" ); data.registerOption( m_dialog->altAddress, fwopt, "altAddress"); data.registerOption( m_dialog->sshArgs, fwopt, "sshArgs"); data.registerOption( m_dialog->scpArgs, fwopt, "scpArgs"); data.registerOption( m_dialog->activationCmd, fwopt, "activationCmd"); data.registerOption( m_dialog->ipf_manage_virtual_addr,fwopt, "manage_virtual_addr"); data.registerOption( m_dialog->ipf_configure_interfaces,fwopt, "configure_interfaces"); data.registerOption( m_dialog->ipf_debug,fwopt, "debug" ); data.registerOption( m_dialog->ipf_optimize,fwopt, "optimize" ); data.registerOption( m_dialog->ipf_dynAddr,fwopt, "dynAddr" ); slm = getLogLevels( obj->getStr("platform").c_str() ); m_dialog->logLevel->clear(); m_dialog->logLevel->addItems( getScreenNames( slm )); data.registerOption( m_dialog->logLevel, fwopt, "ipf_log_level", slm); slm = getLogFacilities( obj->getStr("platform").c_str() ); m_dialog->logFacility->clear(); m_dialog->logFacility->addItems( getScreenNames( slm )); data.registerOption( m_dialog->logFacility, fwopt, "ipf_log_facility", slm); data.registerOption( m_dialog->compiler, fwopt, "compiler" ); data.registerOption( m_dialog->compilerArgs, fwopt, "cmdline" ); data.registerOption( m_dialog->outputFileName, fwopt, "output_file" ); data.registerOption( m_dialog->fileNameOnFw, fwopt, "script_name_on_firewall"); data.registerOption( m_dialog->ipfConfFileNameOnFw, fwopt, "ipf_conf_file_name_on_firewall"); data.registerOption( m_dialog->natConfFileNameOnFw, fwopt, "nat_conf_file_name_on_firewall"); slm=getActionsOnReject( obj->getStr("platform").c_str() ); m_dialog->actionOnReject->clear(); m_dialog->actionOnReject->addItems(getScreenNames(slm)); data.registerOption( m_dialog->actionOnReject, fwopt, "action_on_reject",slm); data.registerOption( m_dialog->mgmt_ssh, fwopt, "mgmt_ssh" ); data.registerOption( m_dialog->mgmt_addr, fwopt, "mgmt_addr" ); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); m_dialog->installScript->setText( pis->getCommand().c_str() ); m_dialog->installScriptArgs->setText( pis->getArguments().c_str() ); /* page "Prolog/Epilog" */ data.registerOption( m_dialog->prolog_script, fwopt, "prolog_script" ); data.registerOption( m_dialog->epilog_script, fwopt, "epilog_script" ); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void ipfAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); Management *mgmt = (Firewall::cast(new_state))->getManagementObject(); assert(mgmt!=NULL); data.saveAll(fwoptions); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); pis->setCommand( m_dialog->installScript->text().toLatin1().constData() ); pis->setArguments( m_dialog->installScriptArgs->text().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void ipfAdvancedDialog::reject() { QDialog::reject(); } void ipfAdvancedDialog::editProlog() { SimpleTextEditor edt(this, m_dialog->prolog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->prolog_script->setText( edt.text() ); } void ipfAdvancedDialog::editEpilog() { SimpleTextEditor edt(this, m_dialog->epilog_script->toPlainText(), true, tr( "Script Editor" ) ); if ( edt.exec() == QDialog::Accepted ) m_dialog->epilog_script->setText( edt.text() ); } fwbuilder-5.1.0.3599/src/libgui/AskLibForCopyDialog.h0000644000175000017500000000343011733011756023000 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ASKLIBFORCOPYDIALOG_H_ #define __ASKLIBFORCOPYDIALOG_H_ #include "config.h" #include "global.h" #include namespace libfwbuilder{ class FWObject; class FWObjectDatabase; } class AskLibForCopyDialog : public QDialog { Q_OBJECT private: libfwbuilder::FWObjectDatabase *m_db; std::vector idxToLibs; libfwbuilder::FWObject *m_curr; Ui::asklibforcopydialog_q *m_dialog; AskLibForCopyDialog( QWidget *parent, libfwbuilder::FWObjectDatabase *db, libfwbuilder::FWObject *curr = 0); int getIdxForLib(libfwbuilder::FWObject* lib); void loadObjects(); int addLib( libfwbuilder::FWObject *lib); libfwbuilder::FWObject *getChoosenLib(); public: ~AskLibForCopyDialog(); static libfwbuilder::FWObject *askLibForCopyDialog( QWidget *parent, libfwbuilder::FWObjectDatabase *db, libfwbuilder::FWObject *curr = 0); }; #endif fwbuilder-5.1.0.3599/src/libgui/newGroupDialog.h0000644000175000017500000000256411733011756022146 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NEWGROUPDIALOG_H_ #define __NEWGROUPDIALOG_H_ #include "config.h" #include #include #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" class newGroupDialog : public QDialog { Q_OBJECT; libfwbuilder::FWObjectDatabase *db; public: newGroupDialog(QWidget *parent, libfwbuilder::FWObjectDatabase *_db); ~newGroupDialog(); Ui::newGroupDialog_q *m_dialog; public slots: virtual void accept(); }; #endif // __NEWGROUPDIALOG_H fwbuilder-5.1.0.3599/src/libgui/KeywordsDialog.cpp0000644000175000017500000001036011733011756022473 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "KeywordsDialog.h" #include "utils.h" #include "fwbuilder/FWObject.h" #include #include using namespace std; using namespace libfwbuilder; KeywordsDialog::KeywordsDialog(FWObject *obj, QWidget *parent) : QDialog(parent), m_obj(obj) { m_ui.setupUi(this); m_ui.newKeywordButton->setDefault(true); connect(m_ui.addKeywordButton, SIGNAL(clicked()), this, SLOT(gotAddClick())); connect(m_ui.removeKeywordButton, SIGNAL(clicked()), this, SLOT(gotRemoveClick())); connect(m_ui.newKeywordButton, SIGNAL(clicked()), this, SLOT(gotNewKeywordClick())); connect(m_ui.allKeywordsListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(gotAllKeywordsDoubleClick(const QModelIndex &))); const set &keywords = m_obj->getKeywords(); const set &allKeywords = m_obj->getAllKeywords(); set::const_iterator iter; for (iter = keywords.begin(); iter != keywords.end(); ++iter) { m_currKeywords.insert(QString::fromUtf8((*iter).c_str())); } for (iter = allKeywords.begin(); iter != allKeywords.end(); ++iter) { m_allKeywords.insert(QString::fromUtf8((*iter).c_str())); } m_allModel = new QStringListModel(sortStrings(m_allKeywords.toList())); m_ui.allKeywordsListView->setModel(m_allModel); m_currModel = new QStringListModel(sortStrings(m_currKeywords.toList())); m_ui.currKeywordsListView->setModel(m_currModel); } KeywordsDialog::~KeywordsDialog() { delete m_allModel; delete m_currModel; } QStringList KeywordsDialog::getKeywords() { return m_currModel->stringList(); } void KeywordsDialog::gotAddClick() { QStringList all = m_allModel->stringList(); QItemSelection selection = m_ui.allKeywordsListView->selectionModel()->selection(); foreach (QItemSelectionRange range, selection) { for (int ii = range.top(); ii <= range.bottom(); ii++) { m_currKeywords.insert(all.at(ii)); } } m_currModel->setStringList(sortStrings(m_currKeywords.toList())); } void KeywordsDialog::gotRemoveClick() { QStringList curr = m_currModel->stringList(); QItemSelection selection = m_ui.currKeywordsListView->selectionModel()->selection(); foreach (QItemSelectionRange range, selection) { for (int ii = range.top(); ii <= range.bottom(); ii++) { m_currKeywords.remove(curr.at(ii)); } } m_currModel->setStringList(sortStrings(m_currKeywords.toList())); } void KeywordsDialog::gotAllKeywordsDoubleClick(const QModelIndex &) { gotAddClick(); } void KeywordsDialog::gotNewKeywordClick() { QString newKeyword = m_ui.newKeywordLineEdit->text().simplified(); if (!validateKeyword(this, newKeyword)) return; m_currKeywords.insert(newKeyword); m_allKeywords.insert(newKeyword); m_currModel->setStringList(sortStrings(m_currKeywords.toList())); m_allModel->setStringList(sortStrings(m_allKeywords.toList())); m_ui.newKeywordLineEdit->clear(); } bool KeywordsDialog::validateKeyword(QWidget *parent, const QString &keyword) { if (keyword.isEmpty()) return false; if (keyword.contains(',')) { QMessageBox::warning(parent, "Firewall Builder", tr("Keyword cannot contain a comma"), "&OK", QString::null, QString::null, 0, 1); return false; } return true; } fwbuilder-5.1.0.3599/src/libgui/InstallFirewallViewItem.h0000644000175000017500000000232311733011756023757 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INSTALLFIREWALLVIEWITEM_H #define INSTALLFIREWALLVIEWITEM_H #include #include #include namespace libfwbuilder { class FWObject; } class InstallFirewallViewItem : public QTreeWidgetItem { public: InstallFirewallViewItem(QTreeWidget * parent, const QString & text, bool slt ); bool showLastTimes; }; #endif fwbuilder-5.1.0.3599/src/libgui/addresstabledialog_q.ui0000644000175000017500000002034511733011756023540 0ustar sylvestresylvestre AddressTableDialog_q 0 0 774 264 500 500 Address Table QFrame::Box QFrame::Sunken 0 0 350 16 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 0 0 Compile Time 0 0 Run Time Qt::Horizontal 40 20 File name: false 0 0 0 0 0 0 Browse Choose File Edit file Qt::Horizontal QSizePolicy::Expanding 10 20 Qt::Vertical QSizePolicy::MinimumExpanding 307 16 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name r_compiletime r_runtime filename BrowseButton editButton BrowseButton clicked() AddressTableDialog_q browse() 20 20 20 20 editButton clicked() AddressTableDialog_q editFile() 20 20 20 20 editFile()
fwbuilder-5.1.0.3599/src/libgui/UserDialog.cpp0000644000175000017500000000577711733011756021622 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "UserDialog.h" #include "FWCmdChange.h" #include "ProjectPanel.h" #include "fwbuilder/Library.h" #include "fwbuilder/UserService.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; UserDialog::UserDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::UserDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } UserDialog::~UserDialog() { delete m_dialog; } void UserDialog::loadFWObject(FWObject *o) { obj=o; UserService *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->userid->setText( s->getUserId().c_str() ); m_dialog->commentKeywords->loadFWObject(o); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->userid->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->userid); init=false; } void UserDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } UserService *s = dynamic_cast(obj); assert(s!=NULL); } void UserDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); UserService *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); s->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); s->setUserId( string(m_dialog->userid->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/ipv4dialog_q.ui0000644000175000017500000001522711733011756021770 0ustar sylvestresylvestre IPv4Dialog_q true 0 0 873 319 IPv4 0 0 QFrame::Box QFrame::Sunken 2 2 350 160 350 160 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Address: false 0 0 Netmask: false 0 0 0 0 Resolve Name Qt::Vertical 20 21 Qt::Vertical 20 40 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name address netmask dnsLookup dnsLookup clicked() IPv4Dialog_q DNSlookup() 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/TextFileEditor.cpp0000644000175000017500000001175411733011756022447 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "TextFileEditor.h" #include "FWBSettings.h" #include #include #include #include #include #include #include #include using namespace std; TextFileEditor::TextFileEditor(QWidget *parent, const QString &file_name, const QString &title) : QDialog(parent) { this->file_name = file_name; m_dialog = new Ui::TextFileEditor_q; m_dialog->setupUi(static_cast(this)); if (!title.isEmpty()) setWindowTitle(title); } bool TextFileEditor::load() { QFile rf(file_name); if ( ! rf.exists()) { if (QMessageBox::warning( this, "Firewall Builder", tr("The file %1 does not exist but it will be created " "when you save your changes.").arg(file_name), tr("&Open the file"), tr("&Cancel"), QString::null, 0, 1 ) == 1) return false; return true; } QFileInfo fi(file_name); if ( ! fi.isWritable()) { switch ( QMessageBox::critical( this, "Firewall Builder", tr("The file is read-only, you can't save the changes."), tr("&View the file"), tr("&Cancel"), QString::null, 0, 1 )) { case 0: // open read-only m_dialog->editor->setReadOnly(true); m_dialog->ok_button->hide(); m_dialog->cancel_button->setText(tr("Close")); break; default: // cancel return false; } } if (rf.open(QIODevice::ReadOnly)) { original_data = rf.readAll(); m_dialog->editor->setPlainText(original_data); rf.close(); } else { m_dialog->editor->setPlainText(rf.errorString()); } return true; } TextFileEditor::~TextFileEditor() { delete m_dialog; } void TextFileEditor::save() { QFile owf(file_name); if ( ! owf.exists()) { if (owf.open(QIODevice::WriteOnly) && owf.write(m_dialog->editor->toPlainText().toAscii().constData()) >= 0) { owf.close(); QDialog::accept(); return; } else QMessageBox::critical( this,"Firewall Builder", tr("Error saving data to file '%1': %2") .arg(file_name).arg(owf.errorString()), "&Continue", QString::null, QString::null, 0, 1 ); return; } QString tmp_file_name = file_name + ".tmp"; QFile wf(tmp_file_name); if (wf.open(QIODevice::WriteOnly) && wf.write(m_dialog->editor->toPlainText().toAscii().constData()) >= 0) { wf.close(); QFile old_file(file_name); if (old_file.remove() && wf.rename(tmp_file_name, file_name)) { QDialog::accept(); return; } else QMessageBox::critical( this,"Firewall Builder", tr("Can not rename file %1 to %2: %3") .arg(tmp_file_name).arg(file_name).arg(wf.errorString()), "&Continue", QString::null, QString::null, 0, 1 ); } else QMessageBox::critical( this,"Firewall Builder", tr("Error saving data to a temporary file '%1': %2") .arg(tmp_file_name).arg(wf.errorString()), "&Continue", QString::null, QString::null, 0, 1 ); } void TextFileEditor::closeEvent(QCloseEvent* ev) { if (m_dialog->editor->toPlainText() != original_data) { switch ( QMessageBox::critical( this, "Firewall Builder", tr("Dialog contains modified data. Do you want to save it?"), tr("&Save"), tr("&Discard"), tr("&Cancel"), 0, // enter: button 0 2 )) // escape: button 2 { case 0: save(); QDialog::closeEvent(ev); break; case 1: QDialog::closeEvent(ev); break; case 2: ev->ignore(); return; } } QDialog::closeEvent(ev); } fwbuilder-5.1.0.3599/src/libgui/Help.cpp0000644000175000017500000001177311733011756020445 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "fwbuilder/Constants.h" #include "Help.h" #include "FWWindow.h" #include #include #include using namespace std; using namespace libfwbuilder; Help* Help::help_window = NULL; Help::Help(QWidget *, const QString &title, bool _load_links_in_browser) : QDialog(NULL) { load_links_in_browser = _load_links_in_browser; m_dialog = new Ui::HelpView_q; m_dialog->setupUi(this); setWindowTitle("Firewall Builder Help"); setWindowFlags( windowFlags() | Qt::WindowStaysOnTopHint); delayed_open = false; http_getter = new HttpGet(); connect(http_getter, SIGNAL(done(const QString&)), this, SLOT(downloadComplete(const QString&))); QString locale = QLocale::system().name(); //"en_US"; // Set up path to help qtextBrowser find contents, such as files for paths.append(QString(Constants::getResourcesDirectory().c_str()) + "/help/" + locale); paths.append(QString(Constants::getResourcesDirectory().c_str()) + "/help/" + "en_US"); m_dialog->textview->setSearchPaths(paths); m_dialog->textview->setOpenLinks(true); m_dialog->textview->setOpenExternalLinks(true); setName(title); resize(600, 700); //raise(); flags = windowFlags()| Qt::WindowMinimizeButtonHint; }; Help::~Help() { delete m_dialog; } Help* Help::getHelpWindow(QWidget* w) { if (help_window == NULL) { help_window = new Help(w, "Firewall Builder"); help_window->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint); #if QT_VERSION >= 0x040500 help_window->setWindowFlags(help_window->windowFlags() | Qt::WindowCloseButtonHint); #endif } return help_window; } void Help::setName(const QString &name) { m_dialog->objectname->setText(name); } void Help::setSource(const QUrl &url) { if (url.toString().startsWith("http:")) { delayed_open = true; if (!http_getter->get(QUrl(url)) && fwbdebug) { qDebug() << "HttpGet error: " << http_getter->getLastError(); qDebug() << "Url: " << url; } } else { delayed_open = false; m_dialog->textview->setSource(url); } } void Help::downloadComplete(const QString& server_response) { if (fwbdebug) qDebug() << "Help::downloadComplete" << "status=" << http_getter->getStatus(); /* * getStatus() returns error status if server esponded with 302 or * 301 redirect. Only "200" is considered success. */ if (http_getter->getStatus()) { m_dialog->textview->setHtml(server_response); /* here is additional layer of protection: if I make a mistake * and feed empty page as an announcement, do not show it to * the user. If the user is behind captive portal or dns * intercept that feeds them fancy page that consists of only * a chunk of javascript and empty body, do not show it * either. One example of such case is dnsadvantage.com */ QString c = m_dialog->textview->toPlainText(); if (fwbdebug) qDebug() << "Announcement in plain text:" << c; if (!c.isEmpty() && delayed_open) { raise(); show(); } } } QString Help::findHelpFile(const QString &file_base_name) { QString locale = QLocale::system().name(); //"en_US"; QFile f; foreach(QString p, paths) { QString try_file_path = p + "/" + file_base_name; if (fwbdebug) qDebug("Checking help file %s", try_file_path.toLatin1().constData()); if (QFile::exists(try_file_path)) return try_file_path; } return ""; } void Help::closeEvent(QCloseEvent *event) { window_geometry = QWidget::saveGeometry(); QDialog::closeEvent(event); } void Help::hideEvent(QHideEvent *event) { restoreGeometry(window_geometry); QDialog::hideEvent(event); } void Help::showEvent(QShowEvent *event) { restoreGeometry(window_geometry); QDialog::showEvent(event); } void Help::show() { Help::showNormal(); } fwbuilder-5.1.0.3599/src/libgui/PrefsDialog.cpp0000644000175000017500000005066611733011756021760 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 wdarranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "check_update_url.h" #include "../../VERSION.h" #include "utils.h" #include "platforms.h" #include "PrefsDialog.h" #include "FWBSettings.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "HttpGet.h" #include "RuleSetView.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* #include #include #include #include #ifdef _WIN32 # include # include # include #else # include #endif */ #include using namespace std; void PrefsDialog::setButtonColor(QPushButton *btn,const QString &colorCode) { QPixmap pm(40,14); pm.fill( QColor(colorCode) ); QPainter p( &pm ); p.drawRect( pm.rect() ); btn->setIcon(QIcon(pm)); } PrefsDialog::~PrefsDialog() { disconnect(¤t_version_http_getter, SIGNAL(done(const QString&)), this, SLOT(checkForUpgrade(const QString&))); delete m_dialog; } PrefsDialog::PrefsDialog(QWidget *parent) : QDialog(parent) { m_dialog = new Ui::prefsDialog_q; m_dialog->setupUi(this); m_dialog->tabWidget->setCurrentIndex(0); m_dialog->wDir->setText(st->getWDir()); m_dialog->dataDir->setText(st->getDataDir()); m_dialog->objTooltips->setChecked( st->getObjTooltips() ); m_dialog->advTooltipMode->setChecked(st->getBool("UI/AdvancedTooltips")); m_dialog->advTooltipMode->setEnabled(st->getObjTooltips()); // m_dialog->tooltipDelay->setValue( st->getTooltipDelay() ); m_dialog->enableCustomTemplates->setChecked( st->customTemplatesEnabled() ); m_dialog->deletedObj->setChecked( st->getBool("UI/ShowDeletedObjects") ); m_dialog->attributesInTree->setChecked( st->getBool("UI/ShowObjectsAttributesInTree") ); m_dialog->new_dns_name_compile_tm->setChecked( st->getBool("Objects/DNSName/useCompileTimeForNewObjects")); m_dialog->new_dns_name_run_tm->setChecked( ! st->getBool("Objects/DNSName/useCompileTimeForNewObjects")); m_dialog->use_name_for_dns_record->setChecked( st->getBool("Objects/DNSName/useNameForDNSRecord")); m_dialog->new_addr_tbl_compile_tm->setChecked( st->getBool("Objects/AddressTable/useCompileTimeForNewObjects")); m_dialog->new_addr_tbl_run_tm->setChecked( ! st->getBool("Objects/AddressTable/useCompileTimeForNewObjects")); m_dialog->toolbarIconsText->setChecked(st->getIconsWithText()); m_dialog->emptyRCSLog->setChecked( st->getRCSLogState() ); m_dialog->autosaveFile->setChecked(st->getBool("Environment/autoSaveFile")); m_dialog->autosaveInterval->setValue( st->getInt("Environment/autoSaveFilePeriod")); m_dialog->dataFileCompression->setChecked( st->getCompression() ); // dontSaveStdLib->setChecked( st->getDontSaveStdLib() ); m_dialog->sshPath->setText( st->getSSHPath() ); m_dialog->scpPath->setText( st->getSCPPath() ); m_dialog->sshTimeout->setValue( st->getSSHTimeout() ); m_dialog->rememberSshPass->setChecked( st->getBool("Environment/RememberSshPassEnabled") ); m_dialog->showTips->setChecked( st->getBool("UI/NoStartTip") ); m_dialog->rulesLoggingOn->setChecked( st->getBool("Objects/PolicyRule/defaultLoggingState") ); m_dialog->rulesDefaultStateful->setChecked( st->getBool("Objects/PolicyRule/defaultStateful")); m_dialog->rulesDefaultAction->setCurrentIndex( st->getInt("Objects/PolicyRule/defaultAction")); m_dialog->rulesDefaultDirection->setCurrentIndex( st->getInt("Objects/PolicyRule/defaultDirection")); m_dialog->autoconfigure_interfaces->setChecked( st->getBool("Objects/Interface/autoconfigureInterfaces") ); // set label icons colors and text strings using user's settings QString t; colors[FWBSettings::RED]=st->getLabelColor(FWBSettings::RED); t=st->getLabelText (FWBSettings::RED); setButtonColor(m_dialog->redBtn,colors[FWBSettings::RED]); m_dialog->redText->setText(t); colors[FWBSettings::ORANGE]=st->getLabelColor(FWBSettings::ORANGE); t=st->getLabelText (FWBSettings::ORANGE); setButtonColor(m_dialog->orangeBtn,colors[FWBSettings::ORANGE]); m_dialog->orangeText->setText(t); colors[FWBSettings::YELLOW]=st->getLabelColor(FWBSettings::YELLOW); t=st->getLabelText (FWBSettings::YELLOW); setButtonColor(m_dialog->yellowBtn,colors[FWBSettings::YELLOW]); m_dialog->yellowText->setText(t); colors[FWBSettings::GREEN]=st->getLabelColor(FWBSettings::GREEN); t=st->getLabelText (FWBSettings::GREEN); setButtonColor(m_dialog->greenBtn,colors[FWBSettings::GREEN]); m_dialog->greenText->setText(t); colors[FWBSettings::BLUE]=st->getLabelColor(FWBSettings::BLUE); t=st->getLabelText (FWBSettings::BLUE); setButtonColor(m_dialog->blueBtn,colors[FWBSettings::BLUE]); m_dialog->blueText->setText(t); colors[FWBSettings::PURPLE]=st->getLabelColor(FWBSettings::PURPLE); t=st->getLabelText (FWBSettings::PURPLE); setButtonColor(m_dialog->purpleBtn,colors[FWBSettings::PURPLE]); m_dialog->purpleText->setText(t); colors[FWBSettings::GRAY]=st->getLabelColor(FWBSettings::GRAY); t=st->getLabelText (FWBSettings::GRAY); setButtonColor(m_dialog->grayBtn,colors[FWBSettings::GRAY]); m_dialog->grayText->setText(t); m_dialog->chShowIcons->setChecked(st->getShowIconsInRules() ); m_dialog->showDirectionText->setChecked(st->getShowDirectionText()); if (FWBSettings::SIZE25X25 == st->getIconsInRulesSize()) m_dialog->rb25->setChecked(true); else m_dialog->rb16->setChecked(true); changeShowIcons(); rulesFont = st->getRulesFont(); treeFont = st->getTreeFont(); uiFont = st->getUiFont(); compilerOutputFont = st->getCompilerOutputFont(); m_dialog->rulesFontDescr->setText(getFontDescription(rulesFont)); m_dialog->treeFontDescr->setText(getFontDescription(treeFont)); m_dialog->compilerOutputFontDescr->setText(getFontDescription(compilerOutputFont)); m_dialog->chClipComment->setChecked(st->getClipComment() ); m_dialog->checkUpdates->setChecked(st->getCheckUpdates() ); m_dialog->checkUpdatesProxy->setText(st->getCheckUpdatesProxy() ); #if !defined(Q_OS_WIN32) m_dialog->plink_hint->hide(); #endif // Fill lists of platforms and host OS QMap platforms = getAllPlatforms(false); QMap os = getAllOS(false); m_dialog->enabled_platforms->setRowCount(platforms.size()); m_dialog->enabled_platforms->setColumnCount(1); int row = 0; QMap::iterator it; for (it=platforms.begin(); it!=platforms.end(); ++it) { QString name = it.key(); QString readable_name = it.value(); QTableWidgetItem *cb = new QTableWidgetItem(readable_name); m_dialog->enabled_platforms->setItem(row, 0, cb); QString res_status = Resources::platform_res[name.toStdString()]->getResourceStr( "/FWBuilderResources/Target/status/").c_str(); QString prefs_status = st->getTargetStatus(name, res_status); cb->setCheckState((prefs_status=="disabled") ? Qt::Unchecked : Qt::Checked); cb->setData(Qt::UserRole, name); row++; } m_dialog->enabled_platforms->horizontalHeader()->setStretchLastSection(true); m_dialog->enabled_platforms->sortItems(0); m_dialog->enabled_platforms->update(); m_dialog->enabled_os->setRowCount(os.size()); m_dialog->enabled_os->setColumnCount(1); row = 0; for (it=os.begin(); it!=os.end(); ++it) { QString name = it.key(); QString readable_name = it.value(); QTableWidgetItem *cb = new QTableWidgetItem(readable_name); m_dialog->enabled_os->setItem(row, 0, cb); QString res_status = Resources::os_res[name.toStdString()]->getResourceStr( "/FWBuilderResources/Target/status/").c_str(); QString prefs_status = st->getTargetStatus(name, res_status); cb->setCheckState((prefs_status=="disabled") ? Qt::Unchecked : Qt::Checked); cb->setData(Qt::UserRole, name); row++; } m_dialog->enabled_os->horizontalHeader()->setStretchLastSection(true); m_dialog->enabled_os->sortItems(0); m_dialog->enabled_os->update(); } QString PrefsDialog::getFontDescription(const QFont &font) { ostringstream str; str << font.family().toLatin1().constData() << " " << font.pointSize(); return QString(str.str().c_str()); } void PrefsDialog::changeColor(QPushButton *btn, FWBSettings::LabelColors colorCode) { QColor clr = QColorDialog::getColor( QColor(colors[colorCode]), this); if (!clr.isValid()) return; colors[colorCode]= clr.name(); setButtonColor(btn,colors[colorCode]); } void PrefsDialog::changeRedColor() { changeColor(m_dialog->redBtn, FWBSettings::RED); } void PrefsDialog::changeOrangeColor() { changeColor(m_dialog->orangeBtn, FWBSettings::ORANGE); } void PrefsDialog::changeYellowColor() { changeColor(m_dialog->yellowBtn, FWBSettings::YELLOW); } void PrefsDialog::changeGreenColor() { changeColor(m_dialog->greenBtn, FWBSettings::GREEN); } void PrefsDialog::changeBlueColor() { changeColor(m_dialog->blueBtn, FWBSettings::BLUE); } void PrefsDialog::changePurpleColor() { changeColor(m_dialog->purpleBtn, FWBSettings::PURPLE); } void PrefsDialog::changeGrayColor() { changeColor(m_dialog->grayBtn, FWBSettings::GRAY); } void PrefsDialog::changeIconSize25() { //st->setIconsInRulesSize(FWBSettings::SIZE25X25); } void PrefsDialog::changeIconSize16() { //st->setIconsInRulesSize(FWBSettings::SIZE16X16); } void PrefsDialog::changeShowIcons() { bool areShown = m_dialog->chShowIcons->isChecked(); m_dialog->rb16->setEnabled(areShown); m_dialog->rb25->setEnabled(areShown); } void PrefsDialog::changeRulesFont() { changeFont(rulesFont); m_dialog->rulesFontDescr->setText(getFontDescription(rulesFont)); } void PrefsDialog::changeTreeFont() { changeFont(treeFont); m_dialog->treeFontDescr->setText(getFontDescription(treeFont)); } void PrefsDialog::changeCompilerOutputFont() { changeFont(compilerOutputFont); m_dialog->compilerOutputFontDescr->setText(getFontDescription(compilerOutputFont)); } void PrefsDialog::changeFont(QFont &font) { bool ok; QFont f = QFontDialog::getFont(&ok, font, this); if (ok) { font = f; } } void PrefsDialog::findWDir() { QString wd = m_dialog->wDir->text(); if (wd.isEmpty()) wd = st->getWDir(); if (wd.isEmpty()) wd = st->getOpenFileDir(); QString dir = QFileDialog::getExistingDirectory( this, tr("Find working directory"), wd, QFileDialog::ShowDirsOnly); if (dir.isEmpty()) return; st->setOpenFileDir(dir); m_dialog->wDir->setText(dir); } void PrefsDialog::findDataDir() { QString dataDir = m_dialog->dataDir->text(); if (dataDir.isEmpty()) dataDir = st->getDataDir(); if (dataDir.isEmpty()) dataDir = st->getOpenFileDir(); QString dir = QFileDialog::getExistingDirectory( this, tr("Find data directory"), dataDir, QFileDialog::ShowDirsOnly); if (dir.isEmpty()) return; st->setOpenFileDir(dir); m_dialog->dataDir->setText(dir); } void PrefsDialog::findSSH() { QString sshPath = m_dialog->sshPath->text(); if (!QFileInfo(sshPath).isFile()) sshPath = st->getSSHPath(); if (!QFileInfo(sshPath).isFile()) sshPath = st->getOpenFileDir(); QString fp = QFileDialog::getOpenFileName( this, tr("Find Secure Shell utility"), sshPath); if (fp.isEmpty()) return; st->setOpenFileDir(fp); m_dialog->sshPath->setText(fp); } void PrefsDialog::findSCP() { QString scpPath = m_dialog->scpPath->text(); if (!QFileInfo(scpPath).isFile()) scpPath = st->getSCPPath(); if (!QFileInfo(scpPath).isFile()) scpPath = st->getOpenFileDir(); QString fp = QFileDialog::getOpenFileName( this, tr("Find SCP utility"), scpPath); if (fp.isEmpty()) return; st->setOpenFileDir(fp); m_dialog->scpPath->setText(fp); } void PrefsDialog::accept() { QString wd=m_dialog->wDir->text(); /* check if the default working directory does not exist yet */ st->setWDir( wd ); st->setDataDir(m_dialog->dataDir->text()); st->setObjTooltips( m_dialog->objTooltips->isChecked() ); st->setBool("UI/AdvancedTooltips", m_dialog->advTooltipMode->isChecked()); st->setCustomTemplatesEnabled(m_dialog->enableCustomTemplates->isChecked()); // st->setTooltipDelay( m_dialog->tooltipDelay->value() ); // QToolTip::setWakeUpDelay( st->getTooltipDelay()*1000 ); st->setBool("UI/ShowDeletedObjects", m_dialog->deletedObj->isChecked()); st->setBool("UI/ShowObjectsAttributesInTree", m_dialog->attributesInTree->isChecked()); st->setIconsWithText(m_dialog->toolbarIconsText->isChecked()); ProjectPanel *pp = mw->activeProject(); if (pp) { pp->m_panel->om->setAttributesColumnEnabled( m_dialog->attributesInTree->isChecked()); if (m_dialog->attributesInTree->isChecked()) pp->m_panel->om->loadSectionSizes(); } st->setBool("Objects/DNSName/useCompileTimeForNewObjects", m_dialog->new_dns_name_compile_tm->isChecked()); st->setBool("Objects/DNSName/useNameForDNSRecord", m_dialog->use_name_for_dns_record->isChecked()); st->setBool("Objects/AddressTable/useCompileTimeForNewObjects", m_dialog->new_addr_tbl_compile_tm->isChecked()); st->setBool("Objects/PolicyRule/defaultLoggingState", m_dialog->rulesLoggingOn->isChecked()); st->setBool("Objects/PolicyRule/defaultStateful", m_dialog->rulesDefaultStateful->isChecked()); st->setInt("Objects/PolicyRule/defaultAction", m_dialog->rulesDefaultAction->currentIndex()); st->setInt("Objects/PolicyRule/defaultDirection", m_dialog->rulesDefaultDirection->currentIndex()); st->setBool("Objects/Interface/autoconfigureInterfaces", m_dialog->autoconfigure_interfaces->isChecked()); st->setRCSLogState( m_dialog->emptyRCSLog->isChecked() ); st->setBool("Environment/autoSaveFile", m_dialog->autosaveFile->isChecked()); st->setInt("Environment/autoSaveFilePeriod", m_dialog->autosaveInterval->value() ); st->setCompression(m_dialog->dataFileCompression->isChecked()); // st->setDontSaveStdLib( dontSaveStdLib->isChecked() ); st->setLabelColor(FWBSettings::RED, colors[FWBSettings::RED]); st->setLabelColor(FWBSettings::ORANGE, colors[FWBSettings::ORANGE]); st->setLabelColor(FWBSettings::YELLOW, colors[FWBSettings::YELLOW]); st->setLabelColor(FWBSettings::GREEN, colors[FWBSettings::GREEN]); st->setLabelColor(FWBSettings::BLUE, colors[FWBSettings::BLUE]); st->setLabelColor(FWBSettings::PURPLE, colors[FWBSettings::PURPLE]); st->setLabelColor(FWBSettings::GRAY, colors[FWBSettings::GRAY]); st->setLabelText (FWBSettings::RED, m_dialog->redText->text() ); st->setLabelText (FWBSettings::ORANGE, m_dialog->orangeText->text() ); st->setLabelText (FWBSettings::YELLOW, m_dialog->yellowText->text() ); st->setLabelText (FWBSettings::GREEN, m_dialog->greenText->text() ); st->setLabelText (FWBSettings::BLUE, m_dialog->blueText->text() ); st->setLabelText (FWBSettings::PURPLE, m_dialog->purpleText->text() ); st->setLabelText (FWBSettings::GRAY, m_dialog->grayText->text() ); st->setShowIconsInRules(m_dialog->chShowIcons->isChecked()); st->setShowDirectionText(m_dialog->showDirectionText->isChecked()); FWBSettings::IconSize sz = m_dialog->rb25->isChecked() ? FWBSettings::SIZE25X25 : FWBSettings::SIZE16X16; st->setIconsInRulesSize(sz); st->setRulesFont(rulesFont); st->setTreeFont(treeFont); st->setUiFont(uiFont); st->setCompilerOutputFont(compilerOutputFont); st->setClipComment(m_dialog->chClipComment->isChecked()); st->setCheckUpdatesProxy(m_dialog->checkUpdatesProxy->text()); // annoyingly, widget shotTip has the name opposite to its meaning. // When it is checked, we do not show tip of the day. st->setBool("UI/NoStartTip", m_dialog->showTips->isChecked()); st->setSSHPath( m_dialog->sshPath->text() ); st->setSCPPath( m_dialog->scpPath->text() ); st->setSSHTimeout(m_dialog->sshTimeout->value()); st->setBool("Environment/RememberSshPassEnabled", m_dialog->rememberSshPass->isChecked()); st->setCheckUpdates(m_dialog->checkUpdates->isChecked()); for (int row=0; row < m_dialog->enabled_platforms->rowCount(); ++row) { QTableWidgetItem *itm = m_dialog->enabled_platforms->item(row, 0); st->setTargetStatus(itm->data(Qt::UserRole).toString(), (itm && itm->checkState() == Qt::Unchecked) ? "disabled" : "active"); } QStringList disabled_os; for (int row=0; row < m_dialog->enabled_os->rowCount(); ++row) { QTableWidgetItem *itm = m_dialog->enabled_os->item(row, 0); st->setTargetStatus(itm->data(Qt::UserRole).toString(), (itm && itm->checkState() == Qt::Unchecked) ? "disabled" : "active"); } if (!wd.isEmpty()) { QDir d; d.mkdir( wd ); } if (pp) { RuleSetView* rsv = pp->getCurrentRuleSetView(); if (rsv) rsv->updateAll(); } mw->setupAutoSave(); mw->showDeletedObjects(st->getBool("UI/ShowDeletedObjects")); mw->updateTreeFont(); mw->setupGlobalToolbar(); // app->setFont(st->getTreeFont()); QDialog::accept(); } void PrefsDialog::checkSwUpdates() { st->setCheckUpdatesProxy(m_dialog->checkUpdatesProxy->text()); connect(¤t_version_http_getter, SIGNAL(done(const QString&)), this, SLOT(checkForUpgrade(const QString&))); QString url = QString(CHECK_UPDATE_URL).arg(VERSION).arg(st->getAppGUID()); current_version_http_getter.get(QUrl(url)); } void PrefsDialog::checkForUpgrade(const QString& server_response) { disconnect(¤t_version_http_getter, SIGNAL(done(const QString&)), this, SLOT(checkForUpgrade(const QString&))); if (current_version_http_getter.getStatus()) { /* * server response may be some html or other data in case * connection goes via proxy, esp. with captive portals. We * should not interpret that as "new version is available" */ if (server_response.trimmed() == "update = 1") { QMessageBox::warning( this,"Firewall Builder", tr("A new version of Firewall Builder is available at" " http://www.fwbuilder.org")); } else { QMessageBox::information( this,"Firewall Builder", tr("Your version of Firewall Builder is up to date.")); } } else { QMessageBox::critical( this,"Firewall Builder", tr("Error checking for software updates:\n%1"). arg(current_version_http_getter.getLastError())); } } void PrefsDialog::objTooltipsEnabled(bool enabled) { if (!enabled && m_dialog->advTooltipMode->isChecked()) m_dialog->advTooltipMode->setChecked(false); m_dialog->advTooltipMode->setEnabled(enabled); } fwbuilder-5.1.0.3599/src/libgui/FilterDialog.cpp0000644000175000017500000003455311733011756022123 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "VERSION.h" #include "FilterDialog.h" #include "ObjectManipulator.h" #include "ObjectDescriptor.h" #include "FWBSettings.h" #include "fwbuilder/Library.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Rule.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/XMLTools.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; FilterDialog::FilterDialog(QWidget *parent) : QDialog(parent) { m_dialog = new Ui::FilterDialog_q; m_dialog->setupUi(this); } FilterDialog::~FilterDialog() { delete m_dialog; } void FilterDialog::setFilter(Filter * f) { flt=f; /* QString p_n; QString p_a; int f_a,f_n,f_w,f_c; f_w=flt->isWildcard(); f_c=flt->isCaseSens(); f_a=flt->flt_addr; f_n=flt->flt_name; p_a=flt->getAddrPattern(); p_n=flt->getNamePattern(); init(f_w,f_c,f_a,f_n,p_a,p_n); */ //table->setColumnStretchable(2,true); } void FilterDialog::apply() { updateData(); if (validate()) { update(); accept(); } else { QMessageBox::critical(this,tr("Filter error"),tr("Invalid RegExp.") ); } } void FilterDialog::save() { QString dir = LastFile; if (dir.isEmpty()) dir = st->getOpenFileDir(); QString s = QFileDialog::getSaveFileName( this, "Save file dialog", dir, "FWBuilder filter files (*.fwf)"); if (s.isEmpty()) return; st->setOpenFileDir(s); if (!s.endsWith(".fwf")) s += ".fwf"; xmlDocPtr doc; xmlNodePtr node; //xmlNodePtr tree; doc = xmlNewDoc(TOXMLCAST("1.0")); doc->children = xmlNewDocNode(doc, NULL, TOXMLCAST("FWB_FILTER"), NULL); xmlSetProp(doc->children, TOXMLCAST("version"), TOXMLCAST( VERSION )); xmlSetProp(doc->children, TOXMLCAST("CaseSensitive"), TOXMLCAST( ((m_dialog->case_sensitive->isChecked())?"1":"0") )); xmlSetProp(doc->children, TOXMLCAST("Match"), TOXMLCAST( QString("%1").arg(m_dialog->combo->currentIndex()).toLatin1().constData() )); QString buf; int n=m_dialog->table->rowCount(); for (int i=0;ichildren, NULL, TOXMLCAST("FWB_FILTER_ITEM"), NULL); buf=QString("%1").arg(((QComboBox*)m_dialog->table->cellWidget(i,0))->currentIndex()); xmlSetProp(node,(const xmlChar*) "Target", TOXMLCAST(buf.toLatin1().constData()) ); buf=QString("%1").arg(((QComboBox*)m_dialog->table->cellWidget(i,1))->currentIndex()); xmlSetProp(node, (const xmlChar*) "Type", TOXMLCAST(buf.toLatin1().constData()) ); xmlSetProp(node, (const xmlChar*) "Pattern", TOXMLCAST(m_dialog->table->item(i,2)->text().toLatin1().constData())); } xmlSaveFile(s.toLatin1().constData(),doc); xmlFreeDoc(doc); } void FilterDialog::load() { QString s = QFileDialog::getOpenFileName( this, "Open file dialog", st->getOpenFileDir(), "FWBuilder filter files (*.fwf)"); if (s.isEmpty()) return; st->setOpenFileDir(s); xmlDocPtr doc=xmlParseFile(s.toLatin1().constData()); //TODO: use local codepage if (doc == NULL) { qDebug("Document not parsed successfully."); return; } xmlNodePtr node= xmlDocGetRootElement(doc); if (node == NULL) { qDebug("empty document"); xmlFreeDoc(doc); return; } if (xmlStrcmp(node->name,(const xmlChar*) "FWB_FILTER")) { qDebug("document of the wrong type. (FWB_FILTER)"); xmlFreeDoc(doc); return; } xmlChar *xmlbuf; QString qbuf; xmlbuf=xmlGetProp(node,(const xmlChar*) "CaseSensitive"); qbuf=FROMXMLCAST(xmlbuf); FREEXMLBUFF(xmlbuf); m_dialog->case_sensitive->setChecked(qbuf.toInt()); xmlbuf=xmlGetProp(node,(const xmlChar*) "Match"); qbuf=FROMXMLCAST(xmlbuf); FREEXMLBUFF(xmlbuf); m_dialog->combo->setCurrentIndex(qbuf.toInt()); node=node->xmlChildrenNode; while (node != NULL) { if (xmlStrcmp(node->name,(const xmlChar*) "FWB_FILTER_ITEM")) { qDebug("document of the wrong type. (FWB_FILTER_ITEM)"); xmlFreeDoc(doc); return; } addPattern(); int n=m_dialog->table->rowCount()-1; xmlbuf=xmlGetProp(node,(const xmlChar*) "Target"); qbuf=FROMXMLCAST(xmlbuf); FREEXMLBUFF(xmlbuf); ((QComboBox*)m_dialog->table->cellWidget(n,0))->setCurrentIndex( qbuf.toInt()); xmlbuf=xmlGetProp(node,(const xmlChar*) "Type"); qbuf=FROMXMLCAST(xmlbuf); FREEXMLBUFF(xmlbuf); ((QComboBox*)m_dialog->table->cellWidget(n,1))->setCurrentIndex( qbuf.toInt()); xmlbuf=xmlGetProp(node,(const xmlChar*) "Pattern"); qbuf=FROMXMLCAST(xmlbuf); FREEXMLBUFF(xmlbuf); m_dialog->table->item(n,2)->setText(qbuf); node=node->next; } LastFile=s; } void FilterDialog::update() { QRegExp r; Filter newflt; newflt.setMatchAny(m_dialog->combo->currentIndex()); newflt.setCaseSens(m_dialog->case_sensitive->isChecked()); newflt.clear(); int n=m_dialog->table->rowCount(); for(int i=0; itable->cellWidget(i,0))->currentIndex()) { case FWF_ADDRESS: { newflt.addAddrRegExp(r); break; } case FWF_NAME: { newflt.addNameRegExp(r); break; } default : { } } } if (newflt.isValid()) { *flt=newflt; } /* bool res=false; Filter newflt; newflt.setAddrPattern( addresspattern->text()); newflt.setNamePattern( namepattern->text()); newflt.setWildcard( radioButton1->isChecked()); newflt.setCaseSens( casesens->isChecked()); newflt.flt_name = name_checkbox->isChecked(); newflt.flt_addr = addr_checkbox->isChecked(); if (newflt.isValid()) { *flt=newflt; res=true; } return res; */ } bool FilterDialog::validate() { bool res=true; QRegExp r; int n=m_dialog->table->rowCount(); for(int i=0; itable->selectRow(i); return res; } } return res; } QRegExp FilterDialog::constructRegExp(int p) { QRegExp r; QString buf; r.setCaseSensitivity((m_dialog->case_sensitive->isChecked())? Qt::CaseSensitive:Qt::CaseInsensitive); switch(((QComboBox*)m_dialog->table->cellWidget(p,1))->currentIndex()) { case FWF_CONTAINS: { r.setPatternSyntax(QRegExp::Wildcard); buf=m_dialog->table->item(p,2)->text().toLatin1().constData(); break; } case FWF_IS_EQUAL_TO: { r.setPatternSyntax(QRegExp::RegExp); buf="^"; buf+=m_dialog->table->item(p,2)->text().toLatin1().constData(); buf+="$"; break; } case FWF_STARTS_WITH: { r.setPatternSyntax(QRegExp::RegExp); buf="^"; buf+=m_dialog->table->item(p,2)->text().toLatin1().constData(); break; } case FWF_ENDS_WITH: { r.setPatternSyntax(QRegExp::RegExp); buf=m_dialog->table->item(p,2)->text().toLatin1().constData(); buf+="$"; break; } case FWF_MATCHES_WILDCARD: { r.setPatternSyntax(QRegExp::Wildcard); buf=m_dialog->table->item(p,2)->text().toLatin1().constData(); break; } case FWF_MATCHES_REGEXP: { r.setPatternSyntax(QRegExp::RegExp); buf=m_dialog->table->item(p,2)->text().toLatin1().constData(); break; } default : { } } r.setPattern(buf); return r; } void FilterDialog::addPattern() { updateData(); QStringList trg; trg+=tr("Name"); trg+=tr("Address"); QStringList tp; tp+=tr("Contains"); tp+=tr("Is equal to"); tp+=tr("Starts with"); tp+=tr("Ends with"); tp+=tr("Matches Wildcard"); tp+=tr("Matches RegExp"); int n=m_dialog->table->rowCount(); m_dialog->table->setRowCount(n+1); QComboBox *cb = new QComboBox(m_dialog->table); cb->addItems(trg); m_dialog->table->setCellWidget(n,0,cb); cb = new QComboBox(m_dialog->table); cb->addItems(tp); m_dialog->table->setCellWidget(n,1,cb); QTableWidgetItem *itm = new QTableWidgetItem; itm->setFlags(itm->flags() | Qt::ItemIsEditable); m_dialog->table->setItem(n,2,itm); /*m_dialog->table->setItem(n,0,new QTableWidgetItem(m_dialog->table,trg)); m_dialog->table->setItem(n,1,new QTableWidgetItem(m_dialog->table,tp)); //table->setItem(n,2,new QTableWidgetItem(table,QTableWidgetItem::Always)); m_dialog->table->setItem(n,2,new QTableWidgetItem(m_dialog->table,QTableWidgetItem::WhenCurrent,""));*/ } void FilterDialog::removePattern() { int r=m_dialog->table->currentRow(); m_dialog->table->removeRow(r); } void FilterDialog::clearPatterns() { m_dialog->table->setRowCount(0); // for (int i=table->rowCount()-1;i>0;i--) // table->removeRow(i); } void FilterDialog::updateData() { int row=m_dialog->table->currentRow(); QTableWidgetItem * item=m_dialog->table->item(row,2); QWidget * w =m_dialog->table->cellWidget (row,2 ); if (w) item->setText ( ((QComboBox*)w)->currentText() ); } //------------------------------------------------------------------ bool Filter::isCaseSens() { return CaseSensitive; } void Filter::addNameRegExp(const QRegExp &r) { name_patterns.push_back(r); } void Filter::addAddrRegExp(const QRegExp &r) { addr_patterns.push_back(r); } QString Filter::getNamePatternString(int p) { return name_patterns[p].pattern(); } QString Filter::getAddrPatternString(int p) { return addr_patterns[p].pattern(); } int Filter::getNamePatternsNumber() { return name_patterns.size(); } int Filter::getAddrPatternsNumber() { return addr_patterns.size(); } bool Filter::isNameWildcard(int p) { return name_patterns[p].patternSyntax() == QRegExp::Wildcard; } bool Filter::isAddrWildcard(int p) { return addr_patterns[p].patternSyntax() == QRegExp::Wildcard; } Filter & Filter::operator=(const Filter& f) { addr_patterns=f.addr_patterns; name_patterns=f.name_patterns; CaseSensitive=f.CaseSensitive; MatchAny=f.MatchAny; return *this; } /* void FilterDialog::closeEvent(QCloseEvent *e) { if (fwbdebug) qDebug("FilterDialog::closeEvent got close event: %p",e); hide(); } */ Filter::Filter() { CaseSensitive=true; MatchAny=true; } Filter::~Filter() { } void Filter::addNamePattern(const QString &s,bool wc) { name_patterns.push_back(QRegExp(s,Qt::CaseSensitive,wc?QRegExp::Wildcard:QRegExp::RegExp)); } void Filter::addAddrPattern(const QString &s,bool wc) { addr_patterns.push_back(QRegExp(s,Qt::CaseSensitive,wc?QRegExp::Wildcard:QRegExp::RegExp)); } void Filter::clear() { name_patterns.clear(); addr_patterns.clear(); } void Filter::setCaseSens(bool b) { CaseSensitive=b; } void Filter::setMatchAny(bool b) { MatchAny=b; } bool Filter::isMatchAny () { return MatchAny; } bool Filter::testName(const QString &s) { int cmp; if (name_patterns.isEmpty()) { return addr_patterns.isEmpty() || !MatchAny; } for (int i=0;i=0) return true; } else { if(cmp<0) return false; } } return !MatchAny; } bool Filter::testAddr(const QString &s) { int cmp; if (addr_patterns.isEmpty()) { return (name_patterns.isEmpty() || !MatchAny); } for (int i=0;i=0) return true; } else { if(cmp<0) return false; } } return !MatchAny; } bool Filter::test(const ObjectDescriptor &od) { QString name=od.sysname.c_str(); QString addr=od.addr.toString().c_str(); return (MatchAny)? testAddr(addr) || testName(name): testAddr(addr) && testName(name); } bool Filter::isValid() { bool res=true; //TODO: Filter validity test return res; } fwbuilder-5.1.0.3599/src/libgui/freebsdadvanceddialog_q.ui0000644000175000017500000004020311733011756024176 0ustar sylvestresylvestre freebsdAdvancedDialog_q Qt::WindowModal 0 0 507 363 FreeBSD: advanced settings QTabWidget::Rounded 2 Options Qt::Vertical QSizePolicy::Fixed 20 20 IPv4 Packet forwarding Qt::AlignCenter false No change On Off Qt::Horizontal QSizePolicy::Expanding 40 20 IPv6 Packet forwarding Qt::AlignCenter false No change On Off Forward source routed packets Qt::AlignCenter false No change On Off Generate ICMP redirects Qt::AlignCenter false No change On Off Qt::Vertical 20 83 Path 0 0 Specify directory path and a file name for the following utilities on the OS your firewall machine is running. Leave these empty if you want to use default values. Qt::AlignCenter true Qt::Horizontal QSizePolicy::Expanding 40 20 ipfw: Qt::AlignCenter false 0 0 200 0 Qt::Horizontal QSizePolicy::Expanding 40 20 pfctl: Qt::AlignCenter false 200 0 ipf: Qt::AlignCenter false 0 0 200 0 ipnat: Qt::AlignCenter false 200 0 sysctl: Qt::AlignCenter false 200 0 Qt::Vertical QSizePolicy::Expanding 20 40 Data Qt::Vertical QSizePolicy::Fixed 20 20 Specify directory where data files (e.g. run-time address table) are found on the firewall. Qt::AlignCenter true Data directory: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 300 0 Qt::Vertical 20 155 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true tabWidget freebsd_ip_forward freebsd_ip_sourceroute freebsd_ip_redirect buttonOk buttonCancel freebsd_path_ipfw freebsd_path_ipf freebsd_path_ipnat freebsd_path_sysctl buttonOk clicked() freebsdAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() freebsdAdvancedDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/discoverydruid_q.ui0000644000175000017500000025104311733011756022763 0ustar sylvestresylvestre DiscoveryDruid_q Qt::WindowModal 0 0 660 670 0 0 0 25 Sans Serif 14 75 false true TextLabel Qt::AlignCenter 14 6 40 0 0 0 Choose discovery method used to collect information about network objects from the list below and click 'Next' to continue. Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 20 70 Discovery method: 6 20 6 Read file in hosts format true Import DNS zone Perform network discovery using SNMP Import configuration of a firewall or a router 0 Enter full path and file name below or click "Browse" to find it: Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 20 31 File in hosts format 6 Qt::Vertical QSizePolicy::Expanding 20 20 Browse ... Qt::Vertical QSizePolicy::Expanding 20 41 Qt::Vertical QSizePolicy::Expanding 20 181 0 All objects created during import will be placed in the library currently opened in the tree. Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 20 20 Policy import tries to parse given configuration file and preserve its logic as close as possible. However, very often target firewall configuration allows for more commands, options and their combinations than importer can understand. Rules that importer could not parse exactly are colored red in the rule sets it creates. Always inspect firewall policy created by the importer and compare it with the original. Manual changes and corrections may be required. Comments in the rules that could not be parsed show fragments of the original configuration parser did not understand. Qt::AlignVCenter true Platform: false 0 100 textLabel1 Qt::AlignVCenter true Qt::Vertical QSizePolicy::Fixed 20 10 Qt::Vertical QSizePolicy::Fixed 20 10 Firewall name: Import from file: false 0 0 Browse... Cisco Router IOS Cisco PIX, Cisco ASA iptables Qt::Horizontal 40 20 0 This discovery method creates objects for all 'A' records found in DNS domain. You will later have a chance to accept only those objects you wish and ignore others. Please enter the domain name below: Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 20 21 Domain name 6 Qt::Vertical QSizePolicy::Expanding 20 21 Qt::Vertical QSizePolicy::Expanding 20 21 Qt::Vertical QSizePolicy::Expanding 20 20 Objects created using this method may have long or short names. long name consists of the host name and full domain name (this is called <i>Fully Qualified Domain Name</i>). Short name consists of only host name. Check in the box below if you wish to use long name, then click next to continue: Qt::AlignVCenter true Use long names 0 DNS zone information has to be transferred from the name server authoritative for the domain. Pick the name server: Qt::AlignVCenter true Name server 6 choose name server from the list below server name or its IP address here if you wish to use different one: 200 20 false 0 0 32767 20 Qt::Horizontal Qt::Horizontal QSizePolicy::Expanding 50 20 DNS Query options 0 Timeout (sec) false Retries false 1 1 1 2 Qt::Horizontal QSizePolicy::Expanding 160 20 Qt::Horizontal QSizePolicy::Expanding 170 20 Qt::Vertical QSizePolicy::Expanding 20 131 0 This discovery method scans networks looking for hosts or gateways responding to SNMP queries. It pulls host's ARP table and uses all the entries found in it to create objects. Scan starts from the host called "seed". Enter "seed" host name or address below: Qt::AlignVCenter true 'Seed' host 6 Qt::Horizontal QSizePolicy::Expanding 211 21 true 0 20 Enter a valid host name or address. false 0 0 32767 20 Qt::Horizontal Qt::Horizontal QSizePolicy::Expanding 40 20 The scanner process can be confined to a certain network, so it won't discover hosts on adjacent networks. If you leave these fields blank, scanner will visit all networks it can find: Qt::AlignVCenter true Confine scan to this network: 6 Qt::Horizontal QSizePolicy::Expanding 271 20 Qt::Horizontal QSizePolicy::Expanding 271 20 Netmask: false Address: false false Qt::Vertical QSizePolicy::Expanding 20 70 0 The scanner process can repeat its algorithm recursively using each new host it finds as a new "seed". This allows it to find as many objects on your network as possible. On the other hand, it takes more time and may find some objects you do not really need. You can turn recursive scanning on below: Qt::AlignVCenter true Run network scan recursively QFrame::HLine QFrame::Sunken Qt::Horizontal The scanner process can find nodes beyond the boundaries of your network by following point-to-point links connecting it to the Internet or other parts of WAN. Qt::AlignVCenter true Follow point-to-point links QFrame::HLine QFrame::Sunken Qt::Horizontal The scanner process normally ignores interfaces that have no IP addresses; checking this option makes it create such interfaces as "Unnumbered" Qt::AlignVCenter true Include interfaces with no ip addresses QFrame::HLine QFrame::Sunken Qt::Horizontal Analysis of ARP table yields IP addresses for hosts on your network. In order to determine their names, scanner can run reverse name lookup queries using your name servers (DNS): Qt::AlignVCenter true Run reverse name lookup DNS queries to determine host names false 0 Enter parameters for SNMP and DNS reverse lookup queries below. (If unsure, just leave default values): Qt::AlignVCenter true SNMP query parameters: 6 SNMP 'read' community string: false number of retries: false timeout (sec): false 1 1 1 2 public Qt::Horizontal QSizePolicy::Expanding 190 20 Qt::Horizontal QSizePolicy::Expanding 250 20 Qt::Horizontal QSizePolicy::Expanding 250 20 DNS parameters: 6 Qt::Horizontal QSizePolicy::Expanding 300 20 number of retries: false timeout (sec) : false Number of threads: false 1 1 1 10000 2 1 5 false Qt::Vertical QSizePolicy::Expanding 20 80 0 0 16 75 true Process name false 6 Qt::Horizontal Stop Save scan log to file Qt::Horizontal QSizePolicy::Expanding 141 20 Process log: 0 true 0 These are the networks found by the scanner process. Choose the ones you wish to use from the list below, then click 'Next': Qt::AlignVCenter true 6 6 QAbstractItemView::MultiSelection 6 Select All Filter ... Unselect All Remove Filter 6 -> <- Qt::Vertical QSizePolicy::Expanding 20 300 6 QAbstractItemView::MultiSelection 6 Select All Unselect All 0 Choose objects you wish to use, then click 'Next': Qt::AlignVCenter true 6 6 QAbstractItemView::MultiSelection 6 Remove Filter Select All Filter ... Unselect All 6 -> <- Qt::Vertical QSizePolicy::Expanding 20 240 6 QAbstractItemView::MultiSelection 6 Select All Unselect All 0 Qt::Horizontal QSizePolicy::Expanding 30 20 Unselect All Remove Filter Filter ... Qt::Horizontal QSizePolicy::Expanding 20 20 Select All Change type of selected objects: 6 Address Host Firewall QAbstractItemView::ExtendedSelection true Object Interfaces Type Here you can change type of the objects to be created for each address discovered by the scanner. By default, an "Address" object is created for the host with just one interface with single IP address and "Host" object is created for the host with multiple interfaces, however you can change their types on this page. Qt::AlignVCenter true 0 Select target library 6 0 0 Qt::Horizontal QSizePolicy::Expanding 71 20 Qt::Vertical QSizePolicy::Expanding 20 340 0 Adding new objects to library ... Qt::AlignTop true Qt::Horizontal Qt::Vertical QSizePolicy::Expanding 20 241 Firewall Builder uses Network Zones to determine network topology. Each firewall interface must have a Network Zone configured. The Network Zone of an interface represents the set of IP networks that would be the source IP address of traffic arriving inbound on an interface. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true If you do not set the Network Zone now you can update the Network Zone configuration after the firewall has been created by double-clicking on the network interface of the firewall object and then selecting the desired object from the Network Zone dropdown list. true :/Images/network_zone_dialog.png Qt::AlignCenter 0 150 QFrame::NoFrame QFrame::Sunken 0 true true Name Label Address Security Level 1 0 400 50 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 40 20 < &Back &Next > false &Finish false &Cancel dm_fromfile filename browseButton domainname uselongname dnsfromlist nameserverlist nameserverline dnscustom dnsretries dnstimeout seedhostname snmpinaddr snmpinmask snmprecursive snmpfollowp2p snmpincludeunnumbered snmpdodns snmpretries snmptimeout snmpcommunity snmpdnsretries snmpdnstimeout snmpdnsthreads discoveryStopButton logSaveButton discoverylog networkresultlist selAllResNetButton netFilterButton pushButton7_2 remNetFilterButton addNetButton remNetButton networklist selAllNetButton pushButton7_2_2 objectresultlist remObjFilterButton selAllResButton objFilterButton unselAllResButton addObjButton remObjButton objectlist selAllObjButton unselAllObjButton unselAllLastButton removeLastFilterButton addLastFilterButton selAllLastButton addresTypeButton hostTypeButton pushButton26 typeChangingList libs addLastFilterButton clicked() DiscoveryDruid_q setLastFilter() 32 67 20 20 addNetButton clicked() DiscoveryDruid_q addNetwork() 32 67 20 20 addObjButton clicked() DiscoveryDruid_q addObject() 32 67 20 20 addresTypeButton clicked() DiscoveryDruid_q typeAddress() 32 67 20 20 browseButton clicked() DiscoveryDruid_q browseHostsFile() 32 67 20 20 stackedWidget currentChanged(int) DiscoveryDruid_q changedSelected(int) 32 67 20 20 discoveryStopButton clicked() DiscoveryDruid_q stopBackgroundProcess() 32 67 20 20 domainname textChanged(QString) DiscoveryDruid_q changedDomainName() 43 312 20 20 filename textChanged(QString) DiscoveryDruid_q changedHostsFileName() 32 67 20 20 hostTypeButton clicked() DiscoveryDruid_q typeHost() 32 67 20 20 import_browse clicked() DiscoveryDruid_q browseForImport() 572 147 20 20 import_platform activated(int) DiscoveryDruid_q importPlatformChanged(int) 244 176 20 20 logSaveButton clicked() DiscoveryDruid_q saveScanLog() 32 67 20 20 nameserverline textChanged(QString) DiscoveryDruid_q typedCustomNS() 41 205 20 20 nameserverline textChanged(QString) DiscoveryDruid_q changedNameServer() 41 205 20 20 nameserverlist activated(int) dnsfromlist animateClick() 38 149 39 124 netFilterButton clicked() DiscoveryDruid_q setNetworkFilter() 32 67 20 20 networkresultlist itemDoubleClicked(QListWidgetItem*) DiscoveryDruid_q addNetwork() 32 67 20 20 objectresultlist itemDoubleClicked(QListWidgetItem*) DiscoveryDruid_q addObject() 32 67 20 20 objFilterButton clicked() DiscoveryDruid_q setObjectFilter() 32 67 20 20 pushButton26 clicked() DiscoveryDruid_q typeFirewall() 32 67 20 20 pushButton7_2 clicked() networkresultlist clearSelection() 32 67 32 67 pushButton7_2_2 clicked() networklist clearSelection() 32 67 32 67 remNetButton clicked() DiscoveryDruid_q removeNetwork() 32 67 20 20 remNetFilterButton clicked() DiscoveryDruid_q removeNetworkFilter() 32 67 20 20 remObjButton clicked() DiscoveryDruid_q removeObject() 32 67 20 20 remObjFilterButton clicked() DiscoveryDruid_q removeObjectFilter() 32 67 20 20 removeLastFilterButton clicked() DiscoveryDruid_q removeLastFilter() 32 67 20 20 seedhostname textChanged(QString) DiscoveryDruid_q changedSeedHost() 42 160 20 20 selAllLastButton clicked() DiscoveryDruid_q selectAllLast() 32 67 20 20 selAllNetButton clicked() DiscoveryDruid_q selectAllNets() 32 67 20 20 selAllObjButton clicked() DiscoveryDruid_q selectAllObjs() 32 67 20 20 selAllResButton clicked() DiscoveryDruid_q selectAllResObjs() 32 67 20 20 selAllResNetButton clicked() DiscoveryDruid_q selectAllResNets() 32 67 20 20 snmpcommunity textChanged(QString) DiscoveryDruid_q checkSNMPCommunity() 111 76 20 20 snmpinaddr textChanged(QString) DiscoveryDruid_q changedInclNet() 109 318 20 20 snmpinmask textChanged(QString) DiscoveryDruid_q changedInclNet() 109 350 20 20 unselAllLastButton clicked() DiscoveryDruid_q unselectAllLast() 32 67 20 20 unselAllObjButton clicked() objectlist clearSelection() 32 67 32 67 unselAllResButton clicked() objectresultlist clearSelection() 32 67 32 67 obj_name textChanged(QString) DiscoveryDruid_q objNameChanged(QString) 371 103 582 211 import_filename textChanged(QString) DiscoveryDruid_q objNameChanged(QString) 300 124 583 237 objNameChanged(QString) fwbuilder-5.1.0.3599/src/libgui/networkZoneManager.h0000644000175000017500000000321611733011756023033 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NETWORK_ZONE_MANAGER_H_ #define __NETWORK_ZONE_MANAGER_H_ #include "config.h" #include #include #include namespace libfwbuilder { class FWObjectDatabase; } class NetworkZoneManager { libfwbuilder::FWObjectDatabase *db; QStringList netzones_object_names; // netzones_id_to_index : key - object id, value - number in the list QMap netzones_id_to_index; // netzones_index_to_id : key - number in the list, value - obj id QMap netzones_index_to_id; public: NetworkZoneManager(); void load(libfwbuilder::FWObjectDatabase *db); int getListItemIdexByNetzoneId(int id); int getNetzoneIdByListIndex(int idx); void packComboBox(QComboBox *combobox, int current_netzone_object_id); }; #endif fwbuilder-5.1.0.3599/src/libgui/FindWhereUsedWidget.h0000644000175000017500000000441211733011756023052 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __FINDWHEREUSEDWIDGET_H_ #define __FINDWHEREUSEDWIDGET_H_ #include "config.h" #include #include "ProjectPanel.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include #include class QRegExp; class ObjectDescriptor; class QWidget; namespace libfwbuilder { class FWReference; } class FindWhereUsedWidget : public QWidget { Q_OBJECT private: ProjectPanel *project_panel; bool flShowObject; libfwbuilder::FWObject* object; std::set resset; Ui::findWhereUsedWidget_q *m_widget; void showObject(libfwbuilder::FWObject*); void _find(libfwbuilder::FWObject *obj); public: FindWhereUsedWidget(QWidget*p, ProjectPanel* pp, const char * n = 0, Qt::WindowFlags f = 0, bool f_mini=false); ~FindWhereUsedWidget(); void setShowObject(bool fl); void attachToProjectWindow(ProjectPanel *pp) { project_panel = pp; } static QTreeWidgetItem* createQTWidgetItem(libfwbuilder::FWObject* obj, libfwbuilder::FWObject* container); public slots: virtual void find(); virtual void find(libfwbuilder::FWObject *obj); void init(); void clear(); void itemActivated(QTreeWidgetItem*, int); void itemClicked(QTreeWidgetItem*, int); void findFromDrop(); signals: void close(); }; #endif fwbuilder-5.1.0.3599/src/libgui/ProjectPanel_events.cpp0000644000175000017500000004007611733011756023525 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include #include #include #include #include #include #include #include "fwbuilder/RuleSet.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "ProjectPanel.h" #include "events.h" #include "FWBTree.h" #include "FWWindow.h" #include "RCS.h" #include "RuleSetView.h" #include "RuleSetModel.h" #include "ColDesc.h" #include #include #include using namespace Ui; using namespace libfwbuilder; using namespace std; bool ProjectPanel::event(QEvent *event) { if (event->type() >= QEvent::User) { fwbUpdateEvent *ev = dynamic_cast(event); int event_code = event->type() - QEvent::User; QString data_file = ev->getFileName(); int obj_id = ev->getObjectId(); FWObject *obj = db()->findInIndex(obj_id); if (fwbdebug) qDebug() << this << "rcs:" << rcs << "rcs->getFileName():" << QString((rcs!=NULL) ? rcs->getFileName() : "") << "file:" << data_file << "event:" << ev->getEventName() << "object:" << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "") << "(" << ((obj!=NULL) ? obj->getTypeName().c_str() : "") << ")" << "id=" << ((obj!=NULL) ? obj->getId() : -1); if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL) { m_panel->om->updateCreateObjectMenu(getCurrentLib()); ev->accept(); return true; } if ((rcs && rcs->getFileName() == data_file) || (!rcs && data_file.isEmpty())) { switch (event_code) { case RELOAD_OBJECT_TREE_EVENT: registerTreeReloadRequest(); ev->accept(); return true; case RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT: m_panel->om->reload(); ev->accept(); return true; case RELOAD_RULESET_EVENT: registerRuleSetRedrawRequest(); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT: { RuleSetView* rsv = getCurrentRuleSetView(); if (rsv) rsv->makeCurrentRuleVisible(); ev->accept(); return true; } case RELOAD_RULESET_IMMEDIATELY_EVENT: redrawRuleSets(); //reopenFirewall(); // update rule set title as well //updateFirewallName(); ev->accept(); return true; } if (obj == NULL) return false; switch (event_code) { case DATA_MODIFIED_EVENT: { // This event does not trigger any updates in the UI, // this purely data structure update event. FWObject *p = obj; while (p && Firewall::cast(p)==NULL) p = p->getParent(); Firewall *f = Firewall::cast(p); // when user locks firewall object, this code tries to // update last_modified timestamp in it because it // depends on itself. Dont. if (f && !f->isReadOnly()) { f->updateLastModifiedTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, f->getId())); } registerModifiedObject(obj); QCoreApplication::postEvent(mw, new updateGUIStateEvent()); ev->accept(); return true; } case UPDATE_OBJECT_EVERYWHERE_EVENT: { Rule *rule = NULL; RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (RuleElement::cast(obj)) rule = Rule::cast(obj->getParent()); if (Rule::cast(obj)) rule = Rule::cast(obj); if (rule && current_ruleset && md && rule->isChildOf(current_ruleset)) { md->rowChanged(md->index(rule, 0)); ev->accept(); return true; } if (rule) { QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj_id)); ev->accept(); return true; } if (rsv) rsv->updateObject(obj); if (Library::cast(obj)) { m_panel->om->updateLibName(obj); m_panel->om->updateLibColor(obj); } QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); // QCoreApplication::postEvent( // this, new reloadRulesetEvent(data_file)); ev->accept(); return true; } case OBJECT_NAME_CHANGED_EVENT: { objectNameChangedEvent *name_change_event = dynamic_cast(event); m_panel->om->updateObjectInTree(obj); if (name_change_event->rename_children) { // This performs automatic renaming of child objects if necessary m_panel->om->autoRenameChildren(obj, name_change_event->old_name); } ev->accept(); return true; } case UPDATE_LAST_COMPILED_TIMESTAMP_EVENT: if (rcs && !rcs->isRO() && Firewall::cast(obj) && !obj->isReadOnly()) { Firewall::cast(obj)->updateLastCompiledTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); ev->accept(); return true; } break; case UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT: if (rcs && !rcs->isRO() && Firewall::cast(obj) && !obj->isReadOnly()) { Firewall::cast(obj)->updateLastInstalledTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); ev->accept(); return true; } break; } // Events below this should only be processed if // ProjectPanel has been attached to an MDI window. There // is no MDI window right after project panel is created // but some operations may already be performed. See // FWWindow::fileOpen where ProjectPanel is cfeated and // file is opened before MDI window is attached. So the UI // update events below will only be processed if MDI // window exists. if (mdiWindow == NULL) return false; switch (event->type() - QEvent::User) { case INSERT_OBJECT_IN_TREE_EVENT: { FWObject *parent = db()->findInIndex( dynamic_cast(event)->parent_id); m_panel->om->insertSubtree(parent, obj); ev->accept(); return true; } case REMOVE_OBJECT_FROM_TREE_EVENT: { m_panel->om->removeObjectFromTreeView(obj); ev->accept(); return true; } case ADD_TREE_PAGE_EVENT: m_panel->om->addLib(obj); ev->accept(); return true; case REMOVE_TREE_PAGE_EVENT: m_panel->om->removeLib(obj); ev->accept(); return true; case UPDATE_OBJECT_IN_TREE_EVENT: registerObjectToUpdateInTree(obj, false); ev->accept(); return true; case UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT: registerObjectToUpdateInTree(obj, true); ev->accept(); return true; case UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT: m_panel->om->updateObjectInTree(obj, true); ev->accept(); return true; case OPEN_RULESET_EVENT: openRuleSet(obj); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case OPEN_RULESET_IMMEDIATELY_EVENT: openRuleSet(obj, true); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case SELECT_RULE_ELEMENT_EVENT: { RuleSetView* rsv = getCurrentRuleSetView(); rsv->selectRE(Rule::cast(obj), dynamic_cast(event)->column_type); rsv->setFocus(Qt::OtherFocusReason); ev->accept(); return true; } case SHOW_OBJECT_IN_RULESET_EVENT: { // if obj is child of RuleElement (i.e. a reference object) FWReference *ref = FWReference::cast(obj); if (ref) { RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && obj->isChildOf(current_ruleset)) { clearManipulatorFocus(); rsv->selectRE(ref); rsv->setFocus(Qt::OtherFocusReason); } else { FWObject *rs = obj; while (rs && RuleSet::cast(rs)==NULL) rs = rs->getParent(); if (rs) { // reopen rule set right now, before we post event // to show the object in it. openRuleSet(rs); QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj_id)); } } ev->accept(); return true; } // if obj is RuleElement - select its first element RuleElement *re = RuleElement::cast(obj); if (re && re->size() > 0) { QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj->front()->getId())); ev->accept(); return true; } // if obj is Rule - select its comment (the only common rule element) Rule *rule = Rule::cast(obj); if (rule) { RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && rule->isChildOf(current_ruleset)) { rsv->selectRE(rule, ColDesc::Comment); rsv->setFocus(Qt::OtherFocusReason); ev->accept(); return true; } else { // this rule does not belong to the current ruleset // reopen rule set right now, before we post event // to show the object in it. openRuleSet(rule->getParent(), true); QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj->getId())); } ev->accept(); return true; } ev->accept(); return true; } case SHOW_OBJECT_IN_TREE_EVENT: //m_panel->om->setFocus(); m_panel->om->openObjectInTree(obj); ev->accept(); return true; case EXPAND_OBJECT_IN_TREE: m_panel->om->expandObjectInTree(obj); ev->accept(); return true; case OPEN_LIBRARY_FOR_OBJECT_EVENT: m_panel->om->openLibForObject(obj); ev->accept(); return true; case CLOSE_OBJECT_EVENT: if (RuleSet::cast(obj)) { if (visibleRuleSet == obj) { clearFirewallTabs(); closeRuleSet(obj); } } else { m_panel->om->closeObject(); mdiWindow->update(); } ev->accept(); return true; case ADD_USER_FOLDER_EVENT: m_panel->om->addUserFolderToTree(obj, dynamic_cast(event)->m_userFolder); ev->accept(); return true; case REMOVE_USER_FOLDER_EVENT: m_panel->om->removeUserFolderFromTree(obj, dynamic_cast(event)->m_userFolder); ev->accept(); return true; case MOVE_TOFROM_USER_FOLDER_EVENT: moveToFromUserFolderEvent *moveEvent = dynamic_cast(event); m_panel->om->moveToFromUserFolderInTree(obj, db()->findInIndex(moveEvent->m_objIdToMove), moveEvent->m_oldFolder, moveEvent->m_newFolder); ev->accept(); return true; } } return false; } //if (fwbdebug) qDebug() << this << "event:" << event; return QWidget::event(event); } fwbuilder-5.1.0.3599/src/libgui/RuleSetViewDelegate.h0000644000175000017500000001052311733011756023063 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef RULESETVIEWDELEGATE_H #define RULESETVIEWDELEGATE_H #include #include "RuleSetModel.h" class RuleNode; class FWObjectSelectionModel; namespace libfwbuilder { class RuleElement; class FWObject; } //////////////////////////////////////////////////////////////////////////// // RuleSetViewDelegate //////////////////////////////////////////////////////////////////////////// class DrawingContext { public: QRect objectRect; QRect drawRect; int itemHeight; QSize iconSize; }; class RuleSetViewDelegate : public QItemDelegate { Q_OBJECT; QColor standard_highlight; public: RuleSetViewDelegate(QObject *parent, FWObjectSelectionModel *selectionModel); void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint (const QStyleOptionViewItem &, const QModelIndex & ) const; void setStandardHighlightColor(const QColor &c) { standard_highlight = c; } static const int RULE_ITEM_GAP = 4; static const int VERTICAL_MARGIN = 2; static const int HORIZONTAL_MARGIN = 2; static const int ICON_TEXT_GAP = 2; static QSize getIconSize(); static QSize getTextSize(QString, int flag); static int getItemHeight(QString s = "AiqyW", int flag = Qt::TextSingleLine, bool text = true); private: enum PixmapAttr { Normal, Neg, Ref, Tree, NegTree }; FWObjectSelectionModel *sectionModel; QString objectText(libfwbuilder::RuleElement *re,libfwbuilder::FWObject *obj) const; QPixmap getPixmap(QString name, PixmapAttr pmattr = Normal) const; DrawingContext initContext(QRect rect, bool useEnireSpace = false) const; QSize calculateCellSizeForRule(const QStyleOptionViewItem & option, const QModelIndex & index, RuleNode * node ) const; QSize calculateCellSizeForObject(const QModelIndex & index) const; QSize calculateCellSizeForComment(const QModelIndex & index) const; QSize calculateCellSizeForIconAndText(const QModelIndex & index) const; QSize calculateCellSizeForOptions(const QModelIndex & index) const; QSize drawIconInRule(QPainter *p, int x, int y, QString name, bool neg) const; void drawIconAndText(QPainter *painter, QRect rect, QString icon, QString text, bool negation = false) const; void drawIcons(QPainter *painter, QRect rect, const QStringList &icons) const; void drawSelectedFocus(QPainter *painter, const QStyleOptionViewItem &option,QRect &rect) const; void paintGroup (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, RuleNode * node) const; void paintRule (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, RuleNode * node) const; void paintRowHeader (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, RuleNode * node) const; void paintObject(QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const; void paintDirection(QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const; void paintAction(QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const; void paintOptions(QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const; void paintComment(QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const; void paintMetric(QPainter *painter, const QStyleOptionViewItem &option, const QVariant &v) const; QString constructActionText(ActionDesc &actionDesc)const; }; #endif // RULESETVIEWDELEGATE_H fwbuilder-5.1.0.3599/src/libgui/longTextDialog.cpp0000644000175000017500000000305311733011756022471 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "longTextDialog.h" #include #include #include #include #include using namespace libfwbuilder; using namespace std; longTextDialog::~longTextDialog() { delete m_dialog; } longTextDialog::longTextDialog(QWidget *p, const QString &txt,const QString <xt) : QDialog(p) { m_dialog = new Ui::longTextDialog_q; m_dialog->setupUi(this); setWindowTitle("Firewall Builder"); m_dialog->dlgText->setText(txt); m_dialog->icn->setPixmap( QMessageBox::standardIcon(QMessageBox::Critical) ); m_dialog->dlgLongText->setText(ltxt); } fwbuilder-5.1.0.3599/src/libgui/ObjectSelectorWidget.h0000644000175000017500000000431011733011756023262 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTSELECTORWIDGET_H_ #define __OBJECTSELECTORWIDGET_H_ #include "ui_objectselectorwidget_q.h" #include "ObjectDescriptor.h" #include "fwbuilder/InetAddr.h" #include class Filter; class FilterDialog; class ObjectSelectorWidget : public QWidget { Q_OBJECT; Ui::ObjectSelectorWidget_q *m_dialog; Filter * flt_obj; FilterDialog * flt_obj_d; QList objects; QStringList objects_to_use; // configure this as a proprty so it can be accessed as a field after // registering with registerField(). Now it can be accessed from // other pages of the wizard Q_PROPERTY(QStringList objectsToUse READ getObjectsToUse WRITE setObjectsToUse); public: ObjectSelectorWidget(QWidget *parent); virtual ~ObjectSelectorWidget(); void init(const QList &objects); int count() { return objects_to_use.count(); } void fillListOfObjects(); void updateObjectsToUse(); QStringList getObjectsToUse() { return objects_to_use; } void setObjectsToUse(const QStringList &lst) { objects_to_use = lst; } public slots: void addFilter(); void removeFilter(); void selectAllResults(); void unselectAllResults(); void selectAllUsed(); void unselectAllUsed(); void addObject(); void removeObject(); signals: void selectionChanged(); }; #endif fwbuilder-5.1.0.3599/src/libgui/newhostdialog_q.ui0000644000175000017500000006432611733011756022601 0ustar sylvestresylvestre newHostDialog_q Qt::WindowModal 0 0 616 621 Creating new host object :/Icons/Host/icon-tree:/Icons/Host/icon-tree 0 0 0 25 Sans Serif 14 75 false true TextLabel Qt::AlignCenter 0 0 500 450 2 The Host object in Firewall Builder is designed to represent real hosts in the network: workstations, servers, and any other network node with one or several addresses. Host object is useful when it has more than one IP address because then you can just use it in any rule and have Firewall Builder generate firewall configuration to match all of its addresses. If the host object you are going to create has just one IP address, you may want to consider an Address object instead which is simpler. true Qt::Vertical QSizePolicy::Fixed 20 40 Name of the new host object: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 20 QFrame::HLine QFrame::Sunken Qt::Horizontal Use preconfigured template host objects QFrame::NoFrame QFrame::Raised Using template library file: 400 0 Select custom template library file Use standard template library Qt::Horizontal 20 20 Qt::Vertical 20 269 0 Next step is to add interfaces to the new host. There are two ways to do it: using SNMP query or manually. Adding them using SNMP query is fast and automatic, but is only possible if the host runs SNMP agent and you know SNMP community string 'read'. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Qt::Vertical QSizePolicy::Fixed 20 20 0 Configure interfaces manually true Use SNMP to discover interfaces of the host Qt::Horizontal QSizePolicy::Expanding 40 20 Discover Interfaces using SNMP SNMP 'read' community string: Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 140 20 Qt::Horizontal QSizePolicy::Expanding 40 20 0 0 0 Here you can add or edit interfaces manually. 'Name' corresponds to the name of the physical interface, such as 'eth0', 'fxp0', 'ethernet0' etc. 'Label' is used to mark interface to reflect network topology, e.g. 'outside' or 'inside'. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Check option 'Unnumbered interface' for the interface that does not have an IP address. Examples of interfaces of this kind are those used to terminate PPPoE or VPN tunnels. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Check option 'Dynamic IP Address' for the interface that gets its IP address dynamically via DHCP or PPP protocol. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Click 'Next' when done. Qt::AlignCenter false Tab 2 0 0 0 280 210 QFrame::StyledPanel QFrame::Sunken 79 77 20 52 0 0 20 20 QFrame::HLine QFrame::Sunken Qt::Horizontal 38 148 20 30 0 0 20 20 QFrame::VLine QFrame::Sunken Qt::Vertical 68 8 200 52 QFrame::Panel QFrame::Raised 88 78 180 52 QFrame::Panel QFrame::Raised 68 148 200 52 QFrame::Panel QFrame::Raised 10 70 64 64 :/Icons/host_64.xpm false false 38 28 20 30 0 0 20 20 QFrame::VLine QFrame::Sunken Qt::Vertical Choose template object in the list and click 'Finish' when ready. Template objects use generic interface names that will be iherited by the firewall object you create. You may need to rename them later to reflect real names of interfaces on your firewall machine. Qt::AlignVCenter true 1 0 400 50 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 193 19 < &Back false &Next > true false &Finish false &Cancel false InterfacesTabWidget QTabWidget
InterfacesTabWidget.h
1
obj_name useTemplate use_manual snmp_community snmpQuery snmpProgress templateList intfOutsideText intfDMZText intfInsideText templateComment obj_name textChanged(QString) newHostDialog_q changed() 20 20 20 20 use_manual toggled(bool) newHostDialog_q changed() 20 20 20 20 use_snmp toggled(bool) newHostDialog_q changed() 20 20 20 20 snmpQuery clicked() newHostDialog_q getInterfacesViaSNMP() 20 20 20 20 templateList currentItemChanged(QListWidgetItem*,QListWidgetItem*) newHostDialog_q templateSelected(QListWidgetItem*) 20 20 20 20
fwbuilder-5.1.0.3599/src/libgui/ConfirmDeleteObjectDialog.h0000644000175000017500000000317011733011756024201 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CONFIRMDELETEOBJECTDIALOG_H_ #define __CONFIRMDELETEOBJECTDIALOG_H_ #include "config.h" #include #include "FindWhereUsedWidget.h" #include #include namespace libfwbuilder { class FWObject; } class QListWidgetItem; class ConfirmDeleteObjectDialog : public QDialog { Q_OBJECT private: libfwbuilder::FWObject *object; FindWhereUsedWidget * fwu; std::map listItemsMapping; Ui::ConfirmDeleteObjectDialog_q *m_dialog; public: ConfirmDeleteObjectDialog(QWidget*p ); ~ConfirmDeleteObjectDialog(); public slots: void load(std::vector objs); void findForObject(libfwbuilder::FWObject *obj); signals: }; #endif fwbuilder-5.1.0.3599/src/libgui/instBatchOptionsDialog.h0000644000175000017500000000221711733011756023626 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __INSTBATCHOPTIONSDIALOG_H_ #define __INSTBATCHOPTIONSDIALOG_H_ #include "config.h" #include "instOptionsDialog.h" class instConf; class instBatchOptionsDialog : public instOptionsDialog { Q_OBJECT private: public: instBatchOptionsDialog(QWidget *parent, instConf *_cnf); }; #endif fwbuilder-5.1.0.3599/src/libgui/ObjectTreeViewItem.h0000644000175000017500000000461411733011756022716 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECTTREEVIEWITEM_H #define OBJECTTREEVIEWITEM_H #include #include #include #include namespace libfwbuilder { class FWObject; } class ObjectTreeView; class ObjectTreeViewItem : public QTreeWidgetItem { libfwbuilder::FWObject *objptr; libfwbuilder::FWObject *userFolderParent; QString userFolderName; QMap props; QString lib; public: ObjectTreeViewItem(QTreeWidget *parent) : QTreeWidgetItem(parent), objptr(0), userFolderParent(0) {} ObjectTreeViewItem(QTreeWidgetItem *parent) : QTreeWidgetItem(parent), objptr(0), userFolderParent(0) {} libfwbuilder::FWObject *getFWObject() const { return objptr; } libfwbuilder::FWObject *getUserFolderParent() { return userFolderParent; } void setFWObject(libfwbuilder::FWObject *obj) { objptr=obj; } void setUserFolderParent(libfwbuilder::FWObject *obj) { userFolderParent = obj; } void setUserFolderName(const QString &name) { userFolderName = name; } const QString &getUserFolderName() { return userFolderName; } ObjectTreeView* getTree(); QString getLib() { return lib; } void setLib(const QString &l) { lib=l; } QString getProperty(const QString &name) const { return props[name]; } void setProperty(const QString &name, const QString &val) { props[name]=val; } QVariant data (int column, int role) const; virtual bool operator< ( const QTreeWidgetItem & other ) const; }; #endif fwbuilder-5.1.0.3599/src/libgui/upgradePredicate.h0000644000175000017500000000372511733011756022470 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UPGRADEPREDICATE_H_ #define __UPGRADEPREDICATE_H_ #include "fwbuilder/XMLTools.h" #include "qmessagebox.h" #include "qobject.h" class MessageBoxUpgradePredicate: public libfwbuilder::XMLTools::UpgradePredicate { QWidget *parent; public: MessageBoxUpgradePredicate(QWidget *p=NULL) { parent=p; } virtual bool operator()(const std::string&) const { return QMessageBox::information( parent , "Firewall Builder", QObject::tr( "The data file you are trying to open has been \ saved with an older version of Firewall Builder. \ Opening it in this version will cause it to be \ upgraded, which may prevent older versions of \ the program from reading it. Backup copy of your \ file in the old format will be made in the same \ directory with extension '.bak'.\n\ Are you sure you want to open it?"), QObject::tr("&Upgrade"), QObject::tr("&Do not load the file"), QString::null, 0, 1 )==0; } }; #endif fwbuilder-5.1.0.3599/src/libgui/FilterLineEdit.h0000644000175000017500000000132711733011756022057 0ustar sylvestresylvestre/**************************************************************************** ** ** Copyright (c) 2007 Trolltech ASA ** ** Use, modification and distribution is allowed without limitation, ** warranty, liability or support of any kind. ** ****************************************************************************/ #ifndef FilterLineEdit_h #define FilterLineEdit_h #include class QToolButton; class FilterLineEdit : public QLineEdit { Q_OBJECT public: FilterLineEdit(QWidget *parent = 0); protected: void resizeEvent(QResizeEvent *); private slots: void updateCloseButton(const QString &text); private: QToolButton *clearButton; }; #endif /* FilterLineEdit_h */ fwbuilder-5.1.0.3599/src/libgui/FWCmdRule.cpp0000644000175000017500000004511411733011756021341 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWWindow.h" #include "FWCmdRule.h" #include "FindObjectWidget.h" #include "events.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWOptions.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include using namespace libfwbuilder; /******************************************************** * FWCmdRule ********************************************************/ FWCmdRule::FWCmdRule(ProjectPanel *project, RuleSet* ruleset, QUndoCommand* macro) : FWCmdBasic(project, macro) { this->ruleset = ruleset; } RuleSetView* FWCmdRule::getRuleSetView() { RuleSet* crs = project->getCurrentRuleSet(); if (crs != ruleset) project->openRuleSet(ruleset, true); return project->getCurrentRuleSetView(); } RuleSetModel* FWCmdRule::getRuleSetModel() { RuleSetView* rsv = getRuleSetView(); return (rsv != NULL)?(RuleSetModel*)getRuleSetView()->model():NULL; } void FWCmdRule::notify() { QCoreApplication::postEvent( mw, new dataModifiedEvent(project->getFileName(), ruleset->getId())); } void FWCmdRule::redo() { RuleSetModel* md = getRuleSetModel(); redoOnModel(md); notify(); } void FWCmdRule::undo() { RuleSetModel* md = getRuleSetModel(); undoOnModel(md); notify(); } /******************************************************** * FWCmdRuleInsert ********************************************************/ FWCmdRuleInsert::FWCmdRuleInsert(ProjectPanel *project, RuleSet* ruleset, int position, bool isAfter, Rule* ruleToInsert): FWCmdRule(project, ruleset) { this->position = position; this->isAfter = isAfter; this->ruleToInsert = ruleToInsert; this->insertedRule = 0; setText(QObject::tr("insert rule")); } FWCmdRuleInsert::~FWCmdRuleInsert() { if (ruleToInsert) delete ruleToInsert; if (insertedRule && insertedRule->getRefCounter() == 1) { delete insertedRule; } } void FWCmdRuleInsert::redoOnModel(RuleSetModel *md) { if (insertedRule == 0) { if (ruleToInsert == 0) { if (position == 0 && !isAfter) { insertedRule = md->insertNewRule(); } else { QModelIndex index = md->indexForPosition(position); insertedRule = md->insertNewRule(index, isAfter); } } else { QModelIndex index; if (position!=0 || isAfter) index = md->indexForPosition(position); insertedRule = md->insertRule(ruleToInsert, index, isAfter); } insertedRule->ref(); } else { md->insertRule(insertedRule); } getRuleSetView()->selectRE(insertedRule,0); } void FWCmdRuleInsert::undoOnModel(RuleSetModel *md) { QModelIndex index = md->index(insertedRule); getRuleSetView()->scrollTo(index, QAbstractItemView::PositionAtCenter); getRuleSetView()->unselect(); md->removeRow(index.row(), index.parent()); } /******************************************************** * FWCmdRuleDelete ********************************************************/ FWCmdRuleDelete::FWCmdRuleDelete(ProjectPanel *project, RuleSet* ruleset, QList &rulesToDelete, QUndoCommand* macro) : FWCmdRule(project, ruleset, macro) { copyRules(rulesToDelete); setText(QObject::tr("delete rules")); } void FWCmdRuleDelete::copyRules(QList &rules) { if (fwbdebug) qDebug() << "FWCmdRuleDelete::copyRules(QList &rules)"; QList positions; positions.append(-100); foreach(Rule* rule, rules) { int pos = rule->getPosition(); for(int i=positions.size()-1; i>=0; i-- ) { if (pos > positions.at(i)) { positions.insert(i+1, pos); rule->ref(); rulesToDelete.insert(i, rule); break; } } } if (fwbdebug) qDebug() << "size:" << rulesToDelete.size(); row = getRuleSetModel()->index(rulesToDelete.first(),0).row() - 1; } FWCmdRuleDelete::~FWCmdRuleDelete() { if (fwbdebug) qDebug() << "FWCmdRuleDelete::~FWCmdRuleDelete()"; foreach(Rule* rule, rulesToDelete) { if (rule != 0) { if (rule->getRefCounter() <= 1) { if (fwbdebug) qDebug() << "* delete rule:" << rule->getId(); delete rule; } else { if (fwbdebug) qDebug() << "* unref rule:" << rule->getId(); rule->unref(); } } } } void FWCmdRuleDelete::redoOnModel(RuleSetModel *md) { if (fwbdebug) qDebug() << "FWCmdRuleDelete::redoOnModel(RuleSetModel *md)"; foreach(Rule* rule, rulesToDelete) { QModelIndex index = md->index(rule, 0); md->removeRow(index.row(), index.parent()); } // invalidate selection in RuleSetView getRuleSetView()->unselect(); } void FWCmdRuleDelete::undoOnModel(RuleSetModel *md) { md->restoreRules(rulesToDelete); } /******************************************************** * FWCmdRuleDeleteFromGroup ********************************************************/ FWCmdRuleDeleteFromGroup::FWCmdRuleDeleteFromGroup( ProjectPanel *project, RuleSet* ruleset, QList rulesToDelete, QUndoCommand* macro) : FWCmdRuleDelete(project, ruleset, rulesToDelete, macro) { setText(QObject::tr("delete rules from group")); } void FWCmdRuleDeleteFromGroup::undoOnModel(RuleSetModel *md) { md->restoreRules(rulesToDelete, false); } /******************************************************** * FWCmdRuleColor ********************************************************/ FWCmdRuleColor::FWCmdRuleColor( ProjectPanel *project, RuleSet* ruleset, QList &rules, const QString &newColor) : FWCmdRule(project, ruleset), newColor(newColor) { foreach(Rule* rule, rules) { int id = rule->getId(); FWOptions *ropt = rule->getOptionsObject(); QString oldColor = QString::fromUtf8(ropt->getStr("color").c_str()); oldColors[id] = oldColor; } setText(QObject::tr("change rule(s) color")); } void FWCmdRuleColor::redoOnModel(RuleSetModel *md) { QModelIndexList indexes; foreach(int ruleId, oldColors.keys()) { Rule* rule = Rule::cast(getObject(ruleId)); if (rule != 0) { indexes.append(md->index(rule, 0)); } } md->changeRuleColor(indexes, newColor); } void FWCmdRuleColor::undoOnModel(RuleSetModel *md) { QModelIndexList indexes; foreach(int ruleId, oldColors.keys()) { indexes.clear(); Rule* rule = dynamic_cast(getObject(ruleId)); if (rule != 0) { indexes.append(md->index(rule, 0)); } md->changeRuleColor(indexes, oldColors[ruleId]); } } /******************************************************** * FWCmdRuleMove ********************************************************/ FWCmdRuleMove::FWCmdRuleMove(ProjectPanel *project, RuleSet* ruleset, int firstId, int lastId, bool direction) : FWCmdRule(project, ruleset), firstId(firstId), lastId(lastId), direction(direction) { setText((direction)?QObject::tr("move rule up"):QObject::tr("move rule down")); } void FWCmdRuleMove::redoOnModel(RuleSetModel *md) { move(md, direction); } void FWCmdRuleMove::undoOnModel(RuleSetModel *md) { move(md, !direction); } void FWCmdRuleMove::move(RuleSetModel *md, bool direction) { Rule* firstRule = Rule::cast(getObject(firstId)); Rule* lastRule = Rule::cast(getObject(lastId)); QModelIndex index = md->index(firstRule, 0); QModelIndex parent = index.parent(); int first = index.row(); index = md->index(lastRule, 0); int last = index.row(); if (direction) { // up md->moveRuleUp(parent , first, last); } else { // down md->moveRuleDown(parent , first, last); } project->getCurrentRuleSetView()->setSelectedRows( md->index(firstRule, 0), md->index(lastRule, 0)); } /******************************************************** * FWCmdRuleRenameGroup ********************************************************/ FWCmdRuleRenameGroup::FWCmdRuleRenameGroup( ProjectPanel *project, RuleSet* ruleset, QString oldName, QString newName) : FWCmdRule(project, ruleset), oldName(oldName), newName(newName) { setText(QObject::tr("Rename group of rules")); } void FWCmdRuleRenameGroup::redoOnModel(RuleSetModel *md) { QModelIndex grp = md->index(oldName); md->renameGroup(grp, newName); } void FWCmdRuleRenameGroup::undoOnModel(RuleSetModel *md) { QModelIndex grp = md->index(newName); md->renameGroup(grp, oldName); } /******************************************************** * FWCmdRuleRemoveFromGroup ********************************************************/ FWCmdRuleRemoveFromGroup::FWCmdRuleRemoveFromGroup( ProjectPanel* project, RuleSet* ruleset, Rule* firstRule, Rule* lastRule, const QString groupName, QUndoCommand* macro) : FWCmdRule(project, ruleset, macro), firstRule(firstRule), lastRule(lastRule), groupName(groupName) { setText(QObject::tr("remove object(s) from group ")+groupName); } void FWCmdRuleRemoveFromGroup::redoOnModel(RuleSetModel *md) { QModelIndex group = md->index(groupName); QModelIndex first = md->index(firstRule, 0); QModelIndex last = md->index(lastRule, 0); md->removeFromGroup(group, first.row(), last.row()); } void FWCmdRuleRemoveFromGroup::undoOnModel(RuleSetModel *md) { QModelIndex group = md->index(groupName); QModelIndex first = md->index(firstRule, 0); QModelIndex last = md->index(lastRule, 0); if (group.isValid()) { // Group still present in the ruleset. rules need to be added to rhis group. if (first.row() - 1 == group.row()) { md->addToGroupAbove(first.row(), last.row()); } else { md->addToGroupBelow(first.row(), last.row()); } } else { // Group was deleted. It should be created again. md->createNewGroup(groupName, first.row(), last.row()); } } /******************************************************** * FWCmdRuleNewGroup ********************************************************/ FWCmdRuleNewGroup::FWCmdRuleNewGroup( ProjectPanel* project, RuleSet* ruleset, Rule* firstRule, Rule* lastRule, const QString groupName) : FWCmdRule(project, ruleset), firstRule(firstRule), lastRule(lastRule) { this->groupName = getRuleSetModel()->findUniqueNameForGroup(groupName); setText(QObject::tr("create new group ")+this->groupName); } void FWCmdRuleNewGroup::redoOnModel(RuleSetModel *md) { QModelIndex first = md->index(firstRule, 0); QModelIndex last = md->index(lastRule, 0); QModelIndex index = md->createNewGroup(groupName, first.row(), last.row()); project->getCurrentRuleSetView()->setFirstColumnSpanned(index.row(), QModelIndex(), true); } void FWCmdRuleNewGroup::undoOnModel(RuleSetModel *md) { QModelIndex group = md->index(groupName); QModelIndex first = md->index(firstRule, 0); QModelIndex last = md->index(lastRule, 0); md->removeFromGroup(group, first.row(), last.row()); } /******************************************************** * FWCmdRuleAddToGroup ********************************************************/ FWCmdRuleAddToGroup::FWCmdRuleAddToGroup( ProjectPanel* project, RuleSet* ruleset, Rule* firstRule, Rule* lastRule, bool isAbove) : FWCmdRule(project, ruleset), firstRule(firstRule), lastRule(lastRule), isAbove(isAbove) { setText((isAbove)?QObject::tr("add to group above"):QObject::tr("add to group below")); } void FWCmdRuleAddToGroup::redoOnModel(RuleSetModel *md) { QModelIndex first = md->index(firstRule, 0); QModelIndex last = md->index(lastRule, 0); groupName = (isAbove)? md->addToGroupAbove(first.row(), last.row()): md->addToGroupBelow(first.row(), last.row()); } void FWCmdRuleAddToGroup::undoOnModel(RuleSetModel *md) { QModelIndex group = md->index(groupName); QModelIndex first = md->index(firstRule, 0); QModelIndex last = md->index(lastRule, 0); md->removeFromGroup(group, first.row(), last.row()); } /******************************************************** * FWCmdRuleChange ********************************************************/ FWCmdRuleChange::FWCmdRuleChange( ProjectPanel *project, RuleSet* ruleset, FWObject *obj, QString text, QUndoCommand* macro) : FWCmdChange(project, obj, text, false, macro), ruleset(ruleset) { } void FWCmdRuleChange::selectAffectedRule() { RuleSetView* rsv = project->getCurrentRuleSetView(); RuleSetModel* md = (RuleSetModel*)rsv->model(); Rule* currentRule = md->getRule(rsv->currentIndex()); if(currentRule == 0 || (currentRule->getId() != getRule()->getId())) rsv->selectRE(getRule(), 0); } void FWCmdRuleChange::redo() { prepareRuleSetView(); FWCmdChange::redo(); selectAffectedRule(); } void FWCmdRuleChange::undo() { prepareRuleSetView(); FWCmdChange::undo(); selectAffectedRule(); } void FWCmdRuleChange::notify() { RuleSetView* rsv = project->getCurrentRuleSetView(); RuleSetModel* md = (RuleSetModel*)rsv->model(); Rule* rule = getRule(); md->rowChanged(md->index(rule, 0)); // rsv->updateColumnSizeForIndex(md->index(rule, 0)); QCoreApplication::postEvent( mw, new dataModifiedEvent(project->getFileName(), ruleset->getId())); } void FWCmdRuleChange::prepareRuleSetView() { RuleSet* crs = project->getCurrentRuleSet(); if (crs != ruleset) project->openRuleSet(ruleset, true); } libfwbuilder::Rule* FWCmdRuleChange::getRule() { return Rule::cast(getObject()); } /******************************************************** * FWCmdRuleChangeAction * * This command is used when user modifies parameters of an action, not * when they change action of a rule. * ********************************************************/ FWCmdRuleChangeAction::FWCmdRuleChangeAction( ProjectPanel *project, FWObject *obj) : FWCmdRuleChange(project, RuleSet::cast(obj->getParent()), obj, QObject::tr("Edit Rule Action")) {}; void FWCmdRuleChangeAction::notify() { FWCmdRuleChange::notify(); if (mw->isEditorVisible()) { QCoreApplication::postEvent( mw, new openOptObjectInEditorEvent(project->getFileName(), getRule()->getId(), ObjectEditor::optAction)); } } /******************************************************** * FWCmdRuleChangeComment ********************************************************/ FWCmdRuleChangeComment::FWCmdRuleChangeComment( ProjectPanel *project, FWObject *obj) : FWCmdRuleChange(project, RuleSet::cast(obj->getParent()), obj, QObject::tr("Edit Rule Comment")) { } void FWCmdRuleChangeComment::notify() { FWCmdRuleChange::notify(); if (mw->isEditorVisible()) { QCoreApplication::postEvent( mw, new openOptObjectInEditorEvent( project->getFileName(), getRule()->getId(), ObjectEditor::optComment)); } } /******************************************************** * FWCmdRuleChangeOptions ********************************************************/ FWCmdRuleChangeOptions::FWCmdRuleChangeOptions( ProjectPanel *project, FWObject *obj) : FWCmdRuleChange(project, RuleSet::cast(obj->getParent()), obj, QObject::tr("Edit Rule Options")) {}; void FWCmdRuleChangeOptions::notify() { FWCmdRuleChange::notify(); if (mw->isEditorVisible()) { QCoreApplication::postEvent( mw, new openObjectInEditorEvent( project->getFileName(), getRule()->getId())); } } /******************************************************** * FWCmdRuleChangeRe ********************************************************/ FWCmdRuleChangeRe::FWCmdRuleChangeRe( ProjectPanel *project, RuleSet* ruleset, FWObject *obj, int position, int column, int number, QString text, QUndoCommand* macro) : FWCmdRuleChange(project, ruleset, obj, text, macro) { this->column = column; this->number = number; this->position = position; } Rule* FWCmdRuleChangeRe::getRule() { return Rule::cast(getObject()->getParent()); } void FWCmdRuleChangeRe::notify() { FWCmdRuleChange::notify(); project->getCurrentRuleSetView()->selectObject(position, column, number); mw->findObjectWidget->reset(); } /******************************************************** * FWCmdRuleNegateRE ********************************************************/ FWCmdRuleNegateRE::FWCmdRuleNegateRE( ProjectPanel *project, RuleSet* ruleset, RuleElement* ruleElement, int position, int column) : FWCmdRuleChangeRe(project, ruleset, ruleElement, position, column, 0, QObject::tr("Negate")) { } void FWCmdRuleNegateRE::redo() { prepareRuleSetView(); RuleElement* ruleElement = RuleElement::cast(getObject()); ruleElement->toggleNeg(); RuleSetView* rsv = project->getCurrentRuleSetView(); RuleSetModel* md = (RuleSetModel*)rsv->model(); md->rowChanged(md->index(getRule(), 0)); selectAffectedRule(); notify(); } void FWCmdRuleNegateRE::undo() { prepareRuleSetView(); RuleElement* ruleElement = RuleElement::cast(getObject()); ruleElement->toggleNeg(); RuleSetView* rsv = project->getCurrentRuleSetView(); RuleSetModel* md = (RuleSetModel*)rsv->model(); md->rowChanged(md->index(getRule(), 0)); selectAffectedRule(); notify(); } fwbuilder-5.1.0.3599/src/libgui/customservicedialog_q.ui0000644000175000017500000002216111733011756023774 0ustar sylvestresylvestre CustomServiceDialog_q true 0 0 754 262 Custom Service QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 1 0 0 0 0 0 0 0 Platform: false Custom service object has separate code string for each supported firewall platform. 0 0 Code String: false 0 0 0 0 Custom service object has separate code string for each supported firewall platform. Qt::AlignLeading 0 0 Protocol Name: Choose one of the standard protocols from the menu or enter custom protocol string. Policy compilers can use this information to add correct protocol-specific parameters to the generated configuration. For example, iptables compiler is allowed to add "--reject-with tcp-reset" to the target REJECT only if service object belongs to protocol "tcp". true Qt::Horizontal 108 20 Address Family: IPv4 true IPv6 false Qt::Horizontal 40 20 Qt::Vertical 20 53 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name platform code platform activated(int) CustomServiceDialog_q platformChanged() 20 20 20 20 changed()
fwbuilder-5.1.0.3599/src/libgui/SimpleTextEditor.cpp0000644000175000017500000000544611733011756023022 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "SimpleTextEditor.h" #include "FWBSettings.h" #include #include #include #include #include using namespace std; SimpleTextEditor::SimpleTextEditor(QWidget *parent, const QString &txt, bool enableLoadFromFile, const QString &title) : QDialog(parent) { m_dialog = new Ui::SimpleTextEditor_q; m_dialog->setupUi(static_cast(this)); if (enableLoadFromFile) m_dialog->inputFromFileButton->show(); else m_dialog->inputFromFileButton->hide(); if (!title.isEmpty()) setWindowTitle(title); //editor->setTextFormat(QTextEdit::PlainText); m_dialog->editor->setPlainText(txt); } SimpleTextEditor::~SimpleTextEditor() { delete m_dialog; } QString SimpleTextEditor::text() { return m_dialog->editor->toPlainText(); } void SimpleTextEditor::loadFromFile() { if (QMessageBox::warning(this, tr("Firewall Builder"), tr("Warning: loading from file discards " "current contents of the script."), "&Load", "&Cancel", QString::null, 0, 1 ) != 0) { return; } QString filename = QFileDialog::getOpenFileName(this, tr("Choose file"), st->getOpenFileDir()); if (filename.isEmpty()) return; st->setOpenFileDir(filename); ifstream ifile(filename.toLatin1().constData()); if (!ifile) { QMessageBox::warning( this,"Firewall Builder", tr("Could not open file %1").arg(filename), "&Continue", QString::null, QString::null, 0, 1 ); return; } m_dialog->editor->clear(); char buf[1024]; while (ifile.getline(buf,1024)) { m_dialog->editor->append( buf ); } } fwbuilder-5.1.0.3599/src/libgui/KeywordsDialog.h0000644000175000017500000000320611733011756022141 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Theron Tock This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __KeywordsDialog_h_ #define __KeywordsDialog_h_ #include "fwbuilder/FWObject.h" #include #include class QStringListModel; class KeywordsDialog : public QDialog { private: Q_OBJECT; Ui_KeywordsDialog_q m_ui; libfwbuilder::FWObject *m_obj; QStringListModel *m_allModel; QStringListModel *m_currModel; QSet m_allKeywords; QSet m_currKeywords; public: KeywordsDialog(libfwbuilder::FWObject *obj, QWidget *parent = 0); ~KeywordsDialog(); QStringList getKeywords(); public slots: void gotAddClick(); void gotRemoveClick(); void gotAllKeywordsDoubleClick(const QModelIndex &); void gotNewKeywordClick(); public: static bool validateKeyword(QWidget *parent, const QString &keyword); }; #endif /* KeywordsDialog_h_ */ fwbuilder-5.1.0.3599/src/libgui/ipfadvanceddialog_q.ui0000644000175000017500000012441011733011756023345 0ustar sylvestresylvestre ipfAdvancedDialog_q Qt::WindowModal 0 0 689 567 ipf: advanced settings false 11 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true 0 Compiler Compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 32767 0 0 Command line options for the compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 32767 0 0 Output file name. If left blank, the file name is constructed of the firewall object name and extension ".fw" Qt::AlignVCenter true 32767 32767 Generated script (.fw file) and configuration (.conf) files can be copied to the firewall machine under different names. If these fields are left blank, the file name does not change. true Script (.fw) file name on the firewall 32767 22 ipf.conf file name on the firewall 32767 22 nat.conf file name on the firewall 32767 22 QFrame::HLine QFrame::Sunken Qt::Horizontal QFrame::HLine QFrame::Sunken Qt::Horizontal Always permit ssh access from the management workstation with this address: 0 0 32767 32767 Qt::Vertical QSizePolicy::Expanding 20 16 Find and eliminate duplicate rules Accept TCP sessions opened prior to firewall restart If the option is deactivated, compiler treats empty groups as an error and aborts processing the policy. If this option is activated, compiler removes all empty groups from all rule elements. If rule element becomes 'any' after the last empty group has been removed, the whole rule will be ignored. Use this option only if you fully understand how it works! Ignore empty groups in rules Shadowing happens because a rule is a superset of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. Detect rule shadowing in policy 400 32767 Default action on 'Reject': Qt::AlignVCenter true 0 0 400 32767 Masquerade returned icmp as being from original packet's destination Protocol Helpers 6 Qt::Vertical QSizePolicy::Fixed 20 20 Use raudio proxy in NAT rules Use h323 proxy in NAT rules Use ipsec proxy in NAT rules Qt::Horizontal QSizePolicy::Fixed 40 100 Use ftp proxy in NAT rules Use rcmd proxy in NAT rules Use Kerberos rcmd proxy in NAT rules Use Kerberos ekshell proxy in NAT rules Qt::Vertical QSizePolicy::Expanding 20 270 Use PPTP proxy in NAT rules Use IRC proxy in NAT rules for DCC 0 0 Some protocols involve multiple associated network connections. Firewall can keep track of such connections automatically if you activate one or all of the following options: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Installer Built-in installer Directory on the firewall where configuration files should be installed Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 A command that installer should execute on the firewall in order to activate the policy (if this field is blank, installer runs firewall script in the directory specified above; it uses sudo if user name is not 'root') Qt::AlignVCenter true 0 0 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 Qt::Vertical QSizePolicy::Fixed 20 20 External install script 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 Qt::Vertical QSizePolicy::Expanding 20 20 Prolog/Epilog 6 6 Qt::Horizontal QSizePolicy::Expanding 40 20 Edit The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOff 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOff The following commands will be added verbatim after generated configuration Qt::AlignVCenter true Logging 6 Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Horizontal QSizePolicy::Fixed 130 20 Qt::Horizontal QSizePolicy::Expanding 120 20 Qt::Vertical QSizePolicy::Expanding 20 240 Log facility: false Log level: false Log packet body Block if can not log Qt::Vertical QSizePolicy::Fixed 20 20 Script Options 6 Qt::Horizontal QSizePolicy::Fixed 40 70 Add virtual addresses for NAT Configure Interfaces of the firewall machine Turn debugging on in generated script If this option is on, policy compiler adds virtual addresses to the interfaces to make the firewall answer to ARP queries for addresses used in NAT rules. Optimization These options enable auxiliary sections in the generated shell script. Qt::AlignVCenter true Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Vertical QSizePolicy::Expanding 20 200 Determine addresses of dynamic interfaces at run time IPv6 Enable IPv6 support The order in which ipv4 and ipv6 rules should be generated: Qt::Horizontal 40 20 IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 tabWidget ipf_nat_ftp_proxy ipf_nat_rcmd_proxy ipf_nat_raudio_proxy ipf_nat_h323_proxy ipf_nat_ipsec_proxy ipf_nat_pptp_proxy ipf_nat_irc_proxy compiler compilerArgs outputFileName mgmt_ssh mgmt_addr buttonOk buttonCancel ipf_fw_dir ipf_user altAddress activationCmd sshArgs installScript installScriptArgs prolog_script edit_prolog_button epilog_script edit_epilog_button logFacility logLevel ipf_log_or_block ipf_log_body ipf_debug ipf_configure_interfaces ipf_manage_virtual_addr ipf_optimize ipf_dynAddr ipv6_2 ipv4before_2 buttonOk clicked() ipfAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() ipfAdvancedDialog_q reject() 20 20 20 20 edit_epilog_button clicked() ipfAdvancedDialog_q editEpilog() 20 20 20 20 edit_prolog_button clicked() ipfAdvancedDialog_q editProlog() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/gui.cw0000644000175000017500000000636611733011756020172 0ustar sylvestresylvestre findObjectWidget_q
findobjectwidget_q.h
1 0 1 0 0 789c7dd2c98eda401080e13b4f618d6f28626c8c37453960cf35518e91a21cbabbbab159bc2f4094774f55616066d04c09097e7dd0edb6799e5bbf7e7eb7e6cfb3b6135dae2c9589c69a437f389c7efff9f677f6b4f42d7c794bcb7dfa327b5a58cafa51169a3ea7f8d9f642cff3984a4a3ff2a4ab28cf9c2650317fd9a60c9c48a88072cde9862bb9a23c51864134e59133f65dc7a36c29232102e0dff69c3a3697a546cad8151242ca827319f9a14f59737a42a898f2c01907e02c29334e255d60dd520a470a059486d39311706a4e21b57628f79472192d1d3e7ec5b95281e6236c387d2520a2dc512a37761cfe2d5c121ccdfb2ace107ccdb74e7202c49af71594e0025c32e7f4c1185e2ae1947a65f8440da576f1eef0650c9c421bc397d1519ac04486377ae1c489f93216b7b1a799f21d0aa9406b233ec5cd8768b27cb37d8dbbfd7e7f3814256265ea46e9fa8ebba2acdaae4355aa32fd90c3b6be229a1063d70da4885d23406f6d46b46618cc3034f9119730fde97c5e9f4e8cfba21c86ae6b9b2497702c525dbfc50e97a4070d156295f5279a37080015a3ceeabeaf2f7898b0aa2a6d10153e429cf68a035e8c8d4fc26488522af21b264992db59968d2322ee4ddcaef9287467a46ac7716cd1923c2796132ef07450b5386829ad427e45523d595a3609fb0d17479e22edd2f4a56c1af23b4e8f0c8f545eb4691e90f625a5f707b4d738a4f4fe0ea7217dfc9bdc352d3fc445597e828b3425fcf775f61fb8fe4c11 enableAll() public disableAll()
FWObjectDropArea
FWObjectDropArea.h
-1 2 1 0 5 789c7dd14baf9a4014c0f1bd9f82c8ce345e1c6084345d7075dba6cb264d17675ebc45117cdca6dfbd738e7a0bdcd4890bfffe9c17bc2c9c1fdfbf3a8b97d9b1832e978ecca07516aaafebebcf5f5f7ecfe62c74ecc767ce6afe6936771de97c6b761abf2fed77373411488e79c4e41ed7b1c1dcde72ed8b107347c979c415668bb90ea29560981d66c4e295a0b91b4a00ae68e59ad2c42178980d66ecc14a469825e51a40fa98052670c1a5c034f78c95c44c31852f99a25369ca40721d60e694462a458754f7d49a36929832528106cc8452b280c59882522bd0b4ef89d2f88cd19f7b4cb50a3c460a94bed29aee7ba60cc390d1212f94c00da36364b7d4bea16775a5b48f9dd1dc374ced29ae492b4adfbe04bae02b65a0bddba9f694c278866e74c03481e18674f96fb8a34108c23e176d4f6cc43384f4096679f1016551a6886525d3728a79bd2b119b3de4a69cce4ccb141f6173a8204f8be5103390f81a2db6c763dbb5631469912396168fed0465bd2bf0c045d7b61f6716756a57d669d1374d33c62a13b994a87d6f8ce92698010821e5e9d4f7fdf97cb95caed7777c4b92c46a92a0ded132e1fe151192095e6f58d9dfedd28876ebcd18f7fbaaa28d4fbd1062b31d2e7b786896f500b0d9ba2eda1def4a9c6588ee005189ab07ba031c7075c3c73d379331c2e5763206e8fe6f3cc73f9f677f01b5d841ae objectInserted() objectDeleted()
fwbuilder-5.1.0.3599/src/libgui/CustomServiceDialog.h0000644000175000017500000000333611733011756023131 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CUSTOMSERVICEDIALOG_H_ #define __CUSTOMSERVICEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include #include namespace libfwbuilder { class FWObject; }; class ProjectPanel; class CustomServiceDialog : public BaseObjectDialog { Q_OBJECT QMap platformReverseMap; QMap allCodes; QString showPlatform; Ui::CustomServiceDialog_q *m_dialog; protected: void fillDialogInputFields(); public: CustomServiceDialog(QWidget *parent); ~CustomServiceDialog(); public slots: virtual void changed(); virtual void platformChanged(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // CUSTOMSERVICEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/FirewallSelectorWidget.cpp0000644000175000017500000002031011733011756024152 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "FirewallSelectorWidget.h" #include using namespace std; using namespace libfwbuilder; FirewallSelectorWidget::FirewallSelectorWidget(QWidget *parent): QTableWidget(parent) { // this->setHorizontalHeaderLabels(QStringList() << tr("Title") << tr("Use") << tr("Master")); } FirewallSelectorWidget::~FirewallSelectorWidget() { clear(); } void FirewallSelectorWidget::setFirewallList(list firewalls, bool select) { QSet nonuniq; foreach (Firewall* fw1, firewalls) { foreach (Firewall* fw2, firewalls) { if (fw1 != fw2 && fw1->getName() == fw2->getName() && fw2->getLibraryName() != fw1->getLibraryName()) { nonuniq.insert(fw1); nonuniq.insert(fw2); } } } this->clear(); Firewall *fw; for (list::iterator it = firewalls.begin(); it != firewalls.end(); it++) { fw = *it; QTableWidgetItem *title = new QTableWidgetItem(QIcon(":/Icons/Firewall/icon"), QString::fromUtf8(fw->getName().c_str())); if (nonuniq.contains(fw)) title->setText((fw->getLibraryName() + " / " + fw->getName()).c_str()); title->setFlags(Qt::ItemIsEnabled); QCheckBox *box = new QCheckBox(this); connect(box, SIGNAL(toggled(bool)), this, SLOT(usageChanged(bool))); QRadioButton *radio = new QRadioButton(this); radio->setEnabled(false); TableRow rw; rw.firewall = fw; rw.master = radio; rw.title = title; rw.use = box; int rowNumber = this->rowCount(); boxrow[box] = rowNumber; radiorow[radio] = rowNumber; this->insertRow(rowNumber); rows[rowNumber] = rw; this->setItem(rowNumber, 0, title); this->setCellWidget(rowNumber, 1, box); this->setCellWidget(rowNumber, 2, radio); if (select) box->setChecked(true); } this->sortItems(0, Qt::AscendingOrder); } void FirewallSelectorWidget::usageChanged(bool st) { int row = this->boxrow[dynamic_cast(sender())]; if (!st) rows[row].master->setChecked(st); rows[row].master->setEnabled(st); bool isMaster = false, isSelected = false; foreach(TableRow row, this->rows.values()) { if (row.use->isChecked()) isSelected = true; if (row.master->isChecked() && row.use->isChecked()) isMaster = true; } if (isSelected && !isMaster) { foreach(TableRow row, this->rows.values()) { if (row.use->isChecked()) { row.master->setChecked(true); break; } } } } QList > FirewallSelectorWidget::getSelectedFirewalls() { QList > res; foreach(TableRow row, this->rows.values()) { if (row.use->isChecked()) res.append(qMakePair(row.firewall, row.master->isChecked())); } return res; } bool FirewallSelectorWidget::isValid() { QString host_os, platform, version; QList > fws = this->getSelectedFirewalls(); if (fws.count() == 0) { QMessageBox::critical( this, "Firewall Builder", tr("You should select at least one firewall to use " "with the cluster"), "&Continue", QString::null, QString::null, 0, 1); return false; } for ( int i = 0; i < fws.count(); i++) { if (host_os.isEmpty()) host_os = fws.at(i).first->getStr("host_OS").c_str(); else if (host_os != fws.at(i).first->getStr("host_OS").c_str()) { QMessageBox::critical( this, "Firewall Builder", tr("Host operation systems of chosen firewalls are different"), "&Continue", QString::null, QString::null, 0, 1); return false; } if (platform.isEmpty()) platform = fws.at(i).first->getStr("platform").c_str(); else if (platform != fws.at(i).first->getStr("platform").c_str()) { QMessageBox::critical( this, "Firewall Builder", tr("Platforms of chosen firewalls are different"), "&Continue", QString::null, QString::null, 0, 1); return false; } #ifdef COMPARE_MEMBER_VERSIONS_FOR_CLUSTER if (version.isEmpty()) version = fws.at(i).first->getStr("version").c_str(); else if (version != fws.at(i).first->getStr("version").c_str()) { QMessageBox::critical( this, "Firewall Builder", tr("Versions of chosen firewalls are different"), "&Continue", QString::null, QString::null, 0, 1); return false; } #endif } int ok = false; // check for at least one same interface in all firwalls if ( fws.count() ) { FWObjectTypedChildIterator intrs = fws.first().first->findByType(Interface::TYPENAME); for ( ; intrs!=intrs.end(); ++intrs ) { //if (Interface::cast(*intrs)->isLoopback()) continue; string name = Interface::cast(*intrs)->getName(); int got = 0; for ( int j = 0; j < fws.count(); j++) { FWObjectTypedChildIterator intrs2 = fws.at(j).first->findByType(Interface::TYPENAME); for ( ; intrs2!=intrs2.end(); ++intrs2 ) { if (Interface::cast(*intrs2)->getName() == name) { got ++; break; } } } if (got == fws.count()) { ok = true; break; } } }/* foreach ( string name, interfaces ) { int used = 0; foreach ( Firewall* fw, firewalls ) { FWObjectTypedChildIterator iter = fw->findByType(Interface::TYPENAME); for ( ; iter != iter.end(); ++iter ) { Interface *interface = Interface::cast(*iter); if (interface->getName() == name ) { used++; break; } } } if ( used == firewalls.count() ) usedInterfaces.insert(name); }*/ if (!ok) { QMessageBox::critical( this, "Firewall Builder", tr("Cluster firewalls should have at least one common inteface"), "&Continue", QString::null, QString::null, 0, 1); } return ok; } void FirewallSelectorWidget::clear() { //QTableWidget::clear(); for (int i =0; i < this->rows.keys().count(); i++) { this->removeRow(i); boxrow.remove(rows[i].use); radiorow.remove(rows[i].master); delete this->rows[i].master; delete this->rows[i].use; } boxrow.clear(); radiorow.clear(); rows.clear(); this->setRowCount(0); // QTableWidget::clear(); } void FirewallSelectorWidget::resizeEvent(QResizeEvent*) { int total = this->viewport()->width(); if (total < 100) total = int(this->width() * 0.95); int controls; if ( total/3 > 100 ) controls = 100; else controls = total/3; this->setColumnWidth(0, total - controls*2); this->setColumnWidth(1, controls); this->setColumnWidth(2, controls); } fwbuilder-5.1.0.3599/src/libgui/PrintingProgressDialog.h0000644000175000017500000000276511733011756023662 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PRINTINGPROGRESSDIALOG_H_ #define __PRINTINGPROGRESSDIALOG_H_ #include #include #include #include #include class PrintingProgressDialog : public QDialog { Q_OBJECT QPrinter *printer; int totalPages; Ui::printingProgressDialog_q *m_dialog; public: PrintingProgressDialog(QWidget *parent,QPrinter *p,int nPages,bool disableCancel); ~PrintingProgressDialog(); void setCurrentPageNo(int n); void genericProgressIndicator(int n,const QString &txt); void setNPages(int n); public slots: void abortPrinting(); }; #endif fwbuilder-5.1.0.3599/src/libgui/NetworkDialog.cpp0000644000175000017500000002177011733011756022324 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "NetworkDialog.h" #include "ProjectPanel.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Network.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Inet6AddrMask.h" #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; NetworkDialog::NetworkDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::NetworkDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } NetworkDialog::~NetworkDialog() { delete m_dialog; } void NetworkDialog::loadFWObject(FWObject *o) { obj = o; Network *s = dynamic_cast(obj); assert(s!=NULL); init = true; // See #893 No need to show address and mask 0.0.0.0 to the user // if the object is "Any", especially because the same object is // used as "any" for both ipv4 and ipv6 rules. It can be confusing // if they see address "0.0.0.0" while they want to find object // "any" for ipv6. // see also #2454, trying to do even more handholding for users // who do not understand what "any" means in a rule. if (obj->getId() == FWObjectDatabase::ANY_ADDRESS_ID) { m_dialog->object_attributes->hide(); m_dialog->commentKeywords->setReadOnlyComment( QObject::tr( "When used in the Source or Destination field of a rule, " "the Any object will match all " "IP addresses. To update your rule to match only specific " "IP addresses, drag-and-drop an object from " "the Object tree into the field in the rule.")); } else { m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->address->setText( s->getAddressPtr()->toString().c_str() ); m_dialog->netmask->setText( s->getNetmaskPtr()->toString().c_str() ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->object_attributes->show(); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->address->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->address); m_dialog->netmask->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->netmask); } init = false; } void NetworkDialog::validate(bool *result) { if (fwbdebug) qDebug() << "NetworkDialog::validate"; *result = true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *result = false; return; } Network *s = dynamic_cast(obj); assert(s!=NULL); try { InetAddr( m_dialog->address->text().toStdString() ); } catch (FWException &ex) { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this, "Firewall Builder", tr("Illegal IP address '%1'").arg(m_dialog->address->text()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } return; } InetAddr addr(m_dialog->address->text().toStdString()); try { QString len = m_dialog->netmask->text() ; bool ok = false ; int ilen = len.toInt(&ok); if (ok) { // permit netmask 0.0.0.0 if the address is also 0.0.0.0 if (addr.isAny() && ilen == 0) return; if (ilen>0 && ilen < 32) { return ; } else { *result = false; QMessageBox::critical( this, "Firewall Builder", tr("Illegal netmask '%1'").arg( m_dialog->netmask->text() ), tr("&Continue"), 0, 0, 0 ); return; } } InetAddr nm( m_dialog->netmask->text().toStdString() ); if (nm.isAny()) { // permit netmask 0.0.0.0 if the address is also 0.0.0.0 if (addr.isAny()) return; else { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); // Do not allow netmask of 0 bits See #251 QMessageBox::critical( this, "Firewall Builder", tr("Network object should not have netmask '0.0.0.0'"), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } return; } } if (!nm.isValidV4Netmask()) { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); // Do not allow netmask with zeroes inside. QMessageBox::critical( this, "Firewall Builder", tr("Netmasks with zeroes in the middle are not supported"), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } return; } } catch (FWException &ex) { *result = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this, "Firewall Builder", tr("Illegal netmask '%1'").arg( m_dialog->netmask->text() ), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } } void NetworkDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); Network *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName(string(m_dialog->obj_name->text().toUtf8().constData())); m_dialog->commentKeywords->applyChanges(new_state); try { s->setAddress(InetAddr(m_dialog->address->text().toStdString())); } catch (FWException &ex) { // exception thrown if user types illegal m_dialog->address or // m_dialog->netmask } try { QString len = m_dialog->netmask->text() ; bool ok = false ; int ilen = len.toInt (&ok); if (ok) { s->setNetmask(InetAddr(ilen)); } else { s->setNetmask(InetAddr(m_dialog->netmask->text().toStdString())); } } catch (FWException &ex) { // exception thrown if user types illegal m_dialog->address or // m_dialog->netmask // bool ok = false ; } if (!cmd->getOldState()->cmp(new_state, true)) { if (fwbdebug) qDebug() << "Pushing FWCmdChange to undo stack"; if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void NetworkDialog::addressEntered() { try { QString addr = m_dialog->address->text(); InetAddrMask address_and_mask(string(addr.toStdString())); if (addr.contains('/')) { m_dialog->address->setText( address_and_mask.getAddressPtr()->toString().c_str()); m_dialog->netmask->setText( address_and_mask.getNetmaskPtr()->toString().c_str()); } } catch (FWException &ex) { // exception thrown if user types illegal m_dialog->address do // not show error dialog. This method is called by // editingFinished signal and therefore is invoked when user // switches focus from the address input widget to some other // widget or even when user switches to another application to // look up the address. Error dialog interrupts the workflow // in the latter case which is annoying. } } fwbuilder-5.1.0.3599/src/libgui/simpletextview_q.ui0000644000175000017500000000557611733011756023025 0ustar sylvestresylvestre SimpleTextView_q 0 0 488 592 Qt::StrongFocus Text viewer QFrame::StyledPanel QFrame::Plain 11 75 true Object Name false true QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Horizontal QSizePolicy::Expanding 91 20 Close pushButton7 released() SimpleTextView_q close() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/ICMPServiceDialog.h0000644000175000017500000000264711733011756022413 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ICMPSERVICEDIALOG_H_ #define __ICMPSERVICEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class ICMPServiceDialog : public BaseObjectDialog { Q_OBJECT; Ui::ICMPServiceDialog_q *m_dialog; public: ICMPServiceDialog(QWidget *parent); ~ICMPServiceDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // ICMPSERVICEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/instConf.cpp0000644000175000017500000000431211733011756021327 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "instConf.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWException.h" #include "fwbuilder/Firewall.h" #include #include #include #include #include using namespace std; using namespace libfwbuilder; instConf::instConf() { clear(); } QString instConf::getCmdFromResource(const QString &resource_name) { if (fwbdebug) qDebug() << QString("instConf::getCmdFromResource resource_name=%1") .arg(resource_name); string optpath_root = "activation/reg_user/run/"; string optpath = optpath_root + resource_name.toStdString(); QString cmd = Resources::getTargetOptionStr(fwobj->getStr("host_OS"), optpath).c_str(); cmd = cmd.trimmed(); if (fwbdebug) qDebug() << "instConf::getCmdFromResource cmd=" << cmd; return cmd; } void instConf::clear() { quiet = false; verbose = false; debug = 0; incremental = false; dry_run = false; saveStandby = false; save_diff = false; diff_pgm = ""; no_gui = false; backup = false; backup_file = ""; wdir = "./"; fwobj = NULL; maddr = ""; user = ""; batchInstall = false; sshArgs = ""; scpArgs = ""; putty_session = ""; fwscript = ""; } fwbuilder-5.1.0.3599/src/libgui/finddialog_q.ui0000644000175000017500000001430011733011756022015 0ustar sylvestresylvestre findDialog_q 0 0 424 196 0 0 Qt::StrongFocus Find Object true QComboBox::InsertAtTop false Text to be found in object names: false Search in policy rules Search in the tree true Qt::Vertical QSizePolicy::Expanding 20 30 Find true QFrame::HLine QFrame::Sunken true Matching attribute: false Address TCP/UDP port Protocol number ICMP type Search for substring using regular expressions findText attribute findAttr useRegexp searchInTree searchInRules findBtn findBtn clicked() findDialog_q find() 20 20 20 20 findText activated(QString) findDialog_q findTextChanged(QString) 20 20 20 20 findText editTextChanged(QString) findDialog_q findTextChanged(QString) 20 20 20 20 findAttr activated(QString) findDialog_q findAttrChanged(QString) 20 20 20 20 findAttr editTextChanged(QString) findDialog_q findAttrChanged(QString) 20 20 20 20 attribute activated(QString) findDialog_q findAttrChanged(QString) 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/DNSNameDialog.cpp0000644000175000017500000000721511733011756022116 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "DNSNameDialog.h" #include "ProjectPanel.h" #include "FWBSettings.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/Interface.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" using namespace std; using namespace libfwbuilder; DNSNameDialog::DNSNameDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::DNSNameDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } DNSNameDialog::~DNSNameDialog() { delete m_dialog; } void DNSNameDialog::loadFWObject(FWObject *o) { obj=o; DNSName *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->dnsrec->setText( s->getSourceName().c_str() ); m_dialog->r_compiletime->setChecked(s->isCompileTime() ); m_dialog->r_runtime->setChecked(s->isRunTime() ); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->dnsrec->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->dnsrec); if (st->getBool("Objects/DNSName/useNameForDNSRecord")) m_dialog->dnsrec->setEnabled(false); init=false; } void DNSNameDialog::validate(bool *res) { *res=true; DNSName *s = dynamic_cast(obj); assert(s!=NULL); if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void DNSNameDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); DNSName *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); s->setRunTime(m_dialog->r_runtime->isChecked() ); if (st->getBool("Objects/DNSName/useNameForDNSRecord") && m_dialog->obj_name->text() != m_dialog->dnsrec->text()) m_dialog->dnsrec->setText(m_dialog->obj_name->text().trimmed()); s->setSourceName( m_dialog->dnsrec->text().trimmed().toLatin1().constData() ); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/freebsdAdvancedDialog.cpp0000644000175000017500000000747111733011756023735 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "freebsdAdvancedDialog.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Management.h" #include #include #include #include #include #include #include #include "FWWindow.h" using namespace std; using namespace libfwbuilder; freebsdAdvancedDialog::~freebsdAdvancedDialog() { delete m_dialog; } freebsdAdvancedDialog::freebsdAdvancedDialog(QWidget *parent,FWObject *o) : QDialog(parent) { m_dialog = new Ui::freebsdAdvancedDialog_q; m_dialog->setupUi(this); obj=o; FWOptions *fwopt=(Firewall::cast(obj))->getOptionsObject(); assert(fwopt!=NULL); Management *mgmt=(Firewall::cast(obj))->getManagementObject(); assert(mgmt!=NULL); QStringList threeStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); data.registerOption(m_dialog->freebsd_ip_sourceroute, fwopt, "freebsd_ip_sourceroute", threeStateMapping); data.registerOption(m_dialog->freebsd_ip_redirect, fwopt, "freebsd_ip_redirect", threeStateMapping); data.registerOption(m_dialog->freebsd_ip_forward, fwopt, "freebsd_ip_forward", threeStateMapping); data.registerOption(m_dialog->freebsd_ipv6_forward, fwopt, "freebsd_ipv6_forward", threeStateMapping); data.registerOption(m_dialog->freebsd_path_ipnat, fwopt, "freebsd_path_ipnat"); data.registerOption(m_dialog->freebsd_path_sysctl, fwopt,"freebsd_path_sysctl"); data.registerOption(m_dialog->freebsd_path_ipf, fwopt, "freebsd_path_ipf"); data.registerOption(m_dialog->freebsd_path_ipfw, fwopt, "freebsd_path_ipfw"); data.registerOption(m_dialog->freebsd_path_pfctl, fwopt, "freebsd_path_pfctl"); data.registerOption(m_dialog->freebsd_data_dir, fwopt, "data_dir"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void freebsdAdvancedDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions *fwopt=(Firewall::cast(new_state))->getOptionsObject(); assert(fwopt!=NULL); data.saveAll(fwopt); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void freebsdAdvancedDialog::reject() { QDialog::reject(); } fwbuilder-5.1.0.3599/src/libgui/portinglog.txt0000644000175000017500000002764611733011756022004 0ustar sylvestresylvestreLog for qt3to4 on Wed Aug 15 20:07:00 2007. Number of log entries: 45 In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 51 column 21: qobjectlist.h -> qobject.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 52 column 19: qlistview.h -> q3listview.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 55 column 17: qheader.h -> q3header.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 56 column 22: qwidgetstack.h -> q3widgetstack.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 67 column 20: qpopupmenu.h -> q3popupmenu.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 68 column 22: qtextbrowser.h -> q3textbrowser.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 135 column 21: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 162 column 14: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 162 column 47: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 272 column 36: QPixmap::fromMimeSource -> qPixmapFromMimeSource In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 342 column 21: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 360 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 371 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 389 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 414 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 460 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 563 column 21: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 587 column 17: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 646 column 55: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 652 column 20: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 660 column 36: QPixmap::fromMimeSource -> qPixmapFromMimeSource In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 708 column 68: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 709 column 57: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 733 column 40: QPixmap::fromMimeSource -> qPixmapFromMimeSource In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 743 column 40: QPixmap::fromMimeSource -> qPixmapFromMimeSource In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 771 column 20: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 815 column 49: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 832 column 14: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 832 column 36: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 836 column 14: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 836 column 44: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 837 column 14: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 837 column 44: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 1829 column 21: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 2062 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 2107 column 48: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp at line 2142 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.cpp: Added the following include directives: #include #include In file /home/krava/work/someproj/src/gui/ObjectManipulator.h at line 36 column 19: qlistview.h -> q3listview.h In file /home/krava/work/someproj/src/gui/ObjectManipulator.h at line 51 column 16: QPopupMenu -> Q3PopupMenu In file /home/krava/work/someproj/src/gui/ObjectManipulator.h at line 82 column 25: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.h at line 110 column 55: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectManipulator.h at line 141 column 35: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.h at line 190 column 34: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectManipulator.h: Added the following include directives: #include Log for qt3to4 on Wed Aug 15 20:16:20 2007. Number of log entries: 57 In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 38 column 19: qlistview.h -> q3listview.h In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 39 column 21: qdragobject.h -> q3dragobject.h In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 40 column 19: qiconview.h -> q3iconview.h In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 49 column 39: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 53 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 54 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 74 column 23: QDragObject -> Q3DragObject In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 89 column 69: WFlags -> Qt::WFlags In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 120 column 37: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 121 column 38: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 122 column 33: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.h at line 123 column 32: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.h: Added the following include directives: #include #include #include #include #include #include #include In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 53 column 21: qdragobject.h -> q3dragobject.h In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 54 column 19: qlistview.h -> q3listview.h In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 55 column 17: qheader.h -> q3header.h In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 72 column 73: WFlags -> Qt::WFlags In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 73 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 88 column 54: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 89 column 52: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 94 column 49: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 95 column 47: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 97 column 48: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 98 column 46: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 114 column 30: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 116 column 35: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 121 column 31: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 124 column 28: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 130 column 49: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 140 column 44: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 147 column 43: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 173 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 192 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 193 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 201 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 202 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 210 column 25: QListViewItemIterator -> Q3ListViewItemIterator In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 211 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 259 column 11: QDragObject -> Q3DragObject In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 263 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 346 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 361 column 21: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 418 column 17: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 467 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 480 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 504 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 514 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 572 column 17: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 593 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 601 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 617 column 48: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 624 column 13: QListView -> Q3ListView In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 654 column 25: QListViewItemIterator -> Q3ListViewItemIterator In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 659 column 25: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 674 column 25: QListViewItemIterator -> Q3ListViewItemIterator In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp at line 681 column 25: QListViewItem -> Q3ListViewItem In file /home/krava/work/someproj/src/gui/ObjectTreeView.cpp: Added the following include directives: #include #include #include #include #include #include #include #include fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator_slots.cpp0000644000175000017500000003471211733011756024421 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "events.h" #include "listOfLibrariesModel.h" #include "ObjectManipulator.h" #include "ObjectEditor.h" #include "ObjectTreeViewItem.h" #include "ObjectTreeView.h" #include "newGroupDialog.h" #include "FWObjectClipboard.h" #include "FindObjectWidget.h" #include "interfaceProperties.h" #include "interfacePropertiesObjectFactory.h" #include "FWCmdChange.h" #include "FWCmdAddObject.h" #include "FWBTree.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "ConfirmDeleteObjectDialog.h" #include "FWCmdMoveObject.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Library.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; void ObjectManipulator::undeleteLibrary() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj = getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; // check that obj is in Deleted objects library. We do not show menu item // "Undelete" if it isnt, but will double check anyway if (Library::isA(obj) && obj->getParent()->getId()==FWObjectDatabase::DELETED_OBJECTS_ID) { map > reference_holders; FWCmdMoveObject *cmd = new FWCmdMoveObject( m_project, obj->getParent(), obj->getRoot(), obj, reference_holders, QString("Undelete library object"), 0); m_project->undoStack->push(cmd); } } /* * moveObj is a slot called from the context menu */ void ObjectManipulator::moveObj(QAction* action) { int libid = action->data().toInt(); if (getCurrentObjectTree()->getNumSelected()==0) return; ObjectTreeView* ot=getCurrentObjectTree(); ot->freezeSelection(true); FWObject *obj; FWObject *targetLib = libs_model->getLibrary(libid); vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { obj= *i; if (fwbdebug) { qDebug("ObjectManipulator::moveObj obj=%p obj: %s", obj, obj->getName().c_str() ); } if (Library::isA(obj)) { /* We can only move library to the root of the tree. This case only * happens when user tries to undelete a library. */ moveObject(m_project->db(),obj); } else { if (obj->isChildOf(targetLib)) continue; if ( FWBTree().isSystem(obj) || Interface::isA(obj) || Interface::isA(obj->getParent())) continue; moveObject(targetLib, obj); } QCoreApplication::postEvent( mw, new dataModifiedEvent(m_project->getFileName(), obj->getId())); } ot->freezeSelection(false); } void ObjectManipulator::copyObj() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj; FWObjectClipboard::obj_clipboard->clear(); vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { obj = *i; if ( ! FWBTree().isSystem(obj) ) { // while obj is still part of the tree, do some clean up // to avoid problems in the future. Create // InterfaceOptions objects for interfaces because we'll // need them for various validations during paste // operation. Interface *intf = Interface::cast(obj); if (intf) intf->getOptionsObject(); FWObjectClipboard::obj_clipboard->add(obj, m_project); mw->showStatusBarMessage( tr("Copy object '%1' to clipboard'").arg( QString::fromUtf8(obj->getName().c_str()))); } } } void ObjectManipulator::cutObj() { // Start macro to hide the name of the undo command created in // delObj. Normally its name is "Delete object". FWCmdMacro* macro = new FWCmdMacro(tr("Cut object")); copyObj(); delObj(macro); // works with the list getCurrentObjectTree()->getSelectedObjects() m_project->undoStack->push(macro); } void ObjectManipulator::pasteObj() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *target_object = getCurrentObjectTree()->getSelectedObjects().front(); if (target_object==NULL) return; vector >::iterator i; int idx = 0; FWObject *last_object = NULL; map map_ids; if (fwbdebug) { qDebug() << "**************** pasteObj loop starts"; qDebug() << "Target object: " << target_object->getPath().c_str(); } // If we copy many objects in the following loop, and some of them // are groups that refer other objects in the same batch, then it // is possible that an object would be copied by // FWObjectDatabase::recursivelyCopySubtree() by the way of a // reference from a group, and then the same object is found in // the list of objects to be copied AGAIN. Since this object is // already present in the target object tree by the time it needs // to be copied again, actuallyPasteTo() chooses the path for // copying of objects inside the same tree and creates a copy. To // avoid this, prepare a list of objects to be copied before copy // operation starts. list copy_objects; for (i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i) { FWObject *co = FWObjectClipboard::obj_clipboard->getObjectByIdx(idx); copy_objects.push_back(co); idx++; } for (list::iterator i=copy_objects.begin(); i!=copy_objects.end(); ++i) { FWObject *co = *i; if (fwbdebug) qDebug("Copy object %s (id=%d, root=%p)", co->getName().c_str(), co->getId(), co->getRoot()); if (map_ids.count(co->getId()) > 0) continue; // Check if we have already copied the same object before QString buff; buff.sprintf(".copy_of_%p", co->getRoot()); string dedup_attribute = buff.toAscii().constData(); buff.sprintf("%d", co->getId()); QByteArray bytes = buff.toAscii(); FWObject *n_obj = target_object->getRoot()->findObjectByAttribute(dedup_attribute, bytes.constData()); if (n_obj) continue; last_object = actuallyPasteTo(target_object, co, map_ids); } if (fwbdebug) qDebug("**************** pasteObj loop done"); } void ObjectManipulator::duplicateObj(QAction *action) { int libid = action->data().toInt(); if (getCurrentObjectTree()->getNumSelected()==0) return; ObjectTreeView* ot=getCurrentObjectTree(); ot->freezeSelection(true); FWObject *obj; FWObject *nobj = NULL; vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { obj= *i; if ( FWBTree().isSystem(obj) || Interface::isA(obj) ) continue; FWObject *cl = libs_model->getLibrary(libid); nobj = duplicateObject(cl, obj); } if (nobj) editObject(nobj); ot->freezeSelection(false); } /* * Note: this slot gets controlwhen user presses "Delete" key in * addition to menu items activation */ void ObjectManipulator::delObj(QUndoCommand* macro) { if (fwbdebug) qDebug("ObjectManipulator::delObj selected %d objects ", getCurrentObjectTree()->getNumSelected()); if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *current_library = getCurrentLib(); if (current_library->getId() == FWObjectDatabase::STANDARD_LIB_ID) return; FWObject *obj; vector so = getCurrentObjectTree()->getSimplifiedSelection(); vector so2; for (vector::iterator i=so.begin(); i!=so.end(); ++i) { bool del_obj_status = getDeleteMenuState(*i); if (fwbdebug) qDebug("ObjectManipulator::delObj object: %s del_obj_status=%d", (*i)->getName().c_str(), del_obj_status); if (del_obj_status) so2.push_back(*i); } if (so2.size()==0) return; if (so2.size() > 1 || ! Library::isA(so2.front())) { QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); ConfirmDeleteObjectDialog * dlg = new ConfirmDeleteObjectDialog(this); dlg->load(so2); QApplication::restoreOverrideCursor(); if(dlg->exec()==QDialog::Rejected ) return; } /* need to work with a copy of the list of selected objects because * some of the methods we call below clear list * getCurrentObjectTree()->getSelectedObjects() */ try { for (vector::iterator i=so2.begin(); i!=so2.end(); ++i) { obj= *i; if ( ! FWBTree().isSystem(obj) ) { if (Library::isA(obj)) { list ll=m_project->db()->getByType(Library::TYPENAME); if (ll.size()==1) return; if (QMessageBox::warning( this,"Firewall Builder", tr( "When you delete a library, all objects that belong to it\n" "disappear from the tree and all groups and rules that reference them.\n" "Do you still want to delete library %1?") .arg(QString::fromUtf8(obj->getName().c_str())), tr("&Yes"), tr("&No"), QString::null, 0, 1 )!=0 ) continue; } if (mw->isEditorVisible() && mw->getOpenedEditor()==obj) mw->hideEditor(); deleteObject(obj, macro); } } } catch(FWException &ex) { } } void ObjectManipulator::dumpObj() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; obj->dump(true,false); } void ObjectManipulator::compile() { if (getCurrentObjectTree()->getNumSelected()==0) return; vector so = getCurrentObjectTree()->getSimplifiedSelection(); set fo; filterFirewallsFromSelection(so, fo); if (fwbdebug) qDebug("ObjectManipulator::compile filtered %d firewalls", int(fo.size())); m_project->compile(fo); } void ObjectManipulator::install() { if (getCurrentObjectTree()->getNumSelected()==0) return; vector so = getCurrentObjectTree()->getSimplifiedSelection(); set fo; filterFirewallsFromSelection(so,fo); m_project->install(fo); } void ObjectManipulator::inspect() { if (getCurrentObjectTree()->getNumSelected()==0) return; vector so = getCurrentObjectTree()->getSimplifiedSelection(); set fws; filterFirewallsFromSelection(so,fws); set fwset; foreach(Firewall *fw, fws) if (Cluster::isA(fw)) { std::list cfws; Cluster::cast(fw)->getMembersList(cfws); foreach(Firewall *f, cfws) fwset.insert(f); } else { fwset.insert(fw); } m_project->inspect(fwset); } void ObjectManipulator::find() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; m_project->setFDObject(obj); } void ObjectManipulator::findObject() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; mw->findObject( obj ); } void ObjectManipulator::findWhereUsedSlot() { if (getCurrentObjectTree()->getNumSelected()==0) return; FWObject *obj = getCurrentObjectTree()->getSelectedObjects().front(); if (obj==NULL) return; mw->findWhereUsed(obj, m_project); } void ObjectManipulator::makeSubinterface(QAction *act) { int intf_id = act->data().toInt(); FWObject *new_parent_interface = m_project->db()->findInIndex(intf_id); assert(new_parent_interface!=NULL); if (getCurrentObjectTree()->getNumSelected()==0) return; ObjectTreeView* ot = getCurrentObjectTree(); ot->freezeSelection(true); FWObject *obj; vector so = getCurrentObjectTree()->getSimplifiedSelection(); for (vector::iterator i=so.begin(); i!=so.end(); ++i) { obj = *i; if (obj->getParent() == new_parent_interface) continue; if (fwbdebug) qDebug() << "ObjectManipulator::makeSubinterface" << "obj=" << obj << obj->getName().c_str() << "new parent:" << new_parent_interface->getName().c_str(); // new_parent_interface->reparent(obj); map > reference_holders; FWCmdMoveObject *cmd = new FWCmdMoveObject( m_project, obj->getParent(), new_parent_interface, obj, reference_holders, QString("Make an interface a subinterface"), 0); m_project->undoStack->push(cmd); } ot->freezeSelection(false); } fwbuilder-5.1.0.3599/src/libgui/PixmapFactory.cpp0000644000175000017500000000325711733011756022341 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA This class is a simple wrapper for QPixmapCache, it automatically creates pixmap if it is not found in the cache */ #include "config.h" #include "global.h" #include "utils.h" #include "PixmapFactory.h" #include #include #include using namespace std; QPixmap PixmapFactory::getPixmap(const std::string &icn_filename) { QPixmap pm; if ( ! QPixmapCache::find( icn_filename.c_str(), pm) ) { pm.load( icn_filename.c_str() ); QPixmapCache::insert( icn_filename.c_str(), pm); if (fwbdebug) qDebug("Created new pixmap from file %s: isNull=%d w=%d h=%d hasAlpha=%d", icn_filename.c_str(), pm.isNull(), pm.width(), pm.height(), pm.hasAlpha() ); } return pm; } fwbuilder-5.1.0.3599/src/libgui/natruleoptionsdialog_q.ui0000644000175000017500000004046411733011756024175 0ustar sylvestresylvestre NATRuleOptionsDialog_q 0 0 942 345 NAT Rule Options QFrame::Box QFrame::Sunken 3 12 12 QFrame::NoFrame QFrame::Raised 2 2 No options are available for this firewall platform false Qt::Vertical QSizePolicy::MinimumExpanding 20 0 Normally, if object used to define translated source address is an interface marked as "dynamic", fwbuilder generates NAT rule with target MASQUERADE. However masquerading has problems with policy routing. This option makes fwbuilder use SNAT target instead. true Use SNAT target instead of MASQUERADING for NAT rules with dynamic interfaces Qt::Vertical QSizePolicy::Fixed 20 20 Randomize port mapping (translates to --random) Give a client the same source-/destination-address for each connection (translates to --persistent, requires iptables 1.4.3 or later). Qt::Vertical 20 81 12 12 Qt::Vertical QSizePolicy::Expanding 20 20 0 0 Pool type 12 12 default true bitmask random source-hash round-robin Qt::Horizontal QSizePolicy::Expanding 81 20 Qt::Vertical QSizePolicy::Expanding 20 130 static-port Qt::Vertical QSizePolicy::Fixed 20 10 Starting with v8.3 ASAs support NAT type "static" and "dynamic" for source NAT rules. Firewall Builder attempts to determine the correct type based on the information in the rule, but the calculated value can be overridden below. true true Automatically detect NAT type "static" or "dynamic". This rule is currently set to type "%1" Force rule to be NAT type "dynamic". Note, rules with destination translation defined cannot be "dynamic" Force rule to be NAT type "static". Qt::Horizontal Make this NAT rule translate DNS replies. You also need to enable DNS inspection in the firewall object advanced settings dialog. Qt::Vertical 20 265 pf_bitmask toggled(bool) NATRuleOptionsDialog_q changed() 20 20 20 20 pf_random toggled(bool) NATRuleOptionsDialog_q changed() 20 20 20 20 pf_source_hash toggled(bool) NATRuleOptionsDialog_q changed() 20 20 20 20 pf_round_robin toggled(bool) NATRuleOptionsDialog_q changed() 20 20 20 20 pf_static_port toggled(bool) NATRuleOptionsDialog_q changed() 20 20 20 20 pf_pool_type_none toggled(bool) NATRuleOptionsDialog_q changed() 20 20 20 20 ipt_use_snat_instead_of_masq toggled(bool) NATRuleOptionsDialog_q changed() 307 108 304 116 ipt_nat_random toggled(bool) NATRuleOptionsDialog_q changed() 366 123 362 166 ipt_nat_persistent toggled(bool) NATRuleOptionsDialog_q changed() 474 148 470 172 asa8_nat_dns stateChanged(int) NATRuleOptionsDialog_q changed() 470 32 470 172 asa8_nat_auto toggled(bool) NATRuleOptionsDialog_q changed() 470 64 470 172 asa8_nat_dynamic toggled(bool) NATRuleOptionsDialog_q changed() 470 93 470 172 asa8_nat_static toggled(bool) NATRuleOptionsDialog_q changed() 470 122 470 172 changed() fwbuilder-5.1.0.3599/src/libgui/heartbeatOptionsDialog.cpp0000644000175000017500000001002711733011756024177 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "heartbeatOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include #include #include using namespace std; using namespace libfwbuilder; heartbeatOptionsDialog::heartbeatOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::heartbeatOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); FWObject *p = obj; while (p && Cluster::cast(p)==NULL) p = p->getParent(); assert(p != NULL); Cluster *cluster = Cluster::cast(p); Resources *os_res = Resources::os_res[cluster->getStr("host_OS")]; assert(os_res != NULL); string default_address = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/heartbeat/default_address"); string default_port = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/heartbeat/default_port"); string addr = gropt->getStr("heartbeat_address"); if (addr.empty()) gropt->setStr("heartbeat_address", default_address); string port = gropt->getStr("heartbeat_port"); if (port.empty()) gropt->setStr("heartbeat_port", default_port); data.registerOption(m_dialog->use_unicast, gropt, "heartbeat_unicast"); data.registerOption(m_dialog->heartbeat_address, gropt, "heartbeat_address"); data.registerOption(m_dialog->heartbeat_port, gropt, "heartbeat_port"); data.loadAll(); toggleUseUnicast(); } heartbeatOptionsDialog::~heartbeatOptionsDialog() { delete m_dialog; } void heartbeatOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void heartbeatOptionsDialog::reject() { QDialog::reject(); } bool heartbeatOptionsDialog::validate() { try { InetAddr(m_dialog->heartbeat_address->text().toLatin1().constData()); } catch (FWException &ex) { try { InetAddr(AF_INET6, m_dialog->heartbeat_address->text().toLatin1().constData() ); } catch (FWException &ex) { QMessageBox::critical( this, "Firewall Builder", tr("Invalid IP address '%1'").arg(m_dialog->heartbeat_address->text()), tr("&Continue"), 0, 0, 0 ); return false; } } return true; } void heartbeatOptionsDialog::toggleUseUnicast() { bool onoff = m_dialog->use_unicast->isChecked(); m_dialog->heartbeat_address->setEnabled( ! onoff ); m_dialog->heartbeat_address_label->setEnabled( ! onoff ); } fwbuilder-5.1.0.3599/src/libgui/HostDialog.cpp0000644000175000017500000001133411733011756021603 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "HostDialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/Host.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include "FWWindow.h" using namespace std; using namespace libfwbuilder; HostDialog::HostDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::HostDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } HostDialog::~HostDialog() { delete m_dialog; } void HostDialog::loadFWObject(FWObject *o) { obj=o; Host *s = dynamic_cast(obj); assert(s!=NULL); init = true; Management *mgmt=s->getManagementObject(); assert(mgmt!=NULL); FWOptions *opt =s->getOptionsObject(); m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); // snmpCommunity->setText( mgmt->getSNMPManagement()->getReadCommunity().c_str() ); m_dialog->MACmatching->setChecked( opt->getBool("use_mac_addr_filter") ); m_dialog->commentKeywords->loadFWObject(o); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); // snmpCommunity->setEnabled(!o->isReadOnly()); // setDisabledPalette(snmpCommunity); m_dialog->MACmatching->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->MACmatching); init=false; } void HostDialog::validate(bool *res) { *res = true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } } void HostDialog::applyChanges() { bool autorename_chidren = false; QString dialog_txt = tr( "The name of the object '%1' has changed. The program can also " "rename IP address objects that belong to this object, " "using standard naming scheme 'host_name:interface_name:ip'. " "This makes it easier to distinguish what host or a firewall " "given IP address object belongs to when it is used in " "the policy or NAT rule. The program also renames MAC address " "objects using scheme 'host_name:interface_name:mac'. " "Do you want to rename child IP and MAC address objects now? " "(If you click 'No', names of all address objects that belong to " "%2 will stay the same.)") .arg(QString::fromUtf8(obj->getName().c_str())) .arg(QString::fromUtf8(obj->getName().c_str())); if (obj->getName() != m_dialog->obj_name->text().toUtf8().constData()) { /* see comment about this in FirewallDialog */ blockSignals(true); autorename_chidren = (QMessageBox::warning( this,"Firewall Builder", dialog_txt, tr("&Yes"), tr("&No"), QString::null, 0, 1 )==0 ); blockSignals(false); } std::auto_ptr cmd( new FWCmdChange(m_project, obj, "", autorename_chidren)); FWObject* new_state = cmd->getNewState(); Host *s = dynamic_cast(new_state); assert(s!=NULL); Management *mgmt = s->getManagementObject(); assert(mgmt!=NULL); FWOptions *opt =s->getOptionsObject(); string oldname=obj->getName(); new_state->setName(string(m_dialog->obj_name->text().toUtf8().constData())); m_dialog->commentKeywords->applyChanges(new_state); opt->setBool("use_mac_addr_filter", m_dialog->MACmatching->isChecked()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/printerStream.h0000644000175000017500000000553611733011756022061 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PRINTERSTREAM_H_ #define __PRINTERSTREAM_H_ #include #include #include #include #include #include "PrintingProgressDialog.h" class QPrinter; class RuleSetView; class printerStream { QPrinter *printer; QPainter pr; QRect pageBody; PrintingProgressDialog *ppd; int yPos; float margin; int ymargin; int xmargin; int fromPage; int toPage; bool active; bool printHeader; QString headerTimeString; QString headerText; QFont headerFont; QRect headerTextBox; QRect headerBox; QFont bodyFont; float headerHeight; int yHeaderHeight; int yHeaderLine; int pageNo; int pageWidth; int pageHeight; int dpiy; float pixmap_scaling_ratio; float table_scaling; public: printerStream(QPrinter *p, float table_scaling, float margin, bool header, const QString &headerText, PrintingProgressDialog *ppd); bool begin(); void end(); bool isActive() { return active; } void setFromTo(int from, int to) { fromPage=from; toPage=to; } QPainter& painter() { return pr; } int getYMargin() { return ymargin; } int getXMargin() { return xmargin; } void printText(const QString &txt, bool newLine=true); void printPixmap(const QPixmap &pm, bool newLine=true); void printQTable(QTableView *tbl, bool left_margin=true, bool top_margin=true); void printRuleSetView(RuleSetView *tbl, bool top_margin=true); int getTextHeight(const QString &txt); void beginPage(); void flushPage(); int getPageHeight() { return pageHeight; } int getPageWidth() { return pageWidth; } int getWorkspaceHeight(); int getWorkspaceWidth(); int getYPos() { return yPos; } int getYSpace() { return pageBody.height()-yPos; } }; #endif fwbuilder-5.1.0.3599/src/libgui/Tutorial/0000755000175000017500000000000011733011756020643 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/0000755000175000017500000000000011733011756024032 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/0000755000175000017500000000000011733011756025277 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/21.png0000644000175000017500000007560511733011756026244 0ustar sylvestresylvestre‰PNG  IHDR—IAв‘РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ \TекџчМљ~В^@ћ€vќK Ћž,”J!RР Щ<^2Хд„дд—CEф /y ё03PЅe^*EЛ ЅЧЫ1•в$3щb№š88oЪ№љрчџіЌ™5{іьНgЯЙ№›Я8Ў§ьg=ыyОk3Я^kЏйћkjt:]ќфBњФ @@@ }+—ќlGџ(…їП0 œ†“   D ~ђlJфˆ4Rx}C# €€€ КУ[ЏўыWa,.Мšь|‚€€ s7›=ыq§ХГКƒЎХ™“ƒvz]xTDЇžѕж@@ќ€ћyС,ИOв§(Ф>XЦт- bЉ›хњ‹5њvКˆStњ0'LыЯЋ?џmDЇh'jA@@Ря ИŸќС‚ћ˜нBтЯтЙuГщф–ллещюE‰ЙѓяGЯ5шы;=кT‘ЏћO]hJUO\њН1тСt>D,s\ж‡EєшSїѕ]‹c]h€€їѓ‚?XpŸИћQињ`ЩтЖRљ­vњ№№pНЦ9rgS8kRyьўХœR№кAyп\’ЊиTйхRSš*љЄQ‡žЕВW­мœУ№Ё р1ючАр>їЃљ`Щт–џEЛxБ‰ЧНєgУo ПxйhМxІщФnЃpС[ЊTЋ.”зvІаDЪdSЩЌNwя-†яQ*&ϘaJіKœHі*6UvЉјрц.Ÿ4ъаgxeп;іц‰Gšs@Z€ћyС,ИЯЫ§(l}PN˜\яŽ$]ЛЦ№[tњіњN7u2”ЮtЁєws•V( Xr№‘[jТщr{Лцњsѕїъ${БУсэŒJ6Uv‰-xЖь“F†рAЏь{G,qЊЃК nŽГxшmбїќQ—žR[[нЃ[šпj.УъUЦФzYjлžГЉ2|AЂfСЫз5 к2WnЃ*lЧъ6Зшž1,љЌš& ИМ8g8эЅ|РtFї‰ž8 +•ЏщŽџbXЙЗ–ЮEи.њ|mz}Šэ№]М@ЧEE……4^kоVixяŸТ яшѕ@txVRLtdVT§Oу–уЕџќYf Ђэt3IИ'*DдtЖДmzrэЅц kQzН~wNo* />^џЛQЩ]pKЇЋНк\ќYѕ75fgžш5Ђwtз!ЭКВCеŸ|#W ŠцBьН2YЕљP‰]ж2їїŽН„0 e:švй%ч$ыqЧlР€@Ћљnw˜ШAQ^Б % ФжФJdAЌтZYѓAмйЕ*љРГ‡дЎи;уя5Е5бwFoйКх/‰ohlh QJVЈEVЙaБ!лrИюRCЛH™**˜КSЎХМю§рЩкЋŸLˆIОПЋёZѓЪ}†KŽ1CHxsŠ7uњ{ѕz6§ж>$ї*]Ѓс/їFe ˆЅ”9яуZоюё“е;џYњHOn‡я2BF?3ёб(:WXјNео]'>C9{§? ДwіиАіКU;ŽџZлxGTиШо1пќм@MлZа)90%ЁkrlдоЪкЯ$м/œjЏџиићЎАўбК/kє§c„SŸЊs†Ю-†z]”’)жтё3Е[іUп61­їьĘбo#gўк'jъ€ЎUчs?>Hч:O>sЄnPХ dН2йЇИ­Ё)Х>њB$ƒЫОwь%ќr‰ИЃeƒšРаЌ§мt 0tїъЩ‚’c >A|CР./l{жf\G^QъўŽ№еjѓтyСЮ‚šЪ†Kl2З вŠЦ] QˆcчdДј№ZкеыŒсaсQQQwtЛЛЧН=ЂЃЃuFЃѕы\ƒ ђ‰од=™ыЊјЛьЙXюЋ‚JxЛ†ˆvцaєБohЈкАѓX5ЩbЃ:ЗГЙ§\}‹ОIGгя‚ђъ}ЕuCНQЗџ”0†юѓЇЈ;лY”пœ2о0*й!§Сї ‡кБ#Uєѓїпщ?=Žš,Г5 aэшrƒюФo†ЂџЩж вЁ—’)Б‚хЃЇN‘eц€I]w Jp/56:BgLŒЮZО§ОZO3џ:Ѓ’)sХ#Чt7Žќ"T љ“^`2є9[}ж`0Ѕ@•*эфЏ[SїHп”˜ХBс$%Ф3–vЎыZ:е…Жh„кYпPoДў<НAF‰v=а-,Ћ_Д0щmЉHгпzceR]н9eВњвsЩ‹Љ9:-ˆ.;\;ЕoзŒ4aРаи\Жпpтњ­Мбhjšщ?­шущEЩЕN^пh…vЄЦаx-ІgLTчŽ5Ня ЃiќГП(œ;Л…/юgšРWХВn€Вš^Цќ7^kЈЇVt!фyЈ”’W’~QŠ]Х2BŸМwT$М9sйevВYŠŽj)9&юо. ­DР./Pіb9›ђO]2ЮазЫ vd”eEŽ,и'&ЉnAКУљmЙ(…l ЗqLС;~нб5:&†н‰E”7›ѕэCЮ]гi’Aё%;VЗ™’ЕT ­—Ћ-{џoЏ76†„Ж' Ъs” C-УtqšX6MzW§P[ЃПI_јB2эЅйОРоЁCЃШ—Џлv‘B6M)‡гџєjgќ№˜с‡геїпІ‹ю•ќPьДфЈбoзHВ…Štž| oЏуpЯiŸЎФ?џX ЅЅSпбtDЭNcјŠБPu#хiбМwЈpz!јІ7^RИ гЂW JХ+ю”bWБ,ЎюTй>('•sЊE(ƒx€4/4Дf З=k€eЎЃЙUqF`.ˆѓ‚д‚6'е-иЗШЌŠхb ккTг’‰bј; э$Wф}а4Ѓо`ЈЉўЅКЙЅ™Ў‹г@ќЂстХ+twUХ›ЖЪ8ЈxŸ^{нФzвhFѕЎЌŸ:SУ*в"5zбЉ†е(;QЙб@)|`BŒUn)ЩкБьўпvR˜EOMшcМ)\w“ўюЎQc‡ЄаؘфыOХшУЃіtGkЭыШюЕŸQWv`ЯaVЃ(Ё=гkѓ)aZ)і.ЁOЊЅФ,t В)S%љm•ІЋIНщ|…^S3§й(Ѕт•ИЅиUpйїŽНDм„JЙмtбЁџˆЭъ %ЧTЌa€€З 8ќn7Ѕp]ъ"ПЬyСЁх<ІS JХ+БeЅиUpйїŽНDм„Jy§‘кшАfYtJŽБ+,*6Б @Р‹”Плiо" iфR—Щ#VWй‚cЗ=eСqKŽ4фЂр)œNe(…“ ’Љ-ЙКц'“жеУ5ЅзшЈo{ЦєˆЙ'ІњGс]Д^ВјЙ№ФКбWTЙщтйлџ’"Eъ$ц—Ыім…oї„*<х§YЊ{І%z›щ—WsŠ…_БA*5дЕЙ“6щЧЧс:aЁ8 ^П7 h-[чvf iвt:ГCњЬІЌоЉQЪ|ДVNЈйЂkŒ‡АцшzМОЅY˜Ьoббм э/њЊ8@—Јя–к‘aсдGьm> Ї9Ёбs-бd™$*ІФ“Іx“Zќ7™ЂГcЛzгђDЅ дН"уьЅЛ .ћоБ—ˆ=—ЉQё&wRўкѓТ жТелш№ PJŽYЧџ ­M@6/0'X“IZY^АЗР“ŸEбњПФšŠJœіgdY"WЩMжV5”TЂрГ<.й(x#ѕпUˆžLЊ4&9Іkїо‘šˆ†Ц‡+іU4\nЈЛ\WџЏzн­:уЛuнюе]{\ЇыСš dЭЮ =ІpЁAo;яЯVѓлеefЯщЂє:б4ўMККцгКL=eVгyЪ/-a…х‚&х]’зщЂZBТл ’&С–…W;ФІиŽuW;с\ЁŽЮ™aSИРЬšЋo ЅеZ&kѕ-КњvaТЕgлT ЫчZЂТ­ѓ№VпШ$§Ќ.Мp:вd1ЈbJьАP—уbўЗ—&Д)pЬ*Ѕю•ЌщЅЛ .ћоБ—ˆ=—ЉMёfЮу1›шC ћчjе?жъnЮБО’cЬm|‚ј€}‰YОЧd[2‚єJАI‘чGФfmЌЉZ /­FФЭq жнЎ–ФfE62пЉ&>ŒР№їЗж ШG!ЊEE5ЈM- \flа7oшдёњŠЌџНžžƒbьT‘HЕПЏџўœNї†­MХ-ђŒM›(jЈюАњ7ај›ЇdK]SВфB“в•‘–gS7иНьmrЩ.2Ko{#Rуr­HuxІ…РЦйЖbaKXUnkPХ”ФaЩІЌџВBц†ŠWмOЉ3"W•,“ќœh?™В—ˆ=—IYМљm­qљгДt1ФpMЗїЄсЧшƒц~WqŒ;€€Ÿp95И\‘юОnЪхїA|У…ЭЊeqБFїs}= _o §чЏ_єя2LИ}Кщ›КЩиЄ?E?№jjjЉ76|qл_l[ВIЂт]b/ХrsYpGБ.зАВъ‘avЏЖLр“я/ЈЎŽа™/щ…љ’г\K[І‚иAРo Ј}ЗЋЅk^Б V‘“№Єnдх‚ж(ЄЁYЃАiZ+ОкuЊПœlЄ,~Б!"|а‘–hŽ6u1o3ъкъ.žh:O3ВКˆ.ьGh"3tб–sEUИЉs7lgзљкšУ0ЖЃIЇfa№нB)\˜/iK+їѓ‚?XpŸЗћQињ`Щ™–џХ{Co‰внђ<§žŠНъйЗџ‘0T—С$іŸТ•WЃ^n5НЎX"моœ<‘sFЌFeКMŠ б )ЉˆЭ`"`žЗg!с`ІЎE,СGР§МрмяїЃАѕСќЭЇ~hяЙ—>ЊОІ6"КЋS‰œ§oЕЁzd{дЯ…K  .p?/јƒƒUs? ‘1*zeќЂП%Œ rсgMї€ћЊЃКb Ъ  A@Р§МрмяїЃјр•,NmЃє–4†M6KР§Мрмя>їЃћ`“Хы/ЋнћE\ eŸˆИMИ‘6{YГ8Ѕ№&JяjQУџ   ~A`шкjžШџУ/<‚   Ю@wžj€€€€@ї~€   р<dqч™Ё€€јdqџшx  Ю@wžj€€€€@ї~€   р<dqч™Ё€€јdqџшx  Ю@wžj€€€€Аое?ќ иŽWЋЉЉ ьМŽŽюзGa'Ф О!€,ююh5( Аž’œ”бэй[Aq!‘eч"ЈР%€,И}Я§ŽТ)…‡…ч3y{Фє8[}Yмя;8дЖ И’ХƒxЮPщ` ЙФ`&х!З…yА(ИL`лі­.зѕyE?<ШqТчGE ;рtЇnИlШ|ašy‹Bј&ЙбfЇiы†ШК!ЃoкЉjŸ4š­&XЩЈѓhмўБ#лдB–ёпAМЖpЫ=БDЌЉŒ'ЪЦMЪмВ5FЊЁDž5oй+…Ю"SъЧ”fum-pџХ;uф†КЄ­ФŠВ„Щ6Ы^БіnДб К }{}ЦИL!,KјжЅ<К …"–Њ ІФ`х;TкЂœW&WЙ)ѓA.iбЦ%;ЗХ{э*’yn\wУr№ГШФMn0БљГХ\‘\ЊўБ:ц.<к6Дp:‹г4уЙLЃбіxеирM z&Йо~gˆНШFbWХN`ЃЎsyЂѓРA+!+Ч+уЈjАvњvQЄЎ…щbŒЂvmŠJБ3%Ы^Х0TiˆRА  з4•]cegІ­Œ”™Дџэ[zй†ЮM:iп(єЕ­šэ–ШЂS=Јщ —И-vXЮU‘gЂЂЩC-ОuэšБqгFdqQ—ЂшW~iІo'=Xkк  &Цf—FD NХЭNWZh§џяКћЎјбѓэњAШ<4^№p˜­ЃЗœзЦТЗ­kѓб]­иИИЊЪJw­(еo•ƒDЉqШн €‰ "рЪXм?аЗГ:Џќ€П”hН‡Х‹)м{NлYіЗ.ГsаCЩЕvY…™ЖCРЕБ8M9žЊ­­-*.:|јыІІ+ю;aђ””Єя‘§ё‡*‘WŽнsоM6яК;жф‰sцЉХнрчкRежd“МeF:vИЙoпфќйЏ8џл*M йЛZћKэЄ)“>§ќSюзQЧю§Уƒ;є­}gќНЙdMёюŠ/Ўўv>єП:іpдшQН{їжШЖЫd*9ѓW#ЎЎЩnœiіъ_Њ‹ ‹}]йсж/цLMћх\[iuУИ№ѕЅхŸэ Н54s\FAa‘yД­ ч3ъTX2oюЊѕk)vЛ;іѕЙ3КоiZ ­Pбq˜Ю$Ss_МГЫJ7DоI‡ЪЉуЧоzsulЉж,юи:mwєE$5тŒџмИіЃОї&MЩž™;sqс љэВЗSзХ1Щ/э'l;AР[3ъEЋ‹&Nš6јЉсТ(­.цž˜EK,_є-К…‹&=Oo*№ŸЌФоЛыуmƒвХїŽ=|hUUеž]Л†*lŽMƒ0Љб’ЮЄўIёНЅеэу.[UТ4gЭ™еl4џ$„,lћ`л ƒbя7)э+К/1…ГЫŽр5ГyќШqŠŽ‚Ђ]Л>оEBвdŸЌ@eњ.x)чЅјGт)ЦЉгЇвзЋ+ћщУЉss_Э?tјsL VЁЃ­Q()|ўBŠњŽњšcЁŠGО:oЕ`W"e­‡‡ѓ­лЕцaAЩ[Хѕ—ыv|TNяКЫuДЩ(yЋДўwcХЎђяo9qђ oUIЮЈpфы›K7јЧЁўѕŸЗh‰КAqEїЫ•_˜ž=R8™ЂC%!9eUщ:Гй]I‘№З™”ПэƒL(9~xПЫі)лKŸ\Э}‡е-№ЃНљZ3yNŸ\ŸKш{oъ”Љ I !њШЈШйГfsх‚еŽВі€€"џPмЃМC˜ЂS`еїсУ‡S’RduJV•д_ЌпQ^AяК‹uДiVЃoœУGшЬ§РўЪ' Ыœ”Йџ№‘5Ћз›)OЬ[0ЋЈ<БcыŽŠЯ*ШŽИ:W`…kЫN|wfЧћ;ь?к.ДИЈ˜+œ8ybѓ{›Ћ*ЋЬеX !sуМpфш‘Эы6“џ§SњЯЫ7ћŸ;+wЪфЌЂHOž>IЪU'…q-} “'“ў{вјбу~yєРоїмqчвeKЙMIСЧ12nŽN'Ћвб, %AоPO§KНL}m…oд}}єPŸ^}„ъМQцџ$ДNЗЮ›P)˜ќrљcwХЎМœ<Ъєš›“GsбЬђrВMтАМщймО’œ+P!џхьАa!!њБЃFœ6Э PKEБ›ВJјЖЛттЬ_@ЇуТѕ7л]ekЪЮќ$ќm~^~ртљ‹ќЈ?BЃЌ–\ŸкџеHšпф6m§‘QцšМ`q&$$d№РС[ЗmхЕЈ<]M0Е>vдXўњŸЁ†+^ShГѓfЫћhѓGБНbi#Є}Hжфщєе ЋFBпЦHQОQи/ОwO VЅЃ™О’‚XN}ЭWЉњSЬŸ‰ “аTŠјЭе4тVцŠŽCБ\м:ЗяНТyУ•Ш끘}*\5œgхѓ†ѓ‘‘V9w@IЮЈвоќgH‰ќК%ahЉ(6тZyХы+юьвyЩќќј„јAC•-уузэ;ЗsсЏЃ}ШДь—Й}ёёУ…TаиЇт*/‹і‘#FnкВIHЬєjбQyф3ЯRёЪе+П^ќѕу>ЇѓяP}ш‚з˜4№^$рвuqђЇХС,Ph‡ŽW/б Роwг7HГ&|UYЌ…ЕзГrˆщr xSјВЈQ-йъ\шZ`к“iV(V‹…А0sCжНъЅ#ЏЋЎ(ьЕДBщЦTІpИџEЫ–ЎYїwFмњbюЬ„‡,‰Вд"UgЊW­<]}šNeƒ"ЯЙqV№UŒьbDЧџЂеm§ђ_Эу^‰СЊt4гWRфtф˜€}M/Sљш?џёHяx[в•и€g[м№ђЋKTЧK ,‘SЁCTGж  Пd`‰œфм %9WP*И\QчЬџ™ГшMnджжМѓў–_}qеЪД)†/vR|ќrэ}*ЖЂRvЦоК§боѕіЈ{џєЇ=ћїЄ$%вч=`GlЧ›oЮ<]јУзщrЇ=Ÿ˜žОЈ%_Хѓ.ђ /p•€‹YмAзщњЦї-пW1bи{ЧшЄі‚!Ъ4ц0˜ОЊИ5^`Е”6mЋwсj’B‡Ј.хы7ˆЯ$$ іО)IшŒзUвсrЎЩ lлŒО+fё’Х$9VylNўœЯ?љ\М—•_yѕ•s^ьгЛн№’n бЏo?nJR№UŒ•Ж?G–xХЂpибJ ‚ќ’!Ъ4њЄ#„Ќ1ћ_љgNvŽl[ЌEіЉё№pЖuq^*ЇЅ.XY?{.йŸПВ€6YC&y‘pЖЄгёж•ф\AЉрrEЇўФ­GužўЗщЉЩц#ЙKTоMb5оЙLШ7ЙВщCцO^lDЅь”џМuйЃ§ЉЇG­/[Ÿ˜”јўцїrђf0eš+т ™-fсFНЂwŠћАpiF]УŠЪIY“6­-+пUоx­‘юhMkдgЮ™Щм`њЊЂщ)zбwm:vгVƒ~РfЊнXDпtOˆFлЖjУF›Пd>K5чjшэ~пl‘5Е5Т]О…йГє#–š ж‡R755бm*ѕzНс’aщыKUѕЯ™У;ZIфE+-]lIZЦkЦ Пќмѓоž*4и.‡‡S­;lдZ@.~“…i“Г"nыœ:4оoыL›ЬlVfVФ-њдСщCžйыО{nЖœ{+Щ:уrE‡–Х SІOЁ%)єЇJBУUCщ[ЅОпМ@&Щ Џ6RЗЏ2/тз•”eћTђW#ЉтэЭ>q}ъЏ/пQУVўыt}ъЏХ%ХНп~Ѓ(љбdoЛћ `љ>p–„ЃDUДъэ5oЏ)љП…MMзЛбяХ3&АTа7HёХщCгЉЭєщДЩф‚ Г ›єE6ђ™‘Mџл”ўxrжxЙъІŠt5šLNš>‰Іoяо§…ё/XэK, mЋО(нjЏТ5yй6m&ѕ}˜ЎжџTѓSїюн_[№3›1&klЦXš?Џ8~X•ёtЦЁ}ўБуЧўќ щN)–&тloœТа‘;ЇZ—DщўІєrГx“~v^.Н%іщ’іьYљє&9MMгbІ $чЦyщѓMЅŠ’ve6љC˜2nЪцэ›-^tхпWшHюћHпзчПЮŽфЌŒЌтЗŠGŽIMdNЬ”9МYл–О–эSЩ_ŒЗі"gќWєЪbvЬЈ1ѓЮГфMЎ™’’rёЗ_‡ B'т§’њхПœЯwY*йџOWыь…€€Vˆ4­пј…ѕC§хк&:~Ў=—jФЮЏЕ6тQНИј8ў}эQУjЦh ъˆс2Wдък>џŒБцЗšьœьЗ|\ИЌ№ŽюwŒxЪA/xі№р­kьЬђЗzщљт%ЋŠщфЦивМ`сќ;яИsђw IDATкдщЬ%%ЙC‡]ЈXUuъляЯЖў‚ћдђужЫ3žvp`;ьP(Д)CзVGмжЕЎВќъП~uu,юлх>iн'Жђщ71ПUš5ійц#M­H@‹Њ;<ђЏC„еU_ZtTиЗЎЊо;;uъ4Fx-M4I+L_Y^JrЫ~Хџ]ЎЈЉ ›uu‡л}jmиƒІЌF]/i8 ]7Žšm€kY\ћГ НТа'ЧНOѕ >eЃў#х˜!ЃFВЄѕьјgЩ1њ}?9ЎХC-:Ъ „=і­ЋыЗТосУFалО!%ЙНІDтrEїёJ<бВщСF=hJ‹чаop-‹{л+5ћќNajJирвŸJЇЗ Axф№pЙuF‡<вЇ[ё™.Šћ }4ьRЇУЎ­ym!фЖcќйњ.Œ@?Hќгђ /p•€KП4sЕ1д &PўqyttДв-  <ЊkWz;UЅ”cc{ішMaЖB[h@@#WЦтєД жƒFMЏзэљ,ШПМкBŒ^= 3ЦШ\ЗvЙХ?ќсџяџ§?Cm­ЫМQБwœpЋСР§[№ЯƒќФwGєцzЃг`3аH€§•iwкЙ,~Мђ™Іпвhoš Ў№лDsWз"B-YјF•Хв6…{іVPрN%rчВxMM—~л6; Qƒ€:џLфЙj 8і‚@л$а#ІЧйъГNeq\o›‡ Ђ”Ш§№yРрƒЃ ьХƒН‡_р@"ќ>D р-Што" Л рAHф„ S LХƒЉ7K0@"цоEl р*dqWЩЁД:$ђVGŽAРп 8ЗFнпЃ ЄшЗуAТp‹ВИ[јPМJ€’7ПYўvЏу  `F]#(Ј@k`їncЃpЬЅЗ6}ДBY<@: nЖ1,…ЗБ .€€г0Ѓю42ToOžS™ЭЋгpЉнлфaŽЦтзep@@Ь0ЧЁўN€ ЧЩKёнп† ­BYМU0ЃpђЗ{ќP‚–fдƒЖk€€@а@њ.F€  AKY­{kgq‡_ ­?šYЩ“ёmY2іB–Тћ$$кя‚кcPМ­œШ[;‹ЗЉEА аа(œRxяИоm!XФ*bюŠйИЎЌ•Г8Ў‹Ћєv€€€_@їыюs    BY\v@РЈ:q*щ‰Бqqу1№dqOP„ №5•ЋV.*ЌЊЌ$GЫ}нhZВxыБFKСDРп2хщГ?їюе“fЙм‡Д#-Џ;Кп‘1&Ѓі\-s†Фі^q!/ˆu,–Ќџ‹їRљрЁƒєК‡оTрЛЖ}И--u€Ў… tT?c\†uлT’mQЂЃДЉБ]V}элk#oЄO%kƒ€ЫХ]F‡Š рGЎ7]ї#otКKІзйoЯ>мїс)“&Иу3Х?%ІђfцНёівeХT`Л — ‹ѓчЌ\ЕZgћœˆ№ˆяl”TwyS{ЛдФкѕkWМО‚>]nA@‰ВИШAРy7t “њ'в› К 7Œ -ˆOHЄKз?xWvOBкE ЄЖА`ЏKђmлЗђTьCцkоekJ“RЕYѓ47Љ f>љ›„Ы–юњlХ•IТ6™>пхНBHћЉЯOЅyя5ёгO?%єMH~4љТO?БV^ЪyiъOЃпќH]ЖxйњВ7љФ€dЏГ›кл=јƒЯfDDFPйй† ъХељ`/8A ф­тњЫu;>*Їwнх:кd•Kо*­џнXБЋ|Чћ[Nœ<ЃdёDх R ЕњЫ %eЅ\эФwg6ПГЁъ+сšїЦ яžјсЬŽЭ[ь­еыŠK„&и:}В7Ћјђпr?м§сС§hsЯўT& леjŸЭзšW­^ѕчћџьНЛwя~№№AzпоН;ЕВёНFc§ФчЇкЗHЇЏЏ(š2uŠxІн^MЃD{Лж­™)ЬFL7ЪэC 4@з j р˜РюŠ]y9yaІзмœМн_А:TШЫЩfђМщйJ†x]*ьўd7W{eКP—mnкЙ=/7;ЌCXHˆ~њфь]_ьхjвТMК• __\М‚Цю+ŠWPYw“YЅ.œГыиџчЮџГvнкuЋзI}sfлzIмT’T-x­ {ъѓє.X\P[[ЛhёЂ+WгїћЄЫЉ"нšІТ#ЫW.—qaScЛ† Е‡Пўzј“УЉ њЄВс‚С…цP”и^8Rв‚@@ѓ†+‘ЗG1E*\5œgхѓ†ѓ‘‘VЙ’%йКЄL9›WЙњлљД'‡ёMЩЅ_ЋмTЂм?ьЩДЂт5ss…s Щ^ЏnвelВOiѕХмЋЮTE1,Вп7ВB‘sЬ”H`SLx4с›яЬгУ‡ЅЭzeVзЎ]GeŒ*Zѕ6щЭ›™їХŠ+М”;+эЩДдЧcn6Ч—МБv%›м”ЦvЫ6М{хжe}7”Н4cЗƒИIРб›цQк.Q/]0АdL…QYє‚ќ’%r’+!Б­лEV­CT—ŠѕФy]V kЯеlџpї›oЌX\И"1!‘Ÿ%ЈTёь.JЈЋŠW 8шШЁ#4Ён=КKѕет+жеgЊЛGwїHЃД\ЏЅЫЯd]ДІТЯ–‹хж&кщVЏZ=aт„OЪ?Б E%ЩIƒdSЄh.ЊЕлЂлИicеIЫIŒNGёЄд$:“P?§ВoP"€u%2ƒ€гвRЌ,h4НцЏ, MfТ$/bђ‚т"%ЛДЫЌCuŸH“U3rи‚%ѓйЉ%iZр&ЋFBZјіъœМЅ $єKœ9cцпfОЊЛ!,…ЃWЋ­nЃЖЂ"Ѓњ>вЗ|їV*Oœ01';‡ВšpeКEG…œ—rH(јфо‹N–§_ZНЗŠ™‘\Д–июzgз у'ЬЮŸ-‘ЛАЉоюЖлњЦї5ЯC˜ЌSљС$Й mЁ ШЊ,kzЊR`}Ъі „A€/gђyкфЌˆл:ЇMЇwчл:г& $+3+т}ърє!ЯŒьuп=7+LѕКџR Еˆ№№i™цКcЦіКПзИщ“тŠЃ$єh’Do.[:zд˜иXсGф ѕљkњ —-х{[Г0ђ™‘ыџў>ЕH‹ЮžѕЬп^љлню 7žЩxfтѓж,.{ \Vhу‹.gъ”зђ_уљR|бкFгВACvZ~hйrѕGэЎ/[?юйqы“žП~Уz‰› р2?DšжoќТzƒЁўrэGЅПЭиЅ_МЄ$ЇЖђ6‰J›”МЋLO…SR€4 ч‹{яЩЄЕЕ5“rВ?нўБФ:h…Eg’F=ВI_ xІ™GHТH  Й4zІй№a#\ЄЊъдйъГ- ][q[зКЪђЋџњ5xЦт—ТйœЫŠE dUqѓ5#§‘ЅѕXЮУ[П% fM‘ЉЯ’шtz0їb@ Yœц!k/ŒзєэУЛо%{a>р’ЂЧO;ДP „c>‚€h%ря3ъєk™={ї”я­0ЖУ:Fб'•їьпУn-ŽвуIQl\щ—9ДRщЅмућ'в› єЫq-JЋЫŠ  {Š–гЏЇцОxМђW№р%э”xыо(ШRтB^4эC‰)l‚€@[#рзcqJNхЛЪ{ію“ёPПIТрƒ~uфщƒгщ&”МУZ,NПй}vђѓ/П0mёТХфЦž={žњќ–ВwиН5Џ6ŽЪ7ьЩaVЏ‰ьеј{cѕ™Гџ`sяИ>ЬgOv8E‰уђ“‚› §$Š6юFttєБƒФїriу@~›%@ дщЯЁ•Уїы,~ррAJс %ькНkeбтЊ~Ђ›9Ь|iцр4сfŽKIJфМФI‘†}тЋŒ|“†Т+пXAЗsъ№Ч.S'L<8UЇMoмО­ЉЉ)999џеWФ'мО}Ёh§šЬqмЎ5МН~ЭьYљЄ\\њі˜ПЃ_їВŠt їC}шЭэxъДƒS,гЭ4,/тFE %ЫNсŽ… љІg)‰[Д/ЛЩао $­O€˜вїWы7AРЏP чуДVsЬГ8MGhN)ќЙЌч‘Ÿ~ј‰ЪыJзЅ<žrьШБцk!эЭw‡ж’sgЮy-VТУ‰—Ўо^џKРќ!Qњі!…o,Ѕ‡DНќ’ІG?>|ј•)йтЎJOyr䆑Lrј{Їoм"о+)‹O;$ЛДorJВUњєю#Ё$Ћ&z–’ФИdгM†kиєњцj§//_‹vAРЏјяuqZЮжуO=Т%ШHrSH˜5Еж[RkIŠЁЁЁ†+”јщŽжÃ܊ꉇDйњqхъЩэЌiѓъе+L‹ тН4вeonУ#зХ9%nV\АЇ$оЋTі,%ЅV˜мM†ъЦБ@‚ž€џŽХ…щaсд?џќ“Єhj$њ[єП7№]ZЦтEЫ–ЎYїї’U%З†О˜;“nKIеzHoŽ ;tЄ‹птTM›:˜€Aё^6УO‰œ[аrкС•• œ’’‚„’’šXю:%йЃIVhiЯM†3ј@к(џ‹гЪŒП›o4wы+щœиЛcIN{УєBšg/qRЄћTѓEь4ђЖЈшhЮђ%‹їW|N‡XМ`“гCЂU|AYжќўЊ’ыЋш9х{vŠuhѓО}™ЄoпОхŸкьkRй#cqN‰€ШО%”Ф>xœR—?v‘ЌвЏ>WMBqЃ’В› %жА  m€џfqњ]8нN––kбC$Н"HZtД7КЋљ™ЭЄ NŠню‹}wѓVJф4^КЌ€WЇ@бяšt7„U`M-fБі‡Dq;Ќ0)k\йкЛv•SCєІmfO˜Фі>Ÿ5iг–єtaz$%IHAќ33’ˆO;X>9%љКv”ФjЇDЋљ^]4ž5)ОЁЃЛ‘Я›ПdЬШ1тF%e7JЌa@кещNŸТ EнQУUЃ…lДœmeбЪŸЈъvwїœь™$9xш`TT_кFžŠ“тМY3(”Ў.жЂ?;qчЇ,”ЄGЮЮЭЛPѓSЗюн ПЦ„l9=$ŠІжI>!ѓйИХ“сBs••]o~gЭлoНЖЂ$qЦб&„3]zпPњ­Ё—ѕьUУ•аџъјр_ўМЎєMn\Ы%ЎЌTр”њˆVПseњIž„пES"’4?oQўЯ5Ш~Зшлџ:bЬ№!цФу Хс   m€_?гŒЦЏєЛ№=џ"ќhŠŸoДш(9=ѕэ№Ївu7љђїт~rИ8EЩO|іs7МњL3?юј€ Я4уЙб‡n+6MПлІ[ЛаяЁKОљ6К[txћpњAvЭЯ54О”Єp2!‹+ZєЇ‹S@NQђ'№@@Р]~Х)8JQ)Щ)єЛpњQYЃБ!Њ}xŸС=Фщ€Ї’"7шэ‚O;ДSђvPА  аšќ=‹3”Жcю1пнE‰Ž“ЂRž•{ќДC %Я†k  О%рПkдхBIбй*ОеИгптBы  і‚'‹\R ИгћЃпž,Ю’b}мi‡oTД  `OРЏifя.$ а №KГV€Œ&@ь И№KГр‹лу€@@‚›Вxpї/ЂfШтСмЛˆ @@ И ‹wџ":`&€,ЬН‹и@@‚›Вxpї/ЂfШтСмЛˆ @@ И ‹wџ":`&€,ЬН‹и@@‚›Вxpї/ЂfШтСмЛˆ @@ И ‹wџ":`&€,ЬН‹и@@‚›Вxpї/ЂfШтСмЛˆ @@ И ‹wџ":`&€,ЬН‹и@@‚›Вxpї/ЂfШтСмЛˆ @@ И ‹wџ":`&€,ЬН‹и@@‚›Вxpї/ЂfШтСмЛˆ @@ И ‹wџ":`&€,ЬН‹и@@‚›@;П ЏњLѕЉяПUwЏчН‰Й'FЂWUY)bг щ4Tж$рПYœRјдœ—дYЌZЙм>‹ЋWС^ў›Х}ˆ˜Ц і­гјОЖЖfMщšУGПnjКв­Gь”ёњ%’&зяј_7їэля•—ѓТТТь-@  ž%рпYМХГСjЕЦ'фХSЪ—.&M~~ъЄiB’О%ЌККzУ{gYœьВ*Х%E –,mБжЦ   Ўъеm7t “њ'в› КH7Œ -ˆOHLzbрЦох#iЫnљџ‹JзLœ˜9xHК0ЮОIG3љ‹ьR5эЪ§[іЁУ‡ьMЏ<6:cTќCqƒ†=ЕkW9W([Sš”:œ™5AsГб,<чnuш!)MВLіGŸP{Ўšй‘Tф›‚ў“~ByUUujЯg{†>ЭЋзpїˆQ"їШ+@Nжm2ЛmћжACžŠ}H˜ЬP ™G@@РMСœХKо*ЎП\ЗуЃrzз]ЎЃMЋф­вњпЛЪwМПхФЩ3 >z8хБT Ъ!В:Й3чL™ќТбУ•VЏ9yњІГqУЛ'~8Гcѓ–{+BѕКт‹‡eЅѕ—˜‡G*Ш”|}bsщ†џ8дџБўѓ-‘ьЕп$ГJзи{ш‰Ai™йгіоЗfѕЊўDJџyѓИў‰ЪD‰i­Юн ТюOv3#JnгоWІ `™šlШ7А   рПО.о|ЃйиЮЎDоХ,PсЊс<+Ÿ7œЇTЪх›эаБёjЃR"g“еlu[ўЋyі6‹–-]Гюя%ЋJ"n }1wfТC}HчъoчгžfUЖє†рЁШsЋ‚r)ЄН9wRbОЎa=ЯЕЄOVХ›тъb78@%З;Ђй•#РЇ Xђ†г B—ЈŽД$х!*tˆъШœф— ,‘“\c$}ућюйW1|иY}О Nv/ cюŠYОDXђFW‹ѓѓч|њЩчTюеЅb§qцcеЛDu{Ю„.|омNGзкYžІi,ˆн o™%З%іeC–ш`@@РС<Ѓž–:И`e0‹ни8em2R&y‘IмXP\Є_vжЄЕkЫhYѓЕFZчU§cѕЌ935ж%5ZМF?TˆЕшš,cх1#‡-X2ŸIдžЋ!‹‡Ш1Г‡+ Ф­№jbЁRЙл}БяnоJ‰œf–.ГБЃTE"Л‘іDлЋфЖЄЎlШl‚€ИC ˜ГјДЩYЗuNšNяЮЗuІMF*+3+т}ърє!ЯŒьuп=4`еђЂ1§šЗооwєШРЁщёIqЏ,y|руZ*2ЄGЮЮЭ‹яЗВdEстз˜0cЬи^її7}­-uN^вЃIL>mђtЋ‡q3Ё ŸѓfЭјrп—‰і•5юa—ьєКџЂDЌ"ТУЇeš*Й-ёP6d‰6A@м!№‡шAгњ_Xo0д_Ў§hЂєnІгє;Ђ”фT~ UВзГ›дVцѓгдm–Н]Ђ4Х­^‘яЅёёЄœьOЗЬ%~X ёЗУ{?t;p]Њ:S<0йP[И!Рs@$@Пћ=[}жa^КЖ:тЖЎu•хWџѕЋЖqЈ/`а=в)IЋЗL:ъ J{KVgЯ2Ж4Ѕѕ Є9€€ј3џЭтt[ян#НSЇN‡ijiJ~4™&и§Й‡р€€(№п,ЎфБGф4_сpЪТ# yФІг=‚F@@ јѓъЖры-D  bШтb(ƒ€€@ @Єо‚Џ   &аFЏ‹‹   ž"@7gЌЉБ>аSf§жNtttя8с~вВ/аХтY!ВИgyТ€@л%Р’VŸ„Ф€FpьрЉг_вТЊтхЄ)›Ш эІ4ЖиЪjл>м6ќЏУ56ЊBCЃдХ]€†*  C€Fс”Т{Чѕ–й8"ЪтЭЭFmЯЂўtЦЖ6ЪfqЂAwюjЄ[VђЫиbдТ№1л6Щг№\ї[XР$@Яzh1Jоwн}—D"lъДeћРФрДз–gd8]б ‹ЛUA@  PrІЗј{_,mоu_lеwUb9=оIѕeа/ аПCРX< /8ŠœzќЂьhГ„сИљЭR8#!”-r*`$юѓcqŸw)Я>џЦYkЮъKНЧv0'шићу$Хо[uВв,TЇ љ^2Њ—ѓћЭ–fgB№СYџfёъ3еЇОџVН‡щi(іїZЧw:4ьѕЏfžНчЎГжИОWcєH/„‘х…ЫЫж–‘Ћ™3_ЪеКілЧЁна5S6Н*+- [фп+’Щэgцe”ќ[Diй‰г ДжŒЩГ8Ѕ№Љ9ŽјU+—лgёжФзjmсћДеPЃ!№ m[69єхўћЩцдЌчЖEGЉѕgKtУSъƒlЋE'rœЕR–|0зщp]\цhЂ”iџ&=zљЌ93“RЦ'ФЮœp№аV™+'ѕO$…ЦFќВ‚lŠ=уУ#БeП#pCЗА zSСК(ц†qсЂё ‰IO мјСЛжЮUs*ькU>hиSёХ?Ёі\Е9d…ŠВ@lЌэ0YЃ8c=ЩxЯg{†>Э›яUТєљ'ЏNЦХeйЖ ”иќСћy3цEEFб› ›?и,Q№уM6v№it8њ$…€~S‰ќЇeіoЋ‚/КгПГИˆ“Xшd”2й›ЬѓђЅ †I“Ÿ8юс[Зн_9яЅŸ}ўoŸЉэјЈн3Ж'гЇmjЏыSMcccГ–ЗOєAуU'm—шгпˆЄ•нђпu€ бВТНŸ—“ЉфщГ_ЮенdВJу˜з—–Ж7єжаЬq…Eь KНХЂв5'f’Юдh&бk‹%UТТТrџ–˜nжБйЋр nђrГЫ6llњпІєСЩГ_Ю''љ0ˆ,0пHbvRйЮ’ysW­_{ѕЗѓнюŽ}}юŒЎwЦPuК}вЪ7VќќгOўиeъ„‰ƒЫљfу(6\'АЛbз†еяаa@&ццф›2iкдщTо]ёхN&Я›ž]БЇ‚ЕЁ${џrvH{СриQ#JWiЏ(6ТЫЏМœЧм1|DСЪ"ёfqБй8WЖ/hљKБЏе–%Wў}=Є}#@…+џО46nиш9?}2Эь9їK6!аЪ>ОтЯДЪЯfЏgжb-˜Г8ˆ™ чг&ћJх ’/x]ыИљ№бУЏLЯжРдќ+бTr†дNTž !šр 9YV:mR}WZгЖ­!;lаІoђюц­4h[WЖžЊцЮœѓZўЌ„‡/]1МНўdq[œо:oИy{3J…Ћ†ѓЌ|оp>2в*ч­*ЩЙX  !њы4eziЉhVЕ§Ѕp’‘5њorуЖ5АхŽџusѓЕf–ШЉаёП:КeЎЕ*kПк?JМ IDATmЊсЊюVІц—х Uгёч}lізжCыWД$:­‹ lЭЙЗхп3ъюХFЃМaфA/бИ‡йЃB^NЖIF#4]НжAЉМшŠxсKћХїГзQr†4Й“Tи§ЩnћКb‰ŠД‘‡єэLƒЖг–;3„††Ў_”EfчхŠMЁьq]Ђ:в•f– ЂЬ_й‚ќ’UЮлU’sЅ‚Ы• Bю%ўѓŸOUbЦЉ@›^jШГfщЌџжєЎuЊМh­Лi$ИŸœЌѓДtп^ЎBТ{Лќ:‹7пhVЋsqv`Єn-ДCЧЦЋŠЫжhшLя!Cг›ŒЦќWѓьM)9CšВЃ7{ LЂbGvаVДlщ‘ЏŽ 5rшАЇ~uLЩ,ф!–:И`epвди8em2Г&y‘IмX šИV’;tЦхŠ-‹:vИЙі‚ЭуЙш + ьРSУž)(œgИd 7F==ЪaПP в;АЪKlg›§Тљ6цD0ЯЈГЫ‘і#6УЩGNћНo|п=ћ*†!Ћщ№zЁ’3d|9йEж>Њис:тBЬ]1Ы—зящy~ўœO?љ\МewHRг&g-\Vœ:TX|>06™§ЌЬЌТeKSЇ K1ЦdкgО.Ў$wш•ЫZ+dŽЫ‘1іњПЏ;<МХЕPШaЈЉIJL"!§^Ї Θdц~z @:‘kэ—_Хн„aЏ810Ro.;kвкЕeєГŸfzDЯ ]ѕеєЃ2ѕ*тНJЮ ЮЬЃ4Н=‘Цjйƒ˜\ХŽИ9^ž5§@N8 [tMџоx5 Ф&y 5nвгe‹Ѓ_ Зp§т&ск3Нш2ЧьYљGиџЩч‰ ‰ДвP]ЮГ&/0}ОЉdЉI”y-^(H6ЙZ֘Бп$5q™еТЇC/ݘuц‡3є˜[ОАшыТєЖ_ƒ-H,{iV/+ТвъЏ`Ют4ŠИ­3 ŒшнљЖЮтQФ-z yfdЏћюЙYл| —зМѕіОЃGMOŠ{Н`Щузо_JЮ…^їпCž?ссг2ЭЃ76 ’ŒіHYХŽЌ3I>œ›п7neЩŠТХЏЩъ@и JV7_Ѓ_я4ЅѕР[T’sЅ‚Ы• BЖЌ—}­ї[~XE?AДюв0Neћ6ёщƒ‘ИNЇ-ƒйіmыmЙt^c.˜FіKКи8†ЦFS7}И])"Ћ)“FзЎбЫэ~]F{$jђжœ!хŒЇЧв[R‹†AєцBk vЌ І:|3%)…ом О"аЉSЇC‡4Е4%?šLѓсм %9WP*И\QЩ ф `% К+вbЎИИ8aI—s_ЫFЧЗ…БЖъ%сьУЙ[; џЭтtєВЗKдyŽК‚в^ЧdЯ2Ж4KFJњƒ€›hE…ьЂ %ЙУц\Ўша2@@ `w1ИђhЅНаЉЛŒЌ7јoЇлЊxящЧxу`‚M " izXeœMwI|,5 ™›єC!иWAQkTі”šџfqOE(kЧЦ1|ъ[жOAˆ}ƒ;x€~@>+И*мUa—X%oѕŽыCЊЄ`S!а6h…Њіш`QЗf”m4‹З&bД аFАo№ыЪ=^эw`UЯ[ЄѕГZ Уwжdqg‰A@ o)ЂСяц_šy‡Ќ‚€€€П@ї—ž€   р,dqg‰A@@ќ…ВИПєќg ‹;K њ   р/Х§Ѕ'р€€8KYмYbа!€,ю/=?@@@РYў{з—ъ3еЇОџV=zЧНжщižИ­Љ:7ьў›Х)…OЭyIђЊ•ЫэГИz?м‹г?ьИ A3ъђнD™•э {'ѕOœ5gfccЃ|gЄм8Ћ„™gрA@@РJРПГ8=›]§m Ф‹%ЪВєоёQyЈ^П`Y[‚i№’MџpЪ3^№аxСЛюдuЁ9TўХUзВы†naA!ЁщMыѓэo.ZŸ˜єФРМЋё2,,,їoй‡’iYЁ!ВLіЉjkaСцkŽ>yЛМ@ В“ТЎ]хƒ†=џPмшёjЯU3ŽW1Š„Д‹dƒ(ИX•@‹Ы#ž{ФH ‘ƒП р€@0gё’ЗŠы/збšоu—ыh“С(yЋДўwcХЎђяo9qђŒB6ЛClЖ,J бў•'ЈjЋўrCIY)Iиќ9п[ ˜џWБsфы›K7јЧЁўѕŸЗh Ћ;sЮ”Щ/=\Йaѕš“ЇXУІпијСжи‡ш oЋC%y‹<kI$F${[gг5Я%ОyФˆФ&6A а sп]Б+/'Цаєš›“ЗЛт ж[TШЫЩ6‰УђІgkьBК"^јЦв~ё§ьѕ•"MюvВлОЎXЂb'џхьАa!!њБЃFœўЎŠе 5\!П##ЃfчхŠMЁьЯ6mй4wFоі-›ќйIј ќ:‹7пhVЋ#>oИy{гЁТUУyV>o8OiЫеа^Ъа{Шає&Ѓ1џе<{}Ѕ†HSж{ LЂb'Є}гЁD~ж ˜^EЫ–љъШQ#‡{ърWЧЬRќчпŽu,тжˆсCFDDDа5ЋГ7t%ЋŠ“R&Ѕ&n3 гйš~LЪЭзIЇљš‘W$O’K— /ݘп?‘ЎрLЭ}‘­ФД7BЫж”’R›5AsГеЗi-(\хб)]–R37Ш,d/)ДК"дe[ŠFDЪВ4Dћх‹dyлі­ƒ†œ›wЁцЇnнЛ.~MVBП"Аeы–+WЏФЦ›g†ЩЗ-эœ6I80„ =– @ъ>wэ}oЬŸіь?’”Иgџžz>РЎUЉ^YДђtѕi:Д мW;Ÿіф0k jLAщ*вe)%ЙЕ9Nіђ–Šˆ4вWae:‘В*I”`веЎ5ыў^ВЊ$тжаsg&<дGЩф р&еП`7mЛ_нЅёЅ55оЄЇ5_іЫОшвђьYљє&i,KC{OЙ^АзБJ"…ŒЇЧвлЊi*eŒKo.Д6Ё`ЧЊ`ЊУ7S’RшЭэ аj\М=№ нЖЛОјd7_–Aё‘Я Їw7щКDuЁы/љЈЇG­.[OYќ§ЭяНš7ƒўЪЋЏМ˜ѓbbя>4ЇЋнq}ћЩщеЅb§ЙŠ]хa^й_–b№ЫFдЛ\e/—ѕD,tЙЂиˆИЌ‘†ИŠ}љцv:"IпД‹&еь”`ВЋ]ЄOШѓѓч|њЩчіu!№п,NїH/{ЛD=HвQWPкKЫˆВЦg[š‹Š‹вњPRƒd Иv{р={і<ј—?ѓN–ЉL’Ї<ž2ьЩДљ…‹чЬ凄”ўН”MЊГ‹/]o–Иб;ЎЯЪ7VlлQsg ллддЄзыBєz:9(ZН†W‘3rи‚%ѓщG”›kЯеЌygУЂЙТ­ь‹]хЩŸ=—ік_–b‹=Х—Ѕих*{ЙЌqБахŠb#тВ БŽУrЗћbпнМ•~bМжМtЅЬŸ”`веЎIЦu§c4Ўv9„ 7 јoЇЄ{ящ:u8tHSKSђЃЩ4Сю&DT-жo{/gђ‰цSУF­/[MY|иuриK—Ѕ&хdК§cI8Jr‰š§ІЫэMAE ЊъдйъГП:†Ў­ŽИ­k]eље§ЬkдЋѓр-К,E?RЇЋХ’ЫRJr‡бЙ\бЁe(€@№пѕ †Žа@ (]–R’; йхŠ-C‚˜Вxw.B/ I?йy?%ЙCW\Ўша2@ ˆ ‹qч"4/ {{б:Lƒ€€6И.ЎД@РC6nz—юvю!cЎ›‘Н%Иыц”kЖZCЪ.јћZа$мЙнr—x7нuhЧЁ‚›И\ў.шЏУхъmЖ"Вx›эzюt ‘В Е?IЯ}§і+л§аь-hАtЧ=zП›“}\%qЙшя‚ў:шЙ8ЏЯНEїyР6DрРСƒ}удxƒ6p šм KC’04игgNш<ЗhuЙшятСмs№ l_CЈDY\‰ ф  J€nЌў–ЋНџћ’}Lndm—РѕІыt ^МˆРулџ#@сdqЇpAьіРt‡`•ЗьэПљўћПмлг бющн*ЇZВВІёЈф‘и’MssB[ ш™тє0ђІч—s7dЭ:|BЖ}Лм $ЃdЖKЖ!q-z@пТ‚ТЄў‰єІ‚№М>г‹Ќmќр]ђœќЇ(˜œ5AŸМ-^PБ#ћts‡СŠДЖbёэU2Ђ5ГFŸfГЪФн*іЧЌ=Kuэa’P).ХGП{сYђщйѓћSпиD‡ GХТ~А#@їf?‹Rљ”Н№еKWУ:Z™eџєn•Ч‡+=ЪšМ“<[ВЩм/)+­ПмPБЋ|Чћ[ŽTZ‡;JfЕН[щёсJВ&S’GbK6Эm}В›ž€BЗOІзмœ<Г:’Y-OШ–mˆ[–”ЋЩa мy*ьўdЗИ–}YХŽьгЭЕkпŠD"kDKдb;*ž+б&Ž–žЅцИО6˜_фхd›œ0ёТL-„—Ѕ­ЅЂ˜ ЪъќїїтЎ=6J=к@мK™Ь~ЈˆРg"а!ВУЅ+ўX3йЇw+=>\щQжdVђ˜QЩ&#/~~Йxy’Y-OШ–mHЉЃ•ыЫa мg*\5œзВ/Ћи‘}КЙ–`э[‘Hdh‰ZlGХs%кЮі,5ч$ЬѓќˆхЩˆ–GТЫвVЉHЗGvAй!џЭт]o# HсСдбм{яЗпŸJ‰4?^щщнВWz”ЕF>тч—‹ŸЎdжй'dЛќ(nБџJ@H‡?|нє˜ѓ.тZіe;іЪ$q*XЅHe(с•uƒ„ЮznЊb}2Н–žЅ*В0•т\Кd>ѕлW’+…Цх*П=uъоžpMД№пuС{ѕ5РД/(Д@§ГЯїq—йгЛщ"є?Н›nќН^ђјpі(kі5JЯЇ'Xs;Z iЉшAрІІ DЪV2KіщйbТ:В]“†П5і(nњA|уеЦЅЫХ­юП Pь|кi,dішtћ№Uьи+“D)Xйk:J‘ЪQТ+ы ѕмTХЙžЅ*В0•т2Йd9rŠ‹ИчJrЎ TPЉјйћ’њ>ЌTrYўХe]v$”ќсёMзVRkdAv]+ЗЬ<т›‚ўŽђAУžŠOˆ1ŠnЬДчГ=CŸ~*ўЁИбу'аї/@vё*U/Fхfщћ”њ””:0)5q›эcfа>Рч&OйГoŽNЈ=1žCeЏЩu„‚Т*YХЅЊ6•­’ш\X}Эm9p˜ыљ}!1!сыЏПцzzwФmS‡ІгЛѓmi“G@ŸПdўј1ЃИ„eныў^є\p:^“—єhпЅЅ0mђєˆ[єЉƒг‡<3ВWœѕ‹RЩ,{Bv|пИ•%+ ПцА zї—ћОL|ДпЈЌq‹ьѓŠJ q*Јщuџ=ф9љ>-г Š=нњ7bБЅbЧЂbѓПlАє—л;ЎЗžiC)RY#ZЂ7сЌчTзйžЅ*В0•тЂGП[œћюЁ!;{)ЩЭЛ•џSЊH_ћuЪc ЪUБG†€џ>_œ2™kpІ?iё,4пЄќїZўЌ„‡щвЫлып™—KlыЖ­ХkK“ћіу›_RѕЗ„ъJM››ћ›АœDмJйкRZЄ*ИRњївiSЇГvљЇ}€”ќПБтЃ›™§tчŽ;:e<=ж^Sм+œћѕ\ўьЙ$œЙpў=wмЩкфчыђ_F-xН bO…˜3k‚CnйђТN]˜2нmБЁЁŒЫ*“З&ы03тO‡ЯwЇQŠšњqљ’Хюikuљ‘аšO>eђsSb{‰~иšЭћe[J~W’; B\‘юРкыО{шМЧa­ VРѓХе:зЄВ+-U{ххМШQ!!њУG\џїuёцщ“UЌЂЪтUйХЈлwюž››G+\BкыэS8йД&f#єЁ{і Уq:Я=ќЯУ#ž!ЋЩ\bŸJЋdZY* ЋЏ™KіЁ‰Ќ2}I!…D—­*^ЮzJщбяJr‡§+[‘ў.кx wШMVС29"ЛгзBЯ>6ЪЄВ+-U№Аa4)P"ЇOёцuЫ%F•ХЋВ‹QХ+Qe›– pBц„+пLIN)*]3ёЙ1ЬYMnSi•ЌЪЪR^—dЃsaѕ53Јю0ooPzєЛ’мЁ.WthЙ *јuw­?”VZzdЉи%Ѕ†Ф:*eчЏZWЂЪš• 0сЁФеџљfЩšвoN}Гhv>Ћ(ЋЩm*­’UYYЪыђ‚RtЎ­ОVw˜7ŠBААПvЌ‘њg\J~W’;ŒТхŠ-ЗA… \нІДвв#+HХ‡ˆRCb•ВГ‹W‡=™6ПА€гђ4šВЗ, ЉMШ|aMщšЉ&ђ{5+i2›JЋdUV–к;ЃkЋЏеЖoh#‚p,N+-чЭ_RККЈУЛL}vтЮO+X_ВЄj~ъжН;_sЫ.УаК_š&9%<эЏдF Ю69>‹юЮ8dдHВ?mRІ}+В’šОЎ{З.ƒЇѓ*JšLVЩ.\VLЋІi3}`:m29­,-\Ж” ‡оš9&уа>3XnV\P‰ŽV_ЯX8]Щ›\_E™щЈ;Ьэ  m€_ЏQЯ|~šzаГ(hfF]{iхчуKI2пiФ#@Ф+K=bаЏŒxuК_E g@ќŠ€ kд§w,ЮЅЮWіБQъUкк^њЅћ/џѓKJ’g~зD3љYуГŒ-ЭEХEi§Д5˜ˆ@ќ€џfqz$”ьSЁќ ?ћCПВэнЅшѕЅžr+K=Ev@@Р#ќ7‹{$М6nФу+{БВДQ@РпсuC @@@РKХНfA@@РыХНŽ €€€€— ‹{ ,Ь‚€€€з ‹{1/@їX˜Џ@ї:b4  ^"€,ю%А0   ^'€,юuФh@@МDYмK`a@@МNw`ѕ:bя5pМђXMMїьŠхшшhzly x ?A@РƒХ=ГUMБ>uњK­кjk5ЖэУmУџ:\ckЋŠ—“&ЙF\P&Штк›4 ЇчЏ7^k дT§6ЖЕ‡6|LЦЖM‘ХU‰b'€@pРuёрьзЖUKл б‚€'аЖВ8=o›Gю~СГж\ђЧЈЛЁгў>UyъБфЧюКы.эU|ІI‰Y{h.БC%m+‹A‡Љ„pзнwЉьЅ]Џ/}Сь?ў№ЃКі‚€ ПО.NƒнЊЪЪ@Aщ?iРкbфэўј]•x“Ыyсєщг Н{ЋыpeZšёГйЧоЂy№ПЮт>b0ЭRЗцp ^_oКn ЇДьDhИ.ЎЁїЁ ”pF§†naAaRџDzSAИzЪ^7Œ -ˆOHLzbрЦоuxбКlMiRъ@вŸ5AsГБљZ#m6_ГцAђ„Y"QЖ4i§пasVUЏ•bя‹eЖЉАыу]ƒвХїŽ=jtэ/е$g{щгЌжЂ[Иhaв#ёєІ‚.!Fт^;І`@Рп ^/yЋИўrнŽЪщ]wЙŽ6у’ЗJы7Vь*пёў–'ЯЈƒпИсн?œйБyЫНЁz]qIqHћАС“ЗюкЪ+n§xч№ДС!эѕіЪ\ЧїaRнђ&oXYЇ;rєШцu›ьЏьŸв^ў<’WЌЂ§є)Zt%ЋJъ/жя(Џ wнХ:кДкс}XрБ˜|`'’OЋУОяx О!xY|wХЎМœМ0гknNоюŠ/9*фхd3yоєluœ›vnЯЫЭыЂŸ>9{з{Iфˆ‘›олЮ+nњp;IhSV™ЋБ‚П]ПЯ5?Ќ#E2vдигtНмюЕћ“нyЙŒЙsiгNХьDьНDМeh#ф2ЉЈ7ЮЎDоХTИj8ЯЪч ч##­rQ ™тепЮЇ=9ЬКУ„Ёkзш{cўДgџ”ЄФ=ћї<аѓfPVйZзЧ%ЩtВy3Є=Й%”CBtзi8k*›<5+ИncђШШ0F‰)“К/?lќЉ:Y{Пљ‡‚TEфKб6€ј–@рeё.Q/]0АDN…QAA~ЩРђ.ЩеБvˆъRБ~Х%jЃžЕКl=eёї7Пїjо ЖWIYRз7›B†Нј&/А|гRpекbДь™ѓ]‘œБѓ‡&<Ь?[ьтk#|ч/ZŸМѕДдС+ MЏљ+ h“3Щ‹˜М ИHц˜‘У,™Я’}эЙZрЦєщ.žЦпыЗэ( ˆЙ3† •”ХMјfuл aˆЭпф+ѓ‚dS,:˜ш]jlЄ7h“лё‡‚иUБ?•••тMV&eМ@@ m№їБИ$;вhlкфЌ…ЫŠS‡ІS‡ЅLЇMжsY™Y…Ы–ІNН54sLЦЁ}*=š1f,э7}Э–wыо}Bц \yєЈ13Ю_Wђ&—Ј(s€+dMЮ*^VœnСH›јCє i§Ц/Ќ7ъ/з~4б<њTтВmћж”фTZAІЄр'ђккšI9йŸnџиOќё†ду2iюСЦ}nsЯЇ{RЅhvУXўqљ№a#4ы;PЌ:S<0йP[ы@ЛA@РЃЊЊN­>ы№лlшкъˆлКжU–_§зЏ7ЃЎBЌdU1§р›[QqQZџ*šиT$—Щƒ*6 jќ}F]ЭwЛ}:u8tHSKSђЃЩ4СnЗ?(жлдWx—жаДъ D D ЈВ8ЭB‹BB:GIDAT8œˆЎ^7ƒt*ф№ -ИŽ@D рcA5Ѓюc–h@@Z—@PХ[[‹ŽŽоИacтcЉ>іУ;Э…;лгяШ4НьЋ šTЁ СEYfA@@РmШтn#„№dqGГ   р6dqЗТ€€јˆВИРЃYp›ВИлa@@|DYмGрб,€€ИMYмm„0  >"€,ю#№h@@м&€,ю6B@їx4   n@w! €€€€ ‹ћ<šЗ ‹Л@@@РGХ}Э‚€€€лХнF   р#Шт>fA@@РmШтn#„№dqGГ   р6dqЗТ€€јˆВИРЃYp›ВИлa@@|DYмGрб,€€ИMYмm„0  >"€,ю#№h@@м&€,ю6B@їx4   n@w! €€€€ ‹ћ<šЗ ‹Л@@@РGХ}Э‚€€€лХнF   р#Шт>fA@@РmШтn#„№dqGГ   р6dqЗТ€€јˆВИРЃYp›ВИлa@@|DYмGрб,€€ИMYмm„0  >"€,ю#№h@@м&€,ю6B@їx4   n@w! €€€€ ‹ћ<šЗ ‹Л@@@РGХ}Э‚€€€лХнF   р#Шт>fA@@РmШтn#„№dqGГ   р6dqЗТ€€јˆРџС яЈ§:шпIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/23.png0000644000175000017500000005411011733011756026232 0ustar sylvestresylvestre‰PNG  IHDR˜ЫEжtюРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ |SUЖџи{›‚3m!рp[аБˆ(XZ•Ж2в‚‘Чє"* LEш0 €ђyByи[D@бa (PPЁ82DJG ‘:ŠЭTк і^БщџS?ўзЩIvvr9yЕiњЫ'Ÿv}жZ{­я>Щ:{Ÿ“фКšЪJp'а+1БМД4мГD~  а \Ч yђгЙ­r–IрФЋ3)№)xЊт)у—ДЬD5€€ДFЩOЯЃZ.ЮШЅ*nЉ­k3€€ДLеЧv^§ў[ћŒ\LЁСк2Aд   аz 8 ЙекX –šѓB­Yhєцќ Т Фc;їl$№   ќЏ ЁрС’ўgСЧр,фBc-ПУOйRSiˆbяЪ б^ИВжYЮ—XЊЮФvŽїТ Њ  !OРџК ќЧьn1№…мm—sГўєŽ#Њ…[ГЈ6wљсФ…ZƒЅѓ}ѕџ!De,wъёвuБwe †HОЭГlˆŽэ‘T§Я"ЁбГ.4@@ZџыB(x№ŸИџYИЦqВМЬЕEs+ТcаЙXюm—zVŸС4?•T.>ЂЂw;5|jьђЎoД›ЅS6qTMмЧєЁ 0ўз…P№р?џГрbˆHНЇŸАю€иТMЮ9IЌЇ)rУљ˜bj.[­5чъOэЗŠП QjVB”Ь‹ž†zR"ŸjnсЖЬ_XЎ>zСVя—yQя5|jьвˆСЯ]ЭвЉЧ˜•|tф-R$щЮcRPh:ўз…P№р?/џГp!ТњƒŽ{мК "ъbn э ЏяlЕZЉЂз Q ЗКz южРeGюНЁ2†.НG4X=,кпf№PяљXc"Ќj>5vё+7KЇS`Tђбс[МhaC@Т›€њЬ—Ы;Њc|Я_ ™Љё‘‘‘&SE›{T~WYcЖдiЬŒ œЇX№”‹ЩЈзЭЮ}6Щ6WЖЕMнR'Ў) Ei'й64 GЮ™—}XAЫЌ=њ(кK%Aв›?a`Щuз„“п˜з2бщˆД‹ў.ЮGy?lШУАDЃ1:ВюZCAЉљOь_mл7>f∄јN‘tfQўяК'MŸ|­pл jТ $Єі4FrCA'L9щІK On.Ё Уўщ§H•вђƒUЭЫ]ŠйtЕ!џУŠЯ*эС<ил8К_|\ћШКaгбŠї?ЩЋ%E+"ђЈ$Зќ_м=ГйшШ[ШП­Qa i—KRJAJ#Ў?dІ% №оюБ(P„\]P№ ' n№ој ХyрU|“нГbрЛ#ПђFЕИъ!ИЛцДўPWiЊŒяПcчŽ;юHЎ­Ћ­яGЃЊЌbEŽyпМ/NŽ.еFtтё67бPХ­8Ђ† і;сœ6э=RёPjBњqжk k>6\vђЃФš7?›U0мf0Hы№бэ"gn-ъЬwмf7АUЭw›XП'OWь§ЄbаНН™ЖЫ&DŽН7aТ}F:]XВЕ|xПИ ї%Pй~у3э7МWt;aнž“пšъКЃЧєKјьыZъкеƒ РфдИє^ЦCЅІЧХDRяЯ6ЌзЌ'ПЊыwKє§ёТп+ ї'ˆg?хЬ]ЭСЈцJъёф9гŽ+nž0ДпМЁ cџRBС<’dœ20ЎќBнЬнGˆ№Cї&†$Љ&Ѕ•Э?хэLM-їБї"\ђб‘ЗАы&ќ@+&ѕЄ„юДщ€эанfЈ#jIˆ№@ yШъBСу.S;ŠŠЊзЈ­т[ЋЫƒе™5 Ÿ<ИT(цAЃЛTВрsgdєФаFgПСc4Лн|kлzФЧЧ VЋѓ]‡ ‹ž4B_/gЯMOѕbсъ№!ЊФDдЦFи'г%Ÿб„ЕvoIЕЇі2v‰pљr:KЃЁ^ uxQy§ЧІjГйb—‰3щЄ›Œн#œЧJёgeжŸЌj~HитбVrМœ>Пч3ё 3‘К=KЗ,DGаuсдwцМн'or ƒtшЁ@F/бѓ‰В2ђ,`SŠЫХ№ѕŠЌi т‰Ы™/* t @АЊЙВ/~Њ=ўhy“Ad2*QћT:#bыŽЮ т73Mщ7nЈИ `Ўkиtи|ъњ НеjыZвяЏЭцщAѕЕZˆБд9ЁЏ4з]Kш`ьвЁВ_їhZЯ?џ™вщ~sЬвлJОv.Ž{ЈА бRќжkЕъEˆЄи(BЄдЂrЕм5ЕДВЕЕЮCm„лЅхє.­зš++ОЉhhl kф4Џ1зд\ЁЏ_UНу]!F­”ј}§Жi}{гwдd%‰WйЫЮUJ†tЯ=шlУщT:]љЉ–ЊјрдgЛCRєуи)ў/8-.ЇJMВ^#\oИ5Юји№ šS|љсCŒёcГpТdП­ь6љвКzEчФЕ$.Б?лc{™ИОдыq ЫЪLT›Х1Twe3RўSPjЛ0 ВаcђяlЏѕЄ4Ђт;PЫ]—|tф-|rЁэъƒ„nќН.wZЈІс Л@‚MРу{Л­Š ВъEqйы‚Gъ)ЬƒzzїЈeСЊ89кєT‚ЗžЄВржЈАc0;а%rёyяоНЃMбgЮž7аЅHЕ9}kКЯнЖ§юLиvgХ@“зƒ%eЕЖiшЖcІq§уž}|ѕ?0ї$§]ВЇтЙСёS?_ЎјPєУkв /ZАв•уќgвЉ№”§Лю-Б4Ј–я-7O—аЉщW\l8ђi‰A ЋјіU}Щ‰Fы\Šo'Єў–nss?УЈОb%‡ 7Fš.еедеаE„њFƒ†+>`7љнЯlёї1nњC?šШn:jЂћ о-д’вˆŠїЌ–Л.љшШ[ј.4ф7Ž›тЃбЉ&]jṉ] A$ ўоN“б˜FqVЃTНlIЖъ<‡(ž{ђЄЁ”Ћтt6CUœ\P aqїЅdыќгъJqвІіk<г;ЁGBЯ„ŠЏФOyбьTШ/ФЄU7r_ЮИОцќwdp ЂHу$ХЧкят™Ђ(•пMЙзpžlЯ5Ци>Ž5?_ќ(š4UЅ‡ъFБ|в&}(9FoЇ)ьVёŠнкж%ТоBšДЎ.љ!}ЩЇЂжЉ‘ ?КuNДlъEч‘Rwtmоаи Ўъ7 ДB@ђ РахълФ;яШБxіУЧF›} Дв vzЁ1ž`вф7Љ1~›+:!АFDZlw+Њ%Ѕ9—jЙkр’ŽМ…œ—ЉS~“iˆŒYќёkЩњ:<”Z`ŽРё@ Љ (ж)ЉŒ)д-GŒR]{`ѕЯЁшќяцMУеNљ yvkзЈMЮ^uHYА5 –—bЌЫч]ЦTmrY"DМsМ2ЖЖюžƒЌН\[}ЙкђНEј…`эЖ_Иљ6ск‚аƒљЕ фMцPN*F0з\ЏHЗјЫl%ЗЃAржѓЏЊВŸIаWФXЈИкЮVОiŒю"оM jRщЅіjСXл!Жд‹ОФŠ(>"7ŸМчЎёtЁšЮ%'тІxБYъЮвE7oйМYKDДxк5Шѓ…FcŒsAоЙЄЯкХDˆg$ѕ‡Ўј€E[†KŠП‘ЂДA M‘ГшV-)эЈФdmЕм5pЩGGоТGЮЫд'П9§„эЧ QжкСIтщZХW&сzћ'е“ТЦ_f @obŽї1ХоХŠр~UиІШъ‚'М[ošмf˜N'|wЬƒsЗЏя–ѓ1qkё‘ŒzЇЎ`Ќxп€rœ‰šPЉx4жЦўzsTДЕжPo§ЁЖs‡n4щДќ`ЁŸKБvЎŽM#_XОИ ЏИКUнЂрЄѕU Эђ€Zš…ГЊьАЕ!G9Д5RХВв л4В‡м'SqлEnщ)wтю\Љwж‡M ЄйЖkГИ%оgюъPУ•[Рn›Šё+6JahDХтt† UЭ3Е_рnщ'Wђ>r^&e~ѓŒЩКъїt'cЄљšpшДљ%є1BћИkЦ‚‡ "|. >ВФ§їР\љ,Ајѓжшб­‡B.X+…Џ-šФоѕЩЗнпuЄјыЖ7ыzkН~o%КООбb­=лёзЮ\ъ(П‹”oЗЫbDЊЖLрšђ{#Хevaƒ€€„ђаD  >@!ї Œ@@@ 4И|Ekh„„(@@ ˆN––TVVБ/]ЧЧЧїKLђвъ р$€Bюd @ ь HU<#}PшdZtш ƒZ:#вт"A!oqC†€A|'@sqЊтбб!є Ы=zœЏ8Bюћ ЖzK yЈ­M5С8вђWH-Ч#хжc0Иё>[Уж#?ІA Ф јRШЉŠ›/›'>3UЬ­Q%A[ЛеeЇmы'—&ч†‚ОmЇІвhpК$Ћа.˜џ’уZ)+Фя!_W8ž“e‘82VЩT!uч6eцй™#YЈ‘—КwьUШBpДЉ „gъKЖЎXќќNТа€ДеX1GŽ4Yƒ‹риЫрdши+7q’іиЖдBmd497ŠžiП­ЦfЃТСІь‰M]бЙЋg­нVъ]БkyПnЏюРИ*>ДC Т€/…œ&ІуžšhЕ*М xFrНŠŠ­н п)ori‘™Ш\дŸдŠОЄЌžЏB šЩЪєe \ІОЅщcŽ\П.ЂZю’’cЏjš4јŽT<Ј4ѓ–6й7V27і:hИЛН^PHC“ŒL_жРѕс[юох(OЭжт–RRЎ:Ў[~gС9€-›€?3DЈОЈZ6D  -Š@ФЩђ2V[ єб] ЭnЙѕ–ЏОќ*%_!2K NГIr V№њXНї&aЈ/з iЕ†ƒŽA АкЄог/А›бНA7cяш:Ф ДЊУ#<’mо,z%&J‡4 вsР§isчЯЉЋЋг>дM*ЇLŸ‘|ксƒї}XЄ­ŒН р?ыВ›ctyЅ фžЏ‘›LІМќМcЧўY_хіНž|zrЦ€T]ю}RњъЫr.*Ясyп‰.ŸЗмкЫ‰wюНБba0СЛО4ЕuљЄh%'кЗэп?}СМYоžGWGђPMп˜В'gpргбЦќУƒЂ+5oFœyж+И&ЋзЪ=]9влЫк љћ~tѕЛЊЈ_vшŸ|WжиЌ~§єNоьІЇЫМѕyВЇ{x”8W‹z&МДЬё^п(,yiЩ€{“щIћЄSЏпікЗЛ`Ша!Щ§z5ЂМММhпОУGˆ›Yci*&ѕKjлоо6рўЩ§мЭхmZЗVвœ;nƒеОќ@ ўV0d№^wкg–rCџ[lщьГЇ#Ц_!љІв^њЫдЙК+ёіњШvбУЇямЗ“ЉэмНwдаaTз8V{ЅfШƒƒ“SХuј†kК–.˜ р6>и‰xlвŒ\ѓyьиБŒŠ:kз­ЕдXіЄguM5mкешmњиq:/>\њр‘Г'>v|Уњ тfЦƒ/.z‘Љ*=Еgчžƒ$?М9S„m›7њќмžПю)>\•Ÿ—ЯN>Е§эхЅхіЭ\D)3чL8~тјізЗSќїgмџт{ќ3чЮœќєŒGЪ)ггgO“rљiqvKEСIіГЧтя'Šїьж}ХЪЬЇ›аЬ9JмAрСj Д”…š‚и^kЁёЅQІБvТЗ џr=Qе_Н"ЮХ•ћпп?{цlкK?Яќ3m2-Z‡ядЉSddфшЌб?ўяГž›Х6Яž>ЩдfOЗ›“оœ)HНКФŽ:D“УœЉ9ћˆг_щ1ыO>\жuыўП€.+иz,ыБГЖЕh2њ(ѓ3Н)PjѓfЯStіоіїzѕщE+‘э"'=CgEŠjдиМ9кокrЅЗ6)BЌЦ@KЪj |;5ЫНќ\љM ЗЉ…Tј'Sгyx№Н№Ч!пЮїЮќOрЛжЏЏЊтAЈЧаџ4WПМК{з.Ы.HNM2|ШкМ• зьЋbЛіюЂХWGЛШЉгžc}ёЧk$Aч˜ђ&”Ѕ›н†ШЌЗZщD3аУx р{!їPЦЁrџТŽ9ZBWcгEГёFёж|бмоиyc‚dЅЖщjо•ЉЙ э] пиТŸLИ)ШcSkЁЅAfЋІУк™&Є]вfќ- K—‰wН–”–Ь_0џРћјН’<ыљY3ІЯHъ—dhgА6XSњЇ0WnBsхXjЛWŠ–ўКE%Е{h5Б§’йh›таТќџ§ј'гЇMWь‹EB‚ЮУУлољ.дdпŽцЭлд@‘C5JRЛ†! FM№*GцФŸѓЇœAщі#ЙЋБ+&ІC [jd›LйіŽЁ№’ч4L?sВц•е{ ЃЂbК'H>ђ№#ЙkѓiRN›ЙЏфЅп—о4С —жLРзЅu_‘=)ћэЭ› їж]ЋЃoНІЛжчЬŸ#Б8hиђ5ЫiU–$аІЗc@ŸjГYзх­Y>єAnЮэъhф˜‘ —-”*Aх…JК\чКПyЖ(ŒJSЅјMртƒ=њWхEчo$зззг—s ѓ%ѓŠ—Е.Г…fŽRVZMкѓж8†8?OђfНfНјЭзНoыэqиt^ѕюБг€(x’"(=‘јlЈЧ9г™œ3™nOЁ—*ŘЏš7ОКёі;эЗЌгRйђмхuWыhXѓзх35AqLн^5jЖСk›ѕ(НУŒ4‹uA6ым9f№ˆсi зсŸ›ХvA №ЕS8T‡4ŸFЃ1oнktѓк˜™i—-_іРР$“I'uщи%sD&=I MЛ+7Зj›‚ачЗ=Чќї˜Ьa™Б11“ЦЫЬ†teКЯ}ВsВгюNœ=і€ў”;вLФnBWщ8zw ’ЁЃ}@џ{шЪ}bџФеkW/^ДXr;юбI{,‘ОƒТІ@КЏzЗ;wЫWОщЭqТO2uсmHŠ ФPй@0СMJDеPž‘МEwŽ“Ÿ˜ќсщ.АФЛГŸЬІ_+xyсЫіЦMъо­ћ˜Ќ1УG ямБГдш л5ZjW|ЩЛНjьNфѓ-bКl9 rГaУ2Ы?-uћв‰OL:|№Р‰#Х/-^Ъ>Ÿ&ЗE ŠРu5••ЩOчІŒ_b1›-—MяMА/itPАkчИ'&JgйjСл•˜œXzBќ~†І|ь,и9z”Тe‚ІŒ!и}…fŽ•пUN›>mїŽнЙ+sЛ§Ілш‡=ŒB`жЛNјMРP-$Еv‘{kи9КХР1-мН3д~МММŒ~|”вUH7иF`ФцŠиŽqеЅ…WПџжїkфн№вŒfщНY:mbШ!“cўЋ'=іxCЃ•жиІ ЄуэXЩБ1 зuрљ…Мw/ЦСяоћR I­]б пшГЁш$89ђсЙЫMпЃ{и%aŒ‹ѓ)4п~ФдЇЎ”Œšх$ЂY:UЪ>ˆmЁ“cчЮ‡gЉoЌЇл…џ8FŸћЇЬѕDЈGGЂМwm}~ЏџНѓо˜Ќ’Z;3T|6$‡AЪQ-дfщQ#ь"рЧŒМљђ`п#ж|! ч Ш|8“ž>tУУчо}XЇ‰ZHjэ:іdж IDATнњlшбsР2І A DD˜M&_BЁЛ]шйЊ­!хжcАкжРА5фьуўA pќИk=pAР€4Тн…ёёёє…’Mа—ў.zѕъMQбMФњM  <—жщ x/­A6„Ђ У;гжcАGА50lЙ9Ž{дУG‚}xЈљ—>Р†ZЎЦЇUЕгYл=Іяu!?YZBNщѓ]C@@@'zяNИЅ‡NeЈ…1ЂC);ЏjЙз…МВВ2д>…Ц#Šд@ZP[ѓo=фC*г =ш{М*фИFR#ˆ`@@@Р;(фоё‚6€€„ђ  о@!їŽДA@@ Є ‡дp №Ž ЙwМ    !E…<Є†С€€€€wPШНуm)(ф!5@@М#€Bю/hƒ€€@H@!Љс@0   рІ+фНН ЭoэІяQВo1јf%яНYZB3ј E(Зj~л›eЌ›ИгV›xsFw-Ž@гђ–…&иoўћїпCSŽHЫŠЖ)Щ /№“@DРWё-ЛМДдЯ@›и<ићяпuuuY?Qѕ]•?NМŸ;2]Ј\ў?yЅgJлџ"jЪфч†=сUПPMє.сѓ!š!*hFmFиющѕ)=Щ-/Жxѓ‡РЦ7_{tЬH<4эЅ‹ць?MЫљpёЗlмzњЬёІщН€€@ "аЄKыћіљpђн‰cЧ?iКPС0mкАqР СЩЉis.jhАВvЇ№“Аdyю€ћгшI‚№“}згŠТсїКлv^T[D~<8xлпv:ЭAБ wsЮ€­+ ЖЄ>bфУ&SЅ$}X$ дBэ’ЌhЮќS.kзхSњЅp1+ZIЅПЬ лўіЅL‰SњфАсZ9lИц$)Ж?З}ы–ђOХЅћЕ›6Z.змWИчЏ;Ž—:go]№цЬЇ› 6гщŸжПьTmж]­›ЗbБt"RrЊŒк%mѓMon<їЏ ”ўїж\ЎanЕ­˜š$œ*=E)Sт”>Aˆl=lpњЮ}ЮS™ЛїŽ:,Вєѓђѓž™oЈv0$м’АЪvBFзТ,˜џСћx+’=*№њjGЌЧ№tТTdЈ–š{`—ЬR-чK-яGЇОЮcIЭ›N|`A hSwЭ~+Ss%OЗO/ZЖPzOЁЯб§nђH†Ж|ЭrqнГЎnсšхД)зЁ–Ёƒ.ЯЯГiе‘>гбгSіAИ'хоЅkV?˜љ й>8фСЅЫVS‹N?#К0w9]_Ї Рtз›N+75>ыЁ•ііKLВў`)иS›а=Aj”.LВЫ“ђ*Njѕѕѕƒi0аJ‹^V^ЭцPУЮы№Вўhyј‘мЕљD†žЙЏфЅп—ЮћQ”oўmЏЗЖяЄZNHWЌtLYэ` OМi‘юЃlъЫEЬŠ МВкы1<0ЊЅ& ЬёЩwо§ Ч–їЃS_эXъаО­щЂ§QrЋцMƒnvу‡r+'аЄзШY{єБ>wіy"'›n~~ўьї ЋM}zRlЧ.ƒFdвГKЧ.Д)зЁ–ЉOчФо`4,sјщ“xгбгSіAHKJІ%тŒƒШ6#}ЩiIi:§L?ЉчoКЯ3xФ№Ю;ыДrSыsgOJ™‰™:б glжЃ —-џh–›ОіцтsWчЎюе?ё‰IйфY[™іЊaW3д-}jМsч"“іР zЋuСsГд|ВічО№їџžv_JжЄ'юсŽІ v0 Ияži3g'їO\ГvuювХLŸ ˜& jGЌЧ№tТTdЈ–нєр|ќЖ'­H=ЖМњjЧвФ'&ї+Цjоtврƒ ­РuЕWjя7/eќ‹йlЙlzo‚}ъІЦ‚>ъCЕŠю”QS@{P\oтєwзВЂеŸWKдЄˆьщг>иЕЛ%˜A \ ”——Џ8яё+^FlЎˆэW]Zxѕћo›FЎƒМ@ 4 аКTAW шƒˆCяšA"*§"„Fчз†ш7ƒ&€@ %@WpшjE}c=нs@+э-4 „  РD Œ3-TPМa-dsiYб†,FЃ%;Ћvўј‡-€@РвzGw   HmшУ6x€€€ДP˜‘ЗаCи    Bо   -”–ж[шР!l ДС|€€Д\ИFоrЧ‘ƒ€€]#Ї_‰Р@@@ epќfB@ЃЇ‚ЌЌtўДQ@}У€ёёёєћ~ @ЈјЛнЄ*žљp&ј‚€€WŠ>(Ъ’ЁЧЄpw!ЉЁ–ыaА'a єТа\<-}PнИ‹.ь$&PK?$Џя­#sXfсОBђмЕLAYZ'‘-ЂhFМu4#}tнb D4\ ќдYЌтС:ChБЄ8€€GєОЁѓ­CЇšЧЁ-Ÿ@DёЧƒ“EЭЩSюK9њЃњS(;WЖtёвЊяЊМВвяš ~Рœмx0m­кх Cјdy§кѕ3ІЯ@o­<ђTђё 4QЩeѓf$№~йіЎф”iгЇEЗ‹жŠКККьЩйšC§ѕзI}џЉŸ4™LЏОіjiiiћ_DMШžš‘Ўы–]mbи   аzщ›нДжеi6LЯ­лv †М5yYo}kыШGFzTгЉ№c§С>{бŸ љЂyжѓГ† BїпцНњкЉЯOщЬj   R!ЗMѕiЖЯžд›$;„шбгrІ=zДЁЁaјˆсє—)‹-Ѓэ-І‹Іc%ЧF-†ЫМё‚ ьмН“є=0hХ++xЕЗомHžЉ}бЫ‹Eџвz§r"љkW ЪDЯќЕљЬ–іюл™5vxЪ@›Z„ wх {Ÿр–­&<5!555вi4g=7Ын-Ÿ)d{з;^G3_Ўx€ˆ‚VШuуl™>0}я{™ХоТНУЃvjyѕ/ЏN™4E*КLСM8uњдж7ЗюмЕГіrэЦ77J{пкіжЙ}Aэ4йЅЉџk›^ЃіЃЧŽJ%aуІе5Е;ЗяЄguM5Г%SŸŸлАqЋt)]б•д‹žП ћч?kkkХГєA‹–, Ц'єDM)§SфЯf еGЯfщ‚€Gm vэєЈ КђЗ>/%%‘œ3|зŽ]Ќ—]{w=4њ!к,;Ufљ?KъяRй.EfібЖЧД?Nћшр>Igџо§гўј<ЭћiВ›=)ћаG‡фЖиG&r[вœ6YlзяJю\O‚WЎ^ЙPuaЧЖ…{ФГхk–Ы§ Z-щ„›O_оТя Њ|нuзЁ–•0œћL ‚юZЯ-Ъѕй^ЭP~G)kЁSlВjћЫЖ)Щ)ГЇЯІі„уnJИЉфШ‘Дддт#GњіюпСH:ЋзЎžѓьfШЗNуЂ2=тo4V™ЏHjUцЊ‘ЃЙ+ы3gBее+d"ЗЅcч-xЎ$[щ/sЋ?СЖmлЮš<Э`[{ S‡ЬQ™Ь я2ДtќЛНJMДНc’hОЩTЫўљgГЩдф=ЃCа"@WЂ‚ѓ;vД”žр^ŽЮГ~ŸѕЦІѕiПK§ыіwІЯ~AZKџз—џzjвS^ЯŠЖfГйјkБ›П3w5vlЛЛnйИfфЬм)8"щкОƒ‹m{Л­Јща!QЫ•гЉгD1HХoOИ]. ’щ‰ы—ї Z йK€^P‰ЩЪЏ§Іg‚ZоєЬбЃGВG = ЂWЗkОEОK „­ўauсюЂЈ_Ф&м” uRzЂ”ѕ–˜œШoВvђђ7Ь~aЖMШ:h”д5ншО0w9Эјщ&ВЪo*ЗМГeСМ+{‡[žŸїчўLэ$а&Ж3HMW—тfТч^ХіHўЋЏх<CzЏ­ЭKП/sтД…­†Нv^>jЏ§fС‚Zо,ибЉˆцКF.щбЌG.Yј—Е‘явnщsgЯ1уЦдџ_}цщ“&N’”ї˜А]ШЮЩОњ]еПљЭ3уŸ‘;!хќWђiA›veЮdЖnšz\Й™(nЪЄzЊ1KЗмзззЇ HY№;еPt€F €ZУ€ Ў+9Y2zСж”ёK,fГхВщН ійАCС§?ўŒєAьF0їн‚ * Ы4D(œVЫ•б Œ€ўŸ1ЅKQ…Лvх‹)Y4œ@ЗЙQёцDзЫн€`3 ЪЫЫЮWœїxlи\л1ЎКД№ъїпFєKь'[вН‹“цИХ%l€Д8tUЎхМu`^отŽЏp Иљ?GЎd‘€@№h}yd№z•yІZŽЯЄЩЈ ЁЉ чfЗІЮ§€@“ uѕ&э€:РђјјјЂ}…t™\НSьжFЋЕСЊАCжDпиHo5Вц 7P§fЫёђ уFњОїK[ŒjЙО  N:п:ЈŠKo5NЫрKвнmR-ЧђрѓFz ОŸ,-ЉЌЌєxЧоЁ 2вчf›В–KU\@ љ ОKUМsќЮŸЖ^wA@ рF|Œjy“r~dLЪ›Пv!Ž@АюZ—^Здеrќ€ ‡x€`rЉ~ёЯ??ыUїgФз|7е[+ЏК€2€@А а[cž:ѕ™;‚@XЭyBXЂFR-‚@А Йк+fУєќЏ[жY„з7zўЌљВ%i›6— e$}дџ ”3e?њМѕі˜іŒо№ZY‡ы’ян–м?Nй#ZA\ №ѓз=ижH X…\ћ•і}Еѕ™ЉEщqПњ•ЁіЪTњЫиѓ-}ю4’ЮВхelЏ\˜З ‰<аЄі­З3…џtю_Й:MjЇЉЛбП4o––hГ];У[[бк=I M٘цЭIт—фЎœнЈHz\М(uЩKGо~чќЕkжЪЏk{ŸМWЁ‰fp% 6OpеТДС*ф:_iпo-и]‘=Й7у=-ЇїЖэдN-+VІ-Zx„ъл+юK‹ПхЗ›ўЋћКЮFУк•i’Т’ЅiI}w$mыаy]э5!o•и.]—fЬДЙ|EZч_Gгк=ууЃ—/ПЧFz$'{%n’є]9=џзH0c@|чЮ‘ДЈNg!т…юlЦГ_h€@+& =OhХ`z+%ЌBЎ§JЃ+пY›qфА‰ЈЏЫ/™šdŸLџЇ№иIЙЋХЕєŠ7vˆмќК‡Kк9гŠhњKOFДŸL|ЂїІб4їZ­uЦsEЃVјmжQЃ˜-)њНѓdbъCщˆауJ~ьшI0К}dќЭ1Нш,фПЄ r?hа9OЂТ’@рПFТDЏ4ХZ.­o7\ŠWŒ}R\L>uКЖќœљбЌoo=?a\’вJ*РдОцхŒЩгŠŸ ЕЋ§%ліЮŸSЊ4й}’­W|њ$3ўT,­=а…†_˜Тћ   F€о[j*еvЂZ`rХ*NtЅѕj7ЬkўЇфХљЉTШГ'ї›–c/о =Ѓ?:8ŠiRTДЅ[ЦЄz|ы-1цЋ ’ОљRCђ=лјzЬќ0tm™‚~WМ‰bŠ –•›yCШ : а<С,.чс жвКWk_яя­ŒŽ6<7+Щz­сјЇіђF‘=)PХIэљЋ2h›ž$ќЭ~[ншОщѕŒ[{ФаŠ=}Ф‹Ў@‹ЙК> *ђѓЖyДщКпОЅЧ•Ђ!ржЗЪWП’A—ЦщI (Рћ  @дц €­“@›ККК`dюэ+-эЩмхЉ/лЎŽ{Я?>Љќъѓ‰Д.][g§‚§ƒjѓ”œјЄђ№пЧ§|эйэ[3ЗПЋP#gЯ*Ў1[џ§еz’@›Š§ъqЅhшж(Opэ_ޘώћъЫ‰џўїCЄ№ЬгžЏ#ИљФ&ДN^ЭZ'"dнЊ\ЗvѕЪмЂoSЦ/Б˜Э–ЫІї&(мЦЁ*ШHЭ7ђ2)аOŸуођЖ–ѓN ƒ€€šЪбв[†v@K$P^^vОтМЧ_БЙ"Жc\uiсеяПmуQл7ЈтОqƒ€€G˜‘{D…VE $Ў‘З*тH@РO˜'ј цaF X…ЏД0;P„ЬШCg,I(V!—^iј  '€yB(Ф:"ш†‘рD3їчŸEЧј  '€Ÿ Юћ6МЖHmz$єh‘#hњB˜egZ.‡N:yќЩв“}ћѕѕжЪЋ.    MI Эs|Ў)ћkоО^\ќтŠ—W\КtЉyУ@я   (mЌZ?nи ˜щбѓжž9Sr<~Љ\ХWуžзэ7нњіщ[№nџСœ=}6§Оtџ§Иy ЄЄG~t&HV‹n<Б    Ÿ@АюZW‹€fУєјє“O УГГžUSЃv“Щ4~lжјБуЯŸ=џСўNœ8ЁЁЌsзѕ? Сњ™{њ” VЎ^9сI?дІ3;Ј€ДBM]Ш%ФбэЃч-˜wшЃC4эљлžќд\œЁкZrWхЮxaNњрєШШHуЦмхЙŠУГљЕЭЄOГі™Гg N•UЙЋШsЗјn9гrЎ‰ПŠ&Э›ЅIГЈз(ЬŸ;Гч­нш9ю|fK ›_п,Ю’oДЯГхЎœнЈHz$SггG?šђќ€Љ G4ƒ€x"а<…œEEпй>jјЈ‚П9—Э ўЖmфяЧQћБтCц3-ЊS‘жX‡?~тјЧХŸž)9cЉЉ^Еf•фy]ўКSЇOўћсѓ_œЇЉџ’KЈцЪв_Ix)їЅъЊъO?9CЯ Uh“EuњЬщ}|щЂЈЏшŠiz4$лE/Ю™3oNА < –K №S3Oгю%‹–Є/WOš8iѓЦuі qЃАљЗ'N˜HэUц+пV~ћёсЯќѓ cšС+КрЯ hњKЯ‹—ОНуmIчэw6/]ВдиЩй.rоьyћї:O˜“];v‘‰dЛtёв]яюbЛцЭЧ~F+fШ= 9zЄКж2lш0f@@М%ф+ЦВpЄѕээлR_ЕLœ@ЧuЛщЖліиG%ўо•t-ЄS{‡_Ж7Ч^PЉŠпqзљyљ2B\\œдwcмеяЊ$љbeUbrЂSY)Ы*s•Ђ-YбГеуŠ)“ ?СНјЪв—y[Ш   р-Ѕч­oєЅem7‹ьIйyk^ІBўцkы—ОМFк{ћэ\%„(7Ч&н'еcгESћ_w•šI8БџО;дџЛЛКиэЖN ›ЄЧoЂ?СђгхЪlщ @б–)@9fОF.”š’jБXЗmнfИ!6ЁЇ§бГЭZВt ­Qл—Љ‡fЪЃЇ–E I:$<њШHI‡юŸ;ѓYЊгДbOŸaЃћнфЖ#ЧŒmЏжбsЮќ9Д)зЁ=Ў љFХЉlГ)“Ь›@=Ј§sфzт˜ќєфЯЯШžœЭ”G=2Њ[зЮwїП›е­V+]SgЛxсžф{~gг‰‰}vц\iз”gІєIО'ыїwЛЙгф)“Ь›Hђs3ž‹э{wвєьвЙ mЪuЈE+ECЗFy‚n и\WkЎЙcќ’”ёK,fГхВщН і Бš/њ‘•ŒєAь^0Й)Œ9кшИt-W@ €јI€~4EzЋёгЬA д”——Џ8OeT;А›+b;ЦU—^§ўл6!1зŽ{A@@T„Ф5r•иа    р Й@и   ЁL  ћjвPŽБ€€(ќчШуууqŠ"k4‚ŠНЩа[M МСДh/ф§“ˆНЬZ4 ЪЈŠKo5Ё$bІ!јBNqг ЏБІ?є  аЪ аЭnтO|т   а рfЗ–8jˆ@@ьк`>Žc@@Z.|ŽМхŽ"…€€Д`mЌз№mы-xќ:€€@+'аfчn|рЛ•H@@ h3њП•ж‚“Cш   юp<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ьДrIDATысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5ђА^$  юPШУ}„‘€€@X@!ысEr  сN…<мGљ€„5џлИ?€ІKIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/24.png0000644000175000017500000025304411733011756026242 0ustar sylvestresylvestre‰PNG  IHDR;НН;џ”РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь \UћјOщГ‹и Ш+(˜оBCХKІцНTЪЭS5C#o•Jцн ЈзŸšQZЉрkŠ—МоM…д oKˆ.…АХeіѓЎŸўЯьй= Л3ЫюВ Лы3ЬgyцЬ9Яyžя™™}іœ338x€р‚@H $рР+-ОяРцЁiH $€@Ф+S#$€@H G&№џй8Д $€@H`Ф†‡@H $€FlŽоBh@H $€м„rЎчe\ЪІиVюбЅGpћ ѕRЉ И‰@H G&PБбШiо;ѓьgnќџХƒraаV/•кЯAдŒ@H {ЈŠи w Т5NЭйЃЊsтИ1лvьFlѕRЉ§DЭH $€АœЧfЊЈ $€@Ж$€›-iЂ.$€@H иƒ@еЈЈ^{ ЃЂЇЮЩЩS(rKUœ\Nќќлш‹[їП†JŸЯ7жћ[J-+5V‰)H $€pDЦ›)+ГГr~Lћ‰hШэћїJJKНЩНнQмlE,гdЊб}>1ЁТєтЕ™ТM”‘@H $рТŒт,ЄГщg3Џd_iњяІYПdqeЅЏЉoЏ>žžžœFћž+щ‚’йKЫ>д–ДДЋ$€@H 8ЃˆMТњLmИцххuђмYТq1гоъLѓЪнd…ь Бš†TbЌfДЈ $€pX†›ш„ВЬЬЬ ш]ѓђ:|њdЩ%НCЛ…‹цДЮOsUiУ5ˆиˆЖ€ЙЅЌГЩŒR99йуЇМйІu›НпэЪм­н•sс‚AЛ rжЭІEюˆšФ|t4зD­5HЕY4б  E›ц@ЖHa§fх#šX—vš™Щ kшоАu џ€ў'FL”Щф,нL)dgM4S!fCH Јљ^б^'OŸМwЋАУгO 5Ї 5PfзM}яZ%G“:Џ]ЬЕŸ~цп1pР@БЮ—цbю8f ф:hы WTVфќzcэЦФqoŒSЉTu`'VАˆ€a›AaˆЬ~ќёЧІЭ›žќщф­[…­‚ZѕъкыОђ>\б|хО™эЛ ƒЁаЋlЕЗ)Аoefi?~т8фызЗŸYЙ>“Eю;о32а"ШdЗS™bdv$ч§–Зdхъœ_rnм,јjг—ѓцЮw*ЇбX$€\Ÿ€ЉˆM]ЎNKOƒ›@Ož9{+ПАCЇНzєъгЇмSОmЫЖ1сcрЖƒ:#Є з oя!iжˆфдYХхч+nмМсуы#|…ƒD^'HЖ­;ь[а <ЏCm Й ЗЌЊњm}Ћ!=єёGK† оO;c“ˆ­~QXжl˜ ‡' БСмЕџ —Ыя§YRxя^ЋV­š5mЦЉJхФЯЧ/jвФMv к2ч7 ђ2 w^;}MЭ‡rф)x[кй40qPПA†жf3хћ‡ОuыVё_Х> ЖjеКKшs/щ№TS›yсќŽнћЎ]ЙјрAБћП|:vl5nєы}žяЫ2ЇЮє ЈРпПХшQ"^#Ш”›ŸhЁ6‘6ЊВъППџ„QЃУ_У, B=,н ГАlЪwЛ’w&пЃЧђ˜6‚ЙХTвфЪjјЉЇRї}фъеЋ•щNК‘УG 4XLGЕ4Ё;Т™YйћіьИ”}эСƒїЧvэкmмkур~ѓ­™јчХЬŠk,+Ђ.чњО8ЦmсїѓЁЛ™, H < $#Ж+—Ў4mйђњЏзo§~цЎ;NгqнфЛОл5fТФЊ mфO[іДAИжЉeтхCˆ;ЧƒVЪљѓ]jаЛІ з tkкˆoіT8!щ‡НёФЩŸAuП~6_ЛnЫЖ-ЬмтП*Š/чd^ЮIќ*‘[ё q[ўћЫSё 8-жЬIЏПfм%П6nЫЖЊЬЌ”Ј`swDkDQЋЬё ц вˆ 1C#ЖŽџDkFlА‹І'f\<ЫŒяМ XП;іУ­пnГт›ЯœfbеfA~HЂпvVїИAЁ[Зц~СU–nZAЄ’7п 7ŒгzЁ!–Ц­Йc‰UЕ‰ ‚м„Ў9h3 В>шŸЃ{ћЕ`Y-]ЖџР~ЖЩNК—УЮЎќh1K7_0Р Чф'г`…г|FдБэоГ[Б8–Ъ‡k„єэгзŠƒж|л0'@ŽLРшЮ~ЂПішоуњхЌ{Ппsw“ЛЛЙЗjя6вџeU*•^кžЖ]ћvхпЪЯЙ^DKе№)EB_)э]уJџрюќЊИё`HъкчOnэvрcО з8т/'pэютЙpƒjшьЂОQљy№BНAЊвZЄУ4ОЬЫ™аaг'ДS-дT+z№ћ]tћгјеЮœ†ѕаЎн-x?јнSTMЅсZpЛ6аЯ”“qсјсCCњѓНkžz,Еš:Bўpьѓџ| zр›€Х|yшІю@чё*Њм би*3§ъї\Њ*ыrŽ?ЦGъn„Д л%œ\XRЦF`N?ўўьШ qЂ >ІХЭљЌБ™Є”˜ 9%e зкДnБћП|+Уч™ѓgЄдђщfќ\Б‚qU4\kгЎM•UYMYU}ŸE@б3YсјЯЩ83k:е”Мswu•"[fB)IЬcћ`щКk`поT€ўTЎAЏ-sdи щА—f3џ“?кЕПЃ|ћа3|мўЭзC%№Уƒžяw вЯgjїьнCхЩЏc‰( $№Ј0Šиє‚ƒƒ'П1йллИх#!этыяћђр—З%oSѓAлФ IћаЈ•Ѕ)GЁЌЖKшГэ'ЎZД+шЃ]}–ЧЏŸ aiјjЇ†/uтŸш}nзеШ—†zЗі#•фУЩ~Au>Hšгћ4фљчŸ' ,~ @ŒšњјAo&ЌOBЇТіoПЁEіЄlЇТ’–ёL ˆЏЏптиhтStзtІљтх0ZjЮs ьъГ‡ ЦV™щWpp'˜5J.^ф…œЌьтХЁЯУ  3Б]“ VЏŒР 2РЬЫ8bЕЫЅѓ—Ј`нЇT3Ii3ђž#‡Љ†…,ƒ™UаЪ№Й№ƒ…RjЭLЗ‚Hщ­ZіўBfеВЙXe‘р(‡уЮЏ‰сКі*TмЈбY3! ѕАЃ_ЗРЎ6-ІFMЃyіаVЫ>8ЎoЖWЈаДЬŽіх  ~a0z6УБ |hС“ЇPaпnн3ƒђo+t†ЕnCћ’MW{‘pUІ~žCа3-&яf^їюн…ПуiаЖ+yл˜зЦь* ‚ЉЛvѕ3&p9с#uBжёRC\X^JTJmuђСЊ˜АРЕ{ГіяD4Ўё}iЯ6'%AЮk•ƒк+GДRB9ё№$nž.uђ8_И|Б_ымЌVJп#^CGEсoќЃЁZћwxКCП/іщЩЯа‚хjюM*РW „ŸWѓЎ 7A6ПџЯ wLwкX"м4ЖЪ|П`жрwЛОƒј FЏ~Hћд>зg|ТиёO'~№ѓѓ„]Аi0ЙІdљс№ем[0 ЉBџУВЬU‚s–›IJ‰™oодЕrhЇ ІЊS‡NLЖNА‚q1Ћ‚;TY,ААFЋ,2ДwвЙ,ѓа§(ЖTufB-^ѕ<ЖqYЅ7ѕ'аY&ГНЂ EйбоН—юМ6Шжч…Оа‡уЮ?ІЇ)с—ЦўУК1й у'dЦM$€)њxAТщ іAАя„ ­{—О3NЕт{=ј…mЩŒJSЌјф_žНVnr"уEM*ЭК!K;™н04"ЖŽM‰'ьyHЖяWћйГž—ЙQЗ)Ш›M)ЋШО_К$—Шl9ЕЮРЕš;}њ4Ф”Rз\a~Ÿ5„8HRТю.˜JLГA*Ь‹™еЎmЛ#?№œ!ђШљхЌпэн?}ЪЄ™бГ„:EeИЗР0нМў?‹м1ЌТŠmѓЌbŠ…~ѕыз"6и•}ќФ1њvя Бv9xќаЃЅ„“ зУ4РЏ™6Ё`N ЬOeыšЩ*ШКHъхgjšЙ<Щg1SmTe•HMIzHш’NЖ 2БњЗ‡Д!Ен9qТ‚%Kсз) МFMžšђ§AаŠАkОзЁЖucy$€˜€љ_†NЈ8љеЄtб‡эаѕД=ЬŒmeаІ.-Vь]—*кЅ'‡SНžќШ‹Œu[Wœ™зА}а€rзŽžP”мWmК//CбЉ] ЌyGўЦ„тТьtzЖ]У5pі|жy˜к-дœ‡›Д ъXЌНљ+;+;Tп[JВsјQюдT§ШЩжWТќЕ‡ jUŽ„UТЊЉ\{ŒuЇ˜йИЌTJ•уйyС!Кц`ŽЗnлZЊ T:;кЯŸ=нiЂйFМЖсЋЭ0•mїю”Рж-iЯ1Œь ђ‰ФD$€\›€ё<6˜:fжтЂКњmњ-ЙSLEDЁт{кжэѕм” ГрE•HСдeˆј((j}аЬѕAoёЋпЋ Ш§_ƒЧEm}+ЗEyXSU Щ8Џ<“Љ^иnЇ"ЙS›&аЕІЮ§IuхDіх_C‡–љД2ЊZЊR+гњщ”жŸЋq5bЭГ8n?зъ!+АIгGEИБFŽјЛеBŸŠюЎа-zсѕqКСаw~ясШ2РTk˜бOZ1N_РВџЙc™jѓr›я|cёs Йёы јьн[7=Мw?^ w’L.ЌдTR+фrO ZTЈ\ЖbMБюГЦfUk>фQaКfѕšUљЗѓр`€ёЋ>П'б?А ­nлŽ]žХ КуJhFэ!ŒzIЏY•G­К'Z—А^&зоІЪ„`>dJ vzUwz‚Га|sІлkPЪФ&;п?\Е2ѕT?фŸJГшCСЄР$ђ ~Д ЈxхЊx^›;fЌ ЕИ G€>АЪзишNdэљ›вI” ЇmoŸ1ЏN“6s’ј/HSU•—ЊaОŒŠКСэpЛШ0]м/4D]ЊXфчхEvЅ*чO&a­žRь%Aя| {‰FaчїпЪ=›qš[ІєлbпБŸЮ€ИЭоe#F„Н’ЕяўEС›Sп4(ђђЋ/гN5H‡Лњщ§yТGOЄ)№ќЇщS~Mќf єСР\7ƒlVoZфŽеŘ(h‘_§ћѕџ1ѕGЊэ…оНtB^@˜ЪAXз˜WТш­yoЯ|›ІПіъЫТ –Ъ56“ЈBѓ!‡sјд И1о˜4|Œ.FmЬk7nŠ<ЈŠOй€зЎ[ +№œЮ ЭЈ=„№№1‡OžпAљhЁUкаYX—Ј\{Dе$šй  ‰Э№WТВ.ŸнрGоёъѓG_{іš(+К .Пцў 7wCЯэDgйV.ЏŠЖУF„­OмyhлўCш­3,3 H <‚Œ"6dБd‰ю^Йіќ1Б pi3#Э kјaPэЂц8шс#6зР4t‹,ВПтђMyЪљ `.zИJuуїб{ АуяF€ЅR]|OІзІMБёtnС<уРќqЩ•‹Пия…}‡Ž^ЛЦ?0 jмИE‡FQјф[xvР?ў№sцЅ›љ7+**|ўхгЊmЋQC‡С%žљУЃ№мŠяїяЛxщRaбђП їЦ>[З yЖЫCX6ѓ+м1_Йљ9ЭїЋЬз†šц†vЇU№‚>‘Я XцЭœяххЕ{џЁw 7o1zи№ЈШЉ0;PХ2бœf2аhффыџ|Vѕ]эУcЧŒЃјиЌGZ<УюЧйНswснџц-&Œ)Т'ібl6€а€l\ћйЖ$§s}ѕДЅVјkМiŒ•VOБ rѕВІЗV~Дъ…о§ївN0…G[k[mцtE5УЃaЊхОяї‰€gж и{ўLўЅjИ $€€€-#6PЗqљр \нЄ&QƒО[“Іœ8КкLpга‡W˜ФF—цŸLб“мдзjwА @6$`уˆ ,лИ"ьЋЄ‡’1až…kPV}­Ъ7xtйЕАЉR^‡Muщ б<ррU`ВQe‚gy/™мKћ6Оœђ№zyѕлЊДЁ„@H Ї%`ћˆ ^/3uRидIЕFc Сcx-СUЊјЙlкHNu7K•}ˆћ3‹/BЃ'e~ў№] зЊHЁ„@H ИЃˆэa}8gYЅrвa ПъТLr“У“S-гSžbH $€АœРџГМ–@H $€ЈSUOа…wлe\ژ8N;iрёЙ=КєођV/•кЧ9дŠ@H {ЈŠи ?йЋ*B Т5ZQНTj?Q3@H $€lN ZФfsэЈ $€@H іp[эЂ$€@H и—Flіх‹к‘@H $P{Беž!j@H $€€} `Фf_ОЈ $€@Е'€[эЂ$€@H и—@Еwd^8ЏP(ь[!jGH $€А„@```UФFУЕЖAm-б€y‘@H $€ьK 7/З*bƒо5з8BЎd_БoЕuЋНsЇЮPЁ‹9UЗ­Љ Б[C­жeœЛ“šmusЙЖП.уУ:тА†™FИ€ ц;k“œ@l№ !UU ‘ЭМЗg7ЙMъЈ%.ўѓѕ`†K9UџXkВБзDШ.ћЛ“šmuКЖП.уУ:тА†™FИ€ ц;k“œZbA‚Qб*ЕnrN}mЎА( •:7\Ш)ЧoФ^/mфЄидlЋ›иЕ§uяж‡5Ьќ3Т\0пY›фdФ№^Q›№D%H $€А#ŒиьU#$€@HР&0bГ FT‚@H ;0Мѓ@WеC;VYoЊ]вЉzЃivХˆнlTЖЬшЄиэlvvVvЬ1Š‚п~§Э–Д­жeg­ЖЫ6]Ц;‡uФa 3џrЬwЖж9Б­жQA}xКнг61СVzlbŒƒ+qRV'|М,v™Ѓ„kfЗБ=hлCЇйY–бСMupѓЬgэ2Ž˜яВгх|#6ЎŒ‹Oˆя?Дчgžюљ\ЯЙГЃ333ЎхœЮ`И№+0яоyTјЈѕжЋT*ыМ0ИВX§l+=жyQ7ЅьtД[ЭмLЏ šЦИTŒ‹@ЪеЋWћєъ#КЋ~С~•8;lBл€˜MtZ-)9 „ЯKеЛЉЂъкˆЖ”ўrж=IQѓђoхGЯŠюмН3Ќ РІh6aЂЃqЮЯЯŸ;.|)wщ<~мЈдSЉBkM6 W7ц=Š№ј’_яИђЫo?љсХс#Пјђ‹КС§ˆз—Жп~љэTZЦЧЋ>ц8nфЈ‘JЅўё+8ЛЙGЛmEe‘˜ "ЬV/ВЫŸЩ[7ЏŽ]М5Й^№жОRОД+ЈЪЕз\{ ЪЛЪБ“Чіи?уDЌ Р&$ж^siШП›?)blЏНрKљJц•/9zшhею,IEl№<6зX… ЁѓшєЙчХЬђkю >zzЪъГљЋ :5мŠ•Ба +„.ПjЃщ* lјЩЇќvфsТcют{іэйѓЙЮIЩ›t: З~ŸПц.˜ЫqаБTЅЪEeьк$оqЙœЬ›;sєибыжТˆRЪ<›>*ќЅЮ!OCŸш})™ўВOa+P%’’’Тїž†< нxyyй4]y7?zЖізgќњŒTЉрBfJДЃдa ЊŸжтŸ"иMэG&`деэž†у–+Ћ:bЁ[”І0јЖ8цEЬfG‹h›jk'№YeFОО”‰зЉCPBмJS‡hЭРСгкД‹ЖИсзŠ1Нš\Ў:`ЌЪЉkt‰ˆMCˆkЌТc[яQЗn}W,]–•УŸtњD*ФЏ]я~ЩG~„ѕ^СНѕkзы2€aNЖIHж/YћvюјэrdXŸИщіыпяњўд‘Дћїяг"›7]џ…OЬHOswsOXWM•P­ЫШbиљДъŽёђ™ŸЮ˜І4ы§љГпšsхlЮŽЏЗ\Йr2џіKh‚O^  ™fBЮ^<ЛoыŽŒє УXВx Э0#zњфё“ЏЄedœJ{ЊхSqbZ‰У@TПЮŒъоеC"XПш1qДK™ьЈў%gФа)Лw1_Єь e„\.уЋбVaƒc^o2гЩk†…К жІЦЧ@ЭО\ж0‚#GєЈ€Jmр‘ОЮƒM­sКЖ‹љЋOž|fšЮšF{С‘ђкиcbLЇv^Џ~бћЦяиОcЪИё М>ўлэ;™њ4U`ГЇJа;Сџ7ШiТ6сX=sілЏЗ№зŸ—FOŒŒ:ѕгйoПLдnƒN#ЊGЊе k1Ј”mђщ}"\HУ^ j€Mvu…мg/d§АїћДc?–ќY3R Ї  уЋДаYo>џŸЙpцLXџСlS(˜:DЭЮЛoF6Щv1я$4иіВž˜xФVЫhаqŠынфџ3Ћ>џДiгfK–.юмЋGџс/ХЏW•ЋщоC‡Н?џ}љžžя/јhїсC4]XRи&яНћdІйvяй Ѕ<}<‰‡lfЬ<š˜МцИљ IDATgwЬќїљDЙlжЛГўpІЛ№Ї–юƒЙЩ БOпгM)JюЛ+ўT*U*O?пy‹bifUl„Х,–iQ™0ёъ/94џі”НС!С ‡yШІNŸuьЬгzLЂњЉЖzџїйТŒ1qДK1%ьЈћњиЭл“9ієбЭ;“ЧŽ{”УBЋЈ§1ЏUІћ`f3§ ˆ2ghs|š ВдQQ{˜Ђ‚ЮUэ?–СРHžl/Ќi ”зЂ.0%ДRЖiлЃдВ…y—_XtёЪХС/Ž€јRшоz4•™'*0/@0Ш`Т6Ax/v1\ЉрR?цЕ1UМїС{lѓъхLЊGЊе j‘к„ZиТђ<(f_C46<а]]!еїкќїwяЏс{ЭвCBє*Эl3˜§ АН`­ l— {ЬؓMЊ] И9— f­=FЬQчt0э ؘГa Œ’eЏП/­гззїВ ЦњљPLП№Х}uХѕiфСн‚сУ†ГM‡FSea]IEХEћакЄ(­§ЯкФ/зџпzя'мч,XичљІCуR…2ЙЌ~Нi—œœœЯўя3˜uзP>ЁІЃоФa ЊŸжт˜Ÿ&Žv)цр;Њ:Е‚)Рƒ †Я.]КјТ’`Љƒcоццј"АšЅŽŠ:№ШРбMсй!ЬРšЅМuAЈD(зСбОsзЮтЂтрgƒYН;їюœЉН;šЉЬBыOOнз\@ƒp“]ŽЄZЭКi)ŸЦ>0cAxlР&ЛКB‹Оз,=$,НJ‹zъnфЫfТ!aШ/мdР в 6Y6эbЮ%ˆYkWЁІя.ЛVюЪс iўмљ}ћtЃЖД№kQTXDюЂЂЂЦ~-hzC7Ђцдє$4q‡#_МHWœ9J~мОCx.Б]ИАпўоЯѕІЄ(ЕJј,ђdžЭ\Мhў‘ЇЌ€іоМїцЬŸгЗW_8ёдхъn=tЭ-ЅJъ0Ъя,щGЛswЦŸМqУFˆиў›єп~`АзAŽy3}/uT8ˆGТГChЖP–ђZдaAЁlїЃ]CRОO9~ќ8‹ѕс;6bьЬщ3сЗ“c™*фb7YЊеjSaяоН=1!‚)Э.НuWWH§^c™ K ›\ЅС…дcЉсЏ…›–кcЌСœ{Д‹9ѕZ”G|TдіЃАњБъКж,„ЁЗ!zъ›щЧRUХ*0Žуuжu|6”akтжР.X—Ў^ЪїiKЕ~&x[ђ6јВW)UŸР,(XЈ6&h7GП<JAЕJН>!žц™0vТВ%ЫŠђ‹ џ7?/б‚EКВz{\pS ;ƒѓЎч™65Ц4%РХпІЭIЅžЖOу†|"ЈOgUшvщг+++хnrY4їВЫX6)=R‡+h ПЪfRНМ}њEo€‰Ѓ]ђШњт „†„re%)пЅИЛЛЕ 2№нЧМоdў?Ћ—ЩL Лє›mgІ/PšU!uTиР#ц…ЈРЁ_XHаЪЂgŸ›цd‚vSЪkQ ˆ16>кyНњEkdъбƒ];wѕѕёeфa ЂkЧŽЉGS!Ѕ>MЅHЅ>ѕN№џ ђЄАM&аќ›R­fX‹AЅlдВEŸ8}ЪєM›7L9ЧЌї„Э§еВГя5иїš­ бЋД)w˜§ ш]k7'ЎЫсл.јy9y‹цЯЅ{­)=R‡U9\GЛscЦGD.XВры_яЊЏcо эЬї…Й yTдгYlть`6R^‹6Š1ІЪоGћ7;ЖЯ~k6ЋŽ #_їЭП8иЁL50вN›R­V›ъ ћ|ы[зЌ[Гќгх Ї[зn[Пј’„BJШГ!№ХTљweиˆЊя5[ЂWiKнk7m]ЛqmќЇЫ+++:Ж ž2yUbяC”жbiЛHбГдq‹ђ?v_Ё Rvяjд6#ћЪМwц•ЊJ-втА™asзО]`ž+9хАД™aˆЁЈKСIБ;ЉйVЗЌkћы2о9Ќ#V?ЬќqkѕQmQA+\АHПыeІФрўq‰QQзѓ=BH $€€гU;­G& wIЇLјы Л{Н4„“bwRГ­nbзізeМsXGЬ7ЬќœVЬжtXУЌsЧОЅ$"6˜Cчz‹K:хјЭ„иыЅœЛ“šmuЛЖП.уУ:bža9.№ГрsqXУ—xФц’AЏK:хU5Ѓ{5uЕсЄидlЋ[еЕ§uяж‡5Ьќ3Т\0пйкчФylЕgˆ@H $`_Бй—/jGH $€@э ˆŒŠ*‹•\9<БдЙ‡œКсJN9~У іzi#'ХюЄf[нФЎэЏЫxчАŽ8ЌaцŸ.р‚љЮк$'#fј<6ˆдЎd_БIЂЄsЇЮ`‰‹9х lM˜иMРБп.'ХюЄf[нŽЎэЏЫxчАŽ8ЌaцŸ.р‚љЮк$' 4Œи aЕvxѕеeБ @H $€€8ZdTT<Ћ6ѕиЧ d"МжФоњкЁЄcV_@ъІ^Ф^7œ jqRьNjЖ|ѓ7]л_—ёЮaqXУ№0Ÿ€Ѕ9ѓrr,ЛѓРtИfiѕ˜ $€@HР6юc3ЇJЬƒ@uЁ2ярСв+—еЅї8ŽШнˆgЗ^&EШ|§5і№7jњќ ѓnЇЎИКO>ТXи”gPiоЄЧ Rшf*!{4dЃ 4кђhNLЌ{‚f1ЃrGюcKˆKиДy85wў\3МС,H 81„uюм‰[cјUфФ.т; гиўЂЁЦ‰Ю•’ш ђчŸфтп9r/Ђ)хўЎфіь>АeSЇeЫƒF…;—;Žf-„k#_ЪнZ †ХЬxƒЛѕ.яЭ›ХнšТЇL}2mž§FЫ}šёО”—Ў„hИteсћПўњo7ЯК NЊŒ,>.ŽAРВˆ­ЦylѕхTЪЮЄГЇOœJ;DO}3%00|ЌШ% §ѓ•йћО"мŸryCЎфђDNC:‡M4п!.њОООEEEѕХыEЮE@о оьЕыЉќVh%МКЎЭ2оСkEb8s<ЗЋ‘ЦHVЇ!97€+~џnJJ9NSJH%—=N<Нн§мнѓ~˜џУбA‰ќяm\Ќ&имOеј›NЫy*пэЁqа‹)—ћќ‚ŒSЉDеЪ›?Ѕ,nЊц8Ў\Ю•ЩѓўМНрўяAЃЩƒCФ+а›4’wŒиDбežЫœѕFAQqe[Б9lлŽяўћў‚%~коuжФ­ивОŠѕ’?wB*ШœІ‚ќ]Ў8w‡ˆии‘!yэc9P@.JрБ тƒ5ЦюЦw‹/)+1NЗaJНœ‰rК„4”ёя‚Дь mCзmІ*o{’Ќёt“Ћ5\•;рЌџу?;ј+ЮЫљ,!x6Žд{YъБдRU)WЦ•–BhЬUТ ?RRЦmœVЉО0\ієlт9ЈЊhBAхryшгЁ1Ћњ7ь]ю}МIbя29Ў_ЏЊЬ,е§yКdѕ’ФM[C{ђпuYЛeз‡эcЛzѕjЇрNєˆ6E.˜9бнпƒ>иЋ’dм+|‚Ј5•Є\M<ДПgE‹еyb‡эuцпц/7/XВ`ѕ’е‘г"ыЌRЌШщА‡L3ЋбJг8јr2+ЋX&sЎГѕr&6s#їЪ з@Mфќd/ЉХћЅЪжYКъvОњЎТзЇЉZЭёЈ†“kДAЕрqˆ ј єї?Пa]аk2нœ6№ŽЯтF|ўеАU@ыƒ‡EM‹ђєєЄхъёгqЯІ‡ъС§ыШ4ЩјƒG.‡nВє9]ќ‚:Ш4%ЊуяyŽКTEуж\й§cюй†їЧєѓ iVыŒ&‡ЖBZ "Ж‡UyJ28јыў<Нzљjh7н\…КЌ]њz ж>лЧVќW…LrPќWБ˜љ|кљТrјє|\З_§?"+Q{o‘Ы9Й7\Sќ:†peЅЯ xІOе/B]vќW+›ПйќщЧŸ~ОёsŒиjХбТТNŠ}пш '#Gё',,y[љMКНС'ТyJЛєЩ.ђП™Љфˆ;\›Ю~HZƒWy2U9хЅ|ИAЌAПI—Ч‰Œяislв8owR№ЌЊn6њEЈVЋЗЛRvѕЁџ‘CGќє!О|]џwиГ fјЄ

џђЕГmOwX‰В’(џцПТ­vѓШНtтЪ‰УЅщЩЅiЩЙЛзeяK<0Ѓя†!˜ИjЬŸ;Пe›–]BкУo,ня?mw(ЫKWцУ Пe`ЫˆIЊКiaѓз›Л„vёѕзў‚дљяWЉeЊЬб“Д=щЙ^]Zњ2žЭУЪ:ЌўSКЗЗwФоОо 3;СYc_ТG‡<ЃеКEYЈьв…5Б>џзLРIБCИАlM@д  VЃсj7WпМібЕDѓр9œМќ|/ЖhШ‡‹цЗoзж}Шbv6бŒt“}ВНjр€pBСi•В3E˜™—%NUиї<ЕІ=œщГbfйфm _”e\%Ќа§Є‹WЉ9тŸр‚ёDГТХЊ ижІ%\gЬz$ѕK3a†*Џ^_Дk))+еFl•U–ИСT=9пЯ?_oХЉЌ d2!žЅ‹b5冇>›4мр 35j*Š+—Ч&,_<НХЅ>o5ѓМ[ЈЮЪIПшќо9д•аi9фќА3+я’/ој"аЭЂg§ ЂwЕќvл0ёi|lгs>ЉF1Ah дmбI!zВаъјъѕ ­ЖŒ­…]RёƒаZ(+Œ `SИ—Щ–ElлЧжБcЧьœlъАЩ<4кz“Жо^ю&V №шрбЧ›єѕзџ|œЈ‹pS‚."W],у?хgЬ\ЙxхфЉsg3Юш4о1eњдщЙWssЏхЖoг~ХвX–чђ•Ы',*фя0Hˆ[YђgЩ•ѓWN?wђЬI–‡ &єdddь§ўHnояУТFЭў`6+тАТ–ЏЇDё7.M™4dЁЦОФЬŽљ,с3–'~m|єŒhжЪвQЈ‘€ `‡@Ўрl‘ВHYЈиљп­ЦŽЏŒ[yЏроЙŸЏРzЛр6lчa)Дџ>ЉщгЂЇ-xС›E{wЩȘСrRAъTнАnCжхЌS'NС™“V|ВТ  ›žnФŸкhмf–у3ˆƒ‹еЩДsp…)Й/сГšh(ZDTПЁХъВJд`^B7ЎRДi…JNіw Љ,!џЋweаЇШп ЙDМqќФqКлvcSmx1qфГ ~РlћvлW›ОŠћЯКe+утDgoз=Ђ•,ч–*Џ0ѕВЯ ФыФЃњА2мRVЂиМpшн{я„4нџ зMNј!UNu'  eъbБш›ŽžГкsздzRgДE'…шЩ"4€]@(&уУвЭŒ„Б$єћ ]зŸz№Р?&—дЃЉ&іУ5ЫФ^Люк–МmєЈaї•їaaзwЛ„е1УтЛКЎx–vѕ'Љ/‘мQŠБА™;Š”ŽчзД—ШЎС›zІ$Є[Ш§Л КЉP(š4iBe&ˆnвDш nзБЫR>A-hЃ›&дв z`n)KlІГ‡І8Ш'Уі=ТџДІ§яяпеq†ЂО {yиэ dИя ~9ИNŠ™MЦ“SќЊxЧV*{МщAзјOV шпЋWЯHŸ9gоАQЃYs„<[эl‚c†ю’:I в!џЖ-л„Ї'gyЄNUАЦьhEЅХЅ!ЯъЮtf•”Рќ5ШаЄџљ]ЇИy›ЙРwJлЭ)mї^)ЄфЁ›Ь6DЯ H^^+@‰ъ—bц1яRЧЮЩЏoF*оœ ;:wpЏмgл):*Z7QД Мп‘_KŸ ,эжnWџЬSцKЋG`€юB'…] …ец˜сP1Ёa`[фДyiЇвВЕ ьЪM?p~UЏВ‡§Г9№ў'оl7sкМ*’Z)ї RКyи?'ќstТ?Л‡§“<рŸя№ТОa|Ъй™џ\‹§чю ШfPаV›.0Ец|г›T•дmбIaЮЩТj—:ќРбјЙ ”^|˜Nažмьl™Ч1>BЉPМаїˆLa8RєFQие=Р:9a*tАСcЃŠПЩvN !Љљp)›IсЧŠЊВ>йRpЗРЯ?€nшЖзXШЙœГtљв W.TќUСя`І7Дв" 6 Р”Zzи$\5Ј˜jlŒ#ЄlкВ­ИЈX7Ќ5(iЫІЙ QлD}™§ЮьеK>".!nЮЌ9рІ#8т\685v˜СЦ†jЇЏб‰k?™Ф’ютP Ќv6=И[ žO"uЫз[жўgэЪOVz?сНцуe}њ f”:U нztЋЪ)8гЋЭ“ш“иVЧ№wPЕѓ#ю0ц ЃЂrтDw™x*›шz„—Ф PЂњЅ˜н…еш?“У=м…ЄњХїЈС"“7„СP9?ЧoТФЏfІЦр wЕqу|VBL`5е&?›€ѓвKKў(Љ;>цщCT3Йв?2џlКњмОWPtе>5мБќcиЊнШ !ок6шcгЎUћь(йу›NъŒЖшЄАєd=ќЬŒ„БkЫFEvИ_џзНЋ‰Ччц§QЎќЛЎrюM<xŒiхбЙ ?ЁmHё{‚pџ#Й%$їoўYAНБЅ…_ hЇ›љz6КёCд4]%xцЭЄЉ“&П99їJ.t™ў~ћїЊyLЃVhбМE~ОˆZ–ЫL=,Пƒ ’”œч$эЧ†O7%'IaЁ^ 8ˆШнVЏМxў"Dфъš#›хЬи'\ŠO”Ѕœz„Ў Џmњ‰цР2Э.;u7Wђп4•Ќр$žM§tпюR')+H…рр`xїѕ_ЎЏљxMЬЛяь•:U7o‘ѓKеMg;”5s“d{вјYљžH+xЎЬг/#•0< УСV=DЗц: ЕХм‘bТ2€рїl—в?JШН{ъ+ШЭ„+–У3•H?њИЛ\юNмљUў„ЛЪнлЏwaY9щЛ$˜hH-Хnƒ‹‰УŸM\™*цэ˜%Ћ>NќПџLљ`SŽМ+зi л6CЅxNЧНћM№ћлC—эщѓЩaО]јQQo"ѓтWRGOїАЧ7дmбI!uВHM—ŠD3гDЉЋ–e›УЮc3сyЕ]OіRhšpnчџ(?pЋ<§^y^Iљ}эћR‚‘АfdL+DТќIгFТћъGНhщ2ˆЩ`YЖtгйёйаM_n‚  ~џХ.Œeщ•••0ЉК… Ю›ЗpK7F кxЅTЫ>\hА6Эдc\аЁRRіЇєюб[x“Ш]Лv…tгvЮŽ™НцГЕsfЯvRš.‚{чХžѕ%ЙsуЮЉiiщчЯgfg_ЫSф+T*m(у&‡ЩjVЎДІEБNRўlzРŸM ?\›t—дIъги'џЖюїф„ЩкќІ†/Tљ?^­ЉS5rJфЂљsљя Щћ-”hГ[љaYfVобѓМЇ:CПДUќ–g]ИFш./кЋж„Q: –‚’rFЉ0аИ‰Ъќ›ъ_sd0кї„ТJ Нk№гbЕFrљоф oЅм=hdИА,•съ wV­\О2ykђМЙКkЉиky1qќГ‰{HbцХФЬŠ™ўЮєEqiYSвќeЏ1€Qј]&$ г љ™…ТК<= Э‹_нљxэкЯж&ў_тщ3ЇћŒŒ’шžQ*l‘j2џД§(}єєБyxiWOmаVG}l–~гœМеœвoHбR'‹ОГўѓJФт…ЅЎZСmДXЪю]mƒк>Т„гЛр—м†m:OНь5m˜К\Ѕќ-[y-[uїЮ§_/Љ~ПЩ•(aBл“э%_76~ˆ?ючГ?яТ!ги…9Ѕd˜’8rдH˜Ъ&•г 8)v+ЬўЪpˆо~NsЪ3бДП0qmњИ ФжїЎu™RЭ; 96)œЄ ‚gy№ђh/ $OИУ*w‡{НѓммЙv!ЁъJ;йiнХЄš#VYf]Н5Ve`М6єХЁ§М|<сЩЙ^0Мусщщ!“{@ +—5A?eєœXƒїŠТ›р={‡dž!–ьƒс >Ћ‡ќќ'‘}"z™6\уŸОЫхM Гг›р \Јбe›d€_wwкD­љJj?фхф@DmСтАя<АРЃЌpp<лVЃ=е [тzxІхВ% ‡П<Мк>мАx&жэлЗ1\ГZS*ћ­›Зр=<Іœqк}аЏA[mzзШu˜Ьžœ’ѓхцѓ+’ ?А †DaМ—Ш•Ф] ЯЮ?9иЮПЪъыЈЎЫzUЅЅ№І]ЮMMqrŽSsžВrЕЇ‘˜Вюы\В—Œ„i' ц Ыр1ђ№Ј+шх'ДAvЉd1мa [Х–ElN?ЭФy{ію пaУУ舋AмДј%дІu›Ф/Ћ=ЖЭVЪQчТw H9тщ.Ўщ["xZdа‹ƒГПл–}њg.џy\юѕd+ПНК —iп­ЯhћџѕuTзeНанl&иtАбœЊ3YКA1˜1YІ]сх"ѓw›аƒЛЌ#`ЋјСВˆЭ%ћиЬlxX?ЌffЦlЕ$PПзЕ4оy‹#vчm;ЧЗ\ sщLХvqЂОŽъ:ЎW4&3дNc&jt„]uм(Ьe[Х–нy№(їБ1є( $€@H Ž XБ9ћНЂu ЋCH $€€MXБa›M Ѓ$€@H XDРВˆ ћи,‚‹™‘@H $`–ElиЧfшЈ $€@xЄяMј,СЫУKжHџŠq Q+…јцЮž+мD $€@ѕBРВˆЭХњир-7‘Гuo•6ІПrѕJуDLAH $€@нА,bsічБtЊёя%$$|'џЂ\ф2вЌёђ M=Hd{xГў…kuп,X#@H $€,‹иœНЭ SmўћќУKрm)nФлƒxУ[:dФKFрujА`Ф&8NPDH $€ъ“€ew8ћНЂЌS-b пCИ2m/šспG,чc5/9ё”“Œ[|“шіZе:№~гх ]„йT*еЌшY-лДlџLћ ы6А]щЇг#&„З фгчЧЬR=Iœ^ЅaеyПхELŠЕ]BКЄьIЁjѓѓѓ#&№‰А‚›Ќ:Ё ЅS˜'!.Ё}ЛіА‚ LG $€Аќ1$z IDATЫ"6шcpаЉЦїЋ5 %e%АщэЦЧj|›6hЫШчЛмјlev|Щ4М+УјuБ‹cсuМW.^9wцм;wXt•И1qњД˜мМмsiчф^^бГФчо‰ъ„Plђјq“ЧOЮНš{фа‘ŒŒ о7BfDMщеГWю•\XCК…ЬxkM7је)Ь“В3щьщЇвNС МљXИe$€@HР&,‹иœО­zЇэrƒ‘Pшcу;иdфВ6\гŠB[)C ]MIл“žыеЅe я№!ѓЎчБ]|г3эЁlVЬ,uЙв!3§ЄЫYЃpрак<Е ;’wа"IЩI}њѕ‘Щdž=cЦž>}ЁFU,C\Bмœ !д†т~ў~qkтшЎЋЙ7ЃgDЫYщДѓЌЦо)ЊСФЇh#Єнzv3QЪ`з™ДcЪћJ…бOr…Wš!lDи† Ф„и4(hц&й)ИЭ ‚ЈЭfЊТlH $€€Ы"6кЧ&ѕ)U‡уЄtЊСцРЅVš™Пbй шF‚žЊЈiQW33izђіЭЋVЌтг=dБяЧк_Ћ1САЁa+V­€  *џ*fЕSњіЧ.ў4юSƒt›Ът;Š;'O„СVˆ)ЁыŽfާ(ŒђЉ'a6M(1БЋјЏ №fЁиШfeq@H $`&kюЅ=mЦŸfVYйXЇЕaб‰уЬєЄrФј–(`Ќ’nBаVЁбэ)Ttы!шё’РЩ†Giї›P­P†(mю{s;wъмИБ{ф›3ћЕюЭМ3czтз[„щІeŸ5„Tj<„kЛv^Зv‡;aцД™ Џџr=lТиЋiUЂ{A?євб  ŸљˆfУD$€@H 6$B •аЛцдЃДSЭиЙ/ “г ЬЌŒKX4пмW4nо"уашc3ж)L1ЈБœWmJмD7сЖƒо}{Г]„оЕ-[ЗГDs„Ž%!юњ2ЇOŸNк’DДэѓиZЖnЉпcйџŽ;fчd‡і …b РІeх17@H $`ЫFE:\ЧOgы”Ј)tmідSзЙžѕыѕЌзГ~Й~§зы‘Qf уГDN‰„№Ž4††РC4рцZаЇБOўэ|3•Аl№|8e‘R­V;~ьгеЋцПЫ?.–Э_o^ЕdёО=ћŒУ5ж{GsŽ›0ЎjЄuйŠAУuѓе Дbѓиж%#­uB-,ЯШбЏЏ‰[fУ ТИзЦл€)H $€@- 6{ДъDH $€€i–ElиЧfš&юEH $€€=<вїŠ&|–рхс%kЄy€†(‹•BЪ№~tс&ЪH $€Ј–El.жЧ/†œ)Х}хъ•RЛ0 $€@uIРВˆЭйŸЧfаЉАпIфn$ЙŒ4kDМџj! 5ТЕЮ];гˆ ЂJ0 $€Ј ‰CBЅ єБ‰vЊ xi˜œande\ТЂљцОъ qѓ‡Žа>6 f|Вщ@„ИjSт&К Зєюл›э:xш єЎmйК%88˜%š#tь(( qз—9}њtв–$ИO˜ЧжВuK§žjџkЌЗcЧŽй9йЁ=CЁАY­ }ћфпЮ7S ЫЯ‡S)еjѕБуЧ>]НjўЛќут`йќѕцUKялГЯ8\cНw4ЇёчИ у ыІЏСЃЂƒ†ыцЋAhХцБ%ЌKFZLЇ9ѕŽ§њšИ%`6Ќ Œ{mœБ ˜‚@H д’РЃеЧЦ`AGыTƒ‰бNЕF‹+[љЫcާv4<6mмk# ZЗ žЃЛ#aц;3ћю[ёW…Tя‹ŠЈ@ГѕшбуЅЁ/=јћСѓ=žџvыŽ€ЇtЃŸ >XЦ‡_џ§wœ5АPTgјЈpх]EЯо=+ЙJ:OŽ–кИaуТцФХѓЗŽ>џ|7и4а›цд ƒШJ…т…О/@ўЈШЈ№БсЦz0 $€Ј%Чю+TEЪю]mƒк>Тj0?=Ј}еХэWаР0О M?Ъ кЈ5iѓ&+"6ћйьš АЛ€GNс‚“bwRГ­>$\л_—ёЮaqXУЬ?#\РѓЕIЮМœœGБ ‚3ŠC4›FЈ $€А7Ы"6gПWд˜&mТDƒMKI…ЊPFH $€€­XБ9ћНЂд0 3‚›H $€€cxДюuЬ6@Ћ@H $`š€e›ГПWд4 м‹@H Ч$`YФцzѓиГUа*$€@H  Xіtгѓирf]Ёj”‘@H $€l@@ЃЖьЮƒћиœтyl6‡*Ь €л1’эГ8)v'5лъіsm]Ц;‡uФa 3џŒpЬwж&9сyl–Šт<6›pG%H $€Аˆ€ћи,Њ3#$€€пa9 Ÿє$„#D^QЊ*њ.X*ЇSЄ+UЪ”Ы)YwГJЫJ‰І^6ј\TЯ(?O?ЇАDѕNРuњир­štЉwІh@u@ aн†љяЯЏƒŠъЋŠ†MdўC jмЯЏaSнœx9˜s0ўTќВ;юžю^ЭНфЭн+НШ!Хю>!хBŠ;†І#:$р:}lєeъДе!=Ќ z# oP­j8їщE Zj-6lЂАVJмˆ;єА•Љ+сѕЧабfыЅVЖ™oŒ†lј)ШHЫцMK9ЎT]Z l„LiѕКœx)еЪгчэЛЖ/щ$ѓUbN$№hА,b3}ЏшЃIНFHР†›PэХq&4Чw‹/)+1‘СйwЙkˆ7Q–Ђсје9—Є IФCKЉІ”ї€†Ёи(P‘Ѕ ђZо?~ељy ?Ќœ;t‘sКˆV#:"`йЈhїŠж‘еЕЎfѓ—›}§}сГжšPЛАl—ещА‡L#цЌЅeWцЌqŒ9Эыэ%JFјXJ*Jеjшi,аCЦ–іэкGMR*ћEDШ/’jЯЄќљ •Т5Ž:Ё&h/ОЩFЖ)/ѓ:zш(имжЃm—з_ н lЉуCз>ul’м|Ф XБЙЬНЂ›ПйќщЧŸТч#оќuь>bЏcрД:'ХОoЌŒXоVЖвDЎ й\0bSЉ мsаrXN‡6ВЮ~Ф[C*K9т&{rXŽяІЫЙŸЯAаіfд›ТНŽ Ї^Kе†kЅБq„_СЊJТЕѕьœ–žцэхн6Є-чщ%ў­}’ЮŒ:рЁы€&9BCЃ uCРВˆЭ5њивJїііŽx#Тлзd~`%mOzЎW—–ОУ‡ „ЇХРЎ№бсdyрa—.ъr5KAСLˆнLPЖЭцЄи!V XЖ& j4P,Ao”п\}ѓкGз=ЮУ&ЁLѕn': љpбќіэZТњсЂЕ];к=щpтCЧI—gкЗlг’П•A S4]Y˜™[ЖŒ˜Ёz bѕЎ\НВ§3э!xкќЕсЏAИžt э’Де0(б•еўѓЕ{ЪHбср ŽЛєЋZ­"УлB7›ЖgJУ§~XќvQЯЦžsgЭНzѕ*ГԘэ@‚O*аœЦW<Ё=Е—/^†BˆЌЛћw0flЋБœІђџўDEВ.fuюкYArГЫгˆœј7ї>œwXXЃдЁ ˆD8‹&’—--5+fЛnу–ЅXx:в=‘R&Ac’јн!lM”mBРВˆЭ5њиЖ|8%j р›2i ШBŽ{П?’›їћААQГ?˜ ЛbfЧ|–№ЫП6>zFДЬЦ*pБŒbЗŒ—rЛvдш HŠ”EЪBХЮџn5geмЪ{їЮ§|жлЗa“f–J‡Нg3ЮžL;wхќ•’ћї>K`ЪEгЧGL™>uzюеммkЙэлД_Б4–цOX—p§зыЇNœК|ёђ§Лї™р›ў•1Џ|ђё'№CQ˜.”}dњѕрjZRІBбO8+j*mї§Mš41ЎChи§ЛŠvл§ѓ?mЎџ§2\[i([ZZJem lІS5ьхaДd EHЗиe\І@ьЦLъ ХIБ3ГЩxrŠ_яxРJe7=шџЩЧ{ѕъщ3чЬ6j4CЪЮ§gCрTЅщєœЅВT:Э/•ЮjЎќѕDЛРХщay@ЩЖфmPuvv6KљK›є?пnTюŠЭЅЃпS€ЬrвєР—Њ•ее‚Ѕ]лvЙyК+А O™f ДшO˜Ч:™y7:qєЬЃ‘3EžWœпДyг„ёЖmй(є0oЮМyЛјіM'НЮ’^щэ–щHBЅ&.дЂœEс8Qмв ЅХЅ!ЯъєƒуЌЅ„GЄјЫ1m’Iћ}w 3АйY6]Р…:F›mq•њДAi­ mg6?Џ– Ђš6mйV\T З№‹П/ШI[6БœžžК‡ЩdВ §рШьwfЖfф‰Kˆ›3kьbљQ0“b7”mГ95і‘ЃЪ;”:$ЪКй’ЛЧ–|t–ћ8ЫЈeA@@Эр№рn•ЅвaЏh~ЉєœЫ90рЃЂp yђЩ'‹ыєп-€ъЈ,ќќ|нчЉ‹hBNОw­‰чЬ ~pх0жлRш}аЏV\ЂОГ_М,э0ƒЯп~ћmfєЬeKъ,‘ ДŠЪЂW<уlVЇРƒнющЅЎЅ Љg &L‚ЬЂ$ёЛУ#Ід†€e›#Яcc/*ˆCбЄф$ИрВЬ oJNЮ\1.8hр "wOXНђтљ‹у%5Œ bŠŽbЏ—CС™БOИŸ(K;9ѕ]A^л ѕЭeš]vFRœ•ќ/*бЖ№k‘ŸŸOгѓ ѓћЕ ВT:ь­–ПЙ.ПTњЄЉ“&П99їJ.\F~П§;ЛzДhоЊЃu ?ї~Пwїн0qJ˜ШdЮˆ›Мї3rOOљю‹i$kŒ\ўфЫ9JxЎŒcž†€ЦєсЬж8}њЭfТSгzlОЗKѓ.їT…їИТKхіэь;ЎЧˆWFdœЯшаЉiЮэ.^OУ5p№С]2ЌУp&]QЮЂ‰›ЗШљЅъj_TШ гEЊХѕћў›4Щ(З.П;ЄШ`Кu,‹иœ}[Ъў”о=zћљћ1X wэквYŠЈ0;fіšЯжЮ™=ЇЦKЇhёG<БзЫрМиГО$wnмљ15--§ќљЬььky xF„Š<„Ї›цЈAXЙв’ъŸt˜GНlщ2И!ж….„MКC*іђљЕ FщђKЅWVVТЄ(шk‡[ц-œЇЋ•шHƒъ`ЂЬp_Й\7yіњљњэMйЛ=iѓ†Я7АЬL€^ДЂƒЏнсЎ(ИъE wџї§Сpѓ_еВ,ЛИ5nјrCыЖ­щn)O}ћфп‰)Х•к"ubЏ‰77n•пЈ$Імн“=ђхЈЁK—/Ё.пRe~‹WsФ* vњюЈНaVycЫB.р‚-q˜Ё+/'чбъc3ƒ‰H–”)ЗoпЦpM=“Л=щJъv"ьЗnо*,,”єФйvp ф№6'w …АЦ•7’2-хЃ.ы‹Я{ƒziёКЌІЉ-ОжКЌTДЎКiёКЉEдALtU–Š:ћНЂЎкŠш@H $рк,‹иС>6зn~є $€p –ElиЧцŠF"$€@.FРВЇ{˜vnж5ї"$€@H XL@ЃЖьЮƒяuечБYL ‚лЉ—ЃРIБ;ЉйV7Бkћы2о9Ќ#k˜љg„ И`ОГ6Щ‰ЯcГ FT‚@H ћАq›}ЕЕі„ЯМ<МdрСлкEC”ХJa%sgЯnЂŒœˆ@ЪхЄ\eЎіyЌмФžSUхЪY;{єм>,щBвт;^фЯFљyјё ЧХёјЫiјЄ'!№Т{ў!mEп9ї@”*eЪх”ЌЛYЅeЅDS G]HрsQ=]іylŽw@ЁENOРВKЕУо+š~:=qукгЇ/И?с>bр иVx6†+] М—0rvЄTІ•ЋЋох,•г‘€Ур4ъŸяў|Е8gb‡IЉПЅnHярзqлб-ынШіьЭO§ЛеЁ[KЙвyЯЧЪ МШRџЛХa§yє kиDц?4€ƒWWiд$УЙ§?˜s№Ї[?A”цющN< 8UЂЎ<Єиt)iљрхсн№•ЭЮнОh}нА,bЋq[нm\KтЦФщгb6н+чтзЦGЯŠLJN1ЮfаЉЦПIš№DюІ§+#Э/вдƒDЖ'tЏБLБ”@њч+Гї}EИ?хђ†\Щф‰&pНю6iаќ8KUй#?<šм%Ÿu9цйˆІ>~;ВП:ыЋыqН;єŽ ]™_–'—{y{ЙOъ6йлS~Џь6бРзgЉЬЊчЮз=:V#ьqH8ŠNˆo ‡­L] A­ВёRG 5dУO № б–Э›–r\ЉКД:и™въu9ёRЊ•ІЯлwmŸЋОЈЪЦm†ъm–=нУaћи’’“њєы#“Щ k-va,tЖ‰6+пЉ6-2b|]iLVТXсхФо|Wё’™іН~Б‰2Д"1эЋXђЗТЯ ~ZWШŸ№ š ђїŠs­Peз"№fW§uЌœя6k@мНH€oуэќŸ**+ шž'•KВf]+Л4)dr^aїАŽMУъЬ"рЎ!оD]YNH9G4vйЬВЂЖ™`о—*oфЅsТPmGA`Ѓ@ю7.HДМќ5юtТ8ІQ[дXох XБ9Хѓи`„Д[ЯnЂ-Gƒ0шT‹иCТїРWэ5Ў ЋСЯ=зфФSN2nёЅu{Eе”Xуw?d ‹P“JЅš=Ћe›–эŸiПaнЖ <Š˜о2OŸ3Kѕ@ќЕƒz•†aGоoy“"@m—.){t]љљљјDXA€MVPв)Ь“—аО]{XAџьЛh IDATІ3К0Лћ{јyП'H œ”ў]?‘Ѕ\Эђ8‚р‚=m№ешQ ЧU;џ“Њн2O.ъТРдпSМ|м—єZЗч•Гr5?‰Mюёџй{АІЎєќЬ#}r1і"…(j‚KYj­ЂЂЂЃuwŠеZЗ:•ж*TПV­ƒbХŽ vєk­ut Ž#іW+ЖЖ.uwZ\ЕСЉT$Ęф/ШЭгєсџЙЙpИ$7!a xз№оsоsЮ{>gЙя}Яr=ёлу)лSќќёы mЃYdPњ0]1YaЪHЭfXкŽіMш}1ѓbє…5–с x+Ipк{6ЊOС§IЧ0 ““C.7ъNъ6‰)ѕ9rшd–ї}ЊчцЬMXшf#LЗW№ib‘li­Зц2ѓКЕыG  ЈlЬЮ]р ы$HДОD=љЄ<ЊюœШщЄ–нги<жЦFKˆ УяХПЗa§ъ#$lŒj†RB•^œЎЦиЌJлљn’ЮPЪ™юЩA9Азтп‹Ча–})ћмчnнКEЕ+~ЮW›Ї=wњууƒ9_QЉDг„*ікЫ3^{љ5эUэї‡О?Оr9Ьќ˜йƒ"ДйZ\a§Уцџя|згrІ}•zі‡у'OŸФ"э+‘Щh№g–х–щ~)+*…Х€˜#2ƒюш[‘G—Ž?И"ърлQў™”ёйЪ‚+жa]˜ƒDзf@J…BёМzZWпnЫѓЇyЫЩџЁ};)‚26G+Lњ € …ЌіEŸuЂЎ1SvЄlјp~ыš@Kg2ь9ŒЬ}Њ‡ЌЗŠ(-ЄмШ/Y—Ш\џБЙТRё]ПчЮœƒв6'fŽ0дшєkщVuЭХJЋКVNи`EягЇ•>ЪрА`VC@wпдsЉ62{`№@‘l@k‰ЗбoDЃ…|Гя›[…ХчЮŸ›1qвG?т т$Шн’Ж‚КsOcѓpл…‹^{uЦЖэлдjЕh]кеx3ЁАБq6ЙbUзxƒ‹ MUъpъЉƒ#њjќЧНА*„pІЇCa[ДxорЯыЮјх ЪY+qра(mxОТјrї—|ч|Eг_ŸД~ЩЛЫЁjcЪX ZџQхвБЋкŸЬ_ “Ыp-]ДєъеЋЂбkѕќrЯџ{ћнU*._юЉ”Y1иOЎ№ЦEєхDџРКjаBЬ^rэхуйЧ3vOяжюлœГлљУЖŒmGуšЭцeK—Y­ƒЁмыQ•…€<'НеФDЧp†CM ЬŠд †”ЯSњ†ї…Э†‹b!ЫоЎN–fчJ:ŽšMФЃL§Ќя$N$VіКњЏ#ќЇMˆUЫƒžѕ§гFІЖ4g7*ў•@ kшЇ2F…ІŽOUpQO$мH€ ;ЅRѕj”в_ кЃPmByœˆ„э‘œ:eъСCеk?`MФ,џŒАIVК§сфXЮ„' РуoєјчгіTОќ; r ЗЦkNHйѕ“—™яƒјх ЮSЌЯка=Э“mlшѓ^ŸЗэѓНz9мocT+РYбR_ ›G‘ƒШ‚^dѓ8ВўYВіYЈђђ66XЇОљі{mоэШ “cп‰хЁФмeж•Ќ“ЧOjЏiё*™№qќyу™ЈХ‹хтЏЈхdЮW4йOеq#Ц&LЙb‚Œg›№ќ„-[З`јРЗЂбkѕ„Яєz†g!*3Bƒ•Иф>оDЃ$cеђajљP% ЏLџ1b.жaSѓ!8#я7$ЂЪ`t…aMVZHЮo%ћп!‚ ЉЙ цОћіЛЗ~.ўfпїч/UeE=QоFdччлfЧЬFњГgЭэiР6†<ў#/ј>. œXЉ=ПsУ”ј…žБўЬф >2Ћљп>wєыЄЭIt5ШКѕыюнЙwюL6Ўќ;љИEбqЉ‘ЊJXЮŒ„5ўnTенДчtsCчu`4™™8у#ИWАЮЂ§Оd7ёb9)gk ЙŽкJz§ЇыuЏ\КRtЗˆЯKдSt|цљ1žœ8}ƒ€ЁшvЄ9Т‡„'‰„P{$Ч.о˜Д‘ІРm‰ГО$S‰ ќqPџИЗтrЏфт-zђ„“ NчЗŽъNДхˆz:jNЂcЃЈ'•аО3ŠіYЪ_Mщtќѕщ†Фєƒ*œКє#щwє‹ЧЄги˜œ’б?LwS'šlЪє)`˜ЙПbсбŠ„Г#GŒt~бдќќќŒF# ЫœІЃOG ЊЮдXb ыТћƒŸЦuBиА-|c!Z-2‚AsЁ)  ˜ЪдщФ‹)šЕ_GПъ4—Ф-|s!ЯVЄ/‚№ni.іxь=yЄ/ оRићўJшУ{GєчˆvВ\7]Ž[эdb|™ЛN?GіŽ‘'"4ALзн­,,JMХ DЅ bтЁšBzVW‡А€H–bш$Y>q›tP5дпО‚ЈфЭHPи!CђYvoа™b љиИїЄієždіf&Л/Ž]Ўa?‰Ќј8Ќт§юW—Ie>Лvю"† QOTDC"•ЮенoV‰~Ћ3/­zJPБ[!,/$ї‘2Y›bœђ–4- яЏy.‡њP]HpN№Ёa}jДpдя~nЊњ„Щ‚ІЅ›ВmЪТ#б Fgъ21JЯ|y&šVNNоИ%qђі†$a$т,‰Ш‡ЌЉьАHСIі_šЏЈЇ“ёY88ТGXч"9B2rbфыSй! &TрzсzІгŒб…EРєWтЧ‰hЕђ„5 е-гqА§ iћB5jsBЭК8` ƒРТ[G}VШЃЭЩЉ‹ЗДйџVЋMNНћЮЛџенщ?А?ofФЏНЊЁlŒjЧŽЃ^шљ‹њ€–ІZўг‹Ћ– 2}2фЩ;њaJSЉЈ(‘№~‚Сhш§LяУvlЏъ,dЋuЮWШLiпџi k37ЯjiХФ+„УЇLŸy;џ6.u>+щS;?пџёЅYSb€ZŽИ… {07š§ 9pГlo^ŽљH/ щЗЩ…_ˆ‰%ІœuwюоQTNpЋЋjOр 3А&№.]К”мЏЎLкR~$KчЭE“u’`фг6šВGЏBІ3‘c:FЩ0оrF[BLНЂe%ZйЉDт ыдx1м8EѕB‚Ÿя~ВЁбФTDМЌ-тз<Вg™{ˆ/жРы3џeёхЌЫ E=Ѕр‚…›PšљE-Ш €†Оtй ОЙ6JІЭ—(”3шЭCžf &х”‘Д“ЕЕАІЫФммННTrR|\\]ŠŒЁ3nызѓžш8Тnѓю'ŒииtпN}ߘŽA'Лg.ќЎјЋБ3ЦСvВuЫжIS&‘NьОЛŸђъjіў]2ѓЉё•ђ8m\џ-ЌьПT~QO'уs |:uІщ8$œŠф(жшQЃ?јшƒЄж]ЪМД9iГ#6Щ_ˆ€КЋ:ўН„р ЌпДuN‚lY…їNыNДхˆz:jNЂcЃЈЇP(кХ>[›MN-шVh?ЃFЕŽ]Л^џЯѕЌŸЎg§їzжЎc…DTtŒ‹…Šž ѕЫqˆ6№}лћфWk.І†5Ањb=t‘ЃЧŽnјр§eYЦGФъкїWНЗџы§h6IСaуcs;cц ˜ю жРСд€КцЂуVЃnпв=И;ЯŽУЕ№ћ\ _Оr9nyџКK.Ъ ЪіJФ+?ыў{ГьПхфзДЛ[чLš3nѕкеЏН>#›=Eе5я6фзŸЩД№WјDœЗL­ЂPмPi=‚"ъщh|F”ЪРd1srэј8IДьМgьти6nZЛЄUОo8)И[AS_šzєаA~Џj6ёуК(гI‹Y8Џ;б–#ъщЈ9‰ŽЂžBm:ЃЃ>+Œк=ЭУїŠк”ЭЩ- izžЛюъБсs.ИіwHсˆюrWЫmиРˆ/M ью?СќqcЧёЁX.6lЬ0ЊжЃ№4‚јPJРрРЯ{.Иg№?>џЧ?ўљ%о'xfч|iR”@єЉ“Їvю0hШ lЫ‚‰JŸ&^sЯўp"јЉ`\YЯт–їЗљЅIQТ†gGє<|иp\ƒFN>е†ЗбЛЯ,=]МєhЩД­ЇМ/ Љ{цЭ•BеЂ‹цHxXђztян1Hўю"рžЦж:ll#I!ЃPx,SяqyЌx-O0ивz=Я]МыЪmђ•\Г#€}Э.Cc €ej+ЦЏРеиеšО‹SЂЕІуœЁirq.ƒкЪpoчAыГБЕВъ”Š#! ! ! ! ! !а*pOck5{E[e]J…’h­ИЇБI6ЖжкЄrIHHHHHx2ююс|6ыzrQ%й$$$$$$$Z$Г{;jЕБЕˆѓиZdUЕ@ЁЅуvšЅвZ(ь-Tь:Wqы.oЋ)ЧФcsНGД‚"И^исФylюЭŠJыиw)       Зh`›[yKЬM†О1šq“рѓ№QaФѕV6™xRFіјGцЖэ‚гfY|M ‡Дяiй'€шMњД+iYwГŒЅFb)ЧgТ4ƒcЕкѓиь+Tђ‘Ј'юilЮзБеS”њDЯ8•БщГMЯ]є~м{єЈбё+тUў­ѓTЦњ д\qЗlо‚Џ тћzВv2œЙoчипY“‘ћЧ‡,]jЧ"yд N]+ ч ЩхЛ„§Фє—”Жzсй4‘лњЩЦЉY|КЪb&ч›&ЯЦЪх`юСS7OAKѓVxAЁ цђCК}Љ—SзŽY;ЕПєйЭЦB^JЗ5!рžЦVы:Жц‚fлg›ўwюџ§œћфQђЮфѓчЄэ;d/LЦgыrіџАП2L[ж№ yмGя ГF/[oЯмє>ЎэЎщeЋgŽј†Ў‹)$­Or‘ГЩиZz͘-œuё"љ&Rn!›.sШM %Нќ› ТЫˆж%,iLњ ,lЅfдghkhзDZШ–SIјW`ЇF–5šх0А2ЛлŸтЃ7ыWfФэПЖП)П+ка@JщЕHhћЇ„чУ=ЭcmlЉ{в(жјђюњФ5АгЧ7UоrB’ЧхЌх!yPІ;wq~šf-ЈЙŽLді( Bu™5Г†RRXj.)хBŠ7嘿i•8h:Ї<г‰ФЂ™[H7RXFŒ,1–5MцR.uGРлB”ФŒњт>ќŠЋeКд‹ЉDЮР-V#:Џ†ZˆІF—Ѕ Z;"ё§ЬИЄ­[:Ўљ?‡а21n…RKƒПhЅКЗѓРcmlДlfГ9ugђшбЃЉ€Ц0 @ЎRеуDУуƒ2мŠŠ2Г­йщVіyжњАQ2„ЛкЩ№ыo]{YgFXb`9УOлvВЮOp_Рф™љ*ЈєъfЏ,ЯРє;1Б@ž юN|k\FЖцYЊœ № ?vЌž&Sѕ—.5ЫіЛa№ф“3—™з­]78bp =4f^Ь…sцф4 e{ dРЏSЎжЈєaКЂO”BП&fиJ…ŽЋЃ*ЧC­/д ьiАл{6ЊOС§Iuызœќа;9еsRЗILЉЯ‘CG sА<ИяS=7gnТB7ašИ И‚O‹dHkН­jШ•QЬZџж …ѓrЙЇБyј^Qдv—.]Ж|ђщ{}ЯQБ3 Ыr ЫtП”•rFѓoDfа}+ђшвёWD|;ъТ?“2>[Yp%У:О8JFђwўIeЬl^Вr"Г.d! ƒ яvВ€'˜ŽОау$з№А,б•?u#Ln[ЗvфьLВюЩ фŸQЄ0W4? —Х…ХWВЕ7meYvФ№Bm@щЃL§gЊhФш7Ђёlўfп7З ‹Я?7cтЄ6~$ЪYЋgЪŽ” nРo­œ­ŒСd&иs™ћTYoQZH9ŒЂ^В.‘ЙўckдWMVwюЬ9(msbцxщзв­ъš­‚%м Ы Ќш}:у4RpX0+‡П! Лoъ9лFхmРEђДJЏ›~и˜БлxzЗvпцœ§лЬЖel;šLwЫ–. ьи7,”{ЧЊzUЅЯIoѕ…˜œ & г§JR>OщоЦ.Š…,{Л:Yš+щЄ~‘:8Ђo ЦVlCуz !R12iУА/мф+3Y9ІHк)|н|eyFя*Gqa_^>П<СG‚A(єщPРОhё"и{xO0aЧ­}jрtTkUтдј‹Э.ЃFŽўЈ…ДЏЊ'хkРпт MV ћVљд—o35Єpщ&\MДїЙ]ЂЧ ИпбRаыz’*w)НGі§…|НЬ‘о&“ЩpТтŠ•+fО:31)‘f–ј~тŽфЯ ђ Ј%~8љCќђxUЗяGЁPŒџ|š`ХeЋ•МJЅ2ъе(ЅПt­ќ­ƒСd.Ц…ŒрУ№YіђOfГ‰Œ†™Эj™ВАЗ|0^б^БtбвЋWЏVт`!+W,ƒ‰зЪ+љ—OО›р—'xNбŽа€`^)М !–Џ 0M=mzЗщЌЅ|xРb"Y—Вzїы­#кœВг„!”‡ѓ Гvи,dныа ЄЂ_г"‹xтАOmOAПУи >By@; к#9uЪдƒ‡АЁвсЇoX_:(UyKХ ­„pєЗ}ТЈŸwЃђ!˜іuхh јƒп­JCр}ш-к€ы#П#fš кž}WE(ВЖ(ЪяžЦцс66”J&—ХЬЙxё"-Ё Ќ$СJЙ7б(ЩXЕ|˜Z>TI†`e›е=FЬХ:lJ`#XтFу&nH4”В/eŸ8yюьљГдпёrдьyЏЯг^еjЏiC{„&ЌŽЇœWВЏœ8z ј$­_gје™}тиЙ?ž <”p’ЮљѓчПљі{mоэШ “cп‰ЅQ<€‘RAmcЁ"b фgZcˆŒQ*ULзœMЉр;ЈЂЮОМќЋїFVѕN†MЉYWВN? иЁ&&|œ@“ТOћдрщmš%ц.˜ћюляоњЙј›}пŸПtžїЏ]€ттЉ/L*1i{RЇМхІіИж6Cp…РВюƒХiKЯMeIk1Ev#owЫ{ы)ёеEGтХвBr~+йџБ›ІѕRдБуЧЈzй‡6Э_0ŸдQд?ю­Им+ЙxЩњЛKяќ|ль˜йˆ5{жlаюFo‰ќў#/ј>. œXiE+>~ч†)ё =c!§;˜Щ|d0Q‹9ш§I›“њъЯЎ[Пюо{чЮdуЪП“[јѓнФк]ЊmЂA,‡:њ•Г#aПUDu`їэ9нмаyMfF&ЮјюЌГhП/йMМXFNЪYnGuŽкJz§ЇышцW.])К[Фѓ‹z:щSЦOœ>‡БзPt/i#ЗлI* O8 ЁіH.Ž]М1i#M!qSт‚љ аwЈDИˆ€pє­гQcGe^ШDjњb§ЪЗтxЕ>№‡Ї[{­"Й5ђ‹2 ГэЊ<ƒАEUG)вщјыг ‰щTдцвЄƒEєЩкb7Vxм’8нM]ХoЦcТћ SІOцDKьOј+ЁGьAвŸ#кЩrнt9nЕ“‰ёeю:§й;Fž<ˆаDТњ‡неёЗ:ЮЯЯЇ)!zЫ{B_ щBŠєE<_$‹дј['Щђ 6щFъЏщX)яу!Пv<Т!RмQvсvц>6r7;r'‘Т§NйУ.<ШЦeNrЧЖ„cц…„hy)Я1(ŒkV‡–жGvGЉёљмЩЮ IDAT_Д…A<КлЕs—А6сяА0Ђк*ч~C”ЩЉ+B':АгМ„œ6žєѕшњШ/Ъ,ЬХIWіM>Š6'Чm?1ъшЗZlZjмиqГчЭTћ6ШјЋ1ek•ЉМІдrь<€ lиs€Йбь_Ш›e{ѓЪ`кI/ щЗЩ…_ИeкІœuwюоQЈљ[uACэ и`‡ЩЖM,­+Й_By„Х!YЕкYВNвU†OSWЂвŒ<‡0aVУ’5wa›VГЩАvMЉuTШ|кЩ™ŒрjУН}АЮZЬЙRоBнўћsИ'CžМЃ‡Щ‹Іцm{‰v~ОѓфЉ“УG‡с=удQžСд]енžzърПИщќіаŸCt%ЎНN|RђЗќШ(ПљаћзЖ0hо7џšW|^пk,)Ь&ЧЭэ”ЄC7ЮЬf=j(*лЁh‚xsmпОГMавe+ŽŸ8ž{БЦЦ˜–.[ ƒм-н­/ПкУ\?и…ІŸМsWIq Vp.Р4ЖбажGpж5?ХТ™*ЌђМx‡Ѕ>ќ>иеJ ц[пѕ-5o0Уя7.XИfеržэŽОЦРrџ.wЂAœЕNО8ШУРЫ‰qлѕž§ І2зНПю/‹џb0ЦН8.лrЪzRЃu’Й,mВЪ9iмАi7‹z:щSТз >Uтpˆ„PQ$cпŒнјбћ]ŸД~ЩЂ%ЋЙ„$'†mЬМБSШ"|hŠжща?НtцGDљ"э‹э[ЖЙчKа—20h(ЗvaОЂД[#П(Г0Y']UиЂhFv^“№иulЬйђ~)Sxсс…Ђrn—(ІъЩ3”i ˜%КVy-–ХœB˜­rU1Ю+m…еЫwкzЬў№§PИ8iжыГжЌZГ{јn<Р`ЁэвЕKUJ5ўvюдЙ  €;„ЩR&гЁќžI` Kч’t,ЫЉwusэ;u>ш{aїv+ЗаюеЋlH+џeёх,ю”3РŒљІ>?ўљlпњў‡•ѓ&.ЦuНDW,gYђалјDЯЇК_-Ш-7=ќњчЃЗиђp‹’јјЩ†FSёђцќ5ь™Cцr”xъžT,нА ѕ"[Зl=ћ№Ы(tгјї‚ƒ‚ЉK„…ЄюNХ Ы+Вˆ‚@УЧ‡‚Шm[iuЪєц!O3 “rЪHкЩкZи‡ гebnюо^ј:EёqquMˆwЬИ­O\Я{bМ,эUЖкЖ0nЃв};ѕ=c:†УїЬ…п5vЦ8Xаl&M™D:Бћю~ЪјcНюп%3Ÿ_)Œг6Р ›…•У&^дгIŸЊO'№q*У†Рqю|єAвы.e^кœДй&TК­ЂuŠGp@ЗnGdМ™ЁЯ§pУ‡Gэж­џhvk`Ї"9zИЛ5ђ‹2г,@ИлUнЖБ 3kyt—Хѕ’gўRгZЦН2ЈkEX яE‚к‘ ЩДn$&ˆL кЩЙЁЄЪašuХъ5аЩржЌ^SхMzі Oоž Ѕ F,ИІўхххXG…ц=/nyѕЗ!ІLž‚дИDя›жЌЌ|?ђИ˜Ž0Šвх у_˜:ў…ёу#ЧkН"ЧуvъKSЃfFagFдЌы5ѕЅ(о чb)|лћ зПGЯŽ^Бl)ЦbЌЏТВSl>p1žЭ-Д‘8—Е…‹Zў[хњРЁСРbЛ%гN‰Ѕ§|ю.Цх™]љ5АжeAСЏšsЫН(КŒ|ЂgoпЎDB:…“’"R’OJт@˜ЖиАkŸ&66ЕрДŽнџмЗTЄC'›§кьјїЊ[>ъу&Пе"ёуКИЪ>}QŸДяв† Bе5№€юзЏќEљ[К'ЌhХџюuэ›­cяЃ0>&ѓлпѕТцз?&†зТ-лЗtюЮЃёŠXюsЫђ•ЫqЫћлє—&€ю•ˆW~ж§їfйЫЩЏiwЗ.Ю™41fмъЕЋ_{}F6{ŠЊkоmШЏ?“iсЏ№"9o˜ZEЁаКPj4N>ŠЈЇ“>U9№ZЧѓ™“kЧЧЙHNŒ]ћбЦMмf8СХ ПфGuњмЈчоZѕоŸЇќбёћж;oѕŸ”[;ЭнбУн­‘_”™fТQWђд н]Ч&œ‚ЕЁ…гв6AЭ{k+X)ЋЛpњє'ёЛцŽLž’8Т‹и>эOv "FLЌl›Ш-qУ-“пXuЅ9a=C>нђ)]гƒ”#Ÿ‹ФњLЎякН‹NucZы“ќрoѓІў”ЈLљ7nйŸ,&рi(%\L‡ђS=А…] vrаKрmKвrQ‚ч З\]tза[„Тu 9f$П‚žB'З.ЂЭЫ€ФG@еcEЮ)р=ёыŠ`УJ 4aDзувМD ћЇзУњ…œѕ 9(зь–ЧэY‘s "/НтBrХй„ŠЃёGЂ+іDV|Q‘ЕЗЂДrY$в\œышl#жЅaQ Э !”ц ь$Ѕž™g3ЃчFcMЂc –0 укDоRБбЁNŸЌЦ“чСz, M3Ђ„0‘Dгђђ2kІk#?1†Мg yпЈ™SЙгyq€uЈ)д]ФЩWoХ…tзрA—OйєDfas+ r—–.~Мп'ђ§rДУ#X…Выє…єєk{ђF\ Yddбь&‰Gh.Юл8b}$–+Ё™СЮ]KдгqФx‹СИq gљ“Vf›ё„ФЙH6а oБц;bhЭ‚–БžЌžщ4cta„ˆё"QJPQEЧXЄ†б˜_ћ…14]жYыРnŸђB‚ЂwЗF~GЬД,ŽКЊИH99€ЦЦkpiћіbўЛёk(t5oœѓЏуд`P3^3п9Ь\fвпШб_Ы1нНUєгeгэŸYƒNуM|К„Œо}н^tXVfМ<уЬй3іA’GАsЧ дtkз­­щ!не!ьiљЉ[Г6єU щ ш0РЋУPVFђі“nЁGВў^ЮuїˆЩ@о8С­#lV'ЛYiЂЬmЪјR^РUдˆSў§­mЮ–6‘ˆѕШІFщ,dъчSO—эѓ Њ<:чђ3Ёјtљf’?23›ђ+UXiПXJДИ5 "ЪQ›'Žyš4y–@дЦш^x§s/ПFрnEhTœ%™—›ыžЁж•ЕbЮ2єШ0™\Ёю3—sщ`~ЧnŒ/Xо;~bеz чqЄP;ЊЫЗЮ'ђ3№Lн™jЧ+yд"ј)Eпоў5 .n{м‡Ÿ'%Ђ§цд5EїЄцжиъ[д–ŸmƒѓnˆЗ)ЧъкжфМHкмД-ЇЖЌ>ўv[M™ЗŠ0жMSЌ‰м瓇?Ы7Œљ[д ЈжTbZœд˜ŸŸпръM_"5мгиœлиZ7vfаA81hТј 0ЄЗюТ6^щ$ЭЌёАЕO9М}xјЈ№ўAcИлЛљЄя+dx)Ю#ADf}„жр“nš‡Ьф7нQюХ<4VЌI…hЬЬ<Л`BЏ ЛЮю:”wшПE9ФЋmЏ'zL ѓfŒJЁjЬœ›-mXђztяБmћ#qš`ГЁќˆeьžЦж*ml.ж8Ž_Чх"ГФ&!рЁР–жыyют]зšњœ‡ нњХТ>ƒV_Hu{ѕŠё+p5{I]œ­ЇœM“K=…”ЂЗ,БНЂ-Ћr$i%$$$$$$ЌИЇБ=Ъ66ЉСHHHHHHH4юilžџ]бцТQЪWB@B@B@B@B@B@B ёpяtчr`ГЎs)TB@B@B@B@B@B@B@BРm,fїvдКWД%žЧц6jRзŽлq ЇцjЁАЗPБы\y­ЛМ­Іt[Ьѕб Šрza„чБЙ7+*­ckмЅD$$$$$$$мB mlnх-1KHHH8BР?2Зm•ЧТвVМЇeŸb.дчќm:!_[ШVjДГB”SђlzетBцncУеGŒqGwG:Ч…Ъ”X$$<Ж~В€qj_Б˜ЩyЕVс дŸ9ХXˆž9ŒБйхьзћьL~fЭк ЩSkMAbp‚дЕIЧБ7?ЯтљЏВ7џт­ИEьЭйœЯыЏ‚С^iS<;…ёэШ%[f Ќп>ЩаО§гOOxЩƒ8BLчГxBњѕмгиj]ЧжМEТЧХЃgGЏ^ЕКyХrЗA уГu9ћџNи_І-kј…<ю‡‡Pя ГF/Г}эГ‰и4ЗЎdАiф‘rq‚­,J8anёA^ФЖRs9”6кк5†’Лu О ЊzЂ1ВЌХˆ/; (ВЧˆBщ­ђіЮ[ОВр_GFoKnшђ=Zщi:ЉLэwаО<~yѕˆрм”э)ўўјuЪ%6 Œ W)‰ъqЂaˆёAb)'e.<ШЕжЩєкк[Ји и •>LWиІJYb$f3,m‡ ъBCBcцХш ѕ‚pќ"ОщeЪ/0пеqъšJ'Їz2Bеѓ1ƒmM@€vЫf,tЃВT-Р?4$pќиQIы“Аш…†6#сЙЭђwѓ˜cІMšіJд+‹ЧХџ5 Aк”ЯSc;пT)erb:іV шXіЃь}sв'Фќ=&a_Т§YнЯћи#ж5ЈzЈЏпkА7іMbлєMн&G›л†‚нХ чБ6ЖŒ2ю ЯЏњZbmeJй‘ВсУ Ÿm§,zntmМRx Щ ˆтБЪЄЬП™Awє­HТ0,ЃФа ъЦ–5ƒЧЊŸъЂкнb=IДажоBХЎ›2™Щ“/цЖ%dєsўНUфG )4Т:%ы™‹Ф‹џ]Нџ€Оc˜ю›’w&Я‰™sш№Ёњ а€)шOЄЫ Ў•ЙЧ?”ЋР)mTћ|ŒШ8K›ЗЦЏ}оОд^‹ЊЭl|щЬfГюІnoкоУG|ш{U@3oS№иf‰Ѕ&Ї0–r668ие№V Яз|.‡ПоMІПgЮЩ-аћіš,Ј^ ћZч!Ъ6§<ёщA&ёзSђ•эzрСъЌ7А6щБи6Eс]ЫЃ•ииV­YѕсЪUЎ™dœЪP*•јЌЛв_ šЦ‚RœњEърˆОМесДM2ѕр!ЬпU:МХі ыkі0уP•tњ7иOЎ№ЦEєхDџЋ+ЦГ—\{љxіёУЦŒнЦгЛЕћ6чьпv`ўА-cлбb`А^ЖtY`РОaЁмыW•…€<'НеФDЧ€?P5+ 1ЪђyJп№О0Ќr>ВьэъdyќК’Ž} Ёб=“hЁ­н‘иž rCIх?2S!#ј0ќC–Нќ“йl"уƒafГЎcГАЗ|0^б^БtбвЋWЏVJb!+W,ƒu зЪ+yѕˆoојх žГБлГўъЮFШ]Fют4ЖђjuЭ‹Ш рEю1ЂђWъNЗGR&“с˜Я+WЬ|ufbR"e€)єщPєєE‹бEГ/QŽсŽšecчKKэŒААcў4fкдiЏЧМLж­OZћоМЮ—‡ўoGХнBsVnЦ%п^oЋ‘‚Й[‘—MZ6ЁЭТђЛфoЏўMух эЙъ‚ЦІЌСп˜7ŽА­%Яz7uG ЉЦ#C „шS†яSјЅbа[>ЖЃŒЌ-v0ZђЈ‘Ѓr/^Hћ:m№0мZ•Ж_%pOcѓX[ю•мQ‘у)@оыYЧЊхУдђЁJ2,+лЌю1b.жaSƒБћgуЖ’J й—ВOœcкЉcЇОIУээШI“—ЧqJH WЄгёзЇгЈpъвЄ#мб/:гиMшччg““PАЂЛКž!ПYY~Ћ]tЗˆчGD,ифiX•5+г‰œyРŠŒNЇ ы† ›єЅ[Q(ь‰§ %єсˆН#HњsD;YЎ›.Ч­v21ОЬ]ЇŸ#{ЧШ“šаF}ёЗŸж,%ј ›[оеФUДеЁH_YЫ№@ВHr’,Я`“Žh с9=ф—ТyZPkw]lgбJї*pE ayСя7"3dВ6!Х8х-hšяЏy.‡њP]Hp}>4ЌOŽЯћƒŸFлFjЯДtщ/OбЮцЎ9бК93uгЇhЧDhћ„шzjtн§tСšЂžмeьЃ1ій;b$ЯFTЮџЗ КRўˆAa˜*х™%ЦА>е=]ДDuУiA—Gѕ&Ё`-znмщ“ЇsЌAкŒ™яGTфDVЄhŠ>ж˜Вpn§еОJŒ)‘gV™YБ/ВbїШŠ=#9b$чsvaХЕјŠЛ `ЃQ–С9Ж|О"Mƒy§šК“†$|d8*ИЭгAШf#­“Œ„-жy—дцф8xeЋЁдUп№66GПе|L%ямUR\R9;f•3ugђвwW№"+•Џ 0Х?ЌZiћfьЋпУ"ЙѕIы—,Z‚ .Ÿ'Š6@-Ч<–ВСР‡ЙQн’mсliиШ”^€mЄ›IёŽh*/У/uwюоQЈљ[uACэ ˜ZWЏ]}1ћтУџя!*hн*С)HV­v–Ќ“tD[ˆН$тгB[ЛsБ=лƒГЎљ)ОЄ2–’‹w0Ѕ€Яэs5ие0U*\Л&Ь—ZЫ`cK§g*v_ЅюNУ}~џ.wнžБa&А” {и_ I1§т,jp2І-&CnŽЛ5тгб:@pw"N_ЌoпО3PЈЛг`ЅA‘ѓєtб5ШюМY6^О"Xˆyче Ћ ПpЬ—TјгС Ќё— П†„pnџЪ‘HішqюЖъ /2zЌвj`ƒЭzU‡5"х['зГЉ;iHТG†P'O!› э$#aЫA,с-UBhjюЭŠzђ^QZ$:ŠQŸjТBRwЇqо\‰_аЩЛSЋзUTГVSЃG&Œwвы.e^Šz9Њ:@Ђ\C я—2§ƒ2 гF>РO>F-ŸжMол[а6VЭm e#Zб>рŽh‚іF]gUg,рo ЊмЖѕ"XтЦћ wЭz}жks^гfkQГЗѓo;ЊжЮ:ˆ$Kѓu1ЪяЁD mэuлCЋРБ œсб8фiFЁ`і]bI;š7™]&цъ­ Šїj$ЂIb”Чj~ИШ‡Ђу[x{UЅЂ#ЗQ=U}њ1{їЬйЩЯџ%l ƒУ}ШCnє1o†ё&омХ<юmђVЊ†Œp"LъžT,єскwъœћŸъaœ_эр$nŒсuj– Џ“Rе bKM‹пXМъ§З}ђГпIЮeњБЯЬ"v=ЩPGk Y6ш/;zН§EјšЏ‡~|˜ЋnVTId>мEšфt:aЫ—ЉžMн톄LыіtЈCFЂ•цžЦцБыиDЫfя™і]кC„Л@їызўіЬBŸиХБmмД$vI­CЇ0–DW"а%BgёcНф™П”ИY–qЏ,ЯPVd§LMP;2Ё#™жФ‘ ЄC;9ЗлПЪM™>eХъ5аЩржЌ^SхMzі Oоž Ѕ ЏнёЫуЉyy9ЕР =/nyѕЗ!ІLž‚дИDя›жЌ\nŠ[гБшQ>-ДЕзYlпua`Eƒ эк-6[ЧоG4‚ылпѕТцUе:ЯZSУвћ-лЗtюЮsЂуp-ќ>зТ—Џ\Ž[опЗН/Ю­Ќ5ЕdšёŠОрgѓOЙ2˜НБ'Ќkјыос ЋЕc˜Ч•фqЅžёš4е>ktsl[ЗvнююŽ[ZйЉqRњŠeK9­дBђnфaЁН}DŸzŽсun–ѕЬзІNnйпЩтИХ‹-žїцМ\]‰БДщ4б'lЂUa XNШ­,:˜<хАБљp——‚4Щ„RБ…рѕlъuhHŽž6ЫцЖ Ћ…вюil-ТЦFЫfOьHо1ыеY6ўѓцМЖcЇuХЅM€р‡Gїщ1Uњ”ŠзЩшнg–ž.^zДdкжг^—…Žд=Ђїђ3те*ьНIвя‘—ž‘-3 И%qЪvЪоЯє1dPXПАЖUц7ь9ќ§срЎ]^|сЙCRI6oкќ^ќ{ўjџ_˜4А_Е?eр‰ЫV(}ЌЩ!іZяb:6Щzкm mэuлг№wKžТRr­Œxћ0Икњ0œЉУЧяЕТopя`lЭйБ­rу:ЮЪAzуъиЁ#nљФОЙpи˜aЮ7fЙ­,Š'ƒ4Г^бУЎfyШютд5ЏЖмd(gcc8Ч0ъЉ/ЫjžмС•.Р?Иg№ќХѓСyти њВНрa#fМ4)АЛџќѓЧWЋLѕУым,ы™o­х2|ќсІM7mћdл?ў0tR Ѓ~F*BsліЋІDљЃза№ф>жKaUкšТЦVglQЂz6ѕ:4$GO›Юes[‡ŒDъ‹?`лЖoopP№h—4ГOoBи†mяпь>ѕ gFLš<ЩѕѓоšНШž €sиЭe&§§Егн[E?]6нў™5ш4Xаж%dєюыіђУ60ухgЮžБ’|„8‡]Шщˆn–ж^БЧ3§mЪјR^РU 7'Uў§­m•ы,=SјZЅЊQ: 9:k*I?„Г<Иƒ<ктkuфqo\Œ7і$*ѓММйА№••‹‰kMМn ukе5 RЇŒы–o­Yй†Я†ўiмГ>О ™ŒёС<ƒ\ЁЫ9]FжF;х‚%ё6пХ—рCТ.ќHžYЕѓЋœЩќ8zhT‘Yе5ьѕbѓцNhЄ/СлЁж"K yЙЙЎНЪUAхсп­ГџІ}•–ŸŸ/Љk +ЦuŸЁИœ'‹йМЌршmЌЊ?qМsf)ДўH­Нўж-')ШˆЗЉ\™_ЗT<0ГяNЫнž’Йю] yЈ‚„˜хv1zт­ЧйЙ/ПжЋ–WJм\­К)ѓ5LТz™I;–aY3Ћ•™rš˜Оћ:КœU“АкlXЎ-Уyц˜‹‡!ЊЯ3:Œ&4юil-}[†aОGїлЖз8Ж­щHQх+u IDATъ†€FЃ4d>7aќ:ЙSЗЄЄXЕ" ЕіZ!j$†‡Ьф7нQюХ<4:{О6’lЏЙбA“ГgWЮgи‚{ф1ЦЇK7еРˆ“ІЪћИCŒцjеM™/ьg0Г9AЯЦРЦsš~ЬЊœƒqЗдz’ЗlŸ“tЄ цEР=эДБ9лyкМUїhфŽOSрz4ЪкќЅ”Z{sеі4WжM–ЏL­_Ж‚8г+E–цjеMœЏЈNцаFšыt’ЃTмлy№киъБ”‚„€„€„€„€„€„€„@=pOckщ{Eы –]B@B@B@B@B@B@B YpOc“llЭRIRІ8ююс|6ы>тhJХ—hx,fїvдjck­чБ5<є@Šвq;ЭRЩ-і*vЋИu—Зе”Юc тБ‚Йо#ZA\/lƒpт<6їfEЅul ‚Л”ˆ„€„€„€„€„€„€„€[4АЭ­М%f  ЦC эJЊVЏХGqXщ+ƒ^7•щПЪњj zр˜а ЉSo•мђiЧDѕ‰QЩUвзrЏъ“Вdnл. юЌYТвVМЇeŸbК’Ы^Ю4п-bKј9Ою шш3b˜,Дe—Ћ>Uм qёѕбtв љкBЖ ђв‰Ђ@Е OAeК Еѓul.$аX,8ЋP˜t„#ЬZЂ%<жb>sїЬе’мWžš•~#}KFтSЊžЛŽьќд‹|‘“вѕ‰n‡n^2ВЦИ?ЦуАs™їНGЩym§dуд,N7ŘЩyЭMaю›єGвЭ8јwю+–x‡€cK цlƒ>;K1dИbЪ4"—Z —:§(žТјvфЂ–k 6C_јіO?=с%W Ќ<%зt>ЋNiK‘<ї4ЖZзБ5cЩ$-­С—Ві@Іѕ‰ърЋњ2чЏ‡/њћѕѕCžОЎ 4a|”>оГњПІT0їJѓ‰_ƒ6ЪмзƒФсѕЉё:#Mœ "Г‡&тEМ9ЭЦ\Ѕ­ъƒн (jah‚Кv5Y;™IoЬЛu6Ц‹(МИя"AЗ0;BJєŠЙ %Ѕ­Ю•ЫtъЊ/щ`fYЖŒaK™М_ѓп-К4…м?D|4JвŽ!rяGMcmоЂžu†Нщ#Jыиšs)G І@€3›Е!о>DэЏf‰!$ kqiqИzЈКНšШЫWe-КVzyVиky…yьяM!”‡Лx[ˆ’˜ЫЫ`8СAesW :ёыџ•ŽVтХ€ГЂэ˜№eoїzч}еЫЏБ:bFЖ5іJ–љлНuJž‹„ЧpуЖ’ˆ^Œ™]PoSФИgоHктeh;ЄLyЬoя |у]&ї–љћД’’ Šс ѕоФ2ИЇБyВ-єща@џрaƒЗ|ЖEPЇтdЪіџќŠKОƒ€{уръ8Uиахх&“)$ ь„iŸLСЦ\•~;ЭЧз{UФцЏ_8ۘЙElŒœŸЇrœŽгFГЄжЂєaКB)e‰‘<4šЭPzАS3/F_Ј„‹рёmL/ѓ•\NKуд5юWС0ЯєŽPѕ W…ЉGVЭ{<ЦŸXРž:BrsЉ,Дh=ЃfFфа {Ђn6нКЁсЁЭ’e?Ъо7'}BЬпcі%мяе§Мпс=Тa]У’Aряёoey7ђЂfEЁКЙŸ…[ћŠЖёЉ[Нл$RЯлКЩPЗЖQнгиVЏWВ&@Л  `Ц‹/Lџ'T7./Мј<› ы–•…{›'лиxмƒž кВ5%uwЊ“jШ8•ЁT*ё}qЅП4х„к›њEърˆОАе; ЇХ hъ”ЉЄЩ:Иhё": K$Ъ€Мж}АЁзІ|ЮНЈѓQ8,мБ;:j–HФОЭ7щГУ\ŽЗЎe“–MhГАќ.љлЋгxy“ъ ›в[ЯёйœД~С›qSЇGЁКqˆ{3n}вz^B›:ЂЗ”АЏ_aб№(яо7ѕŸеZ+UƒФбTгq|jЂMЋZBDьeуЃр—'„Ђ‚v4ќђlюilkcГ)3!хv>е;?п6;†{c›=k6шъBЮŸ?џЭЗпkѓnGN˜ћN,‚Ч.о˜Д‘ђ$nJ\0šѕ‘`wЈdS …iЬЂ/rўEЬ%ъ(yМЯ rсPRИ^cњюS ёВвBr~+йџ1UOЈН5{оыѓДWЕкkкаЁ ЋуˆCByseГяG4ШEТIkq1…Чц?ђ‚яуВР‰•кsёё№;7L‰_ш щпСL˜р#ƒZ#ц0ёД9Љџ ў|рКѕыюнЙwюL6Ўќ;љИ…#е”˜8ПRжl2BO Ÿ§ЊњеhsЇ@NicЫe—ЮlЎœ Q„>ƒ™_гІЌШИ ЕlЫж-=ћєDЂ[6oЩК’uђјIДL†a>NфФ‘ŽЮѕŸЎ#т•KWŠюS ›дьo4Kћ6пЄЯ‹‘”t)ЫЧнНїЪ­Апэр„їbˆ Л;NukубfЖcЇ>?щy!рИ§ёєB'Д}§Rf(й/L{су?††zКX5WВЏœ8zЂИт5-šІ#{йœЗНZ†п"ŽП>н˜~№@Em.§H:XDб‹j‹нXс п\ЈЭгVќVЁгщЂ_їVœ0'Ё`Ewu!=CРЩЙп*@ЃѓЬ~~~FЃ‘ЇБчFгбЇ#'FА"ƒФУњ‡!ˆї—~# СюŸF Тž|–н›ХЦ4FІC>6ю=Љ=Н'™Н™Щю‹c—kиO"+>Ћx?„ћеeŠЪƒжЮѕЋCђа[JP6б~$ŒkO ХvоIi.і‰Д ay!ЖпˆЬЩк„у”Зt iAxЭs9䇈]шB‚CИ1аъТњ„aАтi~дтi№ѓН­CM SpDгвщ–ЧуJŸ3Г(ЋВКt§Ct=5:ЕŸnЩBn(.5{њБ§5ьф‘4AaбP~”ŽІЛYY.c‰1ЌmЫtФ€q›"Ь‚вŽZ08o–ЂH6оГC(˜іUbL‰Ќ88ГтШЬŠ}‘ЛGVьЩћ#9ŸГ +ЎХWмM›Ѓb6‹ПА~xкђe*Ъoєlпny.ъяЈ~wэо…Ц““Sн}h”ZЋœEњJнй9jZ4AG ŽdЃuB‡_АisrмЖБёЃŽ~ЉОйФФ ‘/Ь_0?Pэ?iЪЄЎ!Ё klпНЈ<Щ;w•—РЮЩЙаЉ;“i(Vќ№ДL&{Шэ ‰}3vуGяУFк%‹– ˆђK„‹HАЛTВМN4 ™ЮDŽщ%УxЫm 1ѕŠ–•heЇ‰O€ЌS7ю-мb5l(д4ым+ɘ5РЌ(КH—.]Jю—а  б~фb\А9o-ЎЇгR89ыšŸbсLnШХ;˜ПRР‡пgЛZ‰С|ы;ё3fyг&~oмИБpСТ5Ћ–ѓEОЃПƒb<­PпП‹DХ]=kJѓШQгЂ:bp$hC8~нгиЗ2eQ'm6Oy‰лm№x[rњ9J”эe~ЄO˜Н(P=1пєVм[˜mпЉsюЊGo~КJХCчNƒгmКNЭВщžxяbй ПьшѕісkОњёan›U™w>нcШАбїWЏGэр–CЯъjyея7п~ГяР>бC!м­GM‹6$G ŽdЃmGУ/ЯцžЦжrжБй€Py›і]кCTеŠ3ш~§њС_фѓ!АюпўЎ6ЈфЎЪЫ-ікОЅ{pw>Т”щSжЌ^ƒ-#И–Џ\Ž[оПakЪс|†#7ЎБg/0gO™`ЌкХЂўh3Ѕё†ЎF”JYЧŽЄc=V4M˜:† rраошйб+–-х”Q Сщи|`Уяˆ†р€v  шInЁQчfй4ЯЌД]ˆ—19ll>мхЅ ž=5ДlщВФOгОJEсJћ*-qCтЂ…•ѕыhфЁЕ/ZПEЫљ&э›/RSDЯќrЋj5-*ƒ#QйœД=GУ/Ÿ‘{›Чки(jЮ‰Щ;fН:Ы†gоœзvьДЎгД м2^LS'OјIЄЋHАЛŠTƒђЉВяЎ™™6\ЂїЪHG/гк0]tЗ<ю­у™С„a ц˜rю І?#3ЋOКйМiѓ{ёяљЋ§Бн~`ПT(lС9ќ§срЎ]^|сЙCЊ§БŠtи˜a˜ЋЂœѕ!ъмZъ“iГЧ-,%зЪpм1ƒЋ­>ц’Dќќ ~ƒ{Ÿ=vЧЖЪq,nIœђ х НquьаЗ|r [SЎˆ(ы.‹Х‡ѓЩ#yЏOжџы ЙXеMіDшjœКж!€tюFžAz…;JsњŸЇяјЧџ[№Ц‚А3^šинЫ`ЦgУяˆiБ‡fјШс}њѕщаЉЫ-4ъм,›шйс…/—TБŒ ‡&$їБ^ Ћвцб66XRП§ц맇Ž %wщк/Š_э§ '?№5хhфсCё+ZП|(”ЖЏїџuкзАдR~žpЋj5-šІ#QйœД=GУ/ŸбАэ€Ївіэ  =ОЦ~ * O8џЎ(іа…VBlБyoы/;˜4yвѓNСiо2z`юьЭR)Bио _fqѓ˜]UЄw§ѓ^ЇIо~в-”рHжпЫЙщNн=b27N4ћ+ИPьfС­‰3Е)oрKyTP#^LљєЗЖеwбUЧ&ЛЅУWЊ–, пяцx“3с=Ё-ѓИ/yм[цз‘<KIА‡tJЉZFl“Z­ЗX‘l?CZk,WjФ•v<єь †/С+†„]ј‘<Гj?Lу0уLьЬЃ‡FEЕvŒzБys'xд—р…EЈ›…Œ;*vilc?pЄjЏэеРФz“—›ыкЋ\Uд–ncЋ*‡{aЁЭЯЯoьжуžLЗ{§+Y­ Ф‡!Н§e*_5ётоЙ‹Я“бў@‚Gsъš"€;оГ'Mъ…чЇРтќёі"х}ƒћ@*Њѕ[Ь]йнлˆх!ёjЫэ3№і–СР] ЊъLЦMЈГК†?жэЙ/VSФhтA,gе$˜ж АaсЕ л0ЋŽхxШ{сŒˆmхs]вБ›№з•Ўѓ7gSbІГ*ЇЗ`І-Е^„ф-лзd…mиŒАЛѓrжх†MS˜ZCUMгЗ=ї4ЖGаЦ†эrТš–шІA@‚НБp†-­зѓмХЛЎW5–RКb`Ÿ˜wыђУšЖ> поnщny&LM6ˆyд\Їgж…T U5MпімлyавїŠкT›t+! ! ! ! ! ! !а"pOc{ml-Ђ%!%$$$$$Z7юil’­uЗЉtž‰€{Ї{8/іM8gB%$$$$$$$мFРbvoчA­{E[ыyln#+EРN%O=ŸЏuWN …Н…Š]чЖдКЫлjJчБёXС\я­ ЎЖA8q›{ГЂв:ЖС]JDB@B@B@B@B@B@BР-иЦцVоГ„€„@у!v%UЋзт€yBиWНn*г•ѕе@ѕР1ЁR/Іо*ЙхгŽ‰ъЃ’ЋИ36%чyјGцЖэ‚Ѓђ№ѕ!юЖт=-ћНIŸv%-ыn–БдH№хr/І3(FЅЈўаГчU‚$‘„€!роPэЩ66|xMТš~ќЁ§уэёб_щ žгЪИКЕ!јˆ›ЌЬgюл9іwжdфўё!Kc—кБHn#РZЬgюžЙZ’ћЪSГвoЄoЩH|Jеsз‘Ÿz‘/rRК>бэаЭKFжїЧx‘.ѓЊyаЎлЙIЖ~В€qjgЂZЬф|УЇп”)Ь=xъц)hiо oЂРG0‰С\~HЗ/ѕrък1kЇі—>йм”Е!хеRpOcЋu[sСPPP№кЫ3ж$|œВ=ХXbLм”(ilЭUЂљт+ЙЂўіžIы“ь=[‡кnЈ“]dZŸЈОЊ/sўёzјЂП__?фЉ!ёсы JѓЦGщу=ЋџkJsЏ4_e-FY БsP )с -•њ ,lЅцr(mUŸљnРВ4†ВхT>—иЉƒ‘efc9 l„Ьюіg†јшЭњ•qћЏэO}5Е‹&%ѕЈ!PŸЦ\ŸИMŒГ{›Чкиж'­_ђюr^Њ/вї ыи#pб‚E&S-цƒ)Ю?РП Ђ”ˆsXыУFЩюj'УЏ7жVyYgFXb` LmлЩ:?СMЬёЬЮ”B]E*ВМн!$ ь„iŸLСЦ\•~;ЭЧз{UФцЏ_8ۘЙElŒМСО=ŽдUйjу“:Љв‡щŠ>QЪ#yh4›ai8@M]hHhЬМ}Ё^.B‚_ФЗ1Н юшL:Јk\Пцф‡оЩЉž“КMbJ}Ž:™ƒхС}ŸъЙ9sКйШвФmР|šX$@Zы-5r”MщрSk4хЌ…x u‹2r.Р?4$pќиQ˜e*0"уžЦцБ6Ж;њ|сыФЩй—В1:ФПяЭ”)>м€_чlRhУ Р?i–KA? ^Вr"Г.d! ƒ яvВ€'˜ŽО І74Œи-?f@J…BёМzZWпnЫѓЇyЫЩџЁ};)‚26G+Lœ‘Cс‘_‚d;ЉЩLАч 02їЉВо*ЂДr#‹^г%2зlЎАUтqХЛsgЮAi›3Gъ tњЕtЋКf„ЦЦю‚Tх„ Vє>qZщЃ  fх№7tїM=—j#ГЖЩДz‹v’qъ(ўшБЃ№ЁЗ­›рzqaё•lэЦM[Y–1|„№эKˆƒ{›Чки|џЇmќђx<™р Ў8tРIgœЪP*•QЏF)§• )'”йд/RGє дјCеХi1š:eъСC)p„%Я\fІ>Q+|ƒc >Шв†a ^ИЩ=Vf ВrL‘ДSј*КљЪ:ђ66ŒоUЕƒз T*%эЋД*o‚ЗаЇC5‹/ЂuъKљ<Ѕox_ОІ€ю[хSKм;#„…Ќ\Б o?ИVЎXiЕp‚ˆЖ*a%a!Ыо^ЛoпАPЁAЗ*ю`ЬНx!эыДСУpkmx7*OЂ›ай&юТНFІ~жwЧШЪ^Wџu„џДщБjyаГОbкШдƒцьFХПHa =@vHbэЮdВтeцЅ‚|€((z|Ј“_GдI”Vф?2)d†ШВ—2›Md|0ЬlVЫ”…НэрƒёŠіŠЅ‹–^НzЕБFk_;`ЖёЦ+…W`!ФђЕІЉЇMя6Е”AL$ыRVя~НuD›Svš:)чцюА XШКжЁCIE—ЇEё$ŽЧ Лf)ŠPаŽDB\{$Ѕg‡ zЮocЧnњфo”чoŸl„НеФDЧ`ј5+ЪtПrЏ5ЪfC ДђЁP5А‹Žџ4–h..еЃXCВЂ ƒfgCШd2œhЛbхŠ™ЏЮLLJЄЁBмги<жЦжГgZ<XЎыФэќ|ль˜й`˜=k6h!чљѓчПљі{mоэШ “cпсšЫтиХ“6RьiX0СџЯоЗ€Eqdћз~rџ3ˆ{$€Ђ>ТC >ЂhL5ю‚W№q…Ф(Fзˆ1*цЁ˜ f зЈыъ‚YWЬ7jbпКQPƒТF&т "У ЮЬ JЯђёџѕєP63=ЭЬ0Р€еЖУЉЊSUЇ~U]}њдKсСжQH'№б&|/q %DKШ=оДІ$ %ь?]§”=Л№6L„”9zЭ[8яэ7пОѕCхgОЬЛœ'јcхiС•‚S'N_+†.˜њ~*хПrѕЪЩc'ёЙїB\ЮОG^ЮОьищ ац[^ISˆД iїюмЛ№ѕUмЅwJсЄ –­… DЦ†4экЋљWOПpђ_'ХЁyЇO}іЯŠKŠЇФM™6cъщуЇ?Ыѓvєф)+’M§”`>СяŸЗўyвФIтш6в*Ќв[єQQъWФPр‘тyƒ\<’1DЈџ|+цЎ)ЊЫIоvr№-"’„96*3D› 6•№|ољ“g.mХНŒMЖ.+‘yHiЪэŒ№Кш§kEа$“і\ybШњє4ЪZ2И‹ќЄ‡&jЉ п$[23uƒ’VВvmУRЙйсWУiu„г§Ђѓ#~‡і*О ž6П‹20џl>іј QзYЕ—ИqJRУё+шe­  ЄзПЛŽрЪх+w+~IO™чнВYJтC…k"!дIію0COо эЂќЫ‹Ў№эџтЅ‹хZ­Xп˜™0{ў+ѓ‹П-FЗж',uu#Уh4/гKСиБЫД_2[ъQђ‰вДlT6kDТє„у'ŽгP1ЄB­ю­гsЊ“Нrц"мк/ ”нŒћьO~#YgМ’—&'Н–$ЮL,XХ]uhПаКŸс?зЦ3/0ћјј †’иеG Ѓ'E2"ЃVЋ#G H№gПђPиQ5рL>Ц%хтpб{ЙЈн\dџЛK:ЬЅуROё7ЯЖ”g. Нgїž Љ‚ЯШaъ›jЦКрˆЇBеG9С98‚жrфАHЁ–m‰+ЄF#žŠ@Н NЁаь$[ ђ‹уBBЩИжžРœ>?њwб\Е­­ŽТŽш™чЙ§\Ъa]t–.є}нўSХgіer7ѓЙЩмŠ@юƒшКї#ъж…ђПъ|!;ќJТn&Є™“>,ДŒBjpŠ@Ъ43B,ЖќCJSЦ~ IDAT6KЁm9Хх…ф>ЃѓCЇЇfщbпPƒІeќWH}(lХWhH(>„P™FKЃƒ@єFлА˜пvš–.vGlвбФЄc‰љъќЬЌЬј™ёxЂ ЃFGсI?TВ?т‰8K"Я“ШГЁkLЯ22’iтЧŠŠ$щ)ѓМK6KBZy‘Ќ!й|яБ`f2ЗЇИђћїэOœ“љad ТВFр‰W0џ7^”‚? Ѕ/јШДq,чвh=Ъb’џ\№шeAe+.,tФЦ&h|–ПT%ly{yuя2lФ0˜йtъšGv3a2wяЉЊЌТ,?ўђїН;“ђР #аАO>Ќ7і,ymЩІѕырЯЏH]ДA”ŸЖ  еСЌ†)k ўЦ 6ЌatS`юš—JбUЅ№ьЄPRмx`Řg]эоЕћдщSЃЂF NЇ8”Ћя :иXОO†>‰)ŒѕьФЯзO zєълї№Wќp6~==+ˆAл—І&w4w:Р?рўн;”AВЕаPwю6ˆ+Ч…ПиIќЫJЫПБxWц.ЬК‡Џ“@•B­'ЧеJ/ЅвнCY\Eєс‰ŠЊbХщtтщЏшж‹И)љНLy Le) ;Я"z:Ьœb™$ОЌЁ'ц1ЃхR3цvрф­k>ЊЄx~Ш%Д//|„uАЋUi З>—^C-˜3ё{уЦЄ…Ikо]! !гhЭрзЉL%šХВн‰<ДœЎ†шv\_пl eІ­K{}ёыZ­vќяЧ_­=mмЉбИЩ№РП“MYІ №•џЃц*D‘є”yоо,%‘dяZЁЖxѓЭ7˜†t­№šйў\АНatЃЂшљ{єшQuџQЗ/Ÿ2})€MІ=‰XЫЅбz”yт$†МЬšJMчЮн%yьги\vЪЖpбВыџО~ыћ[[ЖmЁ™—Й–dяЭF­аžtцоlљщ5cЧŒ%JїŒїв.ч_N˜™`ž&s7†ІБ€%s<ЩŽ!GІугШё™ќoЮ dЫxВі9ВђВrџ‹‹уxѕNИТУУё]Žj]џЇѕ‹_C№ьм­{бПе &lжГ7ј њпvm‡зпvn_є‡EvХ'днЏ;vћ|ЪЪЫ:ћI?Hт(”юо­A\ъo#ЙГgЭиёСAнД1eƒЎрMО(ц—шbHкЫQЋшЩнЋФгG12‘xt!nЦ?–}shDIиiЈНDєКй€žCЉНRЙ?”3шЭ#~ЃTЉ”.sЄ“Ђ#†>•Ъ“Š4изЃЬ'Тљѕ:Вz<Ьж8wю’Ре”F+›нЛ МЇ/ПЧ•ѓрвч•Ÿ<;cш„&фхчѕэп—tуTmхwќ1оїя’шО1І dлџX•›I*ЄЇL_б2Э’Н;hйDИ‘… “^™ƒЦlжцgН2ых9/_-ЦЛћvщmљWЖЕМdкƒХZ.жЃsŸИь}йтѕЁттиЇБ5O'гFшœЯsF !~џ4hќхK€Љы7m^КdЉY3’ХBj~вЦМѓBLLtܘчwt œqгут04aж\у7=A0Ш БАF&ссЌљйh "$qvтЪхЫјЗ–р  №Hт<ђ™‘Z-—§їle'/LчxlŒ+N0vZьšеk <сЦYpŠCхщи)ЦȘdt_Пf•Щў!Eš8{ц‚з—†?%m_sJгЕМђЃCЛ/˜/kЙ1о•‘оzтJК !UЄЊ”ЈМˆЗ?QvOў”„]: _яЮо|•‰.=у"~Jуш9ќŠђlK$Ќh•џ Пv‹ЛЊцюCpO[зэЯУБјРЯУж‚`§ЭЖлz‡є"XkД–ЕckŽђНљтъяo>јО†ќ˜swћтТЩ“цŽ_НvѕЫЏЬИЪІъš{ђуdъ…|фл†Vё$ТRЇ­5Э+•є”yо%›Ѕ >ђ"ЩРУо2рX%Ю[xЋМ2q^ЂYPMM f-c€ ‹’W$›…кш”iB 2ЙШзЃЕ'ЮFС6ƒС€ѕŽhв{џО7y™tэги\йЦf 4f~8ыЅYfœѓчМќсюЭ<Эœ8aЉOh3;­sZCрШGŽќ#чШ?Ž€8ўOўŽ5* гЫ0ћ${w6Іw6–€І3ўљё02јОЛњнй)јуј„ˆЁ‘3ІOъэЛ`с№P~3bС,}kщќѓЉПэqiЬЖёzТkигpwэвNд(БrљJь_0 џ€бЯ‹1КQ~3†3ч/Оњ‡W…ё_ќš…6ъєS)>ПfPvря= ]нєk#д‰НJјЏŽўУБ`—xУ–SC~!фї&ёѕkю‘„НбьL!}vмГbi#‡FŽ6NWЫ–7ОEЊУЉК&[y5Йіл+qwєФЁa6‰IлFШ€LЅџp‡ЉГжh-kЧІlšРьќbџљUš‡§DУЋQ>аЛU<=rёц87lYТ{B]ћЁˆЌžай4ж)пА*sЯGEzjаS]КuЄ“є”yо%›Ѕ >ђ"Щ Фо2риДeѓ–wRоё №§§ “‡j{D1ЇL{иdr‘ЏGkOœ8wš§}Cњ…,XМŠщЩу'Хv%qФ_aйрЮ9А?$8dlЬqА]4дCjЬА+bs37]0Ќ+žхъSƒ­­ŒжХŽПи ЌДД”Љkv@fc І@Мœp GBЦђъšЪŸ?Љy46чЅ§ЇФuР~7Ф7DЕЏТК‘œy9лNo[}тЭŽм§ˆвИО‹г“ћђ№уў’0ЌО[h_EgяŽіQŸЎSіilЁК†ЏБ>Нћьий`лЖіб [ЅL3kIиƒ}Щкё gСуxю–’/’QЩЄВ„ј—<ѓ %jѕМўd —љсŽ7хCiwаV—Ъ‰,|nсФ№‰{Юя9RrфћŠBтж1ќ‰>БС1s_›ыЇђsbFЎ“{wИN]4E—ЊGћ4ЖЧаЦfу˜NS‹Ыh9`K ŸРпТеsHГfЭсХ:9л.ІЉ­ŒY‰Ле‹а2ЭВeriu0лН.Uі­€Ущ Е’зФФZ9њсЂУЇož†–цЎr'*‚Bi 5GдВПЩ^;nmмрИV–eЯh иЇБ5:­ЕŠ,оу.kWV…ІТš$8 жZ™Ц† 3Ÿvу„‚+FЌЪеІaoyИœR#SŸJштэїqсп^ВшЏз7Œш;"eHZYu‰Rщщхщ>k№Ы^*хНъRœ.ЪеъmdпyZ”p V.šєXиЊ 5Pк`hsіеBж’mЇ3pWPЗ.:Žгt50А2Лз)‰ЇЦ Yu6љрЕƒ-yЎЈГdщ9j™„ДXFЮШ>ЭemlрЈ%YЭњьŸ=ђБ v–)–|œгV“ђjCU5Ёrsл€А(tы{8{›{œZe‘МйЌqї$ОмumЈXeuх€‘њZ=ёЈyЗ`‘’ИПБІЄМ$РВЫхpЏ%^ФPў66ŽПлц…!xтЁФЅЋ5Ž]jh- ьЈ.аћЏО.?9уЋДeу[џ8„Ж‰ёу"ѕу№F/Ѓ}+\жЦFlЮЇ9#žсч+}PgьѕМ”„П;)№ыŽI>nF=GДСЗlЧNŠюO№#D3M™#р0ьбИ–ъБˆˆ/Н^ъqR@Ётц^“{;Чгл§нШ-ŸОp^iр'Б)=œvіИk$kg–ЏП/~‹š’*Є—ЇВ'КЂjŽшШCСK›шдє ›;ЎІ\# — С/слœ^eїЫдz5д5Орх‡оЩЋž“{MVV{=r2‡x„ ьлoKўfLt3“Ѕ…л€-јДАHf€ДWЇ-ШЃьОк>ДŒ’˜иЇБЙўZб[7.њУ"Ће&tyJцэрEEм5DaœQAДЕJXън;)ќŸPvѕvк ЬЊ$UƒН•Њ[P•—JЅš0ЕЇwЏЅSн=ШгО#Лzw VŸн’ЈвѓF•KžŸѕaжЦ?mФo+зjйъ k‚Ђ‹њіQ №#^ЕЄFЧЁГъ]фћ|‘X,tюТuсы PкцЬ#u:їZЎQ]гAcуCЊТ…Јœ9{ЦЫг+$"„ѓ€ПжПЗwі…l3™]А И Hf 1g;FР>ЭХml‡юћdп€žж* }‚”x)”Єƒ’#јђ#ї8…–(j`ЋяЄђїVѕђVtllшFъЏГЇЯމш;aф’§Q6ƒx1ЯС&74ЛGD-Yўцђ >A#ТФF‹њИУQАшвE)‡? Ї1ЉІЄР&О%kх0ьШTШ„e…PA0*ˆ-ЈJІ†4хesч% ‘0+AџQХбє)сM‚Jc…T<ч=™фЏќqДядiўK<‚Ÿѓў­Вƒ" Vx~“ъЋTRо@,Z=hrMХВFрƒі†6TбiЃЕ"я#oШрхх•№R‚—ЏшGэšђ*D*СС№9ю›я =‰ ™Эh™Њхn[90^еYЕlбВoП§жT_aY;`Ж|Ќœ №•ђ+АbњкгўOO ˜:­з4ЎЖf”џhЂ'—   &Х…Ю`AГ7Џ/JОчnЕ д’ДїваЕBIEOK‹,сIЌwбЭRБ< ­‰„И–HЦХЦс•DS€5q`Ф@њš ўŒDоO%p‚@EHО‘)˜р4Н…oRQ`0s ž’яš >M‹f#зRcЁфКP!ёЏ™Јіil.ncлОyгтE‹%9ЃЕУH(!ZBюёІ5%Q(aˆшъЇьй…7АaF6ЂC™ЃзМ…ѓо~ѓэ[?T~vрЫМЫІU[XYpЅрд‰SХзŠЁ”ЄОŸJљЏ\НrђиI|ўЦН—Гя‘†—Г/;vzlЧ-ЏЄЉ Dк†Д{wю]јњ*юв;ЅpR†МММЯўёeqЩэш‰S–МЕ„њS"cCšіGэеќЋ'_8љЏ“дDощS˜іW\R<%nЪДSO?§YœЗЃ'OY‘lJЊўKОђЯ[џaЉЋSФ˜бЎа$ЬDВtЊHАJ?nбGEЉ_CU@‚GŠч rёHЦM ўѓ­˜ЛІЈ.'yлЩСЗˆh@JВhHМбІbY#ˆu>яќЩ3аіДї26йКšgїЎГчЮFєйГfƒЖ,ZћѓёКш§kEа$“і\ybШњє4ЪZ2И‹ќЄ‡#R>3Жd 6X”ь+$kGђAЪСAПNЋ#œюё;ДїPёѕМАљ]”љgѓБЧGHxˆКЖјЫЊНФSzŽ_‘@/km%НўнutМW._ЉИ[!№KzЪt–ЭR*Œ@X Ё–H.^ВxSЦ&šBњцє… *<иЂl ‰‰DоOq4k}”˜ЧєЖx“Šy(-гT(ЫfO™Иf24к…вМ$1сC+дjсоК1=ї№ЁКЦЎмЃЙ`‘ќХ{ЎБиЭ~цд™и)Б’PС’пHCђ1.щ(€‹оЫEэц"Гјпи}\вa.х—zŠПyЖЅ<ГpE ŽиГ{– ж{№#‡EЈoЊ]•.тЉPіёёЁœ`ˆQїГ1фgD‰Dcc\!5њёT„ZmЪD‚NЇhшF]}hJ€YQ$уЪ'•>?њwб\5Ž-WгaЗ&'-#eфБЅFР)_L!) кяQ…Z–зš„ЅT№ЁАƒЮ<Яэ/рRыЂГtЁяыіŸ*>Г/“Л™ЯHцVrDзНQЗ.”џUчгд$‹fš™гZ€Mм№hЃЅyQB,vХ]5~§SZxjРŒ…(” )Д-B\^О\ЃѓCЇЇfщbпPƒІeќWH}(ФWhH(ОЛ„P™О‚Fшvb~лiZКиБIG“Ž%цЋѓ3Г2уgЦЃ#-,,Œ…іPЩўˆS$т,‰_­f5LYS№7fАa1›sзМTŠЎ*…g'…RЁ И;№ŸAZLј­Пvяк}ъєЉQQЃ†G?{њ˜р]ЎО3xш`-q=њфMU=;ЁK0DлЋoпУ_ёЖqќzzŸ?П*Т–И45ИЃЙ`№ №Иїe€бN  ХC‘i2мЙл .ѕ!Žkц'UVZЖјХЛ2w9№ш0ьжф &цБUqЉijEWŠ0ё;Th=Њю?ЊPq.э MТR*БЯсы$PЅPыЩqЕвKЉtїPW}xЂЂЊXq:xњ+Кѕ"nJ~/S\ЊGs $‹ЦГˆš™™“bШ'е№Вжhr5peюоSUY…eќхя :{wfŽіхр­k>ЊЄx~Ш%<ж^*јы `WЋвn}.Yb|ˆ з7’&­yw…Р&гW˜Ѕ#ЎS™J4‹eЛyh9] бэИООџиўЪL[—іњтзЕZэјпПZ{кИAІqљ—с'/šВLр{3џGЭUˆ"щ)г!8НYJ"ЙфЕ%›жЏƒ„26,]Д§3- #фФ“FБжGQє-,іДFЫ4qЩf#зLqЁЌиiугgХШ.–QDЛђ<ЖœE"7 1ŸюЬё <­98ŽWя„+<<ˆ 1|ОјѕХп|КsЗюyGО4ЋSб ДmоєЇ 1ўЖsћК?™Œф6Ц%CКћu/++ZLYyYgПютPyК{Зqх™-C1ЃkіЌ;>и!Ј›– ђ>У.ŸЌeЈЈŠ™ѕЪЌ5яЎй;j/ДRL7щбГ‡8дŒv…&a&’™КкИ^фНГќЪhЬ№r#GдЊRN?Су*ёєQŒL$њ т† ПљБ„ь›CцR,šYтЖ;4кn64кZ’Н7к3ml˜4ъљQЫ–ЏфW ЕЛ ЪєцПQЊTЪЌг:вIбБ–{ЈTі˜TTД?мЯƒTžVзФH ыЧˆл†є ‚gSњ qВMЇvјЕў8vSКg(џМђ“чgŒ‡]aћЖэ“c'“nмЛ[љ–Œї§Л$ОoŒ)Gй6РїfхІžJ(щ)г!ДLГ;fь{ыпЫx/эrўх-[ЈДŒh"ііQнˆС`4fёЬr*†LSЁ< $›qХщ8Lлmcs8'WˆXѓ“6ц…И˜bbЂcЦ3RЋхВџž­ьф,№иWœ`ьДи5Ћз@yТНbе 8ХЁђ4Ц‹љИИюызЌ2}ˆЫG‡&ЮžЙрѕЅсO5ўцЧЂДУАгЌоНљzЉП@Е>*џЗІІѓёTc BђŠdq%э MТRЊ>ЕЭЂиxслО–у]щ­'~ЁЄлRUAЊJ‰Ъ‹xћeGЌ“Іq%‹FCх ГГЉсщѕ тЇ4оhs>Я1tUзшAƒС_>ы6 +Zх?УЏнтЎЊЙћ(ƒ'СзіэЯУБјъš>0Жэмж;ЄЗРo­ЏАЌгw˜эХШPѓСї5фЧœЛлNž4wќъЕЋ_~eЦUю4Uзм; S‡М(d$п0ДŠPSЉAЉгжšІѓJzЪt’ЭRy‘d№YВxЩњM›—.Yк.П7d nW ђ’щилGѕ{jHцЮL(mh6)+R,г”i*bfЩfcc\q:Жав˜и;ЉZтaiЫаVє‘,}c:Нe$Ф\„Ј‘‘iЦє ,JЇœ[ЗmХv`€OдИ(aО‚,‡ŸїялягеGl6ЦЅyaцс…іФ ‚N‰0ЫЮЬiŠў3?-/0 0Ђ_hцŽLЪC Эšўт‹Š$O4vd*/0 ьHйРl Њb~DЁЮмcɘhˆšТдCЬЖЁў”—зš„XJSиїж%цЖž­KСЌЭ}\ќu]сЁК’мК‹™uчSыŽЅдMЌл]їAd]СўКjгTHЄ#Y43Ќ9ЭjlhohuЈ&~bЈ05Ъ*"Ји˜+‰9ЉЂž-Е]ЬЎX.Х,.‚ђb!3uRBВ—Žr žШ 5ˆ78оз{іJїэСђmn–ІdГd\3ltR63L цБ§ › юхи26f‚Œі'ці• 6$™DZ>Шš`ќ ЏЕikz0—у0иЧЎ 1ХАЛA>.р7щщGtаLp;CJ’^a[ВўRУлŒеїˆ^K^=ЩOпl† ѓа0бЪ–„ХbлТпжyЬЪ4НФџ?-jФMYѓoЭ­цѓДкVy”Ў–ФэŠ;ѓр€wАiЧreгH(ŽЎ"Пђ|ђŒ2О%OЉjЩf‰ ƒ&O™ŒY1Ю­С;7щ–J­ЭСіfгL–й71Ф•чБй‹Ц@MQаKт2"Яьнй&іЇ`А7ЈV“ФсS]UФSIј*ќМˆoё№$•yЄJKŠЯ‘БМКІђчO@jЭЊd,РЎЖ"юnЄ†п\Ј]n$g^ЮЖглVŸxГcрw?Ђ4.”тєфО†<ќСcуИП$ ЋялQЙQlоYZZъtu­}ФJcіilђ66;ВuVІ™ЕJ%0и[і`_Вv|CуY№8^€ЛЅdр‹dT2Љ,!ўСФ%Я;v>Л ЖПъsЭйЇБЕ'›kж“Š!аМР–>П…ЋчfЭЮЦ!бf•ЁM$ŽumBЮІа9`eЬJмMIФ)q[ІYЖL.N„%b ЎPЁзZQ[j…ё0 †C€!Рp5ьги˜ЭеъЩУ`0 †Ру€€}›‹Ÿ+њ8T+#C€!Р`0!іэю!ыЪ3АP†C€!Р`0 ЛЈ5иЗђ бЕЂmk?6ЛёbьA ЭmЗcOс\—ЗТоFХvИДяђЖ›вЙlA\y:з IDATV0лŸˆvPл ыNьЧfпЈ(›ЧцмY" †C€!Р`0ьBРЩ66ЛђfЬ'›2<=<ъї Ћ%š*ŠeK–‰Œv 8cєьM‚ус"ˆэV:%k–ˆcјFuьнf9BјMк*їЕэ@4zMЮ•œ‚ЛКjЉ­СІхУчkЗћБ9Vщ,C@ћ46—ЕБс8іoЏ8—wE}fш3ыо[ qЬЫЖ-лHЂtSB]€в`‰ ї Їзёџ„ І:XBдtz˜И$бZ:iя™ŽvЖЦРќ@€WзЪH^9љц.с~!s3ЅЭ[:JG…џј‡ВдH^Kчюмќ>}ѓ4Д4w•;QJkЈ9Ђ>§MікqkуЧ97;–C ]"`ŸЦжш<ЖжТhСмйбЇdэЬ‚[wn]№‡GО8")ЬТWJњ[zflШАєl>-|>š™Q `ŒћЊГбz  ];OвХƒ$†!Д}рь"Ѕ0дђж5 ]Њ'5Еdѓ7М\“ТHИЏ‹h‡ДщRТŽШmŽњ ,lедџЈ8ћj! kЩЖг8€+Ј[Чщ Ки™ныП”ФScаЌ:›|№кС–Š~ФЋ–дР(ъІш]фћ|ƒњк ~/|}JлœЙs\­јЙзrъš­‚У”ЃКVCИе€3gЯ !…D„p№зњїіЮО`оЈ\А И HЎVщŽЩƒvrіє1їиёc№ЁNFиЇБЙЌ KbЇХп.Н„ЕB P*”ИI%Цх ЎнуZЂЈЩЇ“Ъп[еЫ[бUАБЁЉПЮž> }?(аwxф@ёл‘Зsќ& f˜E‹СК АуГ kWжР!A TlŸ=АоЇ‘Иўц6|ЁЎZЙfмЋVЎ2~Ађ"—ьВ!ФƒE›мдK-њ[K0iДї„‰ѕq‡Ѓ(`бЅ‹аW†? Ї1ЉІЄР&ОDщкD&/L*љ{vHNZf oщLnoцЈvЌšЋ* ё&WŒъš№trXGV!SkEГDЬˆ'ШYŸ€M9ЅMeМ@|Мїc!Zіоь‘ЯT(ЊЮЊ”)чЮ]В)9#г†Œ Kп^/DїѓїлА~ƒУї ,Tx(pcјўлoПЕ=M1чЧћўчЭЗпѕѓѕУ ту}&™Х<”@ŠяѓЋDO”ёцфЎЕeсз3ќŠvъ{фРыфгхжє6WЎZџR|zF:M0}]њ‡™.+•0ž;uXЁШ`Ђcc&фь“г&išfž8//Џ„—М|Н@›…ЖWЇoTžk•‚р`ј‡їЭwƒžФ„РЬfДLеrЗ­&к 9Iѕ’ˆЕчЫY_)П !ІЏ=эџєд€ЉгzMуjkFљ&zRpЙ`Р jR\јр Qџn^_”|!ЮзjЈ%XŸ„ЎJ*zZSIOB,; № tƒшŠб%ђ“4Œ_ђ’јˆхmM$ФЕD2.6ю№ЬE0]јцЙО&ъНй_K/йќС_(љ`|ЈSS^67q.?:?ёjВ™|E ятњїЉd{ Б$sБЅ%€ЌЕЅ§­МЉЉ„іil.kc;wю:,њ"„“–PLКwЮ8чІž{МiM‰)T^*UW?eЯ.МЭ Ctш!ƒœ1ўМ…ѓо~ѓэ[?T~vрЫМЫ&{ Fа Ўœ:qЊјZ1tСдїSi^WЎ^9yь$О}у^ˆПБrіeЧNOР›ЌёИх•45HлvяЮН __Х]zЇNЪЮgџјВИф6–_,yыQ+Ї вД?jЏц_=yќТЩЄў ђNŸњьŸС’4%nЪДSO?§YœЗЃ'OY‘lJŠ~ЪџyыŸ'Mœ$Žn ­ЮЩ)\•ruу{%;ЗmyŽŒ~nДцвХТM‹гSKўђзИždЫxВс9Ві9>Бšš66ЩЂIЂ!]еЉЌёHjQ!КyГWЩ}еФ;ЈКи>ЋЫIоvr№-b1 %Ю1azТёЧЉД?mмМ`сњй@ƒž68љфЂ+Eƒщ†йEьоЕcімйˆ2{жlаvХmЃЬОQН­šdВЂUžrч†>§#В– юb ?щсЃp“.XЦ– кD%ћ ЩDђљ’ЮУ!пNЋ#œюё;ДїPёѕМАљ]”љgѓБЧGHxˆКЖјЫЊНФSzЎСГo­  ЄзПЛŽŽїЪх+w+Й$=%; џ|ољ“g. KдVмУв(xJтcVhk"ЭЩХKoЪиDSHпœ.|­QFˆ€vQўПхш:рyёвХr­VЌoЬL˜=џ•љВРл6ЌOXъъq\кє.6ОOeкƒ‚d.6жЃe@šжrДц/ѓІ6•БB­ю­гsЊ“НrцЪ„J™аf Šў]єжЖb юєщpŠГЃ‚с]џфc\вQ.ўН—‹кЭEfёПБћИЄУ\Ъ1.ѕѓlKyfсТжžн{*4ѕќпШaъ›jСGWЅ‹x*T }||('"Gд§l љQ"бХиWHўF<ЁV›В‘„ dЇгщ*i`W…`ЧEЩИђIхŸЯА@˜&+OPи+Žцž™Пчџ‘=žХY™чѓŒ„ѓаSpnнЖ5jt”јІЩZ“GyW† Хx’^MBУ†И@Xˆ‚ т(€’)›ЅщгечQšK““^KbЁa@x0уAл‰-iŠyО5'… Щ…IЁ}xnѓˆиxІpњhJннТКƒЩuя„жm‹Ў{?Ђn](џЋЮЇ B6J›ˆŸыЕС3}]jњћщMЃ№рћщЈЭР€@Дќд5Љ@е<5)ЗXьŠЛъа~ЁєЉ-<5ˆG3Ђ„TbmРO\^О\ЃѓCЇЇfщbпPƒІќWH}(ФWhH(ОЛ„P™О‚FшДvЌub~лiZКиБIG“Ž%цЋѓ3Г2убьоSXXˆ‚іPЩўˆS$т,‰yGSE3ХX•@є шеЗясЏxл8~==H0В%.MM юhюаMцќюпНC`Дh c=™)УЛ тRтИfNqR[ќЦт]™Л`_GЗ…Юќ&ящM/ѓѓР пzћlТT]оyЯ‘CЖl6 |ZхЉ‚5&z‹г‹Gх‘AOWЈќŠ=-щдuЉhњ=jXPї Ю~нХ<јк{љЅ;vю р‹C­боџйƒƒFZ1№*pк8|o-Yъєщ№ яџєІA”Ш*ні/хЁš›нь;ђ}У%•yš№чIљUr"наЩ‹tщХ›йŒ[-•Фў…4)MЅІsчА hйђ•'NžРH:eСі._†ЊМЅОѕё'Б™ƒэћщаt2wяЉЊЌТВўђїН;“†Ж?‚ЗЎљЈ’т§0Йіk/|„uАЋUi З>—^К.X”ё{уЦЄ…Ikо]!€#гW˜Ё‡і)јXы:Ьјэub#-ЇЋ!КззїлC™iыв^_ќКVЋџћёWkO7Ш4.џ2<№G›ЌПdкп›љ›7WIO™Ž‚>Юf}i}ўeDЗ$’K^[Вi§:„ђг$-Шщ2ЏzтІФ}ѓЭ7JОVx tН7џЖ7ŒNbШ]B=Њю?zлŠй,iњ.FL{"ZЫХ–z”lжrДц/ѓІ6­}ии,dБех1ХMь/OCЭЗd8sъ О_ЈУb§2›щ՘`;…ЗљХNŠІ’и—І ТќЛЙ^ ГьЬœB ж4w3fkNXЃFFH|ш‹%4Ѓia…яiNЇЫЫ[кўйп;–ЖмcɘХпяЇЇж[kФ‰X“Чєd’э?АŸкУряcР“€˜G’65vJ,§фк;PˆЫ“Щt7oИ2љ ЁfПfiŠCбЂ`ђ|@ ;JaO*‰(ё н{6*tЏOрFшЁ)‡6ŸКѓ™uGSы>ˆЊ[Xї†GнО‰ —eОА[S“Г8&dT.ьjbЯњdјПМхFЖŒ”™Š XФF50РРFMn4#JакAЫ +šЯИТФ5ъ=ЧИˆз*чUN+іљ]!юŠjЙ2™# jNŽѕц ЪeоH-]ЪС”Јн‘б‡##І\L>s3ЖgєЎЙ7™ЌkId мMвб …KЖ ˆ{3*‡5Ok]Дн66Y‘Ь ;ЃЦEС #§ЃŸ н‚"м„4Z9ЊИБЬ[1Ъ‘Й#SŽњЃ~б #<т‡2PB\*3ЯF_жrAšђѕh–uZЫQЦ_м2i:BЁкЭRГ–єЉљIѓB\Ь 11б1cž7об1pЦMУV ˜Я˜0kЎёNˆ›ž ф„tАА€Ÿgm4_еќlšl‘8;qхђeќ Е[9€G2г‘ЯŒдj9Ќ­SvђТ1Й%мНrћП‡њk…cЧŒНuчVСїз ў}SчJFЗєД†žwgoЩщ№–)ˆ}0ѕ6$ЬЛТъЄя­[ўњr!SVзНћЮСO†‡›пyт,щё3`Кузы1286fЂРгЏ_?К fоРIу6š&8)ЯфиџZПс]ˆФŒщ3h:”аrЦiA!П5еИ=єWѕˆzЂпяžФ/”tBЊ*HU)QyoЂьˆuв4"%€ В`ЗŽНп›М,™њS&фй/Я†‘њрQ:vфА0/ВЅПŸJ'WQy"чѓœCGІhє Aƒр/Б†ТŠVљЯ№kЗИЋjю>ЪрI`KО§y8и~˜ьЌлvnыв[СZ_сив`_Œ|ёѕї7|_C~ЬЙЛ}qсфIsЧЏ^ЛњхWf\хNѓЫУЗ{ђуdъ…Мфл†VбђЯЌq+!ŠЄЇЕŽQL§Ё^"~ŠЉ/•СG^$ˆ0}~§ІЭK—,хKЪЎЦHœЗЫЬч™/ЬЧќfL‡‘‹’WHєE%Ь‡ЫД!КL.ŽеЃЕ­љ7ўІ~Ќllbэ[ a< Зe(ѕv#tX`3Ѓў˜ƒ…iLё.ЬW@™^  Щcт‘8"ёfЧРю~Di\эРщЩ} yјƒЧЦqIж>{lоYZZъtu­5ŽЖQзЉGћ46ёў(miыR2ЭЬ:6Nё{n$vМУФ5ž фДњDќб…лц,іЏŽ™ИчЯOnњњбюЌ`ЈNЋsВkrC:2fHƒвуwKЩРЩЈdRYBќƒ‰ТД`А'sД 2ЫќpG›ђЁNп‚9ЗPV Ÿ[81|тžѓ{Ž”љОЂИu ЂOlpЬмзцњЉL+ы[H”–Ъ–М>Нћ`™yKeШђi\Њэгик“­Yъ–%j˜жp T!ѓ#МwыmѓН‚­ЄСМliсј[Иz6дчœ‘KУАЮРXm+J@ч€•1+qЗКи6‰6QЮ–ЩЅ‰BВш"рRѕиNіcktЦР`0 †C э"`ŸЦцВчŠЖн `’3 †C€!Рhћ46Ьc”6kПцЧ †C€!Р`0ф pR6ћ46:MX‚`љKгeC€!Р`0 6„€Ѕ’D…— Ђ<Ю%,ЇайЇБЕЇЕЂЮE–ЅЦ`0 †C љАOccѓиšЏ&XЪ ч"s%;эЋUi_ЅсЗL_VT~qе‘х‡‹r Е†Ќ YЋŽЌЪ8Ібk„Гзœ›5K!Р`и@-I{/-ь7aaЁa8аБ–ЌZЙ<,47ПнНАsЊёАОьВ‡G єy~ vтјa“єGhЦ† $„У$qИMп,SСŠ†_0Бџ>Цњ# ­ˆgЫ(вpd=&jLбЅ‹9Ÿц NЃф7L’уш-ьа‹sюС†Ma…SўŽЅіilЬЦ&Ў F3\Ўж№ѕнЏџZИ™ЋхroфЮкїRЉО4щшЋЙ7}T˜uЯPКЗ0{ы…tНAЮ• Тdc0к78dGKŸ:qъЪх+w+„ТІmHЛwчо…ЏЏт.НS '!//яГ|Y\r;zт”%o-‘їпЖe[С•$ŽsБp8iъћЉПeІТ($~‚& B№1†˜ЖЃ’O1яєЉЯўёYqIё”И)гfL=}ќєg9pоŽžЩ‚`ЋМўЙпх=ž˜хццN<{їˆўб@€ЛЛ{…ІBs_учя'ЈkBйRпЯ№ѓѕƒщ[U§пУдuЉдyщтE>9i IDATkхчяЈ:ЋpПГvноOіZccў †C€! €}›Ч&& eИ‡Џ“@•B­'ЧеJ/ЅвнCY\Eєс‰ŠЊbХщtтщЏшж‹И)Im /ГъбB­нЛvŸ:} #У#‡Ÿ=}Œ–HМЪ‰aeЙхkЋНЬи˜“!Р`0фАOccѓифбdЁ зAКZ€7љЂ˜x)‰RIМмШЕъ`žмНJ<}#‰GоЦ†ыЧВo•<<<уžзџ}}§Ÿж/~§ ъяб`ЕW7W{9–5‹Х`0кіilЬЦжžъž•Ѕ#Pkа< б!Šнˆ—‚ZnŒweЄЗžј…’nCHUЉ*%*/тэO” 1ЊnFDА–Š_-eмхЈцgЃЮfЄЬ–S!ПкЫxˆŸтрj/›ѓgŒ †C н"`}Ї6Љ"УЦЦ”6)`˜CРх№S)>ПfRAY#їЎnњЕjокІ'Єџpђ€уїiдз№Юпџ™<9ŽkЉfЯšёУїпї пљ—дпBXN…} щњƒШЁ‘ЃG ЛЯеL}aъВх+mI„ё0 †€%іilL]ГDљ0\ИpтЉT|\РŸцGјђ@G ’^a„шˆ›бxV л‚'Џи з„˜ Иы]ІПTмжœXH[7q^"nБЃ †CРьeѓи€˜EaДиЮЃЋŠWз†њ*ƒШАё2 WЎ%gŽ‘*ииДDхгж’хЫ`0$ї?Ув(ƒ˜йaКerqXдщ+ї…Зщ"Ъ5%‡ыЎ^1шюqQКерШўГО~mК\."ќмљЫЗ%—цІ~{P9С’ШмБСLЮ’YП2ѓœЙ„|ZKЖ‹Tƒрнu’œЬГхU‹ ™ЫЏЕ!цbСIг)+R}uШ]щž4?iсЂчфXЫ•уИФ%VЯЯI{/ЭZDцпьMAХ}|шшЃ№РсБZЩkлх.;rXѓѕie-ёФ;GщIjuмO5мЇэЮьПfm№”ИЖ]Мж–ъкфIуЙ›яAХ ^тnОтфEмЭйМЯ+/СRiS=ЋєюЪЫў@K8-Ю>9Ћ)ѓЛяžpѓP 5Mpвч№ ьr ьги\v­hЪ;)и”хъхЋ@5uMjЮЇ9qR]€™uЊју>сПіјЯXщк‰xz.$1ŒЁЎQMm[ {лЎ?W’›[ л&QТ•ЄsЖ,nФЖjC ”Жf8HЌ…0Ќ%EлЗa Уя‰.DЧqЕ:Bј3mџAT^ю~юю%+V•}utьŽLgУїxЅиЭOпљУўkљRы}?Вя5Ѕвџ‹qЃœ^/‰…В[OMU^u”\ЕВфЧвЗ+nЧ’ћGˆg щЄ$ю­ЎБбVJ ЩВШ{6%Ў|Ъ-jŸЦцВ6ЖCGA]SЉ0‚@ Н%ЮI”диЬЌ;Ып\~­б>яхAМ”МвцЉ %_ LcуQpЦХ`wŠ,ЧїZтE х`cукюйЏ%e+:•›в€Rам?ѓП§ќеџ:VД)#œЭBiJя Ш=–ЋгыИjNЇƒjЬерŸб*Ё­цЖЯЋ1\ŠQ<Й„ЈЦ>Ъ•Bˆ:xьCžВxншŽ#xїй1ЂЛBЩЋkФзѓ3Ѓ\іyцСЗп~+‰­а|aTKј”Ф}ŠWуw+>dЁЋ)y]ЭSITJ’w“m •LЈ1Ohєђ,`.1Цv-\д'‡o`Ogtімй„ј8Чџх‹щяK0е'ižuЩ’„Y Hv`Ф@X…dЫЪЪтyOм рЄйQТЦ|љгBBУpƒ qХƒн.иЕЊЃк(ь”9kgЮlС/ѕiDл‰иzy*{Т6…nJGъ XкDm$ №єЭ?WSо`ЎˆзD‚гвГY}єЅe†Лj^]3@щфUO%є6z§‡уPк§§‹ЗmСD7b*?Š„гŠакб=ваV$\ЗYўb7zмдЩS_Lxqбтф”?І4H›Е+{Iї›~С^ Ђ?ўFш8n§еsr'Ю§ымдЉїЛєЮѓљbhŸ!АЎAеC}§в€НЙNФЖх›zsƒ#ЄoŸЦцВkE'ŽŸ˜К.4.5џW% Ÿщƒƒ3ке:mЕl^nМЎЦиŒJ[^?HŠK[Э›ю›щ’< ƒŽэ^јз…[ЗnбзќŽэ;цЯ[\\R|сЬЅЇчТEвsя$г„*іђЬ/Я|Йјлт/|‰#;„-˜;;rXdёеbмƒ#ќaeImЩ7ч“ьѓчNœ:s 7ˆœOLЁ85Л]А:ЩЊCj ь”?ыУЌкˆ_ъг&ˆ6*vгБежEѕэЃрGМjIж)Eш"пч‹Фщ эПООЅmЮм9тPW 5'sPзшx @Иk ”6LhУH?˜ёJЉТЭ=аЇsЩlБЬ|щЪ+Џ\-оДy;њбЃF7Њ’ŠЃ7эВЭѓ>Дчу=Эќы–Эщ+WЅ.[О,ёе…gп8ф•^ Э=УЩ‹eWОдjЙ—Л˜ю—D~Ѓ>ЌLџёŠЧЬN}PЦЫT?ЭЃdВ.‹­ЄД­тiŸЦцВѓи Ѕiuк§Œ5,Ј{PgПю’hšеM#ЁАБё6ЙbTзŒƒЂАБaО…щ‚ТоЪblJЦvqјxяЧBій{ГG>7RЁPЈ:ЋАРтмЙKѕr5ўwCЦ†ЅoЏ@Х!КŸПп†ѕІCпџАpСB…‡їВEЫ$­’ЖфћёОџyѓэw§|§pƒјxŸIfБd vЛ`CgЖv!юйгgНММ^J№ђѕM”lвqБq‡ІБCRЭ]ђ——ўшцNнxz5рoN‡5lЩГЩMнZCŸ(/–AS^67q.?<„СЋGC^ЕЋб&ёэ„ИІ(’ž„Hf ЦD є9к>O*€}›Ыки тdюШМЅОѕMСuПn~#žAK(&ЬŒj5?ёй/-cШЪada8й2žlxŽЌ}ŽTSгрsЄх”•дЂ0R9xи`qЁфщ9ІЉрпЛhar… RрŸ8aтЖэл№2Ц NљtЌх !ћ‡їт‚”™Сю0ьж*Хи…ИЛwэ˜=—_/6{жlат-›єт%‹7elЂ<щ›гЕžњД!#v‹ЩаТљF]єўЕ"h’ЩŠVybШњє40G юb ?щсЃ0šџ-CЫи’A{†Д iїюмЛ№ѕUмЅwJсDXЌ„_Бl–‰7ХЧ€‘ŠjцUмалИЃвf$j8ХOZRЃ%?з@5р‹ж Ч5Я6azТёЧ_™ƒР-KфФV-г,›5_s,ЄмАБэљo`л№п[жЄmH{aaжŒЇz)ŠnъKЪsЏxнqx№SН]XR­Ug­їо‹З"К|ў!фІфЇrcШ Њ[дL ]2иЪHаФІ.гЬN”Ї2ЬL˜=џ•љГТ!єa}ТRWЇAxЏw‡г_Й|Ѕтn…ŒЇЕLч-œїі›oпњЁђГ_ц]6† ž4wRЁV їжщЙ‡е5vхЭ‹ф/ аXьц O~#ЙBS›І^FŽPпT‹sЂ‚ХN‹…ќСКЄcuЉчыЂFGЩп4ЬхœШ%АЋ@G{”—ЎJёTЈр~W†0cKz5 AFИ@а\h (†2еъЅЃЁa–ІOWŸGi.MNz-I`\ЬИ@Рi–Žи)“/вsŠ vSU: ;ЊFŒ­˜у Б“ТџŠЛъа~Ёu?Ѓў\]‰‡x-nвб“Ђ1Ж43 —#Hрiю_лХ$‘ЇЙEuJњтђ"AŸбљЁSŠSГtБoЈAг,џРпRJёЉBhФSД—ъQ№?NЩ6 цqŒІЅЫ[i^ш­;ЗТ‰1PЩфѓEњАвahqAxџЇЗe" v`З„Qьc ьрЯмНЇЊВ Ыhмьн™Ыо^)8%›є’з–МЗњ 1јёєEKбкiм#фХn11Z,#оКцЃJšюЇЋ&—ю`$JŸлџф-jАЋaЈДђŸвƒЁД?-ћяйkо]‘Н—ŸHzGs‡іўїя"QщKВ HГ:ф‹‹X0ЉlXsР§o9ЉФІ_МE —BйƒЁJ~ ŽwТјяйUn NSЉщмЙ;Я*лёJ–Ш)­ZОY6_ОB‘§ЮЋSWkџW‹Н`>ўcДЪ›ш_фtџ{ёЧа!я]8И*U"…Zюи ~ЖGAndьѓ^FllЦћQX3RђиЪdмФІ.ѓЧ<Щ|‹Ў­^ЛњвеKџя!Я`lНј{чюЯ1tUзшAƒСŸ&(I,YМd§ІЭK—,•Qь$#:ХгaБ’{Ы'+LhзnqWем}dяI`ТП§y8@]ГётgЃюмж;ЄЗРщkVЏСœhм+V­€S№wЌ_ВQIЖр/jЪ~0|WЄ€AЛЏс†u џЁКA]swWvR*эE~эЅQКOŽГL§!FoвжІэ§ћофeЩƒЕŽз2:ѕibЋvИY61_*Ѓї YœМxёЂХѓ_›_ЄЎвUw!н&yFLEDaїЫ0ŸY(О`ђє€Э“ПнTЄELьc С›идhH˜ре:.– $Џ05HH?3Яџ`@s@•єД–)є^m0j~6е‹ЩГОŽк‰­О8Жў…!еАВC0ЊuZљЋъ4ћP[јъBl›6cњфђђ;НCТёp `КиГуž…едšuОzB`Г6Жћі[o#Yё№ыэлЗ-‡Ћ$г„щQsW=lФ0ьІ(ь"HИ}ліo->ЪŸyf0œ–ий’/‘5jѕЈgG!:VаФM“шsiЪ v[`\’UIaa ьf~јж›o‰cž?чх?mм$oЦVщ}BћШѓ˜%ыDЇУb;Q†–OЊМš\{@мБ!$єOƒЕf‚бvвё?;>3т™wgŽ’М4S †==ќbЇТ)DlД_2KПщNе“СГ^дlй„с"AoPŽФ­#?Ъли”Pк ЛЉ ˆ™ЂЈ7 љђЅs#;vьнЋwєИш“ЧObIЌd­у•И‰­ксfйФ|eJdєўŸ6УXцйI ѓЪCХУ+сА:$њ‹‘‡Q]У^i“яœP‡БEіMlъ4$L+ТxзLѕЬ>нКПКhщОџй' €Ё*Ќ5 *цŽЫxZЫtќѓуgЯšёУїпї пљ—B ‚чё3_ Ю_aй@хи26f‚р”ќЅѓи$Cё%„eи’A­ыi&oB3ЊБ|sal”йY™hl­[.ЯСо*dЛ2@ѓž=9NaeQžГJкZ­К%ѓ…§ f6ФЬ lЇў_ІA1wЋ7!%ЫШЄУ‚Zћ4ЖіacЃˆ3Э€Bб’ƒН%бЖ+/kг.эJ„1;€ж8ЋmEQ С:e9НЂY дZ­К…ѓ•дЩdmІБN™YPгxМжŠ6/–C€!Р`0 –GР>­йиZn–#C€!Р`0 АOcsйsE(9‹Т`0 †C ­ `пюђЅТb]yЪ`0 †C€!`7ЕћV4КVДMьЧf7L,‚CАэv‚­Љ‘к(ьmTl‡kЋ}—Зн”Юe тВ‚йўDДƒ"и^XЇpb?6ћFEй<6ЇрЮa0 †C€!`NЖБй•wЋ3glЪ№є№TtтЙуЏZЂЉвЄ№Лl‰­GТ‹c1š!Р`4пшЂŽ=p.‡žАI[хОЖНˆFЏЩЙ’SpЗ@W­уЯ w#Уч›ыЇњџэ \GšРk’п4bF(1 ‰†ЧT|D‰—‡FуcŽL<С'DЯ€!($ы+чн5@\ЯѓчтJ\OЬх‰5ё5ОпЋРњq‘ё™йгѓsђуОžž”mгн33Cљ:•ёыЊъЊЏўUд|ѓUu7їT]<pHР5‹M >6юesЖCєД›ТќBўНї№VХЙNYZ,ЫІeЇЩ1‚w„Щ%a<@HРгzkТ&†Г№tSЋ…œіtmž-_хОЃз‚•цшOсu–ЄЩbоЏп]ђ—’5ж$PzБg5Ув‘€яpЭbsИЭ ч 5jЗё5–~ZrђФс#ЧŽРiЦsKu:ЩW’‹œj`БAўфOЙWs?c5Є_/@њДТЇђху'@j јt§fSƒznжь№А5[Ь`Дqs•› гЭхŠŠГ’ЭG сХGі5ВЌбb4ƒƒ9Oќ+C‚ УŠу9{.я)™Y"КOсМ4>}Šr7йЧіё'џ§ю’•Ё!Ё@јј“%{sЊЭKKžЪо&kb x#›оЋІ!A/Р…-6I†‰€wј[‰–XЬ-„ДР=`ВyЅ%чJHУє В7ЬP›Ѓ@зKЧ^c#­‘kЦ\fOўЎixЅ?|П‘ПІЫфM}\ГиTћ<ЖK—. ŽЬїp*й‹МNЕдЯIђч№уе6‡Р Жќмs! 9}Лкž*YЃH‡]јCX’ЩdZ˜Б0b`DЬS1›7mІIЧOOMIŽаqёЙY MwЅ_;јs‘іUczyѕЕъдYЉPьАИaЅŸ—ђёЕЕЕЉ)\$р”ц re ѓРztLt „ёэхт­Х!a!№й> cmієйU—ЊОоџѕщгіэ0 вчФŽЏ*Џ‚7"nСП- jЩ2…шz4,IУТtщЇv‹P˜‡ЪХл‹?јн№IcP№ХюЃjwОCMїD$Tўz fH(бZ‰йШ?Эc •!/U Ычџ<сѓдwЇРh››>W˜ЊЙьr™Э\3‚ХЦТК…Э\36*pШБуЧДAкЈИ(6т›Тє)9%^UсPЁJjшшЮш@‡1"”;SfwНж5‹MЕ>Ж>џагвbс; „>џаGВУDN5о€ƒ•P№Бq6 Йh3зl‹Ђрc3вBРv.љЈф™јaКI/Н’ЁIœ‡щЉp€-ЬZШыРкќošЭaяўН`Дк>оe_л-йUђьѓЯj4šРоЫ—.?qтœ3Ѕёyђ ѓ-Y І6\šП>ŸПTѕCЦ‚ Аn!,^ИXЮ+щА"'зЃЁœуGkЕкд™Љк-ШДdIЖЩIЩћіяЃyр‡88FtcЎžIDATiгx№Qьrj;lЏOgW ŽЈ@ УЗВь_ЎZ,&2) мl6Я”•Н)ѓТx˜ј+Ж’ЫrcЂ# ЌXЖТцм"’ѓ’мДц.Œы/‚‡ЖЏ=ієд№ЉЏ=ёk5П6–˜Ш…ѓ† Ђ'U-ЧCТе~U§•А^й1`%p[ЬК`ЄјѓЯ?ЩHBкЯЯP Wй0˜ЗFфО›ЋРGЈШr*с$&хЎSЩёЩdО;^ї"|)УWГЄГ@ВЃyнdЦ‡ХУFƒЕ ШіsЗ>пяPQхЙГрFyц98Е™зьfЏ§фgд3дзТ’мJ—.жСюЏžЩ f(г5‹MЕ>ЖAƒUTV№=œђВшSфT3џШyбJў™lz‘,M2bЩІ‰$џyВцyю:ГљxЇОјѓзUе7&OЩўM6_2Ќ]^ИxсШс#U—ЋрЇdоћyПјO^рsvрSвŠ‚вЃG8_кЗЧ8s†,ЙТТ+эфW&oоВl  РЉѓe s:Й —ьјАhNњцЬšВАіlГВГ6n y 6№і%AСI>Š]Am'юsйBЦэѓА&тUЛэЮс‘uзL+бзB~4AŒЦцўoп4јЛ.мTHg†Ељkoзн>ѕ]9„šК8…K$чЅіzэ яLŒ™m2жј“1”„юнЕЗъ”~^ЬќОŒюЬё3№ŒЈи(НЕъыЦ]Фeˆ™}`Ъ•ав+WЏРЌ{ёќХ†[ Мz’‘’ѓ3Ÿџфщ“п;U~ІМЉс6м‘‘’|Dm—S ВЕ'‰“˜ˆ^NлS2/cо’w—мјсЮЛП>}оО|$ЬrћŽ†H…qБќт7ПЙSЯ}‰Уqњш‘/ўќ,pMIžђкДЉG§ЂNo&$NYšc7јœэЧCѕІЇЮ™џЦ|Xўћ!f`LоЊх|Q’ƒ™O" z=ўѓƒ‚В}{лВe.ї Е*^эЮФрр`aq;wэLš’а`h€ТgŸ|&LЅŠ%Н–ё){к2Жхl7vœr …@uFЃ‘?ЯœЎŸНіјбqњыz>оиhŒЭЫ"ѕh9"A”-ѓЭЬœwr "8@ ЕаЋ !А”ЉзлkЄёBATfpПрћe.ЪЩ|+“Я  @yШ p*,D$CQ =…ђЉ ‚№”b‡ј†[њшAбmїlyяЕ S-!эхe!л„Wік$Джm!‰ЯƒŸЪ|ЛѓjѓЭW“Ъ|T’*l/Ј<іLє”ЊМbcв;zЉ’|Мюх C <ЂЃЂс{…OGg ўЯ‡‡ќєrрTђOO˜Їc2m]RQRцДЬƒigєgрщK)гSvюиYQQoЮЂœНеŸХ!qЧIќI< zЕ}ў„Jf ˜ hыЈz’‘ ѓ3-ANЂЌ’IЯMbBХ(пк7СЩёIГAЇУpRјђ‚œ’­00„Ѕ‰КUtJП Љ>Tр;ТЁzТў‚/8ю+вvHfHЉЊЈшˆїДЕџДл€ў\ŽМз‘ P!мћ?т™ž{Bќшq’і€l"ЇкЁУ‡hїh ТІРZ% Ы‹­?oЎзз5‚зфЩш'ы вћчј МкТ2ErоКМ&cгСCЦО0:ЂDяаўТ gЯ=sZбжЂ№№paМВ ыХАJWZaс•ЯNz-хfЭM tјYСNЎGoлБГёN#ИšЙ#,ф’лЈц’lГпЪоА~фсv.ь4? N№QьЪj;йvЪЦyз‚3SBсqeчъ`km Ф№ї€_­БЩrуЫXЩцРЯzўИvэZfFцъ•Kљlu†::K„‡…пН…J’zвY; ђhbfb,КВ~№јСА”ЙvнкЗГоnjjšј/Ы­GIлОaxО’Ѕ%Ќ—–VЂ0ъnеAЃhN^ŒT˜Ÿф#ЌEA%Ш&I'1!РШ’Ti9;>мqфш‘ЦН№Lќ3ЧЄёBAВЃ6Ёa(”л›ЬТд.”ЉbrЕМї жйТћ ЗWUd;гSА……&9Нf 1’‚BЖЯvF§ap-x›рw3ќ6•,G)*3iJ§ BєŸYЎГ{Мрќ^w*ˆЪfц™“v—PMЅиЁ|ЁS 2€ƒКмD… OЧMWА.мŠїUЅЅЃ CРGБЛЊЖpœШPu4m/xб‚'TЄ­жя<ШЦНе ›з {­*јх  ЭJMќ‹}lCуј‚D—(Ÿ*еэ(ЖnљžхуvФ'ь‹л­[~6чиѕ2pљЄЬL)ЛОзю];Kт/нRp Я^АтŒ!щ‹”›Ÿ%]/"   mˆк&БћŠ9ъ еІЗo‚ˆПмЉ(xьШ1ѓэ[ 9%;кЩ/nQErЇ4ž "Mфд5р›ЖзC~јЄ—KfШгA›аŠє-Yш?ЃNЕ~?~хЏW.\Нrсћ+ўzvHЄІЅ;йЎД9iЫrsЦАxˆм|Р_иЇwŸкšZ' Ёй`ЌсŽСbБlѕЃћи`е\ИѓЯa™PЭ“˜єЏыѓW‚к@˜іњДіj”~Y:fдИя&<|јpˆЇ1’BvVіњ e/пЎ№QьVлU>*Щ^Д;џ{љ[Ўgя‚NA~Лпќ2n> pVGn7ъжЭЂ№РіеЋVУFfKW,…S>Оcѓ’ГJHх›?у§їз[О7“П•ок’U‘јjњФUkVЭ~cZ9{”Л+пќ{П§@ІŽœС—Ё<`iХM•-–ЕkьOq“Œ”›ŸЁŽэ!eŠc>Ъ*I5퇓˜œN&С.ї=k[ђ2п{`$-YВЃНА‚шяЫЁzАWЖПУђм‚Г4‡ж(9˜љTзVEU{Џ(mЊ“ТкќBƒоР…[ИсVш ьщ[Ь Х\pВœŒ73тFХO{=1b@Ш‚Œ_šШ_юБч&Ъ*)€ТILN'“р wЮЌiс!+W­мњ‡­’ЅIvДТР,ФЩHбјqЈоІ›о[ў^HxШПќsтЈсЃh-’ƒ™O§ЌŠђRщюЯЂ"ЃЦOz…^цЊЯМˆŒ‰tѕ*/ф)ЦЙаlV97_€ŸpЧhёЖ^Ы~еМЖЭ њќBЊaя@ЋсЮчФ)‰ЏtbLv R_ПФGБw^mпъ8Q{#^ЏћЧа&n:bЬ5м(ягђсжYIђ‡ЩЧZvї‰фžЃѓ-М`†›u!РодŸH§ђLŠ7пR6.ьџsЉЈ›œЙD”ЧC“Xчщщ§S/4СљŽі~ѓ;PcueЅЭZqњR5МWдiee3RšhВŒTЯзЉЉЉAsЭЫ]иН œVЧі`Р‚78™љBв_ќHщМвЭG7Џ:ќnO]‹(al7qБ&rз@Zј`ТRGЇњz+%ѕЧП&I,йaЎYlЊ}[‡лF›№Zб)Км„pМ)УoЃТБоЌыBь]5ZДѓмr‡йi5кšиUЪxЂоŒч3&ЧNоyrчўъ§п7TПžБ LŠœ”ўVzhр§ЎžЈКЋЪФПІЎ"пыuЭbы>6кhQjœ\ГP›кОЎbяЊ„ћ КЊjЏе лд–MZСk5ЪUфqюZфкˆё@ ћukwt?k$€@H ЈŸ€k[ЗЙWT§ƒ"$€@H€pЭbC‡@H $€МFРЕЇ{(яcƒ›uНІ7V„@H _ ЋХЕ;њи|тylП”оэъvzсq;]нD5жяЃи}Tэ€юноnг:е6DЕŠ9џб šр|cн’žЧцкЊ(юcs w, $€@.pГЭЅК13@H ШIЈьљ§Иš[šлDЌьqC§ЛWЏ>т8ЪўТIгщ \<дAР5‹Эс>6/4Š7дЈ}Fk”‹ЇP@HРз Р>§K§fѓѕІIшoI[ГХ F8км}P˜ю.јСђЌЄrЫfxƒhш#}‰‘e­FxГфа6– ОyTTЂщA§ 4~с€сї98ІрoІїнa;ь§s?3J* рšХж=|lЧзjЕЉ3SЕ!Zi/РЏК’Jž‰Ё _u№ДHJNJоЗЭSЦАИa–№%усФю/7хіQьrjЛ‰ŠJ‹ W Ž@ УЗВь_ЎZ,&2) мlЖ}lVіІЬ у{.^ИјвЅKі†YЩŠeЙр‚Аbй ЮYBя`у}WД§эg<šфСpщ"ч#ф‚‘ œчЦЬыУ•яцF„а­ўШсі•j4xЬчВЫRfІа р@Šy*&BБ0k!==‡Ы KOзK[­$Xй џ4ajђд7вп&kз,/\ѓоќўyіпњоЊЗ\Ј<~ОOь;Ї(Сb†[‘ss'їШ4п"˜љŸ?ЙРhг>OКš€k[ї№БэјАhN:wЭœYs@vСщгЇПјѓзUе7&OЩўM6$eegm(м@ѓl,ШXЁ јљwM@СФюˆGв}Л‚кСЄ‚BCЦэѓА&тUЛэЮс‘uзLР5ЂЏ…ќh‚ Ќ!JАbXИЉpФш|ткќЕЗыnŸњЎBM] œBrѓІЭ.^8rјHех*иƒ•ї~ЭмОEnœУ†ЅGыЅ­SРЧЖѓOœƒ-џї›VЏЭ/X’QQ<эщд'4•зMеѕeћŒ/КBРBpHs“ОxщФ[Зgмˆыћхv.Э!†Р>60нz@ЯрЁ& z=ўѓƒ‚В}{лeЪ ‹ф'ќё8КкmщССС’eIЦ kИЅнvЯvѕН6n5№EСЕАa“—С ЏыgЏ"се№6CМ^ЏI|ќT&€и•љx(еGБ;Џ6ЯMђ/нCH=QЌАНP~№и3бSЊђŠIяшAІ5ђёК—+h €€№ˆŽŠЎЊЖЯРqCу`ВтsђГ/C~z9p*9у ѓtLІ­+›žT5/ sгєsSєЏ%UMˆЏ­ЄгжGщqС8Tg§йиqД:‘Њ\ќН6]И]џјбqњыіqCЃљ хZдс9œ6ЪWеw‡P1а-m^ЮБ#Ч*l$Uп{f]|[EB[БЎс}ноЙб™ѓrxDєГj&1'ДэKi;вЖ;ЁmзИЖOЦqТž.цdfлххmЗђ НФН‚Ј ю-М[–VUQсš LM~aTюг Ж(ѕъSЏ”žRAR™m;v6оi„лИ#,ф’лhЮР@ћOpХЗк– )ћ­ь ыз_˜Пhс"HЂљQp’bw”{Гљ(veЕн‹H ЅqоЕрРЬ”PX%ФДяЌЁJіЊџШпž’v_Zйƒ‡›~uћрQірir№[.FksАЭ”kХTяpйbѓЎzЕ§Р\€н'NœуГѕэ_[[ЫЫЕѕЕНCэ†Žr!žH :ЬјMфіmKљ9ђУї„mdЌ­„Дrk љ3Œ?ёчm&mш˜Б :”|RђтИљ Нэ_љзћг8м  p!$ЙaяаАtCНЪ ЄВЭІЌ7ГVЎћ]бќ~ЮoЖU2УйСГШфЏРbЈм{ Y6ђээБя~4rѕчЯОџз/мЊЈ–h‚И@№щrьК&ої,ЖЮp*§ВtЬЈ1ЁaЁД‡ё4FRШЮЪ^ПaуЂьEЇNЩЫс‘ˆНK€bяАк]Йѓ•‚эЮџЦ^ОС–ыйЛP\яўЭ/cсцƒаg‹‡­ї›Зn5€П щЕЄеЋV›юš ,]БNљј>Нћджи-9g‹ю\ОШi3 Е?XЎVjўоЪ=} lYƒџтќ8œ­ж‹aж’‡ЕЦ?21Й}m‹n[ЛfэЎџк•Г8‡Я6'mYюbЮ*Е’ъkеАбО§…Ђ˜NЮс–ЌWд …Sі'’•“•Е0kў[ѓ+ѕЦцОфбWƒтІТ%м#TЄиNШэ,Аw-|lA\№ $И $„Ѓљ—eБmпЖ}жЬY"ьѓчЮоОУЖуR” 8…‡GŒ˜ŒЏR0q^DьЮГrcNХоaЕнˆЮћEе7“Ы-Ф?ˆа3ˆ‘ЛУ@ЄП,ŸQCЂNž>ЙНШ>х,Ъб>Ђ§є§њіƒSўТЬЗ2Ÿ›№ф•уЙгР'#uГfРЏfme8sЭЏ'–чcc8[/FЯ0сЩг5‚пв‹k]XHд ЈY ч7‡ОЁ?Ж3оЬˆ?эѕФˆ! 2L|iЂУ&trя№АьdНл%Ь№ўя6nмАБш?ŠN|{тйФt&|А0UBі#,}<џш5Аэ‚l!аfДЁM[FЩио]Ј‘'ЋоџеўіХ?ћќxKЅТTсщЧŸ~МєнЅш`ђq^FьЮГrcNХюЄкТ?O7BыТЂš nј~ф6IПSHЄ›иk›П>‚ш0t аHQ ЂSš­“ТШ%k^НR[v^TЩoцю?„oјžысЧT6:nфм4aE•Е…ПVt•№Д“sИ“УВНЌWШФБ Tэ_щЖ{<{иOИїгЩ†_/XЕ™kp•ŸЏОiУЩцњ\6{їњœооTИєгвšššW&НтЭJБ.Фо%cБw vЈ”…')hˆПсžuб?2~Wiхжт3k—шH+З%–DЙЬ1тo€gчNŸысйЕЋFЕ7ы5LТњYH/–aY ЈiБАрž44*§ЈX™vчяdќ5pлЌХƒeЭ№№ЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœPIDATxэ] PWЖїMе КЛЌКбPфљГf“,Ј‚Ф‰"бhbPP4€Ј@HTФЈ!€("D‹Я‡т Œс/Ў`Ъ<а2 yDX5ђЬюƒ2x"№^6@VНЏЙ3—žžюaІaf€щЎІ9їєЙчœ{NплwzОО3nй'їeвf}wо>fRЎ,ОT,%оЬaзJ<Б­T(ЭъФГZ“Œ‘Hїx+НЦBт\]Gcі,ыіџЪ+ЏŒфˆ[6В#92№чЏаИмкмКyGdQоyйПhX§џ{џйЖ+*ыpкЕЏПж:!Њ`рc„ІІЦДєДkпеРШBзЈmQŽгžбoАО†6vУх"Ў" бKmќяЧЛЮ~!ц§нŽŽƒ8iЌ{†ЫSgиUhгјz<.†ўнобоeЖKЩеrRЄЧтŠb—чžWи*)gHл/К­ЙuУ–Э//zЙђR9vТ7ƒ) nI6"‹НВЄ|Ћлюи8 КB;ы„—#А7>ИЧд}"ЫШLпЫЧГ№мч`*8ВыR+†Š Ъ@џѕ?ўXOuвКМšyнЋЎЙЕ.а_ѕ’ыве+KKKЈёФYbrŠзbOьМ‰Ч`ЏоЇЯšю8НЊъхT|Sљќѓ.іSћ9№‘<[pўоwsГsKŠJ№Йќј‰\0нчЛпО‹Џў]э=)i)НܘЎИ]wпнЭkМ!зЏ_їѓ~-‡"˜”S[S[єйљђв’ŽGй'(Ÿy9gkИWTpОђJЙR–ž‘NјйgNм{№№/_,oyФ|gСю%Fq7ЬЫ;ћТГN†дr/zЯ‡[ЗlЛyН&чXжїw~0D•~™ŒOяxєsбХьМ‰зЊюџЖџЇŸRVўчљў§нr@”—EНЛлvВ­BЁ ЛђWРTЉTЕпз‚(ПZn#ЗЉМЪtњкПеЊ\T ŒккЗлNВeWAёёуvЪ‰y?ЦЖQіUх"ПјBLtЊ`ДˆмUњ5уЖ ХeEЧ0ќ Ъˆ№HТт‘ŒЎ‹цŸЫ;t№!к„мГББimяТfggП/&кUњeЪЪKi x&wœЪЮx˜*—еезЈЋН5ёЗgЭšХ‘yињpѕкеЬ~­x{фш0Ы*ЪіюйћYоiязМяжн…эIУЈЩ“&w=юbчХI“&гкvSэ тqыCЪ'ФуŸњОЮuЇр6­ШЉ"КHЦ Ь?т“тю7мGЮU%ф^ZъсЌSg223&ўЮf{є—цЊJПРУжvк^ОФы№6n*8Wр<зЙрмg›з2S9КѕгіYЧВау)„BЎ˜т8ЅъF•вfў‚љЇѓNпЊОŽbЦyжfРДо]х^RQјіzZ ХнqЫPo4iˆIіЖњ?8хЇsиз 9ЗiEN•!сЬСјCўkОМ8М\†YшDїее,фоЌ?Эњ8щ фqГ§№вW—uыХqАŸLл;јPеH[ѓџ4W\­hюшpžЧsн­^Е:9%ЙЕ•™f755%$&‡м^rЫLO]цН E=9eд1,4(ћd&8ˆ v(Fm ЃJ’гг˜1БЋ+љhВя2_Ъ'DРšе Iёh3ŠMџhФќŽ№WПюŸ’ŒСЗdЬђsђЄёMЭъ9)сˆ;т:{бХЅЂЂbЦ_œЮ|ЗaшpjВЎ6!їр'3;Ц\ЕOжнЇ[ЯhŽЏЯrФ‡Šнyѕ)  ј ЃWЏа[ўo…avъЬ™Сƒ‰˜ъE>|{Оь‰"ŽА Џ§LЧЉЯфfOўЗД§GR щътŠ"ЕР™;чЙkзtџ_ЗпkK"BB9к˜Ё"(2 ƒъŒ™37…l#!C1пYсПХˆА53(є­РѕПўяЏdа&LqЧ•+VЭ8їЙЧв&=эО!ИјR9G›{^‹DEЧ47>€Я)їsj‰(Fl MLMїyУuЧЕ4\нйљgёэ&I"”ŠЎвћЯ^|;вŸбJx+:НфZџ­˜g8МкЦ“ЇЧ›їЛ9™Зx11oјЏмвФдДŽ:<‰зšЛк(Ќ'$њНсљ„6jc ЯqОФы“5чnV1 ЄM(М‰ƒНP“%>nтёРг})6c>Z‰ЧГ6LАЭпfи5ПQ+ЗЈ•xKХ O‹ {-е^Ык%˜f­Ф#њ!С!–uKВnъdŸЬІY,НЉ-IњGZtЙЧ‚yд-iМЅЁл’.Н;7ЖSЬп:М0iаЗsќЕ%юhŽ€жфNЈ! їъъ™ 8;;ЯzŽ аRHјNqЊџ[Н~Ћ:kЮ€”xd=<2\2г3MМBsЖ_Ш‡1Я7(ёъ(єЩЂї2ШЏ”)Ь?NQ TMoJKOОvГЏrŠŒqœ ІОMм0 tЙ€ЏkLœ ]=B QВвгЎпќЎЛЛ}ЦГN[CЖzxy@XШI!=МU†ЅE'О?Э9Їsˆ‹Ш=.v‘зѕЖцЖ !vОЛѓ`"ОХѓyчэІкёЪ›‚Is,"штќAЋУ6n7bзОXл Жј‚8'7‹$^œBN­ai‘˜ЩђэЖиfу˘v, O„–Џ\œv(?–FeђђѓМ{ЉцЉ$b!ћŠЮЮЬ {?м и•ZЂO–‘Ц№НbјQ;9Е )юzouLШŠP§н:­жS…э УH@w0) ‚Ъ ‘`юё­]=2Йт~C“]НO˜av_ь>кзQ Žžм3xјЎ.6ьEm<МњfoggЧ‡gCfg™СУл i–Рv‰ЕѓYтєmtZ­G˜э c[H6ЛHe†HШ1Шwсо)W|sЇešоNгћ:њ:ЙG(їююю%- Є^ЂЈ‡o#НЖЖ6~<ќЇКЁa№№mъŠTГh‚ЕѓYтj­ЎИRёцлo*iAпєќ‚[ЛЂБЙkт‹<З%-Я4“Џ ѕAW/]ХQ}VУзю/рu*мKП,”;ЃЖFQI ё Ь„яы:xјu€шc’Œy>b~G*ЦŸпе<|oFZ*a2xј&}ƒ5Ъ!Ќё9еu‹hрЩSЄе№Пі~Аƒˆ‰vRзЪ9LаЕГЅѕ/ ђмvk†ЫДŠ^8::тMJРщїf`с >xјQzЎымoЌ`№№Ы§"Т"8jƒ˜Ё"(4шqлУ3XxјрŒЬTTФйˆpu­рHРћ<М‘O…Ќё9NъбРЌЙxЁ ѕШўюю_ёъфІ­DLД“КV†ШWW{ПБЕJgЮЋЉМпЧуУOШ;!њ-eŸЪЎС ŸВШ|[ПEщЌИ`аХ[ rЌvWŸьэm•“eš№y8ЉfCFП€g€‡w0PXЙ­\љп‹^іАЗ•нPƒGУѕ^РТ{}РњшЬƒai3iфx‰ГГГЅГНЫЖYЈУ›дЎђ›е7Й,Љl‚0C§œgŸЙ}ЗNљ[НцL`[RiС0OюцЯŸ­ьыЙзЋиZАхVnšIМн$[O7чž_Єї(Ќшb`mжєg|<цZ:ZCд‰Чобq№еZЌ!"VвFMт­ЄЙR35Џ‰„•§—oe з4WJМ&Vі_ƒmалlсъЉMa Јўa'FУК0(ёfУе€ъ†xdr JМкužSфkЩaыџВœžњ@MћрюОdзюЧ%ы,œxQИzФ”цвќё%І№IO= $ЯЧ) ЦYкHФLю Че FЙO–Ÿ8Нзb/@ыЉщІєH{-Lо{ЙЉАsј„•dКзмЎЛЖGoї\р‰4šэЊreЫы
ѕКЊFטЁ^г Че ЕoЎАѕКbќ9[ˆz­_t+ sКЛЛ•Jќœ‘ГМ„C Т‚ъ3ЂЁѕƒjЖИ€Ћ^iщ УеЃydМЅэ$Н`xLЮ}–јиќЮ€юђ ююќ9#ŸœшГдzќ|§(–žЊ5иpџ‘Єƒл~zш№ДC№Ірт‹ƒЌц(Zo ?–УЊWу:л™ЗMЩ–‘•=pѕwЄџ&‰pѕјUƒVН2'Ўо$m•”jGЋ^4Й3'Ў^лCЉdЊ3Й3•’^ D@JМ‚>LЪёD#СЩ3G@Ž%ЉЈЩдOдяšSŽDŒеШ{њљyЌ6Oj—PЄ{МPdЦ8_JќOАPѓ№9~хэ„jJќQЉЧъє‰w^NЏCЊ9 #`а#[SуъѕЧ пящ~ГЎПЪАŸ > oЃф†мсЭ†ЋоЖIкєDРДїxЮ—ёФ^І:E–еР&€Б_ћікЪŠJ ў5ј‘,Эь•БТ2JЋœЩ-(ћъkі›~єдh$L›ј€5Лcу№ќ‡ kѓ" ^KX]Єи(zРяЉ0›/„Ў}ЇъJyВ­Е-=3§…9ъ)=Ћ/„Бч] >р•3ЇЮ\8!/'К4J‰ІцFг&ИєU+WХХЧсŽ‹=щ@вЊ7WБА‚7p€ЭOќУD юБ"=ДЇ2 џЎЧ>хЉ)Мшњ-лоџђђ_Wј­РкчA‚zzzŽІ%VŸЮъ ЦоЩе ысЯ=`sМO гЏ.}ѕЉЇў•ZЁЮ}ЩМLЩц:Кю?ыЦЕќ4€ЋЯЮ‘pѕЃ.‰F;Œ-˜>cЂХ?щeы“pѕьhŒњСX3lсIИzсиŒж3†~œ­э“ќˆ€i'wF%Ж…#P_S#ќoa'%ѓ&‰€дуMж‘ЏTJќШЯ‘I<дšеЯvžy&Б#)1@–сЫџ0Щљ_cǘŸIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/18.png0000644000175000017500000021144211733011756026241 0ustar sylvestresylvestre‰PNG  IHDR˜9,dжaРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН \UeОџПЧ8/6еќэˆv|IMEc3:9‡‹Ѕ™bŠЄ/9Іi#ЄЅќ8ZH^ѓ–†”ўрaLgЬЫ8ŠvA;ъЪ„If2ƒŸЅ8*2gxН№uўпЕŸЭУУZЯZ{эьЫgПxmžЫїљ^оЯкћЛзГжоЯ.ежZ№tbbЊ++=JФ СHрG<‘ЧЯЩ Fˆ@@ќ“Рё7ВШёц„œЌ>нБХАbэоНЛефbЙГYœYж?ƒџdY‰<ЖњˆЁ‹Юuш4шrЮ†3в]bдЁƒьU'›s>@{Ф+эьh[˜'1ч0(€tїѓ‚/hpŸ—ћQtє!ЄљŸ&юqЛ+Щви§v‹ѕ6kя[z777SFПn ћоњгŽкМ[{l푇oЏэN—оCZZ,к?`uяE_Л‡4ыщ4ш5xЖм%F†рAЏДГ#Ж85б톈6§3_!юА;Ђњџ›%5!*44ДЎЎцў{юЏ§ЎіRsxCЃС™БUPа^мѕыC&О]поg+йЮухcmЇn iyЛHЦББ-­–#gыз}TCЫМН`ўDъЅ”РdІЦEЭzЌ•Аœќ[}оЁ:њ8ТКшyuЦ4zѕ№.^ cb"#УChйUYџл?ккі—Qнг“ЂЃz…в'‹ъџзИуdнџ*ЙmPзЫЂЧЃњG† SA˜ve ЏЛмђЬ['ШЋеz`~,&œlјgГž*;ѓЙюZKСG5_дк=0rRlTПЁ-–ЭGk>јB!Џ­ˆhНbjХgƒиЅšЙ‡|vД-Єпж(™hъъ”ЬI6уމўЃ  аЙ$яэ“y(ф‰3!hP9 j3” Aq­ЌŽ‚љ š#НкF=„ьaQЋlўgcm]mднQ;vюјХ/тЏ7^ПЎмFYYg)u‹К„rwЫхы!Н„‹r››2PG­2Ѓжѓ­і;сœЊлwЄц‰„шсіkўЁ%яp§cыN~ВHЩyЫ Ж6[ЌX­l>ќЖаЌ-е–Цњ_<9эБ”5WќЁŽл=yЊfпk’Шѕ№.[!tъУбГ‰Є kЖTэ7ы‘hJляќБžz—Ž~›eуо“пж5о>96њ‹П^'г5Xєx.Ёп№‘‡*ы>ЎPIxPљДбќCѓЩ?7Цо>,ЪђпЕжaбЪЇŸъѓѕ}Zы,‘zЊ˜Х“gыvЎљiTјЌ”иЅ)бSs‚œљИШЙѕЋ>‡#Dј‰‡Ѓ+B,Ѓтtƒ’zeгOqЗ‡Іћд‡ ‘—vvД-ќК‰8бв žaшNе}l;КЌЄAЯ1†Я ]C@“v=нсдŽМЂь5q‹ђжксСѓ‚FC1ƒŠK:d(ЎСРŠЩ.(Фи93>t3iзjiюо=22ђЎ{~zџїGEEYš›лпбMh!Зшf(ээjўЗљзИЛ&t("нCЎG„иOІO|A'ЌзїЈЁі„‘}B:ќ8]CЋЕЩBы№Š№ІУuыыš-ŸžVЮЄу~ywHћБRўХщц›ЭzzH~ЬƒЪбvЂЂšОПї х@j ™S4Г[ТCшКƒЅъЛњќ?œќIG7H†zŒ h>~њ4ifиФ-хеŠ{ЩЂ",Э‰бЪ—/ПЎБв%KГž*ћРŠ–›з+ўІ §‰Ua21Fљ|Ая№Iњˆаав\rјtwK‹APz^1ќY/vЭ|Ќ8;ЌQе"NtЙ,ЈT†юDtl”žcм: ОC€gцRїжЫьw@,tІќГ Kˆ<-’?fмPN~эЁиж$ќПyНОокЋWЏИ_ЦЋ9W_oЫ‚CBфзАi†дЇр”›ХFхЃJЈƒГљ6ЛзhОикЛЁYБEчЉ}ЌзšлПЖ~нNЙК~yOxња(eѕЛm ­ƒGX›/Ж­Ўы!g"mZ_јѕpNФfŽ>Dm>V7wHПi)Ъ2@}cЫцOыЋўFпЁonЖ™fђПŒвu€ЮцщAљѕЂЅ{Cc;ДŠкњЦЂFGіщY{w8­чŸћ[=…sї=нзЕ­фЧвv%6Ћ5œљпќУѕВb %пШCƒ єМRЭ‹^ьšzцГcаТЭй'ЈcPv'[дшh”žcтЄpЛ(€tM^ Цв6хžН$ЮалЫ  ai“# кФЄVУ5Ј;œЏЫЂ в,оС1ЈйдуЎ~QббьGZ”Sѓ–цыmЁчА4гjƒюCzЦоamЖmЈии~щК­WїїлЌЭЁaЗu' Ju”УкNжХ1ДТl[§ЎўІЎжz‹5їљсдKk ќ–{‡zъ•\ўњлЛ.QШЖЕхюєŸ!ЭП?QџЭ™šяАDѕ‹>xРМс‘SпЌU% шš=љж§6 „{N+љtUўйGЃ)3ўŠшsGфвЖ’Џ oІT-,€‡)Ÿ0џЛ‡[›Џ*Y\‘iЕeрw zБh‡;UжeрЄžcNY„0€€ЈѓТѕeНpзгіsАДЗi…UЬЬ1/Ј5˜sвXƒж"г*Ж‹Ьй4’’D1qKЃŠУѕеЅЙf—жЏззжќ­ІЅЕ…Ў‘гщјЅњK—ЎвЯЏъоё.ёб($БЯj~lт/вoдL‰SЎВŸ>[Ыв=kє OэJйЧ•›з)‹Lˆnoo+IѕДu*џwR–г“тšoщnЙХњг~‘гЧŽ ѓcЪ‘ЏŽ‹Жv<\o9^gП­ьэвКОЯ*kqB Š=лcћie}iР}ЪDž>]GЙY™C}UЖAђЇ]•ЖЫIБє‘…Я=j{хшeр•h@/v\кйбЖˆ& ЪЅЖЋ нЬ‡;мiЁч˜6tx›€Уїv[ЗhВљeЯ 5ш‡р1 њ&ЬішEСГ8)кќыh*K,-Ј%еюVkdOКDЎ\#8p`x]ј—gЮYщRЄо9§jКЫгccŒоњ`4љ@'Џe'N_З†n=V7mHПžCіЫ=IЯkіжМ82jю(п/—>ЄzDI:У З4г•у‚ч‡Sт9§џпSRЃ•rљОъњєЄ~бН|Эї-G>?aЕаU|ћЊ>SbрРІ#—ЃnГ$ќœnsSТИxЕ™FпZwЙёRу%Кˆадj5P%:Ќ*џў ›џƒ"7?K'В›жб§П?aб ЪР+QГ^ьИДГЃmM”пЉЈ‹ o‘ЂгsŒ]j1а‰./аoЇ“бю­ЪY,{йЉJ_JюnQnЇSиЏ›•+tk[Ÿ{ IвК:гCђLЇT7Gb4„’н:ЇŒlЕ4)ЪC™9К6ommQVѕ[-ДB@к Рахъ”;яHБђщGєЊПДвJƒbє|kiІUЂУ$)VЩŠтПM} h mАн­Ј”БWЄœ=єb7РЅm‹шЙX&Ѓb•;i эОњYх3жšMЛш№ PzŽЕ9Žџ M@š˜,IђV›,/h5№ќз&иў_ЅЭ@хNэвЌj7ШMэVM” Ђрk<.iмHУWeЗ1е;9=a љmEmФѕЦ‡Ъ—]Пr§т•‹ oАќив|зЫ=X~xмbЙŸыЕH›FЁ–TwK§ukЧkьЭXІіМ%вjжѓoБ\Мiџ$A?г@Щеіiхo­с}”Л IJНд~бyН5Д{ˆввЄшR2ЂђБЈtŠzкЛB” щг"SЂT•‹ЭЬ\Ckї0КyЫІ­ЁевЎ\‡ю‚Єљ|kdїіљvпH%}зЎ{ˆђ‰ЄЉMЁ*бae,ЧХќo%/mЈЊpVдъeь•ЌэЁЛ.эьh[DЯХ2йЋѓо^a kО>2NљИVѓч:Ы-іo0ъ9ЦмЦ3€@ 7БЖї1Љu%#ЈЏ лy^pЄATлA›ЁеfЛбзаоэjIT+шHлRC|‰Пmм5UЙo@…0ŠŠ†P)yД^јЗЗТТ›Џ[›šџyНwЯЛшЄГсŸ Д]Jsя‹‰Єры†ЏЯ[,џеQ­nœcы'К†к€ыtЮГrлX[jK‡ЖFЪXЭtУ6Э„цЁеЩET]Є–ўДJдЪeVд2м†­@!АГэŽЭJMЙЯМЃBU*‡UUЉџвFц†WмOЕ3‚ЋzšЉ§МpK?ЉвЖˆž‹eЋ_ж5Пў$нЩZџƒхаЉњЯNазэѓnрw!рrjpy м} \•Ыюƒј9†7:Tы ‘[šk-mh “илУўјэ'УњNP~bніfндмdЅ§VТ›šZšЏqЧ/:ыGХ.бQБн^V<вЫхЫЋ~8TYfЧ#˜ |№ѕхЊšš‹§2’UY5 Е­И3Ф>KРшНн(5Дч‰Ѓœ„'5pЅ.ЬFЁ­=ŠІ•fЃGHя†+У›)‘_Кб}TEk”6ѕmnОЃйRёRUгZšЕDєeпL4бЄ5чŠŽœbкЮпьИЬюœ HZЩhЁеЇхМ•ВИВj Б! 0юч_арўЄИEG„œ)ЙLиэ‘–лŸЅ/YБGћwЛђУ,ЩЌEћЌ\…mЖЪюЏгЪŠ-ЪO “'2gD1*г/Ј(-&$UQ $і|†@šZФxмЯ О С§yq?ŠŽ>ДПѓY•яр{юalЈ­‹ˆъчT.Їмп№]]˜•NЕ=ъŒчТ‚& ИŸ|Aƒ‹С УмBPFХіDоБннšѕіpкgхћПšњXбX˜5œЦŠ-(ƒ€їѓ‚/hp"мBхƒЗ9™!_щOeU %р~^№ юOŸћQˆ>ЈyУЃŸ…GЂ    а%"юP~i›=:$rЪт{fЉ(ДMџA@@|‚РјЗjx.яцС — ‘Л„ ƒ@@@Р7 ‘ћЦ<Р p‰ЙKи0@@|ƒЙoЬМ— ‘Л„ ƒ@@@Р7 ‘ћЦ<Р p‰ЙKи0@@|ƒЙoЬМ— ‘Л„ ƒ@@@Р7tј‰V“.Ќ“hыеDŸFЛ [IGƒNГjАХт+{ƒ‹ лhЈеоb‘„aHF#ЏilИЛs1jCГЕЈн’еQІcЭе(L9ЏђYœ~Њ4CИ_Пi[ЗmE"ІEчцзЯФФ8‡в  аEš[œ?Iш"Waж7 „œЌ>э›žЙрхяъЪJšЂЗјijАЧ„юћщ}ўцЯЄŽ<Іš)ъ”0НхМ9^Зо) ЭХъ5)ПŽбЏїк”BБџш–№PЌїМЏЋЋ]ВlqRђШј„˜ЉiЯ9Zю=[Єй‹YмЋ~CyЇ ќн)v|ТH`Q8> Tзн€t вќЯі5:єИ]Йќ}§ь9ЯЮ=oс‹йсЗ‡здд”ќін„Ё‰n+ю*f—Пюћщ€?SэЌ—ЮŒтž№‚Гж фMщ$o™Šž=n2dјђЅ џFЂ)CZGыўV7ћЙй~ќ!їЫcЗѕrЃМРG{А`JЙ33юДoƒuzИ‰ІbЄЗ—ТЂ‚eŸ\ћюBиџщ9$ўпЇLkіфСaЎ24хvРд)SыўVУ†žЌ89uтxjЄ. F’dЯЌ@ez;xaў ёЧЧЧЦЯݘKяlЌєyѓЦТЄaI$Йdй’–fћ ЉкѕўЎQ#G xPQюЅˆgНДќшБЃLПкhЋeЭ+k’ŽЇ?*HОМЇ'@э+зPDнаЫБ•ŠЯ+туу Т!aТ€ˆFE%ісЮ[7Аы™.g]вХƒЅ‚є ЄЙа#ь™@lZ*?/ЯШЬ ,N5:T†иXќЖ]ЋЅ0_9n“уwНП•5’ЗтA+FЁSжKЯ\ЬЎйkџјбођC yNЯмoЩп”?їЙЙ I Ёжа^‘Н–.YЪeє эzєeаККщіИнбtэjxљ—/”эЯžŸMЏ zМˆ,_СкГ–d=7gСё#еtІrъЬ)jЌЖ…FЯJС6vіџ=sъЬуџ}МќPyџЛю^џкzЎSUињжfњPВїw{Ы?- +Ш/рUЇЊЖџv{uЅ]ЇНн юЙL[hДё‹hДpcaУЅ†НЅeєwёвEЊrпXAO@iПоPіQйо{щC›2;ЬnГхOЧЦ ŠSЊМQх-љ@ŸѓvюЅсd]k”tкКЪДЊч•VX&щЌKК ИrƒPw жOm WЎэъи“ИjхЊъъjхы№Л6m>ћхИ§ИДќв…KіоŽЧйioзЬЉіUЃ2!Џr§‘sI^`C,–ааа1#ЧьмЕ“ЂђФ”1д~ьиБыѕзGБж‹–Д4ЖpНB ЉХм рХDжЃgу5љyф…њЋНюŒdnSсZ§OЎl \ЌоwНс\+а•Й”'&аB:§ }ьБЋзЎrН\Р#…х/-яI#BЇO™~ЦЖMjУў%Ќўj=dїъеkiіRЉЁ=лї 4Рb Н-4}NН;HХЈqлящУJ6Г’1/cџЧЪ)>{,ќO.]З 6їŸЂШ§ЏмЁёCЙИh”>c)Ой/gНЌ§ШЅ' Жгg5ЎМњlѕOЂFLX -6ˆ\Ќ§s^–бч<бŠшžи.ZчњНWM›qI”зsUzšш~˜^нpwп>ыV.Oˆ5vTaўkќ,vїОн rмо:/ѓEnK<~x#LЮЉ8ФуeёhŸfEс…/-\0A\l§:,§^Фа!CyЏЊ@VJ;~XQ hЂбmp*ЬЪŽ_й—ЅOluпзGкV_ъmŸиTbzJћхњШ^ЪВ Єg6№П+ў8?sОJ‰6žŽFћjхY‹ГжЕ†Д-N1фŽq=ЮКЄŠrхМРЌДЧ.#Ь=1(8#зй/*у?3’‡лфО‘}љ4q*HНЅv.l;$s**1(;хT5я1“є`џБПšœ<&5Ђ{їyiКУЇ=5}аƒƒfdЬŽѓвВьЄG’œ5ф yКjX[WЋќЛrŽnЗ@пlЉ§О}—wКЭž~œгjЕж_Ў_џъz7&LžАrнJ–эjЯз’rсNюzЬі‰$щAЙЈЊr@O€кѓѓђmуѓ ђйЈцšПџл_>0PЅD[Ѕ!іБ†ŸѓœВЎЕтg]’‚2у˜ЫЭ(ч2Яem:-ЄWWОЗdљ’ Й|З€N\f=§дОв}эpЖ]}'љйГi§Ю{я}~цѓI“ž;&wCЅ\hOOK/јЏ‚дёЉ$’:2•Њ*пєвgІг§}ЉcRУ~6эЩiG—бР'Oќьпm?Олf"Іуoё2tdkаЯћOўеdхл‰'U*ЃŠП6 NYWF™y8УPыПГ.IAйнlЃд>ы`БЫ›‰O‘1уs3žлО{ћ+k_ЙњЋt$yxШЋ+_ЕУŸ–^№FСф)“I_кЌДv'ЙлЬ›ЖЊtNUЏ6ТСГiч=mжл Е?5хЉ•kVўІ№7\`Фˆ—ОћvьUЭПА IDATјБєY|hвахєхXЎЄуXЁFWю„Š р$]Њ­Ÿ“;tцš†њњ†+u{fй?WъщЁн<Л|?rКsMLеzЎzЊНКњє—_ŸЃЛш=ЅаgѕаЗ>fэwЕ™ѓ3џАуЙЏхоuя]“Ц9˜ˆ˜јžбнGЭ­›Tе ѕ\вkwшЙГ;!F•ЯœгЮw^‹ЄккМѓЅгžtp`KЂ)ˆ ŒЋ&тŽ~+KЏ§§[яž‘ф ЙХgТ,xЃ8}њг-­ЭДЦўXтc–жцc'ŽMўБTp|\™‘1дЂЕn(оБгmыейkz.щЕK•ˆ.T”x'Fб=uйƒ=ЈJэЅ+uД+j1&x„Dіычwбvцщ8‡$/6п ГwяоcЇLnjmЂЋŒOЯ|šЃяФгt˜ёаŒ ŸYiAk]*&mtпКT­žKzэR%bЃЫI‰—bнS•=hбƒЊTNЂ ]Bgф]‚FH—JŽх4ќgц4=N4Иlн NŠъЙЄзюPНЫjіИ€Gцду^yL!.{ e* ЉЏЋ ва ›^iС№b ’0šzg…ƒЁ_Чш›Ю“Wx€€ЋМјѕ3W]ђЙq МџўЈв?”њœgp@@ ш `iнд!ЃќјкС<—[­ЃЉљvC(њuŒОщ|еWжнnv@ЂЂЂXЦ1ЙYVD6њОћЭJC@L яєš–…`€8xЈŒ"t*—#‘;qL№\œQ0MрўшћЯеœs*‘уЙiКп#€Dю{s@@@Р4$rгЈ   ОG‰мїц€€€iHфІQA@@|ЙяЭ <гШMЃ‚ €€ј$rп›x  І рaLЃ‚  “•'jkkƒ&\ GР…_`uшЙCDр"РВx\Bbp…hA Sœ8RNvœњс6‡~!‘;D.t.NY<6&6ИТFД а)Ђя‹оњіfЯ&r\#я”Љƒ№$rяp…Vш,bb:Ыь€ј"nЛvяєEПр€€!фoC<ш "аmт„IA.BЏЈЋЋ]ВlqRђШј„˜ЉiЯ9ЊмвтНGueЅї”C3€€РвКM\ѕ]—ПЏŸ=чй‡bкЛsЧёO+WМАшЃ?ђ]wс€@@" ЩD(]G ПИhжЌД1cSУУУ-ЗXЂћGПВz­н›–59ЙIУщ –›іfZпПЗtд„qЪќД)ееЇ~tpќ“утЧLљLнyћзИIlыћя%І}ОJЎ wsQБmI qЩЪU--ЭL€4аДQcЧ lПšŽey-:Д€€џ@"їпЙƒч>Dриёc#M–:TјFAУ•‹{ї”впХ+ЉЪХ**+JŠ‹Ъ=*%-sоЇЧm**џьшшУVфЌрbU•U{ЗЃliУ•ы…›‹yЛЊАЕфНЊoЮюнОЃќPY˜еRPиnЈъЋГлЗ”TŽеx3TA рfЗ@˜EФахšЎ] я.uу@йўьљйtІN—чg(ћ„‹-|1ЛWШаPыЄ‰“nќу†X=sЊš‹ёсT8№СоЎ*lлЗ;;+“м …s2їrˆ ,ЬШ$ыМŠыы BцfМ{0#"A а…ТzєlМж(ЭхъЏіК3’љF…kѕИŸ<ЙRъЅFБzЃ•KYє†ЗKиJзОЛђФ„іFсзžЄŽЕKЂ рЯBhєgџс;ј!ёC.“~ЄodOКŽ%c*єˆьщЌЧ‡їео#Вoй;%Шйz|аJзШufWЇШLŸ§ж[›їя/mЁOЦ7-5ЎЁЏЂ1R’Чффх4к+ѓrЈъЌg9љl8щIЂ7ќЉЩV­[IYŸш^9КпMO7Лщ‘A;ј#~Ќ?zŸAРGа wбoвНыЏ§ЙMM7~vџ€gf>У|›7'}ЭkЩуSЉš:2•ЊЮњ<шСўc5ЙщšR>/MwјДЇІ“цГi§ž{я}&эyg A@Р —бќб}ј >C _ПЈзљWЮDЏnБ.ЭЮЂ?БЪЊ;Ю ЊгžœNzУХ”ЫY:…EжЎmхQ№/н,­і/›њ—п№@@@€tCЧq  ўK7ЛљямСѓ  €e№ ˜f n Ѕu7Fc(€€€@—РЭn]ŠЦAРїDEE8R}_ДяЙ@Ря l}{3НФ<%ђЯj„6П&Gўгл_GчAР7 Pg/1К‚Ѕuв„* єFуёїšР ƒ(@Р tУљИЮ \“pзКIP_$а ?бъ‹гŸ@@@Рœ‘›у)№I”Шёлn>93p @@LшжŒ„1 "   р›№ƒ0О9/№ К’РЩЪЕЕЕ]щlƒ@€№ЪїШ[~РаєxAX р–Ху]A FшgЉлГПгR~ИЬШ&њ@‚Œ‹S‰ ВИ.tњёcњйDЯ&ђn'Lъ пa@@@Р №ѕ3/@э •bbДfЅZ1oЉЎ>=jь8Oы)=Fеяю420AB‰<(&коыНчC^~отE‹ƒmпnяё Š—‚"€Dо>™uuЕK–-NJŸ35э™#G•[уб%IN•iМчУ™sMˆU6ьrэЁђг5%?Ъ{<;?Xp‡ЙохяыgЯyіЁ˜‡іюмqќгЪ/,њшум!‹БFрFг Ы-f †@@РЗtлЕ{ЇoyдEофЭš•6fljxx8e…шўбЏЌ^kїхІeMNnвАDњЃџuz:“лПЗtд„qЪќД)tЅірGЧ?9.~pЬд™ЯдЗ зЄихЫѕ/,Z?,1>!qnж‚ЦЦFf]ОпfХЎЖF№j 'Йѕ}“ШO:uЕY,›‹ŠmЋ‰KVЎji‘§оŸ>‡­яПGn3krV1>Ь"=‹ІЯuxЪ"ЅoC^ЂJЈ …]Iл?Е!}'щPW.Ѕюp3zИM­И9D… cRrт.>)њ.™<~ДxЩMЖ„ђ_:‰$ЉŠ]:Vдƒ2€€Р]ыіЩ:vќиˆG“Ѕ3WјFAУ•‹{ї”впХ+ЉЪХ**+JŠ‹Ъ=*%-sоЇЧm**џьшшУVфЌpJlі‚Ь™“Ї?XVўQYџЛю^_˜п>ќOUл‹KHэАG‡­xek/м\мpхzйўвНПлAnpa‡… ™Ж­%яU}svяіх‡ЪТЌ–‚ТіЙBU•Uф9C.‘c4„-ќвГvи@дЗЌХЫž›ѓќёc•%›ŠNљ†ћУ *CЪЋО:Л}KIѕч•Ђеpж%uУ ЂЭяŸ§ЫyТјёžВKW.1m.™<~ДxХxйРCiь| ~MKыіщkКv5МGИt.”эЯžŸMgъєxy~іВOИиТГ{ѕˆ ЕNš8щЦ?nˆе3ЇЊлГuћ€A-ЗXCoГІЇЅћьОќХLђЌLŸ2щЬWvЕ>8 zХ…ЄкЖэлeЗ’1'sџ'‡Дz 8pOЈ@ŽiЧŠ-zЄО………е_ЅŠЦ^Н"—fg‰ЊДeх 32iЕCД-R7Ь кНяРЫYйЪdнf77ƒi6rЩмёcЏ‡ЊиЕŸЎДа р/№­і™ ыбГёZЃ4—_ЈПкыЮH&G…kѕјьђФ@Y–Хъ сGьХv=БъГ5tїѕ™š3є@б/ЬLшmієCVИк ѕDЏ”!цRmзОЛђФ„v‚uоhРAєDфУЧŠ=Rпђ_[_єіЛ… #~Ж kqТ`Ѓћк ”K'WtŒ—Ѕn˜Cд>)\›‘Km,Œ“x <4;w!‚kфlЊ†Ф9xИLњѓ8}#{в­pьЭ” ="{zcvОДpСќ‰Бqt2G—Јc† 5Жв7ВЏш•БАУо‘}Ыо)1~Л7р zBЊŒЭш‘ЄBz}rП],_О|й‡|,cЮ*7PЅъ2‡Ј}Rјpї]2‰зŒ‡м+@†@7ќЂ2›ЫЬєйoНЕ™юrjљЁ‘nзЊљs }uЅ$ЩЩЫQжvWцхPегпддdЕZB­VКыmеЋыšHI~,Ї пцT#ЙчPоXрЉЩV­[I ƒФш6=КпM+oРAє$et лГЧ­uпK6о0аЃ5J-ф }3PЙ‡Ўев$ЌsH…UNJєќTщ7ƒhТ)+sshiЇх‡fКыipС%•i)^• UЭxШFсf7-=Д€€џш†_Tf“G'мEoМyјxХШёЉёI1ЏцЌ{|фуЌkоœєˆ;њ$OЅП>wєЁЊ7ц{ѕђ%r7 3#}і ћ;41oNFФэжф1Љc5yPЬCхІ=5}аƒƒfdЬІ›У_Z–єH’Vо€9Ln3нЛЯKГѓI›‘>iкtmЮ0аЃ5J-I<”™•?$&ЏpCюкеRошЌrЈч'зЩ fЅЭLяянcЇL9~lяоНй@\R™–тUЩPеŒ‡кQh№w?њпџ§пЛFg ЙІЁООсJнžYбЦ!бRќˆсЩќЂЏБ0zƒЅjм<хН‰ю|МєЧІ)о›PhrДŒJ›ІH/у22єMцs5ч ˜ијЗj"юшwБВєкпПХ]ыA~P!|џ&€DюпѓяA@‚œyыъ€ЈЏxѕй @@!€DŽу@@ќ˜€ь‡?ќ8И р.ЈЈЈGЪщыћю*Тx Кг^bšfЗШнТ‡С xbc”пЮЃЗ›Р @— ,Ю^bє‰мƒ0Ё „НбxќН&@а №=ИFю{s@@@Р4$rгЈ   ОG‰мїц€€€iHфІQA@@|ЙяЭ <гШMЃ‚ €€ј$rп›x  І ‘›FA№=A‘ШЋЋN'Iћ:‹ќUUБЫїЫДaэЈБуД!h[TБш T‰щщбkW зV]HЊмxSЏeи-NЭО›‡З’в#ЪЬ@зdxјМ`FSТfžL€!ъF›œо$Љ"Ъл˜—ћJ.лE*0ц//?oёЂХ.ь‹хђ@RЉњѕдЦБꙇJ'о8Ђ:sBaЫ$n^њEхККкВФKЄ?*дЏuш›o[УЯœћkь Ь’ŸCЯ;M€ЧH%Ф*?ˆэьCШЕ9ЋФлђtЬЏЇоŽUЮ…Uщтс-ЪxаtQЄ'N Ъ$аmт„ITЧT]ўОўщ9Я>њШЃх–бžžћ,5zмI…7šn˜”є1%Ђ[\qжхЎѓ17ѕ>еw]ш„УG”яN{ц•kфљяЅЭ˜6fLjhЈ•ўЈ@е7п)bœUŸяX•?ѓ^*l}џ=КЖŸИ&g•хІ}–И€ЈM;œЯЉиEeеp&ЖЙЈ8)Y1ДdхЊ––f>–hдў§ЅЃ&Œ‹3uц3uчkXзхЫѕ/,ZЌ,<$$ЮЭZРЏS(ђ{mђ 1SЇMЁKw?:8ўI>М}}ТЁiю/Аш™xЛЊ е,ЫЊЌ*…Я%—тkў\CWїwэоЩ[TЉcRј4PЃЈMTEeVj %ЕnDРCSЯ>Yy‚Ž":іш$gT!(е›–Тt '%'юzПэMЫšœмЄa‰єGё$Hk…9@Ям*ам)їg Vю8сэЬЅіЊЦжEЯэ2zгЇИНŠ^PєкпЪcaјГ,4Љ юЄЪД” ЛvD‘r‹TЯј уh’E@яЌ@-дNeНУ‰‰щ>Ы80aщыз |еЄG•YЁ^)IНpyН:ŒLHп‚ЬWК }НУ+‰ќиБcЉ#žCЇ*5Š-Њ2[EЄgq9БЊВjяяv”э/mИrНpsБjˆX•gb—ЈœпZђ^е7gїnпQ~Ј,Ьj)(,р]bЁтOUл‹KЪ?;:ьбa+^YЧКf/Шœ9yЪёƒeх•ѕПыюѕ…љ|HEeEIqQљЁЃЃGЅЄeЮћєисЂME4|єˆa+rV01“ІЙNV#RuёЊTГ8P,ѓQbСОQр2PLѓЩЯO<;7cёЂы@RЧЄ№Ѕ1Š!ˆЊXYьЅВC L^jнˆ€ЇЇ>kёВчц<ќXeЩІЂSgОQEAеЭяŸ§Ыy:†?оSvщЪ%&PјFAУ•‹{ї”впХ+ЉЪJ#вZђБU_нОЅЄњѓJоЂ-h§бЊвƒOЏtzНгЋž^ћє"в*ЇihZlЌД]J@Я%юƒЈŠ•y—ˆEЊgHтгUЇIОёZувѕЋй У‰ЊгдN‡7Ё-H901узЏдChfтTnHI„уЉ7F#ВЗ 3Ч•*4?Њz%‘_Нv5МGИHЊзЎ][Ь”Гчg‡лT8№С3C\йЖowvV&yH‹s2їrHЊdљ‹v™щS&љЊšЩьйК}]}ПХz›5=-§иgэVΘнЋG$щœ4qвмЋgN釛4-ѕЧИб}ЭЦ№ —‚"owэ-]Оnй› ';Џэ•ъt?F“Єж ˆsэ‘Љ ЋПJЫ=НzE.ЭЮвђйНяРЫYйЪ1|›uом &p l?ŸФ—щTі (ШЁ6|aF&Н(Й*iAъJR>НвEЗUЃXе 4ЉМЖQJ@Я%эpm‹ˆEЊ'>ў‘ŠSU4АєрОААƒ•“ђЊSдNƒУIk‹Зpр Љ }ѓ”zHjЭLЗЮ R’сxъеa`Bъ’™уJšUC 9]ЃgžєЉSЬхTэбЃЇГ {нЩ†PсZ§g‡›”Пін…”'&Д ыlбz›§Э‹rѓVЛxѕйКQіLЭzПVš„БќЭŽфЉGЌђс&Mл9ѓЯ}ЭЦ№ —‚"пЗmykТЃя‹v&ЛЌTЇћ1šд Еn@@œk @ЌК6ѕљЏ­/zћнТ…?[Е8aАњ>Ч ѕј|qМъЏђFе+H‘C+LГјКцЖTЉ?*=јтXюПjЌAh*IНЊ”€žKzJФv‹TOм kз­Ѕ!”Ш]ЕzгЛяа5Ч/ОјzљKЫЉбрp­ЈЪ8:ед3 RЉK„ЏВЅW•’4G|9NБъдЋУР„д%14G/(ПkЙ?њ~ЫСo=ыїј!єЉsк“гЙZЊўrˆВ‚D[C,ДЌФвПЈЬКTЯt#N…‘}YЏљс*mzUв\іN‰ј:д“дЖ/|iс‚љ cушLˆ‚Š2T+cатŽiЕдхОf)|nд…Рп-.™™>Уz{їiOzцўJїctGƒ 8=g'ˆ>§МnЫt{љђe~№БЈŠЪ}#ћђљт]}#{ђFл+ШС'i‡VИf^а{1J§сЃXAО8–мVbUgC“*б6ъЙЄ•4n‘ъЁwМŸєыsфгrЋ5,vpмІЭ›Ž|^N-ьаЕУЩ€CЧЉЗПyrЗЅRЏŸ ЛPp-nHЯ=.@gMˆЁщWЂ~џ*w;~њK{<;}ЦцЗЖвM”лш TЭ|f63tЯЯМЗ}'ЕгiњњзrИѕž=n­ћО§.0jЯ)ШWжsђrRFЇ8;œk6.<5yТЊu+йдвзфш~7cyБЗЉЉЩjЕ„Z­tчХЊWз‹]fЪІХлRЬЈRЩhц’ZрМ‹ Rј\Р…РщЃхђнПпНuл{\4LcЧјX31raiС .}pЪ4“Ъ}RtПgЋЅЉUTc/Ox"eenН Z~hІ›•XkJђzсАWаJz%‘ŒšЄVŒчBяЕ,ѕGЅJ@JђcтБ'8и^t64•щvEKz.u”r\ггѓаа‡зцm:šTŒ5zэК дТдЙv8pђ7OюКž‡f&Ž+1(ИWЈч ‚Г&ЬWЂ~џ*w{ёџОшqћнЕЅшЭ?;œ8*™ўЈ@UОšБbЩЂџ>ќп‰ ’>уЁ˜‡ИѕДщ“ІMпй=иьЏ&'Iшо}^Z:“4?œk6.L{jњ ЭؘMwПД,;щ‘$cyБwѕђ%r7 3#}6y+v™)ЛcкXПЭZрЂN)|.рZрJ.Гhї‡ш^RE7ѓЧЦФrМ`ь3#–мбрю†SІ“y(3+;~HL^с†мЕЋЙ^H›™оџоЛЧN™•ўњмб‡Њ\^ZZ1ž нЃЬ•*=ѓцdDмnЅW=Ні яЂЯЮ†І2-ЊЫz.‰2fЪzzутщсˆЄdR2bx2•уьї‹Иv8p0~§ъy(=LвЩИз ч ‚Г&ЬWЂ~џ*џшњѕыПјевЁ3з4дз7\Љл3ЫС%LКІN‡ ПАсНh)ЃЋю ѕž-hюs3ž›ѓыч”Лё№>њв ёз Мя,8&@g8чjЮ|Е‡ЉџVMФ§.V–^ћћЗТнYŽѕC?Ё о`П^Љ6еp‡Uкcј‹/О 1ЖЧ№яї@eкc˜кŽ…€€ИO ФзШѕv“ЅMBwџўРoўkУкм ‰ ‰|?41 НБЂŒX6оDй`П^Q‰Ыeу=†]V‹   `’€WЮШЅЛЩвфДIшњ5Ћ†&.^Дј?ПdЙЉ\ Wm,kŒte.oА_/—1_`ЗЙЉф іVIЂ   'р•нЯh7Yr”vјІuђ{юНї™ДчЉšћкњЉSž0@YsNWџ]эšзж/Э^Ю6ЛНёьŠВtЌAиlхяkџB†Д[5г~Нk^+ §˜ICъШT‡[2выЂ=† ђђљУЙЙ9|aН!hOјбЅя.ХЇ­ёС§Ш=!є€€€€Пpa?rZZoё—№р'€€€€Š€З~FeUoш†ѓqo`…Nш^ЙkНs\‡$r   рЧК5џр_[їc"p@@ќˆ@ЗищGюТU‘@ЗI‹&‰u”A@@ќˆЎ‘ћбdСUP@"WA@@ќˆЙM\5ЏlšЂ6‚:€€_8YyЂЖЖжЏ\†Г рЂЂЂbcт<ы+ЙgyBј=–Ху§>ОGрФ‘rrЪГЙ‰мїц@— sqЪтБ1Б]ъŒƒ@`ˆО/zыл›=›Шq<0D  $ШƒdЂ&€€@`@"ЬyET  AB‰ IDATœWD  $ШƒdЂ&€€@`@"ЬyET  AB‰!qЩЪU--ЭЌ>зьп_ЪNтЇЮ|Ію|Cљ]Лw*—m+зГ/_Ўaбтјa‰Є–hI€йg%z?4I­[nZжфЌЂБt…lыћ;ЙiБ@‹ SЇMЁ5r’\ЕwнДn, p’’wЕ $sЂoм:ЖОџ™ CdŽŒвƒѕв3’ŒVП4XІJЁЈSыы•“GЪœБЁЫM–HkrrYPЬЉ!1LЙEGs!!І ‘јР}— БXєXЩНjг%ЊЂ2ЋВxХIЇ­žёЦеее2M?:Ш дBэTж›V&ІїLьпk{с$ФаёIWяHѓј'•Х0лыШnNWЙtNuрˆСКFЂрJXDМЊ"}а?Д„™~еDДЃгQХ|рЯTЫlИI[zbкаД&к§ДQв!Нy$mfв ѕP4­-ыЙ*m—КЭ$IГќ]ДЭЄЈЪ|ѕ;p[gfл+џЙ6cФ!TжкU9Щ4sхЊсSѕJ"?ійЁдQOшАЕфНЊoЮюнОЃќPY˜еRPXР%+ўTЕНИЄќГЃУЖт•uЌн@ОъЋГлЗ”TЎ\ЊœН sцф)Ч–•TжџЎЛзцS#[KЁgОЈЂЇ­psqУ•ыeћKїўnGEewI,d-^імœчЋЄ•†SgОa]›п->ћ—ѓЮЧ{Ъ.]ЙФхEпx#Њ*ЋШ"sd”ZДNŠђR§в`й()CQ!•Е>PЃqЌд™Т7 Ў\мЛЇ”ў.^ЙHU>DjˆїъYt8Zb>0sк!д.eЅчw[TХЪМKœtЉž!‰CNW&yZЕZК~5ћ{Ђъ4ЕSЃСДrвБ%ХEх‡ŽŽ•’–9ягc‡‹6быhєˆa+rVА!zЪЅsJCЄpDыRiдт(уВTЇоё``KœбЂž*&ЃYja&mˆiCЭ‰NђВvuщЭ#u™9 <фvЕ=WЅэRЗЙNщЛ(яВ2ыrшЖёЬr§Ќ`ьƒ(,ЕЋu’ZDoE SіJ"Пvэjxp}TaЌeлОнйY™$jݘ“Йџ“C\rљ‹ііщS&љЊкЁќТŒL:нgb{Жn@—-oБ†оfMOK?ій1ЎV,шY?№СьљйЄ/ЯЯ‡№rXXX§U:еoЄ•†ЅйYЌ}їО/ge+смf77ƒ ‹ОёF*p+T Ѓb—Д,еoЌ”ЁJГд=2тXЉ3Ъіs…„ю@й'|o—ЋgбЬ\pЌ`рƒJRЌJYщy%д+‹“.еџHХЉ*^zp_XHиСƒЪIyеЉ jЇ‚СДъYdэ _Ьюе#’^P“&NКёbѕЬ)ћыHOЙtNI­Žш†T@Е8ЪИ,еЉw<и'BДЈЇJ”‘–Mк2“†&ЕХЅCєц‘F‰ѓЎwxШэКYКЭuJпEyЏ^СЁлNЭЌyкеsИ“лНrМGžtТСs9ћЈТWЎ}w!х‰ эq .„оfЯЪє–tЃе.b ЯMhѕйКЏђLЭ:‚•‘‚ZЛ"л?=mъ/єК3’Iђ‚8ЪљЏ­/zћнТ…?[Е8aАrы‡8P”}лЙr*\ЋП vIЫR§СJЊ4K}а##Ž•:sЁўЊT! дkg:ѕ,ŠVИб mйР­0o‘ВвѓŠ2(ˆ“.е7hркukIУЅrW­оєю;cЦЄ~ёХзЫ_ZNгj`”Кшг' ŽЊЪ_GzЪEкЂ)‡вЈХQЦeЉQбCёx0А%N„hQO•(#-›Дe & Mj‹7J‡шЭ#2sxШэКYКЭuJпEyЏ^СЁлNЭЌyкеsИ“лuв{^ 2ЄєУ}гžš.Uг#Вoй;%zЏ4э“ђ _ZИ`ў‚Фи8:3Іۘ!CЕЊЈEO[пШО—ПЏgoTŽО/њuлЛ0]bYО|й‡|Lbт@щ(UЃh…œQѕjЋR§&ƒеjc-RєШˆJЄЮєьйQaO>ЄcЛ:X=‹ЂвРЕ |0%эвѓJ*lа(еC‰і'§њљДмj ЃG6mоtфѓrja иЭi5p†Кє”‹Д5˜щ•F­xkˆ…^Ё,dv/‹J@U=3ЖLЊR‰iЋ&m™гъ7пЂ7&5t‚‡ЦžHпE‡PЏCЗѕЉfѓ>8Д+епљ^YZ6}іЖ[7—МGїePHєЂЅЬЧc{jђ„UыVВdнљZКпwI &х›ššЌVKЈеJFWНКžЋъйужКяэїћPЃžЖ”фЧr ђ•uѓЦЦœМ>\,ЋЪJt‡ZЋЅЉmС`Т)+sshЂх‡fК+M”—–E+)ЃS˜ŒЪIq TП^Ат@ƒВд=2ЂЉ3)ЩcˆCЗ2/‡Њ|ˆдяеГhf.TФ |рцTCxЛЊ ч•JЬaUOЯCC^›Зatъhв0zдшЕы6P гццДЛЄЇ\:ЇЦЊ zѕЂ‡мѓѓяmпIo єЊYџšќЕ&Ъыfl‰zЈЌЇJ%І­šДeRŒы7yLry*шЭЃ(cP6№/š зv9‚є]TЋVеbр6“tjfЭћра.Yw–€*4TНrFN—KŠЗМљЮ–щO_ЋПіzўћ/~іvёo˜ЧьL}FЦlZЕИчо{ŸI{о8“ђЋ—/йЛсљяаGГYП~j_щ>І6mFњЄiгiН­№ыi›7'cЭЋЋ’ЧЄ†§8,mFZйсr­WI<”™•§}э_ШэмЕЋэњgІгVcЇLІъМйiкQЊ–AіћЋЩMџг”њј№yiщv%‡ЄЩєы+4(K}а##ъ‘:3oNњšз ’ЧЇ’dъШTЊђ!RCМWЯЂ™ЙPMЋмœjoWєМR‰9ЌъщIŒ‹/ШЫ‘”LF OЮЭЭIŒKdкмœVc—є”KчдX•AЏ^дтK­XЙЎxS~ы;їщYћ>,{ЕeНуСŒ-•6=U*1mеЄ-“b\ПЩc’ЫSAoEƒВГЈb]Ю† }uhХЁлNЭЌyк%Я%р0X~tюЯ%.:sMC}}У•К=ГЂЕаї:шн‡_Œ1FЏŠ}цэк›UўxЕTСz•$”ƒњщЙšs'L2yќ[5wєЛXYzэяпzeiниNP0cDь  РtЛџGЅ`ЁGР/vЦеsэ  С@Р[gфвЈ9PЃ-uЅЗЌљs m@N?Jгж ўЯЮішY<э“юK#ЕЭŠъDU*…\ЬX‰б@Љu#&і–vшМтЁоНJЛ|ыni8їюе‹QКOЙHUqRѕpfol#†вЃшfѓšWј–ѓя1O˜}iр*зPп$р­DnМЕб–КВ-ЩЛ“ŸŸxvnЦтE ~ђ†}х‰žХя>IїЧ•n4+N’ЈJдЦej`’RыFLь-mЦДоНz[wыщ4ГwЏ4FЉ!‘*'Щ NэmФPvОQм№ЯfЖх|еЉГмЈ^р\№eоJфЦQlЉЋЗ—эЎНЅЫз-{scAТ`ћS›Ч*ещўFГ&5H­№дІТzєъmн­Ž™Н{Ѕ1ъ2˜8ЇіЦ6`ЈуЯ'йѓ3щз…щ‘‘Щна œ   ОLР+›ІPР|л`*hwн6иRWo/лm[оš№ФDк~ЮšRюo4kRƒдКJ3,FƒНЅЭ˜жл Woыn=fію•ЦЈgШ`EŸE1Љ~†RyEy/Щ–ѓz‹   >KР[‰мx#jЖд}ЗИdfњ ыэнЇ=щрЇфMВvЃYw4И@@ŒЫŒiН zѕЖюжгi~я^бC*ыR‰‰UбgБ]Zv–ЁтЯхz–ЫнмжZъA@ Kxkiнx#jЖд яNЙ|їяwoні'%оЏФMюkfЃYЎSZpGƒ Dܘжл Woыn=цїю=ЄВž!ƒ rjolgкќЩgћІгёЩНе œЄˆ€јo%rЖ5mябН;пu›ЬЖд0$fFњl’фэЦ%—ПYДћУtwIв^oБ1Бк!lwX‡oСДбь бЖшёƒc^Z–єH’V•q‹;\#Р§1cš6шИнJS@лŸŠyˆЅ­Л#юшCл‡г_Ÿ;њ№эУѕtВН{у‡ФфnрЛАsm=CD{cїПїnкм}фјБН{ї6PN]Ю2LOKoђѓўЗЖ­FщnlН  р#~dБМ5ъ[м|nЦss~§м€A}%м№#uuЕГчg~Ић~ф3\СЕљЦ‚MШтСpX{0ЦТ-?4гъz~A~ЪАЧ<ЈЊ@@ ЋД-/v•}иN$@ЫѕДhпдк4ќ‘сДво‰–a @МE‰м[dЁз аO ќš: —@@Р!oньца0@@@м'€Dю>Ch.#€Dоeшa@@м'€Dю>Ch.#€Dоeшa@@м'€Dю>Ch.#rюS“Gt™}№='+Oджжњž_№ќž@TTTlLœgУРїШ=Ык@Ря А,—шї‘ №='Ž”“SžЭхHфО7Я№К”‹S—юHдЅ~С8кzыл›=›Шq<Ž Ф  ДШƒvъИыn’k ККъtвш‘юh0PЎэт†xA+ƒП&€Dюзгз5Ю#%ИУ=oc^ю+Йе••Є$н!‰Б Œy0 Д•'mш9jТИјС1IЩ#_XДјdеiѓ X2МќфСˆЮœћkь ŒžC’б Œnv Ц#aСŠХwїэSВЉЈWЏHкœћtе—яОН)Ж`S0Вшє˜o4ншt›0 ШpFШГЋ[хчхs2(‹“@xxxBRтFžХoZшdNг“’wНП“i ѓб]ЛwŽ;nРрjсЇЇTињў{tХ7>!qMЮ*ЫMEœѕв3cJи35юп_ЪІЮ|Ію| kП|Йžт‡%’ЊЙY шуEЛќ^›|BЬдiSЊЋOќшрј'•Ел№ія:o.*&Зiј’•ЋZZšEЃіђMЫšœмЄa‰єGц-uщЙФ5А@ш™XЛ4 ъ2vCT%*ЄВHXЊgќ„quuіx sƒZЈЪz™˜ъY Dе…*€€п@"їЛ)ѓ€У1ЦЎzu}ѕйЫMuТлќnёйПœпЛ}ЧЧ{Ъ.]ЙФU}uvћ–’ъЯ•+ЛтЃЊВjяяv”э/mИrНps1uБхbzж[7ЎјSеіт’ђЯŽ{tиŠWж1mГdЮœ<хјСВђЪњпuїњТ|nЅЂВЂЄИЈќаббЃRв2ч}zьpбІ">zФА9+˜иж’їЊО9Kn—* ГZ %ПqTјFAУ•‹{ї”впХ+ЉкnBця•F$ТЁЂ*‘АTЯФ!ЇmW@Џ5.]Пš}X9QušкЩU€<@’y@NЋƒ 6Мšwwя>ы^YŸ”Lчйt NWЭй˜нћМœ•о#<є6ыМЙ\бТŒL:wчU^ШžŸMэє Т№vƒТђ3§ЁжщS&љЊšIюйК}]9ОХJvггв}vŒkXјbvЏ‘$?iтЄџИ!VЯœВпЖowv–]mЦœЬ§ŸтУyс@й~юэЫфmй'МKъя•ЄCЬИ!еF"aЉžјјG*NU‘dщС}a!a*'хUЇ*Ј ЉWѕP}†PѕЂ  р_pмПцЫ3оRВL›NЄŽжfЗќnЧ‚Ѕ‹7цm ъ…њ НюT–мUJНЊVхТTИVA*Ѓj НЭЎŠrѓV{'-фхчЉ9CЉZiLњ”Р„Hž b•Пін…”'&01хYЮ/д_еѓVъ(-H‡˜qCЊEТR=qƒЎ]З–$?(=ЛjѕІwп3&ѕ‹/О^ўвrj4Јgэ A@і†‘! sњѕ‹ЪњЯŒФсC™xпШО—ПЏч ЯЁ.L…‘}Ъы ,|iс‚љ cушC-Ч БћЃ'Џj'гeя”ˆЙP%@еО‘=;zлS+уf‹7ܘъЁЯ1?щзчШЇхVkXьрИM›7љМœZич7šё 2 ОIKыО9/оѕjnЦs”и e—ЏеМQќГc™Щ OЄЌЬЭЁЋАь+j§Ш)Ш'=єШЩЫIТф{іИЕюћіла*!ІІ&ЋеjЕвM[t§оЬQцЉЩV­[IyšыЮзв§nb/+Ї$!'™З+Щлф1ZН“™qCЯ„иЎЇчЁЁЏЭл0:u4 5zэК дТ:7Л‰ДQ'€Dюя3шŠџs~§м>љhьЄЩtњŒgf777ч­y•)J›™оџоЛЧN™шСўc59yLjDїюѓв”ЕzzЄЭHŸ4mКSйbѕђ%r7 3#}6щdzЬ?O{jњ ЭؘMwГПД,;щ‘$эиysв#юш“<>•ўњмб‡ЊZН“™qCЯ„иЎЇ'1.žЎ_ŒHJ&сУ“ЉœgпкФM€Ђu”Aќ‹РЮ§я9кЦtшЬ5 ѕѕ WъіЬŠ6€О$Cя ќ:ЅБ0z›Ѕjм6xSLЏqlšxгŠˆ|„- вІ)'Lвѓ‡Оd{Ўцœ8ў­šˆ;њ]Ќ,НіїoqFЎэ   рШ§`’р"€€ш@"з#ƒvЧАЎю˜$@@РЫШН ъA@@Р›№=roв…n№CQQQ'Ž”GпчрОW?Œ .ƒ@з ;нш%цY?Ш=Ык@Ря ФЦФQ єvуї‘ №=”ХйKЬƒЎ…Œ§iВх'ЉдU ўN€оh<ў^уяLр?ј,n[Ъэ[UњЌ‹p @@@@@З№^ђЭ0є @@@РwрЎuп™ x  N@"w€€€€я@"їЙ€'   р4$rЇ‘a€€јЦЫžѕІњlgB€€§=љƒK!O'NђьїШ‡HИ €€x–@}]†ь§ІŒі#ї FЯњчAЧ  @@Ў‘оœ"" "€DD“PA@yрЭ)""HфA4й@@ № ‘оœ"" "€DD“PA@yрЭ)""HфA4й@@ № ‘оœ"" "€DD“PA@yрЭ)""HфA4й@@ № ‘оœ"" "€DD“PA@yрЭ)""HфA4й@@ № ‘оœ"" "€DD“PA@@Hр…$FTsЖцєз_Š-кђР~н?Zлю-еUЇ3–d]Н|ЕКВВУ ёB'ѕˆ‰ъъг —.П№н…ЮхŸЁ@Ь№DNY|юќŒAlЬ{нyоЦМмWrc ЄЛ<ЙvЙ—ŸЗxбт„Сq2ш$Kы­–Ќь,њГДкцHUеŸЗ­яя08†žѕEКИчЬЙПВ,N~tљЙfЇ9@ŸœхN b%YмUІ=ЋЭРК@@€№3r%NJлKВJо)a1гљЋЊЪYh лvl{yQіЖ-лІ=9Iлы -7šnј‚Ояƒъпw‚€€г‚уŒМ Ѕѓ‡‡=Ь“z[ГќџЩЯODќ8bтиI'+Op!*O6%~pЬЈ уія/eэвFељЏRaџоRŸCЊшђэСŽrщœ:ѓ™КѓЕмжцЂтЄф‘ё ‰KVЎjiiцэЌРв3џуэЛvя5v-'А­žёЦеей ‘u&F-дNхЫ—ы_XД8~X"™ž›Е ББ‘ ?3HFJCK’[п/iДкšœU–›іN=Л$Я#bVш™DЕJљІeMNnвАDњЃгь`ˆM…išeeВьГSCтПžѓмСOэаЈJcGйђƒz‚lŠё о%‰œЮТg<3ƒќЫ7ajЁvКлwoŸ:e* ќjтдэяoч’Y‹—=7чљуЧ*K6:ѓ k—6ђ!кBEeEIqQљЁЃЃGЅЄeЮћєисЂMEхŸ=bиŠœL~kЩ{UпœнЛ}GљЁВ0ЋЅ А@Ѕ‡-eг3ћ{ЋО:Л}KIѕчЪpR=C‡œЎ:MНз—Ў_Э>%œЈ:Mэд8{AцЬЩSŽ,+џЈЌџ]wЏ/Ь•;,›ЁQUYЕїw;Ъі—6\Й^Иɘщ4АЫ#ЃжzRјFAУ•‹{ї”впХ+ЉJ2ЦCšЎјSеітša[ёЪ:’.э™пl~‹[ѓ-Oݘz›•З  F (9б\ГjЭН?Н—cЅ2Е№ЊЖ@чXњђЬ˜#ЈkФˆTІ&V•ЮQ{ѕŠ\Jзнmi#ы’>/|1ЛWШаPыЄ‰“nќу†X=sЊš йЖowvVfxpۘ“Йџ“CRUвЦ…™сссzтуЉ8UEЅї……„<Јœ_VЊ v*ьйК}н@w‹•’SzZњБЯŽ1U&ŸЭаШžŸMвƒ >8Р4и#2pу@й~Ўљeв\і‰0uБOгЫ_ДЯТє)“Ю|ЅЬNlL\„5ьр!кхяы§ёиЄqЪХЎЪx€€@чќDоrГ…ў–._ЪЯХ‰,•Љ…uIAяиЙуъЕЋтmЋжё1TоБg“Ьm}ХчcЇLІUш#Ÿл—мЅRЭЌ‘+P’І‚XНСюШГXЎ}w!х‰ l yшc‘ U]”ўy‹TOм _|ёЩ|Pz wеъпяџ€Ъ_|ё5ЕSЁњl ­гв:Y2єъ?œ0MУЭашug$Iвƒ зъ/АВ]1"&,}ОPUЊY*,6˜Н­}ВјьІВДёж -YГЗx“—™ED="ћ–НSb2‰UeЉђъ'§њљДмj ‹ЗiѓІ#Ÿ—S ѓvсK Ь_Ggфхr•N󌔆jШВŒKђѕКi—”єьйQsO•]НЊГІ'nњ—пqњ‹W–.зS‹v№6Р?#WЖуޘ>󹇇щйŽЕ­]E™ж™џ§?уYœzЉL-l§™ю;SnЃћГZ-MmЄїќ|Р{лwR"Єыаы_ЫQYqX}jђ„UыVRZ"IКŽL8"агѓаа‡зцm:šF5zэК дТ4455Y­–PЋ•>СЌzuНT­AЃ”†J>Ї _Й>би˜“—“2:Х)Л={мZї}ћ-Ђц”ф1Єi^Iš“ЧˆНeB~&эљЂтЂЙЯЬТ§№`б рmA№ѕ3лrЦQ9џQЎ—ЗWe€пйѕлљsžSѕŒ›0хЭ›F<>"щ‘‡2ГВПЏ§Ы=їо›Лv5“6ЎXВhХЪuХ›ђ{ќ[пЙOЯкїa™JЇquкSгI`FЦlZ'[”6Œхѕzѕє$ЦХфхHJІ#†'чцц$Ц%2%Ћ—/йЛсљяєьKыЦћJэ—єLЈкЅ4T2ƒь?іW“›ўЇ)ѕёсЪR‡эaвnкŒєIгІгНкkвѓцЄЏy­ y|*щK™JU•]НЊIгтpkˆхо{њŽЃиТ@КŠРўѕ_џ•–ж‡Ю\гP_пpЅnЯ,?VJпЂ7}~MЗЋќ6i—МM{vžБ№ц7 'N№бЏ‰{юПНtщ]›ƒ§.њ†оу#‘Єм‰€x„}!љ\Э9‡Yiќ[5wєЛXYzэяпј9§Ž:хicИ$c,€^а /—џэџ§mD’rЗ  а…<‘гЈћяяЈwсaгЦhEЁoTп|чя0V‹^p@€'rˆ`H'№їuuїПІ&@:@pмЕоi8a@@:—yчђ†5№(nG/ѕЈB(ш<8#я<жА  '€DюqЄP  G‰МѓXУ€€xœЙЧ‘B!€€t$ђЮc K   рqHфG …   аyШ;5,€€€Ч ‘{)‚€€@ч@"я<жА  '€DюqЄP  G‰МѓXУ€€xœ@€ocZsЖцєз_SјР/АgЙ1"єrДЙПьaZ]u:cIжеЫW;ЧaN†84@МJ Р9eёЙѓ_0&И1яu$rcDц{ё&nРЊ“сфmЬЫ}%7vа@rЉ“M@@€€Ч ЧвzЋ%+;‹ў,­6€ЊЊ>д­яя08†žѕE<йCяЖRuдЎ§#ЩККк%Ы'%ŒOˆ™šіЬ‘Ѓхl8N–HRЕоhьœ“?oxо :нЃwlИ}цм_Y'wL˜шœ.b'Ч\е9С x–@€Ÿ‘+А(m/Щ*yЇ„ЃsUешЖл^^”НmЫЖiON2ѓvІї&^Оќ}§ь9ЯЮ=oс‹йсЗ‡здд”ќін„Ё‰Ь&F)М 0еk9ЏЏ^ыm'ЁпзмhКсk.СoŽ3ђ6r”Юі0OъmЭђџ'??ёуˆ‰џ?{чх‘%ўžшM–€9’d9f2:Ю8 &nPLP$D0ђ]„СF8 DlEEE#ЫŸ6Š|0Ž<4‚N"Ћ&$ A™dYЂСй‰Ш9rц›jŠђћъћК›—§И}њ4ЗnнКuыWEпЎябdooџEэч§F= ѕЎ\и{xЛЃ›uЎRЁШЯгєю˜нзnJыюОKœ@>.:|аУvвющ™iŠ­šl р•§нIH9šМeЫЂќќэььЃpv`‹([CUђЮеp~rFД$,ФuІЫќР…ххeДnР\cЎВ?јEzf€'dŒd˜аt ]/‰ˆlОжDКцzЃQii‡b˜Є!w,!7hТЕяэ7 f цKъи јфЦњc%Gч,„у:рп8Ќ=mЭѕzр6a‚,шB<ъE с`qUѕQ@zoнj}gMŠЋЇ;0Y‘œdрёCњчтe@†ЬA*Ж q+2 |EIР*9ьТУ#УЩќ}wх;"€є2“Z\RМ$d МОxIёсbj™_ iќюк‰т#ЇWўxћGЂч*‹ ж]iЫъ3•ЖJEЎ:—:ЉЋ­;ёс‘ЪђВŽл?Љѓ5 '{hxЅ{njЬj.жxНьЭ­К_isQWJNYП<іэ‹5Е…Лѓ.5\!ZЉ€ЙЦ\%эKН'ЗуіЭЧЫрyѓіM(вЊѓ_жk Ћ?=чљВчЦ-D/я ldŠa‚НдX Š€”=ЬЬЬЬзљкѓ$Zё+70ЋћІБј@a§…ZЖ‰мXxітЕ!уtФ6Ќ(6$юЈнмн.з]?эыЖo&@?ЏЛ zPЦ$%D‡\ЌЊЌўЈrЪЏŸоЎЮa‡&#ыэкŠ—;т\&к…И•L`X…Ь€U$r˜ЄєДєIПŸDg dааЂX€O§_~нрчхU^^^ ƒ†˜•”VlHVй9ийŒUЦ­ˆ—Q*-Q%'h-m”ёБ хgЯаŽT‰*и.У„Š“ToИаеоžхэaЗ”ѕплgЙЮ›йккЖЖA}чјёŽыръо‡TР\cЎ’vTQYNЧИЦXy–VЅЎд1Yд№M=бЫ{‡Д#ІдXР7){˜ъBG!Ј иЌŠO€YЫŒ…k/hEbc†э‚;jWз9ч/еAЋВЊRлбЖUUкMyнЅѓ сxQБ3\@7J ы?:*КцгЉЂо~ЁЁоe л…TЈG–GРђЯ‘wїtУД­K]GїтP42ЙќШб#mэmЮЎ§WŸ9^ m[Z[Ц?щ(X \eћ-О ћ-идэ­-§6KЖу`У$•ЫЩЁХqџ>ЦЭmVъjNњЩйБ=я§ѕ.Е§#ЖIЩ)ГgЮ€žЅцs•4ќ–ж6Љ1кŒе%6ј|s‡\~ЈPШ{З2ЙI\qВgg–vD‡IZ;Ём ’ зžіBдFJ`ЛрŽzЦДЉ[3ДUœ,ЋШJлМЛ`ПŸŸџW_}›К:”ѕMй9й M w~ю=ЯЌjЉ‰^oП`ІwШРv! ж"K"`№Ё9r6=/{q’ቆŸЫ{ЧN”Ÿ=YЛU2nиŽ‡Н gЃрB3њЦM ИJGЇЪ§…м7ъ0]7WЗЊ+ђЏТMћŸќлЩяіОYУYЩддѕЇNžЉ€ЙЦ\%эШЩqм§cGЋИ‚М7h"у№ўŽt0ЅЦТэ”RіьЬBGRЭЙ1HЫŒEЊ‰@?xФ!wд№ы7žјь“jЅвvњЬЛѓwvЁ4 ‡VЋVЏJJLrŸ>vфpднХsМG­ИШэЬє.ƒЁ @j€љАŽCы}лО№ЅсŸњ^uжЇЬK|сЙgh‡ZACŽ1.№н”• Лсю_юТUoЄ-W˜–Б‰Мћ7_ЛзЛбŽ2ssДЧЕ;;3Г3}}|‰~œУ˜цК‹ŒЈЅ”Гo_>\Зе§K'\еєз&ИгLЪXЌ‡`Д4Сuvї]}Єцs•Д#_o?у&ЃЗ­т ђо ‰ŒC.LЉБp{Ѕ”НЏї+ЌЉцЌ P)c™БH5Ќxрz–ѕ‹Г^кšНгЧпZљЬїйšБ4ФCWW—RЉАQ*сгmкЖэ\Зz•R§r—`ь hЅ7$4@цKР*vфtл­FkЯ—“ Ѓ‚`ўіћ 1vЙ@Й00dўnЏWНЂ"ЂсRЃ€`0ˆ‹‰"f\eXшRЈ ˜'MŠŒz›њœіќ”€зƒЛўЏЫџеЙк~я#*<:(l)БдЛŸs8$Зg/\ЛОуџeuuнyцwЮ‘‘дП^СcЮ‹ ЩЊзПƒРВЖn&іRsЙJкo\ltњŽ\яEў ёŸчEZХфНA‡\˜RcсіJ)ћИијєmiо~ўЖиF…GU~\ЭѕРk J™БH5Ќxрz–Ећ змь/эе”^sНГВ2нgшюlмœКvgжЮЗH‚cЫо --+хz–WJѕЫ]‚Б€ •|š™ЉJT…Н$m5d52яP%ш†lКЙЋ)аTќхlћ-Жџ>ю…^ їБ=4'MИƒbэЧ9Œyс…YЊФ„ёуЁ7*Њ” @oCЖG24žN?Z1nܘ''L|щХ—–†лйй›с~ЅQљї1.Я=ЃJ\=aТSd,‚ЎiДDдBQР™zf-Ё­XO=k-6HБ 1KZl<MУеяgOњ,>„aC„$‹УшŒB1„1 ,6БTVШ{гvсўB2…Ы!ЉГE™Љ=tфа†5ЊCL"—‰ЊИяISžvzЂpw$нЮЮЮЫu_МП{zюnj,~уm~Ž;ђЧUЋ?(и/дJ ЗЁдˆЈОЛћюѕЭЅЅЇCо.д Ÿ* q;HТ> §ѓбеЉ)ЪЧ@џЮДЙxFh•РГ.’ФAЬHяtнQŒЩюK!>€ЩАЎ‹н ПфљЭтђГ№Х…ЯэБ_dooџEэч§Ц= ѕЎ\яyоюЧещЙJ…"?O–ЎГнзnJƒЬDŒс­Мш№A­>=3MбЃUƒ’МXъ}­НPO’l[g{ИяЪн-гJrPL№§§їп3:Iби$‰*ll”“ŸžМ2!>pСтНšrњxхЗ$zЎВЈ№`н•FАЌ>SiЋTфЊsЉ“КкКЉ,/ыИ§“:_zВ§‚WЉ§mЫ .ЯOOлЖНОБIбЃћ”РжŠeЉAБ–a8.Я?У*Ѕdcђ#Ѓ_рП ІІFl“”rБЊВњЃЪ)П~zЛ:‡кœџВЎXSX§щ9Я—=7nЩ zр Д9?_{žsи‘|цwЮмZНJC8ыu"0тfтхJ)>мЕJњ‚Яo­ˆOY“Д8P{.‰Л€Х 59e§ђиЗ/ждТ‘ЁK Wˆ+С+7BCќЋїфvмОyтx^Tь WRТDDGEз|кŸьSWъА/ jјFЗЋЮћ†D•и!б`\цЬ:tИhлжmдЬРhС^ž3uH=Kq?t\ьr’тУ]Ррфи‰ВдŒѕ{wхЮžщNb“YР4xlmm[лру_'ZЇв^Œ"~p#4ФEe9m ГVQy–:_ŸџAЄhˆ+к мu20WФ'’!Xh$тц‚*qq0qŠНЁЦЌ Xў9ђюžn˜ЁuЉыш^Š ƒF&—9zЄ­НЭйЕџГ#ЧKуbЂЁmKkЫј'ЕWБЎ.@ѓ]иoЦРІ@homщЗ‘–Ÿ§‰!фАЈ˜hxBБЙљњ$­Kй•Н“ыFfP`O§УGƒЧр*ПmЛВхŽвѕIуЄEeq-­b…[m­уX ‘с8\омадpччо– ^›БКїwјuчžЎ);G”?Чm­v‡wыFыІŒW›ЎвsѓF mх9Kѕ(ж 4RРŒ‡]NR|Xl‡ьƒГ“;™*e0Е!gЧіМї дЛдіи&%ѓЏ6чFhˆџ–ж6n[ш>"г0 qEЉР]'sE|В!‚…F"n.ЈЇиjЬšѓцgжу r6=/{q’ቆŸЫ{`wR~іd}‡=VpиqQбp Ž“ЃМЫг7в3WщршTЙП§пІaR €еF€ыЋ“џя>wп‰ь и&кaK]{јГzНВžєЖ—0(-+ussWЎZН*)1Щ}њ Ў?pq“x_KvŽ{ŸšџцwыІm!aС>>> №ИZƒ9s[Ы(Ѕ8@юr’тУr`Л+аFD‡+~”^к)Г€й†ћпЭи 8+œšКўдЩгl-‘ЙтпЩqм§m9щ  C\‰Ѓтj†Ъ•!XИх˜б Xеdэбы?XћЁŠ“ѕ‰В™АŽCы}{В№ЅсŸњ^uГеЇL^UUе Я=CГ8д‚ аƒИРwSVfg{'ь\сP6iЫU†Іel"9ЃљкuИоv”™›Ѓ=йй ЗЗљњј=мїе|у:Е1DXПќГOЊСпjoЭнЃyцљщм†ђƒb›hOœ8q"Ћ”’ @Ъƒ”оХšЎ5с’вcoEЧˆЭККК”J…R ГрBБ@уы§ ‹]P+.Т'Аџ|с2щтZ)сœЅ<єz9€=;.КœЄјpз*8ёB./љSIбЁƒ$Љ,XЈААсhі2Д{Š.‰џ)n„RўYОо~№?вћПвЙ ўYМ§иZ*тJ6m+ q%hТ-rБ8œјЌѓСтЃ0ћ№VГ}GІИ‹ЁŠSь5fGР*vфtл­FkЯ—“yЂ‚`кіћ 1vЙ@Й00dўnЏWНрŠnИт& $ тbЂˆWКjУуcр иФI“"ЃоІ>Ї=?%рѕрЎџыђuЎvЃпћˆ  [ ŠЙGqйƒв`Nlbп\^№Їтѕ[ЗД§м;-З—мВгћOывю@Pџк[Ј_pйЖu#mNЋˆ† Я№Ј7*HЙеъG+ЦŒ3Бї>ђтGшЉPк„ЭЉkwfэ|ћ‡$јВ7CaУЪжŠхИијєmiо~ўЖиF…GU~\-Жh,ЬVяіѓѓН\ДL3ччecи/Ъy6€8т.')>мЕJЂбцђНy+b %‡…/•ZР‚…ъ1чХ„dеыпС"ЯкКЙ`ŒФPЪ?гNО#з{‘v ќчљC‘­ЅВ!ЎaгЖСW‚&м"‹1€Уkзlм”Ёйу№N+оXVzЊRаЫPХ)p‹Es$№ЋЋџКъэ“;+"НЃЕЕуvѓёe§gШИу$МцzsпXЙіV бFН'Cў^5ЙFWоlkс›Э…Cш]Y!\NV8щ8d &_Q WчшЭJ‹і5й?6сfmYћ?ўnс;rјuШгђS6ђX‹@HРd Xx"‡/QЧяQ7йХ‡!$€Рр XЧХnƒч4Є№ИњтДvgИœЌ}рј­ž&rЋ_ $€Ь™&rsž=Œ $€Ќž&rЋ_ $€Ь™&rsž=Œ $€Ќž&rЋ_ $€Ь™&rsž=Œ $€Ќž&rЋ_ $€Ь™РCЯ˜sќ;@H Ћ&№аъV @HРœ <Ф§ЕlsЦŽ@HРŠр9r+šl*@H X‡š›-oT8"$€@VBрЁUoЌВ’Ёт0‘@H X‡воOГМQсˆ@H X ‡&;OЖ’ЁZ№0]\Flt#йзˆ ЪD:*ЖCхЧDА`H ШxhжјYђX‹€€€‰dJ C‹H Œ0‡Юн:7Т]šEw№Љ}Юtё№t_ЉЮгtvvšEфzƒ4інпX{Aƒl.№f"ХњкZљHFfд4Œ‘щN~ШX‹Рƒ"0њAulњ§’wЩююЛзo4—–žy#ИPs`ќxGг#DH ы!€ї‘ы™kхфЇ'ЏLˆ\АxЏ&XУшXЩбљ aЫЎеє(в3Г`яO HЭŠє№™ч:єiTЏЋю§ЎИ6ЗnЕОГ&ХегкЎHNъ?аЃPяЪѕ№žчсэ~ь№QжШMm‚Ј 6ЂЯЯг€%xXЛ) >‘€’lнр• љЂіѓ%a!Ў3]ц.,//# щЋиЊР ŒЁ ЋhОжDŒЙs›Sчм&P ­юУЋPˆBШєUмбq•R“z1pJ;юЈљCаЎœ4˜ X$EЂй„ј.lnОNЦXѕQ@ziGDІQA‘;GЄ9О"$`a0‘:Ё ќдддPыКo‹ж_аbUяЩэИ}ѓФё2xоМ}ЧfЕu'>eMвтР аЌЛв–еg*m•Š\Е6*r˜^щQйф”ѕЫcпОXS[И;яRУж!з”чПЌ+жVzЮѓeЯ[2HnРтюXџм&Ф€ХЫыd)Wмбq•R“(\Њ_ёЈЅ†K,X$чkЯ E7wЗЫu—Aшlя\З}3љ4іyнeаScqwPХ#к$€,‰&rCgsќ8Чіі6jН*>СЮЮŽ+*ЫU‰*(ТcCЂЊЂђ,5Ѓz*NVP=+pmŽ;O›ЊЅДЋŒŽŠЎљTїЂЄДbCВ ОXєq+тЉŸc'ЪR3жян•;{І;Q*-Q%'h-m”ёБ хgЯPcVАЕЕmmƒ 'œ5XЇJfЋЄфд•:ЗKC‚ОЉ'fRK9НLЏ!‘rХW)5‰RРЕд`Iа釕#fхъ:чќЅ:а—U•кŽЖ­ЊвnЪы.Ни˜еpчˆ5@ ‹!€чШ Ъ[m­уЈ5ћѕ-­mуŸд;ЁНЕ…šIщЉ\›њЦІьœь†І†;?пбїMTKk Еg:АўOўmџЭ„э?Дј.ьЗщѓаЏщ•rvlЯ{П@НKmџˆmRrЪь™3тЂЭXн'јˆpчžЎ^*`qsЊ‘iТт5d RЎИЃу*Ѕ&Q 8…TПtŒDыœ;­3ІMнšБ[ §д IDATœœ,ЋШJлМЛ`ПŸŸџW_}›К:Uа… Ш# ‘А яю–188gмиtљлЏхG3ѕЯMžвŸџЄŒKЫJнмњgВfNŽуnнh%oФ 88ічћћѕNl+*smV­^•”˜ф>}ьМс€Њ‹›ю.A'G'jO=€P )ŒˆW>ќhиkкуъ№pptЊм_ШfDЂМBюЗ7UР™уддѕЇNžX” XІЙM ˆ”+юшИJЉI”NЦ%еЏ`дRC`УД ZA>*§fТŸ}R­TкNŸ9cwўюЯ.TƒєbуЁв сQ!С9~zЦ‡6ф*iэР„с№9АHАžШ!‹ЏH|GžдЎьwe9ЙjНђфi8є W­s]љzћefgІЎлЕ›В3ЁHЭ2ssRWk™‚Џ/еГзІЋЋKЉTи(•p9UЮnнEvа*pяІЌЬ­ы7(ml4ztЖ6—/QмЛК,Cƒг26С‘[ј„б|эzоТ-ДлИqcšo\Ÿ№фS$И.&2|Т<ЅИЇшъл^“*ђ*АgЋXY*`™цRMXЗ K „5“rХW)5‰RРIяR§ F-5_яWийgGDхgНД5{чВ7CAу3пgkЦЮа%Ь–^;AwДэР„Сџз Ќ_l…РРр9rIn№Б.JwŸяНqS†bДВјРЉ{ЯтbЃэ{Т{‘?<Ÿxь (RЇгžŸ№zАЗŸП§ЃЦEѕыЉ\›ЭЉkwfэtvs Žj=eвг!Сѓ<ўјуT‚6—яЭ+9U—VAвљДчЇ…ЧЧРххЋзЋ<цxуЈ№ш АЅ0:Rє˜ѓbBВЪеЭ%[Н3kыfЂd_іl+K|w†4am@–k&е;wt\Ѕд$Ъ‡Єњ@“B\lМ§УJXАHІЙМШŽˆЪю3\сd—‡7hМцzƒь>CwЕtGѕ(tЕ#$`‘~uѕ_WН}rgEЄwДЖvмn>ОLЯAfИ/оMрЊ.ГРбЎˆзЗ#Я}—\ц=ф#2фž!6C:D2д їЋ” ž[%p"(r›  <(ѕѕ—Џ6]е›•эkВlТЭкВіќwфjВА_$`iИwеУ !qђяkзw§}€$О­Aбs7} Нџ єu_+цn{ЖŠФ7hу?бћн Г]рKр}ющ_є§*нў‚~БˆFŒ&ђC! ' u7? ›{_ЛолшY^R7њЋїh:ўy—м‹_wЉ‘mBdУяГ—Кн_эљBM^ѕ™s>ѓ}Ѓт>Љљ8ow|•‚—чЦЬтNQƒF’&ђaЄ-ОWм™!6тVЈA&H@ъn~•{_Лолшй1Jнш_л JLа~‡ƒ*>m"#sу‘КнќЌZЉяр7 -‚;BйbУЅz™ŽА Œ ПjvїtGь X§зШмUЯНЏ]яmє,RЙ§ћ~{/>ы„ЪмxЄnї‡V№)Д%7ўБEњU д9 H`„ X~"a аœQУ}іШcЧ8яЊЇqъНžZ‚ }Ѓџ887Oю(со‹Я:‘—Ѕnї—o…ЕHрРCы| Ќ+і‚#ыЙŒ–НЋ>mлvН#&ЗбkПИГОhAоžмшOŒйokшеч=м”ЯuBюГчVБJrЛ?љ4_Нп7РжЂŒL–&r“ LЙёX……Ь+oRwеѓlЕ:CnЃЇmЅnє‡_"шПџй)cx МЯ^ъv HР4 №VНiF:рЈxпV6`gи X§зЬžхOЪgq€юл‚Ÿоњ‹ЃыжІТ“4Ёп.L=€Р+сG}ФПы'­ЉјзC*a›ы<‡.…$Mѕ§>{UlЬXKв„5|‘і‚1žШс{дѓїЊхi‚иі‘7ькПЎ™ј{чmжLxКїЋrрfжYgN—A“Йѓќз­LVŒЗжiрзСVЎZіF(мкo”CјЕщœьœ ДпЂ wЌzНъМI%$&/љГЄ+6јэ=ЙЧN”+]qЫт“/`—^ЪЁ”њ_з.*9‡RчЮ›Кz•юЋПE‚0&Џфэdнћ ‘САƒCyX јПfXЃ’q?}ї^wNnŽЏч+2–X…,’€…'rјu™яQ—ŸQrчЋrЌЭСтЃ№Ћлячя{z3+Ш)щ› HПэ\р ~<9u§цДЕєwE wH~…9љjї—gCІd…šыŠ €ўŠ6љJvR%М”CЎžоn pВў{;ќвљЪwДП*юrvцfу“%ЩэєўжXFƒљЏЦАЄ]УwУ7wныš;g.i—6Ф$`™№ЙфМrя4•К™UрEќыр``ИCНПBЭuХЦР§m™рЅrѕRЗлr;eЃbхУ6G PpФы“ЪгџR ? Є;8DыP@V@Йф$sя4•К™UрEќыр``ИCјъЏОњ š_ЁўSљIсWЈAO:тК"Uф•НC—ъe‚—rШе“лmaЋ ЯYЏМвжо&г)э] ,"$€РDnм2 7Г’6p› ћгуЌ#јEQјжЊЂУGY%Wц:„]ћ+д№ЫЄЦў 5ЙCWа#З/!EИні\хY8lЎ{^Ј%­ИJ9Њ`ЄќЃ $`%0‘7бR7Г М_/љSIб!э/ŠЪ<Є’_ЁіёїЖфWЈA#уGPE~ENБwџr."ЕR} къ-JнnЫэTъоЁ FoДh€Аl˜Ш›_Љ›YХ^П.6 )‡†ќ Е”OаsE[Њ/?м*ЉлmЙJнТ;TСp#D%@HРzXјя‘[ЯDтH‘@HРря‘[Р$т@H A­ M‘@H ˜LфІ6#@H #`"7š"$€05˜ШMmF0$€@FРDn,4EH $`j0‘›кŒ`№Љxnђ”Щђ6ЈuvqЉЏ­@CЃšдз]Ž_›мvЋmњ‚Рш Ј`TДhŒ@CNРТ9dё‰яШSл•§ю`љ€Sк€ВУЩо•Е%kњДЉ ‡Ќs”‘@HРє Xx"№@RЄmЧ9Œyс…YЊФ„ёуЉ’ о И!э„†Ћп“,ђ8dЃŒ@ІOР љНЮЭ‹GљуЊеь ЏakvЇыЮАљFЧH $`№b7§“dgg§§їпSиЌ+9:?`ЁѓLэЎНяоЃHЯLsэюс3Џш№б~П=wгЗP§AjЯ ххeѓКЮtYй|­IзVЂ!ѕL<Р+}’*(В‚2?Oус=b[Л)­Лћ.h.lnОNьЋ>Њ"h@ђ­[­яЌIqѕt‡&+’“рЃ 1РW$€05˜ШѕЯЄБќЫѓЯPгКo‹ж_ИяZ6uОІуіO•хe'>R}ІвVЉШUч‚Ѕ›ЛлхКЫ tЖwЎлО™dїЯы.ƒ”1I С!Ћ*Ћ?ЊœђыЇЗЋsXч(#$€€щРD.9t›;ы•WŠS%ЏІІЋт`›N‹DЈ8YЁJTUДЖЂђ,œ_яUлЉтЈžRW&и9ийи(—†5|SЏsh@Cж +Г*-Q%ыќЧЧ&”Ÿ=–ЎЎsЮ_ЊЁЌЊдvДmU•vS^wщ<шA8^Tь аRкŒUFGEз|ZJ| $€€ Аќsфн=нуNЯ‘wџrїрБЃ™йлveя&Ў щŠ}ЖДЖŒRw5РLЋяЛJŽеГlЦъB.ПгwRп†ЌVf#lџЁХwA`mяœЯ˜6ukЦVPž,ЋШJлМЛ`ПŸŸџW_}›К:”ѕMй9й M w~ю=oљЫЄJH ѓ"€;r§ѓЛвЈАЅЕЕ ђІNŽNЗnД*@бЩqœrыхН ІЁРГƒЃгЙЪГє<9#Ÿ~3с‰Я>ЉV*mЇЯœЁИwїГ е =4_Еzеы!ЏW—UBЋкšsŠОЯЯXDH NЙў)€yQёС‰'Ъ›њzП’™›'дс‘™I}Н§2Гszе`@ѕz…7x LЫиD>[4_ЛзЛƒgНД5{ЇП}цћlЭи RеееЅT*l”Jј’ЖmЛР!‘@HРt`"—œ zŽмнпN'oлКQвДЗ".6оўaЅЗŸРыСг\^ЄЦpŽЙ_џь”1ІpCк5ТB—N{~Zx| \ПzНЪcŽбЛЯpmomёђ№†Ђз\oнgИ“ЊЭЉkwfэtvs Ž™іќЂФW$€0AПКњЏЋо>ЙГ"в;Z[;n7_ІчЫJсО&xг‡KЗLp0т кЈЗтФzV“ПWН80ˆе Ÿ їwХ$&œ*љГБ] ИЁБЁ=@H <@ѕѕ—Џ6]е›•эkВlТЭкВіќнрэсж К†яQ‡<-яlф _Ћо•}ї^wNnŽЏч+†;pCУЛ@K$€0kžШсKдѓ=ъC5Е?ўјМE]їКцЮ™ Ь w;р††w–H $`ж,<‘›ШмРAНЧIИЁИ!з*‘@HРђрХn–7Ї8"$€А"˜Ш­hВqЈH $`y0‘[оœтˆ@HРŠ`"ЗЂЩЦЁ"$€€хРDnysŠ#BH +"€‰мŠ&‡Š@–GЙхЭ)Ž $€Ќˆ&r+šl*@H XLф–7Ї8"$€А"˜Ш­hВqЈH $`y0‘[оœтˆ@HРŠ`"ЗЂЩЦЁ"$€€хРDnysŠ#BH +"€‰мŠ&‡Š@–GРТЦДЉБщђЗ_ЫOлд?ЫУгžщ™Y<.lnОN Њ>Њ"h@2 м=wгЗаОR{т‡МRЅЄЦlŠ„Ш!~ R[Џ”0xІ]ЈbцoЦ.ЏњD74hмцћЬыўE;•є§+9:?`ЁѓLэ31‰’;уR3H;B $0`V‘ШaN}wх;"€F{ЄнрЧџ555ФМЈ№`н•ЦХGЊЯTк*Йъ\а“<МвУЙ\3АЬ/а4~w šŸ>^љуэЙmIGф59e§ђиЗ/ждюЮЛдp…VџВЎXSX§щ9Я—=7nЩ њ˜Є„ˆр‹U•еUNљѕгле9DЏЮзtмўЉВМьФ‡GЮзžЇNд{r;nпoQYЏ 5уR3Јз! $€єш{›зkhЮГщyqи‹“ŒN4†чђвВR77нeGЇЪ§…zптЅЬœ` H3“^Д“;љноД ЇZSSзŸ:yZІЩЊеЋ’“мЇЯ€9wq›EŒйNЁwъСЩq Gэ‡HiП™№ФgŸT+•ЖгgЮиПћГ е сІ:ъŠ ZŸЗZI.gћЂюв‰xрЯuЮŸЬžщОћпоSчiОКќе–uТЯ(дŒ cF+)аё­V(ЄfмЈdќЁˆаOР:­їэVУ—†|ъcxещгЫp‚7юІkMpmZIщБЗЂcˆehp`ZЦ&’ЂšЏ]‡ынˆ~œУ˜цКkФ@#eИРwSV&œ~†KЋР3З-Q’W№ЏНє .CЛЇшвsWW—RЉАQ*!•ІmлN§јzП’™›Ѓ=@пй™™Щш§ Hє›В3}Н§Hе‹Г^кšНгЧпŠ>ѓ}Жfь m%/€“Ььт:•76А– озЧ—ДъэˆМи'—9˜EFНЇЩ[ЙL1JмHЈ™јЌѓСтЃА$`юЖяшgHэЄfмЈЄоP@H BР*vфtл­FkЯ—4Tр’в^“oQ@зНЎЙsцТ‘іƒ|ЇАЫwzЪ)‡ЙŒ@оk‘@ІIРТЙiBЗ†ЈрИоCC†sŽуъУсг№Ё%@H`ЈXЧUыCE § $€01˜ШMlB0$€@ЦРDn -ДEH $`b0‘›и„`8H $€Œ!€‰мZh‹@HРФ`"7Б Сp@H CЙ1Да $€€‰РDnb‚с $€0†&rchЁ-@H #€‰мФ&УAH $` LфЦаB[$€@&FЙ‰M†ƒ@HР˜ШЁ…ЖH $€LŒ&r›  $€€1,ќgL››.ћЕ<ЉxГ\‘ХзТo“уЏšZќ,у‘€ЅА№DY|Eт;ђ“З+ћ]LфђˆLЊ“ЎIMƒР'€‡жљSй‚_aўZsnЭ тJО#зЂК7”Ма@H “"€;r}гбs7}KšыlwŸyE‡вэ,ххeѓКЮtYй|­IчЈG‘ž™хсщO=:5и+9:?`ЁѓLн^??Oус=<Џн”жн}—зFлѕ‰оЎgЛ, ЉЏП\ѕQеЂзh$з‰+0ƒ€!lш"=3DJЈ…W"МЛМъ“*кѕ­[­ѓ}цuџr0вю‘єРЉв5)rУƒЊ/j?‡AU` „йЖД!јSРД^и ЩЈiН Hє\цzЃЂ>Q@H Œ0Lфz€Ћїh:ўyЗВМьФ‡Gъ.5ВжчПЌ+жVzЮѓeЯ[2H•zOnЧэ›'Ž—Сѓцэ›PЄMъОi,>PXЁ4E…ыЎ4ž(>R}ІвVЉШUї›Q{›ѓЕч 5yеgЮљЬїJˆћЄцуМнy‰—чЦЬдC]m„ СwмўIЏ=9. ЏDXљ^ў>jПwџа№0›БJЊA†;"™ГоXYд&ЇЌ_ћіХšкТнy—ЎАіb™;36HA•И(ХмЈЈФnQƒ>˜ШѕА­Ј<ЋJLАы}ЈтXыд• vv66ЪЅ!A пд“ЊŠЪrUЂŠиoHTAsкdUМж)*-Q%ыšЧЧ&”Ÿ=CЭЈ cГjЅjМƒ#tД8шЮЯwиbУ%]$р‡FBХЩ ъ™ г]fи+mЋЮh7хЗnДжќOMаТ ZKьˆd.pH‹м№lmm[л:с1~Му:U25ц м)XВA ЊФE)цFE%v‹$€Р№Аќsфн=нƒСзвк…xџЄN E›БКЌ ѕNп™ј–ж6jB{k эВ>•лhё]H‹ о<Шиаа58a‹4аKEвпЏBЙ3ћ=ЏЙ^9šМeo†‡Ќ vD2gНБ27Мœлѓо/PяRл?b›”œ2{ц Ж‰@цNР† RP%.J17**Б[д $€†/ _ofшйЩqœ9&ЙіЌzG ЕПбJRŽуИM*їЪчClИЮЉђўHœЈžfЯtп§oяЉѓ4_]ўjЫКTЖŠШј˜б И€|>€}6ыŸофпN~7c+˜СiщддѕЇNžf› R– †x–b>ЌQ rPи +'€‡жѕ,_oПЬьэЁоЮЮЬм=ж EЏ}&Бп” En“арРДŒMЩ ЖљкuИоMlfˆИЋ€I$™‰/Љч0Іљ†ю‚8Ђ‰Œz;O“З"r™bлZ'H@jрŸu>X|ryg{чі™lм№EsѓuэЅyї]}Ч9иVƒ‘e‚!nЅ˜kTƒЖEH `"зГЂЃЂэVzћљМ<эй)АЅ“ФХFл?і„ї"x>ёиPфк‡….іќД№јИ<{ѕz•ЧБ™!6тVЌfкѓS lоўбGуЂt‘D…G…-e/иVŽVLšшфччЯЖЅВЄОqэšП|ќї9ГBЂУ_ty‘КžЧœ’UЎn.йъY[7Гіƒ—e‚!ЮЅ˜kTƒz@HРš ќъъПЎzћфЮŠHяhmэИн||йdyp3з\ozRVојзBДQoХЩ‡‘ПWН8Px…З ьcN•ќ™[kjJHе~wЪ;kR^їВ—‡—о! !УУг $€,†мQ|ŽM^ IDATЕщЊоЌДh_“§cnж–Еџуяњ6˜fЮОGђДќ РFо@Н+7:"њюНюœм_ЯWфЭЎnХўлџўЭЫC{ZZъaйЄFz$€€YА№D_Ђ>јяQќёЧч- шКз5wЮ\8Юlѓj`А-vzЪ)gлvy{ & ?pЌEH ˜> OфC2pˆCяQŽ!щhhr\нˆj8иѕа2AoH Ы#€ЛYоœтˆ@HРŠ`"ЗЂЩЦЁ"$€€хРDnysŠ#BH +"€‰мŠ&‡Š@–GЙхЭ)Ž $€Ќˆ&r+šl*@H XLф–7Ї8"$€А"˜Ш­hВqЈH $`y0‘[оœтˆ@HРŠ`"ЗЂЩЦЁ"$€€хРDnysŠ#BH +"€‰мŠ&‡Š@–GЙхЭ)Ž $€Ќˆ&r+šl*@H X џгІЦІЫп~-?mSџ№мрГ\Њ јСoюяuJщЅќ˜ВООўђЊuЉ-?ДpGjj‘KE;Д3BНQСд8 U<?РЁ…~Р№А№DY|Eт;ђјveП;|‰\ОkЫЈЭЮЩNY“2{ц ГŽyE+FЊ7qъ5ћД ТБžЙЖЊ‘Zx"№\Т?М ­Yl71aQцАсъїГЇ<‹ƒgї—нweэdЃtWtјhfvІ*QіZ˜‰g”Nа Ѓeƒ| Воaъ5 [Р\ЪЬМє‚A ŽyЃЕ6VШя pNёо@pwКю(FhЫ7{єсG([рЯЏV(9ДaъаC$‘гЉМMK5gѕƒ–ѕ†2@HрР‹нŒ›ШххeѓКЮtYй|­‰ДПuЋѕ5)ЎžюЎГнW$'uvvRПE‡zјЬ}zfšЂ‡Њћ…ќ<‡Зж`эІДююЛ§}вЕŸ/ Ё_шЈ!’Оzэ_ZлЃ”BJЯЬђ№t‡'4BА?Vrt~РBч™.Ф9МAмo•оицDN]Йъа‡š›Џ‹Ћ@ѓХ…ЯэБ_doo(И6%/™є{р5джі(дЛraІ<Мн>JьeцНпЁBёfьђЊOЊЈZЭї™з§Ы§s-б/ФL'<єOAЯнє-iАl`uСŒS=+ОVI+xЅЭЁ/ўЪдЦIћеq Cг 6Ёќьmmm[л`“п9~Му:UВи@ ‘ъ‘ЋЏЈ,Їњ aхYъmU|N‹†іць<ѕЅщ/С{Б иМ~љuƒŸ—шНММ@Р†[”‰„kO•R KJ+6$ЋДS?VЗ"žиЫЬ;uТt—іJлЊ3кMљ­­5џSДP{ВŸ}Hѕ 6쉈™R%j'Њјж•]ЋД!R+ж0Л`и&TцВ’ 7N№ЦеKЦэ”†$Œ ЦиџAAwXDУJРђЯ‘wїtŒ љ8/nk3V—л —пщ;_пи—C745мљљŽЖ Уuќ“ŽФ э­-‡э?Дј.ьW2 Љ2gЧіМї дЛдіи&%ыП>\ЊGЎОЅЕЋ‡о!iб у-.*zILЄы WHъДЛ#GДЕЗ9ЛіŸG8rМ4.&šH 2‘H5!zЉ†-­-ѕ 3я䆑Q‘;Гпѓšы•ЃЩ[іf(,TП`Цm<ућ—–Р)ЛVY'R+“х B<А6дЇЬЙqBCЎоРhЇR‚БСћ?(е/ъ‘РpрхсшЧв}ЎZН*)1Щ}њ иЎСynЗYtФА#яw 88:Q=@SЙПћNM-'џvђЛ[Ё'ъRSзŸ:yф1ЃаЩь)yЈ’ъ‘ЋwrwП~эwТ МRlKн˜Ђ*оW ыКGqьDљй“4cСv<8ь Hљz/Џp$R ((JFfоЉ fЯtп§oяЉѓ4_]ўjЫКTA-Ѕњ[жўV+!I™‰ѕЦ,Е2YR§В64cH C4 †ћ?(v‹$№@рЁѕЁСоееЅT*l”JxoMлЖuš™›Ѓ=,ой 7PљњјВU ‡Іel"oˆЭзЎУѕn(‚R{!\(wOбеw `тГЮ‹B.яlямО#“m%е#Wяыэ‘7A„о~Ќ+*sг|ƒ1ЕС@olVž0сЉаEY;tЋЊЊ^xюšХСdа€žmХ•‰TУРО›В26\ЄU‘Neц]UdдлyšМ‘ЫИŸBЄњћ!š^ћ2q0ГRfbНTЬ‚)–Z™ОоЏА Iь4\VЦы”Rq; Šњ46юџ ѕ†xА0‘KђgOї_ь*aО9uэЮЌЮn.сб1гžŸТZA1рѕ`o?ћGеn%я„….іќД№јИ(}ѕz•ЧћыЕ%9/&$Ћ\н\Ве;ГЖn&зЎљЫЧqŸ3+$:ќE—йVR=rѕqБбі=сНШžO<іYWTŽ  [Њ—ƒоЈ[БА80шцO?§ўc„М"АYђсБJqqР‘H5ŒŠˆž2щщ€рy‹ќqвЃЬМ‹CRŽVLšшфчЧПЫNЊ_БЂK1ьVТК‚е5эй)p„ЦР‡TЬ‚)–Z™qБё§§оП№h\VЦzRq; ŠК26юџ ѕ†xА~uѕ_WН}rgEЄwДЖvмn>ОlВ|@p'Œз\oИОFоЬDj!кЈЗтфƒЩпЋ†ф!ocFЕkЙgїЅєf44snP|uоЫ^к ї†іlbN•ќyhнЂ7$€Fž|єеІЋzГвЂ}MіMИY[жўПќ1~фG3=ТїЈCž–ї6ђX‹OюNўлџўЭЫC{­УP=рtDєн{н9Й9ОžЏ •[єƒ€yА№D_ЂŽпЃn^+в"Ѓ…У!NO9хмёФрG Gјс8зНЎЙsцТ‘іС;DH ˜# Oфц8%ƒŒ™{\|Jщй67„Р0С‡ƒozПк $`ж№b7Гž>  $€Ќ&rk_8~$€0k˜ШЭzњ0x$€Аv˜Ш­}рј‘@HРЌ `"7ыщУр‘@HРк `"Зі€уGH Г&€‰мЌЇƒGH k'€‰мкWŽ $€Ьš&rГž>  $€Ќ&rk_8~$€0k˜ШЭzњ0x$€Аv˜Ш­}рј‘@HРЌ `"7ыщУр‘@HРк `"Зі€уGH Г&`с?cкдиtљлЏхghъž3ъ7ЫсЗЅ‡щW)хуФZ$€@bžШ!‹ЏH|Gю…^ ™>m*иЫTБоp€A>*Јe§ЂхvФUŠ›Ѓ $€ЄXA"П'5v9§­­1Бo­ˆ‰[ЕReїА]SSSс#ŸШ!D[Ѕэg>Ÿ=s їГsе ЁЁ'mLyкщ‰ТнyуЧ;vvv^ЎћКр§нгswƒLm>`A&*zо“є€ёbC$€€с№b7>ЋMоВeQ~ўvvvŠQ 8іОeѓVщ­[­яЌIqѕtwэО"9 ђ(1€V~Ђl~рBзй.KТBъы/W}TЕшЕ…Ў3]–DD6_ЛNЭŠє№™Эг3г=їКтђАШ§ћiнўЂ§pl€k/TЧЧЦC „:лУ}Wo‡ЂLmЁ‚ ЏDаъ{щ™Yžю№a`QQџ( $€РpРDЮ'\sБЦыeo~]Ÿ6&)!"8фbUeѕG•S~§єvuN_т|эљBM^ѕ™s>ѓ}Ѓт>Љљ8ow^ѕЇч|М<7fnЄfuЕu'>оЎі6;;~]ŸN];УйшQJ›БЪшЈшšOkњjp@~МƒЃ2hqаŸяАХ†KѕдL•Ј‚m4<@Ј8YAѕaйвe @Йч@ШlэЮmйO?ўDЦ–TWяљ еЛrсд81Љb=фŠЪrеˆЊђЌР€eЂЂ6( $€РpАќDонг-џф"ЖuзйЎ;TЮ5%ьƒпŒ]‡жсИД‹лЌЖŸлЈ%фf"C.-оaЮйR{H ДЗЖYќъ7пџлЏПЌњЄъo Г№"*&њƒЂт‹ŸUчхцќєЯЛIыRˆLыA ЗДЖ >*O]‘{=WЩoZ$€рАќDЮД*7WЗЊ+х W­^ѕzШыеe•p\КЖцœ‚Щађ i-\RGdЈ^(ŒR„††­[Н&4< NиK=&Lx*љёЕЕеb™*Б“уИћЃ'0ш/Еwњ'z}Q6]k%5@ $€@9ZBtЬО}љххeнПtТ_MmZЛ^ЗгЅ ККК”J…R WНС‰jЊ7\ШЬЭKфр‘™щыу+г0,tщХ ЕaЏ-иЌˆ_ўй'ерєЗк[sїhžy~:Б‘ЉbŒsг|Cw§ш}Н§ ˜о :7ATо~ЌБ@–ŠJ`FŠЁџИzЫFјŠэt=ку7e„‡rQ‰@Р#›|Ppx9oЯ^Иv}ЧџЫъъКѓЬяœ#™kХI›ЭЉkwfэ|ћ‡$'GЇeo†––•ђ}IkЇ=?%рѕрЎџыђun\TДДЁdMь›Ы ўTМ~ы8АaИНф–ОXЫTБюЂТЃƒТ–Т‰|rН[\ltњŽ\яEкјўѓќЁШF†ЌЏ|XЙqKъїзo€Ÿ‰O=љ_AЁ‹ю;S0џи $`~uѕ_WН}rgEЄwДЖvмn>ОlВ<ˆc%GНцzг“ОђЦМЂz+N>ŒќНъХAђ6УQ gжщЕтУс}"$€€й€Л“Ў6]е›•эkВlТЭкВіќнТwф№=ъЇх'lф А $€€ЩА№D_ф‚пЃnВ‹CH СР‹нЯp€№ИњСa3$€``"g` ˆ@HРм`"7ЗУx‘@H 00‘30PDH $`n0‘›лŒaМH $€˜Ш("$€07˜ШЭmЦ0^$€@ Lф ‘@H ˜Lфц6c/@H †&rŠH $€Ь&rs›1Œ $€CрЁЃG™"ŠH $€€9xhэšЕц/ЦŠ@H 0Rtw3E‘@H s"№Іqsš.Œ $€Р§F+юнЏАЌRScгхoП–гд?<7„ПYюьтbюПOjьŒЕ—ŸR[_yеКд–ZЬІ!ƒE$€Р`ŒV(юІН‰З…,О"ёљ weП;„‰\О/Ќ•'@?dчdЇЌI™=s†М§рkiƒw5’†*ьЁђ3’cЧО}зЂwф‚б^„7ИIПŸtМЈ˜mВ(,фЛ+п ЧКc;"ђpt$юХpMsѓѕѓŠ„Ф/шŠRmСИММl~рBз™.K""›Џ5щкі(в3ЉOўї фhђ–-‹ђ №ЗГГƒ '#Жlо*шZЊп/j?_BзiХU’саWоŒ]^ѕIэʘя3Џћ—ћJѕ k[Н+А{xЛ;Ќы™ј$­Ќ…хсщOшџpЁqу'>сUм(Йk,a‘РRqžЉJmw'zчhЖ @ƒkЊ>ЊZєВыЄ т_gЯ›S.qTz§( Xo$$|EHрA€ovЛя=ёAХa‚§ЮіpяшИYпЈЭv№~кббСn@c’"‚C.VUVT9хзOoWчАCјтТчo­ˆOY“Д80єE…ыЎ4ž(>R}ІвVЉШUчВЦ\YЪПzІуŸw+ЫЫN|xЄюRЃQmСјќ—uХšТъOЯyОьЙqKiЎЮзtмў‰ј<_{žыГцbзЫом*Њ”Š99e§ђиЗ/ждюЮЛдp…иs•ЄŠŸ€Wx.Š|/эbяўЁсa6c•T‚TПљšЦяЎігЧ+М§#XВžY ЋїфvмОyтxѓ}Ѓт>Љљ8owL™—чЦЬ4**pУу2‘>xуњ1dНбHP@HрxЯ‘Ыp_ЖtYС0иs dжNŸ;O›ЊЅ„Є]ѓi ­=vЂ,5c§о]ЙГgъN!*-Q%'и9ийи(уcЪЯžЁЦR‚”џŠЪГЊФиУCŸРm.еŒSWъТXд№M=i^qВB•Ј">7$ЊИ>Лкл ~nUJѕkkkлкЧ,:Чw\ЇJ&і\%uE…щ.3ь•ЖUgД›r8М_ѓ?5A ЕŸи‡TП%Ѕ’UZьc•q+тй&bЙЂВœ…œЉ šёS'2k`U|РЇ–pђbМƒ#,• ХAw~ОУ.щІŒƒР OŠ лP s§Во~АˆРА№лЯ€fwЯРo•ї›яПы=5к§[CƒпЖьмРNЎЌnhj€ЗZ­žЙира} OўэdjпўC‹я‚@Zdћ•їKRў[Z[ лёOъ„ћ›*Єк‚™ЭX]Т€WTјДuзйо)ŸЫЅњЭйБ=я§ѕ.Е§#ЖIЩКkбЙJAЇЄЙ3ћ=ЏЙ^кУћo†Bф3Љ~йq šˆ‹-­mtь ДЗЖP.4Уу'~dж€€*MъdЄl‘N nxRL膙ыЧѕ&№ƒE$€F˜“FИgГшn”"44lнъ5ё‰ ‚kЏV­^•”˜ф>}ьірœЗ‹л,: MaDtИђсGУ^гэ*ї оЏЉ=Wђяф8N’\;TЃкrAщфшЎH“ђщцъVѕq%9S хG*fјLѓn†і„:œWNM]ъфiЙJЎg8АБћпоSчiОКќе–uЉbЉ~йq‰[ 4ZА ЧqAб№јIУЌAFЅ˜хŒ YoЦњD{$€†–РCŠ{пАm(Іщ-,tщХ ЕaЏ-„зееЅT*l”JHЋiлЖГЕА!——ќЉЄшаAЂ LЫиDrdѓЕыpНkЯ•ЅќћzћefчhSwvfцоwbžњ‘jK ‚Џї+рЊзegfvІ –ЂcіэЫ‡ЫОКщ„ СрRОЕыS–R§Тxсж5эхcї]}‡ИJCZŒŒzю|[ЙL№qŠHѕИРwSV&H€‹урЊ7b<ЮaLѓ н%cд?Н`3 „Mй™PdkХВој ` ˆ;5\#ХD•^‡†Ќ7НNа a%€_б:@М›SзюЬкщьц3эљ)/к\О7ЏфT\тU№i`кѓгТуcрЪэеыUs<ітЂ”8oџАвлЯ?рѕрiЯNУ;Є"еVм бФХЦїћty‘kћѕМ={?Оx~о"W—m™ЏЮ{U`)еЏЧœ’UЎn.йъY[7“V\ЅР!-*G+&MtђѓѓЇVъ7*"zЪЄЇB‚ч- xќёЧI“Ј№ш АЅєjmъ'.6кўБ'МљУѓ‰Чž€"­т zуt4€5Рэз@Ѕ$‰сKЙ5dНIЕE=@#CрWщ[г5Ÿ§8+"НЃЕЕуvѓёe§gvЙР­2^sНщy;Ўщ(!кЈЗтфуЩпЋ–?b,пќжТ67&1сTЩŸ` #г5мщїъМ—Н<МFІ;ь…KРzжwјЈD#Cn’КкtUoVZДЏЩўБ 7kЫкџёїбA~ 4Ÿэ™јFОјuШгђ§‚МЉеТQтшˆшЛїКsrs|=_1Е№†<8žџЗџ§›—‡і,;>Fž€Е­З‘'Œ="A]uІr.LЙ9|o‰х}:%†cХ]їКцЮ™ G>M™џрcƒcрNO9хмТрнЂУ Xеz3 Z"г!0іяYUYІFЂ—L™оЃ.z˜‹љs‰ж"уДЊѕf‘3ˆƒВx№Эnј@H $€Ь•&rs9Œ $€РDŽЫ $€€РDnЦ“‡Ё#$€РDŽk $€€РDnЦ“‡Ё#$€РDŽk $€€РDnЦ“‡Ё#$€РDŽk $€€РDnЦ“‡Ё#$€РDŽk $€€РDnЦ“‡Ё#$€РDŽk $€€РDnЦ“‡Ё#$€mйš›.ћЕќЇўсЙСќf9ќ`6їЇ6ЅєђСкСД5Ф?к 9Љ)“вyVхЉJM7’‘"cйz OфХW$О#?…ЛВпL"—wŽЕ–AРєпM?BЫX ц2 љѕ _k.cФ8)<ДNQp„ЂУGgКР+ЇЮДU№jкjЃ“ ’V@žžюkзЇtvvЪЋљкѕ‰IЎžюѓц•T%6o+’“zк@O‹мƒ.ДvdŠ™.€bIDЄ:OУв0…G†ƒБНш\CcэЁ9mЂ›#э ЩrФfxQ~=Шзо Zš+Hфї љЇєT:rhУUЩ‘Cв&X3ьрMž'Ž—й*•i;2eњЛuЃ5ц ! ЋOUj\њњ<зјб‡=vЂŒ[eтJ-Š ЕЇOUnмАцюнЛ!oпКеjт1[[xCО\­ ŽwjnО>€fжаф‹ Ÿл?bП8 Шооў‹кЯћ‡мЃHЯLsэюс3яОЭК”ОПЅі“ћБ’ЃѓТFдєƒ<1‰2?Oус=К[Л)­Лћ.QBxVА#(фт’т%!K ѕы‹—.ІnдљšŽл?U–—ј№Шљкў=Ÿ”ž6$Bн7Х a_%аs‹E…ыЎ4ž(>R}ІвVЉШUчГф”ѕЫcпОXS[И;яRУA[舆ь H•zOnЧэ›АЉ…чЭл7Ё(h՘Є„ˆр‹U•еUNљѕгле9Ф&П@гјн5ˆсєёЪoџ(Ѓ”Ššдеж.€шhФAЯВЏ6Pk3жЮoомЃх§ч;ŽўЙtБЏŸЭXeЭХšŸк~„фЁ§мГ>…MіЌ[АL[—В:m#МЧ 2C –ъ=šŽо%Г_wЉ‘m~ўЫКbMaѕЇч<_імИ%ƒV‰ЧU23bј YрП ІІ†vDюкрNЂ8Ж2dhРЫЃ"пЫпGуйЛџ@hxаІ"pЕќˆјЈ§жŠј”5I‹ƒ@УPМЬИ|h„b{1%jЌOšхЪХexTмЉЇ‘sЁA­<%к!№а„ O™H(&ьОќКСЯЫ Ђђђђ4$ТŠ“ЊD|т†Ч†D [JO ˆА*> ”RХCЅ%Њф;;и„ХЧ&”Ÿ=C,mmm[л`ЯмйЛяL–jNѕ•хlЬ•giŽ;O›ЊЅ„wошЈшšOuЂЄДbCВJУXeмŠxbЯUJE Mhя (кЉс 6ыПЗЯrM‚ƒ‚}PBлњS h ижоії–џ|єHѕGф8ќvj#œЇО4§%xшe†@,*Q;ƒ№PХ'АЭSWъfjiHPУ7ѕДŠ;v™1|…ŒчиооF;"wmpч‹ƒ[24рщ.3ь•ЖUgД›r8ЭQѓ?5A Е)V№р1jљC89’šБ~яЎмй3퉙йИ|XЬЅ$А‡pЙrqwъiРRаŒЅDЂ№@XјUыРДЛЇ{d=YСйЕџ’Б#ЧKуbЂСUKkЫј'‰O*ШшНCFhdŠэ?Дј.ь7ш›Ўœлѓо/PяRл?b›”œ2{цŒ~žдвкFCЁНЕElUпи”“надpчч;ккООиёвV\ЅTДаJoядГX ‡Ч§ћ7ЗYЉЋЕŸœргч&џІъ“j/w8–ћŸSџ>а€~м˜1Щqёd Чсн§§З(јGзС8.*zILЄы WHъДS™!эР{ћ‚"Љ‚эЌNАQоЫ2њдŒ%/3#†Џ[m­уњњб§хЎ ю|qcb+C† 82*rgі{^sНр4ЧВ7CсЈ <(rЕќРЩЁћрЬТфпNІўe"Є6 pљА™KI`У‡|ЙrqwъiРRаŒЅDЂ№@єН[?ЮMЖгјМ_~іd}Ы†эxpи№жЏЅprt‚нљяBJO ФҘб 8эMоьр#МиРСбЉr!ћFIlр§ынŒ­ УЉЌддѕЇNžЗe5NŽуи˜…яў`МjѕЊЄФ$їщ3 BT.nкН/<иq”R*ZАППw'ъЧэX†МВ;?$ђ‹?X­ZCj3љ™\q”b[ъЦ„UёОj&3bЃ%yЋ•, vіЉБРЛ!3"v%а”–•КЙЙ ”мЕ!1‰ќUСeЋ— іЧЛџэ=ИЂўЋЫ_mYЧџХbдђƒО 4…бсЪ‡ {MЗщ70B.CЖhьL љrхт2<*юдгJA3–uˆТ!€чШ9иЋЊЊ^xюšХСdа€d_яW2ss яТ#3Лџ"j)=Їƒ>еФg…ЌййоЙw=vhp`ZЦ&’0рЦ*Ио4A{­œтНЇшb6}ŽуЦ4пшПŒбзлB%1oЪЮ„"ЕЄBWW—RЉАQ*!QЅmы?(ИРwSV&DЇœсЊbЯUJE MXbО>ОФ‰ H‰!ХНћЯ8ОjkkW~‘&џЕ№ПВдЙ'<Гў;gюœЙђЎ`їК(0kGџ`e†@\ѕ’Ь!$aPђўI-wь†Ьˆ”sX0Mзš`.JJН#0уЎ ю|IХРeЋ— #2ъэ<Иъ0r|ъх>И@ŒZ~р>нB./љSIбЁџпоЙ@EqЅћО“xgЎёБDs]2™$ЮѕLШШ ŠФFёyQУ(ŒL”ЫёјˆФW4H"‡ ŽA4ЦˆЃЃ``^$cТGтЩkр(Žb˜s"А–ЎЙ_SА)ЊіЎЎън]§ЏХjv}ѕэяёлЛыыztзЩ‹(BХ4уђ‘ЧЉаQ’wБйц"е9]ЙИєGХzАšMJЬž@…œ3 ћŠ_ЃƒХ†™Бq*~„KЇі§…єдi3ў07$t SЩ™‚КБaнšї?x?bќиИф„12SL3~ў‚! Љ)t/єъѕ‘у#ЅM‘уЧЄЅg„…‡цфяШоК™щГFRBђœјьодЅ‹“ћ=k§ 0˜V™&klЮ\З#{GpxhBrJШˆсLž”˜<ќО{fФЭ4kЦ Aƒ$9W(Š–КAТEањоu—ѕФFћЂRъ7уЖ‰ѓЛFjъЃQƒнEqF<нвкJwЇлДFїI]њщ'ІІ‘‚ЄCwtўУщœŠЭ…›ЛžQ[ІЅя;DLŽоАq›Ѕ—џЁWЫ?nJњмЙС/дlm’aбњїВмwяЉSЇ1‰ЂСbhњI­Е|wAЩл'шŽ-’ˆ"TL3.y„ } Jђ^6лjЄ:Ї+—ўЈИCЯЂAГI‰Y@УмvЙЎ.lqіиФ-зЏ_­?КЈыš7>њІGдФhКг‡Лег„mв“KЕЃкГ;_КыU[ [э&@х‡{Обnƒв‘NŠЄ,K{ЛфM‰ЧCТ /1>:щсЈШ(nЋЋыzЛ‹МР,p бШЙ› W@!wUиt'ЉŠ/I]сЮ рл\Šп(ž§fыЬigо‹Є‰ZЎд'€Bю8CX№,t,NЁoўЙйГТB4оL ѕfЋў5{~|ёС"rop/‹зШНlР.€€ЇИщщ">“Р9@kjЮ­z&Гс‡;#HOeЖЃ?Hэ$аjЙegOtЊЭ˜Q.y‘ѓ‡!'7gэšЕžYщƒ?hЯ–ziиž б€€ЅWЭ…ZscшЈН,§яМѓюЁї>4цЁqsmўТќљ‹пŽщш}ЇЮ:4WиqћЧ O[‹хЮџygшя~›БlѕаЁAЂщd_иЬ—dVБ*ђeЁуЇ›­Т­иF мl32ЃкŒš‡>8B зФI-ЙЧ1сљ}ЅвжжZїc§ёуяЦ=>wсЋjD~Ѓх†хэидA ƒэЯ­Gо<В:sУkЏьѓ4TУQЦ=a LUf3 зШM3№^’Шэѕѕ^ЊЃaњљљЛgиЪДдищГw0s{ #Ѓ'…‹XЗq{’Kšє*5Ў\i\Бfmи„вY’ОМЙЙуvhi+ГУ]eF˜šдйЄыpљ;ѓ(žШшˆтзЈƒaЋ[–-Yй‘"шь9-++;3ltшМФ…ѕпѓNК8взъЛлтзл?>nСЗпжHR5R’Ыљpєф.ї*7(—Ѓ ю%€уqїђїAяОx|њДщЇN’ЛhџъЏ.;tИђdy€П%/?фвQ&НJ”хi‰sуЮT”WОS>ќWїlЯЯе3QF]D6їМRxс›я)žw–_ОzYŒмNўKyзЏ^:vД”ў.]НDЋlыщ?W*м_љб'žАсЙmLЮŽєeFXЃэчжЂЂП§M0IИH™І†‚Ёмхљmыйuќ€“а$“MЇр‚е] ќ )ИŠ€/ђ§›šЎID/ЩHOыгЏЏЇ.N+{яЄšєбЂCС!Zю№ЇуЮфЄфSu|Pkъ—ˆl–?ёlz†5žоўK—ЄjЃHжЄSЁуЧ|Ншљ­Я“а&R‘‚žмхЎхmyjhƒ€Ћ дœUОЇдWЧћ РјтзЯЎ\kьзЏП„ щ‡†˜щБ ‡…ЧƒюЄ›иЯзžПёVMžN—}-‘Э†Ц†wk]М—›ohМЦ”ЉбдиРЖњѕю#ЕщЪ :’P-Žє•“Њщ•7nлpБі"нy`ЉHСPюђmœр€иNнfTЭйЊрпЁЖХвmЋа ь"рŒЂd—c7v:^z<<<\  _рђ}ћщX#žUЋW-_ЖО(uА: аtRЭ(њKgЄЌŸe›№sTЁц$>tjŠnэїЕt+YЩёт'“S$€ѓчЦnкЖ‘Њ ­ж_GїЛЉСЖДДјћ[ќќ§щЕMЯog ї>|ра2лмдМ§…,&gў§юЌџ‘џш‘Эищ1ГГШ ]uІP%S";1бSГrВш3-sВh•ЙЖйpЄ/з8}њзпџОЂЂТ&R‘‚Ём)­›нnY№Ю"@ѓkЊЊЊJ-чОA 繉BnНŽ;:4brє†л,НќНz˜}ї,~ў‚! Љ)tƒїъѕ‘у#еЌ7gЎл‘Н#8<4!9%dФpІАaнšї?x?bќиИф„1Ёc˜œ5’’чФ/рж‘ЭЄФфсїн3#nюЄY3 $™йYК8Йя€СбГІбпрƒi•ЙЖйpЄЏШјЬ3_+~У&R‘‚ЁмE1@ ОFрЖЫuua‹ГЧ&nЙоиx§j§бEУД—‰šMwWiЋa+(аgЉšOщRЂЫšЂё It–ТхžрРgTМ]59JwК­Ѕo–ЮŽЃ[Š аE€~ œю7В9fэ­э;`шЅЊвІПџэvгџВ[ДмG іыZК*я>џ№ =H@qЩМ=У•o№‰_vѓЭЁѕЈЌ<‘”ўo6ОMчь€ ќ—Г]Уžљаtв;Ѓєъ™2r^ОѓЫnn" ЗVg>ЎьY­­8*ъYтціf-у˜QцcoЮЮ'nvѓцBь    EРПGЎХлМŸ@PPPбўЂˆ‡ЃН?dр)ZлZл~І/šщZ*?(ЇIЈKJ р (фЮ žD`dЈѕљГД3ѕЄ ‹w _}в?ЃЈŠK“аЛsFєоC…м{Ц ‘ъ&@ЛQьIuг‚"€€wР5rя?D  руPШ}| }я&€Bюну‡шA@|œ ЙOЄ  рнPШН{ќ=€€€@!їё €єA@М›€ѓП~†ЇАxїŒ@є  .&<мЦƒF љw~!Ÿ8iЂЁ    >EРЙO9q~!wn|>5ДH@@ŒР5rЃФ   D…мƒЁ€€€€Q(фF‰A@@<ˆ Й BЃPШƒ>€€xr „  F  %}№ (ф4@@Œ@!7J њ   рAPШ=h0 €€%€Bn”єA@@Рƒ {а` 0JРљM1Kѕk/дžћы_Д]<ј/Пfф‰rСЁЁ5UUк6Бе)едœ[ѕLfУ =9ОоЪФглЌУaG^vtБobˆ‰фіy1w/“rЊтK–­аТ9/*фкжМw+о69Й9kзЌ7z”ї""їpЎ~—Йк>сэ>ˆN­k JбыG‚G‡вЋ–’YЖБУPzЃš%'cyœПјэИ‘.Џт>‹зи`ˆЕ= Ю0jь]&ЮЯЁ-ЬОТЏЃ:Л0zlBЇgј@!ПiБhџ‰I<|№й5%‡ŠUАХ<nДмАмažt €€№BnяH~ўщg}йwіŒ9}ћі§Мъ3…™YБ3ыыы$aХ;Rƒ$$Їі•++жЌ ›6.bIњђццf>БјЉŠ;4%ЩS&Е§мJЦчХЧ…;ГЌЌT2%ЅOЪEЏˆœ2‰ЌmЩкdЙеЕqOAadДUОnуІЖЖViщ—™а’)њџф’дЕk–ЯŽCѕЬQ‡С…ІVcа4тсЮжQ;MIыWлЌ]дXXRƒЫ„6бŒіcвDЂТz‰фЄ #б„сЦУ2Іi ѓ‡’>Kўљ/чЇFEбцЈЈ(j“DЎ6ўєйj’”VшPQa=дЎ>{šфд8Zt(8фAЫўTЇ““’O}tŠ„#CGѕѕЈ8iеМђcуЉџ85gІu7аxк› |&#$ъ%cYFŸі…'о:!)<^’‘žжЇ_??џдХieяdWЅІ‘zзъЪŒ§ImЮь97ўqc•lѕќйІfГС •+$S™+;b[7чќ—/\JдБфј‰gг3Ќyѕі_К$UŠŠ+р†ФjЄ,gxЂМŒ СГ4хяБŽr˜іБх‚ЅЦќJ =оEœЩзЕHŸВЮXfWДdЄІБH4BеžFwnxЬЏЂЁ§–дСюo–тcЅ™лжяо™7nt„фBЯЬASЩV5тбЮZ;Mf_на6Ћж'‰v›XDLh&71з"9)ШпŒЂ У‡+$ƒвцкл&Пk†ЇэV›ƒtјШсkMз‚УКN>z|iJ235*фС­лЖвъ[Ѕ'В7mоѕЪОЉSЇ}ёХ_3Wg’АцB-н}Оі<эй­]:1/LZИ#чQЃr =1Ÿ*+mЬ}a{СЫЏфяЬяћЫ€хщќЛІоhЕcБPЃЉБAj7§а3=Vj[_;НP“Њ`—œV;‹КфQОzƒn аНpCх ЩЄ_яŽШ)з‹ˆRCcЫ—…ЦŠpCт ™}uCЮАЁё I>дKSБЪЭZэˆ J”šЂЛя"ЮdŠыZЄo‚]ѓEЂЊž№4КsУc~ эЗЄжvГ|uoьєйУюЦьы™9"hЬˆЂЁvжкi*МШWЕЭЪ5Y[Л‹M,"&ђї2{[‘S‘œ6ЩпŒЂ У‡+d šІ!лї›&'ЧЙe)>Vіо['иn‹ЧчЦ?О4)™н EХщзCќaЅПРШбЃvэйѕёЇ•$‘*хЊеЋ–/[1rSвYїа№БRPєзџјc~AсчОxюkЩЇ…v/Ж& Ы9™™ып~ы]I.Ѕ#xiЦSЃ_рi5Ъїэ—OqyWДЙЁr…zМ‹( ТђevИBnH\!ГЏниŸ…д>§Еѕп*JЭЫ"Ю"S"}+„+в›‚ Аю†ъ`w†і[RџОRИ?19СџwХ?f=aF‹ž™#‚&YPПъGбW;M…ВKWmb1‘П—хI$Wd!š0мxИB…AЌтд:gщ<љяї[VХIƒк$‘ЮŸГcЦ>Д5gЧ”iSH2eђ”­лvDккввтяoёѓїЇпІчЗГ.дX˜єtAaС’…‹иgКOЭzпнТvгв"8>ЮЪЫЕž|onЮЪЩŠ™#œ?7vгЖв;юY#;rGvЗћїЛГўЧŽ;рFИЁr…ŠŽмUЅищ1ГГшцКюz“њr…"мИBn`jaLєT"/ СF‚шЉj Мr Ђдф::л"ЮЂю"§vЙšЌЛƒЁэЎPу-Љщ“1еђ’7JАrфЮE"h 5M<Ќ khЄЩtD~™‚КaД ‹мЌˆILє#ђы"’3Љ!š0мxИBВƒ›нTMИКЏјЕИЧт‰ЭŒћSёkraФЈ0:ЫMТЈ‰бдŽеqQmsцКй;‚УC’SBF —їђяeЙяо!tž #ЧIKЯ ЭЩп‘Нu3“ЫddЦцFOжїЎЛЌ'к—јљ BF„$ЄІасЋзgDŽ”wБЛ”<'~wЂsCх ѕxQJJL~п=3тцNš5cа A’)ЎPD€WЈ'NвYК8Йя€СбГІбпрƒiUgGЕš^ЙВ(5ЙŽЮЖˆГЈЛHŸюішћ š„4C~gчщ<C5к] Ц[ваZkљю‚’ЗOа}UD‰;saˆ )дsCёА^RC#MІ)ђЫд Ѓ]ИXфfEL–.NэšHЁcX‘œ)H б„сЦУ* š`ѕЖЫuua‹ГЧ&nЙоиx§j§бE]W†ИщбзЈhБK_\ЯRДIO.еŽgЯю|щоTm5gmЅЏЅ=:щсЈШ(§ЉІšьж §ЙCг3 а9Є”eio—Мщ™с!*№^є с‹ЕmVЅY{kћzЉЊДщяыќPэНIkFNПЃNuZSХB:к NмJ_л§ю?П‹ŠмъD›0=F€Ўt$'&ЗоlЫЭЫ™№Hљ…# &/фє#ъžѓ;ъt`=$hHnїKцcƒM рiшJ]яhЙй2qќD:гюiс!№M&/ф5ЈvŸЗЛЃGЅ`L@€Nїй<уg‚4‘xмЕю]у…hA@@ ђn8А  оE…мЛЦ б‚€€@7(фнp`@@М‹ ЙwЂnPШЛсР €€xrя/D   н wУ№.(фо5^ˆ@@К0џ/ЛбCОыъјхьF+   рbAAA#CG9з‰Щ ЙTХGыxКЈsйС€€"№йЧ•ЄямZnђBNЧтTХG†Ž4Ъ   р УюVєђчr\#wХHС&€€єђ 7   р (фЎ  ›   аCPШ{4м€€€€+ Л‚*l‚€€@@!я!аp  Ў €Bю ЊА   =D…М‡@У €€И‚ Й+ЈТ&ўгH1ДIDAT€€єђ 7   р (фЎ  ›   аCPШ{4м€€€€+ Л‚*l‚€€@@!я!аp  Ў €Bю ЊА   =D…М‡@У €€И‚ Й+ЈТ&€€єђ 7   р (фЎ  ›   аCzѕ7Й њьуЪaїs“И.E/яЁТдЕюŒ–Щ љШаQD‰Р9ƒl€€€€CЈŠK…Щ!+н;›МSВ„ЬщдК3Ф€€ИЎ‘Л =ƒ€€€уPШg   р6(фnCЧ   р8rЧТ€€И ЙлаУ1€€8N…мq†А  n#€Bю6єp   Ž@!wœ!,€€€€л Л =ƒ€€€уPШg   р6(фn@*ye  єшhtзГЩ‹ššs“gЬ4дEO jpЁvъ ЄЧрШуєFPђјMжіісшјqQS}.rЪ$G,šoЬkъоcЪ(ф=†к$ŽrrsжЎY[SUe’|œšр8'ŒqxxEсDьTQЮЮœьчВЅ§ЃsE!—гшjл7EьыехЕНх# ›N\=ёлq#­Я”УЂ&а3p<|†ЈБxšФCъ CЁцŸЁ)82ш-62фAЩ‚7Ђp$wО(фpА‰CрFЫ Ы9DDp0 @РЅЌo1,*(ф*$нєYВЌЌtrьЬАбЁѓж_+mџМъГyёq$ЄMЄ@BщS'НВŸWЎ4ЎXГ6lBDиИˆ%щЫ›››ЛлцЌЉ7’я)(ŒŒžDЦзmмджжЊ6GжŠKŽX/iЖ^•gIšŠUIЈmSо-Ы–ЌьШ єG Ы­Ž~;ЄэџдмHЬ’\”83($|Ы’П3рDFGП~ЄCŸ+`ф†ФВ`p”ФЌЪŽЕOАqЁ4Ѓш*{Х;Гcѓ­Žй— /’PJ{4Љ/Yгу]Фйкїющ[nЕnynЭXКЬYєњ))nЈ:У# ТюЊ№$Їє*ї.Х0+vf}}pIH’[лт”ПЫЄ^єZћu-НѕhЕе3GšZ­+lq<мAaйHSќОг™љЂ†:Š"фК`жфІЈЭPPC1j;кYsс3Пžп@!З=FЇџ\}ЈpхGŸLxxТ†чЖIвзЎjёгgNUэпUpіќW$”Юѓа+;с“В<-qnм™ŠђЪwЪ‡џъžэљЙ6ЉPnEћTuсиЁУ•'Ыќ-yљy\уе_^8єъўšOu]вЖiS^ўKyзЏ^:vД”ў.]НDЋ,‘_57ъТŠg.Ј!"Мч•Т п|Opо=Z~љъeЉ W(J™WШтQР!Й‚ЋгUЇїTžќdЪф˜ЄДЅžњ `WЭЗ)Q6dm`іЅ†к Щ™!zМ‹8‹\‹єѓ_*Мўп­хeЅЧўtИњь–šhЌіuРбъЎzѓrJ‘„G„ŸЋ>GэцІцgЖo–>V}Žф$дAљ@KІ>џєГ'—ЄЎ]Г|vь’ЈgŽ: .4Еšd_;ю|`Ег$5nwC™/jpS0ъB2(7%Е™#љpCеЮš Ÿїќ Йэ1Ъ\™жЇ_??џqsЮY#uhМFЧиЭ>“‘ЮЕrДшP0]ЮЙУпЏЗrRђЉNqеl Й<^’‘оXътДВїNrэЌJMыгЇw“ZЈг&ыxЂМ,cYйЇхйe'Ъпc›D~ЙмИB2ХMœЙ †ˆpЩёЯІgXG­Зџв%ЉRЎP”27$ЎPЂ-‡ ХjeЦР~4СцЬžsу7VЩVЯŸэ˜o ЫŠU.(QjŠОrw"я"ЮdŠыZЄO3$cYZћ|щ“‘šЦ"бUOxнЙс1ПŠFXијгgЋIXZq< W@E…ѕ Мњьi’SCkЛПЫŠ•fn[П{gоИб’ =3GMВ ~еˆG;kэ4ЩЗЛГ K‰uЁN_!‘ПзИЁjgmОТЛлW{Й=ЯРЏwG!Є]э›ёцОАНрхWђwцї§eРђєЕуFsюџЊЙPKЗ1ŸЏ=OћGk7{ashњЁ!fzl=q*f]:ЖZ:m23 зо(­RЃЉБmљхrу Щ7qц‚"Т  ,0ІЯŠRц†Ф2ћъ†‚ЋЮOZ4СШе9Щ”|ОЉЫ%\PЂдфЉ-wЇXeГ]Ф™єЙЎEњж!и5aX$Ёъ OЃ;7<цWбђржm[IјVщ‰ьM›wНВoъдi_|ёзЬе™$дСюяВƒЏю>{и§У˜}=3GQ44тбЮZ;MђТэю,ШRF](rWЏЪпkмPЕГ6 _€{%‚нП{ƒržїк Ечўњm{ўЫя† яzЫi+Г­є.}Б§=OWП23зП§жЛlkЌZНjљВх#Gбq!І Ы69ош8Є|п~љєЕiѓЮ^ CЊм іFm ьхЧFЉdRЃ_`›1pЙq…6M‘‚ˆ№Р!,0f‡+ЅЬ ‰+dіЕvАв6hsЋ(5›е "ЮjMI"вЗBИв(еr жнСPьЮТ ЗЦЏ‡ўјУJџ€‘ЃGэкГыуO+I"Нeєр+…ћ“ќqWќcжѓъДш™9"h’ѕЋўx}ЕгT(ГUgAfе gЙркбЮк(|u№ю•˜ќд:Uё%ЫVhџйЌємЂћЫЌїХаэ]7--‡щ§ћнYџcзнI---ўў?кymz~;зŽZЈ0ЂV$ѓчЦnкЖQкж_Gёˆ4™ќо‚:BЕœ.n!‹ЩYӣݘшЉY9Yж ЭЭsВh•™5ИмИB‘Й\D8vzЬЦь,JГэчVКыMъТŠRц†ФЪубhлСJdЭu3DфQФйЈ~;„міљвœ•зuЫˆhDіrЃн5ŽћажœSІM!S&OйКmI$wњG>^S-/yЃЄшрЉ/wц(ТAVЈБмѕЧУКА†FšLGб0 Yо]”‚\‡кŽИ›йбШZ_nж“л&/фЎC9~LZzFXxhNўŽь­›%GI ЩsтА{)7gЎл‘Н#8<4!9%dФpС(ŒˆzХЯ_2"$!5…юœ_Н>#r|ЄH“Щ7Ќ[ѓўяGŒ—œ0&t “Г†Q›K'ї08zж4њ<`0­2SЂ—W(В —‹'%&Пяžqs'Эš1hа Љ W(J™W(GЃm+‘5зЭ‘GgЃњtЇHп_јGO6уsCNЇˆЄE4 "ћ Йбю#F…бЂЈШhr51šкЃ:ЎsAk-п]Pђі КёŠLqgŽ" d…ЫнP<Ќ—даHSЁЩVBfЉ!JAЎCmG\ШM‰ьhd-‚/7ыЩэл.зе…-Ю›ИхzcуѕЋѕGй8ЩLwљгќfЎ<97ŠЂ]’КB;Шy/Jw–jЋa+€€ а ­”eio—МщD›0& @пAНX{бfUšЕЗЖя€Ё—ЊJ›ўў7‘›`м‘x КвAз;шьzn^nЬ„GМ&n L ѓм–‡ˆа@LC€ЎtаѕŽ–›-ЧOЄ3эІЩ ‰€€  Л>\ƒ€Я †6Яњ$ Ž0!oЛец"єЯ%€kфž;6vGЦn›Зл:‚€x rўHЁђЙ@   рaPШљЂјE~О’XŠЯb6и  рLцПFNПМ†@@ЬJРф…œ~G}Яю|эС#ЕRKхєSъ9џОулoОщїП†,YИˆЂ PV+H‡увkЧ‘==9ј…ь“я–RІ=Г2нr‡е щаЬіь/jљЏ–iS'>Г2S[N]ш9ЛE%Хєƒ‚'NЬ\НJњhы“’_иTZv2р—I IVгX@@|ƒ€Щ 9= ХŽЂШ‡ž$LПо7nLФ•kЛїНЊ.фj*оьs€dŠ=٘VзnйHЋьйšеUеєlf’o"љžТЅ)пЌхЪйsv§{ћeџћvzљЪж'ЈRЧыWЂЧ§}ф‘kMзЄxфOкfеЁB  `>&?Еюј€й|АMŠAуЩСьБйд ЧшВ€Йrюsvлэw=~[zА)Гƒ€€€Й рˆмЦјr$,яУUP<WуЩСєTцŽЧ3гѓМЇФ0Ы\Йш9Л1бШѕ™4@@LOGф6†Xz№uпм{п}ьЙуђ>\щљЛ7ўqCКkžМх…  рыPШ}} Џ&€BюеУ‡рA@| ЙЏЯф  реPШНzј<€€€Џ@!їѕ€ќA@Мš ЙW‚№u(фО>?€€€W@!їъсC№  ОN…мзgђ№j(ф^=|@@Рз  ћњ @ў  ^M…мЋ‡Сƒ€ј:r_ŸШ@@РЋ  {ѕ№!x_'аЫ(€   Š“хПіЃЁ    MрbэEЊГк:Š­† љШаQd‚<) a@@@РATХЅ:ЋпŽсBNІЩ‡Q7њ‚&€€€€~ИFЎŸ4A@@Ру {м аO…\?+h‚€€€Ч@!їИ!A@    Ÿ Й~Vа#€BюqC‚€@@@@?r§Ќ    G…му†€€€~іќ LбСяњњ}x‹ц„бХЯ_р-б"N'№yеguuuцƒ ѓЇЭ|<}љИ.фR?QrBnХэ˜иJЕмЃ‰,@РмЄ2Ж$u…љвм™ї"%Ѕ§ћЁ>žОbа r:уЕ7šnV2СъЫ…/?‘ќ Й †)€€щ аБxв“KMЙ+ž=?Ој`‘v!їёєглЁkфї?ј;2gŽWЌ‚€€€WИНшѕ#іJѕћыsЁО&x•>‹XnкGН@@œGРЧwХЦгяuКъДХ2ирДZnYОЎў Нšc1S.цd  ƒ€uWьУ‹Їп5ђЗ?Л,ЃkЭHыўыyus,fЪХ#‚,@@tш5№ю@Њ]jжџжЏЋЯаk—АGZїџярЏПЊqК+Зфтє,`@РЗДяŠ}+eyЖ^’О‹Ъ–œDЏ+?6ЪзѕЖoZюіѕчTЫ{|1~§РfˆЙДйд„€xь= ;нЛboIпXœКгяЊ^Y9YFЏ‘гa8§е|~Ц‘уёр‚kОT[s…ЁvќwФЉТ[эШХkж piWь Чѕпечцe}rІŠŒ MKЭњыЁ’#љ^šдRžz|бIГ‹wfњvХvЄ____—{ъЬŸ[ZЎнћ›рЇ’ž9Ю™‘ l+[њв—ЛК=$tŒ|];xd˜~eз4S.Žсx8+?^y<щё‡ЧOЎЌЈЄ?jа* aздд|yњ:'Wq…ч­R )‰ sЌєи™г5жmxчн7gо–nlŽ}ўщ(жОŽ:{эй™9!2ldиКѕыкZ•ЇшSaбС"IaЫs[ќц˜”‹в‡Ю@Ё &"Л+7iQвд™S§zћб5huїЎ\yŠŸўљЊДдьЌьЈ‰QrЙSк.кS^‹R–N9ЛOŸ>–^–aУ‡=ЗЭњrДP_БlEиCaTq–Є.inюјХ3*4eo–MŽ™62x^мМњяj%}Њ8љЙж VќzQ‡аbб.[LMЛaGњіў ЬM‹ѕ(–Юи§GЉЈћv ‹іюЉўђТБ?ЋќА2 W@^n^‡rЇ§ЏЎЊ>vфXљ;хз/_Яп™ЯБІЖ/tфBFБ€€€ьгйž:ujкФir ДJBЖўјфЧ™Яdцюм=2dЄ\Эim§ќЄO)DEFqƒLљП)‰ѓЯМІђdх№_нГ§…э,йгgNzљPх‡UЂ&lШм ЩїьЙ№ЕBН[ZyЙсВ$Д]ЖtFЋ?§NM{ 9]#?эшy№ˆ`Х_gT–ƒo”dЄgєщпЧЯЯ/uijйЛelkd,Ы VДц‰ЗњэwЧsaQЁ ^MрZг5кЏЪS еІІkLВrхгkзЌvџ0&ёŠF‹*/ібCGƒC‚щ0Ю@$/NЕ~jщ\2WgJ•hAм‚ѓїu•/y6§YЋМЗпвД•’ЎžВеiеЩџ џжzЇџЖр15Ї+;Wэљ_sжz'…| jБXЯ+4§а3нњ“ŽХ&;пабx7M5k{рР>M 2…Ю^Кџ;ž‹nWP'`;FЇйьпЏsѓЊRЬ"jюзЏ?лЧЎпАm}цњМмьрр™Ž›вPхХbЎЉЉЭљcЮљѓчoќу†U(Ћ8~НiнъХЯЯrƒЉлл  Tw’ lIšNЕЗпДд|\i=ŸрШТэо.ь8Є|пў>§КfR—ЏЮ^WъЅ/Сг7шHПKСxHЙјєo$Ї† n'аЙ?tb сaсЅяlГIЋџЮіБSъsWŸдДєЭ›6=ŠЉ9­ЁWl$}ЪЋтdљьXЮmaЋVЏZОlyФѓЃќzћЗЕЕ††eЩv5Єєк= BuGё+,zЪ–.Dњгя4gзЉѕ[жЯ$Су"шею? @н— cчЦЎнЖБўЧFвЉ§ОnнЦM’2S FV^юњмимLп ‹™ЃЖІ_"хB6Б€€€зhпыпбщдLHNиГЗЈИЌДЙ­•ўЈAЋ) SЄю‡ЃFЪ~1›ŽЫЫоЉаiVПš^ўгOINйЛwЅsхчцЖ[–šЏkWЌ_+EеввbёЗXќ§ыЏ4nz~Л”#mb I­в уйYWšš›n}agžДеfй’дlОЖЛ5іbяЙХREGф.[ЬЗ~LIMЁ“wпwпгIOЋ]…Œ>їs[ўЋeкЃ““’е њ%.ЭEаЗК;hwСюм?цfяШІ`BJЋЊп}0јA’Ї§л“?5џ4Чоo?ѕdВ”BюKЛ ђџ_vKЫ њљТФ…Rы2зэШоБќ‡хtЈНш‰љЧKk–œ˜œїRомИЙЄ–”’$)ы)[кfэоj!сH§ЋЊR^ ЇфB‚"q‘ч&W˜ѓињ“oЕЛэ`.vћEG№@AїQaу&п “к›ЧохЊyІ0hhажЭ[еБEŒ ?&Ÿ6ЃуєЛKЕмШа[wХ>Мјxњ]#oзїШлЛMџЭєкE-ї Z.нўцОрМ‰Рm—ыъТgMмrНБёњењЃ‹lќ|юЉOНЖяхЦk‡ёІ\mЦzгВlѕВ—ѓvйT„€€ PйІт­0ˆ{п@ЋХ%GттЭК+ЎxЇ”ћl ‚ЇOfэ­э;`шЅЊвІПџЭ№Љѕ ЃšЗ№‰ч7>Я€šІБњйе”iвA" реpŽ]{ј‚‚‚ŠіEВіryДA@РYЈ~Г‹хјqgQ…гАџЎuгЃA‚ =I@КЛM:ЇrŽз{>|y5rЏ>&! Uq“$ƒ4@ g рдzЯђ†7љYtjK'иqЇ›Š Р'€#r>HA@@Р+рˆм+† A‚€Ъ)aљ‘КхTAР rƒР  рz(сЎg ц!€SыцKd  рƒPШ}pа‘2€€€y ›g,‘ €€€шvœЅBTёA H@@МˆеkmЗBNRљ6І„€€€€gш*фєXSЯ Q€€ˆќ˜•ˆ=фЊЁIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/20.png0000644000175000017500000007772111733011756026244 0ustar sylvestresylvestre‰PNG  IHDR—1—K5РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН |TеЙї?yџ™ћ&€‡€хmХ#*–‹@*‹хRŠXБ@бх€"Šˆ‚\DЪ EА-Š-UЈ `+`ЕxA. ‰Е˜…P%Щ9b&џ?}Ÿ={ВВГgяIВfіdц;Ÿ0ЌНіГžЫwэ™пОЭЬY'‹Š@їл—Ъ3@€šНЯ<›Щ?‘№cч7‰ЄI€ !а§ій"фgх˜,^ZV@€š oљy(tђHХСэ!у‚w0гmTГ@І]ŸF…‹O7ЗРЅч”|ЪёpљђНaБ_TБї№щБЪ#‡FЎђ%h9kЩ*zvЂ{ЬLД„ЋГ( ФhМ.$ƒ‡Цѓj|ЕspLew~я@ГђьsСцС6gЗ …B"чeЬЯ‚—(“4њ,zэкsŠВхr{ГЪвЊ:Юе_ЌCь­ g7 ЙљєXeѕ ЗэKа:Kа˜UєьX{ъ5бuІ д&PЗŠgž›лё[МžЙХХ…чтЂO‹N†ВJЫ=މƒŽд6ўДжсП*Б™…рЧ†кzŽ_ОQ†˜pциЪЊРkGJ§ЉPNЈўќiУe­шi3К[юИ>эЅ]~&Аџo%ЫwЫОˆЙJžš2Fž­~д*еƒКффde”ŸЉмx фЗo_x'ЋrГ'єюл:Cv+ ў^ўьўт7?vИOа5f{ПпЁgЧœ Ы<ШовЦ)}‹OUоіф>  ЗOы*сљћKП ЙЙRЕiХЇ+ѓџTјNQ$™›.Яб5З}ЫŒђЪРкз _|Ч яV”œ ‰Ю*ьЕж“GэŽžU†jvЂ{$@ИгaЂeU­Ђœ’4gм#БZА$”€У{{Ђ ZtССC,xxА%`ѕfU(‹ЋIУкі*ЬЌсФotЇ[J=ь~­й…О,/*.ЪН їйчžНтŠюeхeeЦ h"Щ.ЃФЋrluTЛ8UжЌu­>qk tqkLg№XUфОїзП№Zсzvш{eћа™ЪхЏ”єYДџх{ СЛ?}(М44OПg5ߘёTA МфŠKsЦєщ$’љрцbwџЁТо,ьэхЪZndŒОЖУИыsd_aўSƒЛЖw}бь_ПY"kgю”е<АjЫўOŠЫЯЯЩйЕУ;—Iшкn мбГ}пN9ЛПДЧ(Єч•ЦЎFшLhџGх]/ЪК!7№чЂр Œ]Ÿ‚c%mЋJJ9nЎЬˆћ?ћJс%ЙYуv=АУшџк'ЩќА[ЮЄ>э Ž•Яиќšьыќрк{šts-Ъ1ЋАЉЛІ4ЗкG_+ˆpEЯNtК\bhЧЂn3б*~)М ˜ш. –‹ЗФLD “ьfe-šEЃїН#‡Њe/ь+”ўžrк6ЋѕѕsЅUСŠ€œ~7Œ{ЅјDIIi(№ъaуКлЗs.hVГЁь~чpшы›БtЅБЉэлS пђŽ!џy]$œсйМG!Ћ™\nќДdХц§пЎ†иШУ-~ Я{ЯfaѓРю#Нўr[BН:{-я~P”3џ›ЋШР=ћ_—эљ›1<++улAƒЩ№.ЦЮС Џь—§ƒвЪаКWg*=ŠrЫЪ Ёžнjї№ЌЦZgЧьДѕX'zЗSQy&К}Еа™ЃмSбi@ЩC@)‚™RvеЉчІА6™ƒкq1QЩЂфKЦ‘ЏёЈўп\В?]VRlнКuЗЋК-щ]№aqQ№ьрвŸї•ЕrvAн`_ЇŸ’rCШ—§jуI)9|J9[ў—GГаі•|ј~с•чrлчєНКгфО9ЃŸ(ВЉ…Gr^rЫnP…ЈЬхО\‰џйї:ˆ,~ON!ШNGЮьц |зZdxHtкrо;гиН0ђЯЮ †О0$мАЉ zх‘•JOnЕ{xЖЏW;К($нЋWDŒ!8АыBY3уLсЦŸDРЦџJЮ­ZСLСЊ vБ%щэ!:Ђщекoѕ[L/+‡*†?UnуPжЬvХС9‡˜ЮЈ—•ў­АВЊRЎ‹ЫјЩ’“'ПoWu§вV‡НъБЎ Ц>ЖзU—ЫбŒъf\Y?|ЄШ(7ЉЩCv5jœš;*_—‰„пиГCMuЫбOѕJуџ‡ŒГш§{v 8;xIћœ[ї“#cШ‡‡tfчМRи[Йьвш3ъю ьGюјpєcЕ”cЛЌ@HЎчџМЏЈЮсП—?mшbP„ќ…‚’ НлwhнIь ?Ћ|э­}С€\ЙœЬ7x$№иkЇr›z^&їЕйw/N|‡ЮЫ(>U~ВќЄ\;ЈЈ zИВ&lkџсpўsжўЌЋТЎ}НXю!јУО€[QYY=Лею+zvЂ{Ќ!<кПоSœ›UщˆЮ-1ѓ ‹‡OVAq$рўо.‡ЁйUЦ!“t…32ЧК{Ј;m]ъŽT—…SJТeWF$\\H`БћrљeвEЦсšлctЮЛ—wИИCЧ…ш’ћеEХeї:Qe9фЕ Ў8yєМ+њY:ŒІL’™œъwœЙЯон™щђƒ(зЪи#UЙУŸМК?пјд™y*{ 'Њ э”Eљ№qvРИQ\^?ф^ЖЖЭ"=b)ЇгM?boњtєЃТ‰™ х“{хŒ‘U Уy†NЎЧЋ*“љU97 б}=Kд—Зк‰ccзЧš›,^”s FаcUЙтYz<\YKыЂD1ђЛ’НPГŒв№э‰nEyg%ЮЭ‡[эИЂg'КЧšЙЕ-A­‹*Щ`FіC?3vАц?ЖQ6х–Xuтќ$š€Ѓ.˜I˜ц Zе9šКэA‰_ЕaЭџ6oD8ЃїФГ­пC›jЂЦађЈBPu9VЁ‚”ОЗУђЫЄnЧфћЭ~ЛЇЈEYљ5;^йQіyй‰ЯO”ўЃ4№Э@шќэя\8ѓ§@рbх4вoQЃ1eJЪ‚ЕЯћ›wѓG5н ф–гјgN|йя)e яЇќ­*Ћ­qћ€a)К+§'9eUйЭŒž У—!‡ЦЃYРцгъЇfU3c_с„ь'šNŒEуГЎД*;Sюж {+­ ”6Ы2Ў=з.С#ё|Ќ*'Лц<|MnтR>V—нЬиЉЈvшсЪšА1Vс2ѓЏ’,УdбрlИu+Ъ;+Ѓи№У­v\бГнcЭмк–˜жХiпяАaO03Tvc7c_­№ЃтРйЦ>–РwKЬL›g@Рђ&V§>цнPћ•рАЁв…КYЈ„ќ_’"#’€ @ ўPёњ3c @ 9 тЩ1d@Ј?TМўЬ@HЈxrЬY@€ъOЏ?3F@€’ƒ*žѓ@€ њ@ХыЯŒ€ ф €Š'Ч< @ ўPёњ3c @ 9д|krфC~и`_QQ‘Ÿ4йиЙЙЙ]ЛtkВщ“8 аT  тMuцДчmJxПО§Е{N‡;wэ2ђt˜kj„@R@Х“j:ќLFŽТEТГВј=й†ЬТХ.>Zxo;Ц@ аOУѓЎrО”SЭиЬвeшЦMЯЅ|ЉMњЕ„Щs-&х_2ё.Ао*.^ђyЩјŸO62ЋrI/мЊЕ2Мєu­Ўšћ№JOџbQYуТl…ZC(џћіlє*й!џ:ъ­ ЇюbU&еЛTъ‰ЛѓАБђМ{зњjчќпСцС1ЗŽ7F:nЗеЕЇоeЋд6gUэ'МP§T{*Ћ{ыщмбГјЊэмыЕPЈАSaoЕЭœˆUй^нz\E’ЗUZ+эЈ@жЕQzОЎ]–u`5ЦъЉ1J6JJ…vИˆ_…ЎaCЋ^ъ­тrH:цЇуCЁклkŒ1ЯvБ їЃWfDwеъ‰еQЫ<ар“ХЛ_ 4Єdїzѕ,6Ъ>ЊУRiƒЫДј Yo!yзnРыТ}#‘ Ій};‰2ŽъЈ]SУЖ“њНЂЋs|Б;U;ћкK–BъUELЩлr>л2 uфiO2–мкЗГў™ѕЈИeJiж@C>ilfпXыыє&аЉKјнЧТ œB• :"JЮbШЪѕ>$щvткl1/КфЂ>ќШжЉa1 JVЅЉ††КвУ…ˆwСqЏ5 6’Из(št™M:љDЬ.1š†Њxђ•‰А%lNдсlЋџћыЎыqї]3vg{qqбдiSŸпДYх ЊіiяЕЪIj4RуЕUдНEйЎЕз= д"а0—S@uŸ*..^‘Пт7оЎЈјтп/юtлэwєынГVp­ }X`ЩЊюєъ<&Ÿ]в)œI§мзg”JC5ъK‹Е)Šхххљ+WЬ{dёВ‡jq[Ї“}ћї]wэuІYR sЌ“RŸЏ“Šн іkСОVЧrLe†ОЌ\Й:ћŽ—Oz<ѓџЖКЎћwGеЕkзЈГІ2Œ)yх\fТ­ZЪ>kп9Гяіоg-ќ[сŠЅ+^ћ@ЫoЖœ>mRо A1ж‹F A*.wёдЕџxъГSЗŽљЩЄ_LОћž9YЭГф&ЬuO­юй#Ž*n­ПЮєЌЦ1ЕПЎЛdхЇaбcЅЬTCХM|CоЮfќЧд^yyfh9>~ро™O>ѕЬё’уoѓЎѓYКыЅ­ВЖяyГяšАн7фf№uhўУKЖўiWц73Чп:fёвJАїМЕgШр!•J3gL]Лn}ХџTф ъ;ћЎ9fPщWN"Уын#ЎБЊ>‰˜'У жQ‘уъ˜Ыœ4cњэ.XЗf]ыѓZЫпс§ћџЏЧ:­‰UХƒл:ыЭ0цф%r^№ž!Œ}жG–ЬzpоВЅЫliЈEyп›xЧдY3f-\њЈи?Бі‰~пAХ9ЩЏвЈ?†мнK”­7qђ !У§жf;,XTНщWц/˜пћкюђ' ѕБœN—uкЖyу€Кwэ4zја‚‚‚лЖ <дX5КјoХf\1“[:{паЛ{Wћ№шФжЎZiZоwџ}•ЁШGBФУЦпopу€NWFіВЃ6О'\ЮЖH9Fў…ІЯ§{іKuR”ЌкЖy›tŠЅљl6Є-яwNЛГћЕнЅЦIS&Щл9жёйЧУљдКmїр{G6<ЕЮ№@`хуљЅŸŸиђќVљ;ёљ YДхяfАђё5Ѕ_†vlлКхwЯа­s_tz№РA(УK?/[ЙvMЭ№к­zGЏ=<.K./ yЬŸ;_6й˜eуWл‰[П2†lcбЁл@НExkї”ЉSDТХ­Мєьлoеš_EBTVЎ0^›Н{uпјћѕfЇdk}aZЋˆ~Щ›kхY™щM>к›БЯzЯœзпxНђLЅd.ЯЪFѕШћоЄ;&ѕьн3#˜б:Їѕьћf+їFwж@Р•РПИЎq_aœ’cqЯП7оxЃ_я~Ž6+W­,=YКeыљ;qђ„,FЬ=oь‘=їнЏИiРАёЧПњЦžе­6ћнєрМ•™ё6§м–к!~ЌУ•йXџфZ•-ПлВћен™Э2ѓWф+ƒƒ‡nјэ†‚‘ЯZ ›JVЮUcЯо=~ЕAђПЁп Ю‰ф?уОwм>}яkRщЁї‰qС!cO_žF8“‰П˜8vєиНоЛ{зюŽч_Аф‘%ЪЇ­ЁЙЦpЁБ?ЩюХв_.щбН‡rї”ЉЦ~[јБ}ЧЖ™гŒKцђx`кL9ГЊЬМ ФrцДЉсqY3ЇLUЃ >8ќэo'Ѓyф#rxm§Sf*Ј4ЖПИ]ѕлnщЙEЗ w^ЌsCR2^ЕЋn/ ЃПЌT6xйьeу7B‡‡Иѕ+i8n„ЎЋ3‰Ю­ІЇ:zMЫЈ.]zЭ›;OvЧыoЕmжЎ^{фЏЦkѓЅ­ЛO?YдzaЊ@вѕ’~еиB8/*ŸЕѓq0V–Њa 222н8шЙЯЉQв>pєЫћ^YIй€№1Ц}їоWY^Љlм•т–A !*KИŠг_ШЛАЃЅМБЮœQ§ц>уыћЌœ~oнКЕМFŒёеuї]wЋХїэWоjоІgxНM?ѓ‡MF VYтpЪф)л^2|ЭЧнџQЧХ­jУF§?GЎ&„Ѓп2ъ–їУ'хФ]цџЩ,љЂDєOJ›=sЖc€ч7<пЉs'9‡‘б/Ч\%г%Ч•™йp3ђ­[з TЃіюл{э5зЊE9Cn§S§оA•Y}ЃЋёkИН4Ќ§ВёЋмњ•47ТXZ4Ќ§шУ^аЎэЂЙsКїь>`№€•+QЧЏ›^иєРŒŒWGѓŒЩSяRўн^˜1Оф•Ÿx4ТћЌKЭ}ж‘#F>ѓь3†0ЫЃ* э‘?ў‰4П8§Х''?йќќKВџЬœї№МАOˆ#]—|Њъ8 ”йВUљщSжїtUDј=:ЫєаКu–ёц^э-KГТэŒ№TытWЦŽp$ЈŒrЎ Ь†мS3№U\Ee• TГжЛURcН ЕеyfШЩцъrTў+YВњWП‘ƒЁпЬœ>cVЯЋЋЯWG —ЏXў~сћВ+c8ДdЎœ› 5‘b}иЏ1;k—гъдg%ІІJЃeN+›•›бЊФrЈFНЙчЭiSЇЉEЗFэ эмЬънЭOMН6f™qг‰лKУш—нЃАНБёWuыWвpмНƒ=1—)ЁЧ› тN>\№дяž~ЯєUЫ•EkЅж`іf5ЂК_ђV/э˜“7|TG7/Н™ŸШ0іYЋ*лŸ—sщЗПНѓе§zї’чЋ.ПЪœ VпјЦŒлЇЬ“&ЗŒ,Јšc,x?$+h(Њx\з§К­Џь1lDtbђюYќYINј(­$ќцЎМЉ†9ЪmБі№vЪЬжh™гnыЏзYї$lбЙЙѕШ‹LuГQ§ЪR5ЬUцbюE.2юшоw`п§sющХ—ЌkЭінїм=}кєn]ЛЩ—zЪ—BєИЎ‡rekhЌб ­ёy`џA‹—/ž3ћё9wљbYД9w3їЏ0ёчЏ0GUž §эowКєr›“шE+AoВьЦе6­WєкC—ъЕ‘ˆ 5•ЪлKУш?U’>?!/5ж­_Xf3ЈЧ@гЬуЙОešЎrкчNљ)§ћFЖфv9эдЋиЫЦD-*у№;†УKоъФЃ]ЏфUєЕПiРьђЃQП^ћы^Н{§nУoЇЭМзьќv‡—цУМ™E9ЉюŽњ_nИ‹ъЃБhаѕюЈœ8aт3OЎнКmkљ™rЙwWюQŸuџ,3­>с7w9=%y——Хиг5-хlсбх+<пІ‡6wб\ѓ]ЏшX‘\ЂЋo xиKEХEТ$r,C>ФRєYЭ{WTTШЗ>ƒС’S%K^т‘Frжh&<љі -ЮmлhžќЕ=З­,к q3˜0~B‹s‚§х ўёШЮ—uќFxWsпС}п§nы]юж‹твVЮ;_йQЪ№йй“Члƒ*ГzEWЃткp{iHџŠхел|ѕndтж_g’ XЇgЋСSю[RфЅ*%ЇKж<ОцпЏŒм .'Щ/]\~Кшџ№м‡#™™џxўШQ#%ЦјqуНГЧ—МэUу’nэю˜“7†Й1ЌvyѓЈ›чЮŸћ_+џKYіызяфЇŸ :XvФ{єю1G>шЈœTŠњ_ЎжEѕб˜ œ•;`rБѓKKJJ?/~~\dвcИќіЂќp“ЙэaПU]Кw1Ѕ.~!Ђ=Ы=Ј#†;\ˆЖlК=[7?—<П/ОrUО(MЈЊrоќЙœСфIS†"ЧЃэлчz–ƒђі6u_нн6ВІ р№ЛMРFRєЉёэu›ŸнlKЩ­пfНXп‰-h|Щ'>љhріžЊаs›ЗŽљQŠПНиЋfЙq†>Yитмі'l=§Oz,юяэОDї%hуfКщŽnгІЭr@SU!ч$Г5€|ыjТЪ‰ŽkшИm$љЏ™pЫO*ЋBВ+гЇWŸ@u Зў:n№@Уsuє:Ѓh3аQЃ+хqQ\ХДіб0oРя/ъЄьЫvяKPдš”ЏсУFШ_RnќИmpєјm$Вc1xдHsЗц'cЂЙѕз‰ЎСХГŠ^g]#jtЅЋ:ќ@ 1Іт‰ииБђнIuСx45yCђф/:kЗўhK[Oƒкќ$`1Х_ђ\OР6”в!ЄтВйЅл–—†%Їєv—твd#iвe&gђ’4”@ƒ>iжа`ŒKZ[7oЭЭЭuћКНЄM;yыдщђ‹/ЮŒЩ“™@щ@ !ЧтђЫщ€ЦZc0иљЇT~ƒssC.B[бюкХјОдоNЄР&§ZHЮфОЗ'h|š’r4eО“ФЮЂ~*ОџР>q-ŸGŠ=–HђђыpбХщS/•j!Р;ЊŒЉсdчЎRHН„М~*^TT”<)N9ЃŠ#РU‰›PЪ@" \мстЃ…GыЅт\Oф €  “*Ў“&О @‰$€Š'’6Б @:  т:iт € HЈx"i €  “@§юQїˆ,B“;и= X@€€hРчТнИщQqSТіѓn™б@HIђпRWН>QцЦAЯu9 GТнг@АХдuіZŠ[“Ѓ @€@b т‰сL@€€~ЈИ~Іx„ $†*žЮD ш'€ŠыgŠG@€@b т‰сL@€€~ЈИ~Іx„ $†€?*оЉK——WPpxРр!одZеhpИДЈђІVАŽVƒЦЗнBИѕЛEЌЏН›еЏнЁђмдБМв›\ё›ю‚ƒ‡{пtcќќ79дщ“А?*оОЫW,ŸuяЌ‚у$–БМbЁфmCo>_›Т„іJoќ,$ƒ‡хЋ–/]Ад|cL№V‘рpЩ@;Љrаѓ Ќn%9Юn#ј§ЃїькЭ-ЂЦўFцЉ1“Іы †кчN^SVЊжЖіXmixX6xUТ^щ Ы0ъ•˜ръкљrsHМЗ [эёW/ih_WГk›ѕЦ€ўЊтЋРйqРX@  р•^ЏI2pёHKОQпЖmы€aCК_нeєилŠ*јkWЏщнџЦю={н7w^eeHѕ› й†<›Рзљ‹—іОЁ—ќIC]N–C‡ ).ŽќлЮ?э4ЧJє›QЬ‰хœэзЁљ цIЊr9j§яŸŽЄdЫрыРЪUљRQяўН6ўојњ{ус”ŒtЖ„Бєь2zЬ(Й.(Y §‘ЂI5FГSЇJюМwVїzI†“fL///ЧGq„odЅЪЉN5ŸК‘ddІdО„ƒщD=ЧШPйЛ5 `”T%ыИaЭКнy§†ян№р‚Efўыз=}№У#[6<Л{зŽЬ` eО­.ѓр^žЭЦЪЧѓK??Бхљ­ђwтѓВhГW‹Ž–зѕКю№СУbS~К|і’‡Ь†}KПh6Г]љјšв/C;ЖmнђЛg:bb.Ў§Эš#=&НєќŽ“ŸŸ4;“‰:АgнšеЛwН~г€уЇN~ѕWV?ЖZ(ндя†?hкШѓžЬ&NŸ:vфЈН;wьўгŽŽч_АdхŠšсN№WЎ]Sњy™YŽјWЦ3fнЧэ?пћЦu­>єў‡ЊпlФЮа6аЖx№РAС(б%ЩФ\[чі fneК•ужяЫЭоЬ0Ѓyж ћ>З­fЇчЙЭ/ 8(ЃyаЭЁ <јо‘ O­+x+ro‡cэŽuйЖ3ѕЫVЁŒЅсЕ:m!jltЎЋSЎмвˆЁ†ИНю<€;О~=ь­уDИyѓо~ЬЂъ§.5;V\fлєьЦJСŒn4 vхФc3pœ5FcјІтsюššе2+##xЫЈяПW`ж№Ь ›fЮˆєOЙ}ъЖ—wyзЖ}ЧЖ™гff…L›Й}ЧЫnіŽ–нЛ_ПчаAВuч ™Э2wю4Чк#§6?ŽйJИ™гІšбgN™jb.nzaћ3f•6Nž4ХьtLЦ\uї]3[ЗЬ,#†јъППВ.О(BI,­§nfЯЏпаIЎ“”аЦOxу/o˜!фйЙœЗ[a*уЬЬЬ’/фHОМuыœй3gЈ~Г;Cл@лЂ -э/n7зЦВ=И•)N”Oй6T8З~ЗXnіЪсШ#Ÿљэ&ЕјЬ6I,К9”UwO165Dхi­н­.5*КЫVaхБ:n!жБЖЖ‡+ЧъЌУ=ЦZЭTлэuчмБ{ыХ8nоъм~ЄЎњОK8–ЃјXnЌЌ6ЖvjW<І2іœ•71ˆяuq$ф Ц\+ŠѕUUФ№єЇЧў`XЭЈКВ;^ђEыѓrL{iœ.9^3ЖvЫбВ[чЫ.Z(†/nнОtоC§цзƒхНѓЮsю™S{tР1лу%ЧEиLK•†m aSЁZх˜ŒЙVНЙ щБ.*JЖ~лЂ2+8R(wљО_јОШМсмгЕœъT­9ЏxdЩъ_§fхЊ•-О™9}ЦЌžWзКЕ0v†FюQjcймЪД’WЮ%О[П[,7{UJћіЙ—vјіЮWwїынkчЋ;ЏКќ*sЋps(eЏN —†JЯZЛ[]жЖЖuk‘UжEЕUX‡xl‡Ž[ˆuЌ­эсЪБ:ыpБV3е6fФщuчмБ{ыХ8nоъм~Є.ЋЅLз77Чrд@kУ•еЦжn@эЪƒЧTЦžГђF#F–ЗіGФгЌeNЛП^gнŒМЃЕЫiuъГѓmB-sZЙй;ZŠR~Л}лз^н fvНКлck{э­нвc*Ј›+еoј€СhЪтt:з]ьЌbgеD-9ЃоD'ŽД!@Tœ€ аT  тMuцШ€ €ŠГ @€š*TМЉЮyC€PqЖ@€@S%їOšЩOhщљкчІЪ˜М!@ - фццЪя,ФЕєјЊИ)сwИ8Ў5р€ „фыT%ЋИ y|U\ŽТEТћt§ЉБ$„NJ€ -кЗЯнЙkG\UœытZf '€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€Д@ХЕ`Ф  @РЈИа @аBз‚'€  т>@'$ @@ T\ Fœ@€| €Šћ€ -Pq-q@№*юtBB€ДhІХ‹›“мммЃ…GлЗЯu3 € Њvюк!:зътЋт]Лt“ьЅŒИж€s@€@ 7u0~ЙХWХ%o) о5Фž!@ЩL€ытЩ<;ф@№"€Š{бa @ ™  тЩ<;ф@№"€Š{бa @ ™  тЩ<;ф@№"€Š{бa @ ™  тЩ<;ф@№"€Š{бa @ ™ Ф§[_’Йxrƒ Gх“ IDATd АџРОЂЂЂdШDoЉ№нmz‰р €RŒ€)с“Ім™buI9Ћђ—Щs\ПР”cёдлlЈ€@S" Gсу6ЙќLySJ:Ж\‡пmzЗЎн4ћесŽ]ё‘nDяы~ШaИЦ#ёN—uВ…,pi3ЈЌ52аЭвц0жХјяš№ ЌБЮvB@d,о>ўјуn$<Ёы,­ЮЃџdHВЮ*0€@:1ЖўЅpЩ‰Sq9|мЖmы€aCК_нeєилŠšXхгPЃЧŒ’NY%ŠѕкеkzїПБ{Я^їЭWYйK'7=7`№NWw‘ЖЫГйPЭ†tЎџ§гНo2<Ь_uлЫЛ†ЛЇLЭЪЪR‹™гfŠЅ<ЄБ§ХэЪвъaћŽmЪь1лёВ23nb9sкдАћЌ™SІкF™‹ŽЅmzaћ3fš'OšЂZГRвPщйЊАкдЋ-Zuтdйsž“П'OЌљeџцаСе­оњвЫз~ЏЯЂe‘н,хќѕ7^—Ж<› i{Лzъ7O=ЗщЙВЯЫЌ!”7ЧБб!L{ЧўƒNй>Нўщ#§@BЫGTƒСрkŸPUcСМуЦŽлёђы+[q№Нƒfџгызћф˜ |vуVЩYЫоеъ5OEŸK—шЖ“T~h@ … єИЎGєŸПѕvКВ“ѕЯLF„@НЃ>0у3д=Ё*žб<ЂО"ф_ЩžNјБт‘%ВO4xдШЁУ†Між>ГѓєЇЧў`˜yвИGŸ>_œў"bˆўЉЖwЃѕy9І4N—WЦVЧKОp33эн Ž——нх_9З6K3V'f5ЖfeэWЦЖ*Ќ6ѕjПќвЖЉПˆьHухлдpcћn••Ь9jd,ЗxxИšой’Н[ЫcЌВёn8fЛ§…эSqYХФ wYіџ”7йЛ*+/“ЧœV9wпuЗйП§Х0)ПyЦ„л'(уЉwЌдЂjдY ВЄ”' іьUЅб=j•{CN?ыњ“Cъж?гsјэW^ЮF”ж­ЭзЕQ’В5Дeт^Џž5rФчG‡‹:,[ДP’ЋШsцмџЧ_’vЫœv;~НЮMиbЬјдg%ІJC:Žj—гЊЖY+›™›бЊФrё`e.:–ж.ЇŠш8ЪжЉŒЅсV…mˆmбv‡шёг_фVяFHCvS”AVѓШEє`Г 9wЄњ­­Ўrs"Л8ЖЪ•ЧXke/ [ПcЖђ*6bXЭЈfіQВjЩќyПyъ7kWЏЭќfцЌъћс…ƒТR3<ШiUKТUn*ЋкH1Вл6ѕoМохКf™вЎЉWЮНЧјЈ>Д‹бМ3'oЦлoq.”YtЃŽБ­Žџв%єXмБhЙy­ИИШИ­Ќ*PQЭёц‘Уц-škЊcёБ"БqлЊх7Š?s§IкХљ+Œ3ѕхх‹—/xг@Gћ’ЕІй\1ы?Шfцfю_a”@ЖQцЂciУ~0pювХхЇЫ+Я„ф67ЧжNЧ*М З7кВЋfљkзВUII‰й# YŒЌЕYкMЕ;=\е ‘SЂiЈ!ЕCЫ’Е(Е(Џв—_м~`яы‘?y7QЊ.эА№с…/§qЫЌгя_ИР4н2•sЭ—(в­Œ †Њ@›}uФ‡є@ 58mъђЂ“nуйZЃtХђјZлaИDЫУёPz`џ>ђŽzЊМ\ўф _™Љ†МЕ~Vф8ЖaF*q~јЏтНЏПfъŒ™нЏыВ|хЃK>dж;цц[:_йљж)хоѕ{юŸйћњоŽЦп:aԘ[мnею|eЧС?йP^‹ььЩуkЮ‘Z]MО}B‹sліš'mЯm+‹жЕвv3˜0~B‹s‚т\BtОЌу7dЋz8–6~ь„Ž^ Wn:ИM›6QƒьŽUx^Ы…‘˜Йпyю3pPxЯ ВММRВXm`ГД-Уe/њTN<дэjEўjё/+ђW ь?\ Q˜гˆФВ…зYіЩvи‡ЩNRI‰ќФaАшo%ѓцЫНuV3Ѓ-EХ%ЊpПБуh4ў`јтх+ЪПЈ })wџЩНц(Еp,0*Iг ЯHіЪW^кŠ•W.ЕfnŸ<'(_э>ђЧ#ЏщrMtZcnpۘ[dhєЊЄэ9+wРфcч—–””~^ќќИо‰ЪЇЁњѕэ}™Pњ‡с=6СkEкню]зž‰œK˜8mъ7mжюЙ‘Uѓ5(/иL^T5PU(џ—љ[_к*]y7цMљ)ІA—ю]ТЏРˆЅmбь•{ЧжЌ[ѓеeZzИ’[џж>ГОт*ђОпwЦ]sŒ}ѓкБж4д [h[zжХЇ7<Нщ›фжŠѓ.М№чcоы{Н”ГБћ•џЕцЩП§ѕТ /œ>ЙњfЊљчoлnм%0~мјУэйъжК(§Žк’4Уё д#ћošЮl­K фjЬ­уЫПLСп—гЬ[7;ыЃЃn>ZxДN=њda‹sлŸ8Аѕє?>AХўњ’ѓсЦNUUЮ›?ї‚ѓ/АоpоpЇЕGЦCХkGˆЫ’MќтУWЇ)_ Џt оФEХЫSQХ!љmVGUжЅтQ‡HM`ћI–х|ИœЏЈЊш{}_9Сž,iEчћн%бcмуKаgл€)_`˜0$}ˆt№ˆeКЋoіŠХЖa6)Ћт 8.ЛWŽ{X › ЧQ ЈТ1.€Дˆ|юE‹Џ&ш$ђЕЃёЬYžе‰eOWЙ]Жіп.Xе&'ИђћƒŠgЧБб!ЬћГПАWЗЋrЎшЖОU›Ueg+–9„~rMоМ_;ЋљВюНжwяйYyфс^—џ{– МшЂЕmО•­jяо-ЇS—ЕЊdе}/{ŽI*{HOжCˆє$€ЊѕЈИмLo~Д?ЂОЌ/ЄсУ;L™Кѓ'BђїГI;‡џшrхэЇv—9ZД`_ЇЫьЧтЪL5<\Љв>Ќ&D,c•wУ1лёЗ^.E}\vІ,4§ЎУ‡tˆv кЖЫЪ§Зl1ЛхцШ'[Цќ(2№џMžTѓq—ЩПxM@E;ЉГРш!є@ X!вА|’E1u}Ž\Я'ЭЬO фsцу*y!)!Яiёсћef2~T–гВц‡DРЬ~ђ@ л…‡ЋZ!Zз„P<Ц*я†cЖтіШ{уМѕмМћzЩЉђђђаєЏmzжИ™N>л&4ЂЪnMtЇєдY у(:!nфЧќМ8ъ`›zŸ#снкмe‘OћЙ€ёГл|х( —TJNU^ђяйІ]rQvЩщЪччсЊЮcœY\p“^гѓžзJњ}пјJШa?Мxеc§L/љЌRh(mЎ3‡: ЌгHra~^œяŽпtы9ЃПќ№мxж“Z7цЏшїЏmƒђ' YŒнyЙБ ь=\х/ЋБЌпЦпVCTУcЌВБ6lЁ­ЋЌэЕOю[ћЋ~—\œ-wЋuю’#7ИYзšэч6хuО2ЧМч.XНЛўї‡ŸXе/ї;йџњЏAЙЭ-z”­ЧБР“ДЙb)LРz‘Тeњ[*ю/џDDЗОfоНћdIшяM’?iШbьЌќЯ}‡іŽSї`{ИњЫ›EН7ўяЧ&••‡fоЛ/:„ЧиhcщБ…vД‘Юйsіэ}Гше?љч™;7<•Зсћ(к^ИљybА№сžЃo‹ќкл]їь.њhќЩOЯЂ[ƒ:c’V?Д!P'yХЉ]ЦЩf`=„HЖмR&ŸГrLю1v~iIIщчХЯsИШZЊœЁэзЗVV–Е“vвљ’Y9эŸЖ yМГ•wœш›Ку4‘ўSОРDТ$VТллYџќч?›шЫъdбѓЈЮJ1‡­ѓФа' [œлўФ­Їџё ЧтЉПх$RТSŸ&BРg%BоєО˜cёl,Јx ћ‚’Я@xш а…œC3_‡TМ@)А:С/Є&zо/і‰NљcGe‚ 49!ч"[*žШ>‡0_HDm\Hѓл ч#ЅF'нїЈ›^чеSjšB1БПrо?є~пы#оx=ЈSТТšdrт— Лv1$\uB0Эќlcяp Ю“К„ПјЅЉžHGl›љцlў˜mU}ѕœQ—Ѓp&ЉОш“ЪўЋŠЏbљ3sNў$“?Cgш &`›ЯœKo0Цф(ŠЉыьЕO4dтM фГтёуЦŸсљччž?цж1хЇЫХ^ŽъЬgiXлЪеВЅЫ:^жQ†L™:ЅђLфgаФђЩ_=i\M?Я~5нtbњ\џлѕз^sељЙ­іяSxФјbѓ†…Аr,ФHИ*А`бЩЖу%%=Ѓ'ќp,ЁzeјЧUћя›бё’ѓхяўћючцC’ёЎK фaWVVЮИs†0ПЊsЧ'ŸxRѕЋ†ђЉVАŽ•šcхйlШ@е$cЯйŒШs’hŠЇа“i*Ѕ‡ŠЇвlж]Ыш1ЗMœ0ёшћG~pДу…чЯ-cЬ“Бђl>Ьi›юVхЏ:xшрЋ~U†ƒСљKцЋ0‡о=єЪЎWN}цu |яоНЯoљубТПп”їУiїLГ…‹=„™ЪаБёЖ,й‘HЖ‡о>tђг“uњ7 м.XКрФёoНљЎќ;~L•Нw]Šžи?ђш#Ѕ_–ОћіЛЏМњжžН{”†ЌcЅ6VWѕЪй:v“ Рсx“˜ІD&ЉчзPјВћDЮYьБЬyЩiпоqˆ#^љн+МwDжЪ‘œk[VЩ‘є†пnnсDŽнПзчъwF†МWг:'кЙђ >њШќљ wёџіIXђ•96ЦЖQ*ЎЕ97АyгціЕKvѓЏq~ˆ7хспЏьКі‰Е"ф’эьYЦ ŽЗJm еX-9+o4 $'€Š'љiN/EўœйsZЗo=t№юпэюш}ђ/&їъзK.Лšk'§|RчюзŒњбѓПгњŽIwмиџFЧQѕъl|ЗBюœrЇмЕзћ†оrЩПЭЗкФ^‚уРЛІпетмWwЛBўкЖi+‹ѕ*г46œœгтŠЫЏјоuWwўnчodF|,_ЖќХ?О(ї < ћuЮs!Іn•кЊФДфЌМб€’œ€?wЗuъвЅрР†Ё‘‹џwЯž#з=<(џЊбАXM}”їнmMНКІ˜Пœф5zд›{оlŠЩ“3@€Ллм щКЛ­щ‹/_Б|жНГ<$м Y}ћe ОCА‡€#9ЗoœP?]>яСY0аб†N@ `ЙсИЃыт(„рї~мГkЗК"kXпШ<5d€‹T! п™|ѕuWW„*ђц5ьД|Њ @@3јЊИBgЖ/Й<[3мA ЎЦќdŒќХ5Ю!є$рлѕmлЖ6Єће]FН­ј˜ёХœцcэъ5НћпиНg/Й­ЗВ2Tнљп<И—чШQўзљ‹—іОЁ—ќI#№ЕЭмВшd9tиттШяАэќгNгZzЄ_к‘с†sЖ_‡ц/˜'ЉіОщЦѕПZй[Ђ$Ѕ•ЋђЅЂо§{mќ§s‘UN٘Зm cщйeє˜Qr€d5єGŠR$U ‹йЉS%Е2a€RŽ€o*ОчэƒжЌл§—зoјо .Xd‚]ПющƒйВсйнЛvdљ+ѓmРЭƒ{y6+Я/§ќФ–чЗЪп‰ЯOШЂЭ^-:Z^зыКУ‹\АœНф!sЇaпСУвЏš ЧlW>ОІєЫаŽm[Зќюйƒ‡ŒЏ3‹~Ќ§Эš#=&НєќŽ“ŸGОд1sьž{ж­YН{зы7 8~ъфWпxeѕcЋ…вM§nxpёƒЪ,fЇOUі4 @ % јІтsюššе2+##xЫЈяПW`Т}ц…M3gDњЇм>uлЫЛМЁoпБmцД™ђ-Zђx`кЬэ;^vГwДьо§њ=‡Ъ­;_Шl–ЙsЇq8~№ащЗљqЬVТЭœ65я?АпјuВъЯˆзiЏзРЏИzЋР Ф№MХK•oИ|}ЧЫц sуљ­:>Sо.ЇеЉЯ"WЅб2Ї•Ѓ[щtДЅќvћЖЏНК;ЬьzuЗ@UшЕЗvKЉ nЎTПсГњкГJC­5ђu˜бЋ“Б lќтнїмЛ“zpЩУKф;VcKф<Tё Є0фRё›х /Э5eЏјX‘мрц~`џA‹—/6ПлrюђХВшfяfyMk.єІМ›dрMnZИшQщqsbыћ\aF_œПТЖж\іƒs—.–ыю•gBr››йщ–ŒЃ‡wЪ7wЦ>і§CяїНОЏiяЃ”њОMЬGбЩа@РF ЙT|ЬЭЗtОВѓ­S&ЪНыїм?ГїѕНmщк'п>ЁХЙmћЭ“ПЖчЖ•E›ZtГье­Лœ‡язЛПXіыл_кНКѕRЃМЦOhqNАџ МС?йљВŽђубёc'tМ№‚СЃFо8tp›6‘/uK&zxczšs_ьУЯя9хЛ,!@ ёќљжФзяˆђљД‰гІўqгцxЊ—џшo`•AЙяўyЛўВ+№ПН{ЌZОJюМs;мTGЦЫ–.[ЛnmХџTф Щ{dс#Э3$ ЕшсEЋ[%п†{ЊіЋц/ZѕŸœUŒ6bщ‚Ѕ‘]„ЊР§ЬЌdј№aЗ<4ї!Г_ьЭXЊ!ПМВ`щ‚ѕЯЌ—Ц]wп5юЇу†.ПЦ6h`фtKЩg%иѓњ3KtJŽ™Пі—зœћрЧœw^Лщгf 9мm,ЭUђЌhЈ€@јV7Dщћ ЌnD|щ—“фrЊ\NЊЏШ_1№†>ОфPЏ ЃЧм6qТФЃя=њСQљељsŸв2ѕIžЭ‡й#mгѓЊќU|ѕЯЏЪљ=ДљKцЋˆ‡о=єЪЎWlnЎнГwЯ+ЛпzwпЛЅ'O,[ОЬьa>qќФ[oО+ЧŽ“EхЪжX–ПьШ‡G$шЁЗќдј„одiSхчC”й#+™tЧ$Ћ„›ЋЌ)ЙeўГI?ЛwцНŸ||ъљMмћі^s ЃБ AaQбi@HЩuF=I Фž†œ$—Sхr>?xNЖœ`} _–/џљхЎWw•_&§“cм:?Ы'y>ѓл'Ю_˜г:G†Ьž9{ћ UђГя›­юЂWfcЮsф(_ўц<Д№™gŸ1;7=ЛIЭў…-мє‡MЖQjё™п>#fаћю7. єьб3јЭрЖэлЄ-?“*…ŒЙеслаЌ)Йež™™yВфdЩщ’œѓr–Ъ—…nЦцZžцлг~“IDAT!$'Ў…6j^†!r‘иС‡ ц>4їРЛфSцFфцџГЂу]К[~Ц2DTж-§іэл›ЋкŸз^>@hЖхswާбNф,Н ДѕOћХДEsчШIѕЅЫ–NŸ2]vElВhMЩ-ѓuПZЗт—+,Yат›-?<ЏgјЖ>7ушє@H‹'Я\$"“['м*W—О{TЮџ§ипхЊs–пjW№^yVйxЎ} мmИ.›ЋŠ?+f[>wWЋ?'вэЄнЗкЩ@[п>}СЬe‹МНяэ1ЃФmіn™wъдiэ“kМwdёУ‹ЇўGфѓxnЦ6Ÿ,BH*ЈxRMGм“‘ŸЩЕm9Š•лмюšu—cМV-[ЩЯ`ЋUуnwпŒ; ѕ­ ~T8ejфш”ccомyцg№Єqѓ‡™6Уф“„вкјЮYїЯ’EЧБвyѓш›Х фTIх™JљYOe6mъДХЫWLŸ6=–Гn™K Fс=˜Šџ|ЯЭиFCeB€@2@Х“a—CўŠќ9ГчДnпzшр!нПлн1№ф_LюеЏ—К={вЯ'uю~ЭЈ 9џ;­я˜tЧ§oteыМІћ5пЛюъ+О{E‹ьwЮˆ|цM~”ГХЙ-Ўюv…ќЕmгжу7:яœrЇм|зћ†оW~їЪ6пŠ|BOB›/МфТс?ŒмUn j[tЫ\JИэжQчЗo-wЊ?ёјц(7c [!јK€OšљЫ?ОбЃ?iпxеоk>0VнЃыџёуЦљсѕy3]nёФ‰Ÿ4sЫ'ЭмШаŸВ6>ЛёиБcHxЪN0…Aѕ'`ЙсИўƒ„ућ Пsсъ'V'," $?ИЋјўћŠŠŠ’j$ wВkєfКŠ‡OэIтp$ gћSО377Зk—nq-3О*nJјХ.Žk 8w#pД№Јл*њ!$Œ@кЊ€љ&W!ЏŠЫQИL^пъяОNиC “@Ј2фx| $†€МЩёhкЊ@ћіЙ;wэhТ*ž˜­„(nЬM'mЯeЙaЁHœRNX-Щ(ОЧтЩYsњd•гО§ ъoBMŸЊЉ€@њр[_вgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR ЄT<}цšJ!@ е тЉ6Ѓд@щCOŸЙІR@H5ЈxЊЭ(ѕ@€@њ@ХгgЎЉ€R*žj3J=€ >Pёє™k*… T#€ŠЇкŒR џз^ ыпкВЮя|m)М ЈјлЃі @€@G@Х;_[J€o*ўіЈ= аPёЮз– @€Р›€ŠП=jtTМѓЕЅ №& тoкC€я|m)М ЈјлЃі @€@G@Х;_[J€o*ўіЈ= аPёЮз– @€Р›€ŠП=jtTМѓЕЅ №& тoкC€я|m)М hЗЌiЭxГ7IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/9-1.png0000644000175000017500000011164211733011756026320 0ustar sylvestresylvestre‰PNG  IHDRiљzК"РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН tUі?ўцOЮщŽјЕђ§%ˆ$В” рB* ЬHиLaBŒьВ!іe" †E"Ђ,Ѓ€ ВЩ’d1ЭЯДІћL8Пџ­~—ъZ:ЏЛ:еЮэSЇrп­ћЖЯЋ›ћоЋКuџд5§рўДh‚?Dа€@фЕоГi(Г"ˆљџDаŽ*’v БD-оˆ€7@‹ф БŒZ*R­Пo ьксxђ/_=љ§IньмЎstЫ(*р–0Э‚Šф[М P՘єж$§YќСbИ Кф–0+Їv $АE EV[)=Œ%№‡%ФS“%fЙФfЁEbP ш”ЋwP~Љœ„Dд‡ Ѕцл,›œУ.q)RaadˆŒlЬВ!б 7ƒПн ь•VыЖH=ъGд_ЂRРИЪC…†K@Ы…Я;Е‹xЌqDdЄЈ%9ˆEРпюёИHhPЊ” ДDFœd*D%iR,Рh.‹џ}%Z„† ˆ†џ !n‰”–Яп@‚2х—*8ЗН]џ1Л-њѕЖCXZЎўМ§§y’cзOIР‰чovлƒ3LzƒЪяёЛvѓ&иl(Е”‚J€bАKTC L›ЭВiыіфЁУ˜0c2TŒ2™0MТ™wjЧ2ј›ЧіАЁбЃ!ЃЉ—œй*T‡#d*l•!і$Э+&\S;– ч0  FCм6JльГ5zfW%I1Пqcaw­  €Ъœњ5‚‰1ТНЉЫ†"Pƒ Г5sБ™ъ†Их•ZёР*žкАXLJW3О{‰eCЈy< ?ЩŒЩ•~ЈёUФн^#Љ”ƒlDР€їшьoС еЬˆAмf}F‹Ф @"` oЃ‚ЊИш!{iе-aV Ў‘H ž#€S;ЯБУœˆC‰A"р9ЈHžc‡9†*ƒ DРsP‘<Чs" T$ˆ€ч "yŽцDЈH $Я@Eђ;Ь‰0P‘H ž# №Ўнщ3Ї*п-їМdЬ‰2р‘бБC'жCЉ"Q-<(žI  rvф ЏР2]’NэРЁЩQC" AдDSѓИYкЌaHLŸ(аћCŸr<рЬwG—[j0 іЪd2uƒшшЇЂй9пn—юнYАhСЗ'П%џ%Кt˜;g.ШS™ysц­\Гђю›ЭšEЯŸ;+ВЉ}RZNцdЮЩл›ќ?СЩIЩ I.Ъyянїж}МюІљfўљ|ЮЃ˜НЂќ[эИИЁнАHЖdг—‚-є1†cЃСHшdѕ@0YVRњ+)qCЭ+r—^юејчSЉэДС@ бЯяж/=–ђќ ƒЉО dU/дYŸУъ’тrl$EїЌcў~ЕЌœєыпЦXзј§їfуУТ†`DГхл:єШ˜‘№zBtѓhБОС­§LДpCУЯžwЬ[c2Іf,™ЗФfГ­YЛ|ст…™яeвBNœ<Бѕу­ёwгжMГвg}ќЩрЏXЙЂЄДфР—€ž>kК YU9чЮŸлКeЋ ŸхЊй…r№ЇбC,/Щ1шђ "Žлп0ЃЫ=c0>nћgБэD9o† ’ѕJ1)И'fЋАќKХЖЂп\hЏЈ~1D"рzQPPЧћЅЛе5Роƒх6$‰­T,ЎJ‘р‡ы>DZэ[„€%ОбTbћЖ‹YZEи—FuTs/ПДIУGчЭNямНѓЫ§_^‘Еиv_Й/Ÿo§<К­ l†К†бM=~ќ8+4§tS˜Щ`0 KіCХВjпћІŽŸ ZПї&ПЧ„]”3хэ) L%еВГrаŽ€\gфХZмАHџЎ•д3nRJ|Ÿп‹d…Нщ`{1pЫ’VАEж C™РQОџ$э˜БвBџёп*5€Х)Е‘OOF|sA˜œu­%ЎќЎ­јЉjx`ДZЫФ&ТЙЇКŒpя„Ттэб0CpеX‡џъъкёQбML{/ ’ ЌЮй+SА›ŸкчŸгЧЖ)јЕ4uбеОƒьЫxtрœЅ2ГˆŠlаxђИдБн*…EЙІМ3eТј =цw2д5кlж1ЪbByі\ #о)4‡7vяйУяиљœхЈeЕIї€!)ЭŸц М<gщ%ѕ'Nn(ЉC†Х‘R‹mяbьm 62˜ѓШ!4E(Еђ_)mœкцqХ‚!К}ЯzЫj[њIРа gbzШ"ЌhЌ–[жтbzYрK~*ўiS~1ТŸ`оHˆЩh В€iкzАрЇ›ЖФ7л@/ Эж:ЮYDŽMћ—AyКэг0Ї2п5oлД­ѕ3щПЌАz]-*hм@фПВВ2Ё—FcсsіЊlрАџlŒА :ј}zѕ\АVrвѓЋЙgБТ1ьоз‡^lAJ!ќгЏЧСЄёžЕ§эЋƒoч ООтЙњ?кЪџАоГ–о.БZ%­’Hгюj=aќ‡„‰рџ’‡я‚ТDд5РJ .Нз8eTTH]b„WЙmVEiьcП<ќхј!А7fдЋе:Ю|ZxтˆбУ‡uЈxбiFњŒЅ‹–vˆщ0fє˜ЖЯЈьІГfы(и~шзЗпП щкЁ+ЛТYŽZvV>D@жhЋє…g2kvіо6‚щ80Юbт~EШa.UКћF–ЕЄ}”еlI 3їэh!wЎ+Ÿк,ЗHX+Cдё$1(Lь С‰#’с+5aз€"ыЭzIш…Уу#Wm-ќK|”`ˆ1•nоVиЇНqєЫ EБЈ=м0юeсёпЯšЗ+)ˆXYм™кUTš“:иV’CіЋ`yы/ш$lЊAЃрѕ…&$В“АХVХ‹vвК?щЛuь—#OўpБs1СжHu„ЇЦ'Oь8l~џѕˆNQ‚Т"р6Š {)ž(d„])xЫє^М%[е'ЗN]цcŽ5ˆ“ Iо‚NПЪ]8xДЕОя'Ї~=5w}i9<8Ш`ЙSњюЦBXgm!ьАЋoй9‰‰Z€АЯХйQr*T,иЅoОњ=щ5WZI7Rh‡хZ$СЂMDЇ­я€ИЅ“рЕeщ>ШЎCъџThсxЎUjф[ТНЭ ФќЋ#šQІ’ђЊHвь ЉЂМŒx„€чЩЃъДf’kИбчlШщёB/­EcўZ‰€еfU{sEŽЧбЏР§&чЇ†)’Мдяz(П„D J`9СѓђЧO)а%E7њ*ADDР[hZ#yЋX"Pг@EЊщ#ˆэї P‘ќbА5Љ"СrŠ~fПІw лT+ &т<щЎ]ЕЃ.Uы`с€€dOЊHаCм €aЦ.шŒ€tjЇsѕX"(XЄРшіPC џђе“пŸTЛЪЩямЎstKЛЗЕ=ƒ)FgсBуA SЧN‘‘ ЏѓP-šєж$žB\Ш,ў`1\eКф/ŠDЕЈSї.šŽ—j9ЇŽхпCCАШu lhМbЇЬa ё›Жnї;E‚ш, E;_Ц" ˆ(|BБ(^•0iЙ"IФМ•є‹ф­ў`9ˆ€*МŒИД‘LT$~ЌPвPсуvЫЊP3ЗЫsoћ[тяэvm˜PИ,’ыЏџ(2и-ПD, пIє•A…ŽxybЇши'1;р”*їKEеRdU? М:рбф-???:ZјŽўѓ ч.ФНФћЅ.e‹$зœъ‡k@М‰€ъ@]Vђбърл‰#ЧЄŒ9qьФт…‹v™УqQY‘$9%і‡š,zf*З6{MNюјњnlllњ;S ђWuш№оДЉы6n"ќ|'|@KR”Є"L"U#Paj<СтЂŠ•ЫWжЈџѓЭŸA‹Кv4Ъ…Ај’{› 4'U83-ЪйАщм—woнvєаˆJД|ХrVЧЙ]оКqе"ЦDаŽ€<рŠœЃZ hЃЪ1ю­q+>XбЕKзьВеdОѓOY‘РnАУY^9ЕyOюдЩiІzؘњзДН‡1Й)Љi,Т0™ю1$7€Y›уА‡]qфЎСТЎКYЊГј‰яNЌ^Пк™ч*Ѕ<Еsїv‡ИХ}^TYЈTаЎJ>Rˆ€vœ­мЋŽѕ‚3ŸЈ‡`qн0Gд(ёx§Ч9gwЂ[оuё.Џж‹hx`§д— сEo сc/вн,.к‘2>eё\aƒЁџ+§“пL^ўбђЇл=Mїё\ф‚KЪS;зyр*D *,*`bC‡ ژ7›Я*МQ0cvЛ$!рŸ‡„ƒIDРА ёз7F&Žˆ‡Љcttдке+р‚Э$ ЇV{h‘’GŒŽO!щ$0qш0(uDъ˜у5{т‰QЩsЊˆ€рГЙ|р$™V4/КeЖ‘ а№S‘ЌШсјЋ Hђу04‡*+NЮKLž‰Щ9ьˆ€7рSoеЈ Hо*ЫAЊ—ІІЂJзB0ŸѓюЩЛxbiе€е+QXМоJ7Мо,Јбј‹E‚Џ„џcTѓЪЏIдhXБёе„@aсЮ’!Ц|ЖSX˘П(§0eЮЧkЕw K`јCАЈ}ќФяж/–ўЂHа^ќ0%я Ёœр3Z№ јt‰†2„Ќ№х(ŠтGŠФк„"P}аяў€hЌТПkЇБc˜рDt‰}F‹3K•bИkW%D(€T€ТдnХЪ‹ћўaЎ:+J Е>/FŒKБПCdAЊHT‹Ю9_‹!ТЎ#<п Б J~+a|JЌЭ^{љ_—woп}ђибр рХK–SўŠьЕ7Ў ќoіН}ћ60ЏйџУY ЊП_ўX…C?œОщќEHvIA•\Y$ДG €щЫКyЗи`2‰’wя3ЮдЩSbФЈЩ)уhЉРцЙйЋВMa‚@ълЉ§џмвдI@чюЬнŸ˜ЖѓЧЅMbЅ1‚R Я6ј'тбЯ•"yT fђ&aѕТ, НуiЙЌW/Œео œвсссwЭ7ŸBpƒWњT2+FТU|%)ЭT@ЋЙ , :ˆ‰‰Щћ2ж0ЌpHЖ‹‰aЩ;EwЈ.нЙsB0>%„р[ЖŠѕђF4yІ„’\Е6YXXѕŽЈ8.ЩS3ЇVђнE`ЬЈ1У“‡‡Bт^ŽƒМ\ЛnэЖOЖ k ћoСЂщ3гB0>|J 24cVЬњРўР]’Н>;гОK1шеAГчЭž;sЎбh\Гv9Ью !0ТO…‘‘‘ДфкvчћЋЈ\§сЫч&Т.‰ЋLЊFрЖојбЦЫМПє}ЈІCћ?Z-Ж$mŸiл?ОПАkзЗпИ1Žkл'ˆŒ;ТмрЏŽрЩIЩ+V.†Œ Щr%HOŒ#œWиќee,б8~r_SQЁЅA$Я™lм!†тO]г~žTљYЦ—ЧО9sыOzkRЉЅT,ŠtMA КCtў™ZЉ FШСЃ?Tцъљќ­‹Ў\њЩВ?W˜)РЯхі7СsBръЕЋАЊQMі‹Ц‚npк"аЅЈg„ЧnтŸыЉ‡От жaУ‡M~;еўDчškvu nY$Io]*[ЙJ2aв€gЏBыpьм#АHќКdЗHWФ5ИR$ДGbЄlјЕf€ u4p$“Еk$TЄZzп`З%hДHЊS;sБйzпщ‘“ЄbL"„@ЕЌ‘мzЪHhb_j-ё“gxз.Њw_8j-ІиёZˆ@ЕXЄъУБ№№ЁШžБеWОZЩnеkЌ˜№n_Ж$ЄnˆсaЛ3]N`Ц+ЎЂ_ъDqщš‹@u­‘Њ Ÿhє…П^ІEЫjЕ&ORƒBёгЕjТШїsа"q ЇEЪ[юd‚@‘ єСлhPрІ§шУ$Є.Љ_—$ЕдŒЋnЊ  Eт%N‹$1A“ЇN†вKЌ‚"…ж%ЁFA—B Ф`. ІHн„[Ф|[вz-y%EAвЛЅЩЫ$ŽF‹Єїs$А >AŸГ^f‚w’С;‰ѕžнц‘`P!Ѓ B!Fb2’“? p\ѕIАRo# б"щ­Hœ–Сл(ёЎ‘Ј" ЌPRrЏZ$Ј`ŽьКtВP0P№+ЙW&o'`Т™T`гВ%§ŸiйЋйуiЉЖћŽWЏN?6ВWЯ^ЭТКЗ;ИSpnQЬ+ЎђЖх€<фћJЯТkWйUyU–Цђ"€EвђіЗоŠФiМ>ДœѕJLе+˜ЮEЬ‘œЗkeНЇрЏE'upfГЛMЋV^>nуoђ.^де чаоeІМ™4qкЋwВ>люьI`ЪѓЪq8wќdvюўМKП<лoрМ‰уЉ€b<ЅЩЫЏЕЉbЃW/ќќм"ILа­џ6'Gp$­ј‰ќPЪЪ,R…\хп}[жemйe >щ8fъЬсНЛЄЮм]ƒƒƒK‹o[ŠЭ "Іd.ЊЬр’šњўУ#ТW†М‘œ=o6•UЋТeIxб k$Н ,ƒOt‰жЋvfˆJL${Ои“]ѕŒИYpsPч•y+ ЯXГс“хYkfџOш„9ž‹­”Љ иќй7ЊEpн`00_ Е**ŠСПU#€ЉjŒ@‚jЏк™?š™ џ8Ь.хlЩЁtЇ!‰ŒЩC4|Ќaію§д"‰хЃžŠž›Н8АXЪ|;mїщяХW)ЭєG~IЬQЋB,ƒДk4Z$\#9СKMX!Щ‘Йh‰ЙР,ПšсuЇ<В|ŒЮќK!c•Д`кDsQ!|Ж`П^Ђ№†Р ЫГDI^VˆkB­ ЯJs]W ^E‹Ф5ВœѓЩU*MаЉmєхсoрУПB50+ƒ›>ˆdŒINЗХКSЦ ‹ыŸуЁі$ўM!ђuкkюнlа,:)ЭБC№BЏощI зЏ_ЂEєћ+WгЂ$yЫ—3еЊ№Ќ4yљЕЃб")EшЪ—WvО]#ёw ЬŽt~іwтЧ ядЕ{яOпЯўv.žЗоў–|EўЧъњуД ^o“[ѕ‚СqЌуљLз[‹ъ€F‹ЄЗ"е‹ФІmh‚єПЁ}U#Ў‘ИwЫ"‰K]r‘Ф™žœMЃEт>Я,!ъ И!Єб"щН§эБeа8XОЊWcГ1Лn€EвђЎЎ‘FŠљіЁ‡Ќ:Ъвh‘єV$_Yўz™С ЯgЕ{ШТk>œ/(ш-Z3К…k$Ўqт\#щщ!‹ Ц5rz ЁEтBšг"ILPЕzШVЋ™B-хК-DB-’о› `DзфЌ кi@Y§ЦЦ?jвh‘єV$NЫрul9ыЅŠфuYEЗVц"!w••w„ Iє•УхGуЎоŠФi<ТuЮzЋУCІшжЪ,w•e—Ф„b!ш+†H ­б"сЎјес! (КЕВŠ9]e AпXЃFBуIoEЫР9Ывˆ‹$;­WэЬ„щдŽ}Є’к=dЁpEЗVVЉЂЋ,›јБ= ХBа7–СЈ‘@‹Ф е^Е3+Ђ:‡H^–п-O[П|СВ.BIќ!ќн"Asmєkє’†W•ŒœЛ‰‹ѕФХЏ\3Nw^JUШŸљцлМKы„€\„˜1uянŽŠ‹‚cщŽ kсuяn}ћMЛиPWƒiлдљѓ6ЏZ ю aсaлŽ~ЧœlП[†єшœž-š;ŒвВfaцоЯrрCс‰&ХП‘D W,м`?œ=Ћшпљѕ4L?=nр`ж$ќIŸ];?,?ЊB–I–RqZ] pŸЭѕЄЖюв!kњ$ШfsФ?fŠŽЅєъЙГчГПњT%Жџр=[+Эзž­9}_KdzТ›>XrуЧЫ|ГэфљRѓmš]­dN7XжB$tF X$ј‡НчƒХb\^}KVCоЏ IDATaЯ@,Дэ~ЉСZ*еИPmE `г‘.•$™эЩљЋ7o[Нbю”З‹ў§яzсѕzО:hxЪ8Њ .KгfЬѓє9zЪыт“’иН$wгf˜%ŠыйЗmsж6GpибггWЕ’9н`Хх#­'-’NлпŠš#їWuюш’•”лCйA3ЉкА3ˆвЖ—‡8х%`Ж6lќD8€БёvЏ]>;5eю†HКp,e1*#›D6mеъи—{Лїщ чvкУZKT<ЙљыЭˆвнBЕ’н`ХЅ!э[j‚ERYчШ§UХPZѕw.УЧNХL)m4S})S) Zёfњœ~­žЄ9KоГ~щ|PЄ-Џš6g™Є`(ZF4rв%Е’н`%bв‡hДHњЌ‘<ТЧ!h‘Ѕ„XŠь#hЮ%фžеZзЩJˆk?t№БЏіZю л{–;це чДюрˆ.ЎцX*Юt›˜ю%џБцmЩ }84Вe”фjŸ!CГfN‡’aŸ}ЭМLzU­d-nА’z1YјЛE‚чE{ВHрWи1Бо+qˆ•лM›у \Ћбъb[oTъд]›ВOœ\ќ{1Šv/іœЕj-MЭБдQ—шЯаПŽ§іп>ќ4WФsУоšЛvУ{=гЮф)ŽUŸZЩZм`хU#ЧыhДH~ъ!kLћ“щээ$Й}‰<А/“фШе &ѕ[‘ш–ПЧ+>•ч@"рРєЕ†?iŒ~ЩиД-ЁЖH@цu &П‚DР]4Z$КѓхnЅžЫг:žќЖщm`яЛЪзxŠBD Jќ}$щчлп8U“р†ЩъF@ЃEв{з§‘Њћ†Рђ=C@ЃEв[‘8-’gX`.DРcР"еYДfп%˜БJ4Z$Н7ДX$ўМш][х}ƒ4Ў‘єV$ў];I?!Щ›зНkхBŽŸ ШЩ‡оЕ‚оо(ќdqЦйуЧСgЉYыжЏЇŒяо;жнQGПtwѓ•| [$zзš)L2 yђ„ДyKLuMW/чo]•х"љъЖРzнE -`СМkї,Э|UЩe]/эоЕўО(95ЅпDZ>МЛОr-Ѕ%F†%х>Аp Ва3sЊ]ž>9oїvрїы?,5у}Сй‰zцў}щцхо-*jаЌйє…ѓ 6џ}iQСѕfOFOЫZй\њЪЌ оC@ЃEв{ћл§7цZ ˜‰i—jіЎ=~єPОюyƒЫ}`ЉђРйЁEDpMПuћжіЃрИuћЦšЅŽwЦЁ3чŽ|“ћyоЅ+}—т№‘Ќ­ќхХчН3оeoёЂаh‘єV$ў76р]Лt1tрлWеМkЩ§R8KKЉ ргГ­T­ЄbsБЩdRЛЊШчё=М37mж\S=@@’%Ь!У#р ЏŽHўуї?воŸУ’љЇO31$Њ РŽоЕдС–%ЕlтГОр]kБ’тсЗ%vО_‘ЄФ=ЇLтDXD˜Хто‹~р{тШ7рU‘а§йSG‰KcєMѓMцоЕрcЫ.QџvHВЏЕаKB’у+ Яt‹^IєxD4ЕlтГ>№Ў%‚Њ” GБьL™рЧЄъ]г#ішоѕн}ўђ„љ 2'Ma|1б0Ђ!lcPxзBR|i"ј‰‚ћjŠУsŽ kЭоЕ#оžМvљвƒлvРWИ@Џў+?#%™V§LЧmЏ]пиЌwgВі(њР†е cš’=Ъš•NЛpdЭšI– п" б"щ§@ж­5’НkaЖ|л.xŽД"унВ2Чs$:вг,›7q|іМй 7š:сРіЯ(_б61eмАИАцЁћ У'LЪژџЌр;(’ОН{Аv†€Ц];?ѕeнœo6 w­4ЄљLYyџљ­zзЪбCŽk4Z$НЇvœVEБЯќyбЛV@dК@ зH’nsZ$єЎ•р†I4Z$НШв'?<“ЫhЩ+/ 9ˆ€IoEтД*т2ZK^Vˆ€"Ех9tо-‹д­зi8"Ы]b{@hвd#–п‰Б"IюУчХQEf­C-’ТƒкєJŽzm\Tѓ—O_ЬЗє|љtЏ‘QpDї;}хЊЅ$“…dЗ?Ÿ.(TˆwЁP"ВДHЪ#lН‘,)#?^БПХcЕЧ)#…іOпƒяŠ[сjA‘=Љ\rk-’олпZж9ќyП=аБ[їгX-/Нa|и›гfа ‹ќЧђ\ЯcaЩ—zЋ~€Ÿ:‰я#њj‚Z\ZЙ<фЅYЖМ.kжДДYѓXH?И$–‡зˆк?3fF& —˜лkcЊ5€–щ"ЃИFZ,v№ƒШC<д,ВYЛ^2&™НAЫ№„Ц];Н‰џY|фмЪЛeK›“ЇKС(=b2ЩЅ`„žlnOnlsф„рCб8R5P™ќІyЕИДL˜нёЌ§ЙызMПtѓЊХŠWYxяnЯ†ЕГўњЦЊ=ћX.5B­jђb>ЋQЬšђсэAѓOЛwlгѓ…Ќнћ%С $Y/‰IyL#Т =К іЧh"†:’НКI1ВјXHю'†ЎS{ХFCЮї|ŽˆыИДђІœ:r,44Дпы‰_l§\h;Хt—Ы€oЖиДbЙќ’œуnф%ЈqР_BзЄО;#$ФИaЩт)KЉI$_ЃEв{ћл­7Щ€Й•Мx"Т‰Љž E№3[›9/ЏˆШпjИw+ъЫЗ;}79Њ<пЉYRЋЄ‹ИДŠйvmЬ8r\˜,“–чэ–— чИn€ИLy^ЩUЕ™^DDDйн›ђьЭЉu‰к%љY<Ьл~šГИшog,_ц§А,uGЏ‹џЪБќД‡„5&'ЩЉТn^P0 idИхpГgЇ4мgтƒ2i\кO>№яŸnйeНW qiхy)gЯцMХwŠЛ5 ‡;Ю@яйМ– ГТџxmpЪИe3ЇГK.з `e2B\cRB|IL›Эцрz Хœк@kДHzOэјwофƒGѓЊ™ќі+ѓЪ~њ#јЗ‡`ЯЛЬі›ЅјЄ%К)К@ўБиіp(ЉпKŽ0Я&ЇАЌ‚ЦЅ=ѓэЗЪТШоЭ9Йgђйэ 4p?_чZіfЪпqfWЊЂU ,q 7'цХžЪз—‹Я‘Єc{Йќ!—ўoг'ЃƒСхџ>Дчмђыђ н“Hнњ‚E‚пoW#vМ!Эя2э".­$пС};ZwŽa9И tыіэ/‘„ээЋW6xВ™„Џ˜фo€bvLиЕ+М|‚сюлИyDZ­ѓ8дh‘єоўжn‘\м є’ЕмZнzђŸЪѓЫ‚ўh`jєbHыЦaMЉOыHŠoЫ b %uђ?Бk”RЁŠ+ qi%eь\Л~ддw$ЬУGЎ_В,юеСРgхУœ1нdЏgТьх€Mc—јРВ0B­XЯ‘zЈAгf1/М’§езА‘ШrеBу)=dЗ_^’[И ,Œт?Ъ,ЄщМе—РaџY›8ЉY­ОƒАѓvДXЄШШЦzOэ<ж"шЌ–МxЗ ЎРчHЪј ‡Ќ2.ШUA@‹E‚"г"Ё‡ЌЪн‚lUДX$иlа[‘јwоф=v+/zШЪдШ‘<ЯеXšПeзh‘єоlаВЮсЯ‹Вь6…ЛŸО!W'>‡‡Ќј V>QxэъGs2ЮœќЖоџдKš6=n №b‡П§ф‹]ДОJ/О › z+’–7ЗђЂ‡ЌxЄ)­І ”_MВŒcЪ№„”9 п[НЎДИtCжbџT$X“ОŠ 6шоЛяВЭв—PХ陇,јЩ‚‡ЌјЃЉ‡ьПјq\ю6РEQ’KЬCЖЯ№Ёр!+Й Ifг€€QєІeЏ/œ:оg‡р7BрTќЂё&MžоНg,”ИMYрпŽЗ№я~їс€@sіŸƒЧlОc_2с(~НЌќЋЗ"ЙЕЮЉlІr+/zШJауOђxШž;~bу?ОлўЯ ЅПнZГt x‚ФіМgkхџ”=[sњО–|ˆЦ[њ›ЙЧv uBJЌlќMђsЩ€}Г=dяџфЅŸ,ћsурr`юкЁ‡Ќ0ќјгl6Иѕ,H^є•@‡ЩъF зHzШVы}xѓ:эpщ­H`U8ї ф}г’=dхx"Ч[јРТc-‚>kЩы-ШАD@|ŽЄиOd"凈м(ДXўМЦяж‘O“€{eБЕїD'&я!ˆk$›ДШ4j­ё™N(ыЕ –УŒ_L’уf}Џ€дѓќ;њђ‘S;а[‘ј­ Œ‡мiёфї'ў‰QНж’›qJˆс‰ЎЦ–Фv…^5F†…G†і=HяВtелdvckжџ“ˆHЙ1kёёО[t=88ЌuчіоЃrO1;2k>x ыжЮ8-Ц‹^?aГ}iІ E1лѕц)вwК*Ю@IXY*„хŽyЬ ?ї2|Р­РrпrхмEЙ‡ŠЄXmgћЕE‚СБбї2йГ4ѓU%ЅRРШЙ›e‘E"rЗb,œюМ”ЊШЮZcЭ†GОоыљ„юЯž:rH1#2§š№fЌsшј‰hКћ'>‹ёЕыAUJ…ЃXvІL˜зечгDѕРЎЪOyˆ/Щщ† ^ ya0ын™т*=Lс#;…7 …џ0ѓќo™XiFРппl€чE{В $1Ž’я\Š/9hИmФzЏФ‘ЄХивHрZЦPс–UљС*%kїў +Їѕfnaѕр9RЬ‡;+?Хљ†O˜”•13ўYсы›Бƒт!IЏN[АlоФёйѓf7lмphъ„л?cЙ=L_ше;=)сњѕыOДˆ~хj&Œ„џ# їfƒ[Я‘рa‘јy‘yЫС…џыDџзЉкаs`Л€ъЎŒœcХЏД'Y/СЇao@О=п-XѕХ>vє’Шшј7’р`IJtяг “5НЩ­7$ђчЕ†?iŒ~ЩиД­jpЫ #Ьы@LR&№ї7$]тЗHЖщm`ялiu/) “ˆ€W@‹ЄіюœWqгT˜dfЈЉ,Ььдˆ7*qЂO*гH!~ƒ€олпќы9DZђЪKC"рEєV$-VEK^/B†E!|Ай ХЊ№чEYЩHcВКа{ГчMоsоМш!+Ч9剈ППйрCYц;јУk;Ÿ,Ю8{ќxйЪšЕn§zЪјюНc2O<§ЩУт1йЋчѕхг}9іЮ8МбОglкћsи ут,Hћ„іФ=пЮЧО=чю];ТљєЙгpюнЮђŸ_[$zШ2Єрэвд!’'OH›ЗФTзtѕrўжUYT‘@&иh„зД;='шќN>Jг3е(x/;sNжД‰щ+зŠЏ"эŸєэгB_вЖ Ё/ Ё/лЌЗ"ёЏshs}х!ЫР‚ЈЩЉ)ьэxA[Ќ `>§№#ІHы?\œiЃ^gй)ЎJiяЭьзIx~Ž@\lФЅьо­;ќЄtЧЖ…7˜•~>pЃpчMь+І•:Фxš=dYIЕGпС,)!Р4•ќпЂЋчѓёЬщВ’fЌ$’˜ lќн"љЪC–:„@5™žАŒ)&†ўuТ'ЋВРІ|CЧM_b48#СдЎ[Х ё‘№C#ФW‘ім}Žфяo6Hч…Вш0Щ@€Џ‘ўѕzШђп7(щєžкё[yї8ѓњП‡ЌМkШёА*wIK^+ХŒˆz+ЇUQlК–МŠ"№ јЭЏРˆ… КЛQhБ*ќyбCom=№СfџЮ›оМы! o§сs-љсНЗПљ­ŠЮМЦ)!†'К[FлZˆ12„,ц+nƒ[w0„|лјСтУ_ьЛYp=ь‘Аі11FiгEEЊхчVДT„yнE@oEтЕ*J§рЯkЛ~Т<ЅŸЄ q#1-ƒ$Л_=ЖГпJzДa“ЌЯ>hўO[П|СВ.;фu!'и7"чn"Ф"~[\aДъЯX8=Yс’Œe.*ЬšqцШ!ђ_всљnS­‡YВйlYщ3эоќ?С‰c'eЭœF•№Ь7пц]Zg0@"™wянVъІeKvlX 1вЛѕэ7uюbC]A ”vъќy›W­МYp3, Й›6П:ТЩrюлЖ™2zк з%—пЖ›až9%sk$^D@oErУЊШzIѓЊФНC– Жeќkƒ{Еx&`=›4*О[Lљ7Нб ’вŒ€$(ЩАёA§ќћч…[vYя•ЮNMqd)И9Јs(Ž>O5‡`Я”gа.JCDІІ­Zћr/$смЎS{а&„И^Ц‡9ЁbЩk6œ8ђЭ№^Я'tіЬNёW шНйРoUфЅyеЮbyяzШBЩщcGЄЬܘџќfаи‘ыйМ­ЎaDCX>QBмFƒVМ™>L“#Ыc Гwяg:УФ$DТcж/пНOп-Џš6g™фjУЧьѕ6rшАы’ЃžŠ† ы ‹ЅЬЗгvŸў^R&5"Иo6"„HЬ–b)ВŒ I8—{VžВbzi0 FhЫ‚щ“ю=ЪЮЬ€}98Вцd0ўјЁƒ}Е>…Ы3,„Zwш@Џ•Д`кDAыТkW3вRY.1б&І{ЩЌy[rBl%ОtŸ!CГfN‡’AЋaоHЏЊ• UоЊО]ё_TWR&Е"Pѓ,WсІБыН‡pЙ§єю$G­FchлzЂšf,YОtVњЭ‚зС Mp`ћgє"Ќ—ВІЯŒoћДАkїЗqgэЁќQЉSwmЪ^}^ўrј_Cќ§› ОŠ!ыpžГkЃЭПІ‹rтеВДфАˆ0‹ХBПyтT—=Aї0ЮЌ™šТбВFђСfƒ[ЛvТ€g‘в–#>‹ЅМю! …Чєˆ=К7OэЕ:Ж'!nв5ЩџзH…З=dЁ#оžМvљвƒлvŸ1y@Ўў+?#%йЃЦa&D@Ы њЃїдЮ-‹фW1d#E.пЖ ž#­Шx<Ящs$М#АM! Х"љ`ГС­5’cШвБLир3&ђ-o”ˆy4Ž˜ЩЧhY#Aг§к"I хЗfzzШJ‰ЩŠ€‹фƒЭЗ,’dHјѓъщ!+i$&k(h‘ЄЇГ‡ЌДzLзLДX$шqMкЕ‹T3Ч[]аВkчƒDђЏsфиkЩ+/ 9ˆ€IяЭўuŽИ“”ж!яХх\1Уыё№юuX—б–ћцmчЖuŽьзВ_Ю™œŸ‹y蘼LВХA„Ј0ј ДЌ‘jб78­™ЕміЯ_џЙцb–Емz№кСŸ ПaЙ1юЫПМ–ЗхтК[Ж›/цЌјnББмb{ №*Ÿылът™г™‚9/ЙЦЋ:# б"е–5чњ*.:qќ уcЃz ы˜њѓ§ѓ1­bцОДrћkЙУž бadЯV1ЗЌ7 хФ ‘c읭ژ5aўB|шф&l:‰kY#AѕV$NЫ žyы`ЮBЂТ#­ЄЄEƒ&fЫŽ‘н#ыE’КeГЮЅ^Кї§ˆЖ#ѓ‹Ў яЛљћї?tъыf&з -Щ› œ–A<=ђТšŽКef‹ЅEƒЖ_[rMѕЌЩgzќeGHX№ЌЎЫwі?Al`ŒŒuнёСАїчВ?peЅ8ВўРD‹Ф5 ќж ТЗ„˜B#LІО‘ёMТšNП\—t яўhиЃQІЈcЫ“lХцЦ Ђ Uп$й2}L2D%ыеьёщI‰4И ]С™л?^зџ™– ЖpъdЕ—мЙњ†Bо@@‹EђСfƒVE VЮzaЁБ!ђЙАPЦћ†б‘яН?ЄСјШКQЯ…НdЌcˆ,/щxzY›УsLEљJѕ<Х€ГtigЖF:wќФЦ|З§ŸJЛЕfщЕвЏh‘ИpцДHTТREŠу’Зф/8D ‹#ћеIЎ‘гћ–t47ЖьYfШtЏШprUШоwŒП›ыV 8+N›•n‚ТgfЭ=МsГф*&uF@‹E‚ІъНйРiAдž—– ?‹Ћ;pйVzпјЈ)Вфž1ѕ3’wЦlћЩмІUух=g7…‹Ј`вШpџБŠ32Z-р, јe8ˆ‘Vr“:# Х"љ`Гг2(‚Ј=/-A~fеЛLž4 ,фp1дh Ўk,Еkt’ЁјŠсШbвР№XSd$хіјe&ЇЎЌ8;pјШМГW`wјк/jћ{№}/šжTеeGТ' Eт‚гšнЖЈ0ђХj$F# "ћ LЛЮYШЏHШџ1tO"uы  ~П]иё†bнjg%Тs–Ÿ…XД’Ћ˜д-Щ› к­Šgјrзk3п'ЏidYдЖ@АM№…к6Я’ћVс)“Ѕ ’ц?hkтˆ*ihЇžБ[{Ц2fПз)Эіыh2ў$8˜ОE,R iU ЎЧ…pц{Š3ОЮоЃ{4Œ<A,–RгЙ]ЄiKBJI}iпњВ[ѓ~Vƒ oј ДX$l6pЎUЧFŸМM$дDšD !Э#Э]ЭmF {-*!G‘bАH%ТдЎм)bƒ‘YƒаВF‚nъ=ЕуД Š OоШp’кгЩдиšЧСЬЮјы вn˜Йл$УЋЖQVѕ7/aJІy’Ћ˜д-Щ› њXљ0hЉІpцЇњМžSаћ}k]“ЅIGZ$or|Ž€F‹ЄїY}ЌŠ|TДд+/ 9‡€‹hш=ЕЫрё=­C^є < сь‘–];l6xЌE‡yЋеCКРмcС9Ь(VнhДHzOэДЌUtШ[­Ве}+`љZаВFђСfƒVEMоzНч! юFн"УсЌи9“К*IЮ kсk§‚чRГЧЧОкчиWŽo’1ЩўOЕЬHK…Зфe"‡ДH\XёZ3X3Тс ймѕыІЮ_ gЎій? {тt[œpІkл>їќЦЃпИњѓјЙѓПоSМ”ŠС%c1kкDЮŠPL- д{jЧk”њЊO^эВаіSGŽ…††ТЫAp>uќ˜RoИx,p­&НqИі[ќz&ЂЊBZ,’6x-ƒRuШыYhћЎйGŽb`ђЈ]g+ѕ†‹‡kЙ`ђ†Z$.9­™WEйdяцœм3љ "hБ`Žо|хyСуШ§ЏcрZ64еMhБHа6Н7|k‘Њ эВїэhн9†iдtыіэ_eэr \+ЧЄš8Z,’6Д[ЯpфЎWЋ‡ьЮЕы !iф€с#/aђ$iркGОђl—^Q/›ўЮ Џ&№dDwаh‘єžкEтОЇЅPшWЛ‡ьЊ=ћЄэ&ЄгsБpŸ>&ra&C/aрZ9DеС‹фБ‡,l6ш­Hk`ЇC^є­Ž{ДF”Љб"сI:Ъш!+EЄvЄЕЌ‘!ДHвлDYi­˜і5Z,’6ќ|зNq4бCV–cjДHzOэtXч(А–z Df€! Х"љ`ГA‡7ХцЌ=dбЋ L-Лv€Z$Ї›=dрPJР{IJьJч_ХЋŒЉ– И&4fwQИ‹Хъ­H~ОFBYЗчЅъЛз9р™˜–5’6ДЌUєШ[‹=dНЅ’ЪžнжњчB‹Ф…9Џ%„Чp ‡,Ј%ЄХ"љРBЋЂ4Оќѕ˜‡ьІeKшїрЛЖћТ7ЭсNЛ#{ѕье,<Ё{Лƒ;…ЗiЉ9‚3ГKŠ‘pэЙ‰ышЗЌy-4{оЖЈjћJЯТkW)ЮŠM…шКc"эіяи’џЌL~-Vœ)РиlрД ŠаhЯKKŸХе’‡ьЭ‚›ƒ:w Ж>O5ЧuкгŒ5NљfxЏчК?{ъˆућ^b€v —3њ­Z-ј‹§КФт‚Њ5ЂыŠЋ“4в‹IЉvНkGmšќЬЦ#РZ$. ЙзWр!k€ВЅVЌ—.йcШЖ3SE Y‹=†l4і‡b Y№„5ѕI›РCv§’eqЏ пrыG=d?YœБ"у]ИГ›Еn§zŠcuЮSNќ›) –ік€ЛE74‹NJsф}ЁWяєЄ„ызЏ?б"њ§•ЋiQ‰)у†Хѕјуї?ш~„{ГрuА CS'иўЋ‘FП-Г–Хіw§VБVˆ„Pk*”ПpњфјЖOџOpт[“Žю? Щш­Є‹mјSзєƒŸ'EБжМ<шрЙ3чЏќw9уx—ЫР}OKkж!яС‘ŸbШоОoЛп.5чtНh![@Ъo 1dЫoЫ-b.1wŸ1d!\’Д•˜Ў™Рšа-]š8љдЅŸ,ћs…8ТАйPЛжHU1zШV Q  ИЅE0”р їі7чZEвJšд'/zШ*‚№L-k$ИQx<Џƒд'/zШМЮ(v-’",RІk†ВR41­Х"zOэєБ*ђжRЏМ4фZ,’6tиyScЮzбCVНкР‹фёwэДHN7Iu{Ш:U† o Р^6ч,LM^‹EТ7ЄрЃ‡Ќ‘Z“Ц5зPѓЎ‘ЊйCVёпЁ"“ѕ ЎЪИЊ%Ж,ўHЌ JЧuK$ђ–дb‘ НЇvZvЯєШ Јс№…‡Ќк}I}„шk;Œж[6иhПї}ъ№!рЈЕЁ6№ЕX$ИQ№ZЅЁг'Џ_yШ*С №ДЧ–…wі>§№#Vўњ—‰птSsUvzuvbefДqRбђ6ЎKшкЂСCЕ6И№™U,ж…<ы>h‘ФhЈвœжЬпЫЄХC]ЛжHUŽzШV Q  hБH€‰оS;ж9Š#Э_/zШ*№L-k$ИQшВЮQtўzбCV>wX5q^§C‹Ф5ШќI^zШЪ1 <Ž‹„o6о§€=ђIяЭА ќГ, $:фEY цЕ' I‹‡ЌоŠфБСˆъ—zШўPœ?ЌеˆƒзЎ<ЖИUDыM_nXDЖ\\зф›юћщlЉЕttЗ™b4€ѓў- пlош!+EЄжЄЕЌ‘$НЗПuА*ŠCЯ[o5{ШBлрcіг“!@ˆCжёМг и;djG@‹EђСfƒ–н3=ђТTŽjѓ<[ућПаћЅМГWр’ткo,С3а"qсЦk‘ЉVY№l… qC!ш@@rУпЋ+d4(dG@‹E‚єžкщaU”ю ЮzЋлC<[{ѕэ+n $=,ц эДX$l6№[9š:ф­nYСГ5Ь)~$‹Э7хEŽЮ EтœZ$ЕГИˆjѕ…ЈxY\$У"Š9Hћ-Щ› :XХa ѕЊYъ![`!‡ ŒЁFcp]cЉ…XЃ“ ХW G“†Чš’ #)З‡‹4EВŒ•ФВwsNю™|іщ, #Ф™$$ІgьН{+… dL1iŸ €‰ vЮ5Ru{Ш‚gkЮ‹nЫ№ЦpмЖ’Рфъ U'Z,ДKяЭпZ$ށЈ^YСГuћюЏПњВ_ћ'сјњЋ]ЄТiлмu•хшŠp! Х"љР,ƒЧКЄCо‡ {. 1dћ[їIг ЫЂЖіВ„ДyVˆ! O™,eФBЬўbШЪ‡hеž}rfЇчbс ќШцQsзхШe€SCћRу˜`‘№]ЛЊGS{бCЖj(TB‹EђСfчZEqАєЩ‹ВŠр4Z$НЗПљ-ƒ2ђ‚‡Ќ­<ŠG$™o й%ВŸifСЕcЇЭK:6эdљfФ75н+"'O†мОdKјињˆ“Л+m3?u4о@†O˜4Єѓ3ђОИцL}ŽСJuШЩйѓfЛЦЋ^A-Œд"ЉХEhїU ~*ЎХ5MЕd„И‘хЎeёЊwаh‘єоўжСЊ(тJыU;Г,^№%‚Ÿ>ОЖЖУз~Љд{LUZ—8І*Ћ "€‰ |Ю5’vYhZ№SŘЊ№!ќДз(VЇZ$.tЙ-ЁVYhZ№SŘЊ‰)у†Хѕякqu …МŠ€F‹„1dFcШ:СQ›C–kД9-zШrЁˆB-’о› œkХ‘в'/zШ*‚№Lk$|Ž$НCаCVŠHэHЃEтg-ж =dЙ ЎсB-’оS;ЮЕŠт ј*Џbc`hДHzOэР2xЌ:фEйSўю€Eвђ];ДHNP{ХCŸ9aZC-’оŠЄe­ЂC^є­!ЗНї›‰k$.Lyч“О№хъ U3h‘ИцЕfАf„=dЙ@ (!ДH\УЩk‘Мс! кўёКўЯД„Их ЇNІ‘‘€iГй Ьў[‚[JЁ(Яе1ђh‘И€фДH^ё…;~bу?ОлўЯ ЅПнZГt mтЦЅ‹­Ѕ%лO]иxјЛs'Oˆл­(/@КК@‹Ф…0ЇEђJ YhPкЌtS=iГцоЙ™6ё№žм1яЅ›1С‘63]мnEyБвеZ$.„ЉER;‹‹аю! ЅБиa "oўz“–$)ЭGВQ%ŸЩгKxжДH\8S‹ЄvfExХCJcŽz№EЁ†9b-7ŒhIZ#Щ_*љLžЕ @‹Ф2чЩ+Ва Ќ9рL=ЂM";Г’/nЗЂМXщъF-Тœk$иZ3п'ЏюeFщъD@ЃEТwэЄƒS­Вѕk<І|Я S>˜щIыЦДяаИFв{jЧiёд'oЕzШіž‡Єwt*(abRgа"qЮЙkЇXzШ*Т`LIяЉ>VE>ЦZъ•—†œРC@ЃEв{j–Су{Z‡Мш!xТй#Лvz+’ЧZpш—zШўPœ?ЌеˆƒзЎ<ЖИUDыM_nXDЖ\\зф›юћщlЉЕttЗ™b4€ѓўIяЉ–ЕŠyЋлC–ЙNИО§8Х\‚WнBзH\pёZ3/yШТѓжŒ”dС%Љйуc_эsьЋCД•lƒЮЕЊ01žО‰‹RЋ—–#8AE ОO<Хж6ДH\#ЮkЭ`Њ ‡6Yxc5uШ€ЖЯ=ПёшwЎў<~юќЏїlхjЅ6Ё*ыЭ]ПnъќЅpжVO`цF‹Ф5ЎМЩВўО(95ЅпD№;"uHдSбщ+звVRыСЮܘ‘Зq]Bзv`1@’ђ—ПїюС;Xї€KЪ ѕ‚№Љ#ЧBCCћНžчSЧЩГзrZ$Ў€г"yХCіјбC=њvб,:sƒГx wюьљьЏОўЖ№ۘšўўŸm=іе^рлЗhрАЋrТuНЛ6f9 r LЕыуlyіZЮбh‘pзЮщўёJ йbsБЩфіkxi3f LќЋCf­Z7ІџЫ?_КВognію§`п\ќ\д юO?œ=;wudы3xEњЛц"sD…И.ЪьKh‘ИЦ—Z$ЕГИэВaa‹E\&m WИ­СYНЯAй‹ •4-&~єыЂо=›7п)южШžБQ8а{6;f›’BjmRЃEв{ћ›­"Qэyi ђ3ЋЫ+В1=bюЭcej! Џ]нЗeѓвM[rзЌd^ЗtN(žв*Tы}@іnЮЩ=“Я2 іy#-- ˜Мh‘И†’sфйoO^Л|щСm;РcnжЋџЪ‡­pI+yтЦТчЛвгЦN_žнЉgь„љ g I9тЄZНїэhн9F<‘КuћіРgЏх4Z$Ў€лšyСCО|В|лЎGОђl—^Q/›ўЮ Џ&HZЩ76+}цафБm:t„Мž‹}%a p$хˆ“jѕю\Л~Р№bI   | Г6'5Z$Œ!ыtѓ` Y'8jScШr6ЇEТВ\hЂF‹ЄїfчZEqЄєЩ[­ВЧBІ?  q„Я‘ЄƒX­ВвЪ0э7 Eт -ж =dЙ ЎсB-’оS;ЮЕŠт ј*Џbc`hДHzOэР2xЌ:фEйSўю€Eвђ];НЩc-DtШ‹Вќw^€IjДHzOэДЌUtШ[нВvѓRwpФ5šМжЬKВ\mB!B-зh№Z3˜ъТЁЭC–ЋA(фg Eт^‹ф YxQОё lшџ”+^]ZxЕтЧ8рЉ:ВWЯ^ЭТКЗcЮАр"ЁRVQŠмДl §8DFZЊэОу­V(Фсrл \­іЊѓкнu+Zрб"q 0ЇEђŠ‡ьІ–мјёђЦпl;yОд|л№ˆ)Жџр=[+_ЕоГ5Їяk‰РЯLy3iтДWяd}Жџмй“Ќ'Š!e…7­Zyљќ9Ј+ятЃбИzсœЪBЈЫmбЕкЋЮ+rзeХ*Ёб"щ§вЊџƒэ>1пБl=]h йХe"зŽЭWЂšvВ\>`(ј>Тњ)§Хжј9sТЧжGМёрг YлvБш—аeјИЯ”зl§і{СХѕIxўйЌЯ>_š:ЁGlœиЋŒIюЩ34;ј Ѕ АѕФїPˆЂ0˜ВЌ-ŽК ШХ№о]vŸО ТPШОѓљДXек9ђњџxyЋ…ІЂBKƒHЮ3hнжEW.§dйŸGPЛvэЈ]’ŸХƒЁнCV+––й$ВiЋVЧОД}сЫНmƒ€…dIDATэ:ЕЇоAk6œ8ђЭ№^Я'tідЧ'Л SBqZEс›7uюjGŸЇšƒЗ9ы SNЕкyђВвžаh‘єV$ўЕŠ|фДчЅ%ШЯЌ.ЏxШBXIˆX(?с1;?^Ф–W%$ЇвсCsГзю>yТќ™“ІАf0gX(‡…”U†Ћ`y˜ыЋјл)Ќ4 kчЬ+.'€i\#q .чЩ+В}† Эš9нrЧ Kиu эkгНф?жМ-9Ё‡FЖŒЂLи€y—рђ]NШЫXOCЪ* УЗL›(шэ~щ У ŠЕsц—РДF‹„o6Hю №5@ йRЋ О(tЩCЖE˜‰˜*bШZь1dы4 хЈХіжФ5 3aТъ‘<Ѕ2šиаПŽ§іп>ќ4—UљBЏощI зЏ_ЂEєћ+W3> )[f-‹эЯBа* ЧП™Йв^pЗшfƒfбIiуY!B^;^IQ™дh‘єоlЫрё M‡Мўр! Ћљ‡MђоѕЋNЁ‡,зppj/zШrЁˆB-’о› œkХ‘в'/zШ*‚№L\#q 1ЇE‚В|ю!‹ѓ:ЎѕЖZ$.DЕX3єх‚И† iДHzOэј-ƒ|\|•Wоф-’олп:ьМ)Ž1gНш!Ћˆ^m`‚EBйЊšгšЁ‡lеPЈ„F‹ЄїдNЫZE‡Мш! jRuЗpT5F Сi‘zШrС€Bh‘И•зšСšєх5 „а"q 'ЏEђYq—р!šBбsV,ŒДЧ Eт‚Žг"љ‰‡ЌZ—=gе„‘яh‘ИртДH№ЦЗЅ<ŠЧ%oЩ_pˆGіЋ;“\#Її-щhnlйГЂOšюNЎ йћŽёwГbнћЖmN›3ќъ u ЃЇЭ™ў#GчЎ_)ИKРяЩнДљеЩ@—пЖ с\Їd.В_vuJ›•0сH›5ї№ЮЭЎDёš› EтŒZ$ЕГИ№ЗGL+zЮŠіДH\аQ‹ЄvfEј…‡la!.-ЂoA#=gYу‘а‚Z$.є8зHўр!§LЧmЏ]лЌwb]*zЮrѕ…ЊB-RUйЏsЎ‘ёB Y№mвЂ%xШщќL§ЧъГіъ‚w&$М9†qЈгkЗ&сfЮbВг,ћgо=›73шхЖ1™0дs6Огг!!ЁЬsV,€ДЧhДHш!ы„М?xШ:5H”@ЯYо'бC– SN‹„В\hЂF‹„якIo є•"R;взHzЛQpZХБг'ЏЯ=dћLєœUCЦ+|ДH\0rюк)–…ВŠАSЃEв{jЇU‘Б–zхЅ!'№аh‘єžкe№јžж!/zШž†pі,’YДHN8Sй5ГЌхжƒзŽјlј Ыq_ўэрЕМ-знВни|1gХw‹хлG$"ЇќJ іњЖвEфљ -’оŠЄe­ЂC^ПѕEmЌn…У5ТМѓIПё•hnйq Г!ДH\рёZ3X3ТВ\ ”Z$ЎсфЕH^ђ]8urЏїя(Фeэƒр+гЧ$ПWГЧЇ'%B€=И4ўЕСЧі ШшЯ\dюпБ5GpfvILфmЫРdPФŸНzўєС=;FОЩ№БЏє„Ш.%)Ч–eW‘ €Iˆr’г"yХCvЭвЬвпJЖџѓТЦЏО;wќkж Љ#G%Œ“wс Ф{mђDЫьLсЭюQoЅ­ЫZЦd6Ќ\œ8:…NфрЌ8Ѓ;wф›ьмЯѓ.]щ3xрИ„ј‡dm…ф//8яGXёaY]Hˆаh‘є~iUмtџЄНC<ˆ 4Ѕ\РKо ‡X}ТиWћМ>flї>}iФи пœ0 `‚ФЙXˆ}?^3=ЎК‚лRЯ&œ’Эб }jБe§shgєXgДcШjФgё@zЧCЖQ$-‚РВТс§b˜ШСд” јЎ#оыЈДёы–ЬБ _Б™A‹XE‚j\Ђ’NIˆќgџЙˆыР?ЮhДHzoѓЏUœЛ)ЄДчЅ%ШЯЌ.ЏyШўRHЫ“M;bр№‘ygЏ€Љ9|э!мЅ§зЉg,1ЏY”љ§ЉГ§^KtpЕ§СјАют‡k$.Ф8зH^ёэ9pУ•ѕЎ%kжtжОВВ2ƒбh0@ЛLЏ ‰ I)у7,ЫJ?дqˆ‡е cŽхЌ~уУђcE%б"q!ЦmЭМр! ОЋрСпіщс/viѓkпŒ%Ы—ЮJиДAкvvr}%AЦ'Z<з0NL7,ЎLЧ-тУ‚;-Ф–эžž2\qнЪ^ …5Z$Н7Р2pпгвбд!ЏЏэЖяLIСl™L.H! HЄЃ |™г#YА% -_јxсВ•я4wTМvИсT-№ёЌЮdњЗћw[?=[љЮ{ћkЛ=—p^&“+ 30щ‘D?ўцї ‘JbШњ•В™ѓџкф1яNзTGЩЙ–šzЯFїаБої‚1dQm­ѓв'ў™/ћО‘йЮcЋ*іП‘^с{§ћсwT2<Ёc!­RH†R>D “Љ*\&cг€єH\zУIыLaB–дRК}з‰уяA$2x‡IнёЃ„OўsFзтKL&Kв1kРЄG§ј[€WaЊзЋu&Y,EШ’ZrFц>ГmМАaщГыЪ—?Iј4W]‹/1™t.IЧЌщ‘ИTЧЙFВ!KZZДИ­Е '(hѓџ]С|$vђCT”<ad§_њсЉ–a2IБ’0Ѓщ‘ИДЧэ -DШ’†2CЧЊ БЬ@ДL&)Vf4`в#I„l˜ђ{ !ж™ш H„,—ж9=RЏ dЙn@ YЌ“IєУЮЕ Sibђ FШ2яT2ХkРфIўЄю2СYuѕ2нK‰KёfМ™DШrЉИŸ ™єHЂЇvœkfЇєV^fc$3С4`в#‰žкgˆйф•й3ўл$ВњътД^‰еWe‚J˜єHЂЇvfж*ђZАЕhі /,Њ 9Š•k$Ў~цєH–"dЙj\ˆ /Œg•9z4 =R.ЂPМоL"dЃ(1Ё/IФеНМЩJ„,ьRнМЊxвШ›риМъзЪІеРцfХД.†ьLї˜ŠƒodЂbтpБћN| їž$,ЌFXXZKtZШŽ—I@ћДХFТЫ†тЩв%­ЅCVK3a|ь‘ДЮДЈuй ž иŠ :@Пм•дЁАd(BІVZRиŠб†2в’жв€I$њё7џZ%ђ†ЭчХ%DžI]–"doЬМ‘DГ„$IН<„VZžМRFWrЄЋ"E€sd)BV‰-ЛІд{й Ф–…$WгCBQBа†Dфwь‰KwмоЬB„ьœЅЫг Оw+Юƒ ЩеєPДД!љГLz$бР3piЕNф•YЕв“&-В\]ЭiН!ЫЅЭD2щ‘D?lр\Ћ0{JL^‰e*?с™&зHЂaœžйmbђJ„,Sљ Я”‰Ћ‹Эx3‰хRq?2щ‘DOэФx•Ш>5Sodi’“x0щ‘DOэ9=R?BШJ`,WЧs IФЅ*^o&В\ъL@!щ‘И:•з#Х!‹аюM!ќыЄoп\ .‹Њ‰Эg›gо5цЭЪ=a| ќ,@жЏ(ž4тІin%˜,™ббD`+Бaъ4š‰Kcœ).йн[Зœml€№ЏožљЬnЗПДОŒnbнёšтŸN[ZЖ~ъœY4_ ?[љќsОюЎuЇ+}дP{‚ЮBh Œ%Њˆ™‰Kuœ bШz•Вљѓ_mZwЕuКІІ– T_Нбэь=Œ!kЋнъ|ыWіЯ=ЬКЋ_нYTі „ЕЅкžXQrє/Jмrќyѓе=Я//кАgџи CМр7Dž…€Гy ‰/;TѕФoVдŽЂ’еЊ\8Йтщ2Ѕ:›эЁЧц75ж3e$3КЄGŠЎŸрUь‘ДЮtq@ШžЛ№рЗУд ŽЩ#‡uz:Iљ{ЗО0љсG є%сB ?KЧŒ*‹ГK`,QcЬ„єH\ЊУIыLŠˆBЖКБ žЊЖRўЖЊ?UЌ‚ЅсB ?Ћ№ллА!H.IФKв#qi’s„ьƒЎ[ЙLєзP[K3 kДLФCЭoПuњЬщU+WщVОЖli_Ѕя“yWхcyб[„„x†*8ы„ьˆЁЖэўV/”Ž~8yНншФ‹Шїotѕp џљ}Ш?lЊ/еСЈЩжіЕх~˜к]іОXід„ћ'[Pƒ,­оaІwЬ~d6ЋT&к8з*ЊVтЄ˜М}!;№†Сн}ЇђЪg™ђ1U$™І5%ъŒJфI­”>ˆ…ПnUџоЊ-гqв€?єBvЃхIЄЏ1‰езQТH„ЯыВГГ3=жЭŠ6$ЮЕ ЋЉЈЗђ2#™‰ЉЋ>:В‡dУ=*ч'HАю\єдж91лƒ€М!Ы$IФѓ…юuиАa!eжввB’LBzЄ0ЕXА ЋЉo'ШжђОнL ZkЄkˆЖ"\‡Т \"Q­TuKІ@ШLЯмwцГн‹wŸн0юцqХюrЯЭvЛ3Э™2їіyiћХ/ZmW‘ЯпmћFfXц$N€с%ааГ8„šўбй™јR$sЄG зЬu6tJqЂœ —uШтёvИ]yЎы](ѕЪš†ХŸ|ёёмбѓšк›ЃMСлUщsxъTўyŠR@MЎ ц~?uЫИг‰aEЪэ†?l`'YjmHbў ŠМSоzСCУ‘zХуѕŽШ§ЎЗЪqНoўЩ GЮПюLOYsзцƒгN f7BіT{d-„гГc5Аu•№ћQѕЪЮЯ>чОа˜Озн?‘@€ёmH1?i€Ж‹Щkƒiœ#-гс˜т*’>єЉж‚”T46#oPњ GNЭцBЇgpVŽЭfx[И‹H(+і!p&ЮDЋм Z№pз„{$ы>Ј™7i„‹™7цШAђ„/С™Шр,є`…iiiSžg(Ёчв5Dуp Šт‰oKj ЩїWИЎџ*в=ˆrhBД!ёzК!Z@^јЕlsн“ўдйёЅmы7їf<”ЕФ•šsOњэзй\WЛмѕ›F+sД3ІбЁ–j~GBYёЄ{0’­сTуЖЗп}ŸТ_K„(_јxсВ•я4wTМvИсT-№™EyLМQЙmњМGž>џб7^оFЎB@люџvј№tхл5|№.сСп6L>)уиŠ6$1^…юWLsж„,д?ЬєAкУ e-ZUBЂ_’М*"%%ЅЛѓ’Зг“™•љdљеUfџ ,*ђLЋВƒэіAзЧДј5ДhŒgxЇgЌћnдАп~ъx ‚œйЖ//"oвxp‡],І9ЁЌ0p#ѓЊ8Ѕлw§asХŽѕх)_O[ZV:іž‰*H’nЯЁНЛ;;:ЧgїМЇђао Š•§Ю 7%h—˜Д—V#О-№Щ‡ѓ‰|!`Cїn n-Ÿm$џ9)<б†Фщ˜Ъ5Ÿ—y&еa„ьgўcчьCVGн^фЫ-ДuюAЧŸѓпx—э†Ёш\ђ]VЬЩс"-$ x‘Ф€э#^§™m; Kђ_§Й^ Ўњ„йѓ5єжо=U'›Рƒa1pGпџ§KWСƒЪoPтл#Ў‡ЙЊв;ЙЁ;Ъ§„‡гЂ {КќД€М€ЭЫA›jPšйэ(mЊ>чhѕyЇЄžFЮoйђ ‘Р<п›3_ьмcеќэз’LП> тH™млмћ_оo5ёyЛ+ЪЫˆoч§Вихr)hџwѓЃuЄњѕ[юGЌфОхЛп~ўg(јмВв6Biп–д’T + I*ЭШ5’J!qˆ! %в $2ПRеD’Г.šЗ–иЪu›>|ѓ/†e?ёрFЛƒфКwв}Ћ gŽ’ёBљšЇЗМ„љQŠ:Иу•цЬ%й1ёРœyРќ`4‡;чwŽwЏJ,‰’џ#1—R!6Hњ8B6Ќ­2W иPЎxЄЋьП‰шЊкк=Аš:л8œFШŠžк™_чаЗФOsж+cШђЋ4!%cЦ#‰6$ыfѓз‹ВN;К)УцtИ<Г|_sfvжЂЮ.єйћhјDфэBщ№ђ <ХbV'™§U0ЕУа‰ˆ8пz>‚зУmHœžЁЇ%&oDШR:ЄХlZ=пва К&р(?кбР3h7FчJoх•YŽI Ы`+ј H@О–1‰6$1^%ВgЭдYšф$ЌшшjљTѓ)gŠ)ёH\Ш\‰MX сЛ1ш€I*ŽV1rІŒ§ggгь›чi9ВЅцЙ›3oй§з]П€^=ГsШ7‡VџыTЗЏ{Сј/ВлМ$? ІРУ†юIєдЎЗж9œѕіЃВ1tЖЬТЁјIї`#кЬЌUDфMh„,Нyою?Э=Ц(NJ”j‡.YuеP2^хЊ”ж#ѓ#к8=Г­"ђТTŽ„FШ‚n››?Њ)^0їщЭ•y“Ї`UEFМ]ђ“5еoEТ>qp_8юУ —ќё…ЩЅW^и’ŒёVi‹нœ{Х/2"r+*Й/š€§A Ls€§АМ џ˜VЕU@^˜ЋВGМ•ЃRяЁВ™ѕ›ьэЧЛoŸуЭbоSЕY•ФYЛУ Кз.[ВѕP5 `м„с”@Ш Њœ„ьђu›ѓ&Nєx<ЛЖ<—?}Г(UоšЗnYѓфцЪ}ЎяфрK$т­=е qe тэтп>§ш/ŠžџэbiPўЌ !’'dЩЛoтЮuЋСЇхм–{цd§•Ў.рZHФ[рЌ+^Fј@`Є-мћЁ];Э,пдŠ}ТЩЕПZВЕŠ­ КKiЉ…’VТћPніІеKчŠ•X1ЏмЇs['Ї0Щ•0„rћ™ƒ•ш:^yЖVжŒIlFфВт:§MЋиŠ8си!r mnп—‡лŸџШ(o–Ыкфй: X7&ёŽŒfhьБЇvр^[Ъѕ‹jЃб”~§-шњ%і+‰6ђЮ=ŽvХŠфй: @,НXЦЄЦC6z”AМ#˜бYbHЁjŒ†1щPќпGŽсќ‰JŒ4Ѓ4-1HZ7zdЩDЁ~1:ЪŒЪ‡ъ1јЭіHИHlDЙ8^{39‡ѕlžZ|Ъф)јй\0JЋЫŠ_Zњ"РнetLyЁkz0D3$хeдGЙP1Љы@jm —Š5•џ§<џ—СЗЅc­“+ље0ž’ЖЎ`O“”МbKQ1E\­!нz ЃžЁЪ€—Т%чGк ‡5ќxЦЄ DЮ@AY№‰fHФŒш(„iActŠЌyП$ђЦчСй(­SДЙЫIы%иб-ю"2ќ8Ч$‘'=ЬьˆѓQw6„`˜,4Ф ‚4шЊT—тž Ќ‹HНАF2@ЧН1ИРРэ‹OI[—jј“ЁЪ‰/ ‰ѓ~GѕH”`FюHхќЈ№ŒHћчm\о]nяхр+vв<хЧ,C~5“v” аюzјёŒIZJрЧ б Iѕ\ЁЉБ)їЖ\“ЎOЎ‘ŒЇЄЕерH _‡ыŽIzИ‚0Є‡Ўy:Њ!)РŒАOSуЩZ#Œй“ПЩ~œЈњх•эюбn8Ѕудv1в~h Єzƒc24†u†nЈє˜ПЃ’є"цЪЬg„u  `”6_ЛV Iы%иб-VОб1iT^Ћ‹uљб I7ГZ€у-•ъ,FвА‰У Мa”6RaY‘у)iы2м+b3А іУТN>иƒФпц ‘љГїkIђЋ™ДЃ\€Ќ“L|‘бЩ6$М›ѕ)8„8…ЖЏяЫУэƒ§( $ЯjРК1 =ˆ 73идxЄпo9S§7ЯЭC H5г™Wj пiРH“Йhс(мrЕG \PlЉпн˜lАд€H аVѕЊ=’ШІШКЄFџ$ё(ncO‡IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/7.png0000644000175000017500000011650411733011756026162 0ustar sylvestresylvestre‰PNG  IHDRaЬ‹ŽАРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН |дTњ>џvџ“ЁИS`eБ•‹хЖA”‚ Ў@Љ+‚,”Ђ–Ы"А](7+ЙД Z+bЙ[.ВT(рJAW(*A@@*лХЖУZ:ГR›љn§ј{2gšI3I&г™Ігі„0}Я{оѓžsž$oоs’ѓцЖ“rєсКQ(9‚Р№рrY”G PоFpЗь ŠE€" ‹Рџ'ЫЅLŠE€"@ 6‚ž Š€дFЈЁCѓ(j#ш9@ Ј!@m„:4"@рŸkа"@|Ю]Ь?qъ„J;ћіълНK8№JXE'ВЈPЧ‡цRrЭЯўлl•жЌzsra&МVQHВшXУ#DT€"PїРƒ€рьVВГMYЩўј1ЃˆЃ!J‰ AиcпЈс"*@*•[тžUЩ„˜[Ё€еR"sчYJ„&QXX€ђЁЁa‚ЪЁh“ž Еq&š„/Ќ*]љ­Ь­ФYЄ8Aь,аюТ’ŠФI­c ѓ]aцаPqIЪЁhш™Pg‚XЇ˜ЦuN.uBZ, Ёы@$IR"ЃžдфGРRJ хˆaЅhP4ў:ФxVЃнШ&LїЌ*NЩ%­юrx?–8…Ћ)ѕИ kУ?Œw>/ё Ы0дБФI  Dб h“ЁіЮсdлА}+ц,­6+Ўv\ѓŸ\ќH‚iЗлЖюЬš8nМ LФ"F˜‚0IЊќjk*Јc)@‚ЂAб до™ F˜aШmќ ;ЌCіЊ,Б8/SхAЦ‘$eХ’jДІБ† Р_Ўе#@ ‚ЂAб ИŸ bd@лУђ+dI’b~XяірДК+ „ ц‘№nЌсQ Pj2|А”ZШe/ЎТuСџЪ‰Ч‹Iщ*a)п-эсVœ2(ј•)ИъцќЊа%О‚Илыљ%E”O дX‹сxеo6(юp" †6x%ьБЭд№ д=dБЌ€JS„5]^ Ћ($Yt>Т#DT€"аЈ cF}јiч) 6Т#DT€"аЈ 6ЂQ~кyŠ€GЈ№ 4jЈhд‡Ÿvž"рj#ЪђФ-]Юо“ 1ѓ”bUѕоF`вeрр(л-|2€nFŠ€еЮiМЂ‡GgяЯжЯFиlŒЩфХQщоЛїЙ“'Н( Yд Y’ R,Удо%Ps?"u'“Ы‚k sЛWd`nŠŽ\?Žн‘П§мO—wЧюсBЮ2}к+*ЁzŒЮЙK@ІGХD%Н/с(l+g’З1‡О0ЬЕћп€§Ъ1?ц1Ѕ—л5цVБн^СмепаўqІЅЪwI]­ˆйSЪ•v iлЬаzьёё§тїY˜ИЕРФі˜З‡•`wшFh8дЂ'с`т“О“љњ;ІEГZ˜Иvд~jГсЎЎ!Ёї1aл%ЮrŠћщˆНрcюex` l–йъјЗѕ;† ~сiБНу]Д<4э˜1ˆY№—Ас‘Ё№}ІН}юТмЌ%Ÿ"ђсШмЯr%UШ2%24IЈЈЙфВэЏ~yЩŠˆ˜\%cЗ3ыї0ЧП3єяmП№Г~?У*T:=FTR3i?ћЖ)М+SЩ2•VУэ,МжмžЉ42MсM3EyЬНaАхГŽM\§žЉТ–>#bpoŸ9щљY_Zš7eЏџФ”В}кSWBѓQЁ‚яl ФЪЬ… учЇ КмХРjHЗJЦjЗ_ЛŽ+а;/уХ56Ž3TXSІ†к†DXИ пX ‹YSkЎє*же|ogћkЉД6GZzЕ7 сПftГФмЁ†ЬАФЏЮ_чкД ‰|<‚eй›Лѓj<Х“w:яэwо.К|ЙЙЙm|\ќ?98mнВў§Нћ+**"‰Lœ™h0№M‚ї‘83aћЎmз-ЅЙGЄО‰lO(“"hxa#ьП2[џЩ{#fи†Н5А }Нт ŽБўШ”сƒcоn•†'ЂТ~(0Yэ_с3tПНйЪzlwШ## ІVМ2NYiѕ~ДfJ+#Ынт&Їч3•ЬрaF{сTl4ё?е‹TkЌl–ƒЙ4yщьЙГ<8РbГМЛљн!УyБuлж‹—/dnЩdƒйДЗвжm^7cњ Ђ№єw3жgšМzќS­)4Aа€РэЊчГ*"ВWƒМ<†О1Аїи?/eš•šs!Аиwq ЮЮ”XЙЋЅіЂŸф•ЈqƒГ‰љ!ˆхm, œ ўг†ŒS˜ЖўВЖ[Цa,дД№`›7БнmdйЎйЏПхžŽ‹А–rйЛЮFvf[пe:яУуWЃбhЕYm6›Й…yюьЙЄ!іH{#Эд‚Ю‚Љ?ZgЌЬУ?@…МЄˆ Д­Й­хjaXћP“ЕАэ]m‰|DxјъW—!+яЋМ—–-§јУН QфнЕВц@ЉA9%(О#р~>Ÿ<žлЛЪ›эЊЃ/7oж}оЮŒТŒњЃНт Ч45ЭЧГ‡q\МС!;ehН:0А((e.1'ЎrЇ-М‡гУР=qЈ25aCј c+ц~МЊЈVЈкAАxТ;%Lˆ‰…@щ9kнˆоЪЬ[7WSЋфш‘‹S–ччч$A,OY>nєHR$yErAQ!Ÿ…‚UzF>5ђ•зS,Ѕ0 !C„bnU8s)Ÿ"р/Ш Y]лЩЙ`ѓПb>RzЗЁДІg<Э0ялГ>ЖuxЪTv‚оЪ†+PfЛO†'ЫzЌ3cНZ€Ќу'эlџ№В[м§%љэ‚ђ˜[жО­іЪ_И[wЋ‚aл3]ŸbкQТwТеˆ&ќШфLг›И†Э&f%§Ф0$3&Мѕ))СˆCо'?f<ŒRRЪВЂ‚"lжfмŸЧ kЦщџhтМЄЫ—;vьИ$y Љw|ьxf'3eFТЭЏЗщиё…g_ЕЧе0™–SEР?р4“9гNž№aю­Њaой”‚™˜є$ЬЗУŸ4œ1љі.іФgп>џ)ƒ{RЮ=кз4уќ—˜KŸлmmm•­ O2цNŒAўЊЎъ‹ѓoЧІсЙ{Ў7Уs рG№“ЊpБngЌЅжэЛ Ч?2щ 5UбOŽТ.QK’‚н= –Л„я—#$бI“№кF }0 3žЖ—mcіѓwkanpAЃQx™В™ эуИМe ЄJХ[†яœњЯgOœ?л7ˆ1aа‡/ЗѓУ_МФВdЌЙOИw UъЂY@Ml@С:.ЌдРМ ЏЖЎ­˜т<ў]sXьЂЅ\X3ZХхџJзŠfb№тЦц˜yEyЫжsЮdАнДОД “\ць0<^ЅE Ё!€ыXt јЗw5ДhяMŒёчЂЯйЯЈСLH „$}кєйѓ22ьЧA­}ШЗUrЅ("аАрs/7ožkИЉіv&BЫЕэV‰‹AŠћЈФЅŽRŠ€jюGhPюwј|9ћГ‡ зАаЫџЭЁ)WЩqx{HУ† TИd4КDъ™p5МŠ"QЗ`&Њє/E 1" ёhМ1oщwƒуeAћь=ПЭ%V\я§ђa1sЈыеiqї(M ˆРнfТЋ˜З>ЭYŠыdКаVјPњCї,iyјћУмNк6Š@"Pя§uLїŸлПі‹зПВœл=†{{ >юU/ЁknЫ–-oмИQу*},^уziСF…€дF`JЎH}оїJяrгZкЦііЉˆБњХ>Y8…{вЇ‹ХfЛa` сїЊDаmTчэl#EWК–gRA*dbЃў"—_ђќъ€YБїХ~EТоВь‚П„яgц#zџУvс[ђ$лрћф_КД—лW­^uррЂ‚ЫЦпЗшџpџ)ЯMy п„оКыяYA[. @.pЯ8Є6Z`&Мšв*ЎBбœ•ЯЪџіVЖ aoЇ:УоОєvўћЧmЦі&ТоZ№ь­•›ђFўеŸИС##z=~эŠхъU p4 pІТйЏ7лžћцœРE™_Ф/!36і9АМtўвЅ —Кtьђъ+‹ё'N|ИїЃKљџ§дЬy3 џЕ•KЫ~*;“wцг#_~zќSAXEЯ7gОљє№Ї7ŠјЉMЅт‚JPД АaћVьч„[—j™лLЪљ0> fяШРU[+Ÿ ЧIђ~Dг—o я|ѓЧЛ›—йЋ3{ќ.vвжR{ж|илvZnнџъ БЫ50ёжлoќшр•+WкДl>lФШщ›NBзТƒ „Є50(їнпХo/‚БяПџžПSЛЛp\ф№іьоъx›ЃАААwяоюк$zЮ}{ЮмвЙ MKqIЋh’" FРRXˆсљФЩгС\ѕцЊОНњvятсђ—™kд&ЂЯ€ож˜wьЈlWилcТ{їСГ$ьэўяQЂЪљ—+l6М8чEьШ,МVИ~CњДІmлОЭ]ОЦ+K^9yцф/џ§…ЯС)„УЦЗ6~AT;Чv§ЧыФ@ кЦѕо—ŠС@ ˆRqЂœўR4"@wŒ3jыЮЌzc#№К$ ФНљg^mJ6Тіж„ 36DЃJžQPШ‡Н>:B{ЁэB%Нк)М“l‘ “&$/NоўШv˜xwЗЛ[VL`"v.мЇAтb:ђ4ъQ*.шЇEРя4аљПA*і6ФР‡Ћ30[ўiйxшЦФ­­W6њ_КO?ѓєсћЩЄх†eUъЋНћ9#мДhоžE• ƒsё10щ8{СlЏD :nђ+ЩxVхЩ/-Ф4ъQ*.шЁE@| zm’LУД|илрЛЋТоВ|илJћ“УC_˜и=„џК?Y€O+lјпЮ}{њ=дOžі„ѕЗq­ѓ&&(<зHOKOZ”д2ДхŸcžь{_}.іТ9 ›…4ыбуб§ьџЈЁQRqA%(šРрЗjќыQоЛ9KD‚rррБ-˜GЉйXcЭыЏЙЯYbuFб­Ы{льЬ‘љУ_п’џ\lw2Y`)Вmм‘?юaѓ‹c]гZZHe( 2g;.}Б•л01qœ4VГЄ›šќ!HœЄpР&?њiЗнѓ/§Л€а›|ил ;О9XpЮВ13?mj85{ьhУt@Р‹‘FЕ‰јЊІI,wпЁіŠЊVјєзd80љШБkЧVp–|и[‹…[Гљ,”~Д2ТмМA§|j-LЈПˆж‰:сnD™ѕ†аnРДЁ…›?,ФаkЭжќ^Mkц„ф{\o:EJаMWŒФk ŽљЌЩ†ŒѕлvПљљСƒ'Э›kРЬ У@цхљ‰3ЗуЋЙчО‰Ўf­Edфš›лкќn›qЛžкЭqCZ7c›нЯа˜ЎбŸ*HЯБ0•lќфN={А%юефjЦB№#Фj(MhHрFXRрu‡фЧеДhоЄАШUлИб#“—ПrЃˆ_s]x­`с+ЩJ0„QЪђ#?˜х№VФ§­†Юz8)„‹˜јZожOmбš7,Œxфс№ЗіsЏф˜жŽUЕŠ§ˆп~уWsI6YІD†&)Œn„UЭУЋЦќлЦZЖњ'L;‹ЩЈ$жёЊж„S0шшаБуs_аRwэЪАЬž’{>e›™ўмЉoИЩЪqЫ7хŸ+ф˜псН6И W.jѕ#D`PВa"рђ#М™Г”Бю“G `ˆ]Аtч KФм9B–‰&MЌШnҘšT2œ•›‘VPZЦ0FІIЈ Ы7~Щч]ё&і#Ф|wzфSaЫV ogВмАПšrь­7Я™UЋNœ';9џЬѓlNЙ•Зй№>^ZxlњД>ц6П<|qoхP4"PГљˆŽ54ЖЉ.ХXІ VsБLFŽЅєг6ммЖ™сьЗЫе@‘цbЪRзG'/>v[№k}nылз§хеeћє2їшГ­EЋ5жr&э5W ŒО}Ьн{o BLЪдсFшХHCщйЇžэЎЅКš№O0›aН†1–‚щин њњї–!L‡V|ždр“№н“І2кšТю)Иb?ю€1yZ8pfЭЮyњIWlŸщ;іŸbЋфЎ™r(ЕŠ€іЁИ ж0"~гЬhdFG`Ы цfБ%aTиs1ЁЭ”ЪmгпŸЧd=ўXи™Џc &ŽэŒ=cniИјm}в5gё`?saЁsј‹c–!Ъ‚‚‘OuZГvШю]—@cnЂяƒлЈ9pУ•2j м кЋ1lЭц#ХF/zlлДС?ˆЂ[Ж [mАdФqјKEгƒЙ № fbУЦМw7 љ{BЮ'Чy3ёXѓiCжoЬ#хВvG/[’wњŸХ+wl(ВaггrОЛfэaN^д'њЩlg§CЈnЛэЖп~ћMЛ™Рю|?тW/TuŽ{QЄЖDkіэљo№`ј‚јY8˜’РжэSХ=|јL(Иo‚@жЂЄ<ы-fэšш№{љ—DѓПЗ­пpvеjЇјчќ=D‡оmЪПfћœг ШЋЩЬП>‰Х ђЩ+ŽЙWA9П#р•™љќ5€3ˆ‹эБIоХЁђЈNиФЁjЦ;џЎэ‰ƒСwTќЁ-зќzjз{ ~АwэШ_э\%Sєw.@W^шJ KьGИєPŠ"Ј`ЌAZЇн›()…Kя Ё –Рљ ?ТŸЧтЃЁхCТ&4Чp€пьЄЃчПАќћgЎќВ…qММ ЎQьGˆљ”І>Н С№ŸNмхj#аХœЁх­KЎ‡YлЗ20A†ВюГГ6І’+?kaўOfАA§ёiAщz‡€3сš№І{26ЂЦпЫђІ^]d‹[§чwЖЋ%!˜ƒјъ?ѓГЕќ|Её…ИдЃAщњˆ€G3!јdЏ†п 'Bщ“3мЅ|ўбЃтVh=­эѕтGа_Š@}A@іœЬ„R/Шs r“k‡"ч№!зŽЬX…a fП0‹#eЋ (ІЕ”>п) FCЈUІЭ”F0€ijTК"ШјbШуб,ИЊіе[A•МрГƒXЎRfnO( k2 4d@€Д†6Ѓq `)ВdэсЗЯўль:ПL>ОIŽ@ьѓU…WmnАы5TЂYƒ ьё 0єЧŽѕWЉ№’TE@oˆЈэZ•ЧЕ]3еO ј€€0Ќ€тJРРцwУЁj#МYјсCgiQ'їvОїћяОЇpд3№2ёk“шXЃœАѕ •Д‰uŠ€э&?+С;7г–ўjЕўBRЋžТЋ…гfLыбЇvHz,Y3ч‚ZР60XП@Dm„Ўч‰хGЫшgG?:шбŸœРI0um­Œ"р ЊѓL=x?Т›ЮжНlњ;Љгу'>§фpвœЭ цЋK–ЮЖw7МЕqCХЯбOFПКpYЎzoчюпwŽМЕц­mџxƒџ4xщЫI,kрљ•ЬЊДЗопћ>SY1}кŒиqБ(6q%„ВD§ѕ7 ќ2Qѕ#„Ÿю~EрјgЧЃџ-FI0†љтфщ?м{є№ЁВŸЪ`>!6dlИјэХНY{O;j 2Ўz-№пЪиpэ2ЯџзGGKJJРќў[оІр—'ќкЊG@Ме_xХНPІеќˆn•AЉНœы7K &“X$oо,8‰sСA@LxnТФiгIcˆРіvgЌЭ0Ерfќ}FЬŸcf'ЮНћƒнят[Šўє„й‚6 Jшom арAVГЕh#зйЂy <Ъ&3ЩцЭ[АДlг’а-[ЖМiЙ.№ С{yш0Гъш]З\‡М‹O)Š€џЈ:ЫќЇ‘jRA џўйџЬЦ| ƒdЏў§…фЂФLмИq_Zј„рПНМcЇиФ~[s[Ш іERŠ&)О @ч#ts™ђм” 7ьПНмŽ}џž§H&LJpђ&eeŠ­д†я2Б.ŽАƒ7z\ђтф…70›\˜_ИpўBТ9bф+Ы_БYlv›§­зV&џнfХ9!4$vB,žtL˜:СљэхП:ПН<1~т[kVЁ $…R'Ь;Šџnѓ7Юg"‚JPД#@m„vЌќ#к>tЭыkdu‘‹Y<qЉŽre0U‰]Ќ…З)tЃј†€ъXУ7еДД_Шџ>г ~QE•Pj€€ш%Sкљѕ:™Ъв ёqучќ}УаcЁт^згРЊРє нъМ.Х7‹К>Šѕ7єCЃf#ИyT<ц4ƒ"р ў2Ёѓ^œ T”"а 6ЂtкeŠ€(Ž5,ЅЎМСПŠюRT”" Р;?+б.yб#ЂЧжэ[D(A HР5NНОL№ IЇd“ђ6"|X8vй”I дяЫфœІљжšЬG~\(`ф-aБYžMЙ$2яћЊ. ›{ь\ЮŽ/ЖŸГ\о=fwrц*Т$Щ R&E€"@дФFРаn&bвcJ­ЅCк63Дп/~џЩТФ­Ц ЖGcГ3,cИзp-€`ЁMЁPœhВљђ%Ÿ?qъ`кЦуxьп%п1AС/ ˜{_ќБ‹–‡І3ВЬ‚П„ яj+gІ§ум…ИY“ }ю“?$‘-#soфJђd™šЄPќ‚€&1bОЬшОхћ<кО•AхГr&ЎоjЊА†ЅOмлы0чэќЌу–ц!ьѕŸИ л‡ЁЎ„_(UB№3šч,іЭ х IDATёRКћЎ­1MBxЙ›зЭmBC03,ёЋ“џббkhD>Г†"яГМg{6*,rЬƒcrvх№šлж•ыcў•œŒP.„ я#{Sж˜b"лD:хшŠEРšmОцО{вNђ[У•`0Ф(Вr“пШПњ3xdФ§…_Б_х?-Сjђfd*[:mi|bќЁ+ЙiЛгN}šHlMпzё› ™Ÿdf_ШfYv]ъ:Ёфщ33gцI/‚%( ^\ћRї‰ ˜+3њ 8iX‡ІСMlwYЖkgіыoИЇ'EXKЙьЬГ‘йжfгyШyбŠj5FЋХŠo™л˜чІЬ%yvHл‘fjЩž’8%nPмŒWАЖšп&дЦЧз‰rњKhhП:ЙsЃЊCРПЉMžqˆЋЫ№)WkA3–eZЗ`ŒALЫ8˜ПafxїvІїПїє‡lЋ˜Щ›’ЗМБeCъуЦY+fѕyИЊЛ^p}dп‘ЎfT ƒC ‡+‹RŠ€'DЊ(ЇАHž<џКЋ1ѓІЮBˆЩРАF ІGZgЌЬ<кУлœmУк~_zЏыŒТ‹…`’ZТЛ‡/лИ 4&&–ў}щог{AЗНЋmЦ jмхPj€€цљˆш&E‚Ж)&%yЇ#$„…РзчvўГ`ЭЁБ3Т[™љЕ1Юѕ1rUŒ|nфђ„хљпф“SЫ_\&‘Х”dс5GшgЄџч,м”9)–B ŠРО@FN1хQ(šафGр=ˆCorзG–ЕИѓХœ&LpГр?0MoтŠ5™ ˜•`*Й'†‡!Щ§Ъpo;J,qШ?к5yц—Э]VtЉ’m:ЕљьШшБбЄŠGЃMštљђхŽ;.yg!aŽzaˆ„gn]oгЉc|B<сг_ŠE hВx Bг{rѕЗ Я}џzѓ0<з`C‚љG† –ŸЄ bЌEжэ; ЧЧ„Œ-o ˆОшИhьrК™У`wЯ‚™ –Bœхў.–8—вŠ€,Е>жxwъЛZtЬПє ŒПъџ‚8 7.+и™?k*;~Ќšm4eR(К! Щ№Ѕ5† УкЩ[ђЎх­^a-ЙбвdАXИЗ6ч3 ЗnЅйммнД,E€"PыдК =шгЎЯШЁії>Мiˆ[ Лud^žc6шTy­ƒH+ 4`єЛLGХпš˜tpб€Я(кЕ††@­ЯG44Рh( Нm„/1ЌйЁЁнЅњ5HwЕЇasØїUiФlюёIе85Mа5EŽ–Ћ]№ЬдлFhaeЗУ@˜&­bџ8юћГЖЗ&ВћVЙ"nIгмѕВЖЛхPъ;uh;єЖ§vV„ЁcOЖKcПDŽ.jbRГYƒIјцyƒлК6‘yiЗЦ)&9№Іі–[О>ўuХЯЅКu›0vРу2я\IJ)%ы№8)5‰ђѕ+зяп˜…і<?jќџ8МBяjі _ЮXНm„V?пЩО|к2‹ЋZМйD 1-bЛH,й˜ёдŒ‰s&&Є&˜‚MљѓwОГгсRM)Š@urveŸЪ=•y”Зѓ&Эk–3dєъ"ѕ5ЅЗашGЮаeјlЃВнŽ<ЖpСDY‘w_{wтŒ‰Тт,MZ“$‘”Z!‰…ЄoПђvб•ЫЭлДŸу,”%П‚QGРЋїпн_ёsEф“‘‰Ы Сќc]Ш$ЎHиОvлѕKЯЦ]•Є 4й8јƒSчO%ЋAl^ЙйƒЈdв_NЭо}}Э‡8ЉКГжem{s[W1xфрЙKчОpfB^іЌУ›GМ#Г}?SY;wвЈчGЙŸБвSБ‹s ЏŽ?зАл›•ЙUЂЖC мЊдУуG|R юм#\Л€_—а№Ъ]•{u”Sп8ўJЇюH/@\=ЯЧNRйp=_Зf}ž…Нјz1’‚№щЇ3ffхeYKЌы_wё‰€R˜Е­щыЏ}w сзv}m§‘П(мЯиšŠzлэ~„Йе^ЮIwgЧ>џkЕл… d'Qj)5§žFUƒM6Т•D^%М:ЗИxuxO ›8р•UUхшпњŠР/џ§…x‘шˆвџўЂо“#Лі',I057aqфƒ§‚|ТЫ"ў.Ÿ(uv8:ЮЦI/ЩЯ†дьTдлFї#”~˜x‚ƒ(cJ;!lХ|ВМŒ!IBмRД-Ь-lџѕ8kQ­N!W_|іEмcqˆІ Mр‹ № іa‡С$ Йт7ZT )QOhђћ&Bte-~яˆхЌм™ы–RsЈ™ф#в"†Ѕ‚ЌŸ(uа=‚YЂfЇbеHVe-0‰Ёє+Ў jХ–_cИ21SJГݘŽЈлв >н`џЃћ*­+w–bьvЛСРЯ#иl.ƒ"сЪYЄъЦ€WZTUЉЄы+нКuИtюRDПtDћnнд{вжмsъФXŠ,H ђејwЙјD@щЌk{W шь‹ MLHOХЬ]т\%КnќЅжTу›рJ№.ƒЪ~‹у‚mч„'lx}&œэјX%“.?yZrЕ*Іћ}нw­л3aЛaK[&фЪFИjбМ‰хШ›l^ЩЊЊвAџ69tѓЪЕ8‹АƒњЬPѕŽ =<э•4„kЦžіR’‚<Яwl =хтЅГnииЇЁЕУ‹YПФ9‹!9ckv*ж!РЁFTтљ'УёC‰ ^ Ilh/gЋЖІТЩwdJ~`Sг?HЧћo%ЅWTќвсОюc_+‘™џк|ПЫXž™уfŒ;”х З%с*іo“Ц‘'™ в№JV•Є4YпРуГ’‚’ИќгњсёЃ<<д`˜ИYqiIiЃњ№ђx~Є€@ЯО=уњЧёЯ5bOr{ЯBщЌ?cќњхщуЙЦФЙЮљЩ[ГSёЖ“r>Œwž}wVЇ№NЁУ\Ёщ~!4ОСNыdšН9§Sr•љеa#мЋПнШДjЯє|ТЖjЂв;Tю…(‡"PР‡Ѓќџ]˜sіœУ‡ž)} I‚Oрњ\ѓ0ЖћЃlћžˆ)iД3ФrС­ &ŸKЙ†‚^џOXшм-Нm„F?(и A$\з,ЂЮРаъ(ƒРє?MŸёђŒКjŽо6BућtьPW'­78T •^Зv№s н0 Q(Ъшm#4њЪ І9Š€Ўшm#Ш–Кv‘VF ј€€о6BЛ8TxZmџXКОХ‡ŽзVQВикЂЖjЂz"xкш=gЉѕЙFэФЁТVm6ФŒіЉС"P‡Їn­лˆќљgЮžКЇN ‰o…Њ|а/qЈ$&жё ДЮЗк8ЭjІг/–Ѕжm Фˆљ#мЦОхћTlф}C%5CжНЕ”C№ˆ9йKсQООдКр K-М„Фї8Tю f„8T$нcћ`UxjfjшНЁШЭљ gШS|шБТя чЦЭнљХNЌБУš“ŸdўЧє~Єwты‰р^#8вр? %„™lg)S+4U5ЄoЮ}Џ&!—№9•œRяє™‹‡3Щ;№ВБ}њGѕ?ѓ?JТZК•sW’шр€fblт˜IcВЯgg_ШnзБuЦ+.ееЉšџЉЎƒІ4•єˆюKн'оЅйriпуPA+ќa—T"%лЇяРОˆ†R‡і2ВЦЃŽ‚>}ќtпЧњ‚иђЩ @р Š›;љј‘у§BВfС„т”hдЃ8TКŒ5nФмЈъGš_ІEžqˆЋЩ8Tе–„sL%ы\Qвvp”7•љqЈ(лЧЅЦЁЙGdеѓVƒyр§ з,|яM>Šщ…М ‰ЋСЬџ&э’ЕчЯœЧRqО 2ўГх-R7я0ЮZ1ЋЯУ}xyК5n|ŒCхЏъФг‡ЊкЉиМ‡K2UUƒВ„я9œТ|„{4*q]ОЧЁkSЇecћРEhнОѕБЧррТоМzsо‘}єM[œ60†Р?pјР”y)}х'#А-L[Иzбj Rрƒ№Ќо“щ#‘ЌY№R–ўж#0ѓEZK•q.Фh*Х#Ћё=K‡JAšб( qЈd;C% e5Jh*љУNуPЩуBЙ‡Jц˜г8T2 PVcE€ЦЁjЌGžі›"P?ЂгmйЕйјjЫ@kГ"Њ›"@PDрвYЩ›ђ’zטٚЇЇGžђэфЙО”UжJs(5єЖCўTs'Т—Вjа<ŠE@љБ†ВМЏ9№j|Љk,л3фtћп_љпTcPEY…ФеŠі_ќчA_[_ћхћэETrлmЏсWLз~ЭДНЈЅуЋЎV=WНm„W"{'q +Аzuп МЃ=ќ’lРьетkc‘uєŒЋ42ПcXІЂ SЄ$OљZB$1ї>ъЏС…эcттzлОiЂJ +ОвdМЇ™3—ЋфрH Х§вXlЊ\JI[нё§rzе]ѓoЭ9џuщŠmeJ  ™“иЇSг?eIЉ/Ч7рч#АjУ}—€-IVVќPЦa/љ™ГV№†ZпQпс“‘ЁŸ<жњ“Ё­?СxћС%’ЂтфьЙ}J~œўлџ^М”?1~rиrbЮ!#Ін“‹є!%–щ[п q&ТtЊuŒ)PТтZФ дЂЎvњ = ЎN$­њ§ЊHНщ 9pcЯœEХјeYїFˆ/ЁqšсdУAФ)ѓ„A–@48Jч–UEВМ§ h?‚я XyЙЕnfфWЃџ)ујŽуh•1Fc%ц&јсF;Ѓ‘ ЊhЦ5ƒ[б‹ЙЮЦ+умkРZ™2р№Ч…нŸуяиэ.ЃФС9бЋчЖќяmЯMш”Оf0d?Юѕ,ЙGЗн6”[yл…Z–,Аџ@ўѓ“јshгzЕZдеіэкЕзЖ'‡†mл>|э;CТТ6(5ђѕFgЃЖэЩЁ‘oУ-mгц!8§@ЌZwƒ˜‰пЁ~>ШЊвж ЉTРћ #`ZкЗ4юк­Xіžцl3жињуƒ-Б3їЕd:7у'/С`ŒЭ‚8LRƒјIM7xЅJЉ Тx?B!†™зџ §МVC€џUƒ”џCŒ v“уIGч;“УVќl,СHDСЦ‡Жс/Гя.Y‰кяОw$ЉђћиАЩ"К› СN)SsƒXц@HJkЙІX‹GЕ…ŽВџ'шІD! žzРq™>M1n€Є‰ЎѓЭq&гC"C’ЯэЊdѕ‹™юGрvпбђ|Dќ+єЊЫl‡ЫРћAFkeХХŸ+О(ЊјWя2|SVqцFEAдV№3 [a‘ 9aBH~ч{„Л8&ЅФЬлЂшgїќўл Џ5mКFœхN“Z:wЊЊЅ]5UbyЏдŠ RКŒ<ЖDr&гCЖ”ЧѓAЛ*Y§bІо6w~qѕЕAџ€ЉJЧ­К•‘ЙЇ9FЦGZл53bdбѓNcH?‹љCEХЕŸсnT )ЛЅЏ9 ў[Џ ИѓNіЮжlњkе|ХТBо‚Œн)8˜}uIЕј”ф™kYм„MIхƒгЈlы3јZV’ZюdA( {ЅVI х8ќ™аšХ)GЮrЂЭіrОсТeкуљ ЄŠWфхІp‰xЉEЛИWяGЈЦАR|?тъЭfЭ~WЦќЮxБЌ‚љ™id„БРlf#†9KЧfЉ`J8<•ŸX•Ъ?ИšачFбДТлVЎњj№уќ‡6Ш6ѕЏ9ЏЇ yћpXњ•)_ХЦuЏЪaЦ>—§њЊ!G=m)ВЏz ЃJW– #Џ.ЫУќШє)ЮZ’W|5|XИ+&МR+.Hщz„Рž}…'Ч†оmВмАПД№9 бўW—УєіХятAпФуљ ЄЊhмі`RЮ‡ёЎѓђ§нYТ; Q~CЉuˆ‹xѕ~„И ї4wgАЕуяŠ›‹ПЋРьяјJ`­№dќсgјЋЮOєЈМsЗ‹пЦ^Г…ЕЇЯ <ЂEМF@іЩ…зZМ,€5]9‡==r”zЙ€і#д›ю)—§OyЋџ0­kO‡$wчџomбЄЌйяЌЭ‚ЪŒП+ƒЅhЧТ‰hІЄ'{єВWѓО8eщм.dн~ЌћМ’0хS*zл§Щ!cџѓ­АKИ*Щ;ђ3ж щоХŒo˜чЖФŽлП}‡тGEЭЂдkєЖ^ЭGд-ВАд(дэ!h<Е{ћDOdрs =сЃuQ<ђ~ФЅпд^ і”KПЙјЈŠЇPjŽР9Л–ВzћјО†–fљ]ІЎъѕ{GЈBŠ€Юшm#Ш7>uю$Њѓ{Нйщ9ызћвсГNО(Ёe!:Ÿ9zлˆККŸћН^ііFxrв.ыŠ€ЮЖ@ЉoђѓJвОѓ§~?WjRў|q +ˆ!Œ~ёюfИТЛŒШэ4Ў“’B UяUeЗ+Ч$ЪIrѕo@ EзЏ\П#’фщјQучLј”h0h94ž-Е‰о6їs}Ь„J +И{Nж„Йѕ(Чнr­рдTF›PЮЎьSЙЇ2ђ6bоЄy­Тr†ŒЎЖZD›*E№z5є1NlАЌг}з†лž‚Б Вљ™СТN˜м-+Ч)кˆ­+зЧќ1&*,*9!й^ЮЯПП„ JВwdypLTXфдЈg /:gsўурдљSM-MиA )4ƒ‹‚D,Lъ…=}aКАЄX|Ибxс4 Д›їYоГ=‹3чCЮ.gА!кRSЃ:FХєŒЩZЧп<„Э§LВќEшm#ќ>/ bXЙяjœyАЁЩ)ЁЇ‚ ІсqхW–_Й№ђ…Œ`~ЙVЌW(,-пšОѕт72?ЩЬОЭВьКдu'~#~ХфщЇ3іfdчy(zађyЫIѕчЯ_щдн9фqѕќyТЇПŒ†‡Хз­YŸga/О^ŒЄJkнO†Ѕг–Ц'ЦК’›Ж;эєзЇ%eЁЭњ“5+/+ѓHцщуЎ\й3MRжїЄо6BW?ТћVю€Т4Y7,7,EЛоЫtsь8№ъUО')Lј…+Auоw№Ѓ3BRЂZђzСѕ‘}GКXЪLUЖР`Мг&Пo‚с 1 ZќО‰KЅы–RsЈ™ДзљѕKНjiђІф-olйКСx‡qжŠY}Ў”кФЪЭкЯ4ЁH хѓЗЪ4бгPŒCчˆAZЂдXо48ЌќвГэЬ"ІкБ“яpлЛкfШ€ƒ Ÿэ‰л­[‡Kч.Eєуc‚hп­›Ї4Пюhkna)Д+йRdAвйІ ЦnЗУUDвfуCЩnснУ—m\†,LL,§ћвНЇїŠХкоUMЙху™&шQ'єkш:ЁоuхмqЇVeŽ~:щ#ВƒNЛ='Е2;Й2Лз.>ЮЖŠJИ$ђёiF>72eN ЮИ…пbк’iбМ‰хš…а*ПКyхZл vCŸЊ"LГAЃ‡ЇН’†СіД—в$ ы~_ї]ыvСLрhІ-HZ+9p’^+tњ’џЄœФ ЇЪacЪ…lЅ3M№ б`§еVjа^ЧєљЯ51нШoСЌЉЉХG2‚Ыb: иК‘аќ2ЊFНРэHx&сfбѕ6:Ц'8ЭJьп&2г тiKїђбcЃK JтђJ†ЧЂ>н! @NмЌИДЄДQ}јЃ6xф`$I#чП6љ‹Ы3–gД k;nЦИCYЮјЗ’“сбЈG“&$]О|ЙcчŽKоY(щрЄ9“№\cTФ(ŒDbџ{єЃЃD@щL“ї1)‡*Tљ-#ы#Г>*ЉAqЏъ:tjkФФ ЊoVЋЕЈИhЫб-`/xfAYYйкCkЋ‹аE ў pЮˆqЈ”ЦџЕЋWѕЎ=шљЪЏр0w)?жЈэОP§=h,ѓ~ŸЙzхjQQ‘ž‡ŠжEЈ= АЫъoАѓ’оzхGHЪЪ&ї~[mцYV†2)ѕѓ]aцаPKaЁЄЭдB“Цˆ@hhXh;љрOдhŒ'э3EРw‚ШP?Т+)Gћ\мДШЁіьy "cьQŽ=}cЙ!UKгz€о6ТяѓQіЅ^эeїng_žК}Па3!6єхЩс/НРяХЅцЩ3™М/56ЖжХ\ kН*WuRЉЋzJЉ" 2gЉЗа~OVэ‘з™ОдЋНl+Г!ь.–mЪПxл#œ57eТлs\WФДщg^šюuГkЛ@}ЙnыK;kћxеЊ~2gщ^…о6Bћ=йН­Оp|ЉзЋВls™–Ѕœљч)kиНЖ!ƒ,uЕБ&ж"})Ы—љЅЌњŸ>VЁ§ТЦкч˜ЮQи AЖR_к‰7˜Ч<0F{cd …‰*Ш.ЖльЩг’љаŒСRn!ыlnоЬq3aќд„TМd-d‰ Шhд#л6qE*s–zлэїdq|Ї}ЉW{й’R{Щ-;YKіщцТOLz&7s ѓљОZ^A>gю{g–!юBo}ž{JˆАтЏ^fЎЮФКiSбCцnЫR’R№ТnізйЛŽя*ўЁ8чƒЂaчкїў2љ/йљй™G3!ЦХ3Лkж‚Œ=а,л6I˜Г”ЖдлFxuO–єС—Є/ѕj/›§Ѕээ/˜›Ž№TХх\Г!lfЦl6ВЬеЯ 2 =д{Х?Љ/К" w? Х…$–.ˆ_€люH &,nGШо”5ц˜Ш6‘|…@FšєШЫ‚JЁ,hїhH$Пb1oуn eХ1ё1О:Fa њ…5’јхЛщиФ,”:~шјЈЩќ2Š:йrф&$% vЗ$ЭXЖ§u,ЧzPФ›˜М`ђљмѓюЭг‘L‹wЭ^qєЖкяЩ^uУЃА/ѕzUжXр‹СЪ Ќ+&лVLА-{оВ3ƒ1UeЉД7=DСЫњ:+ѓ_™ˆRЅ"IВcЧL“}>1ЏкulёJ†Pфє™‹‡3s‹rСQ d$Ћщ‘ –%! ‰мQ%З/ПФн‚м{”ЩZb]џњz\{ƒcяћЧ>ЁI ‡?3œФцxgё;гMcє~Ф/ДEJШF;“{І[?™оF$Sв#m„\:€ц,Еп“х:Rsž/ѕzQ6ШР6e0ЌРж,э8€УЎНнˆ84‡By,Их“-ˆ4лbвФЭ|ќШqЁHТB^I*2„UєШЫBAСЏж IV•Jм-Ё Ё Ф™§ œ˜‰1Лзяv.ЌЎdvoо="žt6їl™ЕlРАтт:г‘GІ-Kƒkƒ„{T1Ф1]НhѕМ•ѓмІ‚ŒЛАŠwaYN ЬYzuO–эIݘОдKЪ*§VožЉэВКМ4ХGjc&\ ‰вљпфЯ9Ž7МёAw*Нщ $rЃШHаЄЂ‡м!ЩJ‘ы‰†„`жyXЉХеA?!dU‘И[D@Kм-qD&ю /ЖякўиЧЧ ПНњє"а­N^=ѓЅ™’6шœLX–РYЙшˆшбŒnнЖu !іŒЃgOž77y]Ва)qѓД#ЃЎGЌS‰V™Гдл ѓтžЌд›ё}Љ—”Uњ7'kсьї–gфy†[ўдХ ‚шсУYШ)ТЅ\!œQвЄ9гЯ^ёШ јИРЕф*"Ђ” "ѕђbТЧhHоЦнЊющ.gИ' И6ПО.УŽu;цЏ˜Ošwљ›ЫЯ}^h*L˜Ќc"дW.)#‰hЦ„eџ§…ZŽ8ЖfбЊфЬ•B%0Х„Fd<ъыTЁe',!Oч#T@ѓ: Ў§€о\x;Ор€ћИ>нНж€лшЏ" IDATјEgфизH(ЏЮЈЂ‚1АќP%eAŠ /!” bѕђ pЩ‘ЄR4$IЈ%qY1­wKЈB,Я‡{ЊТ§"Y‘eeй™йЭšВЁ]œыШlљ…˜ў•bbЈ0w$oуђў>48kSжšХkR?Hw7BЏЕ ЃEЉQђ+žх•dI’zл_юч’І{•дЇоќ‹Lфc6ьЧј‰BF=)л~Ф/b›† тP\џИžїїlbtJ!œбч}7aJЬ”ž§{ eІ-Фh6242!&ђ_B QHˆCэР8qqALЃA^L RЯО=w+ЊCdвД$„T"Й$д’pЦ‹‹ˆiФнъкЛтnaякЏ—ЧИ[Ј рŒКz„~ ЊЦ§u\ЪМ”1SŸ8:ш)щЌ@ hэ”ЧуЂЛEяйє^jfЊЙs ™6/ cДБ}ЧaќТŽHЌ-z Vh’@ф}ЩBиTц,i*%?АЬнЁLЫ\ЫЯ§ФЄžєXžлЭ;wч;=J6œтuт4<„ёЁ c& qЈ`#0g‰™їѕ#ќ|є[„0-ўрвЉžtЩ‰ЈѕKжУФ›xn7h„ќќ‚Hœ’š pќз#0”W™ГдлFјђ|Ё&HT•бЇо[LЅч KПЪz–Ÿ…ROV5MњЗUXЋб§G#z*|i!tЊTˆІ)О!рюŸ*НgЉїXУЗ~бвŠ€џаѓ–њўCœjЂд[Tц,ѕЖњ<_p?RuUЏ{K(‡"˜аї, ѓРаVQšГЌЋћЙпыЭNЯYŸ(ь@у!Чc<’TЌБ!P'ч†вœЅоc }ž/ИŸR~Џ—НнНЪiМдьЊЎY)QnАы5ђфŸ9{FŒц‰S'Фw@У•ПTиi\'qzUяUeЗЪTмГpBh|џG8u4ЪЛзE9:#PГ#UГRЕб5ЬYB-FюЪѕЖИŸћнэwя80#цѓ „%лОхћTl„{N–”OZrјnА|žЯ\rъ–Тg}TEР3dЮВ‘Нg‰…ЬюЛgЌx‰=cdѓ3ƒ…0 †уm„/q™„J)Q :йp[yŸх=ћиГQa‘c#ФуJсDХъ/>ьeЯкwм§\чњ‹ 9KПЯ Јaє+УИяjœyАЁЩ)ЁЇ‚ ІсqхW–_Й№ђ…Œ`~1 ‚VVРЩm>Цe’SIyѕ йp[KЇ-OŒ?t%7mwкщЏЅЦ”…ЩžKЕ„…вœЅоc }ˆћR]!ЬР1Wfє!Ы0 џ†хWnн•Е‹QUƒИLi;вHˆ—)‰SтХЭxe† DL . Л2zђшŒхЎ0sbJз;dЋбhДZЌX†ƒр sSцJ:…@aiЛз!Ж%ј KŽ~t”h?—$ §˜длFш6сРˆ17Њ:Xќш€ДAќ[]†yђЉђ=I‰`‚Р/\ "pЈѓОƒЈЈрдm‰ЫфвЉŒБl\&WAJеOdkђІф-olйКСx‡qжŠYx+юœR 0эч’X[ шšГдг 1ьнё"mџКЫР:№ІСaWb;ГˆЉvdнЫёу2Щ+ЅмzŽbЩ,лИ РФФвП/н{zЏИCJТє<—eЮRзљёA№†wjU†сшЇ“>";шДлsR+Г“+Г{эŠ'š**с’TШjѕ1.“ЌNЪЌя$'$# ˆ3 шџЄНQ Іt.IЫћœV™ГTіƒ}ЎUVn~оƒ8єц!ї6€яЮsNЏcњ‡ќ€чšјt ПГІІ68„ bL,[|НиК•qђ&‚A\& .гЭЂыm:uŒOpš— СŽ=>ІЛ сQ^м~J&Я•4!щђхЫ;w\ђЮBI#P Я5 #‘иПХ ѓJч’ЄИ_’юO=‰ZНз†ы;с‚ЮЋzЇкњЮжАЎђЪjЕm9КЉЯ,(++[{h­D†&)ѕmkУЌ!9N^љ/kzОђ+8Ь]*8’Кi’"№ЈЬYвѕ5ХХб(Ў\*?uМ!и€Ы•ѓWДы  9Kэїdэнг"щKН^•5VИУbАВыŠЩЖlЫžЗьЬ`LUY* ЦMQ№ВОЮЪќWІpP‘OŒM3i ю'йВлulёŠ+PЭщ33gцхЂИR˜#AГšžЇ3іfdчy(zађyЫ…"!+‰ј’л l€&AFJpяЭЪЫВ–XзПОзор˜Сћўс &zј3УI|WyкЂiŒоЏ *vхъy[p&їLЗ~нЫИe?њ5њŽЈv0”Щг’ћ9Qч<“@H…DщќoђgŽœ‰ћ МёAw*НY*d’`y$ЉцHVбCnШ„™э‰•„`жyЮ`A­„№ЈJ"/›цс€њ™аvЁэЛЖ?іё1ајэеЇnuђъ™/Э”UЂ3aYgхЂ#ЂG?2Кuлж-Ь-ФUŸ=yvnммфuЩBЇФЙJt“п7IXрП`8C$Sf.6zи‘kGАƒ@RIƒ,_щ=KН0/юЩВ§Ј)г—zIYЅ_q‹ВжЮ~oyіAžїhИхO]М№ ˆžЖц˜b Ї8—ђ SќUЪ0˜ЈјI“цL[<{Х#+p‡‡‰ˆ%&”Т 2ѕђbBЯXIЈ3vфŠ>шi \›__ —aЧКѓWЬ'ЬЫп\~~шѓBSaТdA 6ИrIID3&,ћь/дrьРБ5‹V%gЎDˆ*Љ…шжM~`r2їќВw_'+ЬGDuиЊE›GъGx„Ш Иіzsсэј"юуњtїЂ,4zxЦ+iАив^IЪwПЏћЎuЛ`&l7li \ќŠ ЦРТtpСр› /!”Т bѕђ pЩ‘ЄRЌЄЭ›XЎ‰ЬœИА6ZЈB,X№№ј _$+"2ЂЌЌ";3ЛYS6Д‹sm™ !Пгп@ RLЌтсРхЩлИ|у„ПO Юк”Еfёšдвн „lЏI)ђ;tмPзј%9m№0чша­ƒk>"}+’B):hЮв—ћЙасњд›‘‰|Ь†§˜УћSOЪі"nVл4ёˆтњЧѕМПgЃSjўkѓ?џшsИ SbІєьпS(Л0m!FГ‘Ё‘ 1 јaŽBBjЦ‰‹ bѕђbБ’zіэ‰И[Q"“І%!рЩ%qЗ<ž† Б~ КЮЈћGЁGш—;юЏуRцЅŒ™њœРб™/hZ;хёИшnб{6Н—š™jnчHІЭKУmlпБDПА#ю T d№6†-ЃћŽО?yIHN$чЏ™*їTtзhьЇNžZМfБЛBpФЊФJs–4•%_iXцюP&ˆeЎхч~bROzЌ Яэ№|ч;=J6œпuт4L„ЋЧЁ"kУнпЄв{ЌЁЯ§м§ˆъVo‹ІХ\ѕЋ']r"j§’ѕ˜Ч›xn7h„ќќ‚Hœ’џ  4gЉЗ№хљ‚/HшSяŽ-Івs…Ѕ_хG=ЫЯBЉ'•Кг*ЌмШQ}x_C%1ЪЇшƒ€оc }zEkЁP<# kаx–^ЌнєŒ,• 4D”ц,щћ ёhг>QМD€ЦГЄ~„—Ї o|ЪœЅnЯ$‡ияѕfЇчЌO\/Љ…$ё|N–O™ ПtП(є‹њ\Ѓ†ч-{{ вbD@х=Ы;‘ џЬй3тƒqтд $ёНЯ№aŠЏЧwзI\D…^е{Uй­2šEЈ_9KїwЈєЖxOСяnПь‘€1Ÿ_ ,йі-пЇb# мsВЄ„|вz”Уwƒхѓ(—"Pп 9K} „ѓauЖћЎэрэљ Л ›Ÿ,ь„‰H0xU^'*™є…ЉQЃАЇ/L—]X-_rы/J])Id-ЁыВ|,о“<†Гk§ђѕЩг9 Ц%„ШϘ dXѓ&с‹“2gЉЯћŽЮžџЪ0юЛж!49%tтTФ4@0<ЎќЪђ+^Оœ‡$‚VVРЉnˆўT|нšѕyітыХHЊŠгЬ†€€вAWтЃЯ’ШZ В|Ѕˆa[гз_ћюZц'™ЛОЮЖўh”€Шћ,oЮЈ9ГV,ŒŽ‹ѓ5вzЯYъъG0ЬОд}т]#(b1˜ВƒyУrУRTАыНLБ€ (Iњ$DB0(ašе0P:шJ|єк=ВB–Џ1ьРЧЩцˆ6щ%зrXФ]§їЅ+п[йgP„hЮRЗљмˆЙQеqсGЄ тпъ2Ь“O•яIтзл‚Р/\ "pЈѓОƒЈЈр™‰‰>yнR*Ф‚&ЩШQVB@щ +ёбuЅ“D–ˆak—Ќ=цќ/$ь]еŒЂ8‚™Юэщл‡юЅB,Cш@™Гдг 1ьнБ mџКЫР:№ІСaрGэЬ"FЭKе№AЅФA“ЊЧ)“Jгtƒ@@щ +ёбщj'IUd-%ОRФ0>д"˜Й}PёŠЇ<=…5…Ј 9K]ч#jzЮ;Е*УpєгI‘tкэ9Љ•йЩ•йНvХ­•pI*дk@P)>hвMіД—вT—ЇЙ ЅƒЎФG—e#k)ё•"† ћ4Ю1>цUЙс$ж4у§ŒлdН-ШdЁ4gYхЉHФk-Љ›ї НyШНрЛ3Хœгы˜ў!?рЙ&"ѓ[0kjj`ƒCи ЦФ˜z„ЖЎAeœС`ewZRVyC~№ШСtЁЗч†J+t%>p ‘Е*И |@YK–O"†!†ТˆŽ›1юа{Ю“,з/O{,ŽЉЌ˜8з5§0i{вžNр~х„…iЧ_яЕсњЮGИp№ЊоЉCЇЖОГ5ьƒЋМƒВZ­EХE[ŽnAjС3 ЪЪЪжZ+‘ЁIŠ€WрйgEжвЖ6МСњ’уф•џВі ч+VЛЄšЄд_”ц,ѕ~іYWѓ~Џїъ•ЋEEEѕї„ -ЇˆPљѕ#Ф@yAя§vЏвT”" €@ 4мкуОRƒˆP?Т *Ъ PDшm#МšЕгWВЎъѕЕнДL^0…Дm•ЬіѕЛGЧ–ђцр?N?Ћ-Аƒ@Вf2юЅd92gЉ§ž,л3}ЉзЋВFgЌ ‹СЪ Ќ+&лVLА-{оВ3ƒ1UeЉєЗJDСЫњ:+ѓ_™CЄ"IВ”Ђ!їє™‹‡3s‹rAУЕўdЭЪЫЪ<’yњИŒZ5='Nc}qvў‘‡Ђ-ŸЗ\ЅI*Ё–dKIт,L,jкї}‚0шсЯ |!yкЂiŒо/§ mёq&їLЗ~н$Šr>Шщ5АЌ€„фљѓW:uяDј ЎžwГ/кdм5ЛshЮRћ=йНОp|Љз‹ВAЖ)ƒaЖf!˜|А vэ-GЌЊ)/'˜Тy,Ј•ђzˆЈ5rWЋЂ'19g0ю„Ѓ'>їе9ЁЌЛ_­jЩ]˜o!zкм„бКPœ˜‰1ЛзяvўЌdvoо="žчs6їl™ЕlРАBэѕŽ€ Жzбъy+чIZО§­cў:FТ$ID‘1;ЇЗ@”’ 2еEЕШT/Ё˜RšГЄѓА ФPњФ„žіэВzAgJMЁЋdeФLD%š9r&№сн=ЈєfЉ+О5ёjЋЂШЊUбCnуP 3Ёо)•PKBЋФ„ИIh!ВBл…ЖякўиЧЧ@уЗWŸ^ЄЕЋ“WЯ|iІИl§ЂЯž<;7nnђКdЁЫЄ§Чkso{єZЖ;M~пС HˆПoт.ІEЦН”WНm„їdЏњсIи—zIYЅ_qЭYы O„[VОЪѓ ЗМы…Aє№бŠŠ,„>Ф`Њ‚№1НOќ"*бSЯ?•}&7ъ#зŽ(]У|ЂB9ЕUŠ4ъЉ—џKB-‘<4IyЙ*ЎИIh!a™4цƒM;@яXЗCИС^ўцђѓCŸ‡$гТЄF•І€ў CАlвKЩ›’нЦэHлјьŒg•Zп­[‡Kч.‘\эЛIЧ)Шв"ЃЄ_Ь 9KЏЦіт>јHыS/\ћНЙ№v|cмЧѕщюuЋ­(ЁЋТ хЛпз}зК]04”ЖРХWŠJ$$Ф ЇБ жK’‹ЄF=т‚юЊJЈ%waЈ’ПQVV(яЭšВЁ]œ7X2-O~QPvф"n[раcПfёšдвн ТUГwУя —ДVРъБ‘C7Џ\‹#ŽФаg† ’^ЩЅФ„xn˜№eЮв—ћЙИ‡овњд›‘‰|Ь†§?QШЈ'eЛ€hElгQЃтњЧѕМПgЃSjўkѓ?џшѓAэM‰™вГOЁ,‰J™“y/!н($ФЁv`œИИ ІQ /K ё!Aм-ь!­B”˜$ЮвЈћGЁmтјKуў:.e^ژЉЯ ’ѕ‚РuK.]@ГгцЅс…ŽБ}Ч&~№Н7пћЫ j}ŒнЕwЏИЃАwэзkШш!ю8h‘A)ЁI‘ї%џ aS™ГЄqЈ”ќ@Р:0w‡2A,s-?ї“zвc}xк7wьм_ьє(YpВж#w >"Ќоf|j֘Щ9‡==Rце qY:!FУt‹ІХ\zд“.9…€Ѕ№1(РгОA#‰r(I№Ч?9ЎQ—о6BŸyїЮыSяŽ-Івs…Ѕ_хG=Ы2е“ю$œVa­FїЭЛы!žнu%%”OPG@тŸЊЬYъ§JŠ>ѓюшшSoh(ƒ!†Ѓvў!‚zвН‘„ƒЎеь›kJ “Ov\h<ЫТ@;$Д=РA@eЮ’њs˜hK(u‰gI§ˆК<џhнѕНч,ѕ™p?~Џ7;=g}Ђы‹iю5zфрсŸG*POЈwWeЮRoЁЯѓїЫяѕВЗЛWB9zŒ€в{– v>"џ@ў™ГgФGьФЉHт{ŸсУЄoП bЦ9—т %bUяUeЗЪ”reљпRŠ\$Ћ“2)~As–f<‡“лєЖИŸћнэ—ы1b>ПЌXВэ[ОOХF@ИчdI љЄѕ(‡яЫчљЦ%‘‹zlъС•s™i™ˆ\єњіз}SIKS<# 4gЉЗаЧ@8ёЈбъlRvЯ|@˜'Ÿ*'ЩќLW|˜№8ž‰H0Їh#ЖЎ\џўЛћ+~Ўˆ|22qY"џ“*љ^ Шо‘Н=}ћЭЂы:uœŸ–L–0!rЉkБЙ(:<š$щo@#€H_ Sя>ŒИ•БSc…Ітˆ'О‘HŽr›Є.((,иўЦЦЂЧA_“z/ї&'†PJ8CNzлнќг_k, Dhr SјУž kЛоr*iјЈK‰Г[nXІ”їAаЪ Д5}ыХo.d~’‰PTiЩiыRзЭxeŽ:ЮЩБG &„xbM,жt"ФгкНвoЫF.ЊaЏhБкD@ˆє…JRfІˆЋ:§™ѓ(ялИoњ˜щ‘GІНЯt$—ЯvtсФ@аЪO?ўT\\s–Ј#їъєЖКњ Г/еј 1WfєсŠ˜CМТЙaЙС•[weэbTеиq mG ё2%qJм 8иБNFˆ'С!ž2–g|BШEiџp­—аdр €H_iЛз‘˜зЋuєЃЃBлRСS+mqZТ2Qђеjїь—g?иђСYoeѕ$”оГдлFшъG0мˆЙQеQцGЄ тпъ2ќcOR"˜dЌ! 4uоw№ЃœКРZр‘}Eс›•1V ё„ШEЫІ.C`Iф"ISi2@P‰є%D фy1LЕЄШХ2пеs—ЅьLтгщйЕšГдг 1ьн&mџКЫР:№ІС1 !Ил™ELwY)Їэ]m3dˆCХI%<ЅЙhЭЂUЩ™+н“x*Jѓыщ‹єjФД5Ы|“&$-x3Y6’ 6ОJЪœЅО~D QwjеРћ0“\ХЙJDсЇ(ї|АчдшШЈЈDЊТ%!Ђ№ ˆ”9)p8qМqsиђж–ЄД$фЗhоФrЭbnч!J%"э^Л‘‹”ТŠЊЂd  @"}%ЎNФ,XкKеFZš8яЙyуў>Ю=&•–ВЕ-ЃьзNЭКљxта›2>_НgЇз1§C~РsM–lСЌЉЉ aƒЫ_/†ЖЎAeœМ‰`FНРэHx&,кtъŸOjŒ§лЄёCЦ#Б0AEј’_CyЯŽ IDATD.‘‹ў‘!nЊРЁD !€8Zј‚ ˆёЯ5ў+žавдs_œУўЪ__!Тъgˆ…оЪЈЬYв8T2`N:Еѕ­a"$yVЋЕЈИhЫб-р/xfAYYйкCk%24IЈ7œГ qЈ`#0g зе}Фб`§ЩqђЪY{аѓ•_СaюRС‘дM“€G@eЮ’ЎзЈсбЛzхjQQQ гbРC„ЛfR?Ђ†ЧjяЗ{kX’Ѓд+ЈQЏm,E v Ес^Э јКЊз] Њ(ЕŠ€вкpъGx†яtxrH2‘Cэйѓ ‘1і(ЧžО‰БмаЈƒŠQъЬY*НCч#<э>ШоэьЫSЬ7F?nHˆ С €?:ЫMžiY8ƒщгЯsu:HИЏ.kЈ•ъаЏS…ь„%zG§Я‡XЛбЪlЛ‹e›ђЏхїgЭM™№іФU1mњ™—І{ЎKg Щ’dkз^]}iЇіе#IНm„і{ВAєЅ^ЏЪВAМРf)gўyЪvЏmШ ЫC]mX l ‘О”E$ы№ЗVпчгxa#южЬq3ЃТЂbў“šŠ• ю€јвN|yЬc46ЦНjэTAvq|r-yZrTGОw diщ5„eu‚_ј}с‚  vLߘœrˆZ|‡}ь…„№YvЁRтzХќšГд~OwРwк—zЕ—-)Е—мВ“ЕdŸ^a.ќФЄgr3—0Ÿ_1ƒ˜ +Пъ”nHм­ьќьЬЃ™Ц#тnI|LfЎЮФ •h)CцnЫR’R№ТnізйЛŽя*ўЁXИž5іZV'.~|і‰БOdŸЯN;АQHHѓOLьвЏWі™lь]zїZќзХюЭз+Щ ”9KЏюЩ’>ј’єЅ^эeГПДН§sгa ŠЫЙfB.иЬŒйld™ЋŸd:zќПіЎЊЊ*mVЎХEc&бqpќImјdB›I”Іq"ˆIE •Е›V Zˆ˜ TкQBќ H+ˆ&Eэњ*1WІRКЬd4~ŽЃЮ2Ё/хВЦпsи—}ї=їмЮНpї]gоНїЛпНїГ7ћьŸГŸЃ] +zЖH|ьФ$UoЌІO?*шд‰#†K3Фч žУxАа‡0jЗTЇ§6)ЖЌ,IйvГ4КьlЏMЛ/-~`ьSёГ@i! №nс9‰<ф›ѓ[oДТ‡XЦ&O№nЩMwkЬяЧр@ ШРЛuЊю”< j`гЁ\xPУ‰;ХњрLнЁН‡Rц‰'h|ђЋл]gЮ5ƒ„=ліlh”кi>Ы_-ЭШЩїр8€†sƒYkВH”sg.ЭxjŽ–уšБpЦЙSчфІиtйP5KЃчњŸЩl<—=IзЅИ!Єv ЁКоиДz^ѓъ™ЭO\yЇTэв(z`СЋ>V]ёq}>hшgOЯN››†чIэзЕƒ†і+]a'ЊЉџъtщўŠКKuˆNY’*TдВ=vXГZvкЩВjмŸВ,6‘)яђ€g&xЗрOžЈ’Ч снв0Ѕ‡w F0тЈ>RнtЙЉl]ўї&&MмљЎLђфЧ&n|Wyў ѓ UP’ЭчлSі*щ)5U†pшгc(;ž"ш(1‘Ё§cьфиЪ’JєбИ РЩЦr*ЋНgitЁџ™ьДH.)x’Ў q{›z ˜Vрз' Є—­ССV\њГ :ЃЬх"O~цхfЇпќшЭшпEуy‚GGzжМCьƒ6/3УБГА†5.Z—›еАВ,pa eќт$KЧерн2ПДDдщ о­§;їS‰ fŠЈо­%//ЁБhд[UЛр“4'ЉІЌc ёwKЈйZЦ'ˆ'ъN\oК>.a\{€on"3]џЦИ \ћўІ$ђRKфЮkWЎo<_ѕqІ0ш”1!:@u7(—X)šэ‡Ъ“`}Œю#\z&ГѕPі$]Wэю˜БVвAˆžЄЩ:;u‰tF§ћ5*hФjјВaQВИL…Axм/уЎ}w*Г$7,ID_Уy C н„bЁя2€+aDZ0ЭƒDа0о­ЌєЌќЮyЗ(1№AЙ6іџz№СП„ŒћЈ1Ѓtkѓз.zq‘$;СLgmВ&F'Іў!Еп€~с}Уй ш/5ЋчO{š—кч/˜Юа5‹ђRœ?€ œl,V&щВ>k–эЩЗLLАUФЈ!іѕˆтJ8i,ŠЄZК~ДfщЩѓœи јtN Бšql§i;K‘О8нд; tFщcгcFЧє БiхМšѓй‡Ÿa˜™”36†Ц]fYЖі…ЕБ‘Бц$3єЉПDKRXXЛйёщltЊІгеg№nХмо­ј!БЙѓsˆ€„о-к:й(Ќ о-ЬVРЛMrс?ŠUШH рЄŒNA‰P.:эЩik–ЌI{j6ѕ1X ™GЂT€Œмf>˜ž•јС–З‹*Š(SЁЮRSST€ЭILТД%uljтшD|фХœŸMJšГ>чxнёФ_'т:~єxоњ<тЯойtYШjk–œ‡J”GNєТ/#…&с|CнGЁкNЇ)aплря~ЧЉfр(р_ХјљBЗ…—сЁв(Ѓбs cžчђ–nx˜ў3{њкNЛ#•­,У8&иЗ‹›ЂМОРЈs‘#р4ж,ю#<й_№ cвнўfшЕ“Ў}б?KќьАЖS­8#0ŒL#ŽЅ1ѕPSуўя" іžЅбs я–Š[уpмGРqЎAО.?§ЩЧю#ЬcrКjk–Fї†­ H*ЯWщJВС.‡€б}„1ыђj№UКђœpŽ€" БfЩпГTЎЏЂЬ2х€vпЌRћЖМ†šЮ ОŸЇ(ЎЦ"рѕfЃіžЅб}žч>іЛ”.:ˆMЅ/Гѕ!‘чd>янn‚иїz­KВЭ54ОСctс“ИИ‘nsv"жNo›- єзжжFeEџъФ/#Ž‹ХЉzўRQŸzђЗƒ(]Nш§Л|Gƒд_ал\i;гджhuвAsфŒ@Хgе8КkЩВЏа›зуј Fїn<ЯН‚•щОѕЇЖїRФЁЖЁэгF]]ƒ$Ћ"YCЎЙю@ћс „нŠ—ХˆЧUМЌX~Юš@TV(2;%ˆЧ!DХpзЃіq‚ #„ё‰zrСWŠУ­AХК†‚„GKžgшАbv›эЊ'‰.чƒџ‘OŽЬš0 bрўкWeуМ„?U&qЩ]cЭвш>ТWћ nЄ;§oAV‹ГŒФaAущ4<,h ЩaоСЂьTдП.6UVы_џЇZ”ЪтВѓпœЏјЈЂъXmг?› 6{бŸ7ПК™ъ—[ЪЇ?5чСЉ|ˆ™$’С#Щ†F]KxДГЭrˆ)*АžŠ<`PX5UFvЦоsu–K§1љЋЬЌіžЅб}„ЯsIIмszžЎKs ’IёќrО%6ютi8 (ИЁдЪВ{{Лf;ГгмХ=”ши1!? !C œТ>ўбЁ)3EЊ%ўѓO4ъZЮЃ%/Ы!&•јЈё€…„„4]iТСа‘PЮKV™ЕуGgУнxžГ%q[&щЊнЭВs}.Ю50 Ф•roŠxtЗаvtїт•kr%ХЄY6*Њ0ћщй›зˆC PžN[8‡№ЭаP.јu­Ї АbNЫЅЦ–П%џ№'‡г'ЄcЎyБУ*K,ЋНgXћd4!ПKР"NЬ5 `_s VСщО”w(DŽ)–CЩ‘ЖŒMBЄUЄДŽ‰ГaЭЌS?ђuжЋ6j#6—§Кvh@D@mЭ’#Б5№2s$hœ чу VмЩPј{–‘њk^›„ŠиёЗ §ЅуšнУЖQžkИДПрХКt5]ЇŠюА0Оa˜žЈ Яš­5йЋГЗ•l#}эКASS+2їїgќhЭвчЙWu/нЖњфЖƒЌџ}ŸѕныцжзЎ33ц‚ьšM5т‰ЅЮсѕщг=HŸ;њаCЛJŠмЏk @†ИAЬД чќ“‡ YV[ГфћZ­0(І&hмGІ?6=VoЪh4=§o-m& Q‹з..œ_('Єƒж[>xdЮ#™љd&Л$dˆ;vE*5шю#м{žЋх^ПП{щЖ5fД}міХӘbKŠбїD7Њr§d7‰ bˆSЧNMš"žнФ2|є›хš].ЧCхGgУБПр“:&щЊнеВд`ймАЉІсэ=PРкЙд”хўsŸŸћйџo8кРэ,пyэъЕиўтИwШ№aИм шŠ1uык­œ]JKзrЊ›пп$Ы–рЁТƒ„c(ХФф‰pвтЊkЫФЄ‰тјбйцЧЬп]КијPТCuіьйЁ#†Ву •Ц{–|_CЕІа(ўT#№Ž@WFР_ж,Бсо6Є‡рЛšЎ6•‡™сб9ў†€Цš%_PЈ,~ІSюх ќhЂ!+ŽŸЅбs.ДЏ!У{pЃћŸL4PБОJ7л/sD€Пg)јjќв[ Яr€"р/k–ОzžЛš.Ж?C“ XСд"XCЁE0…жA€џТвкŽxБ§яnЃњбšЅЋћ оЊ—в-Ю,sЪCe№КІw„ЗPхvКўВfщъѓм[uрRК,_аД \.ћпі!†н)‘ФУZэWќајEгЉБHHbIœАРњјѓz8›Я€•%ѕеp0zЭвWыnЄ‹оaСу'їžйUўжіЗюшyљГэF€i\Е_ео?vTafЎЖ2хј?ZГtщyюEр\JЋш ž{bСЏњі;д\ѓЫЄpN|њеKWёцЅў\i&eоŒsgЮŠQ䉉XƒфqDяєщФ ЕлkгюK‹ћTќЌ Ї/ш­­­EЯaф’“І#ЊЯчr'! Џ/ъі[*Е5K>ŽPh6˜kДmk{eЫ_7я ОЉь8B!Ž’WыжЪ’Ъ!wD 1‘<*™YСˆ<ДўѓњвЅЕ юOŒ+\RH*жVXhЊ>V]ёqфБИOч! Џ/ъFэT|ZQ}ЄКщrS™Œ‚ˆdВўЋгЅћ+ъ.ещЩseqхщ/ПЎјЈЂіыZ“ЩДБh#‰ЕjўЊŒьŒНчъ,5–њcЖ&С*ГЦБf‰3ЪЌ•ю#\zžг\z.И”.Цјѕъ!\ъб`ъeKœG[€в_4uK$ŒйЕm—pЋezжм”'RШ3„мI[СI;М$щмйлћШX”1)uЩПwn лЪj@фЄЄр%[^T[Гj‰Щ‰ W,$ЭNуšх]Ж‰МvV йзРџ9ЙVжЮZkГам$ќpYы‚Т ећаЇ‡тЇЦГ‰РyшЃCдG›ˆeьaщ}*‹ЫЮsД?UЧj›ў)ІNњмщУD‘ˆІЫ…nŒРОїї?J~R[RdЗ‰Њ:ЉYњžЯrgбN\€‰ ШфЮVќѓпhjНa•^ЭжV\№яM­­tBjd`ћa}сЄ №зfb{XzŸнлwAУŠЙ/*яГ(RБ9сrwE`л_7Ї=™цДtnUu^ГT;nШ\CАNЩŸч;‹іЁ§л6тЗГ№j6{w@жŠ^рКmž‚lbТвУ*м2‰C22y!y‡Ъ/ќіp5А=:œс}эЌtaB‘ˆ0іиmw@Х2>йC%PНљк››Š6…ќ$dёъХc~?Ц1œЛК'wьч`5bHЖЬnUyГYоўš%_ЎY"жŽѕ‰LЮnАwšcQГG„щЦyСzѕ”ЪІ>Bx˜дГУ=6nєоіІЬГ/|Т9vќиŽp'Œ@Œ=4ŽШфгЮјдС8Ц„иEE {0—К)л-›-еS8З‰ЊМй,+ЊиЌЊ­YВб‘‘јХЋо*{… VЋ€Ё„ЦѕƒекЫЦ(З2ѓ™L,IюЋЊ?5.pЮ|v&едfb{XzŸ„Ч‘hЃ`ЧБ‰5 ‘"M— н,T›~2ьnе}ЖдnUп,;аlіН*у=ˆНЏ+lУпI:}Д жАмаN1KчlЙ1с[œЬ EbАя ОХ+Цћ//-Fо€“Ю/рCФ}Є‰rF аћ@є>п]Кија sБ?cсŒВТbP‰b_cN–m=‚анќў&YЖ$@gЯž:b(Ѕ"бљНЛ"№іыoџљ/Гu–DU–\ HЩ m5ЪKЇOšЅЦ{–~ЪCeš?<єЙMB§‡Тхo…лћ9іЗ…ƒ…˜‡š_™Ѓі•<’SŸиўБ:ПkрдWрx Ni– њЌYb%E>ушєq„#§ќжлšF>`#мRйЙшaВіŠ€š$ Oœ Ї0QєФЫ№:4KЏYВщ=ЏyЦвI`іvњ2%kмsyС,\Оаs;мGР‹г,х#R?GxqюрRUэmTX:qЩWцxп6KCї5€Ц^Gфp:Ѓћ§ыWfn™#Ра€б}GшЏЎЩ№ќt=аt6•? ЯѓР Р;–љЪitЁw_УwяЩМ’=%.ъьє>BФЅуH…СЂМU87јзƒў§ f(И3 ы,ŽŠ„Tj–93 ]ї“з,ЪKHMH—ŠЂa=NввдJъoїсАрЋєЧыŽW|*іKц.‰ИoRъ$VЁыЪFї:Ч4ВЏО7 рЄбјн†0г…Ѕs4T$AДЫ€§ZіЖтmтgС‡ ]ZДДёBуЖз6_jМ8dјаœѕљ‘wкq)ђJIЬrg€#Ачн=Oх‚ѓPЉЕі5<цЁRЫѕЏџЄОtG)јьMXЖр№У–їDч„Љ …Я5 Ц*j‡ SЇЮ 9œрслS"љ­ЦѓPЉ‚Ѓс9•j&:ЬEftќ МСдЭяoš ьЮ“_œ$ZjМR6ј_Ž€ˆк8pдXЮCЅŠYPЛ;DГZ[›ЏлЈт0%qnЋpЫ$вx]2O‚Л?ТI‡и”—X$ MЦ*w“хёК!=кd–Є›€€o5h’ѓPЉтCЦjw6šЕG„щЦyСzѕ”ЪІ>Bx˜дгЋn5^)Џ&ТuyЂЂ†œ9y†|НТрЈ(э"q*m|є…і ЌVC ыЋЕ—ЧЄ>г.hЉёJЙ`‚Ћ’оњr шЮpAxјБ‡Е ЭyЈДёбŠб~Ћ`§яCДˆшќ™e!&S ш3ъВ–Џ”Ы†x„n@ту‰—/Їwы'gЄ8йдЮCхis0Эњм&ЁўCсђЗТэ}„мфm!BФ`!цЁцWцШпЁ’ЋsŽ@зE €xЈєWчЁвзьо•ўКl]: Ьб~™RП5ЎЩшК•Юzтs@qЕ@@ АxЈЁFy9н Ѓ9fКvМ,@@€їPЫМŒїр}„ћиё˜@@€їPЫМŒїр}„ћиё˜@@€їPЫМŒїр}„ћиё˜@@€їPЫМŒїр}„ћиё˜@@€їPЫМŒїр}„ћиё˜@@€їPЫМŒїр}„ћиё˜@@рџcF5‚цнoIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/25.png0000644000175000017500000022230111733011756026233 0ustar sylvestresylvestre‰PNG  IHDRX§I=•KРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь} TЧіwх“wІѓфЩ(p ŠИk\0FаХИ€ƒ†ИХ5ЦL <џj|$hbуjм\СDС—€ы "У Т$,=чMNОлSCбЬє ЭАЭ@ѕщ3sЛ–[їўЊКoпZК^Ъ—Ы=(ŠE€"а\АК–™б\uЇzS(ŠEНT\˜Oa P(Š@ГEРŠ-Q5[хЉтŠE€"@јŠE€"@ 4gЈ!lЮЕOuЇP(D !mŠE€"аЌАТкgоЫNЙ™RHxѕѕrsuбсп(…ъШ@/)ŠE ™#РBl–}АЌўАˆќПH`ЮЗ…Rh§)H9S(Š€…"РB№С В*Жўt˜0eяўC|Cи(…жŸ‚”3E€"@ X(tŒаB+ŽŠM P(uƒ5„uƒ#хB P(Š€vВŒFњjКFYV•™™-—g+Y†A2™s7g''Їкi^MЁЏњчшѓП_ЫBѕYвŠE€"@hІ№ Ё12в2NК„дшqўѓЂтbЛVŒ]Ћ'ђ‡mƒƒ‚‘XЦј‰ГѕфЧnНЦПЄ4E€"@ PjƒЯˆЉ ђIОr-=#НэПкІнNcKŠп?жЧ{АT*eеšЯГЮh#‰ЈiоП49kš‹G ŠE€"@ TE€gЋFЋk+hkk{съФВЁѓоыхю†c+ IVя˜@5*Ї&АоІP(ц…@Ѕ!ЌЛvэZ ј‚ЖЖЇ._(њoб ЯО.юn‚)MƒM,+Cˆ4Фц2M&Й233ІЭžгЕKз#іJюцсЃ2Џ_зIc$J'eУ\жHA‘ˆŽцІš Д:‚2 ъdЌбЅkФАq т#иrŠ™IkiнВ‹Гу№a#fЮH.’ Щ]E2ЄЩcГFГсs3Љ)mэm/\О№ќQ^W;|*ЖСwЋЈ№ЫYд5xщBurщWю+<#†ŠДМА&ІŽyVЙъХ4ЫЪЫ2{АugtРЛJЅВфЄE˜•ЁŽd`№~ўљчЖэл^ИtсбЃМЮ.Нћyч+ђЁЁ80:‰ыїzDСwP­ВГBЙѕ[˜(ючЮŸƒtC|†ˆJmі‰jЄџЕзь53#kВЩmQЂдdв’ГяgЏџ4ѓvцƒ‡ЙпФ|Нlщr‹Rš [BUЉ*)9 Іƒ^јхЪЃœМНzx{y<˜‘2{їьт?fЪдAстXh­ xЂЁv­PІИ\ѕ—*'Gўрс{{ў‡rъЏИњц\Зъ‡K}‹mYќыdГеНqkпd]^uљь“ѕуЇјАч’~ЉCиИP˜m 1[С !Œ ўtъ'†ažџ^”їќyчЮлЕmЧ*‹$Г—ЯœSoЖ№кђЖ.Ж:XЅj†U\Ÿ(‹:™СТЄ+I тШ!#u­ЭeќЧO>ѕшбЃТ? э[ЖьмЙK_ЯGqъTљЅђkзSї'Н›~уХ‹Bыкїьй9РяСЏћrљУ'Nпwє№УGЫў(3~Oж­:|А`ќAЉЊеы­ЗрЭИэлЛП|@–9яН!Лџѓ•ЇG ргЕгfL‚?p›x&qЩкUŒ9:ДюзаМя:8Ъp`MХT“ OБ џХЦ|З7сдЩЙŽŽќ&O|{ @Т\| јмъЈRЊŽŽŽг'ћљП=…HТ'ј|HИ 1?oќCqуђ‡~S97#„X…X899урŠ*]N‰ўxњЮ;хhoКIу'9JˆG•0О:ќˆkiGяП™qїХ‹\ыДьзЯ#рэhУsо[pэ:З0,tQ(ƒ}LhДтekц)y“eИA8юєъяuяVкѓЇЯ­­k+k7W7—Ю.№™бУ&BПЈBЁАеј…‡ŽЪy”“yЏчЊцзЬ…b_-ў/ћф7љƒЃЗО~с{уŸqљАd‘#ƒр–№q—ЎоЁГИР'8'>;SСA€0Th-Тaˆєк­kр^ іьU 6UВžјёОў"ђгыП\†ѓфЁ„OV­p{MЛLхФ™DlнКwЏ(3хњЙS'Gу|AO<›X…B'~:ћеПП>pƒSЊ“_š МъъŸ‚ЬuѕЅЉз^˜Uк­4Lœ=w–{ВBЁ9HрЖЈ„+сђЙs+‡BZxЯˆцНvрьb~Ћ­&CLD‚[СЎ]:$ќРе2ќў’њ‹!Ж\ИˆЗР _G Ж‚]Лw­”*э†1ЉЊЦеHШњKк hџ™)—CЭЧœт&Te)p%dœСсЪ ыqдŸA˜я[Aшc Š ББ8™ј_ЎЕk^Oэ[лу;tмїэюбЃFxŸУї{юГмфЋЉ„эс#‡1=ыэH‰:G€g+xЛЙЙЭzw–5ВFаAЪЭсрш0qдФНq{…œ-œ1}rѕ /Ž?^[mЯ>нg„ЙЌ9фђЩЁС›"З/ы‡ZОеЋхи^м’ №YЖŸ IZ БЃэКШP9њx–ЬЅС{J“aшT^§uдЂЦгЌЋХЈ­Н |o8:9У+№ОяОХYЧяУФњO6r.Q фр [ЗіјCМіV!ќ7­л]Іb&‚зЋ:DLшK%R/7З^0" LnмрžП™i…/ =_sƒшk"Q:ЗQŸn+HЃкаb5ЧЭд›˜0эзP5т&фУЇOaЋWn„Q+Јeј]НrЕ!Ж"Уk‚@UHЕqХj"еЦЅ5ЊF€RРк?м_3ќЕѕ•'P­В"Aцѓ!яs~яLƒ™2ееЙУмрy8ЭсуклjуJžтеAbљ гЄЕoZНfдаQмэй‚Ж јрŒ fЭЦФбэЂЌœЧr­`]КтžуEаX“~Ѕ[:/4ћavџў§љoиŠл;хэ)‡ \ [§аЁСSІ$#6г’ж}1M˜лвbЄThŠc&И)C}ЗЩh9ЌRƒф<П>эHyї†bЄЋbBg9ЪcYIДЊYнГ‡@С7† 3MЭ*Й*АŸ№цм5 kЙ%M]{МкcШˆ7рFПрИ“ѕpЧb‚џ{'ћџhёоЊ ъw1u$с_ъK%^/‘=pш˜=шТњ)щ'`;p№pј…фKч’ЩЄ—:З0мuњЇSwВСOYХћ$г‚1GЕеdˆ‰H>джВg/ТЊW^„6ЈњuDЄrыQ)•OТjЅЊ‘РЭ­—Ve‰і]“_w†Š В`іЪu„3HЁ+n:ОВ„&Б‚ Ikяя­НЏu’ ъ't>џœœTP €ИcЇДГгЇMзIL/ыŠ‡БWW8ѕ‚иТў}}\vщЬНЃsЖ…,К8Щ‡˜№Ы}Ђ|,+I8ˆ53‹гH’.dДєtCиГ-’BЬ_hп19ЪЯXдgйЕr˜YУДuFъ2TR–‘_ъЙ> IъrиRG•ŠН|љ2˜jCM™ŸоўŸ-ЁB п9ƒбoœ `bYшЂюнКŸў‰“‡zцэp8rlўь™ Cёy в0F7\œЗZ#ut‹0сZœT„1_Џ!CМРBTFFЦЙѓg№щяБu:qю, ‡sёnЗУы7б„Ÿѓ`хЇЧДiеdШZхrЃр"ПвеcuT)•@I‚j,№ia€—с`“@F&ПвЄЖ1A3ІЏZП^њЁї5xжмјOGxPјОQ§єœк–нМѓ‹ПЯ*q‚Э'юФ&ЃРС$Hыўu-аЯD[Ј*.” ƒ€PІЈкОђ‰-šjЕ­№ZvKW—с=А‚gЮЫ‹ђ•{ЦЭN‘їъю,iп“›KS˜—ёрПНњtЏW+ЪІІЅТРЕЇ‡Ї˜е#]zjІeЄexVјvР$#“ыЪƒЃsg^{LxcœpЗtв•д%Ы–ŸpТžнК€ы!чŽ4yЦЃЖ$о_дсхЋ3RМ^§нћУk;€Пk\юГBeСoi@юк2щ мЦ'ФcAa<> я"€­Ч зk#Нёjф,ф.]Кр~АЬЛаc†Й]ЫШdлв qц\]љš•™ЁmWќєЕAPЊLRё‹ЦtэачЉ"d§М†B*ЯШvsзVQМKЗ.†2 '­=ѕJ*8‚Щ&ŒѕнёЭ.&LHˆwювїs@ї>џMZ0# Ќ%ќ1B–uzКЫ|н•wОK~ЄDO ‘МЩ•œ_Иэˆ4&&n21$Ї6БSр'.Сл]nwy;eo­BљПЙџ^V‡6Œo[ЅГ-JIUќrMЕКћЉ<ЎWз6рЊВ.)гЯgмњЭsМŸФОГ^б† 51ќвЅ‹sм0ЎSЎкcђ„q8ЭКˆЭм8ж_,œ@Р%Ÿ}GM’‰'LPGigwЎѕУa#Э‰^&ББГѕžР>gŸнUf\F%ПГъRpeуВ…ѕ;FhdыAёZšOЪ&ІŽљЫ—ЄІ CZЁаЙѓ Э3фз<щš‚lЖ(]Лš:Їb<„єєpEWM4Tmе!QПјdд‚яФTкТїg%Я}­мG=DL[Є.&C†\ŸЇšяYБpєШђ&ЦZвУKТВвС“ДБŠГДї@Ц4‘™#м‚aр_nо„qMє–ŽŽ­ћѕъћцф€ІБЯ‰™ƒo>тСЂ ‘#-_Ш} ƒ@нBuчІQ VПЃBС#lIѕUЬ№Ћ2yСИ>ђSŸ" ФЧПœs.Ф)х– Т‚вvрJА_—№Й5|†[…Z(љ_“QІœb^ч’гƒ"`ЁРђAВ‚аBU b›ŒЌ66У5ў&ЋcYыЬ‚к;У|П‰=~2Vъ+­‘„МLШнJр`ЩннуpЉTмЛЇМљ RП`сƒ2 ЌRІ]„ХШоVТРŽMкaAХЉэLе™2•м(E P(УдЅ!„o#Эщ;wІсвDЦ@GЈл.­[enœPc •Яв”'йпгИЏЯДzE"s„5ѕд V"E)ŠE€"@Ј аЎžЂЊYТЕyBЖ„ŒŠ6fXяз^0pРвХ!зЎ]ЋYЭад5GZ3wц§{OіŸМ}ЧvЅRYs6\УфчZ]ё1M‹†ЩUO­нdЬEj­S5њЙЊM ŸBюмЙ3и{А`Tу‚:мiрюЈДuЋž5-6.„пjs5–ЈЭЫ.]Ож‡ьпН?§і§ŸNџєЦјIџљњ?еж MP{роЛћўХЄ”Я6ЦВьЄЩ“ŠŠѕ-ЕчN9!@[;•Вђ2ЭwДјaцB7љЛ#юћ]ŸЎ§4юћ8sA\O}Cы›ЦЩзUЋбхЋ?/ ]$k/ЅRЩЈ‘ƒw}ГCЋЏš _ . œ@ n=%wjоP*!—@Р ЮАУрM‡K ‹IЃ"ј 0Аwl\Œ–'bЗяр{Лї^Кj)Ы‚TЩЊ‰вАk‚8ХЙИ8-[КаoЊпЖэŸQКv%yВџиоюЏ‚ќh<$Цo‹№ЫЏЬBтуу9_п§Up:ГГ3pИтYNШто§{C„, R*СњуѕhЈђЧЅ˜СЏьЦZЛ– 0j[uїWЁнВ%•-œxBРЏ‹6/ 6i-‚uЊ)ыЈЃZ]^У‰+s Ж Ўы§.6ІЏрнAдЂЪЧ€жњ*h8Tъ^бў5Ђ:nэ‚кБЩW’­эьќ&иЕБ†›КђfбCЛEе}ыB5BMуфWJ…F>a6fЄerіЈ"‘[З?Я/њщєЯp>Я}О}ыvmрУOI.JЛvєрўћЗ2!Сіш˜Чю§xшЧ‹Ї“ђѓѓq–˜ш˜{ЗЙР”ф$k+ыШЈmUXёй6Zv.ЌЊ‚S&Lќхв/ЦQZДbљтї–Є_ЩмП{Ozњ-H|џv&p‚_ŽР g„ЎмИrєћ§)ЩзЧО~нzœ`AШќYгfЅ'ЅЄ\LъдБSФgŸчcЄђзŠQUЛFф Ў8*„1вк ЖLвЊogN3!>сбхxќ!џ7'0Œ„+FSDДљ ‘ OŽ3XЁ:еoеыrKг`x-GАU@Ёu QјZt.5ЪiHбЗ"„wp‰q8ЉЭЧжњ*ш#FxжqkчјVК€№ћїэŸ0 ˆwќЇ}Зo?AІ1Eх‰‡хб5„К†Вв|[˜/SQ!м?Qъ‹Ш/кЖmЗ~УКоо^УЦмЉ,Uси“ЇNЎXОB~ЂTКbе' ЇNтp~v!—@|єсG'K8œЙЄіRd#YК ЦN]О‚ d$‹>\tтЇ8М џjвў5 h$Djя№тЯB|i%ыXЫW(”JЉЬaйšЕ8Б+r ФК•ы$ЈЇLŸqчv&NП/ўˆ›Л “Ѓm$sч/:ћЫ/Цљi‚ќ1ЗFџѕЩA„1вк aLHЋžњЮд]ћтXЕціQЃ]уІМ ЬсРEдОЭk˜iˆи„?‚˜“8‹]јbmЈUд^#Ђ… ЁUUѓGшЈсќЛƒФAЊввZPТJ.ыЖЕ[rэrђ nЄпѕЦ_ !Ч6ЂЈDžXSpнЖDl(87|Кѓф4ЙКМцЖ7nUЬЈж IDAT/†šЩЈУПR"RЃœ|G…FZЛС– <*ВсщюЩ–ХˆЗЖЖvщьЂЃ{Дљ ‘ЙR.Ё Ѓ*.uъNЄ.›aЈUдFD A‚Ђт @C о\jœ’šKCZ Њ ƒсYЧ­у[qh„LNЩ—Ÿ}‰Ћ^RТЖ„і —Оc|ЙwЭБ~ЭњѕжГmkыіBf;~ ‡ыќУдЧ7ЇМ с$oрЬ@xё™Й`&єctщкuі{яыфj>—\пˆjйВeЇ.НТјЙTЊэX6„ваCC‡цЩtсЋр™‹ІN~ЮL˜2 тиДqг›п–лЁ}‡ w+ЋЯCЭ@DQf—ФHk7„ЙОгƒV­_Е{чn§ЈЦjѓ:u'^Ђ‚СVбHwБ‘ЛƒШЌCвZАRt#ЌъЛЕЛптї“т01щэ€oџГsдЃЬJд—ђхђБ~‰А1oицЖЫ>XVЌ,ж‘лB/ЁѓабC |SRЪќы‚То(udЁА[Ји&WqгжзЂЕгы5Й’iFŠE€"@ X њ]Ѓ* дЂZ‘›ЄRеjнш (ьR Л…Šmr7m}-L;=Cу‡Mяh’J™5QиЅŽ,v лф*nкњZšvК†аТьИИVи$•ЇzcІЂА7 њ Л…Šmr7m}-N;:FhrKІ)ŠE ) @ aSЈEЊE€"@ ˜Œ@•ЎQEЁ‚-…ЬMс`lЌFSRЪќ+†То(udЁА[Ји&WqгжзЂЕЋ\GxќФ˜єŒt“ыи 3іюеЄjbJ™!Ю:"Qиui˜K …нBХ6ЙN›ЖО–Ћ]Ѕ!ќћяm&з.|7ЫфМ4#E€"@ P*]ЃFф8ћгй‘cFIŸH6лXQ`ЁЭSАЦЄaЪЅА7 Ю:ЅX(ь*Жјт/›ЖОЊиЩ2Ц­ јF@SR(ŠEРЌЈ3аЌДЂТP(Š€™  ЪSdŸ8Qœ~KUќœec…ЄоНfJdf"ЁXChЮaTDTЬЎ>gОtљR3A–ŠA дQлvфч>‰иЂн“ЄžJi`ЖУЏщ—XpоS?аВBrNžPќz‰Q#[А6Œ-RГ–Г‡Žя‰щЕq“ЫdsPGЌ!ЌvŒАБ”‰?{хђљ‹IAи€-оййЊВЩ_…g§БП3LKЖшПшх6Ќѕі9rЙYмKАMьылXвr)–…гЂбф­з[еэ=Яrј8<•ЙРбƒ­ІQŒцѕ*ЄО‹SЃЬ;@йПкЂb–UУжFмжЂ’ ЉЕЬк:{ѕЧ9?ЭЙ1{ˆ5„fыю?№УŠUыeи\Wа&}Гж–A2k„ЪаЫ6ЌК §Y*Пz!Г0„ЄlR$%(M—ІП$RГHШЂ’"‘‰MKж(w"ЃVq=‡n'[БЯfгєkˆ\йћb%-дŠQЉйJu@/8џЧ§іrr”џr6ѓЫ(ЗХм“'vВ x„ \ЭЫИsчN/З^8p)ШzЅћ;кШььeфЬ т?K@ъrTj^_ХkЊ~сЎЏw98:РЏ`эаРzBРт`wŸ‡ФœХ%,[bњЇ?РШU xЃм‰эРB”"ЖDХВ*ЇCŒќВ6\АђqŽъ™œГ‚*VГC=Ы€9$Ч?x&ƒ-tvtЬкБ I hЧŽЎн;Ž=FО`ЇC[OШ"ъ0[А№2‰І&Zr7с„ј’ќ’XjФ№pCСm0žŸ˜Ѓ мЊЮŠыkЎpЇ/ ]T'MД-|В„-‡ЌМі5‹#ќ *шпA8)<Ќњ‚l];Тs†„x €Aў†1!‚*юм]4g1*)жТђJIЌ`”Aр–ќЩьфЯ“Œ„H$А |ЭЧkІП;=2*’„ Т.(Њј‡‰XChЖaЯž=3230F@Р%СK‡шf‡КййиZ#g;4кЩЦЧЩfАђqЌxйќRШa uѓgeŒќ‚HП‘~сте+)Wtxъ_N œ=юќЌ;YYwГ\ЛК†mXKвмJПuсь…‚WQхnzё,W8а=Лїl§їж№ЯУэ^ЖлђйЦСCFђКUѓфЙ^•)ywze 8 Џ ќ4”›єз]†ЌЁуКFdяю‚ЃŒЌ&Мƒ€џёB1(Aў†0сЋЫВх*5x{ RГьѓPALNФ[I˜–а#ЪXYуЧ#ŒйЖг<—љљy4єДnн]PT‘Б]Ѓf;kаЇъНпюСid5}іK–B5836§лиŒrВ™вйІwnАpД7•”§Ъ*BYrk\Р(’ЃƒЌ ћсЫœ .[Z!>ФсќIM3чЮœ5gVVztМ<}ќДВOœpдкwШЩ`KR‰фCв›)ЁFБqБ`д5Qма1qБ†`СZŒ11жQŸ†пHН/:fЊš9‹eЩАOП-IК0ї4>ок"ёsѕёъу}jgZ•sѓЫI РMЪП›ZЫДMC7)Щˆ 777ј"ЧНлїЖ|Ж%єУtb нЊ­лwШМ]йАё‡N^‘—иЮNт&’H[ЁЮЖšй%%ЈњHЁOиЄ5ѕUiЏЄ–@u aB!ыгЗјПEшљsUњuє№b XД†ЪИŽаX3Œ5ВцNцekЅЕlа0~^:і@, ттРšТ.ђa"жšэЁd/_ё–ЋлАV6Љџ-=ўЈ4љyivQiОцc?.­o;4Ѕ3 vAОŽЈm+n^oХс7еoЭ†`ъриИacE0ъйЧ3цыА…№ЖВvѕZ^^^рФ€љ\Жz з!ќ&ћ7Žщ хЦWыФТЅH>њЭ*$ўXќ ЏAќщ^@їызТЫЙ8tё–/З.YМ„яRЯBc – {кзшЩƒ'?'&%%ЇІ^ЫШИ›-Я‘+• aХР@ $€“-.‚!'rРMЪнM/ИЛiѕЧЋсGКIэ[лч<жО†BJ˜ъТ]ЊЙLхџуёеp1tЋЭZГ|)goд(ћ~60б$7ёЌнЕДь3ЉœІУ{ƒХйТВћйІYABћxб<ЕІOжRS  )c~z—€Šœ‡Њп2%а7ГCсФп _<0­цe;єВ‚Бv™фЯЯ‹ixКТdР№MсqпЧ-[Њ}–šЛ˜‡‰XChЮЁ>‚њ!AqП.M*XzЖpЪЮЄўяЎ•И—Пм]aеІоГбЁG(ё9ЪаЌа-fK‹yїТВ%ЫьZйС>[У pячоВТY„ ЇNŸъжщ•Зоы5Ш‹”ИmыЖukз989Мѕц$Џ~•с$&ж,_cgЋaы3Р[шmH$ЖцvљmЬЗ3пЉ#еќ9ГОнѓ­N Ю%cХtэоеВРэЁ“’^ъ#`ЁАџї7œwпНїрœiЗг`ЦЧ™s;Кџ№б­_§ЇЈЈЇсжN№Ѕq7щПьєя gЛЖэрcbш&]јСBŸQ>dжш˜бcfЯ шшфА~УњЏџѓЕž†nеїCмНМоžдБ‹У‚РD'cM/СцKЬNЙЫ:л#_ІьyŽЩVŠііђ†GVя~Нс9ГtЙv$ЂІ@RС&ќєвW]œgЮP€Ј.cwr#V-ЙQЮ#d8А#g'џi’ЊK# j`0Ѕ[Яn B@Ъ ч.—i`ѓ0ЉГ§ЭsЗ#у{‚ЈJ•ŠћŠЛЪgOђЛЉ|њ-’;У`с+нGЦнуW*ІсЕ1`ZРЏW~еЂ!|ŒУЮOiˆ†соI“'С0ЁЁ4\ …нБЧП9ŒтЏIy'зчИDя7ндo RE;5:;г%žqХмJ‰–№…KєВ5œŒ5ƒЛl+kЖЛЛчЧZ;]OrŠy˜№:JaЖп5*u5‘ЉSŸСpOО9МBТзыWŸ8оxb[{`-зуЧЉЌ=’5т`AА?zјЈœп7Z#=Э;1x` kу š‘~Vhd\|цзЛRУW9Ѓ2H§Ђащ‹ВVРRњiГмъљeWdЋk-~ŒА­УййyР pуљŽї%Н.ЕрGГC:EКvщ§u•х†Ц2аИК@РВ`‡‰-uЁД™ђh"VА]ЗyA.oŒЪ8А7уђЏlЮsєЦі•Ю2/яў“ќы{&ё­ZЌ!l’aEMUѓŸDГšD4КŽ€™ЅuФ‰ВЉі€E“打“'ŒS.ЏaЖZ'пЊХN–iЮa­Ћƒ2 P(ѓE@Ќ!ДєYЃц[T2ŠE€"@hTФBъ6j5бТ)ŠE ОkЉGX_5@љR(Š@Ѓ" жRАQЋ‰N P(ѕ…@35 ћ’икиJZU|ЭY…•[$иKWюY_иSОŠE€"`ˆ5„MЬ#„O4-6ИUzјЇЦі33ƒZЃ"P(Š@! жZњ:BћV!Bў5[еУ†'дЎВЕAmmP+|э–‹ЅE€"@ 4ФBKїu\Рх+ИЕEšн'ьl|їN‚l%HЂй/‹ТцаєЉŽŠE# vВŒЅЯ%.`рaфБ%ŸЯ qŸ~e8ЛђJ”ђˆƒEkRњЯ №СOл1- YдБkGзз\wlлAЂ’/'NїяшЬ…/]ЛЬ(>QСRЗhи&pf Аэыо7ўАvч#и8&p:'dп2>C  ёф'‹Šˆrэю 'ќpJS( B@Ќ!l!д И€œи•p[.йYq&s5Ж0%‡ы)х’•”sѕsРWє?ќГvнZиm$§Fње_Ў>yђ„­шбѓч…feg]MКЪик†,зф nжД€YгfeнЩ:}ђtJJ VhA№lяоАu0œюю о[ ЈЈ O~ЪјƒБW.ŸП˜tN руЖќXJS(KA@Ќ!ДxАЊ ˆDшs%ш–Ц jzFС#,&ѕŽQьОио};:;Œ=6!Qœ?єš+ИkА'ЇЊ”л­у_L”еЧO[(е@ьлГРіюƒ‡ †m~Ѕ­ЅА§яхЫзЋeEDDE,YЕо` ;ьцБ%GнЩzВ Db#sщЂЅwюм!YjDь?№УŠUыe28и@+s˜аФŠE бk-н#дqЫџф|Ои7бЖhЭт†ЖACаІ!\Рю№ќŠ_ъШЇГВŸŽѓМxхb˜iЗв.žП˜u7 œЙАЯУ ЛzењR|ц‚Д q‚nR‚щI:ЋШW@Ї(tBП+єОтdО|wьм–N рR0{Е d/З^8‚2WЫ„& P(Ž€XCˆ=BCПЎFЕшИ€p9bјC'NLx†m ЇќЊрyСwЎ]УсqћvmлЬ…лHжЎX{ђX­:}Чј†m[х’в1ž(l|џEФ:сF.s…OфO.\М=Ў`ЊСбФ‰з~В„Ѕг+p—F˜‰*ќЃ tЧ €(д“йH^E PЬšЭХ~ЁўЏљшcHттkЮŸ#)Ёчгг„їZ‚Kœla™Z›/OžысХѓЯ IњHБГH е!Рј-§hiя^Н[ЗЖšГАЕЌ?СЕызBЬоНЧЩЩ‰nœЖџgKшMХТƒьнЏїЖ­л |+Рoъє…ѓН§ыэp АЦY Ц№)Б-ТўŸі‚Щh E€"@0s <ПѕЄ_аЂ{GБ ЈЇ>vƒm› ˆZГ\ьeZЗяrђ4x„њ<љ!ЦэI ц*&:_ТL™A>ƒH䉓'Рмѓ§777(†шй“gЇВЎШsљђхи=БHSѓ0FиБKЧŠ˜š§їьй3#3Уs€'d.k–ŸІІP(ц€иЎQ‹Ж‚ѕЙѓчШ9;x6>лuъ[]Ї§v/эСНДлїю§v/0(XdНЭЋЩ­=P#XЅѓepFћжі9sD2!Щ`]ЃЂ@ЁRЉЮž;ћХЇ›—Ш-s„cзю]›зЏ;zјЈО$О&NЉџ0= ВЛucиШёкБ@АXdŒ0j[п€UЫJ!i&љНГ%b=ˆ 'oшЫ@C(Š€љ#а\аЇ<)ŠE бkЉGишUE P(њ@ ™Юњ2ЪжЦVвЊт-jЄ(T№ё…OQѓ/)M P(MБ†А‰y„№ ю ХТЛНCM‡оTы›ъE P(:ˆ5„–ОŽPЧФ;њDŒb‚­ълЕBЖ6Ј­ rE:ћъ@F/)ŠE )! жZКGЈуТnP‹E,gэlУйB[ ’0\хRCи”š8е…"@ G@ьdKŸ5J\РРУШџ0bKРф>Кm &сL -ƒЄ JyФkc9ВЦйДСPNH€~и˜~QШЂŽ];КОцКclkЁ=’/'NїяшЬ…/]Є|ЁЌˆЉђ_СвЁJ(ті‡ œlћКї…mq,l8 „n')НCdЙQQАƒœ@шё ŠEР2k›€G. чЖ@E%EpigХ™@ЮдиТ”ЮAф’•”sѕsРОKxы%>{иAža˜єщWЙњфЩbДЂwFЯŸš•u5щ*ckВHx\S'XИYгfM›•u'ыєЩг)))ИФСГНxgЅgСщюсОрН|I0-ІмјƒБW.ŸП˜tN тj ­>7B PЬБ†ат=ТЊ. vЁ;ƒŒиеєЯ8ОЂAун•kTЧ„ЫУGˆЌ€АaрЈAтрyСŸnРЙтіэкПя(8CpЙvХкa#lкАI$C§dxy№љ *lsXљ…:iР]Зv]МЎ\Eсљ“ /p<7†ЃЙm+ЗїђкOжОѕци ›8EКvщ6^Ї,ўЅ‘r џ(Ÿ'ЂPOf>JS(ГE@Ќ!ДtИ€И&жœ?GЊz>18-ђ l!њЫ`_{Э‘'Яѕ№тљg€$}Єњу‚ZFš?0~K?ZкЛWяж­­ƒц,l-ыРНv§Zш‚љбЛї899ёУгіџl – VАwПоиТЗќІN_8o!dпўѕvИ„ŽPAVЦЫўа!Œm!іџДdB)Š€™#`рљ­'u№]РсcЧ1иЖYЁ№ˆЈ5ЫХ~PІuћ)'OcP­ЪуіЄsƒ/aІЬ ŸA$ъФЩр юљ~›› CєьЩГгYWфЙ|љrьžX˜1 ŒvьвБ"ІЪЕхіьй3#3Уs€'d.ЋфЇŠEРBh.c„чЮŸ#чьрйјlзЉгНлїв~Л—ір^кэ{ї~Л,Вт‚fефжЈЙU 0_gДomŸѓ8G$’ ж5* *•ъьЙГ_|Кyљ‡м2G8vэоЕy§КЃ‡ъ[Aтkт”њПгРб„ЁA8 ktфxэX X,2FЕ-ŠoРO1хNђ{gKФzN оа—†P(ѓG Йx„Є&Рэ#. ,€У.`Ћ5/еtЯњї…ѓ  IDATC`Й_Рл“ђђrЛts[ЊDГ№ƒ…>Ѓ|Ъў(3ф cƒ œЬЫЫkь˜Б/ў|ёКзып}ПпЉ“Ж tеЪU 9ПіщгЇаCKдС„ OџЩўŠgђƒ”Гхx 'оЙcчъ•K""ЙIЄЏПю—:мрRLЙа“ЌЫ‡њ …єСAСўS§ѕљаŠE€"`ўМ”/—ѕKLЛ~ыяПЙ™І0ЅТХеХДМѕšKG0ЮсЋшхЭk@ьЎ aНŠmщЬu`Зtu,E~ …нBХ6ЙU4m}-TЛцх‚ЭУЭ—Z>“ocš‘"@ 41ФBKŸ5Њ_m` љ:—5э)хГЂ4E€"@ Xb ЁЅЯеЉjчtЁ—ŠE й"а\f6л ІŠS(Š€qФBKџжЈqh,E€"@ 4[ФТІ7FиlЋœ*N P(|Ф.Ÿ0>FSfљL)M P(KA@ьd™j=B‹XGh)ЕbщrZшZ" {Ѓ амZKгжзBЕл5JЧхA ЅP(њF Ю<Тњ”ђЇP(Э‡q™-_­пX„˜ВbeСš}pпмPR(ёЗтгžЅУžчъrјЄ—ЛѓРрС2)З9MС#„/mтУЅ2P(ѕ@дЖ№њњ.ЅљЗl#qудz„Kы!В–mЙЭP-ї8‘y"ђbф“’'жRkліЖL{ыr[tRž0єЋЁёзуЭDЏІртяVƒ-4LЉŠ@Н"РДЈТю}CпИЏ’NєE0Ќ+nп4ЖDUŸDЗАЎZЩ&^5кq) IPЧіm‹YЖXU\ю BГ;ПУ […JёqђВЃwЦО+že=ЅkЯ­'с([ŠE љ №вє*_=4ЂxЄGdQI‘‘–e­FvH•WАšхNЫМћЩнh›TИdСBTu’ДаЉбЧk–ЛvячЧk>жn> qТсЦЯЃяkЎЛvфfп№x †+ђr`jHмбЙcрЬ@х %)7ќгpзз\С&эк­ћ’ Я“Оž}cПз}жkѓjў†gBщR *8хVЦВ7SЉ”h|7p 5~”š}zJxтЈДЕtщЂЅwюм!’ш#€нAјХNЉџФуЫS{њVо-№gс…ЅПcџ)NSІvžЪЊЫ‡:CJ”v#­wПоr”•Qš„фиоюTі)~‰†š.@$€Г` BQQP#PS‹B‘ч6  _Г(ж6 pЯюшйСГёй3gЭ‡>%%хШЇГВŸŽѓМx%Зн|шта/ЃО$i"ЗF†,‘ишюOPТvCШдkx€ь>ЈE"O~№‡я€ў<їље_гс|œћ.qbCс{%хЪ…ЄЋщЉщEљЯЃОŒ"ЬУЇЮž?w~жЌЌЛYЎ]]У6ЌХщЃЖEнћэоХѓoнИ•џ,Ÿ0žщoNyѓѓЯ>‡їo~8Ÿv~ЭўeIЧ‰ZŸЏрМgю}eф>ЃFmUшO%„H LчP*•PКЧЬPPS№!{Є\§'‰ЊЂœ-*Flё_Х2$;w<ыЊ|žыќЖŒsjr*,ЂшцжMЎЮ:]‡ЌXЦ•Гм$rjК‚8 юиЖ#эVдд8ІaŸ‡цњ5Ыс;дЛ{Ф Д№яъŽФ3‰D№ Ћ.wНЧЗiгFП О`љЯфн{vџћšTџћhhВ8 ф-..Ц4tЙ8ЗгВ7qмёЧ!\ЮЁфQ8 §5Ž…н8>ѕkЁАБб4ф~‘;хиР‰i›96јŒќ$ 0йЗŠЮШШ @}q`›aЉн'g…э*іћH4I‰УЧVЩЋЭЌyGїnнГВЕO`#šЮ@@nС'?i4бЮ/кoс™ …gƒRхЉ1ЛbІO›ОwЯ^€bјАсЫ–,;ž}ˆЋпdф}y'лtпЈE 5ђ ФY0к‰ќ‘Ж%ЛїбђХIMё[H sюЬYsfeЅgСcфщуЇфщбЁ}(—Хџ=ђу‘„у 0(Х$4иuлЗ}пчЪМчlоЭвыЧ њxMxsBJjJ^=P{6Ёp;Ж‚ р‹gh\ёZŒ6]Aœ[ЗяyЛђi_ЧuуCАЦХBK#Œ??ШkЬQVК_П~NB‰ХЁ‹З|ЙuЩт%еЖHСьЭ<То( РraOћ=y№фчФЄЄфддkwГх0 _ЩЭП—Z10ў рd‹‹Њ*iaі›ъЗqУF˜УчъWУ%Ž0Б\zЭФєЩкє†ТЫЫЫaР z†`жЬВеЫДЅ"nƒ˜0)#|“v`beВ#ёGіХюкёе’˜рѓќьvї ›.g_@Ј-‚ОЈЇЧм`ОŒЌrЮ,I.L@‰;ОобЅ[mHSћжі9LЕ0гКс=уЁќСЃвхшїјg;C3&M Гaг†YsвйKФ ZЗ@П?DSй§Ыn@џоpЖkл.1Ж†Т!жлЫ{и 0‰&є/]^ЙЌ[0|лжmыжЎsprxыЭI^§МHХСМM˜;3tја>§њДmп–„Ж№№бг‡уУє ~8ЁѓJанRdmЫРйв–14)†ЄЧюєƒпnНЛJпFkŸc†4]јСBŸQ>^‡O§]К8ИЬш5ПPQ] рE”3ЅJЋќўƒ{#{–Е‚5!šѕѕ-аУLДa`˜SkmЧВёІ+ˆГ``Шћ!ю^оoOъиХaAШ‚1ЃЧMkЖЮі#lЊл0СlщI“'M?рH‰jЈ§V,іjAжO`ЁА› іј7ЧƒQќ5щW}j†:9k”Ѕі‰uєэјvЖуыВ"˜—`Х”пV<‰kЌ}Ё ЦЁŠvjфПл?Љ4СоY3œхуОЇ1№н5єЪKEЏ3гђk†jМЙx„ІЕƒјƒё?ІVа4єLЮEa7КкdД и=|”——WeЭ*/л‚O‘YCw(X‹ІtXЁјyёŸєн^˜jѓBŽЪKДКБJ”—‰З ыЕЗ!­ hЋŠ­Шк П5 я]ЛtўКЪrУ <ш}!@aЏ/dђЕ,иянОgTKŠ,ћS…nШAтr+nЧ%K]œЌ!CB|н|ї^й{2ћфƒќ dевэ_]§\Ц`Fл0‰5„–>F(ЎЪЊЄjј>“*Х7з {Ѓд|ѓ„нД†Љ1Rу Y( ЎПЮ†,TА,C5.Жkдвg ‚B)ŠE€" ж6C6ŠE€"@hˆ5„д#l­ъH Pš!b—O‡ІЬO@c)ŠE€"`žˆ,SэЌбІКŽа<ЋЭЬЅЊВ–ШЬemBтY(ь*ЖЩ ЇiыkЁк‰эЅc„&З{š‘"@ PЬ:ѓЭYI}й`у1[ЋŠн$дHQЈр'[Кx)џ’в B ўVl–"KГ<›1`ЎВTq0э —“з(WпиыБO ŸиЖbћЫlИMшa†Р>ѕ-_§pрлтмтТ‚–НФBЁTФпŠO{–;"u9Д:wчСш:ТКkzЩ—“Ѓwn…Џ[Пl=aФШЕŸ„С–ЭеВ‡o-ж~Щ^?1l‚ЌHC(–‚ЋV§њьз;…™3zЬLМŸИ#9В‡Ќчо3{Ж[Ё}Л:§ЋѓЩG7ŠйтeЏЏe|мВтuаRдkrЖl#qуФТwзд*”bй ŸШR!>јœ`CДE!‹`чkиЧ™П] h8нПЃ3ОZ4G3сQ0!шІ‚W„ђ?Ы}'љFnŽ”иp“Т„OУ>нё‘/иђ)~S"Т#0>bЛFщ:BRС” ˜?Rф"UŽZД/3ь'Є*t ДYk{];хЉpVлn Є$ЅьDGW"^ЏдМyЋVЌzђАрHТщ”кйŠ‚€@JJЪ‘Oge?ч;yёЪХu…ЩžнбГƒgЗй3g]WlЭ™X>ћ—%'fb! Ю{цоWFюS0jфбV…ўTBˆЁыЁї;j[;ё<їље_гс|œћ.'6~№‹ \J=UСЙœ-*F,8…2$;w<ыЊ|žыќЖŒsjr*,ЂшцжMЎЮ:]‡ЌX№ЫYn 9 Еаєоoї.žПxыЦ­ќgљ8Н` 0ЅнJƒ”YwГ {6ьѓ0ТќJЪ• IWгSг‹ђŸУ$JXФBVФ$(ЎЇqVP_N№l№ёъЋЏЦDЧlлŒг$LXЗi3И‰pnоД9сp‚~^RеЧ/ І‰ВlЋ.R"Ѕ­Нэб„ЃщgГd%В}ћїuъаIСШwх­}ЄN{ФТ™QФ‘МFк@мО8PŠku6’5k7u2И 0С)зЎX{ђXхR‚uŸЌУјPqуpЙb !і §(A 4:'ю!gЉDЎDчфŒ[Ÿ3Y…Hщ$)Ь’\ŠDЖŽ’і‘УЭZ‚CъDоГ{ЯХK‡ #4Щ—ЮтpС@.ŸT;ОЖАŒ› QGЬžН……0S†;€ŽнS|Э•gлHNч&.]ЯEШŽГ…xj иПТ"е“c•з|%4оїsџў§…! 7Ў_csЙNNк urtzё ˜ ѕQ}ќ’`ЅD[\ŽŠЃяmщ5ВLї пўaш‡EEEcо“ЎО›a2(ЮЊJ[й‘МFк@юГ\PŠЄФ„``ž<зУЫCћЎа§е\E!Щ%ˆXChГF‰Њ” 4gР:йЃSYšuA ВГB'хвЃiJє,йЖ‘ B6m9ŽпГб9+777р„§пЗ|Ж%єУpИ` ЩR—„С№Oц­Lђ”:F3 T—Ѕ˜ /ЮџГbНЦHЅLТ Е’ДУР0ЏLЬTРТ шВ;яvТјі,dAY6жAжЬЯЩЫi-ы`<{§ХіmпїЙ2я9›wГєњБ‚ƒ>^оœ’šвЃWдžM(мŽ­ (јтзcМVЃm Cћ ”ŽЬ‚­лwШМ]й ђ HЎ*јДзт#жв1B‚#%(цŽ€ZOвqн$}л#;˜" fGиxл+‘Ќ;jя‰ ѓQсc$ЕCіŽˆ)Š‹ЈQiQшЂœЧ9šЩюЈќкaСРњ@ ўXќ ЏAа+K˜нЏ_?'!M‰ŸК@я>aгхь PЬc§є˜Ь—‘йˆUTUЊкёѕŽ.нКр ~S§6nиSIс\§ёjИФсі­эЙšmРc†їŒ‡ђJ”ЃпуŸэ ݘ41xЬ†MfЭ Hg/+hн§ўMёœE3оІO›J)  uј&эъCСР йAk–/хlžС*2hУDuЭФєЩZ|ФBъ)A0sdRЩБЛ*јRЯKQ;+х&wyPчlЮНш51,ВЯЃСjњЗОBгwuЦŒ3{f@G'˜;њѕОЦс‚$KпЦ|;ѓн™: чЯ™ѕэžou›вe^ К[ _?`рli _МЅюєƒпnНЛСьoЃЕ-[ВЬю_vњї†Г]лvp‰й-ќ`ЁЯ(H/Š{]$rqp™бk~ЁЂ К@Ёс•3ЅJЋќўƒ{#{–ЕbЙІЫИ[ ‡™hУР0юSšУx€љБЎ]]‡кЇ_ŸЖэлт,‚!я‡И{yМ=Љc‡!   МНМ‡ аЛ_o;[ЛЅЫЕfЗŽОѓYЗЫ'м^sѓцУ_Ѕˆ@ 8ЮJPъш]\ГJ{ƒе!лjY‘%\ђь}Д?[|жI†zЗPLАJBйGQgW+Дџ*ч|>9L“)Bя_@nZy#|БQŒ+ZGпŽog;О.+‚БbЪo+žDыށ5˜`uRPэдШЗRi‚Н їщА|мЫ™ЦТwзр=,/НЮLoШOЌСЋtМыkк,šH6t œ@pяуšƒЄзЙ„pр†ЅтЇзfЃъpq@›ЦH–‘ŒtEnИ?Ьer№тОrеw…&mх:EM§ВLuхгxБ”§ЉzqC^ž"‘Ђр>"гфސ!!зCяЮ•…йe{ƒё{pМ]†ї\iXцс§Ь<Žџ'R ‹#„E'зo\Йz%Б@Dыи]1iПнћёаIЩIжVжлЖnƒЈAedЄЁ,TЎнИ[Чд›Љƒ|‘Œ˜иОc{QIбЯgўёШiзгјБiЗгімго Kі{бЇ†ѓyўsИфЇЄ№Юq{tѕщ™а@Š@%аъ6Н‹Цoть_'O$бЎЈLCЉGІЦ<йхТбN–Оя !№`pЭј5П.ўЕ`KIAxСЙХПТЅЬЄmO !2\А_ђŠ5„э‚žnюnА4*f—ЎE‰;œАbљ ЉНTТH}ИшФO' Бз Џ+78ЋvќЬqkЦ;…№Y ///ф№}П‹WР f8€?ъЃ?‚@Т%ƒRў?{яжФЕѕяїпœ'ƒи/DZ‚ QAДЈ ˆˆZМbНRХЫЉ(ЂXEЕѕVё.Z­R__ЕОz@=VЁоЏxЧЊ J•‚U„"О"ф+šЩsвчќ“ CI0С™gžЩо{жо{эпьЬšЕ/ki_­0oЭТб#pъИ9+‚њ• aК"РWZЕFШ‚2{цьK)7ВВЊ­‘С†гсУ†c(gŸР>Ѕ/0yBzњіМ{ї.ЇOœ†1КO§ˆ№нћw‘ЮХ]Б}л~йЈСŠ,WSd/…м-S§bља›*GH0_Ahэ!ƒ‚ˆЌ_З~љЊхьP'‹ 6œ^Пz+HuЇv$кЁ›МuЪ…dxhђ №#џІсЩMю†t4Б}•лЊiJщF2n—+іЯrЬ`g‹~сњХrєњBX@@@@@@@Р"TmZљЏџŠ5Sbђйnƒ‡о3Eѓp$VЭšКлtвa\gвИIœE0†Э˜ЋcVcјњVгьмГ“нЇаgРКпNŸ14У>w“ІLЊйh“6oXОt9nmиИЁ&›ТmмА|%CЖъыAF[ IDATUˆВщэ?№кЗпфI“щ—є7›ОбЯЮб#0|TЅй} !м„hЌПCcећšТJйЎwЋ›w{­БuU‚аќC5#йŒO˜/чнJуБ<ЩыL:!4jN— ~kŸўЂЄА}ћ‘ŸБЗњємКqУрСƒDFŒФ .—.ЌKљ$ЊScёj”zыФdMb+eЛfCxІ4яіZiыЊ6дтjцAжЊZNв–нPoІQ–Н…rцЌ™gNy§b1a)ьї}Ћ„ІАЁОБк^z­єеY–ВYšw{­Дuгын-Ќ=уЖ-›fDЮЧ‘-›З "ŒaZћѓl†ќУюhЪKмaо„ПЫf„ѕ4ЩaXV‹ЖXm‡]ŸдЋrЅЕoЋP(‰™‰Я2р‰ёy""о.Н#{E6Ъ ЃН€Џ 4Џ-њ-Ittt  Ч’ƒТHщ[вjЁ™ж‚# HjЙћŒа’H_AZСЃkёОи)XNУђ†FMR­€a3,žЬ:yѕЩU?‰ ‘4ЊL­:•Ÿ”p7aЭр5ЁОЁfђ6и-О‚Аж9ТуИЉU„IGœ–хJЕ,žomi№l]–ўѓ”DЅ![˜=AdgkЦЊpсЌDrЋbПŽЬBl@ЌPуЉ1jЁЅТPCЖ_…YQWgGјщ-W—УI!šсіWŠи)дŠe)ѓ><кЌЌён>авЯB(O@@@рЭ"pПˆtu&;в3nvЄLnгЄ\ыыюЭV,”ўzиhˆ”ЈUxR/iыЕ›žЊTK;(‡tзj^.-]шGДЛЦ}MџMщыБчt•^ГзЪЭW сkС,dh ”%MЄ-Iяі›`mФdЧ}В7У$+P˜УЩСГ“ы№!c7ЦъooХv•Е~~$ВQжEь7Й2й=#gFІнJгЇфŽпpхŸЅ™QJэЈvиД\ЯђЊ\ЭњЌчкШ<ЃЪƒ…ZQЄрю €мhњ›K,xQЏЬЇ(ІawшЕŒbЫФЗЊТюьЉГрйУжУЇs—­ЗЗ`ሓю|Ё <'!* ає i’_J†К1юo0Aшж’мœDжvL#п‡1іџŒwјЂ’Ь{9›ЗьРАўA§ѕ_Вpс–№}‚Б|dњgгёЪ;’tфiQЩ­д[G…`‹­QЪZуїФЛў[\kЅlfJ5С2зaY;ˆЛЩˆTCTPсEтЖУВ†T{^ЬcвЗnм‚,œ9­ЉA‘ќI Ыб+hТœрPEhI7vFGђ№і m‘^цдо>с–aЇjр>РW aSыg?MЈG,{јпяучƒ€чžњ Т>•)аНpзеХЎДф­4уWз&ћЩIЮ fНшЅf‘BkMWvЌ,k'Љ(&IŸ“˜‡bБ[сv$6ХnтънДnгžИяŒњ:П~хњв%KYџђАЊ;hј8`с2ђЄ\M‘JЅaSТЄR„љgДjJ‡YP›$bмЏhњю/jЕ’ ї€RЈеЃ4єoЇužm š)i%gкшв5dYє(є8—E/cн Аъ Ўl€ЅL8а;РЧеХЊ?і<ћњбЬЂLшØьщдsœ|мxЗёДFфдŸ( ь6У/n>ЩЙџђЂЁ:BтЊ_Hjjъ‘cgь$vqЛтц-žwъи)§ЛЏVбeхrв2";Бџ„K{—O{ЭTЈ•З“oc…‡—ЧmЭљЫЅI0cIйRXuЏ_ЃЉ>Л56ћ—lіŸВщ[нї™бD3џЉ›Љ7/_Л…ъОœЛ9іЫ_Оъ‘•…FЏ0]&lЈзBјmFъ“%мЭШxa АЬA†0Љ‰уCnмМЫˆ щнЗ7ЁBсУќрЃђvŒkrх eџНjцхƒЇў^цYsNЊPМ"ЯI+ђо–О1.E9rЏё$э{rї$‘Й‘—Хк]6dТN"зНgkО.СЇk{‡ЇљЬ;”ЛћѕZИSЧD?ŠьЖяЖ>sњёуЧN­†;ћяГ!цkх\ŸmEQAарьЬl"ЯюžWЮ_aЕLЎv.PkЩM“@ПН €‚RIиpYFŽђZš‚“ylКJЅfЅЃ~[€€~дО•§БЧм;К#бЧлчшБЃx!# !cCюІ1k… @CєбЃGьгQЋеэкb@[ПЬz‡Йж…ю mэb‡ч8ЅуЬћю_Оxyh№аnон>Ÿћ9˜ќ№oўЫ‹Ц‘w˜%ЭDc[vЙmі2цџ‚УLРШЪб$]ыXb\&šљOЅЇЇзФ‡яа(ЇВcЄ5Џ[B@@@@ PСИ1aV " QчжЙ3ыъ з={АЏјЂќB__М›ptьдбhоЪТx§Цчmџ‰:ЁzђЪцїј(Ёў=З$Uс5„н#—6Љ[J‰Ѓ$#qH˜—ІЉCQЂhеЊСн/D_К|)+НкP ”EˆЦ‹—.>Эz№аQЌ–њ,Ъ c­бИНћJKJБR†9œNиWk.ы%`Єнћ’й“dщ…„H%Ha—Ц@"––ЉŸ7>"Њd.g0йИzхјУaпђˆЪф№Ўc юъћ+f1‹…ь”(ЃЫUЄ|gі†ЎƒКbG? $*щMZŠсކPTлQY0ƒ€Ѓф’Ѓ›= ЯЂfE]ПžЮRСб A6\PTаˆŽk|œ}Š•EХtбн—щЧKѕ›ш?bєˆдлЉЛv&ЮtRщ6Fдž/ž‘a‡ыZiЖДqnƒFрa4бЬЊ>ЮК<О‚ЁAѕBT@@@РXѓbєVп>}ЫЪh,МЄZJ9йг#ІG/ј’љjHюЃ\Syh4БŒжNЙxМz ЮR‰^9IкxЏK7ћvDж‰8ћ‘вчЄ4HЄФо‰0bR+Ћ„с2ŒqСЫўяїЯџr~ѕ›L Ђ.bjФвхKЙ[0+qсдI э"zфІobИ‰+ŽЦ| ёxb  Ћ%Г”їшбщц3Zщ]ш|%чН>Ѕяхг/а;ЭьЗу^X/УпОEЖякооЃ= ТиёcWЏZЇ€sЩВ%ˆВщ>5КФщЭA79`ђуќ_ŸМќUE~O|Жcю§Q‘СЋжЌš:cт=њ*'mо!П?&уќ&Гœ˜яp„FЁwЁеЌ› ф2šhц?ХрЃ=˜4F‡_A(h„oЎЧ%7?‚‡›jдЌПЭњbёАЯЮ`бл?`т„ЬЦaŠ™М\ѓQ€ –bС § Т5rњВудP{цМkoBбФš‡ŠќIШЧп‘I•ЋяД…Вc’]’@G‰cO‘c_ZLr7Oи–!Њ˜СЦ|,-#Ÿ]&ЏБТг"—[^a‘вš~!эuыдGV†'"ЂT?+žю4œkњ-вчАZы4$twшЕ—IіюФ†b$іГВ"љJћ“н&}ЈI ib Ÿxзg˜ Пе!МеDЄ)ЇXУMЬцЭ›‹ФЃГФЇ›ƒO‡~.э“^aФ{*СцЦЂ2rэ)Хњд2"qВ^ѓ]ЭщёбяP0Efc 5Н95‹‘y‰Ÿ&Ў№йVzліE>cч=h%ГѕзЖ1]ї5Є4.?=Мrя„™‚„[MПV~~Ћo>sgМL“gyФg2 šOJr‰“;зОНЁщ4ЊYrђъ5Й“ІЉDŒЧЅцзЦЈЃFzмwsпЉмSП>ПOD-Моы0ж}xфп­а “UЯbТЮ­[~JНЃR•Жї№š9ЋoPпцзс„ ˜CC ^#˜“=кU“цr їо XѓKoEc 0zx4ЮFgЧшИ(Ит;4jНЋFБ}цд)иsšz3keєЪГчŽ6њѓА:„qiЋ{dУ<р+­W#мВcЫє™ГG„„2HEkжз~ЫЁsђшIЌpѓїѓњdт'Otї ;ПœїЅo?џЈ9QXjЫвуUh”KbVХ€Ы™АJџЗ}q fеДЮў$W;аm[š ~ўАЙЅЛ…зЦѕіЧ‰ГДСр0A€ЊaФыЃрМК7џЯLH Њџd :Ё †A€Џ ЌU#ќЯутЏЕxГњщЇСƒДГ#ЦŠОyчцСя^KI0xРЪх+Y’™‡95ѕZъЕ+з<;Дћfг7\VЃєлЖo+Ћ(;сќБ#Ч2вЋœм$ФЧeќ’}ь№1X[ЗйlнВ•+‡ `…aіЏ ЭЙ3зž?ЮІ3ў^vьЬyœХЯ‹хшk%Шј9урЁƒи‰lEˆZAZFЁ&…@еі‰џќЧШkš'ЏX2Ы“ВVВУGGNЌ•Œ?wЏдє,fЭn/Еєдt˜†ТЈk§zљІжH 3Џ 1E lяžНи>h“‡ d]ЬCзмЙc'kбjхшGГх€Œ;єѓMDссgЮС]0 +ЙzњзЏ^—и + 8,-аьS0U4>nЦ…Œ3uWHhj“ЦxМpюТ рAЦюшв83fhxнВєќM+{!SВ•‚`LLUмЫЪЪкќ?›сйфеџ{Х№Ќ’QzиїcЅ hѕЗЌТап№a•ІƒЊ—УЋ=˜М5vЙјBQXIЎ—Ћв5Вы˜jЉA BДо˜—‚lБћ;д…Ыj[Иъ’Бqi­”эzƒжМлkЅ­у;4j^ жЛO4@ЦРРРф ЩuЊhсќ…№зkЩз№ЪƒЪhdŠЎzqАяНMг_•CаЯPˆюЌЁn" “ЗЦOƒk Ќ• :ƒBЬb№‘‚ЋL(H@@@ Aр+Ё6?–ЏdюЌЙёЛЗa‘ c ЖГsЃПњв|5*• ЦЅ`”тmѕњец‰qjœqkЭз)7lмРбУоъ˜еŒŒд‚'X/УнтcЧŒ]ѕѕ*eЉьmлЂѓАХИQW юVS+Е9k%рЪD@‚S(Ъ ŒŸњ™Ў3squ˜`ѕѓ§ъ"EжЎј”Ј9&…žzaBhкЦXu‰Т  |‹Џ Д^ƒ–;џё§хŸ.дЯ?Рk§к•CƒCЬЃМfнšoП^чхы>#мЛ›Зybм1s†”Ђ† ‚Y@яюо-*‡…‡!ŠBPят%sƒ> ЊY&DБƒ? vtte рW‡|4' "jБVz!њњR№ѕ1Jр‰@‹їХNСђVн[}(kсhнSўЇNопО‰<ўХNDd”‹ˆHўPб?&”ћcS1ЇЮwБŒљ9B Ž Џ§z­eЫ№ьy–"Уц}иS>sŠYл"o'MСжЈ!ЯѓэЙpv XQѕYхг^зщЙэ‡Л—•ЋUЂКcyЄoУj­гЌлБ‘ваЄœІ+ЪIyСЮQўMšфQкЇOЃ„›ПFи0АbTc›смВyЫ№!z dІzЁf„€†H‰ZЏ„/iыЕ›{ Aќ‘ˆЕTЙ%‡Аaщ*wџt!ksеЦюЦz†|ЁѕЮ6 Ве d`ьЦXЮЄ Gcё_AhНs„‡Ьh№JŠ=‚Љ7Rс.;1Œв‰ Œ@ќžјoз‹kзћšеY)лЏйjdWЊ ГLfXVчтn2"ХИh9\ї‰лЫrRmЩ F‰йуж[…г"ЇН~э–-Aq9Y )јЁеžfŒ”Т•uГёЦ“Xdуђ~ЋмЄ§к™І•dоЫйМeMг§ƒњз*щѕГз#ЬW a=РВ4")WSЄR)мчJЄsœр‹;с@BяW|qcRЗBЧ†žх—o џЉ‹‹UЏ0ШьЂРд Јљ‹ …Ш_lХкб % ьo†™„ШДrn“zъ 4B3єњЗxіjО‚АБЄ šдД^1њ a&‰@тёФ@џ@N ‚G„{єшєа1Ь`ЉЉcомyг"І}Зэ;3ђвTозOЏ7лЏ_uЃ”РŽyіžž+uІ_€;ђъwђлq/SгF™Фj‘ИНqэ=кГwЧŽЛzеj,'AtЩВ%ˆВщі­ь ђ фэфF y‰ю''янgїъUеР‚v™(#!ЁтG+ *в7ФHЗTЋељOђ'Ц/gЂdzФєш_bјњnn^южm[КЗгoŸ^ЭwhTX5ЊЌhЪь‰л>%м€У™гІюйЛЧ б J‰Ј:˜–Y,­7лфЁс‹*Њ _; g ;ŠЇdЧqѕшцq3ѕцžК';џ‹љАЮиЋg7œАЮˆ(лЂйŸнop?а7X%н]Т'+4ЏˆцE˜“‘ˆЂ”ШFЋR…Є%•OQђаOФ•C,{Lыœ<КxЬš; ђђђХЫмW]дgQоў'„ИЖw˜5+xHp­-тгЋљšX3_Y5Г:цIkЛkэ&жjkŸpПљ#`Н&ж`н0dLШˆс#ђ!Y№эбlзЛ.ƒіКNШuъ#+УL­ˆR§lykjѕцГ~ЋЕNC.„‡’фГюevJД Јѓ‚якP6ЁЄЙ"К“ЗŸ1oѕЋнh.>НZаB'$ Мu$JЬЫЫk`)јжЁlЌСє;БЅllй}цЦ(Ќ4MDэO”ХlЙ§—˜,Ф–HˆCfc$•Oln‹l$ŸL}гRgЏЖ‚9B+элV„ЦЂ:ДяАsWЕэ†VФПѕВњъ5Й“ўU"ъUЙвzbŠsЏOЇЛ|џ‡}їЏп  ŠЩ_(ЛЖn2џ€ž!Ёbоk^Ln>Џц+qеЈљІ w^,Х§B„ъLЩд#—ueЫх~XБМ ЁЙцпЋљ6тЊб†Џ1ъѓњ љџWЁNкр+…UЃЕc)PX!|Ёѕj„oTй2S8nБЇoьxХ.W+ьЫЭ‹ЭbеlѓGЋŽ-Ьњ™БЂ‹ЏиКxстдБмZhЌПCcећšЯЩJйЎwЋ›w{­Бu|a­!ќeдЛ[TЫxДZЬ‚шg_Ч|Н§л_”ЖoяЕ~нJЙУsкЭДЭБычџкЪЁMдŒЈ!КMTqлЗ%$%ЊўP :hyєrжЫ YБlEќюxиєc]œ …А2Я(З06)lыЖ И b}Jƒ(›нhНFK›,ћ;дЅ…x5JНuсб­•ВmЄ%ќ’šw{­Дu|‡F›ЧсЭ;7~№ZJњ€СV._Щілб fЭў"ѕfжон{3сCK{$ФЧeќ’}ь№Бk)зlD6њV|2~Ю8xш 9В" W}йЦfзПB#„Ну.]x-‡1SЏ~™BX@@@@@@@РRXL#ДCoДœх‹—Г.ж&Ošќ­[иКlўbЃј]З^2‡ЅбKйФ§?&эмБSbЯщŸѓљœбžПHgЌhсч 93чцЙe•EаДqЖпћ§!ѓФь]3ѕђЩ.аФЬ„EŽv{6=Йз хKХЁŒCўrџСž#вž–>ЕkI…u”й2N„Ѓ "?ѕ-ктхчDЬцТ’x}F7С†А,)3ГшЛЗеЯžг№ЭK"JвоеЎ?БgSiпџAѓиGШ9Х8'ч}fЫoС>тmџГMњЎЭ_- +<<И/>lxUЧвУ‰•ŽUЗL‡XMБЄЈdеŠХ9r hMгъю˜ЉЗжМ€‹­QпxvуAiжфЮсЩ’ЗЇlъ,ыВяьоm"rр~|ЛїмN=Й—Љѓћ,…+БЈЪ*В`A ХћbЇ`9 Лk5Im"Lе‹JХйd5 ќЩxdP@МW”Љя•)юeHƒ$cЧлЦяz/x-‹І.ЕЮšЪиєг1­Л9|bВpyє‚3—Ў ї%чф/ѓЬ4жcз­п™J;Жf|BЪgfЈЎKЉеh!бЋХыс+›БFєaам9s§}НАvtуЫА№0яюос3Т§М/™ ЃGNŸ3nт8n.а( ›Ѓў`…ЮЅфK§zљNœ21РпЛ&=ЯzkfRЊ!€Б[F:9y_V&‰%tdњРфпэьmVl§qєMJЭLRЖь`UЕЌќ#–z дП+у(ИЄП=QЉеRЂ‚&хфUЙšѕYЯ5Аs‡g'ЯШ™‘pМЬн5Нбє7—ЈЮЬbD8#™Ћ„ЂКv uї“yКЫ’ЭœA>№VkG$щЋgIГгŒ=ИІЙvpХz{ИQЌМcфЗ~#5бр;4jНs„м’N.РТЩEŒГ&ЦI8 вЙ\lКQƒђй(м H`іъя&QщŽRПX3eВE WZcT"ХЊЎдИ_47—фkmлОЇCп{šЫюї”­гхež}%bf9XS;тїФЛўляv|7§гщMЗ7ЪRM:~œе‚A9t“‘Ÿ4ЄЈKKФm‡1rЂф|евN(_(с˜wZфДSЇOНQоъZxљУ{ъR­Ё1 q(ЮZА+^Ў}ІЙ\ђйьмеK%Я‹В”ѓb/УжБ>‡gЭŒ8uўb]kЏ+Н ж1^@Р pЫ?ДaЅХ3ф+њ;Œя4OnыўЁ§PъБ\SцrsГф\ )Њњ­ЂЈЮл№%юътŠ2МdйІ|AГQюЊ7с@BяW‡сCbK›НNз”Ћ)RЉ4lJ˜дAŠpђZ/БУшOD"&АС§ŠІяўЂV+Щp(…к9B §› лм’V’/ч|љрС]л5dYєЯNЎ8—E/C™8оа“2ЖZЁ ЪмŸoц>}ЊЦР‹Bцd|ЗхŠˆХВЧ3ы–qц?­Yж6F}ѕ ч1{+vcЌчžш™sцЮŒdѕћžQдЗШећП‘Ы(|aѓиGXk!E@ Y" !юхр9ВbЮсЋ\fЛдюI;ыЇpQп5P\QDRwЃ‹‰ВjTэ“Аˆ™3fц<ШЩy˜уйС3fеR3рАJ Ўl€ЅLMM=rьLNюoУFŽ™Зxž™ьІnэнН3"2w#Т#6EжœвЄйП+vЅћ()ЙфWјHЙщ€‚в_G5љC‰Sžы1њЛ5жЗ—/ Шкk‹ ‹oнИ‡3Џ0QЄГHћ Њ|ŒМў“ЊхT`)D9ФŸ_Фљ”щjgWFв*ё›[ЎpH<Лbј—Ти)Э-Я`я0WHЛэ;Жwщосэ[Зgdf\Йt=>ыcО‰ЉЂг†Lœь_В‘1ѓNцѓgЯAk О‚s„Ќ,4u5`Kˆ 4"‰Yъ|%FGхO*Јё?фLEљEзЮ§ЈьуВ;ћь˜Яpbз–М,&ЪЊ9˜‹—.њѕђуАЯ_8џфХ umBЬъ™ƒ D~љ -­ЎйЁ’ўtчNшЈPdФсZgПъZESЃgЄ T6Zцы%A˜eЃ ЅyŠИ$Ez#kђ Е†=:vьЗ3n]Ь:–&щPвђ5ы &т\Зf]вI5ѓВ)ЏљЄL[•Б!‡ž†Ђ""Ÿ6]эшЈО§“:ѕ:љя-_Юбъ…4ЙwмO'…yUЕJZзЖ][шpЛwьЦ­§тбFІkйŠ—.ZzъxЂ>Н‚§і6ЃЉ5ШЮWrs„ьЊ™šWЖ„Ј€€€@c!p2›ИHФљJr1Ÿ’Rp}Nх”ЅзtqiŽјъ&bч$vvУЂvЂб~†KфŸА—:6CЃЬkЈmлвЅм-žЮжd!ЗU—g^ХэнWZRŠ•2Ьсф€0Ќ2ёЯnu”Œ|_2{Гp)Н)# йЅ1ЅeъЇЧЋfЮє[ЧЊwИ>zєhvдье+—АwaњQ.з=PЙ“ћ’ѕsщ‡_ѓIщe2L—Ы(J­`муЯ‹&§‰щWтПЩБд‹цЈПлF§SЂDмRЊ%б]ижЅЇЇЛЙЛee3ŠrQ~ЁЏПЏЖ[8tьдБPaи3M>+њ… ѓ„ЭxеЈQ\„DыE"PnONч)ЖkQD*"Їђ%G3”фй=bїОИяtbыШh„8~Я%?LуZŠeвSЇMЭЙ—ƒ7бoyПщцraіПЊuГ2FїПr%МV@Cі'@soy„уі'plМVсM/3Ѓџ‰ЈР(‰„JКƒнbрŒжvT–'0ˆwЩ‹™?3{@žСЙЭѕыщ,UYnCWAQі%›Э§oŠэ0р‰Е0єЎЪ<эl1єТи­ъБ5ёнфк r"H[‰пw"н,Ё‡DЧ€чТљ 1FкЪЙ VrƒйиV§0EаЦЙ pЈNk$ЦW s„FР’š&5оЄУ<Ф>ЮDŠUјz }I€Н’Ш:g?Rњœ”ц‰”и; пуZ‰ЈmˆJЅТ ”9 QЮ_ЂГ)ˆ;]КћХэŠƒ,T”(–.Љš8Дoeo~u{рI<žш(sЊкрp=^ЇrЌ…:†@>Ѕяхг/РД§лq/Ќ—‘йђm3‘Жk{{іl†БуЧЎ^ЕЋœp.YЖQ6нВOŠsv}ћ‘Gщ›iдЭЋJ(Ќ• ЏфЖR…” D ‘JХ­[“жNdаЃebH3Аwр‰S‡ЇGL^№%Лс;їQ.жЫа›"РЮlр€~  жЎбЭMжDƒЏ 4Bм…Ј€@“E@&ЈІоa,~IZ‹”kМѓЇЛх2ъEзо„Ђ‰=4љ“П#“˜ЅtьуђЫ—.w;|<:ФП‡e2йЛљє™гэк~<њ#џРЊєйŸнop? Xq”ЏиЗ'|JИA 3ЇMнГwAbsŠU‡/a§€ТйТяx5Ž$ФеЃ›ЧЭд›{vъ šџХ|щ{в^=ЛсlэиQЖ8Ы>)>,ŠЛћ‰RфC|хlюŒ1Šs'е% HDё{ށŒtt"mмШ‡§‰—‘yPЖ–ёПчŸџŠњ,Ъл?`т„зіГЂf 6рС–дbйWа€ ю=К;:;ВЙjЂё_Яѓѓ?›œ‘žљŸџl5(Z?ЪЭъ'ra КоРRW,рцJV‡@\|\єWЦMНбЖшџ /<"3˜СЬv2вэХб5’{”ИyьаўSХ 6цc™Lљь2VБПQЎj-\ŸэZ‰›A{]'ф:ѕ‘•с‰ˆ(еЯŠЇ;kŸаjЪ TkLЌ}EЮьgў‹-ѕ|~Е оЕ'якˆпoMоУ)%XM:6ŒHъЙŸЩ5‡IыПЯl№ Tв…,‚€\BZKˆEК9ˆeіrтFlэHI*)-#9з‰Ч F JœЋ-Ÿ&U)§kc6"Ђz-;?MЊMZf$йЦэjзvєўDѓŠˆZ0KcllФP!ae­Н Yo)Ё‹9Q‹4›Џ 4ЏZ„ЁK!рю@жWWѕм3…?Ы#>“Iа|R’KœмI“Д,c)ЌЂœWЈЩf]ЅJФx\В žыРd+‰xйёШQъ3ЧЩЯwЩџ-fЄ kgтб‰јѕ#zжdъPf%щЁCbV,ЋŒНж/_A(h„ЏГY@ б€цч5‚9йЃЩY™Fчє­bKcš{1_инђ§эЉ1{4ѕ“яbaеh§№r 4qј ТЗA#4хDТT:џGћњ%˜ЏыM—oОvсЎ€€€€€€U#РW ЁU?fySXlŽ xLебвaБbУЦ ‹,‚ƒ+‹№У)a-ўO пnО‹ОZФY6zЭђЙ’Qџі№яГhо"Ќ~Эb…ь ‰@c§ЋозФжJйЎwЋ›w{­Бu|a­ЋFн=нын-Њe5xш„9“<ЇŽŸТЌ!Д.+ОZС= Sщ€ў‡ЮAіJXПсП ююџ1‰Љб^Q4чѓ9'Я4JЦ–ŒkŸР>PU}Е’%Ћ5ћЉгеZ„(2Т8фЭ;œ8{Т†Вa•ТŒ;ўўUF#йђ…kѓ@€жЈo<Лёћ[h ќ(9ќ‡)yЪМйg?K~tтР§јbuоўћ лnmRЊ•jM-cЭЋkE‹їХNСђVн[}(kсXOѓcMЄе'ГNnКВщiХS‰ГхlЃВƒ;”Є я‚г›Š9uО„ЕЮ6аkВqш№!x5ѓъ^ѕIuшШ!x№%|wq‹Pє ›J7(œЩƒX]ЕbqЮЃYэыYрlјАсUх˜€Ÿ›#„КЙяр>,ѓЇfфЊ5Лч/…ШегЗчКЏПЇOœоИvуŽн;F„ŒИ{џюђЫЋ8Boє.xy“5T+{\ї0G{йСћџœс7чй;.ѕ[[P‘KQvR;›pпЉR U\‘‡‘sZS.n2_хекP#ТaШj4Ѓу„ЎPЋ`ƒjЁЅТPCЖ_…ѕ8WgGјЊ/W—ЋД.0#мўJ;…ZБ,eўб‡GІ$XК}u.ЏЙk„’x,ётХ‹-ьyёќХФЄDvђ vъ8эPџ=e*н(КЅыжo^З|&ќЗm•г~FнЖС=иѕЋз9fрnЭh™\"& #У#с ’MЉ5ЛчЌ72hŸnђж)’сšŽў7r=ХMю†tЎ"!аœ‹Фф84 r9MЪ:9Е+Љ(ё“ї•З’[еЪŒ9+ю†{OЭ-ЪЅс€B8š6"%jеKB^вŒ=Xы<0Ol)ЊЅЎюкO—–.є#к]уОІџІ‡єѕиs:яHиJО‚аJї&Ÿ=йЃ[}] rЋGЗ.Щ˜5#PЮ lAbс@€{ Ів9ƒ†:}ќ1фиўЏ}ћїAb6ю›ѕп! чXЋcV3вWCА\ыejвшЇ@#Фаhћі:gcЕfзч|езЋ8э3 Я€uП6b іб˜ukжє аЏH77№ЦБUЁcwrђОЌLKшШєЩП%кйлЌ ињуш›”š™ Ф\ЕЅ%УREХяŠЧџWKhuхHэЈvјL­ с,фUЙšѕYЯЕPs‡g'ЯШ™‘Š"wзhєFгп\bС‹‚|e>м[b|^Ћx@21Ф-„ЊА;{ъ,xіАѕ№щмeыэ-˜D4рЄћ_AhЅЋFї<0qќDˆCЦNќWуО ЄR;щACF<клЗЪEВЉtƒrєЃ!cB$XЙ|хЅфK§zљNœ21РПЊ@Ž2,<ЬЛЛ7ќ€ћx-^27шУ ю–~€›#„ГЗ›щ7зГžН[kv†ѓїЄC>‚оШи`фэаУЄƒ3f—Œ0RєkТЭ 1†A%RL~kgяЖ$oœ-щщаЗЕ}kw‰{ЪжщЅТнЩ]в$nЧя‰џv§ЗИ6Г‡Rks”j‚e2ЎУВ:ww“Љ†ЈЪi"З–х0ЄкшчЋ§ж[…г"ЇеZx$?ФЄ`9!M˜ Јэ!щv-х^МоД-вЫœкл'м2mр>РWZЉFˆэwмQЎєэгwwТ&*"KW,MMKНrщ Ж@p3s&гЙ"*7r ~~~ЈЫннЛ S3ГЮœ:3"$”+ €Т wSгВ<2xж!WŠ6P5pњsVъдэ[Зыoе7šНЊ|Д(z)rсD aЙ›;ИТkQ\FŠюž№ѓ&а‹Иvpѕёідзl№ažp Ёw@oWзfЅЇ%ў˜иЛЂУ‡ „ыm–ю{Ÿ дƒAБќCћ&#-ž!_бпaмxЇyr[їэ‡Rяˆхš2—››%чbHQЕзkЪеpfzј$в-dрУ3hP•>ЗЃс>x@СNF№ixР6ЇА)aR)Т|В4‡Y€H"&АС§ŠІяўЂV+Щp(…Z=JCџfТ6ЗЄ•ОgnМлxZЃ rъO”+ѕКѕш–OrюПМ†ЅЭNЮвгЙЇѕЂЩ> !pXыљ'dќюЪя$Ѓ‰„ФnŒ%ўhpgЁ5Ж|Ѓн‰|Ё•j„њр aC vуZьcЙwћох‹З.џtYПодЋWŽ;’“›3&tЬј‰уЎ^Мz$бп†…ŒY2KЩ}яЗэЛQ#Gщgч–w‰r№œY1чˆКTfЛдюI;ыЇpQп†"qEIнAŽ.&zЃRŸF}њеЂЏž>.9’t&ѕN*WW­<ГSь,л\.xNП|э@({^Л9–K7иЛ{gDdh"Т#6Oм<ю: HГWь:JїQRrЩЏ№‘rгЅ!ОŽjђ‡)І<зcє;vkЌo/_ŠЕзпКqg^aЂH7њtRSS;УtМ‘cц-жu< тЉЂЫЪ ]ўgЙŒШNь?‘s+џSЯ™Ž”Ыэ”лиDссх‘ЏЩ9SКŸˆhЪ–Јh•~еІњZš§K6є–Ь;™ЯŸ=gГM„ў‘™Ъœ‡9PLcО‰сЪЏй-Oн<дГkGk^-hM@№PЯ=0!`ЅРC}вIG“ŽВЊ|AAЏЏ/ћ2ТЗчЃGXе\­VЗmлV?ъбЎэSЬWiЗвVЎ^љусБfЊ2ЭмЏўп0ў–ZB‘{ЯшЛ ђЄ”ЌщЉ)Rzњu%‡ШУФБ‹˜.жюшВ!vЙ[ЎŸЯsОРрЙЬЁjƒOžAЦЖ‘- Q,ђтr7эЎQюѕйV ЮЮЬf34ФГЛч•ѓWdN 3\љ\РhiM?QПНLЛ Ѕ’АсВŒхЕ4dл6]ЅR?­Ё §fкЗВ?vт˜{GfŒЧЧлчшБЊŽЧСnЂf:ž~сu s­ нккХЯqJЧ™ї/мП|ёђарЁнМЛ}>їs0љспќ—У’.ŠyаЖe—лf/Ыfы2га?ЙПטбD iРќ­jќ›Œ&ЂПaхз‘ИmrhN5|*Л%_A(ЬжЛCпBЦŽЛzеjf_Ю хъeUжћxB1=т“YŸЁo‚gF™F7щ0Б3‘bTUCД/ АWY'тьGJŸ“в<"‘{'BЕ ЬжmнeаDYСЃњЗV_ЌМUы/ш˜Мz‡ЅIcЦън1L<žшЈ/ћюбЃвgАђTш|%чН>Ѕяхг/а;ѕњЗу^X/#Гхл6,йОk{{нЋБуЕягё–,[‚([PЭЇУЗ‚њвM˜ќ8џз'/U‘пŸэ˜{?dTd№Њ5ЋІЮ˜xОЪIA›wШяЩ8ПЩl=цћіЁQŠZНvnїЁбФщгЃ|ЩШ< С4tlЎFЛ%_A(h„ŽB@@ VЂDcxЗЎнњїыиПVz‚k7г>ћлgьРЎwkЪ$туед; aёKвZЄ\у?н-—љяк›P4Б‡цЁ"ђёwdRхъ;B‚‡Cu•;Ќ\ЕrзџюЊЕ"}‚йŸн>њмјєь…ѕ€тЫЕl™EQ{ті„O з/с™гІюйЫlvjЎGQyјж(œ-ь(S‹b šЯѕ nX§БgЇЂљ_ЬЧЊ^=ЛсФ*DйŒ5ŸŽAК;ИOю:ГTё C шx*ъЅRєМgпnФžІEиТ$B Т[СЊо1ŒЉэaО`}ЌgЯ Aн{twtvdГMŒњ,Ъл?`т„зіГЂfЁcs 4к-љ.–сJ1р&Hо­SЂАXІNp ФMŒ.FUћ{птœыџ /<"3˜%уэdЄл;ŠЂk$ї(qѓ$иЁ§ЇŠбљђ‹‰ВŒ|vs•чтM)>%ыГЭ‡окi кы:!зЉЌ ODDЉ~V<нY5ek-­ж: нzэe’Н;Бхpа EF Ђг§IŠn“>дЄ†4БfЊ[ Ё5v6gZKHk ё”Б‹Лœє #оS $cQЙv`щЄ ФЩzЭwев~ЋКMПCС,0ўBšг!"‰Ÿ&Ў№йVzліE>QaOЄі •Ьўе_OиЦtнзRа ДЭМaސL‘€@г@РнЌ ЎЎъЙk­7<Ы#>“Iа|R’KœмI“Д,г4 l .^§Ё&wђQ™JФx\j ZАšЈЃFzмwsпЉмSП>ПOD-Моы0ж}xфп›&О‚н;и€ш U X z`NіhЇлЏfб:Њ у9.Z•сm aiLГo:ІЃ‡Gуlє–šъ–|‡FАбЁР€€€€€€€€Р›@€Џ VО є…2О‚Pа§Qq Р7Џ‰€ХцБjі5YВ 4ыяаXѕОцƒГRЖынъцн^kl_AXЋFшюi!З>GынЛŒgфєЇџЇ…o7пE_-тlЭЯаЉVСdcc­uZьяP№j”zыТЃZ+eлHKј%5яіZiыјZѕ!ысяZђЕ€^‹.цз]šЪ*˜lhP„њо<гп<ЋЏ[ЌјУћюжmи‚тЖoKHJT§Ё4tађшхbŠйtЭьы˜лџџЂЄАНK‡ЏVЌ~žŸџн?т‹Š~mпоk§Кѕr7­н ‰йsсд d4|фвEKсR'xd№Йч8_А†ЧЅ­Ыh{єРм„Ё IDAT™3UwЕМщGЭДТhЩBтлƒ@bfBŽ"GЛ=›žмk†ђЅтPЦ!Йџ`Я‘ щ OKŸкЕЄТКGЪlЇТб€Ÿњmс5^н™Э…%?XїВ…R‘˜™˜ё,žЕЮПˆЗKяШ^Mhс[ЁВ’ .]КtaКTB|\Ц/йЧЛ–rЭFdГuЫVюЯpѓЇ›pFs-%}иШБ‘3#ЏќtsчЎLєЃapЧ’mлО nW9Гјy1Ђ`#‚G>z˜+чpтсаб#nІ.Ž˜ ш3Щ%š дЉdS…щЭZЃОёьЦ?юoЁ5tђЃф№Іф)ѓfŸ§,љб‰їу‹еyћя'lЛЕIЉVЊ5Œ6сhjДx_ь,o5аНе‡ВސˆV|œЬ:ЙщЪІЇOm$6vЮv”ГЪюP’‚О JLo*цдљ ТZч›ђƒ‚j…юЉіJXПсПСъў“-X$Б—@œѓљœ“чNrќ/\КмAц€єqЦНњЏ.^ШEdІБdЇNŸbВk_­@щуџ:~џ§Ќх~\їк?~тѓuq•"P“I§ЛFУfZa”^H|Kз=l^џyƒмћЭ№›ѓєef`чРиЁлOHrБїкй„ћNи9А˜ЮC/Ѕ_–[ &œ9o.`-œз‡OЄFЖ 5c– jЁЅТPCЖ_ŒЭWцИ:;кIьр)ž‘ЯП. X=№ќe)ѓУОГtуъSп‘ЋЖ,УŽ(Т%еЊ‹sх@АСMш№aУЋгƒЁЪ_ЅvАT?Ъљ …їKx eГЃKНP"Œ58нн’Џ$4WT„t3uU1@HM&ѕя ѓ,йh^!Б# ‰aђпЦŽШфtvY''Я’Š?y_ЅFIlU+3цPФfБїъмЂ\Й FI…ЃЩ!`Ѓ!RЂ.‚WB mНі`1Њ8Ъ5кя-­tЇ5ФЅЅK~†ТнЩ}MџMыnЯ=ЗіЫрF6:ѓVh„l7‡шZЗ~ѓКхЫдДК•ЌЭѕЋз!{tgfVў №~Щyz„Э”ЦfŸјЩд%ќ a\У'ыЪдЉ.}&сЅЌВ%УБ]MыTrЭьBJsFпvЖ*t›NNо—•Ib ™>0љЗD;{›•[}“R3„”­ХЬ<[PЩˆп?ЎЭљ™m›дŽj‡E 4œ…М*WГ>ыЙ€š;<;ybGQЄрю €оhњ›K,xQЏЬ‡ФјМvœ Š-Ѓл†И…PvgOЯЖ>ЛlНН“ˆœ4pр+­zе(1ЦB}ќ“Я&У—уъ˜еŒ0г‚'бЫъі=mrУЦ ŒлUЅrезЋ8хвЯЯЎ(KLLДyзЦн]ЗŸЄЎuqLЖџРkпў}…ЪRх7ыПсZСъZ2—Q4{Фe'‘bсV‚У мј BЋž#д‡8dLШФaсaонНУg„ћx-^27шУ }šZУГЃfУћх†р„їKDЙ,Ÿ„M_Гjъ”Љ\J=ъb™\Й|хЅфK§zљNœ21Рп›+ дЃd.ЏxЃ`б[>ОФуwЧћјљ рљ'ОœИzіЉL‰н‹ЛЎ.ЎpЅm$oх8<—З戋XўЁ}CF‹gШWєw7оižмж§CћЁд;bЙІЬхцfЩЙЦŽо‘r5eр€Ў.Н|щ2€ѓ„ Нzƒ=мЭJOKќ1Бw?D†їп(€U8pel >ъб@зЎ -аъz5™‚ЉT6%Lъ Eи4aГКу0 IФ6И_бєн_дj%юЅPЋGiшпLиц–Д’Р3эƒtphШВшž\q.‹^ЦТЮ>эУЉв ЕЯдGїп€9”ЬЂLшГх4нгЉч8љИёnуi*ШЉ?Q’Œ;pзœOrюПМЯSNЮвгЙЇѕЇЩ> !pX‹ d?ўV\“$bђ?UЃ[О‚аz5BvюCJл„ˆBŠœ9u&5-ыРС#˜еc ˆMFEdiєвдЉ8а_ƒ>"dDVfjсj4U—>AE,“а)<š™>G„„r4\€OЩњЕсC ц›ЎЎЬ{™—/\Цї{шшаФЊ–Щ%ў0vB”Жэ[Зgdf\Йt%чa>ЂфХаE q—(Я9sŽЈKхaЖKэ‘ДSБ~ хёm˜W‘дфшbЂ7*ѕiдЇ_-њъщу’#IgRяЄruІ^Нrфи‘œмœ1ЁcЦOwѕте#‰ˆў6,dЬ’љѓ@†жБW6Рf„чєЫзnнЛ}ЏьyqьцXЎ4ѓНЛwFDF€&"<aѓФЭуЎУ€4ћwХЎЃt%%—ќ )7PPтыЈ&(‘bЪs=>ЇbЗЦњіђeЁXЛqmqaё­їpцц!ŠtЃO'55ѕШБ3ЬC9fоbц!ZіPбeх„.џГ\Fd'іŸШЙ•џЉчLGЪхvЪmlЂ№№ђШзфœ)нOD4eKTДJПvS}-Эў%џ”Ь;™ЯŸ=gГM4ѓŸЊй-O<дГыeŒ^БNФR&-ѕњB[#№PŸt(сnF6˜ЧЧ&>\d2„ ђ &ŽЙqѓ.ѓхЄ!Нћі>’tDц$ƒњu№РQy;f‹Њђ…ВџР^5ѓђСAпЈGќ-Е„"їžбwфI)YгS!SЄєєыJ2‘;‡‰c1]ЌнбeC&ь$rнw4з/ц|1xш`–aЖR4сбЃGьЊ1ь—mлЖ­~дЃ]лЇZ9 2})ˆhzz:kХЉ   dlШнДЛF[ЁЯЖЂЈ hHpvf6 ‘gwЯ+чЏ"dфЪчFKkњ‰њэeк)(•„ —eф(ЏЅ) ѓи&Ащ*•њi ]ш7гО•§БЧм;2s1>о>G­ Лhˆ}ˆњХж/ЬЕ.tWhk;<Ч)gоПpџђХЫCƒ‡vѓюіљмЯСф‡ѓ_^4KК(цП`[vЙmі2цџ‚УL@џ<šЄkKŒЋбD3џ)ЃнВ!;:jъЪБ% ЅœPЈsым™нЋƒkž=иW|Q~!іірн„ЃcЇŽFѓrЅё œЬ&.qО’\ЬЇЄ\ŸS9ЅDщ5]\š#ОК‰и9‰нˆˆb!‰жF„Ж\ь НrѕJа€ „І\НРеUЕvN ‘CЂ[j*‹ЙЅд1`_ЧˆЪфXсЬЅ› ФэнWZRŠ•2Ьсф€0іўšЁЗі[ŒД{_2{Гp)I%Ha—Ц@"––ЉŸ7О•пьy†Љ™е+—АP`A;Oиy>Фz#ЌвЈЪшr)п™НЁы ЎЯ\Лn-Є`YYY№ЧСї4WuRPDhѕKЇ–RЎ"3} №Y!њGЉkВБD3џ)Ѓј№„ЭfŽаD!* №&р>sЦЬюоФюк1чosиЛ­œл@kЌ|Г•˜ЪkP”™(D мžœЮ!RŠ`я–T„§Ы’ЃJђьБ{_мw:Бu$"fЃљ=—ќ0+ЪЫЫ ъlіЯйжo˜ћљB.Н~(‚lЦ‚ЂДБіB4$af8(ŽлŸР~Бі*šd>G? $*щMZŠБPЌэЈ,ХK†б’K^Œflі€<‹šu§z:K…эе`Џ\аnЖŒ7rгЧйЇXYTLн}™~МфPП‰ў#FHНкЙkgтL'•nctAэљтжЙr3›й>аЦЙ њ’ЛFЭќЇЊсSй-љ Bы#4@Mˆ 4XѓbД–О}њ–•б п'P-ЅмlТєˆщб ОdўŸ‚Е'Іђ-аxЂF7щ0Б3‘B…гаэKь•Dж‰8ћ‘вчЄ4HЄФо‰P-ˆvы6[ЊЦј-+xTџжъ‹Ц+0’Š:&ЏоБzеjЬ`с@`в˜БzwŒ'њВZ2Kp=n<ƒ•ЇBч+9яѕ№)}/Ÿ~ЖиЈзПїТz™-пЖaiеі]лл{Дg3Œ?–§…ч’eKeгk>Од—nrРфЧљП>yљЋŠќžјlЧмћ!Ѓ"ƒW­Y5uЦФ{єUN кМC~LЦљMfы1пАNR”(аъЕk˜щOFЭќЇŒvKО‚PаYа…Ћ€‚‡›"›ѕЗY_,ўbцЌ™AдgQоў'„ИЖw˜5ЫL^.‹љ€L">ўPMНУPП$­EЪ5ољгнr™№ЎН E{h*ђ'!G&UЎО#UG„Ot•;Ќ\Еrзџю2_‹СнйŸнop?Œhrщў§{a} жЪЙ іJ{ті„OбэОх ™9mъžН{Иhѓ U‡/a§€ТйТŽ2Е(Ц скБcцтбЭЋ?іьдA4џ‹љXаоЋg7œXаŽ(›Бцг1(атQwїЩ]g–*^aOEНTŠžїьлигД{B˜DHСЧYdUяy+н€Їљ>€ѕБž<ƒuябнбй‘хйhЂ™џ”бnЩwБ ЛFЦXмЉ)ўщТbўX ”MŒ.FUћ{птЬыџ /<"3˜-эdЄл;ŠЂk$ї(qѓ$иЁ§ЇŠбљђ‹‰ВŒ|v™hЇ§,Ю обсфSЌ>л|ш­Ц НЎrњШЪ№DD”ъgХг†s`жеоj­ганЁз^&йЛXn€­PdЄ *ў$EЗIjRТ”„kЃЉn)h„ і„ŠXNk-!ž2тя vq—“^aФ{*d,*#з.,х”8YЏљЎ†ƒђЭзDПCС,`S]Г:D$ёгФ>лJoлОШ'ŒнTэA+™§ЋПžАщКЏ!Ѕ l!šyц5B^Eд—(--­ОY…| „€СЮбЊеt5юdM0ОКѕwэfйgyФg2 šOJr‰“;i’–eє˜nўСWЈЩ|ДS%b<.5ПG}5вkфО›ћNхžњѕљ}"jсѕ^‡БюУ#џо„м0ё„8Gид^1ЭЏЇ -z+РЈзцdvеl>XžуЂЏзъ ФвЋуЙЎ c 0zx4ЮКfД8НЉnЩwhTX5jёG"( ар+Q#l 0 <4Wј BA#lЎ=@h—€€€€€Р[Ž€ХцБjі-‡RhО€‡@c§Ћ^Ўсѕ X)лѕk,r5яіZcыј ТZWrf2ън9tОnB~FGРb‡КД/ FЉЗ.<ЁЕRЖД„_RѓnЏ•ЖŽяаЈ0GШЏ“з™ЪыƒцПfŒхэii;A@@@ QА˜FиЈ­*0‰ьŽІД@ZYŽ тBUи=u<{иzјtюВѕіL"№аР}€Џ ДjУOу?Пџ'џЛћЇЯ˜ЎњЉгЇ-XхЧŠЏV ŠЛуџ:~џ§кчПІdџЁ§у'NAњў“b{‰˜Яљ|ЮЩs'ѕ‹тТЌbфыяЛџPТњ џЭЅ› №,йT \8uœiТ:T/JЯТ~ОА&1 {E9Q§’ёоИicŸР>l"ѓЄцщžšЉOi>м`рplL§djЮƒœ3ЇЮЄІІВ‰Г"#0Nžs/ЇЗЏ7МrФњж9Л~ŠA8ёPТЭы—Ў\Л‚ФCцfYhšф—’ЁnŒћњOтж’мœDжvL#‚§cУ@QIцНœЭ[vа4н?ЈПўKžсUиX>2§ГщxхI:ђДЈфVъ­‰ЃB6lо`”ВжФј=ёпЎџзZ)›RMАLЦuXVчтn2"еTx‘ИэА,‡!еžлOpНuуdсДШiM Šф‡ЩZ)XŽ^Aц‡*B{HКA‹@Gђ№і m‘^цдо>с–aЇjр>РWZЕFˆ0bФˆ‡їя$_H~’ћ`ФаJЛУкОSЈ(Фч'л№нєBQˆА\.яью–|%a\}||d Э‹g…У‡ gпнxA—О(e3\YХштљ‹nrЗœG9wFy–l4/k6СхkІлДВззЬ—†/†š,8œюheщY„G4DE—-_КœM4xRU%kЧ[ЊЂlH/БСРсxР‡ЃX,†ƒѕ6В‰rcхpТ•шƒ8т:ў№ЏE_­”9Шp"p№‡ƒfВћЩIЮ fНшЅBkHkMWvЌ,k'Љ(&IŸ“˜‡`ƒоќŸ4eвІиM\›жmкї'zіюѕ+з—.YЪњ—ЧзЯ с#00ЮeфHЙš"•JУІ„IЄѓЯhе”В№С-ир~EгwQЋ•dИ”B­ЅЁ3a›[вJR­;iШВшPшq.‹^Ц~ЪГъ VдНш€UТ„о>Ў.P§БљЯтшeeBŸ-ЇщžN=ЧЩЧwOkTAN§‰’dмЩ€Лц|’sџх5Ь`;9KOчžжgРdа8Ќѕќ€‰п]љd4‘fрфOWз9sчpѓ\КІв;И.XД€У‡Џ ДvГY“>‰\:џ‹IS"™ [НЃЌ >й|aЕ’ЕaУ?™њЏ„!ŒkјdуlмН~ѕzеЛль оПыжo^З|І[ˆ7ЁhT№)йL!F› зJ‹ё=aБтLФ"|хF*& 9врIqYл8З)xRэŸœ››‹DŽ СРсjФ (ўisЂцpЯzфˆ‘лwlЧ'ˆrФu @‚vѕъЪfAР”@UЈ'KПМJ“XZЃцFЙх.ьœOь]ˆЄ5|Р’Š"’Кƒ]LjŒJщѓ6!ьтЅ‹\ ЄјњoЗЬŠšХОAИtњєђПp>†СеjsчњYŒ†їюо[сЅif‰вьпЛŽвщ|%—ќ )7PPтыЈ&(‘bЪs=:XьжXп^О,&k7Ў-.,ОuуЮМТ€–fџ’}хв•Ь;™ЯŸ=gГMмОѕџoяKРЂ8ЖЖ+Ш?=˜мaЙa *ю 1И 8"jˆQŒтB Wq ?ФИ/ Ђ.HWИ^аЯ~FСб$тдмPЙЦ€QAtИa™DaцП|џi ›qfœгO?=ЇNŸ:uъэš>}ЊЊЛ’ѓoфƒdсO…˜Foцє_ЪЛt6їЧ›—oV?zŸР.,|ЁЙG„P[оШЛQУ3"”€oKмhOА­пД’”Ы?ЩWgdd_:;;SцЬ3a#{c­'ЅїKс‘YE›JB"7‰WЮЗ9=пrн›О|ЁЌRЖuѓV1HђбЌE W |'5VAН”ч,ZИ(uWRі‘lі!Ћž§XTјъЅT­НusC_/^.h`ЏTBу•‚jr:gNŸЙ*2Š}Њ­gћБa08*2 №ф Wтйsgo^Л џРˆШЪŒX‘О/ЕKї.АINИUDхЕрh *џам'Б­(zyщЧdпюННюxс€ўвФ•{lHIЙœСe%$6]ШXЇОT‹wVU•) xИ{Œ1ŒоA”љЉЛвЛuюіщ’O]œ]†yИСx!ќЁ”јавђв‹зЎљOђa8­м1ЫGƒйЩА^аV8Yью*šк_qвЕВXš’)НšЯzAѕJб№ŽН{їNй™Ke2dFnŒ…0іиБ™‡2еѓRNє†hИИњ|[kОB,(—WЫыЋeDfcos$ѓШЭS…тЧт}ћїuям]Ъ”Є–GмЏЯП/‡§VЕМšГSK€с*Јkvwяm†™ ˜PЩˆ•ЧГš:'"зER|(ѓЂхђu„fr0ЋЁ!ЁЖЕѕчћп€$'2#0h}єњЙГчr№Іƒš3ŽФгuеšEоo{sЇš#ќІјэЫиЗц39gFu˜р)Є.ЬGГ%0ь4љ§Щ>Ѓ} ѓ=tASд zA„Й;ПќъьХГcЧ6ЧDН7жъ  ›0 z5_АˆцВЯ_0п–a ŽPSИ жТFA€nŠп”ЈѕQO ь›b6MёŸЂќФc0p8Ы!Š… МрБуЧ(sщтЅSЇЯќ­ј7и€$'м*Тў/ж\?іБWЯžZœ|‘9VwПVјЛ5t=U)~/ЊШ“Књђ›фЬ6ХЋЖЄc6(Ќox 9Љkр8в Љ]g.I‰ЅЫУЯœ=SpЕёЎM™poZК|)„П–ќКџРЙМ&фу•Œ-&Sіь­ЌЈ„6ЦnŽ@УtГs™Џы_…ЮC7еUxоАe}!ўЏВZёk–ц1tЛ{ї.мВ6D­Ё Р№ ыPкЩб \šк'=ОАŒtНеезUЫkъHЭЮ;[њюН”1Б1Ÿ.њц*Ž}ьЭњяЩЫ„БbпІ+ž8B›|ЖiieЪ RЯ52ЫKЪ`ŠFC3rшнЇw™ДщyQ#>/=*)75'џъЇOЗЋ œ„ˆP‹/дсїх  88(XЙhЄ[D|є%Ж(fIz.XИfЃДX)Уƒ“’šпУ $:xР_~Ц*~НїkcЗ|=щжГ8 рkмр З9ЇќЇњЎ\х1”`Z&Л™OЛмп0ьnрErВюЌuП7{о.-Ј“жіыаХ­“зЦz[r}З‰Ш‘Ђ3Єцyќ;щљ6љЈqv•zЙљ=*{Х)Ÿ…aТyAѓN;ЎFSЁƒBC-uфjЧ™ qjп}ЯЊ…I“F )q„AаНœ˜шыуkВЖВ§ь2є>іHьзЏ7FVU IDATЃфŒ‡?'G7Gp2~SџЖ%. 5иј @=KЕМaШХЅіЖЂ ЮЊжQдeд_ћ АяNФ}H'RљˆT‘-Бw$Œ5ixu[E И1ИЃAїfњWщЫ–.S9 IЇюNѓцЮу:~уџџЉуйВ*Ж;lлЖ5šИRЯЎ‘“‘•с%ётМ Ш=x№`рk”7w&Ф|ањгЏђ›%ђ*ЈŒ ШьЗ,W˜/ЃХ ЊдўЩ_$їtщIљSЇOнА~\изЌ]IЪЗЗГз8ХIE›“ГЅ§/)ПL†33гfЇщІlZрQ@cO>F„<РCDРмш*rySф6РA2ФadзюcШа@2h.сЇђj’{ŠР乂"Gѓ§|—Й]mіЪ_fрSdТІk3ПsV$уЃŒunI•—;T•АпљЃ›\ЦОПњЫБб§їв jT^›–™2МђЃ"€;wŸŸvя<†-џA1q›EМ—‘Š"тшLОx`@3Б(ТЮŽЙV@дYБ+.Y"!o‡LtИївоуEЧyt‹XYЛўЕзTgпрOLh&ОŽPћЌQЫЛxX#DРв€.Pз ьNЗюЯЛIKЋ­йдІЦ˜­m5†У}УaoЋхги/ кљvbDЈГKŠD@L ОŽgšвUC[D@t†_G!ѕ…Эuf*BD@ ˆ_GШв>RѕЃmЦЂD@!РзтЁЮ GEˆ"€ І„Ю5ЅЋЖ К@ уFZЁДАс­4љЌЁѓeOЄђHœ$cњNLЛšіkхЏ6Џ2ƒХиo=у† Й МШZ /’з№е6/k K”з+~x№У—Зaq№œЛ9sОž],+§іуœЛЧінJ}Ј(NП•–єу6™BІЈg?ёŒ"аЮрћ@ШЖsМАњˆ€щ#0m``G{ёў[џ=п#ьЫ;q^ozExФ”>.b[сїЙЖ"цсуbјаšМОF R§BПщW-Dt‹_GhОc„ˆєъгыpЦaeроїџ—ŸбгвE\шc§kїю+WЏTY7DйsЄс›ю;З'^ЬЛVWWйгХua№То# "PёжBЊ1  Ќєых5zХЊмкiсj”З"іжжŽN=‡6+p–і,ѕX S`%€/ mˆ“ƒ“ќNuЧО+<œFШъeЄC]T~C„Ћm(*/r;сЇe,цКcEкŒпЎQњжD›‹1nF!#<спќМ(ФdР ‘w&џ_љћь‡XуМСVѓqcѕѓЏцkQ5ЩoиI Ž“ |ЊЋРщm{?ЖPЙ`ОгКwІMw\ьдСљmћї˜—Nѕе]/%ˆО‹fWPкЮўнQяvыъ0Ьг-у@уrИъЅэKц9Ќ[зnpЖръ•ŒCУFBвСзч]XѕаpŽ” œд/Rноъл­WЗх+—Г ?с†˜*|ЁYG„>,Xќп_§7џмѕЯ љAЪ—уј‰у+—Џ„ggиж­^I8;§oггїЅ7ў{ыIњєщГŸ~(“ЖA№іiXіwйЪЊ8‚ин%ющв6oљœуk!јh>žѕœЉœ6UxI.]cНХБoAW0 ѓЏхK$š1rU$­ШЌ™Гn7И1NЁЂЎЊ€в" |jХЇ†ї(8єТ*IхьаГЗ-nИзpЪdЋЙИёJСUP–TЁьЊўЌlЪЅv}ѕŽŠFLŠˆГH6&l_AєwDQщи!Тц.Йr<оCкU–•зO№Иœфэ GV™”ГѓЃVЏ\§ыНŠУ™пф]ЫујyпŸ;|єpaQсџ)гІ}њ{t/,њmМп”5Ыƒ§–1)A3Т‚БgsМyљfѕЃ‡ё lЗnˆ€i"РзšuDаO˜0сЇ[зrNхм/К=сНgрoИ&eв2XS›^xž­’– г[оtю‘sŽэQ„Ѓ›››ƒ˜•ЉzPц;о—оЛс]YеxЗЅйЙ# ŒNŸ<нУЉGс]xЃЋхfS9Ѕ*|Z…!юCЎ_П2'Žˆ‹‰;tќазo]>Эn#Сjy?А эьС?бŒ-СбЊЫPpИиQ%Iх)Т“ЧљдЩЋ##")SЅšъš9NEe…НЦ\z‡3РшDFЂDНЃNї3гП&97Є5їЅ§пЩмЩ_лk#ˆVBbг…<хyћЯСfЁPјHњHZ%…UщуЖФqЕˆо/v ‚р рЪ?jЃcЃЙфе+W81"r]ЄШN{фЦXx”T9‹IDРtрыЭ="„бЌ™3‚#–-™9;hх­ГИ3LЁxžЕwІtРŒЙџ“і?@УqЮЌ9” g/|Ёщо­Егќkьц„иШЕа-imEИEŽ„fSЉIpTсг*@ЬкУщѓЇr†xxzџШa–8fрsл@xyyСѓD2Ж* Eјмy0Щ *едЂ0ыHє S•\zG‹I†<•}‡t Jdфt cЫРŠЏLa%‘Й * пo#6Ž‚N=`=tR_ЧZ%jZ}ЯЎ=чО?ч=Ъ:BЯŠГ™Лр йЯК ЉхŠ›,эфшЯyœ6$SC€Џ#4їˆpœ˜wЃfЏЈ\ˆ№ЖФmчлњMы!I<<<фЋ322„Џ a eЮœ1&1ВŽГžРФ˜/ЃЂM% !‘›Ф К%{ОхК7}/јBБлКyЋŠ$љhV6lц”(ѓ•Ћр9|Tlмgу'LЩёуІФnŒѕюЩхjБhсЂд]I0б†LTOŠю…Џ^JUСл№fEлдђЩХV3ЁёJ)WŸЫ №%%nЫ<”љб-Ђ|C‚УYb\\ “=9QHlAЖVфx‰шHОŒ<ИIl^Œ":В!lП‘Џ?фЌuuuMIMЙѓЏ;[6oYєщ Žп6‚k ЅхЅvŸ/лІ s!zE€Џ#4ћˆАyCCBmџjы3Юі7:ОINvF`ањшѕsgЯх8рM 4gў‰ЇыЊ5‹МпіцN5GјMёл—БfЃœЩ93rЈ{РьOЩ ua>šYSml}FћL~ђ ї&%ЭUaЄчш 3†л2цН1@GНшVq ЬнљхWg/ž;n$€А9&ъНБ “2  ›0 z5[ЅП№ќѓ!ОiЌўРAж wršэJш:rдHvж3thW6œ5$8ќыЂ_Щz…є я"pыDl!„Ћ—Пk_сi/#т>Є“Љ|D*‹‰Ш–и;Ц:D9cТ…•—вЁёКџ4Ф‹мЙ–{;{6ЏвЖa§њ| ФЬ)S•Ю ‰˜/=*)75'џъЇOЗk1 "B-ОТ˜FЏ%;џS1›b`‚Пћ’k_1рHШ“’„єш ^‘X5„z!R„гIУА­ып АЋд[й ТЉц’!‡РЎœ7шЃ и•9H#І‰пЎQ #4Э €VЕ ŽЛ8жgЂѓ*=Ѕ­ЪлЎ„сЫioˆX/(qtuv"CЩ Й Ћ‡ЏрУzRА=Y~ПDќзŽ"ЦF`Х.… Лш"Жіwp,ZГід‚`SИl|!ŽšТеBD = Ќ'ЖDQїО–K…шСФЂ}i‚—‰HРАЅqЃp@PкŠєwr\бЉ§+в.]8s.їь@dа6Ъ’К;ѕГЭŸСQcY&Ы4SГ_O™‚Р4™nу оь% &ЖѕЄЎFNЌ]Ц8ј(ыЇэŽ?ў№#јТƒ?T>k Дєlє…*`§/˜CїzО#L_aЛIVТЎЏлeІ)лЬжЎМтЦЭТ„ФАцк;ояДшщ•ГЗцыЭ:"„Їя№хKНGzK<\gЮ8ю|т“…]'Нa— “„, iюЉŸ*”1kрџ"ФŽbvAк†эvс=h‚и—†-Н}ћvл*ИџыџYЙ:Jь †ˆ§_яoNЯљяЯлккЮДuАšƒ'юД}iУ<нКuu€'nxё NљOѕ‡Uy9Ия@8ЋxТЎhhр­9Г l†‹sUa“H@*NИжЪхзV(dФз‚Т†1Тzљo'4Oй‰žkNѕdmјrˆЅ`_О– Х–VІGхИPН шЖЪвл7иˆ–нkи|a}Е‡-Ш М ОvБƒmЩЙ3ъЅУ?о‹ _>sіЬmёл8ЖGф­ОнКv [Ц5бlе|ЁљF„№dБ`юlO/ЯЃЧŽц]*ˆ њі;Е—і9Œ_˜(јWьЙ9Й№јПjХЊж‡ Ь№"аЦѕъLœ01yG2ќoa’mЋxаўЎ§i^ Д8д=ЛvЮ ž’ѓцЬZЙ8ˆS§ІАшЗёЇ,^ЕN-ZМ(!>“й–ИКmŽc0B‹йГСР9ŒКbџš лЄЦ˜ЏтŒGй]йЖ}Ržм;*ШŸ2ршИššeаРтЗЧЛuЇgbтb–=ќё‡›А—Cј_б#%ЈЄz |]ыРџЩkjьрхu ОАЈ“ ўЌ&uеф?uВUkX+КЙЂ?<}ц4=›М=9џFўЙ3ч *d&zk4—KНFќ[5_GOИд6wфЌ15"qGbа‚а ~ў"‘Cр#fгГ‘•zэ=L;мг DuiщiоЃ ‚lт8џУœS9\э*ЄуЦzsЯ#Ÿ№ду@їюБ-[e,P%IхS’“hq№јЃс1\Х~LО gЯНyэ&ќQ#"#ЈЊˆuщћRЛtя;l[•дBыЂyЈќЃRЃiyщХkзќ'љУY8­мЙН!Jxтў(јvУ' G СМЦа z2рОУœ5ы•ЉнlНm,хЌДNЛЛŠ€ІfTœt­,–ІdJЏцГ^PнЖЦ4‡оН{ЇьL‰ŽЅ2™2#7ЦB˜{ьЦиЬC™ъy)GН 4'йF>VУ.(Џw(x_^t›мЛMŠ ЅхЄМœРБєSZ§ŸZJЖZUUFрП•e[oAФЪˆуYMCъ5тпЊљ:B№ДwДЙЃ–jїдХ‹ЧŒnX’TЭŽЄфЄъпЋ~sі‡B’ЩПšє№б“ЇN‚@вN–П№Ѓ…џјч?8/RΘ9;˜Л%q|J€ƒLл“вЏŸЋ _c2-5%џч;GЭ=Ÿ+ДnOмЎQ ™f„ѓЗтп`’mЋŽ§_ЌЙЧ/ ьџbЏQOЪžН••0S†н€†ЩI‚m”_X[пШ^ќЩт„-ь§4.>nIи8ХЩŒаnЖСЬ0XAЌ|]:S ЯшWсVoЫњB:5ќ_eЕтз,Эїv­aЛ{їnhHш†Ј5дц2i™““ЅЊ4њѕilъbmцШхu  B\X|_cЅхLл;*`ЌBТ…ЬkьЬŠиМaЋЅ i…дЮЎ3(/)s—Игч€о}z—I›5жˆgЋцыЉџгbЋЩžЊЋЊфR1ђј‰у+—Џ„ГА­[Н’œЧтxЫ‡Ožк2BBwыХм‹гІNуф9‚ŽТЅJ?ЖyЫч_ ‘~(“-ЮІ Т> Ыў.[‹0ž2/„ЯЬНpсŒхР“ь@@ђй™ж§іызяVС-šHjШ_O KЃрFСГЛeа)щi\Ÿ‡†,„Œ~w4м•т7Х\Л|-p†ТA0Џ fkЌ‹Y0йјЯŠёz‹‰˜ЬkrђЊРк І‘0]&HŸА5Ј8у Rћї.шФОpс*ы,юЬMM(-/Е7њэJєqV<а­цпефсCХЭЋфо/D^ЩдзRЫv„О"d!В;јB™аVьѕŽвОN{wдЛTРЎSg{т6мŠЕd„S<[5_GhОc„B;{nœF2xz‚‡eЪ„GŒ*i' ‘?яПўc;Вн­ѓƒРoqђAЧOŸ<нУЉGснBŽЏ…€Ї6пёОдƒї^YеєŒЃ%ž2e ЩС}5Ѓ}'R;Сcqc„0ЈЃьР эЕXNЦoъпЖФEС32ь@| ž7#+УKтSuИS@<јG#Бxбт- ‰K/iёўЋ1ћ 2лlі –kЌьѓAшOПЪo–ШЋРбљoYЎ0_FмЏQа+ќErO—ž4УдщS7Ќп Ћ’СОfэHRОН}iq)_ЅКs˜%-НЇјЙ@№G-љaї†Зщav ƒр_e˜зlЩkЖRFшьЧісЋl …frХlŒIџ*}йвeєlаМ ˜љШ:ћzRtЗцЫЈфROђiе|ЁљF„^^^Ъc{Ъ0Сгї@ЪOOљау, ЁѕњѕыўšЎЇќhьц„иШЕ0рOyмАм9Ž€r/|zPіxЃ€;…„™"0дkш€С`ф|!­ТŽф—.œuyгіќЋ— ЉБjДЯNq„ŠФjžюУ` 4ьžCGљOзpйВ{Юь9*|8wїžн*L•$cХєъгЫŠ*’њHЖйl}c0хЩOOˆа†нк†inRŒŠ=ДyРбe€ЫЅМKЛw6^йeK–йўеvшАПбё HвŒЁŸ„Ž3фUєш/)ъэмuЮ,)DѕЕ aw6nАВfЌ„ !УF„Џ2% уф?C єаRlэ\њЙ,\ДкЯž>Ы=е…|2Hт№_Зž CŽѕлbјДъ—•”Œ›š“ѕЦгЇлЕhфЦ5Ъшpщ˜M1СAСKi\кœyгC.3f {РCФžЏvвљ2I‰IХПGFE‚ц5kњіъК(hЮ|ЦјPў†Ј н{u‡^xZ:јд%Ÿ.йДyг„ дэŒрЩ8~јъpO‰чОŒ}Ѓо5kц,љљжm[ГŽeQN8mOЬƒ‚оQИњ№ЄГsїNxт” avЄЄІРЅ7Мй/ў7„ПžпП ОкЖўЊѓтfыЯ6}hVЉoЗŠ‡‹ЋaЄжŠЉћ—єз#|њ(к:ŸЋ]=95ЧŸф|ы /KАoJX3Œ5qСз„Œ!Œm‘•PоgЧZ§ўYјДjЫсЩbч—_НxvьИ‘OзЭ1QяѕЃ м<=љŒѓžž8ogс•чЩяOіэckcК б Ÿ}ИшйkТ{МюpO/u&чЬШЁюГ<%ƒдл"LЯ4pаœљsРМUkyПэ­.ƒD@пРЛљХХХі‚њЎ”Yш—ПЬŒКCйїЬ-hГ"Ѓг3Фб‰—_Б†nY˜ /wШОЩ”сe+ЁhЦ\}{Až­.ymк#B^*Œ'гЈ4ŒЪŠD„GРЎnМќЛ:џШё#‡}ммŠr8ya~ЭОД}@ьлЯщ/rPBY|ЁQfЋ?3 л;аOx;ПxюuУіŠAъ_ћЇ‚\+ЂъЌи— RІA q§(ШљН1ЗОо{ыТђв‡фЦІKБФsˆŸПО—aтпЊљ:Bѓ#дс5ЯЮЮО_|ПЙ—1tXЊB ŒŒ‘ИD,Ž"Sc, ““ЧђpВмахпЊљ:BГŽu? щuюк9q[ЂNДЁD@A€Џ#lWЁrЇ%w42ЙГH ˆ"€˜)|'ۘя{„fzaаlDЬ† IDAT@У  ГˆfЭЦb,0}Œѕw0VЙ/xEЬдь6зкВыkŽЕуы[#„YЗЙY<—Q+CрЅыъЖЌЏ#ФˆАe,Q@] Ќ'ЖDQЋ>‘“zmЋЗыЂ4}щHЛšпPe^ЕiЌxї†.ШЎЏv•п•;з;o|gлOђ ёпОŽ#B}5д‹ш д/RсЃѓpд[ zQlІfы [І;ЌZєXNjHm‚ЎYЯщ‡xŽлњіщМ XZ.хЮj$@^#_ЬвЊв,ВФШС‘C/;оЩ:DП~Ьc›o 6Лtpq{ГпіЫ‰0ˆЈb‰л_GˆЁЪuт“„ЏВёCD@OЄюN§lѓgpд“~=Љ5SГ_ ™‚Р4™nу оь% &ЖѕЄЎFNЌ]Ц8ј4­яqKДџјУр ? ў№ХKз­†œŸrМ` 8B9awа_Gф.ЂЙчsaU—A.ђРЏvьiŸіcšJщn|!F„*з “ˆ€‰#pўћѓЖЖЖГmlцЌ…р m_к0OЗn]|}о…Пр”џTџьуйœ <­Л rƒеЯ9ŽСˆцЬ6˜F)ШaT„M"opзЪхзV(dФз‚Т†8Њ^ў[3пцй‰–†-Н}ћvЃйѕdmјђО}КСО6|mC(ЦЎs giЩеNН pЇtBм(Пёl\>ФqШ4Їiг{L—ззy;ОCd$џZ>,[]B o=Щ…•Ї;йž(:Ё\hГm žР‚Е}пъ О?uзГЧ;LB`Х!ьжЕЌbЯЕdbM7рїъЖ|хrОŽаЌ#BXэ6|љRXб[тс:#pЦљsM7eє9ZK$Їш.& YšЙ\H &…Рž];чЯ“цЭ™ДВmyyy‡~SXєлј‰SЏZ Ї-^”ŸРЩlKмЭ[а]TмЛà l‰СŠsuХў5AЗI1_ХВЛВmћЄL=qяЈ Ъ€гмЪѕ2™,~{МћPwjmL\ЬУВ‡?ўpітВbHŸ.Т@ƒHЎRъm€;ЅЂN^]Cф5џ[#&тcщЧ ,љЈя‚ŽLзЫч/УK.Ў.%ѕ…пTІ+9гдЩы” mЎ @Mяќ|чм™s7ЎнxєрЭЂ‘™М=V;ЩТŸ !0оЭщП”wщlю7/пЌ~є0>!ј€ _GH#ТцŽ\&HР ѕ цЮієђ;u:сЮвЏŸцfЊ"Ÿ–š’џѓЃТ(БаJИ=qЛŠ&]"POввг npЗK SвгшˆHs~w4a„ё›bЎ]О8УowЕЩьцЊcњ|6ўГbМоbD"&ѓšœМ*АЧР0]&HсХ шВ;у ~Bћў :Б/\ИJХ:‹;sу5ЅхЅvтЮкГыяЌ['З‡Вђ‡ђђыOЎfU ™0yBохМ7ћПI:Щ3+“Ј„ V= упєmДDkшмЉ3TJХfLЛNсЮЕшфr=‡OЇF|ј:Bѓ#ЌЋЊфž}8,^„€€vxмH?ЖyЫч|TЅЪ\Й|ЅШ^$`aŸ†eз4+Ov”AZ…@FV†—ФKьиє§*  |эz/ZМ%!qЩт%-оЕыiлй6›нЖтŒž b>ш§щWљЭyXcC :џ-ЫцЫˆ;№ЕžШ“ПHющв“f˜:}ъ†ѕdU2изЌ]IЪЗЗГ/-Vu!|Ыh“м,ЯYїJ~Йџф—:ђ{Цƒ‹nљM Л~уњЙѓnЪПчМ №eђћ=2Эc-D{˜9c&TJZ!…ZЧll|ћP#3h^Ь a}^=)К[ѓeИJАј4l@Ьœвˆ_GhОЁаЮjЭЁ№т OŸ<нУЉGснB> ЁƒТwМ/ѕ УН†WV5Хщ|ВЃ "а*vЇьž3{ŽJ–ЮнНgЗ S%ЩX1НњєђŸТŽ,~kГй†7U‡%–?&?=!BvkІЙI1*%вN?8К pйЛw6^йeK–йўеvшАПбё HвŒЁŸ„Ž3фUєш/щьр<Ћџ‚Ji-tТsUѓDfѕhШˆФ^.З‚wBX&xA\Z?,кЩЎБУS{€љБ}{ѕѕх=p№РŽ:Rу52C>$ё јРЏ[O‡…! ЧњŒхjъ)ё|Чk(L[…W8–.Їќ—•”Œ›š“ѕЦгЇmяЏгсв0;68(˜3њХ “єж џ4ќЗ%]sМ Q”Ю\эE ѕв•OЩ*eг&9ёнШЁюкѕŒ;nџО§Њ+DŽх!’šОКёfШкНјпўz~Sќ&јN0/Г iэ‹—Ѕr™К}Pф8\\ #ЕVLнПЄПюT{ё ЉсЙкеџ]ўЙO2э‰a=грY/7нџ%х—Щpffкь4ƒYа_Њ^œхG„‹.Jн•”}$›}•Тф;EсЋ—R zОхК7}/L]—ЖuѓV{;kЎ™cЊрим$^9пц4Ї‡ЫСћ†ш l?u=)Н_ЪЭwт@ŒŽ@ЦŒттb{AЃзк ПЬРЇШ„а оТ’6+’ёQЦ:ЗЄЪЫЊJћнд†M.#хф—cЂћя5Єд-_GhОc„0enч—_НxvьИ‘OзЭ1QяѕЃˆDEFЩ9ё\РьOЩ Ір Аiг ју8Э№јМ/c_szИ\0}аРAsцЯV­Yф§Ж7w DР€'хЯ>ћ<‘з˜З)l16дўЉЈКVR—WR•'­}ЄЫA(фэЋ‹~š/ŽЖ-ђчїЫБзmoyЮE|r/pЈ1цdiТ…oз(Œjё…Я…УšŠсЯгyз(џЂQа цл5Њ“ъЗV‰я­-к(ђ–]_3­хG„FiыX("€ ˆ€Й РзšяЌQsЙh'"€ ˆ€QрыЕє‹Хn,@Dа 0•зІ}ŒT@з0/E(„ДŒѕw0VЙ/xIЭдь6зкВыkŽЕуы[ŒсžmnЯe|Ёb?Ї ˆ€БайпЁ5€QЪmdЭдl 5сЧВьњšiэјvт!ПFŽRˆ"€ f†€Ю"B3Ћ7š‹ ˆ€Љ"ыд[wQСЊюLmЌты–пi6еЊАv)ЪЅEйй57o(jТšє№ЁQ‘Лgџ9‡ІЯсз~Œ‹?–Ž ˆ€*жЏ Ч:йНыlїЖиКЃyšБєxі­фmфоЯ6VDЬиt/јgќPцБQоE‡Zј М*.zKѓu„-ŽъЭBTŒ ˆс>Э– |ЊїXС~– ТB]oТАžlO–п/џЕЃˆБXБŸu†]є л ћ;8­Y{jAАЎ+з}|!ŽЖ]Ьƒ ˆ@ыж[ЂЈƒU ŸШIНЧцхFс€ Дщяф(ИxЊ !О Ъu›…Џ#ФˆPЗИЃ6DРЄ~‘ пк…ЃЪвafjЖАЕaКCшєXNjHm‚ЎYЯщ‡xŽлњіщМ XZ.хЮj$@^#_LYqЉтA‰ШŠQ(Р—pчŒВG…ЁKvut,Lоƒˆœ%UstшлЇ›ЏЯЛёqёК]G+H™ры1"TF iDР,HнњйцЯрhжrFšЉйœ§m&d гdК/xГ—`€˜иж“КXКOаe|ƒOВZnэѕј|с‡С*Ÿ5Zz6њBOjLЁ{=_ШР‘.Гё лM*Аv}нЎ(3MйfЖvх7n&$юЫхяxПгЂЇWЮоšЏ#ФˆА рђЬТg™ >ЊtЅ‡OY(cњœџўМ­­mрь@[[ 9ƒс‰;m_к0OЗn]р‰^ќ‚SўS§Гgs2pпqфЦЎ\f№­9Г nˆA tUa“H@`yњZЙќњЯ …ŒјК@Pи0FX/џэ„ц‰Ѓ";ЌL{ћіэFsыЩк№хKСО6|-Š‘ЦсUiqЕRoм)вл7иˆ–нkи|a}Е‡еo^!ЏиХЖ%чЮЈ*рНXXДnць™лтЗq#і}ЋoЗЎн`нyЎ‰О`Ћцы1"ф.ˆ€Y АgзЮyСѓРдysц­ls^^осЃп§6~т”ХЋУЉE‹%Ф'p2лЗ…, t€GvCoZЬ6Д)†*Яaдћзн&5Ц|g<ЪюЪЖэ“B№фоQAў”ЇЙ•ыЁл0~{МћPwjlL\ЬУВ‡?ўpітВbHŸ.EKƒHЎNъm€;ЅBёИќŸМІ†РюP^зр ˆ:ЙрЯjRWMўSб![Е:me~xњЬi*‘М=9џFўЙ3ч *d&zk4—SНFќ[5_G!ѕ…Э9kL€8‰юо#%АnxК›лiq…J†Iр†Тg™пVс––žц:аŽ­Ъ…ТэiyщХkзќ'љC•сДrчRє†hБƒžИƒ? О}х ШŒ>‚yЁA!4WИяР"š†‡KЛй†ЗЧ%В^аV8Yью*š–XqвЕВXš’)НšЯzAu3вzїюВ3%6:–ЪdШŒм a"ьБc3eЊчЅѕ6аœdљl X Л<ЂМмЁќс}yбmrя6)*P”–“ђrЧв{Li9єj)кjUUHп— •e[oAФЪˆуYM/`ЈзˆЋцыСк;кмQK5Œ~Њр_А=vRhE`ЅxУиC ЭЭЩѕъЙjХ*нšО/}]ФКЬ}щКU‹к,”={++*aІ Л9:Ж'…ЋHдјjјТк†о38Еј“Х [ићi\|м’А%pŠ“7Ёнlƒ™aА‚X/јК(tІК ЏТ­о–ѕ…tj јПЪjХЏYš{DixЧЛwя††„nˆZCm.“–999QкЩбЉъAЃџPЏ‘Ц6 .жfŽ\^Ї Б Ф…Хїхаy[ZЮдБНЃЦZ $ŒPШМЦўШЌˆЭЖZ ’VHэь:Sђ’2w‰;}шнЇw™Д’ЫЈБF<[u+!Wž™гђU‘.^ћa$vщтЅЎI<$!a!\˜xхв•ўяK<\ЧљŽЫ>Т™аpFx\ХS’“МGyC^шПVШЕЃРcKрЬР{їиN•ШR%I•ѓб FТиПП?цЌbDjXtLtSw|=Єї0 ь”ы ЦuЏCFe” EкфЈg[BСюv t є<ѓy §юhИ+ХoŠЙvљZрŒ@2њeЖЩl§šЄOэlќgХxНХˆDLц59yU`mгH˜.“ Є№тмІЮИ‚ƒдОСm њœ.\ИJХ:‹;s§OЅхЅvтFџЁ]‰>ЮŠКеќЛš<|ЈИy•мћ…Ш+™њZBjйŽаW„ #$Bv_(кŠНобbCкзiяŽz— иuъ 1зАсNЎ%#œтйЊл‘#TЦkС' цЮž›—›—{.ЗoЏю[ЗmЅg—‡/_К$яRСž]{nР`/!:=RшДд”ќŸя=x4ї|ЎаJИ=q;ЭЋёžФћѕгќXЇ’…Їц§іЯ˜yџ0he%љWѓ>zђдЩъпЋ“v&бSIЩI<њЭIи>zIpЯЦN8xф —ї`ЦAџЩ€Яг.#&ˆ@FV†—ФKьиє§*  |эж.^ДxKBт’ХKZМџjзгЖГm6ЛmХ=Ф|ањгЏђ›%ђ*АЦ†@tў[–+Ь—wрkмa’ПHющв“f˜:}ъ†ѕdU2изЌ]IЪЗЗГ/-.хЋTrЮГЄЅї?ўЈ%џ!ьо№6=ЬŽa``\рЋ ѓš-yЭVЪ§и>|•MЁPРLЎ˜1щ_Ѕ/[КŒž šО|)ыьыIбн"˜/Ѓ’K=ЩЇUЗ#Ga_мЖИс^УЉУ‡]БO[pыŸП ьтХ‹>с+BщяRt;D„GЈc œєC™+—ЏйУ{Ђ‚АOУВПcGѕ‘ХЇHлМхsuuЭ№tэцЕ яM€ьcо›Дђ3kXУФёЌуДˆу'ŽsќuЋзAјгџ6њWC„z’~ }zРlрѓБЊХЃЩ"А;eїœйsTЬ[№смн{vЋ0U’ŒгЋO/џ)юJ*’њHЖйl}c0хЩOOˆа†нк†inRŒŠ=ДoŽ.\.х]кНГёЪ.[ВЬіЏЖC‡ €§Žo@’f §$tф˜‘ ЏЂGIQoчЎsfI! ЌЏeЛГ]эVжŒ•А!"dиˆ№UІ„aœќg”к@Š­ЃƒK?—…‹ТŒ˜ГЇЯrOu!‡ ’x|рз­ЇУТ…c}ЦЖX>­КЅРЛХBЬA€vBкџХкыэс‘‘`rAAAТп`Юq-<­Рі †ФЯw~Б3щяIЖЏ —Ќ^c­ъѕƒnwпёОMќgy›8  СK­_ЗЊ№n!xVѕ$Э€ё˜)Уe?pј а$ДžFТСЁJZFi6PчУ@Т›Ю=rЮхŒ=ŽnnnдB>6pE#ašаgлFМ=v`BЗ’ђ)х$t0ЌYЙ†ћ;(‹€цiЖВСАЪETC6pbˆ•ŒOqZ€‘нИ-qАЋшџ;ЧTб ’фФ^№XНёдЯwJsО…%њш€3„‚lы‚xqТŠ)"ByŸA)дЂ1*uЁyUr)'љДъfютЪv™?ЭѕjrUYБlХ’хKFzŽ„ˆњ nЃЇрЕ•ј†я§Ри[dјђoЮœуВptЛŸмЗ"BŽЃ…Л9!`кф#'ОƒP„8фЙQIхМ-kЎ'G3NŸ>ЭЙUpДгЇ‡.Ѕ7/HRŸэ€€aќ€sw$яGј?iџГjMуtž–mPЖi B у@Fqqё_ЖГ7C" ™GSљи— ,iГ"Ѓг3 ОHНГК+Љe{ъЁ_”}1’‘Ё^ЅŸ1зUЯэgЋnG]ЃЪ ЌЎЎ"nxzБaѓюL~ЁНЯРсоlБЗГцЦŸ?sЦL˜z Ё_Бє~)dсВk$РeКIМrОЭщљ–ыоєНр e•В­›G%•ГДЈ9чльСs^ђ‚л< _ЮЉЊgKмpБАс;Љ1l…ј•уЏпДž g=<<фЋ322„Џ зUnбeƒ‘Ж /ъГ„Я>Oфе‡o1Е6…ŠдўЉЈКVR—WR•'­}Ф+"4ГљлрњQаФѓWIшъ[§<ЮЛœWl КєPјN’ьЄg/ШПUЗ‹ˆP§šmŒнјйІи”uюдF_ГgQяЗН…-*/љЅgЏ^\їBpPиД€iа‰J#Kњ~еœљsЊ*Ъzіь5/јcu§*П)~ ‰ Q‘QАЙ=&>…ЬЪ:жX('мЂцнћї-a_VоќІьўчŽ1яц їA“пŸ\їgнФ й0БaƒŽгш-б>у| 5бw"з ЩAЋЃVяњr•„c‹6p’HXЪ]I–T/гЏ L1}#_аB““ЧђpВќеД:;џV§вЃ’’qSsђЏоxњTльGэ&РмшTд.УѓlЬІ˜р `žТ(†˜ )Љ)№щУІУПЁ!7SГл ‘eззLkзNЛFлмˆ1#"€ ˆ€…!€ŽаТ.(V@D uшlŒ"тж•Œвˆ€х"`ЌПƒБЪ}С+iІfЗЙж–]_sЌnЁЎй†uЄЭ­ 3"І‚€.џІR'ДАXАkдb/-V @D€шљ „2ˆ"€ ‹:B‹НДX1D@> #фƒЪ ˆ"€X,ш-івbХD@ј €ŽJ(ƒ ˆ"`Б #ДиK‹CDрƒ:B>(Ё "€ ˆ€Х"€Žај—–ЎЌ?;є­_–ЃfD@ €:B€ŒE ˆ"€˜.КљФšщж.‚ѕuНМFЏXЕB$тЕИеЁrT… ˆ@{C ]8BzQ!\О*ђТХ Ќ(ЏXКxЉd˜Dт! ‘ЩdTцЪЅ+3ќп—xИŽѓ—}$˜4ƒЃr(–’œф=Ъђ†Џ WШ4ЏЦЃ ƒ pfрН{œ*NLY!ЧфЏВ@`у{…їјfЏ'б1боУ$АAъй|яO~Пє~)еѓm%€|Jу@ЫF 9Bх Йр“sgЯЭЫЭЫ=—лЗWї­лЖвГЫУ—/ ]’wЉ`ЯЎ=7nп&^єH  гRSђОsєрбмѓЙB+сіФэ4ЏЦЃт‰"mOJП~ЎЯЊ0[Ѕђ‚џ†ХаніЃzZЬž”œT§{ѕбoNТў№бCHBFЏa^Зn]fЕUЪ"6DPП~љњeЏ‘^T-DАlк‘#ЗЗ-nИзpИЂ‡3Лr%V"Жљ Т.^МH/Г№Ёєw)H:ˆ"Т#4^ћєC™+—Џй‹Œ ьгАьяиРQ}ЃAЄЛФ=§@кц-ŸЋ ЈsZЅєC]ввгVЎŽЂЊZЬ~ќФqжђ†mнъu„Œ/ЩЅkљ@ћі˜в 0џZОD"Ёjёˆ ˆ€e#`љ“eрњбNHћПX{Н=<2"8 OИ}ћvэЕь~Cтч‰;Пи™єї$лз„KVЏ1|{іљ­ъA™яxп&оГМMœŠFаЛ~нЊТЛ…рYUд“­в й!ммЛя–И-Щ;’!йbі2i7­ЦССЁJZЙ†И‰н Ф‰c'тbтvьк1СoТѕ[з#зБ@с† ˆ€Х#аЬ]мВъЭѕjrеZБlХ’хKFzŽ„ˆм ФmєЌЇŸ4 F†/џцЬ9. Gи‰;ŸмЗ"BŽЃ…ЧЛ9!`кф#'ОГЖ"аёq$ШsЃ’Ъy[Ѕ2‚ёСs‚%џl нZЬоYм3ѕ… Я*a=œо8*‡aˆ‡ЇЧŽ ч/œясдƒкЉlвˆ"€X$эЈkTљњеее1 #Р1lиМ;“_JKKщ,’Кg\xKe>лfޘ SO!#ˆСЄШђьŒц_p™n/шrьљ–ыоєНр a4nыцЦQIх<­еЬ@ІЇѕьй“*i1;В>‚†m§Іѕ\\ы9|Tlмgу'L=уЧM‰ны9мSй0ЄDА`кEDЈ~§6ЦnќlSNСЕ GIDATьЧЪ:wъ4/(ыp•ё~л{QиЂђ’_zіъЗ%Ž2ƒƒТІLƒNTYЮ ўœљsЊ*Ъzіь5/јcu§*П)~ ‰ Q‘QАЙ=бЎSчљAYЧ х„yjцІ›В/)vпМu3еаbіааш-б>у|@~ЂяDHвŒ#=‡lл2fЬHŽyoLмІѕРЁЇ№ˆ ˆ€Х#№вЃ’’qSsђЏоxњTльGƒГ)^ 0XqX" s`*oјъњ t^(*D6#аNЛFлŒfDDА0аZиХъ ˆ"€Дt„­У ЅD@, t„vAБ:ˆ"€ ­Caы№BiD@ CЁ…]PЌ"€ ˆ@ы@Gи:МP@DРТ0ƒъЏ\Йba cu,ЫЋжh'˜#Ф[L;i‹XMD@Œ‚vv,@DРT@Gh*Wэ@D0 ш;Š ˆ"`* #4•+v ˆ"€t„F ED0аЖхJp+ЊdnŽЏ"ж†Єў4ЗСЬ‚ ˆ€%!ао!:KjЭXD@к€€МGи†Z)gituVФоккбЉчАУfЮ‰DT†.:Џ,o0šѓСьBѓмWЎ^щффdАвБ D@Š€х;BЈ'ѕv ЙЂЄД$ыXVРє€=_эq;Н4іDq0урЊЋіэпgt“аD@кэЈkTРœ—-]6uЪд/’щ•цТВ+—ЎЬ№_тс:Юw\і‘lzЖЂМbщтЅ’a‰‡$$,D&“qэ#-=Э{”7№ЃcЂI=Чn"R’“Ј@јкp№СM'д(AAрЬР{ї р g•RIR&ЭjE!@D@vфЙЊOђ›tётE.I‰хсЫ†.ЩЛTАgзžЗoPц‚OЬ=7/7/ї\nп^нЗnлЪхЪПšє№б“ЇNVџ^Д3‰уS"-5%џч;GЭ=Ÿ+ДnOмЎ" œT"€ ˆ‡@{t„іUVrPBјŠPњЛb>ш2 ЬУ‡]Й+AлќaЪюsхђ•0аЧГŽЋhK?”Щ и‹ ћ4,ћЛЦSE >ин%ющв6oљ\хЌЦ$OЭѓ"@D@v1FЈRэŠЪ ;;{fтч‰;Пи™єї$лз„KVЏ1|$ќ=сіэлЕдВђJh9861:88TIЫTДU=(ѓялФTЪиФ|6x Аыз­*М[Шgи’ЇfхRFDа‚@3wh-9ЬџTж‘,Џa^*ѕpюыŸL,Œ _ўЭ™s@ЏXЖbЩђ%#=GBD˜КqЙР{Q_XQQa'юЬё)œ“ћіCDЈТз˜=Б›ІM>rт;k+ŠG‚Єђ$—БUšЙ\H ˆ"€4‡@;ъSTT””И-ѓPцGџЕH˜вRZZJЇНд=;WWWЧ0Œ@ ЗЗaѓ†glіwKмpTАс;I)јkš9cц†ш  –о/хЪyеip™nЏœoszОхК7}/˜*Ћ”mнм4$Щei­f.#ˆ"€ h!;ївŠX[[їlxpџ§0ЖЇ‡їло‹Т•—ќвГWЏИ-qєьЦиŸmЧјAYчNƒцeЮтr r4љ§ЩuжMœ01tA(ЧЇDрœ@ цЬŸSUQжГgЏyСЋЈ'§Іј%$&DEFСўхіDЛNCцСЫ*’mаЌЂ“ˆ"€ ЪМєЈЄdмдœќЋ7ž>е6ГQ9^щ˜M1СAСz-•#zE %5%|u }z5•#ˆ@ЋhG]Ѓ­Т…D@к шлЩ…Цj"ˆ"€hFЁf\‹ ˆ"аN@GиN.4V@D@3ш5у‚\D@v‚:ТvrЁБšˆ"€ š@GЈф"ˆ"€ДЬр…њ+WЎД“‹е4_<<<ЬзxДhч˜#Ф[L;oЃX}D@єŠ€):ТŽт Нж•#zE :VЏъQ9"€шSt„„Шu\KT‡ ˆ"€4ƒN–id#ˆ"€ДаЖыŒЕDDht„ЭƒlD@і:B=^чЇO—ъ\Л>tъмHTˆ ˆ€!€ŽPї }•ю1Eˆ"€ш vс Д9–=БІ&єщ–оЪœ9лEoxВŠ_z)^ЏњЈ|oњФН{|” €$0•9H#ˆ"`^Xўы}њй|ѓ]рЖ-ч?œwьп2ЙЇЄуš•#вПКiЈыЄWAєЁ“џѕбБыW‚ƒ>tIнХєс€!Nn)јЦ /јP@LЫ7n“”x~лgyџўЗœќ?rщќЃ‰вkбЁйЛg’ќq8ь@@’nOŸ†/["))2МА(t䘡Ё(ЙЯ&oн фо‘‹ˆYSЙL.п›>‰ќпІь”вЯЖЯ|ЈфБ#г:и0JgšrEЌ‘й\іˆШмМJЮ іхПџPQs’СGй“&8?ЎYšw)№ћмRŽЯmаЩхU&Zх џ{—ONNQњОЦЩG@œ?_єЯ/4Я§Q.iD@L—•”Œ›š“ѕЦгЇлMСژM1kLС–m€Й—mckYЕо$l~I]§гЇm/TW…œшXОš}7D0 ,?"4‹Ы`t#[нZ4@"`š“eјОB C кЊЪŒLе\Eˆ•N˜}u”ъbDM>Дгt„­Ў†Q2МєвZЃ”Ћ“BњBћHЭК":A• ˆ@{FЛFлуеo№‚ki,иа)КБ=Ђ€uFD t„эЎ!P/июЊFD АkД`,”­м 4э m aжЈїєZшхТj!ˆ€!0MGˆS6 qэеЪ@ие i#'ЫД8Ь†“s„њˆŽ5иbFСм„ …З6щH!бБ6&d™9›mиœЭGлv‡€ЩНPпюЎV@DРЈрdЃТ…#ˆ"€t„ЦОX>"€ ˆ€Q@GhTјБpD@c#€ŽаиWЫGD0*ш ?Ž ˆ"`lаћ `љˆ"€ FEЁQсЧТD@Œ:Bc_,@DРЈ #4*ќX8"€ ˆ€БјџщЛжYё‰п-IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/16.png0000644000175000017500000007067211733011756026247 0ustar sylvestresylvestre‰PNG  IHDRМ ЗгРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэН\TuОџ?^НпХн!}Ќу5/ЄЕИZPЖ€šBd k@кЂЦ І,ЖТх+Ѕј5EK/\cЁ5‹ЗмMА­@3‘‚ЬЄMяpе7ŒщЋ2ќЎ>ії>|†Ч™sУ0РќyЭЧЯyŸїч§yПŸgfЮћ|Юч|>§Ўъѕ*М@@@@ 3џв™іƒ€€€€@I>   6@в`&(€€ iРgРY46ъщ{ƒMаР‡РwAќ]рŸ њ„’†>СŽFЅ шюѕељј№}и ||ФпўЉ@Ёї єУгН-Ъ`П †ЦFІ€Mтј0|Фпі‘Р{Ÿ@ва'иб(€€ИмžpНcA@@ O iшьh@@\’з;f№@@њ„’†>СŽFA@@Рѕ ipНcAР™ ј2їxС™Н%пœЪOЇrЦЩмыHњ;uO п4<ѓь,‹иЌOж‹*vlЪ5Mmё?2лMлс­uIџ­еzTт(8]ŠХіFsѓђУІ…†M›^—пЃ` `ћи|[>>О\аРgƒl,T~rњЩа'mTvЌš\гѕ55т†,6ХЛњЖ,чozх(8=KYYщgЕŸ..% KW§псeУЃЂЂХp№‹_lіyшщOBGOƒХŒcд<$тя$hx& qд–?Љњыу=оЉW8SS=/>vТФР1ГшЌРхt)I”BBWoШlm519]’–:8cц,џ‰цўЎO›цзЕжжЌ}&fVуaboуu#5JяTІŸ$’Sск5УK+WM˜J~.Y–f4 {%_raŠ•Ѕ§ПcкД9“ь‡=5Нш}bчХuЙ\Ю%Ы`яЈ6eqГЙ)[ьаaЂƒE‡lоТEx]qA:•Ъš0k‘оyгdGВ‰?•§yiвRэ-§Q6Х-В2~ЃФL@Ѓ‡h˜“Ъб|FuLпKA"&žICuЇe:k^hќж?  SMЎАlекџюєЩšТнyŸŸ§šЩ‹ їе~}юpёЪух5ЊœмЎ_ћхЙтН…ѕŸоеy@{эhšj‰­I6:9єЩКЯъHГЊЊrаПЊњЄ’ЪuЕu$ЇBRZъТЙБЇ+Ъ+п/{пЈmЙй$”|I†)ж”ѓ?їѕќn˜ЪЫJП} іѓsт*’e—ФСцфџ№}33{Њц”Е);ЇўV[œ_Xљё‰ЉOL]Пy‹u]ЙX$ ГО zwrH6qЁсЌп8?жœŸŸп… g-šЦo”hє~еU•Ф—7аг=h‹Ёgзњ$№/ˆBЁт§ŠN~Иyу+:t)>%а^.Ёnƒž!"$”.y-КЭЫЩі!|+щ 4ѓ7s?њѓ1VыDљbM^EЁiЎCrƒ7MБ5ЩFЉ‡рНЃяo^—ёвВДQŒНјїsЏmпБzУЊY‘Г‚ƒХ–Љ;dzєЬЪЭ~Вxy[’aŠЋЫљO ѓѓ† г‘ђЕ+†'ŸŽДАЬŒ№†Ф6-\К+X2Л;oиˆNЬ2kvj>ў@э%,’‡>>хДU'‹ќa<(Щ&ЈЇGœ,ZlŠЧo‹k§ЖИмёњєсˆПo Œ€ѕ'ALFВLCиф'$v™‰іДKВ_нvъгS3cчR‡еЇеLуњхK‘ПŽЁГ§MyђЩІыMМІdЦ@{e›nKшœФўИV[“l4h|РWuŸбйёo_œMŒŸOяTўЌюЋ ёBЦPЎсљХ/вэ :ЯNžвєc‡Ÿ I†)ж‘ѓџ’сЫH™уХЕЌЫ .‰ƒЬЖe rfьАŒ*Њеš[З­]=’„%ъ“хЖЄФЂ‰Ёƒ|Іпzг4єЇƒ$ы2ЁѕЇ1.ашжw%,ЃЌ Ž48 *x qдвх;Њ“ЇO,9нzяHнHРzh/]X„Љљ§мяЕ-BЯ]гgdЌ§K[ТнШђ=…т“œЕЭЛ$ђMпЅІИ!нhЭˆбЃОw№СT{iшЪуFVѕl-_БSW7кч~­Жу.зŒ|*2k{іКeщt–ЂsUжЮь˜Ї#й^ч˜ДhЯНОЊлЊ–іЫжИЙ1™[6Є/є/ъѓів nЭК аДЕВœDЎб'&NЪн•“œ”B'MœT—“œ*”щеввЂбЈд зГwч1ЁфЛd˜\SСџШiQ„+c…ŠeхtŒ™Иџ!џ}ХчЧЮ1нlнЖ3‹›ВбЅШiO’5ГYQѕЎксњМ ‹сЁC‰sJnЪЂ№ыЈЇvцэољЪV’S6-Ф›је F '> OOˆ)Ѓ  а%Ї?љxjШTЩ*Щ ‰c1vС‹ItЛоЧџblТТDІіјЄдeщ&юЬнБ§•L7ќ#уЄ$б§kгУ“4Ы… MsN r†N mњёVpАp?"48˜ЪЁAЁЬкЦŒе;Жя№ŸИ 1iќ#c𐠓ы+јŸ˜xЯ`ЭДЈhи1ўЁБдСР^ыWЏќы‡Ѕ!Б‰ &NтІlt)yqJ‡YQѕЎксњМ ‹с„‰sтчг-nDВ@X>:ўб™БбєG‹ч-%Ћ@=AKcїUиє84ЇSжжm~ЃЬул{3ў>lк!aкш?нжIZšњ—Cя9Єб2bc,=д:Ь‚@/@ва б€€шцHтТDгэжЬMFн7*y‰љцˆцP @ {кћћКgЕA@ ' >|њ33[nЗ„?Nw+zЂ иАzlgM№hщб‡Сƒ€€€э4иЮ š   рб4xєсG№   `;$ ЖГ‚&€€x4ДиЎG@№   ЖшwОNXњ/P&0@rЖ|х:и    р0ІС:B{ iА‡ъ€€€€@вр!ƒ€€€=4иC u@@@Р i№РƒŽA@@РHьЁ†:   р4xрAGШ   `$ іPC№@H<№ #dА‡’{ЈЁ€€x $ xа2€€иC`UЊ?з`OUд№$Bв@Џ№щсЌ€w$`NhŸЁБQRB г€€€€€M4и„ J   H№А‰’›0A @@@I>   6@в`&(€€ iРg@@@Р&ѓ4ШЉcОH92ƒ€Ч щрlœйхLMЕ^ЏїXPмsјњњЛ}М' „ѓEК§ч‚€эŽ;nЃ2ЫfЧЬБQj рКJ$чн>oА)i 6^UИюё†ч '@} ШN“}д)opћЄcœѓуЏ@@@Рщ ipКC‡@@мž@cЃ~ѕкUaгІO œ—АЈъDЅ3‡ьШмCврЬ‡ О€И!kW I‹;)pвсƒNTГўЅ•я{п%тDвр‡ N‚€ИьќМ^Hˆš­еjU§U~c§6o|ХоеІЌэaSCщ Њ;f1]ы—.3Kш™ˆ­ЏЏЋxПт™ggM˜8oсЂЦ‹цg”lT#Ѓyљm§ЁЋ7dЖЖšX3BѕВЖVЬfHЮКшў4˜ўо!pђєЩˆ'ІIЖ•ћzЮпwјнRњћюћяh“ЋЊ9U˜ŸWyќФS3"R“?:љaоюМЪO<1u}жњ.ЉюЋ§њмст•ЧЫjT9ЙЂVўV[œ_HfЇ>1u§ц-dЖОІ†НSIчŒ€€є–ыMк!ZЩ–Ž–—Ѕ/MЇz­[š~ДќЎЖќхєaCtjЕfЮь9З~М%о<ћy}—ді9”О,•| k)‹SЫ>шxŽ:уeГ|~ьœГ_v˜eіm}ф’{ƒ€€€@w 2дxн(™7\24 ЁcЦЉpнp‰7Di+г™ž тЭ[ЗЙж]r9Еы—/E>гQG” ЈН:Z›eЪ"ХŽк._Т$t.@Ÿ№Йэњ”1їh“'LЎјА\r“‘КЁ4L’х TЂкЄ†шF–я)”ЬZ”›sУЄe С!ЁЪ‘c/€€ъЊJкхігдШ…9є4дФЄ Яiдšˆ'BеmУ…†ТНoВБ‘гЂВvfeЌYG>lи™E›=сLмм˜Ь-ш>e'4ˆ2ooсцu 2ЈёŠоg„Џ& 4 e AA ёc€€ПŸћ§БIƒ"ью Suоы g(^§Џэ--ЗуПhс"f0yqтІWsІ=M›бгЃiГ; Ще›OЛЄ$б}Šћx`QТяф4™ЉџВžўўњс_iг]#E\ р*шLљL|Ќ…З$!Й…а=6тъєђLЁЎœГчП BЦ @ШCw9&iШxyљўЗігBŸжЏ]3МДrе„ЉЁBB—,K3L‡>ЧЖЌНAЪ’‹jМKп„Э71l№рСё т[oЖRu6‚оYyѕЦпИяћњЉћ=6щБњњz&мѓцžѕ™ыuУtєGкdrМƒ8€ЭdЇќ'гЦ@ЭРЊOЋљNZY˜$|…nИеr‹RТ ,8&iP{i2зЌZ‘ЙžЏЧХ›IJK]87іtEyхћхcяЕ-7›яВeэ …E5ИN Џmэ“šOъkъ› Mї ОgMЦЊТnLа;+0#~ќсщON›~4Хќ:&iIžЎ=<оœqSњ:m =MрХјEт ~OбžлŸtЇІ•.WЌёSаWн1mкœIз п4dnЭ,*ž€ >ƒЦ‹>Ѓ|”=™?o}ЦњЗŠп"5*№Т•ka/€@шЏŠ‹‹_ГbeЪвT‹Q{]Н\‘г–Мf`y-9Ш#ъцѕL7Ћs7ь(ибД<œ‘|=Fю‰іy]œŸ€#oOАhi­Яяš›yф3VяиОУrр‚ФЄёŒхr 4пѕјGЦгЂ&ЎX›іx˜Хj/-}iв”IЁSCћyѕ‹}.6ізц'ЕвWІ{tœјщ q-^~сљ yŒ:ш ёЯХѓ](€є-њ‰8§iMќГТъ;т—јr%skЧeŒXG\–гo[r0›ћЂWVNЧ8nv=УвZ$pѕ†LБЕNЫ]­ЮжьдЌЄ‚EнЎ6M6хрФ<Йa{–ёКБѕІ‰FDВжэА/щ6„ЮIР= ж—ћт‰žhh’xtвь™s‹Z ›| ‚U,іZlRо@ЪBёcЄ)омИa#§YTЧ&€€г`—+ПЛœ6R7ђ…чуŽ”QvUNŸ†oSзщДЈш?˜тУrf‡~—Ј`ћ"­wЕ:_cАKП{ЌQ‹К]mšŒШСIX˜˜ћzЮЬиЙЄ“œ”РšГУ>Ћˆw— аяЊ^OїЋТЇ‡%=Vо+YЅo…єд–ЦюлC€ж]]Uгвидk(ˆэП єe”3Т,“BТo“%[сТ‚?ф*сš=] Љh’–Іўха{=ньЛ(N?№.—иmє4ˆЭЁ  Ж u%('Pж'e…žоKя‰ MЗ[ГsВ#Ї>йгЭС>83$ Ю|tрИ9ZTТљз•>|јєgfЖмn <œюVИљ!Ax  HIƒ"ь№xtsФIюxќЁpgjЊѕz‰…œ?B7L|}}ЋЋ*§~ŽЕtџу” h я‘“:З@РХ АŒaŒпWŒУ “† @aњеsХуŸAРPЦРОGЮр |7#@} ”1„GFЙb\n˜4аa п;ќфЙтЧ>ƒ€83ЧOюфЬбТ7Л iА*‚€€€g@врYЧб‚€€€н4иA@@РГ i№ЌуhA@@Рnюљє„ыЮ›aїDEp qњ„ъU_YГŽнSЄvŠойWPXдђџZЂЃТзМœСяфх*iii ЯXБœпBуЎй=ОЁЕЕѕхх/яйЛ‡L-znбЋл^e_‹[ l“u3АwжpќƒуЫ_^^ћU­яПћnЪиџ\<йщЈ{[•’šВЇpЯ ŸZЗrї– ›7nЮо}ыЧ[ГbfНёћ7„М@AР{АЗск]'cЃбHBБm–1ˆ%T&5vŸ‚nлkkx2AЛИОFЃЉiгТлЄъЩЯ'[Џ…ъ7мZзъюhкxг|Т–ДР…Ъ ‘šœŸЬ‚dѕЪЊђа PЁІБ ЗU›З #9ш%šВ}VяnCРЗ'$Y$ЅЅ.œ{КЂМђ§ђБїк–›ЭеjkjП} МЌє‡я›s ђ™МЈp_эзчЈ<^>PЃЪЩЭсњн/lЪмєнЅя.{™ў.ќї…MЏlRАЩzgвœ7^цІЬоќчщЪгєВЈЛvукяЎ~wЙёђ7_~ѓсGђНЏmэ“šOъkъ› Mї ОgMЦО nу7ІЂЌŒNэЬ]WЊ 7†ЮpЪЏŠ*HЁЕUш7fєIeпбОЧИкдSг аЏw<\@rёајpЗЂЁООф­"vлB№Њ“'whDd]—ъњњŒсвP Iї:кшЇ‚чЁЊ5нQОi,9PФ5%C“уРkЁрNzЊЇснЂb†IэЅJLHœ=Se?ЄJ_šЮzЈАрХЄфЄDвмфP^NЖvˆ0Т9eqъЬпЬ}љЅe Лєи…ИюОЂ}•U2уЛџswhXшЦ Х ЪхAƒ.шВ†z,svYf3ћоь0Оуе‡ўtˆYЫЩЫЉЌЈЄ*ДЙiуІŸ?єѓэЏmWn{Al$р?жOыЅЎ:UMГ Po/я€‚&‡Доь8ЉKšђс[rш Чјњ†‡EДо”И9|ІЎЎшаA:ёЙПCэсqc о( {і№‚џи€†‹њвŠRњ@Яh?ь­г5 ўўѕчкЊЋшщ‰`яЁКц&ƒuƒЦPžQєЮAzz" рa§eНdЪBлR0BKTTTP\д‹0.˜=HBњ’ЁЩqPА]ЎK Ї’–М3{чй†Гд9/аЕ3Ќэ;ЉѓŠтЭ ‰AЌзњnЖšŒТ=Б‚PЋП*$(€ В[\N™!SB„ћЖсєю7Ъ7ј‘vnЋhf$ЁzлЩ5dJ{ѕ6—lЏ+n:80ˆПsoyэх›6ЖХѕ-ЊгІЯ_?ПэOливƒЃм6уw…FЛ•М| IDATф8№Z(И ‡žœET–ЏXžЖ4-4(XэЅЁžРРЩSјЮkW ,o ТнH&ЇBљžBжР5U№ѕёmМиШђ†Цџiєо~.џ?дKIуЁ„ЁМŸгКQџGќKо)!9 nHx>сПѕџ-жБ0ЮwбˆгŸœж 3Эцr@8ZWЂрЙ|SВ@:’r )Bћ vЇ€ Х›’ЕФ T‹К"шСыСжu­%BЃЗUдЛ`QнZгZ"бДT€м[^mOeЈ`mйZ"ж*‹ЊSйtУHmтЖ7ю†ThЄ!iПЃ:JюB ЇЦ4аxF<ЄжhhDdцжmb\Y9йt†ІWжЮЌШЇ"йЎИЙ1™[6PA›ѕЋ7dŠЋАВнЯvЮŸŸіrнŒЄ?*а&38щбIЙџ•KyнzXђKx‹?ћйЯ(Щр›єИvУ7 ь^щ­џmы8сћTЊљ чЇ­ш0ЮїЄ,IYђт’ЦЦFЊHЋђФ/ˆчЛP`hЈнь˜9ЪžМ№>' рl“4ащ\ќGAnЬXНcћџЩ “Ц?2V6mв…iQбїx{''ш7ќ#уЄ$M˜ИbmzиуambЧМб Фўoїо/§QIЬћC AаќT3сБ O<ўo,}eњИGЧБ(HјЋШ_Э|ff?Џ~є ХЁЗЭCИђšUkМННяѕЙ—F-<жaфЅЅ/Mš2)tj(UŒ}.6ізБМ }BРЂCОO|@Ѓ рвњ]еыiќнЇЗшцтQ)яхjЮS QNXхвyєMƒ€K Qє=rщр<€@OpУЄ!(0˜HбЏ^O№‚M№”1Ая‘'‹Al'р†IOПwјЩГ§CMА…Ц4иB :   Ž] ? гšРЋVЎ ™(ŒЧ’{ѕО“=дЂ-СЪA€МЯ iшѓC@КL€ЮgBЊЁƒ№ЙџБIЭЋm[ДКЫЖT*[Ўя­Э:№œzіќЗ!AJЕnŸ“жnл.щДEћиЌэNBГ— iшeрh@рnЗяоДy‹вZ[Mњ+GŽ‹}nnaўоaЎЙ§­–[Њў6GютŠЌ‹+ ї‘4H@z‡Р™šjН^п;muЉzфR­жјђ{9еЯ{АцљykVgАH ђђ‹•ДДД„‡‡gЌXNj‚ќŽjгЋ™ЅeЧўd`Т‚ЮЄуŠљŽ*їѕœ’Уe*UKђ )ГŸ–ьКvЭЕ3ћФщЊџUN |eЭ:ъв`]ь_‘wЉQqыTцІ$›c М!s]!œэЧ•вfјєш5//k5Ї?3їиЛ‡е^mёЊT­7гчЬ=vPHКGэЎ[™ўЦо§— —ъ?­1[nћvБЉАe§К]{оИ~љв§П№пКnЅЯ(?ц0{чŽuк„Њ-GфЕф‚Ѕ#e} Ш)IћbŸQюiHzš0ьƒ€4–1аŠЌвЛ-ЅЯ–Єt2z€ЗЙ+ч5*ЛжsЫOG?Н`сs,„ЂТ}Е_Ÿ;\|@уЅоўŸлrrs^~iэЪ-Шџсћцђ2с,ЛjгІ,~/x3џмп/ еъќ7ѓйЎЄДдЬ—VНЖ)ЃеЄ"сЖмьЭЋ3ш4Ig>~В$MЛЕ0%йœиI^Ігъпwј]s8Д™М$%jzјСВƒёЯЮgjп;2;2Š29їH­іЫsХ{ •oюœњ[mq~!ёмW|p§ц-,иcс6йББ 17Й`%„‚}Ю…ž&€ЄЁЇ У>H >†о\У’†жVЃЉUк щьgуKо)r­ЄaиPнѕыM,§Gххdk‡hi3eqъЬпЬeIУб?-мЧЮŽы–І?љaЅEр‡ŽД)ДUЄ0лћnQ1+ЈНT‰ ‰гЃgЊV[д6эnдТ–ЭQ­Ѓхe…Лїђp̘D>Я37)%•' ћџtˆBVpv-OIUЮH'ухTЕ—Рs~ьœќнйTА~Щ MЙ&ф‚•< і­Є‡ iш!А0 ЮG€z†o›,мЪ}Ѓ љ…ŽŽњіНЖ%экнљПѕŽcкКжd2d(ѓ„zб#ŸŽщ№Њ§wŽzр‡а19/tЈЉTb.Џ?з@ўЯ6œНѕу-Aиn+А‚нZиББ9ЊuЩаФЃ ТuУ%њјјŽѓ]ёQeDXhХG<ЪЦyШЙGUXveс†Х&ЫHH7znЩ CБЃ Й`%„‚} oБйsd>ў=з`пY.иП/!Юмeз}/k­ћўРtJ€ђЫ”Ё­Ž„PцЌаi}ЈpЄєШфЩ“™Ct#ЫїZŸ GъF^Лb`'Z*X{+Vр{—ЏXžЖ4-4(˜:љiмeрф)|—И`wЃb#TЖБ9вЉ*gˆЮœ3Х>ЛЛ`% oПЕ"}%Г/чžEынйДЃ Й`%„іЛъJpН!щl-‰-B-j6ъ8жšB КE@шl0џМQ@dЭ\h—“‚cЎ§ЛхЈ­•щ,оpБ!wWЮЁ#%ПMLbетцЦdnйРв‚Ц‹ње2™нГ`У!эn”YуяrЭq^H^œИщеœiЯD“$zz4mђ]ѓbуVnк№Чмпs‰œ{\СŽ‚,Ы+y z"пАK’@ПЋz=нU ŸNЇaI хНT…n›yжM в ббэI§}ѕ™ъш_E˜ls%йЊ BJVЏ\-чЖЕЎъ[[KkMle!Prш ѕ@ШЕыжцЕ [KMI]НVjИНth^Хј ЦF ћія›o}люŽЊєНƒГc„­_ў&№*ЃœІC ПMцњ’…‚?ф*‘Ќ!є>N?№Ь%Rу7&<вм3дћ~vЇEє4._џxКH1^3˜nЗъДкшЈh­—Цdnжзж}qсcНу“щЁ–>šh|CЏМhQ‰ž^WЂWт@# р)02т‰э`MеЉъЂ’}%‡R]І3~д—ЁеzS'DаИ€ѓ ч5ZoкE…6ЙЦдд4ж_5 §њ^;)SE2b}3‚$є' Ё 2\њ6Œ7M†Ыњр‰!­FЃuЦ Д.х•пи1tWEг>yдzГЕЮьЊebO)ƒoЂ і8]{:xМy*А.ћLЩд2єЕшќOІ:Ф žNР= дЛ0ж?xbZ­5ўhБŽЯпКК†Кк:C“1:&˜f\—ыb•ѓŠњЈ>S5ЛюЋъ>ЁAдЈœВИi”AР!ММНЈs‹}_Ј№ГŸ§Ь!fЙлЇ‘6\7”ьG†СЩЁ `&р€лЧ+ѕь4OяUŸVщ†ЇiУЈ ZzДДёсBC}}Щ[EьŠœфЧ*„зЌ­cОxѕІК”:КSащ!в ааудb5ъlЈЌЎ ЌюЏ6нМk—XMЮ+КЧбj25^hTPљŒђ1›Љ–œВи EoŠxЪ `; у'TгнНЖќђЗНЎ-š44ѕкђЧгw[ЬB@Рs8 Їсс€%PIЇy“‰КhШwєЌйtц'ˆўc.ъK+Jщь­ѕ~4и[Їk6ќ§ъЯе:H:ССоCuЭMzЖЂъL5ЭЏьMЯwЖњu аЄ4ІлТ#ќ€Q+ўA­зeЛМЂ]~cŽT™ѕДŠКк• ЗШ i›v˜??ОUќеЅТЂ…‹ь0ЂT…вtЋiЄeє-‡ЫЈA  рY4аКF­nы] k”VКЂi.гщх7Ъ7ј‘aоrjъЖŠЎr˜œђ†)цžиЖG'hHСьЈ(zЮ‚i<Р4Х9Iјf›…ЕVXC…u`PюL­4›$КxEв—ѓЊMžL6iМk]NYlM\цЕPЎxсљў[џпЌƒ!щХ$‡?:Aїќ,oћЩЙи~ЃPn?ф žIРIЃ‹r6+ƒ$DсqЪЖДрЎНtjЇёцEщЬ{;WDsLЕзВfШ7Х–i*YšИ†2 !/‘љЩуЉ=q]Бc’rIЁиšИ,Ж†2t‰РЦ щЏKUКІ,њjˆы&,Hр›шgр(PpLв Жи'eUр=и›ІЁTбh†}т '&а‘ДЯЭэи%5нWC@Рs ИIв@7ш‰pћCt[Сs*"IwT­ЂžIA@@€›$ !n(fь3‰Ѓ%йи:јAВ2„ юJР}’w=Bˆ JРІl@nއzc ЎGIƒы3xьшсdzРияч~НŽ0Д-ЭU~XNюйЂщ@ЃбиH‹ХмlжxyћŒ 9Y…ЃњъEыnГЏћЪыviбœхk2.]ОфlŽYЛ ‰@врЦЁ95 @a™‰Ђ?оѕCzlћ4в”10їzдnœцsЋЌЊ2›i.5эP=UzМ\7д;tRˆZнЩТ4мˆѓz(си™НsеЪU!ЭЋ“8OМ№ФЃ i№ЈУ`‹˜{ѓмь\СЗ{C-d?1D˜ЃЅэ5=Šц‡%ytM#7аЙ™)њщ Р‡L_КТЧЇЗ{GЬюо§_Ї=іegЯ„Œсnжиъu˜FКз}Fƒ юC€њ(c™RђЇ’GЧ?кЏ_ПБЅ2IH^yJiFy:=г_eiљЄРЧVdЌw(R‘мjЙEЋт}KICпђGы рбhн•`Уœgчд~^K8О>ћ5•)o 6 Дјœ2#Е—&>vўЗпж3Е‚МќАiг'„„ЎоIнцКwL›6g’0ьЉщEяьуНМРд,6IxэšсЅ•Ћ&L ЅКK–Ѕ‘У\ГфаС3gљO4wx˜ЂщѓлЛ@ЈPVV:#f愉ѓ.jМи@:l/Нs5JњL М ‹Zr^бЙЛr(ќАiЁ%яѓєГ—Є§іјК@IC`A@РБhфу˜бcШц+[^БАLZyŽF9ш;™Ў­ѕІЉЈhпƒc„ѕНŠ їе~}юpёЪух5Њœмf6їѕќn˜ЪЫJП} іѓsm)l&ЅЅ.œ{КЂМђ§ђБїк–›Э•kП1u§ц-ЄРn^А>І/ч3эхMXд’ѓЊрЭќsПHс{ЗќъїW;ЕЯ№Ж@в`;+h‚8˜€№ЌФ`aШBэWBƒјХzhЏбd^ШFМ—•йѕzруSіПSДѕ•­$мфPњВTэ-„HYœZіСqІyДќƒєЅЉєDНвSR­MЩIо-*і ъЏЁўŒФ„Ф“ŸфšЫSRЩп”,dМlvf~ьœГ_šћB,4х|&5Й&фМ:tфшКeщBј^šф%)Ќ!ћž`:%а>юЈSE(€€€Ѓ аг•ІІж;­уЧgYoaќ#уIN{Еo.Д(АыяkW ЖЌ?пpžЯЛ~љRфг1jэПp— —h/“a.tЈЩ—ъЯ5аc gЮоњё– еnŠtn–Џgо#ЌезіЂ$ц–Ьtœr>S=Й&фМТДŠNСОйKќ6}lЎEpšЁє§ђˆ№z˜Ц1ˆm’„&†ЇT`Nд4БмКLЇЩW6lŸћоЛСCt#ЫїZŸkGъ†в8–7P’С @Ћђšи|МпK…х+–Ї-M Іkwв œ=eњбDяT&ЩљК/"Bl™`жЬYo•ќ)>n>х R’ш…kгУc@h8Т=ƒ5гЂЂgўfюј‡ЦR{­_НђЏў5єё)Б‰ &N2KEџmЬXНcћџЩ “Ц?2VДЧўbТ‚Ф9ёѓљгr>+4 чUТТФБŒš;wњ33‡Ю,иa_Ёiьђp§Ўъѕt{,|zИм‚OЪ{% ЋWЎ–‹Тyќ„' ръlџM 'gЧмuгA2vКаf„ljіНпзлЫЛљfГў[=ѕ1Cщ™$эи(llд'-M§ЫЁїlд‡иHРЦ<ЉбcAс‘Q6šu*5є4айКтЃ ‹Ј:НюяTСТ 6Aм• ) a 4vAGу"MЭєNхˆАPЧf д]Oіt{";';rъ“ю q@hяЄы^#оZѕшђuЇ нs ЕA\‰]№лљѓv‡DнѕдiпrЛ%ќёpК[aЗTO&р˜Є!тWE…Q#Ђ%Qжзж}qс< „іНW2‰ЎTЌ›aѓ–ЭЄŸ7Пфp)]UА'žiь’Я(ayК ЈјЈrіLСц™OЋЯы…qCДŽ_Џ…Œ„>:ЁюЋ/šM&2B{й‹UT•Œ{иb§@‹О ^Eжx0?oКбь­ѕ 1ЛGMX‡Ук%ћмІйќ р4шF‰-їJœЦ_8ЮHР1IƒZ­ ­8^e2нЕі.-чzЕЩЏЂ+;VVпPфD'W:Хↄ’‰жV•FЃІDЁВК:yl@ГЩhИf№ѕёе№);Z&Є/$hдšвЃЅt?5ШпЯдіФГбdŠoГЬžІђS•гBB§ƒZЦці9_Љ!j”њ6ЈP__ў›ѓЌŸуLmЌёІј˜йДц^е™Њъ3е,4ЩpLЗЭ!ЃяФ?у№ @@РA0ІyB< зщъЮ5№ѓ7“ŸП ЇЛ•Z­Зёš!h\=u­бvLеBї/шO7Тї|уyЪ .4jЈ єЎ6Ўњіmmmе_8/X№в˜ŒЭСу™ѓм,$'kd™нЉџМОђT%-‹Gѕ7ˆ3ц ЉезœЉ&Аz:›„JЦЁъml2јј’3”єОB8шf`ё  рЎггРшјћ”Џ№Ёc3Ѕ0!uя[мP{ЉUMwёєбщшRžКєпR~0­Кі П™б†&ƒяh?SЋ‰^К:Ъ ш‚ž,“An Ц+‚œ™ЋќЄrLл] AљюІ єdœЊІ[ъŸjI‡„JЦеЦ…EoкP)‡УrжоA@@РЭ82i 4“‚+>Ќšеё$ MŸќ|ВpšWxѕWQG‚ў‚^5@у7жПъLЕўšAыхMw=ш6…FЃЁ“=KhН;к[т $ааŠ3'д>>ТЈ‹=жUQUIƒ'ш–KAHСvуЬšMсX4ŒMp Л=СhуŸЧјUеžсpшiTˆајpЂЁООф­"v9Ў Ё;\mјНО4$ТoœIќ|}+оЏ№НпOE3Яг№ЩбОЧ„G:…‡ЙЯ|Ay-‹Ѕ&Q3ЂыОjhИи1лзЁl&8 €’уѕŽЮ л3;rса^‹о.   рмг@PќFљVЈфtќЧа)МДЂ”F$аcС{ыtЭУУуЦМQ`Кm~№І џтГгСAСд—рыуS]}кoЌнš ;AСgъъŠЄч/ЦмябzѓЎБ–М-Ёа_QVQЁКнjёєФеІЋWЋЎ–W™}cCКf\Ѕ’ ‡љ€w l€€ИЧЬi}ВЄймTj5ПЧя­ЅЅZЕТА€л*уFг ЁAЖ-,kю{аЈЕУtlŒ „дВq mChtЄFKSа ї8(c {ьщ ‹vљІP}˜Žђ‹БЄ >|э}]3nім*’sФ­  nFРс3BК„уБcц,ъД`F ђђУІM' Ћ7dђjb^|ь„‰3bf•••2MIa‡'єœv йfЇšзЎ^ZЙjТдPjwЩВ4~FВЂЄЗЅКcкД™иЧхT ЯЩŠbоТEИЋ’!ЋdˆёZBAJчљХ/R_WЃаf<5–&—s@.vAџp›У!ŸVџЁY|žy–ћož’‡HЮашtьТІ…–Дї?ЩчюБ‚œЯjО‰ЄСУ?њ’ ЦfsЦ`хMмBЯaбГгV{Ь‚тCХѓbчбЦofЯ+~Ї˜Ћхфџ№}syYщсЗœЊ9еЉœjПPyМ| F•“›У,,[ЕіХХП;}ВІpwочgПVВ]я’еХ:IiЉ чЦžЎ(Џ|П|ь}ЃЖхf+4Ёl-їѕќn˜кЯЯ‰[9ѕЗктќТЪOL}bъњЭ[и.ЙхHŠ Jъ̘АшїopЕ?ьйЗ ^э%Ьч+щ€\ь‚~ЭЉТќМЪу'žš™šќбЩѓvч‘џOEL]ŸЕž7#ЉиАˆIDATС oцŸћћE:vЧо-Пњ§U&T0.ЎЎрГXЭУЫH<ќ€№A / 4^1Œ-?Чk5ЭСЊoМыљmю.]>ўэ‹Г4™I"""ЈLЖїшŸІ/MзЖНж-MчUффЄА<%•д™цў#‡в—Ѕв"|tg$eqjйЧ™|рР†&ЪsŒУ†щжЄ/SВ]я’еХ:яћPѕзаЩ51!ёфЧ'šPЖvДќƒєЅBDєJOIЗ’ёВ9ДљБsЮ~YЯvЩ…Ќ@Œл”д ОG3†Њ->|ђ““sf™яI: ;U_ўrњА!Т’FsfЯЙѕу-ёцйЯЭўsg9КnYКpьМ4ЩKR˜\С8ЏHŸХj^֘џ |шKІ›Этeo­]Ёе^Œ7š­х$9p№@гѕ&џ цЮAђю‘фЄD*\2\6ТМ./(ШifшНЎ_ОљtLћ–yБ:кЬ~u[опЬн•{ЯOІ-[21XNиQWT’Ќ.кЏЂЧFvfя<лp–N‚М§чYВЂЄ[ “ @ Т<{m/: пЂ›Am/ЙхHšЋЕ§'ЇГ(aбŽПЇЕˆГѓѓ^x>ŽM‘t@.vjђжГ офўsФЮpЁ‚qЎУ r>[ЈyђfћЇв“ v>" ёђ6н0Ео‘žіj5оонQ•.ћрЯGљЉ‘КцЦ?—œHsЩдЄЋ[–.PW—“sVЂYОЇPœF09ЭLџк–WЈLу 22жўхЯЧЈ,)dњяj._Бiiъ_НзћMгЄПšўDD˜0XеU^нёй–йSіеЅ !.ќЯ…ˆ0aˆЋМ\бч^fыЄСDѓiр рдшМэпгііНх 4Ќцc Ї+Іf—wpдЩЛНу{Д2|ј№щЯЬlЙнўx8н­шх hЖЅ‘О#ГЗnыхvЛгœ+њмxэЋыЄСОІQ @:P–р7ЖуЙЧŽ(йE€ю.Щн`ВЫ^з*ЙтbЎшsзŽŠ#Д1Й“#(Т€€xGє4=™щ„шкh.лПЇВ'И6x а=ŽHшЇЈwя€v/dдO$аzпSO<юˆKРЗ'lПxqЌыА аSpаSda\›€’зяAЌрц„@ŽЙ=A“Њт рьDпг‚ТkoiђDk!$  Р  ЇЃ@<ˆ€u~`-ё @Р6ъiPЁ;г6оаО$pзї4aСќ‚Т}Ь*Ћ№-юЫCƒЖAР58(iu{КFм№<}I­ОЇ qѓ іяЃwЫ]ЖЯщieтЅЩ{aj оi……X__З|MЦЅЫ—z!.Ј;#G$ wp…тŒ‡>€ЛњкїЭ›/)oпп{џЦЦ+гЭf—7-™M `і^лЎмRe;ГwЎZЙ*DjѕQWІпЛKcКKѕAКI€КЌ8^QzМœжЫееб;•+>Њ Й‚e:YZя•ZЋЙ“Єгžћ˜œ=џmHPА;B,!рˆž‡8# ND@щlэX7йвиAСёЂЅБЃІGбвиЅeЅД&-gхиaЭЗZnЉњлЂЯ"р žКŠ?g&@lwЏiQlЪB(c xб6і‚$$ЏPyМ| F•“›гЁџхЙтН…ѕŸжDNь5ВI–Щ ^WЎ`ЛyAяќ.†\[dГЖн%‹ZIiЉ чЦžЎ(Џ|П|ь}ЃЖхf3 оЬ?її‹нБwЫЏ~• ьЫЙ Й pTв@™јpFяМhфу˜бcфкRїWёЃo4Ш)(Ы3^NебвнљБsЮ~YЯ•хф\СЂАќхєaCtdgЮь9З~М%о<ћy‡йєЅщ4x“^T8њчЃЬШў#‡в—™нHYœZіСqn|yJ*)+Ћ‘nvнвt^WЎ`Kh6К$nтнЂbџёЊўЕ—&1!ёфЧ'йоCGŽЎ[–.@ів$/IaBћb›(Л(iш­ыЅ ЗAР)8пїTxVBы­G3XcМб,­ љы%ЊНЬЇd:ппХ.'—nEЅтЇv6КBМ)6;l„ŽY ТuУ%VО~љRфг1–EюбЙ–Ыхд..‰Эr}Й‚-ЁЩЕE6Х.‰›Ј?з@Sœm8K9“ oBьзWАЯuPp]эП[˜zэКЄ[nЂ2x0жтlшщJг SыйЇ>iЏV#UŒМwdуEНЯ(_TУХђЭ. Pб€–tмГяЉkW ьO…!:ГT(пS(w2ццхдFъFŠЭr§юфкRАЙ|ХђДЅiЁAСдЃ@”'OaЪbїxu;ьѓК(8?GнžpўHс!€€г љЮ7œЗœZŠЛy[E{}}ЬW№\Ь qПŽYБy}УЙ6Р“Ў†зoи77ЮBЭЦЭћђпW|ЮˆЦыЦmЏfйXKЌ–•“MйНВvfE>ЩvХЭЩмВNќДI)…Wсe9ЕШiOŠЭr§.†дxЅcРІ\[ 6[ZZ4•ZЃЁ‘™[ЗqݘЇ#7lЯ"b­7M4"’ЩэАЯ ЂрќКлгрыы[TXњФ4ч‚€'0ЕšZoЪ^а[ЉќАœОкТžиЄЎ~нPяъšъ`ЉI„шЉKNЧЛм-ˆ›O7/жoЮјV…vня;тзsтfЯŒЖPГqs§ъ•”sфяЮrяШ%ЯНpф/х6Vфjу;ѓ7s[ў_KєЏТ“™œœЄТ‚”$ъДПџ%ќŽы‹ rjЩ‹S6mЭœ=№'iqђ+ХЕl,',Hœ?Ÿю,Асrm)Xл˜БzЧіПЛœF] /<wЄєSNX˜˜ћzЮЬиЙД™œ”Р„vиWhЛœ@ПЋz=eшсгУ ’Ю)яЅ*gjЊѕњŽ4Vв„ .D€2† @й‰}:§Mр‘в#|Гcц№MЩ]мг| cžЁрW1ЗU”1œЏћbіЌh'YBp6Ж|рЩgRЃОс‘QЮцП-ў№яЈ-Ъв:єуЂ№ћ"]Rh#@Уh'š­!їГ/|яїѕіђnОйЌџVO} Ш№g#р€ЄСйB‚? ЎE€ђ†ˆ№šžЎ4ššu^оСQcфюJИVh№мŒ’7; \•e ~c;žBtе0р7И5<=сж‡С€€€у ipKXЗ&€ЄС­/‚Ч@вр8–А  nMIƒ[^  Ž#€ЄСq,a @@мš’З>М@@GIƒуXТ€€И5$ n}x€€8Ž’ЧБ„%pkHмњ№"8p$ Žc K   ржА`•[^NOрLMЕ^Џwz7с Ї№ѕѕ іt *’|@њŒЫ–ЄМдg aАРЎœзHy’л>/ашдЧ№лdуMcи†Ip$йqё%ћ‹4`Lƒ#?UА  рžnЛgX] = ]%}Ч0Љю8ж Ќєє4єYишs?џХЯћмц@ozRW[їФє'zГE' 7zzz2š' єњšфwwOя’{НфЩжзжgЎYвУ`ЛЛЌђЯсџЭзѕВЛБУЩ ipВw@Рѓ˜ьК[\ДП(k{VњВєјИxfіW0hї.kOќђЏџRщ|йЉ‚Є3gЯ~bнœЄrW…­7[ѓ rŽ–p§ђЅ?њЫ ПŒЄ`Ч" ‹M"аCЎ*ИdзЎVЛjЙ[%мžpЗ#Šx@РЕи}ѕНџ­§ыжЌ;єж~зŠЗМНеrЋчžІO[‘f2Љ ѓ O^Иє№ЌщПzѓЛ{!ЈОoТЎдЖянvДHMі@zžР™SgюЙчžйГgг;•;М­кДaг„  aSУЈ+‚фteLezч:\rэЪЕ—–О4сБ ЄП$e‰бh~ђ“.…Ыо+›9cBџМиyЬuoЋrГsЩZXш„’wуьUАK’‘еkWЗšкВђЄ]]тЩIHЊєЮ m‘BЩ;%3ІЯ№ФЌЬkЩХЈъR,"—k>­LIM6bЩДZmHxФЎќ?ђ§ж(˜ѓм‹MЊШ$Ќ ‡]|LЙ>їyГŸЁcDGŠ*rzЈа~\{ШМۘ§—ёŽ‚И+К†ыт_ё[Хt:ЇZП‰Ge^=wWюЭ?”П_~јрсSŸž"`jЕ:jzдС’ƒ\‡ЪГ#ЃHžєI ч-<§зг•Ч+Чо7jлЋлЬ:*еЉгЇŠџX\љQЭдˆЉы3ж3yA^СЙПŸ;ќісcЅ•W/]eТЂ7 jП„•U00';‡Щ­=1GJўБMЉы?ю\аЛPhS“k‹дj?Џ%ѕ5mЪЂZr1v)БчЁ™2ыыы…(тXnЋ$нГˆТbSА@/yДKLВЖІ–ы/[НьХХiЇЋъЉлуѓГŸ[8ујЭ6Oё†ЄŸ#pэкЕП§[TxљEe’АŽўљhњвtКІзКeы˜pюœЙћьЮ"єК­Ђђмпыйи={BЇ„О]єжвє•LИ|ХђДЅiС[ƒ5^SЋiЪф)м^`MАMСјГq&Її!К‘Ѕ{ ЕC:Ўђ;”Ѕ<сХ–Љ,йЂ…\Ў- 5ёІ\Œ]Š… JОt#|ЉseZИ™›ю1Г3sј№сLg~мќёŒOJI ˜О6=ьё0&W№DвИЄ0~Aтќјљќl'з–d]&”‹БKБˆэПјќ‹я№>  œ˜Д(Щd2mнД•)ШЙg…ХІиИd™њј1ћаиAэ§уaOЂБtјvфюијЪFЩКвШOМT§ЎъѕѕчТЇ‡%y(я•Ќ!€€А§7ЁфаСй1sPBќ‚К‚TаС.рє—ѕЉKSп;№—є^сЖЉДЌДгЯГВѓ–>іcќЦ„G #y]ю…ž—;dp@<‹@NnŽщ†‰нžxrъ“žМ“EлобуdnСO"€Ž_O:к]uјШс3чЬlЙнўxxтBz\Ж>0}аdзAѕB $ НM€(0ЙШв !`WЯ A*єЧлР†Ѓш§nOє>sД  .I= .yир4И__пЂТЂа'ІЙG8ˆТ T~XNW7аЦа4и j Ž'(ЬтG?ЧŽ7 ‹ рP”1АЋC­Кž1$ ЎwЬр1Ињ!ЦoБ;PФто0ІСН/Ђ‡@вр0”0  юMIƒ{_D  #€ЄСa(a@@м›’ї>Оˆ@@FIƒУPТ€€И7$ ю}|€€8Œ€Mѓ4?vмa Т€€Ч љp:]лc` P7'@uЇŒ$Еѓ ч}|\r~ЩЮ“†№щсn~Ј€@Я`Г6бiߘ‡Up"ЖOЩОЧ]r"д~Wѕњњs ”?\p2грdю€€€€Г@врЌG~€€€“@врdю€€€€Г@врЌG~€€€“@врdю€€€€Г@врЌG~€€€“@врdю€€€€Г0Oю„9ѕС/pТфN:gq~€€€8+ЁЇsA:ыб_   рD0ІС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&€ЄС™|'"€ЄС‰\g&0 ООЮ™§ƒo   NBрџ2їлД’хIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/27.png0000644000175000017500000005500411733011756026241 0ustar sylvestresylvestre‰PNG  IHDRœјtУРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ tUКял+wЅg‚pVт ‹ˆ`03AC!1бСУc $™ $7Т3@фa˜ЩMŒ‰b$Ю0<bТ ŽdˆУ#2<дс$+ЂЭ’G;B:w’х§ЊwїюъъъNwЅЋŸџZН:Лv}ћ{ќЊR_я]ЛЊю“_ПonЄ €€€€Ÿј_~ю?м0@RЧЁ  BI=@v$Т$u ЊhiiІWUаРСРЈњП€ЄЮ3@мL ќоˆ№ЙRЌ‚F@Нџ…;0ћd(€И—ЫaК–ІЋФ4p0ѕўдй†o№{~їћ]ˆ@@@€@RЧ‘  BI=@v$Т$u    дdG" P›@tL 3С j[ьІ~пєSUЏдЛyЬ 9€@PИєхЅg3YЊэййЖFвDСЊ=гd‹H­ІxkлDж[1UkмG6ОFMˆŸПxсе+:'cq—Wbs=Ф+ьGF№Jд€;p$рHЄ#Ÿтœ/4ќэј“ёO:/яFI{І›ХV$ЋтMо-лѓп“^Й ŽНX˜~Н^П{ЯЎџЪ_њЧЪэЮDзMЏdOЫвžКф17фjФћ4@ƒР‘ряG‚иgЪ;ђзЧ{мI&sВёФsi3FŽyjЪфккоАВМb|RђЈИјk кл Ќžzl{ію~jвфшбІёm.O'MѓnŸ­6[ЃЯN™мrExˆЏўКžŒв7•)IP=Ў^е-ZЖœњф'u=)WQЅьb/LБАМџ†uы HџјЇ“ЋџМCьМИ-ЏЗч’4иNЭКBЎv7WхŒкMДГh—=7{NЫхKМ­И ‹Y"444cvцз_4™*gŠЦOˆЇ4f9ѓ_юm*лZJЦјЄј=он~Ы@e іNеЊЙ9§Е=Y%uъ‹ dyІ#5@ˆhри0јП№їџ БџЮ”щєњЯ–ЏЃ‡ sF˜Щ,^ОъХy/?кXЕ­ќєЙ ЌВКjЧЉ чїямеpИЎЇVSZVЪžњтќЮwЊš>Гъ|гVІЉ•X›ЌбБёOž§ћY’{ъ,еS!kaюьщ3Žзз5|Puп Me%T)ЛШ†)–Дчйы7~4дежьџгЎSЇЯ‹›Ш–И$ЖЌВтЦї7™кcЧlU9аsьѓS;+Њ>љtТжЌпhлж^,\’*пЎќP4Ћ){НєЦїпюпWCŸoПџ–VЙЄЄ@­Юu™ŒCћъОћўЛокд”дšкї™иЩS'}јWє‹AвJіD$џD9йN=Љ#\)d@ƒ 8p$јя‘РOhŽ ѕд|єЃѕЏlˆQOK2‚ЪkЈл=ї…Й‰qёЁ}-чbъ–—– ь/œH)LњэєџrˆЪдъгКХ’мг\† ф7-б&k”zияј`§ъќE‹uљЋѓ[Š^[Бvљф”Щ#cbХši8!yтЄыL~ВxЙ-й0ХЭэљO Ћ*ЪУТТI˜.B?љLŠD3SТ ‰uJ\Ѓдn+ып…ZІMЂЇё“Cz ;‹ъуwмц–НXШIІАзЯ{Х<“З —žš”\ЕэюLњ‹YїПG’<(^ЛЭTбШDzfжСџ~OsЇfѓ–Ђ‡ž8>‘mВ§Ÿ„­zъbQлN=jЇБ€#!ŽёоДWІŒ>~ь2[­f%З›kJ6o:ійБI3Іг€і‘ЯNАЖзПiMљЯ)4мMŸqO>yэњ5ЎS6ЃгVЛІ‰œ!ћp=Ќ ж&ktфˆaџ8ћwЪ^ŸŸ9—™6‹ОЉќїГџ9BШшMч/Н0яE~ЇЌ3vмЕ,~J Щ†)–БчЋЎ•etfiOмЪЖьР%qА‚ZcFЗЇж–бЉaHˆіv‡­ ]я‹уmиZќџ•пЊЛ&vцКЎUFЉБJь6“!8 ћe§‘zZ=zтѓФИ8{mY=?-›@kqђIќ6!кˆ1!а FG‚П bџэ–;5GКфх<[сшЪ4ыyгVъ0Q ‹| rЫFЁgO}тќќU=ђОсъЖW‰“­NЋћІ­ФЎШНSлџўћwПЗћWПњ ів7•yџ§д/ЄeЩв% ,ŒK›(йS^ЗgA6L‹А}џ„їЃЮ(яЉѓ&НzeJЋTCƒМоI—ˆ?ѕћyч˜7ч'ѕpyKС~,ы’ЃШ™Ос§ЌЗ[жФnѓкєчfПКeу=с>ђKЭ{‹јD$ŸдЉ%•з‚Ž|Ф(@48хщ”ТЂ’е‹ѓ(‹ащЛАИdЪ3)LЭƒЫš“>№оM‡ІЭмэ›9}JСЦЕy љ–ЫЭхяTбИ=ЛTяРДƒV’MіŒ>1z MЮЪЮЪ!љ1ЃЧT–—fч eZкккДZMˆVKyЗd[9Ћ”§– “K:№?%)•pх/~*–ZЎйгщ;wЯš1ЭpЋ}Sq!WхЄK)IO’6“ZQsWѕpy^p —‘Œ1цЏ\Mѕk‹ iU"РWщАY[TИaеjmHHХлйѓ…ЉщЁ}§Хѓ^x‘Kк+№=ЛУяіZЂ@‚ŠРёП}2!n‚lШй™QFбЕRNЇяFбфg&9ўё1Й‹ѓF).{­hУ+Ќ2mцЌУGЄчdбыЅЋђЦ?>^V-Џt`šЫtYАg4~LќЕnЧЦ уэёББTŽЯДН’ПтЕЂзЂЧЦаeнУЃ˜ “Ы;№?3#ѓюЛДIЉibСˆ‡ЂЈƒЮ–5+–§ѕЃПв%э™щcbЦpUNК”=/ЧЂVдмU=\žФТe$…ьy™wџЧ/’žHŸ_ќЧ/hU"РWщА‰2ˆ.ж$?;щž{юсѕsfџіŸ-пFpa†ІќD9ЎrєЬ™ТW7EŠє</švKАNњO—-Вфм+L"ѓйХЩXмы?нeї?п|—eїз€­9$u[&ЈP ўgЮЮ4tДЌ[;шОAlЬYuЋўc€юVŸёТьЗЗ•Л0 CЃ1yјOœ№@@ а836ЗuД%<ž@Ѓё‘Cn“ыЁYНlЕK@Oн{Њ@@@Р›0QЮ›єa@@мHIн0Ё @@МIIн›єa@@мHIн0Ё @@МIР ГпщЁ‰ЭЭТ+џА€€€И‘€’Єо§Ќœ˜фЦ  @@@€Иœд)ЃыОзeќ.CЃqє|y{p+п(ЃŒ.ћe{MP   р —“:œgМ”­щ0h4єС   р+\Nъ&ЧЭ/ђ•8р€€=EГп‘бƒўИ$ АЇŽ‘wм—p @@ Ш (ъЉ93„  >IIн'w œз ЉЛЮ -@@@Р' ЉћфnS   р:Eх0ћнuа Z4ПЄ š€€-EI=hiy<№„фл„A% $Љ їГuњkР~чЗЎЅХя|†У  ^! $ЉЫ:њРƒ|yсKё&лёVї”;5ЕNŸЙицЯЌэЉбxhъSёš;нД€€€€Kм–д%V[ZZz§М—ЄвэЋ”б9уvЕЪв цLjjМ2 h  н!р†ЄN=rц/аjПО§rВrКу™3mЉЮФ*Ы‹œ‘WU&#k1щ?}ю"’КЊœЁ@@РeIнъ)Бlднƒэ6AјТЈЛФЉ6с§uX@@@Р нЇ.7KNrAн ЁР$€€7e=ub&э>№`Д-Щ//4йVЊWsв8O\лCBaѕаhХ–œŸМfDТлк#$RnO†+A@@д'рЖt$ЮпzНО`нІ1ЃЦЈяПЕ +ˆђЎЕж@@@ №4шbl*к;tЩЫKf§TJFnіЧG?*пVо№ЩЇO'NXSИЦ%БъЊЇ.œпПsWУсКžZMi™ШЪчЇvVT‘к OLXГ~#ЉeЩ›О‘Х9dч nыlждждЎ %лa§Уђзф'%$­\БвyW<&Iхи„86KŽьВUњ~э=Ь ЛЗДyЬK7hЛ~-ДЏprЖ]деVm{‡КW/ШK1+{~[ђrЋŸ6uZaq‰xЕДД„Ћзл{ї§НхЅ%Ь‡œyЙ“~;§хEТ„eZђ_Ю щ-ј6kЦДŠmЕЦ–/$x ‡%ЅIнfЎ\ЯŸѕ&ѓњЉЦЁyU6rœгn™мюœ<Є@@РПєьлO]/›з[uзТњ‡ГpЈ@зOyh,Ѓг**ЏоfХѕ$,^хb4КžђЬЎY|э’etf…Ы[$Qr‘€л†п3в3 ж\Нr• o*S‹Ю@@@Р§ЦŽ[џQЌос§hлD…Ос§dХКYI­>­ћЈ пŸaf{7‰кmЎЈЇ.њЦRЙЎоrмP™UR}гщ&.щ‚!џ'СŠйOЩƒфʘ(чМЄ_?ч-@@КO 73+=уymˆ6ё‰јmшЅ^Њzчm6W.%)ЕАИ0хjВВЖИVЛoЮVУЬщS 6ЎЭ[Gƒ-—›ЫпЉZП:пVŒзєылЋхJѓРўТ\<Ж`Ђœ™Dн–”<œЖ„%žœ/IчZйnТeu[&Ј№G”JЫ_ƒцРoўПEmmЗ54zЮь9,ьy™ы6—&=+LŒŸ˜<‘Vе0mц,R›ž“%Ьr2dNЦKŽ­dЄgNK›uћ‡лИ”ю”эVЗ%u[е^Јa]s“уwЗ8p§opTлtВёDssГjъЁќ˜@DDФؘиn0p`Ф~›Xзк•y‹щ#ЎЃВ$›к[ЕWЯД‰ЗR^gЉ]lH, 6j+,‘+AYLРmI=zxДЄГn[#6ЌvйnНгєRv/Ікn@П3XFѓнч[9d@@%'Ž4цючu•мƒZŸ"рЖЄ.‰ЊЅЅЅзЯ{I*е^e‰<Ф|)]ЦetZ:…wЌiщл—^Э"уmаTQ2њШ˜‘A1D>Y§V%’К Ш‚XTqRЗє„Ѓ‡ OџЁ…КцЌ@п4Э!g.]›БˆёM(h7мaя-jКМŸ6-Ы|p№к*y•‹Q^he^шїƒ§›y A@@Рћ%uыЋЮMЇ…›(ЕГ‚зcЂпі2КХ7–бы2їЉ3КE˜JжНг;мЌ$А  ^& є>uJrжaƒuќЊЊёвш:`wl…gh^0ЪKRЕLВ—sl [=C ,,Ь3†`@|™€’ž:u…-я;1ЧСo^3§ѕЭљŠKŠ*­ќЄ+ыЦйsV§{#!LkBxЁ‹:п[Ёь~ѕЊ№$,  „ЌS–гl/•7Šо}Ћзы 7Ž5ЦVЬi Jйъ4Ю]‹ьЯw)ї˜њНџDќжЂзФ}ќIМчнЏoП„'жmXЧŸ=)ŽТЖŒŒnЫ5 СC@aRw ˆЮПєф єЬє‰ЉТ <МPj—qй‚iьЙi€н8o{7_Mg›ЖяћамШПџіЙЋЯž§5SЭ/^є‹`XzІVг -YTYn=От1РI№,ЅздЛђ2Єw=9Ј+)woЇєlЬа]ш5Ъt™бe•ˆW'+р›•љ//yїяЖДШ<нхъUнЂeЫGMˆ?ёBea!PWОvЭSS&Š‹y.mFSгйњъŸ§ЭфQЃcž›=‡єШ#Ѕз$OJІц+жДЗ[Щ^‘с­œ,а+(VцЏ<ќсa“|‡fеŠХQоGŸU+VйюnоХЇMы7Ўz(*ъСЈ7пz“šO2Еі@-ЗЋЛЂ{dФ#эЗ<<œФэЃ ю' JR7Дvям=јAЫnюwмF‡yНн:ЃSC›Aј 7~МAKлПк„?7n’g“Aу=ю–ФхР _кв[[Аrљв‚5Ж ГцЮž>уx}]УuQї кTfyѕЁ3oSv№šd5Ќ/ZџmыЗŸ§э }.З^ІU{VЖ”n9сќЧ§јєчЇПћц;Ы][МЅ˜Ыo.й<џХљєы“з  ўN@б№{ЇСіql11ІЛе"=4бE/[НЬУtXŸ‹NвКE?9шхW›ы!$laБХpЇ0а`ў} Kv7бє:ѓжPлц&>є':zиc#Ћ|Л"Cx~€eйWН“­„єжdfd&OœЄYaккЭз$Лeš$Ќ+XG—е™O{wэ}oџ{ь ’^й0yЪфЫЬюZbJ42ёооїТУ„wJЎX%ШФ‹гўLKѕд”Tz8⇧4 ЂX@ а р1ЬО‡-ёЙ-‰'ЪYд{Ѓ$Mч”z­ЃДwЋK]фsрMb<ЛїАмўN›ќБ—‘љ\жœQБЃ(СѓА›Ю_*.)>wщН;AЈБтsгМMйСk’Й e6NO1ЂŒОeуІЄUз:pр@Vи ƒK<­пД’€Фє‚џГ`ук|JъE[Šц, ёЧн(‰ Ћ а–б‡FэB›‚€шюR<ю›aю’й.„Y†f1йdkжБœ e–ђТB:я!€:й,ЏЗ\i!ыіИw №_LŒ~l,мИeуњЯO|^КЅд^[дƒ@  Ч0SFOHQхЊ*0bqЯ5uн7К‚uЩ“cЦЦа7•ЉЦk€(C“ДХcœ:х–OЛЦаЎiЇOЇqои„вЙmЧнЂ„ЖŠWќГLojšљь”ЂЭ›Ић4Ѕ@Ће„hЕ4cЎрUK=p\`ЏIОzEин4{ŽцЪqyЗL”укXa Н•ymM‰ЇЯђUЫiU"РWg>7“tWu4n§+–Kя r—аяё˜o…€ј57$ѕц6?Ÿё|дAЛооеxД‘ОЉќќМчЉоУh„Ќl6ЩЪТw‡ц&Kч=Ѕpі?•žjЬ­‚сяд)гОНy“GњJўŠзŠ^‹“ž™5bxЏwВ@oH1|Н&™fХ/]•7ўёёN6T&іђТ—яўЛGЧ>LŸ_мѓ ZЕЇgQЮЂЈ!Qу'Œўш№{юН‡‹i{h‡<8dъNх5(€€@РP:ќ.Pђ‡’ьљйќ–єа~ЁгfЬвоеЇф’з^Еzр‰Ј‘:EcнаCYr‡=G2~ЪNИяіПзђІ250пЄЮкоњї-Љ’џgUёнПВZїел kтбФ‹Її}ъЄiЌ,iх`еіЭЧВИ g ВcядЎ‚бGЂ„ЫѓuФi~›"'оЙkчђМхшІ‹™   0маSЇ)r‰ ‰"TгјЙ№Ђ/,’Бw‰!‹Члi‹ ]ЂЋ~H`ЯЎ=—/_І‰r~ш;\Ў (ъЉSFTдЎkwК'a`гїЮkЦчЭYп^FяžhэЃh:§СCЪп(їQџр€t›€’sЬш˜њУѕ|јЙD51Šю\яЖЃЮ(0нtо•ш[Ÿ\х?JшtгbМuъ-5є Wужі+СXц[M•цжјыћ,#ѓОя+<ExNsЁ5uvЕ–išмпЭћнќУ7““ш‚КўšОЎОЎВЊњ­tЫа1іиbšЛnюˆлГ+јol0ЦbOѕ   рO”$uI|ї|ЇђђэU•я>эњ5z­жиQRMјНТУМ<ЙмtnћьЧю2ye=3юр?~ЄzњeРЛуLЬO5уIђА  р ”&uыоpxxxўв%вxЌeЄ[UXwjјyeЮЩЋЙюц~М >BЅ ˆˆˆG"ˆ”й†*zеoUвџHаcЇ(MъN)їU!ыŒn•ЮE.›ž(чpкHEхFЦФRc:s)W– И(ЃГџ‘Р ‘Й€ТЄюбKхЎЛgšшђЂчДп)<П§э“Т0;{(ЌP` l’7няnЪыЎ;€Ў sN[ЎBƒ<€H(КOнууъЇэ­вхpaЎœФ=zwЊЈ№sФ( џЛDвVдE№qŠ’КoЧ$›­…Мnь‹лvОMђЖ‹e о7_]улЛо€x…@&uтhъВKˆRzюєь=vА   jЬЄЮˆQмд З3ЈnoЋЉ^Mюа   n' pЂœл§pЏТД}v_шR“ігД;[­пзвЅKўђB—.€€@`фžz`ь!D  NPкSЗ3 эЄUŸsБюsўУ!PјЖ5ЪшJ ЈЪ\ИŸЭ‰eGуO’›дљ­ъ!дмЋБWORxЁ‹Є!  рQJ†пХЗ}{дYеŒafœjhЁ@@Рs|ВЧ­rјГ†й™('gїьMбУщфP  >B@IOнG\Wш&Ѓš€ј:—{ъТ ЕŽэёѕАрŸˆРЩЦЭЭЭЂ A ар•'ЖGR.'uJ/ek:^†Ў|ЃRЉЋ.ДЋ|ж8ЮмТ4пV/wйqVQЗš ЧонrЇёе/ЖхЬzќё/ЫшѓsљЃѓ№9˜ ьљя=SџsЊ“Ж–n!IМШI\ `.'uM2wnžyƒѓ—а„aПЫжпвћ‹У№C‡СљуvъЬД=яV#ЉурEI?~еЧј-чcСЯ@7У3œaХч (Lъ>0а›l/<јР—Оt,0[ƒ*X?оk”ЇЛ:n§8:Иъ№яйя={иОIUNNkѕA—œі]FђŸL­\•ѓ’r­Q  рўнSѕшУ?N2ВЛ†;TŒztЈ;дИUѕxЬx(кVѕ—_4 •fБ€АIЎ^,УЪЮK’Ь"wІ_п^cЧ&ф/]jЋY\Ѓзы'OŸбњMЋЩgё6—ЪЮх’JцЁЙкђ2:к<іŒmя™X2HP]P”д}цђUbB,ExцЬХ†›]†ЊЖРнк>?<”ЙЄЖ-—єг ќ^…&–П5šш‡Ђy™mх2.)W&Ьm1(U—nоД|]С–"aГƒЅєѕŠ™ЯЭ,,*ф;идЭц^бьРh@nЂ,эТnђ™“R@ю хG%uŠЯgЎuQѕС<ъGGwŒМŽ IDATЕіНк­[Џ_m<8ње kоI›xю?yьdё– _7е7lРќЬљЉ“SyCVp^RвVЉƒОxi~|b|ћ­іф‰Щ‡j…єУO‹ИІЅЅхшпŽюлЛ’:л*љ&VЏZ§ц[oЖъZ›N7q—˜˜d•UVn-ЋоЛЇэ_m ПNШ_‘Ђ5йхšэnлєS+іЭ0q=(ЈJ§tUёBЙPrMн…ŸЯ~D"А]Fр­?ЏИFЃ9vќиЮЗv6|м8!qТšќ5–b‹W,~qоТуGšЊ*ЊNŸ;mе–щ1+t^R@nэCHHHjrъю=Лy=•ЇІЄR=е”•МєтKB+ZФ yYЃ9uњдЮ?юljЄЋ6bМ•ЙP§fхЉ/Юяџгў†zішYZRjЋV6й†є3‚гЗPр.Ё ˜€y71˜єkЩіcсLТX@4%Iм’@ўвќа~Ё”>gݘuЮsA=рv‡jБŽЏDНЄвоЊБ>rPф–H=w6?еСП’(V]”ЄMtj-F 3~3c[хіФqёЊўувМeLmг_=7ы.J'wi[ЖMEЏtIо"мїHƒТvОеXш> n{Uh_б”{.РДi4В;jhЃСЌ ]$@$m`вNŽ1юzЩ&œ”\Є ё@% xј:ыЪ>Jв‡уъКŸ’Й+ЎБЗЪыWЌ-ИдвмоЉ1thк:Ќк2= $yБ'T{уЧ{ізєьywФ HЖЕQДPCZ“ДЂU‰ТСEяиЙ[пnИz]_АY˜[Чš№Т”щS–o\лrEGѕ—.7SŒЖ:eЗзюЭЛtЅйV jрЛIвжоЎ'y, Šzъfl<(sгГyЃ№їЫ Ц ХU(ћ'ёЁЫЯ_55dШW6Мт ч%(™9cцкukџPі2]nZЖbйЦЕKЖ• ИwРмччжЌ“4™5sеdхdбpzџ!C^Ъ0ЯТЩЩ†cЏaZzцЌДYЗИM‰GЄE№;Цфзя›+мМффВgяюДє л‡BTП[}Ќёї†…Е\НZИqэ˜бcвfІIд’XbBR—Я‘Д ЮеІѓ—’t--Вс;оЪ›А§e|цЕ(€€ЯЈ?XŸјTѓ"EAjоЋ™:ešЈ&шŠіЮ t94!Ezjа Ž€ідmgЪ•НYЙп~ЪжД)ЌXўК “žDЏN Œˆ@РЋ$—иНъ Œƒ€ (Jъrџ?єјIЖ5Ќz€эЯ0‡)PB€ЭкqЊ%ŽoЇ0A((Jъr\&ІN,XS@УядMПzх*=ѓ‹jфQчyšн†ќ‹€вqмњз>ƒЗ>@@ЩьwйХ+WЌtп є9щtч1}2ˆj| @И  СBРm=uMMvn6}‚…œŸФQ]UџD’Ÿј 7AРDРаn 'џ;‰ЃсЃ::д†0ЅIУb~rPŒŒ§FЇuЩKкчЯ™Лщї›кo]5П5C*`ЎtU(КІ.7QnйšЕфрћ5я‹н”9ІXe7P”дхl#ЫQA€€xŽ€’Єюьѓ <,€€аsрКЗФФФАWGSСVо*mЫ5    ю&užЖyA%GЁ@@@Р1EЗДuZнК&юЃ‹ЫŽ c+€€€€{ (Jъюuк@@@мA@щ№{ЇЕqёЊИl-…5ѕ ЇЎ[hPкSЗv2f”eъЛИмxМбZk   jP”дщ‰rЂvШмjэшW`јнZ& ъq;э%наІеXнецtSzšРЅѓ—ЮўуŒcЋУ~љpdTЄclŽ‰СУ†=Р&@˜€’Є.р{ЇKcђпа(ЃЯ_АШБџ[‹ЗјBRwь$Ж‚€tI@iRяR1|Š@‡fёŠХфQбњ"a>„dеЦUъ4лдiќЋ~ПэD €@РP”д;4EэžІhLсU뎘{”з)С‹WmнцљЉбj@@Рg `ЂœЯюUЃ\ўи„ЧxFwСFЇf]aбј ёєЁ‚Цќˆ!Ъњео1ўщфQqT_РыХšIfЯонOMš=Z UЩVё*+W–WŒOtЎX[аоnšРqВёФsi3FŽyjЪфккоЪV˜™ o‰-оHHъЙ[ЅAQя<}N:Ћ§ъТWЌ@5ТhМsKйыЅ7ОџvџОњ|ћ§ЗДЪлj<ЕџOЛъjkn|ГЌВ‚з‹ ЇО8ПѓЊІЯœznAuеŽSЮяпЙЋсp]O­ІДЬdkёђU/Ю{щјбЦЊmхЇЯ]`њe…йH}ѓ!Б3(ƒ€@ @Rд=+k]СК!сЕTІОкeс@]mо‚МPуВzAоКy^O…9РыХ…%9ЙдT\у ќюћ{ѓч†і бцЬЫ­§№0юйГЇюšž–АА№•yТZь Г­ј "€kуПЛл;л)Ш•љ+yVЉL5ЮчѕVнЕАўс ЎыZ98{ѕ\€ ”ЁХЋŽЫзПiMyfŠEЦ|–lоTўжлe[ЫюўYЯ…‹—ЧŽ%{Т–ц(€@а0Ÿ/] їГЙ„Ы„)ѓышдGgйе8™з„їЛzEЧђ7њ†їуaYзрѕі Нzhш29ѕТI€КнЖb}УдmЏВ§љ@ф–Hž.ЎччЏ:ј—CTЖ'lЋ5  №0ќ№Ли љwXњЌє~DпІАЭѕ]RHIJ-,.ЦОѕњЕХ…ДЪ›––Ћѕ$ђt ЏЗWќPєŽЛ)ЏыЏы7m.Д›9}JСЦЕє[6Е\nІЙrL† --ЭТ\МM›йs{Т§њіjЙвlЋ5  Р”єдi07$€‘bhМ;.zhЌV‹7{^цКЭЅIЯN$ё‰Щi•З1&wqо•цЏЈВhУ+ЌвžpFzцДДYЗИЙrМX`wŒЩЏп7з…G„вНIё i!=dFMЛФTѓ^MкЬi]ŠA€h:)!9Aзв" ФёVо„іWЦяВљЊlЁђВЉSюКg YS–**AРУьш$04rhBŠetЭУŽСœ' ИаSЇ ™ЭЭТxfУсje.ЁЌ!Z)&@ЯuЇœэИ9Щ8РVП рlRg=1!Љ;Q9SSwЌ ­˜=дЯuA@˜€ГIњш”б‘•јPPЦо•qC+PƒfПЋA:A@@Р дН&A@@@ HъjP…N№$u/@‡IPƒ’КTЁ@@М@Iн аa@@д €ЄЎUш/@Rїt˜5 ЉЋA:A@@Р дН&A@@@ юIъбЃcдp:A@@œ'рžЄ> |€^ЏфeЌЮ; IЧм“дч>?sгяKєз‘згЦVP‘€ГoisьТк…$№~Эћb1МПKLeP›€{’:ђЗкћ њA@@ KюIъ]š€ЗTОЛУ[Іa@Р2fЮrЃ6Ј TnJъ†Вз+де^з]ы> %щЩьy9š;š?Х…?э-ј  н#рž‰rы6—žџŸЫUло9ўYcеЖr*Џл\д=Ча@@@Р5юIъ5‡j6Ќ\ж?œŒг7•ЊqЭHƒ€€t€{’zї|@k7pORŸ˜<Б`нкЋWtф}S9!yЂМƒ Ї ИgЂмЪ—shЂ\њ‹ЯЗъЎ я—’”*L”У   рAющЉkюдfЯЯ9ИџPгgєMeL}їрNєІЉІSgЧ?cѕ№ЩЊ7§s‡m5ТБЇг^Н;т€Р'рžžzрs šщў-Wt†[7ЕНћ ьъ8єт­ХEы‹FŽFb”№"ЧИА@T%рžžКmїТЖFе0 Мћкл ѕ‡ыkз: Ё§Тщ›ЪѕзSНхч.~Э2:ЩиfєюнзрРy56љУj@€NoPЅЇоrЅЙзЯ{y+$иU@€2wMmЭА‘БiЃу4цƒ"59ѕШgGЈ~bъФ­ЌклmЗeыQ   рyнэЉSП„uMX}??{VЮмLЯ‹Š 49B=nt\эк''<ж?ьБјЧЈL5Tпpь„Ќfл]/oхѕ•ху“’GХХЏX[РЧHrЯонOMš=къкљєщФ k зАЖY sgOŸqМОЎсƒКЈћm*+с:}~jgEЩOxbТšѕY=нСqуGC]mЭў?э:uњ<цў3лјpЊё"s7ОПYVYС­АB—Ж$ђX"анЄЮ Вs€њ)š7єўЁф|qЩITrgШаШЁЭ-ТCКЙМћўоМХЙЁ}Ci0?g^nэ‡‡ЙТ%9Й|RыщђўЎd•5Yђr^Xпpв3mъДл?мЏž;нФdіUяŒІ|wjCzk332~r”›ЫйфЦЌгЮ}a’?PїaоС ZђrrЙ0/8№ŸЫH |Ш[gВЕ яР_H*А%б€U $`О|Њ(t:лВtN[ШєЖL|ГF˜ык‡|ћњыЏ$6]jДwiѕ?о”lRАz§›ж”gІXŠŽ>ЪєМ^|ф№cŒoeJ‡ЌР.і‹Wow˜d›Ю_*.)>wщe}ЁJd.ЄЗЅ9—oеЕ†… :І…=ѓ˜•љЗџЙŒЄрРn‚ зu­’† lI4`@  ˆЮsЎGЯOОМрКД№>К{Э№ЃЁНГ}№рш&sЗ•Й§`4егжP­ѕЛЙаќъЖW‰ѓw7:nОdщ’… ЦŒЅž:]П;ЮБ<=7‰.ГМЮ(‘WрПШЫыT ЭнЗ%б€U $рžсї H!г§ш/]Єыш rHтj:4Д5b Љ +pМкЏo/К‚ЫЬœ>Ѕ`ЃщqТ4цЪёMjкккДZMˆVKЉКреM]š '!—а Z K-рyCgќ—„ьР2a4Ѕ/,.Ly:…[aglIš`@”їдe‡мХ@б}г№х2]‡їыsЂёDтЏпЊx‹†ЌПОа4јС! r—SЭ‘O„‡‡ѓёj—ЩHЯœ–6‹FПйСРІOІчdбиђр!CцdМф’6W…_Щ_ёZбk/}Гp@ј€Й/Ь|Пц}ЧшК{бцMIЉ{ўЌgЦЬДO?Њ“Ш;уП$d>Œ5щЗглўе6ёз йвЛEœБ%qЋ  pטќњ}s#ЛAw%&$ё+—љъ?я>еxŒ&ўаp"%Ў-.3&э7г$bXu‰]ŽMHNаЕДШЖrМUЖ‰ƒJvŸњаaгxЫЕч нЇ~ёь™Љ“'вt3ЭoSKKsж‚мƒ{п МаQ АwN Г7ЭuMHI дР—˜€ђžКXKeU%нœУR>хuzŸ:uAдХˆ|МLгЭш 3tЗzйпЯD ŽшгЛЯЭ[7›ПnІ>zPeєВ­Ѕ™Г3 э%Ѕ%)žєёНї@@@BР=I†%zmk$Xѕ5”зщ~tК{MoИоЛOlъPeЃюОšѓўмsЯ=ЩЯNjыhKx<FуoI№юIъtQАреBКЕ— ПгФŸ‰Љ О|p•eёШ(ЫнeЎ6їwљЉSІбЧпЃ€џ AKР=I}хвќВзKг_ЬЂ;}iRMхЕјДˆ8€€x†€{’:Н=оЁ.МF €€€€—р>u/‡Yp7ю&uёнъіЪюіњ@@@dt7ЉЫЈD€€€€7 Љ{ƒ:l‚€€€ дU€ •   р Hъо ›    7мв†љq*ьЈ— t7ЉуUl.#GP‡†пес ­   рqHъGƒ    $uuИB+€€xœ’КЧ‘У €€ЈCI]Ўа   '€Єюqф0  ъ@RW‡+Д‚€€€Ч Љ{9 ‚€€€:дес ­   рqHъGƒн ~&q7дX5ЕЇг^НUcЌ€€€/pі1Бѕ‡ы†FэŽѓббУКгm=@@ЏзЗ\бnндію3АxhhЈŒТ€€€[8›дGЦФ’Н‹—.vЧЊЁнРєtG кЊD НнаpфˆN“~К…і зџЈЏ9\оЏOќ˜И­JFUUK]mМ›@UТP рkœMъф7хуnІф={w3=ОFўPFЏЉ­626mtœЦ|PЄ&ЇљьеOLшЇy{@‚Š€GЏЉO2­ЙЙ™xƒ Б_K}tЪшq”бiщ04ЊЁњ†c'ьEAНск§5OM™<*.цЙДMMgы?Јі7“GŽynіœ–ЫЭЌсеЋКEЫ–š?*.~ўт…ќšз››ф/™ uж­/ сёO'Wџy‡ьхэЪђŠёIЩ$Гbm§(‘xШšа7okЯjH&ШЉZWX щ”hVл’i€*№&uo›] KЃюІŒn#;2VЇгЕпВћSьXуБЊŠђ†УŸ>§TJFnіЧG?*пVо№ЩЇO'NXSИ†щЫZ˜;{њŒуѕu дEн7hSY ЗsьѓS;+ЊH~ТжЌпШъЫ^ЏИёЃЁЎЖfџŸv:}ž ѓBuеŽSЮяпЙЋсp]O­ІДЌ”ob6№Nп|оЇO‘!2wућ›e•U]к’Шc@МEIн[ф}Ш.ЭŒzПн)!w†аUіц=—Мœж7œЦчЇMvћ‡лтеsЇ›XЋ}е;ЃG гмЉ щ­ЭЬШ<њЩQЎ-џхмаОЁд|жŒiчО0ЩЈћ0oA.MгЃ%/'— ѓТЛяяЭ[lj˜3/ЗіУУ|“Н‚ђф™l-Ш;№— lI4`@ –зЉ@š%Эи’hР*€x††п=УйЇ­а§шТЭŠц^ЕдзсVЦˆ2нeЉЄ§ѕЖЖ6­VЂеRЊ.xu“}Aг–”ЄдТтКиOKaЉх Ѓ)}aqaЪг)\+8cKвЋ  рHъ^Сю[FiРœюG?б(?Хюj чƒфЪ\%ХkEЏEIЯЬ1<ЊK%tн§юЛДIЉ'§vњˆ‡ЂzйŒ(ЅЭœ5bјˆєœ,šfПtUојЧЧлъЬHЯœ–6‹Я~wрЙD†Шмн}њdgdJT9cKвЋ  рwŒЩЏп77вcЖщVѕФ„$~йеcv§б]NHNаЕДШ:яxЋl•ь>ѕЁУцРѓ кЁЁŒ~ёь™Љ“'в7ЭUндввœЕ їроїTЕх ряьшЌKs]RR§=@јя ~ўvF2K€цИбfшnѕВПŸ‰бЇwŸ›Зn6нL}toeєВ­Ѕ™Г3 э%Ѕ%)ž Xє @мGIн},§\хѕФ„DКю^гn†їю›:Д›ЃюнArЯ=ї$?;Љ­Ѓ-сёяŽ*Д !€Є$;кй0)‹GFЙ0ЅмYНЎЫбѓщуz;Др%€‰rСЛя9€€@€@RАŠp@@‚—’z№ю{D  `дl‡"р%€ЄМћ‘ƒ€$ѕлЁ@@ x ЉяОGф  FI=Рv(Т^HъСЛя9€€@€@RАŠp@@‚—’z№ю{D  `дl‡"р%р‹/t9йxЂЙЙ9рїIDDФؘ舂€xŒ€Я%u–бчч,ђoкZК…L#Џ{‹?ь‚€@р№ЙЄN}єŒпeыoщЕ$ЂЉ3гіМ[Є.С‚UХpM]1:4п"€ЄюН§бс=гА   ˆ|nјнй щ Dиˆ @@д$€žКštЁ@@Мv€Џ&uйбrзBГ’жЕДX­Г•і.mі йBž/мКБ@}tƒAШюэЗ $/rq+WЫн{jž|DЎњy @yяŽ ‚§,„ш“IНSУ{Ъюк В Љrhфаš54ЎЎЁўЙ^ІщLќИxn”ЕЊџА>6&жаn8qђDŽH НвIDATФ§CiЋЌ6о № ŸLъ$5ЌљrsM}ASк'і‘и№№pЮъ™3§#jію6ЇЧ'ŽOlП…œюС=S  NќЄ>kц,[тЪˆAУ† э* [thє?Џr Œ=22*’ЎЌS=etо*хл*G €€x…€Џ&ѕю]o– lЙ,sA]\ISпщу •Ќ€DоѕUЋ9іЎ7G А"O”ГŠиwVм2лЮwТ'  о&€ЄоХ˜5CfєО‹6ЮmF?н9Np–€ЏП{ћеЋb~-—/‰WQп$р›Iн@SЭБ<3‡€€€ѓ|3Љ;я Kт™qМw€Ј@I]ЈNЊьj4ЯŒs$Ф@@ŸKъєюъЊъј'’~5|TGС|˜@@Рc|.ЉГSТѓoЂŒŽЇ1{ >ь‚€@@№ЙЄN”ёю€<д€€€кpŸКк„Ё@@ЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь \TењїЧЗЮŸA9Чл МХhЉЅEoxPФЫˆї 5RШ„†DЂˆrSЙЈˆР! #я†e^JKA6^Qв’ќыС˜T„ТД7ЮбяoГ†5›™=Уryіg†g=ћYЯZы;›йЯ^{эЕкм,*’бFˆ D€ќlШ„"@ˆ Šш< D€"@L%@qƒЉЄШЎбЈеEиyq”$t20єП ў_рg L€т†FNХ™DРІЛТЦж–›R’hаЩРаџ‚јŸ$4&64.В1qSY&`? %j5ГЇ$8 :@€ўФџ ь” ЯF&@qC#Їтˆ D€4cєœЂyTu"@ˆ L€т†FNХ"@ˆhЦ(nhЦ_U"@ˆ@# ИЁ‘SqD€"@š1Ššё—GU'-•€ƒkšxK›K=›8FЊ^Г @qCГјšЈ’­ˆ@с•ТЩЏOвiАўeI_Ѓ“ЅICEЃ,ОУmC]‡къg‘ЌПОYƒjš,œm59oUždгoйк*xГIC4иЩ@gB§ЯўoeК :™7Z9кt{3Z*К ?_\ŠNR|шёЪ†ъп˜Е2њяЋџ1l †BƒЮdЄб™Œјˆv‰FmiˆэM‘Oћзˆ!#LБd6gѓЯLїђtь0СcRVV&ЯИ1}ƒѓИёŽУ•a+Ѓ**Ъ™wУ{іюžр>ЩnАцAЗ‡`bбќ–Zп›~Ё“=&ЉoГ†пЙu…т2~аЁ‡PZZВhYЈу(%ъщtчŽpTr3дLББt§–ЧФFСПѓФёŸ~$ЎМ8/зЊ’ncЪbтИлнм•)~№5сЫТW6}жlѕO…<ЏŽ@џkb DЃщај?ˆGl{i'єEЭH#ўzˆб`ъv&ˆщ™"уТyU§ЃнK/™bЬl‚C#цЯ{;яDўЖѕщп^МЬ”л>:љвўЛT‡Г-хВ”дю№ќї—vnпVpКZŽжЁhф{“,tЈrє…s`yь˜Њэ_к;Љ‚|сќш!јЮšц™—“­:˜нЏgЏЕЉЩPJn’Э[Њъ~џГ<;+sџ'ЛЮ{IœER6R%qcS7nј§ЗлЬэЉќSњЎŒј9ѕЭљЖЉО>>jфЈБЋѕѓBSЗѓr‰aЂЁ/’Кtp’qЪDƒhА“С\g?ЕŒ 9sŽžШ^Ѕc†ЛXpЎAчСм9sЧWЖядžчТэlzJВm7с”Це§iGП<ЙŽg[ђ,FŠц6P ^ДŽ7ЩBбOАяРСих‘‹‚ƒzѕюїг—тУV†Nr™4аaи3:EЦЛЙЭжд“Е——%йLqvCѕGЦmв­­m`\zЃdєЋ.:ž™^иЇN•ФшЗыг­Лер–yгё“џѕ‹vТ—НrФА<НN\sф‡~гиyUџ3ЁкИHъџЛ ЂС˜ыLѓ4$#hp:Rтш“zК*MђКЕЇNŸrїœ†žџcЇЯ0Л[зЏЙМцчи‡]vЋŒч— pд`б•БЎЕlч~˜ і&Yш@ћ—ўїТ9\ ПљюЂЏ—7>!ŸЛ№Пэ… ЁрRсœyѓёœ—m‡ЁУЪўажSЇ ЩfŠm еџZЩ54И]цХЙєe#U7Vp[4rkФ бТB~я~t5ц:Щ˜,бЈ3ЊпžЪn1чњˆЮHУЩ ŽбЈ- БНAљЁьDоё%‹Cє zиєР(ж€ЃИc€†™ѕэг7aЕа?;ћШШˆЏ*ћ:йєШоВM|гїYMcИшjfFв…>!яіЬ3Лїэ~с…,кЩё Йџ3ЯШž|-YК$harр B<аСP ’ЭдЎ›ЮВРћx–ЖO ЗћИrCƒ.Ў7БJро опРГsСD?мо@џkb2DЃ)ааЦ Ј _pзŒ4ёЃ u Ё“E?yіТ…glŸmп^ћИлИLt‰‹O^‚ .WqIЩЏКАЃіш7{Іmw…ьь~еЭыŒiQЋW†,ье?Ѕoп†'м›О`Єh}cCC…Žь”š–ВР/;mLOY(ШиюпП/—Ы,фr\к“зЇ3ЅфЇd3ЙЅ‘њЛŒsЎШЅB4—Ђ?ёь‹vэмээ9ЕќnХкЄ8юЪФ*ЙŒ oЗЂьЕѕУэє;,†C4;jЯ)ФЕ!™F&wђыQУGIКРЧЗпѓ§fЮїУs|к?пЯg–/Гtст8д!)51~U4SzЭ№Жй~f€э/qс,щ–+Эmj ЊtR–§qoа сС„rа ШЪJц-:2,1>бnЈУL_?ћ—ћ)BВ™моH§}}|;ZЩЧЙКa‡§‹§аЭРЖaЫў•ћ/ /№єщфрФ]™XЅѓДnEйkы‡л“@š эИШцRcЊ'hЉ0нSмšЕ}{ѕmќ>ЦЂЭвXыч;~ ПкЛЯ,…’"а: Pма:Пwj5hE№”Фw–oљƒŠЈ˜•НzіZрЏyJвŠPS‰€љTѕй™Я#y"D€4)]Кt?й§ўƒћcFŒСc‹&U7Њ hvЈПЁй}eTa"@ˆ ‹|lшЉ`"@ˆ ЭŽХ Эю+Ѓ "@ˆxl(nxlшЉ`"@ˆ ЭŽХ Эю+Ѓ "@ˆxlžФЂК­p*˜"@ˆhVкќћ‚АФ-mD€"@ˆЈ‘Р“’“сз˜ ˆ D€VH€Ц7ДТ/šLˆ D Ž(nЈ#8ЪFˆ D  ИЁ~щдd"@ˆ u$@qCСQ6"@ˆ ­Х ­№KЇ&"@ˆЈ#ŠъŽВ"@ˆh…(nh…_:5™"@ˆ@ PмPGp”"@ˆ@+$@qC+ќвЉЩD€"@ъH€т†:‚ЃlD€"@Z!ŠZс—NM&D€"PGOŠѓ\*'I&D€"@ˆ€˜@ЕИЦŒ#>L2 D€"@8нИJдj~˜"@ˆ D€p4ОЃ "@ˆЈХ 5ЂУD€"@ˆ'@qGA D€"PŠjD‡‰ D€N€тŽ‚"@ˆ D 7дˆ"@ˆ œХ  D€"@ˆ@ $цo0”ƒf“4D†єD еРLq4уKЋ§іЉс­“@-тЂй$[чYB­&’:,Љ'% -˜@эт€ {‹|6Pгˆ D€'@уŒѓЁЃD€"@ˆ€–Х Z$"@ˆPЋ‹Т"BЧwю0нgіБуЊІЬФЮСЁ‘ЋGqC#Їтˆ D щ(НQт7я-'Ї§ЛwхЭ_БhйСC›nuGЭ(nxдЉL"@ˆh’’7ЄЯыуъюжО}{йВО§њЦFЏвдєЁ,&.оy”;йCwќYћ3'xLњ'М< .фЬ™ќњ$ЧСгgЭVџTФьL4ƒёЦє •НЪА•QхкьY•ЅhмBЯ:№ЩnЩ„њЄИЁР’["@ˆh~Nф;rœdНS?Hљ§Зт§Ÿgb/ў­Inv*џдЖ щЊУЧ'Npё \pєDnњњtезЧ'ŽЕ"nE­Ь2Ж}tўђЅ§;wЉg[Ъe)ЉЂRО9ПsУ6И5rдŠиеp[ŸЯ>™Р jPт†ХKЮ‰ D 9ИЋЌ}Їі’5>В0§и–/ 9}„›-YbнЩЦТB>uЪд{м'/~[P+Г_ь Dр-`^`жэлЮ‘‹5zoЯЉПзКхў™аа1D­пУдЉ%‰ D€Д–:пЙuG2tИVRfнЭ†ЕТ­’kМеˆ$˜Œ‹=qђоnUMoШьжѕk.ЏzhѓˆЎвэДЅˆнjEеЈQЪkЪ…œЭ?STЄyе”ыIu#F@ЁP tдhХQADрБъ84'7{ŠЧT§šєАщŒQ“,t€аЩІГОM§5lzdoй&ИдпЙY-№ёю7лq#bо Мъ”œtБ№""A)*Y<•7Žˆ“| n#Svѓ"Ь+|”ё‘ъ˜ŠMі™И&qяЎНЦ§Ÿ;Nc`!CЬёtЏЇЙ}B|Ÿ4єЃ­ЉŽVЙ]—Иї3]ЗFќЄН—Цр,xgСт№Хм? D€"@‡€љћ„z?![Й"2n_8К%K—Мсљ†*3нљ'ŽЫDK}˜вTLй}<ћђjігТтЁ КЉ‹lmmYЖOk#%žЭ?;zмh<€РЙ\ўkёЏмиЦZГ 4‚л^Цмё#ŠЈ,dџсюI D€"аH&nЩlm3&{ФЏ[Ылqџў}Й\f!—c€dд­žи”нXJf˜В;leЗo q‘ [†,АRдПh!љ?2 }`z>КЩЉSњ/,+)Уѓˆђ?Ы™ўЇрі')ЗUІ&њЉ2ЇПD€"@РџiИЂ07mёэлмtdXb|ЂнP‡™О~і/їуzLйmџВ=ІьvьА4"Фy„Г‰ыlцэхК,УБ-еЮKс4Р)ѕНT„%Ѕ%ўяјsџїюпC7ƒ……ЂЙoЯхzС{–7Мiм.жКхf&њсі$"@ˆh4цŒєЧ'ІХ'rх№aЪЯїю+8џеў}SмЇr=X›$:|Еw_ощќ3vŽuVrF:YИОžBxdИмJонЖ{Ÿћ8 vB7лв?LЧ љпфŽCGŽЩKйМes@`@›ПДQŽRŽЊеs&„‡†wшаЙщ,afЂЗ”$D€"аh]+ dуыZ^)twsПtљR#|%Th:h]ЋІѓ]PMˆ@!`Юў†&в$3V#",П›xК4S2˜б3Й"D€"а Pм`ь[ыЉшйЇ_ŸgŸ{O№|ј)#D€"а ˆfQh­­mчО5{ms‘= D€–J€т†–њЭRЛˆ@г"p6џLQ‘ФЪ5MЋ–T›–H@ЁP tdbЫшD­Х D8БЮSѕэгЗFdd@ZŒЭёЏQџіВпbџэфыѕїIˆ€‰вR`iJшРNдчњ>gЂчжiFqƒц{gЇ~%[чy@­&’juЃ&щ)бгрѓж‚;w5‹НБЄCDРьІЬ№кГ#У”И'*‚†1.ЎfЏCKrHqƒілФYeЪ‰ЅЭ@ D€VF€оЇhe_85—"акдr9Єж†ЇЖэЅў†к#{"@ъF \іАn) Mˆѕ74Ё/ƒЊBˆ D ‰ ў†&ўQѕˆ@K! є\'ЖЅ4’кAZ>ŠДп1НЖЋeAЈ$`Ўї)48щ1ѓc=ЏњМhwхћ‚ЧZ…ЧUx…й nгІЭЃGъуіиёcг<~-ўЕž~LЌЏ0Ф%•bБLqƒ†Н_.>-HnСі|ЖgЪkІ.Жbњ‹я5CWCSшmА{бЎ@як)ЉЌБEЦsЉЏЊ“SтŽчхУЯ0G‡Р€лgl™ЯŠЛ6ІШ>rыњ5ЫПuў‡у?<Їy8PЇDЭФЙtЊЄ“DУ›ТW Ўp#ЩАš~ йћЩос#†‚щЙ‰˜бb(nарЁїЫž'tАх(Pnњ< ІПјоr™Ѓ%Ѕ7Jпєysё;‹WХ$Т_NN’Л2vYwГF2hiPЏНЖmи†$VЮЛpіЬжзыЧ &š™ЃОфУ \бѕщ!0rHЧЯ…s†‚lІчbії“ЦE>^ўT: M‰РYLlŒѓGьdUїЉgO>eВу@Л .ВіeЁЦИ•gŸLаiCђњdŸЙ>Ў“\-кY`‡€ф‡ы“™YўiU@`‹!кЗo?|ЬиД ›u< iмlcZЊѓ(gЧŽaaхB?МN•t’м€ hк‚MїœЎОZЅАЁљ+cрž3vd№Іщ7Ÿ™7—Яњ<ЅРmhl•XЏЧкнЛweЭѓЮН1т;NЪЁ рТїIЕЭeŠчšl*пУЋbДLзBг[WuсЌщЧДу№іиwдTПUЪдДдпoўО?3{ёЭb$™qpX№ќyAyЧ аI№эХoЁ,јV(€OAаsxтФ З1nb=’P2ƒƒ2jeTAA№фF//з1ЫиДёќї—іВ_uTeљЄeJr rщTI')И­j&ўžЪ;ЕsѓNебќQcG­ˆ\С šћїьƒйћwя?Ÿžлы7ŸWВyBKЬПmкМЉgяžm,к q"|›•яŸ8|ф№ћ8 ›Œэ:Х33|ђgO{?Mp[еЯ‹гЪЪЪkІ]СЌпѓ§ ЏhBН=ЛіАŒа@Y­VOy}ŠUG+=ХcЪ[ІNв*йIo7АV™ў™”œК,Д _x.H DРМь^ЖгйЙџ_ AЖхСЫ‘d‡,џbYRV‚g жжжс!смоPvЋ ФG‘МuЋŒiз$іъбuѕЪHЧсŽм'Є&ЏcзБ=d#f;>л+дГs{ ‹€Y‡„.Zm‘K#YvoOя‹U>ФЭYТжЖљW._бЏ†!НО%iˆ@K!PŸcГ1(јVїžФюeє‰ uЛVrЭК~ЕйкК§­’kLNўчкєЗтvМу_-ƒ–…Ь Є[дЙSч;wJqaц•FЬбЉSgцЭЂЬЧЯ;ŽЊеEл?й…Ё i)ТHёfФ *]^uб ?фМ&\`ЧЅ“pЎЉŒ…ьžа!˜ ЭЗж6П2П 7мќJ“жњ‘і^ЛЦ-xgСт№Х:кЖm[rНЄЄДФІ›MJZŠЮQ#IФ э;iЮœ”єUŽ `гчХ>ё ёуЧпњёжЙsцюйЛЇ­eлн{w{Нщ…ЋўЌщГ`vюќ9s YLTЬгНžж$kњ#йIoцŒP+vљЧHJjrдКИ„шU5UUтјНћїdOHш\%ќѓh‡їyоюЪeMзSН‹жК­юЪОКЅˆ€9 рJ`њ‰'\6ЬЖ џbM`“ЌFЅВ‡MчRu‰uхЯtщ’N6Yї~п^}V Пfxё*22тЋ/iš!щJ&ъ84ѓр^Џ{ѓж"9`шPц+!иvS/PŽІШˆY'›й[ЖёЋ‹`ЩkТ–пPRJ/4џF‰ЕЕp•‚Рнl>+ЂщтС\lќЦН>ВџшЙ'sхъ•ЫТ—!ˆФƒЄ1уЧшZHлTђg‹~)R<ЃЛ э№aУ}ќ}`АiћІ?њxuьjФ ЧOпєс&(ЯцŸ]К!Тј‰кl’Э‘єж Я)P|№Лh†NKKK- uЅtЎєBxжKO.0%KтAlL\Мѓ(%v|žZнГwЗ0 bА0xЩЌ§™<&9w˜юх‰9s&П>ЩqАУєYГе?ёšhмђtuЁќŒяТ;KЂЄОŒРB_ЉЏA њJh щ%IIЬE ТшY­SJѕџњЅ ЗД}GєыР•ЃЧЙЎLŠ+E_С;dЦa+Ѓ еE…џхћ4:wj[xЃHп43}gnм”Б'+ѓNE9vHњЭіcЦsцчUЁ$еЗJR>и№ТЫѕ§1У{џЁЋWЊo” WсOEЈЫЎS%$o&X.žD{у’’YѓуR„QœЬ@ВљьџФOk27hd iќ ЯТі|КЇДД >o —љ:lŠЇ7KnђЧьсFкОаї…Ќ§YrKљ˜бcю?Ијаah„№E&›ъ1uЁџB<з€qљŸІп!HзNв[ƒФ •х айќ‚gMѓЬЫЩVЬюзГзкTсМd]јфSВdъ)ПџVМџѓLьХП#Щ}bXаЮэл NkКOхŸкЖ!]uјјФ .> ŽžШM_ŸЎњњјDŒњ‰[Сsъ иˆk:Dš)Лвfк “Ћэ;ЯЗыпЛКMvУI–еy„Ц8 uHLMŒ^Э”^3}ННМЄЦ}+К)>Lџ]Чу&ŒУIжлŒМѓчЬ?xфрДЉг; ˜(//_ГFПŽFЬМgxлПlярЇьт<ТYВJFjЈ_4О>Оr+Й›ЋлД7Іѕ{Б_л'5V’Э—є@JNoаЃ+џƒю§їззJ№№ŸяС‰№SxЉC#Yі‰&тсШ\ЏЙHтнаАCшА—Ыхˆ!kюл‚A}6IomniяХ .Ђ/ЅU”кŒEФ›ьbЯžSќўg9ыйуzБзŠŠђёnюGГ‰32Б§їёлжoчн†3чћ}ЕЫr<ћяІC–уGŽАnxv:LœTŽ–W^ˆы –б{с5ЧЇМB<р$t9eНhВ,dуІїџп}ЗInТЈЈ'5Џ<1Ь olЧХcš—уВџЪ№sА*fЋdvц–e„ŒWЊ2іюџ1ЏŒ‰ ‹Д Qо}JJXѕcбЌ{јћњуU.V}њШЪЪru5ѕ\Т ~™{wOё˜*YbП <—№џ5гчЮŸІэцIx\ŠдE їэ~o›§іP–ЙЯрi,nNдчњ>7Іr€ЁX/8Ал}І7”фzLАqљЪeћўіЩџLfѓ;‰}rKБsБ’'$% Ч,ь_В ruўyёњЦK/н.О‹ о˜шаЕУПП§wп~}q(ы@V№ЂрЫџОЌxVБ$ТЧЯ‡U›{цѓЯ>u”<)щ­*ž;Ј‡Œы7rГq‘‘KЕУq™KќЪр]‰‹…я§Q|™PјЕ’24Р„ЪaJšњё ЅEЯfфаˆ“•Ѓ~4ЙjјЃswU•Ф+Ix1 yЃVDalдџxЧ нPьM'QњНу•А:ЁЂB˜ nэКЕБЫcYqњй5еЈєŸБMѓJ"§јuёxЖx‘0Фя>E‡FуQVщ­вЗ|hњoНЦ9§!†Tи8ŽгXпJsbыЈЇІa3зГR”]L %5Хw–oХУŠф”фбЃFѓБjA IDATGУb›f(koы\yqа'†’\YYOЬЪ-ХоФJVеE aзЉЖнЃ Э4ИrfxЋ‚НXСВЬ}KгхР=sAьSGЩ“’оЬќœ‚=n8њ/UlДцn[\Г%K—Мсљ†*3fљ§ њё›‰e6N‡i4У”Ф‡KЦ+IDАЁЏ’ПšЅSјч;?ЗГЗCW>љЮ оеЎкŒg7єJНћTХў6 §A_г€Х“ы&F K.юSннІИuАъ€Ђ‰еЎЎе1сZSWз­1Ÿ ЗќцУrџў}Й\f!—c€dђњtюƒwд7Š0Ў˜kИр"Œг‰‹ _ †)!ЩеM?‘ђ€ё:тM“”|5ЋвNk_PP˜є~вХ‹то“ВzЅŠо}$›•€іМ…[М—Xљ"ЂPBх;ŠеŽšЕ\rжд L4{SЏe-ыg†о†Z–иВЭ5nˆŽ KŒO|ћzP›sчЬј"ѓ зgІяT/o<М`У#ФФЬѓY—2nВ”nун5ПЌ–V%ЋПšеCлSRe€š 7%harЭ ‹vr6Ц‚›Яnш•Њfџю“љПђh8iEч-ѓˆ=MH­sШЬOшмп љ •€9у§Ћ>kзІФЮл;Х]еzЭ№ЦЮѕм^а‰@= №3Sь%ѕb›њЩх8“i#D Й0gмамYЉП§Ы§№b’№>Х+c№ЊГdя8Ё›?Иа„UіІщѕІрdv^^Љ‚ŒWЊ№РЂ[яоoћМЭБwŸ~(њЁwяоќе/ž‹"@ˆ O€тƒЬY4РO}нЛŽ)Ўїь’ЯєЪaJьмЦ­Њ7…љбЯ.іЏуJуаyЌвy,wHxшЩТу Neš—ut™•'Х еqzškH_=7Ѕˆ@3 €паF?Ÿ EЦЖ хШqЭ€UБХPхfу ЌsГЮž>;еkjбEќэФ:Лj‚љT ІзтгY‘%h}ЬtЃ6аAX ?п­ Ејё@аРЮРКU%pIрЦДІ/0QЗR:WтCUЂИA‡ŒDЏl>І€ЌХ:@:)IšœфчЙd-MЕ“Ь\]‰юњќvWwF)"аx.œЛ€e ЏМк—dJL`ЦЮŠЊEfКЛЊю”RD ‰ ѓМ‰}!TІL@XX’.•ЂoШЬѓEŠ<7GБœнˆб' Œ@sќ7І:3Р­<Мс“ X,jЪыSЌ:ZЕБh3Хc ж†а”ѕ@aнЭ[кћiМБбБPZYYaIЊŠЛš79<Р~<єьн3c{7ц+ @)и! ЩБ:p3–фŸќЈЄ~гЗ`Й,T KKбVn%kЫ‹ƒРšOqƒ˜ ЩD€"@ДXї>>™0Щ}R`@`йЭВђ[хНzїZЌY9"vuьЙяЯф\Йrхцѕ›,B|ТЩќ“PbUыŽVУ#У™~КїєЈ˜ЈGwхЉђАi Ћ’bЂbŠЏ_џё:іЋ?_YSuDт/ЋXeБУЦ§GDGп,ОЎО~хћ+ЙGsЙGCЕхXѓЭЙІи{Г“ЯцŸ)**ЂёоЭю‹Ѓ з–@vnі8“пk`б K0}=ЬкV’ь‰Рc! Й&юдйЕYЇJшxКзгX zєЈrTЖНlХ6b%z&њМи‡cЅJ,UШ—VчМ)zЊŽjМЉR+•?§ НNMx’ ЬЪеїЯmtœ+žQАжЊ-ѓ)ўЄИAKƒ…к4ID е0>т†V‚Д45Ц gѓЯ. ]šw2OєPЙБ‹ЎpUўя#ax!ћO5DЬKЧ­\НR•ЋъмЉ3@жSƒ_у…ЬdmкЕa+^Vг‹ТНЄnУѓПhЂ"CЕ7€5Ÿ{h™аxo- ’ˆ D@РTЉЉяЅŽ§|,ж=ЦxЙ6ХГ ѕ/jўХг D6ж6Ь†bёњ=ŸюA|цјАО~‚ТVnц n]Њ&Ÿј:9,,,`sчNеа qЮJйИч<ЗЁкrЌљ7h™Pƒ–ID ’€ёў‚DZ{їяЩхr\Й1B04"”7пwІяќwчo^ПYоNОnэКшиhТ№Cџљў‰I‰Жнl ЏF­‰ТьgаћЬѕС:ˆXЙђНџоуNИрэхД8hг†Mа@@’rр„ЈeС; nпЙЭ‡VраSO=Ху $ћїžхД4hгzsцŸ†jЫ АцSм aТ‚џЭ 1)’‰@K"АчГ=S^›bb‹вR`ih|ƒ‰NШŒД›ЗlЦ —џ} CАcћжДАeaСaСИбGrљŠхLЙhсЂY‚r”Вш—"ћ—ьЃТЃ˜ў—Wм'Л_ОrйОП§оOі2Ѕј#(-юўlw(gOŸЭTІ˜юї–пт№Хшˆе–В,Єџ€ўwoпeЯAŒћ їЧПЛmїЖkЛ|йђНŸi*`ЈЖтŠБцгј <жђykAљМ}FhЩ2dКЙИ™иТђŠђ=;2ІxL•ДЇё ’XHй| HŽohОЭi šг{˜ –м"@ˆhш9…јK-oќѕ~ФХ“Lƒ&‹4}]+šYВ1О*ƒ4'M=nАsp(ШЯoNDЉЎD€H qЧRTHзhxЏy)›-n˜0qќW™‡dOTЋ^Хнђй~ГЖЄoЕhЇyYЅкa4˜‰Lˆ@S'@уŽ›њ7дЂыGУ{Эћѕš-n№deeККWoЕ{пюўvџЈsа`оІжьMш’Ѕq‘5s"‹fNsн›~žk&ЦЏg“1+ЦпЙk№ѓzњЇьDР)3М0М—^ 2‚ЈV‡Ь7Ь|sVШв%ет†‡ВЛіn[ŸŽ mLпБwЯ§ћїЧŒЙt‰……а§€gЫ—…lкОуZЩЕ‚гљИ#Iњgт?ќаЉ{џйs]]…DћœтЁ,f]ќсC™PŽяО8˜ѕmР`ѕŠхi[6нК~эйчэж,_f[љRlЕМH˜Ж•гг\г@‘Uѓ%Pё@Fчyѓ§њЈцDрБ0лћ}ћєэfћЬБЃ*оЄœœœ/ѕЗюf“БэЃѓ—/эпЙKu8лR.KIMс6чППДsћ6 а‡FЬŸїvо‰|„п^МЬm˜њAЪяПяџ<{ёoХHrƒSпœпЙa›ъыуЃFŽZЛšыk+˜~ V[ЯdOš+ŠЄ›ы7Gѕh”гѓ7‹ŠдІєZ‹Ч$еЙbf‹а№ysfmЩиТ lЩи„N$w|Б7$8А}Їішf˜˜uф0ЗYиО}{–ДДД,)Уд™wЌ­mТC‚Й dg…, 1Жх Cdс‘‹5ЮН=Ї^ќО€ыnlж&СŽC:bB0>пЇн‹vYћВ&ИLph7нsКњj!*3ЧwNЮс^Ћв’в уљ‚Њ\Oh‚Ьѓ”BгАЪї•№*эD ‘ 4С­ц\%Г=Ї;Л—АЊGСљ vі/сЁCЧŽб =ž ИМъЁЅ$*Сз'Џ[›ОykjZjЧПZ‡<ˆ‚p­Є ]LсVЩ5~дЂЦ т’{ѕŒ+MЫюїŽ_THTТъLОacЪкukc—ЧВњœЪ;ЕsѓNLZўбЮVDЎиМѕуљsцЏJX5жy,3јpу‡3ІћŒ›Vo& DРlDч›сNЧ3жХббP’цN кŠVFУЛ"и”:ЖЂkИЮ‘:%gЯšџСЧ[гьЗюи9kцlцЃ“Mь-лФ!‚Єo ЋWсbŽШШˆЏО<$6ыaгЙєF  tВщ,>кШђч;?g%ZЬВћЂћ!fь2Ю5.)NxŒqчЮЪЄ8$%ˆ•2)Nš&Ѓ_VГуЧ”э\У…‚‚‚9ѓч8*aрршPvЋЌъЬЂЪ< CЁВѓCgћЬ~§ћ’з'Я3Ѓr13mAа) Gi'f% 9EЙЯ‚oЕSЄTЪтSЮДџ­№нДw\ЫМ†`Х pЁ!™4F‹Вўцљ:„_бКoXТjЪыSЌ:ZaЅщ)SюмЊz-шА”•••u7ыД”4mєИ‰O{?­gяžќn>6:yсСkІxE2и@YАЬиžСмJ*qˆЛв–^)щ{f–јdГпДy“P‹6Cœ†рКІуФPвЬqŠ™=knxјВй^гy‘^3Мэ_ЖŸрч8иaiDˆѓg~H,8p qъ”šПJXLLМ-˜члёя]ЧMvУоѕя]‘5›,њР№ЖыŸИXЪь 7T™й0Ш?q\k€zˆ<ЕЊLЌДќ‹,5mУЙ чІИN­fSi`Є,}cвГРˆГUјŸРЧ›iCWCSлћМh'оQН‚я К’РЩŠр‚ИФ;w+ж%Џщ2сџОl7XщьМшийГb}M+u’а"qщMSЮъzl“м'–н,+ПUоЋw/ОeDtDёЭтыъыWОП’{4——`H<ШўюЬwьn>!>сdўЩ‚ќ‚В’ВŽVљтUгНЇGХD=Кћ(O•‡Й•TђuIЯЌP|2eЩ§:+}—џQюёš‡ŸПŸŽCI3?Ї@1шЧЎSBь:JіSХ•РpЅжц 9Kъ—дTц'Х2whLxhjPŠJex“T.W—–ЄWОhЪЃY.А‚xrЖЯлXЏŒVTŸЫX}шhќДЛG ,ЉлД<—е&е(,pмЋGЏmЖс6}ЋЮžйњсz<ыlR•lm•9wўœІЩ˜Ј˜Ї{=Э’m§HuTХС'ЎKф Kв#Ўшќ‘}JzŠ*GeS9n/&:ІЯ‹}ттaгЖmл’ы%%Ѕ%8”’–ТЪ’Tт8`–ј4ф™p!эН4Мj€$жцЦ2›\o\0ƒёђZЦбАШАФјD‡Ё~О~і/ї3ЉQOЪz?лclхЄ&й“ NЏDБ2!ьљtЯ„ё№ ‘i6ІЅ:rЦ+TaaхBˆ5й}ВњЊšЭ9Јyg шЁ4єжГ7є™Z…eš4Р?шУЧŒMлА™ызUŸ\€1O2™e‡Rџm/саYЬЪД ­Ыи‘Сќ@}ідйщS&уе0М †ŒЬI3§Ќg@|6џьшqЃё4=ќrЙќзт_‡"u‘m/[&л>­4ЄЧ!kЭш~Сь—"Х3ŠЪчm:tюРнfюЩќъШW8ёњ=пя№ЁУЬПЄ’вџ4фYп’ а CѕџЃ\ZCqƒ4уZх0хОНћђOчялПЯЭ}*nд˜=є“|{ОПqЗt”4=шx6пІѓфБ'б2:pLvўлѓ;?о‰ndиdlкˆЩfіВї—–OZІ$Ї@9tШа чЮ@ИSr'<*\x>§@vцмш!р­ЋYгgх§+OuXеЏg/МuЅА‹ŠаhDuppPF­Œž4МHYВl+>сL')xЧоіRЭ5vоіbўё ляЗЯ>˜НїўѓљчЙ}pX№ќyAyЧ аљёэХo™qs§ЌФPчЉSњ/Фгмм—џЉ§Pи*д?iGѕ/ЅвыT@ёДтfЩMсБAеЦ 1 f---EgƒЯ[>F”:yвgnPOт†ъё4ЗіЬЌЬЋП\UлЮЩ'Ј\KL?ЩЋџДМ’Ьћx—МЛ„пэј “а„ДяŒIh,dюП‡:bв9™3-ёЮTŽахpў›ѓаCР[Wvіvx5/Xс­Ћ'N@Yу–И&БWЎЋWF:wœр>!5y.'Y‡Š №ЖkоітSнјђ€аДЪ sфp{ЫП`B<+БЖЖ чњV(мЛн јъ1@rюлs9яYоxЎ„a’иёКF=7`ЦTњЯї‡ODc…— 14’щ}цњ^)B4™ьояQтx#ГФЇ!ЯO=ѕtИqŠъ­vY№ТХІ-›ЂТЂj—Ќ‰@S PљуeОŠ УИIэИAЯч{eнаVVCYћЮФЄЉmх$4.,Ш6b{…j§Kщ ›/Пк§йОЯ C=#o]UЙхei™р…,?пwюЬ;ЅJOIО]^Ž+Г—ЌCх!?†’вo{aškk<съP)hВ'џsэЉгЇмЇКOvŸpьє1fаl?бЈКo›ЗlЦУЃ6iЃЅ9t$wоЁC‡юЖн14aЄsЭzž‘ ˜<аi˜|ЖiзЦѓMOЯз<™ў—WЪ%‹—ь§dЏ% `–dЗHђВ,Єџ€ў’Ё†ŽієJ.ˆ Ь?.RьНЪк>(sU>?яx•+ѓ;ЏђL‰€щpšz*šjgbсfŽBL,еЈ™~•И† 2™Ф$4dOШŸщжѕиa•ќIKМvОўƒѕЧŽЋ 7‹xы*harЭ ,ьWQQю0tЛƒjУ=sAЊŽЖнС ”c4%ы ЩЇуЧPRJЏ™ЇђЙ;{[žUЏo/cъHеЗ ыаСVЭеХ;w0ї-M—z 6ІoФЮЁћ€ †єxС0xь:Ъ)ЏMСnŠ›VD­аБdIIЯ:Jњˆ“bYп?ѕ7Tg‚џ+к‰@Ы&€SоєVџџЈWЊђ}%эuИuEstъУ5\`гwўЄџ/IME‰тeБІR!sеуЁ,sпnCЇБИœЈЯѕ}nŒшЉ„ј(ЩŒѕ7hЮ…B‘Б-C9RИo Д`х˜|o šЖЉrГёЏaš­ Vѕ{ЬlBdR)Љ)ОГ|+V$Ї$5ZxнІЅmд•lЮo”т MЖš~%ЭI—|ІG/ ˜~ž#hр Э4НІPЬC K.xoтўƒћcFŒAaЇMЪ єаf>7hYтї‘~"Е8H"D u˜:i*імVъm0я—Kqƒ–'жя.іа ‰ДVцюo №жz&QЛЬС`ќНЪкVт 14јшОJ[[ dOš8=Ÿэб;мPгRpШL§pхxЃ6"@š;Š4п z|оZpч.їnюЇ4еПхЪM?ЯЇЬ№кГ#УLqC ЃУD€'`Цžƒ:ИBV=ŠŒMt”"@š9ъш2гШžwPм ЦYо_@7d"P9YЄщ/к™щ—оsІ3я1ЈяыФdЫ#вЗЄcЂех+–ћП-Ь']QQБxЩт-лЗ@ž§цьukзaziШИ)пИi#fЪТbжNœв?LЗГ–b7ЄЧЁишифѕЩ˜Йk’ЧЄMяoТBhPЂ,Bйэ>ћфу хХ‚[ЖmiћЗЖЫ—-МUпє]jNѕ|šХ ’XHIˆ€9 А'ІПџiЮВЩWЋ'PЯсНБЋcЯ}+ЊЫлЩ0œ1Q1ХзŠЏџxЩщГЇЧЌŠ‰^Эх~›w2ЏCћЉяЅњљћT4ЂOˆO8™Юa@$<2<>!іњ…"VРѕžG А1”7":ЂјfёuЕPЗЙОкЭ04бžщѓEšX™ЧK@rОШžН{ЊrTЖНlХuыЉшЉ:ЊQbqjЅГђчЂŸa€KћэлЗй ьИ‰—џMўЈт‘Ни9жуЦвšЅ7Ja/ж#Щ6ИAlS-oѕК)žQˆЃ iWеГ№цT•,ќхЅ7ПўЌиіцМЗПН`UЬ*Д“цОщџжЎл­Лй Д"Ћзo[Ÿnmmƒ•у/œџnыцѕSж ЎqКdkxOЌЯѓvW.дш‰ ˆ@&€шИ†ѓ\Ty ЅE0Hl•Š~,В}КZа ˜“›G8ZtSЛb `#<Йј™Є3p]зUI’…Vдќ5˜ЗzнtrI&4GпОу†‡В˜uё‡eЂcЦЛ…/–=!д/@&§3ёЧ~шдН‡џьЙЎЎnшl€ž}ъw`$oIї™щ3!ГLсінлnI‹D2џД*ё№q Ь‰'У—4мY‰]АЋмŒwcРDќž˜н‹vпы†аˆm4~ЭёчьЉГ[ЗoХЪ4–––CG ХЪыќ$гqx(зЎ_WO}UрїљЏLєЃОZˆE№ђПЩяєзNXўееUЛJЌNq”la*T;Я[XыЈ9DРьЯ*дПЈy”Рќ+lшf`JUt‘Иі›RХг <дАЉ\Ч\l/YЈиВСМеыІ“K2YЋц4о:кЉЄќў[ёўЯ3БџVŒ$Ћ}phФќyoчШG'СЗ/CЩb|ъ 8zтФ ЗБЏŠ[Ž$”Lу№ђ@,Y‹юSйCгяЈ4ЮjA\‰zЫ[?о:ыЭYЊcЊ§™ћ;Zu ]jШх†6ܘ>Cчш™Гg†*GCiŠєƒљzzxЊўЅкЖ}лЗп}Ћу’D@CРLу"‰'hО|gњЮw~ЩмГE„EА†` в ХAx:€’uk`юлцћЋБœфYсЅB,ЏШќHњдSO!XсЪы=Ы;hЉЖnм^,шИЊUsЬ7р†^gч=В0їаи–/ 9}„Тэ5VЁФ†' с!СмоPvЋЌ}ЇітЃHоКUЦ4‰k’zuщК:6вбyмїIЉi)ёР%~дЬ BжОЌ .кMїœŽлwЎћaіытжeeeq=dhx’ i)iZШ-РCaй’И:6Hтє:qђ–Ле9tъє)GGG(MёƒБЛ8S‡;Gqж6жсaс:о(IzJAg[жџљўv/лѕщгЇKї. 0vэвЕћГнБC@Вn -\ф4ЬI9JйІ]Я7==_ѓd~$ Yв@Œ3`6†ђ†‡†wшаЁЛmwŒ–щ;vlМѕџю3&riЄNЦ*єЗШ:˜хњŠіБN$§Fђ3ПтAEц^ƒ гИH}tЄiж$ЧE6ы5DхЭмп`ЄŠ=l:cH#3€аЩІ3“ћіщ›АzебьCЁЫBWEiК€Œјъ843ч Б’†k˜lkЋ~7ю*§CfбрrлОs{Œ|ёієОЈ7ЂZOЪ’ж$­JJм˜žš˜”йHа€Ў‹UёЋ–GЌЉцЁ2qіьйп/Fа sЈрRС3}_аЙіёƒ>›ŸoўМяѓCЊУ*KЙeдš(‡”l=xˆР›ЌЏс‡H D€4^мр2Ю5.)N§?ЄU IDATx qчЮЪЄ8$§А•Qш&\z Лџ@ѓtюдV}C;и№ТЫyvtcpй€€~YОУ„Ы\рJ™E;Œ1Гї„š3.TKЖo/їxе%y}њмщ3 WsЗЁрќYП…ЩkжZwУГнЃIЩЋ.ZXЅз”wђы!NЊєB.у~:ЗmМ ѕЧќю[‡П>,ЮKrK' =sXK ОеvVЪтЦД"@Д ї•kmЬ#-˜чГ.eмdс=ЗёnH2ПЮ#œƒCn§№lяоёЋЂ™вgІяT/oЬŸЅ?"СЖ›b{њ‡qя'G' “c8ќУIі&’ѓцЬпњйЮˆUБe”ѕАщ1tШаЄ‰wVŠФgUрЂ9Є“dZЎф‚HпіIFTА:Xј‚x›њЇЂНŸxџŸ‰Ћт•NJ^a–•}цU%&Х&ЏKA Ы%> ЙрћІ{ЯсJЛ—5fœŽu‹]T%Aєšс]GЩ“˜х)-^zШ‚§K †gyвV†ћ …|ёІ“d‡И’ b§Г/к}ДsїTЯЉw+аП‚C0+Џ(Œ‰Š‰zЩюЅа'хя†.]ПiНќ сeQОэўtїŽw$Ї|ˆїat<;88Аa’тС’L)8П[~ѕъ}ћПФr™тчЕIЏХЇІ,@щ)џL3bŒN‰МV$ДH’_7Ю.I}‹$@"D ЮЬ7дЙM6#ЎЭтК‰/лbНX^ЖlѕЪеxaЁGїsпœ›§U6ŽЎ]Зv†ч   TtН(eнкрaТ ОХХ A†Чk\sќФqyхD\#)œ9ц…8АЩ0``ŠŸБЏŒНYђГћdїћїяs†’žIIˆ D@‡Х :@ДIЩ(+ЙР2№dп^}ЗlнТНИЙ Яe"+чЄтЪЉSЙЬюkИ yˆ+ѓђђœ;7fGy$НgњbчЙH h_c6`@j"@ZŠЊпЭ№i.Іs˜ік4ZЩГњI)У0‚Ёžч†лCGˆ@г"€ єзƒhД*жЖєккЃ!74кЗйPэлЕЏЁ\“_" 3L’€"`2:\’ХОы™]ьЪМ2Х :<ЉWV%[œфІžчІкЕлУэБhVOEOМНЯ5xv›6oъйЛg‹6Cœ†T-€ чV2;SroЈ ФВВВB}Аž‘8Klt,”8„хЕxe9<Р~ŠF2Ж Х bh$"а Ааfў7ОУІAЪnHЇч/`Х&Ђ5O%xA\0_ђR'1Q1ХзŠЏџxћеŸЏЦЌŠ1ф&vuьЙяЯф\Йrхцѕ›0[ЖbUє*nМ8Xg­~BюзЙXnЛќrМЋячЏ™Yп­8‹!9":Ы6]W_Пђ§•мЃЙм,!>сdўITВЌЄ k2ѓ•КІ{OЧфCю>ЪSсэН<и›s]+^|sЮцŸ)**RŽз+Ou&ІШЮЭgђyЎЪЭV(„ецє7гзЕBФрПp‘ОБ&-)aŠд+ЪbѓЪš)2ысtŽЯьљў VЮ5Wo5V„С…ГA­HЎk…;uёsŠлЗoяљTш*@ъЈЪЖ—-d,o­tVў\є3dnЯмЉЋr4–0`лх wƒІМ6EШ;Vљя‹џЦjGU…П<;ŠЅ’ЁDЏ†ќoђG KКчрzj+žQ03Б7<‘СZšЅ7JY)K"\]]mКй ‰Ц702іЫˆ_IMšўJг”š~ž y/:оj˜@ж„^ќї,h€m§Н™P ™<ИшЂ`a\фФI›жob•(RБ IлЇm‹nJЏЉ„ЃE?С€хтŸQaQ‹7рnf ›1 ГџhJКеЩЈŸдЉ67(њЅ1Or!sOцЪе+—…/ымЉsJrژёc(nрp„аСа}•жˆ$"@ъF %ЦМwџ^н`PЎцE@|уЮkŽ5аU щoјE­ш"qбeЦŠgъ_4–<;.Р–с–Ы#Nœ8Б1}#з›.HКеfџЁs‚…#šХ’*щT›л+žVрQˆЕІSыэ^Жc§+шр3Ч}*4ОУ!ІK]Xќv‚Ч$ЧСгgЭVџЄ QZZВhYЈу(ЅуpЅpіїёЁ,5-ХyмxчqЪ=ŸюFУр}2ЩwяРkбё– š‰ЭЦє 8 ЯXЖЋяr&ˆBЛEwїїIvƒ5еыћ™ь1IXИrЫ9˜Уh ‡lАQЬŽ>›o/я ХAшвЧICѕђщ;џнљќˆѓ$ЙYT8њbТ"УъжѕoШ-ѓя4Р)ѕНT„%Ѕ%ўяјѓBНgy-еV›ы1XвОПZ­ЦРI 6ТаHvШgЎOс•BЖтНџ 2Х  D€4iЇО9ПsУ6езЧGЕ"v5ЋЋ_PрЌižy9йЊƒй§zіZ›šЬєЗnИєУOћwю:єyіЭп„‘hь9>Х,кЕw?fw–XАmїО/ІИИZД“glћшќхK№ :œm)—ЅЄІT™hўŠŠ}т№љя/эмО­рДА@ЙЄŸЁЪЁЮ_РQ\rТзFГ фЬљ аCiЈQ8D[г!€‘ƒ]Лtэўlwьј@B§†- ыџ|мИїщгЇKї.bƒч_xоkšц -ж›"q‹ьщІя§l/C8q9b$wоЁC‡юЖн1‚aЄГVПhс"ЇaNЪQЪ6экxОщщљš'ЫђŠЫ+XЬЪ%‹—ь§d/”M1nрa;og}-ы{уnI D ˆ\ˆсАHНЗчд‹пk^Eћ‹т“в’тcуmа2ƒEŸD€˜‘@ХУjяІзС3њX.„їhрŽЄфЄ‹…я§Q9д ъ'эZЩ5ыЊспЦЫВЕUєяћLЮQеXgeЮбœ/ АЎ|Ф{ыњ5—W=ДyЋГ|ћѕюхю9mќdї.]4#б|fњNѕђ–ќ˜ю9/ЉЯšЁ ?^3Мэ_ЖŸр‡78–F„8pцЮk%ђЃфxЋфкXgaЎЙБcЦAVR2Я†UЋr٘4sЮ‰џFC‹GA l$чoРMЖјBЮ“nпОЭfР9VžФтOр§Э’›6•Ћœ ‰юUŽЪЖ—-dL`ŠU(Б гG,‰puuЕ-ЄТУ›Ž+~Tь“Y2cq=Х6еЪUєTедG§“ZёŒBœ‹yыYнFщЌќЙшg^ѕ70JєIˆ D vјЊЇТb˜џбцхATEПскŒK>Ж;ќZќ+ГЫм“ље‘Џ0еtПчћ>dpЕUБ+^@бEЖO ˆ‘ЭPЙEъ"Ф Џ!':6E7ЋЭЮNqƒьtˆ"@Z=џ‘ёќxяЏЖ8O+а§€{zО1ˆі|Кkkc nŸЗ|jхVёЌB§‹кxCх*lшf`y 9бБQtQhЪЊDAqƒqђt”"@Z5ЇNЉяЅ"t()-ёЧПЖ,0бОПZ­Ц€ФТK…Щ<јЬѕ)МR%Ж{џ­\^&{ъЉЇјEнHAО3}чП;ПфF т d–:y •ы=Ы;hiž\`Z$YŠЗ—7q$™CAqƒ$4R"@ˆЄ˜ОїГНОр8Фqфˆ‘Е…Вhс"ЇaNЪQЪ6экxОщщљšfэДW\^qŸьх’ХKі~В—Й Yв@<б0^JиВАўЯїGEŸ>}Кtз,лІ“зPЙсЁс:tшnл#-F:K7ƒ7Лvщк§йюи!№Бœ ‹4ўэаQ"@  q‘бацI@r\dѓlJжšњ.Й&D€"аТPмаТОPj D€$@qCТ%зD€"@ZŠZиJЭ!D€"а€(nh@Ифš"@ˆ@ #аBт†к.][ћі­Ssˆ D€д@ѓŽшђ_Зor"@ˆ@S pьј1ЌKYу„ fЏj}J4sм V…E„:я8мaКЯьcЧUfo­иЁxMmБžd"@ˆ MŸ@Hh&}ТдЈj}ЎхйRsЦ Ѕ7JќцНхфрДїЎМЃљ+-;xш`c6†Ъ"D€"аŒ\8waјасЌТ,zhњ•7gмМ!}ю\Ww7a‰А'd}ћѕ^ЅA№Pян-ЮE;Ф4H&D€F#pїю]й“Všy 2gмp"яФи‘у$ы•њAЪяПяџ<{ёoХHrГSљЇЖmHW>>q‚‹Oр‚Ѓ'rгзЇЋО>>qьЈq+Ийљќѓћ?й••љћoЗS7nрz!cлGч/_кПs—ъpЖЅ\–’Њ)Yйс%ъфЂ$ D€I‡`? E›žН{flЯ`6xІ–’†Ё VVVXAŠ-O…CXў* 0РЊЃv|!MI={0OОqч›6oBq(tˆг‚‚І‡?”ˆrQ:r1НјЪДїг„М•Gult’,clt,kжмЊИ[С”’­f‡Ь7мПUжОS{qИ| ;+daњ!А-_r ћ?Дdqˆu' љд)Sя§qOœМј­ŒyvО<РГы;ОиˆjРaРМРЌ#šEЭ‘…{@ФЙh„˜ЩD€" &0н{zTLдЃЛђTyијЁмЃЙWОПr]}НјfqDtгЧDХ_+ОўуuьWОГ*Цˆž=˜аY_›йч~›w2Џќrз<ќќ§И“лЗoЃD”›{<—)ѕ?OхњюЬw&>ѕHˆO8™В П ЌЄЌЃUGО„•ЁVЃ8sіXvъŒe7%C‡k%eжнlXѓ м*ЙЦ›ŠH‚ЩИвC'яU.0ЪsqAœ)љч­ыз\^ѕрIоОk%зФа•ј# Š-ŒrЂƒD€K mлЖ%зKАˆЖM7›”4M6Z›И.‘]я (Ч*ЃWFCљQЦGЊЃ*І_џЯѕJчє†ЈЅН—ЦЎ† оYА8|13œг8O\“Иw—fM'$/Ф:f,™’žЂЪQЁiHЦDЧ`‘Ьј„xШ†ZCцьoъ84'7›UEчГ‡MgŒšdJl:ы䘍žН‡!ћN6=ŽgСe^ГŸЮg–=lzˆ=ЪЎЃч~tє”$D€VB sOцWGОТЂе§žяwјІmЗэeЫи>m[є‹f4^‘КЈšўf zC EЗаВџhЌчЖкB хЕБжмЅ2ыQsХ3 <ПРжЁs‡_‹eG ЕGЭ7њњmкД1++Гтю ],МRˆw2Y \ЦЙЦ%ХнЉмV&Х!)ЎЗ)r\J2Ы?.] e™1Э#jѕJ"`X%†FVU`Диƒ8;яT+I&D€"ˆі|КЇДД >oљp&ъŸдLVџЂVtQ0YaЋЈ•ž{3EœЋЕ…š’Eі?Т f‰kЈ~ХгŠ›%7љГўtУPЋсСœqЄ№anоЉё“нжФ­~eќ+Ќ– цљvќ{зq“нАw§{W$ѕko\cџr?ї7ІsuыиЁУƒйНfxлПl?3Рod,qс\U€ŽVrd‡{'уeбQ"@ˆ Œ€Я\мГ‘їў{c Z„Gѓи!xЯђfzo/я ХUњХAHзsoІ№К,”jJЇNЉяЅ"tРsџwќѕГ`PЇџ|!y +МTˆЁ‘ЬЦPЋ…~‰›Eš^˜\*3~LIU8ЃS€ёЃ:ЦцMЂK€F˜)y#ѕ'№ъ_yђ@є ьйЛћЙОЯqЉж#ОчГ=‘—Џ\ЖяoŸќЯфс#†##ЎžИЏ\НУљ=gxb8‚……єИB/ZМху-gOŸН.qq=ќ№[|.sе'сзў;vЖ§[лрХK?Њ&Œoм˜)ё.†п[~ЇЮBПBDhЂVœи,!)])x`aџ’}Tx”ЋЛа|ЩVCŒ7ˆ“Lˆ@-PмP XdкHЦ ’_w% Z‰.w7їK—/5tAњўЭљœBп;iˆ D€sˆ‹Р0ЮшїЂт4KI1WмIШ’I#…ЂVЈjˆњ ЖЬRчЫ[XuДТIf€ВPCЁТ•UТ’тŒЃЧЦZ\SrЃЄйФ |Еk.№fjkoм%D€жF їhю•яЏ\W_/ОYСšŸŸp2џdA~AYIYGЋŽс‘кйOхњюЬwќбCю‘мЃџ:ZўGљŒ7gŒœ0ђрЁƒGГ…ЄЧ4љўѓХ0Y|rGyВЁBQ+д 5D=Q[БO.ЧDХ_+ОўуuьWОГ*†Ъ§:7яdžPЅз<ќќ§ИТŠАЋЂWqMLlLѓXз 5цKbr7УИP[{уош( œ­kХQа2HЎk…лёЂЋEЖНlбFѕOjхXхЯ?ќ 7шЊгcmы>/і)НQ =ьo–мДБЖЬ’ЗoпnпО=dмтЫхђjЩПЩйš–ШХb.TцМ1=K*ѓOЋŽj*ƒJ*žQˆsiђVЗQ:+.њ‡P„ё* Q z7hЪkSXѓЭйпPЗ;ћКхbш“"@ˆ@C`СJБ}кыMГт рђŒ‹.Ж;ќZќ+Џ˜† йšке’џс™L ZЄжD6№‚JJњвБ)КЉiŒW)*, +‰У,*&*bI„9уЩŠ’’"@ˆ@Г&€ћlVѕ/jE“O+аЏ€лzО5B ЊАUˆ+)YоIcБrЬј1–––Ы#Nœ81wЮм‰а…••9Сc’у`‡щГfЋвŒћ8›fК—'”8T‹u6р“ї:”––,Zъ8Jщ8\щ„CХЕз‘7Іop7–a+Ѓ**Ъ5GЪbтЂ tž8>угнт,МБ’d"@ˆ F- Т“ьМgy3KŒCєŸяЏVЋ1&У14вˆг=ѕдS<@.ЄЁBQ+m%IчэхДИЊ!‹ƒ”4“TF…ЃЏ!&,2LіЄЌAт”zъ›ѓ;7lS}}|дШQ+bWГz‡FЬŸїvо‰ќmыгПНxJЖ@6>љJй~AГІyцхdЋfїыйkmjВd ЬиібљЫ—іямЅ:œm)—ЅЄІ0Ыд~џэvvVцўOvЪ?e(;щ‰ D€˜B`фА‘ОанЖЛxѕъE 9 sRŽRЖiзЦѓMOЯзyїініoкхZ4ьuЅŸ7oоьєvvќибvІ-Д–œY˜ЛpЭК5чЮŸSб*!K•бФ :@д|VSЕЇJ>Ыћрћk>ЉQyећЊэIvЋеКvнкякя{ќђьœйЖGlк’ƒ<ЛБЉбљ†SUŒœˆїuњ|Пћь“ьћЋћѕ\%ьu§§мнзЯЊUСхUњшБЃSвІИVЛe1Cі:Ш•ЕмYR@V/д‹ИAy’@@@/рёzRІјіх•ђXŠчЗРƒЦŽэ{ЖГ„–ПД"џV”TИЫмr,‹юMn™НыOЕž’[;ЫЦ–І–аJaЏыяч_@Hyщgh-9#Kм%~Иаеее|ЊЙЇЇ'џе|­d„,) Л2еkHŸkvœD@`и ЄІЄЪ‚:xёІNH`WчП8tщhїлюГgЯ>t8L­QљО@‹'дч~)&CнчўНВбСљšѓšчZ˜К!Їќ§єzЕаAњ’Џ?!OšмГkэQ›>Уb‰%…Yoу  €}……6nИѕЧ-yKBNSQ*k •%e%a>э˜с8Ая€„ђ•„l;PЭ:_w^щИ"?|зПяЈѓ‘вБ­omэыч– a ЫnЭ_œ2’+[5KЫJчхЬгJFШв5Eм с@€€ќq8abђуЩђ–„ђЪx*Ѓ`yA肇>ЛЇЋЇЁЖA+!Kзаƒ=зJW™CˆqY‰ѕyџE4Ц•ўH8wў{ЧѓТќМ‘вс‡вЯип џ@<”.rQ@†@р™Ќgх*_Е4СЕFю% nрSХШfzŽ 0 Дшa …cГ ћbsо5 €б7DЃF@bS€И!6чQ#€ qC4jдA@ 6ˆbsо5 €б7DЃF@bS€И!6чQ#€ €ўў aНMУдA@г мwŸiћНGpšn˜ @ ИoН;B J €˜W€§ ц[F† €€бФ F‹в €ц n0ям22@Œ n0Z”і@0Џqƒyч–‘!€ `ДqƒбЂД‡ €€yˆЬ;ЗŒ @ЃˆŒЅ=@Ь+@м`оЙed €-@м`Д(э!€ `^тѓЮ-#C@РhтЃEi@ѓ 7˜wn €F 7-J{ €˜W€ИСМsЫШ@0Z€ИСhQкC@РМФ ц[F† €€бџў/ьь)‹ДIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/22.png0000644000175000017500000015114311733011756026235 0ustar sylvestresylvestre‰PNG  IHDR™Mѕbљ<РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь XTеКјwWюУѕGДGЌы#u2:v–… )Шё"ЉЧуQLMHMИ\-$ПШв“Ы3ТRЪЮ1?Ž кБ0Љœ0ШLN'ƒkъxT˜sK†чСчўп=kfЭbіZ{і|С|М#ЯјюwНы]яћ[{цНіžйw]kl”$)va><у $€№ ЇпЬЂq…|јм\ЊB $€№rБ Wбr~WФИt(фЭ-/УCH $€(ЋЇіоњЧЄœЫЧхђЃЭHўЧg$€@HРЗ˜kЙбицоИ›Џ]”ZєRЛ#‚tR№А>К7є†@о@РѕКр \'щzЪ,Чхэ-Ъ6Ї5ЭзuARиSc$]ЈNŒ†ц‹gš/ж'Т^hА@^OРѕКр \Чьzмh-чЖЪЪжs{К*§r”чћ:}ЉEзмgDkeŽєЏRؘ<~ЗŸ aO%KК`~ЋHЋ {4цъ_Iэ" д#$€€opН.xƒзйЛž/K-чЕйъ‚t=zєаi\5wД“СФЧёŸЌŽ“QыOкFхТЖŠO•&ДгЕKЕ“$urT<œнєб ЗpН.xƒзqИžУйњ:иВдrЫџŒ[с@yюb{z\Лa4^ЛаZ{Ф(Ÿз…ˆzI!ДЗ#B+ƒO‘[Izь§7Цp—Ÿ,7•ќ”|Ÿ*M*1Иид%ƒкй-Q)gGЉ!‘Иe8ЛIЁ@GРѕКр \чхzcˆ:тВI­L‚ =ю‘tнu}Кѕ1Pд[Є+К_R“NFm<љє==р4|P[sЛећЧtvJ>p ЃШЇJыСНr— j77FЅœVуаDл  @ўMРј“|щК§Zr_Ф€“’у"‚ƒƒ›š}јбЦЏC› *ЧЧ:.Л}Яuш2ѕН™щhžпзt—ZАКƒ9вЗ­]:yAПёЃX< њЂ%SЁЊБ™1T? ?KgПзo‚O$Є žзgЄР3ы‡6QjјВбЬјсгGєыlh“ЖоpєK™М()и)”Q™МvxRЩы™FHgGЉLJЮDCS‡ЄxA’W ЌCИ@ЇрМЗл-  S8Дd тС&ж[ЁЌ‰sВm$v8№ЋTЊЧ@kˆ­w6FуO†ЦІЦˆ‡"іьнѓјуБ-†–љђ4(Ь‚^р•:fu”{Hз[‚zwа[ЙЃР­<ЉКKэцkуOžk:|Вс™ИШбOє3ўмVpB?jуйO–Ыeouб.ЃЄ{LЇ# ђЁнƒГо­— њЧ O…sЭС&:юйs ‡џвјє@ъ‡6™„р™OGЮŸrп­Ÿ8Ипќ‘PЙwќE­Ћ&F…v—Ж:ћC“сС№ащƒ#Пќ{ нбƒ$ `Q\ПбQсЧkš>Ў–‰{BўРaќйxіo†С„ŽŒўмЈ)ЊПЄПП]п,…‹\‘Я^hкsЂс—Ёѓ“ЏJŠœљЦцЗ1с‹GѕЋПdШ:x>ё<ѓtdu4.F˜7*“Шлšš(ї™O".хь(5є ;бмЄцtчš>6энc:xFс3@]C@Qі=лсшЂ‚6ѕ]љ­ЕУƒж…‡f*NyшPЁЈ•Q46 В`sЇdДЧ№/ZFзIЦЁ=ТУУ|ј—>іhDD„d4Zпд5И€Шр&)ѕzњЗ§Й(БВI –А ѓ!ѕ™/сАЕх№™аЧE…пдсЇыšлu­,ШЫЦлN4]еы›вЇuђёtЬ/Т Вю.U_жяE~Р~ТђwІКО.шKљC@r4 '{&W0„С ЉіG}сСГПшиРCИ(йѓщК:№L0™KUѕrx‰Qa’1>Rўьђе7 :8 EЎЬЋЯHwZЊП—Л‡†џB'3™-D8|т,|Jhn3–Јы!ЕЉ$%ŠŠ AŸEЙЋxІ}йй!J ;бUМЄ’ К3а‘^ЂРшш( $р=hE !ѕhПоЩБбXЁ3c _HAЄeтб†|,?,џ“-лч;-zНЎwяо1OЦ\lИЈз› ЁJ— ўљl˜$лq(ЯЌRўРl'ЫИ-?ЏЖїi6ЪcСбъ§К–fЃѕыь-R(”hzђсаДсђ2ИЅ#,ˆ‡щŒW-Ыьъ~ ˜p“зŸMБ˜†ƒлO5-ж/%I^ акЖЊЏ§О[o4š†&іOF€czx@‰Н*ѕh6XЁU7ъ ?GŒ ППWур‡BaaџтїzHчЁ‡{lnZвWЯХr=д6.”ФoќЙЅF‘‚!6ˆP%)QT6ѓ"Ъ]Х3ЯtvT4t8ѓuLЪd›-:ш% Œ:. H tE]€F*7дZР8СРлЉ cЎЪžeaВuC=и68ОЭЫPp y‡РTc€FћћEDF’пo‘алŒmКюС—~–ŒАь |pл;,вZКВJыilKЋ№џнuFCpHї`еjbˆхэKЭІe№њo›uнtљ/Œ†VXi слѕЃ7Шхќѕwі]ƒ”M‹Ь=рxџtFџэљ†'ю“"њ…•>:|ц[65C%8Бѕш.бDhфАЄgшŸџu$ЇКЏa9>z„ЏJ"KњТ\ ЛЊ5Г"ШуяЊ3о” ЙlгЎSIJ%*ЂмU<Гн’•IЉ) ЬЁб А­ -AђЊсОgЭ‡aЉяР:+[Hl]Аѕ -HuЪ‰WVЯzа6Іš'‹Љяl8ДйœƒP‹Aг{‹ОБсћ†Жі68_хзєзЎн„пgўь+'LЕЌи6іОёO„ŸЏ™#ŸqЏЛаH:Т%l№€VЇфуЪ(фcу"­z‹Фѕci”џпwN^WOŒ‹1vы!uг§В_јь‰cр(Ъфk“"u=ТOшЅгMцЋЬSЎБ‹8vA^сˆa‘Ч3=vзЩ MQШsYWзхYžFБ+S'ўгОгy„С№Љ‹~mzёˆ“R‰Š@”Л .хь(5ь*rЙщ4A7їщW]ˆSё†MH xš€нїvS!— т2зЛФ)ИЭƒx­-Ђ,h!GлŸ‹TсР‰n“UйCЇ яЇЫхѓх m §ъќEœ–—У/Ћ;§амw№‘Лžˆ„рЖђL]‹щ`tзЉІ”a§^|vŒ?*џ,<чjxilФтпЪп;ч>И~XK8Ю •ŒpЙш…бP{ъўЧ№ž\uPЮзыгњEіŽћ†+m'П8Ѓ“рŒОyyŸ8Q `лЩынЅИ_СUoЖ2Ўо4‚УШ‚›ЎЎЎСй„жvŠ+6`љO_šтО§љСp8Л§ѓ&ИЖрOg$QR*QБžEЙЋрRЮŽRУЁ"яЈnŠmуЂFЮЙЈјФ&$€гwДVЩпO#Ќ№йсjЛ\AaОЌмC’/&‡йoŒђЉИвэў Г,aј{т“ы‡fаъ\I'їl—ZeчСd88OЏko“—їл%X'ЅђdАJpъњ1љBЉ‰MИ…?Ѕ[чМQlmш&R Чмеђ–|хyG‡*ЎlЖйфЦЯU’0TЂЂqкУ„*ђ њKЬEўрJЉa#ge0f7Пj2Оў;ИА1XџГtќœўГ3№нBѓМЋFƒG /!рtipК#Mмuд•г§(C•нЊеrЩи(§НЙeя љЫŸŒь;EўvгћuЋБU?чкккоllљ*ьОЧ;ŽзЁ”ВMlЌЌо,ЫсћRћQѕOЫыэјdGПЙ^ла&™O)щфЕ“`гКK SСм‘€зP{oW+ жКРё ж‘’pЇъдiAkЖЉYГр -7 A}šoŒ6B-Пжжc\u{šЖі5я3JAњЋзj[/У­ж—|]qПТl9&ЊFD]]КгqН6 H`=УЫPmђx;ryэ$`ЎHРwИ^МСƒыМ]Я‚ƒЅrZўgmBю —юyОyEЭфП{фџ@"%†ђY>#kд‰ЏИSі љgв!^06]рЧUdK›ŽИщOЬ+љ$%мќij1џ#рz]№ЎЯ‹ыY№b0ПџщфЏчЛяЁ onl ‹шчP9‡ђпќcSˆИнŒћвBOH $р$зы‚7xp2yІ›ыY0ЮЈш‘cн=Ёp;–+wрЗdI@!КPшKƒC $€ќƒ€ыuС<И>ЎgСС#ЕF‚pс;$*‘@H И^МСƒычzЪ:дђцjПЃьŒ$€@H “ „н'џ7ћАжr(фцлў’(kŠ2@H $ах&Пн`SЮџЅЫcТ@H W`-w…іEH $аѕА–w§`H $€\!€Емzи $€@зРZоѕs€ $€p…жrWшa_$€@]OkyзЯF€@HРXЫ]Ё‡}‘@H t=Ќх]?@H W`-w…іEH $аѕЌПскѕБ`H јГ5g}!RkŒƒЃcЌл(!џ"€ЕмПцГA&@ љ˜б‰ЧЭюЏXЮнŒнy Ќх^3№pD…<4дЧюhќhфЃ.b-ї…] ct†€3ЕмWиœaУє:Ÿ[TdТз$BŽš@И`„ ]€з]їэплУ82.ў;B m…ЎхPШѕ7єЉ/ЄЫ.л~Mzc‡Fгж*ыЧодЈъ,кЌ.ˆd”м:ѕІzŸZЪœјэфлާdi$–Œ™r";7SЯжЁ‡ˆ<овЪЩBВшDaпƒ8`вЗЃ?л(Aъ€ЕˆudI“*:–V6+CKЋВ‹i1m‰BmЇ47\ЯаnвГјњ8˜Œ;Fb2ч:яшЙъј.&_uнu)sRmїэИ:Д*^эь[#}ЄАЯ4ќ­!ђМпД/эK^ЋУЕOSžK59яігы&01щuЪЦ`ЅЊƒFбEЁш`.9Н,XuRr&eqОœ@U“Uи+LІЮЅщdŽЬИDQюФШв*LC•;Рƒ@Эі4ЩЮБRИ1+œdhЁaыЖ›ФIC•ŒТ^Ё`ЦpoюŒc/P˜эОqйЬ…Э(р3|б@ с~§RvНП kЙ…ўя$gО“І тьЕNŽн@LРицдqQУдЙ>.7{­ rщ\х#П|фoпўЭ§czAЪ45*И9ЭNЩбSСkcсёб;…ЁЖ\}л**:КОІЦЭ9рьИ(Кыzgыы gŽЫЛ>v^№ЭSЃ Шjї№’dл~6o-7eRьш„ФБ/._qЖV~гбјА[ШЁиktхеfмkМ:b ЮЛФ  Ю—УЂ§uЁІІІТЂТSЇўккzѓпšЗpб˜„8Я1јлЗѕLTіУs<M>љe”)Чм;⋆AЧЦRЕжфЂ%NzѕМ{иАб9Ћ–9ў %M)CmњОiСЂ~ќ!кЈcїќюAб”š#3N=k:&ЋЕ—лэ–ЎYёPпћЫЖ•єюn0ъjПкљЮЖСEлм>#5Э8ЄDї4{{Уї …љ…ŸџЕІчН=—.YœэХ%ФУŸyШ;Rё›EћUHRkњќŒЉП›z8Ю~eyіляОYЙў‹КЦBvVціВ]­џлšwaŽ0ЙY/ч|~ъs˜-XСD[Г€~m.фssMБ@Чъ/Њccc­kн=]1šЛކ$E‰ћ˜r'„ˆАSŠ~b№Кз6е_hюи oпYzсЛK‡vяљј@хЕзш Е__и§nrЊ!BmMэЁ?юЉЌ(oОбRМН”Є~УГжBnубёMКЗЗ§м{&Ц…gY0EВр?Ь9їєŸOWЏ№рC›6oЂ>m„.Ю‘pЃp$‰Ћ2б$ ‘Ќoi†љ…Y†ЙЖТ7J=§yЬ Й;”Ф@Ÿ!mЛ‡УЃг!TQTЪ.5( ж3‚ЛЇ-Ь€7Ў(Л6GШ"џПђ‡ЧЇсБ`U&šи‹ X=Ь5u^Ёў‘џLˆ–Uи?jІqї`GaїCVЯŽN§{N`‡жk/ •ЛjщшzšPЇSЄ§aзюг'ЋJŠ [~2.]Е‚И…Uєо„+‡€ъЎT‚†ƒpK™kуi%ЛЗOŸ6§§=яЫхэШгџ,ˆ7oнќск| ŸТCt!ы^[gВР'$рqN/‡ЈкэЌ …єьeИuћЪ”_ЦНC‰фWІХ[hw‘ƒMПиРnо†—ХLдсж—“žIВ"„\-BCЭY[еЅv#эЋn(ЗZF †Ђc’!сцM%яь„ЃА{C–f­ˆbЙw“Ѕ8€eЩ‚Т‚ѓ чсь‰œ:'BWхHNOєњpэл№œ—ГiT,X•‰&і"Yящ& ђ\УУ$ŸўЫgO~’ŽeЛИjЈqїptt9 ЛЇіъебD d‡мP­#Ц­BП~Yџ™?кќБЏoxпыWєДBлŠƒа3МЏ]{ОCГ., •{{ПТћХ/Ž}zlLB<>9љеі~0ЌУp€“ЕмN%—ЄaБУЪOTN›"_вbѓшоЋщŠ>мєЉ\/П2{QoT ]D›ЛїЅf6МцЫw”БŸ'l lSй„—эЋbfЖMВёHф†РђLЭ™е9Ћ?>њБM/и\іђВЅK–Ц Ž_„Ÿ’>l8ue#tUŽ5ПјkЩШюD‹ d§u}xoљИ іx&ўџ\§—%™KИc‘ЩГЦнУббй!DВsћ ѕцhH"PрPD‰шU:в`\g,š1хї=kpзoщп}oЯП?1˜ИђLвкќМ Ћ_б—ю,e—йЙуцЪ%)Џ /iМљ:\XоtЅБпм.JЅCГн)Cюо>щw3vlпŸџЧнX’НœУК-Ыф"ъDYзK лА h%рдЛ†Ћ.Є-xџээхх†Ÿ №ЫиpћŠецхЕQ‰р V№6ЕkБƒЏК™z ™ЖЅбњџ”щSжn\KŠAуЅЦukНbН Тhlj”-\^i0G яJWЌ7„nmm…_ядщtњыњMЏmВІЄМ3GІн‰€ОАР2ХE…Ф›ёgу•яџ>№Б Ж Л‡CЃлŽс™mGCт‚вšгЕ8Ї6 Ÿ[t№“&N›5$zЮМ№ћЉЙЏ‘ждЙiњ?4qЦєБ“'іщг‡v ƒž0ёїг'$‡ѕш‘žšfv2'mZЪlrAЛЈЃчє1б1Э?5—* ‹|ШќkъПєлЂт"иWся­џ*=bДч@ЯH€%рфqЙнW„‡‡n}Ћф­’тџЮomН§0|П*~”дn-6Њq[іЫ IDAT^”ЃЋšwltyєŽюЬ[ЂDzЎVщtGж‰яЩž™W8hиЁ]q}…€sЕмю=‹ЏKіў.дГоН'G8‡ 'S[л[сŒуГsŸ…Ррї ^-jБQЄоAЁНCГъ†ыЃsн‹BщЙNXЅгY'#Г‹э.ŽшЁйq1*ьŽ\'р\-w}\ч=а_sоієzЩ“’сЯ‰0нВ{8=Кkь" IЄЗыжщŽv=Ѓc№dЙcМаšOРЉZ;_ эr фШИO‹ нЧв§žМvv 0| з8ѕ4з†ФоH ј(ђƒх№}qŸ‹?*jрЃF@ќ>9ŒДpцИю]ЁХЕ?йшtвБќќ] rєє>щї Sfйљы„Ућѕ'њІ&з]йx-џЦЂОkПЎжэЗ 7”|V&;ЊЃљ;VЫЯжœр)ŽƒіH юКыЎџћПџѓP9|фQatšОЃvjяшиёJв‰rюX-ollьфЏ–z?zŒ З№\9їХnЧ‹Н–РЃ‘^lИшP-?[[w№OЛЋх^›?†€Ÿ№\9ї3P˜N€x.э9 €зОјn€щ#я%хœœ>їо12$рzѕь…Ем цC@H@@ЫЙ Њ‘€•Рњ+Б–[q „€Рrю…“‚!y˜Ё1XЫНjF0$€8Аœs   0А–30PDHР[ `9їж™СИКžР™ъ3x{зOF€€ јЎЙJ+6!$АzУЋXЫq7@HР @ ‡cq™'~7Цs֘€SnоКpkьQqёР Ÿ}—€SЛ:vђ1фwпШ9ЎЎћифaИKр7пxf\т]ув‡ЯЭmжы›o4˜ЉУО§{}њwп €еŸЌRЯ[‘шBьяБƒLЭIiяТЈph$а9ъыырwпІNБsуƒЩo7„нзяjMљ­ќpњЭ,ˆ-АŽЫБwЮюшЁQШZ‚‡œЃ[/!ЫщtE<4ї’yС0Мœ@`еr,^О;Њ‡‡Хдљ`+@K Аj9ŸобёЃ˜OOŸsС“Cs\cwŽі >{У…†КoОRŸА=9@ОРгчЫЃЂЃыkjдƒqКUф\Єwz ;кЧЎ(ќ(&"упzКфюпibvHР>_ЫЁ/^ђЂ:‚­Џ“Zо%ХРщвЅžTЖzњЃX"Х”‘№ўВЦо.eegСŸдnš›MЫ\Б‹ДPb-jЯўoїHНг"ёlžžїо%Х<ŸŽ€p•€Я—Ы rЏЬ*лQF`фПšoГI!a1 (|QРуr_œ5Œ N р/ЧхTPбŸљ4­ыЕљіИмІЩМyGЪЭЫO HwЬъызѕ/._;2>6.~qжRƒСРиЏeТјБЛ>иЫѕIЛAиѕС{` іЙyыˆsв ЯдL8–$)ЛлŒИНЄ4!QіПrэКЖ6#i=[sffЪŒи!буІLЊЈ(Зщ›0tХЁrh‹Kј‚уБŽMўн$ш2sюМІKц.8ЄЃ„@3"нm6‰вЁ€ёЃ˜y"№?$€@G~RЫсX|ЮМ9$ЕяО§Ž =›ЏнbPќfQѓЋ‡”УпеWa“t_А4sюєЇUV}T9рС‡6}ёівц-•х‡ўИЇКІš‹+зжд‚%иC/ш 6džщRМh,0VvgGйUі^эЗэоSuМ2D'›ƒЯZБzбТNŸЊ)лVrюќЗl*C№eЅ%UЧ??.)53§гS'JЖ•T}іљј1#зф­!f"8ŽB ƒ:А§bд5 H @"р'ЕІ,w]nџ_іЇs2hш&ьƒ#•йKВCMW–dЉќ„t<Аkwд R7]pw]ZjкЉЯN§‘ЃGX{›с”›дшЋ4h,hRяўўс§йY™Ё=Cƒƒu 3+>9Nќ‡„„шoТR‚Ёwя№UpIяБьЅьо=УЁуДЉгnџѓ6Лyў\=щ!‚у(:ОЃл§(F=Ѓ€(ўpОМэNЬйЊœUєˆ6AM9З[ .ыoі~ œь мв_&r§…†‚Т‚ѓ чЁЮЩ ЖЫњЫЌ=1VyfЉs{бX`Іо§ж—“ž™bѕf ВpѓІ’wvo-Л7diжŠИ!1V‹Ÿ^ˆхvѓ6ЙœP’Dp…`Sr4`<_NбЁ€` XояYЪPЖщ9r8"'EhиrnЗє яu§Šž”Lz†ї"0–НМlщ’ЅёƒcрИЮCGNє}УћВіvЩБЦ=УћrэEcБzwpXЙЃ ŽЫmмF>љњЦ  „ч99Ћ?<њБЦM„Лƒ$`E>XЏ0`s4`ЛХп("$€ˆ€ПЌБ[ŽчЬžsтУ№lžC‹žlк-I‰ђ ђфѕhƒamAl’Ž­­­:ЌгС…iы^лDwЄФQyE…&stЄz‘Р'O"fНzонtХr}™$‰Цcnw:жЌщSжm\ ѕ4pС\ўFš@hjj”/Еk—Z;Ё}Е"8"џ*ъНн{Ёœn6mцРq4`ЛЇHДd6H џ#р'Чхєр[‚фsчdЊЈ@6mŽЫmЎЌ†ЋЯвІхn.Jœœ іЩc“a“t\ŸГrKў–~\ Ч ѓŸ›uИќ0бЇ/ЬШ}m]т„ф{CRчЄVžЈ"zбѓ 'Lќ§єжџmMўЭшєTГѓд9iгRfУъ=ЙќM4јфvЇcЅЬš ђœŒАv§pџўѓR_ M #†ffe_iќ”љжS{G„5+—ЏYЛБt[aЯыЛјйљ‡?ЌДбб€э~Гё›H !рѓї<…лАІ>ŸЎ>[лп*Ж{ 9uni…єbuЗ8 4'6Х-}Ь П'рє=O}ўИ~kJЕњƒ 1Рb ЪЫ[ёИмЫ'УCH Ћј|-‡Z'ПЕЎ… -”Мж?Šyэд``H tXœ†Ё§хк7mЁh3єˆ.АЛˆ?ŠЙЛ#$р|ўЋ–c1№щ§Иk?Šљ4:  %pКю+јѓљ5v‡ІiТхmЦјQЬлfуAH Ы Мє/A w\NŽэ№йw tљ+@H xcЛў|ў;iо#AH $р 'О“іехпS ЌуrWc_$€@оIkЙwЮ F…@H@+РКіM+ДCH $рр^ИЦю3…A"$€P!€kь*pА $€€РZю“„!"$€P!€Е\6!$€№j/.бh4`-їъIТр@H Ј йќzжrDи„@HРЋ dќgFХЧј4Џž$  $€€ сУ†KA№H $€€oЈџКЧZю›Г‡Q#$€ЄІ†І’%xОї$€@ОJрх™ Ѓ№ИмWчуFH $№‡н—уž€@HРЗ рqЙoЯF@M  вЧZићf@>M ]ŽkЙOЯ!@M@>*ЧѓхН `ђH $р№к7ϘFL $€˜ЎБ№фcъH $руŒ?!Ќх>>>@H 0НїBіXЫxРд‘@HРЧ L›4 2РZюугˆс#$€@ˆ йуЕoМ `ъH $р)%рСZ^PXАbљŠњš:˜w nyaИХ‰wђё‰Ј<ФпCnCъUС8—‚J/џЮN%ё.or#y7Къr,>€ћk9Юѓџ78Цћ‰Ихг†v'”ї“бЁ7dd—ПsAкuЋ‘[Ьh0Юхт–мшФ& š+CŸ6žеЊtqШrЛ+zHCЩЛ0u% еѕ!DžQяўZN™оnН-uЃ[( $€@!рЉZN>С3чƒи)7o]l\|ТјБЛ>ПGлKJЧBгЪЕыккфяП“ЧЎоcаCGщŽYiуйКyטћ*ѕџž]=5ЁЂЂ|м”IБCЂgЮзtЉС<’ШЁЙYў:9[sffЪ №~Рcb5cjObI7AиЗЏ|ССљ‚ифЧ&I|hbШжd›ќ„‘ё№ V4–ЕЏE"У3ˆZдЊХќЯЇwG*оZ;FBbќ>ЫУй№!n@Џм[Hl№Lf@iђ”IMMDsьЃcD шAVкГ}Љ fм`ˆu‚ˆ Бд ёЯд-єUw |АтŽvgŠмсYМ;i™k:b?vгьOЧЭЏчWXцZ@MG“[к9_ПЎqљŠи‘ё№Е8kЉС`Gмюth­8dzЋ‰‹†З ИДіНЩПЃя<ц’ы™:Ёсo №ћQrgM4ѕд 4 “MкJP*'‘иsї|АWNё ЯDА6mтoћйЏњ6гЁcY3оЌБ1&р™ЦѓмТEЧ>5ПЂЁ`ŽГє%Ц~іьЉZN[рYЙъRМНДљFKeEљЁ?юЉЎЉІ@w•НWћэ…CЛїTЏ бIEХEДЉЖІŒЁ t„юTЯŠп,mўЩHќзžЛ@mDzjBѕ_kw—–U}іљШ_\ѓъFвЄЅ#u’ЕbѕЂ…/œ>USЖ­фмљoЉž*Xl,aГіы Лп-ЋџТ|С764dv”т7‹šo\=t ўЎоИ ›Д•;menFмюЂPYo\zлw–^јюьЈМvуЕЗсcе+іnФ~XќАКк: З Ћ6­'Ÿ Яджž:д"ˆ‚БщЫ%CmДУЭEн-јч‚=ЗЃ–™Ђ1SAewRО~ЙYW*~Ибвд…—ў3ыOGўtђг*0;іiШ QщТР‚Ѕ™sЇЯ8}ЌВъЃЪ>ДЉИмrЛГУС[_YiIеёЯЧKJЭLџєд‰’m%№Ю3~ЬШ5ykˆ%з3urі‹3Я/ЮXБ|щд)ђз‹EГ&šzъ‡vVN"щ(кѓ•Ќд‡PЦм=tТиб{+ЌЧ{{žš4!ИЛNiLгЁё,JїЦіЗЉў­яЮš“}ЉЦЯOеrLGŽЩ^’jzМВ$›ZОxvVfhЯар`]ЦТЬŠOŽг&jtЇzЎpЄђ“ь%™ФvF&ЕщЉ9/™˜=cкљЏыI“–ŽдIHHˆў&|47єюО*[эЭ‚v Ы2ф,h+764dъ „#•,LЄI[ЙcбVЛЗЛ(Tж—оўУG^ЩЪ–wŒюКєХдо†егЄДь-ББ#ЊЯеBпђc‡C‚BŽ“?ШзžЋ=uЈEcг—K†к8ŒК[№Я znG-3EcІ‚ЪюфаŒЈјсFKV Vi–ЛIЙЏm(кЧs[ŠЖ€LЮЊuQxсp`зюЈAЅn:и?гRгN}vJбЃXіRvяžс№^7mъДлџМЭnž?g~чQёМяPyЮЦеom-ŠOМ‹fM4ѕœ˜TUЂIэљ\V*#pуŸ>mњћиO{НџЇ§ MЎ11Ѓё ŽŽ г…;.ПЂЏ_бŸњЫ)ђ›*д›Ÿ ]№[1—ѕ—{?N8R6o§x9щ™)VОLhд „[њЫVž$ћяЭё/вГ>р“ й„зиmгMaaSKGъЄpѓІ’wvo-Л7diжŠИ!Ю_§е‹К›š2ы№ВўІ,w,ЖЏКЬэ. •uХЅЧцТл№ЁMЂЄЈ+Ф Иaуа-?’Пn§Ж;&LHўђЫor^ЮaЭьЪЂ`l:rЩPЇƒQw ўЙ`AЯэЈeІhЬTPйš?мhiJЎх’‚ ŸŒЇ<“TXT"4d>%+;Š4мъ/4РwvЮ7œ‡’,wdоИD~@O€З›MњЮЃтљ§wпžђЬдШGф !бЌ‰ІовOыџЂIэљ\V*ƒqуяз/тБШ_Р:ژ„xX0rр“фНkLœГёЬKЗЅр1ЃЧ––ЬnA­ƒO7iлямšbп№О№)‰ь Pп=УћVю(cg‚6Бі`FєwIА"JІ‡œЃ"њОсНрд™rжПHOG u„WзыІкЇЉrrVxєc‘[ЂeЁо‹ЖŠ ‰ гŽ Шy1б3МлъvY*;—› k,’;&eо[DЦАџќЂп§АєЊг… ГmћЖ“_TЦ•—Нгsъ‰`Hт\А"&ZfJйWewrhFTќ(UзNmš.5юџг‘7ўkЫ†ќ-ёqёД8Qч„e//[Кdiќр8.‡wЄшaУѓЃьЅтygiймД9К{zЄќN^`‡‡hжšzтŠћьа$r=Ј+EёЯјнŒmлw@-џую?МœНœ8л ‹лўѕт’в/ыО|u•cŸЮm\yџfЌБ'%ŽЪ+*”—Ё †М‚<Ъhжє)ы6Ў…=4№ЊƒЫпhkŸ4>‰шўUд{ЛїТ‹Юtnкlѕ“”8!Џ афоЉ‘žˆ‡:BиђЕTp^Лдj9Вg=їъywгѓЕ- eСvQ‘EаDYWІМђЈЕyАЩЖrez УЖкdФ6БВ(Tж†KŽЅжцчС,УU0pkЯ•Й{‹JC‡?НЁ`ЫјфёрmќИё6n зГFЅ+sЊ%•\DrСŠŒЕЬ”ВЏЪюфаŒЈјQЊ]o/ЏЮо”Л.nx<ќюХЎxYКcНК–ыG#чжжVN жщрbнk›Ј+нЉНRyK8цrОџOћwНџщ(š5эSЏ0w•1ЋkT†ХKхЦŸšсœBHHXфCцu‘БrєyЉ/””–,ž7пяПTеЕ<}aFи=КФ Щ?}PєPJ?eжьAO š“Б.‡W]Тˆк4ш‰` ]ТzєHOM#њ5+—џљФŸуG Ÿ‘6g(уNYY§џj$‘‡HOG uL143+;vXtAё–ќ ы•>SчЄMK™M‹Ђ( eGЎFM™u’О0-ьОћ''Уп§їн›lЋR†ЋmGVъm2R(TжžK/unк€ўMœ1}ьф‰}њєaэЙ2woQ 2>&NмŒIHocF'‚c>ЩѕoWщЪœj F%Ql\А"c-3ЅьЋВ;94#*~”ƒjзфoо4sЦЌЈЈаЮ|§6y|юfkнхњбШy}ЮЪ-љ[Ђ†EЯI[™RWЛS{Ѕ ђL,хrўVЩўР…` ЭšіЉW˜;‰Ъ˜е5*Cˆт‡0qk7Ў;kuЎbLmˆ  ’њ?мNœйш§oѓЎˆqщУчц6ыѕЭ7šЬЗž}сІ —ћУ›=гУЕё*%"/X’љсўƒ6Q‰є6fЪMЇ;*]љœfqЦЂ…Я-’/ѓёт|HВYYѕт`"4œ?˜fпDјКрoЦўzLТ_™8dКиp‘|7A%цЩo7„нзяjMљ­ќ№УQyЕВ ŽЫUтsWЌФТz,Ќ&EнŠєд@$8нQфаѕ[‹Жyy!їEЊ3@"пqџўОїЁBю ЫД+>МЏ/ЌФТzlk{ышЃa…œ(вS‘рtG‘Cд#$€€чРZBпˆО…Ь žЫ<ћg-‡ ю…How&œюhз3И—.АЛ—ЇыоpF\gих|q}1fW&к?зи]!‚}‘@H јЌхжљ‚5ыJ>EРлцЮлтЩєDHpŽ|Ы{/з |jgФ`‘@РZnКнЗ!;§БйD Ћ0vеИ2э№{g№]mя_ЬФн @vШ@NkЙйЇяS^ѕvро`р‚ИћНO/rXЙм‘рnE`cе8.QŒŽwхїаHРэуђЃё ­FЄlЎч/ў=nАѓПRЬКђЈм%ЛЗ[oћ§ЯiЙzB$рZЮЛл4ѓ o•­с>О№е•л§Ънљ7&оI"'ŸŽщ3h+”7гUЙ_ВвXіУуf3 ЬAf[Й>эоʘЦ?)щ7˜QЇЎў"ќmн…‹ЄѕрЁЁUt+eˆо0˜DХEMCk?ЈЩПы<яD/ёЯд- ЭuK ьЂK-whэЩ&§:Иƒ5ЌpьВмd!Щ3‡;н`ум<Šf‡к*ѓ^Œ$0xЖFhэ яœЪзЏZйžCC” шE№й(ЌБ‰іžvЛŸЈь~жx •:'–d“>гVДчЈьn %$Р#рўZЮНлДк=‰5мЧ"wёvПЪ›щ‚O-7љ&аШЕпʘЄ 7Дm§чݘ'хo ?ўф@щіmа&GйRn‡n>mиE -whэЩЂ}I8ƒМ›В;=ЭŽ(ЄЂ."ь"ЂСОˆžhoщEqRН–Ž"Ђ •<ЪQйF‹P№ѓћ—+Fїш’›ФУAЦ‹ьМ`@E(к[DzЛpœюЈюw0u>иJр§ЫqO№yx“xŸŸТNL@ДЗˆєvCsКЃ]Яh€:€ћЏ}ы„ qП$€7‰їЫiѕPRЂНEЄЗ†гэzF$а А–wdBЎНI<.Аkš$Џ1э-"НнРюhз31РL#(4sŽ€ћЏ}s.ь…@H 8GkЙsмА@H o!€Ем[fу@H $рЌхЮqУ^H $€М…жro™ Œ $€€sА–;Ч {!$€№XЫНe&0$€@ЮРZю7ь…@HР[`-ї–™Р8@H 8GkЙsмА@H o!€Ем[fу@H $рŸџ=і† uп|ЅžќРЧЉnуЙVЛї:ДkрЙиаГ{ рTК—'zCH@#ŸЏхPШ/yQ=л­Џwa-W­ZЛМ!УН IDATРtyйC 7OPEŸHР/ ј|-wnVр]Rйб_odдхyuyЪЙЖЋё†:j—›7i—$ $а ќЂ–З; ŠОKтЛЁУьА@H xМіЭЊ№рC›Š !`ВlЯt§FфM4зlжY+V/ZјТщS5eлJЮџ–4mпYzсЛKА3|| ђкkдž*APю!Ъ Y{”‘(XЫэOїВŒЬааPj—ѓRfhЯар`ньгЮ]OѕT8rєHі’lшW–dS§ћ‡їgg™ћf,ЬЌјф8mЂі @wЊч G*?Щ^’irš‘ImDzj7x-TVа !)шBнr}вVСЎБ(z\Ÿ*іь„иЕ;jа@Љ›.ИЛ.-5эдgЇl&›"oЂЙf„„„шoТПЁwя№UйYЄiџс#ЏdeЫ;Rw]њт jЯЦF• PјZіЖ#ЪH 8_оvЇЭЃSoИЌџрюцM(чЗyЇъ/ы/ї~ œtЁlоњёrв3SЌЎід „[њЫVž$ћяЭё/вГ>ИСkщxYS$з';(+л5ЃBыSХžањ …чЮпўчm9NfRиАEофhysЭі-мМЉфХ[‹Ую YšЕ"nH ДВYc66VЯŽbwa;ЂŒ@ МuBъsМ;H‚иPžAMNšvlw`ЋoxпыWєфЭкГgxпЪeм7kжЬHQH}У{СY^RЮYџ"= @$hщ(л0Iѕ я%ђцЂ^Œ =юˆэ—НМlщ’Ѕёƒcрјv€шaУђ&škжIф#‘Џoм8qž“ГњУЃƒЬvdErGјц=DdŒz$€ЎБ›gќс_EНЗ{/М›n6mЮse?HJ•WT(/Њ yVWГІOYЗq-ЉОM—сђ7: kŸ4>‰шE!%%NШ+(4Й7@GъDЄЇ"AKG“MtmAlŠМЙЈЃB;ЂFћжжVN жщрубКз6QWНzонtЅ‘nŠМ‰цšv&КЉЉQОZА]jЕ,фLy&im~ьlm?с"8жž+sї› ЙQ‰@ РZnžх5+—џљФŸуG Ÿ‘6ghєPWц>}aFи=КФ Щ?}у*eжьAO š“Б.i~yuvТˆ:Ъ '€1t ыб#=5шE!Сi]Ћџ_ €Уwђщщ("AKЧє…iaїнŸ89ўюПя~иysQ/ F…wDіыsVnЩп5,zNк˜ъ*uNкД”йєq‘7б\S? $Œš™•;,К xKў†ѕЄ)unк€ўMœ1}ьф‰}њєaэЙ2wБ ’л•H Л"ЦЅŸ›лЌз7пh:0пЮТfЦŒN„ЋЎМ „”њ|Кz<лп*ž:ešКЖТп‚%™ю?hПHocІмtКЃв•ыЏ Цѕtœі)шѕN;СŽH x?њњК‹ эЌЩo7„нзяjMљ­ќ№УQyaЯrLч§) "„пZ‡R-h4ЋСFнРчZaU6mnšБН­АЈ0iф(ПHO D‚гE]б{U0Ў$‚}‘@CРчk9ќаzўж:ЌЪТкlk{ышЃaQšю+"=5 Nw9tEяUСИ’іEH tŸЏхƒЩлFю"ŒHo7~Ї;кѕь„WуDќnя‚ ьnGŠ‘€ŸРkпќlB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3XЫ§lB1$€8XЫnЪ1a$€№3A~–Іƒ@H p4\h€dёИМSgМООnмФIQбб:Њ ƒЙЊЈЏHяB˜и $ "DТŸжrЗ” З8QюY…+–ЏЈЏЉQ6Ё $€€sм_ЫЁ NN™a hЊ№рC›Š iSѕ_kw—–U}іљШ_\ѓъFЂйПYкќ“БВЂќаїдžЛ@АзЁ–ŽъNШ <<гЅј]eяе~{саю=UЧ+CtRQqѕPћѕ…ня–еa6ІНDymпYzсЛKръу•зn\#~DўГVЌ^Д№…гЇjЪЖ•œ;џ-” ЂQР€g{iѓBЕКІšњa‘ЯbA_‘|R8 ;”#7q‡<АЁŒ№iЉх@dўьљ;пн Т›яю™et`зюЈAЅnКрюКДдДSŸЂ­9/e†і жЭž1эќзѕD/В?RљIі’ЬPг#;#“:aЎC-э:a @~џ№ўь,s№ 3+>9N –eШAвM*ˆђкјШ+Yй2‡юКєХФ^ф?$$D–6 Н{‡ЏЪЮЂЮЉ  јpŽЩ^’MЈОВ$›њa‘Я#‚О"=јdс8”#7q‡<АЁŒ№ižњ~љ„qЩ[п(>іщБяЯŸŸ№к–ЏУхмчЮпўчmYЯ„мн\ѓ œпn7wй_ж_†FŒz?`Ь},џqjщhq џЯuТ€|ыЧЫIЯLБ*™Є *[ѕŒЄ–—"‘џТЭ›JойYМЕ8ьоЅY+т†и^X'сц%УБŒN&jYљѕщС ЧЁЙ‰;фС&)мDH ј.ІцИ7‰nвЌY)Ћ^^žБ$гцjЏe//[Кdiќр8ю„ѓЪбУ†Ћ,Вяо Nм’r~§Š^н лъtGж‰м3МoхŽ2Ж2й(7Хyѕ…tlъЈШф#‘ЏoмЮсќqNЮъ~l3h3Кй7м:КˆЊШЇЈЏHO%‚C9rwШƒЭшИ‰№QН{їід;I™5ћє5)П›mCЇЕЕUЇ“‚u:ЈФы^лdгЊмй'%NШ+(”з— †М"ыIwЅгY?НzонtЅ‘jfMŸВnуZRќš.5ТхoДI$ˆђšђLвкќ<У-CлЯFИŽtљ‡ššсЂ3Љ]jЕЌdА#ŠFamX9)qР4A5ффБMTљѕщЉC"8”#7q‡<иŒŽ›H п%рСZ.‚В>gх–ќ-QУЂчЄ-єФ‘е‹ьс\{и=КФ Щ?}аЏм­y‰СщŽ4$RчЄMK™MЏc‡.ƒž4'c\Rўђъь„ Ќ1Wх•:7m@џ‡&ޘ>vђФ>}њО"џ #†ffeЧ‹.(о’ПaНr б(JKЂI_˜aЅ=”k&ђ)ъ+вл8w(GnтyА7‘@ОKрЎˆqщУчц6ыѕЭ7šЬTЯОA4ft"їJ.ѕŽžn…cгK2?мабœюшш@h@H@|ѓыbУХЉSІЉ›M~Л!ьО~WkЪo§у‡Žyv]=ЗДТ4,DУ‚paQaвШQк}:нQћh‰@H sh^˜юœp– a!КЕНuєˆбАrЎНЗгЕ–H $€:‡€oзrXˆАЛСхшtGЎ7T"$€шB]pэ[f‹C#$€№?XЫ§oN1#$€,XЫkО1[$€№?XЫ§oN1#$€,XЫkО1[$€№3зЏ_ЧZюgsŠщ $€@РРZpSŽ #$€€ŸРZюgŠщ $€@РРZpSŽ #$€€ŸРZюgŠщ $€@РРZpSŽ #$€€Ÿ№эпc‡ЩhИаPїЭWъГ2№БЧ#иЙЋК•VИEнВU9—М\_SЃbцбІЮnмюPОŠаб0DГр.?Ф}m]ЦЪЌ›зo:„H›]= ž vЛЈИХ‰ŠlBHР|О–C!_МфEu4[ ^w{-Їoy…+–ЏˆЃiЅНДkЗq(эnнhщ§’dн2A[ ђ_Эt&ає„ч.:іщ1ъѓњuљшпц(Ÿи“ю№abм”IБCЂgЮзtIž жѕc7›^0ю‹ЫWФŽŒ‡јg-5 fWwЄт­EWBbќОіЊћ?[s–( 6ˆтЄЦЌАыƒїЦЫ”rѓжБ‹Ъ€m"умМќ„‘ё№э f,aKщŠ  ƒ,№ЉBТ†р!…] *xA9AђˆwŒЙЏвŽяQ{ бР3§#MАi7ЛЩS&555ћc™ї%а€”Т\ши<ЦхЯ”€ѕЭВbЯбВЋS?( $рQpўќЄ–УБјœysЏяО§Ž =bф#‘єћХЩOЋhыБcЧžјВя*{Џіл ‡vяЉ:^Ђ“ŠŠ‹ЈMэзvП[Vџ…ѕ7В Я№З(uол­ŸокёюЌ9)*Gље­н]ZVѕйч#=rЭЋaжTK06Н,Эœ;}Цщc•UUx№ЁMХ…ФеіЅОЛy}| ђкkъўГVЌ^Д№…гЇjЪЖ•œ;џ-1ЖyЎ­Љ=єЧ=•хЭ7ZŠЗ—Њ8Д‰АјЭЂцW(‡ПЋ7ЎТ&ѕЬVЩкSAфSD†А!xHЁКІšњaхAkё›ЅЭ?IЧкsX{"ГЩ™киЭnXќАКк:А7м2ЌкДž|ŽђJVЖœWw]њт Ђљ бп„CzCяосЋр*о#{I6а€GŽQwШ:8RYAћО}+?Ё­,aQlд˜D>E4 `6ж•Йбf/Щ4хš‘IЕvГ‹Q}Ў\•;Ÿ/AЎ=W zDЙиšfЪЮ”ˆ˜в›rЯqtWWњD @ю%рчЫлюД”U9Ћш9l‚ •r5P ’рыCPљ`I9,, жЁу­/'=3ХJ™!…аЊчIѓRчm)xcЬш1…Ѕ%ѓŸ›ŸxVf]pwГ70ЛM.йSX;L§…Иhќ|Уљлџ4ЕЕФYVlFљ/мМЉфХ[‹Ую YšХПJŸzс–ў2ё,rШŽ{Y“лlXТZ\QЗ"ŸZhа`Ј7"p'HЦилŒQдбЦнД›]Ь 6nћЃхGђз­пЖsЧ„ Щ_~љMЮЫ9 хB§‹'tІDФ”NИ{ŽCЛКв'jp/Ы;Н{НvК7(лє9‘“ЂN4*х|омEoўaчжA[vОП{юœy$ъžс}+w”БoЛкГ‰Пэ_п(.)§ВюЫWWЩяП.>œfйЫЫ–.Y?8ŽПa‘6zиpCп№ОАZ@пж‰Rф>жМn**№)''gѕ‡G?V&BН~дВнћ†їъиЗлJeQlд€D>Еа€`XWъВ<аu=)чuДqЫЭ>е§Ђп§pъGЇ <$fліm'ПЈ љP(ЪХЦГrГ#mѓL‰ˆ)ЛsїЗяъЪqQƒ€vўВЦn9Ў3{Ю‰OРГEЯ%_ oОzVХ›››aйиЬš>eнЦЕфmКщR#\ўЦэ+RЮK}ЁЄДdёМљЮ]моЋчнMWЬW?СNгккЊгIС:”œuЏmЂqNy&im~œˆ…Ыёр"8Ђљ‡Ќх‹АюШпh0Ь+*”Wс †М‚МЄёIъi $%N€.ЄяZш›8mЅВ(6jР "Ÿ"I‰ЃијYWъВi B7ЗYЏoОбt`О:…/еРћ \јуєxnя!Ѕ>ŸЎюvћ[ХSЇЈ]†ІонЁVј>иoЦўzLТ‡zЁБ/€Ѕ‹K2?ма›ƒ‡Џ–й\NяЎhqWwIєƒ(јЙы‹ эЌЩo7„нзяjMљ­ќ№УQyечЫсЗжЁTS\lИzЗ+сЩпџЯїcфЫ—№сЏр Eкм4c{[aQaвШQўšІz^ИЋЋѓСV$аЩ|О–“ЏЩw25юppд7Ђo!sŠšk†J_'аЇOŸБ“'ЖЖЗŽ1–м}='тЧ]н hи x”€ЯзrвqШЙ‡V2Š;,й]ы„04с‰нв>5ІƒfH p јЫuьмфP‰@H `-€IЦ‘@HРЏ `-їыщХф@H `-€IЦ‘@HРЏ `-їыщХф@H `-€IЦ‘@HРЏ `-їыщХф@H `-€IЦ‘@HРЏ `-їыщХф@H `-€IЦ‘@HРЏ `-їыщХф@H `-€IЦ‘@HРЏ `-їыщХф@H `-€IЦ‘@HРЏ јќ=O.4д}ѓ•њ |ьqИЭЙК+­ѕЕu+Гn^Пщї‚ЌЏЏ[Ж*чђ—Л<‘РэДЕ“чކJWv<-};m -С  @"рѓЕ љт%/ЊгйZ№КGkyСж‚ќWѓaјС[gAaСŠх+т†ФЈSэ„жNˆФЯцNћЄјСŽЊ=YДD~OР_жилЅЌь,ј“кMSfГ)˜ЦІІЦ•ЋW$$Ž‹ž™:яфчUC;ъѓџN 9и9}€hg ^3МѓдV]Ћ)#A:qƒЛОCDЂHœЫ‹Iб*vемY#ш"Љ3wд.J‡EDРчЫхЙ‚ЪН2ЋlG™78DЖйфЮчѕ+њ Ÿ_М }йKйЁї„644”§agм№xЎБКђvыmuпj•гщц!wB$~6w^1m@NР_ŽЫ-р Ђ?=ђiZз-jЮџ…Ѕ%ѓчЇN˜˜ Ѕ с_]ПСlwGЪЭЫO HwЬj8ЌЈ(7eRьш™sч5]j€rŒЯєЯтԘћъКиИј„ёcw}№1ЃіfKwЂпЗяИ‰“Ђ†˜ЖЗ—”šж тWЎ]зжfЄ]”8WŒvсњ„юth'<сњu§‹ЫWФŽŒ‡Dg-5 fWwЄт­E^BbќОіЊћ?[sffЪ €ш NjlxРm"ЁЦ\Н2}bЯЭ—ыŠІ ­ S "?“ЇL‚uвzьЃcD шAr#v‚gЗтiƒ…Ђ”pЙxžќ;КП™‡:L СШƒ*іj :=AЈFH S РEc№ч'ЕŽХчЬ›Cј}їэwD шEPO>5цз‰мжт7‹šo\=t ўЎоИ ›дЌњЏЕЛKЫЊ>ћ|фЏGЎyu#шЩZ%<“?jYќfiѓOЦЪŠђCмS{юеЋЕ__и§nY§5`ГЋьНкo/кНЇъxeˆN**ЖЦРѕ щЂт“ЭІН,Эœ;}Цщc•UUx№ЁMХ…ФеіЅОЛс}| ђкkъўГVЌ^Д№…гЇjЪЖ•œ;џ-1fŸЙРm"Ёі\Н2}АWЩ—xc]™ŽBˆќ ‹VW[­†[†U›ж“[gjы@J7ъ_$TзT—•–Tџ|ќИЄдЬєOO(йVћлј1#зф­!НDЮЙ“]ИpиИvщБPFH ЋР(ќљI-ˆЙыrћџВ?Ѕ 2hшІRhНu3ДgЈRš#•йKВсxЏ,Щ>Rљ 5Ыy)zыfߘvўыzЊW а+{IІЩGhvFІв@ЉY–!л§ћ‡їgg™ЧЪX˜YёЩqЅ=Ћб˜ŠOvhжэ]ЛЃрšОnКрюКДдДSŸ"­ћy%+[Fб]—О8ƒ(EўCBBє7соаЛwј*ИІAёPЎАх+Ищ‹тсЛшЈep§ФЦŽЈ>W Ъ 9vL>4Џ=W zDм:Тй‚3>Н{†У6mъДлџМЭnž?gопDЮЙ“cpсАcs ИYГНPFHР{јУљђЖ;mtUЮ*zD› ƒFЅœ‡єьGTмr~YГїсd’@ИЅПL',ИЛЙжТЛэmrmы(\ж_†вEtlфoБСмњёrв3SЌvі&JK`*>йЁ­ƒТЊУ…Șќ|УyЈ+Во†œЕљ/мМЉфХ[‹Ую YšХЙB^8uЎ.pгХЃюŠДВ@И~b мАQ>)sДќHўКѕлvю˜0!љЫ/ПЩy9жqY IDAT”"nv‡Іц`cv“юo"чмI'\8l$\nжl/”‘№–їfя‰ШЉH lгsфpDNŠ:бˆЪљАиaЧNTN2M9`п№^peЉU є яЅДБЋ‘\з“rNЈ§нAЌЧ’wjыщgкlz†ї­мQЦVK‹ѓџ;сsйЫЫ–.Y?8ŽП!ьшaУЩ№}УћRD4 ‘џШG"_7•=8qž“ГњУЃг.onnу6Eё(-е5\?0ƒПшwџЩOЋtКСCbЖmпvђ‹*а™qSHcЋШ9wR4њTšqГVšЁ o р/kь–Cф9Гчœј№<›сZєJж™i о~{;\ѕгіГЎnkј[|?˜%%NШ+Ш“… †ЕyАЉьnWcrRhђaШ+2Ÿf†^џ*ъНн{Ё.ТЊРІЭy"?ГІOYЗq-љаtЉ.YЊш{ѕМЛщŠљ‚)0sТgkkЋN'ыt№Йdнk›шXSžIZ›Ÿ)Д§l„‹рˆ^ф‚—/ƒKлЅVоŒ8 м&/• ŠЧЦЬюІШЯасOo(и2>yЦќF7бщEЮЙ“тgжX”5kƒ2@^BрЎˆqщУчц6ыѕЭ7šЬT ОЈяYєžКqчДBHЉЯЇЋЕ§­bюZКz/7ЖТQщ‚%™ю?шFŸш $€ќŒ|ѕbУEЛkђл aїѕЛZS~ы?ќpT^ѕљуrј­u(еъг 6ъj…ХчДЙiЦіЖТЂТЄ‘Ѓ<4 КEH 'рѓЕœ|ЕЮ;gБOŸ>c'Olmo=b4,Й{g@H ј:ŸЏхо<АNbwЉФ›уЧи@HР'јЫuь>ƒDH $рXЫ=]"$€шDXЫ;6…@HРА–{*КDH $а‰А–w"l $€€`-їTt‰@H  `-яDи8@H РZюЈш $€@'РZо‰Аq($€@ €ЕмPб%@H N$€ЕМaуPH $€<@kЙ ЂK$€@Hky'ТЦЁ@H x€жr@E—H $€:‘€ЯпѓДсBCн7_Љјиуp›suЖ5*:КОІ†еxЇ,ŠSЄїЮ,ДDХЭˆЋдтЭu›.к•рыыы–­ЪЙќуeŸиН]ЩTдЗОЖ.ceжЭы7;Ÿ€ыћŒЦщsz QG‘^ѕ]BРчk9ђХK^TgЗЕрu‡jЙК7чZёѕр7з{љ"yХ\PXАbљŠИ!1ЎSѕQ[ ђ_Э;uјџoя| ЂКЎ?]Щ[Б]uIьs™ІI]Яќ‚)ŠVEbЃhдJЉЊVˆ&ТтЇ т_Ђј/ˆ‘ЧkX%jBTj0 ˜&>cBK*БDкўŒ<ƒU }‰ШZКжлУУёоsю\цЬљВf ћžЛЯ>{і™йsЯ\8~QЫ]•SПxqТдщг‚ƒƒщ ŽсЗlкЊЗT˜_аvсЙvcFkыMІpхJуsЋзDŒŒЙ,uEss3kЇЋŠ#%‡'OŸ6R{йФ/8H8№ЦўЈ)ДЙ93Уv[?ІMeŸ”Љ uЄюо8мйSбЎїGЮgUŸЮ™12|rьŒВВRfVкHЇЬ[шtЯІŒˆ<Єi\}ЮТEѕык{)"m’,%Љ‰šY/ѕX77oсTїs§;ЦRљуhЯŠIX6gЦЮ %жНђэJ&P Е“ЌtCћ Ufgщ™ЋQWi^HOHM/ƒ9–З+—ц|TtфaŽIэЋ& …UчWЫMу!7в.мЖI“ё'}щИЂ}’йЁУјmљшThѓ€’РЉЖ‘УWОZYM9Јe6:=гУx‚QеыЂУ˜у73( gUГнФ4ы4Љ{ n-?}ієФЧЃi(к_§eэБтCЇNVйmЙyЙLЩŠ”…qёg++NН]1фglЯЫсvЊПЈ-~ЕЈцЃ[чЊЋЊН~ЈЂЌДщъwy…М/TіI™КPGъ~Іъ зWЕ“‚ш*œд5ыŸYњьйгUEЛѓ??џ%3+mь’ю Њˆшд™?Wњ№уёпАeыe‘hVERŒZд—ѕrAгї7еъЯkE}.ЋќЩ{9ЗщъхcGKщqљъe:Є.Ѓ#GŸЋ>GBѓѕцuл7Б€ŸVŸЃvfPъK#ш•йЂ(=ѓеQU^ШGЁщЅЪHсО‚к\Є9џЮбŠoЏ~ЫœQй—NЇў“‚”›ЦCЉcR;ЌЃ17ŽЎЭч@у ЇJэ*8Њ9Ѓ1ХѕѓS$ˆpœN0еыB4h Ћ)ѓО/,OуUэЄ њЃ '((Јё-.4їяК.-•™•6vЩwUDt*§љvТѓуgŸџЂ†ѕ2ˆH4ЫihHŠQ‹њђБ*оM[žв–рДфQŸЫ*Ъ+ЪИ”‘ђŠwЉKDФИ3ŸW“PZy<шю ЪJЧЅyѕчgЈ”КСNщŸЭ(ЋђBжT(T)9^ўBjšcЮїЖ'-KfўЈьK'‰&ЉџRnšŽšCЉcvЄуjlВCЪšг  щ(RUСQЭ)~hоaЇŒЯIЭы‚e,Јgic—,pїHPEDЇzѕnџшC˜nа}m?ЕkД§iˆ$ХЈE}хX§;3"ъsYхOCу5Н#† нКЭё}Э‰вђЌŒMЛїэ:uк_ўђЗєUщЬ д >–F0ЃЌЪ ™RЁPeDŒ”{ЂВ/$МЄўKЙi:jЅŽи‘ŽЋБЩ–MMG‘Њ Žш0Ÿ$;тЁy‡N0> тыBЮ@VyЎŠ”L‰@ ,у”їUШ{ƒјЄхбЃ+;лРЛ>Ё+іщЇщЪU+W,_9|]Ла jјш1FєЇшЖ;іb#†а+Јь (іхUэ\ Њpџb№KmЕ‡ОўLO_џж‰wH_ки% тшЊˆDQ6‘HCJRДЉ’†іЅ/йЛ9”ЊЉќqєН#›}Љ;}(љљ }pЪn>rФюТн}rŠZЈ]jм§FU^ ,Ћ2"FЪЛЋьK' яe HЙшг)Љc.ибЂšїмmЃW7ЫП'Fп]GtX5ЏєжЬД8`wЮЩіw“с*ЯU‘šё:о&Иkь)‰Kіь)ЄћMZhІЛTъў^GŸІС=7.6cлFі:ЌПx‰nc ---vЛ­—нN5 уХэš^N3ss+кЭЭ™й™1Sbєњ*ћ1бOˆ}yGU;W`‚*ŠЫqЏн…wЫжвqe,mь’qtUDЂŽ(›ŒHЄ!%)кTЩ1бS3ГsквLЅj*књfВО)›бSYїQc~Н5{ч”iSшpЪф)[ЗэЄЉeзћіЙЇў›ілыШ‚*/ЦU‰}*fcV&-YЕўp“ю5cTіЅ“Ф`P~JХMз'Aъ˜ЪŽибЉмfD2|$lёa*чDcћŽL•еœQйщRЛё“О.L†CnЈ№ЦсА‘сємбрјMњЫRWˆ-ЌQгЂjе †е421;…\C‡  `Š€_дђ[6›ёC†‚Ъс’ЅO uь№ЁГTmxnѕляМ-StоvЃх†s%jєџiшcПњUYYЉЦъс7?іЋ^Нэšvё№рЁƒ/ЌN+9tPl$љоп{ф˜ж FЧ{‡†wyЯ<,ƒ€€?№‹ZюR‚r ђ/N˜:}Zpp0UZ„пВikЛЅлЖЭ™YQу#щAПќЅ+N*Ÿ“cgDŒ ŸГpQ§Х:вg—ЁєЬFnnо’162jЪЄoьgj\П]ЇЃ;k?RrxђєtбЬЮцД­DЎн˜бкz“waТ‚п-мѓъž;oл*yzўяюhМѓрГO> љIШЌщГCBB>ЋњT<™ўќЪƒЏЄЕ Бб@ІˆŒi№Ов@Ј;—СЁg&\Йвјмъ5у#‰­477З›КmЫл•KLЂЂ#ы Rћ-QPІ(_њ=м7  рЗ–Ÿ>{zтубвцНœлtѕђБЃЅєИ|ѕ2rЕ3Ў..(:ѕсЧуПaЫ6jg‹ъєЬ\3ях‚ІяoV”•{§PѕчЕМн@ЈўЂЖјеЂšOЊHч@бўъ/k:uВ"ШnЫЭыєYќ‹С?єѓ>шќ^ ВВђБЁг%ЛСХ%ХsтчТogЭ)~ЃXдЄЋљŒukVelрŸ]ФГRй˜ыbWdHН–ЌHYЖВтдлC~іРіМfЊp_Aэ?.“wŽV|{ѕ[cћЉkж?ГєйГЇЋŠvч~ўKІŒg№K[Ы[Ў_ ю,MjyEYкђ4К^ЇŸ–Ї•WМЫевŸOЁ^НzйчЧЯ>џE oз д+myJ›рДфН‚ОeeВCŸЕ<^’–к>Vђв”ВwOъѕ—ў~со{yћо{шbъКо§ѓ_ЯO8‘NMœ8‘djеТТ†ўzјЏЉdŠВˆёŠЃ=PF7оeЇ‰ ‰Ї?<ЭЮ–/!5ЭСПЗ=iY2kTй jМF—єЭ§ћ‡ЎKKэCП!@ЬEЫпЧNљhНнъBV‚њєmОо,-ч зје- зИ§^Нлk-•ѓє%НњЇЁБЊ;Я­ЉеgDgЎнѓTlЇО,QTzmwлш/тЈђб’2-›гХzgtш№ЁkзЏ…EtоwшшёЄ%‰ЂbRBтœ%‹"FD8Œ;ћ1CУ 1^qЈšк:К­§|нљџnЛЁ#vRнЊƒЪ~ЮŽэљм—З+/ф'A+Rq‡М2€€џ`Ѕеё6щ?q™dtФшЪї+fХЮжwк—юŒceƒ„>Ё}ѕ:N[FЎ4ВrNFИў=wлшЫoњ(@-пѓгBŸа{‹TеЎCЫЖhс3/ПЖoзАћ/\АˆЗK„лЖ#ЧЪо=QЮ?a{qѓ~GХћŽ›ЮюВ͘О!eMZёž}#]o2ˆhxхЊ•+–Џˆ>‚ЎП‰Uјш1ььРажМДЭq}ЪIO_џж‰wx  рgw=%qЩž=…tWTыЭє qнпышягXvcЂЇffg:жg››7fgвЁ Yo3’гfЃ93З§_Вѓр#aћ‹S‰ЂUэ;2U–чЦХflлШ>д_МDЗПI5щВ›.SyВВЉЉixИбпtбЗщПњх№BNжHІjзX4шўЙ3cГvlзД›<ьлчžњo:o 3ˆhМЅЅХnЗѕВлщгFЦ‹nФ>Г1+“ИбнбMpЌ‹Ъ>sмЧGЖwЫжbИ‚" @ЌH pk9]vчПќЪћgЯLš9-"*ќХЬmONz’Ѕ0iibHПб3Їбc@ПtшBjщ‹олЃЇN›ўлИa ЁЫqіГaэъїо/r옼Фєq*ЫѓцЮішАЩKшNьUыгЂЦEЉ4-\МnнъEѓwД‰?ьЖpўМїШkёП‰Hžџњ‘з4tHЫ—ПћNпnІ%aAтьyѓйщЄo>n|SњкY;УF‡/H\2ьб!М=aaт‡˜7iцєћюЛЕЋьG•’š1:<;ogжжMм№??Кrв˜…›››Ўж]lєm+OD4qB4П?ЫpK O'{RјJžt-нИ—Явт’х)o•МщA›0  рgшПY_ЈЛрД`ЭмSвoахЊвыџњъЋŽEЪŽЋEЫђ џЕNЅки}в1V№вYZN\˜xѓVkNnNЬј'М4 Ь‚€8ЫзrК…ЯЋџkнљAыРДмrЋeТИ ДфюŽ)єЫзrU`ОаNы$N—J|СOј  `i{я›ЅгчA@@€@-ч( €€€€%  –[2mp@@8дrŽ€€X’jЙ%гЇA@@€@-ч( €€€€%  –[2mp@@8дrŽ€€X’jЙ%гЇA@@€@-ч( €€€€%  –[2mp@@8дrŽ€€X’jЙ%гЇA@@€@-ч( €€€€% X~ЯгКкКsћЋ1ћЁџвЋ{œзTŸK^›zэЪЕšЊ*cO<{6,<мньюйX4жjjЮ­\—о№uƒ;jlт@ќ•€хk9ђeЫŸ3NЯЎь—МZЫГwegmЩ>l(Йсƒв]2ЮЭЮЩ^ГzЭи‘#œjB@@  зиыы/­]П&*zRФи№9 ‹>њј”kтќ…ВBNн}№:вЋ.бchNЄн щис(фR6h-ПЈхЗl6у‡6jЧё•o—,}zTјЈc‡§ jУsЋп~чm™ЂѓЖ-7œ+AЃ+HяъJш‚€@№‹ZюRўr ђ/N˜:}Zpp0• Z„пВikЛЅлЖЭ™YQу#щA‚эv{3]b–••NŽ12|ЮТEѕышЛюЄgўш0rsѓ–ŒˆБ‘QS&xc?Sуњэ:нYћ‘’У“ЇЯй~Ѕ[˜_аЖfЙvcFkыMоEШ2йЇQ6gfˆ~ŠІјаЄ@j.юДs[ю*)˜ёйЁQŒс№сЄ6Љ;ї™9LЯLИrЅёЙеk"ЦG’чЫRW477З›КmЫл•KˆЂЂ#МбŽдўgUŸЮ™O‰Ѓє‘Ÿм  рЗ–Ÿ>{zтубвцНœлtѕђБЃЅєИ|ѕ2rЕ3Ў..(:ѕсЧуПaЫ6jg+иєЬ\3ях‚ІяoV”•{§PѕчЕМн@ЈўЂЖјеЂšO7а(к_§eэБтCЇNVйmЙy>ˆЊЋЊЩ>вtѕЛМТ~J4ХIд˜KgЊЮtЖ+\5щЗc ‡Љиф>‹HЉз’) утЯVVœzЛbШЯиž—УLю+Ј§ЧEBєЮбŠoЏ~kl?uЭњg–>{іtUбюќЯЯЩ”ё  ўA pkyЫѕkС}‚ЅY,Џ(K[žFзыєѓТђДђŠwЙZњѓ)дЋW/ћќјйчПЈсэzzЅ-OiГœ–œЂWаЗЌLvшГіƒЧKвRлЧJ^šRіюIН>Еp?I(?QЮuDSМ‘И>ХейЎpеЄмŽ86Ѕ>“ёЃŠУшОТЛьНzлOxšXrМќ…д4G:zл“–%ГF•§   ЦktIпмПшКДTю3№–ПrаzЛе…Lѕщл|НYZЮЏѕџi(ГIТѕЦnПWяіZKхќ}IЏўihl ВСЮskjuЧб™ы_7Ф<лЉЏHЗЌёS4Х8\тКЃ]цЊIИ3p lJ}&у5Еut[ћљКѓ7ўнv_B 1юƒЪ~ЮŽэљм—З+/ф'A+Rq‡<@РкшГ)€ŽїEkЧтŠїЃ#FWО_1+vЖОѓРаОtg+{$є эЋзqкт0rЅ‘•s2ТѕяЙлF_~гGjщќъ—Ÿюњ„Ќи[Є*oZŽ;ј?ђvЉ00t ЈЯuTЎšєл1#И`sхЊ•+–Џˆ>‚ЎП ]јш1l 1>ДЪўр_ ~i›у~њт<=}§['ос] €€€u АПИм5і”Ф%{івmP­?4гMauЏЃПOcщŒ‰žš™щXmnо˜I‡.ЄЙЭHN›цЬміЏxЩЮƒ„э/>L5‰VЖяШTYž›Бm#ћPёнў&е$ЫэCŸSbЄ:М1&њ Q_hЇx;ьЎšєл‘ }ћмSџЭ%~Ъ›---vЛ­—нNŸ2^мЮMХ>Г1+“0Жўp“n‚cэ*ћўбq{р-[‹с‚ З@ЌB pk9]ЮцПќЪћgЯLš9-"*ќХЬmONz’Ѕ-iibHПб3Їбc@ПtшB:щ›нлЃЇN›ўлИa ЁЫqіГaэъїо/r옼Фєq*ЫѓцЮішАЩKшжыUыгЂЦEI5‡=:„ьг(!їо›”рФЯЄЅЩ. CЋ\5щƒд1о˜А qіМљьŽtjtСцІєЕ;Гv†_И„тэДМ0qШCL›4sњ}їнЧкUіЃЦJIM‹žЗ3kы&n€јн?9iЬТЭMMWы.l§еаФ бќў,cхю9K.%<d№@@м!€Zю=єž'€Zоѓ9€   рдrwшЁ/€€є<дђžЯ<w –ЛC}A@@ ч  –ї|р€€ИCЕмzш   =OЕМчs@@@РЈхюаC_шyЈх=Ÿx  ю@-w‡њ‚€€@ЯАќžЇuЕuчўіWcCўЅWї8ЏЉ>—М6ѕк•k5UUЦžxіlXxИ7Fє’YЯЦ^SsnхКє†ЏМAРГЎТ€x›€хk9ђeЫŸ3ЦД+ћ%Џжђь]йY[В†JnXЂутg}9–ьœь5ЋзŒ9‚{ @–@@ЏБзз_ZЛ~MTєЄˆБсs}єё)зцСљ џd…œКћгeЂGbЁЦT*HЛѓБУQШЅlа pќЂ–пВйŒВД^љІqЩвЇG…:vјайЊ6<Зњэwо–):oЛбrУЙ4#ldћ…la~AлšAфк­­7yQ ЫdŸFйœ™С§$СМџk}юъan_єYx[GyŒм‚(5Н6=ѓБЈ‹4pRр|4НЎ\i|nѕšˆё‘ФaYъŠццціqoлђvхУЈшШ#otЦ%ЕџYеЇsцХSf)ПфЇш9d№q[ЫOŸ==ёёhizђ^ЮmКzљибRz\Оz™Йк™?Wњ№уёпАeЕГ…hzfЎ™їrAгї7+ЪJН~ЈњѓZоn TQ[ќjQЭ'ŽшэЏўВіXёЁS'+‚ьЖмМND еUеdŸFiКњ]^a;е%џЉ uЄюЬе3UgDћ\жюшиХѕFDzl,ƒР9MЏ%+RЦХŸ­Ќ8ѕvХŸ=А=/‡™*мWPћ‹Ф№Ѓп^§жи~ъšѕЯ,}іьщЊЂнљŸŸџ’)у@,A pkyЫѕkС}‚ЅI*Џ(K[žFзыєѓТђДђŠwЙZњѓ)дЋW/ћќјйчПЈсэzzЅ-OiГœ–œЂWаЗЌLvшГіƒЧKвRлЧJ^šRіюIН>Еp?I(?QЮtКъ?uфv(^щ@вРЛЃдˆf8ƒРE>bЏЃŠУшЦУЛьНzлOxš-9^ўBjš#_НэIЫ’YЃЪ~PPPу5КЄoюп?t]ZЊh2€ј8ЫпЧN|[oЗК@9ЈOпцыЭвrоаx­џOC™MЎ76pћНzЗзZ*ч7шKzѕOCcUvž[SЋ;ЮˆЮ\џК!цЉиN}EЂИeбЯЎњяpUˆЗsPA’оеЅF„AЂAр"БWMmнж~ОюќЗнИаСJŒ‹ыЋьчьиžџЧ}yЛђB~Д"wШs`@,@ уmЯЎzиХбЃ+;[ow`h_К3Ž•7њ„іеы8mqЙвШЪ9сњїмmЃ/ПщЃЕt~ГЫOw}BVь-RUЏ-л~dэ]ѕ`ш@б7юTPХшДЃ‚ЩРE +W­\Б|Eф№t§MlУGagХИИОЪўр_ ~i›у† њт<=}§['ос] €€€Я ВBОю{Jт’={ щ.ЇжšщцЏКПзбпЇБlХDOЭЬЮtЌЗ67oЬЮЄCВиf$ЇЭFsfnћ7ИdчСGТіІ’CЋлwdЊ,Я‹ЭиЖ‘}ЈПx‰n“j’хі!ШЯ)1LЇЋўЧD?!к‘$mTХ(UV5іэsO§7—јY“s}ZZZьv[/Л>X ЭИэ#:й9йkVЏ;r„ј7@@РзјЫћ-[jZ*=lЗкkедМq8ld8=ЋUxшр ЋгОzpоofЈсTИбrУv—[упћу{+5}šЪŠf№Я^TбЙЌъ‹vшqўr]о’*њЏЧџšзѕŽfљяЯ>љ4ф'!ГІЯ љЌъгNЅлЖЭ™c#ЃІLКу’]еожГѕ‡цЈшI­?мфv-S-ќ*„#%‡'OŸA‹Ќ‘žХГМ/ М§Ъ•ЦчVЏ‰I.б%fssГЈІ‘•Ъ*чэ4:w• Q˜_@’k7fДЖЖ‡IмцЬ‹>9vFYY)г”6в)ѓxP =Згpx›5>’$иnЗ+ъНхHH~хСзжз_ЙЌœ\€ј6?Љхt-О`б†њ_ўƒ дBэќ‹KŠчФЯ!…пЮšSќF1зЬ+,hКњ]EYщБзЉ:уД)єъ+fjЏоvn„ъ/j‹_-ЊљЄŠ]№бГг+П%+RЦХŸ­Ќ8ѕvХŸ=А=/G4Ј‘UЪ.Х]Ѕ!эЏўВіXёЁS'+‚ьЖмМ\6nъšѕЯ,}іьщЊЂнљŸŸџв БKxPJy/ч6]Н|ьh)=._НL‡\Sє–72RБnЭЊŒ Мі‹ Њi ъ@_&р'ЕœoЮиќаџzˆГ&™ZјЁ^ ыз?џѕќд‰щдФ‰IІІV~ЂKРО/oНнJ|зЅЏуWфtH2Е”ѓC‡]Л~-,ЂѓюГCG'-IЄО  §ЪrЦƒvІIЯƒнџ№рŸW~pjbTdх• }Œ*?Ы*‡šЇ‡5Еut/їљКѓ7ў}УЁl˜4•В A‰Ў^џК!цЉиNW;|ШйБ=џћђvх…ќ$hEjћнцвЦ.YшшNЉЁёЯ зјyб[о( I ‰s–,ŠAuЗLЎ@|œ@Ч[ВЛщЬ=*лќ;rК"gEЕШЫљmл‘ceяž(чЕ–ЎЯтц§Žоющ6ЋЁЏ|гШj |pU;W !ў7ёЛ їR-НјЕUiЋХSNх{юЖбїаtсKšт—т+W­\Б|Eф№t]N сЃЧ˜R)ЋœWЕk†ш:Аbo‘О^ўХр—Жm%eњŽ<=}§['о!Yки% šбљсРаОbjњ„іхЇœ wй^LпВ&­xЯОveУiрм 4@@Р7јЫ;ћS4›mСќяПѕ>=ЗуэhзаЎЌЌќе/џƒr:K2ЕP;Щ1бOdцц8Ž››3Г3y_U;W axјˆ›п7б]гAA!ƒpђjњіЙЇў›ЮВ|$lёaЊжЭз›ЗяшЗЅЅХnЗѕВлщGЦ‹лХсєВJYхМЊ]cyn\lЦЖь“M§ХKtћS СqOнƒvЫжвA[ки% šбљaLєTЪKЭЦьL:фЇЬДp2wflжŽv†ЦгРŒAш€€@Я ˜F?ЉхtёMѕ›ŽЋ№ЛпwЪ0я=ђ]@kЮЬˆ§Шkд˜Д49фЧішЉгІџ6nXј(ЎІjч L˜?wуЖ чjэkдш0aAтьyѓляаЖй6Ќ]§оћяEŽŸИ`”0юІєЕ;Гv†_ИdиЃCєvФ•ВЪyUЛh“фysч{tи‚ф%tЫњЊѕiQуЂ˜BдИQ)ЉiЃУГѓvfmнdаи% ЬŽў9iibHПб3Їбc@ПtЈз1n™;ћђwп1уi`lgA@РаBЃЧюŸœ4fсцІЦЦІЋѕG;ЙŽЄ?Rš8!КЋЗny5Zr)сщ$у! _ЩЃwpcœž%@џВњBнЇkцžК~ƒ.W•^џзW_pќ9хП/ЇџЕNЅк˜>щ+р,€€X—€хk9[^Аnр9€€ИIРOО/w“Кƒ€€€u  –[7w№@@PЫ1@@@РкPЫ­?x  Јх˜   `mЈхжЮМдrЬА6дrkчоƒ€€j9ц€€X›jЙЕѓяA@@Еs@@ЌMЕмкљƒї   €ZŽ9  ж&€ZnэќС{@-Чk@-Зvўр=€€ –c€€€€Е  –[;№@@PЫ1@@@РкPЫ­?x  Јх˜   `mЈхжЮМдrЬА6дrkчоƒ€€j9ц€€X›jЙЕѓяA@@Еs@@ЌMЕмкљƒї   €ZŽ9  ж&€ZnэќС{@-Чk@-Зvўр=€€ –c€€€€Е  –[;№@@PЫ1@@@РкPЫ­?x  Јх˜   `mЈхжЮМдrЬА6дrkчоƒ€€j9ц€€X›jЙЕѓяA@@Еs@@ЌMЕмкљƒї   €ZŽ9  ж&€ZnэќС{@-Чk@-Зvўр=€€ –c€€€€Е  –[;№@@PЫ1@@@РкPЫ­?x  Јх’9.iѕ‹&O…цŽwњz/ >хUї8УGс‚ї№К`Yх•Њн…!,зEЛДБлBыйбЛ-LпЕмы9Т\ї:b р!™Ћ1тЁ€ЫLw’зЅoё}њVєYEе+ЕМЙЙyGNжфи#УЃЂ'-K]ёYеЇ*Мкю ЉЊЉЊ2Žбœ4іg„€гЙj†ƒS#˜№f0К у”М 6yMжєcё&Зр ‚Ц7юs—|гщR_o(зежбуn›nОоŸИ іЉиЂнљ§ћ†6п\W{aпХУУGx|,@&0xШ` пѓзхЙЏЬ§Яи„ѓћїЕнe >rФЎЌœua~]ЌGŒ\Л1ЃЕѕ&kЇO:eeЅьR~ЮТEѕыœъ)9: оиOCа@4 J?ь,=s5qPвбл—ЫLЉоa“8BЮŠI˜3tFeм " A8P 4rдb чiщ@ЂI’ѕйљ§вg*?Јфjgђ”I­?ДOкіvsЦќ„сqqчHIђіЭЭ[ј+e?зчHр$ш‘ВГєЬе”SN–q ’Ѕi53є”кfИфA~–k{kNя55ч*пЎœљЧЂcл;е%ц’I5UАŽюв7@oMœ GЊДІ Ц-Р№Иx#тgЙРћВўЬSЏ n‚ѕЋI|o{Ј’)M–5О‘ji§Ё™оРХЕЃЅэe.ЕЌ7BvЄѓPtВdЯзђгžœ6љ)•ыŠіWY{ЌјаЉ“Av[n^.з<ѓчът‚ЂS~<ўёёЖlcэње_дПZTѓ‰c{ЩŠ”…qёg++NН]1фglЯЫЁFЖ~BЯ|!Ee-ЏА щъweЅЧ^?tІъ wIRзЌfщГgOWбzУччПdЇ їдўу"…ѓЮбŠoЏ~ЫѕEпx# еUе4 DУб дЂwRд—к—ЫzIŠЙœїrnгеЫЧŽ–вуђеЫtШNЉŒ›ADTѓqEA•)jБЃЪyв‘P $к$YŸg§ЁpW{eяЋsЬыелЮ[H№)gК:aФ@4В”dоЫMппdЏ”ъЯk5]є‡zЄњ ЏšrdMп]B•VЇѓGJЩ(UgŠ ђOќxЪф˜„”ЄNПŸП;ŸоЉІLП!sw‰о:œЊ+nт­‰; Rk*bbGЉЌЯšT5šf^AЂ)ƒ,Јо[THѕYжјЦЦэе;xъЄ ‡Ы:/сПy|VЬTz™K-ыИLU м}йѓЕќњѕkС}‚Йgє)†=XЫСу%iЉ)ЄаЋ—=yiJйЛ'ЙfњѓээѓуgŸџЂЦЉўЪфКшgjG‡ jЛЫN HLH<§сinVTЃ—Ÿ(O[žFжшч…хib.5^Ѓ ўfZoX—–ЪкKŽ—ПšцЇЗ=iY2W}у$№QH AХSRYjп X)CЉхђŠ2ю …\^ё.SS7ƒˆ,Ј—њ J‡ЕhAх<щH Јm’Ь№ьаC!і Ъ“ŽKѓ+п4žў?Їgߘ­щхSЮtuТhbЅ$ižЄ-Oi{ЁЇ%ЇˆњRYTЏІšrЄiм]•VЇѓGJЩ +ŸOып'”оВfЯš}уп7ФУѓŸЗПS‘ЗbЛJЭ X9poMzЄд"ЕІ"&Ер‘F3Џ q Ѓ,oјbRi–ХŽ\Ž›w№Е~x№O%дB‡*Ы\“ нOUу;єќїх}њєЅЏЬy9gŸbиК y§ы†˜Їb;]ЦЇЯGЌ^37nЕЋшѓ!HЕІЖ.;'ћ|нyz 9z fл Е§RYkhlшџгPІЩБ#Щ9;Жчџq_оЎМŸ­H]3vЄуыБЃЈ/њ&Жsу$\olOIeЉ}ƒ`Ѕ –ЏIQ=сѕ–Uы5ЉE•)jбBCЃмyв‘P $к$™Ч%fgQТЂй˜8abNAўтпЯЅЩЉщхcЮtЮdюЇ*Ї\A*HI:І}wжіУqIЛktDЄ}їјвюЊДš˜?JyЄЯ.Ьg–}ёПS‘‚иЎ9фjС*;{kв№lwЕ‹oЇR#itњ G1Ъ‚p‰(vQ!пВD}Н|є˜.>0t ]uБ7Є}џb№KлЖв)њ6.=}§['о!Yь(эЅiGЁа4gѕ‡Rћ&ƒе[[†іНг™ОьЌЪИш‰ ‘hŸф{юЖQ.илЛƒAЃ JЎЕиWхМЈ#ЪЊD’явžБ##wџ?фхќхм_ЖЌKзtЁCsІs&sWU9х цGАWй;™i EЊЮР=уюЊДš˜?J]ЭЃ& “‡СJ-И№К“кa*bbЇ/[QйŒьє$q! *Є":qЉџ›јн…{Љ–П^ќкЊДеLGeYcС UMoz~§щФ%(,кOЏyђ˜оЭЉјqзчЦХflлШоъ/^Ђлпј)Љ`RПЅЅХnЗѕВлiаŒЗsS}ћмSџMћЭ)дЈВ§DfnŽcНЙ93;“wrЕОўнOaЛekщX6ˆ}*fcV&­Cа­tŸ…Ј/•ХQbІФ0“bGЉ}UАbGЇrLєTŠ”…М1;“Y•q3ˆ4ƒ>јHиўтУ4ˆЯіЊЊtHQ‹ЦUЮ‹:ЂЌHд!Yšj_”№l~AўВE‹щ^N§O9уН Уo 6‡MТЅЇЁi‘"еLxе”#Sвю|UZЮ)ЅЎц‘Лб%С XЉ^wR;ЌQELьЂzйjВ&vбШzMщ+ˆ/жŠн]Ш‚ Љ4Ыzпишє]РЭя›Ž+ ќ€уЖpњQYж1C•єъГчk9}f/*xѕлoП]ј;КеsвДщХoџБр, К^ішАЩKшдЊѕiQуЂŒУ3ЉП)}эЮЌaЃУ$.ішn3aAтьyѓљЄQYKZšђc{єдiг7,|я. QуFЅЄІEŒЯЮл™Еu;•А0qШCL›4sњ}їн'ъKeђ† BюН7)!БнШNŠЅіUСŠЪIKCњ ˆž9њ  CжEeм "Э жЎ~я§ї"ЧЁПQ%ЃЊJ‡Еh\хМЈ#ЪЊD’ЅйЁvћнЖ‡8uъ4>;є)gМ7aXАt3Jч+х‘!t gќ#EЊyUЊІY–vч#ЊвъtўH)u5м. СJэИ№К“кa*bbеЫV“5Б‹Fжkъ_AєчУУ‡k:вЁ YP!•fYяїaNќмл6.œЯ[”–я|Ч6C•лєž№Ѓћ''YИЙЉББщj§бХэŸGTуб_LœЭПRЉЁ]J€>RАЛЄgбшГшЯŸœєјФЈ‰ОрЁя8CЫTK–ЇМUђІ &МŠL Еы'эВфg–ўўЧ ЫјЙ“}ЪЙPwaVЌіл;Еl3їд…єtЙЊєњПОњъ„cIиѓзхš!q–&@ѕћпџїП}Єћ‚3є]}ЃDЫь9Й91уŸАtrс|7Nк]ЙЛQШ= пй™gGƒ5АКВxџРсŒtпGœЁя’шЅ–[-ЦM %ї‚Ё}Ÿ€LZпхО‡Јхю34k ьfIљŒžOЅЬGœЁе?Ї €,>тАЯЬІ@ts лВŽ5іnC@@@Р+М^ЫiХ+Ž›0Ъ‡ц‚‰NPq‹€ ЕЊн­С,ойM&nvЗ8<Ÿv?Rуп1JЃ“6њЮDєz-їP§еЬ0ёWТˆЫ`ŠgСK|Мdж8?ы›L<_Ы}3Nѓ“Уrў{ўјa= IDATф)ЇF,‡E“ёюёпЋЃxеИ—:ЂRŸЛZїŒ" 7:хуš“мЌkнЙ{ў$p&>”чkЙO…g@@@Ря xИ–ГЯnє,~ˆ“яЫЋиѓ•:šй-XLŒt—YQA*K{I§яьЎо[WЃn]fЪщfЗ"=ъТЅ3ѓГ$(칋=Їл8hі0–’дSbˆш™Г2ПMВtˆЮ)Ё”ЙИS_ПНЗуМlšIBАйфщ‡Э@щЬЇNznЬ’”€J™uQюZ- КtцЅ­Пцйф\аДы]bšєЌщТ;ŠгIЃУI0цЬ4щ™w!ћЊ.R˜ЬіЌТб.Ы# 'ѕŸкѕѓŠљFЯLGœ;УёпЉл~hkv&P Е“Ь;2YьЎŠ‘Yp<Ым–NofмЬ;?9`FM5Щн}cŸјNJ’<\Ыйт=‹Ћ]нIзЬ6Рbјв]fEЉ,э%ѕŸw7и[WЃ~]2хЮfЗN7f–Кс{NГ,ˆ{ЋHъ)щгjJ3C№)a HsЁб—юЯ-ѕM™r:„tJg>YгsЃFѓХаTЛVKC;К#ы§—B‡s-ЖkdcЮвQЄ]T0ХсєQаYiЉ]хП~^IdуŽŽ}ЎњЩДoТКэ›h’?­>GэLžЅнЅ1ђ.$Hн6˜&пљЭЈЉ&9y%u;Я7і‰щuUіp-—пеtЭl,dr—YБ Щ.є2и[WЃt]w6ЛuК1Гд џиsšЅOм]Eв)%2eJ3Chц’єPš Іtnп4н!Њ™/хцdеЎецCгDjцPъПqG1зšN9ыћJЛЈ`ŠнЅQHѓHНTўKч•8Š(GDŒ;ѓy5Е”VК;ЈВвqi^§љjеєВ4FQMъЖС0љЮoFM5ЩЩ=Љлхп'žтъŽџ#н—з`ЯWўџоw ц“Цф.Г\Ÿ .є2и[WЃt]ƒР5ъnЬЌtУš{Nѓ=vY@@ФнrU$R";Љ43„>5њi.4jв§Й |гtw:„tЊfО”›ЫЅЛV›MЉ™CЉџЦХ\h:хЌя+эЂ‚)v—F!Э#ѕRљ/Wт(ЂrФюТн}rŠZиЅWsAК­š.и7шЂšфЊ.ЂЋlKn•І™v3‰6cЇK:ž_cзьэЊђЦƒ{ОЊv™U ЭкUН ќяъоКв tЭЎкBищЦЬв§cЯi}h*’RJšДšLЅjr†Џш3п"нŸ[х›&3ЃHg jцKЙЉH•5.щw­V…Іš№ƒьPЅ,uЩ<4•YЉšF“ЃЈ`ŠжЄQHѓ(івШвyeрфЈ1ПоšНsЪД)dgЪф)[ЗэЄMƒюM~(u[5x/ЊIЎ2о§ћФЋё*O\nЧўх.ЃГdGь9mЩДYгi§ЎеюФ62Мц“*w,H_Z12ўr*@8X4Lь_nбФu“лиsК›@c˜єWМмїНюяuє=k‡mќашБ{пДŽри›АчД7щТЖ–]zvпїљПOH§Џdэ08ш €ZоAТЏcЯiПNЏЯчё5оГђЙ }е!Уїе@сз<ялцq   рeЈх^ ѓ]'р‘?ї29l7Œе C˜ жƒj<(.xаИїLЉМUЕ{ЯXvŸЯЬлЄ[Ь&OŸсДЃSѓ#zOГЎЖŽЈхо#lyЫ–˜ЧžЂьgСz)/™ušФžзЉcP№nЫ/(;'{Эъ5.Сэx$|7 2˜RЫнGЯ,л1>ЋJ˜І—С@M•A—л5і]›ш#fœqЁ‹Г]вq-Xщ–Ч5'=HIŠNешt\зТQ з§эОуїxЂХi~=•>аљ џ;|„оЌЦ1НkсvT нп(ЕМћЩbDп$pЃх†э.пtЭEЏ<_Ыщs~ї\ђЮ`CYq^53лжв@њ‚йG-z?sщеЈ/)ˆЮ@еo3ЌХ >ŠО—jP‰Іb7hб‚Ъ§жТzћдвњCsTєЄжл ВGЫG‹дВоѕ’ЂюАзЙA2ыЫкх{ ;3E}ЩˆtњЉvMжИс8дmКЌм›w)—УбO3Љ‡дHуђIХ™SR R'™О™нЌ™ІС3ГЯјЁ<sieжL†#œЬ‚|zp_ЮЈ<њiS@ЇЄ3_oJ’ХK›4Х,Ћ†НRЁрIaЪм:$ЙѓЌк3oШвбљX|.ш_}фдˆ#“ЭМNљак0лL№Гў(ЖЂч њlъыžЯзrђ[П{.5l(+юТk ffлZщСl=„žљТˆT1Ш~›a§(Б№QєНTƒъ5 vцFT>шЗжл'#Д адI—цПy|VЬд^НэRЫz#Ј™M}j—ю1ьд3(~fXБюz2ЊнИ™ОцйГсшЇ ЇїљР'•Ц%=Љ“Ќ—™нЌ5іЭJУ1™V>Š™pЄ““Yаwч–IP9#ѕ\ьиnќ‹ктW‹иџЇ3oJŸƒщ*fY5„ш˜ QЩ]ђФЬВtt§(мщм–с]И`ўuЊr@к.}/тƒšœ\п{‚WjЙtї\ƒ eХ]xдžOып'”vя™=kіпwБ=џy cdf‡`в4PЙѓ4ГFщ6УЂ>ЩFБ$Ї№ћ4Н4iЮŠ‡;s5•в­…y/Qˆ›w№Еоr№O%дB‡*Ы\“ Ј5šтЁta“ІЄгЯ +ц€žŒj7nбacйхpЄгLя!]5uЅ@TЛМ›ЕЪ и. ЧdZЙ3сLNую*gЄžs—И ІРSгеЬм Pˆj*йШoШ]]:ЗMqџu*… }ёrM“ƒы{O№ЪџŠсћП’@џІŸyoАЁЌИ Џ‘Zp03eАЏЙЩc дDg ИKЗжшХвЇ=M—.ьЬэЈ|їыхЪRaа ћќѓЪNMŒŠЌќ ђБЁѕoл ]eYcФЕFS—Џn~пtфXiPPШрГv•e3Ј5]јИСŒ)ъ"~fXБсЄdш”~7njфWfЌ/{і`8вiІђPєA”Ѕ@ œ4Г›Еh_/Ћі—†c2­|3сЈ&'‘vчЦUЮH=чНЄB—LiвarКЊ†§QЁPхШ5OФEY5КfоE:ЗUFx/QОNEcYх˜Њ— CeЪЭvЏдrщюЙ&7”5ЉІ [ЕCАfѓ]•šЪЌО]ОЭ№‚Фйѓцѓїw“Бh|гХ[4šfvVљ нZXcŸKТœјЙЗm\87ž7*-п С jƒqљp$˜1Ejвщg†KJ†NщwуІ5<|8ы%>{0љ4ѓнЌХxѕВj/pi8&гЪG‘цWУ\59ЩˆД;7ЎrFъ9я%КdJуПЩщЊBєG…B•#з<GeешšQxщЋOe„ї§ыT<ыTV9ІъшТФP™rГнѓћ—S%3^zrгctо›~њнИ—%?ГєїЯ„ jрOŸђ ЭЯТщ†ў=Јўuj­x]оПм+п—[‹МЇ:vуо*jюЪн-BшYвзiЯКдmЃЃ–wj dUt-шйнИ­ ~ƒ€№зЉчk9и}xЖћПkо˜~оАйm™АДѓzJ~Ž>@ДИL Рч†Wю}s9ш   аUнTЫiѕЃЋžщѕЅFЄњОh%аMЕмBј№сРBЩ‚Ћ  DЕ\; ќK-ƒ€ј<дrŸOC^ЈхКэŸ™]лТYa„™Њћ{нфщ3h_v(пXЖэюŽ—ВЪоЎф@HІ~ШОЦю|cZйd„,Ј‚еŒ…CpŸ€чkЙtZrTК Ќjџ]•Вѓй'Ÿ>Н,yЭъГbgГјЅK7~ўПRџTўЇ>8Eiу/’Љ…б?;н˜V:Г# V?Z@@@Р}žЏхв hЩQщ.АЊ-~UFh{єmы_й•Kћс№рЅЫЗнНЫ–НљХ­Й; ѓ vцю$йv7ЃœnL+ЂЭŒ4Xэ8O№ќџŠ‘n@KЎJwUэПЋ2r№е=БOЭЂmцФиЅЋЖн І­xrrѓ_HM#YДЃ‘nLЋBЌЦ>A@@Р#<]Ю6 5щэПћqХЛtыxћу“*жQed_AQљ‰ђoДSЮ”iCb.С }яlяЫкы/^*љSљўїЮ=Џф ь”ц™mLћAХ;kVЏйšБ^s–йЮОЌLѕ mBЏ‰№ЯзrщДЊTћяЊŒї Іr^ђЇ’їs›в ‰ЅЗЖо\Е>mћцŒБc"ЉBџзšUЖл7ЙрtcZщ#8o№|-—n@Ћ CЕџЎG9%Пф­rКoŽ™•nH,н8kЧvк‡;,ЬБIхи‘#ўsк”Э;ЖЋ|sК1­t•5Дƒ€€€—x~џr/9 Г   рп\оПмѓзхў б€€€Џ@-їЕŒРшЯџMZзЦ‡6€€€€ЋъjыЈ+jЙЋќа@@zšРр!ŽИ‚5іžЮЦї –ЛЧНA@@ Ї  –їt0>€€ИGЕм=~ш   =MЕМЇ3€ёA@@Р=ЈхюёCoшiЈх=Œ  ю@-wzƒ€€@O@-ящ `|pjЙ{ќа@@zš€хџ‡+§+кsћЋ1ЦЁџ’§—;c5Ÿ:^SUЅwIеЎзD‹E ХMм$`љZN…|йђчŒ юЪ~Љлj9оˆsс;g}?SОяЁяdž€@€м5vzЃдч^кЈW3h‘^L‹њю!Zы~й{ў{Я2ЃЄБя4SRЖ#RO5КцЁЇF‡ АќuЙƒѕ- ‡Ћ   рa{]n ђГЊOчЬ‹>9vFYY)W.Ь/ˆŠž16rэЦŒжж›М ќК„oьšтPоœ™aЛэPagщ™Ћ]Йвјмъ5у#ImYъŠццfnJпŸb‚д•чb_§HЩсЩгg„l_œ0iJя?ХЕ93+j|$=H`aвX&‡р^™ЗЬЛ Єwл–З+—2yфУЬіЬbrыЭЄгњCg-S-RЫ'm6):ВЯЈ—<• tbЧvYЮя—>SљA%з$o'ЗЙЭ[ €дryКSзЌfщГgOWэЮџќќ—Lщ@бўъ/k:uВ"ШnЫЭЫ•wюh­ЎЊ>іњЁŠВвІЋпхP3[5ЅgО|КdEЪТИјГ•ЇоЎђГЖчхtєЖщЛѓS$Јœ‘z.vdrѕЕХЏе|тИНЮМ)Нџy/ч6]Н|ьh)=._НL‡|,3Cpх.YцНTє їдўу"eъЃп^§–єѕіЉБWярЉ“&.s{іsјЭуГbІіъm—ZжQЁыАзў[šJtšюњpžIXє‡Т=\э•НЏЮ]0мц-@ŠjЙ<нAAAзш"ЙЙџаuiЉLщрё’Дд”р>СНzй“—І”Н{RоЙЃ5myZpл х'Ъ;šяј}є@qиАЁЖЛьєFœ˜xњУгќДqw•3RЯЙM.ЌLN!зиЁ;ІЪ+ЪИŸ/P˜яviЎЌ ,seН’ух/ЄІ92елžД,™ыы…Ийq_+сэџTB-tЈВЬ5™ BЇQуˆФ™`&@fGЮ№№!і Ъ“ŽKѓ+п4žў?Їgߘ­‡ CРО/oНнъJТЄЁw4цьиžџЧ}yЛђB~Д"uЭи‘#hˆы_7Ф<л9V‡rgЫRџŸ†ВЎ76мyВ§ЈІЖ.;'ћ|нљџОсhlwW9#ѕœ/,Г+K‡ъ\ЛъИЄІx/&44^Sљif5ёаР2WSбkhlр^qeЉ0hа§ўyхЇ&FEвЊѕcCЃOoЄЉВЌ1ЂЪ‚F;CŸ fdvЄс,JXД3ћ'LЬ)Ш_ќћЙєљR3(A‡€P:'шЖHўЯѕ/ zр~wнХ:jd‡ƒ1јЅm[IІЏŸггзПuт’ћ„Ќи[$–(оW*а{'њJuVЎZЙbљŠШс#ш ’О€=†ЋwW9#ѕœ—pn\КdJьHђРаОwњйWЃРUCH•YЃЫ*zCrЏ †`ЇтПЛp/еђз‹_[•Жš5Њ,kЌ™Œ‹;CuaFЬиЁ) gьШШнџуyљ9ї—-ыв5Žс@  юћмџŒ]Еe§ЋЧэZЗзa6n›7—ЅŸnmЋЏПф8uЫжrЋ}JЬ‹ЭиЖ‘оŽщ˜>Žё\ЩЬЭq,г77gfgЦL‰aЪ}ћмSџЭ%оБЅЅХnЗѕВлщіЅŒЗѓvЄнЙ‚ЪЉчМ—Tш’)џ1бS):цF 3zj—†•]АЌЂћTЬЦЌЬцыЭtнЧFбичCгzѕЭя›Ž+ ќР`жЎВЌ1ЂBЧ3AšJ“шШ‚4j_”№l~AўВE‹mwiФ!€@`мыђysчлlпА%§Ÿ—ОЁœ?xџOџsімYгЇБќG•’šіЭЅ<јаCY[7БFъBТ‚ф%ДВJэєNЪкUЯУ2§Зq-џЏeк“’™ZТ‚ФйѓцгŠ:ЛVо”ОvgжЮgП^A—’ДRzМє8З&эЮЯЊœ‘zЮ{I….™вјŸД4qѓŽмш™nг&MЃУ. !*Л`YE/aa"нY6=оёЭwв’6ŠЦО8єœјЙЋ7oќcоxЃвђщSЁуv˜ MЅItdAЕляЖ=єрРЉSл'­fP‚н?9iЬТЭMMWы.nП(QХOШ4qB4ПgJЅжэфRТгIЦ#О’7+ЖЛя ЂЏЈWЖ}ЦYП!рН™@ЭјфЄЧ'FMєVœ@MЭЙ uœЌ™{ъBњ К\Uz§__}uТБєhљыrњ_ыTЊгO:Ц 8 –#@џірПџяOŒrме'`љZNџhНлўзz€Я„я;шZр§sюМСТwмƒ' нLРђЕМ›y™ ьцYљЗІ7f‚7lњwј7дrџЮ/Ђ№g[ЖmЁ№PЫ§9Чˆ @@РП Ќ]Н–D-їя,#:П&аъјЯЇЈх~c  рзиџ0G-їы$#8џ&аіŸIQЫ§;Щˆ@@РП мЄ№PЫ§;Чˆ@@РŸ мlЛ.мНUќ9Зˆ @@ рК<ВXA@ќŒэч‰5v?Ы)Т0јО<РŽpA@ќŒћОkь~–V„  Hpя[ eБ‚€ј-\—ћmj€€€џИ…џсъџIF„  ўLџУеŸГ‹и@@Рўƒћ)LЌБBЎ#€€€˜=ѕ) Ем?Г‹Ј@@@хЩ Е<rA@ќ“РЌийўЛfQ€дђРЩ5"№OЈхў™WD  8PЫ'зˆ@@Р?  –ћg^€€@р@-œ\#Rџ$€ZюŸyET  CрџјfЉІ˜ЭIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/5.png0000644000175000017500000011635111733011756026160 0ustar sylvestresylvestre‰PNG  IHDRjдœzѕБРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН \Tек?О-ў?†№=ŒкqL}!ЕЉ ƒ!•AKСМPХK‰™ЉбХkš)ођ’ŽšyщІшk^*Л€vЭ …“ЅxMOЪLoФЬчрЧџwГ†ХfЯž=цЮкŸљРГжzжГžѕ]{?{­Еї~žvмgЗ8vp\АSAЈsHšsupHЇT2ЖJJCЋjЗЎВAP]бD8лU hЊ„џЖзTђ(йи§›-UИНeВeЊЙЛaйГZБ”умщxUV“!р3˜ЬlGќфх>Ѓ5S”!Р№xѓAlG­Nяњ0 ŸA yёТ… ?ŸщS”!Р№ЭцУ`hнŽ—Yjk*8–kАЧ*(8ЅЊC—3a,ƒ!Р№:šЭз sЂvЕ5UŠЎУ§‰œ"ФБ}mEqэхГК„йQ‹Б2ž@@h>,Ж_f_з€ЋмНcaюњ§д%ЂЖЫрњќХмџЧ%Ў–ЎіЛОУ§Щœ"PКдRЎ"ЄC„њъw>јаЫR—X>CРo˜[њ P*• —#ікЂ€]Г•Ц*Ч^ерџаeEЖєР‰<Тv…tы›Jв"Щ2E"NЧ’D>Љы\xх5—/ЕдZЫuj[jКЭц Ь‡€4ƒЃгhE…ВНВцWƒЁц|}щПЉЁВT+€ 2“bKF=˜ SJьБМ™CW5›Œ>эЕч *aЉ{haЛBšД.дйhфЪЎшГ *Џ^ЗЩ Ѕ iQПdŠDœŽ%gm8€Š}кs_L!ФœєN˜#й„%6ЂЙ|ЉЄ@™LШ„>}ZЂ­ЋС‘бЄ-I]Іц§О{ WЖчСŠ.Зw1 А#:.шŠт^s^WчГ™ДвGССdрtиОJ‰­–cmƒЫЅVЋЋ 0 ]"†ац:уЂТв‡ЦЎ|4|њлeђіCи#yЩ(ЕдhЋ{fљWш+˜ЎL‘™6Я‘lZШfоAa)ЉюXПšj™nJКћЌDРџ2m2Aw†ѕюЦ%kТЋЋ+#zET§RUcЉеЫмэ›O8!jžnQ%ѕ­АtуœEК.сЭИtЬЦqšŒЦ›Є№n~œІј;N6:FЅ дзœжюљІ ™}К)7NŒЌМbœў~Б"@qфХXdŽкP‚Yе–Iъ№ЎГv–Ÿћ…пNFѕ)CCAшыИ’‹к GЋa@‘Д§ :Ÿ:ЇMЪ…vщйxŠюКТd#mъQ‹VИ‡kzЋЅЦMВ›Ј.‰I БжК%Е‰ц$Щi…fAе7Œ?ЋќОJG[N^hi-aiГ”FЪRП0EЕ„Це{6ьEэБЄЭOCЙ‹ж№ЛОЊК*ЌGиО§ћњѕ‹гщu:ў•~и Е X(л‚BJюš. s‹Bˆх+ZлШЊkPе ю‡ЄzЇИдtв””Wя+Њ4 ˜žмз?vЪ`UбyэђхcbCЇ ЧшнoДч~1Р„wь`ьб+ŒhћxnO™™(тЎW)8ьDHpрœхœ^лЏ*}h$.н%WЗа™ом@K({‡ѓ“ЊЏшБM9њ(єТ›Й0)ьQcsг5сУ"UGOW~ВђMИц>оЈ‘ЂqУ%ЛйФР 1ЖHd QЇDIT5!PrОzп—•ї†…LЛhTјИ7‹‡Ў*9Ж€7ЭЏnЬ1pŠ> m”)mд'PІ_г5Ё–аh9цкЪі•кŒ€ —xЃ,gP†Јpмныоˆ>ŠjEЭZ\Жп…LфчЉ;ЕЪ†kTНOG’Lšc•X6+ђрфЃД2@з!РtЯЩ?YЬнфъ/вдћ”р)>YŽ7P}_=ь№феgХU˜§Є}_&VъоезŒuOеПєZ˜’ЪŸЊ!0( Фа иђeѕ]z\№_•UС|€ЇG@ЩЅ†г(Њ†$!дЙр8Џ3н"jSk(ь…&b#љFO••a+ъpqЅР|pЃяу‹$ЛIъ 1щ` -’Rg§-lDўфEУ˜нРžМqЄІ’#ЂuвœЈƒЂRТ#г/4œе&GљunъДZEчЮе§е•ZmуЂCІJ€щv$л!žn`ѕ.Ь„LдЕ,™мФpƒdьчб[пPS-Ь;Ў6tЉхpёѓ'1J^~zЯаx`6q—B[k;uQ ѓЁ E(*ЏцЭGя№~Wј—ї+*Ћј&Иўa!SуУТ:вѕB` зAaИ*\П4ЕЫ‹вЭсбЙ_xDњ№ШФ!Б'w—д й„ДH‚А(ѓ ^ЂЁЮp•SжъpЊFЫ)йMОj 0сгM’ЭсЇфКЖй7х5ўob6eŠ’ШmЪбA7 пДЁЁž‚єV&h‚' \ бMЋч/­7о9PmŽ’Ь™ и16pБбсАиЭAЉц>NŠЬŠ_ДhѓЬРqšn>Tўcu•тvХкч†A8цb9‰єhJBкW•Z˜ь} Mы,Rо!XЋІЪMџБЄ‚2Ъ`Ю  цgUєщ&хЁ˜аaО)dР“#ЅTЗr ^gdŠО•FœI>g‰иlLЪєK …3ЖV"p›ѕuкЊЪ‹•Ц#і>0ѕЈбжд\Ч щfчN“8›Ў†&ц–џЯЪ–YЂnSX;Ÿа”ˆиHђР~Ÿ"IЃ6мЎфnWмЊš0&ЕјгК+ОЄWuфoм5ПшЌцчHV^вnТЦ№“г}ѕІЖcИ& ŽаЙGOОКіжAE€AЋчб‹ш†лg5tCN|Сy~вЇю…eуXu‹=#ЙnЪ‰ф0уxuуЬ№SrXZ4пЄѕЄQА 8ІkxЪ*+eХѓ…0Ч8pзсџ™ђЅ2§’AУЌ–сl}( U'гоGTTTHuШй*x1Ьвь_Џ8|ДІЎYЃkC8жЩŸ†3ЕьѕЛNУ (ˆн)Ќдkў‚эLУMне†Ађjcdh`ХEотЫhљЁЪйУУf<.~хФЌЙ гоGWyEН@уЕюѓ*HNЅI—ЋкЂlKбЕА`NѓWlšŠ ™|7[H1K\jPТЂ™e‹36|Y­hаЧў%,ч9~нѓwрлъГпу!Д•БЮ9Q>(єх‰ЃQЫ|}$_*г/4ФЊГДkhocфƒ§ЋUќ5cщЇ:о;МђЇJ˜ <…љИЄLИк }KЉЏЉшк/Q$Mй нёt‹ѓ>uЇ™`г4яD^9[dсЋЙŠ 0ŸoM:„љBš(€k{ŸИЏђ—HПЅŠ 6$ѓў.…ЎЇEбЅFБ§xрТo.\5„†кЛt Сƒ …\iDa[BšДKў’|R9€]лЦ}Х]кvJЦДЅO#КДPFІ›–tъiN›Уol“cшкrhН'‡'GX|5fѓwb˜ЂV„I,‹0Е! œ3№O l/•щ—$ЫfёЏЗ‘+ѓГЅЉ§o-‚釈l!5А˜ иsВЊƒN? џЫ|нЏКЋП^­§w-ї_œсю#\Џ>\нӘƒЗЈ‚Є™ кТЏфД:EГср3q^Jе%ќ—8•‚k\1Е.ЬвЄЮкЋАP JМпХ?-ТЖˆТа4Чс-QЃёЊwŒHˆ2@ahЄ W9•Љ.гƒЃщf f>BšДKў6ч7Іk9ŽЗB…†x­l–ŒŠXЕ)Јs–fedКйЌCKм„zšгC7” фэЕс&ИrчТаФEŽыР*u† ˜ѕœва(VдŠ0yБ!ф.~7я)ьx-z!€NОTІ_’hЄn(]FCЪл мэMg”yїXNЋАr6е7ш:t{;(Ф Sд~зuщt7.якпkёБœЁЫе ИоЮеžЛФqЗQ“д=Іщ†ќ"6K“aОІеqžсW+ЕдтЯNС[$ЕxЈб’­ё"gЩТЖ„4m„Ѕ|9&зžhђE›ГдMh]IтвЭ&{Э[ ўВС%Ќ%jE˜D­KQЫіR0[ъŠ$бPp!ИЭдпlВ­B-э<Ќ˜ЮPХ]Ј­ХMЗ}а7џ:іPїўS—ЦЋЋоPЏ(УУ§њњ†Zƒюl‡;ћЕдЪтШ™ЯAZTф5ВXЗ'KИсEюњжœж‚ЊэДўЛK5ѓаЅізa˜]хˆ“ aИ§дw7ю4pкЋ5Ѕѕ—Б,р:t7sЯ!xБвюОXSЪnЌC€!рWЊ€Є ЕWqэŸСcr`нЮэљ?Ш т’:№Єд-†<žД{СNMЄ”‘j†х1C љ2U4}Жр]ЊкЊъaЁvYXœк_ЊƒXoc› †€W#аl>œЋІЂ}ОВЛrкgзЄA]ЛЊ0f†CР#ИЪ| 3АЬxdPYЃ ї 6ЕПЪН<цX+ †€O аТ|Рv|šйќЂЁOt€)Щ`x цJ~o|ЇгSъАv пAр6пQ•iЪ`xтйGkД+)/;[vЖ5dъі‹ъ%УРŠ 7#рLѓл‘”˜фŠрх‘УŸfцУи2™ ‡pІљ J№оЈœ~мtКD&!Рh-rцcнц—ўu)ѓЙL4rј“У]”ЪДдДБ'эyянжЖЬъ3>Ž€M[ЇŠл9>6e{iЯ@#0tшP‡ы:\12&ЦсКОXбGћы§j{Г†nгMж|рУќЎ№›Ттв2|Щіхё/ЧN™ŒЯRъц8z1yФj˜+ыjˆ]-пМGvхxЙzvѕХя™НvАф/Œ^UUЅЏ3cSvИГCм§q2&њж-ОхујБcјбъ"fš/"lyХтђгЇEr„IZŠŠ”2ШгзЎh'eLќ4їsоŸ•р0жžš6љн­я9 S Ц>ВКК*{cіёяјўЦпƒѕfh3 -E:ІžcX‘–щнёЇ;bњѕїтќаP+JЖTй™)ЊŒPЈc˜%иKыѕњ1{т+СYєђ‚WоXЕв$ч&7dФ№CћїЙ_1;"g>ТџЎъ ŸкТи”p˜%ћеLфёЏ›э…X-3f1IлЖuъN”;wUѕПџўММмбc’…:яџxŸШћm М Ќш0 C6ёйgf?7sхrўД+((˜8у™};vBC‡eКЈ" XX 4ёю бSЅ5Бѕ(…„„мпяўЂЂBЭxюуŒuzјеыч!Щ‚Ђ‚ћяПŸа­oЫd/ˆъz] ЏШ$>‚3№Б)ѕ:#ŽЕтˆ,БхБыНc{"щсфЌзW­’/Vэ&З|uVœ&aШШс9ьЇЅфўCџJоŽ(Г$1iтфЗwОнЂш&З{пСg&LDІPрŽ­л‡$ ‡ —f‘о=–ђ(І ЄnСg„@ђ[Д!‘§южŒIщЃG'Та+@ Йэн­ДjЮЛаwД|ђъё<7ЙM›7Bэ!I qk VІVџСЖІpЁёklЁ(%I-sє_rКx\њиИbFЄ< #N8[ѕ—?Oжy(?(вљMЕR“GG=ќё‘‰АВђ l”Џ Щ}ŠRаш,КŒŽ›ќTѕЅІ(NrIхxюнF<6A!ўo0žƒЦІ C€(1“8‰№‡ba’ЌWHŽЉhзо}ч<ЗsЧЮмCЙxХcліRUФЭи˜оДc{эЏКќМмCџГяфщ“ЂZф.„Пєv$bIbvж5ДgбW…”wўўQ}DЗ§œїw•ўxўао}…GѓƒмЦMС?(aPY)|=rњњEk–›‚=&фSi6'NœHN|DШŒ$2iNщщRє Aѓ !ЉŠvМЗ§ќЯ— ічхзќZƒœж`%lГœœ]}#lњКЪ’zs^yuњГЯ:qњ§-[Яќ№ЃPОcєІЗ6жўzѕаGЙјС8’DŽЅ|кJ+5б H8їУXХ@рйГg4 ј 'ЦХŠPJ"ФЩяJїnП№ыу=ја’ЋHІЅ“\Ry'ž{жfzФІдъЎыHlJl… жЁСКiбхјСёєзЂ )qф№‘Ьчч‡t С*iкдiGП>кTbпиfсT>ђЩ‘y/ђГAЏН8Я>‰жИŸ}zђЛ9ЭЯАпЭySQЅн‡Ю›“вНSЬz63япЛИИС'Я”‚Ш-8ЛКєЬIф‹Њ[M^ПqТ…lHоИqцаюƒ4Ÿ’ъЁшрс#ЏЭ™ЧЋЌ˜9c–Ј–cI2:1ƒуwѓњЪзmbI=М= НŽ‹NпЙГjбМ9Жˆ’ч9’ŸGТyr$џсЗ”OЅЕV“лЙQЃFЭ‡РoJПі™gП/§tюЇ‡‘/кYCўтйІsiТиДўiђЇcщ$—Tо‰чž•НUз0L=‘2ХІ Ah(;у_—ЏqY{9хo)Э•пzMB{№ЗœМOsБщтўШ>ьЧЄ†фг†dс` OrIхxюYYМРcSFDD МX §ezŽЂ”ЧSVЏ]UшъъъЌхFW^‚LщЈЄЁЋ7fѓг\Н~ѕ†ецœ:оQ}ХД‹i^j5їНкЋW ŽджжЦЦHмЧ?‘’Еj)дъKUи=%2Ф\Йa§Шф‘HŽ1rхЊѕШБкœ9УДЉ“vМƒ5\‡ј@2ѓЉi”Sи§Q#Gб|BXR/х‘QKзЎЦD[иC%Ь­ФŠ6 cŠчVXВѕњkфЎНћЁ6ZГNbt,ЉљНgь#l`гM˜Ъw€•4Ї9O–nX$b)Ÿ6сMOЙю›тюПbуњ XЛu#rhV K'Й%хuюY1ич ‡Z­ц7Y8$|x#gicгЂя‹Юœ•™48~ёвХ~а1щТаDШЬgguhЏHŒьб1Ь%gLšš–>ђ›3XЭyjђ”E‹<•>N’3}ќєnвЌiи-ŸџъМ!ƒ‡Жu–‰C’L–:A-о'“(Ъ эЖsыЖOПў2aD~ Ю`ЃяыОJхЬŒЉЂъ–дۘ<Еї==ЦŒ}bјccКtщBjЕ+књЃcнsрУ% |ёх ƒуЧN4@jt,Љ7d№€Ь9ѓтХlиД~эЪeTЌУФЬgЇvИѓЎЄЧ’ёЛыЮЛ$Ђ,хг†œЂ N€њпЎc‡bћѕтўј9Д Ћ„Ѕ“м’ђЮ:їкvыЮьYё“—зjЕ№6ібгвНфZсо‹я**:єV0ќnh›ВіЁ‡юOR эhb&нлБ{ОИХЅеокЫ`Ќ3т‹лŒёЭѓs{%0~‘Ф”+їZˆŸ%ц˜oK№<ияићЫ›m“ŽMyžћю|ёЙ7п5пЖ{эnЎ”YN+Ж>ЬdБ ŽCœsЌŠ V" m>ЊЏUЮЩХІЌЉЏ­Ћ-Љ,ŽэmЖкˆŒ‰‹щwњдqQŽS’––’ЯbœвЂO ™№tЦœœѓ,жЇq`ЪЗ\t‚k] )ДcXtЇбј:NWW;јЁ‡УBТ 7БНWЈ†š›UgЋJ/i/qŠ№аA% вEЦТМ%f&Ь1‘Щ9UT(SЪŠЖ €‹Nк|„„Ј2–О;ErQ‰1ЩВвйђEVШ№ЄЭ‡УНУ+чxєхpuV‘!Р№!œi>рЭЯG\дyw‘d&–!Рp gšЧ4АБќ0ЛЮЛ:06Ї Рœц;FoтLѓЫ;cJ†7єŠщрЭьx{sšяЭdЛnbѓX-ЖWfœ Ч`Ї™cИy[-Бља ˆuXEЖИpКЖVБ5ЇY[УЪ›ћ rФbмzѓhљnь4ѓЁДђЩœt’ѕ‚!РpЗеЙB*“Щ`ДЌЯ>рU:ѕm€˜КљзHwжt№8LoFРКљ€іЊnaЊаPoю†лtsУ%э†&мkШПАn>Ы'Д‡gl.ЄГfˆР‰WWѕХъ—_œ70?HŠк2O–79Ї5/’Щ‘бEТ„8ж„LыЌˆ!р"Ќ›4Ќ­ЎЦЯ#ЋФж=pр€+:эЪЕ‰<ЂА ?H"гmЩЫ„Н ?yNVЪ№*l2TcїЏbрy|їЎн0]T!БcѓІ! ‰‹[јъB€цБ1бIDsјЅ‹еШVН%яШŽ~tt`p ~ мЖ%›ВхьЮ!Т—ЏXNo чц­ѓuИMйМVCт|ƒ R…L1ЈpBиe“n‹3‚!р nГНQЌbpag-ЩšџЪ|zS…sооС‡_кЈАЈЁR6fѓю| TVV B]П(kБ)Х_тЃ+=мТѓ’тшJЪ?š_ћkэІ­›hЛ„lEx#ћќЯМVŸZXSSƒВ!ѓ ‘“–кВБ:ccИыцCИf!ЋЉbIldtфРwМ-О€wˆ№KѓјрRŠРY/ЬЪћ<тХ! ˆмЯrƒAdRњ]i\\œH>]ЉЅ[V$[DW‚№Ц­ •ЈКdыр9јсСзМЦk83sЖЈ–d’LLdІ'–к’”Ц2nC@ќвКdУdЭл!Yъ†Ь™гfŽ›<.nррШШцчЉ|!aиЦЎЈcдMс—>YЛbэ–wЖ`Uђ}йї‹_‡_тЃ+щѕТр2HЖŒЎд™t­sчЮвб•ЬZ?АЇГЉЂШщ‰ ГdOeјYCР=рšГт‡kЯ?Е рг0ѓЅЬН9{).|Ё={…з?Š0сУ/-P(ИиБ[Жn(:^д3Д'ђiEB 43”єёщ4Щ–б•ЎuюЪ‚kзЎIGW2kЬ|РžkІŠTr+ ЩžЖR&ЋЮh=ж/hУƒO^hCCCЧЇ_‹ачMЧјqуPŠVвРaЛЛЇЄd@ќC+зЎ9њq$GŽx|хВ•т%ТЛ ˜.і)ђ>ЮCќ@ ™9=ГI<‡ШU$hˆQ˜EWВа:B^-]Е;/Й){‘ЦGWjХмЭROЉЊŒ`x›ЬеЬ§O^hг RŸLEшsš“>)П4uRм€ШљЏd6‡_ цУ/%&‚3ёсD>ќв3w№{ДsЧЮO}š˜€ˆ;]Љyн=цБ1IУ’:(;`ѕDл%„Ѕжёј†Ўєи˜с#†wщr7aޘ2 ЁА$ЉˆФJ&-Е%ЩЬ2nC ]pо­;7K„‰’д€Ќb,m‚ L”пЛ ŠМ/ВќLЙ$8,гF0ЫcПlФЪЫйФь›ЋK>xСŠ,)ЎšзѕГœЪJDWъюgbнa8Œ€ѕ­SˆЖњфEqЉ@Сёя88ёŸъ[}ZсDMЈЈ у'Ь™=‡&СhуXpkѕЩ‹Г+> |r>ї3' 1ђgУЉ’Sђ Ќ”!аІАn>YГW1BŒ 79E]ѓŽІАˆб †€#рŒ'/З+И>уЧїљ1LЌk †€9Зq6Э?јŠ2пМТгtw›Kg9 †€#`}іaг7/Зs\x‹ЯЯќ2ж5†C€ `н|€ЯІЗХА„aC€!а–И­ЎСJweж,VjВb†CРЏАiчCўЩ‹_уУ:Ч`XDРІХ ­mг*†r3‚!Р№klš}ЌО?цз@БЮ1bЌ›слb2пМˆГ4C€!рямlCйšХ C Э!`}яƒ=yёћ“BўыDПя>ы УX_М@4{ђт0ОЌ"CРА/DЖћW1‚ѓубВк5ИD\8чх! ˆ}9.}\бWEЄ|чгs IDATŠѓ KUиˆX…ЖУ`}ёBБpџ*Ц{СQМ™\г&O0hРЁмCЇN–/YИфГЯ?vЎТlDœ‹ЇЏKГУ| ЋXХИѓс‹| 8м%СAO٘lр‡?фЃF№wцБуЊ/Vњњр‰є\SІЭ§h*П&€ яОbер!ѓќ%Щ9№СУGРїЂHˆ|R~DфыВRџCРІ'/žъЖcрdbВќюфо{ ‹N?”ја’ХK<е/Е И‡ёЂEqМ„ПBLЅџ,нЛoЏН~[­ŽˆЈi–єoьлћp3Ž‚“‰Щ†ˆЙ$*мў№Oѓx\o7OfМцО0—ŸЄД<Ш …ЮSDI№Z‘–ђXЪЯР“ƒА‹%хeТЄgiЧСЩФdCрHв#DњУкЗ‚žэЛ­™ХЭ“" ЏE8…гиa’0X™…E^uš cД]ˆмjФкU_Ш|ЖьЌ0йzкБ@pm6&р*8Z€h8­Gо’Ћ#bЉЂ(П5Ї™HKzБљ0ќn%fЅ;uE И‰“'*ƒ•$цSAAB„ьЫiіŠˆјo‹—№Сk…рHL6ФЕFЌY<ШмњюжЫVШЋ-МгZЂх%xC)BфMzъ E pVўTљўЮ­dї”„ЙCdЌVъiuDl”яUЇ™:36sФцУœУƒ9$мъ Ћ—­Y5bю‘ WџѕЩЃ“i 8Фd3ЂЯнИvЙWЏ{žЪxЮƒ]pgг‘ЗuћЮьйыж/ЋЏџЃoDфSг‰$ЬнП§aОБKCЋ#b—4ЦьыДу>ж…m]?yy­V[ћkѕGSТю’›ЃЬ Ї ыЬ*КeЮ§˜ЛЈХл‚oКH2Ы`ј9оЛxСфBћVNТe$Г"†CРFМз|X5Vl„€Б1Ž!`пKыŽЕСj1~‰3~9ЌЌS w РЬ‡;Pfm0ќf>ќrXYЇю@Рѓ!ŒVIT3Яq‡ЪЌ AРќќa9ТБѕ~4ь0ш˜ЙЗ1ѓaџЭGРќќa9BФМ ;мšЧy1Яіœб yЬЯ–#DЬћбh|Pwчћ^ZЧœ DпhWIN~QaЦ” šЩ†€$xi=I“`~ўА—ЅыЫ ёБoёBЯЩ9-eC@ЩѓGеђƒ`Ц#Фа;бАcёB;+(iѓЪЬ†€9Ё=ZИ0?XŽ4ЏEУ‘Х‹АcBкЭ_м ›fД!РОИѕЁС’WеСХ‹МPVЪ`ДYМИ%ЪоИњјЉгh4>.&sжМаž-цНЮU†~ц{ЧŸюˆщ3oСМж{ш’зy-‘Ч‡•z3^=ћ№HP"|Ш‹_aAс€ЬŸ;п›ЯЋtЃ–зЋДbЪИЏ6ђA‰pОК.L|ВЇOПpСЬA2юзРmЪо4фЁ!Cт|CЧI’кšЉ"—ў‚J№QТ?zсЃр{DmЏ6Vƒ•ž.=єбЁќЃљЕПжnкК‰ ш”0QЦ:cЮћ;њіх]Yˆ-Рѓ?Ÿ?ДџачŸждд8а:qYBц;~Ї7Ъ,ˆг!ѕf^m>Ќ%‚;uФ:ТтШс#шV†‰"s˜И˜нћr^_§wШД$№р‡_[№w*8pfцlЇДюЭчŠК1 b#P~Рце[ЇVƒСЗ8ФdИЁНLшV†‰"3lЛ,}m~ХOU- МЌНŒvE'%fАљw*А&сЧxЕљА”9Б зЎ]Ct(2NN Б+_п06mЬЧŸ|nI`wUwДKM˜[їнŽйп;4ЧтЅEJDИЎ ‚a;Žи‰Р’†D[Dt(}уa& –[›xюЛ№е…”п.Ћ’ўqƒ >+ qЇЬІ<žВtеR§u=tл”НŽЗФlЉiРЩRЉoх3лс[уеzmНzіa5(QtLє˜ЧЦИ.LдЃ?К!{Уžœ=к<юОмДy@щЬ3Щ`иЄЪYœZ*ДRГ­аЋуЅѕš;w,gaЂ|q№|TgівКœЙк^§фХ\]–У`xЬ|xЯX0M>†€›ЖиіБsЉыwXй:-9]\UХћcCР‰8Ип‰в˜(O! g>ˆэHMIГQ9јћА‘“БЕql?Љк8P^о}ЙХ цl˜Н|ќ˜z " g><Јkš!Р№~ф/­зОЄЄЄѕB˜?@ 66жzСК BРЕцƒ4"ИY’ РЖN§уLp­љ№ŒX/œŽРŒY/;]&ш~˜љp?цЌEN_Їg(јNл:еГѓСN憈=8gілБf/зЃН=-3оЖŒРЭЖмyџщЛfњ:.+‡;\ш?ЈАž06 рјьCбXUЋч6юхОћ‘ыдСhCsŒ…!аˆ@ƒї:Љb#d;Ž›Cg4rл?цNќ8(ЦxюGлeœо…я€cJ†;ubЦУhЛЎ-ЧЭlЧкНмЙŽЮqНЛq­ыєd’]‹€ЊГJ{ŸkAі?щšуMnзgќМ#e0ЇPrŠл ЎЪщЇ_WRZRuБЪ№ЛŽS(T*UП>§DЎ‰§oHZг#8~-.)жjЕœС ьд%Њ ВщРќBКŠГFЄЁ5НduНЭж,GЮ*ю6~sыPи!и Tp gwЊрh2D™њd*юFЃvЄИД8ЙGВСШ&ПXУvфхЊc’G%‡‡`6QђmQј_Т \Ь/ЬЋА‘РН g9h>€и зQx•уjq'Љу‚ъИ‡œЃі—Њє'гœQCoh0`іA. \pn^xВPћ &<ШK’˜ѓAј9кЇŽц”—”œ­Ќ€яѕАА0MМІ™Чй:{P^YiYTul|,РбџІW(šЁ‰јЛщM>ўоŠU+№—ьq`f‘00ЁЌЌXїЛСЎ]™БГуlЃнNРМ’^jіi7ѓQNhм~"Ау з^ЫВœ='Puы’їY^xx8тШс‚‡ACф^šћinЂ&1<%ЦЅшxЎFб3ЂККќ<'Ч•Ÿ/яЁъЊ*:vДцК.cRFШŸBђ>Я+//‰ећКэнмИЖ‡%Тvшъt&Mс‚€НXИРА‚ьqшuњєё!Cьъ“Ьˆи%уШ?@РAѓСнЮMHфtzcоYN1<$(ЋЏ3rЮоћH6КђЇЪЂЂ"ОFЁP†ѕ ‹Ž%‡ддTUGџюѓM.626gїŽФ‡Ућ„#,KTd1 ч*јЩ‹бXvЎ"5%ЖїdH8p0G3$б wЖЕѓєщ`0`0SГЄˆps†H’iх‡•Ё42a!9d’"3"ТŠVi6їА ‘O08j>r1›•ЪqŒћ?зїz<Єі”Лгй]р` дЈoФ•_RRT№UAђУЩАзДзђђђtзutШGЛэRU]…П…ХNHgўrТЮыŽї[\`vЖЎž—‡u Іy…1Sd;Р§RЖƒNXHo},ˆ|sЌд/pм|\ƒS…1фn\МИ!\ tš­йёў&L" 7 …_х'hТџХŽmрVЌхі8№h’Ч$—+K|0SHPДWЮ|:ƒ†˜%œўїWе-Ќь|YxOгкЭj% p† Ђ$r,ˆецZ0А—ж[РсЋ‰жОДŒ9ˆqв№GЙѓзyy˜D`ŸштОZtВЛЄdё‚—жƒCАЂ­жј№…u}ѕOеиI §яPЬчQб'"їH.ЖEp1`5t`пѓЋ‚J№]"*:ЊјdqхХJВГ€ш™EG Hw ™Eэ]–л…0NПA UГ‚B`077нфIbTћѕWW\ЌРМХ hЏыiЙ60ѕ(((0шu˜YрВЉИPA+‡ї‰:\p8эQоУ3йgŒŒЌ<_™›—kЈг)ƒ•jЕЯƒuњІ§EZгЧ ,н’G'уйvaQ!зРПїЁюoъiПў§АЏ‰ƒ]ЯYЬёsfйчпld›c….AР9=?ЫэџиЩ*b*к#KzКUХ6Aа о†Т ќ™ЦC­ІmуЩ ’ќк^рD МwИ:†Яфйќжп:˜8$Qм„XSOa@5hHї1ѓQ’ )™)3"[Lйс8Ч|XW˜>„ЙpОшšр&VзЬТ?Й$IdfsЁ„{Т>‰К/ZО‰’ЄЂdІЬˆ›ct[@РiцУщ`‰" хKо… ŒіrА“хх2ѕlAР{Эl}ˆhоЩЃ9ЫёN ПЬїN՘Vv!рНцн`6ТЎБє!f~Ь‡KFеж>И•ЭŠ џF€™џ_ж;†€ Иk`›X.Ф—‰fј1rГ|лЮЂљёиГЎ1Z‰€мжil џ.–]Є‹Њљ§ёVjЦЊћ+ЫWкwRљ+~а/9ѓюС‚#bKWwьох|ŸЖ4Ьx| іфХзFLZ_ЙХ‹t –Ы`0`цƒ †€ƒXYМ8(•UcШ"`з†šЌ$VшI˜љ№$њmЖmЕ&ЁЭінŸ:ЮЬ‡?ІЯє%6&жgteŠZFр6тМЫ2ƒ'K‚•Š[“ЊЊfоњЯЫ:нЬ‚ЯвFŽsЉB‹Ћoнz]к Ю№ˆѓ.чuFр€ЃеB?§8­ђ‚~xвŽ+tОK‘”БdБњ“O›‹ЕКБ€ЉSЂцЬ;:kFьђЌBqK3-pќЩKdLLKQЮOi…fОœлбџОjиНѓЌz^-с{#”˜Œ~_xы? ŽN€qљѓŸКыГё—0рЏ0gнњ$” s?NУЄ†ђ‰”Ч#єzУК5Їє7  iшŠJЬ€жќ2sцѓ§h>#mЛЭ‡Ќ’ЂoЋп{;љЁУ‚ƒХќЁмє йХToДџѓUДonJўїП >Ўœ6Нyн‘9KГЗ љЫW&ЈћЋњЉwtъђ†ЎЮ˜§FmBH<ћœzл[%ШйЖН4-z{{rж’‚vС+тrтт\ЛzЂ2‚!р§X10ТњS~њДЈWЎ3()яЏЊвoйš|§њЫИѓc„N."Т7}ђiU]œ2_*LТ_е›7ЯœХ§ПFџ7aRдкѕХHdLŠzfFnејы3М4;?ѕбpQФt&6ZѕюћgAу/hф6xkПЋЛ2ьП•0aќaѓК,‡!а6АўфХм^И )LfП”ZŒОЏЫK/ЊюOKТЏ_0%y}ebTДJяЉєLMљy§јБ§АЬ™’оЏјД<˜UCЮџs†Мк3gЈC:ўўЛ)’#˜‘3ѓyОщЧЦцd-д,zEƒЅЭKs юsсц‹М’n(Нu‹G ];Sм7ДШš№]ЌЬ>Ь;&šk$™Ё˜3;1ІсйчђБBdюй›–НЅ‹œшэ;МAк№ТЬYќCСiгcзЏ-"љкkЦЛУ6ƒ“ў(?!‚ƒЙєёQНяmцфу8YT“ј№~ЅrнK/lо˜,ЊыЩvэк#т]c=r.v›Qѓdn‚ПЎ˜ЄŸœ0~b?l‹ЂбА^Ъьѕ %ЇЋ‰Š@Ф~1д§aРcя{Э—є'‡ЋBBГчЦъŒ'П­!Ь;о.оёN2Пљ\tLьžŠzёдЄ~%%ZВGKŠ@—”jЧŽч7JїLУм‡Ќ‰‚щš№ГD‹ђ•$Г О2RžегКљ 3 7Ь/ЬX’U8і‰№ŸЮЯФХyЊ0#АНbдућ лŒчrзЏMМe\јещ_cВ)ЄhуІЂЕЋ‡НОО \ДИ№д7UрМUЗpяЮдНVв"B<35і­mќ.‰№@Nцt~"ѓй‘Ъ?LEн•Џ'Ž{*WШуЧ4Г ~<ИЮъZЛрЊю|omќфхЕZmэЏеMiБ­Ћ!šVаsь/zХYŠ19žA–†ƒЖ}ыж-ЇяƒРп‡(ј6mŽО…€ѕй‡oѕ‡iы\иФЙxњ™4СRобžuъxGѕ•ЊаЎф…gОuъЈFvзЛuk™Ѕ:экНjЉЈф7ZЬAœˆƒј-ž6‚Єџuг ц#cвдДє ќіGц‹™> SЏ Х@NmXЙцX™Џ `eё"кј@Џh%вЧO8ѕE!MњJЯ™žv!аhA,Юбь՘§'Ь>ќ жIА{*™Я2Ь|Аs@Цg.ІG0lq'Q›ЯuКљ№Щ­г6ˆhДsˆi꼘#fr<ЭЖNЧЮЋj:й|дhg{Uї˜2 ЋрфЂЁ%KЋьx{‡^ЏЇIFј.N6О гœ УAЁ-œ€‹(cDЮ;;ЋШjyЬ|xеpДeX˜(џif>ќc]е 2t'N=\Ѕ+“ыv˜љp;фОж 3О6bюгзЪkcюSФЮ–А§fg ЦЮ`8+ГM›ЫŽ|бМ—&пxЪуђхN.UuVБЃ“1u—И)юjŠЕуBфЬБЅЇЯии~Ъу]lфД OјŠKŠЕZ-М);u‰ъjr8fЛЦщmи~Ry›цL!rцѓ snо№ГeМaїАyЙъи„фQЩ!С!˜k”|[ў—pƒ‘Нœцўбpf‹ЫW:џNуL§ь”е/ŠїJчЉЫФNeЩ.g>H;eіs3Йыo ЎћЧ:gЊЦqeЅeQ§еБёБЦ:Ѓў7НBЁа MФ_‘љ(9^TqЁ M‡ѕ гФkˆзЎ\+ўІОе eTtTxИЩ RyIЩйЪ Ч kdЖ€sћФЄёЬ~о^/l0Ќ{sп)л.:lЛz†м№ЕПT%K„э€0оР‰mGI‰Ю`Шx&C Ш=’[^^ mѓПЬOz0)ВwЄБСXєU2X !хЅх5зu“2Bў’їy^yyIlЌЦ#]ѓЇsШОјцк+M›ƒКLРпYUМњЩ œ!‡t й QЯЋ.VРФ`i6uЌКт\…Ђ1ІЌ 8ЕзЕШ !Ё|+*™џ‚Й Ќ ’„Y$“% [Аmіa‹$№`‚Љ‡ќЪ№Л`є7є` 4ќЎ l §›RvО sиѕ5йpEщŽї[<ё%Ь.а‰dј?^m>TнТ`Т{†ЫXE{vX ƒБN$ДN!‰CљYIѕџVчцх’ WE{хЬЇ3`eќ`YЎGРfѓqгѕК˜Е€-Я‚ЯјBЛ†bѕЁПЎ/+-ж K2†ѕŒ(јМ;Іиу(,*Žшi a]єUЊB zНЦ%$$ФpЭб'ћ#ъдŠ@lЭj†˜ЖZ…2эrytrqiqaQ!зРПїЁюЏV†(uњІTŽУFIiIЮ9x˜б+bиАaFЃ‚ТBУŠО,а]з);)“†%б‘‘‘•ч+1Ah\lІЊеbib Xš!РАŒ€ЭГЫ"\Z‚…FтDlpš6)8}я*"cJ†ЉнN3@ƒТлaЈу bhЯа№осXМ№›ІЈеф`™ъЕi§в$ЭЅ]`ТўŠ€З›рŽЅ‡A/1EЂoЌ[bР3ЩЇ6ќcр:Pж/†€ћАн|H\Р.USцЃИцЉ‡K5`Т]ˆ€ЛO'vЅ…hэW‹Nв„ЭцЃVq'В–ЃSK ,пЋpћщф&4ќЕ_рƒљАў6:ъzФЈ2aaд|>л#Ї“Pѓз~Y‚ЮЋп:ЕЄ4Ыg0Мf>Мa˜ ŸDР{ї>|NІДјыПіЫТАbібжжk`й †€АХ‹€1v†C  f>š`џ ;Аyяƒу?$aCРIјыщфЏ§’v›ЭGл’F‹х: =ќЕ_ЦнVѓбЖŒЊАќ5пИљ;=ќЕ_–Ю|Жїa qОЬ78bVLЫ|рƒНa*Л [gnRЇe3єŠ…зТАnaФЭOKІDїdђ Ž—ПGП’aqD}Б5Щ*’™ЖHc<~‰€Mцƒw8мшDУ§,\АТ‹GСб‚тo‹сзƒј%t&Ђ@vоo;dТтˆњb €’U$3m‘&фёдщ$дСY4ѕЖэСЫФY}БWŽuѓ8ЛvяВWЎљЩE Џb9Лs0T№§{`ТР„ВВbняВh— ѕЖ8uМQ]!` ›dДЁXЂџŠU+@&„7^Щъ–"Ы8 yQ–ТтljŒB"ъ‹@yЩN/нџё~ЇЫє @&ЪГ—‰GКoн|„ ЧЯхіЏrљ9AЃыuњєёуХђŽфI†zAœ"Њ ŒNюЁц02б^„bqН‘ЙфFnМ–ЊKF–Б7gёX ‹ѓл'ъ‹АЇЮRРv9i вlgіN/_щŽ-zZ7ђRЊ?Џюђ ГFƒБјt1Ж?Ј2XХ№Ю“у3 дKъ“щ№Kˆш-ѕWІ№œL”%ч­‹ђо%5%‘ЂHД—s4CMќБЄ-ѓ‹Ѕъ4В vjhdЊА˜XjKи!€”V†в Ш„…ф)˜А”б жšWлrуЪDLЩФQ‰X†ЮJ‰э@вRЈСйВy™h/BБІ–ЬўYЊŽ в<ВŒYmfи‡6/йSиЬАpђEr„ж‡ЪaD[F ЕцУеГ:хЦ aѓ:ZtеRЈp BРiљh/T,mHDXЊ.YFTзЅI[ТтьЉШFˆ’ТъŒfиm>*TŠ"‰Ÿњўp$ЛGЎдъl)д ”)8V y 1ЬЩТˆpSЃН`Ъ#ЙАT]2ВŒ+Б$S&,ŽЅОXХђЖ `Зљ€эxdС#цЂЏ:lžщžKЁ^аzXз0lm 6lˆ)Œб^њѕя‡НмЂEЫ~Kе%#ЫИвŠLXK}qЇzЌ-џCРnѓСCаДсj8Dз-mNœo!д јcˆŠŒ"Q]hфKF{‰…™РЬ…дХ HX*YнRdЊЖh+GІ/аJи5ЊЄэ™Д #к™7FтГДrхcŽ  Уi)Њ‹dОHЌˆGX**"чЅШ2ю<Ћ,A!RXиЈ'J…mЯtgY[оƒ€CцƒуЏiБTydЎФrЦ{:йzMшMЩ{rых3 _DР1ѓaxdЎ)jlSŸНбуЁ/uˆЂO4%яЩM8Аџ 6„€#цУрЎНжƒ/u'Šj}Ϙ†€7 Р>иї†Q`:0|ЛgxП#џљц}EОш}s–У`јі>…•љ‚Ž™:3X_VА{іaUЂЁЄЄD˜dt›E 66ЖЭін;юZѓСN?>uXзlы” †€ƒ0ѓс pЌC€!РЬ; `цУAрX5†C€™v0МјЮё^ЊY“Z~b>ш'mM§2§З”/bЃI{љiEF0솈ї˜˜? ЌG?iЂЅ|!›аjиТ/ЌЫh†€9лзnso~Лжn7/meЮёkЧр Ѓукї>шЄy•ђђђГХЇњЉурѓЦМдЁБ@u|MK>ЈЕїЃ8ШБїЃ^к4МЊT*ѕ5\„AKбс№NpIiIеХ*јgц|•~}њuюкй^Г*nC `_юїЧПпYШЧ-™?u~—А‚Ф'нжК;ђѓQqЎ"сСЄтя‹сћ‹їyуŒCшђ`8ьЕD LUь­Hš†ыГВвтЂЂЂдGSЬRt8ФжS†(SŸLECЈ;R\Zœм#~‰œ“с>љр“щ І‡tцo о]ћЎѓбРm|mMюСЃрONIžЕt‚cџЖ§9џШЉ7дK6wХ\’y€`vsр§МњџЋ4~оЪyФ9ю:˜ўфэЮуъгчNM{:L=Ш_RЗјыт7—ОyхТЯЛvŸђт+šдџѓіНkWЊ јDб…ZtМ(ч§œЛs0=vЫRО41ф/yJqэа| ›DЊ šА.‚нŸЏrМH(JDЃQ^ЅЛ^ƒp34:яај7=zЊšˆПМ’ПT~x4,œ6Ѓ fЩЃ’ЙF$%Н ~ИATqё‡феУЅ~ѕВnџ7ћёЛzљ*’”ПєTщЮТћ‹їыjtл74ч†]w?snч;sЯхт„йЖf[SўіK?^BўОяruП№w\b2№—к3VL™7%џТёьƒйЅп•вэ"Мн|œ=Wе? Woxx8‚?У”юсkDEЪx&#у™™%Gћl)Ÿ2X"ДПŠ/ IDATD[4”мЫ/ОŒ uхх%ИЖ…uЩВS ќH]4M‚нЭ|n&†QUVј•Кр~‡ЌЦ:#цVМЋAќŒ №ЋКuЩћ,_МРн3"к4ioh[ˆb /Cрпў0Э8ФѕпўW№иОМЬe™™ˆˆcцQўЬзљћšѓ У‘=G2—ЯЧ4­L›7эшa~ў‚уШžFљS_J2Eƒ‚‚tИ‹наЋКЊцЎž+*Е1й4IВ‘нНlИЂДZmzJ:цэ0e%Х\“›UQdЙŠ D5Kљ"Х­ЦOГJN$I:'5- v'ЌE›VЖWЄ?™;".qишЪŸ*БЦбщk eXЯ0И•Ї3[ЁXF{wќщœКФ‚€шєЇ;фuЛЌНЎ 5EчТХ|љ—ы”пR>aИ\u9%.…2г Ї9_ŠЪz'ыНППЗcЭŽ џ zщѕ—дƒеR\VђМк|”+УЅЕb=ЇšeхeИQѓ7сп ИчгrMхтˆs4_Dˆі>DЅHZ %gЮIsD*AШKy@ІБWš{$WЋзbШ1эФI†N йLt‡ўЊPоˆuMIIQСWЩ'K3KдgY@ oп^хQDЁm=ћі•WЂЛЊ“ЖZK,…іŠIЪп"П[s>aшо­ћж#[Щ& ­Ђ{ЗNCMАˆвс‘с+п^‰$6AVМАтPщ!Zd;се‹LfN›Iј‹EAY™i§"Œ,‡K‘vиR>e „pяƒfRЁфf??›6MЎyZ*I›6жщiP;sf4хIb|bСg(%бс,­t`)АС‚DlД+l—˜Ыd9оƒРC)#п]ЛEMˆ‘OŽ”зmшЃГ—fу^ˆ_іЋйHR~>Пё1єёц|ТђTЪъ9Ћab0‡­ўЉ:+3‹ф— 9hЗЅэЫL;&:оЁНдМьsѕЅjTфџzvџѕ^ѓQYY‰BЌ)ЙдqЩ…tRU^ЌФ•ЦG–;V€ЮѓбГБЈi:,х7•лњŸ„’ЋЎЎFгX>иw„Ј2д€n4“Л#*GєьG‹Є ‡Ђ „ѕ.>YŒ~‘Бд_зхЭ Ž‚ММъ‹еш#hœ E'‹TЊ0:GmdaМфqЩ}bњOLHУЏЯ§­>䘼вDхЪ4u~Ъ.J$i—ЂуЂ'š˜všRЉœ:GМ‹‘і\2ŸЬLъПxЦт“$'ЬšауžЛ&>4ё‰ћ“ЛtS’ЬєчЇNHœ@пўѓтI‹уCуёќeй[ i‹vоЛxЉЁФ?”bVв"В\ IKљB ЭW"4‡рEfJ ДˆAмДyС“RhБ;Mu)CSћпІ˜љ№ЬYЏЕ˜VxЏ6ФХM _0ЃђEѓšЯ†€$љUq$9нiЗЇu7шфЏMРRˆ^N#=ЮwќЕяЌ_~‰›}ИuX™Ѕp+мЌ1#рНn]мq&ž!Рh-Ь|ДAVŸ!р"ш;.’пzБЬ|ДC&!рVМЧЌ0ѓсжgЕp…“Ÿ+њK?КЗKИ+Œ3v cfи„€аГ†M|“‰™п7ІЕ?!oc з$н›„пЦ……%Рли˜ПŽIК'iЭМ54_8€З1ž!, ŸРсЋ(*№6ЖŠЯ‡Ге§я№>Iс„кN~hrRXќиc і™ОБВTf>ьEŒё3œŒѓ6цd@™8†@лA€yk;cЭzЪp2Ьл˜“ѕqјJ…}“т%cсЧj0ocЎ\xZBАоуљл;ђ>ЮƒsWЕ$%—~Ѕ"љЕ›T –ЧАпѕ6цепМ№Ж#/W›@Ђрƒ‘’o‹ряƒ|Аoї(9T~Ѕ‚Џн(э$VЉ !@ŽBўM ИЫ^œ Wcё\ЬНёq^Ц “є6†*№6vуЪхЎїLЩœB †ЗБэЋ6ТлтМdЬ5y-"оЦрž(CМ§ќѓЯїм{УоЦкП_vчоmё“—зjЕЕПV4%œђˆ”‚вгg*nйъ\`џЊ§Юъ#Р мљikxOТ$0вэМcaФAU*.№NЦТz…iтM~“0MH˜PVVOХpиЅж$€™Oж!йEѓ †DuГ =N=œлA u›"€gк3Ym ‚жu6Оkќё+Ч['У9ЕНzіЗРpолб\О э Њ‡ЃpYŽ *№Hм"hмџСIjЩщ’ќЃљaнТвSMIИ…[@Ли0щ „zKfsчœzLŠCx•З1Џ~яƒ@‘\Њ Ј , т­ЁЎ†ШСœШp`ЅЃсУЕС%*$Р9(M н”лШ&bf;„€0к§РлијYюoWВEЏv$E&Ј м‚Т:™b ЯТ$яуАiО%Ь—a“De2<…€Wyѓъй‡Lљ *дv1%щР‹ђEIЪЦ†C@І{БdacfDЛм[З эк)ЌўЕ,УС’Јш(H)Дk(f €‚Јєša‰G‚Њ`Чди`Д)ЈŠƒ*˜Њ‰BКДNЋЭ…sћm9Ѓ—#ѓ!Qp†Ћ єDўяђ•VD ЄкDт)‰Ѕ(UБЉI LЂ.ИXЖ­X=— ˆёx?жgЄЖžЮцГХRPбƒUKIKљD}ZJ qHgw“Щcј"жЭ}xЊ{и’hЯЅIKљЂ‡#–’–ђ‰xZJ QH—&-膈ИuыeHiзю 'Шˆ+_*c‘Дn><;ћАЈИT№§.ЉrSSШ№А"†€sРЕъыањkоY§ F„Xk‡Чgжl.‡] ЄвЬбDб9ESћЯp ŸЅU\аЏ]ЭGq UЮ™ЇŽш’ј0яТGx8ХВКћd˜ѕЗ>4ћdА Жќм.k‚!feр}Ж,4ў*|Ž92˜SiŠ=х™~•ЗўѓrЭ/3gЯ5…pёP9‹^Q“Z5к™ЛоO Vš^Ё$ ’Ђh]J@HU•ЉХE‹›ƒF?”V\’n0МŒ_сWi# #Unн|`іA`C€!а*l­§ш#Ёёƒs:wн\RZЕvЕfіKќѕL') (|XЅўб9элo^ОД(}bф[›љ—ш!)Š–іbй MёЗкіЪЭ9ЛЫ–-еРšЂ=9ЩБ1Њёѓ:uкМdEё‹Я›ђе1*ыцУЗf"PX’!рY6f'И~Q9PA#Ч•цМ\єяЋ†џлќГ2Ѓdj-Z\\zF[WgиєцYА%?lš *Жˆš:…7 ЏfAШъЕќRkъ4S‹Ър@ИYНR­Ћћс‹|†fZyЉT!~ЕїAРbоƒ€p›ЃЊZ7s†­ЎЌа‘^ќx‰'BЛ†XъЏgiЂ"UС&–ŽBf[D…vхЋœџЇщ“аЁЁІe-Яв|s’_•ŸбЮ­ш“Уќ—ю8nЃю›Iкќ/›}˜cТrі" \kиRїо%aЛЗOT_б[ЊХ/.P:Џ]рXϘГй"ŠШЧZ‰,‹„‹ЃukŠБl˜ѓъkE‘їЉіМ›Lšаjѕж/lяУ|­­5пЁXН&А џZ%ф!ђпќ{"ZФЮkЪуaи%% ЙyiQ§CNžвћ’ŸtšіBЫJЕж/lі!D™б ї №ёсъг'вCџ;D{ЭјъТ"LHЛЫWсAЬљљU™бŒ{*wУКФcљЉк+Цuo`Ѓ$RЄЁ%QB6Ш7ŒГžНve†бШ}[§њzS‹яНSЖzeЂ:Vў’гкљsљНRн.xkёя”ё6vыV-Оyaoddй_№vпЂWZио‡яТ{p Yг  `н|xэьУWЕяТ{dYЃ~†€№Љ‡—wЭњж)љцХ–ПNя*5№жЗщЊnЊЈШЈ@…щ™6љТ…}Нтtин#а–3Šёx;VЗN=ЈцУфпМгоа–—–WTVЄŽIхмЛяFд`vЪYfxВ@ ЮгГrЌЯ><ЋZ'з-& БФbъQR^Ђ Гœ…фAЯЕ+зŠП)„?…B џ†ссІP5цsƒїтд§ћ…GђOГѓЁ№dЁі-ž^ЋTa CШ\ЂЃУы~7=<*:^TuЁ Oд#ЂњyІCР;№ѓA€у§7р“чАмМ§б@‘Шoљ_ц'=˜й;~O‹О*P+aJ0Uб]зeLЪ@и’™ћinЂ&1<%мШ‘YVZІб№–Mшuњєёˆ:яH"f>*++ќEдŸN!‰Cљˆsеџ[›—Kbh СPўТЏђ4 с‰тBЗbэ Z‚кa]„щђ0š!Р јШтЅђвИz61>бˆ—ђ"icХG3zН&€СŽ(јМ€BбР•œ,!ь№ЖизR[­=№сŒ$DцX*"0wq‰щЭџ,СAN=ЎIК7 П 7тD"‡hB’є/--ўКxђC““ТтЧ[АЯфšŒ–Bкšyk’юI=fџЖNw­н>цЏc’Т’В2Г0O—QаYERйєГD:UЮŠUќЋМї–>1жЋ a#иO-њВKe'eвА$R‹нгœƒ9HЊћЋQ]ЇзaъQPP`аыэљg4*„r( ‹“Г;O^ЂњУƒ›ЩЛe`C@эkЗ_НЌлџ mЏ~q5’SLЕФU LƒpmВbЦŠйoЬж ерІј~іћ‰OДp/iК_uћ‹MТЉи]w?snч;Б…—•НmЭЖYKgбR^НxЛ>ЦtрІ‘юPаЯѓB{†bC‹~ѓ”ІхFdtЄfˆ†ьncŒm,mШє€ЊЃMnзЈ(Š2žШ`ч•дUטиh)#2л——}hyŠ—Й,33хѓa.'((HЇес|qд|^чцяG}О+mКЬ|ДщсїХЮ3гу=ЃЦЬ‡їŒг„GЄЙ7 ?xЏDDјmЛ$ƒL&О4;ж MŸPЃо˜5#‹wеёз1јОž•/~qќ‹№гќ5™kDў((›Udl”#ЉZЉўЉF@X’C+вЎ1ѓAGЧ™Dф_ХaŠ)нeьЫ§ўјї; їуїЭёяЉГgѕxчњј6ФYвdфРЦ™›Йе‹WУеfюwЙћNьЛњЏЋš\энђ?{цoЙ•Й; w)ƒ–ЬZb.йdl‘Щ’К!џlбйA !#‡дЅ˜љ0)gц0;b Эм=ЙИзСЇжєЄЩечЋ л'|2}Сt|6Š$iuмё-$рn‹їЏuO>сНУщHт/­%ЬС‡d'ђOЄ=Ут‘уј‘у™‹3CёёЩnSяVюо€Џђё%.\„<ѓЪ3?џС\=d(Г-r(Г9qђы“ї%м‡|лхxЕљpѓЕ'гŠШoHB"WЩ|m-•ђ–‹rX’ PzЊtыЁ­Й•Ч&]5Щќс‡ ‘„qё‰ I „рŽ з[Кні лqY3ь№‡)шбOŽF>rоZђжŒE3муƒ* CHіюьёГ}шk^Ы^d,Щ1—lЪiрNŸ:­Žoс[E"9МБ‹Ÿœ0vџ›МЛ3Џ6Лъ‰ќхцpYЫГ<Ё‚_Е9/kІИхтіђ“‘ХWЇдЕ=ˆыП§AћlО@Qцk™Иcу‡есу 9c2Цм~аф^Д;јюСGІ<‚ќВуeЕКZЭ( ш~"~x|іЪlLˆ№!ьQГАѕ‹жЯ_;п\7dЬ™eф˜3“œВ3eН"zQ№IІH†ра?хWЯz{Э7_Г}йvп0Иѓч}|`ФЈqБ‘уR+///ШЫ{lЬc|rьИъ‹еЄЗ`ƒƒв! ‰‹[ОbЙщBY‡фqј ѓСрƒ#†€#а`Ф_BцсшpЮќХЧO7YL+6Kkр6eo‚n˜Пј  OO}КрЈiѕ‹$‚HŒ>Ф=nЉz$ШŒ №юsšœ пёЇ;( :§щy …~ЗˆSЏаЁ=ћє,њМёЗПК?ќ_€^ŸЕўХW_”—цъвЬ•™!9*љ‰!Oме§ЎNдPcУeЇЫцNœ›Е-‹vJЈэШШЫЪвиј8d 0GFNш_B—lY’З{џm\CѓBQXйлш“'NОџЮћ…EЇG&ЇdLЫјъФЩ­лЖђЩ#—d-Ёк–ž.=єбЁќЃљЕПжnкК‰фoкМ ЩCŸцуwЕц*’Эќџ,нЛooљ~fL2Х ЅV ЩЂКјJ§ќЯчэ?єљЇ…555(ўЬє7пz“ВmлБmќФ ‘љЇЅm„шлЗWEЙЩ5ˆž}%ІёB(рд‹$yЇ^н:zьдБОГєžm{Ц>Ы?JРёѓ™ŸŸљ4}d@7PHЉ{ўтоГxытќЊ|8ыв­Ы ~Ÿ’EGŠVN}n сjЌ)ЏХ‘Б*Ї…PAт›ЏОщЇiŽЧj‹œzZМЬ]ДИГЊ3BвІ=™†‰ммљsiђ‡3ЭцЭ›3ƒ„Ф‘УG>G>9Bѓ_[№’ЗЙ/Ь3MZ%АыБvнкјAІm<Щ"Q?<ˆІ’bfцl”тƒ Š 2A˜о…'вRвDЕкZђЁ”‘яЎнЂПІЧФШ'GR$/xјьТˆр7\„9*>ЊЖЖ>wgn‡іŠао>Лš7аG’K!к–‹ьяЂ_№WX|ЌјэUoOzaihџ;ћ7/йМцУцЖƒікdl‘#й5,ІЎT\ˆК/J^ИAУУ]LaЕсAлLЎ§dNRWЧ2щEN‚Z “4M}!ЙsзЮD~чЮoh/њВіВd>Jq=ЋЩ2гщAƒу/2Й“‘,Шsv6щF‹žzvњњЕы%/{Kі”ЉSHзhi$’Ч%зTеLLрЭшш)iЂц€DЧEO4БоPSnИ(УјgЧ/}aщ›ћš'wДШ=Нь AЌД6|тџЋ‰ыЛfчъ0{>яsp\м8ЊлБџ=F\Ђв[БEšыVќmqпA1tSй’œG>ИxЦтŸџљ3&z0ж№Ђц3цƒт(Oр6N,ХЕkз:ЊКцюЊю’љђЂDЅdu#ЪД]2ЯyЭЄЂ‰зlйД+ яПџ~Хk|D›6rˆnўТ$bH†5 <”Vx +љ vGЦє%ИpЩ&OФЯМEIfТ&,В Q+B9BšА)<3`№ZХœi†k№Ѓl |cыTЈБ<Нzэj2›1ъ‘Q„yдШQ4щЊЅHJ Чкъjг.Ќ$ƒyІ’Q1хё4Xyим”НŽŠz*уЉ­[ЖޘюEЉnŒh#œјт„pуУі^ћ›љˆŽ‰ѓиФšы ь0sкLФЬ3;мй!iD~wuЙ II€2ІЬJ›жќЌD’ЉeІ’Q Žу{пгК 1МK—ЛЉаЛЇз=Ѓ6­лi>#nC`яЩНxbх@sэ‚змYpШ?\%уЪ—\b8€‹лЊМ<чх‡‡?ŒэЗЕшё†˜ЋdГ№Зй‡ГpqœМММ‹—.Ж)лс`Y+юA!ВнгPj….фЇB`CМьuЭ‘~кFЌЋ~€_=y‘П\н6^6Њa#›лдf 1ьE€-^ьEŒё3мŠ}MУ­­кж3ЖсФИ6#рияX-›•r #3.• mЫXzэJЧjЩЫtu)3ЎF˜Щgј-Ўн:eQцќіФБГcm*`–!d*bопчэоИQя{EмГ ;‹|ТWќuё›KпМrсчŽ]ЛOyq yПžжТУа5 з=x4шП‚вЇЇ ‘†џзячеџ_}ќЃёѓVЮѓјїйЎ5mъЄ3ЃтTMЂиЗmœЊm9Дљ+fЌ˜§ЦlЭPіšі§ьїEŸчР%ВюW\ЈЖR$с]љќ™s;ПиЉVdgeo[ГmжвYДд#[Мxvжh[A@вЉZPPNЋƒGuИ2šЛzЎ‹cц НЈбв#{Žd.ŸЯЛh œ6oкбУGi‘ЇзЮ><е+ж.CРKtЊЗ@я§§Нkv`yђвы/СOВP[ИMЃЧˆЋ4RzЙъrJ\J3Ї\Л^ B3ŒbД рhхл+бUl‚Ќxaœ Л o№ЧC,МЈбЂюнКo=ВГšуq‚-^<>L6‡яЖыяЖ‹?ў#ю><ё˜МЈнаgПкќM"дЌžГšїЯиР‡t‚qMЗЇёЭ‹СэВm“\ѓ™юN@РЋЭ‡њЧD0.CР7Ьnў^eN8Т)‰dt;0а(vЈoя/ПјrмР8С›1k\:iBЖ6zN/ЃНп0Рб;ЃЬб–Œn‡ввІ(v Ї=?mђФЩЇ O~UЗЩkж­iЎоФЦBЯQLс§јŒљ№’(s–F”FБFЗГ0ŠнG>ŠŒŽФО:^:ž:mж‰'Ј4ЪЦBЯQLс§јŒљ†•ЌТЄ{ЂЬЩЅ-Qьйk,^АZ‰‰‰Й~у:•) v‡аsonфУЃљqш9_tC‹Ÿ1Tcyћ „С<ЪœyОМ(ЛJ%лI˜;{юпžќ[aA!йœ>uк’“j„žУ'U$є\ъЃЉ"!,ЩLїœўf>h49їD™Ѓ)й.-%D}}НBЁ@ьRиšЌзГDЅТd[=ы@~BЈЖКл IDAT@„tѓыUТ\лhlWы$й DЂЮš‘•tOв˜ПŽСзїTхВуХ/Ž1)ŒЯ_“Й_тв"!!) x§•IЏ@ьиш1*xЗ§ШМ' ?ќЋюR‡%™B^KMŠdЎЩЬŠ<Р<ђ6ц2љђБOЯ \RЏ$лeвЖ„„Ј]aЪуo‹a‡}”n#ЁчˆЎмЪc“‡Т —cƒ!ИcУ1—ЎFЗ}Уv\™УЦ ;ќСa* єш'G“+і­%oЭXфEЁШ/ў№е“gŸэћ@_šДJœ(ќ}=Ж +#X%R%~tќЎ-Л`OёЄUQі14pиПcцУ:hТ5 Ѕ­Wsˆђ7oйМzYГ‹:‡Фј@%I7\2z‹&#„Sш•ыиОмhn;${-дsфј‘Э ЂЌьaЃL{НњіjоћиИ IZЫЊLpЪѓ`ёuЅтBд}Q~ЕxЁ1Тw '.!фЏѓшИш‰ƒ&ђO^Ц ƒ“.кыёЯŽ_њТв7їё/яzфьД6|тџЋ‰ыЛfчUб-{>По7ŽЊzьёkК–‡ЄL|uф˜о #РЬGk‡ЯZ+‚еgј&ЗћІозZh5TM№=ЎSР /J8KЇtŠQМњЕ1с%JєЮ˜’!ъ€Г’hЫ’pЩ"0УjhЏI{aq–VLCР›№jѓр.Guн+c$‹\Ї‰7Ÿ1L7†EРлЭ]Ѕ%'‹B:ЉТУM_UVVъЏkch0GˆSЧ-;‹Я7Уz…Сc(эdЩёЂŠ UH ѓСŸ00ЁЌЌXїЛщЋŸЋV€Чв„J#„pJRђmIсЩBQЛBљљџЗw5PUUiћВ–k‰жцњВLjX1\г‘лРdM 9# Іˆ?(fj7­@Q Љ$  ›)"ў$†„3zЕo’pJPѓjЂ8TцИFп˜0п˜Зѕ1Ыя9юЫО‡sЮНžћчœыfuyЯ{оНїЛŸ}Ю{оНїйяFиШД}oХ:hPpдуQ}§ЙЏ’љbwКSџ >hH)IЬ{+’mA_АS†€вhoш–ЂхЛšИѕЛV˜˜шјР€@ й~Љ}юЬЙ‹ž_„'aЭђЬcЧŽЕ[­sгц.zЎ—:к;’ЇЯ…ƒC|BШШ ’-­-тrљљCвќпfC˜сХч_\єќKXmйPп@ду‹ХŒihh№яЫЉ?KНEџ ыЭЉ$сГ_Э аЉ[Л"?іўXјал—РУ•+ёБАОЮ.ЏгIђБЮ83•‹rŠиbˆ§e’кЉ+Э-E>яХz<\Э_7O Ÿˆ%…ОЇj7№№~ІЉaLtЬСУOзŸЖГФХХaqQ{G;.Х<p[€ѕŠеnhњЊЩџю9lљЎ ђЗXщЦчфЃc аЉƒ‚вЄ,9П’х ђOLL y ЄУкѕТУТЁQ/†Ееp4Ш"tѕmћОХ№ˆ>ˆЕ“­Š–гЊ“)-(НxОНђp%Ž‹ч/т”ЈшˆЋ‚јiДJ’ќŒф D'@”SѓWц{‡нUВК„Шo_[zю›seЪ*О4ЗЯ=єЯђЙххЄ——ОБ+V(гmBэщБ>КсC‡=q4vl,^ьдш"žhŠ>Ь.#ЧKРЫп^Ў џƒŸэŠŒ ЙO‹Їєѕnœ…ўQ5P† <ежж?1žЙ"-чл.баaш„’xhЈˆ#>.IЪ;т7Ÿl.~ЕИёTуЯ$юaзгŒ‚HŒ5hхkЫ'L‹ѓ–э@цjяМъЯvъjkЋ1о0Йї/{§u6KQ]SЋПXЙAЪс!мŠ@ќ^§IПж2|ˆOЎв_Œ/P/†2e’х вZ;сьp(єM>кѕ‘р*џШAЫСЈHмШѓ/1Z[ 4А[<ДЎш„ŽјЈ]7љЎјiŽјYѓ^ž4gЖbРђŸšs5ИљЩЏaXФvТћWВЛdŸЙУ(<žGdZЄGйєXb2BГЧFэЕzН!фОМѓяtІ`jеF>ЪЭГпќQећV+К6СбG#Ќ˜с#Уе{џУїQStyЂЃm|š'!FŒx’3/b5јЩ%Ых €†ыQ]]mэhїП5P?RпtЖI `?эЃУHpиCсЬѕАcЂMjмф8„AЫ(рBј˜V™pJъсˆЯ‰AО№К*1&ё,$=ч…+}ЎшдЛ`O2н Иу3ВxК`Ш›ц#№–@в $\vНw гqWЎПКћш`\0JJЦ(_`&ТТТ"‰фzЂю’Є49Й*.— Эб+ЩЃ[ѓF_ fSsSдcмеі+нНˆ<ће)KSLYІ$ї b'œхёqеQќ4Iў г Df?пr~№=ƒЇ/žОЇmw7-Э]›ђDŠЎѓъмtћиђ‡1§й b§bDЗ§t™•СѕОm ОЦYХ%nCЃHBЬCcюvaкТŽ+ОкsAKy%к˜" дЃ…bтV[QК[zЗ2ЧM&™NќК–г"UМ50>Ž›QѓUлЁХva:;B@Нцƒt $ѕ–t1|РЌа*cXGВтŒЩPъ5€IвL8ЯUy'Y)uЩЊ t>PЎЖz.\ƒЗ>p›А*0|f>|ЂY%J ѓС>LRxV&C@ћєьиVЛj"V/ ю…\X*C gЭЛiTжмъRGsŸ9Ј >hгГцCd*ЈO&0З=?z>>Иє$“žƒ†хЋзPgйZМГБЎБпЏњ7fў+ѓЩтZ*Lєщ{џ§пиОхkˆeў{7sЫUS“ft­Фх €–#C‹уы†Д­пЖІЇЄc (™z"9:рЯNЕ–r$ЬNP­ЎxД'T§ xч3iߘ›ЭeЫњіЫ^œMє'Тф7у cвL‰е(ецu'ЪVт8\wЂКЂZ\w92H%ЉјЇjOyb GzвД4f>€ ћSњ!ˆІѕKЧ/–…_ЊŸгzЎѕаўCIi•W!БІМШ№;n!5œŽДЬ4И!B%;uхЅU“Sma;јW?ў№уЫ`Х 8х_%Дq*Ъ9ђљ‘‡ЂТщѕьJУЬGьПЂЂiѕ ш=1zЯ‡{ЈR уІФЮ†ь W.Єq^ЈŒ†ˆSuЇB (\НЋzTд(Їg‡‡ '|п5ŠL<qЮ6NЇюјбу†лJN*&а“ Є1+jjхzЎЅіћДŒ№mФбД&Ю˜>9=iNg&:uU[ЋLU&€аPзpЙ§rф{(lЭ!гњu+VЪš>фЊУџ+wsЮЖ|>‡вD–ƒƒт‰D/_'фШtOa?k8й0tјPZЙ а}џлжЂ•EЧМ;‚7-хhubo"ŽВtoа‡д~R 5№;Ъ0ŠDа*Ь)\ВjIoъцнВJ#”9sh•IўЕћjяОoj-Y\џлњ#ў Йbрm§ХbrdФЉ=ўџЊ#=!t_PvqіођJ_0jИћљИk‘ЧUщхZHFйBр][v@“wL}v*QщЬЩ3sЦЯСp :Ё(НЌА{ХСFЌ™З*gKŽ8bргцY‹g9Ъ64thгi[ˆ)CB…$”#у(џУŸiФчDOšУUЎѓЂт?jќ§§ƒя FиqВ7Š@eВPеЩb3фуыqЕ–<Хt&ЂЯ#NЊЮj xЇ~”ž‹{}7WMf‹Hъцœ)eKЁПœu[ Ие?шлk™КаШЖƒъМХЏbЯ„ЊтЊќ]kХ. ћџЊ_ШCЖн‹ЈЊД‚O$ŒпZPœ]ќ.?e’{24ŸРАє…ІГњ‡є„щHЯcЮЌEГ <‚›!šЇTm>Pi!ТЊ?­Ж|aAа0U˜_'ЖƒˆсэzC~†ZЄa;Њїš сQётБ1ъ{ь‹Z„8#ЁCм@@2‰Ьq@ЩhZШdњГгWПАz}ХzW3TVžњD„ 6ЮДŒь˜і№4Њ[Э?jHМяь|цЙй”/&тЇХџађCJ7й—š39Ц=Єы†'+tЬhъK8вsьјБY ГЮќэ bЉŽ›‡˜ij7Ј-yьВє§ђїЛ;ЅрH7ˆУK•О'9~dv`ВZлюŒ‰р€ф…щвrт†бз2„GpAR;ўе—-r\ ~п]џ.єч# аек‰[Феˆ<пqР,ЌфD,žЩGEœƒ{:єP*~еh’LrЕЈЊˆŠё ~lђ@іyр €vU†/OВ:y№фЃП{”f+ —"ŸŒФAХ@hР|№е%ІВAљhЇє=‰=’Ї$ƒˆЪ–ккј„Db_ш~1>ьƒ`[)xgАі Љ\д2IђAv‰І-тR*&Ќ*8„y.7Tв†љ@XdЫq †?h ёœРє‰7yŠљ=чдснЋб[j’ЭхH*6Є‚VЋvгЩv|$$ž™_^0t"nšŠšCЊЛЇГкЭЙƒБ KpppЬ„К­&ЈХЖрeHљ\$ЕзЯНV“N…~ \ЩБ!qIa#рЧa O]6Т!жЧQ‹ˆ‹Яqф-ЫЯI*‚€к/ўŒTИ&GЯ‰#>MшЋФ {‚Оn"I1О‡ Їр8i_–еЫјюw09АЖфяЈn”/оAŽяЅ;Ђir­и}ЪrФвќ]3ёб0 TћЉma•O*хy‹xR:KЋдю}x)Щфшh+ŠpD{Ѕє^ЫгLифСRo9X{PзЩ}їaeР–Z0Л’єšbЌ _EРO—О=јєбˆYЏ]nkЛќЯж?Ѕк?\y*ЁКўјЩІk‹eVО2ЗR0Р&3Ё1ўƒЭ№щ)%ˆ0=ХNtф{~ъгKtDѓKд GглЖ ‘NнnJ€ПЪhM2„/ЩЄIфpїnЊmЂшЇ_rРб–ŒкНњД `№щ)%ˆ<=хц2ЏtЫƒ^зн-FNаПУЇ1be№Ћ,@€ІШО$“&aФM…€zЭH‚п$^wpј™3š!Рьл#ВШOж ’ќIDAqь(„2A@Нор`fB‘{‚ъ)КќљŸV}Š˜ІЩ ’inЩx;Ѓ|mљOЮп=tXf~fKkKљл›/Дœ:|иђu9XaК&…$TѓG1Њ6wF04„тЗџГНвТХуЪ[’ЧзМўѓњ’н%ўў{6яY4uQФ“ІlЇЙ/хя.†0ЕhњзOўЪOЎ6Zп}Ј 2ІCР95Лі’рiXC`|еШ6ц‹ѓbOЇ>р`Ц5іггЧNѓ%ОhиѕоЎWоy…ЯTЭМЕЕгGѓœџў$F"Єб*слB“™ѕnЇTJ‡Xа…щkђ>0 Ђк%дAѕЌљ`ЛЬЉЃ••зтІк0 с0<XDжq},кЪš™•љNŽРєИšO/ШїЌљИЉnš^h-V„&@([№Дџш•ЫU—Э^6§…щтШcЎцг ђlьЃ@fEм\Ь{y^```’>)%*eф˜‘ЎVўє‘гЋŸ]љrИšМ7х{жћшЭšАВjA .§­tDENЉОЃS_-•’вƒyRЈ0C€! f>d€ФD )˜љB…ё 0ѓ!$&Т`H!р;ц#ь7aRd<†C ЇPѕЬ‹и"œў[З{љЈаKHEiОЃ я"€ћоЭаЫЙ1Cрe@е‘ОhааєЄ:0SЃкыММ™їцоН{)– СС)qUшЏиsЁIЁiый5]­+ЏъЮ‹$И/НјвœsќћFFЧ`ул]Лwm)оB%с­АЮ ECsDCekёЮЦКFDЪ3nЬќWцгi]8В7,\ЙP=ОъwvуH–Sk* таС/Qї‰#9šГ0‡šЮˆИˆэХлБi)8хЇгЎ– c}ќшqэ™lЮМ,3;џЭќШˆШЬU™/,}A0y4№іў­­ЖЗ™&ЦQ 9$южфДЩ‚@[аўHсЪТeЫЈЖтО.ёƒzеTpъи)ОЊДЪvKtъЊЖV!Ўј u —л/GNˆЄі>С…&\cТŽФЅ§,аA\k€јєRлЅs-ч*>Ћ@Ÿ=#єˆ йЗcпИ{ЧсSqZЪqЃм†“ C‡UЛљр|€F… ђ І%O уhXIœєZоksS'MM"Т|>ЃU…ё wЋћз ЧвSвs6цˆGћU №лу Wƒю ђркOjAуw”a КS˜SИdеAђ^>EhBkЛ5^?љёЩw Оkр |фзšŸЊџm§™іњGфjо’ь “'дœЋСЇќT|кНr1№ёиуЉzцEђЃ•ЏЌфW>qJ"9ЅТЩ3“q№e­!jїеЎ[љfNYAH˜}УCGњѓƒz!Ц›:oъжЂb8;6юXўЦrТ@‘tgЈ@OЇЫ*Щ"9cмtLдZŠKЕІЉ@„†JїяŽз5Ўйf›UРиGьаэќT”vЛмУŸ^АjкНZOFм TnЉ\—Н.зZБэ #І|д sБј_ф’>BљђUs™yР­ўAp[рL[аЩ‹оЗауЛ?Ђыђ‹ЅЦВ9wѓЬf^WMчj­I*ђ;~њx{‡(Ч=С6Ц14tЈ}ьcэvœвTIЗЫEчыBгY§CzU{ДТ|BВWB]О$Ѓ5‡€iкoкУгЈц5џЈ!Q…)‡OŒ|xdژ”ЋжЋ1EŒ/ziњГгWПАz}ХzЪщe‚>Ђ„ ж кЮ2хЇџНŠ1ђЫђн;ˆh%Гж’yт+Оџaђ˜Щc+k2HžЫз-/ZVД§MЮщЭ^—Mјќ_ЗЫЕ|a 3ƒа~Кч7{RЕ[dѓkЫhп@Р[[dуqRФ‰№V№ЄkWЌ§ѕ№_ЧЇФГЮ‹'0ВД ›CˆškЏѓr36Ћ3C@M|pфЂѓ>дд,LW`=WаъY˜kdЬ2e0|ov^FшG`TЬзcѕѓм'žfСвЋoš !8фзЋѕ“ж 'mгђђSy.ЉTЙžkЮr`Ј ošW+Іˆэ€’Ў–›?ПдIевKьŸ8“y‰MFЪЉёPъЖQ2XЁR^€KхТvl*)р7•€ž;џeяZ’ПR7„ vь”!РG@p[*9ѓтЊРЏ†'ДхvdјсxџДЮЏћп емф˜x?ЗžŸWп0 `г 2RЁZ\…ZЩWЩ‰ў‚лRIѓ/@~•М(щyЙ–ЖkMэзZЌзфhФq”ЎФzjS:їQ6ћcјJš7МЏ€юFЙяџёкGIœБ07_;и"ЫjTEј,˜ЊЋЉГё;ukWфЧо‹Ÿ VЌCЦўшд•ц–"ˆќЌqТЅ% KАP’цпvЁ бb†rЁ Єс№ЫoAЩЖ†€ ZšXmؘЗTN Ÿq7чбиѓМ.*8%ЩЗpwKlplŽ1‡о–Я-Гž˜…иnˆ№V]a ’yБ0ЩП’™S&(ЏЄљ№м xЙњыFЙЩђKЌєCAё!~QС~†A~У§‚§9Ž{ЅЅЯЗWЎФqёќEœ:Ъgћквsпœ+;PVёЅЙ§ћvˆЭ^ђЬцЗ6SљmІmЩ ’“ŽrЁ ФН'.'QУI[ ЂЅIЊ]ъы’OЫъ.tНx$…К˜лзnџњфWИ[Ь_qбƒ6цo$W^_јzjFъўГuІ*S§—ЖxЈ’Тb§Лђў‡ђJš7Мa м:їМ\—:/DGnQyŽ)bмhrŠаXЦWpI8ЏфUcЭ.ћж‚:элq]ђŽˆyЋИY}„Ш‰‚€'zz&P‹§Љ'm-Ž–&Ў‚q…Q~@_.АиkЫИ0nЗєŸ1џг=Ÿ’ ћѕызожоёS?Њ#aБ’(ЏфФ-МЯŸdЩŠ9g’r§JІEчХПяwt^ќ]|ЭЏџэ§#ЦEsmыЉЯЗ]GЪ’,AДHМ,ўейЯЯ^Пz="т RюєХs,iчЇbД"8ik9їl|ЕБEТУМPђ]ЯwЮ–œїо~oSў&Мx–ОБёЈ‘Ї#a™ХAљЎьeІ№Њ˜"Ж5 х:њ•Ќ":/р›“ЏЁѓТИvэЦу ФфЇ=xаРn‘ВКЧ­у #ˆТhŸIDATF7ш}F.Цжч­Ч˜Ш ЫWщoйXёS1Z=8iыnї@WД4gšїб!кy[HЮт ОgpЩОБХAјЅ5›з g ‚МўТыЛыwƒv$ьLо5(ЏdчХ1žђю“^)WўЬ‹ЄЂу&Чq‘В~ъРaZeТЉЄ˜І%B€‹Ruх—вWэC$ЉЦдmEлR—ЄВUгŽ SŠ`нmчкhщNкZ2ZM(&Т ЋиX ‚ћС”)1‹‡]lђ^ЮУƒСxl…бS’ ьSaЁџ?[ЦŽ„њ‹е (ѓzŽ@‘ф :/ў’R.0S–І˜ВLI†$Є‰NˆЦЉЃФTYšЛ6х‰]чеЙщМ/\ћш†н?˜l)ц(-у+‚@ђѓѓfФЬјљ_?ЧгI[;Š–цHэхo-Я}1З$Зdp№рщ‹ЇяЏм/LzŽЛЃŒSŒ?]8ї№axЧББcГff9sfи§У^нА‚0 єAOЁМŸюЙwƒЯ}у•hc4_™})ьE1—Ъ%_т›1(€ЮЫ ННѓ‚я>‚њъzшЋгж735ѓЉIO)ЛѓР •dNР ˜dЧжIѕ\"Ъ3яCV‹фqcЩ8d vШЪб3!Lн_8wйЯPdЉ=E@Iѓс’рiEyщ]*ыYр_№R ЩžX№",Ѓћ9 џрЁƒБ Jw6;cє6Jšeg^ф#нћТЙnкѕxзыfЛЊщv$ЪГ™—›эІeѕex %Э‡VМЏЭ2bјJšŒA(ІRх*RYV(C ч`c7РжyЈ1’Xmƒ#7ЈЛьs(5ЌЄљpiФ‹-юjЙ7Œ6цEнXV 5# АSJš }4ПhџZŒпК!oн`Э рŽz*jЭ6nЙ§Дт&˜ВMЦlcRїЩ ЎRIJhz”žжт&!эЋЙZ;б_p*i>\ѕМе ю•;МPX~гR!Gђ<0аЛНcCPЩЋ`Vm­Ъx#ЃМИœ˜кBNZбQVŒЯшM”:еї&ЙVŸp­і ы_Е~8вК9ињЮЩl'уšŒЊMUм‚%Љ?Ќ€0`ŒЫ€;€–a<-!@œGќ‚SнAd9Аhcю7-Мї{вНr§FVљE№џ§џ)ѕўЉ-ўЯџLИeiсвм…Йтˆ„ШсЯ[ўZRЏ}•pэиxєYШ!§h§ЈШQл‹ьЫэIZђhќВ1цщœт48ђГe’š@РЇЃu*жюAxЎ.)збЏЃќ›Mі№Ђtфк[ŽФ…ќy/Я[№є‚‡Ч6‡ŒЖoФЗgлžK?^"QpIpц-ч­ЪfУЮЕ‡‹6ж#mІЌїAJџJVuжаіЗ анЈЛ3@WЙH7(@чo•Лi —gнђuЫГRГJЬ%Ж":u{ЫїVЌЂБсzЄХІСаА@’­ Q&‹6ж# чо„чЊИQю‘…Яє+џƒпkћ-щ—4Ф/j Ÿсž@—” К7(aVЂ‘Tе{ЊCЅЖLаЁП пЅl™АкDыђэhcVЅаWжћpЉжЎkpз-КЛЎ{p=8яЃгяуzy˜a92ѓ)zзІ]Г3f дјУœ?l-мЪbˆ `бжЉ Z—OGK{3јgбЦн $кЖІ”@ЈdЅЂIъӘBЗtvFCjU‰ђJ~6І!яCNDuЭнLa†€‡(i>Ш쇇p#ЙЋх:6ц†, CР7Pв|hТћ`Ћi}уFWa-Длs˜Dy%?ZwcФ+7RхzEy– C@=ќ?%†щЫЧъIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/28.png0000644000175000017500000007310411733011756026243 0ustar sylvestresylvestre‰PNG  IHDRNЌУІkТРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ \TUџџoљНf\~ n[Јn`цnZЂiŠFJЉЙehЄ`ц’Љif€>>ъcњИ„bЙ т‚ZЎЉЅИ„Jj’kаѓ<<<Žž>%шѕ‘уоkРтjн4•ƒ7”МB!Ÿ”Мr@KY"@ˆ ЎG@Ўъ)nš;{іl ьyћNЭљПœNэлј(Ц, ЕYє<Јz‚!кT%Ћ“ŠTii—†zЗi“І;ЗlЖ= ];”vюœ,Ž• YЬŠqкеХ*ё6:Zгk+ѓTЌГЂЇ,Ё]N5эЪАr#+ђQєЌШzЊЬ+йдЏСЮэIвъё >žЅЁЏ xчюцг ~ƒ§ЛŠвђ„вјцВbЖцбШ‡"PVlп›ŽWhœIЉухqєфбпoо{ўЙF(Л@oXД-ЋZЈЩЧdЯЫз Е… /]Љ†?ќ$ОYЄgžJЮччbЭqЬ Ша/vAОžqчрЁƒ*ku6ѕ зѓђйдK*гR4"@ˆ@e[ѕdѕ€Jї§їпзЉ_чшGoоМзиПqЧЖяыючххykНe‘Ыз‰u[иё`в+,№tŒ?ЋЫЗHЙ>r1Кvщj#ž“леВL”ЌWэ‚\В"(•НџљЏЕЏєzE ЗЄнXДЋёјЧ“v'ЕlХКЁнž/Фt{LzѕД&§.ю3Vфѕ™œеeLfzІБЮЪЅ[*ДўXМ>{с,LDлЗщ”"3cвНЛЖ1iqьТs?žФ™МmћЇгЇМ`|ЈЭо™žаМ),[i)чяKюн]4EРп|kљоя§ѓя‹‘ЭЕд4жѓS ѓZЉlWз—‚XўЉR™pш№!QХwDСp№ щЪœ‡z`+p8yј№ДЩ‘ˆ Mz•DБfЩе|кь&K™Ј„œ˜ИщyM›4иў­иЫјќёЬ–В§UќЮБ ‚yЁVLЯkкМiQ­RЯ[ЋUё0Л*€Є?ІžЧјOK99i<ЫiгжэХГTpЉ„,K У|жЏY)ѓ—:Б.Œп]№СUппАБŸс„J#“Lˆp(fЊžЉv#пщщY]Ј.`WдЂ ‡w=яз_y}уІКlQл{{јлB‹іcф&чСRэ_lюїі|џ™лќ?нжљГихQтЖ5оhUуЕVтV`хгылњšjТkН§<›јљТ'#}ќ+|=їФ‰уђђЫ/ еЪ~л`/иOqњ6ђƒу›Џз3Њ;ПaТœOч‰f­j‚ЗЗЯьYŸ2Яo&цФчgГ?УТ.ђс>–„rmŽЌPѓZЉlW@@+ьŒDnчЯ‹FZъЅьйэ_Р нЩ‚d(у~Œ`…TиoŽk8~>ѓ3JіiЉ›,хІђŽ§ћX3>žчџœиЫјœёё KйЊєЗ ‚B™j5oк ^ЋyQvдЪЎ  QШуззлЁЦўК—qнfcUB–хУvьAcУ–Ywюоџ=“{ѕъЅЉ)^SјьеыeцЩCy|ˆ ŽCРšAк^фИШєщ:tZ˜ЖЗmгЦ!oй–х5Аmл:rBаЇ…4š JжТ(”r…<Ё8mП€МШў~Kw^ЊбН•P=OДоНX_РD‹˜WЮыzЕаѕkœ!мг 5н7wjM…<ЯїЉ Џvэ^ВfKeъ~†А\<Ћж‚&Mъ=џмѓ]{ОЪ•._ЛС~KмŽ&;.Ї_–љЈЗ8– 9|MYVЈMЇy­дЗ ;#ЗlлХF”яއВ^ъмŸј’ўсШw>>ю‚SЖлЮіЗяђЕ›љd?6§bAДК;јДїАйM–2T љЦ c/ЗoUДAГеѓЅ5лСМx­ž/ЊU€Є†–ZЭ§эЊRД26™щU№‘іЯV&Ј„,KЇqЧоšѕl'€y„ф]‰Ьs`ШЋе,фeйЛDйСАЗт_+Юž;‹Ч/›—pіє™;YтЏьN &ѓO„"N{Ћ[§xdˆ L@§wˆМbyzэх„Bxg`Дэ§u6|p ЕН‚мьŒѓХХbCНДИнзуйO=„ЁnЫВЯІзhспуy-єМG2rючХїIJOЩhемOSПЅxзFіНKзџЏе‹ЭЫUЯCcЯЄžСюўіэкЋЙћИБЫьsтfіKЉ—Єп—Lп(ЃђЦп78сР—жёSgІDOœИ}SѕZ6kТv о\тЛGME§ЕЋ9EЩЪNRпЎ`яќЕ›7нЙ›эUл‹§•Нvу&T ЄFЉФэFc v@т•ЭаЖСЖ]Ї—KS}ынЄ˜ГzШMš4С-Ш$эЪ%ЌYГмЮ^JWЬЖ†›СжUXєC"э’‚ІRzŠЕJГP+ѓЊ–ОцyšћЈ‡lž>ЃFOŸ3їЋu_›‡&%НУ<”љ ŽєЗќ‰ OР|ЏЖЧЉ:лњєЬЛќѕ‰›yТэl!#KШШm{ЫvКЏй„ЇЯ+fbЉЦШОсŸњYю?qЙџ{тщѓЦtсўЏac6Мw­С3кўuђќ<„”3КЯЬhОШ=cSЋІЯИWpэ‡М‹G.]јЕ}Ш`WcГЂ-ZBџ~8†”}Л‹K‡6A§њВ8Гc>ї“§ЅЧ Nц?h x7ŽwE.qї_‚ЦM‹[OŒ‡Ix+ЬИnћсŒa{€Ъ‚и‡Ž]kx№ЭА№0SћўкећВV[}Л Ј‰ћ#сњЏзёйЉS'VBЇЎЂРюЯ•m Ь/ЬgqДZwPЭКЇ›7ѓ)йЇЭnRЬV=фA§fсЂЯ3oЅc0Єџ–ўљГГ­чз”љoмМ 11xfЧЧ•4~щ! zЭ4Œ}žЮju+]Б,iЙ\.}xVVѕ3С]Д ќЧ6мт.БCХUZЩЛЗГ›œјgђŽэ,шаБя“ЩєIˆp(&=ЂD•šбJXzfЯšТ‰mogч!oњТуGиxN•B™r А' ИnИїї‚@Ц^zŸіЙг|<<„muSG §7Ъи)јАЁBaє'ї]_kныъ o*d[І^‡~o‡ьвYUы№§qъbъюЛяdмywьЛВŠМўЦыЬŒ,с”E€3t№лЬђ?ъзUыуaѕС~>ѓ˜%ѓБЋ9%+Тz*Лк…‡xoњоэжЉ#ЫЙ[PGf2"H‹2 ?{тЬћпgўoОёК4‚НВЭnRЬP=фаCі;‚л]г~Н2ФЈмП9фЭы7ž›ƒ‡лсЁ'(qщВЅ8!рБ;L–VЃєBC‡ь;zmGцƒЅЕ2шмвВхвW@1[™ЇzШВ„мЩ {мЩ„ƒ‡Оgk§0фћж“?Яы?Ш<ЮSЭу`dљ““"PоЬT=,žкsЬŠшПєЬ!%mOаŸ8Z•>$ЎиŽНІQеƒž‡ЊA0šбн3.ма&юзі аG„фхг‹aьh„т­8ђ Вз˜r3ј”ёЬiX+Ф#'д/Ё.˜9ћеЎн’’\ЙrхСƒ;ЈPэк žўyья–>њЯАјўћя~:ћѓЬ?іњ›Wуfѕщ+}dVrё‘]Л“ЮџќѓНЌТŸЋзіjйЄqр‹mzїш]‚І– 9%(ХfѕэъŒ§‘шbь•loм+) &O1‚фˆž8еУУcћюфwядЎп`pп1ЃЧbЄ$Š}Ђšn’хhфjТКП/)z„ВсщСCњѕg›љЮNVbŒ›•Жoн~яюzѕ :>в'/ВheЁšАrщ’ І;›žiЬj%kЏЙГ *`žiqћ OЫ]§^ыПb§Zќ*у>vьйЧœмB/ … і# 1Iе“С!' Ž@рЉћЦ'B­йД1њƒшмl] ЊwќфUП–c:7vz ~о‚ŸЛђЦ‰гЃЧ‹›ЯиQ№—+McLOЛ€ЇЌа‚јvИЕBЏ„onэгИгBапЯ№щ=\ыQWpї4u"Оі_Ёгдѓ)јqwЦОXџЈBMбј'Кя6мНЇП}Ъ=Њи3ЎЬ 5жІDиѓШ уЁ1”(ЧJфbЭq,ИІк”2^лѕОaуfћŽэз-Гіј7S™Uюoщ!W9dд`"@Њ CŠи4W‚уѓЈ.3?љ• МWД’›МГsШBŽўрьШ"mO1s^ЈO—ётmЊnтГT2ЖЭђ{=ZŸћЛ^ї{^њy!7[ЏџП н*УЛ4f x*ЫЉкњ- т‰ wsD=/Ј/ЯMБЌRzВ7ЉwyЉk)ѓqф.жЁ*Ћ†НБ№­аA­лДђЎэS№(7ш,ј2–х9j№[ВЬЩЩи ™И"@ЊЙЊWт–>­Ы”ЙЯAл“ьл3h{кйъ3еcЏžaщжDу^F;їЦтJ.уŒЃІ{цЊhMMOŽ§єйПыя^ЩЛtRxј}с#˜}њNдg—я^Н[6ЋoуЧtБц8&p{!+ot"ЧŽЗљžVЧ$PЕВrT‰Š D€82SѕаžХŸО2с“ƒ—зi{я<1ўЌ‹/*Puhы…Й|ыžИ2[Ј‡…Opгk`ЌућвVз<Єбын;4zўЅзr)%L.ŠфŠОYПл1ќљgь/ўЇFНzЕлЖj3`P{ѓЏ+ƘкDˆ хH ,U=TsхgЏL˜ОчђšaLЏ-‹NDізН=Ии6yыMЩиЗPРF=v<э—y4ЂЛји-k_>в4*„"@ˆ •GрџU^бT2 D€"@ˆ@љ(z„rкеє”ŸSо3Ќ™–OЁx~rP› щ„•Rhљ4Žr%D€"@ˆ€У(RѕP5Іx•_ez+ЈR -П6RЮD€"@ˆpХT=ЧЉе„"@ˆ D єhЏ^щRD€"@ˆpPЄъ9hЧPЕˆ D€"PzЄъ•ž!х@ˆ D€%@Њžƒv U‹"@ˆ Ѕ'@Њ^щRD€"@ˆpPХо–qім™ŒŒ ­)U‹"@ˆ DРNEЊгѓšљ7Г3ŠNˆ D€"р ŠT=иѓ чщстЅ‹ZйUЋuЋжHчb*‰ MDи+ЗЉ0Тn"Qь/a)†Ѓ,„Д,(*фA` ”ЮЋЊ!Ulo‘ЊЧ`B%Š~ЂрІ-[‡I]Ј§чrдЦЅх0t-V„А[DSž„]‘.aQФROBZzVвX+pJTеZhЏ\еaКiѕ…АюЙТЁЛЇ36У…хјCи+ЅЛ"vТЂˆЅ4ž„Д4єЌЄ%АVр”,ЈЊ!Ед^КЗdу‡R"@ˆ DР ЊчDU$D€"@ˆ@ЩЊW2n”Š"@ˆ N@@iЏЊ§—Tню*:XЃžkўмoПўfw+œ.aЏ”.#ьŠи+K9]рх”­"-Už„T&ћ#Xћ™йHQHmдЄb‚%э%Ћž ф˜X­ЧАСzr U$`“ЊЭŠй’Їu6ЉкŒ`= %D€8;gœ-XѕœН+lе?ѓfцЂ%‹NІœDФ—ƒ^ž6yšoc_ХD6 o6#(fkЩSџPП|еђфя“мНS§o^‚к† йО}{KёЫпaБ/]7СЋFzОMztяёvјлюююV№"IйvН•ВJфАи+kД+Юдп›e8„*‹$™Ў‡диЂЪž\lЅU>h6%Ь]8їгщŸ†чžŠ‚ьR­јЙBБVvyVEЋžюЎnшШЁн{vO9’‚œ№Д \9EŽš…'нl^Зљт/П}ЗџЛWC~ЕњЋr*Ћ‚Гudь@ЋїЗ_~;v<х‹ЯПаыѕ дщbH”В›{evБЏ ЇБпMr)QWbђЪ"Щ›ьzHcЃВчз[щc•кMж.œЕpг†MмЧU| XRѕ№\=з8Ѕ}glбВЏОœ8zLшР~кZNpТ“5њ;”}шЯН€Ѕ[НсG•!aЁ~ж'ГZЖюо%8!~ ї— ‰‰‰нћtoјм аAщщ—X†КЛ™“#ZwhД“FчхA`5AнфOžў>:r’O}и“єююšWzu^ћЏ,šЌbž”м%8јЅж ›ж˜gUЉ>N†нP]Б/ДZСпп7:jтрЁƒ—-7‰ГЇN } нŠЮн“”ˆh†N№Щ{ПRiѓQфdиUіцЯaыцqТyyy2dAPРbЉ ‘žьтВtЭ"šт5n>B й3WЬЭ0rфChљ ёŠЦD5=JЏ753Я\гЬ#^щЦlMMыЏŠЄaB+ЃyУP у~L0VЯй‘'ЖЈbчзЋjЌ–СUЯ‡Ѕ2вЇNTїє ычљLu\ПEW“йЋљЅj№1ф_ЈŸП`Vp‡ж8!ртbљ ‚тDQTŠйWй)ДъUЏP\у”ЖкдЂјБџЋ§Ѕ „žFAH§%5iыцп.Є‰>8 c—.Я˜sќаїI;w:—Ъ§ЅТЉѓЇ’6lN9qЎя+=цЬžУNˆ?rиШ‹ЧSRŽoдАQЬ_ђ‚Œ‚ЉbpЖkзeўмy—RгФ‘ ёхт[ОjЭ­ыWwmлulџёћїяЫ#ЫвVАSЌЌщ0эШиХКšъЩ„!§^чCbвДЉ“п›rёTкцuё/^@„п~IC |ŠBё„•щ4!—6Ч‘БЋэПЄѕыг/qћ6vOтЖа§ДZ їБ!(a1&AыОт—•kVё7!bЖІЬs3BkV­Йњ‹xEЇœ8^н­zlм2VЗх+–чќЧ4ѓœ<ХГ5жмPU$ ZйЬ†Ц?dупдjќ•NЄŠ%ЧD*ЖЎxг*bNK5ХK}™“ƒU5VKеsz&œE A›Пй<*lО:ьыo6ѓО6П@Ь/UžД‚пяч|Зџ{œПпљ}љвхМG5/ЅЅіт[@YеуњАГ вVѓЖмy­qwчNp>xЭ|фЃ?трdўЩћ’#'Oƒ?ЮiSЇqЉ0ћуй/wAЋ2ќэЫПЄБ„п$ю  аcWdMЭиё“§ј#/ˆ вЯХБ‹ыдЉ;gюьжƒК‡МЛ46яQ/­иілЇMџдХедLŒŒ–fRщ2˜№ƒWЦ‘БЃЖМžLpїђ~№_уЈў?е3ўЃгххЙћxGЯœХ"˜'‘хPёNЮ\Z7GЦЎrД}kшкo6щ }T(ЌнКihи;ъё*b‘u"тH/.+зЌт5n}„XЩMкŠM;ЖGN&^бZЭЄ'э§n/ нО;Žqц™ўЉДsyr•$ПLцЊ€дœsЬ UЌЪБZЪЋž_ŠH3яeПxў•Wћ!>!У‡%QМ@dƒ;ЁHЏЭэћ’Y&ˆ 8Q№Z•Ÿ и^| TХл2Мj{a HœRMœЕk{™\‚4ˆ{обнёЎчЭœооF‡2ASScДšЧјщ`8ввв–ќcЩхЫ—џёXєАŠ9Œ‰˜ˆ3337lм0ху)+–a W<ЄыcЁ,ВЃ}:2vsVYйY|H,§ћвUЋW-џЧrЯџ­>eњŒЮ/w6яА>ŽŒ]хhїѕѕ}оПёСc_щѕ >лДiуэЃ|–ІЄ—•kVёЗ>BЌф&­0юФ щRфcš(‰Ні IDATTЮ<8o85вЂŽ0IŽ3'85XGИъЗnлš•№b€Љo…­;ЗN4|экѕХ*Л6шю№ ' ZСОLгI—\ЉХuъдiЯ=в›nрlгЉ“ѕJ5№iu/‹i{YYYж#KC?ŠўhЪд)]:vAп<*hдNjEЦ7мдЈЉ]:+Чы“eЌ•L'ШYА3bЛ“vwzЩ8$ќ[јЧ-‰ƒџйSggЯœКџШ1ЧЁjГ&Ю‚нњhЧ}ш+WЌ„ЊїmТЗЯјиfЋKСоkжњQ™[mŸпГYњ-ЮZaяЬcdeЭ*!№Žs(ЄЌVŽ9'85XыcЕМЎњB!qWтсУ‡љ/F|Г :qќDbьК@dз&.a>€JРЗ€ђn9.$ѓєŠЄМM%Ž5~Эк5{їBёТЙ7i/œ‘c#љ*{Бц#CBќрЦѓYђВѓp.ŠY$fЬ24ŠћчччkнДšjŒЇyѓч)$4U FŒ}їФЁƒ(2т/[БЌх‹эхт~}0nЯгхф,‹5Ц‘dU™>b#M‡ЉJŽŒ]ЌЋЁžщWгСfќqІ!1sњL<ЏD\>ќKШ7ХєЊ]Cє4ЕЮ!rодЪ‘БЋээлыц$nIЌ^НКcћh+a1ц`ъM)1ЉНfMЩGЯгRnВ!4|ш№ysцeefaЄeІg"OVIqц‰1Э< %3dьЉ'Y6ѓ†и6г!Љ†XaЬ‡ Ї%Eё‹ЇЊtЄМb:'ˆЅš„ТЛ8"цt:АъЧjЉЎz)7QFьрНm[Зѕіђ6ђ,А>жЖeЫƒТGё‘]Њb~†ќЅз&ОŽEЋМRёјМФrxcM•DYјА ъIcЛœŒ_ОкАџ‡§]^щ‚sџс§ОZЭg-5wь˜БžZmяW{2 №…РЊэЁŸЭћlqЬчС#ЦŽ|1аRўЬџНq““О;0рэFŒG-љb‰b’1ЃЧДhи•щгПO: у8”Ї#c(ѓСуaЮм9‚››vљњxЗžн"'G,љћч1 bе1#& "]p(кМ2ŽŒ]§hGs†…Цd:ђ‘Мiх'иuЭЂŠ#„WЯRnВ!>"<А]рˆ #0в>ž‰о>ш?‹b)ЊzаоЄfМЉгІ"~Ž^Tѕ„н.ь fЉ+Ѕxmbч‘зЎ^ы]ЯŸм‡~QˆуD8œ–˜и4МйŒ`)gѓ'ЄхдЁЖ СbОgE=Or5?ƒ'ь>ѕѓѓЛ–~O |B– ’ *HDщ%.Щ>UЯa­zй<жд4о]!ћlE"Lч€OДфUrц šЇ›Јф‰&=ƒЖ—’)љpф<ЬWЬЄL<ёѕ`ў 1kі,­V{ёќХг?žО}ћ6зV­\5~\$FощуЇЕ“”ї*ц nфАА‘УF^Л|mђў””Vџ cFu юxэт5œэ'М7СМ]jЪхKчX=ЧzтVЃ*)ЭАл…шЛRŠT vэњЕ‹ПXŒOюSХ\ao ђ*џрTќЕSХAЉo>!UЯЪЎ˜ж.\6#У\ЇqгˆіМBA_hАѕHг0аM+оЂсх“žnќШ&dі•-•ЅI\ЖOеsXЋžзпj<*`Ќ!x§ЭK‘ЛЬŒЧT,кТЊ'šє4ТƒžЧ^ІІ˜Ы36№MТKл4єѓщн;:yh\yЁLn“"'Б:0е›Љџ<šaOђh{и€ТцM›YЊ„M Лvжh4юЕнgݘuђф95ЙБ81q1SІЯ€ŽŽф>ѕ|bХ0џЫзnDLˆ€ZŒ3jR”ЂTMЙ|щЋчX:пМХXgi Л]иЅш,ЩjАГД'~8сщщўNИЇЗ'džЁтК7y/ЃЛЇƒ%˜_Yмпй…eq1D‡ gуœЫ–.cэ™ЕыжЖiпІPјРЩќ ІFM5XЧ[ˆ†R“ПTPœ%tї2qЏ˜hAї-ˆ–ЌђNM•–SїиВ›—-Ў‰AЩУ=с/Ё АРДŒ‹%]QУ3œЂaЯУЫ›і,•.›%,]уˆІ8'`*юйЃ'д (ціХми<ƒO&АŠ™Ћ–*lŸЊчАVН–-[В–h'8,3ухџWДл% –ѕf ТВ>BLWсГЎbъќќbV=fvюк-§п}ћšќёd–?–YS/Є;r ЗэР 7џЫљ№—ъў,ZЩ>е/,ЊЖ nЇ>УвнПАёMƒеaбvm8њїыПbх |‹у„Їѕ<-•ЋfщœА—ЛЅNQƒЅ_Зjд˜QGYšЁљŽœЙ$n Л4–§р>Ў!>~ЈпРbЏ‚ѓ№‘УМu.^8zшhжНbїLФ.ŽХH†б§шБгЇRNёШRС)B‡…?v<Ьъ˜%Z4m1ю,iз i9ѕ#-[АЙrq'†xŠ'Ы\4юСТ§'ѓrгhkЙCДrHg +зИтœ0.bмєiгoпШкЙ}ЪyуR/K17sНBQ§р™Ш…ћь\О8іро=OЌDИЅOLdVS—cрЦMъ{_w'„m[ЖI у|џЎБЃ‘9ЊЧђ”щОЏїнc˜0ЬАВ Чй?љhDCDzŒ oеŸOјх2вЫїh€'K8м_*("х…@OБG O(рD2!-ЇЮ"Аe–#Хй0ПA‡a'фmI{ 0Яэлі$эчžqтзЌ&ќš… %ЄбdзИтœ€ЩdcќFY-ЅЊџ№aсКŒŒn]КЁ,Ќ•(о~‹ nЦcUš)љ++ѓDVL}bQ•љ`%є1Vњ ЧНŒ;э‚$66 8ЙХ•)цЦФfц>?ъЃ(МЋИvэъЃпXлЇ4Ъйsg#'Œ_Е.оззWъo]Цв6ж|YхБ(мКmkЖP…ЇC:|тИ‰HО|ѕr8Б\Ћ˜•ѕrйв9ТBХЅsТ^ьŠ}С=е`Gф5ёГГВйB$K›П&jњL&+щЩL^8w6n=—ў'MСhч…КŒа Ж—юŽнАЯЇєr“ёVпЙ{ЧЇžёвѓ5 <” ŠHг.ЄЭ§lюЙ‹чџёXŒfa–eх\NBZN§E`Ы,6ъ‰KЗ†QзmЁЖыуЁk†O<эЁоУнУQљC:KXЙЦч„јuёKџОtС— <џзsбѓ:wэ%-УJnвh*е–ФОYЧaŸЋ‡Цр Œ‡IqHeє+ШЅ>LюёZ_-гом„1q3е=ikзo’М_кхц™УЧК†Ч“`LЌYЕ†9qOFЇ.xvPЭž5;~C|@@їT#Дl)бDЁК)ЭЩ“'тиЗіъ5lваRьЏЭrйвyћріHfiщœАл‹НX(9д`ЧЈя˜5АG“хНwнzw‹š:гŠЖбЋgЏ…‹Ц-\pўЬљeqЦэkJUpbПN={эMк;z\бэMpі”\nŠmkрг{h˜Ж—y/S1ŽЂчˆБ#цЭ™ЗЉл&ќ"ТЯЁg=ЋЭЉ= i9u-[Аи'>9йУє„ h@аѓPє<&‹ŸM5жУSWT–nя5ŽяqіЦlк‹ќ0ђчдŸЅЉЬMЅњСrv‘НzRLVdlЧс'60БГnЃFWЙšњыедыWSЙzѕзЋсЃЧXЩD4zдhш…тН{…nЬЦ,дЋЖnъ–ЦT#у9К,v:|hёТЯЇ~(>і6‰>gvвŽ$s=л YLѓЯАсa0bЏŽљѓцї 1юЩƒЎРїъХ-‹“юnфyЊ)wррЗХЬAЕqB{3ЬМœ9ТnЛ9@юУЛF іФн‰‚:q=™@nлЖ-ќy†ŠТфШЩ‹–,2yŠP1ЁГxтЪŠ§G,юbf{UБ-ЮIQЦЫЭR+А§cцмyьRš7wžЅhцўиѕ KьЃаЃgD›GpBZNH`Ы,^{†­VyџЩЗщAЋƒOD=нГє<јРBШb ‡Нз8TQC0˜ђџ,vWJГ”›LЏАЄ~(жз>UЯaяРUl›O˜юtxїЮЛ:<ЋZ8“ъЌ…Етi%­4(т§ˆР ŽaolиФ{BФ„>НћАPl‰ыђJўХ,MТdБP.Р?((шЕ>Џ5kйьыu_НaГo#уjбєЇ_7ЌГШј„:Ј2ЯаAЁ д юŒ5DŒ]h{,сЪ+O<Š7РрL=w Nѓ е”‹ѕюŽэ^Тв9ЮŽС=,-ГЬ Ль`ХGdНЃћњ5ыGМ3B–pќЛ#зЧЏ—yЪœ˜ђš6oŠ‘#ѓw'ЎЌ];w%%hжКЮЄф$8mю‹ˆžэYЫћ+Кw lXƒ›jmqС– ˜фН}Нё€— ЖAЖЂ;e8!-Їn#Аe яЗХWnЮ0nL1…{2˜”И}[3џfНJёxh<‚ФП…Z-XБ6хф)Ћ˜hД3-зŠ‚AЕ‡zWkцS<)Ї:TСl {ЅtК { ъ€нЎ tЅ'ХBщБHIтyиААŸN§$ѕЌj2!-Ї'АeVІy<з ЫИx1Д:Жt+ &{"Рд‡]I|›]™зЇМ3”Ж—•ePsTыШ{ѕT7BрF;вэдC+}LТ^z†V3oнКхbz^Yq[№йќАЦ#цЭ™ђzHYe[•ѓ!ЄхдћжX(pxП-†лTЕ5ЕююјЃ^ŸЇЧgЈЖzБ•ѓъyŠ ЗOеsичъ)ЖM'Д=i4™“Œ|R8e(Ы8Ыœ„Н Qл•ж‹›6iКjuБЧяй•ƒkGЦы’А"_ŸЏ ЌчКvc+Іu„Дœ8X+`ЁЦсз,Жтс}xpьZ†WЇ~V­ZЉ_ЗЕR„ЃйЇъЙ†UїЉEE „Н"iлU–Ъ[ХэЪг•"уЅ#8]ЉE•оBZN]@`m‚ХО=œ6ЃЙFћnЫp=Ћžkє"Е‚"@ˆ ŠьSѕ\ц\EфIˆ D€#`ŸЊGV=ы~j D€"ркь{иŠѕНzИПзЕaQыˆ D€"р\ьЛ-УІUЯ)žЋч\=фМЕ5ДѓЖХ‰jNи;‹А(b)'!- =+i Ќ8% ЊjHЭлkп.эе+й8ЃTD€"@ˆЈelеЋ”6”ИаИ%q5=4ЕŒЏHСCuй:inQ“ЃЄN’‰ D€ €wоddтэЈКМ‡yxkЈјhНњ>xиžK>Х>UЯњ^НЪэ{<§•U@§ГСаЛЃ'ЖTэ X ""@\ž@мВїямŽYуђ-Ѕ*EЏ>У'”<М/ЬаjДњП шuwux…^’лљхЮєЖ LУу Ÿb-efЭƒШЇќvлРq‚š3їЁО\'дЪ•Lw|žЇ”сpЪАsЇЭVлŒРГЊ -У^Цў<|ЯŠъф0j~Oи}Š7_KПЦЧ0џ” ’ *HDщ%.Щ>UЯйяРeЊЬxЂ%ЏšР~В{К‰Jžhв3h{)™Ђ‘GЮУќcЕ™s™љt6kі,­V{ёќХг?žО}ћ6WЫV­\5~\$FощуЇЕ“”ї*ц nфАА‘УF^Л|mђў””VЗ cFu юxэт5œэ'М7AБЮŠyJc&nM8uђШБуЧpBHмjT%ЅqИМv§кХ_,Ц'ї!ЁvEШI;jтфAщjђ“yъцв.ЮЧК€y&ьC^eS 8-§€Дž…J X)вЫ0зiм4Ђ=ЏPаšэбb* ›VМEУЫ'=нјs…}ВЏlЉ\њњTXіЉzNoе+nЦcѓ8maеMzс‚AЯ3ЌпТЊ—ЫЛкtТ7 /ulгаЯ;ЄwOьшфAЂMы…0ЙMŠœT№ЈўLѕfъ?ІFи“Мкір€Аyгf–*aSBчЎ5{mїY3fЧЧл'„Э[Œu–Цaђ‰Nxzzт%мžоžyEЖЁƒCї&яхqtїt0I2Мм“5Л"%(yОѓљŽ™ixˆцџЮЃ o\љєЪЊšgрд љl‰‡eQ(|2sj‹ц q~2ѓуъщzчЅ№Ы>вIбГGOL ˜Fј/"YL[(`?‰СєоBfі6ŸaxYŽ#,‹‹‰ј :th8›R РЙlщ2VC4sэКЕmкЗQ>МеSЃŠZЭ§Ѕ‚тФЋЛ—9fєqQТOД ZZшp>%Ў -1:Х„yйтš”<ьбў ŒВИЄ+jx†S4ьyxy`гžb&№” iKбАтlРЫRЬ]јd‹Ќ~rАOеsvЋžЬŒ—џ_бn—0@XжS˜,DЫњ1]…ЯКŠѓѓ‹Yѕ`лЙkџЕєїэ?hђЧ“h,ГІ^H=vфnлAnў—ѓс/е§YД’}*Њ_XЬmмN}†??ЄЛ/ъI˜Б:,кЎ Gџ~§WЌ\х '8еч)‰JЖ hХ| (ж™…ЦЏ[5jЬ(ШЃFŒ‚,ЭФœmффШ%qKxœиЅБL1х>$Ј$@иm‚‚†ЧNФЬвeщюel§vƒyЊ1 ~ПѓћщŸ.тМuчœцqИљ$0.bмєiгoпШкЙ}ЪyЃqЧ‹YѓŸœ‹g.=|њшGЙПт УCG8|ќPП§Єѕѓ№‘УмчТХ GЭК—Х} Ф.wCbушБгЇRNIƒИl>9 hXјЈёcЧcЅo‹І-цЯХу˘@`ЫЖCsхтN ё(O–Йhмƒ…њNцхІбжr‡.hхi+Rq[Ÿ s3ŸRь›юgdАsљтиƒ{ї<)ХЋЎЉЫ&щ3Я‚UWќдр>ц‚,Яgъ>S”ч”ш‰LdIюыюЃђˆŒœцYqФсВL@ўRЉ“cG„ћw3šЗlўфOCм?Ÿ@ОзX"2G{Y&RЖ}_яЛЧ0 б^,1#HZЩ–vE2‹0L<&žдФЩфšяжdgь—ѓ{tяˆ+ўЇDї$Юь|1_zlL2йеС\0&oИ1~ЃьBуq0ТЅ™sK3ŒБN•њ‡#E-Ф Ÿ]нМJ>с3š#m8oZ™Ѕ@ѓЙПTPœx!03ˆs‹ср ЅœN&АeоeщšЕk№Еr№РAvBо–Дgл–mЦsћЖ=I{рЙчРAœј)"Ћ `ЄCZM6 0FО•йРJnв +“o/Я–І­hЎХ‚œтЙzЬМЩTрbЕ‡ЁЮdЦcў3%?:aeežсУТeЉ˜‹ЊLРJшcгВЮНŒ;э‚$66 8ЙХUБVМИљŸЯњ(ЊuЋжЕkW§юФк> x„ГчЮFNПj]МЏЏЏдпКьѕЗXѓe•ЧЂpыЖ­йЊ ž=xш№‰у&"љђеЫсФ2БѕЌC‘?ь‚XЕA(ЏПy)F[П1;+›-пА ёkЂІЯdВ"лЩL^8w6юз 'MvХœЩг ТnЮРAАt+р4,н˜›„YBхDwtwјЅч[ЯїСн;Ъё,јЦЏ‹_њїЅ О\рљПž‹О˜зЙk/iФ;w‹eЮƒTЮ0<~e j{щшА‹ƒWNщ & тqаjŸzЦй HЙПTPœв.ЄЭ§lюЙ‹чџёXŒlaт•цуЄ2-лŽУF=qщжp@Р!ŠтК­ TУv} €{ЊБIЁIDATZЖ”hЂ‚Pн”цфЩ“ ё lŠФ^Н†MšBьћлВeK<ЃЈ}p{$ƒЇBњBz$†/6 ВPьНыжЛ[дд™Vцш^={-\Д0nс‚ѓgЮ/‹3nњQШœМ, ь–ШТ№ŸcЛtь Œ-ŠЁЧ‚І~AHк‘єѓPёЮЁ|qзv>бРЇіШ3m/ѓ^&зcjИ HЩ~Š№ <pхТЂ'ЖщD~љsъЯ<BƒњХ2чA*gПВ„N={эMк;z\бcpі”Ь`ŠRlKbк*ЦQє1vФМ9ѓ6uл„™ј…љlЃgЃЙ€'-лNФ<ёЩЩІ'l@‚ž‡2 ч1YќдhЊ xДžКЂВt{Єѕй@envMUkЏіŽ№ћЦиYЗQЃЋП\M§ѕjъѕЋЉП\Нњые№бcTv№шQЃЁŠ7š И1wfА„^ЕНpSЗЪLx4ьЫЦN!|m:|hёТЯЇ~(>іv4>g6ОЬѕНћАшизх•.\2ЯA,” ˆєZŸзšЕlіѕКЏПоАйЗ‘qEcњЧгЏVŠYd|т{EežЁƒB6Јм)KЗЛаіXТ•+Vž:yo€С™zюœцТ‡W ВhXяюиюЅn]Ксьм#thЈ,œызЌёЮ™џјwGЎ_/ѓ”9qэ5mоMљ“S ТЎHщЩІ'8ЏмКrѕњUœЉПЄт†€‡%эNкМ#iщ?ПЪЩЩaqФХЩуЂЇD{>эмЁ5ЮКuъТЩђЧ§Cћіяkжшй7Мд)ˆ*›09Œжаз{Юм9ЋПZЭЃ1aцд™žžиМбНKpЧNнyЈЅ†Gp“еЎЛ’’4kн gRrœ|НлR%EЄЕ ­юи6А_tА”Рф](Xх№іѕЦ^‚к17…ЛЮ_[Ж}‰їлт+7gїžЅ,ОЧ ˆЯaбрG„6/[“џ ЖY{ЄѕйРRnВ)ХЎЩс)м“Сš‘И}[3џfНBŠнE%kЁѕНzx‰ ЕZА,чruЪ*&э П­EЅ‚AЕ‡zWkцS<)зšTЉЬeиKаv7OжбeыЄу jВк—сJS‘Lˆ D€!`ŸЊЋž+н™ž\є~nY—,XИ@цCN"@ˆ D€8ћT=gзѓdf<ё—‚Кя9 i5BнZ‚GMЁNMat <;[ Ѕƒ"@ˆ ЮKР>UЯй­z23одiSбs9zQеѓЌ)xjEmЯC|пБиЁЄъ9яАІš"@ˆ Œ€}Зe8ЛU›ёТwЁ;§CƒнЮMЈ%O+*yZС]+ЄмсCK4R№‚)ыщвhxЫђЄˆI ›6lёB‹ЫV№ М­/|xhC?бjфЄМyUЯйяРeЊЬxЂ%Џšѓ0ш=нD%O4щДН”LбШ‡#чa~љu о@eўЊYГgiЕк‹ч/žўёєэлЗЙZЖjхЊёу"ЏЅ_;}ќДжУ#b’ђўBХ<ЁУ6rиШk—ЏэOоŸ’’Т5aЬЈŽСЏ]М†3А]р„ї&˜7VMЙ‰[NŠjнЊuэкеGП;БЖOiшйsg#'Œ_Е.оззWъo]іњ[ шŽЌђаѓZЗmЭT=<z№асЧMDђхЋ—У‰хZХЌЌ—‹ќadкЏПy)fBžD€"@ˆ@ЅА ›XЈ‹ XѕЭx=^ыЋeк››А &nцTЕ/ЩЈ]ПAJђ~fеГРLєЖЎсё„PШжЌZУœИ'ЃS—NA0є?іъ5lваRьЏЭr[Жly)эRћріHЮbщЩAˆ D€T*ЊЕWя№‘Уќ5f;ы6jtѕ—ЋЉП^MН~5ѕ—ЋWН>zŒЪN=j4єBёI%…ži‚;3XBЏк^™З2UfТЃс9К,]AAСЁУ‡/ќ|ъ‡тcџpЌ]Зіѓ9Г“v$™ыyм^Шbš† ƒБ[єp`ЗWˆqOt2ОW/nYœTEуyЊ)wррЗХЬAЕqB{3ЬМфCˆ D€TЊeеу”aКуf<<Ž™ёjЭ|ъс‚'<Ž!т§<ў.ьЭїюнiв,`rЄёv‰LьђJ—Ч<ЖdЯуъXД   зњМірП^zљы ›}jЇ<•‘ЎџћпџЦ:ВЌ†Šy† енЭюœЏЯg{YЊ•+VЮјxJLЌxCюЫ/ЗƒS–œjЪХzЗ.#Ѓ[—nˆ?fє˜аЁЁцљ D€"PYžКŸ‘СЪNмО­™Г^!§ЌTХњ^=lоїoсo%yeЩ*&эLЫЕЂ`PwжЎ)ЊWY-rŠreиЂЮ.PIҡ艄EKi< iiшYIK`­Р)YPUCjооЊhеƒVЧ† щv%Лl( D€"р,ьSѕЌ[ѕœЅЭвzBлГтДw=WšЩD€"@ˆЈtіЉzЮ~Ў 7ir2 ф$D€"@\Œ@еКзХ:šCˆ D€ыьSѕ\ЬЊg …"@ˆ DРй иЇъ9ћ;pНЗЈўD€"@ˆА‹€}[Бž5юяЕB‰ D€"@*’€}ЗeиМз)žЋW‘|ЋrYціЉЪ4*Ќэ„]5aQФROBZzVвX+pJTеšЗзО\кЋWВqFЉˆ D€"P)ЪиЊW)m B‰ D€" žоSŸ‘™Ёгщђцщѕz­›жЇО?ŽчёЅ_ълЅг>UЯa­z'NžXЕrщЩ“чЊџoѕ~={ЭњtО{mwХ“Ї#ˆ[Жтўл1‹Ф7ѓвAˆ€SXБl…PMР7ЅІ–ЦЃІ‡yѕщѓrХ,(jr”yђ!F //KœPђ№ZTmM­VЃХХЁЛЋЛvхZГч›u~ЙГЛЛKЉіЉz6їъUXWЩ ZЕrејq‘kзuа?вЧ.˜4:aSЂ,9Ÿ€ЖZЅеблл;++ЋвŠЇ‚ЋWrяGЈьРȘ8•1.š+uЈ О+5 zоЅДKh ОР№OаkУ?­ж§iїŒŒ ќ,щвП‚ЕНr…lŸЊчАVН„M lhj4šY3f5ѓo&ЉфЌDO /іі9+5‰m›ѓ0ЧJ„в•ыхTњъQŽFРц€БСбZTNѕ _Љ-ў}Ђ/№EšѓPИїА ћЁXlжв€r*В›Cбf„Њ€1§ЗtX aЯ Э5 кjZИѕ‚рWп/уn– ћ…єs ін–сЯеCЕ ngН‡жЎ^ы]ЯŸжЃQhY'Ј9sъѕq­•№РDf3e4нбh7˜юУG„7lк'8Эу0›ЦfK9ЛŒПОPМf=Е†Г–Bu|iК Pѕrєт™_(дЈЅi№ДбXd—i{4„ЦjBЦў|РL*0м_*˜O ШAw/sЬш1ЂбOД ц=ШcЙЬЇV+ъpилŽSЈІе Z\ШПы59‚&п zž{=/їЦ^šКЬЊ'љ-Їx…"+Х АЈ_МНqyŠЖгЙЩЧFZCŸšвўZžd{S–VqAU i_Bc J;w6qGтK]р4|ØLШˆ&=ŠхlrаX5‘(›ПyйтА’‡­Т_BAaiKКЂ†g8EУž‡—6эY*'%,]уˆІ8Š,|VœbnШ ЁlР№Z)Žv*ьSѕйЊ…lќиёЋжХииПnеЈ1Ѓ@aдˆQЅ8RRRvюк-§п}ћšќёdENŽ\З„Чяљ˜ЏюCB @Уc'вfщВtї2Ж~ЛС<Ÿ1 ~ПѓћщŸ.тМuчœцqИ~l‰Йц9.bмєiгoпШкЙ}Ъљ“ q1 rў“sёЬХЃ‡O§ё(Хэ„ЉR9†[Б№6џЫљ<ШэцНvјјЁ~‹эТѓ№‘У<ц…‹Ž:šuЏиїиХтFв‹ч/=vњTЪ)Y*˜O > SгЕЫз0ЂZ4m1ю,i™%њž‹Ж‚€ЭЖП‹Ц<­ бzКЛзѕб6Њ#šє<н {Ё$ПхЏP+ Б_ВВB„&n)Кё.qKТр7УБ‰оvкт} јV&Хо”і—Ѕ9qR~8ЖsзN, 44lШ‡и™чПћ4#ZќfССэCџ\ўЯзћПЮ­ри…aBр1ёЬј &N&з|З&;cПœпЃ{ЧŽС№Ÿ8%Кя С<лРСœ9|&ЃЇxмЩŠЮкПёОЮиПВД•fЮгЂ&| хfчОи\Z–уЫ;ЊJЃї—Ы3ИДй Рƒџ|ТЏwŒщ˜с,рbЪyійgГ8ёˆ’6–Ы9Йт]ѓ9…ёФ.=ь…rг`žЇЛІЎЛЦЃ–F‹9g5qцЬ‘мwЅx…ZЙyПј6ђmќќѓ{ПЗжрГm‡Ж>ѕФ.S“бЄ‡•IFБ7‹ЅЕ0‡ Ž4­ЬЩПYрЛ"?Š\ЗfЅ•"ЋRрЅ—БQKЗЂѕЎP ЊЂ”+ZђАK;p.–rФe\Ќђъ=мЩыРG#|Ќ\ув‘РЛ^qфѓœ­фЦу@А2кЅб˜ŒЙТСl›Ж[R(рБ,рШцФЧоЛnНЛEM)іД…ЃWЯ^ -Œ[Ирќ™ѓЫтŒz,Ф%o‹†џлЅcalQ=LшИъ!iGвЯCХ[dђХ}ВљлшYХhЮы™kјЎ\гGU єzQ/d‡тЊђФšјв%_рq_Џ^љљKX†*гšЪџZšdЄq,Щ–цKёeўиЕ9jDиЊЌтпGВpвX5gRьРŸœь!ѕ€я}(vШБšAНcJž›FSM€ˆЇЎЈ,Ыоk\qфѓВTцfзhЗЯЊЧЋтЄBтюФNAЄзфЖmлТпz‹&GN^Дdщ”ЩSЌh„жsЈтЁЉЋ…лзo№јёgЮœНtщJ:оH“—‡э‚Л›ђЇ>7G_Єщ ƒ‡ž7w&Dœ3>™'УиђХіkVЏЖ‡m~xŒ"gыUл П’Й7UˆЮBб#џOIО†ƒ2‡Њј oо'3xЊбЃFЯœ%оY(рf{dТƒœK бnЉПІ~85іБ‰[ xсФ-;pNŠšj)>ѓЧ№›‰бh80,­G–†цччУR€_&аЃgDKƒ\CЮџoNШ€а!!}Czі6œ}Cр }34|x8юD 1Цp†‡ОЮL€ЌсŠWЈЪ я3ШЩб'lHажђєoa|“•ЪДRь–&iKВЅ9ФR|™џшQУ&|8%рEk›ЫiЌЪ •в‰зža[NођФU?ƒ}Gдѓ 3цСь=>X9Ed•Хй{+Ž|^–Ѕмd_pvіЊЅъ­_Г~Ф;#8P&Œwфњјѕ2O™ƒ iѓІЁƒBeўфTCрЩІ'8ЏмКrѕњUœЉПЄbWћУЧ’v'mо‘ДєŸ_хффА8ИКФэБІлz<Ÿі юаgн:uсd!ИQfпў}Э=ћЦ€з‚:™Ђ ?˜их•.X&c>}zїСц†ОоsцЮY§еj 3ЇЮєє№lнЊuї.С;uчЁxю`PЧА76lт=!b2сAЮ%аhЗд_XўлЕsWRђf­›сLJN‚“oА”JЕ ІSp`лРе-E”ћуо^<Ълзx j[4\хёœжМ/9yWbђЎd‡ПЯОЏєшб­ЖаaORB|6ЩЮм?hМЁŠWЈњ pТ{І|TЏ’РRБD€"@ˆЈ|Д€[љ}@5 D€"@ˆ@9 UЏœРRЖD€"@ˆЈ|ЄъU~P ˆ D€"PNў?!S bн#"lIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/26.png0000644000175000017500000024575511733011756026256 0ustar sylvestresylvestre‰PNG  IHDRА7FўШРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН XWЖўЫпŸV’ƒNР5„8šИяN”LT4#jќGЂ1nЯУрОмтўxФ8ЈИ‚/ЭЈhœqMдhаИ:qДIzFBѓ=чЫџœjЊЉnК›юІiЊ›{ОЏњоКЫЙчўnuеЉSчоћФƒмм_@єzЬ\њі2В™ЬЇЇМПц!фЕЇкеL wЊМeaУКlЫ$q.p+к< є!8ц\ЛŠO7nыqhO_ЗШД{OТУТбЇџЗ№“™фмЬAXD˜|ъеЁ/ѕХЋТƒТ‹1ї и*iЊ.ŽЙ/іЙžJЎ'Ї•W–[( j=!‡5X kгжiх••]Ў\ЕЦжciGџz}^ыуБіDC€@@ pџpД`M—c Ќ €/!рЊђЪ[V~k›„ђZл# к[xЕжVЇDК@@ д% ,žђђЅОјЪ˜дt?Ԙз4Тъу_ЧмзњЌжX{ wѓГз–ШXC .Y`…ЌЕ+@ЄyќPї•ыз№VƒŒuqЬ}БЯЊQ`РUеŸРнќЊjOф ,Ш9˜ƒ+WЏX&;tўbлЉœСЁВ5UHјРжВ‚Џ@@ Tе(АюƘКТяъ'ЩШнћ4†ŸЁб4€ЁшGžzxќ3BЃ‡ЃэєеХ[Еѕ{ѕ”d;]pZ -ЯU+ИŠcхuюьЙ.IИdйЊWНU6\jXQIјР*РQ€@@ PЊQ`Ћc1ЕeщЪʘ%ЭжЌАўU/ѓ“Нёch€рњхЖЏЇќ%хе№ЏшО9JМ|WUеUщkТ”•ЁŒћє˜ 0H!Eџ­8—г——хЌZ&_ГР™-((0ХED ЊF`uђ:<Иw+—ЏЌКАJЈFuХb*уУ–ЎГЪЇ•Т§Ыі;ЄРjЮMќMnЫJЌћ%} аГ‚QBjˆП_%ўО˜ [b}БoЂOŽ!рkXYiU*ВŽ!!J €цW•1рћЉ|o­œыоЫЖTЃРVЧ+A$[АЊ‰зЙќ‰ƒі?+•§ -ЪEЮŒ 0hъгЁ†кгДnУЃbwя‚рпvЊ@3s{&взЇуaў=4yЎFФРТq Ѕ†d…бкЇ{ki™›3Б|жrЉЭFСаЇ_ŒŸ3~х Ж\gцЊ™HONЧНюсtўiЉ­ЬЭHпИЧLŽŠоcr}Y.NuДЭљšєџNХ?ўq­žo…)+І mG^зT7!рkXoТ^Ш*j 'F<сыUWЁшQ‘KukЂR*WM4igu,АGщsЌuоŽІ†?эbiо Й ќ‹jБ’JIŸ|ыћ#їтY(?˜,ВRjѕПCщЯаэј ќОЧ/кlŠ•зхг–#ъНї—Љмђ)Є€Z#FХ@‚ьЬк‰f!8ВџўзB”>.ХŒхцnwГяbлщm№ѓ3ZŽ%9f%‘Q&9’f$Y“ЂRšЃm^ЪК„”#лpюЫs˜§іl,МŸž§Д?‘рyyЙR…Pч*КXкз,А.Т UKнŠй fcй‚e3~LuX‰К^‚€s/(7ŠY—ЦМнxч+>I.pjwrБRjеldPm ,ѕjџŠ§•eg‰‡вд™@l(ХЃBќб›Ž^яMю&b mAЎ4бKУqђ“ЕGlyeš0?Z­V:т(ю* }o(BZажЛЄьімWbѓѕСЏ+Б9cЄIyхЬ 9&˜ф˜0BЅzжmsТд R›Н"{IlюхоГЦNЄЙ€@№ГЁqnЫeš‘ЊАVд-ЉXѓбp(Јn ЦМnŒГВ—uqЬї~ю>””ГнЪCЮу/ЮlШR ЉFe lѕШ€3Ђ*хгБ ѓЗ •mfџX‚“yЦуY`sщШ."kliЙ[[FщшL D7†Д4ЦЕ4ё‹-ЕіHVт‚››Š)уІD"9п^E|L<ЂZEЁg“ž?ї>,ЌT›•e%Y•#ЈB&eYeмЉ6ƒЪл”1q“{‡RžКgЫЋєвтЁЮ ЌшS_B`` bGЦ"0(|Ў$іЫJ뙆юнкЃyhњGEB^0|HЬ8x@YК|кЗk2іЉЄJԘЋrXjTЈК8цЌИ†$.GШи‰’++­ tиШмZv 7цп@Šџ9 {ў]jяyNyЮŽˆч›KЧ‡s?,ŸМ\>tUфѓН”­рэц­šcњЬщцѕ‰2_5 lu-А Ќ­ƒЁ“љ[†хАJAgВДђ$.&ЖОВЋ€Ž&r]љ‘ќ?o— #ЇDjущкGОЮSКž^FєЄшJnRMы?MC›Jќ№’I—гЄњ"“О@/GMсєqтќЉѓXœКЇѓNуиїЧŒyŠzІТЋrTШdQмtZ6MLDЄкшђђР‡'HX`(oлœ‚бcGK'ЃGŸ[RVVўМяВsОGПшСˆŸ/‰‹УкеkЭŠЏJZ…I'™ќеЭ2Х‰*cЎŠa№ЈbЬJ++Ў|0ш ш…;ЛўwЛCcБdхмПwпœЙ"wюнЇЩTU>—;›u'N~ƒ+чЎ шС}Ќ^ЛZЎ.…Ъ|е(АВeдLRŸфVGЎdPEЈ†”Yђ‰эKJэа–ўx‘ЌЎleЂЏЗВlvYhIyѕћOув[іФ1q„”В<eњ2шѕz$-LЊTЅщsFEїмБs(Ѓх—Ж'U~X‚ќo™ќ5Ц2+ЛИИЮˆqхr,L‘d`9R(^%UЃЭ*y‹ЊD€-АВ[UЈЪИA(]~ООpC‘ИqШч–/Ÿ‹#˜ОdАЏљиёcq§ќyЉ|ЏžН yJcВТцбЫЧБуЧ;*ж в 5€ѓš@Uн<ыъ˜П1Иyѓf"oгzpœIЖТrxј/ћ1kЮL|}ІВ{ЂЕнГkц-Z mCr“Єc)Хї|ОЧTДЊ|.8oў K++АaOmщ)їGЪ]Un!б#ЃЅ*М"@tлH4 ЅUў8'3OJn 2П9ЩsАfЦLy{ иZ:f:MйИ_Ю–ТE›aЭœ5xwр{hњlSŒˆ7*Ѕf…lœDПЭ+‘bЯњ=кЖПIŽУЖГЊN›6DЩN"рщI\ЌДЪnіBљsЙ“нёxqў<%“Џjљ—Mлv А AM*ъ2Дm›0UБI…вU‡•иŸ_Cт?ˆЧВ…ѓ0 џЌ\НS&O1ѓK—eЁ:cЎŽq№ЄuyЬYqee|ЩжWŽЇ#ќ$9цнгнCˆbŽFH“<ЄdЊ*ŸЫйЋo™Џ–-АЎ*БМI#Ш к ћІ—Я”'п4нЭ+аЭ‚ўo§SЙ’ѓЧH#§VKЈБbLŠ-/ЗХ+Ше *b%VVdЙЌ.ЯјщОUЋVІЊМмджу[Mч‘'iЩ‰mЛV.§–QA–Ы(—П’гфpшЛCС‡’,лАЌяj›–|”mŠИѓШ“И<сF +­ЮKЉЮU)Ћ•Є&%4-= з._ƒв_­Џ/GНŒЉгчšН|VЊ_žа'В–-_†еДЛк…sМ:йVQ‘^лˆ1Џэ№|ћuxЬG\\…онHCgЛ7д)cSШ7v/.3N^-}Ь)Ж•ІСMС_™d%4О`5Є4™ЊЪчr•ъ“‘NIЪ|еИИЊМ*;цЖ8­ЅмБ3кNžŒ^)[бwЯ>DgDчO€f№шZtУЩЧO##ŸZЅ?@у–U/m”8!б8ЙƒЪѓC0щCЃ СˆЉŽ[PнжGСШы№є$.йmРы€r“РЛїяF.=Ь”WfЭЪl‡РљŽR|\<–ЏMТ”ј))НŽђхм‹€sїтщ мъъ˜_км§Ч]>r'OУЙѓWqѕFriЙF=Oю!=E[O#љДrY> ХdЬГ­П"fX &BџP/s>œ#ЅЩзAUљ\NЊOЎьоШёƒcфъRЈЬї ЌYяjъФ_‹р—кJ‡ЋMМ2јЌКЗЎ_Ѓuc ѕ‹­Бцз sЄ6zWѕ|OX^e |Э+їЫбpЫІ-˜5s–ето}­Y‹!ƒОБV )5є рM=-ЏЈ*ЂD@ŒЙСVISuqЬIџEB?В_ЄД1†6gВFХХХ(**Т/ћŒх‡МIї;Щ k­40mЪ4$ЬK@зЮ/JФ •вфвUхsЙn]Кс•]ё4хЁƒ†ПtЩ ,ђŸx›+IіzЬ\њі2В™Ќ(*Ђ€Ћd,ЫР\і“ЄЩxв‚IєFKяА+Vќ[q.хб9КЁ`GњмМŽЗѕ8ДЇ/Ќ6эо“№Аpє!_LGHщkЏ<ћР†E„й+т5y5е—БcЦв$‰7$?XЏЃŽ*ЦМŽ ДЂ›uqЬнбчўƒњK э™“ghК/ЪsœqѕR V!pп0Nї#Р“Иф‰\юч^™c]ЗРVFФЕ”нЛvуЮ;Byu >ЏЌ%Цм+‡­ZBз…1П}ы6ђѓйoRЄUљРЊcl„Jxr—ЃиJBŠlQhѕ\+Єlp`Љ:S-ёfԘ{ѓшЙ&{]ѓ›Лщ@5TK5 luV!Ј!lЬиЊ]>3aХ‰O"Р“И<Е,(,АеПŒœљV§ж5 Ц\ ЃрYԘЛogqT к-Аž”/3љ6Юмшž+BСEоrV‘$Ђ^†€и‰ЫЫLˆ+5‚€jXЕћРzR>ЭЏjdЌS€S ЌSp‰Т€@@ рATуBрI gUјцЬС•ЋW*Ыʘ%ЅёЮ^Žlœ>"МGVu\%-mсHY[eикъЪ&WnФд ‰э1Cёіt‹Žm5(вkyЛx‚„Ќ'Pm€+ЈFU“)+ЏgД‰чўeћR`™AЛё6йиЬ(>IK-=т/Љ›;гзV%­ТЄЩc–ОлцxYГЖЪОщCшc‰†юžќ:ЋЁgи3O‚,Г@c:ЦDPК>ь6Е†РЉO–ръ^Zƒл№Йe5€ЁшGрЉЇСЯƒЃGЁЯє•Е&›Ћ ;ЛПМЋэxkНЁ/ХЂqЃ`|zu+ЦušŒ7WЂЧ =аi ђхаu€Р€њеёj5ИџшŽdј1<.ІЏ™d‰uЉuŒ”r)уnшВ[XЈF•-™nщ•Ъ˜ŒИИ НЛ‘†jБ"Пљ••бŠ$яоЯїттАTIђвЧœRjЗ1ЃcА|њrФ-ŠCp“`фнЩУжЗb^в<Љ^Ѓ†  ЛЃCp Чџ`ЏЦєЃI[ыБ`§GŽї{sА]9DІч№є$._ВРІЅЇ™ŠП<$ЬI@xXИ)ЭZФšЕuњЬщRб"њ‹ВH k }yd%6€?ў I$X#оі{rch ƒыгР‚мЇžђ'х•Т• ї›”ц} Ќr дЈ„(хЋИdEЅЕзы!A!0м,ТѓM"P№ЈBzAџXј—bСЅЩds­Yэ‘“Ÿƒр8ї§І6zчлmЊF•-™j€›зy=ќ?‡mŠТљŽв%šWе#рЎД,OД’ ДфCЇ!_:~j)§ўНћрВL/д+‚СОўŠЁя •ЪЦН'­(а„VWёi3іƒqxЛял`ПVЫ‰\RE+?бoEуAюŒьmф=€жKhYЊ“x—ЇШ—,А–˜БKAЧЎ-“ЭЮe%Tim}F^оŽўЗѕYqЅƒWVzШ8ƒЌл@l R`хrf]?qFёрВ2YnЭЈзы%х=ѓЏ™$}М?с}ВDO’‹УW {э1уœяrИ8ЇП>†O5Фœч`Шр!R›yt=Я™=ЇГNKч=ЛєФвeKb\EJДјЉЊ=‹тXНr56Ѕn’’ЧŽ‹Љгmћ&ѓ§ИsRZЫ™а}8ы~ BŸЪг ЙUцx+Y^окЗЫMуЮJ*џ?žoв‡tщш…БпFтїоB@Ѓњˆk™ˆЮAНpѕЛЋ’џЋ†žуО@ЉR1{Сl,[А cЦWшоа76Uš,АМIхFЎШ—ЮŽсРФ~Ѕ XyЕFХХХ(**Bі>cљ9oЮЁOђ-дZ c+БВ"kYЪZž5Eж2mмьqрC@Р—,АЪбфхdц%ЬУЇŸ}ЊLЎ—XЅЕЕшQ‘T.юœЌИJжWњ[s<‹о-Xb*zTХЈБXќЪJŠRб“J˜GО{tКrСИQЫтФХи§љn“BщŠЋ…НіXA}ч­сЄРЎ?(‹ ‹%ї Y8v4њE–ђXЦ7|Œ‰џ5П8(‹\)ДзžeснЛвpієq|yђK)kвИwБ;4C†hЫђ|~.ПDJжўgEnйџ‘uН(Ggє“оZ š@щ3rpыvєВRŒаюQљm/1БЇ2ЏŠљб"@­V‹šЁјћуØsg(žёNRZЏ<>0mN%AHЗсŽш­Ÿoи_SЗЄbЭGk№ЩњOМNUЭ2ZjВРZћчUGОѕ_ЌЧМmѓ0#e†еcщgKБѕфVSГЅd~хC@@‰Oт’'r)гk*ЮX_ЃѓпžЧ;#‡#eCŠ]+їлdE%ЅTЖЖЪJ-Л pšd}ЅјхrхU~EeЅFIЌLІэLCїnэб<4§Ѓ"СŠД’иRёлЪoŽЩq“Ѕ •œ/+ЂЪqe=gт™3СJ,?ЈљрјЇщŠ<ЛZєњ]/i‚'OpcW žјц*­\НSШТЪ/CьКСюN+—W|†Пž} “&N’&ŽђЊ'S'OЅхќЎЛк\ЅzŸ~іП˜9{‚ƒ‚Ѕƒуі^\ТŸі‡–мДѕie Кыўe|)aиВzўШОxWށтSщ(>™Žь=Щф3KЫNьuQф­ ВВ2LŸ:Э[5Gћv’’Ў?e\ЎІLгхч-Ц\ŸЏ‰иQБа?ЄЯйхФeS7ЇЂ}ЇіjRnu'9йЭEйІ\žCgљWuЭ*y{s<д/Пkє†Б ?Œ ™W‚†bX“x„ј‡QояЁљ•B!єьZhџКШПVЉЫЇО:…ШW#Ѕџ8џзwяЊ№БЗ—ЧŒjk–)00Б#c>ї&RЫN5“'хЛ}ы6ђѓѓе ‡­–'qyЂy_ГР8xЦM@ЪцmhгІM•ZГЖђІ!Liƒ€фH`nW`БJ~М#,ЂƒЉДДђ hVVўМяВsО—ЌŽёГт…щw]ђ:\К| _џй7В%+щтє$’-ŽЪq)УM?іFG\-ь‰ёѕЩЃа=а‘GŠ;)b“'M–>гЪuЂDcнњu’ВЮЋžpœгмEмЗЖmŒ“R™'Чэѕ—Ы„“q5œœ›iоB)тоtєЂxor/0YhЫ rЅ‰^ŠГŸЌ’V­1n Южю_~ƒГYg•йUЦпŠ-]ЏйзГЅk"ЂU/L0ЋwљЪeœ8zљRњъ•KPєSЎœЃ6}ƒ_Ÿ0+ЏY"f&ррў ыЉ`5#бЏEcёвХ’Щў~/§gЁUЎВЋХš•kЌц;’xOWˆЛЙwI;!Й-Аћ[}eJ˜Ÿю{ГЭЄƒуœц.тuЌйВ+“qmkы§х2й?–рdžёx@жз\:В‹JШ[юV@жxабљi К0ЄЅ1Ўеј›мGфЖі|ОKцЯ3YЛчQм:vќ:uэ$]/,їДгpриQ3 sжt91кфvиzЮЧвEKхЌJЁ#ќэ]Г•zqТюkeШеГAn?в`иgР‘Ы:пжЁэ НЁЙЙСv @zГ  С/ЙO ЌЙс­~§њx {нCš@mёЕС^CчiЌйТџѕ… 2ашNУ!ŸыђЭ•r5+‡*ШSO Ўvљ<‰…hЋі№ф$.й[UX{h8ођьYГЅТ˘Oмњўћя%С'ЅЕUЮŸKJ…’јГŸLБoХЪQЋ!В—‰•иŸЫgє52ї,ecEЩ)?;j™e…uъŒЉр‰Ј жטwпGУрІ•šaW‹И‰FkЕН U•*Z$№:вь† ї•з;МˆфЄdЉ$oі3lоџОtЮ>АœІ\5Т‚ЅSЇм~хЕ­йфб™,­М66ћСВѕ•‰] X‘НђиЈФђь„#ЄЗГC>#ь^ 'зrщХ{?м#%Іт…3D—Wёsэђ5,\Дп^љVšŒ+ЗИ&ј…HIмІrМьЕщyмИ ЫkVйЎ7Чм$K;mюsЅ  Чr5hIЋ№"йєžЃi3~…єџjЪšvƒпГєЦ’K~№†‡є"C)МJкF_w’ў; KV,AрSXўQ"Йфє‘ŠиЫуžЦzгЖ(,(Ќp?)яHкЖM˜:{nљ™К‹ПCэ ыI Ї+НTЛ|ЎєIдиCР—V!pTСSт![[•iЪјЋЏїƒFVBщNК„|Xчк™сЎЌkoHы:g<$Y`-ѓlЛв'~HnJйdbЩИzєюa:чЛZ№$ЗmлsЕ0ЋlqвКЕљ gгcпDЇOŸFк6RЪŸDьлќЙцІќъFZг:жWЏ]•,™Ь‹уœf‹rШЋ%Yи—9”ЌЊСOKђyYbГIwщнФЈађ4…l:XЁeeV9щ‹k5ЅЖrЩJlХ•д€кa?YV ™и"ЎЄQуF!qA"в_N—ЌШЌˆГЅкёњрžiб7џv—ўNЧ?ш јMŠЧŽыd+ІНt IDATЦтcF‘”_V>иШKOёD.™5l$­ѕ,ŸЛђ]NRœŽвчш5Дdеє?N7БsФеBiљ5UД>bИЙЫЙQєщm*ЭЪЄвvuђъJ І3э1ceљ7bў?,_Й@ъ3ї›уУпnjПRЄY7ф>І hТж9Rf3o—р-ЃХЪывTy•‰0šЋ§ 0Д%06ŒтЄа6~ВВ AЬАЬ]˜hrзHЄИ’ZПд ›6l’Ц‚ecKЕ’иš].XСeExкœiЪlЋё˜С1рvXц _‰Дd™-r…П-^^NыБыШИо/мэŸ%%–п'h ШFшжˆДлрчg;…ЄМв&ДZб гFцЏcўГМ&ЛМУeщџбN9ёџйVž\ЦSсnrOъбЅ‡™ђЪmГ2лЁCpО7аЈEHЕ[8н-ŸЋќіЅk0Bв7—IC‚љуУ№с{Цу~a0ЦЧг'Аoд2ВЮЩб3ЈЇsба@џ›Т?|ŒH5V*џхџьшQУбœЦlСТи№Ї І|{yІBŠlйДЃFŽВкк„wпС–m[ЌцЉ-ё‰ЙЙПАPЏЧСЅo/#ћ—ŠЗ~O ЋvSwЫч*ПŒЭZК!`щњ\lЅџNЮЗЁД5&П9p•^ќО 5– є‡ЫџF‡}щžAїДХJЂМ6­2ююеутЌ<Ы20—}‰шс/=ўщсЧMОr|”ЯЅ<:хнй(и‘О7/‡уЦm=эщЫ% ._рн_ин{2ЄнЇњє ГsKШ“}Т"Шхd­/’UU~˜qœC"VXŸœћ-‘nЃЦDёыUXsk(+бCG‹иыn\…ў‡Лx№ї‹а‹V!ШE()ІЭžGŸє›жЊJil}Nkтž9{Цf‘с,ЧќшwРЇ—Œ/iМyх‹Пвa@Н“є€н ДŒ ЁhYМ“тЪџ§\zsбг›Ы{'и1и3ЛЁЫ>Лe­Г(П зКpе"щ)Щн-_uјiъUќiјгЧй‹Х˜їЛ2џЦ@ Юш‚i[< AУоYоKВ"[=pVY•eмИr#ЄfHЇБЃЦЩЩn ]Q\]mм—|`]Х€ы)­ЊBY­’о]зЯ_‹—zI‡Ѓ=YВh иzЮЛФsа`GЋŠrD DKVW:јБљb­Wмˆ&gХвю\4ЃЋ ‹\HaЭ>MыЋѕ1*Џк&ЄЬвѓе‹XТщБІTЃРКj‘єRю–ЯU~ Ы№рQ™ЩŠwтpћ'Z‡rЛ7r FZiOчвbяV^=5ЎюlчШЎL\<}лOиУЉ‡нЩоуМъКЌ-РY‰Е$kiТ*k‰Rн;Ѕ]Пи}‚7І‰&п_v+Є>ТhˆEЏU†L†•§њсаўmрeП‚  }qђ‘ИL}ѕТˆjиъX$=ЛЛхs•_ц7z\@0–ыЇїK |.7h ;JF}бл_хb{…ыC№А[вœ$нwѕŸЊи‰БHJHВћ9_iЅфй‹I&слЏОўшјrGЬ\;SZ‹рВ3?ŠCњњ4мћЁЇѓOKŸcVЬ]Ѓ{*кT ы4џџž‰єфt<ЬП‡чТ[avR"B"*–9QђуvvЕtїЖрх’zОAђ-)ЭіхrLrЈДgюЬДйЦŸ}‰Г'BDЏђ5@ђ.\МЌ'HX`+Ѓ,”вژˆл№G|ђRиТк†\ЎјЉMшЄ T3‰‹-’j&wЫW~МFL Šr‹ёбx=>ЅЧвwuј4…&J*ЪШeэ…лзl—ієЮИэ_nЧЅЌKіŠWЪ›;УЧ GцѕLdоШD‹VЯ e! Ђ KWn"хшvЃђJщќЙНјЇbdœЃ6Q›_лnг!ў$sЪ>кж1чКGGbйЌeŠжЭЃ;’йЧєЖп.ЩЫГ}7Ќ0j§ВТЪЁ—k3.ЖкИ~§Тл„ЫEk$єф$.a­‘!L€@Р ЈFuе"щ bсnљ\цGўЏš'–V<\t`рЕ всPgЌ:і9mГ9?ЮДkLХЁ­ЧЗЂmзЖ$ƒŸdХ9c<О>іЕ‹ИЙFўr"ЗЩэШЛЦФ-ВнІ#ќg&’Х—ЌŸ,УАёУpэќ5Й))T*ЃwDмтYЦђДЫЭ„™ptџQГђжNьЕёГХЎ?жъW'­ЖvтЊŽЬЂЎ@@ jеИИъZ Xущnљd~U…•e)“мLщMБjEјГОrAceмЦ9—sА~бz\ПrнцЎ1–ŸжЅ6CШяЁœьЕщ?ZE&iqp;имЃЅ‚bКФШХЁџ{m4АиѕЧœЙ{Ю<9‰KX`н3f‚‹@@ ИйюoдG—-’ж˜е@šЛх“љUZv%cƒЎ~ЇУ;нŒ9Џ„щ№ћˆъOиjмHкYV"+э‡LWŠН]cц›ŽI ІсЃ—?2эй"вR|ГѓІЯR›yДgtЙ[ЉMEiWј+ЊWŠђŽ5)SмъЏкКѕsШО–-YЂ+5ЈЂ„'žXэ4Gўђ"њўžvЁЉ‚ВoDƒ—hёђЅОјЪ˜дt?Ԙз4Тъу_ЧмзњЌVЖDЊя27JЄљh'HєъXЁАіzЉ"^ь"‡ Ÿе$Ф­˜)БIЂИ’кМдЛ6ь’>ЭєXцгІ1№гћ}ОgE4eЙЙџЋ’—<@т3s ЕIЫЬ№$0[ф K^ЪI\1ЃcА|њrАл+эМFужЗb^в<ЉZЃ†  ЛCЪ5/ ш Нг[VЎЧ‚ѕ9XУЙbžžФхˆђ*ї ќ…L9ъе!+уОВІ­W„…ч‡КsЎ‚Іът˜ћbŸ…Ќƒ&йRъ`ё+–s“fЧПЊ—ŽSЇЭ8šfOЈ‘SF’om†ЖŠ‘=FVк5fіъй8sш иЊ:aаДыбЮŒнмЄЙX“А=Cz"nPœTпЌ€•“qгЧ!  МЭодІOeWј+ы[Ц‡О7”v>j‡И7уѕ\OЬ›4ЏDUьZћС8МнїmгJ–ѕ­GП:ЖЧШо„!5AžœФХXA€@@ P#b'.GE-XV^бŒ–†ЊGЫfнЩСщуZI™u$ЭСЎJХи"9у­јєьЇЮTeЈu'ЎОВRV?ЪVKa­>Ž‚Cэ р‹–ЉкAв{Z­jЬyƒ SЗiг-zмЦ’­&иЩU}дˆDU}VЃЬUЩЄЕX8mІ&љёЪЄПвкЪ29š&—Зn\Д#? УП јг‚?!r }VkpёZф‡млЦvє %ж[ЦРQ9UЃРЊХТi 8ЕШЗsЋoНc\37ъо^GгlѕMNoкУz “vщгПи­@PнEРXЕЃп IЩчqјH.~І6fOi‹Œ=аЙSšMбO}ВWїnЄ'иOаhаžї?O=-э‚їbє(є™Овf]ЕfЁ  @­тЉBЎIяMrIŽе+›щsUЊызG­\У–W iFwШњZJчIрŒ § hЧЎКDЪыAW ЊQ`еdсД68j‘/„МиmРH:)p4ЭZП”iб#ЃС‡ u"рщI\ОdэнЫ\Q]Жќ*ІЭшew OnLіF–vљ™”WR^)ќW rП9@uНOUvX$Ѕ|Ен')1–2HЁ1”PєШЇ-Н )d*HjcŒ(~О 0М$z•ЌЎmŸтљяMcн’ №љфNР;ГS(H]Јf[8еLj—OЭи й쇈''qљ’V9ўД{нь™mqъД§{[a:7ёGp }>| %ЗbR^9ŽЧДьЙ"x3 Klхб3<6ЎъHc-фFРa}:@з+АET„ЖЮ5 ќІП6Ў?-з•Й:ƒ/+Л‚j=Й а";ЄЭ‚К?G–XкњtЌП lЛTЕ|<Žвб$Я7GџЈHАe^Џ'sЎ‚ИLьЈXEJETy-”б=fЩЂ%шо­;šK<#0vТXœџц|E…jЦR7Є"ˆxsшm$,АŽ˜Z,АŠ+Šљ МW0›л=DОd•!ћхЃЂўaКі6ЗЪЪe”с96ПiџГ"ЕŒ\ќŠrqtF?zТi`а†KЪLpыvвvЬЁнЃђ[ВюЊцюZ!ЛˆUЃDЌЙ˜ЦЯORV ЫPDя,E5(…ѕYЙ}Rƒ@ЃўZc‘э Hy-&Ћњя[’s…ьџк’”й]oA…Є4nOњаВM*[мхўЩ/.Мnzюэ\dьЮР+/П‚C™mˆДэiˆi]‘e~cоƒЭ[рЯ{ў,еeEјќщSXОv9vЖ[nВZaъ–TЌљh >Yџ ЦŒS-^žЎ,,А".,А%Šе(<‰ЫSЙ|бЫ›8<ИЇ\ХіMьŽUјгўа’ћ€Ж>=ЬШрЊћ—б7Ž­peѕќ‘}ё8ЎџХЇвQ|2й{’Щg6™{c]=ѕФГщSЇЃyЋцhп.BВv(--ЪИ\M™ІЫЯУи1cЅњЭC›Kж§У Ћ—MнœŠікKж‰Щ9}Іy›2oхŸЖ3,Aэб<4HВ,ёЌf_# Н0iќ4в_б ݘх1Пo№CH™%ХЖў“Z4iЄEЫF~xFЖРВіЃ %ОЗ…Ÿ\ŽC9.Гaы]Фo#ѓц˜7l‘“‰ЫZŽ9Їйj‡ыUuЩМ­…ЇО:…ШW#Ѕёчы`ї.sЪaYIFю“ЅU’Ял+вцGжCwQ'Вd?4Ў>pœ>а№И?ѓ8mnЎF№Ерб}`ЯЯЇ“oС5ЛЭђšшМО№мчbФШXЕz•YљUKWaЫІOЄ5ШЭ2'ЇП<„9 &ХWK Сїщ?РmЪ+i`` ЄD‚ЯН‰TЃРЊнТщIљ2“`уLš<тfт…ќ EРыРВETЖŠ:*WuЫ•CлВ%чЄ ЊтNЦе№@JёЈєІЃХ{“{‰ШB[V+MєвАЕ–\ ”ДjЭ*ђ›,Т• WpтЫop6ыЌ2ЛЪј[БЃ1aмd_ЯFіlDДŠРт… fѕ._ЙŒGO  п8IkѕЪ%(њ‰кaV^yтџЌЌ,ќyп!dч|~бƒ?+^ЩТ'т†r%”ѕX)ЊЌ’бq_ВКR")ЖЄD<ЌA‹Ц<гˆЯJ/+;іШ~ВХŽC9Ю|xE„K—/сЫу_JcЮЪѕт‹ЭšАsЮДеч92Ю\ЮŸ4ž\ofую­ВBж…,S1ЇdЅ~4Є’ЖћГ4ФМ VвœтW~Н›„q!Ђ+гс@СnL§fљjR\ѕшGVи™-s0у…\ Q(}†yЦИ|х#r”ЭZьEў:‡Z‹Ѕ~;~ЬЌЌŸП>Z“„‰“&J_pЬ2ЫOzvэHОњгpэђ5i'LkeЊ“Жms F-Б=j4јм›H5 Ќк-œž”OCЫИX"Р“Иф‰\–y5qЮXY‰­*ЌNћO<ёD+БŸEЃнKСРџCŠhH–ЏшSпијdџX‚“yЦуY_sщШ.*!klЙ[bІЃѓг@t3`=№8ЎејWšДчѓ=X2žєpцє<Š;Cќ№ыдЕ“Дг?јјЁvриQ3 s$ўrb:ЕЩэhjЅcщЂЅrVЅаў‹#8(X’aьјБИ~о}~x•ЊЅ„?=Z6а2Zly-њ7ЄМJыn“Щ.M4dy%х•з:(ЗкТТkйgёKп™ŠЅ‹—1Ї1O˜™€ƒћЭ­ž–cЮmкkЧ‘qЖ”[>Џ_П>ш@їv(Єн W._)gСYYЧ‡ды*7RўSЗЄK_˜ЉГќL‚ИY•ГгѓоУi§_Ауњ|Ь~m§г\ИatП@.)ыч{~IЉW ?| YcѕyЕШџ›‡яU*лЉc'МкЋ;VЏ]])R7ЇЃyгцју”?"<,нщ ћФZZЏ­VЎ"‘­ё__И€!‡H%9фs{[КWСвуй| VyвТYU‡sцрЪе+•Še]Є‹˜шХЖ/"ЌXЅ|Ы„№с–IЏъhДж8TиF!хЖЉ6ŠXMVZiOœЖZF$жђ$.OИ(}`ewkaі њюVM2*БП€?ёзэЅџєЇ;i›ипhЁџgŽЭEЬ0seРВнЮdiхћСВѕ•‰] X‘НђиЈФВ…ю=У‚љ™Fz[сєЄрZZую§pњ8…(ту*~иГpбB|{х[ќќOZ ЩтюЭI%q›! Ÿi{m:ТŸo™јѓшЯќ0ї1**f{+ћЙњIcШgl‰eт‰\ьяњ …<ж’ЁѓЪq(zФWƒmrПќм{шиЅЃ9У*Цœ лkЧ‘q6oАтlлцmHњя$,YБObљG‰шѕЛ>Rge i‚–/М€=€єIœУ;˜>•;ЫЏBJчcЉwжсkM&JoўŒњХ PЊљѕ?!Ї š6У’OКРёU(kк ~щ-5—Ў љА"Ћ­јOлkYW CУ†M­™:}.њьЈWzЃ )ДJт—еЉгЇJЇѓC7%ƒ—zKKOSu:ОiлVИ•sHлЖ SgЯuš_mTАј;д†Ц6йТЉ%–•зГкcџВ§)АЬ нx›llfŸ4аdћ7C›•Ћ™!+­JEЖš,Eu7!рщI\ВВъ&ёЋdS“Jlњіl№с хVKwHвUhZ€W тѓВФfгsЌwЃBk Х6›ўзВ2ЋœєХuš7•ќe%6ЌJj@эАŸ,+†L––QуF!qA"в_N?диВY ВйЁІЯ6%‹=нWЫ•XЫ6•U]сЏЌя+ёb^/‰hгkЮїШ`0*ПЮзД^Ѓ!_OќБx1Б^кБдъŒs›6mА)u“дћJЦ§1/IuEVv‰IZћ‘ЄРnнАK?Zkъ„+ќL•Œ\~|–ўЗЌМў­_xзѓЎЁTџ3>Пuwщнщ1НН< П^4СIџРЈИr?‘јgяуVйbЙGАџАUЂџўњuы1zЬh|‘љ…е"r"+ў ѓKжX9ЭЅ^КXцЖІЫФжз—Ѓ^&…™X’KэєjP-ЪЋ ~ЋЖu˜ 9йћЙ?јPRЮv(9Я№Ј˜ОFU­РюXЙƒ~;QЁQHŒK49јЫЪ'‡r\цЙ3УЛ Ї:=11ъфн4ЪхDЈN<9‰Kv№$žp'pИ?ЭК!ї1m\@ЖЮ‘2›yЛЇю—HЪыњ{ђ2[aO’ћЙЦ mIЛѕаG™hRh?Yй… fX ц.L”SVN)ЎЄж/uТІ ›$%–­5Š’жї#вШУVZžфEѓz$ЫkБ\*žэiSІIJ)Л5|Њ>-ѓ>ŽнocэъЕˆŸ•ЫЂIhSМ7y >ЫјЬ”Ÿœ”Œy ѓ№Vю[hE–9)џ+ђM‘ЙdEсUф6'}0 ћV”ЈˆКТПЂЖяФ~aнšfщЃшю-cпџр}єюл[r‘'rёgтuэ№7п@~ў=<оёqёеЛ:уќZдk=j8n§уxюљ6и№Ї &Y\•uтMФ{|{vэ1ётˆЋќЬ˜8xв­^7мШ9‰вFTсЙчаГЗ‡І ІўцRRщO­ЇI\mЛ“Я+НЕВЦЄЇ?ЗžТ?|ќІ/EЬIZI‚Ъ5hаЯЕ|§њіЃI”'$?tѓ’цgМœж_F§Х,qfќLЄlIСdZСЄ№Ÿ…рЏ*lЩM]ŸjVЮй“-›Ж`жЬYVЋMxїš\ЖCБšЏІФ'фцўТНs—ОНŒь_&ЋIОZ‘%cYNˆ§+*0В gPњš§:{Јœd3dXv!P*АyЄРО1ИФЌЮЖ†Wa()ЦЎŒ]86№cєи? ЗяоСк=KЭЪ)OиŠšД3 С-‚ЅdЖАŒŒ‰}—іIчжXN;ін1јiŸ)љ 1ВE$NчŸVВЖYПR!‘`ОŽцВ/с\Ц%Ѕ—r‘_NЄ—Єђs9жšфВ;вљ%7nыqhё&)OрbWWhїž щгSпŽ}JWњРкk/ћF4Т_ШДWФfЏ@Р Ћ5њх—šѓ‰ЕжЇq_xщ›ЊЈЌDнwWЁЛqњютСп/Bџ§-Z… ЁЄЬ4{}вoкdУ–Ќсo Ч™Гgl–žA€­dіЦќУЙZdб’EVгEЂњАѓнwвАўвДзі@cmctЎзНhй4фьЅ…`#ЈCХРПIqхћtю}R`Щ]фНД*…ёYЊўSWЊИЮНЁ–2ђћ„*HuXђŠ8#Ъ 6єF$ЫkZЉ )Ќ{чЭ”Вdх•]d:ќќ~|qш }Ц#оЖ]oхтRxќcКԘЅ9тГ"+Џ\QђЗ“'sNтLЅxrWmY`eшеb‰•хQ†~ўZ„МдK:”щітќ)‘-m —ФsЄ‰іЪ‹МкGРlЗ$љ^YўдфМДmiЕ/Є к„jУё‚Ж=^ ъ‚PmЈtHДќišЬ…BRXГЩаоЧЈМj›2KЯk/R`Ћ ’ ”џk_2ЕљРšЌd6 ‘хЕ m—”XIi-W\йu@Іt$ањ;ђ™c!JH9˜mжБ Ђ”з#рщI\ŽZ`kX5+БЮі;44]{tE)љDїЛR7BAUїјИKКN ;ЁSdЇЪьТЪ]~ пзіo/гЖ ‡vтЂЏ4~тй[0ЯІЈF•-™žэОgZqqzw# uœy{М5aY}BІфНŸяХХaЉRRi?nњ\a‡bFЧ`љєхˆ['9^ѓ'Щ­oХМ$уњ’6€ю­зWюb`‡•Шђ"<Б|– GmZ`й}Рзˆ}мьmщk§§x=lam3РxШiaEб•ѓDшQTЃРЪ–LіоFc<щс№џЖ‘k\жfІEЦЅ фpWZ‹gKMКвв>књ<С3™Е”~џо}pYІъUšbЬЉјњоPщ$юЭ8<$џ&с­0&Ž–љ(ЇиЦсэОoK“ЌMц’ЫY†ЪU фИ3ѕ-љ‰sяEРгXЃЯk…?lM­ ыН#"$е(АjВРђ&–И"_vКqВЬФ~Ѕm$YyЕFХХХДœHВїЫЯysŽбПЦZaE+БВ"ЋH–ЂжђЌ)Ђ–ЇЃи, IDATi–ч–|Хyэ!PнI\ЮJюI ЌUххYxљ)Wˆы2Щѕљмв +—q…П+u<нž+2Š:юE@ŒЙ{ёєnuqЬ}­ЯЊQ`ЋcсєФŸХ“ђэћ›q-WOєKДс]xrзбПEŸзЊV`A{ыhVсšфm)пр=йžeћтмѓˆ1ї<цЕнb]s_ьѓді…$ЗЯN5“кхS3vB6яDРQхЕ&zЧVX> €@РЊQ`=iсДDUij—Џ*љEОї#Р“Иф‰\žш [` €@@ЈFUЛ…гнђЙЪ/ е=ћ•!ѓЏЦЫ‰у=•!ЊќHо ш дxЉ ™м€<‰ЫМЊтQ›иЊds5_ЏзЃ}Їіі+w•‰Ј'ЕŽ€jXЕ[8н-ŸЋќіЅk0Bв7—IO\lцУ‡яћ…СœћІжЏ-—зžuЉr WЊmйxWH‹юe{_ДРЎZГ cFWЌ—\б[Ї>Y‚uQЭБЎї“H ТКNO`нЋAXн;GWNїJˆФЫšW›*„V^;ЪИ*„#!TЃРКj‘єю–ЯU~ƒ§њ,mˆ@!0НІA№“4‰І%эшUЯ€Rš–зЄk0–${ ™škЇЖЦšы™ыœy—Ї&rљš–wЋ;vј&Ÿфњˆš>РЩД­їПrLїQ-~†ц)Z“ћgJћЙп№њОЋQ ёzPEj е(АЎZ$=…œЛхЋ?M=ЃђЪ}з•ЙXŒапшб7R‡ю/шЁбjP?РњІ žТЫэдцІ Ў*Я\O>мAmђ№5 lт‚9˜“@›„ИАіJъ†T5 ‡‚|оБsСOЁt-ўW‰ЧcZ›ЛФјхЫ[((ўeіЦЎ.ўЯНЙЯ.мЪэ Пыyl‘ЌŽRчzЫŽеtЗ|Ўђ{PX†Ъ`xl”ћФ-ріO@ђvnфRZ#-)Џ@iБСБމRnE@VК]U€э #OрbWO/Y`O>…ћХEаŸі5wRЗЄbЭGk№ЩњO0fМpApBЏЉr.ŸЌDкџЌЙьџПЂ\бД8 вpщмКmN„юQљm/—^Ž*ZБкF .ўЯНЙЯТыр?ЦнЪЕЋќ2Пбу“ГРУr§є~‰Яр†>˜юІСЈOƒл_хbћ;V^ЌЌЌ +ІЎ@TЋ( j72$KЂЬХšBІLгхы0gЬЉ~ThцŒš§CН\]т•Й9У; BЯ&=щєX1гМMSŠ8Эg&†wŽЈаž˜ѕђnц)й™ёуŒ+7bаoQљ($Ц%ЂЌмК"ЗЫЁ—eVб†\ЎІBONтђ% ь‚ФјшУ. ЫЉЏN!00Б#c>W–M뙆юнкЃyhњGE‚з\d3šzцџJћvэMз›’—ˆз.сOћC[ŸњКEWнПH_%3 Ъъљ#ћтq\9ўŠOЅЃјd:Вї$уъоdNьMОГфЫЅ ОЇNŸ:Э[5ЇёŽЌїЪOјЪИ\M™ІЫЯУи1cЅњЭC›#vTЌй=•ЫІnN5NJЄЏ‘œгgšЗ)ѓцаYўЖЎk%O_‰зХџyU}VћиЊFuе'дSЛ[Оъ№ЃћЋ‰4ўхуЃёz|4JЅяъ№i YeL…эDЖЏй.Y2.d`ћ—лq)ы’в•ГfЦЮФ№qУ‘y=™72бЂе3HYH‚(шв•›H9КЇѓOKЉI,ўЉчЈЭcдцзЖлtˆ?ЩœВ&9Ча=:Ыf-SДnн‘М7/пРіул%y5dUйАТЈѕЫVTхИ\›qqД ЙŽЛBOOтђ% ьЕЫзйЏПє—тrXејlлœ‚бcGKХF >ЗЄЌЌ,ќyп!dч|~бƒ?‹fRХХЧaэъЕfХW%­ТЄ‰“рч_с dV@œд*сd\ єG)БЁ ёGo:zQМ7Й˜ˆ,ДeЙ0§ [kЩе@I,4ЋТЪЅ’Є6Ckгў~к ‹+вьЃf‹юхоCL—ЩE€хэџ|ъЬхЕVз™6ЌеїІ4й[UшM}rVжMлv А PšРХ[žШХчiл6™Бт?™јкћYqэХЕЫŠФЪе+1eђI)‘Ы‹P=t&K+Oтbbы+OфbW‚+?™ЗK‘S"ЙЩŽ|œЇt=ЙsщЩњ*ЯK{sя‡{tO­Xі.D—Ыи љЋЛ А _{Эš5ЋtOх—&%q›!!ŽЕщ{зЕВ]oзХџЙЃ}VѓиЊFuй"щ!tн-ŸЬЏЊаВ{ќ№z˜+s^Ёј{БеŸАе4И‘™UЩвТФVіщ’‰„WвМqг1јнСШМ’)}v?vч˜]’ы6}–кЬЋАdUjSб€+ќе+E›>лџvP’Uv]*VI‚и‰Ы}сˆѕ•_€ввгРzЅѕ–Я7QКН$ЅЄ}"ћ#e}Ќ^ЖЮ]@ь[БЪlW9dе‘2ЪkИ„’UЕ3љФі%ЅvhKМHVWі‡"§[MьЪ.ЂƒЌД~фBL.Jjм”юЉЄщ–Sž"ЮI ЊИЇŽ7 яМћВЏdKзпїwHcVМЩ|•!пзиЪ/“e›r:‡Ў№Wжї™x]ќŸЛЉЯЕ} ЈF•-‘Е ˆ­іе"zzu4 Ќ…Qв^/аЙ-ЉO6€|V“РŠ)IWR›—к`з†]’Ћ/ ќ9цљЅdЅ№гћYŸX]>gЙВКеxфрR;R›4с+щCsžЪJЎ№WжчИrBVЬш,ŸОмЈ@гŸ9яЛ~šждіЧ9Rfйъzъ~ rШрй X #Ўшg@J-06ŒтM€ЦOVv!ˆƒЙ MїдDŠ+ЉѕKАiУ&щžЊ+а!aN‚2Ѕtгcп|у=5гцL3ЫЗv38мŽ|OMќpŽЕbRš+ќm2ѓтŒКј?wgŸksшUЃРЪ–ШкУ^лj‘/ч&)bЏъЅудiЃФŽІйыпШ)#ЩЗ6CлХШ#бЎC;4PXfЏž3‡Ю ВE$& š€v=к™Б››4kж gHOФ Š“ъ›Аr2nњ8”Зй›кДрЉЌт e}Ыјаї†Ђ]—vˆ{3QЯѕФМIѓ№Jд+ІbБŒУл}п6SzM™v"Ќ$+e;EЮђє$.йїеiA}ЄТ–M[0jф(ЋН™@–Б-лЖXЭГ–ЈЉЇAЋч[aШ`Ѓ/­Е2"­і“~SO`ъбB ]G&Р/тUф>ѕУOK–и&~љЎ­{—ВmeМ†Ль0{е(АЊГР„ћWьЏфРЖ] *Ж‘ [Zхь] %Хи•Б p§Б]ДoД ;tХ-ŠC\ЬxЁРЪћPшЩI\ОdѕЁK@tE p#’•&NзB‚B`ИY„ч›D рQ:…є‚ўБ№/Х‚K“ЩцZГк%"'?!С!їФtЃ8‚•ˆu`m‚eРРQ•і‘ab‹БЕPJДјaЗМy3‘GжWй…€нфу№_іcжœ™јњЬз5;НЇ+ЄЩ=o‚СM‚qя‡BЧ*‹R^ƒ€и‰ЋzCёл4 BїонБю“uN1KнŠ &AрPPн@@ŒyнgЉ—lЪ#%UЏз“ђк'є{ШКjРиo#qфћнhT К%уѓAgЁ)Ѓg-•зјГЯЌ{ЩšЋ“{[ЈЬЭ›Џsе(АjГРђg|[_ВМ–aхЫУ˜ТŠ+ЛШJ+[aх#НsŠцŸ…сЃKЖЊлMoмК<ЉŒ._Nф{ˆИ\Sўwѓo7q7З[SЗтьW'АdᇙЅnIХšж€CAu1цucœЙ—~ ДаjЕ2-ЕФœ;CQŸІЉtъ…g=ƒ0mN%VЏCX“0h§|УўъЭзЙjXйЂщ‹™W!Хя$NŒ;d:ј<щWGАтq&щhПkŒЉыЅйЪ[j:Џ*9l’&AџP/I&г Њƒ€ЏљРЪX„§& ыжЇ"-=MNВžњъ;2Aрs%Бе$mgКwk/YxћGEB^0|HЬ8x@Yќ‚йО]{”•”™Ѕ‹ѕ Ц\=cс IB§B№ЛFo›2јa\Ш|М4УšФ#Ф?Œђ~ЭЏќђИЁgзBћзХ@ўЕJЂщђѓ0vЬX4oеœюЭ;*Vz&Ы­YXх4e(ЧхzЖю/rОЋaUзЙЋ|=UO5 ЌlЩєTЧэЕУыМўŸУ6Юw”.mюўу.9‰“ЇЮсмљЋИz#ЙyЙєЙ‚UВєjы‘cјНћрВ|Š‹`p\ХШ)#№ы э3ХХХШПŸ­'ЗJ­ЮysŠŠŠАў0§Iy-Ы20wі\К–AВЕбЫ ћPГkŠDвJхчr-щТewЄяРЭЫсИq[C{њJХYyхI\!-BШeФшƒmdфияю= GŸўŽ[чх‰\іТк\Aэ;MŽ›ŒЩяOFX‹0ф‘•$ёУ9lќ V._ižхn5lQy9ъ5‹›Цeщhœ"^ŠР—‡Пћš3БЕфЛяО“>?ђywx‹fИ›_РЇш?Ј?&ŽŸˆ„{л1oрьщГ№ѓ ЌP-џˆ1ЏхЈ…ц-Ч<ѕ›2аИђƒI'НMSHuж!Xw ;Е%ЫMАО@Ћќ4n ?У}2<•в§ >№&НЬ†tВйОМдс%Щ}‰ ёНТR9UІ)у2гЊю/rЙЊBЫ>;zo“хЕ&[Umжt>Л.Ћ‚дdЕHuф[џ…sŠh)™_љ$P"P›;qЩюжBО1Њѕ„‰“&тжпЎЁсГM38гІLЋRьMлv А PšРЅ,œЖmІђЫI9БяœLЌ˜ў,ПPbќёXЖpžЄРЎ\НS&OЪЋ – C1ц*”щРM Tы‡+e8–ЋAKZ€}_ГI‰еДПBr5њjЪšvƒпГ-м"ВC<4*АZѓЏ]О†…‹тл+птчўl”к Z–Нћ‹Ћа8zЛЪпѕTуB vXOЪwћжmфчгg A <9‰KVV-D№ЪSюЫБУЧ$ЋшХѓ%Ыx•PRBйO–Jђg=љ|ћЯ*”T{ є‰ьCOТњXНl .œЛ€иЗbэyЕ‰€ѓкDПVкЮЅUВBhЮѓй@ YaљCi )sЕи{‰2И< П^4OХПБQqeIЂїЯо5“yдИQxчнw}%[Кg|ч{ГћDтЫVY™xеƒZ!7]чЕ"ЛЂQе(АеБp*њScQOЪЗяoћpј‡kЌ/‚Б@Р|пж> ЛїяF.=LЎrivшаЁ8пQŠ‹ЧђЕI˜?ХшŠрhEQЮЃˆ1ї(мъhŒмЖtД fПp?Д–”WіьЁ‰д‘ а­)˜СЯЯ’›@с:hZ­šІл€ ’‚JKK%WA~9цOєгц˜хi§R'lкАIRbyуЂ„9 ŠкФЖa#фнЩ3KЋ‰w^ч5!ŸЃqчuюfбœbЇšI\NI- МoŸФ%OмЊ jЫЩU•Ws~Mѕ…—жyc№’Ќšћ_ec^їFнrЬвjŸ^2~кo Мј+д;I ЗяZF@ХЄД’тJŸо‘K“Иєфћо Z@ж{&bZійF]X`Ew[`]хЧ“Я{і+Cц_‚sМч 2D•Щ›к™V" vтђЮAнНk7юмЙ#”Wя>—ЄcюlЕV)„ц`>CG)Џ]‚ќF“ГКЦэо!ЇU+Ÿж“GЩ…€тЌМjЩ…@ZЏНжD lWyвЧд•Л[>WљэKз`ў„`ЄnЮCєk~ˆ‹ ЁD4а”фЁЋŒзa.­†жЙЋ+=­н:=ƒzтtСщТSэИЛ#Ў,ŸхЊ ŽZ`]х_ъёв3­žk…” )uЁЛЂ„€sяЛ Т‚hй,zžVЂ0у†ј|_лП МL>­фV@;qб^Г•Š‹Я" –-’Ў*už€ЬнђЙЪЏq0Н>K ы“Ц?л‹aШg'И‰WЩ:[J#кЄk0–$ыАЯ XхXЊUЩTЋ\JьмЏы>АюРP^CбМя@@ŒЙwŒ“CRВ‹@Z7›™Zа„.AЊ@@5.jV^yЄм-_uјiъUМ)ђьЩП\,FшoєшЉCїєаEЖ~­тхф KЌ+е–\žžФUзW!pхкu€@Р3ЈFuе'д30ю–ЯU~ Ы№рQ™i7ЇЗ€?Щл ˆ_œЙЅE}ВТ–гŒIAЊAрШб#8ђх“<ЇNŸТЉГЇLчч/UяФL;_y‚„ж(‹6€@РTЃРVЧ"щJЧ­уnљ\х—љŸœ–ыЇїK |.7єф}ŒњdxН§U.ЖopЎ‡МИђŠЉ+е* ƒк BЦ† №Їr™”qkiК|цŒ™#е ТœQs XБH3зЯмœсЁg“rО3Эл”ysЈlг!ў;31МлpD…іФФЈww“|*ЄфЇH–f–&Я%9ž’ŽфЙЩЦйІŠBЪК–qЦjаoI}чў№Lе2НqFЋ‚EЅI<МЕЈ’,Я•yїє$.aЕq.jA@јР:8ЎњЌкb_~МЭL Šr‹‘2ЧЈ0љљ‘fћЎœыxИ}Эvўіо<Њ"k}~щˆ3'‘ˆaQУ6€ ћ&–Q§ AF"‹ KŒЌa‰Ј@іЩbр(”MT@V…Ші!“И@"Э’Ь€щќ?|јŸSнЗsЛгнщюt:н:ЯS]uk9UuъоОчОuЊъVЖ№yЯD &.pМ0хLŠMТФyёцЛo nУвtЄН†ЉЉSM|NŸНˆД}LgЦЏ^ДEПRпыœ`ЛN‡јgŸFкі4aBБ9}3цO›UлW™ъЗрv\ЛBэјКЌ7rњH[EЬтOSНoq ЈЋ—Qй)цe{іш‰влeJmз.]ЭќЖ­квЦз:3Ож.<ЙˆЫ–ЗhёђЇОјЫ˜Tu?ф˜WЕ„НMsыГз(АЎ"’žz,мн>—љ‘§Ћц:џУ8rСtnsaN)mGW9“сzƒ; IDAT§лv!u{КIЙL|3‡wvXМяљ~Y^2б:u=9Ј,ŽB‰3Mќ9AдЙ•ъЌmXЭ™8‡ъмcНNGј'ЭNЂ…ЁћрAЃ!mОљЪo[ЖЋћ7ћЎjGтРQf Ќ­Вм–•КЂЌ…Ыљ|œй… В ­Ъѕт?xщ‹ ‡GК Чм#bіЊJjт˜ћcŸџр-w•Ћ6ЁžjПЛлЇ№ЋШ/пПR“ђ*вhКкtх—Г#3љИLg(їL.& œ ІбyŠ=ъ‘(мфMѓЪHjОэˆЈ3ЂЌ{u:Т_Q^ЙFqЮНƒВЙЂЃО[Дƒлц(9Rж6Аž^Фх ыЈЌd>)))))wH@"АJбeФд…_EОeё-щ8їНУ;RžŽдсЏM*‡О2ЇКa!b [Q"ЫMgгТvВB1ЄќХХeі­\~жШ)їжdМг§д гхQ Ђ8Щ&е}˜ъЬз™”ЧruЊJКТ_UмnPєнЂч(YіћeиЦЕєv™мјКјf™й_Wd" ,тЊ(ŸЕњsu–ЗЬ/% % %р Ш:“‰]5…wюбух#Q|[‡ЭЇ7Ѓ}D{єlв™'3qЙр2‚а і‰x„е"рХkД'obѕДСk†€‘HE™ЋQиЏе[кЇ%Гk›2…Еыeaћ=АŸ5Ј/йЌІ"qa’Ш˜Ja55Ђ9иЎ”ЇцѕХzXІ—”ъЉ  .+Ђi ЬЇяеМ”pд€О‚OвRЊ“Ю–N}УМN%ћЎ№W—ч0#УжLИямŸЄEЦОS;8NMЖЪrQ–ћ` sП,Щ6АМˆЫS;pћ§ Э§>ГSfушWGQћЕ1уˆm9TђКK`хђ•РНЄЪмЇAэЕT‹lДlўw=Š‹ŠQTLЧŒiв„IJPњ>"§R|§ЫзИPp/7†НпяХЪ#‹б4Ќ6~Ж+HKњр\<иЛ:…"}&wI&u—юе––>в]ПjІз(АоЌМђˆ{Kћr/в­qoўl-КvЁуšŒГwч8Љ3Rг" DьиXœмWf:}ЩtЬŸ4_и•ж­WC†р‹-_˜XЮL‰ЅЩKq%я ъ>lLџgYК)Ѓ*Р xеОЉЮзbmкРКТ_U•н шћ,ъ{Л‘ЏЧРр8GЉUћVкy(Jє%шё|r ИхуH>O ЏJ;ќ ЭЇ3˜‡П4˜и…ШHЯ@QAЇ.– Ќ2ив7I`миqІА3%‹–8“НFцхSЪМэ ‡˜'bёPH><ї>FЖMРъ‹‹аЙig$З‹ќ[Йаh‚ˆam†#˜іXПv‹Nх"ѓ4§"ZsцзуЈ/uи[:}ЯѕММЛм˜gюХщ“gs—Ю ­ђ„гVзНЅ}]ž!хѕк”\ЪХб/Еp4ЮVпЌХч_ЪЧд—ІтУcZK–qF иCfЗЬп‚™гgВэvб>АL=Лw{јђ>АL];Жз'Nœзm›ЗGooмДЯ4Тw?cЯVуq†"‡ы?Y[З Qd#єАиОЫuކ’ОА8 !1O=ѕT… Ћ/єЅВу%Ы›K@=цŒРŽK‡иє|гёмъмzV\Jѕ(М\Ѕ§И ШgК‘кЌРNš"XƒDЌџz‹ЄsnщОќ]и~щ},* SХЂ~э&шІэцЭQ|ЇqŸ?‹Т;…„ЙbZЋйамCDXТjћŽkйgы#dЋ/uиTя! ъО1s š4Ў/м3п0;‘ао}n‹п”Є)bЦЃuЋ&хf/Ъјu2`Y?yYлВаЉЧŸ%Z|Љ—БtJZeќzx*ф ч‘oтща Ÿ€ˆZ‘”іWhю @™д;Ж кЯSШ†ф|Й*эЙГ§хќLJ•ЪјšQS{žMbГMЎ+Tб›+<=YЦkXoA8m пллgЋн2о;$рŽ}`Й'МˆЫS Йќ mжЌMЙ!А\Œѕˆѕkг0"~„H1lјк’ВГГёёі=ШЩ§Яѕ€ г&ˆ,‰БlЩ2ГьМxlм˜qbЛ9ГyQэа•PжcѕЄЈВJZHюš@])’”к`њЊІAƒ‡ ш+/ьab%WMЃЦТєЄщИќу |МuВOe›’йжіє™г8јхAф|—#fR’RЄЂ3gЯрРОbбSєѓбШњШ\Юњ(_ŒeNёЛzCUKYpюЂЙt"с5џњЌp—Ў\ЧЉЩж}ЎЮЃ„—PйТ_ qі›Г8Аџ8|u@I2љй‡вsѓ1=79=ƒЧраўCј8‹ушYzafL62XѓG …хніЙБУb+Ќ[f№МЎџz]TЊЇEВŒМўNŽ”WБh–Дк`к4KъВ'ŽŸРКїзaх?H&n ЌѓЅШ+f3‚ќtKƒA{ЯшPє“-švƒцт„кˆ њЈС}єщєpћ)АцІіЦœ›щj-ЛЈ–+йІЭ›,ГTxэш[…ŒЊ1ƒз(АоŽpz{ћЊё’U; wиРzz—‚РVф;а§jЯТћНжЏћ:tю€–OЖ$]C/^Ц5lЭњ(ИQ p‰Љ<š~хыЬѕkЬŠВY‚Blzѓ›ЂhPф„з&`й‚y"yб’E˜˜0Q(КJ~щ{ ‹oe;W2`ЧЖЏМз'9Жy ж’ЩЙ khœi ЩЬ€—ЙenBА~эzfюА4)МjВ7ц"ЛХџ„Е8ЫўЊљ+aKЙZŽ“’Яžяш›=еЦп^AоŽpzВ};—яХѕ+—1rСHЗŽН-ŸмZ‘dVePqyТŒРŸіх—0I8‡‡”аЬM™8цМIQрВŒОvяеЖLЂ-вјэеѓЬЧ’љsqъ›SXОdЙУM=+Ђ"ƒКІЗѓѕъѕхW)йМysЌЩ0|шА­aты‰јієЗ"Й6э•Н{@•ќљЃGŽFъВwР35яЇЏТМw–™ŠИТЯTиЈVdoкчљ>шѓ\Dѕ2: s\є‹бˆ+L@b‡Х“Я.–тcЁ ЗJ‹xaЃ…ЪДЩџQ;Ъ7"3iЯXVD8O‰уќіˆЭQ iџЎЬ ™а<ŒШ&†]hИŒ+ќ,ы8h fП=›ŽЗ.ŽOЊу8Wiр#?2йažГ‰_e)nФKѓњD№Щn#:‰KwxЎQZ?LЪ+ъДZTШ t !э6Ќ1№p[ €”з:Ф€v+@H8iКїSFЃ2klŒН1wЅН!ЕC їEa1N,WrBВv†мљпцLНюЮы~рю*­ѓѓ$ТiНeБЙЛsqі}uYPіЗй"Іe‹–ˆьSічa‘ЭtйhH#Sи™Рт6‹i:Ъќkо™ђœзДѕмбoАnе?qсшqWчЈЮ§цhaУфl§2y 0rRz›ўФзХdЇ_W„ЌV”Ў№r‡яoЌГ2YЗfІ%бB +4њ•сxgщВ FPŠђбЄ5~ЬсќJ9щ{VЛ?-Cгд5[.’qфШиоНz Д№Ч~РЃ›#§НtK>эk%] ~ё\Нz6jўШЉˆЦМ:c_ ЖWU“Ћќд<&Oœ,vчшаЎЅˆю;0ч*ЭЄ ^!ЯяЫк ФИз&cЧž/\e'Ъ>vьЦО:жФGYьdŠp2Fц;О+E}ђ™Ў‘2[чОbЬi•g€cљ/ЛE'Вy%tž5ІbњсИџyxМ'ЪШо˜—хr<4ўЕёшжГ~#л`u?;ЖяˆЇЩъ&ўѓ|Œa6ШqЖpч›еК=Ћ<‰ЫŠHљЅўгmЏnм1bІЧX)iХ lЋQцqŽ\ѕ9œ‚K?\ФЌѕГЩn55жZœК№Œ!№ТЈПЁeВЄ‡uCъќєУOXЖЉlЊJ_†эK@}miDbєeЋ•чHу5Ё0‚ рМђ$.Ѓ<<ьЙrZ#MфХ6/ xALџ:’_цёœ*sБ”•цЬ™;ЧJЌŒђ XŽљ>кmрУгт_ Т€–їъаїОУ4lB]*~'Х•џЇѓЎ‘KгXкUm =Ll‹ЏVf­оВЯŽ–ѓц|Е5:ŠBa+нЩјOЖбŽШD/  Я;#хn0Ф)з‘C iњ[Eb‘‰oЫпИh5ВжяBЩKах….Hš—$ŒкYQeR|ѕ^Ѕ;?и‰MЫ7сІјъ гSg#Ђ‰С}žJQх…(ЃfŒBПШ~ЖЊ—ё–/тbbSOPMG`н%cоџѓвЅKRyu—@=ШЧlЗх`|krZцњLЖFVUUˆаъJŽ6˜@Ыа„…а;14–NчЂc/oаЬk)Ќ9GF= ЪЋ–LјдЖjP`ЋJОШзј(VгйЦд›Ь а1їШ…•зˆй hљфe|Вfšо*уЫJыž&зQЊ';œ:ŒОнN t|LЁ=кИ|#.žљОм ŽДKŠє…щHx;ЌАкB[OgŸFкі4hh ˜Эщ›1к|ЌкОЪjUgžEГЭЌІЩШъ‘€'qеtXwŒ0Ѓ%=њввгмСNђ№АЄ‚ъaWSu‘tfРœоVадHЃ‰Р/dћкњe ;™TмШш$.јЩI\е$rЗTы5 ЌW)ЏFбюXИЃœћOЕmZP.ГiU’oшnа”}6oй 8Ш~їЛ‘њA*ДЁєйH4:i4†F  ЌТзšŸ4›PZЃ­Я Qƒ6пњ‹5џb>–&/EъGЉжиШИj#ЏaЊmnЊК ­М„]™ъЋ|­’ƒ”€”€[$РkѓОЇ0lаV U‹/џSЪФю5 Ќз!Аd›иjЏ2I™B†mV”іZњІlЊ› |2+IФ(&jѓ/яРЇ{vЃЄ„x;ЈР^Ё}ЖЗXyшРh*Ъ+7Fkщ=wђц™‡йkg“ТDA’МFž\Ф%XЏvй)))) 8 ђX”ЈЂKoC`-ДьЖв^Kп2ŸrЭŠЋPZvЏjv’vJNЧ|оc/mwš uЌTХЙŽь>‚•Щ‹1{У"D6ЏxЇ…Š9ЪО*‰РњъШЩvK H H јПМFULљoЃ[GвP-Ю%аѓŠѓRZ…Nўdл'јvP†ш~ ‡ƒV<кЁ#bС”Hœ“(іЉф§п_ё>fЅv.Љ}?t—шC^Rщ mYЛ[WmХТmЫС'ПHђ. xz—D`НkќekЄЄЄЄЪ$р5 Ќ‚d–5­њBМoнџАН_Ї;JЇгЮA—ЁЇc5tФ‡ptL–"ЄŽ-Х_Лr œ—Љщ}… эньRЬXУ6^‰/&ŠТ=†ИD:)ФHБЏФЫ=_ћЧЉw!Pв­љЉг іЎ/ЕЩ,yџЯћ цfБђЂ:$рЩE\Ю АМE‹П?ѕХ_ЦЄЊћ!ЧМЊ%ь}ќkт˜ћ[ŸНFѕ&–)А<ЈР•іхlЪOэ˜чЦˆƒ XyЕFEEEtТJ!rЖђЯxq†a‹k™UqЌФ*ŠЌ*Z­ЅYSdеqъА%?y]§№є".gXѕЉ@е/)з[Р№ўвзЅPГJЪ1ЏYуЭН­‰cю}іж›XkseкЗъгUжXкŒ+!ј•$)K xr—3Ќe;хЕ”€”€”€”€”@UJРkXWЮЊŒ%oOЖяЇ’ ЌхШkKРжу“J H H ИAYg2‘ЃуйOž!еух#Q|[‡ЭЇ7Ѓ}D{єlв™'3qЙр2‚а і‰x„е 3+ы†њ% з%р5 leNзЛяxIOЖoћџnwМa2g‘€ЇqљЫ X/tМјЏЫ–бІы•ЫWївkэ> Шf=ˆOхБAњпѕ(.*FQ19iЄI&)Aщћˆф˜ћШ@ЙБ™М˜њы_ОЦ…‚ѓxЙщ0ь§~/VYŒІaЭАёГѕXAZвч2арС†и§г)щ‹0ЙK2ЉЛєПpŸ•Уми6ЩЪОМFѕ$Тi_$жSНН}ж[-c§Mž\ФхOЌхцпk3p]wНТлcмиqцБ–aЩЂ%жЂeœJЎžщЎbQ%Сš<цо:&U2аFІ1OФтЁ0|xю}Œl›€еЁsгЮHn;љЗriсu‚ƒ1ЌЭpг –зnбЉ\ДКўN DHЌ“њ~P‡НЅЫ^ЃРzсtEјоо>Wњ$Ыј–<НˆЫŸXГ‘І—OЦъ |М§cГh[БщљbЗЫtо+ZOлрвбаWo•ЂРxDєдц–YхЕIРcю/|4W Ј4гH,Ёа_,Dу№&ИqыкFtEёb V о:@˜k ІЕšмЋЙˆ‹€сL4SVbEАW-QŒpz3ЙЛ}ЎђЫ'1uyЎ;?7H‹У]ž/E/Ѓ[О “i%љЉx—ЇrљЋОВЖeЁsЗЮ ЕžшХ~Ь@0™Ц GfьВЉ}њГ[H[6Г+Ё№§”^їAУ”ЂRV]Џ {П”qsט[ЂўіzЯЪЎЄj”CyЄЄ“ђк ŠЗКЊGќЩ(ь§9 A!xЋуrl{ў4ЅєПAљ5ДfU“'ю‹Œє „†‡‚}_#ЏQ`Нсtwћ\хЗ}“oŽŽРІЕЅт^KŒР›Ѓ"ёЦXƒЛV†Q€oŽћк­hho—а.^лpon[UXЄЅ+–"се„ŠЛFJЉ )Ѕьј%G6o%0(Џєобˆ#GIy Pƒ:!UџR3ЖJzU!9цU!UЏч@[\iƒЁеjб7" BbЦЅжЂC2CЛвs]‘кHYmБ‘с‘ајўšБ.KпY і}МFu‘є”Рнн>Wљ=€z“љ8Н0™ZFjійNєКOzЩ†wУмхž’LееSгЦЊ“Єkœ§нЕ{š>одЁ“ц”}›5єМ‘УНZЃLŽ”œkњ’"ЫЯ[рZ„‡hб0$uVЯЇщ•б‘CGѕLъз EЇŽ­‘Е9Ћ,‘Bl3лф/M(Н>Pzл№Ъ™…a›нжm[‹0чcЄHM|нZя0?B^Ќѕё™SаЄq}с†АћSђr›2?Ш}с>ѕщ%іжTвЫљФoJвдЌ>ZЗjRэ)узIШ€euўф 0ZоЉЧыјОьР .cщЪеыd„;ЧœлІPYџZ—ѕХxј‡’Oщ‹R†}gЧб^=ЬOw5ёqёbј^‹‹т›цїчГF>w[ы„Иzx*фC*=л##оФгЁ1>Е")эЏам€ˆ;…ЈwlДŸЇнаљrмьЩЈllЛЧmнЯh)?яќ<ёsХ6ЙЎЗ788БCc Оі%ђжUDвSТvwћ*УOЃZљЈЛ |іmъ=^ŒžQ:tjZ šљ>T+ИЂ<Ÿ;њ & ™€^ѕzсљП<яЉ[ГЪъёGvUъ2$&$:$3НQ хѓGєЄЈВJZHюš@])’”к`Blъ„iар!њЪ‹<˜XЩUгЈqЃ0=i:.џxoнƒьSйІd^љ~њЬiќђ rОЫЇѕЅ,ЄЄŠЮœ=ƒћ€ЇЅЃŸFжGц pжG™јbЌ@œтwеКНбмEsХщ€ЧП> v—Ў\ЧЉ);;›ьˆї 'їg<зo&LЃЉД„ЪўZˆГпœХ§ЧqрЋхrf:(ь’srs0 z ŽСЁ§‡№qжЧ†:^€“Ыъ`Y(юняЂПўхx:сЮ1ЗЌл–МSЅ/J9WЧбV=ЬїЅи=r4r.фˆ{­ЩcMђvВRЅ]пзюaЛБHд‚етžHјр 4VMіdФљœЙЧmнЬчXі18|\’й@R\yШ хД= 600Pьz ЛЉCXx-XdйІ20/ežАЩ Ј€фЄdьоaЎ &ЯLЪ)?’Ёб_Š’L~ЦКMYуtgљqKкКy+fЭ™mm­pѓ(МuлVГl)ГS m@ќЈx\8qТ,]}Б‰ЪЮzs–?u:‡S.)уG(aС~CЪK–ЯІ’ЯžПf§Fм( Иј^р…\|Й~Нb^•Цп^AŒHКЊдyЂюn_eјБaЙBМВ0Џi3 6sєт|EIuмпАtєЗŠАхдQhСФŽІœIБI˜8o"о|їM mXšŽДЗг05uЊ‰ЯщГ‘Жoƒщ!^M dбЏTч7Ц:'иЎг!ўйЇ‘Ж=M˜PlNпŒљгцcеvšъБB—oФХ3пaУ—ФjвдйЉH_˜Ž„ЗРІ ЌИZ3a8эDVЊѕЉ(EiѕЉFлilжVsTгNV‘TdœХXгЛЂœхгѕzƒђЋЄ4oоk2 /F‚_OФЗЇПЩЕЎ‹ьн{*мAсХ>OЇ.{}ћєХћщЋ0яeІdWј™ uУъ"ŸvМP^”љ„ждІ8WЉ.ѕб’ŸЋМ”rlЛ9bи`Є§#ЭЄМ+iЎњюsWл ”sЧ8*МиШa˜§жllъОI(ќlk§HB _Л‡ш’ШТŠkOвKч“љ'я>С“(СЄэЮгт’О}k%хѕЯшGэuЫ%%{ьшe;jЗЉ*{22erCРђYт{Х)КdnЪа№ŒB Duяе“ІЬЄ~*БоыџС[šцЭЪ+ЫШнэs™Ё?šhсˆёц цУєЅўш…su<їoл…бo& х’П)ь НџхћhбЁ…@ :uОкџ•‹Ф™ўJ$зЩѕ(㔉slзщџЄйIа†jE„ѓ'Ьье щюv#1eš!?ЕwtвhьлБOišMПЂ:”‚–шЏяKОb6рKmvg[Kў[ˆ>doкчљ>шѓ\Dѕ2: s\є‹бˆ+ТФ‹'Ÿ],ХЧBAђ”і№Т,F •iџ’џ3"8”!nDfN™$бa“Gъsч˜;RŸ’'ЄvˆсўP"ШwЧ8Њи‰`II‰АБfФœЇ'ߘl™ХцЕЏнУ6;b™@'qёZ’ч ѕУЄМ2O[шE…м@ЧвnУЗ Hy- C hЗ„„“І{?e$sй“‘*›УAkїЯ&?Kф8<„ž/g(‹L”:ЗЇ­UЪ+—чы'Ÿ|œю ф5:veIOкнэSјUф—я[ЉIyiєТs]љЅРьfЖМБ+Њ#їL.VЭY… g/р7В]dqwБrЉ&QgDйзŸН:с@г@ ёДЂ,(qjџ Mлloёа[ДW_ ;RЧЙ“ч0oЬ<№Kл—ЩпXgЧbїЇeШŠКЌх‚ GŽŒэнЋЗ@ ќс<кИ9вп+Гёс“ŸVRƒ_|WЏ^СЃšcBтu•VУc^ƒБЏлЋЊЩU~j“'NFђЌdthзRDїŽs•fЂУЋЅ[Жh‰к ФИз&cЧž/\e'Ъ>vьЦО:жФGYјbŠp2рЮ1wІъёЏGЗžнФЇвwŒЃe–Ї.ЧЌфYx)я%>9юояiЦбžŒЬ2:xaэОрЂлwФг;)a bž1 ІђфlыжЌУДЄiVKŒ~e8оYК б ЖБV3yIф=зѓђюr[žИЇOžAЮ]ћ_ў^вюл њрТЙяiыЌ="GЮаyЬїъбЎyхD2˜ь^SwЇ›”X]Ол 4MЃГнъўKћКЩ5ё—_ŸЧћ˜вйЖuм[“бЎ;й€ЂЩSSQ ЂLщжІфЙLъVЊгЈФ–ЋS5я ku*Rм–ІwЇ V‰SћжЪ:wdїЌL^ŒйсьЎГ˜9ІbШОXxˆ кюLљшјk4^+q„pо›иФЁОћЉ{ЖšџIЊлщL8kы4Šl„4эьЉm`эхЯЅэ€д НМоžVQ_ФvRV:1g.­ ”ф“cю“УVЉF[ŽљОяOЬ№Івђ^њоw˜ІC>6ЁКŠ€пIqхџщМkє,ЦвN ”x˜и^UљШqІjЫ>;Sж[ѓz #‘оLов>šнGз6х•хеѕ‰Ъ+ЏЬ'jP_ВYMŠ)+ЇЉVЏмfЛR^ьU|ƒвg˜ЇгЬэ* \ЖЃY0УЖ=ЋТ7j@_QзЧгŠЉo˜ѓTђБя uyГЊаРБ`Ъ:еJ'ў”ђПЯ Й”єкїCw‰вœ -ДHmх[+БpлrD6/›вu‚…We­щЌх`Аyo'%мeђйЏ9M’џI@ŽЙџЉЕEа{ЕЙ&ЄМЖЅНж#iqVzІ[ '‚J\%…ѕ№>2! 0+ЏZ2!0žдgŸŒѓŒ˜4ѕLC\Ж ѕLѓмnыjГs/в­qУЭŸ­EWвЩГWча‰C…Rг‚NЁ)ОиББ8ЙО@4}ЩtЬŸ4iѓгPЗ^] I‚/Ж”MЮL‰ЅЩKСSѓМ`CЄџГ,]сЃіGN)v!0ељZ,я)ЋSзўъђ–с˜Б1"*ёХDмЄiл№F!.‘ŒєћкHМмѓe1ЅЇЖUв­љЉг јKэ_Щ‰­eѓ™8GXŸщP%šЙ>Г’dq_“€s_1зкIgNЬщmM4Ю~§BЖЏ­_К“Э\:-ˆ ?9‰Ы5‰yG)Џ1!PlAНC,х[с-эыђ )Џаз!яEy)GПдТбИђНВУ NІО4ћаv&™bW[цoёiЛS%њгд”?ѕE5D2hGrЬэЧO“jт˜ћcŸНЦ„@"АŽџS„аЮ!šчw4ЮМ”љеъ9ЋQZL&4џо[я!Њ”yyUЃ$Pгw!ЈQƒ-;+% % %рc№ж[lLmŸЗДяƒїЕ(8Ÿ‚Йш5м`gщhœ­О)ёе{ƒ:BLЛЭ $е\ Hиš;іВчRRRо.iырy BЬ‡уАй€ ‹ŒЋЈЋ§†і;IR,i+я))))o•€з(Аоbcjk МН}Жк-уЅ\•€3,лWљ љS_ќeLЊКrЬЋZТоЧП&ŽЙПѕЙœлшžИ{W{юбxдoєWЎ/луѕ:кOooŸЃ§љgћ#ѓW§§Э2іerѕх~ЪЖK H H H јžЪ!АŠвъщЎєќыYOWщT}•mпsЯвIаЇ{h‹анЛ“шƒa‰j’UјЊœA`}ЕВнRI€Њ„€Tћ„оtх:qфXсŠъ“ще/'{ф':t‹v­Œm„еЊў6Щ”—@9VР–Я^u1ŒpVVIЌКж•i+ЏG:иМе№”Ћ4H*ГŠ$ЄЏ–€?!Аљљљ˜1}Žf]ьвО цЭŸ‡^iƒV._ мKЧЁгžЫЌМАc‹єПыQ\TŒЂтВUЉЬи’–oХыѕzФM(;фФVычЮŸk+IЦћ„ђšd_О§…ћІ#ПулH%ж‡Аœ+XыУфхКhmoС<;ъs,mЋkлћйчъKЛaV:*ЅЏХНћrёЪ˜Нјї5НэА/‘X‡EUЃ2њ;&~žы7щb WЄЏР˜WЧ`їЇЛэŽщИБуьІлJ\ВHЮnи’яъ™юJљЊ№­Ё­ЌР2EoцRh(LЇfЃЮ р!rqM(о˜Od–?>)RBжyхqОDшk ]Ї~kшJуцtbWM"ѕ3Њ{‹ Ъ)АЕ>4•A`Ыs,S2W|єЙxXTГSхѓ[QЯ?збрнПїФкеД Vп-ж3ЫX)'%рOь…œIY%eдј7)a–џ}ЙC‰MЯЯЈef=НмєЅzоЂЃвo•Ђ€|ІЉЭ љыsА†ЖNIš"њQHлЌи“ТLЫCX‰ "`X*"XŸэђ >GЈk‹‡ Л(žя†4щr•Ђ"ћ"ђ%y—Ъ-т’Ќѕr{ЈУvzj;U ArЁА›G\­ЗЪЫЈыиё{бГGйth­Zl\п њ[“„у0ЧY#5š‹џЌXй EуQT4Щ3к‰"п‹Eм+ЬŠз{4зuуQ+Ш:_ГЬђТч$РЌПPПО§АrеJ”о.ŽУgєw šЌЌGfьђэNŠ +АЌдАcЄц~JЏћ сKT)kПLѓ> ((*Ѓ­Блu%ЇПeИxЬyь5фXqхП=-ЙlBь˜Lљ —•ўeФЫQтМŠГ,S\\Œ„q ЈџX}4љKгUІ#G vH4ъз3ЄOILЇ1ЊВ” *uйjcюїЙˆ+ъlнЊ5ВЖe™xА9OьCЗ‰Уg*ЊЯВ,Я€4iмD8gfCŠЩ\ ˜†;˜аѕN>RiЌWжŸЖЌЅќЕЉсЁTw}єщЎŸЧ@Mœхcд2хџЋЙsцЂSЧNЈ/x6Aќшxœ8~ТZQ—тxV*”x+ГS.1ЉІBхXF`ЋƒсєfrGћž:ў<ž:єМшfJ\oLву_ьјНёrпоnэў‚…н№аУZ<ђјJсъегbС|ƒ2jЏЂХяtC‹fZДl—‰Ч_C< voЭ?‚ЉгКšM™нŽ”нop›?O%љќ M~3›>ШР# ŽУg—H)ФP;Foя @  Ъk))Џw4tMŠ )ЏсjP'„4I>+ЖwfL К†эŸЩо*q"WЩВIХS6VbГIяbT–Љ№п еC7nм;k”<+™кЋСйSgqќЋуИ|љВ™B™Ж* ЃG%"'7Ч‡†Na—`пцз^}ЌŒi0ЙсШЙƒ=Лї ;;лд46чщиЁ#rЮцзЊM+aЮcЪ`%`Џ>ЫьY›3qьш—8xј pЮк\І@[цW_ГH^№з††Бgћз†ЄЬЬ}œ”Ц Єt^=Џ.R.,кzѕЮPџ–ЅЎШќгнŸ†юЊЮ,opP027dšХY^ФЃџ=>оњ1.ЯуйЧ1Иџ XАleV—Џ3жe`щ;KСОЏQ9V"Аж‡аЌ5ЮlBАfычиИЫu4V˜Ќш‰#щпдHбб‘HH4иФ2B;jм^DПиBIЖщЧRЮ›їcў§o=ЦћBф§tG!WД˜СˆТ6n„žн#Бl }šJђK јЫ Њ‚Ÿ/§,‡+ZdХ/}& ЭГУНВ$GŠэ5} I‘-!х%№-ТCДh€: kayфаD=E(W(Ё)„HYМPbDшЃ` „€1ђЂ#2k3аКmkВ1Šf‰ш№ukUМУќyБJдЧ7fN(#IoЬ|CLЉ*yЙM™dŠОpŸiВЛI:ёуЉxFмZЗjRэ)уGHЩ€euўф ЁhuъЦqЦ:йSˆЫX:%ЭUђИёШ%ЅЂQж\Ќщc@тTЖпOYаІНxm.‘{ЦЈМюF`Ы№q§e}j]ж~‹?l—Ux(aсТЯЮн;СJЌVЋŽУnњаФ)sS&К>еdЧІ­­ЅYЗd=zв”юl`б’E˜H &љ˜y†…‡aб‚E&6lЮ3nЬ8д ŽЭy.\И`JЏlрУў‰Єщo!,4L8јQYэёoфм4ь>№%/?ыuюфЃљХ%;ŸмКl}иFf%(Вмwо_xц31dш,^ВиЌъХѓcнšw‘ЉьНm–.Ž<*ЦƒeШФcиЃO_d}ф˜B. йљсџЅрр`ФEph0јк—ш–•ЌЅD з [‘oНД!і3“ мbBРSџь~ў~4Е€—Fь4U€](ћC§зїEЋMANх(Џ5z{ў ЬJю*’цЬюŠХЉ„О’R+Щ?%рOьбЃGС/JѕK“уь‘ЂИАЋ'E•яtЦтЎ д•"IЉ ІJ0 оО‡ЛŸХЙ г&Ј“ЭТKЈlсЏ…8ћЭYиО:`–Юй‡П8 z ŽСЁ§‡№qЧQ/ РŒЩeu(ЈћяЎx§ћѕ/ЧгйˆМЌ,œ{#g—ЮGnњJ, xњ)BЯH™>Зl)rЇ їНеˆn,я ,Ђє9ф˜JJЪ#АіddoœИOLJХ…ь)ŒlRаІAЭ.вW‡їAw]G*ЄИг ›/Ј?И\1чqІ)мЗЭЫРлы/ѓж•ъАыF&Іч| =ПХxЎ!д0S›ц!ѕH{ЌC30є|п"CйьUР'гШоРUЕеЮXz6їЙп,™џ‹оYšŠ1у֘}Њ3uЁq˜8ПЁg’?Lя $ћ‘G€лзHЕž*МйчћњцЭ+ъ(nлІ-žщк Мћ…5ЪXЛ ѕыжЧы_GЃШFшDГ0lЋў АVЮ‘8не||uъЂћG‹ььѓЕЅЉƒ#МЊ+O9V"Аж‡BA^­ЇV.ЖВ&жjЯЪЪХђдž`ѓvцИŠ(ѓЃsH_йМ@ыЯжˆ]ъ2Гп9BіQmiJˆІў?uŠ ћ›ќ ]ЕrйХ@ЃІ„;}ђ8Юl яЙ;Ж}%XЖƒe›з`-™  ЂА†”.вМШЬ€QЁВ№ЧXСњЕыq№аAtІЛXqфа>c ЭDц]A›іmLгс7~ЌЈ‰_€ E4ˆ@УІMБыs^* с?йюIЁѓЕГќИŒ%]б]1л#7"<71ѓtІBЌtўЦ/wt…ЪЊїмe~–dЩг-у,ырщзФЉ‰XЛf­™вbЩлбы5пfЃ)ѕ†l@ЯM›Ž#Б1(Ъ&хЕuGД]žŠRRhЕAZ\1ЊІv–ѕиkП#уdЩOm2a™fыšVО—[Жh‰ЇЛw QэАКхВŸ ”yјаСHKO3Ћr+ˆљг§bк›ћЮŽ•W6cPШsЅЌ#>зЏ6СсpШŸШцУe\Z‰Џ4;Qђгoќѕ~Вn–ўŠмйа5яEдYрЫХ(} ˜іLkhј€НcDлЕхяckешnшPЛvy™sоISfтЫ_ “ЫВЌ|Oš2IмcќQ№сцOшлИЎnяЇцПf§Fм( ИФ}EцD|Й~:›W‡яГlD`-%bИVWыЉŽХђ.єфчC˜№*Ve€cЯ•4ѕ0оKя)Ь Ид–эЙрИŠhђДУXГМ}9ЧŠЌ‹–GYѓiƒМkшЁ–фз№Ї}`YщЫtвnЌШИ8qMoч‡YЏ7(ПJЩцЭ›cM†сХРvf‰Џ'тлгпŠфкзE6-tQ+ЉJ9[ўш‘Ѓ‘Кьє%{ИїгWaо;ЫLY]сg*l д%‡у(Jg>Ё5ж”ЫrЖЎыR-љйЪыh|ёЭbšі$…ыi&хнбВЖђ}ЙїK§Z$арвЂ"\џ„PчbњŸ~Єк.KХљлХ8{ФА.єіœK+Ьg’‚с Й2NŠi3ѕБЙ&­L)с:wыlЦbзю]y]Пa=ј^­ 5kVоќ€0KБщNцњLR QlкSџбњІєЪxfхмљshлЁ­`Хa{Г-gюЃR^‹DГІтBўy”џ†m?юУe} ко!Х5шЯшJ5Хз ,sў•Ё^FэЎАЩ™dтУHНU"9№ЧєˆИјtчЇVГ(‘ќ?–<+E БJœKў€mŸй4AБЏe>ŒОvяе](еЪјИФпC…ў`YD`-%bИvkoыЕкŽUі€Е•ƒmS_ВS˜А‰‡еіЊъђъ0ЃЊёЃП@Pа сRц™+АУ_jй)}Е%wŠї'ж•q)љo!њНiŸчћ Яs}еЫш(Ьqб/F‹-€x;œиaёFKёБёRзЩ ГФb zq0•ќŸСЁpмˆ8Ё‰­„(З тќіЈk—Ў(Є§ЛxГ†!^,Ђ+ќ”ВŠ?pа@Ь~{ЖиN‰ХoЬ Ep•dЇ§Œќx›јЭ&~•ЅИ/aЬыбќ‰Ъ)\ъv0šЪ‹є4њkWMIzš–.ўюzDѕРх+—qњ‡‹8§Пqё_oЪчL Ђq ЉbwЃuёт9Fй†rпў}XJ'аMy}ŠЉ8/œїж,|Вэ›ЪЋ3 ЩlnВ@І&=њє3ечˆ93ѕ1cuўў Н%њЬ§ц№р›ъЗ ’]œx§† ЅЄМоїТЕр™›Ёe;‡5&eИ€”з‚K4-@ mH8}еZ ЕjnЮ™хЭ&<хПiУ&Lž4й<ƒъŠгУG˜™Zp2џЧьЃ ~f˜И?‹Щ>О26ЪЬ'‹L”:ЗяlІМr<+ГO>љЄHчko'у7PY3%[& uШlа+Ÿ – шєvтд-u;Њ3<ўЕ–ˆhЈЅб9ей YЗ‡$рOЌ+"ГuJ—ЅНZEЛpнН{ѕhс?ќ€G7Gњ{щІ&ёtрJКќт Иzѕ mдœŽžž`JЗр“ФЦО>lЏЊ&WљЉyLž8YМL;Дk)ЂћŒЧЙJ3iš”)žЦЎ§Ч@Œ{m2vьљТUvЂмсc'РnьЋcM|\A(M…-b:1l^ЯfšˆpФВ9XОp1Ђж?§cПЖ,ъдuEу4ўЕёшжГ~#хЙЂ~Љ8%Ќ”iпО=žэ§,nўї&јхї7|V˜šЮ§"b35§ќѓЯТYЇ„•:јZ +ѕEˆ†ю—Šчz>G ћяr™UМРgУ>SХа"В IH[—†„IS„/Яd0’›Б*У,ŸГыжЌУД$Z„f…FП2œ—-ЃЗг=зѓђюr#ŸИЇOžЁUэбТ 4#œюPЋЊй•mпsЯZ_йoХЫ!” IDATйоOїX_@e™ЯгзМлA~~)ЧnСБ#:OWя“ѕЅЬгcцє™ шЅмОщЫVЈџЮ‘Цk#2‡;†М7mФХ3№нOХиГЕќŸ$—t–ВЖnSOМ ‹;‰Q5шNоžцUQ_ФvRV5gю+Б2Ъ$ ѓ\Zœuю+ Пє/Б`Ћ-э‘‰ohg‚М5+H+Љ…FЏŒAЮпZ"ЖMЌ/tOЖбŠдcЮЩY—2БъєRДжvЦCк‡аюО‡а•ЖЪCю'ДlЪAяяпIqхџщМkЄРcьо™eŸ} Щ6Q"АŠШЁВЪЕЗ*Іv_ьvрh^™Я?$PгXЫQ4;9Gљр0ўƒršАыГ,$Џ}Jкf-D6”zк5ЂэпSFv”}вЃАэЭ+„.ћ”и… Gw–њ%XŸ\;­Їm„ІкжhкѕДѕ„/аЊE€-цB)Ќ9GF= ЪЋ–LјЄ>^И)Љк$PNeXF`Ѕ/х яƒЪ=sчWлsэ–ŠkК ЌЅЅ‚j)џЛЃ §y_ЖwaътЁМ/1ф32ѓx%aНѓIіœп}ЫО^\NЗцŠ Эrё2ТЛ%аЖv[Д";WKŠ4Ю~§BЖЏ­_КO&…6ЄћDk™[^{XхLrюк_<рсіЩъЄ|V[цoёiGXššђЇОјьƒус†Ы1їАРН Кš8цўичrЛTзН•џy~uUэPНоо>‡:!3I 8!‰Р:!,™UJ@J@J@JРЃ(gBрбкU•Eє.[ЉŠіš`eкЗpєjЇњ15mЄSљef)Њ€ЃlUд-yJ H H H H и“€з(АŒpVFIДзIwЄUЖ}kв [†Tд–јбeћѓU”WІK TЅU”X{ОВй}UЖEђ–PKРkXoV^Y`юh_юЄ{дВ/Ž\тј€.Ё]аэйn˜З~^9>œvєЦQГј-щ[њV*пJDЬЈ‘Цљl‘ey[љdМџJ@QZЙ‡Š95ŸmЋ$I H H H H xR^ЃРVсЌjЁЙЋ}–ZoiЮDыёіbƒш,кvЂпаВSNlхпКn+’оIТІU›L ЌZIЕІєкт%уk†eЕfєVіRJ@J@J@JР—$р5 Ќ;ЮЊМЛкwї4ЧHћ –оцгАZaЇrљ‰ |ЕrGŽXwа=­ЖтžЎ_BѓзcаМxšИƒЮM;cЩ_WbЫ‹[Q/Є‚ƒ1ЌЭpDQќ5=j@€‘ў6/+ЉZ%р5 ЌЛЮЊ’ІвОŠќŠъЯMЭ@юš­Ш§чЇ"+лФ*ЎЂВЖвGN‰Џ|‹м“хгьXП7 а%М иЮ•}ОцxIRі$ X{в‘iRRў €ћш8и{@:56"4‚Œ б8МnмКЖ]Q›”-С[Ї№н­o1Ќеpф^Э…ўwшНoїAкР:8~ [‘oн№G‹ќ€Сt]zX"Ыx Œ|Ои^Qћi4ŠгWNЧЌИYHл™V–—Оwmк…­gЖ",œlvŒФшыЈ^ЃРŠЏДуQЄ"}K HXK‰Шk))П”kBЄЄ“ђк {t›а3ЂтOFсЏ!/!($‰ gЃ]hWœћўœxojjБЭlеRhh(nмИQЕ•ј0wЏQ`йT”Co”Ї;кwli­vшю]ЧЗбВdУ‹ИˆдYЉІЄН;іЂYћffЪ+'В2льЩfрєžŒg=›JЩ€”€A•w‚”€”@M@€Fƒ m0ДZ-њjb№Џ;Ч0уR ъдzT(­gя@Є6G–Ч!Ђу`„5щ m!O’ЊU^cBрЭЪ+;кзqežлtqŸмEђСЛXqњ.Жќt‡ ют]хэix;­Ђ_Ыјl[Г / }Съ іТ+/`лњmVгdЄ”K@кРЪћ@J@J &H ^@ž 1О+ѕё&žС № ˆЈIi…цоDм)DНcЫ §<ИzОœhŽ:‚ЈgЂPП^(:ulЌЭYІ<ŒІf~Iё(НОШwўф dmЫBЇnŠ>НЂћНСѓ3БЏ„•ыŒє ДўKдЌ>І$бсGvq &~њ#XжлXѕЎъ.Ј6Xѕщ*u’Y˜ЗбRoЅe‹ŸY!yQЃ$ и5мВГR5VZDB[†„ЯH)Н/Ѓ:D V›Œќяр„n к6l‡тƒ+ИkР­Ћ@v6p§;`ШZ@[fž7jм(,_В=Ђz@wC‡ХЉ‹=(к$зьCёёі э ТšŒ548†‰щ‡ГЪтfLž€ЌэЛ…щ+ЎжLŽeУУЧпIЦaЩВ%˜4e’ЉžšЌƒ#э–Mь9›"ГI xDѕˆ˜e%RRе,ЌѓЅШ+f3‚ќtKƒA{ЯшPє“-švƒцт„кˆ †ќю ‚Ё§лЏб^юљf- Фuнuшnъ„ЉоЂцGШЇ,\‚Аа0 >.џљ )ѓRЬтNž8aЦгкХЌ7gA[[+мЌ9ѓАiѓ&kйќ>N"АqeијбѓK’№! Hж‡K6UJ@JР% ьКдгрьRьЯг aэHP‹ЖИ, ХеЭуP ZŒвК№pC ЏіаЂˆX‘%…WMызЎGъпS1wс\џ1 о™ЎOѕ0ea[…X‰eВŒћЭs€ˆˆВz#Т#pѓ—+ лх{ы„Г*GЎ2э›šFЋ§%I ј˜ф.>6`ВЙRRNK 6ъIzщќ#@0m,@ыЙLšбю<-.бю@}k%ФѕЯшGˆыuƒтЪЕќJЖЊНŒкmЊГyѓцТ4€#и6ёѕD|{њ[SКЛљљДшнЈФц_ЭGэ‡ыК‹ЕOёљƒЗД–No&ooŸ7ЫNЖЭ7% Xп7йj))'$@'jщnЯ5 @ы‡Iye`”NфŠ ЙŽ!Єн†5n ђZ@‡аn 'Mї~ЪH(ЌŠ‰t#ŠZђ%ЊTчƒ!ЕC ќ,ŠЮ~{Жиђ‹З§т№tD} $‰Р:8ш•A`ЌBf“№* HжЋ†C6FJ@J  $Fц;О+E}ђ™Ў‘2[чОbЬi•g€cI‡E‹NdѓЊ'є•ТХЄ”rмџМ *іє'@У&tAсћŒhъ-Кd„ЕI?к’Р єв• О}њ‚5R+ JzEqуЦŽ;KŠv5МFѕv„ГВэ[8z5M6q TGŸu(!Ÿ'J(Ha~48=!эe I’Ј~ HЖњЧ@Ж@J@J ъ%AkЋъ ЂWtЫа„…а"ЉаX:‹VtнШ&гZИ•s”Ю}яAш+…ЕЄс’™Ѕ[ѕ-•5Ј%р5 ЌЗ#œ•iпrR^зЄ™oЇЁu˜w+№ЦE_]BЛ@юЋ)џKжџЧXіPJ@JˆЄ3цє6GS…\"&Пэkk—КO&…6$х•4^Iе*ЏQ`+‹pVЕ+г>уФƒhт=Cюў]:‘ЫPZk)цqЌP*tџŸюGЦNHЁSCшHйЪ’5eU*Џ••Њя•—Ќя™lБ”€”€%Р&ЭЩ$€B hAW5’5ГƒjlNЕV-w!pPќŒРV–XyџйЎМ4 {@АуЃхBУCqЯ=Х–M %V*йэ<Л:ЗЦќбГ-*ѓI T(‰РV("™AJ@J@J@J š$р5 leNOШЎ2эc[WV^'П2ѕУърЋт­xфљл".іЅXмИzCœахj?j fдЫј1ч 20_>s!z5ю%мђ™ЫMлzp5zЋдЉФЉ}%lY†уw~Аƒ;FЏz]0Ізpф_,S№KKKБpеџX/<пъylIпbЕNЅnщ{Ї•$% % % % %р№жgU И2эc6XМvŽяF`№Џ­†8Kж•>”о.ХЦUёшДœ’hѕЂеИvЅ[Оо"мЕ+зDœ#МSнЕUцtіiЄmOУЮм§шд/ ѓЇЭ7eнАtєЗЈўS[Асрp^IО'‰Рњо˜ЩK H H д HXGКВ,WS‹Є}ѕО\аŽ&b–BŒж:Jj„4фсЄя6ь9Зѓ.ЄnOч$3ЏФ9‰H8 #ЇЛяDАЄйIdУnшШ Qƒ6?Эдь§лŒѕЭK|3‡w6ЅЫ€oHРим‹ДАСOШŸњт'CRхнc^х"іК jт˜ћ[ŸНF­Ь*O<Jћ*ђ­ЕEYФu›ІіЯ­Н іеФцЪЂ.%Џ:нVXAKuљ:М3хф]ЬCXxЎш f*&т~)0]Л# (ЏЬKœщЌъгЊ‹ыTHVтЄя§plBЋr§€јо_њтУс‘.Ш1їˆ˜НЊ’š8цўиgЏ1!Ј Тщ‰'Ci_EОЕЖ(Ј*+ЉЗжп5)ЋЌИ*ЖБьЛJЌЌОЕќ-Ь<lNP7,Ќд*ЄЛЊqЪ5Ÿ&ТvЊ ёqtю$Q?еЉз/Щї$ m`}oЬd‹ЅЄЄjŠ$ыС‘цн˜xб›ДxхЯПSiƒФюЌФЦ=@ћЬЙ@кP-žьє$яўQƒњ"ѕэT$-JœRпHq лцd+Л9}3xъ__Ќy•4іCjпн%Т”ЁЈъєŠТ\еŸИаX?…%љžœA`}ЏwЎЕxЩВ%ЂЭЭPйбьƒЎ ќGкЄ “\ЋD–ђ* Ш1їЊс‘0IРkXй4ЕЬЏ|—AqUК%Ью§7~КѕoœдFэ@‘фш>А ЕџТп^РЊyЋ№їџŽдYЉˆi#’{ ьЁ‡šВN_2ѓ'ЭvЋuыеХ„!јbЫІєизFтхž/‹ѓ—3SЂЎ+uеп" DьиXœм'm`WeqЦжЋnЅ1<Ы<#;?п‰@M Цq хhДRд,JЏз#nBХG8Ю?зЌœМ№] Ш1їнБ“-їo xЋи–њЃИ•Н]CCьЂ›ЧVzл˜tз7oІ|—#dMБlбЅV}j`:uСTАГFM"Lљ”є~/бЙЮFŠvjRзЇ+yдql;u еOŽ)џR>ЖnЌЋd•ОHРŸифYЩаh48{ъЌ~ЪьdmЫBє€h›Ѓa yce†)z3Mџžт`hcыаЖЮAЕ€‡ШХ5Ёxc>›Ьe‚WJ@ŽЙW‹lT5I€uхрuИššSЎZЏQ`§ 4Š]ЙјRYДХa6(Л6 ЕяЫДzЮj }m(єПыёо[я!Њ”/wЇFЖнŸиЛw хUkмƒкИWть*АжЗ)I†ЬBв\Y &…5˜YоY$ˆ\€ёё• Ќo>2rЬ}sмdЋkІМf#АўJ i#СШ*ЛЃgИцИИ’E|ТИ705Ю[іzЈоCдy0c 23a№ƒюеˆ.јkmР.\И`-кЇ(ЁŒЖЦn#д•œў–ёЄ%1Х7э/ђTъВеЦмяs;,VдйКUk|+•цччS}†4n‡9ЮЙвО%‹– Iу&ТqиЩ1oosЏŠю1Ы1ufЬеe3в3Ф٘ьзђх>{ыЯ,?SI‰eЧЪЌg}q§ВˆOXщЪ+їЗпа~иўПлёХ_`jъTУV[œ Щg$рOЛєын)ѓRР ;—ќЧўжrŠ2УhЋ@\я%џVЁП`R`YqшЋQ‰Э&Н‹QYІТ[%†@5ќђLzЖGнЕ)ХёЏŽуђхЫf eкЊ4Œ•ˆœм?|њј—`пцз^}ЌŒi0ЙсШЙƒ=Лї ;;лдЄ1ё#аБCGфœЭЎU›VѓъSКeРйіemЮФБЃ_трсƒТq8ks–%[гЕsяs{ї˜i№ŒgЧ\]>c]–ОГьзђх>{ыЯlMyd?§Kў„РВТZXTˆ–-ZтщюPПn}дГo—mBQUhЋЂрАЩ#А}Ѕ№ЃђJQ‚ј$:51‚ФЇюuъиšаЭPєщо—QM5"T”бЯB>yK<&йTP(ugУlJСJ,›RА󹇛>4БЩ씉ЎOuœкк”N пŽ=iJw6АhЩ"Lœ>|/Бm<я НhС"› 9?bм˜qруАйMJ˜{ШИГэћ№Ѓ"iњ[ ŽУ~Tж_SCŒ9цо7ц–cTбЕГcЎ№;rш‚ƒƒ;4СЁСрk5й{†ЃFcзю]ъьрэ#yЦAyŽЭНфЂЂ>{I3m6УkXG`mŽ€L№R јЫЪкšД5ИœwпžОˆА‡УаЙ[gЛ’З†Ж–ќз€Ќf>,'Гю™€qЭ)мXє0‡SIIy–‘ЧЗя!tѓg<зo&L›`ШLП<•њЬiќђ rОЫ ЮRІˆtMu…21v `Oaф)ћ6к8РХz–ЏяƒюКсEЮ&lОРИB§њіУЪU+ХKž_єц8GЉЂіqпZ4oabЧa{§•cT$S“0mЊzЬmTkŠvvЬ•‚ызІaЭ06|mIЖžсФ ‰XЖd™YіХЉ‹Mgf ^tсHŸНЈЙхšт5 ЌD`ЫŒЈV 0jІ(БљекP*чХWК:q€ЧО§ћАtў_[ТcыюкЅ+4д˜PX6йџх~aћэH›Ћ#Ѓ}ЎŽЖ9ZЇбbЫбьU—ЯUVst №O+x§'Cп{dе5иШЙKhЈЗЊђ eR’+­Š=пr*мCЭsЊšіэлуйоЯтцoЂKћ.xУ‡ˆha—‡mU2ЮЄ—’šи,@Ёи—b• U_йY‰§эNYЖЋyWаІНвYСПГbZР\”ЖŒЃѕ›RLš:I˜RдЎH;1ŒЗjJqтф $ŽДЕыa_Nжk2Ф†ќщ~a† є•з–OЖФђдх"і0pаŒ5^\ЏH_ŽcS{фhћИ~FvYqeтpШŸBlВ–cюНcnsа,œs.Оf§Fм( Идь2зЏСЄщ3MQЪ}Ь–Я№„з&`ўлГаЗO_г™„‰"ЉА—эГ—5лЌ9ќEšх­в —іхуPIyеŽ\ Э_К™кЇџўŠWФCГcБ)Ю2 ŸГЈэњГ%?[зRСЕ%яэP”VooЇ#эу§^ээљj‡‚МYKуИgž}E ЅвЙДТ}ц”IЖВлЏ§p]dг'Fh%G•V5?Х”B‰уНp-M)и–‘зѕжЃysВЈ5kfЁ”/e[Af{єшQdЎ'eеј&bињжч$›фLћš5k†sчЯЁm‡Ж‚‡9ЮЩ1їЮ1З5^жтsа3ЬLчЯœ6к OF_ЛїъŽISH5оŸJš5ПGTЬ_0Kш“SпœТђ%†4kyЋ=ЮM}Ўю~80,юobюю\œ=gиP\Э=ћ[УъT^hй'Rd5Ќ™иЕ‚ІI=њДЮ1хбDh…;ioF­иh\IPX­Jош §ЪВ2JЕŸџ}>оKy'П2,bhгЙ ^M~;ЎјК •ŠАzddиP#АžЈЯлър)@5ЉбжЯіФХџНhHцQVdЩ‹GfЦu1‡Тq#т„ђ;kЮ№b0&ž‚эбЇЬЦ•• Ж{%^Є3kЉ`ЊыsЖ}/ ќ,z‹ъX+јsx№‹;Gaё#ЧмњЛM="+wщю1/W•uћœѓ,2ещмОГ™ђЪU№‚У'Ÿ|œюшЧя„Ф xeФ+xwХЛ)НVКт‘(wій# ЖQIЕ(АЌМіŸопF“€ѓw8ЄР2ƒвNC71Ц*ЏВЅ†dЫkЋ…Œ‘К|ў'уgХуЭwпБ‡w!тв?MGX„уH‰Нzdš”€ЗJРŸиЪژбU5кЪћŠ*hы3яС­Йw+UХИБуР;В~ё\Нz6j~*4ўЕёшжГ›8оЙ"х‘_ц )aЅLEІгЇME-Э~ўљg›гЁJ\P +ѕё‹_їK:tю€} \Ѕ}ЋVЎТŒiБhБag‚.]к€уl‘ГэcГ]^Кwы.XЦгFє ƒЃ­:”x9цо1ц<Ъ}Ѕ+ї˜2^Šяь˜Џ[Гг’І)ХЭќбЏ Ч;K—9ЌРjюгрБЦ9œпЌ2^ИГЯlvЙЊюЙž—'ўyŸИЇOžAЮн„r™мБeўєŸRІРВТЊVhw,к˜щж•Ru[4у!bоFŠ"еєwuŠ№НœІAўŒxЛьТФ…hаЌbF™ЗcKњ\ЪЙd:&•‘бФ”Ddў#SќAїиSчвЊЦOKфtуЂеШZП lkех….Hš—dВЯbg5ЅякД‹ФN‰˜WbР<дЄ КпњяО§.Ўўјj‡зgДїдSU†ЋQ|ŸЯdћ)2u!cJGszgAџ?{o_E‘эўoоKоDрдQЂ#ВЈ  ‹Ш&Ћ# 0•a!Ф ћŽьШў ‚A…€ƒ,3ВЪ.1€ВDEР‰ѓ‹Т<фщ|ђЏoнTЇnпОЗћ.IюMN}>}ЋъдЉSЇОUнїєщъj9g ѓŠіЋ‹7m]>Q›Оќц*НП94cКiѓFЊ]ЋЖ№€u)TРwфд‹5АЕък?1ёнZx”Zѕ^Uщa…Š8Џ1V…ч7М­Ё0`!šCщ Рc^:И—fЋVc }pƒд­{7Й6ђB)ЃИњJ§•UxіЗZјЭЇ9яД‰|aМцaЯEБлИЃ ˆЛ$ЛpшР!2iˆ[ЧnЉяу}ншЧ3Žгšk$mоˆyєЦ’7h№ЯШв–С(љ’жь]Cб•ЂiщŒЅДrўJJšюКiH[іџъМQОfБK& VГ!ŒЦf'ЮІб‹FSЫv-хжЋ—Ў&6`톆3A РXxњ’6Vƒ˜PT•Ч<‚+LTХ2ЮŸ?–Цk˜@r5JЯ€]й:Ћб!•~jl‘gж(є‘ШПv…Ђ„+=\V|ЪГexN„Ё}ГЇ-Wlџ‚МЭ4”щ!љЅdƒ7yf2%Ч?oiРюxg-}g)ХФКф7„њЖыkА;ойNK7Џ4ЪOё4‚ѕv+VЌHWrЎШO=bНЮиyТѓЫN=А!j.bФРˆ5+ZАЫ ЬmpОєА_+yщQiЖŒ%5яЉI+VЎ(M5Ъ]лЅhРцбSc;JРЗЮпiЄ•'UэJ`Ž=FHьۘѕ'‹G|ТP§оVQC7b!t›€—&№ pel*vаЊUwп†E_ CђТEwWеН ЖЪ‰oЏВЎXдC}ЇaЦ›3шэџy›RчЇRХџЌH#_IMZ7qZљ.t›› IDATŸАж6P<1)ыѓВ>ТСїЯлzмр%Г_hц“/Жа—ы E›ѓj_Xslж$я7ЗRєЕѓТюFЌ“]…ЈšНЖyЛ‡iч{;=жР‚fоv/|)#[oмё;wWЉu‡и*gХŽFqQy5ЙqВ’ЅшотZѕjбœUsd1жУЮўгlкr|‹7vІ3~!РXПрbfF€`D ,ОФеqЄЫPП+‰ЧёТ K№Т:9~/ЭTВїrіћгљbжЎ лŒЯ"—ЕњъчІъвщKхчё‰DЄлuЗ~I&~@<Э3`№Т+ŒmКf$Я0duюеƒ–NВ~И*л|cцFYЕЊ7QЮyQO Ј›}>ЛШУќ‹VШIF Hи$€\`F и(,іyнљЪNЏBЙу€хblž0LХШ]еє%HНЌ(О1.xTЙ‹лђЗњнеiй_—Щ}`LtmHŒ}`A3{H4m@}›їuэBаЕНхњW4ђє0зŽЩЯ&гbЋœлkзЄЩіћ$ѕЁ7ц.ЃОmХKbb‚Ab^L}:є‘лшЈ]кtlCSћMЅЏПўZnн1ѓuёЦ;F DА6D@ВF€`#`˜v!—ьC >R`ўPZыъЃšuбПђ]ћР(5яd ђ*[hхс;0ЂŽ“€ЬYэzDя_“цэЖ ~Т0b•!k№Ј„р<%IŠЄbЋz-;З$т@Р,Жh)+Ё,ѕЅЌŒIqїƒЧМИ?љхqЬЫZŸMцUщM2Еже_ ђЊЦQtН6§ћТk /Ќ ЖЯЪЋt+ЁNIL–;L/|•DЛм# ќёР–х}`C%Ы_p.+ѓ7|Q/ЭЪу˜—Х>‡Ј6bЙ…–и 6ьТ№? ЇЄ—ŠџУaзqVЈL рЖLt˜;С0Œ#1„ˆ6oљ™Аzg–їuОa­8+ЧќёР–Р-YD7WК™Ђ*GuY,_ЪЩuС…ЃFŒ*тс#Р0Œ@H6PlHб`aŒ#` iX§{щVћ2.ZАˆRХЇ_№ЩЧQcќ70ѓФŽ'GНxi€eJЬž;лDс,#Р0Œ@(6l(`YŒ#рŽ@Єy`•бЊВЊG›6ЌЅУївўћ%)q№sД).Žz<гCБxФVоVА=6ˆњ‰Ћ'rбТ{[ežYЂ[Х1А.vіГY/Ѕ№#Р0с‹ЎЅњuUЅУEуА1`й.S‚ѕ`\DšжзИ­їЯ4nТ4Њыкщy цљ4`­М­cЦ‘Эќ$ьSАU„СZE|иFьЭтˆ*ќШАОFƒЫF€АјКЈ6њрFŠNЌэy|Xє€рab Œ@љCиВОјт Њ_ЏОбЄAѓ” okТ_„зUЎ§ІE-aМV„с*Ў7‹8FпИ$|О№ЃЬЪЋь­:xеaцСЧV’“шЎšwQнъвђeЫнXвІSBяtWœЋ|Lr’ќЄЖ“)ЃкђІуйsg)Ё_‚lГaƒ†Дщ/› йййЂ=WtB4_СЎ=s],Љ[ЇЎ<vV­\EБЗЧbхђ8ц‘мчА1`сѕ;ф‹§\џ<™b/ЄъKGЬpБЮmыBOЃV3tщЧкѓ[Aџ*Дˆmс_цfЁВфЭ§чuŠЊ$,ЭТ€tю?sUж2V,М­ву*і‘ўщgз'ЋЋ†ЋєОБт’Џ,ТO?~TХ•-б_<цѓіЈoђдЩТшŽІ“ŸžЄO}Bп~ћ­›AЙтЕ4фљd:sі }rрŠОљfJLђНцзW{0Fћїъ)Žўtц‹3єўŽї)##УРcш дь‘ftцфy4h䈆О0д(ЗJјjЯЬЏ/Сђ,#йДЁШ€6ѓыљUo­ЂХ//&ФЪхqЬ#ЙЯЅbРžнq–6Юншvd|–aфQю$DЌOQ5Pt]БЏkОи‘ №ˆЎC1ѓЗ ƒіХhђ8Ђъ4Ѓш)|6‘-Ÿо˜ЙŒz6ыI-noA]ыtЄC&вЉONљЌLЁњ(B02И.#*Ъ’Жкoo’ŸgVирќЎілj*k^TЭлЊŒZ,€Vz_EњDЁё*H2ф§|ХM&М†kпYK6k(М›БдЙc;ТОŒzžBс…ї3Ix>Ё#‚ђl*ЯЃ^ЧпєЖлFlLŒИFŠщѕыжbжЎ[K-[ЗЄЈЈ(ŠЉ*Ъ'NІƒхў&,Z@#'L$м AfѕлЋг‚y 1_œљ;%M”7ИЉ•4Ъж3nTvа—Ž`љ–ŽЌЗЈПоDЄ”NUЊTЁ„О T%Ж !Џ_уй#ОmпБ]gЇœK9яГSЗBЮ„хqЬэњуC‰BŽb(:yъ$=5с)Џ’ЗЮнъёЅ.oЬљ_Їœ‘ЎOДšyЬ{Уšѓf~=?}иtКэЎлhщцЅђЂ‹GoЇžЂЗ–МEKо]ЂГrš(“”%ь§їпOЇ2OQуGЫБB4_СЪлњ§џК<ЋkЛšjжsЯпИсщ…чёЏ[оЇ›cnІд•Љ4bќкБe‡ЌˆGљЧOЇ§{їЫmК&ߘLГцЯЂ™гgJo* &o^Uї–§ЯљZJ%iфПаТ‡ьІ:ЕыHуэЧџ§‘ž|ќIš5g–4žСђd—'iљkЫiаsƒdд7S%­АzаQ KGашъ7WасFаo€ЬУАзƒЗёL‘LгІNЃ.Ль —.4 uƒШ‰АB <ŽЙ“>‡е ™”)Vъ№k‘&0X}ДEœžЉsвQ˜Іџђ,ГЄˆЧ€тAeOt]0-yёиўДэьщ5МVŸnM[№mZНnˆ?ЖнZаИ9уŒG•X0юхdZїкZК•KеbЋб†C(*FИl Cўе|zІљ3’оюоvdxa>oйлз‰;љ_oPТиСєєsE†КЏv|t„^ў*]њћзTѕі;фЖ?žёэqVњpZьжѓ…ЖЕаJSЛиХЁmЕxЄu‹џoёвж4a,Н)@КчГ.Х[‹VоVакЕmч­ŠOњЌE†л чб‚Йг ўuяЌЂѕяМgМd6yмdjгюiРL!H(žU“7М,Ѕ€‡xъфЉŽ<–оTЛ“Kпf}KћіяsЕ'0€зwйвe2?љЅЩєЧЎOає™.,jоs‡4ђНЩѓ—Шв‘œKйtшгOХ–kkes=žъASІN‘^TxU№6ž-[ДЄшџŒ–^XБИьйЛ‡РЯ!<(cюДЯс9b.­JЯ€5œцМSдђ…ёš‡ЧuNЗ­љФ'eэТ§ТSГtь<ъ6 'Х‰% xќeiЫвшє‰/iЭо5])š–ЮXJ+чЏЄЄщE_п:~ђ4­иНFРЫ&-Ѓ­яnЅЇŸ/2D‘яђl7ЃэЄ-{ƒЮuоНfёЃyЛvg'ЮІб‹FSЫv-)ч‡ZНt5БkРWb‰ы?Hiыpƒх@нг'œЮiџх;ЉЁ<АvБY%СЃЕЃ-•V^Ы„^ ”“•EЕzLЊ‚}`}mЁ&м”"шожIТб–Ј€6|мЋ€ыЩuq“ЊТЅЌ дЈЉЩгisuV}„ еO%Я[ ƒuдиQ„љUЕjEјмpЊZ§іЃЧŽRђа!ДтЭеTЃF rЇ,н€БЌњуѕС‡4 X|ь!ў™о4ќљсRdЪЪљ,eEPKGдњg'KGRWЇQюЙђ.]‡ЕЋSiд„IIѕ ѓxŽxqЭ>Uzaх2ŠЄ‘–џ!†0N”*хqЬіЙTЦІq›KЄMэ ‹ЗЮпjHPщЇЦz_Z`0k‰ќkW(JАЎеbZJЊ? єщпЃ њfUъ5~љЭ—iУЋkhЮШ9Т“y‰ЊЦVЅvO5ЇО/>o›;ойAKпYJ1БЎ?І!у†Pпv}н ифIЩЦХЛы Ў4і™Б.OjЁ>›пк,—)˜йёЮvA_iШ…KjлБkyЄy`‹ xWuo+іUожЪ“*аЯГ ‚j>qX"-z>л.]К@їдЎG0€TўтpjеЁ]лйy^ѕЅ*­ъ4mк”žxќ Т U-šЖ ЗзЌw3T'Œw]ЬЫОћю;ЏРUаUЅU{0іr.fб#ЭЁy7Œ—ИTП^[ўM?’,tэLаЂE#ЭWPm€GЅU{цzў.y+ѕ-?nМYŒЬyЎ?НМx‰c6Z,UЋYЇІc~ЫF™Xь”Ч1eŸ‹}€|4PjЌЎSЧ‘.OЌNsœЎ$пуГ№Т: ПVЄМJžFЁЙъˆgGPїОнЉ~Гњr;™Ћ?\Ѕ5+жжЦЊ? žц™GЩ3“х;МДoЇМMS—NU,q§ѕщЇЉ7hлšmTЅr4еЈkэQщмЋ-В”Ц-'ззb ЌZF`зюŒфдџO§ЉЦ…ВёPƒ %Š€з.%Њ…П•wЌТ ^UљT\1хџМ­V–™#‡U№Ufц7ЫеЫaPњђ њЊЋф˜yЬyХЇтDБ,‡U€c`эЛОїe5Ы7чЭrЭхў,йёЗfqFОeыіb‹Бі2onD3m§†ѕ4qмDіО†gЂ<Žy }6ЯяpЭR1`БЦoч+;НіхŽўL„}ркГё†Ћšђxi6Ў‚ŠboСЃЪ}42`Фzя­їhсЈ™bУѓыв#кАmsšік4ЃжгУž–щфg“щGс5ЙНvM˜<а(ї–ш§BošўЇщєъёhЩKш“д‡о˜ЛŒњЖэ+єНAƒФ.*иЕлІcšкo*}§ѕзв0ѓuБn‹CЉ!ш ŠЅІБЋaіРКpа—„ТлZЪУЪЭ—јXТљѓчнЖв*fЙ‰RD€ЧМфС/ЖVчZћМЊЕЎ~C№Џ|зў0JЭ†‚ЪЋјпАТVМB ъи…њд'vЦЄ2(ЭМЦ–XІь`Е+€П™СS’фaЊ.ГОкЕкюЫJгJ‹І;яО“О;џ] )X3ьЕЦ FЌ9Xб‚]V`nƒѓ‘–5дМЇ&­XЙ"2f-ƒF€ЧЁя ˜ *EšV­КЁЊ`WЎѓrš`ђŽЎЅњuSЅУ—А1`ёРФs` гT}.жYё9YЂhЪž8ШŽгkЙnд"=юЦбКeышЧKшvё С‰ѓ'RVv­ћŸUt)ынSЛ&MX>ƒjм[Дd!mСДiѕvКёП7ЈE7!cЮ8ŠЊхЕM.ˆ<Nž:АвЎКЕЎŠŠ‘ц EŸY#Р0Œ@d 6l XЪЦkоЖSo•XH >)ЪpќЃуДbЫ ŠŽ‰І­ЋЖв№žУЉХу-hщІ"кмбsщЕ-ЏЩfг–Ѕ як—ДfяŠЎMKg,Ѕ•ѓWRвєЄPЊХВТI&ЄХьЙГЊЪJ‘ц eпЭВV­\EІM ЙгцвРчš‹9_р1/ƒƒjгЅђ8ц‘мчџЯfЋп\A ™§ђц‘‘Aнђ>9ћuzВ;?BВ$HІ%‹–ИБ/\К‡&ђšw7TТ+Уc^уQк”Ч1wвч’Р>а6ТЦ€ ДTIx?…VzYсiЕ;„ї5ЏRѕ€› EХјё4oЬ<ЪЩЮ‘–ГЯeгŒфЁЭ2ТТхwоy'y;м–„IрUFЌ]&*‡\œKйtшгOЉЧS=ЄlФШУ‹Њ‡Y3fQѕиъrб чбGЪт–-ZRєF^X,йГw%єKаЋs:Œр1ЃС(!UЪу˜;эs A@ЭDО у@<‰ЫƒaњѓOЎуŠˆq ЏbY& ннp­G ЎаTzzигд iJ~6™:ог‚І&NЅ6л„F8K ?~ѓNп;gЉ›Єђ€/œ‚ZF`‡ƒЮx”ЏЖавгJ7ІЇUЙUœК:rШЅил]В#ПvuЊЛyЩаu\— УˆGа’ysdnСЂ42iЄ4tU9Чс…yxGIhSЧмiŸKџ@лˆ|і_љЎ§ YЙд[jсР3#-xђЈЂ !у,ш{ТЊ:MO[•{ЃСˆ]x=эЬ:Hoя|›ZvnЉX9.cР$UЧ9“‹М*Sqы~‰u{šНqs™эž†тzБvнZЪ<‘щ&љTA—^sН/щіэк‹eKi‘иYтг#ŸRBЏ/œL.uxЬK}J\ђ8ц!ъs‰•ЉСАйFЫЄ—уl^е8ŠЎз†Ђп@zЙ|VлgхUК•P‡#Pbр&J чО:GїжЙ—;оПXЋЯЩ’A`гжMдМisЊ~Лћ’#ф~јaByюЎЅvHAЯ xŽ^MyUlуgЧЭхЅ…yi!_zэ–Ч1eŸKoфЪРЅ4bщhЛСr`Т<‹e™Ÿg’=,;PN•z+ѕ-?nМeя‡<зŸ^^МФБ-nžkжЉщ˜пВQ&;<цХqи5PЧ<”}.Эh_@ођ3Ѕ‰ЗЭ8C@<ЎсyьјлЏJЗlнžp X-E0гжoXOЧM,.Џ”‰ѓ21Œ~uЂ<Žy }6_гќɘ˜#к€-&LX,#bœЏЙqУ,. иДa?žКtюкА %yI ^m№˜—ќxА[ђ˜s‹х |іР–Г/ъ.v;ЈyOMZБrE‘Seѓ2=М–у1З„Ѕи‰lР;Фм#Р”WТёБ[y‹’ъ7yI!>э№˜—ЮXDў6ZЅƒЗЪи"№`§iЖи:ЩпЖ.P—#Р0Œ#РX#РXk\˜Ъ@уzѕЅ ЄўЏЈЛžŽјSyF€`rƒ€‡“MG3OбЩS'§AyЉыwcЅTAGЏЁЦ1Mˆу0ЧЁцВš#˜Ђ0D•![JS–›eF€`Ъ.ge WOФяЂуЧNаЖэKуuв„I~wV=. ЄЎп•Rєёщ O §Ћ5ђ8cдX ѓ1˜ЙŒККшT5ц}љЭUzs‡@EИелДy#еЎU›к‡јmјГЇЯКЕУF€`F И№№РТ{*џ№§|s:ћRЖЛЎљeoы ьœйG6^#Уx?Й.DsйЯsЁOя>„eхХѓZЋn-їsŸsŒ#Р0Œ@1#рaРЕœ\э"-vэо%3кЛМPСц‹$žbЯkdxž‹F8ийl§"M8Х0Œ#Р0С#ре€Э7}П]5uчwвwп}ЇВоc?НVо‘м<џZ‘ СƒЩћjЫI{`#УЋЦ2иЙЌзw<џUу3Œ#Р0Œ@Ш№jР’…zчнwКА(ѓд,Я“ЅУc-…БzеЈlоD‚=АцЕ˜Џ~ЭeS}iФžwpФуЊŒ#Р0Œ#рЌЛzчНїIљеНЌЈ (•gњг/*‰ќ{`#ЫKІљъя\6зЧ †ќнЙs‘?™ЙŒ#Р0Œ@"ре€еMд{uуUtR/+ю>ЇL—MДlбRЦСцCЁ/{`#ЫЋЯз@цВ^_Ÿ?0„ЯБЋCТiF€`F D№ў%.Ќ-<Ю}eђ4ieŠЧC[+ž@hB0жМъэ•DUЇА“ь0Ќ?=—Е‰.eiВѕ9ЊБq’`F€`BŒ€wЌщБkцч™TяzВљИћŒ#Р0Œ#РDlРFкˆБОŒ#Р0Œ#Р”sи€-ч€ЛЯ0Œ#Р0Œ@Є!РlЄыЫ0Œ€†@vvсагHbТИ№мрsЁьž lРъW}N3Œ#Tџ]UЏQУMsІ1ŒN žeожэ’ЯF€`"eМцdgЪ3MќiѕŒ cРртP–цАЦхžŒ#Р0Œ#Р0‘€/!ˆ„QbF€`F€` и€5 р#Р0Œ#Р0Œ@$ Рl$ŒыШ0Œ#Р0Œ#` РЌ'F€`F€`"6`#a”XGF€`FР„@НF Šž6ˆe(QVњi§g}й€-C'8w…`pCрьЙГєЧgЛYЊхэЯбнRHˆv:B§@“%­cКщU„Џў{­TŠХН/<єyаДm+J3’~И”Хб_КЄd T:zь=—4”šЖlEu|œ&MŸAWМjлВaРZ}­Е™юТq`\0ŒƒћWЏ€GYН>шchњРЧдЎUЛ@Ћ—H=;3#§€RШ—•`зџpыgqco‡‡š ;џКдЉKš:> ˆŠЃvКЄh*§1Ё']Нz•2ŸЂIS&КI|{ѕ[4рйџІьЄЗmЁК5яІэ15 XHГњZг‹pf|\X0ŒCбYСз …EY=/Tџ?NпK­mhu‚wІ—јѓkњH#z"ОmпОЭMVъŠ7ЄзоxnђѓѓŒrxИ6mоHOtэFѕD}o!uя™ЗvМщіGбьKЎ!xš ›ђ8сfх?ќCЃ&L$xња?xћ`и;ЬЬѕ}іџ_y4kі —wЌгуДін47яГŽƒ’Ћгьњ`‰нПˆfЭглмЈDЫи_љ˜3˜;˜CНњ ьѓgнф™3>ёа˜cbbhPџСєїЯ3‹ЈRїє˜3Гц- 4Ћ ї<)Ы—ЩЙќXЧVДщн”-OцнЦ\№СKщFг„ћвн k7 хXбTоцД*ЗŠсЁЎRЙ Џ>ўˆkнЦmљВзЈe‹VU)šЂЂЂ)ЁчгєХ_ИёXe ЖF8ЊqЗћЇQщ.иЦС…уР8”ŸыЄ>жЄё'ћMіпЉ^§њT—uЦLœBC_F‡ŽбъзVа‰/О2d­]FЧП:M[жo ЛwRХhЂe)ЫŒr$Ž~šжЏYM™ŸX{LCЁЃU;Оtk.<вЇ>;%ѕLO?@7§ћM”ўё™?%˜Ч(%UДљџЎm>vиkNфўє8­c5јш Еmг–ІЭžыUžzE№ІО§нѓ@=ƒœђњ2ЁћїДExgq|/в йШ9§ѕy9—?ќыNКќџ.KƒЎKч.ДmћVЃњбуGшся—Ц A,L8бнŒЕY†ЏМЏ9mUoзў]ђfЇнSХшQ™^ёжj9~‚лM^7 kзoЄ>n8Пх—ИpˆЃMLwЁС80|^№ѕЁМ]є9я4Ныƒ]Дџа>š=sŽexzЌЃъtxO>7:dLе79№Њ­XЖ”jмюњЏТxзџ~†іџэCЩ9wюёЈЇ qЂЃЮ4tжuДjЧ—n№ОЗуš§вT%МЊwзЌKчП>M‹,^ф‰д­s7jмЈ‰ЙYщ]~ќЩЎДgQџ~К>О03 Еы?d­~cХЦV—UсMƒAbеЎ’­ыЂh*†bюƒyŒd›тf%іvчmњ’ьЃ=ТtЭДпЊu Ъ№rCc‡њІТMПН‰=иˆЦH6ьЅ'К>.nДжИщоoшzЫ{ВšŽž6їYЕvПСЂў_D§#ZИh=ј№CдсБŠХˆшnЦZзA вizкзœVu­bx№[Зћ5iPŸКѕъIяovaaцE[еbЋб†д" Э|*ox`AХeѕqїЫ5ТŒу ЮuФ<x>8™:“4ŒзЧšЛ?.tЋїЗ\QFЃ/]8Ÿr˜Кі|F>ZOџфˆСїуХ дЙ{М|Ч№-кЕЃмsr$ЬFЏ[ЁШиъ(x`Ќщ‡Yђцv|щжXќ‘yъ3i~zђ œа‡УИњьд—дИЫxЭ<}–ž{AМм"EуЯНQѓ”ћOїўYщт 33П]џ/ф\0ŒWдUFЅYŽЗМ“>˜Б“mЏvm:‘ЏŒWШТ#ъыПzгжПљБї-_Ви0^!ѕBNЎFРыGЁ]0їYёуЦЁa§ћhWњ.I:tфSq3зRЛХvc f3жnl2ОцДЏЊŸ~і5ЉWŸNež}iш•чиБCiаГ 4~Ц4Џ|Њ@ЛL(’ЫГRН†ѕc2І3>jІРCЯѓчЯ…€+.Ћч…{/фФZНCiьшq^™яЈ~‡\ Њ<Ј`„gtjн[‹ЭuypсЙœ:u Н_шa­*јvŠG’џ);аQщсoьSЗ‹Ілџ{кјоFКџўћхЃbФШп'ш№Д!Œ?–FŽI­7‘<0paФк_˜Йеuаџ;ЊW“kquЌ.у&aE@/†№‚ы!>`ќсщUЦВЏЗќ‘Џыч–v€‡ПEFтeвНЊРа.˜ћЌѓїыеŸ^^4—n­G7МOЬж:жакonќ…Лёгыјœг:caZyT‘m$Мо*lнЖ•/œkщE–k`žІeb‰]А4`Q)';лВ.г]А0Œƒ~‚№|рљPцƒоGЛєбSЇшї5юБ\ЋЇъvюд™ц-XJ/'*ѓ–,ЅxёˆZ̘5d@?Њё;БL@xЮnˆC…оЯФгŒЙгХ#\W§ьѓYДBЌwХЃy'С‰ŽNфXёищжц‘fђЅсC’dѕf"ŸКb OvхAМqуE [%JќрQђRёXнI№…™^пIџ;wь"ЧdъxзШ<БdCXџ™&ж,і/оф]ЫЇљKцщХѕЁsЧv„vŒ6M2ѕХH—ЁвN№PМоb^ѓhъф—$ЫtЁ;hvs~њ‚y4gЪKEoˆ5БУ]sЁVнZDП‰Із_]B/<7дRT КлŸо˜нœжy‘†Guзю]tRЌ[-ц5ž&LЛ ˜—Їb‰Aп>тN1мЅ­]CКп,Ю#яu 'F€`‡dˆЗлЖlы“{ј СTWlC„5‚X€лсЭnkнŒ’…лДy#Z’В˜Ь™ЉŠ(Ёwj№Pъ—4DОa>~Ъ8ё†ѓcFЙ]Т‰Žv2М•лщжЊY+Бр:5iтZ.аJФШЗjмЪ9sъ$Z,жХж}Ч:Ше5Ъ|%|aІзsвџСbŒЊTŽІŽ]ž”ы‹RћYVњЉјГоŒ#Р0Œ€lРк!aхƒЂ† zеZgFUъжЉKГgЮ&њеkЕА+Аыg8(œўQ:ѕˆяA•ЋTІ чЛjоEI‰I”s)'дcF€`ˆE€ иbК‚‚ТQbA ыџВžтЛЧл6ЉtЛђ§jпЎ=Mž:™’F%йжѓХ dњт I™§ I{ YњЪRJ‘LЙ—sщЪWh№РС”ђj §1ўJфjŒ#Р0Œ#BnРжkдШYotKfФU+WIOЖ‡GQх]TyФVДхЏ.7шwХ яXrх_Ы7ЊЉ:F›ZЈ šЎ‡QБ0ЁъыtЇmЎ}g-е} Ў!?§`К.Ц2НћЃнtэЪ5zЊлS–хVԘЊ14kЮ,YєжšЗмX-Ydє}EоWАъ/њёhГG]Hёк5k)ћ|ЖФžIox€co•egЯѕк”“~*]ЬcЇшКp+š^Ž4Ц žjхI]ОlЙ™Х#Пiѓ&jйЂ%EEEQLL 9ZђœЪ<хСЫF€`F€pŽ@Ш XЋІГ/eбMПНЩЊШ/Œ‘ACQЃ‡<‡ћіьЃѕ›зћ%CgЮЫЯЃ3gЯP^^Эš;‹R^IЁбc]F†Юwт‹tцфУ› =†'ЇM[zМЗх=НŠзДг63eа‰ŒДэ/лшј‰уєќ чНЪT[ЖnЁИ{тЈ^НzŠp cWŸо}(яŸyдчй>2ogФъ 'дПНЦэЇ“ЧOвЩ/NRЛkPя^НЅБНінЕFІџјўвƒ\ыоZнœ№ЇŸцБ3Ыr’‡БŠёnоКЙФžдс/—F­“њрЩЯЯЇд•Љ’НgяžNЋ1#Р0Œ#РX PсrV–Ѓgм›6oЄэ;JO’…ђхa­Vѕ&дo0%cЦ. кЕjSћЮ]NІеуzxдTi+шzЯ-ЗнB?\њA’U+ЙWžJ,ѕШzФйыЁdЈи[›—s.Sѕиъr]j…їьЊЏЧ№^0„fЮžЉ“нвЊO ›ЋWЏвф‰“хЃmeЫ–.“ќ№Иf§=‹”9?фа­еo•ђЗ_+yЬВЬy+œ”2™'2Љ~ƒњд Qњьшg’Œu­Ћо\EвHЯЅт5ЧўєгћLЮЛjwTЃз_}ЦtyЭќ*џТѓ/аДгЈZЕj]5šRWЇЪѕЦяЌyGБpЬ0Œ#Р0 ђ5АV:Рћжsp?zГ§›њОжРZЩV/qеЙ_МPѓЙ§ 5V2"†Ь]<—~ўЧЯ> Рpэgll,]П~.^Мшѕ%Aшщ§ WќY/F€`F вЙж €hБўяЧ‹ЌŠќІсeЃЬЬLљv>ж §гP)cцTяoоћнH„Uиќ—ЭдГЛиšЩ‡ї2\Л„eџјЧ?hhтPŸЦ+єф~†+ўЌ#Р0Œ#‰ЛЩ“/іZM[П‘юЉќоЄИgЏž4фљ!tјГУTщІJдКYkкЖ}uБиv+$?;юк†*КЅYGmееЖM[љhнN—HэЇ]ПИœ`F€`ќC фЌy?и›D їMЋ_[AŸ“1ђГЮ(хЎ†oѓъгЅаPO‡ЏЦсЅ>/‹ТќСЮо№ъ­K›Hз?1eF€`"Ал>иMS'ПDБЗW—( F~лін!Eeе›ЋhаARцЂ‹мО№фOClјƒVxђ&MІдхЉђ3ЏсЉaЩkХѓКф1чF€`JАџГЂЅіош–Ьˆ‡3SГІЭ$чсOSг&ž_лвХрн| пДчйœњьЕoзоk'ЪЃ1ЧѓкыtрF€`2€@Ш иA§hЦЫѓш‡K9Ф3fM'аC:DM7‘"Є ЦлŠЧŸК~иV`†ˆ@ркЕkљ‡ˆ—•dF€`ТАѓ,ЅЛvRЛЇ:і„EМsпyu‚EњGщ†ѕЋ/ОЂњѕыЫ<Офtыяnѕk Єj_їЮ!Нќехы)ё гилcЉrхЪ” ёќkљВzн:uщьЙГJmкАЩHƒŽr|1ЌЧГ=Јr•ЪT!ЊѕˆяAјМЎПAзUееiЛїьІ† Ъ6А&tэšЕŠMЦоњBЛКК ќќ|JJN’§AŸMш„%r]ЊшяЃЭu}=M1ˆи—.›LњjOѕБJыѕЭЊ<”:B>фaЬ1ЦЌЭ]ћЮZЊћ€‹Юž.š/ЖѓтW’Kc0ї№Й]ЬM=јв_ѕќJЗ@ЧУŸЙЁыЧiF€`F ИЙ‹}`tЈeы–вƒКэНmп=^ІSWЄв№aУ Яj rѕ:XšpђШI)tЌЏ§јиЧЂO™”›“KU*WЁЩS'Ы*ј BzzКLчOsџ!§ уtѕС…n]ЛQrR2х^ЮЅМѓшюšwгЈ1ЃdНPўєъгKxЛgPСЕЪ8A†x_§“ЏК†ТФЌГшћ пгХП_”Ч7п~CГцЬrcлїб>Ъј8ƒђў™'ЧjHтЃмNƒбA{ъQЙђЌ›ыњ*ЅŽhwпž}Дя~йчо}{S›'ка~@ћwКhёЯФЫOц*эцХьЙГщГЯ?“sямЙstљтeUUЦОєwc_МvусЯм0ЗЫyF€`F XИœ•UрфHYМАрЬЉSŽxШѓЦƒvvmп&ьяaј‹У „с*zїъ]АqѓFяЬ…%<,vu;Pš H_ЮЙЌВ2ŽЛ'Ў ы›,ƒv%їJС-Зн"ѓЛ>иU ™Ny%EвгVЇЩ<ш(З yyy† ”›uАЊcцSЭ=—іьн#ŸŸљт EEEббcGiќФёв#)зkŠQњшэъщЂж\)Ћ2–y"“ІЯNФ’jUЋбВЅЫЈ§уЎ—›|ѕв}еЕеC<ъЎPIр›яТWзIееivКЈ:*жыJšƒіT]Фѕа‚жбAŽцХ/гп юСЎOzЙžVRtš]_§™J>ЧŒ#Р0Œ@q"ђ%VЪf_ЪЂ›~{“U‘_4|Т;DЗмr‹4FЯ|y†ъм_GІQцЭxѕЋsмq$МВFhGžQ•ЂшўZїгі-л)КbД|ўЦЏ7hї‡Л%Ц+ТгёOгˆФr ъц§œgjХaі?Шm­щеЋюыhы=T6НЛ‰~јсZЖ| z~!иW?РфЋЎ!Є0!<Ђ”}>л g—MqЗЦyЛ„.цњСЖg–ч$яЏŽNdšyьц…№|А-ю`зWцFqыЪђF€` 2V9KЅUмЗJ(ОФ‚pєшQjмЬЕуР‘ЃGЈyѓц!ъ]DRb%M”/b‘№ќс%МШЅBЇ':‘Xв@JтA‰ƒtЎпИNбббв‹wsёЊrЇqГ†ЭH,UFlЮ9”јbЂ[еAЙ^*z"\џхК+!~эњсЋЎ!Є0б'Ё=RОˆ†—бЭiАгХ,'иіpУЃмfљVyuД’aGГ›ƒћ ІЁJX_›•)“Іи‰ ЈмЎЏўЬ€рJŒ#Р0Œ€Ÿ„Ь€U/nЁ}•Vёў(ЁЗsЧW2ŽdаЃ<*Y№’’к жW`ЪFEЭZ4ЃVm[ЩЧф=ћіЄžн{"[=жŠВ.gQ=$ qжwYbЙEƒчЭЗо”oъWјї RN›цmŒ2+VЎ ЭйLбПІІ6Ѕ6­нхќЁѓЈыЛJ=ЧŽK›џМйoз_u !… МФvл­Збяюљ<V/Ж™y­ђvʘылоИ ушО†їYюR`nKх§еQеѓ'Ж›“&LЂћъм'Нуїо{ЏмiУљNyэњъЯмpк&ѓ1Œ#Р0С цЪ‡ IDATђ5АС(ƒКОжР+›ы3Œ#Р0Œ#РD>Џ‡з),№Ќ^юђЦЫtF€`F€`FР Аf#kїц/œWьњ­:Ч4F€`F€`В‡@ШжРzƒлn1Ž–ПЕЪ гF€`F€`ЧЛ MЂХvS?^МрX)fdF€`F€`М!Pьl~~Ѕ­пHїдЉчMІ3Œ#Р0Œ#Р0ŽљXѓK\7‰юy M{i‚cЅ˜‘`F€`F€№†@Ш XѓK\оfzЩ# >Дф[]‹ўєуш'Gщщ„Ї)ыяYЦдBЇ KbF€`в@ и—WЇVНЙŠ $Х/ZАЈиОRфMQТфБЩ”К<•з№*ж`F€pŒ@H иФ'/'ЭžAOtzœš>вHЦГDєP‡У‡­Йr˜š6iъ&|Ъ+((№YЎ–c7\ћxъГSдО]{}8‚NЃЏъЈ\Ѕ2=кьQšђвљi]]8x:wэЌ“ŒДŽWўЕ|3n е­S—*DU ииXъёlJ?˜n№s‚`F€`Š™›}>‹žщп—ъжМ›жЏн@Ÿ“ё]"џЬ От[єYE­† uша!jвИ‰”t §5nм8RYDYCркЕkD!_(CвЃ‹›˜мЫЙ„Oќцххбƒ Єььl7oћЏлhеJп[ШuяешWЂw~HљtюЋsдПWš6cš›,Ю0Œ#Р0Œ€ Аѓ^]JЃ_N ЯіЁ˜Њ1R:bфGNKEyА!§ЃtУѓѕе_Q§њѕeўџј‡ќNМюе2З•ŸŸOIЩIЄASuБ,сЎšwI/Мj™™™Њи#жлђUWё!Vi%lіЬй{{,UЎ\™њ%і1eЫЄмœ\ЊRЙ Mž:й­ ,“8yфЄ[ПМЕƒŠнКvЃфЄdщЬћ1юояQcFЙЩє•ё%л—ОV}ьвЙ ЅЇЛчˆ%$§‡є7 tаQŽрd\Ќp@ннюІvЗЃд•Љ4№љ Й+Н‚iЯMИEfPПAДћƒнn%јЧЪзWRџ§Ѕ—е­А0гЉ]'J|1‘Ž;ъvSeХЫ4F€`F€\ЮЪ*prЄ,^Xpцд)ЏМqїФd=cY:ЪЖГkћ6a{xУ_^ WЩаЛWя‚›7zg.,‰Ћ!єћ&ЫрC4WЎ\QйёHИ€ўЖЃuП vuu^UGтЅщs%їJС-ЗнЂŠБРЖрrЮe#„];nЬ"ƒ>˜ešyTоNЖ}•,ФЛ>иUаЛooIJy%Eъ‘Ж:MцAG9‚“qБТ!uUЊЌ{ъј))Члћ@к3Ы6Ы4ЪcЄЭOмœуй`еЫ0яPжрЁ•*U’чЪшБЃнцЃQ‘Œ#Р0Œ#PPFЅј3Е ›6oЄэ; }hфш‘вИ†a4h%`pыЦ3кLJLЂФЁ‰ЎЗж…wюьщГђEЎ`єЙ~у:EGGKу/t цЙ.4PљvњZѕБгH,ї  .=JD ЋшИTПН:СˆMY‘B‹–,Rтlу@лѓ&/…сE2lƒѕЦыoадISНБ SŒyтШD7žvлICѓž\Ќ‡nлК­gF€`FР…@Ш<А+ŒŠй/MЅ§ћ2Х6Zˆ‘=T!уH=њШЃR\FF†БЌ|Знz§юžпЩiѓKSv2-7aнз№>у }Ш5b5kбŒZЕm%aїьл“zvяhВо›oН)wWЈ№яЄм6Эл%OЏlЇЏU[=жŠВ.gQ=Є(ФYпe‰Ѕ(E/ћ3.еc]FьК5ы/™9 СДЇЫЧђеn­F§žы'oN?iь$ ѓъiМlі§хяuM›:жoXOїжЙWЪlкЊЉєžџe§_мј8У0Œ#Р0.BЖ6T€њZЊ6X#Р0Œ#Р0Œ@ф"RlфТРš3Œ#Р0Œ#РD lРFЪHБžŒ#Р0Œ#Р06`y"0Œ#Р0Œ#РDlРFдpБВŒ#Р0Œ#Р0lРђ`F€`F€ˆ(и€ЈсbeF€`F€`и€х9Р0ЅŠігхPірq-{cЪ=bТ 6`Уi4XF€`F€(—№MŸУБЌе@ы4ЄеQЙJeљ™VѕЉNEЗŠ|Ы—-—ѕ›ƒЙ^ll,%єNp}Ж<о‚ЙОЪ+ўќkљђгЄuыдЅ Qђ{<лƒвІ+Пb_}Б„ЯкіˆяAР в щСЎрU§ВŠЭхц1Rхˆ­‚jпJЖЂYе MЕ Y%)#’ѕі6ІWЏ^•чvхЪ•ХџbiімйnюоГ›:wъLВ\œGƒ’Ÿ“vc2eT[о№ТЙаЙЋKц]qwбкwж№ЩhU†6‘6Fк`.LиЕч/џ”—ІШkЎГgКуa–ЩyoуЃїIЧVЅѕrЬ|ЪY]gњ%PЮ9:KиЅєлЌt uЬ2B‘D@ъ˜u… œ‹VA—ДелзŸ}зўїѕ€O‹ƒOйz™“tAA-›нџљйsтГєB/œџ˜зЖzT~Њ\lЧc…7œЬџноъъѕu]‚IG” а•a…NKрФ@y3ь0p\ќћEљЉЯФ$з7ш]MsВS–ЇPъŠT#ozs_#›=Ÿuў)XНОJЋ6Кїъ.O”w~Hљљ§{ѕЇi3І)ПbЛОшТ№gлЂ] ъжЕх^Ш•в й§ыrV§Bl•зiц1’ќ8iУf cд[Љ˜јbЂ<З/^МHчNŸЃѓпžw3(—МВ„FŒAЙ9Йђ<Њrsъ•аЫJ”AѓеЮŽOvЄЁЯЅмм\Ъ8œA‡2ŒК={ѕ”ŸК†>8№йkа|_эYеѓХПvЭZњ8§cЪќЇ#лўы6ZЕr•­ТjžшqLеjеВmпБнЈ›чuяЌs3VЗэи&љР_\СзџЙМ>ЕяHmкЕЁsчЮQСЕZёЪ љЉrЅ№ъ§Wi%C/7џw+^Ф:ŸЪы2‚N_ЮЪ*prlлМБ eёТ‚]лЗ…ќалWmˆЮzqq)˜5gVС•м+@ІрЪ•+Л>иUащЉN’4є4hр­TЉ’*6b3 vэоUаь‘f’ЇYЫf2oT Ћ:yyyєолЗЋяV.фф§œЇ“NлѕХ,xрs R^I1“%mрѓ КЊаЊЬ Эќ€іяtбФХ•†&5еre•ЎЅЁЗЎpОРx— Т/žЕ3Odz )щћг чW чGNNaщ–р‘3<1*t‹яF‹–,",заJ*dЯ & šЭ! olq'уъы†}AЬ ёД Ч7п~CТYсІісŒУtђШIyоy›Яn 3ъQjнъЪББт зк”WSшџС‹cz0ч*щеЇݘ5Czа2/†ЫЫя­пxJ–œ”LЙ—s)яЧ<КЛцн4jЬ(ЉЏЗ:‹,Ђ oНИfс E•ЪUhђдЩŽћш1\u‡НАђѕ•д`ЅоњЂгЛ<о…Ž}rЬ№ИfЩ aАвG$йАєф‹_јŠ+и§ŸЫџя=|6я„ЧЇ€p*дНŸNг№’тN5яч+!9RWЄРУ‹і}y`Х#§xЗp$0”wЙИѓT4є4<Ж№ъwOV| AгИZ–k7[~—‹F<ъ(}ФИŽyУXaўјZ‚b дЁЪЌєrJS20OсpЎX6Є?ІЖ’% )aPсTwі Љ ЇЭ*жљЌvPu№хЈЃ№Мт1ЁвУŠGёл•Ё;б/qб‘эрNYЎЛоЇСi_ЌфСГŠЗXб/е7+o+юєpз)E я0вxћж*ш8Ћr+š*SqАm(9ОbшЁП!uИуѕАdEЭAƒGxрБ> c†C­“BЙПђ ™ZТ +Ї4%І4єVmЋИ_Ь+<ЪrВ њi>”ј:ЧPз8œW8жЯA3ш“х|6u^IuТ<СN!К\НcŠЙ /m0СJWЇ4еЎ0XŒнEр)ФŸ V§ЦВ:ЙC‰РџИnъmZе<аСk8pС†pд]ЧBяўЗѕ2Є­Нц№Rы“ё„љ`ч каuблєчџз У~zЁЎy\эxЌ0аuггКžцДS>s=Їљ 0ZE#~…MТS9шљс”їkž_ѕ|1Џ}3•:ˆ§Ыv OIэZЕЉ}gпoђС+!:щK$—1Ž(юЙTмђu2ІHе;€Ўr•bF€чR1ЬтЫ|žј7Œ/!ЎiŒ#Р0Œ#Р0С!™™Iт)ApBЪYэпепU;ЈЪь} >ЎЬ0Œ#Р0a‚@§Fѕ)eIJ˜hjlР†nё@dХZ–]ŠћfЈИхзШDЊоХ…Ы žKcЧ5Ыјl<џ| э07#Р0Œ#Р0Œ#‚0`й’`!Œ#Р0Œ#Р0~!„ыW;ЬЬ0Œ#Р0Œ#Р„€зР’|‹НА!Rц(+лЃ”F?JЃЭ2?!У ƒ<Ўa0Ќ#СА6‚UgF€`ђnњ8!œ‹Н`ХqozŽѕйQИH'G)ЋдiHЋЃr•ЪђyјD!‚Ђ[ХЊёхЫ–K>Фц`Ў+?е†OЊoС\_х?>п:fмЊ[Ї.UˆЊ@пуYзgt?БЏОXЩС'ёй^р†iљ9FйЎ`U§ВŠЭхц1Rхˆ­‚jпJЖЂYеcZйC@Зšzё9E|ГrхЪ{{,Эž;[/Ін{vSчN]хт<Уg0еuТQЫјjl8W:wuЩМ+ю.ZћЮZЃvіљlЃ :4_СЎ=s];ў)/M‘з\WfЯtЧУ,+’ѓVѓСм+•жy0?№iouЦ\Т'gУ98щЗYџ@ъ˜e„"ˆд1ы 8­‚.iЋз \_Є]Ѓ б?с 2>y >ЛkŒ&Т-щd7Лџ{|:zсќЧМ~ДеЃђгѕzCvѓхЋъ’ІыЄ˜мh%аеЎлДi№Y$мt/,Џts%yю+vЬБЖкЊЌGl>=4‚U{80о‚Мis эY]—Ќъ[ЕgХЇhVќmлД-8~@БШ4hХlЦКњ:г№‡`s ‚?ухM.к імХuч<ў+ачДеЎ9ЇїYя[–јŸ&^b‡:ёнухџ(tєVeГfЬ’з0Ьбо}{‡ф)uИ6(л}WAЧQOЋrov 0VЖ јЋ[|_эCІнџНќч‰Џр„ЧNsЙљП]ЕoцStЇqрXŸ’НёП7„^žСн“гšlŸо}HнНФФФPћЧлгŽ-;Ќ+H}§езiXв0Y{и Уy_.^Hm[ЗѕХцИЌSЛNЯббcGх#Ч-§эЫжїЗЪх fQXТАћƒнfr™ЩялПЮ}~Ž.f_Єя/OSfN ИoЈ ™mЁhoпž}Дя~Ъћg‰?jѓDњрУhџNM3'#OgIDAT\LihтPsгŽѓ%е]!'mъќЖщ_<92Odz )щћг ч_ чONNaщ–р‘3<1*t‹яF‹–,",з аJ*dЯ & šЭ!'hХœŒЋЏsBRє§qN‰Їi8ОљіЮ 7ЕgІ“GNŠ?ByИ1š2ъQjнъЪБ1Y<ўMy5…ў№ј Z ‰`Ян^}zбŒY3Є-у€№ђgИМќш/‚ЙпxŠ–œ”LЙ—s)яЧ<КЛцн4jЬ(ƒзЊЮЂ‹шуcТ[,S>ЁЈRЙ Mž:Yж ц'\u‡=Бђѕ•д`ЅNњлхё.tь“c†Ч5уH ƒ•>њј#YKOО8ёЏИ‚нџНќябУgѓNx| (ЩBНЏр‡—єrŽw,МOН{ѕ.8uќ”єИ"FtныЊЇx`Х#§‚[nЙEохŒф],ю,UM= -М‡њн‘hЏ™КЛGŒМЙШзш/Г zћŠІbНžžVхИ[С/юАqч‹;ьбcGЛy’ЏЏиI_ЬѕЅоš‡Ш(Д`<ЬVxш4Ћ1вЫ = VeV4s=Ћ<ъe}S4цо‚U;:M|ЯкCž^юo{Vz@ц‰ ˜Ї–4сmёtN+‰~ЈvUlзІтГŠuнU9МFИю+HыѓXё!>%žеЉ]ЧmьєrsкЊ=аєіpн*рšЇ{ ‘ЭIАjЯW=+~Ї4_r)ГWшхыДЊš ЈoЦбЊЏŠп*ЦгŠNOt*˜еј€c)m О‘(UЏ}c}QЄ%h/XИ…Ж/•Fш‹а#mАѓ›фПwvvЮю9svїоЛћ=psЮ™чљьйнйййНўѓоkЇNПэ}Эš›ЫЃ:тЧDЏбълm%Ж=юПЄ‡ї_ыgЇумŸЅећДџ ?œъ›žWџќъ‡і ‡џАоЧ-mЩ>nKšПЮћ}xэЫНПG…еJ3Р!ngюНнЊ‹гYX“НХVO*НhІ ^{] ­ёqЌ:І'ОІреq}Є1]кb лŸОrвZщчQœкiљтНТmKѓЈM=№PxёЋJcскЇљуИмБЦъЋ-•ШЅ‰лjёuњbimЏЧ+}#PœТв7 Ы“юs§Ћ ГvчЃ\Ћ+— ГєЖЗњтДёqH— ж-Џэ{вћˆ8,>ю”чЏGлВёšЪч‹+ЫѕЙtuгїф•K‹~XНЖWYі‡йqи'uvХ%'qл,JЯy=їѕAPзЖžЇёulщєЕКоXѕaЛю–ЋOзq<8бБТlгs8,ƒђсŠгqПчЕхг>W_ŸчвЋ-ёђ$ыУwщІ:ьЯЪАѓИўј8ЄKзl|єœhя+щЩc ьГзы\•‡Ќt§є[‚’­6иŸХхкU7ЬЪаuЊ ЕUКтЏЉse…”Pщy`э‰гХЧV‡2qZ;ЖјtoёqYЙА•кіNќЕЉхWZ’Ѕ-эO']ц@‚УђC_ЦеГW‡џ|шЯЕзч\˜Ѕз~uФхUЋёLC˜fwв|za—ЏmˆФ}б)-/ŽoZŸеяуђ,МnX'§ ш‡ЕХіƒь,]nŸыšNыSuЧлќГѓaPлd№ЊќЙњ4Ищ7€Mg7š<ЏsѕХ§Hsщ—k ь ЧUmMŸ3ё\ў8>зз\Xj”žыOќ#oђxЅyэ<зЎКaVFМзКЧAŠзun^ДыŒ­lНўц&3,~ћ•віДџš4вРГŽSъ Ќж$ы›mкkVжДiњ&чi;-oнї{НіiцОпV'MU;ЌмAёMгYњt_ОжЗpм›ю@ ;h-’6­!{ђЉ'нКЫз Ѕ)Чž9~!xщЅ—v•Їѓы7\яцŸ›я З­g{јБ‡нКO ЇКmЫ ЯНаYKsтнaэQ“5ЖЅ}9Аџ€;єГCс—Щъ—ўєЫe…)ЮЖ=ЛїИ­пнжщк-бДfwзїvЙЙнs–Ќе~uXїоБ7xk=ГŽЗlнbQ=ћ ŸнрќNТuЈuMZЏoЪлUоіЦбсИ+~@}=™‡АћQЧЎIїu щљЃз §BиЯRt]Чџтq7wћœ{ёЅнњЋжg‹nr{—m[З9џэSxmвыгэ?ОннєЅЛ ШќояэФk ЌТт­I}Ъз$НюАp№РСp+(]Л:V›GНеy\ћ='Ж|Ч?ЇќѓHЯЯ№ѕЧ ыЗљйЩwNбmгТ-§o:tФэ;ЗЛmп^ђиБЫЧћп^ш5N^Z‹лftПі6‰ э>з.х;ѕпSьЙ~ŸzџTИЧљчŸЖŸЗmяЄзA.ž;ЛoнвЋџrвšюЖлjhЛЦъћюНнЏэuњ~ѓ–›УЕzУ 7„фкяћщ>З}[ЗyВъІЉћ~Џї№ЛяН;МЇ‡Ељўqеoтл}еISЗ]#OWМ„рПЖbіѕх?МОf™ё_йщ+ŽјЏ*OX•Ћ_OъВ‡ хъыAћфЎ0лтc ЫэуtЙ;X}EЃxmЪџiцU_Z;ri,§ 8ХыыLѕKnЪЇOТa]]f „вчЖК}ЩхеЬjpі§ВОхf[ѕINŸ*УWM~6OЧњumnS?в-–Іi[GZ^ю\эˆ­u‹ё kšЧО&RПѕиЈЯq_”WeШN_Ч К С њвњuзgёuУ,§Jш‡ЕХіƒь,]МWПг?‹зŒЋfŸь:NПТKѓйЙЭTЉ…Х›Ѕ‰їqМ–шqWZџЯШjfGы,кфуз •гДОІщѕUЃН&ыxл ЧU}шїT~НъЕ_:V˜mЉТЕДЬо+,]КзЌЄН†щ:бвЗИм8^ЉžЋЙЅhiЙ§Юsm­fхњKчn#š)д{ЃmЙ~kй–Јž№šх_Лу:syTžТ•^Џur’Gлm%Ж=ЖˆћЇїѕ8NЧЙП8ЎyiЌЃMпръМэuЃВтЖшмЖ&яїz ъŒ/|Л”7}\ЅЩФm‹­Й}нtЙМ ћˆАОFлг~Іђ›пксѓœЮцгЇ|џUšлrгЇO|uЖЇ§LъўўdПї3!WЌЛТmмдџ—zšu№эЏS4iш+0юkiмѕѕэ|‹ШIщG ВI€kiH3б”[_€kЉО)ЇS@џ­ќюлšџЈl’ЕЪg`§ЏзЊЖŸ<ЂžŸО'ЩтТBO € €д(Рjё@еЯГЄжх' € €@SтЌ*ЪЏ€mкв#€ € P_ е6Ўfvvж-œ[ уЊЭвTХŽ € €@?Ё `уi|мЏrт@@h*P~‚3Нџ‰A:ѓšž7mщ@@HЪАiIœ#€ € 0vKЮdZ˜†Ѕч™,!€ € PW€иКRЄC@Xэf`3]˜НЖћщљТ+ќG6‚@@j ”`ѕ?q%ЙœжT' € €@Б@ё‚о{ЗŒ € €дHцPkч;—alS1в#€ €Дh7€е26@@Ц(PМ„`ŒmЄ*@@:х3А~іѕtyюN8@@@ ‰3АMДH‹ € Аь `—§!  € €MР6б"- € €РВ 0€]і‡€ € €4(џЗаjтLZ@@! 0;$HŠA@@ёіƒёДZ@@ш(Рv•Т  € €c(Z;33у^=ўє˜šH5 € €,  `п|ѓMЗуЖ9чўwzЉЄ–GGuДe dG@˜Ђl€б]ИС4\#є@XQЌ]QA@$P>ыKо‚AЭ$@@ГЬРr% € €Ќ*АЋъсЂБ € € `Й@@V•@љ–;ЌЊšЦ"€ €“"P>€њ € АЊŠяBю@pfUѕ•Ц"€ €L€3А№ в@@`šРNгЃM_@@ h1€­ўo .џєх@C@@VЂ@љЖЯњзЕkжК“'OЎФўв&@@U.P>€эгёэпнюМџ.wђ_ bћ0… € P P|‚Гuх—КћPˆ~ъЗЯї4щoo,і„€ € €@]–и|5 Rѓ.„"€ €Дh7€хуjџP € €@#‘Ќu~`ћаЃGмОєї™Ћж‡§Ўp6@@к”`§`T+`sћпу^џћыю‰п<с^YX ћзќЙТsщѓ+iлt‹М € €“*P>€э#2џЛywп=їЙ‹/Йи9ПHA{ПфУй@@h#P<€eжД ;y@@JŠА§*мМiГЛыр]юНwп ЩДзљFЮ† € €@‘ `їяля.ћфeю–mЗИѕўG\кы\сl € €Дhw­Њš}Љs?˜ UIG@@ D |Ы-БJМЩƒ € аR`$KДl ЗU…чв† € €@N`$и\EoНѕ–ЛрcфЂC@@ Ж@љ‚Lё k|ЌЄ]xлГ}O&A € €дъvё/‹Ёf ^эИ~SH‰ € €Р`‘,!`№:ž € €eх3АК Сytj]еЌŸu]ч:Ўк,MU<с € €є(РЊдшVZ‹ ~№zю<WехЉJB8 € €UХK–ц^ЋŠ&@@с ДšЕAььlѕ’ДЩ šЉeC@@ P ежъLЅЧž:цŽ/wћ~ИЯ­Йd;ёю wј‘УnУьЫТ@@"т%§j;њФQwчў;УрUщ4ˆеЙТй@@h#P>€=sКВоїџ§~6Ў*<›˜@@@2хиLaДёЫнсћ‡Ѕ г‚Cїr›ПЖб’АG@@ H`(k`гšмqР§њ—Й]ЗюroŸxл­]Гжmњъ&ЗsЧЮ4)ч € €4h7€=S]зЮяяqњыйњфщIK € €‰РH–$upŠ € €Ра†:€НЖћ~АƒЮ‡ж B@˜ђ,џ%ьд\$t@XIхи•д к‚ € 05ХиъЛРNE@Xvw!pЙal6ш|zM• € €ЋV хЖЗпГз^з˜žwEr‚ € €@Cvиф‡\ њуръ“<ƒ3@@%т5Аށш’"G € €ch5›Ўn[ЋЉ@@`jЪg`Ї–ŒŽ#€ €,ЇихдЇn@@Ц `“‘@@`9Р.Ї>u#€ €4(Рr‚Циd@@h/аъ.мJЋ§@  € €ЭŠg`?hVЉ@@Š@ёv(ЕS € € Š–ЬЬЬИ_xвmўњfЗцЂ7Ќ’ф € €”  `?7{;эџЎљgчЫkNrОізуюЦ_LB9E@@ [ hЋ">н5сЏЛИђГ>Sž—œ € €г#РищyЌщ) € 0 `'тaЄ € €Рє0€žЧšž"€ €!№Ьџ•NфнžIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/new_button.png0000644000175000017500000001542111733011756030174 0ustar sylvestresylvestre‰PNG  IHDRйё№XРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœїIDATH ЕUMlEой]я:ЕCь€JгІŽ Šš*qЈ „"%P”›oP •ИгЪ…;‡(€И'тТ‰H­RдC‘hЉ, qЛNтќкы§ѓюђmŸ2у5‰(МУЫ›яНїЭ7oЧЖЖЖ&§І.,,ŒЭЯЯ#9UNW(TU,9ўЏ‚VЋ5;;‹Adл6P@A0Црѓ€тŽl{UњО&xыѕ:хdYF‚xŸд„ŽRлГ|WxžG-‚C ЮѕEQЈ+”–ЩdрA † Шк—З#ЈсрA‡P&єў#u^ЫwL $ІЪzBbЁЌCM№B/Ц„">, bЪ-лљуІWНЯЖŠAcУ5›JіВ><ыЯ‡ п'О^„ЧŠ(GМ(ВŠ?4o}ееїќSbЇGќZбЉоГџиxАЈ~5љцЇJOZаKїaeeхШƒ Ž›Йєewn@ЧЯdвŽœ`ZNIїыЯfЏd?ИС+)X^^ŽшJbс!Ы>ДлdЭэ/ЎfїG_zTПЯX­iщ^kН’Ш ЅЮН`=^mš!oDŒл&єђ1RЉгbЃW^Йtоhњj<–ЪŸO чтOO_М”<{ѓ—\›‹рьˆа єяІ(Ќ7-Ћи–oьIŽЅ–Ьй5ќ}Ÿiz`’жй^;Ža[2 _/ЉJИЊn{N m™в7K'IJОїЦЉтЛ~УнЊ*Щ”я ,ƒщсw†с єн"М”#ПбP “Y<†ќVѓЫA|#wБ"стњнЋпщГЭв ФЊ=НžeJ=э­aŒ „^JB#‚ІэЏn8 ;X7‚5K]w%OђЎ&о%ќ]ЦЛЛ=ЬvЇfюжЛВq~P"‰Хb^ьCМoНЌ›•M№м^2фзsІщ\ињ3чпєзkзrŒЦоіон‡іЭФЏ‹_лСwууу“““д~ф>+єQХ­хR-Љ*†|eј™/Пя–яZwОuЖŸ3еьї›­ЅZгзP™Яч'&&H,МІiB/в0 фЉˆЩLM*­}™Щj,}*–>sbшmЯЕd-ёС{ЦэkзЬннT*555Хo'u]мп'ЬїbF=ћѓяC•jџЩPLжКдЉp—ttxІЇЇSМЎы Н$АУ_џ$ƒRёњDг8ўЬЬL6›ТRБX ѕ–Ыex„,еfG- D@15*ђža4<и€ШпCГќX###bОи ­œ:дЕCГ ‘р˜/Фх{ЂЁ=ЦВсY €~ЧрМsssaы1ЃvLl‚FЬW`Ч§Š Дk•њХТIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/4.png0000644000175000017500000011217411733011756026156 0ustar sylvestresylvestre‰PNG  IHDRюf$–юДРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь}\екџєЛєcWэ‚њ&j†•†–WќsM+СђнTЄW„ИŠhЂ’Љ‘• ЈЈ˜"h—д№_†aщ›ЎиMгJQ“LS“ќМ†Ўї"Ы-cљ]яЇпw8Ыйavf˜e—йЮ8Яyц9ЯyЮwЮ>{і™™ѓмsГЄ„уИwзх1‚`C€!Р`И?Ѓ‡љЬžхOэєEќxСщГ”Ы†C€!Рpoњr\ѕцМ+Ч|~мАџЙТЂBї6YЧp%}ќћ yі1qх5`mз"pёЌ\їьY–2яЪЩ†њц+Г9]-ƒ§e0м5Џй№.Ъьc"…‘.C zЊAиЖе•ѓ\љЎYxšб †AРXV{3‰}Lи˜p?ўћ™Ф,b0 ћ`Ўм>̘4C€!РpC˜+wУ‹ТLb0і!P7VŽКџБЏ>“vG{>њу?:Ј„Uзі1бqGлkі46+wtˆ4R}ŒМFвЬд2Z-чsФ\ЙЃКєjщЌ9Гњ ьƒŠѕЖкАЉzЫИѕШšf}јшŸХQиб …’ і9BEeЕЂVмЁШ\yЃ_уЯЦ№)сC‡=uфv(‚йш ГMЌЬ­Щ‹’Г2Гšx?Д0п&VЮБчЪŒ{њ{ЉГЃЇa б Т\iѓ­х+чУЖМЛuKе/UС/ПЕpWsMэйћЧЮwзПћсЧŸ@`Ф_FЌX’ЈгyђќЛмšДw?йћ wЗjіЌ9‘#Ql2› u‰vt6ьcтlDmє;љ­ОmлёcіьпљэЩcO<ѕDDƒ\T$K/йКmыuуѕП?'ќећA#еёйБU‹S’УoO~›ќіЪ+W.Зыахѕ™Г‚k?цзxГ™•пх}лˆРёЏџ%XЈE0-Ž;yКрѓџй{є‹ƒџЌРpЁ|BlЩиrёћ‹{sіž:vTяЁ_ѓv:сП›БхкežџеgGoоМ &.FŽ<С.Ђг~4Ўœ)ДA`зЮ]/ELРHўыј лwю"CZ4ШEE^†у О/ј4{зgk>(Эѕ}аЈ[ЕrУ9ёѓцОќzсЩsЛЖ}PXxжЂФІ/ТHМпYЗШцф"<œPМ~ЛмгЫK8‹CёіэrЪ‰ŸZ1љЅЩгfЭ&­Ќ=Л36fxЕчцМ6'фПCоŒєю=Л?xџТŸћ&еF Ђ„rc *дyЋьжw…пННњm@=ђ/cVЌ]SZvЋCчDF„ПЈїZœ№GЯ*аhыTž8%ї1дпЋ/љЇбЏВвЫЇУ›  ЋP…кbWЎMЋ-Њ•іэкWтJзјbвqлЕkOA ДC‡Зз)ŸЗО>zдh+ГіŠсї#ф­|F1šй9йхЗЪ{їхc†dЫўŸьйЕГœZžє_сgM(ЁќAJквrУДwв26eМћЗwлоЇ}AB`@ m]m8ЕŽA›жZd+ƒ6ќн€X6э=ЧІEL@Ш ЛuыV;Ÿ.”Opюмe;:Лјt<ЂZЌШhТмхpш№сУ|,“|FТ#УgЧ`НП†wKђƒжЪƒЋ6W{жмТKNЛмЧая1ПЗзНZš'.œїй‘Џф446ŸХЪkCiоŠy)fЫж-ћ?й_}ЇћўOїЃ;=–ЦцRVЇT–WbСOР‰%Иђ5ФФ№‰IK“n•оB№ЋДИtс‚…„:6tYђВJceueѕЛoЏ!ЬіэZёO:6Z_ZДfсg‘!м˜њћў?їљs‡ішxУа?їъuшя‡Р rQ‘ПJBлh‘у$?hнўд{Gж|0ёQJ]•JЋ‹дЪ} ёyф?qЌќ‡ЋЂm h<šЗеКйИrы)F9__пЬї2?ћњГ!#‡`џь№g™яmЮІћѕэє— ЖоmљyGн-rrdП§&Яœ<шЩоѓbŸў,9?-zкc=ŒŠЯ?зБуCцф9a‘aТŸЅ„ЯŽ &„РћЛvF„Fˆ ~сХˆvНцДКƒ\Tе%?hK.=rшШС"ІF<ѕч~T^ЄVюcˆЯcьмX|6зНГrѕŠеДКіФ=Hї|ш!ЄžxkeЧ7_}гTiвожЂ-Нє>wкђ0ЂэYЦбќњЮљ4эВ‰ірГmxcюБ W+?л=’œbГr[ˆ\Я)ўБЁpзлС,`0šЖ7Њ›ˆхЭйЬIQ“цН6‡уиЕpлЋЬ.л^šj˜+GžmЎFoё&Аkсъ !л>Л4ВаАЎA@ьЪйdУ5зЕкЄ`“&uЙZ„Б,Vо".3ы$C€!аМ`ЎМy__ж;†C E P'Рb,7šяИp8ыdE@зZG,g“&z›ЗйVWоЧПоzjоНeНc8‚>#ЈЮ>&Ž`Шъ:BUVWю7кЛ№Ѓ [иЧФЦбЄ‹„Њ•—~^*ЌfmЌ4NIXџcО]™0C€!Р`ЈAР:+W–і}ЮWY@ђьБs‡vžЬ:gММ;bЗЗйЛ№*В€H 2&C€!Р`4ЕЎГrѕо<$=ЄмTонЛK[ЯNќЃЃŸŒоК4~G‰оCзч1OЎВšгqžжd5kИхЌ&C€!Р`XuхХЙХ…E…BœN9…"юќд+ќп›?p­_ œй7њиEугГŽщu\Т_ЛŽyвЗђ7ыуs~2П>нs`_Ёz+а! яVžЕ\CI2E2ЌШ`0Z&ВЎ~|ь‚БЖ ьKоWЏ+чkyмy§аДЕ;МЊL]гgњр'>oCqЮqc;oнѕšKŒК›˜лЬ8 †CРno{bЁ л]]­МyЙлз}:{sž­Йбёпі™qьјЯе!ў§GљЗтO6ач?eи” ЎOEЪ>ФkЊйvЌођЇ ЎAIБIXHž01—7lЫ‰x"$ s€Eާa0ЭEWў>5†xWAћж| hФUЪLця_§'7"дџЯУќn\1оИj„ьяzX1kEt|єС+yiЛг О+ в;вw\<{!ѓHІс‚AЇгmJнDЕ^Ьј"3ЏLБЁŒ`0MzъОд}ТŽ“Й,4œx›ж­*дыtїд}wж<~КПЉмlШ, шЉыфуurѕД,Ё•АєzНЩhЊМ]щгй'.%Ž0swцІэLѓъРЇЅ‰‰5g‰хЗи…Б^5љьI‘ †@ѓC@йЁšЧЦеэ3џZ?yšExЌ+У—tpЊ%mu:ЎS{NяСyыИмХ[цњѕ~иы“ы[WNвЈZfвЖЄэяlп’КEзЋ^јЬ@4wНфzш PЋЕТрџn=Х(†C€!аьј<›О™ee&O% 6U9}kоƒcъээхЩщЬЇ$Ьі/)5ЭY]<"МžwJЛtэRњcЉяЃж'йK/–‚IZёыэЗrыJаšЏxmХо‚Н Л<а%#7ƒymл С8 †@K@@1Vо`<8]мзфЇ№оо:јq'Зыя%ыоŠœузб‡_–ШВ4‘TЁ/…&Ч&Ÿ-&7]A$П‘ &‘Х]Эвk5IхQўЗЅ>ЮІЬK1–Q_‘RЬx †C y" ;+ЧѓуџvаЖгdE![ОгŠkнЖѕqmnУБzyy"bЮн5??І+Šцџpf3ятof‘~ˆ%lFn]ЎŒ[YvЉ ’{t˜љAЗін‹/§пЭЏђŒfФX.+й’YќњLнЄ J~М™BэЪnнsЯ=ФЁЛвж6C€!аhШЮЪiбгУsуŒэљзђзЎ2нМеAясi4šп}ГBѓІе>>эбЭъ6xѓпџЭЭЋЦpoХ•“.|x`шЈъўчBф[w”іъЮ-™чуйˆ К7вn`ѓцnp˜ FA q=kXˆgXБ›ETхњйЋ”ys{cђ &@ЃФЪ›DЯ[Ќ‘,nоb/=ыx3F@ WюHЂf Н ЛЦМЙ СgM3Ц А‹ечЌаххp-ЊгЯБošŸ›^‡га[ё\ˆ‹Дбp-ЭFІkёo­kсЪеf ЊЎ†їšОFїЇ!\ѓE•яNгэ[c‹Еyљ!ЎѕЭ~[ЦЉцЭы…ШЕЬХЛџІеКЎ\хЌ\їКПgї~КЧКrе—ˆ:_/.е ѓєт_­йШыўІёмт‘цѕБк“–Пx­ћЊэпџЎъ—ђnНzOˆјœФ+EЂZrХfљqТS‰r§e|ЛиМzѓў­9Ј2>:lв<чќ|Є4ьЗf9b)&ŒC@ WЎvVЮqе— ŒЏѓЏр ЗJAAH иVЫАЬ7gкМiБЉБ^­НŠ/яzo—#ЎмЊКщS№р˜‰“~АЬПž‡В gђЮdх]љќщѓ;v=42|Єуj™†@аТ•Ћœ•Уzп•;8Ў’OvЁА§чtЅ г$E>xћƒisІб[АŒbтњD‘ЄhкB‹XjqУВ eW.Зым%zn4>–8…КфHЇHHWєЩћЋ~Љ x! ~eМgkў9KШФЏŠЭкјсѕŸЫ‘цТV•Шэ‹ф§ тЭYhХ)јјјРЬ3Щzœ о_§~=Ўќ.—О$еАћ ДЬ/Љ_ћљЫй”ѓсп>Ќ2WЗ"Ž№щШ„МфЈУќЯ‚Ќ§мнЊШИщaSУlGЌEЇ€Я”ˆpГ'XЊ+ЙJїыMЅwLЂnатёЃЧ‡М` ЕSІJТ6?qп8Z§ИКtEЖЊTкаHbФ7’ђЋіќљ+=zї нqѕ<ŸREaƒлНqн”s"ћы7PЄТЇ 2fцфч˜nš6ЏГђ‰€\’Ќщ›Џ§p ЩГВП3˜~ц?Ж#жн†"э2#œ‹€Ў\§ЌМ>њŽЉњŽYМWšЋБƒЯMее4x.FЃмXюѕG>—P6ЩќD"=HWћж|LФ0GКЂ/іё3,В гЉQU[Џбџ"–BУ) ржб$&цlUЁџэ_П‘пdаЂќ_П)+<œН?vyЌW;/ь яйOхc—јйV>uЙ;kжŒЦщ‹Ѕ#ѕn5iсtДpхфЙrЙc.™сЌ+Иђš•7јт Ž ёЋЌ+oягОђ_ѕFдыДI ШOtђы“QУЂ?K)_HtEј‹}tЯбјц g…‰/дЈЂбDhѕЧV4!8ˆіЌI?.п™ыЦr_rщ ‹ЃВr|" 7ъ zЈI‚ EIXšГ6Vз˜=#ГrЙЃАeГGGнkœЙBШгКЖ\{o1ГЖЇ‘КЊђЙrнЌ^onс >уn^хўSуЪm њƒžыјзяљЪ5гф^В­Ф8 Іˆ@@ч<ик-g6k€@в‹EЎV~Жлђ*ƒ{ЭЪЭэКъzе=вЙ@ЅБ№а™[w„˜єYЦe4№v›0˜о\КХњбXhсЪUЮЪбХъ„‘HоlНйXНfzюŽРьПЬžГЄБ~(Л{ч™}і# …+Wљ\9 ˜иљXf‹РСЫ-œfлCж1Ї"рfOА8ЕoLC€!Рh!hсЪUЮЪ[тЌ› †CРщhсЪЩ{žN7)d0 ‚€Ў\§ЌY„№Hb§sёвBnxхШrt0Œnh$3Щm`УЦm/M2L‹лžjŸ`iœ,Bјœаu ›а…aІ2иаec@=тЪ‹s‹ ‹ …Fœ:s Х>ў}ќFћ љBк)Y„D8qцЧ… 3кЙаёжУЌa:й€s/qSбж(Ў~|ь‚БЖьKоЇрЪ!яx!(iиРжZЦaд‹lдЁз+Я„@ЃИrоVВ|ŠV;žEШЖA:I!LєIлЬ,Xо653еїQ>єЁ=‡FŽу_Š-§Б4.*nзЩ]X…Ћўњ4їonРГтзХcсiлСaЉ[$aiщL–EЈЅ€FьЃніDR7лНоŽ8œEHЙ…‚Т‹_d’u-$3Г \ј-ТjsЋуV“еЈСЬјШјˆщ†ѓУУУн;e,ЫkŽЅn‘CІ%ѓYЁ–|ѕЛяцЪ9n_ъ>сЎІ'ŽgB+˜}г]дЈ0бdf–AC!5jќє ^Ї?š{tСё‚AУи~d;ЇЦBчH7ујсу"§ДШRЗP(A`Y„(Œp:`сЬcу‚ъšЫЏEžfыШ,BuжЖ5swu–un!JьG~Sˆ• §Ь,V55šћєY;-˜ЙŸф.\П№ЃПё‰w/ф_ˆ_fёйтЫ7ž/<5oљŠђр!uЫіwЖoIнЂПOџњЊз>3—g[ЫFРС,BV№jžЪ,Bl(ZЁkОTэ pvЭ2Бrл\BТ–Я"$дІLKffС„Лг#ŽхУДўї§ЕячЮ‡ЄJœ>oжв7W=Л ГrФ^†?<\Ў –КE™–ЬgY„ZђеoьО7b€Ѕ!І;œEH}Ѓr™YžўєњЅkF…ђap\;8DmUчЉуу+Иџ™’ЂаKнЂN‹=ХВЕиKЏAЧeVŽчЧўMb]7№ыщцђŽeЊGПрД\f–Aƒв–І й!c†ЄЬO4””c[˜ЖpэЂЕˆЬ`FЯЇњHЂD’Ѕn!84ћ#юЪ>B!И1–EЈйver!јЌi†€,‹:-ўЫ"дт‡ ) РВ5…ЋфF66J€Eд?ЕkАА,B"рXБ#РВЕр‹пЎkсЪUЎŒШВ5фВ:Э–EЈ™^иЦъ–OА`VоXц3Н †C€! |ЫЅЧ=†п7пsЮщЧЮSЁ™щd0-Žы!ќ Г>Сђћяˆ№œГшCя3ђ/uжМUЏй‘Къ[a’ †C i!01Мы…Ћ•Ÿэц—ќУf А4’G іужхћЧ6†C€!аАКrФUЉП˜Y7XГЪК§М B}ГЂЛёћь[&њfaъў“ nWЫŠПџўvвЂжвж–64вѕUVЋ|VMЧпJ%‡ўІFXK˜У`^У"#ЄІЭЕЕЌOАИЩЌмАП‡0вНЕ’‡oŠЙ$Vџіпщ=єКšо˜яъЙ{9Wе™+““g|†@#!pЯ=o;Ўz Ф)Њ4ІukньWy_7џЈƒЊœ^&y.ц%ЇнЙ#;ЭйьплЇ‡пЇPЏТaC}^šвgH Џяƒ^еџсŠ‹+Г?)zkU>їџъT§jŸyo<сыЫч?hиEЗКrrЗГŽz'ьŠw+d трŸх6§Cm-gЭwЭUU(™џ i\]љZrк\ЧoиUtНЌe ˜^КRЙ:%хЎОоѓтішц5ђ/9"€šтѕxБЋ——ч‡K ЮEнqy&САУ}aфжm2SНџЫ?чїюІo•­mЄKѓЮк‘™;Ю­HЭџсGSзНпJ \О,АG7яI“­Ы~LŒъБhaрГC>МјCДВ‘ g­7™•ѓЖb%л]Ё|•ЊŸ*Ьиoўb6Uёў:нWнэHЈя‘aŽŒъtAьїЗОЉ щЭИ7ž§ћПпИT<-zFсo.! ЂтЂў(і›Цй;>jэmљў L‹кк( „…­эБKэьWњ”\FЌѕ|WЁFkŒРœиCјQXX‰vqдщ8plm^_Bc˜aАс"bH`œ*8E Jƒ#7ЬˆАЄ*rJx„’’K‹‹­Ё‰a#Лцi6П§шWaЃЦZFд_jђёюЪ.*QІхь$]лžНМС7џњ§дpџ—3•ЯГ__oх†p–FŒ”геГ5З;[Цбзж!Ж‘’ЄТSЕ•Ќ~`GV0jб+Hи‘фпяУ5k 8oТ4МфŠщхќЈ{Б7еœзЏљќшœ.™(Г„е•ЛQЌм6§8Š[ЇЖHСсГTЙЙŠ'8="-z2я{ЏіџуЧл]}М=і c;F<]R.Уъ”РsчŒ|з<ѓaФ8йŒвЖеёбэпяУ6mжПЕьXdTяїж[n+Щ>НМЛѕкBОібЪђп”V^ЋдŠВкAƒ}яџaфф§~zm|ЏN‹Ж2ŽІ`.Ђn{aЌ/[‡Юы1$0ќо|ї­t†‚вр+IU"+рЛ1ќђП1Жё^џaVfˆp:Dfч‡СO №™ЕП}ћѕKWфЯ­ ЊрдР>8?^"RЅPTЖS4nсцічУлЮœjyК.tLЏvфw@§оFŒ”4щ…ЦВъ“пи§“BdЇЄrЪ„†ыXН"pиаЎјRА(NzЩ:ѕ&’yŽгXVIŠољ~№Иё9Їэ66MЋ+wЃYЙ§ˆ0юЈг=дNзVЇяtŸўЉиЙОИžmѕ|?љ0’О­‡tНЇїЈ"чЬђ“Љм0cŸѓ†ФЌJT…%цуЗЂuяnрЛ ўK9ђыѓо1YyЄ•yo#­ЬSlEYэЂЧ 6ы~КAЂlдFhŒ@zкHЌбпЧџCД‹#hpди` џ0ƒ€ќœX~ЪmЪуAЊщбМу^œt c5e5šciбЛЕ'~Ы–•šюќл|фPЩШ–шРE|€ZE&­Тi,=Ee;mЧэЪšРдєiOъљљЭКЗyѓD›mгФ0bЄH˜ƒЧј}ђЉ?)Ј[;щ)[x†‡эЏМSНsW0ОAџї~Q@МgяЕыјQёњ|ўZcлѓI№„— GОtдC•лХЪk:(ˆФм…Чaўp­]СџкШЬПѕоzЛзН<Џч}œWK/љEс™“oчš![ћ3G8vy-ђО„W%тО fdУœB(ЏM‹тVЎY?!T†ѕЊ-)­ЉћџDѕXбУтИ.Гg‰Їcr6бŸе?дŒ2<$…ыjTљvцGцХя­1Y: X”t ‘м'љбЙГЦљKŽиgЧLœк\ЏЖуіф1уБ”р‡ПwћwqЪhф?ЈєЋBЙѕк)йСUЋŒŸљВџУ‡Kсяво•ОKiл4љœТHIЕЦїЈМ]’gdŠќ@П>гfsэ/ЩЂўчџрgъФ IЩcНvJжТ/—Чѓ‹йлxЋzыіBI1[црСМaљ2Бц1cќ ћ]БmˆpфќмТЎС‰7`"˜x:ЗСŸє З@…~\Ў‰†ё­ЎмMfх$’‰vх DWoЗНv‘=&ц'oU§p›3Vqx”›žдAџL§sѕOС­п+;+ЧЌp?ёDз[eГNмЛЏЮ˜љђ!|п~’5цТ…ШSЇјСM7DЛpъ№СёWЮOћщJST†o­Ь_Мфи§jZ9љщОRzJDиЅVT—› lr‹У $–ПЕђXee5žN#350ыrЊ„P@џœи/ D‹хзgНќЪРUk--nпV”ВrЄљ_o|y(ђлгЦ ‘М?Тіщ~ˆF„+нŸЏДъЕS(,ЄSж|‹ˆoяО>[2Ф] ХD41ьяЙu>­DцЉ@ŸЮžŸюmHtEд -ЪљэлFтщƒYЏ~{fиA ц‡ŒСЃœНтžЖm ŸЊuœpї5XььЁљўжІюїоhЋПЁПЗ O–ыюхorbšЂ#ŽњŸ~С НjЭљiѕjЦ3R)–^ЋьњШ–z…™CР^љ5mo[ŽШcjљѓЯгр№Œœ”#Њъ­k2Эжщ<|p§?ўQћЃ@БNПО>g "ёїР[l_ZГvШьOшкН-К§ЈЈВЩœ­Сb5ИЩЌм1 uџИгё\GЮдЏFљўџkjпЊЂэНІЖњ{+ражaЎоVЎУўр•oхŸее\~1rтўЌЮќuІо&Щp%ХоЈір )CиYАШŽ†”ПZ\ђІ~ЃЂЄ мъЪ›ХЌ\ЁЇЊNСq3п­ )&ф0 {PСсfнTAЧјЇeиж`ў­Iž`aG†C€!РpЈы&„ѕЖчЅпчˆЮБ"C€!Р`И'I/IЇžh™yЗђфЯ[Яl^Нyџж”ЧG‡Mš7нz‚QЭ5ƒAхhi.А~8 -\9fЧкxs… D ЎXі›Ё PгQГљWU/ЁЉR':”m8“w&ѓ(яЪчOŸпБыЁ‘сuV€Ш2’!Р`ˆа"РЂЗє икют^K—?нг;=Wœйšю„iўеdІ‹ QЙZbЧъЭ! ъ”›T}ЇlђcGBAУNCФSA]fM)НXJ˜>>0sСLЏ^иA XЋ•§ucА(љТд žAигІѓЏf^n0ш0 4=›џuў”aS00e[ЧЇgЁ-5>5Ј{PHПœMќw<нlG=Хˆ‹€Ўмщ1kЅЋe"Ђ Nм7)ХwкLФƒƒяuчJђ• K.dДц—ТъЛUЕW‘ ;вw\<{!ѓHІс‚AЇгmJнђcGсЏц‚S{3 Х‡ŸžД •SЭъG­Тˆ–€€МЫq^яЕœ•Ыe "6Ж§ƒч=xЧЌœdq‹И:1лz<ЇЫ]2r30н–>]ЗWЏn—Ю]ђ’ЯВт‘^НъЋСЮЛ.>эЅFтpeF-6ypееејс…be%ŸБDrѓыэЗrыJœBа|Хk+іьŠuy ŽrzЪС‘Fѕ0Ђ™! E€EгXyCЏЯФ3k2<~9§3ВƒNћУЁдЛ†ЄЛ†ўй–DˆUwёјJM> ›VB_ M™—‚6&кЅ?–тЮ'iпЎ•ёZ§K< ѕўъ•З*Бƒѕт(›Уэ>&mY"$игЇЁHLьнЗwіІlxs\ЭД„4jЗh0`”^+Еќ2ћ7•ВУЧе(ЧWArzZnЄQFДLšеЌœd ВНЪˆ _А‰ь§4ФK~k­ѓjуЩчЫђрМt:мб‚ЖЧ=*Ьвžœ {…ЯЊћbьэВы{tŽЕxџШWЇO9 ЁpсO^Wн-xB№Э’›QCx%cЂУи“ˆuсqгRдыQi‰iaљЋ6"tŠФаo/H~#9#9ЃKз.чL<˜s№EƒahааФЩ‰—/_юоГћђїŠ:9}оt<Сц†№KфЋ‘G?;JфFšЈ:+Ж4ДXN‹DЈЕGжЎvgŽšй 9u|Кgсf2™Ъn”m?КЬ„***6м(`4C€!РабrZЭjV.BгЎ§Цѕ;ш*3nЪLЫEmГ"C€!Рац+wzŒўъ•Ћeee^жC€!РЈвв6+Џ&*Бїћ:ЯP># †€k`ГrзтЯZg0Ž"рылU WnWЬкб> ъЛЊ] Œd0Z  …+wzЬZ%0ŽДЋОni)0Њк№9oˆ€ъ š=}gМЅвR&Ц`0B@ WюЊйБ#эЊЏЛ7KЗ$Ц7kПblЄя’~‹_сїх>3цrљп8tyœXйКфž•жЇЪ%жg;ЯhnрЖЇЎ\§ зЙ;вЎњК}<Л> гЕспвюуЇѓiУљ=b6{˜Ћ<ИЮOњЌHwnŸœ ­ЉИзІbЇ. SСpі‹4„ъgхЈЏѓАЌeМУЖЎK-T@†ЪPBA•Eg‹КѕшFSV‘Г"=є ЊОnб:SЙiњтщ”у‹šh:эТYВƒюЦdГrщ+BfхrЧКuЊ‰ч™ЕYъ дSтѓХtі!B”PЈS|Жxnш\D‚ўр№ђлжф5ТмrihЈf=ФC’ЯŸ е)’Ы`нstЙбjеOIU$kP“5I˜O‡$ыё}иї‘Ч9іљ1(СБџРўКЕIkч.ž+ВAуbьЪXГЩьўlxЇ.кг”5v.Т]ЧЄMIДSBѓд#ЃЌGЈSH#PўєГO 9 z|ѕ]КqщўЌ:sд•уSЕюЏS=ЮДSюLhtлгŽЎSбrЄ]RWю(43g“чѓ~ЦеoёМЁ~ЦW"э›’ЃŸŒІЬ’ž‚МКšd4”ЁFмZ rќ&ЁS%Ю(ї'иЌмбk„ИHрГпУМžРОцНэVˆь3HFSГ!+ ­/—ŒІЊŠѓдaКь П†‡оЈМˆKCCХTъЁђ Јg”Ыe#J”#Ќ+ЄВ&б&„ђ|ВžZ|а/rЪ?РПЂЂЪihлFчћ˜/aZП]jїB=каИ7‹ќAИ›8kђжЩЏM&эцlЫYПt}ъžt[?N{­5z${Š›Уe—Ўјїхѓb“гУЇ7њ‘Oo„oа”Й)И-Aфхј8Kэo*:p&mrЧšo#[эШьигДiЗј"7uV%ьLNђ р”‹’нс“б$ЄYђХМyњ KЌ\.ЭТД…ˆД"ФЉ1ŸЄц#K’‘rЙ44TLЅ*/$фrйˆхЋi{Г&ѕд/jp‹‡[AПЈЊ‰/O\ікВ й(Gc‚К0Bр‹Рк˜чЂnџR5`PЏдЬTŸ‡-бГДљќїє„AЈ‘‡џї0ТljQЃ*mmЫџ&Пзрє†АœžЁЃ†&ЮJМќ§eќТ'ЭŽ$Ч˜Я5jpіЫЭiміdY„НFУ*Й}9w­8яˆ—rБоЦ№ ]мўѕz%[Ž\q‘-ЇЫдгє…щѕx(8*И‘є3ЕZ" Ь"Єб‹ћкЬŽmAдЌніо\ћџВЖЏ\ДЪ ЈЭЫ7уЧ/žЧƒtУЧœa$CРi?r\(wš^ІШеhtлгЎgДˆ‰6эюмюU~ЎДќлт )ќ,хЂ\я:vэ>8 НННщяY9aЦg4 ќкУ“? ЋЫjЙ9ZXмfC€!Рhr,0ž=СвфЎ 3˜!Р`дA€ХЪыРС †C ‰"РfхMєТ1Г †€n{jі$‰шТ:Н]CњЁЭё›E­иUЄњкU‹ Зииh WЙёњШfхv`ЋћƒТLДй#а0члАZЭLжAhVo{ч 9uцŠ}ќћј–^ђg{Lь!ЌЂ@ЏАІтз лSјмЊ|Н…~ТUЪлЖХ8#аА+еАZw5зДаh‘[<пэєX‡$а№уcŒЕ=Е/yŸ‚+‡|ПЖ•$8ІЃfѓЏvЏ–%ЁHŠE>сдЁK‰0C€!РF@‹‹6~мв?ЌШjЛKї]Ь§tOkь”[œйšю„‰fГЌ+w$Ћm”MњН B2YRўзљS†M ъёTMzGka bс-,Vв/i’„ЗKТГŒfˆашЖЇ6o]ZњіŽГнE§–*Т‰ћ&ЅјN› ‚xpHљEнЙ’|хТ’ ­ѓQDЯ*ЉХЛqЪСЌ:R1^SB@2YвŠY+ЂуЃ^ЩCZŒ‚я D§‘Kѓ$9–DuY‘! B YХЪIпіЅZѓ„36N"ф"BAT„Їœ[Ц[ц;ІьœlNQƒYuhsŒhЂH&Kвыѕ&Ѓ Kы -F\JœЈkrižд%‘BVlЩhсЪ5‹•з\HѓиИ КW”‰„ЧК2м ую|š&11'{ю;№YnU•Yй•“Ќ:VђИJfеБVdTгD@ђВ"ХФіwЖoIнЂПOџњЊз‘ЃYи9Й4OъЧ’PЃ[2нід2VŽˆфFlmХрФy^уФщФ<‹[Фељкжу9X:<#7C˜MZŽq[H1БrыJєAѓЏ­@R!aяIš'’N˜ц‰%!JŒV‰€З=5•ЋьЗиФ3k2<~9§3ВƒNћУЁдЛ†ЄЛ†ўйбDМъ.&јвiАЬЊccc4јД;зјt<ќіoqфв<Щ%q}Vfд"€лžђ€Z!Чџj6+Чѓуџ&‘R|х^lт{џ„ udk­ѓjуЉkэ­ѓрМtКзo@луfiOЮ9˜UЪщƒ „`O+_В&qvhааФЩ‰—/_юоГћђїŠl–Kѓ$7–DеY‘! D@‹EnЕ•[{gWЛ3GЭьt'xrk§Ъd2•н(л~t;J /&TTTl<ИQ$УŠ †C@cD‹м6ЋYЙJЛ~ l3цrљп8t…œX™>ЗюDѕЊrIЃѕZХЭ6+—ОІъgх}<Л> гЕё„Ђ>~:Ÿ6œп#fГ‡ЙЪƒыќЄЯŠti§.ф6їкTьtсЅdM3ЭэmOбuU?ГUDбЎК:оc3осNž1%>SэѓЈйtWwТшЃїЦ;GВKœ“Zѕ=Rј_•њЉЇ–“—уЋЋВВ2fD жЅrD‰š†${Q]Y’’їyž^Ї3~вœIDUQ^ўћ?:ŸwЋk >8fIŒW;/лV$uBЌєЧвїоzяєёгэюгG/ž=rмH0ЅЦДЋNŸ:zР ^БЩѓЩЂ."Еr:…br2h7.*nзЩ]rігŠDХ\Ž/lДЉш„ЭX”xџV~Yљёбa“цMіТh6+—О ъgх7ЫЋoўZM–ёњђ wсŸ\zІyюrюФ/НWer/?.н[WpёЇŸyЇЗŸЙ6+™8]­­BЩ^Є$ІрЕaУw†ьуй7~КqhЯ!RqзЦў:уЏ†bCцбLНЗ~щœЅЖ С‘д —7!юљ ЯЮвr7aytRwщДјЧžьo(4`l@џЅ/лЁSдКdЛ)œ^Ч]§К$ГfёхNUWWЇОaЭ&Cч2” еiЋш%D' ћLPз „Щ X› ЖхD<а9€чШ$ЉQЅgЇ‰oўffа”в‹ЅD?ŽД.hлL7ф,ŽB1Щє:TЁ-Aы $й љSКŒД;шІН(тHЋ 9XСъјСуa3ТшY‰МмМиФX,{‹ФЌФ€•YыАЮ­'иэМf$ЬРє\НaМН :№Й@TЎ~~хRйЄ™“<[{bЧєџЪљ+ъuЊ”<љѕЩОCњBићхкj*:||`ц‚™Xњ;хzфОFЗ=еЯp‹‚#экUW_›ENзZWQbZ5ЃrефЪ•SЛ28ЏкS ]УЉцrОЫЩќ*“ЮЖфу#у#ІG`vfИ`xИ{ЇŒeTИ №bЦ™yeyрШ%ЉЁТJzNdьЭ0~:xxђќdZ…’™n0ƒ€hj&™^‡ъQI@ fВ9љ9І›ІЭы6УEŽБяckŽаc^C oщ{ГЭтДxћM•љWЯKИьТМТ^OіRUПFшјбяаwЄŽУїYвЌ$њ50&`ЧЦеwЊБƒ@QНNU’wЙгЇN /є,ВŸџЂэ0eHDЮ>A79>юЌѓќљ+=zї ж‚МІТОhOk1оеЯpлGкЕЃЎ‡ЇЎ ‡X ЖЖо\ХЅjOOћ‚*|6™Н›ММјАiь’иЃ†ЃЪ8l?Вн"рЩEХЭџs8•]Kє€#—Є† +ш‘Ь‰ƒŠФYƒPŸщFN5CDа&„|РBТЪБЫccCg`MСi!qсqaSУx—}—л§ўn$]C•ЂМЂ SEрш@auщ€чвVІХ&ФЂ]хџњMd~шЌ]Д6эcо`•[ЙБќZЩЕьЏВ!Ÿ–”†NbZ"h “Бœџ:яв­ О€U*T)VtЖЈ[n˜ђ хEігK†ЈњКEыLхІщ‹љPВ_ЈŠвnЎѓЗ§FAa{MiG\BАЗ=ea'ГrЙcнjеФѓL™ФuхХ%>›LgТЅ„XHP.>[<7t.fgA pxљэrzR˜ћB.I VаCІЗФЯyЩN‘L70ћшžЃсhЈZQЏ*‘Мd‘оЪ>шd|і}фёGŽ}~ 4ާі'а­MZ;wё\I%š1cWЦšMц`џр№gУ;uщдоЇНАщЂгEИ‹˜Д)‰vJxVŽnѕЧVјn˜иДA ‡HІЬ]::|єсk‡Бƒ@QNCУј”?§ьгТК іћ>ъЛtув§Yu&цЈ+ЧЇjн_'№Чяb0ˆіlEw‚ХЪЅ/™•Ы…ur6y>яg\§Яъg|%вО)9juёiO“ШP‚WчС!ŒЮ‡G2cтєyуІŽУm.Ьz№–tЕ#IjH­:jkЉдS+^ч/2нф~Ÿ ,{MHЇŽ„S ИщGєЁ#шЁeкГm'ш›vFМA˜—Я^ž:j*љŽсkyФЃФŒФƒ%‘6Јуся’эXюБ•г#Q еђT§эеK:s:яў}ќFЫ.yбcЂeэJaEIzЭ€5ПVHžbL†C€!рB<4hГcmю@Т]0жЖGћ’ї)ИrШї›a[I‚c:j6џjїjYŠ‹!Р`8n{jуЧ-А`™Yл]dŸюiЪgЖІ;a"A„й\Ÿ+ПЫЅ/L ъ„я=Ы-[H[aDs@@юЂЫ№ЮхEЂ HђБnšdо(ŒЎЭЩ›‘о!ЄgжЅЂJQ|Б)ЅАм˜ˆЯŠЭf+џЧйю*.œИoRŠяД™ ˆG%ПЈ;W’Џ\Xr!Ѓu>ŠHрY…я Х Й{n\7хœШС~уњ ХйЩц€€мE—уЃЯЂМHIО\ОЇщ›Џ§p-ѓHfіwгЯ&ЊDўзљѓТцНОj![AEK3ІЕpхšЮЪ9n_ъ>сNvдНeМe,+Щў(SЅžУйћ‘щ)oАƒ@*•™XгE@юЂЫёбS’Щ2HВ­ƒD’|OўOњѓыЗіDоЈу‡Ќrwж Ж^р“Ф=„|Њk_[БњЃе‡‹Й5]™х htлSГXyMWЭcу‚ъі™‰„ЧК2м ую|šШ/ GLЬ‰РСžћ|–[Ueц$‚№"|ёКБœf‡Ё)o$фЋ! wбхјшКм ‘ф#пгЦхЯžЧъС%PЉ‘| љ”7u“й6Ъ8ЭЙ‹.ЧG—ы ’кМHr|ф{šЕєЭUЯЎТьйШ†?lY;“OUflB‘с3f|ŒЮЫ;lПО6лš=ніФ\и§ЁœxfM†чб/ЇFvаi8”zзtза?;šи_u|ЙДV–."%Ÿђцv%іДХi(Кп™…" wбхјhN2/’_.пгш у1ЦјŒEwЊБN2эRМf|’‘ћanЮёНP*Уˆf†@Гš•уљёƒ“HЉОђe+иФ іў ъШжZчеЦSзк[чСyщtИ{ l{T˜ыёфŸ(1 ЫеB~DшЖb­2ђЭуЌмE—уЃзry‘$љrљžЬssrzдА(юnеД8kr%ш‡7Oћ4-v|Ќљ?fˆ5œY/аb‘[mcхжЮкеюЬQ3;нп žмZП†2™Le7ЪЖнŽRТ‹ nЩА"CР.№0"Ы‹dbLиб"ЗЭjV.ъ­]1њъwаHЋˆ]д +2 —# ХУˆЎŠ•;НнЋWЎ–••Йќš1 †€міdГr! ѕа{Пп[;ЭP‹ЎЈ‰‰и‡›•뇓f0nˆ€ЎмЎ˜Е1rUЛNьSХ`0ъE€хі”…H}œНД” UmјœW" Є:ЈfOпЦoЩъg' †€`Гri0еЯшїfщ–ФјfmЋ†ЂиHп%3ќПТя7Ъ}fЬхђП‘жЏ=зЙЩeœЋM{4X‹ ц„@3лS§ЬкіЂЊЏлбЧГы:]O(щуЇѓiУљ=b6{˜Ћ<ИЮOњЌHЗеэbŽі^Xћ] 1kž! 9ь iШеЯЪQ_чСћqlЦ;мЩ3ІФgЊ}5›юъN}єоxчЈО%ЮIe­Žк?>сH‹•••1#bЎ—\wDIуAKПЅ„цххППёЃѓyчѕїщГ$+ Т*LьiеЎеС$^NЦвИћЗђ/м›4ЏЮ;œД#jdhsBл ЁєЧвИЈИ]'wЉД“VЇ ‰”O­"„лœ%#jК%Еpх˜скхu=iW}н›хе7­&Ыx}y…ЛњO.=г|Ё„ук{щНЙ*“{љqgaЋ™žЬЕ™Ё/…І-MгЌEЛ"юLфуvmќшЏ3ўкg[ѓsfZцв9Kзe­ƒZЁя3lЫЙiЌГТ8iїPЖсLо™ЬЃМ+Ÿ?}~ЧЎ‡F†™ЄF†6'В ќТc…ƒ‡ !g'­ BД Л :EŠjls–ŒЄ-“ЉбmO—јq\QGкU_з№Mх†“мэ}уŽЙm7я •>œ^Ч]§К$ГfёхсU]]њFjPї ~!H"C?{” еiQ.Ї р 8& s_х.—oUKmPЅgЇ!тЉˆ Ў3ƒІ”^,Е­K9hE.kmHHˆВфTWV# ŽTЁSz­єјСуMnyП•Yы>3Ћ‹c2>#aІчДwт.—ЕywxtȘЯq>>0sСLЌ ‚Š “Б­E9'П>йwH_ыЗ“жQM8Ы~5zTе"ЕИэЉ>юь\ШiзЎКzЫкцœЎЕЎЂФДjFхЊЩ•+Їwep^ЕЇК†‰'RЭх|—“љU&’Ш(H’Sr9epЖ №bЦ™yey ёжєOSN~NцсЬ‚уj•єœ*РBЉ†тУOOžŸЌ`ZБ+k’(KŽЇ—чˆћ>оG›=цХ1рƒѓовїf-šE—чІ2Mˆ(Ь+ьѕd/‘С‡іъ?Є?œЕˆтљѓWzєюAј ЎžЗљP'cЋйТЙЫ>uz`€xсf‘ј~Хљ”!ЂЕхјД9gйЏFm”ніT?Уuю%qЄ];ъzxъкpњšHU[oЦЋ==Эиеї™†b–ФzеlH"SoEЙœ2ЈЛзC4@­0%­Z=ёIёp4˜W†Я?їэ9ZзіїЕBЂ[aоBє”ІXЊЩž2-dїцн–$ЈwЙняяЭЇљ(Ъ+Њ0UŽЄ­79?hж.Z;ѕ|‘хYяnx9BФ$E$—РЂф„QNrMдU#SЗ†ЕTtЖЈ[nД rBd'.^l>X’—Д5ѕФз'шђЙr|ЋvŽSc›Гd„э2šЭЪЅЧ™•ЫыжЉ&~œgЪ$ОЈ+/. sС ёјДM9eц†ЮE@‹с/П]NE„=^­ЏE›ЄZ=dR Е№цЪRH”C­B“`!Nљ>ьћШућќhћьOЌ]›ДvютЙТКM‹.:]„Л‹I›’h—‰§Чru~єєZВ;­ўи ‹“S кџБ•­˜лZ„ƒ@љгЯ>-<+g'd|ѕ]Кqщў,>p/мфјQc›Гd„&1Z WnЧ зЉФ‘vI]ЙЃаЬœMžЯћWПХѓ†њ_‰Дc>Nє№ЙfЪŒ„І_єрF'|<ШA‘Sfмдq†BfI‡Џ–sЕ|Š™R)ЕЕŠTъЉ—ўKхs0EiЙZЎа$XHиг#іlл zчІtКzљьхЉЃІтыŠ„кiРНV“[џ…П^9}qвЖ$лЌl;гЖN™3EЮњ^НК]:w‰œёH/qpЇдШШщ?ёе‰>}шY;ЉŒмZ ’|5Ж9K†ZШn{кwvтUбІ]Ф3˜§ц ьkилю зLеlH.Cыїюл;{S6М9вФЄ%Xљr9ehEB W“Яjkђ‰ЮЂЈRАЂ­?UH”c+ U’йsќќ+*Њ ™†ЖmtОYІЋјЂЂ;*‚ZтЮtЮЖœѕKзЇюIЗѕуљ_чыюгћѕѕйOБ:ъ§еqХБƒѕт(*i— ­%$pKЙьвџОў„)ggRlXФпЛ)sSp3ƒШЫёqж.льЃАGŒІд„xiЉqGfЧŽXЄMЛХЙЉГј)sr’W`Ї\”ьŸk&!-Ь? !GОyњ‹ЃDlСл ’пHЮHЮшвЕЫФ9цXžA–Ы)#R>}оt<СbQћjфбЯ,jЉ˜J=T^’PH”#)/™%’_žИьЕeВ7Hжr[&ua„ п7iѓљян ƒ&PГџяa>TХq§эЃПОђхлС‚o–мŒТgЁfћ$"јjd fk[ў7љН З‘хь:jhтЌФЫп_ЦЯ&Lp‰‰r|r–еиц,aЛ-œЦmO–EШб10Ќ’{а—ѓаqзŠѓŽx)ыm пХMр_пЈWВ) РЙ4ЁЩuSDXйцє…щѕx(8*XYŒmГС`+wТUkяЭЕџ/ЋхЂUN@с!ќјE$п kЩЇ.8ЯH†€8~фИ0PюL…л  …+з&fm Љ6эюмюU~ЎДќлт )|TЙhk$сtьк1|p8’;{{{гпГrТŒЯhјЕ'їфLУВZn‚n{j`q“о23 †@ГA@`aOА4›ЫЪ:Т`Д\илž-їкГž3Э +oNW“ѕ…!РhЁhсЪЕyОлі:Н]CњЁЭё›mRЯЁњЊЏТ$› ьт6•+еќьdБrћЎЉюіЩ3i†C€!  ЭъmЯтмтТЂB!pЇЮœBБПбтWЅЉX‰–5E)GŽX3`MХЏrg%љ*_Š‘Ыч"Љ“1 †€мідТ•уљnЇЧ:„н 4ќјиќњЈЂm_ђ>Wс~3D5Є‹ІЃfѓЏvЏ–%­Ћ.W!ŸK]AVb0hсЪЕёу–Ю5h™YRїг=|žˆЦн!ХтLОH6П(ž‰fГЌ+пБzѓ'ьЏњЅ*р…€ј•ёXšOЩ‘ОАnиiШJЯК]vН[ю в’ШъQШчBТJШ;ьЧ^­Ж яжЇiaъЛПрЯ™IMХ'ž\хЮнК'Є&””–dНГЕЌЄцЂЏOТ"Б&ƒжЂ#„rСP€Ў\ГY9пэџЈя{IјqпЄЎєЇOЗl|ќWЫ)x№ЯЛYmЎ6о2ЦмˆžU2_;вw\<{!ѓH& Ѕ%ЅmJн4gй|8ёq}D‘F zt^:Ќzˆ=їnЌcR/JхЩАЂ; @ѓ4СЌ (4ЉрkЫUоЗuпьˆйЯЄ}Т_t“пД\t:0eњђѓ/…еЭА мідТ•k:+чИ}Љжьb€clœDШE&2'2ЗŒЗЬwLй9йœЂšмЙi;гHц‡˜ј˜ЈсQpх’­ AIь€=XѕP$CђЙЄ}l]вV$РŠюƒђ4Ѕэо„ЄH0)vyЌpэЩиTK:'dDBŽщи•‚т[u.nб7E{Жяy'чїщГЄ)" …+зtVЮ™ЧЦеН|H„и <ж•су*Ÿ&ЦƒI,4КrАчОŸхVU™•]љѕ’ыЁƒB­:хqUHаƒ|.+gЎDОQоЋZFЙ yšhZ>ВЖmЂр‡Т\З2eWš(C›;ѕ’йвашЖЇ–ГrФ@$7bƒ№h+'Ю{№š9˜gq‹8qJ[лЊ\—КdфfѓБI)ВЯe§Ђ5I™Ћmѓ(жc']†ЩгDОwыЄRgТLœœ˜№З$Щt}ъt0)†€љйЃѓ вvVо@Л'žY3фЉмtkuѓ]$№сяr~Кчг3с[qЂъ.J’iАИа—BSцЅрW6>–˜jmw{bZ"ЊДoзЪxЭшѓАUЏ…|.Л7юFоЖp+вЅѕЛлTмkSБг…—’5Э А'X(uѕГrTгy№~›ёwђŒ)ё™jŸGЭІЛКFН7о9’]тœдвјиЈoТџЊбЏ&k’=rаUVVЦŒˆСgŽ(‘S.фгяaCе•е) )yŸчщuњё1у'Э™DЊЈщ5$%u‚_њcщ{oНwњјщvїщЃЯ9n$˜ЦRcк‚UЇO=`PЏифљЖkБ9оn\TмЎ“ЛфєPƒa6 …Ÿˆ‘cSб kБІёў­9 ЦG‡Mš'XтCибніT?Уu.ŽДЋОюЭђъ›ПV“eМОМТ]ј'—žižЛœ;qХKяСU™мЫ;сk#Y“ Х†ЬЃ™zo§в9KЌJВbцкLЌŠ#yЪЙLИ-ъЙЈц”ФМ6lјЮ}<ћЦO7э9DNЉьЕЄNИьИ qЯOxоpо–Л ЋоKЇХ?іdCЁћcњ/}y)5ƒŽД %…Ч  BAБйжr9ОлфъЪёUчЁlУ™М3™GsАŸШ;ƒ%цisnBh`Бk†ыD\iW}]У7•NrЗk<і;цЖнМ/Tњp>>zwѕы’ЬšХ[”;…UЛRпH ъв/$gSЫP‚TЇE,Т—љ ЎA “АР0lЫ‰x"$ sЯAŽ›xЋZ"ƒЃ*=; OEu ˜4KЈлжY“Bў’b“Њя№З ˆfi`"k’­*dMјЬ@,‹ХО‘5щ|?Љ$­+$ пVї є§ТДEk+ес`9Гу‡ЭрWХqЩ–—››‹еŒБƒ8u€˜ЁаыzэќрэŒшбЯ4,й—GЊ\ЙT6iц$Ќ‘‹гџ+чЏиЊrЄ]h;љѕЩОCњ‚pP­aMHчЬ\0KŸbЂdw\ХдшЖЇњЎspЄ]Лъъk3Ч!…PE‰iеŒЪU“+WN5юЪрМjO)t SHЄšЫљ.'ѓЋL:лRŒ˜й™с‚ссю2–ePс‚Т‹_dц•хCsмdЮ,8n™ФQIJzjRŠ?<ЉŽ„ЕMГ&СЬ@‘5 |L—Ш‘D’dMRPЅ&k”`ўž“ŸcКiкМn3\фˆћ>Жц=цХ1d-јї–О7kб,N‹и!щb=ЧЋч­_TTTMЏЉ0ˆуGПCпёeяГЄYIєk,`LРŽ;№UŠŠТZЖДНэт‹ѓєЉгФ =‹єд|ЉL‘ГAаMŽO„„;ы<ўJо=ˆЕ $ЏЉА/кгZŒwѕ3\чіп‘vэЈысЉkУ!–‚­­7WqЉкггО  ŸŒfя&’ vIьQУQeЖйn№фЂтf„џ9œЪЧ.ДdЋG!Ч ‘Wа#—ъˆњшЦЫšD› XhВžиаX’0dZH\x\ид0оeпхvПП;m7ПЬlQ^Q…Љ"pt АКЦ4ŸўmeZlB,кQўЏпD4 WTЙБќZЩЕьЏВyIiˆсU”LLHLЦrўыМKЗ.Ш5(jKXl@ЛEg‹Кѕш&ЪŒ!вC/Ђљы­3•›І/цCЩr|ЁI”vsXм”‚ТіšвŽИŠа"Рbз з‰@8в.Љ+wЌkd5ёуњ№ЕУиA (Ќ%Єж.хO?ћДJ=H?Нtув§Yu&цЈ+ЧЇjl“Ћ+Чo$РŸDЁDћ?ЖЂ ЙЁбmO;fИNEХ‘vI]ЙЃаЬœMžЯћWПХѓ†њ_‰ДoJŽZ]|кг4”реypЃѓЧс‘ Bр˜8}оИЉуp› Г|€%]-ФHŽRЋŽкZE*ѕдŠзљ‹ЌIЙпчТЫ^вЉ#Q_Y“VN_ŒьwjВ&сІб‡Ž _„F”iЯЖ wnкёra^>{yъЈЉф;„Џх?А3–м[АЗуся’ЭЎ^зVтџіъеKXЄєщМѓ‘cžˆŠє”hpЛ'О:б'аКмП=rk‡Ъё›„Ю^НК]:w‰@ т™Ы!Ф\cšЭЪмЫ‹ `і{˜зиз<АЗн ‡‡ЩX–g-m% [яОНГ7eУ›WоЊLKАђЋЊ8OІЫž№kxш­V\ќ—фИс•оЎ”ЬqЃRP/ѕŒ$kяaяђЩсЮ'#Y“„U$idMZПt=В&йњqк„А"`с;RƒњENљјWTT2 mлш|ѓ%LыЗKmр^ЈGїfqЩpсђчoMо:љЕЩЄ]{{-ДvдФQˆе DŽ–Ѓ-_QнzuГЦЪгw HkQ$м.к*ЛtХПЏПВ§Ињ )sSpƒШЫёqЖ^лфъЪё[чАаQяЏоˆЫŠФЈG‘>КЩБці"ыШЌ\ЈG™.ОШMХO™““М8хЂЄЊЈзЃрЉУќУєїщ#_‰<§…%VОрэЩo$g$gtщкeтœ‰s’ъ гЎ]Д!LyўGОHyН9nTъЉ%EГ&ѕд/jp‹‡›@ПЈI_žИьЕeВ7PŽЦuI„Р €Е1ЯEнўЅ zЇfІвt€*sEIъФSф7О>8 П2žєtСњыцЏлБfŠНz-]П”№…ЧЗ›џM~ЏСш d9=CG Mœ•xљћЫјС„/ZŒgвК_mruхј­3xB№Э’›QCјЧЂЦD‡ чъwЋэž›%%Я‡*8}івяsЩ2DœЕёЊ"ћЕi7`X%ї /чЁуЎчёR.Š,Д-тA:<>Œз1lOЕX\q‘-Wu<}aњC= Ž v•Ќ]„Y„ ІE€Х%~}гЌніо\ћџВbЎ\ДЪ ЈЭЫ7уЧ,"!xnјис‚3ŒdИ уGŽ х.Гƒ5\ні$ЯдgŒѓЯkгюЮэ^хчJЫП-šт‡>(х:йБkGќvцээMŸЪ 3>C@№ыO iгkХAДА8h"ЋЮ`0"\`бfv,ъ'ŠЎjзжЦa0Š‹•7*МL9C€!Ра-\ЙЋfЧЎjW‹ыЦк`0ЕрЖЇG-нˆ5{’Dд{лMй,в ,ЦeXgђFГь†[ ЏХ†M  нзТ•cvlЏWUАX§)Лк…п’БZAљД˜yЮѕцЄ-ісTРœrlXК љ†ЕЋб"З.ёу@ЄэVЦпƒ§Уsм=uЗzёХа'{HO~ RМb^o"Р^~Q ”ŠсŠЛЁUъMRАп‘a‰СёD„‚rѕ2IѕАXЙVљЦп/™~/1џЎ$T{Ѓ{ц‰Ќпg]2Ѕі<ћЫhh–ТЉE ЉК“ZИђЬŽUлЏ$и€v?ќяп? уЗЁјїЃ%Њ<ИШ,ЋЭЏAz˜_‹ƒпюrщ SƒzaЧkаЖЋZ'/w'N\:>IDATЙЭЩ|^ЬыБўЊb%[,WЃ…?`ё,d +mR>#\‚Йp8 Џ фЕ†€( ’­Сf€ВъЌIuл,Nрч?eиЄBц&aв2[aЂGIх” Bd<^KvчNЖиЖ{лS|•#џчžё9ї€ьwЯЎї єЙЇ‡ї=]u<ЇaRљмИnЪ9‘ƒ§Цѕ(Ъщй‘Ољкз2dfg0§l‚иKsџКѕэ­TўƒД"gFвѕя)Ÿ.A€„ ШO1b€ТЕeA’4X˜JR@Ш”ЬтГVDЧGМ’‡DпYRGI лк/д/ЄEЦcСє&”ТIи‘цMГYЙвѕЕ+РBё Б&Ѕ @Š‡ГїЧ.ч3р№ГѕхБШь#з^юЮЩ^pж$ ‹Р@Ќ•H&цX>єЬ‘уc'•ЋЮј.G@сZ“,H–1-=„ ъэ В8ХО5™F0ZbтcОиїЉЂзыMFѓA"šџSNИоVˆ€­ёHсД{ѓnЫOЬšNcЃљ‘щ)œTvЊ™‰itлгUЯw“vхŽ’зR`9dg€…ќV f6›c“-k^7–лfР‘lZ˜Kˆ МєъK[Sј‰9ВєNœ3ЯщУ6wE@сZЋТ PѕvQ.‹Ry ЋrдА(Xl!zф„ыm…ияЮ)œTvЊљ‰iё0bbжNšД+w”l№ ‘П#Р"ј§їњуцфЋАh>CPЉ‘|ј 8usƒ …љЄ?eIЪ8|р†” ˆЁŸЩПїv"х3Т PИжuЦ@m$Ѕ.д$"пм’OCaЉњŒм [яT+ЗЎ„fјёЏ­@#аrТJЮINяЏлˆЊHсД`е"NR8ጘмH~(Ј#œˆ€зЮЪK§,’ !CŸчЖ%•Š’b`Žž0Й~јь3wЊБц-‹Žў`нбsЃizŠЎE@”2IсZKfAR0^.­"—Х‰OВsOшУoџЖˆЫ ‹ьЗHлќ‘4оmS8й˜п"ьmOёeF€EчС!Ё'Xtžœ—N,`o™Я”˜†еkQqDш…l‘˜qsr:~swЋІХ о,ѕрКїь‚$2і6ЭфШWЇO9 ЙиЩмSсZЫeA’ГP.•—Ыт44hhтфФЫ—/wяй}љ{ ‰МœАШ~Њ\DШяђN";[xQ‹En1+wIŒХЎvЩлžx?–Iўж ž+їѕфщmЯzЧ_BtТѓуžЧ/йz%™€{"аЄу MкxїЮВJДШmѓ•лœW ФЎ"8n—ц† убрВkeЬ7 =V‹!аrаТ•л5;v"єvЕ‹ѕU0яVhН1`QhЇ0!ъв­KвІ$e1v–!Р`hсЪ]]СЅЕЗ]эЕђјcwџ•ёi*g›єulвЦ7•тИьmOЧ1d †€ыатaD{gЧЮBХUэ:Ы~І‡!Р`ЈA EМэљџлЛ (ЎtнTЌЂQ7rWбфт &ЫЪ5ц17Ђь&ˆz% Ћcб(™H5Ђ!Ф@%‚˜3йШЈЙы#ЕqЉм˜G#ЋБєf-uЫЙ"=uIyџц =MїtOЯЃ{І›ПЋk8џќч?п9s8ѓїщѓ)eDа5ш+ЗwŸ<… 4gКЎGяИ5ааH-ІrЗv’јwwыuЩ"фCлP"ШрџŒ@юБmјЖЇ“іoёѓЂЗИ8ƒ†ў”ЧЇ”эfПр.СїЮ}Ў(­0—šгГ/B.'ЩpУEр§ј ,”Бп›q‡ЦфNЫ…3ММQ"0Ѓ.атБ'ЌŽ]кЁ†€gѕŽлJ n…Ж…†вжzЋŒАЅЮRИБ>‰ trC”–б€Yˆ@р#€,Bкї‘F=§Е“ФГzoЕЅо:>•љЏ‡˜їу˜Ѓ™7~­АcЬe…–і0#gœT–’™6<Œ;}д™ ІщђЃ >I€5Z‚1 D<т‚ В‰aСхрЊ\ˆUPœ%ш‘Oш?ЖвsлшЌ єsџJHФ kў†eФЌoPтЃ]ЭЩž9 ч@XB&ыт=р~WнШ" М]њіВW–с)žкc-ІrЯVЧоcсYНЗ.dнњ.ѕжчOœЩЇШ­м’иIБ™аАЭqD-) ‘Ÿњтдє™ьщ†№ aHQЎ%uВ!‹ПЊF=ннIт+8HНRŸRЕДW8ш4СiNЎ[[ЄФ…щ9/х,ЙєЧкЃ'EsyЭЛ›Џ]Н–0ЪёœRrŠx'йrЂа-кГ9 ъл‰,BяМўЮŽђ@%˜П1ђЃ“A†А‰…)В!!8шэј_ŽO˜<јч@ЧжЕ[‹ЫŠe•aІZє ЕєГz=[{oЉWъгЉўЇЧt„ 5…™ЈЛBЉЕo95ТDбLЇSaч‰ƒЈЂэE%Y%ежjЛ@u ё€х+ юKђХI‹aвЧпЁЮ1дg*В!‹ПFЎF==лIт=(длК,єаТ ЦйAЏўGађИ ДЈ )сA“яuЫ`>L}:'HЉ#ЭGbˆсцqH„pЬФHwK- dт6bq­Ы lёWхnuоCл;ТBM#‡P#{WхА$gWх=юЌЪ{ыƒ*­ [IеюјpQс"ГŸ™]ЗЕЙАш+*`сA!}uŸСЌE!{‡Ё  чЏMГПX„ 6р`s`Ѓ!YЅъБэК6^€+З™Я"ЄбcOџњЪ•C’0eЛ%Тˆ"€Z8XШэ[ыnНђ,Bкл5"ˆ" xьЉХTЎ‹U9žzЈdФ ŒшзЛеЕёt–~‹hёŠ;I|ЈПъѕ‰ёЈ@хh1•ыbUЎ2”DD  @nЯ€ъ4@@_Й8иBбХPнM1!еMб!гMQžWНР!Š!DРрж@ Ўƒ:5zьщюN_!чVН•ЙЕ.Y„4~4Šп[_ду.8імEЬяђш+Зw,НЩ4?юΘуoя‚н„`ш“;ilвŠљ+ЄN-”DA?7№бРА ПаBy“dьїfь‹PЦ§2Ъх­Т\Яаb*їзNъ…I|љМЌЌyЉC@їьн3|дpђ (И\ф!†бЗѕkыУё6ф–Ш c."`TEHћžешБЇ.vА€gцёŸYў›#OtZў}VDŸšїдеKWнz(в/8wц,лвД2ќЮ&ыю“[Ю№жНжŒ‡2’F',Mzњтщ‹ЄИЭf+Ё~ЬŠ›<5œ<_9†UB@м_2н,B*ѕЊхРUЙ pАмjМЕyз›­CТЉя-l”П*ч “иКl U cюb2Д2b%ф'-Yк‹sл>kЋо_mm?іpJт†•ˆ,˜ћОиWџзz—Тѕї—LwCядZПяПїu\юЈ1“#лО>]}ДОхR‹›*Nѕ]§'ѕжяЌ4Mз”зRы—­Я*Ь:|ЎЅТRбі…}H8л/UЏРј`S№ДYгšпoцф!X-ž§ЃЧG—э,§0Џ~§ўЖ§–vmFЏ„Sу3r2ъЖU!моšНE‹ˆ*dRЉЯХ4zьщСNŸ7UЁBиЏ7ƒЇхЁХПN}&.Т {ZИЕЙ=№›ј№ФO–Ђ•пјІš&˜Э;ЏvVWp:Ќ4\КTєWЏЉ€pUЌqш‘’Чtп" ш/Љю†JЁwz{‰эІФ93\š!5BИ‚Љ‹R7НД &Yј‰vёзšз’,Аa{zcџg—иЯ)œ›{§zЗЕо6”ŽМ7’!?LЩ'ЄwМ@FUB@ ‹П|хnBяyRА_n€Ї…Кэ_?0m•эЏvS"ПЏ\Pзь?Эў№C@+њoЁi“гр…(+кRєїџ^ѕмYЙqёq\YТJCЖFp‰2PH M‹MЫŒЯŒ›7иЅ;_FfЙ€ ПЄКЧ=}”61-44”хtuuIЎ\кГi г<зœ4&ЁdYЩcI‘,”,,IˆLxkЭ[ыо~™$J ьч” RЦЯ_2гЪMK ф1Њ=№игШ,BnJX„†g—фWЏ^х–сїЄRџГŸКБ;аY„`-V0ЏрНжїмj5 k€ќoжяњTзЦkаЙ~Ќ‚Я"fйWюЪdE “8)Х9ЧyŽrvйhWэКкЬч2™_и–831аЬC{D@ĘЪСWј>–МъТ"s:ЛY,Ниd }%/ї%j]ЧiEŒŽHOяfКЇ%Oу8к Ќ@ƒs{К‹ВЦЇeЙkžSљ”ЬИfab€  _я Јkуdhc†=uДƒEаБD@|ˆ€Спіє!RЈ @@FWхм;h"€ ŠатБЇђgžtЫ>ънWњ>ѓEцЎїсі+"СUви`ŽпРaщ7шRБF=•ю`Бй`7хlІ7… Ьќу›Ю7ГщцЭbР™uGЈaіwЬФЙюІрwЩ]ФP^pXjВaЊPeUо~А§ыoОцcєй—ŸAєїБПNŽцЇѓУt~l№и8њоб”э IЇ#MTЙ•6qЄdkwGU!Еj:Гн.ЦWaxљэWп>yт$„'ХOZђЪ’ШЛ]Lњž=ІЧošљ…Рoђрaƒ˜Ÿтe‡Ѕ—œтjq{Т<>Гˆ=єRp5oh–™ЪAиvЖэJ~š T'/Юѓ’A8•"я?ѓ–—dЏ~k5ЄТA(­9TУюцХ"рќЉжКkпх+ьx!~A@•U9лxХІї‚щлщДnЯюџ'ВЌЮ Є~щŸ*ˆнqњbqЖ ™Dwoй§дsOMOЗoЕ†@GГЛbwСћйЭРчВч=ь;5Љг жї€јыы†зj?и} ћЛf'–ТyаЌц–Gт@уЊЇћЉ‚œДgвШŠŒ|’Џ4œE_\:wvиЈ;ГVdMOŸюдBL4 =Tc­ИA\4 XЅV—[-GA,%5%oMїЖ5KаaЖ+TлСг1ЙС~Xо ['ейAнИ,wƒ@—фђчФЇ'’f'ё+ш‰ONp)J.œђ­@VCeэљяЯiKгжŽВЕ“щ>ЙЅ™S~Œ#™0e‚јШYAc=ІТa)@Ѓд=фЖЙМnЈ’ ЊGm0GwuиКснЩир†tіГУfуœчBp?pЕ№S!ЪЬщbJОАпЪСН€џОЋАHЯYх|GSОr Ц7wf,Щpй:i†pXКФTsАPЬЬvuм\~˜Ј^ЦzВ›…џйЏ˜ЌЏл3`xi1TЭў%b/ЄH\сУТ ‹П>‚hјЧaџœг€…G †№­8ћрсѓѕ8rћ‡€РхзпйQО#фW!љѓ'?:Й>ЦŒ‰РёƒЧGнФ:.›ч1ЭK—иpЕ{ЌLŸЏ\–gѓaEа]ч)цК\ЧаaTxЈ”@|тФУN[ьxv бј)ёœМSJ.WŠo˜_XОžШœЄ8р”РE,†)C`oХЮхХJх1ЭK%№pе|х}И&хїѓ\ї%KќbЂ†‚…ЙЬ}ƒa†HNЉ ŸЯ…ЇšGšЌР|7 К№……\}N)QИ\)О•фyOVЌЊва чЪy ‹SN3 ‰<ыІ}Ÿф[~Ћ=ІТaЩ‡УNшѓ 8Эє4і~УЩ[HwЁжђ6ŠЙЎ№^VdЮЉЛЅ!4нmwЖ8г5тЎ•Ў„}хЏWB>ь+‡(5M(Qи,ГІ‰љ\€oJ9ЫO—~5nl–9‹TВ oAэ†J`П…,йv_9!aЙљѓMђф“Иœ={vь=c9g6bšqxїwџєЌR8…ИЂЄ(Ѕ §АŠ(1KуŒ Д{‹НlœщХTлЧдхЈ_zЇr1(З…PQTму›ГЅ^r™’0*ЁхR‹K1@ДD‡Ѕ–hыЎ.>‹F/ю+?ƒ…6šџGѕHьQD3C"@Ь‡ИЗŸn'ІЂ*DР{pXzсРб тcO>ˆJЯ`чJёtћŽІзђ?.Я[Їi•X"р –ЎТќ~Јт+яWE)\•ћаa"0@>zј‚ЗО|ЬEдF‡ЅкLПъ;X/X• 5l"€ …€SЙТUy@с‚Ц ˆ" #ĘЪqUЎЃІ"ˆ€ _9РЇ6‹{m6<ќƒ9 пXl Jh1•+нСт?!—рт—Э%D(рspдљR+Te*ї#‹МX_ПЕциЁpQјэƒ'>:iіЂŒиcНьBю$[/ѕ`q#!чљTm<љй)hдЄbЬVђп+іОЅž:ќр=ђzд ЪTюGЁ5ЯЎљ›‘– 8јАГГѓ›–oъЖеm{›ћmpJГ NI\]ГьlЊi*]RZuЈ*РmFѓŒŠ€*S9 VпЩˆГќыЇжіcСС,ѕЩdz$љИЙЮsЪЋ˜ТцЦЊ=?^И><МщDSАЉ—9^YъДЅЧЇCJтн‰і%’ˆNˆ(wЊy…8ф 8wцRеЁфt 8ЅЇсuрР’НEHЬєеvА№™ƒјaycНfŠy№ўŠ‚Mэ_ЕлРѓоџ’ЂbЉЖЏOW­‡ЩЮиj~ŸЅЫ „gЬСЭь(ІъMl8§еwР1d§ЮJгtMy )ŽМBЃ~&ЬHhЈj gpBЂђ-E!y|0зT›ЪyфAZВmмЕqф#ЫђЫRЂS2юЯЈ]W +k фš_6УГВgYj-іŸ=”ЅЮ23ЋпДS:!)ЭШ+фЭа ќВРH]ŸxW"мьXm–ЗY„фёС\oPЭСт'! l[№RмЪХѓїяxoЭГ+ЫY_Й dqЌCРѕлЈу9nјœ0yјмљј:Ѕ’вŒМB|шŒоДЂ49=9}q:4 |х%#MЊЅШ"$… І{€ZSЙПX„јˆРММИФœHЅЈXјE œ‘“QЗ­ ІђН5{‹6 rв IiF^!z‹žl9UЖ{ч+OуТWŽ,Bе,ЄГ­˜ЛИЯjвp[ƒїœX"EХ"ши„иызЛ­ѕжАЁtфНBТFЇtBRš‘WH€­СЂcbЦ8|х• •o ВЩуƒЙо  ЪЊм,B‹V,њЈюЃЭ/ЌЛіѓMXAO˜_ZUJ’bУ7Щќ5ЯЏyЋщ-q–S:!)ЭШ+$аH)Eл‹Ж­мжА™]ŒЧ$Ф”n/•oВЩуƒЙо €,Bо ‡e@!СеПj>‹ДF•UЙ%х'#њ…EH`-F@@Y„ЁtdƒSЙв3XќФ"ЄЃоBSШ"4pњк'-еb*WИ*ї‹OpD%ˆ€o@!птixmЊя`ёМrУ#l "€ј-Іr…ЋrџЕ#ˆ" _ĘЪqUЎпё–#ˆ€. _9р…,BК4hЄoРЦ}‹чРдІХTЎt‹j,BјU˜ƒ[я­ЦqЋїдв~-Іr…Оr:?6xl}яhЪv†@@GšЈr+lbњ Ё{U…дЊщт/0єћсшZЯиX*0„H чжиЙ2ŸЬJ#‡ИIz’ьйИХž`­џ2ZLхJWхАЏќlл•ќ4Њьq*}?м—цјЫ }ЭP0ЄGšЌ_Ж|Yџ);•ЏЬY1њШєєщЊе†Š9ĘЪЎЪСЬШ28ЮЂ“Њ ™ы6ШЃ/gЫˆВИ™…Џ6V6ўtщЧQcЦ—_ИxЁёѕ—.ќ8fмиЂэk#яЖŸŸх”H ЃCяZZД”œ Кзъ\LхШ"4РGŒšЭА,^ГЙФЊэomећЋ4.љЩфхЫ[ЕV|РFЇЮNо№тR\†oШЅ~8œ:unмјqЄНјсЫз,s!‹ 8˜х%ZLхЪWхЖЎЊЋУжХяNЦ7ЄГŸ6ч)ѓR._Иœ9…н>;#+ЭХіŠB!у џЕP !…­Ѓ—3НИƒjћ˜КќѕKяT..y[EХ=оЙ9[ќŠXS§"€,Bњэ; ,ї‹ђV!‹rЌPви ‹Бћзч­ ,‹­xК}G/D` #€,B}ИйўšЪбaтfпЁИ‘@!#їЎ m А,*ДU"ˆ"`xp*7|cDРјрTnќ>Ц"ˆ€сРЉм№]Œ Dу#€SЙёћ[ˆ †GЇrУw16@ŒNхЦяcl!"€џG…ЬaY„IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/9-2.png0000644000175000017500000011020011733011756026306 0ustar sylvestresylvestre‰PNG  IHDRiqсЏРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН xUі7|џљžЎ^ЛCо/, ‹pd•АP! ,36A0У"( 2H@V'FD\ 8 ‹#ddŒЌ1з@кLї3сљОSЙЩэъъЊдMWч&щ>§єS9їдЙляжЩЉ{Л~uџ'koС"€˜@рJŠo˜ШŽYD€„ЙnЛD0ƒРџe&3цE@Н/DР,шEfФќˆz^ˆ€Yа‹Ь"ˆљ0„zЮ_Ь;ёэ‰*КйЃkэуЈAЕŒiєЂ*АХSС€ѕŠ9ЯЯЉЂ3ЋпX gС‘ЊeЬ Ф;: С‰D!p!—Л„~Ѕ†’ъ њБЩI4XЉŒY.ЅРŒ^‹(5eњНѓ=UFlіЦЁФсyВЧWУJ4іЂ‚‚|Аމ‰eyPƒhа‹ЁЎ] ьѕ\ е …o4Ж7VžЂV 8žCA†S ћƒžыŽЮо4жЃhA ЂAЈkW‚r\T2xu*PYeЃL2џЁ–4Љ4`Вq,‚џЛ*B ƒDЃю Ёl‰ZіНm Њє=UЉЙqэFуІхQшк cuЙrњnфЫ7l<ŸКОБ=xcIЏ[п+Ay=oкЖVJœ%ррьuH‚вэvnнОsђ˜Бܘš1jF•Ь˜&сШuGЧЌыZјЦіАЁбPЂс#Sюйќ'Ох•ЙlS…Ј )OвМ*cb|GЧrр­ ƒDЃ.ЃЁl•нх7iєШЮЊ’J}lЌМœ–ŸŸOm@MуІБ 03&TуŽŽхAЈGа›4GБƒ:†Вх—ИыRобБвL-W3}5bЫƒ"PџИKђє #wuњЁЇз1ЏоМHЇT#uxFЎќјЅGї Ь е2f}Ц;: A‹@Е0­–1… Н(h/ь˜0№ŽNдXQа"€^ДC‹†z‘0ЈБЂ EН(h‡;& є"aPcEA‹zQа-vLшEТ ЦŠ‚єЂ Zь˜0а‹„A-шEA;Ди1aЈŸщ>uњЄчqqa­РЁz…,тЛugMіђ"ъBOŽJbЇQ@_vэо JцH^wt…а…|!C " BмDyЫцхE*SL"ˆшE<(Ё "P^ѓЂЊ ыъ9\ЉЋ#lэR­((ЛWПНˆКаДГ•]BрD`зGЛžљ$ЇёКŒ5`ЩV”ЙъЗС oђsгwœЪ.ЁŒp"р*sё_ЛvЋTZ›1Ѓу€nV№ŸоЪл›э З‘›%Ў\‰oя•ƒ%ІН8ЋeГ–lќ КIДгщWёRьі6эмE7JŠ5ГЊ•їиdlnоАЗnLЌ2dољяЏ–Дnfы3$œўа?NVёŠџгЧЌ=Кж"Щ‘ЪjЕ& H„/ШьРŽчЫ#RQaбŠU+О:ёљ/щжГлВЅЫРžк,_К|нЦu7‹ЎЖnнсЕe‹cZ•п‹–‘ЅiKГіf…џЏ№Щ“&ƒ%§TQЮ+/ПВљнЭWWЯŸ9›чhfЏ,џж8U\аМБШ}—l§—…Fѕ#’H $‹Dш=kОЌ\ЄфЙU ЏЬ]fyb`ьOљжї)‹…X:t–n6.9КліШ(‹ЕБlфв/дл™Ѓ"Hq —Hсmз”Пх•–‘aУ;JвЗп:Є†ђŠ…>НГШх—КuыЛфЏK’ŸNюаІƒвйр:юаЙƒ|5УЇ<я”чЇ,™ЗdЭђ5nЗ{уІŒ•ЋWІН’F 9vтиіwЗУМ[Зo]МhёЛяњ7зНyЋфжyўтљВЅQ99grЖИ]vЮ2ньr9ј1ƒ€тJ€!і-Љbа}O(4М+нp#ЗћДEjсўКи},ŸœqР}‘+ǘфп–ПWЙр”ѕŠн…ПTсЗŠЪ•bБУПђ0Iі№Х;%–ђ`kХч Hw‰в\W#с #ю!эТ%щЁv6pЁ”g:‚?ьмqюО0чіђщPнмk_[лВй}ЫџКЈGB'†?ёfњjїэОќsћ?;t‘=ЭayіO3ВГГYЁ‹^\dВZ,–БЩcПЏœJэћtпМ™ѓР%рѓЪ Џ0у*Ъ™ћ—Й`L-ѕВГrP0€ЏУјj4kсEљІ‹4’,з Йю{‡„пXф‚eш№ђ2рz%w]…\a–RYЃ}ёЉБ`“ўЫП^bXSт&?aџтЌ|OжЋqnbйMwёuiЙ+Й\ЅЪрр]ŽW]\xљ‘0aЛ/Ъц’ьЯђ6ЭŒыавКїЂl žън“‚…ћЩSž…/Ј`‡Ж-п1ыХYы2жVZx*:>яѕЗ^џўћяћѕ7љЌЂЫхЋџВ%епфuВ 7fбM eВM}C–Ћ(ЧQSЖ^vz&Ј@˜–pўЬщ+~и™с_uљМ^4}‘,юй–F}$вfџЄ”ro!З<5HФJ$Иn~р‹„\/ГL§C,\дp7‘эG"]oбŽ ˆќЩ‘иј7Wў"]qYя“Ні<еUJђ•ъљ„GйБУˆ œБќЖsўдŽљзJfЌЪ:Њ|Š?xgёdVH1Mb_˜>Ѓя€‡=ЦŠ\s_œ;kцЌОЏuЗDHnЗЋ[m3ЙМђ\ЭьЭŠ бMф5ЦЂТђэqЪѕœхшeWДХъ#C Sšџќщ㹄еЇєYтѕ"в€ŒM$%NїоГDd ЗRИеёiмЙHЯ?Qк2Н#мОхЫ!шЦmзu—Qœ“@ˆ“Фvd“g1.чuWё-b}BжЋ>w+џ]S}‘`AOlФf•Є0'ЅэѓМъNyЎ#єкьjрEQрдSџ8ъКt‚[)ЧMЧŽ­;~з9žўГŠjtO^a~ly‹5ј”––ЪН”Є‚"Ч†ѕ@УўЇ1ЁмАB?d`џщѓ^œЪПОО‚йs–Ѓ—VGПP -чєщгšzНZxчEюOfљУ›§_r—§цКэ*ЙqЫхК<0‰ДJаыгп#пџ§oв№&x‹=ТГ#8ѕDbьД‰qЖ"С,+ŒмpшB4ѕ™Љџ:ќЏбIЃaйmЪФ).—ыЕЅЏбТSЦ?;6elЗЪч˜,ZАvекn}КMyvJ—Ю: чЌY„Рм ж† 6њЃ{uыХЮp–Ѓ—•ƒB-"рЕѓ №` ЙЎ№лЫЦ]–Н7$І;­мOUDIО>“юКѕPœЫсœхя$EЙ$їяnчuѕ€%nБЗ%ћ9hpЪјЩ№У+5љу…ЎЋbIфйУ3Sbжo/јcRœ‚q–lлQ0ф!щй'4Šb% :м0ё љ— О+ыу,ц JgсОЃЋЌмfЦ“ю[™ф“Ѓ•Њ@§‡„%4h< авNbКЫ jбЉы~шіЉџšpтћs=Тˆnэ`^д@ўiјФБќ]‡Џ>mя'G'ќ еF@sўR^JЕНrСž57ј ыНЁяŸМvrй{%љŽш№0‹ГЈфх-0Зк2г./Іы/аy‰‰@@^итьhvўxд*GЄф@>а=чЉЊ\’.›аоњКя#энЗПцЮю2Ы™АМЇмєџаТёRШ>ˆKЂЋ *|љgD4ЃЯеЏ*Я IГ›,Ф <ј…€ŸБШЏКЬfђu! Тg~йїбf‹Цќ!‰€Ыэв{6Х#Ÿ€ыЭWšњфEО є]шžя)д †Р,‚џт кЗ—LрHšTxCбўЯ‹е,Јя еїФіз>шEЕ?и‚њŽ€—Сќ‰О ПОї лд(р&Ъѕ:Џчш b|aoЂ…Њѕ:ЕG'Бˆ€HМюшDVŒu!Aƒ@§ўе5h†;" ѓѓN|{Тdu=КішаОœ7]^P]ё"œ™WЬЎD {|ї˜ЇuЈ Эy~ŽвиyѕЋ!sЄ:сEд…К'єѕЃ?˜%D8yєџ;t—_G‚(.Я™mlrвжэ;ы–С*рBёнфљтаDМ^§{ЅhžU)щ.)О^Є2 TВNФЂ@uЫA*0` qЙ"?˜шEќXЁe­# НЫNЕ›eрcе.Џ+н*кvЕЋТ ˆ@"`‹Њ~wOТ‚нЊ“@ с›)оЈб‘пЯљВєTшЅО Sє+‘AUЭ#W?ЏјuЯvўќљфо9ŠЮцœM|œї%[БШзmjЌ$КЏэЌВ’Зпy^И™2>eЪД)ЧŽ[Нr5ШUцЈ8ЉсEЊlЊШCƒ=2лДacцю]№Вм,zqЎveпЄКu{хЅy›Зl“wр9.ПћJU”Њ"L"ЦTПwIЉЂŠuылџtѕ'pЁ^ В;UaЌ .Ф”( ц№нХWЃ[ ИЂЮwњѓгп|уЭ^={mxcƒžЌїўhxD іѕ6жNmћdїМR­`ЧiЦŸRї>ФьцЮHe;№€’93@Ј&pГVё-пЅ"wх.)ьl5Kѕ6?vќи;яНу­Ћ*ЅqGWнk6ђћQžJE‚kyє(!ц№Žp­VLМѕD—”Њ›ˆ†#Z4nСySЇИфЋ.^џl#{Гя}€Ѓž Њ]vЪK­ю.)U4eкЬiЋ—Щ+ УŸќмфŒЗ3:uэDWэЊШЇ4юшЊЮga'Ÿ‚Т|f6fєЈ%ЫџJwЖ*И’ПрЏKи)•џ6TL"ЕЛёѓўєЬ„”ёIpЧиЁCмІwо„/ьв[№jЕ?Бhђјg“RЦТNŒєо/eЬX(rќŒ)pkзњўћ'NўГW ˜@ˆя­Z•?,Љnџ*›зЁ}GЖr Ы№бБЌЬQёWэEО“"ІaИ ѕV–ЏN1{fцЋaЇP@‰пеЈе^ЈrБD fЈ2ШTVYЕмЦіƒ^X<БДEРRоDVо,Јзд‰Xoї&c\Яы ъ5ІијB   ˆГdи ^НРilоЌNxнє!ѓнMцћƒ%1ќЛЄшННЄо…>^,ё­ŽМHЁ] @пя1йxu‰ђeZшE&ёФьѕ šxzQ=ЛАЙu\ЃЋƒƒ‚MЊgЈWо\wnпПѕЌи\D@,CГOŸVўˆPyН^^D](чєБMТкz‡@gBЮ1Gђђ"ˆBрBY{=wЖоu ŒјРф1cO?Чsйwъи)ОCЧй/œg™>­ЂB//Ђ:(kЮŸЇ“0љн јABƒ_„Ы~СK ;›Ж<ЭзFУ‹dЃ0‰ѓ…ШО%ЂЈwTИЧ“рcЧŒнКm+!m•}дё"Ѕ Ъˆ@Ј рчгошEЁr`? pћћdў^dˆ-„ pGЇј6oо\™ЌЕРаEўњЅV-Ј <mкЕЙ|щrрЫ х/oоІ бМeѓŸ/ƒŒБ(иЎ№Ў`ы’ЈўC–~Љ бjAfz= -z‘Ј!ђЋž‚ ІЭ˜жЉ{'ј‚IУbќ Pш{2Аpџu—Д)BJœeMљ)Нзмщпб)‹AЙ6p\sŒž0zЮЌ9k–Џњїк Щ=пcojЏцєзѓпїэjе?ќTсEzсЫЗ ддoЏœ>iђ“#†ввAp9K@ЙєеŠў2?иєццMЅџoщАУ–.XHЪГMЛ—/U\oЎ{3ѓЛР`Рув^Y$IЙЈ2В:§Э]{v‘ВвщгfЄŒI, ІсˆхЅ•†ж‘уї"M@єяш‹+xЖцШў2{иуУ”рC”lБшищœЯўЙ6ИѕЫ-pІЇТІ ›.~wqЯЮ='Ž  _Н&ƒъпмАщЪВў‹§GnмИЪЫхџ}с( 5пЏКXE…sxНфбћ5Žь”†щЦ"ŒDh‰U]НYlБZ•Щ›7‹™fо ѓ@aќФё“ЇMЇ Єл>кНa§k”l0у/3†џaјœys@о§бюрахњщЉsXiL …„рб џAќњшz‘_ЅaІ@"е(ЪщtвЫ– ЩFЂXбMЂЉ}гq•щЉ яB0xˆGY9дАи{є(™F ZгaG OŸ>YџЪ‚y +’]ћєaЩЂТ"ъHEEEАчгSAо…рУэJ'Єњfіf`Я‘y<ИiѓІяячхŸЋV,ZИDфАSЉЇТ˜бc–,^7{yрй№о†Дђe‰QПѕзх]Жp™$I7eРM” я`№cALL -9дŽРw(Ц”Ћп`|ёŒз§ЏОqˆF5ˆ\г[ооВ"cХЋk_…jК=дmЫля(cH—Ю]†' —зш†›>ЅbRФ$яНFЦO_Б СŸ*v!˜њ+нє<ыy—ѓ`кSЏš\' ŽС…Р‘т:Ы?Џ)?UмбљЩЕP–ŽВ`ЦŽћТ_f”џа!Ицњ]8FЕb‘ЊЗњ^ФІЊЊ˜ЌУРЌrыpьЊ9F‹јЉ<х*kаѕ"ŒDJ˜Pnј]nќРхThрМH&C“ѓ"єЂPМhАЯ*LЦ"э;:GБУuЧыw%U­˜D‚ РЯ‹Њѕ;n0A‰} Y’^Xр5КИACсВ€bЧCРЧЂšБ𹨘ўќ+_@оsпeц:`^ ылѓYчЧŽœ=bz$Ж–y:ѓЇтŸl Ѕ”Ю“’4№Џ˜ЋŽ"`r^$tuСoьфu•ЙПОіѕЦsщ@>xљрјŒЛтМ2§_>x9ыУs›ЏЛЏl;—љцёеR™г}ЈЃўр_ГъгФџ: ЙфMь2ѓб™тњŽŸёг3}шГьёu;Ÿке6в>Ол„ўєЙюКb)#Ў;јЁп#Y3b,2о8жРЗjс6у"Зк5iщpХЧ$Ф4Š!Ѕ‹sf\И§эј.ЮцсУЦ з+ ŒEЦУХЧ`йОЅЇГ]“.Ÿ;w[Й&Ÿю№ч]ЖЈ№ХН2>~ŒИэ†ЄмPУіzdБШxАxc!IВY#эVыа˜Є–Q­ц_I  нЃю‹К/Юw4c’Лил$Юb‘_fрћЩxххƒy˜' ƒЬnЕ#39ЁїРж-& ьŸwцдСOvMx ’бSї/ИœG‹rЬŸ2y`Л`6RŠѓІ“ъOf…\`œœаUY>k€ЖС]Вqyк№Юэ‡?и~чЛ›ЋЎЂВ…]UMbUЗ€БШx|9cЌФZbњE€‹юXžyхбшЄбMfЦDФѕ‹z\j`‰)ЛъѕŽ‡—Z еORбFЬXєъЇџи~єГН<Кo/Ш ЁЇrОќbУюf]ШђфШщЩIЧ™О’??6bфђgR›y&&Oœ’u67ы\nЫћлoH[Hѕiгž›4ћЅyEщџиŸѓЭ ЊT5 ЖОБцЪЅ‹[|БуФ™ЧЊЋ€Г9й'6ьоMъ=lфђйMRжФВЩXЄСвЫ§oFуUuзмwˆЃШЙ§T+,zBO)ЮJђ/•Йq­К;/Афkw§HJ~vЧіs$ПыКWуэŠ@І bШШQћр<{і[ЩQ ўгяЛtйzЏ,Лнюў-›{%л4џЊ Hе00нЃѓž3AŸмЋы˜ГњHДFkдЈgЙвw|loЎKWV-<|щВ…ЕPЋIЊSВZПСЉKЦьЊ5–gLаѓyi ОGeu.КKюHїYcnн–fќƒdvИtt| Џtёћ7[mђФ)œиš[ю\'ЮeF&ƒл =jУЊЃ&NЂ.DOQйb‘_­ш•Ќ$2РXЮ|ъIИЃƒk<­јf1ЭЛdуЧОќbмРGрž№ф—ыœšWЏ]Е7QЛ^rУЪ]ЈЂ…•MЂ њЃЩXBПбй‘я‘]"G/’ЖVKО“Ю—"%)Пфйw=у[1м#-J:?cCїўfНЖrё”Љ ё5гг”––Тђ†EВРеПbОќjњY’:ЃрJќЊuџ-їсЪSU =&}с|g‘У}Ч Ы дRЏ яђB.…БШxШЙзшмŽ;dp[KзІ$вBJЫ\}ЂŠzE9‰НiOŠoт+ФIЂšщBЪнЩЛђєE ЧLžкБ[<ЈЛї08y$hМMЊJ-X“БvёЂ‡[FЇŽбЅGfњшРA‹&%ƒў­ДХЏЎ{‡щ™ i0іљй-лЕ‡ћ@˜_5nк˜ыUСŠ MСd,КК1ћ‚VІ€МП#?]sЗАZnмq_EцGfЏsrTrц“ВЈ"e0КNЗ Гм-]кынъІcК> P­gКkѓ@~ЛŒ‚€М‰’v­,Ч eК/Š<о–8сubЧо&ЎŸd/ Л.џ&{›И]ФнfКP}p о6šŒEBW8ч'š]“7жJ"­ЄЅДkbБЕ‰qєLqtœ@`jSx‹9D`ЭЬyKОЃSl]ЈйZTж/LЮ‹рПЋИ€xЂйўzcЂЩŒўх›ќTфn“7wвЕ+ЄыXЧУs,Eyю&q.g*3спz†Ф"~GKBr•=ФXЄDCCvY,އц?™?шUИ‹sЖŒGв€ЉžЋј]ЈіпФ|ЅЖђњЖ5С‡€Щy‘а;:ыlšЬY/r]5б %Ц"уQцŒcШu5†RЧтмщS№и<ИЄs^VГГLЈТX№)“БчEžёBЎЋ‹jJы—,†g5рСЅjцЋ+ц‹ŒG‚3фКcЉmёŸяПяў№эsѕA‹БШx”xk‚I"|‘ыjŒЈктЗвпъѕ{‘0ЉGд7Э‹ыšрз•ЮsрШхдСYВyTЦXф‹‰ZУ‹ыъз•N‡рВѓ"ЁOЃЊЏюК—FЎ+Œ А9њW“ы ‡ЙR†вXвWЈ;уБЈZ7uШu•ЙЂ4:љЦ(фК82W‹ы n@ПuчъTKЊхBрrЊz…ЎtѓЯOT­„ЄљМДп#Ћ ЙЎ MоГБ˜Ѓi#+УфhFЯ:…‡ыСчE$фКЪуwМЛ  hЖщ/WƒЄк§+c‘ИiцBЎЋ&,еSОДтѕЏГ>…™е”QOtщуaьVЏБж&c‘ае˜‡ј}cf&/чˆ з•Ј 4CЎ4Ђˆ# IDATk`†ЙЎСБ–b2 ]]№]умL^ўZыЪU0Yšœ eFј};f&/џx#з•Ћ`В„XФяH`ЉтК ѕ"3s3yЭŒ7p]]%№-џИZЪoЩТO!РяBЁЫu В!ЧюœR,0ф0‹„об™™л№ч•Žo&Ÿьu! ^э4лKƒ D@Ю‹`€шv‚ Y'n’:wЇ'\—Я:п+}ъyэ5Ырz%ŸРn“ј y‚6х}ЖїьЙГЪё=ё­МVЇŽтUЬѕ•gЉ,ЭЕYюя%ЕЗwХУЄYyDВи\•жt7Щ’ѕ!uЅџ•jЯ_ієБGх§lВЌ#їм{Oы˜ж]пш˜e[сEРђ>%U|Р9Љ`ОїєЉ {­SР ˆi7ух6›єСšеsзЌRZС`ЉЏ,жН“R‰rнD hcQ9миWz˜Й`#pЃO˜ЭШ‚їќРQ)Я ‚зэъС‹€+іЩЋ•˜џўyEЅШю;%W‰†џбШЋ’ Р‘NT™§Jкэів›WUYZwtї вcВ"мБˆhК }ŽAyєиEоkЈ|Я9ц3дs˜#A†2§XЙ|?šЪr3‡УоЈЫAюitИPъђ5LBE Јc‘Юм†ўvЄ<*‡Ч%5–Š.[“SžЌ”ao/kХіr•*ЯпfБЭ`{ж˜6qLUp1ЏYь§,ЉьЮьѓXІ4fƒ2SъA‹ќйb—]6"хсHо:’ ЌАpRщŠЈXRcZ&Œ;iљь™3—Нзž;$yчЯП>џEи3œPЎб}іёЮУэ†5:еYLж#‚6СяBŸl№šбQНС№@sзm№ЂђнБ‹нкЩ:—$EVБˆ—єм4ЉЁuймПцўЌ›Дm=*eтАЇSЪ‹“ђ=ќ^tЯ=MZЕюѓшр Ÿ}+rь, ѕ E№ЃђwЁj<г]‘H’—ю*BН9ЄЧсхUнђЯ(нFyYT}УVѕYe9(з‚6Љ цŽЮнVъ№ИдЊ‹юО‘aмЮ™Њ L†,A‹T#Ъ‹мѓ;Т2ЗљT Рd#€БШkp5Ÿ‹ѓВР"рƒ€ЩX„я]№AЁ‡€ЩX$д‹јч6Оуh&ЏoiЈA”@,*8чЫДРх”yAжџA^eˆ$џмЦЗ6yOžй /ЉNьt*/Ыnuоqœ(8!IЖ”ЮђwцщLWYI[{Ї„– nXœ№m"jъ-‹Œ‡Ž3Ž­=Жњ­ciЖф§œїŽ\9А§тіЏЏ}§яџ|:mЯ3ч‹N­јњ•’В’9ћџМє№Ы]ЗћЎЦ“zU4…gчг*ВуЉEРd,zGёФo,фН/*<2*ВФэВYУ%‹ЙxРтŸњ№Vиѕ\gю§БЭЧХ?зШ~ЯзЗќ$u‡уБqEoыћЮЇŠЎЁˆБШxP9cБ’pxЁŒ„УsЊ.)Ђ~М’ь}Q‘’žw(~ёијšЖžйkўЉ‚<имИb…E}пљTб• 1*go)mXH$ч-KЁЕЁ4$ŽВќ“7о’ ­Vл}іЈwпŸ9шАфВ—”Й$KѕљЉя;ŸЃ\Ÿ-0g,JŽ›к*њwг.’"Hb“ap_ї~QкЧЂ‰mІЗЕЦЕŠnBЮЬЯ6[ЌББ1­к^ф(,˜?eђРv-Жn1R №ЦЁ}”+G*œЬ>:a`џ­Ѓ“Кќh—qаЂ†РXd 0g,ŠП7qt“ЉНѕInњgЛ%І{Ѓ~F?љИ}LbtJtDь ћгЮœЌюпnю~<#ЦY WыМ “'NЩ:››u.Зх§э7Є-KњpЉ6эЙIГ_:W”ў§9пШЏdСOэ"`2 ]щцŒ š€ ШыИkЕнM$Їрѕ ‡fMfMp:ђЮлeOЌŽМэЎBЫ‰ѕЖмЩяКюерVМрpEћ-dмЌ9Ѓ{tіэNxxxIё gБ^x27Эыm ОЦЈ€Ф"~GKе{КChŽF$пЃgO.HЙ…вOЗcˆЅУŒ]$+ЧщШЩыј@_{сYщŸsb%Щ*5"Жц–;з‰N8‚ё˜љд“pG7o§[6/ОYь)ПRZВёƒc_~1nр#Щ НO~щџКeeyјз,ќ.КящІqLяШFіuэeЩП#e_ГE6Д…GиJр=(]&YЙ–ьеФжФвД’,хЂ[Е_Йhъј‘у&d}“ 7o‡/џ,4|>qvXЖaгž3gНЖ"mЮ\ŸѓЈЮ‹Œчœ™пзšRZZj‘рз& ,3Ќ˜Џ§Ў•%Љ3 ЎШ4A№Бџ*HPЦ]A‹Ac‘1Ќмs*ГћКBSЌЩXЛxбУ-ЃSGшвЃ‡fу8hбЄdАy+mёЋыобДAЅHLЦЂизb#сОЎ"/мКVчЃЈt^Д}Uю…ћw'в^]]рЙ”ѕРїuе?шѕ&c‘P/тœŸhŽ™˜МИЏЋ&јAЏ49/Тп‹МЎмзе ŽI@,тw$А нп‹ќЛ$`_WЧƒCѓŸЮЬєЊ+ТъlяЊцtўе‹ЙD"РяBЁў{‘ШQСКъ&чEBяш8зЪ4@@^фКj" JŒEЦЃЬЙОWЃ\Wh%} [)7-„ `2сg”j”ыъЉЅК‡Ц"у1сŒEфКю|wѓУ1бp4n\Ѕ‹T• љ/S‚ cЂ>иbърўW­§‘˜eХй&бУl)O1Њ@cQрTœтќ­)€\зняmžїкZ87ŽлBІ'СsЎ/­YяrЙ`3YGЁƒхІфЅ-GŽKal&Ыє(№ €БШ%ЮXЎ+Дцф—G###сeљpZЋqћЊcС6“2n l&ЋЪJ7“§ЪФ[bT†Hc‘ё@sЦЂ€p]Ё5oй0rТDFNžјёЛŒлч—l&›}Є’шW ˜‰!€БˆAЁ+pЦЂJЎkZnNл!‡м7†Iг;w?Зo“ћј‘„­$яг ЎыоЅ_=wSЪŠё§7п$”‰CžYyпЅД4)ыm&›Ž›ЩVYŒE֘бXЄwєфзѕ“m[‹‹Šn^Оа<фOЖmђTQ…ЄљгІВМпЭda!Љw'иў 7“­fЭS&c‘ў(iжfNЩ4+1Ÿ—–р{dеQЎknЩО&ЕВ‘№2Rтt–s]3IіjwГ^2з5џЙ}“„…MЎы]Вw[цюгчс… ДXDЯ ~фйY HVЖ€›Щjу"D Бˆп‘РŸЃгѓ\зƒћv§ЎGцBPШП{ш!аыжZy‚n&›їнy™{—РИТоВš›ЩТVЭ—ЇэлВm|Њ6—ЖВHќЫ‹П i>GBБˆQрКZЗЕ”ИмЎ2rЁЬе'ЊЈ]”•Xл‘ІёЄјq^!жHв  )ћШ›.Ћ?mzoтМUку&МЗцѕФпЫ3Ѕ*>И™lрдє)“БЙЎžBЎЋ‹а“ыj0цœs*фКрМЇqЮxl9/‚‚ыjŒf0Z˜™фуМШыЂ@ЎЋ!“09/ТgК ЎфКЇЭФЂ˜˜XЁ^Ф9?б—кЪЋйT&чEBяш`~тЗ3Ш‹\з ѓ ўю˜‰EP Ц"д5Эuѕд„RЭ Я@UЋ`fo&Съ‚P/т_+ѓХB@^фКњТ"ŒEЦЭ{И}]5ЙЎь?ŸВХšJC– љk‚ йac?e ƒ†UЁ:”I3БHєъ‚€xЂ9ЦœѕжqЎЋfз@iž.IЪm”N>Нъ‚RБШxX9cQНрКъѕж іщi3џўжлЌфїоz4,ЉЙS-œеоі.Y9яиmx|{9 WNT˜@‹U&ЗООfxчіА .М1Т}Їbчv0ШкВ9ЙWWГEЏ №иЎВ:жf4‹еГ7‹ .œyЏ_\WOЛН%?8А ƒмњ?…p%AIчNŸ*Нu 4ЌTЭjсЌцюДзІ•ќrkчзgЗ|v<'ћsVˆžАu§К‹grЖјЖС•$щ•K™eЮ7g6|і9Мj4zmаЋNЏX={3БHєъgL`8*yызU ŽRі;цOГо_Ÿхl_Ÿ>fњ,eАSmЧžёы,иЉ6ЛђЅšЛгўhwътE№њљ ‹—)Ыб”ї}И9uщ2kД Ÿ2oсЁO=’д ­їVlфЎзНъєŠеГЧXЄ9:^J:/в;zLk—ыъi‡ЗЄљ“žІВ<ŸиФQO~џэЗGїэ§ўмJwg€+LsЇZЭнiЏ^Лjo^БWЇН‰іІЌdЎц_еЃмПСwШƒmŠžmpСŘЅ^єЊг+VЯоL,‚е§б`=œ žh6–жЋwdYj—ыЪšЁq`”g'Н4ѕ™д…ЫUД\иЉvкТ%Џ=В ТЬ[њЗiN[HwЇ&HiIнsъ[›5mцјЙ€:Lf<} #nЗтh”ЏЫћ {і+Ц“E!щЕAЏ:НbѕьСKљ ,‘ыЊoБvЙЎоmёЄ„q`&“Єч&yъ.—єvЊемЖџШQщK—€Ÿ8o:гЯgEuшПунMрHЮ"GњЫ ™ШМ+^š-ћл]Rp9ЪdЇ”‚^єЊг+VЯžп…4ЙЎBWj7)GEG6ЛЏ+p]GŒЏ*ИЎ ЇJzыТŽU(Y!pqNўуВЙзОЫцџepЪ“žё\ыri1бУ:Е]4{* “`FЎЄЌГrќєvЊемо0aГE&uщ4юБž]њ<Ъ*}iХы_g} qlЪЈ'Кєёlw НывЃWъS#ЦE/š6ЪdY”‚^єЊг+VЯоЬМVыъ,фКzА?gЈАš-ЦoЎ+Ўбy r]НрЅ„™X„Я.ЈЏфКЊ ДЩyQ­бё\ШuхA‰пІОмЮсё˜r>GЇYr]5a 2Ѕ™X„ѓЂ ЛА;~"`f^U НЃƒ˜рїbЗ€МШuѕѓЌџйЬФ"бЋ ~Л “€МсКТкn§ПЈBЎ&c‘а_]ЭЬOфEЎkШyOe‡ЭФ"(CЈ ˆ'•Аx§х­7p\WЏъ§J`Lѓ 6?3™‰EЂWФM9ы зUГЈЌГ`,2ЮX(Ў+pwIЦ‚`‡pјf,xЙj= Dpd НbaЈvƒЪЪ№oѕ0‹DЏ.pЦMф з5'ћи–ОgЩ/з7Ў]CЛГqeкѕзw9 пы7ЎщВ =§БR~Ё‚т!4ЭbЗОБцЪЅ‹РнqтL‰у†&tЈ4DРd,њ4Њagjйр.qпq—ыШХ‚O/8gэg%NG^IоЩи(ЛU’ŸЏЗпўеѕ‹;ЖŸ#љ]зНk9н'NWl~.H=bћ1™x“п5§ЃљѕPŽв…t‹эе5}GEБЌ (TˆEеrЄ%cv]јбЙw"­Hшъ‚€xЂ ­WяшЩЎ+”І${Й’–есE5д{ZU)i мRJieјWjЙИœВбЋ œѓe™l>/-СїШЊ \зќ;Rі5[dC[x„­"S—IVgЎ%{5Б5‘їu…WL••ЪY4їu-/ ШžДL ŸЙ’ЪЭь2 дЃЗшЉЅђш• мR%ЅT™enЬЬ‹ ’ŠE†šчКв**ШžП:Ar%UЪ,ЫХK€JI †њЈFQЬmЊ(vШш1щ чИмАЬ`иG4аDРL,НК`>žhB`ЈфЎз,з•ЖШ›уњіLъо XŸђютхx{Ž­qdRяN№Е5О’UыSІM›иІCд ŽšХŽ}~vЫvэЧ |dtЮ›6fЦ(T “БHшъЬLИ/h5ђжeЎЋjБAІM#р7зjzGчЗ ACфEЎЋщKБО`&‰^] Ћdў!-&/r]§њžЫЬМњ.”! žh'Нu–ыЊќэHГЈ4ƒФ"~GKхћшDЏ.ˆ‰'ОhšЉЙЎОxŸ†п…№}tС7њиЃР `f^-zG1џцJ€МШuUa:I3БHєъ‚п.У) /r]CЧmT=5‹„Ўt›™ŸШ‹\WеЕ:I3БHєъ‚€xЂ9№Мѕ"зUОPb,2dЮ8†\Wc(ƒдТL,H„обёЦ­ЁЗ>r]Е7WеuU `&‰^]рŒ šНЗ>r]57Wе•U `2 }ЕŠnд‰Sѕ“ы:fЦЌО ЗЃЋзеF@,Њ–#!зѕ %lъјVЙЎš›ЋжеkЕюЖЋZ..ЇъIЭ‹шЬЪїШЉ\WКЙъž3gНЖ"mЮ\жЊ…€™yT$д‹дџћЋгQyы#зUssеърŠЖ2fb‘шеыlšwНѕыЊЙЙЊ&ЈЌ“БHшъФю Zнey‘ыЊ=”вШu5mNзEЎЋŽС{кd,Тy‘зЅ\W/8B&af^ eFpЦЭБ“ЙЎšрНbП#Ѕ’ы*zuAР:›цx›ЉЙЎš™’п…ыdCн fцEРŒzG'`MWЮz‘ыЊ‰^((12чœ* \WUk”/7UТdнAРL,‚^рg(ы,з]б3H5#™‰EЂW8c‚&P"ђжЎЋЪm№etš—D•‹ŒСф\ЃCЎЋ1”Aja&с{М.ŠРp]яиЮ6uяЕб*ь24ЪdаlнbўЄиъžљд“Gїэep:†ЧwЅŽ,")…Ќ™Щ НЁ ћч9u№“]ƒdєдС§ .чБЂЖООFо[Жu x\6eaz4РXЄ ‹—’3„ы Ж–ќr 6uнђйёœьЯY;цM˜˜Џ™y‘шеѓёФПсфЌ7 \WyџжЅKœПVьпЪ\ZZj‘$‹dзZ1Пb;JzvвД™Мž>iц,в ТмwSWV0jтЄ/Э–}ј.%X`рЩЪ6‹ŒGŸ;€ы ЙТvЎI]:{Ќg—>ВЦ-X“БvёЂ‡[FЇŽбЅGІ—…0щўvї'’)}7ueЇx„ЄчІС&АЉOНhкTрУђф e3БpКК1ћ‚VЉ€МЕХu…№'~?д}ЦД@ќцКŠ^]№л…Lyk…ыz№Ѓ]…WЎ  єЊLЦ"ЁЋ œѓ^VОANѓ”Ё’П^С\WXCлќњкљkџfи4ЈQЬЬ‹D3#ФMЌљыЬuUў(ЄйrTŠAbП#Ѕ’ы -ФXd0LШu5((NѓЛr]ƒbРБ5€€™yЌ. зе3&Шuѕ`bЦ"учœ!зеЪ Е0‹№йЏ‹ЂЮr]НZщ€U>oІќAc‘1jœБˆдЎЋq—*-p•Џ SЭФ"Јзш<ш#зеƒEˆIfb>ЛрuБд(з ЭX№ТР[Р7cСЫЄИ%уЁЏjReЁvGWYNW_оЋW'1Ё…Ц"-TМuœЯ.д(зuуЪДы7ЎяЛр5ъѕ‘ыъеLј‹Ц"cфxуX ИЎ№l5kPС•‚%г&г=э`ŸЂЃŸђœКœ;ъЩ[ыЕ“ЗжSnƒЧlP†€™X$zuџw_јф ,зш3Fшвя‘-GŽШћiцВз>џd;э—|*iјЃƒ‡Xр $й~-О}GMM#`2 ]]р Z˜ Ш \з=ŽїІ]d‹ˆLl2ЬA.Н_”&5ŸиfzлˆИVбMˆУ™yqol‡ФиЋ5BоаЎŠьъ5yЦДaЃSЈMмƒ­лDe8•ђќœФЪS ”мvƒrюšŒ* ФS5‡ў^dŒ-g з•Е&ћШЁОC=›Љ0=pjрPЏ" ™}$[iƒВHЬФ"бЋ т‰&єœѕ:юZmw†ЅхцД’qШ}3a˜4НSqїsћ6ЙIјбJђ>ЕЛ -'жліО(§ъаЌ‹)aHЋU;^ЩЇЂьЬH;<М=х)” `f^ЭКвЭ4Q3Ÿ—–р{єTЎ++-Ъхt:YR)ШЇŠНœ’Аžвe‘˜‰EЂW8c‚&|цѓв|ЌК€p]Yi}њ8В7‹%•œ:АwЏRЩ‡њ PjP‰Ц"cД9уX@ИЎЌ5уџђТІŒЕwьrџъ„їfх}wVНщY8•љЦъƒ;2нwм№›ЬЕЋ'LЧнWxЂ3БкŠktЪЎЋep[K‰Ыэ*#Ъ\}ЂŠкEY‰ЕiOŠoчb$ šВп Wцє•эЭc2v|ќўъ%o.yјо­їЛЇЇUМнJ>ЕsЯлЏ-YЕhсoПўvЯНїМЙ++ІMœo!Јƒ€™5:бЬˆ ~п˜ Шkkhљф‚Л…е#w§iц\е%ŸHйMЧофŽKўŸу,…ЄуoЙ[&jАђ•П1-cиъЖЪ|fйцLYy—LxЂП#?–ТU6˜†€ЩX$tuСo4ф­Ўk2?§oЋ/‚ЗšЛhА"fцEЂW8ч'Њ⪘МЕТukпaЯЉo­Д—Х5б@e`0‹p^ф5Шuѕ‚#dfцE’а;:1ёФwшЭд‹\W_<ƒOc&сГ Сw=`ќAРЬМъzG1СяEy‘ыъЯyЬФ"бЋ ~ЛŒ”€МШu №Ї&cЮ‹< #зеƒEˆIfb@%д‹ФЭбч­7 \W/выхМсё]wОЛšzеWГЭЈ‰€™X$zuСЬZ™€МхКВ‹FhЦгУч,^’єЬ$Њ„ч”_f‰Bm!`2 ]]р ZX ШXЎ+эФЙуG_ž‘њjЦ–Ž=уЕК…К:ќЇуw$АTОV„z‘€u6Э1сЌИЎ–вIчЧ>bЗФtoдOВиЌaЖФF).тdкy4Ћћ…нБw.•tчŒ0~ь ^WВnёмŒ-лcку“Іš#SW”ќ.фћnTшƒP/O4‡…ГоJЎkќ‘œ‚з/š94a˜5СщШ;wlSl”=AВ:ђ>ЌрКоИрN~зuЏ_еЗъ—ž}zљ{њКrЪЙ”хж2z IDATАњ‚˜‰Eа<ЁЋ ц6šˆгzѕŽž,хКBБЏќэ­еГgœ;}ЪSEЙЄœЁ ЉРЉ•Є™X$zu3&hтh>/-СїШЊ ,зŠMљф‚єŒ—'Œ;љЅчMtЌ:ъfжш !‹ Ч,А\WZ]ї~VenIKq№“]† @ƒкBРL,НК`>žј‡2wНфКВІЦuŽfымЇ“K~qвХnœ1pъˆ`r^$tus­LYyЫuUNx€йК§дЗД_JНfOQ)3БZ+єŽŽ;&hР( oэp]5њŠ*б˜™‰^] Ћdў!$&o­p]§s“БHш€xЂ‰,НШuе0ш•fцEЂ™bт‰я›ЉЙЎОxŸЦd,ТyQ№]иЃj#`f^• НЃƒ˜РsЅBB@^фКЊ0Є™X$zuСo‚сЗ>r]U?=…ЮuиžšŒEBяшЬЬOф з/ыР^пbJ3‹DЏ.ˆ'š ѓжЎЋсЊшfšcTЛJŒEЦјsЦБтКЗ-j3Бк.єŽŽ7&ha* /p][Eџіu•"ьыjГ†УОЎ‹ф}]­•ћК~ЖйbщЈЗЏ+ 5 dэШLNш:АuєдС§щ.тє,™єuыыkш>фKRgРF,Дїrі-›“{u}~У*[МЖA6kзbхМрљьу[‹|ъ.ЩX№ТР[Р7cСЫЬ^.жЇUД(ЭfАZ‚[0‹DЏ.pЦЭ7АћКB/rВOlиН?ыТЯН‡\>[оv…ояС‘нјm]Пют™œ-ОШ:—+Iв;+—Вюч|sfУgŸUPD59йЧЖќћјЮЏЯ–ќr}ук53ŸZрдЦ•iзo\пyф,|ЏпИВqmZеіU4ƒe bСd,њŸљљ 'FЬ9}&їПЁКгѕ]тОу$.з‘‹Ÿ^pЮк!ЮJ€ыZ’wИЎVIr|Оо~ћ?Vз/юи~Ў+ќГЇТсK—-їЪяАwЛн§л4ЇўР (ьЌв?ќv4‚$l1nPЯ=Ї.‚ fћЮœЗFWаi!ЙћФijцјЙ uєˆэЧфЧ[ѕjIŽяšўQEБ\і:Э  њ#ФЂj9в’1Л.ќшмПЛbїЁwtт‰цxгzѕŽž,цКR‚ђ- )ѓдЃ”Ўц_еЃ8|‡<и6Nfg™ Q u!эMbЎ^ЛЪЬ4kЙъИZ={§fАŠ‚XЈ– ЫЉ њЋЋ€ЙЊ{4Iые;В,”ыš[DВЏI­l$МŒ”8Ў.“ЌЮL’НкнЌ—Ѕi+’‹мОIТТ‰UŽц?Эš6лАgПЪa4‹…R‹ —І S6Г7ѓВЗйs7ƒULBЕbИœђ@€CХ"УQЏ ЎЋoЅА—8\пL?jтЄ/ЭvРЌ@Р;Ѕв—.qўъ„/§GŽRU%С }ёИE„oњтљ†іќЭPUI3БVB(qŒwp]UѕІL›>6Б/lчJЇOIЯMƒдЇFм,МкЄu‡IЉ{ПЊrAВK^уњі,u•žєьЌОJЭИYsв—,Lън ”F%ARyжWцo†oо а˜ŒEBW`fтїM€МП#?]“їuНqЧ}Ж‡,qdі:WОЏk>)Л!яыZv8ЏЧ-GТ,изе!nї;˜5БeН Иjы`Ќ…№Ў9ž#ИміUЙЕЖКрЗ шђ"зЕ^мbšŽСщBрfхѓ"ЏvсМШ фКzС2 3ѓ" чE^WJхКтэœз8:af^„Я.r]1Њџ&c‘а;:sЭ5SЏfЈ 2ЬЬ‹DПеQР:›цшrж‹\WMєBA‰БШx”9cQ@ИЎА$mм  3yuŠD5fbT єŽbWŸДŒф зUЋэЈЋы˜‰EЂW8c‚&ф"ђ‚ыЊйxTжq0gCЎЋ1”Aja&с{М.Š€p]Y‰yѓ€ЉšЕ%“j4™Є0RZСRаЪ•]‡пz2ћш„§r \Іƒс0lˆ<Ц"zg, зѕф—G_ју№YKW—­Њ‚IЪChхЬЎЧoM›імЄй/Ш+JџЧўœoNшЁЪz3Бpњ4j]Їq]ч­^ЛэѕЕKоћ юA ЂШ“„VЮьzќV‰cfЬъ; ‘‡ХDjGˆEеr$%зUєъgLаBѓyi ОGOuтКn[џжЇЧ0‚ђMZ9Гыё[—lќри—_ŒјHrBoмг3м ЉZ..ЇШ*‹!є]хѓ=2DХuнАћŸSF§AВкшЮyPОIB+gv=~+јѓВ › 0AJћKъžЪ§ШXЧQЈV,—Sr]EЏ.˜'ў7gНтКТ8вОЬЭ;пYGЬЯ$е$ДrfзуЗЖрŠЬЅ•п§№пRџ0 ю\‹ŒЧ—ћЗІ€q]С‘вwэOMщКKЦNЦЯ$е$ДrfзуЗ>:pаЂIЩ?ќ№У§э:МКюcМBЯТL,Д„Ў.@LрО е#) o]цКЊсРt рaЙRp9%зUєъ‚п.ˆ Ш‹\з@_™ѕІ

ZwPгn r]Ыq]hGїшМчŒМН,№dгwxі‡…Э3йЎЕћ.]ЖВ]k[6їJVnbЋsнгB,Њ–#)ЙЎа›šбˆф{єŒi(q]с–Œ~iїс2šљд“pчЪў-›п,Іzи@VЙ?Ќ+BЈ FоЕV•"SНњTЫ…+Uч„ўъЪЛVІjcyв|^Z‚я‘еR\Wе&‹ІŽŸЖpЩklГDXмwфб),@ГUюЫА 2ЁZБ\NЩuНКР9?б!yC™ыZZZj‘$‹de†ѓ=лWЪќYКŸlљўАšCJ“БHшљxтп€qз \W2И­ЅkSi!ЅeЎ>QEНЂœФоŽ4'Х7Hёb$QMˆt!сU4†r]їэњ^‚f@V+lо:0.zбДЉ@>еЫKЙЎIн;йl‘lѓVЮьРuЕ5Ž„Н\сkk|лЫ•r]n§Vкb=Ўы‚5k/›дQ#КєшСšm€–$uщ4юБž]њ<ЪєA&@,ђ›_$zuт ї­&y‘ыЊ=”в~s]$ŒEž+ЙЎ,BL2‹D{‘€Йцшѓз‹\WMƒ^if^$šсїэŒЂ˜МШu z‡бь ™5:(PшL№эjmхEЎЋяXŸЦL,ЭŒO|ЧиLНОЅЁ&ј09/њЋ+ФП/hy‘ы|юСй#3БЊzGчЗ ACф­uЎ+чћgіј—1r™‰Eјь‚з‚\W/8B)БШxДyуr]Б N 3БHєъBm­Гqж‹\зрtŽ^a,2‰3езц$šЖъ1L5wbѕUеДрJэ?PMЉаЫВM•šсQ‰€™Xх]]рŒ Ъю1Y@оšуКB/rВmљїq –ќr}ук5Д_z SЭX}•}ыідI(ЪYфX5w0@>{ьdŸ§AЈ‚ІJkЧ#CРL,НКРXп”‚€МŽЛVлн„aiЙ9m‡drпL&MяTм§мОMюуG~Д’МOэЎBЫ‰ѕЖН/JП:”ЭSЪYfЎ“К*sGїў˜>uё"k#+|S/;ќб6ЊџРсŽ=ухЌx;ћ№!Њ/)Ос,vи›ичІ­вSіxЌ_NЖМлёї†KсG>Ы9чФ‰}ћpјЃнЪJi!xдDc‘&,^JЧєŽгуКBJЦ(HiЅ0xš SЭX}•z&\8™ EэћјУщя|њэ ƒє TASЅЕу‘!`&‰^]O.JжЋwd–”ыšGЪОf‹lh А•8‰ЋЫ$Ћ3з’НšиšXšЖ"’DЪЪ7uДЦАŒ*AоŽђЃнЪ7ц€0FЉЬ…€@Je`˜Ž7!ы›\`žОќГМcdљ‡юФ o>˜ѕкŠД9sѕ”Уюkеъшg{УУЅю§\eЅ' ЅpSš*Э •Rš`,в„ХKЩ9ЇЊ9Ў+ДFsУV=†ЉцNЌšЪо§žXЗxбрQ„*џук…s{ї‚v>DhЊ^#эoТL,‚:…Ў.дn,т@ИІИЎPЕ&‰UaЊЩNеTіx4юмњUРф ђэ|B„ІJ;kђh&Съ‚а7iAL№л‘ф­9Ў+ЌtЋоbrд1{Р№›ыŠkt^c\W/8B)a&‰^]рœŸhŸ˜МШuе?ш•&чEB™~пЮС(ŠЩ[C\WМЋу~Бˆп‘РRљ>:шšае1ёФwРЬд‹\W_<ƒOУяB№Т-p9BНHLїрьЦ"c 8]WзiЇЦc&жТd,zGgf~" /r]Х^КuЈ6“БHшgLаDWD^рКBнe$мFH„K‚чх$"YlРо“,Ф%ПxlќM[ щTAž%ЪnеlЈ Ѕ*FБ•НsйGп{+§ћуЇУџWxŸўІ,X Я†ГzœП:Ї zєjўUfЯNЁР‰ЎбХЧъз<}YЧЖПГсN…]ы€ЁоаЖxЦ$v „-kVšшЅQžE™“БHшˆxЂ…gН5ЪuЭкВіЅ{~*џhR_Ек.ы–}йНO<Љ !шЙљ !(1Ы‚+йџ>œ4iг р8/23е,зѕ›3>ћќЋ‚"к\Mъ+œоЙ=l0 л я|GоВХїsіЋЃПыйщп^:к‹ѓIІ@СLЦ"œy@ЏфКЦЩ)x§ТЁ™C†YœŽМsЧ6ХFй$Ћ#яУ Ўы юфw]їк=™p]ЗНОИЎ@bъд йŽ Є,дraYъшЯО0d6Б)Иœїњтљ%Х%ЯОД€•шa—Ёєe6|Ю?zЋфVТЁ4‰GПРy‘1t4щ=љk’ы ћ‚y*вЁО2ƒ˜6q‹36ян–Щ4 œ;}jюИф%ы70кьк%‹gОМXiƒВ˜ŒE!4/ЂГ#п#УНFЙЎЌ*hR_U6ЅЄœT[Ў=КoяВЉS–Мћ2О§pцќ3ƒ‡РЪ]мS-ёЉJУdрМЈ p*NqЮ‹j”ыЊjЅ&ѕUfГ^Юƒ7`Щ›ЋО0mР№$š –"ж-]ДrЧЧqэ=ЗˆpŠ­цб[AvCЈЊ “†˜ŒE8/R" \W ьыZтrЛЪШ…ђ}]лEY‰Еr_WgљОЎ šВпxіuMMщКKЦNеX@ЃдзRW)И лПѕбСУЅN§сЛѓ№Ъ„ўПХ6fM_јДђщ>žE…УW~І/WPЖeП09/BЎЋљšуКzъ@ЉЎ"р7з:Bѓ"УсCЎЋ!DСj€ѓ"у‘хœAAШu5F3-p^d<ЊœЯ.@A5Фu5n"Zд*&чEBяшјc‚/ЄЕ•ЙЎОc|“БHЈёЧпqЊ­МО-AM№!`r^$tЅт‰пЮ /r]ƒЯ=8{„БШ(Nз зеИ5ЕdЩ•уюЎZј›ŒEBяшjknУYЏHЎЋјЋy§’ХГ^[‰Я7h9СXЄ ‹—’3ћКŠПšџѓ§їн@qяУ^уQї‹ŒЧ„;E–6,$’ѓ–ЅакаFGYўЩ›oI…VЋэ>{дЛяЯtXrйKЪ\’ХУй6nAАј­є7Є!щЦ"=dиО ^†ЧUщЧwЇWYЏeLЋƒ#§‚hQЪ#œRжImfЎVЫ•хд#c‘ё`qЦЂ@q]sОќ6ƒз$ yrфєфЄc‡ПLпЩŸ1rљ‹3UЭнњЦš+—.n9№ХŽgJ7ий7vуЪДы7Ўя_oП§Ћыwl?‡зўsяЛt™вZнnwџ–ЭН’mšSв8˜бЋжЭвw|Ьˆw"Й3чБ/9ОkњG6@Lnьіcп‚%ф3cVп‰ЬRVъГСF)г•GUэм}т4mЁЊvп–+ЫЉG2ФЂj9в’1Л.ќшмП;‘і1„жшhDђ=z;@\WЦ ЇфЏdхž“ЌRyїе&›[*уЊу*s30†,4ЛяNЏ з3f5њ р'єЫN)kЅfэz-g…д#ЁZ..ЇъšP/тœŸЈšH“цѓв|ЌК@q]Y<‚МћЊбІЋЭьЭМИБіŠma5Зе3ЎЂ1є6ЦFM3Џк+7ЅхiЙfiuP‰ѓ"уAсœŠыjм …ХбcвЮw9мwмАЬ 8ухZ/qоtТ7}ё|Hвsš;Нъ{Š#$ЊQs Ѕ^OжdцђД\ЏРКІЧXd<"мq,`ћКЗЉвbьѓГ[Жk?nр#Ѓ{tnмДqЅкы/^m#“zw‚Џ­ё}ŒЋЙгЋžБВФ”iгЧ&і…Л8ЅВ YsSZž–WQf:e2 ]]€˜Р}AЋAЙЎjаЫгрlUмьifЉJфКŒЇы"зеЧр=m2 ]]рœŸh–˜МШuе?ш•&чEB™œ1AsЬФфEЎЋ/јЁp;Бˆп‘РїuѕНNЊв зЕ*t‚хП сОЎС2ци@#`r^$єŽNР:›&Мœѕ"зUНPPb,2eЮ9U]рКђџ†cмm# ‘uЕЅ–Я›ŒEИFч?‘\WO­|^ё|8љi…БШ8ЮX$’ыЪЭщЁАPЦ0/`,2ЦœѓЗІКАЏЋqgаЂРXd *g, (зЕЋŠм ­мњњšђ '[РSЄ№ь)hh ‚Ѓ2"iK=ZTV(J›їЊТц.Y9я…эZ ї№jСxPJ=Ћ оЎЊ’њ˜ФXd ŽЪ6Mb)ыЄ&•Юjђ^Y.*IЖф—[;П>ЛхГу9йŸГГ[жЎv•мкyђь–УЧsNczЊХлUfЌ_ВЩX$єiдКŽl€ИЎ‡/]Жм+ПлDцКV’[“КІXСW‚УИA=їœК6№џ^щBд$–23=*Ћ&яUИ’W ЬˆQ=КбЊe§ю)YPЉ‡JНˆК:М]U-ѕ1 БЈZŽЄтК†аяEєW#пЃgдЫЙЎm%ђгэb!3v‘щ]myёё}ЅœфьЮиЦПГ”5"RИхЮuт, :Л#S‚beЎk%ЙѕjўUИj=uщЏI,eѕЈЌР{}?#}гЪД№џ9kщ’ю§@pš‘z‹ЬNm^СЋUl•ЌUЅђzuUЩЪЎБЖеcС‘Пsе'œэядБ“ЪR0U†HrЮO4Ћ2Ÿ—–р{dеQЎknЩО&ЕВ‘№2RтtККLВ:3IіjwГ^–І­Hў-rћ& 'V š7+ЪWfш†=ћULl_3а@4 з:p`!—Ъ†RY=оМW0† Rк_Rїœ’_Ь Œr”йЉŠТYЩr™…БШˆxЫr“pімйолЙWбЛ4™LйVi€ПyаЈQЎыЈ‰“VМ4[&‡п%№>-X` ћвN5‰ЅЌ•zTVMо+ЫE9яв%Ю_+8Гь,ш7Є•ыu‚г‡œЗр№Й_gХGц;EGaљЗ@ўјТ"д‹ЬЧп№hИы­AЎkвsг€1šњдˆqб‹ІMš*mЙ/эT“XЪКЉGeефНВ\T€ dmЖШЄ.Ц=жГKŸGйY(S’Ъѕ}{vyЈЫ=сь \]] sЎvљ Ш‹\W@НрJСмqЩл~э3СЌиЙ*MОЃƒ@Н”ч{.и[ўШ/а,—iВL6иКmыХ3mkэMZм1ЁМоyC™ы /Nq—пщННt~џСCМБЧ”Bяш ž4GџД˜М!Ыumм4vtпžђлQl‘ьэ(њЃgМЁ5:Џ~ы$B–ы:l\ |uPAЕ‹ BЎЋ@xšЁ^$`nЃ9Іfъе,•ˆ€Ёwtжй”}c2gНШueˆЁP-0yр 5ЎЋЇч(™C@Ј‰Ygѓ„Г^фКњB‡„z‘™љ‰ˆМїuecУeMAѕDœІ *k Ё^Ф4БЙЎšШЃвЁ^$"žhѕ˜Го чКBм+чЎЊyИ\" д‹ќv!@V@^фКжЧ+И.ДчE^Ѓ€\W/80С‡Ц"/œыъ&јРXd€r] Тг„ѕ"sЭ15SЏfЈD”НЃАЮІь“9ыEЎ+C …j! д‹ЬФyы*’д9щ§œїzХіОX|ёzЩu@ѓXўПџдkъŠЏ_пuтœ§жії ‡ЌƒеoKyM?ˆ€а;:ˆ ~#. or]§ю8fЌћѕ"ёDqоzkr_W|у‚ца‡RшчќDYyыzн§"9oY ­ Нq—8ЪђOоtо’ ­Vл}іЈw{юЗ[ь‡.-)sХZЊEзь*ы:oВчiЂP/т Z ИЎ{яMЛ8Ш™иd˜ƒ\zП(Mj>БЭєЖq­Ђ›‡3ѓтои‰БVk„ЖAЬ™їЗЕл2жо,МкКm‡—взЧД‰ЃˆщЃ@ Ї.]žљЦъRWщ€сIs—­B>ЙжА вuъиiыЖ­œ•ёХ3.ЅБP/O”}c2gНРuЕ4N:?юд№Л%І{Ѓ~№ъk˜-БQŠ‹8йŸvЭъ~awьK%нЦ9#:АђUнUВкvМЛiљь™ы?йžnЃ|”Вфdлђяу ЌxaкЦЕkž}aЖЊLŠCР;yLGg“kaЯq;9Љl›аW”зEљ.‘7ЎqЙŽ\,јє‚sцаqVтtф•фŒ…7ўH’уѓѕілџБК~qЧіs$ПыКзюл №–У—.гэнnwџ6ЭП*(3•Arї‰гіц1pЪёsAъшл}ы[jФ Рщ<дСN9ЗЏЪН№ЃsџюŠ'’…Ў.@L№ѓyi ОGO“Dq]iд…@Ж7‰ЙzэЊЇ( Gƒп‘тЃе7ѓBНHРмFZЏо‘eЁ\зќ;Rі5[dC[x„­"S—IVgЎ%{5Б5Б4m%%р=u№БЪaФЬBЭю(,hжД™™Ђ0ЏIР1xnфX,RU'д‹ЬЧUы9“œѕж(з5ЊQsкьєЅKœП:с Bџ‘Ѓ8ћ‚f5€ЩX$tuЁvcњ5ШuM™6}lbпп~§­1tщбk\пžtюйY 8š‡&5…Ц"cd9cхКJхo0e\зI­ђdŠ+p]%‰"D*%№;воr<ЕYГbц$є,K&MvрвO, g“ž™ДчЬEPЮ]ЫмšXŠSb,2Цš3"зеЪ ЕРXd<АœБ BЎЋ1šСhБШxT9c$ŒыЊМЕ3юZд0‹ŒцEОe!зе“рг˜ŒEBWКљc‚я8еV^п– &јРXd<ІœБИЎ'ЯdZяКѓ.юrž*ИМwчс—ГВзXя8р›ѕхHžћnШ@цУO0!`2сяEž‹ЙЎ,BLТXd<рœБЙЎЦPЉ…ЩX„ѓ"Хu ЎkСхМљ“RЖk_ ЉЈУЌ я ПќЊ>ю;ю ƒћЛuТгтє;ќСі№Z}xТˆZ‚ЃЪJ•&4“‹ŒЧ;E–6,ЌфКкHCЪu=шсК>О?sаaЩeЎЋЄУu…Ћ|Fв№G=žѕM.|A€Єъ :уы[Р“рѕю“Е;SeђЩЖMuщJАŒп-GŽKaRњKк’Э™ѕЁ:ЃЊœаLb,2wЮѕН€ьыњСпVЅ}ћ0 [iPR\ыКяЬyК* Ы_еРВh ŸŸЙ}}:œкўЮ†‰і DДœп§Дhн&zъь М™hймйьKmziŒEЦcЮ9/ зuќ_^€їcм‘ з(|юиIPВVjR\GMœДтЅйрW0c%X``іzBї~ О~№“Н…џчzЧ> zfšњ˜–1ЃR&І/YЈy6•&cQ˜HШ8ч'šM’їџoяJ€ЃЈв№Ћ’Њ™ˆeSKV4АШЉl8дЎ”—›T„АPVpГA9d‘%a#ЂFСƒ…\ tбUD–„ К ШP2["“кPЕ_Я›yгщcњѕy]S=ЏџўпѕїџЯџњЭћоЌ+lkЗюzmљт• %}АO_\ВQ(šзGЇfуVЮуЃА‹]ЫЖЩY9в,‚с‘5=wюєЩЫ^}гSЭ0<3уpж?еєшЄ„ш‹,нI >!hcА яўЏЩй R\зKзj+ё_eГЈзIO\зsЄю’зЕю'тњ‰8Џ:3зе­ГБcEФ †[Ф­‘@Х‰rS†єьЌљNZТљŸšРКњee)S&„сŸB<–Ўт|?Q4‘^Z“W`]5…пф‰тНШјѓ##uУ9уЇеТK=?&АЎЦђНљ9BєE–Žшј}‚њЙ4T^uKЅщI@ј"уgЪщ‹жеX”M”Cј"уЫщЧ€u}хp^м-q]?ЏмЗљдц//|љЩfяš\~Йq]kъjзuЩљЖЕЕ7МЫЎЋo˜ao­hМMОШјйpњ"u5eхОШјСrњ"Ќ+] ŠГjŠVиГ8{ ==bЈк€ЛРѕm%ЁŒћsSqpКANЖu]ј"cСrћЂ0`]бКT5•0Аъошћ*Юц.]ўщ›хMЬnЮђ|œхD‘ЖFТЫ™г…ыЪZЃ€š;х™ьсeФо‹Ў2`С5c.љLB7 ŸsЩЁƒŒŽ_h5ж5їёБїј—;/:Б\\UЅwƒ‡§xсI ŒsєІЅЉЫЁt]ŒэЦ уzнї€Е“&ађ‰ƒ– pюўRЈ‡С™ЙЌИ7mŠД)E[iS зi€šёг’йЅК ЪтYј"crњЂА`]ѕZ lПacѕююмX8zт$м=eвЮ7 хl4JЌы:щЯ9 ќНwж­ЪјSvкШБeЅRАQзeчЪй3)ъЁьpIŸAiiъr@„Б=vЂpяЇЃ€MодМьЉYЯЮнWqЙр§Ž;‚[є_fъœ)чœ‰“ЦMšV\vЈо6эю-Ь“жьЊйфХЪгъ*фwƒN _d,:N_Ќ+kj*a`cUP7~žП9v,}ЄdcщCЧ" їТЪQc]ƒˆБлЉ;Т@ёЋOŒx*#ѕсўАфкЗswŒ=цѓНХH?r$Е_Z”Ка`lsц/мІчРFш9&&ІІњP‰‰-gч­”пbщЗїшв3ˆC z3gЬ<$л‚ёH№T Ло-с‹є$уЇS_Єwіѓ…ыŠв0ќРG5MHLpЙ”ЋiеlzЗњruп$ЯXI-Ц†>ЌUšXзI9ЙV/Šž™ькгёmЩ!Pіь|o~СыО/Нt:-JГœ[РдiFœѕиhOйpkёяўь_™ƒ`YђйЧ,Л<ег‘bD‡\л$U_ёЃzхlziž*єђ ‡ш‹ЂhM7ѕHъ3.ХКžОL]АпGbъHЫх‰ыZD­ЊНЛ—зѕмUђЫв,&@\W:>aХвDŸ~iŸя.ЊGA,oїІЂэGЫёћMoСM2@ŠЎч‰GІфї\ї˜іЪъeoЌЬћЊфиьЅ †`HwJ[šьމБїшяxыЅх%>tЭ(лТ]Щ F“YMбSМь--”ьo/yЩйUЊ5}сгOe/XМ|Р&ј" ;ƒ]ГFD^C„vкxЖЅ8yЊа.0 UјЂ€тёмф|/ жUЏ5€ЛЎ_›ш+6^„хT|]ŽYo0cћžЮЉ}˜ ‚tч]Џ(JЯЪЮ}gMAVю flНћ^Зhс1O€aШШ'ђЬю=ppрB81Жœl€шJлtн вўџѓФ&Dаіњѕы6ЛнfЗaЛbоLж<[rЗ”-oЎ‡!с5ЏрљŒMГ v7ш„№EЦЂу|/"$ XWНжHи-;п^ЕјхХЯC“кvю<>;Ь;жП5iЮsŠ\Ѓ2'ОЕzMњнй‰П™Н]ЇvєmŠfO}ШQАdnПaУq‰ѓŠ3RосePŸ91Жœl zdaжИяПџО]ЇфП­{VЇh;ѕкќE <7ў cб}[пзd›Лb Ж +\іТн­ыБiVЁю—Y |QiљЩВMяfькЅkJr›РКњbже_YШ)Ь1Ъ1tXШ%‰HХонe'ЫцЯ5ŽQЗ,†ДyЃ[ŽukК§:ЌkЇ{l‡/Jpё;Ш:—Ћ†~ИЯJˆёf?Ia’!ЕnRл~xpqM!Ї№oЬХЪJaB! в[€з„05њ<9сI0+ъЕдŠ8пOMЄ—жфН)АЎ˜нкА&^ўп5%ˆ!H+Œ ?ХGбFяUЄHc]UCPЬŒS„ШЃ%ZЬ‹u_d 6u5PSК]8—””Є1РгъЏЅVФ=WІбв†ЪЋбAjЊЈУfiоORщ,щьЃxZ}ЗдŠЌyЗQw“Г^uU‹.Њ(nBш'Љ}{жqЄ ЭУR+j(ТYoЃТКВe5šM#"Мн эe&Dk‘(ž[вYыАtv>SЁеMЕ /АЎ„иkjнqБ1јw=ОyќДЇuHш0zзргЎгэZ'eІL=р,ўж§•НЮэЎuлnїЏ4S7XPn: И1x#ЄќыruЫщ-5R,ЕЂ MmЕ"/АЎЈЉŽФФвмmЏЛNьФn‹Л3!оn#n{ѕs‡ŸКяЎЖ€!•VUиЕWhыIZаП0ЛдaщˆŽѓ§DГ#ф…Е„зUГё‚x“HР№Я"0h–Z‘ўDЃМ~,vЋуœ9/-9ё…лџБgЧvљu(мlјW_aт;дЫДpЋ™-§5 нŸш[€[œѕыъш@ж$ё˜рЖ“јfdЯЙиJЗkXѓ2ї›#‹И€&УЩЯ‰л&Ÿ›МG]щРбcЙuЮЪеА‡‚Eѓo>6yŠлUSЗ„бхиЯТѕvќ†”3юX{BqrsšѓЗЅ‰‰­ЊўSёіЫkHpqq„.p­#EuQф‹=зКж• щhЛџ.o#зым}.їJp‘ФNфЎR}‰TW’иx’а’иo%žџ–д…`П„ИИјGЛwЭ|Иgї>1€7П,ўл L3И{ŸTFЇиЯОmZфŒе=еOЇ 0Є‚mэйЖѓ  Р–с_uhБ0ћi?Y9" д_ЊБЕŽhО> ЌЋ_ј‘РКbF[ќ"nЌЉ­+ѓ$_TЇ§wМеUxƒ:uЂЃыjщˆ.шЉtУ‚М"ЎЋ\]Ђ04ОШR+т|?б|~жфЅXз8;љ] [\l+g‹ їmq‰еGHѕUrњ в1ИЎJ#:,И ИC•fББKР3ЕC1ŠІžЏ<Џ Ш/-Е" ќ‰Мo,Э_oиБЎb8ЧžТM№ЌF=цŒfƒ"§nъ–Ю.РŸшЗФрNCхXWƒг„nУPшч ЬЦw Эшz–dЉёћ_ќп •зп‘jђ` ЂфЬw’!IgQр‹в uXWьд›žќhiEqblkз5ч‘Њ#v{\FЗ ф-:ZфЎЋщ˜иебЦQлX`кЛgЏeйR„}A|,{ћсє” ‹i­ѕхі†:Х%snєЛŒP„Sж€ЈJь ^cЊ),џГт–Ѕ#:МŸp*ДЂ•ИД /АЎЖ[ь%Ў]ohkеуŽўиК$ЖY\њnтz$qМы`qoЗЗОі]Эƒ™ЎцЩъFЪ)qЕeуњЖн:S"0­3/џыKыАЦqуKЋЯtіji96УЦ"НbVЖМ„РiD8Йb­#-Эщt"Дkњш€aZ—ѕwi0ˆLЬ›‰B—ЋQ/›%ХrQmŒЯђШд.9™х›FZъ~bk)њЭe—8GV‘бIjfЕёйY%ЋQЉ qТ-Јфd6лжЦЯюO™аХеВU ЉчШI r:IXиЫ”юiŒшрX<ЋФЫЉКXхgЊ5^UюgnЉ*Ї§€ъФ^”LHœ#'DЙ F'9цмЙ№[‘OУЭY…9n_ќпћ?оцєДtœЭІљk ‚3rЊ#Jf№=ГZf–пWЩo _DKPc-ˆтќy§ѕсvoВmJіaC‡с•RЭІ•e…яZx! $@—YdќЊВ2шZ‘| дт]2•ШЎ,KрЈНцЂ§5›YJ `П—(Sджх}ѕеЯX'eќ’!ФzЦFїX‘п*ќp }”…[жbЃJ›д}a<HРЋ12ѕубI(V'!…"pшZГ!y FŒ@K Š<јХAp8њ:p6›6(:ДлQы,0&[њˆ˜њqъ$уgOЖ'Ч1zˆ §Е >XZxЋёН  yхŠ[aП$яBЌ^sщА7†шщО•ЪЕu)дЯДNњ•/фcч§жїE2я  EђяЅПъТ-д–Ял>GЏзif‡й4ЭЁ3ћНŒZЗ@єйЩеG'хќ(/dVUt­H1ЛP~Ђ<Й[В‚(ЏLМY LQkЈ^MЋџюmЈ“ruГќRЎКЁЇѕ­ˆ(чкЫO%*ЂПѕ{шЇ‡)UzМ%ЅtOСйl:LMа.F№‰оЄNњде@u}Ѕ§­kEAc-‚nŠaFМ 9/zufг†…ЭЕўСуaВЅOЧЌNšхZt­Шt‰ћJš.S–k4œОиfгВbТŸДR™ЂЖЎ№?ЖА–ЈaEXхŠ%zX_Ф_‘ццХќйojNі{Е*n"Ї“šx!Г ЉaEteж•IаB8™Э6ЎёѓЃћ0 AФ9‚ˆœNт вТCQЖzјЂ—змѓ‰ѓО{D№ьPD*ђ6} \4єсФщй]hWыљ"U2ЄІ/бC!$ 7!ѓ Ј(7ЕоьIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/30.png0000644000175000017500000017360011733011756026236 0ustar sylvestresylvestre‰PNG  IHDRпЮўтш­РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН\TхЖџПq_ ъНж—QTР“ЂT‚ќЧHГ#hЅ%ўЉМJi‚’yШЄ@ cˆьhа=•t;&ѓ_*˜ќƒ HхЮ=!:œИЏŒсѕЃзљ­Э63{†A˜Э |іkПЦЕзГžЕжѓdЯѓЬоПЉћG‡@@@,†€-w6—Y/eYLVH@@@`и8§ЧaЬЖТ?Tš<В*}иaР€A@@,†РЌ—’…х7%Ѕ%‘йŸSiвмвj1щ!aGрFйЇЗџљCAмB[яiї9 ]3ь0`Р   F€*[ЭЯэBVVЈ$›oжp-jЎЃ/E­‚sP9Ž™2P9Р€€X2ўVіпCџљ lT™hї№™uДє??цЁљfТ–sє хJІь]аД6з\hnЈrукЛ1,@@@Рš єџГВџњЯЯ9ˆЋƒЖUюuЖНСM]FЧиŸЯ_kQ4yДэx їoœ}шVщn?З:њ>Х)ьЄ[ iJЧ)7.•p†, ЁB џŸ•§їа–fШAT˜’Ÿ­ТССAaтZM_K!Уs-П{P3ЯU9’Џxцl9cJО'6Я4н˜9їЫЬ@Œ4щXт@@Є єџГВџЄ3ы‹v sU'"Q/Ѓ6šЬ№Vд8ŒrИљ“Fsѓj[Хa ПЁDaoЈ—-gЏчХE‘O)З1ѓм•#ЙЭžiЙЅ~`їFeŠCВy`”кtcцSмK,3A0вЄc‰KшA џŸ•§їа#ЁЛК0CRU€~nnГ9лV‡QœbЄbЬ=c4 •)-œ}ЃbЊО­љ4TšаЁiUѓ Ч9кЖ7w˜Дrф`Ћ1н˜<ЯyыЬУЃъhпŒ­vЇАFš:гФ €€€@п˜Tипчъ1Ž{jІЋ]}}э”ћЇд]ЏЛЉQ6З™НPH&Вou.KпWы˜uЮИHє=ё:ПFCGVьRz§АКр…iЕэы>И АU~ХŸ”ѓw”гŒЮЛ+мэШрЛык}О[bУЉЕНƒ;sU§жбZaS‹р jЂC|й)ЯŒмБOhъ~Ех^м}І‡ЪN лђз~*•вЎѕNћО‹ъПж>"€e.јaЛнBІ$>яL!!њЌдѕ ѓ9+і&ўЬy›м,ƒ8љ+ф ў˜еѕ.ЮQѓsk]}ыDзНŸюѕђ limiс7ЎRЉa 9ћћЩ\S‹­“HA_:ъКѓVљ‰зљdsю эPДо™цюd7бЖ}т§ЎBЌХp_QВѕЧнЊS№щёGyeэЏkч>ь2нEsЇ}ЧIЕ Їз­тEёЅ=ЇИж!ўТ‘нК™ю!гTЅы­}zІћЬщ.]~ь–?ьёЈŠЊŸєЋњЛD<ъNГ:џ§uw ђъњНgj5эš}X“ъђA@†"г>+%FЮ>+ћтЁЧg.ѓ сН*9P9ВєCэчрОДŸШ&ц`ћФ“ѓ8—^QpЅŠЗћЇNy`ŠЂ^qѓ[5}…ЧФ Вф_ШŒuшhbс VгНр8–=гš;јкЅќjЊhR'РУЎОЉнЮV№[е­jЊTjПЏwАmБЗежЇ/_бќЪИPKѕФЬiЊOЮдош*;ШЬбV)8$ŸТЅ], šаi<мѓWЎP %xєєК`:пtсl5нпхѓЫѕ!AюOљЉŽ^ЈЛб™*5?{ћ•kы,цm5,"ѓ@@„@фћењ~„\}Н94єБ.|шг+“)db’ ињјњ–ўГГ‰j#ЧЏ-jЕТЩЩ)Р' ІЖF­юЌ†ŒtБ•оBЅ‰юd еb%_‚йŸwiсјzтЏпЗRu2EЅЄЂфLu=_xИ{5ђїуЏЉ­учWКвkЙЃЙб1ІYУЇD_љЋhiжˆ&EКЬДЃ_і”Е_Шчам* -ЇъєЗ:„!ь ЄnжhoмBГ&|œRУЯ9™4БФ\Aš |Vі>Xњx>+ xаџЈеѕЩ<ш6є§Z*V”АYЁ4щ‘˜сlWОАЊ4ЛѓNіFѓqsquw>hiХЁ]гЎiwэЇ§Ќ•юЋЛ:гiEъњzБвдщ˜ЏыZi+‰ПЗЛGћ`Ј™9›щэBЪšыj*_„‰ ъ0RЁiЕГщ@2m ЁЕіЖ=Ђ8ŽдOIbHД`DŠУHк™ЋѕЦŒд­|’§ўО›ФЄs€ТМ’(†Г3Š‹9ƒ  0|˜єЄ‡Cќ)ІяAќЉ*ю*ж‹=ˆmюNжЯFZїН  ˆ|П–уьZlЕы;]1 ц`у>йНЫШиП-ъКкдЖwДгОš8ЙЉОyѓнЅорЭя%в4ц^мІ0ЕowсZЋj4?ђ›з[џVЯЯšаeэ55­уhи,ЧЭђёЄEЈeќ—+Wi? Ј[љфЇќж•6еО4“э щl3№Rr•Ÿ1 yc†ћ*ыIž;3@swbЊ‹ъљ…ЁT!й3    а“€ЉŸw={u^i?+ћяAТwU†r`Ѕ љ+XэЎWšкр'>ЭЊ˜t8(Њ{ЕћN<==•ѕЪЊoktїaBп=1чЎ“ћžЎm9YYпиЊљЕхF‡ku}ћ4Лš№…‚ИѓŸюОgК;ЅJЛV_Ивв9ЗБэX]ќ<з№љ3УMЮѓн3MЎ#Й™б~Xн’юГ j%ЇЁ)ЙыChђцЪ­]Є4и_b2]‚€Р№#`ђчЁoџ=HИюЃJ*VšаЌ •&ф‘44›ЂыZЊ/йˆЋуѕнх„?јŠD8љ Ц{uЇA99tЈ…™VPВK‘ сvNVѕУŠšЮˆдЪ|љ]ыеœ™ШЉ;SџѕчZMhš9‡6~;ЊЂЋ я˜lЈdQ№ƒ’Z/зЕЧНfЂmK—žš:лЛ{‰=tFьроЏžущšTшЉЅ+qЎzТŒ‹СОіP€€€ЕјМыхSR)џщ-єэП‡ўГ35нЁuB7‡оЊл1Э?…hЈ:Ййтш№ФйWZiЏбмЇсlе7nVД5аjч8^{WnїЖl™Є[gЊд[RІњ€€X2ўVіпCџљ˜!Q! YЊіЃTмЈЕьkБЭBУ(ўRкss™ЉŽ@/:4єe]uЏ—ДёжШО“^ЛУ@@Ќ†@џ?+ћяЁџАЬCwIЂрш&-w(TЭuѕŽЎ.}*PЈ iО^oЏ ­ЏšЬР ž@@@`РєџГВџњ?3фа]є?=БХ(%=8Аё%nѕ/6г—эJъЋЏ‡@@†ўVіпCџ‘š#sU'4ZJ—Юў@@@`Јшџgeџ=єŸэ€ч [4џФпh€€€ШFРёО”щQPiђ—н{ДЫ–€€ O‹ kХŠЭ№Є€Qƒ€€X,T'ћж 1ІlЪЋщ†Џ8@@@@Р"Peb3s†ПEф‚$@@@@€уЈ2БбќмљШ_р @• іXРћ€@@@DPˆ`@АЈN,рM@   "ЈND0 ‚€€XT'№& лъzшВwqšŸ_яFАk P}ёЂNšјёж‚KњПoЛЕ}ѕЄТИ…~k_cш{€€ЁB?оƒўж !FРая[#УДЁЇiF€€€ШLРЦ~dŸчNdNс@@@†G'Уъ Ч`A@@Рт аЪŽХчˆA@@†›БJЛс4^Œ@@@Рв иŒСІXK€€ /6#‡з€1Z '`ЃФЎX ‹€€ 36иv2Ьоr @@,œ€цN,ќ-Bz   0ЬиšiюЄќт…КККaУЕЎЎЎў~‘ ’‹@yѕ•Њ+UrEC-/O/џižцРaЋьhpПBi2Х}Ъ€{†Cш•@Mm й @щд1J“ШˆШ!3" Ќ…@AaЅjŽХV}M=рhж„Jzі1ўš‘dKХ&щGN?•Ф64dnIщqT'§$iEнщП•&gОjн_|ХŠвFЊ `еТ–x.]ьžєzRЦ[fЉNNŸ9m&@є+#~} g‹-=whЖэЬ#рєф2Wlн]\Т|X*MŠ>ЦjВ•НkHзz аЗO‹ŸЂХLCАѕrУ}a&ч•&ššCСбM@ни5Y8нTFъf;0ўр@@Р њ“Р|е‰Э4ws>„0LР†ЛЧp#ZL& ЙЃЁгds‚@Ÿ Lѓѓњ0ЁЯ.а@Ќ„€•фiщiжџЃVЁРK›Ь—*уl‰C$–їB+€РА%`ўъфWŽМsђфЩBt&˜#™жжVš6Qў‡RA[€{Ќјg­Wcє‰€˜­9eсѓ•НRЈъ‹ЭОAР:ќы_qьдЩ8b­Wн?"џѕџХбkФъї›0д4#HUѓп…^INтаr+Цѕ~џИbЬ_6yъdУждB›1]UЎэээv#эї`ХšоЛЛЮ•ЪvоЕ“сйQр6<Ч>фG§›пdгЉ?Ь%‹] v…””дrШЇз‚ТO>­§n‘І?Нџ”Л‡rщsћш•dСэю]ЁлВ/д§o‹~h†љЊЊEФ'Aќўoп”:к5Ъ{•єЪupм]'ŒLаУ^q q43Ш Ћ!ˆ—-іњФТАiAкm"Ло›=w^рЬYIЉiэєCТq‹–„езkПћZrДDEв“мдЄŽ{=1№wГЈKtТF#? tлУхсЫƒќžXvшаAœ%У4bOoIѕZОЌЄДD˜ Ф2it.Љ#ЏЁpOЮKпš%Œ…™эћќ xд:QФ єЩ-ёYєœ6лъjмЮD вšф /ѓЗoоіЮ…;w4єJђkЕ7t6вф>YI–Х‡јџ,‚L“.*'ez&яЧа& _uBЉaчСкдXЏrвN9ЖпiЗГЛЫщЬБ/Nл+ьгвг† Ÿa8ŠoЎ~ђсечјЕž=|TёЗЋŸВїtщq{—›—KЪрYСW*јкжл­Щoo>ц/T\!=)Ѓ6nXѕьВѓ%ЧO=юс6ёэМRJ ‰›зНДў|йХонUљэп$mt”TCЄОЕѕїŽ;ёЇќ]GOœд1рluьšъ№УŸW—]Œ~9ўЯŸў9ыoГ&~јћпія§D5•&ХчЎ(е‹"ъiмэљЊЪO>ќdлЖэџлпSоLѕƒhM<ЇѓП$ќЏЮ…WAC—FšjПчџN{ђq~–…ф‘ŠŒЗBзEwтЄЧ1T ШPаЃpC&ѓBчЪŽVиSДчБ9M~ˆжzxM^ўЖ YA^о^qЏЧi4єЊybўДѓTh=Шџ™Ш›‘†є$ЈЏзGПэрE]Ђc#Z[щž"МAчлІ#—єкЁiimUЉЈРчj~mсh}‡Ÿ>1т_ќГФЬД]”JЛ„ј„вП– Q2šєŒф /:Iрј{ЩtžšфЭЩ4іЧfэљ  O`ЩCљй3‹—>сх=љБyмПO№)Љд†36КЎ”ЧFЬжМВ0 3 „|5vƒRЩџЭGGбтM ”Ѓ•TЕЦОДса zgЙРРGЯVVpАф€Н­}I ?}RQy–є$ќeЯ'гМ=Й{v#k"з”§ЕŒ”’‡НННњЭ­Д:9Љ’7%0#›`Š>,$ГMЏ№вБ)vыеЋОтyКгн=м‚ЧCЩИєDФжDЎЅ1 NŠ>."aC'‡^ЃwЛ†w;sЦ,rјїы ‚МZњЭF9гФ {4tiЄiUдСкЋ­‡‹—выЊеsВg:TлжЦщoFБ: HИWцЏNhБC8)&ыhшWѓ7є‡зї•еdSАЋръ7W?џєѓѓgNгяюmйЙЄ ~8јТх $Је­ЩiЩšŸлIОpсТњsГƒ[ЕjљЊЊгчЯŸ:=бmbжяп&%В LаЩЁ—ѕM4q"rвNџ§ј_в БВ‡м™”і…uЅЧџ'f—=ЩlЫЩЛqГљиЧщМбp#/'O№LњЖŸ›щЏѓ§љќьEўcOБgwIАdЛ)с•—6V­ўф§ЊЊ*…О’J­[–ЖЅ ќШe:иІ§R€j–Фэы ѓŸ^"1Ь™sыі-j №іМ|љ2 GЮJлђйЁ#$_ОќщIЈОZЛњЅuДВCНќ‚Йѕ|Щ#gллgЯ]ИьYZ:sЮЄЙюЦЮxЊf‡NЮZAвПXIЋ*кЌ‚ДпОбIŒЊfЏЅ+3`Bяn˜Тшч ‡uhmхш6r$_П Џ‚†.4=Ѓžђ@Сoў-›^Йу,p§Ег’›QЌ“ В6FРье ћSšВ˜ќа4vђ%tз_т$Мњ_Џк)•‚qбgХ6бNNaћ_Б‡Ž"}`pрйK$-!™4^$|Мя/гМЇihRzЄнšЈивВ2Rв)!hђ•JЅ[jЇ{Ф>[:4Д=–Љ+ХrgRкІgyЊ[[гЗe=ќˆаDz1™УGoJиD шмєњХG fЄп№J—>aѓІг],yАџ7ћКŸЈъkUЊœт“’Ÿ’JЁЩb_iМ–vŒVџъј‰юRІsЙ‡ЪзпКŒ=sъДBaя@s`gЮ&0ї№ъkЏўчВџ<}№8ѕКXі_8м'ЛgП•yъјБФз3г6АъЁv7žЎik‹ mbw.fV]сhе‰щHxuSBљХђМЬmДВS}ў+ОЉЫRl&ШКQКТщ[іЩ­~whЌ…Р•JўGЮ}2_Џ‚†.4‰GЗ+џЉЄзЯќѓŸ§Э(b3ШC†€йЋ1ЉъoЊй)ж“Ьз"]џчц“ѓЇ=4NњœжўЙщаѕчц‘ЌŒЌЯFц—Џ\№уЗVUWWЏ^Г:№с@ъBp ]Кќ™ыпІ[Mќп‹zыєt[6~їI0$Œwсsл4Э)Щныыb2 ъ'g'aЙ5фzЫ'ѓПб*z]Mœа+ЩПпЎэ3вФЦ•œ@kш…яW‘Fg3 Г0Фш}ДZРјшЯЭу"ўXЅЄьvќŸ›Ѕ%є‹л†џЛЛvачшo]~Kzj}5ўе gݘEпщЅ­Љ~;рјZšдЎ“%ž@RмQаяq SЊлz5Џпди$(MMMJшЂЃ7фG,Л{ИgярПX~Ж<%)с‹/OR’GŸаІ В_EЅс§“&НЙ^ш>+ 0wGNшьЙtIUЮЪк:+€пZAЧ–”ЄэYлз_пHokФъєњЏГAГŒu'ЯY™[є є5K>ES5…Эš3ЧйuRФ‹ЧKŽГ ;эЭД”­™ёџЕ‘&?"жDгжWцў$ШЬЮ\Оf5eНš/qŒK—<ЃщрhїЩмy|”ѕ/FјтИЄ}ŸмJz€вЂаЭNX>‚,|СИјГšШ(EЪkў?ЗDзџиQzф€іkkFšWtk“јW‚‚ї—Д…wиfТ#`ўъDє'ФT0keЧ­xv§–Є% šЈЏЏпѕпЛ2ЖdїAПЫЬкAП;шЯЭХ™[2љ?б:;ђnк*ьюБЃoэjЬЁО0яaы­VХHЅ­Ф hQщŽFщФпœО`,ЫŒФВИHOSJ[ГЖ 3+ЉoЅвЅа‹зяиšђ?уB|oж‹ †С&mNŠZхтьB…ѓЫvv‘TђžqHн{э>aуDŠPЃ0 .нЯwЎђL3pLІЫ™ЬЂ“/]јŒ 3ЯLJ'Гd3`Б@Ѕ‚F˜д™ф:IИœ6Э“іф2caїЋpщянГ‰ЊœЎC2\јsЯайeТUwnЄ.ХіІЛїbn!XЩ›IюЎЂS2a#MdOЗ6qpШcЯžу7ЃАKC•€MЙхнB |eИЗŸїЪu+ƒІН–Иaіœй§Y3h-#4„џuLЏ$“Fhк’Жe{VцД i+зЌєžю-(ЭњЊО­VЉT†BаєI{k;н=жСнщcЂbч>5—ЮБїЅKС}ГУQЁ˜ћјм…Я,є~Ш{„šгX"Мс• D{Ч2щoYСЇЄђювF/‹"Д9БіћZЊDiх(u_ЫЎ_гЫ\ˆEхd@†<ЊLlgЮ№чђЩ0дjњ>NЯƒi˜РкУW„гЩ.СхЗюч/j№nvЩд:ѓ‘™3љ‚й/]ВT™g&0›ўДяUaЇ`З91шЪ–Ѓ‡яє2}вййPzКz[.9)™NˆДЭ%љ :IOГMEŸ Кн9NЌфŸр’JИИДFЯ{ќЭ­o§я7еі#F<јрƒ;џА]0ы/Ъ>ecшмвХїдЈБ›Н:ЈDс@$ xyz$Нždжп•’ЁЁaN у­ њhЈNЬA>Aф#р?Ÿ^Іп’ђ…D$NTšџœ‡yЋz н—lР“Жj‡tY!Р№ї‘БpЯphсшїЃ™~EZјР‘ UfЌNЈЄњЈшЃЁ Ў?уцСЇ? ѕ5гЃЁpаƒ€˜ƒ€Ћ“ѓаiŽЄ‡†OР1гћX[­{п?3‚[3ѕХт1”+_B€ џіС8Bц… FXФАt6ЊqЎƒ’ЃхЯќ&ы7t pФђ рBP>l]&іўМsрРм ЃЊОЃŽ+лџ§w:юќ?Хџ›Єœєѕ _ГV Н 'šV]Љъе  KРŒп(VззlЎ&zЃЙ+*Pў•№/ЧufбЧЂ‹џЗИdiIШФъІъ­gљ‡ку0‘€PšDFDšh3"@7B$Wцј>ППГc|№}*M + 3/Ш™ IDATЗ|НЅюNїНо‰3Ÿ9є 9*aё…U:—љѓcNЦБыHзЇюjлœmvЖvt)˜„n…юdœu!‹Eчп'З=ўQЦйŒПЕўВЭ Щ™щ2SьJ_Ів„”гœІ Џ{юa6:qu.їTяйYБѓЌњ,.}fzјДpЁЃ!= 0яr%Fі  б~б‚}ycљkЇ^;Џ>O—Ž{єЕ з„œ щYz@РаЌ •&*'•%$ƒ@`X {4гЭQXСwvЈ4‰,‰єузђrЫЩ'?Йњ‰щяНІCSQЃyECоyWђтOФ‹ћVЊ+kжжЅ EЁ:ц‘qQізю[ъШЦнžo<_ЙКђ`иСŠ[kЎещЋIЕ)ЇН?-ђp$ДаЃoЃЏЁ„Ÿ?њМѓ(gJИ*ЂЊЊI;­mH/jСу‚‰ЦЯ54XвnŸйџЬ—зПмЖџVь­7y3чbŽqН~2а€€€РДъФєЙ“mЖб€ЗЯйЎДSвI‚щу ŠsэNѓ%ТМТŸkџ,ю›>;]˜J!Ѕ%svІ…БЅŽlмmђ#ЩфvСdў^/4QЁгWџђЃб,Ы?5џ,ќŽ/8ЦьC5ŠО™ŽFKжœ,СРžfMШ х‘Ъ-ЦŸŸO4$ќдўНЊFЊЈЩпйпт}tI‡!НаŠW0AЋN„яьzVј€wQjwя2Al#)гТФœчŒк1ŠD„5ЊФ–TˆАKгЃєъ–>ц™[SZFЙМњђЭѕ7iIˆvХR—Ї6ікQ'afo\яКл•P8Му@і‚% 9хŒДщљ'5=ќсУgъЯо щY,   `ƒVs'†^ХCЊœJ—lНЃОЕ^м*–™ d ДvCЫbK}YˆТœ3AпВOnѕЛвPMC<_ИHПtќЂoІ3:„™Нq=- v Н"ІGаšЮ••WђЫЃ],K>_b\ЯbAsДъФєСФ№›Eш;З­э­tn<бc^Aј0.НVкобžўUКиэ/ПђŸё4AТ7•ѕh› rŒПи‘x*QˆB‚О щ“[CNФzšр9є§!ŠKЪ+MWшѕqзЧ#ЃА !сЭн,t1Ў0"6я|ЁKјчсЕЗki[ю,—YЄqЯуzЁЏ   `&VPа_ієхšЏЎEыA…MГи§јnкДК/tњћгХMХ ‹Љ) (`Ъю)nJ7q“ОL_`Ё™ƒю(ю=ЂˆэћфVмбьЈpL8™0nч8ZXY}tuФ…ѓ c#Ѓ#,Дє–ЏBЏ)ЃЇ]Œы/Ћ/“§НЙїўБтєнЁЫ*ЯUєZ›Q4уwу~їiиЇЦѕB+^A@@РL~sГЎ.№ЅЌGVЅ7ЋеЭ?еџ%ТнxЄi~~еље#ЧОтOЇИO 1Я#iЭ…6OаЄТеЕWф€ІaK€žXRz|щўkчFЩŸdIЅ'hВEсХ–№F ‡сI€ОQЙтyуc7хWыЂТZЧћ\n\ЊјлURž.=nЏрrѓДЦ ‰›зНДў|йХонUљэпcIЅаЄѓj(‡М?ОзќГцјЁƒŸџЯоŠЪЋ:Нp  ц&€;й››0ќ_­­­Yxћ‘РG‚Wc7А=(‡кє П%…Ž7^йtјј СЌјРс76)G+эF*bЂceбтM xЅ"іЅ ‡N” z{{{ѕ-ŠгъфЄJоЄН;€Є’х  х@ЩlzeCgjЪMБФ] ƒ€€й ќЪйrюkvЮ0ФавI]]Ю –.y†i„ЅaWlЪk›˜žЪ &7Јo99Ћ„KnЋЙAнРєЬјіѕ†љO/a—ќмЮ#gллЛоџS^~žуПлoLHœ@jIЅЖCЯŒхрд›И-N‰/!ƒ %ЎЎЎў~ќЏ‘A?l5ƒžk" ”&тZD?{кЋЏдбŒWнлдЈ FЋю ЦЋЦ3=ы2Z5ўј .n„&їЩюйoe’LYЅЄlўтШ1’%•Ь•X0œУНMMjš!cJFмХјРХ–AЌŽ€№ч‡%(XйБК$<Шhжd@>ЁчЯ]АuЧV~UІЕ5uЧVКЖфщљЉY[[oЗЖпбаіXAЙтй%ioЅ …B§Е:іU;ъыыјЕ\[з_’JIj†rшдчtІжК57GВ/” C§rгŸ”aкДпi”Р Уœ@ЬKkя;wбStŽНo,] @"W­ё˜4qсВgч-Z8fЬAОтyящо+cЃшы9Џmо4ћбй‚žОsЗ!aS`АпŽМэY™[Œ(…&WC9Ќ‰\у8J1wСS џѓYя‡prvjmmНR~сOЛп5_u2(~iћ…*Ÿъи;(?B   +‹чNЧnˆЅв„Ђ*•Ъ™!ЁљяН/dадиїJ\рУўбБбTЛаDЫьпЭІW–ЂXSŸG­dœД9Љ]гmУŒЛ….=#}іУt’@ .кƒєЉщфќь)кCг$] к Нv7rееSмЅGЧ.њзHцF‡!r!—ˆъD.вˆ  3ЊКN?ПYiЉiеееќzO—RЂ^ŽZЕ|ељ/ЯŸ.=эс6ёэmoлйй-˜Зрг}Ÿ2K’—Ю_@њ=…п\§ќ>?}ъДН­}nN.Гщh˜!ђђѓšo6~№87nо Ыn}KѓёЃЧ?џєѓŠ‹<•ž)UWђ[Fш•ŒКbХ]YлдхМ—Ьљ$,ш@ubAoR0эПп>qќиЗRSg>Б№‰Мœmljф/Ÿќešї4ZБiЗцЅиВВ2Ъсйgž-к[ФРгбС‘ќьО@bбgХ›6)яURЅ{шиЁN щ—УGѓЦЧ oаЅ`'жoze“tчžZqБЋžVЦЎњ”Й1GВД •*Y`!€€€Uш^ЏАЩEF­Ё“ђЏЏЏћ№івN”ќмэtY]]ЛcчкRњЫџ§ТŽџ`lwqQ=№лп–|U:{Нњјј89)IO›jч?=Ÿ7ŽNуЎ ёП|шuƒ“3п‹dъ~[н ШМОг› яьжjчЅ№в­4фJdЌлEˆеЉх§˜œЙžЫСP : ъˆ   aцC/‹ГkBLьЌG„Љ‘W_{uу+g§>РnЄЂН]уЌе/{nйЛџњШЌџйѓёk›^ŒGЋЦџя”ЃЉцш:$Ѓt*ЧЋюmЊW;9ЋШДЉQ=ZuЏр„з7ЊœДzо‘a'BCЎ„жюWБ&w НdnaїеХЪNї{ @@`шј•ŸВ`чъиu%ЇN7бŽWš;Й­Ю§у{NїZлкк8Ч)ѕMъДпПMНЇ_@ѓЯЭћ>?hoяш:б]P.yvIт[ЉѕjКЌНV—”š&шХЏЬУœЙ RwlЅ t’@—‚ [wфњ­Й9Ь^ьфоб#jы˜Ц+f@‚и“™`s­™…ЄhKАT€€ ЦТV+nhCп“Эžї †ў(1Bы!`Гt‰­{Y7d   Cˆ€…Э3aWьњйТP@@: ИККюљ`ЯЌЧц‚‡‰NŸqejЭСЈ4 YШ PXШ4@@’}жZдЧэ@ŽmјВйWќщ0&†   `5lІИOБšd‘(€€€Р0 `sўJе0&†   `jЏжкФПoЩ"Ka@РнУнFг§ƒЗCы!€яьXЯ{…L-Œ@^ў•У_Њ-,)Є wC`ўяT1бžwгг<}P˜‡+МuBiRqБrЈу&ІsмЫ)PP “; s€ аЌ •&џњWюћwљ;ѓ+Њ* v™є­ШЈШОоkЃ"2|€X u}}yѕ•*Ојтхщх?Э3.с§Z‹Б˜пЖмЏ–‚y€ шѕ}јcb3 ‰С €€l„в$щѕЄ^#fМ•бЋќ6ђ‡DDГ YО4Ёgћѕv>ПтySІXЬš­ОsЌьш3@@†v+Њ+}у6€€єB нj7oаЪюwвЫЛ‹fАJ=—u&L˜ Баc‘ГсХ   0єа WЛЮ 'ајјз.VАШQл`цФ"п$5\899 јPщХє=aуn{лЋŽfYИ;_Ї— ƒB€>т…sТфЩ,’™оbk|g‡Н_@`(hooЯл™—’”2XƒIy#eл;y”Ц`%€И нhпЩЏмdQi"4ёšЮ&‹НЋvХvП‰@РТ œљъЬЎwsОњъЂ§Пл/˜’ќFКrДR'ч’Ѓ%!СС...:zй.)tp`pIiЩ‚љ d Š@ ’„GщUS­пjсOйУО§З АPЛонЕvCMmЭЙгчбБњ‰;~lо“aњz95a‹У( 9#"€€4žЛb%ЖФZъоSЌьHПЁа‚@? а>ŒТї }ќ}œœљ%l[†рVчRPfge{<фсцъЛ!Ж§ŽФЪШžЂ=3iggGS&Щ‰Щ4‰ЂŸфЅЫ—<НЛхE+, q n“м|М= wJФэр6'%xLuЃssвfё6yВїЁ|&Й%lJ`zuc=э,!%хО2МѕvЋ~ўоž—.\взC ;њMвы){R&Dub$˜€Р]ЈЌЊDГ&|јСДiг$љњј–W”/pж~_fМj<э ”њF‰_Ud@ПТ„B„ FЋЦ3З=єуДњ•kVІН™V4ЛˆцNhsŒp'жEЪ+Ўјјъ(q  '/OЏŠ>21"_­ДЌ[ŸиbцФФ7f аNї/и]Й6ВЅЕ%=5]пUФ‹I qД†BЕзjsѓrssruЬh›mсЛљћ?ля2бр†чЭЗџР~іmо%Я.IJMЫ~›п5’–šІу.Щ€єД!—фФЭ‰tЩlx§vmЧ‹ЕњЖЖ6кCe=щ[ØБX Тžфя ‰ѓ У€Ћ‹+§PззЋ\\Ly§фCcЋЩђФОљ™#тp$А#{Ч‘/ŽL™8aбТ'ƒѕDЏіœБьЙ0ЗћжEЏЃ"Cпцѕз^џ{ч}ѕF8єozњxhYY›бпя8Ъ‘ў0z,8Шлз{„НЎWор>Ч /:ЧŽK—ЬbFр ъххыхшр—$шЉfЂЩ'ЇE У}%BЁ/—•…†„2?@ф'@гЋІ%‚MuuЕќ(ЕhlМZAL аддуЋ:юю‡f§Т—‡ ВиŒ :™О 6жo44ЋГ>&-#­`Wiш2+;‹N’ыЏе}ЄнмЪ\ё[Гшдq(DЌеНЅJШœ:™qј КЁаб/Ч[f@@~Tp˜^ tЎзШŸЄ‘ˆЖš;–Едd$W4˜B@ЇФЩи’ѓr нЏ:эЭФљOЯ7ХCl„ЊЈ?а@ џL/MhщЧчNl>нџiџ)Р€€Хpuu Ђš/{GёТХ&ŒФ@њO€ wœатNчмIџcЄлg^цН3К›я2| *Z|aы/ƒš‚ƒШGРъчNфC…H   ВАіЙ|gG– `юDFи   `Ь˜ & аmK ДмН:g~dTЄёўНЦэе@Ч?ГЇ'юЮзiХ%€€Ь0w"3p„0F€юЯ–З3/%IтЦК \=;pл;yњЗ‰И№ а;ЬєЮ BрЬ_Я,}nЉ›Ћ›ЧCБbщiњnKŽ–„Гјщ˜[CЁƒƒKJKЬўAŒРм‰8hHЛvцМДіЅšяj*ЯWN25zнj}яЧŽ›їф ?у&lqЅЁŸ4 ВРм‰lЈЌ‰эУ ‡іљјћ89ѓ;KиЖ a :—‚’ХG“"45Bѓ"єј_§бюљѓ>К‹<=˜NкоqётЗњ6—._ђєіdzZaIˆKp›фцуэQИЛP"nЗ9)СcЊ›“6‹ZNі>”Я$З„M LOџЃаЄЄ<УW†Зо–xоВПЗчЅ —X@ф'€Йљ™#"XЪЊЪ“Ѕ'›{Щ^а“Aб^эуO|yТ?ШŸђGyЦПшD)Г‡ `90wb9я2Ы"@Ѕ†щ 5ж5јњQхAЧфЉ“дЗ ѕЅЇџxэЧˆЈ˜ЏlдЗqvvя–mИо rvЬ\КqЏuлBKЗЏ7АVI}ueѕв%Kie‡ђЄ"щжm‰<еMѕ”ѓ@@~˜;‘Ÿ9"‚€ѕaЫБ/йЖЖJье=n|ѕ7еTyhЃыAќО“ЕДяфЂ>_пђŠrІЏO;E„Ыњ.Е’@ѕѕнЃUуYk§8­~хš•ЋVЏЊЉЊЁ<ЉHbћQX/Ъ+ЎјјŠ5Ad&€Й™#X%Їћь. …&6’%іjDМ‘”Ч\эїЕД1VœДПЕўo@{QiC‰_ŸОЭМЙѓіиЯєKž]’”šFѕiЉiLЯ2 =9Є3qs"]В&^пеqХb­О­­ЖХаТ=ё‰ёЬX,P”†X@@f˜;‘8Т€Uи‘НуШGІLœАhсСњcˆ^э8cйsanї;­‹^'љщNЪЃ^tsqzlVPЫO-…яъћ }<ДЌЌŒM{ФoŒwхшхщѕXpЗЏї{нМС}ŽA^tŽёЫš IDAT3–.™ХŒРдЫЫзЫбС1.!IачцфІ$Ї8Й8-Zш+1 }ЙЌ,4$”љ ?kŸ;Б•"‚Рp @ тaК{И>r˜iТ—‡ ВиŒ :™О2/„N}НXCГ1ыcв2в vž.ГВГш$™ц]Š>вnneqyƒ­YtŠ,DЌабгWšщdЪ№tBЁЃ_Ž!ЗЬ€€ќhюФє…,9ЎFў$DDubš@Р* ш”8[2b^Žс~хвоLœџє|sIЈŠЬўAŒ0Н4QЙИP)cм›ќ­6ђ‡DD9 ИККбM€—НƒЃxсFЮ @@fжОяs'2џР ШM€_ињ‹мБ@``юdР#,€€€€V=wR{Е+;оXЈA@@Рj Xѕм }е‰еўш!q0@РЊчNhLЈN МБPƒ€,ш~№'g~dTЄqЗНЦэе@Ч?ГЇ'юЮзiХ%€€ЬЌzю„XЁ:‘љс@РМшvДy;ѓR’ЄhоиощйлоЩcЗэ—!"B€шАњЙ“Gœб4 K€n.яуяУц*tђ,9ZЬрЇг*У%… .)-‘!B€"`ѕs'_5}ehlаƒX zТ=”ЧPbЧŽ›їd˜ЁVyєa‹У( yb! €€$ЋŸ;‘” §$@s…яђ“ЮќЮЉK!VvVЖЧCnЎnєРі;э’ аншO?Нжр я/]ОфщэЩњв =;аm’›ЗGсюB‰ИмцЄЉntnNк,~ц0йћP>“м6%0==ќv–’ђ _NЯdБ˜ряэyщТ%v @@~V?w"?2DaB ВЊђdщЩІЦм14іќмќŠЪŠS_žЊљЎ†œўvКЄ%н>19‘3|ХЦЦF•JХњвDKѓЯЭU—ЊNž:wіќYІgBFVЦ†чОЎЂѓZУ5КdMdђєЙЊ UЭ7odяШєЫУ_ŒZUѓm хщ1Щ#=5™й3AхфBiАK ђРм‰ќЬЌƒ@rRВRЉ41зЂ 3г3UN*Л‘vЩ›’иЇпёЬWgnД4/˜П@ПIЌБЛЇћ |ХŸgМ‘BiаAћUХf‚\МЗ8eKІrД’ЮЬ-™dЯlШ^а“Aб^эуO|yТ?ШŸђGyЦПшD)Г‡ `9Ќzю„Іfmезд–C™€РP"@Ѕ†щУiЌk№ єыЖ—šy3эЭ?dўОлFJrvvV7ЉUЮка зTЮ.‚ЁK— юз n`[hЩріѕж*ЉЏЎЌNн’zБът/џї o)•ЇКЉžв`~ €ШO€цNL/PШвЂžQLSГ6Я‡>/?5DсF`„-ЧОdK_КбўшqуЋПЉnb‡дzUsžœO{G„э#ТЋŽ+_пђŠrІЏO;E„Ыњ.Е’@ѕѕнЃUуYk§8­~хš•ЋVЏЊЉЊЁLМі#лТz‘P^qХ7РWЌ  3гK |F1MЭкџћq™‘! CNї/и]@ Ml$'Jье Џс$%ФёAWћ}-mŒеЇФJЈUxе1›7wоўћ™rЩГK’RгЈЂ#-5щ™@ЄЇЭ­t&nNЄKжФыЛ:ЎXЌеЗЕЕбЖZиЁЂ'>1ž‹J€вk ƒШLРЊїаŸ^И›Ь?07L ьШоqф‹#S&NXД№‰Рр@} быЃНg,{.Ьэ~Їuбыюњг=єёаВВ26эП1оq”Ѓ—ЇзcСAоОо#ьu#ѓї9xб9vЬXКd3gP//_/GЧИ„$AŸ›“›’œтфтДhaX ЏФ@(єхВВаPц€€ќЌzю„ўє’Z4–Ÿ""‚Р# 3БAЕ:|ф0eјђpA›QB'Г1.ˆ;Š-iV#f}LZFZСЎвгeVv$гЗ‘‹>вnneнyƒ­YtŠ,DЌеНБJШœ:™qј КЁаб/Ч[f@@~VНя„ІQШџ3ƒˆ `^:%NЦ–Œ˜—cИ_9њ6ђќЇч›76Ч U‘ЙЃР?€€qV=wBSШXй1ўўЂЌž€ЋЋk-аxй;8ŠnЌ~`€€aVНяф‡:Ќь~kбCƒ-ОАѕ—Ё1"Œ@ WV=wBЃУмIЏo1 @@@РЪXѕм БFube?pH@@z%€Й“^С@@@@V˜;‘7‚Р# yПз~Ž1g~dTЄq'НЦэе@Ч?ГЇ'юЮзiХ%€€Ь0w"3p„0F€nG›З3/%IтЦК \=;pл;yьЖ§чž@њ@РъчNъПЏяУpa  0xh~B|H&RrД$$8˜=РOвЦЌJ \RZbж(p `œ€UЯд^­ЕЉ*Џ2>BД‚XК…+;$Г:vќиМ'У$›dS†-Ѓ4d ‡@ њЌzю„nЎmSQVЁ?*h@њI€&9 п/єёїqrv"Wt)vЈs)4ege{<фсцъFlПг.Ж7]Оtљ’ЇЗ'ГЇ–„ИЗIn>о…Л %тvp›“<ІКбЙ9iГј™УdяCљLrKи”Рєє№?кYBJЪ3|e8=;Хb‚ПЗчЅ —и%љ Xѕм сВљюТwђSCD*Ћ*O–žljфŸ'мы‘Ÿ›_QYqъЫS5пеаC€гпN—ьвYО8=<ыaкњ*iаииЈRЉXгЖэлšnЎКTuђдЙГчЯ2=2В2n4м8їuзЎб%k"ћ“ЇЯU]ЈjОy#{GЖ _ўbдšЈšok(OIщЉЯ[V9ЙPЬљ Xѕм сВћлБђSCD’“’•JЅ‰#-њИ03=SхЄВi—М)љ№}њiMчъ7WщЯ*ќгйПžЄшшлЦюžю'№VœёF ЅAэWеЗ/о[œВ%S9ZIgц–LВg6d/шЩ hЏіё'О<сфOљЃ<у_?tЂ”йCАV?wђ№œ‡-‡&2ЁD€J г‡гXзршG+/tLž:ЙA}ЫH_їЩюљяю)кЃoуььЌnR3}Уѕ•Г‹pщв%АVд l -мОоРZ%ѕе•еK—,Ѕ•ЪsТ„ ЗnKфЉnЊЇ4˜ ђАњЙ“РЧхЇ†ˆ 0мŒАхи—l[[%іjŒ7Оњ›jЖуеДѕ 6}ŒО>ОххL?^5žvŠ—ѕ]k% ъыЛ FЋЦГжњqZ§Ъ5+W­^USUCЉўxэGЖ…ѕ"ЁМтŠo€ЏX@@fV?wт2Yћw•Ьр†Їћь. …&6’%іjDМ‘”Ч\эїЕД1VŸ)Љ‰ Ш,ю•ш ŸбЗ™7wоўћ™~ЩГK’RгЈЂ#-5щ™@ЄЇЭ­t&nNЄKжФыЛ:ЎXЌеЗЕЕбЖZиЁЂ'>1ž‹J€вk ƒШLРъчNdц…p 0< ьШоqф‹#S&NXД№‰Р`‰ Ышѕбо3–=цvПгКшu’Ÿю Ÿ\HMn.NaKТ&NѕHO“и9њxhYY›іˆпя8ЪбЫгыБр o_яіКјyƒћƒМш;f,]2‹3Ј——Џ—Ѓƒc\B’ ЯЭЩMINqrqZД0,аWb њrYYhH(ѓ@@~ж>wb+?2Dс@€>ФУЄЏя>r˜iТ—‡ ВиŒ :™О2/„N}НXCГ1ыcв2в vž.ГВГш$ЙўZ}бGкЭ­,.oА5‹NБ’ƒˆЕ:њ9!t2eј КЁаб/Ч[f@@~4wbzB–W#’F"Ђ:1M `•tJњjOЬЫ1мЏ\ꛉѓŸžoю! U‘ЙЃР?€€qІ—&**eŒ{“ПеFўˆ 'WWз Z  №Вwp/мШ™bШLРкї`юDц„Й ат [‘;6т Ь x„0@РкчNАВcр…@@Ќ–цNЌі­Cт   0D `юdˆОБШB€ю?рqш‘Q‘ЦніЗWџЬžž`\И[њ …:]p  `>˜;1[xш3КmоЮМ”$‰ўѕйз]u gn{'нЖџЎ| €@ `юЄПб@Рtt'ћ№•сє>oŸ}ŸI<ЧИфhIHp0{€ŸщžЪ’B—”– ”CјИ ˜;Й hш p7ш&ёЋ–/[Е|UЭЗ5_ўтќљѓњ^Ž?6яЩ0}НœšАХa”†œ @@‡цNt€р@€'@ћ0 п/єёїqrцw–АmKA™•эё‡›Ћ=эЏ§NЛ Пв щ7ОžH7ГЇћФЋœUњЗŸ'уK—/yz{В^ДТ’—а9зтQИЛP"nЗ9)СcЊ›“6‹Ÿ9Lі>”Я$З„M LOџЃ%ЄЄк;pЦВчТмюwZНNђг}щтЅnуЧyљzi4*Pє§„>ZVVЦІ=т7Ц;Žrєђєz,8Шлз{„о| opŸcP€cЧŒЅKцsFр ъEБу’}nNnJrŠ“‹гЂ…aОЁа—ЫЪBCB™ ђАіЙ[љ‘!" Д№!ІЛ‡ћс#‡™&|yИ ‹ЭЈ@Ё“йH бБqtJ6 JšеˆY“–‘VАЋ€4tIпCІ“фњkѕEi7ЗВИМСж,§/' k#tb…Ь Ё“)У_а…Ž~9†м2 ђ Йг ВфИљ“4е‰8hЋ$ SтdlЩˆy9†ћ•K{3qўгѓЭ=$Ё*2wј0NРєвDхтBЅŒqoђЗкШAф$ръъЪ/xй;8ŠnфЬБ@d&`эћN0w"ѓ Т€мhё…­ПШё@‰цN <Т‚€€ `эs'Xй1№ЦB   VKs'Vћж!qЂЌ~юdЪŠ)Cє­СА@Р а§р<Ыќљ‘Q‘ЦніЗWџЬžž`\И;_Ї— 2АњЙяЕ2C83 лбцэЬKI’xрŸЃŠ\гГЗН“Чnл/j ЋŸ;Љ§pЄ|Д @ h~B|xLuгwVrД$$8˜=РOпРм \RZbю@№ `„€еЯ|їЦwF†‡&Ы!@їoeЧ[П+|х§мŽ?6яЩ0}НœšАХa”†œ @@‡€еЯЈыt†„Kў IŽТї }ќ}œœљ%t)іЉs)4ege{<фсцъFlПг.Жз•;ИТї i‡‡Ўžу.]ОфщэЩєДТ’—р6ЩЭЧлЃpwЁDмnsRMУаЙ9iГј™УdяCљLrKи”Рєє№?ŠKJЪ3|e8=;Хb‚ПЗчЅ —и%љ X§мЩk‰›фЇ†ˆ 0TVUž,=йдиу;†žŸ›_QYqъЫS5пеаC€гпN7dIњ}Ÿэ žЌrRщл466ЊTнњmлЗ5џм\uЉъфЉsgЯŸеЗЯШЪИбpумзUt^kИF—Ь†ьOž>WuЁЊљцьй‚~yј‹QkЂjО­Ё<=&yЄЇJ#Зчm})жн=нOр+ўЌ8уJƒкЏЊпЅxoqЪ–Lхh%™[2ЩžйН 'ƒЂНкЧžјђ„?=фђŒ5ўа‰Rf@РrXћм‰­ЯоќvБœŸ'd2”HЮm`c]ƒ_ _wЋс‡L:|шЩИLtщ6IЮЮЮъ&ЕЪY;}вpНAхЌЕtщDц\ƒКmЁ%ƒлзXЋЄОКВ:uKъХЊ‹Пќп/МЅTžъІzJƒљ ?š;1Н@!KK{FБ MъЪO A`ИaЫБ/йЖЖJье=n|ѕ7еlгЋ‘ѕ wsvlˆн` ЏoyE9kЏO;E„Ыњ.Е’@ѕѕнЃUуYk§8­~хš•ЋVЏЊЉЊЁTМі#лТz‘P^qХ7РWЌ  3гK }FqssГЬШ†!Їћь. …&6’“ѕ DМ‘”Ч\эїЕД1Vп†4gўzЦўпЇMЇ?tЄysчэ?АŸЕ-yvIRjеCtЄЅІ1=Ш€єДЙ•ЮФЭ‰tЩšx}WЧ‹ЕњЖЖ6кC ;TєФ'Ц3cБ@ Pb d™ X§О“?ў“ЬШ†!й;Ž|qdЪФ ‹>ЈO z}ДwрŒeЯ…ЙняД.zЁOїœwr^Zџ’~wІ }<ДЌЌŒM{ФoŒwхшхщѕXpЗЏї{fЈxƒћƒМш;f,]2‹3Ј——Џ—Ѓƒc\B’ ЯЭЩMINqrqZД0,аWb њrYYhH(ѓ@@~ж>w"Еh,?ED!G€>Фcrїp?|ф0г„/dБ(t2Ia_ББнВд…f5bжЧЄeЄь*.ГВГш$ЙўZ}бGкЭ­,.йgmЭЂS'œ`Б6BG2'„NІ Aw :њхrЫl €ШOРкї :‘џgAРМtJœŒ-1/ЧpПrio&ЮzОycsœP™; ќƒ'`эs'6Ц‡‡Vk'ръъD 4^іŽт…kђ0BРкї`юФШ›‹& hё…­П …ё` &Рм‰ `   #kŸ;СЪŽŒ?,  ВРм‰,˜@@@Рd˜;1 AєH<4XЯІЏŠќљ‘Q‘Ц{ѕЗWџЬžž`\И;_Ї— 2Рм‰ЬР@РКmоЮМ”$‰ўы6pmєьРmяфБліœcxшЬєLAњC€nУО"мm’$АТŠ}–- f№7Щ#SшрРр’вyТ! €€$ЬHb@`р Ќ‹|qFа zо~оы^ZЇуиёcѓž гзЫЉ [FiШБ@t`юD.AxДЃ№§B'g'сRЬ…эв+ГГВ=ђpsuЃGЖпi7 ђЗ5џН.кnЄqБqп~ћ­ОЭЅЫ—<Н=™žVXтhЎХЧлЃpwЁDмnsR‚ЧT7:7'm?s˜ь}(ŸIn ›˜žўG;KјљWЗ№•сєь@‹ ўоž—.\b—@ф'`ѕs'ѕЧДO—Ÿ"‚Ра&PYUyВєdScюr~n~EeХЉ/Oе|WCN;]пђЉOхП›O… $аЅОMccЃJЅbњmлЗ5џм\uЉъфЉsgЯŸez&ddeмhИqюы*:Џ5\ЃKжDі'OŸЋКPе|ѓFіŽlAП<ќХЈ5Q5пжPž“<вS%žЗЌrrЁ4˜ ђАњЙ—y.ђSCD’“’•JЅ‰#-њИ03=SхЄЂy‘фMЩ‡H<э/љd2›0q$аЅЄsЛ{КŸРWќYqЦ)”Д_UпОxoqЪ–Lхh%™[2ЩžйН 'ƒЂНкЧžјђ„?=фђŒ5ўа‰Rf@РrX§м‰х D& 0ФPЉaњˆыќ§hх…ŽЩS'7Јoщї{%nЩГ+~Мі#$аЅОГГГКIЭє зTЮкП@\КжJBƒКmЁ%ƒлзXЋЄОКВzщ’ЅДВCyN˜0сжm‰<еMѕ”ѓ@@~V?w"?2DaH`„-ЧОdлк*БWcєИёепT7БCj=шЋЏОЂэ&lп ]ъ“єѕё-Џ(gњёЊёДSDИЌяX+ dРОћCЃUуYk§8­~хš•ЋVЏЂmЙ”)Il? ыEByХп_Б2€€Ь0w"3p„Ћ$№рtџ‚нT аФFrЂФŠLФ‹I q|AаСе~_KcѕЧљрƒВ}'йЙйtЉo3oюМ§і3§’g—$ЅІQ=DGZjг3 HO›[щLмœH—Ќ‰зwu\БXЋokkЃm1ДАCEO|b<3 ”Ѕ!ж@™цNdŽp `•vdя8ђХ‘)',ZјD`p ўЂзG{ЮXі\˜л§NыЂзI~КП›џюйЏNNy` ЯвЅОŸаЧCЫЪЪиДGќЦxЧQŽ^ž^yћzАзэСмчрEчи1cщ’YЬœAНМ|Ну’}nNnJrŠ“‹гЂ…aОЁа—ЫЪBCB™ ђАіЙ[љ‘!" Д№!ІЛ‡ћс#‡™&|yИ ‹ЭЈ@Ё“йш .]іќYbЗЌи’f5bжЧЄeЄь* =]fegбIr§ЕњЂД›[Y\о`kb'$ k#tє!sBшdЪ№tBЁЃ_Ž!ЗЬ€€ќhюФє…,9ЎFў$DDubš@Р* ш”8[2b^Žс~хвоLœџє|sIЈŠЬўAŒ0Н4QЙИP)cм›ќ­6ђ‡DD9 ИККбM€—НƒЃxсFЮ @@fжОяs'2џР ШM€_ињ‹мБ@``юdР#,€€€€ж>w‚•o,д   `Е0wbЕo!JРъчNІЌ˜2Dп Ќ€н~РГЬп™iмmЏq{5аёЯьщ Ц…ЛѓuZq  3ЋŸ;ё^+31„0#КmоЮМ”$‰ў™1ЊШ5=;pл;yьЖ§Ђˆ ђАњЙ“кGЪG ‘@њA€n+KOрѓxШ#?Wz~ЂфhIHp0{€_?ЂнeW \RZr—§б @` X§мЩwo|7р@Рь’S’щ7U—ЊЮ•ћс‡і}&qпиcЧЭ{2ЬьЉ Ж8Œв0j‚FѓАњЙucy С; KДЃ№§B'g~g л–!РаЙ”йYй4)тцъFlПгЎэрсƒT (;>)њDпцвхKžоžLO+, q 4нтуэQИЛP"nЗ9)СcЊ›“6‹Ÿ9Lі>”Я$З„Mџ?{яеф•юџІдЕЈЖwк•TDˆЋVЭБ ЭiO;‚Tm+ŠЧz4ЋjQ…:Ї…д) TТŸљЕr[РЙrHWgZzZЏtЇ`- Œ-E„Hmoья.ЦЁАŽxбИ“ IDAT2vЕu\зЎЙOњ†Эkо7˜ ОY{йg?ћйЯ~ічЅђИїЮЛuLO—џбЩRRœкЭZК;Х„xetчЉNV… рS~эфЗЙ{ќO #‚Рt аmщnijьЛщТwЇšЎюЎжc­жЏЌД@Rєz‘;KІ?wю“™азз'“ЩXЕьВЁя‡hЙЅЅЕ§ФЩLЯ„твт~{ћ*Ні^ЊВ&Вo9оn9eњЖпTnтєЕ[3ЖgXЯY)NХEQШ}Ы2i$…Сќ@№?)Пv2єЊШ_XўчˆA №єŽuчUћОЙЄЈD&•пlиcЈ?,ВkѓtЪгE%Etњ„>$\ћюВЈѓр;GnрЋћЈЎје|nЙ…ЮЋ эыдх–„„…P)),!{fCіœž j8Џl>жŸO—ќQœ9/ч|ммФь!€LS~э$і€ыЄ“.")M€R ЯуяЛ`SЧбЮ }\ќ }@$ѓ ŒdшяC1б1O<ž ‡Щ"„ўУУУ˜о~Щ. фЊ‘Уk%С>`gGhЩрЪ%;kеїtїЌK[G;;чМyѓ._‰s`аFa0?@ќO`ЪЏаЂЎџЉaD˜nfЭА/йвЪ‡pњas#zОьdБ§ ZЁ€џvсogКО–Э•iг§ЈbU]L!‹ “"\е6,АVШРf1рg<7щч:3ЁЭл7oy~‹еbЅH/і^dчQј>;КЮЊ–ЊјШ ~&0хзN†††ќŒ УР4$АфсјšъJPhaУ+rV#}kК^—эHnHЮsžЦ )бщTъNNšš›ој]‰ю?uB›”х)‡bњДѕiњуЯ{AWFІgžЗRЩЭЫЅ*krшўАi­Sэк5:C;”єффц0cО@P| d?˜ђk'яЧЯШ0LCхІђ†# ‹цЯ[Гz…ZЃШм•ЉT'nx6Uў€tgцNбпюjЕzEЪŠEKНѓі;яќёƒШљЮ-ОЗф'“лккиВGЮK9Ёї„:6ƒ4 J•rжLО­CvмšА4†ЪœћчP•Y$ЊЉWŒ*&tvhЖNЯщ+оЌШ7фK#ЅkVЇЊU"ЁЁЯДЕ%'%3?@ќO`ЊЏЬ№?2Œгm|№ЇЙPБАОЁžiДЕœЬ7Ѓ… Г ыжЎЃ"дѓ5ДЊ‘Е+ЫXlЄ= вSЕдTJ…d[Џ­і]чсV6ЎУрЕR*|'$sщ;\ЯЅ%-KЂТŒЕЯЙN„†ЮмEn™ џ ЕЯВ”HЌўr”‘ŒM 0% ИЄ8Х…ХYЛГ$?IŒ{sW=ГЪзSтВ"_џ Ѓ№<5‘EFR*3К7џЗљHŒ рOQQQ ДAГ4fцьPўЦ?cРX ~&0еЯ`эФЯ?0ќM€6_иў‹ПЧЦx Dk'У‚€€И!0езNАГуцСB   S–жNІьЃCр    Аv гП їСћeЧ UћЊЖel}И[ЦsKџЬžn66WWЙДЂ  р#X;ёXИOє†йЪ}•љz‘‹ЧsїОшNСВЗ*йыќнЂ@``эd Т€€‡h)‚ћИи›JMŠХ *$И4qеЦO“4vБŸЈO•4ДF­iljєщ(p Р№лк Н.…ЪИcЧЉиqG ‡ рCє Wю-Ўќ1xяФчЧZЗR!срƒќVN>њщб”•ЉBН?5ЉkS) ŽˆБ@`к№чкЩwм1ю В“iћЃ‹‰ћ–­p˜п6ЧЦЧJУ'KЈЪЯЅЪ59ж?RШЃфtрѕЎѓэG—?ј№ПїМВW&•Q!сƒ?кwžщŒVF3=эАшВuђђXЅТ\m‰ч†$OЏS,–SЩгчёя"&ћXŠsœn%dzКN–’тзnжв‚l,&Ф+Ѓ;OuВ*п№лк 7…qOP‚lGmОЃЯ 0 t[К[šZћnКpЧЊŠЊЎюЎжc­жЏЌt pбыEю,…њsчЮEџв™y@UЁM__ŸL&cњВ7Ъ†ОВtZZZлOœ<СєL(.-юЗїЗaЁвkяЅ*k"ћ–уэ–S–ЁoћMхЮЄк­л3ЌчЌПbЂЈ@фf™4’Т`~ €јŽ€?зNИYŒo‚™2ўлEОУ Я 0…є†Ў}п\RTB‹Сwіъ‹ьЮИsuљЛЉзJТхя.‹Zп9r3_нGuХЏцSxєЁѓЊBћКuљ…%!a!TJ KШžй=Ї'ƒкЮk›5Ч'Фгх@ЮЫ9771{ ў'рчЕn‚у˜ рMіўџ™Сˆг…ЅžOЕя‚=N7bяЭџšїўbэq їўто?УRxxјРр€,м’§’]юќ—IфА0lыјЏ}РЮŽа’С•Kvж*Њящю)(,8m9§уw?:,ХтДQЬп ЕЯВЏ;Š)Aљч?џ9`Лнmœ;ёнЯ<ƒРY3$ьЫДWЏŠœЩ›бѓewшеёЇgћAмK–,9лs–“I ъШРУ’*Vебе1\“DШ"шЄWЕ Ќ•2А џ§BaВжz“~ЎSПyћц-ЯoБZЌћХо‹ь< ыEBGзYеR_@РGA@@`" јmэФe’мђЩэяѕ-кДШХ5Њ ~#РНМФ?УUэЋк–БmєБnЯ- \ќ3{КСи\]хвŠ*€€Lрк ЏgЬГ Rюs_t˜2ш5Е•ћ*ѓѕ"ўљgtw`й[•ьuўўЃ€РД%0Qk'у<шќя/_№ рkДС}\VK]єЌкјIc’FУ.№czП 4ДF­iljєлˆІ3 \;ьA_НњеИ8‚? WЕrokuЫž™§єhЪЪTV!um*…1!CcP˜nІќкЩ@п…щіЬ0_№ZЬ0ПmŽ•†;ж3ЈЪдЅЪ5™JMЇђ(9]x§‡ы|ћл—;ЯtF+Ѓ™кaбeыф фБJ…Йк,Я Iž^ЇX,Ї’ЇЯуп9LіБчЙnŽщщђ?:YBJŠ_ЛYKwВБ˜ЏŒю<еЩЊ@|G`ЪЏќ6wяшР3Lgн–ю–І–СО›.мqЄЊЂЊЋЛЋѕXЋѕ++]і[єz‘;ЫБщћњњd2ы[іFйаїC–NKKkћ‰“'˜ž ХЅХ§іўі/,TzэНTeMdпrМнrЪ2єmПЉмФщ7jЗflЯАžГRќŠŠЂ‘{˜eвH ƒљ р;S~эdшU‘П˜|Ч žA`њ0ш !!!ЮЗі}sIQ‰L* О;иАЧPј ‡=7 ОsфОКъŠ_ЭЇ№шCчU…Nъдх–„„…P)),!{fCіœž j8Џl>жŸO—ќQќ9/ч|ммФь!€јŸРT_;™{ ‹јџч#N”jx>ЭО і8uмˆ§x_2>08 w†dПd—…GrУE #ЃK$і;;BKW.йYЋЈОЇЛЇ АрДхєп§шА‹`аFa0?@|G€жNФ<Є­Oг)OЂБРШєL вгсV*ЙyЙTeM§pЧMkњkзЎбqкиЁЄ''7‡ѓ €Трk ƒјˆР”?wђЮёw|„nArSyУ‘†Eѓч­YНB­Q3=2we*е‰žM•? н™Йгнoqњr ї§&pX• Ь3'$?™мжжЦ–=r^Ъ Н'4&:ц M‚RЅœ5гХ\т0И/4ai •9їЯЁ*ГHT'RЏULшьаlžгWМY‘oШ—FJзЌNUЋD&HCŸikKNJf~ €јŽРT_;лі-xiC€68јs]ЈXXпPЯ4кZNц›Q‚B…йˆ |{О;=ГЁUЌ]YЦbcЭўRRЕдTJ…d[Џ­і]чсVцЧa№Z)ц8ƒєщ.њЄeIT˜RћœыiшЬнYф–й@№Љ~юй‰я~6р&—дЇИА8kw–ф'‰qoюЊgVљ:V.+ђѕ(№ Р˜ъk'ИЃ?Щ 0M DEE%аЭв˜™ГCљ7гІ E`ЊŸ;СкI`§4„ О'@ы цjsьC љЙnŽнйыаПmŽ•†KQмфщuŠХr*yњAз^џс:ЇџьЏŸ-ће2y”є‘ФиƒŽЂdЋ$Мїў{dOНV-_vўыѓ\/КЇP—­Ѓ˜c• ŠŸйГFоЋ}яб{”оUB7~ўљiЁБЫє]ќЛTЙюžOY84 0m LѕЕ“ЖЃЮKвЇэ#ФФAРGNœ<бrМœgϘi*7eыВЙК-н-M-!!!T-.-юЗїЗa!9ѓХLЊъ_qмЋgЊ0}§џ|нzЌuінГЫо(у:VUTuuwqJƒбPєzQaA!5эШмQaЊ knшфВ7Ыж­_чNЩљсўњ"cЦЖлJWР5е}Tw„тљ9sЂјџх0П‹‡2­Фа}Х|јЈ=њЂ|ЅWSцw„ гœЅ&м_&žp •Z‰d‘'–~ГСлиќ†M;‘‘‘мœ#У#Џ\ВГљs9WЕиEЭь—ьд‹uс„О і8umачСХк.sњ?М§‡жПЖ>ўЋЧI|фГП6Ђф;dэХќxУйBуЪ†ЧРяюNю8нБхЙ ћЋїГyЙXђЇяв$Ќz5eawh@`К ЭZњќ@хЊѓsхъе+ДЮ:аїsБ9>“юй™„!њžћ mыГ…ЭU„,т&3™г,bnѕrљONNжўvЇ цs љЇ(ПљЯпœщ:CВЈR4О’тшГq РoђDІХdZ5љУџ@Ѓ{b?k†„ўцЄєˆŒщЏNaЏІ,ь €Р%€Е“)њрі `,0rџX!aгк4бˆгжЇ9ЬџšЙš›—KUЮlгЦMTЅпа?zŠ iбеёIпšЎзe;ўЁsCrў›ѓt0–г“`ыu(щsэџЛ6Š’kхO @Я {Kaо-й›шЃCІ&фaЩУёtъ…š)ЄњєjЪТюа€LQШNІшƒCиS€@Ђ:ё MBŒ*&tvhЖЮyvФ%юœ—rBя MXCeЮ§sЈЪdП­X xќW?ЌzјўЙїsЪЬ]™Juт†gSхHwfюLYžТщIиКyƒ™LЦєЂnЙ7ХбŸœРŸb=qхгk_ќэ‹œr”eвH‹ @Ц‘@ааЋ'Цб\0Н!$$„UGjп7—•аЂH№нС†=†њУ"Л6—Пћ‘Z9?$\ўюВЈЯр;6дъ‰[ЮI‘БШ1zp№ЖлЮutpJG J3Бв›ЦмAм _ію][њ.иудq#ZБK&ю§Х,кёсю§ХН#іУRxxјРр€,м9Д'nЙЎ,‘ЂхЧNwЃŒ80hЃБ†‡ХA@`< ѕлћЧг|ˆ˜5CТОK MТцFє|йУэЖ8ўлZВdЩйžГ\_Ј*єЃŠUut9W>ЈеЗB'L3Ъˆ]gUKUЬ€Œ# ЁЁЁqtW Ђ–<_S]C -lr B›є­щz]ЖЭf“мœџц<ŒкЄІ§ЧkЅ{Щ6<ЛAh“В<хасCLяЮэНaїкzmЬЬ0Ъˆ4 хЎ#є  p;‚о9ўЮэєG_O”›ЪŽ4,š?oЭъjZи%sWІRИсйTљв™;Eёk7jуyќБЧЉ$&ќjнњuB?ЩO&ЗЕЕ9ВœŸ?юмfэЮz,љ1ўwv„ЎHуnDђІ­-9)YД”  p›Ф6Зoг%КƒH$ќЏУ…Š…ѕ ѕ §жчdОeT˜Ј§ŠžŠhЇЄS#YЛВŒХЦš§5œFд­‹’ѕтWEG$џ™ЛГhЌQ"A€Œ™В“1ЃCG˜Єn™тм~м,ѕЙ}W№ BИЃXШ‰$€ьd"щcl!d'B&а€€€L$d'Icƒ€€ ;2@@@`" ;™HњnљЦ‘1 ЊкWЕ-cзё–ўЗЅo3WWatп@vт;Ж№ @€^G[ЙЏ2_ŸясиљЏц—НUЩоВяa/˜€€O ;ё)^8q&@k!мЧпЦO“4šШШHw.zВдЈ5M.zTA@` ;™@јМ&@oqхПШUиџшЇGSVІ ѕЃhRзІRЏQ а ~&€ьФЯР1мt!@+цЗЭБёБвp)Э™Њќ™ЛTЙ&SЉIёB%Ї+ЏџpoяЙмyІ3Z-bC’Їз)ЫЉфщѓшЎAі‰WFwžъdU  0с‚lGm€$аmщnijьєdvUU]н]­ЧZ­_YяКыЎЂз‹<щ%Дщыы“ЩdB}qiqПНП§ •^{/U™LIНX€L8 ШOїЇ'ю dВЅxШu{tL?аgЃ“%ЄЄ8Е›ЕЂы7ёЪшЮSЬ№–vvМ%{№”@ЗЅЛЅЉeАoа“UU]н]­ЧZ­_YяКыЎЂз‹FяEЛ™LЦєeo” }?dщДДДЖŸ8y‚щ™P\ZмoяoџТBЅзоKUжDі-Чл-Ї,Cпі›ЪMœ~ЃvkЦі ы9+ХЉX (*ЙoY&Є0˜  р-ььxK і р)ƒотЁuэћц’Ђ™T|wАaЁў№СQ:žџњ|О!џв7Dm‚яЙвЏюЃКтWѓ) њаyUЁ}нКќТZŒЁRRXBіЬ†ь9=дЈхєЭЧšутi§†тЬy9чуц&f@Ц‹vvЦ‹$ќ€€+J5\Uюы}ьqъ8кyЁЯƒ‹Д\vgлqКcЫsіWя=њ>08Рњк/йeс‘\5rX`­$иьЬ\Йdg­Ђњžюžuiыhg‡тœ7oох+"q к( ц€xK;;оƒ=Œ…РЌі%лЋWEОk67ЂчЫžAіqГєq§ЧДБВџэ?ќђ—ПCЋъшъ`MВ:)ТUmУk% lЖƒ0YkНI?зЉпМ}ѓ–чЗX-VŠєbяEv…ѕ"ЁЃыЌjЉŠЏ  ^@vт.ƒР ,y8ОІК†Zи ­B/щ[гѕКlGBpCrў›ѓt0VhCЧlKіцњшЛд„КЄ,O9tјы›Ж>M_`Є|ˆ>Ц#г3 HO‡[ЉфцхR•59єУ7­uъЏ]ЛFЧbhc‡’žœмfЬ( ƒЏ  ^ŠйЁіЊ#ŒAМ Pn*o8вАhўМ5ЋWЈ5jaЯЬ]™Juт†gSхHwfю§эўЪo_љпМ к[aы1Ьaђ“Щmmmlй#чЅœа{BcЂcžа$(UЪY3™ЁSpмšА4†ЪœћчP•Y$ЊЉWŒ*&tvhЖNЯщ+оЌ #/вHщšеЉj•ШDhш3mmЩIЩЬ№–РŒm:oћР@р–hуƒoГPБАОЁžiДЕœЬ7Ѓ… Г |ca+ЇЁUЌ]YЦbcЭўвPЕдTJ…d[Џ­і]чсVцЪa№Z)‡œAњзWЊ$-KЂТŒЕЯЙN„†ЮмEn™ №–РŒ—їooZYсm7иƒLZ.)Nqaqжю,ЩOуомUЯЌђuи\VфыQр@ А рмI`?_Ь$QQQ ДAГ4fцьPўЦ а€€РЄ%0cб‰Z1iУC` ЗK€6_иўЫэњB№ Ќј3№˜@аЪїи†    рsA/ўfЛЯС    р1  еxi’ЧД`уM€оY2о.%UћЊЖelнэ-ЧНЅ‹fO7›ЋЋ\ZQЏрм‰WИ` “НŸ­r_eО^фТ?џ„Nw–НU)|MœFЧ( AйI`А№„€Ao ёФ’ljп7—•ШЄ2Z1ь1д>шЎ#­Ь›7Џъ­J:*j|чШ |uеПšOaаGдОю@]~aIHX•’ТВg>Щžг“AэчѕЭЧšутщ’?Š3чхœ››˜=/AY›ж—/јр Tƒ_]юЛ`SЧQцAŸ?hИьЮžnОи{1=#ыЅ_ꄇ‡ѓOЫк/йeс‘œYфАРяeАГ#Дdpх’ЕŠъ{К{жЅ­ЃŠ“’ЄЫWDтДQЬ№–@Pх‡X;ёьAРkГf8ЖcИnWЏŠœе›бѓeeЮЯЈћAŽs';шмЩiaЊXUGWгGШ"шЄWЕ Ќ•2АйF ТdЌѕ&§\Ї~ѓіЭ[žпbЕX)NJ’иyж‹„ŽЎГЊЅ*О2€xE (ыYЌxE Ц 0KŽЏЉЎЁ…6 Й"g5вЗІыuйŽ„р†фќ7чщ`Ќp:пjыuаYT:P—'ДIYžrш№!ІO[ŸІ/0R>Dc‘щ™@Є'‡TrѓrЉЪšњсŽ›ж:ѕзЎ]Ѓc1ДБCIONn3ц …Сз@Џ5~‚/ўyE Ц 0хІђ†# ‹цЯ[Гz…ZЃКШм•ЉT'nx6Uў€tgцNбпюЄмšБU)}тБ„ПџЯпЭП7 §$?™мжжЦ–=r^Ъ Н'4&:ц M‚RЅœ5гЕ‡УрОа„Ѕ1Tцм?‡ЊЬ"QHНbT1ЁГCГuzN_ёfEО!_)]Г:U­™ }І­-9)™љ о˜Qўцyлі З$@|›…Š…ѕ ѕLЃнЈхdО%(T˜PHJIЂ"дѓ5ДЊ‘Е+ЫXlЌй_CzЊ–šJЉLы.Ея:ЗВqЏ•Rс;!™3Hп‘юЂЇЏ4SaJэsЎЁЁ3wg‘[f@М%0ЃсШь(\Sь-6иƒР$&р’тgэЮ’ќ$1юЭ]ѕЬ*_ЮeEОўA›оЦиЯГITTTmа,™9;”Пq4  0i ЬАўѓщх++&m| @р6 ац лЙMWш ў!€ЕџpЦ(   žz=Їb=…;?ЊйяzVпЃbpG;;юШ@ў @яƒїaЊіUmЫи6Кл[Ž{KџЬžn06WWЙДЂ  ^КуŽ;МъcЩL€^G[ЙЏ2_/~A "ЇЛЫоЊdЏэїУˆ@ №§ѓŸџ МYaF РшхђБёБl­ТeІŸ4&i4ь?—V?TihZгидш‡Б0€@ РкI >YЬ+` а ;t)Лщ§єhЪЪTw­ўбЇЎMЅ0ќ3FHX; ШЧŠIM<Zл0Пmv,r„;N–И,uИTЙpMЅ&ХC y”œЎМўƒѓBc—™алш›?mЮм‘щЂgеЮ3бЪhVЅК;PО@ЋT˜ЋЭ"уофщuŠХr*yњ<ўУdKё,ыіш˜ž.џЃ“%ЄЄ8Е›Еtw ‹ ёЪшЮSЌ @М%€SБоƒ=xJ лвнвд2иwг…;ю:WUTuuwЕkЕ~eЅK€‹^/ЕЄЗбчr%3DЪОО>™LЦšiЁeшћ!KЇЅЅЕ§ФЩLЯ„твт~{ћ*Ні^ЊВ&Вo9оn9eњЖпTnтєЕ[3ЖgXЯY)NХEQШ}Ы2i$…Сќ@o нБ ЇbН…{№ˆ€Ao ёШT"Љ}п\RT"“Ъ‚я6ь1д>(ьјйчŸѕџ}шЉUO ›јšр;GnрЋћЈЎје| ƒ>t^•oЦЩuъђ KBТBЈ”–=Г!{NOЕœз6kŽOˆЇKў(Юœ—s>nnbі@@`МЬШ꘢|ћoМpТ№PЊСЋнBьЛ`SЧ‰­Žь5ю§?Kўзˆ˜>08 wmПd—…Gr†‘УПŸ}РЮŽа’С•Kvж*Њящю)(,8m9§уw?:,ХтДQЬ№–@а5ЩпНэ{o Ьš!a_ВЅ/нЛ‡ЭшљВg}Фіƒ(3XЖrсŽpКИRХЊ:К:˜2BA'EИЊmX`­$Э6b&‹`­7щч:ѕ›ЗoођќЋХJ‘^ьНШЮЃА^$ttU-Uё5A@Р+AYШѕЊ'ŒA<'АфсјšъJPhaУ+rVƒО†Ѓзe;‚’ѓпœЇƒБBч,u!ZЙ?]ЬR–Ї:|ˆ)гжЇщ Œ”бЧX`dz&щщp+•мМ\ЊВ&‡~ИуІЕN§ЕkзшX mьPв““›УŒљ@a№5A@Р+Aпџя;ёŠŒA`,ЪMх GЭŸЗfѕ ЕF-t‘Й+SЉNм№lЊќщЮЬcўэžќdr[[[іШy)'єžа˜ш˜'4 J•rжLз‘ї…&,Ё2чў9Te‰ъDъЃŠ š­гsњŠ7+ђ љвHщšеЉj•ШDhш3mmЩIЩЬ№–РŒ2tоі=€Р- И,l,T,ЌoЈgНДЕœЬ7Ѓ… Г]рwф[вЊFжЎ,cББf щЉZj*ЅB2}Йі]чсVжнa№Z)О’9ƒєЎ/VIZ–D…kŸs Й;‹м2  р-/ьпў—•оvƒ=€РЄ%р’тgэЮ’ќ$Ёo#Џzf•ЏУцВ"_џ Mя; ьч‹й€$***6h–ЦЬœЪпИ˜ДФО8iƒE` о ЭЖџт}oє €Е“ €Ž!A@@F!€ьd8h˜ШN&:†…В“Qр  |N@є}ЏЗ9jеОЊmлFwrЫqoiртŸйг ЦцjмŽс‚Uя ;ёŽЌA`’ збVюЋЬз‹\јчŸШщюРВЗ*йkћ§3(F0ШNьb:L€ж'јбЉ6~☪бА ќDm|ЊЄЁ5jMcSЃOGsР&€ь$АŸ/fhшЎь#:ЗЃŸMY™*кф7eъкT УoУa Р#€ь$№ž)f4)а"‡љmsl|Ќ4\JQ•–K•k2•š)фQrК№њзљіžЫg:Ѓ•бЬžvXtй:љyЌRaЎ6‹Œ{C’Їз)ЫЉфщѓјw“},ХГ@ЎлЃczКќN–’тдnжвнl,&Ф+Ѓ;OuВ*№–Вo‰С<%аmщnijьsм'|ЫOUEUWwWыБVыWVКИшѕ"б.?Ї/вG{„ŽОŠєѕѕЩd2жTіFйаїC–NKKkћ‰“'˜ž ХЅХ§іўі/,TzэНTeMdпrМнrЪ2єmПЉмФщ7jЗflЯАžГRœŠŠЂ‘ћ–eвH ƒљ о@vт-1иƒ€Ї zCHHˆ‡жЕя›KŠJdRY№нС†=†њУ…iOчы/Пўл…СwЬяœјk ] #Д!M№#7№е}TWќj>…A:Џ*ДЏ;P—_XBЅЄА„ь™ йsz2Ј=рМ>АљXs|B<]ђGqцМœѓqsГ‡ 0 а!АЦVч9АЯ>џьГŸqAvtuP™„s!!;™ДMy”jx>‡О і8uэМачСХк.вwсƒ Ћ~o~Џі=ЁMxxјРргл/йeс‘\5rX`­$иьь-\Йdg­Ђњžюžuiыhg‡тœ7oох+"q к( ц€РФxjеS,w23˜$В“Iђ F€˜5CТОd{ѕЊШYАЙ=_іАЏžэ]RSХЊјџАEаIЮЬ6,№{‘Э6b&‹`­7щч:ѕ›ЗoођќЋХJЁ^ьНШЮЃА^$ttU-Uё5A&Š@rR2;ЧішП>ЪЮŠХ+уњFў%3QсЙй‰;2аƒРxXђp|Mu %(ДАaШ9Ћ‘О5]ЏЫv$7$чП9Oc…У“’šШ€ЬВ_Ь|jѕП mR–Ї:|ˆщгжЇщ Œ”бЧX`dz&щщ/,*ЙyЙTeM§pЧMkњkзЎбБкиЁЄ''7‡ѓ €Трk ƒ€€Wx… Ц 0FхІђ†# ‹цЯ[Гz…ZЃzЩм•ЉT'nx6Uў€tgцNбпюЋWЎІ&yЄ45-uўbE‘Qффlђ“Щmmmlй#чЅœа{BcЂcžа$(UЪY3]GvмšА4†ЪœћчP•Y$ЊЉWŒ*&tvhЖNЯщ+оЌШ7фK#ЅkVЇЊU"ЁЁЯДЕб?з˜ H`Šž;™1Ш040кјрЯnЁba}C=гh7j9™oF f#’R’Јѕ| ­jdэЪ2kізžЊЅІR*$лzmЕя:ЗВqЏ•Rс;!™3Hп‘юЂOZ–D…)ЕЯЙN„†ЮмEn™ ‰%@gMЎџрмP&љъч†ЩУЛЁptd'B&а€Рд&р’таW{ВvgI~’їцЎzf•ЏчЦeEОўA<$€s'‚‚€€_ DEE%аЭв˜™ГCљ7~ ƒ€€7Аvт -и‚Р$@›/lџe †An‹wщUђу’zп §љhb<§Щ}Й/ў—#Џ–О­aЦЛ3NХŽ7QјЩDРн;NјњЩЏ#d'“э‰ 78w2n(с@@@`:РкЩt~њ˜ћФ їС{tAрЖŒmЃЛНхИЗ4pёЯьщcsЕј ….]P№)њОd'~јйР р?є:кЪ}•љz‘ џќнXіV%{mПХ( ЃрŸ/q'в}Bš‚Ў_Н>!cP1 7йk7kщОXeьСDю1nќЄ1IЃaјaˆльBCkдюkЗщ нAnŸРT=w‚W:оўг‡№zIќ–Жlмb=g=RффЩ“ТQ~z4eeЊPяOMъкT УŸ#b,#€{ ˜Юd!@ч0Ьo›cуcЅсŽ“%ьXŸK•SšJMЇђ(9ніЧюхЯ‡^Hџв+Йє2{zOМ,\&|§<wžщŒVŽМР€vXtйКŸзZцjГШИ7$yzbБœJž>ч0йЧR< фК=:ІЇЫџшd ))NZХaїђуŒWFwžъфk ƒLœ;™(ђ&)nKwKSЫ`пMюИ‹ЕЊЂЊЋЛЋѕXЋѕ++]\єz‘аВэxгРЗДЇCЩС ™/а§СB›ОО>™LЦєeo” }?dщДДДЖŸ8y‚щ™P\ZмoяoџТBЅзоKUжDі-Чл-Ї,Cпі›ЪMœ~ЃvkЦі ZМЁ8 E"ї-ЫЄ‘ѓ@`b И;kТзOl„ТбБv"d ŒƒотЁЏкїЭ%E%2Љ,јю`УC§a‘3%іЫЛ№З–жЪ6(ƒ1ф‹d4\№#лЕuеПšOaа‡ЮЋ ƒЉ;P—_XBЅЄА„ь™ йsz2Ј=рМ>АљXs|B<-оPœ9/ч|ммФь!€LBSєм оd? –R€ TУѓ™є]АЧЉуFьХўзМїГ ЙЮŒ‡R“ULХ›#]~–ТУУhп‡гл/йeс‘œ9,№Лиьь-\Йdg­Ђњžюž‚Т‚г–г?~їЃУR,ЮA…Сќ@o `эФ[bАБ˜5CТОd+К#67ЂчЫžAілZВ„—ОH$3ХQХЊИы3ИЦYсdлАРяGtи–„Щ"XыMњЙN§цэ›З<ПХjБRЄ{/Вѓ(Ќ ]gUKU| d№ŠВЏpСЦH`ЩУё5е5” аТ­НЄoMзыВ С }m˜Ц m6lкPTRDЩ }ŠŒEIЋžкЄ,O9tјгЇ­OгЙ.Ц#г3 HO‡[ЉфцхR•59є?HиДжЉПvэm*бЦ%=9Й9ܘ/P_@М"€ьФ+\01(7•7iX4оšе+дЕаKцЎLЅ:qУГЉђЄ;3wŠўv_Зv<тўMэщќуџ Eш'љЩфЖЖ6Жь‘ѓRNш=Ё1б1Oh”*х,Сz‹УрОа„Ѕ1Tцм?‡ЊЬgЂ:‘zбXЁГCГuzNO{Iљ†|iЄtЭъTЕJd"4є™Ж6къf~ €€€ЗФ6Нѕ{кјры*ж7д3vЃ–“љf” Pa6ЂBц йTD›8%­jdэЪ2kіз†Њє=d*$лzmЕя:ЗВqЏ• ПœЬЄяHw+iYІд>ч::swЙe6@@Р[ШNМ%{˜ь\RœтТтЌнY’Ÿ$ЦНЙЋžYхышЙЌШзЃР?€@`РЮN`?_Ь$QQQŽЭ Ѕ13g‡ђ7n€@&-ЌLкGƒР@`|ац л№ >&€Е†{/ ;ёЬA@@|Lй‰У=€€€€—x ц 0ЎD. ОmџUћЊЖelнЭ-ЧНЅ‹fO7›ЋЋ\ZQЏ ;ё ŒA`В збVюЋЬз‹\јчŸащюРВЗ*йkћ§3(F0AзИ`SТt@ P ањџЃX,ЮДё“Ц$†]р'4№Е††жЈ5MОўA˜РŒъзЋxz˜і‚Wš”љmѓЗп gwєгЃ)+S…zjRзІRO­zЪŸƒb,@"дtИ)цƒЙ€Р$!@‹”@ФЦЧJУЅUљЙTЙ&SЉIёB%Ї+oБЈyCbў/3№рћффЮ3бЪhІЇ]ЖNО@ЋT˜ЋЭ"уофщuД C%OŸЧПs˜ьc)žrнггх4.))Nэf-нШЦbBМ2КѓT'ЋBo ]ИьmиƒxB лвнвд2иwг…;ю:VUTuuwЕkЕ~eЅK€‹^/rgIњƒд<І‘IeB›ОО>™lD_іFйаїC–NKKkћ‰“'„іХЅХ§іўі/,TzэНTe6dпrМнrЪ2єmПЉмФщ7jЗflЯАžГRœŠŠЂГg‚LIaА*№–@ач}Ÿ{лі ž0ш !!!žX’Mэћц’ЂJ8‚я6ь1д>8JЧ7*пxсз/И3ОsфОКъŠ_ЭЇ0шCчU…]ъдх–„„…P)),!{fCіœž j8Џl>жŸO—ќQœ9/ч|мŒХW €РИ˜aќQ" 7p 0L@tmcИбѕП}ьqъИэŒбEњИўуy№_"чGКшЙjxxјРр€,мЙ|bПd—…;-#‡~Gћ€Ё%ƒ+—ьЌUTпгнSPXpкrњЧя~tXŠХ90hЃ0˜  р- '–?сmиƒxK`ж ћ’эеЋ"g5ТцFє|йCч^їћAПГќ7/ќЦ]ЊXUGWkEаIЎjX+ d`Г„Щ"XыMњЙN§цэ›З<ПХjБRœ{/Вѓ(Ќ ]gUKU| d№Š@аЃЋѕЊŒAЦ@`ЩУё5е5” аТ†!WфЌFњжtН.л‘мœџц<ŒхГП~6ѓџ§хУПm%eЪђ”C‡БжДѕiњ#хCє1аBЉы‡ HO‡[ЉфцхR•Y8єУ7­uъЏ]ЛFЧbhc‡’žœмfЬ( ƒЏ  ^ђЪЦ c#Pn*o8вАhўМ5ЋWЈ5jЁ“Ь]™Juт†gSхHwfюtїл§ЭЗоќѕЎ_ Л3Mђ“Щmmmlй#чЅœа{BcЂcžа$(UЪY3™ЁSpмšА4†ЪœћчP•Y$ЊЉWŒ*&tvhЖNЯщ+оЌШ7фK#ЅkVЇЊU"ЁЁЯДЕ%'%3?@@Р[b›Цоњ€=€€€m|№uOДв IDAT  ыъ™FЛQЫЩ|3JPЈ0Qс`нhЇeЉ ­jdэЪ2kізpеRS)’mНЖкw‡[йИd_њZ)—с8ƒєщ.њЄeIT˜RћœыDhшЬнYф–й@o ;ё–ьA`ВpIqŠ ‹ГvgI~’їцЎzf•ЏЃчВ"_џ M;;§|1;DEE%аЭв˜™ГCљ7@ “–жN&эЃA` 0>hѓ…эПŒGxРк‰У=€€€€—x ц   >&€ьФЧ€с@@@РKШNМsW"—пЖџЊ}Uл2Жюц–уовРХ?ГЇŒЭеU.­Ј‚€€Wx… Ц 0й аыh+їUцыE.ќѓOшtw`й[•ьЕ§ўЃ€d'і@1@&@ЏaеnвЪШЉР^ЫŸsу'I ЛРпф™†жЈ5MўЃ€$d'љX1ЉР$АsлжФ„DКŠ2NЙѓз;…ѓ<њщб”•ЉBН?5ЉkS) ŽˆБ@ŒВ“{ ˜Юd!@ч0Ьo›cуcЅсRЉЫртsЉrJSЉIёB%Ї+Џџp]8“sжџ7sgf№нСTВ_Ш>wюœаІѓLgД2šщi‡E—­ЃЕ–XЅТ\mї†$OЏS,–SЩгчёя&ћXŠg\ЗGЧєtљ,qЌпDЩЕ›Еtw ‹ ёЪшЮSЌ @М%€ьФ[bАO t[К[šZћnКpЧ]чЊŠЊЎюЎжc­жЏЌt pбыEBЫЇŸzКъїU”ИP!ЊB›ОО>™LЦєeo” }?dщДДДЖŸ8y‚щ™P\ZмoяoџТBЅзоKUжDі-Чл-Ї,Cпі›ЪMœ~ЃvkЦі ы9+ХЉX (*ЙoY&Є0˜  р-d'оƒ=xJР 7„„„xh]ћОЙЄЈD&•бКˆaЁўАШm†W d6oў<*$PUдy№#7№е}TWќj>…A:Џ*ДЏ;P—_XBЅЄА„ь™ йsz2Ј=рМ>АљXs|B<]ђGqцМœѓqsГ‡ уEйЩx‘„p%@Љ†ЋЪ}Ня‚=NG;/єypёƒіЫBльГгжoКи{‘ Tꄇ‡ 0Н§’]ЩU#‡жJ‚}РЮŽа’С•Kvж*ЊящюY—ЖŽvv(Юyѓц]О"чР Т`~ €€€ЗxK і 0ГfHи—lЏ^9Ћ67ЂчЫžAілњќѓЯщИ ;wBUa(ЊXUGWгGШ"шЄWЕ Ќ•2`п§!ƒ0YkНI?зЉпМ}ѓ–чЗаБ\Š”’$v…ѕ"ЁЃыЌjЉŠЏ  ^@vт.ƒР ,y8ОІК†Zи0фŠьШЄoMзыВ С ЩљoЮгСXсHK–,aчNL&Њ mR–Ї:|ˆщгжЇщ Œ”бЧX`dz&щщp+•мМ\ЊВ&‡~ИуІЕN§ЕkзшX mьPв““›УŒљ@a№5A@Р+ШNМТc#rSyУ‘†Eѓч­YНB­Q НdюЪTЊ7<›*@К3sЇшoїпW§ўФч-‹ўe•Ўг'Ј*є“ќdr[[[іШy)'єžа˜ш˜'4 J•rжLзƒћB–ЦP™sџЊ2‹Du"ѕŠQХ„ЮЭжщ9}Х›љ†|iЄtЭъTЕJd"4є™ЖЖфЄdц€xK`†З` р кјр›-T,ЌoЈgэF-'ѓЭ(AЁТl„BфќШї>9-ЫЗЄUЌ]YЦbcЭўвSЕдTJ…d[Џ­і]чсV6ЎУрЕR*|'$sщ;в]єIЫ’Ј0Ѕі9з‰аа™ЛГШ-Г о@vт-1иƒРd'р’тgэЮ’ќ$1юЭ]ѕЬ*_GЯeEОўA›vvћљbv ‰ŠŠJ  šЅ13g‡ђ7n€@&-ЌLкGƒР@`|ац л№ >&€Е†{/ ;ёЬA@@|Lй‰У=€€€€—x ц 0Ўш}№уъЯсЌj_еЖŒmЃЛНхИЗ4pёЯьщcsu•K+Њ  рd'^с‚1Lvє:кЪ}•љz‘ џќ:нXіV%{mПХ( FйI€=PL' аkх_Ш|nрS<ЄЈЊ_ŸhќЄ1IЃaјљ ­Qk›§?4FШNцQb"OРo ;n,–іЖіП§эo?yoьбOІЌLXЉkS)Œ‰ЃƒLiШNІєуC№“—У0ПmŽ•†;N–Аc\Ф.UNi*5бЂˆ08РєіKvYx$WX+ і;;BKW.йYЋЈОЇЛg]к:кйЁ8чЭ›wљŠHœƒ6 ƒљ о@vт-1иƒРXЬš!a_ВЅ•Ё‹АЙ=_і Ви~-а РЛ№З3]_ЫцЪ4i„~TБЊŽЎІEаIЎjX+ d`Г№3ž›єs™ацэ›З<ПХjБRЄ{/Вѓ(|Ÿ]gUKU| d№ŠВЏpСЦH`ЩУё5е5” аТ†!WфЌFњжtН.л‘мœџц<ŒŽDЇSЉ;9ijnzуw%Кџд mR–Ї:|ˆщгжЇщ Œ?я]5™ž d@z:мJ%7/—ЊЌЩЁџљCТІЕN§ЕkзшX mьPв““›УŒљ@a№5A@Р+ШNМТc#rSyУ‘†Eѓч­YНB­Q НdюЪTЊ7<›*@К3sЇшowЕZН"eХЂ%‹оyћwўјAф|ч– п[ђ“Щmmmlй#чЅœа{B›AšЅJ9k&пж!; ю MXCeЮ§sЈЪ,е‰д+F:;4[ЇчєoVфђЅ‘в5ЋSе*‘‰ааgкк’“’™  р-оv€=€€'hуƒoЖPБАОЁžiДЕœЬ7Ѓ… Г ыжЎЃ"дѓ5ДЊ‘Е+ЫXlЄ= вSЕдTJ…d[Џ­і]чсV6ЎУрЕR*|'$sщ;в]єIЫ’Ј0Ѕі9з‰аа™ЛГШ-Г о@vт-1иƒРd'р’тgэЮ’ќ$1юЭ]ѕЬ*_GЯeEОўA›vvћљbv ‰ŠŠJ  šЅ13g‡ђ7n€@&-ЌLкGƒР@`|ац л№ >&€Е†{/ ;ёЬA@@|Lй‰У=€€€€—x ц 0Ўш}№уъo4gUћЊЖelЭBp—Ваил€™=нllЎЎ:„@„™@H€о0[ЙЏ2_/r fKw –НUЩ^чяŸA1 €Р%€ьdŠ>8„=M аRїq™ПЉдЄXЌ B‚KWmќЄ1IЃaћ‰кјTICkдšЦІFŸŽч AйI`Vю8YBU~Ф.UЎЩБўёB%Ї+Џџpo?КќС‡џНч•Н2ЉŒ |јаОѓLgД2šщi‡E—­“/Ч*цjГH<7$yzbБœJž>1йЧRœ фt+!ггЅ€tВ„”ПvГ–юdc1!^нyЊ“U!€€€;ШNм‘n—@ЗЅЛЅЉeАяІ wм9­ЊЈъъюj=жj§ЪJ—Н^фЮRЈ?wю\є/™ TкєѕѕЩd2І/{Ѓlшћ!KЇЅЅЕ§ФЩLЯ„твт~{ћ*Ні^ЊВ&Вo9оn9eњЖпTюмHкЈнšБ=УzЮJё+(Š Dюa–I#) ц€И#€ьФшAрv є†НдОo.)*ЁХрЛƒ { ѕ‡EvgмЙКќнд‹k%сђw—E-ƒяЙ™ЏюЃКтWѓ)<њаyUЁ}нКќТ’А*%…%dЯlШžг“AэчЕ‚ЭЧšутщђ? чхœ››˜=№–оdя-1иƒ€Ї(е№дT"щЛ`SЧи{ѓПцНϘE;A\‚BТНПИwФЯА>08 w†dПd—…Gr‘УТА­уПі;;BKW.йYЋЈОЇЛЇ АрДхєп§шА‹`аFa0?@@РЌИ#=Œ'Y3$ьЫДWЏŠœЩ›бѓewшеёЇgћA\ˆK–,9лs–“I Њ0tUЌЊЃЋƒщ#dtR„Ћк†жJиl#aВжz“~ЎSПyћц-ЯoБZЌћХо‹ь< ыEBGзYеR_@D ;Х%Œ3%ЧзTзP‚B †\‘3щ[гѕКlЧ/ў’ѓпœЇƒБžGšіЏ•ю%ЯTHи№ьaп”х)‡bњДѕiњ#хIє1™ž d@z:мJ%7/—ЊЌЩЁюИi­Sэк5:.C;”єффц0cО@P| d%€ьD ” 0ЮЪMх GЭŸЗfѕ ЕF-єžЙ+SЉNм№lЊќщЮЬю~‹г—kИяз0\i7jуyќБЧЉ$&ќjнњuBџЩO&ЗЕЕБeœ—rBя ‰ŽyB“ T)gЭtэс0И/4ai •9їЯЁ*ГHT'RЏULшьаlžгWМY‘oШ—FJзЌNUЋD&HCŸikKNJf~ €€€;b›УюlЁ№˜mp№m*ж7д3 хœЬ7Ѓ… Гјі|ƒьWєTј™V5Вve‹5ћkЈ‰ЊЅІR*$лzmЕя:З2џƒзJЉИјс вwЄЛш“–%QaJэsЎЄЁ3wg‘[f@м@vтŽ є h\RŸтТтЌнY’Ÿ$ЦНЙЋžYхыйrY‘ЏGР €РxŽ˜xM ***6h–ЦЬœЪпИёк:€€РxРкЩx…?˜"hѓ…эПL‘&€Рt!€Е“щђЄ1O˜*L•'…8A@@`К@v2]ž4ц   S…В“ЉђЄg`р^^тŸЙUэЋк–БmєБnЯ- \ќ3{КСи\]хвŠ*€ˆ@v"ŠJ4єšкЪ}•љz‘ џќ3UК;Аь­Jі:џ ŠQ@І(d'SєС!ьiJ€–"ИЫќ‡еR=Ћ6~☪бА ќ˜оo ­Qk›§6"˜КLнg‡ШЇ#zU+їЖV—ЩЛг3ГЃŸMY™ЪЊ"ЄЎMЅ0&dh  0Е ;™ZЯ бNĘa~л+ wЌgP•КK•k2•š)фQrК№њзљіЗ/wžщŒVF3?ДУЂЫжЩШc• sЕY$ž’<НNБXN%OŸЧПs˜ьc)ЮrнггхtВ„”ПvГ–юdc1!^нyЊ“U!€€€;ШNм‘n—@ЗЅЛЅЉeАяІ wм9­ЊЈъъюj=жj§ЪJ—§Н^фЮrlњОО>™LЦњ–НQ6є§Ѕгввк~тф ІgBqiqПНП§ •^{/UYйЗoЗœВ }лo*7qњк­л3ЌчЌПbЂЈ@фf™4’Т`~ €€€;ШNм‘n—€Ao ёаKэћц’Ђ™T|wАaЁў№A;zn|чШ |uеПšOсб‡ЮЋ дЈЫ/, ЁRRXBіЬ†ь9=дp^и|Ќ9>!ž.љЃјs^ЮљИЙ‰йCo рMіоƒ=xJ€R OM%’О і8uмˆ§xџЏ>08 w†dПd—…GrУE #ЃK$і;;BKW.йYЋЈОЇЛЇ АрДхєп§шА‹`аFa0?@@РЌИ#=Œ'Y3$ьЫДWЏŠœЩ›бѓewИеёЇgћAž‡ЈŠUutu0ћYсЊЖaЕ’@6лˆA˜,‚ЕоЄŸыдoоОyЫѓ[Ќ+Х~Бї";Тz‘абuVЕTХз@QШNDБ@ уL`ЩУё5е5” а†!WфLFњжtН.лё‹џ†фќ7чщ`ьјFВ<хасCЬgкњ4}‘ђ$њ ŒLЯ2 =nЅ’›—KUжфаwмДжЉПvэ—ЁJzrrs˜1_ ( О2€ˆ@v"ŠJgхІђ†# ‹цЯ[Гz…ZЃzЯм•ЉT'nx6Uў€tgцNwПХщЫ5мїk˜РЙbU&И ‘ќdr[[[іШy)'єžа˜ш˜'4 J•rжLs‰УрОа„Ѕ1Tцм?‡ЊЬ"QHНbT1ЁГCГuzN_ёfEО!_)]Г:U­™ }І­-9)™љ юˆmЛГ…@РcДССЗ]ЈXXпPЯ4кZNц›Q‚B…йˆ |{О;=ГЁUЌ]YЦbcЭўRRЕдTJ…d[Џ­і]чсVцЧa№Z)ц8ƒєщ.њЄeIT˜RћœыiшЬнYф–й@wИ#=—дЇИА8kw–ф'‰qoюЊgVљzЖ\VфыQр@ 0я93С,@М"•@4KcfЮхoмxхЦ  0юŠW<#>dЉDђзqw ‡ “œmОА§—I*Т˜VєЏшƒЎFўcZЭ“˜дЎ_ Бн5ЉCDp   г‰]3†Е“щєР1W˜ќnHАv2љŸ"1шhя Ы„ЙїЃ0.UІŸ*Т …=ОЁvœюpмд}ѓнSх‡ qN`эdтрcd№1НПлЛПцмJ№ыСЧА=u?…ФИ„КЗpяыџыuіO1СnzјжNІїf?ўш%єкЭZљ9ЈzЫ1nѓwР(нЯuŸ‹‹ч˜ъПˆф#‰мІ/ Цwш1<ˆё РsDcUшœ~“ўmф5}Bh@@”жNDБ@ c!@/kп@/r_ѕ$]†G…ЊВ—ЧХуэѕљёкЂwпžз‰щ}ъГЯ–§jй„Œ=Csѓ№n{ §оєѕŽРO8wт0XƒРh*LЅ™Лsж­зпL…Њв4\—EЎЪўd­$˜ЋЭt^„V_t{tьВ_fРї&ьЮту7‘ЬUY+'˜JM (JN—^џŽЩЛ~Јз{яПїHbЌ$ЪƒЗ!БЁщЎФ ыSП8qЦё|oHyє‘?е§I.уЧЩGA+‡ъFт‰‹‹sy^.q €"ŸGў|Hюќйњф‚!ЯьЙГ№јБ‘AЯ—=2Љ3ј[†Ъœрт‡Я–= О= ІЉЙщЯ‡џLK‰Д’TіVYa~сКџПНГЋЊJїјОФ<`6hЇ”@M!š@M•`ќЭвЭQœJQ3 Fє‚’_˜п^RБ›zDгР2qЪА2ЦS™8W/dдс^ЩгM9<ŸчО›}XlЮйћ|Р>‡}8џ§ьзЧЛоѕОПu<ћ=k­НїЬфŒДŒ™3ЇЦ`cŠ™Bi]]]•івХK­ъЃа$",<+Лђ›kњЧ _qV[й%`ЫWыг{kќюќЁКДёПџы\б OG<+VИ0аEТ.ы! ŠА%4QЄ#s%}њъuьKŸ(лG`.iЙDИФ’L`ПРЦяoXюtm}э‘Q#л›гEWъBЊЁз пi1Jh/hWЏ]]}БњЮЯwј"Q[Б<еˆГЌЙ];уИŠ3уЧŽgYI7t7фИ‰хэ5‰uMaм G-ћА,aJ§9BMфPмјОƒ=ЬxqТӘдt Ё ЅщГ!V%™–Г„ХŸRЋІZа#vЏЄ14ѕ•ЗќЊ:Pr`їЮн. шфЫЪЯhBHR…]$ „&єHxЋzшЅ6Veœ/рщ gХR€bѕЧЋѓНE рPбтЪŽ–Э_8ŸѕBй БбBі^Oўw']у)K‹ПLЦ§СэЭЭJ–цsЧ?_Ѕ$Х$ Ÿ]№ьšUkінOлkhŠўЁIŠЩклѕGЇ?ZЕr•œ6Ё<@а›AЁœIтЎi1Ћ`ћŠNок§њњ л…~хPєя`eу-дŠ i ˆqюЄОŽЕ’ћlШйЦ ЋІкЈЧD­I–>љ§ :uМЬЛ—wЬяb6lл@Г)ƒ ўG˜#лu4kТ‡&mП(,(œ;g.-q\ˆgWЕ4уžg3G=˜@іŸВiЪКфbК`гYђN e3ВВ—;,Ђhw(ДюО"gуаЗO_Z5`YJЌYНFиРF‰9г“ьm.Ve!=џљљЙйYtEЇя/кœHc-›T555бVКЎаХriЮR“ZЋY ]гB€IsBqэЪЕˆaЦ[ЃMjY6ifЯ­QOgЮЪЪВ*[’&™tMПўњЩPќзbяћќ‚C‹рr(’ІЗкC*ѕkVциbƒЙŒ‰фTЎшГСфх>ZrЖБ†BТЊЉ6ъЋ5GЊZб;jtє8&oWТФоЧћZuF>bјННŒЪф>rЖ™и`еTѕ˜Ј5ЯЦФФаJeтдDЊJLHЄtЬ8уNgsa”(B љ.gѕTЄ#e•а\ЮП\ЙtiтВнЪюŠUжJhGмЅ%YhвЛ…]Б&’ЫВ]„kоѓZбэС!!!)LqОkниЕрЌј]КГg}~іsчcA.A€v“аЪŽpo3˜aПЛўЫ нME—/„ЈgWьЩ =АwеdœPК%;6&Ж[LъЦЎЭ Ш_›OЫ=ќjбЊœ)OMщ,шд•ДИЖSиЦџm+1&дчE&toЄњ ƒE  `$@гТmЯЮ'в] Юš@ЗЄЂUПШЁН|§ь]Нr>@єиэ 'œ ТŒЁ4+Ї„ ŠLD7Ња@˜фHХћпўш‹8-<~д˜”9sIЮБКЭŸTсиў нЅа WЗ,rЙ$+"p—OyЄ=4ъ† rѕлЋ"9е%ЈnHœcš?Ь?оЊ‡S’јщn—PzиˆРю"` EŽЃ‡я™ T™—ЋЄб‰JТйfаЌЩ‘GєЗ-=uУй6)дп›{оœЗ`Ђ…pB €€+Асy'ъtб‰:ЧV€€@з аЃC\ђ№pIЋa4X рВП,јdW•јб)Ж4ДWоŽ“ЁїЮ№/з5{h›ИGVЫтZЄAР}4ЗpVOuвРм‰:ЧХ9VИж SЮщ Н8š]‰нaG-Нpг†MqтЭњAК‘цNК>КюсшyY‹RC 4`ЪяЇœњ№”Cv‡а„~}сы8МвжЁŸ$(я)јїTИьЙ—КЎЮЏ€Јѓ^їЎћж§ш{aкєi™й™ы6mѕщэЃНЌн§FAм$ќтяъамiКcѕЉі]ээAРѕ а[Zпэg“'$|љ‚К.˜;БiфzЌ(=яф_yе§Чц­›33вRfЇ№Џ˜їфТТТ wЭjсVцf‡>2€NzT9{‰(-Э(3z ЭЕL?A[]UrЄdL,e§ЇLœ@/ъš“ион{Ї)™СВ—e‹››ЛНuѓVaђ†^ђзўLыŽRѓЧ‡‡’*ѓVTrц“3du=fєує:CжЕXИ}WG GЭІŽB нћf›BЩBŽ“4IВ;ѓBЁGњЫвіˆK9.9)Йьx+геыўx; Vє єŽbлНБKиvЕ]‘ФмIWшЙv[Š“Л*гWќžЂТу'џN/єъѕ›О#ЂFЬš9+"‚lиca’7й;œ?'д§ЧgЇжНКNвŽќЭљ?мјс‹ЯљяŽД%i”х_tоzœћфєЛЧоѕѕё-к[4sжŒИI‰я–Г9K—”3>ŸцьЙГW|A-В–ЄmнО5+;KhnђwgсЮѓЮŸўшДooпkVЌлДnэъЕ$ГusўOџѓгХJЃ&­„ьТД……[ i{НQyKС–ф™Щ’bBсжТ­—ПН,tДeл …r&Ivg^HЋW—иЛ†ѕђ’—Wх­J˜’ FюЄ-NѓъэeС#T@ РОXЌњBП.ЌЪ8Ys'NогКЃїЕ мО=ћЮ]а+=6mв“oэ~НЇ9й)u7}~у#йє№;‡ѓжЎїщуCчњЕы9ЬФhHуЏёђђJŸzѓч;ыжЏcйъЊ*&–їjžаœєьg?+7Iь?Аw§КѕМ†о^+–­8ўžq dџ‘УL`вJШіъеыGнКFІŸfѓЦЭ’2Ќpџ§ЄGш(wЅ1в’)”6IВ;ЩBжЉэ‰˜'bМэ-LŸаŠНМ&хйл›C\˜€ Гуъмž‚шФ…?uj0Нњ‹ Z2№ячOЦаFL\ќЮ=oRš&N„ПB‚7Е…[—Пnь˜(:)Сж#H xёиёcЃ":”ѓM:uЈb]‡уњhњъ–~ин нРР@СЙР~4эФх—Z Pш_qіŽhNHЎ9г#$ъkoŒŒйК тOВОЁЛ)”пјОƒ&­„ьО7їўф4 ­4љф”Є +фі3zdЙPЮ$Щю$ ™~ЛK^ZВ}#‡ЕЎИe xэвapMєhѕTЃgˆNд8*ЮГЩ†Аš#фЯ‘#cзЌ^ЃеjљU"‘˜іџрdњЫ'ZЫwьмёг?+=Iч?ў@YЃ<ЧЏ>ьаБ“'N’@{ЙH›XГѕДѓ№Yъ):6ЎДЌTR"@Р~ЌдезѕбHŠY(ьаМПlѓ>§hqжAŒG}ƒ 3 $;Ђ2ДКtљЋЫ7l|љOЏ2їzrЭЭЦ№^”Ыђ ыыXVHHЪ™$йdЁИ9{Ф2BšПйЛзжзђПЌќ’6™  z$цЛœеSŽ#:QчИИŒUл6l№рkЋѓЂbЂ&OМЃ`‹мfУуя_–НŒ&шx5ћUЪ2'—-1–“€Иœ Иb";+{ліmДŸ”ПŠЗpРeЄЅ Ž$ЭLЂNпЈЇ3geeэuoоzPbЮtйцѓŸŸŸ›Х‡2-mЊЅY.Ѓг[ њ5+s${'aК#š9Ўщџš™п‹(к]D mFY‘Г‚5œ3{9B…4њљk и’…r&Iv'YШ:Ѕ„œ=b–^ђђ’л 2—dт–Ц‰žO€ў ЗpIќџnсT%D'ЊчeuЦЯŠ€Wo.uб‚ž;[БЋАр–С@;Qк&ЩіцДœсп–-јŸF-gЕœLy{л6IKœ‡ЯBOДјrєШб?1*j䈇,_Б|ъSГyzёНп§~Ѓ"‡вљрRж‚ЩЊбQЃЧE:bЈŸЏ_VЖqŸ‡Йdк‹iУЃFЯzfꈇ§Ї-ž4q’ “›K щТqБЃFG3oH%$ќќГГњЏZНjїЛ™э[ЗПџСћ!zzъфЈш(ж0+#+tpшиёc‡і@џ„rЩB9“$Л“,dRBЮБ K{{z~dpђtKл{™0 аCа[[ п]5}1_вZХџUхсYWWЋJУ`”SPрЌми/(;=#6ю с7ЏXЄ?@гЗЁNчпOCХ ѕ:к–Сj;–АђNšІšр ,кUdюmz }Іц[Mi§E,l!;с|:ХТ”fђ,A… аi"I“Д§‚NЁм\•г.ь&ж<84X<ЙеОDтЩбfXЖж(/Y(c’dw’…bяфьa2,A&|ч`ЮВLœАбDТАауъеЋC† \І4+W'ŠL<4§ƒдiЌr8ZДsRТ\~^Цтђг z=Uе5ъ пиC“э‚Xп>їждзВ&&&ЌоО‘$щЄe…*rscaPОqћFzІ*kвЙ„УЙЁ$@KlзЏ_7З\а˜ і _kmчеoљўo[‰1a>ЇЩzвЯ;Їu†ŽzХѓ”œ4ƒў'Ї›=#оq§B3€8š}ЙбWœЃ{БE?Ђ[(ѕ@™”жчЄб…МчљFЁ‰рƒ\‹IšщџАƒєC-€t M„ЏИю2€ѕ‹ш„ЁpЛ]ТzяС@щЏJўї`Шp @Р рy'ю<њ№@@дHб‰G6€€€;№РђЙ;?|Е ШФ#>nЂкЬ‚=   nK€"ЗѕŽƒ€€ЈE&иwЂЖA=   рюИћ'ўƒ€€€к :QлˆРpwˆNм§џA@@@mЈmD`€€И;Ю<Щ>lфHwЧџ{.|М{юиТ3—!`wtЂ­Ўvч`(иIo;A@B+;С Ѕ   &€шЄгша@@@@yкЫ5ˆN”Ч    &7)бIЇщЁ!€€€€ђtuuЙљ…Ъ+†Fш,ЛяйЁŽЊЊ+kkk;л#к€€И    ˆ‘‘іzыљCщЙaЛmo&„&єvcл›@@@@Р= ”Ÿ:IŽл xrПВЭšPhBo7ЖЏЄA@@м@HpШ•š+іF'иы~Ÿx   ъ&рёzjЂК-„u   юEs'ю5о№@@дOРCулG§VТBї!рСyyЛЗ№@@@@§<8Я^ъЗ‚€€ИŠNмЧYx    рhW,Vv\`œ`"€€ИЬИЯXУSp П/2И†ЅА@@@Р=`з‰{Œ3МW аSп0jс-hpй>˜6йˆQЖ “ЭBžяПрђ–ЭтЧЎгiYŽQпZwnЅюЭп3—ЛsT”юЃЌ,QЬ(Ык@:I€о0šК0][пЩі*n–<'ЅdБyt—UО u ўўтN5ўнг9œ\ЋВЃeС!СAƒММ;Н‰mSН}jЎжьћы.чD'ъAAwу&@П2ЫO•њл!нM]ЬИMœ3t Їѓ–ўVxXј­›З|~уC’ЭЗ›ЉyёОтт}Eх'Ъ)ЪaЭЋЊЊŠїSyqжєŠЈПЉ/љ[qЭх&l!бЎб‚mU4qRљ ЙХm›СgNŸdЊЮžЉЉi7’вT"Ь$хП–/$LzŽŒŒдпв:|шЬЉrbkRkcVA—-їШfS(Aqеф)“Ѓ"ТfЯš]wЭш5Ј:[5;љiЊ%’dj%[БZл К\№zСќEщ г’}||h!848џ5ўqУtPр’Е$+jLTTDTZFš^o|zЁœћє1иQАcьјБccЃш+(ЁПE;љBR’Л2Wќ™gЖ$tйМ;[џљƒy)J@@ {а\БmЇ^ЇЏњ”Ў|s%$8$ыХЌфщЩAAњŸѕgZ5S8B*M_ ?sмТ•~Pљh$5Oiщ§Иtў’7чMхк*-E0ЉsRг_JЇoaпоОМкжЃЁЎЎєDilЬԘпХјzЕ–[ЖйиNцЫmХЕчхх3:ОќD™`$3‰7јМіЧVƒщъхнл[Ћ­"™ˆˆ˜кkЕtI#КkuФM\šЙ”LЁЩ$:i…W":§§§cbbвІ‡„ НRs….Ђ-–Бž–ёеX,ъЮК*Б0Еg)ЭJ8юьЙГп3$–ў2•вБџШс]…Л„ТŒєŒЉ3І.Э2V jјы™v\ fРи:[<#сЉКz]щбC>}5!ƒ‚ƒ,яЂыАяЄЊВќгђD~{isCƒОьDM“АШ†ц'Јм№‹AгП=ЧаТ›dh›BЏјМ"фбЁ|hвЈ3ˆ–К0~ЖКмжEsXXpй‰ђ ~ЏооЌа№Ы­Ђ}EmYў_ўR­o&,šœћЧЙ‰1БДьEfs­ЕJЪwнТе\Ѓm<5:§­A!ЩЩ>}| ѕЦuq/JЫїkMіBЕHDаcдце›jј4 р>єdН№‰‚лДkї[;vю№ћuЏЬЭ‰I…tШЗъ•њЫŒБЎАWŸОz}ƒ=˜HkЕ5лџВ§ыЏПОѓѓОŠПяжЈYв‘КўўštшНёћSžšвЎYЄФDВ]Цщ)о(   ­ѓЖC?.#4ў1Ѓbjji9ІЂЊ2ЄPа  ZЊ9tmЛ(ТWž­№щэkјEWqцdlD,ЭCxбЏе.sыK Gѓ+ќд]Ш;š”њl*эPЉњд‹‡l<,?ЗЃ~ы*[хуGG–|&9Ёm 0|ŸwњМtг‘Z8ђтЪ7gL~ЊќL…ЉЭR]74шЎ\ЃжвM‘с‘ќ Mo/ššтяЃ–’—6XY—Х}˜лРJXBgйжD№Рр­Џ­Їz5t^оЪоџаЈ•‰™Д2Vлќr.GGE—Ÿ:™œ4УМяW–П’Й$3vC$ІЭЭ†‘бOДŠ”#š€†zПџ)њhNўћ> 7лѕГЖ,б^'ŸВьВ|;[j<Ж§ЕФ9Ш€€€У мхтй~ъ Э:НŽіXФЧХЇЮKе ЊќЧ%ЮлЫ\ƒ`ЙБќ.WuОŠn~ЁŸиTbhсМњњюruWыŠп)f’AС!х–7гš/IhKЕtљŸœxщ›ššыЕцI–XтfЫЬ6ъ…ыэCwжœ9_Х iѓMщёRђ‚­V[| ˜d<%Бqƒ ‹‰-;UЮyђ^гmеД$imeeЅFЃЁЛ”SfЇ…ы› uѕuќšˆЁYR^ВP)—M”“ZЙ“*–e‰меkjъj x kл,X!꘲ЖВ‡=ЃLн-ZАhяоЂ’Вв†лz2X{Е&keŽ`FSSm‹ЂиЙЎAЗfУ&ъQ(g “,Э‘ЌоМБЁQЏПmиВГPЈMš™”ѓкjšzЄ,}Œ‰ŒI+!kѕЏЌПJTxvџ*Ђn@€€ћ щ_ј‡Р~ДрBw`ведœлwТ?яDЃ‰2QјбK“хх§-š{4’ц „Жt_ээ [W(KSД‹–ЎаFЕїpёёёдŠ–H‚†›їхœКщЗтг жWph8нS]Z^Ъћтуљx$ЙYzЌ4ќЗ!aЁaДз„~+?L‘Yј№№Ё†а ;Ę5wЮ\ІAHФ'$I§m=эJin_2‘rНьип^–НьŸЕџфй>)фќўб#€(G€.ЅЭњfZШ0WI_Чтrzъ‰А9Tг/(%8œП˘К[И№‘сLŒ”ј'т…ЕAmћЕќ.!!пN{›j$zdJLДїоІ4і‰XMRћЄ=Х+сУТ)>|Ё­О‘ЃјИŠŒю%ZЃјŒ x"Fиzi~лАdxзжgwў[]-оtТ[ТJXBАeY"vl<&жГZ“V&bЮЯвнgызђыP&8Ќ0qЊqѕGж‘{ИŒД :Y!AŸ%ѓ“‰“&ЮЬвD і88њАFРa+йuз%&TkјјBaа’‡бЪЛœљSޘžцЛЭuпЩъьшЇХIj{\fН3§&їнёэіЗ ™ИР pМƒц’LЇ Х\VТчш€ЫŠqŽ›’€шD1šP  No|[Ю0КѕTЎJЩrЛvЪtlС jс$Gdl“(VТeЕ#ЃFš”TŸ3J1pjV!—Энd^ЈЫ_2K!—™ƒтžw"І4€@$@Wnў™(2‡љl„Œ`ч‹-ўІЖU­e/H‹БеVЧМ/IuзцŽ8eRЉr7ХN+хВX'K{>7†ѓСђH€€@ЗpШ7^нѕіЇЙwЋw’лъВКНtMЎаV—хкЛ`ЙКмЅQђф~еЅіh  Ъ ‡Н*ЇЬ54СeзЇЎYщ†Ѓм5`чq№ƒЯЛЊэA@@@@9ЪЉ‚&)n7!фи§’RˆUP†QVtpЯŽЂ8Ё @ Г‚‚‚ŠїЧŽ›иYъmWёёIђЮм>ИlЮФuK0ЪЪŽЂeyB€@' DŒфпЪF_ёlЏтf…о™и—M€ИtЃЌь№!:Q–'Дtž]­%ЏтзЈњ–pYѕCЄ€n8Ъ]Ї†}']g   J№ШY˜ЂЄ>шЎ№р_…@@@TCРc§_ŠUc s'ј€€€Ј‹vХЊk<` €€€€‡€€€€€š`юDMЃ[@@@ш-€€   Њ"рБ%'[UС7'рiяѓNшUхЇN†‡И98И   `•Р•š+9Xгr\XЦsщšЭ‡žЮYN oС Ю,‹Ё@@@фоШШPhrъУS,+$:ѓЄXМаШ"В    šьŠэL4ш*š„…›шBtbY‡‡&”6щб‰ dA@@KР$41пwтQrоБ@;€€€0VC’Ф[.$@@@K@24СОЧB‡v9rЁ •›4ё8ПЯŠ5a‚,€€€€Т,„&ћNюъ@@@@ #ЛBjъ‘ŸkЧƒb;і…€€€X!`54СО+Q      [B’1щБУ“ь§ю|zo‡з№˜H#    ігMЂУIDATh‹+>Ї„lš"БЮџЮZнОлшБ№IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/29.png0000644000175000017500000007143011733011756026244 0ustar sylvestresylvestre‰PNG  IHDR8РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэн tTеНјёгПщЪ іŸmb-M|бD!€ъ ,|Ъё ^DЁVQATD­‚rЙ@­-Ј(Z№и ZНAЄB!or˜\!IЏЩj\§џЮœ™“yeg2яѓ•5йgŸ}іуГw˜чœ™љССЊ*У0њо2Wžy € €„јшгВdŸ„Mчн0'\!ђ@@D я-3ГЌАЉЖЎ@@rЂyЮЩ|4zЌп<#€ €„№ENOcИбхзмcдЙІЖdY.#7ПгёнЂk‘Ѓ@@ цэAo эT ћр?чдTзўnЉjVЙВŒNч 2\9*Гѕ„ЇОvЯ–к}л;_иzaJ € €@œкџ‚оўк?ФиіAENa;ж№щ+'d0N-СаOПћшы:WэёПlX?ЫјЁбaаcЁћЎОг9У WvшНсr]9К•јxƒбЎљ € @іП ЗП†і7І}№GN:нЪrхццК4ЏПЕ5lВ:ўе…gцOКЄ0ЇЃ]єаFўО{_Љ~aUЁ§({ZАv”d@4hџ zћkh?_ьњрœќПCѕ­ANѕrэЩ=.їрЗЯСн лжyЬ˜\Т•etUQЋy RBъ UэЄKŠr:ї=ПБюћŒуŒ]žќVkГ œqœ[ПАЊг~”=­ ДЇђ€JиD@ Eкџ‚оўкOг>„ RКxтљFV}юq†ЋЃыјcŽїx<BеіЛN(зM ›фсЉw›б•atЪjЌmвК˜›хб/,5_єшЦsЋЪ•ћДВ|wЭGЈ!Т.o7yB@Œh=rъ№уТю?3†—fggWWWv;Ѕ[е7U=9ЕѕЮњИB"­КЉХ!#ŸqѓžЉ qьЛї˜знф1wђHyžќ|Х’ыŠ+ї7N\ЖХ•хZwGЩ:Ћœ {ъњ’ЂВЅРЎo|їМ?4yЌьml26юv?њзJы&*ЋB ’d—<ь›оtщјљЋЌ]ЭЯYЦ=П**эžŸЪlLIсАољљ9йѕGW•Л_њаќdvyЈž[›ЊEk“g@R[ Ф‹ВN‡m/ш5ікь­{‘швЁћ`oNъЕ:fЯ йVjяšчЛњЊъЊТ“ _YљJЯž}ыъыъЬ›И% s”дЊ*ЖWд2kддeхЕШ“jЭЋНшб­яоc†Gї-\ю‘НMЎњ#ХEyй'e5žtJЁеж•g/эpIf§У8Tх2Лg>Ж~Zљц‡•ƒЯэqёYž#ѓпs[љђ|†Ћо~!ЯОйСp}нdc`іФ​‹ѓп)Џ~{sхЅЅEЅgјыЩsnбИ_цKd6чљŠЫњŒћe‘œ {іУц†ЖVTПВБвгш9Уе†ыŒўњљ €@’є^аCtNН ЗЅ†Њ!DэmЬ г •F>я{Б^u/lhЕfœвъУexrsђхqт)Їw;Ѓ›ЋкupЇ[оjЇyГИдouHњ—лTЃš[rSБЄUЇU~фDm“Wmны–8FN†•tЯЎЎiЬЮђ”œœџ_ѕn‰Ђ*ПЈЮЭЊых‹{Ъ>йсљоxsKЅФ:ЅХљ+6V№‡DRЌSVŽUЁдimZ­лгVЮ bгєЃ;фЌ•U›•/ЯУЮ2wmй\!Ÿ_ѕЦ'еї+о;џЏ[ЊxЛ*Лжoоb|o4x#ТNYеЂЊ €ЮџLE№`­Ј 8?9{X‘‰<ЋД4Вc№GNўпЛ}›пзЙнЎМММ’ГKіTюqЛНZ„CВBп$aSрI&‰Wь™RЇЁfУЈ3ЬXч?ПЈ—ШЉ[~ŽL+ЊЭШЉ{QЯ§цwШьЉЌ2ЯKљ+Љ;т9аt|­Чь’М5яЇЎКZэd’П˜oЄіЭ–iпVR›‘[[o`–‘я­яЮ›.іUтkШ]ыё}0•œm2ћ`фxЬsuZ'фTU$@Hš@˜єжћ#ЏЁж z˜‚уР:U ;кОЊ*`Rg›ЌАЉEЧBѕAђZœXPXTdrђ)Збгшъ˜§ѕУ„Ў №Š›З”СљіLнгXVеЫ­K}zegrп•„JЅgЅН $sЯ7n ­Ќ<вhnG—Ї>ЛCЧ\IЫMHr—y‡Ќ­tъмЅC’‹€<хv”Лд}ЕЉBюz3xzт™UХФ;Р\ы|œ­!‘‘KUF@”аz• ъБ§Ѕ6ИћKП§P{ОН{™швС}Ћ^ѕЋЎѓLџLЅadзeљЎйљлб‡џупщwЛЊroecSЃмч$'œК<$пЌі [Bє.Rѕі}.нc›Œ-_зчw6|№›њЯЋЭГMВYљЕ[ЎЭyдйУxvЙА8КФМЁjЧnЙџЩ|ИыЭЮw;ЙPn0ПЅTнБфнцiУnѓL[‰­6UpеЇе’\Zт9&з8ЦuzAўЕ— ’ш­ƒ*A@4а}Q14п zћkQwГТѕA…MRп’›Š‚Т&Щ–hsЪuЙђЛјюsъбЃGNuЮі{\ђЁRжЕЇрШ7аE§а>ЖЌВОєДœъ§ѕžяы4VT7dяйk1іБЯYEЫЯ*’ЎЪмыЗьЈѓžšїvедK Ч-ЋнЯЇ6жv4J!ї†єъwŽс‘ЁоzБœєкёпѕ/”K7\мЯХ& €@š hП(‡—ulћkQuГBѕA…MrЖIТ&ЉQrф,T`еAЧЊШ)rЌ#Ÿтd>JJJЬhЩњ1ыŽ|Tsыв•м&Зе3•keЊM["DЕЭ­8зЕЧлЂь5 ќmW§юНO2мо dЎпО\yЖKN)yjмѓжl—џГb)#с”ЫŒfrdя'Uw>ГёЄЌ:Оьђюo>Ъ^ƒЗХ&уПVŸёЮVo`fv@"Щ?oЉџ“jЙћл кšЬ›СхђœђїС[ƒЗлfox € ž*рю~ˆА#/|ц nЬjо‹tЭ—эBO-GсœќП;—НХШzisUЇКњўып[_їmнoдўO­ё#Уsт:у”3Œ#П’Ћ^GImAŸЫ5мuЎ–%& uЌUџзFОЫ№^"єWnžдё^’lY†|Ž@n–Ыг”эёGˆЭ‡xЋЯЌ•˜ЦЛЗжШ—’ЙоЛ4W.R­!{ZТЌЏ›ђsГT@ъŸNѓm†ЎrїКUЁЙ)w5љВзрэO €Є‰@јхр˜/ыъ>!ѕ‚Њ†€3)ЭUй ЋšwG›ВWkЋcќѓ•Dэ”“Cž ђж^ћQіДь•Р+м58ящ+йЋZ№%jмЭ6 €щ#аЮ—rhћkhП–ъCsЈЇнБH‘“сЉ2ОЊ­•KOЧuј№ПоНАыѓыъМ‘AƒЇСЕCо|пааTыЉлощЧ=[У2ІeЎlйЛДг:SіихЩB@8 „xQnхЅмъŒ_XЧЖП†іOЗCkEs"FNYЧз~{БG"Їƒur‡ln*”+] ]=ž{Œ,їƒліЩ*ЃSWпЇйk бЧцнS{ёHv"€ €@LВдН,mЏжzAo mo9№ˆ˜іСЇјлыp\ОqмПЉЗжзZћŽ3Ifcp'{i{ZnєiђШўэy:iЙ =Т}N:5P@b&аўєізаўСФДОˆЩeШgOХюсЪЏ­ЊюTXаІрI‚­кoЊ;Иф6№˜v&vУЂ&@œ%аўєіза~ё˜і!дЙІvwбu\Ž|I№ўЏB|+MфК;ИrфиШeи‹ €‰hџ zћkhџHcл‡ИDN2HщЅќДДд€ €Ihџ zћkhџ№c臑SэЗцpѓ@@А tњБяЛкš#' ›^јН"іcH#€ €ЮИbiЅ<§gŽŸQ#€ €Q9EЦ! € рP"'‡N<УF@(ˆœЂ@у@pЈ‘“C'ža#€ €@DNQ q €8T€ШЩЁЯА@@ "Ї(а8@*@ффа‰gи € …‘Sh‚ € rrшФ3l@ˆB€Ш) 4A@‡ 4уЏ>@qяоњ…)‰ €ЄЌ@Eyy›њMф$ ДЕ™6ѕ‰Т € €@Ђ8ФеКЬ M € €@†9eШD2 @H€‘Si@2D€Ш)C&’a € €@ˆœ€L € !DN2‘ @ @ф”dš@@  rЪ‰d € "Ї г €dˆ‘S†L$У@@9%™&@@ Cˆœ2d" €$@€Ш)Ш4 €"@ф”!Щ0@@ Y hƒ&HМРкЕkўђі[;їьmјЧ!у‡F‡]NШыєгŸžpв‰'MКmr§)юн[UQ^ЎвIOШH_}§е{П:њЃвщ[ЪvUЧ*dчCfъдFMТ!35+Є,@ф”С“ыаЁ56z&о~Чжђ­Эуo2Ž6:tјPХч_FYt‘SsmqKEёBЕќХ›П n=ЪЬŠЃpЮLF…Q 9EХЦA),№Їч^PaгЅУ/Н}т„ММќšwйЦВЅK—ьЋ9”Т}osз^|eЕ:fнЪе'ЊM €ё rЇ*u&S`нњuЊљYSяЪюш’M žFŽ5|и№ЙѓW{3 БЯНOB…M)u1QuD* АfRyvш[Њ 9ЅкŒаŸі ўІ9˜№46Z‘“UivЖkцŒY дьw?Пђ•OЖnњjџ~уŸG;wюzійg_ешЂюE%Cnъ^И~хkЏ|ИљУНећхюЋЮЛœнwРш+//.юaП~dЕbЯ љЊf/|ˆъЊ:ж^О|г џ№ЇЕыжњЧЁŠПћюйвШ#.џВЪф=ЖƒёбћхЦ1†\э§ЫѓŒ&УШ2Ъџѓ6О7њžпћhƒй…S ЛОЖњuIlјы†)3я1Гф‘et9іи NЙАємQ#ЏЪЩЩБВлњ\БmЧŠWW|ВkзсšУо‰ыrrЗ“ћŸuюР „>їfGАšГч(ЋъЏЋžх•?йДџa)vB^чsJ\wеU*6ме­дl" {K–НАњхх‡:хХwмvGŸ^=Є­Ч.иДщ†у”SNЙqь˜AR­Оќх•Ћ_]Нџ~бˆ+GŒНцкp%U~Ш„ЮR y ™d†‘SfЬ#ЃhшœпѕЈ?xКїўЛoПѕŽ1а†w6Ь|№ЁЃ цНежCŽнїЭО7џђцєЩЗл_Zќћ[ќж?|уeSgЭДnті5Tshпš7п\ѓІzСnQu<7fЯ™§ц_жл[аШ€}љТ29PЃŠЪЪтюE•{ЋЭАIM†Є%Їbз+l’<)янg|єёf+a>7‡ўqєаgŸUЌ~sнŠg—хtns№$їХпѓРƒЭuJ—ФГцPйЦ­-\аRЉљЁ9ЕхmрЫЊЃ_VНМцЕ—я›yџАaУэЇu&:К&ц<6ћх•oZ-V|ZqгФ›žœѓш“OЮS ХsЪнї<9Яt~s№Єz8чБЙ/Џ|йк”ЩэqЛПќњсћџ#ЁЪ‡Kh.•p‡“@№Љ0‰ Ё…Ра_Uлe›ЗŽИvLп оvЧDљџzuu•к%‰Ъ/*хDˆ6 ьпчнѕыфdЬеЃЎ6Ы4ђвВёяeіђi§УхУдЉSЌАщиЧ>њР§rzІтЃ^zі™СƒKЕђJ№boхчЋ>яR‡Ј2сЛvэZ§ч—T њљх€ОЊЮ=;ЖKКъЋ=*ЧJoпеœЃЪз~чЙџžщяОЕN§рнwЇпqЛu”Љ џєGUƒ~bёŸ–ЊТr+›д)s'wzI+ХП(VЛjШ*_ЁIB2+vWоу›ЄYЌЗј,ГB‰Ѕd—PЧ'Zші4q`пY6-љкm2$N’гl’љЈЪ4Œg—Пм1ЩйЕ{—}8’#QЛФy! ‡Ыд_*сj   rЪ€Id-&Пљвсf8ЂВШЉˆ  НjФœ‡gЫх$ыБьљч|чK cњ”Лѓ:чЫХІi“ўMИтХ?ЋtpBџ№ЇŸ_ІЮaL›4YЮ[˜зqЩuК'}$ИцxчL™voбiEЊ§є(ю!‘ŸuрЖЯЖIтѓ=ŸЫs—Ю]ЬєWfкЪ—„””ЫI’‡ Sю3“ЛЭ$-—чь'ѓ6}ИЩ[ЄmO‡ћЎЩJгуЧн,uЪмЩе4iхЅчžm[]Жв+^j^wLš(KBЮ‡нqЫD_‘&У,ўЁ3бQ7qЫПM”e3АДФоў-7™™У•ЊЬЏі|ЅвіDˆсЦŠ7ЬkЉњ§ЅЂ_'%H;ЎжЅн”бсжŽ1Оџ‘бWŽ~{§лђЊlн—у;ІЩxљЕ7ss;YLАщуU]CGPi•(пЙSЅƒњ‡ђQsp0Ш{’)ИЖDц”ћЋQ§HtвЛwoy—Ђј‰Woз{%=iмјч>ЖkЗ™охWэнЏЗD‡VrЊцWW|МуЙsшш?Њ€UіЖнфnжy>Ѕ[Б\Б’’ђawN›в§єюнКuыQм3ъЛІЌFэ=Кћ”TBЪи їSgЂэ5ЈšU"BEEfА›нБХ•M+гt–ЫНWэ—žэ=TMЈ„ьнЙ=в ЗnЅэтO&ИBrHGЮ9ЅуЌбчжфtЮд;ЇЩэЩrЕEЎeШ­Ъъ˜uызZщ†У‡TfШ„§ЖЄрњ‡Ы-Нъ№(ющQЧЦ*aПk^ъдˆОрМўV7фіљЌ‡Н•;Лt>vфШQђ,iЩQЗн\аЯWrућecn#1ы—_э3_зmЗIUъlœU­цѓгящšgžш’ЧњїЪ<ѕє­Пrо%I%7M[љQ<л)”’JH…іСѕыLДНUГJDhТМћ>шбœйR5Ј „\ОУUТlK>'Ж-{чCљO&ф!d"vœsJЛ)ЃУmHeиЏѕ8Ѓhш•ОГJъх­Cч.r[БUљО0џK‹fњ‡лKЪыz*Oі1кЛзЊCIџцЋEы7Ќ—{Н/2Xоd7 яyrзЙфЈšіhЅŸ\ђ{-нп§#х&ыc ћлОд!њ ЙкјњkolйМeћЮэЛџыыђЫЭзь&3Šђ4=Иxў“њUйKк)xЌ%! UF ЈtpТ~xИ‰Ж—‰Ђ‰рF5sBЗѕ# 'Иf{ч[]*С‡“ƒ@fpЮ)3ц‘Q4 ЬИяоšУюцmo*?пМУЦztЮѓ:Їч9ў<ЃlѓF•жLш> яUч[lЁ2}‰$§GF вЯ‚ ЛњOрНјъjЩщпз<Зd=[9В)eђN№™яџђKЩБ#‡ ’А)рV}џЮЖ§–г-Ѕч” Џ‹ч>Й~еupyЋпољœsš—ФŽн;Ќ:UB6и ЈUBgЂлй„jЋ­ 5 •Юьyf›ъiгR‘рX§ДЉ #тDN)>AtЏЭrцcјeЃф-м[ЫЗXg фвьп5ца }o•ПaЬhѓюяусЧчIyЙy\> ЈђыЪUЋWŽcфЖѕŸpншc§ Э]ДPо”nvь{ѓ\чЉVКц7ŸЈЈ№НlЋНёKшФъУEчњС}оЯv*)1ЯBYЯVŽl^4А9Xьќ3_Ј*љол(c—Лѕ­ЊЂ~Ощ–‰ТhF`rПџїž-ŸlQUЩ‡ЉtШDчЎj^ѓџ№”œ7’IјъЩ2FЙ!dVІЮDЗГ‰­Gоb8†1њВЫ#АЗ­K%рp6Ш џ?ч™1F€W@nІ‘OОQ~cWщsVёЭуoЖrф^ЈћяЙюЃц‡їШЦ7нrЋНdЋi§У N*š7яIыѓœЄoђADіЯ"zј!плы†ієГцЇ%ЩcЬ7Y ынђV:NЯњБ:аwР/—§йїЩ@ЇžrЊѕŽ9y>ѕ”Ўr'“Uц—}Љz;nЬ5>њ˜Е)oЄ—ФеW\ЊіF—/иQпБгЂ†,уж‰ЗЕШ кˆрlЇ;аЯь ВЅ‰}яЛч~љРЊ њš3t&КM47жЦдЇaŽ-—YKЯѓ]QеЌЬољ(ўd4[Ё).@ф”тDїк,№фМGїьќ|ї—ЛіV8\{јшбЃЧўаь>ЙшЬ!ПМ р“ G^6МЄGW^}eг–хГ•хЃЈхNŽ3O9ЙзYgОppЋmы./QrEЩџт_ЩэAђvzЙє#яT­LКeВыИмПmXїUеўpяR…c›аˆД[вK>›Рќ0Ly №ŸђІ/њђ+3ђ“Я#шсџ<й”O 0В\/>Пtџ7ћфќгˆ_•ЯЦeWдљшІѕeыЗ•ВѓЋНђ~ьэœзљьg[ŸЩЙкШЮ…љт[6э—O'ї}†јйз]uНЮgˆыLt;›ˆ<Кp{gNŸvт‰'Ў~ѕХ§ћїзеќ ёбз†+!ПMK%B=ьB }~P8dвy7ЬЉuЛkП­~m\ЄџNЉAЪЅыќ?X5G@ ћmјќЃ ‡8A@?ЄЙbieЇ(_У}NNXŒ@b#@фGjA@'99a–# €ФF€;ФcуH- €@Њ poSЊЭ§Щ Ю9eЦ<2 @H„‘S"”i@2C€Ш)3ц‘Q € €@"ˆœЁL € DN™1Œ@!@ф”eк@@Ь rЪŒyd € "ЇD(г €d†‘SfЬ#Ѓ@@D9%B™6@@ 3ˆœ2c €$B€Ш)ЪД €™!х7ўїюуg € €€О@4‘пП­яKI@Ш$Ўжeвl2@ˆЏ‘S|}Љ@2I€Ш)“f“Б € €@|ˆœтыKэ € IDN™4›Œ@т+Э{ыјH‚јЮ Е#€ €@Ђкњ‰бDN2–Ж6“Јсг €  +ХЩ ЎжщтR@ rb € €КDNКR”C@ˆœX € €€Ў‘“Ўх@@"'ж €  +@фЄ+E9@@€Ш‰5€ €ш 9щJQ@ rb € €КQ~ћŠNѕ‹яXї7ЗNIЪ € €1zaўЄлzФАBUUМ"'+lкVўЉj‰ € (Г cG<‚ЇxENrЖIТІ5k/йОc{ЂŒ2Єž=zЪH2У-“Ц’Ќх…a<фQ‡*u":ђ7Отy„"“n‹}Їт9Y=•—џЉЗN2В\БяxІжиф™їћE2ИLpЫЄБ$kНayTуЁJЄŽ€яoМ[œzпШЩьt–Ыгф‰Sя3ЏZї~џaщя–IcIжJУ0ђЈЦC•:HцПёјє‰їжХЧ•Z@@ ˆœ2qV €ФG€Ш)>ЎдŠ €™(џћœDэћdЪvњi_|ў…є@%’й›6ЕT7ЋЇ1CKБшлzыж­“яœ|ЈцЕ–єЋ’’СЕЕщ№цТieимmэT[ЁкZ>tGв_U9ЈDш‘хЖЕ|Pd рP$Ÿs’?]‡ТЇіА™k~”Уќѓ>БP…рЉ={iж;…œf§ІЛ рT„FNђOЄ§GЬЃјМ3gЊККњЮiwі;З_Я^=ЧŒОrУћтъПyiџЫd„dз•— rљ‡иT;wюьгЋЕWeNиfдУQ=Œ\CЦ,65^Dd“vж]хбЅгUЪ €@{9IGхUG§ДЇпŽ:Жњ›ъыЧ^екЬ§љ IDATПoџЗџђіі­ляžѕР_з§еQњƒuЙ:lмИQ•пјўЦNЎj3ъФб†ЃFBЎlGнУXШb‹•$ѕ €@І $&r’ЯsВ~„QЅЭ„ї?UОФђ—_pбЇ§BЎп™9‹Яы7а<Хrч=wz<ѕ’3dшъН•жо5kзX Щ‘|IЛПЉОэŽлz–є”Cn›<ЎО^>ЩjK5ЊV~j>лWšЏ‡\Д`м­“FŽ–““mdyzœQєФм‡}ЃkђЬyxfП’žђ# Уќш,ѓG`W­Z>ф’ zі:эЪ‘CvTl]Гv•@y7ЏTŒRlљВ%–ѓЬ[ЄbFќeТI†‹7+А|ИЙлКyЃt^њ|С%Ќy}•5.ЉAК­VNЫ>7ŽŸјд3OЉЬЇ–ліњ++ОјДBЪ,yzЩюЯvПБђ6–uШъ0я‰…’9рм[>й" ЗЛ~ць™žя%НeЫ–‹ФФл&м0ц†эe}є~йI'ž4їwKІљЃU‰€>ЄдІЗПО'Ч6mк4ќ‚AОсј3­Эy 8Xћі_жЫЯ}-XЄFНyгцчžYібЦђ_qэИёяџчцчўјДwѓзrжЊЙXљЖЗ_{ЃьѕЕпж.Zм|И*`%BЮˆЏLЫ.5g†‹™T>ммMž>эŽ[Іlп\Бт™eлЗ*~ёY…T Яf"Јй5шќвкšклЬН;ЖVджж:ЏT5ŽK.У„з_{cѓ›Uy+aoдJ[M‡3 [[p‡[Э1{рЈТ’ЁвўDЌ SyБХ ж/jўіЖHћ3cЅк\ЙalўxѓыЯЏ0џ]ј€џ/QgЉ‡ыŒНђФ­L?Q3 9ЄŽ€љWЧG""'ѕпЧiП(V?’/kЏ$юњэ]й99жц‹ЏЎО}кєœ.9†+{ђo'Џ}{­фїаwѓЧл$БцЏk:И:Ќ§ыIKNЯО}%ёвЊзŠ{{ф’JЧь›'L~gг&Щ”{VN*?{ћы{R§<|ј’Q™Vbн[ыІO›.{хgњ=їЏ~k•/Uм5sVN~žŽКzдбНыюЛдцЮOЗЊbЭ‡O›ОњЭцУU+rFЌ]сžCŽE2ƒЫ‡›Л?ьPѕ­ФЩѕвѓЉ3fZ†ЌСОkмуž~ў9ЩY№ЬЦнЊЁ}ю}y'фY›yyy‡нћдЎœŸgЖ+[2э›GхўGИУ§ћ}ПCЮH@™Ј7УЭн‚_№єŸ^є‹:§ЈУ”{ю-ЕЮЕжЬАaУ?5oУ;іVю6БНx8Ў€|ћ!всLЂЋ-BC:Лbe˜Ъ‹-ёАБRЕЯ`vGѓяQђ‡Љўu–zИЮXЕйŸSjeк;FЬHбјЂs~зѕ/­ˆфš“ ~Кё .—бЇŸЇžžПёƒ'œlEwMНkЪД)ћ”˜4іюл;3fHF1`Р‰F^=2xD]ѓЛжьЏБЂŸššq .9Gѓ№3Йf§НсцЎЈ{бѓŸzЖnо:kЦДПќэ}­:ГŒkЦŒŸ9uЪфiгшp\љZ­F8“шjгl4\БXІђbKњ yЂ.`д‘7 C.‰‡K_М5„›_sўЎЖиєУќ­ игўЬps'ѓ^НЗкМ ђНбр?АKчcЭLџБ-ў2cЏћQyХиЋЧњіњѓУqйѓ{є1)p`sŽДыпЮ$lm!ћ9глšяI•єwР>іXІђb‹lТUЭ­щS‰–›:K=мWžˆ•ЉV# RPРќЋˆу#EЯ9Н~Ќœ-И~тѕrкљ”SOНё–[-ƒ§KЮlаХƒdSžч>њ фXЛš§а“sЙѕ›}]жuмuуо\ѓfй[ЕœRzzЩѓ žZ0яЩ‡Žžй­јЦЌї‹“&LšѓиœСУK†_2\6лкЕ^gѕКlдe џл0|XЄУУЭH[›“ђХgлЊјД"ммбљЗпqћўЊ/e ШѕYыЈёзO5жМsKДзЃ“ЧхЫџер?ъ0~мјѕя­зЉ-œItЕщДЈЪФЯ0•[МaуЇЊ&.\BgЉ‡ћ3 Ў3‰+3И3ф y?(2щМцдКнЕпVП6ЎHg„ХН{W”—G.9dФ†mхŸЮyфјЉП™ZW_Й0{•€мЯДђѕ•В™7yЉˆ"ўPНœH№X"w&Mїf’a\[›ц7“Tл4p #рыo|їЇнvэ­џЫjѓTK„‡NHc~ХвЪN?.8PО&!Wы"t™] € €@њ$цj]cњ€ЄTOу–I­ЄдєХМ3‰™Љ˜wл^a !Лd#)'ШInу…@ќнЬЋЎёoХzbZ‰9IsУФ-Ж6ЭišЋЖiЌF˜$"rтџtбMU&ЙeвXЂ›Эі…aћ ƒk@5и„ˆ,Р}N‘}и‹ €4 95[B@" Ф§jћлsD>Ъ‡–€ЋЃЫ*—n™4­Щ‹C! у€j UъD uдпxœКпШЉgž/МјBœКžЉе š -3м2i,ЩZoЦCеxЈR'Љ# уЛ?зY›јFNУ†“Ÿ$Ržxzїџњ|w:>'з-ЖS–Ic‰­Œ~mъ[щ—DUпŠ’ЄРŠчWХЉЯё§ ё§ka„~Пѓі;_rq„эмeLэЌ„У@@ эЦ^Н*?C<Ўa“ЬБœmJ№LчххЕПE јк_ 5 € €@<т{Е.rѕЯ9ЙПЈЈйЖEЎXК ЧpЙ:fч•фŸжЪЗь%ёœ“„P555‘‡nЏ=рЋЈЈиОm{И’V~Я^=‹‹[|‡nфђьE@Ј’9ižsЊўћ;oдTхќа№ќгЈo22ЫМПЩ§н‘эџsDІЁЮcдя§|энУWнTВсЖ’ЕЗѕ_5СќY9mД„Pjžь!ШМ'че~WЛ§уэяНџїЭmVeТ%ЦŒНqТЭіьмГgзžюЇvŸѓрLUђгэŸОїЮ{5ћЭл˜ž˜ћpэЗЕлЗlянППЗщ=UF%"дѓбGНіЦ_іTўїЏ‡_yЧнwЈCьŸЪД<{сЙђŸF›йГїф‚‰ЗM ўрХ oћtлћ{_Ь].зœЧчфффŒМlфЊ—›пYКъхх#Ў+љС…‚}‚Tf&%0ŒЧlЂUъD 3 ‡LКцхК_џЧžўГ6ЌЊвљљЩO~вjБ^Н—ЦЄХтq№§5†t,ЛДу†K;ОpБуЪŽђГчЊŽ[.5ѕ6V^`Ќ,5^(5–є3іќueШ6{ѕюu№›*kWUU• СJЋDШM+гуёœ~цщЊРAїA+-ЯR­дfmFЈж*PO]]Ъ/ќЉЏ?’SиЭз–Є_XіТПўљ/љ™zзTщЊ§!9ж.ГLš<ЄџVOч=2gоуѓЌДЪьпЏWе^fнЁК^g™’гПw/sЄђјчПњїы№г?daЩ—кьd•YХ…a 'еbR)"pЭU+%i5\1_5є‚ “$XъuнМфŸsВЮ<?Ћ@Еоу‘SM•5GЊjŽдџЏБЇіH]У9c‘“еб•e”t2§мєSCюЯўЁ:ШLиЯ9эћf_ў жюЂEщ–ŸVŒ1R.УЩеŸŸџќч‡RћѓѓђUZЊ-(ˆTm„zфФ‰UOvvіб&UeшлчЬžsъщЇЊB’–Е™v‰;ЇЭјл{Ћ(пjяљўЊ}НћіpyœvњiћмІyСI'ŸqЦкЗзJZžЯ)9'џг?daЋ6ћY9љŒa<ІеxЈR'&ЬШЩКЯ)мГ‚ЮяшXа1џG%0ъі“Ž’яіїYS}ЄЎЩ(лol§ЃВж|л]у?х–Јц{bь—НКцw•[ŽЌ:Ћ§ й<6Ы[ Ќ|ћ§4зп|§ 7нАgћy—м§пС—–ЌCКўЌkuuˆj­НђЌY*/ {Р'›п7ЪЯЬY3ПќќKULв’cэR™щ”Ш2žZќдoяК[nfRнюќГЎŸUИясН*{хВщsЯ<%‰чўјдф[&[хУVЕe~УxЬ1ЊёPЅN2K ™‘“ІЄЛбГуŽИџзМУ)Їƒб­SЧ?щXдЩшйЩ^`”œ`фw0?Њ@^%соћЙЊж‚ŒИjФŒgKl$йЮVeЮ<ЋЯ’?.‘рЩ]уžyoѓЭL rЋœ ’xkъНSUљ€Фˆ+GHmfЅ‡ыgпwoР^йдЌЧ~ =рГђ%HRї6Љ3O’#љіг+-'“nМсFћЦн8nЦД;ЭHДЩЈќЂRnЗFTz^im­Gо‘ч:ЎSQwп‡x…+œ^эь-†э y8Њ!YШD%‘Sўi%E7Ь+3геџš-M?/лdЫ#UпrТI^bѓ]FбqцеКТrёЮ•Ђ›=™:ejЇу:ЩW^0 _ЏszлСWjўѓпњЫ[нNњљ— щ; Џ:vс‚…ГfЮЪ+ШЛтВЫћžгœЏ X‰гfШ›™Эjіы?р‚€НВЉY§@{РчЫ—‘zз_{§{yOžђ}›щіK>ЊъРЗTЏoЛѕЖ^}ћОњђOЩ“[Ш/|‰к5ё–‰Sюž2aт•ЁА*󄆸˜eTуЁJdŒ@2ПЗЎЭˆrjЈОЮуiєqWo-ЋкОйѓэ~—ЇжS{Шеє?ђ<ы'ЅГ_Ъя}БUГ„ ірI5'o‰=fє‡›?T9)›-ЃЎ%ЂunЦМЗI>”ЁхцЪ—WЖњi™);@:† €@<тїНuђ:œ>Йx–—Ÿ-зьŒ‚ќю}њx;оxи]ЕЋЂБІЪhђœ\˜у›dg@иє№COњЭ$у{cіїНthЪ;0рѓžpjО<дfЪŽ…Ž!€ ai9…ВЯюœ_tžљfЋрG@RXXиo@ПOУ№ЁУхт]pљЩБ|ђt+WЏŒм1)Й{@@ Vi9E€А‡ RL.iЅХU-{Р'_H—.пIa"и… €@ЦЄСтQ[K"ЧІнs@Рѕ№9@b.VwˆЧ|єTˆ €™(П;Ф3љœS&ЎЦ„ €Щ rJІ>m#€ €@z 9Ѕз|б[@HІ‘S2ѕi@вK€Ш)Нц‹о"€ €@2ˆœ’ЉOл € ^DNщ5_є@’)@ф”L}кF@є rJЏљЂЗ € L"Їdъг6 €Є—‘SzЭНE@d 9%SŸЖ@@ НˆœвkОш- €$S€Ш)™њД €щ%@ф”^ѓEo@@ ™DNЩдЇm@H/"Їєš/z‹ €Щ rJІ>m#€ €@z 9Ѕз|б[@HІ‘S2ѕi@вK€Ш)Нц‹о"€ €@2ˆœ’ЉOл € ^DNщ5_є@’)@ф”L}кF@є rJЏљЂЗ € L"Їdъг6 €Є—‘SzЭНE@d 9%S?amџр?HX[4„ €@ 9e№фЖСS 6@ˆJ€Ш)*Жє<ˆр)=ч^#€Є‘S MFКB№”dš@Ш`"Ї žмаC#x эB. €DNHW„р)уІ”!€$H€Ш)AаЉж СSЊЭ§AH "ЇД˜ІИt’р).ЌTŠ бY=:Zр_џњWшф"€ €@DЮ9EфЩЌL™5ŸŒ@ DNI@OJ“Vиd=s.)S@Ѓ € @ф”“ињ8лдК%@а rв@ЪЌ"œvЪЌљd4 €  rJ(7!€ €@Z №оКДžО(;ЯХЛ(с8 @Рёœsrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ ѓЏ1цIDAT €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДˆœДЉ(ˆ €Ž rrќ@ДВДKЖ­ра ѓ уЌБWЏjлa”F@к-АkoН7iwEAФ+ršt[УиБюoю Щ@@т+ a“7‰}+ёŠœЄЇвуIЗХОЧдˆ €$K€ћœ’%OЛ € ~DNщ7gє@’%@ф”,yкE@є rJП9ЃЧ € ,"ЇdЩг. €ЄŸ@Мо[WмЛwњaаc@Ш Šђђ˜&^‘“t4нљјЉ@2R N'qИZ—‘Ћ…A!€ €@\ˆœтТJЅ € ‘DN9­ @т"@фV*E@Œ rЪШieP € "ЇИАR) €dЄ‘SFN+ƒB@И9Х…•J@@ #ˆœ2rZ €ФE€Ш).ЌTŠ €)Чo_бёкZОЅЊЊJЇdz•),,ьгЛ$dŸ8фd"€ ŽЩŒœЌтЖЩwІ#\ф>/^ј„ž8фШPьE@ Н’9ЩйІёџ6ЉўH}z‘щєvф5cWНИ<8rrрuИ(ƒ €@КpŸSКЬ§D@ф 9ХgšтSm*зъР!Їђtа7@ј$ѓjwDућјŒ,ukuрSw2ш €mрœS›И(Œ €ŽHі9'ѓ'С3pкщХ_|^!ЊDB;Œ!'t€4† €@ц $;rйЄмЃU‰ЯqcЄњтеhЄ6уП/туп<- € $GNrК)Ўgœ–ПИќБЙMŸ6}ь5cэšЊQ•АяA:|lдЮ!џЂxр/\lяЄdV|fžEKц#ќ“й+кF@ І~Ÿг‹/НxџЬћWПєbLб’\YnnюЊUЋ’м šG@Р‘™9mнМЕSЇN#GŽ”gI'r~уzсjжнГ^|сХъъъ#j2ц<<чќsћЪ$д•P9)ЕіѕЕC†щлЇxЬш1е{+еБK/:џТѓћіщ;уОžш;§‘Њ+$@Hyˆœф*O|~VМДBЂЉќџ#щцVdVЌU"цˆ<ёэiЮ0ВГГgЯœ}їНw›W:[dбтEЕkпXГ^~< ›ЊРц6ЏxfEйћхК№YXљЫ—.йійю7ўќFйћeВ:,\АаW>ŠF2{@ШˆœтуXSSѓёЮ‡]gін›й5ПKMЕ;яsд5ћнѓЛXљЊ€™АођѓЛЎvYNg ЖќхўmэЌ] @Hed_­ћо<ХѓŸЕ6œгѓЬœМ|UГЄЯьyІф[gTЌ|™U Ж‰HSоО!лћœ_P8тŠsч=Ў2/<ьСљедзЫ$d3фHUљWИїбЋїЛЅXхзU3œЕCЄ!Г@LHvфЧ—VНtљеЃъ=bДфdІћцЈЃдеЉQм|ЫЭ?§ёO‡_1\~$!›jWШФЕз\лыЌ^&OиЏїєћІŸџЫѓC#@,ИZ‡ЉxvЩГСЕ–є+‘Щ///ЗіЊDpс”Э юѓ“sŸTНuуš6}šќЈ+p”}S‚'љ (Я& €„HШ)3я‘ џpрУcА@4ШЬЋuЩŸ€ЈяГN~зЃэ‡-Ч!€ЄЏ‘S\ц.тЇИĘєJ8фЄ›г@Ф ЄРеКј~чoтIuZ$ЬаQЂ  €)'єШЩуqмU9хж=B@ :ЎжEчЦQ € рD"ЇјЬКуNЄљ>Ф<>šдŠ €@Њ$ѓj]aaсђeЫ^08U0bзВїжЫш‚ыsрƒШA@ }’9ѕщm~.ЅщЫЎч!YЃ (рР!А‰ €@Z $3r8‰$BFimЙѓrdі"€ Fмч”F“EW@@ ЩDNIžšG@4 rJЃЩЂЋ € d"Ї$OЭ#€ €@ 9ЅбdбU@HВ‘S’'€ц@@ ˆœвhВш* €$Y€Ш)Щ@ѓ € FDNi4Yt@’,@ф”ф  y@H#8~ћJqяоiAW@@Vт9U”—Зк6@@єрj]zЭНE@d 9%SŸЖ@@ НˆœвkОш- €$S€Ш)™њД €щ%@ф”^ѓEo@@ ™DNЩдЇm@H/"Їєš/z‹ €Щ rJІ>m#€ €@z 9Ѕз|б[@HІ‘S2ѕi@вK Ъo_с;щвkšщ- €ФD šШ‰яЄ‹ =• € €@к pЕ.эІŒ#€ €@вˆœ’FOУ € vDNi7et@’&@ф”4zF@Д rJЛ)ЃУ € 4"ЇЄбг0 €Є‘SкMF@Є ДљѓœЖ–oЉЊЊJZi@ˆ@aaaŸо%њѕЕ-rВТІAжo€’ € €@Ъ lxgНєM?xj[ф$g›$lЪЩЩIйёг1@@@_ [QЗ=•{є#'юsвЗЅ$ €8]€ШЩщ+€ё#€ €€О‘“О%@@РщDNN_Œ@єˆœє­(‰ €N rrњ `ќ €  /@фЄoEI@pК‘“гWуG@}"'}+J"€ €€гˆœœО? €ш ДэлWєыЅ$ y™њ•чОё”!gЬ2f–c5•DNБ’ЄШp+†Иmђ™7ЮХ ŸAoCЮЄЙf–c5›DNБ’ЄШpљЪѓёџ6ЉўH}цsф5cWНИ<8rbШ™4зЬrЌf“ћœb%I= € љœsЪќ9f„ ;ё}ь*Kšš"t…!GРIЋ]ЬrŒІ‹sN1‚Є@p€чœ0Щ b%`ўЏнЋЪтQЯЂЇ—Lš0>–5Їќc9XЋЎTrь'4ЄW* 9d­ЬгN/ўтѓŠГ‹Ш)1ЮД‚™"`ОЦЄє#Їs~}Л]lŒT>х‡Љѓaї%hШ‹–.™4.R,лjЈ&4фА4фmЧ,ГmЋ1тЃэ‘SДr‡ЮгMq:уДdщХщЪrхџ,`џйГUf›mюdјWЃ6 ЙјХ/Иxсb{o%ГтГ6Ÿ'ˆю({Л­Єc4ф€Vьѓ(ЛЦ/?9yљю№БlЋЄž6Oh@ǍݘЙККњщ… 6}єqCУЁSКO?БєќвЭЦ6Гmс‡мž^9ЕGc@]FOcезU•{*‡]>,ф13ю™aх766nљћ– яmyљHOSл^)BжœШЬмммUЋV92~Ž=цЪ+ЎєЋA999ёk%ъšеьWОhrэкЕŸяљ|й ЫфX9э$ЯŸžЏКуЮ;о~ѓѕE цžгїМЫ‡^^z^Љбі—ВЙy˜ў”šGЩXВlЩјыЧ[‰чмБc‡чЛКм.ЧЫJА"?U@Т‘-[Ъъъы\ЧхішбЃш4пФ‰@йЦВ€ЃќMЕсw ‡МрЉуЦM6ЬKW~ш Y‡ђЈЉЉylюc|єёOЃwПо<№ˆ5ЬтГŠ}рбХЯ.>ќЭОSN/ўнь NіАЩXєєЂUoЌ2š&M˜<ђъБж‚—ŠoЈўЕфлŒјЋ•!G<6ТNо[‡] €@єЛl§ћжх//пSЙЇ[QЗ;oНsфU# O.ЌџG+ŸЅ)чœ$$Ъя’ok6Ќ)9ЃDŸє›ЉЧџьxyщ•Ыyв­Šmђ*;ўšё“~3I^!rsrU_kіWЏygЭРвСЅ•цvlЮWт—+ŒГgЮО{жнжыЈНЁхЫ–lћlї~Ѓь§ВЎ -”НSoŸњъЏn|ƒЄ7МПсеuЏJŽ-Щspи$Хњєъ3ѓў‡поPіЋ‹.XёђГч>_ТЏЪн•іЖR*BОеŸњКњБ#Цо9mFбE[6otЙЬy”‡U`§Цѕ%чМsЪŒё7oќЎ^Mœ|iШЃЌc“ђМiгІA йє„пLИaЬ §эЃВwЪКŸxвуџўИ*ЖљуЭ+žYQЖЉќТA>0ћ+_Ўoюўв\oЏ);x№ •rЉЈz’žh{ žє.г@ VЎ]™{\юЈЫGœT a„œ:’HЎО=ќшУjXђš*/–V№!зьђѓђЭxыˆбЇ{Ÿх//‘ UžCž={З1VўC___пЇИ:ж:E1|иp9 Лj^t3гћмћђђ$˜n1зс–Š”(щЭ џдЪУq‘SDv"€кЗYШЪћфч•і+­ЊЉкБmGйж-н~V(Wыђђ|зn*–MwuЕ•йуdЙšS–г1зѓЛlуњ}ЪэJйrCt“ё№\яЉЉ&CЮK™Ї”$ljй%9Я!;Ж~mЦj1yДЌП•*§…7ыляОbщsfyofчќЎыŸ]–гй<чф{xѓЋПЎZ§ъКпџћ“Ь}RоQ˜чЦх?ЦиКmЧлoНўЮЛяœsNяб#ў_щМЦ1оўІUЩшэЋJЭcsќЦВў|Ќ,˜Aч•ц nмkз]3жѓ/{TsэNЉžhд4 я€ яЌ9bTpY9џ7хŽ)W’нб%бmяч5Яc@оЭЎљ]kіЛ›'н[cИЅbю Ј$ИёЯс>ЇјгdŒРїцѕъ=юzЗЋЃKn ‘›WђO.мђЩУ•\ƒ%фЫџ^‚ƒ­ц}KйfIO“‘н%ЧѓНQ§EѕђW–Ћ’…Eн6МНЁQЎšхwXЧЪ^Й 2hШ№Л*+ПЎ n(dNЄљiЫЅU~Aсˆ+FЬgоцbeŽИjФН>(alJпf<8[ѕžля›>{Юь’ѓо{ЯНПНїюњяЭe]:[Й?tџч/˜тщн_ymDZrTу1ЭZ щ<ЧjШmYек3UŽJX{еІJlќ Ќк]Sэ6r~QBL)ЉіeoB3эЏ,дяЖЬВ47сц K—.YЕvMЭ‘zY~_TоyпНV7ЬыŒ.Wu{іяšg_ZЕїSmЪiШч>VsИОўˆgот…V™KEvЉЃьUEH{ˆ§чœboJ €@ yЇ›їфAС rMоХ]НпwnЩ^Lн#kђѓѓ§jИѕпы§K6lир1пrх’їЪЩ§ТжQ=Š{ьиНcхъ•ВYвЃDю(—[d|c 4HŽ2š §oбВЗ•˜єЈЃІL›ЂкКіšk%=aђЙsТЉЇо:ўVй||оузŒОFЦ"щ’~%UпT-œїјДщГЦ^ѓЕcЏ•+>хххЊ+ёьsЯфdЦІФšrЂQ.ЫКrr_<8•%—‰ќсOџщщEџ1ЗЁсЈ|žг7мhuxЦЌOЮ}rЪ7SфdвИ›ЎysЭ›‘rѓ 7/ќУТЋF_%ХЦћ?ў>фR‰\O"їў pШЄѓn˜Sыvз~[§к8п{ Уѕ`еъ•ƒ.юОАpG‘d€€ќ8іњёr,Nc1o$З=фn'y•gЩ“`ЫМШ%џе• ьѕ’Ўўк{cфчфgч˜R ї[}“zЌНйЧd›7BЉ—]ЖŠC&=k^_|ё%оCй•DeЦkШЪ_ DхЈ„ЕKmЊ„}Ђн‡нђЎ)ЉіЅъзNФkШкH|СаCшGEХyl№њ(vХвЪN?.8PО†sN2l"€Щ№CЁ7ЃŸ#ЭбOsєіН!ЏЏЦсЧЈzПoЌўя'ЗZ”Ж6Rро‘НŠkVм†ЌќUїUŽJXЛдІJLt@Б›Њ•жqrыM'ЋD|†Lф”ЌљЄ]HSцЗ‘Чj/Ќ0ЏИ…|\;:ФMИ!KЖ'ГЕ!ЕЖплvяОчEшCЙ|4b*=ZRkћC%x3}Ёњ"ЏЕ!ЕЖп_e„‰NЗYіЉП‰œкFqpИ@ў{эШQсяFЊў"йŸёЈ7фђMc#НJReqEелѓ˜ќщг4еrЄ‰жЎDГSЉYŒШ)5ч…^!€@j и>И0І”oўŠi}1Ќ,^CŽac]UєCNсyŒŒ§#з›‘{љT‚ŒœV… €qрœS\XЉ2O@ОЏwљВх/HщЗ‹GЧ^іоz]№Б 9и$}s˜хXЭ‘SЌ$Љ2\ OяЁМќdо8%BВF04†’ж›ЬrЌІШ)V’дƒ™/ ‘DШ#ƒGЮ3xrеа8ЫjьQ$ИЯ) 4A@‡ 99tт6 €D!@ф‡ € €€Cˆœ:ё @Ђ rŠC@@РЁDNx† €Q9EЦ! € рP"'‡N<УF@(ˆœЂ@у@pЈ‘“C'ža#€ €@mћіљж› яЌяVд-Š–8@H5=•{$М‰мЋќ‚УЈДЪД-rВОАIкˆм{@@Дї]ШЊѓ6Нѓі;jГm‘“Цї*; € йa“ –ћœ2{Ц €D) ТІтюEЊ "'EA@№ иУ&I+"'EA@0Т&ћ}NDN,@@ Y Bи$…ˆœšЅH!€ €€УB†Mмчф№UС№@@ „@ИАIђUiЮ9)  € р\aї99wY0r@а ›ф@Ю9ы‘ƒ €h5lт>'­†Š €tТ&)Ѓjhўі•N?.ИbЉяльдn € €@F јƒŸ%6-a’…а9ЩЖЪЭh ‡ €D)р‹œ”Џ‰ВC@#№џ"Л/ЛЅ)uIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/0.png0000644000175000017500000010172311733011756026150 0ustar sylvestresylvestre‰PNG  IHDR”@ЮРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН |EК>\ЦЏ;$ž™Э„Ы™ `7сšd#& \‚ €ˆРВ*ˆ ЂЂ‹М, шЂ(*рA.Š^ˆŠ&"K‚D’LдРЬB’AТLгѓэ№ѓџTwвщЬ}&3Й@5ѓ еuyы­ЇЛŸ~ы­ъЊЫШЧПvДбaЊКN’г MŒPg0™U’ххТсjE0Њ„#oPmG…2`ўD[е"фІ~)ЏЈ*СЋТJPA‰єpWO­МЇ4NU*ьоФАј!‘>Bзг“иˆшп"D;Jс˜+ЈЦЉž№ ЪЕFцtѓR„о•Ц5 [CiVG$И2’Т™l†@;Dр2уЈзЭ|ВjЦTb0>Иlк;v›]№‘ƒ%1 vˆ€фЬpьck‡-`*1—$”МD1ЬD[uБ[‰3Nд№DЇMHК$Џk4C€!4’ххД]Ю{[Е™зиСй„зzЯх–" ЖВBлщcБ FЗ4С`0\ЩЫ5V9Џџv{7Mщ3|дЕі№I;oKVПЙœDe?ЃdkЈb%<з,вя ЏMJЋњ&O=Уo!–!РИdШ+жkxNЧи –Йd‚ВдЄ"Ÿ=’‰џo|Ђ „1К^uИхUЈЅЉУ.’}$Йф эT–/— /МО5їъ­-JЉШЉэ­jп†Hфх‹Съa фЫt1КъsЂX}ЂОxŸHY|”ЗRRƒъQ 2=‰§ь!JRъуЦЇšЋ_ŒѕИЈWЇЖNX]Џ:,зЎжйс %•ТšМђЊš€ш_-Mvi—$—œЁ.|q' і‹!kя„€sЙuъUxЫ&kю;еЃ@‘ }њёVYлHƒуC–д:xЂ uЭ=‡ ‹!|4Ÿа)AEА˜DUђ}дЙZ',?Kr]§xТТЭzmŒY›ЦasйQmБв:ˆze1rи]YчєcюЉЋ&˜цНVт›Нд-ђ-Љо*mqЫ@~•Гщ№‚ЫKТ=Цcеъlю TЇЪХCkWcЉ…O[ћЎ№ˆ‹Œ~Ш+ъJcпюdlІ‘у8‹Ѕ<Љw’љŒЙZдк–NгэЎжxчЭŠLzнЊNEXВз<—•sК•Т -jV‹†9T>.г”9€RЊœ4ѕZ“Чf6f jLд5*|\хrŠЂ Аl?PоЧЈ5&uљгд— o|ЊшГ‡ш‹с‘Е[DТїуyЅv4аGЊЄчЃ]ѓ2 оаh~ мЕѕйV–иЁ№O3<uZ=ŽžНћ$ѕKт-|ѕwV<„[ ;oЇ6зЄЗЌ:чYœw&Ы‘JŒпР s•<Иѕ•АNcе4Мoї*$HНD“шЇ№P)fœНд2тІБCєšб*јAШ …Q™ж—Гœup1-QJА‚ШЪА@`”F+:љ—XКjаЭ%fђєвt63!5<д:ч}EuV‚Вк Ћ[ЁЫbГ“iЅ‡KJр‚ќ А\E^$gMђиLЙЌ“XЈд(Ї†ыoО„ќЁ qH_Ы%RjVˆšШ•ЂvЙ:—КЄЪy|ДЫсj“гўШЫ7ƒ]А[­||||к ДВђ2ЋUъюљ(ЂixЛ4ЬхjjСkЃŽ„L”ѕ.Y~уЩ№"+ЏqZQc)и\UЮѕаG)їп9‚fXR]yЋM4ЎА‚М’єZ№QAЉ…’W_SџJњ™TYЙ™VЁ!ƒŒк9зёœвSу8Ы‹UъžccНTМ:,U‡?ВЮ§MIЙ7%gO=ДЕЈ^Mv‘ NвРЄХ:БŠшl‚ a бKМэБ™Д JЉ0Ёч’?[BЭ"љИquгЫ 1NњП1sCЄЫ)bcьа Ш7zAOМjјиNДЎЄйX2<Іњh—4є”џSUб,ž\јПМ= F“дыСS гъЂƒцNжАƒїЃщ•ЋЪуб†WGњ7цд€ђWUAƒ"сdнЌ}АŸ}g5Д•(O'л‹О/‡“Є4рХCjц’9а€ШВ3Vдл }<$ып/§оbц;ёЋясАCНГКшбx i_”[A^№yEiDББ‡+ЇЧF{ФЊБpуџшЬB]4.*šZ”ЪсЃ™J%Ц%рю5WgРh)€т9^ž…ЧѓTgDКД g9^Б1]ВxъЃ]>аP8Ыv №_~л`ЗšЫ+ЪN|^0ЛЊ­ее5јєЧэЮmаГи˜Йљџв3б<Ъх ЏhєкфŸšШ\ВЩЇ;ПЅўЉ‘™ib'щФї1шЇЯF)њP9IсIAп…-еg„я-дцТiљIЋx G З›т‚ЬuSІ B; sЏDZмz=P‘зˆVЂ—”hФpСн™ŠїЪ—јМдрM”‚ћ”ДfОB_Эє%’РкzdэNи†јщКо^_rэ#3RР_8цeRJЪЫ}ŠЇ‰xрР;ўчvјNѕб.hИUТ".Zќ[^:žзЧ5јМRRRДэБяЪxLCѕfyс+Х–”uЋєнBЋ–ˆ№ЌНgž“’ ›€Юx™ѕђЫ…ЬkДpЂ‹ьUNcЉХ‘lрЪ*(пЩё“я—/ОЩ8џVз)fnѕјŠh№y9IyЅŸ u>ї‰’sЧdцњ*к,эх‚ГЦh’љ{Иъ]iдw3›Iq;9щдOнЂ]#^<`сBъ5Ц-їа+Шwч?-ЧŽbк‡ŸkНх %wЈсўлsPЪНgъ;еGЛ| сЊ:;Пx KтT™щыэ˜Њ?–bJ2ѕ5•џPТТШ#ШыЄ.ЋЪщљuZ_]ж­Ж‹4гКёЮfOнЄЗD"›]гфџЎ<–ххльkљ2d>с4К\ъxuXVO&<юА)шъЄŽ|tm A~ъКђі^ФŠЄ“’иA<ЉSЉJдЪziЌ]5v„‘ЉќœЫ:ЈыR‡хzхПrМ\1€БЩЧwеX{)&[? “uiІŒfzгM­Ї{јГ%t8E>n\]ŠjO$-EЗWŠІo=МРtЉE}Š)Ь:„у"u <еGЛ<ЂёФB:™V>`TКп-‰ьџ‹Щђђf~q…Dѓі!sЌ]Ши`П§œНъ\•эgЙ‚ˆ=ї‘о§HнЭш§ИТinе %чзЋoЂ-‰ЇТSY9џIЂч‰дWm.\ЏЫЅ№ЬTœГIщ)мaМиhпQ”ЈГЙ5 0­NУ‹NNЩPEє e ˆGЃЁЬ*}дaЙ^љoSМtn#„2„hаЃ"ЊUР’Q§eFY|­IЭlвЁ9nj=нУ7ОXz-GптLq ЧFTQAH,сxIg0(РЌ':QыR‹њДТЉэJЧphKёБЁ*ш|Їњh—G4&НX„З*вuIЇЦ;ЪНy,цЂ@@ВМЮxАМъіXув(ап\p№hyЩydSKЩяЪhNRљWЫK)Х­ƒLЮ†Зe-HЇuъma-TэЖњв,ю§u,šЩO6 Ž˜ЈЏO}vC‰є“FЉЫP/жѓ%˜ЬS_яД‰іcБWіoŽзЛм•­šЃfWyB\П(OНЙкyc;ЈкэеіЉžwђв$иЮA^еіXнЈCN#XсU=T-ТŒ ЛэЄ™юŠЩ1э\=oj_šёьbљИюžЛуFпd6›…:‘ц:%€Пt1Ки+cгЇћх’ф‚{щ‘#јЙф ЫЉKEщЛ"%•pрšœ­Дޘ}ћG{>ЁkuЊGxЧм™›6М‚L•˜р‚‹yЭк5_}CНn№єє Нм)j.24ѕBУJЎYЙ@џЛѓўП[zяƒƒ%›ЋЮ3EЕаа0QK6,Тј?ні…ъ.КџЁ‡ŸjUƒœ dјЈ›опБНѕ А!я‘ !›gђ2]cвw3`ŸŽу,–ђЄоIи лpЄІЄUGЋAпjЁљёнєƒоЛwOЮјБj4vьоб/y0иVfъ‚!‡AЃЗп}зт{Ќz’оєyyyЗЯПkћЦЗ aШ2#TPО@рw єрŠЧкаsЊм*­ќЄЙЋеjї\PŸ9< IŽ:+­ ТRФу4Џ o№рСrиЅ ;U№вm$DЈБbЏ yЧ3,mьј9А˜j /Н^>ђІєЬЌeЏt8Z$пUЕ фЩgVBђ№б7myg‡’*ЋЁќѕЈ•’йc`Цэ3_{ыЕfIШжэЛюš~;"ен[wЫФ 0—фВyчЩФ О™РNжlк0{FnNЮXŽУk†GЇЏlк нђЮfДl$.ОеЃy.uызтЂ ™ЕSТ­%X5д*§fЯ2§'iХЕHt9•KЙЃ‡јЂ#…SsЇЄџaШЈ‰№ ‘sЖш/НOVП! ? №пXY 5™0ццнћvЫТJJЫрЈ)9Aї РБћ§Š€ h,šŒ†Oy‡хdуОs^nrЪ‡ёо“дєѕЧуЕS  9oN%C Џф%:иn[žѕьн'Љ_’бhФvГH *Я–77т§mлѓ?нХ“ЕыжUмwцu_ЕГяпЛч§џн~шШ!—Ьђ•WБKЇАLЛ ОШWђРъ”вЯХфёиКЁYCKŠБŠ6Ю ЫŸ}BцkјЏH 0p№рСБйуд™qŠH%ІјH1к€аPтх€GѕДёWOќxх“їіWŸЋFLKАRW ЫkЫ–ЭПK ш+Zoъ-yј‘ywпsјр‘7_о№эwпЋх‡^їЕЖsUяПЗ?l1ƒSYŽЗxЅ–j’™‘uќЛяа„РcЧŽeefс/ТИ1*ЪОCЊR‘8єMёЖWпЬџђЋЎПсБП>%GzЛЩ=*Ц{ЯE7—SoзNЭїЭЉЮщ-ь•МСŽ-fэ5іДAieхepaзx1HўП*?l§`зв%‹Д]Д0оНhяgŸzЬц7RЉEШљї}ИoщНдЧёшНK§ *УнwЮмДЅiжШІ-ЏСs‘рБuщщУ}[Œœ{ђ>ˆвDѕ.ўіт]Šћ=­9_шдйpzў|Ѓ4 ЁФЫъ!iзћ]В”^”h~Сќ….ЅB;•ЏЫaзm}gЫгЋžDˆ7ѕ0_ЧZƒG^ˆз/_К$QОѓьлПW їЩО§ŸЩљНХ+вZЊI'2fLNоЇћ!№ытЃwпuїбтЃяљшФЛxTПbqУ“2}ЪфяўеА^žЗ›мЃђaМї ЫC‡SDЪ‡Зkз˜NџW0їxsЊsz {іy!ЗО›f—TL„ ГK‹fƒ<ќ5чЯœ3nb“TЏъ4eёђXбiыiХR‹‡™œœ‚ЋK‹K’І ћ sЬEŽЧжЅ LY%љe?мГoѕЪ'^~cК{G_ёр —т~OуКФс-­ц/œvщЇTZРyыi%^xTIjм\Š„|*_ 8щъ1М С;~EySoЭsЯnx§uызХ^uп’‡3џцW”я Ї­5ђЏHkЙ&{№ёЇ&M˜,жк’ћšlЕ6tї№ђXѓєJЅ%РE7МЈ№ІџUк Iъ‹ЅДBŠїаЈ0о{ЈТ§ЁSјЫлЕSк‚€Ђ­Ч›Sг[и+[Рс%д x Зяиочwріyоa‚OЊйЋо›муЛш{ьпєІњё А` йzш{рi‘1B "AхЙcцММ§Цњ/МБuлЬwИ—ѕи:мy‰†Ўшrђ|Tъв^ојrС?ѓƒxw Оc†І…љ–ћЧщJ6œкд§T7Ъ(йф€GѕЄЦЭЅH Oq-V=ўє”млvП—жYCаe–[-w\„{SїЄ<*‡wЦŠ|єс'.ƒ=эЁkTћ{‹WфЗ\C/њТлћб ѕ 08ЙпЮ;`аЩёJE>ъ‹ЅОЩ=*Ц{Я‡JHђvэдЅšcюzsЊsz {э6ТЌР№ЂьѓJIIIJJТVЩ\№лjxЋXŽŸvлФ•O=.ƒn9i†Яоwў RЧŒМё™ЕkhCžyёїВq]:[*|чюЉ~c№ЮЗUUц}šgГйR‡xxџ{k]ЦuзЎzё…бcGЃŠбЃFЏzъФј­Ю=Ум936ОЖ~\А~рtбs•œъц=F‰—од›8nЬуЋŸ<їrцbЅTЦjбYю§ћфЭлv@mTєьsЎŽ7ѕp“аŒ?` єFD‘B`ЬШмђ}ђј‹ЯрTт-^Љ",šм:vєs_—>xФІїЯXНa-b”*ќМнфо”зНч[1oзN]ЪїЭЉЮщ-ь•Мрп’ДД4К]Ѓ“ююу {Э‡ѓШ6}р€3ЮХЪƒ,>lxhв]КпВw/ŒсGцŒХ„šC2м%Яž1grюtХжuЯр7цŽ™Г–/шŽмЉszk]VZ::qйУGЂTіˆ‘gЅЙzg= t‰4t3ОЕс•О<5j$~рTБЦ‘yр€Оh;ˆещЬžуRм›zГgЮщ{uЏёSnЛщ–ё rЉ–cЅд>aќ„ЗwОћиВ‡>?№yжАыІЬ™‘сщъxSoјАŒEK–ІђтКVЏzBr`СнsbЏь:ђ–БјuНВ+NeQот•ŠТЂ n€њџЋgbћJ!ПўŠЅ Пo7Й7хУuяљVЬлЕS—ђ}sЊsz гГmV+VR}oVƒЫІшlўЖŠM|Yl_]†X+кЯй1cћйFЎ bOл 7 Љoшвй›\пnHўУвFdЖpЛm2SЌН!‹СнeЌ’Ў–ќ\лЮМ$jmvcЅиЩž‡Вu˜­J.'bBUl–x‚|ГІ№)jДГЃ"PўC9М!PqІ2CРW‡Нхl™xмfУFй1Q_Ÿњь†ёI#э6R/жѓ%Є^[oЋГ•ІіѕрхQФЛїХZNДŠpuРН"95BеЉЋюˆсщwЮ^ђ—№Ь~шˆЭg:‡o,Ме=Wђ2t1ŒЫaйыlУnИйЈ5ŠрTЅћYW_03ŸДžŒ"МЩф…Vk@ЋUфЛН%ѕpA~GQ•щйnhљCзr ЧƒЯЋнBЦc0 Ў>/% †@{F€‘W{О:L7†CР+ŒММBУ іŒ#Џі|u˜n †€WšF‹Jщ:-ь`0&ђЪЬHэ3% †h"/Б6ќk 2ˆ †@„`>ЏЫФ2‘E€‘Wdёeв !р‹МАj’ВUD„ЊosБІа ­ЉFызиš­cu1Z _ф%єн­ќlЗZЫYE †@‡F Щaяо ь ژЫУ`Д|‘єГZ,ј+wУЛЫ1l/ˆЄSа ЗSдЄеФ„ZЁМqDйќ0ŒкеrћЭwЗnžзЯvф‘X,'‹§AЅue9 с5<ЏЁЋАcЙ3Ўђ}UœЕZЫ*ЪЬgЌФIwBСtІDЃВƒЏВСЄ‹їЌTƒЯtэмЇfksЎ щS5ЫЫ ?фЅ•ћ2—)‘Ё@[‡žхЯ'l'œŠbќIФЊъ%хV<Щ„˜њ™rАC”ВŠyѓІ|YPPTHSЅјЬŒ4mуц+ў*iLП@@YVЋ(bЋбQVn=tF<ЮЇP™NвU,яЧWї4&`“%m4ЇуЕбУє?VU/,.,+;eEl,ЉБ1Би liК&аTЇs_}дШ&ї_}>о[a^ѕ;@MX6†@ 4тН”oџ‘s=Ыїы+ўє— =Gуa.Џ0kuZёJК>ЂУсАX,%ј0РIL8T;9шdjyIлˆ8j…={їчNšьОžчšЄXXXцч9sЙхуoЊЋЎЬ":.Ж_/m§PХ'W9MБЧ ћёe’’НЁ›6Œќ…m) Ž‚Ња›нжЋGЏ‘YУŒ‰X|!šЋ>šъž$Еб=šХ0кОШKн[ йцЂTУЅSƒЅР_ШёэМЉз+Щ x˜K*ЪјN|сбBlBЛlEЋa…йыьzlш}Ёq’-:w,ІhЇх:E3o–w7І6šз*ˆDУ••[v4“пхФbч$є„‡|j|ёh–-!ѓ›ѓlіc§Б:ЃбdРюЙСжу!?‹f‚ЙьЕтЩO ьгwмиqьuшAVQАjnХX†@Ћ"р‹М H {‹”ЙЌ%МгJДI„зв'П2Ÿ3$=uyс4№ЃЄМ ћА52-zв Zy•jQА‹utЗ#˜c4†Ўќ*?<ўь‚xuŽ DРfIю‹яЊuщ9 ­(ŽЏwrXWjG‰…iј(Љя“]ёc^ЌйЪЧ№`.SwmPіЛJДЗxДа|†2збяЂЋhьнГ•˜K2ИАŸXT˜vso‹a„ _феТо"eЎ3ЃНŽ9GНЃСўтEl­”*j,?uдiIШž{ptЅѕиwe ЮЃЅGБcг “’Œ рГV!О[шœшЗНrК‡+ъv:Ђ,РВ1кјTТwџ‘>UчKјZ3Ш‹D›D^Ч[)s}‚е*№5ЇєФFт{QцP щ$ѕ­œjFћ}tjBгŒ˜ВВ2oZУkЪмœѕМq‰a}hxЧыcр#ЧФњ`ѓP*‹qі:b›ФŒR$OSщe“’.2}œЪУцŠ2є+NŸф/'§њєып?)mHšpоjЎЖ$ŒGс‡|-Uя‰š­АjS(sсеrФFг6Вƒ!аžшѕп<[Чз/…д ф‡BТщљ еb7ЃѓЃ‘]Хѕтѕ tЄЌжсРD ђ#Žч%ƒzш‘O5 Ю{к‘ р žvыP‚VdЕZ1 ‚#z<х’“^ьDаsфdŸ=Ь. Бc–z(ŒзiЕ 3Љ‹зLЯ€Њ#ЄАЈ№XйїЖZБЊК*JƒЭЎЏеХщ Єf0€х/ўŠwћхu ЋЮФљ+ФŠі›%ђrPBsю”?) IDATJфhязиH–!>|‘W€Ѓ№СѓDрњІаюЇхˆ‘œЗNb.Ћ]Oь -1ŽsкaЎmд`Ѓдтр{ @љjЅg,Еў”й<ьњL0 Fа•JA4 ;K>х‘„о%’VЃ–ЋFгР’*†ѕ,нS,ІТ"›“‹ѕѕƒ7j$рТHCйдК4I`bќ pZ-ќ|ЁеQТ‘Т'‹ѕWТИКв*v+Љ ƒђ”Г'’(sIО<ZЄ#ЇjHо?E КІ$ђІюЁ02•Щ†@d№ѓXћю-B%ўdК‡м€t<Оtт;јКdнвRгЊЯUьь{yКМr1^K;ЊMќх$V‘˜KZжWЫ…42 ~Ц08ƒФФEj{АЫ?Љ#]Еu`bJ^БМи5†зЕЇЮp/}"Ф‡{lwѓ`ЁfљЁ!р‹МќіщH[йЛм$б`.љщЅ†•ЙвсpъуЃС˜$ЁwHs0Ж\ь:­СjЃ5>СГќдПŒ } іJъxdЖ Z4uAЋNd@’ёиё шбяешИџц` ЩFMHЗд—$uxЖEtЩёђ„8ЬS ё!7tгУкBїѓщ“’’€щD н›Љ§%ђёш0qшыrQВR1 tu†„8]Ъ\Зžрt“мн]А}РџЄ‹':t#a“nWђ бж]ЕtуЯŽъoOСд:ўШEzФ3˜лхНд№E^РЦїh#|и|]…2—=Ь]0[а‘вkѕ&ОІœ`ќ‡D^јO&ЊЋu:P™.xг žpО^д&Mб—еHeА ­@:аЩGCiMЂ•Є8rђAtzBьaЅЅѕЏо“_vќЏщOНзNѕй)FЩЫЁu:ЋоIJŠKФ:8ЇL-™Єjшf7v$fi`F[CЃ№ŸФ_€КАBЌŽгСЯgМ†HL_фcjј‹N. ю:ПвїЁŽpЉ&ћдЁќњO,чk ‰с1ЮиЬ…зЮёd™e fПI8!‰.–г№№§ајŒлƒњЈ+8ѕXn†@`ј!/Eˆчў#fѕ›цјj;—1 ߘŸяœ„IdдvKт0a‚в™Ў`|ШC{#’™Ў_tђbёчЄџм :tдщŽЯ[щ,+ы€В‰|Ш‰МрЄТ3vJ Ш†ЇБЁTcЦРџяЂЭК6%ПАф№з…I))zНCЇE'NІKi>† эŽ:RvЂоЈД“6І‰KЏH3О‹žtQGHсNxшіGŽZФDх*у5Z№зЧŸ—;œць }Pі—CЌЗџŒTФRCRH35ќї|п'Г~НJпћjmOjФтcж^ЮТўš]|ѕФй™stAAыщѓ|g’z#/З‹Ф"ZхщїUБўЃhš,–яа|ЬЅЇ"œv6Qt‚CЃ%uЊHtqРЦёXУg/дйш“ігqЂП‘ЄLЎ"ЙЩсaЂ ХeнЅП2gР.щ@џ ВEХHžu9^J ъжoР€fЩёВВ’B3ЏХGHшrqh§NžlGu%Ц$ЋiuДk”ьр2ѓбко*~S~œ˜ˆ‰2'ј+Cc:№a9qZВ3ƒАјД)#Є)Џ ˆBo­МmXWёы7vэ 4s ќЙ’aWОkдќH‡&№>Ј=oЕџЪ'˜ДдЇ)SwpM`ЙсEРзаh#FжLcХ žќѓcnрѕІxМЕOšKьz“ЈЧˆдьВгщ˜E™Ћ ФХŸЉ н'Š)јLZцœ€[eё™N ‡Ч ў,њ‰‘lI€AK‹vТlRЬi@<ІhIS,ЎЃyFtй zx,•˜ЏjЕž1›ЂѓјбwУ /ЛнЎЃІ–ьЂтѓ ГjK І4Ьi.% gшfЇjэuж}пЋјЋ—6cДщЃwKDgљиых/­Б/эШKЃЂ1 ЦŠm)Љ=o‹Гл>ЗV!Жо^+LIЗš„*}я,>q mмa%_sWvХHqкУD0ZŒ€/ђ‚pЯНE—Z;ёbb6Љ Єјз7Уа-VЌ=i-Е|=^тєІЇCѕŽZ0WeЎФ‰Є_№ЬЪi№†№aуH}OIА'§fHх—}^є”дјТSУƒк‚3’ЕZ“AяРэ'ЅN5њдУњбj9ŒЋbБ-]Дж]­еŠККC"™"r)R†pў‡NŽq[ыО5уЏQ“SонŒЅ5J&J›ћ=ЕvxЏdЛ|Е|ФяAGў >™Ф,‘ВМФ|јL”Da cЌa OaŸ8YЕ щ;Ekщžгatв_,!ај"Џ€Fн”с IЬІdёѕ3М.NЌБ9’ІsЉ-e.єq џY˜”ši>У0‹ФнхO•Fр „ѓ*ё4њЊf-ЇзЧ[ЯZьёŒфAљ+uЎхh(п/зУщoуњb /RЕb*џœмё’O?) 7e~њvyNOѓœ)ў;ЊжЯ_%Юs jсѓЦCЛ№рuнDќщŠЂффRЉM;щ˜ЭЪЙРqŽВ".•љМTјА`! <їžыЈЗш^”N^LъьжЯžф‡.ц2ZЪ\ ЉЌЬЌэяm/УИ^ЦќМмЋєѓСюbѕ),ЃLЭŠHр/}цЂђESyО\ьЏШ‘Њ-™™вѓуТПм‘гЖXJ 'qЙ{š`Р'цУ,Cf?IЮй„КуЄі< пYЌ8J-Xm‚њ JсыИ[обkйT+ 1Т€€/ђ ЂЗшЎ ˜тsД-6ИС№‹/˜9‡žvТЎ6СЦвмf.Y!.ZЏЫ\TšWŸLОlT1Л1‘џС,ЙГr'г@ѕvMw‘цьЫкс3/љА–_ %GЩЙR:.Љ‹утК9ЬЅ”ЙКј7ю"вT&”!а_ф…œAŒ66—лpоѕа(ДR›@d|М1~кЫШhd‚ŠЕ0KИкЈ\Џni\7зQK:.Р†@ЛAрПдDю?˜™ec0‘FРх%WпЂўcЄ[Рф3—$‘‘ћDЉЩ)­мДжЏётЛjЌE  hЗ‘Х`0кŒМкех`Ъ0"адm,*- ДЫЧ`0к&ђЪЬHmkeX§ †C PšШKЌ•зЈ Д$ЫЧ`0кцѓjC№Yе †@ш0ђ ;V’!РhCyЕ!јЌj†C tš|^ЁЫ`%  PzЂќ№бУм 2}Pzr_зЯьлЄвакШШ+4мX)†@dIdёŸGЎšчўў„ЋљЋM* ЙŒМB†ŽМи№ktЈM• 2‡€l.0—МWUХ)2}ЪфЭлvЈЩЋM* DUyyy„…E^rbt(ІJP™/9([ЋСЬaпZHГzк7F‡ЋЪтGwиkўC$Lй х’Y.тђWЩмОлнЕc–WОxLѕ№# mJтYЌ{’“шє ШlЗV+Eмc”Є~VДФц‚ЅЅхfs™;nbyН1Щd4 !еЅђSщ5“,JV%№УЮVЊH 4(yЉ7уeГ,sІРЬашXh(Ю% ~jЋU”” OP'ЩЅƒu­v€ЖœЄОUšьоІ@Щ %н7у`1ъо"CЃcЁсў0(1 #% V’‰I‰q(P—uЯlŒЧюgQQбс’c :н‡_А§lš:Ш40йcЮ`Ћ“ѓ*Jb.JжR@K…І“ЇRAt•тЌЄ@CЃЃЃЁжŸymќU~ЄњŒПЦ$uvšGfЎЦ|Я$a Йh*l.‰ЙРb 14Т!6ќ(ЏЕЪС,ЏV™UвюПO=љаTљ0;ЈЬ>њOj$‚єДє7оzЃъg[”†вD%їm˜1ђњqш3NŸ6]ЏoАПF^?Rp№ЩзДРжXiбCдцэ?ћЯVЇqњ‰ЭПОAg™ЙDв-†№’5Pћ№zс›ѕПˆ›WL­b‹1ђђџА— $ѕ О[TfпЂIMNNžyћЬМў›XЮ#ЕnЄg7О[ќИьq›Зnž>c:њ`1Ћж0{rС’)жI77\ ђ=цIаG—™Ы’Pж§ZwШqчѓ|ч[RmSСНyЎ5вј­Y$Ѕ–Gfъ[‡Й 0ы6zМj,’!аю-Кkбд1Зо>§vѕ4™ПvlнlЕšwœ5˜ВcGцъmмЮн-uЃг!д:;ЌвOШI6/+ќњ^‰D^”ЙРЁКK֘“џЦ:ЂЏ5'Б„T–СBъ DFDfyE^&œ!NL}MјЙKЅ Ъšї•)1Ў!ќ5yrHŠr'4ћбНЌ:UПO4<сЄYћ~й {ё\ў’ЮЉ&зяˆ)Шл˜IuЩТ‹‹^6ЃЇЩ'‰ѓWRћkIu]ъce„‹Ш0(#/зŽ%1: XTтЛ-$7SбXц/rЁ(wbˆќхАз˜п{RщЂђкд§ЯЃ:r›fmMQyчОІњё`Ў?7лЊ…7oк]~иœвЧШuџѕчзT–ќјsЪ€>b.4“‘—r­Y€!аДч•:P?v`Щž7 ШьцќuK(цЭž–Lл*5ф>JK5’„CА[џwyђЬчо\6їЌЁ ‚QЧ.Д,r<‘ќŒжМ+хъЋ`p9ЪОХКђs$uЬD"жc2˜ЊƒШлЈWEXV†C ="А|~ YSИgcsўz/sђ-Dtц/˜I ЌГ;œ"э6j‡ў# ЂеЇtЬЗ›кЂзщШŽ<ы’™dlb/ѓ{Фєчз‘JœЙ jпƒзv‘CŠ‘WфАe’-F qжB€‚–ЯOЋ_SјЉ'ў"bў‚YёWcЅQф(sё’ч &Xу< ТЭКоќэOќЮјЩтќ1‚pDЄipэƒQРq 3*ъ5U\ЃД›x6F^cХr2:]”&>ŸџеFвЌџј^цjх-ž›xЌ6РщŽ> (‰П>x"жЁјc^з•huЯхšч;Йѕѓ­$ZЯkx+фђЪj<р/"?.ž*VЂЏ7РœŒМŠecДЁЙ‹VнŸѕ№3љ_§ƒЛ›ќ_ћ$ўВ‰y+љс/ЅR}ж\ŽЃ}FЬ™0яXnЗXДW‰ж*ЁќbЏХŸpы†Ћˆ.ŽджЬЉ8є1пН/x‹цglтЉCкєбŠДАУЧШ+ь2 ЖG`евЌћЯ;ўRљя%ўтWЎŸ%/љрД $ZЇMHћ˜(‹#ZkйА˜‹Žеeфˆ5Uт™уBЩWЄіœшЌƒ™ІН@Ќa>Џєи †@ М№hіМGђОSѕя™Y07н;} "јтДгЉђg–SЄ3W5"ƒ .|љрЃИ~щœ(j3'4D^­ŸnkHиЄъVAб‘ТШ-юсV‹`\„`iд!imиА—ŸШžїаžя6:ШьяЎ4ZlAPKЇqзі'л_8ёY6>еvNQ­C-ўПŽfФс™Мdцš4qr$Њd2—;wбЯМл˜Пžћъ–=ћЖрЫmPЬЭљљЧ›Ўд‘пƒSСz\%=HœчELЌ…hрХџ#HœŽуБzNƒ›Ыњс:ў~Зѕ…š$Ж4ф™М`s1цj)ДЌќ%"№Wл’щDцЬ;gF‹/:‰Щ’5Ѓњм›і%RЮ %ћФsХt~ЬџpњnТБЯ#Ъ\Јй3yЕИЁLC€!ZqНУ&uƒЋ”'§&г_уф.`zёзгo#zАU%" /Ю`D ‹Чђb# ‘КG˜м`—“^^Ќuњ”њ•…a•іЕIЅJэС.ђ’™kўТћƒm?ЫЯ№‹РЮwwNКu’пlr†ѕkŸG х~Ў@k P%oй”…a• mRЉR{А‹„М0Т0ћЎж?cC мˆN1№[kвДм[ЗДœМаˆV^ЌU†­M* эŠ…Сч%ЩЩC†„І++Хш(S:;€Ў[Х–Z^`ЎgЗ‘Й„‹Ž‰1ѓM™быЙ*бушF^љž—n*­)н5e—Nд•YHv†СГЫ№ˆј(ТgЋe‘Оhy udхВџї@Ў#ќпŽcўШ™BRSF„“ЄЖЪсЈ'н‡r‰7‘xЫрК7ђњ7џpКЖцj]XЎыдASg§aжЇG,s7™БљJŠIpˆЇсАсŠ{AУ`tB!/ьt„У*ЕлШ7п“Ии|7~2пqtзНŸЮ0€“ˆP&ZŠч>s˜?#њA\ъ\ЌТсŠ/^t!Ё†ЃќмїD}OЦ}ЙCr J­зЮ/m=ќ'SЮuzpюќП—?%ЌœЪgіѕЬКзќ>љ‡Йю_р1ВБBіџХ‹6’PнZўкЧС_•—fz(ф%:щ7LЏю&Пч†qџžМКЗс#swŒwѓу(yIkъG№EЛгŽ%aзёњDтŒ"иоRSE* Щ5c]Є€ЗšЈKNгднw`њ ›љzЛqэТ”CД ­%/•я=(DщШyЛXf%Љ}]Ф4КJ“R‘.'„пЏ{;šsh\4Љq’(žTжŠsџV^я$cЧЇ№бќбЃV>†а/Гši&иc’Йdй’'~"ѓКЬГчЯОВщ•œJ^[омXќЏяџяћ| ПњЙеkзЌ]|џbY`ёЗХлооІеj}UзЌnvвЮPн ЩT_ї5ЊЩ^KHДоџAO•@oqзŽящјКЦqШLОЕЂѓ%–еs-§YE) ају5ŽЪsСП‡4DMоАк]dCФž—œdГs№п еt L‡= x4$*&К3щХѓƒћшР\ЙwІРдкБНЄЋFшЇ—\]’фž)ъђ(kU„јјјхK—ЫЖОЛkщ’Ѕк8-Чq ,мћЩ^Ѕрy€2;. мyЪ=цЂhh{oDs“)0mЯ‹Є ЯUbУыЈŽDеСђ1!JšР‡цАЙD WOcтЏeыБ ­ОЪЮСВВ;ШџжqŒvќ2ЪВчБ’?‰Žх.№"6SђЊuГКxа…9+uуЂ4"п‰ќЄ|уНІф^кН'hN$­вусQѓЦШ5{vУ+oЌ[П.іŠЈћz8ѓtЄѓgN7ІIXcfФhу`ф5г­) u š]Овo$h˜Ўˆ0ЛИmr Нв€7mLР*ћŽWr]†ђ$uROˆDRФжT†'ZТƒХ~ ЬJg9ЙyЗС%шrТŽЋ |UЯќEDь)kvТЏЂљ$сOŠX3ц˜7#5ЊŽЈhBљTCАA$Ёoћ№МѓћТех9Ѕљ˜МгМˆRКGї–Ь†^F%Іќd9"хќІ^ІчŸZ…$|–ДbХ#}ј Т]є=іozSлEЅœ"\ (тX !€ЫчvKСtkќuMb3ТZыЪM^Xhz6Б ŽНЧ“6Š#ѕuHіЄ/•ЈХ>ЂKј;Hu­X%ђАщР‰Xm–ЪХžqšЮМŽzЈDЁJЌБэ(яr\hnл`П MR3ŽшД<Џ`‚mЫ3Wœvфо•‚V@gБSѓ"*oјр_{шў‡L&JsхххO=ѓдДлІЩяп•ЏœqЧ cw#Ј–І9ёЖ‰?ѕјв{—ъЛщЭ'ЭoОѕцŠG– oіжVеТ‚W№Ш‘#у;JЃ:КžС“# 'ВгБуЁї­Zлa1'Rƒ‡c€‡8Q7є!і КштС#~ЈЩV+Ў.яЅ)$ЕієЋБ РЏb­(жж>‘єЛ•$fzЂŽьL;™W’˜ѓ )}4ЯRGeSK Œ#жбэ3Ћ­Иї<ъMІO›Ў‹сWќuEЅЙEКЛM›‰pЊ~™ $*‹§ъгWЛOw1bД‹;Тђ"дE/yшэVћжэ–щУtsВЕ>>ћ›3Пf54ЪЯЪЬЦЏ)Љ1~њ”щјЙФ9|ФG-M™YЈн"€Y7`N IDATŽEу%@GяŽд Г,#"yЁАеТIлђAAре–<Іj˜FпKO iяx6‘МI|#gлМgўЎ$]CДш?Тче‰ЮЄ=|ШМѓ3ыSѕiІрzЋˆХ3š!рб…в,; Ё“ъЧЧијЊNё0в@ПRUXNћzŠЏмЯїиj š^z0Е6хМQxІpе&ЛйЅс„ГіGоВ зјжНz:УЧPЃZ$ 3ш­вtkљЦ#а|ОЅАдhyA>ЕПІ„sI‰ХєУ„.+ъасž†C„3ЫхHбЇm{qBœtDШ\в’xЫ-ЇKAvЪP дХnŽvz’ЊЛцСzЛTtу.ЬŒКИ:ьП$ЫС`\DДдђj(РY SlЋЧТс[ом’u§ШЦі?C lˆбљ@љіуn ,/Ые":$yЁХ.6—Мъ.ю›С 3=b™ЛЩŒmЎSL‡(pѓxkF›Ф3Ю ;ьi™Y-”YX?с§ YПіyфtч/и\`.|в oйІO™МyлF^о№ia|{!ЏђsпMє=їхЩ-(Е^;ПДѕ№ŸL9зщБЭѕќП—?%<<•ЯьKз%єx€JВЎЯZПvН:5\ќтQГЖдP‡%œ:$Е…r@^МьœёЮЄiЙ;Зnq'ЏъРŠЗэ…Мhk5uї˜ўТfОоn\Л0eФ-hkЩKх{ Q:rо.š­$ГЏ/Xt:нЮ;'MЂkwБƒ!р?ЋtФ€ўka9"ƒ@;mьŒ ЪАћaЕО›Žh92fiiџЛ ŽšCטн(}5тiW<Иbыц­ ќdŽыз ПaxzjњВG–aфИeќ-–ІЬyчЩeƒxхнЂ`Ž)q[Жn‘…?љз'•Н”aч;;Gн4JоcљlхйћяН?§кtш0с|ьY+WgЛsЮyŸ6h‚дГжГЃnјz,Š>—v@ЄKЮђѓ Ј­…?пђYjЫјЏŠЛЌe‚EтАt=ЖЙцIe­8їoхетиё)ƒВL'Њ`taziћ eхH.š[љиЪ~PЁ%ѓ–з6т§ячфGiЂжЎY‹ЄЁз-))D@Ј–Џ\.3ZсбТЁYC•‚ŠПџоћћ?нo;g[ЗaRЊј_ХлЖo“wTžћчЙ3oŸy8џpўљ}ЏюѕьsЯКg›wзМ—ўё’џЪЦWІн>эRbX€!Р‚М"ФY WДн™єСf?ƒћшАbю)рВлKКj„~н}z“&_›qэЦзšшC–Пѕн]иЌ .ŽчўeсоOі">}hњЁoŠиѓёž(>J6ОŠП)NOOoа*рџЈpщ@`пћ”rќхDЫЇяэ|ъЁQ Ѓ9s/јКДДT{)Ž=4ќЎz]ЭљЄІ I;zє(юљpѕ_WПЛя]„–EМКl сјnёrЖјјјѓжгJѕ)TBЏнFш0dШY9Ї:лwЯ{i-5ОжММfжœY`[E ‚@рŒуnЁ"_ЙЕаЉWМ dyТ‹€WђB5`+хоZ=J‹Š&р,&:lŽђ№Мѓqј=Eп[‚qjШгЋž^ёј Й(зеEпуЋ/ПТј`Уя[Jmр…DCз‚OѓР˜ЉЉф?bСW‰†ФјV’\бйГgQ—Ч>Ај?§ёOљyљаnцСг‘y]fTTдКѕы@Ќ“&АСO…).аЅ›WїWў5Ч7wўмщ3ІЫсцYиYk р‹М\ъwБГфSќUЧoм№ъ№‘7Ѕgf-{|%Ќe Ш€Щ‡ЃЦOHўУ%ЦE88‹ЧюŠ-’€ОN5d[žљЕ§ggп•Ђ‹їГЅ‹4ƒС€ ЎW?ГZ‰Ÿ6uкЪ'WRŠqИфсГ—“2ЎЛaеъFчмŠгбЃn]ѕФЊŒы2”RžY§ №83nŒЧ‚ѕѕѕи—у8ЈБђщ•ѓШ‘wЬОcУЫцЯ›Xи ŽvйжvљK_ђ/бгq?А#3‡ edfфЮШ I +дR‚ /—Њф^ЄlšЩI[омLтлЖчК~їЕыЈS\>Šџubл[o–ўSйІЌ1ЁёџЮ$:6њHЬyмU№Сѓ…” 7gнaтЃі…ЌЖaMњуЄЊsUт юАޘ3#=#љС‡ 6\NЪЪHC//;›n}s6ТˆQJЉЎ€:CŽПeќШ#cuБшЗ6Ol8{bе/<Е*yH2ди ЧђАЄ@‡Jд9нcдЉЭТ ЧЙќyСКПЏЫјCЦ†ПohЂBЗlЭЄБ“p#рыЭЎ6ЉdЊђ]ћжvmXЛFл…њЇоНhќŸn[|џЙШ )~kФ@šЫЊWטОкyК‹‘вЭУьтАСЕЄНFмКН|Юњй9 žojИOu™А ўrIM‡Ѕ.$dBC%ьR…ЛpкŠЦO‚ф@ю4з7А’A–†ў`цОЩЪ|4—lША{пю{оУЬ.ЋрM=Твo$h0љ&>єAUtшŸ‡^йєЪђЅЫƒ*Х2‡ _фaЉѕ Nёq›bTВeFkJr mћую;vпqИьpКй6јМ@^eХж-ŸXWпЉOѕ>ЗоMXЧŽиЛwoХЩŠьдdGˆРRИ“ё&Іїsѓx:,Єf—l|!а3ЁЇћK1$ЉЌPpЈ&И‚rУQНг›~yЪCI8Л4мл“о.В­xYДVкЃ4œpжОъ- цLl_nˆїery”ЮHtнХЙ›KюyBˆA]=Œ=ж<З&„ВЌH<WGŽi2ЦZ†дќ{ч?Зъ9жјбуgп5{э?жід?9йУMвВzXi?ДˆМтКtЖTš нОЫŸvлФ•O=ОєоЅёнє–“ц oНљзGWxЌЏСEї.rOJ5ЄNЛQиєuЋЏлвЏџќмј6я=EˆЇм›˜жЌЫЃ,R…€gКЛћЮ™ЩtЃGrВiу+ы0іFU А /ZD^ГgЬ™œ;§зџћUю`цN›ŽЊf,œ‹ўcяЋЏОcі=Оjі’–;B›;ТK‹fˆ@ §AŸC@.}ЬЦЊ“ћІ(нOЦс%gc іD№J^ю/%F €­dТRTsA’’_Щ†‡Н’Ф жC€‘NыaўšМ’WјЋb­‡€O“ЊQ п™ёbZE-ЏolЙ|PR€BМmРбP<а!ЫkcйТŒ@[’W‚~g˜[УФudž\EкЩІГиВ џ`ћŒТ‰н7 Њ…BXqoД%yI НySŒХ3к yПPO 5`ћ6Ж@пХл–М|ыЦRm†ј‹mYжfшV1m '–‹!РhgxЕМю(яЋЏь‘гvЮн‘“Э$wTFMlк9ЉЃЖAЅї˜є цKпЉ"Y0\x&/™ЙЬ–SсЊЦ“œO‘,ю’F јШЗWћRТј+Bзд3yСцsэй{гБ’cЊ˜‰ѕ‹РoПнйeЯ#›№[ЄЃgxrеEѕJ;ё­vпчжѓ;њeiЇњ{&/YY0зт{MpыЧиP EЫ9Gw§pP—УКЫыˆ‹жUзG#ўФ/)Л,Њu кŠй.BiEPЩт?/nЭъ"]зЌ;їDКŠKYО/ђЂИhx[рEъ ’ЏеŽн‚Д—ЧˆшŒц/ЏYіŠњ1и‰П§ЖЌрKKж№ЭjeyйeUЧ„†uAШ ‹XЕL/a|%р%уEЩ›эЂˆ5B…€?ђRePk=Їu‹–MG=9\EєWћ~•Ш+8ЃЯZ#.~ §ЙgGBежbЋHшЮd2.Bк~Њ(ЌЌ+ЉЌ3џ\W][Œa‚%uЉ{rРцХПл2Ћї.ќnИъыб]?я}вїИчю= яN8 СcЖч^iЏY,ŠЫіьž cГy’yж]§хRˆAМG ъHХC`љУщеg+1СVд'I—їёdБvйoџY–їщєЋКGйj­X˜!pщ аіфеџЊhm~ФZOЌПаƒ@gB=бёц„ЫПЯИЊxјUХ7tџђZ§сй}_{nРrзцчŸХyѓїМЙ)‡ќЎЙž\••6Hп?mc\Тѓі:ЧšчG"GоЇ–o kX{ыжП#3bяZочyzš!yШ:й4 ЁЂїїфОИІ0Nџ|ЬUЯ›ВОДnЌЯкX"C€!@€М№yj$~ ў’‹_Д.ŠcЩHCt–!:ЛQЯ=w9!—“ОŽздщЄh•r~dЮ/А<ї4х&ѕ1{FЪ]ѓї˜ВзйХћяŸ4‹Ž“>)–e@`њДбсИуі$„ƒxuY9 УJљЙЄ.јsоЯU >Љ*J2­ƒкuu"t[t_~і№†=\j ћЉмœА‹m‘РHмim(ГEXАТ~h{ŸзБ*е—ъаЅ3РCюАЋˆ^ъE•иˆЙжOcфф‹ї—™}CЖёѓ<ГR@Џ=ё/з!ыї›зПHw›>%eжœ=KЪ\їїcЉЉњ)гš *|јМЬ–ІйМ!TtУѕЦЇWeЇ дsœR[+.ЛьВп~ћЭGгZIV C xкžМ`gAmИН`vс@чбќ 9цЄЮ/3yЂB’R›4Iѓј9ў2уіНлЖO”жДОŠѕЌ#=cЃše –Ny…0эіў‡ИынВGЩœx[b`љЉТ{rННmђ§KђvP}аu­Еня]|јS…S&БU лa=ЪЯжYЁг#Œ|tкUДУ891КџUдљ5в@GХџ2)ћ…Р.‘r[§ъЦЂ764u7ОVИёѕБpУ6pH|іВœ§yцчWgПѕПЅ8Хпѕ/ŽEL UxЫBElљHЯмЯƒ№­f<УмЮџзНЖqљУjbŸшЊФџ>йЕѓOБš_yќ.ЇzxОРYp{a+м^АТІџѓIu18ьСYътmыџТb„ fЭVыгбУѓЏ>кE§Њь;ў}^xmЕЪС_з ?Bn@uбDМ2КЊwчЊи(›.ЊВЋцИ,щ Є\е*Ъ\Ђ•ДЙџЋЕnЖKєњ^dЭіO^‘lАз{юњККЎцКЎžjїZЪSfќѕHpХТ“›ЭЮ Ž—ˆ”@|^—Ќ™ Hќѕƒƒ!аЮРђrЖѓ&0ѕТ†|^a“š vГ…†л%Y*ђК$qЙЄ-љщ<ї—]ж&ЦK oжи№ РКсСБуJ‘˜ыйцbЦŽ{/AЭy]‚НЉЩ2s5ГC у HЗбБцАqУˆA€рЫ.[ЂфBXю<6Ž66%)y"РhcфnЖШЋЯjh] ЏˆљPЋ­еšП­{с"[[›\šЏm$Лй"‹“ој'/і*l‹ывuZЯZeЯmPНT%Лйк љŽXЏђъˆ­b:‡†@вVh ГR—2Ьa)_}жv†@FРхe­БŠ-XмЊУTo иЭжЈwд:}‘Wџ”ў›З6лIЌZЙwЮpбіo,&сРТЊXР+yXіЃЏЗBНЌŠі€РŽн;кƒсг.,ЮŽ!р™МЂЄ5џЦц”сs‘Ы.ућM ћп'Wyž'цтџSЇ‹‰ЦвЉЂ­Юqђ;"„ущ:њXPгъ+%ћ>љїЩЅџЂkВЃх,{(Rї[$юaП2sџиrH˜Џx!Џ+t(!_Р\юѓ>юйet ?Љ~тіiD.зƒщLluжк:,н…C+šѓФфЪnŽџШХЦeЏ§ТЕ ;ПXх^ эl•RгnЛX.LЛl‡/‡Н|'yS;ћfЪ\A†Sбу>ПЯ[A,:ЈП"š“H5щЊhубЄжLlfђУ!ђЫЯBХїо ТšПаu‹ DzЫlМХbYЖфўсYУгS“ЇцN-јЂ X ъќaTL-–…—ОШ –— `yљHuMКuЙmkŸЛ>ߘ`ЛcјшнЗosЭаx.’ЮvБNРŽ„`Zѓ/uиУGџX‚Н}/­гщvюмй()œџŸ­<;wцэC3опѓўсCЅ-{ьуOv‡Г&‹!Р_фхbyэй›G•ђ;|єАFМпJЃy{ N}пА:1eіѓ…J‘Н Gэп{чЄо{Ч'рЏЕвŒ „Ащ™ё bŒ!˜r ЮJрщшЪвmН+\БuѓV˜HГl\Пnј А›в—=ВЬ!вщЗŒПХRб9яу<Йbя"aЭЫkfЭ]3a’VЋ…nІОІП>ѕМKcJ9-:T4uв-АзFЕwї^”’“№WЩƒHwѕфœ;пй9ъІQЩТfBКЈЭN_фхby+96юЁqю?ФдxžьЎ~mцп 6ф sЦ6ёНМX{y^CИ+ЂЉa%} ЂЯšfюšQNŒVЯpЄРђтЉ9цурЂЙ•­|№снП2йђкЦтяOМПу§ќ‚ќ(Mдк5k!gшЕCKJ( 5Тђ•ЫeF+иkoОўцЗп} ЩВƒOПGѕdŠџUМmћЖвoй˜€Ы5aЇ—:ОШЫХђЂPYмaиf!‰Ж3†эMRž'№mщcЉЉ%жг hБяFвШ)9OmЫ\К.ы/kL#Ї‘Ў-$šПœ№WљйM:y`ђЕзn|m‹R[пнЕtЩRmœ–уЙ…YИїjЅM?єM1{>оХGЩЦWё7Хщщщ.ХыЯзP›+Є#ъђ(ы9Ћ ёњјхЫ–{”сQ=9чy фЊ=жХ"žGхЖ)ЃMMХ|…žtЎ%СU„lШГ.е S"ђ-tпFаТ8рГ/ћћЧ@t:eCзgЈе~^лs˜сOїІ&њя=-˜Л`ъЬЉщзKNnЪ|ўЬщ1ЃЧ4T‰џЄvЇ I[ѕд*œ}ИчУе]§ђы/чLШ9ZrtХЃ+šrJЁЈ.q`pŸK| ЇkўЖfУ+ж§}]ьQї=єpцu™юЅ<Њ'g ­Rї*X Cр"CРyyАМљрйдŒ{`œњдGИ3O~­kPBRuџвАcЖДіБЊ:l1K;‰šhСіГНОa‹YЋ­FќхgБвœWќeі i M[ДyЎNCž^ѕєЂћmлВMЩаEпcџлл\ˆVXЂЁkСЇy`ддŒд—7МX№UAЂ!ёJA90tшаМOѓ&§q’KМњД3&жŠЙ,˜NI‚ƒьљЉƒ ЮЏЫ–|єљJ’№Јž’Ъ †€;ОК.>/ЉА8ю‘ъŸД-‘GенkŠЂнЦи(tЯР^*Ю,џ™`H‘ц‡“>6:г€}ГIvзh№ќєdLс†QЗ=ЉЏГ–—ИKv1 г&O[§Ьj%iкдi+Ÿ\‰AC%\ђ№йЫIзнАjѕ ЃsnХщшQЗЎzbUЦuJ)%АhоЂз^_wЛЃЮ х'Ъ—=tП’*zџ>$€ПрA{іщg•TдEЧ$ЃR8Ѕ)q]:ЋМЉЇa†CР‹ИЄ4ЮтSGЫн:uŒ–ч|ЉџКч‰jДЖbcјzщInШЃ!˜ aЕеМJ*)‹Њ0ЊˆКАv2Ot1ЄЌ–цE€!РџѓМфй^aћkЎ.о~ьшЎУЁЋЬJ^д„эN“жDi[iѕ…jћЦ]6эЛЭjЕГМ7ЋiцњЈ‰yХGО-ћmaфмёдŽйГfGN>“мсРО“šмсдіЁ№Ъ?–Џ>кешЬѕ‘•%€/Ы+xi–А|b 4+ЫЧ`0,C€!рЖ!/fyyЙ,š!РџзољРVUнqќ.АМtЁЕZт Ћ fќCвuP(иvиBtиH]ЋlЋ7ЪЊ`БВ­C4Јh vД4 В9ЈФ€ШtБ uВАЬ@‡BЪ+ГкзЌfћžwо;=міоої я>њОз“чяœ{ЮЙч~NљхwЯЛя|э^RuкGјѕЌ"/яШаО9#†6nѕїZn&ўХй‚H`8pЧy!ђ‚јфucіЩёz<‰c„и­щ№уПд)ў“хХї‹Йx Ф9wœ—)ђ*џ…Y,жjVмQЫЊ2ЫI€†1wœ—yIИХ/ЖŠM Елxљ{ќО.у‹ЎžŽРNЊэ5}‚ZХ  ФЌe™6 DсUйЯoР~,ь?0SId­L0K$рЮ‚НyЩѕЌ$Џ!R‚ŸbУш€’Яo aЯшб žЎЂі‹_CЇ˜Э? X#рŽѓКьлFЙŸ={|єt„]ОУз+і•р™pН759Д–opшГ­Џ8гkTmЈЪžžCэ™сP+{ЮyšH` ю8/=ђ’š^Щсѕ^xЎs~Я№tC'-aь„фБiЩžTyYяaЛ:Хьаѕ•my~‹я‚яЭ?яG:wўВђœ­ьО^h‘ „CРчЅG^RSЊ@~<*†Я0Ю‰€Ы СŽЄБcSЧ{П—"ТЎ$lиЯоўю†H1ХZ•)Љ‘ьћг>!ЧУтhЈ •IDAT8_§8Вђ”­lе  АИуМєШыќ…ѓБЄˆЙ|пxёЈhрm/Џ iНiЩодБоФoЂ=ГМфC1ћрсї[ZZtR’ZzŸ™3:.vр,Г›››aHХьЦ}АЁ˜rН­ДБ№oJЊЮйЖГаF“йqуЦ]l;+mhe=rД№оТ{ѓч@ЮVеЇA$pх.џ†яЪћsжƒўmЃЏС–Зы\Т‹‰.АfŸф1R!к?†VQXѓu9x[uГэoы†ё7@ЮVњЏііvШ_ЫњNДВэ{цY +ю8/=ђъьўh[žе/+їћ…ЇєАRЬЦУ"#HUП№Ъ žм€~ЄbvщCЅАЅbі§м?hџІ љwчoЊоTљD%Ъзm\‡ЌЌ­ьЅ-8AьџcвЪЦM0K$wœ—yuщЫ/„cЗё_!б(ШЃ}Сз(ёk!1@љ=ЃXыvцМацъ*f‹QY”?RЕЉ*wN.ЊЬЭŸ‹ЌЌыD+лКWž!А#рЮ6аˆМ№ѓ Ћm kwдЊ!—-)SЖ§K^Њk”ЗОF'Ю­aЛГ`ЏлhКѓ-5[:/tЊєьцgсГd2еd–H ž ИѓиЈЏyщє—ЏXЬ†ž‘E!вЈSЂM$ю8/}ЭKŸ:)m ю<6ZE^6х) а ИуМlжМєСб& +ю8/F^VѓСr ‡мq^ŒМNЋ‘ XpЧy1ђВš–“ 8$рŽѓbфхpzXHРŠ€;Ю‹‘—е|АœHР!wœ#/‡гУj$@Vмq^ŒМЌцƒх$@ ИуМy9œV#А"рЮЯƒL‘WP(; ’Нэхmž…mpФНF[G›>zŠЮъ4h“@мpЧy!ђRŠйAєЯЛv•ўRl 8рБaЃиA0nj>ЦэдѓЦћpЧyщ‘vявC-ЉЧБ`— ZlБ 9Дд#qŒ‘2Ц(§Оpm§я%$@qHР§5/j=\ZМИX&щžЄм,vЏ‡-ќWЂZBbvlœЂ’ђGЫMSˆBSIdйШ:ПZWlЬlEУ›€;ЮKМЄ?BЈUмh,h4ќRbŠBBHИ-hp@іьƒЯФDЯZЬЩ*fiч7Фb Kю8/§лFSЈхыI#…лaWР}а*ž"qјК”ХЗ4ЄŠйсv.У.|Jњg­ŸЕЪAxћ€4P‚ra[hnЃmУцфЭ™rћe!фЉSЇPˆSВ~’@pЧy]y]jI_†GED^"ьђЧž+(Тбеi3ICЊ˜nчyФPЅд#ŒЬщ™'N|уRЧЅЕызіј{`иќafV& +Эmœ:іЩБК]u-Чћd(џvє№У?{xЭoж@dx@|ˆ’ѓ:ЕяT§Цz•єЏMЁVї—"ЖЊ-4ž›mTќа(Ÿb<—gTЯ2žœ%&ЈЛл.ђB…ЁSЬЗs1\эШШЬ8њб1ь}{/„‘d№uьЃc(ДвмЦЉ•­„ЗъЉЁЁЁђ‰Ї^|ўХ™3fЊB$‡ЂєmуЧ'>žЗzžЮwЯЦ=2k Е}чlНfИ6Г—,ޘ>kЪ”ОG-Љ˜нзUрОЁŒ§дЦЇP(ГЗОМЕрž(fW>.<œwnjn-+Эmt26ЙЯs!Лу•—ю›Ÿ9[SџЬ’@Мˆ’ѓXЅІ†aРmщŽL…Z}ХСwддюЌ•vЮ]9ЊppcHГwnЇЧыI›˜zИщVёвЇЅo}сw‡п;œ61 хЈiЅЙmъйэЏе•ќДФ›Ш—uћУaI\ˆвcЃ`њM(I;„Y†ZˆЖLiCѕцЖ3m"}оЖэе  5фџVŠйэ_ДУ‡b™ZжВ Љ˜}wС|dЅbіДгь{wоyђuЃЁЮ­zГЙ–дмО8tЭmеVФЖПМ}їЎнЕa2Q=а сA Š‘bЎg‚ŠТ]ygнN…ђ@S№kИЗпyїф''E9Њ!di,_]Б9œзы‡T1лaчeЅ.,ZјѕО–‹їYг~№\ѕІœEцќ8Їzу:”Ш{Звм–gMŸв•,-1z§ХЅeІГЬ’@œˆ’b6–ъч§*W2нѓЬўy+sїќvПI1с•7$зˆїшЫ–Ѓў5)џZv>N&#Юo“Šйqўюэ‡тŸpл…_пZѓBSн–=!А .ŠEj…?"Ж И† DЯy)HЙЁL•РP„ Еt,ДI€ЌDЩyнvыmћџАпjІrј/НФ”хSЄ‡6 Ф-(9ЏЩљ“‘eМaЏПЇЊЪaа7щ4h“ XˆтЋкєп6jХ4I€HР)wœ—ўлFЇ#e= аИуМyiS@“H ю8/F^‘Ьл hмq^ŒМД) I$ wœ#ЏHцŠmH€4ю8/F^ка$ˆ„€;Ю‹‘W$sХ6$@(НЄŠTБЁv]š$@$pEЂфМlvRХ№Љ˜}EsШЦ$—ЂфМлаЎІTƒиЉ˜эряbBrk0uY…†9(:/ьЄЊЭІbЖЂBƒHР9Ј.иcUЙ™ЊкRХ6аTЬv>aі5ЅF$ъР);+Ѓbuі—Жoињй)шgLЯ€ф[oНe_™gI DгyљБ*n[~Ъћ—ъATЬОъ R2ђЭНћG4жW­Зщ[ћ/}tYб}E‡zѕЕW|мІ2O‘@ŒˆžѓТюЉ2сЮѕTЅѓђљ $яhbS1ЛJ­"zКBХlh>ЎXUљо‘їzОъЩО3Ÿъ/O•дl­)џyљЬь™27~мкŠЕЊ ˆYбs^ i'U?ГЃЂ˜ Хя‚М‚њ7ъеDд7д/(,@љ‘#G:;:чфegЄ‹gLнСЉЪ4H жDЩyЩTБ™ЊJ „)дR2ŽTЬ–ˆЎP1Ћ]еЯVЯШœо§dбŽ;‚a]ЏБcзŽEE МуbЧщГЇпhќЫЁwAЭ{§гыеьа ˜%%ч…mTЎ^ЈRЦTЁq/љищеQ^#б#жяѓя[а№з†„Šo!Е^j…žcгЩ&™}КцщP;ЫџCдњрсї[ZZєR1[Ўaу_2ўЙт,TЌ›››aHХьЦ}АЁ˜rН­n;я\oлўZCЁ˜-oЖpNnЗпWЙVh€CqђцЩiоњrјœ:u*a'НтБСVќzEг;M(фA1N ŠЏJh$№лFЕ Д ЕфyЉ˜ Wѕн[Ц$Ѕ7?3ЉырџTvкі[п'кБЈЕНŠЕ6^ЭtмЙжF˜із Хьп+Z\Вѕљ­P НіѕUkVЩAІнr‹iДЬ’@ьˆRфeЁџЖЁ–Ў•]МЄЌvg­Љ~ИYчЂж6*жVuоy *fЇЇЇћЛ| ЃО3jђф ЊРќТљеПЏЦRž1яš}—еНГœb‡€;ЮKпUŠй*=Xі`бЂ{nš|SнНѕџўћW'і~ѕщЪ3€ѕFЩ`vЙШ:9 j}юТ9UГxIёЗпБфЁ%гІЌZГ,{VЖ<Эъ‹mg•Š5lЅb­кі7v.Гёј6шЕ ˜t}Rюœ\Єд”Tdћ_T•HХьн{wзОДM:7—ЎЋZWђ@‰jRPP’’’77/+;Ћлп]ЙJЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН XTекџПћХs1dчк%ъёГ;гтESTшё…дPѓЈЅ&-ёЯбDдд|7ЅрёfЄV–v|Эш4 ѕ˜HЂšœЪр1u8*LWЩp§№z~їf ‹ЭЬо{63У0/п}q їОзНюuЏЯкГяYkяйsЯх‹—Aˆ9‹^Б€€(8ѓV*љьџxџЖ7M[Ѓd=€€€ˆšН”rч=!У“)kжд@@@@…РѕSћoџћ'“EНQХE   Œ€)qѕŽ%RsуВPЋZ“}tB@P`—^Žо@@Рk и*vіŸ§НЦа4уlЈ•jэ”knTъ|„РЧу+\ 5—‹jЎ^ьвŠZ0#`џЉи<ШѕЌu:ћ{aжOœfњцнКѓћКљ\ў4‘raз_Я\Љееt\—П\јС/nCГTњејx‚ ѓ•ъЌЫ:џР^‘зП)ЌлТ@@Р ћOХЎрСJ'5лп‹–4%Ю–Zљ=]@@€NутkkГ&kВU3Tљ( =Ж,šМ ]}‚^ЅВ\[Иhkџ B рMь?Л‚ћGЬў^HbhJœMџ%E\ЌЃ)`?нх€ћnм4o\Њ+Щ3Š/u~JЕ|?^Л5B“O9ЗЧ7&Гѕb2ГaГЁњ#їы/ƒX[Rй†жyЅ0хŸ7@ш\jяЉи<и?іїЂe r9ЊЅ…а#V№1м/ш:шКмлХh4R­ќЎщўdfш„нGtЭЩЬ†цZU=РЧшcКgŠЩ5 ­\|VQЦаѕ'žИП2€. ћд;ЪПBГPƒ€8€€ѕФщї@Hя? б!ОООUUНъUљsх ЃС4“‹B'ЇМаЂЪИwєffŽфы2K–РЄ“VЌК]ŸѕYХЙJёўІЧBfЦ††tіЅWі?†}gЋўљC-›чQiжМqєJЙŠUŸ2ch0Щ†п„Г?ъ3VбЧVЄхuв!Ѓњљћ~ЋЯ)жПћЯJV‹7GЛѕ Т‰KњѕŸUаЌыЅa4*Ѓ“2АКZ|’Ѕе.3ox№n2ЇSЋчa"&9Ыxа‚TХƒYRoвЄ ё 5БM6я‹AкљЕT*ХРЇЙ_itЦ_ •U•!†ьлПябGЃj ЕЕт§;”j‘WюXъЈЅ TзњtnЁ#ЗbEЗ&SгДяьЅЊ}Ч+ўт?cdФв‘Ё“о,2 КЅЃУќ;[Ÿ§ЉЪа#ШBDшЙj‡Ў?{lqе^–Е‹lбщиЌпдїЫƒўбG‚І ѓѕV|\е"A:Х$Й9АщOO”[Ќџќtй„ша)ƒƒuї [OшyѕчЋŽœЈx::tXп`уoѕ™ЧѕJaP?AwЅСпЊOэ]ІnђH €x)‹Sёч[Ь^ e‹qя7ŸИL јЉиТƒV’6yh‘И­M*л)єBкwNFK bšВКщc€m=њSЏGzщЊt7Ъѕt“­ій‹‰†' Ёš7З§…0’eЦŒ[Ј …Ї‹„ЛТщ3СппЗЇЮpбЈc€§}haY(љY_ђГЁЇёbCsЉi”}Œ$l=^ееЧ@e_–VRтŒьє Яй+ ц–l сЂй…sgi*yЄЈ"Кop\П OW^ojЋш\АЂшА ='*Ў749‡‡Сœјдњј[ѕi[—eу‡@Рk $НSЦњЮNТtZ6ŸУД1€ДŒTгv2х–•ш•Ыдœl`–a4%ЮІџ–Ђцn­^ЏымЙsфc‘—+.ыѕOTЊјH'jЭ.e‡Ї…’|R]ЯфЌЉДі7уѕ†.ќК хЮћЉЊ9ƒЇŒч—zC§і/ѕ%?в—J›S|­рЯ’жcљЯ".ъ69Єхн@ёКtЕЖЉHьƒTІTнAды5B@Aь/Э_Лъє5Fг—PMсyQmБ9qђ0D/lѓбьГщRЋz—M)МЉќ№2Їb>{ЁLЩчX2PшtЧNХdŒeUжf+Žђ1ќ•vxQ­ОВтЧŠњ†zКЦIгЭњ7nбуєŸв' їeEайQWt§к˜P]@аqНpІЪє,ЄG|ФчзгM:ДQжџБ}fИ[KYѓЉша&­жџeтД;ђБ>Дd=1RМR{ЖЌR|ŒЄЈє’ЉH& IƒV}Jl›EЅ.7[@№Jв3’,€ЦЌ)Xd В5Š­zuлЈt˜х&Д–(ѕ‚gMrД§…Pf-išqшtALз8ћєщу_хЁќВx9QiЦIOЕyГЇ.]S,гЯŒ э,^=­ИVты" ^>мuЊjЪРр—ŸEњЁщgщuЭсŠO…ЬyFќzЈ лжгUКњш?†Dї Ѕ™тЏЋ.œ-­•ЌŽFє не7”б]ЕљEЅЕш,У6mеЇд˜ЫJ]f+вм €€зP>вd+ Aќє/—-9БКЪЌУt”ы-YГыЯšєщВ&Й a1ї%W—'NѕTG_гЗШШH1YВ?бНz­ци БрИ–з4 2n‡І—=ЁЛмиЂN*“FКћЯъЏќ\ЊkЈ—Lšж4t!›‹ чKЕwе !ч*ы_yчDWQCГqj’жiйЉCЉмXкcƒ@7Ъ~~‚V9јEQ]р_з`šд.ЫПaвф\Wг@E2aД№п SђйТL[—[Dл5ўƒ€hLryЂ™S1Я7- wdВŽцaщ­I#CS‘эџy/иœ›"gzев‹ІФйєп<п"СчУг•Е†љЧѓkoж^ПyНцп5Тяc<сЁG„пўKz™з"o-?зњZ]ЫeJЩru™џ+BNh\іЄ2•Jwkќ„ЦuZ1k 5>ўт5NсЧџЎт%bбƒxW­ Л.е6ј4>х NlЃi„Zњ—:­š6JŠц“R.]}ЌŒМуї зяš’(нСDЭ?ЙX†!ѕЏтSjF!Hw•Км)ўƒx%хг)У!ž„ЭЏъ5–№SБ5RЌ-МЉz0›D5;‘6Ч=4л*IнJ|$Н_AЉїЁсР$ёКЏ|/$ЕH$Š[]CmрvјљkuuЦ_kЛtъAsИš_kшёюЦ.зcЈіХš‹WсП]Д, Шит@KЕжНыM“9Њ •ЭvsXЅLгж$PNК"YJЅRsЫІє_ъ_*KLDбвЇд ЖСŸђЅT#[ХЬП’O33щЎyGšКlж4vA@€АљllsENо~м•ЭAњЙ+­КUKœ‚БRјЁІFЈюїћчOЧ†tOQлxRЎ3жщJщuu 5Цк <кВ%ѓlСKЅQreГ †ЃXЗйЬЕЅЁ™eOјвЊ26h_jЇSЕГqѓЉXЦƒZEо]GzрNmДіТМkЭНhбДЈVм|КдмfЄФyЃ60`јщ†ZnЌыn4>`|єзo”д]НNuЛ[ќ|&=@бЉЕеˆЌUv•ђ+w›V•]%"Ф р}ь?Л‚ћЧЭў^ДŒЁ)M5§—–њн$мџ7њr$лjиПћХЄєт™Цђ•*д`дЩнŒdi+еа§G*з8Ѕ–.._ЇurкфЈКxф@Рsи*vі‡§НhƒщдЎkёPж–&6ьщ‚j*ЋC‚[•;)зжќ\хЇЃЙнТƒ @@Р>іŸŠ]Сƒ} ФкіїЂe m2'вняOЯ…Піƒщqˆ-[TлѓгљS]5 ”€h#`џЉи2:Ј@@ZOрџї[_ 5мЇћ"p)”/i–ЩBвWUЙTlІ-`ЉЖ-ЈТ'€€З ЌIЩ’Э5БHы%ЃŽЇ-ЮЋ•sййPe•.М+ЧЦхцц|”ћЩ?–пњхŽа Њsˆэ~ќQљ?мЁvu \œ›™ МЌвЌ"лe–Ю!/)YжT*ЕЊ—эЌЌвЊ+ \  aЛB$NW™œіц‘iЛUюоЕэ;ЖmкšнЦdмяк§С†ЬM2PЕщЊ,›tвŒ“6;Гi;ѕЭЖ‚g+`СˆРЎН8‡ЗНжЏпmSaїОƒмоўƒС†№] Ю$€ФщLкhЫ:і]yГŸ мК}‹›9-kR‹WѕWyЛ.ГЧ ќJЇt&jCЏ1І6@sr$N‡7[<Аwџю}ЛЏU_эжЙћфчgŒР[*+)нѓбžs/оЎО-ќп;;vъйЋч€ОOФ<"ѕУЊH5ьMU№YСќЅ‹M}„Nїнз-јЁ!бOŒ7СппŸ7фЁъJхћћі}sюдЕkЗЩaЗЮјќ„ ќмЭZ1 rзо§?:xэк5ВO|&qЪфчШLj#[ЫЬFzБ- ›G…gіЊ?е†8‹OЬzk[n^ю­_n•}-sЩ\Ѕ]i„<ЉНЌѓъkњїїя;wідзЎ5н{ьБЉ&†іхЧ&ŽљОRLеїљ gО,юъысƒ‰зt}„тЏNњњъ„ЛBTlј:БвУ!нќ˜gœbУ-З]{?8ИярЕълнКб7yЪГуЅ4dЉ+ЕwGк,vZlпblн&?“8юйё-c7эI§№иl ƒЊЋМd[‡R $N-”Zmѓњщ;џБ—UЃГЯЪе+uї ЃF‰Й“юяXМbЅдуъ[WЋož8Л!kŸH ,х3пœnV6t‹Ъ­oЫЪО-;x$oЯЛ;§;:,wRДЋзЌМгxџ kёћЪ;пWюЭ9ДwйвWYš#i’жlHпЛŸwџ]™Лє§•ЕЏ.o*oѕлТhыQАь†mqЎZГъШЇљ–оЂБt^pД`щЪеwъФл‹иvччЋWОzфг#isSиGвŒњ§;I МXVQж;ДтЧ*v'Н’LšВ‹Ѕ,k2{цЭiЇх›х••ЋŽфaa|џУ щn\§‰экќj[w,БЗŒэћ•щ~jMlЖ…Ёђ –mІфmёu”6ё+?§XќеБWЇqяјˆЩ[ЖэрЪ”gœв%+2ћKббlv@3T_ѓЋ‘ь}’GJђ6/…љЄг_жЖЗЙ;…ВK‹›В&Хv,?яdўБАОb”JЉˆ d›ИxщЂд˜lшtvтdЁД ЌЂeз,к†=Ѓ`iTтKmЦuётС|hщœЧ`YФЙq%сbKчџЊ Е –5cDа0бсїьјgХъ }Ф9ёu!s5x`їyЙєЩ•?\ц&_ИиЌсіЮ98y$\ ŒgMvИRяЮ•}У фksлКc†н,6zбпЙВ‹ђ!Щim Cх- зtZ qj%е*Лй{бЗƒТ‰SLЖ§№УLИ}[\ўЂ­SЧNI3fвЪ*-yбВчИФёОї.+ВњњЦњudпЙsY’>K нSџ&—|[BТw—ПЃW:nEљQfzШ2Ђщ&)чœдЈй&=РиHН›7{О™YkwmыŽvГиш}$О•’›оJbВ- •З€†6aЂHРкЧ-ХŠ(P#*ž};шИ_{ЈWXйљ2вг=&/ЇЮя§ЇоНzѕъіhЋЎMвфц№G{О)=Gзяќ_гW Y[З%З№жmN}гќiНOoгНЃ\ ŸRiм† TZ~Ё\jЃ]–ЖТrќH ЄnлzЄm™…СУу‚™ДndXо—kц\ЪjфјDiL..7 %д№№№Ттє\у‘pё_?’œ<#‰–/^х‹MGHxџpс^гбюœƒ“E+}•`;ЅЉ Вmн1У.[г{JKTЖ…Ёђав(l” q*‘БK/о7ЁА­H[œ’2—.jRyўёBњ }„јш˜х‹_еryђФ—…/-šЯч‚fэHЏGšЕvЗNrћ(џРђ&5:ч6\ЛlУ&m…;ф9”H§Зщ(HbВ4 дт”|РВtkЇF€J МіhЖћф ,qвсZ]­џБЂМSЧћЦПyGЩЄa‡1?йЋтДƒ“ЬКЕŠЫМз\рE­lюŽYЛvЦf{Ъ'ЂVq€Б$N3 mОK‹r:\tКшBљ…K?])ўІXƒВ”YбTEjщЈюДˆMю­$mдRvT–žЁБЇmмlЏѕТьщK bЊЛ+wEчŠИ/њЪ#—Л5ЯЯЪZОљ;ўСt.#у‚у'шУѕІЌ6yлД i ™m™om5м6а &•0qв4“мђŸŒБ L=†YЉt­ЅгžЭaШzcJЃ тСВЈ-тДlХNЭДIЭcКvуыg‹‹ш8ЄЬQqЅтРС§“’І›љњФ@ІЙкјЮШHqЪ^™†v‡Ц˜lHvкСЩЂ’ОђŒ”[ЗdšЎRSAxшЁ‡И"чГzНѕvгЭ з‰#M?љ–}wHк”л‘ЊL4P ЇГ‚ГХgщ{œ#ŸI ‹ ‹4бbS>ТK/ЮсбŒŒХхIг_ яDѓЏEߘ4™QuњNz`@з8P ыѓътWяkЬtCг јЁєЧюl"хњХЏв7љd›{фHЩ†–јЂ™VѓTК&ыЭц0dН1ЅЦQPё`YдqZЖbЇF$-lО0ћ%:УJ?iхњ lpЅMD Ьw~шav#7Н>ќPѓЇЗСQЭ6N;8yT\ ьщ„ЇйюйІУѕ‘оpЉ0iм3|—ОfMoЂ{єф.8Њ;ДТ$Ўr7nќ­DoоКрЈ0д[AЉvM э5`iњЪf~a~IёЙђ~Є3з}џq_ЧЮыѓиФgЦаIћNž=WwРy?T^уwфВRњ"ŠрЃл§ўŽk?_ЅЂ‰#FвзZі:Ты:P Eіщ#>9Јш=ё„<7>9шБч'L5{rДбЅiЉ=zє8јбюkзФ'‰Ošј7PщЗ1l УЬ‰tWу(HЋh‘Ї–F[kУ‚мїбОSEпаЃшЩAtсѓЯѕьзїБј!І“;їйО”">ЖMГЯFyшї?ˆG 5Я>M_DЁ]gœдœйFйш§ЇŸдxрM˜<~TнйФэщйЦzуюwг›ЈлКOž0™žуУZТЭиЕ+жб-єO2ХFO5тБёe†!ыЪжИ'dxђ ikjєњš›U‡fШO Zыі^H€OˆЉяєѕ|/$€.Л ё~дѓY`1б1ZnОsС^ $W 0vGEрСз‹snџћ',еКТˆ  Kзє@СълzђUџ›фeыжrПг&Oф2А‡–jэЁ‡К .D€.]гŸe@ДžМ,-5"Мљл5–6а€€vHœкYС@РЅ ќрУ#Ÿ>UђЭЕЪЦkЗПядГgЯ'"Ѓ›†иmM.=‚sHœю3VЎ)ЎkКіјxEtєГh zЇ.№ŠОЂ“эIз8л“>кp;Hœn7d@@ = qЖ'}Д   рv8нnШ0€€@{@тlOњh@@Рэ qКн!`і$€Фйžєб6€€€л@тtЛ!CР  эI‰Г=щЃmЗ#€ФщvC†€A@к“g{вGл  nG‰гэ† ƒ€Д'$ЮіЄЖA@мŽЇл hOHœэImƒ€И$NЗ2   аž8л“>кp;Hœn7d@@ = qЖ'}Д   рv8нnШ0€€@{@тlOњh@@Рэ qКн!`і$€Фйžєб6€€€л@тtЛ!CР  эI‰Г=щЃmЗ#€ФщvC†€A@к“g{вGл  nG‰гэ† ƒ€Д'$ЮіЄЖA@мŽЇл hOHœэImƒ€И$NЗ2   аž8л“>кp;Hœn7d@@ = јДgуhлkœ-.ЊЌЌєšюЂЃі ‰Дз ъƒ@л@тlЎ№*!РВfdtŒDд(ЄbфN5F(k?HœэЧоkZІЙ&eЭˆ№Џщ1:j/а?†юzg;ЇНQПmрgлp…W%€ФщЁ‹n€Д $ЮЖс ЏЊЮŸ},тБЮ;ЋZi-t”­эС@РЛ qzїјЗSяWЌ^БёЕеееэв>mЛ`GЃ р1œ”8УТУ-‘Щ*-Э ё<хчЫ‡ ж^§jЏ„н^§EЛ Ž%рЄФщи сЭн мЉЛ#р†nwEФоJР%'}Яo┉Q§У‡'ŽЩЭЭсcБ={[lќSQб1ЏЌ\U_odzšЇ8Ијш1a§ЭgБTDеЩ Йš4mzе• VЅКZџђт%QCbШеœдљƒЛЪ=мhN”••|V0іY^Нљ ћВ‘LšЩVНВ•RzЅэ‰OTќЫ4L>:Рќ†є$ыЏU%ЭHъёp!=ІLbИm8ЁAHMK%§c§zяx{oюњpе%ћЁC†–Ÿ%ŸOФаnч‘ёCyCdЦЊ4й?f2ИdŠ„;„ –\"qІ.Yіть—Юœ*оЙ5ћ|љw,Ъ];?(љювс=ћ цћщ„ЌЭY<њ’o/эygйзХ\У…гп”ьйЖГ№Ћ“CžВbэzІŸ5?eꄉg ђ ?ЫянуС›75лŸоЙ-Л№шЩУG&Ѕ$yъxіжlЊ>"nШŠ +ИѓаP IDAT˜™J$мэиJ)Нв64~hбй"ЊЋЏж/[И ўЗz’ICz&M™>kцЌЫх—/_МмћсоkV.e­М‘ОЖцfЭ…Ђ Ч}}ќдqІdЏgОњђасC—+.?3ю™ ЧuьЋChїFŒyfЩ‚yRK“§™3‡*$<3o‘Œeh@Мœ€K$N???§-š:wZš–Ъ†dї‘ƒiЉ)ў§}}usgЇф;Ъ‡jсмО+–/0UynтјђoЫXбЁ]{ТњѕюељvаЭLšyъЋSМЪТi;QуЧПѓЫщnљySu•HЪŠe’7wС*С1ƒЯœ9CfЙч :Пœу…ЩGrŽДЪ‰#iUЛ^bНzХт„Цƒ!aTТвEѓЃŸŒf}Як”Е|щђI•“ўCї—цЮпћНLџJъ+tWэЃ}эј;П9џп‚#Ÿц{ +t@Рм2‚ˆ@@РЉ8[р oБя>;юЙћ0FЄ  @тФq  ­ рЄ›ƒј|Јгяя8pаТiўўў­І   рœ7у,+.ІПУ‡rќtКUЏopю#Šі$pтЋуžзусєGэZFуЭ6–4 pЮKœЌЗ4бL§{ЪЩS'iЗКZџђт%QCbЂЂcцЄЮ7 ЬцlqбЄ)Ѓњ‡O“››ЃЄ›8ІЊЊ’•|VРв^”я k6ЄЧ‰Ё?h—m4ї=ppџ№бcТњ7^ЮЭVQБ#žкЕwПЩШьŸFW’ZдЪЎНOђLўyыvv™ZPђLEФŠˆЗIгІW]Љ`с˜ѕЗU‡эйлbуХ^МВrU}Н‘љЄWrЫeл„-Yo$ŽO,<^xч—;єGэnЩк"ѕцЭ6RA\Š€Гgcч}‚YѓSІM˜xІ П№Гќо=мИyгЇ.Yіть—Юœ*оЙ5ћ|љwJЪ1KKJЉдpлАtуjvZ/*)%=)7П•Usѓ:MpщяњЭыДЫќаkЩЗ—іМПГьыbбlћЖš›ЕљЙ9‡џБяtёin#4К’V!ЙЄИ„|’gђO­АR;ЛЬœШzІЂгп”ьйЖГ№Ћ“CžВbэzfLЏвўЖ*€];?(љювс=ћ цћщ„ЌЭЭ ЙsлšGЎ\-ГъАrѕJ>яєfлЈЂ€€s8;qвД2§П7ŠDн;ДkOXП>ТН:пК™I3O}uŠѕйЯЯO‹ ;-MKURFE >}О„Js Žјљјˆ“Ю’ѓЇIOB^~nк<ёJ*mЏЮKЫЫ?ЦќаыТЙ)ЄdЛyŸфIЭИTашJZ…dю–j…•кйeцDж3-_тпбпзWїмФёхп–1cz•іЗUь>r0-ефsюь”мcGЙOZuчВ ТІ7M’,ыђ".xЁe—ЁpЮKœДИGЃЧ&дЫЅ‚ВK/Ь~‘–jI>pа­_n1.›^пxњыгЃ'N Eз_))#ћѕ9wю•~’“—ОjѕGЙŸ|юмEв“pUЋsЗ V—„лњЋLІWЪ.\ОЊП*5уzЉ б•Д ЩRЗМu;ЛЬšѕLEОL§ЂмyЇЁ9i[РэŸЏŽ|:‘ м ЁCoн6 PГk[ЅтЦщОlэтoL)й›mdЩ@  р"œtW-ѕжrŽВpбТљѓцЧDDвŒ“Z)w2(Ё }c§:’щbчђхЫ>§фs’-•”zw=ёeЁNчб?rыі­'О.$ щЩО{PЇъkz–cHшд‰97{эд]jfVЪv5К2Ћ+uл1Ј;+ЕГЫЬ‰ЌgГж•v[…џюNiоUr =€xчЭ8-™жеещt‚ЏNGwЌЌzm#7 ћPФЛ~шvžЁЎiц$Ћ0ш‰u™#FPнУGЌ[ŸAцgdќЈ ™Ф_ƒaeцкхўЅТШјЁВ65ZШ^ZФeЎИ=ЄnGŽЩ”іw™ќШz6k]iЗULžИj§JЪгф­ъJ% wKгP.л „Г;Гфj†?nђьЭ6r` pэ™8W/%#=#l`јд™ГњѕэЭ‘Ф’š50Hh!@YГёАбb p6$NgїЮіш$˜<Ч;ЛŽ^ƒx\уєДE@@к”g›т…sO#€Фщi#Šў€€Д)$Ю6Х ч  žF‰ггF§hSHœmŠЮA@<ЇЇ(њ  аІ8л/œƒ€x$NOQє@@ M qЖ)^8№4Hœž6Ђш€€@›pЦГj+.U”^М о><к;TнЦJЗяў iђsЎ‰3c№Ю^;“0кp#ЮHœ”5чЬ{YЪ–Ь7м"qR/‚‚ƒѕUUънёМRяьЕч#z `?g$N›ЃЄ‰ЋЋѓбu ˆŒˆєїїЗй*‚€€€§œ•8l ѕ•ХЏPЭњњњв’ЂЇ‹Цe4жлш е@@@РnЮJœvЪжECƒC Oњw 2^Ћ*+)Н№уeЁAљCPє€с^б;MOc"ЃJ/^6ўZрљDd­СXZZЪvЃЃcјlеЮъgП>[xКPl=$$К$я™ЂлЧ(Њ ЕFЃйХQ 8ъБЈ tѕЗЅЋњпŒ…g‹єzњйgcPPHЬ€H__ЕR}M_tЎЈжPЋЛ? OŸ>Ё†Ш*Ю‰‹5uЖъJepЃ™С`(јВpмшЊrіыЂЫ••$HущЕŒѓФзE•••:Ёз#’1лdch*Ф№ n8ХqИ+œ-;рпE№ЪЪJoмв'MžBI4їѓмВŠвˆАcƒ8 еjЇ$ŽѓяtЖфlўёТ?„L=Ю?Hм-*Й№_q4[ЕГ:ЕRYUI­ыќrч”]Њˆ 56ЈEe0Ї4FKС›]Ѕ,hщ*чxAм1Ё ­їNœИ\qyмЈQ49ЛќceмА8џCЕ>т‘>ЄЇЦЦ*ad‚ЎS€с–>Д[їF'ш‚LЛњŸ+)б’™еЩCмSbыЦ[Е‘§XыVмRД!Ek–5•\•њ—0УoЕЦ[њˆ?†Uўx™:EЦ4љЃš‰RŒш!јˆгPKePЗЫU—)/VќXEЅzzѕеыo„і Ёoђ&вы 3ZФ/#‰ГВЊ…•ВЭВЙІќo!рЄg§]/LВkœ4yЂщ‘ў7ƒP-ав+ЅRщјјv№n‰ ___У5=›}šэiПБЏvV'7ДфKYZЁTђF’RЭm‡Q‘1пd]Uп6фнQ{Ћжи FMk".:ОДтrўЯљtЋн'мMDjЉ  *:[DSЮЪ(љХгT;tt‚ў–>ЄgЈБž>NƒКЕˆŸг“ФiќЕ…Ycт‹esМ€x '%N{hВ‰Zм€˜ЙћЇ<›ЄЛ_—ќB˜,х6ž5YЁй.)эЌN(‹Г”шb$ycљИUnyрВЎ OфЧDФа—s|щтamњZfяпб?.6кп?Ёъš>'7'tђуЏye]х•4% эvтlQeЕоПCe_šЊъt:IЃкхСРqQwИ™с7Sў&йцЄ ƒ€€ЧpѕЅкцИWъTu­ЊOшЃ4ћЌњW%дŠВВюВ\mЎe!ѕ эeOuђWpЌ€^ыыХ[xzѕьХZАЭ­Ќ+КbълЩпxWаџЋъРО]М'NъщZЅ^o ек#х0*’UvљCHСб‚аGФJ„†„|VђPЈpЗž<‡є )јœЧТцўЅBHp/›8mкd›k*Ф№ n0уфу@gyК­”nџ):_šSCWщФЛg‹  ЊяAеД…ѕюSqЅвцъдFHЗїSъ2,6Ўў7qЩд6ЗВЎш6к‚‚ъMћњ<Щю€л 9qК–pЉзёУтYoe•Сн‚.œ;CЫЙѕПB‚ƒ‹ŠЮаќ•–iЉJDŸШГЅЅЛюЇЙlЏ‡šуgојkDП>gKJwэнO5ћєyДђgё.\кd›cEx/!pOШ№фAгждшѕ57ЋЭh“‡оQšIњ[В:аэoo—8овЦь5Кћ}§ЄПVEї”њv№—IУ/ZДЄКfЦ*ЛіT'ЗѕƒИŽJѓЮпъi§“’(лДИ5™6~†ЎрЪКвняяџ{Sя(љQ[lV-е~бsЖМRчып9ˆ]ёЅ›ƒќйuЭЦЏРR.дљБЕniќfИZ˜5іW%о)  р‘ЦюЈ| јzqЮэџфŒ'=‡–ђЂ:JВ‘50[†ЅTaќU|мј-‹/B˜ЋькSнфжЂuQ™uS6њР> ˜Œ›к2з7Ы+щF Ічв•K.S JѓtП.ЛJŒ.s3еЄ~ ƒ€€gpFтЄuBwy­g6z  `?їЙ9ШўОʘГ ЙXt@@@žЇ<чhЭVGг(ZА‡Ї=єP@@Ры qzнЃУ  і@тД‡ъ‚€x$NЏrt@@РHœіаC]Џ#€ФщuCŽƒ€иC‰гzЈ   рu8НnШбa{ qкCuA@МŽЇз 9:   `$N{шЁ.€€€з@тєК!G‡A@ь!€Фi=д№:Hœ^7фш0€€€=8эЁ‡К  ^G‰гы†А‡Ї=єP@@Ры qzнЃУ  і№БЇ2ъ‚8РйтЂЪЪJЇ5‡†@Р“„„„D„G:ЊGHœŽ" ? а†XжŒŒŽiУ6р<—@б‰BъœЃrgћ$ЮА№№ВтbЫ1Rв[Z:PуфFys\іEV)5pВьjё8ЙћЎгЭ5)kF„GИNHˆмˆ@шCwНГнQ‰з84є”œдšБFЪ>~Ј žOРё‰sзо§a§УщеeсйyfД­Кь лeЉfuŸЎSjлHy6зDЎ@Рё‰sїОнЏ.N;ИoЗ+t1€€€€c 88qž§К(№wуF ЄлšcН+ЌйА**:&vФS-&Ѓ zњќ~ррўсЃЧаф•9йžН-6ў)ђ№ЪЪUѕѕFІЄ&&M™е?|xт˜мм%„Э шU:E КфќLš6НъJ3ЎЎжПМxIдjtNъ|ƒС@zйъЬ~lт˜Њ*гMŸ0%iHЯ+2ЅњыЎН%j”ˆ w›me 47ХЦ5МƒВ”ШLоЁТˆ˜ЙmPЌ’;$†ўHЦЬk‘rѓ–,С輘|5BЁ"9Я=м8"бс4ОeeЅФsьГ|€LЕ›5‡!Ё$V—wв›ьхbж~TШу•†@Р= 88qю9ИgвФI„тЏу&эйЛ‡3йМ}[ЭЭкќмœУџиwКјДU=”|{iЯћ;ЫОя!кЕѓƒ’я.оГЏ№hОŸNШкœХ<Є.Yіть—Юœ*оЙ5ћ|љw*JVDЏl!Ž^Ѕ+rЇП)йГmgсW'‡<9dХкѕЬxжќ”i&ž)Ш/ќ,Пw7nоЄTйŒXZRJВсЖaщЦе,Л•”’žh|-).!JФŠˆ7VK‰€ŸВ””*oШрцЗВjn^?|(‡ўЎпМNЛм˜ лплvщћ+4‚ŸЪПqѓгЋTЄƒdчЖьТЃ'G ™”’ќхЉуй[Гi€FФ YБawЋбŒл› ВуЮmdcжxT(схЮ!€И/G&Nњ0ўЭ…ђQqq„#..Ždв04yŸфЅЭKѓoм^—Цy)щЩ`см2g–ЛLKMёяшяыЋ›;;%їиQІїѓѓгпЂЉ Ёsч ЅiЉ*JVЄєК|ЩљsЧ—[ЦЬэкжЏpЏЮЗƒnfвЬS_RЊЮєQQƒOŸ/!9ЇрˆŸ_A8щ,9šєъЭJ9(ˆ+U"`VWvW–’’C•‘uNЪМќ\3 n^ў1KЫƒGђ^MMGАƒ.yЮ\f Rqс‚ДЮƒhИЧч—;внђѓІ"'RНŠ™eЅЛWѕЗdcniг|pНJEў™‰F„ьЅЛ|€ЬєfЛR3оЂ™ ;юмFŠ‚+5JxЙ юKРZ6аоГЛТУЙЧ>ЩЃЩЋDгЭ SžONš)м+tъ^}MЯNЏ$pЏJznР„ŽAнѓпн)MЅLO_ЭyЃ1WбeМхЫ—}њЩчЄ—Uš9дВЛpбТљѓцЧDDв$‰ж]УRЏEЇјžС]O|YЈгљEємК}ы‰Џ IУN§ъuЅЅRPдqVЄD@Zё>тdЭБ+ВЌTˆ’C#"mЗ{PЇ–1w’–2Yъ–—jЉШm”АXu(ГЦЃB ЏеFa рњЖTK+“?њgž5Љч$“†­XŽŒК!k“ИЈj0lШмРЙ(щЙ&OH\Е~%ЫИUW*щў І'AМ‡ю iъšfŠВJЉУNяЋКf§бeuuu:рЋгб'€UЏmфTЊєФКЬŒ #ШxФ№ыжg†Wд(HA1’еR" ѕља_Т>иГŸr']dнјz3dY JЕŒˆ‘ёЃhLйрЎЬм@Л⣘œјєШ•щ(АњпŒt—SjЉhщЊЕ%,V§ШЦЌёЈPТkЕQ€И>‡%Юw|8ёй‰f“8ё>$eђьЙїытG%Œўы„~сИ™’ž0aЪфчњѕэ7uю,КёuбВДиСБL;x@JjZдР№ЬЭщыVЋ(Y{Mš:sќ”чšož”–IфеЫ_ЩHЯ>uцЌ~}{ѓ•ъ1‘QДИOЦqУтIމlѕ3вЈ-ЂDЌФљzуІD€GEТŠWqќ‹˜Сƒ&Юœ:@Y–’’C-#bF yіЬРКЦM ПЎtЅ]iTLNš6ГїУŽž8сЉБЃЛtщТ”Z*ZКj­F ‹U?В1k<*”№ZmДU›6i-њ3wЮмїш§—о[ВЖ№Ђ'OL™<ЎGˆЈOM™Kbx‘ThrйYЊ$Йт_SІN!Зѕ{ьРGXiUUе”ЩЂ’ўH ]ГZlWЩЇдX‹д2Д#{B†'šЖІFЏЏЙYuhFh;†‚ІA”аЗГ”ЙG)ЇККšWœ›2WчЃ[К|)iжЌZ50jм3уHІФ6ыoГ"ћG3ООщѕ+п_кЕл”џx].˜љЄŒ81qЬЊ5ЃcЃkoеRѕtњо‘ ањФˆ„g’^H"yѓл›П(ј‚пЮЦ]qСЬ'зK-6R{Ш  ‘} ЄGюKЏбовlьŽŠР‚ЏчмўїOŽЛЦiй4 N'“—sс› ьv*JŸ3^˜СчЎнЛX,ОООK—,экK{hщoЄЯ_МdиSУЈJPЗ –5I.ПќCо'sи}s/Я}9ыПM‹№к=Ум‘€У–jнБѓˆ<ž@yyЙeiй6Мщб"–Ѕ–šS…Gѕ7єДHKKВДLо™MТЈ„-[ЗдџVO$аЎe]h@Рѓ qzG^M сЉ„5ыжА{ЕHЈћх–ŽŠKЫ—.Їыїfz•]њтаO•?џђ8Эeu:г:0й/}uщюwќчƒџI$аЎŠ€Ч@тє˜ЁDG@@$@ЩВІЖцб>>лПGїќMŒЮйтГгžŸ˜§vvppАv^~­ювђ/mДќKЋСЌюЫѓ^Nœ0љЎќ§‘@Лк}Тм—@;'NЋЗЖZ’ЕЁ wRVRJЕЧwЅEр qAK-и€€=(ЗmЯоNФs%—‚ў$}тcn^юЌ™ГВпйжЊ&ўќчцЇšPEПІЪ'OžЄK›О|щкm*С№dNJœ.’92ЗdІЏMgO[u‘<љрBпкƒ@jZЊОZ___єибŒѕыRџžЪЂиёЮŽu+–ќбЧ–Y“юeUtтф‰ЭЫПЋж nіѕ IDATiК–љч?џ™_у|#ы кх~Ќњ$K-6м!pNJœќ‰ъ6Є+Њ(ёЅ›#шёГIЩzpq”xXюс5ќЉсНўмыНwо{я§=Сš–d/Zќ}хе№ЈpfLЏ”\-;Ш]qlшОмнЛєиџбЧ5є-Vqы–­ЇOяѕH/њ+)>MЛ–IУ]qСвŒqСвp>.‡sТИSзјдYч4†V@  HПОЩ›Ђ$ЧОТ5L5Ж,R2›3їeњ3ѓIYyз^љ/ƒJ§HeЉЉ^*Km ƒ€ pиŒSЫЏQВЙ#НJ'‘ВП‰ШIЕЊŠњ/ J]Ic йъoЊїŽžЩgљЫМ f УL‰]w!рАФЉхз(-Ъ‘0Љџ&Ђі*VQъЪlжъoЊїNі7нх@œ  ­"рАФiѓЏQЊџ&ЂlgdЋиѓ ˆVћSНwЃ‘ѕХ,gЫvJ—%рАФIПFyюм9ъ'ћ5Ъr?!™~’єъWџMDйКВUи/ В5иAC‡в/ƒЪж•UJАLжzяш7_˜§bдj~}ь–ХWЮe…@@Р 8ьц G§ЅЭѕ ˆВ~д{Їё7mю*‚€И‡Э8ЉKZ~вьЇЕ€аXХQП€ЈфGЅwJПб(л;м$‹JpŽLœZ~вьЇЕ`вXХQП€ЈфGЅwJПбЈЅwАp/ј=Nї/DыЅT~гK‰ л аާ=NGЮ8[г и‚€€€[@тtЫaCа  эEРawеЖWа.xЂ…Ё ѕ†ЮЂ рpЛойNo"GЙEтtIј6$IощЭп†mР5x.ЪšьMф."q:#œ€@› ЗНпљm.Я%€kœž;Жш€€@@тlЈp   рЙ8=wlб36 €ФйPс@@Рs qzюиЂg  m@‰Г  Т%€€€ч@тємБEЯ@@к€g@…KЯ%€ФщЙc‹ž€Д$Ю6€ —  žK‰гsЧ=hHœm.A@<—ЇчŽ-z  а8л*\‚€x.$NЯ[є @@   qЖTИ№\Hœž;Жш€€@@тlЈp   рЙ8=wlб36 €ФйPс@@Рs ј8Ёk—*J/^PoЈЯ#†іUЗqївА№№Втbъ4іЈЕінzЊp9vdСS…g[УБЧYIщмWRoUпbЇ•^8Єˆ‡Ъ‡ИuM'ЮHœ”5чЬ{YНџ[2пpTтДgиьЉЋоA.uhюЇ*шš3 dnЩL_›бЏ5ŠƒпБф]}ЉЖЊЊђхдљQCbшoNъќЊ+•VћoѕуCJNЌж•­ЈтPжоЅ”іoš§MЈгшпjœъ­ дГ h<Šк‚У(ПќЫš3~ЧœГgƒ ЈџЩuЋњšўљй{r№“…Ÿцгп№СO>?ыoЄ”Г…@@ ™РК;Э;JРY‰гІ 7Н›4uЪЈQ ОО:њ#!iЦ”MлВ™3Гf|— dЖ={[lќSQб1ЏЌ\U_o$ +ЅWЉŽ+IШЭЭž8&ЊјЄiгЋЎT0›ГХE“ІL$%‘ЌУъj§Ы‹—ˆГфhq–l0ИKЗиЂшЎАfУ*Њ;тЉ]{ї7‰њєи!1єG‚pЗЙ„KJ‘“Бe]ж:НЪ†AЪ]{? (Ї7Gњї=&ЌП8wчuIА„ЦJщ•›ёPIPb%ыъ…й/|YРЋSнс#ž’ѕo†е8EЗwkжrьД*`ЫƒЧiю ›Зdббs€Љм Ни§У‡_t8oeeЅŸŒ}–Іuf­‚,FЋpјYэЃJCв†ZА|cŠэЖм,m^#=їГц€dвАJ–ЦЂ^ŽЙйАВ]ў*-Uђ)џо”Џ2Ќrg^U6 йƒ™ЊШ‡зфKъŠdо/ЌŽХиФ1ДдЧ<бЧвždЅQnjй+ўЛtт7q|љЗeЬРЯЯO‹ц†Юƒ–І‰oZЫэаЎ=atAў^oнЬЄ™ЇОRЫєfЧ4ѓ–їI^кМ4џЦэеyiМ‰Мќ\Љ>/џ/’ В‘kЌ+ѕC2oŽŠŠ—.œ›Bбё].Ш6ЭK-V–Ў"Т#u~GХРДbъŸЇЦoщ“4–uЭЬd ˆgк<Б_ДЅЭM1ЋТv•Жz`<’їjjšx4vа%Я™ЫМЉ ЪТi;бЁ;~мј;Пм‘ю–Ÿ7фDЊW2SŠ™ЊЫsP8ќЌіQЅ!щЃх)osЏЙцЕuY4йЪШЪ YИW)o,ВЬХ 6%ŸJяMЉK•a•.­k)ЫVQ ЯВКЅЦъXDE >}О„*цёѓё+(пq%чO“ž•QЖlЫS5ЮИЋ–иеп­З`ЇŽш#4wвЎпя;ituћчЋ#ŸNl6ne_};˜МюакЦmгыГпyoѓ–ЭПѓ›ŸК$КdГџ&ЉьREцІЬђŠr:‘‰КVЖK5ЎъЏvюФќqЁQ‹я’p[•й˜НЪF~UЏЉЎ™+ЅцЄƒ"­"лДдРLVa%ыjzвєŒЬ7у†ХбŠ§Œ&га˜9dЛВuЅ–В"іЮ2иЅ•Жz`HЧ”;TJоІО4іQКЫF2ъЭvЙ™RЬdЏШAю№ГкG•†ЄŒ–7І’ ѕ7ёщ‘›ВВХO!Mˆ”Œe™3ЊV_Ејфя3o*У* мЌКйЎlЅ№ЬъЪюZ‹Ш~}ж­_Gu?ЩЩK_Еzы{явeВsч.._Дœ”*Ѓ,лœG*[Rw"†Qщ#Я”gŸуmвюРтrmїљД†РNВз;uЯwЇє(aэy §cш‡]яYО|йЇŸ|nщmсЂ…ѓчЭ‰ˆЄЙE>pЅКІ{PwšQБЗЅєfЈюAЄњŽAZ?CPsЖеmй\wѕАm(m-Ћшў1[џуЭЭйлЮ•ž[ЛT|;pUыYю”b—6ЁАеC:ІмЁmƒТЋk”bVЊ. UЪСj56ЄхЉdCїеќ(яЭџЮX—žУо#JЦвŽ№ЮZ=o0K->ЅpИœ0ЌJсIУа"ЫњЁ“jЯрЎД$ЎгљEємК}ы‰Џ IУNЖGYKыюkувKЕ)3gmпБ‹ЎSњЁ?hwжєЉ їC ћ`Я~вг4tуы,Ч`ђ„ФUыWВƒ›оotГщдёОЊkжПжbщ4фDМlNwх4uMгP3‡uuu:рЋгбYxеke§p%ПhЯ5$ŒŒК!k“И"l0lШlюкШјQДЫє+37аЎД–КЌTз,x3'в0FŽiVЊqWЅ‰VБbЭMOz){[іœщ3и2)UќkŒ™5"кФ№RЧeы*,{`H=аjlHщ)Gж†оь‹–Ѕm\Г*zPЬ’ХKўОdнЯEЕdI/Ы\щМav)љT‚# ^щН&ЕQ’ЭТP2S OЩ^IЏфgР 'жefŒHAG Бn}i˜ЃЌдЂgш]:qвЧЩїГп>ўеё˜сё4o[‘ўі–Ќрр†~Х+‹П8ўEЬрAgN>Рr<ІL~Ў_п~SчЮЂ›`щ§;8–й$M9~ЪsВЫ≙&v№€”дДЈс™›3вз­–uИzљ+щaУЇЮœеЏoo3Zv“gЯ М_?*aє_'є“t-yіЬРКЦM ПЎtЅ]-о˜R]u?Х@‘$'ЕЂ9i`*MиРJч#<ќPwZ;тMЈјч6ZК нŒ§/НijbЙ),{`HЋ'M›йћсGOœ№диб]КtaEJƒ"­hПЌГ’gЅУЯj56ЄєЦ”Ц#k“ўњЦI'‡…‰пшЇЋ$Я$ŒXѓКјСT昺ВЬ•ЮfG‘’O%8врэVГ0ЄnЅВRxR-В’Ÿ˜Ш(КONт†Х“Уje-­ЛЏЭ=!У“M[SЃззмЌ:4ЃMzGw?'§-YбіЗ7K”ПбУTёЎ0iъDšmФХšЦOн!Jэ'@Ÿ-dя]ВпГ=шЋ>џѕд“qБqі8БZ—жfЭKљєрЧV-a р ЦюЈ| јzqЮэџ$їЁкб ш9Д”еН’К­Ы­xuUJЪмШ~ђ›ЌTAБЧ хњџчЧИXёЮ…ЖиhuцД™Ц†њMY›FкMР'€€ЛpFтЄ‡а:ф9Дto‚ьЭ8ю>ˆ_#šwщОЩкecоdЭh•–Rыъ† F+ЗВ6P‚x9g$N/GьОнwЕuZ'ФCз Ќ\2pпсDф "рв79Јp  #€Фщ0”p  р 8Нa”бG‡@тtJ8№Hœо0Ъш#€€€У q: %€x$Noeє@@Рa8†Ž@@МЇ7Œ2њ  р0HœC G  о@РмЋИTQzё‚:MzШЛCžg+mХ5мCЁceо_.8ж{ys~wœпb{БmЛvлšЁ=ўЫJJчО’zЋњ–тH„yЈ\h;ь№ьЮHœ”5чЬ{YН?[2пpxтToБ}Kёj_ўhн› dnЩL_›бOќ]OМНљHАЙя.КT[}M?|ФSТ]ѓ~еџfœ4e"НšИлОеКє~vЗ>ЙqМ ­2x.Чa”_ўeMъЕеwЂ y-g%ЮAPџk9Л=іјуєу‹-еТўї?іИo™Л   ‘РК;-aВœ•8eWUN}~кŽїwД0Й+ьоw№oЯ=OЪэйлbуŸŠŠŽyeхЊњzг”>“8Ијш1a§MгЕ]{?ˆ!š­йАЊyўzWXГ!=vH §‘Рѕg‹‹h:е?|xтiЮ–m‹b§LJйFЭbуuI ЖЈEjwвДщUW*Иg*тfRеењ—/‰C§š“:п`0HKхЛ§J3A‹9АwПЩL…есЦЈЂУ‰IYYiСgcŸхAVВъЭ”Ћ[є]є,FЕŠzGcЗ‹‡*Jdъ‹ (5Є^‘AІW&0oђЩx/Ь~БрЫi ДXbЖ(ЂЕhvФ*lм? –6ЏП‘žћYs $“†UБ4ѕrƒДћdТvљЋДTЩЇьЈБ0LЏ*Ч›ь‘аTY6 эcдфFќ/uE2я VЧblт˜Њ*гСOяц–4Є'Yi”™^=‰€ы&NњйъnС=O|YШq<жчšŒюкљAЩw—яйWx4пO'dmЮт6%п^кѓўЮВЏ‹™ІЄИф№?іхчцдмЌнМ}Sn~+ЋццѕУ‡rшяњЭыДЫєЉK–Н8ћЅ3ЇŠwnЭ>_ўSЊДХ ,_e%3ГиxХгп”ьйЖГ№Ћ“CžВbэzвГх#z•]Gš5?eꄉg ђ ?ЫянуС›7qW*ТіїЖ]њў AћќPў›7˜Ѕ *=]|zчЖьТЃ'G ™”’ќхЉуй[Г)ШqCVlXСвbІАeпЩ3љчmЩ/%AЉ!ѕŠВДe“=^LšўціцOxoПћўфЉSЬE”Ѓ˜ЅG…ЌiI–ЕY№їдђ>bo–‚/ I&’1щeГ†иЎ%йШXiдЄnеŽ7‹wДЂeTЊ}Œ”\™НПЌŽХИЅ%ЅфЭpлАtуjі‘НЈЄ”єЄTei=€€ы&N‚;ћ…iяюz—S~wзš†вюю#гRSќ;њћњъцЮNЩ=v”л,œ›тяяЯwгцЅб.m$ф}’ЧєyљЙ\џ*щѓ1НŸŸŸўЭп ;-MЯ;ДЉДeіЎcієЪK%НYlм~љS_ž›8Оќл2ЎWэкFї5мЋЃГѓЬЄ™ЇО:Ѕd)е<’їjjš­ƒ.yЮ\VЄ„‚J.Hым1ˆ7ўЮ/wЄЛхч›ƒ”ъ•ЬT–э;gHФ{!;@М”Ѕ†ЌV”:aВl`ВCDxd ЮЏрЈ8џ kѓЇўyjќ˜ёf•#3щQ!ыпЬ•МЭНBцšзжeeа\0#+ƒdс^БžМБ Ш f )э*љT5Љ•уMИДЎЅ,[E)<Ыъ–Ћc5јєљЊ˜SpФЯЧ>Ъ“\rў4щIPeЫЖ qkЮИЋ–еп­ЗSXXСG {Ч)Oаj[`` MCЩЯэŸЏŽ|:БйЁЄ”šѕ‚@гSЖKТm§U&_еп’еoz}cі;яmоВ9№w~ѓS—Dї${•ЖЄ IeYчd`ЏтлС3eЉ;t%икVvЉ"sSfyE9%*бVв}•ЊWѕWy`мL аЇ fFQ™эJƒдbІАlпЅЁJc– о”ВZQъ„ЩВ) г“ІgdО7,nгЖь/LfФЄ>•#щQЁф_ъJЩ†"ёщ‘›ВВХGMcЇd,%,uЎEжтS:jRŸ*Ч›,pi]KYЖŠRx–е-5VЧ"В_ŸuызQХOrђвW­оњоЛЃF%œ;wqљЂхЄTeЫЖ qkкNКэзХщг^|ыУїЖєЫxoїžiSЇГ@:uЯwЇє(W fь=Lеbfнƒ:ЕдwbzЪЪo4О+(I/_ОьгO>'НіЖx -›хЅі -œ?o~LD$ЭiБ(|р ->Лuчq{%мР!Bk–†J1ѓdˆ—’ деŠR'*ВвСн?fыМЙ9{лЙвsk—ŠчPГM)033%џR3%›Њ+•?Ъ{ѓП3жЅgФDЧАУ^ЩXJ˜;ПЯG У‰e}• чZ|JGћ'С Ч›Rxв0ДШВ~NЯрЎД$ЎгљEємК}ы‰Џ IУ ie-­УЦХ ИєR-БЃi_ЭѕkДVSSCkbŒцф ‰ЋжЏdoN:_а§AJ”7dmз^ † ™FŽЩЬFЦЂ]І_IњјQLO~Ф+џwХ€ыšf~*mёл ЬZ—mдЬЦъnЇŽїU]3н†`f\WWЇг О:нŒАъЕfЅJЛ4Y™ОЎЭа}+t—3SBЁфФ6}k?TЪ7*;@М”Ѕ†ЌVTЁ-ѕЏr0LOz){[іœщ3иЉД–J`ff*ўЙЅЌ %МEЫв6ЎY=(fЩт%_ВHИ+о1'kLzйƒсЁП„}Аg?ЙЂƒdуыx‹fp”|*їC‚=Ч›YRЗRY)<ЉYЩЯ€AOЌЫЬ‘0‚œŒ>bнњ в0‡J‡Ÿ–ц`у^\=qЭщгf,]Кxњ”Iœь”ЩЯѕылoъмYt'*/bЧђ"3Ё_поЃџ:!~TB`@@rвLVš<{fр]уЧ&а_зКв.гЧ’š50uц,jKЋУi3{?ќрш‰ž;КK—.Ќ– >5šЕ6рфйsязбЈбиѕ Р[‘ ^J‚RCV+Ња–њW9t>ТУuЇ…;Љ=—•уLPёЯ-emв_п8iтdёвFуgЭgFЌy]ќD%kLњ$ЙƒaХ+‹П8ўEЬрAgN СnGЩЇвЈёШIАчx3 CъV*+…'Еб"+љ‰‰ŒЂ‹>qБёф$nX<Щ1‘1ЬЁЦQжв:l\œР=!У“M[SЃззмЌ:4CМ‚ш№nђNњ[ВКлэoo—h~K…zз,ЅTЇtгkŒЈB€О є_O=чop рjЦюЈ| јzqЮэџфŒkœєZЪ‹ъШFнЅ рВш …?ўЯqБтm#и@<ž€3'=„жЋžCыё :(%@k нCКoв|БYZ2€€;pFтtG.6ЧŒuZ›бЙiEŒИ›Т› ИСЭA6ї A@@Рс8ŽA@<™Ї'.њ  рpHœG ‡  žL‰г“G}p8$N‡#…CO&€ФщЩЃ‹О€8œЇУ‘Т!€€€'@тєфбEп@@N‰гсHс@@Р“ 8у‘{—*J/^PЇHyЧѓlеёвВВв…K—_§љЊйУо”єМ"Дќ~KYIщмWRoUп’6ЁЅЂY[йЕЇ]йŽ8$*Y'цРо§&хvэ§ v„ишš ЋXl/Ь~БрЫю™>т)šas(Ш9”щ{cЉ~lт˜ЊЊJцЊр3S+Є!=SZЦУєьUъŠdЖ+5 й*FйрЉ"yЃŸ}fЋ“ІMЏКRaцYк:/RЊЂ†дЩl—Х`ѕЈPgЈщ сбC№,.8УћFЌzmcйЅ сn‹ŒТщ•Џ"n~+ЋццѕУ‡rшяњЭыДЫ‡ЉфлK{опYіu1ivэќ фЛK‡їь+<šяЇВ67›qћYѓSІM˜xІ П№Гќо=мИy/тТіїЖ]њў љљќPў›7˜^-†т’Уџи—Ÿ›SsГvѓіmdџbвє7Зярп~ї§ЩSЇјvаq В-ћЮЊHѕc–6Ўin–n\Э>•”’ž—XФ#mWъŠ–hС(иЅыњЕЫЃbуiжH“<ѓ9YгhфхчІЭKЃY)mЏЮKЫЫ?жT",œ›BJЖЛћШСДдџŽўООКЙГSrхf\8ДkOнsЏŽвиЬЄ™ЇО:Х‹Иp№HоЋЉiЂŸКф9s™^% yŸф‘}Dxd ЮЏрЈ8ЌОІ?ѕЯSуЧŒчў­:4Г4лŠ|њ| )s Žјљјˆ­”œ?Mzfi™ѕ]-Uh,_`‚ч&Ž/џЖLН-V*[EKJЮ­ъ Е$JMC рюœtГўnН Є(-%ЭšIT—VпџЧОљK—lЩЬАtuUЋs7qE—6nыЏ2™^)НqљіЯWG>ШwЙог—nO-Џ(ПѓKуu>9›ЋњЋМ9юM%n,mzвєŒЬ7у†Хmк–=у…Щ”ЫЙ+&Ј84Г4льзgнњuЄќ$'/}еъ­яН;jTТЙs—/ZЮ,eу1sЂВЋЃJ№ОL#B]ОЃэтЗl-a(ѕТъQЁЮPЫAЂд4є ю}ь!f IDATN@.-ИdŸ‚ƒCRџ>7fи йшКuЂyЫ$t ъ$kж1Ј{ўЛ;Ѕ'MKГ…‹ЮŸ7?&"’в6-r†”iБ{Pwої 7nŒ­;Ћн?fыМЙ9{лЙвsk—šRїF‚ŠCЉ™ЅL Љgpз_ъt~§#ЗnпzтыBв№м,Ѕ%Œ6ЏдЈЅ^K–Е,5В~дj9H,‚@Р3ИєRэœЙ/вйŸнžS}[ŸѕжЖ?ї`м;uМЏъšщўвŒŒЕ!sYвЖ2sэЪЯф ‰ЋжЏЄДAЅUW*щў KГКК:N№ещшКТji@šФЇGЎLп@Wйf˜J В65†f  GŽЩ}NOz){[іœщ3dя’UqШ=( =Б.3cDТ21|ФКѕЄсЦJёpuA F{‚7\Ѕ`Д„ЁTWЊWђЃТPЫA"m2€€'pщФ9ћ…?>ійшёшžиЉгgЦЬ5Џ1њISgŽŸђПO2yіЬРКЦM ПЎtЅ]йAš2љЙ~}ћM;‹ОКhYZьрXKГеЫ_ЩHЯ>uцЌ~}{[&iкЬо?8zт„ЇЦŽювЅ ГQ‰ќŒўы„јQ ЩIЭБщ|„‡ъNыЈВ­Ј8”Е—*c"ЃhН:.6ž”qУтIމŒсJёpuA F{‚7\Ѕ`Д„ЁTWЊWђЃТPЫA"m2€€'И'dxђ ikjєњš›U‡f„ўПіЮ:Š*лї=kИ+‰ЬL\}Yd•w™1\™I Фؘ V3|ШW" ЩЫ Q№!‚!JVV‚1$*‘0‚€ Ž&ЈeЭ‡ШрЭЋC†У№1ё]Ќ%kНн9“ЂъœъЊўЈюЎўїъе9чд>ћь§лЇjwUWъјУ7Кѕ?ы‘}ЭелЪЇeЈяŽбя*[)ЛЋnщф–гџН<0юОд”Tо‚€€@˜њR[П›ŸmЎЛјЯПYё'=‡–ђЂ>’бАпVњпФЏўўUjŠѓ.М@@B…€‰“B‹чаЊ&†ЦЦХ–J~CU Ѓ   <ЌHœСуm@,^Ї6Ф<   `Š@PпdЪƒ€€€8-€Œ!@@ьC‰г>Б„'  @тД2†А$NћФž€€X@‰гШ@@Р>8эKx  `$N cћ@тДO,с €€€8-€Œ!@@ьC‰г>Б„'  @тД2†А$NћФž€€X@‰гШ@@Р>8эKx  `$N cћ@тДO,с €€€8-€Œ!@@ьC‰г>Б„'  @тД2†А$NћФž€€X@‰гШ@@Р>8эKx  `$N cћ@тДO,с €€€8-€Œ!@@ьC‰г>Б„'  @тД2†А$NћФž€€X@РъФйкzbќф)ё јцП!И§М 3–юІ6Y9–)У.p2м^№ыї‰й!a$<ѕ [*Б:q–”–Ќ|reksГПi†Яž)$щЅћ^všЂ^Ђ№В{ˆBƒй `o%N~ј8љŸџ=&q„L=ЫЭмNo,є‰o  ОžЙЯ5енНщЫ­ѕkЃ№ЬTонЗFzfŒom€6!„FˆХf%NNэђ•ЫŽѓ   b,MœьЛ}ЊО”-XМЄёH#'wю\Чј уКОПъИциPTœ26™оT *{ЉКЋЊ*кZ__7>cJвШ„™ѓцЗнЦ>mўdцьLjЄM$@L}r…dЩcOЎL›œ4&yiўђЮЮNжWчSЋ„„…P{ueUJк8RОjнњЎЎЋZЕЄ­vїŽ” N™ Eы9ЎЛ@’х[Ыh””ДфНЛї€”6ямƒ‚HЬx&.єWш—р К‡>аИ1 )њuМёэЦЉё8žv K&I7ЂѕФшеv;Ю• Эу[Uю ЕS™U•2S3ІДЗЛŒ! й&jЁvжE),+“Z1g‘wм$­1LПxЮ˜oк‘Bэ^аѕ}'Э(чкѓrЖА}V6Šгq8zt8ёšВœфїюлуМgbЄѓž Њж˜0Zw˜ЮюЂmNЁ<52KXiІO#;І‚0nїzщ(ЂYDЃЈŒTU]іh дюC—6ЛќБ4qВЫVєЉК~Е$kў е/qЄл^yuжмй}#Ы_,Лtўь§uє>{ў,UЙŒЉТБ?ЕьЊЊiњрЃБї]ћЬ&ж7хъ%‹=~ДЙІЂђѓ“_RЃжМEЫѓцЭШ<оиаєvУаŸпКЙМдэИZ%дEh@mЭŽ–/Oиѕzгс†ЈHGYЙиЛ–ц–ЏНоP_wщќПЪЋЋ˜ЦЩToЏ:ѕзЏi”wі7|{ў[ъ.Ѓ-sMh<жњ+ѓЫpЎ–Ž5ЋЉЊl:ќб„ёщYy9GŽО_YQIqœ:vmбZ&#CAЌˆq#zЄ‡k–™Ч„­›\lTђЈ-'ЈкyБѓЉЭOГ/@ŸДœ v.cЄ ф,єNЧ6pЮq\#RЈн "њFOwџžzчї0ікѓцСiщiŸ•" Gз_Г–З|qjзЋ5­Лю™02aДюp„!yDНДђВа˜нщ„Nn<dЃИэЈTЂ*k $`–ЁJЇ Њ–&NЏФ„§"Ѓ;П­ŸћІушNŸ2Ъ‡ъ –DwПж,+8д№ЎLƒ~{суyб§Ѓ#""чdN?љE+ŽŠŠъИ@чЦQЮiмђљ1j7ЅJШYцОfюИrЮq\#с^0cњŒПпЧЭиљЦ>jЁЊlY8ИV0kљŠм<:йv’vBg7Oi Иј3щfИЌ‘+0NцLЧЎ%ЄЭЗЊ BуU2ЪЊЬ/#Р•zЈЬ‰l>(Ћ<Ž2JЧ•dцЉ†6^1|иЦMIў­КCХыŸЎиўЪФ‰“>ћь/…OWB’BЮ2яє5sЉРї#Ž c$м Žћх_4iJMIІпY~=ьзє”Ќ’" ‡ЪГ–г7BЅх Ёve•OЁ;L‰02Ј‹P^iВljЇТШdŽbЄЃвTeY8оn–!яh›‚ЇЉРзЦŒLЎјЗЪ+Ћ>;ёй3OЙŽ8Б1ш”эKTш3€ {C]cS#П; rЧчЛwєsBaсъ?МѕŽVlХ+–/[žœ8‚NзhФ„QЃЕ2Зє‰mxЅFЕчkЕ]O – ШШhЛЧЦФr |Ћ6пъeAц—р -CЁtœpЭ2ѓИ€йЭУ_ ОљУ#M‘‘Q‰#GTTW|јqЕАљiV›J^цJLUхЇљЫЖq\#й^љPfEѕ+”8_лѕћ' žдE_YЎвЃS•Й#ыb„›ЌЏВндN' „‘Щ EжбШT8юŽY†МЃm AqЉ–бœŸѕheUхвљ љmЗщi‹JŠœ—S;;з•Q•IоvgќŽ]{(“бЏJ›Ÿ+ђ,t?ŽѓžКсшЧ•žга§ohџІчЎ‡уЪ•+‘‘ŽˆШHњ1|§Г› ЄR"ы5kFЦњMыи1Н§ыгdPВЈЌД@'ЁHŸЮdddД2L_W\D шVКKˆ hiѓMf *e~nvh’—ЁHOћ­з,3Ф7GєєTЙйгьќ{їш{6–l™0i•'ŒŸАqгjQ x\–yЇc ЅtœЯЧЙyТЩіК0xѕ.э=PеoШ­C˜й(Вp№ЁYСcЫUztЊ2wd]dЩфuB#мщ„ГNйdPYЂEжбШTx1ЫPeЁ ЊA”8#ћ8nП-–.sqЌ9‹ГћнtsкдIєОљІ›ЉЪ6­]ѕф{яП—|яшЬьЙw'мЭхMRюН;/П iTBIљ–тOГОYsГЇЯžУЇђг…ЋЖo‰•07{б№Л†дЏR"ы5{жœсw Ÿ›Лˆюь}buAЪН)BIwђяfЄMœдяЦsВ\ddДВцeН§жЩ™3ЦM$N}>Ў­t ФœHШ›О"}>h B“”^ЕЖœ ŸЙ‘JƒUe[юo§*wМЉzcЊХг€›Ъ о8ŽОі&€Фiяјš№.xŽ%[KŠŸ)fз,ЖЪтсL„ЧџЂСц{Їџac„а&`ŸФЉГлыl’EЯƒ.2UžЕ[o@№ќ@B‹Ж&іќ[ˆП­RqіїpžM?ѕђ‡я*оXnх4№ЦNє CіIœa<ЛКь\ДЏА'€iіS xX”8щ{Јrх<тЁZтЮƒў”:йї\њd%oС&ЩъtМ— ‹kjrЕВEьДkя `zєW”­иG Uќ™ЖЖџjЃх iUй Ќ@џ І]Сдqэъ†gј’Š;И•НИ#ВЕ`Е6_G ЛЂ]WRКVЂЂГЪfкЂкMИЌVПs“lb‹кu|ЇMb%!рViuв&Б*ЙkL›R•Y•6QAVjб"впG„3 ŠO0HРЂФIж(WЮг.qGы ˜]сOЉ“]aЃOэЅ6э&ЗЋгiЛаXкЕїЈQы5Ъ^ВEьДkя `jѕWдqMЩŸЉњєуOYšЛђЩхг2œ‹И)_BgЫ_ЌКє?Wй —-ŸŸRЪѓВpѕ>ЋД)}geІмШшм VPК,„ЏKез”ЭЊОTеЎ+)[+QеWiГЮьвъ'=2›…э:О“*m\КѕЛ™BBU:Ў1 JUЌЬкщг-"§}D8Иr@РыЇrх<сwfWј#ї”:xЫd<[NИіžа™%ВEь„kяЩ”шЏўЈуšŠ=›Лpгъm[Ыh9эXBgi=д‚eyДTН rѓДНЈEИzŸŽUТ„šŒЎъЈtY_е…WНДYЛЎЄl­D>"+(mж™]Z§д]fГЌ]5ДВ*Œ‹! BU:Ў)Э–н"впGЬЮЁ h sж=AЙ~–p‰;Г+ќQф”:вГещ„kя ‘Y"[ФNИіžL‰ўъ:ЎЉXэ|ѕЅŒЇбъEТ„Ю:Wцы^s‘К№uUн…ЋїщX%HЅ“UŒЎъЈtY_е…WНД™ѓЁ_SИV"‘”6ыЬ.Ё~™ЭВvеаЪЊ0.„€t UщИІ4CXv‹H1;„6 1Ь X—8• eKм™ZсOЉаTYЖ:)%LXцˆP•l;ск{B дЈПњЃqзЖWеЬЫžљ“g?ЄОN+кЉќ\ЫЪ.•ђТећŒ[ЅTЅ*ЫF7ВІ Љ’СWТЋ^к,\SИV"Q[а™]B§2›eэкѕ[d!ая%мЊуšP^ж(дЃП˜ ВЁбЮЌЛTЋЄ,[тЮд J…TжYOЕIЖ:RЁЊ‹r“В,sD)УЫВEь„kящ ГњЃз˜=єЕrчО7іеюмС-д/t+яYДЌT(,\НЯИUBЌQ6К‘5Iƒ ОŒГ—6 з•$3Дk%ъИЌ3Л„њe6ЫкeОЫL’…@)oPЇŽkJmnЫ2=:ћˆl&И  Р &qъ,qg|…?ю+ш,ƒЇк$[NЉPеEЙIYжqD)ЦЪВEь„kящ ГњЃзИaЮмЙ­rпбМQЇ•нЛТхCщTOћЎоgЪ*­Nж"нШš‚ЄA_ЦйK›…ыJ’кЕeўRЛЮьъ—й,k—љ.3IЅМA:Ў)ЕЙ-Ыєшь#В™рv,€'Dыqr›P~ээЇ-ЫћУО7bj`GїЦeлЌ•К!№&|шЮ”ыqцŒ3œщ‡Дях[ЫКОПкййYZVš>іЗћибНw–ўЃБ{бй^Њ=дCр}Ёˆ€шrР€€„Р AƒЦM|х‡+їп{?]И“HљЋ9АЃ{щ§чО  щxAtN—j9 @@@@L—jХ\а   n р7NЗˆ   Н8{Y   n qКEш%€ФйЫ%pK‰г-"€€€@/$Ю^(€€€[HœnA@@z qіВ@ @@м@тt‹   аK‰Г—J   р–€yo;еvт/ж7eи/џcШа!њ2aЛ•žокмžю{у{kЫ‰мUљЮ]А†7•”!6*<.ћOГЧ&ЁЃ О>„щ+UV$NЪšK—=Іoёж’ч‘8ѕYМеЛkЩж’тgЇ#t6pЧт lУ!‚С‘pЖ'x/ев~Ђ}ѕ5.l’С`МлГ4?щCЕ'џѓПYжЄјКus@HРl8ЬЪ 6ђњoсИж7коAы‘њ|D+Ю8Fџ`кrх~ТЫІЕ CИ|хr{зAќE xЯ8…WWVЅЄK“МjнњЎЎЋLцгцOfЮЮL™0>cJ}}5ВЏlє)ќюF{їэ?yJќHчYЉJ†WЉ@кH'iž9o~ћзmм$.У[˜/е2mL9}*G‘Y"ЂДJ ЧЙѕšЃ|k‘LIKоЛ{Wh?™QЛ{GЪ'і EыЉ/Н„F2=ЮЯkŽ EХ)c“щMж…ѕ’9Тњ еЪКшћЎTEeVe6(нЄ­žЉSклO3“пndjЁv*Ÿ;зёи“+“Ц&ЅљЫ;;;™€лO-FъТ cнЙйl“jЋk'оѕ4:ЅЖ'|ЮMьЎ^нHЁ˜ЇЈ/7Fh†vj фEjЩ’tЅйЌ‹ђSh5 !SGm”™6ЅдНў@ї.?&)­­'(њSтGз”MgwЩC6КVžљEŸЌ@FВз‚ХKИІ"Е у'Œыњоu ь‘Т_‹„RтЌ­йбђхЉЛ^o:мщ(+/cђWЎ^ВјбуG›k**??љ%5В3Tњ”ЊЖ|qjзЋ5­ЛЙуциŸZvUе4}№бићЦЎ}f“л˜јD­аxЁ%2 J;ЕphkѕіЊS§šHОГПслѓпry™§-Э-^{НЁОювљ•WW‘МаHЎЇќХВKчЯи_GяГчЯR•o:ТЗ е ЛИѕ]ЉŠ•љ(J7…zF%:бr‚ф;/v>Ељiіэ“–дN‹–чЭ›‘yМБЁщэ†Ё?Пusy)зЌ_аb”Щ+зЪP( ЪБцc\@;—Ё‚ЇАЏОкЉЅ•ЊeЦИ‚вf^жС7Йдjц*Е Ѓь’ПўP@o!ЩКЦƒQ}Ђпє[>?FэTи_Л+žn8њq$бЫЮЪ>њСQj4ђтL b”щЄpU„—‹щ`ч2Tђ4иWЉG8Е”TжQы6 *UЋœŒВ0ЪLЁв jYёxСРў1t„™>mњхя.+Ћ'?wt&€­ЮшByЁЇ‰ #њEF5vNХsпt§убщSІ %бh‹~уьКжхН3џq&§СŒ^==Ж—>ЗЙђхэх[Ыћ§4jyўЪ1#GєЪHJ”3$[ЎkŽшыЃщВŸi§Є–lZ"ЂєAчLЧ™ЗФ(ХXYf?ІТХŽ3кŽЊ–3d]„ŽЈКЋЊТ.F|WщсUЅ›B=#†лИi#ЩПUwЈx§гл_™8qвgŸ§Ѕ№‰Bjl=еVRZrВэ$X:{цЁГЌћ’1бэ$иЈ зIr:и•Z„< іUъN-Ѕ€ОInЃ ReАЪPЯUa”™BЅдBпY;эђЊ*?шL![б…ђЬэчќЌљ[J^HН?ЕДЊrс‚YЬB­Z, `xЇЗРwCє‰mxЅF5бЉг;†<п}˜Ѓ] Wџс­wмiКnћ }t-ŽЭBуПW]ЇBTё“ZхP2 J!œи˜XњвЪ1Jya™ SЪ(cc\пe€rЋOЪF|72PM†_ ОљУ#M‘‘Q‰#GTTW|јqЕАIВт‰Ы—-ONAgœ4sF62Щ\ЯФ…бƒyЂ щфЃ{ƒнƒОТЉХaƒj…QPЉ2XBіЁ~2Уь№ешcF&Wќл х•UŸјь™Їœпс№ PКT;kFЦњMыи‘Ђ§ыгtЃFч­tгЪŽ+=ч…њпаўыЧ|}ИЗнПcз:вZ›Ÿ+вf[UПл Лx –ы1hМ зC!œŒгз‘Пtsн%Є”–‹ЪJ—Т;;‹JŠв'Є3#гг&’$ыВŽКЄMЊ6ъЈUЪё])/+Ыєм=њž%[&Lš@'ŒŸАqгjaJЎ\ЙщˆˆŒЄ4ж?ЛYІYл.Ф(›':вг~ЋTХђЛЌЏŽТЉЅ’—Љх6Г‚, *1VU Ё’Q’сsе”~•Bmеь0;КŽƒѓГ­ЌЊ\:ЁуЧNЛŒˆДіЃХ{Ё”8gЯš3ќЎсssбmЎOЌ.HЙ7…љŸrянyљIЃJЪЗo|š5fЭЭž>{Ž‘‰Еvе“яНџ^ђНЃ3ГчоpЗїL™oд4^Dщ‚ЮМьЁЗп:9sЦИЉ“ Є”–‡п5tђяfЄMœдяЦsВВ™ŒŽ‘9‹ГћнtsкдIєОљІ›Љ*T+lдQЋ”7тЛR^V–щI‘DњRSвЈcъ§iTN‘Ь”<]ИjKё–јQ sГ™fmЛЃlžшpШYœля'‘ ЪpХŒѕЛЌЏŽтЉu§~'SЋ‚#‹‚JŒUuL"!dSњ…ƒ*ЭNГЃы8йЧqћmБєУв”­'№ЃИё9ЃчmИдбqщ|ћў…~yшн№ѕHŽОoелЪЇeрЗn}HйJ_>d7CЦ Œ ЖŸЋєPŒЛ/5%UЭ~$0ѕЅЖ~7 >л\wёŸГт7Nz-хE}‡HF_[A@ œ а?}~ѕїЏRSœЗ­сXV$Nz-žCи0ct&@'гБqБЅf~Siƒмx+g#€yњpVŸЖЯUЛ<ѓЧИ%ЁtsqЏ   ~"€Фщ'АP   `OHœіŒ+М№$N?…Z{@тДg\с€€€Ÿ У §%IDATqњ ,д‚€и“Ї=у Џ@@ќD‰гO`Ё@@Рž8эWx  р'Hœ~ Е  і$€Gюй3ЎўіŠж ?}каrЇўЖ$8ѕЧХХ%&ŒNл`€€—8НŽнYж1ЦЕ>e˜ јфУІЅЙtvkйѓ$‰мiФ@ Д q†VМ‚ТZ:зЄЌ™˜жXe%ЮЎЎЮЋ]†Ц›іаьНЛk‘8 С‚„ќЦjƒН$№ƒУёУUећŽПCетЌ:Œ%ињ‚ЁA<%€Фщ)9є ?”Uя;юŒ' єЉjwPŠХ @РІЌИTлvЊэФ_ўЌpи/џУћХЎi­WoV­sлн­€ОТ­ўа)О! Шˆёw9Г&{ХппњykO ч›œ `CV$NЪšK—ЙЙЋbkЩѓо'NЦЧ.!7ћ‚"зсКWobЪЃ­Ÿ7ЛЏЉ6zREр<Ё†> рV$NНшњўjеіЊCяН{ёgЂ~6р7ПљMцŒЬФсУkaжcљnО'W\’з]=gœЭЭ=9Ra"пЊhѓМhMр<З=A \ X•8{7І8/_Лђжи›k**Œщьь<бђчэ/W$–U˜Ra ь}НіиGяi:Bc-Э^А7.nкŒiŒ€!ŒžJвžxи“@PпдќqSют\ЪšФ>::zLJђVž5Џ9ЪЗ–ЅЄKIKоЛ{N}}нјŒ)I#fЮ›пўuoЏЎЌ"сЄ1ЩЋж­яъъ9Ј]sl(ZO)Це*”айяHU•m+TtЃ^{їэ?yJќH—6Y—кн;Ш2ƒŒq№уВгЖт”БЩєІ‚~;Г>…ІђF*Шј( їЄИkїkOЎCo*ькНЫ-ЁбGuИzUї›Ђ3К'ъ˜„™Г3[[O4Он8ѕ!>o]O–А pЁV‚@ъФ™pWтњg7Зžjs\ыIu=јЊЗWњызvНўЮў†oЯлгь8іЇ–]U5M|4іОБkŸйФкkkvД|yŠ„›7DE:ЪЪЫX{yuеЅѓџjЈЏ;№кыЧšq%n 2…ЊŽ-_œкѕjMыЧЮkz:]Zš[Ш2ƒŒ!“˜’ђЫ.?{`НЯž?KUvvM>н^мђQ™эAѕфЩ“Ут]—аЉ@U”„B—Ћ]Fоn}ЁљVSUйtјЃ угГђrŽ}ПВЂ’цэ„дБk‹жjЛћ)pка р–@P'Ю-Я–м:шцMЯ&ЅЄбЉbвЏžЬЅ}­Щ/ˆюб72gi.їГ№ё„ TЕrtЫЦ2ўШ=<СВ ` Аž@P_Њ]šЛфУ#M,uЛиQіbеЏюr=5уСєuХE;щт-]Те7kFЦњMыXjlџњ4нФфгг~[TVJњщUTRФ•мvgќŽ]{(w’ўЭЯѕЖs™B. -шtQк>!ѕMO›H&1лж•QUП}@џкП иr%S2~WTМЖу\НЉљPІ–€Zш†ц‘{т<Сё† &дgœ‹,йўЦЎеŸЁпЬшsд=ЃJ6<ЫќШš—MїЫLЮœAеœEYbчzZgЯšCХЙЙ‹шzщmЗп>?ыQЖ%gqю†gзЇMœѕгЈЌЙY я7БіЕЋž\ЛnSUEiџџЛєс…џааЃЩѕWІP%ІЌъt~заЩП›qхџ]™єР§9YЮывєЪYœНсЙВДЉ“Ј’œBjщџ8эњП(ьZ†ŽЄeикѓГ:Ю8ЕpаЖ!№ЃИё9ЃчmИдбqщ|ћў…Cќс§WFж#9њšЋЗ•OۘЎ/ƒ­AB€†ЋЃаУ­f/ШКкs{ХBљШ=Њ^їШНКъіэС”’ 3@Р{S_jыwгрГЭuџљ7+Ю8щ9Д”ѕэ&}lр а{›=`?xЏћa{Н›zџя68Œ† >$`EтЄ‡ат9Д>ŒTŒ€т‘{Ьz№^BB}њіa{sƒ `Eт4`D@ D№G;ѕил|МYt~Љ~dG8ў‚„<$Ю!А–€ЁŒЈџШ=k Цh >&€Фщc с ...ю“›†мс—[Щ‚ ѓ‘{F,ЄЇ %#’9Hœ!ВРœ˜0‚ŒЈ}Й:№ІXk=rЯр€”5%ƒђ!Hœ!Ќ 2•ВCХІ€XH ЈŸd!   † qТ!`81@@@Р$NА   Hœ˜   `‚Ї X$NЬ0A‰г,ˆ‚€€'ц€€˜ €ФiDA@@‰s@@L@т4 Ђ   €Ф‰9  & qš€Q@тФ8MР‚(€€ qb€€€€ Hœ&`A@@81@@@Р$NА   Hœ˜   `‚Ї X$NЬ0A‰г,ˆ‚€€'ц€€˜ €ФiDA@@‰s@@L@т4 Ђ   €Ф‰9  & qš€Q@тФ8MР‚(€€ qb€€€€ Hœ&`A@@81@@@Р$NА   Hœ˜   `‚Ї X$NЬ0A‰г,ˆ‚€€'ц€€˜ €ФiDA@@‰s@@L@т4 Ђ   €Ф‰9  & qš€Q@тФ8MР‚(€€ qb€€€€ Hœ&`A@@81@@@Р$NА   Hœ˜   `‚Ї X$NЬ0A‰г,ˆ‚€€'ц€€˜ €ФiDA@@‰s@@L@т4 Ђ   €Ф‰9  & qš€Q@тФ8MР‚(€€ qb€€€€ Hœ&`A@@81@@@Р$NА   Hœ˜   `‚@В{ЈнЙуНџh/ŸрЭuЦŽМgіЌ9з5‰*Ÿ6rњєiбДй„@\\\bТ_9ƒФщ+’аbXж<ДяPˆй sЭHЯH'q§мЩВцвмЧЬ(†lˆиZіŸыЗоёяёџѕeыѕmсUCт ЏxУ[5ŸўђЁVŽzр t53С(ЉnЙаУex&р€ФiDlJ€N6m|ОйўU{iYбGЧ›)zЃ“ђr џb0‹dќё­_ИЮHlб’‡.ШšіаlЦйиё=tgB{{{eYщбуКrхТmџ;~Iж’1)c,ˆcшэ8Цf‚Atјг (ˆ@(8їЭЙ‡ГОяоёMMєІUЉQхCkk+Е/Я_eЯЌЉђжvU шЂyп=ъюuŽk]ЛjэляМi;/ƒб!$Ю`Œ l/ ”V”f-Ьš8ebDпzSЊл*J•j?§єгyЙХEХЉїЇ*лэTіххЙруBQ^И(gт”iбббŽ>Ž!C‡<ГЩљ|zQN}lйcIї$%%&-Э]кйщzа]lЈГ~|њјЄФј™™3лПjcђŽхЅх)cSR’“іюЎu5:е[ЄdеъU]WCЇoMGтф3…А$@pьј>zєшЄћ')]Ѓ*5КZŽXјTaщжm‰У•bv+Ÿд!8 ( Љ)ЉТ-њ?‹цЭœwќНуM‡›†ўќжЭЯmцЁ?vќиЎ—w5i›:vmсZж^]Y}ъЏЇМvрКІoЯ|Ыk_ЊnљТйиtЄ)ЊOTYiWт*„4у3С€$ЇHP#pстчYˆтEе‹/№†Чtх“+‡м1„З rЎhЂЬ]иПkќ№x: Ѕы й‹sп™z^…OFˆŽˆˆ˜“9чdЯOнћю[“ПЦйо7"'яq&Лѓ}љL87'Зўњсў7…ћ {џ}{ 'Xpш? ГѓђИAtБЎџ‡Ыпеk7­.\]VZ?ŒЫ„w!єfB”&Ъ<‚­­m%/”œ”$e$N 4‡kзСЖ‘ЫsГч>2я‘ШО7ІІ:oќillЌ~ЉіеэЏђ *Œ9ЂјљтќЧђ_ўxъЖН?ШPTCs&,Ъ^Д(ыaGDdђ}Щб‘бm_ЕmuћЦЇ7’ЫWЎ\qD:‘‘эч:*+*ЉEz%жNg–ыŠ‹жЌ^C—pЋЖWх.Э%™Œ+7­+XVsKЬщЏOзМZSИІѕхк”ЊТЇŒп8У'ж№4ŒФнЗ­rлћМŸ6>оT *ўT†ХЃі­ЯэйНGЕ ер'@-}qнь3cъЄф”„ME›ї3{UсЊ-Х[F%Pr~зPЗОdЯЫОѕі[gdޘНHьЭяєд№7ФФ ŽcЇ˜*Л“G'г›7NšьКœЋ =mэ­ўиAg™ьD“їЂхNz+[ЎыЅк6U$ЮА 5№щ/ТаP†qƒ™а8љpУ3С€)ИTkD@B”@ШнУЂœƒпlŸЮ$Юр8,№€/Я2<4н‚‚€og.еEPaDрјv‡ œй[˜ о ŸўHœсkxЊ%pѕЊO/рh@KˆРL‘@‡™ИTq€  !B‰3D3A< €+ @ГeŸЮ\ЊЕхSю ŒyЯЬљ ž]їЌ{QH„,'ж†=HœЁ3X   @Hœ„ЁA@BgшХ ƒ€gсchа#€Фz1ƒХ  $€Ф@ј@@ є q†^Ь`1€€@ q>†=HœЁ3X   @Hœ„ЁA@BgшХ ƒ€@>vП›O}ЉWQ`(ErН‰“š”И   œ€+qžmЎуM(€€€ШќшлгЇ“Ы6Ѓ@@@€8ўbўџ%ї~?‹ЇЩIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/2.png0000644000175000017500000023634711733011756026165 0ustar sylvestresylvestre‰PNG  IHDR.$ФЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь} xEжvћџL6ИIP В| КnwAQHȘ€@`Й- YР$ˆ.№!r“ы" , ‹€Š"/AфЊАШ’§LD ˆ$Y ™ќџгЉIЅв]ЇІ{n™™œy†сtеЙМч­ъЎщžNŸЂ?ќYcЏзџєŸŠrUЇw}eо™лЗіe.N<МCгНИКЧ—ре‘ —у‡\Фo-Ы?YжєЅЂзг, Ь{—ЙЊwCцїжРю4Эы15ё†С‹НMзњsыв1іьH› ˆb€№Wћ=Ё/EА=8tŽ/’b€ ˆbРŸН>=‚­C…EХіLI› ˆb€№uokTљQYp_BѕEЖфƒ ˆb 8p-ENЇј*М|V+*аЪэЌp-6>Ў~урdŠPФ1Р№ўј МMяГр*ЯŠЪ‹x“їBсх‹J •KQхџ•этџЅpšвмq6ЖNьхЋNчх3ЅйЛœњ@Ž(Ь*B‹X–KA|ЪмŽю’­Эxу@бїїдбОrЦ[єzOыЪмЇh%Ъ\ Š.ƒ&mФ@˜0р§ё-ˆb€ м3р~)ŠК5БЩЏДžЉ‰‘‘‘љљЙн8ялМЫޘТbХy‰сљ(.[ЏfвяеРŠs)‰эо)њЅ6x-г>ЧМqjЭŸšц^,{jнQG„cзИ–аи}Щ18W[љXrRƒHPјъ[зЯНeхк3/|˜Ы~ˆbaе.x‰›rjЦ’­ЌЋъ3B›ђћЄд&ё‘2Ю%'іhY\RЖѕxСЦЯѓ˜!GЮ6yФ*З$Ф@ˆ1 9FЙ=ИAŠТёMтС  Ђ7ёH+xU<“Y0 b8№kn”bр‡UЃSšѓЧтМќМФ;7oй|яН)EХEEњАЎ Vр•;U—cЕ+EѕЊЕ[нашЖу ЧіNбз›Ыж;ЁЗмQ\в4Љ^фewќ:‘ХzјmcŽ‹K4эћ<‡O;‘ћочЙл4ыt_‚ГЄlЩ'Ќ>яq‹зюФЭ(ЭqО\М§/ђЉдЄNMуїЯџшPюR“RяKЈє9ЈMв№vёАдЭyуTЏ– Ул%СљкkŸW:v*ѓ\g™ѓ‡K‹•ўщb€&LЧЗ­Њі%АТёЗпUGz~|3yАšžGЊiЙЋ!q=$ 1wЮŒ[ њпэЫЁ9ccтсешзw7ОЇБ#пqљtмPgё№ЯСиФ–_ссж<оdЩ€q ™PXЎ/TЧЮРТЇkЩM"ѓЏ”EF8“яŒџКИ–ЅмцЧFEEИ’§_ц8во;š ‹GjгјMr/UЎ1 У‚OЖЩbŠ2kIoЊЯЖ#99p^ХМБvјьqŸоuєа)ј;Њэ_цwj•дГEќ‡Gѓ.U@…Ўн‡Žj?iЅKl\„“GфH ˆPg уеS,vdƒcёЋЖŸ3фФ8 Œит?цьPŸ\†pR`•KQхџ†nзцOEŽzѕъ%пŸ|6їlAAХjЏ0‰џŠ#›jрlž5­HгOџY KQујXœЪз—Ђ&Iї^д_t67O?sЊtRTтМT^ПаЉC‚№nw:…гJ5WІтfuйѕcxгb ‹…#Дј уяфrт TPшt§œщД'|%—ш™л@ !С€щјЦПdУкУЯ$ЉРŽЯŽo&ei“;ю?юAъпVЃ, Оqи:T ˜ ДЙ5JHLJbGU8=Š-s–9Ђ#Я—hЎЋмё"[…СЭэbЃе­ЯѓŠсчŸ–Э“"#5јэ жžдћДдц аxілXЋи)v8‹#ЃЂcA†rрж‡ЈˆjQтЂЭ$)Сu?XbЃсж —7ЎTPЌЏF‹^нz8ЉH0–1 œZЄ’.юŒb€~ŒЂ§Š§ж?ЙОцfМšЋiт‘e$yŒЌхЌі`ŽШМŠэЂk1UZ’,њНQlрЁ(ТpS‚сџЈЂTіфхžЫ-+/ƒпŠр”шrСхЫпУC}аgIаUКrїПУЊmЙvє|q|]}р/[ќ|§|6sЯРх8'?џаДДћ›СЕФЩњR9gр7$§UPЌƒo|g"мѕ№d*џеЇЂљШ:ЃŸ & оИтжљ wNMvоЋншИ;!ўб^щАFq ˆb \p{ŒЊX‡4гёђwпмzРЉђ™<„е, ОЃ5')x#Y:+Šu8тoq§VдЌYØќ˜“ЇЯ:р›их&б“сirП,люЯ-N§MLўХbчOE—ЪOх—5Mˆ<{N_Ф5Зх}IыяKЈp[СюЃ9Eg-/}”7ЁKтюЉC,у\yрJbД–њ;Иa!Щ`єЮб‚Э ?&-ћs'8-ЫљІјЭуУAП ˆЂMb РQpB[Ўg•+RgЖИїќјЪƒћHю4dY№uжcX‡РД-F_&[ОЉјk"§•œœЌ/?ь­ћV[UEg#ФёV>lМЅRИэИ№TЧйŠˆаЋ+|ќUё™sюа *Ў‰9ž~;ї~œє8 ЕиR§~GЅ‰юt`}rшЫC є~™W6ўеwDUЖCWE••шЁ"bЙ6ыУќ{іЋXщtмФЗŽяћ2nIаWСr§И"J•*ˆb ”РQ,+§ШfќuЄЂ‡пмyйЉцMщС№]ПЪ‰Ž{ЈъіTн >2оШ…Ѓ1c пЦт­ƒєŸQфYVр }•–Х§jmTŒГШQъќБЈў-рћ~с…№ Tg§KqipєџЊ№ЋѓšіWдEѕ€ХЮ^Ћ7[нКTЎпz Оє ђ†ih‡ѓЁB Zx™Mx'œО8MњЌWДeш…• ЛьVq‚Н<‚K0x0vг61@ „ т<6фЬyяЛђXрФ•˜7ЊнЊ–"Э™Ї§ЋАЎ6е‰њќыНіе=WqЈ-u–:rрžхввђBgбЩИ[я­ІђtЁz+l‰Mь\ Е•шS1@ f@uŒRтєУ-Г•xPђ}щ;ѕXАš…1ЕЊ,ЊB+—Ђˆњ…W;9a)К\лѕPy"\м*mшtоъд" .]Ю.НЅДИ†ІђBќjWU$Ћ’‘U'ЄG Ф€Ÿ№ўј М'Чћ, •ўЪџ….-ЊNМVч ~Gr!ыЋЃџQZч8Q[”сЧ’r'м'-ЖY‘сЮХoEV<1@ ўeРћу[0x№ž#яГ0И– ‡ўзXО{9т ѓђуl­FАz~›х€{| Цwi‘'b€ 4яoСрСћє> ƒьlHшіLtд‰'Ј^ќ—ы‰LжD9bРжК>iФ1`М?ОƒяIѓ> ƒ_–"(с-F"™ ˆ№`Рћу[0x№~,МЯ‚cЈЖ^еU@/b€ ˆb ФнъzюZеRыаЖсЦGк … ˆb€Ј єY›ЫVЃџS;ѓЇЌ‰b€ ‚‡ZŠ‚g, 1@ Е”ZŠjщРSкФ1@ ДЯXb€ j)ДевЇД‰b€h) žБ $Ф1@ дRh)ЊЅOiФ1< аR!оС ліRДtѕЊсУ3zєъЃнЈ%5Išћќ<žсЮ;КіэвЊХ ЁУђЯчКквцЬ_иОCМAа~ЊTGк?:hШ@pЎРaЅЖЖfеъŠSБДiЯЭ.+sђv&Аo‚№)~%”š€ТЮэ8сЌnШРSЇrВ>Ьъѓ‡ЧЎћЭінрф`ЯЎ‚]јЪ•‚ёSІІtHјz[\\ =жaTКЉјЁњЄмцh—ЏXtЕяœЖѕэ-0ށ;дЩ‘bЅЊ4AЬDЪЅЇjџsцб—FфЦвQ€^4ъй0d0Вы+˜сЎЊ{U]•CЌЗ(еrџ™лЕWя­™:љиkц„I6n€Ы R3{/-ZИѓУ,Ў 2ДЈљaЪ}њіцQ`ЖГFhv&лA”[ŽЌ‚%ШhкЪѕВ9PЧ†И5гуO>•ЕЏ*}Аэк­KY‰ёP   БЁnИ!˜W#лKбС#гъ\•_uщай›VЏлџщgъ0kю Ќsљп–^НД}лx_Кz 6еэЇЮxъЩ?9x|нЪU'Nџƒ)Џ_їfі?ЮlпДyџžнQmйr—Ÿ]6O~§DarшјЁuЋWэпѓYЗЎн3ЦŽоw№“U+WьnщfЭŸХ}fЯоўжцн;w^-ZОf5ogТШgЦ0№Hжю§юnвшŽЫ—BЛ-м!F(Ј1`9Ўy}ѕ™џ=t}ДmїхЋ—ЅРxtƒ DЎcNКЄ&6юJ*˜G_‘лJGѕJQС8ТhҘТШТ4р~DСЬžиЫe…кБУGŸ5fъ”gњѕэЯѕЭBdДcієЉЯЮžeўЂ#eoТгпйѕЮ}њ%ёЌ}ћA†5?,hлДЖ9й9 _+žОрyіMюhvД3)WR }жХ?Гџ~fгыNж/&cЎАс“гSУ^^Г–ћхЕ7?68ф-$ЈцеШіRTzэћ˜К1XТ3'Œ…оШHЧЃћŸўћ)ІЖkїЮЩу&УYМў2nђЎн{еэQQQпУ9FqНzёг'OdЪоЫœ<бх|Ь“cwюнƒaрэ “I&зЋ8ћїы§пзХЭг'\АС‡ ТЎїwqЯLиЖ~SгцЭДА3ŒШq№гƒЖЉ€Сѕ1Š@AsžљоЎПLœЌEДcєЈ1<A:ˆjCЉ †MэJ:њ Х(HQС8rJa6J=[dSƒkn3_˜ёЪŠeЉ­вЬўйЪСл›6mжІeXеx фьнЈ-™ѓтМe‹с cёВХ У• ѓЫRRк:‘ ТŽЌїЂ"ЂВВєs‹ь‡ ™KЙ’cЈ0ъ3Wќsв˜БАЫГMЬ6|вajй"9Ю•ЕGПќќ`џоЊ•ž#!3ДЋQ‡hQˆЊ{ |БТVЃШhзЬƒЃќѕr—Ы пзkЯ6@ИVpЩXћв—Ќzѕѕх+–ЧнѕЬФЉЉ­’AџкЗКџЁЏЫ#ќgИТ„я!€œ‰›6ДKas ЇЮф.YКфtюiXЬєF’w…Q j ˜ѓ И!bQЂкVj‚aSЛ’ŽОТD1 RT"3EЂŽ"4ІЖсЕ}џа/щ7I [БktЦˆA#‡Ѕ$ЇРВФл1і`Ўі§CїЅЫVщ_5*єм ’›7›ї‚~!§§ЛЮ~~хыЏѕшбѓЫ/ПšљьLf"х У&R}Ctё(ЙТ†OфVІaУ/y9НSКўKСуƒйўkˆK›j`5њљчŸ ђѓеjюEŸ8ŠЖ)mГ>й­Оь`Аn |…aѓ „КёЗ0ЌісEЛ ќl0sцŒоџєыЦ7м§к:qrЂ˜7=018ЉЛЁЁwвГ“žїLZЫd8ѓ€+-к>hP`›V``T€5ЬyУј†мPŠ*6uhщш+L,Žї 2ёvQuФvƒŒЉНОzна9ъФyФкwіЕgЮ;uђІЕЏѓ{љчѓ2пйѕђ_Я[И8-5MœПТКpџУfЦл,њСАЉУIG_,JїЮEJЅjRіЬš˜|a‚е(ѓЬѕо4[I[їщЛ№ЅЊY$eОё<;cђ‚9ГSL›:eъгSŸе~вДW№УУЕ~АЭМ%‹Лѕь-нКv›їТbhсНRAŠAЊщЖs… Ÿb˜†eќyеъUЃ† g'й]n‚`ЛRg{)‚oaЋўіЪ'Guщг3Ѕ}‹чП№ћ.П7$iи§фˆИ[oямЇ'МoПѕvиd X{ћv­ЧNœœвЖХ’х‹Ю{ž)ќhѓћš?6f$мY{cћvэ Q`3уБ§‡<ЪЇІГБЅљ}Mz§q@ч=уbcс*Šиђѓ3Ї-^ИИiл šМзрSЫ1cшˆ&wнбkр€.}zеЏ_Ÿa3у€э §`идсЄЃЏˆˆeє“cтъ8`Lad›Зh-U“ВgжTЈщЋб+Ћ2?и?з› Ѕ-pЅсRQя’Вkе ƒйu<Иp§pЯns*V/?мaZr \OoЏпs”оЉ3ШiЩ’ŸВИ>R Ђ‚us… Ÿb˜к]Пn­G'M)AЕниuєƒCч^Эп6мъеmibaжKšљчп Щne7& ‚A Œј Šпwy(Н}zР"†A Иi"5ћЛQŸЕЙqЗ&\:ОУіY‘4j $pQ~[ dDŠE  №гРЙoЮб:ф§pР Ф^оЛђ‰лЗ-ј$*9ё†GߘјДНћГН GЖФ@0*&6\*ќ.$РB,?ќє(ЈnЂЃЅEA{uюШ§(hъ Т— н%C…rX‡`љaЋ,Hl3HРгК ‚A Ф€Њ…Чœ'™9Ёb€ ТŠёZ\pžбYQXM8J† ˆPd€ЮŠBqд31@ ž3РNŒР^<[ђм/,i)ђ‹фƒ ˆb x!F]  ЉщC`‰b€Gh) ЧQЅœˆb€)h) Љс"АФ1@ „#Д…уЈRNФ1@ „Д…дpXb€ Т‘ZŠТqT)'b€ BŠZŠBjИ,1@ сШ-Eс8Њ”1@ !Х-E!5\– ˆpd€–ЂpUЪ‰ ˆb€–Ђ.K Ф@82@KQ8Ž*хD Ф@H1ўK!ЉqідЉœЎНz‡YRnrіДл KVt<яK; 'жюЫи5ч+МГЋ9^нG<ѓсПЙg=А^Žё’ЅKІN™J••;hUбМО*G$Ф€Р€НЅhдИЇЖnпСЭЗnп-|“+ И]EдЛгgџ•к2йJ в‘2 ІWj"6К>Pц!@`яівІЭ˜Z\\,К"йЬЇЮмU#-Aˆ‡O*.„3і–ЂБOŒ[ћЦZWц?ikпи0іЯуj„ˆZєzщuэЦZ›}ш%KМЗoлхpЬ~i~ш%@ˆƒ‰6иї!Q&ŒbБЗ%5IК'щžЌ=Y-++ фЄ;“цЬ__њр ‚і“ ‡сл„aгЅє“Ж|ХВіЛДяœЖѕэ-ЌёЪ•‚ёSІІtHKIM5ёўE<ьмЙЃkпо)­Z :,џ|ЎЫ‰јŸЬ!єK mњЩ9gюl@еО[—ѕoП)fДfеjШКІ=7ЛЌЬ)"2ЫмPšы…OQmkц§їЁVЎFо‹ЅЃ`&ИХ žmsЕНbPR[ 2~ЧЪњ0ЋЯ#|ŒђxњваЧŽ+PVˆЫ•Й€%ˆс„ФчЬчcфšQмŒUN ы’І ]RЬЬsХЧ…љQ|ЦФФL|zьg?3ы`9ЂЙ 90)~)чвF€jнCЕМt„ђcF53ї~tDр gЮыЅE w~Јжи dh‘тЉTбчрh;>Ь:~шУд7€ цt KOпТО‰eСKг‘2#…С§Иь-EрnьS#_{]?1zm§Z—џmYсеK№Ѕо—Ў^‚MЗ!ЙТšзWŸљпѓл7mўhлюЫW/Гі‘ЯŒ:`р‘Ќнћ?мнЄб –/хњ‡ОШоДzнўO?ы№P‡Ys_рэ\:„^ЉЁн@ЫџЖК№Gчю;ЖПЕ9ћФt§К7ГџqВиПgw”C[Жмf`тї"ћяg6НБюдa§ћ54ВoC `)HyАˆг IК?ДnѕЊ§{>ыжЕ{Цибћ~Вjх*ЃnщfЭŸ №ТBOœ:уЉ'џ|фрёu+W8§І,~b ‚Žчђ5Ћ ЏБ1`Ђ+&dRWfб'Б—#Ѕ]XŽX.X;8ё`јЅœKmySSЄTs[пŽИ•†“ц5сщ‰яьzчРО§`•Еo?Ша"ХУб‚}<Ž0п`жСИА.t@§pˆвt+ћ&–ѓŸвtЬЬ(`pWjс†ФЎЃ:ЇА  №jўЖсIjmж;mюьЈ iњД™]{uYЗђz тЁсЪХ‚ЧžљСіwA†e“Сe&†MжпєсФlY‹сЮ0КєьЕoїGаŽК72:dhOkїр‘УњqY|IZ1ДHwОzUНzЎL;ўЁ;KОбЏZЖ4ЁA" sИ^Ая}0ітT`РИѓ›ŸэоSWO^†^жŸb RЌрФ ё(†@:ЖН{с+?koбіAq“p|xzjЯN dХ1œbт0љ‰Ў ЂЎaхц ˆу" С•ab,[ООЪ,zažЈiХБ\Аv[œKТ–1Х1Сэ.ЬcaSj‚aaиЕ…1јјc};wЯмНkгЋыиЌ6р1јпћо.ѓЁOд1Ј/ œѕё‹;#Жo‚š4 iтb:+#"2Ух>ksуnMИt|GoВ.Œ1ВcЗю{пп& Очk з .XїsЁрЗхVЇЮфТMbЇsO_џїuНQШж!h‹Œt\/чU‚дЁЎ_Б€ эвWЌCрG„}эл нџаЗ „ИЊ‘ЄРЬКи‘KAЪƒEœRHX €ЪіX`P ›|ŒАаK_ZАъез—ЏXwsд3ЇІЖ2оŽЁˆ+Х)&.Ž‘™RБEъ У,bу"ъР ›Зќђmл>8ѓйЩb“ББ\Аv№&тС№K9—6кђ цЅ8&HЉmЭВдУf0Зe 3ЙяК/]Жъ/'ѓYmphифs ~шS ЈЏ €GAЯBБo‚i/ѓ]/џuёМ…‹гRгјZс“О*} ™&> ~9€`щ(`КЄYp,ЎРяaиў­Ш€ {чѓ—Ь‡Х^Я-™›LсзПkњцІ-А–_+^€м8пAž[8ЪJœ№3;3,--u8ДH‡ŽћГ_\`Їо”:ФLьЊШtiEЂХѓ—U§‚5x@пй/<Ч|0›сЮ,ЂХі[ъў"џbеў +,)орФ)А‰]Xhр*??OџНЗ\+•цклНsGз-‘пЎf‘^ ؗOd,G,ЌнУ/х\кhЫƒ;&ˆ:˜€б‘цGЊggL^0gvъƒi№w{OO}VћIПџHGœlнЛugIс ‡ЪЪЩiэТNЉ1ЎXЛ4Е‰ЁWšзСв10у= o—ЂбOŽˆЛѕіЮ}zТћі[o‡M–УЌiS>ўфcјЕ`рˆЧZЗhЭ…ŒЁ#šмuGЏКєщUП~}жѕќЬi‹.nкЖХc#F6ПЏ‰ЈяV–:ФЌь‘1"ЎŽЃsž№kPѓп5г>і2јбцї5lЬHИ fsћvэБˆл3бШЃVf!–‚”opb,f„…n艓SкЖXВ|ёТyЯ›Нй;њЩ1Uc„Э:kєb˜Э НlСrФrСк 00ќRЮЅЖ<ˆбБc‚ЈƒЩ'?† s+ЖKmОД`аРСM›6MИPќpЯns^вПЋёР ŽpLˆ‹с:єaъЇˆ41_ЗВ4 n…Ѕc`Ц{žмЖРQжZОЫ7іƒL§ zФ@-dР№ЛН-‚чтMЖRЦ”љm оžaТВЎ"ТЕDИўГtйвю:†eŽ”1@ ј‰:€(ˆ­МЬЄPЁЎJр*"\K,-/эдЎœnW6гџФ1@ Иg€ Žш‚ъ"ˆb€№#tЮф’kb€ ˆ[ иў­шTvљ›х ›nkЅєщл[ЪKХ Њк0Z diU ІЃњD*Ѓ€‰Д”УЯЪЋk˜*§0–Џ‰I_зAP+DРVT†ЁRгЫГeC.XMц>-”pЬVš ЉЧ•ВЪUЄ ‡1ЯM!ђЉЌ}Ukyзn]рЯШИ-X:рVN#R[Hє ђЬ “6lмРїCяБУGуnŽызЋ\\№fшХ6’ИKV%^a`иdN<˜uЬ|ŠЅTHЉ“šѓŒИOЌь8 &Ÿм#ВgYєnЄщцІRjањ№Щ‚.BЃ*rшрцUоLћˆ• Ь§Ё`o)bЇ‡в/bnkЅДMk›“РCчІ/xњђбьhAZУ-_ŠЪ(вR"м!V]У\щGL™›sСЌ] TV*ˆ`иЄEe85НLMš‹ДІ w ‚ХЁ‘ŽйЊs‘В*BYNСМСмтЉŒa/Џб qБз+ЏН1јБ!№LоЪ§,ш’вЈЈ-$К…(ГЇO}vі,§q|ІзІЬMƒ‚ц?іДщэMІ~ДAм%QЅЪЯfѕ%ЅNj^‰ЈкџVv0Ю юЫЌјW™›JЉЙMM еп˜S„‚НЅH‘РЄ1cљ3Щ7М—9yтXxX5<™{Ь“cwюн†))эШaGж{QQPфь‡ „mы75…Ÿ ntРn =z№гƒашіЕkїЮЩує'КУы/у&якН—›№vvUдГр] HB{ц{ЛєGФђhЧшQcDЉ,еW š4arНКё@Kџ~§Ё †ИyњФ)УU№НўЈOx:јєЩ xдє”ХЭ™\#ѕшРўЇџюТ *X)с˜­:)Ћ"$ЅсЬЬЭ!ZЖHŽsDБ Х№pлƒŸьпЛПС KдЄ4ТФу8a~М‰›№єГ6-лР)6‚ '_œ<н#=фєєtЁХ ƒmŠЛ$ІУл=›uм\ЄT(Јm1YмSАl9л XпыСаŠŒ"0—ІŒхТкЅP§=еjЖзgO[Ћ$HkW$7o6ЏЂnић;v-œ§ќЪз_ыбЃч—_~5ѓй™@ХЊВ•Qј3оAрЅDИЙ!єŠХ`ИВBъ+PС’ЩМ)*ˆ`иЄEe865Н\Э,HkКˆj‡FJ8fЋЮEЪЊ di8ѓsiˆaУ/y9НSњвеЋ†?>˜‘hˆЅ:RХ(АшP”сyšƒFKINaхd]›ЗlўўкїMSєЋ=Ў–mяiщIт.YiўяйЌ“К“RЁ NъФаheЧN2жїz0ДтЃЬЅ)R0lJЁњ{0еІЯ–"1+iэ иБяLИJі:Q-[%Џ\ГђРс§аТvx‹U1Ф( +*ЃЈ‹pHV8””P27Хт1М]Šы( ›ДЈ їЃІ—Ћy X)с˜­:)Ћфвpж™—†Hm•ЖђІ——ЏZ§eЮ—sЇып /,ƒпЃ`о.nд^œ9kьдЩ›жОюRјIлК}'дЈdUВ N‰ љ“ўшх>АVЗѕУ<›uX8sЛ]ъЬЌДHg7Фrф jСKsƒs)TO`† кєй:1+ЌvEылЬ[ВИ[Яn м­kЗy/,†fˆUХнšeEeu ЁДвЁ2‡CЊЏ@%кb2†MZTFtЂ —Ћ)rс:СтаH ЧlеЙHY5 ’†ГЮ<bXЦŸW­^5jиpщБKЧ€oZЌ-Фѕїщ  X \Ф~ропђuA†vq›[YмжѓxжYœQuЭ­ф:вYСmБЙ‚ZАkЎNM епX`Эіњe)ТjWЄ%ЇРYszћЮszЇЮ Ї%ЇБќБЊjv•QдE80„вJ?†Ъ"$ЉО•h‹Щ6iQቂ^ЎІШ…ы‹C#%ГUч"eе€JЮ:ѓXG„vзЏТЅcC8Ж‰Ѕ#U†F‹Е…Dѓ~}ћ_**b-Џmн8№‘b/ШНћ|kыFCЃлMЗѕУ<žugFEsЗ 2щЌрЖXŽ\A-и5WЇ&…ъя ЌNАf{kзуPсяO>^ГŒStя€[ZйJоЛ2x?eъяЛ<”о^ПM€^ЁХ€џf…Яy№д›РЕёqЈЙџЬ…KБ>ŸUф0l€П9їЭ9Z‡Тf@k["!=§rлBpЮ€GߘјДћћГƒ<Ёђ7№EЕabУЅ/К~Їёw8ђO ј–PŸРЕh):r`ПoЧžМеўИ:чŸ5ХOэŒB#шЈў№Ш‰ф—л™Х"ˆb€uМ]ŠрЌапxТKsgЂўOЪщкЋwMq[Sq§=XX^XЛПёxрПf'†uРЁ‚“e$РЏ0М]ŠЌН]MПІmЫЙ-eЛi†Јў’ЅKІN™ъзB”ќ`†M w" е,a8еV5оы'6j˜‚ДУ)UžFЗlTЛH‚w)В› щ’Нl•ЭgЯ^€cСолЗэˆr8fП4?Рбƒ*\ЈLŒPСTƒыW0і—"М‹Д˜‡Д2Д |ЛС*ЌШk{ хC*ŠжЬNIMkп­ /|i ‘“С\kDЊЬLр“лЪSM5EєNЄ$‰ŽdћŽЎ}{ЇЄЖ4d \Ы†ЊN}щвЊХ ЁУђЯЛJ=YTƒ8всаЭmжVb2c>™РаŠ)xЪмƒ7W—”CM3gњвЂ8ЬГT_ћЩ9g.Ÿ*oŠЄьЙ !џС#5'>=іГƒŸ™ћ1`ш\Eі2@(ю#HŠS:3ЅЖm/EX Ќ˜‡Д2ЙZ KЋА"­эEФbœI+ݘ•йЉ1ћўЫzЅЉ‰†в4%IЌMџVд0rtsћЕUФЄ@6SСА’?Š” žЭ›RAЭœ4J‹т0ŸR§х[]јЃsїЮлпкœ}т Ў`ы BЄД†ЭUЌœ‹ћ†S:3ЅЖ<ˆЉIЧ›маЌ EХѕ ‚yЭБŒРЇЮ`…Žtюaўm%Ђƒ9ž Гц^се"n–Љ”U lгŒ лћDs,Sа1s Šy(Кѕ‰l{)ТJА`Х<Є•iЬеbX2X…im,"†уЫƒZ#Ь•451Š4MEI+ESРП5Œ0ї8_15ЉŒ•ќQЄ,ѕ#6J9iŠЂ8R}(p5yмX8›зф1cy\{\Ч,РЏD џКрС”Э]0lЎbэрYмG0œв™)mДхAЬЫ›1§HQ‰ Ђ,DQd,#шЉ­Аб‘Ю=ЬП­D Кє˜fU36lяГ’)шHЙUЬCб­OdлтŠ•`СŠyH+гˆNФ4А +вкXDб97Ѓdj0вдDч"оЎ(IDІЦ gˆ›зЫЙƒЈ­Rл$-љЃHй?Д‚”tдEqЄњње‹gФЉ‚M- -ЛрsЫ/бЖэƒ3Ÿ•”ШУ€‰3D€ЕqСpJgІДб–1}oЦTє#E%*ˆВtEБŒ KЄNДВ2:\ѓo+№Ц‡^ZЩ:Ћт сиЄ{яЫКЄмŠQ8`бЁeлKV‚+ц!­L#:Б’ŒДЖQtюОHŒ•№ˆŽ45QWDТл­—$с&9ИВe"-љƒЅьЖˆ„–rˆAВ[GvЅ€­FтTБЫЛрƒЁ‚v ˜˜k7„РpJgІДб–1:6ІЂŽYŠЪŠ!Іƒe„щCЛ•бсц˜Л‰HiжYgЧ&нћxЏ"SQG”Х(тќu|%лО@‡•`СŠyH+г`еbАЌЄЕ=АˆBЬЙѕvCijЂ7išжK’ˆЎьЪ9˜Cj ЦОщcњŠvsЩ,eЗEt Š”C,:VгЏЖ.ЌС цWГЫ7Ф 6WБvƒ ЇtfJmyЃcc*ъHeУL“Ђ’b‡XF˜9ДcЃ#{˜,l?’гЌГ*Хɘї>1q,SQG”-ЮCбФcйіR„•`СŠyH+г`еbА4ЄЕ=АˆBЬЙѕvCijЂ7išжK’ˆЎьЪ9˜Cj˜š•vsЩ,eЗEt œ”C Vг‘1"ЎŽЃsžНў8 љяšРY{йeѓЯл1`и\ХкЙC5NщЬ”6b™J•Хши˜Š:Rй0гм’: БŒDƒŒŽtюaўЅ‰Р}А-[Д4„c›вcšuVЅиРГyяЃc™Š:ЂlqŠ&ЫЕЋ^‘Ч4‘ЁuBЎb K-??oфИБdОk=Sв$д Œѓд“?еДy3ƒœ*ЙНЈk0БИr{_mЌWdq,IЭрЏBЋфќсHY‰.а-]ЖД{‡ŽофNЖФ€ЫVšз!ƒŽ7CnяsЏМ$!Ж‘L xФ|з Й’?ѕызявЇWiyiЇvрzGy“1Pѓ „то'ВFK‘ШЩ^1рЇk^argмЏoxЛгЂ~bР— јcOё‡O_цьЮ—элм9Є~b€ ˆbР!ЖawFкKк6ТбBк(*дN™гТ…0у!РyЪ†ŠP] ({ћ•L?Ѕц'З~Ѕ‚œз!Жљ•&кsНФƒ_Ї™EчKV,™=уyИъRƒ^h&X,RѓžлKЬЮQŸ16LYxvгV№шй-L zЭoƒ‡`иЌС}Kп@,ІцeЛ!Jђрe‚sCО†^[›>teˆ uрЉb†F[› lŠ.1D˜ЭiжвF‘’У€эЅ`Хж‰нК}‡п†Эў2erцц L&4{УІ(+ws\П^§утт †‡TЧмпMx5ш5|U1l2siUuе>}{sиP ˆљh7eНвOy­ЄPŠшAQ/DTcљђЯЊє‘r& `Ѕж‘4К9ŠЮ\ЏEъDЯd+еS ŠйПЂž“a†ˆ›T:Ь!Ьљ*lчЬчеŒ\ЇјbІWШЌм"—xЎtсMšЬ‡дЙД\ г+ѕnЅЛ•eP–•b$H>ecЇ>b€Уp”•C}#јK5ю_oщцj1(3 й0X;КЩp‚ ,ю– ЁђщЩRэ˜=}ъГГgСќ3П6en4pДџБп Moo2+`-МšІ Ж{V5ЄmZлœь№S|­xњ‚чЫЪєs4;кEчnei­ ’шMQ/DTc2Л<ТO(ЁQQЮФJ#itsŽФ\КЄNИ ЌTO‘њWфh˜!т&FО9„9_ЬжmБГ+xЮ n‘›=3s Њ•49ЉsiЙnтЖГ•КUL!ЉОЪJёЬЊщиЉцс€ч[їшвiЫЮЊ/.[о}Џ_їpЬ4+ѓит|ри$ХЩ­BW№d)‚l›6mжІe˜†Ьс+ѓ'OїHO‡ієєtЁХ ƒmbеDЄњžU IIiwшD68м‘ѕ^TDTV–~b”}тДKЃ`вZ#$б VEдQШŠr&VŠйnЎ‰и,:БR=Eъ_•у˜БМp ' FО4„aЬжƒb- №bP+ШE}.cP­ЄЩHiЙЎщЖ@ъV1…Єњ>,+Ї†7ЯQ:vъ#†t8єАac&wЛсLhMЉ2Sч7Фі )NnК‚чт::cФ ‘УR’S`YтљoоВљћkп7MiQеВэНб#-§;VM„ЛЯЊ†$7o6я…yрч§ЛЮ~~хыЏѕшбѓЫ/ПšљьLбЙ[™—юk`DoŠz!Ђ&+Ъ™№cДЂж‘ншbЕЩКЗеSЄўU9жuеsb`Ф ƒ‘/ Сsa‚[>т[УІМЈiЙЈЯe+PЙВ-AZЎ†{p[ŒуYъV1…ЄњКs_”•‚tи!Я ~]K:vъ#†t8яIК3kпўєіiYћВюov?/UfHФљ b“юARœЂUˆЪž/Eкк‹3g:yгкз]ЩџЄmнОsяћЛјМSЂCў‹(лzЙ­dуYе8Lп™pћ}ћŽЈ–­’WЎYyр№~ha‡oыЅЕF0HЂ[Ќ2Šл|™ыхLФ \ЦЂsƒ V+с]жИ­ž"ѕяYŽљв<&XБЕXЌХ№XtHыPЅ†^6К-Цc…gŽСњb&:ЋО(+ХHщиЉии |dрЪ5ЏСRєжІЯNžТТaЪR0ЌQКIq‚ОХcˆ"\ЭvyxŽ†ѕpŸО _ZР6сzзїў–ЏCа2ДАы`Жђt[ЩЦnеНѕƒmц-Yм­g7hщжЕлМC яЕ(Hk`DŸXН,_C-ыхLФ \ЦЂЂp}iMЬ ЗuѕЉЯrФШ—†0ф‹йZ)жbpхx,КH#—1e+ir' `‹]R+ЦУ•ЅxЏAА5…РЖ‚еЅzQ)ЫeЅјЙŽ!Дb;ХИЖцќБn3ŽŠŠKК#‰Х” ЫМa8Бcˆк№єzЕA№ќЎKEE,ŸзЖn„Џ†мzїјжж†FЗ›n+йиЊ"†KKNђНщэ;CczЇЮ Ї%Ї‰ Vdi­ ’шЋ‚хkЈХbНœ‰”ЫXtCЎ/­‰‚9сVЂ Ўž"ѕяYŽљв†|1[+ХZ Ў<Eiф2Іl%MюlБK*K‹ёˆšRЂ‚(лšB`˜ВRии)ŽиpцA?їТsCWЪ"9йМa8БcˆСaаnRНЂ šprеSТєАЮЁЖ•• ћ=ˆъ…ѕўЩ…tѕ”р PИЈeЅjефХm Д›8pБ>фjсйPO 3P ЫJеЖ=ˆ–ЂоЧТ5МљЎйpЭ”ђ ЕАЌTmлƒМНm!ГBФ1@ „7ОYŠ<ИuRJ+цkЗхDЊ\{mqш-Ёц olеЈ Н dˆK›!Ъ@-™0ОYŠBtŒ}Л–Ь_бф~h4нQž„РGt;|Ј@K‘ШЌСЋКŠйЉшђAЮсыТГбTА­шђ‹ўŽШ)ђw ?ёуЗ'Gє ў`sBKQАс!ˆb ж1`{)Т*—Hы@‰9ѓЖяoxQ У—)УІ>КЁЊT ЈРcЉряПR:ЄЅЄІAaYx(ˆ8zъB#R[Ќ@–2Чёƒ хAъ”эе=2•„aqс“ в.)6P––Q1xKЊТ6™ЁдЇ”1t\@BШС{3O[žBОiЮ‚uС'зсIIЛфЙ ЌЃREDvCn‚9)h4ЄУ7yRL‡ЗУІtмЁНА]Ью"ŠВвНўП4h—3эS )І#n‚25ўЩ4ApTљMљŽяn˜Xн Ж•И•ёƒєлKVЙ)4ВЌ№ъЅэлvРћвеKPiУ" nKХ€EешU‘кbBА”ЅЙHyР<иЊ{d. УNисг|ц.э’bS”Q”–TDѓ‰ёРmЅуТzЅрН™'Vl90Q0g!e›™HЛЄЙ`Є+ХЈ8BsD+nЬIq‡˜`ЄH9Сv1+ 0А )MfоЇ Q ›ц А~Žgokѓю; ЏС—1ЖъIKТ( Я(К80<(ЃтЖ2 цууQŒ зoц‰[[,Mi Ж]b.iЂŽEйл EoвЄ0ИЁ!ХЬЛ†а-Ž„ вD0`в}ЪnP €Фœ ‡ЧщŽ‘`А…M)lh7Ф­КЭСь"јZl/En+—ˆ9z\ZУJЉЗUO…FЖц!ЖRгч2цСVн#iIEсE‚eTмVFС|bК@—C+aBK Ф1l и;+’Ђ—ЕЪJ‘P“—юЈŒ$-`УО5Р'˜ЎFЅ›Šџёr R ю›Њ†˜aеS80i‚а Ў YЌ%(/ђ$Е•bЋЪњ'чœЙмл›Мј †Ў}{ЇДj1hшАќѓЙ<iЗЅЇ˜gјф!Аъ5<ЄЃ]r‚1ЦЙ "){cЦ‰љM>vf+ž&r&цEx`+O™фъ Ќ>ЙšK”Б”ЙŽы„qŸxHšмž X/пС'Ч(цжМ7Б@№Щ#bь‚bТ№ЄаЂD<Ў9qŽ;ЏqСлЅ+‰Y,В"­йУy‘Аa'd№ЩЯЬ0И+E95ЬЙЙjˆ˜Дz ‡‚4AІ GС0ˆЎА<˜­лђП­.ќб %U АJі‰3b [хv0TмЁ™4ХHq+ЄЃ†%+*8чjfrЬ8~ји™­xЄL*˜mЅщ[ЁЮT R ЊH™ЉљАNk†g%MnЎ|rŒbў0aАЂDАСчЇ‚œwyЛa…@ ‹EVЄЅ;8 Š6\ ЎІ(ЂЦ€97W сБИ ­žТ{AP$(GС0ˆЎА<˜­—šЌІ€a%M…9яђцХ/Б“ЖРLiQ"иА8?9QМ]ŠАB жЁKKwps‹lЌРP”QcРœKЋ†pфLVOu|š`C1УЏЦІгuЅ€­Fр–{У,ŠШ’?р_1Rbt1YˆЮК0ЂЁЮеф0oVќˆq-Ъ™—Іo‘:‹HЬjnSіa0stоb+M/ыAP)еlт3aЄE‰06МOœgСл tX!ыаЅЅ;И9VРЦP#Ф E95ЬЙДjˆ˜Дz Я,AQd ƒЈ†рСlеи*шZZ\ё~Ф@R‹‚ЁHSŒ”h%5 †hh…s)9œVќ@\ƒ•ˆD*[d^šОEъЬqЭ љЗ~QйJЪОЊ&Ц5РГ•ІнњCb\&KЉ6ЈlТŠ Œ я7фшзMo—"Ќˆuаввм+`cЈb†Ђˆц\Z5ФLZ=…g– Ј2†ATУ №`Жjl#2FФеqtюбГз4џ]ј†Ѕ~aQ0TЂ7iŠ‘­ЄЃ†С ­p.%Ч€гŠˆkА‘He‹ЬKгЗH9ЎфЉS9-[Д4ЋYIйWuТФшxЖвД[HŒЫd)еЕ€MsQ"Œ я7фшзЭЎWпМ чЙ~Эж–sЊ[УщЪЯЯ9nь™яђУЦМПwœQcžzђёЇš6o˜4!ŠЯkэјjџѕ7еvі9QvјVŸъЙс“ъжAЫW,++qТ%КЅЫ–vяаб eдэ;jœљЫVrђy­pн}N”яцЌЗžм]vёжЈкSнЙњѕыwщгЋДМДSЛNpе(TЧ2qз*цсДУчuТТrџѕQСГsд№Кр!‚Ф1@ ˜К@`Т)1@ ФЪ€ЗwаЁŽ•ЇВsкwыч›J­Аэ †ФЭЬ-ŠАЅЌ№<]с”Qч7рuэе[ Cн<ƒ†šYŠ–ЌXВpюBvя\€gd€УfН‰Ђ„„(loF*„l—,]2uЪTnŽ Пa ПŒќ4kf):}і_-+яѕ`ОктТ0ќЮ6+r—† QBBЖtдVQэ!№НАƒЇЖLі nј kg<ГЋf–ЂыЅз=˜ІdB !С€ОƒпH dА0`)2щбSС f˜+ВАu>љлERІХАnѓMФЊвZ L>EЋЪpкœљ лwHƒ7{ІГЋЏђ?i,шDmu~xэŸ-•nЊ§ЏлnЏЈ”кbаpЕ=ыУЌ>№В@y.m„j+хRЊХЋмрЬT6h№7pЁИe-Šђ?hюЫzсЅъqT\`.љІ(ˆгд€]ИЄsXгЄуnЌхuž0`цsЌјЅ Ÿ<_l_­@–W3В@NU ˆN3лܘC`ЖЩ•AЗBчВƒpЯц@†љУC€`ЮЭиЪJŠлwю„Чmѕ–nz  BЕ@8NiтzP+ЧۘY"ь“ƒфј/и^ŠЬEzДЂ`†К8ŠxіjБL‹Ш‘XuCZI…љ‡O1ѓ` Гdi,ІcЮкнжьqй?ДnѕЊ§{>ыжЕ{Цибћ~ВjхЊ§Ÿ~ж-НУЌљГ˜лJЙцA§yь№б'F™:х™~}ћƒІКќV@ХB&ЬЁEŠ žйІџЂЁtƒ‚tьl5Rч KмХ@ œfчЬƒ•уƒ-ЬX0Ж—"Бќ O+˜СЌКY‹U7мVR1`№Г§XђJBHV61иVЪЅИѕџњъuCG<цЈ;ф§ъМм–џ‘PaЖвOЬЁ8ЏФВFGŸЧТќsФXbЛTЖ?жђiŒГ;pи0€—–иС0ˆЖсRœо8ƒz&KчЦ–—"Д•ьDѓ \Йц5XŠокДёйЩSФ.ГŒс4kкjБ‹й–sП*лО@'-вƒЬАНТ‰Є@ŽХЊX%CЅЩЬX,юм XЉйc0С61иVЪЅ`>y;|kƒе(ѓЬѕоdVЪџ˜ Јp‡fsˆQdqєy Ь?WA:‡EQЖ?ж=ц/‘Lc ˜tрD† ŒMбdi‰ ƒh‹.ХщC1ЈЧВyюaќ`y)B[ЩN4‡k†Ю с*wTT\вU—D.c8Й‚g‚]Ь†йAkълK‘ДHV0У›X™‹U7АJ*†J'’7˜БXмЙAАRГЧ`‚mbА­”KС|ŠэњjєЪЊЬvСяŸаnЅќЙ€Šша c1Š,Ž>‚љч HчАЈ ЪvЧ›Ц0щР‰ ›Ђ Шв;б#\Šг‡bPeѓмУјСђR„Ж’С|аРСЯН№маС эцM ЇYгV‹]Ь†йe+–o•ƒєqЈX™п&Oо|Т€? ЈРW3ѓM>AH'4§ЭЖ?цžП1“‘ }j—i9"й №7чО9—о>нŠr-бЁi˜ІЙžХіm ~…UЋЪДј•ЩР8‡sŸWš rПFЁiьWz™sš{ 9!‚є] ) XФ1@ 5Т@^ Ћ.((1@ Ф@Э2`ћКš…Kб‰b€ ТZŠТoL)#b€ BŒZŠBlР.1@ сЧ-Eс7І”1@ !Ц-E!6`— ˆ№c€–Ђ№SЪˆ ˆc€–Ђ0‚K Ф@ј1@KQј)eD Ф@ˆ1@KQˆ С%ˆb ќ Ѕ(ќЦ”2"ˆb Ф Ѕ(ФŒрФ1~ аR~cJФ1b аRbFp‰b€?h) П1ЅŒˆb€1h) Б#ИФ1@ „Д…п˜RFФ1@ „Д…и€\b€ ТZŠТoL)#b€ BŒZŠBlР.1@ сЧ-Eс7І”1@ !Ц-E!6`— ˆ№c€–Ђ№SЪˆ ˆc Т.ох+rv}\`зŠє‰oшо!~єЈfRЧŽЭЫЫ“vQ#1@ 䉉‰-[$[no)bыPіёж&1р югДѓjФжЁЦI}‚|Ф€Я8›{|Y_ь-Ep>ыаЯ?/ѓ^rD X``Ш#[aюeT…ѓ!X‡š6•Ÿ0Еi› Х@BBbжžнж—"њ­(P#Cqˆb€ j~):vќи§-яЏWЏ‚АЦšƒRqA‰b€№'і.аxynЮЛЋ5чU‡уЮТяД›os–kїі|ЌгФ…MХцЌчg-xqAЇŽ:дE Ф1Ц xuVДѕtэ‡Мј-FЛюИ9Z+ПЎ§№]осЖј:}тtЇvіжЁ 9_ё XБ—-–H™ ˆ0fРЋЅШЁ%7ˆŽгтoжZб% hхЅZI™uЪЎ—^зМ:7Г*(4ЏTМ‚  ˆb 8№j)‚Ž^,ЩЙX’ї]ЩхK`Гь?ZdaоžIніŒяОsк“‡{cб—gфŸ8 •K2†ѓheg mZЗЩ§g.SкњЮV&@ Д‹–Ђ o_ДpQ“п5i”иhЬи1e• !hЎпИЬЁНc‡ŽЇŽЗmв`Г^їЮy,P[ћЪкћСќЎF'O4у,ȘŸ1<zСЯЧ†_+†Ижap$Ф1@ H№j)j|[tLМЕ‚R­р N’рЗЂВˆшГ_~|ђуї‹l(кПсlцВœwWэx*mEч:fp†ьDЁcчŽG…Э‚+3&M`+ Д@Лh(šАіЫVdŸШоїёОГ_u8sЬсњG>нЗmћ6ИУ§с~иџгНŸnл ›пtы§№д уИкЁ#‡>йјфб“…—/-ZВˆЗ3aаa#GŒ<{њ,јorW“9ЯM‡v[0 i“ ˆb@dРЋЅ5Žƒwtl”–ЇuNˆNKˆNгвDЛbмЄ•]Щƒ;7iкњi“те.­н‘#G@aчЛ;5GдŽ];@>r№HчэVаЕaукysцХз‹ŒŽœ>yњЎї\gTа5gС"Н=2NkОџїѕ9ѓц№ЭуЧŽqЗ3џ23Іn Мg>?oУц М {?олВUKpў'LšАsяƒлTРъS#1@ ФcРЋ_iЮ~WЂџA­ІŸ щžJbZœ' ?#нІХ;єоœB­ кул]РЋГЂф„hИmС)мА—щN~Їэ8WВ%ЗЇЌ|-ыэиwZБS+ўAoQП`Еhpч{vэtD9RлЅ––—юйЛчЮ;яdЋˆТЖюЏžњћ)v•OџМЈ_єГѕЪЯЯgњљѓС›СіБ }|шй“gСї7чП1џ˜ФєН‡aˆK›AЫ@Ї.‚#B‘Џ–ЂмяJ ~(3ŸDGtђmбщ б§яŒОї6§GЃЮ њтфќvЖP;ћƒy“хžŸЎЛNš5ѓ}џЊ№9щйIuьj6ЛЅю-љч]‹є6|кФёњrRЎСЭpч‚йDн2ћЙйХ/?мз \ZZ ?AСŠї/L˜:їњїL1@ ЕŠЏ–"эПZч•пцŒˆ>њ] œ ИT’[XrйЉ/EIuДžЗk§яд2’Дž ДњuЂЁбэ+55Ўѕье4{іш rъCЉfЋбџ=:-=нУНЃў<ЊyJыєnєыzOzЊKч.fuKы”жЕmuяїЦХЦŸ8Э МlщВ™гgжKЈзЇWя”RxЏg06CЮюb€ j'7$v§ра9……WѓЗ wsљЛkп,ЩуPKЪђЯЭ;Д;яяŸ—]НXTј=ќЁ+œ*С/Fp;ќ\s“–ѓƒц,е†њ9Y†%ЎМ!0‚Ф€ЧЁ~uЎјƒЬtоТ„­™[џ8Tј­.аT^д5@ђї&§Vфo†ЩПмўV—™рqЈ§њіW{ыГ67юж„KЧwX8UQ{‚ошШ„Љ№fч/e%ХџЬ)ј*ЇјлЏ/џуЫМoўхќ./1JЋчнn=‘1@ Ф@-dРKQuк"ЃcюK…wѕfк"ˆb€ ф xї[‘мgˆЕвеЙ0‚‚э‘љьVS_ёђŠŒ‘›{lш6ќЩукWVxь?l i) ›ЁЄDˆ_2Р™_дЪЪЪ–ПМ|цД™О$ЈК/ЗKNuѕЊ-јћњ—ўg9 ЌjЊ•-EЕrи)щ0bРэAа­‚” ™/ѕуqЃuињ#(яnoЄсВ>ЬъдЖ-џKvЉŽЂб зl@е6Ѕmжž,€каEKQmeЪ‘АЭ@Ј<2ыцѕ‡>ћxпў}№aыцЊч~ёœ?к§Q—nНљfА Ню ƒ U€ёдќRl—ЄљXљ*Ф•I jœ˜БЂПпѕьљŠБi ŸL` Б'йЏ}u­^RЙKЙТHvОєсєКЋrmю sсЁјpFЖЬ9|J§CЛˆ+Kѕ™&Р”ЭйAћІЗпšwсмK.ўќ$МЯ_8›МЫ,˜‘<1ъ‰)“Ї|§Џ+л2?8ђ…ўgёЕhсмТЋ…№˜џOіўфр'МKš&ыЏ—ЙfэМZŠЈŠЋнIsрГCїƒКG№Erти1Ќє‘]'ЄO ` Ь™]љьљ'2N ЯžѕŸ>m:dАh‚=œ~УЦ ѓžw=к зcJўйa]є ВBп )ЭžИЬgš |џяя VЎЎ]:А™Й9žСЯЦј3пЩ”š`QQQ— .\+ˆoПpўBƒк†w2љ“ўС9яЕž&7ЉU‚WWЯђЧЁ:+‹-еŽ\*IМY+cU\+'‡[6Cх’ДлDЌ(ЌZЙjфcзОšь,qОДєЅQc†Џп ЙДmХщfјBLŸ=/j*!зИDM.cЇП№эx˜=Wc‚ТПAгЎО4Л[~љ ЈmЦV#nљх-ц( 4€*hАrАЎ ј- в‡ё›=ˆ-ы^]ЗєЏKч.˜wsмќgЇЖы$іъœT>=]$GAKС•|@(:Љ…ВWgEРUq­КFŒ_ цk§†ѕ№аq8LР7ВщSЇійqоE1YУј†еЦяzџ/"4~S5<ЗЦь‡Е4mкtЭк5gў~fў‹ѓЧ>­зЕ_:'•…ЩQЄy,;чфD'ЕPіj)Ђ*ЎтЕlХЕ`щФ‚‹u-Z e–ЄJдH xЭ€їЧN?xарЉ3ІТ œŽЬ}оѕ‹‹тIљтї6žІo€Эѕ BяОœПp`€7hP€MxDђЛяНЫлћшЋ?ŒџZ1М?lВЎпозrЭ+k`5W№M‘ыРГџѕЪUoJџSЪе˜аїс чА”]+ž=c*яХвРцСCœЙч№МZŠ€ЊтЪч­kСЙgrсiп‹.цц$~bРГGШ‹`А‡г3ОЩ]MкwhпїеџU}fbїIљ˜ОЖˆG”‡ вКE›іiэснКUЈЗ)і29§їщф'+ž™wk\Ћф{с}{§лa“Љ-YДф§оo|Чѕще5Ѕm їc@ЫЦАЧ6JЈ7ыЙYЏќэЎЦ„iЇСўяmvяCi­ZЗ}ˆїbiЊ/Lяd|д/7Ќ%‚WOц^дђF”Хƒпр‡"VХф-чJzBЩ"x@weWЈž7\іdnјЂФ~Ь„/#=ињѓc_vьмqжДYPХukцж6-яџфГCpEKnТ5ЈWэВx„ЦЊчдАЭjэхЬАЏ+Šяёvѓ…rЉ †ˆœЩpџњиЇFЎzuœщ›{ЉХЬ=™›sBOццTирС?й'ГзЌZcЫ*Ъ№8Ђж4ўФЈФђaˆрz27Tq…ГTјЙЊИТ ЊИц§ ,/юe€*ЎP.'XЈŠKmWq}qё‹жЋИйѕі‹Ћіс‹ ћЅЋт:{жь э7РOЃp!тПюј/ЉOИlЦЮ];с|hнДIYЄFbР/ РI‰_ќzэ4WGЏsђФWшЈŠЋнbВ№g€ѓfЭ|їwщ|Ш“йJ6Ф1І xЕQWЛХdЇ<;хѓ.ДHiWџи‹пБІŒв"ˆbР=^§VфrOU\нѓL^1@ПqњшЗ"N 5Ш@p§Vф"‚ЊИжрŒ аФ1@ „>^=mAš>Uq•вBФ1@ о§V„y ЉvщsБB*K Ф@h3@KQhЁ'ˆb №фн 7,ђ>ѓŸvоpƒƒ>‰+ ш§” cp7&ЫN<Х‡GЯРгkv|Д#Ъ5zфшQc\XOœZЕr)<џ0ъцЈ;MџЫx"Ђ™Ј9OZƒіŒсу'Ž7+Xє#Хоrџ™;єOC??є9ц‡Ва<5Ќ]D*>Г[žХМТXЎ™Г"vєZa5ЂObР- @/p˜цGjЎ6}цt‡Уqђ‹“‡ўњыЏЗОуz<{<ќймГ‡їvФЦТусЙ Ќ”FЕтJБAћбz:~˜­йжЮё‡ŠO+<ѓЄТ[№фЌШ{Fи ФќtHOмјzЯј‘>9йђї№ѓЯуƒ ЧF1р–ЛvР:Ф +РВ4ќёс§жŸЯ‡gЖ№<-8mjœдиьŠ—F….(:с|ѓГнЌј1{ц-ћ>§dр ЁАщЅюPBХЇžХМТXіj)j›}ч/ПŠНIч'*ЂДА4 „sЅwњЎЕš2~Vj]:j\VццГjъ%ˆo–7… YвЧУ[)*‚Сќˆ:ефrэр‘ЯVМ\­о6(ќ@…ЩвОoxзрƒХ'ї`эеBTnГOЛ­ѓЬ“ WСЛЅЈМєыB'М/џр,*­XЪЕлo.ўыћ&|мсіЛнў1\Фƒїmб—EљYœX@;|Т;//Ѓљ}ЎŠПУŸИ—щC Д‹ЖЂ oiqZбїЃЮё;оэ Џxц„gюѓŸџ3ўlnќ(5њЯїцг7sr2šЗpХЕщ3“™љ›zjџ—{u w7ŽЭњАПѓЧё`˜ЕЇџmЗыў­УнЅЅЎпАёьwп9KŠœ/ЬЯiжд…Aд!™№ №+<ѕљыМЏПЬ>џЋјЖimЙ[x<ќШЊ2%VJЃ‚7З~xDƒ№ёОгRгxЃ5?Ѕ\ПК o ŸyЎžoxnyЕнЗ‰ъ•Š Ѕ№ж- ЎдEE\ŒНщм§ПМtOнsїмяЏўPя№_oрђГ"v_|Т;kO~Чzѕ­Ф_ЧЎXм‰­(аэмб„ЕЯ™—–|ќНЩыoЉПЂЈD[КЈjŠЗыжakи[6хМП­_—Ю iщњц{яцЌZYUЋЊ]Zтo~ЗцПюXQ?оБќЅ*sцћŽ~K–Н%~EлVф§ЋјххКЁ-Ьјэ˜2ЙйЯЊЅ&*L xЩРФЩѕњЊeePleё ѓ&>=‘9T<žп'­(ЪuЌј‘Іw™Ÿ;{Ўх}-еx X*м№ eh †ЫјqЃzєъЯєБvшu‹ ГХк§эSС3KЖі|zѕ[œФТэЂ7kк5Эq“ж„Š—ѓ?Qйп•jКяЈИgiy)ќЄЄiU_^јY‘Ы тП>Ъ:(щЅХ'œф,+іЇЦЫџчdЛД„з7цŠjf9уБfэ;ЏЯћ—ўЃЫ3ВўљїŒŒсЛ™куУВрd8™6#ѕёТц”TюjЬиЌя.щj ьл=dєяч] 4NЊ*З5і™§пцW;Kуš \‡ ьŒЊјZYЋДѕ†.к$<`€‚™Р~љHIIщкЅыЕЎ=˜ђрыolJИ#y†ЧУƒ‡чОљцCuJ(Z—uQAўЎШ|ћД[ёjflЧkлЖmХёњQ?НКѕzjдSџњћ)ЈUКy­UЌ]їUљТАaЖX{Ѕ?§јДТГˆ!ŒeЏ–Ђѓ…šџ4НЬ;Мџ ЕђЂД˜Š{ъюОY‹бoЉƒzzQ—сђ(TОФ;ш*лДwч­XЂŸp<:Ай№Y“ЇД„ЅЈeЫФƒГИŽTˆЏyця’ПeЖPRЂЏ4е6…дџqкuяР?ўYо Q:<”јтМдfЭуѕŸЕ№—†СЮЈрœoЪЄф7жєHnMЋ‘кДЭџе]Д„[Зйнлb#ШReІ#vŸ2 о[б\T6Ј‰]ЂЬд>нџiћvэЙ‰Yuuъв о\ X;(pW\рVLРlБvћџЯфaП)эчкф6§W“3…pЗBHEхЅ—~ар"{(,§A‹Н)Ъ чCp№’žСЯ'ЙчŠџЉqY™3ѓГ™бВя€ЦаТVСк(\)KiНо›[бюўm,[юўMlСЕ2C€›zŽŸ˜ѕю{y€– хх mСа+š{tкDз5 CDк$ҘНя‘1"ŒЄд<`РЋпŠО†Лє“ ­~”жЈЎv_НЈіѕЂюˆƒпŠДцЗEХFш72|]ZzжЇˆRиф/ў[oaТюЌмE гпxKП"Ÿp’-и,..ƒХƒЗЏY{tЭЋщpsмq7#Р МЫЂАlQ:мŒoЖОcАrDjNЇVrн !6НЎŸЗБ—0ЖМнSП5уџj‰ БѓЄ8\PщŒў'j №А~ЕАЖфLyКcРЋЅшмЕИѓзєП(‚ЃCWJџqM+(ерV:xХGi)ѕЂке‹ъв Њ5,K7Й?+ЋНЛѓтыFЎ{S_ р.yэz?OwW§ЕќŽž82œ§т=гg=ђyоО‡ќ\2~г=7Н#YНЊ;0n}њyќТєЭљQEХЮЩSŽКG§9kёТдŸЫЦCˆO?ЏZ<<€ёюЎмM{Ю“йCтoь;Рѕ,CDк$ˆb V1рIWMkT#чmбEwнt).ъRдMЅЭ З0РУр†:ъУgDдз?РRщKЇ3˜ЁєЗЂъ>ЗKЛ.p!)’MрqЈ_+ў Гъ””9иšЙž[гДi3›ўМR?u&~Z(ШЏ™ЛЉŠЋWƒGЦ>b (ЋИjŽяJъЇезŠšWЄщМэџнђ‹ТИ›Šт" Ѓn*„щœ+ХqЄПё^ˆb€ jТ8>ЫлёнџЋo…П :+RрЄ.b€ ˆ0реoEу ЊГ"К:чё8’!1@ >a f–"v}ж№Щt''Ф1œ xrŽпКцMJ?џЌ[г'1`…MЃ[ НйлШ–vjцЌ(иY!|Ф1@ d ц—"ўˆ*?e ŠППх§ўŽтј „фAdB Ф€ї xrŽG=№ђмœwWkЮЋЧ/œ…пi7пšЛЗчc&.ф:5.Ьz~ж‚tъиЉЦ‘b€ ˆ)^э_=]ћ!/>B‹бЎ;nŽжЪЏk?|—wxЇ4’_gЇOœюдЮо:Є№цз, Ю=ƒVьe№F›Ф1@ -^-E№<…фбёqZќЭZЂC+њЁ­МT+1>QДѓП^z?ŽОa,4<“{,qР0P b€ l1реR‘Ž^,ЩЙX’ї]ЩхK`Гь?ZdaоžIніŒяОsк“‡{cб—gфŸ8 W‘@^ы7ЎoгњўF‰ѕКwюЕш]ZхкŒi›мно3ІЭрц>=аБCGP“­›ѕЋр$€}2A "vЕiнFЏФUёкњŽыŽ,hvЬ„З/ZИЈЩяš4Jl%Ж О2kчШл@;@:uќИm“›‰TЦЕЕЏЌНЬяjеЬx"мyСХ|( НрgШcCŠЏC—ˆœkJa№^ˆb€QМZŠпo§)Ј?шх\сЗЂВˆшГ_~|ђуї‹l(кПсlцВœwWэx*mEч:GGŽйЖ§ƒГЙпtыљ№ИgЧ1ЕЙ ч^Кpщ№ч'с}ўТyиdэOŒzbЪф)_џыЪЖЬŽ|qйI@ХЩРCБЋcчŽGщ:…в–3&M`+ Д@Лh%šАіЫVdŸШоїёОГ_…JsЬсњG>нЗmћЖГЙgюї№€§?нћщЖ­АљMЗоOрJ”9єЩўУ'ž,М|iб’Eмœ ƒ† ƒъЮgOŸџMюj2чЙщаn †С!mФ1Z xЕAЊур хђуДЮ бi бЉqZZƒh 7ieWђрŽx іƒ~к$}Э™='ОІ‹Ьx"уєБcL'ssцЬччХдїМччeО“ЩкЃЂЂ.\.ИVп ~с|їGДKkk8йљюNЭЕcз<вЙC;цћмАqэМ9ѓt„б‘г'Oпѕ^епИЬYАШ…|xЦїџО>g^e"У3ŽW&ngўe&K2кАyƒ!”oiйЊ%Єў'LšАsяƒлTРъS#1@ ЁТ€Wwа§ЎфlEЂp2TЄ{*‰uh pž2ќŒt›Џ—жгr Е‚ђhэ?шRSсFƒЃёѕЪыx .$$ИJ '4HИіэІГюеuKџКtю‚Йq7ЧЭqvЊх[RLљь$pВqыЦWў?{_^E‘эпя{ј&:lCP„$"EdƒlъcтШHFQPУАЊlƒ,*њEќС|.Qp@e•E–АЃbт  „ ’|№>џПОuoЅR]еЗћюЙ9§няцTѕЉSЇ~е7ЇЋКК~K—/љЫа$япЛsбѓ‹˜eнwaў)‘}Y|ђ$zŽтb’7љЪ†№ъŽ:њдмЇіоwё_ЭLMŸиИСM‘ї`GфИo#5А" љЗч ‰[“БjЮ|\„!Lгх_0_6CHѓ6˜ЌENT%eЅјvu4mмД  €§/(,hаИ)+оІM›+W@ЦCЃёрр‡fчš4oОёУѕ œMП#§йчŸнИicѓцЭ‘ooЁСЕMї|ј1F?іj6gЋ4фZoCИўƒ<8gіœе=VcT„iУfз5уЇD!x7Dk$Œ@›Д–бbˆ€ЯЈ=`ЯЉ !Г5A—їSiб…RŒ|Rom”xgrтНЭл62н•l.Ћ+ПdфЙŒкW˜aЩе1єЗCч<5Я№ё™6s’Ќ8/`џЫ.yxњ Ѓaƒ†fІПЃoяОSgЯњнапAпSŸ˜кГw_k!ЩкШ‡FNŸ2 с•b™АБЯ1т9 тm/RVV†GPˆˆXП0yкdžr7ИeB€ˆ)‚ EFГЎљ—•зJмћSщКяKЗџXšW\zКм E-Џ4^cмлмевиФИњЪDdК:&Oœ\џWѕЛмкŸkЎОIVќюЛю~шСaЉЩIГŸšНќ–ГЬБл§Ююlе™M-щщщ˜ш8h t9НgКU_В–ѕXVЛЮ]‡н78ѕњЄ1Ycр€Еˆ}NзЮ]{vывЖCлњѕъOš2]R~qЩ‹ГfЬJJNКgарЮ:ѓГЙ\рI B 6„ХѕчŸ_Ќв˜вŠ‚c{ѓw}šџХчџ,<_|/КbЈ„'FXЮ€ЧEuЏ0Ž€ХЕЬШмхйЕJсјO $АхpёпдАЕ0ѓОьиaq [+Щ0!?`hУЦO3†оkпЄ{VцеџUђћжЙЊ(­&жNю˜Ž_T”–}sЄшЋ#%?œ8§ѕќ“п•џ”ŸRЧИКykeiЪ$B€Јс„"U…Аvbнф[вёЉšM)B€ B@@pЯŠд6)З 4;WJ„!`A€B‘Ъ B€ˆ,Š"‹7еF„!`A€B‘Ъ B€ˆ,Ё_ЖржчkkКѕщчьЮ=ъSgЮFцщos›J#аиЗЗVРЈ`ЭDP…vу BQhY\Ѓўyі3Г—­x;“ткŠК35ѓњІV„@ЭD Ј КаВИFf,bгЭр{эдбŒC8Ђю sƒО B€Ј ŠА—OьГИ:яХšЦїъв$B ЌŠрYHX\Y 1'Ц5ЏЋ 0НЖяд~еыЋa%uЭšБўУѕ>]ЃЈАЈ}ЛіиёкЊЩu АкёЭvЩ•ЏЎDuIMМюYЉTэљa•$­bе$„!PУ*…ŠХекJ^WІ†ˆ2шоAЯ=ћ\ц™ШБ’КŽŸ0ў…Х/p›‹–,Ъ“ўЋ&зРfф№ЭёдЁУ‡ЖlмrІаЄˆU2КкѓУ*IZEћ$„!PУ*ЛАИZћ@Щы 5Œ–РQєЮџОгЇwVЪJъ ŠМ„ЋиРЬрHЭ|а ZVMkНЪœгgpN<%•Њ=?ЌC’Veе”&JЮ•цу–сŠ3E%EFi‰ёaЊЬ„€‚ E`qнV`~N_0Iѓr‹K‹ЪLо<Ют:А™‘бмЄs­›рŽ$‚џыy]aљх_~џpАчёfдuыg[{єъYВэŸmdљў8с…OC^ИxсФq9žR“лБDвXsA—в“Ѕ//5z”в‹ -3›ЃFŽZЙ|Љв~МfŘ;Ќ,ЎJФз|АцžŒ{ъе­7ђб‘LAIъŠ1г3 žYќЬќ§{їПИиKiЁдTжb“ЉЄREЈГс‡uHвjS) !GзПБчџЭ€A№˜`нMнKр~,-ЯЫ/Ъл•џЋ'бИДюПHИЊaндпиЎ^Jлк‰PGfmаН'дЯa]ƒхАєэйsgcROfјSщѓ/Нќв'}>/g§yжн§юЮ|pЛ_EБc9ЈPW €№‹+8[q@{˜[Л71ЧIр(Ъ-3ЩХAс жЂр PжdЏЙ?уžђЫх`ДƒApЊNљг”фfЩ9Љ+ф у'<ќаУ/Пє2ўwАCЇщ=эьct5їщф&ЩyЧѓ^|щEпЁ(у‡Х 2у‡ЭzФt‡Hв:oСB–IпQ@ Ђ|УЂ љ;?BЄЉ‡ TЫИКŽбчЏ#л2J.{фЫЅц8пg~*9ѓuбFЙa†Ј„„_еmv}Нэ[іќMн&)оТqє7ѕx\jг П ЪВxSЂЯ}”Ї"“щаээ;Ж/{eЩŽћъ\Ug@я>3ў<ЏnƒК’‡ўБЁOЗnЩс|;ЦЛuюЖaу†§HЕЧkвї:АіХѕфЗF­‹`q5~2‰ђR Ютzѓ•^Ѓљџ6 .%–—›swСˆFяЏ§xHЦЬьgЫbЄЎп}ћэѕ­лpRWд‚[з­[d Щр5ъ4Й‚ёУf0КžКОUЋ‚ыˆ‚U_r€)[[‡ќUЋWЅп‘Ži1ќŠgL›с‘h™ЩћьПЙнЭ•љ—)OСУріэвV.Џt•zЊИ-5%ЕwЏоGїхdПŸ}[w$“њпе;я›nnцВM#п;6vн7їўПmЗNxщъ!“Я_зkях”u…˜юˆ(‹kі;йЧчq"ю{‘шџL00(Ч1fиъ+П7жџhф§лЈ`3rЖ…+|gЗџh—Ьh„˜T/СЈї+пдžO!ўўZпЉ`їOјfšЌ|НAСп‚`ЪžBцдŸюѕ†Х/.>іѕБ­›ЗкшєЇ™ћLAњVъKА"жжIІ0YзБKG)ЩТТТЦѓќХ чџГј№оУ[6эоВs Я‡АчГ­xМ›—‹YœпЛїГMŸсљBnоЩ~ƒ‡L›ьPaАрO~3№7МxуЄdTФ“q/ќGJпБЗ˜W\TTќЯ‚5#Н7ђКfїКсрОC?џь] S‹n>ю/Z\пbйђeтBЛшКDЕ‰@ц}й_}_ђё{wJvВп{ЗUЫVmкЗЈ’†/ЙbŸч:ш`Фгъ*ЃхUX№щ+цћ‹'IжзЛТHї u?Wїл&c\uŸ Гn‡ŠŸћЧ с›oОa}<Јou]3ŒѕW`имжЕ§[oЎMОЮ|X[rЎЄgя.cjGП8ЪWŸJЅXY|Уђ-n9і…YKьжОЗVzЃГЯ-H‚N_r@з:n ябxxVУJў@Ѓœпр3.Ђлx{ЄcЧŽJБzV‰'Ћ{1Яž3ћ§wпЧ^.ЉзЇžШ?сMЦиПлЁ–””lијiЦа{эПge^§_%џИo]pЯŠь+‰вYvDЉrЊ6FИкїQЦГ*Сѓ-8‹L<кSl~ФУŒJlmNoЯЦЗЌ{ЇBl5{НЁ2GјТуPхY„зžšћдОУћ.ўыЂ™с+rъ‡SX $)ли—4YвЙОMыАє|ќ˜бЫ^}Э‡PK“&MŠЮ5nт™nћ–0Hў‹U  ˜М(ŒШ ŽŒŸ:~Э[k*уІ1Я "eу23tq 5*Ю№-рФж,`СgЪUЦеьƒй6s‰ЖgyЗgЈ9Bђ5Ÿ…(<ўLё-УёЁП&xНЃмџyЯШЩМо€Gюс\9yќ$fяйбєкІ…RYЗінъKе!‰ЗуG?bЦ!нДJ‡іrц№‚Іл^З­ўs5€ЁфC[і—e<Ж1ЭœƒG:мкAW*ўђ)Х_ŸR‹ќ#€'@ь!fCj_a>bёЉq}Уќ\e~02Ÿ yB”Ъ"VЊ“ё›зАACмХѓіБзЬџХ— <ŠЧ+ќ”N_o˜Њ@ERf')ХqчRгќ р›•дp‡~й3BТ‹Gx9ŸњfR<Ьљ=s6ЏМЂœ…3ёdќЫcџ8ЖћнyР‚вvЛтѕ†ды“Цdqђп“Но”œtЯ С;tцM7)­EZ^=№єшъkЏfљnэыє%ЗyЅ’№фO~›ЊcчŽh ;№4KвЙѓПюмЙs' MŸ2Н~НњmonлГ{—ЎнzJЪ~“лvх<і‡Ч|Еyƒ+ŒиЙѓЮ>ђУQПжЊЏBЕ\Ж€nУаОњ‚NžЛE јe ы3SА=•ЙЛŽ„џ.Š8фqK Гє•ЅЇђO5LjИ{чnўжХєьжe‹'ЧOйN1z=ї(R‰Ш!` Жz˜нCaјт‰LЕ<‘ЩЗцлtљТяcлOfXТЭжЭB‚Г†cqT>рОфглыйХЇъе*Хf Ц™ЏЭ-V?Я,h–HLЈџЋКзнXяWЭa'‰ѕЇДJjsЋy’B Ц д КрY\эљO•{xАЎйЕgз–mЛБйFёщПАик_JЮVƒоMJЮœЩ”‘§vхˆйoЏz_&"“џВоЈАњI9‘AР|…ˆ/ЮіФФіA,СkC6хтsЮШ?gЋЬќЦлћВ˜5lцЭBїйеU”žЇuwЎ$Ц?A…ЂрY\эљO•”ЉЌO№ ‹FиijжŽRrЖк-`л%/<‹PєЗхЏ<§ь ь”УВЂ’cё!œ4Ѓ’'~ † 8!Aƒf|$1Т7ІѕЬu ОАФ4Я{жG˜ВaАЧK,>yЃNАб~y‚Y(yжS`гѓРЫГ—Ы l(N!P3j‚,ЎEРЧlВИок(ёЮфФ{›'Жmdў†яJ6oю№CХt9Ір17т§Y`eќЇ`>ХЦкГw_ІЅлУgН;m””@>dЈХЊЩюjnOтљЕsvWƒЂŒеŠ‹ЫWНО oŠ€ˆШЏ3bY’c)1‡+џы ‚Т({uѓOу+Э?˜vЛыѓ:ЧwчFцГѓY 3žbЬ b &њ№ќЩ|хљф›Чц7ђё8 ЅЪЬтаз§FDHЫ ј#кБ‘Ѕ7џ™&жяŒЫV№ сЙ)/&…ЬсиЌљSЦУц7ќ”((mBk”2Ьє§ДЧТ%V7š™УЭL| №} DƒСз‹5S0ЈГУfЏZ—ЯЊ‘MИjr;Е6 Ђ ˆMˆМдЈШ‹Ћ џ)о#У%oЅLL];wХТ6sн {'M™nNЩйjcPВ0цcћгcяНcЎtb‡ѓВОє7№‡рrеёŠд†Ъˆх9ѕй8№Œб "–aрХЃУЬАdЦЯДpO†й9ŒД œGкѓx‰•ewK˜йЎŒC(ѕхX2Ў<њмнG™я$ГШЗkЇН2лЪџsEЕГf€Иі№ўУШœ7g_яъ„іE”6cFм?lЮМчА іќйѓ`MekhЧŒzЈпР!Œ†юЅх/сЧјсGŠЮ@І^пЛ};шььэшЖtбхsm|г•ех‡еfі;ЋvэиМuлVд’ѕШУй))|Ѕ1Џ7bB(6ў)­(8Ж7зЇљ_|^ёЯТѓХg ?с‹{ILуqžущ.ž§fюњ9b ЃŠт р7ўйщх+2c‰№_^ -lі Ћц0^A8Сљ˜ЧЇ/){c‰hі4qЋЗŸ3к60Ÿ•"œ Fx\„ =МъйЬСу(|ЪЬр„чOШiхћЗS8nЛЎnrЫLайlќƒP$ўФqˆНф€вШ‡GfПWЙадƒI>њ(ŠЩ&І.юИу~˜і]…ШmлzQЫЈ3‡н?BŠыЂЩUюž.Ÿ+HB,лЬкџё)Г;uщŸA˜Д`сkŸJЭсЩикјЧы–‡Х5ЙczК']QZRєЭ‘ЂЏŽ”ќpтєзђO~WўS>ж]нМ5o „@„@hСPa~Ф шAР˜dЎхС пСI*™ђѓНXГˆїРS"Ш1ќЂы—_~щѓЕђЏŽіДRЃЊДsлЦж­ZЗoзўм…sя8ящy,д 0/љzxдWМКЩЊхф”лzэЮ=;–О\IўЭ,Jv0хXvсl“”У‡ wњбхЫnyвБlxГv‚ВO• GІяw:лЕы&п’ŽOшL’%B 4рНљяёС3Efђ‹ѓрф[}€ч=ьРN6ЌБжmy‹XU‘у3(žєF%Я)&WЦ!ГTЅD –YЈ˜1mъEЬ(ћзYЩаžЮš1 ДЇRОMђTбY ЁЖl5IИ1щ‡9@lк yЦŸgм3Ј/шѕ ЗИОщš>Ж1@Н9‡ršЗК‘П/ЯŒKvјˆOГцܘ†љУщ3ЭК|Ѕ‡1nѓьП.r œЕєЉВQaЪ jйB˜|"Г„@ШРT>ь-W3ќxо2G$XwС|+ Ьеž•˜:Уя<,.јЗQТ+ˆ[ј Nј‚=l^ŽyЫЦU,Ў Ч;Ь‚ S3O1ЩlL#Ќ OОY;6Љ‹Бхs?Хч‹M*„]R›І6hм”5‚}ƒіtФУ–-_ЦпВЯъф†ПќbFB8‡ж}ИŽiNš0iшo‡ƒUHъ,VяЖэлzѕш%кДБƒН`–ОВrеъUЂ>d]>W‹}›РдPЬa й;yСїkˆ|ЭT#!AМqoэАJ=Џ!сљ "†IxlƒУ NeоY5,1(ПТЬg“{цi<ў„…:цl ВЩ7D&Ф$йw•1У8фЇ™і=ё^aoo–ŒoD О]4ж,tыоћкSŒ‡^{]K{Ъ5%сЦ;Š9l;rvьиБъЕU IЅ^Ÿ*Њq9рz7oн<{цl—v<З'МLЅ Юwц›К,і1Ќ4/H!Зyу79z„=+‚€ЄP[ЄEEqЊ/КАјQЂ[˜РLlЪЮм=$ЩhыљДj`nФ€EМьTn.6>-4ў^`|Z`lћб8|ЦР^Ј?-6,н†2Ъar;žz TЖи›дмš{~cxdž•ЪUZˆ–4хё)&ПjEХЦMŸцщ)šТ<БЁ=Х~{o‡ †СAрР]ŸўоgBјŸˆgEИOЧgё‹‹Х‘мfРѕЂЎяsПяt‹љЌ‡Ю–T`jнe~“&d t/гзхуЌ_пteuљсЖ9xшя,œnХТАћ†Б6Fх[ѓ›ˆŠ/T)!fЄ№,f˜uzцЧpж|yШуdœe+…i:ŒиЫ­ь† Срm!lТЭŽzОЕнxgЈЄР\;ŠЄEБmG УkgіXYЦ=ЗёŠ.%FwСџ—ЪіtЄsчЮ}яю‹ѕЗwО§oЏП…MI˜л =…кS–ФїЩ“'ёъ:O2AikчŠ~Шяв­KYy{Х”_YњЪД'&.\drЭм~{G$%kH\/–Šuыж^uvѕRкяО8ŠwлA>yтdцƒ._єАКиЬМ?Г(?ПGїpл›Eq%7ХbnБH&Т€@№‹ЙЗHЉ‡ЊN!Ђ`pƒЉЖ[Џёz_Eƒсљ›ыCфРn f|Т›Њиš:žI?ss ЯaZ№<[т!НlФ^oРI(`фdFЉZЦт#fqsг б.1уэЏL)ќ‡Эbю№WfNŸйЊUЋЬ2ЃS}Мд[‹Й‰Х5^ЎЋјo‡јQ5сžG І"*›В/БГˆ[860~ТC#s‹ElX—`ю8Ч#ž3aН @™[УфжG˜u!“Нu‡gNžp…hФтЇŠRЯ7}…M›7aЫуА˜&ЃA д]јX\С6Дфх%ћvяЋsU>Нћ`лlО]ЉЙЖrоœ;w4ИЊСД™гЌяЧ­№ирm-~žшТ’тY)ЩГNž†H,’Бщ8ЏЭ/„9„b/ДbЖ”њ—Ьсдщ2уД'&yЃ‘ИНwш‡ш4’ЁEЇnЊU@PЫ№3‹kуњžНюА(Ж3нcqеWщфЬВ——ќсб?ф~•{hЯ!М—5цaVŠэ2тўЙ_ц~ќсЧ{іьqbtЌ5РЧd!ђ<ђСмšЙ™Љ3`x‡qˆыћ шџz‚fс:52432Ў32š“MŒп_oŒketn`F&:Ž€я'( AВИšе^6ц/œo.лПlLž:Š o•@^‡чi ˜0q,\Мpт“гиvрn`љ˜ќmлЁ-aЅ)л)Ыš9wў\f‡Оk˜ c+ЖЫгlЬŒygcЌƒ‘ ›…Cpтc"q<$Х!ё”XВ7Аy~dЈЂЖoь…iНКWz_}!…qЮ,gњ@!PS*Хеѓ6іч6# ~Ђц4zФм›ЫЫЭЁШžџzGIйХ#oЬC~жц[qЦbЭc_лКykНФzŒІHдСтбUЏ­шгЇЫTю2їЉЙУ3ъеNш†Ёзу}яьецюXЪLб8Щ5п<Л.л'Eпю7Ъ‹ZupЙž/Ь+//Х,™їИТ$ёlРƒ\Ьxx:;sѓ…+МqQљbьGQ|Q3(Ц!фˆЅМ5тЧуОјфЭєMїё$ „@M@ ЈP€№†a$V\.Х^Ћњ‰Hр'WQ?ёгя=^ё>“ј„}QЫ/ЈЦЎ~sѕкїжВGAlk Ž;[к4Љск>a™ъBj+_YйЗпУ_хОїў{˜Иcџ”™м8 5 ЄnЦ‡7Йт\QўоOKЮž6oЁNћUб‘Я™0kч=<ЏхњRˆ@X“%pь0‡5 „M0#“Йqƒчgф;iЊјC^Kє‡ L‚ EСГИТƒS?œJnт}GAъМа€wмАтФ й–Б|ЇhbЇLСБMЋР,>ќўЁOЭ]№ЬГЯ@fv”™R”Ќ™дnаИх§žЗНхЙЂ’Ђ" Hj'$T”—чn^[ttЖё5j%WќТИtQЪфђ0g№|3{ц€ЩCЃ‡_Uо+jUOМ"РŸZ™ W˜Зtt5  BQ№,ЎРКщЕMСФЊлК ›єzt{й ЪКBАЌnхыЋпќп7Ї>1ѕЮ>w2kЪЬеЛдX‡ 2%5hЬ•“ZоЬЗ€+)Ш+иѕЩљSЧЭЧHЕŒ’SпŸўў њXќfО‚…кя~oF Ћ=쏘й3Œœ0œBXGL|рхQё~љV.œЇxsОmЗЈA2!ЯŠРтŠ_~e`q5Ÿ yц%ђŠKСмкН‰ЙsЖѓЪѕьƒbnлUѕх ъ№ћ‡cM68йГ"6G7eв”qcЧ%7K.љWЩKЫ^ъиХћ.7л)ФЛ=АoЇџCQоgяЯлe>"ѕ*Ђ№ђ;0~Тœvјf‘ышАЩPВ– 'ќOŸ3ъ]пzрьзМхщ!Pc~Д9,Ўиюpў3ѓ{єъŸ7Vа1/Lжб™Лn4hићюxъУђ•;… 25q:щwєЩћ.swАfЭф+ё˜5њ&м"€Шd’кyŽЄ_-гяђюЂ]Z’ЗыгЂУЛЪЫЫъ”€Cђф<ХhЩмШs†›ГmОelћ; ˜Š|Ky‡’R>ѕzэК•ѓ|nн#}B š"T(ЙњsГй‹k>~—Яe?­Ъ3Ї&8‹ыљђRŒдG-#!iС–kK‹МlжИIј№$Ќ№“l9ȘY™)щP’p‡Јэ}a#БnЫ>їтУ,`YDбїЙЦх 6xЪпљQQоD&я^ЅA~6>„O>§фю~ƒy[АпшGЧчцхюоЖ;Ё^НЌq&adŽ‹eХе"S)еBq€@PЁэ‹ы‘ТвќŸJOџлЄ#Т†љЕ‹ѓ7NэЗqRџѕг3з?ž™ѓњтэ/Я,8Д›Т9<@ю€Mф6nђЮb›Ь­уВ2яЯЌ‹НЙjmкДyqЉїЁШ‹‹f§qrЦo3Б7>dДb]’AёTQaXbЭAUŠ9Јтc V._йуАЉSŸТзхs›|5%Љџ]НѓŽљ†q`Г}f>†2У­|еЛчЬbЃX67~(3xE\и`џЭэ*™xР‡›~G:6~5[=mЦŽћИ&И“ЌЮАГјf+Ѕt pЕ}ЇіIMМЪцЯˆJз| щМ™л?лоЛWoХ=' т BX\ыжСЧ(*3@фŠAv&ЎЈeВИоќбљэЋЯo[ћо‹Gж.[7ІћвЛ@ЁШцжƒ3”%7mл8`№ё’›6osьхћ3§Шшм/ssПЪMk‘6яЉ\зž][Жэ>МїpёщПАиo>W`‚х={іЌљрумМ“§™№ФІЯйlэ?tњ‡г,sщ‹K:Š[И‡‘тМчцIЕ YXXиИБzу2LжёMЭ­YŽе %qŠ (™Ž‡кВqЫ™BS],ЅkОЋf>šѕш“?yт;г2„!ЧќGJпБЗ˜W\TTќЯ‚5#§<Уь;tУС}‡~ўљE†Шњ~W‚§Ч[D%‹Ћa€Х•бF`œfL“ХЕЬШЪљй %nЂй1.р)бМ9ѓŠџ]Ь–„Ѕ6I:QpF9ѓƒ›ё3вЉЫFjrв‰BѓŸ—Ю е–ƒчџЗtИхиЧXй}ћіБ0ц саСrичK­k‘,ѓЭ7цƒШŠŠVз5cоbl6[ўШ‡Чрщ­7з&_gR bФжГw—MїФу9Ь[ZёСxkФУ#@Џ.йDYŽ Ѕ3\UЄsjGП8ЪxEГЂ{ХцЛj&”'Ž›xчн9iміЏО/љјН;%ЫйяНлЊeЋ6m*…’% B *рпј†Ÿf ѕnЌѓсž•yѕ•ќуОuA­  ‹Ћш"ўЕ!йАС/А kё3оHƒЦ СZ„щ&Q“ЩM4,:WФџ"Щ›rMЅA~ТбCGŸšћдОУћ.ўыЂ™/рСџƒƒdімЇx)]>W`‚e‡ †iД‹—Нх”lЖ…љЇ:vюXiYpg6iвЄшLQу&UFXW=~ЬшeЏОЦНхњ’ tFвБqC_,ЅkОЋfОіъkKў{ЩќчцwИqЎhœdB€ˆ3‚š ‹+–-‘”њЦ@˜І;ќ“БюћвwѓJ1SЗЁРиpвШљЩ()7J.˜9~s–чЬ™c_ŸРг {КuяГn§:eйnНћЌ_[eС’НЛwуЪJƒќ,„yC,y€цЩу'љ3!œтЫ@2лркЪ№ІЫЭк[–4Y’БйJЇP/†ЌцЗgД'щthп!ч`Ž˜ЙўУѕ˜uDТs51?`й‰’qАЎš џWЌ\СЦЉ’}J„@џТѓйяd›ЫЛ/G—5Šй™ђЇ)‹ўВ(ћUxžt7iŠѓZЪЪ@t–€б ГOž6Y,8чЉ9Ј„сC†ђSК|ЎРЫ’&K26[ŒoаљsчГЬ‘œ>e’ќ.XЇŽ• жВ \ћїЕ<ыžž=kэћkƒ‰C 4Фznг‰\™ КцЛj&кkКср&FЊ’„!PН*`qНмЈМVтоŸJ1кўc)иФС †PдђJcр5ЦНЭQ-MŒЋЏLDf`І˜№ѕ›ўбЅs—дыSŸ˜ёФ п cІ№хƒ5Ќ§№­кЖТgэ‡k‘є;%%КхvГfЬJJNТš№Ю:‹ЇКvюкГ[—ЖкжЏWв”щќ”.Ÿ+0СЦВЄЩ’`ГХК‰Нzрyеез^Э2ГЫjзЙыАћЇ^Ÿ~tDkYEТІqв*j!=‚{V=ПУ]Гrv•ъђУэй'B Ž PЧKM#B z @ЁЈzєyI„@#@Ё(Ž;—šF„@ѕ@€BQhњ‰П‚s.­`1їЈбоз~] Ѕ:v2wщіНJгd‹ т BX\—о•КДћ•+яJZкщ?–іJZм=iуB›ФЖ‘џGŒ7XСт:kњ,ч`†ЩIЦтJ+;œwD,kЦкEmјnзќ:š•Ы—Цr_Ч‚oA…"bqЕvaфџЫ,ЎŸmЯИЯЫтŠsА“PNњ§uYm"‡X\•АTгЬxКБnзЛМ+…оŸѕчY‹ўђR›žTг+'0Зƒ EиЫ‡X\У=„Ѕdз——ќсб?€пшаžC­[ЕЮѓpыВ7E,Ўіј„щЌп‘~”ŽE§ЦТЙлаd‡В!Ш”nзЛ_ ЌjЧVdн:wлАqƒЮ=ЪA…"”'Wщ2ТO‚хшhLЁ`%N5‹ИЁ7+•Y\пЮХЃЕХЬРО}_ŠЪLцN*agёЭV„X\­0ЦwN5КБ@АвэZф;n№С№!ђѕVЃƒ EФт*ВЛJНЎЃ1…š•8™ЎшMХКt,Ў˜XѕкŠ>}њˆЪVйъ ћU{~но]јˆХеŠ[ цржСz—Ую'Ьл пM<Ъъ}ДњУ4MЇЗ­­иШвэЗ Ai“3йƒ4ћ§3ЫМюЇ<>%ЕEjћvi+—ЏыЕ6„эдюц§{ї‹š$KŠ`ЋU}|Aв ЪЂЛ’Л''Із7К{HŒЬšЎ0*Юф—џ”p…a\(•ъж%БX\qkЯЮ­ћKoЮž*:лИAЪ8$Я’,KХГ`ядЅH"0Œ˜ќЛїW!еUћ?kK9јй4kжlщ_^B+ЄSRRщŒЄcуЦŒщ38љžXJз|WЭЌSЇЮщЂг C-“lƒ@,пXшмVошXя‡Pмк:M)_wЛІГЩ™ьзМїёž§{$k‹Ю/ўgёсН‡ЗlкНeч~VйvЖqR2|рš$X*Хu[љ9}СШПjЂвЂ23о`OnаЁокШиЬШhn u‘Dр(Ž.л–—K,ЎVз‘УX\ХSVWЋAQdЃC3pƒ5ќя>{ю,?ЫЩ&fqеYцџЛœАИš $%нањ„^ю‹+O2Пd0Ž=vт„‰в))ЉtFвa,ЎJ7lX\•ЭЗaqЕк‹ыжЯЖішеCђ‡’:bљЦ>Г#9osЃ#i:iT„'­Зkь”в&П9ђТ Й&Ќ~џ=~ŸŠлG~жyCx8`qХX‹0$ТWЄУ—ЭhTŽG…&]^Нќ­%eNY\­о0зЬ2Ї<,Ў#ЩOYY\љ)ЅВб9ГчЌюБcpж5ЛЎW‹FVWe>/ШЫ’&K2zSџX&шSї|јБюп=гa,Ўš ЬЂEu-\$џ$5'I'nHvtЭwеLЦт Ы ‰ьSR‰€ѓ‹ЪтТџн•zјЪЋJ6tѕU '­“ŠА$Л]C\БžUкфLіѕЏЊПрй9щwє šЗSО§бqŸЪOй4ЄшL|рš$XjTD,Ў"ЛЋЎŽЦTRуIWєІМ‰ХЄЗŒљДф\ЩЂчuьвQTv(‹ЋC ЊЃZДшсuXрЮ”.ŸнЎщЮZѓ9“§‚gŒџгTIСМђэЫŽћT~жІ!cГс IDAT9tИЕз$СŠ@PЁˆX\EvW \ЉЄЦ“ЎшMy)‹ЋЩ|:њ!0Ÿіьохќ?ЯЏ|ЅЪcUБ L,Ў6рTЛS1rcм0kEOGW/Йm-шњ„MЌqS\`š<ЙўУѕ/,xњЛoПНОu›йsfЇпž~–­ {7ћнWеЩњуф'g<ЩkT6CЈС§юоЕџž s—ЊЛр—:‘к‹k(BQUP+JKŠО9Rєе‘’Nœўњ@ЩЩяЪ‹ѓS№аЈYы>ЋUенTхeWеG]~U-J…˜"ЕPbЌуд‚ФСУW,[љіaШЎк|4ЎЈ–CŠ„G–!ъ"bq d† B†@жcQ‹Q‰!.R†‚{V)/#_qKUыђ%5J„!@8G€B‘sЌH“ B ,P( Ќd” BР9ŠœcEš„!@aA€BQX`%Ѓ„!@Ю Pф+в$B€ ŠТ+%B€pŽ…"чX‘&!ЃрЭkvˆўсuїqYуАы|кMiр/рЇЖяиž9мK9?eќ8ь^УO‰‚Яd•  їM^цƒ™Жžійя{ЗЉХ†™УЭL| №-кDƒu6E5ъН­ыmадљЯ 2лдхs…jdЎš”H­г№ 6ЁКЫŠЊ{’џ„€ЙеѕЗГf$$$оxїЮн'Nœрacй+ЫF?:>7/wїЖн ѕъeЋми^„Ri1fФ§УFм?"їЫм?ќBЌШ˜Quэв5їp.>э:Жѓ‡1Ђ).+mђГLащьнОНwЏоаБёŸ•ЕZахѓЊЋ‹ЭьwVэкБyыЖ­ј@рД~М!еW§n е ђœˆ'ж}Иqˆ‘ ,aƒИŒ!hрЊеЋX3Б%кŒi3ZЕlхМе /œјф4lС‡""—Я—Йп}јQXЪp`cпџћEч6jn§lЫАћG@9џuuU›oН§П?9›qy@XАpAЦoЭ>ƒƒFEqа‰дBР?_~љЅU “]ЎhDvnлZніэкc"Г˜d6Иє•Ѕ`ќТ’жК‚ЪЙlьмГƒmK*к‘ќЧTdjJвmнoУŽsЂš._дсr,лD'омцfц*eŸђ†T/FEеЋПШ[BР)я8ящyї „ВЩРyЧђАпі[oПхдЂa€GјDў‰-[Mm№ŸbА2Ш3ў<уžA}Ÿšћфз7]ѓСЧЮm:бЬ9”гМе`ƒ•%џ1 ЧЮтЉвœгЮŸ=?}цtфшђES\Žq›gџu‘ƒсЌЅOyCЊ@ЃЂjзeф0!р„ŸтѓХmonлГG—дІЉ 7‹хьЫёРАeЫ—qBRёЌNnјЫ_ Жaвтц™цЄ “†ўv88ьё€ЄЮB`љлЖoыеЃ—XжЦџ–7Д\њЪJ>чЦKщђЙBьлўw2‡!4ќeCю|u(Uї$џ 5ˆиƒ˜5ОЖqЗюнИјxF?2zйЋЏЎ”g:nМБ )p_™;vрюгё€ЄяLhўnоКЙ{zwnЫ™џ2хЏИ:ПZиМёЦ=ТI_ЃЊ§_ EеО Љ„€)O):Sж8п=џЬгSў4…Љ­|uхгГg­}­5aнГвЯ6|[xD„t}њ{Ÿ с"VДјХХтПHП6aм^u}Ÿћ}Ї[:йћъULЭзЫќ&MШ0ш^ІЏЫыеaЂ+ЋЫЗЭСCЗ`сlt+>†н7ŒЕ1ОщYQt"5ЁІ#Рџ•3=щмЙsпЛћžЛpюіЮЗџэѕЗ’ЏKf0=љФ“:vЎпœ5M›7‰ŠjPЫkRSi‚Ў&ѕ6Е•Ј†|Оыѓjш5ЙьЙУ‹Д B€ BŽ…ЂCJ B€ м!@ЁШ^ЄM„!r(…R2H„!р Eю№"mB€ #@Ё(ф’AB€ wP(r‡i„!@„ E!‡” „!@ИC€B‘;МH› B фP( 9Єd BРŠмсEк„!@!G€BQШ!%ƒ„!@ю Pф/в&B€9ŠB)$B€p‡…"wx‘6!@„@Ш ОЂCJ 0"іЬ0Z'г„@” P%рЉкj‹@›Д–EбrЕGЋjЊ—4A>lЩ2!@„€#(9‚‰”B€ Т‡…Ђ№aK– B€ !@ЁШLЄD„!>(…[ВL„!р EŽ`"%B€ №!@Ё(|и’eB€ GP(r)„!@„ EсУ–,„!@8B€B‘#˜H‰ B |P( Жd™ BРŠСDJ„!@сC€BQјА%Ы„!@Ž Pф&R"B€ŠТ‡-Y&B€p„…"G0‘!@„@ј P>lЩ2!@„€#(9‚‰”B€ Т‡…Ђ№aK– B€ !@ЁШLЄD„!>(…[ВL„!р EŽ`"%B€ №!@Ё(|и’eB€ GP(r)„!@„ EсУ–,„!@8B€B‘#˜H‰ B |P( Жd™ BРŠСDJ„!@сC€BQјА%Ы„!@Ž Pф&R"B€ŠТ‡-Y&B€p„…"G0‘!@„@ј P>lЩ2!@„€#(9‚‰”B€ Т‡…Ђ№aK– B€ !@ЁШLЄD„!>(…[ВL„!р EŽ`"%B€ №!P+гE9G>rиIйЖ7З…šCe'I'* S’S’ъж=SRЂќг%z;ЕЙ9*MІJ B bŠи?щONwтхќgцCЭЁВƒЄа ““‚ыwј. v§DЅЩT)!@D @B†8fhЙьпЩ‚Т‚JЅŠŠJ™Єj…@AQќEТ€Xљ}xѕ\.Ёпџ§Ћп0ŒVе 0r– м!H(ђер.ДИгіеS7lмюьs'ОнЪ1еРœбХ!фћ КэdЗњОzш/!@Ф‡ЂŠџ“‘hжЌйЩ“'х\žvp ЬucVа@EЉїЈ[9fха1хxˆХ'fСэ%Сѕ§\9§#5B€ЈЖŠЄ Кfз53AА‹7хе%ЏуwіHЏ(-a Зruo;ќї?*Њкћў/ AпŒFЧѕї1q5 єŠ*CKГn№VqЙ2SЊД\јП#ЂdЕ@РяЈШzпЩ%!ъ„Ў“п|S-  ' B ДŠxЬЙЧ!Ур™Ёѕ2FЌmпБžЄпžŽoЗrŒ4!7ќŽŠxя;М$И>ї ьŠFƒ@ЏИтY‘чѓЭзТЌ/“ЊЃtЊ:& Я‡xгмЩеБНмgOGњљє]_О Х,ш3ТqіЄП„!З1*fcŽ~qДЭMmRЙiСЬzlQ‰эŒєЎJЮ™ЫšqИ•YЉj§эT$єО“KBКZPDЪЉжp‘ѓ„!рРC‘ДBсшЁЃmni#eŠ~аГ"ъ(ћU}шї’Џ(‹ЩъˆљL#D(2ф—BŽкgX2+=ЋњЊ2ПњH9sрlЇv№эVЎ>­дzъwTdэ}?—„яjёЇІu‰N„@| x(ЊЈўЁ%€.ФѓЁЂBя[9€ъbЊˆпQ‘лKТ­~LЁAЮ„@<ЙvтВ<Šrm!кА FЬ ЗrД}A§FE!Ј…L„@ D P„Э’БI%6sŽWя?Иѓ"ЄkиŒŠТwI`:?vЈкЏy‰Ео$˜B PФ6эїlRщП-ј?%‡ЪўЭ‘F”@?bT†ьЬm§п%zaќ-co”кMе„@$pŠњїjlЗLšТў/8к,йw?ыH9-І:B§ш 8ъeW—ЋїЋяK<зžьzJJJn^nrrŠ|‚в„!U6lќ?Oч.И EcГ@bvфУЭочіЮЋ!MB ‡<зžlЃSЧ[‘…‹^>AiB€ˆ*ˆCьчща wЁFёal–CуЄF„\юЎЎјА;D„€{‚ијЧ}eT‚ B€А"@ЁШŠ х„!@D E…›*#B€А"@ЁШŠ х„!@D E…›*#B€А"рz]ЮОНљљљVC”C„!@0Т˘›ХЁV-НЩH]B„!P3РЛчhИѓ-мŠ0Bъ&S:B€  ияž;EєЌH$e„!@D  E‘Bšъ!B€а @ЁH e„!@D  E‘Bšъ!B€а @ЁH e„!@D p…ЂЄЄЄ ›Г;Ї§MiСлqшЏˆ bAeІЈЄnћAКgS5%Љџ]НѓŽх1MлЗЖНwЏо8 ьwВ%;L пќрХWОКв|8бФ;Њ0яjoJKMI7~\Eiдnыz[о7оъВпїZFђqЖЈА`дШQЉ-RQ$ѓСЬ’s%RеКЄВ9:kЮ[ЧЋSкGѓ§Ж—YАтР-3ІИ`­‹ehѓ‚J›ЂKR)Цecў3ѓбM| 9ііэЁуemЩ+Іim2ђпzћrvуЄЦј@xыэЗ$Г’Љ5№В1sњ”ДжЉјЬœ>шБƒ9У=фО!2KBVШЯТк”ЧЇрњoп.mхђЪО@Aewѓъ шšуJxmъЭ*ЫъъRЖNДІ+(ъX0|№Э]cйYVхЏЩkYs‘ѓzQЊЪo9И^Жi&КOйбХшh~ёp7 јэhQ9brCбž={ж|№qnоЩ~‡Lxb‚дЄGГ}ђё'O|wfЭ{яйПG:ЫnuёЭёьЁУ‡ЖlмrІа|†ДєХЅмКykюWЙ ѓž›‡Ьоwѕо›ГBб™Ђ™S'Гј„ф#ѓўЬ‡F?2:їЫ\Ik‘6яЉШtr(›ЃГцМuМjЅ}œѕл^ш(qр–­‚Е.р 5m›м%Љ”Х/.>іѕ1tгЁ§‡NџpšљЃГoЕ-жЩ+І`m2ђПќђЫ›лмЬ )Y“LEІѓЮџёдЛ??ŒЯёSЧ‘”М“’‡8eрт…ѓ‹џY|xяс-›voйЙ…›вuW€ k>N)сее%кд•ееeп:{'yНV#V•XеИMхEЮЯ2џp В—•юБZvэйЕeлntqёщП O;;щhЩэ%SњŽўіљ~Щэ:kУщќ|ћЯKЯ/кА~нЯЊЃQЃFb6’чЯŸg9ххх)зxЯrЕvлНёкЇ‹N‹ЅD™k"“ЫФ"]ЛДЫџ>Ÿ•:і|Л[ZCоАqУи?Ž…АbйŠж7Ж~їэw!}lьЖ­˜&џ†cP`IБ ЎРœU6‡+@­ЙjЪъь;i/Š+q}cUА›КФ":›’KHŠЅИ,Ён љ)&шьћ…NДƒкЅƒEІЄІьОFОЫв[ЊjRiŠ› _лнвŽУ€(=сmфSSШupV4ЮѓuнСл+ bѓaD ЏЎ.б”ЎЌЈ#жЅlЈ,ЪbA1_i„C!j2YД#ЉёЄиXЋф@Sќпd/‹UHю‰§ Џ˜&їгmG‹Й’sAМА(8‹ИƒшгюEaе­[—…гкЕk_єM2№ћкЋЏm§lk^=0oЖ§Г<пЏ€ЙЎS˜ЊcчŽlМ|CыNХЉєлгїОТ›йo._КœЭКьпЛѓж.щШ3ˆonŠ ьOJ.щlr}Љ8’:4~ОєѓМ9ѓ№XЎuЋж+VЎ`uіuаIѕђк‘/,_j xЅФфЂЇчС+|=ЗHдсВЈжђ1є™ fПї.QчйCDg B€ ђŽu^Ца{эЁИge^§_%џИo]—-и{@g B€ †…"КB€ ЂŒ…Ђ(wUO„!@ЁˆЎB€ (#@Ё(Ъ@е„!@P(Ђk€ B ЪD.щ^QдхG 1‰+Њ;ѕgИ;%мі]uVЬ*Ч7J1оКшКчЖvЗњ1xЭG.Х`уУчRфЉ?Л+>мœXЎŽ>;iщФ&A^oAMLТс…ЂJT_4аdGeсЊRфЉ?Б%hUЅ+хШtU%РU5CкОc{ц№ PIмhЪјqJ6ЉˆљЌv1 \‡Эwb;SьZХ@КьћУыТY0‡ё$У+BAєv6щnoJkпЎ=>Љ>Т0Љ`ф“мOћЊН $„ДqYуDь yНYмоЗx:KЁ(оФхe…ѕg АЦВW–~tA‡Ѓ.Xˆ,‡:ЖA+# *3uр*-уv њžлІЪ™.%7ЅЮ,Я—Liё ЗЉвm{ˆtЂФŠЗд*(ѕ%@X)Ѕ“ЂALжuьвQЬ‘dћAYIЌiУžЉsI™ЏlЉВRkѓЕe5ЋМсVS6ЭсЅЌBц}™›6oтљ}ююSјS!(pƒ7…ХХШсgEєъ_]љ@І˜ЩeП=Т5™ уuИЉ ПIчZ/ЇёЦПАј^ХЂ%‹ВЦdеNЌЭs$Aй.ЋYЉ”2щіыЖk”•†73T;sГ§\1ічМЈ Ц™3јжАК|(ˆD:ЖAЗвП*3u[Ьъ,sYA$•м”мЌЄЯѓ!шNщ№сeuОљm ЏQчЖв/…ГЪЮвљУ–>ЏˆщыœфжА 56Pч.ё|м”ВEЂІи(ž/ѓФ„.ЪюжЙЊkЉВRю3sУIYД]*ХЪJ™Кц№іBŠ˜Ї.§ŒЭь™; Ву‘DLŒјиZъЅПМ„жY)хЗВG$;< ї/”хў(;B7Јt‰gr5Ч–е#5‹C зч‚ВgA‡†}Оa‡5?pеЪ/^‚В]JГbЉJ[BWŠЅФKE‡є­џ6EЫ!—нюЬ‚Q‘ŽOPЧсЈЫGШYulƒJFeІ.†ы,[ѕ•м”V5ћ;|ТУmЊtл"]Ї8ЧŠр\_щ$3‚ѓ [Ж|чЃT"lп"QkкАgъ\RцыZЊЌTђпЎЌŠbU*.&mš#ЊI24h*ff Щ8pрІ›О:ђdё“WНКђФ‰˜мГžт9~{„k2їЏDVы pЩІM“]8Кtn[^^Мј™ХLг9€Ъž№Ч /,xІ.^8qмDLк8 l—вЌЏл.йxнv_BЏќЈёїV^T]мжхѓŸЁ&’ЌA[d`фg•™ќЌНeЩћ$LI b-т)'ј№ВЕZtFЌZЬчUˆqe]Їјѕ‡›e‚NŸWФдl’И–pЃzфШЩ2OJe‘/ЖˆЋAХѓхЛ`GЊd–'ЙР,№ЄЎЅЪJy)fФIYёV—;A6uK•с,Z'*3Y*‚ЬEЯ/2Щl<?ЛbйK Cл”Є9fТ0ТG~УlОХM>VРА€WmdFи‚Щ\AJъ@“єu^щдќ^М ВgQ˜вРz…AМ^œ жvqИѓ\Y‡žшŒxЉшPт–ХЎс™сЂ0*вё ъ8uљR˜еБ *•™0ˆ›НдF` IDAT Щ,’:Ы:~FЋW9:|”Д:пt tю‰Н]ЇшќAНсРыVžž=kэћkлДiуЗiі-Bq%Т:іLПеI :d”•J—–ЎЌЎФЊ%SЎšиМcy в]§њъЩ“d у‘f(<ƒ#Vy§ыз~АvХвF-щŒœTіˆŽ|…эљF%ы:а$@PJyeJжxв9€Ъž…,ёX№Т’‰&њХ‡W* :ГLG‡žюRбЁЄьбшЫСŠt|‚ИGPѓEjђљбJЖA%Ѓ2ѓШС#ш0nM”–ЕќŒž’Ђ{ХCДЬdœх™6јЯmЪkс5rAђD QЅВІS`D‰U˜А…?вСoЈ­-UЖˆЋ™‚Š=•ЉЈW,Ы“\`gХЄeЅвЅSКВъŸŒр™dJзЁ„92kйгМ…nЈЙЮpYx>nЬ•‡ЈЬdeшШgaг/п(Ьr7 +A“‘Š0Чt™ШзШых‚ВgaaУ?6tMW‰Фz+э Wl—ъ*хЪ:єДџ]5()ЛЦуHИОмŽŠт™Х5ѓОŒёядЅSє~мy@иЦ]—RƒD`дШQƒ‡ а_БК=@‹qQЬ-‹ЋП!wueелйе駘іАщю!ч"…@і;йЧЇ8<оёŠ‚G‡,„! CЅZ\пK=u ”я EЮБ"MB€ *`/иVІI МWDэT” B€0(бE@„!e(EЙЈzB€ „"W/”E ёиє*bЭяŠТбЙсАiг ЎЮЦ“№Š›6цьЮiSZф›љУw1јЕ‚PфЗ' 5 t'€ишT/ЌЊ—З6АгЉX@ *—гьgf/[ё:[Єbљpћ+Ё(зЂФь5ЧБŠэнро*/eћВЪ"ЁЪŒbеЁjBMА#u“§х&@@ЪмЉЃїMљЈ8ІvХ”йX E1 9C„G€H™9сBŠ”lŒ:іR%Ÿ`хН-Ї!€€ІHіZYа’”dР)3•np ™|3СЬїЧі(+ЁР)ЅІўЋ+лwjŸдФмЖIЯуmЉ)ЉН{ѕ>К/'ћ§ьлК#™дџЎоyпфA‡Љ‰п•zЮВ/)“'}UДїкUіЕш“yЅJ@РQќятУћoйКЕseIPўF$žtе­МT5‚п™›ШrО ‘wDмёлпŠьЎV>AО­ШУ!Zр24E#^)№$І5ф˜e™зФG:Щƒ€"J(t>@_j‹ШѓˆГb$ык(њ щHI›Ђ':‡б;6}ЧыMЁF–ЏьY~–щид++•ђк—˜{|$)ѓ$Илb№6`ГЪ^›ŠЄкY]тЗє“сОqб ЯДакqА`ЭфІ$AєЮ‡М:›PR’;Љl ”9n УєuПe]ОX)—!ш@8§C%зчЎB@Іђ7Тtx.ИъVБЂ(ЪnwцЭЈHЩЦЈc/ЕчtТi(’Нњќ:ЦL{7ЌfВ=*Ёаљ€ZЄЖˆ<8+&/^Ж:HŽЮІш‰Юa‡ ‰ІИ‹NzVWЏYжНЉУтўXБŠs?œb ˜U"ьЄ КŸŒ:eІ@eЧ)3EXtў@'фmдй§eЬbБƒeъктЊOніЕ„Ц>vfАгŠ>‹Вђ7"*ˆВЋn V#94ЁЈ  €ЕЙ А СЕ^ЂтypФУ#rчbT{ђјIЬУВЌh+VЎ8іХБЯ.џЇЉXMЏm #RІMђЕ LЮ2…’’Ћ&ќ9њХQјр= НгYіnXэ4mмДJ3WсcцњUt|Pш|рЅB.ј…ХОFУnAkqвГКzЭВТ5&šхВЎƒœC!VO˜хрЭzэ8h‚ю'Ѓ„N™ЉPйqЪLŽ'?ЂŽ(;щ&З6EћЂьћ=ћљ9ЛъS]_‹ѕњ•aЯи˜šУe~/QWнъзУиTM(RВ1ъиKэљэ9 ­ ъXЙfРД†;ЄCЖG%:И“ ’‡ЂПАˆЪVYчАВяlм-+{V*ЋЋWЧY)кзu Љj˜Rі[ГЂKЂьЄ КŸŒ:eІ@eЧ)3EŸuўˆ:ЂLE;Ђlэ&ё,—umqеЇКОцЕ8`dњSsp[ŒЕ;)ЂЛDyYWнŠR/ђВеFЩГ"%ЃŽНTЩ'ШgEuT‰|вГRг“Ѕc9е”фJ7x-$vHлЃX•*Ё`ж0с›’м4šЈš•DŽУ$W“<=q‹X#ЗЩ8MrC2U™TБUJeQЛВ^ЮJюАЎƒtPHUУOeпЙ5[й^g•I=O.o‚ю'ЃўQЈ№дЈМк•™м:*хбЎLбЦJ#UmZЛIєЫЪЖРІЋ>еѕЕш—ЙР|рIгШФЩ)Щ)эnlm:ŸЌ ЩхЪЌЌюе”П eЋaS,Ш!ŠАріYQ<ГИFўv7#˜7ˆ|НT#!@XˆњяБрxСАћ‡}ОыsЋoqŸу–Х54tq+5 ‡ЬŸ;пœž;W2gіДўПщяАT WЃPTУ/j>!@„”””.нКДНЕmzѕ1YbыqjŽX\CйБ4;J4Щ!бњ=f>‰OpОзИв4*Њq]N &B ж Pk=Bў„!Pу PTуКœL„@Ќ!@ЁHн#СМ#aЮGю*дMŠЧм4йЙ‘œ}9ц6ъеё§AїН›Э ЗW!Б#ю{Ќz— Pњў‹)ЮЧXћUФš?ЎКімйЯ=ћ\И†Wkˆ\сIЪЎˆя #dЁШdцhbВƒИ7LЪєYEtЮЧчcИџoъ@ахs$РЅЄЎxtѓбГ}юшn8DКŠЊVЬљjфЊэиЩї{a8qЕЂДЏ=нжѕЖд&Ii­гF…YVац”В•™N|Pъ„.§uхѓЯ>ПђЏ1Š”MX&q>F ъWD=aРЉК#0ђБ‘х—ЫзМЗцDс™н{vћЭр/,`Еиœ ЙVƒЁ E PЌ_П>–взOЊЙВ%бЄ2г1m(Œ+yЅ,Vу› fО†ˆгЎˆa()QDIЇЈ4%њYфmTкС­ Їj+Г‰фCжQjђЊ•С4”5=\ОВ§Mi  п(пIЇ”M–Z„ЄБ@(h™“јfkˆВRxх— Uзн0ЎыSд˜14c§‡ыYеј.*,jпЎ=юyѓЭtбѓЌпU:TsAЭ ,МЬ>ЌѓкЙ4•XAAєIЋ5”uu]щŒ(}`т› і—ЗMЏ‰­@EьШ;–‡чvЋ^_хЫ№ўе5>(›Х+ 3dxxRљkхgumqB ЛcыŽгf4nв•‚фЂOџйo{џеиœт†OM(zэеez^>єрCЙЛJЂIeІ+šBc#Ћ— cёЭd*ЩЙ“˜ІЇDхrJŠFŸмšhŠ;РЮŠМJ;НяъН7g/”‹ЮЭœ:™§Dђ‘iCЉЩkЗьAc•”—JW™Ои"фLA+‚Ц,ы*uТ…jгнЪ>e5ŽŸ0ў…Х/0п‹–,Ъ“U;Б6ЯБ:)6пЎRЧЬММ..XЖКЁУ FD‘ДZCІлыJiDщƒфЊ§хm д јŒџдƒю„чvж7ImšЃє<ŠWЂ;ќўZ•mqB {{—Ž“ЇNчжс>иœт:a‚п™”…&Cы%ЯЦЏ—~†|њ‡гlX%бЄ2гMЁ’БQмwVк˜VGЮhS”:?uІИ'DоFЅl„<іca л Цwп~ђиЧЦnлКAДЛџrV\Б I I~ж hJЪKЅЋЬВи"T$"&%§Rаr?Yt•ŠМ•JБВКюіыRПпєУVЧ0Т?23ШПХъ ‹ЭwXЉЮ^^‹N™+АR:Ќ &zЈГ&V­МЎDxqћЫл@ЉoЌ~ЪGŽс–u‚дёњфdь\QhяYхЏ•ŸеѕJљ%-џwљЂчѕъй {‡wэиnоœy•АшOЁFхЁCљnwцСЈhХkoœ=skЬЃIфUЏ­`СSI4ЉЬtESЈclдElЗфŒЬŽ’ЂQчЇЎj1_фmTкIП=}џч;QфЭь7—/]ўжлoAоПwч­]в!иPjŠЕшd' ))/•ЎВZФ!GDLJКЅ еUj^)ArFfSчЇTЃпЄвўї5iо|у‡ыъ$Єп‘^vЙlуІЭ›7gџƒЄПtš’ђRщЊпЉ Ћд OhРннЇw#ЁЮтgцяпЛ?ѓ~w{ˆ\i@ЁИ+‡–ƒМЎX-N|АПМИцƒ5я­{OЗXзmsЂ{Eщј[ќZ­§ ]Ш&_—’JЂIeІ+šBc#GDb~tBЮ(сІ$AчЇЄц7ЉГгЗwпЉГg§nшя`пSŸ˜кГw_fЭ-ЅІфƒ_а ЏЄМдЙ*йw›”—’КJ№„:щnЗЦOX№Т’‰&.7 ІR3К|‡XщŠKљA^WЬšЎП$Wm.oчbД&{Э›ЋV.}yЉд$н6'КW”ŽПеЩЏекv`ш—@6уО мь‚РХёLzбsѓ:vщШLйœВж%х`FLЪq› 6§uХ_|рAЉжбјыkEцЄq“вZЄѕшеу–З\}эеLM™‰AbЛЮ]‡н78ѕњЄ1YcюОыnІ сЁ‡Ѕ&'Э~jіђџYn“ЩNБoњјЃVз5ЛgPпЮн*дN~­RУ‘41МвѓышжЅ]‡vПЈcU1Ÿ№ј[_лхЖ.x˜вЗпѓџ._љŠї ›S CЁЮ"зP#Zmэ!rc–ЕкКЧG5xШр§„ЦYЉёDыŠŠ:,БИжјkŸьwВ?Nq(PќЈœŒ@фЏЈъK ыrF\†šв„@œ €Aa‹ы[,[^љV\œ4Œš%ЂrE1йВђВ§bО.JMЄZ E —ejјь\ o~\^вбmTTЎЈъK ьВ…шv6еN„!P(ŠƒNЄ&„!PН PTНћМ'B W(тяє€Б šѓ"ЉHƒщAчЮ8зŒ5œ{EЭиЭЏW/б(ƒUћE5}] W(ыp+Ч Њ[чc_?2TЄУ!6БщUФ:%ШŠть R<иP„Ÿœѕ˘bA В-1X\GEŠ~ŒAo§К•uJС{UаŽМЋКKд/ьLСћЩd)MэWo9•”˜ћм№Г™Ъ ђ6к0™њ ШyYљ„/эWСЇXЃџŠ№€@б'ћЦ>qe†ѕ’$xУ /р/QѓQс™C‡s_Xђ Ј"zіш .DюіŽВrюБГбe2хж@!иPd™š3QУ8ЩэА;|ѓƒBR"sД2WкгDъшyеJѕŠљ<ЉЄY„Іе+dъ”+-ћсmŸš’„ћ;0Wђ"ЪŠјYSPйdўу› \Ÿ%=й•э Ќavу› Ќ”ВCЁ ^іH*Aа"ЩЈX}`т› і?1х%Г(+Ж‚ћЂdbe™ѕБŸžъ2ЖБЩCР^р-гZNŸ9}јУ-^ФO-zzб_WМŒ­qx‚a2…Ужоa­0#ќ'Бт   Ђ„Єед\ѕ5oWь a EJžA%лЃюfTАD2GЅ{šHzGб‡В’fQщ *•ХŠl(,ƒЦ•6ExE”љW ЫN]u=Ђфљ5mюйГцƒsѓNі8dТDџ™ЌTˆXЇX§бyeE[ч$,ˆ—=’Ъ6ъtю4•>HЎкџФ”—ѓAj2uLЌRЎlък›y_&zјYѓ<ћќlЛЬИlx>„ ™L­Н#5U(qf>H(Y­AЭm_3Ыер;xWFфŽ?‘бЩJrРђrЮ™Јc{”Ъђ$7 A$sTкБЇ‰ф6!HєŽьЏKд”2yRIГЈє ж”Ъb-6–УhcSЌšЫМi,Щ€Ћ–ЪJI~1№Њ!ˆ=И8Ÿ,збA~`‡МSИЋќzХX)н•5ёВGRй)bе"’R-LMgФЦnпў'fsЩI­Аgbнvh“{A,юЭПєsJrхuТ2==|ІLцElHNНІ,xYЪос ЌЈ ЮJJkb§~ћZTŽАW]МUђ :a{дЩ•vьi"mшu5кф+i•^СˆRY4nCa0Œ66ХЊmф€Ћ†MБЌ”фlЄКQђќъŒˆў‹•ђZ"ж)Ђ'ЂЌєJT€ЌsЇФЫIЅ5’R-<Љ4bу/hџГЙфЄVи3Бђъ 8З)–’dѓ4hаTЪ Ъц-›юЫѓэ™LEMЅЌVвДСYBIiЭm_KЕЧl2ŒtЪ6;a{T”2•vьi"нв;В]б,*Н‚ПœŒЮ),™WКŠD”мкЫкШNЊЖ).žвѕˆ’чW,шJж9ђNqх•ЄЌsRRг%uHъє•љN|Аџ‰9Пфь™XEїœлKIђЊЗWѕюе[Ъ;т+K_љгд'АjN>хI‡‰Щд ЮJXfHњкЦ~ДNE:щинЖ_gЧ†&в-Н#sЩЭЂЮ+ПœŒЮ),™WКŠDнк”7ESЂьЄjQпFжѕˆ’чзЦŽ§)У!я{7ЄГк:'ЅRКЄIО2_чƒфЊЭOЬљ%‡л&Vб=ч6ХRLЎЈЈРЪ№&Ќ~}ѕфIŠmЊlёаŒY3xY{&Sqщ/тWдсьзSI_;Ќ+’j‘E:ЖGЗmжйБЁ‰ Œ­вЭЂЮ+ПœŒЎ(,•Ў"FЗ6%ТMб”(;ЉZдЗ‘u=ЂфљЕБcJчpШ;Хо щЌ„ЖЮIЉ”.ЉCRЇЏЬзљ ЙjѓsuЩ!щ˜XEї\йф3РRкъЦVcЦIHHиВiKу&љYQРVж?ўѓGž&S @Юм{!$}m_ETЮ‹kT`ЇJ B€ˆgˆХ5ž{—кF„@\"щ КИ‘E„! Š‚AЪ„!@„ E!‘L„!@ƒ…Ђ`аЃВ„!@!@€BQ@$„!@С Ё(АїЮ‚AЭОl„YhEgBEЈьР7)]Ои’ B † ЁШoWEјП^5bЁ02~{ЁјC€~eNњ4 Ё(ђУіiwGHtЊ -G&ђЈAги!*ƒжs\жИдЉi7Ѕaг~~jћŽэ™У3RSЬќ)уЧ•œЋdџф:|&+ЙийМoђР ГэлЕЯ~?›ed73ё€ЄhŠЫ:›\‚Щsг: b>ъ“rtўsуК|бxuБiƒи.{лЎ'{Еn[‡”bА›ЎѓBм”†Ч'Е‰|I@™џЪxе$XˆB(В:g9СsPЦ бmўXџќџіОJЊъJЛџ5ЮЭЌAHŠЄ›QƒЪћ%(/ BhŒD1€  O^A"*аР€ьж ­ƒк *&A% с%!†€3:ˆТ bџ+X’хџн>]Лчž}ъоЊ[еUеЛЋиgп§ќЮЉ:uoUпЗУ§`>мѓсŽww>|˜ЖUOЌsЯФьиКЃюХ›0ЪZМ5&і˜ЗqћˆјЭыПйŒђ;zdчN|xџРL1іЇcƒЧд-Ы^(нўЮ[[ЖnС?e/TmuАйЕm›zпtдЏjіWЮщ)uЖФtрCН‚з;OіŠВэw›Щeѓ››ЁЁ!9|јПяџѓў§мџўяƒЬiХO‘сHžЏl` AњѕщyрOˆt -ЎjQ_€Л0zгCя%zАЪўХ—^TŽа@яЩ_}=kЦдWрпЌГ0TD(.)ЦЋњл—z$*=R+š*ЛиdАuЫжž=zЂNTћтѓUщbV•џѕѕC?„š[\й)ЊёeјЇюHPAР,‚Лi4+h}m‹тUХT ЪŒ†єqдІчђезSЇ[ТЊhxv#Ќвс™ЪCkS Ÿ}rdд]Ѓац,™_œќЂЪ€+‰б#WN­sgUuЊ!Вшz”Md0 ъG•Œ)Ck~=iŒ˜XфД†Щ‚$Жt!„ŠЉЧ)мoзі]JAЏyдOюиєŸ›tcШz§FЉdЩщЩР29ІЃ 5єї^ДЄ/R: Hu oщпKйуУЭк5k퉂/WkœьRж _‘•mаJVˆO!и*е1i …дwцИlЊVўPЄПqНA%ЋАЪO§э>†ПНeЧілѕЊ8YЇtД‚ ЧХ‹цŸњпSюњ№э7wМ§юлўPn„•Н^3E№ЗF‡”РБIr%qzD вЉuюЌJЃЮ У>њШo† Sэ:Еѓы9ЭЛ[7џьИw•ІyS\§У5@e9рц+ŸX &ќƒ€!С­G‘WЗКZй@ЈЎљ\оЛ;п“сnд‹H ЅявНЫЪЧЋ/HТ…гбд0“cВјX;Б) Взо7ѕ>і?ЧРлняэ>vъ46?яТщ%пКwVЕ%eTЫ•ц”ЩY}Рє>4UžЉ`wвіžfRШјФ6ўPЄЕq§sЩHге8(JIO‚:DC:Ѕ#&ТсЉ6 Тz:rНЕ5нF—1я8•TЎ$NМS|ъд1A:Фє+ѕТHІN•fќНуq6‰ё№N+c‹–ьq†JТ–єК`ФФ9zuЬЩSq’ЄŒQ3ІЦx@0ZаB†ЁЁЁКрюкНЋп-§HЏЎ~\rИуG…Э{ШДgєКY†Чф№б[аe д>ВW\;СЉ?МpоЏЎЃјНV<ЖТЇ5Q№хЊЛgЉіЌ(/’­H‹І /яѓБW;Р oaлЕ†аГOOœНЊгah ‡ђМЕ…Ub‹р™yЏ№ЮФ ё Œ{їюХТТ›&ьЗn1/hРЫЫHзRbQ‚—Ё<(0іЮbЉжЧ _2PzЬ&žйWещ”žу ЫnЄsU№НьХ|сJŒНGЌ<3­$VЋA…х:ЕЮUЉтЯ(Pз`uЯ(\+УѕRМ•рг†~oюX„Ў+§В—‘V™A2J§Ю‰qк#Ћ^R„Ё?iŒ˜Є‡€јъ*7dИ†ЌŽ"&ўщ–юњq)•|u/NЏl2?&‡оЃ.ћЁўь“Яh%T§ъkh^лјšЇЏ|g0Мж–г5==И.“K№хЊЛgЉv+JсЯ‚І™2>qчeMЪ™?pŠ„GAŽЧ"ы)8–Xуд›г#<§"KKюn„Щ,c“фJтєFjЎSымY•F@ыTЭјЦ_;ПџСўF—5ъкН+™m|}у˜ЛЧЌzj ‚“2ˆpеUч]ЭЛ0цѓЮ;я€ LеYѕ„)ЦŽ„ћџЊЋЎкЛoЏђ€Ё’пкђVїnн)VАњO“§љ‚]kf‘ IDATŸ19|Юoа5ВН^7nьЈёwп5nь8АОќrdЫЮэ‹,2єм0схЪЬ%} З"ŽЌар4L')d\тN+h2<’ДVdцƒѓ№§ѓœGzŽ%– ”Р‰ѓDѓ‚~^1oі УK “Н1)Єw›$WЇ7RpZчЮЊ4Z‡гюŸvќФqА|тgQKyxк}г”YЩS%ЯГсх ў}ˆ~Хk ха;†т7/о\TTрŠMяўUп с-’О+Т—‘Д…Р%nLнfPс,š‹ВёТал†т(r§хР_к_л2\§ ?јЮ;—‡.S&Лyр­Ъžгу(е–-1­јЈ6Љ54žнdЏЃюwји œC^_йИс• Х+‹§[”aIУ„—+EШe!uшp^Йbх \Ч/жp§ 'ЙъLJuUG qзdд• \"€LПЉУХ%\|oбЌџ ЈЋv№Ђ^†pЧфpНEщщ™ PCЯn‘f[Зm%ƒjП ›gў‚.l”aIі‚рtИ"tU ќъ_§ѕыл%(ќhьI кЌ`тЂ…е˜G^ScRHЏтCЅФї|ИЮ‰ЫnИ–…/lЊmИ’}ЕcЌhkЇжЙГ*caЊўG|§ЁДјЉ.Й`тУ№!нRЩжUg˜‘ћŠЧ*2кЌпEбХК#9‚Џg0ѕјwЧэ…’=тшВVз“\„Ÿw^щ§М“.Gу7]ъЫ eЃGPВЊfx b™сы ь—дЇG4Њ-[bЂf?>PЊ+Щ §ЙЊЏKПep)о@Ш€к'H0­УCr В\§юYЊ {NX\kрsFљЁђЁЗ§§іпз@nI™[Ьž9ћЪ+ЏŒћл­мj:\7Уn2qв§э;U8†sыDзD‘KНпќ_ЬїЎнрJкм§oщŸњ„’!їxѓ­7ѕ/ŠrПс№–>_&ћPxивэсћ&.ндЂ|Кv:}цє€ўpU­u.­І 9ЗNД8­ШV”>ИqE.ЄЄnЩ$йƒ@ A—= HЅ‚€ 5‰€lE5‰ОфA@ВЩ2A@Јad+Њс є‚€Ž€ћ1uЫ“ЙЦ9}ŽЕЏкЉUЭ3([‘ˆ г„@m~еЅb4`ЦH` $š­“Їzzќ MFerd”zЭ…(г?•:D>К Щ EР_S`ь– Л=fєюЛеQAƒь#Њжbъй9#Љ6Т ‰A ИТж@.UP7є&WчХ0Ѓь Fj3ЃЪSХ 6№…—Ќ.е,žЩ…ц‹#B ЃйŠ0y4дLІe:Ш(ЉfЄe%>„Ё.ŒКwд™sgжПДwёкБsЧа[-XК@7H‘ь-GaчLИч‡ѕ >qbЧяw€сtЪє)ч”Q Јq§вgJ Jž.Yђш<+5SxЦP—вz(љ{аб-’шVKJƒ;;бmИ рn˜dIю……sба/1#!ЪD.ЏƒRˆ2›џмAƒЩЅл4ГьŒБVF]ŽЭV‹N‘IК“?ŽтЦkњjLžS%ЂМYgb<МŽШИС ю^ˆзnЦЈи Њєчгу…zнС2ёleнEdzЈ.№lЏ“k7Uƒ/Љ‘хбk^я(УъЫщ‘+ lПЈK5EАш=RSPк-žUn щ€(wдфniˆИЙ%ьСe™!X;в "‘Уоƒ.šГЂ ›g5щЄfmBjGьbTD™\^–Rˆ2+'„ХЧ>]yзuj‡ЗN№`тцЧŒ‰ЇЖ2ЦZu96[GpJ5;Ї‘нJжЩUю ЗеУ‚љїэ­;@з{ъГO/]L‡t\(A~1dрВчЫШ ьљвТл†Aoeне?#+ЎN VАцEЎqNНYЎN+јVЅЛ?2†НuбrUqzЎй ƒsфб%ЫЦŽ‹ЎћkžZ5rєHшG йoqšдe,Q&GFщ}^ˆёПЉЯ4ЂLыP)ѕg,naюƒŽг#мРw=Їьєб )НГеишЌЏї/ЇИ2ˆяш ™4ј MЗBWGЃeчT‰(Џ•Ќ“Ћ\oгЪУ‹рˆL|ВрBuNXU№дUgN_LЙ3сЊЁЈ”€3БюRйЪ†ЋS@.$`qо &нЬ/ыyЙЦ9=rщЭruТнOьkUњЫSjŠП%Y-WЇчš[0军‘у%fTŽ3Qo~ шW_CжзљњћŠPіЌ(WЊошS•D™n2JŽRˆ2е,sјаpx‹œ5c*q˜вj!Aљваћрcд5яЬлЗєМ”Љfч4*З’ur•гЧ/ˆFzKХC8Џ#'Бђћ5ј у™xЭYж]э"\И:UdѕLѕ@P,ŒёїŽвIШžЭЋЯж8QL\V№­J=š.S"єЃJ6бЋŠгsЭЦ-˜2bЭрBмонЛP)СY`ЧЂ. '9uBmEz“ ‡Ё—єx…€-pы6Vй@ —јщУ№)/я 'zлђ>Wщ˜qѓrп…рz+і0Š7^“xq’= œY“У‡t оIOljhfIPО4д?0RX(ѕЦЄзŠ@JуЛ"Ѕ/^ЕoјF u/яœ №iEQ ѓИЃ#ЅУjд#(%Ўб{Dд•ЎrНЭЮŠTpѕL€‹ 3%О#6&$ТS”фx&cTЎNk"УWЗ!™ЫЫ5Ющ\qыдСЇbЌJ:ЊJD‚a€Ёqˆ†\UН~ОKq(#WАn‰yИ№P=ЇОг |Ћ>IђOЙЂТnE)ќЎ(гˆ292J\3ЅAZ‰ …(гКшL6њ5ш!З йќњF№b@ юбЂ…ЕыtыЖnlШVF]Žуе№UУTГsr МVВNЎђ€фЖU\Н•Рw .ДіKЪnзu;uъ ~^Uї_ъ_бђ ЅчXw _ЎN Vрђrsz#/WЇ|Ћ­‹–Шо!pUqzЎYЎ`kъќяц1ПXVGЫ^-ыкБkЃЦШrлЖmЁ' nШ,B$пa‹жjwЭ4ЂLНB%гGZ щŸRˆ2нј(шtsзі]8Ны(.Dрƒ!~Т@зpШž3ŽQ6VŽWЪНGъй9qТaeрХЩ‡•,и^9CnktT§ КЩч§‚Ю0Ѓ!Nь€€NUЬБюОˆ`Џ“BkЋГІЖ‹\^œtк ˆН?—ЕN+јVЅƒнUuтG†:4Šб‡жЊрhз3ЭZ ІьєŒJЋВJ‰5‰s)нђж-›piG)u_]6\’†=+зјћНeЦЧH,R‰>КЊtЅ2I­‹-ьЎ)ђА,ЎТW:@”yїшЛул‰… d`wЭžbsПRйŠтЯБeЦЧH,A@Hўl!‰ЊФUЊЋsеXˆ”ЃШV”Ѓ+m ‚€ =ШV”=s%• ‚€ ЃШV”Ѓ+m ‚€ =Єj+Ъ ПœJяd$гx2ОЊЫф#ИбJu|wієєЄ†„mV>ОЄMnїLй]a†РбЃF—Ќ^yЫбЗМ4Ї‹[п U[‘?SфšŒ7ЃŠ‰j  ИћУŠЧWЬ™9'БhВЦУ-IЏ9?ŸSєи ї­х“I!гЊаKіЧмVгѓƒŸєd ИШ2Њ˜€5sf˜гєД“ЖD\ЇJ_Е†/ШћцП^ty~Гž}њОg4XшhЋяЗТп–щAzѕьЕяћJ ЪМшŸ/ЪћчМ /И0я‚М џљBX~~ќ(иuШИmGяЎ]ѓѓѓ }Рab“тйq(`I9lFр`Оpм3тцў7;њ­ZEyyИ]Pя^НqCRZB/JlZн1ГёhВgEРQ=І$g#Rs­EР[ЗЉg}§эПНЉп Z rі6>h№ Ь]мњеЛŸкЦЪjьVd Њ”ЅЯ•vщмІiAУў7і:Иџ Y.^ДИхї[6-hŠ[ў§{Ѓ>SрvЅmкЗСgLei5Ѓ шcШЖпmУЇT$BКВ,A}ќX9.ј6mоIAЏюЮЉ‡Rб* юя3я{ЛЫ^.ывУЪњ?ЎЊŸ EХaе0lwж,C ‡l|}#Х?~ьx›жm@влa?—7{цД–-šтюcD\[~шT#xV…5& "Яd>цЗe‹–˜PхemGХЏЬS5у0ЖOњЙ<мZгзІuЫ’еU1жƒјv@Lo\ЇNмЖТьŸЯОцЊknhљНч§=WЗОКкžУ0/mЖСkЄyS4N“ЅЯ”Офъb’Ј#ж,ˆYѕRmи›ЧТфAFйJЧ7і2'_Дi]ЂfY!1п8/j˜щъ’bRћжWяйЕ'6ŠѓНѕpgвЭonЎВcњЂ(HM–ЦєyЩУ]чЌŽVдЊDжЉсже™j!…[Q(–Cє„Ђб G\ЦCŽGвˆЖѓw[жПВўРСƒ‡ ўба[їцяж—aјз~ƒߘZѕж0”9lwж,'M\Кx)E.ZV4nь809’F Vич/šџщбOwќўCќ;tє†Ъи>йсњ|gDж‡\@+ѕЊЕЂАL—Aънз/ЇˆѕѕиБcUп/™Уѕpœ­ЊTЈх‹їџyџ–ЗЖќaЯР c?ШўfЁё/(Й,8TѕR=q‚cŒяыЛzщ@#ю r\Ј(5Ш‹Z­vцЮP:њ2"ј_;_ђњ;Їг?фІЦКќю)дDrgnмУеИУ+†D,фБдФhВ86Cиы<4œ™~ГXЪˆ[>ћyuK]F1Ф_Љы‚!еЏЛшЁЈtK(ƒtgѕеГроКИe/"+*OвГ@F+ь`ЭбiQ€˜rДBg-Cйг!G@JdдІ†z;Mт&ERL†—ђхъБН6KРдАОžЧЊѕѕзŽšѕ~iВЈЮ @QƒфEП`]\ЄХЬ1Цё5Ъp wЙ‚Ru_chМЈqyмгZё9Ес&тФГeŠ gdд m})WrдЛˆE§:ШKžІ^ЭNznjЌk€ЪH@{gюžбЗvИюёeŒ}§и‘Ѓэ:ЖУi#пkёНЃЧOв6лЈaѕF‡й“АцЉ5[~Зх†ž7tщмeляbчХt8/oпісT—;є;пљЮЩЯЋ“jVyzСаыCЊ?`(=Ќ’CuЧe™єГIK<Œ€‹/š|їќ‡HгИqcDІ!‡! є~iВШб”|ђrжeРeAZЬ`ЪЙќпўmуoНыЦxnлЁ­ЂЩ тkду@#ю :Vˆю‹Œњ^да—*Ÿ8}тSХOљ/3ршёх˜;Ѓ`џАђ]­aЇŽзœ9sjё#‹•Ѓ/#‚ѕЕф%OгaДЙЉБЎk„)SИY+npYѕгЃЊ“bпyКђ hІŒ[ЕjU\RМџћ<К`т}г§y‡п=|Ф]#|xIџzшЏtёнoWIЈИнqY№ЫœМК.~d>Ў\Л}XмjЩ IЃ&хххjX~ЌМAЃЊїйИаQCр6ЙЌ тЦ\;†‹S+о№RCЎЋq\eщѓЅјО№<Г ђЦ5ўюЛpQ?“3ј†rЫЮэ‹,2єЦАm›ЖЛ?иMJGЭzП€…\”рЪОсkZ——Хˆ0цю1Пzъ (Ењ‰ ? ŽєеC9ааЭЌrbuTJ|yіОЩ­ЎmХй`ж0wtg?$Ч‚їe>Фѕ’ч˜…ЉNnjЌk€Мв!ЄюЛ"§ђ"]Љ„вЪfЈ(GЋ™5f\ЦC–GR gР ЙPdO‚лМ€‹CжюШ—ЫGќmJчnqёкњ ъ( ё T[4+Р?є%“:дVаЌ€|ѕDЄфЂА‡ц=„oуРмŠSUхЫЕуOd……Ѕћд*уъЁ‚ @4WovМGъY_Q$Ёя5Чхlх€ђƒяYя]Щжe€Cж,€ЪˆрgŒ юKЁh vя(У…jsCшѕ‡ž2цЋѕU-PщaL2 V%ŽЦэЋкбікA„P/yŽYИ: 3­м У aП+зtьїцРЏвёWюПЖ‹0„Šмјчƒ?РN“@Xќўј)GqIмЈЉsлжЃю—Ld|Гє%/,ЎЩLzІћт;‰C‡Щ>”щѓФз7юопб№—yјж,GR…@bŸЂЊІіМф}пРFЁФ‰\ЁnоЌљЊеЋЂ,ёВpуC?Ÿ…J‰б!PЋ^ђВEЗpR ПЯIq ŸЙ>r8s‹“ЪRƒ@­zЩЇћtЉ™2‰*‚€ ХШV”Х“'Ѕ ‚€ ШV”ѓ(]‚€ ХШV”Х“—cЅя~oЗwkі0?˜<iN—|СщŒ 2&!кRS6к"%ZТdЭV$ 1ьgbAŠ™ћ‹Й ]XЋОЊ ;ЇbяG Швђ{‰&гШš­ˆоЁ+ф=ѓ17EmкИ!јr№ЗiЛwTнђ ^ц]Хђђ Qб№ь`ЊH‰hЦMАог)sfеъХbК2йH$&у№§шѕООwhЩи8 6nЈИa3Zэг“Хš:ЅЪ€}бвJi1QиTTщЂ“втГf+ ‚щЈ{G9wf§KыСхМcчŽЁЗ ZАt9ж­[WПo7И­ QGБšеӘXѕЫi5fF‚1uТ—ЇП ucНдU"‘A ЭDАaЋД’NЂ+] gЏЖb„>UmШєЌЌwЖМ3kЦ,u{]м Оwџ›ЫžЏ&u ХХiD6™ѕУ6овА””1‚’о"ОAјшGІ"†G’Kъцsє'тšеA"/(!ЋЁе@ТГОHИ0 Вx(W‚вs4ЏжеKЁt!VЦyгgЭe KНYk4•ЮяnЭBЕYљsq”MСаЁR@\LнІJЖ-<\Д8уDQВВ„z=‚Е/ыL)KјКз­УР*ŒЖjRЂ#ЋЕ4eƒHЧС“}/vЅ Ez‹дVєЪкО?ЉЅxЏŽШlEЈХJ:ЩбТо  ТДЈ:Ц9 :ƒQJzОЎS;мыь8t›t:ЁїMН§Я1…ŒoШ:n˜ьч^Du#GIiеsњ“: [Œ›ЯбŸШп€дяKўCњ"qЄОxЫŸЪPШSС†ртЯХЭ&BщЭ†*ЩŸE/ЬЪŸЋ ќCя CЅАŽ˜dЃыЌѕКБзЎнЛ`ъІйгЇтЂ:dh зн­}Yk&/їК…™е ўЄDGVыoЪ uЄџ‹z‡#‡’UЯЕяOъ/оЈ3йaђwцЦ=_щfУо]lc Ё] ь кС L‹tgYќwŠcбТЂž=z‚rБsЛжИK1EV^И…№ЈЛFСёŽŸм‚ЬŒzj+їЂƒК‘JТ-{‰Gy­zCkRЎјАХФхs4qёu”Ш…§Ј’ѕCѕEТЅ€™Ž›1$xѕ\zш9yk(.ˆ‘‹‹ 3НY.šУ]ЏŠ“БоˆП˜KЁЏ+М–њ§‘˜Ъ€МЌГ†лДџйxXтоnЈGН Чп;~ы–MF|ŠCaѕЙІЩ%ГИыжjр@•&%BВZЊV5e…ШРAŸ:Ф9">‡’UЯЕoMjOХX…АwцŽцЌШJ:Щбbѓ4hujEе‡:гbм] ŒSІMyѓ­7q—”u/l8sц ую“qЙ8§)pZЇСЬЈ›YЙд\wV=‡Ё5Љ^•.‡-&,ŸЃ#О^FXY_$Ž:nHЁ.Ћ ‡<з…5ˆaьˆЉ7Ыuсp7баСŸk-иA‡$&й(С:kр7кѓћwa№\йsЋWЎ^їќ:Ш{vНлЁS7Ун?ДжLfqз­еР*MJ„dЕT­Ќ™66fd‡#‡’UЯЕъЦ(8Бa4[‘•t’Ѓ LЌаА^X=Гц<єЮ;яœчшфт<Я26Рi)3cь їП•{18uЃЪ/sZ“њн•&l1aљУЦчъtшгТШЮ!o˜…&3ї€ќЙдE:др1­ГVЇNЦ—_Ољѕu/ЌлэњnЇЯЦˆ.ПќrшЉŒФ„ИыжjеЈШjжЌ™66fф ŽFыk?д;Œ5rXe4[‘•t’Ѓ [Ђaя`Ѕrл,q•ТWЂ‹>дЎS;УМ#ј}нЈ{Fњ„‡VюХрдюМ†жЄ2a‹‰Ычh$ п№uЗOGCЅ /ЋАykLNiфJ2&чndб‹сјsu]B‡<&7k}{ѕ>wЮ ŒдxžўРєНњъe(йб—пšИыжjРЁjЄˆŠЌжhŠƒHЯn}Бqдƒp2зО5ЉQ<31}4[QчŽ{tэtMлkъ_\ЪД™Њ\kнБѓал5mжpьИБ:#obЕ*/\hюоЇ;.šљƒм?щўuЏnшдЅHЦњіяћХпЮ”ћšЋЎЙyрЭфЎЃOi›_У+“‡ЩnEjџЧГаЊƒ^€HiЅфтћ)UI•Ѕ™4мuZѓRё†р7ічхЈ*}g@ИЈ0I8d­С(еЭАЩ!яяМ/ МuрТGт“ sўšкрkmAХŒFџr T@tŒŸЌж<Еjфш‘09|$d‡Ѕ~Ш:}~стŸ (ƒƒOIЙuыg…‹UЩ%ЕЮŽUIХј;езŒхŠ&˜вщТАл†D4СщЄБ _ђ­KЌЏ ;Ž(uF ‘АИъ,~Н nЃЫ:ЄЎчшЙјVŠFэ ‡ЫkдІ†œБ‘—ЃJ„1E" MO­Уedq—фЈтЛ6ˆ]Ќ}v-ŒїюнK‘­еЯ5NЪнб‚Q€•АRЏ!.ŒжхЄ€?ѕ‚Iўь“#ыW•ŠЏО†ќй'ŸЉЃ фС1r- IDAT}К7AzзуВИ•!дЊф’ZgЧЊдЫаaЌЏ8њZтРсВTщПњК џлJV5ФЅ“†ёŠЧV€‡ZlШz;8ФЕ`xЅmX3,Ўњfы $3Й$й@Авrё­z4Cцтpy wZ‹ЄЃJрЈq”˜"•Ѕ5Z@И(Љ5ˆЃrt3l:3Кx|љур;SEŽ+Xk6М-XЃ…‚бКœ‚:ЦO…FёšЕ'OœФ—лоЃqCШЅkŠ  ЌCЧєіVє‚єnФсЗ2„Z•\RыьX•FIњP_3pt4рЎвƒ;­Aƒ&zъИtвЅO•>|їt/ЗьhСэ˜!G“Н@чo#Н`p"Шрё­~wвЉ“Œ“8ЊФ€a“‹RЉСЭАБѕЏЌщЕ—"љ}е!H КН!‡‚бКœ"ЦOЏsyЅЯ–т-зgдrёГЅаЧ}Ÿ>kЈ€НыОрV†PЋ’KjЋRЏЧ!' Ž#2•>_jўjЮI']іBй–л-XфkMi FЎT #иŠ jП є‚С‰ §=sё­Fmz4.Žn“АlфхЈЦO.JСе`”ъ`и Ž>oЎ/[џ\iЩЪЧWR Fm\ #‡‚бКœуЇњjZяЎьеВЎЛвoБprлЖmЁзЭЌ27}ШV_(іЎЛs€[B­J.ЉuvЌJН‡Ьуp‰{П У/wцџbўГЯ<;uŠIžЩбIo|eу†W6Џ,Ю‹їыfcтRбBмЃ4HўЛЂ+W4+  —И(=QЊЧ=фрЂtЪнG­5Ѕјг`ЈЎqђ ШP‘У"wЬ.yыхщ2еO‚:JCЃ6ЕЖ@і†Л1 Ѓu9,fј2Ы›жЁЊ$HёЪR=}AйЏoП­[Њж6YnнВЉп-§0${Ш7}Ш†Џ> [?8ОшТЗ ј–ЋХ•-ŠKŠЋŠД*™ЗЮŽUЉ# їЂЫp 3їPх‚їИєлxWФ‹Нha^TސЌ ЄЧ+Юња•lL7П~ЧєhТ~W‹k”ЃФA@Ш~„Х5ћчP:A –!СwEЕ 1iWA bd+ŠP '‚€ йŠТ"&і‚€ # [QФ€J8A@АШV1БA@ˆмйŠќ1T‰†K[aiK”(qќВНў8эХ;œ э'SC2ОёАЩЭуbœ>7QˆuСVTK€K›щЯ[Љ§?WћJ-jЉŒž!3’ъ2R?•S}ьLC#‚­їТrу”i=;Њu”ЗMGиФE›­љ‰–ЄWД}%YLTюР6lЈ\ТІhŸ!3BeЄŠe–ЂbBе уФаHE%*fМћЅ.ГDN/Дђ№в"9Н%H6A@ьDpVDŸ јљеQ<+AUaef„ЮЋˆЁ?мYjH[ƒ\ињkPтY Fа>ЂДацћ-бšЂ;@{њЇJ@в ž//TEEEЫяЗФ3Uq№\нWH (vdCЈWЇНxШ <+AЕ.ВЯОA*}уr щ5hQЋD=oЎуеcЭ2ЄpШЦз7R№уЧŽЗiнцьпЯ’‚*ƒžЉЊИЏ8ЏТЋfŽei-л_ ъŒ;жP^Їм‚gє^_њЋŒImХЧЊєjˆ=TkХЕŒyЄіџЖ"Н@?џЃњŽg%ИcfФ!WC4(9jHВ>ЌAЌ5Ј ++u]rt“EЂ†Х‹цŸњпSюњ№э7wМ§юлT•5Љ:j-2Ў#—ˆнB@кЧэ;ЗПНuк9ѕйЇ‹—.І˜њdљCжeШР!eЯWп1КьљвТл†н тpѕ;€Ђьм2А’Z•\ыќZ•TŒхј!c%ј] З.ЎN#`ВQ4#”ЈЯuмzЌY&NšИtёRŠ\ДЌhмиquОQ‡4$ј‘qƒЏƒЌRX:–ЅЕl1qлGk(шЙЯщсy+>V%њС-§ОQj’П37нS‚Юxˆ[ЬЊ[Р’rЬŒ0гyЙhњmeq3ZбВђad!ЅЕ$G z|]ІјqЩ"u>Ъ#GސЃ#ЉЕШИŽ\"НlПLaƒа>Т-Ј QЩаы“e Хё™VаЎЕœєPў^”F_:&doUrY`ŒЛХын!ŽUIё!PёJiDЗїЛ ‚upuъб _cHЏDнEŠ'AЗ„RGƒЋЧъЋgСэУе=щеBТ!= dŠ@‚2ОО`ЏЪUXnYъХшeХpэыюКЌ‡Baz™гѕsЉ­јX•zazvџ‚з-“Уо™;тГ"њЬ 6ŽтcfФЋѓ*bhЦQCrћГ5ˆЃ.щу’Ez|”љљЪ>Пq•€Ё#ЉЕHЪШ9r‰Шб-Є}д{љќ“ЃSŸ,k(ŽЯ”"pѕs§’#nXЩ@­J.‹u~­JНCЖbиј‡жeРеiИыО8Єщ•Шf„ђѕЙŽ[—eвЯ&-]№0‚/ZМhђ„Щx‹№'Вj‚€d•ЊрмВфЪ6JŠл>ьЙPм‚чєy+>VЅб‹ЗДКGІŒіЌHп?iз%AХv­Ш"УŒТŸ­ЮќЭћH…g2#B0”4 Xƒ#9~u%#8їй'TуqЋхљKв5еaЏ=ЏNk/0ж{AFŠ‚TЕЬ„aOс`JЇ№–~`B2|ЙњЁЗЅмЋ22Ы@IіœвХ:ПV%„JђЛh 2VёЙ!BЙ_;†Ѓ5WљrYЭуяyј!p•ВШџ $6№ƒЌR k]–\йфЅŠскзKхBAЏзI‘9=LmХЧЊD@#84œЅоZpЙ†ЯŠЌ;ЄС6Ш13Z}§JŽвoщаp5ЅZ#Ф%‹,\8яСyј‚ДтѓŠyГgP.)pчШ%BњN’‹ }@кЧЊ^** м1Иа eх3Ѕ\§\Пф[V2PЋ’Ыb_ЋRЏЧX9 §.suъ6eД€юЪ,n=Ž,“&NZАtйфI“нЅ˜qСGaAV)Еi]–\йF1qлG.Зр9=Ќ.ЕЋвЈ†С-­ю‘)гpVdА b_ Bilк4фЈ!Щ@пЗ Ѕ>Джр/•Ђ‘o\ВH|т›:yjA~AыЋZЏ*&ЧАЧut$в}Љ%а!\ХŽЫЗ cД€F@I‰ІшУ,Q1Ёќ|ІеО!вс–*Ќ†Pcх8Ё. —jX*-єЁu­RКБcШFю$8‚уЕђхВРqгnъмЭ~JЄ—m ї‡дAV)Uˆ\ўeЩ•mУЕ==ИPь –y!шЋрVф­јX•T! зRї .‡=+зШ6ѕœ „Г+ѕ#ЂœьNšJ3ЃG4xаЭ§oŽ6ЏЌвhёŒ$šАИFЃˆ({ЁьаЁC‘яCW)сjЙлB /iк„N\š7kОjѕЊкдДєйŠB€U Mхъ\-œєTДœв…”врЉ@CbњˆјяŠќ D#‚€ И­ШA@H9ВЅbI ‚€ рF gЗЂ ущ†FнНc7ю'UДИ) q]jФ Ъл§оnяжрс‰‚"DŒЫЮщ#LPщЩmЭй[vф8H@œнŠє&“‘ч>2wUё3ъ{б,}х'г~$-GФпХм_Ь]јшBљЪкLNjР‚1mЪ4Д†{cЯd~NіX››Њ][Qя‰§сЃіэкЋ%R#яz дpA‰IЫqƒЉФпІІїѕН§zбФE€>Ь03f @ Ѓ"Т-ѕ?Œ)~ИчУkк^ƒлплоБMG=І+EЮ.jзV”Рм|yњKї§Вˆ).‘ S“ Œѕ/Ў_њLЉ#BЩг%K]‚geƒЯъaLtбz9"'vш§няvhнО{vюiеК•„ г•"glEјH’$ƒ$ЫРhcfОvE† ‘цuBV Њ”aЈ6uGШqйЛtюr№уƒ*QйЫU rа@%ЫѓXU™хПјd‹L;ЊqŠЈ†єLG­ёщ(K@ЩMхгОв@4?QЉПИZЇ–ЛсХтi%ueтk%ѓФ-3FЏзЌт[[Г‚oUъEBіПv‚№ЅТБшсЂЇ‹/?TnTCЄЎ_ПўАŸ ЋпА>dЋ_i4ЋцˆЬŒЁв[б јВŽxьћѓ]w§uN~~Веї[AаЭDЮv"иŠA’ ’ЃUЯБ(:˜е$сЃ§T(ЊMхNѓ—]БзНvэоћу'ŽЯž>Uq'C=”Я#Хї qЩуЖЃЧєЃсŽЯСЫM‡žK—§DЅўJ1 vУ‹У3Ћ^'Ёшх№ALЊ2зš|ЋR/Вџ5/ Њ.Y6vмX|Ш№?ж<Еjфш‘а>Вп€гшЭr6Єча э;ЕЧ\?їєSЗєНТ’Ђ%УG‡€‡n&rж#ЩЙuіIм№Uaд9<@нЁnўŠ8VНƒЪPЗЇћЮъЗ’5”aЉ6Щ‚Nuc- wчџГёШŽ{ƒjw†<ўоё[ЗlвK‚Ќѓ<ъ) 3 у&[фꨘ* IPzk|Вс(UЌН•SжЕAЪ‘‹ 3vУ‹’ъxъe“Ÿ  ˆѕF5ш‰tНQ3—к ОUЉз†рњš‡Н:œ/ьAE ‹”ѕђй'G/$FЕЉЂХeW'ЪžпП учЪž[НrѕКчзAоГынКAрxUpыs\ВХdкAFw|^n:Ќ-@i]†Б#ІЛюХсщ•­щ*G|Šщ hЃшх№A@Нf.Е|Ћ’*T‚ѕ5œ/uЪД™oН§жОїvыa‹зЌ=yт$~Гр=7„\КІX7pШzГ3uˆCCwЌ,ЂсЊ'WMž:ђЋы_Нkф]pсN79лˆf+ ‚Т№Л‡ИkФрЬњЏ‡ўЊ_(/ЏК`]~ЌМСeM(šUƒ}мWy‚^љtЌъ<НЩeMt{ тš4:ЯЅAЃъд/џ!kIрKn|љх›_пXїТКнЎяvњмщЭonОќђЫВ |ЅiеЊUqIёў?ю_№ш‚‰їMї›qэ\tAойГg•=јќќŽAтs№Z{чRд'“Уг+ћXеъЂьAтЛjЫ•brјИджЩЕ*€њšGpuДwЏоyu/\ќШќ=Лі Л}˜сrМ'V>qпєдdяаЙМвgKБгK rёГЅњ іМќ юТуааCЂŒ?ўќuоyїц-šЋТpсN79лHпVФ1AށбЊчЈ ƒ0!„ŒAЈ6ƒL0WRп^}ЇЯѓуТ#žЇ?0НGЏО*  .c\ВEЎЋЎm_МКЛОЕТ…Šo сŽЯСЫѕNY‚F% Фф№ ХпЊ—ЪфpрєzLШ\kV№­J# ѕ5›€|ЉАЬџnўШ#gЭЉZeЏ–uэиЕQуF”rлЖmЁ'M@[xфЮЁAJРп2Зэиђоіvmпе8ътфЩqTeщлŠ–/[>gжœ†љ 8pPЧЖч§Y@чŽ{tэ„?РLqХ€ВъЧн;ЎuЧЮCoдДYC|щzг7)ћ™гfТ§šЋЏщбНSчЎ=(ˆ.рЫ›ю}Кг-i§oеядсќЛє’K1дƒЫ\IнКuћќ“Ѓ@Ј7€м­‡wuЪРџŒNGк4ПсмчЎўхjПзЮвХK§›__љняќp`пŽ]Ћ‘7аpЧчрхzї—ча•$“УsЪ„)-›ЗМЁч зЖНі’Ы.Q5‰ЯфpрєFз\j+јVЅањMн ътbШр!†Нuˆ_Ъ}њПŸЊCO?=ќ'У Г1wxzЭг†2ю[xфШЁAJј№§;Зы yчžъO‹ МЂе‹šУ@†™@ЭГИbѕрŒлЇї[ŠF RФ—jd‘Ё Р! ,Ў2Ђj Т—Z[f:‡њъМšLiEЈќƒbсK•…uдќVdН:9}жA, щD@^8щD[rE…@њ~ЖUХGA Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A Ч­(Ч&TкA ћ­(ћцL*A ЧИ T?ШЯ/х%Ц‚€ Е M›пР~Мхp[Qћv9‚'KA@к†і!Е_l<мV„ ˆ*AР:ФLA ж" пекЉ—ЦA@Шd+Ъ”™:A@ЈЕШVTkЇ^A S­(SfBъA ж" [Q­zi\LA є/шvПЗыШ‘#™RОд!‚€ yЄіЧмjъгћЦЬk\*A@ШдŸŸџЫŸpgE8Т>TЏ^НLiWъA@Ш<ЎМтJмš'јV$пeоJE‚€ д2d+Њe.э ‚€ yШV”ys" ‚€ PЫ­Ј–MИД+‚@ц! [QцЭ‰T$‚@-C@ЖЂZ6свЎ ™‡€lE™7'R‘ Е йŠjй„KЛ‚€ dВeоœHE‚€ д2d+Њe.э ‚€ yШV”ys" ‚€ PЫ­Ј–MИД+‚@ц! [QцЭ‰T$‚@-C@ЖЂZ6свЎ ™‡@8’ˆЬЋ_*Ъzr•ŒбA&-g§Њ5 ГC"йџe+JAёOѕІ E‘nЮф§#н)k:ŸД\г3ŽќЕp–‡UЮŠЧN<A@"A@ЮŠ"Q‚$€wО& џ”Л~ЏEЋџМ/Ъ4пr”ЭЊX™дђŠUХуЧŒŽОG#b&Еl”ІЃ_оzєРВlEЁУд!рНh3ћ‘H…g]-%а/3ŽЅЉх%ХуGЙі’Иѕ4Њ8q< авдrЅђ1Т­FgЫ|їйŠмјШб”#€ЂЕњ~+Њў› .jлёКћ'нпАqCRЉy‡j]tяб}хђ•zЕPюћcшЕФМєМqфˆZ6В—ыšбЃFу_Н†Žѓ{I\LdNѕ:”iЫхххЋ–/{wчžгЇO6ЛВеибcЛнаЭŸ3rM8(ј–“)LЖЂdапF ЂЂbгnzy§ЫЯ­{ЮZ Н_УђХu/о7§ОчJэ–Vї Q^|ёХeeeC† I]=ЗН}№їљAŸzѕъЅ.KТ‘gўћLн›cR–q є€™ Ÿ8vbЬˆŸŒћйјщГцдћFНƒ\ѓЬЊєlE™аОќl!fAj‰РЙМm[ЖM™4eр€џќч&M™зяАјЄќпў[YтeїŽ]:vlпqм„qиЈЊ"œЫ[БlХ =oИЁ{ЧВчKАь{SпВчЫ НuсUŒ9ЬyvэГјШlMTМв+Ьœ=ѓь/mб‚Ђ7’1dhд9"ž•@G• $№,Р6/ЁOОЖl”‡Ёк~д3'AРЄ`FJзoмА‘ц‘ 0бЫМЃА%…нї‡}~/:\ˆАхeO,5fќЭƒ†xŸ.ШЛЂхѓёnиЗ\1•шКoџОлЗТ‡‰ђПФd–БЉЈјЁž#lYЯ+[‘ކШ5„ој‚§;Ия оUёЮЛюљu?шѕƒпўfыЌ™ѓлЗnowG7БА'+№ідюкЋ”fЬЯЦŒИ}ФЮЗvnнМЕeгя.,ZЈєХЋŠїџзўWўу•пОЖѕГЃŸUЙWЦй§ЮЖ{~zЯŒŸ1Єp…u n,c…Й"(›ММ:uъЬ›5яx•bJ%”–№GЏр­[Ж^xС…Ы—-‡~ъФЉ/ПђђЖЭ› oкМ 24xѓEExі_v`$чzѕXїьг@8mПЅKUЫFy*ЌЎЬЫkдА‘WI^fvXсА)“f^ёoWькЖ­юu•^МёіКtŸђГ™Ѓя}ЖЂтт:ЋЃИч…ХKOPŽЎхwп}ЗЯ }Ќ№rЫЩЗямОюЉu[ЗМзГOЯЙsц*wы2Ж.…†5)ЋtЗœшQЙ@—(rтWўИАIAМсЖjU§=ЃVзV›}ГС7Ÿље3Ъx§КѕJЈsAЛ:сІ7ЉсKЏОДцЩ5ѕОщ]Є?qЊRтЙlCYЩ“%ЋWЎОт{W2BЋж­КДяR\Вbє˜ёzоg_~iеђUЊр у' Мuрд)Sё™zщЃK‡ўdhс/§њѕuЯЌƒ&Ш{^ŸмŒћіэ›ўРє5kзЈ ,ˆoJmц?2Ÿт>šdИЈˆчŠЯ+ЎОќъ]лЖжћзzgЮTїсэL8Ѓ:yBћінђ0њЛчэіђ,вў8§љIюъ(З\Q#ޘы|Ѓ„;‡ољфђeЊjы2Ж/•ДЗЩ% ЖB9oб б єЄџЅџxюе_П2aт„ЋЎК|PџСн{tЋSЧ{Џсћў№ž:tіяgж–НИ`бм•ЫŸ€fпОƒK_њбG}љџОє МзWУбуG6Ф>dжѓьг%…ЗєПт{ўCž{"3…3†g<~ЬнЗ‰‹Š­Z]]iь)?џфhџ[њWћЦЉWЏ. ^Ж|еЯџ§~ШZйЎМgЯžйњіЖ ЏПќбGЙЙя[њ дЋ“$*ЙRЛcпХŒН€и>ё[И3ч<йл‚bTкœэsCїНРЙЖЂ;ф7nTЉw{)“HžCД|aƒoVTœPŸ*Œммr…YoрIсїЅwšшЩжeЬ-иG:Ы•ёТ?ЩV3ёˆЪ+-AЂтЄdъФiSЧOлЖmы†з7Ь_ј‹озїОЉп і­еЛГ/F,2vЌбCяьјЫ'е |фŸзuЋз@љБуЏm|эŠ;†љ[еї‚ЌWu Rt-wэиuгц7†ZЗ\НњЈYUlхаКŒЙЅb ЂBqЯю–9ЏxzљЎ(Br<еќУћ юп?хuИЁ;оd_xёЕІЭ[.]іАе…“ОтяgŠз­mжЌ™вœ>}кЛVSЗnљ‰уѓ]H–8Уxpб‚ŸWРОhхreŒЃuд[ѕфš—^~ЉјйЕг-И` г2е†tђ XИпlХZ+ќQсŒGФћ,އо9ќNeŸўч[ oЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ \SWЖџН7Qœ ЪПЄWНЄкŠЕ-Vg@Д ZET;Ју(V­XДТpЕ*ОEЊЕ>ZЏМUkiqЎуcІьёQ|+SZгVХ™Zr}…–ЬMў?§Џ“›“““@’Уя˜O\gЕз^ћ{BЮЪ>ћьнцNE‡ @@@#№3Рqр iРч@@@Р%H\Т#РKДaaєТ™№%ƒЁ‚^ЌFь‚> жіЗxIЇ6mк o`Б@Р7Д]uтП;ь‚ћрсУаz> mющ :7”4а‡ѕЇŸ~2 ьS @РЋ„ЏEіG‡]Ђ ТG†жѓaрЄNђс/я   рy{‚qС} †€€x›@`' DyƒЗ?"№  €OЈШ№iPBв@˜7јрГ‚*@@Z9…$ t‘7Дђ2šо&)TСoзиLџ~Ї_уи‰МE*u‹’z†Bи\i0l@š@ ќZљ‹П™ )hџНfЏ‘iТЎЃЊЉ.і"ЗоЈК бк‘поЬЋOСqЋ-ЎWšГsшШиЁ#GэЪйщˆƒ[U;rвLНы-jBEЎ;o—ыЎьу|9užѓтэ„2Тьfaa:цТџ5”(Pя‚А№ДДџЧŒы3ІдѓХўЬ]JЮœ;мu{Z:ЊZ_Z*ЎEВ+>дВВЃј}•ЇрxЃ-……_”ЩпW@@,џЗG 7.оŽ7ЊЖЏХЙЦSзтќЈ+Иšч‘OpџыА~сћАЁЇA2Ѕ•ѓg e OЄwŠS|cТŸcN"$AЃЅhˆыuE>sђич†Иb)и\,Н05qJє€Шб шkŽЄŸ’єƒ2:&vХкL‹Х,шщ—ЭСCFŸ1 ЎџŸй“рbеьч‘Н7ћJ_L˜`ИХЯŠmКkЂJщdњN$= ••Цз–-KqЮ_МаdтЪnŽš)6–џЁyнњLђ?tЬЈМ?~ ^\–щ…$mьCnнFціsхŠ:MtВш”M9ЫpНœ• ђmс8{ТBєЮЊ&?ВUќЉ№уЩ 45є"vХ52YОъРФшm\Œ9 єщЂЯ}вшƒС=ф зы>ф ,џЗpџ[Ад˜поБ=cѕRvШ^ oьКЄ~џ…uЗYаСŸ5”+Pз‚ј7Ћа6Žтьˆџ[–†8WdКj~gј[DŸ>Ў 6‹—Џš7їеѓЇKswф|љЭA™—ћAй•Ыљћі—ЕWsYйYЬaйз—їНŸЋ?gгy@G›P5•{“­tPь№K_\"Ы“'K:ќS‡“gJHОTv‰є$$/L›9yЪљ#E%Ÿѕ~ЌћІьmЄ”нd›)ЖtіяwўxЯ\TXџ_ћЫОМ,."+; Iмиь];ќ{ЕріlщY{WNќœ§KйОЙ%ŸŸіќАŒѕьЫ:j‹,aсЧ.Н‹ѕЪVё]љ7сO… е…‡‡їн7ЎW(йUœšц%\т*ФЫJЫш3F њ`аЧ#ЌЛЎ§Я:],у?ќД‘аОS'R’œѕћЌiSЇ…uiИс`5ixОЕЄ3B\ЌьЌвз :-ˆ™>‘ьу ОЁС€;ЈгђФщуы_CbFпSтKeъ6˜§ђь1Бєѓ‘•ЂВ9Yл„o%Кџэф&”:UtTlЩŠ8Љšй@aАЊI{“­”z><ќщњ5Ћ_[МАћНЏџѕђ[›п^Бvљ„БЂ"ћ‹=SwШЈјё'ŠъткЫъ’mІИИЃјЉ`юЮœаP-Wо2aЌФГр„U$і) ЩІБфvGNh—Fм о$~J??Њ тOщc‡ >o—Р9l‹уг*ўxP[dЋ žqВ(йBuXu€`ŸGй$5Sl#ьК…K\œЩ$§ш0ћ<ܘ—ќIў‡ѓ ЪО<Л~ џчМbеђ~‘'Ž/П\ўцЖ­яў~‡}$Єo З'˜6{ŒY№LФV fvњH пазтHІŒaш чeŽж‰ЉзlлВщьЙГуЇLІЮЯ“ч.woоћыК*аk№№сUwЋXIйŒŽ:Ќкš(а5Ix1?‚ і&[iTП>п^њ‚ЎŽљъ›9‰гщф/.}еЯє—Ы_ž;nOаwnф СUџhˆSR‘l3Х6ŽтПaМ!d d,|Ї‹KйЫNB7–wkЭЙuтGШЈ JЅО_k‚Уs!KXІ3LEJвœоOіІЅtЛоћ=й;iцСrшi‹гЃEnЭ~{ѓЏ ЪФiгћѕэ7#5™†ш/]•>tШPYЗLщЄjfгЈрЈвиБUџИпП??"Ж’cЃboЏЏ^ёіцЗ#Eޘ“мЏoo'UШ6“й;‰NвœNе#ЧХгРŽ~ЯєІaЫXБьиёc4Є`Ъœ#ы’:фbH)sSмŠŠГ\єУь™рЄ-Ž'ݘ3)qКЃ‹ѓLXўЂп/ЦO‰Ї іЯ[:Љ:р0RЋН‹њгgŒ>i‚ƒщVPвэ9s­™^$Hьн•„lД @Zšгiу››ТЛзoїeл[Аj4гХјЉK&yAк'‡>єHЅ^rтb[МQЛ‹UFo№qтгЩ]'ЅœBврœŽ‚€€WdoЯš3sŽЙж’ЙnmїЧКЇЬOѕJ5Jw ŒNЮА7’†њN1'ет€€€Ї <њшЃЃ^џ іAм8ъfїДћжт}|ІбгрcрЈ@@•Bъ™Cм   рcH| е€€@ @вЈgqƒ€€€ i№1pT  JРзOOаœВќ*œи@@@‹€лICѓЏњ#тF#D    @мK(c0ўн˜єJЧёK\ИЛэz'›2йIьнu{p/i ; IЏІpЕДŒiнJІ>е€€Дї’†К(ызЌkЉ Q/€€€€я Иџє2пŸ%д  ~@ )= И3с'!€€€€Џ ИпгрыQ€€€€_@врЇA€€€€џ@врџч‚€€€_@врЇA€€€€џp $žž№ЩYе_.їI=Ј@@\%р~врЊgи5—@мЈИцК@y№З“ўyЫ‡žЋžœ0 Nу €€јŽ€gЦ4є|ВЇ$d{ФЛ   EР3IƒЄЭƒЁУЯ;H”иhnпžД–ѕ(0 B:‡Є&ЇJ,Б    аš4иЬ"}эЪ5j?e ‚рSэh}n•ЙжтЌRjїpЧ@@@РUю' rЃ [ c жвњм–`­VЅRI›[ЫYZЊF–1‡hT* ч~sy-Гй\Cй’ХŒDЪћ  ­…@ЎЂ„ЦІГі{>aькННвck‚Z­2šTNYд”6№ќ;mZ 7ЎЏŠ.ѕ*ЏЃ2†Мsc•А'zЗц@|{јФњNiЩЕцЕ\ћvмЃСT їЌNзWc1™Ь&“Ј0DhEš–4H‰ѓ“Щ”ЙnгРшR#/эЗу‚ƒј\Aмл nЧY,t‰7…†ж% Typ;ЮTп\жaP—ўШe ц‡\u ї­бќрЗы%цM351au94rOФK-…[hQѕWQЗ‚pкEЏ в,YДdЪKS&Nч–зІSЦ`m‡Ѕ>0>'ЈЅKЛMˆАУвšmЂ!cАД–Ђ>ŽњЬюG3g6ѓяшeU&§о4}zбЏЬмНІы‘’˜/в#с”D€ІƒУЬ.J:Ёўй–&% 5EЄО[yЃ1+ЯЇ vЮlђ…њЃ,c ^~Ћя` ‘Yг3Ѕ М`M(i пNЕмЇЭjupврjЎЦТЕЕjЁ7ЬйBрQ-ј#тЯŠ§1,ФЄ8žOшЊ›ЗїƒЧ—хр%ztYoИ сЄJ и(N!] ckЎ $hДуУ†:D Д=`>­Дv~nйOЋх т"ЬФ—~Uј’6ъhJв`џ#>т™†ЁC;юёg"223ьЭМ[ИіS-LзXmК [яGPЪ`НAжћueлqэ­ЉƒиеЖOLл'ЊLU&UKщŠИ,dPю' vWPjЙўko>(!‹–…aВ!' %ыT`Хiщы“Aе‡)t4tX,мЅ[\Щ%Ыо fўі„ЄПќ3жj9K%’F€€п0*rvцœ>џ—Њя1oцЌ˜СБ~mDdЄОДдoУkхй]]ўщq‰†„р!gЂ1ЖЃ ЉYЄc6ќ}чјKЊ/–^4ЊŽŽЭеNЅVЉуŸв$ ŸџЎщ›2P.|gщЏЁg4žъ”1‚ @Zš@х-cђмWц'Ї,Y”ЎщЈ)//Я§У{ўœ4Д40дяŒ€лkOШпtЈхВЗg5:КoН“L?ш}ЗYo(аЦjz™Иыем{2w((c = ёу=sЕЩ|ЛЦ|›Ь,ќxˆАЎК№юК№žсuЏюКА.ZўЦƒЩ№Ц4ы”P”\йОЎVr4?l€ј1m;sfЯN7>^Ѓба№э№осы_Ѓ.о‡мК›‡‹Ѕ Ќƒ–~ыцŒN˜95qŠ^щШЇG^ќЭ„ш‘SgЮ2\ЏŠЛhFЦЛrv9*:&vХкLњ­еPМаZKлrв“Oс]˜Ѕ рНХ И4ШFМn§КыНžЛ'ї|ЉžоI^ЗqЌЅ7””+мЉсJЎS6PE9ѕ4H/чц{мmЧч &юж=JјBj$ŠO˜*\cyК›Z’1аюэПsЊ ћє‹ЪA?"pњќщЯ” (ћїY?ў§vўŸ шuћяЗi—™-=›Л3ЇЄјд˜бc“вRNœ>žГ#ЇфѓScF Ыи˜с–Y^юeW.чял_R\д^Эee‹jљKйОЙфvиѓУ2жo ЗТ zЧ йЏЯ$ …Ћ3V‡v ЅЋ)Н“\№aoкI”+мЎ6WEй€љV5Ÿ PkŸ PnA} t”іX?ВС• iђЈіœєE-ЕP^тЫWb… €иxpЗJгYcЋЋл;\T˜О z h[Г §pбQfFї2B;г$§ъI'нџЧ}ёю7_6 bы™э§шPњт4ŠМЅЮM+™ž&`4юћvЗ%”+PеТу‘” ШoД…е†яsd#_’ŸLšяiАнxЅu\„­{  р_кw1н5Щц 7ŒUЁ]ДBИ$м5о`ЁS!ШBŸЋxїОш+TЌ'{ё.3Л{ѓЦи˜gёз)ѕзВZ˜}ƒ%$џ#р™ž†ЄI™ы2+oURщdвјЈБжT .c *щZnНœЫдЮzснщM4jСТЉh&щ:Зт‚2@ ~G`Pє #Ч‹dУъІ Ёa’Т!:kCdЭšЉьЌэvЊшЈpЧ?‡'#šIД%‹ЛŸ4ˆrLјЦЭ‹Ž 3<ЂoН“L’…3ѓЂ`Нœг3ТK>oЈ?ЪЬHpВk4jvKБ…2qAюлƒЋ0TЈ]›VЪI-8 ^%6'yїю]……– u,ПVОbеrЁЦБ#ЧmмК‘–щЁmэжДыHІMNШмАVШNh%…t^KHч†[uc-Kё Hчeqдлœ^6]Ў\/КХхr!П0&gаv Ѕg,Y@*ЕškЋ2мх2YјnЙ-\ЋВ”›T]ƒхB ўB€ю;фќўz†bЫl~№рўгН"fЭœ%—2wЮК-Y#_ŒЇнјQёДы ЇM'З3R“щ>ХуO<1+щUчЕ$ݘ3)q:РPч ZфЈg’† НЎRkƒ4йfЩYžПE\іљъ;W4NЂ>]sеEЃюb:bЊЗ)‰пИXzЁЂТц‰oыGm рu:.*В3Ћ гНХГћjЋ^™О˜^bЩ’ЋЕЃ]GzС›ј(х Bъ ЎHl ЎдоXb)vйЧф.‰ю‡@З!$ іїНК\Ђ]C'PFКoеђJ;ЫПмфш%Пй3ГЙ1Њ‹OjЛ>* bzО$ d §cќwb;_в@]J%pсd 5­љyƒRљ ]>&р™ЄAДС`ш№ѓЅїv…lќЫ6‹V‘ел”l|ч]ЙАvхnVєjnњпxeАpL€њ(cˆŠŒrl‚# №hЦЙМww!iјЉ”4э*к0 BD_~і.кЈkAш†БЄЮІ{c fьйg"d•nє”–[ї‚ъШсђ^ссьс"7}Р@@’€ћI==!*Єџ’x†RAhЎgЎ[ЪЕdjUтюфg…jЕZK‹ccжD@t§wНйvO]ђЃTь”ЎћkІЅ§““іЊBxTВiuщХХіTUwђР*t]е……a4CгH* T›6m~њщ'7ЄE*ѕqQ€€џp;i [ kHзЗOі!ZпŒwUQ \o„х/ДмГ]эTзА>]x!<”Ц_МzŠfeрž яЊЅE_d‡ZжуРџ­ƒ@ \Ш%ЮжёЉA+A А и]E]hާP…Rбкч4IШЦ-FД7sСЗ‡Ld›%ЇЄŒ!иXLЃd;' 4gCЙЉZЃ юеCGfзС@љ\ьѓБл7П-&KJпЄtтJ•'{ЕПСѕ+§Њ5Ћh%!Т›–šЖbе {ЮЭ‰“І~ЖџГЋhŽћ PюЯйXCщЪJ+ ьоГЛ1CЇg"$/GЎ%fќУmљЩвЭ“ЊкўE7ыК„ѕ‰шC˜CCљЕ[yіg}pЧрƒљ>Z?ЬŸ9(2ЖМїѓЮœ<ЃџZOЏcЧбЎg›I иІЮOѕЌOx\žOˆ…*HE3љ ]ћэ_іеллЦ:жAЋбвj.2/ъZRhЎРЌ^Дdяі 2“ UV_[Ж=ђтo&Dз-{прjWЮЮЁ#GQqšVМPИь+’—‹Х’”œдБcGZju{жvњБ.TФЩ.=<ё7;vъиFеfbТDњUЭ ЖџчіЧžxЌЎ`-GNц–Ям:ёГћннМU›ч>Їз7Ќ ШЪ’ЗѕЏЏЇ€ЩтŒDK пC'ЅwAj”uЕчН=™кP-НH ]ћ№˜‹PŸ дrtЦi—w*+жа|У…‡ S^Ma>!€ДržOЬѓ}Вс LЏ#ЖЫд2у.h••KЙ…зУѕu”їdЎ\О43ƒІ—lЩ гfNžrўHQЩЇEНыО){38[z6wgNIёЉ1ЃЧ&ЅЅœ8}œњРiйћ1#†elЬЬђr?(Лr9пў’тЂіj.+;‹oa]цКъъъ›†›зООvќдёFc˜0~uщWнЉ2п5wЂћk‹_cEЮž?ће…Џ„>љUЏЏК}чvл2nј9ўљёѓgЮ›џaNјuBђќdцŸ om~ыLщ}ЉОЪXеЉcЇ•ЋWв!Ё^zСXжељВѓ§ћеЭBѕ70ЯВТёЧ Е…ZDэЂnЖП!юŸиѕюЎфYЩЄЇтЫ—.§зU*‡ƒ~dЋ€@@Скмqgоƒ‡ФOHфкJ‡+DFжЭжР“jЧE<БlХВ№юв)– 7Rј>ђSZ…виNЛМXO?­jzwƒёVEXP=!ЙўœЊЬ(ЕœЁъUs‘nLШЎы‘ ›цDЙIЗ!Цw№Ѓƒƒ ЂŒєi‹вrВrl c' CЏ№^;BіGЂЋ„ысйѕrЛ^д+–іS6йkЈbRЪъН“џ9mЫНЙ:#myњОняБр–,]ВpСТиЈўt CшQ`‡\:kЛэЩѕŸN]˜Ž†дѕ4ќЗЈ“цŸ9ъHКйХїя'%LЪўьA]КтЊ;ЪчМлы†КшbЗѕŒ\єSonѓПю_u”Еˆs›УэDї‹ОPv!fp ’@|ЮKˆЂ{Д.YIћ]ZЦк Jvdяјїmџ.x(+-ы?АaЂtt68ыЗGiЖuЪтЦzeЭkПm5ѓŒi0о4fЎЫ?*rP$Н“LяE,ч™~fI^rVМNbfхрШVqzzdк‹ ›Зlb-{№р-N•вˆШЬ7єЬРЙ0mrBц†Е•ЗјгmИ^Ac!™}‹ „œž8}љВхдЩOЏ…KВ`ўb %”7+ѓ7Ÿщя?ИO“{R2AЉЦьWg3НD˜>s:yЋsЛЈС-3sбГ'ЎСТ. Hœ?o>@ЗЪ/—гXHAO}t‘•Ї&NЭXAэЂ lЩc2fUˆ 64dщBj—p(fHЬ?ўИћнъŸЉ#"ъвК9Т62#Yь2€@ы$амЄn‘О”єRя'КяoщщRz'љЅЙ/‘оw@ЉЛФіe‚‚с•і/пEщ5бблее,”зWЏx{ѓлƒ"gЬIюзЗ7гЛ(а Ж§њі›‘šLOU,]•>tШP zЩŒFRoAзАЎ42`р€м?зе“ѓNЮЁ?Ђ!бЯE??фyVћЛ{оMMKmѓOmb‡Х>?ЈAЯ aхђ•ССС‚лч‡Ъ˜ЙшGтVи}mСkЄкЕ™ђв”)Пž"шг—Ѕ?ѕ‹Їd/ќb?Г_ž§\ЬsдС@/_ЊЫ9Ф6bљљСЯiТx IDATj ЕˆкХQ‡=xВtсRІ іš4RДеТE щk4~\МиuAa]ћM› …Ш рCЏ „мtV\9/їс&u‘„|ЋLuЙJj9!œг™”<Rк`эл„7ŽЦїљЪeБВ•ЫИХˆ€f„Є?мžФѓюЗ17ЗЇ†@Žˆ!iiJџТ/dхЃЭОџ€4і›‹fіЁ ЋVЌЂ/YъЋЇЧiъ…Р ‘‚€@p?iЈѕГV5slЃlzсgMD8Ў Ч#{іюљxЏЧ%няЎ{€%€€€#ЭНfFˆsgkЩAe KЛ}ƒœєB99$ёуКЅЄ ьnsRц”• JF IIƒэАšЁyѕв%Ьc`k#=ъб}šВаХ5ЅјеЇЈЃ›"шtК 'KhBCEДy4‡4}дх5IЫ.эИВ6‰_k/дЄЄЁЕCCћ§‚@T$?_!}ЅњE4МC€2сЃюї6^i%UZЂŒцЇљаhvaІ/–[-^ВhIйЗe4щКеыь'qн’f3[ИxсЇEŸжмЏI—А{чnЩФВфŠ"оY–CыСnлБцМŸ0aїюfOЗJЖ,kЇУЊi1лДд=Й{:ќМУšek˜=ѕOЫъЉ–ьэй›по\ёЗ !BУ#Яі17Tg/еrЋжЌЪй“C‘ЌЩX3џеКщщdO–ЃжQДЛvяВ?Й4хЭwЗoя>Ёе)ПKqN›ЂkJва0ЂСОyа€€ а—ЉЯОO}и,T-C@XI5XL3ЈвЂЌТre,”ЉгЇОЛѓнqЃЦб#ЭыжЫ$ Ў[вТАлВЖэ}/]WfЎЄfщ’ЦŠ“@—.КЮБ iиzАоЂ%‹h&ЗЭom&Н}TіeХžUЭГ%уйsS;в“™АЎюИžlЬт%ђњ ыПјњ ZWЄоВi ;*{ВЕŽJЩкГ•Щ`іМ†V;j™Й=Йгˆ_%rэL,nЗ„#…ž]хВЁіvж•Џыі-f—oŽXчŽДN&ЭqЙ Pe\n•jЗqЩЩšuTиљбЦНУ@@Y}'8™мIrUІ]ч+ЉвŠЌЋ–Ќ7nœАЄ™=?цАQKqYёГb=ѓ&(­+[—ЄЌи­XWэh1[GzЊТf-\ЫеЪ†'Ћ&–Х gzЊ]іd1Ф­sdЯЗNne`qЅтеwЩ­ћѓ4ˆƒђYнNЌжhB‚5ЁZuH0ЇжШN#- –.ќэTъ kСЮZ*Ўц 6і…ЕTАИT ЅЄuc@ќŽ€ьJЊ,Ъ‚ƒŸ§$ЂoDя'{VЬєіBЃ–Д0ь№‘У;vьH3zzэ‡л?и;‘h„ѕ`ЩžЖр`VЄбК$~Uэh1[Gzr+^gЮ­№мŠ™nШ.Ў+{ВЕŽЂ•ЕwД2АЃцŸРN(9 g(Q0ršТ2nћg–ч8ЃYCЉ€ѓЫ?ф/ќЁкK•šƒљ‚yчИђ{Tайу—|)kvRnЊ/uŠ#j %e’O.vA@  PКp№+++ГЖg%Н’ф$іF-iaиѓTЋшV‚љžKwМi §В'{Ж 4Z—$NGU ‹й ЦбbЖŽєЗn…чVЬКЧuтx$ѕJvЕNbЦv…•…]q-ŽšC–4PЇ]јшЙ'-Wмїщ%ѓМгЎsjОзСQЗЅA3ЇЁ\Ёф[KEї}їсцфг–Ѓjug­ЅИ ЭюS\Q™ЅЂ’/EеЅНgZєGŽ вrŽЊcч€,ЄйIДЄ‹ѕž,wџя;iGЃ–Ў, +YшебzАВuIЪŠCuTЕЃХlщХ>Iv+<й˜Щ uЂHмвюœsц§л<у-#MGDгфлˆ5ŽZ'ЖЫŽVvд*РIхš ѕюЃ|К@]ТПЈ0w‡ћбЬe™WэЗ№Ѓ<ЪфАДДJЃйuТ"Л|г|њЊљ›|СМгцEя[ЈћBIv+<й˜щЮТАч‡IмвюŠe+žzђ)ъœшйГчЃ]Е7kЕNl#–­ ьЈ9T6€BЊ;jLЕšЮђWыЫ7Й/nšдlЯq8.О†ЋвГ9uЄшƒFsфšцЋ KАšЛr“Ѓk?‹7й‚TŠюDPЯх"eмЗT]}ЁКЌ)špuЙ‹3FдuјПЃaMBчG:Х…pєрd ЄBIjГЦŽЛtљв˜С1-еWnRO]››іђ КY R—|Чg е5мѕ*Оз }ЛК]зI.а[(БќњЇЉЈŸ2О ™ћЮdŒYYО`™Д Ћдъ >cЈЖpЗmK >г[TAZфТƒ­„+ж@р№Ч‡[$cpwe`ї“†њ_ѓ-~U*•бФUзrЗяqј‘взeЄ2зXlCUб5ўN _оЭTШО`__ЅBМЉT4f‚JQЊAьK}[E}СвRbA@@РŸИЛ2Ал“;би/žЈхBеjTпWYшBоžžАkJ?gИUI+WбУ&ь™9‹І–рnSЦ`НќЗЇыПэV_АAЫЛАX‚5мїF~шЅ ээ’Ї_„qЗ*ЬМSl   м]и§žП`ЎЉŽ чn›љс ќvЏјееoП’Ў5AйF)К‡ŠЯX+_pDoUХwWm ђЅЬ§{ЈЈ:GЅFіQ•[Юw\`%фЄСlбЊ,чo7а^rП`Ьг*“AO—pMPC7ƒpЭ5цq\w-SУўFУА^œХЈЇA’‚еfSLwЎ{ˆ|Љ1НИ`“žђI)%~fа&VJРЎOп)~]СГšјє ]Є_ЂеuVэгл \˜ЁšСўщЊЎ‹Юўq3­‘}зИrЈvЫ9юВбІршpUb_юШGWiЪ iСZŽfг\ї+Mі9юьM›RЛЊRpG[KIжуі)VWйХв ­Ўйhpk"рЫЋZWДЕ‰мKш :щеЎЖ‰ЗэwНГЋ‰a:(f6[ЬCLˆЊџXmЩuюjз+„‹эЮUшOцН_оKЊ•v3žЬї,œйИЈŸњ’ISbрюTs…pёсœЉќdСў mзG5!2ЭїLfГ)ЉЗ*ЖЇЖф;юrз›ЊыСЉ+ѕ”1h4СДJИƒHЁі<!cшыyз№~C€жЇXА0›пœжˆ{IOKxивЏИбS•Іђи .О‹Ім`И№Y=!љьS}BCД\[ЧжZLU&gLъЉЁЇh юK'.qœЙW^|ЊбжСаъoЈ1i9SbMp_Њќb9uxPЯe вЮ Ч•уHѓ P KCTdTѓ]Сј-№žсДў;’П=A­-0ї“КЎњЄЖ4ў€ŸУбxЋR]Ыѕ яЅЂч1\ѕEС 6ІЊЪJƒС\Kщ‚ŽF$ЈЛП ”В˜LхЗ єЌ„ЎЋVоh)QЕA@@ 4%i№Я†вЕмz9—Й­р<`~ЪHzЙЙQ–кXzсІK˜ƒ€€€_рЇ'ќšk)Е#НЌ1”   &€ЄAС'MOp?iА› б“сР—wф§ё@Ф€HzїŽ{?ђJkЫ ›8&ZR6qFbЧŽCЛ„ЎпАž*>ZL‹Ф№њаPZЌ–Љe‡ФТЊ5ЋШ€ЖѕЏ7”ИшЇ>4™еoХо ƒ€€пp?i І5-uЧі=эжTзPW„ 'с‡ЄeХEœј›A%р~в@А§іWн­ŠˆŽЄєNђў?$„Уx#ДKнМзL CŽєtˆRжєЛ7oŒ}!w9xјpђ,кЖeгйsgЧO™ќbТ„“чъю†Ш*™+o лЗnџБњЧЎ]ЛіьнѓБЧг=ЊзxђдЩјуїялж=LЌф р KMнR#$<ђШ#і6‚ЦЙGЅ "аДЩай Їј!w0П№шЧ‡щGП1u3LN|)%iMАнMл­ђ–QHH`MrЄg‚аYл­hOЎ8є4ыэ[о ™Ц1Ќ^Нъ“?#YV)ићр‚Ьл[7€‘FAЦХХБJ ѓ S~—R_б7‚)ХBtПш ebЧ’„ˆgфЭѕ#і @”€ћ= ѕ эљd„ѓWН!ўo1GŽљхГOГŒт ™4Є'yьШсГЖYћьMЗndQ:в3A˜69!sУZ!л0\Џ Б‚žƒЁ‚ФІ–{Pџ€ЎЌ’ь}32u~Њё–бbБ.\Йšџ'„К§?ЗЇМ–RT\dŸ1ау‘‚ =R‘Б:УXiЄ ГfЮєєЮl\ёУJAР%аЄžы•рšhD§Œ;[Z–О8=,4дPYЙqУкђK[akQ{ўaСмy’&$LйГkЧˆ_H™›КюЭЬ‘утлџЌ}вŒЄЂу%‚Ѕ#НФOтДщЄ™‘šLї)т‰YIЏ C‡ L[œ~ЋтЏЄмќЦыN”‡йerA ЇЩmє шшбЏњћсC ў\РnCЄЬOЁЃНТ{БЊЭїЬlƒ œ§ђья+О:’ч%'О”ШŒ™рŠ2–9 ўO ЭŠ зЃЄ'юg$бкN’"C‡ Эџs>"G?^ЧП8ўФБГƒ{ѓFФdf’Ѓиа_.g4ФJ&;?ЪЬ”-аЇЋ\*ћЃuD€ОNi•Ы‰ “œгpє@&”ЧчМ8Ž‚€‹ў‹v fr§ўчAƒUВзH А    XмOфк?.>3#ГђV%Єw’I#g€€€@ p;iо™А6|хŠ•ны>cж PFянŸшNš@E‚ИA@@ф4i ЄНЃv\JZ Нь@     MJф†5(Z   рˆ€ћIƒ\ЦP~­E-E@ШњЧФЖTЈ|@€жЇZА0›PЃ WˆЎџЎ˜Уќ†ѕ1PЦх7!№<№žсДў;’Я“…Ч&p;i .еœЭS—MЊ…@@@Œ€лIп>Й5ЋЌн@@@РMxzТM`0їЙЉЧ=фn@@МBР§ž†ZЮь~!ЏФЇ   >$€žТn‰Њш§ќХ %57њ+ПQ‰C?й->ZїМЗ'#3CЊЅ Д+ivA@ љ44ŸЁП{PЉ3W._š™Сй­ ’—ћAй•Ыљћі—ЕWsYйYд})?•'Н ‚аМГЅgswц”Ÿ3zlRZЪ‰гЧsvф”|~jЬˆa3›ф…i3'O9ЄЈфгЂоuп”НMа/^ОjомWЯŸ.Эн‘ѓх7WЅ№~ём…WцЇ._ЖpbТ$БОљђЩ'Ч УќPЇ}U›оЯє~kы[LI‚#Ни†Щўьѓ|йљў§њ Ё’@§ ,l  р)ю' єМe“_žŠ~м$бчЙЈчvНЗSRnяG‡вЇбяr•J:7­№hБФ€э.Y”кYKf“&NКџћтнoОЌЛ>§9o_DП>\[5Ѕ)s’цœўќДPМ}ћіЦ*ъw0…†jWІ/f>щІЩъ Ћойž3 aVGqІТ,нєz}jZъŽэ;„‚tЂВВђ'ЫOљђ9ЖjХ*чzйъќмgMu uБ‘“№У?ШЖJhї“†цд†В-G %iЮБГgшЮ‚8„Л7oŒ}!AИ1xј№ЊЛUтЃbYЃбЛ”7 оН_?o‡ўrљЫsчбэ r9hpе?ъМmлВщьЙГуЇL~1aТЩs˜лНяяNxa"MxЧ4Nž:џbќў}ћУК‡I†їїНwsvцИЈgfўя3(8ШRc&с‘GaСCOpћщIњZЊћ9уЉрЧ7кroЎЮH[žОoї{ЌТЮкnE{rЉЇiš#,YКdс‚…БQ§ЉЇ†GPо xЃДр­ oLƒVЏ^ѕЩЧŸ њїvцЮœ3Cн18ё7Л7Q˜_˜ђЛ”‚ќ‚ˆОВmQЗSпџпћі‡щЩ2 |Fї‹ОPv!fp LBФ3ђЭЗo84  р:пѕ4|X@ї­й/TзC„ЅЇ„…щІН˜АyЫ&цpкф„Ь k+oICуi,Єp(ЄsУ-љ“ЌЌН№рСЕšSЉе4"2ѓЭ†ZШ-? “FTдrъЛ%Ј8%+”7њгЁМН0oЭЙ§?ЗЇМ–RT\$ЩшёЫђЫхTЛС`˜=gіЌЉГ„ъщщ(=)иŠOzT$cu†БвH/fЭЌk# @šOРеžЖqIqхъеKзќpсЁ™(oOл8m:9œ‘šLї)т‰YIЏ ў“fЬ™”8Ц.И5Трѕе+ооќіЋ7vгv›§ђД >М 20mqњ­ŠПR›пx]м>ox'gцќdКЂ'ЮрƒiЮ–2?…Šї яХœ˜я™щџ„&LyiJйЅ2нЃКщ‰гWЎ^)8вГт$ŠЯй/ЯўОт{Ёƒ!y^rтK‰тV@hsЇЂё”BЦ0"ndsЊDƒ[єh|@мЈ8ЃС [ЪљQй"ЪSвSšXхRyЇ-’ ФДЪeЃ9њN ?JЃуЦŽ“ИХ.4€K= Д1e Иъ7 1J€€€2јnLƒ2xЁ   аj ihЕЇ ї ipЌA@@ е@ваjO=  юpi Є{.a >! гщ.œ,ёј„’>‰•€€Ћшб њЈЛj ;№2$ ^ ї^#ЩЏЯD_Љ^ЋŽA х PЦ |д[>D‡ЄŸ‚&@_Іј> рѓ‡аAЦ4кCМ   аB4ДxT   FIC 1Ф   -DРICФ€Ш е‚€€јŽ€’Zв–Tё]ШЈ @@@ %x i˜§вДMџОЭtyCKœ@д   О"рG.зnиHб~T№‘8f}iЉx2€€€@ №@в€ќ а?ˆ@@\!рлЎT@'рžюЁ9ћї;о5Vuжv;rxЪмTЎm “Aќ   6<агАnKжхяЏчюxџќЙвм9$ЏлВйІь€€€>$ ŸМБrMh-б w’‹?+|2h€€€€ $ 6ўА    PHтGХgЎ[[yЫHˆшфИQё Х…f€€@ы%р+Ѕв@Шѓ^КaЌъІ ;r?€€€€Вx iркЊSцЇвKYdаИ=aу;    %рЄ!"RКЪЅНFЁєа,hE<4HhnUtјy‰Л   N YcXGHчЉГч:Ф   !аЌЄAXЊŠ2ЌY%СŠ]Pмž@Ц МZ  іšогР:Фї&XШ$      MOXZРeA+@@@d xрі„Ќ_(A@@F ‰= ВЗ$Фhа§ І@@@ ‰Iƒ8'ШћуВвГщ вi]lZАjэж#* š   &рлЛrw­^Й†2ђKяoЌ\CqA@@@РIУƒџy aЏ‘`@@@ рx iˆџU\ц›щЦ5žо3з­p 0€€€€sMг vКrщъьпgݘ—|УxЃ›Жли1cS’0Д˜2х‹Ѕ***”й6Д ќ†€NЇ‹Šья7с жNРIз–K™ŸJЏжЮВ5Е_ШцЇОжšЖ‚@ иžѕеŠМЁаЃJ9žHфќBЇlдЧєJŠЉЦЄьfЂu ат&NK<И7IC‹Ÿ hж˜ёl Žd€Pf% Ъ@€V€€€џЈѕпаY+$€л­№Є{ЊЩfюЁЇ\СѕBПIDAT€€@@OCœ$„  ў@= ўp3Озд˜Ё#jgz>qэŠо™ށДVЭM0ўБЕ~rЌэЦнVЅž~œY?:Г?ŠЁДzЭJФЫVЕz’­u2 ŸС­ГёLoпŽ щаЁKиуЯХ<7=qКFЃœабичcЗgmћ$ЅўkўGПЅЦВsWжсЂЃwoоhџѓ_FџrЪф)QQQbc’™НDяю.ЮЌЛФМhЮ‹pскmгр62&  @џЅўГc%™fГ™.ќ•ЦJц-88јрСƒlW,,\КаlцrwцžџRŸ_?aдЏо{g‡и2€ј€’@F `C@ЅV…‡‡/zmQТЏоЩоЦŽ­^Кzя{ г0Ёє\IjZjh—PвPчDLмˆэ;пeGjЙuыз }.š^$pь—Ћ#}НЛђђђбЃFќ#ŸЧдu“дbЛ$фэЭ:lht”­ѓzKќпLИ9бL€(юYH<ЫГ•yЃЫ^Ў O‡­ё ё/œ>}КNЩq*•*seцвхKљ?‚e}‘ШШиЬЕ™zНОс­+‰НИЂьэй?ољ1П ˆ^ЗямІ]сЈ#=џ!Ўх.ž:љЪмW–/[>1a"ooU6ИeЛWVZ– Пшг"Њ…9oА”Jз Xйу ќ„’?9Ѓ5эzїn•Их§"ž‹znзюlБ’фЗп|Л{ЗйАvutLєшёЃГЗmЁQGЛ‡?>œО8њ'h[Гx э –Žєtєр‡WПўЦ;лп‰уШ-гЇ/ЈsNЕ0чь(%hж@H%@[šDРеыV“œ+В БЪЛЦЮCh˜c}Sy!%yЮдЄYбЯEGDєБъyЅ*ˆKJžC/’ †Šїџk?rиžѕЖе@ђЦМещiљйа.4м’燆jюoВ#=™энГ;с…Бс=uЂиH-ё\З+ыМЎnќ  ,H”u>}мЁзкЧ•tuЖФ>њѓGƒ ЊыќЇvе}suFкђє}ЛпулZЏфeыжEЗ8%56nА§!ўИ}7mHЅСкEK+o;kCGz2{ogюЬ93дƒ3‰їЩqкбf•JMВЩd]ЈЌО"[чньА:Р[S `оеІ’C9o@вр Њ­УчCщЯжбьfЕRјmnƘ З Ÿ}ќйбЂТœяГпяLа†щ^LиМeU&(чЅЮћmТoŸэї,нb0о5юџ`џг}Ѓ˜Н8&{х№‘ужnнИfх2#vGz2SwжфьЬMž—lЎ5OŸ64?ёСО“ІLЂл"Зn$ ЋhcжЖєЅщЄ!§и1c™>22ВДД”єД9’…Ѓxг(g q*];#DŽ=rУк ъvъмїїkCљћmRТЄлееL?яхyŸ§tђЄЩTLџ№`6Ѓуд?ЮЂпР#—ОсŒZ@@@ р iјSˆ€(™њѓ”|vЏmОЛ=xlБcє@M^n^ьѓ#›р€€”/Ђ?78‚ №$ ž ињ|ЃbщыЌѕ5-Ÿ ŒЁ™ƒа}.*S:$ J?У^k_ѓЈёZhp   ргрЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#€ЄAyч-Џ@врЌp   Ъ#аЮпštБєBEE…ПEхёxt:]TdЛ…C№џJ„Œa~ъkоkАŸxоžѕE‚МСONТp…€% дЧєJŠЉЦфJшm3qZтСНyHњ$"xhm0ІЁЕqД@@šHICС5ЗXms <€€ј˜€нžА6оЬ=є1T   а8є44Ю   DРџzј~{sЫž›ьœ])ЩI-j#рIђƒћ§šЮZSЅб›gЫтMч№   ž'рwЗ'Ј“СƒЏьнЛьНЩ*ХffБЦуВ?$Fžџ4С#€€€Ђ ј]врqккP­НOYЅН4   Œ€_оž`бy_а_МјUљUњнOѓ:Ч Ž‘ŒёиЕ{WtџшЏ.}Х*"ЊСРwЇ 5€€@Ы№ЫЄСЃXжoXяШпеђЋ&j4г]eѓѓb0›ъ“kБЃFhд“ЩдП_џ‚O bФH 9їЖОјГboWџ N€њPщ‹.,Lш Aќ~BР?“OvоЏXЖBТК>А˜яUяЪн%>Њ Rq&V;/№)EЅб\kQqdok .ъS9nTœOыCe I@XрцHqQ`†Ј§Ž€_& ВwšЮh0Ш”Ўхде)/Ї№y€xcЕ[ъc0›љьСRc&{оˆKЙ+7oжKљЙьAZЪА6^+8Я>jЂџ% 9іKпS d’ВWxЏ‚УtпЃў“щ+§WБƒcYЅBЉ#GєьoƘ/\М ыб‹ŽЪzcЅ €€€€R ј_врCвсНћT\Џ(8R`6UЋ5С§б_Ће6s:щКш 0[Џ1t„Ѕ9ƒЯЊ№' OІO›nO[ЌдuзѕщлGЄсЖЌхLџ0‘Ни j@Txяpй@zЪŒ&›”То94    T~™44я~ПфTЎЫ h+щб z9)%k Бwзц ї‹Ѓ€€јš€ђg„є5QыѓШhJы‚€€x‚’gЇO‘ЙЛсЌ€ЫЧаЯр2*‚€ј ПМ=бвKc‹OŽсzЙx2€€ДZ~˜4˜щQlDs>тc  рWќ0i№+>- ц|l1єЈ@@Р$ Рx[нXo ц|єі€w јWв@kЋфхцХ>?внfœ}Щё"jlР…€A@Z3џJ„ вщ‚ЊјSBfƒWќYFA@@aќ+i ИX[EaŸ04@@@10OƒbN%  о%€ЄСЛ|с@@CIƒbN%  о%€ЄСЛ|с@@CIƒbN%  о%€ЄСЛ|с@@CIƒbN%  о%€ЄСЛ|с@@CIƒbN%  о%€ЄСЛ|с@@CIƒbN%  о%ргЕ'h•І#ХEНТ{yЗM№   р>M„uЏ–_ѕBCр@@@РЛкмЉЈ№n №    г ˆгˆF€€€€ї i№>cд  Š €ЄAЇя@вр}ЦЈ@@AIƒ"N#  о'€ЄСћŒQ€€(‚’EœF4@@МOIƒїЃP$ Š8h€€xŸ’я3F    Hqб№>$ оgŒ@@@@4(т4Ђ   р}HМЯ5€€€€" iPФiD#@@@Рћ4xŸ1jE@в ˆгˆF€€€€ї i№>cд  Š €ЄAЇя@вр}ЦЈ@@AIƒ"N#  о'€ЄСћŒQ€€(‚’EœF4@@МOIƒїЃPџJŠ”fЇянIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/19.png0000644000175000017500000013743611733011756026254 0ustar sylvestresylvestre‰PNG  IHDR™!ŠT6РiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь XTежјЯ5о‡!ыEДЌx Г(НЫфCSL4ПRЏb\?RЎšђђj"~тЗІ˜ФЬЬ4-ђ#?P+А4дH%1ШLne№š:^ЙoЪ№Мјмџ:Г‡ЭцœНЯœf€5ЯАЮ:kЏЕіoŸ™uОць?]++“№ев •Жє^bџ@­”РŸh-–мJ`З‘@H 4CЇоM YЛ‘PШћLZй ;‚)#$€hЅBЇ-"х\>.'…Мтve+…нFH $а \=Йыж?ƒrn9.—ЛPmj†С”‘@H ДvuЕмdЊv,ŒŠkЅлFЉЦ–]7ƒдЮЧЋуSŽЭН!$€€+hx]p 'й№^(rЈЋхRЭmХК†,V\+3ИI^="%ƒЇ ~L•OW\ўоЋЃП ­а $€\ž@Уы‚+xh8ц†їB[Ыеk-šЊs;qЛ*= хљс?N]КmЈшиЗ*7IњЩ#r-Пй•^=†IwўZ‘жрщѕTШеяђЄ‘ъ‘@H yhx]p gп№^Јrp;SRЌRŠn†vэкtž5ЗЕ“Атуј/‡Щ‹+Ž‹ѓГy†OU6‡бнР)A­fзФY5q8ЋнG$€F сuС<4GУ{Сфuм-ЌWАДё YЩЂ36DЌ‚хю†‹эhwэ†ЩtэBUб!“|!мр!jх&yЈМшQTјЙ•ЄЎ4љhИњrОЙфЏБЁфkјдXЅ‘CW9%Јеœ’•ztд’‰CТYэ $аt^\СCУy5Мѕs€:юfњCЧ-oEHn•э m яыh2™ Јп–<ЎžЎяАq—^\sќљЪкСexЗъŠ+gяЛЌ”|6зvn&‘OUЌЧЪN jЕ ЬJ=:ЌЦІЖš6 $€Z6Јуту_ІыљwyTцяюю^^^њTчЇЪ~/ЛfђЌЈд8>60ъФнЏеk2њ}cн:Гd>šчЗ5Р…ХЄьCr0GкVзHЧ/з|^ 'Ј>mжhX UиŒ ёŸђЂШ•wЄ3ПSŽ”У Yя+тЦУ;ы‡ЎЂxфуущ^yЇzwЁёЃo,ЯО}ЮП]lD€ПЗ;ь\”ќOхЮ3хпќТЙ‹P˜€›4џЅ€А.>юЬPР>гюИўхзЋ'o>  †CГ‚AvІт“Шэ;ЩЙќVuкчЅgЫ,Щ юцьязоНВZЪ:QzјЌL^д)8/ЂЮŠИeп5њЮѕL3ЄЃЃж€Г’3аАЊ^ЇxI’зHŒЭe$€š–чЛнjQ€ ™КРё Ї  Аои Хx`Mь“•Н 9АсРЏZЉ‘S@$Ѕw6Gг•eхeўќwюкљЬ3ЁЗ+oп–oOƒТ,hŽYпЌ/Fn']ПэцЭ($љЎ7ЙЁР­<Ј†K5–{уŸ+?pМєхА€ўЯњ™юTЇ5ОИцЬ—ѓхВЗ8mЛI2t5Ш yЯЖю лJЄJу3]}ЦП…sщОrїЬЙвп”xОѕCW™їБЯLщы{ +З• і›в7*ї–oŒАvб№@ЯЖвЦ§g~+Џ|ЬЧsLpРй_nCшњ$QгУќњњ),џЂ@юHиГђ‡щŽщЬ?*ƒŸєьч/}Ufш я•\2>\cЌ|DЎHФ3Ъw-}кпsЪрECЦОs’љkˆЯŒ§J.U&ь;„_~> РM"ь7+Гшw]зD}ћ< трRŽZC/ АЭэдd‚ю\љцm€ ыjЈЂФ"|GHР9TuaїЋѕŽю +(`ЃЗЩ_­ѕ^Д.Ј<д3гXАЫCН E=hDбЙJа Жя”ŒЮкш mLэ<лљјј<жљщЇК>хяя/™Lu_ъ:М@f№ƒѓ~ §Ыz-fЌУ‡lвЮэЖ—›хњєY8lН}рt)шУ}vЋїшКŠC•'фeуMGЫЏ&щXБ|<ђИO'ЗКЭ%џlБщžIфь‡>+opЇ JрчђћЯЪ;У‚ œь™мСрщ ЄЂпЉћЮ<^? А—(Ш@йѓЉтb№L0›Kљ%rz§Н$Sx€Мяђ§ЅИ ™DЎ, NKїnќ*7їєtм 3$я"8zі*ЊM[З“Њ5:%ЪŠ„ яЂОkxІmйб!J…†ш|^Ї†tЇыЁ#­D‰бш( $р:hE )ЕЋЙоФЙбXЁ)s Л/Є вВљшLC>ЖМБVХќПwлh4x{{‡<rБєЂбh.„MмјзГa”тPžYЅМУтnх˜О6юэ;ІЋ5+Lr,8Z}иpЛТTїsіл’'”Xѕ\gЯи>ўђi№к†pBмЫ`КZ{š]л$уcіњЦk§)s8и9№Я:Y>ЃЗпј!ђЩceuж1cбЏ№лz“Щšи?ч/LŽщс%іЊдЎЂВZA™БђN@ЗŸ‡;”wђ„ћ5Bw:unЗКљ”Оv_jя'€кf0x’ќMwnW@Щrƒ 5:%ЪJ1.ЂОkx&@рŽŽ†††Г P§NY’ЌVЂƒVЂФиAЁqQ@H ‰Јъд0RЙЁ.аЦIОюH]PyрsUж<Ј “в ѕ \aћ2Џ€‚[Шы%&Южшz=цч@žп" W›Њ mн/н‘LpкAјтЗз;I[л”Uж]ЦЎ]+ќпЎ­СTщюбЖX@ЕƒšшQ{ШЮЖSЭцгр%?•—ю3$ПожТ™zОU?ЦJЙœПѕўюkаeѓIцv№^nІOO:_њьC’ПŸOџž3ћћŒ}ЏLQ34€ыї[ЛЖэЭNщУњППХЉј8Л>‹†SњТО@sTkцLИ‡М“!чпЮг`К)rйІЦ б)Ќhz ˆњЎс™mn“Ќю”F’ЂФlŠˆЦH 4e]Иэ&Ÿ5м§Њх0,ц}8ЯЪV’[”є%ЉэA‘xeѕЌ}1ЕЌ8НН­RСсЖ›т„0НчиoЫJ-­ЎЉ†ыхpP~ЭxэкMx>Ћ№xNšZНbзєЗ Ў<О&:DОт^|ЁŒ4„[ир;uNЩЫНлPШ†дщk%ЎŸк•ђџнчфѓъТBLїЕ“ю3<эч3ax$%C™|sD€ЁЯQЃtЊмr—YWѕ9vqyф3!LGфxцWvБ|Ђ)№Iy,‹‹ЫЁ<ЫУ(venФл]hО. {-№šў‚љУ#ю”FVlQп5pЉGG­aChШ9цЫнЄчынu!JLУЎBH Б X§n7rIUР /K]АъAм‡y‡аЛFд ZШСQжkд‘HePы•švƒOИ\._/яж­›gЙчїч/рВЄшИžЌnїKwлрgЖ?9Р!lющтлцƒбэ'ЫЧїі{уеЁџХф3№Оrщœў3ў*џюœћтњa-с8ЯS2СUфДзћCэ)ўŸЪхъh€r~ ФсріЅWЊ{к С}Ыщ}тD#MЧЏћЗ•ТўwН)w2Ўо4У€GмЫЏW^ЋМWЊj Ўи„ђЇgЭљwїЩњ{0Юf(‡{ >=-‰:Ѕ‘ыYдw \ъбQkиђ–‚rЯj.:Qbфš‹†O\…@#ЗУ!iЛљР†WРЬ‘Жbжгv”ы‘ЌY№zA 9ьа@! ,J_МЖ`Ужrэъ Пс’_!!!r§&rэVuiЁ")R-?ЊЉ8n_L.yоpббВvqšќћ4rРj+Ћ'TЛNWž+>вN’o&яj~4љŸ-Ћ^јўё‡нd кBc8СNўзњ”УжЎЕјЉ]e6— ŸЎ*(ѓК]й+їhюэЗЏоИZёЯ щAЩєи!ЉsWщЮK’єTН&АоTе;\э$уmC§ы№uЬkKќ_’| sbџ>щъ=ЫЙtxzL<ѓ>ЫЏ5žЫ7Ш–P}AUђЙ]уоЮMжTЩОjЧУMRјd§д­r“+§Uиg$NфEљТ3 WQгЮюх‚—\ШЅ 7Oљšt§юk$ž/ејДЋ;3_—И„рЕs“wAЊjjИb–лR\$џШв eЮВ[QЇДГ’;k~‰њЎK=:j ›9+CLvqжKйгэ!ђЭЅџ(—юГќЌQ”Iп‘pёw;IFЎЪ+Фц5Д.XѓРvЊž7MŠƒЬ:'l8ъЁnЕНы–ёГ­ !0њЃЪнcх{јН`Z\jНЊjn{=КйУгtлPeњуvЧСqdХ0ЋŠЉуUЏpЈ?VќxI’ожђТЌƒќШ‰FgƒxЕЦRЙi›л5žPЊщ"ЬuЈžŠ– nс†СPНд>Љ‰bИ…?ЕЅs^Ѕ a  ЂгПђчѕjИR$ЌXфцЯU’ь4ВЂщ+“aRy§%ц&pЅжА™Г2Г‹п—›оznlt7о‘Žœ3~}~[hwФhђ( $р"ь. v7ЄoИъЪnцРюЪPЅЗVjЙd*“~ЉЈ€Cй<ОљэЫ~ОЃфЧА›ПЏЋLU8ЛщYUUSaК§НзCЯдWЏ”ВЋи\YНE–3ЖЅі/І”<ячлёеЊ ўёzQiЉ—dЙЄзYЎJюцѓ.­ v И*­яv­вPW8ДRŽє@к-шэ…ВkuНP†–зhНм:Vмшo‚Z~эЖWЛA5ўphZхk2=d’мŒWЏU]†sД’—ЏjКqxvŠ–_Эuж’"/нЋО]г%ЎlЉр|†Щ NCUЫт5PШхs'-ЕГи/$аМ 4М.И‚‡†AУ{ЁЪ)›ŒHЭ<№‘ј;ќђŠМ*ШПф єxњ]О"k2юИS›S м^ЇqНœšW‘yiГf(Зl–3љЄ“И1ДьСЦо5w Џ ЎрЁсЃа№^ЈrЈћђ3Ш?ЯwмЫрSQVюхяgS9‡ђ_ё{Й‡ИšŒуК…ž@HРN Џ ЎрСЮЮ3Эо ЦыjЙjUƒ†№дХв‹XЫѕn h‡p%vжђ|ЖYчш„x*ї‹–ёNЛМ{Я.*Ѓ`ИZбR/ФP ЭК.˜<^сЂ› vјгЕВВаiЩ}&­Ќ0uЮy …мxУ8~bŒЕFкЌ7е[i^КWOUЗРБ7Џдєеu.ˆd’‚њЯ?В—“ЎŒмœ—KJŠЫ~/ГŒ)tD„іQ4^Rэ˜‹FСК‡Z эjзвЊmFџ‹Зj"ьE­Em”кхњџkзВ9œ.и­ѕбрDДђЙЈЪ„ЎЫЈЬЂYЯ&cж 8p2ЉsЂэYЋ5t >xбЙЁеЊQ|КуЪ’М"\НДUиЕЊ†аЯ:цїъльTmICH) ѓSOт|гЪэ—59OЏцмњчoЇоMАчИ;ЦПc2епj5bВЋюcйЌ70 ‹шЎVегЈšЈѕЬ%‡œ"‡#ђњ^›ыЛSb‚яћЦ”л{б@ScбˆSkCO Ху-^CC˜‡lдeўqЛ0Špн'qКЁIFeЏRа\%;?ЖѕQн5юаѓ:U?ѕњKііBWђŠœйQА’Ї2I=[—Ÿпјэ;Жc-g†E› иљ›4ƒ›r“Е9rsn%аYщ‘аThH&-fЇЄ!А-p.SЕ]ЧEЮMЃЛЗ3%ХvІdѕ$Њ~аьЩЇŸќЧOџp€#‹SйуrЙЏM5І=@‚qГЈ=zSaдюfуЎmж}lжЩ7юИЂїfIъx›А^СЭ2w^в№ЭS;^Ї}\nпГ}­иЗГSЂ‡C“mz’il›–бй–б ыc­ИŽnНZ z ŽЛ™ўЈЛoЃоJ+ pRШњyЁђђђдДд“'ПЋЊКљчЇ'O›fХqVџуЇ&+ыщйЊХ”@хqЙŽ1%аž|:кппЛwџЄEsmџЕžTўkљдщS?ћт3šGѓ@—”B“mЬFЈЬ]†ќЕfm•ыwжжжzьu |НЄgЄЪ§ђжя—=ўГCяабcЃƒƒѕ?Xэ…Н u%Oг-Mчж^њkijrъ‰я л?и~іЌУ†еm€нрƒfЯНor<ИOЪкОфѕ+з'ŽuЦЭœ;/ЩГ­gщ?JЗnЫыгˆЕœa5=жиVYUљрP{Эв%Зl†/ВЮOОЙdО_'љVUј!@Ъл~љљчіњЮ˜R^Œ dФ;˜СmŸ§"Bƒ•ЭыТзJYг‰хТХ ЋM–“рaї'Л јЌхјВж\зџz%PГEСwEй™[ѓП>бя…~KW­!Ж OŸіњЉ“…[7eœ;џ(I§†w"€fъьјIcЂOххцžлхБNывSEqЖo§АшЇ ћГwцЩѕ0HiщiдВш‡ йлЖŠ 9˜i_, ~4м„yI'Nž 6JА‚Ўs(2§В•0О0v0жр–6)јЖ 44”.Њ6лЃЋУ9XckJP”їД|ІфQЉ%aACЧvЇ№лќИј8(фр6•Аў‘3пЇ ЄЇЪŸЭˆ№анŸl'JШ–§`ВНPфЩZxЇfŽM^эnэеwЊ!sxЇ6Tп{3ІЯ‹s7И{ћx/ZИˆкˆ…:?b\ƒДДбZ)^'ŸЂ‚уrЭП“'OFFDrmв7ІW\ЋиŸ“ WЏ]…E‹™$œ,€Нјќc…ƒŠ™sьdAЦІ y1r№вхKЉYQaбў]ћs?Я?lsj@„э›Г žэџxўБ|7Дд4jPtЎ(ћЃь’Т‹FГ/В ѓв_“цФ{Жї„х бQчЭВрЦУУУxvй+НН}%&0ŽыФНлГЛw“ю3ИЗ5ФЦФžќњdнКњвŽ{,QтІХќђ]?7.О}шЂZPю”X…@ Р•A ‹’Ф‚еhв\d ыoWРјТ(УXзљ7Iп:в=Ф2"lT†єm6GЇ!4ŠBУ†ЌтYкš’uŸЉSйяgУ‡Ј_dПЅI–‘АЁеДС€:ЗfО|йrи)—Џод7ЮЪШК№Гќйќ"'џкхk–ЕѕЗŸК@М1-9'Ÿ‚wYЈя\kQwђlєz%Щнн}шРЁЛvяЂzG zјоЛmМ=Ш|ЄБpўТъЪjj#Њ R9О€ьЌхzЂUнК)*$‡JLH„Е№Z’АЉC8!яээ ‰ЈшЈЛџК;wЮ\Кxўмj–8ЫвќАЭЉv| u.бГTSїИ™qП8H цўЗ—x-­•%:U юm-ЅЪљнкOlъњupp9/ОxѓV%ьFˆZНў‘и#I~;ЙOhjР‚еhb/2`ѕ0ждyЩ…’Чўьожђ#_8­ТўQ3›…нY=њo< ­'%ж^”j\ф2&DO ;”z6М›омаЩїс5Ы’BУB ”žКžЫю9А:('жж}fќ‹н~ЈcЪ6qИЬnэcЂЦьиЙC.Я№Њ‘@ѓЗWA„рoз~лЗї‹ќ#љхo.7[рh\і^/‡ЌjЌœђhпЁђжun9+ИооžФЗŒ—Љ7ЯЖ"Л›зР.ЪЕА6ЈЈ95 ‚ЙЮ ЉCн­ѕрщi TЗVЗЄѓzЙШ<т­5Ћa-\8OJZќйс/д–sчЭ=kvxp—WW› œЋmˆІНoю–­\ЮЂ&T_oЇЄЦDсP \žш№Ÿpя[ŸЄy‰Д- Vc ‰НШ@жУŽˆyАфБ†—Y>ѕЭзЯ?GcбK–о9{оь)`‘э)‡н~d}m/Ќ)ыECж<]НЕћ=тгѕёЧѓŽхEF„Ућsнž#[l‡ћяO˜'3—Є„™6lUM’F:–UО@и_Ы­TrIък;чhnдЈ(uzО>ЪЏ}ёUЦ+Ці>Ј7*VЂХњЭ}Љ™B€:—SПЮ) дЙщбд+zдЗYИlљдЩ§ѕ‡нљ*В_/Ip‹lљ•2ПGќ‰-мШf0Hюм—К)ЃОƒzKуЦŒZОfЕx?тS~Љ,cлжUKt|w˜}А;%№]Bсд X(4пЃGWвЖT€UVZd ыЏ}М-[И"nП*јfVќ,‚ 4 "шмЕ јвaЂ6 pГ=56cp>ђЌ йІфi2м­}Ф+б[ВЖ„G„œ§бЌФљФЮAђЊ4џЃNjеЊџp;žJ‡ $`{ЯБыИыrjьд›ГrцTоЉ„‡Р}ь / ЩН8`шк”ЕђуЪJ`бІЄС~ъfn]™šВvШ`цШЛОЃQcF-[Г >ќ .ЛT—юъЏЗsЉЇІ#њіŠOH э”’О!yѕ ’DЬФиЈёр<9Y\‘ДpCђ†РоAcЇvЖ‹FЂуЧMшўlї‰qSC{Э[œб7BУXБЊ;% oъEЋ-2}jJэЇYюћ3н1]љѕ—n]ЛЉ)4:7›Ђ+B4‭)qAщЩЭю†zœS›щqгсVјЈ‚ЦxۘљnцŸŸЕмФ>фх!k“зVоЊ„aMлXwУ&mЋИc {РeWЪ–MЖRёGEЮўЏѓOT є_Gќю?…NСп{oЇіялПЩђС@­™€§ЧхVŸцуу“КёНŒї2вџ_rUенЮ№ћђё“I+И™+ээДa#‡њa‡Сb7Х^‚`Бћ_КŒљл˜Њџ­іRџиIМцц†pBL› 'лyт‰з'Н. dЫV ]щ‰_*пtn ”я Ќџ‚’ Tж'ўштшс–гд РFб–Дb Ј…Р—ЫWўДжŠE‘1ЃЗ:а"гuыз :ЬуAёЏŒ?q4r;}цєŸ{˜їujCРНlR…Ї,?НгЙyи Є%л‚QП­)qAYвЋЅЄVГ^ЋЁVїЬыtїqњФщй{ВW­^7|јњјі~Ої›Ыо$љФŽM{7mLє№3%І.Iš6IЃv‘;ІуЧХN?nЌЁCoО Ї IDAT5wлЖѓкшuще0.zмВ•ЫоI‡DFF^ћ§Зс#‡УЉЕ>}’ц$бUѕ›ВKpy‹]D иLРžyв`fL˜ Šьkла ‚Bƒlјш:""јШйЗЋeЯ“і§ЃFs.ˆ8ˆŸ§n`ЗјYёћvюK^ŸќиEА’Єc7]gр~цЦЦ(JIЄЗšЙ­ › Šœ8ІMŸМЂ/œХгЎ}9у_БВasЂЊpР+++wэољпsч}єСЕj@H ЋкŒeеЈё `†Э˜IБПќђ СВƒ†.R5ЅBOѓЄzЬ4jDhЯ Б“&—_*Ѕ6TАj SЖ Рxƒ†Є МгЖзЏп˜П Д_xhXјŒ„йАB§Ћ…ЌŒЬˆСrсВхее&bЎ`Пjа№=›й=ъЂ $€𒀓Џ—CЭЫњ 3шй?лдgrXяєј^ЃyСwEй™[ѓП>бя…~KW­бА„U\у„‹ЇO{§дЩТ­›2Юџ Ьд L?iLєЉМмќЯsЛ<жi]zЊ(аі­§taіЮќ#Й)-=Z§p!{лж’o•Ј H $€дœpН’ ‡Г whпa[ж{ъЬЅIšяожМMˆŽЪм$,Б$зиУУУxі:*сЂўЂФnb{ЗgН{[)6&vрАсвBЎЁДуРžŒДTЯіrJqгт‡џmЬœ7,>чЦХУ‰ ~3д"$€h”Z'ЅЫЪЪй“љєxКњŽщУнЛжІМЙ1e“ТоІEКs@=гцЄУЂЛЛсn UѓЎqъњuяО1ныAй Тz†Ј—\(MIM9_zўюПюЪkХ\o§~yШЫЃъ<0–ЄРгUNЙ•FG $€NРпп~юpЗŽПїrЖrk$эож3~BhV&БЙпM‚ыЧPtaQћ’ГТЇК„+ В№dР[kVƒшZRвтЯЁі6wомйГf‡‡@  AНћЈmˆІНoю–­ŠВЭ5жЩл•H $р‚ШAšУЫy›qo8ЖЗpDЎПСqљіь;wюLrшќ—РГwA-ЌМUЙn§ZФрЧlхW”‡ўі YwЈ•——Iї$ЉFЊЊ=ВW$PUUe0HюмЗќЭuсЦЕ|ЭВыWŒ`S~Љ œkу*$€hI >ЊЯ[7Мƒn•wДюИnxЎzJќўџМ?ЈGа›Ћ—ГЅ ч/]ЖЎjЗдwЦЋS|–Ыmژ‰БQу'Р эF="'б#њіŠOHМRіsч'žH^Н‚( ЌHZИ!yУыПЯіѕёђкИ9D™7VMŒ› 'лСсф˜зE–ЈGH $ ‡РŸnпО§Ьпѕ™ДВТhЌИQОwJ€v38?й€Ц-Z` џИ\;ЎEH $аТhWЩ’’т‹Ѕ­–б‘›KНђЛZ˜sыŸПz7Ё|ъ_H $€@Г%рфп—7[n˜8@H W!аFЊБ+Ц…†SAH $`3<Чn32l€@HРЅДЉОƒПJsЉСd@H и@рљoДЩ?škC 4uР  Л•G и6…ІЈ ГЙ­і:нКІ™Ѓ:+ђУеs•ЎЩГBH ‘xИyД=*Њ‘МлэПžЌЂKй˜’М*ЙЄА,—U\\фЦХ‚J$€šИџŽssJв–ЏQ7ЉУ§ї?тзљљ^ЯOˆущщI’!%Њ‰A‡јi`lsІtўт/СнЛ9›g+‘­nЏV‚Л‰€SєщнЧ9ЕzKОIЋЋMeWЪј"ње1[3Зy{ћ8DГ zЗъnГЫFg O—••!$а‚ јћћ…4qK~(qZ-']uw7t ˜аюУ{™‹&žАd~тцm;./—|+ŸOЮЪШмОgwUUUџў§“цЭ…цВŸ{RњЛiЛї”ЄЊ™SтFП ‰xЗ~н“VЎO>ђEhњЖhN‚tˆr,"јйрПEџ52"R^!IзЏ'NzuпЎ§юmЭQˆVьgЭв%ЗlОѕћхЮOОЙdО_Їв‚МsR’ЄƒsИMјнЌuЧК":вGЖ/"\#GHMIѕѓѓ‡†yŸчEО$wЖММ,~Vќо=ћ ЫkSROœ:!§Ÿд3hѕЂ%єdImpхm‡`mSѕtA‘”‡”З7ќђѓЯэѕ1yЪаЁУdе&:…sXЄмтГЖnЏњпЊaCћ/š“лЌ%MрнВ TћтuVМЭАži>ЕAф^Ќ\П<чр=b&ЦдщыKл?љP‘Zэ‚"‡„‹W$- ы~§І†Œдrѕ&AZБЮY?E…Eћ?о šхАmdeЮœЋ€ЬƒЬ zng5Ж…[Х"dRqуvюAЫFЋXKеЩУ*юшг&Nрˆ ypPАSЂcP$а4ž иў~Vзђy тльоГЋizЈХЛƒЯ­[7е6sутщЁсŽ{рјЩГН'”ŸИiёПZэ‚"уЭJxСšE‰ђОМD›ыœX’wКm€pш№!vWцKng5ЖЎsЊ„LhbАбRНB 6lђмбW4ФE$€ZВїКС}ьЩyЩNяTЕoпAThЊ„гзC^EЅкs pоћ+к/oRn/S?lˆЩ1“7ЄМй?253cЪkу,ч№ЉЉ$iјqokIZнеї4=nQ7™,„"лЎŸюнVЏY эчJ^Оbг[р@іьй“цЩW7J.”ІЄІœ/=ї_цыёЕ„…ё$Iл!4ДЕVЛ H&u§КŒї?Hп˜юѕ Чь„a=х+UЂM‚uЮњmЌ +sƒ‚ЗГл ыS-ГН ЊЭш*vУцŽОК-jht|[7IGфшн[>ЭЋёjяу›ЛeЋњыизЧЃщ7зƒЏOjB{Ю~4 ыОщ?оIЯШ<[|vе"ЙМ)^:§(ZйД(ъІMNИыі3ї{јјБ|ƒС#ИgШІЌMЧПЭ йk™;oюьYГУƒCрИnK ънЧjPm‡ЂцммдЦzЬрŒж[цНИD’”ДјГУ_€=›ЎўЖсЫЎтЪм \KPŠЖ™ћн$€LШУyusЖЁк€hИЩыA'rˆz$€šj'?УОЫJ/•ІoLлs`їпcЇjу7fдђ5ЫШ—ZљЅВ…Ы–ћQ/Y–М.Wп1+Ђьаўўђ+uwЬ0tmЪZљTleхВ”ЕА(Š59цѕŒЬ И‹ŠмЇ0гяGб)Љ ˆFдM‘НH/ђгЋЯѓЋS6 64xѕš  !NрІBƒAr7р&ИхoЎyVш5*,щЂ(7j@=fАРН{p›˜T#Uеžсn чьткДTѓІQ ЩСCШ*ётeВВh›щќ—@ИЕ>АщЎ[П–mBф!^dS kC“зƒNфѕH 435’гЎ—У[=ƒТ XКlфfШоЖгъвЦ›а§йюуІ†і šЗ81ЂoС3)ЖЫ†G8rxЧŽ-Ъ‰БQу'аћТfN‹ѕzшс#‡СпУ= ‹ЂЁ2ИIOtіЕм­2вяGеTŠЉŸ’к€hDнй‹є"?с!Ёp‰!2b4Œь?ф№Ы­Хpй†ф Нƒ&ЦNэўl‘g…^УЁТ’.ŠrЃDаcбЗW|Bbhя ”є ЩЋW†мMBсœ]„Юџл˜C‡yЕk73ЦВmhŒ7(ы•EлЬв…ѓП:њUxп>бБ{ѕb›yцД8Џ фжg@ЬИЩыAЇŽиєšв”Ту%4тz{{kЌХUH xћŸNŸ9•Д­ЯЄ•FcХђНSъ§’J ю•ƒwЉW ИрГфDйЊѕoЬ_№вРшньjдД0ŠŸ<ДАоЙNwр›A}ћії7_ќхЗЋ,;aъlЁ–_П~]­G pMp†юcз.‚кUВЄЄјbщEmаї‘›KНђЛZ˜sыŸПхП›а"Тn№cш_џчW,ф,”‘@у8іѕбОсђo(рѕVђ[]ўвх1џЧттуШœOф о‰ еHЋжЌГ.OwйќўfYƒ/$€$ЩЩзЫ]jрј žмВv‰х2МKх†Щ H F:yъDXŸ0шкЦДEчŠŽ}uьт УЪu+AIŽШс y+э­ ?]ГsпЛіћЕШЛ„l'`Кcr•ћиmOоё-рё ŽwŠ]žŽЛГ†шЬЙ3?ѕgїЖюРŽ6gДЯЧќчE‰‹^xБчŠeœя;>кБoХlст…ЮЪу"—"Аkп.Ќх.5"˜ hEђчї‹шG:|ЅьrP(3 Ар›щђя—§ёkEŒАЋH@xЌY <ЧNя]Ї‚В‰­і:нЂ@\_ћ*Міёь№8}˜‚œN—пЏ№яwѓ}дЗќJ9з*‘@Ћ%а%Р9ЕЋfЋнцАуH€€л}Нј+LhDЇLžВ0сђђrИЛ ~ЈЗП}‡іЪ/еяqcЧ-XМРxн7Ч­ZБ a"$@8Ї–лw…їpЋE-†Р™oЯШzЌ=—>уѕнC{EП2тБЮогgL8` щщЬџšNяc#ю.Ot‰шёlg;>jy˜D‹a‚AvЈ§$йэ"$€l'№uўзєqOЄ5”sјSxR*н$Их яzSPТE$рœуrz„ ќЄ{аЈ№(ЗБ“&—_*%CЯж;>”А @IšР;m Я…чК„і  Ÿ‘0Nйi 'Ьх1` XТг7сЉ™K˜zэrPF И§—˜/NЃ И Д$_~ѕ%НXо’њ…}AN!рœZЮv•Lљœџѕ‰~/єƒiПЩ*˜zњДзO,мК)умљŸ@INЫУ;=?“mO}*/7џѓм.u‚ЩЖYЗЌLчrЮ?’ыa`тsВ–Ю sWАMPFH Q |S№_'М#НQЃѓVDРљЕœ;хГh~hvdєOЖ-šЫYчќаlP”‘@H Ич_/чNљ,ššХЇВmб\Ю:ч‡fƒЂŒ@HРе8П–s‰ш™ZџdлЂЙœuЮЭЭ•H $€\„€‹жrИCmъф‰~њГ“R“љЄ§ё'ьиЩЖS7eh%s9'ЮJє~Ф&>ЯиЖuе’$А'ѓC'ЭK&Ўж№€Ћh џгЧѓa7Н~А9pe0IlъMŸЁ‹жr2?є•ВŸ;?ёDнЄдцљПяўы.Й§LЖ§њяГс№zЪkуфсƒЙœaL|'лСсф˜з‰%ЬНђЭх0?ДЧƒ1crц‹<   №Mз@?и И2(фdSoт$џєяџћБСq8ysЧpH $а: 8|ўђпЇ9џ>іж9–иk$€@Ž"€ЕмQ$б@H чhЃ§И4ч$…Q‘@H нкр­(КYЁ!@H W$аfєЈ(WЬ sBH $€єРыхњ8Ё@H W%€ЕмUGѓBH $ жr}œа $€€Ћh?Zwем0/$€@HР:6OИmњrюŠЧх ЏHZж+ќњMу{[Ж‘ZО}ы‡E?]иŸНгаж=љэuiщisоH #QєУ…ьm[I=VŒMСwEй™[ЁЩ‡йЛ–ЎZѓ~ж0˜:;~љ оZ™Tm’2?Ш\—žКjaiXPXА53УГ­чЎнЛbтgіян'c“eqщкЅяП+7зШD]НhSзвГ2+nмЮ=(ц+—ЉНA%€2Р`Ј‚7Ўюпki‹3gФ)jt_a ‹ъ фRеРЂЖчК%бГ>ШМ№ѓ%y ннatˆ’›Гк‰FФК‰Ubъ&vрF'{ dЛ s{б;МwqQ1дђЪ[•‹ж­! іeOƒƒ{[ClLьЩЏOжЙš“шноBDŽКћЏЛs™Хѓч,Э52Ё~D‚M];tјPтЌDшМ–ЬJљdѕ‡rВMх~ЩЎ%ВFїеЦ\ —ЊЎ=з3(ї8Д$!QшЖК#Ђ3gDсєSЗхіШŽшд3Л s§„†і-8Wі9y<м<ђђђ@.:WztђЁсP@H …pвq97l­2u§КŒї?Hп˜юѕ Чь„a=хkpž|ШЫЃъшзƒОїыєѕ%їЖ–UPžяжXж•\(MIM9_zЊЕЌb]™OЖƒьсŠЈl`^ЄЭ52!Ця6u Ўx?тCМQAУ9ЌКlМI-AИeМЌЖзшО꘎сRеРТЕчz%лkjЃ3gЈ+… ‡˜Ђ ,r{dGtъ™н†Й~BКw[Нf5иЮ9”М|ХІЖРљЊГgLš'ŸRвЩ‡†C Fъ˜~_юћЈoљЅ2zљ˜–^*% ч(о2mСЖЄЄХŸўєэ}|sЗleПђь‰ЙѓцЮž5;<8ŽќЊЋMAНћифJO&їЛIр™ьР ъпІЎљњј^Пb$ЕъDC№ѕщР6iягAm,ъО(gЕЎFnC…’э5]%Ъ™СŽєSD-кыŠыЖЅЧ§>~,п`№юВ)kгёoѓACЖ1|ИсP‰@ аFЊ=ZmЪЮŒћыЈyЋ––^(•яМЛ'U,]Жfм˜q$‡…Ы–УM=ђЊЉЊ6НqcF-_ГŒ”4иЛ†Лч Щн`€;†–ПЙЮV?z2щќ—@ИBхЎnЎ[П–†АЉkCМИ6-UОиPYЙ6ЅЮ ѕB‡ії—_ЉЛ1xШ€Ё`Iš,KY ‹Ќ1‘EнхЌЁvH4zААmEnGНЯЏNй0xи`h8xареk6€†8Љ(ъ‘haмœpT.IуЧM0<`XК*щ—В+ДГџ#7zИх~ѕˆОНтЏ”§мљ‰'’WЏ ФЁ уІТHаOŽyню‘€ы6$ox§їйp8хЕqrифJO&KЮ‡Н“ЬMЉђ­јЏN9№Y. aSзfN‹[љцђC‡‘ћиsЪЗG*^1cЃЦO€‹p‹Ќš9-vхњД#e’УƒE…=,ŠК/ЪYBэhє`aлŠмЦLŠ…ћб†Gу™ScHQЮ 'zrP4бCLб„э+ы‰Юк‹d‘Ÿ№аД”дШˆа0Вџ€ффЕс!–{ТE|D!P@ #№ЇkЦkЁ“Vі™ДВТhЌИQОwŠќЋ-Ь‘ п#єBВк F’G„/$€%п x;ЅBK%ЇEс>vэ"Ј]%KJŠ/–^дієFn.ѕzШяjaЮ­ўілс4WМНЅŽ1і $€@cpЮѕђЦш њDH $а: рqyыwь5@H ДXЫ[ЮXbO@H upZ-пОуУ7ц/ ай‡Y:eœž€У{ wO >ЂхѕЫс \Э!|(рЃсj6Ва IDATYa>H И8ЈхеMŸ"ќ№:kыіФИјІmSФfW iТ№`ЛѓЊйдe4v:Жzƒ|4Є{Nљ­Ј­ЩЂ=@ЎBР9їОх?о;Д}кhгУаљUыєZЈ3O & ѓd‡;aо=šI“ DŠХ&KCˆ„Bou>=zєШ;~мЊ% $€(6N8*—Єc_шћM‡чЩVЭvъ№(шА1Мєт ЧО.h Яш –JР9зЫЯўју3]Лq™ТЬЭ††…УуNсT<Б‡­ТuФа~с Ÿ‘0~Œ_}ЇЬр1Ÿд‰ЌlбpPKrшяь1ЬЩ=hдˆаžAc'M.ПTJŒЉ<~ьјhX 6`I]Б7(x8Ипь9,<Рel˜|zф+4хёЋ`Ж§“!шрЪЕЫхчзšЇf'я$зІMЯ;&ЯŽE^РdPmkuђlю гw"аЕB0‡їкфˆ~с№‰N§ац oDЏPвE1.%‚UЃ z…UBP—ОAи_Ц‘MyrЙJ’€GЬ–ЛЩA‹gКuћБј,ЭБЮUЁ€ЈOР9Еќжѕ[ž8“›б™›ѓфz$˜Єœd г3O}*/7џѓм.u‚ЧaЂЊЁћя:И‹vgзОЃ‡ …щRDNЈ%9џ яь‰P2Чvўз'њНаf:ЇЦD€yЧЇO{§дЩТ­›2ЮџIБ5‚’9бѓœxЗЇP@H X%р5?*ѓИЮЉZФ<зЕыї?GzGВJЙ37ƒ^4=sє+б›ВЖ@-џ8ћЃy‰ѓ‰7‘E,›ЙѓŽГДўМу–Љмй ‡ѕ пєяЄgdž->ЛjQ’b­žEЎбоzf4йp‰щЄФE! Єнknй&6хЩ5ц*i[j О/.юкэ9Е5H 7бŠFеУMьŸq42BYЫЩЬЭpŠŽЬ`’ђŒm[W-‘+;=sъІ šœDMy{Ую§9^,3М‰œаV Љ§ёg•2мˆ7uђDПG§й)еY{=AY{Е S•'ЭK=L@>d№b Ю&{=gіšЅKьОM]эЬсДh eg='3šOˆŽ2нЉ^'˜@]dУ%І“…(‘bzЄю/aKоmЪ“kЬUв"Жд@-|ўхQИ•ъсоЗ–qšнппџєё|иѕЁ]C Д<0IlъMп/чдђ№ААUыжгУ/кmбЬЭг37хВїгпБъ„€ sFjк„;я8] ‚(sжF[юўl—сSѕПUУ^ъ?3Ц2яИ:Oƒ›єDgпЁC-sНkћфЎU{Эс-šбœu+ВсгI‰‹BHHБЉЊћЫцoSž\cЎ’†БЅ >п}џн[+э9щЂpхj‹Ач )С7Ћ%†љ €BN6uњдуъOџ}qРрДІŸПTYєУ…ЗжЌж“e‹ЗбьПЭ{iр ъSњ5мƒўXvXъGЁгЙ‹їWб ШЖћ_КХ*\DH ehŒљЫs\упVу[ЦА4a/рЩПўЯЏ‘ія5мCvзЁš]qяжЃŽ.@ы#рДZоњP7ДЧpРъыя›њц:Л5мƒнЁвАЕѕз)1(@Ў@kЙ+Œ‚хБ0кЉ4ќЈ†{аЮа!k˜Є]9Єkш $аHœѓмЗFъ КEH $а `-o…ƒŽ]FH Eky‹Nь @H ДBXЫ[с c—‘@H EРZоЂ†;ƒ@­жђV8шиe$€hQА–ЗЈсФЮ $€@+$€ЕМ:v $€ZЌх-j8Б3H $а И\-‡чnЖТapё.‹EЄwёю@zЭ7sзg‹"$ає\Ў–7=6"~ХГ4PnIpлnIЃ‰}A ЮЌхл?йи3о9‘ХІљъQDС'xsЧЂ•(C ыЕ}лvЫfвТ†Лгš 8Г–яиЙcЩќФ=;wДцРО#$€h Їеђ3пžіzаkє№(//Џ3…Їн G№ЮdedF Оpйђъji0Џћ с#р4АSV5"ДgаиI“Ы/•ГызoЬ_к/šЯH˜]YYIŒЩ;BѕJˆR}Чт dЭ`‹†› AоmJ€D?ИпœpXаиёб%%ХyŸч|…ц_F[ -н“VЎMŽш Р"M‰ED‚РХ"ШЎ–+шxН'=єZ‚›- 4є††‰dТU’UфŽŽbQдZиЃкH$ Мз…№ЌmaўOJп˜LФ€№нє “ !xж3жњЭиLhкrsоG€ uЮм-4їКЖ’ФЧЫІ‚2@MNРiЕ<{OіишБапП›§IЖЂуф| МгƒлЗ~Xєг…§й;ѓфzЄДє4кЄш‡ йлЖ–|[H4пegnЭџњDПњ-]Е†(ЇЮŽŸ4&њT^nўчЙ]ыД.=єъ( toы9t`џ]ыЮќякw`єЁюm 9(ф]ћТ‚­™љGN 4$&~цБ“G36e@ўƒ#ћ-]Л”иш ўnZХЋћїцРпеWa‘Д…w"ЊчbЕщY™7nчЬйџёЮ‚Тj/в+BˆВMXАxњДзO,мК)умљŸˆ[Ў’FдИ EЁ52'!дƒOšUж™~О›х{sЏнИFє ІеБ':Эh ЛRnЮм-AЭD„—:G ЇpN-‡ƒ€яО??42њ 2hДћПуРžФ„xЯіžюю†ИiёПФКЂі"=А!DйzxxoТ9‘JooŸE‰ Ф-WI#jм†Ђа™‹Bh№ЄMі8Д$!Qо,лfЮˆ#z†ьрŠЦœш4Ѓi(юHmИ9‹ЖкŠ"М 3\DH ‰ И5q<nчЎ7oн ­ћљйЮНfNеHцжя—‡М<ЊЮ€IОIыєцkВеёneMЩ…в”д”ѓЅчс TV1Э-Ь???џЎчЫŒЯ;–ї\Зч іРz˜жђ‘=Yд™”^jЛHѓзњВёІї#rž№с–ё2‘с]ˆъEX./ГЎЈНHЏ!Ъ6u§КŒї?Hп˜юѕ Чь„a=C !WI#jм†Ђа™‹Bh№ЄMXЗŒR<:ЦќАл€b‘n4œZрnдŒ›ГhK ­ˆ ТЋ0УE$€š˜€fMkЄ\юIЛїќђ№!R !”џъܘXщ>aШі>ОЙ[ЖŠj’АYэŠЙѓцЮž5;<8ŽŸрZ{Pя>ЕkјџЃ_‰о”ЕjљЧйЭKœOŒ’ƒ­ (ввкзЇУѕ+FRƒAhягAсDН(ЪЪзЧ—uEŠєд€Ђlž xkЭjАKнII‹?;ќШ\%ы№~7 † vŒ@Int kЙ EЁufЮЦеУ“uKлъiHэDXЌ:фц,коDxfИˆ@pТ9іМММЯќ™rш0Ш =лљэя/ПRwчзИ1Ѓ–ЏYlЪ/•СэoЌБUЙЊЊЪ`м иoXўц:jЏˆBѕСA!І?*vяЯё№№ ш@є ЩA”Ј-ш =dРаЕ)kхSи••ЫRжТЂЖOX+ЪjШ€зІЅš=U‚OъGЄЇDe ЃV^^ї^I5RUэ)Ў’uиљ/fя‚r^yЋrнњКdИ EЁѕdЎиє№ѕђeЩk!1ИYn(#iыiШvа>Y„ХЊ7nЮЂ-AСD„зjP4@H Q 8Ё–oй§ѕ*z5bTєЧЛ?b•1cЃЦO 7аŽ7ЁћГн'ЦM…Л ч-NŒшС[•W$-мМ!АwаФиЉнŸэBэQЈ„Ббу–­Y6i\]Њ ЩA”QCжzцДXЏ‡0rќ=ќаУАЈсЌe5sZœз†C‡ џл˜юAНЈ‘žA”mDп^ё ‰ЁНƒRв7$Џ^AŒЙJжсв…ѓП:њUxп>бБ{1ЩpŠBыЩ\Б1шс3)ЖЫ†G8rxЧŽIкzВДOaБъ›ГhKP0сЕ hTКјя‹Їѕ™ДВТhЌИQОwŠхT~zйНžЇ6ƒбЃЂдzд $аЪ РЕ•ВВК“m­œvПE№її‡гКк]гЎ’№Ыф‹Ѕ­–б‘›KНђЛZ˜sыŸП§v8ЭзЫЕ{‰k‘h‰H! o‰У>! гЧѓAВZЮЮ kЙУ‘ЂC$€8рˆ ypP0gЊ@K!їфn?ЋщkЙЎ—З”!У~ $€p XЫ]b0 $€@vh6ЕœоаЎПЋv4ЁЮKŠŠсQф ё@]щh *(Zmпё!џјёоЁ=шCU;œ~џ рŠE§~kщєёrlwа@HР*—ЋхV3nƒЛUцЧЖ7M0kQŽ}}4Ђя жЌp=@H ДRNЈх#Gфi~С\нD шA&Чvє=дуЮЪLšГ ѕ4бžƒ™2u‚еYКЕ{OUOЃNЛ Юўју3]-' РЦЊўФо‚IЕй аСэŸ|7 РЬх0ЙќАUѓ‹`‰оЉkщтkгІУД4Фо!чAЕsРS%?OС й\cЎ’ф#Gt ДЗ%h*ВС—эzЋiSЖ( $аЊ8Ё–їя]\T ”с)ж‹ж­€‹С Ÿ.*=EON“Т;{ОT{Vf§MЌЮСЬКb€єи‰РЙ~Д{Ч%šіZ$мК~ЫГCн\pVp'іж˜T›[TXs–УЬх09ЬљЭЎRШ,%XЅXœ3љЌЭДЩ{[Ж›8&ЖЁИyrЉŠŒЙh.koKФзFОžIЧEНЃ9ƒаРДYW(#$аJ8Ё–‡†і-8W|sђxИy)UŠЮ€^КіЌЬмЖм& ™ƒйъ,нкНг9KДК/юnuUаЊюФо“jГсшДх Рœпь*›dxT‚—С#яˆ|h3тœќцdдх“}ЙyŠF‡kЬUв<5КЬн0hC"pm4ры™t\д;6tгf]ЁŒ@+!р„чО…tяЖк<ёхсœCЩЫWlњ`ЫаЁУЮž§1i^’6tэY™ЙmЙM23;щ*зvяtЮ­шK{яізoщЬrVp'іж37ФЅwиРЮ€ЎHIЯтф˜ЩRо‰ь™š™1хЕqdвRЖ!7O.UhХ5ц*i.s7 к\ јt’вSv‘N:.ъКiГЎPFH 5(НPъ„Zпtћ=|ќXОСрм3dSжІупцƒF§]пHcрЈ9˜Й~Д{Їs–hEЧŸыкѕћ‹#Н#‰оЊюФо:'еfЇ-‡’ˆіM•ж3|гМ“ž‘yЖјьЊEœ5nž\Њ瘎Єєtv™кыЌТзv"ълЊ1вf§ЃŒ@ #а%Р чиbЏ>ЯЏNй0xи`МzЭа(р*&NVЌх.ъlтЈ9˜E~4z'š%šлЊ„›и?џт(]Дъ„;БЗЮIЕйiЫ‡ B‚ŠІЪVW,BлЩ1Џgdfܘ–ћХ‚љ V/_LЃ_\мЕлst$€@ЎIР9ЕXќuирѕџ/=ДЧГ ‡>г+9# 4њ №";г6m(šћYcNqбиŸy4Ђw/ъ$€@ЎIРiЕІ-ЏњзЭчфŸœ>ѓ\7щю]ашg4sZœз˜f&люTWqEs?kЬ)ЮŽщПћўЛШТєЇ„–H $€œBР П/'§„‘ŸњЖШоо>T&њЌ*(єp‹мЂ…I№Gєу_‰"<ІmQbќYkџСй{‚ ысфъ‘УAЬИёјаЗZ~ј $€\—€гjЙы"1gVї(:OгCH VOРiчи[=y€@HР1А–;†#zAH $р,XЫEу"$€p ЌхŽсˆ^@H 8‹жrg‘ЧИH $€CkЙc8Ђ$€@Ю"€ЕмYф1.@H ЧРZюŽш $€€Г`-wyŒ‹@HРJ/”b-wGt@HРYК`-w|Œ‹@HР1к\ќї0ЧxB/ Р  f‰/ъБсЗlZ-Э“ ŽŠя(‡"?"НЃђo~BГ&L 4—7 K4Чяk—L $р$ЮЌхл?йи3одїІлРŠЋб\13ЌЮŽi8дщЭєhbЮMNДAH Б 8Г–яиЙcЩќФ=;w4v'б?@H LРiЕќЬЗЇНє=<ЪЫЫыLсi>т{RњЦДˆ#„яІ‡яїЄ•k“#њ…Ув=KS89И?gаЈЁaAcЧG—”ч}ž7ђ•Ё=ƒЦNš\~ЉŒищ4Л~нјЦќЁ§ТCУТg$ЬЎЌЌЌk~аХтЖд^Юj9G Ш=г@Ž–рЄеAž+nhnsKhIЂ>AрњТРP0€†j‡мИ4„BШЪШ„qў.\ЖМКкDж‚Ян{v >NЗ(ье nЖ0ІЂ!fнв^з)­БT'Пў­фƒŸчQ? ƒFd,ыy[І"JЬAfзЊ БъоХјФj[в l8QыiдКХџH И8Їеђь=йcЃЧП›§I6Sж™~ОД?{ч{sЏнИFlвпMЋИquџојЛzу*,вЖ…[33ђœ=+ГтЦэмƒ9ћ?о iPc*гр№Юž/рЙт†ц6ЇЮYы3aСтщг^?uВpыІŒsч{ЕCn\ж3•Зo§АшЇ 0.љGr= RZzн§p!{лж’o Љ1д =7[!VИU,ZАч&?чП>=єщёcљ`w,dаˆŒAЯн2AЏ~Љ9sP4д Р%F›ЋУС*n=iPЗ( $ртœSЫс№ЛяЯŒ:‘‘‘ ƒFMjЯCK=л{КЗ5ЬœG хLœ•шi~-™•x(їKкpюœDяі>юю†ЈбQwџu—]<ЎФ&ГНлГЛw“ю3@ши˜и“_ŸЄЭ“цФЫ)Й&DGџСтіасClVдX[рКв­эЌхњє№№0о„“ •оо>‹х*Ѕ~щЛуРžФ „ИiёП9пX’И[&7%ЕRф“Ед Р%ЦЖUЫм&zвPЛB @ЎIРЭ)iэмЕѓц­›Ёugbwю=0sjЌ"™ЫЦЫојЈ”7Љ„[ЦЫд€V(Д dяжPЋzz‘YЩ…в”д”ѓЅчaŸ@nЩprokЉU…КeSЅще…H\WЁnъЉЙ>SзЏЫxџƒєщ^zЬNXж3Є^ѓ‚ўИЗ~П<фхQu8А—SЇg$Qмl/…CЬИфˆzFA”жюŽˆŒй@œ<4U"Ÿl# \bl[ЕЬmЂ' Е+д $рš˜Џс&K№žД{џС/‚cDЪЧŒufL,9Ђ‰јњј^ПbT”F_ŸT B{ŸдоТмysgЯšЧхp=8ЈwmчlЊ•ЖБіZ[Ck{#kž xkЭjсКuRвтЯЁnЅ?n{пм-[Ee[э4z  EC|П›cAvдш ДzFA”<мQБчгCяМНauђ†№АpВе‰Œй@4ЋщK‘OъЧм‘FпШѕЄСІ„2@ЎLР чиѓђђz<ѓgZШШ Н‚'-K^[yЋВњŽ n‚#k‡ К6e­|ОИВrYЪZXTДrШbUU•С Й АŸБќЭuV}№ткДTsR•зОCћћЫЏXnСуЅ(ДЮц\Яp‡Zyy™|Ÿ`TU{ŠBсPWэpм˜QЫз,#Л,PСЙкFЁс& АЁ‹Ђ!юќ—РГwA9‡Mbнzd=ЃРM|Ю[œИnхђА>с ц/јяѓЄ{ђ }\cаsЗLQz Ю"ŸДћ ˆА6"YNdІ' Q[д#$рjœPЫЗьў(њ•hˆЃЂ?о§‘B3)ЖЫ†Ч/‰ IDATG8rxЧŽЩк™гbНzxРШa№ї№CУЂЂ•CW$-мМ!АwаФиЉнŸэbечЬiq^ 6ќocКѕткЧLŒ?Нјk& ­Г9зgDп^ё ‰ЁНƒRв7$Џ^AlEqеЧ›а§йюуІТёP#њFЈmn К(тЅ чuєЋ№О}Ђc'ітAж3 мф“зЏ=.0Аф ў:l№Ъѕђзєм-S”ž‚ГШ'э>"ЌHV„™щICдѕH И?]ќїХƒгњLZYa4Vм(п;%@;EјбQdџє‚Ђк FŠRыQƒ@H hWIјAѕХв‹VЫшШЭЅ^љ]-ЬЙѕЯп~;œц„уrH$€@HРА–;&КBH $рXЫC"$€p Ќх„‰Ў@H 8€sjyIQ1<ЗмънŽтAQСQžuњqV\щЙ‚YS"r`Ќэ;>„чі+Т­+ђCщ­Эaoе@сVНhгчHNЄW‡C @.KР9Е—zƒЭ;,˜ѓ”\]І~h ‘аxŸ#§9ˆrC=@MIР9Еќn•љ!чMйQŒ…MризG#њО і*oоцЉYдЋЋСЯ‘cyЂ7$а| 8Ё–“ЃxЇ,*fПVЯЏPU•щў?SоХ!ЇE ВЫŠiъВ~vG' E ‘ &hъ1ђЯЈ WKX\)D1QЩ4ЄdXр8 і‡в‰ќ3^џ`6ъЯ2Ь’ˆф6cpMУQfnЂы—k~ЯёХ—ЗНпНЯ>џичЯ—Х:>ћнЯћМпїѓnЯУоgŸ§HCЁ@РsњНйА=mю›žРЁШbMi}хУ†ЎНQЛsџок’Ђ6НёњФ‰“>§єЫТЅ…4ё мZЊЄ•žEgТвЂxБО5П7ŠтH'Хт‹нХЖŽюЉХATХЅЦнwGн§ѓњтщRѓƒCduэД"+‚шLSс)nJс Х!“СKкaХHЩЬۘǨє7‰уЫЊ*ч?5“еZ‡…‡]Ид!VќїБЅSцЕŠОsЉa—˜8YЮMŠг  э "а/$\y‘аC#9VZ_™оO~ї У4X­СУGŽиДyгсЈ…НЯЏРэЈюЏUZ›;0CЌo-–3—NJбWгˆ-Ђ*§Qh/еВлДљuЪхoзќ~iў2цЏYЭѕiђ€Cd––Ш .ЌЛV7=#y>tмШјMџє›ŠЪЊOO}њтѓЖ??оџч_žJ OTДЛkгЁЂя|PЛФФУ@<8yбpNƒ6€@0сѓrƒГвЊЏ€Œ!RлщŽвhЎ4r%мp%š‡њ:Tїкu 7\ib7ЮТЁL‚ЁAL'`N.7wкxѕ\ныО\YWжб•Оž˜ЃЗщёФ@Рs1—;їQЈ?НлzЎюЕчŽTudЛыЈГdvћŠУщФн\БвЃ5Pшдэ цФ\n.qouЏНa @мEРД\./8}sZв:йД“Ю<Є%ŸoіГДўWы„ЩSш›јМEm№г­hъšЭЌ НђОZ еУQ‹Дž4…’ж,'Х.>( Ю7ЩвPыUБюєЪyX…ЕlOд—ЋUзСBQNт4ХщѓЩrCЪw‘ЦбъЂ&ЦуєЕУй(фC†нUА…Rё‘шд(п.aЄL{rќ рХLЫхв‚г”ДN6лЋSђљ“ŽџћЂь‚eЙ:дсCшDSзlf—@щ•_ еQЈBЇžДДf9ыЎГKŒ/ЅЁж/vчТЇЃT*лѕуЅjеХе ХIЉ'qšЂЇк–2фnв8в.Rb<3Œд—^+ІšZЇNљv>„‘2эŠ)`@Р ˜–ЫЅЇ9 :йZ%ŸЉ HсКПлXNх­xЛ†4š‘šЭ: ƒъд“жЉYЎГKŒяД~1ЗХAЅВ=Q?^J[]Pœ‰rйdшNЂЇк–2TЛ‰-в.Rbb/ВдчЈS‹8œNљv>=бТH™v1,l/$`к3\yсdБр4ЄS'[Ћфѓж7_M}|=s‡1bHЃЉйЌЃP1ЎN=išх:ЛФјNыƒp[T*лѕуЅДХл\ЂBБ]џp=еЖ”ЁкMl‘v‘{‘-Ю‹kVјˆsдŠ)ЦQtч›:хлХ!ь–iчa€x-гr9/M/8Э1Ќ“Э§ЩxЃЊznцыOя˜ѕDšию„mЄfГq…vыIлUx[?ЫЕkWYіЎ.ћЯм5Ђпю RйžЈ/U+жиЖ+•є'#\ї‘S„чeЄРšVL1ŽbОiА|Лн2э< Џ%`к5viСiŽIЋN6wPtЊAщ|чvRщ*О—пRФ[ŒвšЭŠтгЦк­'mWвНПђVЭvJч]]ы_.Жы/еoЗ—ТAKЖлыЧKеjWˆф›вУIБdмйQУ`-bтpеЇŽZ1Ѕ|:—oз/г.ъ‡  рLЫхв‚гœ‘Vlю 5lщќw•;п­Ѕ;†Ш*Ч9WШAZГYQ|кИBЛѕЄЅsW-_іЧCŒxLzцœQ1ЃФ]R[Њ_ъЉгЈ%лэѕуЅjЕ Šk –NŠ%гъkЗн`-bb|‡j‡SG­˜R> ЦЫЗы—iѕУ№Nў\П|Qіг ŸzzШАЁо‰ЊмE€ЎО(nШwWф‰cЗLЛ[8аwэP'Э-$Ф› аЧ T'MџЛTєAЧС‰њхпь/7эѓђ>XŒх›њ` >M€О+oЗLЛOOтA јs.„ѕУAРtIeк]ˆО р%ЫНd! УyИРю4; s:‚€W0эо7ЏЂ1   рЛќ6—ЛRЂлЁoВ9фьЛŠ'”;‡Žn ЁGю;ззГ@L0€П]cЇЗxvй•ш~у&vоh:nw №Пй%УЇ\ZVZАЌ nфЛ]ќЦЯнЇguќpƒЃOfєщ)C| ›ищPяћ‰ћ[.чŸџљG‰n­‚Oг?охЕІ)Жѓ)гЪЦ  DNјмE nБћђјЁgП“fzЇs‹rя$@‰œъ},Япr9Ч‡н…ŸЖ•НеЯц(гЁї8Sоц…/цРЬљМ\ZВšNдUЈйвШЫBЋJ8“3_i“§ђ%ж ЕІИ(6.>!yќ–wфЕЯu –ЫeЋЊG_ћО+!iќЕяЏr1Ж–фžЙА›3т]˜ЁžІТ6™oч›Rјф& хЬУJјXЬ­wSЃz7Uу^S\’06ž~Щ Mѕ Т_{cоtUД№MЉBъ$/ѕR”ПоЦSZЖ\ыРАљяо;!uJl\ЬŒYщє1§њЉOL‰3cюМі3m<ВT пK†нЙpg-‘RТ,,Нђј< п"`N.—–Ќ&pъ*ддhМ„3GЯЎIв+ћхэZЁŒT•ж)X.•­ЎMХЕ&ŽЗ}_яп лџsЯД”‰A§­ZТИrЉ!NSъ m”Тз uУкuЕ8ЋY‰НDл‰)KjЭ—ЦтЕНХq™--[Ўs`k‹UЌNUЯW­^WЕЉ,ь_"§jўžwыиpRјZЄЮ\6R­ЁЕ8ыАЧвЗЕ•*дšЏўвН:†д_бшщ\Ѕ›Z„uŽi4‚x!шСб?љчўgЪхcцЎЙмбqљbћЎљ=gŠZrщ;‰у’ј'j7§ЪЌjоB' ъ„ФїІьЙю˜5€€аЯ’Ј_ю‡Kь~ИЈ˜€И›€9Ÿ—Л{ˆ  KР‹r9.Аюaˆ™ƒ€И@Р‹rЙ Г@W\ў™ЫŸ]VАeы[ЛЊ˜9€€@ №Я\žŸГЙz‹хzo“@ZSЬ@@ А˜“ЫѕŸb|qј&=єЁ‡Њ?|иx(x‚€€€ИхШ…#>*]_іc>ђС‡Чє}А@@ќ€€9чхIџЈ\ДVkY;; ЇW~:ЮУ’ёЫЁCП<ѕЉи@@ќ’€ЩЙœ˜ŠхЂЅU–ЩGкЮОУFЏв/Г…ˆ8wЁг/з “‘€9Й\ЬОbЙh­*ЫZэтLШУ*va@@ќ•€9Й\Є)–‹жЊВЌе.ЦQи.uмІhФ&€€јѓsЙШ”UYf-Tп:,bГЕкХО ћѓSЇюњ Ђ›   рМ+—kUYжjзЉО|р§C ЃGљп‚aF     р]ЙœЊ,‡D5ПщwаРAМцЗV;ЋОЌОЮщO|~"ё‘8ХlБ   ўG ŸЙSRо­vЋѕљќ<њUЊвhŸ5s6§*-–тђВŒ™Г,ЗZеЛа  ~FРф\ю!šЏЌ[ыЁШ   оFРЛЎБ{шя'€\ю§k…    GЙ\і€€€ї@.їў5‚Bа#€\ЎGћ@@@Рћ —{џA!€€ш@.зЃƒ}   р§ЫН @@є —ыбС>№~ўљм7яч… рQŸ4okkѓш  &5Nч­-­Шхш€п 3rJфУc†ћнЬ0!№vбџНхЕЭ}œЫЃGуѓro?2 @@є —ыѓС^№vоžЫ‡ФФHjЕKнвиї#КEЖVщtЄZа.hj:5aђ”>иCˆѓ‚  рМ=—л…ЈѕжІеn7 ˆш9z”–•,+hjltД#ќA@Рufцђ-яl22†^]™їTЄоюJ№€эыЧєЧ‰Л–ИљєŸт†›№EwщGŸ&`f.пКmыЪeљ;Зmѕi‚DрJїЫ­  ц0-—ђбёалCЇMN ЅЏУіЮўКeMqQl\|BђјВkДГг,ўЪЯКИaБu,IOПdа&ћ!‡}ћіNH;2fЦмyэgZYћ… Я.+ˆOххvuuѕjS[з-Ы’Ц'$ХярtFм}cФȘГвщжњѕSŸрzžьafРMKЇжМnpUOJИЦЎЭbй\YE'JЫW]ЛvU†њnyч-ZGђЁ5хфu”яиЙніЉѓHлM:nFјPЕB’DэєЪ ІYэЦ|D1tˆв’бЁB 6Ќ#U†е>ԘМ;вјвFr–Зb4и Fр–k]зL™sЭЮšщ3hш'ЇЭЈyЇ†kЈи\uљт_ыіэн§іЖcЧьЖ3vM˜^е‡+~[~љтљнЛівяљ‹чi“Ч2vе‹ыXћ‚мœЙгг?ЎЏk8P7јgїЌЏ(уўjcѓU-_Ÿй]ГэН]uп]ќŽ9шиxЌКЊВср‘ф )9Y=TЙЉ’$'Ž]UМŠЧЇ‰лuгб)—X>Ј–!ЖЅњ­“_ЕаФж[-хНTХ8'Oв:вjвš’ЖKGљЩ/ZjоЌnњШіЉГŽ›>R…ъуDъЦtŠbђ V<Н№™6VoЊќЌљ+qŽd+ТъbL1ˆ4ОД‘zIWDŒ@ амдїsІSЎŸ7OLLЄЁЩІ&Ѓvmўтќ?+чsmZэмAЫЈ­л'Ќ­{Ÿ{>—džжќEkпЕЅfШАЁ–[­A§­™™G?<Ъ§еЦЮ=Е+ѓђmAњ[Гe3—<—A#ІMKЛђЗ+тfѓg=(ˆиЎхІЃS:/ЇJЃmнГ3?Џ‡^іТœ}яTУЁNž Р|t”/ЩЮЁ•ЗяfЃA…:nЂ˜рррŽKtІ+<<тљќ<щdyЃо Lћ“!/m$gщŠˆб`ƒsžћЖmћЖK—†Фі~пlлЎ=Y 2‰ўйŽГсwEАeр†NЛн;лq‰Ч!ЃГу,ядП'mPrНђCOsSK+н“ммкLIджЄKHTЫУъŒШHўт& hWlr7вy‰R9ЎYЧFыќіlЪуЉНН4(ёDђ:ЪщЏ"SЯэfОзСhPЁŽ›(Іьхѕ•ЏНQББ"єірмМ‚И‘zЗЙщТљLЩЦ—6’ГtEФhАA€Ц{АG1\ЗьиНя§§ЕtŠУЦЁ“ђщГ~••‘IwEFD^8зСr\ˆV;wа2"#ˆУ"hyВі%K—ф.Ю>‚NЕщcр˜бctќEUмЭбyG‡ ‡tRdQЊжЁAЙsXDdныеbЖуЛDуЧф#й.ƒЪ К‰У‰ЖA…ншЙŒЏЌ[Kёщ3ьТТяюOKa;qHуKca@ˆ€ їОезз?єЫу‰œDM-дNvJвЃХхeЖЋ™]]ХЅХ|‘ДкЙУ€АлкЯI CЅ$MЄ8,ръвbкф]ЄFwwЗеj ВZщ/ŒЂ—жK}xcъу)ЋKŠЛ:ЛЎ}•n‚cэŽŽШЃ9d8Є“"лшаш3ЇЇ­[Эў&h?гFЗПIЛ‹K™’œТ| *7ш&—Е*Ž-7EXš`{{›эіН,н7/с(|јІ€4ОД‘@8rљы;~ŸўD:WРŒ)Љщoяј=йY ГCjMš8iђ“г‡ХŒтnZэм!cNfкЌйт§ЩlWжТЬаƒ’ІNЂпAб&я"5^(\ОЁdУб1s2 {`Ад‡7fЬЭ|п=“гЇŸ:љЮ;яdэŽŽШЃ9d8Є“"лшашГfЮіРА9й шжюЅ+ђNv'€ДŽДšЁwмaЛюrуЧ rƒnвqЉQKЁт8бrS„MxxTN^~ьш˜вŠ %k_PьUl:qHуKca@ˆРONџуtRrљ˜Йk.wt\ОиОk~Д>њRMтИ$ўAЏк™ІЅІЉлбhшя*ѕз  ‚)ѓЅџƒЈ“f y t ˜ъЄщ'A§,I_W>нzZ?qžњjkшРЛЯ7юэќЫ7пь/7сМ‹    рFШхn„‰P   `фr ШИР i‚˜NЙмє%€p‰rЙKја@@L'`ЦГbLŸ4€€_ˆŠŠ:~И5узГФф@Р аMьєАя•!—ї=sŒž%0<ЦіˆYzOёь0ˆ  "@‰œ§TэёlrЙgљ":˜B€оMLyC1eВ@Ÿ—уп&€\юлыѕ   €\Žc@@|›rЙoЏдƒ€€r9Ž№mИнЗзъA@Jр“Цуmmmв]h№|'Эsl‹KфTі4АІй‚€ Ч4‘Š>ўFhkK+ЮЫН`ё!мJ€ЮШQПм­D Œ ч-вcšњ8—GŽЦчхFW~   рЫНs]  @@Œ№і\>$&F:­vЉГ[ћ~DЗШж "ŽДQ+кEMMЇ&Lž€"и }FРлsЙ]ZяžZэvТ€žЃ‡AiYiСВ‚ІЦFG;Т@\'`f.пђЮі!#cше•i№wOEњсэЎиО~яZГ7 IDATLOqœИk‰›Oџ)nИ­:~@@ я ˜™ЫЗnлКrYўЮm[ћ~кмKрJїЫ­ю ‰h  `”€iЙќ“Ž‡о:mrZhh(}ЖWяuЫšтЂиИј„фё?:eзhgЇYќ•ŸuqУbыX’06ž~Щ MіCћіэ:%vdЬŒЙѓкЯДВі :ž]V;6ž4,ЪЫэъъъеІЖЎ[*6–'$OHŠпС/0шŒИћЦˆq13fЅг'ЌѕъЇ>Сє<йУ&Ь€›–N­yнр Ћž”p]3šХВЙВŠ&N”–Џ.КvэЊ: ѕнђЮ[ДŽфCkЪЩы(пБsЛэSч‘Ж›$tмŒ№Ёj…$‰кщ•LГкљˆbшЅ%ЃC…:lXGўЊ Ћ}ˆ1yw2фёeG%Ѕ*Fƒ  hLЫх5;kfЄЯ мON›QѓN ч^БЙъђХПжэлЛћэmЧйmgьš0НЊ/WќЖќђХѓЛwэЅпѓЯг&yьФЩšЊъ†Œ}dьЊзБіЙ9sЇЇ\_зp n№ЯюY_QЦ§еЦц7ЊZО>ГЛfл{ЛъОЛјsаБёXuUeУС#ЩR2rВ>8zЈrS% HNЛЊxOЗыІЃS:/-А|P-CmKѕ['ПjЁ‰7Ќ ЖZЪ+zЉŠqN6žЄuЄеЄ5%l—Žђ“_ДдМYнє‘эSg7#|Є еЧ‰дщХфЌxzс3mЌоTљYѓWтЩV„е9Ԙbi|щбEНЄTХhАA€9ЙœNЙN|о<11‘p'&&’M- }эўкќХљ!7~V.ЮчыЁеЮДŒкК}bРкКїЙgсs9!a!AAжйщiЭ_4Бі][j† jЙедпš™‘yєУЃм_mьмSЛ2/пЄП5kQ6sаqЩsљсa4bкДД+Л"n6ж#€‚ˆэZn::Ѕѓr 4кж=;ѓѓzшe/ЬйїўA5jсфЩ ЬGGљ’ьZyћn0TЈу&Š юИDзhКТУ#žЯЯ“N–7ъТЙ?вјвЃ‹œЅTХhАA€9Я}лЖ}лЅЮKCb{ПoЖmзžЌ™DџlЧй№Л"и2pCЇню‚эИФубйq–w ъп“6(Й^љЁЇЙЉЅ•юInnmІ$jkв%$ЊхauFф‰ŠF$q“ PД+6Й›ŽNщМDЉзЌcHЃu~{6хёдо^”ј@"yхєWЉчv3пы`4ЈPЧMSіђњЪзоЈиXz{pn^AмHНлмєa‚|ІdHу‹K&:KЉŠАA€Ц{АG1\ЗьиНя§§ЕtŠУЦЁ“ђщГ~••‘IwEFD^8зСо­ШрBДкЙƒ–1@ 1@Ы“Е/YК$wqnќ№tЊMЧŒЃу/ЊтnŽŽШ;:d8Є“"‹REА ЪУ""ы^ЏГп%?&ЩvTnаMNД *4шFЯe|eнZŠOlЎxwџ{тX л‰@_\2q)Uб6€@ Иeђ/&їёœыыыњхПёDNЃ“M-дNvJвЃХхeЖЋ™]]ХЅХ\›V;wv[ћ9IaЈ”Є‰‡\]ZL›М‹дшююЖZ-AV+§…QєвzЉoL}kцьa ›“Н€nэ^К"?ссiwHыHЋzЧЖы.7~ *7ш&—Е*Ž-7E脇GхфхЧŽŽ)­иPВіХ^ХІ€4ОєшЂБЄTА  P~rњЇ“’ЫЧЬ]sЙЃуђХі]ѓЃѕчO_ЊI—Ф?шU;“УДд4u;Z§]ЅўZA Apћ|PЅџƒЈ“цvђFа5`Њ“ІŸѕГ$}]љtыi§ЄdъЋ­Ёя>пИЗѓ/п|ГПмœћи€€€€ЗДЗДёƒ€€€€wИeЩЏ–xЇ2ЈђuИРю‰UOPEL№uЗН&Пйз'§    n‰bчfЗi‚€€€ш7&|Ьm1OјЈzШPˆŠŠ:~Иž?Ѓо… ›ищ? G‡яwфТњNštA|‘Р№л#fщ=ХХC3ј4Jфь?`ЯТŒgИіё1z71х %№HcЦ р№§rЏXˆЇ —;A@@Р+ —{Х2@€€8MЙмitш  ^AЙм+–"@@@РiШхNЃCG№ Шх^Б   ЮhmiE.wz€€€Wˆэў\NOНЁBы^1?ˆo"@љбyuџsпигІЮНщрЏ рЁ‡МК?—->кXНЉђГцЏ(‚ZАs#Њ#S№ЭoTЕ|}†цўоЎКя.~Ч+&олоxrїллъіэН|ёЏ›ЋЄђИ3 п%`N.gЇ†ќе†яVKщš—ж–o гю хШІѕЯж=;ѓѓrBТB‚‚Ќй sіНћ,ЩЮ с›…ЯѕИЭNOkўЂ‰ЕякR3dиPЫ­ж ўжЬŒЬЃхўњ†4ZpppЧ%:Зя x>?OСЙЅ‘wюЉ]™—o›{kжЂl>œbтМ=q>Ё2jїзђv  ~FР#Ÿ—г%тЖЖ6ЉiЉiМ…Ÿgѓ2(ыЄ>žRV^iЫXBV}:П=›ђxjo‹ Ÿ’\oЛХдПg“Вў•zі4ЕД––•6З6_љл[“а]ьЋЖЅбЪ^^_љк+BoЮЭ+ˆ9BнбЙЅ‘Яvœ П+B=„bтм;“бйq–З+ КDЏhС&€€€‡DEE ‘$ ‡3œЭ УЙ˜Й vm?гЖѓЕПљѕ†Е%тутy*Л‡EDжН^­•НDOЉНdщ’мХЙёУGаЉ-}ж3zŒдЭ`cєПFПВn-9г” WМЛџ=uGчF”FŽŒˆМpЎCŠE=.Еpg2ˆ›д‡X)­Phа'РNŸмžЮнЮШH”Y—ЎШ_ПІ(nL|СВ‚џ(XjЙnЛЏm@иmэчzOёgNO-ZЗš’эЂмOЗПщSSьэююЖZ-AV+н’VєвzХ^G7iєіі6лme?XКožњ+;7Ђ42]ДX]RмейuэћЋtœ]ЕХхeЖККŠK‹S’S˜ПBžн pp#ЪъыжЎЧwџyЙMŠћЈщ’{ЩЫыgЄЯ2d(uЇ‹епЖ­yy§ѓљ…s2гfЭІKтьВќЌ™ГЩaNіКи~я}їЭЫxЦШpмч…ТхJ6<ѓm.уЮjцžН{ј.'Œ„‡GхфхŸkћš””Ќ}EPvnDyфЙ™П-Ÿœ>ЪZaW№АO~rzїпЛ'=6.+#S*Яn8€€x?ŸœўЧщЄфђ1sз\юшИ|Б}зќh}бt} q\’жчйд—œ8/з{%@-IoJp4ќA@мK@?K65:нzкnњjkшРЛЯ7юэќЫ7пь/wџ5vїЮб@@@є —ыѓС^№j­-­Шх^НBN‹УvЇбЁ#€јшСбШхОЕdP   JШхJ"ип"€\ю[ыЕ    $€\Ў$‚m№-ШхОЕ^P   JШхJ"ип"€\ю[ыЕ    $€\Ў$‚m№-ШхОЕ^P   JШхJ"ип"€\ю[ыЕ    $€\Ў$‚m№-ШхОЕ^P   JШхJ"ип"рЙ|HLŒїcх"Йс šЗl}ыйef)q…гMŸЉ[”75š0yŠ[B™у‚є%пШхœˆ‹яn.vч2њвpEѓЕkW7WoЩЯЮqBА+у:1ытш љ;фьє\щШ––•,+@zW`Ђ/sr9НgБп„БёЫWtuu„ютЛ›sнљ;ЌA‘юuГЋYG^УсУЃc П+Т IvЧu"Ін.ъAufGбдў:C8фЬуш рnn1ИТцгŠ>Т-1@ є3k’ьm‹ВxyEYбЫХЏМАж,%~<юJxј?ž ПNэJїЫ­.Mю“Цуmmm.…@gЧ DEE 1сqгr9C’ї9ё“&ѕЛnYѓrЩСїівцИё“ž.OёŽF'I=ч.з-П-пБ{ŸХв5?{кiO-|њЩєџ“˜ШB]Иа1gюЏўsћю ўжžр яNЦКU+7ОўjчЗgя§_C^ZЙью{ЂЩоKНсO_і/‘‹цЭŸ8q;-cЏlhŠ\\Zvфу#–џg‰Гіљ•4 >„–ЁŽlѓTЭ‚кhЌ•Ыђ_}sыйŽГM5в&—ŒќМКfо§їюIЧ=џ\!СaТиkAСЇ_~™ѓtяvŠЙ№MЉ6О— )+ЫѕЋk^ZПїРСрлƒ3цЬ*.)S  ЖМѓ–B3›Ѓш,ŽЅhgЮє*Жг&ћ;ЪEоєЄэ:Ћ9Pж‘^™‡Vseе–;КЛЛЧWИtIPэPЄ˜тњR џa еƒrƒM„љˆИxƒўppу‡(TпЇs“sљ |A"ЅчЫЯяоeЫхkVгfжЂlОW46ПQеђѕ™н5лЌAAUoTбЎЇ3ц­§ѕžЫїњ›3чЬЙиьc'NжTU[ћНUГ}е‹ы^лќ:5цЌxЁpyмЈј —:(хrzgяАМћ‚мœЂg ^YSxэЊ…†^_QітђBОWЫPG&Oѕ,Xї“_ДдМY­ўсdуЩнoo#Ÿ"‚ГЙ*kAІZž( ѓBgШћgHЕ‰qЄЌ*~[uљЎжэГ-VбKХЂПhЋ5‹{ѕm§й)њJE*|јІдYЭA-РјъoЉ~ыфW-ЖCДPЩЏз—W”?їl ЕОlЏzP.л Сљ№˜с§с р.бџНхЕЭ}ŸЫЭљМœSЃkьє67&v kЉ­л—П8Ÿr§Ќ\œ_[ї>їT;їдЎЬЫ ЁlЭђ=Б ЕзЌ'Я ч:ŽўпЃiSвНФЭТчrlнƒЌГггšПhbЛ‚ƒƒ;.‘ЈЎ№№ˆчѓ{оyХ^dякR3dиPЫ­V:3#ѓш‡GвMidѕ,Xп%й9D@‡У!Ѓv­кAндЏїВ„z/k‘jЅЌhuђлtвЮэuNh‡6nKEju—:лх@бŒЏўж=;щ: ;ЦВць{џ ЃЕОм€8DРД\N'Лє;yъЄюЋW —ц3бg;.ёЕШшь8Ћ5КўЬ=ЙЯМŒyПЉz•6ЫЊ*ч?5“]вф{FPџždInW~шйYіђњc›œ>}jъ”УWta›M-­t=?vl<щ=цвп.IнвШвYPGJŠюl“OYяFјІ–!е&:KYйФ‡їмUЧ…‰Н˜ЭwдЌŽ ЖАУ†^ХFfKEЊнtœэr ОЦWŸ>ОIy<• ѓшЃ—:{­ѕеR‹vа'`к5vКЈV1€NЉйЛ?aд>Ќ%2"’{rŸИ‘ё›ўщ7•UŸžњєХчэ_їцЙA—G^YgЛ >q,,\ёюўїј.n,YК$wqnќ№t^N_њЂtЮwщвШвYшсSО'RЧ“эz№ўћ?џђTbxЯ=ЗѕГ`і']{рнЅкј^-УЖX:X:'=ZnRЭZJД‚№vщaУїКhс`|ѕУ""ы^ЏFкvqQа@РгЮЫЅтR’&—лЎqwu­.-ІMЉ5І>žВКЄИЋГыкїW+6–sЗyЯTVUвmkŠ›цИƒОБ|uQ{{н’fљСв}ѓd}@иmэчzo І[™ЌVKеJ™ЌшЅѕњљ^id­Y№^ ЃИМь›.Ђ”’œТі*ф‰]ш&іят-їўbн@щœИ­ЙїnЉ6оKЫИБX7ѕ”—iЙI5k)Qб™кйХ)…уЋ?szjбКеьЏœі3mмEyш ZМ+—g-Ь 8(iъ$њ4pmjщޘ›9јО{шbјјЉ“яМѓNюfэgЙяоHКgЗ8d$<<*'/?vtLiХ†’Е/АОs2гfЭцзuщцИ %†ŒŽ™“Й`иƒ Ц—Gж˜…VLnђ“г“&N НуŽЌŒ8 ybпјИИ'N№“цUЫ—§ёау“ž9gTЬ(ю)еЦїjtЏ@шO­$†$ ћХ`:е–ўH5k)QGа™кйХ)…уЋ?kцьa ›“Н vdЬвљ 'И(нA@@‹РONџуtRrљ˜Йk.wt\ОиОkОэЋY:?;vnO—DЗ;iљУДTН›ЮД:КЅžWњијGјньn‰щ%Aш 'Ў0г3\щЎiіСч&B3,ЮywчznD6N€ўввpЛqb№w KЇtЛ~дЯ’єчг­Їѕ#кЉЏЖ†Мћ|уоЮП|ѓЭўrя:/w‘цО}{џќпіЫDю4:;є\"ЇO7ш3:vЫЪЫRЦ>ъДHtp…€Ц…QWBšд—N[#Ѓ"Ы €m’LП–>н Я8Кшї№8КфюWsУd@@РwјO.wтњГя,“MЉNЎйНф[Ё@|‘€_]cїХ€fp‘€Wфr~‹Иг“i:y*!yМС8ZnZэUiuзjЗVк‘nюЃлйьі…€€@р№Š\Ў…[šЬЄЮЅKK^,aWЁї’†R4К7š"И›єДT*UBuMœш‹.  ~IРœ\n0Aџ„˜ъ=ЇgЄпј1оЫШŠК7š‘ѕ}шЁx=єP§сУњnи   8ЬЩхnчkЋї0?=њШ ˜щbЂ  v˜ЫйI9НŠgчєе№ ЉSш Y3цЮk?гЪTsz:њŒYщД—|ШS1'1 ",NHOOаЄg—*:вГZзб^њЌ}Ы;л•{olдРњR­n E)ЌэAА?ўЁgОвЇнT”…ххвзВй~B:}оЛѕПZ'LžB`-П:єЫSŸђН\!o  PLШхьЊ5НŠ—ЏY=щ†Œ}d,UWЌ–~zс3mЌоTљYѓWŠНb@1&/ нpА.иjЁвŠŽTќђХПRn* ~ЌбЮ™ЎО™еъІ€–‚+†ЃвзsЇЇ\_зp n№ЯюЁТчмAgњŸ|tќпe,Ыхпў qюB'я @@ Р ˜ЫЅФЅѕЄЙЇ‘Твм™:Є™•чеЕЉ\:я(5ŒhрбЄѕХuJ_kMЧюН…ыVќnc9•€“ЊЂFёЯ-Дƒ€ј1oyVŒ~ёi*,]љк+BoЮЭ+ˆ9ТШ’АвНžЊЙŠхУy™э^џ[F4№ dЈ‹ЏSщывВвцжц+ЛёщО Gkњ[п|5ѕёiT‹SдB%Щя [`ƒ€2!Ÿx1#…ЅеђэЫ‡ѓbbъ8ЌХˆi­nаxщkохЊъЙ™sЌ?НcжНхj>?uъўЁr  NРœ\ЮjBп}W”Aњtчк‚ysюў—(БЌИнОЌ€4]юІГd* ]љfѕ‹+ Х^)IRuэТЅЖЋыT\мЅЖhЃЅмЌ/ЮC‰ЅЏЫ6Uђv#$,Ф–ЮŸ^`љс*UIažо?DЗВѓ^tя.Гs0ˆ@TTдёУ ŠЫ9  аЈH§ьƒC˜“ЫYMhКдl0 БТвчкООїОћxYqХLд›,љQiКиNчe<Ѓ№ЩZ˜НцЅ"ЊР|{pЦœŒКC qгˆVЋЛћян“Чы‹ѓ Ќєѕ3пцвѕ€љOЭмГwпЅcивљя*ч.Ђtn™5g6њŸјќФ+k~єG‰Nwь @УclBб{JЮSs P"gџћX†Пе/яc|}?}Ћmи/ѓsєО€A@\!р‰њхцœ—ЛB!РћzЎy€ƒХєA@Рw xЫwв|— ”ƒ€€€ЙЫЭхбA@@РUШхЎD0—rЙЙќ1:€€ИJЙмU‚ш  ц@.7—?FW —ЛJ§A@@Р\ШхцђЧш   р*фrW Ђ?€€˜KЯ}3—?FјЄёx[[›GB#(€€6ГžЧŽ\ЎН&иОI€%ђqёО)ЊAР‡ P‰BRпїхUЫ}ј t 3rJфУc†KїЂ@РsЈж0•(ьћ\ŽЯЫ=ЗІˆ   }AЙМ/(c №фrg艉Qw“6Њн|НЅЉщд„ЩSм5YwХёuЊа NhmiE.wšžfGoШOžгPZVZАЌ ЉБQsў^ПУspМ~ъ р‡ЂG›–Ыллл–Џ(HH3#cос# ~и”<ЇШOžга|њOqУG8НX NЧqЅЃ]8о в• Ђ/€@ 0'—_8зБ`сПŠЕ{ћЖ?h\ѕьВя4є>:п+нW,ЗњЈvШџ$`N./ЋЊœ??cтфI!!!”шњР‹/Ќэ|нВІИ$al<§’aЙогLЇJћvя:Хv?+>Е­?P?ѕ‰)Б#cfЬз~ІчБн.\шxvYAьијиИјEyЙ]]]l[ї}7Fщ л*Ј*"ч„фё[ойогЈё?ЋгŒfБlЎЌКqM"~љъЂkзЎJ"isиђЮ[$ƒФЌ).b|иˆє*-(зр)›)}5™№UBM(Т”i‹мБsЛэcѕ‘?КБ@й§Ft9pˆфRЏ[*6–л„Єј7WŠЦѕˆ”ŒР$™М‹6A@Р˜“Ы~|4ё‘$щќ+~[~љтљнЛівяљ‹чi“Лk2vе‹ыX{ХцЊЫџZЗoяюЗЗ‘ юlз8&‹ЖЅњ­“_ЕьЎйжpА.иj)Џш#ЈУсdуI’>—jШIDATAbH Ѓ.ьЂ1НЊЏыФ‘jЫ+XёєТg>>кXНЉђГцЏИf(в ~ђ‹–š7Ћ›>њбЧъŠю,ІT†DRЉ›пЈjљњ Б}oWнwПуњЅzhЏC0y4  рUЬЩхн—BТBЄ jыіх/ЮЇѓuњYЙ8ПЖю}юЖфЙќ№Аˆ  kкДД+Л"n6жфлЎ-5C† Емj ъoЭЬШ<њсQоН№ЙвFЃЬNOkўЂ'lэўZQwЖkHЃmнГ3?Џg”ь…9ћо?ЈŽЃУ+!ƒ„ЉћŠ-:qЄк‚ƒƒ;.бuŠЎ№№ˆчѓѓФPj['ј’ьZAuu‹T†DRЉ;їдЎЬЫЗ­`kжЂl>œ–ƒ0е$ёШ0@@Рtц<ї-8l@Wg—4ŸэИ~WуBFgЧYЮˆчJДд(n^љ{§Ј]Ы­ЉЅ•юЧnnmІП l= A§{2ТУžэ8+ЊъЬž%жљэй”ЧS{Л ЃѓFЂ‘я+:qЄкЪ^^_љк+BoЮЭ+ˆЉw››NpщтŠТИ-•a‘TЊИR|2Дє8S @М‡€,x^ншибѕ‡ъІЅІЉ‡ŠŒ@wЦБwX2Т"Ј}\oYВtIютмјс#шь>ЎŽ=F?fdDЄЈJпйюоАˆШКзЋЕВ ыЎУATBЁє‡г‰#эH |eэоњ4КАpХЛћп“КБFGƒы„Rь2‚H*U\)ELщІC0Ѕа І0ч{Nц‚W_нL7=]ћО‹юоj§ЏVњ~c‘’4БИДиv‘ЗЋkui1mz‚QwwЗеj ВZщ&ИЂ—жл"%щбтђВЂКHž]}‡™гS‹ж­І,BntзнўІізс *IINa}„нж~NRK'ŽzPj!1єuAл-u?XК…ЋRgGƒS-ŠјFIЅІ>žВКЄ˜Ўњ\ћў*нЇЋо4їОЉбЁ@Р{˜“ЫщДЛђЗП;єёБёS'Х&ФМTМюБё1(Y 3CJš:‰~ D›ž€ѕBсђ %†ŒŽ™“Й`иƒэ‘Е0;єЇжЄ‰“&?9}XЬ(ЛўњГfЮіРА9й шvёЅ+ђNPћыp С$ƒФ„оqGVFŸŒ9™iГfЋSŽNѕ д’№№ЈœМќиб1ЅJжО ѕсŽЇŽZ:yLfA$•š17s№}їLNŸ>~ъф;яМSVНщLuwД€€€7јЩщœNJ.3wЭхŽŽЫлwЭж—EпэI—Ф?ЋV;“ƒєтЙк-N lћАœр&этЏ0щџ ъЄIW рitљ–ъЄщ'A§,IпИ>нzZ?ЭbъЋ­Ёя>пИЗѓ/п|ГПмœѓrOгD|ШхГж˜)€€€@.їБuХv7.`К&B˜HЙмDј@@м@Йм @@L$`ЮГbLœ0†П'uќp=KЧяgŠ ‚€З ›ищ?`пЋB.я{ц/Ч1  ОMЙмЗзъA@@ЙЧ€€ј6фrп^?Јфr   рлЫ}{§ @@Ыq €€€€o@.їэѕƒzp.ЇЇоPЁuP ќш‰‡МКџЙoьiSHчŠѕУ&€€xш!ЏюЯхДTx~$ŽWш­-­юПЦо7в1 €€€ˆ\Ž#@@|›rЙoЏдƒ€€r9Ž№mШхОН~P  Шх8@@@РЗ —ћіњA=€€ —уп&€\юлыѕ   €\Žc@@|›rЙoЏдƒ€€r9Ž№mШхОН~P  Шх8@@@РЗ —ћіњA=€€ —уп&€\юлыѕ   €\Žc@@|›rЙoЏдƒ€€r9Ž№mШхОН~P  Шх8@@@РЗ —ћіњA=€€ —уп&€\юлыѕ   €\Žc@@|›rЙoЏдƒ€€r9Ž№mШхОН~P  Шх8@@@Р‡ ДЖД"—ћ№њA:€€DŽF.Чa  ОMЙмЗзъA@@ЙЧ€€ј6фrп^?Јфr   рлЫ}{§ @@ў?шФ48*Љ"tIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/14.png0000644000175000017500000004574711733011756026252 0ustar sylvestresylvestre‰PNG  IHDRkм9œVРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ] \GжОd?ЦшЎ_$‰тzlLBV”(‚h@уAд †(xBPАЂˆr‰x_PQ№DУЊ$LTаЈQ”h”јKVs,Ф Г^йЈАыўќўC EOOЯL6ЧРы_џz^НzѕЊъпнoЊЊЛпГК^VІЂ :!№?u*E…B€а @„ЎB€Ј;dAъŽ•$'Ѕп^$,B€0­A1їЁюц&yB€hсдZQQ^оТс ю„€Yа:ˆYp‘0!@ш @DJ„€Y1 .&Ш‚шРA B€0 В fСEТ„! ƒY8(Af!@Ф,ИH˜ tаyD'G 7V`I№*о “eA˜4СF„Cр№ЁУŒkA MoЌвеC"hD% BР Ш‚˜‰„€В "@(If @Ф АH” DBIB€0В f€EЂ„! B€,ˆJ„€˜ё>ˆZ-MєtЩЉ2Š›cigк[ЏиллїqьkВ В *f>њКИš‹–ƒРЉ‚|tжЄ! ЂТшцЃcŸ–sqPO “єшо#sSКI Bы &‘$B€0ˆYƒаP!@˜D€,ˆIˆъKРЪЪЊОT“^B ЁPЦ‚88:…‡‰к ІˆCIIШ”HТBL‹@@ ‚ЎЖkгnЯО‹шsSkфЃGšZ“Ј=„€LГ БsцюиЙЃММLПт7*fЯtьъфтŠЁЪнЛw™ )ћїх ѓэфт8озЇДє|оСМ1яŽvzУqќф)х?еЊJOлш6d(ŠG-ŒЏЊЊфUа0‡CA!а((fAЌ[ЋуЃ#чХЧЉў+юH`Xшфq>ХyЙљs{ОаeeJ—8QrbыЦДќУ…У‡№ >Vt4m]ZўёТсƒуVФ1БЬ­лЯ~їэОЌ]љ‡s[ЉUЩ)ЩМx=UUUўўmкДщј\ЧдфT>ЫрЋ—'ЫЫЫЧО;ЖMћ6VжVcНЦоНЅ5‘H]›њBЗД’U!A!\-oМ=›24zЌ­њїы_ZZЪЫA4.ŠYtУСсеў}њЇoй(ъв'™YН_U=Ё†• №(:^ФцЮ‰шиСжкZэ=жћўЏї…Щ _kя“ŸfG„‡Жэаb!гCїбКWƒ’в’ЎJAbqќт;wю\)Пrщ›KG šдlД&,OШо•m\§™ГgДж*XŸчЛ<ЯхзЌZУє€Г}Ыіќc5jW'd,VkDOъ_S8СЯ‰žУѕA4.JŽA4=yBЕ<6.vХRсjХмysпѓy/?'C†’ЂBUiйѓЖ s Ќv?Y/уacЪЪЫьььЧюy-!бЇKNП9фMLO0QЋеП\ћ… иvДхДFmcjшиVkеПЙJ"FF@i ЂRйййOуЕjѕJоГЈе*kЕKЊёЫkљ\Р81aœWќВ…7ЎV@ ЫЋXLхђѕД’jogЅ VKљЯZB“ќ_–HŸЏ#щэх=+hжЭŠ›˜­TўVЛаЫ$љQЃі')Е52ѕдˆг/!ајќO}4aЌ—їЕ;wИцEБQ Ћœ'іюе“ѓeОќzїъ=)$ЯhцХDИ t“YАЮb~О~‘ѓ#Б Š=l^э{.§^ы—ђз‘ŠAq§їмЧаУккvgкЬiœ/"ќ&ћA›VэœZЕ\LІ.O!аш(cAєW4SW%pІЫзOВї–ž,9АoяиQоœЯ †‚‘$ŒШьНХ'KvffyИе~D+*ЂšбБбъ6ъNvКПвНп§0є`[к†4,^Јџ vъя4hр ^нІЭ›BBCЌ~gх:иus-Ÿ 0":2К]ЛvLэ 7 1™zDj)I4"VзЋ§b`Б“E ’lŠё\Щ"Фм“НлШЗЙ/]х9ъляОЕ QS ЧGѓt|›‹љ„Є*n”ƒHжaбܘЈ ˆйJфМHМтaб}ЁЦѕ‡Yil_АЁ{Яю]џдѓЬ>Є…ˆKДxъџх Ы„xкћгА[fлЉе„@У!@c†Уšj"š4QСЃ,\BТЇ[ѓ;Лд#B Ю`З†ЩтdAДОd—IАH€h9Џv3Ю5мЩšє(k†:%Z ДвbN5u”ЈШ‚дЈЄ’h1i1Їš:JдdAъTRIДшYŒцTSммsСSGх"@Яbф"ХЬGPH­kBЙ%IŽА(і|Мgь;r?ђJM^ƒЮ™|FIcMм\џїƒяогКGЖЈK‚K˜@хУJљзљи О{vdšД ДbЦ QB€!PПcx!4Ы BЦЬŽН|хВYЅD]ЊSВR?HEєP!B  #ХzСX 6Wž?уІ5KwИlpѓaCЪ у(cA0ж`Лл`磘HЁbуе‹\%_јћ.}њ/bAЙн_ь.йZC|IabMХf1lрл‘œ’ПzХšEKыаmИFМˆFи4ЖZын_tИє6оеc7ІV­Ў*C|])JJ"€Hђ/jŒчƒЪЪиyЂТ7ќдщ3œЛBЦбyРЭ_oŠє“—+nv|N2Ф­ŠЫ\†GЂenMŒпхe АИ|‡ЃUЊГ%gїэо—{0їіѕл)Љ)р—V‡ЧQCT‹~8yќфт/Šѓчї|ЁЫJФы3\\“UЃ?3#уЉ}эC<нVOЖJNJfУЃТgL+.(нКqызОжjc:щHдš ]Qь_PtЌНиЊЏS“Х,›}ћ"ЩЂЅќ–цез!tng[щJ@tАЕск’ру ˆ№ˆЯ>џLВъOВ>qшэ€рж­­І‡q1уХw|œ Еmmк"о]HpШўCксFЋпЕЊИYБLЧŽЃ#ЂЙ6"`џ…B…њaЎ$­№JЊd` Cч&­Kуb6ž*ПZfїœ„;ЦCFЎH\НТ W ЩKе0О’ЊR‰FmкdЧч0]ва;Ж­q1NЈJK/&ЎMМpсТ§_яkкІUVё[W.x{„Ілj &}И2mУ yкџОUиќH—7šЯюšЎвoc!P{нЂЅ_—8єrdMЭЏ[љk ТBчЮМжйЖѓДЉ>Эљ”5бR€ЗЏn<§EŠрщ‹W'ЃyЌу9дIљНЊ‹$F†Т­&yЃМ‚MІЊЧA5c<ЖqBЅТ+lV˜ыђОж­еUU•˜Іq1уХ;иvЮнМUgRV­ЖG—k–i‡уЋПии˜ŸЊЉ•~ Ч@W—рКeŠpыiџ\EYђо^UЦ‚шпџМqŒ@ш\ьМыˆžЫhФХЮљ:zžPGG„cчЙŒа‘б[5’+ЪвQћпš1C —ъЩIеЫ:>‚ё1tКxЕЬОfш„–J­RЉех7*вЊGXЦ‹Ѓ&р5Ю+rйBЬtlŸГ-ћЉlыЖ­Б b‘П0~в”IіьёьэСCqлjкHП„€й№+SXВЄЄD’/”1D+cA ioќоНzŽ{oмƒ=№|Ы=Р_;ђрW=tєшcTlTТЊ„0НВ$‹sXќЊ­g`H І3Яuы6г&Ыrиы#п—}п­[ЗEKqy"І†EоV!ђЖя$џЛПI|нGЬF4ЕгFэ!ъ€@оС<З<фќoeЮо“‘Зi RƒЇЁYŸ!~M9њ%,Ќt(}=+і4зb@Є†„€D ЋŠа„#ёj{ >ф1уK$ЎŠB i"€‹\т:—lЋL9В 5шЩГИ5вєKX&J_чdAиuP)гтZцUC­&4˜1‘ ­ƒШ†Š B@ƒЈ#skІы !zрƒhVTтыя{rпЫ?š‹[УdџЩ‚h#b/“`‘!`брХiљз9Eœ2у\#(†ЩИfЈ#QB Х @cЭЉІЈ—-ц‚ЇŽЪE€Ц r‘ЂЈ—r‘"9 G€Ђ^жЫ ЄЈ—ѕ+)mzPдЫІwNЈE„@ЫF€жAиљЇЈ—-ћ>h!Н7ыЫ:yoЏ6н7Ър7Љ…œVъ&!`Й(`A† ЊџЩpеНЪёО>8жc.ХъЌ” „€Ђ(0‹yэѕзїяЯ9J'NнюНЛ_rx~CmmН)г иъnьъ­YЄ˜PМ*џ:—ѕіЊdвФЩѓцъXџЊvьЪоZэ14=mcfіxuww7—…tС EЙЯS?Lјсћя;tъ4eкШ‘cTыZнpјЫeq R7gРE`u€Ыљv]z0МkЫЪЦ_ёh€Вk&AB hЂQ/{tяёœн Žхsђђђ^{ѕ%И8ЯмК§ьwпюЫк•8З•Z•œ"Й2<2fЦє™ХE%0:__јŽыa„‘№—'О:›ЕqkўёТСƒЧ-Y&*(?)п,ЫзI’„€e#а+ЉгЇNоœЙ™уЕ93$w|ŠˆJЁˆf€ЁGШєа§GsaфЪV­` ё•`ЩVп9Л‘№—БsДЪ§|М/BaзпŠЁ—ќ…№”R‰P•у}Ц—џx=05яpяђŠУ†КЩџД‰$‚hxdЭaXpЄЧoœƒУЋГTzіМCяW1%iпО=&P[QЩЋVП`Ю$ ’’ДzeкІšKстKFТ_ZЗжFЯ……К/Яdж6FDЩ+Ž—ёёk–­ЉЊЊк˜žŒ—K,ašNŸШк”ЅnЃоžЕ=.6nг–3ІЮXКfЉ‡›жЗэ†є Цћ#<~ЬQ[(Iд‚ымЁ—ƒ~-ц†­SрY kФ”Щ3жямzЫŽЌЩ“І0&"*цСˆ@ЛŸдФFап`n`щXюЁШљ‘KуcDM$ќ%k•‘—БѓbYќJ??6 ъгЇO{u+6 СрЅ(ПШ{Ќ6PŽЈ”$}cЁЯ1й*СЈРЄЌQDf\—’€Лхіэлќ;з уМтЋ#*aMЄќЇВДm[—TGTiŠZ8e’]'{ќ9#Р’hЋCјЫ:ЌЄжвTЎPЇ9F\ZЗ†Єfш‡AFѕ€HCOёŸ’ИжУн5i]‚ѕ!KXFъB.m„€вшЬNšVдЫ)“ЇEGЯ_МИvE“ХЃ›TQЉkЗnSj"*‰@A€Ѕа№ˆЋeпCf•^€Ѕ )А\ЕЫ(&kГ‘—тЙIuY—7\з§nmJъЦ3чЯ,‰ŽЫcюще%B‰’„Ру"€kLя2УеЎ§ЧeЩ‹ Ёи}ѓpїР.ъЄ(Ў%Ы­НEЋгX)р‹Мx­Œљс/kЫruЦ НЈ—†ФИдБэ‚‘ьfиœ0NдKХжA€ЦЎ†Иttv DDKYЭyRе­kgъ—\dЩ“!`9(9Бœ^зНЅЎ\Бѓђž5!ФEС1…ЩƒŸœ9#ˆ!‚АdН&EЄцlЪ›ѕеHЫ§Э9ѓуЯ?КК,еџtHЎ ’#”B+J_чdA”:9z;лw^ЙxЅDБ&Ž€haе@kЩ‚p`dйИДЂ:h&T^Йœ ! ‹ЎCЙ—ЂL9В 5ЫГИ5вєKX&J_чdAиu@Q/-ѓ~ V›ƒ€#йjщiЎlЈH є 1EНдЛ(ˆбL Ј—ѕrbйW<ђЃжK#H)!PџPдۜҘЂ^жВЄЗЙ#@ГЭІЈ—Э§:Їў™EН” 3žЃu˜ьœ„ХEV>ЌDЬЊт“%ћvя=є­-›жЩ=]ЪRЙЕ‘!` Ш Yл a+WЌrьŠїq‚ЧЈˆЮэє†у0ЏбˆМ L1laGFˆPNкœц?Щ11;$7lNcb%'ѓCІ‡ f’mлЖuqsMMЎЕ ’ EњM& `R†…@CXCa+ѕƒ]2Щ8JКJ.**ђєx[xz“q{ѕ‰_ОВєл‹ЊџЪєl д$žТH‹Ту…Т2 вчЯžš5oжЗ†Œ3jхђ•пgH9В|ЦћˆšW^^ю3бEdъ|dt$Њѓё%ŒЊgЈRт†PЬ‚рO^Дѓ* …­4ь’чФЭ[7…‘юРGђж­›L ayb—gž]Ж$жЩmШАQЃSR“Б2ТЫJš$žЋ!0‘юњaЎвtVіGяНћПoЫмжЊ]ЋИeq:TЗэЃm^яT‡0Я?чмзEфшЉИQ˜УF Ы9˜“”Ось7g еEќfˆЎcДЮэa0Ё˜aс‘зi(l%‚]ž8yb”ЯИ1^Ѓ Nžтђ†›6woщќ9#йЁƒ “Зn­і и™™U\Ÿ–œtчЗЪАшHCЊъЦрЌХ€РнŽ•к!ܘ6ЙќЧrІ “Щ&#9Џ1я`8<ЩˆЅЫћіщ‹Щц_яOџТзD,‰БCб—яc/Ї^‘ЃgыІДiSЇЙєsБ~вкжЦvюœЙ’u“ƒЬQНo,l%ТжЁ&,|vАеоѓ,и%˜X‰9№љ!уMqvrЮЩћдї]?.†фkЮЮ<Щ ;;ћ№П„ИКзуВХйЏЯІ­KSЗVякГkйšeыRkз\x32kі,ЕZэттRPP№љЯз$Šd„ЩsЇЯНмыe!‡гызЎ вќoЗ‡Њ’s% by  щ)њъЋ.нzbКєр_И ˆ˜aнZ<‰ЉЂdsE@єŸЧКYXT(ППŠAŒTЩТVbmaт $™0‚]тщЌfaUьвІУSхWЫ$ЕLJЯШФškUU%vH†N dТA!3 ŽхЃ $oмЊH^Пёх^}ИEVRЙ6Иё4Qrежу|Ц•~S*ЬгOЊттуRзЅnOпˆ#hБ Рp&!9a^и<OKž?{ўіПnЛ reџі|з?vY#z0ќщђOЛ2wхьЫ][‘ИBЄ’-}cЁЯ1ކшяЬИps …­” vщ?)РлзяўЏїѕW.ьžГп–ЖaХкЄE ЋаЧз‘dC$ЇOБх󍘽KnўzГГmgчўЮ‰‹—ЫoБў“+}Дqfлšџmѕ“жА€œЯ V5KЊлЖѕ>"i]ZФЌPлЖm Еъ|щљиEKW.ŽЗЏЏ‰ФR"gGr§œ8їеЙў}њѓ$JзѓдSOЭЊЎnшŒPЯБžТВЂJ)йЬРЙю’ЂBЧšщ9шкўЪ БЈŒбПлбŽZІА•’С.%Ѓdђ^с§БдU <)$zПКЦ№ћcЕ–вњHшs Я™œ`JXђIUхУ*ЕZ3)Ић[ѕ’M5ПьЧђьOї$ЌNHH\тътjлI3ЁmљG VЏ\ГЊGЂ,–ќўЛяЇLхY8ыЬќ—ЇПœ4ƒ7ЬЄž—{МЌbЫiаХЎQ_xD4KєN7.$G'эхdnbcn›,WосE‡н{vUVVнНywХъ$ж$#ЦЦЧ-ruщ5/6VFдЧн{v'$Ї&Ѕ&ы›œZ&ŒгЬwp˜љЈќ­ъъ?Мњ’іе[9zо9ŽФ!Z,њF„,ˆ&тЬЧ3іЛ=ЊДВRг‘ =A№nˆЄн$ Ђ……]4HРˆа‘hс ћlƒсРИƒб’o—5­g1њ^TŸ_гAcПf•b†У˜:Ъ#ZьT6њ€‘|1ЄiY~‚јЭŸ˜šИjЩ*іm>gr1 ŒAŒkгз—Ї\BРЂ€сРw1&Л ŒСН=ЦзGT8uОчЙ; џGтLQEŠ$…cIcaeeЭКЕФыћќяЪЪйwюяЮі|њYƒŸN"ыњ•`QѓzїВ-+ѓGе2ѕєvДЭ?ІЉюzEp№Ь?з­ЭTЊЙ#А„ЯY@†(cA€f+u+ЁЗф‚Т|pхћю?О9LŽAф(Љ›Lш}“Oй<“кНgњн;UйЛ О™ВlБkz†и%ѕˆсіy‡ЫQЕ=/ОмюР>яД чmlRњg:9{aЙnнЁRЭсЊёю(fAfјNйМe3Џlsцц“Ї№$œЁJЊцЧ;ЙИbБ#ѓoЛЙ<М№#ЖsєДnC†Ђ œ­ТgЊ–ЏЉEBr™*^\Ÿ0 џч1'ьЯšБРfŸ?япя ­У1.Р”ГdzЦсџкuЂф—g›ЖрШvž›ЙuћйяОн—Е+џpn+Е*9%™eзЦ‹K"Ш$e8s ЋSПЬ6эR?н1mчыў3r'њ9L˜ј'dс}1Юyk„}СImOЮdФЪеЎё pчы№џW‹“›ЇБ ТЭ7ћgžБЦќØœНžO?mpЦ$дFtKC@џF„Яk„h(fA tšпД-лЖ€XПm ha5†‚N}іљgЇчел‚YТ"FшŸfG„‡"мb_†Lнф06ЂЭфŠ>dF05 ЏЌќnцeKN9М"сєДЖьПU#ойГt‘ЫъWAЋў]›)Ђ0œIXхђўє§">’УпЖЗЕБЮиєwQжрі/Uќђ‹ŽY1ЂЇmkћЎэ^IўљдЪ*еІЦЬŸЈ.JЖфџЁ*љ>ШШažЉkSђŽх§xсТШх:ў К\q™;[ч„ЩѓtыЪхo{еŠеtЂnк˜@&пˆ№;V3"ЈЉНЖ=Кr+Х™СIDATц&ЛџvqvxŸ˜ЈаК™ЕЉсУь7Ѕ{Žёй§н…;Ем*qЙЧŒакАU5lJхцiAјf\Oе=Uи_ђYћgч§ќS/H!РРНp]<Ўх™:„’cx.™0С7zоќ “|E^LXа)VГ0шТ2 Щљ:M3œш`лЙ0їŸн”ždLUuгЦъ‘o> ЖыЁЊukэЄ@8;РГп ЏњNик ™’Х1СйДEc>NHOazєl{$w,жVиђ _s2ШюsСЦЄžѓЅвњ%[EЬ‹€ќ1ˆЂDЅBЌ†т“%ТАrь :5bШ›+’“4ЁЈюо•њhТ8Џјe ™щ)џЉ ‹Љ5Едfr%U>d†ЎЊвo+цGѕ…БЗkЧgHfmѓ?9‹—A!yЛ>Щ­ зйwЭ2aC%ЬЗx–Ьwd–aЇztЗ§тИіЯBŽžmлK>є@AьkSŽ}pž‘>/Ш>—ГыŸКž/ћXцbD…€bЄММ,*&ВкКуxџ)ˆіPЏ]2щїєqj{ил{ўЖGЈIwwwЮсЋЊх?—sЫbџМ§ѕŠы|БгфЇƒƒfюЬtюы ТЙПsъ†дV­Z1>Џ „нЮ-;ƒgѓЕa.б„@#" ŒЛАРщяїsьЗoїЎтc%qГчVUƒf•——c(ЇПXLхђ†ˆ ~Тц„ 88FDEL›ЂуЁšФфh€л€нйЛ9‡B )  ŒIк˜6mšџШQžšсњЊ={,YДTл=‘b0 йП/g˜зh'ЧёО>‘w0oЬЛЃсvlќф)№]ШŠC,ѓoлMЁa ёe8_K ~” "ƒIJс‘ТНћікик`џ(ћ#$љЬ0Јћ+н;йujзЎ]tЄvХKњ шч:иеЊЕ•ЯDŸw|M“&}}|Йћ‹Ыdї}ЃяНћїР‘UЉЇЎ]ЗжP.ё FA@ RT\ф1HH‰ѕЧPЄф"@Ьжiљ‡ ‡с|ЌшhкКДќу…У=Ч­ˆуpœ-9‹h2ˆ)ƒШ2ˆУљ"Bй 20‚{ВїќVН}Жя3$…еaДqуъ dІЇЅk–6j6‘|џGUЮœ>3r”іyŠh:#Lb-Т_@І* йk LŸP—._žаЌЖbe1& †G@ ђржMсЅ/ь†ЁH1™;'Ђc<ЁP{ѕОџы}aђТзš—&иЦЪ€@D˜ЖјЗ>‚Шˆы 4!@ш" Ьз§­:и`Q@вˆŠƒfžPh “їж6“Ч‘qЋтrm†.UAdtk !@ˆPЦ‚8;9чЭ…ПbБzbИи`•YlmєeŒst‹w6$Œ 2Й›Зъ[1D†7РPqљ|šAШЧŠ$›=ЪЬbB32вїяЯЉКw‹ј Ovv†"ХШGVP˜*XAd еE|B€`(cA№ŸЖ~УбтCЧx:Й9._Бь­ЁoБ EŠ‘zїъ‰h2ˆ)гО]Л`m §тѕDFПт„€І/Osыѕх1`Q/FћšЉЂ ‹МR̘цpіёхЎцЛ^+ЋцаъCГC@™YLГƒЅ u(tnhzj:-п6ЁSBM ад-H}OaPд’x“=<"Мч‹=сбЃcЧŽјДП А 6ЛaЉѓgЮЛПЉ§$‡F" ‹=еfІnALї $оџОm9”{/‰^њювфё“утуъЁY*янЛЧ?і—U€„D€,ˆиŸќ|qќbМfŽ<М`‚їгф/BћвЛZ_„Шr$Н“с+;Œ_рхc8[eў„P№№‘УЏѕ~ L,pрГ=жИG ažYA >t0BšЁ#!аш‘8УпєAащ’гь6fxevв{“ј fњІєР)рђNЋЁ!Ё7ЏпЌМUйЅ[—йсГ™Њё~усHёбНGХљХи6ыкхkW~И‚§ЧќИxщb№йђŽlcаЌ FG€,ˆФ)иљбЮ./t ДББС0k"lш0=`Uв*Lp4МЅЅƒ4фьЬй3јюŸоiМ–Х/†ѓФъ’ЊЇžzЊтJт›КфдdЦмžЙЛ>ƒЏГэ[ДЎЯX. І‰Y‰ѓ‚aETLю|}›{ ЗВВrќФёыбН‡уŸ™ѕ=ŸюqvvfŸеђN†QЬ›Cо„CfL@дj5їZ–Г'чР‘НАX{јаaж‚Вђ2ю@@уњLрTQЂ‰Ф"šdALœXе+Wce„Щ…~š˜”z]ЪКаП„2І!яdо^оГ‚fСё2ц•ПUђš`;рєьЦ€јПяЏUbg/щњŒ—"‚h‚‘8)8ьпЗŸ-|V\­€зѕС398щ€CгŒ ъпЋЙ;BCоЩю?ИЁ&1XR6Г暘џ4|:ФfCїџsŸiіѓѕƒП2TŠ’њ-{њщЇЙ•бЯ%!а№‘Р<.6.kWVїЛcісфъ„сУЧYsЙАYaўўѓТцqŽ!яd›6oТSЋпYСqй чA\ў­o3 ЎЬцЮ™›§Q6уУN=ћЬГКvТB,‚Œ˜ёвk/Б‡2œI!аˆ4ѕяbњ.І@І*,цѓ] ьР ™'У\y™jIŒ 84‹сPAf# ŒЉлП}нJ™нE*@ѕ†€2ЄоšGŠ B I# АСАО5Q`Дa_.ВоŸ.9… 0`" `ВŽ|$rуFХьљ‘Nƒ]&(„J…†бзLB€€ТŸјъlжЦ­ћ2xарИ%ЫXSТ#cfLŸY\TВu]кзО“}Ж#џ~?0,tђ8ŸтМмќƒЙ=_шВ2%ЩP7” cЈт„€I”З БsBё=+ЂРјљx_јІ”Ес`+nbTqЗcGлшˆpЩf}’™хаћUеjыжъџ€ЂуE’b`RhCШд™Яп1сDU/XпњзNЙŠ#№Єт­[ѓ8ѕjі%iѕЪДM[RRSкџОUXxЄЫ}ѕы-§і"^ПpёЂOir 7­Ѕ…†С]зќОЧm–вПЊ›=Gљ1ˆ$dјКdЭВЅЧrEЮ\#)3wомї|оЫЯЩХМІЄЈPћ Ќ”(BУцa3 Эёd “bЁa(3REeёјџ$ЖСm"isа‚зв}'јТƒм|єwэЗрЙj„н†7цщ’<ЋFŸ•ОB}& ~1ЉЩЉhŽМЉC4‘N=NЈ,h Е0ОММL7ћЁъAM<:›O•_еFиFSNт>dа›ƒ.]К7iMУ[№r4ФdДЁ&ACЦІ Mg1ЪызПДTЛІ†*bЂbP#6 СъCСГˆЈ?”Б ќy 'X‹yвУЭу“ПeŸ,й™™еЧQЛCPќE>—qрњIі^LIьл;v”7чыPŽВВї2…nЎZ€žPEGХфћќяЛЕЫ•h%яО‚ЦŽ+ЉC“ѕЎN’‡жоr’Ѕф3OŸ8wъ†'("щmфˆ‘ШХWХ“'Уk4hpРaШmВŒoызЎŸ223ЇЯ->zьшЅo.])ПrэњЕ˜EЕSTC|aYаFštєјбт/‹+­єzЧ+0(\ВlЩ™oЮ”–”bx§ЪuЦ”„BT%ыњВN"тў§и-Ъ Ќ€Ьž?ћЮ;№ыг€EL^$зz5EўЃ›ѕP…ЯpсДYSАFГHЁ№дBF˜DKx)з+ЎлvДeјЮЯЫg~‰ Аћ+нo\Н—E[vnЩмš‰‹…Ы&,OР8‹8№э>д]Ј>Ÿяђ<Š€)Ќ‚ѕ](‰a‚уŽ?џє3<АR%'K˜Y,ћQы “5Wз|џІа_„­А"Q“Иf”ЇRЏўƒša(ь5/+dr(x.u@ љ|YW‡Ю+Xw6|qoќ3жe0ЭOл<]qKzЅіщgХYДЦž7IR!Яeю1О‰ВИљ_в7ќ*bZЅЪи–БsћЮЭ[6ƒЧХЭ„!ЗiШ2ВmЬиkX Bу™Г5pИМŽkЕŸkЖ ёyAFi3ƒхR§[[Ўь‡2јp)‘„B$CЩњ@@™YL}ДЌ‰шdwђoЗУJ/XЋоііўНЕ_„MEЇp&’ююЕў’ ЙАY„Єo4,ОМмуe<RЗR#аЬƒ‡0*GsЊT†мІЉџџiгЪЪЪИQ јЌ_'.џЙ\h+ ёEu™л$ћЎіЈHЄD ‘ %ыВ uA56:vб’E№лЎyѕўЁЊєыR<йeА…ЙВА’`жЅSe љF>lx№Сг|5^бpєђ‡)3ф6ЭHUЛГwЛКИВ9 экЯ5gŸцыlaѓj\ЋЭ ѓ›ьטFј\€ц6)`RРŒПЬР*РЧ’*Sb Q]”TВ uуѓмУЙьоН;ж8?єчУ!Ћ№H!žкиик`џ(ћ#$љxО.•.cШ7šЋ›+5ГЕ^1Тїpї`j ЙM3\‰jэњЕгпŸ.'!%1 „%˜NvкЕkЭ% ёЙ#ЬmRдќЈ—^| ЯПў3žaJ A!Њ‹’Š#@+Љ+ЉŠЃмŒbeГ§тыKЇi"@+ЉMѓМPЋf…ЭbšещЄЮ ŒYМЙU'9…A' ё›[џ[|Ш‚ДјK€ 'Ѓl3)jooЯ>4“ўP7%РM[УЄ&В *і№2  -˜ў ›‘^ЫЕ <@Д]–›ЅnнюO/ЕГміSЫ њ@NПLЊ•eAD_d™TJ„!аBeA№nI ƒКIf!@ЯbЬ‚‹„ B@В :pP‚ ЬB€,ˆYp‘0!@ш @DJ„€Y1 .&Ш‚шРA B€0 В fСEТ„! ƒ@эћ Эћ­SNS‚ B@ыЃЬжNьќZ!§Є† š3к1НuкœO2ѕЈ7ўFщИE*rЗIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/6.png0000644000175000017500000004253111733011756026157 0ustar sylvestresylvestre‰PNG  IHDRбb€ˆ~ЃРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэ} tХЙfхjrК„”л-ЫЋ‘eЮŒ-.#KDВe[2$;јјёЬУс8,7ёЙ@сBЙaYCИ8,Б ƒyиƒ6–СТЃXf<ыбО–Ї{„zЮнЏКЅVЯћ%ЩUŸ93ее§ѕзз=_§§WuзЗШ;џŒћ-oDшЫHлШк‘ #R(˜•–PVЅГ+ЌYŠгЁДFR7Щ6TПЉ—В:ЁIНљс&ф„я&н‹(žT~Œb]“Љœ œаTФвlХрeт|ќЖ4 rёИLŒ{„рpЦ;ŒsAИЌypМ#СлЯрpFo9/О„PдбЏ‹зРрpЦ;ƒБДГЦ;(М§ŽG`”ф\M‹fЮЂЮ@З‡(2 ЅCх6J${AqYеђЂŽGрЄF`ШЯ )#hf лGmЄ`ж"BХ4дjjРг8r  и™F).ЪрpNLЮkrџчKl]dк*ашЄоНэ Яыпvљ6Щ]єHьbНjСЌх„ БЦЫЅbAYmзgлGc~FМ:y>G€#РK†87•:mT’$šbД ]Т5 HЫ/ж‹ьИЗП ~е˜J FPЦZЏ5}Vmжt„ц‡"$3л5єeЧ о ЯБпКФ)цБо:ХJусpBьЯ j^j\!0ФЙCПБпЧГšzЄ|Љћ˜ІuъoоЊБ@-ЭWЪFrc)Jšз шŒЅvЧнŒ[­л‚‡‡yЖ"_nеьжЃc“ЖжkMЕ[m‰ЛS}|ЛЗЋ'Ѕ^ЫЊЭšŽhW‚C’™эоіиfЌШ'ыяИ +ц(4I фж%.1мћBЃв#ЃвдЯi4ЈЅ‚Ъ†йбG30žсŒБш-Bё”љФІJљ„цбтœbMг@О ЩэЄг"Ч`з ЃЂ Ъў“јk—я“>ЖЁ4ЃY[,й4дkЈ1вб66ЯЉr6,ЈyhЅыц?К“ЎЕE‰5уhМJГnй шя ™eАXъ<Я†J@Ии4UfН/IуœЦФ!0dyЬЃz ќ‹#0ж$чмм‰ЮђЩdySПп[vV™ЏУз­‰5_9ќ/Е6hѓuaE.џ“l=ŠДюЧ.kHFPјnѓК…„дн ЛcVПђ†?uU­sйlЛ]дОрцOх—vћpЈbВДўъJog№ц?7QнzG 2—>ЖўћSздКJ„л^hiэ`уŠ(~§jйз&?іžНvSп ›їЖЪ ˆЃH,еi+ТуГюъщС…еb#w_фЊ+З БNZЬfЂxLLТд&лQB’2“‹№vуU:г)­яr ш[ўЁnмчп§ЕbZЁФЌпxє6цSу<›к9‚№ЏnkРw0DЩПу5†КBщ сšv№G`40џО‰˜NыU}~ŸsЊsуІгЇЯQTEa!ƒ@у”‚VSq|ы%rTБ…‡ZV0ŽZ]T йMџХ,›Khћаl_‹cЃW jp„gЬЌЙ~žџУ_hЙДЦq§<XрЙнrk‡u SmСЉg9 kPA^rSdтщёQbЙ"ЖИю…ЂЪг+ь *СwП|ЭoжЋ'ЌЮ5в1Œ‡Эх.6УпЉb(в”Ј ЊеmДюZ[dдrskaЅ§НO§яюёЎЈsеЭ`=qшЊѓ\1›9$@Ќ˜Xk4&„ялq7ы–ю]ПA#Д‚R(Йъ<р[ˆнsi%<ж'_пwиЏNБ‹WжИі­ФTb­7B€„ЈкW™єі}юнВлЛјМЊ…3Z_№Б‘н9!БOеžцŒ)P#cMэиІœ5­ЌЂŒњiїAм‘КПЗљjцс^ў‚,…Žš­zіКJ#гЬIš0мC QS^В)ЖAЇfлž&2@њufЛ|†™І=-˜)ќњ~џТs]Ыgлпiђс~ЙёKuй .|mЙр?lZmЉ§А*ƒН_њЁ0з&j!њдNџ$› –ќРэчBfЊm_{(Ьa7Эˆ™АкМ§#fГь6Ь6Лk+ЌiCэЂJVщ^ЗNм–&Џ…sЩВьPЬfe­˜и4ГFуhZпFY(IPЉ1€*ЂwЩ#Эrs‡ZjгZ‡юєQЉ$ž%F>n,аЭ$>G†ёЛіЛЕAXъ*э/7zЙ“›жiхТc†Рч§ЦЎx@‘eZTTT;ГжуѕШВюD$(bГК~У*AИ‘Ž-"’жLшDйјš ? Ў”FŽБ •‚‡л*0&EfЩOЏ[hПu•šso› Ю-Г‹ бЦ?умrзєNі ДЧыcUиШLЇИі'ЛGRŽЛхЊuYУ C‡XжєP•†Эг]e K*ЭЏйѓ—}§V1k:Bƒѕ 7гЈѕi]D Ј„mФЎw71›iXaХ„х iоБŽyЏЦЖрбс>l(Oџ62"„˜ вg?іџф|GУRІ\VƒЯ~ 7ЗaЪіpm*1- Ћ‘CрУ/Upnтs4h`СIз,њ)Vš8\rУ[QпхŒ)]‰SN—~kŒПМ$JA-Hѓ„і>R‹П™7аVќ%Ђѓ­™akI3mѕŒрm™љж„FУ6Ye|єкм kѕЊ%У;Зiˆы"ќWSэ"BЃu3H]Е™žЕРSОg)Fђѕ–/ќ>šCНe!jзwТ†еKк>№Ър\Фssmš61D ђЂ1БJ"тcЄ< 1 ЙyЬ7ЗЭ4eLLЬœˆD‚Ё­Ic7AЅЏ6Щ_єЮ˜HœћТs+o]hПъ>м4Фд“ sЗOMzŽŒтR5aAрЊŽsк5&0†тŒџ”ŠEіyлМСPё\8ЙнrwwžыћИpW:MZnэ•c6dѓч,іКИЎVЫ‘HцАЏОtJБЛћijWэ˜‹инЁ~сg.vНэ2юR5нMtŽю’:2л`ѓдRV\>Ž0…оvЫJСЛЉЮŒЬ&RП§ЛНЈY…ЈЮЊкА8xЂf&RIрлоЛ~3 :Р}иауšњTњы•.*йSныgуи*l оh%pД­ОЖ.kљJхщтѕX쇋чGр$E %?WЂд^8Я­ЊЊ§тƒŠ ]rЕ|ўЇ#-кM:ќЙe#jЬШ5‹kтp8Y"0*.%ЭёZœЮЏйЃДЖ\*ЂlZEИ0G€#Р8…ЮEћAœ=OЁы€›ЪрŒ aœ8cЦиииСkсp8уaЮсО}ћ№ЃGуЁёМŽG`Œц\TЌѕъOyБ М:ŽG€#0nјЇqгRоPŽG€#pтрœ{тЯЗ€#Р?pЮ?чšЗ”#Р8ёpЮ=ёч€[РрŒТЦаЌЭўэ“ылЗп~ЫэШмђж–bIКтђ+V]Н&77їЅчŸГJђ4G€#РрЄˆ@r?—цI’h~ьз“ЇXMДXхьйб™ЃsB*эF%аŠЖїф7ћdЖ№dЖ зъIn^‚гHŠЯЙxgcˆькНЋЉйWЯьќhчЊызр•§!§Эн™ж’ >кfŒЖўLс,w’›—eыNГтќdf'4nlaХ%K|>ŸкЇбЋБqWнќz`ьSБќ•Њо‰|v*ЗЯš5ЫHвсjOёc „Ј=2–›4–XЧЊ<ŠЊрФRYl1]ŒgŸ~fўт%sъъџэў‚СЌєGš6@|фhžЩ’ нd5Ь0ПcZe ЧL\sѕš?О№ЧАCф/_љёъЋ‘iUнКя_ЖЮЉQvћ;лrІ0…ЧŸ{њ†k–-[.ш)и§УsO›E7ќѕEД20˜и<&4@žxr=NЪќХѕ›uмВСЪ4 tH ЋV­ПsЮjEьЅЂбCўОO›ЎjX5чмй_Ж=Ÿ!™е7ЛNa=>H˜@!;ЈВ,-YЙєЂзЖОf(sЗxЭsbkаa{эѕЗq $аX4 ПjЭЕўvЏ.ШNVЬ‹<Іё#xэ жџ'цЙ3Хбœ˜Ї)pК&qЎ JЂ„5жЇœ5­ЌЂЬщtЕ‘8xУŸ_lўтаы/oмѕоЖ\Jж?Б~Б~тйgЧ”moОёњџйИчг=š пІу!`ї%ŽвЦv™2№1gVUD8˜1[w~§љюf,mDдуъ=Пљ•бЭ nŽ|S[Љ?ўxљЂVaь"гЬiўДmРh˜љF"Іy8єьѓЯњЊ'хнПmы>жœlАВV ?wУ†Я)KщЭёЬ[їѓ{oОщ–НњчЇžўќрV§™ЅŸјЯѕc]Џџэ |АЪ*v =ёђЭZВДЄnn}ыСƒ2@съыъё4.Œ6ЯA5+2{>k~љ™?яњ№Ѓ Пwс/џ§a#3оEгјМі"l‹иwюЌb‰/NЋфщ”NФЙЊЊШВЌє(Е3k=^ТЛZqнєhН™љ‰ м_ЖМrчКлХ "мДлnК§ЭяХKšiжb$ љ­omНѓvГ†эwм™TIZ7]ЗцЙ Угцžл№G8ПbЖnЮœy{>o†флЗфкrAжH7ОљХ“юіяtV1ь?оcц˜ЭGh˜љF"Іy8єЪ–­ПXw';)yєжŸмQ*Г]уМЬžwС_ўКсз§:%ёЬУ„EЙLЅйяЙs]*ЊЫlніІ Ў“­лvђёђMmйZ’C–.]Ж§НmPИЛyџM?Оiѓ~Єпx{ ђ#F пЯџ)ЋW]q№яƒяЇŽw‘Ч4~Џ=иёЇУ.2-оЙ:Ю~MЬc^œVЩг)7ž‹FкKœprѕжjpxсфŠ4э’КЧ;Ž,]qй0І‰,–ŠNХЌшˆ|Фt<ЭDtйЬr*+ЋАŒPKГЛВК ї˜p~#TХl]muеCњPЩ[ol}є_=ѕќsˆ ьппzп]їEOК[8Ё>‘•vБ;aBЁYаl5Чх#fО‘ˆiYq‹(’ёЎq‚€Оџс_Ђ ]&UЯМЧћ›ЇџєќO>Q№м]їѓКsk“ЊJ,pDю‰ TМ|S[і–`АњЎћО|хZo Вмш &€>яё_?`жb&„МСўЪ7њjА8d=Yf+єќСkUDџщLкwюЬЖ aZѓтДJžNщD ‡`ЎкЇ‚G6nк8эœщj”]ˆЗ†9VYТ1С~цЖчўle,Z‹Ÿi?rуд"a=4"щkзмќŸ/=џdѕяžџЫЫkЎЙ6ZgЬжсSъ˜„ИЅЙ5чж>ѕьSŸьBђЃ5$Ю9Юљp–~ИкУюЬѓ‡cжцУSЬHФ4‡ЌИEЩrчтЁћНЊсЪзўV{† ЎbДкИПŽPЯ<\“Цј>ККћюЛїэЗо(˜юю™іТp ;­xљІўь-qLe§є›oПбW$fUVlоМ юГ‘oV” a=Yж‹<Іё#xэ%0 ‡т;kЉpЬ#/NЋфщ”N[€‡‰ F<ЗЊЊЊЌЌL !§•%уѕЃ+/{рсћkХпюУ0ZbљДŽ.]Мр‘ѕГЛPU}фБGЂЫN8Уп98œ}4i<Ќ@WчіїЖšй1М­x­›{Сy=іЛK–_‚*.Йј’‡ўr’V-pукkž§у ­€М№AЛЗ_{Ѓ)imўвK–šљF"žy—­XzџЃРeFјƒi†p–X™UЃХЌDTЮњnх‹/o‚йЈш7Пqvт™‡‹„ BbH0Dњ‡м=S‰Ѕ‹—сђ0Ў“ћ{Л†’xљf#bЩ–_ђлџ§ФœY3 vЮєЙ>Н9fIё.ђxЦдЕ—иАxчЮZ*ёХi•<в‰8Б[cЋ­­ХХvƒdDчв№Ѓее3ЊЏЙэFŒЦоuяѓчЭЯ пˆа’Ёфж›n+ШЇ‹—-ЧDШъйsЃ5пpЭк+V›7DбIsЎ]s§=їм}mУU1%уЕЎОvюєЭ_ŒR‹.FКО6rР$ІТˆLG‰ѓ…Їџ№і‡;ы/^Œи5oй \=Ѓm’tы k#ŠЧ3я†5kЫџeъЅЋЎ\ђ§K‹‹‹RйceжОђв•/m~ѕ—џvїћ;пЏŸwСЊЕзЬuvт™7омлзн9чќй=ёЛGњ•Љ6уФ­7­-˜8iёї—у3iт$ьЊтх›ˆ%ИњџoFM vњЬ*ђЭ7Ш1ЋHšˆw‘Ч3~ЄЎНФ†Х;wжR‰/NЋфщ”ў–ѓт[/Xѓ`@–БNФпЎ Gю;КыхЖчЈЇ \šЋѕjЪ1ƒЙџ яmJрТ g-Ж_ъ˜0(|:С1NкRyюь–OFхс”q ofіРб‰gЏіфзУЯE їхŽпkb@qvj9Jq!оo#ссђmЂwдk‡Шg7=Ьюьјv "р§в‹Hп)h87™#p: c ЭдЃЕЄŸфчю>МуТ3/УkXl~­ŸКIПиш ьѓ6е”Чˆ`šЈDпАRЗ]‘aУ(Ug6№MЌОю†uџcdІЂpГГG оŸЮаЬџz ŽСЙŽ ЮъТeрYЅ/0яТ‹œЂSР8–KгК||Ээr{.Ё.GYН84fИYE‰л{ЊнлИыT1•лyв"§Ÿ.{ '-8‰ ‹СЙЂhПсЂи~P%ЉZ4{ybќ(G€#РрФC F<7ž(Ячp8,рœ›%€М8G€#РHЮЙi€ХE9Ž@–pЮЭ@^œ#РрЄ@икОі‚AОq8ŽР(!ЦЙuskFЉЎ–#Ррp€@чjНщН—#Шрp8i!РуЙiСХ…9Ž@VpЮЭ >^˜#РрЄ…@ЮХ[JЭегв{ cфаюpŒЅСc_уXЖŽзХр$@ чЂЄ}ВsŒ))ЙќG€#Р8ЅC‹n‰УС 7žУрp2D чBЋьїулˆ0€‚3Ќ'V1,ўЅ h$'эEИ2§эНjЏъХ-q6—У)ц[–nЫ‰#—BЖкЇЉЦœ,–AHP_5CАjЃдЦVєТы……,є'2a€•eO›Чз!“[ ‹оЛJцr„‰ЪІsЌБYЛхq5l&Kˆ<|ƒИь‚ŒNP:UsYŽРјA 9чšXAƒ‚ЭЬЬ`л=ПЁk+7СТŒЩ4b….w›WтЊp-У’дцŠXс­iќАБq_;ЊчзЭ­‡–MMVЩаёІ•eMУj‰Zау•їth­ДŠщ ‘IšЗ‚vOqcyd1OАR1oЈр§b…ЎІц&чАЂic]аZ_€Х@AђЎГг-EsЮ(Зч.mїяBw;ТK1Ѕh уœЎ„ГTќVŽl‚pї§†V”k_o‰_gŒ#р o›O”Dm"{z0єћ§n<>".l–ЅЮƒьПAцчъ+i{е7омжpљ$oўЌЏGЅT№y§я|жн5БžHBAэзW?ьЂ•]!WСІ ъ™QV к%тв.Vflмп†EJ`ъ™SзЯs–:р_gxsбјYzуцG8LHТЙжBЦ.cXИ‰9ƒ~PIыFъš*L-SвБфnѓакДП ЋaВћzb%!јМJŸbw:СГƒњтыŠЯчУЫз}дg,№—NmLVV5b<^џkћШ9Ы Ац1‚!BЁŸЙКЭ з}іеі€r`юtМФнщrˆ‚n=1фбX4„Ћєjэ_ЊžVОbљŠЂ"{ ббШРš ЃЁ—ыфŒw’p.рЩ2ЄРWvгLФ2BEFXЛG1БГp.vSпм^~"\VЌ*ЊЂБtІ*Z[ЇЮ/ЫaыZДAёЋ*Њ‘™zuСЂb™c›№ССniЮ2АmЎ@ћCVЭ€йЙšЮМ6š$§гЕ}ЕНР'г| ТuMгђІЃMb!…§MОFИћПиx‚ѓЌ)cDИК{‹ЬsGhѓшжёŽРxF чfR`„лбHЉ&”–‘6љђ ‘P5‡Рх Љ?Љsю‘ЩplkУпд7D‚},€€1,6žжцЕžЫ ў(3MвDk‰А4<&D№uЊ3б|‰шю+•  $ЭЦVgФc4vЛїMAџвЃй 1/ѓq'tю–ƒ„лВŸ~;wъ™“P3ГёЦАf%кљЦЄZцХн4$*Сq8щ!œвšЗ@ћdbХъaФ:š(щжD'щы†WŠE,‰Гšржў#ˆЪ†O:цТƒМЅ[EUр]тžС_јф ыs вЉŒРЯХšв-KчИЄ Cёpn ,(}‚&ћƒƒо.еА(rfѓc&FАO$ІЁkщ”є€яїЗьЧZЫ3gT—•9бs•еЂ’ЬЉ<ХЖЃ;С™сцІX€‹q8щ `!АdХwг^8—фЙ4*Q™.БЫВJ{лI€Me„ЋЊ`H’ЃвЈLХмЌaоAŽЧу‰g8œпaсpВŽW$"_ƒЏgЃ’@эљЖТЬ6ЦG Цр _Aщƒл ш„ЎgRv”Mv62Bg‚]c„азцAHЁэH;§6Љ˜V1}zYэьZѕИьkЖd# ъ—ЛDf*К1НG‘qQХУ~Дd3IDAT=т)ШcmфG€#0ВЄњЏJd8к„ ­PQEzUђeьt [+qژзЊjXЖp*ЕГ1ї^сU"€@‹ fТп<• šAЮ2ёуi,кТЦП,dB V‘,ۘF ‰фЄ›i9сСFƒ“k# fч"Ь €yЉ$Šр`=fgJевДЏщ€ч‹@Џжен•k#е3Ю“ %h; Фh—Œ эЊЭ›дmП 8і њj5х"sƒŒ‡C:чкдƒ?)6’‹qЦ7I87Хy ЃDЪЋи=Е ФIŽЫDа WVьDлjyЫb7ћ ]ЬБ%Z@ iM[аOTњ!‚Сѓ›ЄЁ1ЎбFћ|ѓОWТ…{ЖeAА@'KУЋ5v)!CAй) нhШнв1ФP' O^рHзБ.­ПfѕЬ/\ќѓ|Щ|y—ўRЬФ€‚("†Y-PЅ~КI}їgі‰pe'ЪZ‰ЛwмїУЁ)8ФWSKh‘DїэŸh˜ОQUJ]“3щH˜NОq8C$ЇЂФ!шЁэлCfЬыАЧУЅ-„[щєљeвЃиm-œ"кё •†;ё f›j‚ AO-o7нн ŠLЛЄфоB}ёE*dгв­ ДЂt+=ЊиЉа‰Š›"fА­счši‘0С\…шG(HгЏЫА­ЖІЖћX7бњ1n†ИˆF(Y4c˜vCDжˆЏ%(кдкrQШhАNнћˆcж\’_@H.щКSYБЋ]"“Ф3$t Œs Ј6)ŸJNёp‡№ћwеt29UЬг…šЫsЦI87iHй{^~xЩсЄУмX_g0ВхИ0KЬд'oa"<]ŒzIЖР Kl<_‹ёЋУwOs()””(„§3ЮїЄЭИА*‡Ь(shucŒЮŽрˆMўY€уi0/sибпшвJваЏИ[НХ…x,"Cnr”исл"‚ЇЮЪЪЪЩ!ŽЩь‘kѓv5ZфP‰„сС=ЛНšІжз`>Eке9Š ЅЊBЩtERˆм4Y lЁ_KEDBЌЗ Єd"-Ю#№ЅЛRB^<]ЉТм>6“AэЙщ\\–#pъ!„sб Фѓ0ЌDћКXЛс*ИэХф-ŸwлvбюЂ=^‚™ иtЮХ/… њїj’–вwt18Eћ5Бl•нгЃђ€Yњ†жшёGЦЦ:–’іЛpgœсmxmэєю7vyZPлt6 ’X<кd^ЦЙA1DиГg!тnvk}МКВy&ТQт\Б|1ІЉa&ђ`Ѓ№Ѓг. njгК %ФАg еФѕС.ЬэВIСщmz„DgEP BKЙъ|њфЛўуН„фSЬX˜ТEoйЁЕ{ќеЖm.ѕЖ_#R`ЃˆkаЂЙWЇѕФvzцqiŽРщ‹@rЮ5л;Ш€Ѓ? ~ДQ˜;дФГЙэp@bI™€cŒ…ŒЮр)]vЫЊ;Е HŒЋi!Њ5ПOІп˜ж]?У‡R™ЭŽ%№Х ›‘а9XPУa•@ $2XjH0ѕпЂ b§yUЛšм{w7•UUйэA{Ёˆ;}ƒхѕ q˜Ь ћˆчP "­ЕU.1И HН"Ћdб;™`Эаг9шФЄmЩ~ПVъbы<[эОѓО7ђ-škOЫл j§JывVРмv[. ­Гб/hљІіњoў›§ЌЇHDэбšШSCMгmЏаюЏHш !8х#џ є Rs%чмЈ“Ф38Щ0+‰h‚ ƒцКBѓn’пjц3-!E…šWД‰ЄO%jЩ+&AxДиУhj_€Фз­ФО€T­Nя^UЙBє”l7ЬзП ЊУа–nћ‚ФrѓѕС.#_?˜жор…ЉюVЧнфЃ"ž0Ц}Й€А‡€1ИьюФь†nV‹?ЄЅ;=aš'SYћЬлJ\ФХД;зцкљ–—„ќ‹ъв№ЏХЊ…њƒhj•;Џœ7IћLўLgЂ_! \•sЯ›јЊгі-D7ж{\VОЁХ.‘Хы'Н&piŽG IЄ4ocєЎхZ%ŸМ#TЯUЉнчVь.ЭŽЗ"0'WaѓУ0Ё•nј–vД‘Щ—iUxуŒA•)Ÿи‹gpѓАbЕьљaУыдлї~-‹* …‡0Љ љ˜ZЋЯ1KЙŽpAмз;ьˆlњ;ёx„,wј|_ГЇнpƒ™ЙŠЂHЬБ5ТЏtWSS}ЏлсЊХTЙp-#А‡ТЂQщ“З~aЁнЉтмK\oПъжBохпK•vEg9‹ішѓ+b~Ь: TеLЙВP М/wu@UzеUsd—кe?Ћž–VГ дыо-Lœ„9'#аЎ‚#0.HТЙР$vH!ЌЊ•."m„4яЪч:J Доvй­‰Д.ћЏВI §С^n.#мвЫHEњ„ ІзQs˜рQъ н>{ XŸцdФs1}BO0W4 ј%‹ SГ*EбхАу•: f\А€1#+јšЂ(`†^n+х‰ЮМnQдЄО=YЅ UКРH~њЏ˜ ђжП‡бюХWTНњ"^ЎцОќт*tBIЗ`Џ‚ШЌq—€ю‰ЕnzžPUJVіШЯ}Œ˜Лzе<ЕЎял$Єp’pіtCЇˆЛtiЧ8ч&՘ pb#„s„"ѕ™Д{hXZэšŒљ mjGР~V){~Lэ іbB.Ѕ=‰ЃAs­HлУeЌ …хьa_aг€ѕ\Єйfp и$^аПuЮE)ŒЖ Ауn˜˜U„QZЏШЈ”RЩчлE”ЕЕіŠ%йKк#тxЕ„NgVГЃн…v-фпёЙЛ5ДЮ p:Ф\[ѕв3nmРнpirЎWšЗ’P?ы–ЬЭ+ }Соў`ћš'еUHЊF•]VGЄ>ƒbl”užЈKэш"_ ˜Ую=JЬі№LŽР8C чФѓТр2h7Њm;iIЙkr@#Ф‚Ё.­ЇI{:5WЉX‘с№‹aь@ХСЁ66SЌЪ˜ўЌСЖHcю„>iС№у(&˜яx 37Л ХcЈ­ж%JўVЛ Нгˆ}БPJHлCšј\йUЃ4hwѕEФpЗюuЗvmФY"^{sэяkдДІ~XЃ˜%KrЬd{€ы_x>ЯЙ€(хы§˜Œ7ьд"і/xgЎъv!ymДА˜ˆˆb‹Zця#ХgІ5ђiЉ™'9уфœk"”jСQ‡"Д;y*UJ/˜ЬЈ‘žук9ЋYH!§љЄІ Fяr€г…Ѕє‘$FЛИA6–.цѕУ5 ^ЬcCДq_уЈс™*Fъл`^xšЅeЊ:Sщx o!’!иW0кѕўObZЫљи.ЃнeФpw| кУ2œEТПЎЋЛїрмdЭcOC0bЅЄ ЏwЃŽrZТz.}Ѓvpq[Гъ;(N.ЅгыЕо€Вћ•`Pї‹•ЁЌfъЁќ—#РHT97­ qд!ž@};qыJmš_ yŽnušГЂкИ*fюЫ}К6@ќ}ŒРСЉ:­ъвFTkъАЉ§ŒŽсчJyX;G„ЧЅoФ2б.Vпxt)j{ЯPЪhЗœCЗk%/X5E нЕ—ЛШї›6›NЛ!ђж3о…п‹&лlxІёiЌsв ЏŽ“В /zМ|3Q№\Z:ЯMˆf_вф–T0Я!Yќ8G€#$œ›вМ…(Э"}Ѕ‹Чэ~„J…ZO XЖZЈЩ–pq#мєISYMЏCp`в>јцЏA0лтРxLЂL Ÿ(иэEђQП‚ЙЃЙ1к­ЙбПGsxЗѕі+…rL ­ZёРлк†*эyї{я6’%uяНф]6ХЗvUђh†ќў3$tlа,МraЯ+шЛЈTЂс;Тzзb6‹фрс „ jzі 5<žkС‡'9)#`rUм)…ЂKГg%Ў }ŠМуAzўЯ„Йй.ИЕОЎ~уп6z0C`юOЖ]eмœ-ЏmжКcmцФцкЕзню}GsywѕРл=ЮE нukЊІМгєж‡›–Mƒч[•Ъ“ЧBУУ0рAAпо ^ћЋД“cЕЏ•єЧдBЯакіГћБињVuїсћ/e‘Ў•Ї8у$œ›FH!@мЙkХЌн[S1†Њn]Г–эц`=кtЖ•Ы™є(Ўag—ъnoйо_I>2qбPbT~Aˆ —е7ЌLЇж…–‘ž ?йfX‡gИMvЋmЊю§фX ›с  …%A_ #м Щ]щQi*WЪ8ѕHТЙh`ѓbТ1В3Š2уЭЬJХlN ™EEЮЂ=AАзЅP,K‘‘jЃyОJj…’ШљlЈŽoŽ@ќSъe Cъђ\’#Ррp"HючВ 2DдЩw9ŽРxE UЮ>FсєЊІВjŒ›6і5ž~gЗˆ#pŠ"Flсm!7›#Ррœ<pЮ=yЮЗ„#Р8§‹-ьkqŸў-ц-фp8'0Ю­›[sт,с5s8г0ЮеzwТžўЭц-фp8'Я=!АѓJ9qŠчмqzтyГ9‚Рџ>Ј†”сИIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/3.png0000644000175000017500000013326111733011756026155 0ustar sylvestresylvestre‰PNG  IHDR.# С тРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН xUжїлѓ™їIGœ ?‚'ё5*О€@ŒH`И‰ШE†Ы’ *ф‹ ю"@N@Œ€Š‚ƒDnъ$ЈD2FЩ gфM^ТBцŒЄѓœјМguяdgЇjяъъKКЋ;џ~њщЌкЕіZkџvu­ЎKj§ЊеЧџcГйn\“IŸx€€@€ \ўЇrIyЈч„%і w   @Оxk^ЫCUWЋA@@O ЭџОХyTф|е:и_|‚€€@€ дЇ"‡ЃжПŽЋ.œЖ]­Деy’с"ьЖжБ1э;њ7Xџ№}џf О3ё}<††ЃЂКЋМЩwЁъBЙ=ТѓŸi6{ДжеUЇU§6І}МН   $рћўЭ |цћ(Фx*›Ш5пlП9тМэwЃ(ЛмєяЃgЎкЋк?TSАРіЖЈДœ&Њ|спе1џ9иfф І{tLЧЎчџVhЋ3Ѕ%пїoVАр;8пG!ФаŠ„&ЅaoнКЕнф)7OѓѓЊ>Šъ}wьд~ёб­œщэ‘)ƒV|2П—yeоOь%Ъ\ Ћ4šX7ОяпЌ`СїYё} 14ЄЂ†П этп:Lщl?нњ†ж.9Nе”ьw8/йЃTН"lQЂгr i’M™йЉ§Ђ[йцП}шъхЪЛnА}чˆ5iѕЎ*Э+s›b/Qц L0XЅбФ"€@˜№}џf ОO†яЃbэѕ…еNё–T[DuыlіVіізЕw8”“ЎкЂЮйЇQlжEЪCєrTW:г•ЭQ[Ugъ`ы‡yeВќШВCоPоšЎuEдпЪa`С`•+L|€€И'р>EнпщЗЖСНт###+*Ъ:ооБќЇђ ŽшЊjƒуЛдsў“MК ЃRЃц:–’є§dЖѓTНVdЇЯЬЗK7ў1Бь\эг›й#ьћЇuЁЦЋгБкњё]nŽ$…я~ЊПуХЬБДЖЖЮvшTхВЫи…(fВ­Ђ—Иш’{ЅЏЮgЋ?#lГŸаЋSlЄŒйшЎёƒ’bcЃ#ЋЎЭ/Ў|їЫrж‘GЮЙЧFГ@BŒ€dхvчFCіo fXа ZїД‚QХ;Y; ƒшŽьъЅ1№нЊжЈšупеххёЗЦoпБ§Оћ’ЏV_НъМГ€ђŠЂYх†ECMхжЖ‹W#к5i#ГЮŽZГ,;ўЩlgО™ŸЛХAkыье?'&Д‹М5Ђіжлу™ЏЧяВН{ТNе?лl—ЫэЮ№œЏуп”эљВЌяƒїіЙ?ЮёsэъЯ*Y;}оeЏЯ퉋Q6ћ™:ёіПШЇ{%єIŒ=P\ёз#eіJшu\ƒШб&Lz(–Rн’ЗK‡t‰›єPЏНљeЃЃуЅл•9jwй=8Еи`AЌD@ЗЫџc“й+э‡ПнИЈžяпtЬЯ+ MіДм‚Y—j=Х(ФБs2ncpюјнОь6GышXzнrћя:оеб^aПpВ’nЈ3yйgбмДЎЛШнm|2‘dЩ„q ™PUчLTЧЌЄФ@‡k];EV\ЌŒptН-іПЊ+)-•§Pб:тjTD}")њњ„улžce”аѕtйщЪJWЖ7ш!ПŠ#›&d“њXЖйЎкœЩуѓЊ)uŒІ tЈДТ™Š:%мwЮљјЂгeхЮ#Ї#WvœЏk_хp†D7рнdПZхwдъG*.6•ы/V‘5[ыЊja€ЖX—НчžьSoЄоQe•ЃўЄшxШƒ-кA?Iш%Zц} €„нўџШІмУ$CЁ/>лПщ,H”ЅMю,ИO~м‚дОGВQ№ Ф9А<д$0Y дцўuK\|BлЋвсQыZG­НUф™Ÿmѕ;VЙэI6—эСѕэbЃй­/ЫЋщђO—Ю ‘‘6КvEЙЇз§Ж^уЈёєO•”Ћи!9mнЪюЈŽŒjеšdКCЗ>DE4ёгJ’dHtоВQыVtыDН5ЎTYэЬFЏМ‘˜Ииš1 ŽЖHC\мыаю4ЎF8ЯичџБўgnњe6›Иgc#їІ@B™€zХFхмГiЏŽИж№§›; "&ж -h~ы7нq ЋН•DГ‚єЗЫhoЬ З:Дѓ2Š|B/2І|ед]љэІЈhЧU{упWлЗН…~яW§ЛŠ„ъh>&…іўпU}wЦfћГвDг;zmкlvщ|ѓжёхL 7LS;UhсЅяТWвс‹CЇЯжŠНD™жR&Svs`бZюЁ^аXаЎЦ2€@И№zчuGNЮw м”зAЬФМбиЌQ*В9ЪmџЌЊЂГM7D}љ_Ÿєю0Ьљш9зЎЖЦQc?Aї,зддU9Ў~sу}Mн4.4mЅ%1DнJv,Ѕь+бG€š€б>ЪhчмнВО Fљ§iѕZ0; эаGбшк0EДЏКдЧAЉшТе˜ж§дХгЩ­šЧ[Dхљ %5gщЄ”-ІƒЎМP?лешЩЌd‘Y#аf"рћўЭ |‡ућ(„vќ …UЖЈbm7ќ‰п‘\ХжнрќCQЖО1ЂЖ(гХ’:н'-Ж™‘щЮƒkEf,@@š—€яћ7+X№‘яЃbЈOAvчcљяe­*Џˆ‰ѓ(QіЊњЉ"ЪNї&ј5џ –@@РцћўЭ |ŸHпG!Ф ;V{'кoˆІ'Јžћg§™Ь‰ВGS_ѓња№}џf ОCѓ}b Э’ŠШEIoбdОяпЌ`СїЙ№}<†&ЉЈъ’ѓQx€€@ФмXџмЕЦTDyhз$э#m \€€ДLC7•БlєПZцј1jы@*ВЮ\ hЁŠZшФcи  `HEж™ D -”RQ x @ЌCЉШ:sH@@ …@*jЁaƒ€€u Yg. €ДPHE-tт1lАЄ"ыЬ"JЉЈ…N<†  ж!€TdЙ@$  аB Еа‰ЧАA@Р:ŠЌ3ˆ@Z(ЄЂ:ё6€X‡R‘uц‘€€@ %€TдB'Уы@*ВЮ\ hЁŠZшФcи  `HEж™ D -”RQ x @ЌCЉШ:sH@@ …@*jЁaƒ€€u .“’ЄAЈкЅЪО7и4рв⧇љдг… љтХ‹•§єЋ§йaћХЖ$gEjяz“@‹м>W&AўcфлкuЙ[jп”ќїv0}Вќмь9ЩНS(`њеY]]Э юлЗЗџАЧ’Л%ž0БтL™hпИЏ+ШХd0u@П- Žœ]œСЫкEгъjŠф0юў)eХIаsі•Ц@š­хLMŒГЛl3`cсюјЂЪзd‚rѓжш5]\№ќЬ­яn­ЈЈY\ЉђkrјdJŠWtб(K'ШмvKё№э”њ•N+ѕнђо;єЂo}јwпѕЕ’яЄsЇњJђQГ)ІO&8лC6ъbГЩC2СŸќJћtъљи<ŠЖl~ЇфћSЛЗm/:PeЗхЎЭх1—ќ§дЖЗ7—~хМN` ЦєŸNŸјъЦMМяыoО=fќиШVіЕЏхV]:П{з^zŸПtžЙŽ[aу[N§у Хіз].]`њ“ЇgM9ъhaAбЧnЙuљк5мЮ‘П•lлАЙшѓ/z?м{сKЫx;T}зnмPuщjСОНЛџВ§HёЎЏjч $ P(vQС4vЧNСбЇлsqzњОЊ(NЖІ—ŠžtšTіgЬ™џєSЯ=\Мy}о7'ПБp™І`ѓ†МЂ_ ш?0=kъСУŸх­ЯЃiж{aЮBІІ †жъ‡Я-ы;ЂВjѓuє2mџ‹чЭ™Еxaу^ИAЩРЏ™сЋ№6˜oђW:AцЗ[О=Q•_еД–—аwŠОYє§ЂЭ›…eрZ:wЊя…Ъ)ѓЂйzЉбРЏЊ ЕKCRq`vјЇДo ЇžGт…а,Љˆ§4?yd[їьЬž‘н&:2вžљTжОO№U33ГЂЃЃйЂSш’д5ЦUxРy`tё\хс/xlЩћ іeOЫ&;єzaZіў‚O˜О™Я{іП0#л[+ћд)™ЌЫЎ-л;пkЛЮNщ‡??ЬM-xО~ уF8љїRоЮUп§юƒфњЊvЎ@‚СE€bL3юD;*й-ъЈŠVЉТVб“N“Ъ~TTTхe:”­nз.v^і щf>ŸнЎM,m#†ИіЏkттЩoъЇU 43|юзРз!AЕy‹:LжќPHLМїС.R2аhјЧЋО ЏЦ;s* ѓл­И=ЈќЊІ•­H Э›ХcрZ:wЊя…ЪЉ5_4№Ыuє‚4$Mwiпfšzkп#|7ЁЗ п@љAы•ŸЮ|tXcС?хоn Цu&ІO\ЕњеД>ik6фMzr эJhейЪЫэnŽe:$\Љ<Ыѕн g+ЯђО\ЙєTнжuВь$}KBР‘­ъ&ззъxFAеWt$zTЕ7Z4 PьЂ‚iЦhG%Лх@U1а*UиfшёTізЌ\žїЦ[kз­љuдєszu“мAПZ˜Ж ‰‹|ZUСPG3Учqис:LnощтдєŒб“'&wMІДФ ќŠу%}q‘_…—лqЛтэ_LЭ .ЊќЊІ•›ФяОkщм‰ёsƒ4•S>F`рWЃ).JCRq;’,эШЉзФубЂАgѕЈŸЗЪmb;МЙYмкЄ–ЬЈѕъ–Вў?^]›Зсы_П4oГг!Ж-$Б ˆ„6БmYћѕ6К.Хі5ќzЦu‡иМ/_5sжЬщгІЇtщJGEd!ЉGOОЪ­ ъ+:"мŽЊ+  ЈЃ‘U0ЭИ㘐zQƒA3єxw•§„;^YЖ”дшDџ‚ѓ?њ№ЏМ‹G‚*•еіfоŽtѓVЙkв~эх Гцdoлєo7я—w^Q‡Ытv%4ЪϘ\A*ЈќЊІ•]п§ЬІЇ_1~ёыЉr*œ=ѕЋВCэ*]јЊ@N=wъ…а,'ш т3rитe‹иWœ)Ї;ЄЪ&е&І?“З!oЪФIќЖЋ}хЌЮqž‘ЉЎ^Д:‡™§ляI|gлЪ%еWЊ—ЏЬ‘:ішРE+rHn  уLЇІІЦnЗEкэtѕoёЫЫЅUЊОћ>’“ЛЦc5EЫЛЋкЙ ЊŠ:Yг­ЛЖmЎЏ8'ЙЎБ/]дєUХ эЫUєЄгЄВO˜ѓ2>нНRgЋ‘Й ЎR#ъˆВj{ѓШŽfѓцЇDGR9..~Ьаa+V6nЎљелTсеkR‹t‚МиnЩ”ЪЏjZХЏеРYxžКV}/TN9Э6oЦЏІ 7ЅT4jвХ@NН4“NEcЧŒы|чё™“щІІYѓГSJ•jRЭaЛуіƒ цFІ>•sуM}‡ІїM7оD‹lеТЙГ?§ь㔇zŽЪп=Љ;з…є юИuШЈ‘§†iпО=[ѕт‚ЙЋVЌJь‘4>crчћ;‰њneUпЉOeЦм`я;h№?Œь,ЃjЉ(ъhdLЗювЧgŒ;ЮќPєЋщЋŠAьЂ‘UєЄгЄВŸњPїЌйЩ=’VЏ]Еbщ‹цUСЈ,ЈЖ7ьш7o•;}ћ№a#Ю_НЪл=ђЫ{qA…—+ˆ‚t‚МиnЩІЪЏjZщJп)њfХДnM'*YTžКV}/TNљи5лМПš.м”FPqаЈI9ѕвL6ў*Оџдž–TUVV]Њи5)Сd7‹ЈбmжПяїpZjšEтA рGиМ=‚IП™єWЉ=ВхРКЉ,цЦИѓХ{}TфЧЁвMє?ўїШC~D Sж!€Эл:sH@ аЗ-јkHє ЈC|‡5^Мё—wиf%€ЭЛYёТИ „j*Т‘И7&„ф/иМН h^@ГN—>Agˆˆ@@РKE&KбxwП–1‚цАiь‘­ Є_“xЭ„нм:Фтv,ЭŒѕgЄљЦю{ш*x ЭS§@’БTlKE!]ŠЦsцGSтVвxХ„Œ ›ЉlО4го љn>ЫKEЊR4!1~< эж”w@Tx›oгБІeЗєм*№qбƒ<шэєЄvz84otл+ј2#>Кцбj›І=0‹zяо SŒVoS\k,ѓО\0жїq­д‹лНNНш.г ;žv \*B)OчЦ#}рѕ—[eК—њы’/woлKOjџВфKZtлEЃрѕŒјюZ‰5[Ш0­ п‚Q5C*’Uщ`™–>5)WкNлЈДДr‰Ш”ЌЩ –ШЊ€ЈJТHЋ’4†-ЋХЂЊ"ЦЦenЧHйZњфjдQ:pRр•]4Н”ёШ‚Wйчk7|\кС+<ъЎёЂ‚дЛІ/_дsг€bšв`опїсДЩгшa‰є&ЙY3‚шhх++і}ь|„<{‘L-$“Žtsѕб5ѓтЫиЩ‚О; ˜orlQŠNк]B єђt˜њє6щ OвZVЬЃGŸЊ-ŒHgкѕКѕШ†@jn7lЎЩlђEUGy0Še ўSЂpmѕ’——цЎЂЊЋrW‘ЬŸо+н\}wэуи Кk69):ƒю".†iвІj{§rY2S|ЭІкIE:kn#4vчvУBk"J;Њ‚Q•bjbБщ‚яћѓІі”KўџWяЊtˆJЋn˜ЌиСы‹ˆKШИдІД$ŒqUБ– й "з‘ вЈ4šWекPХ# оРО&ЖhЬGгEъ‘tм\5ѓоЭKLлыЏчUEшIэmsНfh-R z^ѕšм—J;Ш:ЂcЯляИƒRˆд,+XRѓџж ў}^АDЊЩѕ%aXU’sхџ /њ 7T‹…ЎуQM#ъ>ur:3Т*‚<ѓгtњбAЅЭїьнcрбэ* “ЭЊт‘ЏВO ш’дE4Ыd)*ЯГpбВ ызДљm‡)œДчЃІ,ѕЈЗЉoQ Aъ]пZTувр•іЅF*‚ѕ_?]2ЪЙ6NЌ‰ХКЈјш R ЛбЃЦАђоTбМђЇђ%+—ЯЫvж–nЎОЛіqьЊюњЁI[Tн5фнS4nвІзл›&WбОHЕЊfMЁ8 йэ†­њŠI;Њ‚ЁRLK^^LѕœЂ~•>>Нр3ч­4š—fš<нŸkЌ™_ эzEšqвіdœЯ4њДˆ’0z&ЌeJцгO=љ4;CЅвiЩэОѓёbsХдДфM.,ЧЮыљџЈ(„xбEИ*- Ё˜ъКмѕѓŠŽ‚Ш'ˆЎCqІsHhЙЉˆ~“ЂтQHlЃ@ ь „U*ђшьœGЪaП`€'€-0№ЬсбВќe‡ŠР@@ЌIРъЉHsgKР ZПиŒEiЩ‰ўCњ4і–ъ„ncА6†`љ б™ u\ŽпSwžъ‡ЪVdѕTф–c3MLˆ›YНnѕтљ/в™œќqЛх@СGЭєеѓ"*я"ёЎ—с KŒ%фS‘л}Ўw“фKБЗ[žw!Й5K 6=[ЯŒІJЧБљб”*ZM{р=jАкЂз@ЬttћеSб0c\еWlчvМ‹ФЛ^ї+#ЪnDeПШ^Х/о§b$фS‘_(шx]lFo*-ЮАёP#рџTDПіэvъ•4zь(КшRјqса'Kю–4zТDzCЄ*BнХš(œgйe§‡Йѕ’Vђ юWгKЊЊ8Šд>[cмй.Ћ№Фѕ™ †ЧZє^$–Ќш•ktХ] ,:­еfєі5І†{ЌЂЂ~ъi{`НЈ…кВ‚с“ТКАOщЦ ёhlV^rFFЃk•Т/Ž%/-Nю•’: Yf‘Ј b5ZгIzŒZ™#­ŽtY9 •їр Љ…dОVZ‡ЏuM~“oЈћqпъЅляЧBe‹’t Dќb@2YЙёG$>в‘ЪТБ\›џS ёHё‘ЭђŠ|1 џРєЌЉ–З>Џшѓ/Єѕ^˜Г10*вД& щџъиŸІdЮ™=}јАЌЛєS_=…Зв'?€UUђ ƒ)џЃЩdE…*…о2Ѓ$UІUњт.* Ь}ъ SЃдОЦT”'JN2=вmођщБl$+9Aэ$GMšєRm ЄidЖИdї_Жьл[uщ*qq6в7VXћк†Њ;Шй,љцSVФbkѕŸRŒ5Љ#Žtб…^_ORZ‡wTUС13ЂF#ЏхV]:П{з^zŸПtžцЋєл_ЅЄ›hтзGЂi1куЩЖFшq_Ц#хjš%Э|>Л]›X*ї2bјzИœИxђ›RFС ˆІ&JўюН –Э}].=H똠ДzŠІ‹Њ’ЉiќђŽЊPЅХQ ьsƒСdE1<МЈ”Ѕёkbг,J Ћь‹}““:ђM Еь-мUXш<0*љцЕ“`@@5išпŒЭJKЮ„Aж ю/ј${ZU WvfSVФbkѕŸf0JщMё–ThбэаxЉ -ŠУ5UUpT#тQq $DЈйx/Љщ&€јyT*AЕ!}щжЈЂЇВЯкGjм7Иk›х_\щ ЩFХŠ‰‹зъъЧkPDSeы뛆=:œž…ю–”ДzŠІ—Њ’ЉiќђŽЊPХт\йР>зб&+‚ˆсyфEЅ,_›fQJXe_ьлЕѓНK—9Аєсо§+ПИў­7щi˜_§н‚YЮЇ‚GMšц7cГМL W*Я’ВБОБ‚“dЛXІУ-гЂД SгšСЈrЄЗІi1 Ќб”.J‹тpMqC‡ofD‚‘ЫМЏ8)Є йxЉ нDП4БQЕ!щР=ЂЧ”ЋYPh–Tdfœх@4нпкАyBЦxћ ­Ч>atvNгKЕЈЊфЁвЇvUЈbёон ћ^TёШ‹JY?ˆyAe_Д@?Jn‹Л‰ŠjлэQ]Кu]Пq§ЁЏŠЈ…§X1OРЃСРЌДфŒ>‹JСй~Б’e#Б ŒД –ˆE”Э`T9эHeUфЊ*8#вЂ8\GмФс›‘`ЄmгIiЫWљ. ~ЗAЊv#дБщР;0SбуоGЪе,(4Ы :3у4(ЂщNП‰hДѓ§[ЖОЃYefQS~CUЩУР”*Tiq3і5!yQФŒ>"•В4~Mlмˆ ВЏ1еНчƒKWЏ0иYјg@џK—­Ђfж<уAубРЌДфŒОqœЎŽkЊ]/В,ВвФЂЕќ"ГЈЉТ(ъ8’кфіUCSUСб”ХŒ?"ђфэ#т:\PEШ|š/~cьbЬЊнщˆєШzyD;2)WГ ДTФЪ$іHŸ1™ЊЖЃqю€^Ялљб~К”gЌЉ_ЫЪo№-†*ytОП3е=Ђ;њЈ YъCЉњ.šUЈTЅгЗRэЂ~C‡Дoпžѕ2c_U‰Йё&Њ№Dя›nМЩm…'rdЦ …JYП&6nФ@PкŸ1bь8N>Ѕk2 KKэKІвњє%9Ѕk§Х?l šр ЬВBATИ%Іuk^зЪ@Ÿ _Ѕ‘žsƒЌ љУШЮїtЂC ўвФR:RaфІH0p$ЊщeUфTчгЯ>MyЈчЈŒён“КѓŽ’Ќ(NrЄеkWщ‹xQœЦс FЬŒˆ{TEШ|П&<кьХ7­UэFh•tkєˆїnкЧ:F{ЇіN™;нpХцœEЛ$gёЪWVˆ[-RЃиBВГ(Qч{Ycѓн”ЌqŠEh>a›Šš ™яuŒ(yа›?eЗ/^™#Ц9уй™_—ќ­№`} …Т…Д8яљ™ЂЩ(JЄ‚EP'рџTD?№}ЌW$­8ЂЊ‰"­Т2иёG§ ™Ј†тЖРŒжЌ ›Њэƒ;уйЌ/!*ай^^šГjљЪŠsхє^ЕjхŸ—ЏБ]guФФ’Ќ)ыЂ/c\4HJRt @š‰€џSъcН"iХUMivкŠ0pѕZx5Зf4fЭи4œЖH§кИИјщгŸŸ53›огgЮхьхšb LцЋј@ЈEZьФИh”$7@š@ГЄ"Б@‘ѕŠЄGT5Q Њ€ˆдЬTCёДРŒ›b ЂLW‰VќyyЯфžb#“гњЄйьtі.*-еM}&M_БЌ‹Ди‰qб “$5NБ Оh–Ї-ˆŠ(DqбLН"iХUMƒ* "ƒz-єxMЎщQ“6Йq&А3lms}=ЬЪжЌЅEgНэ:U9ЅkEЮДdњ%DZьФИhI’ІУ"€˜%а,ЉШŒsƒъвюЊš(&эЈъЕh|yT`ЦЄM ЭY5ЭZzЦхЊѕ+7ox›ВбјЇџи1!NйitЬ,J‹ 2IвŒwш€€€Gšх™ ЊwHЛь+Џ‰ЂВЃ)ИbОŠДРŒ"ЄA9Ћs\EjЊ­Ю!R5ѓЕЕŽYsВчܘKEиш* Дhћ…<~ЉŠ R‘”њfЧvвUhO -TяŽAUEeGSpХ|5}i<дhоІЪ‚І}ХЪхvябЋg§%"швcЩЪх53‹Њb'EƒT$ЭИƒ€јBCевг˜бj`@@Р№8T9EiЙ*ZA@ќD hЗ-ј)~šЁыЭQ`ЦŸ!Т€„#ЄЂЦY5ОЗ­Q€€€_ эЖПŽЦ@@B˜RQOB№ €TѓˆQ€€@@* сЩCш  ŠТc1 aHE!ЉˆŽfЖьЬЏЉЉщгЇЯ‚Y3##эьˆ}ђ ­”uжНЙщЪOgoџ]тЫ/ЬŽЛеy'ећћ>œ6yZtчЅnVч­7›Š~Б5огхУдjŒhЙсвП;3Vт=‰*ЎЉќЇЦЉf‘y|ээЗ&ќqТЊеЋш’Ь†з6L~ЮКѕыДСЈ–= Rъ]eXлюзs•ZуX№œ@˜œ лВљ’яOэоЖНш@A”н–Л6—PАєCŸ<Qу‘П•lлАЙшѓ/z?м{сKЫБЫN&мUwoBBТ?žєœЄЉз­Mэšм%yюќЙЕчMШ”Wи'˜•}ьы?Аr—ФбЃFWќXfЪДџ”| r]юК.нЛDк#щ`(3+“ќ—ЬRmЩKKRLІ7 ’Ле%ю§–ЌB€@p„I*кКggіŒ,:ЌЁƒЁЬЇВі}r@…sСѓѕjуF8щ:Ш ЭЫзЎQGж%В•§ђПЎЉКKкщкƒЙї–MKў~jї_v,ŠŠˆЪ]“KKПqшаЇS`v(_=ВэmE‹{Їѕ^И`Ёж>u0чБQЭtПYg;іеБЄћяnŒСmЬІƒ$EfvэКЕUЊvя- їљ чiб­ЛZ /‹“TD'м>:ŒЮХбЛч#\ОrYХ9ВU§?œPюЙжАWj{§ѕЕ їјжўьhћ›ыUн}iпњ>хЫьшЖ”/#3Їfюћы>•ЕГ0ЕqЃЦё|ЉRіoЛП‚ЄƒЙЅ+–О0џeџ†ЇБЖџУ§NЄЎз 3^ EAB‚@˜\+jлЁрЭЭьbмoKИЛьЛВФЮїRпВВВлnЛлЌ‘:‡­Юь WОиh™иѓО\p­ŽЄџпtЕD^gsцЫІk*њ–FЛ2Щtœ~ ВДєФЬy жЌ\оЎ]ДЁš’8[y–Л сJхYSюШ^ V"&ЉhЬШa‹—-Ъž–нюциŠ3хyoo~щ…ФЙm›ы+Ю•ЧнoЬќёAшV…еK?сI Ec}О–vif‘ЭFљroг|ЩћrY6^$G%˜гї щєуЊе/-_™g‚Gqš’шлЖт\eьЭБдRyЎВMl[їщц&Дƒ‰@˜œ ;f\чћ;Яœœм-iжќьд‡RЯєё#ЦŽc7бІћхшќРQƒщM‚йлч ,ЪV 9lбВEДЧЄ•хgЪ/ZЬД(_–ŸГJA&ƒмёоК}nMюыyВЮ#}хЌЮЉvНH ExДX@˜fЪFєж№ж4ŠЗв‘ІИ8urН5нн/вй3гwг…289s2ЛљŽ;ž™№ ы;vLЦИБуЎ§ыZёб†ћЭ46“’“XHIINЁQпm Іує1Шœ9ЫАЧ‡ёˆОјќ ЛНЩгсј*­`:HgG“ŒєŒм?чъќ'АС§гЂ‰щ sЊZЯX._ХїŸкsТ’ЊЪЪЊKЛ&YюqХT‚СВѕŠшŠШЗп1|DpЇаŒїљ;Ќg€‚Ќsьј`яи'B`жЬЬ,t@ Є нTscмљтНсsTДљ•kр!gѓ‰ EAћІР1Ј Љй˜[*ЛЖˆ3$‚4З]@ @Рarл‚#†j '€ E-|Р№-IGEгG •Mn%кЏ…ФЎ-$т X!1enЗ=(€@АєQнГясЃ}šœ_§ъW,!™Б’˜xoЧŽё{?иkF:  *ў?*:^|ЌМм?џ%CyЈKRWUшЭдNйшўчLБ№ ?Жz6ЂЛЉ$п`Jў~ФО“/A№˜€пwЮ~NE,бэзLж!ЧCЂOГQТХю-NР_лЇХ‡‰№@ љ( у~@*rйШ=#h€€€ќ|л‚‘XБ+неmХА€„Є"Щ|RЂ#!ЖТф?IЌ  @@Рœ гrbџпЪŽ‡pjNKЫ  а Šš@eyЈI@@š™Nа5ЯХ‘ЬNгб‘GљЩЯ=jŒ €€пŸыу6vЄ"ЗˆЄ"%"v`DЋХЃ%ЅЖk=їˆђP—Є.ЦjX  V&pgТ–76"YeŽЬ'!ЋDŒ8@@  рЖ…œ4„  сEЉШѓйЎ];KФ @@ Š‚A>A@AHE‰IISfLbpŠдЈi яEѓ‡AЏЌxЅгя:б›„№f‚бДXAHEФКѕ ­ѓw[НЗЖ‰ќэ[Ž|ёщСЂƒє&!{ОЂB  р_СIE žŸЙѕн­хњС\МXљмь9ЩНS’{ЅаСSuu5гЁУІ}ЛїііXrЏЄбcG•–ž(ќИpш%wK=abХ™FSѓ6ЄіэGнч.Z\[ыр.‚uрх<ЌЙЇг-ёЗdfeжў\KёАC"њd‹pЫЛ[ьўР-ёэі}ЄьTkміо_Вg/ŒmKoЖНЗ€„ рЄЂШVіХѓцЬZМаі‹–ффщYFŽ:ZXPєqAЇ[n]Оv з8R|dѓ†МЂ_ ш?0=kъСУŸх­Я+њќ‹iНц,dj[6ПSђ§ЉнлЖ(ˆВлrзцђюAжхЎ+љІфрЇOwкnЗ/YО„ТИxё"ћd ьшбЃЛvtКьП ~|кЌiЌёфЩ“ї&оЫdh‘Щјp"œTDя}АЫƒпк ЁЙkЫЖФЮїкЎГSКЪHЯ8ќљaЎ0ѓљьvmb##э#†ИіЏkттЩoJ™кж=;ГgdEЗ‰&ЕЬЇВі}r€w/-.цrР„­яnZКd)гDЖŠœ—=oџхЖ%‹—8е"#гџ”~ђјqсх]ЃŽL&сђП.,r8€цгІІgŒž<1Йk2Ѕ%>рвSeЋзЌ>Yv’’ГQ0::šЉQš!A\МVЧжиЎќtvрЃУъшаНБ1€вЙђГIЩТъx„сDђсД§ЭѕtNe#кўІmc‡+ѕЎ1\g{yСТЌ9йл6НХНЭœ5sњДщ)]КвQ]щIъб“Џ2#Д‰эP№цf:*2Ѓ6ПэptџGtИуЏЛяОћDщ‰.нœO"НГƒ^  `eA;AЧ ФХХ:lХЪхœQMMнn‹Длщў…Х/7ЖscaЬШa‹—-КxЎ’дш^КsыхЖ…I'Эё\EE…­ЮVіCнЙРтiлІmХ™ ›JxlиrV,ЌМXIoF=1JЅ‰v]A=*ra>l„јoF/.˜ЛjХЊg~šо!ЖУЄ'ЧьйЛЧ#ИcЧŒ#§ё™“щLнэwм11§Кћ]yЪ3SжйlЃžxьмЙГЗwLœ–U?Тдџ35%-…NBŠw.шН=ЖВМ<5%•VЅOJ>rИ^-  ъ~пjЯ KЊ*+Ћ.Uьš”руxђwюHыг—_і№бZШuЇсуЩм!7k@@C€ў‹†žЬMЧ švОHџNsКьДз4†n*‹Й1ю|ёо Ÿ 3ŽkA@ZЄЂ–0Ы#€XšR‘ЅЇС€@K €TдfcK@*Вєє 8h ‚3w8QŽ?vЈˆЪТ‡г 0–F€nŸЃНY GTфOк]’К’9šE…-,ЪClo0ЗHE~FMѓр)єѓ`@NзŠŽA@š@*jЪK  '€Tpфp  а”RQSX8ЄЂ€#‡CІŠšђР€€@Р рfn?#?^|ЌММмЯFa@HџW@иЭрŠх!*Yд Жa@D€žCžљ/’8*ђчдвёJчљ(lƒ=НŒžШT„kEјgј  0 ‚€ƒ€еSQbR’GX<еїШИХ•лЕkgё€H X=IƒnсH9-|Р№A ќ!ЕфЗ™4sётEЗv  !D Љ(„ш TАJ*КxБђЙйs’{Ї$їJ™2czuu5ќ–їоIак—ф,Ж§Т›mѓ6ЄіuЖЯ]ДИЖжбИЂAВФсWmўм~w НчЯoЋЋNsєУљ'_{шѓCє~ф–јvv {>ыЬз’Ей3nЙу–:wкєњІ†q;џОВт•NїtК%ў–ЬЌЬкŸkХUA@РjЌ’Š&OЯš0rдбТ‚Ђ :нrыђЕk8Љ’т’нй^АooеЅЋk7n`э[6ПSђ§ЉнлЖ(ˆВлrзцr}K /­xщќйѓ_}љ-НЯœ=C‹сБ3oєЩвќг”?ЭЮž§_џМИkчGGџvTгї•/U]ЊњіиЗŸ}ђеg‡?уkзхЎ+љІфрЇOwкnЗ/YО„Џ‚ $`•TДkЫЖФЮїкЎГGЖВgЄgўќ0‡•=-;кѕ"aџ‡ћYћж=;ГgdEЗ‰ŽŒДg>•Ея“\Ÿ ЅХХ\–АsћЮ/.Ѕ8щНєХЅ;ппщQ$QQQ*/T^ЉŒН9vEЮ Mп­яя\№ТnœЏнњюІЅK–ЦЖ‹l9/{оў=ѕ‡S\€XŠ€UžЖPzЊlѕšе'ЫN^ћз5' !Ўv7Ч2d$\Љ<Ыф+?јш0&;?§ЦF Hg+ЯЦХХБ@тnŽЃА= jѓ›зќyЭKЫ_ŠљuLЮЫ‹{=дGь~іЇ&ЦљЊsхg“’…›р­ ‡ @ …АЪ^jцЌ™гЇMOщв•ŽŠшТORž|b.žЋdйˆ„6БX; onІЎfMЁCl‡ŠŠ –*ЮU№јЏАежжFFFRит…1Э(7nкHtб(ыйЌЏKО:ќЖ‰qОЊЭo;нџё  `eV9AWSScЗл"эvКaёЫЫEd9ЙkhgMЏœе9 dЋЦŒЖxй"JNДXqІœю\Л0й З- Ѓ8-ЎОRMя9ѓча"‹эюћЛl|}#eЃЪ‹•ѓцЬуСЗmгЖтL_Є›œ‹uЮ†šџЏ†З3aиу.у„цJѕтљsјкI'ЭёЅ@ъXіCсЋ €€€ 'Q’пФхХsW­X•и#i|ЦфЮїwIбт?Œь;hpLыжSг3иЊБcЦuОПѓјЬЩЩн’fЭЯN}(UьbљљщЯЧмг­ы}єОЉ§MДШb[§Ъъ?њАу­џза!§“{$ѓ€ЇўŸЉ)i)ќЙ~}ћM?ъ–Иv -|§ЕзЙцޘг:цО{я{8Ѕ[їѓЕSž™в9ЙћЈ'ЛхіvOOyšŒ№U@@Р‚~пjЯ KЊ*+Ћ.Uьš”рcˆљ;wЄѕщK7јh'DЛг№ёdю;„  Р аЉz2ї№a#x‹F(-=qКьД‚F_Е8tSYЬqч‹їчЈHкA@Z ЄЂ8щ2€X‹R‘Ецб€€@ $€Tд'Ck@*Вж| hЌђ/Ўс>>>ўиЁ"* УС(@Z&К}Žіf;R‘?iwIъJцh§iЖ@@ А(БНYРм"љ5Э_€ЇаЯ€98\+ 8r8hJЉЈ),€œRQР‘У!€€@SHEMy` @@ рŠŽA@š@*jЪK  '€›Й§ŒќxёБђђr?…9 ќ_Qa7ƒ+–‡ЈdQ3и†Izj y фПHтЈШŸSKЧC(чO А  єє2zjL SЎcžс@@@ €T$Р€   HEС Ÿ  Є"D`B*JLJ:v”fАдBэbу–їv$vKЂOБ‘фŠŠђЙѓчЄіэ—EЫЁ IDATм+itњФC_iА  Z‚ŠP”=ъаWЧ8)J'дТ™АuћжfgямОUlПxЎrђSъžд}їŽэG/|nіЧ§XT€   r‚“Šž;ёЭЗофАомђцг&ђEŽu,цз1У‡Œˆ‰‰ЁжсЋжlШ›4)}аСбббЖыl ^zq)_Ћ9Ўтэ@@ЌL 8ЉЈWjJUељвSe„ІДєDUUUЏžMў-tлЮmЃGІЕ>zл{л8СУGЇ=м—/BСIEnвИIoН§ ЏН§Щ"Ъ‹+џіэЩAiiд˜––F2Е0…š+—ЃлD‹ЪЂ\Z\,.B AKEƒњўюлП,ќёфI’EXлwlП|хrbrpЃO’ЗякУЂкД­ОR-*CuAKEtЅgܘБѓfЭ3~,ЩЏ_lљЛї}ђс~:Фao’ѓwцл~qЊєHюQјYAЃ2$а'МTdГ3юшWХcŸ'b,,,ќЯћюnз.–7’L-дN-Y“7mкИoпокŸЋ)9•§PF7vsMмЖРQ@"ЬT$ХєfўЛЃžаўзбcУF§%џ]вowslоkЏvєHПЁƒ“S“^ЮYіћ~П—кA#€€@ЈТ“ЙU7Аіw76офЭ!іъж•оl1..ўсnЎC‚ЪВЈ@@Рj,wTd5@ˆ@@ Й 57aиpCЉШ ЌhnHEЭMіA@м@*rЋA@š›@ю kю!б~||ќБCET>ˆ1Р5€јH`ЫioцЃК#y„Ыr—$чч4‹nєА@,L€ђл›,FЄ"?ЃІљ №њy0 '€kEG‡  M 5х%€@* 8r8hJЉЈ),€œRQР‘У!€€@SHEMy` @@ рp3ЗŸ‘/>V^^юgЃ0 џЏЁ@1‚€)HEІ0™TbyhJцs&ѕЁfqљяч|ИЩ зхОBšјЏ2“И "Є"‘†Џ2Ѕџij5;Ч+,8ъцgsј˜Бљ[З …ХЬc&€kE&aK .lG†@sРQ‘п ;lПјнІмрПЛѓ‡яЏ Rы‰’YГВЮ–ŸЕZ`^ђ ьЈйє2BtА €ЃЂА˜FЯAiЬѓNю{МќЪЫ‹ч-“<ф~Иа№@%&%щ/-.ж7†j §ŽЎs№ряМ'‘ЩзџцњЄћ’^˜ЧзњA|ydэ‡П—ŠqъћRфN_'OžьеЅ‹БeMUНЎж“Бд5V8&шTФГх$.‡0?]ш”…‘kmЉk‡^ћsэŽќЯЮœѕюЖwuМoајђоЌЇЦЏе\sz›’…юЇ6Ъ-@РЕ"?a‡™H Ш'шž|ъщТƒ…œћХ‹•§єЋ§йA‰jЫ{яЄш—м+eIЮbё|§ЦМ Љ}эs-Ў­mмQHЗИх  ‘­"ЧŽћЯжgl\З6Еwjr—фЙѓчж:~Mзй–,ZBДjЫж-‰ GT\`Ѓа,RуХsŸ›і\ђƒЩдwJц”ъъњ[јH3џНќў§њ'о_pЦ9p#$ьћ`_џ§“Л$Ž5КтЧ2вakщ“ЋQЃ4fRр.4НTQйъlkз8‡Ÿš’œџо’д>_k}Ёa­)"Ыr*z:}тЋ7q*ЏПљі˜ёc#[йЉЅЄИdї_Жьл[uщък˜Ю–Эя”|jїЖэE ЂьЖмЕЙМЏ…ч9К†7…х’kЋkЗlоxwЧDZмВicЩпOэўЫюЂƒEQQЙkr™ЮкukЋЎV|\А{ЧnОsDЬ4‹ э“џЯф Ѓ'§єhбЂNЗмК|хrоБф›’mяn+-Ігq жtFŽ=ВэmE‹{Їѕ^И`!i–~уL™єщ\њЊ˜IЛаєREЕ1oуЉ8‡џзНEЮ^pc_v€Г Ynж|ВUЮOМ@М%фTDџ„c*<р<0КxЎђ№—‡G<6‚%{ZvДыEТўїГЦ­{vfЯШŠniЯ|*kп'јР-{КŽHшд#iыж-//џ3Мѕ}Evt[EdцдЬ}нЧFAУtЖ7ŒšЭ­АkлЎФЮ‰Ж{e<•yј№aоeцГ3Щ_” f-`СŒ5юЄтњ*f2ЈrЁŠjчž/ЬxСщБUфдЌчYHіЅ1Ѕ‘хZбЕОE\ @Р$рŸзŸ˜>qеъWгњЄ­й7щЩ1”cXшэnŽхТ•ЪГLОђгйk[№УoŒEšœЊ)§ЦyS%кE/.<]іmЛv)ЎQ lдwŽТйхlхйvэ(m8e—PпNXЃK`м…S(--[§ъjКeркПЎ9W7$1К-ёфЪЮ•ТЋО=ВЕ9хШHл5чЏ{ЎЯ›*fвжЙЈяЅŠJ&ug/ћ *Сњл" йLМПўжзЬ6YЌсB@№їхНКЅЌџWзцmјњФз/Э[РвО›e#кФv`э$МЙ™ŽŠИšЭЙзbЛvБKНsrrЗЄYѓГSJЛX_~lШcячП?Ю5ŠЩ™“SК%e ЃШHЯАп`c|їЄюњaЮ]0wеŠUt9jrЦdтІW№ЂeьјŒqcЧ%5ќ˜*fЫЊЈ2&dмzЧ­#G2tHћіэ™/ьИЦ*а"№ЋјўS{NXRUYYuЉbзЄЃЯпЙ#­O_ЗзЩ5^ž›=чї§NKMуэѕ'@јrˆ4ќБугщHЮїxЫ*Яš–ѕСі|7 ^(ќЈ0­уfщЮŽcя{‡ЋПяЦ2жƒ@(-=qКьДя[ћаMe17Ц/оќЃЂ}ћіўјп?Šy(„чЧчащіtЧП”ЬжфЎyЄї#>лƒа\:  gИP'аp(Hу ЃŸёжИ.o)„цpлјЗžZoпЁ§Cjъjњ<д'cТ=њgO}AпšJГГiVЯ„WЈ€@K#фTЄњg U{(LУсУЏcКPDo>L_Lq#М&рLD>ЬІз~бZрŸ kiФ1^  iЂ ѕХјјј-›ЗЄ<м7д‚ј=№gК[лдЋшГкLЉB @ )ЄЂІ<|[bХЄi—ф›єЖ њg-ѓГIyеФ­2sˆ#д љyЦhg„§‘Ÿ™Т€@ИРЕЂpŸaŒ@,OЉШђS„A@ м …ћ c|  `yHE–Ÿ" сNЉ(мgуЫРt~žЂуХЧЪЫЫ§lц@@ €џŸ HEўœ^–‡:&tєЇQиР Їn“У@ў_ R‘?g˜Ž‡(ѕ8ШŸFa @K ..О№@A SЎv†с @@@GЉH‡  %€TXо№   #€TЄC‚Р@* ,oxа@*в!A€€@` –7М€ш щ @@ АŠЫо@@tŠtHа  XHEх o  :HE:$h,ЄЂРђ†7Є"4€€–RQ`yУ€€€ŽR‘ @@KЉ(АМс @@@GЉH‡  %€TXо№   #€TЄC‚Р@* ,oxа@*в!A€€@` –7М€ш щ @@ АŠЫо@@tŠtHа  XHEх o  :СIEхsчЯIэл/ЙWвшє‰‡О(вfЁ†ФЄ$ EƒP@@ ь!]7ћуП~v`1 Г‚ŠжlШ›4)}аСбббЖыl ^zqi}МПи–фЌHэBolПд7гqЩОн{ћ{Ьy5vTiщ‰Т ‡>ёXrЗЄб&Vœ)gz&еHycоз1YЪмE‹kkнїЙМд›-ЃvvHDŸLрšLР'€€€я‚Š=œіp_iшk_Ы­Кt~їЎНє>щ<-rЕ#ХG6oШ+:№Х€ўгГІ<ќYоњМЂЯПж{aЮBдЖl~ЇфћSЛЗm/:PeЗхЎМќ­dл†ЭdЖїУНОДŒЬ–ГO&pG@@ќE ЉЈцЪхш6бвь/и—=-›Ž–шѕТДь§ŸpЕ™ЯgЗki1|ФЕ]O~Sъ‘кж=;ГgdQ d-ѓЉЌ}Ÿрн<_п>nдˆ“o4Ы˜€ДЄ‚E№…@„/НыеІmѕ•ji6:[yЙнЭБЬ, W*Яr”œ˜LљƒqёZзjвЎRЛђгйkь#0ˆlешE4лЈ @@Рп„нАПMЋьѕHюQјYС№a#є bлвM ,‘а&Ж­^Чї–6Б ом,Э…О‡O с]VЦфM›6юлЗЗічjК1Ёь‡2КБ›Х=Ая œе9еЎзЂе9ДшщxЬш9lёВE”ъH™ny ;Œ{Еms}ХЙњ;#˜Іx ƒq_ЌpK GEtа“їкыtнЪџ{EMЭЕЛ;&Nœ0‘:ѕЉŒ%+sћL‹ƒћ ІEЗ№Baь˜qдk|цd:SwћwLLЦиHњјŒcЧб*\"2…Е  р_ХїŸкsТ’ЊЪЪЊKЛ&%xg…їЪпЙ#­O_~!‡ЗЗ†п1ЁcŸЭr0зBb˜ A'PVZZx@~…ХFџQsКьДє:‹GСнTscмљтНA8AчQ P{HEa?Х €XR‘еgё€@и@* ћ)ЦA@РъŠЌ>Cˆ@ТžRQиO1 V'€TdѕB|  іŠТ~Š1@А:Є"ЋЯтА'€TіSŒ‚€€е Y}†€„=ЄЂАŸb @ЌNЉШъ3„ј@@ ь …§c€  `uHEVŸ!Ф aOЉ(ьЇЋ@*Вњ !>{HEa?Х €XR‘еgё€@и@* ћ)ЦA@РъŠЌ>Cˆ@ТžRQиO1 V'€TdѕB|  іŠТ~Š1@А:Є"ЋЯтА'€TіSŒ‚€€е Y}†€„=ЄЂАŸb @ЌN Тъ†T|ёёёЇЫNЧХХ‡Tд@š(НI EnŸ+“ џmѕ‹mэК\Š-ЕoJў{;˜>Y~nіœфо)№”гљqYиЗooџa%wK=abХ™2б~Н,3HЋЄ=vє‹cЩK‹)Њд§ЖМїŽ8"ct’8mЖшшшЯf}qј §ZU`.д<€z\ЮюЮ)Д›œтуХЧFET‰-bёH›„*›wЦ„>E8дKк.R6†)5%эBšћvЛ6˜^I4@К Rјqса'јіSЮ†Cj4›4Ї4Г„‘oР|Авщ0ЗCыХ§№Эл$Mўхеє’FыŒAёеЂsъЛ^уЮ6йМ3eўIНЬ—†*ѕЈпK/=@"`ЙTДeѓ;%пŸкНm{б‚(Л-wm.ŸЇ’ПŸкііцвЏœЇѕ 䘢гщ_нИ‰ї}§ЭЗЧŒйЪОіЕмЊKчщ7>НЯ_:O‹\Ч­Аё­ Їўq†bћыЎ‚ —.0§ЩгГ&ŒuДА шу‚NЗмК|эnчШпJЖmи\єљНюН№ЅeМ RƒДVкбSGk_лPѕoGСОНЛџВНф›SмЉ[t\S'DъZœ ЊРжnмPuщ* рHёоWеN fІxЦœљO?ѕЬбУХ›зч}sђ{fVкШ=’ wvŠі‰ЪвvщЄИ…Љ7eа…(mоWtр‹§ІgM=xјГМѕyД§ HыН0g!АЄИ„ц”Р^‚Щл™ Таd‹њс{d“ЯЌІ—4Zђ(§j cAjŒSЃtо™Вјi†М4TНGiффKP rpR§”аМљLlнГ3{FVt›шШH{цSYћ>9РWЭЬЬЂпцlб@)PЅ†{TсчбХs•‡П<<тБ$я/и—=-›ьаы…iйћ >aњf>wюйџТŒlgl­ьSЇdВ.ЛЖlKь|Џэ:;5fЄgўќ07ЕрљњŒ5тфпKy;Єi­ДЃЇŽhhйгВ\ЮЮЬтNнЂуšЂ@G{+ўММgrOБ‘ЩЊРіИ_DЭ;ЊкIСЬGEEU^ІpЊлЕ‹—=ƒ™•6r$ј2яЬŽtRМ€iаeцѓйэкФв–?bјˆkџК&.žќІqћсTI ˜т0IVM‡FЭ &[”_Ѓi`SœYБ—*ZщWУРОhS”MЮЛˆZE^ЊшŽdiфдn ЦT‹Z NН"іSBЭŽsЉхЪOg>:Ќq• хоn Цu&ІO\ЕњеД>ik6фMzr }УiейЪЫэnŽe:$\Љ<Ыѕн g+ЯђО\ЙєTнtВь$mСЮF!рШVѕ“ыkuМGЃ 5HЋЅ=uф4оЎqЄмЋt\™65ms}=ЬЪW1Y˜8:‘›ЊЌ™™т5+—чНёжкukc~5}Цœ^нœ7HХP}™wfG:)žТ$S]шwCН/зЖ*.Šл‡)н€Uг!в0CЃY’ЛйиІ8ГЂ}UДтFТѕ аq`rоEдdA\ффUЁъmzJ—ЎtTD’zHŽИВFш+1Јбс‹ž:rŽєb%ЫF6ЗcW&AџЛA\KВ*0qtbЊvYUœ w&МВl))гѕЁ цєс_I–6ŠUѓ.ъx!Ћ‚40хE5О’@ж4kUгЁQѓ= AZєТІ*Zq#сŽМАяЧyW…ЪУc‚4rѕ‚s‚No3rитe‹иžЋтL9нЙРW‰‚IЕ‰щЯфmШ›2qПKj`пA9ЋsœчwЊЋ­ЮЁEfіі{пйЖƒrIѕ•ъхŠћФ†=:pбŠR лшЪ$ыXSScЗл"эvкя/~yЙЄ[YjPеЫSGЎ‘Ўq Д:'Зё –ItЊ0єэЊРі}„ќжАКёж;UЛЦВ*Nк$**Ъ—ыыl5 ЧšвFб jоEQnлцњŠsѕw ˆэYЄЈІ1eІ‹и]/‹TЈQPM‡пУ ПОлTE+§j˜AЇ ЩгyзРUЁjtОЮ1!алT„“4зtјьћДn›AC0 `У&}јn6с|‚Ўй С0€€€? X7Љn^RЕћ“ŠlЕaњ‘Дˆ…V%+ѓу``*ДFZб`їh•uS‘GУ€2X*ёXaC(@* ХY ‡˜ƒћгЯ­wЗ в9hжJ™0tиcЮgљИ^TЄ‡ дBэNYQr†њj6жБь‡2њХJЋиЂё'б‡ЭЂЂO&0 њQP;)№4Н Жsi=Љ§&СЫJјЈМP0њq5БцZъшmжў\MeКœхО^ЮVLё­iPtў5љE№Т‹ШŸщ#Уp+гџцГЂ\Ц‘а–yИш№иQуTUa('EЕыS9pЕ›‰–ž=хщ)НzІаг5]OВЏЇЁсрЌ B*’–§ бЋЪиЈкЉ /‚BВЊ–‰Д’Дб# fІЫ#/УфО ŠЏWCёcѕ&‘9Œ вЄTйЩьЧѕэ‘вуDЩ шљ~ѓ–ПHO$љXЩ j'С`дњ`ŽuьOS2чЬžnў.v}иš№(щ(Ј^<M/еv.­gc`ŸyЁOiG•вз‹›т‚TGo“ž*=Ј_ŸћГћŽі 8ˆl&r“_яМpў4(}ф|ЄІgQ.ƒHh-§Уј3OOсЕд[6C мЬw_яХет&кУG_Н|Њ†:+‘ЮŸ#ў˜P ZsR‘Њь‡ЊŒЊ˜‰EPTЕLЄ•lЄY03cy1&їeP|ХИŠЋ7‰Ьy`LЦ Ђ*іMN~шШ7%дВЗpOTDTaЁѓРЈф›#дN‚СЈ5СфяоЛ`йќззхвCйEћЦВ4lMƒQhbр­ЎRљ IDATUлЙДž}nPкQх…z™—TGjsфˆ‘[пнЩƒйњўNjЁE3‘›џ"xсEф/œЧьV +@М(—*’у%ЧЊЊЊЈєŒ5ƒ0ЄРЭ|їѕюЬD{љЪхџ:{сƒл‹>оeЗ/^щйѓšѕN›Џ%џтЊ*ћ!V(сYhфЊvZ%ж’Pе2‘VВ‘6zdСЬ”xфХ`˜м—AёЗеPќUНIdЮc‚4UБoзЮї.uе}јpяў‹_\џж›єлЏПўnС,чљƒQk‚йњіІaЇ‚ЂqЗВ4lM/ƒQhbрЭlч\йР>зЗоЈђB fЦ%е‘кŒ‹‹П+сЖТƒEiЉ)… ИїVФLфцП^xљK#чЌ vrU,ЪЅŠdѕ+ЋfgЯ10EЋ ТgV쾊̘ЖэѕзߘšIЏdŠЮ=І ќ’ЭЂчш‚ŠTe?Ф:ЌH› UЛfžTЕLЄ•lЄYНЋjyфХЬ0})ОтїъM"YEUьB'Вo‹ЛщаС"Л=ЊKЗЎы7Ў?єUЕАђQцG§ж†Э2Цлoh=і _Ÿв(†GВ™QhʘйЮy3іХ-„wTyс ^*›ЃžЕ~у›”ŠўВэнYйГ™e3‘{єE№к ХЃŠм-vrUЃ&ЄєћŒžј$зЄЌ яыiтЬŠЛ>юE#ш=’‚4клюжєЕьbNаЉЪ~ЈЪиЈк5LUЕLЄ•lЄYНЋjyфХЬ0},ОтпъM"YEUSхЅ{Я—Ў^5`№25 џ€ЅЫVQ 3k~дє™ВбЮїwnйњ‰§„ф‹&MxЊQXSmчвz6fьK;ЊМцv•Ъ&цuќЛŠЮ‚FEХ$мZшi&rО^{ЁqЉ"w;dЉ‚4JќMНЄYСг0Ь|їЅŠвhьёkЯDІїŠ?ЏЁgQŠ],%!ЉЪ~ЈЪиЈк5UЕLЄ•lЄYНЋjyфХЬ0},ОтпъM"YEUSW&Ѕk2wOKэKІЈЮЩ)]ыЏїx4jg6z=oчGћщrКATnWiТSТРŽj;—жГ1c_кQхХ 0ЗЋ lŽ5fбВEЦŒтFЬDюб,{ч…:DЮіHаGbІЛЇa˜љю›ёЋvаягкЗoMЯDNљ}п‡cСѓ3Эи ŠN˜з+ SЫ:Eѕ&ЫN а"€zEЁ5_Š–ўƒЄ…WoВаd І‚pлBгАtНе›>@М"€TфЖPы$НИjƒ@М aK З-„-K @@Р+жMEЊ{pUэ^ @@‚OРКЉ(јl€€@@ 3œ€€Ј Љй` €€@@!ЉŠy( і(ŠyаE#^*†Б’V|‘жJ‘6’ѓ2;p -‚@R‘Њ˜‡Њh‡ЊцG,UЂЊ›"­•"mєШB‹и:0H Є"U1UбU;ёK•ЈъІHkЅH=Вйh‚№/ЎЊbЊЂЊvšБT‰ЊnŠДVŠДб# -bыР A@ ‚ŠTХЊК)вZ)вF,hМc@@РkA8AЇ*цЁ*кЁjзŒYU7EZ+Eкш‘ђŽЖеLA@Р;A8*bХ<žљi:юLzrЬžН{XшTДcЩЫ‹ћѕыЈєёщŸЗkLuSЈe|цd:ЯvћwP™8ІРjЅœ+џ5ЎXњЂAЃG4оБ  р5д+ђ:‚€@ %€zE-tт1lcAИVЦ414/ y ]@@ќIЉШŸ4a @@Р HE^@C@*ђ'M蹂R‘аа@@РŸŠќIЖ@@М €Tф4t№' <ј‡Ъж•——ћsА  р?ёёё]’КњЯž{KNE,uLшш>4h€€ƒРщВгф6й(аЉˆŽ‡œy(Т~єыЃц '?ьЈs|{т[ѓ] i’Р}їоGš`k—Gj`ы.”Сж#\)лД>} „s*bD(=џЬTJHІе9VОК–4=шbЪ.”l6АmО­lСЖљ4Ÿeзv›п|Є–}TдD„tеRхЙЪњ•ІЛЈaM`л‡_РжЏ8›л&8ќКаШжЏfнУtnA@@ y 5/_XpKЉШ-"(€€4/р]+Ђq§тљиМштЙЗ=юќн?|џƒ^MеЎзДb‹5и†L gЊ%Б Ь 6zлF!,сЈ(„'Ёƒ€@x@*вЮу–­[юМчNњдЎРВчшрcЪгS4§ЈQгЂYtЋ бЧЂ1тЉwСZN€ЃЛЏы}“žžTёc_СŠД0ЗОНiйМe[поЊ]eЏФДЖчoЫїЊ+:љ‡Lfo2'ЪўБоЌ0hG?=к=ЉћГ3Ÿm#Тƒ›ŠшџŠЬМE.fєНз9tфPTLЬ№Qƒbўwдё#‡УЋsЬ[4яОЮї=œвmЫжЎ€\^эєKŠŽЋ~фa:РbFжЎ[й-ЅYxnіsG5k$я_ч;юї№оhэД)mdЋšсГЙйкцЭ]АiлІŠŠ2!xrZ?Gz,„ŽVГŸЂLфќќ-§ћ=L з‰ву{їхїшфіј№Ч+~ЌЗ\љSХ”iSшЇ+Až’9ЉКšўЭ€g} ee'hšђЗбAp}Hўš›­;G=iтшџПН{ŽЊК?>ї_ЛJ{Ѓа•ќe%> дbT4!>€R (>J@фЁ( "ЄЪ3Мф% ˆ‚\‚”—B H!(˜`•`Ы ђGZР‘k е–”b“UФxЋ$kХЕўПЩIN†™9““ь=3ѓ•ійgяпйћГѓ›33™)9PdNГВВтg?П­цпеž“vы&у,•Г]ўќйlуПLцЎТiлpЊ$~п5іб‘Ÿ~ъ6ІаФцЙ*Ж‹—ЬН­ћMђ#йЌЎЎyYггЛ&рБЬ–К оЖс+G4еЩ_ћлјёжАг^ЁЭŽэ;6\FѕpЮ№-лw˜УЫ_›ё_Kьпѓжо#ёŒЈў(VѕВџјЧЧїьмqц„[ZnZПщ“?йЛkябCЅmЎhѓтKkŒюЙyг'?9хфїŽWЗž–џъ.љэ)4Ж?rјШ–WЗ=tьоўƒG{№ПlйАО~ѓо™ѓЭ&L?zјш“ЅG,НцъkV,{СЈˆь™wыаЁCŒ}bбГГsrrŽЅpђјF№ЃёІ1ЌJ(NыЩ'&ЌЬХэЦ_mѓШXY&йyфиёїок+чЙœэrnm.“й=2…FWЯП* vњ6ЂІКvгцM]ЛfШ-MФаЦЙњтъќЯџyёНпю—ŸЯЯ}žП:?ЉmТРЛюоeNЇЈpWЮ§e],eg№­hуmЦr$SQгƒЎ iн[Уf—ж5Ћ8_ѕЧ“ь{Я@щ.ПЅ,5FЈнoяЫ›ž—”$?yГцЫ‚зKƒЯЬЦFГmoю~zz^Rћ$WbBю3ЙХяѕmОлцьП*+ЋЋ“R’ЇЭ™ЄвиЅ§wЈm ЈєnЗм~Gўц|cќІž‹йРl?cюlдD–CЮ[АtУк Y=z-ѕў–C˜7Н‘[MЦ#}3ВВЎJlSt DЪr†П_zxар!R–[гI>=OЮyу@VЫdьШяњС6ќ ѕф0oШŸŒьЬm; –-YŽhe"эœЋћоЙьўdї;ъЁнМ}[M]§}KkѓЮmC‡=фX!šИЗm8Ы}3w8'jуX;wэМPu!уц ГэЮЗvNš8I6ЯUžKюlд''7‚дЫ.OтiМ}ёsюаИхr5ЊЏ~yѕњ ыѓџ+џЊД™2kvЯ=ЅMРЪІОЮ,M?iјшсйwќ4#Ѓ‰зŠХŠII ˜ ѕоН7П‘Ч}ѕ7ЗлНъПV:uJr•Ї"(ВьпікцСП~}z}яјњѕи“VЎXйЗOпеыV7ЦPя“ќ‹ЪsЧeŠUDw§•zељЊ…ѓgž>s:9%9ˆ‰їЩ) о›цЙъsbPЇІІў$§к’ƒ%В.ђћ–[n‘I„ ЧŠ%№ЦџЏБ4ЇжЭЅЮUИЗ№§їп7–_bШ™7tфPЙ•;ЕŽ)eгјZUUeСЊоl`кЅtмП}‡wr2ъх~№ЅU/IЙьHйМ9гћЛƒRXiДw№я+\Ы–.{zЪг; v˜ГАb1ДЈ0cкŒ)гЇєКНWBл„кЏk3Г3юVž[~НcєуЃПхШ#[t h,zжхЏ“ЇрўєЇ?-™ПФœ‘їI.Ћcды]&ѓXŽ+ШџЅЫV rџžwоS4ёЙп0Љ‡ Нnэ:IEoМ1sіЬИђфtцГЂЭМЯйV<ѕiЏKЩЛХЗоtkrћds0rѕskзЎ%я–H\г,_БМњBЕќ,~ЙgDѕa­ъЭFГCG,ZАЈЊЂJЎН+Ъ+цЬšcдKСѓоPЙвўжuЉ1fРJЃНўпž6оьAЕl Л1lj‡дCFЌXОТsМњJ+–іэОчaiьhЖoЈiьюГyщвЅФ+О“ їЇ‹/2{іЌИКeУ–н;wl-h:–yPѕ‚g7ѕhZ"Шpу<6іБѕыжOWџV{Ѓвхj:ЩW,ї\Чзз[-“*…FWЯП3 UСыr‰sKі%Х%–&^=уБиєОпXјќB“:Ћ[VЭП/ўІАM›6щзІ3В8$yhф№‘Q9КhTс›…9ПШБ9š‚эвR>o[›bі›™ЖіЛшj™TфНф!{зFgЯЫзqrCР‘’‡† R§Е|;'7KyкУ>‘|&Є|HБ|~Ж– ­нaкЖ6@ыћE.е‹WыNO@XрЭмБВ’Ь8руBЗа‘ГфUQш<‰Œ@4 дШїQq & ї€­$Т6˜ЋƒіqUф ХbЈ €@l DєЊЈ•ƒbs%˜UЬ DюI˜%5'†­Iс№BDS‘Уэ>vьНYдnДиkWWkѓ§ДѕSПќгeБеy>\nЋ3r3БœšŠ’““™UUU™S”яœ;{nб{EmлШWіNЬmјюjљћƒѕыV№С1љ:№?я3wўтЄvIf/Г№вŠ—6mо$›ђ•сђ—fНYА'риЬ Q^АšЃ9)cќ&ЛUНї4SЦмь9р=/ћх–§EЗ§ИБвRюџZMдъŽБ‚#ѓˆ–зŠ:џИГёcгUю Э{CГЫмysOўёф‡‡?ќлпў&7gьZПn§ј'ž–ЏП§АєУФ+Џœ˜;Цьb wљрwKЪ w6є5HСNiplоqЂЙdŽЦМќggUoNг)1эœцЄь|ю+3nШ0њJСјщн+{ЮЌ9ђ@Њй˜вІџн§ЭЭЖЭ^OЪљиjŸЏЙFйwdOœ0БЂЂBћ!Ђ+ —m˜йЋЂІщЬŸн2ѓЮ?–џЅM•-Е(кW$yH>gE:JZѓјуOИ ЖЁфВIў8Ю?ђŽпМ‘7kAJrŠь’ТђЫs†њўљЗ8ў‘UŠ9:%Іs@яjК?іœі’`жМјТЂХ‹фš,xќПк8bј99ƒ7‹эНa~ ЩXЃкЏkwюš9cцілc˜7ЬЖо’Н*’ ьѓ#CѓЉQШвЇNђžЊQ–'‹2oЫєЏ—Ц7fмhдK!`_я^VqМл8Нь3ЧыoИўъДф;zнБі•ЕоSГЊїnc–Ѓ9fKЯsRЭМЯjiml6’к&MŸ6яƒУдVзіОЋЗќ6џxзT|VqИє№Ш‡Fzч0Ъ-š‘gў^ЗN_ŽS_ХŠќЇŸКЭMkѓeЅВГ<—Г’ЅŒJЙ„*.,ь? vVЦ№œнЧн%ХХоџ`іЭУ‡ Џ(ЏhXЕзт%‹{п‘-?RЧооЋlДёЎ xЌ†PкчюхцbDS‘юЙК{атЅ‹х1ІмЄpщЋ >G(џЄ|омy+WЌєЉ—Э _}“а6СЈ—ТПОо]‚ФёnцшВЯхYИO>ўфogЋЖlоrфППфЙ%ЦьЌъЮ=ЪcЖш8AХJ9ёо=pзž]f)ч hœ™ЋW­~*ї)WdŸШ0GЪBЦЭў?Ё<`ѓБ%пlлдЕ‹чЩе‚­›ŽќЩо7і–,•—ЅзфЏ1ћ9zdыЦ­Ѕнл№и‰c>"ЯN—>voп{,]`4Ы_ŸёŸїэ—ŸЯџљЙlYї Ч2…HІ"y&ЮчGL}jZєlЄŸ‹_^”O8џYялЎюxuЛ”Žо‹TvЌlє#УжoXŸššъ]o”лџчї<nъoRhџŸэ§л5СуXѕrV}9ІwN_ЛnГљœ›9/ЋzГAєЧД˜“вRGN+^^б#Л‡D:dшЖл<yхVч’ђа‡‘bYYйХ‹ŸїэгЗ~GŒџrŸ№єY ŸНz7+99eщТeK-Љ§КFžnљ`џћЦкy~и8ТЦЦ Жиь˜вОЊЂвh#Ў]J{Ѓpн-Ѕwšf4л0n:ѕЊШМ›3 ђŠ… eggЫ[]Пјп/фЙŽ-По‘zMУqГfЮ’Н™йMяVјћпџ.боЮђ2•gЯіюе[*хяŠќп>'ѕvтHГ€c“zGмЌцxџНїO˜8сгнэ~дq№/O›2ݘŽUНїdгЮ9р=/Лхo37v№<ЎП™…Ц ЯП7fvПјђЪТНEmк\•vMКбцX§§Вб,33S6іѕŽуЌrРщ4?M?[эГ6–и.щ'ЗоZTR2xшрйЯ/Ь›œ—в!хь_ЯЪs-ѓцЯ3Žk6Вљѓ~ЎZ>ю|i#й4z\ї Чв>гШŒh*’Tмx3žЉ-уo&š}jиШ=Нў•ЗnќЎ€>оЛІЮš#?>1eгlc‚Дёnяп,њkЌцичю>ђу?~ЋzoЇФ”1[ўiЭˆa#.^јJў+!= С[*№Р§ЌЫ_їк–зЄујмёђьY‡NžћT‹тŒ{rмšз zpє’wZЩІйннGЅr,3rє"šŠМxšЭ=^m)"р`ѓњЦ,јOfаРAђу_oдщhе%Жъ[єf&ЅЉћPwЯьо}Kw‰(ТHоб}[m&~'Q^JяОF9рК<–_M5сГѕpДЄ"ŸaБ‰@L Dюе`g0Ъ$­&juGgаФЫ(cъm ёВhЬx№zb?žB2їШйFіЊШчEОи(ˆиѓQ0w;CЛD~эќ*ь6"HйTƒ:bO r6cйjЂVwt M\ 4ЂЉˆs(.Ю1&YС›ŽаŸжaыˆn~‘LE<=зќњаˆоЖ‹Ьˆ%žM нjFЮ6’WEЁѓ$2Q"vmZQq‰|Do”Œ':‡QS[c~qГ#<љбIQ•fи6kевІmK;ЊЗX*ЊМPYѓЕ­ч‡лЪ' rCР‘={є”qЫџpGŽ>\ƒNiŸbŸH2Ј–}X†­іѕ1mЕGn6`dR‘сЩ)GЙЗnмzтд‰ •ЦЎЫ4и@РЄ".CЖЈЊЊњуЉ?ь3Pšєэ3PЪRc4пїЮОМЩyIѕЗљгч›1ЌъЭRxkЧ[н2\WИк&Œ{2ї№сУ­Ž9у™2ЃћЖ7wЫ ZIэ“r'хПзpдцЛm*/TЪЕWrrђмМЙFу€•Ц.~#рtоЖрєdќ"аєеЮ]ПОPu!#Гсщ/йЗsзЮIЧIс\хЙф’<““dр)[еЫ.ѓцv—ЏzeеЉSЇОљъOЅчџMАОAb&ЕO4ќХ?Ю Иo€y3ьъ—_XПa‹\Z]ѕƒ6SfЭюy[wiАВЉ/%œ,@*rђъ1vC@žg3nпК wПџЮОффЃЂЊЊrшШG&чњŽЋcJЧЊŠЪфž]Uч+= ъ;ZеŒп3fޘ2yJЏeнк&жжжdой#xп`1ЭбК\эR:юmkRЛ†‹$sHщзЄПєќRй”Ÿ7яйпОѓž”VУуѓ&јЧБw|Џл2ѓžЭы§гоF}яŸо.Џ!ЩсVцЏ|nщsA*]ќFРщџ‘жRб‹/VV^ќWХ[cвчSИ{Wп>§ЬWeЃбрrО|tlѕПпZМu я§жUДgWЮр!1™;Р'NДJ’NDH€'ш"Яaа(рѕVQ …@иHEaЃц@„J ДpЊQ&ž kВ фXюŠЛt zR'‚гjфЯм@Рб:wѓ<;ЗЮ…ЋЂи8Iœ< Яѕ~M4O ѓ3Юќй­s„Q?e“5bEг”ѕ/h@Џњ)Ÿ9~4fNяЮ…T№$Ђ2МžџДб}kЭkƒMЉ5ƒХ‹Ž}ašrч2Ю|ьСAГ єНрбЬ”;geŸ)“lн7{gcу\‚NЙЕ%ЕVŽ~šф‚(DзD7d˜clпю{ЗfїШ›œ—м!йЌД_hЭ­џ{ЗhЪ›6oJћQZп{њzV*ЧŽы]cЇмК^v"7Дб4eŸ#zЏЃьrь–Ÿр+вlƒрн}lГЙ)ЛЫŽк?VEEХњ5Ћ§уЅKЎы’1aь„žН{;КІ}6Gи0ы)Ћ ‡зŠTєшaъъъТп6мjЦн–ќо[ДџњNз?3уЋ–б\eв•UU>#LINёЉБГiеЋxOqљ'хЕ5!yРkg`Сл˜ы(…р-ЃmoFVЖЭ!UЏ?њ‘ляМ}oбоЃGм ц,xїН=6ћ†Ї™§ЙДb<ЄЂV б%вuЎCM<ѕўA§ўќчу“ЇNnv@IIIrёщщO–ђп^Кgп‘•=1wЂЄД†uЎќељНяънЛWvсo |Т–——їПЛП$?Ÿњ€›ядх’ш*ЕzNЩ]VVА­ `k˜mЪŽ’ЁšЃ’ВдШ%‘д,y~‰Q0ї…юнЛWYНkїЎCJфБЙЯ^››Їќˆцu’$‰іа?;+C‘T|ж0kГAй‘Вс9Ъ^i#-ЭА{™{эšВ\IиŒЖzнъ1у' | GЮUзЎєыг—<яљРЙYЎVг—г рiМi­чм–s~ЮГsZёАӘKГS6ЦмвпЄЂ–Šб>rЩoяЇм]ўтђхПгŽпьИччїМїлвЙs–duЫ м]FкЖњBЕмgомеЈџЫёЃ‡>њЛЃЅJЏПњš^|СЈпД~г'љdя{п+*§чЙ6tЏSіСЁ'ž|bіЌй9ƒsЬАС С,‚бЦхJHHшy{п’w‹]‰MCЊ•ћИћŸО;bЌdжФЖ‰nw™ДЩЪъyіГГrџ%+>ЋTдЗї iSІI9ГцШчкшђ$''їьйsв“КdмtКќДф6ЙЏЎЌіiжЬІЎ)_>6OTЋ—ыШб#;^нQz№и]}яZ0oACЫЦ.гчLŸ№ф”Ѓ‡м[7n=qъ„Й7p/ŸЃийlnЪž+ ;qъ\‡юлЛoРЦVЇЋ<рDžЦ›7џиsn—,msE›5Ћз˜ъ_й0—рSnэ^^+j­§"!0јсСг:ЪџЂŒŒІз‚ $уцІfэлЕџѕ–_пкё–QHИ"aм“ЙwКлим§іnЙЯJjŸ$›“žімwЗТ=…›7nоАvCzчєЦКАў+CњП?Jћш“фСВч>Ђё&iCRЃ<ŽЎўЂ:+#ЋpoAЯ}kЊkфN­АИАЫu]< ЪIh›PљEЅбЉђ|CЁ1FУП5ѕЗд”дєдє/ЋП,м[xђNN?IЊ}Z†г{н'.{ŽnоЬy2;вЈaЃ6ЎYэ3Ж6пmSyЁRЎz%зЮЭ›kю оЫlІ^pБ{Utщ‹ žыЁ@7ЋгUкœHРгxл›ЛзЏYoœлЙ“rяrџДЉMgx УњжйŸ‹oOлЄ"H4 Й€н‹ўнolћНЙOчvэzэ~быg=ƒŒЮ}т˜БЗіыšз w-_Б`эšuRуv—ЏzeеЉSЇОљъOЯџЯЮUžKN–Лпёl{mѓрћЄwNѓпхщоš›я!š‹Q›‘‘^ќnIZ‡”„Жц”kkў§хІ­›Мћzю—ЋkeF’‡ŽўщhПžНRкЅTKЊ3hМће—ы\хŸ•Ÿ./ЏЌўВЫЕ]rВr’к%еœo|івЏy +Ќл\ sыqЂ%Д•:O9!Сѕ'I›GёVПќТњ [ђзц_ѕƒ6SfЭюy[wЉ”›u/cПЎпЕЗїr)ЕЎMЛіееUFЊ№iouКJГ€ xёsюѓ|’iУ­ёœЏп4бїњзў\ѕnІŽTд ЛУ!рѕ0?јсфЂdкггЇMš~шPщž}{–М№\ŸŸіЙћоВКнИccdЩXc‡ЪўеFу’bЦЬS&OщЕЌЛм­зжжdойУЈя˜вБъ|erпwlйИuєИGПхШ‡†>m№h˜ПР5ѕэћооНфї‡rlhSчJќ~тЄЧ'—Mы\rpњNщ_ЩЁвдTЩ ^З@‡ЎЊЊ<§™|Rый”ЅtПБЛчкЋmBэзЕеU’УМњ/ъВїБќЧ`ж˜ЃНЙY_HП&§Ѕч—Ъљ@єyѓž§э;я5D5›љєjиmћŸцІь>dљ"ŸЯ1юЬОГфРўœСN0Ћге!аDžЦэR:юmЋ<Жh:Ўйз,4э Pj˜K№)шgЋŠзŠl1б(„пzЧЖьч;ЎюН{-]БrчЎЂЋ;]Пjѕв€нeЬf}ѕз5›vМ~нuз5—.]’—]\‰‰U•‹–Н`Ж”‡ W,ЏњЂZкПИvбXі&ЖKZПqыю7woкіК3x!˜XKІlФiIлЄє.щ‡Ž—™•]вЛэ+Њ8#o5ЈpЛнл ЄPћ­K2PЏ>§вoШшеГWёз !ёŠDy/рАџ№‡?ЄЄЄШ;;F™–‘^][SqОТѓдVMmРі+uMй'И„ЕЊёйenš…9 •Wœš:зЅК†8ц^#ЌЯІЯБ‚oJ_Ы[§*gєь<‚ЙwќИё›7o*,.ЊњКZь>S>ѕййЦ^ЋгUmv—‚Й№4фЁ!ђcuФЬЬLcзїўѓ{™Зf.XКРиœ3oЮЪ+ЇќcŠ<~ѓјˆЗ‹о6ъЧЗцWk†*›cЧ5*пђpr§†ѕу'Ž—ЧЁЃхН+œхДkвJ?hzТ'§њЯўѕlQIQMѕ—‰IWvПЅЛd”ЂНE7vэ’q}†М>$УNП.НьxйнnМщ']фН5u5ЃќОњЌяРAЉRхK ф•ЄкІЇђТ9ГЋїOoЯ›žї—ГщдЉгsKŸ Щ1‚=&WEіn)RVџjУњыѓџkХЅKпШп=6њ1ЃЋещj8рil,њјмёђL]‡Nžћ”UwЋzћsБŠЄў?вњOъ1zёХЪЪ‹џЊxkL3/ЩюоеЗO?Ћз悆]3jфЃcЋџ­ыеˆ€‰PхЗЎЂ=ЛќŸoiХ”SSSхZЧ{’oфmufЅќ—LjыyАЄЩъЏЊХ3Ѕ}ŠЄѓMъВ_.‰ф*ЧгВўЕqГЏwXеВО)ЋŽ$l§-Іќxю„эЏm—…Шьй+Єїрa›ЈЈa.пК&<3сењз\ƒнэўЈў=5–Оn.Пъ‡ЉŸ+тЊ(&ЛТ%šgŸУ5zЋу}уYKІ\ёзЫђЯч]pђД›ќxЃR^уёКyИ< ќ[zЕR/j›ВњPТЁ™);X3ŸЬн8— Sn­;ЉЈЕrє‹nЬь†Їцќ‡yьhУлъќwщЌБїRp№#ООуѕ фэЫAіF`—Ž)ћ лУД|>уАкlnЪ™Н{yюС›ЛљOгь=ѓm˜KsS6GоЂЉЈE\4vŒ@Фџkyш(Щ&ѕšд шўLA‡z—–)ћ 2тыш3ŸЭfЇl'IЬ(ŸІ1kc.ЭNй‡Шц&ЉШ&ЭB*Ђг;ЄcV nwЪmњХCFКЛн)Gzœ_“йЛпБƒћ5FŒ`ЈЮ…TС•ха†@Мб6ЮnL9мГЪи3ЇwHчђтсŒ`Ž €@Dzєщ'ЧЅп!bфЭм!‚%Ќ-њw6ЌМpйЛПlѕŒўFuЎ’w‹,оЬЭ”Ѓ§ьаb•ыпЬ§jЌžи“gNцЭміЮZ9D --MОн зЯ<cьVњћ§2;џI1eчжX­ђ]Зн1ќБЧ—-\цмЉY|цќ™2;ЋН­ЎчЕЂVгбQƒ@VІчу)хџГ†XQBRŽ1;Ÿq1eGoZ­ђШњЯГ{mGЯ.рр%Г ИЗе•ЄЂVгбQ€м5МЫж=*Ѓ0хЈ\Эƒ’ћыPмekeд„уm QГ ˆWRQМЎ<ѓFЂF€T5KС@@x ХыЪ3o@ jHEQГ ˆWRQМЎ<ѓFЂF€T5KС@@x ХыЪ3o@ jHEQГ ˆWRQМЎ<ѓFЂF€T5KС@@x ХыЪ3o@ jHEQГ ˆWRQМЎ<ѓFЂF€T5KС@@xhйїЩїD•ип%НKМr1o@цN—Ÿ–|б|ЛЦ-KEЦWœЩ1Лѓ/ €ОVпoылЎqЛeЉHzХсP6Zё/ €@Hx­($ЌEА/@*ВoEK@ŠBТJP@ћЄ"ћVДD‰Љ($ЌEА/@*ВoEK@ŠBТJP@ћЄ"ћVДD‰Љ($ЌEА/@*ВoEK@4}№ЯU?L}psyHBP@ќ$яuMЉHЖЭZПіT € *†TєљБЂPИ €јџЋPШЯduИЗIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/11.png0000644000175000017500000051305011733011756026232 0ustar sylvestresylvestre‰PNG  IHDRТшк/яРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь}`œХЕѕY­zoVБ$ЫrяŒmŒщН0 =Єђ Є‡—Мф%BкЫO„І…аL7`\їюMЖdIVoЋњŸ3пŽМZVЖфnјЦ^эWfюЬм™Нgю;3Моо7Г№АфўЯAЉ„zЛAЉ•qКъ9нЅбlм(G!lлЋŸЈ­Л mЭ|ЯШmŒдU_щ*mwžвlc‚РћЯЅWA›јiсgo…ў\Т§{ ВшЃЌє Мч-ФУ "ЈJеOяКЏB%я"йС{Ьrк™yл3ЁgХR}ѕБђMз~~„їŒ’ћhт€~_1ќ„ёиПyƒ9фup3и?сЁо&Ћ kI+]xЉўЁx­Ђyд;m\^š И -§}bš"Œ;Ce=ФзfЁoUQU t-ž”ьED•Аџњї’ЪЄ2БРДБ­ эЅœ‡Њ|Жю!Ко1 „a_rEV}:’§Юt­ŸУўЅЗнRз"hяišxњј Œp­ц E# Š{y”sРДЗЪШ р=њц­Чќх>дНСџ’O<ь•њ+Љыi—дщˆхя-ў'JлУ@R*GGМюxh/$љ„6в!ъ‘"яџшЫ(UХ&>г“ЛЙбƒ§э$ц1дТxхpкRг}G№чiŸОй›ŽH‡цТfc№Ў5oe›ЗЗјлŸyR@и8‡І]PeІj‡рМ›Ќ‹”GлуvўЬ<lВ:Іgmх;|хб˜0xЌН_ЙЋWˆ—vPП7Оюkd+ZBeK‹—n89 v 9ЋM;њ/МQМа№Zq[l'В€ЯТmЂŽ„|xAйu”‰4У rЎ A\УХƒ”ъ†Д§MшНЊЌžщл†Рkћь€ПETL ЊЊЉє9bб ЈMэУ‚˜О Ж8‚a/нрBŽ~Т‚lшЌU#ЊБэa q{0*1<<ъ|§ц ўЎєƒQЛC4шwїЙтѕ„жчЛŽ*Xа  э §ѕLѓ€ё:а@с +р )б•нW‡ьTЈƒPˆ$T=[EeЇЯОŠ‚LЯљA&8a`y‚пЮћРyРЃAvкў‚Ч†‘™mDС!kcˆ'о”4Zgh~ QБn=Rу˜9ŒnФ–­O {ѕwен~Hб, ћLЋЋчСёК{/z ћнvNђНўэn]Хыъљ^3§RНм[ы‰{{{ПŸŒъ yˆшяgБŽLВf™ьЛ“k'ДПЈю$<МqŽ $yТй№ЛK_YOпуQ[[ Џ7в8!эa›ѓБ]Є+ж{ ЈЖ ­ЉЁLіајќ•ЧoD4A‡Л"ъOAЭJQZ!nzYA*ЧhfЪЏЖюЃ\ŸЏ•ѓ$VЄ4nђZДд‡…џЪ'œ7ЭМб}Зг„ ~КjJЕЩK|ъ*~H"н{Ј<4xj&sLЙCхСђЋ IЊНlНфЉ—7эL(Ћ_wЋнН’#БіVщ`^ю-юСЌюсЪч`–љбr™qАX{ьЁ­qXкТУбT[_U9ТМAU ЉдCЗ\MЫjRпЫјFšI{§z Јp---hЌиШЈXxHco^ё›ыЋ„ш„TЦ•ŽэH‚(Ђ„€ТvЩ нѕ ­ˆтГоб^#D˜Жў-р*%ъ306Ћы[‘Щ9гd"ЂУ(F’ЅSхH0ЪZяЛšкPFDZ+ыZ‘щA"i dxn  ­уuР!ˆNOnХ п–Ц6laљ‡F…a@\8|,x3ѓы.Џlйм ЖвQЙ }­XщkУфx/bˆlтCp/ЗВnТт<{‰'›јl-г}cТШKЧE$8Н{яrРхРБЯ 9F*$жтЃїp%9]Д)X=РЮFяјQљу‘е^‚ђжDnBxl2МЙc˜FюЦ Оцђ"ФѕЪGlяєшu$Є„Ђ|p$‰Ž`&Ж5TЃbнBДE„3/\%0gWsТ^j™аa,…њŒОёhЄљўУuШ  yх aЏhќЃ{“о Дцšя|МPYЄЭи4јЪAёЊˆЃS#‘‰wЖжскОq(ЌjЦЇ ˆWЁf—Б\B2оЦГR'А\^вб'Ф2n+9!= Н"ёццZма/[*šБЎВЩ‘CЦэK€<=7 ЖзГ^yNb ‰X­WЯœœYOІсџŽ{S џŸVж<š tu~ 2“тБГв‡Л–я֘ЄфhkIPš˜x$ oђгRђp>Sѕ”ЏBљўQu Юbљ[Я_]УЛZоOЭˆСЗВ“№СЦjз5:М'miѕjВh–Й’gdХ œeZTдВ %С‹ћФЃwJŠЋ|јdg=уЗ04Л\ИјBq@Вци h ™9>ЭѓiаCыŽШiкŒ4a§ЖХ(ћшqД6T­ЯиНl еЈИ$„SР…Tcкšааи„…•ј„Ÿ-5>DѓY8С3М釹Ј8j„ёф…0ѓ’рмйдŽчЯщ‹…7ŽФ‡з Ч<~š).o:kОqF.>&0}PгŠз*š0›Ibi=Г 4oR€Kгє’Ю'Е-иЭ­„Žзhm|^BкKљмKaнLїуй•Э†Ž4н…5-Иt|юМzЊiк§щЬБИzb:V7!*Т‹**Ќ/]и nљзР§gѕƒ':ѕth}’&лplj„‚ю0?^~Ј!xТhоŠŒFТИk0}L<1’š‡gвтЯУ–”ЁŒC 2Іў4„СоJ№юцыбЩ^|%›ѓ€žJJѓWЗ6бмШїЬЎ…qЭixТЄЕЋ›1}\ъ+ёШьб+1#уы№ођˆЧ.|5˜а?1Д“†ЌYВ qQсxh|jЉ2>ДВ Б\мsћ˜4l'аm#пGсћŸЕ•˜Bm&+1 /mЈDNœžA№ѕRЛЉ Ъв`ДЙŽ‹Љ2ZYtXђЃб‹uЭ-8}|>vэРSs–ул—MG^zn}aў6% oЏЋDѓџЩј^xs5>\WŽ–†]‘Xg4Ћи№zжИщ)ИoDіNр}2ЂkАЌ9 ЗіOСmљ‰XОЃOmЌТшјpќqX:т Жб‘с˜НІ ›Њ}дNУЬќ›ДGiВв.=l—6жY8љіТUXЛЋпНъd лY†Кfн– 5№уqШLŒР‹kЪQXнˆв˜Ц<ШЯЖђFќ˜МЛєФо˜4В7^ЈЎС +ЊБЁŠZ,M™1lГ+&f#щ_-,EfŠПЫNУГkЋё­ЁЩhт@сЭэЕјЮёН№8щ72пЬdЖЫЬ<зGу­MхИѕнBjЅMјцE)HЂYм›DeкЏВˆnp9рrр ТcлYєvЎKiЇд“ш$NЕ…E")cFŽювЂm0`0квЃБЕ&гБu %eл…ˆtВš`у7…єєAб8wЌ„~;Ji\ДЋЭšнш-*М чПv“'ПK+{Љде5`хЎ0єђ%рЉrрођQU“„…л6улEaq9V­/Фи4/Ў9}jk*O sX~*N{r=žž6ЅЛ+ёвв2 оa(r1Ю:ЎВгТёгEс}rВQHŒjУGСŽš5hnсЌ‹­ХЫN 9Q›­Б|Q,]ЕЇZ–kўN/nnё" ˜žŽoœ7 UO~Œч7z№­ ‡#ђЅeШLKЦ)'dтю9ЅЊZщ™{^F"nП`j*+šЄ§k<Јg]=&Wœ”‹M[wрЦщљ4o–тНuUИэ’‘и]Qƒ•ЌgN”kл"iЦ Ѓ&ж Ÿд:Ю;žIѓЇЖј…Є„ОЌ _s 38Е/nhЧoЮŠМTЪЫЋ№? ЦїŸYSћ&тІs`щъЭфCюl"0QKSУіNjA~L6TFšG fюИЙЉ1ˆŽNФES†cУ§уІГ‡qmoЪџНЗ^4eUБ [Ÿ‚yI8;7 §3c1gч6ФФЄ>С›Z~˜с­xmZžпnp9рrр‹ТI’c3x(”Т†4Sš­ј-Ч™цњ4iЎ06с‘h–YTЃј0 a“& kOKцаyп9)B ˜љЏИљбxuYК:yБ-Ј&H*›vcюSzџ‡žЄ­дГ3гqЧУqaZB š[ЉmвH*сЎ№ђћ‹pіу+1q@*Mu‰ЈЊЌ1€pъ˜,м Мїi9’у9Ї5$;wзaка$Фвщfг&LŠiDmГuѕMЈ&АѕЯJРŒ!‘4cвtIM‹~3ДљyKgЂ6–Ћ/…њ=3FQSѓbхцRDi>•!б[Cчg/ЦSCэLЃˆ6ЄqВШеS[М‚eЫчмл?ё^]И™Љ<Ј%^L3jVЂ%ЛkЉiХb5и–ц&яВЮZ†эЕmШŠ ЧŽ&ў0!Џ\6MЭC/†wФќТНИ{бn4pžrЫŽbЬ|}ІхФсД1№47Ђ‚šр№ќ\G П‰m˜Т МhjQUl)ЧЪmfљЬCoЎФJЊєQд@Ы9@XZлŽд,лИ›Х__[ŽW•ЁЈМWOByM>\2.EЅхЬw+тc#АЛМуџя-l*,ЧйЧgБК>€ьЯƒѓŠк.Deuэ~\И}р гј‹>FхТ)Mi”эA,№Q“ЩLІV@V$NЫ+b(lciŽkЄ wрТŸ†к ]G(#QB ‹!hЂЕ/еФ ›žЄ#[УЭ|S4§OлкHŸщeSОњhП"HѓйЖc;Ўјч\ŒЯNG%С‚ Ч hИ+tIыУЙЛ8ѓ<влŒх›ŠPTRŠд(š&7–рœБƒ0:Ё/ЭћœDS.+єќ;;1”&НџНrжnкŽ­Х †\\DMŽq*Ы`9йЈ5Щ –UхZЙцSœє?ѓQє№u8qt|4{“‰WлDYђEгwrQ]ј—|s€[ykЉ„Д­жШHдx-YйЩiD;F„(^_№ТZъPтЁRєMЩA9у‡…Е`%MŽгFЅaXпTjМхxiеlEœ1*Ў17'yйVвnU‘TTЖЩё…eё4ЃМІ†ƒˆхЈЌ(Х‚БИяЅ•бл‹ыЯƒ&ЯZуќЃЙЮ6o цз'стŒHjк^ЮЁ6#–žžЊ]ПЌ^ИЗ$_Ѓv?ѕИўx ЇXї)cњaбЪuxbw;юф€ŠnAЬ4>ЫG3zoЖ‹й@L|PЧ шkЂы—.О8Ѓ{*Ѕ‡’ѕњ>к>Ѕ”€’ŒВ2IРC=,Œ@‘tй]QN“X …%Е9c ѕ;Р+>уj›6ЧЌhkыˆЗКЖ№гJЇѓФhŠУu„эRy‰Ж”D9hDХeЂ&"ЫšR€–3†(((ърh^рмйЂѕ%Шъ•ŠфЄDд0ш‚9єV,ЋЇi“ іжВmдь"бPWЕЅ>дЖFЁЎб‡„ђГS =S~ц+/P]Ы›R-ЯI•‹Аm4ЅЁ§ђ№жчxТБyыVT4дckY.ž:\>Фа’ЧЌшˆ† *kqЕЙ–•akI#юЙz.›˜УИ$QГ|lСvьЊjD&:.Л[8ч& qЪSI№ #PЪ#і”„pміЬ:|ч/тwНЮ%ZГЉvrМg5ŸЈЖБЈCћїСctXyЄЈЏ|В ‘lЛlЮQЖE%bgC,†$ѓОW=C#ivnDR[)ЖQ+ЅЂŒя^8ЃЩŸІфрW3еѕXх`гвкŠ, oЋЇBŽ]Х%иД‹ Vtca ШЅ4­HIMУ'ЗMЦ€ьx|АxњpŒЩ_G–SЈ\ИјТqР| “хЛYFBрзŽxХ%р%“*ЫЪpкњˆLы‡КъJj_šor€­Š#љIы1sR=УБsћ6,^Е‹#FЂ9’ц637EALWsu’Вћ!:>•ТВН9 vёрvLТЙ'жЖДЊO,,ХцЪV”Q#дВŠђ­+Љ@ЦtˆŒE‡P.+ˆЂ‡ъ|XOM( tџ?%' ž­XК;ЧхФ`WI!>ЉЫA]kв#›q^b#лБЌА›ЋТQмQœS„%Х@Fjo я­X]‰5ОtєmУљ§i Ѕ`oєбk’&Eэ}˜ІЫшє‘Ÿ‡ШЦM˜[–F—8cFœ–эХ”JЎ.‰ФіђzЌ+ЊЦ–V: ФEсŒ|ŸбL›99ЗuWJУђ1"ЙK бПwoxы7с•т^”ƒщ}ŒљЗбчУzШ;•™81Н 'х‡ЁšЮBŸ`Jš1•ШQ_Еѓ*ВщиiјЃNЃ%~дй8№`3 Џ\š8яОМ•ЌzМГЂ ЎЈУЭУлi’­ЧsыУQб‹ђ[Q@мпHр^^д‚-‰˜ž!Љ-иX\ЭeuиюЩЦ„ /Цfљ№С†z4xГ06ЅяoЁпg\œ”Q†5;ЊАм—CГЉЇѕn@5зŽЎkЮч’‘&”UуЃк,Œю•ˆбiхр ”а“і]:]2a(&ЯЄyЛ §їRМ[•8–пйfZШш—.О(ш„vр›Ы‹By0h‘ибђ›Їцƒnє[Zˆak—#&s Ъ „p *ntц,ЄуL*§™…сƒчaWоjЄŸUŽšђЛ8_xA dЕе%ШыM LHCd;—3дЗч†уќ$DІ„^—/nчbьDњyPќQC,мМm\B.№•VIо|жа‚ўс>ЄБleZ-Єџ”.њсHрЦФrзŸ@ ЋЌ49jнЎiгд œ›j‹ІVшХZš+SшИ? *Ÿ4ДcзЧEэбЈІ&ZЭv(ЎчšI/ЫFуЃЉсЕFЃ”Ы>&Хz1П. #Ђ8GцF%Е_qdq[™†љѕуZЦфШ(дДGЁ‚ШTцЇЅuŠ'аХђг–(TЗњ0‘tP3IZ1с1ј˜s|р|+эŸHgeћГlž,з"М†:jx­шЭzGqfн‚VжЇ†ZДT ŽЂI(dѓi€E%Tё}Ds5N‹+Ѓ'f8–7ЄaI=["šшє‹bšG7rоqt=U9ј‰ŠˆAЂvБNе-ѕТnЦg>>Ћhт .ћDp-ЂGkk› р#А­)‚šj ЂУ87e–­ьцм`^4ч@y’œ3І…і2e ј­2Б№m& Ÿа4яЬšS“Žэ":ŽiSŽ/Ÿ/ƒSV•E…чЧЄQS~Zœѓ 3ъЖhQs3ѕQ=WДЮqU[-3qъ­z:ЛкгБ˜Е mpѓaйЉС;Хй”пхU™x­:Љœ/E џ,DEGaбЧŸpKГ&DsщE3еМии8nЗ7нx-ўѓяWPRВ пљоmxіЉYмл3šK\ДuœУSнxkъšадФ­піS#t Дў‚СЏЃЁnŽ`pГ>Њ9аc ”@ЊЋЋ3ѓ8б1кŒ™KЈhK/ЭЕr'ккГЋKDзЩqOЬЦЦ#Ѕ=466Ч ™УДeY]]-iyА‡V5w†‰фЙ\цЇУ]FТ§Д|LЏДaЄеаРХоtТˆуvc,Wmm­qЦˆŠж \№^MZм"LДДhОAѓM\ЇІyЈ& ч&šу”VРUЯwэівVАДЂIKЮеЄM:ЄЇC}ИKK,iy -i5uM‹ќQž*—€ЄšыЃЩЋPД|,S3за 0T.ёZŽ%*З‚сЕŸ–хvа ЩkzќЖв\Й‡зСэЖw^Ћ­pтЕкАƒзІ${ўHРъˆЅЊšZœxжиЙvFŽŸџфЇ3ц8nЮэ_иЦjџ:ЖйШ‘c№ф“Яcцѕ7Qћ„чgН€^НzЁЈˆ%kYŒ?ЈЏi9‡4Ы§BЅб'xл<Ы7­КZ"rЈЪaœ{ЋЫбТ ѕi•W7И8Z8рLфєА4ЮqtlhHЈЇpKJяe@Ї…РзDЭ ™їZx.aъ!А%ІІњЇ‘ё ˆKфš>ўjЙ•X<ЗЗ- іzšи™V бLАвV]Ђ-!*№ёpax‚hQРЉб‰IˆMр^˜ЄUG0‹OK3 кFZРIА$xнBќЄДєZ^HчД$$:hХѓЬA?­ФєtDьвjTб€jƒыDбђƒh8Ъа"/k юБЩ)ЅJј‹–dђЧGpRЙŽіvђ)‘хv™ќс†сёr.!-Уыdђš€-A*^'2­О…ы$›шй›Lк–wпУkђ'’ѕ1М&˜жђођZќБМ-o Џ™OŸwтuB"тќМюдe(гd№е7тжkoФђ%KёЇЛяХ[oМMыз#– ЏВky…6КгТЪFЦЭNMр&єNnркMЖГD=VИw*‹џFядŸ4XвѕС yšыnngнœrt#rЂLдgд'ї,*ЇЖš;иМшAQMT•У ^Y]ЛСхРбТЁZFFтуш%И˜9ЙЙF—––А^м!„ї­дРJKw!†ZPч‚ъ)„ЫЙ=Z 4@VYYIЭЈЪЬХХХЂŒяš J+эЂ”&3§XtЏг ЪH[ZRVf&ъЈљ•—яFС#…•мWTк_vv6b n†+7/зfII‰Пмм‚ЋЯаŠ'gdєт‘H5ЈрЩвH’““ЬЕДСомj,Š ъ$ 0//ЯдMІМpjПzяЃЦЅМ JЏњTђиЂŒŒL$%&АŒхІо999FЫU4pШ%-iŸЅ,—@Ј7Ы->ю&­ЄЄdЄЇЇЁКJД*‘Щњ&$pћ6zd6шХыЈЪ%Ћ:Jр‹_в^ГГГŒц+Z–зUUф5щЉФkНгCMŒ IDATEМеУт@(7‡М&ИЊœ˜|ŽзЉ)Ј ЏХЕM‡№ЅL“\ѓёФˆЬь^0АњѕЯЧАCё•ЏЮф!!~­ŒёnщВqЫїnСНј#ЎЛс:\wг5иОc ?к$Ё{? €њЂNџа А<*—N:QтУљѓ  ѓyG™еšўћРgћЪ]М-хЇkхoщиДі^ёЬ@‰mћЮœ9,“s*ˆ}oуяы[u1ѕcDелжUŠ і‘mлЗ0 UGSІW?З`AH^„ЊЈg]•Se ЖŒzfыЊrАпŸ;•ь‹Ж§ьћРєюЕЫУЭ§2ЊS—якeFwЙ§xЈk=Ъvь0[PЅesOMS 7Ѓf“LаЌцP O *ŽBНbWБЎŒм<.xц–_;w‡ˆ<вjЂ6UЕsЗођ"-Л7j§ Eр’–YE@ЈтIZc,…zyБhе ;ЏЕ ю ЪД2{цѕыŸ@Žy{ИО-5+ЕOcтLHЂf˜†*ЮgUВ\)Y‘(”!п;?Ÿ{ЖHKkлВѓђбРxЕл0jЄЉ™йЈa9ОБ.iЛ••KљDQ —‘–ДЙœОh`’V З7ЫЮЯA…—јNаN!аеp@!ўФЅ№ј%jЈ&бJяM%Pэ&ъыа‰з•t‚qhБ$ьсuЕбќт Цl'е9C Чо%^7ХŸf–Џ”їэ4лђ:’›i'иЋШЛ`^з’з™фuyнˆh ЩиАa+b“ чpпвpn-GРаЂwѕ™“S2ёШC">‘ѕMLХпяћ'2†О†РЂнfКЪG”чЭУgkз™yХшшHœsж9fахcл (4РшВL#!l5'ѕC‡mщьФSщљl_At&;йЖ2ЅЧQK?~ьXŒ5ŠŽ>дЈйgTGГЭKš733ЯE?Šy†БMl9ЬMˆ?ЪOЛ#Эyя}L:ёDђ*ђ є`ѓ,DRr"ђйЊOŒЊТЁ­ВpzђAЯš*›B /dŠW і”Їт‰Чћт‰@^V†ЅЫ—уЄI“L§•nсGЁћW&ћЂ'аol›(ž,FтПђV=5sƒЫ#СЁ-Є:ЗДібШŽImD€аЦ­9ЕИИxcВlбќ Щд‚2+jn0‚VGеS˜JpHћа–V2CF ’dv%-iNё4яХв”*mNДR˜O5R™UŽ вŠЂ ЋЏm4s‰*—Жњвˆ]s)X­д*UЎв‘)Е™х`bЄв,+-ЩGСІЙ0iЛ‘ќЪЬA“nMЏкŽM#џh–)…e-). 4_ЪьшьОC0Ё‰266ЦhnХKD№‡^ЧzD№‡ŸIkїk1ЎXвj‘P&­DЊhЉ\щЄGpn  б<ЄхЕЯђš )!+Ё%У:‰–ј“Ф|‚yЭMБ-ЏЉJ  4o™”ъч5ЭИМB№ZšoДx]C“#љЇќ5YЖ‘ц2ЯЎћ š(єxјu5•иХA‚v§I!Пж|ЖћsљудTю6uOIŽ7эМНp'єяиЖЏ‹?e<жщТ ЮCNVo<ђиcXВt)њєщC­6ЧП@-5ЄzўРiЩ”ЊД§єSlмИы7ЌЃР§kжЌBAkŘОЊ0‚эт%‹Аš‚xнњuXЯЯJ ХхЦyY9Ш (5ћiFuёЧœЗИj5g1Aз1~њйg4AGГяj–CƒЄ(–­ЂМ/НђВбоъiqV%Mц_<ŠQУFв$+эЇ{BX44‰x4ашљžCZ2dj~яƒїMйŸ%0іЁЕCќyѓэЗи~дPYЎššZ<№ЏaшрЁˆч@QР!zЁ€FеЖП…ёуN@!ЛЄД …ХЛ9иmр‘C‡]O~WБНўкЋEРйЩ%(ŸЎ]kLы/Нє2’†№јЉbЃoiрљчŸЧШсУiRн†EKг‹wЃЅ5k>5XN+ЬмѓMЙЛ`ПЁХŸ„J™ БЄъ[ƒуТв<Н› |^~ѕ%cЊV{hјСмЙ~а€xюљ x ЄЛтEWхpŸЛ8иoP™ы‡юaчH„Кз<0Hу a{I+сяР–“тв (‡€ gхъA‚јеу:‘2c |Вв­рш1­€:^‹й~eЈЇДЄ-ЇqЎvв 8тwЬoj5™КŒƒŒ<&ЙСЖР}Еi Awdio`xP? ŒkЏUoёЁ˜кWƒЏСЬбj КˆGёдLGfР‚_YСƒ`R]C+jАВщгOХG‹a№рС4FюSUоЂЉ„v5y§ №ЈUѕязoОѓЖбFЅ™NЄ)SО/Пњ{<м™u—Жtж™g№0p€удхŒиz~ыїеЬД™YдxqрАžZ№9ЦЊА‚ƒ‡I'p+ФvЃЊLW]u%†А.MДX‘/Д)'„Б\Л)“ьІ-›Б›ЗYЖqЧЯн~’ ^Ыј~,6Qc.//ЃvйРrECк­<›ж*GшР–у;лea›iЖљN‚oЇM6oйТ6‰1<*žE'MšЬyыLЃ!Ы|Џн‡ь@/t~юS—‡†‘jђрАSОяє2ш&8n№}PєНоЇ Оп[трИћК?ДЌ№mЃnЅАб‹PЗУОъдŒ{ЅL‹‘†ZЂ"o?šягЕѓмЩ@ЎчЭeaJ ыnP~2Љ]rЩE8`0чбо%аm7ŽBыЙЫДЂЙР0-!ЈЙMс\ж@‚—Ъ1vє(š.'сйgŸ1bw5еDtе›ЈMsvуІMœ3Џ7рЖ•‚_@Д‰пuѕ\вCсЏљ6ёbшрA˜>mўѓŸщфUбЅщбђANgšfШц|ёO=ЩВїЧњukЭAЫ}ђћMTМгЇБЉХ˜ЅЅн lфЈЖš;љHƒ\E“ЌД`™GзP/ЅvЙvн:SІ,š№_}эešu0hа<>ыQdszaoСДІ@|д€€ќИq˜HГsП‚Ц2MgЅepS…‘˜>uš™Ћ”)T­ŠЪ*Z 6G­ дhХKёЧ .ŽH#<ўВц)ѓГ–_lЂVѓЧПќ…ЫюFŸI M;8МъZЛrр‰К—ТkPЪyPЭEj9IAПОиВ^Їдъžœ5‹&шFєяg@F` 9Р ЧгЅи4’smНzЅcСG hЊ Ѓж4й„РdoхГEАi.5™sКN<O>ѓŒ#œ}њi4yЦтЄ“&aжѓЯmјм3N7@˜ЦЙhiЫ‹—.A+7OsЁ€g_yЊ<в’ф sчѓrrщ‘лC‡ #нpcrеZOI<Э‘Го•І‚Ї–žxњ)šNkЬР!“sМЛ‡ŸxмьtС9ч0m$Екј|чyqтq“И^Š_Г ­ šЇdІЩl -‹АЮ5Њ—РюD‚тьзgу]zЬЪщЌ_ПЮЩЇ_ѓЧ >Yˆ%Ы—r~v,вЩG“ ŸхНћэrрPp гy„ёьиЕ<œmLёf<:`;rњ bчо›iфPЩЅŠpšw)с\ч@ ЌляИ?§сбJЭD(иœŠЦБ№L ЇљДbzЮюЂWяЮyYOаРђ‚ІЎ-€‰вe–№БЪїт5ѓщНђбG ˆНЬcoз&?І—yZtŽњиzІ<х"эЬ–O4UF™o”ow‚в›EљЊЏЌЅ[‘бѓ@z&ПоЊГ šудоЎzІ2ЊЬzІ’(Нž‰v -›6ј[i/0Ў)ЫЂљ@б/T_[>ёчYЮSžyњщЦ\,Оu7Прќн{—ƒнв;љСШдЅбsXa#СЃ№ћ{ю1‚ї'?ј™—‘`3ЈчЄЩ}вђFˆЪ3QџЬ_оKлА``Dяїз$gѓJА+X&№™uќБёoђTњVЮГ*вrюЭуЯyT ќN,Ч[и>Гe–ЉйлЧь}Јo•AрЖ†NIЋжЌ1ЕјЎ9B-Я)шлз8Щ(žй)Xѕ,‡KьрС–!T>ю3—‡ƒнBmyц ­G‘м§јуЬ’`їHељ„ђ=жР§hiЗ.\ь›!00™Мо$а|єЕ‚-№}OЏEc_‚q_4€Uм›S{lъ€WGнWЊcџНxOїі&žаБŽ ЊoМю:\yЭЕxwіЋf_аЃIcЗэ@E@:ШЫБЭl4Ў§0е/ŒVЫШЊkLЗку^šђВ<а>:їЉЫ—.ИCвΘ@ydТСDвтDЇ{лŸq™OТU{ЎпИыЉй@wh_ ЋZ}НГhX›‡ —ћуЁћџA/DžэшЂ)л1юЋMѕ{ЕG7:пХ14яg6U4oГ_ђ[ћoх6`)\ЛІѕ’ь$І]ЃyЄT<ыцѓ8ЇKbю—.\dьї•Ÿф™6г`Zа •F ЈeцвVJСždNсч†$ MрЎ#†А_8ŠN1OЏ>r,њф›=85—Єшсa<ц†…аv^^Џ—Лœј Œ…<ља‚ЅВU>№‚ЂПЊˆ),ШрfокоKSПСƒ† ‡(џnoх№ыxВіх(ЁД:˜ŒзТjSm4юTЭљыьVгкЭS7 цFq9рrРх@jЫHN[сГ ! _О„sч\PF0в‘cЏ)фŽѓgžvš9нA fƒ&™‡ЈкюЋE{c-‰ђШš˜x>у‘:­Ю1.Š/'žЈ(žv^[gЖxjц;ыВэKPV_„бЙуyќP$їKсž“\аЌ БYX?ИL“Џ@Rf;a‹Жув—j ŒП(yo’ЯMy˜‡?џmС/’ё"yTSggеЬЉŸiЕCPZKУ§v9рrРхРr`ПPJў-EэИђž0мџ `h”уюne–тX`”Œ–YS žuТ#ЈељЊбМ}%"›‹сm,AcйЇhŽ;a§ЇС›žлЁ )НŽhв™x14С=ўўЃxcч›И~тЕHŠ…w>ђ /= НЊZАxхn?<ƒeѕƒ!г №vqHmEЅ-ЅdŽг)ЛxJANv–@Х‘FЂcЁ”Ÿœ7м:ИV{cЪƒ3ŒЇ шŸжSірgЂJДmИДїЗЮk>:•žэЮы0™,о>?87Н3>CхЊ•№ФЅ#эєЉh,о…JэyЛЧ”ЪгgЈБёž'ЕGqixљНЇЖтGгRАБДoTѓt†шLюЋSœИf)nВ,SiDd4ЭmZЃЦe"t<бG™VUзт_=†ЁC†+qоyчЂhчVЬŸ;Љ<ШДоЗ—_z9^yu6жЌў gŸ}Ÿѓ$nўs`ошjlёГm#PdAMm )z—лmбмMЭZgѓMрБM™™hВЪЂэ"юЗЫ—.#z„’iTŽPпиŽ{g…cnЃ'гбЁОД‰с<‚&м8Ю4KЉ­54ћ]КЈLЈЛ+ZИ ‚›ђFФс„бi(мКbадA3'сЅЙ­ѕ\&ЧŒ>iЁ–:M”€МЬ'8oL/Ьлж„Оc3q^J ВулёRЭt`<šцє‘V:ЁcИ РыvЊБКc§кhц,л]ТbOЦасCCgŽљЮC:=G№0гћўў7œ:uтyІн5WЯФАсУ8ЦљL’rJжEeПDеO ПЉ}ЋЩdЦŽ#Жpсџe3gNм{ЯнHфI mДЛ|ћuЗЊ.ŽBє nPЖE†{0mxјžоDJЋЊђЂ—‘4‡Vф‰РКњЗ$BЦЇїъ‚6дEЅ!БWvU_9–6тEяNœ1j>]­AsAzQЂvŠNI[šм8С„А[-Ї1^єюоiсш.ТІ№ц\уЕK{$ ЅMš`ЪJŠ1”GвDx#Аuk ЊЊvS8Gуk7\‡mлЖcюПчрІЎчœ"=PыQY^‚‹Я;q1pСДмUV…^‰эШыэЅгŒѓожCЫ'ŒЬу­ѕ3чГљ_ъyЏhšŒ•|X\ь‘ЉШz&ъ /wйМƒk,eт:Vdšc_Œy“дУ…ѓ-4Л3ф ‚щиRЩЅй)дW4р§%…•TгЮJFuœMœŒ5ЏиL­0-5™4ЯVšёšš Pїыл‡'‚˜…м-Э4ы1й.оаSŠ­fqxFЏЃбШьч—юўZЙ_fD єаSTМѓШ+”зѕ@ЯxcњR'kИСх€Ы—GŠћ„*ЌC9Я\u‰KСИqŒІ†:с‚т)МДnЯь*УkЋЪБF[*_3ЉWq>0!бKЯLЯ"bL&‰4oўсwcKсNМіт‹$dˆСKpkЁL3з EаzХЄkPVХ=)Н hЅ“Ю„фVєЮNbќ6дS”gЊIЋТјC QКрgп›EнЄпD“Їц|Іr*Ы&+Ї <Љ˜ ВСtѕшЫджt=bЛ:Їя„†[kШKЏ=мЫ Ф\7Иp9рrр№s`ПPEШiiBДЮэхМœбd­ŽРDыэzїюm>О€гдEC!-™ ъЙUZ+бlCtбтѕLžЈ№а?ЄЕ YFГг:ОM7!3ЛѓїkНБtтio'rI†‡&йъJюPУч!Šфdъў=$РEDв˜s‚‚ЗФъzГгŒќьЩ”oŠ w ЗгЩ.(юс‘{хrРхРЁцРЁ ' Ѓм3Ÿ}VВЋ ЭPСЃs†КмK‹д‹z^ЫЙ&77kз­ХЖыЭНЅL>–!юў9lшйУW 7m4к_pцŠЃ{RЬЉ{›БSqя]Иp9p`и7 ЃЉ’(cчРВм{ъЯƒЊдN-Фж<ЃОG qXЪГївКoЛц€6VМў| ˆlcѕ/GЗщ>з}тrРх€ЫƒЭ}Ё€GGъH“лћб, ;g %rЫЬiуэЄNW№І~ЅўЅ§\ЕžIзUфрŒм{—.\ КB # '}жЎћŒІЋœSзцщ&џpР‚`wЋЊ~VЩ§]9Ќ9рvКь—.\„B;З&mpLнЖm+O*є›­V(Сyh(6~1ѓш–›5З=Ъ›ГЗЈ—^ В"ЈEїМл7ДЖpФˆŽ \*dRя›ОУх€Ы—Ё8…HжДСc“†pъCdћМWсЁЮеЅпЬРФ€QW1œчкЦЅбёUЕ\GЃг;Т<м‚Ј[УhѓB\lœ1і@mўюЗЫ—.і‡Ё0@ IИiщУЁ Р жsГынFКšсЁфvїhKЃ3sv!ЂЋ{ШZƒММ>NL2o–WT`ЭК цЙ‚ћnMѕБ„ЖэТŽЂbŒ1P(’gђщ[JfRi ;‹ŠИu RRRЬFећ_jЄgз \]Ёw м<АДт}S7EуЩё­<›Б›ŠЗ{‚`PЗжkс‘ФЮFГ)+ŒэшuЖb€t;{mvлц;•ЏvВ (КдLwSГф&||я—.\ o' IDATt „fаю,f/оО›iћшШ‹ZM”ž–†ѕ6 7'‡'0Ф@Ђе%ФhjV€йg!+СМЌ˜S|›&d\їсЁу€ƒT†џэ:QƒgЖqSqif јвфпЦaИQ+ЏMGщT&Ж:dе['6i hz8шбAШє,Uqc1?ч/oY–˜˜($&ЧУЧС—л'NЙ]И8јшхЪA†mЅ˜ѕьГТ ’N8ўју‘”˜hUtt4о{џ} 8}ђђŒІ(жРГњДСЖ? 1­“ѓE'Ёz№ыуR<X" mžюc[њxжЂ1œѓjў7@&+A“7˜єb:‘4Ъ—д9z’2эюВ2Ќ^Е У8ќР?РŒ—cРРfRЋ_™Ъ ъGб:X9žg[њœ бэKїлх€Ы—‘]Ёšd rвI8ыєгЦ7oСЄ$'#‘`XJсЖ‚Тm§ЦИќ’KŒ™єзпDUm5Ђ8Пtбyа™b ў§ŸбЗo_œЮЙ<#p+";;лh™Б..ЉƒЩvžr…pO^™§ }тq а›ЗnУяј!ЦŽ‹к6nЊ­Ž"k*Q}Ј•Ї|ЄЇІЁЖІпўіЗ0|Ш0ZвyВ–Žвђ'6q‘nkk›]wвОИ—.\tt „ЪIЃrэђёж;я ˜s5Љœ”9+žцP Їž&!MБП~F#ќpў|ь(鉙—_‰'g=‰OзЎ5Z`nя<хЅІ№ˆя0ЃєЙЬy‚4žuк)и№йjќцюпcж“aд№!дфъtЌ.ѓ „zLЫЉQ љК€‹Мœ<ЬygЮ?ћ|$Х' фђСЮк`9i‰КuЭхd‚\И8dи+Jщt€БЃG­PN2ЋVЏцqI{$Œš”TѓˆЭ<§}ХъUШЪъЭO&tŽ;nŒqИЉ­­E?ЁДLЉŽnДq^Om%3їЭ7'OСФёуЭ3T;эЇŽFgе:} zщZєЋс|`M]-V­Zппs/ОwћїH3—]v™9IœшЗю…Ы—.КB3жЇДг‰ђв {ЅЇKEфМЭФšхQ(‡Ю!­\ННhъ№%аЁІпDOг0уё'Џ?Хї?јЙTЂWЏ^F ŽJКyєœ\5СУtЅи…ЁŽ^Є.kwТxдrА#ФвЇÇ~ТІKіЧ‘Ій\zНс\—XQ#cܘБ8nєpЮ#зГOˆ–тѓcг™ю—.\>t „вЅЕ%s>А…^#`фKАЈЩФ9lшPЬ[ИЛJKpyJ}>^М1tЄ4hВГВL:i–’wZn! RfW7]P“Hг2ЕѓB`ш1оž˜'q”ІЋrйwЁшлw*‡хЁGС[яО‹ћџњW#–-_Ž“O; /Ьš…щSЇrЋО}ѓРв •Ÿђ ŠЏОЃAљ_џі7єщгWq]kcЃcњз{­‘~љеWёїўгєЕ“жO5W_5FPž6хcydiЬс:ыKЎИ ј=|и0qGЎБ'тЧЗпŽo}§ы~ЧГЎiˆŽЅ)њ6ЏРgzю†уР>PфХќC4ВЪШШ4?ŠЪ’]Ž@:tйЊj|1ш№‘"шСаAмH[ƒѓCя\=>2Т4+Нd"ЗЃcm‘–œ”LЯт•(ШЯ5[І9pг9}№š[Ч7UTVВЏ…ббŠћЖUѓкyО”ТБ‰Њš_nmйsь“)г>ј№У8ѕ”Spб qmй'“ОЪ&­wM™ѕѕ,’ТйK@QЙUm7Ї#Ђ šoз3n&ЎВХјщX+‡юф=­ ytГ„n˜@NcјY€YЧн™^%ш§ъП0|жF JЏК)эœМбЪЇ)бzЇ}YЗrщвгјmp<ХбР$&:Ц”ASŠ#Ч6б•eGљжУа%OD[SŠЏ8]еMяp6ОGзЂ­єцп›РђьиБsо{Я `єLё322L;X1 Ј(ш™hЉэ,ЂЂ"YиD_ЯUNХы*(ŸЪЊ*мѕћпуѕW^eПБЙ9|ššЬчрфЉG5ою+ЙfњІo~яјžxј1у№gћш)ЈџЉ?8Мі@žђ Жˆю4ЎЫЖSFzgylЂГe_imПV>j/ЇoюБО‰ŽіŸнBг@ќ)ГжўчЕз”Нzeаы4{Џqм—‡њqю-шЊЇьŠŸOg*…B d#іNЦФ•”W~fЃ‡г‘†ZЉhЋпIЬ[№!зžaцЋыИХŸђГхS9ЦCш˜5~м8“NYъЙДE У‰чŽ69 ќEK–˜QОжСъZyi‰–‰lcЙ‹Š‹ р&''ql#xtЦт’ЅK HШ)LПi/Мњї7;'is ЬŒќЕQљZjВЅњФиќйgІћЪќЈ№ƒян†O/1Bwдˆ‘щЯЅыJюЁ[@Яж˜§ж›ј-ЭБз~ѕгџoЛуXЛn-V-Yjи)gžiшl]ЗлwьФщчœƒ™W]?ўюЗРЏОђ ФЄІP›шG3лkИtОџнлŒЦЃп“ЪиЁЕPјкюЏч 9}„‹gЬ@D’чM=Ћ–ЏТˆ‘Cёч?ўХ˜юЬoRщXg ^iЕЯќћмњ­[ ИъЙРCAпвІŸЃyјжЃ O.Ю<уlжИяўRУyљљљf№pы!zѓ•WAС-`МёпР{oОiМРe~Нъв‹‘˜н›Рœ—_{ _Лю:мњ_ЗаtO–,ЦMпј&nљжзQ_WЯ~ §у$вsјцo|ј1ޘ~ЦŽЩ5ЧЋMљЄсЈЮ„ЫfЮФуџњ$ш%{ўќ—Пр‘ЇžТe_Œчў§oL›|~wзo _Uo=Л—fц}џћ(мЖ?ћМЁљСлo›zXmЬ<єѓBзяј!О~эW‡ЛxnyeтљљЊk=W>Е$Ј<і™јћЪьйЌы7ЬnI)8}Иp-wсŠЫ/3+ХQ0mDfЫм}!зЯ~‡i~yчьгР{sпЧх4З*\vбyxюХW ВњщмђНяущЧЧЇjњџЋЏП[ЙїСќньа\7CФ§гc„BЖкOЇBђМЙ5l5d G`ІГи_lГs|8 Овг."yнЬ­и†Žaќ`%œ6rћОСƒb@A~ШбНђ’њд3ߘO 5/3‚]s; ъЛ‚…iSІPјЬуFу№Н[o#Ц­E xеŒЫpчOяD&5Ž—^yзн|Г1Ћž>§Tќфwрк›nBuu| ŽStKJЫЈљTш_!јiдЏЯƒ4ЉIгJHH4цПKЎМгO=ч}Žj&Aˆ?т~{‹ ( Я?є4ІLž‚2ЮJcерTѕмв&Ѕ…ќб"ŒќыуЬdѓтJ›\БbЅСo~уыИƒѕжѓ?ќѕO&ZtДџј+ђHfцдДT1ЬФб|™‚4JЕ‰?ѕ4ыжЯhЕяЬ™cРkъДiFвf &„Eр{З}wџіwціџнї7‚O=њ0Ю8ѕ ,]О <ќ’9XPЛЈож*ўЉ| oМ?џйOiŠЬРwhšœvЦxчНїЉЅ 0qЄE*фdчрілnХХ_ŠK Іk9@5rЄ‰cy%šЊЧnjГГgП…?оѓ[„uдјХзР И o”ж|њЉБќюо{qеe—š>Їƒ‚з\9?ћщyO,ўС}tяјёЬZi—јeƒЈйrhщ™4ЮmлЖœ:qюОћ.ЃuўрћЈ1ІгОвОШ~8iт‰Ц‘ъйžЧд“OЦд“ІtЂmѓpПї!а4˜шБ#lлЖ бЩХЦЦёЧхиСї/+7•ЫЎ9 чзь4G&ЈgsЙmп5дВ""ЃЭН$–’юe†Лš ѓп?ћY‡pа\ž„ЭчŽpЂФ]Вr Ў™9ЇN=™s-в[;FњeхјЩ?у‚CЅс:УІЭ[Œ№”)LaьЊ5+ёУяпšкЬ~s6ЗL6я29ПЅ2USsXMmчŸ<ˆJgbЂcкjђ;њ˜Ш]ќ(HлТуцoо‚“ЇLЄЭXœ{ійdЅA)ž šз\Lгэ•—\†ЄЄ=ѓЖz/.!_K“ЁТEЄ!Ї~ч—œўп}їѓjn/g$3ЫtЊ‹ Њл*šяgнЊxTV"^ЁIs›ќЖё.П№|nЋ—ЫkъЩ?/ЖSлK‹Фф 'rSї6?fЎЙц м§ЇџыzЪЛŽi7гД*Ї9šЄkc^ц‚dBU˜~Ъ4ФPVхёœLѕЁр В €6ВM}Єн‡ІQ™Ы•WpАeYMмB9ЈtџwяяqъДщHІХcэњѕ&ЩЅŸKN—ИФЙgŠ_б" ‘,–F0mЕЏј*3ЎТuз_‹!œЧЎ­­GП~§;xxзЏ~…§ќчИ§Пў U•Uјpў<ќэџўjжww(&СФнћs $Z*зЋё56u:’ијNЇБ1мяƒУўѕ+R0?ШЎ~>N”/м_VWBСзи€Йsо1B@BЌАˆЮтёЃлhцщфAh…r0zН8п$№ї$и$ ˆвЎlИŽрМfxнІMкщ у3|аPœ{Ў6Js;5šTj,к(Ђ_A_ЬИь<љЬ,Мљі;˜?ч=:\Tтœ‹.ТЄ №Н[ОCгa†)УПџѓ~і‹џІ6єП˜|т$ЃMž)'O!&\'с@5XћЎЈh—“Ћэњц:™мŒHsъŽэ;ќ%s4ЖgžџѓППЦ=4ONš0K—-ХгЯ>cкЦђо”ЫыЭF›є^ьЎmТюŠJ LяХIJ9/Vbо91ЧN`I+œKС=чд~xЧїpуЕзb+щ‰ЇŸюдl]ˆ<†ї­и˜мФ[<Н|х2œ}ойЦд™ПГ§ю-З`ч­ЏЬйvўRљ•iy8я*uВf>†цЮщўKѓeћБРRaGсNгЧтууŒ‰[єЕ)ЩiЇLчлŸг:ё’ *юЄ '˜і3MeІnиoье-е˜jЌrНБЙбt€=cЧ§ЮзMФ§0Ьܘѕ^cЗ#kѓCЗ’"(ну– @kCS3яызЭ`яqЮ.>’›uїЮщp0 U_i rўА[љЦРЩiFA,}m _MMFA|— ”уЬзЎПКяЏмJю8cvгiЮ›Ч’вф'3`@Fуч8…Дє4DD9@6Ÿѓyзp0š™ЪЃЕЭёXŒчцт­Э­д"?3iДEЁ•]*ГД8гДќIKP<ќиcдВhЪF№vј ‰ІЙUбRмjI=§^yu6 сИ§g?6qЬсй’-ŽWl‚ъждbœ‚AЁє*П‚ЉяEW|žЮzмїћqяџћ3ОzХL3—јшгГL\ XЌ)Q4ФЇVzЖ*ФЧ'SyБiгFso=sЧ^‹†ђя СђЕ‹Р]ZигЯ=…нЪzЉ||ЎtїznчoхЭЋљWыЭЋњЈ|к\фТ ЮУ78XЉK@Bb<.Йђ*dчцЧе_šЛ‚ЪЄ”VAДD#‹;o}эКkё3ЮE‡БЅ-0o>N>iF…о9Нёп?љ1~љ›пštwўф'ЦЉађкўш$$єУаЗ@?L}"У9OТF(ўPЛb™mЈЎо­Яy–“§Ї"ЊтХК[0yьёШфЖЁœЌ“YT@Ѕ~м7GpСЙчšоЯTќ‚‚nH`IЃМƒŽ šSzтЩ'щЄS‰јФ8 <Фx{Zвќт‰дўf№иБDЎIдЈ§чœZЖb%NрYŠЇŒїњ‘|РЭШSh‚“ГˆL0њьиЙӘьВ2ГЬ‚hсг(шЧЊDќ?вЙЯ’Mќ!MЃ ч}@'–уЭ>Є7вдјЕ™_ХщЇŸЖзОј  ^† Сяƒя•FЯЄ-(Hh‹–žIpъкЁЎ-m~Šgуъ[AšЈтщЃkб ХлИ–Žвщ™НW:틆 ъ;l§Wqўыі;pZ3Јх-'<ПJmѓЗ4IP ш6ї{џ9аY#ДrФ~б•Ш•(v>A/нл}p@ŽB€?7п|Ыь‚"С8‘ІqуЈIp^Cрc~TњQ$бСB?,PЋА~ њСi‘7N&ОѓЃсњ"šњVЌXŽЉSЇгРёи N™UЇЦ:ОsгݘРЕЁДСРК)О‚0яtќ>ј^qФg /}ыcŸ‰пЂkŸщZщѕ˜Ÿ}fђЅЅчЂ!aGї ]бQ…РМƒЂ6эдJуДрŸхъ*H@?ћќѓјћСч|oНі wЗтюЎ2„kх,ŸUvY,д…Œ9”ЅЩXкuS?moя\7qOsЁ6О-юе BёХІ Ь+Ђiуь‹6ёQZл%œЯe vŠхЏgПѕ\›}nП =џРвP\[//T§єNq•ЮжбвPЛЋ­jј›ў=—Жќў/6ЄОvуѕFгЗљИпћЯ=@ЈAЇ~Cњmък‘ў‡ќ2š‡ц7dЛяxЉnшдщЕ&ы}К}—•эРЬ+Ў"юТУџzyЙ™4ЭEуУЙ`*Ыu}в„ё(Ў*7#юФ„|ќЩB.%и‚ўњ™ѕWjƒ%‹aнњ 8ўИбќўqџ§К-?ўxўР(ˆL›§meЪЩeдЗlаР@І) 4?c…„}јн• Вq‚пплx6рїіЙќ^ЯƒŸй4іЙюэuOшгЖt- ћ-ГЇxІmэК Ъџf.EwЅЏБ гЩGж­T/а(˜ВJ`j`йmьГюжЭацŸРtzfяu­xППyвpЈ:ЅнZЯSаОBWtlКрђщЙ}fугОЗёŸыZђтЖеЄЩ“ИAB–Y7iAгвvПh˜їВ@ЈAhаoI Ѕ†imuЖˆ:њEыСaЮСЄ"6гJГtБ>—ѓ.>юƒЉSІrчŽэfіU;‘œЬy”YЯ<‹о™щмсЄQ‚ККj,јx!.Кр"<ЧuDЉЩ цЧі6їh<чьГшЊ_evš˜КSІЃ*ŽП_uГ'Кбі“ЈšГВŸcіГКЧ|2ЗO:@ШМtrє-№SаЗДGћ‘zу~КЭO+'ъ}ݘ:y*bЙ6юЉ'ŸТЫџyчžy62г3 v1fчŒ'Ÿx’nфРCЙ1q Зђђa8OvOHLРлoМEА\ŒкъZ 4 :2№БGХЦЕ‘›€OФџgя=ЋКЎtс%нЋо{$@Ђ.Л IDATїо1ШpС-Ц%N\ЇЬ›$3уЩ8yяЯŸ73q^ўIцЯLІ$™‰эиqт†ccР6 ІšŽшъНЗ+щ}п:wKG‰"KXиwУе9gŸ]ж^{ŸНіZ{эЕdнšuVБoиWЗBЙЧлэ ^ x1рХРЭЦ€*Ыуg–ЙнRЫkфёОжU†n€УeЬwпЅ 5Уx&ˆ|iй4Юбƒ€Ÿу:}%ХSSR`Х_–уьїœ8tЫU" \#ФMА’An†aш—jьсVщ+ЇЙv4Р{уХ€^ є?”’йЃХЛЋЯCPѕm‡wyh%zХ)НяhšCщ‹:(“‹‹JмG'АќИokZ5i€улЄIуЄЙБ"RИсёчЙ2˜ ƒX•Œ”?ыЖ#=cињŒ~К•‚еˆsб6{ ЎЕќx^(ђ/М№b ?0аq|‚“‘5!YbR{e$|œŒšЁ)уТО•—кБгл{Ла`о^–Џм ѕvjњ5@ЄЊСmnЪžЪ’}кcьхкуіНŽ1x7Х#FќAјƒ‚ќР[ч­v Маy1рХР­Š'EЂ&аИ‘хOйԘ+Ќ@$‡Ѓ^8(ЋЊц…їк€Б.žd†‰ІNЃб§XнgX4ФН>j'Р:Јюgœ›W-~Ž=Faф‰rё"iЊŸг ŠUЩЌ—ХМ:.2ю,иŒСn1№,ъ­зЇn˜mу“ Т[Ѓ-VpЁЮћ``~[86F-ИЕф‰cœfы іћŽXЎа!ƒЛ|)OgВАЎщјФЪЎ(ъ"jЕЩyпЕЌk—ёEJсюТ/D“96ШњRд‹š‘zслeуКеh?з7ЦЎD9ф`=1QВб‹ХЦоQw%žК‹Бp7И;>рp‡IЩ'Х-ьз[uБШqэё™‚ёIO мЄъаaФ§@мœ‰Ьq1rњh.юљ<П-ти!cSхЬ1њ ­дgќщЂбŽл ›ф‚Xn№И!Rф_ˆНЊfUдрDЅСЬMHШ•wO8рŠA'7(P9ЄЁЉi!bmГ&=r™žщ5ж-*у<Ј„г<{f№>пвpaѓ4І0`Й*цссЇОmКšX3R„i/Ч^чсI|3,ћ?p<7„CYЩk&№ZxьФн97ю„GŠˆ˜?[м.N`4~ЎЂЂсЩ}жмЙвиаи!iКVлЎѕžupЂg=:YrxіC`=4И]TP(lм(ЫoПKbууды†1pоеіI‘„пж‘C‡хРс#ђШƒъ6™žюш@ŸTк‹B' v5œЏпКEцЭZ iC㏘S,kфh{т I Ё г Ђч‚5ЎА]№AЦ ZjзˆћЗ!bФu xtњ:eЯщ=RZ^"• …’т&Au3с6Ц)У"CŽ(V~e^-ЫN[™ЯЄ&˜JxL`œIЃb/У$ђ^иuљЉ%žй‡<ТЃ%ъrІЉСЕР1рзт'еЕuz$ЅхЕAё†“Й=м№1CуЪ~o/ДЇ{{zћ}Oщ?ЃјNмеъёœFx­‡GїZ­f[Рп0юL{zлvфгя н4QnддˆqвPзa(мTбхЪњЎgp—OјДРcїЊбЅМ>x ŽIЋсTй‰#PєHУvЈЙ<Ќ8ю-ЮЋ=Џ§О7э@~%„јЖjъъ ?B)О-ќ3ѓ.пwРн]vьїнЅ§q$д Ј†Е-.І›БРЎoЈ—xКQкс.ЛгжЈ†лvХCФcNв@ЂVYT)gG\Ј4PD№ИЏ Ÿ8\"у"a‚­ѓxп9ёoуžMђыsџ)я; Ѕ…ё№Лж.3BффžJљУЧђНяFHJœ@ш(ћіэƒЩА8і1/њQ™зyеБ‰МъiуŠŸ?МЊыw9зc|й^ЅйЧфGяp^щ*Щžжѓоlаu* Wб-tр"HN{Ф›іО/ЖŸ.ФЈ3`&?ИЮ?ФеFсх:Г)1#,эXа0?UKЬ8q:,„н•E˜ЏЯ„‹О ;І>cЂcњ n‡‰.т”И$О ŽљЬёЉэФуТ­„ŸээЮ€>w іёСўWи1у2žcлl‰i„ЧŸ>…ЧЃь.€еТБЕяЪѕ4Ч }Н ;FŽ;ЙBаА+ƒe"ЌЂЌBт2у$==$ЈY№яьйГRU^%бqбWd#bтТc•уЬњйYљљђ=ШG~ЗБLжжР`ДПВ9R&рœuеuJwoп-%Х ПjГЯТЪАAЖlи)•е2nк8=jДь!Н|юЂD%ФЩЬлfiйWчир04 3 р&?32?ž}к0– ЮЏЊЈв•тu$‹з4њЭ,ќ0xЃc‘“ЎћCч" /•CхGDЎсЬ™3иs“„„U‡Qd|iщQ‹s—a8 :єЭН|YЙŽєДtх~9Щi:fАхБтX"oV "ˆ{ !Z+ЯЏ:Бˆ чŠђšr”ща˜“v‡HЬnf4К…WLш\ЁWUK~~ОeDœлnехЦ•ўQxјЧ€š|ФФ 8d\3…С'Ѕ |gѓФ1гв)ђю§ЛeпоНђШЃZgvн: І\sеТД@‚eSЫОfаЖ •§ œЗЖДB”W­‹т–у‹F3ъР}?^ЦŽcqцюё`‡ЧмwРA ‹}м]ЮЫS\ MЊcљjуNГw7юГЕFвђЕ nZТК)Щ!ОЭbЯГј дq@ЌУ† ы=<Д›РzљЯрXQ ›йЄcГў€БœWЈщn{‘k/|8FбTз,9's`зВA‚р"ˆ‹HЯviкI8Ї13)Lжэ+“—ђТ%!*XІ‡К$?мœ{еЩvpќh=\qRqџуЛрА`ЉЌЊ”7~§†<ћž•Њъ*ЭАs§ № yKцЩў§2јџ,Ї‘аА™<{В–ШќоpЋa€Ѓсzf”žке5/ЯТР†ыƒdЧЮ2"3SЮž;')АоГьŽЅ*>Ѕ†~ДјјyЅ/H?ŒyњнуО ?ю›6Ъд)S%^вSSS1N­е&-‘УсЧЯ\'цu`хЏ˜?кЇИё2bФHx‚ˆUкf|Qj:”ХМЬЧIї,я,mы щЉХ}oЧОBр‚рЫ`ЯіwплАPˆУ”SyшЁ• ёќrvЉ+m?pТЩж…Х,ц Нчфž>tЈЖ‰ %Єh3г8Сe3_gYesrB@~zЅ7„  јљpУzЙsљК@1œ&qGВaуЙћЎЛЕ>Уmu–oСЪВHЄЫЪЫфОћюW/tЦ2єxЊЇ?Ш‚ŠgТMXќГНя.Т{ЕРv№чЬуя 'с…fѕ{Ћe-_МpQBА7ЛbХ Хё№сУ/ФыујфœЌљ‰7ТHq%KцИ ’mлЗI\\œњŒ—Ыj™_Ысјt;О№Пžqgƒл >жMжОaќЭп<+_љъWdЩэЗУpx­КТГcчGЉŽШЃЂЃ…,8] т›щШu @wWТщ†Uћ}ХБxтфI,DsскюœL?СB2 IвашbEн_X9 ХЪ 0 ƒЗ мZa4&4JS}“8ќˆrX.JђУ5H$!в_B1M%#лъ%"&LўНИх0е0ы“Ћ,-”l8рFЋя}т^йЕe— ЩЂі5K‹Ъра6XN?%Iƒ“tpЦ'ХЫ”ЙSP_Ј4Е7щб‚Мn р“ЦjП утяЋŒЧž„‰Lеˆ)K1ƒЃЁОZюZЯуЦJEE…М§Ю;ВeЫY‡­‡’O>ЁТŽCnЯК ю­Ђeћж%/П+ѓPј~œŸ’[фм™гђјуТ ^ЁФ@2QXT$Х fѓ№бп}їrЉЉЊ‘э;vI#&‚hl,˜7W>ЦаХŽЇŸzФЅ и…SмuяП/—s/KRR&ѓхr)ї’lиД]"УCЅЖЎюЖюPW[7OYХ;§ŠЙ8Р$…яјиёƒ(?њˆŠьrЁэш‡…nee‘lмИEjaє}ьИб2kњ4РП.Ц СсДШ№aCeіьJPŽ="u5е‚…ъФ уeїю]rјШQINŽЧФ™…>ЉбВъыe|mŽ;ѓЅЄcf =дЌЯ~Х|ежн…zдU/Џ§y•.ќP.С‰@<$ywнЙ\ПЛ?м GсичЋ–eK—H 7ђј№[ЌЌИїnљxЯ.))-SБъžн‹gF `KЗ„†~5—-_І"лЦЩ9 ~g-’зп|SJQ'БfєŽРц"'† Ц‰ љИxiТ\t№а!™ тvћ’,pя›”s_~чRХљXPћ)ЌрFВn_Ќх——Wh?&&ЦЫђЛ–ƒ8ŽояРœ+M РY€ƒq,‹§ВzЭ™9kІL6 Ц.œЊЯ‡ЖмГт.р6Ni=д|Оj_ЧhЧ%99ŽS3>ЙXЊСјl =оBх”k0V.\КE&љфРYМx!Dђ‰ђЧз^“1XдMŸ1Mў‚OзОџL„‹6ТqяИёуфЮЛ–ЩрСCpь$_jАЃSяГчsфK=ˆ~(Ц"'[ЙgКt[?Їб1QZиdˆ=ЦŽ*ЧX}Р6а0TEEЅЧЂf` S\rgcуЌ9sФлcЧŽЎ—ЩєtЩ‡пеъъРr^Nœ:-іЩ‘ЃЧд UaQЁ,]zˆcМьƒгnсщa|SТ 8Ц"AqL81Vъљ§O‹жRс‡ŒЩџё€HŒ<уHTbтcЄќ@Йœм~4щАЪђuљJЬд}OqghhЦЙA„ˆHЇФ„€c‰Ÿ'еuМаF ТсiрPХЁMј7zвhЉ,­”оњ@YЌlІ/œЎN:Ѕзв–Рqm€L_4]ЖЏн.›пУŠ#('3$iP’Š–X(р Зиcˆ'д_wcђš-ТифhЖўъZšQp+ЦƒЮДЖC|Ф/ЙЋcVуѕ \M­rъьЌ˜k$5-Mœ˜DОў­oЫ.Ќ`CCC4Юљ‚ кkƒ”ТСЃC˜(!*=vœ„cA6qЪiР$ŽўИŸмќ<ЈkSi аИѓВюvLЂф+0СЭœ=S’RЩє™ръЊ№­DЪm‹o“ьЛТЄA•j]„]n§елўју;RœzД)>%YžўцЗЄМВ\ђАзєтЋЏЪ7ОљŒЖзUR*‡ŽС„7ИСœ№јI“ D'“@˜Ž@ qpтрTр1]*рEЅ {I“&N–Aiƒ1)%ъ$UNZ`QЈŽРY>dјBЕњЭ4н’Y ЗЦ К"ЏFЎщ3ІK2Ъsa’K†В] F€?$F1RЯДFЅrјј1ˆётBОXьёNž6U|!rt№‡y…їѕЎ‡ЋД € ёqH іутdФЈ*Щr ‹0љ7РKЬ'‡JœaБдBнr­ОŽI$8>š чakœ`Ћ c„sW%ЪЏЧйы6дЂmЬчœŒХT%Ж‡j!…Л ћˆэс8Цј Nšв9ю/Ж€ЈЎŽq‡8ŽЛ ”IƒмуЎЖJЂму.<6уnіРЯ*mИbмv3ymХїу БюЉЃйR\^.лwэ’|,y?c \3 Ё3РOс9zт$ИЮpёСјчwр“TцeцЌY ЯДГЅЄЂ[n!В –№И ŽёФ‰нУc …+џ8ЊTY<З%ЃфœТіДЂплёэКАШr6Ђ ЯdјР+IЫGFh„†D‡ШЄЌIШХюГ?M>[Ѕ‰ЕЎŒ›;bЁќьПџAрcќ$,ŠjЗ’s№Ђ|яЩ’ŠŽТ„и:хИ яРJH‡umшC˜ЋћvYўрrНчйDОч~Унп­ї&нф“/Gив[ыcsБ%˜іБqН СВђ™ЁŠЋ/мaбHDФD5PЎК˜{юАозvЗ`…/щЉi№ј U˜šСr,f-X$џњЫ‘™гgЊШœs9’ŸзZ8V€=ђfЌр хЙ[КЩŠŽŒ–c8_USqNжRйЕcЇuьЫцѓ˜\Fe`"Хj•366Vо[§ž$buП“юЂE‹е§ЙХЖц6ˆVaЬb'~ Шo4юЎНIч‰;j-`ёƒU{aa>ФЪql АСXuсJŒклSЧO‘Гp эФЗYWS‹6З('Œ xѕz~ы‰Џ>)-PИЉQє~соW5ŒЬg`п6%!EТBУtяцќХѓ˜Ш0#AjФq ѓ„mЎPšqBИояАщPМŠcРkхЧ ЪhWШgGћУџыЧˆв@[ЃЭ Ю uи,ŽЏ“ˆЈXЩ9{^ТGJpt˜’:–j'‚ЬшљЌ…сW3$„‰‘‰ђЅё@жюФъ8HŽаЬM]Ё<ўHАЄ&јaЬt%‚šP+sјVЪвнї†р2NыРjDaР{ѓЎ'˜ lоыУњŽЖFЫЮK>„FЌ€k1‘иPcXљ Žфќёхб›3чЯШд‰SuМPЛѓ&ЕќМ|85Ю…шiі~FЊ 0ћ?љDr/]ТЂ-ћ X…ž”уXQO€ЈiјАL§шwяй#C Сž П„…„Bц”ˆ№ьA‰1+їЄФdь1a&{л‘: EEFЩLTЫ‹@{кeјас*си MХєДtUФ! •‘hЄoФЧЯsfБ1q:ЙєНТ8Ž3чЮ@4m(pŸ>Є#NМTс^Y‰7ыay ЭЪM ƒhwИDr:Ї!†у$ž6$M‰f`ЅВ Х’t~б^LtЌ*VPс†}УОb{їэл‹§Лj…—“~yEЙ9‚…Є iCв%ŽЕ)ЎezГэЈQ‚^ш8&“'LбёD‘ъбЃGБЧ–/ ,CŽyЪф)h >РЫБУ2€s.>’““х№сУ’sю<,гщ‘Г”ЄŒёRTT"щщщБЖwя> Р–Ц)ŠA[2€—Фcмцi“ЇЉ˜0$(DrTbпХЦЦw;ю8NW ё§eXmšŠМхрў(Š5r”n{ђН‹rц“'LжEџФc$№Лoя~\#№‹B_Е)<Д(ЕcaPъ`5ІAМK рnФb№ФХЦЉфрjИэФ9SбRUГ9iХшБјЎ`„•у‰}”˜„я4В›4„;Е87ЁјДМ2ЎXЅЭl””9C$vX˜J Р Њ ЇБ%•-аєЉВRљIˆфўЌшЫЎi5ќƒіšgшžExŸм§э 3‹ЇзaB˜>EЕƒ АЇ4qќDы@}/њ›‹!Š….­§p­|уЉo †‹.hdBЌЩ} r{ќЉхШ@BУ=Ч-?bj{ђ5ЗјkЁк?ЎЬO­B^ЉфE=о›ђ˜з"˜˜f ж!ї&8К ѓАјбВ|Ѓ5J˜Ј xу_Ÿ)ѕЦЎнсNПEcкGий6тŽ№w|fМЊЄЃ lуиХTUч;„gzj*ВM&žiˆ#{Y,ŸeиёљоКїtЁВ *‹oEyдneП1V— ZЁ з‚•ч;™–к‰ќ QТЭ@и ›žMeyЈАБ Іэь3е&е=џa‹8K1ЮџДъ5љњWŸV=тŒѕъј$ŽYъ% |Я+ыaр=Š#ЄaZЧї&]_Ž;k|јCУѕЄьйПGžzќIьстpЃу@n?<3ь йѓнёћaпuљ8аЯФќЇљ8жИјЪŸў ?И‹Ж8=PЯѓšfЌИѕnVыЁчЏƒ~ ЂБ‘О е^Ќ  ЙwD•ceHAЋ™`|@Dн”бњ•€ъ`0бР ?*Ў Їh+ л[3˜Л}щМ‰@чA1 ВAычžˆn ,Д0 хсъ‹qH… ЌubбётОgй.XŸсœЫЯќQq Г3pP‰в)ї=vцkХЊж„&X‰ ш&/у[,Ћ(Ђ#А­Я”kбQjУC™‡Ў€;rєї ёРСТoЕ‰P'ЄћžmuOVЃЌПяšєьmSGМѕ’ ѕ+ЪвŒЖ?>˜#БФЖlшУгq(CKkcЎZPЇЮ?.^љіъА2‰њeЙ„ЭєŸЕџ1Fиџц™з&ъ$(юўг—зјcУ[le&Žл\ЭюђЌ…‹aНЌврд\љL `ю:ЮLп3/CпŽ;дGА •– mL}Skхї„&DŸ6шеМ7№hЄћчwЁVќэ§w Eт˜aŠyЅbхэ7Ј7b"ЦXp›7}reу9LыЋБњХйAg ЅЪкЅpŒЂvŸ@ё;ЙGРЦњФЄH{eБ4‚Л2&ˆW_Шрƒ3;эq8ЄБ—tg)ў>ўJќИbсоB^qžф_ЬЧFјdiТЧТеƒ!xМš{Цћшв2щ,ћ{Цёйеѓ§šŽ IDATЛŸM~“‡хxУЇЧЖ)0!РМїz1&й/mи@В8?0Lь.ќјqYхq4™`П7qМzЦлŸэїі<=нлгля=гїєЎЇxЯќŸўЙwXLBэJмйыш.gЎ=Ѕї|яљЬ|qцŽKe іc ЦG(“УaоvЭcЯпѕžщL>sЕЧiл{šžвyІБeЗнЧЬQФ­8ц8e;8о-M]{9ннлуlwДЧФйгйяЭ{sэщн•ё„Чо(†&Ќ$Ма3s“ЯєW{і|g`сЕЇw=ХлѓZїу—ZЦœЄ Э–xІŸSw*!dœљЙ_їѕ…мЈŠByoРаz1ˆoYјПїŸѕаЃтˆIWeЈдŸ<'эGwшЊиВwзЁmR;zОД.К…p%Эви >r {9љђTT5qцD•—” Ё—рќ#Ez>D”| 'ї‘ŒRЮyШй‡ŠК цТ*ТМЇqšsb%Ъє*w† 'ŸеЙђ ŠїЯЇЦ&ˆUœиГс­7‹ ~ЌљaћSдаeДі;мcцSƒљ9- w-Z‡Ш}АЇEБ\oњЂ/бDиИ7kр№ƒ!'DЫоJэрїьФ1їй Q7!И­БЦ‡хMHEЙјЖœ­ш“2Щ rў˜DИ‡Ь=FЮ)NмІˆ [ЖF9г0h+њЙ)ютI™•ђ™‘ƒШј@ЙРПЕHЯœіC#*м#” |­НЎіOП ч-б ђkЇ€ кwHі}ДO–~iЉ”–IiQЉš} ”њіz=рLe…FчЈ‡ЖPTT”Р\[‰№>гНѕТ[rЧwHциL іЦрЫRV\uяTнА-Ћ,“ZЈwгаярaCp :_*Ы+ЁњžЄчn(Тђ†O‡Ž Nj…8Ќ„у му1‹*]СrъЁ!ЧУлй'ГU•ЋиїХоPУnBb7юh=&чГO мё{ЇjЯ–W•Ћ]PzŸИкД}Šyр˜“1ЯFгЪЪЉГЇд& Ы@Ÿ:ч‚pWBг— ЬcйЧА/k‰ІћG}PI ї #"# б|VТJТtЏи,ЄX…EЕ2R dЙЁъЏР9˜bKЫЂ *RH)ЋјˆЌ0Щ?Rо§УЛђиЗ“;ШЖї6ЩЯ~MЮdŸ‘ж}$3Э”ьй2їіЙАqЇјЂќЁкRXАWя№JЛС8№ЕK*+АMШшэІыEФЯЯ DмQгrмhœWФц$eЈјpUt;чћфw=8шя4”TKЩZ˜ЅкЭЭPQ9м 3ЏЖp…bЁэнЭМЅDŒі[Ѓ ёЙ`ЮЕадAМ 4сЖ}gњШ‰šq7; rРДpоBјOЌU&† JMpBBЧHk“ŸfЈњ bС–zˆ}мЋTMcО~–Н@–Ћg{B!з…Ћ Ш,иш† №i…ъu­гёї ЌF…„‡HxdИr\Ба[ƒс0hр•"OЎ`ќpА“žИкЅŠuЦИ Е-8bм5Этт`6р ”№˜p)Ю/ЦйГ Mџ•я=%‡O”#чŽ(ьDъЈIЃД­аћчSa€c€š“<€;qТФOU–Щ\VR&ЃЧŒ†цZчЖИyчН^wф@ЊрgŽчфnѕ@Љ ~г Ш­J‹KеђЮ@чШyі’su cxPвjУ ’ZкIž ћђY9B'š$ (|qo_)4ЗGI+TŠ%/G|ђ/YПB\ . 4_ЄН2-и-N’{wЭ8+tъШ) ѕ Eq>RчЊыX’0rАъЕж%BCфСgФџ0YѕтлR/дZт*+5ZЎсЈ;ОSЂтЂ”Ѕ€§Gќ‹KŽ“ћПvПаœлћo~rь&жšлћчг`@—?TEDАЏмnДLі;C*rrРјOSЎЛ˜Яѕe уN%Hю1ТћЋі=­™6]-­§нЄЗЇЕплЫѓМ7щt|КU$M\3Œ)”—жУSBсuА0ы2юёlЪ1iЭГЙкуЏ…“чzЏіВ™‡Я4oB+8ХМЛфиK/ЪСпўFŽМ№‚”;g^wєѓ‘‹чЯГЬŽФ}pcЪV8)vFр=Z7Ц–Ч–JГUЇŸў Mљ…`c›Ф]:lЊ>g„Д•bА`bЋ™pиы“QIЬ’­ EОyЫцЩЛ/П-%Й0эSR*™у3ab)Y8sеxlї1]јш€Lœ3QїŽvЎп)q0№Ž xьQB!`эзЪ]_ОK&Эš$[пл zœ'y—ђ$=3]‘У•( *їю;Њћббс§‹И/rщœуњbhКЫрx!зЩі уШб!žъšФžќ y?PqЇ}й-dжЇхцќћoџC~№§ПгяѕŠОішЭŽvbœ˜{&1љ8>Œ(–\†ISуы|цС~{ZтЏњHщ=xф/—‰?ЉщТф4ЦьЈт*鹓ЁрhxЎUЁщВа'Lі:srrд=X0ЬЫјДbdfvуWФ”Х$&­)‡ЦРiєоWgвжУ.lўšевt№Ду0Пя…3вrpŸ6Bт~њ3uЯ -Ы”cЪэ “ЦМ3ux<п›tз{eнІ~•ё[чq^ѓЭ›ыѕxCщP8‰!E”VoИsГgёЮ‡+ьKДњЉ„AШДлєJиŠЃЕ:43У=Be}є/Ч /—L'ммР.*УфY“евУгЯ=­~шHрШщqУ}сrKnмИHИуDШ5}п§јХIsxЛTc+% fє`ЋsЯиafР/А!XB}a‹ѓŒ;˜іu7Ёђу9йг„Ѓ &Ÿ/Сњ‰L<Ќ™2.Ры5•ILzѓ^#ЏёЇcижёА@”-ƒб–@мssРœYvuuЕŠTY'ƒ›їћїя—… *Œ|f0p˜:ЬГѕЖы_Л‰eZh˜›„–„ _HЯ\АЈ”їчw$œw`JЊ4AjзЦэЎСP$Ќi”ЂїЪљо—ЁpyЦВKJJдRAz№рЗШ``2ѕ{>Ь{ѓ|=W“‡WZЮ)ƒ);ZRBШц‘/ДPi‘ы)ДWiмИф ЎCYЦ]О‚‘и†гЅ5> 9(ܘНAMƒm <0УецДœікaрё† Ь№С0.‹цH-E№]8Ѕ‹D‹џhч1&„дO”…h+bp„‡h††*ЕЙb"c4-Ыу{–Э\љбNл‚]OФx ЁН?ђ§*xHxчэwфх?МЌкdfuO/\ q‚ЕTк;ї)^ЛеTєћЃV­z[оYѕgљ§Ћ/ућ€єЦ=9г\­ЛмLмq›Ѕи~юњgyѓшcЇDž"@u‡3јaЦЭ‘*ЗŸјŠ~ЗФ 'B*мXЧk,Ћ0œpэм'ћїо{юЖз61M~q pЛ„DL јžs!JŒc4G8Э„nђ\ыJэ‡iаЅh/i‘FHФ|8ЧXС”Еmл6™?'‹•ЫWЪ–§[,BЈ6Fб"рAN'*L3oТ…Š„ДЅ•†иПXл,\жІР1ЗXсљ€ЃUдgѓ‡х1#Qcр3ї‚Ќw$e*ОŒусyјЬГƒќЧ{Я<$x|зP<‰%пёП7 \ ЈЦ(РЫЛœЇJOпџсїеоK—ЊэЬпПќ’Lœ8Q.Уўш#=&л?к.ѓцЮгIfџО§КМрЖ7<Ё \Œ\?dИƒЧ‰PhVџнџќ;иLн%w/w“€;Кhz”ИлБўєц*ЧапИу$Ьiт'uїЫˆ%3$qэŸdЖ_“ЄFžЗgю‘іš6љYю?J –нщІѕачЇ` Х%+~X(vСcТ’%KT’їс№ŽА}ћvIKK“E‹ЩЦ ЅИЈФІIюЙw…zVЦD=мЯЏ§k5(MWMЯ§р9…чuLє”,‘н{яН*…2ьj˜7ДШљhf`Лз5I™ЫO’А+фG—viЪё­_ПО4с§м ѕžљц7”ўц?~ —bƒб–yрKЈrбыz3ЇкП}фбGдЖ'Ѕ_C† QЇ4HNњЛУфшS|O}эi№Ž’пПј`№‡?СrџƒtiFхљsтSV У-АЦNеW_\щ№Ž/hзлRUќМBr€YYYZЦЌйГхWџњ+uіЈœ„ч’W^}&ЧУk< И7oоЌљYЮЎw)ЮgЭ™uеягz.кЮ;+kwЌ•?о І ѓ:ЗпB8‰“ц№ззeў3uш§ѕр=Vэ‘ёт™,>[E€уŠˆ_tЄOx$Ў‘"ракaˆеXгHK"f‚Й7ФЭ\MКюžэyѕ=КSm КдS9Ч jОw_&›ї:1рtR.iƒгdяю= )Х$`зtхCУ%вlЁˆ‹Ћ[ЗnеїэќHЕXbГn L6мQŒEуи{vэжЊ‰;к„%юfЭю.КqЗmЋО'юЦŒг`bкР(йђЖ\иў–МwH$ъ„\†вљцУШŸ6О ЅѕХ*О#Qт1КЧњжЗџB љЖЖ)lф@L УцQp\{џ§ї+dќ.~ žIЃX’ЖB?‹ЎQЃGщф3ЯщVа—џВ,Мэ6MgAЕќ]ЙчФqc{i‘4]О ­—Ю‰\ЬТcЎ8ЫŠ% зRЭd>rtф№Htй/ ч/РТЄYЯ…в€7qЧГФ'с$™! ПЏ\љˆLœ< ‹†ЫбcGлСщіорџєщ“z”bhкP_?BфТUЬЮ2ќ8Јњ8Pа‹ў Ф_] п3ш2F+.‹яžЭтЛ‡^} Ю‚^C™ІЕHЃG1лu А(жр-O˜iЃЇiДg57њЬrh=†ƒrэšZыjˆс–чMџ`уšZРTtЪ>qJН[а`0­їч^Ф^OPА: %dfпc$Ф6uu5ђпџѕ[™4~Еb†Б  ŸЯ  ŸY•w˜ИВГO+ЧDмq_Hq‡э:ZeАуЎ­СЗ њ wњзVШоР'ф§ˆ‡$ВхŸфWёџ$Пœ№МдFжЩ/Ч§—퇉|K :TfQМщЗIœhЙWХ@1 ХЛœ эс™gžQ‰бŸџМ .ІjT„NŽ…\хАсУ4щ8ј№#<$&4мqќјqЩ™Љ!˜рzЦг>Z*O§S…Œ)iш82__.劉‹LИЯЂ<#Ъх=y0аЅЯRtiрЪž ƒсДЃлŽ8ШŽFТу qbВLтРє)Нk<7˜1"SѓвУг™Рй˜{Б-АЬе’{Qэп3Ч@ќ ХŽе€[lЈЖФ Мд[›pЌ“b\жХp ИтЖ9ю&7юFŽ ‰LЊтs<ИAТУіё™о]^јнЫЬi3СсвЋЦеПOƒџC‡ŽРљ{ИьйЛuЈ%ДыЄнб&щu (ЂЅБE5,IDŠЮIб…"ЕьbФ…vЧ иј–$њHЪр IЉ–А=k$ьЃѕВsН„яо,ЁяМ mЄШ†§4œe•–—Ъљœѓ’s)GJЁ5zўдљ‚KТШ4Š(Ны*зBКљcђ‘pгRMЮщ)/.—s'Ю)agІё†J x†p'Ф #FŒ‚зє№№НXОњдВ>KАФ= c1Б}Ац™9sІ>џtрn'q7ЂwO~U6wќжšр6‹И#ЇФ0vьxрю}™1s†>їЧŠly6јo$ф iЪAŽњ П)Љyщ2јЬylяЃђLщ_Сж0|'тh-JЯ>.і}"ЋVНЅF4(<ƒЧŽњш#у$MWM—АPb $( -p?TЎJ 8ыœ.ёЭ7о”Гpэєќ?ў=‚Ѕhˆэ›AЉƒ$<"ќ Ђz5\pŽš:9^^ј~ЌМГЁHв’§erpЋ, Њ_џd8&|xй!`р$‰8983~щvŒ\эясЮlw€ы…ћІш˜hYѕж*Щ>–-яЏ_u$ш9cЭ{kT ђ/џђ/JЌYЫd зЦћЄЄ$yїwЕџёяПър"Щ=‘&Юœ-х‡ˆ/м–9И/њц$ўQ‘зWэ ~чя%:ек[%= ;Џœѓ9ђЧWџЈc‡D.*:то мБ}†K%<ія“пђЖЭлd:іЏˆWк‹/BD\-хq­>ќшӘнzюЧp,˜ЫIр›АЪKЌ+—ћšр0І‹?B*—Šz­Jѕ=h9Љг{NУu…КОh€ršm*]ћђ#ђУўPЧ :ЭIЩI2{™ьѓДД4ЩщЦИИxU@б6Ё­Х%ХКFQоёй2jЬ(3fŒц!ЅПC*žТ\cжэK”+Іж(ЧХzT IOOяp1ф9–љLq„AэсъѓСоcА$‡7Ъы›jdRJ‹ќтй8ј" Тg‰F™} ТЭжHŒYrYŒS%?О(р†чŽ;–I4$мCфћмЫЙˆ[MЭDЧ§ОJJK€‹9 +лХ2И ˆ•э#>ш‹ётЅ‹2eЪTЩФX`К:є§ †CqАfPЊTОєВФ•WIpк Ф"Р?О(+ѓ$wј]/ћЖьƒХњV™ПlОы‡>"]MА3B6Ќо ™у2•ыуaљкђYі№r•)гТLLBŒT•UIZfšЌ{}фцј№benж\@гUœbAю§{U pЂS;ќޘнхBcђЄIзw\ЕlїKr-ќpxl†Ё'Š=žъч „№W§з*frѕ…ЛwДРdДэ8В#УOм­џИћ+Фьщњъž\d№А}Aл]љ…E…ђњkЏЫЗП§э1 =v{ќѕмw—ЗЛИюЪ2щ*АŸШ…&ш”ˆяbчюˆVƒAC:ˆ г˜М&}Oqц§Ії,ЏЛќLS‚ѓ‚Qб‘ъoiЮЎ{_ЪўМuЗPЏД}"lE?ўCIXљ˜D`бР1sжО2єT‡IiO™;wШїОїНnћд3-Ы0?9t{YNKфЮТ ЩќмQŸіТтИЂ(<] e—ЫT‹*&5уAТ`9Ё5ЛpЕУ…6˜GтЋ‚:qёјтЬм’р„ЌйјаœZanЁМіъkzоo№АСКР§њКя j8љ@Лы ЙчБ{T^ОўЯыeњќщ’Ÿ›Џэ^ѓЪ{§ь*0c‚ MŠб> Gі‘F(ђˆ#ЎмHѓЮцЩWџъЋаЦўЅ—кЛeрнЛП<ћ@ љl‚Y­3Ž{O=§ДЯ<&§хjЧ‹ЙgлЏŽЛЇ”о мqZЅmZ[Wvt сMчѓня~З#Ž0иЩ%0=ŽЯі8ІБП7Я,аžЮ<{Ц1§€ э™3г:“ШЖй•dLіЋ§о/уљc0ёі8хŒмvз6О2e3Пy6eтeG\Ц`ІO•ЪтbL•>ј~$ЪUpwк Т‚дЭˆ?Ќз”gч г^.jŸxт %‚Loђšђ<Џі4Ьoяhx$'„nЂуёІW,ŽоТC$29T‰^@ФŒ;ЪЅ &ƒќ@РИ‡ k3AH $5WеŠ#їВДеBW7АСeЕ“Jђ$‚kmoЕDfŒ$Z)ЖЅ Д9Ysд^_]MНЎЉО^вGІЫЅs—ф<іў,?>(УЧ@!Л7ю†x%мI…Ф%т?‘MR”1rмHYИbЁl§`ЋЄЄЅHrJВ—*–іЯЦѓйєѓ$pЃ іH#ОР%-#Mї+п›…2}$!1A~№ыџ%‰Љ‰šљ——Ыс}‡%eHŠ 6H}к :HЕЬhZПВЂ2U–ЙчЫї Ѕў \оы­ЯUђ­нš› Нw7п­6%z§LНћrŒ9Y0ЊxНЧ.„ЄC эЪС&ѕu&Ѕ•—Ј”(‰I‰ѓ‘†˜a‚”b jякAQ$#œkiМŒ=˘`ЈEƒЕ†kG€8ГЭ?Bš+`ІЌФЪ NљXWЮыИк`ь Š3tВ;8}рn•Дaщ8bЩ€CТCeёвХZ$Я&Rы“v˜fТф‰€І€gђє) ”VƒйmjIi‘фGлdб‹4/пГ=LMxМс1ФЙзaVF#Y‹ЧРЇзDФ7у:Эгp_$‹•ЙѓFтОfЗ|рЕњŒ1ЫМ qq2aBŠмsЯdX5ЏїSђ‹_,€cзщpьšƒєўАЇъЮГхЄШNFXС7z№PЉМђЪQy№С) ІГa г)З-'ЩЉ0ыvАPОљЭ…0< АжУš%ŽEцЯ}р8 БнѓчЮA)цˆ/fЃпyч=ГIї8Дey№рA8з<ЇјШЯЯ—№Ž0 ћ'O—mлЖЪОЏŽ>5Сu­ђ4Ѕї^ |С0 ЖFIOtGЮN­њ"Ою&'BaЉOЋ47дJCmŽ: eк&C‡„Щг_ё‘2'41_њя Xчž! ‚э\Тр07„DЎХ аP­•/Ј?#—ЗiйQ>RYз(п6 D,AОДђwpЧВ[x0 ОМ` ЁОО bZВœ #mLЊAx т˜Ќ.RќE пџлxp“ЭсеЪЯўПHг ?§щ <—Ыўп5xN‘<7O-ІззЗ`я‹ЫvYzw‚,^˜зW’ ƒКГf&ЫІЭЇ№NфЃэЧхїП?/п. Vя-ёnі ПHœ]UM•:ЅЅxšT"Єж(ХЂДV_YIБ5д`yŸ#эƒ>ѓoЩIИ‚ЙїОћРЉЇы{#:ея/М№bР†'љ"Ѕ КaиOŒGЗгxw„з]?Яѓ%І%KLZˆЃŸЏМјт^YЖtДќзo–СYŠ6їэ/—элЯ‚{K•wHUuИ8ТFЫ‘+I<ѓЭ-ђoПZ,ї?*Лїху]МJ7ЉЈ•Ю!kж!._rЄфчWТ™)Ž”€x+'ки эм6щ:ј[ЃіH]}€ќnБ>#-Ћ0 рќьСNдH№L їШРїМчеЄѕr‚KоЋ^ є„Їѓ+9aUI8зК‰bwрєAyЎС?аЧЬ •! єтуз9Сг|›ЧЮ\n“я|Е;u$LЫ4дЦ„юpN‡=M?PЪѕUЃАщ7J›u’сЇМщW-…ЭЅP&БўpХЄ GР& =73).”Ъ?§ѓfЩ>R#џљлer *DТwОГ ‡•0~§;$u0ЉДП,X№Dr‘rщR“ќэ?†ІЋќюХp{{ФœJ0кtцt5ŽIќYюФ™Иь ђ­oэ˜8_е§й?’№@yц™m№z~мЏќяь”иxыиDњА‡(Ч'B|р@і7pbL<…JˆwoqРl`Я:ачм,Йr{А5CќК{ЯtіДі4о{/М№bРЪrƒPЗй8яpОї0ё‰€ЃyєиIИ<’]ѕБ“;ЫhЇгXЫлЅчђК %и2P4йY_n.Uz aф{Lš09#ј10-їуxm“Б(ЇHнDТ™ЇjY№ДЙœrџЪбђ—пЗyЁV~є#юѓ9$ЂЮ={pЯ€3—Xф RюKYˆjnАУ‘žžГфЛvYЛЎЂ#]Y л„уUЌћœјЗ{З9†ŽЕиzп ИБ(B#ЮZэХхs*ДжбšЯq3НMѓbР‹ŠиЕ‚§\{X1o;ШIaтЯ1#Ž-є&№Ај™у8PŸ qе *g\2,•йЛ) еu’‹(X)іъ&Н;ŠbЭvœз ŒЯ}и†rOVžЫШŒs„щ P,‚?Ї#PVmМ,OJhАЏљСуœ’16@Й‡49ХaRдз†j'ес.b8TШ=<жK„їSєцCу№ŸШчЋО'!d*Їnt‚Х% Є VV:ЏиЮ`ЅѓŠc™тпр+ЙлN+.9ЮŒ}жЮTжС%ŸˆKO|šїнНѓ,ЫћьХ€^ t!„dDT9Х&‘#q A‰ –ж@ЪmГћ тS–дUтР{(ќ;РН’Х›н`!=$gйЦxxS(іAœ|§БЫЈrа.ɘжџLKК’9xА@I5mЕrpЫA™АpМ8 \5М3‹В g9МcНtќЫkn~Ўj.IЂ{œОр M?нбlDfяГ X_јlXЋ#%‚wдТН2x8т—}СР~ЗП7ЯW–тёbР‹/, t!„”СŽЬ/фžшoЏ•šzv6ЧžюšїnЎ •z_pДК9-CŽЎY@ Ќr[pFЏ0Ї{8ˆ#­рШЂ’"%n0Ž_@фЦ ‘ --M№lpDк Fm–?4gє-vL}ёоЦžыЫъхркC2bЦЕqк ‡l;Ыqњ’ф9@аZ@ц|ЅЈДX‚C‚%6(V /сp?ФШЉ™x Я†Шч‡єХErіјI‚гпДŒtˆL­=СѕХŠfїu‹Щ‰cџьЁ8ћЋ~’™™й………0Ww^ћbмX™Сё–Юўѕ‘ввR<8Ўо)†о%ЏїС‹/М№Ф@WBшљ–Я˜ЃHЊtХ›^гA-X•˜ђЌЇоџхJNывљKRлX Ѓо1тŽˆ5ѓŽч‰Ю№%Є&@Kœ!ъцЮ]]}ГмџЦ§"0Гф’Шњ4дЯэ):и ЉЯh‘A‘r_рЗ5O'Ќ˜ БїXY])e•›#СВeЭIœ$sЭUЏѕ5U5’[Ю›Šёё&9VhhЙ ž §Ѕ.ЁNE–фкЬ‘ жЌ„mШ0Y— ЫSЇШЊЫ0С†Sіё8”џГ™/HxT˜М]ё')оUfЅe&РMNА  @>с‹OM–§ліЩэїнŽГ~ѕrсд?bд љЭѓП‘{ПВBіДOўЦЃрЄ]2xxК,œГPB#C%чtŽŒуФ…}іg=о ‹—ЋE†р}dX„кЕЃхЮ;яьX@>zXћ;иЌIђѓ $cј(™‹ѕБбБrъє)%„Ыo/Х{яХ€^ X€Mkя‹Л,ОzOѕ<*pkЭа?Їд•VЩБ3y8žб$aБa*Ђtс˜B3 —674‹/4HДаЭа/15›Ц„HLS6YE)Ž„™Аdi8^'ХmЅ’”hЅХ_ŠоШyfЬїс/#'”§џЖЦИkeъмЉВЁ)rёьEЙџ+їЫђЅЫ%~P‚фхТ-арd‰ƒеŠR#Ђ#Є —…НЁ' pŸ0((XоzwЕ”W”uxŸ0gЩEГ?оx§ Е>c,Ъ№=9ЩdЗ3оЈш(uйдS=оx/М№b€РA€œЎkЭf В(№зE1фж@ХdQ2fСwЧXьэe œPˆЋ ZŸ8Ў`~кLЂ#Cвхљ”yaу6љчцљВ(hŽм8Iўљф?Ш#эH{LГ8[,E;(Šх~V5ФŸ яZёhЌTUTuŠо№>&9F9бЕЩ#—Я]­uJiA)і/эŠ7івНїФЙїz8оНџўћхо{ю—ьl,TZZ,Х'к§ѓŸџ “kƒdСќњЮь:ср‘ЦКŠ ‹:ђh„ї^ x1а 8гwЊФXœр­už‹Њ.0“Њ )%чhЎœЩО eЊ$"9BЙ‚€ˆё ёCJќCѓNžЬ–‘я“рQ-_ќђЗ‘ЯЪsiџ[žŠћ R‘"/я–ˆXM тТПŒбУЅЅn•p”ЄЌА FП›р30D6ПНYJ[JѕиEМ`PќЪ ›ћ… )‰Rœ_$kзМ'{6я’ЬБ™J(o1Іл ЂпЏ$jrша!5и% ё– X?zžјЭo~-яПЗћБ!š†QdНuыVM„х=рz§ЦeмИqМЗ–€Ѓпqь­Р‹/:1рTкGi!' jэ) dUќћ!єё„dTтАD~ї—6šo†ŸСжІV9u„„G‡ЋHв|О ”Эпй,ЛVя’IPlЈјс№}hPЈT•TШ_љБФ&ЧЩoз§V šbpSсfHњ X E lc3T[4c\&ƒу?`zfКr!p,‰аЅШдG5V~уЩЭЙ˜FIbbЂИк]ћ\§€х[ОHrо>eЏ|d%№•ЄэYИpЁтьž{VHVжэ0^аЌо&H8ccc;ќ>ѓoЋVщД)г$1Щo{•’nљ!сm€§†X™FйnЕu%6Б_jэЇђўNI’:юЋ{‚”ювeїх4И 09Bža:hЈЄќE Yp№џк0™ђ_8Žьу•ШћkзЩOхљ4p2%1$!KMLE К)CеТј ZЫЦўгТі(Ю_6УƒpxxИLœ0I9AЏЖhJЛНQ<ƒШ„B‰ ї§ИџG \†Aƒ]‘gљcZ:эЅч I/М]о/МАa {­QŠHo­@двжЂћKTŒбƒй4,CТыС…2mC[ƒNЎдeрŠ€ёА''Mј"; vЊ( ž™LiVDЮху&Аn"Zп^ЏgYЫazц319@цcМ)‹i{Д\6ЬЃmН-ЏЛ|іюоѕwœZ5R5‘Шw„Ыьј$Сф{“ЦўŽнЫ`оYOоПWУ@ўю.л0ј<єЉiЮ­діƒЮ›l|є4ІэИЕпw%„œT)ЕЌlїTж€чфЉџа9lялс“АЛ`4Е‘€{OšŸy‘…\^Иr”& Лœжwиљ4ЁЦtДУъ‡Cј.ќL`Н&˜‰„WsoоѕіЪtТ1стСќО*з?˜˜Sйyз7fѕUНl‡gЌДŽ™L_™ыЕъх{Я4j(Юœ<пiЄїOЈИујр7ЫpЋї)ЧЖП[Б-tˆ=аaзљУ=5{Ž%„єБ›илЧюРд˜‰њ#ИщЂ;ЪМA№9 7U4I@d€Б ёф?#ТфЄLЛуaњXv›Ь™#ВъЭ@Ўї•АјvYДА т:’Щ›H `љІЊЊJ EXH˜Š[ o_тТ”URZЂЧ= bљ$‚ЌŸ"hO"ЩМќзен5 rЗЧЊгн\ЈiЫѓ™TFj‚“^Я{RЛМ&ќєjЯ2hhAЅ]RxzТР@Хћ’ЪhuЕu*яЉ =ž8І~ЕЂЙ ЇфУ3pтСM/­‡Яј/ћпguUЕЮGf‘Ьяйм+Ь6FсГ™8ц|Т s”Ž‚эєЯw%њ™­ƒЛ3ћИдO]œ 3"Р{3љЂЏAlкЄЎ(™глdS‰Џфэ‰B'ћЪПнUюч Лт+‹.ШN˜` њ Му;ф“=ŸШфY“a€wю‘ёгЦЫ…‹фшОЃввд"#ЦIS'Щ–ѕ›%Ч.†ŽЩ” г&‚}€}I‡d’-їq9sъ ъŽ–Š– йГeцM€›љYѓхРОrњиiL`Nхъп›%ф|Зnм* —,”K/ЪО­{Ѕћ‹ю^$••ђюЫя Ѕ/\ОŽ“ЋeѕVУ€KR‡ЄЪМХѓeяжн2ыЖYТ##ПћйяdмŒё*Щ>-™ˆ+Ш-ЄAIZNDŒХ1.ОsБй{DЦ#mxXИёМчY™НhЖьТЙЪyKчYЈЖ–ъzЯqiV—н­­ зї——˜“ ЁY2ом__I_МTw\tсPО>kмБўžФˆнѕХbkж­•ћюНW“ BƒНщS7Хэ7ZѓжззыЂ‚ZэЌŸq†ЈіЎ0YKШŸМQ&/љТђщ9іlЛŒІ‹EхљБИCзМ&жКšЙѕеС`ЕЌЙАОZžЎ%\љФВШ™SLЭіPы~зљeнйїeх)h>)‘>ёВ(rЙ<6ѕ1ЩHЮИЂ>-Уіэ_YKяcьm6ѓ K3m6uћвB#зл§ыќl‚mp\LтI"H$щ"9A-Љё‘C5HŽ&BхП\Y'Я}ЅBюИ міД˜мШ Й Rмђю&™•5[&Эš$GїеAŸ1_'gvяеj ђЯ\4Sц/›'oи!ѕ.и0=sQ†ŽЮ”9sч€аэ’  Ytз"фЂУ`_).(ж§NTДušb—}р˜”W–KiQЉDFDЪно#Ѕee’w)ћšў’œ р"пmLž=E&Юœ(ЋџИZRЇШ’—Шм%s•›lЌo”‘cGЪВ•ЫхаОУRUW[Љ’œž"A>A’9!CБЗС 61Ve№6Bл3чTŽd­Шв‰тШ'GTlKѓtAјЗЧ~ Ž–мKЙBѓhГ–ЬTДљR,б‡V'rА~š_GŸиЦЫc0хvЄqпєєоЄџЂ\;№2РpgртDNБлІ›d#~ыіlж{>oкНI6уyћоэВ~лzй`ŸNќєNBу іЩбєЉОpџ1qfт4WюбЏ_П^S™…гz{œЉkчЮj‚iMяљMые=о9'k‘˜Gв’`ж1%HзАPKЊЁŸ ВёLэ5с@Z?aggкyЃWЭVЗA№А!{ƒь(кІтИФБrћ;хG“ўЗ *ГўЛrтrЖжХ|І.ћН_іxо›аSг6Іы(лжfяYгvхЏ)ЉуЏЫddВѕбеъы>*Ќ‡bzQ‘б 'Ф e Њ8CхоЗЊЗbЋРсiэВlt\ЕKBXE’дмф{ гЃ^ь аh‰ŒЁ2(„СДIzѓрRвuК№Œ,?(!С‘RуЊ’rзe™;SJUHВ+Uю—ќ_іО0ЫъъџdяB™ь ВG тоЕеZG‡­­џЖ_ћu|пWЕZїFEФС–-{…0B d/Вїџї;onxђ0aZМyžч>w?їо3юЙчќsыџISѓic"щщђЃќHђ`,Ÿ`EцЌЃг^­}jcО‘ +--UO5ЕqŽІ•ЧјИк!Bі?SkЦіMћzФ•\ 5FннХ#ШCЏМїьхЉJь.§з]л(п^P!‘}ф;ѓOщiт @Ї’*kKhЈ:6Œ{cЎnЎR^X&ћ“іIђЁdˆ“дUSоёођХš­’Yš)‹ž_ЄШм9Љ]›vЊЧA#ЩЩЌ“Z7jдQ|УzдTеш у§ж[a ЧYB{‡HXx˜Œ7R9:жНјD‘•i;ЈЇšlh}хЉJ]<НСбСыFjf*ћT>ўx™ЌXО\ћ‹Leх)mїЩ'хрƒzoђЙXѕь‰љš6лњ.])ўƒЩЩ_ю;ЁрИaп:uiњNК0wйф;KоOќ™,­€1…ВС2џЃKeљЈOe^ЏЄЈЄ”єЊ‚iЯиБ}ч…ђљкЯ•Pф™™ž.яНћŽЌZЙJ‰:ЮЁЫWй|*Ы–-гxD‚G‘еˆГdЩm33N9rX>ќ№CYМx1Ж tМ”Ђм>ќ@гRœK ‘чдЧpЦќ‰9Ч wжд6ЩО§eт јсgђЩОЙ:ЗЎEЎ§еI).ЕYў*Aоwнy—ЬПqОмџ­ћeЭš5:ї™їв%ЪЂE‹дrъђЏ§KыЪЖГŸbМ/AœэлЖi-ќ\ўДѕщўœ}ph^.QQ2)x‚ФФI`SˆфЄ„ŒЉє.чZ^–cyYZ ыБgЯnщ?АП^Шo™›“+я-zOжЎ]лN|“ƒ}џ§ї%''GыN$іЮ;яШъUЋU4ЫqIbр“?‘х˜П„Н№gњь?ŸEо6т€aцЛлЪоЃeяиБУjƒz Іb КИ $аHѓэно(~Š2šЄЂАQnНзQ>_н 1G“ќфЧђЦ+pє ƒкІййфРЎЙхZьѓмЬ\(”x*’Iœ•Ј\œѕ’ЛуИъЦkАŸ˜-‡і’ЉГЇ*Ђ‹Nˆж‰УCўєrA…юЋMž r?HtЬ”+ЄššЛрњilтX!gж{uTЊЁb убѓ9=j|’НђЦ+a“5MЖ~ў…4€ЃыЊИqВcУеЅ 9NPІ‰эЋїcЇУhˆ7wЩь;цˆ—ђwIбŒdx_XыG&{ЗьWи ;uЌ* 3D€ГŒEДШCŸŒЦLPух3чЬ…эЊiЭbеOо•ИќŽ„CЩdа rчwЪNLB^~žlкМю›І€B,’#)GteзЎнњž‹ЦХЊ—аУџ˜фаС2pр }GGЩ7oвОу‘эЛšjйЕk—­я–_‚ОЋЏˆr бСч˜„ƒР‡$  k‹Г”ю(”y'ФС"EŒЖ…ћcеи7|oъЄЉrЖjЗnлЊGоxѓ ™0nЂ"ђѕж+ідSOЩСCuС\ЙrЅІO!+>^о Ђ>гЖ—ЪДiг$!.О}A~я§ї$""Bтbт„{“$Ž™vё‹ЅOŸ>šЄŸЌф?_Ю–Qп-‡ЪхЇХЫЗ†:Ъ?чЩЭ ТO,N€„ЩІ ф†у@[Жl‘#GŽШЊеЋ$*:JХ"”в[њї oМ§†Z[КњъЋeтФ‰њžˆƒмЧћчŸ.D”ѓѕЁ›*k*ЄИЅDхф†B™‰}СЬ§ЧФ3Ф]RіЫЪЪп‰/ітИжNžЬ…TЉZxрl“бYЉыШ›oП)У†S7jЌПAYy™Œ5FыL‘юв%KeЦєъ§ч‹­[”`юЙчdєЈб@ќхВsyР€rееWЩрСƒл[bк—›sHЖQ|рA9|ш ЊДW ўИŒЗ­эя.У› мŠ@wэl–=oЫ™`ѕ{еЩЁїeыjјЬ;%ЫŸ‘х3х–лjФЭ‡Z›Ж Ы"иTO%œЦrO]-БёБˆeу"‰тћХIBПxэlІcиА‘У‘“#ТЛfю5š†ЂIОїѓѕSŽЯ7мzƒІ5яњ РЦ4ўбъMl‚­,ц3qъDELНB{iC‰R›uтt’№~јЈсZ6ЯS1TяљюкfёЂхжУ|ЕіFŒЁiB}BхР‘@ЬcdњфщАИZгžGXD˜ЬП}Ож›ѕр‘ "o_ь;њљЈћ,ЧЖCєZР…ќƒЯсФ=H<o,t•r`?і>1qh”u`` $NO”'NШєщгхйgџ‰EФ[•|† ЂщшEўўhп‘йюСлЫ‹VњюЌЪ с@пнaыЛi‰m}—hы;_Œ _o_ЙЈ}‡ХвбЫIўль‡ПШ•Е^7ЫСݘƒѕђвёЇхsџ52вkД86(‰Њэpu…Є‹ы4д3Ђo$мІЭ’={wыОйј !™‰–Рр ˆ7(rќўОЏv†iЛvљŠхЊ№rу‚1_$HяНEяjОAAAЪ 3џFH‰x4(а?PЦГэƒ3З4ЎМђJйЙsЇŒ3Fг :c|жCњыПЄJ~ГЗќьО >фИЌйP/їп “ŽMй2cJoщтЗГ3ЧГƒ:рУcN­аЂ%Rѕ„Aњ‰а+ ЄMб+MCђG ц$ЧЗŸŸŸL™:UДО8?u †SЊ6Ъ!џтфы./ўъUфц(S-яTМ$аO8$шаfф„œZVжqYПnНЫЬ’д#)’0 П ъ?„ъ іšpOwюus•Јg Ѕ9UеU’–ž&•е•хЅˆ№Ч?љБєŸиYГgыgУ№НHєЌ˜egЃlrм"В‘HXšN#?WЛ$Ьт2Жјє˜П •'Ÿwл].S%_ яэ Я~Z(НњњЪ >ђъКbiuї7/7,ё68ЗA`й™йЊдBQr‰4g­#Wš`Г‚ 3 /†унМZСњЮzЯ8ЦPг№ŸЦу;я­&сЬ=пйзѕ2щъъT‹•Љ‰шШэ2?">ўу=WюK’Jkqр„Гг.АŽ\,RSгp&XюМћNхpщШyліэК@PŸ@u№ЊЊ*?ђёGoDp5жед_ўў˜ОKCпљћiпQŠОлО}‡6чтK d€”=ћš‹й~D>ќј"і†K+ptKJГDŸ/^Qуф6 a7xѕvШ§”Ќ>КF6zь‘MtЮ‘Ђ8’ŠZЛvя’ЉSІB Йsv‚F‘кt ШЄЄ$œ}ГkиИaЃ$ЩSкˆёAб(ї™vмLкЭ>xњŸOЫЯŸxRNUVР3J’"ЇМ‚<усцЁтxігЦMБŸЗ[mгI7Ч•цТЩ‚Z rƒшдKжІ4Ъє‡|p ЁIЪЋ›х;їіeR"ŽФії„ дш|(?Я,„ђђr —cЊЌ–u<[ПGqQБ"z"?ІуЖ\Њс”4 Л8e1uуCтeSfКДИџKnpŸ$ФРЕŸ‹”цIVUІ@ыxNSЂD„E€Ќ•єДcђУ§Pмр!ƒху–Ѓ–єЌtсўЗ}Тњ„i_янЗWFŽЉu&‚Ѓdmр€pо ':qNnXПAІL™‚яЖ_ѕ5јѓNфЗЗ†{Џ—є!›••#?јб”Й?~<ЖРцџЗ<ЅЦ–№[ дљУАч3?B@ЅЩБєLёђЯ@Јытпљ,фrшъџЊ!и^Х wУ2TС‡ћ`чЖхš 62ђёr!\$( jј2АŸ‹є вУ Œq…!o,j•Ц–’}ХE„дaBB‚єд_м<(ЁЪoЬЙ1ŽщSsoЎЌЛygкaо™pыѕLяьѓљЊ4жїжr­їІ,ћ0Ж*хўўўŠЄuџІ-’}“–Wі1ЭЗ–ЄJЈ:NNŽЪАА0fъЄч№‡ъѓTPJ†hЏ?ЈNRЦЌ[ъ™q,uі–€€§Бl.j[IdtЌLž:YПхљжуЊўЕ'9нwЩњЮ{Ќѕ іEЬQ}c.ZпБZdсЖяќžTцVIОW#cMuН4еДЊЋДŸMјќ`РdстЗхž;яжoЫ§KЮIrlыж~ЎF"ЎКђ*ELь№Еиk+)-‘ыц\ЇHbгЦM Ž*%\Ш soЂu—ЌcY’››ЃJзcёѕѓеэŒдTptЕ‚;ЄАарPх"ГВВd Dђ<КаЏ_?4p ФЇ+TtЧqе…ƒаo‰‹ђљK*ЅЪпSЎыы$п ЎЦ•6tmCs…Р4eрШЙ/˜‹ѓН[ОиQчdУВьеЋVЉ/Я+ЏКRЭEЪ[О#F(ЁЊм‘&%!4Voђе›.ўсž0 ˆ>}фdЪ љИj­œp[#ѓ‡п'Нbd‡гj)sJ“н™"OЧ?+ƒЃ†J:Ів ЎЖСг6pЌeu•В.|ˆќщЂ<1ѕžhВк&мZŽЙчЄes 4сџ–WіўYћюЌэD| qЌ†gљA5nДpд!xдШ‘шлnфu†‚H sВ‘z$˜яo_GkYм‹xё…хю{юVФi}w†bў-ƒЯЇяюКч.]„/Fп‘Ѓ)/-ŠјЯІм“y'eо‚yВy§f]јЌёMœ3…Q‘Š\тuз]grЦ{Юu+xЦˆ–eЅeрN\еЗi*ДBћџОJdАПмсT)o?ŒuЃДЄ1ЗЌ?ЫьLеФ1WЦ%и{ѓў\Ў$§сnмVQy‘ќiЭхџЊў!Bg1иФž‰є-y&цc™{ХмEh}0ї‰О ьПŸљc_S\šsб3fЬјR6ц{а  СфЧ+X&7ЈoєlˆЏte:иуяи‘ДXТ§Бfgl1ƒЩXjqupUъм):˜b3ƒ“ч)Ѕ(в˜+3eўл]Л8А/IЛлЌ–е6зЬшЌ|ѓMљŽš„&NјЯE‚чгwPР?aќEC‚іпЮ,vісц{і ю%kVЌQщŒ5Žu,˜{ћ+5<ЩсјŽР|M<>[яэ‘ ѕуАožрJхЯг рY-}АfУт&§•u1ыŒЩг\зzoњУ>ѓ}6љіђя%šїgЙ.хz9” ­bpх^žо’8y†Фі‰бbОЊ>жїL`žM…‘ШэеЫF1>СФЗ~fђ4ёкі5“тGФHбЖСˆ›ž h3ЙРЊ’*9vј˜ДКр ]% ‘O€Ф ‰W/r†ˆˆцQжжзЪG+—Jƒc“TAфрлЄЦVB†ЭŽ"uЈt”Ъу•š'Є^‘‘•Uˆм223$ 8@ќ}§UšZa^ј‡WЊ@BФzјрaйГeZ• щвОџжГ;їп vњa;ЖУL†ŽЁ_~Ђ2„ЎІ1ёџ-Ўчгw7^кОГ.vѕ=ЙюйƒѕЛš{ћЋ™[OцcтйпŸ­ ы;ІЗцiђыъ!?ћvИ5j—яMцЪ„жћ.gtŽй77™1tКў:ЫцЋъcџоў™yк‡бW)жў4ewfо™ы6б:™&EЛAхчц‹goO ЃЗЁ jћЎ’О+MЪŠЫ$м+М]™ƒи„3:?=ђ3(&§šжП€F‘ˆHС щ+2м#Tfжоƒ‡Ž@˜ 6ќФё“zЄ€›ЙЋ—Ќ–Р@™s+ŽрИBцбLлAž 0ж+4<АЮ:хAуДOЛТJЧмПyВіР……$bјяш~єдОгяy ?Љ§тл§žќrŠyZкТхˆ` ВєаПfn™іp]ЖЧ>ќB>›ђ­yš0sх;ы=ŸЯ€љъ"СEњВд>tuv“†ŠЉ‡:ЌxCs т`MUџYЬОЈЈС/JЖЫ@wЭD™єХ2Il­?—#ВјкUт ѓaЯч=-%•хэ‹'Љ r‚)Pё=АeŸŒФёŸОюіыєьЕ$iЧ’yoњd“мѓЃ{dѓЊM8Гз(ЃЦŽRqkЏоНTIШp—Љ‡/џl1‡ЈLUCім:_7Lќ&дRЃІ-№№[~]ы3ѕУцЪмЌї]Ы§мcq!Ѓд‡cƒ{T]њІ\{zрЇgгœ!ЈxB‰д—@зЭЖtђњKё/QП•ЉЈqMы2ќэуРЌѕЈo‡АЏЁўьc!PcиОсJoЬ9ѓ~ЌfpAў\ЄN hЄ‡xѓЉd1яoЮ†VY‘‹де)rЄЖЊ'дnu2рУpH‘км ЩђйЋ}Pn0П№„T.•мР‰ѓшлжj\ЩyO?.АыYпXЏ‹4-ЪєMшЋGa7Ѕ:En~рf7xœxјxH&ЬŠsoч‡ŒГй в—џЎ™`•˜р8дglN]'“т%Гш˜”TЩ Уn”^~gжрьz‰]‹IТoJАЮэ3‰ЎхњѕФтј4m0WkM^Z”/‡Њ@дWжЫ/nі—ЈpOƒu=3qПŽЖыœ7ЈWXЂЊ‚KК/вЗШС“ѕ|%зТ9ƒцЪЈиQЪL˜Кš+чъЅЈЗЕ_Эё=SіщС‚M/—+Я7R%6#9SŠsЪЄЙgћ *mЎj–ШЩQЊ у‚ЖE@—F’˜OˆOм2 іќ<\ХЭе –`БJ7Ž80паXќgы~(Z[Ё‡‡u­ƒ‰R\X"aQa@Š!ђёыЫ$р‰5{F1“”œH0щpDЅ›UХиyО“DЧФ|Ѓ0ЃНдљPwЫQ3QЬРЕ6Йœщ}+Ю7РFjь’ ЁЊFУŽ/#З’›Сw&˜ќyЯ< 0м”aо™ИіёЬ{^­щJр „gЗтттTДЧsLgKkвѓz)СД“зfєM0ьХ5тЌWCЈМ•ќŠ ѓ#љЇђdOс6йPњ7 є№…aх >]кчi—}™ў Љ1šР"aЪыj5яЖOcвšrLдГh<л7dˆЭ2yзЎІо\—ј_уMЧYлpФи=P"ђOЏ и-ўa­-"ˆг…}›љ–ЃXћ‡їmcšy›ђ:$1XƒxўЯ„ё§Й9=JЬN–рсб%’Y-%Rk8SќfШ[ћо’]ЧvЩ§‰ї‹‹мOЕЕ—u3ѕГжУОюіЯЌЇ}˜y6m0љ’K%ф{fюЭ36Ек’AУёr6„жJzEїŸ`iW_QЏЌЏO(œ‰bRZ­Ї0.mtОіФBйЕ~—”тЉžA[Š[#aK…ќќі_+‡їЃч~дЁKјБЉA666y&…ž(2ђр)wџјmа6(;О џhR,ЄOˆдт}єнњр­:и]`аjaЅC!п<ш€%Ђк‡ЩJrДгH0ƒ—о8 N‰Э;ыћ |›ДДT=і`оsmсb{hѓFIЛяA щ 'Уй"yH™М_aggЕL™Ьп€™<|6їіёЬГyoKЫ+<ѓФЭД еžуu––с—LнymСVB˜oИŒ4Qbнр№sšŒщ;RЅрMфЁОЏKАKИ”V—Kˆ+йРфqІч}ћіЩАaУєЕ}\“І+W[[pр=]hцŒ?і#­УDGGыЕ'"ТЮкfгOчиj{ b:мпIaЫч08B6‘Ўпh~Œc‰ =ћ€аЯ„м788X3хќ1sу|њ™Љб}%˜ˆe)KƒkГћc;ЊV†M—12N[хГSKdЩŽХrыФ;tdЙ4.@Cк1бАBƒvu6іMX[o|)Žyoпž3eў4юaŒKыQ4DЋЬ(aDуЉ ЁaŸцђxЦ сўŸ7lіђП?5oдŽш-­`'xК{ЪєYгeў=7ЪьзъБ†iзO“Йw_/У† SSiqткE/še4Ж@#|HH(іœ|СUиЈŒ € =oШ cZ+рррТыъCвЫв!-уСVЃЗОЗTщ›[ЛрPtuv•`\—д<žР~Ѕ’n&CmmМіЪ‹jdб{яIFzF{оыЇФiьqЙr€c >њЩћ’Дє-йћб;rxѕЩ=Мvmћˆ+D\DXDР$rЈtУ+їм'f<РЇjЃмУwœˆEEE—“V.ъБYЯ6иl!к,ч0^ ?гi+ѓbž,‹WЪя)аь^-aA2)jВќЉ`$Uя)ƒЏ•I­}%ЂЮ‹N@{UљMиolїy lћˆ l'­‘;.)9Ї=ƒnо0пяPVЌА &'R`9М^>pz!Ў†эбg^<& эenЦ\eГќўщI>Œъ€Э›Зhrџ;';Gо_єО†ГЭДЅZ ы8*ŠМљц›0t OЦ'" eŽзѓ–З7{/\/ŠЇЋ—x`н+oЩ“aўЃ%љ‹(:ЩFЫпв.EХњMX& \ѕѕ’r”*ћЇ KJM8яLчЧ‘™kœ4Ю6АlŽ/ЮZ2щHбУ;ƒ];wЩ з\Ђ9Mœ9пыБРуд›э§iaigi{t9BšXгYw Ž)ДЯ:ГЭЩ8œМђ\ря^њ.X†{уЃ3ЈАfˆbлŽсу"NлyA~+(ћ§PЌ›VцєЧЖЦэюН.ќlXЧ"Л›ЭYуфrжHс%ћЋЁЁ^mUіщнGJЫJлKaШ-N…Ё`Nуsb№š cйсQrЭезРlИPЧЋНяуи*B5hL­­иАJ>‡‰:E{—BYTKПШ:L 3—ЬеЎьqёЎ ћŠNЎи№%fkВћf`hоƒччэT›СZOoGxŸpZДis™Д_К"HУП|.ќ˜<ЯШКЉ§W-ліЯ%?kыD Т‰{PеcЖЇ“‹m4}fŸюLЯ:8-y1ZЯ_Мt)ЈкRљй“?зЄжЭnrVЄ ˜КаTпш ювKrNфиЂДu}&щУ':F†ЉПжR=ўREЋ+`CЖб)@ЖbпЊЅй–їŽлхЖ[nСB5§B›ЁbtЕ™PЬœœнБуЧщЁэєŒtИѕ9Љѕілo—iSЇЉ(7ЄwЈ.Bє`Рšy0­ЄєxNЋИЄVѕгUк0wЮ\™wУ|‰‰УфN§Z!ЇE-†BfNД,7’Qъ*?8caџёШzi)к&NtƒДћ]œЯжлGћ€{ѕє‚м+дzЉŠСц\7ƒэp;Й!вжхK/НЈдМЏЏo—ОkeВwЯn=њ еOкЗ_zЯКжіэ/“П”.RгЪхБПф‹3”ђ~ѓзtљЏ'рвщПœ%ъж,y§ћўrя­жУі­ђќѓЯЋнЬЯзСжЬšЧжэлфўя< œ№sџzNЦ\1FэІЮ™3Gп“0И§Ж;T”JŸ………­яЮѕ9ЫМ†lЉЉЏ”§ŸТ.эиIоuPz ’Mеkd]н№Ђ4Ѓqєшеці†х™cщЧ€OBћ4@Вa$ќkЇд€ž#hgt>цХОœѓЅ<,<њЈlGМmћVu'5mЦ4Йщж›е0њЮн;р+ЧзрЬМ ВP3oSR+eйщр‰ m~ŠqгЖX0СpёnЌ‚ѓ[,РVde&Ч'u?wos•W_ФŠ,‘З_ ’ї^я%жOЖя ЩЕГwŸ~€.р*Ц3Ћ§АmiљЮХСEW’"ЊЗѓДЇ?~{~–ћ4Š`QћЮ/‰XЌРpG=Si ч=•MсуKяM;Каf7GŠ+mкЕLKb„"ДцнћŽ7Д‹MЌuЅhЇ3u~КZ"ЅG %IёЄB[=ЁбFAe`щA‰†% ЧHйЦвзЉZв`7Н bNМwСž T'iBŸ№pх<щa›”+“Ÿjямk IЖ“Й'T­ŸG2xf1І )зƒУЅЇ ‚1јЭ{rЗO­XБBш‹’”H€УTNqИ/M…šЏ 8ќˆг‹БЇZе"'jМб6'™—ˆ§xиo-]!n Wсь.Јю‚]тPVЈUЅСъ‘ЃFЊУуУ‡У}Pјѓ|T-1­B{9niЫьс„с=Пqw@‰2$8|(E"ЃЂ|Oш>X*8kњЩdџЌD”єА?lЖёcйUвџ[Чdfbˆ ˆі’п§ЎAџнQщю%9‹ЂхіyaZѓfс"pœбŸпќљѓхџ§G)),ж1IЩƒЧйцˆЋ9NIt Ј˜{дc>ЮМ;Ї+Ц‡ЬHn,]&ЋЊ>–ИY}х~ё7ЩHЭч~"ЫЊ_W p0юЖoВ_2Є5ёr,ыŒЙ€“l XC0пu0 ВэmrNБрOœ<ЁGgЦŽЇH“ї‡™лЌЧ$4діЧЬIIЕьДєT™>c&$|џŽ€Nь.r%фgMя€WMрН<}%2аšŸЎrЭŒ@Йя[.Ау!wНс‡ѓLДQJЄcMyњž†ЖP Ђ5WЦАо3јЮщ˜–‹?$НЛчdцHEi…ž,”ЪŠJ ["IІбИšжQЇЕ ыН}yt€iђHк™ЄљРЁV‡щH‘€ѕg<RUY­Ю‡Ÿ„yѓjъbтђjъ@“wYйYR^UaC.ш?Цw…’SzZ:,Юя‡ылfїG}Є“€ (ОrћњЄƒвиXrOGTќИrѕ 8‘Јяu%ЁуоžЫџќ_т‘јV‘T–- ›NHќЉB.%2Тёˆк v€r“k!‡FИ8*qœЈЎйQ†ѕvOчFљЋoxЙc'a–8РДЁѕцFНДТЃс`ђi…G/oјЋж§œдЃЉв'4LNфhqЧrфђй]Ie8іЫоzл­B—:єЖа;ѓд3шƒ˜Џ бкє>Aё;у€&з Кxš{§\™4i’\ Щ“ы §Vcс—ЛPzaЕхpУф 7Lо S›вœу0e_Ј+июКaвfзœм:ŠF­uтИЫЬpУцГƒ„D5Щ'лЌš $ЃТMŠЊ]фцёtE‚Н*Ф3ƒдЄчb_‰ Џ” Hk"3r†J%хЪўр?.мъc m!т!{_ƒ0/w/uCп4ецС­"]*щpсфZЉЮрѕ™–?tR№ Ѓцk39ФЇ‰ђ ”Ч…„žцЙ В№‰Ћ ‘mяˆо0PфOЄoѕ4DuB‚ ?Мб5A‰ˆuі ФaU”СrЙСЭ=[7ZќСтnИ(і7'Ё›“›"А'<)qЃт%6:FђцJŸШ>шЋ&ЩЪЭ“мщъ.‡}IхrGЌ/7ЪщяŽљаU)ERЙЋ ЛмЗТˆЎРt”Vpžq|S21=1Qћƒ.І8Wiђ‘юЅ8і9OИ>P"Сў`П3œ9Ч*ПOWњнОiY†п Ф?D†Е “7SA$z–~Н EP {[жЫч8fsmЮ4љнД?‰/;ГnœПЦ€ЫЅ{Ѕ@ŒљУF(rуYmŽћpHbШе2M4О'• уБgŸ?”žpŸ“kћ"c-\цаaCЕ=tлDУ Ь‡ыЫa?б›)›э9Эz˜ж]юкЃl‡@1-ъђ•ФV ‡H‚уP’3kd{К‡Œ˜в"ЧšœЄo}Ф5Ы?nƒ?Џ GUМEэРIIюjпЮНВ{Ыnё‚ЬП$ЏDxђйДb“$ЮС …XpнJLОj’ЄLUNЏЪ>ОўО2sЮUВtс9qьИL™3›Я}хƒз>PфДњƒ5ђычўŸьоБ["Ђ#дЬбО­ћєььywЯ—эЖЫ>˜ƒ‹щ-E'АйўНлсGЭMV~АJЎПэz9А' g/гЅтLz”ЇH2ywВєя+SЏ™*…y…ђбсИ‰ЛjП^wч\еф‡Н0"bR‘дь,./–8W9tЬPЩLЪР8љѓу–IWOвVТBТ”"KKN“™ѓgЪіuлхЁп?„С o˜mмП‘?еъЙР™ХЭˆ>ˆЈ `"Aў˜'•LZ}hћ6;КzљHXl –XИЇЯ‚Х x5ЧbУIС‚@D›mN&ѕєіаƒс#FŽрЅаЯ›Œgl†БмфЯ ЙY=r[п3у№зЁ-жHћЇ$Ю’ЊйePpЋєыфх6lД\“ў"ё-‘Ё‰9їБеѕІˆ‹дОxfа F,Ї§ƒКЛ c xtLД&хиa^ў тБОЗƒёkйаo8ШuѕFЄеI9кUрksšЫv9R>нІ\рљГлOBJ"ЦО6§mв0мъЕљvИf2Тo”Эў›хйНOЫя ž{jЫэƒџ.w^s—„„(ЁlŽq0a"@tАŸпt^l€iˆИЧЗЭq†“Хќ Ыјb[:=оX tІ%XЫў2"dŒnH'§п№§› ъ„Цѓ›r<рJ+1ц|йЉz'9R‡`ˆќМZфІ+Ёyш ‹4ˆLЭQ‚u‘uЏoЎ—ЛШ-8CШГш…EКяжЄf№4длDaЬУ”Э{ŸЭ‚Ћ=№љЌ}<$уЉ эWїikк нjЋЙоŸnЇiŽщ?г~†›03nMŸ˜wŒkюлз> 9ћІc^dЬw`ŠЩƒ&ЫАшaђчВП*.q†Є- мЁ#тRZdЖKьП‰љ†ЬЃCьžЕL”Э8ќQ‚@ЎбЖ7ˆ"AЕщ:Рšс=лD‰›Щ“љГ,ыxш2ц№CВЃšA‰ё^?*F%ї7\|]!FдО”Љc›А(:bЈIЦФзB$Щc 2айЎ: И—hTь>цУтэы-ўоўx еРсŠ ( фG!’–-љЧѓЅO, >.У§ƒ§5 v›@ŸРƒuD(|]zJtBДэƒЃr4іЭНBr У@ѕ0&D’W„E‡i=њD†i#XЇа PXа9Ѕ_˜vЙ %^—Јд)&ŠhЉ-ъ‘IH€>‡G…Ћ2пyИxшFЖЛ‹;ъПiиЇёwѕ—SхЇДЌwLџ,“^ZїBh[ік_–юX"‡гi~бббђъSЏJД sГrЅИЌDFЎb^v!ЧЏБЫjЌЙВ жЩЌ}ў7Рwія9љŒ8оМ3W“ЎГ+уPДЧŸSѓlЎ_•п™в1§йвvxwК™Іи‹v5хZћŽЃкЖЋLЏI№щОбwmп‚щMІ’іЯж>Бо›ј]Mяsььгк—mвt–пзfъХ>6[Юи&€LдкКекіьлi’tnпGжИцО§ѓЖœљЦZw3ЗLl_Oˆ§ёГЖ“№Uѕ3y›є=[У(}1SћuТк~ы=Ы"фТmЗ)і2ПВ9ЇёQ—уцлЦУлХ&BсЊм‚8zd“œЌ–@7ЙёЪFм7Р0Д ФVN’WPзOиWѕ;­§H$Смќ Ћ>] Фф.IлїЫœлцHeY•l\Ем”—КqКіІk%RТ ~ы{JкС4§,еP@1š˜}"њШђEЫЅќЪrљлџ&ЯЎxNїXху™Ч9БЄ$ЅhћЙя`,ЎS‘{ŠфрV}МJf^?e%ЈNP(TлЁaЉѕxЁ:|HтХ Ы&b$›D…­єdІeJjrЊФє‹‘иБњnWв.E~,‡јЕПН&ЁВs§N>v8<{РBLBЄ<ѓ‹Їф‘п_ €ыaМ€ZЉЉRс@ЙY*эГH=в?9^=|нЖрщЫюќAvœмpЌr<ЭбuaШ›ad4Эфе1б:\ЎqЯаw\љ•Z[9ВI8кШGmfњѕBtПЧЅ)'$ОP‘Ыа‘D€умcO’x&!h€ Ьlžі?лпЦ!%@єšЁv•л*ЮяaхР”hЙHuжQиVnЇ§вжЧŸ2.™UВŒ(Ы|їЗX*аЧ6ePYЊ,u+Ы@ФIpvН0 /Ч$ї—.n”Л'ћШ№)ѕ@dM0$ы-Нћ5С qН\y­7,ˆДШ”)м77Їœ&Jd|”4д5ЈЈБМЄ\FLЁ])|%Кcџmђе“ѕпјh=л‚.уgŒ"(?œЗЂЕєVэnжs(‚Мњ–ЋБWxh 842&REœуЇWNŒя||•Ыrѓ„Вђrqwб‰Ч}ДˆјuaC ўс}УuOЧ7иWЪJЫ uз[9BюU’ъііW Oœ|YGГ$‡eiS5vV9Ају{њed8 “ѓ926J†aя”fќаE˜­Nд&є’Џ  №ш>3{Jс‘›ў4i:‹ѓu†™>&ЁFPЖ№(’Ž9\›аъf9a pФ*“OНMПœoLЏs Ф& FЖЬ›Zю<‡­JyИчі ч:ЯVOыЗЕо›4†~$бФ>хzf?^€)Hjpе&2дезoРОH<4шF Гф—СН'UФ$ЇФMF4сЌšЋƒ|”у.Пi&еqК)J$—DgРх@8бсЊНЩ3>SЇMELл?Zhчъ)SЇД‡Qшч.+SЫФœOяOљќ“JiuЦѕ‚і#bл…Э 8”–Ти†Ю&hwв\MЋХЛЉ”6Ф@C хBDa`ѕ-рŽ№q”ВA}ЯW чТЅх{ц­ЙтžЧ/Ц|ъZрЄ’љс™?ОcЛЩ=™ВnюYЏš–гgВŒЌяѕCєщлG‚{KўQмУ8Ьƒmцѕ&˜2ЉХй„cДЄЊиос/:‚Rq|wŽ eГрЮт uY ŒAu–e ˜њ‘ћЬ/( v?%Ь{іЩХжA)UД›ŠJ—ЂЬЏjыФ§lRз*2B?А'в`Ыс…]8:ˆф{“pшпс•кгД-Lh…уе–ЃFг?вh’ЮуAБЕ}_™|)Ж#ёУХšˆЦ>ощRПО;эc|sЮBЧ:В%-ђ›ЗŠфеVЈСІWЪЁŸтшA?Ь Ю[л<В%фєљъqЪђШВ_Œ”DгŸУ­;ч/ИX%21>vgэ–OS?•%ЛЄА!CœZ]хІаЛфіБwHdpЄŽ'ЖЪЬ7ГПЯІM^ћиЦтS1s5I.ЃЋu ˜{sэN3квXЖ3Ш Tиа@|ўDN­2 СC"CˆZАЙэЛ•Xl‰І p`r€ Сй6Њзѓž\?Œ" +bш,ЬфХ+уš8њмЖаАHnЭЯЄey:k˜‡IcЭЏ-ЬдЋCоviXŽљ1щјууsЊЮЋ†та8mHа„йЎM ОБѕЃЩћ\ЏЖœи~юu–KPXœ7ѕ‘ТЦ`лЏЁ—феHn…П”ж‡УX$ФУ07ШШШh?ФЖY'ыC0ѕтНyoо™gѓЮфaŸЦ }= c&О5ІЕOЧxіqЌёЬ;лѕt§MИЉŸ;ћiEДЖ;Ф+­q=9rЌФA~yPф= ТZlФŽFЕфeвkоvУ8?ьЫэцlqlнoЂwШ‡пšљв0;EwЦ@Л}Y_їs{хqcfЉ>7кРŽблUтћzс˜Š;ц—mЫЧіож њлкЌщ‘УЬїe9 7ЯЋWЏжГЖ g˜)ГЛWІ'%˜G6ШчЙЋФУзC… ’ЩQ8;8њАM$і9Vй—щЌх™БРpSOѓо>Ьў™ё˜І={a&œё |6`оѓjыQхwЬ‚eDЅ&њхsе†БРŠ›{vnwiIUb/ЮлзЋQЁЅ7]нсaћЕJ‘Б,XџрІ nxoЌƒсМˆ@ў­э'Дъžв^2˜žž.RRу,ПмT#бИVbП%ЏКUЖCФ[ˆу8€Мћ^7ёqГ™fЃJ6ї? іпŽжfЬ99ыbТИіЯ уИВЇ–p"DюiXС>Ž}оіЯжДМ7хв—)ъЋвичqњЙUNVЃ€Fu_џV™лъ(IyшЧЂSт -AР§-9ЂЕ—,X<ЁЕŠВ ™>s†КМЩЬЬ”Х,–ЧєИ†фNЖяиЎ6Y%’­лЖЊ{ГZŸ3wn‡ƒђЇыбёŽmЄ2ФГЯ<Ћ[cЧеo ћRX yН\Р|žЌƒE™в’:гp”˜ ˜ЬЎ‘ьмfxВqЦPuQ#кЛwяж>Ђї ЃЇAx,UлnЏьv-Ыѓ]“АєQь˜Y˜)лŠv@gС_ŠkђЅЂ)OІ‡^)•ЉЕу+3&Ъ?ЗќŸќuўSЖКЁŽYYYђцыoТшїwЕ џœgfЬšofІьуиЯO9~ќxЛ›/“ЏLKЯ4 .”‡yˆxBч''>oРAcГѓ†›Ы€‚tЃ––LkU”у Ъ‰ юoaad‹‰њлЪ.ЇJ*eй3ЫMOоЈNcKЃкимНyƒ 1@"њpяŽћcЄD№ЗSNЇ=W}Я:ўGšйлŠЁ ›ѕЮXT†…y‰7@au˜Ч:ž“Ћж=;]NТё˜+Ѓ&эX %#GŽhhƒош‰ƒNhЩ§арРфЩ“5/ZЩFhЫё‹-_HqiБŒЛbœаLес#‡Еў<Ќ?FПЛАЬ~ЌiРЇЇSНќ1j„Ќ{CЄяtqzЅДТ&Нцнpƒ`ІЙМW^~Ežxт ЃёИЯ–M›9’ш,€Щ5"В?њ@~№иuп/=5ѕKDСйъxј№aEh”§I№8Ї”О˜Хв~‘<[>_ї;жЙжeВГЊaUЩG^x+WvTyШu}dЭ†V™іPЎ~пEіѓƒ[Ѕš/Є‹3КЩ›6mšОЇAё‡~X†ЗЕHдчЋ+4мїьоIž•%ЏxаФМ ЎlЯт•ц–ЪўuћхріƒrxЯa=BАэ~Љ)ЏБ)— ž‰Kuы?=ћyтЭ_Ъ} џŸќђ­пШ/ќќўнпШЏў\§Qyyщ 0ьjуnЌн@U|.ђTXЁU77ЕcѓЭ}Яэе Уф/ЦЧMЏs–/NЙЩŠ/Љ€vlx„Ÿє †ђо7Еqe›7oVѕpк>ЄMУA@O1‚Ъ IDATr ОЃ ЄB:{%"сDІбрI'СЬ'*vЂMCz …RыяС?тPыДvŸ ФVƒqX^^N(QђБ %Сe Љt#&5НјњыЏƒ#№„Upе e^ЋVЎвВіянЏт[jўОђъ+:с’L†ЬА\k,уаJ?§%Ž>J]CБ к$ХXY(зжIњвXE‚Ќ*н0‘ЂH}Яо=ŽѓЎDnяППHH `Мёж:F9^‡ЊяiЪБ„ ЧѓRИ+„л/‚Еа?еeRмZ"ЁMЁRОНRц„м(YЩpУь.iЮЩ0Ц§W Yпf(#?џЄкŸ§ЩO~ЂФ5оЙзјъыЏЊvjœrozг–MjЈ=ІoŒкŒЅ}кХ‹ۘбc0oђ…іDЉњЋ_ўJтbт$ѓnћЖэJ|RbC"д€iпЩɘ羐SfЩЩIm!‰п6!щх†й@"BRCaƒУр‹.BЕ!М”#ш!o іЃˆ^o}SюŠyѓхХh‘ЗјїУœcХ?ЮK* Ф9iŠIв~eG’ћЃRЩ†хы`lћŽ “јё6… Тo ЇіФgѕ5тeЇ„PЈмcНŽ€ўС\8’Цѕ‡Ј” Њ>.^RSR  -P.ІРQ]{э,pЮАc8DEAдЄ5“ь8"ZТЩЪЮRБ •4hђэ;пўŽr”\шyOъћкйГд(Ј;Дeїэп NІIэО†РЄ=Ь„H1 Хт€HЫў§IК€‡— кpЅ˜‹мЯЃ>ЊšТsЎ›-kрcm l9І‚ЛяОћ`ˆ>џp\%iиŠ#Ѓ€0ЈЅLgж:ЎЯ0vљŽІгjRdж‘+ЄЧTЅтO2}Фх9VdлiёŽЧр8‘В“@„”Рш‘“ADlщq†Q|>{жyсЙIP0|Т* H<№рƒ’|0Y]^}‚bСЭ7KLLЬыЧ|YрЖїюн\qPˆJ…KŸB kc”Сp†Й'ўAЧPJњыoџL“нynђФнН%aТ1йБ2\~ј`”4>)sЏСbя „A#Жу@$pј+.*ёсІ§ЫОœyѕUкRrOЬ›вƒОб}5Œcoњєщ*]˜–8Mэ•žoЗдbLЅ‚(Jѕƒ­ЂyїO‹ИъeТwFШ‡/IР3†ЅvrtiЉщJЄЅ>ЊО?cЁбž› cЦŒiЏ /˜З@ “0ћіхpЛEяДJт–sрзПљЕФbŽ@ƒ•тuJeЂЃmЖfл3kЛй Ђ!=-C y•Š3…{pЏgУ\У/У-,Š>y–ЈЁВAЯИеUУˆ4W5HxщАQm3т:›гO~V6Y†\(AŸО#B&~iђт„…тrЪYўrтrЊхДІ-єіiДuЧ†8/W/cЇ“^]"w|џNeх­к•&Э7зЏПtŒ€›?‘W*>5[ф*_(ѓxB;~АHр?дгaМЮ .}RЁUjГGH„AD@Фж›ЌD"7q1?UqJЄsбтШœ“$ХMu~к3ЄЈЯ'ЊЯё%'ђRј\ќ5(й,bЄ†Y–§a<` &EjТяf`Б^ќоЄmЯЪ>ІJeLSVQ —uVDh”4Жmн$њ]5І<ћƒя`яч\b‘Ћ`ŸВџ{25БeчTIE­ƒ ш#S›eЬuоВї`58ъyтћБк4cЩжŽƒањAгљŸЯўг66+O EъDx'ђа8гGЗmєТAщЬ8;яОaх1єњѕ•uYАхёВм4ђ.ё9ЫRЮArЊW‘Љ< НAЭhМі†{Ћ!ьДд uЫEcшDXыАЇcXйЙйŠ˜i$(иЖG$ѕˆ ŠЃW˜‡§ѓьt|\МJ ŒaŠ:Џ„СћTˆдЙ!Ці‘8АEТЬ73уИ<њиЃК–:DЯ‰ŸŽЧёw™‚ƒc“8Л9‹ )g7ЬXx@ШЋ‘КXXeBЧЛ^~˜ДIAn}dЅџgтЖіИ|˜LЖR*с+і-“тЌ|)ш›'ё.‘шŽŽB$Ъ‰U[[#“Џ™,‘~Q’5.EЪ+Ѕ ЪкіW/гќ7Ў6‘Yb"ФљypЎьІmбЂw$33іX'Ыl8ТmР‚9p@ПvуФ4LFФfїш8ЁТњ„Щ[oО%~їAЭwЩ’eхŠRYSЅ›м$95'ЋсJЈЦЯQ­пИ^rr Љaцkя%сhъQЩЫ9 CьнТРrhHЈФЦФТ‡сrѕJBGЗ\№ pё=rŒМёЦ№ч8Wƒg›]‰ј%ХЅz„…іSYОi“Љ›ЩУўЪ“Q­1ŽхАs’Œѓ"џ6EњТ“€xРIM!Ўе"ѓ^ яЏЩ=ННeб{‹”ы RКyСЭЈ/ˆф ллH‘)ї*ЙЧЩ:pŸg§чыХЦс›БXЯœaуj:Ћч! `ŠЪh;— šщяQcFJjzЊю!1-лк“UTcл4­іиЗТeШџ”IˆGFyЫCїt4ЊЭИhК=HМљц›Ънг^/Яs 9~јСŠ xOЕ€ПМѕж[ъПFЗЭЗчxућѓTгN“їЭ—%…KЅЬ%E~5џyqiv’хŽяHoнлv FIтž”@Ÿ Е^E<ыL№ŠёТ9_/ьqзЫєiгхХ—^Tcєю2sЦLyїНweпю}2yъdѕZ1nь8YНzЌn5ЩЄЩ“„žZВeыіhпsї=8ЪцЁ\уњuыeњŒщJ P\Ÿ‘™Т"AЧЂiГƒз l] У)†§Ы‘йђ,ЈDFЧУ3ТZ ŸдW‚уТ њыxІЭdве+ЃZ8?uЖ­Ои#™ЎцcЧЩ@Oъ)ћ!ЏХо.|`аšАЉ;SсЗ*TТcТЅЁйvvŽЎˆhsдKЃфо1їЪИВR[Ž…вЛQJБє|н‹;zeњђ‡хб< >^>b”e–/[.Ѓ'–фЩъюhФјђіSoЩќoпˆѓ„НлЯшYыјЭ§WєG &З#жбдхeдИбJНж!˜ Пqg сWфкс5)CNxš3№с’%ъѓŒЪ0Ї  ќэoK&N<­4в•rIЁrс1‹J-|ёбЌžy6eй_MоМ’ы4|іёЬ3}Дq‘'’3@Ю’eѓw6А–Х|мнмЛеŸь;"uJB^M~A’ “х†иЙ’и ЙrцRi­9 ѕјˆ9+EюЫ…œ9œЂЬol! 8Яед W№3€Љ#_3 9nг'жwжффdИ7Jфj€q /gJgті„ЋЉ#­9Йy{{IЮ іћ&У@ЙЧБR^џ! pƒcг:ыB#Е јнl]НAYУ—Hя|ч“ЕяŠ ŠдŠЫЩ-Ь•_Ќ~RоjYУЪˆСœJ(3ѓоoЫэ“nWQгnцcНч3A%(˜ёЮ8 Г"lЖ…@Ђ’šШќ‘#$'ШО p1уP‚УvгPy8=ƒШ@™аіаГЏмџЃз†єЄt9•Jš  и‚F’…іЧ`тЙ=#ЂсЄЄпСяїzLZУjJ;ЦUмын`уг[М‹OЩ”‚[%8!HЪ›Ња'Ї;ƒiƒУlТшЉЃeХћ+фиQˆr&”рјНТП 9РzvЏ_†Еkћ”fR‡;ЉiP7'pЏ‰ˆЧ|Cs=[KЭФ4“йУдXРфЭЋY№Я–ŒШЫК’ŽiXFwыg_–Y4np—мœа d Я0х%‡C ъc?}Ъџa{!Ш–”G5pЧШ€ЉƒyЖ^M0Ьє)яЯ–†я1%;€5ы}‡H=ќЖ‹:‹ОoЅDћY Pt^qk›ь7š8ЃЄЫк‡Х5iЮчjњ:"$BžЛщyЙљр­ВяФ^ЊУјЖŸ\=f– ŠЈEXыУ“ж”ЯїVфmт[ЧуZлТЕоxŸрZoв ЕЦcИkЙэ!_Ую‚”‘#,G8хђрлeAX U BA ёP'‘`gœ'•iR`eЄм!;qиiд(MЇ–P_:VіWэWGj™ Š1oFЩЬŸЪ:4Qі œcp№aеќ2Gи Žp”"ЇЏтАЮTВ™VŽа„)MwТэѓВюJ^]IгYœЮТОЊМюЄ1q­}їUљлПgыЂcЧўЙЋi”#,G ѓ(Ї;eи—љu=›z“#ф‚M—fнг_Lgэnf}юnYХ'GH7p”L 4ћЖХ5ээь5ЌГxіaцй\™оzoђ3aф 4ѕhТLхIЙqShƒіаѓЏй)zЂцў+фDdэ ОЕ.•њЕ#6ыkц‘_’/П}юЗ6‹ъ@’<ЬЊ ЗИg'!І–ѓ 'hэП uЯр„sE‚Lk&=Џ6%Љгa|О`ђ7љи?›№Г]Л’ІГ8…­ОыN—Wгw_•П§{“‡}јйžЛš† Ў‰kЎgЫЗ'О3ѕцемwЗžgJзYxgaн-яKёБš|Я†™ЮФћRvХГ3ЯцzІќЭ{^­їж"’fуMћvi'ˆУšЈЧоГ!ŠЄ€л(бЮ ыЯср8ЃЃЯШƒlіНпЛWХDЈz pТDƒkл"Msи@ƒњўkљгжц‹UЖ=хtБЪщ/кDёFЈdюq/рЋ&X‡є–хєё­jЊktя‰TЋЖщыќf–њѕфлЎїнE„vФzqўR”Эƒу­…ЖљŽeЮ.fЯ4}L оЇugdŽ„иjok•ЎghГm}тюызпVѓ8ЗxоЋ.Їfээа§xCDtы­ѕщ$гЧмS'Pk”}l­‹"BS_m„yИЏнJ ;ЄўŒаB‰GН эD~ф AоЄЄЌ–E  аЫARPЦ†ƒœ$:†S G} њЮˆh‰ јЁ Вюjбl3ѓАžЏќRZ ZuшnўœДќ3'‡oТН:*БPг"0ѓОTЧ.pУŸљQYІ ЈЈˆpЉA‘1ЖжОЃg~—ž z~Ž*іgЊ—щgsэ uЗЏ;xД{`ЃЦјЖ5ž3Љp"Д›Ÿ€ЗЯ.TpŽ ržRƒ—цѕБ7ЉŒE[9Ъљу‘ Х”_УАgWРxЧ›HDYЁ"ДОјOЛonlчVhџс~BћтЋуЏU’vzЩŽЭrу-MrxoolF;Шім™2Д ІЄИСkЋњеэ:PЯkЕ цkˆюЭG\Я >sаЙ9ЙЩЁƒ‡дП }ўБ<*NД/жДЌ›гЦG"Aю…к{HЦNЋ†ьуАNє)FзQDмПш,гGІ &5yщЂЩє%Ыэ Юц0ДuуМ[yX"s"8УtЏќ}]я"C.r\єЮ™Ищzq]Žйъb#ЖzZНКмKDлјД!jЖлУ;JF%ЮJз4ШCs§$œ‡ђк€sŽѓ›`хrl!џ/Ѕ7:Џ0ЗZРyхСlYщб#в `g‰˜Žѓкё _ЊŒЉћЅЈЗ™ї\ГŒІ5з'–MŽоЛєё—zфk0 zЇеР ƒ>!\/yЩ X8оuЋе 78ИLМ’\х‰w%qJБ„…BмŠ кЦd{VьhšccЇ“sЃb -usoт1!5PщВˆяŒXЊ \СCŸ:ч%IЏѓˆєKштˆИјЧДTю!7ЧgІ'чgЪЃЂPes%ЮІхщ р{".ж> 2Ѓ})rЁёvѓVчР&Ц%ЂДЙwrа{ж›§XЯ I;’dв•“к‘јЎЛ “‰ˆ€ЯufЌ“ЁTKsГхисCЖz)бџŒ8sч ST,QјЖ­ВЉ‡ОБ„ыKЫŸЮт™0­C[]h ˜&Ўhй…TВзšЌLй&эW•kв]ш+ЫзzsdДh&ЬО,ћКž)ž}Кѓyж2IфЮTmНвЂJцїызЯЙ§5ѕцUлci ‚lуkєцьyNЌ%Н\юЈl"Дq…ДcЦ‹i–5O†Yп›wьZFЂЖЅ 3щЛ}E=9wˆhЊ‹Šхф'ЫЄё@ВД•ˆcvК4о-‡|B$шŸ’A7оˆњœжъДжMЫхїФ4}С0Ч>ЌЋѕ6ёЌщMз\д|РЎBSє’=–ИГŒЖ вхьлъХ^гš<кТЉ ž+№'J$ОЁUюmўYЕ’Rх*ГщЅўи(uЖv4EG3R•#Ё“YjX•T”(‹Ю\RVЂšL<їУГ04јЁЦО‹KŠЅІВЂНV‰‰‰‘\иШ#[ЯќСЁСъ ž~йˆh]„ђњАШ0 є„eŽ2}ЎЊЈTЧ™A8тб„я]\YЌƒ–чТˆьjыk%уXКИЉFDEш@фBMNŒ^хIэ•ž*•ЊŠ*нУŽРљGнŸЁv9ИМ}МeлкmВqйF5q”ИћЙw№ehп?gЖѕЇ™gлљ[“–‹ 9ЬЄukф№НРвНШЩ‘|${ј`’"ТЮ­™0ч~:д>žy6хŸŽ Л 0фMл<ЄЯƒфбббэ“ёЮ–жšЯХОяPїЖЁЭ0"rѓІPЧ\MьŸMјХКВ<.Ц'`ZЭЯзOчЫкЙsЇiцЕ'"ТЮњƒmiG‚ŒФш$ƒыхЌy{йŽЄ вДлЬ4DDб}ЃѕМЇCLnю—№ ДТBƒеD„чћ­˜П#іоБіœ„нR7XЏёzpЖ-ркњ„H`uƒмtГd~і™ФЭž­eвf.Ч?ыэ‹3О}ТqўуЬдW+Š?цйОžіЯ&ўйЎ& Џм—ЅoЦj†Ќ”\сЅ‚ю"ЈKX/ЪЕЩёА“єЎJђЬ)ЙѕВ6Чж€VW5ЬKО3ЃV~yOУ!^Е%бtќУќжМNіlй%IЛ’фяOў]йІх›tтт8ДlZБI‘JвЮ$)Ъ+’ВТYёоgšЧGo.•~Є$Жё–МЖDВгВх•?НЂзiъ­ЌИL2fJЦјЮƒeЏ-U|З№щ…RVT&Џџуuн‡рbПuэVвј*Ч'їИьѕЅ’z0M>_њЙьоДKМ№/х@ Ь~й8;цПmн6yыщЗ$'3G–Нё‘œЬ:)ЫпYЎHžm\ёю Љ*Џ’є”tЕrВрСjЗН#zШ Ф4ДСт1mŒx\5H‚qД)sэgrtэЧrhэЇ’ўХ)q(ШS"Й†IœkЋ`УŠn”zИ;ITтX)yѕEиёХщzР‹Ћ‡’R<Пїю"YўО›ЎЁ6E(Ю%жyЗ1Ь%3ЖЬедНЛclїЎн2qшe>`kzС%ДbпIkarНœЏЖ5Њл-hЌZpДM`"B.F.№_чN‚аат$Yx ЛвЪlф€RёrЅ(?J˜лЈfS0D= —уЌг‚ћoRфJQќ`ž>8/дŸg‡8iy~1џDОŠ:їmп/еАЮп;"LЦߘ бАуЗxщћrнэsdHмPЉЋ‚й8 2ЃР‰ГлboІФX&-(мќэ›exТp5ъ\*з,ИІ]ДJ*бйнEnМщF)(+Я?^+ЕSkeф„‘Аœх!YЉYКhГŽЗ?|Л ŠЄі1=œХ?4@ђŽчЉн?GєƒˆПЌ~nЕмђН[dїЛЯYœiњяB_9,|Б§Т“ZyрЪ\k2e`п`)yэpнƒpP;uЃрdvЗШќ];$~ЬXЁ Ѓї1a#aегЦЭђ—ПўEіьйЃfžHQгЧ[tt4ФЯџ{ы`JЭKЊ€МюЙя^йЕk—њнЛrц•2uЪTYђс§ц ПћžЛ%''G‘_\lŒ,]В\ŒПф<)ї"mЈхЇžy &&J пyзн ;Œ'\.5бhnN.$ОђЋпў ўЗЩ,PїДэјђЋ/Ыx˜Н:–‘ЉuнДy“К‚Š„длa—{в‰3/j§щ…рЯ§C7гПY9—/ Л­Œc•ђбЇХђуЧbdш /љэ3хђШŒ\иSіpnСxД7Є‘э3ІЋхŸў§њЫѓЯ?ЏЭ<|шЌYЕуЭIІ%&JяАоЪвdрЭ0dNnшХ—_”О‘Q8еШНї zиО9ёU~,S‹AТМl:б:BЇСŒ–ьѓКСЦ­чжeRQќ?т ­|šWKDнур%т™ЇŸQCщ‘‘ђюЛяЊU~ПЛяО[RRRфЕ7^“Бp9vќиqЙуЮ;еГЫUW]ЅљаЛ Зx&Nžxж6А}ŽЧcЈяЊэЋeы_шќўУ iІYp–sФ"š}њгf;тТюЭ,.2Ка`QДžЂиsСьFyхСzь6ЪMSрWЖK›€ьШ z`%tЕ[ TЬŠ.!'AІWjК1šyу•{wфМ(~мВzГ/а`šŠs‡нХ:ќcќ& (ю3вэ‘5уљ7™В7EХ™M@ˆЌ;nоnКяч /|f˜’*№Тz1O^Эч7aЖXЖtLЯВ] 6fЈР^ро­{eфј‘J8PдAŽsЭ’5р2Sб;шШќ^$uœмХ}юуT*qq03F&Ю—IБCQ6РTaѓ–MАз9[nЛэv‰‰‰Q*š”ДЁЂI•ђйтИ‰'aQšЁ FĘЯ8W_}ЕЬš5K'+"РйsfлЦоSЅл жhЦŽŸ ‰P( Ј™ЖEЙp"ОљІ[фЊЋЏQлŒЌ™ШМПЄа6^іьйq\Bѕю#;ръ†@.wќиёX`o‘ЉXиВgЫш1ЃeУ†ѕкŽmлЗЩАУ.JuЭЋЌЌ€І]ЎћшHй\f@N“[)ўс„М“ь$џїТ132HжўЂ—ќьВхйЙЮђЛ'ћСь#4ѓZх_џњ—,[ЖLžќХ“ЅЁkз}.wнs/ьр~WжmXЇЧСцЭ›ЇО fоѕѓ€dюQю%м$8?hТœiЪЩ”Fјэl-Ъ—њмcвœз ™тw\œ‹ ХѕілŠaˆ9O(:y*l‡Bќ{ш 9—cо]бeЁв Ч=]œнrѓ­rХИБ OЊЯIКIc>;wэ”!№ ѓU`цO*Œxѓ€}xX„Кьrфю v?EЄАЧ V!И7+хWхмSпw“hvёpWOЈ‘xЕ§pO$BяЖЮs”рР&iЛю'Ну†жЩŽ­u’sH‰wюЊ“Ѓi@0–~у$uƒжьї-~ѕ}љє§O%#%Ÿa=.qощ}YБx…ьлКЏM‹ тЕъZЩЯЭ—мЌ\E|DœT§чПCЪЪХЋф“хŸШЋyU‘'MGhіёLUQ~‘Є%Їк,І#ёЎYКFУHљ Ё€Eo-’пјPЂФРdЋ4d“tЫ H˜љsА.~yБ|ЧЉ%%ич ”№Јp(мфKvЪ1‰Jˆв§†G~ѓˆL›3MЦL#б бшnP$—`,9С SЪ 8uX"|CFЌd7$5P’дВ*Щ‚T€CЧ“@IКі" 8Hћ‚уј{bпp/•РкЕkсш(ˆ&э†_Е@x1ББšO|lМrЫ$l˜їлhyџ |Va?˜žX}BBC:˜‰вРKљŸцК8†R њfнш ‡7hш˜DжР6ѓYaaaкG§њ)’сљЩЈЃдш5гБЭ Сx4% [кџЮшwrDдА6пЉГ§п YѓЭ ]{ЌNXOj$ъŽtЯю%‰C}хё‡jфNƒAvH #фО›УДЈfД@ХrL7Рђ/ўKH‚ЪTRD#дAрўЈLзЛWoєЦй9ŒUгџSY‹yЪ œ№Ћ2Цt(ЧфdKнОт˜vPвœwЗ IDATœK ФL–gЇfHм0•шŽ‹РљС=J"ABв$Еƒ[ТВЁЉA ТСC‡9DŽ=:М&„‡‡c=j‘!ƒ‡`о§іОАЎтX{д›е%[ХVГ%7ЙїcSBO0фвШЫЫ I^:ЩBЁCh ›b юНWЙлВе,ЫъЭ’ўя›sG:О\ЙW`lнsЮžн=ЛГГ;ЛГГ3ђд?ž”˜HвюбhЬъПjеХЯŠ•Ы1iЂчш5sg2ШЁxqкрдіпХдVё§ЊНPŸ6iУS^Cххgхб;Щ#ЏAб%ЊIюЛ4AјSЅŒV-7 OЎ7еЩ[Oq3ЁJXШОЗ!SpVћїСнттЩKA~ эЩˆ #є;&OPб( фЁп=Єxє%ЃA,ЁКЊЫшšЁтIjr>љс“КGиgH%ЈИ‘q№„“Ќ+З‡џњАОЃApц_ЙƒrUфJ†:fвuгУМ Wнz•хщ1 кlЕјдfŒƒЏ8н^{ЧЕЂЪ>c•`ЩTЏПчzeЊhˆC–ЋРёWŒзќЈЉjФЇ;[?šHя*Щ?ј–Uэ—§Г_•Xб LУЦТ№:ЄM!ЮLлƒўщхzФ~O?ћ4VXоyћ>rИ<ђШ#pдћВvbт ­3<ПoXЇƒEзvˆ—ї)xЇї'џўИ\wУ кЙ98ЉG†n`”~№ВAŠGю˜gЮg иЎ”XЬž=~{ Н]ВГЛЩŒ™3 „вНе^*ыk{ЂЙЙ}фБп?*SІмyzŠŽўIzу 9cЦ ЙяўћZНLќ о СЫ9Л!qЬЩЦЙ $ЯC-%Ф‡Ъ‚?ЄЫп?>$/6Ын?–{oУ$ЗYrВХ4жЩцЄ zSроїVјžф„‹G(§™њіTн=X‰mјœЄѓнЅK–‚–‡(=йо3щЬ$'†#Lp0 +ЖЕїм'Њ+еЉyС`Ф!`Paр`чGтїЭ_IФБ–gУ† ꆋ,R&Ц=sNю9цбЫ лJ„lckC☾юн{Ъ Я<'wнuцyЄ2I3лБchДJОѕРэ­бB.ПћgіФ! 2хфк Й&3{qВcыv‰J‹‘№ИH]•œЬ Ц•ЩЁкCъ‰*џЇј ю•q!B'l]Pn_Uн,яцЕШЅ—KfF“МКLepАєЫm–Мš&hkЩ„qX]Rƒдa(+-“Е‹жъjА{пю’ž™Ў„Џ›ж\!’aђhDBl‚ЮlT­aa!|чфХу‘с‘Ћ3=;eт’ђёИш8uyУY ОУЬ‹яИЂЄѕUгb˜'л‘W=fй>ЫЂ‡yСм,>gjdЄIЛяn‰Iэ"iиу Р У&Ј­Љƒ_РоК?ШЈЂ K/ЛT’“’с=];l)іщС" *ћTH f(ёУ{jєхчяhg˜HЖЖ3gц\qRл–ў sћє…ЈЖЋЦЇЛ'Оч`O7BЬƒpВИаLŽу‡R Šпйžнsr”і8Јp‚ Qn|$v‚[в,ЫJЋL,+WИУGސьœleFЇzUЦŸŠщAЃмoт JІMќtвUtЈЎzЈ)IќŸч"АМ:aBŽ€FЈ?њ§эеIЇє(э'з‡;/lл№=утПяйg‹ ‹tЏ™ЋЈ‹Ч_Ќ.ПКО,C›‰Lš8Ii8(„”+Aо“69&ЦјL:%0пуjh‹†€СDЂ Њ1™+{і9I(-—№є.Š-ƒ`HжЫђeOЏK%ѕяHОKрw ЄКІ{ž]dтФ‰*)a;ХЦЦС GW˜Ё3–зMcЌћjˆРЧТБpFfЦiŒuЂФL'ьРovЗnЊAЫIС/ьoKZŒ%aШ•§–8ИGžŸ7L]Яy7LZ зaTuйQ)кdЧ8Q и…ŸР_цTUЋ№˜­„5cVвІCЙ Ÿj~чј0шцp+Е2ЪR^VЎЋ5ЎАdnPтУмхeгъ;Od>xП?к;ЫЧђД++fпm/?АСЬхБg+[kоpЄ+Ћжші)vУх!vv_ekТ>WУ!ˆnš0!!э §1Щ 9ІЅЫ–b’c pўŠ=—p6ђq‚ЏoKюtюћcI{ЊтP“ŒкМ]ДWw8d>ўјcљЮїОЃвƒSUw>\%аX5EЧnp—У~.о[Yнn˜ђр†Љћw`Т Ђб"kфеџNТ8dЃt[-,m[ˆsч+мWcЛУнїоyщYnУАEв„mXяєЗісl8r С1›лО/Щзн(‘œиЂЕ`lsFVF8ŽTї;ю.YМDќіƒž­ЅУѓБ'KSYQЉѕЕ#_ЮxT ƒ—Жс•Сч'АbФЎ^­BžAжЛFЧ;аž™ W[˜PДG&aйХРeлёч‡Г/”uу пЅ8д9Iy7Vzам3Г"“ Ьž`соŒC_ЂьофсяHЯЧњЮтй•8kяЛ‡n€<&ДФŸa€N(ђѓднžOьъ|ЫMАЧ›Яai]EwhФiWюГpBЦ?ЏаЊWЅдBќњэЗ+ДYЄEЕККiЪТ‡їќsЇsПgœ#ЅЕwоi˜юtПkп4њp‡ёо§ЬИ|&P*qз]w)tЧ9хuчgх"n)QZv•УОЧ46‰ГАsэjŒ!59Tжў>ИїўЂZ'уох5|ЮљžaосfєG<йˆfq-­ї7Žємжhs|з +Ф’ ”rL 8нЇ6jіљxжав0Ж•ЧвY9yuПуГнS”Ы=СлЇмюHК\ДjqНЏіm†+НИ&фиЎёС;эyѕl–TZBP#ќчaёC№Rя hБ…@{зŸ„R‡ оэлvHJVrЋH‘ёЕЃ“иШдœ”ДАBНKRNQƒ1=І#pяŒeфокљК‚mЃЧг^|bж.ЛžШG­у№jтx c#­JŒл bўДWžж|-ЂзЕНtŒvЄДGzчѕ‰SњhпхеЪnaVfїГ…ёкЗo›–ЈwО?АќX&їН;O З0яg ?лW+ЏІ4IunчрћбЪЧt–‡;ЎЏpkCЦsSОЏєюМкЛЗtdиюМ?">AџМгZ†{ЇqЧ=в;Ц#ЎњѕызšФok чЦоЙѓtп3кInЂyђž6ђCОЂД@ЄEOЭ~и78шЈЗG%EЉrјЯaРA}й~p2ѓІ-ЪвP6ŠхХх2у‰rѓ/nТžV†P rъЬ’ЩдШаШ4щ•œ .ЛЖэвYOr\Вg5щ|‚6;+aсЅC ICNЅ•ѓ NSЛљФƒИІLŸћ@дxгйОЯШGфЬ—šŸдОх>as(0еƒ{ 8r ŠБ=eВNuД4Ÿ‡ї‡сŽjюАd3uтЁu† м0.У Џ4sЂэv$ќё[Ь—ЂQўQщуxлєHљŸЩw†cС!q€цjЧ3Чж‰њ zДя Јz+žГѓыnЬWіRњщУP…kвrЊJЋmNšУп‘РpЬё…S%DвВб*гžyFhИ9RЩу‘Эе]ўі|йЛ{ЏD$DрH$N‹Hў‚|Щ#Б8јMFFрŠŒцРОњЧ+dWg(вS™ : бlЎ)ЁrА2>`ДŒŒЯ&eВVръa<(OE˜Ѓ–9ŸЬ‘дЬTщгНWjГ{ŒЁ8ЏVXМOІНќŽt†цшіu[хтk'H7hм5ЖœœW…жB}oHмрЈ)Цы‰Јl+.0ЙпЇч#СимрsˆОSR%7юTkѓЮўйчš`„ƒG*ЈбЧ‰л‹gИцdpЫє„#хЁпРїи–lWjQsВт+хwД<ѕЃgс‡хSњф1)LњјьЭ䉑ЌаёyC-Ž3QџN /'›‡Ж;ꈓL.ŒљљCС г2гwk } <щчLƒсиДd‰ooŸyFxАРЦTЭЃм.вЙlм ‘Am†5кбLРП&П6qЄ_ГŸьJ –џз5I&—є——УцЫУЕ_vHО›єm‰ъвAж6,“’7іFl4РЦ™ЯœщГqоЋVSeиУdЭв5Вnљ:‰П?^­ЌМђїWeч№z$сŠ›Џ”˜„X™|чW%9*YVdЎЋ6JьЪO‚–O&Я‘,бПIЈмдІuў;Y тSdtЄj5žl^_Дєl J1СъReM%‡‚%&,ZЪkЫ%6,F*ъ*uЂIћЖgX.К/Ђэоѓ88S‘‹–Ђ|AI) 7дcЅˆ—C0 ?q&ш+џ“ #Ї+,S,d^-4Iˆ ,#™e`кш,0AwНЈбЬё–кІоР +}йњтЬ3ьжOŸЬ Х™UХ•ВjыJЉЋЎ“ШјH]IHИŠ0yЄ‚ ЅrxвPЭ^™X2Q2^(—~АS*“вј"ЙЁп вœп$+ї/“К 6цЩ ЦЪs>ЌЈ4д’KПzЉ<ѓ‡g$;7[ЦN+бqбв9ЎГ†ябЋЛ\yнU2ю|uu4aв †’ЭњВnб:4nŠMПd‚эЗ8›ˆWvІІхЁVаlжj”я-ьDПёyMЇИўЙАzї ЙыƒЋdrк}’“и]Іmz]&їКY6–l–5ЅKфG#!2}—œЈк ФOnмѓžbA^ЩŽд&+B;PoqНл”љБЯѓъˆюœЇw9Юц3ыB7zЗКh™№Ž&Ъ~ІPž<„}УUВс‘в3ЧйИ*<nСяёЌёТћУОwœˆаВЃ|” аћ ФRОfT@kИ~уZЉпЖI‚yЌыЂёsХ5”мIПїš`Г .nхт•`эк^Y-уКяљLаrzЦ>[>–ЏУіXћ;Ф2уГ $Ђр0ьк?Eвt–д^Ф?ИEjїзЊЏњƒѕB[ЂDFEщжЁŸ<žќЁ|ќњЫoТ6ašPц(ђч…ШџЎПWЊBЪ[]iн€ІЅœ™чfжЏZЏL ђ}žГЂr;\я!Не:K—Ќ.КпШ№* }яЕщв{hoœaЩўR,zLу#‰јdўZ?хЂmцЧС–Wv ћГpћЎХБч/Ъ•ѕf]9аѕO,ў™ŒЮ-k*Ыљ…фvю/MAЕ,ЛЪђАэр˜4ќŸКЧъЩЧђу{‚MrАfЭЁ‹ ‚НГМмWажtЮЃW›2>кSЌЫ+СЧЙpЏ…ђњБr%ZEЌЄ;†HFдwЧљ_GЇяQG‹я}ѕEЫ†gZAЂQkУМгы3гГŒvМЃGjWЏЦvFьч™њЫЏC)ЉR§ЯgфрЃП—ц‚B§ЮaпР"…Яœ0Б<жі4DП&лјŽaV~KЫя3Œџ,LХф.М0Žу№оЦ€3/m+‡•ч”\)юНЖM+‰­\%)%I*K+%ЛGЖZsPфƒ`7УЮgZч4mz*рwъp›TqЈB~zЯOфЂk.’NЉф@х=—Х8_Т™ЧлŒчм6nм(ЗоvЋЎД]„Ѕbmшы^_~A~HЋЪ•љp’њќѓЯЫаЁCЅџ€ўкnмcцwй'Я0<бЭR=ЌљзT6Jd˜ПЄЌ‘ЛЊЅИДіŽЁŸ +WЎT#№<žE—mуЦŽ“œю9ZU7ю‰Ÿ+VШРА* ^ьН;žО<Ю faтqћЉн ws8ќZR ]GŽ“Ю—_)5RўnŽ4<ћИдС,cј=пРІgЌ(} %`r\в|-оАœќ3 ‰<2@‚w9 OŸёVƒ 0Р’З{eš];wЉVšЈkЃRw’ЖrИCOЭ§)ћ63&Ѕ'СІ]иQ*ЅїЫоЅљы\Бё, ђ|›švEŸМшIёћ’†6Ъо]{$i‘”/­•ЊyUrUСƒђXЬcRY Ы :пqE*РєиKВzeЩт9‹БOXЅт…nНВБGY#Х’’žЂў—Оќ2ЛgЊ’Ц˜ЫЦJTLДа5RсQдФ†ќЮ <шцІ9ЩчmЩ“­[Зjh+”Хœ9ŸЪrјjу*ŸцŸhёƒ†ЩєїШћ/ђ&5&Q’c:ЪХiх“ІЇTят“ЅгЎН’БeЙ$8ƒёT]U) ,?ќPvяо­ИЃFЎајОЈЈHgћSЇО+oРУ‡/‡Eš5kзРЋЧBѕ–@…˜c…Э№‚Б}Чv5Рl+ cІ‹ž/@м4A ~o~ іД§х‘Пэ”Х[ых+i˜ЬCЙtи”н’ЗЭ1ПЗƒ9-В\3љЙќвЫхэЗпжqхXцЭ›ЋfёыЅtЉ<ўју№ђ‘Ђ †>?§єxыpVр'ŠcЕ0ѕVЙoь84–ЇBа†UXсwР9мФn–Р WHгЇгЅЙи1№]XАOn€ЉС`H{ц‡3Tџ‚ЦъЇУg!­Ш$ЉE ЏVКит–@<эоЕ[>CнНgЗьмЙSўіЗП НP2ч мc.НР№{+с>J!+ТOЧ\іp ЬЛѓPxLaбaвkX/xDш+}Цє‘~уњINџѕ*Ё+‰?ЎъhnlвИIrыЯn“‹~8QFн1V~mˆtЛЖ‡єЙs мљН;eфˆQђЦ+Џ}fаc^‡ ”+'_)у'Œз V&п8т‹D5/•к9Uj[jѕ,agИяс їњ›Ў—БуЧj:ЮиЬDйљфЯG)ЭКџЌ@њіщ#пћоїdjшЧџў75ш;nYШi@{еЊUњ~кДiъФSЮЃюЁх=?Цќг[&ЪєЅ-ВvcWЙ'јЯвeŸHкцb‰\їŽ$|x—Шћ––FЈ_ш:‡†И№цыoЈі/ёi"9ŠAщЄИG’‘‘Ё}‰ lоМyъBiюœ9ВvнZЭЫVњаЮЯrИЮњбў&ФКЈk(FГб=Ж“ќЌЛ‡н—пи#oо%ћіVЫoю.}УeЮќRQ+k_I‡k&Ч\\8 а1oqIБьмНSн-‘AМљц›•щОј‹/ПЈ[7<лiў/щ~mгцM0EзI^zёE'‚'ыЭи2*YЕLЂ/ОDТ'].лжKХУIйќЙи'„Гф‘cХџ-0bЯф†кЦœ БяЅgfРмк>™њЮT5nПžMШиX7xЇх{G-}ОЃиєйžК–Ђћ:šaЃЁzЗУhяFЕњЈ‰Ф_ўъ—ВЋjЯ4‰њ<€ #„˜бГbШyьЈ№ A…šSѓh!Ј[ 70nMszqї‹ёz‰ˆ|€™иЋѓ_u:'Bт2B­oЁ6”“ЃЃ)…ќZjœЅ;Т™žё)ЋЖћъцjУѓ-\јўK8ƒ@ЛxФtѓчЯУЁ^"Ю[(_§ъ j+ёїv>ЛЩW])…иЫ  ЅЇžњ‡v4К2lˆј зvŠ;‘B,Bя “OіјЫЫE-ђHFЌмœR$чўVУ10ЧІсќбVёЃ› PЩЪъŠенZ=VQпи т8ZQэ=`’э€rрЂ}UW‹SnŸЂэpхUWщŒ]_Дѓcћ{іьТ g)О™-[6o…–beАЖ"<кЬ”*Ÿ|nЛL]х'пЙЖ“tЙjЛlx5M~ђэtљŸŸo•Ÿ~#QrСщ}!ЧД8А›TƒbСŽ˜Œ3ЌЋЈ+Оr•bэх_R]…и‰эоНЛ†ї—С—$ ŒЛ№5bM†r2а щIœЉŽ€ЧšШО§ЅёŽџ’Њ —Hэдпˆў[6)ŸёУ*РЖ&CЃ$ІOnHе‚Sі.йпШЌMУ“n—Њ!о.ƒ§TкјЅЄ†щ/Лф2~ь§вХЫхk_П]§оpу 0НДЂтVMQ[њШтœтФšоЖnЏ”еy2zPЌlС^`Vїp™ўбЉЈm‘пў4[њї‹ббШ†ж‹.˜†УБэ]wмЅnБˆ7юЕRЩЄчћJАwШvуЊJюЃЦФГбђБЌЖIAбв!oОдОђМЊЌИ‹'HєЧГЄCяhiКq’јНє˜O'~А[KˆТ$шЂ‹.’‡zHП­_ГV’S“да§%/QІfgџq.1 ЁгaЬ~ нгI5л~;|ш[А“-“6h ŠШ)jнКeЇм}Янв-Ї›|ї{п%#Є@'юqХы`ˆ€lЌ>(В[Мd‘  ў{A)тЭзпФžрыВaЃу‚‡тЙчž{NZ8ЕUл!$„і|}щ†“*Та•гCpїэŸ+kж­‘њлDс9Љ9—ј­Ч9СnY‘ђуoЅЩЋjdZK LоAО&цm#Œ›щИЃшў‰'Ÿ~§сz 8>bИМєТ‹ђ4$TBЁСtкЭ}ўЙчЕr%nДЬwЇb5rШ0 J"-<&EџяЉкЖEЂћ №Ko‘xˆ‚„РoЪЗрЏ)E›"чљИК#pТЩaЌ gЯўXцAjCWKTш!Sчj611Q>™=ћЧ‹t2E‘:ЄџлуТэ њХ$Sbx_ЬєТ~Mн€.i•™v„зneљEќqф€ZЈќ{МO”чЫѓRЅ |З}ќС,I•. ]a2ь$-ЁpЏ-Ћ• ивЃ‹Єг1ќёЧы}BЫuЎfpж|• Жф“ЂЁЅuHЎИЖAvЌK6j‹L]й ёЁфСћб˜-cDџЬX‰0UщEйє?"АQŒ[яїќЧwќу3[гqІKњ„Єе>хJ ‡`эƒ№™Дш„ѓжћ{њš…Ц23šђ‡ќ~ц;3dЬФ1к,M VN I6ёяhqЇЊКJЪ” їEULЭ -НрЧž‰{цI[­R}Hђо[/‡ вƒвмi 0‹kiOфJ <œЯAТ№Ю|xoЋоsеТNФ{~—оПщažѕT”уDЪ~ЖгwQР]0ЅW–’щ;šфЊЎ-r}иRёпћ†Дд‹_ тŽY"SvсФwэ‰IЅikrРVЉ№JБVŽcаХŽ…1=ШФГЕя1zу3{*1qož“BKkёиЎю6m/‹6ЎFSnя[Ё“§{˜МЪ‰•;*х™`ЈИ*PŸУKЩ:’QfY7УЇTƒсfqљl86њЗv8<їc{r{ŸЈ‡(Мъў)rhўrс&ЌW”ЇvџЌ>"О"rўРАX™&”Эк„х!А<‰2œbб… Њрap]Цђ“NшŽLOЩ*pd‡ЯЌ?щ€ѕfZцE0sеШ0Ž”ња˜}—ЃbтЏСN˜Сy ЇИмэ‹ ‘nщ№Д $†5Iю€b)‹РŒэ lyTœ)6ђ”ƒЋЬPП6я д(хЪIЕYнюЩLhŽЬ †fсtХ‡pzЖ`:šl Ч?6"эgвvЉyЁѓ‡ŸAќЃ TŠ{™/ѓdWИLO`ž|ЯwAИЧЯЏ)ѓZЛ|­ 22œЛ„Жg‹єX_яGЉŸl„6зКЄNDЛіь*§Gізњ‘™‘!Г<–…@Іg_ IDATЩяђ›Ќ•Эј8W/<ўМ Ÿ8RњdївН]Mxš~исНС:Ѓ…[œз_]}Зщl/­cYМ/ве3NЩUЙ2!Ч_:p…8F5П5гDr/њ;h•*€ц ЖЧЃžsчфsЧ3<[;Иу}цогЯ9,-я-ŒїоmЬАsBБч2Ѕ3њzh…єˆСфж3 {.‡›ѕВу&юр9љpC{qO n<… ZШ[гЄqжвМ +~„ћЇb8tмJѕgЃ3iмпuЗWЋл е}і0 Єї;cpQ‘ŽУbЦa›ћТпŒёyрї(Ы8‘ьзC[іx~^[ћёŸЗ/ ;йВЛZ6я ’ЌњfyiS‹|В=DŠтq5фзЮюЊ;-‘ЮПђђ• WъЪŠŒЂ{ŸюВmЧ6IыšІЬhлжmв9ЃГЌ8(ы—ЏWФcЉ8ˆКyу&й_X"a‘вpYЖx™2Рy;eф„‘иsСйI,їibŽІоЊ*ЊАЏЅЂЪЯK JЄ g#“:JЯў=uЕG‘Tо=Є3Љ•ѓWbл"#Ч}{іЩ ~AюkAЃ`§ГЋХŸ.ЦyШZЩЬЮ’ЌnY˜˜ШpФŠ’—џіВdєШPгe;ЖУSGZŠcp ЈZ6Ќм ї(wŸ}dsоfœщЬPBЅ]ТН;іj–.^* ЫuˆСеСЃгF№nмы§ai=M{X2rг:$УЎНікЖС”iOІŽЕЌчZЅa№FtЫэО“{hƒ/лв;їОм‚sОV^KУЋжа‹ЦмёŽVїЗ™Ÿ3mу2†RЕ6Мёнщ31˜œШ7F•YЗў кvИю)c€г ZQH„XєоЩ"м^.wоP%aМХЂк0@ъЏП‘+P с Н т 2FjЖRМИjс*еtнГm$ƒ™ddЇЫ‡HУд'я} cтћtѕЕjёJYЗt$tJЙгчЊ]B2ЮŠƒŽњp‡pщеП—Ь~{Ю@VЪІU›dЭ‚5HлMfН3KуњЊ8Ў6?x§‰‹УІuЄЬјЯ en}‡іЕˆƒ^iQЉT•UKjzЊL…б№Šъ щеЛЗdvЩTƒуД?IqVC]ƒ”•”ЉbФІе›”9?њƒGѕ<хњeыe§Ъu’Зgіжo•јЧњцJYE™чЫWюјŠЮі€єV )кŠРЎ­/уЦ:ЏоГ@Ы†яьЯц^QИЫfq>яW_Иуф€]}`ј$Nэj1эYѓGTїГнЛг[:Лj:<.иg ІžgяМьнЙtЕrѓjtю„1žњЕWfЋЃћЊqН№Ъ0‹cїЯ+мТŽхъ”“љbC*‚…Е›оCоq­lОЎз§ЮаrX˜чћ sƒ=П‡уИ-VлŠаpNЖН?ѕwg‚йžHЉQЎњrŠџ<$Д@ќЇћ†иЯ$„A9ЧЛ2ќvŠ/—№`ю“љcŽDрIыЙpП.„‚У‚eмј €Whnа]4з“xј/2&R‘ЮUсњыеN-6ЙrЪШЮQуM”љћцЩФы&JїЄюrлЗщŠ+Ь@mЋЛV*SjФў WŠ4&аhЩIЩ‘тIХъ*=5]Ј‘uАю ОцKJЮMZ;>HЪ бwЮі№†Ё§†ftтѕed€є>C &*ЫыЦa#фwXv шч=|Ж ŽX%"*XНЭщЯ•оm7\Г90Ие"w]Э~0HC, щНcСЩ‡љr№8ˆеRё"9эйОG‚B‚Є`oŠ1ыыdѓкЭ2івБђцSoH.Фˆ)™)2чН9:АаЦ#пѓ€ноькКK’’’dнВu’–“ІL•›ЧѓgЭ—CЕMвkB/™ћС\MK†Dюб™бq2ќ}љ  ЦL“qQqQЪ8) -/-зјЌПЭП† zьCBu),+’ЗŸћЗŒž4ZzїЬеНDžлЬЏЮWbуО"Ž6`qФ#d7ъKЭЎдŽЉP ’щЏM“єь4‰‚чmКЧЂыЌтEХPЏ”БУFiZ~›?<чЬ0a скЌŽяŽ @ ь Ќ•x~JЧ„Г}м CћйC>;Г;ўЙxя-ђ9Љ2zpG†УЖш€§№VмЁ}T J ?iјOz#­ž =pbУњЦФТП'6_`јАЋЏ8g5 8ц^'gДWL<ЋqxЅУЖ’Seзє кФ–gД-кЂзнЉТ'J‡`h›“h›(ё <Ч*wљј=Ж—;ьИ |2‘=8Ў№ЋаяSБ4э.K#4њ%Ў}гдЩхЬЇe=ŽрПаpАDъ@\qр|:ГQЦN’Nи|ъя2xі ЛљЫє7HRg}!”i@ФŠFЌЬh‘}јE#х§7о‡(3L*+рЦgbzці”7ž~Cт;Цы*…Ёч€^ВsыNЕ`в!Кƒ22+Юf Ъ"ƒF–ЉЏL…IИНR_ СЁС*х ‘“)Ы>]&+ц-зj(еЦЊG –ю](ЦЄ"Эrht]q§rС•ШЪ+%4"ЎЂb$=+]Ы6ЦС'}u’Ў(mжб!BЕчޘ+лЗьРо`&Ф[dќUу•г Uю \§&ЫKQш;џzGЪŠЫфŠ›ЎЭљIЯA=eъГяШИŽCmˆЧБŠлѓЗЫўЅи зNЅ ЄSУ“РrŸ,АcR}œэY…е2ЫШNьДswV8ь ƒЈМС8_‚3‘ˆmђ`ъk‰tŠN’nКЪЊ]ЫЅ_—ВЋtTж—Ы9уБш(K МБ§иЎ‡‰АЯФ‡OУ7и_IяZ—ЖQЙѕKяЬм/љ•PƒЏе/Ž–$Иb:W€_іQRы|йЎeВЅp‹4ƒI‚ Мqн/ŒŽgЕШФ1ЧJ–—n№‹xЧ'<рŸ’{хљIчёё‰ЧВLHgрГњш•Œ0ГБ_џЊAžўqВќфйb‰n”яLN–лyPЦЉ’ЏKW++о…%~Ќ.1]*Ы№XAѕСjЉЉ­‘І~$_џіз•Aжд9жhИЂ#YPDЩ˜ГC‚{цІЧ`=‡кЂ|ЯFх{5@)†хЬ’>GsMЫЯ=уY%ьOж6Рѓ8fђa0еФя“ˆЙТг<<ё™ЮЪС™7gЌ,ѓЅ эг№]ЈЈš&Ѓ’}5вYkH`ˆjРкЗ9€9 щёžPэ‡уы\Ч'`ЮnР@Gьr‚LЩЪ]R\Ђ>г–ТњH3VЩ‰‰ёР™gФ!Š№ЧКsUМЖg;уA3“dфхUeњЦweйўхВЛnŸ4цЩ№‘вXы'“2'Щ•ƒЏдьйџљпWйe"и{яgОћLв0гИыФq‰c*Oшчд§ža4–Ђ @чГ :Э№йv;Э<5йs7фЊЩR^W"YН#Єk—ZЙ§%вwД@ћŠ|џЏЅт Щ ]upйŠzJбр’O—hCŒЛ KБJЄВJЮQ”)x~э|Œ…г`<ІQБChлY>#Šўx6<ІЬ‘ТТBxp˜Љn…Xw›ѓžxЄ!nZk!НjрIќp‚ЛfЯйWПN ТБёQ/Х‡vЪ€ИaВqс k “‰}/‘?Ќ§Ѕ”Cћœe"ЌYНF†хSУк|fЛѓбУјЬpo:jЗzњТž={д3ѓ№Дq:МЯp5њˆэfHЅ Кы+цч<Œ›N{ЙœСиАССо мŸ&ЖZ< l MFjv2вшl4ŠD9шЗxTОр|…іMмyžюй‹ѕd„ao57%D‚А‚Ј/?$IЁM&q]EК&СмTp9_N}D}Н­_Л^EPaмЗWЏž2sцLЕYЪvОюКыTќћ‡Gџ ДюŸП'_nОщfѕPЯ ЄЦŽЇ’Ь'1!Q.ПтrѕА№1LI 8HншиlxK^ќДН/cПyЬѕЋG{ѕ `МXКІІt–+aм яM›. ўы?p€к—ќЭo~ЅG]Р§NJR'ЉCмKўЃGZщ ;$ѓцЭ‡­ХяHчдЮ­ƒ;oЛЗ6wЁдTGJvШ8‘ФщжвО>a‘iо;вЙp™„\њiщ:TiœОђжЎ^‹,Zdд˜бТу6ќуЃ№аnіcѕ’$5`”љ{vcеv5V75ъ‚'55U.ИрљЧ?ў,јcKЁZ.wЁкЕвЪхО.YМD~ў›Ÿc`лЉ^-8гЇиŸ`wќsѕžтЮ|xјpVЉмљѕ4‰ Їо-—я] E/H-іŽœ=Т@ЌАxо•ŒДєзПўUЋХГЩяM?™xЩD‰ŽгќXЗ2(1 QыЇžyJ:%v„ŽŸмxѓMЊБz$ќ _yE›ЄЌљ€ …в[h5&IšqмЌІFВ;”M‡ЩЬ№…ВЏdŸDGDщdŒ.•ў5э55МM3j3Ь_ ЫV,“„ИЙіКkAo5ђъkЏbL бcЧ ів>HЯ ­Ж>јћ?шЛ§Ѕ%rЧ”;eліэђюЛяЊhœЖX ЌR:і5~{VЧўy`Юл!ьz_.иСxўnбьЭPй&yѓЗШ–Х{dл’=ВцгMcVj"к€ƒA\И?lЛрЯБЋ‰З˜мСќc‡Ѓ•э[p˜{+6чьV‹ЖiЭлг@іќхѕє`  ЅmБЄ!Tf–‡Шsх2Ѓ)Jіc ˆNŠ– hПёtЇjюЁЫр›"ьKрѓ- і ЩlцЯuФmqАk9ћгйкюм+§ъѕ_•‹.{ˆŸhс—-]ЗNeХђх‘ѓЕ“ЏеNGQ™;чх—_~˜е“їaЅџкkЏ—лОі5™љбLЅЮт/С`vяНїЉП=кE5ШЧЌw 'мyз2іIWѕи+І8шІo’ЫЏМRцУ ёе`4wмqЇњZdZzа€фіь­ЬйђkяЪ­(*-ъ-Я, ’пН- ЛЧKјЎBI™ёž$юœ)!я‰Ьў ЬУ<€~‰—I0QGMgжƒЖoМёFЙ№ЂёВtљJЙž?nЙх6YrДЩAšLѕ())бIУзП~ЛЬ.И"р@yxпq:h ісWb№ьйЃЌоtЕƒоьГч и‰’’y№W{ф‡6Ы?_й-Žэ$гŒ“яўr—ќю"?љЫЏЛKlŒУ‰'Ÿ|R'џєсV›Иго›&зoП§v™іўЛъA… “7ІЁРxа*qл iЎ(Oja7ДЈqИL‹,§ї*IоŸ&цУysZ,Њ›#яW> ELJHH€эАEZбdnЏоВ~i$†Aц/˜ЏФщg‘{˜}ќ‘ZЛšrЧjщ‰ћНьƒЄiwЄ6ўЭЗоŒ‰оp™3їSL *­ф7vЖnнЌ –пЮлМc=ш њXЪ~ж2 ~„@ЛЉлW”ШеIi2gєbC2%d?”M jЅgLWЩ_YЄšŒK ЙЪ+,*кП[Иp!fmљ:KБw!~аœђїG[HСžЉЎЌ–В§ezFˆŒщЩ$эžW‚=ыУ—?Ї ŽШх 6ЬуТхЛ=Cф‡}ТфБaђо%aђ—Qar{яPЙІ{€РoГдbѕFррџyћп8гxP­№465Ъњ X%b_„юcШдшœа+ЦВŠ№Ѓ–ЏєAOщє„PыBt8; Цi&ŠŠ§ћСф” (ІЂ3щd˜ЄтБ‘Дд.ТС%33љгtЫЮЮvTП=щjёэžшЬ„^`дюффkФˆ‘UбјёуемV,Ф–Ip’JЈцc5xЫmЗш`У œбКFp§pŽFFИГ{zDиU#лjх‡ЃЅЅ6VТwўSТ2GС E~,СЊЅ\SOž<Цw!ЖфСkR„ŽX‰\pс:  ћŸ’ДБЉђП_џ™ЌZДFB{ЪдЊ?IxhЛ< XБr5ь†ЫB8№ЅF§Цѕыuš•™Ѕ"эј„xGZш‘гCmŒВмщSZчнG ИВ$UА?=щ ќЏфЗЁч0wЮ6MPёo"‡ЦY+.=9,;ЄeIЯУ+љ‹U‚W‡пVЎЮќˆ–ХВoKЙі(DЏcafЏ]ЅEWn–ЇЏ+чƒe№<С­ьh&УЪRLщљ5С}R\ь№иD|‘|Ќ `uŸ*;wюPм•УНаЩCgљ \нбБ*uc8'[р#ЎppЁЎ Й‡C\UФёлчГ $ћ8Uт‰џЮЛяНGу3Я—^zI=еѓžѕЅRЩЙ fШд;Р!СГ?J•-ymOЃмўгhЙцваhV№ЖџъLLX2юO4@^Ž1ˆtТ1gжŒ™РY),ф‘КтЂчїм>ЙjЈлшт№DСшqXі7ˆМіЙ&ё>y№Б{%ц7†.У6й› ф[їINzŽ:м-*,VБ<П{ЖћгcъБЄ ЈО%—шЪ‘ЎвЈѕћцо”!сEc&Чд8ŒГ)ž>ШБœ§юЩ'ž”ŒŒ нŽшщB шiэšЕЊyN Z,'i‰{‡рДјo?аZeXа§кЯœ'd†§Ќџ`щT_!“ЛEa&';Жn—ЈД ƒХnќ3ŽкšУqм€с@zЌБи™“уH~LQљІžУь‡aаМЗЬ„їD^йЎƒв1Ње ‘вyt”6іыЋЄ# *–Uь—иŒЈи{f’ьtXбэj=эpL(tЖ KdŒ=’—`Ѓѓ`YЙ,ћd™єбKMˆQIfуъкxU ЖЗžўЗš"ЃvзКХk@|Э’‘”Ёž$ЖрL^їнгА<І ^"Б –(нR,ЩSДƒBн’=+˜“Ё;ЂˆV;Ш”rАЪШЦ 0-Ћ;& ђвПў#ѓ­„Сqˆ№.‡ВžК‡•ŠU]7ХЂ# С!уддЮВvэZXНЏ”ЬŒL5ђЫpюШ уС   šМ]:wбŸ6^y,…•—.ƒx5`ЛuƒхнЛ0PUc–…Ўф‡ Ћvфјјxeьи4Ќœ‘žhмЪрШGnoЭ—3gцЯхQŠŽгPX}q ОќŠ+ЕЙЫHё5*ёТМмЦба^\Цrя“ѕeћчаыOЉ*ZТyп`ЙхУZЬ+"eDЌŸм41ИЇWЇ}]щШєЖnйЊЂЭRL.ОјbЅЧЎY]e7і^:К\ёKХЁ­лЖЊŸ?вqЯЩѓ ŽH[ц{<РЩ=TJ\Š$H”—wП' #–ЩpЩд”X/Ы§fЫŒ:œ5н"ђьˆчЄct')Џ(—ЎYYк&œЈ oвУI||‚єыгOжmXЇe&dІgъD† ’G`иŽdŽыа)iсЪ–>2vвi,ъХН№ а+њѓ[Єqю rВЩxщN>ќ6ыы'П›й:НŒТcEP˜є+п-/^–7LYчЇ&œ#l†Њq@VИV;\§pвaЌіЁцFй8ПP.bіьЌ’дEHrS1yOŒўВlе\ЩЙЈЋ2?ЮƒЉšЭ3r3?˜Љ›+г_|WюўбНВiЭ&=Ч7fфXЁ3вЎЙ]!ЂЈж•по{еNшšХЋ$Ѓ[–tыоMъ›ыЅЖ6gПћ‰\зѕђЦSЏCЋєr‰‹џb2BЖњž?иУЯžz7LЦx8€ОŸx4pР=@vND&Mœд:И] єvЄwGŠЯtЄ-вc{рNяОЗјОТ|Н;R<Ц?в{uaЉL|ХЎ&Y_ˆеIzАє)‘Рu/Ѓбў(wŽœ@ВtЩЋŠL4) ѕюoЙянq9АНікkrы­ЗЖ{ЧežПуŠл оёмяЮЕ{+Ћл SоHО•sпhЙ>МZ^ћяNр‘ŸХЅЅѕЎ“Џp_aLчwп{чyЄgї9BNџГє?ђШЦŸЩВ ѕАK‰”Xl~'јЙШIvj6ОйF'ђM_iЖnн*<9~ќјv‹ЪОЮДг­\|Я™ћиБc[ёж^mСњЏољЛŸ™ЧЙ VКЄЄ0Yј“CXЕУЬ ЖY|1AwН ЧfјЕpУŸљчMюxЧ…v OЁ ЗlЗы†_'#ВGHaqЁкІЌœ.9*сЗ8AђѕM[Б іокдшеЛ.ŒЫ8”&˜шœЬ˜х X:ЋГ•гM/ŒЇŒ7d„Nwo­ƒЯK ЄЩ4_–elЎэчm-œ@B›­ˆлОz•м5њ~‰эиIšvЎбы.ЏGŒ.iёiR<7—ж-]ІН2Mіэ—…-”ћўї>ЕJЃзДРBюєn2§•wЅ{П 1лPЩъ™)3_џPюўС=Рџ‰ЫшНЫјyxж>цYQXg8‘zсѓjљX˜ЏќМпёљXТмyљJcпЖxоyКУНпЙŸнїGJу~gїМZzяђИуиНХхе&tіЎѕŽ}вЬ~­zу-У#Д•УТ-ž•‹Я‹ з;ХЗ№іž-ќl_­œМкvQT$Ь2‚hї€щ,wt_сю0wїН;ЃочЦ•чнŠ=bўyƒ}ЫЎюїжі ѓ~я~gянq(ъхј янщHУќчЮgижрJšЃЮ*cђМ=?uхŒBџсЊв‘Е­:|lS ЩьЃѕ22(BD^.!Эu’І6§I+2ˆDкЧфў -ЇTр.##+C&O™ЌОџОірз$*,JВsГU„JџƒмJЦŒ%84HlаЭ•gЈYzнНзуLMДдсЛэ6mХўТмЏяИтнбŽЄv ю‡Љriэі%nмQнžmТйЖ{в\ИкХ;'мhŽžћбc8Ћпљ9єс  ˆє|mS7ŽY'J*8qцаc1§:у™ƒ3Цѓ•ЃуєTЧр˜Хђв0m(лJŽ:vЯoъЄх4–šxф‡ЏЅсXЭBт•Г”Ž]хё[tž+Ш=М'№фчЌRvEvD §ђEрPъж}љиЈ…tЇšy0]ф/+Ё<й9Zї§Сž"АqЙQKЅ!†уЂѕnЪгХНЮSФI5xЦ …э@ќkРqЬŒ, DŸЮћTж-Y'w„@k“к—О М‚fї8‡.Rl0МnјŠuvТ8ІХ%Р^Їg–ЅрYлЊZ­Ayl‰VbЮ6TUЂ<zєё†ж!oЮ…†wOјљ(•aЧ СQ‘><|iЬŽW™˜ЁсWqd`n№~Жw wПsп“Pю8щiщК/Јўлџ„eљ…О%ЖбэНБ}<ˆБЩ W.œR%IБФРЭU`@лдЭЬIPLO•Ќ’ŒЬ,њ†2ˆ,{ценЎю№ЯЫНе™јЇw“%ЛШfў—\вхjщ”+oЏU&їОI6•l‘ЭekхЛ#ўGzwЩm/ŽŸюrйЬовк;wџ;оrœЩјV^Z•1zЗ06@—œŽџєщBљS=№=еВёЛQвЃŽГщжŒC‡ЌЏЅkЏюіўTеЯђу•“c„[ ЗТХ4YXДюЙJЄ ЧЬюшzЏ\3xВDсЌ.Ч^лъ`ZЫЇНrŸhy™Џѓ6ќ2ЬойЗk ЭРј€Ѓj§ЦвпWŽЂm8№Y6D!Lњ”Ќ?œafœx$(ˆ'bс5>ЁSМ‹Iz^ƒ, *^уш у4fъАQ џhaF oЮ0]§! W‡šж“‡>|љs8МX6Џ‘ЌИt†ˆдtОЪmeА|­Ьќ†}q>So*c8ХiЇq§ИѓАрYГf -Žа Х:Р№Р1QFУБ ь#Х8kK 467W[пЎњ?†kУ%пniwtрРzіеТ,нБ^э{,ЇнЏмО\fэ§@ъ›с3NП›ƒdbќeВГxŸќpъфџ.§Й$FwTšфw˜ЮвЖв Њn гъbё[у Ѓ]wЫ›W2iS Бoй{{Ve“F]ЄЩChŒєyЬПdнЧ[dHf …ЧГ ћГѕјЩВ•ыdм‡knЁЩTŽЯ•EVdjlEДGVA9?gE,6`#™т8Ъбе54Л чѓŽч­qDЋ!_DЬpыМ'XGrž>ћЫt$Œ%T7GЩЏчжI lзрPіСZLДЫъeYIФ`OwіЭБрX@БŽТмМПЗ&ЁzїvЬ›й`bё­,іЬєю{>цч^ІYЉqb|6ŽwооЯ–ЮЎ–ПЛќGKciэЪјaсеБƒ$G$KJKЂT„ТfjФt1 rOЗJhK,fџztЌНќнe`оV6оѓlчіэлецЈЏєЦИоР|˜ўпo§[ŸїънKщVyи6f]Ч;нЙјlѕф>yМбЊ‡Qј0щZ^#ХАf@ _SSњ…Ÿi‡H7cpœ‡Х n\?nz%^xо;žяxїї–э•™{>’АQА”ЕоgЪdXТp .РйєРўв’Z/OЮљЋќјЪŸыXІ‚‚Е tеUWЉU.я~dEqзХ№cДЃу)ЦfwІЃ5!кPэкЕЋeгzeкНљ{хЃYЩWЎљ &ЎйБЗW2vїН'Œ ћIPЯЮ Ћ‘§oўP g=#3ŸжћюсuxзћTт"њз[№бљлOџЂ+Т`˜ыт‘ њф;Т+П"/ўљE] вKћ'г>‘чўјœЬ›1Ovцэдp6ф—p =<ЧY #ыж­ƒ1х•Акs@­Й,†qfš #ЌZЕJM1q б“И„[Мж3žмiIЦ ;Б ЋђACќНХ…ЪХ]УБП ͘E8Ё!#ІЅћ А/Кўў`сїžyц™={ЖЃеŠ•ёOч| 'АZЎь8јЌ^НZт-[ЖРˆїRй€03ъНiцРWуЈp`і 5?хЫeщв%jG“ІйlсЗЖmлІЯ7mо„xK…§ hYƒ†Й ќWFЬOд‰rˆуc…xьГІФv”‹г'Ъ[Е?–FиаКИзdщВћъЛѓ$вцOблЌКЊZёД9oГм4ŠЭ6]…#K4ЇХЩ$ёѓФOЈcgцСе1Md-AнMkѕHэЛmp o4кL`и~ЛъУ9ўУrsˆ(-­=јЩЯўАMжц7Шф.X B‘Кџ=ЛdнFgЂ–—ЗEЗгчтˆa#ф­7пв>ацПrх ЧT&{4gGм’~ м‹\Зn­,НьйэаЧ ЃХГ€ZЙ{%˜_%Ќ ХKЯ8ž єрnВyХVёOФž?ЮG>Vё й]Д[л†п[ƒєєH;М23ZЊ!ЭŽm•З†БFгФЯвJЫŒУ1šЪFyyyjр~Ќ,8>АВ_Ищ‡}…ДBkc„@<њ?Іє-йчръi$яš—ЊQYК_њЭ”вІa єпRБqІT!ЌI—Щ‡'цЪU]jzЊ,ўt1ŽЯъ€FMD”пБy‡№ь`]5N_~љexKX†yњЉЇ5,##CM–б4Uоц<]виёkџњ—šˆ#ќѓ_ўЌцбvьи!џї‹џS…ˆщp›DІTUUЉ^вЛЄЫ’…‹eѓІMzш˜LС Я=їœ”—–Уx{ьJ–ЉMЩ7^C:&tRtпЩїњО*~oк{p1{V€хшь,Чв%K•сu€и’v8 SЇN•рэ‚Ћ‰Ѓgн„ю—ЩGЋDvnя.vxA2‹C%–™"жМ-Ін$~ў†,`. №іў#[7cФ?ЋчЊьПюЛGВ`џшGŠЇmлЖТeа45 F“z4ЗЦСю7Пљš+.(’НњЊцЩ№і`щт…ђЋ_џ мЉЪTЯpщлKЖУ ;ЅјїЛљ’}гv)+­“п§$G:тЈзкеЅ_P­,ўSŠєЫu“ТУУ‡œвsC Ь:GюѓЄЈАH^yѕe0]Кti=tNЛШ р8€Ііўё'[WЬ'ƒЇ’ŠB)n.‘4ЩрМPЙ>э6йЗЉ@B"ƒeOњGЭгтЉyЅg"[КПD'•њѓŸд%’jtЃ>§ЯЇ•qяоЙ[%pЫ—-—g~(ѕЕѕиВ(аОGŽŽŠ}/WКцЄыš+ЏЦxм"3р’~iBŽоNЬt1kѕ+С$Л цйў„ўЙ“S•=ё‡фŒ–Ј<я,ЌŒ‡™ГтЖЊCЈSQНq‚р7+) к л$5&\Sў ЁЮMšNRуЎКPДHЖэи"с1ŽŠе‹WKџЁ§U)ƒЦЙsКчЈИ†ГМзFhПЗ–ъ‹~cъф']*#†>}рс"CŠ}/{rŠhхїœ#TМ%›šжЫ~ F™ kжЎЦr $$dнšuhЗэ’кЅГ$Ц'ЪЄImІѓЖфЩ­7н*4œMр Џ?v8в3ХЋ:u’Gў№;MФц•ьœy$oЦјДe[ЅМѕQ•L•"ЫЗС=DЭЯќЋPОs–<ѕ‡юJУюBsп›іX9A;z,ѓўEёШ>УUщ™tЪёЬŽy§g{>Й qЄіwЯчНќ4Gu”щрR)4RЎКрЋ2їЉuP:Œ‘КдJYPљ‘d@йgа5aу0ИлnеcR_Пуv4б{ %?l3Š;Y~іН§`жd„кџбз8ЎђЌі(Bбi‡’'dЖ уЄд Ќ3i!oѓvuAЦќxрœ+їФjєЯNhLOMЌ‘Т\UВUЖ]Јп!Y㘠W.)У7]/LhcR`с%*AZŠ8Нп…EFD.—ш]ЛHПQ§х…?О ЎŸ ЋСБ—Ž•qгqhWЬ[!Ѓ'жCмЎlОМ= АЩl№b'uwTšьoМѕК 'wпsЗj&RdЛтг}…’‰AŸ в˜гXЙє ЄX+gšИїИaу:Ÿ:с3птїшИОІLД4УеxC"МQ,ХоZ)ійbbcє[f4€eюпw€ќўїП—п§ўwЬB.Мp<<”Яв тўВRѕйц._{xгФј  Pж"E5№{˜ф/ыђЋd~Ъ&щ’p)ўѕ|Ђ1•NџЙДDУ‹вА^EpСT‡•BGLlУ<‰7>ј}цљљљъ}œžмc}ѕ•WрA ЂРО:1r—“їdtUеUВekž| 3ЊоГwwYКbЉњgфїМї]v.ё[Wз$й]#хџ“!;(рсЛу"хЇпNтИЎmр]fzЈЋхьnй*юŠU0лŸ+Пgž~t(=zїT†B|Н€Щд”;ІДт’љЙiг;џc~Fљ.шyєYоSок?CJwЩїю§Ѕ5њЫ{ўЏH$sі”&џ^’ ЕНn=˜$шЖGЯњ ŠФ—-Уq 0эн{Ш_ўђ‰ƒїЃыnИNF-/ПђВNќЌЪP={єФўчbLDЄп€~:§№§е[ ' SnП]'{+WЎзўIњ#уЃ˜„„xэV??П_OЃЂ$д>‚рЉОEрPљ€ЊByўЊЌѓзћDЕ#†єek”W††Ÿ…KіБЅЩeO­—ЋћРНФюBЋфІЁЙRPК[вFbЕ|y’ˆшT—ЋЩ0А­юcгŒЉ3Єc œŠТъFzvzЋ?4КDйДj“ ;X6Ќм §†єг| ё_^]@'тШљYя-ъKŒ+(2>ф8рѓžЂ2њcу{s)уЪѕА[З{1sжGђт‹/ы mќрƒџЈ}ьЕ^љ-,œSД0ЎВИyэ0"Ю`Ы1›х †ћnLC†Щ?Юа9№s@fyљЧќXф\ЭБNŒcяЌ L[†Ч|Й$Є1ЎNщB‡ЯЪР| ЬƒхdЧ7†ЃћHјХЈ\Z=ьН&єёCмбENЪївтC2mg“\‘й$З…/џЂwqмЈBќ*ѓEЖЮ™ВCЄS†ЮШiОђИъЄ‹*w9(ё™8`Й‰+kSоГžoОёІ\vйЅК—Я:zёRзgёУ<ŒNЫќмо'жm_'7ЯКVжFчЩ…)iАЌ*kšђdv~єkљж…JxhчuЙwЬ‰ ЫШrА|,ЫbZ­Fяь'ь_4ВA UІaж•.Ъvюм)›АЧNq(щЪв‘Бђ™xс ™п УдњёFРё ўЃу`јjв >9/ѕё|џaUМˆ‡Uтљ›тт дUdЮq@>fГˆлx(DBqЖВЌДB2ќ;Зжžo€ѕ˜о}{CˆgЦд,BО“ЎšЄЯŒиŽ{cд|кР!еєZkf_о#œ†#ёdBЛч ‚Ч .:`ЇJNю$?ќ?zV‰L`)яйці-Л2мю9Р'&$2H"ФЁЁIњЬђv6Цvяt|еянРДЕи зЩЦФ ЬƒЬЮ€iИ‚хŸеУžtхxСR}ЅO€ŒЯі“и№_|1еХoх›Дoщѓъ‚IѓЎYУУмed›~мx6|ш`цEчЧGж‹щMŒЮ| єoЧ?ƒуЉЋЅ9уW}A,IDtР#=ЧБ<сЈцg€8фоЊ/0џ˜|G<‰!N\У=пЙяљ|"Р6 фfхЪЬычШд•яШЧ{01‚дэš r}Ю2Вї(є5Gќьh3Е™ЛмО#YvЃ Цч3гИыMZc}9ёГ8,“1D Фћ7уђ`хkХ“взIЦ5|`\“‡?>ЊBжOoѓa)СВzџFuдмŒ}@МІtЃ„ЅBЕžZЁŠ ЇоDš™L3тДƒёŒЁHѕ|ߘ"У}XЈqrќђїШ =:„Я+qЩNаи{RВлZл…žЄЬƒgnя\‹vи•я-їїь‡%РC{сŒч~чОїЮУ§lёьъы;ЬюŸр.ЗЯ0ээBєНтЕ oš‡wš+јxkL8ІE{t%~YУ1†xBœoћ*З'‹vёсŒ@N™8PQaТЛіь”йrlЋЏЖ=ЊaёкbАД‡зЯ§ю\ИЗvъœ.г‰I8лD;+Фџ KOŒЎ}жгG?iЏ=мсvoп8Nј}‚Іq ЇЯd4b;Щнуя‘)wpuрј…—`VeЌмюoZžбыЧт3ивИЃpя›Юz-ы`їМГЕ4,'УјŽq!ЇёМ"(А8ЮЁpKtо]YЇк-:Uп!Н0€Х+В…б€Ж7Амр§ьыЏ8к^yЙг~бяй|FМv%N|св+яїжЉiЁТммxЧqЇїў†ЏИОТМгožоёнљљњžЏ0wояНŸ5ЇУ;Щ|аЂ/мy Єqњў‚ :љYVžw>ђtbоŽюВй7Яfэ–†Ww\ОЇ†БwИЏgtўX}Iуœ„(­ђїрДЕШЈІХe˜нЛёб—я}роW˜цхŠл^wоšЦE;юОхюЋfУж,ХИПcїV'wќію-ћН7НX~з]6ЛЗwPBV\@‚CЕlŽТM,ЭЙv=Цbг`e}-fŽ7"EgИ†‡8KlяЊщ{W !вдю­›љqEъ‹бЖ›ј‹єэGBхСяЪrG3гМуFђbZю1аО*ˆ@ƒŽtян–оyOлzЇ§\<wœ;тП‚В"§9ХЕцкЩ—ƒїyИG|Рџ€jEЖї—ъдf‡:’жuП;G{jАgJњtiCВ…’oЙx—;цПgЁ‘‡–ЧD ЎъPP^н§‹ёN{"‚|б Т‰cв њ\КуЖ б5 ~ИBlЕЕц+W‹x_‰ЌŠѓKЄx ДюpОЊЖЛЄиР …—эЦњF‰я#St)ocУ’q“з€> ЙмW&‡ˆ6`ыГ‡Zэ>а/Pm62Пh&&':Фт!7БАЁtFЃDџ9mCЂїе%ЮBЁ:NKёœY^НЃѕ™mєTрžїCˆ[vTюёё@qe Б IDATДIІbg%m`Хљ$=TџC§aјєТїptA$т‰&/бLАЪs†f|“є@eю%rпг{`ГzXПd{Ÿіи>ztEГsЫ.ь-і•.™]фЕЧ_–Ю0З–„уЫ–.Sпy9=sЄЋЫђхђџйћРЊЎ#эQя*IH zяН›j0ю5ХIМ‰эdw“Э&ы?›В›Э&›dзvїŽqСЦLczяI„ЈTџя›ћЮгеC`@МН{ящgN™sцЬ™iн^WAyХy’—'яПєОмї§ћ$БsЂvzЎžв3гЅМДъГЪ%95YТ Š_э'{їь則Ћ—и„ижЙšU_Ђнь>t•ЩA†6АЏьI, \hЕЏ+_,|ШnbŠ\SЧe(TШькОUт;ѕ–BЯXьj ђТП—М}%ф,4cœЪTBhђ6щ˜ќј4nцiw3сь~ъцR‡Іт\ШЭЄižчЅ W7ћЗ§НЉ<\§эu7mСЈЧhлi‘g7S$_фw“ъЅsЖZЭкЖœW“ŸІ­\ѓs§fиІР„c™јN0nЮ№ŽтPыЅ ѓђђ %Œ‹Т­ LЙљ4,б7–(E=чmЎWЂDЪОд*Br6(b&Ј†Š5ФЗpc№ЭЦЪЈ)йNЂ`мRИД7Oюј”Х „K.–ЏOЏ—у’Uu@zњ”•i+eVЗй2Ўч8Mœу˜џ›*˜Дэ%qus§ЖЧГћ™ї†>|~њJТЙaФ=Y–KСк@:>nаЌџЬгњrж† A мжћФH™o‰:K;Я ЌIg тЛ”?eГбzzPD”WЫ'Џ}ЌФlѓЊЭjнžinZНIѕ’%Зaх%|d…rеGЖлъ/V+ыэЙ_?'yЇ s/яЌ|іюgШЭC–-X*' і'ыd–ќёgД&qŽˆ[и–ьЬDѓ˜bл:ў.„њиvM;шиТЦ‚g№ŸьY(iчв$ЎMœ$G&ЪДјлх‘ЄGeBЛIђЗ]•е{эр ‚ььwЮєаŽцeb]ЎnцлјлУаїXйL8WџŒо-T"NO‰Ÿ‘‘4Q=nЄSp§98_}хUљђЫ/Ё7ѕмgЭХљtм^Žа ђЪK/СтЦvuN|Ї~вgŸ}DЬВОСК/^ДH6nм•bŸЋЎRjcљлГЯA‰їyўљчe2х'!\НzЕ|ј!юўЬ$Т:БЮѓп›Їz?_Fђ1БZЌ‡ѕ‹Ып˜žБPHi +с’ъS-ѕGіAЖТ‚ФАTъНюЎ;хХП§]–/УН2ы1qђDЇЂgNа‹PТЂ/i]XџПA]ІœњqNЈдIЙtЩR С:ѓ\˜uГпЉМ@єVуЬ~Š"ХАђ^'KWф№^— із"ЗJ>]š'i\HˆZ?YИp!д•їчПўАXыaњ(?јNќ1!„ œЋšёeЋž—ћƒљ–‹І=ЇіHFEф,‚ЄЂЎЖKџ6CхШ&ЈџЋ –™}gЪ_vўujX„энЛO&ŽžЈт™-ЫiЪkŠaЪgяt3}кј›ј&ощЌЌ‹.€vюм%ЧLTmFЪ5 !4п7мCW'0џсA-С.Рѓ&њsRdУ•W–Iї„Tй3el<ИQ~јђФ+ВVІхЭZ'i=? 6‰S‡ШВbХ йЗeЊ\Ћ еrСГ&ц““…Ю (<[ЈюœДJ‹J!‹d­|xXKЂъ‰Jђ~"yэ,WEY…”–—*ћЖ№Laу•ЙKnЦOт…BK‹W­P…М՘рaЋЛЇltю1cЧЉ2]Nž$*Лwя–я}я{Ю{DMЕ›і 4gB›XIџ9љёшћdA\WфЪд=+ФГџ0ЩˆФƒ ТгO O[їJ/^,™'OшсhH˜Ьš=+ы ЌЉЅ#ЕKЊPэгš5kдХ§мпpЖˆќиюIIIrїнwы.‹эEˆКџўћuRYђЬ™3х^(ЧцEbд…Ÿ~"§ Н‡§nј№сЊ•Ÿ*Ы‚ ‰fїю]rІgюОыneqEЕR3DУ† —QуFЩЊхЋдL“a 2 цЛ`С&Ћ}œ ћн‰'Рй(“ЧЫѕ_ЏƒчЭ2}Цt‹™E&њoM§YЩЋ “Jш/ODЎПuџ'ѕлњ‹ЧˆGЅ>ЉŸІЭ3™iгІщEюБуЦЉк,*чyу~№#U˜>zY™7wымЅnмМA~ёѓ_*чdвфI˜И­ѓёІлTГqўаТЦ?<ѕЊTМZUТpСк,”ЬЄщ мŠ_ШюЬЩ­Џp.8wv,ЮзШЫЋЫфЧ3q KъkЗ”Ъ]3Р& IКFЉ”ž–ІBЯЉЬ“ђљчŸbWT/гІNџ@%„ФУНїоЋ‹ызоxMƒ „ўЮYГTихŠат˜&œо/Eu2ШцВT‰k+^E>R”_,UуKфxэYшПLNцdJзФЎZ†Н0і‡Пќ ЖЊн@ЖѓіmлeУЦ ЊŒсЮYw*зюƒ>Pѕ€ЃFR{•_}Е Њ#кячЬžЃ‚Ž/Нј’ъж-U—‡~D5ЭЬƒе^Д6l˜_VGц‚€цšў yЏ‡(e^Qх[q$*•ѕё‡a$—?o_н>МРUJЄРйаsu/Ш™Ј ™ђщ9tьˆјсŸ‘42еЅb%„)(Ф’д5IђВrХгЧSо}щ]љ|ўч’к'Ц_Ё ъМ7цЩтї+л408PђOцЫŠe+tђaAвь$дШп­_wљ№Еф‹љ_HіЉl$HРo^ъ0Т‰Ч;яМS8‰.„щЂ)ЗM‘Л1ˆз}НVQ1cЦ Е\а.ЂvіoФ„МЁ-§GOJўЫ?“‡ЁWіиќљ’іХћаz‰<НNкgЏ‘u+>EыZь'кФыйГ4љ D+lœBнЕБНюНч^Y‚]Э)Б,wЭНK‰ wњd§qїХIž@6Ё™ЬI2‘mФбž w2ЃMc=lЦѕэkћ*˜aЬŠžяŒOvи>шєфŽ“yвRЧŠеЫх7п‘ЏзЏUХз K0љ“рИІKZјшеЛ/_%9%Х^ьŸјїNц;ђOЛЃdUњeBјFyВы^ёЫ;„ BВwЯџŠЌј iэX9KГоХ™гfЈЊ8тЧВ/Ы—,гЩŒѕЂісƒ‡ЫsЯ=ѕj@соKжФХЩNœљ='ЧQЗЁ‘с>fън%уfŽУ9ЅЇВPЃcЃuЗУГCгxW ]­.Yд*\eщзЏПюЈ1bњєщ$ гПHї*qNЛvЭWђшЗ-ЛfgЃž.?œbМбї6Ÿ>%1ѓп“Т…ŸЩц‡Џvэ%щ=C?йЙj­ЬХd1ЇGЇЊ&šPъгЫ2]гŠŒЙУЈРЄK љлЖo“>}ћЈюNКѕNdu~‹ у@Рi ˆ@тg€;ДЩ“&ы.ђиБЃPHmЉOcПЅеjь:dЈЖЛ!ЄьФ '%\яПя~%~zHOOWТбЃ{˜ŒšІЖ9iРštiЩ9Іыє’Š‹-ЂЬ3p,ЫхугNХ_ЫƒHямЎrЄ№2<ђ!ъ5…Ѕ6Ё—xU@ёvтƒ›!ОСš.ѓ2yъ$ъЅѕр„7V5о~§M9|р тсІLŸ*ЃЧQуЌŸ|Œ]+кŒІЎ.дЖfЇwєШQ)РMхУhы ,`†сЌЇГŽІ0­ьIш юP>ŒёЮњ‡CP-џвйWюК=Sўя•*љсЗ’фЋџЊ—]У0o`к1Ёеі іГN8Ю‰яЏ†ŸЙЈˆbПю”ЄЕLŒOдлмєCЊынЋЗњг<“й97-4fНГ№]I ы" ƒRф™o§Fb“уdђЯGШkЅџcHV`aЯи…имё“›R kAБCыгПŸtэвUuƒJ„Ur}њcaŒc ќут‘rфUcююжЙ›Ю•ф>pГгЇO_иZ\ЏуЧдзJ ПVж0НS#VЌ\ЁЦXй#ц‘ˆљГ&ЮИ-њr5гОФ‚r`ћB™vxч9˜v\209цCяhїі}e”L“Гй%еЃ“šd,;Вq$Žњƒтішxa`щB„#џ=:*Z #У0.qhk‹@7vb> АбxGБМЄ\Ж­н&_/љZ†Œ"Ооsм1aoі'<|'p`sїCр.‹;NрџЃšё‰Еs3ЬХ&;ІGГC= ”XЌh“кYN€­ш CЪ1 p‡ѓrtwЕЛБ@ьLЬNaо/%Об dAИ7еЛЇxи>cОЬŸч4, їу?ю$‚œЌiUюgфШ‘Њœ›ЛТя~ћ[XkШQ–(…>и?hР—Т- Я\ffІѓмvзh•žТ;ЖяP)@т†жQЈŒ›VсIаДмЮ2Шze:,ѓ сf>ёё`С|­N4Ы–/mdЧ С$­ь8и(0З!Qрв•Tњ#}?АЙSцЭ›ГРcњНxбЫзsu?ы^šz4ѕƒЙ„уŒј]ŠхžxBІL">іˆAO)э6шovІM%гZмЌE‰‡ќь[QАєю)oЎ–ћџ5L† —тђZ5Ђ,)PЪ“м,ЋдFШˆ‹#*ЃЮюH№ЪpЗnэ:й b“y:SяZццфъљ,c$0іЕцB–›f@Тй‰ЁзsўCі…o“GŸЙOІЮ#™‡ЄЬИ\lљЎч#’в1іsхdf–<љд“2љЖЩђєOž–ЭлЖшЫШЬPcЛ;AЌ8о)ѕћйŸЩБЃЧ$#з d;,"T’“:Љ}O^Ÿa§i цЦитХ‹$s-ћЦС§БыД8,'uœВOцффЩєCЕ1њƒ'Оn=цў_)6№Ул8аC.бЕЅ2Л2 ДЃЧ%ДcИF†(;чJ“…XМ|НœъЎšL‹ˆхС<›‘/аTЙƒaTз'кK‚:ˆ :ЬЫ$їKп8мlзєх(4;˜NРћd—кѓ1nh#13aL<ѓд0HКЮІB €Ÿ/]ћv•Ž˜шЭЙЂ=п›юјён;s$ж=b•uCНм=G$LД6Mќr!ТСP„LA‹У haƒ †ЕЗСS9v ОPШŠфЁ7^—ЃП|FFПёŽЫВнћ%fHŠLЙяn7|ДsЁУИL‹Qwa(-MtТЄЬœoEС\aoпБ]ЂЃЃ.x;тS+>YЌœД8IБNЛpОwрРАЇЊ)NLЇOg ‰,ыCЂE§‰\pЇЩKуыp–Сњq—Ч4И о­[ЗЉi ІЖ30єЛЛеpЂѕ!БczЬgэкЕzVHЖj X œ9v@z1 т{|'\юФkв#,ФnГ&4;иѓАЛЗЦwSV5УЂ іпс#ТњiБHŸ0™ы_&ѓŠр7рв^7“ц7ЙбпжўnћMяv3LUеUђюњwх™cIfbђЪІвoе?,Oѕџ'щдЋйy6UNJ"Sиkќјё,.•Ѕ0nhXЈ†БЇу FœiГ-Э…ЃІ^FWу;lиЪ\‰ J‰QM+yт ыХv/ ‚) Є&О“x€­ЅФŽР‚./W“вVŒ^˜ ЯєЈсхDЦ беМБAГ;:Б€d<Ѕ:s‡a•пФudж$!6щ4їIТmšЄЙiншёЩкb˘Ж1ј‚эжT…Пƒ4ВgOЙ ь•ьŽ*ѓ3%ЌwИрn)№Ў‘ЭЧvЩ.˜пЊ@Ÿы›вW !ѓцJšy›|™МkоќцŸ kŠ`тБ1йЭL=\у3МЉчљq­x&“У5•ŽЋ›)Ÿ&УИІcТi Ч‰ƒСЋ0.qЂHЂУ“‰DЧжН ј§˜љ :OрФm/‡:внG c+љvуЬп$pог*˜iЇІв1y~sZч%~M8?ЂЂќeЩС›CŸ ДgSDсLНјn‡ІмэnцOзw{:—ѓЮtdЩ?:цQеe”dfgBГ И9~в аZXZ§ЮДГ‰ЧИІO?КW7ѓЭ'ЧЙ6fwkя є7aј4щйУ0BЮі˜tјоx‡ф№ИтЗВДRєwЫaтк;Ш[Тл‡KPxЇ‡†ДAРЄЊ\ќ—Ю—H_zMS“—жеJЉЭ8‚ A–њ!ыNЅKyпaR—ŠнLЁvš‰ цТ*vЮpb:DK€W€кsHR{ЅJћАіzMсNž8ЉьВиj=jugHтУђ(т@ќHРљЭY^i wЊMѓBєS‚еPƒ–}ГЊеВiо€ЉБѓšЬт›wѓМм*…рlН.Й}‚ў1>OnЇЗ‹уЋЬ2іќьяєчЗЋ[уxє7. uhpБи{іoОлгl*ЛП‰ћMnKЇЉИ&]ыIЬБ"xђ5Є-XЁјk.”–ЋЛ§лўоD’tтdhзt\Пэa[ЫЛщсaО2ytг8u-ы…ъе”ЛнэBяЎщ_юЗ!6Щ1ЩТ?;?Кйѓ7aŒ›yїІТ›0|2]#HwБ1{Бєа{HyhZeћ#вбйёж ‹яшіЃjMЛАИP*}*ЅМО\n<ЈЪ­I(u@aхMйZЯуЧФkы rЎЈ@ЪwЏ•sЇ3Ф "ВО5%тSS*Оѕ`­Ÿ•‹ЭšYXyк<™qRц=їЖфШ†%keхТSЏgn< .Њ‚%gЧ?Њ- ДЮЉ\™R€dCВ<$r Яђђ;W$–BлKeMЅ6 ѓ+‚tTУп 7и~кЛёTж3žtг3\є>5Œ™™nЌъ]евђL”ИСŒ$ќWрг'наl h_Фy ЇDsЅЂй‰^Ѓ :o<ЁЗП–.ŠCЮышWšv„иQ9'sN$HЯЧšSpOwQНњѕ’’Т)ЦхJоQк’ПYE`§wѕ т$j(KјьŸˆ_4„—Гb еиБН7ѕxїŒ U‡xЦч`™С—љЌ[КN&Я™"НКѕ–’1х­?П)йgВѕrю[}KКшЎJkя§іНВgыHПЕ“ЖQmфЫїО€Ÿ^nŸ<{2ЄюЪфѓwОP)Уžƒ{ЊЊžЭk6KR—$0|€,]ИTЊpЉ™ъеFM%Дnl7WюИзfА№Љ 1dЫžoоЏM)nА\4Ž\’ЦЬynh1 hПtтдљвbщ_‹„ьcыšфЧNи T9ЮMQйл›‘šIЦіdŠ”о9u(Sвw‚ЅYћИ3т ёрšJhЉ€ZЋ:м‰С СFLWšRsўa`YbЇЊ„Љд9ЪХѓ?˜ѓк†kœРx~GЕeIЉЄЈЖH‚М‚ЄЯаОz 4RЦL#&Oоz_я1й)ЛЁ†ь`њПђЇWЇфCAv|Ї2bвHЁ–JЙMЛ{šŒ>BJ!QЛwЫ^7}œФvŠеЛ-dšЩеVuїЋ7ИвІYУ9dУ‘ А"+ЃSd{кfщ—0HвѓOр*E‘Œя:ABУšUчцЌъ›•Б;ђ-F„аu­з˜!љЂ!Ф6‰стхёhмзыа-Fђ–хIuI•д@œЕ*„|СмфEKЌвЋJЋХ wЇъK‹@ЃX*юA)I Н№ч Eѕ1Ютq7H™’‚"мЬ—„ш5]tќрq‰M‚хHЋ&Є$H0ўХwъQnЄQ]/ВEЉQујaшХб_к`‡˜q4C:tЇРьзћJ&Tq} Фхyр‡ШБЧdйЧЫdЪмЉЌц“мФай$ю—› фzzƒ.Ы\(ƒЋЦШзYЋ$М6Ry§#йxП,YИXя.ХХФЉ ЮМцЉ>б5‹з@мКгJqЬ(y{тђ{LДJщ§­ŽqВ|С2\№„5 м ЃбЩЃ;HкЉ4ЭыиСcвf˜ЪРъ--,FЮ в-ˆГ–ТН;7ZК`„жNmRdжРЙ2М34Ж„еЪЌСГЄ_Їўа0_!їљЋ„H~б]0^JО$Ўv $/л7Е фwƒW оИ“ŠЩ'pxв’ŠRCЖm˜м+YэќyAvUо9Љ№+—”о)zЩ•ўJDXьКєЧ/ЌЮˆЛУ‚C=ШДњЉ'vwAтсћ]аmh€‡ŠЋЛѕэ.ўС*4бО ŸgKL\ŒФХЧJкс4;c,bь>aеЛN7И1pГc мЗ@Ђ`~l gљѓщЩААйвПЫPщWšŒ9Ф’рpyшe}rlTЛЦ1Ч*/№S)/Йm7wДœБdЩyр4œŽkhтEr#Гуз]Пыƒo@ЬуКцТ>[Ј<ЁQЁЁ+EjЉ№ єеw/“73ЅРŒ'юїUсbЄG[ЈШёk#ѕи­€с Љї •Ъ<( ЦYЃƒroeO&Ї$K—”.HЫКGxЎўœФЦФJ|LМцIТ[X[(Л6ю”щїLWjjїTЁ~FЇЊОJКtM•n]!\ујзЗ_Яє:!ЮШƒiU!Цsƒ73L9jАBЄ“п™жЎZ:еuoишєZћ‰ФƒEъ;хWRпйвHC+40M1j„*Fџуџ§Ќ§ф DCЋШ9œПŸФxŸyћ*…MгTд4fЬyсo/€[к•х2zдсtГMoц^v§ъцmŸТUƒmС ХбЉnŒЛІЊЪ*ЉїТuWЭ2X)R­u=Tс”жп.Ѕа›Wпщ6`%„Ÿ“шсеg|И䇹ів[AHФtАl1MќQЂ“ЬДLOеLуgNЖ%Ё#K†—яYЃЮЩ™Ž#su–^>­ƒ=їN№њѕ^wЮз ьцеX4чgw—{ђхli€<оuЌжя6'vK}:ЌHnYƒћo =qБ>X‚ƒBdмјБЊZ-ФЏC\ЕкAЕsяМ§ЖќћЏ­*у–/[ыs…жH9† `ѕу1 ”—_yYКїьЎ;C71МfЭ~ЫdдАнКšU&ё2џ„…пf•ЉYУW7ъ1pъz „/Юн€SC|7мmДЎZђъGc0ФЯюJ7$€џVždГt.EG-ƒ?p€hЯсЦ0šЪУјЙŸn мlрЩЛџс|е=['ЅсR‰яŸ “З;BGeЦыRзщ.‘c0ЙT”-Ѕ…Ji&g7t[~ќЩЧ2–(Ѕ=pа`EYŒСЃ[ddЄД…fВIЭХxJjгЂuЗкЗ†а*7‹TБсўii \BˆR+ёБaGЗ•ѓ+С—ЊЉ‡Y#еWHТй&Bъ§ЈЎahЦЦБIРxЯЩМF„ж”юмс5UІA5md{ъeыњgKС§ъЦР­…Ў% ЪxsзSКДЋ—Œ|*пRё„%rIž*T­cеrj‘дфbЬv4(ЧHь˜(ЇaSѓ8&'%RЉ6$С$zЦЂ‰нЙ@=|шАœюЪПcдЂ &•ЉcwшPпЦТИСФР5!„$LМІ€1$UИˆ\е0­kE@„ъA„ќ6,—вёŒя.Е9И X&5@šЧвZєhPЏ†щ M$`МOШ•#m§QЁ6ѕ™’Иpюђ0–Œ;ЫЧџќІњ5šњ р -WзU+g|Ц5qЬ7ŸMЙбн n м  йсъджCжЅзЪiшжŽ Љ‘ŸЗ['žiRаN< Š”.ЙьбH’кУђУЎЛ$:ЖН ЦNh!ƒ@•XдwРЈƒ‘ЃFЪ1PJqЇтœо5ДŒqџƒqъXsŽaэўqc љИК„ƒ‡;ДŒнjѓЬ7ШWjЪkєМ040T:щ хйfŽ4КgяЯџQМNxЗУ# НœЦ1?$ ЦoЄfУgRvАT?ј#Ф;ЇћDАДciАсї•„Жы&чŒ 7TКїътjЉ`c6< $ј!/ю IЩ"хюŒФГmt[•jЃП? Ё„ЙѓœQ•z# § kеŠТ•˜"]уІ™ИмИ0€!Ъul4„Е'&{H\vєIˆ€ђќ "{пCЯ‹Дyдёg ~08œы`ъІƒўpgЧХ%ŽДFOж'пi‚Ч0 cНZ– ;йЇжM 6мЯ–ФРе%„GБшžу{ТD5ŒW—KLTŒlYЕEsX,H%„ˆЉв їŠWA†д•`чш Сиђ№ЧvДRМJФh/ЉЪђI#ёБФ?ІЅ/б ю]КШЉГPж] ж ўЅgЄAJtД ШШI#AжЎZЃzќЪ`wєфбj‚,šН{їЊЊЕілы@\Лr-$мђЅзро’в)Ће#В{ѓhБ –aу‡Љжœm[ЖщU‹Ш6‘2`д gyма\ X8lЮи(ЎЃIЙ5Зˆ7qќІ№дЏЃ—№ЯЦєT$~Д–'`u kє^јS‚eYŸ`;уЛЋЛЩ‹‚kК Хѕ Э№лФwІС$1†э`тлнnдїЅ.7J9э§€en @]\zTSЁšщцыя+%9%rlѓq9ќеЁ§*НdВц“ €a IАоNЛw”рTМ'†ТxnАХуЏC&Ж ЫъЛ–u#1ьдЅ“Ќ_МVжmZ/%e’’˜, І_ОЗXњ эЏ:GП^њЕЎї_ќ@:їъ"си=в-ˆFGP­2™щ™jmbяжн’“™-}Cl"Е…х…HыK8rхMЋ7ЉбвЗџњЖєа[B`̘ZtЬюP+фўЙ" АЛН–F€тJ2“'Ÿ&уv%щнJq žьИ;ЏўрьHB/иУ“DрЫ&žЪРпі4ЭЛХџ&,ŸёёёкfЦMгжРж›ннž–3м №bЪЭЇ‘Y0n­НјЮrЂщЬXme6хdсСИ™ђТЬЎРЏщМжЖЫxЗд“”ЊњDЁcАГUƒГBšdђˆ„и TЌљУXo0ŠQ…sAOœТšЖе9А*ЌЧ*”Г#XЉzŸАš*жЌСУ…[&п>Y-•ШЊЯ–KСўп%AЮфШ‰єRVкрЂ} и.ГП5G:wш,Q1QђоsяINIŽй}DњъЇђ‰А‚ГE2zк‰ƒyцzєфQ)).“ŒуzИп6Њ­ЫєћЇЫ–Е[ЄSїN`нњЂ˜,ЈšƒvTНl TVžГЌ~\Qzˆя Еx5АVЮ‹м‚т ќ.дVloўПЅсbИ3ˆAыœžШjYœ]lЧСўAі)Й8\|:лд”ыFyT.РКАNT2Ры]Ў}ЯЙ‘Ax;ЯџzU—PеTтќзлWоLAЕ_шЃh-л7.ЋОх œ h]ШŽcb39ЄФ.ЁeБЬ х\94IљILїx‰€]ПР6ЁИH[-mФ*зМkН)GЃ“™œеОётWP(žgг XcБZЌт!5 КЎ=ЌлTЌiБёs№Р!iз^:ƒ5Z kйщiаjгY-'І$JRч$ЕxQ D)ч№ЯЋиž{ШGЏ~Јкg:Dw};іI‡Фт‡Cќ§лї‹џHнљ‘Ќщ$$CŸ)ъ@СœфЩ(Я§ц9Ё{dDЄл…i”+yЂуzbДгЬUqQБœЋ‚„ЏŽў+H iq1UuЮ:&1фюž@Щ‰ЧŒ]+ іџz`›š4т­ђгю ВЎ38Џp2у8І0sОЮхКььйзБш>k6œ IиЕšщи‘ ЏЄсc ZPъjй8—[‹G`™8ЖЈwДua‰>BДž №vХж—+ЧЭ)ЙЧj6љу[Yю6ќy[Ы фB+ИєŽэJmMЭЩ[у"C ЊДЧ] ЃыŽЉыj(дЮкwZ‰…ˆ#’}6ђ№†@LqЖTg0 l“,Д^Р]Ѓv§Ѕg‡№`t}peR §Є›Wm–аˆHšVШИ™у$и?XЦЬ#–o@ќzщоЏ‡J„RЙ6;ЩЮНЛШЖЏЗCE[7–‰Рu 6pПa§eёќ/фГЗJпa}ЅGяо2 ЊжhюIгъпC'й=›і`@VЫИiЃaь7b5иѕ^ЗАqуџЂ­kq6ІmетФЂчО&=.dHh=ѕŽ(ј ˜X­3)‰ˆˆP"iТоЪЯІpз№ABXpЖ@кДmгŠгЌ2xxщб$›€Т"ь|ЉбЙ sLлDиkэDТй иlGц_‡љА–{8Чz‚@ДУyђu†в\ѕp3у *,у‰]ЁЄМvAЙЦA`\C_ю7’"Ё‰я/q=т>daђЪХ7ФWYˆєsВІ”иaШёj•sG@vyoьСЖeqДX(ŸЮс|aъ%ЯЊ” ~$>ƒF R  оаLУL)Юž§zJjПTM‡вЅч|д*C ’ЧњИ–ЕДОTњтLeЃ ЭЯж+ДnС=dпA ˆиAшЦђSU[ ”ћ€ХмЈNЪ§s%`sз’E qВ2Гњ7ЌГF‹єЖ‰ C?ў‘uІ;я–nнК D’ЫИ"S”Ÿ!‰НІЪ‚ є5Ф С<“…kpэЄ4ч„&Чxf1M“.нљgОЭгюfЪхOУ"?‚Н›4Ьг б№kO‡ЎфЖh|GMHп<;ŸMЙ9§/€;ѕw”зЄaOЧрТЄУіВуя&ž гœЇ=o{:twѕ[О|ЙŒ9RжЎ]+“'OЖoЕяІФŒиKBлјJŒ˜œQёѕi`9’›aТ›ЇFСщЗіі чГ•+WънM^gQ7лnЮФџІgC~ у gЫv)ZБTqЌсE­@˜9 ѓЅє‘GeыЗзHџџќНЕ‹вўaз&-гoLŸЂ;џЬЗ)“НNtЛд>fђa“6пu‡Эu7ЎЊ#5њвљ*€#mЎрLЁх‚Ъђ^]l9wзЃ/Ћ0œэР’NŽгЯQvоTZщ’†3ЮE^L|“ƒ^(-{˜‹$щіК АјуОшЫ—ЩЉ“Їdќјё*eЬ~CќяоНK8 ч)У‡ƒЕdgŸЂџў}ћdѓ–-’НЕС7ŽLКšr‰Œя/[‹‚ЄЄЊHкр|щгCdPh­єн-Яѕ’pЯrёч1€‹ЊІ€љ№ЯРaЌ‚™ŸЎ˜rš'ЫКfЭ™5kT…Ез(;Жя€њБн Ш12aтu[ГfЕфххcQх)'N”p, M РIW‘цЬ™Ѓ,^ށcЧŽЩІЭ›09њЪЄI“дRЪ—‹ЫYА л‚5aТ„FИуYЮG}$ЩР „Iп<їяп/›7o>wZ@ќАЮ,ћ‘#GДЦЎЇ kОMКtуБЦ-ПZ˜ЯЊ>јрщл\›žPЂўBэ5œш›–ЭѕъЄfpЦsђЊjШL@˜0зЧ’ŠЪхtF™@}пЌ{OНюЕmл6НŸIэ<ЃF’ЄЄ$-˜щїќ ~і@н]Џ^№œ={ж’мЧЛ=œz^цз9<,СX- ‹Р]qД6ђ€XŠxТ0{дмYRіЪkr8Е›єћЇжђЌZЕJѕЬRƒуlьиq*ЯaГk2пІxцлр‹юіwЎЉ'уžЬ<)K—.е~ьImƒАЉр-шж0g\Y№!ˆЫDI?ž&[6oqЦel/ЯzЩ:[+sсМ9ЋRП~2 зўБ^nE1ДІјњњсЙE333eыКuы$ѓDІІХ>ф<(’&Ь›7O>ћь3Xf(бrUd [Зn’’’"L‹““#Ы@фЇL™Ђ’v›СBbниo'MœЄњ5?џтs]Ÿє=zД”C’šyNСxѕ’%_ЪјБу•Ы mчЮRZT*AЫYHIѓ›`pЌ“”@œбЯ3gђх“>PТlсnГ†aЙЬЂ@qБ~УzIKOSџТТB]˜ яУ=\†9zєЈГ]x6У5n5ЪUљ9Š:mмИQжЏ_яЌ…ЁМœЃ€е&8§ЩЋФ=jљїџ9.ЛNTЩЌx,Ъ Обџ;ВяPБVчШ‘ЃК ЙуŽ;dдˆQВрЃZwlлКUёQсО^xAОўњkGх\PnкДINddДjЮьм.^чЄЎТKE…тA&,>}q„фYS)mю˜,uП)™V~ЧаGИP7~<,Ыпџўw)+-SТœ2­\Ещк7Йс‚’э{OJйВi[žѕgЪВњГщЌMдЪŒzmСbyыЖ­РУnёЄ@y ‰Ц4‘эe:q2№РJчШ. \№І­Z! пяMЫЗкХ#7K$ї”О[#гЂЎЌЯў=%Р3@ЕССnaiY)ючу ;Гў1ўёOMЙ?їѓкc€“:'|Њи €Р” †. ‰ Тj/!Ё8/ЖС™3geШа‘пЁƒŒЧ ЫЭЭЕ|M]ƒ3hO\СмN$ЛВBJѓŽЩ gфŽЖy2>(Oюˆ8#gГŽ`е]Ўё,X ЋVЏTЉрўі7%Dћїэ—u_Џ“h(‚ž?>6Ю Wс‘иС™$Ÿьw† RyДё+ƒЪ@о‘уюА+Tž€J?Nи$оTЪw??KhНдйOyї6*Ъb+БpGŽ–'3eуІ’––жnˆjl! јLўн’ѕeРєw*ИХYуž8C†Œют1AM”ƒ;4зіяп+=БлњХ/~!ы“ъёуЧх?~џŽнш—ВџР~йБ;^L0ѕ'єнфЅ-ќГxјЭo#туф(vЌƒџЋ™oKUЃa6љpсI‰Н/ WП*хЯt‘8\sлЙНPњћVШ–чуЄOЋ]!ЩЮqBЩйТтBZaПћјуаДu\ћС;ѓобОЧ>jкс7aFЦЫ/НŒEа­Fs№T†4ЊOž”Кмё(.’К2DЬС^ЅEтYR­\uДy/ЄСБкАoЖiгFŸфŠtэ’*YЇГtqљйЇŸIpљ$OOO—?Р„Whhˆ,\ИP9$т$Ž„O>љDВOgыћEш хп<”Б eћѓŸџ Y­NЃєЮзэ…D ФЬЃ0W|?I"СFђjлAj ‚ЄќЌдя‹a|аpЕ{6HiЯбR;jк9ЉјBР!Kіяи/A*ј Э/1ё1тш/ЁЁRчYЇЁ<ЧуyŸQЌ­*б._ŒM0Б3Йсњ`€ƒ‘+xvђ‚‚Г2h˜ЅvЫЮТс@~уЕзeвm“Б#9asзCр W‰dG5xžRPX&ЃЯЩї я„Ў8 м/ЕћdхњЏ•е4|ФHМ•Kзn–NЬ$ЈXБRŠєєщг~ь9€s+ЯЧlУyяО+гfLзнx?gDСаaЙ}ћV:С’С!KH яьoш*ш'Вы2ёJ[,i;WШ‰гyВ}яQѕ•“йtИо3qвd!$А™evyоиq…„‡@fœмsя=КЂх`х]0BppєщгG‰Ї:р‡ƒцТіојёА"ŽTтEwžсЌ^ЕZџўїœqЙкчЄ`&t.8‰ИCŒ‡[ю&; ,Ќ‰с˜‘ceЮнsdшрaBЛЎј ё а8tg혢9рŽњ?wрМ‰pшаСV&ЦѓЭЭЩAі”лІо&ЉнRхŽ90Г„]г0,HЦezмyp№гŸќX&Œ›@g'зўйКuкт~Iюœ,Зпy;<…rм–›“­Иpёѕѕ”#ЧJф‹Ех2qXЄœм3д_оќ(GЪЋ=ф…џъ"CY„lkыuџ§їыYјŸў‰*!qЉЦ_Qa‘.РŠА!јЭ{ŠЖ™щS|š>ЎžW№Утј“QЖdЙд="U;6ˆЯBp_ќСЉ€€ oМUп1UBАЈ$0Oіe>йV‹–,’6‘Иж†В†b|E#Нщ3g(їЄ‘miтБ‘p3ќ/ўх_dђDKЪ: иФЧ0йЦG—‡~XЂуЂхЉЇŸК;B48':žнQъMX28YёвBи”ћХ/9ZЄ+Иы§FіVИС.•Лqё”Ёс_‡sХl™cBcфhЪQщ˜мQRкІШЂе‹єb|NVŽ|њЦЇа3MЯћRќ`QЛћ€юВcнv™rЯT‰OŽ—ЯпњT’Лu–ыwШр1ƒu@QBДЙФ*Дћїr0@Жu Lю|Бш  TСђРТ"wнu—М§і[B5xЩЩ):ёO:U‰$w‰ˆ —чŸN9їнwПЦЅT/ хшбЃє{ХъЏфи‘S’•wZ†!эњ%ыЄ МїŸB‚!B 0ƒяœь9‘ Х.ь§љящJ<тсЦnоыЏП.п}ќЛвЌЧфф†ЛJ,YДц‰а‡Ilxяmсg %"eиM†HчИЮъgђф#[’ƒyВ dљb SЭѓd™I\˜'П‡œЈ—РђГ\tЃІ <]Ѕ"<ПŽyВœмUйѓd˜?ыЩѓ@ж•aYš52“=гaњ cv Ч№ŒЫr2,wˆЬŸe5ИуЏГMрŽeб,ђ7„ŽѕЉЎІ„ЎE'ќcšl .^zё%X-ЉЉЉъvБIŠi].7ПTŽСEёn&wS'–•eaXћdzЙy]­№,/ёBХ>`џ‡AБЉЄќ ƒЁsИ<юU*џ!vУљFРv%з€щџ\\qN%сœŽsЋ9'6a9^иN Oќић˜ѓђ~Љ;š‹OoєЉœŸњжУв~ѓ6сОЯ4Џ.ЮWЪ:Jйw~.юЪТ,Юћ)9qduђHœ хм ,SЦ?Yэь{ьŸГ%ЮXўчŸ{^ІN›Њgє—аіcм-хžЂ†аЯ9шGhИ4Hо-ШПЋФE`%Н§Ёв Ѓ`oTл{u-4€фBЏ8*FYDSŒ† a]0v‹`gZxHdѕФЫƒ„P№‘ЉRš8!ђlЋG<.Я))и+š№ЖАCˆ-=pЕ@юŸoЦšЎJьD‚жLd0ќГлŠўlo†5чІ§жД'…lИџ^йt`“ьIп#'+!zp/тyЩо6{ЅИМXFї-IБIЮ<пІIcˆ §˜'Ыk€пЬЎФ|ѓI7уnЪL"jК›<щЮ ЬєgЭ#ПYЧІ№cpЧ‰Ф„7iмjќ рNѓТDэ ”А5Р0œœ\щSШ‰D`pЏ-јЃeЦX7 “ЫaЪТьL§[0ы–OЪ1њјxШŒАJ Њ/–NСX@9мбДчыeњКЋg˜‹ ™=ЌНꞘk—ќэ(\ћн%јѓХ’ўХЇ’ŽЏљЦFKл)3Єѓ€VUаOа!ЮыЇк–pч“eŠ;ећ-~ц§Э7п„`TIJJrЮѓ&ќ…ž\ йћ†щ/ JLнЭМ›я Ѕж wŸ‹Я{~-3hьzяЉ;“&5Ї7‚оarQФ!Vu"]чH]КF™&W†аR,пЙњбUїе5Ъ#&Ё$Џ˜тКдOкЎ};ЩЭЄ$Vb€И˜8}КЎи>д k‚І€aЙШ"Аc_(œНŸ3ќ дAв3БЇюˆFіЉу€‚ЮЯ1С›Дьщкп5O[ўІ ЮМиŸ]Ъ}^ќ ”йЮўЮ<ЎnЎпVЈ†pv<Йњ5•ž cВ.Ь‡pБzн~ћэЮХŠ3NгЭgOў›пј4e0LYŒЛљ6ў|Њ_K”Сžhsо-4:S0eя(ŸќКƒіCœ§АфжЛ3ЄуХ‹ѓœ›шOLћB81ю—‹нН1]vv^ЩQТб@GП-е=ЊЮ^C‚H`^Іž&пK)П cЪHЁ8žГ7Z7еЖ.86щ.pУdЪm‘YюЙ3‘,.މгЂO3a—(w‰РUНељC_ЇOœдїDЙИтd Y8Ф†юњ`HйYєЪ™ +EЃЛCЦQѕmхR.Нів{Z‘QћЉ ‘КєьЂIё=ІcŒс…шLНЊdŸЪ–hŸhXжn†+T  нp}0РЇTСЌ^/жœф 4Žв—F‚дјѓаxfв0O–пzW?[ўЗЁ8тЉŸKZџ}эby6ЯофegЧ“ёЗЧБПџІpgOг„ГЛй'(gš6œиу\юЛIчО:™!уfвr§6юЎЭфtПN/Іœьу†XЈю[д­\w&~ЃАјhЪН)7Цkф~|\гзxd6ъ‚GwРзž—§н†яѓcЖЬГЩ>цš--3hњКР Їж'Ќурќv8_Ы‡t ВђрqX˜ёЊЧЉ:г2Т ’ѕИ+Xu4GъЗq–уе1 g>уsэŸ, %Мыѓ0ЮИpE1Y'3ЦL‰Ќ2ЗlЉ/ЕГЏxVЊgј6,ZЌQS>Х5р[#]ГLVмгеuъ$хmžЁ’ь7.Ы‰ђyPI8ЮњxqТHрщh Ѓ+”лhуf.ѓ›2сжш ЅŸЎ#€~|œђ<зл&]АМ`sч@›ulёѓwВиС•Є{+Фi­Иг‰ § o№Š”ыФfкЧŒ}NЬWк‡LZWуЉ8ЦЮ‰Ч8”€хтчуvRЧ)йп§Ÿ“ xмƒ9­}X ЦYГв@yˆS.Ty}Эимбz{с*цtzoА<іrXЌQЫПќЂЄ@f}›і(ЄЃдM–ŠО$‚ЄмСNФЬЛyjHgќЬГqjюЏы†L\TКMж—rЅхЁбP ЗpВqУхa ЕтŽzN+ЪБ‹‚РШь—\ЄёЩЎАєЋГ’]ŠХ}UЬ&эк4mЎЩ5оЕј&—…cдNјіdю‘уЙрьUC ”™ я_ƒ›Uдѓ§m•ђ я"*”}нЋ@ЩB%лпee( ё-м45^Ј%‰вІ\D˜№—‹OюАєЂМTО<ИHжeoДŠ ЩЊ>$Н§ЪъŒ5rgъ2ЁїЭ†у›џ›*˜Дэerus§ЖЧГћ™w3ўэсLњ {Wувž$p—ђзЪъ.CЫcФ зfВsВѕОž}ЅЩC–иIш4ф]ЙІ%‡OgYъаьq91‡w˜xџŽƒФієью:pэЗР{#\Д"м5*—ЃшЦЖЄЊ1оё4mMХшќцѓFЋ.Viэ`1&Еѓ–žшЋОƒЖiŽu#БчUлЉ4Єє7xajьѓќ&Ќ^НZЧ~\сI‹cCVдTЩЧ{>‘ŒЊ ‰k'"dZ‡™ђ`ТУ2Љн$yqяГВjяr+7T…ё)ХЯ{­ЪЊt”Э.S,3FM~tЗ‡1ўt7aјdšФqsѕчэ№ЩЧŸШџдэ•лu№4rР‡:3ГКzо‚пФнїПћ} Е.мB…иї< K—,еVaЁp'B#$w#4—1ИKКPZQ'‹—eCHаS†zƒm— bГ8WŽЇs(А+ИJОјт Ј<Ќ–'јN0“Пі]$.Ј˜Z №чVsЯ„еˆWјУчž“{хDe:„ЅВОLrЋгЄ›!rxгq Њ –™}fШŸwўujXРюнЛWЦ §НщšГ)Џ5І­Т˜ђ™ёOWКqЌ›w}С= +VЌ0^ч=i™eќˆёjЌQk…аЪѕЛСЧ§цЦРЕРЯ+`5d2дхчцЋІљ˜ы|„“к}їн'Д Aр р ›шФ‰ ЉЊЈRUgО^ЏŠˆЇC')у™СХ•3…(zь!и-м,уЦS“.Ÿ,ќ:;;HсйB™udыжЏ“aУ†Љ•ˆН{pбІ^†nFЮBЗмYњFkхahйГKTыFEсwёРнОНћЄА PFŒqUqЗmљє?=­ ИвЇF3Yк'ШжоlьЧй9Вч‚їЮƒ№LММІX~<W}ЪjdѓЮRЙїNЫЎ%ыB]ЃВ1|„ќѕџ*ья4іХчŸ"ЎШДЉгдСчŸ[ІНюНї^еЬє*”ЂGG”œŸНБFЂкžЫХгСь§RX%љўC‘VЊD‡Жƒ)>S"UJфhэvљЬ…œЬ9)]ЛЊЂьН{їШ_^ј‹Z€HIIжБМ ЦГ7lкіo;™5{–JПџсћА%ZЇšŠhБ…і=iJŒкxцЬž#чЊ+хяћЛ$@ї.5ъ<ђШЃа—{Hоџ}UtСqL0§˜’ЃіаМзCA>v„М4hўАт№рћљB(LФ n \ Нˆ§щЇŸЪ—KЋ‘U“ЏЄd‹šNmќјЄђш ћ8Аьg(Ž]сЮлд ю€~d3ь›ŠЁІ*4$LюНї>шЦ„оЦcGUiєкЕ_ЉџВЫ$!)AпoЩ'юЖТЂDŒ шOмmRTPХW˜+ю`&ы+ю;%^UДUbсДКE$0 Л BS}фЊЄ‰›+EE•ђЯџ™!їН{NоџфЄЬИ-Vоћv˜< З_Ј—зўЇЋSX†DѓеW_U]ВП§Яп ёЬ1Т…Щ4X%!бћ№уѕ<gЯž­ў•`“4X ЦYXxЁкСцByv5йт]х%л?о#)e]хр†CиСWЖœћZ•<ЏКЬjAащiЧ`[ДŠФ‡H&ЬtхCч-Џb,]ОT|рAU$NтМ|ХrЁMЯ|PmuВЌЋWЌB]ц п…Њ™4ЮTЩvї=їЈ”еkVЋѕ—{№mˆ ѓ4§сјБ#P’_ХєCхгƒ‚јёO5j8оq•рќ"“qƒWШд#:x№`щ —ч}ћy%@Д ;ЗнЏ,2B9$ yAаs HrРьмЙ?GЈDКК*Г‘~v™У‡зАTњK §њѕƒEXАJ7XжІЕ цeˆБО~@)ЁЉИлЕgQЙЊpœЌHтŽ вэИуюЋ_п~jѓэЃ?”ЎЛ^5м™ д–•Ÿ“6Јžй]ƒФІићGkl2t+˜Зђ‚ВєsrлwI\чHљйфHЙgVќѕЅ4Lиmфы?Е•'Ž…`Н4hYФ„}‘ŠгЧŽЋf•*СЎцn'Њ]{иьL”ЖэкJb|ЂК‘ЈUtдCKГL„žАZovЮЭСM ЖŸ; чЩЦЪ53ЄНќђБ_ЫіЏwJ@woљДфты е˜8ОЅБaТіэ;ЅзFxЬAv№ш)e9КvщЊЛљш˜hkЌOп^}ѕњwљМ\EУТдE5~МТ1љЖЩкO{a!ЬqЪОaъыЌ—ƒ‘УМЋ бКbх ‰'їсCœrХЧ@dљX8vЦuПИ1pН0@ыцЦМй!\нqrЃuі'Nшa7йДЂ””$ѓqF˜˜’$ЋVЌФЊp UtєoN7lTk sяОKнЛb­\НJ-H˜3žЃаt ЁWЏ>ђлg~%}КPПoХ."wи='%%ЫмЛч*ШЂZ ЃХД>с BIр„D!$qї›ћВ;ћЋhSЖ'МЅK—Щžјю˜з›oО‰vЛfKю4Z;pGшээ)Я|/ZэѓвЋхС_„ЩшЁАˆR^+#†Ее*hЅ-€!ёаХмѓ`\™уƒG kзЌ• р 9yњЄž ’­M|ЛtV|А­lЏцBнel L(Л‚жљџNцD§ƒ|чз‰ŒЧїH-`6ў}Яѓ1IIш,9Xˆž:uZўёЂe3fŒ<ћмГрЦt– XАЇu”\щеЇ—J§~ нЅƒњв;ХДю&0жлУ†!ЏїАЮЏНђštщмEОТ^л„}†ФЬЯЯ слIяНѕьžхe=’’єњKzFКt#!ŒТпЖэл@јѓе;Д ЪЂb‡ і0Nм]%"hхЈћ#}e0ЛA–УЕM]ЫmтЗІЇЃ{b—ф/ЫџБJЏ˜>Ф№ЁбЫˆ.ЃфdvІAП_щ+/ССЮ|™?СФуЛq3яє3ўMwžѕсnпœкћ‚‰gЏ3гЗ‡сЗ› nh•0›yšAСТ7SpЛŸ}й§MѓДћ™wѓd˜бЃG›Oч€t:м/O|кпэU7юЎnзwіr]Ќ?АlM•г^цыѕnЪХЇЉCx˜ЏLi~SЙь80i1ŽннЄaws kТ\б4аžгшЄЎщ™pцiїЗЛйпЦрЦ„ЇП= йѕ†eokз№Žе†нiК ЁСЌћйК0€Ž^SƒѓЅЦьўr J­TjLЖ ršUт7ЅC)IВl›“ї7хбк§Иƒвђж„;*{f{RШƒ—кІ­пФ+Е!qrіЋѕгГMЧ† }§ЅFWДіPŽяVR–YЯjб?ъ}юъrЗVЛК€ШSiОƒЕtбA+oцУwW08fXіWс 7!t՘ћћњc§˜їЃh4Йз(нжbФЛ„Fр р‡aЉ\џŠЖў4ТЎЃДмБ?p2cЛœ)h5хК’UРmюРrбЇ 0—„МqхРŒšZLѕ\ЄЕ`™TаЇcж˜aєqзo”‘DН„ž}Gяѕ^‡Ђ3_#}^Sл`Мн аM &мЯжƒЌif†вoa“n 8уqFY'nы—ЭжŠ;BСЖQ—ЦFМќš_ЛдМCA.#ЙщšsЎOдVc‡…БюнžЎ!ЎуwЎHdлШFьЫzŒп*\с ЭуЎб70т:аЪšWБ4эц nBшŠїwЋРЙ(Цv$wrЎ<§K-ЄЎBБjхгЩ>УшtВR0Hна4Z-ю8ЛЂƒА=YF‚§Щ]Šй=Љg+ўБуиьђŒ[CБыхз/Ÿ–?T@ХZVЙz*LКtЂ FŠў7дс/VїѓгmШсJоLz|’=jЦh1Є7Г яЕhыfЉЦѕ:мDˆКџ^Iž2U| УФsŽGGц+ћ•”ЯФi*?КŒŸ{0иr?[!H­С}Ѕ…k4!ZЩ)ЄЛИL›‚„—ƒг P3XŒП§ћJЫs#ХkЕИsДЃ+.M›ђiкj5Ќ,№в9Ÿ7 М›:АмžСОт€]UdvƒжД­ыG?f_цŸ‰Ы8Ў}™~ІoS› -u˜pњr™?іМИ0!фэо+ЇчП'>Иѓс$Q`IFdKЩЌйВљ—џ*ZFжЭ”й<™žЉ3Ÿ,kЃoЧјДЛYЙZузИЗІžі2ѓнрЬM›Т–лэІЦР~ЈsZМhБѓа\кЭ $Ь су;џš:ˆПЉ‘хR9т 5тŽхЂ№ЬgŸ~ІкSД­аnдKЩ Е%tiК тЊ}š uрy`MUDzHпТ ‘Ьr9+/™У‡ЋbiZјъьВNe9Ыхк—–nтУhR2nЮˆ—љТђzтЂzДХœ§rБ„…Š/­[PE4хx…Kє]wJФŸў,‡п~[Sgн6@чўљgВbљr5ВLwЖŸ,ŸfќQЦИ1њŒП ЋŽп№УАФС‚uх6&„Xi}Cšno7n Xмh+WЎ”?ўXэВ№ ВgЯn9~–ЕСъЁЭCNЎ4мU№nЅЮnIh w™'—„;ЈїКкИKOKWkОZЃхbЛ™Лeцy#ДЫM(.†$&АіЫџ:&‡sjdNLзUѕ2№GщВsO†й ЫнЛw—I'Љ>м>ј@нQиЏ§™ям§Нјт‹АђАM§iСхШб#BыTwжПcЛxAшЇЎМLъŠ Ё|ЛRАѕт‹:xжž“Ж3'JѕGoIсIм/ьйЕKѕ 8šŸ*ф%˜Mу8#Б#‘кМyГš`#>ЈŽšeЈ_4==]АдІCi[њSЛ ?м]Ј>f‘Aџ-›ЗштжQ ћj­.4"(;шЋОКмИй0`С§œ<КЩПџњпхыЕkЕšдLёгŸџT%TчЯ{O@=еZјQ%aб‹ф№СУњnвб[фЧœзиП–КZИћк†ЛЙ0юИѓ>t№аUЧнІфџѓGX‰–уPяFрDI0,A§hЅ?і™wбв,§0‰—VЩo~жI<ѓ*$уpБt‚жъEПl%д–№IPP ^bЇTЄT”QЗ(ЛЌm›ЖШС0EєLa—Eс3sm€„eщВЅJ`ž{іY5“ХxЭщлЅPP_ РuxzТR=Ќе{@`Ц „бjЭ|Ё&.hУ)‡48!ВMщUgэЃлЫЬлgJlLЌœЋ\PmX€дФм?n мlPбmTjуЦѕаMЋ СB›…sчо­“Щг?zZЭј„††ЉгЩЗн&ѓо}Gbcc%ƒћЮYw*JОiеyГсѕб{`xnмИNq"ызЎюц*юžњбSpwpїŽwй9йrЧw(ZZwfвЫЩ>-›6m‘ю!'3OщЁtаЖ_KчЋ•ЙJ?‹–ž’пP!C†Ж•)?8"_<›,§eGЙї‰#ђђwкЩиQm•АБnЌџ’%KT(ѕяіызWK•юХc=ІѕЇ™&юBg.-КЈ{ѕ‘‡Q[›ХP=F}œссъwЅ?Е z’•ŽMkёЪЫ’šмlёХЮаЃОZ<}!щ S]žUHнБух"…W/Xж%*=ЉЫ7==MЊq„:k+ #˜§‡až~уJє§§ќЅ„ѕЖ)Sфг…Ÿ@Op„юx^с‹ЕЕщ/{іь’Дciњw њДЩtё/—tgh>мO7n| pP1ѓй3gС†ЉV#ББq12aђ$й+йМpkDзљЮћ\m ˆИ}ћіђЏ?ћg™0n‚†1щЦЧШЅз@qеYvмХw“`і†l%тЫX€ч;я}R‰3wf?ПЪИ3gЖ;vь’3яЖэлЪј у•Э'PBko7NЙ~Оž`W–Ш_чШєБmЅЄжS6јШŸ^ ’—яџ­‹ŒДыѕэo[И№ј* П6 IDATАєqђФIœ!žгњ’ЭHITЖw‚da›1лЩр†lу‹{~zчVЪm^Жr­дхznL9'Р­?Д€ШЖАЮюдqŒ…&e 95A*Ьџrй\ ‰TЁЕРр@%„SЇOSЛ Ќ #jм*Ё@;c“nЯќт_eђФЩъїMэЬ< ‘YwЭVƒХпџСїБ#ЌБLqЈЏcc(u–FusџИ1p“`€|зmАVЭДXA…y–|(SRueI7&УRKHH„НВIэ–J/№NЬ бЯ[ц‡И[k }ћіQkЌxюКw Л У~#ютbЏюиNœЬiŸnЮ›žzњ)XYЖДєcВVЮ9Щ3м7MŒs=›ЄЪsЕш‡!ђтЏ“dЮГEВMќхЧ“CхwOGkљ=Ё!Љ)xїнw…64:"q`5’ЅHK/ПјВјBq}|bG]Ј№BљЛяМ+>є !гN†86•іхИХ+*$ŒцŸњtƒ ІRё­Jџ№P єьІХ№ЛЗ%v gЁ0§ьш|ae~2уЦŽЛїбзhO’lјSйYjM†Ь”—miо;b™˜˜"R:iš#шŒЧўРуо%ь;Œ<ф‰gЌщ`4Fi=ЌOдШ[п™рЖ>aАф~^] АЂяй­OpїfвЦqй/жС/Ѕp7ЛqЖ<Щоu6ЯЎc;Vж–э8vbuЩvЌb‰ъ•Єи{'бHЂїћџїрHŠ$№љсm3gfЮœ™3чЬ™3œП™PЃЙH>Кa€їЈ'Я8$ 7mљ2Ы{ЋэўЇŸZЌw™\fЬœnEїмosЏОЦ]ЏŽžь(›ќУтJљ8C0&3О…v}L[1€$„Жї‡!ўРјBzЂ@;„˜:т?&"eФ&a`ёЧ { iтz~Ъђж[oѕ™*yŸiЮЄќч3э…Š;/WY„™=И‚ жЖчУЩ;0КщЙіСбКuбd‚0§ZMўЦЛяОу9„—чбрЭггmб#FS(ѕьЅ2žj§эпѕзщRufJ]KрЛŸ­шIњTжЁLЁ.\У}јFњP^ОнsЯ=~жЅУсН09 t3BА‡ єЋ0[ з3)$DЯк!t,:ў`СПыSВЊ&Є,ўXwЁтŽЬЃH#CЕэ…кV”?Ј4гDЇЙЙ­†ђ&ёЎ№ЪЏах`Д9ићСо$9§h№–\іp€pŠњ[:“ ОгѕШ+9яфxЫ•ќ-дcЄ§гi$бхН„њЦŒ0Уё§…qAЕA:§І†&ДŽz}‰А0ЈРы< ѓЌW…pЊ ‡йтpтž ЮХњэBХхb0фh-жНŽЅ‹жz]/Ва‹cэ­kmiЕжьш””фj\ЈєчeУc}–#GRЃМ|KQЫœні yœ?Ча q;;:OЂ—˜&ЗV|с`@Š“"ВsД~ЁўfўЃ-`iYЉwваyF g<ІЛPqЧ –'ї]ЈЙ.ъ ž‘=IЮЈљ7Bп…PяВм2пІqAї-pœX uzР“cFx!PR\†ў‘vk@€ Ђў о2њGŠŸb Фˆ1pv0а_}v`ЦPb œ1˜А…™~Иž1а@Œ1С@ЬAJќъBС@ЄП8е‚њ…RвИ1b \МˆсХлvqЩc Фˆ1cр,` f„g‰1ˆ1b ФИx13Т‹ЗэЦAЩ#ь‹б’n4N\Хcƒ3Тў[@ЦLeуŠ\\kƒaѓыХUњИД1b \,|ћDЬ/–іЛх”L—N‰'tvtё>ТБ‹ЈИf1b œ)g„ƒЫ‰gšWœ>ЦРА0аэЮБГь§ѕЫі_џѓљ)ьвОТa%#Хˆ1c`ФаY4J3`­žќ Я<ЧBŒущЮУl›+.~ТѓxЦL\їѓ†ї(ЕhХД‰vЩ%SzЯ";oŠ3Ž1c`Lc@aUOn 1#Œ№џ=o€ллЛЌЅЅ]ŒА#^# РœрbXі&п3›Ц5^АјxO{ђу|:нxїшT%V”9Ÿp‡‚ЅВтЧvЈrAo”ЇЗ\–ЦGш0ЙŽмѓЌ~ѕ=›И;KАB}k‡ w}э0КSj5FЄЅZї2Ҙ!вйтc ЦРа`№oгёXGŽЕ yѕяъьДC‡[jF†3ИC‡Kй”bщщщvфШkышАL2^[Sc:Ж'['Ÿ8~мъŽѓћ––f;Z]c™zпЉИРJKœ0№а!ИЃУ:Ќї]]~ЪxMuЕ5ЕДxњc‚SЏcЛ€лЌ#ЗЊkj-KїэээvјШaKзСА –ВФ‘A‡uп)Ц”Ё|ЊUцжVЫЪЮБњњ:;жарА­ІЖЮaЕЕЕ жKW=КЛЛTЦC–Њњ‹C*c—†б еџшб#жЊ|Г„—ККZ;.”ЋЁс„ежзћ}kkKюt<иIИгxœž1мU[ІЪ~Zмщш*Nhю:†‹ЛъюTЧAqЇrѕЧ]ї Игi3УЦ]н%p—–DwВvюjЁЛ&Ч}2нЕŠ~їfœ ѓƒТ5zŠџЦˆ1c` Т |ze•хOœшŒaкєщVTZцLБЌМмЪІNsщ­ЈИиІЮœщ &фхYХЌ**’юпŒYГЩЄj š^5Ыђ =MХŒ™6qв$‡U>eЊ•N™Ђэ4]VR2ЩІLŸсЃT^~ОUTUщРх4Ывр>cі,1ƒlgL3fЭВм‚ФGЋ˜Yi…“Jж•i’ЪжЅДdR™•ЋЬдЅ@љVЈ.):7G7щ3Ф№8]ћ•[њЊ>нb(SЇMЗ’Щ“niйd›\еЗpb‘MSž0ямœ\OŸЎђeЄЅы^ѕ0СR4ЬNWйѓЗ[ыс'сnš`щ}?м)нЩИЫ•4“РнФЁp7Еw3†РъpG;€;Єтdм•їУ]iю ИS}Г“qЇgЧ]ўм їSюtсЎТЯ ˆЛщ*W2юВwj‡Ёp7Йм&мѕб].И›e0LЎЗCnЎOкfЈО)і/ўJM‚T˜myjЦž4ЛЌЛо~№;7йtу ЯџкІ]3г&Эžb=ZЋб,/1Ю*˜{‰ЌR›ЬЖ>ЛС–ЎXfЧ$-вLўђK–X›fІ1нUŒŸ5`HVЈ*a&~Џ+h8ЄЕWЉqЃ[Œ щ‰Ж„ЉqMMK#щђђpфƒџ™Тbн25=u,Сеœa—KхL.cПr%е—Вz…„тTЧА|,ј:Kѕyg жљС]Д_я|тN‹ƒA5кцФЈсHWоХ!Ц@ŒЇЦ@ЇTЂa’Т=чфћР(yŸ|сД№оєЩїР€ѕ‡%ъѓІSРТ8Ђм!`СшBy“ЫХ=п`hЁŒ!^rН’яQ ‡8ЩА<=љЋМVr}Cš‹чЉ†УћЁЪ8Ќ^ИCд—‰ШHqGY€Ы/”‘ћS–kЈњQЎ0їtИ#>!Й\ЩїЩэ|?юв]БЭdЦ"ЂрЎocaєџ1c ЦР`ƒп†К?еЗЁв ѕ^™D 2Q˜Ётє}ra€HŽaPх™ƒ?pЙ'0Иsё‡ФŸсфOР"тѓc§Ž+R5љaи˜ \ѓpŸќўTїJрЦgгž* х!џi’ѓ>Uњфxƒн'У„Pпx,§Љђ>еЗАдтD'Р]#лwѕёŸч) 8ъМ7 @АўPпсб]Н—ƒјєй@wРмзhШ!ОЦ8/РАЂл KJ­X~u№щМK'[Ё,уNˆˆёG:IVlY28hp†˜feг­S ГQSђвЉж|Ќо­њђdW,‹ВЭpYЯ)–Е_Ё,у€E'.•ЅYК:HЃтc…ЌuіvЭкГeqЦї&хCкY —•yкVЙхчMАbЦЌO•Щ".Mћи4иЄЋS—VTXЛ:|›œ y*їTkcъвšXAё$+*+Еb˜tєbYHNШЩЖ}WWО–"ЫКF‡•хЯm 0ћЮ•еd‰Ќ)U‡ЮЮYF–ZQIq„Сš$X9Y™Ž*Чtыб`~Аˆ,SЙZtпЊ­  &:ЌСЂNe§Y(Ћ;ЪХ€5зРъV}ЎUЮf1Ѕ. оyВ"MЦu‘,* ћp Ќ MtЈ“уZ–›JзЈЩMІ$О‡vЫ/ЎеVД–žE“Ї8Ў?ТuЉуКЧqЭж2С ИЦТ\7Јl“LфT$Э>BЖU\Кx‰Ч‡6xЧр,BёЄРЩеVƒŠq=ЅКйDYо|гMіўћялЦ›­ЃЛУЎ\ЖЬцЯ›oџыл#i,ЫЎ^Ев–,ОФл™Ж=*КОtбЇПР(Ў^ЕЪn^ГЦуМіЦЮ$з­_o?љ„­МjЅ]ЃяkзО&†а ювc7^ƒ§цеWэж›nЖ7пxKжЏ6KVЙoМљІ-XАР>ќ№—PлEнПeЉнЩF3~ѓ­7mЇЛf”Ж|щR›;wЎ3!ОS_Ј(ŸjХjƒб8иНkЛ=ѕьѓВє,Г6mДѓGboПѓЖ]~щe6YэєЋ_џкЮŸяLц]IёАшір'яГз4™xѕѕзl•ъБbйr{ќЉ'|ыЪ[яНo_§Т|ВеЅvb"ѕТ / Чк~"њzјС‡|ђёѓЧŸАE кО{§]™њ3e&УЌцžŽю*,StGП tз!&м*кы“OEёЗ3`(YкGе ЮШ€3!/пђssЌZћШP'‹AдЅVi“)--Е.IXіэѓ™nЉLя›Žл~}‡‹Ћ­і=Cyљ6AГљ#‡КњЉИЄФg„їягьЗйЪФ`ЈћЋK ЗtR‰˜Ч1‡Х^И‰b u’ЈЂ0ЛЯГ9Ђ2жзГIbF0С‚ХŒ˜ruˆб‹at’u:pр€яi*”iy­$Є‰b 9Њѓсƒ4“ж$Kб~5ъдЂriщ$ksо'иtўср„цх#f](f\­СѕЈЪ6Qп˜$R>Ч4š6;,іє•Љ\-ТјIMKЗ’Ђ‰v\xзЙк*/†T-†азњpн-†J*"\Ÿ№чз…ыšЎѓ-OкQэГЋбD\gHє нB(G—jРu™Ъй$†HЙРu‘іziи?X 3§ р:бnlЅHs: ИрXКю~РuЉђbаѓ}ˆ’wNЩ•ЉZкГkЗ,цЕЭ Сј€ЃтЪ;рРŽЊ\е5ЧlеŠ•ЖxёbќŸ§еѓvЅЌž—^~Й=ћќѓ’€dј"я]?№ ]* hЄв­NІMЖ\ехѓПј…}яћпЗg”е(’u[}ѕj{№ОћlПкsгіЭvы-7;ГDJ=af›ЖlЖ­лЗйю=Л-Om=-[КЬЎ[Нкї6В2[8%ЏP[ЖŠ‰л з]яmУd,рiЋОUܘюЬ‹[оПњЦлvчwкblEљEЮˆZ%92Y" ЩQц|ѕ‘+—/ЗыЎ]ээS-\uh‚ЕцКьїмc›ЗnЭ•ичљЌ]ПъjѕГnЏ'RZNvЎ-Нт [­Д*ЈэйЗзыzљЅ‹э‘O?l—_v…mлБУ2ХЌН.JЫ^Ph%ЂЛCЦжš^КcМHаДв <|Ма$—чv•+f„о|ёŸ Ќ%ДHХдЌ™/ћбиSЦ жЁŽ6E{вВебaЬжЇVUљ Љ![xЙОг5и)Rpš%­UXRiPšЂ§^YJs\АXл–€њ3 aВЖЁžj|ФІ‹6(uуRф”)х.ЯŸ7зё32Ѓ§yа;ѕЃў/ОњšжN7јбk1Иl—VЉo[{ЋUVVJКЯГЙsц8’7umвdяхЕoиЦЭ[\ѕЬXРФoЮмyN{SеггЂѓ"Ш›@љZдZD{eв&бєžLwєрЃ„i ObFс1ў{Ab Х%$CWЃ‰x™щЅЈ#1hГ)ЛPY‡: uъЮf1д{x™ iиЬЅ}kMОЎ”ц‘ІД.бyеЎЎ]АF ”—Ћћ”žAPY2ргщ€•Ё+ъ<:0’aж?`(HEРj“twŽЬЌl+P|ђe0Щж&ы\СG K‡œ |шж0H‡ЅВ[ЬF`ЕЊƒУp`ДKitшр9„’ёƒDк,ѕ)јЁ\HЗЈRdРOЋ$e7ѕ| MРRћ3(gРuЊ˜G?\KКэХЕуGА„p'‰нq-†Щ$"KxЉ1ш2ш+SkNzqъ9бn0ž€k‡•hЗ€kЄ№V?\ЋNmš41Ir\KЪюУuŽхf зj7С)ЉœМЖmпi35@ƒ кŠAЛPљэлwа~ѓ›Wэƒ>Д§ЂЭZyŸ$їююN›]Ye[ЖlvЩiЮь*I­кЏяЄЏЌЃК>И[d3{Ю,OУ3пhЧ•p—Їќ‘СIЋKmФ| ФRrРO/Ќ зЁ\ЁN\ССАл-Gв€?Рсп+kc‹-В"<О‡ф:qюь9юрсИ&>з^s­MзZ$:jW˜дЕW_cљšTL‡AюwkЫi’ˆ“/цСФˆЃЁ ^YћŠT|—[ž$aђп€1ALU!ЊR&cМ#}4I*№u`$BЄищbИ…њОjеЕV)ЦQ&yеŠURСOВ2њŽдА^9mZ…MаФ‡ЩpQт?u›˜ђДŠivщ’%^ђнДyГ wйТ ђЋPМЮN˜КЄoMЈ.Йd‰Э™=л—XGМёЦ=пщЊ;jЮc𐭐ŠtšД2yЪ›ЕTpРК#Ьњ дмЫѕНRZ Оу‰‡ИH‡e№Жxс"›)­D(7J”…х оš№‚'ў@џс§Д’ˆѕЦЏќEд њ G8ж(Бћ2;a?јкБg™ВтЫ9ЦЈŽ{–9ЧxŽСŸ-’ž1(a С)‰šРр‰”cЪЬШtкEфтяФH<žžY#п“љј с+iaЄa„…&ћ щ3№(СЅF1M\Ь‘?8§Ъч,,ŠЫ7ЪŸ| љ†rЬ+L‘wЈŽЗˆIv+ŸѕжйчљœЁТХВ30р„ДдƒїЁ<дСыЁЗYТ>АСi|'_ž~ЃŽфХ7№вxТ3ј3@бzтЄ1b ФИШ1'еZЈCUl€3у™ёšХаьћН“J›оЦрqE„!…рёŽ{§щшaўN‘ЙR`‡5rиG`\Ф 0И6w&Жl(qУIО†ђ…<€“†ƒЁі$№њТєђ1J‘ƒѓxШу…ђ„є!nи.в‡<§YЅFНI^д#b|‰ђbя ”лу%ОЁŠ'„ќќс џФл'Юqђs‡њ t‚s—S 9Ц@„д{C АЩяMњPА{п%žо…kРs2SяТ59nИз'”%љ§`ї!х п^Cœ№ž<’™tШ“яФ]$u%ћБˆ ѕ0ˆр і.| 0“у„w!Ÿфчгн‡яЃНЦŒpʋгS  PA§ƒб Њ•С:Ь9-@ <Ц@ŒA1ЃB*CНЪo,„˜Ž…Vcup&(ѓш2:ШTG;е,}ŒU=ЎNŒчb„ЭœR.˜{~,ьrCŒѓƒfxуРŒнaLчЇ!т\c Œ ˆВ№ШЯPКТЇ;ЫП IDATЃRнФ!ЦРЧŽ–Ю1ЧcIUUUЏ!РЧ^8У1ЦФ‘ Aфю§Cќ'ЦРЧŽ(uуУ‚ќЧ^ˆ8У1Цт5ТqбЬg%У” C™иXцтlУИд1. hз(›DQ‹&‡ЯЩптћ1b Фˆ10v0 FШМЛЯ‹BTЕЯcЇТqMb Фˆ1c Ц@2Фё0ŒИ$^#LFR|ў0ы&Ююуœc Œ h0јРKf~}ЎЦ "тz^xРzд]HХk„^уФ%Š10†0 F˜ЬCЭ{ОХзчlЈЧ+ўqyЏ?R[/WN‘пs›k =Ц@ŒёŠ!ЌFc…дx%ˆ ЁоОАЋ['Д—шlИ™~$’ab Фˆ1p.00#<YХ0c l—рДѕџжІгЭуэУЧ]3Ц@Œ‘a f„#УWћМ`i0–Я ъуLc Œ ЄЛw5ЦДЁ\ƒЫбqPљИŠ6 IџЩяhb Œg Ф‘sлњбСМЩуЬPїчЖ1є'a€3Явг9Q;=Vž„јХxТЧЬ№мЕјрЊбX uю0CЂ@›ЌКІЮOуށa -Ž2І0uЉiЉV\Td]b†q87œž›МbЈ1†‰rнmЙљVTVŸ>1LЌХбЦ8јі№с#–ЊЊM}ЂГГ+– ЯA3ЧŒ№ 5yц@Cм,M‹{єгЖТ8ФW№ЊEї™"~Юч<Щ%єИТЦЙ­lЬЯ-~cшЃФ{ 9~ЉЕЕекли>џлфьQіd1W=ьХiЯ%‹љщ_gZЇњжѕ/>%імс=f„чЗ1ф3Фы‚Љb€)2š‰жcv†(“_№шЃqw1(i0ј’шћrСWтЂ+`Ь/К&o3фГSoTLЉНŒѕьРŒЁФ8€6]šц”vЩџlsLТˆс˜lжИRCaуLб;Ѕvэj9~cруТ€˜`FfІAŸннБєуB{ШGŒАUї™њХgЄФзБ‰$СуЧй‡ыжYюуcрBРЊЯЎЎ.ЫЮША+._jYВM– /„2Žѕ2ˆТcэѓXoшё^?fл[ЗmЕЪyѓlЩ’K}т9• •']‹ЕžXУ5о)№ѕGмДiЃэлЗз,XxюiѓХŸфYF›4SаžMЋМёˆЪИЮ<ФДUпŠŠŠ-Sj(~qˆ1pЁ` ЌДЬvжж^(ХWх#dжŠDЯYЧUЫ_$•…*ƒq ъЃ3ѕ0ЅГFHъЇpх№yљ МчKV$Нщ(_zzК­“ъЕААPЧHMЄM˜0СU_м7фС3&ђHŒ!?оХa|aРiJЊzЖ Хtp~к^Ђ`ZФcfx~Z Юѕ”€Б466њ4mBnn/C9eЂг}„&B`Lс™kђ`4д}МB:ž)+ЁEЧG!mТC@-ТРДс}|п€жbqфќа@КuЫzNОьЌ'tкиˆрќ4Eœk2`Ќ›ьиОУ~ѓЪЋ2n1[Вx‘­Иr…mкМйŽ9bз­^mЭЭЭ.1&Їю=ЬjгІMЮФ ђ Ќ|JЙеJ=…4Чїъъj+..ійњж­[§:oю<Ы—ћЗЃGZ}}НЧ›ЇuЧ=ЛїX{GЛ—­ЄЄФrŒ›<Жmлf V9ГвJЫJ­ЎЎN†;Ч§G^У-v/Ц@ŒГŒˆыiаБЮ6™.‰)тiI„‡јяyТ@ДзЏННУ~љТЏьвЫ—и5ЋVкуO=iMMMVVZjГgЯ>+ЊЄŸўьЇіі›oлІ6йя}§їœ1ўтПш•цИЧЛЭ;яМcЧŽГЖж6{єбG/§№1ћбdЙ9ЙЖyгf{єoЕ#‡ŽиŸў?jіЪ+Џ8Г„ юиЙУ232э;пљŽuЈ^ЏНіš§хџї—жкжjџэП§7;x№ Уd‡1>^ Є[Њ<:Вц‘&ЕŽЋG?оФЙХ нн]ІџvшаaЫЮЮЖ[жмьыr0™‰':ƒJV]gЈїЌЩ464кWПњU‚ –wРpЙ‡9-’4КsчNЫЪШВ 'œ!#н]џ…ы щяч?џЙ}ў‹ŸЗйsfл7Оё /!iЋЊЊ<~Ff†КYšеезy_џ§Џлм9s1"!N:еу‡М‡*wќ>Ц@ŒГ‹T<šЛхhЊ,ш`Š„Є5”шEќ7ЦРЧ‹ ­š9Уђ$qЭЉšЅЄјклžН{ьЭЗоrцx&  ЏЕЅUь;]uЩZЊбАЉљРžчгO=mеЋ]нйнйэŒе-{ОєРH HŽРF%ЪwЄПѕяЏЗТќBыlЮ•у{NvŽЧg=‘єqˆ1cрќ`@ŒPSnІнЎе2чЇт\ћc r8 ГИс†ы­ЃЋг6lќШ&Mt“#Цˆж-Fs&у$НoћліУўажoZяŒ ‹ЯПўыПЖЧ~є˜НіњkО~˜“›у’мц-›mчюЮИ`t_~љх†šѕёzмўт/џТ™'пјхффXSs“mлОЭо{џ=O Ѓ Ь–k€s&ѕ‰гЦˆ10: hћDТ<]щƒ][,Ž™qЊГ‡ЖpіZЖЄІ›nМбoУјкклm’˜`Љ LкЯ‚ЙљЊUЋlжЌY‚лfћьѓ­їнwŸдБ‡œ~тžO8ѓ§ф'>щF00Яе2вЩЬЪД[oНеЅRj=sцLћ“?љWўњХ_[^^žoЁ ~йф2›Y9SЪ—ћоЃпѓoW]uUЏ•щвЅK=рФ’!XˆУh0OІFƒЕ(MzVКќлiХLB1kFGЯ8хYФ€B—š0VA: П ‰ё|ІЫЭWe•ZSWcЋW­юeNЌз…Рƒt e'k€„hъqЦ‡4Bђ–‰)хSТkП†oЄ ъеx ы‡Ђqѓ@ЛCЫшуЮ„ЂЁQ&R ЄqƒњоŠІУљЧЦоОfˆ‘и‹ЁјцМbJЄsdzŸ‡UHƒ‰Іc–“'OЖћИп.п ЇЫ+њ>К>“ ;љ~АrФяЦ&BЛЃ=ш’š<<ЄЖє‘У‡ЙF"b†#IЧMяшжтН†žМёƒdУФ6Š?1Ц4ёЖBYюйЕгЅЗvЉYtвeЩ ё7Ш4šв˜ CНoАч3I;Мјн˜С€H-UFZ7ЌГв‰EНkЧУЉв’р.бє‰Цf›Пp‘~‘h9œŒЧXœє4Э$š;t…њiЎЋšд*X’Ц!ЦРТ ЏKF7ѓцЭЗн{vлКЗп–ЄЉЃ‚Jr43ё1„ЂИ*ч Ќ‡ЃЉ(–Z}кД _Ї†›Š ,ЂЧ3<~ЂСЎИђ*Ы+ШsX1-ФдЉŸгi„­: Јgђ‡c a-†Н{qˆ1pЁaњ„!Ž& еш‘ZЕE[иЫИ‡сc C™мєlЅРсЋTЂ=1‡О8цХˆжQтcруРРp5aЭЈЄ9поaЉ=кзŠ?Т!„‰erVС‰|ђЛЁюKтœё№сv,ˆЩАЈФu УON—œ–ћфœ7їВk5€њO9 –L’гХї1Ц`€јmжО>N‘ˆŒФЦDетJ\pˆFьдд4зИEв^Хћ Ы`dŸlaсDWсGЃ}_œгп1vЫаІ‡ё\зг'8Ѓ0ж&йвд­{јGЊ|VгП:Е­‰рLIЊЦдHн˜ˆзwВ щ§Ф •6ХгА^š‘нJЗCў{СЦDщњF~Рф]8БіХ;М7ён™ЇЎЄuжІИДŸ–М)'yра‚мфg”њxr[щcb \Мwзю]vLы)sч-pЃ‚а/оšХ%ПP1РаЪ€‹5'Lѕ?ц с$—›zуGкьЊ*9|/Ž q2иwhЌOщBН::Ыгфђœъ>єЅwпћP[ŠІYЁмRЇ#‡ZMMœT,ŽŒікRяЖЖ6џ.вd˜ЩZ=0о{џC[rщЅn)лЅ=УЖ8оhkхЇOMИRМњкk-wBЎіёжhЋгЫŠ%fлйn—]БT. ч8Ў`РэкfЕіе_Щbƒ3hО]*Gф•••эeˆЪ’jыygˆ ОёњыH„I~IЏул;шЈtˆуЧŽлв+-П0п;iD№ЃЋ№’5КN4OqЯ№Xmwjuj№Џ˜9нB$гŒуGtФ€мкеjећкфЩх#ђ`€! Я яt€†Д#Й’g†ж$ЗiRY6mЊeЪыŒМUЬlћž=vйВхЖcЧ9šпnee“mўМy^ŸлЗлўћmњtЙM”У‰G{ЬюЙч[Жl™Sdyџ„qўуO“эц;юД^|Сž}ўy{рЁэ‰чžБХ л’Ы.Е;ЖYНЌМЛTзс/WЎ _zсзж.†З цбЃGlЯюн.уБ%хн7пД1Ъer^уўП‘уќЯ|њг6ў<{ь'џ FH ьа{ђHPЧ1pю0Р@cЁуAš<'„f Ѓ"yz†дr+и,SsT+Aw`њq\НЂC~“Ы5иЛщтчёшЂK>lёe‹ФгмдЌњd‰x™Š—к“&‰(lˆ9ŽRDп)]R3К№NФшH)–‘mћvэЕŽжш@сНЛїкФМBЋЋЎЕ>њ˜нИцFћеsПrcЩЄ{є[пГЯ}іsvpяЗоЎš^iEyE–ЦšІДЉщщvДцˆЅvЇи­7нъVнwп~—§№?АFI‰EyХvрр›R>е*ІЮА"m5ЙЩдSyєи„Ь<;И‹>pФ ђѓэКkoPяБ_§т99ЫЯЕ‚Т{цЉglЭ klЮŒYV˜[`™)YV!x ˆГЯо&ЊМўЎЋ уN~зї<( ШїWГћD=МдчxVuСU4r’ˆˆ"р.ЬРwŸ{уbОЁ'tїјщфDy ˜L0raцШ=Њ”фяМgн€@|žЃЂ]§^k(Љ)bˆzСwжЄэщјC\NŠшдwOзћ%К!яm[Зiv;=ђ+*ІšІ5ŒэлЖл4yЅЩVЙЛЅЂђФ xƒх1lќ8†0 ГэKФ0Lф&jЁЊ!žf}'бaˆsњk‚Jйюлпx>G dњЄŽэлВyН5œЈѓѕЙэ:jь’Х—Zѕ‘CЖbХRЛх–­|rЉЮнЄs8ЇйŒЊ лЛŸЭ]8GGЉынtХŸя}ЄS*у эaш’ЪГHлH2Ф›-W. ђѓЌН­ХюОѓ69л_kызНу}яњыnВЫtD[‡&m­M:Њm…тfЊLj_хn›7wБнpУjлИqЃт-•KFЙQмЛWвhЖЭ›?GврwЂ?}z`„Нј€МФ# [Ы”‘мнwьо0`Щ%ђ ри­ѕ(j&њ€.њOƒF‡оа“Šr'šhс§eПN~ШЮЬв АмнеджXSc“ћec<*жJtp.Lѓ ќƒJ­RцpXЏр%˜Ѕ3@•з™БЬЫ{d$жЁNЗeЫ6[МxЁЧвеію„^ЇHд7XQQQЏš*ИEs&œ’noОНж&—пk9ЙщО"7MііЛoШшс&ЫЪбђЛ?і*?„dс]|›€цвєы–K—Д]~mgpщ aHМž}mmГ}Ђ[’šМF ы4щ№™лейс§фЖ[nГrѕO&†ГwЭБ]RGBѓ‡$Й5JuyTLБЋKLN}№Ў;ю№uП=і}ћњяџОњoƒŒжн_oЗTЧт…6!7л6nл`‹ЗЯг:ў<1Нuvру@†едЕхЫЎRџ*ДЗоzлт_vйb/ “жI“ГЊfлUW­В}ћіК_п•+—YОдАEњ•O-З’‰ЗЁwYН\*ЖЖ4YІв5œ8wKxэыДLOzвДаи˜n{7э•?ЦZŸ=“ЂпРЂFФЂ'?7пЙx‡f№g=ЩЙ їžљQВюЙFУeb`KФ.мЁт‘_zjК•фk‘ЖРХъЁтŽїїŽ+‘ЯСƒ5vЌщ˜ЅЩ2Ž]DТ]Д&чt1AtбЄГўдy‚*2™>шИH~s'WЩЫ=Zэ* ,–Пљж›zNБG>ѓiћћјЉіIЕиУZ/xёх—mнњэњыЏгY€џфw .ДЇŸ~ЪИџЉ^цyœ;nЛ-::‰Сђщ‡QЊ*І:ГцЮѕЕ :7ŽЗ 0S˜шу?n}ъ!ЫжB; Ќ^ы‹Фc}ƒuŸЌœ ж(ЕW‡оQ~ 2зсkцп ŽЮl5_j8kj8ю4ќ”њ‡јЯ˜Ф}ЁGZvбEЇЎmњщ/ј}ќT­ЁsшЎ[єиЃxŒlЃ "lHМ]LКFMzЎ= udŠT™'tŒYNs‹ONeгкбeЅвˆ4uwиџњлGхэцИ}ъЁ‡ЌVjПzщ1ЅBЋœ3зR3еЇtЦші3{№ОМџ4 ™ђьі;яБzњY›VёаšщНwпcщЙьнW_3Йž6}šэпЗЯnИў­Ћ ПЊk–Цэ=иK/Нd•Г*нiўВЋ,=;зV\sЕНџоћvАЖкћ§tбЄjM‘Мyј3VQY9ЂRъk ЕЃejsћК6ГjŽнqйэšУ(ьё…|•аёуЧь[пњћв—ПhSЕа9˜.|Є —g6 Б bРкˆМ‚Ъ‰w,B3и2˜2H60HЁJлПџmољ‘ЭXY!qќd}ўhсЅtаEFfКэмАKk9vЧђ;zе‘Д $Dб.ѕЧыэoD_ў­/KMвg1L1KЕвм‡ызй–wǘМР;ЊPoВШ~Х%—кwЕАЭSЇйЕW_mU"єuы7и#ŸўŒ-“хX—8OЎќ„о~ы-ОnpјШЅoїмuW/mЦ …@С:‘кi”SфЏ[}}ѓЏОiВъЋЎЎБ{яНЧЅРЗоxлІOnknZcМїэнЙзе+K'кЗнiuЕuіиSчЮЗ2ИэілЂz#Эюйk/ўѓ –&ššZ1E*šэЕЕЏйюэ;5€ЄIUs™-\ДH4&‹: ^qƒБЅhНKC‹KZД&I!6l№ЩэŽVЃjІ,EKK}uІXHa"J~ч0Р;DЗWЏКк'ˆєѕПS&OБВIвЦЈO?ќРУvтФq1И\Ÿˆ2Žп}зН>‘e­ŠПщ†5šь6Йя_Црv‰‘Ю‘T7ѕsх:КЌйђжф9“lг„ѓ:њВєŠ+|ЌЙўкы4!р–пŒ9эЖpС›9cКХn“šU‚™ДAМ_ ёЉZФb”I,хc мSіЫW$3BАЧ/бpŽШhПF}У1ЛѓђХ–-БU,•ХF: bbRЪљСёІkOkЗМ‰y–™—ciR™С)GЈмЦMЙЩ1ї;їь’>y‰m–ОЙLD“ЅйФЖлl‰ЪmВ ЪгLbŠЪnIЃŽхцЫрžІН+нЉjдl‘ЌњTіуœAFX„‹&:L,MЊŠІЎЛіŠх–5!ЫВК$ів…№ІСоuщЂ‹дЫ]/]гЗД ­6еXqD#КŸ5gІэйПгђ5SLЦyЗкР'9Ъ3K“Вьœlkб &K›s,LАX*Ьv}І$ВVM`˜иаљфzс% щЉ|ŽбL'щв2ь“ї~Bj’ћХ/~aŸњєУъИwкm:j‰5Ш’Ђb+П*:AтG?yЬЎОъЫQYWнВвцЬžcпљіwЄЖ‘ѕ›TЙ+МјТ 6}FЅЭ•ФљЭџёM[zљ2лЕsЇT?љvеJuМLMђ”Џw9•%c>ЈЈmЁєу@ч бй†зйќсz…џїўћЃ§Ч:u§ш‘БŒд24њБw8Ѕ eІG–žдg=‚JgЛ„#Ih“ŠЫМяvЖGТЬ„œ<ЫŸPр§В[“зŒД,ХЩKaНБЏЬЌЫчdO№ОBпщ)Wa~ДU5p—рЊsїyъ_љ ]3хKТEЇІО’DSђ%- 6э@йs”7}IЊQЉEyУь4IWЭ ‡1вQV˜ўЫQ7ћ“ї~вЊЊЊЌ]œYƒŽ А’ъжрфвд(gКƒ|ѓх7o‚Ls‘ЪЫ' !mєr,O‹ЇА&ѓNъЖьЌLЉ2 ­M3d4ќ2ЛeъŒФЋЯ\'Ѓ8–г7=bPLPкл:œ‘xuЕx]мџЩќ|>жа рЯ&EиИiЋНіЦkі;П§ЛšйiнD„ Skœє^ѕЊ:‰$ЉšєМѓЮЛR-цИГьFfpъЌG 1вaиDЫ=?Š4ћєsЯй]Зпо;#ЅЛzƒЊь"RбqЛefІХЊ*e…V8AЬ-M)[{’4б“Їu#~ћїяѓ…і™г+TNYіЩд=_ОЉхЅъœ9’VЫ5ћlR]…›nT]vЌЎZЬЏЧюИх&KOщ’Фz“mкИйž{юI[uѕ*+-bPаТHRgv$ХЦ| QUdР’ТЄO4“&:јђ>'+F-7энgјЏПюuэ њэŒ4u–СyEЯmш‘СLЂМ|ьeШ=ѓM]Р‹&ЂXpњђ;бФI./нЁ[<&Ф щщП]cB7ŽЊ˜\OО vЂ›{йLЅб{•5Мя—7_нГ бХрФЭ=И‹Е$ўЈ—ЄWЭ\lГљоЃџлўшџќc{ш“ї[—ЄŸ.ф;Е]™Ж3ˆœЛ6`хh ц˜2ГДў‚лмоj$з;$ƒv‰еЭ­Э6AЊЉ­'Бю‚‘ŒŠ>œ@ѕDЅšм@LI’n‡gќФ‰CЇKѕaФђня=jќoџФ>}џƒт3mb0§\њƒ~4йƒњнп§—2[NзкСƒ‘j…8њ99е‚[$)ьЊeWJ0Iфзc7ы€оliZЅтX­MЖйвѓЃ>ЙL›raЖЌ)VUV:ГlжZт-7нфjW˜ЇЗЉŠLЉЩЎ]7Ќн“YvŠ&x/Ој’ЋЇjkj\ВЭШš`ЛdaіС†Єf]`o№Ž]В№+”фЙIš )~uR§-рзЩњlОДлэЦлnБкњуІ­L6НВЪДІ8­ЂB{žvJэ•Ђъwh§y’ejмЋЕЙѓzbешэ5ДhŒЙ5]Ё]уaЛ&š(нЉu/іЗБžЬгYZЩ8@ЯdA,ѕ#ОDпуПЇЦ€8 ŸZ†sце7$‘žкЅ_ЏСцЙ_џ‚зО‘БMlЛ‹ŸОўбЃNˆ>ъ‰6м*SєysчYmMНез€3gО}Дm“Ÿ(~Ќю„Ў>ь,7mYя:рмfъ>/ёђфЉ˜Д9CIТqWэ­К3Ыkвъьй_=чирЙM<аŠъАљ•№ђкWьŽЛявФFgŠ‘vъ}дьбDIqŠжчia›Iв^&xЯЋQW›HњЫ ‡Џ{ŒVФ)V|в СщULљЪЋVˆquкЅK/ЗЭвѓЄYXЖt™ЅJЕ{нѕ7и‘ЃеZ“œmїkAгІЭvДОЮОђ/~GЬ3еnКEŒOжgѕВ\}HЦ<™bЬ—jэ/]jу+WЌАї?ќР>кВй&kS1jїRYзmкМEfф•Z\ш НG <cаdвЁOВ{4HвRD{Ўiэ1pТ%ЗŒЎЙR*l%Мвtањh…g>†ˆ2ќЈЩдНOFЖ§Њш NHF*уюo§ЯoйзўхПвљmV,гu,уЂY7›A5Jаъ)pЦ~а†ї@/Z0Wƒ–PѓГ­dRЅђiЖѓgk!4CъЉ[0wЖTnM6ov•ЋвИmžфз•&rŒgSУk bЉ}щьHeИYњіЗПk_ћнЏ9у л\•)‰ёЈ/‘цz№aћЦŸџ'_чErC5 гьm;Хeђ…;*6Ьв6|s}ОЎ'н‹йёŽљ…јЇД^ж˜УšЦЌЪйV}єЈMШЩЗkW­і2bшХКФтљ‹-uЁжу˜XГ7”Fд7Лћ=mЮ6еЃCшЩпћš9=jфaЂ|”ОїЮ{VR:Y: Чa$E‹x!v jэgє г/D%фjжеSaўћц7џТеZldЄ#c8Ук mк&ƒˆЖЖh-Ї <0@ь=АGFХОіxtї>›9}Іэ?И_›& ЄJШВmЛіXеŒJ;(_~YšO*žф’€.#Ш‹Ј#ƒu—$шДwp€‹‚›б8Yбю,є75ЗлDбХ_‰.|ЭOtсh„С‰.XџhmiTкњѓ?•WŠ4kбіE—жил3Анxf 0„фяCн7| зОї*.Ѕ\ец2ioщА\эљ[ЙтrmmЈKLшЂ|лФ аuW‡T\Ђыш0З@(фh‚iB IDATхы•ZыŒШмЃH_пTO6 w$`пЫYЅcыъФЏБDtŸвЃu`W7I8`На{†Ш„CR*}єЮчгhэnЫ0 Ф Z‹УШ0ЎўЌѕїpгз0Щ0є™8д;5лц4ћЭf Х `ЈžёёЮlœћLЂ{GO†5Ь{šІ4QыeЪЇЎЖж*Д%#[yчЫгРф’mv–9НохШq‚˜`Ље2b­h4ЬQБё“zyйѕЕбРЫiBЄн{dЏнKХ%It!Ы[Е^щR vj’Q0БиFЋ$(џІ‘ F)ЩZЪЂ§Рћ9jVoз• Ю'pЪ†OD— ЩК>9 іюфXсЭ  ТЧј:&1Цд–h<И­Fr…CМи(Ie{вhЧмфђŒЧћєьюaƒЕЬ‹ЭДоЂб?“Ц#€xЬиYŸй#\т+>4Ъ?lвЦ%3rљабžДу.…ю;Ап% ђFе†GѓCGk\‹Ъ4šьЈ{OjыыЃA[DыFH И˜я“п oЈwЩщ(ѓ™Р"}2МАЮ*|eФвjёїпп ЛСT?К@’J“f енэ‘{xТўваaС;ф^y‚˜$xmђЧh‹2ŸНMnpсд$oщ2† dX™iw5eТ`ььeCЧ`sЊЋ-зыL1РЪ>жуšРCkнВА‡ж“iŽОЦЕFyZВX.УˆУИ7ТœФ`G˜~HФфЌРyѓц‹Љb<#ЭЮR`€žЇN™ъзкšъˆyŸT Г”a fмcъe_ђ$э1Л6$}ƒ m.эOд‰ Ak2юј1" ?#”ЧСMlŽзЌыLд_W_}Яh>Цr #Ћˆmvф#ДР%Њќ˜­ •6‚ щ’N?KрХaА8У}7Ш~ЏЯ&Ќ~€сый_%з?”FшьS‘rЄя\‹ рЬЂГДЁžЕХг#~xЙD*и лГgЗеiпœy‹м=гiлuxруX1NТ§„“жЪ*F7KХб’бРЈ’еЁЖlкр§ЊXыьЌ%&:йРШЇ|>лš”Sf6†>rt@4жˆтя1ѓK х'ю˜жm0† ДуŒŒSY1ЛGm•ir–V-|ХIМУ* B БјУs цљCŽ›єk}tЈя!›1{ў"МI}Ш"~~QG$zŸРsИ‚Џој‰o§о …АЄИЌезОФLY3a9!šєєhп_Н]Оl…Г'їJd‡gа=~t{4АТиІЫ{ЖЎqKЪŽxЬлвбЂSоЫ№ЏLОŒФG€Сђl,I л15нїв'ЊУ†yйїZЃ<ЭќХSoиік–+3w,8=œdKР‹ўBeQу&у‹˜Ћў'g}cѕsщLЗщў^/фЏw|тёMЈэ Еђ4ВЬe”лз4йтJXрЫŽ8ЎЊ2ТаlЌў˜6уkЖйsцШtНUяф1]ЊК?іћ”< АџkE'N1L’Rпѕ­гБйО-ƒMуу)ј\CuЎ—З˜)S&Лjгзі„іuжЪbЗЄLЮuЕцчЎ‹œQВ™—ŽЈ6ђ5тhm7Uё};…o5iGЯ@Э• +žУ#,ьдк.3=š+q#fж—.ДIђћpО%_}РMЄщD<сDgrŒј>ЦРйУєжЉ=жУ=˜?ЄXН‡О0’’аЧZZšнр&о>1ЬEq#о“HЇ=ž6CКбФ8˜+—eК Ц-Ќ%†у ч9‰3Fєš-žLo8мЉ_ Љч‰ƒ+3ѕ€?FgzЉYб8›Yт1TтљDsЋЮ–šf;ГІыд›;ЋЬZкДНУ д(@LЈvkjŽjŸXЃ˜кY0ЖјўУУGи5ЫWЪqђеnK91GjФ&† Ч”nжЬJЗx<›*КPО њ*„PgŽN™1c†5i2С^@:6лcђѓjmrХ4ЙЄхLПШi-ЦRИ8k”“…й•8?`{DšеееЖPnШшфL:`Ј|‡ёy\]MgзЎ]n˜Ѕ’јd|БvB г“.Єѕvг33тHђїh'§ašУоAъ–.Ізк~А Ъы ФI~ю§ИIў>МiтчБh†ё„l1Тst0/_ ЈhHМбzХ‚юkДцНS‡бN­˜ЙМћш=Ћ5дp 0+x‰кУ™!jRЗЊ МЮ{8ІС‹"0›ЧЭ>‰€ ІЈ‡oІtшŸё\Zд'1жљˆŠ”ˆш[4є‘WD Š‘ЉMЉЉbШiђc:QžkPmrДF›œ;žФ—ђ#рЫџmmMю`9MŽiпx§5›4ЉР&O™Ђomк29:gNiЂ™œ`kр @йЋ`hpђвЕqwМ‰ЮSК†BДMŠpДˆGњФ„ЫћїаЗ2 i†ЪzађФ/Ч4 CДKнкPп­хœш€^6зŸLŸiLаR\'7"œ4y@~—Щ/я”ЉS}RД‡ac ]+ѕТЫnH‡QHмј…†J5”уŒЩ_FЂыŠ&1С"§mќB<зРxЕ[Е~Їй*YхИФI—Љg”ЏЬЈ8щЧOбГЏюˆX‚ТEвТћq^MЅЈщš•!Yоwп'œ‘жЉёН„оr{щ<8AЈЄGъˆжУдёs№9Fˆ№ žУГЎIИg dВZ•Tа›6mВ•+Wъшcъ ќБ'Ÿ|JЇ…”лкззкУ>dЛu^п_ўїџn_§ђ—…а{іЙge:ОФЖlнъЮВŸзQHїщXЄWзЎЕэ;Ж‹RmfХtЛѕ–›э~ы[V9cІжUtTг ћЪ—ОbG%u’іN6cxкmАyЕ‹@SYџeв“ˆ бьмеSŠгмвр˜<ѕfЛЄ`TOЌ§рZИЈЮ‘pйK ;Qв-Z™™2Д#0Љe’L ПS>ЪЩ{ЗWс#!-вШ`‰Ф‘NŒRaŸ\0ъ”O;x№ \~–Ы7pЉУЬЏщz КmћV_жЪ/ШЗЪЊ*Ѕ?“і’+yП^ю3)oIЩ$љЊЎwS™–sZ9'9M‘Xу DjAа: а‰Ѓ(ЮрHЃ|ЂДКРоА'хUHЭ’ЅРШИŠЛё‘8D,T Ѓђк?ёй_№„ќ}IбЛ н#2БyP"Ÿ‘™[5цЩ™wŠLыj$ l˜Е1sO!ŸpеЋ8œA*,‘†їoў/љœЭзF­.%оyз"тC6wю\Уhц6KИNqoљHu—-ЙдmўдЇМГЌЙўzбWŠнДцf?—f˜U9ггмМfw4${ыЅsIе}Хe—љ„fHеЈкж›ZmЭ™‰=ЄЎЙюz‡AUЋЖса‘ЊcНёЮіџђїlэкWЄк=Ё=Ћ=VЇm#­в_Еш„‰zmЪядђвЅЫэ_}эkі?ОљMбnЄЮ%џДŒlћфї{Їo•UГgrjєХ_Ч\;!Bv јZžб˜г&MA—у§}ЪhЖŠ5ЕДы,ЫбЬ›<ИW“й\УлqM29`qƒqЦХ; оjДпї„<•a879w‚”:gQЛR2Є ’–Ш—Б$Рд іO~іOЖxб"э .ДЕoОi)R;ГФR_WЇ}Уu~t`™Ж{НњжЏНŽјщ“єё?џГ?З‡zH`_ioЪPЎЇ+еjŽекѕšшОѓжлnTЧвFЃДFгІй?ТЎ’Ёнц 5Й-В_n}ж>ї…/JЅ,оЂ|˜М’uLе:\›ЖгUkykЮмOјјВxСbŸ|жUзиГO?%ЅvЄцАн}ї=ж eŠ]кbВьВЅ~ПsылЗkЏ-ZМHМЬХГўUg`Ы ѓœ %СФT$ПЄ;кЙ“дž0FgbIƒP4Ж0$`|1AЋ7шЃG€“‚ъSџКХfSU&ђFDЭъљ№GЯОй `˜7Bъо6 TГgЯБ­1a๕в М99СьžzŽУG lЙ РјС adс9:­"њ}ЦОŸ{к‚Ye€ХЕя[п=i‡УдSшT,DB“ kЫЏИ2‘Пњшƒы…э:П0Kz”Х /Бm[ЖйЯмљдg‚ЪыeжХF{aћЛјЯИС45ФСМнn–ЏqNєчƒЛЦСTіgB,Ђ]qшчˆњ\`\Д­ќшЧ’ао~ыM;qМо™_qQ‰ЦиkзЖД‡|а|№лМy“Нѕі{>ц~ИюC{їнw­rжL;ppП>xиŸЄШ~ ЄДШІH]‰„цnчо]Ж_ЫYюrQyЅx§ЈЇ&šВр.ГМыЖлэЩŸџTrTІLдŽ€ћmчіV]Sokжмf?љИ–9ФeШ7oо\ŸXwiB{ћэЗКqNб vњНлъO0pEФxdр‚”ЌЊ•5&XH~ 3§т№ѓ#‚ˆги(‡•Њ["'љ‡tЄE’є k?‰зЇК0.u)3ЁMз&kФtЋЌœцIњ^T6дGІё‘T(uИž*—јл@ DLЌяm`pсЭHОw08у…8']1*ˆцч‘š>–†,OкZ"FЮЇˆЗЩВѕ”мOАo8^cїмq‹;Ш%VGГЇd^ ˆ8ŒG ˆ 7 ЩљZЁ&ƒў/ˆЮу Bх E€H!Ь.ŒOtˆv€FФыЇ ЈжХ—^~™lnw­Ю†>JXАІk\}ЃНY‡X7YЎ,Сыd№‚ђiSчЛZє‰'Ÿ”ЖЈФJŠ Ечјзvћ-ЗYmЭћх?џЪVЏМЪїsˆИsзšИзфоaЄ=вzў%‹иВЅ—I эАЧ~ј#лјбZУ—Ў№P}xП]В`žœЃTєюG&m› яьh•” О:…3 WЕNЗ‡Кw†є’ŒўЎФ^њ‘ЮЙ–ЎМs‰1ёMЧ5W•JмдљzЅC}#еuІb›ЪKŠZO,Я@й!’ 5]nlУг0ƒ1)—г^B,†t*Йfƒ(5s}„д[п1уч‹ЂкйЇEъ44ёhnс‚…žМ]Ўћ" -Д8нXФ@˜hЃўЧ(ЄK{‘сFџё+ŠЧаЃї§? -Ђe†-)ч%,!]?щhcвzЄYio”єзЁqљЬ“V6ЅТуМ"Iqђ”i:voІЮ'•pю]й)ьЙєѓыЅБэ= 0LЧЎ*Ъ2№G˜TrшУ?wrАn…ЕTЮp%’";MјыљљДIILе,y†R8БА†ШЯY%ё‡}r‡ŠукBn•ѕ,П8Œ9 Јн9˜ЗЅНХReЬТzх™„fuLBŠж/тc` Гвd г) “ё.бI—4^ЧІўрЫнеѕ ѓ9šиE#pєw˜ GM§ &5ўЊUЋД4-gL—`ѕФB”uє<Хa-ЎГd]1cКлќлѓяЕjЂ овэ›ѕ7О-jсТ…юрDSЃ}љЋџBŽ:Ъ}%щФЂЂШ™…ж ЛTс,Зн|Ы-rЈqTЬЗлю§Ф}V>Ѕм%SђлЗoŸЖsM–СŒЮ;•пšыoђmZSЕяјž;яUљYЙŸAЄСz0с“r&уLfIg0;gLzC€!= сЮдє.J)ƒrq  Иo[лёѕN)єшљ%b*‚`—2ЙЄНC”]œjди‰УН0ЫAбАuъD”§Ь†ЧSУПž @у„’IЅЖсƒѕВZ+ѕNz~Jч:>0#ФёЄAэY“4уNъ}мKТ@4`ЪЄПІї`оЄЏ#ЛХx…Сюc pˆL­Э•iыв.Оšђs91(ŽЬfBxПќŠхЮ3Xчя”•vљфiТ‰˜‘ЪK]и'ЎИє Я|ШƒqЁMRЊіN li/B$ ѕ:Ј)пљъ?^FIќ ы'lsˆА1KюжчФ HŒжйj œФ{ЩŽЅХ # T)4[JU'ЅWДсвщwКфЇћ>ќ у˜˜всІWhЖ*ZУI1ŽЗќёB*j\–1„.­AMвv!бv­•Йз“ѕcЬa_$U;gЃ2Ци‘р ЫТ}Ѓ№Ч`4пG#зn­Й%оъ“ПoбVqс,+№QЁ]7МжжfЧт бž‚шmЇŒ ;Pљ)DyEљujb‡ОљћŒ––Іо8!ђ”эIUgš8рШB Мs))!ЭyБ8C7~я‘%ё‰i%Vк”F PџќИ їХw)Sљ ўєМљŠuDЬŒйcЅЉR)HzЖNИс0Cя ФADТОŸ Eu+ZХЇьq;`в…jeџў}V][Ѓ5…y>ƒ›yьДёWЇ9€S[­IXЗݘ:#’n ьбH“b;wl‘™цћоFК)]2aœѕДxУЙGK*ƒ*-<‡œC9є>|ђБ™їМп‰ˆм+јЇфябыўi’сђ=Љ§ђгЇоьœ9hнЇУ`|0ЃоH‰’Сј`|…AС#Q ђЩ/Д)ЊK>і2Х  C4Џм љqK:ђ#x<Œ`R5›‘UPЎд›]‰ЮїєЦHМоDм#РLйюЁe\џѕ IНLЦŸС“йˆKЎƒ&ˆ_Ф@РYђћСо%OО?U\О…яЩГФ№8МOў`‡wGЕПh‰д3%ЅХ”˜Х†ё5ЦРйХtЩсвi{ёnвЅЩз,I=Z@tŒ™xGj#;|јNg)Б6YА‡8ЃЂњG‹i‹˜&ћ,%љ8љqгіPљ%Нї1< 9щ}xЦї~ёz?&н Hл/~вЗ~я•МїYq’янX№МL0c-ўЫЫ"ІЫ.']LP‚Ѓ˜L/aг™рИЌ Џ7_ їРуої&кХ3љy,-(G[)КeJn fє№е@_ƒІDБСёiй +›Д`лей"И:D€p‘Ž9т›;ГЕqzЄ3Г!@‹зр/ИP xЃР)ытТ`ž§Ѕў>Ф яТ•MѓlОЧ/шќљ–­ї8P' ћG:XˆЪ'c-ecCt0/Еs)§їжOt?T>Ф ј мЁL\Нc‘іtпУAќюуУэк™цэДfљк jЯфRЏC$Y™ђВ":іvMŽpŠ{КДУйЋ›7m‘3ˆ)чDџIуь)’ЧŸHgmU pbv’я„UўEУCЄ6эAlдџа@X‚2ьžЄJХРGЯzЧ7i};вЅf/И_cуrLa1eL$Є‘&ыN;‹ю=ИC˜рілмj(K.wvoп Ј@;U@њ3ж~—Š9KœiтA=^$ХЇ IDATy:UъёќЮь“љЭ‘‡—МФЙ€83?Ё ЋбфИХU’pЬОM№Š*ˆtyж$„S$X?РYЗнѓМmћ6Y‡еhЯQ‘Эž5л‰э06ntїl0бщгgШ›DaoSPЎ`D”ЁGmšЎMёа~ФXљˆ>|Bз(дKњ@Хв№Ў*ВKр:ŠС‰:RчОEpвЅѓЧм<:ЕœDGQ6hЕZ—&!­—Jѕт`c?`XпYcŠУ…†ш)вFЁлт`^NЂˆТєUпКЕ-`Єš€ЎЊЊfyџЈ>АпЧж“ˆlЄ€ЧYќєlu&˜ ТЄ—ЃЛњНо#ѕ… OЦзпВГџpAZтŠƒ…Є>ШDNиЂЁёH јМ%WЯРSAHšэHmŠz6Е'C~Юћэ{в Lƒ^їяпoW.Пв§G†AшЄШ^„+R „‡гc|Ёољ@ЮwчъLB|‚ПFђёКќџ=,7Kœ^фŒ2WG.ЩЛІеrФ]'Иr–‹ТќљЯ _ЂU••Ю$‰“!}ѓ­Зь§uялuз^gk_[ЋЖ= Г o‘УьшбУvљeWШ3§?—Члј7Єэ˜дDLMuPSКT&˜ВущВ–І6пи‹еўЗnнтe™,зjH—а’{ўHF$БrU€з&nuЃЛФ ё\9њ=ъžq& œУr’"НeЌеRю„\ŸеѓКББХЫн nllpгѓ‚ќ‚hВƒlбy‰uк7…++Ьг=_‡џЙ0РXэщˆkiл˜шр=Љa'мŒй(цy0™Мdё%'С_ тgЈ%еЛФhКYчѓ­ђФ<ІBђ=ѓ—ОКїxД2r]†3J{|RшЇџЮ`•&™.<вqd 3%рБvш[(dЊ;œРЪРƒeкщ˜х  ЄУШ1ўТЁЃnJ-<"е1ШwJ„Щ!ѕT‹9оЇуŒЪЪЫь?|LЎЫfЫсu›]!џ0E$ѕаУіЁМеуХЕыф/u'юЂХ нј3O?ыˆВђЩж!F:mZ…}ц‘G\-ќГŸ§ЬvЫсяф2ОЩЅ“˜ч3О§ц;іѕ?је‘ѓб2t~сq•.M*о™rO5MПЉі›пќЦ>SEЬžЇLM_в™viRя.б‰Ybд9:8ИK›Е\т •ЏчГ}.њЁ#kWћэлЗп™ЁOДdУ€qЬDљЬLјgu™У87jу8a:nЫЄe‰ Ш™PєЬ сШеZV›ib„0- T•0,Ц“hM1JJЛТзu ИЮШcМЅ)Џн*•›9_Д>ћ №ќŒРDšсЬ{Hы X*‡sŽT<ŸИч?M‚Ik~[uф Vs…rvž%)F“CЅї;_љ-Йз^}у5ћвч?яГZŸА8СDвyІЄЋ]rО[Ѓm0†I”[ЕўЛќЪхV ы—Ојy—’ж­_oO?џœЮ{ћm_ЇЄВ§&? €і\еКCь‡ЂjІž*Ђ­ЋЎѕИЕGЕХbF•нЄs џїїџЮ8,5ЊмEщєzTњЧыŽIу0С.]МФžyцqІ“isцЬГЩ“ФшtLД—Ÿ›чRщžЛьшЁУvеВЋ$uj•tciкУјўляљъ дЗLи”џНЌВRLП0’kWл–6к5зЌжi‚ЋДќиoѓ'к;kпж„ б|шAКLЂОН”ЏRФсМa аƒ$ДІBУSO}ЫP;ТX}ЬёO‰юŒDsБ6YЪёVпќX'˜4Sеvђcхю‘ј†Ч…э/ћHŽЄGŽ:kЁMх­ж ŒбbšЯ>[KЂОыОджNrјЊНšЙ~ЅъГ№rРЧLsGЈv№>0т0юв;Y"mžOа4ЈYšQ§€ОŒЋж†њИИХ ~ |P]šД'І№0mC=ё9&о)!^л•R$CjпVž*иhЭгЩœЫЁМ”ыз#bF’$§ExŒ ЌleЙx™6жE)Вж@№Г… УјБcmbџmШKН­)4ЫcpвЮqсЋIeJ”ќмС)эзiцœЦй›І%А€A7Ў§G9„t^–ЙPžЉЗощєG5‹ћЎšc…ы)Э д\!їСяС{Д#хR‹x8ž– Х[nœhчgeL˜mшрke?r„Ее,МЉQкMcoД9вЊUV~ЏžНэ]мА~c=rŒцЯ„оŠ{њЩŸхѓrЇD?vЬ8ЋCwNfїg<аœЦŒEфя;;Йp``)р˜—wЁАc^ой8N^ИFf5СmЈзрСžАƒJЉ+џ@иє QЙ`ћы-BbШЉџФq‚ъд…;“*sy,Yхшфт8XЭŠЗє|Мf%%ЁВ8‡р[6lQц [ћЊ0„••лЕ8ЁVѓNуЭuqЌтЫТљs №xG?їšвqщkЇуX(Этbb’єœzъ%ъ=А9ЋNе-НЊ{ѕЃbsц5’ь,Ј§€‘НЌJжЅœS=…s§—AсjZŽаJ‹iЇЕш"ш(Ÿ9?Ъs§ХЉeе'Y+iTGˆ,/Дг\^тЊXxЃ`аЕЖcX)йŸяš,№г7Нž‹žЗyŸзћСЙН%Йкx=rtІжŽOГUMa|ѓїЅ^”Ÿ{ъХ_жfЕућheSЎЛн’ЖB-.цчЌ?хдЄ|aк>CЊŸRŽзБ{r‹з™…ˆ:Ѕ_‚cЙS”хh#eЎL#‘i.еЅ%60`uR'Їф˜Е™ˆ^D‹0ЅЗц\–}љЅ­Ж;*ЕU?э›8aB^ZiqЁY†KƒМЎ6 HŠ”_BЦ‹)!иZ‡ё7џbj]ж–s@/:gхзѓžбQ?d“…й€…Чќ —LoЦ9>” НвМMЩщ Šk84U­—AŸтчг!MхKІ3uB9h58ђћЎsБhRкJШAгXаЁ*цi‡9 Ќ4З*){iжDNєГE3œЧۘAЈb’Œђk‚8%цУ`ЄKЊ6цJђd™ŽeѕщhMSВOрa1‡tчэЗ‡Щ'jqТ1[СЧ*CWйOљYо‹œzўx ЏЎбМLIfGі"Z?‚цiЎМЄ4дhњЉFšГГ2Rƒ‚ЭFЫњЗWЋiЖБІЅФУnьFˆHРЅЏ|§uэ­=‘Юў\Р' ^q|љт‡c,буИB‹Fг”СИъЦK"uиzОdYœ3ёё'ŸhкЋэ&Žr“єЩsЪх:YŽзхiIчїЅЖSБІ`ѕІMЖ(/I›>/Љ• 46№Ђ†dсŒўы№ щЭ'ЇЌ.5ф"ZDфR,‘‚/ЖX@Ы#†@1xЃWцXŽтЩoy”nдTA–вrЕššешЉBhoY••Aнт?0‘ЄГfЯ…-лЖ†e•cа Š [ЬбK'ƒwЈЎ]Л…eкПgŽyеэ•Мtn#kщ%Фо9І\іяпoaѕЩ*sЙЙ-u/ejoДV'С)ER№’ђv GiuvЧ рЈBе[§‡ kП\Кwяfi€ЭюнЛЕ‰П‹ ŒЏ€i'M/ у>ќ^ у†,hы%мћ…1bС<ОпѕP&ЦФM/‹ђїЪќржэ•сЇ?*wTšaŽйžZн{сх Ј—sјC\sфG–ЄдCјњыЏmuљкuы =%ІўH", b`"š‚ІЯTИ~~ФА­BРцЃ†туќNйјn(чЉŠ‹#'ч1•sf ЈЧЊЊџB07Щ Пњ)ДMqЙ_,ЄuaЦ‚…‹Ує#ДїlнњѕсcYюIЫТЯС“-)—LoъœgKЇьпЏПй4=uЪ=‘ФwОЉќYzЦ–s€ёЄ6єьРG€‹qѕЫbP?*ЎюЏэFэ=ЕAЛ>QЃW˜jыдО“Ќ#%ђjЋ:т}hЃ. ДЯvъmЗВŸ—-GнŒf›Wйіhu4ргCЋРQ1bъ№ˆіњ€}Д_ѕkЫz™œўРЖэi@џ~fјЉ:ию еж˜M<Љђ1ІOнєCюЋLЕкљ„МЪа“–0E• ШRчa§hрI™h№(PєјЁbн%pЇnЇ…ŽzкыH№vйEъOI[іэ‰YЬч6жј"№˜DШPц ›zИёV#гйvЯуЭ€.—Ѕ–ФјzФљ\vByјYШЁЈЕOеціxrK”пVЛЈ:(Іžдё6UG1ŸЛJнIK‹Пьщ§eуєРРKлT№<|ѕy9љб ќKЏБrЈ'8…ЉHыЁщuІЪb3\x№nђŽЗънд€yЖZ ЩЕZшХ8fу™іЛеЄmЗЉ?сК ƒ3dњS]Кu Чeт™Ÿ=VЎZvюЈдИXaЕш‘GУюЪІEы.ЪѕЃGй– еВ ЬъћюЉ…ŸІЖW‡qZ]^QV­Z);К›%lŒ dlЂ“ @Дб’iwХ•Юєiмн­њВ›ЖБ’џпџќчaжлГe.qkИџОћ B>јрЃаEgД5hЬш1aўќyс‰ЧŸЫ–-ЃFеЊк§2ђп-ь‘T|ѓ…ВхzпД{тЂz|ш;oП-МїўœАY ?vьHИяžћ#Г’.дЦ,ЎQ8`d|aвЁљaќœ9^H6OЃ@тљЂу+“Мм&§Шс#сumRПwкнfЌКГіѕyЩќ”Щ5Њ”ХK–„)“&еЋ'нhОtГqрbфяqkC—6ўXж8J3–жbН2su`Mщ Iwп1UFЪ§s2њpШŒЛгзgЬ|Э$НUkзФю C‡U?;m†2Ўhw…ЖѓŒ1ЩА F\%ыQЫdƒЗBкЕЅRХNšpKXИdqИЊЯUВ7<,<ћ›_ЫИЦMfŠі\wнu&!><}К­з`ŒРуг2N?Bћf_ž1C{n‹УјqуУ z1”—W„Ўн{†mлЗ 0gI2lО•ZЖП~’{PЛиn€7ІЗNžbeзЛяF.JЪр;{Q`к"™H R јdŒM_ЄЈћй_wэ’x?ЗT/УHф ђЧŽ]ш:Ж‡фЖШЈ:1ЕЉўАљДЕћс‹ЋЛ˜љдSO™G$ ‚‹ы­-ћrЯбqP5ГwOИuвdу) ѓоœ9Ж*Я Ь; Д\ТурПаС’xT,›Жl–ЋЅЛ䉆ъ|‹д(Wšdщ+Э|_!R ЉAфЖhЏT:Д@%њТnэ`sЙ?уьў/fؘ„•жhAŽд†№оC|НћpdŸl'Љb;1/Ї8LвoжIЪB*1ќZe‹ГЄc% WeXMBе‰}xЦщIl€фIjK—/Є…kdœтcƒш(<(ѕш#=l§œійJNŒИЬ#Ž:№ вUs™|Hs]tІHжЄОеј1QЦ7т:Žљ цЫPџЄАQ†іх[ѕсћБ,>U<єяkї@›МŸћббЅ/rХЕm$KЫЎ(тйњ0 „U˜ЂuД-Ј$%ЦŸтEc?ЅƒаЦдXњЕЫKrчe:–IЌГчЪSІ•{eЫЄЊ,+’‡f=ДјSœ$RVЏ*YхщІL…Ы­4v;…n1>(OСЮу'šФŠ?VIŽŸ8fПћЎ€V•dЁерЅрЖЩ€іѓo†бAяъЕЋУ32‚ul[eeXќХ6o@gр‡‹":ЯžНпъ§icst ZэЕ{ї.Sе№м(ŸВtй2Г+ъuˆЫО\nj@:Tо‡хЕwSСЅЬІшВєŒ3xя“? ЛЃо$Ў^аЧ(§HHcі~ЭЃНXEOиГgWhпN€ЇМ+з|eZLО!ї`Ю§PjЯUЁ‹РsСТљжч(џ њ ]†Ўџу—П 7ŒcгУЎЊ=В'Tоъѓ‡ъ@Zm пёёлF}жя Јaв№kЪ*яv’ёeZЅ=ДнК\){ХЏ‡›eЅ —k0гж-ѕЁмбРs§Ц ‚^& Mp@Д‹дŸ6З<ќ—‡Ы%лOˆАХO Їя€(Є Дк$л ,9bќК­Œ—шhцй8ŠжЎЕL]ЋЭ'J’+жЙљР‡|i?ЛV.$<шUЎэД#ч Џk­ž™-Г­:y<ь?й1|[в9Lяs:єэбAњу:WKфр†‘DіЩ3ЛŠБ8˜ћЯњBљуЫ/лйКuЋTi‹mТvшЁзГъZsyœдЧ/wЕ^$ч @s\sЋ№Ј/BxJš’@UХЄё7„CЁ>кЏ9џ_ц‡GЇ?lъ–§ђёкЬ™Іц|чнїТшыЏ7[Ÿ/щyєшй#ќъЗП їпsOрЙАП“ЮеЎЌMžу№wфˆaцЬз (ЗmпЊ:ЄЦ‘Gњ?НєВ\U…ušМпЙk—9і]БrЅurіˆвйМ§Щ'G›^ЄI$UіЂKцЩЮ3\H№^впАƒ[ @шMОЃ6.ЊO2пжkHъ'E—“ЊSZt"№`ЁЉИ#а]&;Љї”ˆ@@Р,!š™rIr5’бо=ѕЭПu5Џ/н4HьеиИРМI’rатt‘Хqђz€“К№ƒwЬ`Ÿ•Ћњš ђ1WIнјeўžv‘ї*wж"šН’Y8ƒ 4$Ц[ЇLеuяаOх :м€pдІH–,К}Ъ­ЖјЦЪ=љ0мпX()Э},ИЌ…Є‡эб6О(}БTчz &ŒP‚>гnT Ађ T™lО‡ЦЕ :-МVOJI{”эQ:—ЉQ‰žNлВ#ŒgЧš _3<(_nЫ@XнШВц–еtSыс+ьzмš5kУŒз_ ƒЎ)7ЛŠМи[ЅлHоЦk™7–}pа‹чˆћяН/LдОN&љэ QрDЧ`PyyЙ=Џ>ўXо‘АzУ)gД‡Ь87^Йqpћ˜&єYЦ§і{яйЪ6МN№ЬiЯ=HуKР§tў|›gЌњ ЉRгyГыŒ lXжЛмЗOпА~эЊz ™>•оЏo?@”ОиЛwoћ№g>Е$яНŸiЦš—Ѓ№CЈр‡m\њчфсCжгћЈ<тесNT–ЄиVдG4=кРкш‰#?що+WmТИўрŠ ЃЇLTєёЫ8бU Щ§P/г.љ[p`эeQ6їзXPЇЦ‚\+јњ(шХD+^л&,-HБ8˜l! ђ gј€Q@лv,гiс?@.Qžч2—ђшЄAo­і•р0–0oС“,XŒCи›oКЩšќкjE5—u)yЙЏ>L^з›ўˆyœзЊ—iђ„ј|ЦЌњаЉxХˆуE”Ўъu•ёѕ*OОђјrЄ“@{eЛ+MJ2hА}ВчЈЊъ”:FЕŽO)—eжДЧ–ƒч:dђсFЇA"dЙ5язйѓOr);П8Јt“Є…VЅЁ ?€‡їWŽЩsшМџ@ящ>'язєM?їђшЇБЏж фщ|оъqZЯяGЏРЋЪѕKъ(\УурF<чщМ~эGЏЗабŒnG‹‰0)Š\ю_А­}HЧЪk™ЙДЄЙЭlƒXЙ8!B‹НВ(гŒр@heЇшНHбАЕƒљK@“,Э 0 f ( Уљq@2prнмR3КB€‡HaУ‡ џ_ўо]~ЕЌf\Їљ‚чџ№ЂT˜ЄлпюбB˜іWД/*nЏT7”kЃџўпўk]‡UY|œё5IgB’=fTXП~Нд-mC{mž2iЂ}>џЧЕјИ*>ѓ,+5 šgœtDhYљ†Zд;Xš.ЛЮ8pБsРAЅЁvІЧ6Пі#љќœЃŸ'ЫKЧ'ћ”гћББ|щ4Ў=Ÿ†ыBqЩ<~о:/7},њЯјPо‚œbI†ъQЛЮQлО<є08!› Р€Ъ ЂіqфЎtH…†рЬKOІk@д|б‘}{УЪ]нТЊvТяЦ уЎэ0Тd*IDATNЪZ?І‹`жjŸЫ˜17˜TА_“ЊЈзаcГёђАtжьqљB.uЦK]ња§їgЁ3PGЄЃGŽJ 1 зžK,CЧ‡Уо}ђт.)КЈZ'щЮ_@Ž|%Bƒч–Ћ'q@zPцles- `”й6Э˜† Еl~ЅSѓ љZєЪeю€–=Z•Ъвoц9ф<)р‡DЪ9o„Џ0Mмк9ЇдGл§>Ю!Ш"2ќ`є+Q?иЃўжGёge"›Чў~„LЌiвRCƒ†ДDП=EhxˆёЖbг[*^(Щ9{“03y,еЅ Jео1йч瘽Ѓ ЋVё‡œЙљRbMŠЖ t&k5Wi‰ЄЦшНаHšљ‡С’ЅїЩi*ЊВ™oОІШьѕ2g4x№ №еъ5љAЛ™Хfd8№ЙŠ‘sGЄ.ŽЈ/Y|УќЯ„EN<_–eЃуїЏZžєЎжфмA€МКџP+CхXœц P“В˜€СТ@VЅSfSќYШ8qрђх€yŸ`>Я€O[€<=Si8эe.ЧPL„QЪ‹У\’qФ@Ѓэ€>[OЊХ7јќгJг\ VъЛпЄ‚xp‹ЪдБц†ЩЪ‹хb‚D=z^Aхq-.‘‘л6ZЬђ§ЧžW‘Yц:ИЮП.ІŒќЃ#Фw*~Ј$у>‚9'н‡ЎѓqRz Ў9шєй1у@ЦЫ›%ЖКSј„ЩgВŸY0ЯЭКмЌхqЉЯќЃкѕ IМBВг’O‡RЫЎђ‹5рEи”Д˜/3žЛМЃc+(ЁYsŽљВr'TЌі0АbY†хЕГпy'`"cБШœtб,ДžMёЏPzЁИt ’4ЩsЇ+чiй1у@ЦŒq@FЗСIZ’њиT~9јБhЦaРєѓЦ ”wNфRЫ+ˆгˆN‘)”UЇ"ЬЉ•‰€?BлBсёЭ“B^jQ•E‡ˆ g m5gУLиДsOtVaъ.вLаFh žЩTќЂ ф‚%чh<ЎЅGЬљр_ЫмhЉ=ЫыmЉK Ъшфƒ=?я Пя* ЙS6л*Юju(ЋD аёl“ЋQ б~WэM–SHУhЗ/ JЗ%™ŸД4я’щЩ4_TЈNЪё|žюзЩ2 ѓP(нј,~zNЫбщ9OІjqщz+›2Гqрћц@IЉА cл UЈ&Я꘽СEFЏ>лZ!qŽ•!ѓ‡…†5†#+CG€№Œ”Ÿ,{qZrЩ№§Ur$І4IЕ БL…0Ў‘‡vŽLˆdfфщš–:+ШТ—_}U.˜Ж„M›7‡E’ YщH.ДтБ%udДqPDнŒњ™gФVŒxB‚_лEъ4FЫC2ЯK@lЧXЕzЕй1ФЬ’‹— -.mРЕ4˜[Т”S’:кXPђaž‰}ŠiZв“mNЇ3зьћYYйЪћфђ1ŽбёыGŽ4ž$AУлсћ/Щп|Е,зЩv2Їэя­9Пм‚Д”Gћ8R7?OчоŸrвCž!i^{нЯƒ2вВ 'дk—іxШ_ЁсйQІ= K Же…Ж:]šЏ9Вьqр{у€­XlМA2ЬUХ††шŸP['ДweьEcДєŠХKeРзКв4РшЊцlЕŽОС>'] 2UЂ~Њƒ<Д%d§\'Й@ъПђHЁCг’ру3O?mŸu|‰2АчŒcж[Тбsi}0gР_Пaƒ@№Œl і1;ž@УsС\Kžзœ“ЦPРТ іI1Р[Йc‡э=dS=;Даи{ЊЪˆcOЃЋТ1О]ЌrIї`энn}mнЖЭŒtыж= Мz@^’єZo+эЁќ’aЅœŒb,кУ‡лžIh=/›ќЗnн&мxc8ЁŒЖ9ZGвi/i|œЁЕ –ѕ}zЪй%ƒтлwTЊХfП‘НБюJ…8#У%7т)wŸІШ;Bўпг§ћ„ЏзЏ3ЃЦƒeЊЎFЦг“э\Ћ Єc#’=Ÿ№K=UЉ2œ–6Т“э•лхAdWhЃК†+4X.Cщ|\'^№‘€ЗqœДbЄ’№–žGА>Dћ(ГОwГpЁ8Pœ_Ќ"ф’вPџє5/еg[u$г€ ŒђЈVh†–]]Sb,о1зIЙ_БŽЅъРЅ’§фD”tv–в8БfЅPRюgu?Іё—ЈЦƒ-*:›ЮŠЕsМ#3№0eЁѕ€€бсC‡УЫђ&С^ЭіeэУЪ•_ дd!F{6йЊ€ ХЖ(sЕлBЇd5у˜ђlЭyž€—,XТЕ“I"T{IВУBОƒ$GЪи,џi и в ў”К+Ў9RОП ДЗTfкp§„“ЯклœёТЯ?ЗETдgрЋђYdХ9rАЂO{ћтм"u"с`МЛЇцœyЇ\тТ‰(ї @^Ќ~ЖC „пФz.Ђh@ У]$СЮš5Ы\IqкЛtљ2k?€ђць7-~оМyaГ<иw М#wb„j}D`П•М|tМїўЛсЙ^А207їђŒ—MлђЉ<БЌZГЪкjМзЌ]>§фSћr}eЦ+&гvк5Oїчцъh`…eЁ%KПР–˜ХŸwчМgћŽч~07|ГswиYЙ#|єЯ- Œ'‚Ÿ}љЁіЭ—Эпѕ_Џ—ЅЇУaЖЊђœ2Дט§Й€ў”6– ѕX%=Тг†Œ:pр ЭР бrрЃЫ1œћB3ЂыtЈеъTшXAzF"b5 Й‘_2$у ЇН­|&;›wшж—˜х„XJУŠU_…Ё’ ю‘;%Є”#ЃъЅ_, ‹фђЊН@ oвO(ќ wXврЊeг†MЁ—ЌФwьдAч›УПћљЯЭлќ{sо х„sЗРупќэПK$™рЇ Щ йВyKјєгyЁGЏž2—ЗD.Ÿ1ЏЏП93 ‘Wь?М2#ќŸџљ Б9|ўќ'?БчЯ;„›АЃЧŽ,jBљРrIpWšЕЁНшoЫMвї?[ИаьдhoН5;L™<9ЌXЙ<ќеПzFяЃѕ~Ќкр)ћZн;яэмЙЈ–Ђpр№~ГцпП_џ№њ3 TЗ яИэŽ0zєѕVH‡нЂHK•к›dО|р@Ks`Иwк=іpьјБ№ћž(јь5‹Iиl§няŸГz‘šзhUєc<>ј№ƒа[.kюПWоd”‚Д>Нz‡ЛeчuёђЏV„ 7но8;V’уюpчдЉђ 2Ъ$eМƒ`ЈщЇЫм›ž9МzшўЭђЯО§ћТЋЏНŽЩМс!™в{RžЦЁџгK/щЃц„™аУЎы>ЕМмѓ}Ќ<*‹OXњ'Еџ˜TпHКЎ!№КВcЦя“Z##ЩŒ=„2Е–р`дЧ`ФC!ЇщРЋоi и(хЕ(G9ЦRк9иf4”­tФfЮYIЂu}MБЄјOЄјќ PЗ+№ї<їИьиz0€сII ЩˆСpЕ$'ўт/Єъы~џќѓцЏВŒf3рџњ7П уЦ37YЏh—›М?§ѓŸ†Щ“'…W^yед‚Ј;yсH‘x–,_КєшbjП_§ПgУдлІЪУіњ0§щцЎщдёс”Є;TsїL›f lИ;TvH}хз уFп^{уuЄмО (КЛ%Йщх=ЩеCРюЯ{8мvыэЁниЌн#яgƒ6RчF9~щ•WЌнЧЊuЋУŸ=ђ˜yћ^Мф љЦьІLМUqjЅђž№СGрј;яИ>–ф5bј0Л?„:бmдЌйoЈЭcѕ1PЊ‡ŽrsЅ~ЁЮдЋO/ГБ РБzзю]тХК№фOкЁЖВІФГшеGnijЊхуЎ“iHрЯdЙСBKX^)чЇдлЛoя<№б.TЛДƒрmцIЉoшууІё7›флEОыŠ5КЩЎbЗнХ;M‰Јn€ŽВс+‹:wщ,ЏчбЌžGˆѓВ­ЂьOЦ Р’RuіЂђŠєбpnЏ='~Oы§…žЛHЬO{C[ Њ#qЩрљˆdQ–В‰_nщLЪDmkл.ъ‰ЁЈUг%)ЊБ ђшАYkŒIч™ЦУ‘дVЏY Њ0ѕ`ˆj­Dƒ%sБЅМ1О›%ь‡^yeg Œ5&іаќч]ЛvГgХѓbpЦ ^ЧŽ4j.‹zєѓgЩћQЋq5+в ъn@Щ“|U>Яž6рœгпQПлЅMœtKИуЮЉR џїйgУШ‘#Bi4кЖ-Еxъcо­[їž6›/4Оsяƒ{Eyy˜ўрƒ&Љюв–œГЇkе.I8Ru’ЏCдЋД‡2RРж…#*њš'džqШр!FOНДа?%GЋsЄrЌ44Lš0б$ЏƒšяЋ:Ye>Dїьвж Е Уэ:Ж фЈxƒ$mцхоŸ;7 •tЫд@хжэFs№РAуМ еьЩ“ЇjУ5§Џ;Жя0уЄѓТѓуHаД ЏяЭ}_ž>Ц‡ёњ˜A-§эžoУ™гr$+`л'ѕ3ќч‡Z›’vЊэLa?)-+- ЛЅJХЋКѓ„zГqрBp@Ћ ЂРЉџ˜4Ч9!=hФXџыЉ€’H€-PЮЈuФ№ЖI|Ќ3Hd%z‰RпЪя-4R•@a$6'Ј@Фч‰ЪšШŸuФ&T €bžlєШQa†дcoНѕІЄПюaЧюR}="u\Я0яєšŸ=sІJиЩЄB‘gУљ)№D} Ш<ї‡Тžoї˜šє–[&иќ\якшекpINЫ—-З…]{5р2?6h`yxMuсјџы—сХч~oeО­94дp”Э3F’aЎю­Зо ЃфdДZR Bh$­™Год€О7ќњWЯ†џ§џh :"ЁAŠ"Пoмр§e‘+к…zoа с„ю‹С}ПР ј7ЯџN`к5lкДQjдс*,оšџ/ѓхjД…•Їђ)§J НяРўPQQn^SXРО5ћm(дУєF-ИaU4*ЮџєўЃ2I†ЬїvDRйЌYГюілІи}М?gN%#є7ШЁё;яОЖ ,œ8zѕМЪUы2-jФ;їа§тў!tJ{иаkУвeЫЬз€§У,Љ‘‘hёЇ‘eJ_іх—ЖXfјАkMЭ§жляПКѕь. ьhЯЇ%§е@і'уРyp шЗ.Ж X‡ˆ АђцЎд (oгціX JIк‚Tйz]Ž.y ЉG“=Bз…y gЮБZe—Hš8ќэЎ0Cћ&н0ЁЪYБтЫ0vь8[,б\pƒ5ЁЙyŒјGі‡{oЉ&чМпЂ0€+<ё4Зqѓ“@† Ња€z…ЭoБА@aоШм0iРd•#’нч‹…ВvЅ:ПR‹PzhNЋwјF.˜ьKЄи-Z`ƒТ"(V‡–ъљmV44А^%‡Ѕ^‡{БіЧE›™ћ;ЈE0:UўОцо Љ’E1HqH1={і4№CjBJ=tшРТ`Яя тPIrЮ;XJWЫџ%эўfЯ7’0ЃФС1щXхJЈ…“ёЄ{{aњ е\)НvгцM&ЁQљQ/їŽЋ+’иЗšыc>Аиfѓж-ZдгЭц>ЉžnмЯVЭ_ТŠт}GћИ@э ќ(//7žј}г.>.Ј“ч1d№ } œ•ЊxЃёhPХ “6‘кhћ€PЛP(ьЫдŽ(јNeV”+VIpХ-I`ФАЦд™”unр Y0sVфъ ЃUqU*Екс‚&€а [ЛvVVкW,sM:eѕ™j­LьFeфщСЈЉ2~,щмwK{'ъВRЉџє2иФУsZ№ИJ^фFD=дф9љ‘3јЃЎ#WOМ—Јк.‘ВМiЊR$Цt nъ$@K{РˆїЯЫ ŽrhГ},щщЯЅттН&ј 2М\Лч•™›З•А–Zї‡ЖPѕЄƒЕGїD}Є{~юŸўXuКnПmх^<$Ыe‘Ћ7‘цТ7Њ~roЈhQWыcРя/жЁвT7 аz lчЖ[ёNoяќPлЙЛzэ=з…ю›В/Ч2 М0O>ю#LдХV д‰Х’ј4ГbЊMuЏbqБ›ѓ7*6ёVŠЕ_—]}Хѓ$ЊАN iI gD^ ЯчЩsd&R Уq…ЪЭg"]kИTG}Д"б@АЉ dVС f;wэДyЎ‘#Ff3ЩдfœУwг5к)'~rЭ T} tl; ށкг“чфGʘ8a‚ЄяЭГ<њPсXx^@§к@AUЕR3ё}?Зˆмj€Н ЎiЏт“u:р%Ыѓ{ ёЦI…~M`х!™зуhKЁxв§>9‡ЦщъјЪT@tAEнžНЗ8Р­ZэтмЩtі&rџžF~Џƒs@6’iž‡ќ'rќуƒ„xР)™рtœ{ўtЙЄe!уР…р@‰оЯ|рх,)–nСM†’КPџ*ЦЧИ˜ј Œ€X&‰O‘аNk ЃTнeЊaM+и |@{п‹РСАС Jˆ[‘-еoŒ.P!-ZДаcдoЩЏп4}v}.l‚яTЩСЯЏ=7i8чљсАоћ œЬ“ІO^;]]‰Бф4MВОBiщИфuђšQ‹ЇоeP’узhFR ^“RŽYжb=зzlІх Э“Х"•Є§ИA‹ьЬMЫ5iЌ|мДe‹yX`“8[$ аcM%SЉ6ЦЅ,-у@Ц4ŠK‹ё;˜’ХРЉТX•ЮпЂыгк4Ш`еP"й~иPЖ,ў"сШV–УГg @ђЃ7#‹aА6Т7Cш=щЫe…„mИъaotЄ'С–8дEK–XU:ЧГcЦŒMq€]ѕiИD{™)˜LЄ4pšœKLдКXф.AsJнјШE§а`›jЩ/фK-+vБ&BРФrњ“rЗјБЉ{Ї-яьлУBЙ4*+kgюŠА/њ‰ќщ]#зCиЏœЗ`~8*?dˆyДьm6]Ў˜&™TиПп€p‹ЌЩ№[ДxБќFGЛ”‰/ь{Юљxn˜<>–cYЄУ+О ?{ђЉpџнw‡2™vC2МFаБ;jS`э$Щє˜ы,dШ8pљq „ЭуХ2Љ–9) wl€CC!аѓ™Оц рš†4§%—*`РI\ЏкP/"^е’zEž… Ь›Л“t…Є#T™ЫM*› gГeЅэТ9‹#­НeŒ›Рœ! ДaГŒrKuкI†žБ)J <оŽ˜+–ПЪ­цбўT˜pѓS‘іэлЧ H#ѕah ф€6dВŒ4к†)7<І:дœђpЊœ,dШ8pљp ИFЮмвнОVh#ƒ0ѕІъœPЫaeУ\J!ЇжŠ LиШ­ТIOаPЖ]њ‰WІxдЩЏaбIГуФ eА3 Р`\›8М!d•;wЪУAЛаЏwŸАY0ЌНjэWцэ`њ|сќ0ЄЂТМ ьНWrHcЎ/з\н?t‘7Š’і(o xЏџdоЇс]Йњrх ѓБbхЪ№ѕКuбрКђЇР‹*wIљјуsvLгДйuЦŒ?nДљЩ_§ѕпЕaо.‡|у—PЂsI ceƒ[Ср„‰qкbЎJI™Z#нЫЮžS44VЗОрЋN •фGЎЄsxИЯщаЗGI q1Ц9[СЩРЛћ›нц>(ЙЂ1Y4—zhJxR@ƒнеj›гhЧOШН‘ЈHо|!ŒёBМC… ИPqШkrUР‡Ыxzг7`ЕiƒзѕcсjЭ”Й}GЅђ”˜з мсђ{ЬћсB u'.–9њѕэzєшЪ–лќ#}Чkn”№œРBђеkcъЁёёHбM*Kv™qр‚q-§­“њR-яЉЦя‹Ќ—AEв~3Р[j#2#„~€Ћ9Й„’_С!DЉbjэœеЉ9:ВYVšУоT~.srd~žВЩтE4е]ƒЬИ ЭiUeЙ{PhUЉL№Е"€†{їгЧж‡ў§ћаeк]w[NT–€ЯФ Зш‘ЇбсџЯьД4хšф†Џ=Ъъ./ігюКЫЪ §Фuыо-м;mZЬЇ2‰0)Ѓ9ЊЮl`1vf2\Жˆ#иф^љrM]ъд|*–ёОб1?šI.…'—Ѕњ›CI LвI­њњЩyJ€№b HDЈы6lXo’ФЅ8ˆ@S™'0О‹р`ШБF Ш1Gi7<'‘6ЮYkeysB2ЏЯѕ~€›ЇCуqщ|NcФйŸŒ24РџpЛO]{‚;IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/12.png0000644000175000017500000013076411733011756026242 0ustar sylvestresylvestre‰PNG  IHDRmAœkЄРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН \зѕ~§‡ќwVlw•ЦEcЁFƒyЉbTДI“ЈЈ bЌ š€ZЃ„Цј *FJL ƒbT|ФŠZyхIкjŒѕQI4’ЈA–йm$;ћ/љј?Г†awf™}Э.p&“соsЯ}}gіыЙwюœлЉКМœр ˆ€Я#рwЎєВЯ7ˆ ˆщdЈ­FD№}ќи;fпo%Ж@џ!@D M €lе&n6@В>ˆ"а6@Жjї [‰ ШVј ˆ@л@РЏm4[‰ О„@щеВ3ЮиiбЧ‡„>BRЖS&В•p0 @D ьГш•E"iMЂєЗг!„хrSnёП8ЧЅˆ" …XU@UЌй@OІ cu‚|њдhj|Y)ѓЙ„^YЊF*GлЪ>>˜Š 4HШAl›д@ДК@H1ш›?žБ•H—ШЅДЮVмgЯAAС|A(A4шУ€OBGxјОU€ФЋЈ &Q-€$CQeC„m•ЗЪ ъюж ѓЁб р“аža…a`J:4@УBЋ0ЯST“F­tьD[З­р_+ЊB‰PDб Дз'Ax[„m‡{L…ЖIM’ъЊяЗXU?T‹ [T`щ$пПš§№8ђј!ˆ}:Ю“Р?ќйћїТ,ЛСhоісх”† BГйИї`nBЬt^™Њё:T ye•КЪ ђ™бьчЁ€ЂhP:Ю“ Му„Pї-pхOрЉr8›’„ъœN“UEuˆ%Jѓ 5%У­љЌэеаХ~ёЗˆЂAА}„Ш@иlмб+ŸdЪƒƒЙЁIyy9еHя†Џf?рРHа~A˜Š :Игзъ) {нL=?ГТ‘ ( еЌУMЪжђ–qlЋ–1† ŸIљ Гшg LЄфъЂbЧц­D‹@!"€t(р@Ы‡5АRJђУ 䇔эУˆ#Aћј`*"€ˆ ра‡Ъ)‹Tж$BЖjBџ"ˆ€o#€#AпО?и:DhBйЊ ќ‹ ОВ•oпl"€4!€lе„ўEпFйЪЗяЖ@š@ЖjBџ"ˆ€o#€lхлї[‡ M [5!DРЗ@Жђэћƒ­C&­šРПˆ"рлXћ`8wўlГЯпn:Ж@к р|f№ 0ћнiСV”Њ&GEлЯƒЉˆ"€ИУGrЁ@ћ„еb$VR•{я–† rцiuTз‚­фŠ:ˆ"€xd+ЏРŽ•"ˆ€УĘЗr8ЗdРз>pА ˆ€3Ш™Y–лЖйŠRеМФ…Т.a@М…РсЃ‡'??Yfэ[3пMћ3ыТЂк6[СД\ТьљЦzЃАKFo!Р6Ађ“cbяп'Ÿ­œŸЗ2:HЁƒy AЌ@|ІэцeЖЭIл ЈjуA’KTў2+r\ЭlЁC?Й‡Б›™%b›џ/+иvaWimщ‘ЉGДЌіZ‰dЗLD—ћ=К\.W€3leЌ'iћHёiUrЌYх–V љ™%?œ%Езˆё&ЙsЫl6‘ћ‡Ћx†tjI…ŸкѓDхкОк^]U=І=>-ў‰јOЮWЬйUЎіcњ‡ЭЌQхЇвщtRйQŽ >‹€lХXtѕF’y|љ ш иЛћИyТ|a—ъўGДA‘р~Фxе_`џѓЉЙќSЂ{\5xёЗ!рђидЌё(ћЯ7ФЯџхЁ bХž,е›wxjйCЦ‡ы€dчН]vх{cк4fФУт4ћрoCП§ЊДЉАЦПЂB+Œ"ˆ‡@ƒYј{l Ч8ФЖbˆйLv#ЇОQ dОђ йQH‰Qкќ‰­ЕS,н|љMШ#Є! е= XnŒюв &]Р МEЊЮ’#­ђбн[§ъќ}њцНŒЩœ™иє №дтwЪ OеZrлР^г“СЗШ!Œ43Ÿ@**Єc@8€~јБxnо ЈjгArх{UЬ3РЊ‡я'Р_жG1˜Э7+СrqŒ5n5ВЌЪdи07Шб_Я^ЙhЈИХhzАЕ7˜рGt>dЎЉ6дZз&яЌхЛ]­ыH4*2.ЅєыJCŸ^ксуB€\?љыYЇ†П\UчNŸ{ыЭuзЫПыжНзМYѓЦOOНuЫО#‡M?šF?;:uyЊŠс Зап†Ў|mхЮїvVъ+K/Zлk4#^ŽŒ€c!оЪќ3йћgUE§ž0ZТмУЈBЧ†<мœёХУЄЮvmЪн znL№їхƒљœJETЁ1З 'hŸŒRi9%VКа–ЄрOjˆš!Uwи9)35Ш‰§цТ=г…›ЙчЬС–YИђљC4Щ"\М|ёšekF„ЈЙ]Г}зіёу9ЖкЗ'ЛфЋЋyяч1]˜Mщ›232-\D +ЙXr№РAFcЏ:О^ эС/(єБPл>9§Зм 0wЏћ{U|[д;˜—”н,!ещђцњu_ќЄІОісCИ›ЎWёЎ=šn‚Цё…ѓО8 эxцmћвѓчaq8\­“\™%—­Ш=dz1Э…—ѓŒF­"ІzxU)5D3~pЉЙFЎ}a6і26єPѕŸDt§ˆJ0дВТ@`OіэђљБЪnС№Nї€№ж’›WЗLЋє†§‡*Іџ^;+Bcчу€ШёбpЖЈЁЉќ‘#"рlNj’OŸ:N+љљ3чэдвЌŒ!D =!у­Іп…ŒnIЯ ‹evŒ­  ЇФЩцК}$џЄXyЎШ€ј€Z EА`НЗŽ…YˆFм’Њgїјƒs?šyцыЫCќˆ†„0ouЗ„ѕЬщђУŸъзLг……8V TE(GWJ’.дaЖ‚ЂрKfјBfВнјЛ$м:[Ц пј nСЧЬVўИщКG3Cƒ1ЕkќюГ?œ]ЗЫPЎяЎіSk ЏхTР@0чUЗHТЮ Сeb@œ@~ŒЭПGћљхъ5•т [A^ЮТšъN ‹^АG}єmГ-UС„”еб_vp ШŒa0бFŒ#VKYˆЪFг*#FDР8ЎђиЏLюъPл8:ceУ2ЖEк“аь.bЏLCпFРIлЪ+ВЅ*№ыМoЯО‘OёJ{АRDАB€5ГfXл$я8ёїbј ЫгхДк[йіŠњH…>л&Ё@”G&tфџ;ж.p3€АфћuVўцaˆ"р.œŸЗrW АD@ф €l%%дAя#€lх§{€-@9Д`+˜є:|$WN6дADРѓДњ~АSu9їQ1рFэ<@Хѓ~аš­kV„ ˆ€CД :”•DPЖН:TIЄА.DE єjй™ gD“ф ‡<>$єaЮІУWи чЫьм$LBМŽ@ирА  ‘Џd(U-ze‘‹-L;JАOX>СV”ЊТFŒtБӘ@ф#pіф‰y‰ eъoЭ|4m Ќ* *јa[йi&!ˆ€O аŠз*Y”чbG­\Г#mж7ъв=m…ЫЄ3:’тР +wУŽд‚Кˆ"€ИŠ@ыЖUуЖ…ЎV„љDРї›HоМ•§=–•кzуГ2 Р]Ї­ЧNф/п{шАEˆ€3ЫШ%ЇЦzЅЅЅЁЁЁаВ}ЭЅ’KЯ 6ИsМН"Ж•-=9^,ц@v…€\яХ-;§юіw‡;#vЮМ9ЇOžNп˜с–*ФDиЪ*З•%E/zхy-;kЧО#‡M&гшбЃS—$ЋTм6 ГriЪЮœ§•њЪвq{jYeUFDР 4MЁqFеQzБдJтPtkцж@]рї•пU Сб–Cй­”˜eЇ9)CС•ЇЊ}{і–|s5ярЁŸЋ’Й%“ЏЃфЋЋsіPЊт…@DР–˜l%’ЭЪ“8чП2Ыл[†>14ыэ,)N.уa+А€јSF dў‘”ХIšn0Љџ”Tјщ'|ЎфФ$ІyGxžрx ˆ€З€A^уYzБy_aKИ9ЩХFžўзщэЛЖЛXˆШHаQNЙ§CхИ QЭэ ж,Ч"€ј -эјљ7ЮиД”;Н, +j^Aр7Пqe0( gqьІыUМk“Гјa>DР{ќЬ™UVЧљѓчm…V:2Ѓѓ^—ОŽ›YŸ8vbТь„Ьw3<>€О%”Y‚PMd$(L tы\Qеьq4fJTкње5UzPЎИYО|ušh.gK%Ё@к2Т1csјO/ЭŒ #Эааьэ[р„?№lhНїЮиV 3fEЧNџщП?б1clЬtЈgFтіщлїХ„—[Џ5DРGјYf;ь.ЬВ66њp~ У!Ёй”Уо_kЖВДт%|ш‰2_А­’x}^ЭVТ'a@|XЦ]§Вf+w•‹х ˆ@AРЎбддћJюšчjЊMќ/В•8.(E:,ыF“LЈ™e—Y4Њ!ˆ"рF|ТЖ‚­ФРaШƒ­јwcЗБ(D**jdтpтяХрš]ІВ‡д|‚­тPиї^Ж‡:‰Х"ˆ€(РAЂr[Ёд.šr_,кь€w?u,TE+шž7А„•мб(l!бъ&]ШVŽЂŠњˆ"аХіDЖj;FDРgРw‚>{kАaˆ"аыYі-[/}Ц}ё‡"€ Š!0юiнќy–OsЄЋlСV”ЊJЮ_”жЧD@<Рc„\ЖOX-и Ќ* Њ‚Тg.]Оф‰ц`™ˆ@ћ@`@џаќ™Иёn^НЈў™?Я^‘-иŠ*Т=Xєђ|тЧљVЧ@Ќh`гпйBќ™X#уB<ўЅ‚Vs‹А—Чaхю2жjЈ€Д+єWn\—№gЂьХw‚ЪтЕ!ˆ€Г [9‹цCe@ЖRoЌ @œE@bо ŠSф3Eg›нѓ=јаƒп~ѓm;ьXћюўLМПh[)ЖSU‹9•3!э d+EяhХŠy‰ѓ„ €mЕzч .фИVE…6‡В•rЗLџƒ~ЪЬ)OzъЬggр„DAЈ\ А&D -# =oEьЛoЫіRл3пн8?>aђЄёД~АF__Г–JіэЩоВ3лєЃ)rRфыЫWЫЭy№ЁаoП)Ѕ [ЖnйїзУ 0њйбkWІ2ŒŠ“7єŒ-‡ѓ“гќy‰Б1БФдМтѓв№ъn№gтnDЅЫ“fЋЖу[^КwО•rъŸЇЯOюЇљlфЮшl^rњ|ЩЧЫƒF/[•Ф4оќЦXюEіЮьЋ_]ЭЫЭгј3Џoи”ўfцŠ”E А%+ћцw9УlЩЮ„вО§ЊєСп†Т•ЫŽїБDЯќAx=ƒЋhЉ’l…џdˆтхŠАђv­JЃ блЗkyIЪт@˜ётŒ„&ЖЂ ћЩк–Ѕ рџœ8ёYиъШб#{vэЁђљI‹јвј€+mЦМі@эууоTIЖro5X а-Рh4RZЁ€@Д[Зœю=Лгpїюнoы+y9 РVиуЦŽk6нКJ}%ш7Ы1„ДSšљvк=Ÿъж№сУ >*€y%ОU}|јp>ZSUC ЋІІІ›Ў/Ї8($;*яЅыњ<гYхТ("аn~'r<нŠРœчРмSссBsНЮТc…Mš•дˆ3!6m0жс„gFбксYГbІФЄ­JЋ-•XRQVБ|щr*šЕz§jЃоh6šЗМ™N…н:sЫ#мк~,­сЏvBT%Тh[IуqPPPЮЛ927ЌйМŠєЛA9яnкD81z"їNp|фќ9MSьM-‰ o gЬCТ>}ћОјЇ—iJB|Т–­щЂ|Ў„‰бБб?§їЇв‹я›ŠСПˆ@[EйJб;є@ажЗЖŠVIiE8NlTм"HU€Щu8…ХЕqь†"аŽ ЖЃNЖнЎ”}[гRmЗ§иrDРўсЖ.еl-РИтL›ОјЯ‰„рНPzЙт­‘‹”ыzвl“gxx3'OpMР{сэ!Y?оIhмŸ ЩVјO†ћСЦлј3Qђ–тМ•’hc]ˆ"р<ШVЮc‡9D@IФG‚њZ=[Ÿ@)y#АЎ6ƒупИyўLОg"l;;юнПWсv`uˆ@B€ю~Š?ЗоВ~­–&ТV!уBрl5'* ќ™ИёH{сrЋЅ9ђЊ~иМ“j†,ћc№ј'‚Œѕdо_KЏ|Я.˜Ѕ {LX|s8М{јч5Ÿ7Ч-!QЁ•FD §!а:[UMX:СЖчљыѓ[e+.—_§‚у ›їjL†рЬЙ§GвO-~Ї,ї”О›–Љќ[ЎgТšWЖЃ@Z o–>†В=[”#щЌх’nWъzj‰ЪŸŒK97`іЩS?˜У'і|lџЮ\Ђ“TuіŸgg>=sLpјдЁS:Ю•d9іnк1ёЗЧIKJЇwTYС{ЙSO яоЈ‡D M! ­`ћlлS^?ќСМ"0Ќ2АГџRvу?dtTџп=rыКўж n+=ІuѓNМІЕѓжЦЇФ_џ<уHFЩ—%TioцоЋЏф|–SpЅ€a˜эЗѓ™K.]Эњ$чѓ*ыЁ%Џ€D№eфREўЦ|a7&$‹Œ … aрЉ.ўПV3Ь#1_^d'ЯъoЈe r.‡?ФєаiО=ЙMА.^­VєуmЃЎЇ.yC2M.:P”q CглfNЪœИQq‰ЋСу w$-OвXv”ЁQМ"ˆ@лB@&UА’ЧДьї]}?(МЖдсb №FyW†!=ˆкhRєAYіЋ!ЁН5‡Пmэ vбж5 гоKл§—нйГеПP/xcAияУ КЪђЪЈ!QЭЭhR ЅАц$ !ˆ@›B@№k–n7+сФ‡.e^mЫPћs$”VЃ" уОeѓћ—W7•žвЪŠљ^СН*О­zАy…WХе вZBBCжэ\a˜РZћчЕy%мОЁНюя•U”…Фd{#P‚ДuфЭ[9нK?ТtitЮгj *и §рGх[‹kbCuмзЁ_ˆŠUѕbдњЄѕeЫш?ж/\BЊ “ш7-лК@ќљ!uУт њ =dІБ‚Q† mжm+XWUќvБmЯш‡ЖrЁЄ3ёяъџ+вх6p‡FЃ‚й+вР>7>ЂьЯ„e9ЋжУxPќЕ`єьh˜)_—МЎъZhіьз3jfTфДHZХScžJ‘њнwпѕ}Јяšw—SaєЫбHz!щvUeЯ~}у“тЉЏˆ"ажh­`Q•ЌuUbHєв†|~ИВ[0МdДўмы?•УMЋћC•aџŠщЕгЇˆS-/2.NБВЩˆq#рДMТЂœ%LВ]e*LХ0"€ј>ž ю™ЛЇO@пВk?=q^р??ƒзJЫГsЪЬeІOГGUОЖ@C uлЪ•ІЈќTлfя>{ѓьц7 е5не~*НžнВЋŒvћ&Ў›+ec^DшXx–­(–aНУЂЦšпџ[ LWэм[ёh_ВrБNЅDЭы^boі€Bœ=QeйљРФЁ_ћ~ЂАwˆ€Ї№ьМ•ЇZх"ˆ@ЧC@QЖrХяhЧЛ5иcDh€B#AZЇ|7~ЬчЙф§-Z:aћЬЌg#ш!ЫYф0ŸgР'г>ОŠВ•\ПЃf3P•fV:ѓл‘ДѕьЗ—[˜ќtлЮАkŽ“nЭŸци* hы ‹б;Ј([ЩД­˜§U}2ѓ5кJ&HC60* ПЧ!§^ЧА-…МСnmTГz(сЛœнoьўђд—Іkћ<:-iкˆgDV“Zх’Šт#… Ъ›vюЬ…Рфјшщ‹н3рunmsћ{be+ЙЖ!цяJє Иoh„‡Q†тц |*˜ј|bТт„ЄIMйеВƒяt…­š‹Ц"ау‡ .|~!чЧVKf- >1%ЂЅ Цм€€Ђl%гЖ‚n­ƒэWœ @;Ч=ЦT,KUйѓцž„ФўЃBpиК5еJгъ> NоY§NеѕяКѕьџj<)Њ#Е–“ŒЗИh}ЁQИ#ЩVКу[нjQ'ЏЄЇџy:ющ8иŸьg^. P'Ѕ`oУ9юЁq@Ž|Ња œЂјŒhЃtўeg~ПќвВ;Štg*ѕЕК M?н0iРыJЩЉ‚дS%@9|!Ђv№(6 —Eћчn!Е­ЄЎТкXП@Іў&aТ!.Œ IDATы„Bы0г•XvдБNртУG?QxBЪлLc?b6›U*nОЩhlІ6QЏЄYšўШtR*ЇЈІ"ёo[EрбGћ\+Нжџ‰ўа<№шЃі{вKo(1щЋєхѕ[Шяo–SЉЇЎз§PЯt|iТ@;xН`[ ” ћkРМтЬ(;ч–ѕ—ќїdЦТйoeУЫ3ьн@ЪJЫвцЅYUњXшЁэ‡€АŒ5ЦŒe|ЊЈWв€nѕ7ЙMzш!гIЉhQMeрпv‚РгQcwmкOœћТXћ5e|Цъ иЮŒз2 ЪыsrЫQЯ7ЫЉ‚дS7nкd(jЫnЧšЦй.Ћ'Ж<Š^А­јc/аЋЫ єLœDс€ЦB БЩррЯд(З$Z]рп™ЬЃ™АоjKjІЩєSŸЧBЇН<ЭJgщ›KСurжњ,№ѕ“Sœлш"Uд+iь+ГІGL‡ :)гIЉhQVЭРh[G^=W—WЧфжмŒnх… !q т2R3ЂУ8}xїQCЦ уо N=Ыfн–дS7=qњŽѕ™0wя’ч­Ќžиv№(vЊ./ч‘z.ъxЩљ‹зю&ђїdЎЗbцѕг,Ъ&%’ъфg [йЖу5 |€ |ޘž Е:д6JЖˆlйлюїСL{сђ•Ци[ЇцЃЖл-˜ }Šy` јqМќж?дФSQŠД`aГpbЋНtЫ™~(ЪV2m+ш‡yYь-б<яэLз0"а˜џьќФ•žюД-€e+™ы­pdзЖž!l­G(.йqЪЃ5њlсОњNаgУ†!ˆ€—P”­dкV^‚ЋEŸF@QЖЂЋи}l"€ј*О8oXyдwЈчюџ­<pЎЎВЂВK—/9—s!m‡#pfяч+Эl?8”ћB€ŠВ•мw‚žёъ"ƒ4!ІФ_ ЊЫ$?*RЂX"рМОю’rlek#œЙp@ЪДГ[Н[|‡7 б:{Ъ}8,БаЬ‡[ŒMC<Š€gm+А&,`лќѕљvи є]ї …№ОЈl€Dhsx–­88ш'~уКяPл љ‘ „ю=Aгж#јŠй˜Г1шAnŠуGG<Я}PёmEr\ђСгс{wјˆєќ?Я“џ‘AOJy+йж’vрАQД_(D”GРѓяС[БэйjG]іjП†’KWГ>ЩЁп^‰њc>fјЅsм<7|зО)yѕ^ƒ0%6eъЌЉ_\)шнЗGжъ,ЉъкУFЉЎЁPЯлV„фoЬіjBВШиPЈa№ Њb №ёѕбТK{SбТЉ+ЋQЁаН'јcЬ8A]шаИQqр'{ШШ!хпж+V3ъE'рУњ’S%ЯNyšДћГн S‘ИфйS~7ХКMёЖхАёюн…:Нйдvќ‹ј А;!yLЫNsѓЧє§ №кB‡њЕтІІбi Јв†ƒDњАb(ЁЂаН'ѕЧиœj)y@ј€ЭK6ƒАшpбђ­Ып›лрЪй+)›S@XvБlлšm__њШpЅQ‡ЛџВ;{cЖњъo,ћ}Їяѓв–ЯпЂŽи@щп™›а`%ц­l=ˆ +tнwЈА4ћaQŒрPДЧ=Nу(fзц]g?= ъh4uжтyЋНёфр„‰Ѓz’ЊТG6ћXЕаО ХЇ"mYс†Q/"рqЖrВoМяP;љдv|‡кЩg•D§1‚3№lЭm˜КewjЗ—зАQУЖЎJIL€№иЈБ›—ЌšKѓšLDХqЉ`К=kƒфЄ(ƒУЦ™žєknЖІф9мМ‚ЁSЇЕђjЗ­зV"Џ$дBмŠ€gй жUП-ђ9Ш[щXdЎљmЅ|AВ”?Ц!#†dЌЪ9q$шŽ?rУ’ CžBѓ-ЯXОyХfB‚]Ц9}_ЄTгз6ўПdяЎ бQЁlН9=ЃyПŒЛw—ЛСzAЏВЩŽіЏˆ€ћ№,[СЂ*сК*ЙkйЁ›?[іоЮn€JУєza‰дЄ БДт%|€Я „E9‹—@ шс оa#,PрУ6*ьрЈƒМ2ПW_21nœМІЏЖЄ дi~н››Y?АзzslJXШSОvз:l{<ЫVVАЪїС€ОC­ s=JM$ОЪA“_шџфгйџОХѕ“ Ў~5WР"рk(ЪVђm+єъіEдDвuW}ѓ5ЗЕ/п|л QМ"О†€Ђl%гЖBпЁŠ=%њѓCj)a=є НХkŠ5 +BЄ№ќZvAЭ`[ bє>‡џz9ѓЭˆћz0pffDк6ШhфшЬVŽD@yDlЋ~ юоe;ubм~эї,”yЦ%ЗГ2__чў'Atо*eiёюї&ќпЭ…єршQ–•‚ЪЗМ}іт™y*":(b№8"ћ оН?~Oд|ќЃЯ:щdЮ•Мžш‹GЫ|}Лb™;kЊъдЉгнЛw‘tм +–хaрŸэ„˜щ|%"#AQTщ4Uɘ—яmX‹[B…"а в ':уŠ}$3я@mЩПМЂН—kОкЯTgRCр†щгџъ‰ЙЗLњ}LгW/YAоdaНцо–ciˆ€gh1Шa+Б­ ћ }“ƒгQ:›ыр#Ч_“‚цё€/е~jЦв-ЖAMю% 1ѕ$URњPŽ„еozћшВ[љˆmeЧя(ь2!‰ОŸњ7]SйŒ+ˆБмz`ЊHч’,Ў}& aЕЯћко{%ТV>b[qШKјoАwSLпзqщц•ЅПЈ‹яѓ™сLнџ8ЦКeъ тЪџѕјw} Ї*v,J[”‹'Ыn7ІŸЫЮ ZtŒжrМŸбqю š†odХВА5kЙOm`)гёЪў”tЂоРщЈкт”“\Б=UT”чЯkЎд;Аƒ+r"lх#ЖзУŸюfЎjЮGЭџHk‚ЬРYuD­n€9,n0и[­&~ІЎ,Аћ8Й’зclыЊкДaФ'W„ОXЉv‰,DВЭE% CИЏь[у‹3њenMќTгcИBш1рQmŸGГ)A-Рk…Ee/Э:Љяэp –Іђ\њ‹„х|˜YqDиЪ‡l+Ч§Ž‚щЄeц„м&ЬНф7Аьџд%џ6YмцЉЛњБІLoТ1šэ‘8лТ,1щxуt _}&оVMTВ"Еб“С–w.[E>,T[АЄбдтЪЗдВxсIZЫт…ЧЧжт‘Yvac мDX‹­фE|Г7"lхCЖї;Jп Џ<В7aшg ‚…ХYj­šРЉБМ%|шDУН$$х?ЊЋMDвS`O ш|sЭсшžŽ~#mDџP,ЇЄ‡І›Њ1dљC‰‰J‚ЌjЙйт3Нj§"aFЗ‡aэ_ІЇыт+Т"рй;Г…њ"lх;Ж•›аu[Т+пЅ‡яуШј*7ЙЎ†ЁСtыGЃAz\Ќ3i$к{е,XU№ЦPтЈЈ2i‚ћhЫЏs bчКр _Ѕи S]“_(ЂšPњлавЏJ;`ЧБЫоE@„­|щ ЛРaў§џТ)ПИƒЪВЖG„>Ќ3›Щй}lLсў’УOљХњˆ&?{хтD;в–мав Жђ‘y+яорІіDO@+ž~$ sчžA}†6=vКFУ-дpхpЮТBŽsѓŽœWђ }3ˆWo!рі‡˜ЅєbщЧŸX•ЖŠeйЉSІжшkм^ ˆДŠ@уП­ъй(ˆЬВ_Л›hЃ†EШ]ŸыоYv[s&;+ЛКђцŠ5kЁcVЉ|)KS`ІгєЃ)rRфŠ”–šѕyMXˆЛeы–Уy‡IƒiўМФЩ/ФBБ5U56mјќЬч№!д '­{}Xs…‡’7ЭВЗnйwф0д2њйбЉЫSagY^эњ №wпN­fйEl+;™]Lђ–_voеы"\Э>aв„SЇNЕZEЩљ’МПхR\їŸК-Y[ЄєсЉКњнеМмМ?‡ЪЬШ”Њхэ сП[2ћЅ([ЩмѓFfгхЋЙНо‚Ьу;RvШo€­fxїp[Ё’’юнoџXлj)‹SР ‚EљERњGŽYЙtЅ&@ЃђWЭOjќfшo‡џ:0Ь1Юš“(EŽћсjМŒ*ёЯ‰…Jе‚ђv†€Ѓ„%2Ыю9Dфя'шо6ИН^цї6а ЅеджtыаjХн{vЇ:нЛwП­Џ”вЏдW‚‚Ujiiщ[oПѕѕз_џєпŸИ$‰gэі•уЦŽkЮ+ЁжЌ€Ёі‚o_ЫьЂ†лmЉN–• §Ž‚И…+Ќюto•Н_L?+‰T4}PzнІЅ”ZЪјтЗ›o™bлБi‡–xќ›СќcљУ‡ Їuwі#fжLg‹ŒFюЛ"ў€Й'JX555нtНxЙU —Ў(№дFS“%/XМ`фа‘`[™ыЭƒ† ВЪEЃPlёƒ`[‰ІЂАН"р(UŠВ•лmЉiЧяЈЖ‚вЮ–*В…мp‚eяxфkЪу‡ .|~сщ'žnQŸћ"РJххХц}№щžœ=Др>П нЛяє˜щl=Kg—ј ašG@ЗЮAA3ХL‹I{= ƒ`яЎь] сЃрВцѕЕЏ?9lœ€(8Ўyђщ'…юk„иR‡ ВќЕхрЄАЙ !2pŽАe+љvŠŒў: тJНхU7ЙG†ЯЁыЪ oЬ6О1УИю%§С,ЂiJВгюœЭ9рC9їЫ\;:N'xrD]MьC%”–”ТwŽ сKƒНKaЧРМ‹сМU} Ђрpќ3уs57&їpюф‰уAŽ;ђИaРiœ ,EйJОт4Ђ]ЉзМ~*І A]aЯиEFХТ)к$QсЇG чЌL‚ЭћDS]ЦПП;g7”ѓю{яЦЯjtA‹-њ ˆп:v„(ШЇќqЪўћ=6§‡іO™rм‚†Wp”Аe+‡ьfwЅ^šWъ*Ќ…3Ѕ*NЛW8~TўP ^БЯ'7ЧјёуЏ\ўђј'Чo”}=ўйёТl솈6[ТЖ4„ЧŽњC`вѓѕ4Z–УEщЧ СgЫJВеоM;я)4§h ŸžВ.мзбY*zх-Ќ‚ћ3їпЎЊьгЏявŒД ‡ƒš*СПˆ" ‚€ЂГьŠО›ћ™лSkPUPк† „ЙžЂT$u}§ѕ++ЏdљŸ… р|н$С†{3ї^Нx%чГœ‚+ УlпШy8І WžЊ@XrІ$+/Ћ ьгa‘Ѓж/YoнŒ#ˆ@KкЏmEHўЦ|ag'$‹Œ … ЖajIQyО†­7Ъ=DьSt (у@†І;ЗЈ}NЪœИQq‰ЋmKIJZŠJУэ‘3eі”ЌѕYЂ:(DEйJБy+Kїи Щcј~R \i„з–:м№Xj щH?”џС‡E&kŸ­*Ы+Ѓ†D5—) 0Ѕ*аTЉTЎŒ[›ыТ"аЎў1y лJЮ[бВl;Aл МкъOq$e™ЎтЭЋ§d ГеЕ–єКПWVQЕ­Ќг0Ž .  ([)k[9‰JЬ…є‘CУШЌцьllХMЊ;zьТ”`j€˜ЉYCŠz1jУт Ik’РaqХЭŠн[vЇfЄBz@ЗЮњ›z]oК]Дƒˆ@;D@QЖRЬЖ‚uUХoло.л …’’эdИі{XфмсЯhКЈ-уG4 sЋђ(Рёˆ_+NV$њeЮѓgв I№ВЏgПОёI[ЫФО2kzФєŸўћ“pЂ]X5]oХЇ:ЈЈЈШЪЬ8uцK“ЉЖOПPиLPИC—гХbFD@1аwЈ5дsЧЮэq_`*ЋƒСPuЋjї‰н _іТ2иo[ё6+wEню;|ЈЯˆ2я•љ#žŠајkЪО-л““Еv§›юj0–ƒx+пЁэгЖВЮ!›nл­s‰…йv уЪЊnпˆflЫˆŸ3ќЄЩД9!‡4SьвМсѕOŠ iєИШ)+шv8АяCЪвx\`сXфЄFљKГ^њу „-ph9№žtFм”cG?†5eОбQlE{F §ЎЗм5˜/ФмМq§FUU• RЊˆSЇNёcUЇэ.ЭМBЩљ’МПхR л8oЩкђЙГчОѓю;МТіьэ1q HU< №(ŠВ•C6ŽЛэіzѓОЪ+ўNd^ЬmvoQІлЕR[@‹ювLkчwo†@Q~сsХЎŒіO…0Œ.O8ХЭгс(€€ЂlхvG&@оЊWfѓPSw €E+нЅ™jкюо ђџ4їLЮМтF—ГтU ŽEqEЁћP”­мnуШФУ[ѕЪlžjУ‡Ї‘m]Н,Л4SyMM ьУЬыpћ›ZЁ|DјЕZ уЧ .LnšуГ`№ŠВ•ЗlWъ•ŸЗЂ‚„5|Ьн,„O4Бœ™я}уЏоsїБ•’“ц&э|oKсБBsНжЭ—]-[Оt!Э#ЕK3ЄђЛ7C`м„q|/&̘Е-kомyVлгѓ @<ОlUљvYо~fхнЮї*"ŸQ%Хia–н/ГГ_е/O$aOДR—ч’aL—Е#'#3#}ѓ“щЇGћ…О˜0—Vл2У;AиЂЂ‘у"…Л44pт&rяЧGЮŸгМ{3уЧєэгwќГу=з`,АE@QЖ;EўпЖ­NK\ЉW~о@*ј~†щТЭу aиzЂыЩ^Ў &?вѓ нкL}žїи šєц&БV~dХђpкТ Ї­ќXбБ—_FУЪ”xEG‚^Ё*€Я•zЪЫј5N9ыыЩG С#Fщ‡=bd4ŒZkНмдЃїеs…оИ\МS. IDATyCj=„чъХ’Д­ZyфлVеЕцъ;fњ5ѕпЏ“џ!™9ь•rјDPЃж“>-lѓ,эм+#=ЃЭї;аP”­ВSмІ+ѕЪЯ[№/у—DwлBJЗъйЎ}ДWŒ бЕЙёЯђЫ†і;Og,Ыј$я“Yё‚ЊэчёXjщWЅЖe‹ mеP‚xEG‚`ЇxЂ­–щJНхU7ЙD†ЯЁыЪ oЬ6О1УИю%§С,ЂiJВгкœЭ9рC9їЫ\;:˜„tXаЖjхжЫЗ­ˆŸŠщТYRptе’Кkf•ЪБбпЇG 3ђЖK-:oЅЁ˜ŒДwаЖjхSлJък2Г™R'”№коRп:VљC-xХВ–b@, mеЪƒ@m+ЉЋ0sюvехoѕ3‡rВЇBєЯ>ь˜aЙzщєUz$,!ЊFxаЖтЁp5 бƒио\9#cУB.pд”ёYЋ3Є>шsИ8Ь€Д/e+ц€мŠВ2ѕ–]%сOс<љ9зzћQбўХ-ˆcКhЃћЃWQxPибP”­zПцЦ;ЃLН/Э3’_‘о!KS9oіЃЂНƒЭo’пL..oKОhD;‚BDР(ЪVЪи8Ж0)Vo€–ќЊЙ~ћбf=AhЧšfЃY Р "€4" ([)cуио[eъ=А[S[ZQ{ЎlЬЬhƒ§Јm#Љ$08pЪ№)RЉ(G:2јNаmw?(ˆ|ўЗE3!zјп~дЂ&r‰Œ‹„v‘IC"аБ@лЊcпь="аvP”­›?ВТп[ѕZ5УЛQиOpљт…OŽ|rШраiБгNўуЄ§іРЬі0PEйJ™љ#[НUЏmKМ%ŸХsfЦ >4Џ яЬщвUЫW}єё1o5ыEœC@QЖђ–уіz 2яHй!Š8ьД,*їЎпOћбїДВЁh”ПZЅzЗX{G@QЖђ–уіz™{киccg?AбžPЯ0pE1Ђј а+ДЯw‚eEe—._zцТˆш? dЗМ@єшгOTn+L”^wЇЮVюГ;ћ њl›Бaˆ€ŠВи8n”Yѕ‡FЊ&,`›”П>п[ўРйЖ™D$†,{Чс–E RJDїдаJеŠѕ nE@б‘ 2TеˆјlБ=хawьЈ?œМnYŽ?R!јЬcйжиЊd.п8цЁ1pf.ЯtЮ‡ пvіььGЬlуъyќ кEœ1ЛGP”­м>dšŸ Б=эehLž Jл”0”Є !$ЎўњњыWV^Щђ? QpОnjЭƒеŽM;nUrПШ…ѓVх-ˆЪЈмS*vіьѓлаНћїakпиШЗ  [gXєРG1€xEG‚ŠкV„фoЬт;!Ydl(TА IёТ} [o8”{ˆШ+цгCG нИСWвšЄЄЈйГ–zЭлК§WЅЎ‚sGfFЗћ{Э›Ÿ_аZB|bєдшŸўћNДѓЯМ‹€ЂlЅиМ•SvB2ЗЃЇррЦnД ТЋ@ NzОўXj РЬ+NJHёCљ|Xd2Б2йЊR_Ћ jt іР/(-Ч[WЉ§CBB<РЗj|гfёБ3bсфх@МŽ€ЂlЅЄmEwЪВХ—ЖAxЕеТтHЪТSМyЕŸЌ aЖК’Юh…žx…ЈЄ*& ˆ€ e+em+НS‰Й>rh кии:‹›T?vєи…);!“Љb&БмЭ2pšБ:#egІeМ–бц4 !ˆ€у(ЪVŠйVАЎЊјmŸv ЗQЩv2\ћ=ЌN`шсЯhКЈ-уG4 “х Ч#~ul+dEРhFjFtчttдhˆкЏSDР>ŠВ•bЖ,ЊЎЋ’YяЕ§зЌЙcчТЪO ++р C]]нЕŠВ•|;Х~ЃMuЅ^‡ђ2~UСЁЏ']0?hŒЅіˆ‘б0j­ѕrSЊ‰WD‰€Ђl%пN‘йz™jЎд+?ou­ЙњŽ™~M§їыфЪHfћъђХuк˜ тkпevеDч­ZyфлVџ2~ItЗ-ЄtЋžэкG{ХШЊКёЯђЫ†і+ƒЇ3–e|’їЩЌxСGеіѓШKЭо™Mс‹ЂрћƒУžS1f М”Ÿ SеO  (["џЧяЦоКRЏCyеMю‘ІЎмЕŒѓ ЌRБф%YНЩйœ>”sПЬ-~Gф“lYEH+-_КrќьПЮFŒŽ`%>u”*Cз]ЇЏбKЅЂ№4ŠВ•WЈ tЅ^ђњЉ˜.œ%GW-ЉЛfцxЪ‘угЃwЃАхŸgЪ5ƒоЗ№ЉБЪxтє §@@ЌN<ђЩ‘др‚­RЯ~qТPo`mџ§С]5ЭжЎ_ эт-Ќвsч.•]ѓССС#ТGР6…x Eч­Z—Ю[I][f6SЊт„­ymo™Б1ўEСЫЈh’л…р"ЂрУ‚АаА…Џ,œџЪЂРћ/—\fќИWХ/6rс+Ы^J0Z-e(АЮр tJKJЋk 3ОКˆЏДєЭыіvbˆ€Ђlх€Т7аWъЅyЅЎТжхnW=Ђпє:'{*DџrЌc†фтмVyvЈЛEœќзI˜К‚ъ&Ož ›6Y#[Я\~у№Ш)яшkѕЌ™<Д…бж5аЎ•]ƒБЄц—у`ЌA”ц…ьx B@QѓнЁ9 7vX™za7bP#CxЬaЊ‚ў‚бЌеISмиwО(:Ž&‚[ФИАў`_ŒТТBC­ŸРƒ є†._Н (‡ ‡ю|!|цзВї4ЮмS!ЭЫ+`p;ŠВ•+6Ž+=WІоВЋфЅyFhчњ4Эˆpb?*кЮншВŒшўбГўфцw‚PeЇѕТ\;иD'ўQ[U–WF ‰j.S`JU Щy†’АдšЫС"асў1y%ч­шNYЖ m^mu€Ї8’ВLWёце~В‚4~іk›ЃYвыў^YEYдЖj–::YtвuдE: ŠВ•ВЖ•“З0цBњШЁaDрmяuмЄњБЃЧ.Lй хšИнbLЂDНЕaё†Є5IрaНтfХю-ЛS3RA3 [g§MНЎ7чдмЮ‘ћ^ю‘mGЂžXgvД1 шH(ЪVŠйVАЎЊјmŸv ЗsKЖ“скяauLs‡?ЃщЂbќЕŒб0Ь­Ъ[ Ч#~uЌ8Y‘ш—ЃA!щ…$xйзГ_пјЄxZcь+ГІGLџщП? 'кi’№šБ$Cѕn8єЗЁЅ_•zЗ X;"Р# ([)f[СЂ*сК*™ѕ^лЯЙЃ›;v.ЌќІт1ЂƒСPWWw-гYіТ2"Нх,a VB+ЮтЃ4c„y1Œ €€ЂlЅ˜meukЊwллЌВлFM,ЬЖKWЖк> +‰k… шмЙgPŸa#†MЮћсsКh|9 ftіЛоJиV‚˜‚7ЎпЈЊЊrCA cКв‹ЅvbUк*Xк:uЪTX“Ё`§X"р*ŠВ•C6ŽЋ=фw{Нy_х'2/&ЈгGƒА3ьНМhс"˜ШпОЅyŽ,{ы–'Ÿ~rШр!Ы_[{кЖоVкkpm4м,ylеl‹B "рŠВ•лm™}іVН2›чЕ “&œ:uŠVНogvЩ7WѓrѓNœ<ЁіSgfdZ5ITNРs&[гLМЈšUQEœF@QЖrЛ#ГлоЊWfѓМЂж= ћэkiећIYœл‚х•јчФТ ­šдЊ‚ЬrЌŠХ("рŠЮВЫ|7чPф(ЛRЏќМdкŸЬ)IЊШgHјX3Й—tЖ4.rЂjЪxЂы.ЇЅЪщдджtы@ыЛ§CхИБуšыЖy(ZUYNsBGРцСtМљ9МeуИRЏќМyћ™•st;пЋˆ|F•Є…Zt?МЬЮ~UП<‘„=!*kцЫ>l8­І›ЎWёƒ`[IекЊ‚ЬrЄЪG9" EG‚оš?rЅ^љyuЊрћІ їЁђ€Fз…„<РВ~ЌЩє|BЗжz.HЮнqПЬ —••mЩH?rєШь?%б bІХЄНžVSUŸ+VмЈ€‰vЋŠЅ`>lзЬ+KЉё @\AmЋVа“o[AAŒGUpшыЩщ †дп›uВ†ц НN­…хІмgео:И7w~ЄsчЮ},ы­:ШЏЗŠ ­š1kЦэšЪ>}њО˜№ВU#ЅтЃЇFУ}:б.ЅfUFчP”­фЯ9зЉ\Ўд+?ou­ЙњŽ™~M§їыфЦHf{œ€hдZb2x“ЊјзvRбPЎ*s‰*и m%Т1ŒИ‚€Ђ#A‡ьWze•з•zхч-ј—ёгфЖ…”nеГ]ћhЏuDЇS3фЦ?Ыs,Z5Ь* Oo\ИqL_+G7VZE:(ŠВ•ќ9 їо Wъu(ЏКЩ%2|]WnxcЖёЦu/щfMS’ЎхlЮЪЙ_тG‚v@ТЄŽ‹€Ђ#AљvŠ{oˆ+ѕ:зOХt!j Ђ]ЕЄюšYЅrlєїщбТŒМэќt’{AРвЖŽкV­мAj[I][f6SЊт„Nљ­ќЁМbЕ,cˆ"аˆкV­< дЖ’К 3чnW]ўV?s('{*DџьУŽVЋ—.@_ЅGТЂŠaD€Gm+ W 1ˆ щЭ•3т16ЬтЃХЁBGMŸЕ:Уh4:” •‚€ЂlхР[сWІоВЋ$ќi#œ'?чZo?*кПИqLmtЮћ(ˆ"`…@ЇъђцmŸ‹:^rўтЕЛт;JYхt" Г?Ъ‡Uл”ЉxŠќ:ˆј1фfйчŸiьG­ZhпЁ ё B!юе,DУэсFПй;ГbІѓХy+ 7ДАžдоl,Ъ~TДОkvФНg›$М…ЖЉ(A:ŠŽщ›5хaUІоЛ5ЕЅЕчЪЦЬ >кJ8eјЉT”#Д­мvїƒ‚ -Хщсj?*Ukd\$œИ‹„>(яШ mе‘я>іhK(ЪV^™b‡Лс­zлвƒ€mE|EйJ™љ#[ЬНUЏmKP‚ N#€ѓV"аmœГCDк$JЮь:п$tњoxїp~ыSЇ СŒˆ@G@@QЖЧ+ƒ2‡ъЊЪЮкdчо'ЬYь^ТЂuЙH[ћўzИКђ{иzЫNЫлVRiIiђ’фЪ*…nЖкVАЕюE@QЖђ U^NдkLщ bяNяЯјуюнЛ|X4ЄCхрјwЃТ“ж%ЩєЉрЂ…Хм#кœ6,|ыЭѕЫ^[6"|Dю6н­(ЪVй8nьІыѕžепеЈЮŠe”wŒЗYkГ2’3RГRedW |5P<СFš>(НюNИQnŽG>5rkцVЁнbЖДZNЋ ТVёсЏЏ]ёRРSЗ‚‡6Ž[ZчDНћўpvЌ/ыeO9qhКi’R“"й˜ЗdЎмXpфˆFFE&ЎNДТОy$ивлЬРйВ*7œ`й;іМ>hЕкУ‡Ož є“щ'+ˆ| Qиo"€яХб§[ЇЩЙм02ЄгШрNaКN§Д‚™ЃBёœв›vмЊ4ф~‘ ч­Ъ[•P${3E’Žѕ‡“ЯR–уЯŸTNGYж[Ѕ.IнПwПp‹О4июџ‡‰€§oЈЮёŽгH@.Ь( ƒ UxЌ№ЙqЯ :mъДŠe BzЅЊo[е9ќзУЯ=ѓ\шcЛеCš іуYјъТ!У† rИUЩТшщ/OЬ9xтфљЇ#ž^•К ’ш`ЎќЈSД:ZHЩW%АOщХFe>зœWцЬŒ›yцФ™џ8ёpпог7R}јъѕъwWѓrѓ>ў№Duu5к)Ÿ*рЕ" ([Сќ‘W`ЂѕJ]E›#СУб7СH№xЙ$Y`Lgєh0v’жЇађ+ѕЕК FП рoм„Šж B;I $EOзшkєUх‡оЯ‘*ЪJ:0tиаaй;ЗXЩE7Ž2|Шщ/K@ГрЃ5ЃІцUЩ—%C† БЪ.Œ‚GwЈŸ3§ыЏJ…I|XД:ššќчdб—;ќ7h< sgЭIJuЧ‘&ЃЎ/" ЈЇc_РІMоњђFи+OЧ0гдуОРTB †Њ[U0 a`ŸКККћXщ`hЛxггБ[цœ€оЁzс@јаN-žјHаNut`wыdbaЖ]ЖqeП>LE|EG‚NЬЙ4GыUž\яцы7­\‡K№eeЧ+XxЋ^%;ћЯўqц‹3Jжˆu! # ([9jуИ oеыЎіc9ˆ"(ЪVоВqМU/>aˆ"рFpоЪLћŽCЉv[œиВю'ЦЖ†€Ђl6ŽWeŽжлЊяаЖv—БНˆ@{@@QЖђ UС]rЂоВ…->фouШ›­,j‡я™G>7rню ;ўaѓтOBrЗчfЌЪHZ•=;t •зЄЄW“Ќ$EœЗ’|њm&VЇЄjЫ­–)Ш)h)k;ВыHЪ)pЅR 2zB”ДШ€DPx–н Ч-їШЙzя–Dн=љ4ћбPіЏйСьлїЩlLвК”#йG*nŠ/з8ћЯГ]Лv… ™Лvя a™eЂ"€ m%љ txЄгˆЯ˜gO3/”0ёхЬ+џ–Tm™~l^А~оz[Пw xьНcЯ'pп ??уyЗЬŠ1DD@QЖrЮЦ‘lЛьчъН[їJднscЏ- є”]!щ?Јџу#пћ–ЕЯb№lѕѕ—_GLА|'ŠВ•6ާжЫLuЂ^Їm+с*Pк<~ЅшЖЖй68ьїapRЙm^ЁОг›нC!Р нЋ™Ж<>:y‰јО5ТОаА‹tŠ–гљ— ”В4œ8лжт„ќ&яШЮ,*ў6ЄPџ2рwC~7uЪдСƒл) ™з8юJRt–н Ч-§tЂ^ё‰ni[ qt‹CКWГ[ЊЖ-„nќ—WPЌі#iЏЇй*xHBы=qќФа'†.I^тЎZ,Y;ЩюйБчЬХвМ‚МIЯ<Л{ЛШП4юЊЫ‘‰кV"@йї*’A‘‹›нУNSЇM 5@`sу}G›~4~vtъђTииіdЮx+#ш&Fни IDATЮZЭС/;`Џfј*шoyœoeлЖ\М$udФШЦЄђњ†з?)т–ѕЙ"e…еЫ„f{Ж\оКхpоaв`š?/qђ Б/Эzщ/ќ1btуtьœ8#nЪБЃѓ;€ kalLlц– l.гЂaЅЙl;+, ТчџubѓЩЭtwшдˆбpђ:ЖйЁHЅW FО и" ([9aуиЖи ‰CѕњЌб- Ах`?iКW3ч7Йхmч77†-*`/œЬŒЬE)‹ш^ЭРVtЏц‘OŽ„_oЋ{5 [TїŸКМ‹AИlХ2ˆЮOjмшAЈa~Ыe№=C0Ь=wн†u<[mЯо— JU  Змƒ{}Дy‡DЋђ…QбЮ  LєšBЃ5‰uЛPУ S•§aшJ…Fфœ'zќџіY‡ХfŸНћРљ>я~ЮsxзЛпѕЎw§і>/k­Ніћ~kMЄŒŒЪHЁЬћЂ $I›”Ы)ЗЄМДѕ%Ь?љф“Е+ж*ЊШ‹№‰ыžп<}кфCoНsY`6™™kУXO.ЦhG39c™oсS ЧІXГC;ZнжтєЗЮ=5ЦqД]„н2wЯЫЗ…оЙСRdќ>cэєŠHvЏ'!ЋЂ]ЗхjNЛ+-wc.\dTFQa /ЊІ\Цй‡3оўвіyЯS,ёŠœ0„nJƒЇ17їьн‡…хЖ Яoрœа“ЩyоœGЪ•ТlдТџ–m[ЎПбК}AЋК"5oŽ'"@c+%˜pRНnХєШJМb&hPцBUvФNй=Йš‘<Я'LœKвгвy.e[УTS.CL ‡Ц tч$л*Жœ)˜В9oѓЪх+ёйЙ%oррШysf)RО†Љ'“ѓcO<љкОзž[НіЬOg0ю3vЬцM›Y‹ZељЈmЭ#Nџ \ЭJ 1€bоъ’ћЅ№Ёї*ŸИЭŸћмќэ(Ћu•ёК2#Бeяй<™ѓ$оПщ:ЉїЏ"W3лЫЎК;cЋЈ`[.|q/{Џp<Е№Љ;яИ“?ьUžќ EЎfЗЮ=ѕlЎэТUeݘ={ЦдЫg]Ž; _>G.ЙDђ_‚Щў=Ст,њн˜›жЯЕ.9лЏЂчЌ!ї">3в–~РUљыQ\\|њыгфЊќѕњіЁ_n :К~д‡ўЈVqЈнA€Ћzњ‘ЌA†а]ѕ/_3Y*b„5sЦLUхZLqk‘CР­оЪSc+б•Ж]т•|@`J(\њУiSѕ–њœЁœС}™SўcЪ›ЏНѕр‚C:-i>ЁƒBQd&-yaЩпоўлэзо>wђм„1 ŒIп„! Š€[Wйz6ЇjЎ˜l;оТE[xy пlѕъЗS…§ 17ДП™@О#uуo‰g!Cх.ТGaд№(y@бєщ *„GР­оЪ'ЦVlнŠљ)РФ–Ў@`иE;0Жт@A§DР­оЪ'ЦVѓЗЯaЃ'И-щёf‚f_Оlўм…BИHћЕ›~^ ЊNvpЋЗђ‰БРђШKЫv." ржUvz&H7!@xnѕVО2ЖђЖ‹Dі„pыLа'ж­М№ЖАŸЈ™h/*.о‚ІW ˜ј_б­оJџиJќр №?ЫzР}їгІ;4пю!ЉЃ ~ Ѓ†‡Ez шaћЈyBРѕИе[щ[сe”џYf˜ГIМa,CРєEMлжLёШ&[@LkJ…‡ЛГеУ8оьХъŸВОЈЈ0>і…оУB`шсв\ЭН*Яп›ЈЧHƒФАŸePtD18т2”ŠYTР]ы­ъKъOжœ”ƒћб'Ё8"~DlZЌœ/ЇХёСCФсб‚ЙŽёХ(ƒАЁH 6№8xlЫSыK‹…чRMлЌbr% Пhќяœџ>ўсqаЃЦŒzlйcQУzёkŠН …ZEЗљИИ?)MЈ[ фh•YЎцŒŒ -ў№{UОwпоЫVь}ѕeц­ИcВ?ƒcbRКР‚ƒHХМoџОўЩы"ЭЕ‘з"3^ЎТы™5U•HХl?q<ЏK„p­З‚ЋК{ЩнЖн;Вўˆoyѓ—еЭ ”љукdŠфДŒнMт-тљїЬЯZžЙтХртe=wМЕƒЧBшѕъbѕTсќ9s{‡аfЮŸк/4ќПtšяв\Эі•WUT]yх•p”oztтhkF–#Ў!Ѕb払‹Йў™ vWZ>Gжa„єнлЕnOдК­Qkь~ Аn—–Ін/ьžљŸ3SяMЧНŽwчэцђwœ|Уф C'lXМ›ФCSAlЯЦ’@є„ейЋyђKHю\/ё'џvТСWЄ˜yЌ ОyнЪџЋ|шЖ‡&Dп2}єєвRўNg—$^’ђžxg…x_Е8ЛAќOНЎ –Ћ™w–[Хѓ—•—…… W3NБ\Э XЎfd‘­•ЋйŽrдк`џŒщ3@ќЧє A8tќќнЛMХ,я‹Ђ9–ŠЙЖЖV'lˆ‡o>$T(ЄЂ{pНЗњEи’гіћgnкZ…ѓплћ@ ]zЭXѕ@vп SЄl+ќ@ёУї>фХъЊ_/{§`хСжя[wnоЩљŒиГeЯЉŸНўоыEŸ!нљŽ RP={ЖьќњѓЏС?№qQы7RыlђШbZYD„ЕѓжЮ^<ћшWфцU\ݘNљОи0ћтgS/Vн… ћ8ЄжЅЙšЕ”ух№O~ЬђжЄо9 4{]\х˜'тCЉ˜ѕ`2Ў 2lАfIbФн‹Tц† ЌЭэ­СІVkф'љ96.ƒе ‚L‚*?)ЇЯ4ŸaБ:9E0y1{Ev`ž {<5waЎфб:ЅXhgЇвfd ј'B}BчЮ5же.doўКл…AИёыFы№gЎВПФшm­wэН8ћаХeя_мZ}ёрщ‹eg.V6kЎмйiЙšПћё;.€ќУ 7&Ьš3+yДё™gГЧ§~;5vtвйцІддTSяL ЏЅEШ•ПКпє{Ї+$ЇLў?љЏ*˜Н‘Šy_С>фa~ЏєНБ7šўрєбЩ ЖЕДњ"—D*цCяќurњdЬOg=8Ыd2ЩS1ЋBСR1ѓ-`rmDЛ зцjЖнoХ:жЫ~Ћyq†Х{Фу‡L?žfQ[Кgвrг"ўц*гЈџhЫ} ћ­№ќ.;'ўЋУд1~ђxiuЩЂ|ЖjŽ6ОxАpOсйo›ЎŽ:;{vJZŠдАєLpKёЧ„ЮŽЬEsв‘ЖY@rчŸv^јщЋ[^RўrюЫ_~љхап]Ањ‰ј[zџ…Kše‡jЎf–{U&e%‘4Ь_s5лv–8…€"WsзzŒk0РІ*љО*Н{йaЬ/fi#(|#ђƒбьћRЌ~…@ŒŸД%АtнюuЖ|p˜[™іЈrKW—+”*M{b>ЪъAТœчцу#ч+$сзЌЎM.дoZ*У~7E oDРЕоJбc§я šF‹Ц[Х! B'пОоSYh0b=Й§*еŸЊяЮFг/MЮЏl?МВѓл#„€ї!рVoЅle~6Ѓ&wѕнЌ;ГцЏш1hъЏF'е№ј NB‘дј<nѕV:ЧVZыPЎћhCgˆЎnŽє„€CИя™ ЬТиЪ!уH˜ Ž€[Н•ЮБ7ŽB€ 8nѕV4ЖтИAŽ"рыVшƒЋc‡: Щ„€ЧpЋЗвћLаsБC{НђэЃН ;Q ЊЊЪ‰кH!рЕи ‹шZoeЛ—нmБCёfЬыкёю[т§фА__6ђїЃІ<<=ўцј~^$ОгНŸz­nч:ЊŠф EРЕоЪƒБCW=БъЊП І2AŠfћAЭЋ›_нќЦfНNd6!@Иж[IјВ/ˆГўˆjдcеk€иЁвцPљk7Жr—‚%6>›i{œуя—еП к`0(о†A\а‚нХџъИeЪ-‹з-FшKˆa–ЗјљьН/х75œ ;№с`ƒФЧan3п;ц^pnvЛux…7ю,о[Œg.š3ЭђТ $U5#šш‹Ћ^ќіЋ/^9ћЩйЉїJя гA!рњg‚№8ьЛфД}3ћ;єњ›ѓхжŸЈ7cЌчЁRе'Om?і:ќ^u>ђ†5ˆ ј 'н7‰;/plƒˆZ˜ъG]MвAЎїVRО#,j('zБCХимnR~кЅЯТ”О[Э–wŸUЕ=џЪѓWE^ЕnСКєиєщ‰гwЎй‚ё“D\аьœgЈC*Ф=vфзН41'gN.мYhv …Џо=ЛGШSЭ^“Э”№ ЂZš]M”[N!рїИ~&(x&v(<б чрƒKˆhS‡wэ_ѕФ3ыіJыVZqAqŠЧК6jШuCЪп)Чп7%нЄЊDTKГ‹Ђ‰њ§нI$фИм[!^(?фДg§ЖлЮЖ4ХФŸ_З2jHЌ„@ЇГ6ЇЈИyЦ2gg&дG/GРЕ3AEчuŽ­PЫ#БCжNБтуŠ§Џяˆ{іюAR™WђїЁя[Зo=зzюш1i"џьВg ъЉз"рVoЅslх3;oИќCq3Xd^\ўЬrЖ›џћиЙ%ёKŽ”ь~u7л}ЖbЩŠлџзњD•з"‚p3nѕVњЧVnF!šSx(y—™Ћ'X ОаЕуЄЉЙ ™J™XxИ•з"šp3юлС€Žщ[ЙjNШˆHdgЇZZЌ„Њ$1 ї рVo…Б•{zE­єДЛвr7цВtж њЏ4§DР­оJџи БCБЁЧчkї~v˜ЊыD k^ж•ЁWN?aђ=“F%шЌEb„€ы№Ц§V‚й,.ˆ7Ьй$о0–ѕмєEMлVѕ‡шІ5ЅТ@хFs-М<љSЫ-Огї[i5D|BР›№§VpUСCФсб‚ЙŽA)F„ EbА'n-'Z_Z,<—jћ ^Щі ŒЇ"кCB€p/}&hўВКyС4EgЄWўК9нХыўЫН’Џ ІКM'Š 4pЋЗвПnеџиЁЊ§хЮ Фт?/оЛeЏєЊ`Ьаg7<лаиАїЯ/ла7tЩЖеQУЌГKеX ЊЪ‰I.EР­Ћь<ьwьа^QЋўПъэ‡З#rZFZжєЌŠw+ђ ЄтmSвж?НžUЗeДW§$@ЮEР­оJџиЊџБC{…){ƒ%ђgp0‚‚^јщBіКюbmU-ЋЎ ДWх$@NGР­3AЖ—]ыЛGпLˆh|Ўg “а)JсbxєTЇЏ{ЇЕyІ ІI*ђ§м MS“ЇvЗрVДК›%Š €€[llЅѕ-ПЮ*зь­3ЪЈC:I˜ њ†€[g‚˜8Р ˜L†Wv>чMІшt\T+ЈуšЈ!@єЗŽ­0sБўХu -mQ§QFЕuаB€pоъ­~Бфо‚Я’'@e4ћОT0 !Т/Ъ\ TјЦ+ЦчEN(јЖE8,цГšЉHnFРKНХuѓ}@Эо€—z+Šъ§ЗYHИoєVЖя§Й”lއiї­ОћЈйОВїXы­ЯН!В„ МђVоq\fТщЛmпяŠvžZјTwkЮBІ›C!р­Зђж+у$ЛАeфШ‘х”3}цvѓбвЃм=•О_ŠГ|[П“к$5„€K oхXНJщ”ЩS>ФLЊЉЉФ8ЋІЖ†СЧYF*ž˜619б8cњŒЦгѕМ ЛЖmХј+91yщsKЭ&ы–,МQ0ёŽ‰Ц­ЉtTХИђЄ;ђbUEеŒŒ{а.Z‡ МŠКBd9\•c`Rўо|.LD @оЪџЏrЪЭ)Ÿ}і1Oќффи[ЧžОЋџQНџРўкврvФИМБpщТЧГ|TQЛћ•н'>=СФДђ,‡‡џrИтяZ:‰я—ЗђЫЫкГSABк]“JџZ юпN|ђиЃ}rтаШУœ6yUY a$щBVСOџ!љ {п,\Мp1уЯџуќтwКЧ>‹ўИˆO!эˆ1=vОC~вќc3œixDјВЅЫ˜Є–Bd9”ьБШrhG-ђ?МqƒџЁьён~ї3ߡܘšaњз9ЃбxюœпЂ№ЭТМЭнЩlTГ ž§І ЩoКэ—н/paœoGŒЫhyЮлОcћжџкzх! –<›r‹4жгRHYЕ` Оью „юjЃ†ФЂыХХХзG‚iYP˜ТјvPytп~ЙcRж#vY€e/Œн /ѓƒŽћТц@`kљв…oПї>h-…‘–,‡,-+e9PuаL0P.їюљУІ?mJ™Œ'''oЬлNЏПЦ§ЋsVKiP;…ЦгXhW­ЂG,цуžН{рАА^Жсљ \t666В=]\-…”хА Ё@ќKcЋ@ЙъЉwІnмД*)1 ‘0Bјљ8Нv~цЌ™™5gжй–І˜˜Ёg>ЁZEVюёйЙ%oррШysf):ТTћ§Иьљйп6|3tшЦмŒЉЅYsжц ЫaШ!™Г3БCеbњ%nЭ'ш—КЂS”OаЈ’NŸC@‘Of‚>wЩ`B @ o žКMјф­|ю’‘С„@€"@о*@/Аjkm›y&†]8[\Rмj2e>š)‰E%EЕЕЕ‰ ‰’М D„G4З4ѓЎђbы™жЬY™т#8Й<—$‚ш?ДЪо }@ƒщМ žˆћ&Œ†и‡›ž:>ОУ.8Ѓ†гu(Вarфд}V‡S\R•†iП6˜кM:хU•“Аy+ћјјЩYQ1Аbу#t КЅKЄЬ€Б"Q3| €kПэ'iТ(ёЯЗK)Kэ˜W:$oG"Д oЅ…Œ_ё#ЂЃkjk0ГуН’Oш“ћ2ёrЙ”Yбмо†"ўtZ`йоJYўШфЭ\^.@4!аШ[ѕCа”„'€pXaIцv Rњe#zH\щ;ЅK*+ЏŒ2‚ †† *џ{Й(ˆрWўНL^Лєн.љŠВИXЋМ\€hB џа*{џ1є ˜аeLЮЈ­­**.ТЬNХˆˆˆiSІЉšŽ5ѕЊъЊќ7ђсАтbтЦLII)Џ(Џ,//…ћc ™†шЋЃ ѓM&ШGg•WUNLB ЯЗъ3tОVQGЇЄŒOэ^„ъ0ƒC7фћЄ^ )ЃSАаЮ$сЊАЄЖ!Ь15ЋяРŸ/§Б‰7'ЦусQтђжsє‡pф­œЄ/ЈСR”ЉM}/ЈbKKOљƒEЉЧэнн–іFШŠн'ˆ"œ„­[9 HRC.F€М•‹ѕЪ‰dt™КшШ[yvkT1‘єЗюQМђVоqШ B€ш ђVН!Dч BР; oхзЌ о oеBtž МђVоqШ B€ш ђVН!Dч BР; oхзЌ о oеBtž МђVоqќЮ Ф&ѕHŸZš[ о(№TыЊ]vЇ1Њm!:Pўо|еSЊї“ЩтD?ђъф­87˜эЪЊIDATD8˜дЩzэЊЋЌЈ;n,"ЃzЄu-гмiŒm[•ŸTІп™Ю0qКQэ2ЗЊbŽ2Щ[9Š˜OЪу-§kЉТtїмИŠFэћoRkлїЦсFDТёѕ—њ‡9>b‡Х2L№RЇs=oХ y+7€ьM„B[•ёBН№ЦэЇI&ФbъЮхуаїеˆ~BС›•‚VЫ0ё]?Nё­ј5ѕs"ѕЮдќнЛ&]Сbщ)z[[UuВОСBЃЃ- ƒ„‚‚‚ддTЄ‡€dущњЈ!Б №џЙДД4##CQНЊЊЊЮR=щІБFЃќ,Цђ МˆХ”ЪП•!*–(†"А_ll,MЌ]Пеy[Уp’ŠˆЌE…[1­<‰m5ˆЊ Ÿž”2ЖЕ­ЕІІЦдŽт ”[SђNйЯЮЊZ+ЏЈ% PбћЪЫ?(oјЊA ттUbLЫU1= [[plmГ jvYEYѓ7ШиfŠˆˆЦ~Ђют|;ш”8Иў ћЙ:Б-ў$ˆыŒ6Œ~Ъ:DžСі66/У*;F=lMџэёдLООУUIе ЁlйOй3AоЂЄЄ+ !ЮЂжh7_ж"7УОa\ЙмFЫOЩiœEАlЕг’'‘bі‹ЌUуqŠл‘&‡QЎPU@Њh —ДENЩрevВoЙœц—ф-ЪЗsАSЌКќЪrЭœа‚‹7­Jр_Wц§№Sф­8^DИТ[yQїШB@ oEыVњ`#)B€№4ф­<}Ј}B€а‡y+}8‘!@xђVžОд>!@шC€М•>œHŠ <y+O_jŸ є!@ЛCѕсфi)МjяiЈ}BР`ПЋV3ф­Дё.ОKш]†’5„€Ы ™ Ы %Х„!рTШ[9NRF.C€М•Ы %Х„!рTШ[9NRF.C€М•Ы %Х„!рTШ[9NRfƒ€ё†)plЮƒа‹y+НH‘œC“r.жƒэЗвƒ’?Ш ёі-y~єqGЧ™˜8уу™ЇŒKq]ЧjџQы:хЄ90 БU@\wЄŸœћаƒЃЧŒ>\tјЃŠк•KWўѕCбsъЄ!@оЪ.ІvWђ^Ъ›=7kв” )YC€№ъkзП`яrжцŒћ]2> т–˜Ъ*˜˜619б8#уžккквтт{&п#ЇЯh<нШХ|мmу’•е­ŠdvmлЪ$—>Здl2ЫЮIєŽyЋо1ђ‰?ќ9нT;Вuлжs?ž;ќіQ|Оћў;ЙXХ‡Л_й]V~ќЎєЉ™s3пџАbћŽэRqт]+WЏфbеЧЋџх0RCЯжэнеЙ#ђ_оU§љЉУ—•—……lЩлЂ "!`ђVіёё“ГgЯАXЖ§)yЋdёТХ8‹cХ’(r™EЫ–‡G„‹Сгю›vсЇ ‹žYФ‹Ÿžш~ЫšWQrЄЛ:зУˆНoJ’a(œџЧљHaЏ "!`ZeЗŸœ †д˜№Ж§ijn П:œёУУУЯ67qј/FУП€/tMСзЊЮѕ0ть7MiwЅu3щжыЦ‚(]а-Ѓ &_3f ђ˜fм—aл‘ШˆHЌС3гвв20"вVЦ>Gguh>КoПЊЧДЏŸЮ š Ф§xіЫЏl->TŒЄoXGGЎгЅKžb=Чx'wc.F^8V­_еcјЃ^DкнВбSЯъїЯИuЮjИ6€Ez,Дїœљ8k(k^VNnЮ„‰RЖфєДt5 aTТф{&wќЋ#}Rzж\Эъ3gЭ„цYsfmiЉњpцŽ6DђŽ€JігЂт;р}–.бѕЏoэњЕ@PЇp€c­Пћ@ещЙšѕЗю$6:аFP‡#a§(ВŸЊŒ­ЌЎJЖŒЊЅНёлЦюSfк>г Q„!рtTМUWŽyЧЄЛкЬПX№FЧй(-:0‘Ё^vаєVц_”ЕЎЙцšўѓŸJ./ы‹qY"&ЅM’М-‡э(б4а'.“Љщ­јЌŸз\{DиsI&џ@Ф НH—bnoc iбn0ƒš | ;оЊлћ\3l˜ЕWнLE?Mі™B–Š„!@8Œ€ІЗтniwU‚Р™ЗCd”PŽRЪ-RР-Z&N$!@Hhz+Ёkнъ‹ЯПілЎБUS<;ЇTЄ…ЕЊЖГжЩ шQџ žhz+“l⇕T RЮьЉ%xй@ЂСHиvЖ™дЂ5Њ›\4Н•bAНіD­ёFЃ‚)‡ж­фhMNG@л[ ЪTЕ'Ž 6Ьnƒh•Н‹^ЈЊj)мJbB"ОЕш^TаiB №а|Ћйм)єњ <ИœжcЌUq]Z4 ‚ €€Б•ƒјt*Чbж ёDc|sЃѕЅ%-:€р ЎњPёVЋ€ЗjИџ}$)фSб/L’~†Б™~жAъŽ—  т­№пЦэйЛG‰,bŒNa= I† UzxЋДл"сЦЇVZDуT+(˜ЇNА К„uЉЈ…Р№ыДNѕпЗQOпjѕЭBЊEєŠ@o•5ЃЊš’їЌ[z­L.B`ј.RLj F ‡ЗB?рАВцљpќУє]њІс}ш,†KыsжoлЙЭРгјќК•QCbЁЇЊЂjѓ ыОjјr`xфМ9ѓ&M™I№й7 Д€ ХˆeќСG? ЃnЕ.gЯ+бKЈ !р(š;UDђО‚@ХЧћ_пД€ЗЅоЖrљJfіТЅ ЯZ€4ЮH xтг`2…oF€3ї?‘яљЁЪ>*{Пlјаk7lкРъв7!рШ[Йg/jeљ3ЫYR?<і§єЕЬВ_…4џиŒDШИlщ2UsџR№c‚›^‚Я™;UUХˆIИђV.ж{еТз0у%ЇЬћs23#Ф=iYXл Йќ#sIў]2І‡ЃF:sіŒ­ qз! \Зr]KЄй›ˆћТц`!А–/]јі{ялZЛшщE .;z,ќŸŽJe+CBРuаиЪuињ’fdї“ЖјZ^іьш2ђ—#^о)2Я?hll@GЂЂЂ{фєОљA/АƒСWђ њкдЏE€х„ЗŠum­МіJ‘a„! !€QUDTђVtC„€З#Рb–а*ЛЗ_'В ф­шN п@€М•o\'В’ Ш[б=@Оy+пИNd%!@а3AпИЊЊЄ49t~@bЂ” JѕАz+О[” Л<<ˆošv.ЁB’Š„€_"д=ФnQЖ‹w•8 юDCо.б„!РАŽ­јnQŽ q8 мŒ†МiЂ Bр7Ј|O&€…пžBƒоф—€ˆ@Fя NH иЏВ{&ШAqч”‡ктАƒАEC~–hB 0рП х3A7Oy+eдz`оŽдkB@ ЙOPЮЕъпxсLбy: wBAm2,b G@e&ШЯA„€ї @оЪ{Ў… -ai]иЉ&\y+зcL-„€3 oх }TGЇГ6gмя’ёСRHH]щЖцmwлИqc“ оШWtЎОО~т о(P№ЉHИђVЎFи{ѕoнЖѕмчП}ŸяОџEf+–6O}yъ№СУяМ]і§їпЫ;PUQўшc>ћмГїeШљDn@€М•@ів&Jо*YМpБСrЌXВEfhс›…(Jљœge?Э­/((XОrнŽm;RnIсL"З!@оЪmP{]CMЭMсW‡3ГТУУЯ671Zт‡[љrЃїОњђд?Є!OЊœI4!р6Ш[Й jЏk(2"yL™Y---#"-ё[Ќ|ЙбЏНОПф­wѓї*WВф2DЎC€М•ыАѕvЭiwЅхnЬmГЋжЏB‘Y<ѕSQl;г†єё[ѓ6ёn`nјк+Џ(ЬпM‹ЃB„ћr_S––ЊŽW64H™Wщp3Š-Wи˜ž5/+'7gТФ А$=-EfЏnнЖiђ=“QфLvŠ9Ќ‡ц>$tšfЮЮdLњ&\‡@AсAЎмс7oњяnRЧK?:ь pАјхjЖƒ №xzкЄЛyg[СU5џиœљ(ўЉŠ\…~bзŽ­pUxЅП I„@ # wŽy+Lт2ŸШТ,@№Ёƒ ї!р˜ЗВкещ>ћЈ%B€ Ž?$WEї!@xОŒ­hш‰+EmŽ€уcЋ@GŒњOžA€М•gpЇV BРQШ[9ŠЩ„€g oхмЉUB€pЧН=tc’'g рИЗrFЋЄƒ GpxƒД}сG[!yB€ њ‹€sЦVУ~;Laˆ-G!@EяGя”іСШОеъCCT%Ј=UЯ?­єдииxйЏ/г#I2^Ž@DxDsKГЃFі­–Ѓ­| 0ўŽёМ›§ѕV| Х Ј6ю|оGул4ЊL›JršyБоЊЧ‹7_|ўtСU1‚ы%ТлPяЈ2НЭrВ‡`8ю­д–иЩUљє§„Aжи”Б5е5&SkЈaPЪ­)ђ BЌkU”з}%}Ž‰–чМЉЊЊЊЋЏC ТЄ›FФr+ЙєXQ||%žУBtŸpм[IMѕ^Ё<ьЗ=nSfЭŸз2‚ОНx–™їЭ4 4”џНМВМ<}j†Щм}•с’ZM&DaƒФЂ’ЂкккФ„DSЇЉЖКЖѕLkцЌLq€XўAyш€ажіVжй–ЦЦЃхeЦO0ˆяЮљоYшЕєЭ[)Л#wLHJА:gУшфбJ!*{1ЉwІТКЖŸктcу+ЫЫ  roеpК.Оl€I‰IEХE^™кLuѕ'%ўЏ%>ќ—аu7еžЈ-Ћ(KŸ”;,їƒ\•c@Іy;}кС€эькмг‹ž^Дmч6oG#pэ 6Е›0\2 јмя0DLчMXс‚K‚RЂšЮЗBЇф|œjmГЌЪўVwнrU{?ЙІч}ђVН™b žmiъMŠЮЛаЫC0ѕSnмМ(ЇХЫEiˆd0ЗЗЁШЮЪљryЬ ъъАдEЃ*9,Dїч{+“ЩœПwOLŒЪJV?mЅъ}F юКИвтbx(ІЁЅЙЅММ<>>^ЇТш!qЅя”bАl6™ЫЪ+у†Œ`уb-|xЙNЁЊЂŠkУјkв”ŒšЯъыOеs&„@?шZipDэП`yЎКЫ‚„˜Œ+WЏДsЄ]ВmиИhљ‡/J§…`!8HDƒpЉЎъ#„ЅnЬасЁиd-д]lтЭ)XџжжЄЊЊЋђпШ‡WŠ‹‰?~Мй,U4&$bЁ=П0tвMIPЫ'ƒ˜KNš4ЉИИЇш™ IFldч|ЧН•Z ЄвфнF4ўНДlsЖдœЉ]Иb€(ўЦpееЁCGF\Ѓ!yOEуЄ|’ЈБяCР9о л;Ъ^зП:|љЪхиФь|oѕ‹щр3S„Y'3KЏг чx‹ уыЩџ)вўЋЕщkНZHŽ <Š@ŸМ›jЩьЙ"ФК”1;+G&уђRQZPЧj”e­ъхгЦVБWбxи[?ИЋ*џN~ !BњUBAЃњ›Ў9Єь#„!рBzћ•ыkЛWчЌ^ќфb ЌZОmЩнœ ŽОЊ}”ТАш{|LТЩs=4АEїИ+$/fА,ЉЫOcUЋЕC§•bёQС’уS_ˆ“з"š МЧН•ЭР нРBО–х]ݘрр­1Юя'1H”<Jѓ8шТjTO(Т‘}tNњШЩqYjE‡X]•ќ,б„!р§8ю­дњфDЄІ^ЦУhШтŸФСаХЖЮђ~Ж,ЅƒйгŸ2w&}[\лиЫЛЊyёпё#(^А_2ЭMр‡ oЩ9оJЎб4_’v‚ўJРЬЮъТXЗ,nЫ /†Г–g‚ЬsѕДаfКиѓДGJ‰Цx|XгиЫ‹ rђ]'r“ьŸ•Kњ(]uМВЁAŠЋEG"аP_‡яИsМ•ёFЃbxeЫсM:\•тАј)i#Лe=>‚„†sжM Lж:цъФ‹ЗцрРоцЮёТoцЊ’RЦzЁmd’ћpŽЗRиэЮ,*ЎЪb sUЬ08&ы:W—ЁЬUaиеPQdˆ—,ил…вP‹^гщТЩУ1Њ‚ЋJ•шa;Јyя@ oоŠЯРуЃXG0˜т= xйќйsЁ[ŒŸr.ЁЧUёЙУbЎ [АoњЎЁђеѕЁсз‡^)I…ˆ—_њяУ#Ў7Є­;ђсРшei%„€'pм[a’%ЋT{т8Ь†Яb„'КаЃMih$3“˜]sUUxAЇCb…Jк…sŸ›[Є"ќвQ5T bШПсCpАœ/\~uФаы"FŒЖМЃlЕЁšхMiМ2ЭŠњ`‚ўЎBрџ0on†EШIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/15.png0000644000175000017500000011217411733011756026240 0ustar sylvestresylvestre‰PNG  IHDRюf$–юДРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxь}\екџєЛєcWэ‚њ&j†•†–WќsM+СђнTЄW„ИŠhЂ’Љ‘• ЈЈ˜"h—д№_†aщ›ЎиMгJQ“LS“ќМ†Ўї"Ы-cљ]яЇпw8Ыйavf˜e—йЮ8Яyц9ЯyЮwЮ>{і™™ѓмsГЄ„уИwзх1‚`C€!Р`И?Ѓ‡љЬžхOэєEќxСщГ”Ы†C€!Рpoњr\ѕцМ+Ч|~мАџЙТЂBї6YЧp%}ќћ yі1qх5`mз"pёЌ\їьY–2яЪЩ†њц+Г9]-ƒ§e0м5Џй№.Ъьc"…‘.C zЊAиЖе•ѓ\љЎYxšб †AРXV{3‰}Lи˜p?ўћ™Ф,b0 ћ`Ўм>̘4C€!РpC˜+wУ‹ТLb0і!P7VŽКџБЏ>“vG{>њу?:Ј„Uзі1бqGлkі46+wtˆ4R}ŒМFвЬд2Z-чsФ\ЙЃКєjщЌ9Гњ ьƒŠѕЖкАЉzЫИѕШšf}јшŸХQиб …’ і9BEeЕЂVмЁШ\yЃ_уЯЦ№)сC‡=uфv(‚йш ГMЌЬ­Щ‹’Г2Гšx?Д0п&VЮБчЪŒ{њ{ЉГЃЇa б Т\iѓ­х+чУЖМЛuKе/UС/ПЕpWsMэйћЧЮwзПћсЧŸ@`Ф_FЌX’ЈгyђќЛмšДw?йћ wЗjіЌ9‘#Ql2› u‰vt6ьcтlDmє;љ­ОmлёcіьпљэЩcO<ѕDDƒ\T$K/йКmыuуѕП?'ќећA#еёйБU‹S’УoO~›ќіЪ+W.Зыахѕ™Г‚k?цзxГ™•пх}лˆРёЏџ%XЈE0-Ž;yКрѓџй{є‹ƒџЌРpЁ|BlЩиrёћ‹{sіž:vTяЁ_ѓv:сП›БхкežџеgGoоМ &.FŽ<С.Ђг~4Ўœ)ДA`зЮ]/ELРHўыј лwю"CZ4ШEE^†у О/ј4{зgk>(Эѕ}аЈ[ЕrУ9ёѓцОќzсЩsЛЖ}PXxжЂФІ/ТHМпYЗШцф"<œPМ~ЛмгЫK8‹CёіэrЪ‰ŸZ1љЅЩгfЭ&­Ќ=Л36fxЕчцМ6'фПCоŒєю=Л?xџТŸћ&еF Ђ„rc *дyЋьжw…пННњm@=ђ/cVЌ]SZvЋCчDF„ПЈїZœ№GЯ*аhыTž8%ї1дпЋ/љЇбЏВвЫЇУ›  ЋP…кbWЎMЋ-Њ•іэкWтJзјbвqлЕkOA ДC‡Зз)ŸЗО>zдh+ГіŠсї#ф­|F1šй9йхЗЪ{їхc†dЫўŸьйЕГœZžє_сgM(ЁќAJквrУДwв26eМћЗwлоЇ}AB`@ m]m8ЕŽA›жZd+ƒ6ќн€X6э=ЧІEL@Ш ЛuыV;Ÿ.”Opюмe;:Лјt<ЂZЌШhТмхpш№сУ|,“|FТ#УgЧ`НП†wKђƒжЪƒЋ6W{жмТKNЛмЧая1ПЗзНZš'.œїй‘Џф446ŸХЪkCiоŠy)fЫж-ћ?й_}ЇћўOїЃ;=–ЦцRVЇT–WbСOР‰%Иђ5ФФ№‰IK“n•оB№ЋДИtс‚…„:6tYђВJceueѕЛoЏ!ЬіэZёO:6Z_ZДfсg‘!м˜њћў?їљs‡ішxУа?їъuшя‡Р rQ‘ПJBлh‘у$?hнўд{Gж|0ёQJ]•JЋ‹дЪ} ёyф?qЌќ‡ЋЂm h<šЗеКйИrы)F9__пЬї2?ћњГ!#‡`џь№g™яmЮІћѕэє— ЖоmљyGн-rrdП§&Яœ<шЩоѓbŸў,9?-zкc=ŒŠЯ?зБуCцф9a‘aТŸЅ„ЯŽ &„РћЛvF„Fˆ ~сХˆvНцДКƒ\Tе%?hK.=rшШС"ІF<ѕч~T^ЄVюcˆЯcьмX|6зНГrѕŠеДКіФ=Hї|ш!ЄžxkeЧ7_}гTiвожЂ-Нє>wкђ0ЂэYЦбќњЮљ4эВ‰ірГmxcюБ W+?л=’œbГr[ˆ\Я)ўБЁpзлС,`0šЖ7Њ›ˆхЭйЬIQ“цН6‡уиЕpлЋЬ.л^šj˜+GžmЎFoё&Аkсъ !л>Л4ВаАЎA@ьЪйdУ5зЕкЄ`“&uЙZ„Б,Vо".3ы$C€!аМ`ЎМy__ж;†C E P'Рb,7šяИp8ыdE@зZG,g“&z›ЗйVWоЧПоzjоНeНc8‚>#ЈЮ>&Ž`Шъ:BUVWю7кЛ№Ѓ [иЧФЦбЄ‹„Њ•—~^*ЌfmЌ4NIXџcО]™0C€!Р`ЈAР:+W–і}ЮWY@ђьБs‡vžЬ:gММ;bЗЗйЛ№*В€H 2&C€!Р`4ЕЎГrѕо<$=ЄмTонЛK[ЯNќЃЃŸŒоК4~G‰оCзч1OЎВšгqžжd5kИхЌ&C€!Р`XuхХЙХ…E…BœN9…"юќд+ќп›?p­_ œй7њиEугГŽщu\Т_ЛŽyвЗђ7ыуs~2П>нs`_Ёz+а! яVžЕ\CI2E2ЌШ`0Z&ВЎ~|ь‚БЖ ьKоWЏ+чkyмy§аДЕ;МЊL]гgњр'>oCqЮqc;oнѕšKŒК›˜лЬ8 †CРno{bЁ л]]­МyЙлз}:{sž­Йбёпі™qьјЯе!ў§GљЗтO6ач?eи” ЎOEЪ>ФkЊйvЌођЇ ЎAIБIXHž01—7lЫ‰x"$ s€Eާa0ЭEWў>5†xWAћж| hФUЪLця_§'7"дџЯУќn\1оИj„ьяzX1kEt|єС+yiЛг О+ в;вw\<{!ѓHІс‚AЇгmJнDЕ^Ьј"3ЏLБЁŒ`0MzъОд}ТŽ“Й,4œx›ж­*дыtїд}wж<~КПЉмlШ, шЉыфуurѕД,Ё•АєzНЩhЊМ]щгй'.%Ž0swцІэLѓъРЇЅ‰‰5g‰хЗи…Б^5љьI‘ †@ѓC@йЁšЧЦеэ3џZ?yšExЌ+У—tpЊ%mu:ЎS{NяСyыИмХ[цњѕ~иы“ы[WNвЈZfвЖЄэяlп’КEзЋ^јЬ@4wНфzш PЋЕТрџn=Х(†C€!аьј<›О™ee&O% 6U9}kоƒcъээхЩщЬЇ$Ьі/)5ЭY]<"МžwJЛtэRњcЉяЃж'йK/–‚IZёыэЗrыJаšЏxmХо‚Н Л<а%#7ƒymл С8 †@K@@1Vо`<8]мзфЇ№оо:јq'Зыя%ыоŠœузб‡_–ШВ4‘TЁ/…&Ч&Ÿ-&7]A$П‘ &‘Х]Эвk5IхQўЗЅ>ЮІЬK1–Q_‘RЬx †C y" ;+ЧѓуџvаЖгdE![ОгŠkнЖѕqmnУБzyy"bЮн5??І+Šцџpf3ятof‘~ˆ%lFn]ЎŒ[YvЉ ’{t˜љAЗін‹/§пЭЏђŒfФX.+й’YќњLнЄ J~М™BэЪnнsЯ=ФЁЛвж6C€!аhШЮЪiбгУsуŒэљзђзЎ2нМеAясi4šп}ГBѓІе>>эбЭъ6xѓпџЭЭЋЦpoХ•“.|x`шЈъўчBф[w”іъЮ-™чуйˆ К7вn`ѓцnp˜ FA q=kXˆgXБ›ETхњйЋ”ys{cђ &@ЃФЪ›DЯ[Ќ‘,nоb/=ыx3F@ WюHЂf Н ЛЦМЙ СgM3Ц А‹ечЌаххp-ЊгЯБošŸ›^‡га[ё\ˆ‹Дбp-ЭFІkёo­kсЪеf ЊЎ†їšОFїЇ!\ѓE•яNгэ[c‹Еyљ!ЎѕЭ~[ЦЉцЭы…ШЕЬХЛџІеКЎ\хЌ\їКПgї~КЧКrе—ˆ:_/.е ѓєт_­йШыўІёмт‘цѕБк“–Пx­ћЊэпџЎъ—ђnНzOˆјœФ+EЂZrХfљqТS‰r§e|ЛиМzѓў­9Ј2>:lв<чќ|Є4ьЗf9b)&ŒC@ WЎvVЮqе— ŒЏѓЏр ЗJAAH иVЫАЬ7gкМiБЉБ^­НŠ/яzo—#ЎмЊКщS№р˜‰“~АЬПž‡В gђЮdх]љќщѓ;v=42|Єуj™†@аТ•Ћœ•Уzп•;8Ў’OvЁА§чtЅ г$E>xћƒisІб[АŒbтњD‘ЄhкB‹XjqУВ eW.Зым%zn4>–8…КфHЇHHWєЩћЋ~Љ x! ~eМgkў9KШФЏŠЭкјсѕŸЫ‘цТV•Шэ‹ф§ тЭYhХ)јјјРЬ3Щzœ о_§~=Ўќ.—О$еАћ ДЬ/Љ_ћљЫй”ѓсп>Ќ2WЗ"Ž№щШ„МфЈУќЯ‚Ќ§мнЊШИщaSУlGЌEЇ€Я”ˆpГ'XЊ+ЙJїыMЅwLЂnатёЃЧ‡М` ЕSІJТ6?qп8Z§ИКtEЖЊTкаHbФ7’ђЋіќљ+=zї нqѕ<ŸREaƒлНqн”s"ћы7PЄТЇ 2fцфч˜nš6ЏГђ‰€\’Ќщ›Џ§p ЩГВП3˜~ц?Ж#жн†"э2#œ‹€Ў\§ЌМ>њŽЉњŽYМWšЋБƒЯMее4x.FЃмXюѕG>—P6ЩќD"=HWћж|LФ0GКЂ/іё3,В гЉQU[Џбџ"–BУ) ржб$&цlUЁџэ_П‘пdаЂќ_П)+<œН?vyЌW;/ь яйOхc—јйV>uЙ;kжŒЦщ‹Ѕ#ѕn5iсtДpхфЙrЙc.™сЌ+Иђš•7јт Ž ёЋЌ+oягОђ_ѕFдыДI ШOtђы“QУЂ?K)_HtEј‹}tЯбјц g…‰/дЈЂбDhѕЧV4!8ˆіЌI?.п™ыЦr_rщ ‹ЃВr|" 7ъ zЈI‚ EIXšГ6Vз˜=#ГrЙЃАeГGGнkœЙBШгКЖ\{o1ГЖЇ‘КЊђЙrнЌ^onс >уn^хўSуЪm њƒžыјзяљЪ5гф^В­Ф8 Іˆ@@ч<ик-g6k€@в‹EЎV~Жлђ*ƒ{ЭЪЭэКъzе=вЙ@ЅБ№а™[w„˜єYЦe4№v›0˜о\КХњбXhсЪUЮЪбХъ„‘HоlНйXНfzюŽРьПЬžГЄБ~(Л{ч™}і# …+Wљ\9 ˜иљXf‹РСЫ-œfлCж1Ї"рfOА8ЕoLC€!Рh!hсЪUЮЪ[тЌ› †CРщhсЪЩ{žN7)d0 ‚€Ў\§ЌY„№Hb§sёвBnxхШrt0Œnh$3Щm`УЦm/M2L‹лžjŸ`iœ,Bјœаu ›а…aІ2иаec@=тЪ‹s‹ ‹ …Fœ:s Х>ў}ќFћ љBк)Y„D8qцЧ… 3кЙаёжУЌa:й€s/qSбж(Ў~|ь‚БЖьKоЇрЪ!яx!(iиРжZЦaд‹lдЁз+Я„@ЃИrоVВ|ŠV;žEШЖA:I!LєIлЬ,Xо653еїQ>єЁ=‡FŽу_Š-§Б4.*nзЩ]X…Ћўњ4їonРГтзХcсiлСaЉ[$aiщL–EЈЅ€FьЃніDR7лНоŽ8œEHЙ…‚Т‹_d’u-$3Г \ј-ТjsЋуV“еЈСЬјШјˆщ†ѓУУУн;e,ЫkŽЅn‘CІ%ѓYЁ–|ѕЛяцЪ9n_ъ>сЎІ'ŽgB+˜}г]дЈ0бdf–AC!5jќє ^Ї?š{tСё‚AУи~d;ЇЦBчH7ујсу"§ДШRЗP(A`Y„(Œp:`сЬcу‚ъšЫЏEžfыШ,BuжЖ5swu–un!JьG~Sˆ• §Ь,V55šћєY;-˜ЙŸф.\П№ЃПё‰w/ф_ˆ_fёйтЫ7ž/<5oљŠђр!uЫіwЖoIнЂПOџњЊз>3—g[ЫFРС,BV№jžЪ,Bl(ZЁkОTэ pvЭ2Бrл\BТ–Я"$дІLKffС„Лг#ŽхУДўї§ЕячЮ‡ЄJœ>oжв7W=Л ГrФ^†?<\Ў –КE™–ЬgY„ZђеoьО7b€Ѕ!І;œEH}Ѓr™YžўєњЅkF…ђap\;8DmUчЉуу+Иџ™’ЂаKнЂN‹=ХВЕиKЏAЧeVŽчЧўMb]7№ыщцђŽeЊGПрД\f–Aƒв–І й!c†ЄЬO4””c[˜ЖpэЂЕˆЬ`FЯЇњHЂD’Ѕn!84ћ#юЪ>B!И1–EЈйver!јЌi†€,‹:-ўЫ"дт‡ ) РВ5…ЋфF66J€Eд?ЕkАА,B"рXБ#РВЕр‹пЎkсЪUЎŒШВ5фВ:Э–EЈ™^иЦъ–OА`VоXц3Н †C€! |ЫЅЧ=†п7пsЮщЧЮSЁ™щd0-Žы!ќ Г>Сђћяˆ№œГшCя3ђ/uжМUЏй‘Къ[a’ †C i!01Мы…Ћ•Ÿэц—ќУf А4’G іужхћЧ6†C€!аАКrФUЉП˜Y7XГЪК§М B}ГЂЛёћь[&њfaъў“ nWЫŠПџўvвЂжвж–64вѕUVЋ|VMЧпJ%‡ўІFXK˜У`^У"#ЄІЭЕЕЌOАИЩЌмАП‡0вНЕ’‡oŠЙ$Vџіпщ=єКšо˜яъЙ{9Wе™+““g|†@#!pЯ=o;Ўz Ф)Њ4ІukньWy_7џЈƒЊœ^&y.ц%ЇнЙ#;ЭйьплЇ‡пЇPЏТaC}^šвgH Џяƒ^еџсŠ‹+Г?)zkU>їџъT§jŸyo<сыЫч?hиEЗКrrЗГŽz'ьŠw+d трŸх6§Cm-gЭwЭUU(™џ i\]љZrк\ЧoиUtНЌe ˜^КRЙ:%хЎОоѓтішц5ђ/9"€šтѕxБЋ——ч‡K ЮEнqy&САУ}aфжm2SНџЫ?чїюІo•­mЄKѓЮк‘™;Ю­HЭџсGSзНпJ \О,АG7яI“­Ы~LŒъБhaрГC>МјCДВ‘ g­7™•ѓЖb%л]Ё|•ЊŸ*Ьиoўb6Uёў:нWнэHЈя‘aŽŒъtAьїЗОЉ щЭИ7ž§ћПпИT<-zFсo.! ЂтЂў(і›Цй;>jэmљў L‹кк( „…­эБKэьWњ”\FЌѕ|WЁFkŒРœиCјQXX‰vqдщ8plm^_Bc˜aАс"bH`œ*8E Jƒ#7ЬˆАЄ*rJx„’’K‹‹­Ё‰a#Лцi6П§шWaЃЦZFд_jђёюЪ.*QІхь$]лžНМС7џњ§дpџ—3•ЯГ__oх†p–FŒ”геГ5З;[Цбзж!Ж‘’ЄТSЕ•Ќ~`GV0jб+Hи‘фпяУ5k 8oТ4МфŠщхќЈ{Б7еœзЏљќшœ.™(Г„е•ЛQЌм6§8Š[ЇЖHСсГTЙЙŠ'8="-z2я{ЏіџуЧл]}М=і c;F<]R.Уъ”РsчŒ|з<ѓaФ8йŒвЖеёбэпяУ6mжПЕьXdTяїж[n+Щ>НМЛѕкBОібЪђп”V^ЋдŠВкAƒ}яџaфф§~zm|ЏN‹Ж2ŽІ`.Ђn{aЌ/[‡Юы1$0ќо|ї­t†‚вр+IU"+рЛ1ќђП1Жё^џaVfˆp:Dfч‡СO №™ЕП}ћѕKWфЯ­ ЊрдР>8?^"RЅPTЖS4nсцічУлЮœjyК.tLЏvфw@§оFŒ”4щ…ЦВъ“пи§“BdЇЄrЪ„†ыXН"pиаЎјRА(NzЩ:ѕ&’yŽгXVIŠољ~№Иё9Їэ66MЋ+wЃYЙ§ˆ0юЈг=дNзVЇяtŸўЉиЙОИžmѕ|?љ0’О­‡tНЇїЈ"чЬђ“Љм0cŸѓ†ФЌJT…%цуЗЂuяnрЛ ўK9ђыѓо1YyЄ•yo#­ЬSlEYэЂЧ 6ы~КAЂlдFhŒ@zкHЌбпЧџCД‹#hpди` џ0ƒ€ќœX~ЪmЪуAЊщбМу^œt c5e5šciбЛЕ'~Ы–•šюќл|фPЩШ–шРE|€ZE&­Тi,=Ee;mЧэЪšРдєiOъљљЭКЗyѓD›mгФ0bЄH˜ƒЧј}ђЉ?)Ј[;щ)[x†‡эЏМSНsW0ОAџї~Q@МgяЕыјQёњ|ўZcлѓI№„— GОtдC•лХЪk:(ˆФм…Чaўp­]СџкШЬПѕоzЛзН<Џч}œWK/љEс™“oчš![ћ3G8vy-ђО„W%тО fdУœB(ЏM‹тVЎY?!T†ѕЊ-)­ЉћџDѕXбУтИ.Гg‰Їcr6бŸе?дŒ2<$…ыjTљvцGцХя­1Y: X”t ‘м'љбЙГЦљKŽиgЧLœк\ЏЖуіф1уБ”р‡ПwћwqЪhф?ЈєЋBЙѕк)йСUЋŒŸљВџУ‡Kсяво•ОKiл4љœТHIЕЦїЈМ]’gdŠќ@П>гfsэ/ЩЂўчџрgъФ IЩcНvJжТ/—Чѓ‹йлxЋzыіBI1[црСМaљ2Бц1cќ ћ]БmˆpфќмТЎС‰7`"˜x:ЗСŸє З@…~\Ў‰†ё­ЎмMfх$’‰vх DWoЗНv‘=&ц'oU§p›3Vqx”›žдAџL§sѕOС­п+;+ЧЌp?ёDз[eГNмЛЏЮ˜љђ!|п~’5цТ…ШSЇјСM7DЛpъ№СёWЮOћщJST†o­Ь_Мфи§jZ9љщОRzJDиЅVT—› lr‹У $–ПЕђXee5žN#350ыrЊ„P@џœи/ D‹хзgНќЪРUk--nпV”ВrЄљ_o|y(ђлгЦ ‘М?Тіщ~ˆF„+нŸЏДъЕS(,ЄSж|‹ˆoяО>[2Ф] ХD41ьяЙu>­DцЉ@ŸЮžŸюmHtEд -ЪљэлFтщƒYЏ~{fиA ц‡ŒСЃœНтžЖm ŸЊuœpї5XььЁљўжІюїоhЋПЁПЗ O–ыюхorbšЂ#ŽњŸ~С НjЭљiѕjЦ3R)–^ЋьњШ–z…™CР^љ5mo[ŽШcjљѓЯгр№Œœ”#Њъ­k2Эжщ<|p§?ўQћЃ@БNПО>g "ёїР[l_ZГvШьOшкН-К§ЈЈВЩœ­Сb5ИЩЌм1 uџИгё\GЮдЏFљўџkjпЊЂэНІЖњ{+ражaЎоVЎУўр•oхŸее\~1rтўЌЮќuІо&Щp%ХоЈір )CиYАШŽ†”ПZ\ђІ~ЃЂЄ мъЪ›ХЌ\ЁЇЊNСq3п­ )&ф0 {PСсfнTAЧјЇeиж`ў­Iž`aG†C€!РpЈы&„ѕЖчЅпчˆЮБ"C€!Р`И'I/IЇžh™yЗђфЯ[Яl^Нyџж”ЧG‡Mš7нz‚QЭ5ƒAхhi.А~8 -\9fЧкxs… D ЎXі›Ё PгQГљWU/ЁЉR':”m8“w&ѓ(яЪчOŸпБыЁ‘сuV€Ш2’!Р`ˆа"РЂЗє икют^K—?нг;=Wœйšю„iўеdІ‹ QЙZbЧъЭ! ъ”›T}ЇlђcGBAУNCФSA]fM)НXJ˜>>0sСLЏ^иA XЋ•§ucА(љТд žAигІѓЏf^n0ш0 4=›џuў”aS00e[ЧЇgЁ-5>5Ј{PHПœMќw<нlG=Хˆ‹€Ўмщ1kЅЋe"Ђ Nм7)ХwкLФƒƒяuчJђ• K.dДц—ТъЛUЕW‘ ;вw\<{!ѓHІс‚AЇгmJнђcGсЏц‚S{3 Х‡ŸžД •SЭъG­Тˆ–€€МЫq^яЕœ•Ыe "6Ж§ƒч=xЧЌœdq‹И:1лz<ЇЫ]2r30н–>]ЗWЏn—Ю]ђ’ЯВт‘^НъЋСЮЛ.>эЅFтpeF-6ypееејс…be%ŸБDrѓыэЗrыJœBа|Хk+іьŠuy ŽrzЪС‘Fѕ0Ђ™! E€EгXyCЏЯФ3k2<~9§3ВƒNћУЁдЛ†ЄЛ†ўй–DˆUwёјJM> ›VB_ M™—‚6&кЅ?–тЮ'iпЎ•ёZ§K< ѕўъ•З*Бƒѕт(›Уэ>&mY"$игЇЁHLьнЗwіІlxs\ЭД„4jЗh0`”^+Еќ2ћ7•ВУЧе(ЧWArzZnЄQFДLšеЌœd ВНЪˆ _А‰ь§4ФK~k­ѓjуЩчЫђрМt:мб‚ЖЧ=*Ьвžœ {…ЯЊћbьэВы{tŽЕxџШWЇO9 ЁpсO^Wн-xB№Э’›QCx%cЂУи“ˆuсqгRдыQi‰iaљЋ6"tŠФаo/H~#9#9ЃKз.чL<˜s№EƒahааФЩ‰—/_юоГћђїŠ:9}оt<Сц†№KфЋ‘G?;JфFšЈ:+Ж4ДXN‹DЈЕGжЎvgŽšй 9u|Кgсf2™Ъn”m?КЬ„***6м(`4C€!РабrZЭjV.BгЎ§Цѕ;ш*3nЪLЫEmГ"C€!Рац+wzŒўъ•Ћeee^жC€!РЈвв6+Џ&*Бїћ:ЯP># †€k`ГrзтЯZg0Ž"рылU WnWЬкб> ъЛЊ] Œd0Z  …+wzЬZ%0ŽДЋОni)0Њк№9oˆ€ъ š=}gМЅвR&Ц`0B@ WюЊйБ#эЊЏЛ7KЗ$Ц7kПblЄя’~‹_сїх>3цrљп8tyœXйКфž•жЇЪ%жg;ЯhnрЖЇЎ\§ зЙ;вЎњК}<Л> гЕспвюуЇѓiУљ=b6{˜Ћ<ИЮOњЌHwnŸœ ­ЉИзІbЇ. SСpі‹4„ъgхЈЏѓАЌeМУЖЎK-T@†ЪPBA•Eg‹КѕшFSV‘Г"=є ЊОnб:SЙiњтщ”у‹šh:эТYВƒюЦdГrщ+BfхrЧКuЊ‰ч™ЕYъ дSтѓХtі!B”PЈS|Жxnш\D‚ўр№ђлжф5ТмrihЈf=ФC’ЯŸ е)’Ы`нstЙбjеOIU$kP“5I˜O‡$ыё}иї‘Ч9іљ1(СБџРўКЕIkч.ž+ВAуbьЪXГЩьўlxЇ.кг”5v.Т]ЧЄMIДSBѓд#ЃЌGЈSH#PўєГO 9 z|ѕ]КqщўЌ:sд•уSЕюЏS=ЮДSюLhtлгŽЎSбrЄ]RWю(43g“чѓ~ЦеoёМЁ~ЦW"э›’ЃŸŒІЬ’ž‚МКšd4”ЁFмZ rќ&ЁS%Ю(ї'иЌмбk„ИHрГпУМžРОцНэVˆь3HFSГ!+ ­/—ŒІЊŠѓдaКь П†‡оЈМˆKCCХTъЁђ Јg”Ыe#J”#Ќ+ЄВ&б&„ђ|ВžZ|а/rЪ?РПЂЂЪihлFчћ˜/aZП]jїB=каИ7‹ќAИ›8kђжЩЏM&эцlЫYПt}ъžt[?N{­5z${Š›Уe—Ўјїхѓb“гУЇ7њ‘Oo„oа”Й)И-Aфхј8Kэo*:p&mrЧšo#[эШьигДiЗј"7uV%ьLNђ р”‹’нс“б$ЄYђХМyњ KЌ\.ЭТД…ˆД"ФЉ1ŸЄц#K’‘rЙ44TLЅ*/$фrйˆхЋi{Г&ѕд/jp‹‡[AПЈЊ‰/O\ікВ й(Gc‚К0Bр‹Рк˜чЂnџR5`PЏдЬTŸ‡-бГДљќїє„AЈ‘‡џї0ТljQЃ*mmЫџ&Пзрє†АœžЁЃ†&ЮJМќ§eќТ'ЭŽ$Ч˜Я5jpіЫЭiміdY„НFУ*Й}9w­8яˆ—rБоЦ№ ]мўѕz%[Ž\q‘-ЇЫдгє…щѕx(8*И‘є3ЕZ" Ь"Єб‹ћкЬŽmAдЌніо\ћџВЖЏ\ДЪ ЈЭЫ7уЧ/žЧƒtУЧœa$CРi?r\(wš^ІШеhtлгЎgДˆ‰6эюмюU~ЎДќлт )ќ,хЂ\я:vэ>8 НННщяY9aЦg4 ќкУ“? ЋЫjЙ9ZXмfC€!Рhr,0ž=СвфЎ 3˜!Р`дA€ХЪыРС †C ‰"РfхMєТ1Г †€n{jі$‰шТ:Н]CњЁЭё›E­иUЄњкU‹ Зииh WЙёњШfхv`ЋћƒТLДй#а0члАZЭLжAhVo{ч 9uцŠ}ќћј–^ђg{Lь!ЌЂ@ЏАІтз лSјмЊ|Н…~ТUЪлЖХ8#аА+еАZw5зДаh‘[<пэєX‡$а№уcŒЕ=Е/yŸ‚+‡|ПЖ•$8ІЃfѓЏvЏ–%ЁHŠE>сдЁK‰0C€!РF@‹‹6~мв?ЌШjЛKї]Ь§tOkь”[œйšю„‰fГЌ+w$Ћm”MњН B2YRўзљS†M ъёTMzGka bс-,Vв/i’„ЗKТГŒfˆашЖЇ6o]ZњіŽГнE§–*Т‰ћ&ЅјN› ‚xpHљEнЙ’|хТ’ ­ѓQDЯ*ЉХЛqЪСЌ:R1^SB@2YвŠY+ЂуЃ^ЩCZŒ‚я D§‘Kѓ$9–DuY‘! B YХЪIпіЅZѓ„36N"ф"BAT„Їœ[Ц[ц;ІьœlNQƒYuhsŒhЂH&Kвыѕ&Ѓ Kы -F\JœЈkrižд%‘BVlЩhсЪ5‹•з\HѓиИ КW”‰„ЧК2м ую|š&11'{ю;№YnU•Yй•“Ќ:VђИJfеБVdTгD@ђВ"ХФіwЖoIнЂПOџњЊз‘ЃYи9Й4OъЧ’PЃ[2нід2VŽˆфFlmХрФy^уФщФ<‹[Фељкжу9X:<#7C˜MZŽq[H1БrыJєAѓЏ­@R!aяIš'’N˜ц‰%!JŒV‰€З=5•ЋьЗиФ3k2<~9§3ВƒNћУЁдЛ†ЄЛ†ўйбDМъ.&јвiАЬЊccc4јД;зјt<ќіoqфв<Щ%q}Vfд"€лžђ€Z!Чџj6+Чѓуџ&‘R|х^lт{џ„ udk­ѓjуЉkэ­ѓрМtКзo@луfiOЮ9˜UЪщƒ „`O+_В&qvhааФЩ‰—/_юоГћђїŠl–Kѓ$7–DеY‘! D@‹EnЕ•[{gWЛ3GЭьt'xrk§Ъd2•н(л~t;J /&TTTl<ИQ$УŠ †C@cD‹м6ЋYЙJЛ~ l3цrљп8t…œX™>ЗюDѕЊrIЃѕZХЭ6+—ОІъgх}<Л> гЕё„Ђ>~:Ÿ6œп#fГ‡ЙЪƒыќЄЯŠti§.ф6їкTьtсЅdM3ЭэmOбuU?ГUDбЎК:оc3осNž1%>SэѓЈйtWwТшЃїЦ;GВKœ“Zѕ=Rј_•њЉЇ–“—уЋЋВВ2fD жЅrD‰š†${Q]Y’’їyž^Ї3~вœIDUQ^ўћ?:ŸwЋk >8fIŒW;/лV$uBЌєЧвїоzяєёгэюгG/ž=rмH0ЅЦДЋNŸ:zР ^БЩѓЩЂ."Еr:…br2h7.*nзЩ]rігŠDХ\Ž/lДЉш„ЭX”xџV~Yљёбa“цMіТh6+—О ъgх7ЫЋoўZM–ёњђ wсŸ\zІyюrюФ/НWer/?.н[WpёЇŸyЇЗŸЙ6+™8]­­BЩ^Є$ІрЕaУw†ьуй7~КqhЯ!RqзЦў:уЏ†bCцбLНЗ~щœЅЖ С‘д —7!юљ ЯЮвr7aytRwщДјЧžьo(4`l@џЅ/лЁSдКdЛ)œ^Ч]§К$ГfёхNUWWЇОaЭ&Cч2” еiЋш%D' ћLPз „Щ X› ЖхD<а9€чШ$ЉQЅgЇ‰oўffа”в‹ЅD?ŽД.hлL7ф,ŽB1Щє:TЁ-Aы $й љSКŒД;шІН(тHЋ 9XСъјСуa3ТшY‰МмМиФX,{‹ФЌФ€•YыАЮ­'иэМf$ЬРє\НaМН :№Й@TЎ~~хRйЄ™“<[{bЧєџЪљ+ъuЊ”<љѕЩОCњBићхкj*:||`ц‚™Xњ;хzфОFЗ=еЯp‹‚#экUW_›ENзZWQbZ5ЃrефЪ•SЛ28ЏкS ]УЉцrОЫЩќ*“ЮЖфу#у#ІG`vfИ`xИ{ЇŒeTИ №bЦ™yeyрШ%ЉЁТJzNdьЭ0~:xxђќdZ…’™n0ƒ€hj&™^‡ъQI@ fВ9љ9І›ІЭы6УEŽБяckŽаc^C oщ{ГЭтДxћM•љWЯKИьТМТ^OіRUПFшјбяаwЄŽУїYвЌ$њ50&`ЧЦеwЊБƒ@QНNU’wЙгЇN /є,ВŸџЂэ0eHDЮ>A79>юЌѓќљ+=zї ж‚МІТОhOk1оеЯpлGкЕЃЎ‡ЇЎ ‡X ЖЖо\ХЅjOOћ‚*|6™Н›ММјАiь’иЃ†ЃЪ8l?Вн"рЩEХЭџs8•]Kє€#—Є† +ш‘Ь‰ƒŠФYƒPŸщFN5CDа&„|РBТЪБЫccCg`MСi!qсqaSУx—}—л§ўn$]C•ЂМЂ SEрш@auщ€чвVІХ&ФЂ]хџњMd~шЌ]Д6эcо`•[ЙБќZЩЕьЏВ!Ÿ–”†NbZ"h “Бœџ:яв­ О€U*T)VtЖЈ[n˜ђ хEігK†ЈњКEыLхІщ‹љPВ_ЈŠвnЎѓЗ§FAa{MiG\BАЗ=ea'ГrЙcнjеФѓL™ФuхХ%>›LgТЅ„XHP.>[<7t.fgA pxљэrzR˜ћB.I VаCІЗФЯyЩN‘L70ћшžЃсhЈZQЏ*‘Мd‘оЪ>шd|і}фёGŽ}~ 4ާі'а­MZ;wё\I%š1cWЦšMц`џр№gУ;uщдоЇНАщЂгEИ‹˜Д)‰vJxVŽnѕЧVјn˜иДA ‡HІЬ]::|єсk‡Бƒ@QNCУј”?§ьгТК іћ>ъЛtув§Yu&цЈ+ЧЇjн_'№Чяb0ˆіlEw‚ХЪЅ/™•Ы…ur6y>яg\§Яъg|%вО)9juёiO“ШP‚WчС!ŒЮ‡G2cтєyуІŽУm.Ьz№–tЕ#IjH­:jkЉдS+^ч/2нф~Ÿ ,{MHЇŽ„S ИщGєЁ#шЁeкГm'ш›vFМA˜—Я^ž:j*љŽсkyФЃФŒФƒ%‘6Јуся’эXюБ•г#Q еђT§эеK:s:яў}ќFЫ.yбcЂeэJaEIzЭ€5ПVHžbL†C€!рB<4hГcmю@Т]0жЖGћ’ї)ИrШї›a[I‚c:j6џjїjYŠ‹!Р`8n{jуЧ-А`™Yл]dŸюiЪgЖІ;a"A„й\Ÿ+ПЫЅ/L ъ„я=Ы-[H[aDs@@юЂЫ№ЮхEЂ HђБnšdо(ŒЎЭЩ›‘о!ЄgжЅЂJQ|Б)ЅАм˜ˆЯŠЭf+џЧйю*.œИoRŠяД™ ˆG%ПЈ;W’Џ\Xr!Ѓu>ŠHрY…я Х Й{n\7хœШС~уњ ХйЩц€€мE—уЃЯЂМHIО\ОЇщ›Џ§p-ѓHfіwгЯ&ЊDўзљѓТцНОj![AEK3ІЕpхšЮЪ9n_ъ>сNvдНeМe,+Щў(SЅžУйћ‘щ)oАƒ@*•™XгE@юЂЫёбS’Щ2HВ­ƒD’|OўOњѓыЗіDоЈу‡Ќrwж Ж^р“Ф=„|Њk_[БњЃе‡‹Й5]™х htлSГXyMWЭcу‚ъі™‰„ЧК2м ую|šШ/ GLЬ‰РСžћ|–[Ueц$‚№"|ёКБœf‡Ё)o$фЋ! wбхјшКм ‘ф#пгЦхЯžЧъС%PЉ‘| љ”7u“й6Ъ8ЭЙ‹.ЧG—ы ’кМHr|ф{šЕєЭUЯЎТьйШ†?lY;“OUflB‘с3f|ŒЮЫ;lПО6лš=ніФ\и§ЁœxfM†чб/ЇFvаi8”zзtза?;šи_u|ЙДV–."%Ÿђцv%іДХi(Кп™…" wбхјhN2/’_.пгш у1ЦјŒEwЊБN2эRМf|’‘ћanЮёНP*Уˆf†@Гš•уљёƒ“HЉОђe+иФ іў ъШжZчеЦSзк[чСyщtИ{ l{T˜ыёфŸ(1 ЫеB~DшЖb­2ђЭуЌмE—уЃзry‘$љrљžЬssrzдА(юnеД8kr%ш‡7Oћ4-v|Ќљ?fˆ5œY/аb‘[mcхжЮкеюЬQ3;нп žмZП†2™Le7ЪЖнŽRТ‹ nЩА"CР.№0"Ы‹dbLиб"ЗЭjV.ъ­]1њъwаHЋˆ]д +2 —# ХУˆЎŠ•;НнЋWЎ–••Йќš1 †€міdГr! ѕа{Пп[;ЭP‹ЎЈ‰‰и‡›•뇓f0nˆ€ЎмЎ˜Е1rUЛNьSХ`0ъE€хі”…H}œНД” UmјœW" Є:ЈfOпЦoЩъg' †€`Гri0еЯшїfщ–ФјfmЋ†ЂиHп%3ќПТя7Ъ}fЬхђП‘жЏ=зЙЩeœЋM{4X‹ ц„@3лS§ЬкіЂЊЏлбЧГы:]O(щуЇѓiУљ=b6{˜Ћ<ИЮOњЌHЗеэbŽі^Xћ] 1kž! 9ь iШеЯЪQ_чСћqlЦ;мЩ3ІФgЊ}5›юъN}єоxчЈО%ЮIe­Žк?>сH‹•••1#bЎ—\wDIуAKПЅ„цххППёЃѓyчѕїщГ$+ Т*LьiеЎеС$^NЦвИћЗђ/м›4ЏЮ;œД#jdhsBл ЁєЧвИЈИ]'wЉД“VЇ ‰”O­"„лœ%#jК%Еpх˜скхu=iW}н›хе7­&Ыx}y…ЛњO.=г|Ё„ук{щНЙ*“{љqgaЋ™žЬЕ™Ё/…І-MгЌEЛ"юLфуvmќшЏ3ўкg[ѓsfZцв9Kзe­ƒZЁя3lЫЙiЌГТ8iїPЖсLо™ЬЃМ+Ÿ?}~ЧЎ‡F†™ЄF†6'В ќТc…ƒ‡ !g'­ BД Л :EŠjls–ŒЄ-“ЉбmO—јq\QGкU_з№Mх†“мэ}уŽЙm7я •>œ^Ч]§К$ГfёхсU]]њFjPї ~!H"C?{” еiQ.Ї р 8& s_х.—oUKmPЅgЇ!тЉˆ Ў3ƒІ”^,Е­K9hE.kmHHˆВфTWV# ŽTЁSz­єјСуMnyП•Yы>3Ћ‹c2>#aІчДwт.—ЕywxtȘЯq>>0sСLЌ ‚Š “Б­E9'П>йwH_ыЗ“жQM8Ы~5zTе"ЕИэЉ>юь\ШiзЎКzЫкцœЎЕЎЂФДjFхЊЩ•+Їwep^ЕЇК†‰'RЭх|—“љU&’Ш(H’Sr9epЖ №bЦ™yey ёжєOSN~NцсЬ‚уj•єœ*РBЉ†тУOOžŸЌ`ZБ+k’(KŽЇ—чˆћ>оG›=цХ1рƒѓовїf-šE—чІ2Mˆ(Ь+ьѕd/‘С‡іъ?Є?œЕˆтљѓWzєюAј ЎžЗљP'cЋйТЙЫ>uz`€xсf‘ј~Хљ”!ЂЕхјД9gйЏFm”ніT?Уuю%qЄ];ъzxъкpњšHU[oЦЋ==Эиеї™†b–ФzеlH"SoEЙœ2ЈЛзC4@­0%­Z=ёIёp4˜W†Я?їэ9ZзіїЕBЂ[aоBє”ІXЊЩž2-dїцн–$ЈwЙняяЭЇљ(Ъ+Њ0UŽЄ­79?hж.Z;ѕ|‘хYяnx9BФ$E$—РЂф„QNrMдU#SЗ†ЕTtЖЈ[nД rBd'.^l>X’—Д5ѕФз'шђЙr|ЋvŽSc›Гd„э2šЭЪЅЧ™•ЫыжЉ&~œgЪ$ОЈ+/. sС ёјДM9eц†ЮE@‹с/П]NE„=^­ЏE›ЄZ=dR Е№цЪRH”C­B“`!Nљ>ьћШућќhћьOЌ]›ДvютЙТКM‹.:]„Л‹I›’h—‰§Чru~єєZВ;­ўи ‹“S кџБ•­˜лZ„ƒ@љгЯ>-<+g'd|ѕ]Кqщў,>p/мфјQc›Гd„&1Z WnЧ зЉФ‘vI]ЙЃаЬœMžЯћWПХѓ†њ_‰Дc>Nє№ЙfЪŒ„І_єрF'|<ШA‘Sfмдq†BfI‡Џ–sЕ|Š™R)ЕЕŠTъЉ—ўKхs0EiЙZЎа$XHиг#іlл zчІtКzљьхЉЃІтыŠ„кiРНV“[џ…П^9}qвЖ$лЌl;гЖN™3EЮњ^НК]:w‰œёH/qpЇдШШщ?ёе‰>}шY;ЉŒмZ ’|5Ж9K†ZШn{кwvтUбІ]Ф3˜§ц ьkилю зLеlH.Cыїюл;{S6М9вФЄ%Xљr9ehEB W“Яjkђ‰ЮЂЈRАЂ­?UH”c+ U’йsќќ+*Њ ™†ЖmtОYІЋјЂЂ;*‚ZтЮtЮЖœѕKзЇюIЗѕуљ_чыюгћѕѕйOБ:ъ§еqХБƒѕт(*i— ­%$pKЙьвџОў„)ggRlXФпЛ)sSp3ƒШЫёqж.льЃАGŒІд„xiЉqGfЧŽXЄMЛХЙЉГј)sr’W`Ї\”ьŸk&!-Ь? !GОyњ‹ЃDlСл ’пHЮHЮшвЕЫФ9цXžA–Ы)#R>}оt<СbQћjфбЯ,jЉ˜J=T^’PH”#)/™%’_žИьЕeВ7Hжr[&ua„ п7iѓљян ƒ&PГџяa>TХq§эЃПОђхлС‚o–мŒТgЁfћ$"јjd fk[ў7љН З‘хь:jhтЌФЫп_ЦЯ&Lp‰‰r|r–еиц,aЛ-œЦmO–EШб10Ќ’{а—ѓаqзŠѓŽx)ыm пХMр_пЈWВ) РЙ4ЁЩuSDXйцє…щѕx(8*XYŒmГС`+wТUkяЭЕџ/ЋхЂUN@с!ќјE$п kЩЇ.8ЯH†€8~фИ0PюL…л  …+з&fm Љ6эюмюU~ЎДќлт )|TЙhk$сtьк1|p8’;{{{гпГrТŒЯhјЕ'їфLУВZn‚n{j`q“о23 †@ГA@`aOА4›ЫЪ:Т`Д\илž-їкГž3Э +oNW“ѕ…!РhЁhсЪЕyОлі:Н]CњЁЭё›mRЯЁњЊЏТ$› ьт6•+еќьdБrћЎЉюіЩ3i†C€!  ЭъmЯтмтТЂB!pЇЮœBБПбтWЅЉX‰–5E)GŽX3`MХЏrg%љ*_Š‘Ыч"Љ“1 †€мідТ•уљnЇЧ:„н 4ќјиќњЈЂm_ђ>Wс~3D5Є‹ІЃfѓЏvЏ–%­Ћ.W!ŸK]AVb0hсЪЕёу–Ю5h™YRїг=|žˆЦн!ХтLОH6П(ž‰fГЌ+пБzѓ'ьЏњЅ*р…€ј•ёXšOЩ‘ОАnиiШJЯК]vН[ю в’ШъQШчBТJШ;ьЧ^­Ж яжЇiaъЛПрЯ™IMХ'ž\хЮнК'Є&””–dНГЕЌЄцЂЏOТ"Б&ƒжЂ#„rСP€Ў\ГY9пэџЈя{IјqпЄЎєЇOЗl|ќWЫ)x№ЯЛYmЎ6о2ЦмˆžU2_;вw\<{!ѓH& Ѕ%ЅmJн4gй|8ёq}D‘F zt^:Ќzˆ=їnЌcR/JхЩАЂ; @ѓ4СЌ (4ЉрkЫUоЗuпьˆйЯЄ}Т_t“пД\t:0eњђѓ/…еЭА мідТ•k:+чИ}Љжьb€clœDШE&2'2ЗŒЗЬwLй9йœЂšмЙi;гHц‡˜ј˜ЈсQpх’­ AIь€=XѕP$CђЙЄ}l]вV$РŠюƒђ4Ѕэо„ЄH0)vyЌpэЩиTK:'dDBŽщи•‚т[u.nб7E{Жяy'чїщГЄ)" …+зtVЮ™ЧЦеН|H„и <ж•су*Ÿ&ЦƒI,4КrАчОŸхVU™•]љѕ’ыЁƒB­:хqUHаƒ|.+gЎDОQоЋZFЙ yšhZ>ВЖmЂр‡Т\З2eWš(C›;ѕ’йвашЖЇ–ГrФ@$7bƒ№h+'Ю{№š9˜gq‹8qJ[лЊ\—КdфfѓБI)ВЯe§Ђ5I™Ћmѓ(жc']†ЩгDОwыЄRgТLœœ˜№З$Щt}ъt0)†€љйЃѓ вvVо@Л'žY3фЉмtkuѓ]$№сяr~Кчг3с[qЂъ.J’iАИа—BSцЅрW6>–˜jmw{bZ"ЊДoзЪxЭшѓАUЏ…|.Л7юFоЖp+вЅѕЛлTмkSБг…—’5Э А'X(uѕГrTгy№~›ёwђŒ)ё™jŸGЭІЛКFН7о9’]тœдвјиЈoТџЊбЏ&k’=rаUVVЦŒˆСgŽ(‘S.фгяaCе•е) )yŸчщuњё1у'Э™DЊЈщ5$%u‚_њcщ{oНwњјщvїщЃЯ9n$˜ЦRcк‚UЇO=`PЏифљЖkБ9оn\TмЎ“ЛфєPƒa6 …Ÿˆ‘cSб kБІёў­9 ЦG‡Mš'XтCибніT?Уu.ŽДЋОюЭђъ›ПV“eМОМТ]ј'—žižЛœ;qХKяСU™мЫ;сk#Y“ Х†ЬЃ™zo§в9KЌJВbцкLЌŠ#yЪЙLИ-ъЙЈц”ФМ6lјЮ}<ћЦO7э9DNЉьЕЄNИьИ qЯOxоpо–Л ЋоKЇХ?іdCЁћcњ/}y)5ƒŽД %…Ч  BAБйжr9ОлфъЪёUчЁlУ™М3™GsАŸШ;ƒ%цisnBh`Бk†ыD\iW}]У7•NrЗk<і;цЖнМ/Tњp>>zwѕы’ЬšХ[”;…UЛRпH ъв/$gSЫP‚TЇE,Т—љ ЎA “АР0lЫ‰x"$ sЯAŽ›xЋZ"ƒЃ*=; OEu ˜4KЈлжY“Bў’b“Њя№З ˆfi`"k’­*dMјЬ@,‹ХО‘5щ|?Љ$­+$ пVї є§ТДEk+ес`9Гу‡ЭрWХqЩ–—››‹еŒБƒ8u€˜ЁаыzэќрэŒшбЯ4,й—GЊ\ЙT6iц$Ќ‘‹гџ+чЏиЊrЄ]h;љѕЩОCњ‚pP­aMHчЬ\0KŸbЂdw\ХдшЖЇњЎspЄ]Лъъk3Ч!…PE‰iеŒЪU“+WN5юЪрМjO)t SHЄšЫљ.'ѓЋL:лRŒ˜й™с‚ссю2–ePс‚Т‹_dц•хCsмdЮ,8n™ФQIJzjRŠ?<ЉŽ„ЕMГ&СЬ@‘5 |L—Ш‘D’dMRPЅ&k”`ўž“ŸcКiкМn3\фˆћ>Жц=цХ1d-јї–О7kб,N‹и!щb=ЧЋч­_TTTMЏЉ0ˆуGПCпёeяГЄYIєk,`LРŽ;№UŠŠТZЖДНэт‹ѓєЉгФ =‹єд|ЉL‘ГAаMŽO„„;ы<ўJо=ˆЕ $ЏЉА/кгZŒwѕ3\чіп‘vэЈысЉkУ!–‚­­7WqЉкггО  ŸŒfя&’ vIьQУQeЖйn№фЂтf„џ9œЪЧ.ДdЋG!Ч ‘Wа#—ъˆњшЦЫšD› XhВžиаX’0dZH\x\ид0оeпхvПП;m7ПЬlQ^Q…Љ"pt АКЦ4ŸўmeZlB,кQўЏпD4 WTЙБќZЩЕьЏВyIiˆсU”LLHLЦrўыМKЗ.Ш5(jKXl@ЛEg‹Кѕш&ЪŒ!вC/Ђљы­3•›І/цCЩr|ЁI”vsXм”‚ТіšвŽИŠа"Рbз з‰@8в.Љ+wЌkd5ёуњ№ЕУиA (Ќ%Єж.хO?ћДJ=H?Нtув§Yu&цЈ+ЧЇjl“Ћ+Чo$РŸDЁDћ?ЖЂ ЙЁбmO;fИNEХ‘vI]ЙЃаЬœMžЯћWПХѓ†њ_‰ДoJŽZ]|кг4”реypЃѓЧс‘ Bр˜8}оИЉуp› Г|€%]-ФHŽRЋŽкZE*ѕдŠзљ‹ЌIЙпчТЫ^вЉ#Q_Y“VN_ŒьwjВ&сІб‡Ž _„F”iЯЖ wnкёra^>{yъЈЉф;„Џх?А3–м[АЗуся’ЭЎ^зVтџіъеKXЄєщМѓ‘cžˆŠє”hpЛ'О:б'аКмП=rk‡Ъё›„Ю^НК]:w‰@ т™Ы!Ф\cšЭЪмЫ‹ `і{˜зиз<АЗн ‡‡ЩX–g-m% [яОНГ7eУ›WоЊLKАђЋЊ8OІЫž№kxш­V\ќ—фИс•оЎ”ЬqЃRP/ѕŒ$kяaяђЩсЮ'#Y“„U$idMZПt=В&йњqк„А"`с;RƒњENљјWTT2 mлш|ѓ%LыЗKmр^ЈGїfqЩpсђчoMо:љЕЩЄ]{{-ДvдФQˆе DŽ–Ѓ-_QнzuГЦЪгw HkQ$м.к*ЛtХПЏПВ§Ињ )sSpƒШЫёqЖ^лфъЪё[чАаQяЏоˆЫŠФЈG‘>КЩБці"ыШЌ\ЈG™.ОШMХO™““М8хЂЄЊЈзЃрЉУќУєїщ#_‰<§…%VОрэЩo$g$gtщкeтœ‰s’ъ гЎ]Д!LyўGОHyН9nTъЉ%EГ&ѕд/jp‹‡›@ПЈI_žИьЕeВ7PŽЦuI„Р €Е1ЯEнўЅ zЇfІвt€*sEIъФSф7О>8 П2žєtСњыцЏлБfŠНz-]П”№…ЧЗ›џM~ЏСш d9=CG Mœ•xљћЫјС„/ZŒgвК_mruхј­3xB№Э’›QCјЧЂЦD‡ чъwЋэž›%%Я‡*8}івяsЩ2DœЕёЊ"ћЕi7`X%ї /чЁуЎчёR.Š,Д-тA:<>Œз1lOЕX\q‘-Wu<}aњC= Ž v•Ќ]„Y„ ІE€Х%~}гЌніо\ћџВbЎ\ДЪ ЈЭЫ7уЧ,"!xnјис‚3ŒdИ уGŽ х.Гƒ5\ні$ЯдgŒѓЯkгюЮэ^хчJЫП-šт‡>(х:йБkGќvцээMŸЪ 3>C@№ыO iгkХAДА8h"ЋЮ`0"\`бfv,ъ'ŠЎjзжЦa0Š‹•7*МL9C€!Ра-\ЙЋfЧЎjW‹ыЦк`0ЕрЖЇG-нˆ5{’Dд{лMй,в ,ЦeXgђFГь†[ ЏХ†M  нзТ•cvlЏWUАX§)Лк…п’БZAљД˜yЮѕцЄ-ісTРœrlXК љ†ЕЋб"З.ёу@ЄэVЦпƒ§Уsм=uЗzёХа'{HO~ RМb^o"Р^~Q ”ŠсŠЛЁUъMRАп‘a‰СёD„‚rѕ2IѕАXЙVљЦп/™~/1џЎ$T{Ѓ{ц‰Ќпg]2Ѕі<ћЫhh–ТЉE ЉК“ZИђЬŽUлЏ$и€v?ќяп? уЗЁјїЃ%Њ<ИШ,ЋЭЏAz˜_‹ƒпюrщ SƒzaЧkаЖЋZ'/w'N\:>IDATЙЭЩ|^ЬыБўЊb%[,WЃ…?`ё,d +mR>#\‚Йp8 Џ фЕ†€( ’­Сf€ВъЌIuл,Nрч?eиЄBц&aв2[aЂGIх” Bd<^KvчNЖиЖ{лS|•#џчžё9ї€ьwЯЎї єЙЇ‡ї=]u<ЇaRљмИnЪ9‘ƒ§Цѕ(Ъщй‘Ољкз2dfg0§l‚иKsџКѕэ­TўƒД"gFвѕя)Ÿ.A€„ ШO1b€ТЕeA’4X˜JR@Ш”ЬтГVDЧGМ’‡DпYRGI лк/д/ЄEЦcСє&”ТIи‘цMГYЙвѕЕ+РBё Б&Ѕ @Š‡ГїЧ.ч3р№ГѕхБШь#з^юЮЩ^pж$ ‹Р@Ќ•H&цX>єЬ‘уc'•ЋЮј.G@сZ“,H–1-=„ ъэ В8ХО5™F0ZbтcОиїЉЂзыMFѓA"šџSNИоVˆ€­ёHсД{ѓnЫOЬšNcЃљ‘щ)œTvЊ™‰itлгUЯw“vхŽ’зR`9dg€…ќV f6›c“-k^7–лfР‘lZ˜Kˆ МєъK[Sј‰9ВєNœ3ЯщУ6wE@сZЋТ PѕvQ.‹Ry ЋrдА(Xl!zф„ыm…ияЮ)œTvЊљ‰iё0bbжNšД+w”l№ ‘П#Р"ј§їњуцфЋАh>CPЉ‘|ј 8usƒ …љЄ?eIЪ8|р†” ˆЁŸЩПїv"х3Т PИжuЦ@m$Ѕ.д$"пм’OCaЉњŒм [яT+ЗЎ„fјёЏ­@#аrТJЮINяЏлˆЊHсД`е"NR8ጘмH~(Ј#œˆ€зЮЪK§,’ !CŸчЖ%•Š’b`Žž0Й~јь3wЊБц-‹Žў`нбsЃizŠЎE@”2IсZKfAR0^.­"—Х‰OВsOшУoџЖˆЫ ‹ьЗHлќ‘4оmS8й˜п"ьmOёeF€EчС!Ё'Xtžœ—N,`o™Я”˜†еkQqDш…l‘˜qsr:~swЋІХ о,ѕрКїь‚$2і6ЭфШWЇO9 ЙиЩмSсZЫeA’ГP.•—Ыт44hhтфФЫ—/wяй}љ{ ‰МœАШ~Њ\DШяђN";[xQ‹En1+wIŒХЎvЩлžx?–Iўж ž+їѕфщmЯzЧ_BtТѓуžЧ/йz%™€{"аЄу MкxїЮВJДШmѓ•лœW ФЎ"8n—ц† убрВkeЬ7 =V‹!аrаТ•л5;v"єvЕ‹ѕU0яVhН1`QhЇ0!ъв­KвІ$e1v–!Р`hсЪ]]СЅЕЗ]эЕђјcwџ•ёi*g›єulвЦ7•тИьmOЧ1d †€ыатaD{gЧЮBХUэ:Ы~І‡!Р`ЈA EМэљџлЛ (ЎtнTЌЂQ7rWбфт &ЫЪ5ц17Ђь&ˆz% Ћcб(™H5Ђ!Ф@%‚˜3йШЈЙы#ЕqЉм˜G#ЋБєf-uЫЙ"=uIyџц =MїtOЯЃ{І›ПЋk8џќч?п9s8ѓїщѓ)eDа5ш+ЗwŸ<… 4gКЎGяИ5ааH-ІrЗv’јwwыuЩ"фCлP"ШрџŒ@юБmјЖЇ“іoёѓЂЗИ8ƒ†ў”ЧЇ”эfПр.СїЮ}Ў(­0—šгГ/B.'ЩpУEр§ј ,”Бп›q‡ЦфNЫ…3ММQ"0Ѓ.атБ'ЌŽ]кЁ†€gѕŽлJ n…Ж…†вжzЋŒАЅЮRИБ>‰ trC”–б€Yˆ@р#€,Bкї‘F=§Е“ФГzoЕЅо:>•љЏ‡˜їу˜Ѓ™7~­АcЬe…–і0#gœT–’™6<Œ;}д™ ІщђЃ >I€5Z‚1 D<т‚ В‰aСхрЊ\ˆUPœ%ш‘Oш?ЖвsлшЌ єsџJHФ kў†eФЌoPтЃ]ЭЩž9 ч@XB&ыт=р~WнШ" М]њіВW–с)žкc-ІrЯVЧоcсYНЗ.dнњ.ѕжчOœЩЇШ­м’иIБ™аАЭqD-) ‘Ÿњтдє™ьщ†№ aHQЎ%uВ!‹ПЊF=ннIт+8HНRŸRЕДW8ш4СiNЎ[[ЄФ…щ9/х,ЙєЧкЃ'EsyЭЛ›Џ]Н–0ЪёœRrŠx'йrЂа-кГ9 ъл‰,BяМўЮŽђ@%˜П1ђЃ“A†А‰…)В!!8шэј_ŽO˜<јч@ЧжЕ[‹ЫŠe•aІZє ЕєГz=[{oЉWъгЉўЇЧt„ 5…™ЈЛBЉЕo95ТDбLЇSaч‰ƒЈЂэE%Y%ежjЛ@u ё€х+ юKђХI‹aвЧпЁЮ1дg*В!‹ПFЎF==лIт=(длК,єаТ ЦйAЏўGађИ ДЈ )сA“яuЫ`>L}:'HЉ#ЭGbˆсцqH„pЬФHwK- dт6bq­Ы lёWхnuоCл;ТBM#‡P#{WхА$gWх=юЌЪ{ыƒ*­ [IеюјpQс"ГŸ™]ЗЕЙАш+*`сA!}uŸСЌE!{‡Ё  чЏMГПX„ 6р`s`Ѓ!YЅъБэК6^€+З™Я"ЄбcOџњЪ•C’0eЛ%Тˆ"€Z8XШэ[ыnНђ,Bкл5"ˆ" xьЉХTЎ‹U9žzЈdФ ŒшзЛеЕёt–~‹hёŠ;I|ЈПъѕ‰ёЈ@хh1•ыbUЎ2”DD  @nЯ€ъ4@@_Й8иBбХPнM1!еMб!гMQžWНР!Š!DРрж@ Ўƒ:5zьщюN_!чVН•ЙЕ.Y„4~4Šп[_ду.8імEЬяђш+Зw,НЩ4?юΘуoя‚н„`ш“;ilвŠљ+ЄN-”DA?7№бРА ПаBy“dьїfь‹PЦ§2Ъх­Т\Яаb*їзNъ…I|љМЌЌyЉC@їьн3|дpђ (И\ф!†бЗѕkыУё6ф–Ш c."`TEHћžешБЇ.vА€gцёŸYў›#OtZў}VDŸšїдеKWнz(в/8wц,лвД2ќЮ&ыю“[Ю№жНжŒ‡2’F',Mzњтщ‹ЄИЭf+Ё~ЬŠ›<5œ<_9†UB@м_2н,B*ѕЊхРUЙ pАмjМЕyз›­CТЉя-l”П*ч “иКl U cюb2Д2b%ф'-Yк‹sл>kЋо_mm?іpJт†•ˆ,˜ћОиWџзz—Тѕї—LwCядZПяПїu\юЈ1“#лО>]}ДОхR‹›*Nѕ]§'ѕжяЌ4Mз”зRы—­Я*Ь:|ЎЅТRбі…}H8л/UЏРј`S№ДYгšпoцф!X-ž§ЃЧG—э,§0Џ~§ўЖ§–vmFЏ„Sу3r2ъЖU!моšНE‹ˆ*dRЉЯХ4zьщСNŸ7UЁBиЏ7ƒЇхЁХПN}&.Т {ZИЕЙ=№›ј№ФO–Ђ•пјІš&˜Э;ЏvVWp:Ќ4\КTєWЏЉ€pUЌqш‘’Чtп" ш/Љю†JЁwz{‰эІФ93\š!5BИ‚Љ‹R7НД &Yј‰vёзšз’,Аa{zcџg—иЯ)œ›{§zЗЕо6”ŽМ7’!?LЩ'ЄwМ@FUB@ ‹П|хnBяyRА_n€Ї…Кэ_?0m•эЏvS"ПЏ\Pзь?Эў№C@+њoЁi“гр…(+кRєїџ^ѕмYЙqёq\YТJCЖFp‰2PH M‹MЫŒЯŒ›7иЅ;_FfЙ€ ПЄКЧ=}”61-44”хtuuIЎ\кГi г<зœ4&ЁdYЩcI‘,”,,IˆLxkЭ[ыо~™$J ьч” RЦЯ_2гЪMK ф1Њ=№игШ,BnJX„†g—фWЏ^х–сїЄRџГŸКБ;аY„`-V0ЏрНжїмj5 k€ќoжяњTзЦkаЙ~Ќ‚Я"fйWюЪdE “8)Х9ЧyŽrvйhWэКкЬч2™_и–831аЬC{D@ĘЪСWј>–МъТ"s:ЛY,Ниd }%/ї%j]ЧiEŒŽHOяfКЇ%Oу8к Ќ@ƒs{К‹ВЦЇeЙkžSљ”ЬИfab€  _я Јkуdhc†=uДƒEаБD@|ˆ€Спіє!RЈ @@FWхм;h"€ ŠатБЇђgžtЫ>ънWњ>ѓEцЎїсі+"СUви`ŽпРaщ7шRБF=•ю`Бй`7хlІ7… Ьќу›Ю7ГщцЭbР™uGЈaіwЬФЙюІрwЩ]ФP^pXjВaЊPeUо~А§ыoОцcєй—ŸAєїБПNŽцЇѓУt~l№и8њоб”э IЇ#MTЙ•6qЄdkwGU!Еj:Гн.ЦWaxљэWп>yт$„'ХOZђЪ’ШЛ]Lњž=ІЧošљ…Рoђрaƒ˜Ÿтe‡Ѕ—œтjq{Т<>Гˆ=єRp5oh–™ЪAиvЖэJ~š T'/Юѓ’A8•"я?ѓ–—dЏ~k5ЄТA(­9TУюцХ"рќЉжКkпх+ьx!~A@•U9лxХІї‚щлщДnЯюџ'ВЌЮ Є~щŸ*ˆнqњbqЖ ™Dwoй§дsOMOЗoЕ†@GГЛbwСћйЭРчВч=ь;5Љг жї€јыы†зj?и} ћЛf'–ТyаЌц–Gт@уЊЇћЉ‚œДgвШŠŒ|’Џ4œE_\:wvиЈ;ГVdMOŸюдBL4 =Tc­ИA\4 XЅV—[-GA,%5%oMїЖ5KаaЖ+TлСг1ЙС~Xо ['ейAнИ,wƒ@—фђчФЇ'’f'ё+ш‰ONp)J.œђ­@VCeэљяЯiKгжŽВЕ“щ>ЙЅ™S~Œ#™0e‚јШYAc=ІТa)@Ѓд=фЖЙМnЈ’ ЊGm0GwuиКснЩир†tіГУfуœчBp?pЕ№S!ЪЬщbJОАпЪСН€џОЋАHЯYх|GSОr Ц7wf,Щpй:i†pXКФTsАPЬЬvuм\~˜Ј^ЦzВ›…џйЏ˜ЌЏл3`xi1TЭў%b/ЄH\сУТ ‹П>‚hјЧaџœг€…G †№­8ћрсѓѕ8rћ‡€РхзпйQО#фW!љѓ'?:Й>ЦŒ‰РёƒЧGнФ:.›ч1ЭK—иpЕ{ЌLŸЏ\–gѓaEа]ч)цК\ЧаaTxЈ”@|тФУN[ьxv бј)ёœМSJ.WŠo˜_XОžШœЄ8р”РE,†)C`oХЮхХJх1ЭK%№pе|х}И&хїѓ\ї%KќbЂ†‚…ЙЬ}ƒa†HNЉ ŸЯ…ЇšGšЌР|7 К№……\}N)QИ\)О•фyOVЌЊва чЪy ‹SN3 ‰<ыІ}Ÿф[~Ћ=ІТaЩ‡УNшѓ 8Эє4і~УЩ[HwЁжђ6ŠЙЎ№^VdЮЉЛЅ!4нmwЖ8г5тЎ•Ў„}хЏWB>ь+‡(5M(Qи,ГІ‰љ\€oJ9ЫO—~5nl–9‹TВ oAэ†J`П…,йv_9!aЙљѓMђф“Иœ={vь=c9g6bšqxїwџєЌR8…ИЂЄ(Ѕ §АŠ(1KуŒ Д{‹НlœщХTлЧдхЈ_zЇr1(З…PQTму›ГЅ^r™’0*ЁхR‹K1@ДD‡Ѕ–hыЎ.>‹F/ю+?ƒ…6šџGѕHьQD3C"@Ь‡ИЗŸn'ІЂ*DР{pXzсРб тcO>ˆJЯ`чJёtћŽІзђ?.Я[Їi•X"р –ЎТќ~Јт+яWE)\•ћаa"0@>zј‚ЗО|ЬEдF‡ЅкLПъ;X/X• 5l"€ …€SЙТUy@с‚Ц ˆ" #ĘЪqUЎЃІ"ˆ€ _9РЇ6‹{m6<ќƒ9 пXl Jh1•+нСт?!—рт—Э%D(рspдљR+Te*ї#‹МX_ПЕциЁpQјэƒ'>:iіЂŒиcНьBю$[/ѕ`q#!чљTm<љй)hдЄbЬVђп+іОЅž:ќр=ђzд ЪTюGЁ5ЯЎљ›‘– 8јАГГѓ›–oъЖеm{›ћmpJГ NI\]ГьlЊi*]RZuЈ*РmFѓŒŠ€*S9 VпЩˆГќыЇжіcСС,ѕЩdz$љИЙЮsЪЋ˜ТцЦЊ=?^И><МщDSАЉ—9^YъДЅЧЇCJтн‰і%’ˆNˆ(wЊy…8ф 8wцRеЁфt 8ЅЇсuрР’НEHЬєеvА№™ƒјaycНfŠy№ўŠ‚Mэ_ЕлРѓоџ’ЂbЉЖЏOW­‡ЩЮиj~ŸЅЫ „gЬСЭь(ІъMl8§еwР1d§ЮJгtMy )ŽМBЃ~&ЬHhЈj gpBЂђ-E!y|0зT›ЪyфAZВmмЕqф#ЫђЫRЂS2юЯЈ]W +k фš_6УГВgYj-іŸ=”ЅЮ23ЋпДS:!)ЭШ+фЭа ќВРH]ŸxW"мьXm–ЗY„фёС\oPЭСт'! l[№RмЪХѓїяxoЭГ+ЫY_Й dqЌCРѕлЈу9nјœ0yјмљј:Ѕ’вŒМB|шŒоДЂ49=9}q:4 |х%#MЊЅШ"$… І{€ZSЙПX„јˆРММИФœHЅЈXјE œ‘“QЗ­ ІђН5{‹6 rв IiF^!z‹žl9UЖ{ч+OуТWŽ,Bе,ЄГ­˜ЛИЯjвp[ƒїœX"EХ"ши„иызЛ­ѕжАЁtфНBТFЇtBRš‘WH€­СЂcbЦ8|х• •o ВЩуƒЙо  ЪЊм,B‹V,њЈюЃЭ/ЌЛіѓMXAO˜_ZUJ’bУ7Щќ5ЯЏyЋщ-q–S:!)ЭШ+$аH)Eл‹Ж­мжА™]ŒЧ$Ф”n/•oВЩуƒЙо €,Bо ‡e@!СеПj>‹ДF•UЙ%х'#њ…EH`-F@@Y„ЁtdƒSЙв3XќФ"ЄЃоBSШ"4pњк'-еb*WИ*ї‹OpD%ˆ€o@!птixmЊя`ёМrУ#l "€ј-Іr…ЋrџЕ#ˆ" _ĘЪqUЎпё–#ˆ€. _9р…,BК4hЄoРЦ}‹чРдІХTЎt‹j,BјU˜ƒ[я­ЦqЋїдв~-Іr…Оr:?6xl}яhЪv†@@GšЈr+lbњ Ё{U…дЊщт/0єћсшZЯиX*0„H чжиЙ2ŸЬJ#‡ИIz’ьйИХž`­џ2ZLхJWхАЏќlл•ќ4Њьq*}?м—цјЫ }ЭP0ЄGšЌ_Ж|Yџ);•ЏЬY1њШєєщЊе†Š9ĘЪЎЪСЬШ28ЮЂ“Њ ™ы6ШЃ/gЫˆВИ™…Џ6V6ўtщЧQcЦ—_ИxЁёѕ—.ќ8fмиЂэk#яЖŸŸх”H ЃCяZZД”œ Кзъ\LхШ"4РGŒšЭА,^ГЙФЊэomећЋ4.љЩфхЫ[ЕV|РFЇЮNо№тR\†oШЅ~8œ:unмјqЄНјсЫз,s!‹ 8˜х%ZLхЪWхЖЎЊЋУжХяNЦ7ЄГŸ6ч)ѓR._Иœ9…н>;#+ЭХіŠB!у џЕP !…­Ѓ—3НИƒjћ˜КќѕKяT..y[EХ=оЙ9[ќŠXS§"€,Bњэ; ,ї‹ђV!‹rЌPви ‹Бћзч­ ,‹­xК}G/D` #€,B}ИйўšЪбaтfпЁИ‘@!#їЎ m А,*ДU"ˆ"`xp*7|cDРјрTnќ>Ц"ˆ€сРЉм№]Œ Dу#€SЙёћ[ˆ †GЇrУw16@ŒNхЦяcl!"€џG…ЬaY„IENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/1.png0000644000175000017500000006765511733011756026170 0ustar sylvestresylvestre‰PNG  IHDR1BSQРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxэН \UeіџП‡јО8dѓEДrб.”S”o ™—%5дqгRSОŽ&т•ЏˆЩ№EGM­,k,5ѓ–š†Ё&‘IScъaTd~)‡з_пџкч9тжBHVиrмBIЈЊ+жщŸŒT!ш.МЛOEe­З)ќОРŸЋTŸЪ~Јhя}УзлRQђП>kК-ь?UFU$2$pч‰ВЫѕХ†ЬќН§˜CђЩVй˜R™i…ˆгЎ№ьY*œЬггћ№bгЉ‚њЌ}_W ьјёЉђЫцPЉ)Зр”p›юЫ‰‘ћ{›јˆДŠ@ mHxН„%ТіlДЏ“s;9O€tŒTу<™vцlWOя\ІсS CR“$Ђ‚щэFЃ! ќ‰№ѓeчFs§зшт­|ЇGq#5R’OъЋсYnbљь‡jЊIњQ):QR!жЄюС_П!щ|YЙx.UяфЦMгхК{ЊLbHєиоН†U&Щ PН™%kщjcйrC‹М эЋЊ% z f/П0Ѓ3dЌ2YўбŠЮФ?Єа"ѕЬћ@hЌіoќh›Š?3PH…>јlџfхAСXQ唇ІЋ ї шПYJЅ,x)тXAj˜z дЂkщк%(8˜э^щ„Љ}­ЉжаЮчТMСВ‡Uі!ПўfЖЂ]ЙЕ^Њд{ъѕEy5н" ыьу#а§-*B‘=„Шž]Hyў#-vRBƒЖog0UћјЖkO2ньЁч$|НтпЮ:$…”ш’ •Ѕіэш9 ‹7ndЌЫвЋЏяОBLЬ Жgч’L‚&.ю €€ћя4nx‹ѓw?g9оMxНLЄ{6–‘tЯ#ї /gmж#2ЏRНдƒО1ЕЌВ§VЕŒУ oйЕMеМДЦ’Дн0–—§TV[WKї“ш$щŠёЪ•kєНAЊ_GЄІФ›ІhалЗN8uЁ:Аƒ8ЎќR§}…x†DЋeŒtЅЮФЯH!ъ‰Чш2уИpёЦейstŸI\Œеb№нDHL‹фw†Ьm*oyчФГУp‰7nИћLЩƒ#УMwДю0<м%pтˆAT}ЙЖB Щ}”Й V;bЪпВkвƒ:*‡yPBo‹ZМ ‘Ѓ­/kpАIяyR{ƒ!АЃх~вc=цWсїMщy§ЗЛЅрX-ZkS+ }ыО%ПЌ:ђAПŠKеІл7.з•Tд†tё9џ“XЄU8ЌG№ŽС*=ƒ{ъь ѓyЬкOЪч ŠЏo,ВкxЂ2Јљ(=н,ыєС)ЃŸ`ЂN9/ ЄЕГџЊ~ЛˆТ0рО‘ VA -PпGб)Bћ:ёрUiGlNѕUїа4GyhzЄІ,”Вр‰ 3$rAТ"їЅд—lЄ5IЛа%‰KxxИX‡иKDЛWClSБЙ–o?ЎЉм>YвЧpо<"ЕŠŸ~W}юЇнЃљr™сЏя•=a г S•аОF|ИРPпEєJ6TЈ b№ЃжЏЫk_~§D7яѕzj2З7є’z0X'Є}\ёЧ#ЇЭ%O €w!ёЇЊ]AЯ/ˆхАN|œ.ж‘Q} fцАХhА€ДEц=Вв.ИQВтоCЖ№]ЙLOЋ ;tьIbАКЙž;SЄШ™†оuf!ЉIБQ>Їяw Ъ§oTїЮ=–{уъЫW/W§ЛJј­`ъzHИџТЭ?б5АF]h…МY9Д>ph/o_gЄjЇд—љП иЏќж;ODЬW*kЬƒвглэН І:S}nшbvAџf[EеТмZ%’e{ѓ?ЦŠнљfіz5–Љ€]Ј lяЭk~§vA4\Іƒ#цP\ЅЛG–ЄоЬQр @ 5PпGБЌФ=›ќŠЙ…япšђ ЅгШ›ІйAƒщpмCCГ­’д­ФGТ[eДgFП[Н{Мx‡E9 I/&’K­ЅІю†џяЗљњ™njLПоИЇcW:ЈњЕŠО}еtЯeџ(ЊпU}wAўІхEвFёБ[‰Ўтх:ё9щ"V‚њч­IOgHUD\ВXwсtBcВВg­в^R™ZЉЄЉ]‘3ŸrQ+С"Ш<Ш›Б аVиМ‹ГЙ#'gПюЪfЧ -Щ\ЉЧm5I0• ?VUб…ЈЛ|Пјљш€Юqтзм™їЙ5ІУYzЖКІІЎЪtуџЛo<^§ Dc-­IcЕjdgWЊ}ьЁ–& ЕвкХ‰{\жWСƒVGž #=pЇ6 zГЇж…|шІj’ї=UWšЈ&]Йсп~hA]]їЊщl2нmМ—Џз\ЄыU‚gЋŸ;ђцТфC6НоTPM{€€8€§ћ7w№`?ћГАŠAВћ—ˆмЬїЎ@сЎљЭUЌс.ё)}…СўмT&а •:=f-S7ЙJQhмOjВ; @@РщьпПЙƒћ1йŸ…U …Ш ў{—уC`Uy…P—f•%*cUПTјшA‡уИДр @ћїoюрСў iV14д$Ћ&Л†Лќшk[/§hљі'§О| ~дWП=,A@ … иПsіCГ? ыМй ж іk(\zйя@@РниПsіSЕ? Y ђѓЄЊЋт— ` рwЃЏvkT“Ј э"џжœˆ C€€x&QлЪЄeЩЫ3) k7$€šф†!€€‡@Mђа ДA@Рэд ЈInЗQ€x,ЏщŸ&{lђH@@Р}L/пkqЪbї ‘€€x,ЊG^тїЫaW zфU}“џ<ЋУСј  L€ъ‘W­Љжƒ uw!@ѕШЫtзюмe{ №dTМФпХ  Ў&@ѕШЋй?Кчъ 1>€€@›$@ѕШKhўOСЖIH @@РХМ јo   Р xэпћ>_  .#рkw.cA@я']ИxЎ‘+   ртyRžМs {   #€gd@А   р:є,ИыЧШ   Р м!рf9   Ў$р#р,Щ•ќ1v›%pКшTyyy›M‰€ ……†;˜„ЗрнГGя#yп;и/м€`)<2Ъƒ ѕЖOрд‰|JвбeЩЧ{аŸeЂ&Е§љƒ [Ž!QA kЙ!1Д8рƒwМОеб5IќŸйO‚€€€5њџ$ќw’5h@@Zž@ќ^№аа–чшМKJЮ1ВЩЄš4p^„ЭѕмbЁ6w цк77ёАhQ08‘Ом‰pс:+;kс‚…%EEŽpцж>к@IpО(NюГ-Is x w4ЗKіДs‘ОД­эпйяA;BзЖ–žџ12LсiЫЖ—ЕmuЗэqpШ|ЋЌЌtˆ8–&p‡žpАmчвв™З’ёnемrјAC+Ia‚x"ЏВЪZ o:ž=x№РаИ‘НBЧO~От‚8(;ШЅwщбюжЭ[Ђ‰ˆŒZД4НЖжФb#ƒн{v‰wVz5К]ЄшСz цDбГ4wђІиЗВвјђ‚…Ђ(ЊЩsЊЋЋyTї™“Š ?Žю§ф}œ7ъЯ<Ч†™lrhсЖА<#3z@НH UZГSг+FNЦM­–ЕbпQq#+*,yQВdC iHЯф†wЅŒXыŽїоŽŽ7ёђŒt–)щYВЬ@9цлТњ 947ЂGэ~oяBЅ}™іЎ85)ћч=•"oFтмDЈ­­M~9Йы]Ÿшй}лkлјЕ5.0[ОjМT‘0%ьЛuŸ_}н2хШ`лылž{" “љжQœвр–ЈЧЯŽwwєщ§Dз €aƒŸ.;з;P#@ѕШ+ЌgˆZГcѕ_ямВ=џГЯ<5 mХ*rЮЮЈшŸZэиўvёїчіэ|?џHЎЏAШYŸУc(ўімЮЗЖ—|йшЮŠЕВЗˆ”žљj}ЇЮ™5yьИТМмќsЛwэЖf}6яRPTА}Ыцќ#ŸЧ –0kцё“Ч6oмL9Ц –‘ЦЬє Н~SNееЫћі зхЋ—i•њ*fЇІwxжŠaїъ{Жј,Х@{ЩХk–Бƒ†SХgIЯ’хяŠБжтЂт}џx?їрЊЋ7жoнТЛ0Aq\jкњц–sџМ@sу“НЙWЎ^!юPq 5џМ—bфњч~ЄТкukЋ~­њцЋoŽџВ А@кЄ(~jтдѓЅчЯwОћн—/]ЬЭЮ|sци‘c•—ФЋsЏfЎЈКZѕЭЉoާђиЩcм† ~ їю;|Оь_1БЯЮž?›w.$@ѕШЫєk­c#`Ч­ќ;O;ЫЏƒŸaтИ1Ѕп–pНTxgџž”d‹YвДYс­ѓ’fљљљёU Aq ЯRWŠ}їюивѓ1сƒO;CbBтЩЯNђ.ѓцІtЄЄЦŒsы?ЗЄЋЅg,9ъњPюС”й)” -ЏЬN9”{”ЁSPŒ\Яаф_пˆˆўgŠЉЫМ§ОоОyyтЉRё™вЫтдШˆgJТЁЩ:ЊХМgџЁW’SФ)дЮ0sF’Ќ—тЊт@jўЙХШѕ'Ю§H…=ьYёJ*лОЉЏЄJ›хЃŸ ыцCK;ŸЙѓцJ?‹-&?Ќз;ь!oФ„^+—­ДvЅсgyњђРšК> /&”ž>mнhyTџГќЄG–O;Ы‰ірЗъd–еыП\іL\C›$:њд5ш5%Х4|  аb$ћзS} sпиЎПќЈ{’ЗиуyоќysfЯ‰ Ї#tКZкЗŸмЛцКžЁ;vЌМddћP:vдtЉЗQЯаjОћR­НЏЫН'Žч ОaНТ7nнxтЫ|вА’,uЅ‘QуL;K{‘Ќ8.щ;vцe]дVЙНЉe 5џм‰bфњч~ЄOЗˆXYЊИTС›юєшVЌ†пЇ$yRтЄєДєwЂпЁѓЄк›ЕшіоE*tў}чŠŠ V–ЄnЙN?мИœ€—k#шисЮŠK ЯL—Оj)эA(ЊŠ хє˜C“сЩ<Јйлр™ЛЊЉЉ1ƒvH_Н†ыu z†6xxFVэ•hYš•AЋкЮ[ kЕА{їыГ2k]Ll E34fхЊuЄБŽV#ЃŒœlsЂе”ђА˜aВОjуЦ=3lifнЧЊНiЂ‡X/mŠЉљчaЈEЎ3qюG*ФЃЩЬВN—ЬъGz„m}m+•%cЅqёТХМ‹yЪЈVQ%›Лp.зЫ„ИgуШ›шіzuњ’…ВVZещЧК#4 р*ŽЏIќNДK˜”8&~"Y2Гј {іш9)i*=ž7IJtџhэюд*ѓ foƒgюjYъЂu™ыBњ†NJœкГGwЎз)шzцДDџЛя<*–^їо}/­j;oЌеТŽ  K‹ƒЂS„ƒ&9*<Ъ:ZŒˆсˆПŒ<<жП}ћ™ ђLеЦM˜œи§n#Ц2jФ=їмУFдц 8šž‚Zф:ч~ЄТм9s§яђќБЧŸълЋч“=яєЕ4fНšѕбсъі‡Q#†Fєр]rВsRЇt 5bdФ“ znР„EЩ‹ќл›нFѕънї)Y+­ъєcнpп\)/˜–йoђђ*ЃБъjХо)СЎ уz2zЪ_іPeыЅAџЗ ёНр*ЦїEС­7ADD€ЮЯщ{СGЧБ“ЦЈmeўwwЙ\tрњП.м”ьјѓ$;уCw$@џ”@wqкvт+–­А\dK[8ьљЫЖ;В§P“єГ‚ЅГL|!aЪs Юђю~щG9{ѕэѕxјуОэ§щRž{…(@РэИзswn‡ЕBѓVЖШP.$ўЙxzЙlx ­„Ю“ZЩ†B˜  рМшkЧ< MЄ  а xгзŽ Ny­DŠA • [GЇNф?ˆGX[ЩC˜6 ‡юhЊлдUЋ“7џŠ-+Дш&*ўф}buї€!Д>TиTwlшxЦСБ<с DєYuЦЧpA ЭР3m~#Ah5МшџјZMА@@ M№ЂЏkг "9VCРЫў]Беl   žMї“<{ћ#{p'xюЮЖbi+N*/oјaАЖ’ђxМ$pgЌ ЭHzйƒDl `M`їЛG?;кZЏЈйѓ*щў?8ORЄ %иN€Ю^œY}OДкЮ=]BРTgв?oGOˆп§Ю‡з$мOrЩІЧ   аЪ д9%~wЉIќчЯ’ЅЇ%ХgЃc†ДX| .шˆQйЄЄфьа#эїЃьZ ˜„л‚У_>ј ЂO5НЂ1”  J€ЪŒўykуGЃ‰nюR“šгљЭYВ2Wd–бP­kџž•ЕpСBЙѓ9)Œ —зŽSЙ6€~аqЉРДe-}?ЉЂЂ|ѓ–Э' ПЊЉЙvџC!г'?йЯ-~,Ѓєќa=c›к…ћwцE&~щ'-ДчmљрљˆЃsgЫПЗttМYgтiў№m‰t•ыЙ№рЃ!ЂžEтЖ‘ЙšО‘V@@“@]­іDmмЙЖёЊcжМO—œuŒ'^*/ЇN{qЦд™ѓцІјнхWVVЖ§н7нЄ&нЊЙЅ#w4#ПУѓф˜Ј5T$} tкЋ™Љщѕ + P‘iЦDrТ§$ЊG^‘НУZlkdoйЖr•xђЃ‡2г—m|ѓсУcПўњЛдљЉЄ,9WFЯХ•–•оњљ~•ОЁГPC!fЄДиX“)+ІWЇ˜šЌГ4Y“tUqТšžїU4ИhМHЧ1Ь†O9оХ&AvТВа‰цЙ(ј™ч37у‚PRR–ѕїЌвRщДбенwЏ„А… |кЌ–L›њVэю лЫм1И›ТчЂ~`ќzUѓТВ IDAT4[ъgZНJМN@ЗTХЋВ&~wŸ›:BhбkwГЇnлЖ•ю0звзЎмЪ~([ДdЁvУЯШЪ/ЦUW/ЭЪ UfЏІЇGФ'VPSOpТиИєUKйŽІтB9йhЊжЊцЇwП>+ГжХФЦPטЁ1+W­# sRSSc0>эявWЏQѓ,г+fЁ–ВДoЧwV\jјъOћSKY:(—eЃsНTPLMj “я4фэЛЈ,біšЕВVЎšёf›'ZuFNЃл~Ж<уp[<=с/Š“Щ$ѓЪъjzбФ3Œщ ]йЅrnOгF CƒЁЂ~кhwчўуЦЦ-\ЕДт’‘ьЫЬSu$ьeхЕЗ“љsС‚R|"I•$Щ4ДъЄЅEkюlоєкБТ‚!Ѓb#ЂCWgЌњг?i'6sZЂџнїKЏ{яО—V™Нš>КяYЩ)}CГжЏЫ\ЙŒЧO˜иГGЯIISщyМљKRЂћGkЊжЊц'*<‚.Т Šп4p0ЩQс–КZ–Кh]цКОЁ“Їіьб]ЭГLЏ˜…ZЪвО “ЧФOфћPћSKY:(—eЃsНTPLMj “г-јєиЇQ§ћKœд;ДЗЌеЋtЗЯџ.§ФхˆПŒэљhw:?sвBг`ь_ЦЦѕoпžeЃФOJœ?14дr‘d‘yк„і j5mЛѓP'šЇњдЄЉQНBS$SАг}&rИn§КeѕŸ о Ип\)/˜–йoђђ*ЃБъjХо)Сю"— SэЉГgоѓЁmЃгџФOJ S.ыюЁЁE…т3œX@Р фЮ4tюРL><аЌ{1ŠžGm+ѓПЛЫхЂзџ§sсІф=OR Jpы7фдо4Q-ЩЮЩ6рi7‰ a€€›ЈП9ти№œv…ТБaТ8ŸР=їм3dдˆšКš§ђЋjv +џзьzWjњњvќ— ЩЉw~ъЕkf.ЈIЭѓЖK€ЎBи!Ђ‰ž&А^>?љЙЂокhybERšЗ- ЎнЕ$mŒ   EчIZtа6 кБ}G”њзhйр]@ ˜шoъ}Ь;џX.Mu‡G…šфpЄpшщиЏAг'жгA џжF€ў)NџМЅ‚ф№>'`ЈI­mж ож@€>ЋЮјИЖ†д#иEї“ьТ‡Ю  $€šф@˜p  `д$Л№Ё3€€€  &9&\€иE5Щ.|ш   р@xюЮ0с ,шчЛЪЫ~4\@ эРГрmo›"ЃЖI€ЄI/ЗЭєUл%АћƒнЃŸ­3П 9Џ’ЅУџччI:љУ є 3Є„gVгWbVEРTgв?oGOˆп§Ю‡з$мOjUSС‚€€›pЮЗЕКcMт?“ъ&ф†&UR|6:fH‹Цт‚CРКЋ“p[Р Z*3њч­s>{юX“œ“)МЪ dmШЪ\‘YR$ўьЉgд 9зЎ?ј№ƒЎ Ѓƒ€pх§$њ…щЭ[6Ÿ,ќЊІцк§…LŸќ|dП(7aDБб~ў•ИПюїdшЌ—fuщfљ\њ)в-on9єщбыП\є§яŽO>љфИБуТz>&‹œіђlw/гЛЯjщљyиnЊћ@г oж5ќцйƒ†ќ№m‰ЌЏЈ‘иШZэY=]pzг[oљњњьп7yю~9!WфАоZиКyKєр!‘Q‹–Ізжв&/йolN˜?|xЌ^$аъkolfvE_ц'MK ЄU >2:jCŽМ&БKaє.Н&Іœ”аt<фDпQq#щ$…šїqHCz&Гwi„в8IоНgза#Cz…2Kk\кCTV_^А0b@ž‘<‡ŽФЅуЊЩВqYx옏’ ˆBm[s4['šCъШmpтP)фбц„ƒ:lhDXШјqу+~ВLxnРЭHX›БірСƒ<’IУW™А!gCXя0šМ4?“f%б “Ь€­VTTœќтdќ„xYkС—Єду'{cіŒщ3"Ѓ#iИ€Р€Х‹ЫМaЕ­pЪY’ Иь<щdсЩAъ?zV№UёЮ-лѓ?ћ|РSвVЌbu§ІœЊЋ—їэ=@ЏЫW/гЊЖ>yс’щг^*K]ЊЏW/^ГŒнSХgIЯbГŽP$Е{nч[лKОwdŠсi1uЮЌЩcЧцхцœлНkЗ5ыГЅуjШвq5ЬQ(nkЉЕЩC6ŠЅ}m”ХЫwѕ/rСe.p%ХPXАѓѕљЧ‹ –šf1цЌ‹yuюЌЙьћрФ‘<ВЩ;’G2iœзrъЫSЁ=Q4ШЮЬ~iњKфU\ъэщ8љЋТЯУ{†7hЬMj~шsqУxcш€шˆАˆE еVгХ‰7Ш­‹€t&д tTd§jиОц‰у№7—еЄšызќ:(_уІ$SчЮЂV:G™8nLi§…јCЙSfЇаЁ-ЏЬN9”{”сPггХtу5:LЏІsšХ)ЩЬј§{R’-Ю“ІЭ:xєˆ5гkVБQ0зЏ_c–ыVguЛчоU+R#ЂгљФњ 9t‡Щк‰ЕF1)=ё+§}#"њœ)І.ђіћzћцх‰ЇJХgшШЗПuHŠšyIГˆ0kR O{ˆН;v†анЕ; >э ‰ ‰'?ГдrХБЄJщИRНLVDЁИ­Ѕе& й(:$НЌTKН9\NŸъз‘&МЯФqљ„WХ[ШZЕ2kнжЭызe­#YуGаш”keцЪW–ЌЖvuњєщЊЊЫƒ’5•œ+Й/јŸv>RН†њАќ|хчї~’$пзр›О:]кrЋ&PrF~дZу№]іŒƒo‡Žt ЏV–|кYі‰T–nб†yЙhМаIМbF з™ЌІЯ^ЛfѓыoЎпАоџЗОs’Fі '{z0aи3qЌЃјЎ ЃUlj‡Y/ке&LMЄ­в5БЗўёўœХ 7d­c­яŠIщ‰‡|ъяоѓБ•ЋФЋ 8”™Оlу›oаЕЧЏПўŽіzБI›ЄE1<э!ш 2+;ЋДЌєжЬїЋ”K‡уВt\ЎДQ(nki_ЕIB6ŠЅ}m•eз6dЋЬЋEщгŽVEйЧG0OxnЬ…{??Cм3УВs6ПВ€бшЇAe6ЬR g§чЅЅfЏ^а‰>Mr›Ќь• RJєƒТ/>ыгћ ‰О ?яМ3yf’9~!љЏ/F ]!шi–@ёЧН4š*%gŠBzX.у“,NŠZїУбуїш›w,wtм§Ž;vЄ XY"ЁC ЅHЈщƒ ~еМwІ› ЉЉKє е!АsюлЕwdФџy"VŸшлшкkъв%(љЏIQћqЫц zтQѓЉи—Њј}]ю=q<п`№ ыОqыЦ_ц“†єj~4є6 1oўМ9ГчD……SёІ+‡Ё}msЇЗ@}YЬzюH)nki^j“Djу`ЙўXЪтVЖЪД\Щ‰^„pГ1ГYХ…ђ=њћпж­Ь\е;ŠЈIуЯ;žП.kEік"#^lБZJО§чј‰/p5эwиyс_Ьž5›wiвTY.ц/6вp| nM€ЖецЃ‰AїVХщ!kтwєš’ЫЎнЭJœКmлVК_]K_Сr[(ћЁlб:jгZ† ž‘•!^ŒЋЎ^š•AЋЬZMO0ˆwћ \PSOsТиИєUKйCtєй&ы!Ї&NкКm‡[­‰^$аъЌчЇ2ЫIгiO1аjхu#=ЙєH0k';мYqЉщoсдЕsІQылЛ_КЖCf1CcVЎZG5'кz†ЈЉЉ1ƒv oкўеZя4фэЛ>ЁЎY›ЁfЦѕŠлšЗ’ 6IЄ62йЎgn‹'&ќEžЙЬЎфkтЋ Bu­ЉђzuКаъЌ%)щЫгУћE-\А№Џ чWп6qŸLиёо.КЌ—ѓZаƒСВ&JŠiшСОаˆ$“ОњІщЇŸ~ ўуcњ§<;ђйЬѕ9д‘^™Ыи lDЌЖ"|юЩbfгCІ$cg,.;OЂƒЛЭ›^ЃЇяжўofMЭ­G y~ђѓкЮœ–И|mЮрQБd;$–V™Нš>КяYЩ)—ЪџyџdЎ\ЦŒу'ˆg?“’ІвU)в?ŸP—5›пЛt zkѓkЯ^Ж.“ЁO†в*?іТє7?иЙdхŠkџЙж9Аsп>}Г–+\ЏO˜”8&~"]ПвО-Ё'IhDЕОQс9YйƒЂ“ѕ ƒ333ЂТmќЧ/†X–Кh]цК—~™CpІМ0aџ§‚жЗ’ЖhAквU[6fwј}чЯMй8WЛŸтЖ–vQ›$RЇЪЁЁ– lњ79м‚E V-]EЖuў}ч)ЯMЩ5CXГvЭ„q џ.МWxљ/х9kз$Ї4К\–‘)VёИgЎQ~ђsƒŽхSХЇy2”žƒe‹?ƒў4шŠёчЃFаБHПш~њ/[ЦРhLр7WЪЫ#Іeі›ММЪhЌКZБwJpcЌ4=L?)I7ЏЇЋ­3зfv} ы˜‘ЭИЂюъ1О# фЮ4Tўи‹њІhж§EWЃЖ•љпнхrбыџўЙpSВЫЎн)%€€ œiк Э `29ч(В!РšI@ЌH.ЗTМLПвУX@@@РХЈЙьЙ;ЇŽсAРi‚‚‚vlпЅўеYNŽAР.&њя—›zЯRђхвTЗk<ЅЮЈIJT ;А_ƒІOЌ>а\@€ўЏ^џМЅ‚ф№>ЇœQ“\Ас1d›'@ŸUg|\л<7$xs@@Р] &ЙЫ–@  ЈI˜  юB5Щ]Жт@MТpЈIюВ%€€jц€€€Л@Mr—-8@@P“0@@м…€—јырX@@@Р р<Щ 6B0№ъвХё_ь Ж   `œ'й ]@@œB5Щ)Xс@@РŽџ­Š’se6Ф.  ­Ž@Hї`ЧЦьјš4pШ@Ч†o  юIРXQсиР_“Ђc†7З%€ћInЛi€xд$лфH@м–j’лn G5Щу69З%€šфЖ›€€Ч@MђИMŽ„A@Рm  &ЙэІA`  рqP“›Д(љZхЕ’Ђ"m2o mљAYЮК…IђИ g5ЫXC=68МгC 6юOРлс!RAš1Л‰{TВ^e5ЩC>HYВ2Wd†ѕ|ŒhЛd‡х№­ь*‡­šЄS7Н‡оЙjтaм#р%д™œ2Xœ’L/ЁЮь^ЖZ?Єє‚}bые • Э­D*=џ#+HЏЋЮZЄЈм„Њ aИI)е&eл6НNJrxз$dДvоNЉHT%oc;ЃCЇВUNЭC>HЗjnё”!иC$ешсэЅТ“Eл7n>Sњ=sВcћлХпŸлЗѓ§ќ#ЙО!g}Žд9—‹‹Šї§у§мƒЊЎоXПuKƒўлs;пк^ђЅјмšЋ­on9їЯ 4Ф'{sЏ\НТњЎп”SuѕђОНшuљъeZх> О*оЙe{ўgŸxj@кŠUЄgWlшНИхњM[Њ~5QT[ё™s\Џ!ы˜Є4™л‚ЂkoвxXЋZюдJЖoйœфѓ˜ЁУfЭ<~ђиц›)˘Aв2вИs5ТЬ`ъœY“ЧŽ+ЬЫЭџ8З{зnkжg“ОYa0?в.Ln )2}Ѓњž->KіезЋЏYЦ_NŸ%=)#фЮеi  D Иѕd“ІЬТPќ P“ўУ;Еt w рФѓЄхщЫxјž$ЩЄсЋLаџAђѕѕ5^Ѓ#ьъ€€РХt›ЪММГOJђ,П~>>†ЄiГ="ѓЯVSfЇј™}tˆлЬKšEjЖЊцjЯўCЏ$ЇˆCД3Ьœ‘ФŒхф>_!ŸЙGЙЯдЙ–x&ŽSњm з[ д+eЖ-)IГЌ Ќ5zІЅБY;БжЈхN–ѓцІt$МcFЙѕŸ[вев3 йёe„йX{wь Ёч;ю0УФ„Ф“ŸДށ4a(кK•M’‰ˆш_pІ˜КШляыэ›—'ž*Ÿ) = :#”ŽHВЦ4аЂ–Љтd“ ЊјA §‡w2‡XЗ"@Яне:< клЂЯХЉ‹љ­’LYYjєAR|А^™НvЭцзп\ПaНџo}ч$/ŒьN>Џџrqи3q ёз7hЬR@Ї@І!сКё"oЅJУe5Wywn|бx+e>}кY|в~ќ–ц9Јш9 !0ю\ChnРŒы[rЎ,+;ЋДЌ”ЊšЈQйLa0?яM’ яљиЪU+ЩУGeІ/лјцУ‡Ч~§ѕwЉѓSIЉ3BYг@ˆZІŠ“M6Јтlp?I Ћ­”€З“ЎнQљсїш ‰'І‘–%щЉѓя;W\(яв-ˆЃ,ЛPFJЖќ`№Ћц} ]OOM]rјЃOHп!АsюлЅћ#оW*T^2В} дEкФe5W;ѓюмИs`GЎ4ћьШ›є Ђ“J#+Kф„wМг[ +KЌА[/МI*ш XъVкW&ЋЙ’™iЌ6І!'Fя–ѕz=[•~&<7E§Ы­јШРmёа5mщЊ c'0Kz„AМGMMuBMН“ cувW-e{^ЊgdcЅёŸŒœlёЊ_uuFVЦА˜a-kjЎтžЖ43ƒnBдо4бУЬzирсфŠљ\J>WєЉ­4;ЩfN(Bn|џЃ!oямEћntЭк Ў— jќД4_Y/ЖкБУ—,7ќIЃцJБЏЂR:Ђ5сššƒA№1ЈЇЏ^У=8< цY-о§њЌЬZCf1CcVЎZGжE-BЊЂ 1 ДЈEЈ8йd”?žўЫрŠЙ@ nB@х2Šнбё“!Q№­JœKЯ“т'L4мeH[‘њcљ%2Й?ЈгГc&ŒЫЬЃћїž•œrЉќŸї?№@цЪeLI]H˜”4•.†ўљ„—˜^іоГGї[ѓџjbџ4pfBЂЌ•­ЊЙJ˜œHЗВGŒKf3Ї&0у™г—ЏЭ]BРлTџМ€K†o’;_ИЃ ˜-v гyлз ;/ыцz.tђя){јс]s7ьн–€џgVOЮј щЁh’о5ip^Е7ѕ4ИžфёAвC 6 а$о5‰­‚€W~§#Ш. —>HЌ,с@Р~.љcPp п\)/˜цШgС\€ДmВgС]|?ЉmГFv  Э"€šд,\0p"д$'Т…kf@Mj.ƒ€8‘€}=нУ5€€ш&реОG@wВ0pkИvчж›С€€G@MђЈЭdA@Р­ р~’[o EР+_ншQЩ‚€€№ sу№€€€Р§$киH@мœj’›o „ D5Щƒ66R7'€šфцс€€@Mђ TA@РЭ xЛy|žощЂSхххž)rhЅ‚‚‚ТBУ[ xдЄ€Ќ5+Hј/1-Fhp5S'ђ)„(KЈI.одt†D џ%цтЭ€сA4 ?Муѕ­-P“p?Is; @@   &Е l    I -зЄаPЭмmi,)>3DцYЖj‹_Wє pіАЇ‹N?іD“5i ЇZG5НšŸЖ­o4ZEm{žИIvmЙ&9qж†ЌЬ™%EEфМ•–"g`Qѓ™Ж,mЭъ5•••jЖщБџВz€ћpAMЂ]ЙѕЫ%Єl(*Ѕч ыљ‹–U&gD^іCYŸо}ьїь(?Э„[zІt`џЭэоЄНУ‹œѕˆееекgxЏfОк§сює"СК;гЈйp>nR\н$ 5Œа{д$к•Г–Ъ­‚ћ­š[-чЉ'ž№Д§9ЪOs#суŠИZчЃkз­ђќЕФwППЃрѓOчЇ ЛппmmЉaУљXї‚<œ€ j’"ё­›ЗDЕhizm­‰йаyЬС}†ЦŒˆ ?ЎЄфlоЧyЃў<2ЂWшјЩЯW\АќŸ)™эxяmКЭCн—gЄ Зх#TV_^А0b@ЬHžC‡РdСN’ш ЌbмД‹Ќ#ЗQѓ …Ћ Ч?;ж?ЙСpЮ{IDATЊ?ЕЪ`љъ‰ЯФЂе5( Oя'ј‘ZЗНОM<КяdЙQФ§(к“џяю фgирЇЫЮ•БxŒ—*І$t} kз Ўё“тЋЏ‹ИhБі/ž<кЬ’f%еоЌefєЮЦeбв;-tкG'Ь`ї–=8?] §ЖзЖ=AЎшšœ’,дYuњ+KцЭeŒ4ЄgН ŽхљЭЉoЊЎ\~5KѕjD&МšЙЂъju?vєЫc'ёVе Ё+оС,ЄЇ-\ИxЁЦ^iiщc!–KИ$аjcтšЊж]#кТЯŽянЗї|йљgG?;vм˜ЯŽ~Жw7­ў+fфГ чZ69бЦЈИeiыPGѓVВміS CmБр—-]FЕљШЁƒДz№аA’IУštЯŒёющўяџў/hшЬ янˆљпѓНSѓЎ”—ЗиыwПћЋghЯSљL>іьУ<Ьd2 U&———­нkщNњГЇ˜ ={єфн™ }'??др_кЄ†д†ЧLJ.sAЉ7’зЏ[KЛfк |Ёе˜gbи*yцzј* єііЗЏЏШZЅЉ5ћ7n0&“‰xJНq=m&‹iJFьнЋgљOхЌщЦЕ={XЬЄуђ€ѓŽфЭќŸ™dМuѓVrИыН]$Я|ifўё<ШŒўw˜Й"Ђe2я.[хz.PЉЎW ’ ЄЙ0џь=џDОnіЛЦЌdЋ–hUlљА.бJЗ/]хŽєRjйXДХЅ[–ЇF‚ZŠГHк‘ІAя^НзЎYKя$Г&YДВUi№RWнM9кYЩv_YЅКCеЇчskЉ‘Cov!ЫЕ•љњ/‡=зƒф„ŸŸгћјHЎоЊПТCњ€NЬŒ„ыЦ‹Lця%чЪВВГJЫJo§Ч|7HтŸл †дLCЖп9Ї}т€шЃPгізЗgџ-{ХšўПѕЯXYџ]JтЅ~дь%<}8Я’3%K—--њІШ—дџЅђ‹Ё’ЇэыЉJЧхСаi_ъќyДњююw_л№Zіџf;њЋS'щЖ ГщвЅ‹Eшд…0ђŽ:…‹П\”zрНд‚$ž ПfХЮввгўЖr5ї (tќя;щTЯЇЕ’аёП;Z›Љй(ђaн5Ђ•n)2–Ўђ Gz)kŒ[VПZjГˆїѕыр7a|мвeЋVЏ"ЙAп№)‰ЉЯэ!x2oњК—чп!АsюлЅ“ИЙ!U^2ВВDy“uŸ7оœйsЂТТ}кшfUhп~2Жjі{ H>=ўiк’4воBmm­јI–=„„„lн&n8КФ?ыЏГО.ўšйKпЅ~єиѓО“'ЅЇЅП§эsi‡ћ‡nрMRЁУя;:ЬїьМI:.WR юЛ.ь| ‘§#WЏ[}фш‘ћюЛЅFflZqЉ‚<ГŽjщsЗ\шќћЮR\Џ$7 •"ЎЁїг1Уј*U,™5=ђШ#gKЮ†ѕ #™Zхі\PГQфУzщ‰–ћWЄ8Fniч–mrб ТmoНѓю?оЅOм ƒxф@& xŽгЄ‘Г &ŒK_Е”Ъ DO.аcЭ1#'›vйДdde “ьP˜ŸššƒA№1шa‡єеkИѓŽюЌИд№…мі‡ЁсAч3”ТOч ы!юьhyЄGижзЖRYЂл0‹.fJzЇg ш><{ цџЋсz.Шќ4iЯ;’`Цe jAЗФч.œ+m’ЪєXкЂф—i'HaаЮˆ† VйИRћЁO—–њ—ИП’оiЗѕдгCЙAњвtъK žЕœ4ЋЅЯ{q!юй8‹‡ыещKrНbМUQ`wVи;H ?Ѓї—ŒЬ4к(є"aмŸЧqWк6” tћvьаQмŽѕ‹ бжwЕќUФШmдЖЌЮ0дfK™fщєгщvяРЇfЏ]3}кtв№Ё!€€NnёŒCќ„‰thRвTz nў’”шўб:Ѓчf={tё—Бƒ‡ЧњЗo?3!‘ы™А,uбКЬu!}C'%N%Kоš0)qLќD^-ьУ~ЇП<нЗo_~w=ыеЌєPЗ?Œ14Ђo|Шр!ЯOзЕK@квДз6НЦѕ\љiвžw$!';'uqj@—€Q#FF<й0Јд†ф/Эшб{мŸGvН?€vF4)eуJЛDFFвеЄиБЄŒKrфS ЯqєŽш§Tп^?љИ{џ—“БŽjщKн2yQђ"ъјјc?еЋwпЇИbМеf!~||яа>бQбєънk]‡ДvЅh#уCїиЂEё2fДŠylj[VgкГˆŽ™І'Lgп&L“щYŒХЉ GQ<  Mр7tO)bZfПЩЫЋŒЦЊЋ{ЇkwpУV**ŠOСЙaЈж!эоГKњНрєјьC=џ\МЕeГ4ŽђгЌAЩиUу67NWй;•е6щYЋrФИm’тгg\WЕ­Ьџю.—‹\џїЯ…›’нт<ЉMnBл’:њщбЈШ(лњJ{9ЪдЇйUуъ‰ЭlРЧЖbpgоtœюЮёyZl_|с”хЇЙСИjмцЦщ*{№qyŒлZx=ќPk‰U-Юж{сN-#шAРИpg4tq7^…gПqǘ€€€g№šћ?Њћz&d   р*оІ:ЫžК*7((шд‰|њ­{ч€єAм™=tG;ЋˆАў aZ`( ЁD ,4œдю№mJбA "*HlgхlЈIЮ&мДкв-ГБ›  рRјџ$—тЧр  ^жП€'i…  -GчI-Ч#€h@MвцƒV–#€šдrЌ1€€€6zюЮџŸtКш§HГvdmЌUуIJЄбЦ6.вi-4>†­%…6ЇїжЭ[[8IЖ ž‘єr ыкс6фМJX?ѓэ™4\Л-0КЧPћz,7LмћіПыл’‘бRТ‹3ЋoVЗф .kє„јняьАЎIžIУх›x&ЕЁgвpЯЌНшч>н32D  рiМ:vіДœ]“ok†ХЈ  №1l`сІ’ї„БrNќмтб™№ПКц !@Рƒ xХOŠїрє‘:€€€pбwАŠgа.xнРKC ) Щ>ђУї%6;ГГЛЭуRGg mэгZcOЬш Ž"рЂšDс{м…нZ­mцq4Д`8ЌЭNЊvvЗ' g mіљрЃ!?|[_Њ1Š=YЗD_ЭaK€1š @5Щ‰N‘l;K y4„'дБУOFєK™а)€+нWPџќлLЃ’%р%|V?žЂВОбіПwkлу Xwwx„|,™`=ДдРЖ0˜Oкšм9ЄЮлИЌў1lу‰ЗžєМ[нљ пEVWWякЙыЏѓўњюŽw[pD    JРЫgIЊС4ЏСЯЯ/aJТчdншрqї{Л‡вУ|.U',_Б<КOНH`ЅwдˆQ?U0ћМѓ˜@в“|КрєјбЃ"ТB†z№УƒЌ•оЗnX= :",bб’EЕ&йис–‚ЭФЌ;вцЃщ $W^Њ|yіЫ}"ˆќŒЄtТmкFДЅЦ_ёS™… mёЅЫ٘6жŽwvX”š~фFЉ;їc!5)Ю s„Л-ŽURR’w№ ЭБњ€-3Ь(N6ЕјхУ‘ H@RW\fнйЊтшd ХЂu—šНјBоЫЇ‰š*•C‡DзоtЧ)яŽ1ёmСLРЫeш$к†…[пЋњZѕжm[C{сљuY40*{cі”&˜ГцУ5Žk  IР{з‡Л4 œж(юJlZъ;њјЦMŒиДEМ2Р.BчРŽ•Ц€NдRyЩи!А#™љмaИЏгН'ŽфМ}щыP7nкxтѓ|вžZƒЛП*V,ОЋ;5uЩс>!™О{)їэ~,Ї_т8’QФUЫmM;л|jКtHcчпwЎјЁМKЗ ю­ьB)›‰)v‡p˜7оœйsЂV‡ћД3джšBћіkh•˜ё^;KЗ8зыєЃж]є#]$CkЭ ‰™и[eUАј-_мЬ,шŒ\+ ХШыGбuеCdЏЈџѕїѕЖаоŠХЉ ‰HpYћcшz| ^‹в]‹/ЗХ#[^(яU}гДuчлїп?гH›HѓєрсKГ2*ЋЋщE­2Гž§њЌЬZCЋ†ЦЌ\ЕЎwП>ЌiбвєВŠђкл‚ЉNЈЉГ 76nсЊЅ—ŒdSvЁœl˜qsпЕлJЃЙ1и`їlмќi%чЪ НHH[КŠОŠЙВ™˜bGzИПьR9ВІІF Йi0TTгWЏсл— Ь’ЏќtFN6пт\ЏгZw ВецZЁl•ЬxРYУb†Щ д"зѓ&ѓЩckrtжQ-ю‡ђ|ТK›Зlžёќ”к;>ЄМеM ‹›/ˆДЎ%44”|чпњdhкЪ4ХјЇ%цЌЭ‰K­БCbi•™E…GdgeGEІеСgdf„‡GБІшўНщВў?ЫџљР,[ЙŒ)'N˜HТдЄЉt…ЄгМ”№г{Ш;Ѕпў.CъŠдKх—(хNA&Œ™;BЄJ‹ЭФ;ЦOJœ?‘Ўд‰—gЅ.Z—ЙnЮ/sш †.э?Ап<ІънsJ_;<жїЗО “ђх3S~дКKЧ“EhџмшйЃћиПŒ­љ5Б˜˜`™Ђ|DЕШ†ішЭЂ'{ мпyаpЫмрY@fј Ќ њsПЩЫЋŒЦЊЋ{Ї7ЋП ЦЛїьŠŸ”P§Ћg§~}чьwŽ“пћѕP6Ь›6з…ŽЎXѕm™-\А№OCžŠŠфжщЈ| н:цЖмЈmeўwwЙ\tрњП.м”ьКѓ$ЛАЋљ,‰ЧбhыŸ3љЕ•э~р№ŸўѕSTфJЗџОЭЁЮ­3gp]MrfVюшЛўЦВ;Ц†˜@РЁЁƒ:ЏY.оѓsїCwпBцlн>ШЖ ЯкТVthE…–џjpЈW8kE‰рcш‚љбЬ!]xž„щ!нV !Ѕ@РC ИЊ&™шyk,ѕ@Ѓžў‚x6жїнBžНН=€ДeЈI-Еuq^иRЄ1ЈРЧPЛ4Ирк]PPаŽэ;Ђžџkеs–ќcЙ”ИuОžIУš4 ад>†-04†аIР5‰ОhŽ‚ЃЩЁ3ФЖaFЕ‡%.KЧ3iШ `Z†€кЧАeFЧ(zИ &QXД#VмAы‰Иэй€FллІШ@Р6ИŸd7єp<д$Ч3…Gл &йЦ Н@@O5ЩёLс@@Р6ЈIЖqC/Ч№:џј .Чc…Gр<Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€S &9+œ‚€и@5Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€S &9+œ‚€и@5Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€S &9+œ‚€и@5Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€S &9+œ‚€и@5Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€S &9+œ‚€и@5Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€S &9+œ‚€и@5Щhш  рЈINС Ї  6@MВК€€8…j’SАТ)€€€ P“l€†.  N!€šфЌp   `д$ Ё €€€Sќџa вфOгјIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/images/8.png0000644000175000017500000013026111733011756026157 0ustar sylvestresylvestre‰PNG  IHDRZk.§ЬДРiCCPICC ProfilexэZgTн–НеhhB“sЮ9ƒ’sЮYr–$H ’$HЂ$* HT ˆ" TAP^Ёуїf~М_3џЦЛVwэuъд­Лъvѕйыь €€š[HHfЁЋСagяР 4@(Иy„‡Ј›™С)џa|} gУcRє`Ўк[-СіжЇJюѓЛШхЁМОџ‡‹ў„ЉТр™СЂЯoьy€нушчф`_7јЊWT{дЌд‡ЈЉcЉЫЈ;ЉŸSЇaЄQЄБЇ‰Ѕ)ЃщІ™Ѕй%ВUˆ.Ф$тyт ё -–Vж66Ÿіээ6нa:WККЫtctkєдєВєієёєчщ‡шW 2 і ё Е # iO2ж3>dќЪФЪЄЩфЯ”ЯдЮє’У,ЪlХЧ\Ы<ЮМЩТЬЂЩРršхЫ[V VyVWж,жжl6 6Ж“l lгьHvQv;іііч( GŽtŽŽ—œЄœђœœyœ=œяЙhЙ4ИBИЮqq}уцхЖфNтnф~СƒчQтёу)стљТЫУkХ›ТлТЛШGЭЇСЦWЫ7Щф—сїт/ццџ& $р(+p[`]KаZ0]АSpUˆ]ШB(UЈCшƒ0›А…pšp—№š—ˆH–HЏШ–Ј ЈГh‘шˆшO1i1?БJБ'тdтътQт тЏ%˜%,$2%њ%ОIJHњHVI>“"HщIък’іЎž’!ШшЩ$ЫєШ|••ѕ—Н(ћJŽIЮZ._n\#Џ!Ÿ п)џEAR!PЁ^с­"ЗЂЋт9Х%z%+ЅBЅЪфЪ†Ъ™ЪУ‡0‡ДЅКs:Ќv8ёpяс=••л*{ЊЊЊ‰Њ}j@M]-YmP­ЎЋžЁ>Із0б(а˜дЄгДг,з|ЉХЉхЅUЇЕЊ-ЁЁнЁНЋЃІ“Њ3ІKЁkЉ[ЊћR[ЯOЏQя‹ОВ~’ўА…ЕAЙСЂЁaЈa‡0в3Ъ7š6ц0і5n6о1б0Щ1™2e3ѕ1m6§aІm–gімœЧ<ШМгeajQfёЦRв2ЮrФŠhхjuнъЛЕŽuЁѕ+›X›a[Ђ­Лm“эž‘]™н{{ћ4ћ)‡‡GGЧNH'KЇZЇ­#ZGЮyы,яœщ<у"т’рђа•Ы5Тuиб-Р­зкнЫНгясъбъ‰ѓtђlіB{9x5zЃМэН}P>>MО_'п~$~.~7§Щ§=§{Žв=zt €9 <`<;0.p*H,(=h>X)И(јcˆnHMШP›аІ0В0яАўp–№ш№ЩёˆьˆхHЭШъШнcіЧnFбD…DMD GgF/ЧhЧдЦ"b]c{Г?>w(Ў<юGМc|wsB\Т\тсФЪФ§Ў'ю$q'Ѕ&-'ы'_MЁH I™<)wВєфnЊkъ@ZvкЇtЋєŽ жŒЄŒЗ™F™ЭYtYqY‹йzй 9Фœу9‹ЙzЙЇшO%œz“gœз–ЯšŸšПV`Sа[(PXPИSфYtџДќщš3dg"ЯЬЗ•p”d—lŸu?;QЊTzЉŒК,ЁьCЙmљ`…dEе9ќЙ˜sЫ•ж•U’Uее„ъјъеЧšёѓJчыk™jГjw.ј_˜НhtБч’иЅЊЫ”—“/oеyеM_1ИвS/^ў*эеŒЋ?Ў_[Кns}МAЕЁЅQ ё\USzгnshѓђ#7&[є[z[хZЏЗёД•пЄО™йЕЧДotјu,t:t>ю2ььVщnя‘шЉПХsЋђ6уэЂ^ŠоЬ>T_bпNџБў;wоx,К ЮнЕПћtШrшбАЩ№Нƒ‘бQнбЁ1эБСqЭё;ї4юѕпWПп?Ё1qчцƒ‡Z‡щ>yl№јоЄЩфУ'–OžNйMЭ>u~КјЬыйћщРщч‘Яwfg‘ГssE/_TОфyYџJђUћМЪќнЃ…ЩE‡ХХ%џЅЯЏcп оdПЅy[БЬЛмјNснїFяŸЎИЎЌ|ˆќАПšѕ‘юcЭšШZЧ'­OзжпoD~F|ЮлdйЌп’пКћХђЫТзрЏ{л9п˜ПеWќ>КcПѓюGє.nЗєЇрЯЎ=УНЙ§ П\р/јЫўrП\р/јЫўrП}П}П}П}П}П}П}џП}З0З_\ #МaнсѓeШэ yђ{ўЗŽђ›m$, KhXIRў BBfа5"ЩŒьFљЂЙаЋ˜‡и^\I'щй9…ЁˆђЕ Mq‚އ>‰ašIŠ9‰х!=ЛG*ч5ЎQю'<“МЃ|эќU)‚žB:Т<"H‘б>БjёD I)6Љ}щ—2=Вхr1ђ6 ŠxХeЅ~хВCс‡TxUіUчдzдЋ4Njњk™iЫъ0шьшЮщнжЏ68aшfЄnЬnМoВ`:dж`^f‘ikuдкЩЦаVбŽпžш9Ќ9>wК{ЄйЙЪЅР5г-н=лЃаГЬЋжЛоЇйїІ_—џmИ 88є(x6фCЮ!iu,4*7њrЬиЙу_у |‰‡O˜'y$‡Ѕ$ЬM-K˘о”б™95ž=™3›Лxъ]оZўVСїТНгˆ3˜bВТYъRb}9cг9цJж*іjюсѓВЕjŒ.к]rПXu%Љ>ћъщk•з/747оnšh^КёЃ•ЎMтІQЛwGRgYWkїНž7З~іћ„ћеюXј ЦнЭЊn}:іv|ћ>v‚саC•GжC&sŸ\›{њn§œ{FmіШ\ь‹’—­ЏžЬo/В-щПŽ|Sћібђў{бЇйЋнW>1­nФnк\њBџе`;ё[лї?xvюьяџк: K[H_Щјœљ#™C–K}Š)#ŸП@ЄPЊHўДђеbѕЭГZЅкeкхккчД+ЕЊДЋѕkЬЮ;жњ^ˆК˜zщєхšКFИ:zuъктѕЕ†MdЭь7фZЬ[лВn^jш˜ямэfш‘ЙezћhoZ_MЯЇыwI†И‡•G,GŽЅŒ—нkО?21џ`чгуУ“žOrЇкŸЮO“<—œБ›MœЛєтўЫэyž›ХмЅ‘7ЈЗЫ‰яКпoZ ќxemy]p#ьѓРУ—рЏƒпОнщй%џщМз№_ћO k. МƒdЁLhсŠXBC1ЂЦбщ+Ќ,Ž•„‚”ŽŒЏDюHq’p“ђ3ЕM8Бі;Н6C:у3žE•5”­”§&ЧчcЎ ю^žЋМE|QќіЪ‚Œ‚п…ž З‰Š‰Š H $^JvHH•б–e•н„OB”Ђ‘Їв–ђШЁђУ*jЊDеwjНъg5Т4ДјЕкГ:­КЙzоњ‡ ˆ ћŠL4L™L7Э˜7ZXFXйY+лАклEЛћ ЉŽ^NZGxœQЮo]юЙvИ]qЏє(іЬѓЪ№Nі‰ё ѓѓѕw9j`Ј$,"*&Ўai{Ь#*8њxLZlсёŠИЫёЭ ]‰}'ю&$ІŒœJН›v'Н7Ѓ;ѓfжьk9—sЋO•чЩЯ+Ш,L)J8u&ДиПФ§ЌcЉU™QЙVХЁsв•ТUмеl5ЬчYj9.№^К$~YКNўŠrНЪUkкзѕ Э››§nФЗœimhЙЙаОгIг%м­йуx+ьvVяљОЎў'wжIюrЖ ЭЛ8о{oцў—TЅй?N›ьxђё)ч3›щьч§3лs"/<^VМš]р]ŒYzіFщmе;д{П•Ћђ/|b_o§ьЗЅіUјЧУ.хю`џыщ5#Р…l%0Ј ъ3Мщpэ1РŒ+E­4' Ў…ъЌ^ЋkR@)h#А§ Ђ„! Ш Š‚•хыаДŒ@!ИwФIФ%X'^Gв!U‘ўШф0r% @]C­Ѓбiшg!Lf+‡=§‚ГУн&с#Щ'й# &]$Г'{‚7Ч?"З&ŸЃ№Іи$$SRQVSIR PлQЏгф…‰їiУш˜щ†ш#ц ˜t˜v˜XмYY'йђйЭ9ˆГœИBЙеyhx–yЛјВљэИ> v Ѕ лˆŠь‹N‹ЕŠJ„IZK)JГHџ”™•э;-Ђ`Њ(ЎD­єMљеЁбУ7U.ЈЋeЉ'iФkЦk%igшщVы5щЬnLФLЭЬ"Ь+,†,7­ЙmЌmГспхOG%Їи#З]PЎЦnЅюя<•МrН|eќR§ŸЦM†ˆ…f‡­DG6G1F'Ч|:ю7š Xvb/й=e(U4эL””ѕ*Ч"w$O-ПЛPБЈыŒJёаYѓвWхЁча•еr5“Еa‰—:ы\ыIЎЖ^wnФ4]НaвВбvК]ЉcЉыTђ­Нчњ-pƒ§CЧGЄGпWм7œјўАюБэ’Љžg!Яљf^ЬП4›'__Ъ|ЃЗŒ}7М’ЙjМF§izЃrгѓ‹№з­oН;9ЛŽ{"Пў?Ј ьZАA T€艹ьBД8Єy@ Ptš„6„8ТŠ(BД#цHи`ƒLAо@ОA1ЃlPХЈ47:=€aРcЦАиLь*ЮзMТ W$iщG2Взx/ќ;ђ`ђŠ #ЁR‹r–*‚šœКŽF‡f™˜M+Eћ‚.›ў§g†zFo&І%јеseeeeЋ`wсрхXуьтЪфvт‘т%у}Ы7Г”A3!^ЁoТїEjEуФьФх$ш%v$чЅFЅ[eЊesфŽЩQPWфU"UZWž†UиF•sЊyjЩъбЁšZGЕƒt"uOшхщŸ7h7|`Дb‚3034Б(ЕДкАсВЕЖЫЖtNЊG’œ‡])нŽИ_ѓиїВђОц‹ѕѓєя` Œ с {!yъиЇhЋ˜юуМq 1єФ|ВIJg*gZfњчLЇЌбљмК<цќ‚B\Qђщ§т„’§вфr\EA%KU}вљћ<.ю^.Й"S?u-КЕq йЗ…ЄѕвMЕіщЮаn|OнmНо•ўМљС…ЁмЅбхё‚ћђЯF?&N6O™<]›ЮŸ‘™}qђ•јќьbцkй7Џ–“пsЌtЎš~|ћ)aƒщsЧ–У—Нэ пwЖwkїЬ~э? ZР D€\pмг`v№Aъа(*†Z Gа:‚! ЛF"ЅАKф ’Љ€єD"aїЧСЛЕ‰>„ЮDЯ`D1'1/`ŸЦYьЮ7D"IRIJ M!§NNЖХ!ЇРRј З(­)?QхP Rај)рzфJG ыЃ?Ц Ю№ёSГѓЫ0k›-;ћ*G7g.—;З2=Я6я _?Н@Б`’ПАЉˆЄ(Qt[ь…ј]‰fЩ*И6ЅЪФЫFЫEЪG(„))љ(;В†йЉЖЊКšЊКЊ††ІЎ–ЉЖНŽЗю1Н,§Zƒ>УEcœ‰”ЉГй)ѓ~‹m+Iы@›ыЖыіr ŽЃGшœН]:мШнН<њМиНOјМі3№o р ,F‡Ф†Ў‡{FLгŽjс=GˆЯHDHIFЇdЅRЅ•g№e6fЫфДžЯЛRРUXyšхЬЙŽГЫФЪ;ЮщT>­іЉљQ›‘їRwх•WГЎ 6Œ5н ЖєДyЗSuмю шЁЛеныаЗu'{ѓnчАхШкXі=Сћ#ќс7>1›њ№,ў9f&cѕ"цЁ ЋK~Џ—пz-/Нw]™^е§xim{]i#шsЩfїжѓ/_ЖЉО‰|злёњ‘М[§ГwяеСўџі`д€і3vƒ§XџЗ#0 ђЯœд№Ьј “ЏўМѓtг2ќƒC~yр~ХН‚Ќ-џФƒмMLџ`я0‹?8$BуПa3Ћ?ёX_Mиі{~Џpэцёw3€§gПуa‘жpј1Kэ?8жзЪіієвњ'юэЇЃџ'юЁџЯНŽўГрŒ№јэ]ƒГ†€Šмдпzїр№?F„W4ьk@38$&ЬЯЧ7‚Cvїy‰pшyˆ‰pHIHJ€Б*ОжЎягЂ pHYs  šœ IDATxьН xХж\ї'џ3с: Й?ˆA@@ФАЩ* ^жЋрc%€(—bd‚1Ф„` 1†UAdШeYd•-И‰ &ЦЩcШ ˜žЧ№|џщЉIЅЇЇgвГЯ$Їi:ЇNŸкоž>]U]ѕі_zХ§:В С @ъ<€РЅмu@ˆрњіъ†H ˆ" ИўЁ@DрџAD  ;Р_"€˜@w€?D@w€ПD0G[цx`ЈУopCпG їvў…+l”ГG—aэLS э2fiЂ;`P €ј.єіž§оlE\љщJ8 С.cq‚иYЃ2"рЃ@Л|oабkРIvаO7†6$Ц,–X`Цт cы@ŒЪˆ€o#PiНx–Ї*IІ1DаiKX4K ;‚"wPXXІЁЁЭYLд єЧ€Пwќи&xQИDt“7ж4ŸЂV 8.€ƒ Ї@Ж4ІQ”v4O5焆Š CPƒhP№—рŽ_‚8MБ З4НЋЉ@eБDfŽ€Zв Ф†ЕРџI|j‚ ˆEРUП1žfВeNSЅхЉ*MЩo%Ÿ2Ж ~+1›%Zј‹]|и2„ыЭРC4 њcpп/§ижgoЁD^76моLOяs‚в`аoйО3jќfLݘ 5ЃJfLƒєЈДГРт`ЫAЂhPмїK#L]| GЖƒ#(€Нъ”и\АЉjPb вИbK“ЌЈГРтЙЊ-„щ0HA@4 Š€х/AŒ ШcћŸй)IPЌoо\hЬP@гјЉц 03Б`_gAeD№Д§Џ-гв;\œoѕН§˜wРXl&•ЋŒХzћZт˜(#ˆ€ЇxL юX<и[)…5НsPл=v`=)<ƒ юBж#ч УŒЋ;4 Р J`—БИФи:Ѓ2"рЃаЕIpУл([Тd—Б8A;Ѓ2"PЇРЮBОќXyD@ŒК1(#utuњђcх1шФh ŒдiадщЫ•GФ ;Ѓ2"PЇ@wPЇ/?V#€ю@ŒЪˆ@FнAОќXyD@ŒК1(#u™5 —._Ќ^2YЇССЪ#ЕX+н­kwq Ѕю€њ‚бЃЦˆPFк‡РЎнТ‚(БGv ]€О і]xЌ"`‰мщ’~€дXЦA "€дад‘ еDjF@:vPs пГРБOпЛ&X"EРrјP\PПwдDЧЬз eD ю АkЯЎб#G+Ќozк*АŠ#њН;€БЈwЇыщХЕBЈ;№•МђпџшёЛВЗZsNшэМУКv­; kŠј"U_j“-›у­№ЫЗ“јЂЊ/›В+”ЃП P‘zœЭфx"Ч!}4?'уЪІмВмнуvёAy…d`/ГЏЮкLгэ'[?зњЧџўшp6NFw8_ŒшsР.їћw œК§#’И•9ЇšaP9­э(yђлER–GєwЩУ{CyЊЗЊх`вЈэxєьп7ї,zXіlPГ`U“ЗКМй3ђихТЉ› Иmє^Џ Pi4%IЁ "PЇАЯpFs­žЄm'?ќ—„УЧо\Нн=eИВIѕдѓAЁHѓЖDŸЧkЏ№П7'š.ЊnSI}‹;Мceѕыѓџ/ ЈџЏ^3#КFœЮеО}С‚7л эЃ/§iў­_є‰oq}лЩћ1ў‘aЭњДƒGŽпџ­(№Що=^7v\Зnн ž­_ћё?ЙЎЌАЈиŽ$ыdtGВФ8О‡@ЅAќћЏЉ|ЖюYћм_I Вn/9ћ_UяЎ†[џ%ыЮJC~њ№š &wоpу3u›чI%G*uЊzД=8MKRHp_$­У%ёшg(Ь”f~;!e WЁkžгa@W58‚9Ÿх8Ћ "їu|ž–tkgƒЂ?˜йЂY‹Эы67jкHЏзпИtёѓЕaFw6е^‡EpBp25'Ѓ;QpŒъCР§mЧ/С…cр Vl'З~Q 7ЇЊнS„tЋ$:ƒсn<{mљ!i,BfЅыy^UЁ[6-T?Аƒ–ПuMWxS7сЫюpЭŸзД~ЮPZЂ+ГŒ'Ѓy"H@ш~‰ІUcЂV‘!ѓroщZ5 ъ=Є xЏc_]$жнрхѓЇRNЇЈ8Ёэ VЋћ;Шa/„БcЎБPZ\КlХВ3Ю?Iзž]'-{jГ$iIњКєћЅE­Z…-]œквиЭЉ$IЩI9rџ–tГ‘ЮG~Дaу†"mQюЕ\b%zU2јЈлїЄѕлТ"eУcВхпBЛ`д+„ "\=NХк}`ЖBѓ'КпHЙўЊ*vЅъЕAЭ)Pы —T*Ђ ыФнoЌ;Н;шеQ*ucСˆЗžЈЙW ЉOЪ*I GŠђS?ЩЏЈ$сУ;pѕЙ+WД\axRhа˜Gв7n]ЛОœИ(qм[уТZ‡‰НмaТ„л6cмЉяMMœ—ИjЩ*ƒСАn}кђ•Ы“?JІ‰œЛpnћЦэ\nЫі- ё Пињ5щkЪuхGў}ф ЫšвЙzэъіmл/Si5Кnuб~Ѕ–`˜~З–'Ь5vМh„>ТюЫ*юУїe†sфššм|^)x(ьZо(ш§­2CёяЖнy)h(€hрсР З=8•G:•БЄ‚‘E} ‰A'ЭB@д‚<Шq/>О bJИБwюИб$@џМЦ8dPЯ"V•"eiJ‹fM–,ŠябЗЧkУ_[“Кв№HО._oџ:ЌГр2TѕUяќ3цьйГUiјте!j•J5aм„›UУ П98oЦ<ИЗaћhЮGЬиF:sпŸ ЦдвZt– ˆ `yч[jЌeGы’ИЯ“†œъ!хр‘РGа:рс-` 1ИёШcк|€ЊBаШпE’ЂФЅыщCјžNO|yAsђКамяе8o`х}Cй=R?Xѕ˜уљ ёук<ГМ8Иƒ ‚aPЃIˆ*0€чъ‘Г‡ѓзЯhжB}рЖ` .Ч‚p*УКГЊ†Н9в†њH!Цлž”WчУ5срјIй“œ{•ЊiџгюNшh@[усю=гŽ ўE;Аё|С]ТнхеM„&Н‰ЊГЋ’„[Ўz ЌO@‚РЋ{4 Іu(јMГ"ш(c7огšGЉŽ,’B›6Ÿ3=цх}ЊEБц~0wцŒ™//эЎЊЯ |зођfBzЦXЭ4ЭJ Еš oFJ‹ЕLЏ0kб…tpЋЫРЏKєГЄHф^О Гўр(=es†‚ю€д#оpр:сЋUЄZбхJ#ЄZ§XЃхГv„žAA™а((yШпу9hw€—!ашŽD№$єєy§=ОЌœЈ_є’эqе”ъЏ!„І Rs\€š лм)2DМлjeцы™G%8-fк›ЃоьиЙ#ДвЕїЕ;ЖьhпЉѕН! ŸШ/.hоД95ЏЈЈjЩq…ЅкЬŒLP2ЭjIƒCѕ_––:яƒy \ДzГW˜ŽЕш4 <жe$П7 ХхЫ—eѕ6€ВcьRІoЬh2єCёaЁ…_~я§›Ж™Ь>Ё“в Ь§ž#К;фЗ‚ГЧ ‹ЁђБ$tЩжб?­yЅё •№y]I9Я7!ЯG’–}mT†žzBшZќ4ИЗНІО F@џкРцб“ле'ŒD­U ІM™іяуџ;f,М,˜:y*ЯѓK“–в”#&Н3!bBзЊЉжqёq)+RКію:ѕЉ;Yyo)*.Œ/Ррbја№БoŽэеЕ;Ѓ0kбY:( N" § ;№%еШ†я№зэR(ср1~dК^­x’ВЉѕbЅШSRљђл№Z}tˆvh7=)Э#y_єїHШѓЊ6#ˆІ-QЩt Р“Ђ`‚KuмоХ|QУц$јњёЁл пгFhЂ-жeя(ђ"їЮk2IБP@ќЃ‡Ž|MxЎlуsіцА{\rПлгYЈЪ юџ˜б†ђ­dџщ*•Ћў‚g(L=lЁ!Ён…з5,Xц§Хаэгў§і…›7z5є`ь ž0WъТЙ‚]ЧЕПЅщоFh/р†дEd{їU@8т .ŒœУjЎsсѕ|crяbОаТ7ѕЭЭd5Є0FbЖUП)€Љ›†~qёЗ‹‹7щ ДTњRн‡Y…0ў5C#МЫДўZС,I ў€0ЏАЄЖэtЗаFчЪхŒГпАх[шH)­ГЅ/АœйAг}ћ`Ўя.Cшћ.7`є6Н#Mˆ€! 8§ЊэJ”`Є|д€FДИ%щеЄбLЄ†<№4"P‡pМuра,}pПmнМѕхПђJy0SDРы№окФYЫВњім2–zЊё3w`Y Jѓ•Д<…D . }lхПџZN з<‚5юЗК№kР:"ЎBРЉБWгA_@н/\,"р ;№‰Ы€…@|Љ;€‘њ]W_(–@м‡мщ’З в7 tL=‚ћЎІŒј–oЄю Šѕ>rЕАˆ€‡v<œ=f‡ Оƒ€LыРw ‡%AYroч_ИrAі”re.=ТкЩСЊтј;РяВW]ќ‹tяж=4TfB1ѕГп›э$L+?] )ˆ=‚ЏИъ Кї}йЩbtDР—ИxњTtЬ,…%Є_Зєа._KІcЭlТИ1[ЖяєEwпe_а­Ћ№э3мкŠИј*|‚]IщЧз-н’ИŽйјJыРБвc,D 6#P‹"Ÿb>шь‚ чр]ѓ§ѕœ…#хДяEЃ„ЁЬ‘ 1"€ј*ŠZЖ}ЕjX.DР'€ЇКВБб‡;d*тњЎ§@Š$+Iˆ,9ˆаAH@У " И•оЩurssУТ„ЏЖ–jKЏ_Н>№Ъ9зs™Эђў—1B"€ИЋŸВ™щчk?‡њDLŠ˜=ѕмщs+—ЏйfŒъ“ђю њМQ’Дhѓ™уXŸЙnыю]№}БФ0W{‡]Л~4о†Ќlјмhюy ]’”$# "uЊЧО3_ЗTzZzcMу_Š~_аЋЏрЌYZъэJЄёЉ €#ѓ[7oЙњплћЖя8uьH GвжЄБœЎўчііЌЭд0% ˆ"X~jнRc(№)VіщяM_ѓщš^={e~šiЭFа[lђюžсlЗˆ"ЃШоП{оœXuC54 bў{рј1f47&О}Ъ‚Ьƒ0 ˆ@нCњІнјСuU_ggцмљsk7­Е+ љЮ‚Н7э§пІ UБ(U№еz”D02УэfъD›ыžžMк@с™ЦЯ(я/ˆn\'ЎSCMГ#›6уя„ЕЮ №XhH6>О.IЃgDЏ\, }xдЛQiŸЇuьв‘Оk`6жљЮ‚5kІiјDaq Ž;*qЩЂвb-h яФ-JdЇ$xA‰ƒˆ"рЌOa&ќsЪл“Ц@g$,ЌЭњЕk`ѕMЬiЖЖЂ&Н3&bТў нŠˆё сI1SЁзаъйg'G§Kš†D€!№˜IЖ›$=‹Њ”Ткu`A†ЭŠeUŒъП2юРrр€i˜ї?u,%K œbіЬЬRУNЁ€ f(ОЭb9qNЄ†QD@ 6ћU и6В€ЈŠчј_tŽc‡1‡р]ѕ§u‡rЗЩСЁD[Iт9D№O|Ѕu”я@гІЕ‘ЃBŠЅFl!PXXjыДш|—шE З‹Отшч^Жn\яіcˆ€WPўёukдЉІт+}=aGm}Х@‘ёs/v\74­У!: ёЉ“o*$%NФ‡мИX(#ˆ€5(ї1мЬж ъ}њ; ы€fˆ"ALˆю*@№Э‚ЋФtПG@ІГА&§ЦСТъмD #0ЄŸfzДqsU%Ѕю€њ‚Ћ—ЏUр_DЈ­t"ф†и#HнД Рф|§ЦѕкŠж №q:vш%ДїŒ?сRю %Б §nafЭЙїћєшj0Єю€žgџk: јqC"PЩЏќl фhя=xєфQИsуцЧеXкф%ЩВ6ђю@0 р~IN6]T"ˆ€chМ!B\;яA“/PАrТј [ВЗвVRBыю@bˆAD№_ыˆюР?Ў0–Pˆ€С‰ЩЫ8я@!Шh†ј аYэO?§Д8h’­TХfыР 7c%;TЛжЯЕўёП?К2ELЫзpр}ђщж­ЁBOЗxњз§NАuрkзпх7с‚T0 џD8”шN}­ШLoƒd нЏ_ѓТ;…б1бЛw„жXbЧš шDjж?  Aё˜Д6Ж Ф4ЦS6>п`ГГ N eo  §M;іэБГgЮ^ЕdфриюћrŸц)7Šƒyњt~@юr-ЫZудлюРFГТ2/дИДЯ—OŒ=b(M^ЏeвЧІi$[7Џ_Гa}ХџV„OŠ[HПШнњЙАџkњ5ЌI_ГѕЋ]`0р’?Šч8•T%Y™КfзО]ЄВbztLФјˆjк@`qiІxє*іпƒ цXЋ‘ЭЮ‚h|RfpЯКГп џGИ|‚’ŸЛ|ѕ№зћрKЙхП—УЯєTXŸЙўіnялЙяТщS+WЅQ§šЬѕwє'*))хЦ‡ С§ѕТ,l! ОYэКІˆf_a1џЮ ;%ЮЃZЖе:Ап/UЇ‹’K(К_ІRЋХ‚їя—1ЭМ9ѓ@y0iђЄЈшщ4_jНgwfFІ:D0ˆy?fјџ Ÿ=o6ШЛїьо б3ъЇЧЮfЉ1&‚GЏ#рР1€qtГхMуЙ †!zНžоЗ4Q6lТ2hдД•5jt_[ФєT>Ѕћњjeее.в}Е%DРˆ@ес№IzїюѓяшлГвAАKяо,XZ\J=Bii)|8—щЉ |JwлvБ7Ёњfšf`Я\‰$§ТТš_<йЈMwрDЋУF–xJ9S'O51H4№ЕышбЃы7ЌпёХЁчiм–­XП0D„†@•ž уЧŽOLH„~Др‡’Й)3й89jиЈEK-^ȘуИuыг П)ŸсНSJSЦЃO Р.Ј‚вРВeуТ$І„€ёэkвОˆMw (Y4r#psf}žЕ,mйЧ)C6]_ьšѕљZёSНsЇЮУЧ о, Ÿ>е4pР _ѕ†w “ІM2}JїŸІOщFEF­I_ С’ХŠš3&bŒ№оk2яЈXš(дbајњХ mšО:]Ж”єОw%LfЂЋ ge  E@,e№‚ћРЭoPHv@ыgЄ<РЮ~{Б<џЧ|PhŒfЕƒAXс,є2Њ>),|0ЪДыQi4ЋЙш9"sкё…г2‰ЁЪ#L˜8aЮћ1ЦЗЭЩ3q/НmКъKм[[LнХРŒ#!EМv.ЦеKЩyі:кrѕK^BГE|пƒ6')ћ2NX6Dp5ш\(І‡ј-V; к2-џH:KСoЋ‰GќЎОщƒžПхн]г›ќf,("р'Р %U>ХаUе’wm…нUy`:ˆ"ріоƒ;W˜X0Ш‹Fqdь №ј1‡ѓУˆˆ"рГШЗl7Дџль,w~љ2Šсѕ•ќрYfпєiкшLqЉУeq2КУљbDDР…8т u Ш#єр д“зsКгѓ?^зЏ™Р}#ЌŸ“lќGЄ!ЎЅ“ ‚ADРЃ(rљ‡РъqЙ.\ЙA№АбНсцЉžэХЕгCЫ…‘хЇ8U{cA‡Puя“EЭљдџgAeУ#CжЇ+sАЈрЇ'C^ьн{ФфЉzvƒГј@Ж„ 5ˆ€3(rр ЦЬ”љ,ьЮ”dюŠeјщœvnИЄ|zQX,‹детЂї"›4k‘њезšІ§§sЇ7Ѕ-[нsWЕJˆ"р"ЙШЫ1ЖаХ№•XН ^wЁѕр?WИ J-ЖЫ'Яфмк R ќПъ'е}…dhА#эѓk‹ S%^ўюљ“t}ЕЯМщъ†G XЮћ$%;-х~qQЋЖaѓS3B[З=”jљ‚9Чіэ ќk`ФДъў‹­t–.ЩЮH/њ­шLaЉЕшBЪИ!ў‰€ђ7 0{кrЏЉв0| з‘‡6w0А>пЉ}ЯЎЉ fч_ЫЅЋ6Y~дР‘џЭ{{ђИЩSsЎчхмШkёlЛЬф…Ьјъй ™ЛхмњѕЅ№‘KfЭ њu)ЩКпЫw~=ы№љЋgПeЦЖвљсZцсo_@ˆЕш,ПC@iыVШэџtЅИzУоЋ~ЂŠѕbй№HЇтu2Ы0ш:-Ш8šfa‰ЃšфЅkГwЌ]ГxюћХ?џмАQУўУFMŒžЎzRxьKЖ/Ž7iTdтЬйc{tbѓ>NЂQЦN‰Ъ\ВˆъяйКc/mAФ&,>uшелH'6n!ДPlGg™Ђ€јŠн!Вї?}Ы >šA№рЩ_Y!(йЭO]ѓpЊ2Ш,–( ЊЏš0cь +М[Иo}ꀘшХ›ЗŠLL"Д 2–,Кy§2а{ *Qݘћ:4_B ЭЏyкє.CгДњЅ†tдЊП}d-КeСPƒј Š; ьыnbњЦQ|зœч“GхBі2‹#U‚Пh,ŽeMmњn|вх3gd тЇM9ёэœђ ћpќЧ_йm/k ЪfO5гўZHЯТx3S˜ŽЕш,ПC@Б;pЌf* 2=x„bуЮ„c9yШѓѕЋŸК’|fŒ}њ№§}с„ОTЛvyRћЎ]Љ |ƒ€нЯ ЉЈЈPС'Ч8млЫдм‘щ?rTjR"М­€ФSА|Іc-:KDРя5Љ­—цьЯ48 ЖtЁ…ѕxТш=Œ?ђЫM6єЫѓ'э/Zžу‚mМz˜3oя–Ь•Гц”=(ƒr—~§26ад"ЂЇOј2t шhbмЊД”„јЂ‚ЗРl|ЬЬ#;П2ejхЯ;3урЭҘЮ…7 яЭfc гБнJnЈFќПєŠ?њuЄёХ›БДЏ:zѕђЕМ?гœ/;ћѕћ;Iю^Rr‹<6X&Z/4~ž„а2Fv’e д ˆ€,А„)n~QF Ы%o_k{ыŽўаnсtSд:Ј2Жћ/пЈ-іЎegBл– pаS3Ы3ЈA#р^w`Xао2ж8ѕаУuЦьD@7КlќЫ"ŽJDРgpѓ›Ÿ­7 @,@w` *КŠ€; В*хJ0FцЊJЗsѕЊ њAЊТB&aЋ$Р*IEz ёEJq QF|ЊЮS%UФ›b, ѓтy>rFЄЕ2?>iэ$ъD@)žv [9ifЭpPЁб;ј8iв€е'ы“Шv‚ГPZ]ДCыxzь@aы@hМёVнщ _ЮиЙz$˜O $ЋtлŸНў9&JhYŠЄЩБ3>KŽwАљ“АJšRЖVХЦПˆ€wxтЩ' гJ=№…Ыr€Ѕв^ЇнmX;ВвW˜7тNgЇЖnžіАuAљуcr {ыюЫЙЌ9Mƒw_x ŒмЭђ‘Кї№йЊ%ыV$_ЙјУмх.Xх-Ÿ j{hпЖ}^ю њyZЖool,•іj<эhЛ ЦRZkє{эuŽ’˜Њ8ЦШЁ(›кбƒЛкїшЭ|и€мўХA?pиhй(T=cў;S>Zѓ™ Џa#:žB\Ž@П7омД"!!c#Є Тыу…с0КБ _PPЅv№ЏЇнТБƒ F‹ oЊо ќћјЩлџЙ-TJmфSJœŸЙ^Жъ{жoš<яЩЉпоДjЕmw@ИgŸ{vрp[.C’,З">6ЂЄ `bПW!—Ё“ЂŽ”љq‚ѓ_pіД;Pи:`рB€5к=зŽ6К|є—+‹dОрЦbБџ 8HхюЏ €dіuЊэй9k6 ,бC€1/6ь%.†јЇ+ж;&{к(lаЪРУпDˆЌ 9рX§%Б`‚GёнЛ0”(бcЈ xкие:`%ЭчЏtУšЕz61Уlz‚ѓЩb ˆ€П рiw`Wы@ "xСћтИжdзЖЛЌх‚zDРg№Д;АЋuРPsЩнЮRC@d№є$e‡[ВЅG%"€Иm=Ј/)у_щ”w‡зQоЃЂуљ{z2oŠFUп…`Rˆ"`BРG[ќ#Bщ‘-+™ЙТ*Цђ€ {Aя/зjрѕCз#рiwcJ*!PU5\@R“1УдБУUТџЦхџІ$ ДAћ№Д;P8v“”uFЦ8œћќЗ@р?ЛxMЯЛ ъvTйь Mы6žv [пчЮ§|š™+Иi+Д‡~ц‚Ћ[дчл6ЕуЂ!’`ЁiнFРгю@aы€p$А%7ўљц\ ŽяЌвЦOб„о9н|[Wœ[уЕC6Є!BпG&ШA#wxЇvƒž{fљМ9ь‹чЉWж†qНКЈKjсiw АuРЈhП*ЩqЊv!$fЌ:f87НСЎаяVЉЏnV=МКя§цћчЈm:dCrЩЏё:WЯžЫ:q~чїзuПп[—RЭžzѕ‡k™‡П=SXъ’zк(mYRЁ†0ŽШќ‚Њј†ЊasвœЈ›РКCђАXu!#шРмГOА0\(]›lHРŒ”ь,А!ѓœŒ•{эшШ” iиЄf"рEbте еАЧ&,>О'›•$6nЁњI5 :)xкажЕ#ЋLK {)а _RсtЗДе„+Э*<%ј‚‚ фт.уч@єДъб=Ђ/dХcC‚6p"3А!1klHV-dCb@Ёр hžЅХа4 -њ­ˆ iLv^№Д; ­kGVŸ˜)šХs4Ё-TћЋЧh"Zц‡ъ U§g‘тыфФJCƒ`вИЅа@Ј„qFBд&ЄXtAЈbC‚•tf$рGb§.3уЊА!.В!…ПMƒ*\№ЏЗ€ц*-Дy›=еЬMХёД;P8v`Q[ƒЁЌ@hќv§ЊО‘Є~c(˜§žЏй5ХТžи`CВ4k€ iѓъдШ3‘ђ@ ЪоE 5)Qџ@;§GŽrSa<э”Ž˜W—чŒНЃGzЂyŽ<е”•ВЛDLBš#~С< А!˜8Щ\G€ єЅ4ˆlHRD0ь}:їш5ёхžcКw ј>нГUM§sOъ–ЉBыРЄЭSЉ5ф‘V Eы№yФ ‚О‚ш‰і>3Дh™В!Yb‚џE`Ь”Hи%хwљ’|џhшšvдыuфмч„џ…T–€{‚;xH <1ДчыЛldй$?8 ж)ќЃu o;п HSv”•“М3ЄэЂ/: •€ЇнДzX‰ы2ГЕЧЎnЭЭяј?ШŸ†'ўЊjџŒ:8€4 сЧеЈ\З„ й|ўчŠt/žv }­4x„Йг4Џ^6ь=­ЛSЂ фIE%iк€ДlFzє ’э#8ƒ–ИЫрL:№S<э”З нЛЊКwue€ЅŒ"€ˆ№єPЂ]­qAQFw#рiw №Э‚ЛЋщ#ˆ€%žю,(opч7/ЃЬJќњJ~№,3Ѓ5Ф‘GСУxЕOЛЅc=јѕфѕ\Їю{ўЧыњ5Иof[^ ўЃвPюЋ­–ІЈAыxк(lpsƒTЯіткiˆ!ž "ЫOqЊ Ж|&2УІЫxŸ,jЮЇў5“ я~Б2ё‡ГgaqtЋіэпŠžбw№‰ђ Ж)”c…–ЎE`нŠU6Џ‡4GGFM˜сš6Вe =э”Ж1ќtN;7\Rbјь лФ2SŠјvЬиQsfЦ.YЅЎЏЮПЛ=#еw NeDРcнБѕЪљY'NBŽL›вИyѓ#GЛ#wOЛ…­Јjшт-@pBлЌu=8Ы.ˆ’5кќЩŠЈ˜ш№Бєl›Ттгџ*о$|Мxієg‹ŠЮmиДYфŒ€>œ‚ˆєШЦЖЌ^Еkѓzhzє>oёJU}aК4иЬ[К$;#НшЗЂ3…Ѕ–I‰ €2"P#п|ѕхД9 ъFТыv6­^ц&wрУo`ј>гњац№5g+лйSЧ^ъ MŽ~7rжќ#љЅЉ_КњУШК8Vћ‚ŒєлзЎf9™s#\Џ]žФ rѕ‡k™‡П_ЫЄ˜ ˆ€nцнlжZ‚pчцM%БАёнжс‘NХыdHQ+е„‚ƒG:„ Wѕ2mЌ‰–;SГ.00PWVЂ/гjšjц&Џppл†дm{ЉЯž:oсФС=c}L-cуЊŸ4e­$)йєQ‰Pўx№mxB„ВenBЦ;­:ћРђhVIј^ЛžОз ;|Ќ™UЉЄIVЖMа(Y9Yƒ:qнцsпœ8шеq}_Кјн1YыЂ‚ЂQ=КBзі!/ДяУЬЈ A%IБˆ( –<ёфРLѕ „< Є€nйМг: #–GqyЎ1Wz›№Vћ‚1p"Љ‹c‰хо/8u '|b„X)•ˆС`2аыTћhXœЙ”аѓO~?vпЅ+вˆ„4{ЊYцОCт;пв4J’’ˆJD€"аОmћМмz п(ЁeћіnBЦ;­E•Qi_э}Бqg ТБœ<фљњV—3LzЮњД”Ѓ;vр>Lђџ“›%Щ:ЌSЗзƒGа—jS?\ШЮ&ЦЦРKJa Г’?+Ј>ЄaМ­`6Ѓ&G.›? ZСЌ№Ч|ˆТN‰йЄФ(#ЖшїЦ››V$РOv^cœm{‡ЯzЇu ЈИp+€@8›ёS Т`мŸІRѓlуеƒцщаД{aоСšФ+*Lѓ$YЯ_ЖzЩЌ™K5kоl|ЬЬ#;ПЂ48>rмO?§єьsaЇЏЅЪˆшщО 9:š8цнhаЧО1т~qQгVa‘Б3$‰лHJж•ˆ€,№vЌЄ `bПWсьаIQnz­‰џЅWќбЏ#л€DЗзFНzљZоŸiU џU8я€‹§‹њ§$w/)ЙE›ЮвЂд $Ÿ'a#єŸŒБ6 IУˆ@эE`чŠфИљqBяъOMh] Gb|deЌ ЖdoЙ}­э­;њCЛ„ƒяЖјFmЙАp-;к.`EfB=0c DР<эЖ J†Р‡Uю9SKŒ‹ 6(,,€ѓžv g%bупцЕУ“ˆ€ыа<ем‡п,ИОΘ""€Ш#к<ДEЈЇнТж|‘Q‹ nC@[Xшiw@g"К­F˜0"€8Ž€Ž@…мЪ†ф8`5Х„ ЫtVjЁчя#рЁDЅoмУ†„ЗЈїwX_E†}Дuр6$ИљХШ‹з&‹ѕ(#О€Лй`(Qъiw Дuр 6$ИЦŒ›РїЏ7–А†€gи`(бгю@љ›чй,СeФ„E`iЩkK›—g}кB˜С}tџЎУ&•ТЛљs'ОН§єїАr)uQтeXћќ'щњjŸy+ве хЙ ЩђB Ц. šЮВ!йF\LXДEŽзЈwПўз/]„D`йŠЙГщ‚ѓыч.ід”ѓоž{ќ(e7dC’…•Ъ№ ’зf%вй–G3€œfC‚дш№Ёь Ђ˜ЖD–зЈcЯОЗ.ž…Dюн—Кі›ЏЖƒ аƒ-wЦЃ=ї И›ў-ž.Л_M…gХВ!‰б@й<Р†Dg%zgь€Ж,bЄœgCЇf[–х5‚“–-O>ШuЅяІO—^<~ 4”:)~кЄш…‰K_Э†жє#њЗ~кZШ†d д+DР3lHО=+бi6$…Xƒ™5^Ѓ—^y-=!ўѕQo‚ЭыУпLY8їЅўЏбdOEХq*NcŠЫЬЖ‘В!йO)AйŒœ ЮБ!)šкXу5ъёїОЉIѓ_fp\ЖpfОBOЖИUi) ёEoAЫBLЃDЯŠВФJb”лx€ ЩЗg%<•Р”Ш Є.b6$`Lƒы ЌrЋZN:`&“рЈS`B[ЗЁпJо#2‚нћио3+‚Ъ,e&є2vf‰"ряЬ‰ƒнˆЪЃјюЌDЈВ!)Пh‰8‰€ЯЯJD6$'Џ0FGьAРwg%"’=зmз рщiHtЎkЪŽЉ ˆ€‹№ѕY‰.Њ&&ƒ Š№кЌDEЅC#D№оœ•ЈЄŽюfC‚ЩХь] ’ђ  "PЛ№ТPЂRОїА!)Йœш&” „6ЕЗЏYШ?|рњыbь.\– vьаБЭ`Ћ“s\Т†ЙР—T?_šxљьЛіюѓЯтaf‘И0–ВcMt"–HЂЦUРЏKœд Ÿ8ђŸ_ФчeЭJ_0fІЬlЊ)Щ6мTЯ№г9э\avАx”I,‹m˜ _[Ž3|њ‚И>нЪSwBpmЮaј”+ГA№}ФЈœЌ %кw”йCГ 0биўЭy6ЄЭŸЌˆxoіРБІщУ ш6’6wе Zœ7l§te_1`ј˜Й‹Wz‚ZќœЗЄH,“uЫ“|Е&PGЬœ=fJ$uоєHЏ2 @сцr“ьu2wэђ„щЌDЯЬ;€-Zю5еШi6ЄГЇŽ jжрйSЧYЦWЯžЫ:q~чїзuПп[—ВŠщЉ K‘ЇЖ|Къюog9ЙуТ5бOSGцХ‘I&]‚Рб}ЛКМд[Lес’di"žJЌ$ћ?]).їАїl­І–РwЄтuрEЄmkР pфЄчYИL[ІбА ,г1MlB<%8ŒMX;vФ;sfБS ERъЖНz Hš8ИgЬЂ§Žьд&§;№§lЙ фPAГdЏIIм а№ИiƒћЩ›ь§Oп2ˆfE6ЄG<ЉЌ”ьцЇ.€y8UdKiЂ/гŠ])C4ݘ Dа4 -њ­кMPJ‘ФŒйзmСьЋѕr0 }‘–К~yrр_ƒg&%ve€œъ;8}№@гжЯУ—эˆЃидCC‰Byшzd‹’Й› ЉwџG€О=Ы‚Н_юЭ‚0жH=P˜mгSA–" Nь™+‘ФЂAd@’…•Ю А-}ѕŒХŸ8“‚эИ^˜•hЛ@fgfCšєў)Žz /ƒ§шŽ]%Ы%5)Qџ@;§GŽbz*XЃH2v|ъТ@Џ iЎ[’LЁ%Ю…Ѕ€ H \‚ Ns nг)Ь%ЉY&тЁY‰0П`ІйР- ш-ЫdІ6…slH№OлЙцЌˆ_)УМŠŸъ{єšјrOњfс‹ЗЁж(’&М7 о,Lє* ^DЭ5 ‚DDOŸ0№e`МЅЃ‰Ш€dv)1р4_~šњцЛџt:[ РPт_zХ§:ВzfЮkЃŽ^Н|-яЯ4[ёœ8ЇpV"ћѕћ;Iю^RrЫŒ IœuН@вјy6BџЩ.ˆюкHЬz$ЮeDР—иЙ"9ЦЖ a^_уyсH{ыF™+ƒ-й[n_k{ыŽўаюF#сctн”gС+lHљЗѓ›‰Ц= f†x%Š*ЉАu1 о`Cš>tPЬGŠЪ‹""PW№аЌD1œ [.lќ‹sЏQ>ђѓ/5к "Pћ№фЌФjє uP@ @|JєЬ$хъ+lTG@ @<…€Їн3­gтz OЬ№K(WЂяОYАUyЫТнLJтВ‰W@*б‹mPF|/ %*Г` “вИоcRВ,3jП@€%њtыРЛLJp!5a~lТёТŸКК”dŠпќnпЃЯŒ„ХnZттSЕЎk…ЙqієІЯRožПјз@X‰35.‰ЎФu-žZр,*Ев'М1Š™”h‘woк0oiJvЦg>ы œtZ4, иŸЕ~IєфŒoЊ DРЃшЧl_›љцПb;nьЮ?тГRW&ФDЎЮохŽњјtы*ܘ”іЇ$ГXV` ч™” х‹п†oБ~Г§KX@вНw_SvЩђsŽэл Ў:bšˆИСŠрѓ–.ЩЮH‡•бtњГ,Щ’,’ЌRЖжЊњ*XdБnЅ‰ш ж\І.JМќн1ђ'щњjŸy+вщѓD(Ь')йi)ї‹‹ZЕ ›ŸšAЩ#abkjќBVЉд…ѓ•‹ђвЪ •Ю#АxѓVšˆJЅzwСТ№чл:ŸІ$:+бїп,0%(ПX–TЧ<ш4“$З7+sфл“A5yяЦL–СК”dняхРЁ”uјќеГпжЈƒЋ?\Ы<ќ­ЩdЄпОvШ”rnфqЗvyMA–@IVЩr а:иВ6НUЇіT9яэЩу&OЭЙžЙДxЖ]fђBf|ѕь…Ьн‡rn§њRјШ%ГfP}VЪJ^WОѓтѕЌучЏ^8ЧŒ­QB)/K — p§Ьщі=ЛК$)I"^JTўvРTV“вўaeЄ,“ŠЄbЮ3)Сгѕц?,^+xхCFЏ‰џP[Ќе4И•Žяй-А!5Tƒ 4JЇЁЙ[г fq еO іАY#Y’%P’Uвtи‘ „<еlэОCTџХ‘Њ.ƒŠLœ9{lNЬ~оЧI*caЦN‰Ъ\ВˆъяпК{/-dьТјS9ћЉоЎвВ,PpР ž’ŸКЭѕ„H~3+юъ˜Xг9тЃй&%=OЪЪ…]/:>Њ RсЁY$q`і–ВвВ>O7‚› Ž яЯ^O 6Є*.f1-’5=Ф32Q’%!йІ†МамhВ@ tюЛ“Аnz\п—.B#пИЩ*щ)v„V=ьЛ/_nйІeСэ\ЊЯП–;убƒž{rщптщВћІ\р,ѕ‚ RзН 1ФOf•*(еЃЋТв сц6n\О4wтИФŒLіѓsmV^JДЛu№XTe‘LгEv„чsЅЗa}ЇX)•9ŽЈK•4ќ˜ШоКћr.m€šяОўЊР‰PЯШ†$ЂQb),Irzf@k$KВJВJI‚4їpТъє‰C^лqђŒ#ФO›Н0qщЋй C?ЂыЇec1%Ќу(žŒЄo TыŸj–ЙяибSЪ Ц’BС€-=!>1ks›vюb@тљўи УaбЂAЛquŽIщшС]э{єfОrЙ§‹/‚dрM2б(нзЇ&,`eБІgTАFВ$K $Ћ”$Ш‚pгОјRoјœh***TЇтTpo/[P3tPјЬфjn(–І]ЅeБPp-№Т;=)~љŽНюѓ~0+б[LJ{жoš<яЩ1ёэMЋV6к№faLчŽТ›…їfГБkzI:жH–d ”d•’ХСcЧf,[ _”ˆ[•ЬЂ‚З 12>fц‘_‰Э,e_H]АаTЉMП|Ь4v`Wi-“EK€=Ю[НЋGп§UшыЙtƒЁDeC’­ІТ9 ^dR’-Жп) яBuћщя§ЎфuМРNВ!iBC}}ој+w№ “’ИЈў( ьФшщ@Їѕyв‚ўЏёЧ*`™AР C‰ Ÿ№ВЕRз+LJВeі#eуЇšЅDВCТЁярG%ЧЂК Zи:№“’Ћ.‰Зв ŸЛЗrЧ|Н‹€ПЬJЌF‰Ю2ЈЃ„ ЎCРf%ŠjЋ|ь@ EDЈП™•ШЊ‚­ ˆ€Ы№3ЎDх­`C‚зfћсU.‡&xeSЖІ—5vЗвZaЌщн]Lп7№єPЂђЗ–x)‹lH–иЁА‰JєД;Pў„З,МТИмм еГНИvbШЃ‰pЁAdљ)NФж0pЦКŒїЩЂц6оDј8’ьГёXˆџE`нŠU6 ‹шFGFM˜1ЫёТPЂв'М\u•Ч5ќtN;7\’†^Ы"ЕTєq6$vчƒ_`ВДір+фWЮŸШ:qЊђСД)›78rДkЋх\‰’ +l@Ќ:Ш†DБ‚KВ$HpZ:№={њЙъЙ‹WРвLЩ†ЌG@|'јЭW_N›“@з•‚Аiѕ2—ЛЈЌ†с я0ЪvФ­{lHU›$HчВNœ'няїжЅHV‘ѕШсŸЅ"оЬЛй6ЌЭ„;7oК)SO/pVў„ЗЌАђИР†Dщр(нѕ:ь ЇGƒЮ2Њ–йо IDATЧ,А! .4Щ€ d < Ї€ѕ(6!и`6$–‚5=Hиb“ƒЇ&‚ЉѓћЦФ)K|$Ћd9Z @‚дЁg7Xы‰УDуГ"ч+.ѓё=й’ИРzЄМT’Иt7<ј.(Э„Вe.Я‘.pіД;Ау oQcзкбЬМ.Б!‰+nƒ‰QшЧ p‰clG“$.нАц‡ Э„'Cм‘Ѓ†•?с-+LуZ;Šэы ­О $1S ˆсй.Ž&I\ Кіmлчхо€vdBЫі&‚\ц[Ћg%жI6$јqи A218=аƒмG’_ВIёЉ`П7омД"A_Њ…„зпgЛxG=zђ(Е9}цєщsЇЉ|щъ%и­ХѕТgч[ж*cІVEс–›”•Ц 0ЧЂ’гL žу‚‰ˆ|Qнйl uюбk"]П<|Œ@њhО!ы‘9О QRP0БпЋPЌЁ“Ђ”МV:dЈс‘щ}:ШњћІ‘/сЖЗV=dCcc’5дPј ЮА!екY‰p ЩЌX$GР C‰№^Рсў‚ђИШ†фуП<,ž[€БHрЋ}сcpьлK†ЄнЊІ0€†mЕvV"6ўй5FЁЮ"рРиAэ•XgXqDкВy }ћєеп7)vымЭІ“ХЉЎh”­'*DРШ•h<…ј1ŽЭ;€ЁDOORvx.ŽђИШ†фЧПe,К+€Б–Œ5™€C‰Ё-<ўйхoФeЅВвИШ†d‰jъŽјњЌФќУЎпИ.ОŽЎ\€ |ЛБЭрjч'6ЙюА!I*ŽСZŒcОѓм0%­xьŒX'№єPЂв'МБZр ЦXLЇ…3;S’mИ0Ј#lHN^{ŒюGP/ ЙџХЎ!'kЏ-Ё5r`оЬJ4Р*уЖ?%y˜œk06џSыйЙШќ‚зљаc’НnУЈaе_жt`о†Ёu`чЅƒeоt‡xbйf2Еš ™‹l^ћКxђшО]]^ъЭjюРиJєљ7 •dЪJиЁЊ&ЁЊНР*o)дn6$d.ВМтu\“Н&eм?cœС?f%{o6ьPU&€L[тЃЕš ™‹ЬЎuœ>x iычс5!CТБyнгC‰Ъч˜ъ&І$Щ4ё‘aBэfCBц"ёЕFy[њъ‹?‘р`яиŸЭJ-4”nЕš ™‹”ў ъ€нХГЇЙПЗщ&ЎЋcн œэjРќ‚§™ТЈdНD# B;ЂіВ!!s‘єrз0{ХHіŠёЫOSп|їŸЮ@8#В!9џ[Т|gиh|~ь@„Гђ–В!‰`CPŠ€Їн]Г%•Pй$аaА€ЬJзAaыйФ ЁŒ(DР/f%Vз…Ю2ЈЃ„ .BРOf%ŠjЋАu Ё""€(EР?f%Вк`ы€A"р<=”шЬ^y\`C"_F™сѕњJ~№,3 D  я %*;PUЮъПJу"R5f(!J№ѕY‰’z(lИ„ Щ4 ,€РЗД[…ЖъђїзЧNR?ЉІE‚Г/П6hё†­т‚’ЮNыЌOWџц`QСO№ээ{ї1y*§ќЎФоF"bK”u+VиМp5a†ылЙtVЂЇ; JŸ№rз_y\—А!™юmƒA{Ї`пЎSћџ=uп!MS -ZPPpЮЖ­сoEX–tб{‘MšЕH§ъk0ж?ап8wzSкВе=wYZкHФв5uЃ;Ж^9"ыФI@рƒiS7oЎфЋ­іТхы\‰’њ(l@,—А!бмU*UhЛ61Цq›W­œЛjеЧ&ЎœўїŽН^/,ЅЇ.Ÿ<“skD„ 4(њ ;=%9кHD[\˜К(ёђwЧШŸЄыЋ}ц­HW7к&а™їIJvкgї‹‹›ЖjЕ`љв‚Т‚ьORŠ ~jе6l~jFhы64dL’ эПСoОњrкœu#сQТІеЫмс qOгŸРосЋbG\WА!IЪ9hTФйSЧ™RU_5syъ’иi–_…oпГkъ‚йљзr  oВЕйHdол“ЧMžšs=/чF^‹gлe&/d ]§юdцюЏsnх =rњИ1чŽ—К‚Пі1rЩ3Ј2&1Иjp3яfлЊ+‚pчцM—W †aїД;Pў„ЗЌАђИЮГ!YцЎбh*ю‰ѕКvывїЅ-ŸЎ+A^К6ЛIГgЯ}?ќљЖуzuYЗ$й№РєU,‰%­%ђХ‘у0мM pgЮ>+rЃБKVСƒЮ ›ѕЧƒ?b?NbСмK—hؘd Еџjр*УЯ€–„ВeюЈ‹_ЮJЄmЫЃ@NГ!™Ѕf hЕкР†Э$њwfЦ}џэ‰ќkІ›ž… ƒ=p?љљ—хліђu‹bЂ%ХAйD q1убƒž{z§[<]vПњРF4YФ”/tO*M #c’a—a<›}sŸvyшЌDO%*Т[V˜ЦЕvл;Ы†$NЋJ>В{kя~§ЋBUышЎЧOœљѕ7U*ГП0В№n|4ЬД’€\"ёг&E/L\њj68јєo§Д$’э 2&йЦЧПЮЖoл>/ї}9BЫіэнQўк;+б96$1жаџ/М ўƒYй“be™р†195БКo?cќшг‡аЯцъKЕk—'ЕякUœІЅl™HEE…ŠуTœ Ц—-Щз2Б“ФhјЛмя77­H€пь МўЦ87еШџZŠ€pŽ ‰f­t ’|т‰'šЖlећяЏgў–Žэ[ |bФЙШ3§ф˜y{ЗdЎœ5њx№”ювЏBЦvжš I$nUZJB|QС[Тј˜™Gv~e-ЂЌ“daёSeјиˆ’‚‚‰§^…ђхŽз tV"В!!’Ÿо#Xl)ЮА!;ЈГ$dC’ўR0ŒиD VЯJ\аој[}Йg<‰дMjчЌDdCЊ›ПfЌЕѓxz’3 -*чL\‹ФP едцY‰еЕD @”!р—Г•U ­DРќuVЂ’*"’”а#р…ЁDшџ;žaC|КuхclHv]3чйjШЮ §‘%%J G:нРвІ†М№tGРlHtVЂяПY` HbЁІˆгlHЖ3АFdIgD]йд#KлyсYD@Œ€ћиМ0”hїмХ3lH}Є‹Џ“­б)Ё3RbУ2B#р>6$я %*}; Т@іўЇщˆЂ„А›T—3B–6Š`J;I•AfБЬьyЮдЬAXЃ?:Ѓ/вRз/Oќk№ЬЄФюЏ `q™ Ф†Ѓ€0€ iqЬTј§Иƒ rёТPЂн­+”4ё‘ЁА!qЅЗ ЌrЖБqQ[eCВNQњ#zUФєG”Ю `€ љ§и}—ЎXІЃФЦ2jъ8Р†”žŸ˜Ей} (€Ая8є3pš ЩvЎжшdщŒ€:…QЁAВВ6ЖГУГuА!љСЌD/В!йў§YЃ?’Ѕ3Šˆž>aрЫ<јƒі>dmlg‡gы8žaCђТPЂ]c^dCВ8€_$SZЃ?’Ѕ33-vіƒ–ЕagQ@,`?<ЫSЎвxg(бюБQu•ЧE6$l("Š№ТPЂ]­I%”ЧE6$ tD” @_И)Бtђ'Мe~ уњ>’eеPƒx™•XДЊ(!ˆ€K№ТPЂТ'Мl5‰+› *D€"PЗИhYРї\Й‹>ˆ@-EР C‰Ю<с=їhF:Љ.€S5Pе—™ТЬ?цѕ:с§I„Ч_^іЭ ІT{р•oжKхžJTўvРВ>ž‰§Џъ9–ekV­X%2яC ў‚JєД;№Рž^ט”hмˆЕ…аMo|%с |љCRќаPіP8Sšjѕу™5>“б_ˆБEY lљœјзex _ісТ3‡sЙРб‘гЁ{ыЬц…ЁDЯ<сט”xуЧ]ƒ9aШ€ЈHЅVAU€/рIЙqљ‰Њ†FрЉБ3у"  ^€9 |Чq9ЏC059ЉХпdКЗ гїЮPЂЧZ€0)Yю5 KЁaуTТnєDMƒr)Џф`Нt`UгПqMBl9bvЭ@ШйБu\п.ƒZ5šіzXЌiгГpdf мВzе№NэЕz8б‹А бГ6ŒыеЅOh#Sа"5аУ’ЪSЃ=ї D_•"[й`ЉхлƒњCy TGїьbV5 i#(<‹˜=ШLSC\cсYD\ˆД bуЊžTУ‚“)УPЂ?­hДџэ€˜@‰ЩЖ@_ Ї9;ЉЧСWžСмуUхDUО@н4Dн2Dефo*0уm/ 6цsѕь…Ьн‡rn§њRјHјИ;шЈ›‡#kѕmЩHП}эjж‘“97ђ k—'Ѓ ‡Ћ?\Ы<ќэ™ТRЊБL єѓоž~…Фѕ!q=…#ldјhxЗHўЌ€yЪџ/4aЊЂБNп)ƒ ŽК ?в˜w…‰OБoŒИ_\дДUXdЌ0тЈ|‹[•–’_T№<ЈЧЧЬ<Вѓ+qeɘ”`ќ?Ї-zџ_Ÿ}Й›eЁ<.‹‚‚АїPT уа_ь1uШkїџї~з}–oм~сРNRGљKЏјЃ_Gš<=œxmдбЋ—Џх§™&6rЁьсБVr‡ѓЭIЋžzшЫS’YMQЈГь\‘7?Ž@k њГМiД[ш5ec'fг€С–ь-ЗЏЕНuGhї@8эЮ;€ZVmŽхЛхЃuПыиСЊє№/"Pл€ЁDOПhtІџясИ‰‘w‹ю ћ/Цн(ƒВЖ§ А>ˆ!0”/lО•rLŽ=ЅiA<7~УV7€I">Š@­Ÿ•XЛ3-‹ъTPBj5и:Је—+‡(CР;C‰Ю<Ѕ§1ЎВkVˆ€ї№ТPЂ‡ћџ coхЫ r2взХЭkь•й[h{#Ђ=" ‹JФ7 Вр˜)i•˜%Tр`І3nˆ€!P›g%J ЖЋuр“RлI‘dj-ИВыЪђ‡іMp†ц[m-YЊ_ЗbеЭыA5a†яR9кЎžѕ žJ„'­]wІХuŒI Šкљ]qy­ЪКS<яЂхO’<Žюиzхќ‰Ќ'AџСД)›78ц\у†д€€w†іPOЦЕЄQТmяžњА3уќЌњlЇJўЁЮuŠ%Й)€ЃxШР’g џцЋ/ЇЭI€Х‘Аƒ№ЭWлY1P@l#р…ЁDgњсžЫи“Ф‚m<…ГрB—…FMzPЖ™јшч%?пњшVf§‹„™фРЙ(ЛЩ’ бnХ§YfЄ›y7л†u )ƒpчцMй\P‰HРY‰@ЬƒРЄєщJБJ–IEl`)ƒ`ЪRm)џHЗcч2Œщd JнЖ—r3вФС=c},cœh'Q6рYЪ\Вˆк АP„ВeВqQ‰X"р…ЁDѕџ%Еu _йћŸІ#>J21ђбојy Žа@ GžлџЭЁƒМmw`ƒ\H’‘,3вO> (д#€ђdˆ$xz(б“§qЕэЮз~&%–8С k d“…Є;3Б*8I.дОmћМм@€аВ}{Ћ9с D@„€w†сЙ**ƒ}ЂЗткUЪёWVfЊN}ћЮ!КƒœZяшђЪœФЪœ.;"iRТз€Ѕ]fГF.$!P’‰iTѕ{уЭM+€!v^cœ5Kд#j;WЂЈКvЕcR‚мЎЎ%Нƒ~—ˆР.lѕ9uW?>тЂцИ{EїРЖчЪyyo@Ќ‘ I”D53УЧF”Lьї*h‡NŠТЗŒfш`Р:”+бгкыЖ^*[g<ЗЭрЁАл*ŠмЙМЭџъiУњУ#pNW^^žЗ[АY0~41~юIbCƒрЈSŸ3-vІПbЅ8јЮœ8и™% ˆ€BМ0”hзSZR oХ•Уv0cџqлpЖ‚‡!E+Эƒ#Ѓ"р6pЭ‚л Еž№Ÿя[?gO#C‰А{КГр­'М3љКќЪьЛvлхib‚ˆ€“рЌD'Фшˆ@-AР; œyJ{+n-ЙрX DР&Ш•hWœT>WЂАиаgXnЮaсЃщ є•;ШИЇmдjMpvE0 DР:8v`WœQоЂй—­§hjш†ЌТ№СaБЁA0QСxqнрп“7MгНЇк%Т4pVЂ (.W)o4жЈš?Хq „HлpšЄMЈ№ЭиŠвДЇ&9C[cйФЫŸk4FD@‚ЮJ”тњ ђжфЭ˜#j‘sWtё1Mk‘§ОŒТ—фkкФ“‘jВХѓ~†ѓѕтЋlx _ісТ3‡sрЂЃ#ЇзќБ^i:+чXGШg”ЗJЪ % єЃzпўLn§NвЖig,)ќО€„6‚ёгвЎ(Іс—€;Z№0џ5чтѕЇЮп+њХЩŠya(бЎЇЅЄzоŠ+)†]AхeЮ9ЏџьЙ/|Pžм{ФЗ КЅчˆFШ‘;пd}V§Y]k`vnм0МSЛAЯ=Г|ојN}=-ъб=ЛtuЮл C‰vѕЅ%uѓV\I1мT?IњvRЕi!t@шў‚Ѓ§cљR“ѕєАƒаф(7•“ѕ.Ыуцэ•С`Иxќи†‹/ Ž8ЁkRШПmш3шьЇЯ ѓ”mkЬВs^_ю9І{Ч  рwf"J€љКМ-ЂoŽ˜%юќbЉC^ яиvoжЫ7:ѕM я,p†'МЃkцзШ[qЭKсЎа”и:ќмќEљgŽtГ”-„јНє˜)‘АЫšЁв_\V~ Пѓп]8РЮ8"xa(бa_ѕѓV\G u(NH љ[uLлСj;”Ї№ЮgoѕџЩзiЈ%АmC‡ВмТВKљƒ"„Я(й*J{@ЎD{аrГmшг*ш#АLl™™Ќ лА”ЕD%" FРгC‰Ю<ЅНWŒЪˆ@-FРгюР[§gђ­Х—Ћ†ˆ№Д;№жо|aЙ(Hw1x(#Е уyVЩ™ЇДтЭH'ѕРpЊЊ њАr@КёyНNјGO„ЧЬ’ZдК0МшЦСˆZwUх+фiwOi‡яjЯФўWѕЧŽф1ЋвЎZ+ЋАРПЕOЛ‡} mWмќУЎпИ.ОFЎ\€ |БЦЎEЌ-Є<…,:А’№Оќ!)~h({(ЈKSУиYw#@Ї$B.т–š йhљ=э<ѓ„‡К/#79wgJВ wР?Ь CЈЪ* ТЗ–С№ЄмИƒќDUC# 5vїягGP$ё IDATъ˜S ˜06$Тч“щок…žЇ‡эzТKjbo\C%ЁћЮхЩL–Є) в•ХœŠРnєDMƒr)ЏфрГŠ TMџЦ5 БEKwёьщЗѕдЊбИО]`ЫbЫъUCQЋgcc  T8'kУИ^]@€Гря™=ШLSCмаF,–IxLвтц zсигт>d„HBv;ЖBС xг^я_јcО4"„рP&ЅснкЋ3ЈŠћT*˜эвб§ЛоюAГЄРLМГш(ИdCВ RИхшБФВеDш——9;ЉЧё„_pW•06P7 QЗ Q5љ›Ам‡6ƒм–§nфЌљGђKSП:tѕЁ‡л–ŒєлзЎf9™s#rYЛ<‰ъсxѕ‡k™‡Пї?`јш§лЋнЧўэ[‡ОМW5Ч-”~‰aнђф{%їvžКћН’ЛыR’ЋГ;{!sїЁœ[ПО>rЩЌLЯ0ж§^LJY‡Я_=ћ-гƒpѕЛ“™ЛПЮЙ•7dєШщуЦœ;ў]ъvўкoФШ%˜’‚Šа§Ѓ5ŸН>LeG 6З€DdЪJис˜„šhEш_cFsИзЫЖPhpDХЋеM4\‹ЦBг X-Д(ЭЉх д••шЫДšІšЙЩ+ЈССmb“ЋiTѕUSч-<іMѕm,wАpЬ†П§ЮюMщІ'љcВ{KіАIQ WWRŒу{v’ˆi73˜їq’P •jь”Јмk—˜ž ЦИеdJLBь’U4.ь§ ц^2KъЦљK{жoњ(%]eз"рZ6$(›Їняџ‚Фіоlи!&€LгY%П—€Ьэ‚ђЧt`‰!сИр\г ЎeзDЭ5р‚Рavђ­ƒФu›Я}wrт WЧѕ}щтwЧhтEEЃztЅ­ш!/Д.г–Q=сŽЂrh‹а–Я?њпТТ48vщў"8•ФЅ)Аc‘ЖШ!47ЈxYк%`OЧei‚@нB\IPфj яІ,ˆMXП|Ÿ8:ЪЎEР…lHД`а?ішfoџ_\8ЛуŠ„E2MG|dЙ”ы AУЦёС/g€Ы8XEšpОuРеƒ!FyYљCywац…АХ™ы!" "$ПЛяв’(sп!vч щЪmуІLн”ВДяЁл6fЬOZMMЦЇзLгЬŒIгL|жЖ й‰ук6Ж<ЋПЏЗ %“њ2KдИ зВ!AЉjyы€т>,Zh (йtЦЯЌLЖ!G’уcЩёЗ„уЎс$m0љјз‡ФѕŽАёМр;,7)„ЧЃац‡цŸ0ў(lЃ&G.›? ЈЪ@x`Cѕ’c‡о}Ыџ—ЯйЖ5ИAph;™КТИтЄ€)5!юLиSиEˆ$ФЅdJЦИтd•ШМѓжјїgЖщ„/b• х”ЫйjmыцьЯќџлћЈ(ŽДэіФџ0F7 љŽdbдЈё‚IиxЙˆš/ЂСQЂˆˆЌ1.Q‚Ў@"xc1;ыЊ‹&ё†† &4&оVƒFQ7ˆЎ5^Щ‰p>=љŸІ†ЂЇЇ{ІzzІg€šгЇч­ъЗоЊzЊЛњ­ъЎЇХYйёВi№ю/7CУFуйЂ№ЕSxOљџСAh†WEПѓтOœdИЋвМ8є%мПћюЛЧŸœЗleО1E|Л)~ьШW.ЕщЏ0‡G4ЧџiъмЗоXўQнhŸ=-Б€}єЬЗЭщ)ФЪ@r(€=iqRbФгO6ћ]ГЈ?П§еЮ]“HN>†mюŸо ‘ф ™TЫN €a&IE‚*aCКёЫgњ> 6ЄЂэ›œА,MвЄъюOcъ>щёrјюту'ЮўпRЉ’ eŒи5ћќЕйыI[kCѓСвlšІ1М’L+Ы…z‡РІЌЬф9ЩИQtxІИi‰{ёЩБE&С{ЂТњ ыKOt=ѓ}хЮ-Cj”ФбƒЇћ”UOZZaMТњwпЙѕг-К!Ј)9Wцд/ŒюШ|ОsщIыDŽщ1Q.]ЗjЖ‘N˜тI8ѕ;w §дrѕс8ѕюдЃЦтEхИЃЛ=у=iн‹"ЗЮhншџыIл ‹W‚#р^цмщШТGБVШ ћkеKѕЙ™љs{Ћvфw"`tw€;Мг>?kкъJєО“п7=е‡@WuОЄђLŸ+МŠSѕn™аЪђБcwтЬmsъFwšњчLГќ|яoъц/TŸ%-` №eђёЃk ШЋ…ЗVМ%Ьm_eўЭЖЁp[~юхЁѓ­.8МW;TАЭˆЧpXРЉEдlНE|˜7юЅБЮ-~F<‹);:FwЌwјš";Чh„ЄепЎ˜5BVэ:^AЪ25ФЧNБv`Ф8ўЂ…„ C€єДS–c]і_БЊХœ6Wщœltw Щ;@•РbфФ/`ўzё’—ЌbT0‚Е‰‚Љ<)VсPMT|њ_уFМјdџчАюиVєD›зОї—ЛЯ1{ў_Б’—4йЃёАКyёК5ФРС4ф,…Ъ/œ›=)Џ№k”mijbС6ё%ѓaІЇЯƒ3~H>{с‚ +–a•ёA ЉЩЙвsЉЏEŽŸ:sDtJ.Ÿ›vхПЇZЕi3#IњбNбџ5&АXюаОНyћПvIwр§O(‹‘Tpдр˜>їљmЛюабƒ‚A\с3›ФOЕэVщ‰Hџ= )9vv+ЌШšѕ6aC+9|tраDкc+"фH’ОршТФWУff,F_€ДŠlK рQf$MћKЙ—шЏЎбнVя€2:#‘кˆС_ЈОƒK§іђ­ђV56Ф“}Ехs j8іzІwP№€ѕЏ[ХD4эаQS}=_|HdFлЕu;D~ѕeфтЂЂОЯ=С[%G"І0`Yђv|Vn~ŸС$F‘m‰тћF…РЩ#…`ш;†ЋjmtwрФЛ„ШˆюIЭ‰що ‘лBue•p§ІИUJіwjƒDИm•H1€еО_џkhBЅGэаQЕ'ћŸ9zС[7&›W~ўqdФ ‚Ж"EЪ†ЫCЧЅ ЕЌШЖDrЁё А$=mЦ;i.ЌЏЗЯи:ъЄђФЫюЅ T™1§XЊF^fбС™я#вTЪђТѓŠдИЩ9Ÿ~NXш‰@іћŽ ПмоЌ™ЉЯѓСЋџО№шо=ˆ!ДbьlE * џЃЩз/тЕREЖ%Z6.4О;qъЕaЁ.Ќo=№œЉ­ПиР/ЈМRГQБП)мЎЊjn!)ДŸІУЃ&ƒM„ЊЉб=мъaаŠQЕЯПМ,-uXјЋˆіъ’”YB^&GййŠр, Gи‘ћСІ•REЖ%š)dЂŠNWщЏИW{Ю1‰ р™BЕPuЛ–МЌцc*ŽCKЋР‡ЊцzиТŠ9МУ1_аx5zЂЈioNђ(†ЩlbпƒЭsž.>ђФ~QЪЬОСтH?MlEшЬ›wЦGŽЊК/L˜:M‘m‰˜хћ†Š}ФH]ЙЃІѕ‰ ‰БўІј&ОomNmЎю[Ј хih&<в]YљЗХзфњ<Ь№zєГ!yЕwр4ўU­ЛšџздёiјЖ†@омjЖGx G б"`tw щ­DЇ[Ѕ:ЉоR`yѕащ,xBŽ@УCРшю@ѓ{к!чЮПvЬx Ž€ˆ@}ВР—#РаŽ€бноvx ŽG@DРшС‚1sЖmЋ)_S-*›оЫіkючгЂіCƒї„ŠыRуќЫ R4И\пЈ=ёЊ‡ЇМі|i_H№­Ѕ˜–wmЪ\Pї•tлЃЖ1xbLоG ‚­Žг1юАщtaxТzŠ€бнІЛД 1eЬп\’КфћюЃѓєXќhТ‡[[~Э…Gš 1нФЮТ…%t“)оMИ иiжшю€§.эZИѓ•Й‰ГQŒ›јК{SЁesЁ%Орь#јљ>–яЙ{cw Лў‰?т0e–]b“aAрфЁТеЫЭЇЧW3† ŽKЮ№mх‹„Вј<ТbЭŽŽбS‰ИKл)ћ1цKнЈO„бŸр5чš ОЉјMwЌxBG€oКћš„ЂяХ’ZŽКЏам2G М•9ЏО_pцьК}GšЕ№K›nРЪтѕЃetwРx—ж_1™Ц|Iww@єnжЌzhйTьDз ІG(*ќnоV~_mOŠ‹њФcC;=–…OЊЫ ЃФНЗ ?JH5ih–TƒCiв [O‚oР“TP“&W "’ЦS 4V-Ш {Њ[XЯn›>ќ€Q+*—PdДћ“ЭP&vЄ–muЄуВ ˜П6ЗЯР`Ќ……S0%)n1.‹зŸЃбну]ZХdѓ•ЙЄwРошј'jњЫGнСЖЄє›=irффИ‚’Г'ЯvxМ[NfнRH%ѕКИтћБx7абЃоŒŒ8Мї€9С‹ƒFŽZ№—uzъ`o;F‰Ы…oKзэкŸ_tтVХ5bC­ЈЖ„KЖ–muдЫХИ ’ƒ…=њ=ckёЖ‘Zcјмb2wръ/т§?7LЂSЧB"мНЋьЌйЕз’РG\Й8ІяS’єіФјйО‰cТW&Ц‚њ.~^F]0C/1цŽќ цќ­„[хu|іЛцЇVTТ%{ЕхЧД#'qIZЊyЃHЅ#§‘ј№Wєr4.я€јЖ{ŠЌЬ@0dPˆкF”iZ*œ;qjЦиб,РЕщаюњыє}\ќа!)VAJ8ћЦСХъпFЮЋVTТ%ћEтG5!pђјБYб‘щ+rќлYЕ#зdMQЙqydСvOЁ32dъ$яЋНЯ#rc.Qы3&Šъ+ ЉS'NKI_јТЏ‚15Єs;E5'#› еееЄПС>Л08aІ@v&Љ•…p‰E‡Нx\г>…;ЖƒJ'}нк.н$Њ HуKv~fпˆУЃЫ;p‡š;™•]QV!n—+№ЊЂ};Dј˜L>&\~‹’>§d?Й§ЃOѕЮџ№}є h6ПЃ0+!cdЂжBЧŒ7Ї$!z(Ь)’xЕЂ*.Щ,+ъаьИрB0ѕЛ,#uqўVY_`_Ž_EЭяzEХѕJЫяveхэъъЊъъ{5›zЩ—w ŽƒхШ :ь„Ѓљwр‹НћKџS*j-8эM…єИидœїеЌ%g/ХяRй8мЧOŸЙkгЧjšNФЯYєо‚„9 цЖmЏl\ЦШDØ№чАЙG}UˆeщЄдŠЊHИ$ГЌЈCГу‚ 0ЇЬЕqыfї^ИQџсъзoXߘ/ЈЦJOШ_œi€lHŠp`О€ёY#IР„+Пšї#fˆŸ{ zЗЩ7sОрVЃЧw#€™ о­}+лј^)gй'$=ѓ}хЮ-ChЙЙw@ЁЈpѓЗ|ЭЭЈKЩ%Ž€чадћQaтЩшю@ы]кUиjЪ—И;р*ќЙРо[`ђ р;@SўИвјЮšЕO @Јаiл KrХRЉUM-;jмN‘ьTAZЉЉ/ƒѕhжk“Р†DЮЎgZ“ц&g)@}G^жYй&Ѓ Œwi—З+ЩWmOГ“Й††о|ds‹ф&иЪ+ЫСŒДЇt .4/Є Ѕ‚Ш;TЫW#% КTa5’J‘ЇHjP&[Б$ ‚UЌТ„Ke—а сjФкГѓѕŠ:F&вРІШЁRЋ/ЫB%IІFƒjUsЉщzDA=;E;U љ6*ВбГыС‡ЄУ@њНƒЦѕо™AАнгГJ‘ ЛЭ[vК/n{пo4иM/ХǘEоЁ‹о! ТЉёЖўVё’CŠђщОuЙЫдЈMЕЊQ'Е*Ј•С‰,ъKАaш6$2њУž# ?bLTї~ЂН€­{ПAњŸ,=•ˆб;у•щкІвš/aCђ{иЏ}ЇіU­Ћ"ѓF шкwlмАd§Ц%)Гž2„^!Rъ$P‘ТИ‰ HЇY­,IXХ:FОЗzЩТрас?\1'у=ЂмЃЧ34(œ ‰BсuюРlHŠ4>рЋHŸšД4ЇOШр™ ЇХM% Ј›…:щчJ”"Iбˆ~ Дš•QЉБ$9,˜b{ ОљKUСЦм–-ZtыBŒ i^”)l, ™&љЯ06$ўVЂе™*$>šŸычычяяŸзeSфЇO ” ”$(>–ДљЦq`"КqхR›N1ёт4ž95e|ьд^ЯˆДv}ž\QV†2mкЂшчњн­К;8,LJФžЂrHЯ^ЋYB=єыЯП’ Т’tЉlМŒёгgюкє1caыˆДуџ4uю[o,џh Е3dдшk—ЫЦдђьK#fЯЫ ‡­6$дlHН.тЩ иЎ•• ёУ'Цъ+‘Г!Q„­Уиш|›Uі +аъш -ЦйX[ёНbŽГ!БТЪѕМ §обƒŒс5]™ЎB[SОœ ЩUАs;F"Рз,АЂэtфn6$Ї_ьg­Йш5†:zЬїX[A“w@r6$ МюАЖ‘гоk\#рiИwРкšМЪ€ТйXёхz^€€~яРшЉDOнЅйѓЅ}к/);С†Фў\E“E‡§Tt­5і|ЙІpя€dFяРЕlHќкcmЎч ИwРŠ"Ѓw sA@  ?€ЫаВЙав$`u“Ÿрcѓ…В§ьљŒК}|јQvpk!ЪВ“ aў™‘~Мш`ЋпЕкЙm+џ‚3Є№XєШЮйXАт:F"€^@ж wsМп+хŒ=FЖхч\‰V˜ю@?1J{t5TEAC;Еž:,=КUЎјšKщ9ЌЫ•Х[я K“‡і| лвфwъx“ю Ћd‚\(Ќg7Ќu!I№)їЄИX0ˆ эєXRLЈЌLё@ƒ@@ЦЅюРшю€ё.эђЦbЬЗЪlHŠ…/ЖсЂjG&О63cёˆш(i+ЌZœyѕкеM_•`ЛzэТЊ%™Dg§пГ/|[КnзўќЂЗ*Ў‘Шй“&GNŽн`СЩГя–“™bkЧдwdЬQњНўdСъ”‘#^§х.ч†ItыdЌі­ 8’А2|аѓZlЮ‚ЙTЫ{7МЗ$+7ПKO‰izX"ь§d‹љ“­„7%>m>x“^O—?юШп`ЮпJ8Q^ŸcYЙ†.ЭєЂgО=ІяSK\l \ЏИ~Ёь‡ќНџB}А\Пw`twР8Уяђц"љЊэivdА eC BъH_ X—*мЋГДaХђаqуЅ}bШЦŠ—*.QЦ+оЄЫ—ЌГX#aqлŠsO—Чкd1Тшv–‡н‚eŽ‚u0GћО\чœ>Mgј]ЩWmOГSdC"Gs7цЁЯ{.=5Х(€ь4.ќ&_ПˆзbHY/@эДѕokХ)фп–ѕf hOA"І-ЂйqСћ1GщїјмUЃУ;€;`ЛefeW”Uˆлх МЊh•F_N>z„ЙlZЙЬО%%™гв1)ˆЭœ–Dy“BЧŒ7Ї$UўXQ}ЇsŠФˆгДEіЫРz2ц(>wРк:Œ^‰Œ ‰Xџbяўвџ”Š2|)јљM"аEаЌ%PзC`оМ3>rTе}aТT‘IIё‡)szJФ€'qtpx‚DmТŸ0Ы=є”-v–%вiк"ХЌyЄЧ CH"RЦЅп;рlHЪ MиФcMМl1#bаЛMшGхd<–#р98+іŒо1GймфАšыqД  п;0z*бГOБЅю0"ЦеМОfЕ4yRЃшьљиA —=‹їXёwЮ+сW;+О\Я ая§ бщЛДNД=•ЏЮbѓфvИwРŠ•&я€2 p6$V|сфю gIDATЙž  п;0z*бSwiі|i_€іХ[Iœ Щ ЮѓЦ^|ЌuўєИKe—доX%qя€ѕDaє'оlБžБЂЬѕмƒРŠє4|зпђГož{іёЉ;ЪшШмFТ†фt_ Ѕт‰™“„—фъч’ыјящг}žuа`=‹~яРшЉDмЅ]‡’KŒљ’œ ‰YOqQK*ЎуПо§UxРAКДИЩ№8’˜Шavяњ Iњ><ј”@ЌЅХр‰М/рЋъbOQІ12*ђ5jЊЦW!@Z{кLыпЫлЈгcщёгБndєпГџхо+цЌоAЃgC*>txнО#›О.ЙѕгеUKВAг08lєgy›)аŸхх…xДЫ Ъ\аЪaO„ѕ+–•ž(љxЎL&гЪХ$‹g‡ро+кŒоŒ ‰в, ’ћ г…Ѕ/ YЯ ѓžѓеЪ†„•‹р>вЉЧhЙС†ДфэxА!ѕ q08HР†„ ‚Фит3ц‹Ц›ћHйzѕыь‰Е‡˜ЧhёiЉ’,6 ‹АIЏoYНЬBЭx_иВ~У+cOЉx Ž–рМ\єN ­м‡РŽацŽ›ВчsKO њюАТNМЕ=ЕBцЄlHЁсЃ7йм"Й ЖђЪrP!ь)нC‚ Э iB‡‚&6$ЉgH-keCš1v4|~˜ щаюњыдŽ}вЈPТЅ€Лw/ќb;bдчўmќ!S*T чтС/ ь[цG]‚7†ї}†œ!Ё=;ЃS&f%&шїšКЄˆьFявь5IОj{j„К$&yп^ИјлѕhоВЃа}qћлћ~ЃСўkzщ‹йлиЌ—Е.EОЗzЩТрас?\1'у=ŽŒŠ‡bШЗ"ђЋœm;с Ъr9~№рВѓYе1уˆОCfAўdС xR*ЄЈ‰Б”ЭJЯuДЋWБ!™3в+ЎФ.ѕ|ѓ—*ŒkZЖhа­ ЉНŒŠgpшзЁТ-Љ">9fбœасaј†͘M$ЊКіро*jВŒ^‰Œ ЩЯзЯпп?ЏЫІШO#.žЮЬ*ƒй­“v\3„|†IV• zяaCzКoџшчњн­К;8,тѕ™^f|ќŸІЮ}ыхmЁ•Qё€*šт‚ћˆ˜"ђeХyуЪЅ6cтgМц,[ш#шє8’rУ6$П‡§кwj_еК*2OМѕI( hАчќt~“P&<$Ї0V6WOb1"uњ•ЄzRХ†\LЮ†ФкКŒо1Gй:<і{пџёД/Т2wнўvцoш H0(ЛНўЙж p=Ž€#є?Y0z*sћšЎLGАз”Џ” щђЈп„ГцТѕ8Ds:ПГ`єTЂGњДгљ>šм$/Њртщ;' юЙƒМHЋ ›пхYѓ‘‚Ы!5в їXбжфPЃt,@LžЛ'tщ6œЉ&8G€{ЌMрДwРšзуxюАЖ€&я€2 p6$V|Йž  п;0z*бSwiі|i_€іХ[IneCb<…\ђќЯ%F Ье<‚їXagє\Ы†ФZ8ЎЧpм;`E‘б;Й:йX WoѕИЧaXгj’—єщЯЩC…Ћ—›O9оьwЭ† ЮLHдљVЂбq—6 AiFŒљЂ;@*Ю†$…ŽЫо€ziG@Š”З2че7т ЮœEEГ~№8ScБ{0ч*6$,2Yšœ8Дчcи–&ПcЁ @*ёИШШˆhнуБŽ%).Ћ˜AŒ“…Н[єя јВ;sТzvCBj„чJЯEі*X—+‹G(ШЯ кЉѕдa!X!CulxШ§ {"PM.†РќЕЙ}ƒдS’8п3№ЌоKй№ѕЋзЎnњЊлеkV-Щ$хU‹ЧQ­ŸbќьI“#'Ч”œ1N‡ЧЛхdZHжџ=ћТЗЅ ЬЩ/:qЋт5сшТФWУff,%ЇrёЁЂœ-; Ю\0bд‚ЫђErГRМkQk\0 ’ƒ…м;`E›б;p-’‘Z<*cKFDjЈПfз^EЪ#E~$иaa^ТТD‘XЩšЕI‡}ЎчfрЧ-IKхOXa&Oдід ™;В!ў€е*ЈђU\В%"Ц5ХcлŠsO—џѕч_ХфЕO/]О.#лвnXБc”нlj„ m§лZ‘ љЗ%‡дтqдJП–ŒH->uъФi)щ _иBD0ъ†tngБџh[L+аž…DbЯЮМD“PƒŠ <254Тл—ЅЅІЏ[лЅ[ ћ<"gCкУвT№ЄlHTЮЬЪЎ(ЋЗЫxU‘ХtР&dNKЧ 6sZ%R‹GE2"ЕxpЗњ˜L>&\ќ‹’оІЅ 3оœ’TљcњЬ)вxvц%š„j <Зz§—L™ CѓФЫ2RчoE_€LѕЯдњ—Fе€q яђт0ц+cC"Хјbяўвџ”Š2аК'юAˆ@Aл)*(ŒЭщ)ž„Юр№‰ВZ<ŽЊ‘)Ц'g/ХˆёRй8№чŸ>sзІ‰§ NРleєаPкиYuнŽ22/;tЏЦР5эЭ CžУP…Ž5h.И:Ќ#мœ2ЙŒј Щыдёу:п;рlHЪ­FиФcMМŠ1#bаЛMшGхdњbбвќКвaЃNЭйX›Ÿб; ц(’Vw€Е4\#рј“VPЩ3Fm:pЗ;РXЎЦ`A€?Y`AIдбфHЂGАtэиЄPsY+м;`EL“w@КіjЇfЙРpњНЃ—09}—ж ŸЇђеYlžœ#РŽїXБвфPЮ†ФŠ/зѓє{ќНy3вОdє2еLЩ>ВCz‚ќqЃєdк“G п™>хњхы˜]’ЪВЪrя@ˆjб;№f6$cК crQm'~@ ѓЮ[КЫеpP*Ыtѕ{|юР Rб˜5.ŠldEЅ?hiАКЩЯG№1‰ЉШQЋє. рЪ”кsсs™e—ф‚EuIЃ@Ой;hї'›Ѕ6ЙЌџž>нЋЗир'•\•• V l Єаянр.]S)ЃwŒљ’+œГ!imЌ\˜љrє$/˜Зэ,.*вjылAрзЛП XŽKхнљЙпйЗnп~l_мя€}њлю<5УߘЏЬб˜LЂkPT.љ…›ЗякŠм{k8…€Єhваs'ŽэўlѓЄAZQ ЩnбŠADвx*€LЩ–ьHщшЁB”YƒуˆмД‰Љei-h.dLе?W‚a {ЊOcжў-+&1)8d0ˆќлјЯZ”EuИ i{Ie˜§ќуІ&Іa 6м;`…šе;pRё§XM ЛабЃоŒŒ8Мї€9С‹ƒFŽZ№ Х§Ђ“ЁіЖcEВ#5fЄЬiSbць:їЃљуХџoкv,ЫŠ$Ѓ`ТрАбŸхе >ЫЫ>6 ё‡ОкsыЇŠАоA,ЄЧO—v2›<Јi{Ieи9}іtзР^Ф юАbЫшШмJА4DHю'L –О$d=/Ь{^Ьы‹еВ_ЗЪW&ЦbС_|-Х‚ЇŽSKХЏHvЄЦŒдЌYГ[зЏU^Џoк™кnкЖLa“^пВz™…єёОАe§дХО^q§Bйљ{џUpДФd2-z'…Б.\M8Е@uA,@ро+˜Ф;PлS+dА eC НљШцЩMА•W–ƒaOщ\h^HЪп‡,3є8dФi}?EВ#Ќf›1v4nЮ№'C:ДЛ~у:Щ$9‡ьЧbчШрGh›ИЁ*рVBІ0а! cїю…_l‡Œ}PŸ? —ќрCЦЯN›€->9хр—$wОw+€”$ њНƒЦѕоёlїДЭЈ;@b’їэ…€‹П]ц-; нЗПНя7ьПІ—ЎЗ˜› еееЄПЈ” ШiaдАи’Љ1# m~Юћ0…I„ЬЗтЗћFЭЌmМ"5SфkqЋ—, ОёУs2о#ЉzєА,ЙЗ5Тcм‡@Ў=Юž:I@B№зЩw`єT"уох2ц я€2 AˆšK9б\^ЄРЇzчј>zа™•Мk5Ў!EВ#5f$ŒфЫ/”‹ю=М’џГŒnд,ЫъЈHЭдk`№Э_ЊРТкВEЫ€n]H’ac#Э‹20e€Эœ™18t„ЬКAc_]•†ѓюА‚Ь8w cCђѓѕѓїїЯыВ)ђгˆ‹Ї…3ГЪпжIЛGЎB‚тGZœ§ЭYє˜ЫsЬmлоŠЫˆкSуR$;RcFzqшKЉ1‘п}їнуOЮ[Ж’WГLГ&‚"џгдЙoНБќЃ-TШЈбз.—yЎпнЊЛЯО4tЬєм‡Рˆ1QзЪЪЂН€,†OŒХмСБS'K6Ќw˜у“Нžь];)UцlHR4ъdТ†фїА_ћNэЋZWEц‰ЗЛ3 e­іœпƒюСoЪ„‡‹ыЌдg sЖ5ъs…~йЯ}ЙНфdIђœd‡UХћѕшђжUљОrчёd&?Ѓ ŒwщктЙь_SО`C9bёЗЅ?\ўсVх-є˜;ш5Ђyїьі(њ Њ КЌˆмG@–ОЃBGл„ё l››бS‰УkК2mKь\ŒІ|ЅlH—G§&ќлЙ@uЬkБXГHвьијyуVА$!7;%њЅ~гчЮЋ3ЇQ’1с\џљК­#ulsч1юF@жОШЎММ\OІFwИK3^™zje›–фЋЖЇњdА eCы=Ъ.Оњ"ЛIэЬЭЅВKс}%4!*и“свкЮH @˜p7Ц?єАє(‘дБЭЧИYћb‘тz†еЭЄTP.=AпQА”Tх”t[=<в 6$_Е=­Ў"9JyPњŒ‰ЂњšАхlлIМ; эї4ЁŒ ЇcєŒдЁ™rС0dэ{Vi‘ЂZajV4v•5К;№Ќw ЋМmоЂ;0шхa&r“o*рUХˆ ЖiЦ„OŽY4'!~о|џ€ђяЯ­љЧвTѓRЄ"мD”˜аЁЂ@˜pвV|ˆ ˜p†ŸLТП }Š:4S.€Ќ}єРBv@ЪЉјбнgН‡ &cC"њ_ьнњQZшš D ‹ кЄ SІAŽ;ђЦ•Km:ЦФ[ІrбсШЅ.cТЭˆ FъаLЙрXЮМ7#f];8ЕSŒђ+ЪS œ I4Т†$k*bLм w›а5ŽЪЩx,GРslЪЪНƒ{ŽљЪЏT`–ЁєDWїZ7KЋЯP0ЭЃ8nFdNџŒюМ|ю€рHмpњФт =†@Э`,m–•С!ёбн—ЯШрC=‚4Rфc)8\і j–0]<‹šЅхAŒHv`їgtwP/МŠПк)\Ј/а+”ђ2ЗSЃ_RЎwоьј!Ž€7"€Йƒкˆћк‹ Rnю(CP8’:<ЪЛ‘€ј@cЇјFwояаОЈс­$Ю†dчьс‡М†їдŠmtwрхsœ IэDсёѕЧяЈеХшюРЫН™;8;Рў.CЫцBK“€еM~>‚IФ“ЌwRC–=žОSЌ–„О‘&]Ю@#IЊ[=Иы??@>yЈpѕrѓщ#Ч›§ЎйРСqЩО­,_——кЇЩЅ6ЁP~ўм?3вlѕЛV1s’_v{віЕяCytLь•їЕYtЄхсВ}л‹F’Дё3т!€ьРщŸбS‰№œ.Ћž„Œљ’+М^А!с2Іль… "&ОN№Щ[™ѓъёgЮЎлwЄY ПДщЪдЏ$­ R|С}VtфЫб“ JЮšЗэ,.*’) ш*†%[Ы<ЦŠэEO8ь$gкџ•НbЧvсtЛvэ.^МЈš C7Іšжs†‡'Ÿ<@ДЪž+Е“9sПРƒ6гzYQ}WŸ“g„U2{нŒeЩВ‚ко5ЯВhЪ*{†М\}Ї’CЋьёТ;QzЇђрUбhЫ`i/ы+Шёe%б{„ ъїc'Nы$іЛƒКЫЛnэДњ’щ*IЙ­sс!oA€їDРrHЎ –ЫJFR€юCd.pЯЯ^w@;Кje ‘ю)бV "ЫрgƒБз*]VWфзhяЬь(цЄщФxYQ}кўшDР_@ƒ.ьО•XЛFкъГ№Е‘ Їe‡ъEАfО€жsфzQAZШšГЦЎŠF[Ыu[л"š/ЋкыžП 6ыП]я@те`еt`OёƒdvзNлvdЌх№”^pџо•7Ф'pјi•IЊњЕЇwЊF{MzrЊHЏ –ЫJЊ šј ДžœіКйTтЉЇŸ ”EJѓуsR4МSцН€АœжSl/+щeiахч˜ню@ќJМеяд Ќ‡‘GжiXзГ.о‹ЅcХЧPКоOїЦ^ЋьХеR-šяМНЄжЕ­"П‚\VЕWœ#ЕZѓ:ўэuzNы(’бI1_PqХ2^а*]VнљёkвƒжгzYiезsŽиы4лeјќ‹f›nN€ї:+jП­UvsбмbоKю“М&=ˆ€[ZдЅF•Л,ТЂМЭž—ЮЫГgФ5ѕ а8ЏC/ЉЕћ.+5ў­ЇŠrw@жBА,œF~тВY,цgўАМж"r}W!€–ТНQ\н,№Нpпe…–%Цuž*rОƒ,;Йc_EїŽ ьz:sтЩ9ЏBdЁƒќпœж‹–Jюд{ЊСŽG A" ы PGЙwа ЋЭ+ХрА №џёЛ№РR/mHIENDЎB`‚fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/stylesheets/0000755000175000017500000000000011733011756026406 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/stylesheets/style.css0000644000175000017500000000053011733011756030256 0ustar sylvestresylvestre p { font-family: Arial, Helvetica, "Sans Serif", sans-serif; font-size: medium; } .header td { font-family: Arial, Helvetica, "Sans Serif", sans-serif; color: #DDDDDD; } .header th { font-family: Arial, Helvetica, "Sans Serif", sans-serif; color: black; } .tip { margin-left: 20px; } img { margin-top: 10px; } fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/0000755000175000017500000000000011733011756024776 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page7.html0000644000175000017500000000160111733011756026665 0ustar sylvestresylvestre

Getting Started Page 7

Let's take a little tour of the network and service objects that come standard with the program. You can use these pre-configured objects to build access Policy, NAT, and Routing rules for your firewall.

Objects in the tree are organized in libraries. You can switch between libraries using the drop-down menu above the tree. Firewall Builder comes with a collection of address, service and time interval objects in the library called "Standard". Let's take a look at them.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page12.html0000644000175000017500000000076411733011756026752 0ustar sylvestresylvestre
Getting Started Page 12

You can right-click on the object in the tree to open a pop-up menu. Choose Edit to edit the object.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page14.html0000644000175000017500000000162611733011756026752 0ustar sylvestresylvestre
Getting Started Page 14

Drop-down list "Platforms" switches between supported firewall platforms "iptables", "ipfilter", "pf", "ipfw", "Cisco IOS ACL" and "Cisco ASA (PIX)". The choice of the host OS depends on chosen firewall platform. For example, for "iptables" the program offers "Linux 2.4/2.6", "OpenWRT", "Sveasoft" and "IPCOP". Host OS choices for the firewall platform "PF" are "OpenBSD" and "FreeBSD" and so on.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page10.html0000644000175000017500000000140511733011756026741 0ustar sylvestresylvestre
Getting Started Page 10

The tree and editor panels in Firewall Builder 4.0 are detachable and can "float". You can rearrange them on the screen to keep them away when you do not need them but still within reach so you can quickly find objects and change their properties. Use main menu "View" to open and close panels; the tree panel can be opened and closed using keyboard shortcut Ctrl+T.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page5.html0000644000175000017500000000076511733011756026675 0ustar sylvestresylvestre
Getting Started Page 5

Now would be a good time to save the data to a disk file. To do so use main menu File/Save As.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page15.html0000644000175000017500000000143311733011756026747 0ustar sylvestresylvestre
Getting Started Page 15

Objects located below the Firewall object in the tree represent interfaces of the firewall. We refer to them as "children" of the firewall object. Screenshot below shows properties of interface eth0. To open it in the editor, double-click it in the tree.

IP and MAC addresses of interfaces are represented by child objects in the tree located below the corresponding interface.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page16.html0000644000175000017500000000135711733011756026755 0ustar sylvestresylvestre
Getting Started Page 16

An interface object has several attributes that define its function, such as "Management interface", "external", and so on.

Detailed explanation of the attributes of the Interface object and other objects is available in the online version of the tutorial

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page20.html0000644000175000017500000000115611733011756026745 0ustar sylvestresylvestre
Getting Started Page 20

You can define shell commands that will be included in the generated script at the beginning and at the end of it. These commands can do anything you want, such as configure some subsystems, set up routing, and so on.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page8.html0000644000175000017500000000123111733011756026665 0ustar sylvestresylvestre
Getting Started Page 8

Folder Objects/Hosts contains a few host objects used in standard firewall templates. Folder Objects/Network contains network objects that represent various standard address ranges and blocks, such as multicast, net 127/8, networks defined in RFC1918 and so on.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page18.html0000644000175000017500000000120111733011756026743 0ustar sylvestresylvestre
Getting Started Page 18

Let's inspect the properties of the firewall object. Double-click on the firewall "guardian" in the tree to open it in the editor panel, then click the Firewall Settings button in the editor. This opens a new dialog that looks like this:

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page6.html0000644000175000017500000000124211733011756026665 0ustar sylvestresylvestre
Getting Started Page 6

Firewall Builder uses file extension ".fwb" for the data files. Pick location and name for the new data file, then click Save.

Note that once the firewall data is saved to a file, its name appears in the main window title. Here it is "test.fwb"

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page13.html0000644000175000017500000000240711733011756026747 0ustar sylvestresylvestre
Getting Started Page 13

Every object in Firewall Builder has basic attributes such as Name and Comment. Other attributes depend on the object type.

Attributes of the firewall object include Platform (can be iptables, pf, ipfilter, etc.), Version (platform-dependent) and Host OS. Buttons Host OS Settings and Firewall Settings open dialogs with many additional attributes that depend on the firewall platform and host OS. More on these later.

Object dialogs in Firewall Builder 4.0 do not have button "Apply". When you make changes in the editor, object attributes are updated immediately as soon as you click on another GUI element or hit Tab or Enter.

Tip

Firewall Builder 4.0 has full Undo/Redo functions of unlimited depth. You can monitor undo stack if you open it using main menu "View / Undo stack".

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page0.html0000644000175000017500000000216211733011756026661 0ustar sylvestresylvestre
Getting Started Page 0

This tutorial introduces you to the Firewall Builder program. It walks you through using the tool, from starting it to building and installing simple firewall configuration. This tutorial is also available online on our web site.

You can keep this tutorial open and move along from one step to the next while you perform the steps it describes.

Let's create our first firewall object. To do this, we'll use the object creation menu, accessed by clicking this icon above the object tree: . Choose New Firewall from the menu that appears and then click "Next".

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page28.html0000644000175000017500000000221111733011756026746 0ustar sylvestresylvestre
Getting Started Page 28

Here are the pre-configured NAT rules:

  • Rule 0: Tells the firewall that no address translation should be done for packets traveling from network 192.168.2.0 to 192.168.1.0 (because Translated Source, Translated Destination and Translated Service are left empty).
  • Rule 1: Packets coming into the firewall from internal and DMZ networks are translated so that their source address will change to that of the outside interface on the firewall.
  • Rule 2: Packets coming from the Internet to the interface "outside" will be translated and forwarded to the internal server on DMZ represented by the host object "server on dmz".

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page9.html0000644000175000017500000000125411733011756026673 0ustar sylvestresylvestre
Getting Started Page 9

Firewall Builder also comes with an extensive collection of service objects. The following screenshots show some TCP and UDP objects (all of them do not fit in the screenshot).

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page11.html0000644000175000017500000000060211733011756026740 0ustar sylvestresylvestre
Getting Started Page 11

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page25.html0000644000175000017500000000165411733011756026755 0ustar sylvestresylvestre
Getting Started Page 25

Firewall Builder 4.0 allows you to compile single policy or NAT rule and see generated firewall configuration right there in the GUI. To do this, select any object in the rule you want to process or highlight its leftmost element where rule number is shown, then click right mouse button to open context menu. Click "Compile rule" (keyboard shortcut is "X") to see the result in the panel at the bottom of the main window. The is a great way to experiment with rules and see what is being generated in response to your changes.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page26.html0000644000175000017500000000074111733011756026752 0ustar sylvestresylvestre
Getting Started Page 26

Generated iptables script appears in the panel at the bottom of the main window:

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page17.html0000644000175000017500000000167011733011756026754 0ustar sylvestresylvestre
Getting Started Page 17

Screenshot below shows IP address of interface eth0. The address and netmask are attributes of the child object of the type "IPv4 address". Here the address is "192.0.2.1" and netmask "255.255.255.0". (Netmask can also be specified using slash notation, such as 24, without the actual slash.) Button DNS Lookup can be used to determine IP address using DNS. The program runs DNS query for the "A" record for the name of the parent firewall object. (This only works if the firewall object has the same name as the actual firewall machine.)

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page21.html0000644000175000017500000000071511733011756026746 0ustar sylvestresylvestre
Getting Started Page 21

This tab provides controls for various parameters for logging.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page22.html0000644000175000017500000000136311733011756026747 0ustar sylvestresylvestre
Getting Started Page 22

Screenshot below shows options for the script generation. Notice that Firewall Builder can produce the iptables script in two formats: 1) as a shell script that calls the iptables utility to add each rule one by one, or 2) it can use iptables-restore script to activate the whole policy at once. Other parameters are explained in the online help.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page31.html0000644000175000017500000000217411733011756026750 0ustar sylvestresylvestre
Getting Started Page 31

Tip

If compiler finds problems with configuration and issues any warning or error messages, the program highlights them using different color (blue for warnings and red for errors). Click on the warning and error message and the GUI will switch to the firewall object, open corresponding rule set and highlight the rule that caused the message.

Compiler generates an iptables script in a ".fw" file with the name the same as the firewall object (guardian.fw). The file is placed in the same directory as the .fwb data file. Generated iptables script supports standard startup script parameters "start", "stop", "status", "reload" and can be used in place of the standard system firewall script in the /etc/init.d/ directory.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page32.html0000644000175000017500000000360611733011756026752 0ustar sylvestresylvestre
Getting Started Page 32

Firewall Builder can also transfer generated script to the firewall and activate it there. It uses ssh to do this (putty on Windows). To use the installer, click on the "Install" toolbar button located above the firewall policy panel or in the main toolbar. Firewall Builder will compile the policy (if it is not compiled already) and then open a dialog where you can configure the parameters of the installer. Here you need to enter a password to authenticate to the firewall. Section Section 8.7 of the Users Guide has detailed instructions for setting up and using the installer.

Firewall Builder 4.0 can cache password you entered so you don't have to enter it again and again if you need to reinstall firewall policy several times. The password is never stored on disk in any form, it is only cached in the memory of the running fwbuilder process and discarded when you stop the program. You will need to enter it again when you use the program again after that. However this feature really helps speed up policy update if you need to do it several times. To activate it you need to turn it on in the "Installer" tab of the global preferences dialog (menu Edit / Preferences) and then turn on checkbox "Remember passwords" in the installer dialog. Passwords are stored in a dictionary indexed by the firewall name and user name configured in the "Installer" tab of the firewall object dialog. This means you can have different passwords for different firewall objects.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page19.html0000644000175000017500000000135011733011756026751 0ustar sylvestresylvestre
Getting Started Page 19

The next few pages show other tabs of the advanced settings dialog. You can find detailed explanations of all parameters in the online help and Firewall Builder Users Guide.

This page defines various parameters for the built-in policy installer. The installer uses an SSH client (pscp.exe and plink.exe on Windows) to transfer the generated script to the firewall machine and activate it there.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page30.html0000644000175000017500000000077311733011756026752 0ustar sylvestresylvestre
Getting Started Page 30

Firewall Builder calls the appropriate policy compiler. The dialog displays compiler progress and results.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page24.html0000644000175000017500000000310011733011756026740 0ustar sylvestresylvestre
Getting Started Page 24

Let's take a look at the policy of the template firewall shown below. These rules are intended to be an example, a starting point to help you create your own policy. Most likely you will want to modify the rules to suite your requirements. Explanations of the rules given here are brief because the goal of Getting Started is only to demonstrate how to use Firewall Builder.

  • Rule 0: This is an anti-spoofing rule. It blocks incoming packets on the external interface that have source addresses that belong to the firewall or your internal or DMZ networks. The rule is associated with outside interface and has Direction set to "Inbound".
  • Rule 1: This rule permits any packets on the loopback interface. This is necessary because many services on the firewall machine communicate back to the same machine via loopback.
  • Rule 2: Permit ssh access from internal network to the firewall machine. Notice service object "ssh" in the column Service. (This object can be found in the Standard objects library in the Services/TCP folder.)

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page29.html0000644000175000017500000000264111733011756026756 0ustar sylvestresylvestre
Getting Started Page 29

Now we can compile the policy of the firewall "guardian" and generate the iptables script. To do so, use toolbar button located right above the panel that shows policy and NAT rules. This button compiles rules of the firewall that is opened at the moment. Compiler processes Policy, NAT and Routing rules even though the panel shows only one kind of rules at a time. Another button with the same picture is located in the main toolbar under the main menu bar compiles all firewall objects defined in the object tree. Of course there is no difference if you only have one firewall object.

A new dialog appears that allows you to choose which firewalls you want to compile. The program keeps track of the changes and automatically selects firewalls that require recompile because some object they depend on has changed recently. Obviously this is only useful if you have several firewalls in the object tree. Since the checkbox next to the "guardian" firewall is already checked, click Next to proceed.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page2.html0000644000175000017500000000240611733011756026664 0ustar sylvestresylvestre
Getting Started Page 2

This page of the wizard shows template objects and their configuration. Standard template objects represent firewalls with two or three interfaces, a host with one interface, a web server or a Cisco router. We'll choose "fw template 3", a firewall with three interfaces, for this example. Click Next to create a new firewall object using the chosen template.

Note that the template firewall object comes completely configured, including addresses and netmasks for its interfaces and some basic policy and NAT rules. This configuration is intended as a starting point only. You should reconfigure addresses of interfaces to match those used on your network. We'll see how this is done later on.

Clicking "Next" brings us to the next page of the wizard where we can change configuration of the interfaces of the template firewall.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page1.html0000644000175000017500000000267311733011756026671 0ustar sylvestresylvestre
Getting Started Page 1

The first page of the New Firewall wizard appears. In this page of the wizard we can enter the name for the new firewall object (here it is "guardian"), its platform ("iptables") and its host OS ("Linux 2.4/2.6").

The name of the new firewall object can be anything you want. However, if you want to use SNMP to populate the interface objects, or if you want to use DNS lookups to populate IP address objects, you must name the firewall object the same name as the actual firewall machine.

There are three ways a new firewall can be created: you can use a pre-configured template firewall object, create it from scratch, or use SNMP to create a firewall object with interfaces but an empty policy. This turorial demonstrates the first method, using a template object.

We are going to use one of the standard templates distributed with Firewall Builder, so we'll leave the standard template library path and name in the Template file input field. Click Next to move on to the next page of the tutorial.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page23.html0000644000175000017500000000120011733011756026736 0ustar sylvestresylvestre
Getting Started Page 23

Starting with v3.0, Firewall Builder can generate both IPv4 and IPv6 policies. This tab controls the order in which they are added to the script if you have defined rules for both address families in the Policy objects of the firewall.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page4.html0000644000175000017500000000157211733011756026671 0ustar sylvestresylvestre
Getting Started Page 4

The newly created firewall object is shown below. Its name is "guardian", and it appears in the object tree in the left hand side of the main window in the folder "Firewalls". Double-clicking the object in the tree opens it in the editor panel at the bottom panel of the main window. The editor for the firewall object allows you to change its name, platform and host OS, and also provides buttons that open dialogs for "advanced" settings for the firewall platform and host OS.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page27.html0000644000175000017500000000341311733011756026752 0ustar sylvestresylvestre
Getting Started Page 27

Access policy rules belong to the object "Policy", which is a child object of the firewall and can be found in the tree below it. As with any other object in Firewall Builder, the Policy object has some attributes that you can edit if you double-click on it in the tree.

  • Policy can be IPv4, IPv6, or combined IPv4 and IPv6. In the last case you can use a mix of IPv4 and IPv6 address objects in the same policy (in different rules), and Firewall Builder will automatically figure out which one is which and sort them out.
  • Policy can translate into only the mangle table (used for modifying packets) or a combination of the filter table (used for allowing/blocking packets) and the mangle table. In the latter case, the policy compiler decides which table to use based on the rule action and service object. Some actions, such as "Tag" (which translates into iptables target MARK), go into mangle table.
  • The "Top rule set" is the one the compiler will use to populate iptables built-in chains INPUT/OUTPUT/FORWARD. (If you have only one rule set, then mark it as the top rule set.) If a policy is not marked as "top rule set", generated rules will go into a user-defined chain with the same name as the policy object.

fwbuilder-5.1.0.3599/src/libgui/Tutorial/getting_started/html/page3.html0000644000175000017500000000212711733011756026665 0ustar sylvestresylvestre
Getting Started Page 3

Clicking "Next" brings us to the next page of the wizard where we can change configuration of the interfaces of the template firewall. Template object is preconfigured with generic IP addresses that likely do not match addressing scheme you use on your network. This page of the wizard allows you to change addresses to match your setup.

Here each tab represents an interface of the firewall (eth0, eth1, eth2 and lo). You can change interface name, label, its type and edit, add or remove IP addresses. You can manage both IPv4 and IPv6 addresses on this page of the wizard.

After you adjust IP addresses of all interfaces, click Finish button to create firewall object.

fwbuilder-5.1.0.3599/src/libgui/ObjConflictResolutionDialog.cpp0000644000175000017500000004122711733011756025152 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/Resources.h" #include "ObjConflictResolutionDialog.h" #include "FWObjectPropertiesFactory.h" #include "FWBSettings.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; ObjConflictResolutionDialog::ObjConflictResolutionDialog(QWidget *parent): QDialog(parent) { m_dialog = new Ui::ObjConflictResolutionDialog_q; m_dialog->setupUi(this); setObjectName("ObjConflictResolutionDialog"); alwaysCurrent=false; alwaysNew =false; m_dialog->dlgIcon->setPixmap( QMessageBox::standardIcon( QMessageBox::Warning ) ); defaultLeftButtonText = tr("Keep current object"); defaultRightButtonText = tr("Replace with this object"); if (st->haveGeometry(this)) st->restoreGeometry(this); richText = true; } ObjConflictResolutionDialog::~ObjConflictResolutionDialog() { saveGeometry(); } QString ObjConflictResolutionDialog::makeBold(const QString &str) { QString bold = (richText)?QString(""):""; QString unbold = (richText)?QString(""):""; return QString("%1%2%3").arg(bold).arg(str).arg(unbold); } int ObjConflictResolutionDialog::run(FWObject *o1, FWObject *o2) { // some simple cases where we don't have to ask the user and can make // decision automatically. // CustomService object, if one of the objects adds code string // for a platform which was absent in another if (CustomService::isA(o1) && CustomService::isA(o2)) { bool o1_adds_code_string = false; bool o2_adds_code_string = false; bool code_changes = false; map platforms = Resources::getPlatforms(); for (map::iterator i=platforms.begin(); i!=platforms.end(); i++) { string c1 = CustomService::cast(o1)->getCodeForPlatform( (*i).first ); string c2 = CustomService::cast(o2)->getCodeForPlatform( (*i).first ); if (c1 != c2 && !c1.empty() && !c2.empty()) code_changes = true; if (c1 != c2 && c1.empty()) o2_adds_code_string = true; if (c1 != c2 && c2.empty()) o1_adds_code_string = true; } if (fwbdebug) { qDebug() << "Comparing to CustomService objects:"; qDebug() << "o1=" << o1->getName().c_str() << "o2=" << o2->getName().c_str(); qDebug() << "code_changes=" << code_changes << "o1_adds_code_string=" << o1_adds_code_string << "o2_adds_code_string=" << o2_adds_code_string; } if (!code_changes && o1_adds_code_string) return QDialog::Rejected; } // fill in dialogs even though the user might have // checked checkbox that makes decision without // them having to click a button. This is so that // classes that inherit from ObjConflictResolutionDialog // can use data collected in this method. Particularly // CompareObjectsDialog::run needs it QString leftBtnTxt, rightBtnTxt; bool leftCB, rightCB, leftBtn, rightBtn; leftBtnTxt = defaultLeftButtonText; rightBtnTxt = defaultRightButtonText; leftCB=rightCB=leftBtn=rightBtn=true; QString p1, p2; FWObject *delObjLib1 = o1->getRoot()->getById( FWObjectDatabase::DELETED_OBJECTS_ID ); FWObject *delObjLib2 = o2->getRoot()->getById( FWObjectDatabase::DELETED_OBJECTS_ID ); if (delObjLib1!=NULL && o1->isChildOf(delObjLib1)) { /* This is the case when an object present in the file we are * trying to load has been deleted in the tree. We can not * just ignore deleted object in the tree and load a copy from * the file because it will create a conflict (two objects * with the same ID). I am not sur eI can delete object from * here either. It is unclear how to solve this problem * correctly. Defer to the user. */ p1=tr("Object '%1' has been deleted").arg(makeBold(o1->getName().c_str())); rightBtnTxt = tr("Delete"); leftCB = rightCB = leftBtn = false; } else p1= FWObjectPropertiesFactory::getObjectPropertiesDetailed(o1, true, false, false); if (delObjLib2!=NULL && o2->isChildOf(delObjLib2)) { /* This is the case where object o2 has been deleted in the * file we are trying to load but is present in the tree. One * situation when this occurs is when we preloaded bunch of * libraries and this object is in one of them but has been * deleted in the file. We should ignore deleted objects in * the file and use copy present in the tree. */ cerr << "Deleted object found: o2 " << o2->getId() << " " << o2->getName() << endl; return QDialog::Rejected; p2=tr("Object '%1' has been deleted").arg(makeBold(o2->getName().c_str())); leftBtnTxt = tr("Delete"); leftCB = rightCB = rightBtn = false; } else p2= FWObjectPropertiesFactory::getObjectPropertiesDetailed(o2, true, false, false); m_dialog->useCurrentObj->setText(leftBtnTxt); m_dialog->useNewObj->setText(rightBtnTxt); m_dialog->useNewObj->setEnabled(rightBtn); m_dialog->newAll->setEnabled(rightCB); m_dialog->useCurrentObj->setEnabled(leftBtn); m_dialog->currentAll->setEnabled(leftCB); if (leftBtn) m_dialog->useCurrentObj->setFocus(); else m_dialog->useNewObj->setFocus(); QString f1= FWObjectDatabase::cast(o1->getRoot())->getFileName().c_str(); QString f2= FWObjectDatabase::cast(o2->getRoot())->getFileName().c_str(); current_filename = f1; new_filename = f2; current_objname = o1->getName().c_str(); new_objname = o2->getName().c_str(); current_properties = p1; new_properties = p2; if (f1.isEmpty()) f1=tr("Object '%1' in the objects tree").arg(makeBold(o1->getName().c_str())); else f1=tr("Object '%1' in file %2").arg(makeBold(o1->getName().c_str())).arg(f1); f2=tr("Object '%1' in file %2").arg(makeBold(o2->getName().c_str())).arg(f2); m_dialog->currentObjLbl->setText(f1); m_dialog->newObjLbl->setText(f2); m_dialog->currentObj->clear(); m_dialog->newObj->clear(); QString s; s="\n"; s+=p1; s+="
"; s+=o1->getComment().c_str(); m_dialog->currentObj->moveCursor(QTextCursor::Start); m_dialog->currentObj->append( s ); m_dialog->currentObj->scrollToAnchor("top"); s="
\n"; s+=p2; s+="
"; s+=o2->getComment().c_str(); m_dialog->newObj->moveCursor( QTextCursor::Start ); m_dialog->newObj->append( s ); m_dialog->newObj->scrollToAnchor("top"); if (alwaysCurrent) return QDialog::Rejected; if (alwaysNew) return QDialog::Accepted; return QDialog::exec(); } void ObjConflictResolutionDialog::saveGeometry() { st->saveGeometry(this); } /* * Important * * normally close event is sent when user clicks "close window" button * on the window titlebar. When this event is processed in this method, * the window is still visible so it is safe to retrieve and use its * geometry (it is bad to get geometry of the window when it is hidden * because at that time window manager decorations do not exist * anymore, so window's position on the screen is shiften up and to * the left). * * It seems under certain window manager (at this time it is unknown * which one) in Gnome "close event" is generated after the window is * closed by clicking one of the buttons at the bottom (choosing which * objects to keep). We call saveGeometry from accept and reject to * get size and position when user clicks those buttons. Window is * then closed and (it seems) window manager sends "close" event to * it. By the time when we get control in this method, the window is * already closed and geometry returned for it would be incorrect. * * Finally, I decided to make it so the user can not close conflict * resolution dialog using titlebar button. The user is suppposed to * make a decision, and although closing dialog was equivalent to * clicking one of the choice buttons, it wasn't obvious. So it is * better to disable this completely and make it obvious for the user * that they must make a choice. */ void ObjConflictResolutionDialog::closeEvent(QCloseEvent *e) { if (fwbdebug) qDebug("ObjConflictResolutionDialog::closeEvent"); e->ignore(); } void ObjConflictResolutionDialog::setFlags() { alwaysCurrent = m_dialog->currentAll->isChecked(); alwaysNew = m_dialog->newAll->isChecked(); } void ObjConflictResolutionDialog::accept() { if (fwbdebug) qDebug("ObjConflictResolutionDialog::accept(): isVisible=%d", isVisible()); QDialog::accept(); } void ObjConflictResolutionDialog::reject() { if (fwbdebug) qDebug("ObjConflictResolutionDialog::reject(): isVisible=%d", isVisible()); QDialog::reject(); } // ################################################################ CompareObjectsDialog::CompareObjectsDialog(QWidget *p) : ObjConflictResolutionDialog(p) { richText = false; num_conflicts = 0; column_width[0] = 30; column_width[1] = 30; column_width[2] = 30; column_width[3] = 30; m_dialog->currentAll->hide(); m_dialog->useCurrentObj->hide(); defaultLeftButtonText = ""; defaultRightButtonText = tr("Next"); m_dialog->dialogHeading->setText( tr("The following two objects have the same internal ID but different attributes:") ); m_dialog->newAll->setText( tr("Skip the rest but build report") ); clearReport(); // Note : these keys match strings generated by // FWObjectPropertyFactory::getObjectPropertiesDetailed // That is, getObjectPropertiesDetailed generates text like this: // // Library: TestLibrary // Object Id: id3F3D04676 // Object Type: Firewall // Object Name: guardian // // Keys in report_attributes must match strings before ':' exactly report_attributes.push_back("Name"); report_attributes.push_back("Library"); report_attributes.push_back("Object Id"); report_attributes.push_back("Object Type"); report_attributes.push_back("Object Name"); report_attributes.push_back("Path"); } void CompareObjectsDialog::writeColumn(ostringstream &sstr, int column_num, const QString &txt) { int col_width = column_width[column_num]; sstr << txt.toLatin1().constData() << setw(col_width-txt.length()) << setfill(' ') << ' '; } int CompareObjectsDialog::run(FWObject *o1,FWObject *o2) { ostringstream str; int res = ObjConflictResolutionDialog::run(o1,o2); /* currentObj->setTextFormat(Qt::PlainText); QString l_text = currentObj->text(0); // QTextEdit returns whole paragraph as one line // Since we enforce PlainText, all html formatting // is lost and individual lines are glued together // with some character that prints as '?' // Could be chr(0) ? if (fwbdebug) qDebug("%s",l_text.ascii()); newObj->setTextFormat(Qt::PlainText); QString r_text = newObj->text(0); if (fwbdebug) qDebug("%s",r_text.ascii()); str << l_text << endl; str << r_text << endl; str << endl; */ num_conflicts++; QString prop1 = FWObjectPropertiesFactory::stripHTML(current_properties); QString prop2 = FWObjectPropertiesFactory::stripHTML(new_properties); QStringList proplist1 = prop1.split("\n"); QStringList proplist2 = prop2.split("\n"); QMap propdict1; QMap propdict2; int n = 0; QStringList::Iterator i1 = proplist1.begin(); for ( ; i1!=proplist1.end(); ++i1,++n) { ostringstream tstr; tstr << "key_" << n; QString k = (*i1).section(':',0,0).trimmed(); QString v = (*i1).section(':',1).trimmed(); if (v=="") { v = k; k = tstr.str().c_str(); } if (fwbdebug) qDebug() << QString("proplist1: k='%1' v='%2'") .arg(k).arg(v); propdict1[k] = v; } n = 0; QStringList::Iterator i2 = proplist2.begin(); for ( ; i2!=proplist2.end(); ++i2,++n) { ostringstream tstr; tstr << "key_" << n; QString k = (*i2).section(':',0,0).trimmed(); QString v = (*i2).section(':',1).trimmed(); if (v=="") { v = k; k = tstr.str().c_str(); } if (fwbdebug) qDebug() << QString("proplist2: k='%1' v='%2'") .arg(k).arg(v); propdict2[k] = v; } QStringList::Iterator i3 = report_attributes.begin(); for ( ; i3!=report_attributes.end(); ++i3) { QString attr = *i3; if (fwbdebug) qDebug() << "report_attributes: attr=" << attr; if (!propdict1.contains(attr) || !propdict2.contains(attr)) continue; writeColumn(str, 1, attr); writeColumn(str, 2, propdict1[attr]); writeColumn(str, 3, propdict2[attr]); str << endl; propdict1[attr] = ""; propdict2[attr] = ""; } QMap::Iterator mi1 = propdict1.begin(); for ( ; mi1!=propdict1.end(); ++mi1) { QString key = mi1.key(); QString val = mi1.value(); if (fwbdebug) qDebug() << QString("propdict1: key=%1 val=%2") .arg(key).arg(val); if (val=="") continue; if (key.startsWith("key_")) writeColumn(str, 1, " "); else writeColumn(str, 1, key); if (propdict1.contains(key)) writeColumn(str, 2, propdict1[key]); else writeColumn(str, 2, " "); if (propdict2.contains(key)) writeColumn(str, 3, propdict2[key]); else writeColumn(str, 3, " "); str << endl; propdict1[key] = ""; propdict2[key] = ""; } QMap::Iterator mi2 = propdict2.begin(); for ( ; mi2!=propdict2.end(); ++mi2) { QString key = mi2.key(); QString val = mi2.value(); if (fwbdebug) qDebug() << QString("propdict2: key=%1 val=%2") .arg(key).arg(val); if (val=="") continue; if (key.startsWith("key_")) writeColumn(str, 1, " "); else writeColumn(str, 1, key); if (propdict1.contains(key)) writeColumn(str, 2, propdict1[key]); else writeColumn(str, 2, " "); if (propdict2.contains(key)) writeColumn(str, 3, propdict2[key]); else writeColumn(str, 3, " "); str << endl; } str << setw(78) << setfill('-') << '-' << endl; report.push_back( QString(str.str().c_str()) ); return res; } void CompareObjectsDialog::clearReport() { report.clear(); } list CompareObjectsDialog::getReport() { ostringstream str; str << "File 1: " << current_filename.toLatin1().constData() << endl; str << "File 2: " << new_filename.toLatin1().constData() << endl; str << setw(78) << setfill('-') << '-' << endl; report.push_front( QString(str.str().c_str()) ); return report; } fwbuilder-5.1.0.3599/src/libgui/pfsyncoptionsdialog_q.ui0000644000175000017500000001061711733011756024022 0ustar sylvestresylvestre pfsyncOptionsDialog_q 0 0 405 242 pfsync protocol settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 pfsync Parameters :/Icons/Options:/Icons/Options 0 0 By default pfsync updates are multicast on the local network. This option overrides that behavior and instead unicasts the update to the specified peer. true Use unicast address to communicate with the peer Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() pfsyncOptionsDialog_q accept() 316 472 20 20 buttonCancel clicked() pfsyncOptionsDialog_q reject() 397 472 20 20 fwbuilder-5.1.0.3599/src/libgui/TCPServiceDialog.cpp0000644000175000017500000002060611733011756022637 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "TCPServiceDialog.h" #include "FWCmdChange.h" #include "ProjectPanel.h" #include "fwbuilder/Library.h" #include "fwbuilder/TCPService.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; TCPServiceDialog::TCPServiceDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::TCPServiceDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } TCPServiceDialog::~TCPServiceDialog() { delete m_dialog; } void TCPServiceDialog::loadFWObject(FWObject *o) { obj=o; TCPService *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->ss->setValue( TCPUDPService::cast(s)->getSrcRangeStart() ); m_dialog->se->setValue( TCPUDPService::cast(s)->getSrcRangeEnd() ); m_dialog->ds->setValue( TCPUDPService::cast(s)->getDstRangeStart() ); m_dialog->de->setValue( TCPUDPService::cast(s)->getDstRangeEnd() ); m_dialog->urg_m->setChecked( s->getBool("urg_flag_mask") ); m_dialog->ack_m->setChecked( s->getBool("ack_flag_mask") ); m_dialog->psh_m->setChecked( s->getBool("psh_flag_mask") ); m_dialog->rst_m->setChecked( s->getBool("rst_flag_mask") ); m_dialog->syn_m->setChecked( s->getBool("syn_flag_mask") ); m_dialog->fin_m->setChecked( s->getBool("fin_flag_mask") ); m_dialog->urg_s->setChecked( s->getBool("urg_flag") ); m_dialog->ack_s->setChecked( s->getBool("ack_flag") ); m_dialog->psh_s->setChecked( s->getBool("psh_flag") ); m_dialog->rst_s->setChecked( s->getBool("rst_flag") ); m_dialog->syn_s->setChecked( s->getBool("syn_flag") ); m_dialog->fin_s->setChecked( s->getBool("fin_flag") ); m_dialog->established->setChecked( s->getBool("established") ); m_dialog->commentKeywords->loadFWObject(o); toggleEstablished(); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->ss->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ss); m_dialog->se->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->se); m_dialog->ds->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ds); m_dialog->de->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->de); m_dialog->urg_m->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->urg_m); m_dialog->ack_m->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ack_m); m_dialog->psh_m->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->psh_m); m_dialog->rst_m->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->rst_m); m_dialog->syn_m->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->syn_m); m_dialog->fin_m->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->fin_m); m_dialog->urg_s->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->urg_s); m_dialog->ack_s->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ack_s); m_dialog->psh_s->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->psh_s); m_dialog->rst_s->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->rst_s); m_dialog->syn_s->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->syn_s); m_dialog->fin_s->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->fin_s); m_dialog->established->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->established); init=false; } void TCPServiceDialog::validate(bool *res) { *res = true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res = false; return; } } void TCPServiceDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); // check port ranges (bug #1695481, range start must be <= range end) // See #981 Do this check in applyChanges() rather than validate so we // can update end of range input fields instead of signalling invalid // configuration. int sps = m_dialog->ss->value(); int spe = m_dialog->se->value(); int dps = m_dialog->ds->value(); int dpe = m_dialog->de->value(); if (sps > spe) m_dialog->se->setValue( m_dialog->ss->value() ); if (dps > dpe) m_dialog->de->setValue( m_dialog->ds->value() ); spe = m_dialog->se->value(); dpe = m_dialog->de->value(); TCPUDPService::cast(new_state)->setSrcRangeStart(m_dialog->ss->value()); TCPUDPService::cast(new_state)->setSrcRangeEnd(m_dialog->se->value()); TCPUDPService::cast(new_state)->setDstRangeStart(m_dialog->ds->value()); TCPUDPService::cast(new_state)->setDstRangeEnd(m_dialog->de->value()); new_state->setBool("urg_flag_mask", m_dialog->urg_m->isChecked() ); new_state->setBool("ack_flag_mask", m_dialog->ack_m->isChecked() ); new_state->setBool("psh_flag_mask", m_dialog->psh_m->isChecked() ); new_state->setBool("rst_flag_mask", m_dialog->rst_m->isChecked() ); new_state->setBool("syn_flag_mask", m_dialog->syn_m->isChecked() ); new_state->setBool("fin_flag_mask", m_dialog->fin_m->isChecked() ); new_state->setBool("urg_flag", m_dialog->urg_s->isChecked() ); new_state->setBool("ack_flag", m_dialog->ack_s->isChecked() ); new_state->setBool("psh_flag", m_dialog->psh_s->isChecked() ); new_state->setBool("rst_flag", m_dialog->rst_s->isChecked() ); new_state->setBool("syn_flag", m_dialog->syn_s->isChecked() ); new_state->setBool("fin_flag", m_dialog->fin_s->isChecked() ); new_state->setBool("established", m_dialog->established->isChecked()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } void TCPServiceDialog::toggleEstablished() { bool using_established = m_dialog->established->isChecked(); m_dialog->urg_m->setEnabled( !using_established ); m_dialog->ack_m->setEnabled( !using_established ); m_dialog->psh_m->setEnabled( !using_established ); m_dialog->rst_m->setEnabled( !using_established ); m_dialog->syn_m->setEnabled( !using_established ); m_dialog->fin_m->setEnabled( !using_established ); m_dialog->urg_s->setEnabled( !using_established ); m_dialog->ack_s->setEnabled( !using_established ); m_dialog->psh_s->setEnabled( !using_established ); m_dialog->rst_s->setEnabled( !using_established ); m_dialog->syn_s->setEnabled( !using_established ); m_dialog->fin_s->setEnabled( !using_established ); m_dialog->flags_lbl_1->setEnabled( !using_established ); m_dialog->flags_lbl_2->setEnabled( !using_established ); m_dialog->flags_lbl_3->setEnabled( !using_established ); m_dialog->flags_lbl_u->setEnabled( !using_established ); m_dialog->flags_lbl_a->setEnabled( !using_established ); m_dialog->flags_lbl_p->setEnabled( !using_established ); m_dialog->flags_lbl_r->setEnabled( !using_established ); m_dialog->flags_lbl_s->setEnabled( !using_established ); m_dialog->flags_lbl_f->setEnabled( !using_established ); } fwbuilder-5.1.0.3599/src/libgui/secuwallosadvanceddialog_q.ui0000644000175000017500000015264711733011756024765 0ustar sylvestresylvestre secuwallosAdvancedDialog_q 0 0 510 568 secunet wall: advanced settings Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 Management secunet wall Management settings Qt::Vertical QSizePolicy::Fixed 20 16 Specify secunet wall Management settings below. Please use commas to separate a list of IP addresses. Qt::AlignCenter false Qt::Vertical QSizePolicy::Fixed 20 16 Management access Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Enter the IP addresses or networks of the secunet wall management zone Qt::RightToLeft Syslog servers true Enter IP addresses of logging servers SNMP access Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Enter IP addresses or networks where SNMP requests to this firewall come from RO-SNMP string Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Enter community string for read only SNMP access NTP servers Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Enter IP addresses of NTP servers Qt::Horizontal QSizePolicy::Minimum 40 20 Qt::RightToLeft Nagios access Enter IP addresses or networks for Nagios access Local /var partition Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Enter name for partition that will be mounted to /var Local config partition Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Enter name for local config partition Qt::Horizontal QSizePolicy::Expanding 170 20 Qt::Vertical 20 40 Disable auto-generation of firewall rules for management services Don't create firewall rules :/Icons/DNSName/icon-tree:/Icons/DNSName/icon-tree DNS Client secunet wall DNS settings Qt::Vertical QSizePolicy::Fixed 20 16 Specify secunet wall DNS client related settings below Qt::AlignCenter false Qt::Vertical QSizePolicy::Fixed 20 16 Qt::RightToLeft DNS servers Qt::Horizontal QSizePolicy::Expanding 170 20 Qt::RightToLeft Search domains 0 0 16777215 120 Enter DNS search domains here. One search domain per line Qt::Horizontal QSizePolicy::Minimum 40 20 Qt::RightToLeft Hosts file Enter Hosts entries here. One IP-Address/Name pair per line. These entries will be written to /etc/hosts file on the firewall Qt::Vertical QSizePolicy::Fixed 20 16 The resolution order defines how hostnames will be resolved on the firewall (nsswitch.conf). Default is "Hosts file first" Qt::RightToLeft Resolution order 60 16777215 1 Hosts DNS NIS NIS+ DB 60 16777215 0 Hosts DNS NIS NIS+ DB 60 16777215 0 Hosts DNS NIS NIS+ DB 60 16777215 0 Hosts DNS NIS NIS+ DB 60 16777215 0 Hosts DNS NIS NIS+ DB Qt::Vertical 20 40 Options Specify secunet wall advanced iptables/routing options below Qt::AlignCenter true IPv4 Packet forwarding Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off IPv6 Packet forwarding Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Kernel anti-spoofing protection Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore broadcast pings Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore all pings Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Horizontal QSizePolicy::Expanding 40 20 Accept source route Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Accept ICMP redirects Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore bogus ICMP errors Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Allow dynamic addresses Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Log martians Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false whats this text No change On Off Qt::Vertical 20 40 Qt::Vertical QSizePolicy::Fixed 20 16 Qt::Vertical QSizePolicy::Fixed 20 16 Qt::Horizontal QSizePolicy::Expanding 250 20 :/Icons/TCPService/icon-tree:/Icons/TCPService/icon-tree TCP Qt::Vertical QSizePolicy::Fixed 20 16 These parameters make sense for connections to or from the firewall host Qt::AlignCenter true TCP FIN timeout (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 1000 30 TCP keepalive time (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 10000 1800 TCP window scaling Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off TCP sack Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off TCP fack Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Horizontal QSizePolicy::Expanding 40 20 TCP ECN Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off TCP SYN cookies Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off TCP timestamps Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Vertical 20 40 Qt::Vertical QSizePolicy::Fixed 20 16 Qt::Horizontal QSizePolicy::Expanding 250 20 :/Icons/folder1.png:/Icons/folder1.png Files Qt::Vertical QSizePolicy::Fixed 20 16 Enable support for additional files here. Files in the selected templates directory will be added to the configuration of this Firewall. Qt::AlignCenter true Qt::Vertical QSizePolicy::Fixed 20 16 QFrame::NoFrame QFrame::Plain Add additional files to firewall configuration false Template directory Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false Qt::Horizontal 61 20 false Select templates directory for this Firewall Browse false Open current path in file browser Open Qt::Horizontal 31 20 Qt::Vertical 20 231 secuwall_mgmt_mgmtaddr secuwall_mgmt_loggingaddr secuwall_mgmt_snmpaddr secuwall_mgmt_rosnmp secuwall_mgmt_ntpaddr secuwall_mgmt_nagiosaddr secuwall_mgmt_varpart secuwall_mgmt_confpart buttonOk buttonCancel secuwall_dns_srv1 secuwall_dns_srv2 secuwall_dns_srv3 secuwall_dns_domains secuwall_dns_hosts secuwall_dns_reso1 secuwall_dns_reso2 secuwall_dns_reso3 secuwall_dns_reso4 secuwall_dns_reso5 linux24_ip_forward linux24_ipv6_forward linux24_rp_filter linux24_icmp_echo_ignore_broadcasts linux24_icmp_echo_ignore_all linux24_accept_source_route linux24_accept_redirects linux24_icmp_ignore_bogus_error_responses linux24_ip_dynaddr linux24_log_martians linux24_tcp_fin_timeout linux24_tcp_keepalive_interval linux24_tcp_window_scaling linux24_tcp_sack linux24_tcp_fack linux24_tcp_ecn linux24_tcp_syncookies linux24_tcp_timestamps additional_files_enabled additional_files_dir buttonBrowse buttonOpenURL buttonHelp tabWidget buttonOk clicked() secuwallosAdvancedDialog_q accept() 316 472 20 20 buttonCancel clicked() secuwallosAdvancedDialog_q reject() 397 472 20 20 buttonHelp clicked() secuwallosAdvancedDialog_q help() 68 464 231 245 additional_files_enabled stateChanged(int) secuwallosAdvancedDialog_q additionalChanged(int) 272 141 272 289 buttonBrowse clicked() secuwallosAdvancedDialog_q buttonBrowseClicked() 193 205 272 289 buttonOpenURL clicked() secuwallosAdvancedDialog_q buttonOpenURLClicked() 433 191 249 289 fwbuilder-5.1.0.3599/src/libgui/linux24advanceddialog_q.ui0000644000175000017500000012751611733011756024106 0ustar sylvestresylvestre linux24AdvancedDialog_q Qt::WindowModal 0 0 493 566 Linux 2.4: advanced settings QTabWidget::Rounded 2 Options 12 Qt::Vertical QSizePolicy::Fixed 20 20 IPv4 Packet forwarding Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Horizontal QSizePolicy::Expanding 40 150 IPv6 Packet forwarding Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Kernel anti-spoofing protection Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore broadcast pings Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore all pings Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Accept source route Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Accept ICMP redirects Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Ignore bogus ICMP errors Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Allow dynamic addresses Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false No change On Off Qt::Horizontal QSizePolicy::Fixed 141 21 Log martians Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false whats this text No change On Off Qt::Vertical QSizePolicy::Expanding 93 21 TCP 12 These parameters make sense for connections to or from the firewall host Qt::AlignCenter true Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Vertical QSizePolicy::Expanding 20 30 Qt::Horizontal QSizePolicy::Expanding 100 50 Qt::Horizontal QSizePolicy::Fixed 150 20 0 1000 30 0 10000 1800 No change On Off No change On Off No change On Off No change On Off No change On Off No change On Off TCP sack Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP window scaling Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP ECN Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP SYN cookies Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP keepalive time (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP fack Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP timestamps Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false TCP FIN timeout (sec) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Path Qt::Vertical QSizePolicy::Fixed 20 20 Specify directory path and a file name for each utility on your firewall machine. Leave these empty if you want to use default values. Qt::AlignCenter true iptables: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 300 0 Qt::LeftToRight ip6tables: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ip: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false logger: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false vconfig: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false brctl: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false ifenslave: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false modprobe: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false lsmod: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false ipset: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter iptables-restore: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::LeftToRight ip6tables-restore: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Vertical QSizePolicy::Expanding 20 60 conntrack QFrame::StyledPanel QFrame::Raised CONNTRACK_MAX 64 16777215 CONNTRACK_MAX is the maximum number of "sessions" (connection tracking entries) that can be handled simultaneously by netfilter in kernel memory. 999999999 Qt::Horizontal 242 20 HASHSIZE 0 0 64 16777215 the size of the hash table storing the lists of conntrack entries 999999999 0 0 false background:#fff <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These parameters allow you to tune performance of<br />conntrack module (netfilter state tracking). This<br />should only be necessary for large firewalls with a lot<br />of traffic and many stateful rules.<br />Explanation of these parameters can be found on</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the Internet if you search for &quot;netfilter conntrack performance&quot;<br /><br />Set both to zero to use default values</p></body></html> QFrame::StyledPanel QFrame::Raised 0 0 background: #fff This parameter is used if you run conntrackd in state <br> synchronization mode for a firewall cluster and have<br> kernel &lt;2.6.22<br> Explanation of this parameter can be found at<br> <a href="http://conntrack-tools.netfilter.org/manual.html">http://conntrack-tools.netfilter.org/manual.html</a> Disable TCP window tracking ("ip_conntrack_tcp_be_liberal") true No change On Off Qt::Horizontal 110 20 Qt::Vertical 397 7 Qt::Vertical 20 3 Data Qt::Vertical QSizePolicy::Fixed 20 20 Specify directory where data files (e.g. run-time address table) are found on the firewall. Qt::AlignCenter true Data directory: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 300 0 Qt::Vertical 20 358 Help Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true linux24_ip_forward linux24_ipv6_forward linux24_rp_filter linux24_icmp_echo_ignore_broadcasts linux24_icmp_echo_ignore_all linux24_accept_source_route linux24_accept_redirects linux24_icmp_ignore_bogus_error_responses linux24_ip_dynaddr linux24_log_martians buttonOk buttonCancel linux24_tcp_fin_timeout linux24_tcp_keepalive_interval linux24_tcp_window_scaling linux24_tcp_sack linux24_tcp_fack linux24_tcp_ecn linux24_tcp_syncookies linux24_tcp_timestamps linux24_path_iptables linux24_path_ip6tables linux24_path_ip linux24_path_logger linux24_path_vconfig linux24_path_brctl linux24_path_ifenslave linux24_path_modprobe linux24_path_lsmod linux24_path_iptables_restore linux24_path_ip6tables_restore tabWidget buttonHelp buttonOk clicked() linux24AdvancedDialog_q accept() 316 472 20 20 buttonCancel clicked() linux24AdvancedDialog_q reject() 397 472 20 20 buttonHelp clicked() linux24AdvancedDialog_q help() 68 464 231 245 fwbuilder-5.1.0.3599/src/libgui/instBatchOptionsDialog.cpp0000644000175000017500000000336111733011756024162 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "instBatchOptionsDialog.h" #include #include #include #include using namespace std; using namespace libfwbuilder; instBatchOptionsDialog::instBatchOptionsDialog(QWidget *parent, instConf *_cnf) : instOptionsDialog(parent, _cnf) { m_dialog->dialogTitleLine->setText(QString("

")+ tr("Batch install options")+ QString("

") ); // must reset alt address in the dialog even though it is // hidden. This is because we read it in instDialog::doInstallPage // regardless of wether we perform batch install or not. m_dialog->altAddress->setText(""); m_dialog->altAddressLabel->hide(); m_dialog->altAddress->hide(); } fwbuilder-5.1.0.3599/src/libgui/openaisOptionsDialog.cpp0000644000175000017500000000717111733011756023704 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "openaisOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include #include #include using namespace std; using namespace libfwbuilder; openaisOptionsDialog::openaisOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::openaisOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); FWObject *p = obj; while (p && Cluster::cast(p)==NULL) p = p->getParent(); assert(p != NULL); Cluster *cluster = Cluster::cast(p); Resources *os_res = Resources::os_res[cluster->getStr("host_OS")]; assert(os_res != NULL); string default_address = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/openais/default_address"); string default_port = os_res->getResourceStr( "/FWBuilderResources/Target/protocols/openais/default_port"); string addr = gropt->getStr("openais_address"); if (addr.empty()) gropt->setStr("openais_address", default_address); string port = gropt->getStr("openais_port"); if (port.empty()) gropt->setStr("openais_port", default_port); data.registerOption(m_dialog->openais_address, gropt, "openais_address"); data.registerOption(m_dialog->openais_port, gropt, "openais_port"); data.loadAll(); } openaisOptionsDialog::~openaisOptionsDialog() { delete m_dialog; } void openaisOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void openaisOptionsDialog::reject() { QDialog::reject(); } bool openaisOptionsDialog::validate() { try { InetAddr(m_dialog->openais_address->text().toLatin1().constData()); } catch (FWException &ex) { try { InetAddr(AF_INET6, m_dialog->openais_address->text().toLatin1().constData() ); } catch (FWException &ex) { QMessageBox::critical( this, "Firewall Builder", tr("Invalid IP address '%1'").arg(m_dialog->openais_address->text()), tr("&Continue"), 0, 0, 0 ); return false; } } return true; } fwbuilder-5.1.0.3599/src/libgui/CompilerDriverFactory.h0000644000175000017500000000220311733011756023464 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMPILER_DRIVER_FACTORY_HH__ #define __COMPILER_DRIVER_FACTORY_HH__ #include "CompilerDriver.h" namespace libfwbuilder { class Firewall; }; class CompilerDriverFactory { public: static fwcompiler::CompilerDriver *createCompilerDriver(libfwbuilder::Firewall *fw); }; #endif fwbuilder-5.1.0.3599/src/libgui/ClusterDialog.cpp0000644000175000017500000001724011733011756022311 0ustar sylvestresylvestre/* * ClusterDialog.cpp - Cluster view implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "ClusterDialog.h" #include "utils.h" #include "platforms.h" #include "DialogFactory.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Interface.h" #include #include #include #include using namespace std; using namespace libfwbuilder; ClusterDialog::~ClusterDialog() { delete m_dialog; } ClusterDialog::ClusterDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::ClusterDialog_q; m_dialog->setupUi(this); obj = NULL; connectSignalsOfAllWidgetsToSlotChange(); } void ClusterDialog::loadFWObject(FWObject *o) { obj = o; Cluster *s = dynamic_cast(obj); assert(s != NULL); QString platform = obj->getStr("platform").c_str(); // fill in platform setPlatform(m_dialog->platform, platform); // fill in host OS setHostOS(m_dialog->hostOS, platform, obj->getStr("host_OS").c_str()); updateTimeStamps(); /* Management *mgmt = s->getManagementObject(); assert(mgmt != NULL); */ m_dialog->obj_name->setText(QString::fromUtf8(s->getName().c_str())); m_dialog->commentKeywords->loadFWObject(o); m_dialog->inactive->setChecked(s->getInactive()); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->platform->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->platform); m_dialog->hostOS->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->hostOS); /* m_dialog->fwAdvanced->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->fwAdvanced); m_dialog->osAdvanced->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->osAdvanced); */ m_dialog->inactive->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->inactive); } void ClusterDialog::updateTimeStamps() { QDateTime dt; time_t t; t = obj->getInt("lastModified"); dt.setTime_t(t); m_dialog->last_modified->setText((t)? dt.toString():"-"); t = obj->getInt("lastCompiled"); dt.setTime_t(t); m_dialog->last_compiled->setText((t)? dt.toString():"-"); t = obj->getInt("lastInstalled"); dt.setTime_t(t); m_dialog->last_installed->setText((t)? dt.toString():"-"); } void ClusterDialog::platformChanged() { config_changed = true; emit changed(); QString platform = readPlatform(m_dialog->platform); setHostOS(m_dialog->hostOS, platform, ""); QString pl = readPlatform(m_dialog->platform); resetClusterGroupTypes(); } void ClusterDialog::hostOSChanged() { if (readHostOS(m_dialog->hostOS).toLatin1().constData() != obj->getStr("host_OS")) { config_changed = true; resetClusterGroupTypes(); emit changed(); } } /* * Check if type of failover and state sync groups matches current * platform/host os configuration and if not, fix it. */ void ClusterDialog::resetClusterGroupTypes() { QString host_os = readHostOS(m_dialog->hostOS); list state_sync_types; getStateSyncTypesForOS(host_os, state_sync_types); for (FWObjectTypedChildIterator it = obj->findByType(StateSyncClusterGroup::TYPENAME); it != it.end(); ++it) resetSingleClusterGroupType(*it, state_sync_types); list failover_types; getFailoverTypesForOS(host_os, failover_types); list failover_groups = obj->getByTypeDeep(FailoverClusterGroup::TYPENAME); for (list::iterator it = failover_groups.begin(); it != failover_groups.end(); ++it) resetSingleClusterGroupType(*it, failover_types); } void ClusterDialog::resetSingleClusterGroupType(FWObject *grp, list &allowed_types) { string first_allowed_type; bool match = false; foreach(QStringPair p, allowed_types) { if (first_allowed_type.empty()) first_allowed_type = p.first.toStdString(); if (grp->getStr("type") == p.first.toStdString()) match = true; } if (!match) grp->setStr("type", first_allowed_type); } void ClusterDialog::validate(bool *res) { *res = true; if (!validateName(this, obj, m_dialog->obj_name->text())) { *res = false; return; } // see #2011 - do not allow "/" in firewall object name if (m_dialog->obj_name->text().contains("/")) { *res = false; if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this,"Firewall Builder", tr("Character \"/\" is not allowed in cluster object name"), tr("&Continue"), QString::null,QString::null, 0, 1 ); blockSignals(false); } return; } } void ClusterDialog::applyChanges() { bool autorename_chidren = false; QString dialog_txt = tr( "The name of the object '%1' has changed. The program can also " "rename IP address objects that belong to this object, " "using standard naming scheme 'host_name:interface_name:ip'. " "This makes it easier to distinguish what host or a firewall " "given IP address object belongs to when it is used in " "the policy or NAT rule. The program also renames MAC address " "objects using scheme 'host_name:interface_name:mac'. " "Do you want to rename child IP and MAC address objects now? " "(If you click 'No', names of all address objects that belong to " "%2 will stay the same.)") .arg(QString::fromUtf8(obj->getName().c_str())) .arg(QString::fromUtf8(obj->getName().c_str())); if (obj->getName() != m_dialog->obj_name->text().toUtf8().constData()) { /* see comment about this in FirewallDialog */ blockSignals(true); autorename_chidren = (QMessageBox::warning( this,"Firewall Builder", dialog_txt, tr("&Yes"), tr("&No"), QString::null, 0, 1 )==0 ); blockSignals(false); } std::auto_ptr cmd( new FWCmdChange(m_project, obj, "", autorename_chidren)); FWObject* new_state = cmd->getNewState(); Cluster *s = dynamic_cast(new_state); assert(s != NULL); string oldname = obj->getName(); string newname = string(m_dialog->obj_name->text().toUtf8().constData()); string oldplatform = obj->getStr("platform"); new_state->setName(newname); m_dialog->commentKeywords->applyChanges(new_state); string pl = readPlatform(m_dialog->platform).toLatin1().constData(); new_state->setStr("platform", pl); new_state->setStr("host_OS", readHostOS(m_dialog->hostOS).toLatin1().constData()); s->setInactive(m_dialog->inactive->isChecked()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } updateTimeStamps(); } fwbuilder-5.1.0.3599/src/libgui/ObjectManipulator_create_new.cpp0000644000175000017500000007015311733011756025370 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "platforms.h" #include "events.h" #include "listOfLibrariesModel.h" #include "ObjectManipulator.h" #include "ObjectTreeView.h" #include "newFirewallDialog.h" #include "newClusterDialog.h" #include "newHostDialog.h" #include "newGroupDialog.h" #include "FWCmdChange.h" #include "FWCmdAddObject.h" #include "FWBTree.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/AddressTable.h" #include "fwbuilder/AttachedNetworks.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/CustomService.h" #include "fwbuilder/DNSName.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Host.h" #include "fwbuilder/ICMP6Service.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/IPService.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Interval.h" #include "fwbuilder/IntervalGroup.h" #include "fwbuilder/Library.h" #include "fwbuilder/Management.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include "fwbuilder/ObjectGroup.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/StateSyncClusterGroup.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/TagService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/UserService.h" #include #include #include #include using namespace std; using namespace libfwbuilder; void ObjectManipulator::buildNewObjectMenu() { QMenu* newObjectPopup = new QMenu( mw ); newObjectPopup->setObjectName("newObjectPopup"); addNewObjectMenuItem(newObjectPopup, Library::TYPENAME, tr( "New &Library")); newObjectPopup->addSeparator(); foreach (const char *type, FWBTree::getObjectTypes()) { addNewObjectMenuItem(newObjectPopup, type); } newObjectPopup->addSeparator(); foreach (const char *type, FWBTree::getServiceTypes()) { addNewObjectMenuItem(newObjectPopup, type); } newObjectPopup->addSeparator(); addNewObjectMenuItem(newObjectPopup, Interval::TYPENAME); mw->addNewObjectMenu(newObjectPopup); mw->showNewObjectMenu(); } QAction* ObjectManipulator::addNewObjectMenuItem(QMenu *menu, const char* type_name, const QString &text, int add_to_group_id) { QString icon_path=":/Icons/"; QAction *act; QString menu_item_text = text; if (menu_item_text.isEmpty()) menu_item_text = FWBTree().getTranslatableNewObjectMenuText(type_name); act = menu->addAction(QIcon(icon_path + QString(type_name) + "/icon-tree"), menu_item_text, this, SLOT( createNewObject() )); act->setObjectName(QString("newObject_") + type_name); QMap d; d["type_name"] = QVariant(QString(type_name)); d["add_to_group"] = QVariant(add_to_group_id); act->setData(QVariant(d)); return act; } void ObjectManipulator::createNewObject() { const QAction *action = dynamic_cast(sender()); assert(action!=NULL); QVariant v = action->data(); if (!v.isValid()) return; QMap d = v.value >(); QVariant v1 = d["type_name"]; QString type_name = v1.value(); QVariant v2 = d["add_to_group"]; int add_to_group_id = v2.value(); if (fwbdebug) qDebug() << "ObjectManipulator::createNewObject()" << "type:" << type_name << "add_to_group_id:" << add_to_group_id; FWObject *new_obj = NULL; if (!isObjectAllowed(type_name)) return; QString descr = FWBTree().getTranslatableObjectTypeName(type_name); // FWCmdMacro should be used for commands grouping FWCmdMacro* macro = 0; if (add_to_group_id == -1) macro = new FWCmdMacro( FWBTree().getTranslatableNewObjectMenuText(type_name)); else macro = new FWCmdMacro(tr("Create and add to group")); if (type_name == Firewall::TYPENAME || type_name == Cluster::TYPENAME || type_name == Host::TYPENAME) { // These three functions call separate modal dialogs that can // be cancelled by the user if (type_name == Firewall::TYPENAME) new_obj = newFirewall(macro); if (type_name == Cluster::TYPENAME) new_obj = newCluster(macro); if (type_name == Host::TYPENAME) new_obj = newHost(macro); if (new_obj == NULL) { delete macro; return; } } if (type_name == Library::TYPENAME) new_obj = newLibrary(macro); if (type_name == Interface::TYPENAME) new_obj = newInterface(macro); if (type_name == IPv4::TYPENAME) new_obj = newInterfaceAddress(macro); if (type_name == IPv6::TYPENAME) new_obj = newInterfaceAddressIPv6(macro); if (type_name == physAddress::TYPENAME) new_obj = newPhysicalAddress(macro); if (type_name == FailoverClusterGroup::TYPENAME) new_obj = newFailoverClusterGroup(macro); if (type_name == StateSyncClusterGroup::TYPENAME) new_obj = newStateSyncClusterGroup(macro); if (type_name == Policy::TYPENAME) new_obj = newPolicyRuleSet(macro); if (type_name == NAT::TYPENAME) new_obj = newNATRuleSet(macro); //if (type_name == Routing::TYPENAME) new_obj = newRoutingRuleSet(); if (type_name == AttachedNetworks::TYPENAME) new_obj = newAttachedNetworks(macro); if (new_obj == NULL) new_obj = createObject(type_name, descr, NULL, macro); if (new_obj == NULL) { delete macro; return; } if (add_to_group_id != -1) { FWObject *grp = m_project->db()->findInIndex(add_to_group_id); if (fwbdebug) qDebug() << "ObjectManipulator::createNewObject()" << "Adding to group grp=" << grp; if (grp) { FWCmdChange *cmd = new FWCmdChange( m_project, grp, QObject::tr("Add object to group"), false, macro); FWObject *new_state = cmd->getNewState(); new_state->addRef(new_obj); // if we add new object to a group, we should still open // the object in the editor rather than the group. Command // that adds it to the group opens the group though. Send // event to open the object. QCoreApplication::postEvent( mw, new openObjectInEditorEvent( m_project->getFileName(), new_obj->getId())); } } QCoreApplication::postEvent( m_project, new expandObjectInTreeEvent( m_project->getFileName(), new_obj->getId())); if (Firewall::cast(new_obj)!=NULL) // Cluster too { FWObject *ruleset = new_obj->getFirstByType(Policy::TYPENAME); if (ruleset) QCoreApplication::postEvent( m_project, new openRulesetEvent( m_project->getFileName(), ruleset->getId())); } m_project->undoStack->push(macro); } void ObjectManipulator::newFirewallSlot() { QString descr = FWBTree().getTranslatableObjectTypeName(Firewall::TYPENAME); // FWCmdMacro should be used for commands grouping FWCmdMacro* macro = 0; macro = new FWCmdMacro( FWBTree().getTranslatableNewObjectMenuText(Firewall::TYPENAME)); FWObject *new_obj = newFirewall(macro); if (new_obj == NULL) { delete macro; return; } QCoreApplication::postEvent( m_project, new expandObjectInTreeEvent( m_project->getFileName(), new_obj->getId())); FWObject *ruleset = new_obj->getFirstByType(Policy::TYPENAME); if (ruleset) QCoreApplication::postEvent( m_project, new openRulesetEvent( m_project->getFileName(), ruleset->getId())); m_project->undoStack->push(macro); } FWObject* ObjectManipulator::createObject(const QString &objType, const QString &objName, FWObject *copyFrom, QUndoCommand* macro) { if (fwbdebug) qDebug("ObjectManipulator::createObject check 1"); FWObject *lib = getCurrentLib(); int i = 0; if (fwbdebug) { qDebug("lib: %s %s", lib->getName().c_str(), FWObjectDatabase::getStringId(lib->getId()).c_str()); qDebug("libs->count()=%d", m_objectManipulator->libs->count() ); } while ( lib->getId()==FWObjectDatabase::STANDARD_LIB_ID || lib->getId()==FWObjectDatabase::TEMPLATE_LIB_ID || lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID || lib->isReadOnly() ) { if (i>=m_objectManipulator->libs->count()) { // if (fwbdebug) // qDebug("ObjectManipulator::createObject return NULL"); // return NULL; lib = getCurrentLib(); break; } // lib = idxToLibs[i]; lib = libs_model->getLibrary(i); if (fwbdebug) { qDebug("i=%d",i); qDebug("lib: %s %s", lib->getName().c_str(), FWObjectDatabase::getStringId(lib->getId()).c_str()); } i++; } FWObject *parent = FWBTree().getStandardSlotForObject(lib, objType); if (parent==NULL) { QMessageBox::warning(this,"Firewall Builder", QObject::tr( "Type '%1': new object can not be created because\n" "corresponding branch is missing in the object tree.\n" "Please repair the tree using command 'fwbedit checktree -f file.fwb'.") .arg(objType), "&Continue", QString::null, QString::null, 0, 1 ); return NULL; } return actuallyCreateObject(parent, objType, objName, copyFrom, macro); } FWObject* ObjectManipulator::createObject(FWObject *parent, const QString &objType, const QString &objName, FWObject *copyFrom, QUndoCommand* macro) { FWObject *lib = getCurrentLib(); int i = 0; assert(parent!=NULL); if (fwbdebug) { qDebug("ObjectManipulator::createObject 2: parent=%s", parent->getName().c_str()); qDebug("ObjectManipulator::createObject 2: objType=%s objName=%s", objType.toLatin1().constData(), objName.toLatin1().constData()); } while ( lib->getId()==FWObjectDatabase::STANDARD_LIB_ID || lib->getId()==FWObjectDatabase::TEMPLATE_LIB_ID || lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID || lib->isReadOnly() ) { if (i >= m_objectManipulator->libs->count()) { lib=getCurrentLib(); break; } // lib = idxToLibs[i]; lib = libs_model->getLibrary(i); i++; } if (parent==NULL) parent=lib; return actuallyCreateObject(parent, objType, objName, copyFrom, macro); } FWObject* ObjectManipulator::actuallyCreateObject(FWObject *parent, const QString &objType, const QString &objName, FWObject *copyFrom, QUndoCommand* macro) { FWObject *nobj=NULL; if (!isTreeReadWrite(this, parent)) return NULL; nobj = m_project->db()->create(objType.toLatin1().constData()); assert(nobj!=NULL); if (copyFrom!=NULL) nobj->duplicate(copyFrom, true); if (nobj->isReadOnly()) nobj->setReadOnly(false); QString new_name = makeNameUnique(parent, objName, objType); nobj->setName( string(new_name.toUtf8().constData()) ); if (objType == DNSName::TYPENAME) { if (st->getBool("Objects/DNSName/useCompileTimeForNewObjects")) DNSName::cast(nobj)->setRunTime(false); else DNSName::cast(nobj)->setRunTime(true); if (st->getBool("Objects/DNSName/useNameForDNSRecord")) DNSName::cast(nobj)->setSourceName(nobj->getName()); } if (objType == AddressTable::TYPENAME) { if (st->getBool("Objects/AddressTable/useCompileTimeForNewObjects")) AddressTable::cast(nobj)->setRunTime(false); else AddressTable::cast(nobj)->setRunTime(true); } FWCmdAddObject *cmd = new FWCmdAddObject( m_project, parent, nobj, QObject::tr("Create new %1").arg(objType), macro); FWObject *new_state = cmd->getNewState(); new_state->add(nobj); if (!macro) m_project->undoStack->push(cmd); m_project->db()->setDirty(true); if (objType == IPService::TYPENAME || objType == ICMPService::TYPENAME || objType == UDPService::TYPENAME || objType == TCPService::TYPENAME) reminderAboutStandardLib(); return nobj; } FWObject* ObjectManipulator::newLibrary(QUndoCommand* macro) { FWObject *nlib = FWBTree().createNewLibrary(m_project->db()); // m_project->createNewLibrary(m_project->db()); // At this point new library is already inserted into the object tree // but it has not been added to the QTreeWidget yet. FWCmdAddLibrary *cmd = new FWCmdAddLibrary( m_project, m_project->db(), NULL, QObject::tr("Create library"), macro); FWObject *new_state = cmd->getNewState(); m_project->db()->remove(nlib, false); new_state->add(nlib); // m_project->undoStack->push(cmd); m_project->db()->setDirty(true); return nlib; } FWObject* ObjectManipulator::newPolicyRuleSet(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; QString name = "Policy"; Firewall * fw = Firewall::cast(currentObj); if (fw!=NULL) { int count = 0; for (FWObjectTypedChildIterator it = fw->findByType(Policy::TYPENAME);it != it.end(); ++it) count++; if (count>0) { name+="_"; name+=QString().setNum(count); } } FWObject *o = createObject(currentObj, Policy::TYPENAME, name, NULL, macro); this->getCurrentObjectTree()->sortItems(0, Qt::AscendingOrder); return o; } FWObject* ObjectManipulator::newNATRuleSet(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; QString name = "NAT"; Firewall * fw = Firewall::cast(currentObj); if (fw!=NULL) { int count = 0; for (FWObjectTypedChildIterator it = fw->findByType(NAT::TYPENAME); it != it.end(); ++it) count++; if (count>0) { name += "_"; name += QString().setNum(count); } } FWObject *o = createObject(currentObj, NAT::TYPENAME, name, NULL, macro); this->getCurrentObjectTree()->sortItems(0, Qt::AscendingOrder); return o; } FWObject* ObjectManipulator::newFirewall(QUndoCommand* macro) { FWObject *parent = FWBTree().getStandardSlotForObject(getCurrentLib(), Firewall::TYPENAME); assert(parent); ObjectTreeViewItem* parent_item = allItems[parent]; assert(parent_item); newFirewallDialog *nfd = new newFirewallDialog(this, parent); if (mw->isEditorVisible()) mw->hideEditor(); nfd->setWindowModality(Qt::WindowModal); nfd->setWindowFlags(Qt::Window); nfd->exec(); FWObject *nfw = nfd->getNewFirewall(); delete nfd; if (nfw!=NULL) { FWCmdAddObject *cmd = new FWCmdAddObject( m_project, parent, NULL, QObject::tr("Create new Firewall"), macro); FWObject *new_state = cmd->getNewState(); parent->remove(nfw, false); new_state->add(nfw); } return nfw; } FWObject* ObjectManipulator::newCluster(QUndoCommand* macro, bool fromSelected) { FWObject *parent = FWBTree().getStandardSlotForObject(getCurrentLib(), Cluster::TYPENAME); assert(parent); ObjectTreeViewItem* parent_item = allItems[parent]; assert(parent_item); newClusterDialog *ncd = new newClusterDialog(this, parent); if (mw->isEditorVisible()) mw->hideEditor(); if (fromSelected) { if (fwbdebug) qDebug() << "ObjectManipulator::newCluster: creating cluster from selected firewalls"; ncd->setFirewallList(getCurrentObjectTree()->getSelectedObjects(), true); } else { list fwlist; mw->findAllFirewalls(fwlist); vector fwvector; foreach(Firewall* fw, fwlist) fwvector.push_back(FWObject::cast(fw)); ncd->setFirewallList(fwvector); } if ( ! ncd->exec() == QDialog::Accepted) return NULL; FWObject *ncl = ncd->getNewCluster(); delete ncd; if (ncl) { if (fwbdebug) qDebug() << "ObjectManipulator::newCluster checkpoint 1"; FWCmdAddObject *cmd = new FWCmdAddObject( m_project, parent, NULL, QObject::tr("Create new Cluster"), macro); // newCluster dialog may create backup copies of member firewalls, // to see them in the tree need to reload it. cmd->setNeedTreeReload(true); FWObject *new_state = cmd->getNewState(); parent->remove(ncl, false); new_state->add(ncl); // if (macro) // m_project->undoStack->push(cmd); } return ncl; } void ObjectManipulator::newClusterFromSelected() { FWCmdMacro* macro = new FWCmdMacro( FWBTree().getTranslatableNewObjectMenuText(Cluster::TYPENAME)); FWObject *ncl = newCluster(macro, true); if (ncl == NULL) { delete macro; return; } m_project->undoStack->push(macro); } FWObject* ObjectManipulator::newClusterIface(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; QString new_name = makeNameUnique(currentObj, findNewestInterfaceName(currentObj), Interface::TYPENAME); return createObject(currentObj, Interface::TYPENAME, new_name, NULL, macro); } /* * Creates new state sync group; this method is called by context menu item * associated with Cluster object. * By default assume conntrack protocol and set group type accordingly. */ FWObject* ObjectManipulator::newStateSyncClusterGroup(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; FWObject *o = NULL; FWObject *cluster = currentObj; while (cluster && !Cluster::isA(cluster)) cluster = cluster->getParent(); assert(cluster != NULL); QString host_os = cluster->getStr("host_OS").c_str(); list lst; getStateSyncTypesForOS(host_os, lst); if (lst.size() == 0) { // No state sync. protocols for this host OS QMessageBox::warning( this,"Firewall Builder", tr("Cluster host OS %1 does not support state synchronization").arg(host_os), "&Continue", QString::null, QString::null, 0, 1 ); return NULL; } QString group_type = lst.front().first; o = createObject(currentObj, StateSyncClusterGroup::TYPENAME, tr("State Sync Group"), NULL, macro); o->setStr("type", group_type.toStdString()); return o; } /* * Creates new failover group; this method is called by context menu item * associated with Interface object if its parent is a Cluster object * By default assume VRRP protocol and set group type accordingly. */ FWObject* ObjectManipulator::newFailoverClusterGroup(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; FWObject *o = NULL; QString group_type; if (Interface::isA(currentObj)) { group_type = "vrrp"; } else { qWarning("newClusterGroup: invalid currentObj"); return NULL; } o = createObject(currentObj, FailoverClusterGroup::TYPENAME, tr("Failover group"), NULL, macro); o->setStr("type", group_type.toStdString()); return o; } /* * Creates new AttachedNetworks object; this method is called by * context menu item associated with Interface object */ FWObject* ObjectManipulator::newAttachedNetworks(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; if (Interface::isA(currentObj)) { FWObject *no = createObject(currentObj, AttachedNetworks::TYPENAME, tr("Attached Networks"), NULL, macro); FWObject *parent_host = Host::getParentHost(currentObj); string name = parent_host->getName() + ":" + currentObj->getName() + ":attached"; no->setName(name); return no; } else { qWarning("newAttachedNetworks: invalid currentObj"); return NULL; } } FWObject* ObjectManipulator::newHost(QUndoCommand* macro) { FWObject *parent = FWBTree().getStandardSlotForObject(getCurrentLib(), Host::TYPENAME); assert(parent); newHostDialog *nhd = new newHostDialog(this, parent); if (mw->isEditorVisible()) mw->hideEditor(); nhd->exec(); FWObject *o = nhd->getNewHost(); delete nhd; if (o!=NULL) { FWCmdAddObject *cmd = new FWCmdAddObject( m_project, parent, NULL, QObject::tr("Create new Host"), macro); FWObject *new_state = cmd->getNewState(); parent->remove(o, false); new_state->add(o); } return o; } QString ObjectManipulator::findNewestInterfaceName(FWObject *parent) { time_t newest_interface = 0; QString newest_interface_name = "Interface"; // look for interfaces on the same level (do not use getByTypeDeep() because // it also finds subinterfaces) // find interface that was created last and use its name as a prototype for (FWObjectTypedChildIterator it = parent->findByType(Interface::TYPENAME); it != it.end(); ++it) { if (newest_interface < (*it)->getCreationTime()) { newest_interface = (*it)->getCreationTime(); newest_interface_name = (*it)->getName().c_str(); } } return newest_interface_name; } FWObject* ObjectManipulator::newInterface(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; Interface *new_interface = NULL; FWObject *parent = NULL; // Note that Firewall::cast matches Firewall and Cluster if (Host::isA(currentObj) || Firewall::cast(currentObj)) parent = currentObj; if (Interface::isA(currentObj)) { FWObject *h = Host::getParentHost(currentObj); //FWObject *h = Interface::cast(currentObj)->getParentHost(); bool supports_advanced_ifaces = false; supports_advanced_ifaces = Resources::getTargetCapabilityBool(h->getStr("host_OS"), "supports_subinterfaces"); if (supports_advanced_ifaces) { parent = currentObj; } else { parent = h; } } if (parent == NULL) { // since we can;t find quitable parent for the new interface, // we can't create it. return NULL; } QString new_name = makeNameUnique(parent, findNewestInterfaceName(parent), Interface::TYPENAME); new_interface = Interface::cast( createObject(parent, Interface::TYPENAME, new_name, NULL, macro)); if (new_interface == NULL) return NULL; if (Interface::isA(parent)) { FWObject *parent_host = Host::getParentHost(parent); interfaceProperties *int_prop = interfacePropertiesObjectFactory::getInterfacePropertiesObject( parent_host); int_prop->guessSubInterfaceTypeAndAttributes(new_interface); delete int_prop; //guessSubInterfaceTypeAndAttributes(new_interface); } else new_interface->getOptionsObject()->setStr("type", "ethernet"); return new_interface; } FWObject* ObjectManipulator::newInterfaceAddress(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; if (Interface::isA(currentObj)) { Interface *intf = Interface::cast(currentObj); if (intf && (intf->isDyn() || intf->isUnnumbered() || intf->isBridgePort()) ) return NULL; QString iname = getStandardName(currentObj, IPv4::TYPENAME, "ip"); iname = makeNameUnique(currentObj, iname, IPv4::TYPENAME); return createObject(currentObj, IPv4::TYPENAME, iname, NULL, macro); } // if current object is not interface, create address in the standard folder return createObject(IPv4::TYPENAME, FWBTree().getTranslatableObjectTypeName(IPv4::TYPENAME), NULL, macro); } FWObject* ObjectManipulator::newInterfaceAddressIPv6(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; if (Interface::isA(currentObj)) { Interface *intf = Interface::cast(currentObj); if (intf && (intf->isDyn() || intf->isUnnumbered() || intf->isBridgePort()) ) return NULL; QString iname = getStandardName(currentObj, IPv4::TYPENAME, "ipv6"); iname = makeNameUnique(currentObj, iname, IPv4::TYPENAME); return createObject(currentObj, IPv6::TYPENAME, iname, NULL, macro); } // if current object is not interface, create address in the standard folder return createObject(IPv6::TYPENAME, FWBTree().getTranslatableObjectTypeName(IPv6::TYPENAME), NULL, macro); } FWObject* ObjectManipulator::newPhysicalAddress(QUndoCommand* macro) { FWObject *currentObj = getSelectedObject(); if ( currentObj->isReadOnly() ) return NULL; if (Interface::isA(currentObj)) { Interface *intf = Interface::cast(currentObj); if (intf->getByType(physAddress::TYPENAME).empty()) { QString iname=QString("%1:%2:mac") .arg(QString::fromUtf8(currentObj->getParent()->getName().c_str())) .arg(QString::fromUtf8(currentObj->getName().c_str())); return createObject(currentObj, physAddress::TYPENAME, iname, NULL, macro); } } return NULL; } void ObjectManipulator::reminderAboutStandardLib() { if (st->isReminderAboutStandardLibSuppressed()) return; st->suppressReminderAboutStandardLib(true); QMessageBox::information( this,"Firewall Builder", QObject::tr( "" "Did you know that Firewall Builder comes with over a hunderd " "standard address and service objects that represent " "often used protocols and services? You can " "find them in the object library \"Standard\"." "
" "
" "
" "" "" )); } fwbuilder-5.1.0.3599/src/libgui/ipv6dialog_q.ui0000644000175000017500000002043611733011756021770 0ustar sylvestresylvestre IPv6Dialog_q true 0 0 712 263 IPv6 0 0 QFrame::Box QFrame::Sunken 0 0 350 16 350 16777215 QFrame::Box QFrame::Sunken 55 16777215 Name: false 200 0 0 25 0 0 55 16777215 Address: false 200 0 0 25 Network (bit length): false 0 0 0 25 Resolve Name Qt::Horizontal 40 20 Qt::Vertical 20 40 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name address address editingFinished() IPv6Dialog_q changed() 20 20 20 20 obj_name editingFinished() IPv6Dialog_q changed() 20 20 20 20 dnsLookup clicked() IPv6Dialog_q DNSlookup() 227 194 361 126 changed()
fwbuilder-5.1.0.3599/src/libgui/ProjectPanel.h0000644000175000017500000002275011733011756021605 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: alek@codeminders.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PROJECTPANEL_H #define PROJECTPANEL_H #include "ui_projectpanel_q.h" #include #include namespace libfwbuilder { class FWObjectDatabase; class Firewall; class PolicyRule; class RuleSet; class Rule; class RuleElement; class FWObject; class FWReference; }; class QWidget; class QMdiSubWindow; class QTextEdit; class QUndoStack; class ObjectTreeView; class ObjectManipulator; class findDialog; class FWWindow; class RuleSetView; class RCS; class FWBTree; #define DEFAULT_H_SPLITTER_POSITION 250 #define DEFAULT_V_SPLITTER_POSITION 450 class ProjectPanel: public QWidget { Q_OBJECT; FWWindow *mainW; RCS *rcs; bool systemFile; bool safeMode; bool editingStandardLib; bool editingTemplateLib; bool ruleSetRedrawPending; bool ready; libfwbuilder::FWObjectDatabase *objdb; findDialog *fd; QTimer *autosaveTimer; std::map ruleSetViews; int ruleSetTabIndex; libfwbuilder::FWObject *visibleFirewall; libfwbuilder::RuleSet *visibleRuleSet ; std::vector firewalls; int lastFirewallIdx; bool changingTabs; QString noFirewalls; bool loading_state; // set of object IDs for objects that have been modified recently. // Method updateLastModifiedTimestampForAllFirewalls() uses this // to update lastModified timestamp of all firewalls using these objects. std::set lastModifiedTimestampChangePool; // IDs of objects that need to be updated in the tree. Method // updateObjectInTree() processes them. The key in the map is object ID, // value is a boolean flag, true means need to update the object and // subtree under it. std::map updateObjectsInTreePool; bool treeReloadPending; public: QMdiSubWindow *mdiWindow; Ui::ProjectPanel_q *m_panel; QSet copySet; QUndoStack *undoStack; void readyStatus(bool f) { ready=f; } libfwbuilder::RuleSet* getCurrentRuleSet () {return visibleRuleSet;}; RuleSetView* getCurrentRuleSetView() ; void openRuleSet(libfwbuilder::FWObject *obj, bool immediately=false); void closeRuleSet(libfwbuilder::FWObject *obj) { if ((libfwbuilder::FWObject*)(visibleRuleSet)==obj) visibleRuleSet=NULL;}; ProjectPanel(QWidget *parent); ~ProjectPanel(); void initMain(FWWindow *main); void reset(); void loadObjects(); void loadObjects(libfwbuilder::FWObjectDatabase *db); void clearObjects(); libfwbuilder::FWObjectDatabase* db() { return objdb; }; bool hasObject(libfwbuilder::FWObject* obj) { return objdb->findInIndex(obj->getId()); }; // libfwbuilder::RuleElement* getRE(libfwbuilder::Rule* r, int col ); //wrapers for some ObjectManipulator functions libfwbuilder::FWObject* getCurrentLib(); libfwbuilder::FWObject* createObject(const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL); libfwbuilder::FWObject* createObject(libfwbuilder::FWObject *parent, const QString &objType, const QString &objName, libfwbuilder::FWObject *copyFrom=NULL); void updateObjectInTree(libfwbuilder::FWObject *obj, bool subtree=false); FWWindow* getWindow (){ return mainW;} void moveObject(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); void moveObject(const QString &targetLibName, libfwbuilder::FWObject *obj); void registerModifiedObject(libfwbuilder::FWObject *o); void registerObjectToUpdateInTree(libfwbuilder::FWObject *o, bool update_subtree); void registerTreeReloadRequest(); void registerRuleSetRedrawRequest(); libfwbuilder::FWObject* pasteTo(libfwbuilder::FWObject *target, libfwbuilder::FWObject *obj); ObjectTreeView* getCurrentObjectTree(); void findAllFirewalls(std::list &fws); void showDeletedObjects(bool f); void select(); void unselect(); void copyObj(); bool isManipulatorSelected(); void cutObj(); void pasteObj(); void deleteObj(); libfwbuilder::FWObject* getSelectedObject(); void reopenCurrentItemParent(); void setManipulatorFocus(); void clearManipulatorFocus(); //find dialog functions wrapers void setFDObject(libfwbuilder::FWObject *o); void resetFD(); void clearFirewallTabs(); void closeRuleSetPanel(); void ensureObjectVisibleInRules(libfwbuilder::FWReference *obj); libfwbuilder::FWObject* getVisibleFirewall() { return visibleFirewall; } RuleSetView* getRuleSetViews(libfwbuilder::FWObject *o) {return ruleSetViews[o];}; int findFirewallInList(libfwbuilder::FWObject *f); void updateFirewallName(); void selectRules(); void unselectRules(); void editCopy(); void editCut(); void editDelete(); void editPaste(); bool saveIfModified(bool include_discard_button=true); QString chooseNewFileName(const QString &fname, const QString &title); void setFileName(const QString &fname); void restoreDepends(libfwbuilder::FWObject *obj_old, libfwbuilder::FWObject *nobj, const std::map &objByIds); QString getPageTitle(bool file_path=false); void setActive(); private: public slots: void newObject(); virtual void lockObject(); virtual void unlockObject(); virtual void insertRule(); virtual void addRuleAfterCurrent(); virtual void moveRule(); virtual void moveRuleUp(); virtual void moveRuleDown(); virtual void removeRule(); virtual void copyRule(); virtual void cutRule(); virtual void pasteRuleAbove(); virtual void pasteRuleBelow(); virtual void reopenFirewall(); virtual void redrawRuleSets(); virtual void restoreRuleSetTab(); virtual void fileProp(); virtual bool fileNew(); virtual void fileClose(); virtual void fileSave(); virtual void fileSaveAs(); virtual void fileCommit(); virtual void fileDiscard(); virtual void fileAddToRCS(); virtual void fileImport(); virtual void fileCompare(); virtual void fileExport(); virtual void compile(std::set vf); virtual void compile(); virtual void install(std::set vf); virtual void install(); virtual void inspect(std::set vf); void splitterMoved ( int pos, int index ); virtual void autoSave(); virtual void compileThis(); virtual void installThis(); virtual void inspectThis(); virtual void inspectAll(); virtual void addRule(); void updateLastModifiedTimestampForAllFirewalls(); void updateObjectInTree(); void reloadTree(); void aboutToActivate(); void splitterPositionChanged(int, int); public: QString getFileName(); bool editingLibrary(); void createRCS( const QString &filename); bool loadFromRCS(RCS *rcs); void loadStandardObjects(); bool loadFile(const QString &fileName, bool load_rcs_head); void save(); void saveState(); void loadState(bool open_objects=true); void saveMainSplitter(); void loadMainSplitter(); void loadOpenedRuleSet(); void saveOpenedRuleSet(); void saveLastOpenedLib(); void loadLastOpenedLib(); void loadFirstNonStandardLib(); bool checkin(bool unlock); libfwbuilder::FWObject* loadLibrary(const std::string &libfpath); bool exportLibraryTest(std::list &selectedLibs); void exportLibraryTo(QString fname, std::list &selectedLibs, bool rof); void findExternalRefs(libfwbuilder::FWObject *lib, libfwbuilder::FWObject *root, std::list &extRefs); void setSafeMode(bool f) { safeMode=f; } void setupAutoSave(); RCS * getRCS(); QString printHeader(); void toggleViewTree(bool f); protected: int oldState ; virtual void showEvent(QShowEvent *ev); virtual void hideEvent(QHideEvent *ev); virtual void closeEvent(QCloseEvent *ev); virtual void resizeEvent(QResizeEvent *ev); virtual bool event(QEvent *ev); void setMainSplitterPosition(int w1, int w2); void collapseTree(); void collapseRules(); }; #endif fwbuilder-5.1.0.3599/src/libgui/dnsnamedialog_q.ui0000644000175000017500000001251111733011756022524 0ustar sylvestresylvestre DNSNameDialog_q 0 0 712 239 DNS Name QFrame::Box QFrame::Sunken 0 0 350 16 350 16777215 QFrame::Box QFrame::Sunken Name: false 1 0 0 0 DNS Record: false 0 0 0 0 DNS 'A' record name entered in this input field will be converted to IP address using DNS query during policy compilation if checkbox "Compile time" is turned on, or during firewall policy activation if "Run Time" mode is used. This field can be automatically populated using object name, this is controlled by an option in the global Preferences dialog, tab "Objects" Compile Time Run Time Qt::Vertical 20 66 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name dnsrec r_runtime copyNameToRecord()
fwbuilder-5.1.0.3599/src/libgui/secuwallAdvancedDialog.h0000644000175000017500000000240611733011756023600 0ustar sylvestresylvestre/* * secuwallAdvancedDialog.h - secunet wall advanced host OS settings dialog * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #ifndef __SECUWALLADVANCEDDIALOG_H_ #define __SECUWALLADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class secuwallAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; protected: Ui::secuwallAdvancedDialog_q *m_dialog; public: secuwallAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~secuwallAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); virtual void help(); virtual void editProlog(); virtual void editEpilog(); public slots: virtual void switchLOG_ULOG(); }; #endif // __SECUWALLADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/AddressRangeDialog.cpp0000644000175000017500000001040311733011756023224 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "FWBSettings.h" #include "FWBTree.h" #include "AddressRangeDialog.h" #include "fwbuilder/Library.h" #include "fwbuilder/AddressRange.h" #include "fwbuilder/FWException.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; AddressRangeDialog::AddressRangeDialog(QWidget *parent): BaseObjectDialog(parent) { m_dialog = new Ui::AddressRangeDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } AddressRangeDialog::~AddressRangeDialog() { delete m_dialog; } void AddressRangeDialog::loadFWObject(FWObject *o) { obj=o; AddressRange *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->rangeStart->setText( s->getRangeStart().toString().c_str() ); m_dialog->rangeEnd->setText( s->getRangeEnd().toString().c_str() ); m_dialog->commentKeywords->loadFWObject(o); //apply->setEnabled( false ); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->rangeStart->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->rangeStart); m_dialog->rangeEnd->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->rangeEnd); init=false; } void AddressRangeDialog::validate(bool *res) { *res=true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res=false; return; } AddressRange *s = dynamic_cast(obj); assert(s!=NULL); try { InetAddr(m_dialog->rangeStart->text().toLatin1().constData()); InetAddr(m_dialog->rangeEnd->text().toLatin1().constData()); } catch (FWException &ex) { *res = false; // show warning dialog only if app has focus if (QApplication::focusWidget() != NULL) { blockSignals(true); QMessageBox::critical( this, "Firewall Builder", QString::fromUtf8(ex.toString().c_str()), tr("&Continue"), 0, 0, 0 ); blockSignals(false); } } } void AddressRangeDialog::applyChanges() { std::auto_ptr cmd(new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); AddressRange *s = dynamic_cast(new_state); assert(s!=NULL); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); try { InetAddr addr_start(m_dialog->rangeStart->text().toStdString()); InetAddr addr_end(m_dialog->rangeEnd->text().toStdString()); if (addr_end < addr_start) { addr_end = addr_start; m_dialog->rangeEnd->setText(addr_end.toString().c_str()); } s->setRangeStart(addr_start); s->setRangeEnd(addr_end); } catch (FWException &ex) { } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/FirewallCodeViewer.h0000644000175000017500000000316311733011756022736 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FIREWALLCODEVIEWER_H #define FIREWALLCODEVIEWER_H #include #include #include #include namespace Ui { class FirewallCodeViewer_q; } class FirewallCodeViewer : public QDialog { Q_OBJECT QStringList files; QMap pages; public: FirewallCodeViewer(QStringList files, QString path, QWidget *parent = 0); ~FirewallCodeViewer(); protected: void changeEvent(QEvent *e); private: Ui::FirewallCodeViewer_q *ui; public slots: void fileSelected(int); void hideCloseButton(); void keyPressEvent(QKeyEvent *event) { if (dynamic_cast(this->parent()) == NULL) return QDialog::keyPressEvent(event); event->setAccepted(false); } }; #endif // FIREWALLCODEVIEWER_H fwbuilder-5.1.0.3599/src/libgui/FWBMainWindow_q.ui0000644000175000017500000020375111733011756022342 0ustar sylvestresylvestre FWBMainWindow_q true 0 0 1124 846 0 0 1000 500 Firewall Builder :/Images/fwbuilder3.png:/Images/fwbuilder3.png 2 0 0 950 285 524287 524287 Qt::BottomDockWidgetArea 2 0 0 100 200 10000 10000 QTabWidget::West 2 Output 0 Find 20 12 20 20 0 0 0 160 32767 32767 QFrame::NoFrame QFrame::Plain 0 11 Editor 0 0 0 12 12 0 0 80 0 80 16777215 :/Icons/Cluster/icon Qt::AlignCenter Qt::Vertical 0 58 0 0 200 200 16777215 285 Qt::StrongFocus QFrame::NoFrame QFrame::Sunken 39 0 0 0 0 0 0 16777215 16777215 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 Qt::Horizontal TopToolBarArea false 0 0 1124 26 &Edit Object Tools &Help Rules &File Open Recent Window View Undo Stack 2 2 false true :/Icons/newfile_25.png:/Icons/newfile_25.png &New Object File New Object File :/Icons/openfile_25.png:/Icons/openfile_25.png &Open... Open Ctrl+O :/Icons/save_25.png:/Icons/save_25.png &Save Save Ctrl+S Save &As... Save As true &Print... Print Ctrl+P E&xit Exit &Cut Cut Ctrl+X false C&opy Copy Ctrl+C &Paste Paste Ctrl+V Ctrl+F &Contents... Contents &Index... Index &About About :/Icons/newfile_25.png:/Icons/newfile_25.png New New :/Icons/openfile_25.png:/Icons/openfile_25.png Open Open :/Icons/save_25.png:/Icons/save_25.png Save Save &Close Close :/Icons/Compile:/Icons/Compile Compile Compile Compile rules of all firewall and cluster objects Compile rules of all firewall and cluster objects Compile rules of all firewall and cluster objects :/Icons/Install:/Icons/Install Install Install Install firewall policy of all firewall and cluster objects Install firewall policy of all firewall and cluster objects Install firewall policy of all firewall and cluster objects false :/Icons/back_25.png:/Icons/back_25.png Back Back Move back to the previous object Move back to the previous object :/Icons/newobject_25.png:/Icons/newobject_25.png &New Object New Object Create New Object Ctrl+N :/Icons/search_25.png:/Icons/search_25.png &Find Object Find Object Find object in the tree Find object in the tree Ctrl+F P&references... Preferences... Edit Preferences Add File to &RCS Add File to RCS Delete Delete &Export Library Export Library To a File Import &Library Import Library From a File &Debug Debug Propert&ies Propert&ies Show File Properties Ctrl+I &Discard Discard Discard Changes and Overwrite With Clean Copy Of The Head Revision From RCS Co&mmit Commit Commit Opened File to RCS and Continue Editing Lock Lock Unlock Unlock Object Discovery Object Discovery new item new item Find Conflicting Objects in Two Files Find Conflicting Objects in Two Files Import &Firewall Import Policy Firewall Builder Help true Clear Menu New Object File Release Notes true Object Tree Ctrl+T true Rules true Editor Panel true Undo Stack :/Icons/Inspect:/Icons/Inspect Inspect Import Addresses From File Discover networks and hosts using SNMP :/Icons/forward_25.png:/Icons/forward_25.png Forward Move forward to the next object QUndoView QListView
qundoview.h
ObjectEditorDockWidget QDockWidget
ObjectEditorDockWidget.h
1
InterfaceDialog QWidget
InterfaceDialog.h
1
FirewallDialog QWidget
FirewallDialog.h
1
UserDialog QWidget
UserDialog.h
1
RuleSetDialog QWidget
RuleSetDialog.h
1
LibraryDialog QWidget
LibraryDialog.h
1
IPv4Dialog QWidget
IPv4Dialog.h
1
IPv6Dialog QWidget
IPv6Dialog.h
1
PhysicalAddressDialog QWidget
PhysicalAddressDialog.h
1
AddressRangeDialog QWidget
AddressRangeDialog.h
1
ClusterDialog QWidget
ClusterDialog.h
1
ClusterGroupDialog QWidget
ClusterGroupDialog.h
1
HostDialog QWidget
HostDialog.h
1
NetworkDialog QWidget
NetworkDialog.h
1
NetworkDialogIPv6 QWidget
NetworkDialogIPv6.h
1
CustomServiceDialog QWidget
CustomServiceDialog.h
1
IPServiceDialog QWidget
IPServiceDialog.h
1
ICMPServiceDialog QWidget
ICMPServiceDialog.h
1
TCPServiceDialog QWidget
TCPServiceDialog.h
1
UDPServiceDialog QWidget
UDPServiceDialog.h
1
TagServiceDialog QWidget
TagServiceDialog.h
1
GroupObjectDialog QWidget
GroupObjectDialog.h
1
TimeDialog QWidget
TimeDialog.h
1
RoutingRuleOptionsDialog QWidget
RoutingRuleOptionsDialog.h
1
RuleOptionsDialog QWidget
RuleOptionsDialog.h
1
NATRuleOptionsDialog QWidget
NATRuleOptionsDialog.h
1
DNSNameDialog QWidget
DNSNameDialog.h
1
AddressTableDialog QWidget
AddressTableDialog.h
1
ActionsDialog QWidget
ActionsDialog.h
1
CommentEditorPanel QWidget
CommentEditorPanel.h
1
MetricEditorPanel QWidget
MetricEditorPanel.h
1
CompilerOutputPanel QWidget
CompilerOutputPanel.h
1
BlankDialog QWidget
BlankDialog.h
1
AttachedNetworksDialog QWidget
AttachedNetworksDialog.h
1
DynamicGroupDialog QWidget
DynamicGroupDialog.h
1
addToRCSAction triggered() FWBMainWindow_q fileAddToRCS() -1 -1 20 20 compileAction triggered() FWBMainWindow_q compile() -1 -1 20 20 debugAction triggered() FWBMainWindow_q debug() -1 -1 20 20 editCopyAction triggered() FWBMainWindow_q editCopy() -1 -1 20 20 editCutAction triggered() FWBMainWindow_q editCut() -1 -1 20 20 editDeleteAction triggered() FWBMainWindow_q editDelete() -1 -1 20 20 editFindAction triggered() FWBMainWindow_q editFind() -1 -1 20 20 editPasteAction triggered() FWBMainWindow_q editPaste() -1 -1 20 20 editPrefsAction triggered() FWBMainWindow_q editPrefs() -1 -1 20 20 fileCloseAction triggered() FWBMainWindow_q fileClose() -1 -1 20 20 fileCommitAction triggered() FWBMainWindow_q fileCommit() -1 -1 20 20 fileCompareAction triggered() FWBMainWindow_q fileCompare() -1 -1 20 20 fileDiscardAction triggered() FWBMainWindow_q fileDiscard() -1 -1 20 20 fileExitAction triggered() FWBMainWindow_q fileExit() -1 -1 20 20 fileNewAction triggered() FWBMainWindow_q fileNew() -1 -1 20 20 fileOpenAction triggered() FWBMainWindow_q fileOpen() -1 -1 20 20 filePrintAction triggered() FWBMainWindow_q filePrint() -1 -1 20 20 filePropAction triggered() FWBMainWindow_q fileProp() -1 -1 20 20 fileSaveAction triggered() FWBMainWindow_q fileSave() -1 -1 20 20 fileSaveAsAction triggered() FWBMainWindow_q fileSaveAs() -1 -1 20 20 helpAboutAction triggered() FWBMainWindow_q helpAbout() -1 -1 20 20 helpContentsAction triggered() FWBMainWindow_q helpContents() -1 -1 20 20 helpIndexAction triggered() FWBMainWindow_q helpIndex() -1 -1 20 20 installAction triggered() FWBMainWindow_q install() -1 -1 20 20 libExportAction triggered() FWBMainWindow_q fileExport() -1 -1 20 20 libImportAction triggered() FWBMainWindow_q fileImport() -1 -1 20 20 newObjectAction triggered() FWBMainWindow_q newObject() -1 -1 20 20 ObjectLockAction triggered() FWBMainWindow_q lockObject() -1 -1 20 20 ObjectUnlockAction triggered() FWBMainWindow_q unlockObject() -1 -1 20 20 toolbarFileNew triggered() FWBMainWindow_q fileNew() -1 -1 20 20 toolbarFileOpen triggered() FWBMainWindow_q fileOpen() -1 -1 20 20 toolbarFileSave triggered() FWBMainWindow_q fileSave() -1 -1 20 20 policyImportAction triggered() FWBMainWindow_q importPolicy() -1 -1 20 20 helpAction triggered() FWBMainWindow_q help() -1 -1 370 359 actionClearRecentFiles triggered() FWBMainWindow_q clearRecentFilesMenu() -1 -1 370 359 release_Notes_Action triggered() FWBMainWindow_q showReleaseNotes() -1 -1 370 359 actionObject_Tree triggered() FWBMainWindow_q toggleViewObjectTree() -1 -1 370 359 actionEditor_panel triggered() FWBMainWindow_q toggleViewEditor() -1 -1 370 359 editorPanelTabWidget currentChanged(int) FWBMainWindow_q editorPanelTabChanged(int) 511 708 540 422 actionUndo_view triggered() FWBMainWindow_q toggleViewUndo() -1 -1 554 422 inspectAction triggered() FWBMainWindow_q inspect() -1 -1 571 422 ImportAddressesFromFileAction triggered() FWBMainWindow_q toolsImportAddressesFromFile() -1 -1 571 422 SNMPDiscoveryAction triggered() FWBMainWindow_q toolsSNMPDiscovery() -1 -1 571 422 clearRecentFilesMenu() showReleaseNotes() toggleViewObjectTree() toggleViewRules() toggleViewEditor() toggleViewSearch() editorPanelTabChanged(int) toggleViewUndo() showSummary() showTutorial() inspect() toolsImportAddressesFromFile() toolsSNMPDiscovery() back() forward()
fwbuilder-5.1.0.3599/src/libgui/newFirewallDialog_from_template.cpp0000644000175000017500000003205611733011756026067 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "events.h" #include "platforms.h" #include "newFirewallDialog.h" #include "FWBSettings.h" #include "FWBTree.h" #include "InterfaceEditorWidget.h" #include "InterfacesTabWidget.h" #include "FWWindow.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include "fwbuilder/Network.h" #include "fwbuilder/NetworkIPv6.h" #include #include using namespace libfwbuilder; using namespace std; class FindNetwork : public FWObjectFindPredicate { InetAddrMask net; public: FindNetwork(InetAddrMask _net) { net = _net; } virtual bool operator()(FWObject *o) const { FWObject *obj = FWReference::getObject(o); if (Address::cast(obj)) { const InetAddrMask *am = Address::cast(obj)->getInetAddrMaskObjectPtr(); if (am && (*am) == net) return true; } return false; } }; void newFirewallDialog::createFirewallFromTemplate() { QListWidgetItem *itm = m_dialog->templateList->currentItem(); FWObject *template_fw = templates[itm]; assert (template_fw!=NULL); string platform = readPlatform(m_dialog->platform).toAscii().constData(); string host_os = readHostOS(m_dialog->hostOS).toAscii().constData(); map map_ids; FWObject *no = db_copy->recursivelyCopySubtree(parent, template_fw, map_ids); no->setName( string( m_dialog->obj_name->text().toUtf8().constData() ) ); nfw = Firewall::cast(no); no->setStr("platform", platform); no->setStr("host_OS", host_os); /* * If we set defaults for the platform and host OS, then we lose * all settings that were done in the template. See ticket * #1340. Not setting defaults fixes #1340 with a caveat: since * the name of the same (sematically) option can be different for * different firewall platforms, options set in the template * generally are only rpeserved if the new firewall object uses * the same platform as the template. In practical terms this * basically means iptables. If user changes the platform, they * need to revisit options and fix them manually */ //Resources::setDefaultTargetOptions(platform , nfw); //Resources::setDefaultTargetOptions(host_os , nfw); } void newFirewallDialog::changedAddressesInNewFirewall() { // the key in this map is the pointer to interface that used to be // part of the template. We do not allow the user to create new or // delete existing interfaces when they edit template interfaces. QMap new_configuration = m_dialog->interfaceEditor2->getData(); list all_interfaces = nfw->getByTypeDeep(Interface::TYPENAME); for (list::iterator intiter=all_interfaces.begin(); intiter != all_interfaces.end(); ++intiter ) { Interface *intf = Interface::cast(*intiter); list old_addr = intf->getByType(IPv4::TYPENAME); list old_ipv6 = intf->getByType(IPv6::TYPENAME); old_addr.splice(old_addr.begin(), old_ipv6); if (new_configuration.count(intf) == 0) { QMessageBox::critical( this, "Firewall Builder", tr("Can not find interface %1 in the interface editor data") .arg(intf->getName().c_str()), "&Continue", QString::null, QString::null, 0, 1 ); } else { EditedInterfaceData new_data = new_configuration[intf]; replaceInterfaceAttributes(nfw, intf, &new_data); if (new_data.type == 0) // regular interface { /* * Substitute interface addresses. * * EditedInterfaceData::addresses uses Address* as a * key. If it is not NULL, then this points to the * updated information for existing Address object * which we should modify. If it is NULL, then the * user created new address and we need to create new * IPv4 or IPv6 object. * * If user created more addresses than there used to * be, extra addresses are not added to rules. */ QMap::iterator addrit; for (addrit=new_data.addresses.begin(); addrit!=new_data.addresses.end(); ++addrit) { Address *old_addr_obj = addrit.key(); InetAddrMask old_net; AddressInfo new_addr = addrit.value(); if (old_addr_obj) { const InetAddrMask *old_addr_mask = old_addr_obj->getInetAddrMaskObjectPtr(); old_net = InetAddrMask( *(old_addr_mask->getAddressPtr()), *(old_addr_mask->getNetmaskPtr())); } Address *oa = replaceInterfaceAddressData(nfw, intf, old_addr_obj, new_addr.address, new_addr.netmask, new_addr.ipv4); const InetAddrMask *new_addr_mask = oa->getInetAddrMaskObjectPtr(); InetAddrMask new_net = InetAddrMask( *(new_addr_mask->getAddressPtr()), *(new_addr_mask->getNetmaskPtr())); if (old_addr_obj) { // User edited address of the interface. Remove it // from old_addr so we won't delete it later. old_addr.remove(old_addr_obj); // Now check if the actually changed the // address and/or netmask. If they did, create // new network object and replace references // to network objects that match old address/ // netmask with references pointing to the new // one. if ( ! (old_net == new_net)) replaceReferencesToNetworks(nfw, intf, old_net, new_net); } } } // Now delete old address objects that are still in the // old_addr list. These are the object that were deleted // in the editor. Do not forget to remove references to // thse objects in rules and groups, if any. while (old_addr.size()) { Address *addr = Address::cast(old_addr.front()); old_addr.pop_front(); if (addr) { nfw->removeAllReferences(addr); intf->remove(addr, false); delete addr; } } } } } void newFirewallDialog::replaceInterfaceAttributes(Firewall*, Interface *intf, EditedInterfaceData *new_data) { intf->setName( string(new_data->name.toUtf8().constData())); intf->setLabel( string(new_data->label.toUtf8().constData())); intf->setComment( string(new_data->comment.toUtf8().constData())); if (fwbdebug) qDebug() << "Interface" << intf->getName().c_str() << "type=" << new_data->type; switch (new_data->type) { case 1: intf->setDyn(true); intf->setUnnumbered(false); break; case 2: intf->setDyn(false); intf->setUnnumbered(true); break; default: intf->setDyn(false); intf->setUnnumbered(false); break; } } Address* newFirewallDialog::replaceInterfaceAddressData(Firewall *fw, Interface *intf, Address *addr_obj, const QString &address, const QString &netmask, bool ipv4) { Address *oa; QString name; if (ipv4) { if (addr_obj) oa = addr_obj; else { oa = IPv4::cast(db_copy->create(IPv4::TYPENAME)); intf->add(oa); } name = QString("%1:%2:ipv4") .arg(fw->getName().c_str()) .arg(intf->getName().c_str()); oa->setAddress( InetAddr(address.toStdString())); bool ok = false ; int inetmask = netmask.toInt(&ok); if (ok) oa->setNetmask(InetAddr(inetmask)); else oa->setNetmask(InetAddr(netmask.toStdString())); } else { if (addr_obj) oa = addr_obj; else { oa = IPv6::cast(db_copy->create(IPv6::TYPENAME)); intf->add(oa); } name = QString("%1:%2:ipv6") .arg(fw->getName().c_str()) .arg(intf->getName().c_str()); oa->setAddress( InetAddr(AF_INET6, address.toStdString()) ); bool ok = false ; int inetmask = netmask.toInt(&ok); if (ok) oa->setNetmask(InetAddr(AF_INET6, inetmask)); } oa->setName(name.toStdString()); return oa; } /* * Find references to NEtwork and NetworkIPv6 objects that match * old_net and if there are any, create new Network or NetworkIPv6 * object with address/netmask defined by new_net and replace * references. */ void newFirewallDialog::replaceReferencesToNetworks(Firewall *fw, Interface *intf, InetAddrMask old_net, InetAddrMask new_net) { if(old_net.isAny()) return; // do not replace references to 0/0 FWObject *current_lib = fw->getLibrary(); // Find all matching Network and NetworkIPv6 // objects used in the rules FindNetwork pred(old_net); list res = fw->findIf(&pred); set old_nets; if (res.size()) { // eliminate duplicates for (list::iterator it=res.begin(); it!=res.end(); ++it) old_nets.insert(FWObjectReference::getObject(*it)); string net_type = Network::TYPENAME; if (old_net.getAddressPtr()->isV6()) net_type = NetworkIPv6::TYPENAME; FWObject *parent = FWBTree().getStandardSlotForObject( current_lib, net_type.c_str()); Address *new_net_obj = Address::cast(db_copy->create(net_type)); parent->add(new_net_obj); QString new_net_name = QString("%1:%2:net").arg(fw->getName().c_str()).arg(intf->getName().c_str()); new_net_obj->setName(new_net_name.toStdString()); new_net_obj->setAddress(*(new_net.getAddressPtr())); new_net_obj->setNetmask(*(new_net.getNetmaskPtr())); QString filename = mw->activeProject()->getFileName(); QCoreApplication::postEvent( mw, new insertObjectInTreeEvent(filename, parent->getId(), new_net_obj->getId())); for (set::iterator it=old_nets.begin(); it!=old_nets.end(); ++it) { FWObject *old_obj = FWObjectReference::getObject(*it); replaceReferencesToObject(fw, old_obj, new_net_obj); } } } void newFirewallDialog::replaceReferencesToObject(Firewall *fw, FWObject *old_obj, FWObject *new_obj) { map map_ids; map_ids[old_obj->getId()] = new_obj->getId(); db_copy->fixReferences(fw, map_ids); } fwbuilder-5.1.0.3599/src/libgui/SimpleTextView.cpp0000644000175000017500000000255011733011756022477 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "SimpleTextView.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; void SimpleTextView::setText(QString s) { m_dialog->textview->setText(s); } void SimpleTextView::setName(QString s) { m_dialog->objectname->setText(s); } fwbuilder-5.1.0.3599/src/libgui/secuwallosAdvancedDialog.cpp0000644000175000017500000003551611733011756024505 0ustar sylvestresylvestre/* * secuwallosAdvancedDialog.cpp - secuwall advanced host OS dialog implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "../../config.h" #include "global.h" #include "platforms.h" #include #include "secuwallosAdvancedDialog.h" #include "FWCmdChange.h" #include "fwbuilder/Firewall.h" #include #include #include #include #include #include #include #include #include #include #include "FWWindow.h" #include "Help.h" using namespace std; using namespace libfwbuilder; secuwallosAdvancedDialog::~secuwallosAdvancedDialog() { delete m_dialog; } secuwallosAdvancedDialog::secuwallosAdvancedDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::secuwallosAdvancedDialog_q; m_dialog->setupUi(this); setWindowModality(Qt::WindowModal); obj = o; FWOptions *fwopt = (Firewall::cast(obj))->getOptionsObject(); assert(fwopt != NULL); // mappings from value to QComboBox index QStringList threeStateMapping; QStringList resoStateMapping; threeStateMapping.push_back(QObject::tr("No change")); threeStateMapping.push_back(""); threeStateMapping.push_back(QObject::tr("On")); threeStateMapping.push_back("1"); threeStateMapping.push_back(QObject::tr("Off")); threeStateMapping.push_back("0"); resoStateMapping.push_back(""); resoStateMapping.push_back("none"); resoStateMapping.push_back("Hosts"); resoStateMapping.push_back("files"); resoStateMapping.push_back("DNS"); resoStateMapping.push_back("dns"); resoStateMapping.push_back("NIS"); resoStateMapping.push_back("nis"); resoStateMapping.push_back("NIS+"); resoStateMapping.push_back("nisplus"); resoStateMapping.push_back("DB"); resoStateMapping.push_back("db"); // management settings data.registerOption(m_dialog->secuwall_mgmt_mgmtaddr, fwopt, "secuwall_mgmt_mgmtaddr"); data.registerOption(m_dialog->secuwall_mgmt_loggingaddr, fwopt, "secuwall_mgmt_loggingaddr"); data.registerOption(m_dialog->secuwall_mgmt_snmpaddr, fwopt, "secuwall_mgmt_snmpaddr"); data.registerOption(m_dialog->secuwall_mgmt_rosnmp, fwopt, "secuwall_mgmt_rosnmp"); data.registerOption(m_dialog->secuwall_mgmt_ntpaddr, fwopt, "secuwall_mgmt_ntpaddr"); data.registerOption(m_dialog->secuwall_mgmt_nagiosaddr, fwopt, "secuwall_mgmt_nagiosaddr"); data.registerOption(m_dialog->secuwall_mgmt_varpart, fwopt, "secuwall_mgmt_varpart"); data.registerOption(m_dialog->secuwall_mgmt_confpart, fwopt, "secuwall_mgmt_confpart"); data.registerOption(m_dialog->secuwall_mgmt_rules_disable, fwopt, "secuwall_mgmt_rules_disable"); // dns settings data.registerOption(m_dialog->secuwall_dns_srv1, fwopt, "secuwall_dns_srv1"); data.registerOption(m_dialog->secuwall_dns_srv2, fwopt, "secuwall_dns_srv2"); data.registerOption(m_dialog->secuwall_dns_srv3, fwopt, "secuwall_dns_srv3"); data.registerOption(m_dialog->secuwall_dns_domains, fwopt, "secuwall_dns_domains"); data.registerOption(m_dialog->secuwall_dns_reso1, fwopt, "secuwall_dns_reso1", resoStateMapping); data.registerOption(m_dialog->secuwall_dns_reso2, fwopt, "secuwall_dns_reso2", resoStateMapping); data.registerOption(m_dialog->secuwall_dns_reso3, fwopt, "secuwall_dns_reso3", resoStateMapping); data.registerOption(m_dialog->secuwall_dns_reso4, fwopt, "secuwall_dns_reso4", resoStateMapping); data.registerOption(m_dialog->secuwall_dns_reso5, fwopt, "secuwall_dns_reso5", resoStateMapping); // hosts settings data.registerOption(m_dialog->secuwall_dns_hosts, fwopt, "secuwall_dns_hosts", resoStateMapping); // iptables / routing and TCP data.registerOption(m_dialog->linux24_log_martians, fwopt, "linux24_log_martians", threeStateMapping); data.registerOption(m_dialog->linux24_accept_redirects, fwopt, "linux24_accept_redirects", threeStateMapping); data.registerOption(m_dialog->linux24_icmp_echo_ignore_all, fwopt, "linux24_icmp_echo_ignore_all", threeStateMapping); data.registerOption(m_dialog->linux24_icmp_echo_ignore_broadcasts, fwopt, "linux24_icmp_echo_ignore_broadcasts", threeStateMapping); data.registerOption(m_dialog->linux24_icmp_ignore_bogus_error_responses, fwopt, "linux24_icmp_ignore_bogus_error_responses", threeStateMapping); data.registerOption(m_dialog->linux24_ip_dynaddr, fwopt, "linux24_ip_dynaddr", threeStateMapping); data.registerOption(m_dialog->linux24_rp_filter, fwopt, "linux24_rp_filter", threeStateMapping); data.registerOption(m_dialog->linux24_accept_source_route, fwopt, "linux24_accept_source_route", threeStateMapping); data.registerOption(m_dialog->linux24_ip_forward, fwopt, "linux24_ip_forward", threeStateMapping); data.registerOption(m_dialog->linux24_ipv6_forward, fwopt, "linux24_ipv6_forward", threeStateMapping); data.registerOption(m_dialog->linux24_tcp_fin_timeout, fwopt, "linux24_tcp_fin_timeout"); data.registerOption(m_dialog->linux24_tcp_keepalive_interval, fwopt, "linux24_tcp_keepalive_interval"); data.registerOption(m_dialog->linux24_tcp_window_scaling, fwopt, "linux24_tcp_window_scaling", threeStateMapping); data.registerOption(m_dialog->linux24_tcp_sack, fwopt, "linux24_tcp_sack", threeStateMapping); data.registerOption(m_dialog->linux24_tcp_fack, fwopt, "linux24_tcp_fack", threeStateMapping); data.registerOption(m_dialog->linux24_tcp_ecn, fwopt, "linux24_tcp_ecn", threeStateMapping); data.registerOption(m_dialog->linux24_tcp_syncookies, fwopt, "linux24_tcp_syncookies", threeStateMapping); data.registerOption(m_dialog->linux24_tcp_timestamps, fwopt, "linux24_tcp_timestamps", threeStateMapping); // additional files data.registerOption(m_dialog->additional_files_enabled, fwopt, "secuwall_add_files"); data.registerOption(m_dialog->additional_files_dir, fwopt, "secuwall_add_files_dir"); data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); } /* * store all data in the object */ void secuwallosAdvancedDialog::accept() { // validate user input before saving if (!validate()) return; ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject(); assert(fwoptions!=NULL); data.saveAll(fwoptions); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void secuwallosAdvancedDialog::reject() { QDialog::reject(); } void secuwallosAdvancedDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Host secunet wall"); h->setSource(QUrl("secuwallosAdvancedDialog.html#" + anchor)); h->raise(); h->show(); } void secuwallosAdvancedDialog::additionalChanged(int state) { if (state == Qt::Checked) { m_dialog->templdir_label->setEnabled(true); m_dialog->additional_files_dir->setEnabled(true); m_dialog->buttonBrowse->setEnabled(true); m_dialog->buttonOpenURL->setEnabled(true); } else { m_dialog->templdir_label->setEnabled(false); m_dialog->additional_files_dir->setEnabled(false); m_dialog->buttonBrowse->setEnabled(false); m_dialog->buttonOpenURL->setEnabled(false); } } void secuwallosAdvancedDialog::buttonBrowseClicked() { QString templ_dir = QFileDialog::getExistingDirectory (this, tr("Select templates directory"), m_dialog->additional_files_dir->text(), QFileDialog::DontResolveSymlinks); if (templ_dir == "") { return ; } m_dialog->additional_files_dir->setText(templ_dir); } void secuwallosAdvancedDialog::buttonOpenURLClicked() { bool ok = true; QString message; QString path = m_dialog->additional_files_dir->text(); QUrl url("file://" + path); if (!url.isValid()) { ok = false; message = tr("URL is not valid: %1").arg(path); } else { // note: "Warning: unknown mime-type" errors can not be detected here if (!QDesktopServices::openUrl(url)) { ok = false; message = tr("Could not open URL: %1").arg(url.toLocalFile()); } } if (!ok) { QMessageBox::warning (this, "Firewall Builder", message, "&Continue", QString::null, QString::null, 0, 1); } } bool secuwallosAdvancedDialog::validate() { bool valid = true; QWidget *focus = NULL; QString message; // widgets to verify struct _tocheck { QLineEdit* widget; bool (*chkfn)(const QString &); } widgets[5] = { { m_dialog->secuwall_mgmt_mgmtaddr, &secuwallosAdvancedDialog::validateNetworkOrAddress }, { m_dialog->secuwall_mgmt_loggingaddr, &secuwallosAdvancedDialog::validateAddress }, { m_dialog->secuwall_mgmt_snmpaddr, &secuwallosAdvancedDialog::validateNetworkOrAddress }, { m_dialog->secuwall_mgmt_ntpaddr, &secuwallosAdvancedDialog::validateAddress }, { m_dialog->secuwall_mgmt_nagiosaddr, &secuwallosAdvancedDialog::validateNetworkOrAddress }, }; int size = sizeof(widgets) / sizeof(struct _tocheck); // reset widget colors first for (int i = 0; i < size; i++) { if (widgets[i].widget->palette() != QApplication::palette()) { widgets[i].widget->setPalette(QApplication::palette()); } } // validate each widget one by one for (int i = 0; i < size && valid; i++) { // get text to verify QString to_verify = widgets[i].widget->text(); // focus current widget focus = widgets[i].widget; // if empty, continue if (to_verify.isEmpty()) { continue; } // check comma sep. list of addresses QStringList addrlist = to_verify.split(","); int pos = 1; foreach(QString addr, addrlist) { if (addr.isEmpty()) { valid = false; message = tr("Empty address found (position %1)").arg(pos); break; } addr = addr.simplified(); if (!widgets[i].chkfn(addr)) { valid = false; message = tr("Illegal address '%1' (position %2)"). arg(addr).arg(pos); break; } pos++; } } if (!valid) { // highlight error: focus and set different background color focus->setFocus(); m_dialog->tabWidget->setCurrentIndex(0); QPalette palette; palette.setColor(focus->backgroundRole(), QColor(255, 0, 0, 100)); focus->setPalette(palette); // display errror message QMessageBox::warning(this, "Firewall Builder", tr("Input not valid: %1").arg(message), "&Continue", QString::null, QString::null, 0, 1); } return valid; } bool secuwallosAdvancedDialog::validateAddress(const QString &addr) { if (addr.indexOf("/") != -1) { return false; } try { InetAddr(addr.toLatin1().constData()); } catch (FWException &ex) { return false; } return true; } bool secuwallosAdvancedDialog::validateNetwork(const QString &addr) { if (addr.indexOf("/") == -1) { return false; } // validate IP/netmask address pairs QStringList addrpair = addr.split("/"); try { InetAddr(addrpair.at(0).toLatin1().constData()); } catch (FWException &ex) { return false; } try { InetAddr(addrpair.at(1).toLatin1().constData()); } catch (FWException &ex) { // not in dotted notation? bool ok = false; int ilen = addrpair[1].toInt(&ok); if (ok) { if (ilen < 0 || ilen > 32) { return false; } } else { return false; } } return true; } bool secuwallosAdvancedDialog::validateNetworkOrAddress(const QString &addr) { return (validateNetwork(addr) || validateAddress(addr)); } fwbuilder-5.1.0.3599/src/libgui/heartbeatoptionsdialog_q.ui0000644000175000017500000001411511733011756024454 0ustar sylvestresylvestre heartbeatOptionsDialog_q 0 0 402 263 heartbeat protocol settings Qt::Horizontal QSizePolicy::Expanding 151 27 &OK true true &Cancel true QTabWidget::Rounded 0 heartbeat Parameters :/Icons/Options:/Icons/Options Heartbeat should be configured to use unicast address of each firewall member for health checks. Firewall Builder will add policy rules to permit these automatically. Use unicast address for heartbeat Address: Enter multicat address used for heartbeat health checks here. Qt::Horizontal 56 20 Port number (udp): 65535 Qt::Horizontal 120 20 Qt::Vertical 20 40 buttonOk buttonCancel tabWidget buttonOk clicked() heartbeatOptionsDialog_q accept() 316 472 20 20 buttonCancel clicked() heartbeatOptionsDialog_q reject() 397 472 20 20 use_unicast toggled(bool) heartbeatOptionsDialog_q toggleUseUnicast() 204 51 200 131 toggleUseUnicast() fwbuilder-5.1.0.3599/src/libgui/pixFailoverOptionsDialog.h0000644000175000017500000000272711733011756024205 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PIXFAILOVEROPTIONSDIALOG_H_ #define __PIXFAILOVEROPTIONSDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class pixFailoverOptionsDialog : public QDialog { Q_OBJECT; public: pixFailoverOptionsDialog(QWidget *parent, libfwbuilder::FWObject *o); ~pixFailoverOptionsDialog(); private: libfwbuilder::FWObject *obj; DialogData data; Ui::pixFailoverOptionsDialog_q *m_dialog; bool validate(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __PIXFAILOVEROPTIONSDIALOG_H_ fwbuilder-5.1.0.3599/src/libgui/SSHPIX.h0000644000175000017500000000276311733011756020237 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SSHPIX_H_ #define __SSHPIX_H_ #include "config.h" #include "global.h" #include "SSHCisco.h" #include #include #include #include class SSHPIX : public SSHCisco { Q_OBJECT; public: SSHPIX(QWidget *parent, const QString &host, const QStringList &args, const QString &pwd, const QString &epwd, const std::list &in); virtual ~SSHPIX(); virtual void stateMachine(); public slots: void PIXbackup(); void getACLs(); void clearACLs(); void getObjectGroups(); void clearObjectGroups(); }; #endif fwbuilder-5.1.0.3599/src/libgui/solarisAdvancedDialog.h0000644000175000017500000000267611733011756023446 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SOLARISADVANCEDDIALOG_H_ #define __SOLARISADVANCEDDIALOG_H_ #include #include "DialogData.h" #include namespace libfwbuilder { class FWObject; }; class solarisAdvancedDialog : public QDialog { Q_OBJECT libfwbuilder::FWObject *obj; DialogData data; Ui::solarisAdvancedDialog_q *m_dialog; public: solarisAdvancedDialog(QWidget *parent,libfwbuilder::FWObject *o); ~solarisAdvancedDialog(); protected slots: virtual void accept(); virtual void reject(); }; #endif // __SOLARISADVANCEDDIALOG_H fwbuilder-5.1.0.3599/src/libgui/HttpGet.cpp0000644000175000017500000001031111733011756021117 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include #include #include #include #include "HttpGet.h" #include "FWBSettings.h" using namespace std; extern int getRegistrationStatus(); HttpGet::HttpGet(QObject *parent) : QObject(parent), strm(&contents) { last_error = ""; status = true; connect(&http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpDone(int, bool))); } bool HttpGet::get(const QUrl &_url) { url = _url; QTextStream err(&last_error, QIODevice::WriteOnly); if (strm.isOpen()) { contents.clear(); strm.reset(); } if (!url.isValid()) { err << "Error: Invalid URL"; status = false; return false; } if (url.scheme() != "http" && url.scheme() != "file") { err << "Error: URL must start with 'http:' or 'file:'"; status = false; return false; } if (url.scheme() == "http" && url.path().isEmpty()) { err << "Error: URL has no path"; status = false; return false; } if (url.scheme() == "file") { QTimer::singleShot(0, this, SLOT(fileDone())); return true; } QString proxy = st->getCheckUpdatesProxy(); if (!proxy.isEmpty()) { QStringList parsed_proxy = proxy.split(':'); QString proxy_host = parsed_proxy[0]; QString proxy_port = "80"; if (parsed_proxy.size()>1) proxy_port = parsed_proxy[1]; if (proxy_port.isEmpty()) proxy_port = "80"; http.setProxy(proxy_host, proxy_port.toInt()); } http.setHost(url.host(), url.port(80)); QHttpRequestHeader hdr(QLatin1String("GET"), url.toString()); hdr.setValue("Host", url.host()); QString locale = QLocale::system().name();//"en_US";// QString os; #if defined(Q_WS_MAC) os = "MacOSX"; #else #if defined(Q_WS_WIN) os= "Windows"; #else os = QString("%1; %2").arg(OS).arg(DISTRO); #endif #endif QString agent = QString("fwbuilder/%1 (%2; %3; b:999999; s:%5; u)") .arg(VERSION).arg(os).arg(locale).arg(sig); hdr.setValue("User-Agent", agent); request_id = http.request(hdr, NULL, &strm); return true; } void HttpGet::fileDone() { QString file_path = url.path(); QFileInfo fi(file_path); if (fi.exists() && fi.isReadable()) { QFile data(file_path); if (data.open(QFile::ReadOnly)) { QTextStream strm(&data); QString line = strm.readAll(); status = true; emit done(line); return; } } status = false; QTextStream err(&last_error, QIODevice::WriteOnly); err << "Error: can not read file '" << file_path << "' (url=" << url.toString() << ")"; emit done(""); } void HttpGet::httpDone(int id, bool error) { if (request_id == id) { status = true; last_error = ""; QHttpResponseHeader resp = http.lastResponse(); QTextStream err(&last_error, QIODevice::WriteOnly); if (error) { err << "Error: " << qPrintable(http.errorString()); status = false; } if (resp.isValid() && resp.statusCode()!=200) { err << "Error: " << resp.reasonPhrase(); status = false; } emit done(toString()); } } void HttpGet::abort() { http.abort(); } fwbuilder-5.1.0.3599/src/libgui/UDPServiceDialog.cpp0000644000175000017500000000773611733011756022652 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "FWBTree.h" #include "UDPServiceDialog.h" #include "ProjectPanel.h" #include "FWCmdChange.h" #include "fwbuilder/Library.h" #include "fwbuilder/UDPService.h" #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; UDPServiceDialog::UDPServiceDialog(QWidget *parent) : BaseObjectDialog(parent) { m_dialog = new Ui::UDPServiceDialog_q; m_dialog->setupUi(this); obj=NULL; connectSignalsOfAllWidgetsToSlotChange(); } UDPServiceDialog::~UDPServiceDialog() { delete m_dialog; } void UDPServiceDialog::loadFWObject(FWObject *o) { obj=o; UDPService *s = dynamic_cast(obj); assert(s!=NULL); init=true; m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->ss->setValue( TCPUDPService::cast(s)->getSrcRangeStart() ); m_dialog->se->setValue( TCPUDPService::cast(s)->getSrcRangeEnd() ); m_dialog->ds->setValue( TCPUDPService::cast(s)->getDstRangeStart() ); m_dialog->de->setValue( TCPUDPService::cast(s)->getDstRangeEnd() ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->ss->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ss); m_dialog->se->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->se); m_dialog->ds->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->ds); m_dialog->de->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->de); init=false; } void UDPServiceDialog::validate(bool *res) { *res = true; if (!validateName(this,obj,m_dialog->obj_name->text())) { *res = false; return; } } void UDPServiceDialog::applyChanges() { std::auto_ptr cmd( new FWCmdChange(m_project, obj)); FWObject* new_state = cmd->getNewState(); string oldname = obj->getName(); new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) ); m_dialog->commentKeywords->applyChanges(new_state); // check port ranges (bug #1695481, range start must be <= range end) int sps = m_dialog->ss->value(); int spe = m_dialog->se->value(); int dps = m_dialog->ds->value(); int dpe = m_dialog->de->value(); if (sps > spe) m_dialog->se->setValue( m_dialog->ss->value() ); if (dps > dpe) m_dialog->de->setValue( m_dialog->ds->value() ); spe = m_dialog->se->value(); dpe = m_dialog->de->value(); TCPUDPService::cast(new_state)->setSrcRangeStart(m_dialog->ss->value()); TCPUDPService::cast(new_state)->setSrcRangeEnd(m_dialog->se->value()); TCPUDPService::cast(new_state)->setDstRangeStart(m_dialog->ds->value()); TCPUDPService::cast(new_state)->setDstRangeEnd(m_dialog->de->value()); if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } } fwbuilder-5.1.0.3599/src/libgui/pfsyncOptionsDialog.cpp0000644000175000017500000000426011733011756023544 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "pfsyncOptionsDialog.h" #include "FWWindow.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include #include #include using namespace std; using namespace libfwbuilder; pfsyncOptionsDialog::pfsyncOptionsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::pfsyncOptionsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *gropt = FWOptions::cast(obj); assert(gropt != NULL); data.registerOption(m_dialog->syncpeer, gropt, "syncpeer"); data.loadAll(); } pfsyncOptionsDialog::~pfsyncOptionsDialog() { delete m_dialog; } void pfsyncOptionsDialog::accept() { if (!validate()) return; // the parent of this dialog is InterfaceDialog, not ProjectPanel ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChangeOptionsObject(project, obj)); FWObject* new_state = cmd->getNewState(); data.saveAll(new_state); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void pfsyncOptionsDialog::reject() { QDialog::reject(); } bool pfsyncOptionsDialog::validate() { return true; } fwbuilder-5.1.0.3599/src/libgui/IPv4Dialog.h0000644000175000017500000000274711733011756021125 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPV4DIALOG_H_ #define __IPV4DIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class QDns; class ProjectPanel; class IPv4Dialog : public BaseObjectDialog { Q_OBJECT; bool showNetmask; bool dnsBusy; //QDns *lookup; Ui::IPv4Dialog_q *m_dialog; public: IPv4Dialog(QWidget *parent); ~IPv4Dialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void DNSlookup(); }; #endif // IPV4DIALOG_H fwbuilder-5.1.0.3599/src/libgui/newClusterDialog_create.cpp0000644000175000017500000002665411733011756024357 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "events.h" #include "FWWindow.h" #include "newClusterDialog.h" #include "InterfacesTabWidget.h" #include "platforms.h" #include "FWBTree.h" #include "FWCmdAddObject.h" #include "RuleSetModel.h" #include "RuleSetView.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/FailoverClusterGroup.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include using namespace libfwbuilder; using namespace std; void newClusterDialog::createNewCluster() { if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster()"; map id_mapping; QList cluster_interfaces = this->m_dialog->interfaceSelector->getInterfaces(); typedef QPair fwpair; Firewall *master = NULL; QList > member_firewalls = this->m_dialog->firewallSelector->getSelectedFirewalls(); foreach(fwpair member, member_firewalls) { if (member.second) { master = member.first; break; } } FWObject *o; o = db->create(Cluster::TYPENAME); if (o == NULL) { QDialog::accept(); return; } o->setName(string(m_dialog->obj_name->text().toUtf8().constData())); parent->add(o); ncl = Cluster::cast(o); o->setStr("platform", this->m_dialog->firewallSelector->getSelectedFirewalls().first().first->getStr("platform")); o->setStr("host_OS", this->m_dialog->firewallSelector->getSelectedFirewalls().first().first->getStr("host_OS")); if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster()" << "Creating interfaces"; foreach(EditedInterfaceData data, this->m_dialog->interfaceEditor->getNewData()) { Interface *oi = Interface::cast(db->create(Interface::TYPENAME)); oi->setName(string(data.name.toUtf8().constData())); if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster()" << "Interface" << data.name; ncl->add(oi); oi->setLabel(string(data.label.toUtf8().constData())); QList > member_interfaces; foreach(ClusterInterfaceData cid, cluster_interfaces) { if (cid.name == data.name) { member_interfaces = cid.interfaces; break; } } foreach(AddressInfo address, data.addresses) { if (address.ipv4) { QString addrname = QString("%1:%2:ip") .arg(m_dialog->obj_name->text()) .arg(data.name); IPv4 *oa = IPv4::cast(db->create(IPv4::TYPENAME)); oa->setName(string(addrname.toUtf8().constData())); oi->add(oa); oa->setAddress(InetAddr(address.address.toLatin1().constData())); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) { oa->setNetmask(InetAddr(inetmask)); } else { oa->setNetmask(InetAddr(address.netmask.toLatin1().constData())); } } else { QString addrname = QString("%1:%2:ip") .arg(m_dialog->obj_name->text()) .arg(data.name); IPv6 *oa = IPv6::cast(db->create(IPv6::TYPENAME)); oa->setName(string(addrname.toUtf8().constData())); oi->add(oa); oa->setAddress(InetAddr(AF_INET6, address.address.toLatin1().constData())); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) { oa->setNetmask(InetAddr(AF_INET6, inetmask)); } else { oa->setNetmask(InetAddr(AF_INET6, address.netmask.toLatin1().constData())); } } } if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster()" << "Setting up failover group" << "master=" << master; FWOptions *ifopt; ifopt = oi->getOptionsObject(); ifopt->setStr("type", "cluster_interface"); // create failover group for this interface QString grpname = QString("%1:%2:members") .arg(m_dialog->obj_name->text()) .arg(data.name); FailoverClusterGroup *failover_grp = FailoverClusterGroup::cast( db->create(FailoverClusterGroup::TYPENAME)); failover_grp->setName(string(grpname.toUtf8().constData())); oi->add(failover_grp); QString failover_protocol_name = data.protocol.toLower(); failover_grp->setStr("type", failover_protocol_name.toAscii().constData()); typedef QPair intfpair; foreach(intfpair intf, member_interfaces) { Firewall *member_fw = intf.first; Interface *member_intf = intf.second; if (fwbdebug) qDebug() << "Adding" << "member_fw=" << member_fw << "member_intf=" << member_intf->getName().c_str(); id_mapping[member_intf->getId()] = oi->getId(); failover_grp->addRef(member_intf); if (master!=NULL && member_fw == master) { std::string masteriface_id = FWObjectDatabase::getStringId(member_intf->getId()); failover_grp->setStr("master_iface", masteriface_id); } } // need to populate failover group with some reasonable // default values. If this is not done, parameters such as // CARP vhid remain blank and that leads to incomplete // generated configurations setDefaultFailoverGroupAttributes(failover_grp); } // Set correct type of the state sync group (the StateSyncGroup object is // created in Cluster::init() FWObject *state_sync_members = ncl->getFirstByType(StateSyncClusterGroup::TYPENAME); setDefaultStateSyncGroupAttributes( StateSyncClusterGroup::cast(state_sync_members)); // Copy rule sets if requested Firewall *source = NULL; foreach (QRadioButton* btn, copy_rules_from_buttons.keys()) { if (btn->isChecked() && btn != noPolicy) { source = copy_rules_from_buttons[btn]; break; } } if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster() checkpoint 4"; ProjectPanel *pp = mw->activeProject(); QString filename = pp->getFileName(); if (source == NULL) { if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster() checkpoint 5"; FWObject *first_policy = ncl->getFirstByType(Policy::TYPENAME); if (fwbdebug) qDebug() << "newClusterDialog::createNewCluster() checkpoint 6" << "first_policy=" << first_policy; QCoreApplication::postEvent( mw, new openRulesetEvent(filename, first_policy->getId())); return; } // See #1622 If rule set view shows rules of the firewall // , need to close it because we are about to delete that // rule set object RuleSet* current_ruleset = NULL; RuleSetView* rsv = pp->getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && current_ruleset->isChildOf(source)) { pp->closeRuleSet(current_ruleset); } db->setIgnoreReadOnlyFlag(true); FWObject *fwgroup = FWBTree().getStandardSlotForObject(parent->getLibrary(), Firewall::TYPENAME); foreach(fwpair member, member_firewalls) { Firewall *fw = member.first; id_mapping[fw->getId()] = ncl->getId(); string name_bak = fw->getName() + "-bak"; FWCmdAddObject *cmd = new FWCmdAddObject( mw->activeProject(), fwgroup, NULL, QString("Create new Firewall %1") .arg(QString::fromUtf8(name_bak.c_str()))); cmd->setNeedTreeReload(true); FWObject *new_state = cmd->getNewState(); Firewall *bakfw = Firewall::cast(new_state->addCopyOf(fw)); bakfw->setName(name_bak); bakfw->setInactive(true); mw->activeProject()->undoStack->push(cmd); } copyRuleSets(Policy::TYPENAME, source, id_mapping); copyRuleSets(NAT::TYPENAME, source, id_mapping); copyRuleSets(Routing::TYPENAME, source, id_mapping); //ncl->getRoot()->fixReferences(ncl, id_mapping); foreach(fwpair member, member_firewalls) { Firewall *fw = member.first; deleteRuleSets(Policy::TYPENAME, fw); deleteRuleSets(NAT::TYPENAME, fw); deleteRuleSets(Routing::TYPENAME, fw); } db->setIgnoreReadOnlyFlag(false); FWObject *first_policy = ncl->getFirstByType(Policy::TYPENAME); QCoreApplication::postEvent( mw, new openRulesetEvent(filename, first_policy->getId())); } void newClusterDialog::deleteRuleSets(const string &type, Firewall *fw) { list rule_sets = fw->getByType(type); foreach(FWObject *rs, rule_sets) fw->remove(rs); fw->add(db->create(type)); } void newClusterDialog::copyRuleSets(const string &type, Firewall *source, map &id_mapping) { list old_ones = ncl->getByType(type); foreach(FWObject *old, old_ones) ncl->remove(old); FWObjectDatabase *db = ncl->getRoot(); FWObjectTypedChildIterator it = source->findByType(type); for (; it != it.end(); ++it) { FWObject *new_ruleset = ncl->addCopyOf(*it); id_mapping[(*it)->getId()] = new_ruleset->getId(); db->fixReferences(new_ruleset, id_mapping); } /* * since the order in which we copy rule sets is undefined and * because they may have references to each other via branching * rules, we need to fix references in them after we create all of * them. This fixes SF bug #3106168 "Branch destinations lost when adding to cluster" */ it = ncl->findByType(type); for (; it != it.end(); ++it) { db->fixReferences(*it, id_mapping); } } fwbuilder-5.1.0.3599/src/libgui/FirewallInstallerCisco.cpp0000644000175000017500000002363611733011756024162 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "FirewallInstallerCisco.h" #include "instDialog.h" #include "SSHPIX.h" #include "SSHIOS.h" #include "Configlet.h" #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/XMLTools.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Management.h" #include "fwbuilder/XMLTools.h" #include #include #include #include using namespace std; using namespace libfwbuilder; FirewallInstallerCisco::FirewallInstallerCisco(instDialog *_dlg, instConf *_cnf, const QString &_p): FirewallInstaller(_dlg, _cnf, _p) { // string platform = cnf->fwobj->getStr("platform"); // if (cnf->fwdir.isEmpty()) // { // if (platform=="iosacl") cnf->fwdir = "nvram:"; // else cnf->fwdir = "flash:"; // } } bool FirewallInstallerCisco::packInstallJobsList(Firewall*) { if (fwbdebug) qDebug("FirewallInstallerCisco::packInstallJobList script=%s", cnf->script.toAscii().constData()); job_list.clear(); Management *mgmt = cnf->fwobj->getManagementObject(); assert(mgmt!=NULL); PolicyInstallScript *pis = mgmt->getPolicyInstallScript(); if (pis->getCommand()!="") { QString cmd = pis->getCommand().c_str(); QString args = pis->getArguments().c_str(); job_list.push_back( instJob(RUN_EXTERNAL_SCRIPT, cmd, args)); inst_dlg->addToLog(QString("Run script %1 %2\n").arg(cmd).arg(args)); return true; } // Load configuration file early so we can abort installation if // it is not accessible // Note about option "install only acl, icmp, telnet, ssh, nat, // global and static" for PIX. This option used to read generated // config but cuts off everything before the magic comment line // "!################". This way, it only read object-group, // access-list, access-group, nat, static and global commands. It // skipped all interface configurations, timeouts and inspector // commands. It is difficult to implement now that we (can) use // scp to copy configuration to the firewall. We would have to // create temporary file with modified configuration in order to // do this. To avoid hassles with temporary files, we move the // same function to the compiler. The checkbox moves to the // "script" tab of the pix advanced settings dialog and when it is on, // compiler generates the script with only acl, icmp, telnet, ssh // nat,static and global commands // // This mode of installation is not supported on IOS at all. 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; } string platform = cnf->fwobj->getStr("platform"); if (cnf->useSCPForRouter) { QMap all_files; // readManifest() modifies cnf (assigns cnf->remote_script) ! if (readManifest(cnf->script, &all_files)) { QMap::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; } void FirewallInstallerCisco::activatePolicy(const QString&, const QString&) { QStringList args; packSSHArgs(args); if (cnf->verbose) inst_dlg->displayCommand(args); SSHCisco *ssh_object = NULL; if (cnf->fwobj->getStr("platform")=="pix" || cnf->fwobj->getStr("platform")=="fwsm") { ssh_object = new SSHPIX(inst_dlg, cnf->fwobj->getName().c_str(), args, cnf->pwd, cnf->epwd, list()); } else // ios { ssh_object = new SSHIOS(inst_dlg, cnf->fwobj->getName().c_str(), args, cnf->pwd, cnf->epwd, list()); } /* * TODO: * the structure of scriptlets (command templates) for PIX and * IOS is nice and generic, it uses generalized "pre_config" * and "post_config" hooks in SSHPIX / SSHIOS classes. Need to * do the same for Unix firewalls. */ QString cmd = ""; QStringList pre_config_commands; QStringList post_config_commands; string version = cnf->fwobj->getStr("version"); bool version_lt_124 = XMLTools::version_compare(version, "12.4") < 0; bool version_ge_124 = XMLTools::version_compare(version, "12.4") >= 0; string host_os = cnf->fwobj->getStr("host_OS"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); // installer configlets should be different for each OS, but if // some OS can use the same script, it will be placed in the file // under os_family name. For example: // for PIX configlet is in src/res/configlets/pix_os // but since fwsm and pix can use the same script and fwsm_os.xml // declares family as "pix_os", it uses the same configlet. Configlet pre_config(host_os, os_family, "installer_commands_pre_config"); pre_config.removeComments(); // test run and rollback were deprecated in 4.2.0. On Linux, BSD // and PIX rollback was implemented by rebooting firewall which is // too heavy-handed and it did not work on BSD at all. pre_config.setVariable("test", false); pre_config.setVariable("run", true); pre_config.setVariable("schedule_rollback", false); pre_config.setVariable("cancel_rollback", false); pre_config.setVariable("save_standby", cnf->saveStandby); pre_config.setVariable("version_lt_124", version_lt_124); pre_config.setVariable("version_ge_124", version_ge_124); replaceMacrosInCommand(&pre_config); Configlet post_config(host_os, os_family, "installer_commands_post_config"); post_config.removeComments(); post_config.setVariable("test", false); post_config.setVariable("run", true); post_config.setVariable("schedule_rollback", false); post_config.setVariable("cancel_rollback", false); post_config.setVariable("save_standby", cnf->saveStandby); post_config.setVariable("version_lt_124", version_lt_124); post_config.setVariable("version_ge_124", version_ge_124); replaceMacrosInCommand(&post_config); ssh_object->loadPreConfigCommands( pre_config.expand().split("\n", QString::SkipEmptyParts) ); ssh_object->loadPostConfigCommands( post_config.expand().split("\n", QString::SkipEmptyParts) ); Configlet activation(host_os, os_family, "installer_commands_reg_user"); activation.removeComments(); replaceMacrosInCommand(&activation); activation.setVariable("using_scp", cnf->useSCPForRouter); activation.setVariable("not_using_scp", ! cnf->useSCPForRouter); if ( ! cnf->useSCPForRouter) { 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 *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; } fwbuilder-5.1.0.3599/src/libgui/linksysadvanceddialog_q.ui0000644000175000017500000003405511733011756024270 0ustar sylvestresylvestre linksysAdvancedDialog_q Qt::WindowModal 0 0 504 548 Linksys/Sveasoft: advanced settings 11 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true QTabWidget::Rounded 1 Path Qt::Vertical QSizePolicy::Fixed 20 20 Specify directory path and a file name for each utility on your firewall machine. Leave these empty if you want to use default values. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true iptables: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false ip: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false logger: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false modprobe: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false lsmod Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false vconfig Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false brctl Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false ifenslave Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::Vertical QSizePolicy::Expanding 20 40 Prompts 6 0 0 Policy installer relies on the shell prompt on the firewall to execute commands. Installer tries both prompt string patterns configured here; it assumes that the firewall is ready to accept a command if either prompt matches. You should only need to change these string patterns if Sveasoft changes the shell prompt in the future releases of the software. <br> <br> The default strings work for Sveasoft Alchemy pre-5.1 and pre-5.2 Qt::RichText Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 4 Qt::Vertical QSizePolicy::Expanding 20 80 Use default prompts prompt 2 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::Horizontal QSizePolicy::Expanding 30 20 prompt 1 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::Horizontal QSizePolicy::Fixed 150 20 Qt::Vertical QSizePolicy::Fixed 20 20 linksys_path_iptables linksys_path_ip linksys_path_logger linksys_path_modprobe linksys_path_lsmod linksys_path_vconfig linksys_path_brctl linksys_path_ifenslave buttonOk buttonCancel linksys_prompt1 linksys_prompt2 useDefaultPrompts tabWidget buttonOk clicked() linksysAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() linksysAdvancedDialog_q reject() 20 20 20 20 useDefaultPrompts clicked() linksysAdvancedDialog_q setDefaultPrompts() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/RCS.cpp0000644000175000017500000007427011733011756020205 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "FWBApplication.h" #include "RCS.h" // need this for FS_SEPARATOR #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/Tools.h" //#include "FWWindow.h" #include #include #include #include #include #include #include #include #if defined(_WIN32) # include # include # include # include # include #else # include # include # include # if defined(TM_IN_SYS_TIME) # include # else # include # endif #endif #include using namespace std; using namespace libfwbuilder; QString RCS::rcs_file_name = ""; QString RCS::rlog_file_name = ""; QString RCS::rcsdiff_file_name = ""; QString RCS::ci_file_name = ""; QString RCS::co_file_name = ""; RCSEnvFix* RCS::rcsenvfix = NULL; bool RCS::rcs_available = false; /*********************************************************************** * * class Revision * ***********************************************************************/ Revision::Revision() { } Revision::Revision(const QString &file, const QString &r) { filename = file; rev = r; } Revision::Revision(const Revision &r) { filename = r.filename ; rev = r.rev ; date = r.date ; author = r.author ; locked_by = r.locked_by; log = r.log ; } void Revision::operator=(const Revision &r) { filename = r.filename ; rev = r.rev ; date = r.date ; author = r.author ; locked_by = r.locked_by; log = r.log ; } bool Revision::operator<(const Revision &r) const { for(int i=1; ; i++) { QString v1= rev.section(".",i,i); QString v2=r.rev.section(".",i,i); if (v1=="" && v2=="") return false; if (v1==v2) continue; if (v1=="" && v2!="") return true; if (v1!="" && v2=="") return false; if (v1.toInt()>v2.toInt()) return false; if (v1.toInt()tm_gmtoff/60; if (tzoffset<0) { tzoffset = -1*tzoffset; tzsign = "-"; } else { tzsign = "+"; } #else // global variable timezone has seconds West of GMT (positive in // timezones west of GMT) tzoffset = ((ltm->tm_isdst>0)?timezone-3600:timezone)/60; if (tzoffset<0) { tzoffset = -1*tzoffset; tzsign = "+"; } else { tzsign = "-"; } #endif TZOffset.sprintf("%02d:%02d",tzoffset/60,tzoffset%60); TZOffset = tzsign + TZOffset; if (fwbdebug) qDebug("tzoffset: %d TZOffset: '%s'",tzoffset,TZOffset.toAscii().constData()); #ifdef _WIN32 /* need this crap because Windows does not set environment variable TZ * by default, but rcs absolutely requires it. Even though I am using * option "-z" with all RCS commands, stupid RCS on windows does not * work if env var TZ is not set */ env.push_back( QString("TZ=GMT")+TZOffset ); /* * NB: need to prepend installation directory in front of PATH on * windows, otherwise ci fails when GUI is launched by windows * explorer through file extension association. When the program is * launched from menu "Start", its working directory is the dir. where * it is installed. Since windows implies a '.' in front of PATH, * everything works. When the program is started with some other * directory as current dir, RCS tools fail without any error message. */ env.push_back( QString("PATH=%1;%2").arg(getPathToBinary("").c_str()).arg(getenv("PATH")) ); #endif /* also need to set env variable USER for rcs tools, but if the user name * contains spaces, replace them with underscores (like "John Smith") * * global variable QString user_name is set in common/init.cpp */ QString uname = user_name; env.push_back( QString("USER=") + uname); env.push_back( QString("LOGNAME=") + uname); if (getenv("TMP") != NULL) env.push_back( QString("TMP=") + getenv("TMP")); if (getenv("TEMP")!=NULL) env.push_back( QString("TEMP=") + getenv("TEMP")); } QStringList* RCSEnvFix::getEnv() { if (env.empty()) return NULL; return &env; } /*********************************************************************** * * class RCS * ***********************************************************************/ void RCS::init() { if (rcs_file_name=="") { #ifdef _WIN32 string ts; ts = getPathToBinary(RCS_FILE_NAME); rcs_file_name = ts.c_str(); ts = getPathToBinary(RLOG_FILE_NAME); rlog_file_name = ts.c_str(); ts = getPathToBinary(RCSDIFF_FILE_NAME); rcsdiff_file_name = ts.c_str(); ts = getPathToBinary(CI_FILE_NAME); ci_file_name = ts.c_str(); ts = getPathToBinary(CO_FILE_NAME); co_file_name = ts.c_str(); #else rcs_file_name = RCS_FILE_NAME ; rlog_file_name = RLOG_FILE_NAME ; rcsdiff_file_name = RCSDIFF_FILE_NAME ; ci_file_name = CI_FILE_NAME ; co_file_name = CO_FILE_NAME ; #endif } // now check if rcs tools are available. To test, try to run rlog // with no arguments QStringList arglist; QProcess rcs_proc; rcs_proc.start( rlog_file_name, arglist ); rcs_proc.waitForStarted(); if (rcs_proc.state() != QProcess::Running) { rcs_proc.close(); // rlog (and probably other RCS tools) are unavailable if (fwbdebug) qDebug() << "RCS tools unavailable"; rcs_available = false; return; } rcs_proc.waitForFinished(); rcs_proc.close(); rcs_available = true; } RCS::RCS(const QString &file) { if (rcsenvfix==NULL) rcsenvfix = new RCSEnvFix(); if (fwbdebug) qDebug() << "RCS::RCS(" << file << ")"; // Using absoluteFilePath() rather than canonicalFilePath, see #1334 QFileInfo fi(file); if (fi.exists()) filename = fi.absoluteFilePath(); else filename = file; if (fwbdebug) qDebug() << "filename=" << filename; checked_out = false; locked = false; inrcs = false; tracking_file = false; ro = false; temp = false; ciproc = new QProcess(); proc = new QProcess(); connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout() ) ); connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr() ) ); if (!fi.exists()) { inrcs = false; tracking_file = true; return; } try { QString rcspath = filename.left( filename.lastIndexOf("/") ); QDir rcsdir; rcsdir.cd(rcspath); /* * rlog is started with environment defined by RCSEnvFix, which does * not have env. var LANG so it always runs in english */ QString rl = rlog(); QStringList split_log = rl.split(QRegExp("------|======")); QString head_section = split_log[0]; QRegExp head_rx("head:\\s+([0-9\\.]+)\\s*\\n"); int pos = head_rx.indexIn( head_section ); if (pos>-1) head = head_rx.cap(1); QStringList::iterator i; for (i=split_log.begin(),++i; i!=split_log.end(); ++i) { QString section = *i; if (section.length()==0) continue; int match = -1; Revision r(filename); r.rev = ""; r.log = ""; QRegExp rev_rx("revision\\s+([0-9\\.]+)"); match = rev_rx.indexIn( section ); if (match>-1) { r.rev = rev_rx.cap(1); } QRegExp lock_rx("revision\\s+([0-9\\.]+)\\s+locked by:\\s+(\\S+);"); lock_rx.setMinimal(true); match = lock_rx.indexIn( section ); if (match>-1) { r.locked_by = lock_rx.cap(2); locked = true; locked_by = lock_rx.cap(2); locked_rev = r.rev; } // older implementation copied revision and "locked by" to r.log // we'll do the same here to maintain compatibility QRegExp rev2_rx("(revision.+)\\n"); rev2_rx.setMinimal(true); match = rev2_rx.indexIn( section ); if (match>-1) { r.log += rev2_rx.cap(1) + "\n"; } QRegExp date_rx("date:\\s+([^;]+);\\s+author:\\s+(\\S+);"); date_rx.setMinimal(true); match = date_rx.indexIn( section ); if (match>-1) { r.date = date_rx.cap(1); r.author = date_rx.cap(2); } QRegExp log_rx("date:.*\\n(.*)$"); log_rx.setMinimal(true); match = log_rx.indexIn( section ); if (match>-1) r.log += log_rx.cap(1); r.log.replace('\r',""); if (r.rev != "") { revisions.push_back(r); if (fwbdebug) qDebug("revision %s: '%s'", r.rev.toAscii().constData(), r.log.toAscii().constData()); } } // sort list revisions; its defined like this: // QList revisions qSort(revisions); inrcs = true; tracking_file = true; selectedRev = head; } catch (FWException &ex) { inrcs = false; tracking_file = true; } } RCS::~RCS() { delete ciproc; delete proc; } QStringList* RCS::getEnv() { if (rcsenvfix==NULL) rcsenvfix = new RCSEnvFix(); return rcsenvfix->getEnv(); } RCSEnvFix* RCS::getRCSEnvFix() { if (rcsenvfix==NULL) rcsenvfix = new RCSEnvFix(); return rcsenvfix; } void RCS::readFromStdout() { QString s = QString(proc->readAllStandardOutput()); //qDebug("RCS::readFromStdout() reads: %s",s.toAscii().constData()); stdoutBuffer=stdoutBuffer + s; } void RCS::readFromStderr() { QString s = QString(proc->readAllStandardError()); //qDebug("RCS::readFromStderr() reads: %s", s.toAscii().constData()); stderrBuffer=stderrBuffer + s; } void RCS::setFileName(const QString &fn) { QFileInfo fi(fn); if (fi.exists()) filename = fi.absoluteFilePath(); else filename = fn; if (fwbdebug) qDebug() << "RCS::setFileName fn =" << fn << "filename =" << filename; } /********************************************************************* * trivial RCS integration */ void RCS::abandon() { if (!isInRCS() || !rcs_available) return; /* check out head revision and unlock it */ QStringList arglist; arglist << "-q" << "-f" << QString("-z") + rcsenvfix->getTZOffset() << QString("-u") << filename ; stdoutBuffer=""; stderrBuffer=""; if (fwbdebug) qDebug("starting co with environment '%s'", rcsenvfix->getEnv()->join(" ").toAscii().constData()); if (fwbdebug) qDebug("executing command '%s %s'", co_file_name.toAscii().constData(), arglist.join(" ").toAscii().constData()); proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( co_file_name, arglist ); proc->waitForStarted(); if (fwbdebug) qDebug("running co"); if (proc->state() == QProcess::Running) { proc->waitForFinished(); if (proc->exitCode() == 0 && proc->state() == QProcess::NotRunning) { if (fwbdebug) qDebug("finished successfully"); checked_out = false; locked = false; selectedRev = head; return; } } /* error. */ selectedRev = ""; checked_out=false; QString err = tr("Error checking file out: %1").arg(stderrBuffer); QMessageBox::critical(app->activeWindow(), "Firewall Builder", err, tr("&Continue") ); throw(FWException(err.toLatin1().constData())); } /** * initial RCS checkin */ void RCS::add() throw(libfwbuilder::FWException) { int i = filename.lastIndexOf("/"); QString rcspath = filename.left(i); QDir rcsdir; if (!rcs_available) { QString err = QObject::tr("RCS tools are unavailable"); if (fwbdebug) qDebug() << err; throw(FWException(err.toStdString())); } if (fwbdebug) qDebug() << "RCS::add() will run " << rcs_file_name; rcsdir.cd(rcspath); if (!rcsdir.exists("RCS")) rcsdir.mkdir("RCS"); QStringList arglist; arglist << "-q" << "-i" << "-kb" << QString("-z") + rcsenvfix->getTZOffset() << "-t-\"Initial checkin\"" << filename; stdoutBuffer=""; stderrBuffer=""; proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( rcs_file_name, arglist ); proc->waitForStarted(); if (proc->state() == QProcess::Running) { proc->waitForFinished(); if (proc->state() == QProcess::NotRunning && proc->exitCode()==0) { arglist.clear(); arglist << "-q" << "-u" << QString("-z") + rcsenvfix->getTZOffset() << filename; stdoutBuffer=""; stderrBuffer=""; proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( ci_file_name, arglist ); proc->waitForStarted(); if (proc->state() == QProcess::Running) { proc->waitForFinished(); if (proc->state() == QProcess::NotRunning && proc->exitCode()==0) { inrcs = true; selectedRev = "1.1"; head = "1.1"; return; } } } } QByteArray outp = proc->readAllStandardOutput(); QString msg = QObject::tr("Fatal error during initial RCS checkin of file %1 :\n %2\nExit status %3") .arg(filename).arg(outp.data()).arg(proc->exitCode()); throw(FWException( msg.toLatin1().constData() )); } bool RCS::isInRCS() { if (!rcs_available) return false; if (tracking_file) return inrcs; QStringList arglist; arglist << QString("-z") + rcsenvfix->getTZOffset() << "-R" << filename; stdoutBuffer=""; stderrBuffer=""; proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( rlog_file_name, arglist ); proc->waitForStarted(); if (proc->state() != QProcess::Running) throw(FWException("Fatal error running rlog ")); while (proc->state() == QProcess::Running) ; // cxx_sleep(1); if (proc->state() == QProcess::NotRunning && proc->exitCode()==1) { /* exist status '1' means the file is not in RCS */ inrcs=false; if (fwbdebug) { QByteArray outp = proc->readAllStandardOutput(); qDebug("Error running rlog: %s",outp.data()); } return false; } inrcs=true; return true; } bool RCS::co(bool force) throw(libfwbuilder::FWException) { return co(selectedRev,force); } /** * RCS checkout * * possible situations: * * 1. file is not in RCS - do nothing, return false * * 2. need to open file read-only * * 2.1 requested revision is emty or the head: no need to * checkout, just return true * * 2.2 need to open read-only, older revision: do checkout of that * revision into temporary file without locking, change file name, * set flag 'temp' * * 3. need to open read-write, but file is locked * * 3.1 file is locked by the same user: offer user a choice * open read-only or continue editing or cancel * * 3.2 file is locked by another user: offer a choice open read-only * or cancel * * 4. need to open read-write, any revision: do normal checkout and * lock * */ bool RCS::co(const QString &rev,bool force) throw(libfwbuilder::FWException) { /* first check if filename is already in RCS */ if (!rcs_available || !isInRCS()) return false; if (ro) { if (rev==head || rev=="") return true; /* check out requested revision to stdout * * TODO: right now it loads the whole file into memory, then writes it * to the temp file. It should be more efficient to read and write in * chunks. * */ QStringList arglist; arglist << QString("-q") << QString("-kb") << QString("-z") + rcsenvfix->getTZOffset() << QString("-p")+rev << filename; stdoutBuffer=""; stderrBuffer=""; if (fwbdebug) qDebug("starting co with environment '%s'", rcsenvfix->getEnv()->join("\n").toAscii().constData()); if (fwbdebug) qDebug("executing command '%s %s'", co_file_name.toAscii().constData(), arglist.join(" ").toAscii().constData()); proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( co_file_name, arglist ); proc->waitForStarted(); if (fwbdebug) qDebug("running co"); if (proc->state() == QProcess::Running) { proc->waitForFinished(); if (proc->state() == QProcess::NotRunning && proc->exitCode()==0) { if (fwbdebug) qDebug("finished successfully"); #ifdef _WIN32 char tname[1024]; strncpy(tname, filename.left(filename.lastIndexOf("/")+1).toLatin1().constData(),sizeof(tname)-20); strcat(tname,"tmpXXXXXX"); _mktemp(tname); int fd = _open(tname, _O_RDWR|_O_CREAT|_O_EXCL|_O_BINARY , _S_IREAD|_S_IWRITE ); #else char tname[PATH_MAX]; strncpy(tname, filename.toLatin1().constData(), sizeof(tname)-20 ); strcat(tname,"_temp_XXXXXX"); int fd = mkstemp(tname); #endif if (fd<0) { QString err = tr("Error creating temporary file ")+tname+QString(" :\n")+strerror(errno); QMessageBox::critical(app->activeWindow(), "Firewall Builder", err, tr("&Continue") ); throw(FWException(err.toLatin1().constData())); } #ifdef _WIN32 if (_write(fd,stdoutBuffer.toLatin1().constData(),stdoutBuffer.length() )<0) { _close(fd); #else if ( write(fd,stdoutBuffer.toLatin1().constData(),stdoutBuffer.length() )<0) { close(fd); #endif QString err = tr("Error writing to temporary file ")+tname+QString(" :\n")+strerror(errno); QMessageBox::critical(app->activeWindow(), "Firewall Builder", err, tr("&Continue") ); throw(FWException(err.toLatin1().constData())); } close(fd); filename = tname; temp = true; checked_out = false; locked = false; selectedRev = rev; return true; } } selectedRev = head; QString err = tr("Error checking file out: %1").arg(stderrBuffer); QMessageBox::critical(app->activeWindow(), "Firewall Builder", err, tr("&Continue") ); throw(FWException(err.toLatin1().constData())); } else { /* global variable QString user_name is set in common/init.cpp */ QString me = user_name; if (locked) { /* the file is already locked, can not just check it out like that */ if (me!=locked_by) { switch (QMessageBox::warning( app->activeWindow(),"Firewall Builder", tr("File is opened and locked by %1.\nYou can only open it read-only.") .arg(locked_by), "Open &read-only", "&Cancel", QString::null, 0, 1 ) ) { case 0: ro=true; return false; case 1: throw(FWException("cancel opening file")); break; } } if (force) goto checkout; switch ( QMessageBox::warning(app->activeWindow(), "Firewall Builder", tr("Revision %1 of this file has been checked out and locked by you earlier.\n\ The file may be opened in another copy of Firewall Builder or was left opened\n\ after the program crashed.").arg(locked_rev), tr("Open &read-only"), tr("&Open and continue editing"), tr("&Cancel"), 0, 2 ) ) { case 0: ro=true; return false; case 1: /* continue working with the file */ checked_out = true; locked = true; selectedRev = locked_rev; return true; case 2: throw(FWException("cancel opening file")); break; } } /* if the user wanted specific revision and it should be opened * read-only, we need to check it out into a temporary file without * locking */ checkout: /* check out and lock */ QStringList arglist; arglist.clear(); arglist << "-q"; if (force) arglist << "-f"; arglist << QString("-l")+rev << QString("-z") + rcsenvfix->getTZOffset() << filename; stdoutBuffer=""; stderrBuffer=""; if (fwbdebug) qDebug("starting co with environment '%s'", rcsenvfix->getEnv()->join("\n").toAscii().constData()); if (fwbdebug) qDebug("executing command '%s %s'", co_file_name.toAscii().constData(), arglist.join(" ").toAscii().constData()); proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( co_file_name, arglist ); proc->waitForStarted(); if (fwbdebug) qDebug("running co"); if (proc->state() == QProcess::Running) { proc->waitForFinished(); if (proc->state() == QProcess::NotRunning && proc->exitCode()==0) { if (fwbdebug) qDebug("finished successfully"); checked_out = true; locked = true; selectedRev = rev; return true; } } /* error. */ selectedRev = head; QString err = tr("Error checking file out: %1").arg(stderrBuffer); QMessageBox::critical(app->activeWindow(), "Firewall Builder", err, tr("&Continue") ); throw(FWException(err.toLatin1().constData())); } return false; } bool RCS::ci( const QString &_lm, bool unlock) throw(libfwbuilder::FWException) { /* first check if filename is already in RCS */ if (!rcs_available || !isInRCS()) return false; QString logmsg = _lm; if (logmsg.isEmpty()) logmsg="_"; // otherwise ci adds "*** empty log message ***" if (fwbdebug) qDebug("RCS::ci log message (%d characters): '%s'", logmsg.length(), logmsg.toAscii().constData()); QStringList arglist; if (unlock) arglist << "-u"; else arglist << "-l"; arglist << QString("-z") + rcsenvfix->getTZOffset(); arglist << filename; stdoutBuffer=""; stderrBuffer=""; if (fwbdebug) qDebug("starting ci with environment '%s'", rcsenvfix->getEnv()->join("\n").toAscii().constData()); QByteArray rcslog = logmsg.toUtf8(); QString obuf; /* * under some circumstances, ci may exit immediately (e.g. when there * were no changes done to the file and it won't expect any rcs log * record on stdin). In this case slot completeCI is called * immediately, even before we have a chance to enter event loop. We * need to make sure we do not enter event loop if this happens. We * use flag ciRunning to check for that. * * Also it seems on windows all data is sent to the process and slot * is called while we still are inside launch, so that once we exit * from it, all is done and there is no need to enter event loop. */ ciRunning=true; ciproc->setEnvironment(*rcsenvfix->getEnv()); ciproc->start( ci_file_name, arglist ); ciproc->waitForStarted(); if (ciproc->state() != QProcess::Running) {//if not started if (fwbdebug) qDebug("Checkin error: file=%s error=%s", filename.toLatin1().constData(),obuf.toLatin1().constData()); throw( FWException( (obuf+"\n"+ arglist.join(" ")+"\n"+ rcsenvfix->getEnv()->join("\n")).toAscii().constData() ) ); } /* make a copy, omitting trailing '\0' so it won't get sent to ci */ QByteArray rcslogCopy; rcslogCopy = rcslog; ciproc->write((const char*)rcslogCopy, rcslog.length()); QByteArray arr; arr = "\n.\n"; ciproc->write((const char*)(arr),arr.length()); if (fwbdebug) qDebug("all data sent to ci"); ciproc->waitForFinished(); if (fwbdebug) qDebug("ci exited"); if (ciproc->state() == QProcess::NotRunning && ciproc->exitCode()==0) { if (fwbdebug) qDebug("ci exited normally"); if (unlock) { checked_out = false; locked = false; } return true; } return true; } /** * rlog - run rlog in the background and collect RCS log * * As it turns out, we can not trust rlog option "-zLT" to properly * convert timezone information on Windows. This might be abug in the * ported rlog. When timezone is east of GMT, ci properly converts * when file is checked in, but rlog uses wrong sing and substracts * offset instead of adding it. Suppose we are in Japan time zone * (GMT+9), and file is checked in at 15:00 local time. Ci properly * writes checkin time as 6:00 GMT, but rlog reports it as 21:00 on a * previous day (it does -9 hours instead of +9 hours ). Option * "-z+09:00" works properly * */ QString RCS::rlog() throw(libfwbuilder::FWException) { if (!rcs_available) throw(FWException(QObject::tr("RCS tools are unavailable").toStdString())); QStringList arglist; arglist << QString("-z") + rcsenvfix->getTZOffset() << filename; // proc->addArgument( "-zLT" ); if (fwbdebug) qDebug("Running rlog: %s %s", rlog_file_name.toLocal8Bit().constData(), arglist.join(" ").toLocal8Bit().constData()); stdoutBuffer = ""; stderrBuffer = ""; //proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( rlog_file_name, arglist ); proc->waitForStarted(); if (proc->state() != QProcess::Running) { proc->close(); throw(FWException("Fatal error running rlog ")); } if (fwbdebug) qDebug("Running rlog"); proc->waitForFinished(); if (fwbdebug) qDebug("Running rlog: finished reading"); // Note: we convert rlog comments to Utf8. Local8Bit does not seem // to work on windows, produces '????' QString rlogTxt = QString::fromUtf8(stdoutBuffer.toAscii().constData()); if (proc->state() == QProcess::NotRunning && proc->exitCode()==0) return rlogTxt; QString msg=QObject::tr("Fatal error running rlog for %1").arg(filename); throw( FWException( msg.toLatin1().constData() ) ); } QStringList RCS::rcsdiff(const QString&) throw(libfwbuilder::FWException) { isDiff(); QString temp = stdoutBuffer; return temp.split("\n"); } bool RCS::isDiff(const QString &rev) throw(libfwbuilder::FWException) { if (!rcs_available) throw(FWException(QObject::tr("RCS tools are unavailable").toStdString())); QStringList arglist; arglist << "-q"; if (rev!="") arglist << QString("-r")+rev; else { if (selectedRev!="") arglist << QString("-r")+selectedRev; } arglist << QString("-z") + rcsenvfix->getTZOffset() << filename; stdoutBuffer=""; stderrBuffer=""; proc->setEnvironment(*rcsenvfix->getEnv()); proc->start( rcsdiff_file_name, arglist ); proc->waitForStarted(); if (proc->state() == QProcess::Running) { proc->waitForFinished(); /*while (proc->state() == QProcess::Running) { QByteArray ba = proc->readAllStandardOutput(); if (ba.size()!=0) stdoutBuffer=stdoutBuffer + QString(ba); }*/ } else throw(FWException("Fatal error running rcsdiff ")); // while (proc->state() == QProcess::Running) ; // cxx_sleep(1); if (proc->state() == QProcess::NotRunning) return (proc->exitCode()!=0); QString msg = QObject::tr( "Fatal error running rcsdiff for file %1").arg(filename); throw( FWException( msg.toLatin1().constData() ) ); } QString RCS::getHead() { if (isInRCS()) return head; return ""; } QString RCS::getSelectedRev() { if (isInRCS()) return selectedRev; return ""; } fwbuilder-5.1.0.3599/src/libgui/ObjectDescriptor.cpp0000644000175000017500000000520611733011756023014 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "ObjectDescriptor.h" // #include snmp.h only after all Qt headers; see #2185 #include "fwbuilder/snmp.h" using namespace std; using namespace libfwbuilder; ObjectDescriptor::ObjectDescriptor() {} ObjectDescriptor::ObjectDescriptor(const ObjectDescriptor& od) { have_snmpd = od.have_snmpd; descr = od.descr; contact = od.contact; location = od.location; sysname = od.sysname; interfaces = od.interfaces; MAC_addr = od.MAC_addr; dns_info.name = od.dns_info.name; dns_info.aliases = od.dns_info.aliases; addr = od.addr; type = od.type; isSelected = od.isSelected; netmask = od.netmask; } #ifdef HAVE_LIBSNMP ObjectDescriptor::ObjectDescriptor(const libfwbuilder::CrawlerFind *cf) { have_snmpd = cf->have_snmpd; descr = cf->descr; contact = cf->contact; location = cf->location; sysname = cf->sysname; interfaces = cf->interfaces; MAC_addr = cf->found_phys_addr; dns_info.name = cf->name; dns_info.aliases = cf->aliases; } #endif ObjectDescriptor::~ObjectDescriptor() {}; ObjectDescriptor& ObjectDescriptor::operator=(const ObjectDescriptor& od) { have_snmpd = od.have_snmpd; descr = od.descr; contact = od.contact; location = od.location; sysname = od.sysname; interfaces = od.interfaces; MAC_addr = od.MAC_addr; dns_info.name = od.dns_info.name; dns_info.aliases = od.dns_info.aliases; addr = od.addr; type = od.type; isSelected = od.isSelected; netmask = od.netmask; return *this; } fwbuilder-5.1.0.3599/src/libgui/SSHSession.h0000644000175000017500000001320511733011756021213 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SSHSESSION_H_ #define __SSHSESSION_H_ #include "config.h" #include "global.h" #include #include #include #include #include #include #include #include class QTimer; class instConf; class QWidget; class SSHSession : public QObject { Q_OBJECT protected: QWidget *parent; QProcess *proc; int retcode; QTimer *heartBeatTimer; QString stdoutBuffer; QString stderrBuffer; QString ssh; QString cmd; QStringList args; std::list input; bool closeStdin; bool logged_in; bool enable; bool configure; bool endOfCopy; bool send_keepalive; bool session_completed; enum State { NONE, LOGGEDIN, WAITING_FOR_ENABLE, PRE_CONFIG_COMMANDS, SCHEDULE_RELOAD_DIALOG, ENABLE, CONFIG, COMMAND_SENT, WAITING_FOR_SHOW_RUN, WAITING_FOR_CONFIG_PROMPT, CLEAR_CONFIG, PUSHING_CONFIG, GET_ACLS, CLEAR_ACLS, GET_OG, CLEAR_OG, EXIT_FROM_CONFIG, SAVE_CONFIG, SAVE_STANDBY, RUN_SCRIPT, EXIT, FINISH, EXECUTING_COMMAND, COMMAND_DONE }; enum State state; int phase; bool verbose; bool quiet; bool error; bool backup; bool incremental; bool dry_run; bool saveStandby; bool stripComments; QString wdir; QString script; QString backupFile; QString diff_pgm; bool save_diff; QString diff_file; QString normal_prompt; QString fwb_prompt; QString enable_prompt; QString config_prompt; QString pwd_prompt_1; QString pwd_prompt_2; QString putty_pwd_prompt; QString ssh_pwd_prompt; QString thinkfinger_pwd_prompt; QString ssoft_prompt1; QString ssoft_prompt2; QString ssoft_config_prompt; QString sudo_pwd_prompt_1; QString sudo_pwd_prompt_2; QString passphrase_prompt; QString epwd_prompt; QStringList errorsInit; QStringList errorsLoggedin; QStringList errorsEnabledState; QString pendingLogLine; QString pwd; QString epwd; QString host; static const char* newKeyOpenSSH; static const char* newKeyPlink; static const char* newKeyVsh; static const char* newKeySSHComm; static const char* fingerprintPrompt1; static const char* fingerprintPrompt2; QString newKeyMsg; bool cmpPrompt(const QString &str,const QString &prompt); bool cmpPrompt(const QString &str,const QRegExp &prompt); void startHeartBeat(); void stopHeartBeat(); protected: virtual void sendCommand(const QString &cmd); void cleanUp(); public: SSHSession(QWidget *parent, const QString &host, const QStringList &args, const QString &pwd, const QString &epwd, const std::list &in); virtual ~SSHSession(); virtual bool checkForErrors(); virtual void stateMachine(); void startSession(); void terminate(); void setOptions(instConf *cnf); void setCloseStdin(bool f) { closeStdin=f; } void setFWBPrompt(const QString &p) { fwb_prompt=p; } void setQuiet(bool f) { quiet=f; } void setVerbose(bool f) { verbose=f; } void setBackup(bool f) { backup=f; } void setIncr(bool f) { incremental=f; } void setDryRun(bool f) { dry_run=f; } void setSaveStandby(bool f) { saveStandby=f; } void setStripComments(bool f) { stripComments=f; } void setWDir(const QString &wd) { wdir=wd; } void setScript(const QString &cf) { script=cf; } void setBackupFile(const QString &cf) { backupFile=cf; } void setSaveDiff(bool f) { save_diff=f; } void setDiffPgm(const QString &v) { diff_pgm=v; } void setDiffFile(const QString &v) { diff_file=v; } bool getErrorStatus() { return error; } void sessionComplete(bool err); QString findKeyFingerprint(QString &buffer); public slots: virtual void readFromStdout(); virtual void readFromStderr(); virtual void finished( int code ); void readyToSend(); void sendLine(); void allDataSent(); void heartBeat(); signals: void printStdout_sign(const QString &line); void sessionFinished_sign(); void sessionFatalError_sign(); void updateProgressBar_sign(int n,bool setsize); }; #endif fwbuilder-5.1.0.3599/src/libgui/ObjectEditorDockWidget.cpp0000644000175000017500000000417211733011756024072 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2008 NetCitadel, LLC Author: vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "ObjectEditorDockWidget.h" #include "ObjectEditor.h" #include #include ObjectEditorDockWidget::ObjectEditorDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags) : QDockWidget(title, parent, flags) { editor = NULL; connect(this, SIGNAL(topLevelChanged(bool)), this, SLOT(topLevelChanged(bool))); } ObjectEditorDockWidget::ObjectEditorDockWidget(QWidget *parent, Qt::WindowFlags flags) : QDockWidget(parent, flags) { editor = NULL; connect(this, SIGNAL(topLevelChanged(bool)), this, SLOT(topLevelChanged(bool))); } void ObjectEditorDockWidget::setupEditor(ObjectEditor *ed) { editor = ed; } void ObjectEditorDockWidget::closeEvent(QCloseEvent *event) { if (fwbdebug) qDebug() << "ObjectEditorDockWidget::closeEvent()"; if (!editor->validate()) { editor->load(); // bad changes in the editor, reset event->ignore(); return; } event->accept(); if (fwbdebug) qDebug() << "ObjectEditorDockWidget::closeEvent() done"; } void ObjectEditorDockWidget::topLevelChanged(bool topLevel) { if (topLevel) adjustSize(); } fwbuilder-5.1.0.3599/src/libgui/ColorLabelMenuItem.h0000644000175000017500000000330311733011756022672 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COLORLABELMENUITEM_H_ #define __COLORLABELMENUITEM_H_ #include "config.h" #include class QToolButton; class ColorLabelMenuItem : public QWidget { Q_OBJECT void setup(QToolButton *btn, const QString &c, const QString &t); QString color; public: Ui::colorLabelMenuItem_q *m_widget; ColorLabelMenuItem(QWidget *parent); ~ColorLabelMenuItem() { delete m_widget; }; public slots: virtual void colorClicked(); virtual void noneColorClicked(); virtual void redColorClicked(); virtual void orangeColorClicked(); virtual void yellowColorClicked(); virtual void greenColorClicked(); virtual void blueColorClicked(); virtual void purpleColorClicked(); virtual void grayColorClicked(); signals: void returnColor(const QString &c); }; #endif // __COLORLABELMENUITEM_H fwbuilder-5.1.0.3599/src/libgui/secuwalladvanceddialog_q.ui0000644000175000017500000013552011733011756024412 0ustar sylvestresylvestre secuwallAdvancedDialog_q Qt::WindowModal true 0 0 762 665 0 0 iptables: advanced settings false Help Qt::Horizontal QSizePolicy::Expanding 351 27 &OK true true &Cancel true 0 0 0 Compiler Compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 22 0 0 Command line options for the compiler: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 32767 22 QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Vertical QSizePolicy::Maximum 0 0 0 0 Assume firewall is part of 'any' Qt::Horizontal QSizePolicy::Maximum 30 150 0 0 Accept TCP sessions opened prior to firewall restart 0 0 Accept ESTABLISHED and RELATED packets before the first rule Drop packets that are associated with no known connection and log them Qt::Horizontal QSizePolicy::Expanding 80 20 0 0 Bridging firewall 0 0 Detect shadowing in policy rules 0 0 Ignore empty groups in rules 0 0 Enable support for NAT of locally originated connections 0 0 This adds a rule on top of the policy with iptables target TCPMSS and option --clamp-mss-to-pmtu. Generation of this command is version-dependent and also depends on the setting of ip or ipv6 forwarding in host settings dialog. Clamp MSS to MTU Default action on 'Reject': false Qt::Horizontal QSizePolicy::Expanding 72 20 QFrame::HLine QFrame::Sunken Qt::Horizontal Qt::Horizontal QSizePolicy::Fixed 30 50 Always permit ssh access from the management workstation with this address: 0 0 32767 32767 Install the rule for ssh access from the management workstation when the firewall is stopped Qt::Vertical QSizePolicy::Expanding 20 20 Installer 6 Built-in installer 6 Additional command line parameters for ssh false 0 0 300 0 Additional command line parameters for scp false 0 0 300 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 250 0 0 0 250 0 Qt::Vertical QSizePolicy::Expanding 20 120 External install script 0 0 Policy install script (using built-in installer if this field is blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 300 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 300 0 Prolog/Epilog 6 6 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 The following commands will be added verbatim after generated configuration Qt::AlignVCenter true 6 The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Edit Insert prolog script false 0 0 on top of the script after interface configuration after policy reset Logging 6 20 true false 20 12 use ULOG use LOG 0 0 log TCP seq. numbers log IP options use numeric syslog levels Log level: false log TCP options 0 1500 cprange false 1 queue threshold: false netlink group: false 1 32 Qt::Vertical QSizePolicy::Expanding 20 16 0 0 QFrame::VLine QFrame::Sunken Qt::Vertical 0 0 Log prefix: false 32 Logging limit: false 10000 0 0 Activate logging in all rules (overrides rule options, use for debugging) Qt::Vertical QSizePolicy::Expanding 20 40 Qt::Vertical QSizePolicy::Expanding 20 16 Script Qt::Horizontal QSizePolicy::Fixed 30 20 0 0 Allow reboot to load modules (only if needed) Qt::Vertical QSizePolicy::Fixed 556 18 0 0 Turn debugging on in generated script Qt::Vertical QSizePolicy::Fixed 556 18 Managing interfaces and addresses 0 0 Verify interfaces before loading firewall policy 0 0 Configure Interfaces of the running firewall machine 0 0 Add virtual addresses for NAT Qt::Vertical QSizePolicy::Fixed 556 40 Generated script can load rules one by one by calling iptables command line utility, or activate them all at once using iptables-restore. In both cases you just run the script with command line parameter "start" to activate the policy, the script will use iptables-restore automatically if this checkbox is on. true 0 0 iptables-restore replaces firewall policy in one atomic transaction Use iptables-restore to activate policy Qt::Vertical QSizePolicy::Expanding 20 200 Warning: rebooting breaks the connectivity until the firewall is up again. The outage can be up to minutes, depending on how fast the machine restarts. true If debugging is turned on, the script will run with shell option "-x" that makes it print every command it executes. Warning: this produces a lot of debugging output. true Warning: this breaks the connectivity until all interfaces are 'up' again. The outage is typically < 10 seconds true tabWidget compiler compilerArgs assumeFwIsPartOfAny acceptSessions acceptESTBeforeFirst dropInvalid logInvalid bridge shadowing emptyGroups localNAT clampMSStoMTU actionOnReject mgmt_ssh mgmt_addr add_mgmt_ssh_rule_when_stoped altAddress activationCmd sshArgs scpArgs installScript installScriptArgs prolog_script prologPlace edit_prolog_button epilog_script edit_epilog_button useLOG useULOG logTCPseq logTCPopt logIPopt logNumsyslog logLevel logprefix logLimitVal logLimitSuffix logAll allowReboot iptDebug verifyInterfaces configureInterfaces addVirtualsforNAT iptablesRestoreActivation buttonHelp buttonOk buttonCancel cprange qthreshold nlgroup buttonOk clicked() secuwallAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() secuwallAdvancedDialog_q reject() 20 20 20 20 buttonHelp clicked() secuwallAdvancedDialog_q help() 20 20 20 20 useLOG toggled(bool) secuwallAdvancedDialog_q switchLOG_ULOG() 20 20 20 20 edit_prolog_button clicked() secuwallAdvancedDialog_q editProlog() 20 20 20 20 edit_epilog_button clicked() secuwallAdvancedDialog_q editEpilog() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/InterfaceEditorWidget.cpp0000644000175000017500000004072011733011756023762 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Roman Bovsunivskiy a2k0001@gmail.com $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "InterfaceEditorWidget.h" #include "ui_InterfaceEditorWidget.h" #include "FWObjectPropertiesFactory.h" #include "fwbuilder/IPv4.h" #include "fwbuilder/IPv6.h" #include #include #include using namespace libfwbuilder; using namespace std; InterfaceEditorWidget::InterfaceEditorWidget(QWidget *parent) : QWidget(parent), m_ui(new Ui::InterfaceEditorWidget) { tabw = dynamic_cast(parent); this->interfacep = NULL; m_ui->setupUi(this); setClusterMode(false); this->m_ui->name->setText(""); // blank interface name this->m_ui->label->clear(); this->m_ui->comment->clear(); // addNewAddress(); } InterfaceEditorWidget::InterfaceEditorWidget(QWidget *parent, Interface *iface) : QWidget(parent), m_ui(new Ui::InterfaceEditorWidget) { tabw = dynamic_cast(parent); this->interfacep = iface; m_ui->setupUi(this); setClusterMode(false); this->m_ui->name->setText(interfacep->getName().c_str()); this->m_ui->label->setText(interfacep->getLabel().c_str()); // if (iface->getPhysicalAddress() != NULL) // m_ui->mac->setText(iface->getPhysicalAddress()->getPhysAddress().c_str()); this->m_ui->comment->setPlainText(iface->getComment().c_str()); if ( this->interfacep->isDyn() ) this->m_ui->type->setCurrentIndex(1); if ( this->interfacep->isUnnumbered() ) this->m_ui->type->setCurrentIndex(2); FWObjectTypedChildIterator adriter = iface->findByType(IPv4::TYPENAME); for ( ; adriter != adriter.end(); ++adriter ) { Address *addr = Address::cast(*adriter); int row = addNewAddress(addr->getAddressPtr()->toString().c_str(), addr->getNetmaskPtr()->toString().c_str(), addr->getAddressPtr()->isV4()); fwaddrs[row] = addr; } FWObjectTypedChildIterator adriter2 = iface->findByType(IPv6::TYPENAME); for ( ; adriter2 != adriter2.end(); ++adriter2 ) { Address *addr = Address::cast(*adriter2); int row = addNewAddress(addr->getAddressPtr()->toString().c_str(), addr->getNetmaskPtr()->toString().c_str(), addr->getAddressPtr()->isV4()); fwaddrs[row] = addr; } } InterfaceEditorWidget::InterfaceEditorWidget(QWidget *parent, ClusterInterfaceData data) : QWidget(parent), m_ui(new Ui::InterfaceEditorWidget) { clusterMode = true; tabw = dynamic_cast(parent); m_ui->setupUi(this); this->interfacep = NULL; this->m_ui->name->setText(data.name); this->m_ui->label->setText(data.label); this->m_ui->comment->setText(data.comment); setHostOS(data.os); list types; getFailoverTypesForOS(os, types); QStringList typenames; QString lastProtocol = st->getNewClusterFailoverProtocol(); int toSelect = 0; foreach(QStringPair pair, types) { typenames << pair.second; if (pair.second == lastProtocol) toSelect = typenames.count() - 1; } this->m_ui->protocol->clear(); this->m_ui->protocol->insertItems(0, typenames); this->m_ui->protocol->setCurrentIndex(toSelect); this->protocolChanged(this->m_ui->protocol->currentText()); } void InterfaceEditorWidget::setData(InterfaceData *data) { this->m_ui->name->setText(data->name.c_str()); this->m_ui->label->setText(data->label.c_str()); // this->m_ui->mac->setText(data->mac_addr.c_str()); this->m_ui->comment->clear(); if ( data->isDyn ) this->m_ui->type->setCurrentIndex(1); else if ( data->isUnnumbered ) this->m_ui->type->setCurrentIndex(2); else this->m_ui->type->setCurrentIndex(0); foreach(QPushButton *btn, this->buttons.keys()) btn->click(); if ( !data->isDyn && !data->isUnnumbered ) { foreach( InetAddrMask* addr, data->addr_mask ) { addNewAddress(addr->getAddressPtr()->toString().c_str(), addr->getNetmaskPtr()->toString().c_str(), !addr->getAddressPtr()->isV6()); } } } void InterfaceEditorWidget::deleteAddress() { QPushButton *button = dynamic_cast(sender()); QPair items = buttons[button]; buttons.remove(button); int row = items.first->row(); this->m_ui->addresses->removeRow(row); delete types[row]; // shift elements up in these maps int idx = row; for (; idx < (rows.size() - 1); idx++) { types[row] = types[row+1]; rows[row] = rows[row+1]; fwaddrs[row] = fwaddrs[row+1]; } types.remove(idx); rows.remove(idx); fwaddrs.remove(idx); this->addressChanged(-1, -1); } InterfaceEditorWidget::~InterfaceEditorWidget() { delete m_ui; foreach(QPushButton* btn, buttons.keys()) delete btn; foreach(QComboBox* box, types.values()) delete box; } int InterfaceEditorWidget::addNewAddress() { int row = this->m_ui->addresses->rowCount(); fwaddrs[row] = NULL; this->m_ui->addresses->insertRow(row); QTableWidgetItem *addrItem = new QTableWidgetItem(); QTableWidgetItem *netItem = new QTableWidgetItem(); this->m_ui->addresses->setItem(row, 0, addrItem); this->m_ui->addresses->setItem(row, 1, netItem); QPushButton *button = new QPushButton(this->m_ui->addresses); button->setText(tr("Remove")); connect(button, SIGNAL(clicked()), this, SLOT(deleteAddress())); this->m_ui->addresses->setCellWidget(row, 3, button); QComboBox *box = new QComboBox(); box->addItem("IPv4"); box->addItem("IPv6"); this->m_ui->addresses->setCellWidget(row, 2, box); buttons[button] = qMakePair(addrItem, netItem); rows[row] = qMakePair(addrItem, netItem); types[row] = box; return row; } int InterfaceEditorWidget::addNewAddress(QString address, QString netmask, bool ipv4) { int row = addNewAddress(); types[row]->setCurrentIndex(!ipv4); rows[row].first->setText(address); rows[row].second->setText(netmask); return row; } void InterfaceEditorWidget::changeEvent(QEvent *e) { QWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } void InterfaceEditorWidget::nameEdited(QString newname) { tabw->setTabText(tabw->indexOf(this), newname); } Interface* InterfaceEditorWidget::getInterface() { return this->interfacep; } EditedInterfaceData InterfaceEditorWidget::getInterfaceData() { EditedInterfaceData res; res.name = this->m_ui->name->text(); res.label = this->m_ui->label->text(); res.comment = this->m_ui->comment->toPlainText(); res.type = this->m_ui->type->currentIndex(); res.protocol = this->m_ui->protocol->currentText(); // res.mac = this->m_ui->mac->text(); bool noAddrs = false; // if (clusterMode) // noAddrs = Resources::os_res[os.toStdString()]->getResourceBool( // "/FWBuilderResources/Target/protocols/" // + this->m_ui->protocol->currentText().toLower().toStdString() + "/no_ip_ok"); if (this->m_ui->protocol->currentText() == "None") noAddrs = true; if (!noAddrs) for ( int i = 0; i < this->m_ui->addresses->rowCount(); i++ ) { AddressInfo info; if (rows[i].first == NULL) continue; // deleted row info.address = rows[i].first->text(); info.netmask = rows[i].second->text(); info.ipv4 = types[i]->currentIndex() == 0; res.addresses.insert(fwaddrs[i], info); } return res; } void InterfaceEditorWidget::typeChanged(int type) { if (clusterMode) return; if (type != 0) { while ( this->m_ui->addresses->rowCount() > 0 ) this->m_ui->addresses->removeRow(0); foreach ( QPushButton* btn, buttons.keys() ) delete btn; foreach ( QComboBox* box, types.values() ) delete box; types.clear(); buttons.clear(); fwaddrs.clear(); rows.clear(); this->m_ui->addresses->setEnabled(false); this->m_ui->addAddress->setEnabled(false); } else { this->m_ui->addresses->setEnabled(true); this->m_ui->addAddress->setEnabled(true); } } bool InterfaceEditorWidget::isValid() { #if 0 // do not do this check in the wizard because there are too many // combinations: most protocols can work with and without an // address on the cluster interfaces and only one (VRRP) requires // it. Unfortunately attribute in the OS resource file only tells // when it is ok to have no address, but does not tell when it must // be there. And we do this check in the compiler anyway. Tcikets // #1180, #1172 bool no_addr_ok = true; if (clusterMode) { no_addr_ok = Resources::os_res[os.toStdString()]->getResourceBool( "/FWBuilderResources/Target/protocols/" + this->m_ui->protocol->currentText().toLower().toStdString() + "/no_ip_ok") || this->m_ui->protocol->currentText() == "None"; } if (clusterMode && no_addr_ok && this->m_ui->addresses->rowCount() != 0) { QMessageBox::warning( this, "Firewall Builder", tr("Failover protocol %1 does not require IP address for interface %2") .arg(this->m_ui->protocol->currentText()) .arg(this->m_ui->name->text()), "&Continue", QString::null, QString::null, 0, 1 ); return false; } if (!no_addr_ok && this->m_ui->addresses->rowCount() == 0) { if ( (this->m_ui->type->currentIndex() == 0) && (this->m_ui->addresses->rowCount() == 0) ) { QMessageBox::warning( this, "Firewall Builder", tr("Failover protocol %1 requires an IP address for interface %2") .arg(this->m_ui->protocol->currentText()) .arg(this->m_ui->name->text()), "&Continue", QString::null, QString::null, 0, 1 ); return false; } } #endif if (this->m_ui->name->text().isEmpty()) { setError("Firewall Builder", tr("Interface name can not be blank." "
" "
" "Interface name must match the name of the physical interface, " "such as 'eth0', 'fxp0', 'ethernet0', etc")); return false; } for (int i = 0; i < this->m_ui->addresses->rowCount(); i++) { if (types[i] == NULL) continue; // deleted row QString address = this->m_ui->addresses->item(i, 0)->text(); QString netmask = this->m_ui->addresses->item(i, 1)->text(); if ( !validateAddress( address, netmask, this->m_ui->type->currentIndex() == 0, types[i]->currentIndex() == 1) ) { return false; } } return true; } bool InterfaceEditorWidget::validateAddress(const QString &addr, const QString &netm, bool regular, bool ipv6) { if ( regular && ( addr.isEmpty() || netm.isEmpty() ) ) { setError("Firewall Builder", tr("Empty address or netmask field")); return false; } try { if (ipv6) InetAddr(AF_INET6, addr.toLatin1().constData()); else InetAddr(addr.toLatin1().constData()); } catch (FWException &ex) { setError("Firewall Builder", tr("Invalid address '%1/%2'").arg(addr).arg(netm)); return false; } try { bool ok = false ; int ilen = netm.toInt (&ok); if (ok) { if (ilen < 0 || (ipv6 && ilen > 128) || (!ipv6 && ilen > 32)) { setError("Firewall Builder", tr("Invalid netmask '%1/%2'").arg(addr).arg(netm)); return false; } } else { if (ipv6) InetAddr(AF_INET6, netm.toLatin1().constData()); else InetAddr(netm.toLatin1().constData()); } } catch (FWException &ex) { setError("Firewall Builder", tr("Invalid netmask '%1/%2'").arg(addr).arg(netm)); return false; } return true; } void InterfaceEditorWidget::resizeEvent ( QResizeEvent * ) { int total = this->m_ui->addresses->viewport()->width(); if (total < 100) total = int(this->m_ui->addresses->width() * 0.95); int controls; if ( total/4 > 130 ) controls = 130; else controls = total/4; this->m_ui->addresses->setColumnWidth(0, (total - controls*2)/2); this->m_ui->addresses->setColumnWidth(1, (total - controls*2)/2); this->m_ui->addresses->setColumnWidth(2, controls); this->m_ui->addresses->setColumnWidth(3, controls); } void InterfaceEditorWidget::addressChanged(int row, int col) { // if (m_ui->addresses->rowCount() >= 1) // m_ui->addAddress->setText(tr("Add another address")); // else m_ui->addAddress->setText(tr("Add address")); if ( row < 0 || col < 0 || rows.isEmpty() || row > m_ui->addresses->rowCount() || col > 1 ) return; if (!rows.keys().contains(row)) return; QString address = this->rows[row].first->text(); QString netmask = this->rows[row].second->text(); if ( address.isEmpty() || netmask.isEmpty() ) return; bool regular = this->m_ui->type->currentIndex() == 0; bool ipv6 = this->types[row]->currentIndex() == 1; if (!validateAddress(address, netmask, regular, ipv6)) this->m_ui->addresses->editItem(this->m_ui->addresses->item(row, col)); } void InterfaceEditorWidget::setClusterMode(bool st) { clusterMode = st; this->m_ui->name->setEnabled(!st); this->m_ui->protocol->setVisible(st); this->m_ui->protocolLabel->setVisible(st); // this->m_ui->mac->setVisible(!st); // this->m_ui->macLabel->setVisible(!st); this->m_ui->type->setVisible(!st); this->m_ui->typeLabel->setVisible(!st); } void InterfaceEditorWidget::protocolChanged(QString name) { if (clusterMode) { bool noaddr = (name == "None"); if (noaddr) while ( this->m_ui->addresses->rowCount() ) this->m_ui->addresses->removeRow(0); this->m_ui->addresses->setEnabled(!noaddr); this->m_ui->addAddress->setEnabled(!noaddr); st->setNewClusterFailoverProtocol(name); } } void InterfaceEditorWidget::setExplanation(const QString& text) { this->m_ui->explanation->setText(text); this->m_ui->explanation->setFont(QApplication::font()); } void InterfaceEditorWidget::setProtocolIndex(int idx) { this->m_ui->protocol->setCurrentIndex(idx); } void InterfaceEditorWidget::setHostOS(const QString &s) { os = s; QString name_prompt = FWObjectPropertiesFactory::getInterfaceNameExamplesForHostOS(os); if (fwbdebug) qDebug() << "Interface name prompt:" << name_prompt; #if (QT_VERSION >= 0x040700) this->m_ui->name->setPlaceholderText(name_prompt); this->m_ui->label->setPlaceholderText("outside, inside, etc (optional)"); #endif this->m_ui->name->setToolTip(name_prompt); this->m_ui->label->setToolTip("outside, inside, etc (optional)"); } void InterfaceEditorWidget::setError(const QString &title, const QString &text) { errorTitle = title; errorText = text; } void InterfaceEditorWidget::showError() { QMessageBox::warning(this, errorTitle, errorText, "&Continue", QString::null, QString::null, 0, 1); } fwbuilder-5.1.0.3599/src/libgui/FWObjectClipboard.h0000644000175000017500000000405311733011756022476 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2000-2006 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FWOBJECT_CLIPBOARD_H #define _FWOBJECT_CLIPBOARD_H #include #include #include "fwbuilder/FWObject.h" class ProjectPanel ; class FWObjectClipboard { std::vector > ids; public: FWObjectClipboard(); ~FWObjectClipboard(); /** * adds an object to the clipboard */ void add(libfwbuilder::FWObject*, ProjectPanel *proj_p); /** * returns the last added object */ libfwbuilder::FWObject* getObject(); /** * removes object from the clipboard if it is there */ void remove(libfwbuilder::FWObject*); /** * clear the clipboard */ void clear(); libfwbuilder::FWObject* getObjectByIdx (int idx); std::vector >::iterator begin() { return ids.begin(); } std::vector >::iterator end() { return ids.end(); } std::vector >::reverse_iterator rbegin() { return ids.rbegin(); } std::vector >::reverse_iterator rend() { return ids.rend(); } int size() { return ids.size(); } static FWObjectClipboard *obj_clipboard; }; #endif fwbuilder-5.1.0.3599/src/libgui/GroupObjectDialog.h0000644000175000017500000000546711733011756022570 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GROUPOBJECTDIALOG_H_ #define __GROUPOBJECTDIALOG_H_ #include "config.h" #include #include #include #include "fwbuilder/FWObject.h" #include "ObjectListView.h" #include "ObjectIconView.h" #include "BaseObjectDialog.h" #include class ObjectIconViewItem; class ObjectListViewItem; class QMenu; class ProjectPanel; class GroupObjectDialog : public BaseObjectDialog { Q_OBJECT; Ui::GroupObjectDialog_q *m_dialog; ObjectIconView *iconView; ObjectListView *listView; QMenu *new_object_menu; std::vector selectedObjects; libfwbuilder::FWObject *selectedObject; void addIcon(libfwbuilder::FWObject *o); void addIcon(libfwbuilder::FWObject *o, bool ref); void setupPopupMenu(const QPoint&); void saveColumnWidths(); public: GroupObjectDialog(QWidget *parent); ~GroupObjectDialog(); enum viewType { Icon, List }; // making insertObject() public so we can use it in unit tests void insertObject(libfwbuilder::FWObject *o); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void switchToIconView(); virtual void switchToListView(); virtual void openObject(); virtual void dropped(QDropEvent *ev); virtual void iconContextMenu(const QPoint & pos); virtual void listContextMenu(const QPoint & pos); void copyObj(); void cutObj(); void pasteObj(); void deleteObj(); void iconViewCurrentChanged(QListWidgetItem *itm); void listViewCurrentChanged(QTreeWidgetItem *itm); void iconViewSelectionChanged(); void listViewSelectionChanged(); void selectObject(libfwbuilder::FWObject *o); void newObject(); void itemDoubleClicked(QListWidgetItem*); void itemDoubleClicked(QTreeWidgetItem*, int); private: static enum viewType vt; public: }; #endif // GROUPOBJECTDIALOG_H fwbuilder-5.1.0.3599/src/libgui/linux24IfaceOptsDialog.cpp0000644000175000017500000001321111733011756023765 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "linux24IfaceOptsDialog.h" #include "platforms.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "FWWindow.h" #include "Help.h" #include #include #include using namespace std; using namespace libfwbuilder; linux24IfaceOptsDialog::linux24IfaceOptsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::linux24IfaceOptsDialog_q; m_dialog->setupUi(this); setWindowModality(Qt::WindowModal); obj = o; FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject(); cluster_interface = (Cluster::cast(obj->getParent()) != NULL); setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj), ifopt->getStr("type").c_str()); // Using "type" control only for subinterfaces // and main interfaces of the firewall objects if (cluster_interface) { m_dialog->iface_type->hide(); m_dialog->iface_type_label->hide(); } else { m_dialog->iface_type->show(); m_dialog->iface_type_label->show(); } data.registerOption(m_dialog->enable_stp, ifopt, "enable_stp"); data.registerOption(m_dialog->vlan_id, ifopt, "vlan_id"); data.registerOption(m_dialog->bonding_policy, ifopt, "bonding_policy"); data.registerOption(m_dialog->xmit_hash_policy, ifopt, "xmit_hash_policy"); data.registerOption(m_dialog->bondng_driver_options, ifopt, "bondng_driver_options"); data.loadAll(); // special actions for different iface types // VLAN (8021q) typeChanged(""); bondingPolicyChanged(ifopt->getStr("bonding_policy").c_str()); } linux24IfaceOptsDialog::~linux24IfaceOptsDialog() { delete m_dialog; } /* * store all data in the object */ void linux24IfaceOptsDialog::accept() { // validate user input before saving if (!validate()) return; ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the interface object FWObject* new_state = cmd->getNewState(); FWOptions* ifopt = Interface::cast(new_state)->getOptionsObject(); assert(ifopt!=NULL); if (cluster_interface) { ifopt->setStr("type", "cluster_interface"); } else { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); ifopt->setStr("type", new_type.toStdString()); } data.saveAll(ifopt); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void linux24IfaceOptsDialog::reject() { QDialog::reject(); } void linux24IfaceOptsDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Interface Linux 2.4/2.6"); h->setSource(QUrl("linux24IfaceOptsDialog.html#" + anchor)); h->raise(); h->show(); } void linux24IfaceOptsDialog::typeChanged(const QString&) { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); // enable VLAN ID line edit for type VLAN if (new_type == "8021q") { m_dialog->options_stack->setCurrentIndex(1); return; } if (new_type == "bridge") { m_dialog->options_stack->setCurrentIndex(2); return; } if (new_type == "bonding") { m_dialog->options_stack->setCurrentIndex(3); return; } // page 0 is empty m_dialog->options_stack->setCurrentIndex(0); } void linux24IfaceOptsDialog::bondingPolicyChanged(const QString &new_policy) { m_dialog->xmit_hash_policy->setEnabled(new_policy == "802.3ad" || new_policy == "balance-xor"); } bool linux24IfaceOptsDialog::validate() { bool valid = true; QString combobox = m_dialog->iface_type->currentText(); QString type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); QWidget *focus = NULL; QString message; if (type == "vrrp") { // Both vvrp_secret and vrrp_id attributes moved to vrrpOptionsDialog ; } if (type == "8021q") { // VLAN ID must be set between 1 <= vid <= 4'094 // QSpinBox widget enforces these limits ; } if (!valid) { QMessageBox::warning(this, "Firewall Builder", tr("Input not valid: %1").arg(message), "&Continue", QString::null, QString::null, 0, 1); focus->setFocus(); } return valid; } fwbuilder-5.1.0.3599/src/libgui/actionsdialog_q.ui0000644000175000017500000004323111733011756022542 0ustar sylvestresylvestre ActionsDialog_q 0 0 852 229 Actions Dialog QFrame::Box QFrame::Sunken 320 0 QFrame::NoFrame QFrame::Plain 5 12 12 If rule action is 'Reject', this option defines firewall's reaction to the packet matching the rule Qt::AlignVCenter true Qt::Vertical QSizePolicy::MinimumExpanding 20 0 300 0 Qt::Horizontal QSizePolicy::MinimumExpanding 10 20 Qt::Horizontal QSizePolicy::MinimumExpanding 0 20 12 12 This action has no parameters. Qt::AlignCenter true 12 12 Rule name for accounting. (white spaces and special characters are not allowed) Qt::AlignVCenter true Qt::Vertical QSizePolicy::MinimumExpanding 20 0 12 12 Custom string: false Qt::Vertical QSizePolicy::MinimumExpanding 20 0 12 12 Divert socket port number: false Qt::Horizontal QSizePolicy::Expanding 40 20 80 0 999999 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 12 Policy ruleset object: false 0 0 100 80 9 In addition to 'filter', create branching rule in 'mangle' table as well Qt::Horizontal 41 21 Qt::Vertical QSizePolicy::MinimumExpanding 30 20 12 Policy rule set object: false 0 0 100 80 9 Qt::Horizontal 701 64 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 12 NAT Rule set object: 0 0 100 80 100 80 Qt::Horizontal 663 20 Qt::Vertical 20 33 FWObjectDropArea QWidget
FWObjectDropArea.h
1
rejectvalue activated(QString) ActionsDialog_q changed() 178 240 20 20 ipt_branch_in_mangle toggled(bool) ActionsDialog_q changed() 45 250 20 20 divertPortNum valueChanged(int) ActionsDialog_q changed() 225 218 20 20 custom_str editingFinished() ActionsDialog_q changed() 46 233 20 20 accountingvalue_str editingFinished() ActionsDialog_q changed() 46 233 20 20 changed()
fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/0000755000175000017500000000000011733011756025751 5ustar sylvestresylvestrefwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_NetworkZonesPage.cpp0000644000175000017500000001117611733011756032303 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "events.h" #include "FWBSettings.h" #include "networkZoneManager.h" #include "IC_NetworkZonesPage.h" #include "ImportFirewallConfigurationWizard.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" #include #include #include using namespace std; using namespace libfwbuilder; IC_NetworkZonesPage::IC_NetworkZonesPage(QWidget *parent) : QWizardPage(parent), m_dialog(new Ui::IC_NetworkZonesPage_q) { m_dialog->setupUi(this); } IC_NetworkZonesPage::~IC_NetworkZonesPage() { delete m_dialog; } void IC_NetworkZonesPage::initializePage() { Firewall *fw = dynamic_cast(wizard())->getFirewall(); m_dialog->iface_nz_list->clear(); QStringList labels; labels << QObject::tr("Name") << QObject::tr("Label") << QObject::tr("Address") << QObject::tr("Network Zone"); m_dialog->iface_nz_list->setHorizontalHeaderLabels(labels); NetworkZoneManager netzone_manager; netzone_manager.load( dynamic_cast(wizard())->db()); list all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator it; int row = 0; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *iface = Interface::cast(*it); m_dialog->iface_nz_list->insertRow(row); QTableWidgetItem* itm; itm = new QTableWidgetItem(iface->getName().c_str()); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 0, itm); itm = new QTableWidgetItem(iface->getLabel().c_str()); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 1, itm); QString addr_str; const InetAddr* addr = iface->getAddressPtr(); if (addr) addr_str = addr->toString().c_str(); itm = new QTableWidgetItem(addr_str); itm->setFlags(itm->flags() & ~Qt::ItemIsEditable); m_dialog->iface_nz_list->setItem(row, 2, itm); QComboBox *widget = new QComboBox(); netzone_manager.packComboBox(widget, -1); m_dialog->iface_nz_list->setCellWidget(row, 3, widget); row++; } m_dialog->iface_nz_list->resizeColumnToContents(3); } void IC_NetworkZonesPage::setNetworkZones() { Firewall *fw = dynamic_cast(wizard())->getFirewall(); if (fw == NULL) return; // read and configure network zones list all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); list::iterator it; for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it) { Interface *iface = Interface::cast(*it); string network_zone_str_id = ""; QList ltwi = m_dialog->iface_nz_list->findItems( iface->getName().c_str(), Qt::MatchExactly ); if ( ! ltwi.empty()) { QTableWidgetItem *itm2 = ltwi[0]; assert(itm2!=NULL); int row = itm2->row(); QComboBox *cb = dynamic_cast( m_dialog->iface_nz_list->cellWidget(row, 3)); assert(cb!=NULL); int network_zone_int_id = cb->itemData(cb->currentIndex(), Qt::UserRole).toInt(); if (network_zone_int_id != 0) network_zone_str_id = FWObjectDatabase::getStringId( network_zone_int_id); else network_zone_str_id = ""; } // only set network zone if it is supported and is not // empty. See #2014 if (!network_zone_str_id.empty()) iface->setStr("network_zone", network_zone_str_id); } } fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ic_platformwarningpage_q.ui0000644000175000017500000000635211733011756033360 0ustar sylvestresylvestre IC_PlatformWarningPage_q 0 0 631 710 WizardPage TextLabel true Firewall Platform: TextLabel Qt::Horizontal 442 20 QFrame::NoFrame QFrame::Raised 0 Host OS: Version: Qt::Horizontal QSizePolicy::Expanding 329 20 Add line numbers in the original file to comments in rules and objects fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ic_progresspage_q.ui0000644000175000017500000000666711733011756032023 0ustar sylvestresylvestre IC_ProgressPage_q 0 0 609 537 WizardPage Process log: 0 true Save scan log to file Qt::Horizontal QSizePolicy::Fixed 28 20 Errors: TextLabel Qt::Horizontal QSizePolicy::Fixed 40 20 Warnings: TextLabel Qt::Horizontal 40 20 logSaveButton clicked() IC_ProgressPage_q saveLog() 160 513 304 268 saveLog() fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_FileNamePage.cpp0000644000175000017500000000414711733011756031313 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWBSettings.h" #include "IC_FileNamePage.h" #include #include #include #include #include IC_FileNamePage::IC_FileNamePage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::IC_FileNamePage_q; m_dialog->setupUi(this); registerField("fileName*", m_dialog->fileName); } void IC_FileNamePage::selectFile() { QString s = QFileDialog::getOpenFileName( this, "Choose file", st->getOpenFileDir(), "All files (*)"); if (s.isEmpty()) return; st->setOpenFileDir(s); m_dialog->fileName->setText(s); } bool IC_FileNamePage::validatePage() { QString file_name = m_dialog->fileName->text(); QFileInfo f(file_name); if ( ! f.exists()) { QMessageBox::critical( NULL , "Firewall Builder", tr("File %1 does not exist").arg(file_name), QString::null,QString::null); return false; } if ( ! f.isReadable()) { QMessageBox::critical( NULL , "Firewall Builder", tr("Can not read file %1").arg(file_name), QString::null,QString::null); return false; } return true; } fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ic_firewallnamepage_q.ui0000644000175000017500000000622511733011756032613 0ustar sylvestresylvestre IC_FirewallNamePage_q 0 0 562 438 WizardPage Enter firewall object name Qt::Vertical QSizePolicy::Fixed 20 40 Firewall object name: Qt::Horizontal 199 20 Qt::Vertical QSizePolicy::Fixed 20 40 The program can use objects that already exist in the "Standard Objects" library and user defined libraries to represent addresses and services found in the configuration being imported. This helps avoid duplicate objects. true Find and use existing objects Qt::Vertical 20 387 fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_FirewallNamePage.cpp0000644000175000017500000000421411733011756032174 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "FWBSettings.h" #include "IC_FirewallNamePage.h" #include "ImportFirewallConfigurationWizard.h" #include #include #include #include #include IC_FirewallNamePage::IC_FirewallNamePage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::IC_FirewallNamePage_q; m_dialog->setupUi(this); m_dialog->deduplicateOnImport->setChecked(true); registerField("firewallName*", m_dialog->firewallName); registerField("deduplicate", m_dialog->deduplicateOnImport); } void IC_FirewallNamePage::initializePage() { QString platform = dynamic_cast(wizard())-> platform; QStringList *buf = &(dynamic_cast(wizard())->buffer); qDebug() << "platform=" << platform; if (platform == "pix" || platform == "fwsm" || platform == "iosacl") { QRegExp cisco_re("^hostname\\s+(\\S+)"); foreach(QString line, *buf) { if (cisco_re.indexIn(line) > -1) { QString name = cisco_re.cap(1).replace("\"", "").replace("'", ""); m_dialog->firewallName->setText(name); break; } } } setCommitPage(true); emit completeChanged(); } fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_FirewallNamePage.h0000644000175000017500000000227711733011756031650 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IC_FIREWALLNAMEPAGE_H #define IC_FIREWALLNAMEPAGE_H #include "ui_ic_firewallnamepage_q.h" class IC_FirewallNamePage : public QWizardPage { Q_OBJECT; Ui::IC_FirewallNamePage_q *m_dialog; public: IC_FirewallNamePage(QWidget *parent); virtual ~IC_FirewallNamePage() {} virtual void initializePage(); }; #endif // IC_FIREWALLNAMEPAGE_H fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_ProgressPage.cpp0000644000175000017500000002307411733011756031437 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "events.h" #include "FWBSettings.h" #include "IC_ProgressPage.h" #include "ImporterThread.h" #include "ImportFirewallConfigurationWizard.h" #include "fwbuilder/Library.h" #include #include #include #include using namespace std; using namespace libfwbuilder; bool fwbdebug_ic = fwbdebug; IC_ProgressPage::IC_ProgressPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::IC_ProgressPage_q; m_dialog->setupUi(this); importer = NULL; errors_count = 0; warnings_count = 0; QTextCursor cursor(m_dialog->importLog->textCursor()); normal_format = cursor.charFormat(); error_format = normal_format; error_format.setForeground(QBrush(Qt::red)); error_format.setAnchorHref("http://somewhere.com"); error_format.setAnchor(true); // weight must be between 0 and 99. Qt 4.4.1 does not seem to mind if // it is >99 (just caps it) but older versions assert error_format.setProperty(QTextFormat::FontWeight, 99); warning_format = normal_format; warning_format.setForeground(QBrush(Qt::blue)); warning_format.setProperty(QTextFormat::FontWeight, 99); warning_format.setAnchor(true); warning_format.setAnchorHref("http://somewhere.com"); } IC_ProgressPage::~IC_ProgressPage() { disconnect(this, SLOT(logLine(QString))); disconnect(this, SLOT(importerFinished())); if (importer != NULL && importer->isRunning()) importer->stop(); } int IC_ProgressPage::nextId() const { if (fwbdebug_ic) qDebug() << "IC_ProgressPage::nextId()"; ImportFirewallConfigurationWizard* wz = dynamic_cast(wizard()); QString platform = wz->platform; Firewall *fw = wz->getFirewall(); // Move on to the next page only if firewall object has been created // and the next page only makes sense for pix and fwsm if (fw && (platform == "pix" || platform == "fwsm")) return ImportFirewallConfigurationWizard::Page_NetworkZones; return -1; } bool IC_ProgressPage::validatePage() { if (fwbdebug_ic) qDebug() << "IC_ProgressPage::validatePage()" << "importer=" << importer << "isRunning=" << ((importer) ? importer->isRunning() : 0); if (importer != NULL && importer->isRunning()) return false; return true; } bool IC_ProgressPage::isComplete() const { if (importer != NULL && importer->isRunning()) return false; return true; } void IC_ProgressPage::importerDestroyed(QObject *obj) { if (fwbdebug_ic) qDebug() << "IC_ProgressPage::importerDestroyed() obj=" << obj; if (obj == importer) importer = NULL; } void IC_ProgressPage::initializePage() { if (fwbdebug_ic) qDebug() << "IC_ProgressPage::initializePage()"; if (importer != NULL && importer->isRunning()) { if (fwbdebug_ic) qDebug() << "importer is still runnig; stopping"; importer->stop(); importer->wait(); delete importer; } m_dialog->importLog->clear(); m_dialog->errors_count_display->setText("0"); m_dialog->warnings_count_display->setText("0"); ImportFirewallConfigurationWizard* wz = dynamic_cast(wizard()); QString platform = wz->platform; QString firewallName = field("firewallName").toString(); bool deduplicate = field("deduplicate").toBool(); QStringList *buffer = &(wz->buffer); QString fileName = field("fileName").toString(); Library *lib = wz->currentLib(); importer = new ImporterThread(this, lib, *buffer, platform, firewallName, fileName, deduplicate); // lists host_os_list and version_list are used-chosen host os and version. // We ask user to choose these only for PF, so for other platforms // these lists are going to be empty. if ( wz->host_os_list.size() > 0 && wz->version_list.size() > 0) { int host_os_idx = field("hostOS").toInt(); int version_idx = field("version").toInt(); bool add_standard_comments = field("addStandardComments").toBool(); importer->setUserChoiceHostOS( wz->host_os_list.at( host_os_idx )); importer->setUserChoiceVersion( wz->version_list.at( version_idx )); importer->setAddStandardCommentsFlag(add_standard_comments); } connect(importer, SIGNAL(destroyed(QObject*)), this, SLOT(importerDestroyed(QObject*))); connect(importer, SIGNAL(finished()), this, SLOT(importerFinished())); importer->start(); } void IC_ProgressPage::cleanupPage() { if (fwbdebug_ic) qDebug() << "IC_ProgressPage::cleanupPage()"; disconnect(this, SLOT(logLine(QString))); disconnect(this, SLOT(importerFinished())); if (importer != NULL && importer->isRunning()) importer->stop(); // if (importer != NULL && importer->isRunning()) importer->wait(); } void IC_ProgressPage::importerFinished() { if (fwbdebug_ic) qDebug() << "IC_ProgressPage::importerFinished()"; Firewall *fw = importer->getFirewallObject(); qApp->processEvents(); // to flush the log ImportFirewallConfigurationWizard* wz = dynamic_cast(wizard()); wz->setFirewall(fw); QString platform = wz->platform; if (fw) // fw can be NULL if import was uncussessful { QString fwName = field("firewallName").toString(); fw->setName(fwName.toUtf8().constData()); // lists host_os_list and version_list are used-chosen host os and version. // We ask user to choose these only for PF, so for other platforms // these lists are going to be empty. if ( wz->host_os_list.size() > 0 && wz->version_list.size() > 0) { int host_os_idx = field("hostOS").toInt(); int version_idx = field("version").toInt(); QString hostOS = wz->host_os_list.at( host_os_idx ).toLower(); QString version = wz->version_list.at( version_idx ).toLower(); if ( ! hostOS.isEmpty()) fw->setStr("host_OS", hostOS.toStdString()); if ( ! version.isEmpty()) fw->setStr("version", version.toStdString()); } setFinalPage(false); // this triggers call to nextId() } else { // fw == NULL // normally, wizard would have one more page, but since fw was not // created, this page should be the last setFinalPage(true); } emit completeChanged(); } void IC_ProgressPage::logLine(const QString &buf) { if (buf.isEmpty()) return; foreach(QString line, buf.trimmed().split("\n")) { QTextCharFormat format = normal_format; if (line.contains("Parser error")) { format = error_format; errors_count++; } if (line.contains("Error:")) { format = error_format; errors_count++; } if (line.contains("Parser warning")) { format = warning_format; warnings_count++; } if (line.contains("Warning:")) { format = warning_format; warnings_count++; } QString txt = line; while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r"))) txt.chop(1); if (format == error_format || format == warning_format) format.setAnchorHref(txt); QTextCursor cursor = m_dialog->importLog->textCursor(); cursor.insertBlock(); cursor.insertText(txt, format); QString s; m_dialog->errors_count_display->setText(s.setNum(errors_count)); m_dialog->warnings_count_display->setText(s.setNum(warnings_count)); } m_dialog->importLog->ensureCursorVisible(); } void IC_ProgressPage::saveLog() { QString dir; dir = st->getWDir(); if (dir.isEmpty()) dir = st->getOpenFileDir(); if (dir.isEmpty()) dir = "~"; QString s = QFileDialog::getSaveFileName( this, "Choose a file", dir, "Text file (*.txt)"); if (!s.isEmpty()) { if (s.endsWith(".txt")) { s += ".txt"; } QFile f(s); if (f.open(QIODevice::WriteOnly)) { if (fwbdebug) { qDebug("Saving crawler log to file: %d chars", m_dialog->importLog->toPlainText().length()); qDebug("--------------------------------"); } QTextStream strm(&f); QString txt = m_dialog->importLog->toPlainText(); strm << txt << endl; if (fwbdebug) { qDebug("%s",txt.toAscii().constData()); qDebug("--------------------------------"); } f.close(); } } } fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_PlatformWarningPage.h0000644000175000017500000000245611733011756032413 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IC_PLATFORMWARNINGPAGE_H #define IC_PLATFORMWARNINGPAGE_H #include "ui_ic_platformwarningpage_q.h" #include "PreImport.h" class IC_PlatformWarningPage : public QWizardPage { Q_OBJECT; Ui::IC_PlatformWarningPage_q *m_dialog; bool platformOk; public: IC_PlatformWarningPage(QWidget *parent); virtual ~IC_PlatformWarningPage() {} virtual void initializePage(); virtual bool isComplete() const; }; #endif // IC_PLATFORMWARNINGPAGE_H fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ImporterThread.cpp0000644000175000017500000001022011733011756031401 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "ImporterThread.h" #include "utils.h" #include "QThreadLogger.h" #include "IOSImporter.h" #include "IPTImporter.h" #include "PIXImporter.h" #include "PFImporter.h" #include "objectMaker.h" #include #include #include using namespace std; using namespace libfwbuilder; Logger& operator<<(Logger &logger, const QString &str) { logger << str.toUtf8().constData(); return logger; } ImporterThread::ImporterThread(QWidget *ui, FWObject *lib, const QStringList &buffer, const QString &platform, const QString &firewallName, const QString &fileName, bool deduplicate) { this->lib = lib; this->ui = ui; this->buffer = buffer; this->platform = platform; this->firewallName = firewallName; this->fileName = fileName; this->deduplicate = deduplicate; importer = NULL; stopFlag = false; addStandardComments = false; } ImporterThread::~ImporterThread() { if (fwbdebug) qDebug() << "ImporterThread::~ImporterThread()"; } void ImporterThread::setUserChoiceHostOS(const QString &s) { userChoiceHostOS = s; } void ImporterThread::setUserChoiceVersion(const QString &s) { userChoiceVersion = s; } void ImporterThread::setAddStandardCommentsFlag(bool f) { addStandardComments = f; } void ImporterThread::run() { QThreadLogger *logger = new QThreadLogger(); connect(logger, SIGNAL(lineReady(QString)), this->ui, SLOT(logLine(QString)), Qt::QueuedConnection); std::istringstream instream(buffer.join("\n").toStdString()); importer = NULL; if (platform == "iosacl") importer = new IOSImporter( lib, instream, logger, firewallName.toUtf8().constData()); if (platform == "iptables") importer = new IPTImporter( lib, instream, logger, firewallName.toUtf8().constData()); if (platform == "pix" || platform == "fwsm") importer = new PIXImporter( lib, instream, logger, firewallName.toUtf8().constData()); if (platform == "pf") importer = new PFImporter( lib, instream, logger, firewallName.toUtf8().constData()); if (importer) { if ( ! userChoiceHostOS.isEmpty()) importer->setUserChoiceHostOS(userChoiceHostOS.toStdString()); if ( ! userChoiceVersion.isEmpty()) importer->setUserChoiceVersion(userChoiceVersion.toStdString()); importer->setAddStandardCommentsFlag(addStandardComments); importer->setFileName(fileName.toUtf8().constData()); if (deduplicate) importer->prepareForDeduplication(); try { importer->run(); } catch(ImporterException &e) { *logger << e.toString() << "\n"; } catch(ObjectMakerException &e) { *logger << e.toString() << "\n"; } } else { *logger << "Can not import configuration for platform " << platform.toStdString() << "\n"; } if ( ! stopFlag) { fw = importer->finalize(); emit finished(); } deleteLater(); // mark this object for destruction on the next run of event loop } void ImporterThread::stop() { stopFlag = true; } fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ImporterThread.h0000644000175000017500000000407111733011756031055 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _IMPORTERTHREAD_H_ #define _IMPORTERTHREAD_H_ #include "Importer.h" #include #include #include #include #include namespace libfwbuilder { class FWObject; class Firewall; }; class ImporterThread : public QThread { Q_OBJECT; libfwbuilder::FWObject *lib; Importer *importer; QString fileName; QStringList buffer; QString firewallName; QString platform; bool deduplicate; QWidget *ui; libfwbuilder::Firewall *fw; bool stopFlag; QString userChoiceHostOS; QString userChoiceVersion; bool addStandardComments; public: ImporterThread(QWidget *ui, libfwbuilder::FWObject *lib, const QStringList &buffer, const QString &platform, const QString &firewallName, const QString &fileName, bool deduplicate); virtual ~ImporterThread(); void run(); void stop(); libfwbuilder::Firewall* getFirewallObject() { return fw; } void setUserChoiceHostOS(const QString &s); void setUserChoiceVersion(const QString &s); void setAddStandardCommentsFlag(bool f); signals: void finished(); }; #endif ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootfwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.cppfwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.0000644000175000017500000001051411733011756034624 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "events.h" #include "ImportFirewallConfigurationWizard.h" #include "IC_FileNamePage.h" #include "IC_FirewallNamePage.h" #include "IC_PlatformWarningPage.h" #include "IC_ProgressPage.h" #include "IC_NetworkZonesPage.h" #include "FWWindow.h" #include "ProjectPanel.h" #include "ObjConflictResolutionDialog.h" #include "fwbuilder/FWObject.h" #include "fwbuilder/Library.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Policy.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/ServiceGroup.h" #include #include using namespace std; using namespace libfwbuilder; ImportFirewallConfigurationWizard::ImportFirewallConfigurationWizard( QWidget *parent, FWObjectDatabase *_db) : QWizard(parent) { fw = NULL; db_orig = _db; db_copy = new FWObjectDatabase(); db_copy->duplicate(_db, false); current_lib = Library::cast(db_copy->findInIndex(mw->getCurrentLib()->getId())); QPixmap pm; pm.load(":/Images/fwbuilder3-72x72.png"); setPixmap(QWizard::LogoPixmap, pm); pm.load(":/Images/fwbuilder3-256x256-fade.png"); setPixmap(QWizard::BackgroundPixmap, pm); setWindowTitle(tr("Import Firewall Configuration")); setPage(Page_FileName, new IC_FileNamePage(this)); setPage(Page_Platform, new IC_PlatformWarningPage(this)); setPage(Page_FirewallName, new IC_FirewallNamePage(this)); setPage(Page_Progess, new IC_ProgressPage(this)); setPage(Page_NetworkZones, new IC_NetworkZonesPage(this)); // always show cancel button setOption(QWizard::NoCancelButton, false); QRect sg = QApplication::desktop()->screenGeometry(mw); QSize screen_size = sg.size(); #if defined(Q_OS_MACX) QSize desired_size(900, 700); #else QSize desired_size(800, 700); #endif if (desired_size.width() > screen_size.width()) desired_size.setWidth(screen_size.width()); if (desired_size.height() > screen_size.height()) desired_size.setHeight(screen_size.height()); resize(desired_size); } ImportFirewallConfigurationWizard::~ImportFirewallConfigurationWizard() { delete db_copy; } void ImportFirewallConfigurationWizard::accept() { if (fwbdebug) qDebug() << "ImportFirewallConfigurationWizard::accept()" << "fw=" << fw; if (fw != NULL && (platform == "pix" || platform == "fwsm")) dynamic_cast( page(Page_NetworkZones))->setNetworkZones(); int fw_id = -1; int policy_id = -1; if (fw) { fw_id = fw->getId(); FWObject *first_policy = fw->getFirstByType(Policy::TYPENAME); policy_id = (first_policy) ? first_policy->getId() : -1; } // merge dbcopy into db CompareObjectsDialog cod(this); db_orig->merge(db_copy, &cod); ProjectPanel *pp = mw->activeProject(); QString filename = pp->getFileName(); QCoreApplication::postEvent( mw, new reloadObjectTreeImmediatelyEvent(filename)); if (fw_id > 0) { QCoreApplication::postEvent( pp, new showObjectInTreeEvent(filename, fw_id)); QCoreApplication::postEvent( pp, new expandObjectInTreeEvent( mw->activeProject()->getFileName(), fw_id)); QCoreApplication::postEvent( mw, new openObjectInEditorEvent(filename, fw_id)); // Open first created Policy ruleset object if (policy_id > 0) QCoreApplication::postEvent( pp, new openRulesetEvent(filename, policy_id)); } QWizard::accept(); } fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ic_networkzonespage_q.ui0000644000175000017500000000644611733011756032722 0ustar sylvestresylvestre IC_NetworkZonesPage_q 0 0 580 630 WizardPage Firewall Builder uses Network Zones to determine network topology. Each firewall interface must have a Network Zone configured. The Network Zone of an interface represents the set of IP networks that would be the source IP address of traffic arriving inbound on an interface. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true If you do not set the Network Zone now you can update the Network Zone configuration after the firewall has been created by double-clicking on the network interface of the firewall object and then selecting the desired object from the Network Zone dropdown list. true :/Images/network_zone_dialog.png Qt::AlignCenter 0 150 QFrame::NoFrame QFrame::Sunken 0 true true Name Label Address Security Level fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_FileNamePage.h0000644000175000017500000000230311733011756030750 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IC_FILENAMEPAGE_H #define IC_FILENAMEPAGE_H #include "ui_ic_filenamepage_q.h" class IC_FileNamePage : public QWizardPage { Q_OBJECT; Ui::IC_FileNamePage_q *m_dialog; public: IC_FileNamePage(QWidget *parent); virtual ~IC_FileNamePage() {} virtual bool validatePage(); public slots: void selectFile(); }; #endif // IC_FILENAMEPAGE_H fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_NetworkZonesPage.h0000644000175000017500000000245211733011756031745 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef NETWORKZONESPAGE_H #define NETWORKZONESPAGE_H #include "ui_ic_networkzonespage_q.h" #include namespace Ui { class IC_NetworkZonesPage_q; } class IC_NetworkZonesPage : public QWizardPage { Q_OBJECT; Ui::IC_NetworkZonesPage_q *m_dialog; public: explicit IC_NetworkZonesPage(QWidget *parent = 0); virtual ~IC_NetworkZonesPage(); virtual void initializePage(); void setNetworkZones(); }; #endif // NETWORKZONESPAGE_H fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_PlatformWarningPage.cpp0000644000175000017500000002370311733011756032744 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "global.h" #include "IC_PlatformWarningPage.h" #include "ImportFirewallConfigurationWizard.h" #include "PreImport.h" #include "platforms.h" #include #include #include #include #include #include using namespace std; IC_PlatformWarningPage::IC_PlatformWarningPage(QWidget *parent) : QWizardPage(parent) { m_dialog = new Ui::IC_PlatformWarningPage_q; m_dialog->setupUi(this); setField("platform", ""); // user-chosen host os and version, so far we only show these for PF registerField("hostOS*", m_dialog->hostOS); registerField("version*", m_dialog->version); registerField("addStandardComments", m_dialog->addStandardComments); m_dialog->importOptionsFrame->hide(); platformOk = false; } bool IC_PlatformWarningPage::isComplete() const { if (!platformOk) return false; if (dynamic_cast(wizard())-> platform == "pf") { QString host_os = m_dialog->hostOS->currentText(); QString version = m_dialog->version->currentText(); return (! host_os.isEmpty() && ! version.isEmpty()); } else return true; } void IC_PlatformWarningPage::initializePage() { QString fileName = field("fileName").toString(); ImportFirewallConfigurationWizard* wz = dynamic_cast(wizard()); QFile cf(fileName); if (cf.open(QIODevice::ReadOnly )) { m_dialog->configFileBrowser->clear(); m_dialog->platform->setText(tr("Unknown")); QStringList *buf = &(wz->buffer); buf->clear(); QTextStream stream(&cf); while (true) { QString line = stream.readLine().trimmed(); if (line.isNull()) break; m_dialog->configFileBrowser->append(line); *buf << line; } QTextCursor cursor = m_dialog->configFileBrowser->textCursor(); cursor.setPosition(0, QTextCursor::MoveAnchor); m_dialog->configFileBrowser->setTextCursor(cursor); m_dialog->configFileBrowser->ensureCursorVisible(); bool iptables_c = false; platformOk = false; PreImport pi(buf); pi.scan(); switch (pi.getPlatform()) { case PreImport::UNKNOWN: m_dialog->platform->setText(tr("Unknown")); m_dialog->platformSpecificWarning->setText( tr("Unrecognized configuration file format, can not import.")); platformOk = false; break; case PreImport::PIX: case PreImport::FWSM: m_dialog->platform->setText(tr("Cisco PIX / CIsco ASA / Cisco FWSM")); m_dialog->platformSpecificWarning->setText( tr("Not all Cisco ASA and PIX configuration commands are " "supported by Firewall Builder. " "The following configuration components will be imported " "and can be managed using " "Firewall Builder:" "
    " "
  • Interface configurations (IP address, security level, " "name, etc.)
  • " "
  • Access lists
  • " "
  • NAT configuration
  • " "
" "The following configuration components will not be imported:" "
    " "
  • VPN
  • " "
  • Static routes
  • " "
  • Dynamic routing protocols
  • " "
  • QoS
  • " "
" )); platformOk = true; break; case PreImport::IOSACL: m_dialog->platform->setText(tr("Cisco Router IOS")); m_dialog->platformSpecificWarning->setText( tr("Not all Cisco IOS configuration commands are " "supported by Firewall Builder. The following " "configuration components will be imported and " "can be managed using Firewall Builder:" "
    " "
  • Interface configurations (IP address)
  • " "
  • Extended access lists
  • " "
" "The following configuration components will not be imported:" "
    " "
  • VPN
  • " "
  • Static routes
  • " "
  • Dynamic routing protocols (OSPF, RIP, etc.)
  • " "
  • QoS
  • " "
" )); platformOk = true; break; case PreImport::IPTABLES: m_dialog->platform->setText(tr("iptables")); m_dialog->platformSpecificWarning->setText( tr("

Firewall Builder will import all the rules defined " "in the iptables configuration. Discovered IP networks " "and IP addresses used in the iptables rules will " "automatically have objects created in the object tree. " "Each user defined chain will be created as its own Policy " "object in Firewall Builder." "

" "

" "The import process will also attempt to detect interface " "names and IP addresses based on -i and -o parameters in " "the configuration, but you may have to update the firewall " "object with additional interface information like IP addresses." "

" )); platformOk = true; break; case PreImport::IPTABLES_WITH_COUNTERS: m_dialog->platform->setText(tr("iptables")); m_dialog->platformSpecificWarning->setText( tr("This appears to be iptables configuration saved using " "command \"iptables-save -c\"" "and it includes packet counters. Please save configuration " "using command \"iptables-save\" without option \"-c\" and " "try to import it again.")); platformOk = false; break; case PreImport::PF: { m_dialog->platform->setText(tr("pf")); m_dialog->platformSpecificWarning->setText( tr("

Firewall Builder supports import PF " "configuration from a pf.conf file. Tables will be imported " "as object groups and their names will be preserved. " "Macros are expanded in place and not imported as " "objects. Import of anchors is not supported at this time." "

" "

PF version in Firewall Builder corresponds to its " "versions in OpenBSD. If you run FreeBSD 8.2 or earlier, " "choose \"3.9\"." "

" )); platformOk = true; m_dialog->version->clear(); m_dialog->hostOS->clear(); wz->host_os_list.clear(); wz->version_list.clear(); // populate host OS items using standard function from platforms.cpp // but add an empty item on top and make it current setHostOS(m_dialog->hostOS, "pf", ""); m_dialog->hostOS->insertItem(0, ""); m_dialog->hostOS->setCurrentIndex(0); for (int i=0; ihostOS->count(); ++i) { wz->host_os_list.append(m_dialog->hostOS->itemText(i)); } // populate versions using standard function from platforms.cpp // and add empty item on top list vl; getVersionsForPlatform("pf", vl); vl.push_front(QStringPair("", QObject::tr(""))); for (list::iterator i1=vl.begin(); i1!=vl.end(); i1++) { m_dialog->version->addItem( i1->second ); wz->version_list.append(i1->first); } m_dialog->importOptionsFrame->show(); break; } case PreImport::PF_REVERSE: m_dialog->platform->setText(tr("pf")); m_dialog->platformSpecificWarning->setText( tr( "

This appears to be PF configuration designed " "without use of the \"quick\" keyword, where " "the packet is evaluated by all filtering rules in " "sequential order and the last matching rule decides " "what action is to be taken. Firewall Builder uses " "different rule model, where the first matching rule " "is always final and makes the decision on the action. " "This means Firewall Builder can only import PF " "configuration written using \"quick\" " "keywords.

" )); platformOk = false; break; } wz->platform = pi.getPlatformAsString(); } emit completeChanged(); } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootfwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.hfwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ImportFirewallConfigurationWizard.0000644000175000017500000000427411733011756034632 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IMPORTFIREWALLCONFIGURATIONWIZARD_H_ #define __IMPORTFIREWALLCONFIGURATIONWIZARD_H_ #include #include namespace libfwbuilder { class FWObjectDatabase; class Firewall; class Library; }; class IC_FirewallNamePage; class IC_PlatformWarningPage; class IC_ProgressPage; class ImportFirewallConfigurationWizard : public QWizard { friend class IC_FirewallNamePage; friend class IC_PlatformWarningPage; friend class IC_ProgressPage; Q_OBJECT; QString platform; QList host_os_list; QList version_list; QStringList buffer; libfwbuilder::Firewall *fw; libfwbuilder::FWObjectDatabase *db_orig; libfwbuilder::FWObjectDatabase *db_copy; libfwbuilder::Library *current_lib; public: enum { Page_FileName, Page_Platform, Page_FirewallName, Page_Progess, Page_NetworkZones }; ImportFirewallConfigurationWizard(QWidget *parent, libfwbuilder::FWObjectDatabase *db); virtual ~ImportFirewallConfigurationWizard(); libfwbuilder::Firewall* getFirewall() { return fw; } void setFirewall(libfwbuilder::Firewall* _fw) { fw = _fw; } libfwbuilder::FWObjectDatabase* db() { return db_copy; } libfwbuilder::Library* currentLib() { return current_lib; } public slots: virtual void accept(); }; #endif fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/IC_ProgressPage.h0000644000175000017500000000325011733011756031076 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2011 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef IC_PROGRESSPAGE_H #define IC_PROGRESSPAGE_H #include "ui_ic_progresspage_q.h" #include class ImporterThread; class IC_ProgressPage : public QWizardPage { Q_OBJECT; Ui::IC_ProgressPage_q *m_dialog; QTextCharFormat normal_format; QTextCharFormat error_format; QTextCharFormat warning_format; ImporterThread *importer; int errors_count; int warnings_count; public: IC_ProgressPage(QWidget *parent); virtual ~IC_ProgressPage(); virtual void initializePage(); virtual void cleanupPage(); virtual bool validatePage(); virtual bool isComplete() const; virtual int nextId () const; public slots: void saveLog(); void logLine(const QString &line); void importerDestroyed(QObject*); void importerFinished(); }; #endif // IC_PROGRESSPAGE_H fwbuilder-5.1.0.3599/src/libgui/importFirewallConfigurationWizard/ic_filenamepage_q.ui0000644000175000017500000000744011733011756031725 0ustar sylvestresylvestre IC_FileNamePage_q 0 0 549 528 WizardPage Enter file name to import Qt::Vertical QSizePolicy::Fixed 20 40 File name: false 0 0 Browse... Qt::Vertical QSizePolicy::Fixed 337 40 Policy import tries to parse given configuration file and preserve its logic as close as possible. However, very often target firewall configuration allows for more commands, options and their combinations than importer can understand. Rules that importer could not parse exactly are colored red in the rule sets it creates. Always inspect firewall policy created by the importer and compare it with the original. Manual changes and corrections may be required. Comments in the rules that could not be parsed show fragments of the original configuration parser did not understand. Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 337 213 browse clicked() IC_FileNamePage_q selectFile() 508 25 477 55 selectFile() fwbuilder-5.1.0.3599/src/libgui/ObjectEditorDockWidget.h0000644000175000017500000000301511733011756023532 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __OBJECTEDITORDOCKWIDGET_H_ #define __OBJECTEDITORDOCKWIDGET_H_ #include "config.h" #include #include class ObjectEditor; class ObjectEditorDockWidget : public QDockWidget { Q_OBJECT ; ObjectEditor *editor; public: ObjectEditorDockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); ObjectEditorDockWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); void setupEditor(ObjectEditor *ed); virtual void closeEvent(QCloseEvent *event); public slots: void topLevelChanged(bool topLevel); }; #endif fwbuilder-5.1.0.3599/src/libgui/pixadvanceddialog_q.ui0000644000175000017500000051732611733011756023403 0ustar sylvestresylvestre pixAdvancedDialog_q Qt::WindowModal true 0 0 829 596 PIX Firewall Settings false Qt::Horizontal QSizePolicy::Expanding 20 20 OK Cancel Qt::AlignCenter false 16777215 16777215 QTabWidget::North QTabWidget::Rounded 0 Qt::ElideNone true Compiler 0 0 Output file name (if left blank, the file name is constructed of the firewall object name and extension ".fw") Qt::AlignVCenter true 32767 22 Qt::Horizontal 518 20 0 0 16777215 16777215 Policy Compiler Options Generate rules assuming the firewall is part of "Any". This makes a difference in rules that use services 'ssh' and 'telnet' since PIX uses special commands to control ssh and telnet access to the firewall machine Assume firewall is part of 'any' Shadowing happens because a rule is a superset of a subsequent rule and any packets potentially matched by the subsequent rule have already been matched by the prior rule. Detect rule shadowing in the policy Normally PIX does not support outbound ACL, however policy compiler can emulate them if this option is turned on Emulate outbound ACLs Normally PIX does not support ouotbound ACL, however policy compiler can emulate them if this option is turned on Generate outbound ACLs If the option is deactivated, compiler treats empty groups as an error and aborts processing the policy. If this option is activated, compiler removes all empty groups from all rule elements. If rule element becomes 'any' after the last empty group has been removed, the whole rule will be ignored. Use this option only if you fully understand how it works! Ignore empty groups in rules In nat rules where network zone object is used in OSrc, ODst and OSrv are 'any' and TSrc defines a global pool for the translation, replace object in OSrc with 'any' to produce PIX command "nat (interface) N 0.0.0.0 0.0.0.0" Optimize 'default nat' rules Address Translation In configurations using NAT, starting with v8.3, ASA requires using real IP addresses in the firewall policy rules. Prior to v8.3 ASA/PIX required using translated IP addresses in firewall policy rules. Firewall Builder can emulate v8.3 behavior for older versions of ASA/PIX letting you use real IP addresses in policy rules. This emulation is only needed if your firewall runs ASA software older than v8.3 and you want to use real IP addresses in firewall policy rules. true 0 0 PIX inspects packets with ACLs before it does NAT, while many other firewalls do NAT first and then apply ACLs. Policy compiler can emulate the latter behaviour if this options is turned on. Replace NAT'ted objects with their translations in policy rules 0 0 16777215 16777215 Verification of NAT rules -1 Check for duplicate nat rules Check for overlapping statics Check for overlapping global pools 0 0 Check for overlapping global pools and statics Always permit ssh access from the management workstation with this address: 0 0 200 0 32767 22 Qt::Horizontal 508 20 Qt::Vertical QSizePolicy::Expanding 20 170 Installer Built-in installer User name used to authenticate to the firewall (leave this empty if you use putty session): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 0 Alternative name or address used to communicate with the firewall (also putty session name on Windows) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 Additional command line parameters for ssh false 0 0 250 0 Additional command line parameters for scp false 0 0 250 0 Instead of running generated configuration on the firewall line by line, installer can use scp to copy the file and then "copy file running-config" command to activate it. Ssh v2 and scp servers should be configured on the firewall for this to work. This method works for PIX v7 or later and is much faster than running configuration line by line. true Copy generated configuration file to the firewall using scp File system on the firewall where configuration file should be saved if it is copied with scp. Examples: "flash:", "disk0:". Should end with a colon ":". If this input field is left blank, installer uses "flash:": true Qt::Horizontal 40 20 External install script 0 0 0 0 Policy install script (built-in installer will be used if blank): Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 250 0 0 0 0 0 Command line options for the script: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 250 0 Prolog/Epilog 6 Qt::Horizontal QSizePolicy::Expanding 40 20 Edit The following commands will be added verbatim on top of generated configuration Qt::AlignVCenter true Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn 6 Edit Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn The following commands will be added verbatim after generated configuration Qt::AlignVCenter true Timeouts Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 20 30 QFrame::NoFrame QFrame::Sunken 5 0 5 0 4 xlate Qt::AlignCenter false conn Qt::AlignCenter false udp Qt::AlignCenter false rpc Qt::AlignCenter false h323 Qt::AlignCenter false sip Qt::AlignCenter false sip&media Qt::AlignCenter false sip_media_hh unauth Qt::AlignCenter false 0 100 0 0 100 0 0 100 0 0 100 0 0 100 0 0 100 0 0 100 0 0 100 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 0 59 0 telnet Qt::AlignCenter false ssh Qt::AlignCenter false ss Qt::AlignCenter false mm Qt::AlignCenter false hh Qt::AlignCenter false 0 59 0 0 59 0 0 100 0 half-closed Qt::AlignCenter false 0 59 0 0 59 0 QFrame::HLine QFrame::Sunken Qt::Horizontal 6 Inactivity Qt::AlignCenter false Absolute Qt::AlignCenter false Set all to defaults.. Inspect Policy compiler generates 'fixup' commands for PIX/ASA v6.1-6.3 and FWSM v2.3. For v7.x and v8.x it generates 'class-map' and 'inspect' commands assigned to the 'policy-map' under either default or custom inspection classes. Qt::AlignVCenter true 12 Qt::Vertical QSizePolicy::Fixed 20 10 0 0 16777215 16777215 QTabWidget::North QTabWidget::Triangular 19 Qt::ElideNone true ctiqbe 10 10 0 0 skip enable disable Computer Telephony Interface Quick Buffer Encoding (CTIQBE) protocol inspection module that supports NAT, PAT, and bi-directional NAT. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true port: Qt::AlignCenter false pix_ctiqbe_port 1 65535 2748 Qt::Horizontal QSizePolicy::Expanding 80 20 dns 10 10 0 0 Based on this maximum-length configured by the user, the DNS fixup checks to see if the DNS packet length is within this limit. Every UDP DNS packet (request/response) undergoes the above check. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true max length: Qt::AlignCenter false pix_dns_max_length 512 65535 65535 skip enable disable Qt::Horizontal QSizePolicy::Expanding 40 20 esp ike 10 10 0 0 Enables PAT for Encapsulating Security Payload (ESP), single tunnel. Qt::AlignCenter true skip enable disable Qt::Horizontal QSizePolicy::Expanding 40 20 ftp 10 10 0 0 1 65535 21 port: Qt::AlignCenter false pix_ftp_port strict: Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable Activated support for FTP protocol and allows to change the ftp control connection port number. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true h323 h225 10 10 0 0 Specifies to use H.225, the ITU standard that governs H.225.0 session establishment and packetization, with H.323 Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true port: Qt::AlignCenter false pix_ctiqbe_port -- Qt::AlignCenter false 1 65535 1720 1 65535 1720 Qt::Horizontal QSizePolicy::Expanding 30 20 skip enable disable h323 ras 10 10 0 0 Specifies to use RAS with H.323 to enable dissimilar communication devices to communicate with each other. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 1 65535 1718 -- Qt::AlignCenter false port: Qt::AlignCenter false pix_ctiqbe_port 1 65535 1719 Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable http 10 10 0 0 The default port for HTTP is 80. Use the port option to change the HTTP port, or specify a range of HTTP ports. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true -- Qt::AlignCenter false port: Qt::AlignCenter false pix_ctiqbe_port 1 65535 80 1 65535 80 Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable icmp error 10 10 0 0 Enables NAT of ICMP error messages. This creates translations for intermediate hops based on the static or network address translation configuration on the firewall. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true skip enable disable Qt::Horizontal QSizePolicy::Expanding 40 20 ils 10 10 0 0 Provides NAT support for Microsoft NetMeeting, SiteServer, and Active Directory products that use LightWeight Directory Access Protocol (LDAP) to exchange directory information with an for Internet Locator Service (ILS) server. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 1 65535 389 port: Qt::AlignCenter false pix_ctiqbe_port 1 65535 389 -- Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable mgcp 10 10 0 0 Enables the Media Gateway Control Protocol (MGCP) fixup. Qt::AlignCenter true Gateway Port: Qt::AlignCenter false pix_ctiqbe_port Call Agent port: Qt::AlignCenter false 1 65535 2427 1 65535 2727 skip enable disable Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Horizontal QSizePolicy::Expanding 160 20 pptp 10 10 0 0 Enables Point-to-Point Tunneling Protocol (PPTP) application inspection. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 1 65535 1723 port: Qt::AlignCenter false pix_ftp_port Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable rsh 10 10 0 0 Enables inspection of RSH protocol. Qt::AlignCenter true port: Qt::AlignCenter false 1 65535 514 Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable rtsp 10 10 0 0 Lets PIX Firewall pass Real Time Streaming Protocol (RTSP) packets. RTSP is used by RealAudio, RealNetworks, Apple QuickTime 4, RealPlayer, and Cisco IP/TV connections. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 1 65535 554 port: Qt::AlignCenter false pix_ctiqbe_port Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable sip 10 10 0 0 Enable or change the port assignment for the Session Initiation Protocol (SIP) for Voice over IP TCP connections. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 1 65535 5060 1 65535 5060 port: Qt::AlignCenter false pix_ctiqbe_port -- Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable sip udp 10 10 0 0 Enable SIP-over-UDP application inspection. Qt::AlignCenter true 1 65535 5060 port: Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable skinny 10 10 0 0 Enable SCCP application inspection. SCCP protocol supports IP telephony and can coexist in an H.323 environment. An application layer ensures that all SCCP signaling and media packets can traverse the PIX Firewall and interoperate with H.323 terminals. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true -- Qt::AlignCenter false 1 65535 2000 1 65535 2000 port: Qt::AlignCenter false pix_ctiqbe_port Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable smtp 10 10 0 0 Enables the Mail Guard feature, which only lets mail servers receive the RFC 821, section 4.5.1, commands of HELO, MAIL, RCPT, DATA, RSET, NOOP, and QUIT. All other commands are translated into X's which are rejected by the internal server. Qt::AlignCenter true port: Qt::AlignCenter false pix_ctiqbe_port -- Qt::AlignCenter false 1 65535 25 1 65535 25 Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable sqlnet 10 10 0 0 Enables support for SQL*Net protocol. Qt::AlignCenter true 1 65535 1521 port: Qt::AlignCenter false pix_ctiqbe_port -- Qt::AlignCenter false 1 65535 1521 Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable tftp 10 10 0 0 Enable TFTP application inspection. Qt::AlignCenter true 1 65535 69 port: Qt::AlignCenter false pix_ctiqbe_port Qt::Horizontal QSizePolicy::Expanding 40 20 skip enable disable IP options 20 End of Options List (EOOL) skip allow drop clear 0 0 IP Options analysis is only available in PIX 8.2 and later and olnly EOOL, NOP and RTRALT options can be inspected. The firewall can allow IP packet with one of the options through or clear the option and then forward the packet, or drop the packet. Packets with any other option are always dropped. true No Operation (NOP) skip allow drop clear Router Alert (RTRALT) skip allow drop clear Qt::Horizontal QSizePolicy::Expanding 40 20 Enable all protocols false Disable all protocols false Skip all protocols false Qt::Horizontal QSizePolicy::Expanding 40 20 16777215 16777215 Qt::ScrollBarAlwaysOn Qt::ScrollBarAlwaysOn Logging Syslog host (IP address): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Syslog message queue size (messages): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 10000 0 Qt::Horizontal QSizePolicy::Expanding 40 20 syslog facility: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::Horizontal 345 20 syslog level ('logging trap'): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Qt::Horizontal 345 20 PIX Firewall Version 6.3 introduces support for EMBLEM format, which is required when using the CiscoWorks Resource Manager Essentials (RME) syslog analyzer. Use 'EMBLEM' format for syslog messages Set device id for syslog messages (v6.3 and later): use hostname Qt::Horizontal QSizePolicy::Expanding 40 20 use address of interface Qt::Horizontal 387 20 use text string The logging timestamp command requires that the clock command be set. Qt::AlignVCenter true Enable logging timestamps on syslog file Other logging destinations and levels: Internal buffer 0 22 Qt::Horizontal 488 20 Console 0 22 Qt::Horizontal 488 20 Qt::Vertical QSizePolicy::Expanding 20 40 Script 0 0 0 0 Clear all access lists then install new ones. This method may interrupt access to the firewall if you manage it remotely via IPSEC tunnel. This is the way access lists were generated in older versions of Firewall Builder for PIX. Qt::AlignVCenter true pix_acl_basic 0 0 Qt::ClickFocus Do not clear access lists and object group, just generate PIX commands for the new ones. Use this option if you have your own policy installation scripts. Qt::AlignVCenter true pix_acl_no_clear QFrame::StyledPanel QFrame::Sunken 11 Temporary access list should permit access from this address or subnet (use prefix notation to specify subnet, e.g. 192.0.2.0/24): Qt::AlignVCenter true Qt::Horizontal QSizePolicy::Expanding 110 20 0 0 200 0 120 32767 Qt::Horizontal QSizePolicy::Expanding 120 20 0 0 "Safety net" method: First, create temporary access list to permit connections from the management subnet specified below to the firewall and assign it to outside interface. This temporary ACL helps maintain session between management station and the firewall while access lists are reloaded in case connection comes over IPSEC tunnel. Then clear permanent lists, recreate them and assign to interfaces. This method ensures that remote access to the firewall is maintained without interruption at a cost of slightly larger configuration. Qt::AlignVCenter true pix_acl_substitution Qt::Vertical 20 137 Script (additional) Compiler can generate PIX configuration without commands that configures interfaces, timeouts and inspectors. These parts of configuration change rarely so it makes no sense to execute the same commands again and again. In addition, runnig the same commands on configuration reload cause errors. Use this option to generate shortened configuration to avoid errors and make update faster. true Generate only access-list, access-group, telnet, ssh, nat, global and static commands 0 0 12 Insert comments into generated PIX configuration file Comment the code Use ACL remarks to relate ACL commands and policy rules in the GUI Use ACL remarks Group PIX commands in the script so that similar commands appear next to each other, just like PIX does it when you use 'show config' Group similar commands together Use manual ACL commit on FWSM Qt::Vertical 20 40 PIX Options 20 20 12 20 20 QFrame::NoFrame QFrame::Plain 12 Actively reset inbound TCP connections with RST Actively reset inbound TCP connections with RST on outside interface Force each TCP connection to linger in a shortened TIME&WAIT Alt+W Enable the IP Frag Guard feature (deprecated in v6.3 and later). Enable TCP resource control for AAA Authentication Proxy Specify that when an incoming packet does a route lookup, the incoming interface is used to determine which interface the packet should go to, and which is the next hop (deprecated in v6.3 and later). QFrame::HLine QFrame::Sunken Qt::Horizontal Disable inbound embedded DNS A record fixups Disable outbound DNS A record replies QFrame::HLine QFrame::Sunken Qt::Horizontal The following parameters are used for all NAT rules: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false maximum number of simultaneous TCP and UDP connections Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false max_conns 64 16777215 Specifies the maximum number of simultaneous TCP and UDP connections for the entire subnet. The default is 0, which means unlimited connections. (Idle connections are closed after the idle timeout specified by the timeout conn command.) 0 100000 0 Qt::Horizontal 254 20 maximum number of embryonic connections per host Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false emb_limit 64 16777215 Specifies the maximum number of embryonic connections per host. An embryonic connection is a connection request that has not finished the necessary handshake between source and destination. Set a small value for slower systems, and a higher value for faster systems. The default is 0, which means unlimited embryonic connections. 0 100000 0 (The default for both parameters is 0, which means unlimited number of connections.) Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Qt::Vertical QSizePolicy::Expanding 20 20 IPv6 20 The order in which ipv4 and ipv6 rules should be generated: Qt::Horizontal 40 20 IPv4 before IPv6 IPv6 before IPv4 Qt::Vertical 20 40 tabWidget outputFileName pix_assume_fw_part_of_any pix_emulate_out_acl pix_optimize_default_nat pix_check_shadowing pix_check_duplicate_nat pix_check_overlapping_statics mgmt_ssh mgmt_addr user altAddress sshArgs scpArgs use_scp installScriptArgs pix_prolog_script edit_prolog_button pix_epilog_script edit_epilog_button xlate_hh xlate_mm xlate_ss conn_hh conn_mm conn_ss udp_hh udp_mm udp_ss rpc_hh rpc_mm rpc_ss h323_hh h323_mm h323_ss sip_hh sip_mm sip_ss sip_media_hh sip_media_mm sip_media_ss half_closed_hh half_closed_mm half_closed_ss uauth_hh uauth_mm uauth_ss telnet_timeout ssh_timeout uauth_abs uauth_inact defaultTimeoutsButton fixup_notebook pix_ctiqbe_switch pix_ctiqbe_port pix_dns_switch pix_dns_max_length pix_espike_switch pix_ftp_switch pix_ftp_port pix_ftp_strict pix_h323h225_switch pix_h323h225_port1 pix_h323h225_port2 pix_h323ras_switch pix_h323ras_port1 pix_h323ras_port2 pix_http_switch pix_http_port1 pix_http_port2 pix_icmperror_switch pix_ils_switch pix_ils_port1 pix_ils_port2 pix_mgcp_switch pix_mgcp_gateway_port pix_mgcp_call_agent_port pix_pptp_switch pix_pptp_port pix_rsh_switch pix_rsh_port1 pix_rtsp_switch pix_rtsp_port pix_sip_switch pix_sip_port1 pix_sip_port2 pix_sipudp_switch pix_sip_udp_port1 pix_skinny_switch pix_skinny_port1 pix_skinny_port2 pix_smtp_switch pix_smtp_port1 pix_smtp_port2 pix_sqlnet_switch pix_sqlnet_port1 pix_sqlnet_port2 pix_tftp_switch pix_tftp_port enableAllFixupsButton disableAllFixupsButton skipAllFixupsButton pix_generated_fixup syslog_host syslog_queue_size syslog_facility logging_trap_level emblem_log_format syslog_device_id_hostname syslog_device_id_interface syslog_device_id_interface_val syslog_device_id_string syslog_device_id_string_val logging_timestamp logging_buffered logging_buffered_level logging_console logging_console_level pix_acl_basic pix_acl_no_clear pix_acl_substitution pix_acl_temp_addr resetinbound resetoutside connection_timewait fragguard floodguard route_dnat nodnsalias_inbound nodnsalias_outbound max_conns emb_limit ipv4before_2 ok_button cancel_button textLabel3 ok_button clicked() pixAdvancedDialog_q accept() 20 20 20 20 cancel_button clicked() pixAdvancedDialog_q reject() 20 20 20 20 edit_prolog_button clicked() pixAdvancedDialog_q editProlog() 20 20 20 20 edit_epilog_button clicked() pixAdvancedDialog_q editEpilog() 20 20 20 20 defaultTimeoutsButton clicked() pixAdvancedDialog_q defaultTimeouts() 20 20 20 20 enableAllFixupsButton clicked() pixAdvancedDialog_q enableAllFixups() 20 20 20 20 disableAllFixupsButton clicked() pixAdvancedDialog_q disableAllFixups() 20 20 20 20 skipAllFixupsButton clicked() pixAdvancedDialog_q skipAllFixups() 20 20 20 20 pix_acl_basic clicked() pixAdvancedDialog_q scriptACLModeChanged() 20 20 20 20 pix_acl_substitution clicked() pixAdvancedDialog_q scriptACLModeChanged() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/IPv6Dialog.h0000644000175000017500000000274711733011756021127 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __IPV6DIALOG_H_ #define __IPV6DIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class QDns; class ProjectPanel; class IPv6Dialog : public BaseObjectDialog { Q_OBJECT; bool showNetmask; bool dnsBusy; //QDns *lookup; Ui::IPv6Dialog_q *m_dialog; public: IPv6Dialog(QWidget *parent); ~IPv6Dialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void DNSlookup(); }; #endif // IPV6DIALOG_H fwbuilder-5.1.0.3599/src/libgui/DiscoveryDruid.h0000644000175000017500000002144111733011756022152 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2005 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __DISCOVERYDRUID_H_ #define __DISCOVERYDRUID_H_ #include "config.h" #include #include #include #include #include "fwbuilder/Interface.h" #include "fwbuilder/InterfaceData.h" #include "fwbuilder/dns.h" #include "fwbuilder/snmp.h" #include "fwbuilder/InetAddr.h" #include "fwbuilder/Logger.h" #include "FilterDialog.h" #include "fakeWizard.h" #include #include #include #include using namespace std; using namespace libfwbuilder; class Importer; #define IMPORT_IOS 0 #define IMPORT_PIX 1 #define IMPORT_IPT 2 // ---------------- OBJECT DESCRIPTOR ------------------ // class ObjectDescriptor { public: bool have_snmpd ; string descr, contact, location, sysname ; string type; bool isSelected; map interfaces ; string MAC_addr ; libfwbuilder::HostEnt dns_info ; libfwbuilder::InetAddr addr ; libfwbuilder::InetAddr netmask ; ObjectDescriptor(); ObjectDescriptor(const ObjectDescriptor& od); std::string toString() { ostringstream ost; ost << sysname; //if(interfaces.size()>1) // ost <<" [" <(ProgressEv)) {value=0;} int value; }; class DoneEvent : public QEvent { public: DoneEvent():QEvent(static_cast(DoneEv)) {} }; // ---------------- WORKER THREAD ------------------ // typedef enum {BT_NONE,BT_HOSTS,BT_DNS,BT_SNMP,BT_IMPORT} BackgroundTask; class WorkerThread : public QThread { QWidget *Widget; protected: QString last_error; public: Logger *Log; void setProgress(int p); void done(); void setTargetWidget(QWidget *w) {Widget=w;} QString getError(); WorkerThread(); virtual ~WorkerThread(); virtual void run(); }; class HostsFileImport : public WorkerThread { QString file_name; public: vector hosts; HostsFileImport(const QString &f); virtual void run(); }; class ConfigImport : public WorkerThread { std::string *buffer; Importer *imp; std::string platform; std::string fwname; public: ConfigImport(std::string *buffer, const std::string &platform, const std::string &fwname); virtual ~ConfigImport(); virtual void run(); Importer* getImporterObject() { return imp; } }; // ---------------- DISCOVERY DRUID ------------------ // class DiscoveryDruid : public QDialog, public FakeWizard { Q_OBJECT; private: WorkerThread *thread; BackgroundTask current_task; Filter * flt_obj; Filter * flt_last; Filter * flt_net; FilterDialog * flt_obj_d; FilterDialog * flt_last_d; FilterDialog * flt_net_d; Ui::DiscoveryDruid_q * m_dialog; QButtonGroup * dm_method; QTextCharFormat normal_format; QTextCharFormat error_format; QTextCharFormat warning_format; bool init; bool isSeedHostOK; bool isSNMPInclNetOK; bool userIsTyping; //QueueLogger * logger; Logger * logger; BackgroundOp *bop; QHostInfo *dns; int FromPage; QMap Objects; QMap Networks; QMap NameServers; vector include_networks; QTimer* timer; QTimer* prg_timer; int unProg; QProgressBar *unBar; QLabel *errMessage; QString HostName; libfwbuilder::Firewall *discovered_fw; void setDiscoveryMethod_file(); void setDiscoveryMethod_DNS(); void setDiscoveryMethod_SNMP(); void setDiscoveryMethod_Import(); void startBackgroundProcess(); void DataFromCrawler(); int monitorOperation(); void restore(); void save(); QString guessOS(const string &sysDescr); void rearrangeInterfaces( const QString &os, std::map &interfaces, std::list &interface_tree); FWObject* addInterface(libfwbuilder::FWObject *parent, libfwbuilder::InterfaceData *in, bool skip_ip_address_check); void addToLog(const QString &buf); std::string selectedPlatform(); public: DiscoveryDruid(QWidget *parent, bool start_with_import=false); virtual ~DiscoveryDruid(); void fillListOfObjects(); void fillTypeChangingList(); void fillObjects(); void fillNetworks(); void loadDataFromFile(); void loadDataFromImporter(); void loadDataFromCrawler(); void loadDataFromDNS(); void fillListOfNetworks(); void fillNetworkZones(); void createRealObjects(); // void stripObjects(); void getNameServers(); InetAddr getNS(); InetAddr getSeedHostAddress(); bool isInetAddr(const QString s); QString testInetAddr(const QString s); virtual void customEvent(QEvent *event); public slots: virtual void changedSelected( const int &page ); virtual void changedDiscoveryMethod(int); virtual void browseHostsFile(); virtual void browseForImport(); virtual void saveScanLog(); virtual void startHostsScan(); virtual void startDNSScan(); virtual void startSNMPScan(); virtual void startConfigImport(); virtual void importPlatformChanged(int cp); virtual void changedDomainName(); virtual void changedHostsFileName(); virtual void changedSNMPOptions(); virtual void changedSeedHost(); virtual void changedInclNet(); virtual void stopBackgroundProcess(); virtual void addNetwork(); virtual void removeNetwork(); virtual void setNetworkFilter(); virtual void removeNetworkFilter(); virtual void setLastFilter(); virtual void removeLastFilter(); virtual void addObject(); virtual void removeObject(); virtual void setObjectFilter(); virtual void removeObjectFilter(); virtual void updateLog(); virtual void updatePrg(); virtual void checkHostName(); virtual void checkSNMPCommunity(); virtual void selectAllResNets(); virtual void selectAllNets(); virtual void selectAllResObjs(); virtual void selectAllObjs(); virtual void selectAllLast(); virtual void unselectAllLast(); virtual void changeTargetObject(const QString &buf); virtual void typeAddress(); virtual void typeHost(); virtual void typeFirewall(); virtual void dnsFinish(QHostInfo); virtual void changedNameServer(); virtual void typedCustomNS(); // virtual void createObjects(const QString &buf); virtual void nextClicked(); virtual void backClicked(); virtual void cancelClicked(); virtual void finishClicked(); virtual void objNameChanged(QString name); signals: }; #define CHOOSE_METHOD_PAGE 0 #define READ_HOSTS_FILE_PAGE 1 #define IMPORT_CONFIG_PAGE 2 #define IMPORT_DNS_ZONE_PAGE 3 #define NAME_SERVER_PAGE 4 #define SNMP_DISCOVERY_PAGE 5 #define NETWORK_SCAN_OPTIONS_PAGE 6 #define SNMP_PARAMETERS_PAGE 7 #define BACKGROUND_PROCESS_PAGE 8 #define CHOOSE_NETWORKS_PAGE 9 #define CHOOSE_OBJECTS_PAGE 10 #define ADJUST_OBJECT_TYPES_PAGE 11 #define TARGET_LIB_PAGE 12 #define CREATE_OBJECTS_PAGE 13 #define NETWORK_ZONES_PAGE 14 const int WIZARD_PAGES = 15; const bool WIZARD_FILE_PAGES[] = {1,1,0,0,0,0,0,0,1,0,1,0,1,1,0}; const bool WIZARD_DNS_PAGES[] = {1,0,0,1,1,0,0,0,1,0,1,0,1,1,0}; const bool WIZARD_SNMP_PAGES[] = {1,0,0,0,0,1,1,1,1,1,1,1,1,1,0}; const bool WIZARD_IMPORT_PAGES[] = {1,0,1,0,0,0,0,0,1,0,0,0,0,0,1}; #endif fwbuilder-5.1.0.3599/src/libgui/solarisadvanceddialog_q.ui0000644000175000017500000003246611733011756024254 0ustar sylvestresylvestre solarisAdvancedDialog_q Qt::WindowModal 0 0 388 285 Solaris: advanced settings 11 6 6 0 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true 0 Options 6 6 Ignore ICMP redirects Qt::AlignCenter false No change On Off Forward directed broadcasts Qt::AlignCenter false Respond to echo broadcast Qt::AlignCenter false No change On Off No change On Off Packet forwarding Qt::AlignCenter false No change On Off No change On Off Forward source routed packets Qt::AlignCenter false Qt::Horizontal QSizePolicy::Fixed 151 20 Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 20 40 Path 6 6 200 0 ipf: Qt::AlignCenter false ipnat: Qt::AlignCenter false 200 0 Specify directory path and a file name for the following utilities on the OS your firewall machine is running. Leave these empty if you want to use default values. Qt::AlignCenter true Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Vertical QSizePolicy::Expanding 20 40 tabWidget solaris_ip_forward solaris_ip_forward_src_routed solaris_ip_forward_directed_broadcasts solaris_ip_ignore_redirect solaris_ip_respond_to_echo_broadcast solaris_path_ipf solaris_path_ipnat buttonOk buttonCancel buttonOk clicked() solarisAdvancedDialog_q accept() 20 20 20 20 buttonCancel clicked() solarisAdvancedDialog_q reject() 20 20 20 20 fwbuilder-5.1.0.3599/src/libgui/RuleSetView.cpp0000644000175000017500000030617711733011756022000 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003-2009 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA This module has been completely rewritten by yalovoy@gmail.com in 2009 */ #include "config.h" #include "global.h" #include "utils.h" #include "platforms.h" #include "RuleSetView.h" #include "RuleSetModel.h" #include "ColDesc.h" #include "FWObjectSelectionModel.h" #include "RuleSetViewDelegate.h" #include "FWBSettings.h" #include "FWObjectClipboard.h" #include "FWObjectPropertiesFactory.h" #include "FWObjectDrag.h" #include "FWWindow.h" #include "FWBTree.h" #include "FWCmdRule.h" #include "ProjectPanel.h" #include "FindObjectWidget.h" #include "events.h" #include "DialogFactory.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Policy.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Network.h" #include #include #include #include #include #include #include #include using namespace libfwbuilder; using namespace std; RuleSetView::RuleSetView(ProjectPanel *project, QWidget *parent):QTreeView(parent) { if (fwbdebug) qDebug("RuleSetView::RuleSetView"); this->project = project; fwosm = new FWObjectSelectionModel(); setContextMenuPolicy(Qt::CustomContextMenu); setSelectionMode(QAbstractItemView::ContiguousSelection); setSelectionBehavior(QAbstractItemView::SelectRows); setAllColumnsShowFocus(false); setDragEnabled(true); setAcceptDrops(true); setDragDropMode(QAbstractItemView::DragDrop); header()->setResizeMode(QHeaderView::Interactive); header()->setMovable(false); connect (this, SIGNAL (customContextMenuRequested(const QPoint&)), this, SLOT (showContextMenu(const QPoint&))); connect (this, SIGNAL( doubleClicked(const QModelIndex&) ), this, SLOT( itemDoubleClicked(const QModelIndex&) ) ); connect (this, SIGNAL (collapsed(QModelIndex)), this, SLOT (saveCollapsedGroups())); connect (this, SIGNAL (expanded(QModelIndex)), this, SLOT (saveCollapsedGroups())); connect (this, SIGNAL (collapsed(QModelIndex)), this, SLOT (updateAllColumnsSize())); connect (this, SIGNAL (expanded(QModelIndex)), this, SLOT (updateAllColumnsSize())); initActions(); popup_menu = new QMenu(this); this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); this->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); this->header()->setStretchLastSection(false); } RuleSetView::~RuleSetView() { if (fwbdebug) qDebug("RuleSetView::~RuleSetView"); delete fwosm; delete compileRuleAction; delete moveRuleUpAction; delete moveRuleDownAction; delete removeFromGroupAction; delete newGroupAction; delete insertRuleAction; delete addRuleAfterCurrentAction; delete addToGroupAboveAction; delete addToGroupBelowAction; delete removeRuleAction; delete copyRuleAction; delete cutRuleAction; delete pasteRuleAboveAction; delete pasteRuleBelowAction; delete disableRuleAction; delete enableRuleAction; delete setColorEmptyAction; delete setColorRedAction; delete setColorBlueAction; delete setColorOrangeAction; delete setColorPurpleAction; delete setColorGrayAction; delete setColorYellowAction; delete setColorGreenAction; } void RuleSetView::init() { if (fwbdebug) qDebug("RuleSetView::init"); /* * #2474 : I want standard Qt classes to paint column 0 and area * to the left of the clumn 0 because that is where [+] and [-] * appear when we have rule groups. However I want to avoid using * the same standard color used to highlight currently selected * object in rules. To do that, I reset QPalette::Highlight color * in the palette used to draw everything in the rules. I am going * to have to reset palette back to the standard color in * RuleSetViewDelegate when I paint individual cells. */ QPalette updated_palette = palette(); updated_palette.setColor(QPalette::Highlight, QColor("silver")); setPalette(updated_palette); setUpdatesEnabled(false); QTime t; t.start(); configureGroups(); if (fwbdebug) qDebug("RuleSetView configureGroups: %d ms", t.restart()); restoreCollapsedGroups(); if (fwbdebug) qDebug("RuleSetView restoreCollapsedGroups: %d ms", t.restart()); resizeColumns(); if (fwbdebug) qDebug("RuleSetView resizeColumns: %d ms", t.restart()); setUpdatesEnabled(true); } void RuleSetView::configureGroups() { RuleSetModel* md = ((RuleSetModel*)model()); QList list; md->getGroups(list); QModelIndex parent; foreach(QModelIndex index, list) { setFirstColumnSpanned(index.row(), parent, true); } } void RuleSetView::initActions() { // Compile rule compileRuleAction = createAction(tr("Compile Rule"), SLOT(compileCurrentRule()), QKeySequence(Qt::Key_X)); addAction(compileRuleAction ); compileRuleAction->setVisible(true); compileRuleAction->setEnabled(true); // Move rule up moveRuleUpAction = createAction(tr("Move Rule Up"), SLOT( moveRuleUp()), QKeySequence(Qt::CTRL + Qt::Key_PageUp)); addAction(moveRuleUpAction ); // Move rule down moveRuleDownAction = createAction(tr("Move Rule Down"), SLOT( moveRuleDown()), QKeySequence(Qt::CTRL + Qt::Key_PageDown)); addAction(moveRuleDownAction ); // Remove rules from group removeFromGroupAction = createAction(tr("Remove From the Group"), SLOT( removeFromGroup())); // New group newGroupAction = createAction(tr("New Group"), SLOT( newGroup())); // Insert Rule insertRuleAction = createAction( tr("Insert New Rule"), SLOT( insertRule() ) ); addRuleAfterCurrentAction = createAction(tr("Add New Rule Below"), SLOT( addRuleAfterCurrent() )); addToGroupAboveAction = createAction("addToGroupAboveAction", SLOT( addToGroupAbove() )); addToGroupBelowAction = createAction("addToGroupBelowAction", SLOT( addToGroupBelow() )); // Remove rule removeRuleAction = createAction(tr("Remove Rule"), SLOT( removeRule())); // Clipboard operations copyRuleAction = createAction(tr("Copy Rule"), SLOT( copyRule() )); cutRuleAction = createAction(tr("Cut Rule"), SLOT( cutRule() )); pasteRuleAboveAction = createAction(tr("Paste Rule Above"), SLOT( pasteRuleAbove() )); pasteRuleBelowAction = createAction(tr("Paste Rule Below"), SLOT( pasteRuleBelow() )); //Disable or Enable rules disableRuleAction = createAction(tr("Enable Rule"), SLOT( disableRule() )); enableRuleAction = createAction(tr("Disable Rule"), SLOT( enableRule() )); //Change color actions QPixmap pcolor(16,16); setColorEmptyAction = createAction(tr("No Color"), SLOT( setColorEmpty() )); pcolor.fill(QColor(255,255,255)); setColorEmptyAction->setIcon(QIcon(pcolor)); setColorEmptyAction->setVisible(true); setColorRedAction = createAction(st->getLabelText(FWBSettings::RED), SLOT( setColorRed() )); pcolor.fill(st->getLabelColor(FWBSettings::RED)); setColorRedAction->setIcon(QIcon(pcolor)); setColorRedAction->setVisible(true); setColorBlueAction = createAction(st->getLabelText(FWBSettings::BLUE), SLOT( setColorBlue() )); pcolor.fill(st->getLabelColor(FWBSettings::BLUE)); setColorBlueAction->setIcon(QIcon(pcolor)); setColorBlueAction->setVisible(true); setColorOrangeAction = createAction(st->getLabelText(FWBSettings::ORANGE), SLOT( setColorOrange() )); pcolor.fill(st->getLabelColor(FWBSettings::ORANGE)); setColorOrangeAction->setIcon(QIcon(pcolor)); setColorOrangeAction->setVisible(true); setColorPurpleAction = createAction(st->getLabelText(FWBSettings::PURPLE), SLOT( setColorPurple() )); pcolor.fill(st->getLabelColor(FWBSettings::PURPLE)); setColorPurpleAction->setIcon(QIcon(pcolor)); setColorPurpleAction->setVisible(true); setColorGrayAction = createAction(st->getLabelText(FWBSettings::GRAY), SLOT( setColorGray() )); pcolor.fill(st->getLabelColor(FWBSettings::GRAY)); setColorGrayAction->setIcon(QIcon(pcolor)); setColorGrayAction->setVisible(true); setColorYellowAction = createAction(st->getLabelText(FWBSettings::YELLOW), SLOT( setColorYellow() )); pcolor.fill(st->getLabelColor(FWBSettings::YELLOW)); setColorYellowAction->setIcon(QIcon(pcolor)); setColorYellowAction->setVisible(true); setColorGreenAction = createAction(st->getLabelText(FWBSettings::GREEN), SLOT( setColorGreen() )); pcolor.fill(st->getLabelColor(FWBSettings::GREEN)); setColorGreenAction->setIcon(QIcon(pcolor)); setColorGreenAction->setVisible(true); } QAction* RuleSetView::createAction(QString label, const char* member, const QKeySequence &shortcut) { QAction* action = new QAction(label, this); action->setShortcut(shortcut); connect (action, SIGNAL(triggered()), this, member); action->setEnabled(false); action->setVisible(false); return action; } RuleSetView* RuleSetView::getRuleSetViewByType(ProjectPanel *project, RuleSet *ruleset, QWidget *parent) { if (fwbdebug) qDebug("RuleSetView::getRuleSetViewByType"); if (Policy::isA(ruleset)) return new PolicyView(project, Policy::cast(ruleset), parent); if (NAT::isA(ruleset)) return new NATView(project, NAT::cast(ruleset), parent); if (Routing::isA(ruleset)) return new RoutingView(project, Routing::cast(ruleset), parent); return NULL; } void RuleSetView::makeCurrentRuleVisible() { scrollTo( currentIndex(), QAbstractItemView::PositionAtCenter); } void RuleSetView::selectRE(QModelIndex index) { if (fwbdebug) qDebug() << "RuleSetView::selectRE(QModelIndex index)" << index; if (fwosm->index != index) { fwosm->selectedObject = NULL; fwosm->index = index; setCurrentIndex(index); scrollTo( index, QAbstractItemView::PositionAtCenter); } } void RuleSetView::selectRE(libfwbuilder::FWReference *ref) { if (fwbdebug) qDebug() << "RuleSetView::selectRE(libfwbuilder::FWReference *ref)"; /* need to find row and column this object is in and show it */ RuleElement *re = RuleElement::cast(ref->getParent()); assert(re); selectRE(re, ref->getPointer()); } void RuleSetView::selectRE(libfwbuilder::Rule *rule, int col) { if (fwbdebug) qDebug() << "RuleSetView::selectRE(libfwbuilder::Rule *rule, int col)"; RuleSetModel* md = ((RuleSetModel*)model()); selectRE(md->index(rule, col)); } void RuleSetView::selectRE(libfwbuilder::Rule *rule, ColDesc::ColumnType type) { if (fwbdebug) qDebug() << "RuleSetView::selectRE(libfwbuilder::Rule *rule, ColDesc::ColumnType type)"; RuleSetModel* md = ((RuleSetModel*)model()); int col = md->columnByType(type); selectRE(rule, col); } void RuleSetView::selectRE(libfwbuilder::RuleElement *re, libfwbuilder::FWObject *obj) { if (fwbdebug) qDebug() << "RuleSetView::selectRE(libfwbuilder::RuleElement *re, libfwbuilder::FWObject *obj)"; Rule *rule = Rule::cast(re->getParent()); assert(rule!=NULL); RuleSetModel* md = ((RuleSetModel*)model()); QModelIndex index = md->index(rule, re); selectRE(index); setCurrentIndex(index); fwosm->setSelected(obj, index); } int RuleSetView::getColByType(ColDesc::ColumnType type) const { RuleSetModel* md = ((RuleSetModel*)model()); return md->columnByType(type); } void RuleSetView::mousePressEvent( QMouseEvent* ev ) { //TODO: provide custom implementation of QTreeView::mousePressEvent( ev ); for column != 0 QTreeView::mousePressEvent( ev ); const QModelIndex index = currentIndex();//indexAt (ev->pos()); if (index.column() == 0) { fwosm->setSelected(NULL, index); return; } FWObject *object = getObject(ev->pos(), index); // if (fwbdebug) qDebug("RuleSetView::contentsMousePressEvent " // "obj=%s row=%d col=%d", // (object)?object->getName().c_str():"NULL", index.row(), index.column()); if (object) { selectObject(object, index); startingDrag = (fwosm->index.row()==index.row() && fwosm->index.column()==index.column() && fwosm->selectedObject==object); } else { fwosm->setSelected(NULL, index); } } void RuleSetView::mouseReleaseEvent( QMouseEvent* ev ) { //if (fwbdebug) qDebug() << "RuleSetView::mouseReleaseEvent"; QTreeView::mouseReleaseEvent(ev); const QModelIndex index = indexAt (ev->pos()); if (index.column() == 0) return; RuleSetModel* md = ((RuleSetModel*)model()); if (md->getRuleSet()->size()!=0) { ev->accept(); }; // if (md->getRuleSet()->size()!=0 && // mw->isEditorVisible() && !switchObjectInEditor( currentIndex()) ) // { // ev->accept(); // }; } /* * Why using persistent QMenu object for the popup menu: * * If user hits Cmd-Q on Mac while popup menu is open, we get a * crash. The problem is that when close event propagates and * eventually closes the popup menu, RuleSetView::showContextMenu() * tries to delete QMenu object and we get the following error and * crash: "QObject: Do not delete object, 'qt_scrollarea_viewport', * during its event handler!". Instead of making sure we do not delete * the object in some circumstances, or find a way to delete it * safely, it is much easier to just avoid having to delete it at all. */ void RuleSetView::showContextMenu(const QPoint& pos) { popup_menu->clear(); const QModelIndex index = indexAt ( pos); if (index.isValid()) { int column = index.column(); RuleNode* node = static_cast(index.internalPointer()); if (node->type == RuleNode::Group) { addGroupMenuItemsToContextMenu(popup_menu); } else { compileRuleAction->setEnabled(!node->rule->isDisabled()); if (column < 1) { addRowMenuItemsToMenu(popup_menu); } else { addColumnRelatedMenu(popup_menu, index, node, pos); } addCommonRowItemsToContextMenu(popup_menu); } } else { addGenericMenuItemsToContextMenu(popup_menu); } popup_menu->exec(mapToGlobal(pos)); // delete menu; } void RuleSetView::addCommonRowItemsToContextMenu(QMenu *menu) const { menu->addSeparator(); menu->addAction(compileRuleAction); } void RuleSetView::mouseMoveEvent( QMouseEvent* ev ) { if (startingDrag) { QDrag* drag = dragObject(); if (drag) drag->start(Qt::CopyAction | Qt::MoveAction); //just start dragging startingDrag = false; return; } QTreeView::mouseMoveEvent(ev); } QDrag* RuleSetView::dragObject() { FWObject *obj = fwosm->selectedObject; if (obj==NULL) return NULL; // TODO: use FWBTree::setObjectIcon() QString icn = (":/Icons/" + obj->getTypeName() + "/icon").c_str(); list dragobj; dragobj.push_back(obj); FWObjectDrag *drag = new FWObjectDrag(dragobj, this, NULL); QPixmap pm = LoadPixmap(icn); drag->setPixmap( pm ); return drag; } void RuleSetView::addColumnRelatedMenu(QMenu *menu, const QModelIndex &index, RuleNode* node, const QPoint& pos) { RuleSetModel* md = ((RuleSetModel*)model()); ColDesc colDesc = index.data(Qt::UserRole).value(); switch (colDesc.type) { case ColDesc::Action: { Firewall *f = md->getFirewall(); if (f == NULL) break; string platform = f->getStr("platform"); QString action_name; if (NATRule::isA(node->rule)) { if (Resources::isTargetActionSupported(platform,"Translate")) { action_name = getActionNameForPlatform( f, NATRule::getActionAsString(NATRule::Translate)); menu->addAction( QIcon(LoadPixmap(":/Icons/Continue/icon")), action_name, this, SLOT( changeActionToTranslate() )); } if (Resources::isTargetActionSupported(platform,"Branch")) { action_name = getActionNameForPlatform( f, NATRule::getActionAsString(NATRule::Branch)); menu->addAction( QIcon(LoadPixmap(":/Icons/NATBranch/icon")), action_name, this, SLOT( changeActionToNATBranch() )); } } else { if (Resources::isTargetActionSupported(platform,"Accept")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Accept)); menu->addAction( QIcon(LoadPixmap(":/Icons/Accept/icon")), action_name, this, SLOT( changeActionToAccept() )); } if (Resources::isTargetActionSupported(platform,"Deny")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Deny)); menu->addAction( QIcon(LoadPixmap(":/Icons/Deny/icon")), action_name, this, SLOT( changeActionToDeny() )); } if (Resources::isTargetActionSupported(platform,"Reject")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Reject)); menu->addAction( QIcon(LoadPixmap(":/Icons/Reject/icon")), action_name, this, SLOT( changeActionToReject() )); } if (Resources::isTargetActionSupported(platform,"Accounting")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Accounting)); menu->addAction( QIcon(LoadPixmap(":/Icons/Accounting/icon")), action_name, this, SLOT( changeActionToAccounting() )); } if (Resources::isTargetActionSupported(platform,"Pipe")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Pipe)); menu->addAction( QIcon(LoadPixmap(":/Icons/Pipe/icon")), action_name, this, SLOT( changeActionToPipe() )); } /* * #2367 if (Resources::isTargetActionSupported(platform,"Tag")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Tag)); menu->addAction( QIcon(LoadPixmap(":/Icons/Tag/icon")), action_name, this, SLOT( changeActionToTag() )); } if (Resources::isTargetActionSupported(platform,"Classify")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Classify)); menu->addAction( QIcon(LoadPixmap(":/Icons/Classify/icon")), action_name, this, SLOT( changeActionToClassify() )); } if (Resources::isTargetActionSupported(platform,"Route")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Route)); menu->addAction( QIcon(LoadPixmap(":/Icons/Route/icon")), action_name, this, SLOT( changeActionToRoute() )); } */ if (Resources::isTargetActionSupported(platform,"Custom")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Custom)); menu->addAction( QIcon(LoadPixmap(":/Icons/Custom/icon")), action_name, this, SLOT( changeActionToCustom() )); } if (Resources::isTargetActionSupported(platform,"Branch")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Branch)); menu->addAction( QIcon(LoadPixmap(":/Icons/Branch/icon")), action_name, this, SLOT( changeActionToBranch() )); } if (Resources::isTargetActionSupported(platform,"Continue")) { action_name = getActionNameForPlatform( f, PolicyRule::getActionAsString(PolicyRule::Continue)); menu->addAction( QIcon(LoadPixmap(":/Icons/Continue/icon")), action_name, this, SLOT( changeActionToContinue() )); } } menu->addSeparator (); QAction *paramID; paramID = menu->addAction( tr("Parameters"), this, SLOT( editSelected() )); PolicyRule *rule = PolicyRule::cast( node->rule ); if (rule!=NULL) { string act = rule->getActionAsString(); if (Resources::getActionEditor(platform,act)=="None") paramID->setEnabled(false); } break; } case ColDesc::Direction: menu->addAction( QIcon(LoadPixmap(":/Icons/Inbound/icon")), tr("Inbound"), this, SLOT( changeDirectionToIn() )); menu->addAction( QIcon(LoadPixmap(":/Icons/Outbound/icon")), tr("Outbound"), this, SLOT( changeDirectionToOut() )); menu->addAction( QIcon(LoadPixmap(":/Icons/Both/icon")), tr("Both"), this, SLOT( changeDirectionToBoth() )); break; case ColDesc::Comment: menu->addAction( tr("Edit") , this , SLOT( editSelected() ) ); break; case ColDesc::Metric: menu->addAction( tr("Edit") , this , SLOT( editSelected() ) ); break; case ColDesc::Options: menu->addAction( QIcon(LoadPixmap(":/Icons/Options/icon")), tr("Rule Options"), this, SLOT( editSelected() )); if (md->getRuleSet()->getTypeName() == Policy::TYPENAME) { menu->addAction( QIcon(LoadPixmap(":/Icons/Log/icon")), tr("Logging On"), this, SLOT( changeLogToOn() )); menu->addAction( QIcon(LoadPixmap(":/Icons/Blank/icon")), tr("Logging Off"), this, SLOT( changeLogToOff() )); } break; case ColDesc::Object: case ColDesc::Time: { RuleElement *re = getRE(index); if (re==NULL) return; FWObject *object = getObject(pos, index); QAction *editID = menu->addAction( tr("Edit") , this , SLOT( editSelected() ) ); menu->addSeparator(); QAction *copyID = menu->addAction( tr("Copy") , this , SLOT( copySelectedObject() ) ); QAction *cutID = menu->addAction( tr("Cut") , this , SLOT( cutSelectedObject() ) ); QAction *pasteID = menu->addAction( tr("Paste") , this , SLOT( pasteObject() ) ); QAction *delID =menu->addAction( tr("Delete") , this , SLOT( deleteSelectedObject() ) ); menu->addSeparator(); QAction *fndID = menu->addAction( tr("Where used") , this , SLOT( findWhereUsedSlot())); QAction *revID = menu->addAction( tr("Reveal in tree") ,this , SLOT( revealObjectInTree() ) ); menu->addSeparator(); QAction *negID = menu->addAction( tr("Negate") , this , SLOT( negateRE() ) ); if (object == NULL || re->isAny()) editID->setEnabled(false); copyID->setEnabled(!re->isAny()); cutID->setEnabled(!re->isAny()); delID->setEnabled(!re->isAny()); // see #1976 do not allow pasting object that has been deleted // also disable "Paste" if object in the clipboard is a rule FWObject *obj_in_clipboard = FWObjectClipboard::obj_clipboard->getObject(); pasteID->setEnabled(true); if (obj_in_clipboard == NULL) pasteID->setEnabled(false); else { if (Rule::cast(obj_in_clipboard) != NULL) pasteID->setEnabled(false); FWObject *lib = obj_in_clipboard->getLibrary(); if (lib != NULL && lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) pasteID->setEnabled(false); } string cap_name; if (Policy::cast(md->getRuleSet())!=NULL) cap_name="negation_in_policy"; if (NAT::cast(md->getRuleSet())!=NULL) cap_name="negation_in_nat"; Firewall *f = md->getFirewall(); if (f == NULL) break; bool supports_neg=false; try { supports_neg = Resources::getTargetCapabilityBool( f->getStr("platform"), cap_name); } catch (FWException &ex) { QMessageBox::critical( NULL , "Firewall Builder", ex.toString().c_str(), QString::null,QString::null); } negID->setEnabled(supports_neg && !re->isAny()); fndID->setEnabled(!re->isAny()); revID->setEnabled(!re->isAny()); break; } default : menu->addAction( tr("Edit") , this , SLOT( editRE() ) ); } } void RuleSetView::addGenericMenuItemsToContextMenu(QMenu *menu) const { if (((RuleSetModel*)model())->isEmpty()) menu->addAction(tr("Insert New Rule"), this, SLOT( insertRule() )); else { menu->addAction(tr("Add New Rule on Top"), this, SLOT( insertNewRuleOnTop())); menu->addAction(tr("Add New Rule at the Bottom"), this, SLOT( insertNewRuleAtBottom())); } menu->addSeparator(); menu->addAction(tr("Paste Rule"), this, SLOT( pasteRuleBelow())); } void RuleSetView::addGroupMenuItemsToContextMenu(QMenu *menu) const { menu->addAction( tr("Rename group"), this, SLOT( renameGroup() )); menu->addSeparator(); addChangeColorSubmenu(menu); } void RuleSetView::addChangeColorSubmenu(QMenu *menu) const { QMenu *subcolor = menu->addMenu(tr("Change color") ); subcolor->addAction(setColorEmptyAction); subcolor->addAction(setColorRedAction); subcolor->addAction(setColorOrangeAction); subcolor->addAction(setColorYellowAction); subcolor->addAction(setColorGreenAction); subcolor->addAction(setColorBlueAction); subcolor->addAction(setColorPurpleAction); subcolor->addAction(setColorGrayAction); } void RuleSetView::addRowMenuItemsToMenu(QMenu *menu) const { if (fwbdebug) qDebug() << "RuleSetView::addRowMenuItemsToMenu menu=" << menu; menu->addAction(removeFromGroupAction); menu->addAction(newGroupAction); menu->addAction(addToGroupAboveAction); menu->addAction(addToGroupBelowAction); menu->addSeparator(); addChangeColorSubmenu(menu); menu->addSeparator(); menu->addAction( insertRuleAction ); menu->addAction( addRuleAfterCurrentAction ); menu->addAction( removeRuleAction ); menu->addSeparator(); menu->addAction( moveRuleUpAction); menu->addAction( moveRuleDownAction); menu->addSeparator(); menu->addAction(copyRuleAction); menu->addAction(cutRuleAction); menu->addAction(pasteRuleAboveAction); menu->addAction(pasteRuleBelowAction); menu->addSeparator(); menu->addAction(enableRuleAction); menu->addAction(disableRuleAction); } void RuleSetView::itemDoubleClicked(const QModelIndex& index) { if (!index.isValid()) return; if (index.row() < 0) return; if (index.column() == 0) return; // double click on rule number does nothing // ColDesc colDesc = index.data(Qt::UserRole).value(); // if (fwosm->selectedObject!=NULL) // { // QCoreApplication::postEvent( // mw, // new showObjectInTreeEvent( // project->getFileName(), fwosm->selectedObject->getId())); // } editSelected(index); } void RuleSetView::editSelected(const QModelIndex& index) { ColDesc colDesc = index.data(Qt::UserRole).value(); FWObject *obj = fwosm->selectedObject; // see #2454 -- we do not want to switch object tree view to the standard // objects library when user double clicks on object "any" if (obj != NULL && (obj->getId() != FWObjectDatabase::ANY_ADDRESS_ID && obj->getId() != FWObjectDatabase::ANY_SERVICE_ID && obj->getId() != FWObjectDatabase::ANY_INTERVAL_ID)) { QCoreApplication::postEvent( mw, new showObjectInTreeEvent( project->getFileName(), fwosm->selectedObject->getId())); } if (!mw->isEditorVisible()) mw->showEditor(); switchObjectInEditor(index); } void RuleSetView::editSelected() { editSelected(currentIndex()); } bool RuleSetView::switchObjectInEditor(const QModelIndex& index, bool validate) { RuleSetModel* md = ((RuleSetModel*)model()); if (!isTreeReadWrite(this,md->getRuleSet())) return false; if ( index.column()<=0 || index.row()==-1 ) return false; FWObject *object = NULL; ObjectEditor::OptType operation = ObjectEditor::optNone; /* * We need to know WHAT we are going to edit 1. Object 2. OptType * Object == null, OptType = optNone => blank * Object == Rule, OptType = optNone => Rule Options * Object == Rule, OptType != optNone => Virtual Object (Action, Comment ...) * Object != Rule, OptType = optNone => Regular Object Editor Then we compare our object 'obj' and OptType with what we already have in ObjectEditor/ If they are the same, then we do nothing, otherwise we open obj in the Object Editor */ ColDesc colDesc = index.data(Qt::UserRole).value(); RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) return false; Rule *rule = node->rule; switch (colDesc.type) { case ColDesc::Comment: object = rule; operation = ObjectEditor::optComment; break; case ColDesc::Metric: object = rule; operation = ObjectEditor::optMetric; break; case ColDesc::Direction: break; case ColDesc::Action: { //PolicyRule *prule = PolicyRule::cast( rule ); object = rule; operation = ObjectEditor::optAction; break; } case ColDesc::Options: { /* both policy and routing rules have options. so cast to * Rule here. */ assert(rule); object = rule; operation = ObjectEditor::optNone; break; } default: { if ( fwosm->selectedObject!=NULL) { object = fwosm->selectedObject; break; } } } if (!mw->isEditorVisible()) mw->showEditor(); if (!mw->requestEditorOwnership(this, object, operation, validate)) return false; if (object==mw->getOpenedEditor() && operation==mw->getOpenedOptEditor()) { if (fwbdebug) qDebug("RuleSetView::switchObjectInEditor same object is already opened in the editor"); return true; } if (object == NULL) { QCoreApplication::postEvent(mw, new clearEditorPanelEvent()); //mw->blankEditor(); } else if (operation==ObjectEditor::optNone) { QCoreApplication::postEvent( mw, new openObjectInEditorEvent( mw->activeProject()->getFileName(), object->getId())); //mw->openEditor(object); } else if(Rule::cast(object)!=NULL) { QCoreApplication::postEvent( mw, new openOptObjectInEditorEvent(project->getFileName(), object->getId(), operation)); //mw->openOptEditor(object, operation); } return true; } QModelIndexList RuleSetView::getSelectedRows() const { QModelIndexList selection = selectedIndexes(); QModelIndexList res; for (QList::iterator i = selection.begin(); i != selection.end(); ++i) { if(!(*i).column()) { res.append(*i); } } return res; } void RuleSetView::setSelectedRows(const QModelIndex firstIndex, const QModelIndex lastIndex) { fwosm->reset(); selectionModel()->clear(); setCurrentIndex(firstIndex); selectionModel()->select(QItemSelection(firstIndex, lastIndex), QItemSelectionModel::Rows | QItemSelectionModel::Select); fwosm->setSelected(0, firstIndex); } void RuleSetView::removeRule() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; mw->findObjectWidget->reset(); QModelIndexList selection = getSelectedRows(); if (!selection.isEmpty()) { QMap > itemsInGroups; QList rulesToDelete; // Sort rules to the corresponding groups foreach (QModelIndex index, selection) { if (!index.isValid() || !md->isIndexRule(index)) continue; if (mw->isEditorVisible() && mw->getOpenedEditor()==md->nodeFromIndex(index)->rule) mw->closeEditor(); QModelIndex parent = index.parent(); if (parent.isValid()) { itemsInGroups[parent] << index.row(); } RuleNode* node = md->nodeFromIndex(index); if (node->type == RuleNode::Rule) rulesToDelete << node->rule; } //Special case - all rows are inside one group (excluding the //first item of the group) if (itemsInGroups.size() == 1 && itemsInGroups[itemsInGroups.keys().first()].size() == rulesToDelete.size()) { bool containsFirstRow = false; foreach(int row, itemsInGroups[itemsInGroups.keys().first()]) { if (0 == row) { containsFirstRow = true; break; } } if (!containsFirstRow) { FWCmdRuleDeleteFromGroup* cmd = new FWCmdRuleDeleteFromGroup(project, md->getRuleSet(), rulesToDelete); project->undoStack->push(cmd); return; } } FWCmdMacro* macro = new FWCmdMacro("delete rules"); // Remove items from groups QList groups = itemsInGroups.keys(); if (!groups.isEmpty()) { foreach(QModelIndex group, groups) { qSort(itemsInGroups[group]); Rule* first = md->nodeFromIndex(md->index(itemsInGroups[group].at(0), 0, group))->rule; Rule* last = md->nodeFromIndex(md->index(itemsInGroups[group].at(itemsInGroups[group].size() - 1), 0, group))->rule; QString groupName = md->nodeFromIndex(group)->name; FWCmdRuleRemoveFromGroup* cmd = new FWCmdRuleRemoveFromGroup(project, md->getRuleSet(), first, last, groupName, macro); } } // Remove rows if (!rulesToDelete.isEmpty()) { FWCmdRuleDelete* cmd = new FWCmdRuleDelete(project, md->getRuleSet(), rulesToDelete, macro); } project->undoStack->push(macro); } } void RuleSetView::renameGroup() { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; QModelIndexList selection = getSelectedRows(); foreach(QModelIndex index, selection) { if (!index.isValid()) continue; RuleNode *group = md->nodeFromIndex(index); // Process only groups. Skip all rules. if(group->type != RuleNode::Group) continue; QString oldGroupName = group->name; bool ok = false; QString newGroupName = QInputDialog::getText( this, "Rename group", tr("Enter group name:"), QLineEdit::Normal, oldGroupName, &ok); if (ok && !newGroupName.isEmpty() && newGroupName != oldGroupName) { project->undoStack->push(new FWCmdRuleRenameGroup(project, md->getRuleSet(), oldGroupName, newGroupName)); } } } void RuleSetView::setRuleColor(const QString &c) { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndexList selection = getSelectedRows(); // Current behaviour is following: // if we have only groups selected then recolor groups // if there are rules in selection then selected groups will be ignored and only selected rules will be recolored QList rules; QList groups; foreach (QModelIndex index, selection) { if (md->isIndexRule(index)) { rules << index; } else { groups << index; } } QList ruleList; if (rules.isEmpty()) { // Let's recolor groups - there are no rules in the selection foreach(QModelIndex grpIndex, groups) { foreach(RuleNode* node, md->nodeFromIndex(grpIndex)->children) { ruleList.append(node->rule); } } } else { // There are rules in selection, so recolor them foreach (QModelIndex index, rules) { ruleList.append(md->nodeFromIndex(index)->rule); } } project->undoStack->push(new FWCmdRuleColor(project, md->getRuleSet(), ruleList, c)); } void RuleSetView::setColorEmpty() { setRuleColor(""); } void RuleSetView::setColorRed() { setRuleColor(st->getLabelColor(FWBSettings::RED)); } void RuleSetView::setColorBlue() { setRuleColor(st->getLabelColor(FWBSettings::BLUE)); } void RuleSetView::setColorOrange() { setRuleColor(st->getLabelColor(FWBSettings::ORANGE)); } void RuleSetView::setColorPurple() { setRuleColor(st->getLabelColor(FWBSettings::PURPLE)); } void RuleSetView::setColorGray() { setRuleColor(st->getLabelColor(FWBSettings::GRAY)); } void RuleSetView::setColorYellow() { setRuleColor(st->getLabelColor(FWBSettings::YELLOW)); } void RuleSetView::setColorGreen() { setRuleColor(st->getLabelColor(FWBSettings::GREEN)); } void RuleSetView::enableRule() { setEnabledRow(true); } void RuleSetView::disableRule() { setEnabledRow(false); } void RuleSetView::setEnabledRow(bool flag) { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; QModelIndexList selection = getSelectedRows(); if (!selection.isEmpty()) { foreach (QModelIndex index, selection) { if (!index.isValid()) continue; RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) continue; Rule* rule = node->rule; if (!rule->isDisabled() == flag) continue; FWCmdRuleChange* cmd = new FWCmdRuleChange( project, md->getRuleSet(), rule, (flag)?tr("Enable rule"):tr("Disable rule")); Rule* newState = Rule::cast(cmd->getNewState()); if (flag) newState->enable(); else newState->disable(); project->undoStack->push(cmd); } } updateSelectionSensitiveActions(); } void RuleSetView::newGroup() { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; QModelIndexList selection = getSelectedRows(); // we cannot perform this action if the selection contains groups or rules assigned to groups if (!selection.isEmpty() && isOnlyTopLevelRules(selection)) { bool ok; QString newGroupName = QInputDialog::getText( this, "Rename group", tr("Enter group name:"), QLineEdit::Normal, tr("New Group"), &ok); if (ok && !newGroupName.isEmpty()) { FWCmdRuleNewGroup* cmd = new FWCmdRuleNewGroup( project, md->getRuleSet(), md->nodeFromIndex(selection.first())->rule, md->nodeFromIndex(selection.last())->rule, newGroupName); project->undoStack->push(cmd); } } } void RuleSetView::addToGroupAbove() { addToGroup(true); } void RuleSetView::addToGroupBelow() { addToGroup(false); } void RuleSetView::addToGroup(bool isAbove) { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; QModelIndexList selection = getSelectedRows(); // we cannot perform this action if the selection contains groups or rules assigned to groups if (!selection.isEmpty() && isOnlyTopLevelRules(selection)) { FWCmdRuleAddToGroup* cmd = new FWCmdRuleAddToGroup( project, md->getRuleSet(), md->nodeFromIndex(selection.first())->rule, md->nodeFromIndex(selection.last())->rule, isAbove); project->undoStack->push(cmd); } } void RuleSetView::moveRuleUp() { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; QModelIndexList selection = getSelectedRows(); // we cannot perform this action if the selection contains groups or rules assigned to groups if (!selection.isEmpty() && isOneLevelRules(selection)) { RuleSetModelIterator it = md->begin(); QModelIndex top = it.index(); if (top.parent() == selection.first().parent() && top.row() == selection.first().row()) return; FWCmdRuleMove* cmd = new FWCmdRuleMove(project, md->getRuleSet(), md->nodeFromIndex(selection.first())->rule->getId(), md->nodeFromIndex(selection.last())->rule->getId()); project->undoStack->push(cmd); } } void RuleSetView::moveRuleDown() { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; QModelIndexList selection = getSelectedRows(); // we cannot perform this action if the selection contains groups or rules assigned to groups if (!selection.isEmpty() && isOneLevelRules(selection)) { RuleSetModelIterator it = md->end(); --it; QModelIndex bottom = it.index(); if (bottom.parent() == selection.last().parent() && bottom.row() == selection.last().row()) return; FWCmdRuleMove* cmd = new FWCmdRuleMove(project, md->getRuleSet(), md->nodeFromIndex(selection.first())->rule->getId(), md->nodeFromIndex(selection.last())->rule->getId(), false); project->undoStack->push(cmd); } } bool RuleSetView::isOnlyTopLevelRules(const QModelIndexList &list) const { foreach (QModelIndex index, list) { if (!index.isValid()) return false; RuleNode* node = static_cast(index.internalPointer()); if (node==0 || node->type != RuleNode::Rule || node->parent->type != RuleNode::Root) return false; } return true; } bool RuleSetView::isOneLevelRules(const QModelIndexList &list) { RuleNode *parent = 0; foreach (QModelIndex index, list) { if (!index.isValid()) return false; RuleNode* node = static_cast(index.internalPointer()); if (node==0 || node->type != RuleNode::Rule) return false; if (parent == 0) parent = node->parent; else if (parent != node->parent) return false; } return true; } void RuleSetView::copyRule() { RuleSetModel* md = ((RuleSetModel*)model()); QModelIndexList selection = getSelectedRows(); if ( !selection.isEmpty() ) { FWObjectClipboard::obj_clipboard->clear(); foreach (QModelIndex index, selection) { RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) continue; FWObject *rule = node->rule; if (rule) FWObjectClipboard::obj_clipboard->add( rule, project ); } } } void RuleSetView::cutRule() { copyRule(); removeRule(); } void RuleSetView::pasteRuleAbove() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndexList selection = getSelectedRows(); QModelIndex index = currentIndex(); vector >::iterator i; for (i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i) { Rule *rule = Rule::cast(createInsertTemplate(i->second, i->first)); if (!rule || !md->checkRuleType(rule)) continue; project->undoStack->push( new FWCmdRuleInsert( project, md->getRuleSet(), md->getRulePosition(index), false, rule)); } } void RuleSetView::pasteRuleBelow() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndex index = currentIndex(); vector >::reverse_iterator i; for (i= FWObjectClipboard::obj_clipboard->rbegin(); i!=FWObjectClipboard::obj_clipboard->rend(); ++i) { Rule *rule = Rule::cast(createInsertTemplate(i->second, i->first)); if (!rule || !md->checkRuleType(rule)) continue; project->undoStack->push( new FWCmdRuleInsert( project, md->getRuleSet(), md->getRulePosition(index), true, rule)); } } FWObject* RuleSetView::createInsertTemplate(ProjectPanel* proj_p, int id) { RuleSetModel* md = ((RuleSetModel*)model()); FWObject* co = proj_p->db()->findInIndex(id); FWObject* t = 0; if (!Rule::cast(co)) return 0; if (proj_p!=project) { // rule is being copied from another project file map map_ids; t = project->db()->recursivelyCopySubtree(md->getRuleSet(), co, map_ids); // Note that FWObjectDatabase::recursivelyCopySubtree adds // a copy it creates to the end of the list of children of // the object passed as its first arg., which is in this // case ruleset. This works only if we paste rule at the // bottom of ruleset, otherwise need to move them to the // proper location. t->ref(); md->getRuleSet()->remove(t); project->m_panel->om->reload(); } else { t = proj_p->db()->create(co->getTypeName()); t->duplicate(co); } if (fwbdebug) { cerr << "rulesrt->getRoot()=" << md->getRuleSet()->getRoot() << " " << "proj_p->db()=" << proj_p->db() << " " << "proj_p file=" << proj_p->getFileName().toStdString() << " " << "id=" << id << " " << "co=" << co << " " << "co->getRoot()=" << co->getRoot() << endl; cerr << "Validating database index" << endl; proj_p->db()->getRoot()->validateIndex(); } return t; } bool RuleSetView::canChange(RuleSetModel* md) { if(!isTreeReadWrite(this,md->getRuleSet())) return false; if (md->getFirewall()==NULL) return false; return true; } void RuleSetView::insertRule(QModelIndex index, bool isAfter) { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; project->undoStack->push( new FWCmdRuleInsert( project, md->getRuleSet(), md->getRulePosition(index), isAfter)); } void RuleSetView::insertRule() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndexList selection = getSelectedRows(); QModelIndex index; if (!selection.isEmpty()) { index = selection.first(); } insertRule(index); } void RuleSetView::addRuleAfterCurrent() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndexList selection = getSelectedRows(); if (selection.isEmpty()) { insertRule(QModelIndex()); } else { QModelIndex lastSelectedIndex = selection.last(); insertRule(lastSelectedIndex, true); } } void RuleSetView::insertNewRuleOnTop() { insertRule(QModelIndex()); } void RuleSetView::insertNewRuleAtBottom() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; RuleSetModelIterator it = md->end(); --it; Rule* posRule = md->nodeFromIndex(it.index())->rule; project->undoStack->push( new FWCmdRuleInsert( project, md->getRuleSet(), posRule->getPosition(), true)); } void RuleSetView::removeFromGroup() { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; if (md->getFirewall()==NULL) return; QModelIndexList selection = getSelectedRows(); QMap > itemsInGroups; // Get all rules sorted by groups foreach (QModelIndex index, selection) { if (!index.isValid() || !md->isIndexRule(index)) continue; QModelIndex parent = index.parent(); if (parent.isValid()) { itemsInGroups[parent] << index.row(); } } // Remove groups from the end to the begin QList groups = itemsInGroups.keys(); qSort(groups); QListIterator i(groups); i.toBack(); while (i.hasPrevious()) { QModelIndex group = i.previous(); qSort(itemsInGroups[group]); QModelIndex first = md->index(itemsInGroups[group].first(), 0, group); QModelIndex last = md->index(itemsInGroups[group].last(), 0, group); FWCmdRuleRemoveFromGroup *cmd = new FWCmdRuleRemoveFromGroup(project, md->getRuleSet(), md->nodeFromIndex(first)->rule, md->nodeFromIndex(last)->rule, md->nodeFromIndex(group)->name); project->undoStack->push(cmd); // md->removeFromGroup(group, itemsInGroups[group].first(), itemsInGroups[group].last()); } // QCoreApplication::postEvent( // mw, new dataModifiedEvent(project->getFileName(), md->getRuleSet()->getId())); } FWObject *RuleSetView::getObject(const QPoint &pos, const QModelIndex &index) { if (!index.isValid() || index.column() == 0) return 0; RuleNode* node = static_cast(index.internalPointer()); if (node->type == RuleNode::Group) return 0; QRect vrect = visualRect(index); if (!vrect.isValid()) return 0; const int relativeY = pos.y() - vrect.top(); if (relativeY < 0 || relativeY > vrect.height()) return 0; const int itemHeight = RuleSetViewDelegate::getItemHeight(); RuleElement *re = getRE(index); if (re==NULL) return 0; int oy=0; FWObject *o1=NULL; FWObject *obj=NULL; FWObject *prev=NULL; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { o1= *i; if (FWReference::cast(o1)!=NULL) o1=FWReference::cast(o1)->getPointer(); if (relativeY>oy && relativeY(index.internalPointer()); if (node->type == RuleNode::Group) return 0; RuleElement *re = getRE(index); if (re==NULL) return 0; int n=1; FWObject *o1=NULL; FWObject *obj=NULL; FWObject *prev=NULL; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { o1= *i; if (FWReference::cast(o1)!=NULL) o1=FWReference::cast(o1)->getPointer(); if (n == number) { obj=o1; break; } n++; prev=o1; } if (obj==NULL) obj=prev; return obj; } int RuleSetView::getObjectNumber(FWObject *object, const QModelIndex &index) { if (!index.isValid() || index.column() == 0) return 0; RuleNode* node = static_cast(index.internalPointer()); if (node->type == RuleNode::Group) return 0; RuleElement *re = getRE(index); if (re==NULL) return 0; int n=1; FWObject *o1=NULL; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { o1= *i; if (FWReference::cast(o1)!=NULL) o1=FWReference::cast(o1)->getPointer(); if (object == o1) break; n++; } return n; } void RuleSetView::selectObject(int position, int column, int number) { RuleSetModel* md = ((RuleSetModel*)model()); QModelIndex index = md->indexForPosition(position); if (index.isValid()) { index = md->index(index.row(), column, index.parent()); FWObject* obj = getObject(number, index); selectObject(obj, index); } else { unselect(); } } void RuleSetView::selectObject(FWObject *object, const QModelIndex &index) { fwosm->setSelected(object, index); setCurrentIndex(index); viewport()->update((viewport()->rect())); } void RuleSetView::changeDirectionToIn() { changeDitection( PolicyRule::Inbound ); } void RuleSetView::changeDirectionToOut() { changeDitection( PolicyRule::Outbound ); } void RuleSetView::changeDirectionToBoth() { changeDitection( PolicyRule::Both ); } void RuleSetView::changeDitection(PolicyRule::Direction dir) { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; if (md->getFirewall()==NULL) return; QModelIndex index = currentIndex(); if (!index.isValid()) return; RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) return; PolicyRule *rule = PolicyRule::cast( node->rule ); PolicyRule::Direction old_dir=rule->getDirection(); if (dir!=old_dir) { FWCmdRuleChange* cmd = new FWCmdRuleChange( project, md->getRuleSet(), rule, tr("Change direction")); PolicyRule* newState = PolicyRule::cast(cmd->getNewState()); newState->setDirection( dir ); project->undoStack->push(cmd); } } void RuleSetView::changeAction(int act) { if (fwbdebug) qDebug() << "RuleSetView::changeAction act=" << act; RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; if (md->getFirewall()==NULL) return; QModelIndex index = currentIndex(); if (!index.isValid()) return; RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) return; std::auto_ptr cmd( new FWCmdRuleChange(project, md->getRuleSet(), node->rule, tr("Change action"))); Rule* newRule = dynamic_cast(cmd->getNewState()); if (PolicyRule::isA(newRule)) { PolicyRule *rule = PolicyRule::cast( newRule ); FWOptions *ruleopt = rule->getOptionsObject(); PolicyRule::Action old_act=rule->getAction(); if (fwbdebug) qDebug() << "PolicyRule old_action=" << old_act; if (act!=old_act) { rule->setAction(PolicyRule::Action(act)); ruleopt->setBool("stateless", getStatelessFlagForAction(rule)); project->undoStack->push(cmd.release()); } } else if (NATRule::isA(newRule)) { NATRule *rule = NATRule::cast( newRule ); NATRule::NATAction old_act = rule->getAction(); if (fwbdebug) qDebug() << "NATRule old_action=" << old_act << "NATRule::Translate=" << NATRule::Translate << "NATRule::Branch=" << NATRule::Branch; if (act!=old_act) { rule->setAction(NATRule::NATAction(act)); project->undoStack->push(cmd.release()); } } // See #957. It makes sense to open action in the edtor only // if this action has some parameters to edit. FWObject *fw = node->rule; while (fw && Firewall::cast(fw)==NULL) fw = fw->getParent(); if (fw) { QString editor = DialogFactory::getActionDialogPageName( Firewall::cast(fw), node->rule).c_str(); editor = editor.toLower(); // open action in the editor if the editor is already visible // or if it is not, only if there is something to edit in this // action if (mw->isEditorVisible() || (!editor.isEmpty() && editor != "none")) QCoreApplication::postEvent( mw, new openOptObjectInEditorEvent( project->getFileName(), node->rule->getId(), ObjectEditor::optAction)); } } void RuleSetView::changeActionToAccept() { changeAction( PolicyRule::Accept ); } void RuleSetView::changeActionToDeny() { changeAction( PolicyRule::Deny ); } void RuleSetView::changeActionToReject() { changeAction( PolicyRule::Reject ); } void RuleSetView::changeActionToAccounting() { changeAction( PolicyRule::Accounting ); } void RuleSetView::changeActionToPipe() { changeAction( PolicyRule::Pipe ); } void RuleSetView::changeActionToCustom() { changeAction( PolicyRule::Custom ); } void RuleSetView::changeActionToContinue() { changeAction( PolicyRule::Continue ); } void RuleSetView::changeActionToBranch() { changeAction( PolicyRule::Branch ); } void RuleSetView::changeActionToTranslate() { changeAction( NATRule::Translate ); } void RuleSetView::changeActionToNATBranch() { changeAction( NATRule::Branch ); } void RuleSetView::changeLogToOn() { changeLogging(true); } void RuleSetView::changeLogToOff() { changeLogging(false); } void RuleSetView::changeLogging(bool flag) { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndex index = currentIndex(); if (!index.isValid()) return; RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) return; PolicyRule *rule = PolicyRule::cast( node->rule ); if (rule->getLogging() == flag) return; FWCmdRuleChange* cmd = new FWCmdRuleChange( project, md->getRuleSet(), rule, tr("Change logging")); PolicyRule* newState = PolicyRule::cast(cmd->getNewState()); newState->setLogging( flag ); project->undoStack->push(cmd); } void RuleSetView::negateRE() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndex index = currentIndex(); if (!index.isValid()) return; RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) return; RuleElement *re = getRE(index); if (re==NULL) return; int position = Rule::cast(re->getParent())->getPosition(); int column = index.column(); project->undoStack->push( new FWCmdRuleNegateRE(project, md->getRuleSet(), re, position, column)); } void RuleSetView::revealObjectInTree() { FWObject* selectedObject = fwosm->selectedObject; if (selectedObject!=NULL) QCoreApplication::postEvent( mw, new showObjectInTreeEvent(selectedObject->getRoot()->getFileName().c_str(), selectedObject->getId())); } void RuleSetView::findWhereUsedSlot() { if ( fwosm->selectedObject!=NULL) mw->findWhereUsed(fwosm->selectedObject, project); } void RuleSetView::deleteSelectedObject() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndex index = currentIndex(); if (!index.isValid()) return; if ( fwosm->selectedObject!=NULL) { deleteObject(index, fwosm->selectedObject, tr("delete ")+QString::fromUtf8(fwosm->selectedObject->getName().c_str())); } } void RuleSetView::copySelectedObject() { if ( fwosm->selectedObject!=NULL) { FWObjectClipboard::obj_clipboard->clear(); FWObject *obj = fwosm->selectedObject; FWObjectClipboard::obj_clipboard->add(obj, project ); mw->showStatusBarMessage( tr("Copy object '%1' to clipboard'").arg( QString::fromUtf8(obj->getName().c_str()))); } } void RuleSetView::cutSelectedObject() { RuleSetModel* md = ((RuleSetModel*)model()); if(!isTreeReadWrite(this,md->getRuleSet())) return; if ( fwosm->selectedObject!=NULL) { QModelIndex index = currentIndex(); FWObjectClipboard::obj_clipboard->clear(); FWObjectClipboard::obj_clipboard->add( fwosm->selectedObject, project ); deleteObject(index, fwosm->selectedObject, tr("cut ") + QString::fromUtf8(fwosm->selectedObject->getName().c_str())); } } void RuleSetView::pasteObject() { RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; vector >::iterator i; for (i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i) { ProjectPanel *proj_p = i->second; FWObject *co= proj_p->db()->findInIndex(i->first); if (Rule::cast(co)!=NULL) pasteRuleAbove(); else { // object in the clipboard is not a rule QModelIndex index = currentIndex(); if (index.isValid()) { RuleNode *node = md->nodeFromIndex(index); if (node->type != RuleNode::Rule) return; copyAndInsertObject(index, co); } } } } void RuleSetView::dragEnterEvent( QDragEnterEvent *ev) { ev->setAccepted( ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) ); } void RuleSetView::dropEvent(QDropEvent *ev) { // only accept drops from the same instance of fwbuilder if (ev->source() == NULL) return; RuleSetModel* md = ((RuleSetModel*)model()); if (!canChange(md)) return; QModelIndex index = indexAt (ev->pos()); if (!index.isValid()) return; list dragol; if (!FWObjectDrag::decode(ev, dragol)) return; for (list::iterator i=dragol.begin(); i!=dragol.end(); ++i) { FWObject *dragobj = *i; assert(dragobj!=NULL); if (fwbdebug) qDebug("RuleSetView::dropEvent dragobj=%s", dragobj->getName().c_str()); if (!validateForInsertion(index, dragobj)) continue; if (ev->source()!=this) { // since ev->source()!=this, this is d&d of an object from // the tree into rule or from another file. copyAndInsertObject(index, dragobj); } else { // since ev->source()==this, this is d&d of an object from // one rule to another. clearSelection(); if (ev->keyboardModifiers() & Qt::ControlModifier) { insertObject( index, dragobj, "copy-drop "+QString::fromUtf8(dragobj->getName().c_str())); } else //move { QModelIndex srcIndex = fwosm->index; // When object is dragged (moved) from one RE to // another, this should appear as single undo // command. Also, we should delete it first and insert // later so that we leave rule set view with the row // where it was inserted selected. FWCmdMacro* macro = new FWCmdMacro(tr("Move object")); deleteObject( srcIndex, dragobj, "move-delete "+QString::fromUtf8(dragobj->getName().c_str()), macro); insertObject( index, dragobj, "move-drop "+QString::fromUtf8(dragobj->getName().c_str()), macro); project->undoStack->push(macro); } } } QCoreApplication::postEvent( mw, new dataModifiedEvent(project->getFileName(), md->getRuleSet()->getId())); setCurrentIndex(index); ev->accept(); } void RuleSetView::deleteObject(QModelIndex index, libfwbuilder::FWObject *obj, QString text, QUndoCommand* macro) { RuleElement *re = (RuleElement *)index.data(Qt::DisplayRole).value(); if (re==NULL || re->isAny()) return; int position = Rule::cast(re->getParent())->getPosition(); int column = index.column(); int number = getObjectNumber(obj, index); FWCmdRuleChangeRe* cmd = new FWCmdRuleChangeRe( project, ((RuleSetModel*)model())->getRuleSet(), re, position, column, number, text, macro); RuleElement *newRe = RuleElement::cast(cmd->getNewState()); newRe->removeRef(obj); if (newRe->isAny()) newRe->setNeg(false); if (macro == 0) project->undoStack->push(cmd); } bool RuleSetView::insertObject(QModelIndex index, FWObject *obj, QString text, QUndoCommand* macro) { RuleElement *re = (RuleElement *)index.data(Qt::DisplayRole).value(); assert (re!=NULL); int position = Rule::cast(re->getParent())->getPosition(); int column = index.column(); int number = getObjectNumber(obj, index); FWCmdRuleChangeRe* cmd = new FWCmdRuleChangeRe( project, ((RuleSetModel*)model())->getRuleSet(), re, position, column, number, text, macro); RuleElement *newRe = RuleElement::cast(cmd->getNewState()); newRe->addRef(obj); if (macro == 0) project->undoStack->push(cmd); return true; } /* RuleElementItd::validateChild() accepts any Interface object. We * should apply additional restriction though: only interface of the * same firewall should be allowed. It turns out to be very hard to * implement this restriction in RuleElementItd::validateChild() * because when the operation is performed via redo(), the * RuleElementItf object we have to use is not part of the tree and * therefore does not have any parent firewall to compare with. */ bool RuleSetView::validateForInsertionToInterfaceRE(RuleElementItf *re, FWObject *obj) { return re->validateChild(obj) && re->checkItfChildOfThisFw(obj); } bool RuleSetView::validateForInsertion(QModelIndex index, FWObject *obj) { ColDesc colDesc = index.data(Qt::UserRole).value(); if (colDesc.type != ColDesc::Object && colDesc.type != ColDesc::Time) return false; RuleElement *re = (RuleElement *)index.data(Qt::DisplayRole).value(); assert (re!=NULL); return validateForInsertion(re, obj); } bool RuleSetView::validateForInsertion(RuleElement *re, FWObject *obj, bool quiet) { if (RuleSet::cast(obj)!=NULL) return false; // see #1976 do not allow pasting object that has been deleted if (obj && obj->getLibrary()->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) return false; if (! re->validateChild(obj) ) { if (!quiet) { if (RuleElementRItf::cast(re)) { QMessageBox::information( NULL , "Firewall Builder", QObject::tr( "A single interface belonging to this firewall is " "expected in this field."), QString::null,QString::null); } else if (RuleElementRGtw::cast(re)) { QMessageBox::information( NULL , "Firewall Builder", QObject::tr( "A single ip adress is expected here. You may also " "insert a host or a network adapter leading to a single " "ip adress."), QString::null,QString::null); } } return false; } if (re->getAnyElementId()==obj->getId()) return false; if ( !re->isAny()) { /* avoid duplicates */ int cp_id = obj->getId(); list::iterator j; for(j=re->begin(); j!=re->end(); ++j) { FWObject *o=*j; if(cp_id==o->getId()) return false; FWReference *ref; if( (ref=FWReference::cast(o))!=NULL && cp_id==ref->getPointerId()) return false; } } // This includes RuleElementItfInb and RuleElementItfOutb of nat rules if (RuleElementItf::cast(re) || RuleElementRItf::cast(re)) return validateForInsertionToInterfaceRE(RuleElementItf::cast(re), obj); return true; } /* Call validateForInsertion() before calling this function to make * sure @object can be inserted in the RE the @index points to. */ void RuleSetView::copyAndInsertObject(QModelIndex &index, FWObject *object) { if (!validateForInsertion(index, object)) return; RuleSetModel* md = ((RuleSetModel*)model()); bool need_to_reload_tree = false; if (md->getRuleSet()->getRoot()!=object->getRoot()) { // object is being copied from another project file FWObject *target = FWBTree().getStandardSlotForObject( md->getRuleSet()->getLibrary(), object->getTypeName().c_str()); map map_ids; object = project->db()->recursivelyCopySubtree(target, object, map_ids); need_to_reload_tree = true; } insertObject( index, object, "insert "+QString::fromUtf8(object->getName().c_str())); if (need_to_reload_tree) { project->m_panel->om->reload(); project->m_panel->om->openObjectInTree(object); // but still need to reopen this ruleset project->m_panel->om->openObjectInTree(md->getRuleSet()); } } void RuleSetView::dragMoveEvent( QDragMoveEvent *ev) { RuleSetModel* md = ((RuleSetModel*)model()); QWidget *fromWidget = ev->source(); // The source of DnD object must be the same instance of fwbuilder if (fromWidget) { if (ev->mimeData()->hasFormat(FWObjectDrag::FWB_MIME_TYPE) && !md->getRuleSet()->isReadOnly()) { if (ev->keyboardModifiers() & Qt::ControlModifier) ev->setDropAction(Qt::CopyAction); else ev->setDropAction(Qt::MoveAction); QModelIndex index = indexAt (ev->pos()); ColDesc colDesc = index.data(Qt::UserRole).value(); if (index.column()<0 || ( colDesc.type != ColDesc::Object && colDesc.type != ColDesc::Time) ) { ev->setAccepted(false); return; } RuleElement *re = getRE(index); if (re==NULL) { ev->setAccepted(false); return; } bool acceptE = true; list dragol; if (FWObjectDrag::decode(ev, dragol)) { for (list::iterator i=dragol.begin(); i!=dragol.end(); ++i) { FWObject *dragobj = NULL; dragobj = dynamic_cast(*i); if(dragobj!=NULL) { acceptE &= validateForInsertion(re, dragobj, true); } } ev->setAccepted( acceptE ); return; } } } ev->setAccepted(false); } void RuleSetView::unselect() { clearSelection(); setCurrentIndex(QModelIndex()); fwosm->setSelected(NULL, QModelIndex()); } FWObject* RuleSetView::getSelectedObject() { return fwosm->selectedObject; } void RuleSetView::saveCurrentRowColumn(SelectionMemento &memento) { RuleSetModel* md = ((RuleSetModel*)model()); QModelIndex index = fwosm->index; if (index.isValid()) { RuleNode* node = md->nodeFromIndex(index); if (node && node->rule) { memento.column = index.column(); FWObject *rule = node->rule; if (rule) memento.rule_id = node->rule->getId(); else memento.rule_id = -1; return; } } memento.column = -1; memento.rule_id = -1; } void RuleSetView::restoreCurrentRowColumn(SelectionMemento &memento) { if (memento.rule_id != -1) { RuleSetModel* md = ((RuleSetModel*)model()); Rule *rule = Rule::cast(project->db()->findInIndex(memento.rule_id)); QModelIndex index = md->index(rule, memento.column); selectRE(index); } } void RuleSetView::updateCurrentCell() { RuleSetModel* md = ((RuleSetModel*)model()); md->rowChanged(fwosm->index); updateColumnSizeForIndex(fwosm->index); } /* * looks like this method can be called when we print from the command * line. Variable project==NULL at that time. */ void RuleSetView::saveCollapsedGroups() { if (project) { QStringList collapsed_groups; QString filename = project->getRCS()->getFileName(); RuleSetModel* md = ((RuleSetModel*)model()); QList groups; md->getGroups(groups); foreach (QModelIndex index, groups) { if (!isExpanded(index)) { RuleNode* node = static_cast(index.internalPointer()); collapsed_groups.push_back(node->name); } } Firewall *f = md->getFirewall(); if (f) st->setCollapsedRuleGroups( filename, f->getName().c_str(), md->getRuleSet()->getName().c_str(), collapsed_groups); } } /* * looks like this method can be called when we print from the command * line. Variable project==NULL at that time. */ void RuleSetView::restoreCollapsedGroups() { if (project) { QTime t; t.start(); RuleSetModel* md = ((RuleSetModel*)model()); QStringList collapsed_groups; QString filename; filename = project->getRCS()->getFileName(); if (fwbdebug) qDebug("restoreCollapsedGroups begin: %d ms", t.restart()); Firewall *f = md->getFirewall(); if (f) st->getCollapsedRuleGroups( filename, f->getName().c_str(), md->getRuleSet()->getName().c_str(), collapsed_groups); if (fwbdebug) qDebug("restoreCollapsedGroups getCollapsedRuleGroups: %d ms", t.restart()); QList groups; md->getGroups(groups); if (fwbdebug) { qDebug("restoreCollapsedGroups getGroups: %d ms", t.restart()); qDebug() << "Groups:" << groups.size(); } foreach (QModelIndex index, groups) { RuleNode* node = static_cast(index.internalPointer()); setExpanded(index, !collapsed_groups.contains(node->name) ); } if (fwbdebug) qDebug("restoreCollapsedGroups foreach setExpanded: %d ms", t.restart()); } } int RuleSetView::rowHeight(const QModelIndex& index) const { return QTreeView::rowHeight(index); } void RuleSetView::updateWidget() { updateGeometries(); } bool RuleSetView::showToolTip(QEvent *event) { if (!st->getObjTooltips()) return true; QHelpEvent *he = (QHelpEvent*) event; QPoint pos = viewport()->mapFromGlobal(he->globalPos()); QString toolTip=""; QModelIndex index = indexAt(pos); if (!index.isValid()) { if (st->getBool("UI/AdvancedTooltips")) return false; toolTip = QObject::tr( "" "Policy, NAT and routing rules are shown here. " "
  • Rules use objects, if you want " "to use an object like IP address in a rule, " "you need to first create it in the object tree
  • " "
  • Drag and drop objects from the tree to " "the desired field (source, destination, etc.) in " "the rule.
  • " "
  • To add a rule, click the '+' button at " "the top of the window
  • " "
  • To open menu of operations such as " "'add rule', 'remove rule' etc, click right mouse button
  • " "
"); QToolTip::showText(mapToGlobal( he->pos() ), toolTip, this); return true; } RuleSetModel* md = ((RuleSetModel*)model()); RuleNode *node = md->nodeFromIndex(index); int column = index.column(); if (node->type == RuleNode::Rule) { QVariant v = index.data(Qt::DisplayRole); ColDesc colDesc = index.data(Qt::UserRole).value(); if (column == 0) { if (st->getBool("UI/AdvancedTooltips")) return false; // rule number column toolTip = QObject::tr( "" "To open menu of operations such as 'add rule', " "'remove rule' etc, click right mouse button.
" "To compile the rule and see generated firewall " "configuration, first select it by clicking inside of it " "and then hit 'X' on keyboard html>"); QToolTip::showText(mapToGlobal( he->pos() ), toolTip, this); return true; } else { switch (colDesc.type) { case ColDesc::Comment: if (!st->getClipComment()) return false; toolTip = v.value(); break; case ColDesc::Options: { Rule* rule = node->rule; if (PolicyRule::cast(rule)!=NULL ) { // if (!isDefaultPolicyRuleOptions(rule->getOptionsObject())) toolTip = FWObjectPropertiesFactory::getPolicyRuleOptions(rule); } if (NATRule::cast(rule)!=NULL ) { // if (!isDefaultNATRuleOptions( rule->getOptionsObject())) toolTip = FWObjectPropertiesFactory::getNATRuleOptions(rule); } } break; case ColDesc::Direction: if (st->getBool("UI/AdvancedTooltips")) { toolTip = QObject::tr("Direction: %1
") .arg(v.value()); } else { toolTip = QObject::tr("Direction: %1
" "To change the direction, " "click right mouse button to open " "the list of possible settings") .arg(v.value()); } break; case ColDesc::Action: if (st->getBool("UI/AdvancedTooltips")) { toolTip = v.value().tooltip; } else { toolTip = QObject::tr("%1 To change the action, " "click right mouse button to open " "the list of possible settings") .arg(v.value().tooltip); } break; default: FWObject *object = getObject(pos, index); if (object == 0) return true; toolTip = FWObjectPropertiesFactory::getObjectPropertiesDetailed( object, true, true); if (st->getBool("UI/AdvancedTooltips")) { if (object->getId() == FWObjectDatabase::ANY_ADDRESS_ID || object->getId() == FWObjectDatabase::ANY_SERVICE_ID || object->getId() == FWObjectDatabase::ANY_INTERVAL_ID) return false; } } } } else { toolTip = node->name; } if (toolTip.isEmpty()) { QToolTip::hideText(); return true; } if (fwbdebug) qDebug() << "Toolip: " << toolTip; QRect cr = visualRect(index); cr = QRect(cr.left() - horizontalOffset() - 2, cr.top() - verticalOffset() - 2, cr.width() + 4, cr.height() + 4); QRect global = QRect( viewport()->mapToGlobal(cr.topLeft()), viewport()->mapToGlobal(cr.bottomRight())); QToolTip::showText(mapToGlobal( he->pos() ), toolTip, this, global); return true; } bool RuleSetView::event( QEvent * event ) { if (event->type() == QEvent::ToolTip) { return showToolTip(event); } return QTreeView::event(event); } void RuleSetView::resizeColumns() { header()->resizeSections(QHeaderView::ResizeToContents); } void RuleSetView::updateAllColumnsSize() { resizeColumns(); } void RuleSetView::updateColumnSizeForIndex(QModelIndex index) { ((RuleSetModel*)model())->nodeFromIndex(index)->resetSizes(); //TODO: update only corresponding column resizeColumns(); } void RuleSetView::updateSectionSizesForIndex(QModelIndex idx1, QModelIndex idx2) { updateAllColumnsSize(); } void RuleSetView::setModel(QAbstractItemModel *model) { connect (model, SIGNAL (dataChanged(QModelIndex,QModelIndex)), this, SLOT (updateSectionSizesForIndex(QModelIndex,QModelIndex))); connect (model, SIGNAL (layoutChanged()), this, SLOT (updateAllColumnsSize())); QTreeView::setModel(model); connect (selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateSelectionSensitiveActions())); } void RuleSetView::repaintSelection() { QModelIndex index = currentIndex(); fwosm->setSelected(project->getSelectedObject(), index); viewport()->update((viewport()->rect())); } void RuleSetView::updateAll() { // May be it needs to invalidate all precalculated sizes. ((RuleSetModel*)model())->resetAllSizes(); viewport()->update((viewport()->rect())); updateAllColumnsSize(); } RuleElement* RuleSetView::getRE(QModelIndex index) { return (RuleElement *)index.data(Qt::DisplayRole).value(); } void RuleSetView::keyPressEvent( QKeyEvent* ev ) { RuleSetModel* md = ((RuleSetModel*)model()); if (md->getFirewall()==NULL) return; project->selectRules(); RuleElement *re; QModelIndex oldIndex = fwosm->index; int objno = getObjectNumber(fwosm->selectedObject, oldIndex); if (ev->key()==Qt::Key_Left || ev->key()==Qt::Key_Right) { int shift= (ev->key()==Qt::Key_Left) ? -1 : 1; int newColumn = oldIndex.column() + shift; if ((newColumn <= 0) || (newColumn > md->header.size())) return; /* keyboard 'Left' or 'Right', switch to the object with the same * number in the cell to the left or to the right */ QModelIndex newIndex = md->index(oldIndex.row(), newColumn, oldIndex.parent()); re = getRE(newIndex); if (re==NULL) { fwosm->setSelected(NULL, newIndex); setCurrentIndex(newIndex); return; } FWObject *newObj = getObject(objno, newIndex); selectObject(newObj, newIndex); return; } if (ev->key()==Qt::Key_PageDown || ev->key()==Qt::Key_PageUp || ev->key()==Qt::Key_End || ev->key()==Qt::Key_Home) { QTreeView::keyPressEvent(ev); QModelIndex newIndex = md->index(currentIndex().row(), oldIndex.column(), currentIndex().parent()); re = getRE(newIndex); FWObject *object = NULL; if (re != NULL) { object = FWReference::getObject(re->front()); selectObject(object, newIndex); } else { fwosm->setSelected(NULL, newIndex); setCurrentIndex(newIndex); } return; } if (ev->key()==Qt::Key_Down || ev->key()==Qt::Key_Up) { re = getRE(oldIndex); FWObject *object = md->getFirewall(); QModelIndex newIndex = oldIndex; FWObject::iterator i; if (re == NULL && !md->isGroup(oldIndex)) { // Non-object column. Just move focus up or down; QTreeView::keyPressEvent(ev); newIndex = md->index(currentIndex().row(), oldIndex.column(), currentIndex().parent()); if (!md->isGroup(newIndex)) { selectionModel()->select( newIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select); setCurrentIndex(newIndex); fwosm->setSelected(NULL, newIndex); ev->accept(); } return; } else { if (md->isGroup(oldIndex)) { object = NULL; } else { FWObject *prev = NULL; for (i=re->begin(); i!=re->end(); ++i) { object = FWReference::getObject(*i); if (ev->key()==Qt::Key_Up && object==fwosm->selectedObject) break; if (ev->key()==Qt::Key_Down && prev==fwosm->selectedObject) break; prev = object; } if (ev->key()==Qt::Key_Up) object = prev; if (ev->key()==Qt::Key_Down && i == re->end()) object = NULL; } if (object == NULL) { // It needs to move to another row QTreeView::keyPressEvent(ev); newIndex = md->index(currentIndex().row(), oldIndex.column(), currentIndex().parent()); selectionModel()->select( newIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select); if (oldIndex.row() == newIndex.row()) { // we are stuck! It's very first or last row. object = fwosm->selectedObject; } else { re = getRE(newIndex); if (re != NULL) { // NOT a group if (ev->key()==Qt::Key_Up) { i = re->end(); --i; } else { i = re->begin(); } object = FWReference::getObject(*i); } else { if (!md->isGroup(newIndex)) { setCurrentIndex(newIndex); fwosm->setSelected(NULL, newIndex); ev->accept(); return; } object = md->getFirewall(); } } } else { // select other object in current cell } } selectObject(object, newIndex); ev->accept(); return; } if (ev->key()==Qt::Key_Delete) { deleteSelectedObject(); } if (ev->key()==Qt::Key_Enter || ev->key()==Qt::Key_Return) { editSelected(); } QTreeView::keyPressEvent(ev); } void RuleSetView::compileCurrentRule() { RuleSetModel* md = ((RuleSetModel*)model()); //if (!isTreeReadWrite(this, md->getRuleSet())) return; if (md->getFirewall()==NULL) return; QModelIndex index = currentIndex(); if (!index.isValid()) return; RuleNode* node = static_cast(index.internalPointer()); if (node == 0 || node->type != RuleNode::Rule || node->rule == 0) return; mw->singleRuleCompile(node->rule); } void RuleSetView::updateSelectionSensitiveActions() { // qDebug() << "RuleSetView::updateSelectionSensitiveActions(QItemSelection selected,QItemSelection deselected)"; RuleSetModel* md = ((RuleSetModel*)model()); QModelIndexList selectedIndexes = getSelectedRows(); bool compileRuleActionEnabled = false; int selectionSize = selectedIndexes.size(); if (selectionSize==1) { QModelIndex index = selectedIndexes.at(0); if (index.isValid()) { RuleNode* node = md->nodeFromIndex(index); if (node!=0 && node->type == RuleNode::Rule && node->rule != 0) { compileRuleActionEnabled = !node->rule->isDisabled(); } } } compileRuleAction->setEnabled(compileRuleActionEnabled); if (selectionSize == 0) { setActionState(removeFromGroupAction, false); setActionState(newGroupAction, false); setActionState(moveRuleUpAction, false); setActionState(moveRuleDownAction, false); setActionState(addToGroupAboveAction, false); setActionState(addToGroupBelowAction, false); setActionState(insertRuleAction, false); setActionState(addRuleAfterCurrentAction, false); setActionState(removeRuleAction, false); setActionState(disableRuleAction, false); setActionState(enableRuleAction, false); setActionState(copyRuleAction, false); setActionState(cutRuleAction, false); setActionState(pasteRuleAboveAction, false); setActionState(pasteRuleBelowAction, false); setColorEmptyAction->setEnabled(false); setColorRedAction->setEnabled(false); setColorBlueAction->setEnabled(false); setColorOrangeAction->setEnabled(false); setColorPurpleAction->setEnabled(false); setColorGrayAction->setEnabled(false); setColorYellowAction->setEnabled(false); setColorGreenAction->setEnabled(false); } else { bool inGroup = true; bool outermost = false; bool topLevelOnly = true; int disabled = 0; int enabled = 0; foreach(QModelIndex index, selectedIndexes) { if (index.isValid()) { RuleNode* node = md->nodeFromIndex(index); topLevelOnly = topLevelOnly && (node->type == RuleNode::Rule); if (node!=0 && node->type == RuleNode::Rule && node->rule != 0) { bool isInGroup = node->isInGroup(); inGroup = inGroup && isInGroup; topLevelOnly = topLevelOnly && !isInGroup; outermost = outermost || (node->isOutermost() && isInGroup); Rule *r = node->rule; if (r->isDisabled()) disabled++; else enabled++; } } } setActionState(disableRuleAction, enabled > 0); setActionState(enableRuleAction, disabled > 0); enableRuleAction->setText( (disabled==1)?tr("Enable Rule"):tr("Enable Rules")); disableRuleAction->setText( (enabled==1)?tr("Disable Rule"):tr("Disable Rules")); if (selectionSize > 1) { copyRuleAction->setText(tr("Copy Rules")); cutRuleAction->setText(tr("Cut Rules")); moveRuleUpAction->setText(tr("Move Rules Up")); moveRuleDownAction->setText(tr("Move Rules Down")); removeRuleAction->setText(tr("Remove Rules")); } else { copyRuleAction->setText(tr("Copy Rule")); cutRuleAction->setText(tr("Cut Rule")); moveRuleUpAction->setText(tr("Move Rule Up")); moveRuleDownAction->setText(tr("Move Rule Down")); removeRuleAction->setText(tr("Remove Rule")); } if (topLevelOnly) { QString addToGroupLabel = tr("Add To the Group "); QString nn; nn = md->nodeFromIndex(selectedIndexes.first())->nameOfPredecessorGroup(); if (!nn.isEmpty()) { addToGroupAboveAction->setText(addToGroupLabel + nn); setActionState(addToGroupAboveAction, true); } else { setActionState(addToGroupAboveAction, false); } nn = md->nodeFromIndex(selectedIndexes.last())->nameOfSuccessorGroup(); if (!nn.isEmpty()) { addToGroupBelowAction->setText(addToGroupLabel + nn); setActionState(addToGroupBelowAction, true); } else { setActionState(addToGroupBelowAction, false); } } else { setActionState(addToGroupAboveAction, false); setActionState(addToGroupBelowAction, false); } setActionState(removeFromGroupAction, outermost); setActionState(newGroupAction, topLevelOnly); setActionState(moveRuleUpAction, true); setActionState(moveRuleDownAction, true); setActionState(insertRuleAction, true); setActionState(addRuleAfterCurrentAction, true); setActionState(removeRuleAction, true); setActionState(copyRuleAction, true); setActionState(cutRuleAction, true); setActionState(pasteRuleAboveAction, true); setActionState(pasteRuleBelowAction, true); setColorEmptyAction->setEnabled(true); setColorRedAction->setEnabled(true); setColorBlueAction->setEnabled(true); setColorOrangeAction->setEnabled(true); setColorPurpleAction->setEnabled(true); setColorGrayAction->setEnabled(true); setColorYellowAction->setEnabled(true); setColorGreenAction->setEnabled(true); } } void RuleSetView::updateObject(FWObject* object) { RuleSetModel* md = ((RuleSetModel*)model()); md->objectChanged(object); } void RuleSetView::setActionState(QAction *action, bool state) { action->setEnabled(state); action->setVisible(state); } //////////////////////////////////////////////////////////////////////////// // PolicyView //////////////////////////////////////////////////////////////////////////// PolicyView::PolicyView(ProjectPanel *project, Policy *p, QWidget *parent):RuleSetView(project, parent) { QItemSelectionModel *sm = QTreeView::selectionModel(); RuleSetModel* model = new PolicyModel(p,this); setModel(model); delete sm; RuleSetViewDelegate *dlgt = new RuleSetViewDelegate(this, fwosm); dlgt->setStandardHighlightColor(palette().color(QPalette::Highlight)); setItemDelegate(dlgt); init(); } //////////////////////////////////////////////////////////////////////////// // NATView //////////////////////////////////////////////////////////////////////////// NATView::NATView(ProjectPanel *project, NAT *p, QWidget *parent):RuleSetView(project, parent) { QItemSelectionModel *sm = QTreeView::selectionModel(); RuleSetModel* model = new NatModel(p,this); setModel(model); delete sm; RuleSetViewDelegate *dlgt = new RuleSetViewDelegate(this, fwosm); dlgt->setStandardHighlightColor(palette().color(QPalette::Highlight)); setItemDelegate(dlgt); init(); } //////////////////////////////////////////////////////////////////////////// // RoutingView //////////////////////////////////////////////////////////////////////////// RoutingView::RoutingView(ProjectPanel *project, Routing *p, QWidget *parent):RuleSetView(project, parent) { QItemSelectionModel *sm = QTreeView::selectionModel(); RuleSetModel* model = new RoutingModel(p,this); setModel(model); delete sm; RuleSetViewDelegate *dlgt = new RuleSetViewDelegate(this, fwosm); dlgt->setStandardHighlightColor(palette().color(QPalette::Highlight)); setItemDelegate(dlgt); init(); } fwbuilder-5.1.0.3599/src/libgui/helpview_q.ui0000644000175000017500000000474511733011756021554 0ustar sylvestresylvestre HelpView_q Qt::NonModal 0 0 469 639 Help QFrame::StyledPanel QFrame::Raised 75 true Object Name false Qt::Horizontal 40 20 Close closeButton clicked() HelpView_q close() 418 588 234 319 fwbuilder-5.1.0.3599/src/libgui/PrototypeDialogClass.h0000644000175000017500000000263311733011756023330 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PROTOTYPEDIALOG_H_ #define __PROTOTYPEDIALOG_H_ #include "config.h" #include #include "fwbuilder/FWObject.h" class PrototypeDialog : public PrototypeDialog_q { Q_OBJECT libfwbuilder::FWObject *obj; bool init; public: PrototypeDialog() : PrototypeDialog_q() { obj=NULL; } public slots: virtual void changed(); virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); virtual void closeEvent(QCloseEvent *e); }; #endif // __PROTOTYPEDIALOG_H fwbuilder-5.1.0.3599/src/libgui/prefsdialog_q.ui0000644000175000017500000017426511733011756022235 0ustar sylvestresylvestre prefsDialog_q true 0 0 731 563 Preferences true Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true &Cancel true 1 General 20 0 0 Working directory: false 0 0 0 0 200 16777215 Browse... 0 0 Data directory: false 0 0 0 0 200 16777215 Browse... 75 true Software Updates: Check Now Check for updates automatically Qt::Horizontal 15 20 Qt::Horizontal 223 20 Use http proxy while checking for updates (host:port) No identifiable information will be sent to the server during update check Qt::Vertical 20 7 Do not show tips on startup Objects 0 25 Enable object tooltips in the tree and rule sets Qt::Horizontal QSizePolicy::Expanding 429 20 Show deleted objects Show object attributes in the tree The program comes with a library of template objects that can be used to create new firewalls, however you can create your own library of templates and use it in addition to the one we provide Enable use of custom firewall template libraries Qt::Vertical 618 20 Properties of specific object types: Qt::AlignCenter Qt::Vertical 618 46 Advanced User Mode, only show minimal tooltips 2 DNS Name 20 :/Icons/DNSName/icon-big 0 0 QFrame::NoFrame QFrame::Raised 0 19 Create new objects in "Compile Time" mode by default true Create new objects in "Run Time" mode by default Use object name for the DNS record in all objects of this type Qt::Vertical 20 106 Address Table 20 :/Icons/AddressTable/icon-big 0 0 QFrame::NoFrame QFrame::Raised 0 19 Create new objects in "Compile Time" mode by default true Create new objects in "Run Time" mode by default Qt::Vertical 20 136 Policy Rules 64 64 64 64 :/Icons/Policy/icon-big 0 0 This setting allows you to change whether new rules created in fwbuilder have action, logging and stateful inspection turned on or off by default. true 0 0 Create new policy rules with logging turned on 0 0 Create new policy rules with stateful inspection turned on Create new policy rules with action Deny Accept Qt::Horizontal 40 20 Create new policy rules with direction Both Inbound Outbound Qt::Horizontal 40 20 Qt::Vertical 20 116 Interface 0 0 :/Icons/Interface/icon-big When an interface object is created as a child object of another interface, fwbuilder can verify that the name and type of the child and the parent objects match and form valid configuration. FWbuilder can also automatically guess some interface types and their parameters using their names. For example, it can automatically set interface type to "vlan" and assign vlan ID if object name looks like a valid vlan interface for the given OS. However in some situations desired configuration might be more complex than our checks allow so this may need to be turned off. true 0 0 Verify interface names and autoconfigure their parmeters using known name patterns Qt::Vertical 20 134 Data File 20 20 Periodically save data to file every 50 0 100 16777215 1 120 minutes false Qt::Horizontal 225 20 Do not ask for the log record when checking in new file revision. Enable compression of the data file Qt::Vertical 20 97 Installer A full path to the Secure Shell utility (remote command execution; for example ssh on Unix or plink.exe on Windows): Qt::AlignVCenter true 0 0 0 0 Browse... A full path to the SCP utility (file copy over ssh; for example scp on Unix or pscp.exe on Windows): Qt::AlignVCenter true 0 0 0 0 Browse... Value for the ServerAliveInterval ssh configuration parameter. This parameter sets timeout interval in seconds after which if no data has been received from the server, ssh client will send a message through the encrypted channel to request a response from the server. This helps detect disconnects between fwbuilder policy installer and the firewall. If set to 0, these messages will not be sent to the server and loss of connectivity with the firewall will lead to hanging of the installer session. Scp uses different parameter for this, ConnectTimeout. Fwbuilder automatically calculates the value for this parameter using the same timeout value. Note that this only works with ssh protocol v2. true 999999 sec Qt::Horizontal 528 23 QFrame::NoFrame QFrame::Plain 0 Download plink.exe and pscp.exe from the web site at 0 0 0 30 16777215 30 true QFrame::NoFrame QFrame::Plain <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"><span style=" font-family:'Lucida Grande'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.chiark.greenend.org.uk/~sgtatham/putty/</span></a></p></body></html> true true Qt::Vertical QSizePolicy::Fixed 20 20 Built-in policy installer can remember passwords for the duration of the session. Passwords are never stored permanently, they are only kept in memory. In order to use this feature, you also need to configure user name used to authenticate to the firewall in the "advanced" settings dialog of the firewall object. true false Warning: using this feature creates certain risk if working Firewall Builder GUI is left unattended on the unlocked workstation. Someone may walk up to the machine and make changes to the firewall using cached password of the administrator who used the same GUI session before. Always lock the screen or exit Firewall Builder GUI when leaving computer. true Enable password caching for the duration of the session (passwords are never stored permanently) Enable password caching Qt::Vertical QSizePolicy::Expanding 505 61 Labels 20 20 Use these labels to mark rules in the firewall policy Qt::AlignCenter false Qt::Horizontal QSizePolicy::Expanding 40 20 20 Red Blue Yellow Orange Purple Green Gray Qt::Horizontal QSizePolicy::Expanding 70 20 Qt::Vertical 20 38 Appearance Icons settings 20 12 0 0 250 0 Choose font for rules sets Rules font 0 0 rules font description 0 0 250 0 Choose font for tree Tree font 0 0 tree font description 0 0 250 0 Choose font for tree Compiler Output Panel font 0 0 compiler output font description Show icons in rules true Show text descriptions in columns "Direction", "Action" 100 100 true Icons size in rules: 16x16 25x25 true Qt::Horizontal 330 96 Qt::Vertical 20 40 Clip comments in rules Show text under toolbar icons Platforms and OS 20 If you disable firewall platform or host OS here, it will not appear in the drop-down lists of platforms and host OS anywhere in the program. This helps avoid clutter in lists of platforms and OS if you only work with one or two of them. true Supported firewall platforms Supported host OS true QAbstractItemView::NoSelection false false Platform QAbstractItemView::NoEditTriggers true QAbstractItemView::NoSelection false false Host OS tabWidget wDir browseWDir buttonOk buttonCancel emptyRCSLog browseForSSH sshPath redBtn redText orangeBtn orangeText yellowBtn yellowText greenBtn greenText blueBtn blueText purpleBtn purpleText grayBtn grayText buttonOk clicked() prefsDialog_q accept() 697 566 20 20 buttonCancel clicked() prefsDialog_q reject() 780 566 20 20 rb25 clicked() prefsDialog_q changeIconSize25() 243 360 20 20 browseForSCP clicked() prefsDialog_q findSCP() 757 182 334 214 checkUpdatesNow clicked() prefsDialog_q checkSwUpdates() 375 195 334 214 btTreeFont clicked() prefsDialog_q changeTreeFont() 152 125 334 210 orangeBtn clicked() prefsDialog_q changeOrangeColor() 353 160 20 20 blueBtn clicked() prefsDialog_q changeBlueColor() 353 286 20 20 rb16 clicked() prefsDialog_q changeIconSize16() 243 327 20 20 btRulesFont clicked() prefsDialog_q changeRulesFont() 137 60 334 210 objTooltips toggled(bool) prefsDialog_q objTooltipsEnabled(bool) 65 53 3 71 btCompilerOutputFont clicked() prefsDialog_q changeCompilerOutputFont() 152 169 334 233 browseWDir clicked() prefsDialog_q findWDir() 757 82 20 20 browseDataDir clicked() prefsDialog_q findDataDir() 20 20 20 20 redBtn clicked() prefsDialog_q changeRedColor() 353 118 20 20 yellowBtn clicked() prefsDialog_q changeYellowColor() 353 202 20 20 browseForSSH clicked() prefsDialog_q findSSH() 757 114 20 20 greenBtn clicked() prefsDialog_q changeGreenColor() 353 244 20 20 purpleBtn clicked() prefsDialog_q changePurpleColor() 353 328 20 20 chShowIcons clicked() prefsDialog_q changeShowIcons() 43 181 20 20 grayBtn clicked() prefsDialog_q changeGrayColor() 353 370 20 20 findSSH() findSCP() checkSwUpdates() changeRulesFont() changeTreeFont() changeCompilerOutputFont() objTooltipsEnabled(bool) fwbuilder-5.1.0.3599/src/libgui/timedialog_q.ui0000644000175000017500000003423011733011756022037 0ustar sylvestresylvestre TimeDialog_q true 0 0 951 251 Time QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken Name: false 200 0 0 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 5 350 16 QFrame::NoFrame QFrame::Sunken 0 2 2 Start date: 0 25 M/d/yyyy true 2000 1 1 Qt::Horizontal 101 25 Start time: false 0 25 Qt::Horizontal 111 20 2 2 End date: 0 25 M/d/yyyy true 2000 1 1 Qt::Horizontal 101 25 End time: false 0 25 Qt::Horizontal 101 25 false 2 2 0 QFrame::NoFrame QFrame::Raised 0 0 Mon Tue Wed Thu Fri Sat Sun 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name startDate startTime endDate endTime useStartDate toggled(bool) TimeDialog_q useStartOrEndDate() 224 79 20 20 useEndDate toggled(bool) TimeDialog_q useStartOrEndDate() 224 166 20 20
fwbuilder-5.1.0.3599/src/libgui/fwobjectdroparea_q.ui0000644000175000017500000000165111733011756023243 0ustar sylvestresylvestre FWObjectDropArea_q 0 0 142 102 1 1 0 0 100 100 Form1 true fwbuilder-5.1.0.3599/src/libgui/FWBSettings.cpp0000644000175000017500000011333611733011756021712 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2004 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "FWBSettings.h" #include "FWWindow.h" #include "ObjectManipulator.h" #include "fwbuilder/FWObjectDatabase.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 # include # include # include #else # include // for access(2) #endif #include using namespace std; using namespace libfwbuilder; const char* DTDSetpath = SETTINGS_PATH_PREFIX "/System/DTDPath"; const char* ResSetpath = SETTINGS_PATH_PREFIX "/System/ResPath"; const char* compression = SETTINGS_PATH_PREFIX "/DataFile/compression"; const char* wdirSetpath = SETTINGS_PATH_PREFIX "/Environment/WDir"; const char* datadirSetpath = SETTINGS_PATH_PREFIX "/Environment/DataDir"; const char* ofdirSetpath = SETTINGS_PATH_PREFIX "/Environment/OpenFileDir"; const char* startupActionSetpath = SETTINGS_PATH_PREFIX "/Environment/StartupAction"; const char* labelColorPath = SETTINGS_PATH_PREFIX "/ColorLabels/color_"; const char* labelTextPath = SETTINGS_PATH_PREFIX "/ColorLabels/text_"; const char* lastEditedSetpath = SETTINGS_PATH_PREFIX "/Environment/LastEdited"; const char* autoSave = SETTINGS_PATH_PREFIX "/Environment/autoSave"; const char* expandTreeSetpath = SETTINGS_PATH_PREFIX "/UI/ExpandTree"; const char* MergeLibsSetpath = SETTINGS_PATH_PREFIX "/UI/MergeLibraries"; const char* infoStyleSetpath = SETTINGS_PATH_PREFIX "/UI/InfoWindowStyle"; const char* infoWindowHSetpath = SETTINGS_PATH_PREFIX "/UI/InfoWindowHeight"; const char* groupModeSetpath = SETTINGS_PATH_PREFIX "/UI/GroupViewMode"; const char* groupColsSetpath = SETTINGS_PATH_PREFIX "/UI/GroupViewColumns"; const char* customTemplatesEn = SETTINGS_PATH_PREFIX "/UI/customTemplatesEnabled"; const char* objTooltips = SETTINGS_PATH_PREFIX "/UI/objTooltips"; const char* tooltipDelay = SETTINGS_PATH_PREFIX "/UI/tooltipDelay"; const char* showUndoPanel = SETTINGS_PATH_PREFIX "/UI/showUndoPanel"; const char* userWorkflowFlags = SETTINGS_PATH_PREFIX "/UI/userWorkFlowFlags"; const char* iconsWithText = SETTINGS_PATH_PREFIX "/UI/IconWithText"; const char* emptyRCSLog = SETTINGS_PATH_PREFIX "/RCS/emptyLog"; const char* rcsFilePreviewStyle = SETTINGS_PATH_PREFIX "/RCS/FilePreviewStyle"; const char* rcsFilePreviewSortColumn = SETTINGS_PATH_PREFIX "/RCS/FilePreviewSortColumn"; const char* dontSaveStdLib = SETTINGS_PATH_PREFIX "/DataFormat/dontSaveStdLib"; const char* WindowGeometrySetpath= SETTINGS_PATH_PREFIX "/Layout/"; const char* screenPositionSetpath= SETTINGS_PATH_PREFIX "/ScreenPos/"; const char* showIconsInRules = SETTINGS_PATH_PREFIX "/UI/Icons/ShowIconsInRules"; const char* showDirectionText = SETTINGS_PATH_PREFIX "/UI/Icons/ShowDirectionTextInRules"; const char* iconsInRulesSize = SETTINGS_PATH_PREFIX "/UI/Icons/IconsInRulesSize"; const char* rulesFont = SETTINGS_PATH_PREFIX "/UI/Fonts/RulesFont"; const char* treeFont = SETTINGS_PATH_PREFIX "/UI/Fonts/TreeFont"; const char* uiFont = SETTINGS_PATH_PREFIX "/UI/Fonts/UiFont"; const char* compilerOutputFont = SETTINGS_PATH_PREFIX "/UI/Fonts/CompilerOutputFont"; const char* clipComment = SETTINGS_PATH_PREFIX "/UI/ClipComment"; const char* checkUpdates = SETTINGS_PATH_PREFIX "/UI/CheckUpdates"; const char* updateAvailableWarningLastTime = SETTINGS_PATH_PREFIX "/UI/updateAvailableWarningLastTime"; const char* announcementLastTime = SETTINGS_PATH_PREFIX "/UI/announcementLastTime/%1"; const char* checkUpdatesProxy = SETTINGS_PATH_PREFIX "/UI/CheckUpdatesProxy"; const char* reminderAboutStandardLibSuppressed = SETTINGS_PATH_PREFIX "/UI/reminderAboutStandardLibSuppressed"; const char* reminderDataDir = SETTINGS_PATH_PREFIX "/UI/reminderDataDir"; const char* introDialogEnabled = SETTINGS_PATH_PREFIX "/UI/introDialogEnabled"; const char* newFirewallPlatform = SETTINGS_PATH_PREFIX "/Objects/NewFireallPlatform"; const char* newClusterFailoverProtocol = SETTINGS_PATH_PREFIX "/Objects/newClusterFailoverProtocol"; const char* abTestingGroup = SETTINGS_PATH_PREFIX "/abTestingGroup"; const char* startsCounter = SETTINGS_PATH_PREFIX "/startsCounter"; const char* targetStatus = SETTINGS_PATH_PREFIX "/TargetStatus/"; const char* SSHPath = SETTINGS_PATH_PREFIX "/SSH/SSHPath"; const char* SCPPath = SETTINGS_PATH_PREFIX "/SSH/SCPPath"; const char* appGUID = "/fwbuilder_gui/ApplicationGUID"; const char* appGUID_4_0 = "/4.0/ApplicationGUID"; const char* appGUID_4_1 = "/4.1/ApplicationGUID"; #ifdef _WIN32 const char* SSHTimeout = "Sessions/fwb_session_with_keepalive/PingIntervalSecs"; #else const char* SSHTimeout = SETTINGS_PATH_PREFIX "/SSH/SSHTimeout"; #endif /** * Settings path defined here should match Windows registry paths used * in the Windows installer/uninstaller scripts. * * Path used for uuid_settings should not include version to ensure * uuid persistence across upgrades. This means do not use getApplicationNameForSettings() */ FWBSettings::FWBSettings(bool testData) : QSettings(QSettings::UserScope, "netcitadel.com", testData?"fwb_test_data":getApplicationNameForSettings()) { if (testData) { this->clear(); } uuid_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "netcitadel.com", "FirewallBuilder"); #ifdef _WIN32 ssh_timeout_setings_object = new QSettings(QSettings::UserScope, "SimonTatham", "PuTTY"); #else ssh_timeout_setings_object = this; #endif } FWBSettings::~FWBSettings() { delete uuid_settings; #ifdef _WIN32 delete ssh_timeout_setings_object; #endif } /** * to preserve behavior of the old versions of fwbuilder on Unix, the * default working dir is set to "." - current dir. * * On Windows default working dir is set to * "Documents and settings/USERNAME/Firewalls" */ void FWBSettings::init(bool force_first_time_run) { bool ok = false; first_run = false; ok = contains(reminderAboutStandardLibSuppressed); if (!ok) suppressReminderAboutStandardLib(true); ok = uuid_settings->contains(appGUID); if (!ok) { ok = uuid_settings->contains(appGUID_4_1); if (ok) { uuid_settings->setValue( appGUID, uuid_settings->value(appGUID_4_1).toString()); uuid_settings->remove(appGUID_4_1); } else { ok = uuid_settings->contains(appGUID_4_0); if (ok) { uuid_settings->setValue( appGUID, uuid_settings->value(appGUID_4_0).toString()); uuid_settings->remove(appGUID_4_0); } else { qsrand(time(NULL)); uuid_settings->setValue(appGUID, QUuid::createUuid().toString()); first_run = true; } } } if (force_first_time_run) first_run = true; if (first_run) { suppressReminderAboutStandardLib(false); } else { // enable custom templates for existing users for backwards // compatibility. New users will have this disabled for simplicity. ok = contains(customTemplatesEn); if (!ok) setCustomTemplatesEnabled(true); } ok = contains(abTestingGroup); if (!ok) { // a/b group codes are "1" and "2" setABTestingGroup(QTime::currentTime().second() % 2 + 1); } ok = contains(introDialogEnabled); if (!ok) { setIntroDialogEnabled(true); } ok = contains(startsCounter); if (!ok) { setValue(startsCounter, 0); } setValue(startsCounter, getStartsCounter() + 1); // disable invitation to watch quick start guide after 5 starts if (getStartsCounter() > 5) setIntroDialogEnabled(false); /* * I am seeing two particular uuids a lot in the logs, both coming * from thousands of different instances all over the world. I * have no idea why so many different systems assigned themselves * the same uuid which is supposed to be random and * unique. Apparently QUuid::createUuid() returns predictable uuid * in some cases. Versions of the program before 4.0.2 did not * call qsrand() to re-seed random generator because Qt * documentation says that createUuid() does that. Interestingly, * if I run google search for the first of the two uuids, I get * some results which means exactly the same uuid was generated by * an unrelated program in some completely unrelated case. * Anyway, I am going to "flush" these two repeatable uuids to * reduce systematic error in counting how many instances of * fwbuilder are running out there. */ QString my_uuid = getAppGUID(); if (my_uuid == "b7203c47-06bf-4878-9ff5-6afffb2db546" || my_uuid == "46759a87-7956-431f-a171-ccb754ef239e") { qsrand(time(NULL)); uuid_settings->setValue(appGUID, QUuid::createUuid().toString()); } // By default sort RCS File preview by date, which is column 1 ok = contains(rcsFilePreviewSortColumn); if (!ok) setRCSFilePreviewSortColumn(1); ok = contains(infoStyleSetpath); if (!ok) setValue(infoStyleSetpath,2); ok = contains(infoWindowHSetpath); if (!ok) setValue(infoWindowHSetpath,200); ok = contains(dontSaveStdLib); if (!ok) setDontSaveStdLib(true); ok = contains(startupActionSetpath); if (!ok) setStartupAction(2); ok = contains(showDirectionText); if (!ok) setShowDirectionText(true); #ifdef _WIN32 QString wd = getWDir().replace('/','\\'); #else QString wd = getWDir(); #endif if ( ! wd.isEmpty()) { QDir wdir(wd); if (!wdir.exists() && !wdir.mkdir(wd)) { QString err = QString(QObject::tr("Working directory %1 does not exist and could not be created.\nIgnoring this setting.")).arg(wd);; if (app != NULL) { QMessageBox::critical( 0,"Firewall Builder", err, "&Continue", 0, 0, 0 ); } else { qDebug() << err; } setWDir(""); } } ok = contains(objTooltips); if (!ok) setObjTooltips(true); QString c; if (getLabelColor(RED ).isEmpty()) { setLabelColor(RED ,"#C86E6E"); setLabelText(RED,"Red"); } if (getLabelColor(ORANGE).isEmpty()) { setLabelColor(ORANGE,"#C08B5A"); setLabelText(ORANGE,"Orange"); } if (getLabelColor(YELLOW).isEmpty()) { setLabelColor(YELLOW,"#C0BA44"); setLabelText(YELLOW,"Yellow"); } if (getLabelColor(GREEN ).isEmpty()) { setLabelColor(GREEN ,"#8BC065"); setLabelText(GREEN ,"Green"); } if (getLabelColor(BLUE ).isEmpty()) { setLabelColor(BLUE ,"#7694C0"); setLabelText(BLUE ,"Blue"); } if (getLabelColor(PURPLE).isEmpty()) { setLabelColor(PURPLE,"#A37EC0"); setLabelText(PURPLE,"Purple"); } if (getLabelColor(GRAY ).isEmpty()) { setLabelColor(GRAY ,"#C0C0C0"); setLabelText(GRAY ,"Gray"); } ok = contains(showIconsInRules); if (!ok) setShowIconsInRules(true); ok = contains(iconsInRulesSize); if (!ok) setIconsInRulesSize(SIZE25X25); ok = contains(rulesFont); if (!ok) setRulesFont(QApplication::font()); ok = contains(treeFont); if (!ok) setTreeFont(QApplication::font()); ok = contains(uiFont); if (!ok) setUiFont(QApplication::font()); ok = contains(compilerOutputFont); if (!ok) setCompilerOutputFont(QApplication::font()); if (fwbdebug) qDebug() << "Default application font:" << QApplication::font(); ok = contains(iconsWithText); if (!ok) setIconsWithText(true); ok = contains(clipComment); if (!ok) setClipComment(true); ok = contains(checkUpdates); if (!ok) { setCheckUpdates(true); setTimeOfLastUpdateAvailableWarning(0); } ok = contains(compression); if (!ok) setCompression(false); #ifndef _WIN32 if (getSSHPath().isEmpty()) setSSHPath("ssh"); if (getSCPPath().isEmpty()) setSCPPath("scp"); #endif // default timeout is 30 sec (default value of ServerAliveCountMax is 3) // do this for both Linux and windows ! if (!haveSSHTimeout()) setSSHTimeout(10); // Note: hasKey calls QSettings::contains using path given as // argument, prepended with SETTINGS_PATH_PREFIX if (!hasKey("Window/maximized")) setInt("Window/maximized", 1); if (!hasKey("Objects/DNSName/useCompileTimeForNewObjects")) setBool("Objects/DNSName/useCompileTimeForNewObjects", true); if (!hasKey("Objects/DNSName/useNameForDNSRecord")) setBool("Objects/DNSName/useNameForDNSRecord", false); if (!hasKey("Objects/AddressTable/useCompileTimeForNewObjects")) setBool("Objects/AddressTable/useCompileTimeForNewObjects", true); if (!hasKey("Objects/PolicyRule/defaultLoggingState")) setBool("Objects/PolicyRule/defaultLoggingState", true); if (!hasKey("Objects/PolicyRule/defaultStateful")) setBool("Objects/PolicyRule/defaultStateful", true); if (!hasKey("Objects/PolicyRule/defaultAction")) setInt("Objects/PolicyRule/defaultAction", 0); if (!hasKey("Objects/PolicyRule/defaultDirection")) setInt("Objects/PolicyRule/defaultDirection", 0); if (!hasKey("Objects/Interface/autoconfigureInterfaces")) setBool("Objects/Interface/autoconfigureInterfaces", true); } bool FWBSettings::isReminderAboutStandardLibSuppressed() { return value(reminderAboutStandardLibSuppressed).toBool(); } void FWBSettings::suppressReminderAboutStandardLib(bool f) { setValue(reminderAboutStandardLibSuppressed, f); } bool FWBSettings::isReminderAboutDataDirSuppressed() { return value(reminderDataDir).toBool(); } void FWBSettings::suppressReminderAboutDataDir(bool f) { setValue(reminderDataDir, f); } bool FWBSettings::hasKey(const QString &attribute) { return QSettings::contains(SETTINGS_PATH_PREFIX "/" + attribute); } QString FWBSettings::getAppGUID() { return uuid_settings->value(appGUID).toString(); } QString FWBSettings::getStr(const QString &attribute) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; return value(path).toString(); } void FWBSettings::setStr(const QString &attribute, const QString &val) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; setValue(path,val); } bool FWBSettings::getBool(const QString &attribute) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; return value(path).toBool(); } void FWBSettings::setBool(const QString &attribute, bool val ) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; setValue(path,val); } int FWBSettings::getInt(const QString &attribute) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; return value(path).toInt(); } void FWBSettings::setInt(const QString &attribute, int val ) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; setValue(path,val); } QStringList FWBSettings::getList(const QString &attribute) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; return value(path).toStringList(); } void FWBSettings::setList(const QString &attribute, QStringList &list) { QString path = SETTINGS_PATH_PREFIX "/" + attribute; setValue(path, list); } QString FWBSettings::getWDir() { return value(wdirSetpath).toString();} void FWBSettings::setWDir(const QString &wd) { setValue(wdirSetpath, wd);} QString FWBSettings::getDataDir() { return value(datadirSetpath).toString();} void FWBSettings::setDataDir(const QString &d) { setValue(datadirSetpath, d); FWObject::setDataDir(d.toUtf8().constData()); } int FWBSettings::getInfoStyle() { return value(infoStyleSetpath).toInt();} void FWBSettings::setInfoStyle(int s) { setValue(infoStyleSetpath,s);} int FWBSettings::getInfoWindowHeight() { return value(infoWindowHSetpath).toInt();} void FWBSettings::setInfoWindowHeight(int h) { setValue(infoWindowHSetpath,h);} QString FWBSettings::getGroupViewMode() { return value(groupModeSetpath).toString();} void FWBSettings::setGroupViewMode(const QString &m) { setValue(groupModeSetpath,m);} QString FWBSettings::getGroupViewColumns() { return value(groupColsSetpath).toString();} void FWBSettings::setGroupViewColumns(const QString &m) { setValue(groupColsSetpath,m);} int FWBSettings::getStartupAction() { return value(startupActionSetpath).toInt();} void FWBSettings::setStartupAction(int sa) { setValue( startupActionSetpath , sa );} int FWBSettings::getExpandTree() { return value(expandTreeSetpath).toInt(); } void FWBSettings::setExpandTree(int f) { setValue( expandTreeSetpath , f ); } int FWBSettings::getMergeLibs() { return value(MergeLibsSetpath).toInt(); } void FWBSettings::setMergeLibs(int f) { setValue( MergeLibsSetpath , f ); } bool FWBSettings::getObjTooltips() { return value( objTooltips ).toBool();} void FWBSettings::setObjTooltips(bool f) { setValue( objTooltips, f); } int FWBSettings::getTooltipDelay() { return value( tooltipDelay ).toInt(); } void FWBSettings::setTooltipDelay(int v) { setValue( tooltipDelay, v); } QString FWBSettings::getLastEdited() { return value(lastEditedSetpath).toString();} void FWBSettings::setLastEdited(const QString &file) { setValue(lastEditedSetpath,file);} QString FWBSettings::getOpenFileDir(const QString &existingPath) { QString ret = getWDir(); if (!ret.isEmpty() && QFileInfo(ret).isDir()) return ret; ret = value(ofdirSetpath).toString(); if (!ret.isEmpty() && QFileInfo(ret).isDir()) return ret; if (!existingPath.isEmpty()) { ret = getFileDir(existingPath); if (QFileInfo(ret).isDir()) return ret; } return userDataDir.c_str(); } void FWBSettings::setOpenFileDir(const QString &d) { QString dirPath = d; QFileInfo info(d); if (!info.isDir()) { dirPath = info.dir().path(); } setValue(ofdirSetpath, dirPath); } void FWBSettings::save() { } bool FWBSettings::getRCSLogState() { return value( emptyRCSLog ).toBool(); } void FWBSettings::setRCSLogState(bool f) { setValue( emptyRCSLog , f ); } int FWBSettings::getRCSFilePreviewStyle() { return value(rcsFilePreviewStyle).toInt(); } void FWBSettings::setRCSFilePreviewStyle(int style) { setValue(rcsFilePreviewStyle, style); } int FWBSettings::getRCSFilePreviewSortColumn() { return value(rcsFilePreviewSortColumn).toInt(); } void FWBSettings::setRCSFilePreviewSortColumn(int col) { setValue(rcsFilePreviewSortColumn, col); } bool FWBSettings::getAutoSave() { return value( autoSave ).toBool(); } void FWBSettings::setAutoSave(bool f) { setValue( autoSave, f); } bool FWBSettings::getCompression() { return value(compression).toBool(); } void FWBSettings::setCompression(bool f) { setValue(compression, f); } bool FWBSettings::getDontSaveStdLib() {return value(dontSaveStdLib).toBool();} void FWBSettings::setDontSaveStdLib( bool f) { setValue(dontSaveStdLib,f);} bool FWBSettings::getShowUndoPanel() {return value(showUndoPanel).toBool();} void FWBSettings::setShowUndoPanel(bool f) {setValue(showUndoPanel, f);} bool FWBSettings::getIconsWithText() { return value(iconsWithText).toBool(); } void FWBSettings::setIconsWithText(bool f) {setValue(iconsWithText, f);} bool FWBSettings::haveScreenPosition(const QString &wname) { QString val = value(QString(screenPositionSetpath)+wname ).toString(); bool res=(!val.isEmpty()); if (fwbdebug) { qDebug("FWBSettings::haveScreenPosition wname '%s' ret=%d", wname.toLatin1().constData(), res); } return res; } QPoint FWBSettings::getScreenPosition(const QString &wname) { QString val = value(QString(screenPositionSetpath)+wname ).toString(); int x = val.section(',',0,0).toInt(); int y = val.section(',',1,1).toInt(); int width = 150; // won't get closer to the screen edge than this int height = 150; QDesktopWidget *d = QApplication::desktop(); // get geometry of the screen that contains mw QRect sg = d->screenGeometry(mw); if (x+width > sg.width()) x=sg.width()-width; if (y+height > sg.height()) y=sg.height()-height; if (x<0) x=(sg.width()-width)/2; if (y<0) y=(sg.height()-height)/2; if (fwbdebug) { qDebug("FWBSettings::getScreenPosition wname '%s' x=%d y=%d", wname.toLatin1().constData(), x,y ); } return QPoint(x,y); } void FWBSettings::saveScreenPosition(const QString &wname, const QPoint &p) { int x = p.x(); int y = p.y(); if (x<0) x=0; if (y<0) y=0; QString val =QString("%1,%2").arg(x).arg(y); if (fwbdebug) { qDebug("FWBSettings::saveScreenPosition wname '%s' x=%d y=%d", wname.toLatin1().constData(), x,y ); } setValue(QString(screenPositionSetpath)+wname, val ); } bool FWBSettings::haveGeometry(QWidget *w) { QString name=w->objectName(); QString val = value(QString(WindowGeometrySetpath)+name,"").toString(); return (!val.isEmpty()); } void FWBSettings::restoreGeometry(QWidget *w) { QString name=w->objectName(); QString val = value(QString(WindowGeometrySetpath)+name ).toString(); int x = val.section(',',0,0).toInt(); int y = val.section(',',1,1).toInt(); int width = val.section(',',2,2).toInt(); int height = val.section(',',3,3).toInt(); QDesktopWidget *d = QApplication::desktop(); // get geometry of the screen that contains mw QRect sg = d->screenGeometry(mw); if (width > sg.width() || height > sg.height()) { w->showMaximized(); return; } if (x+width > sg.width()) x=sg.width()-width; if (y+height > sg.height()) y=sg.height()-height; if (x<0) x=(sg.width()-width)/2; if (y<0) y=(sg.height()-height)/2; if (fwbdebug) { qDebug("FWBSettings::restoreGeometry widget '%s' vis=%d x=%d y=%d", name.toAscii().constData(), w->isVisible(), x,y); } w->resize( QSize(width,height) ); } void FWBSettings::restoreGeometry(QWidget *w, const QRect &dg) { QString name=w->objectName(); QString defval =QString("%1,%2,%3,%4") .arg(dg.x()).arg(dg.y()).arg(dg.width()).arg(dg.height()); QString val = value(QString(WindowGeometrySetpath)+name , defval ).toString(); int x = val.section(',',0,0).toInt(); int y = val.section(',',1,1).toInt(); int width = val.section(',',2,2).toInt(); int height = val.section(',',3,3).toInt(); QDesktopWidget *d = QApplication::desktop(); // get geometry of the screen that contains mw QRect sg = d->screenGeometry(mw); if (width > sg.width() || height > sg.height()) { w->showMaximized(); return; } if (x+width > sg.width()) x=sg.width()-width; if (y+height > sg.height()) y=sg.height()-height; if (x<0) x=(sg.width()-width)/2; if (y<0) y=(sg.height()-height)/2; if (fwbdebug) { qDebug("FWBSettings::restoreGeometry widget '%s' vis=%d x=%d y=%d", name.toAscii().constData(), w->isVisible(), x,y); } w->resize( QSize(width,height) ); } void FWBSettings::saveGeometry(QWidget *w) { QString name = w->objectName(); // QRect g = w->geometry(); // g.moveTopLeft(w->frameGeometry().topLeft()); QPoint p = w->pos(); QSize s = w->size(); int x = p.x(); int y = p.y(); if (x<0) x=0; if (y<0) y=0; QString val =QString("%1,%2,%3,%4") .arg(p.x()) .arg(p.y()) .arg(s.width()) .arg(s.height()); if (fwbdebug) { qDebug("FWBSettings::saveGeometry widget '%s' vis=%d val=%s", name.toAscii().constData(), w->isVisible(), val.toAscii().constData()); } setValue(QString(WindowGeometrySetpath)+name, val); } QString FWBSettings::getLabelColorStr(enum LabelColors c) { switch (c) { case RED: return "red"; case ORANGE: return "orange"; case YELLOW: return "yellow"; case GREEN: return "green"; case BLUE: return "blue"; case PURPLE: return "purple"; case GRAY: return "gray"; default: return "default"; } } QString FWBSettings::getLabelColor(enum LabelColors c) { return value(QString(labelColorPath) + getLabelColorStr(c)).toString(); } void FWBSettings::setLabelColor(enum LabelColors c,const QString &s) { setValue(QString(labelColorPath) + getLabelColorStr(c), s); } QString FWBSettings::getLabelText(enum LabelColors c) { return value(QString(labelTextPath) + getLabelColorStr(c)).toString(); } void FWBSettings::setLabelText(enum LabelColors c, const QString &s) { setValue(QString(labelTextPath) + getLabelColorStr(c),s); } QString FWBSettings::getSSHPath() { return value(SSHPath).toString(); } void FWBSettings::setSSHPath(const QString &path) { setValue(SSHPath,path); } QString FWBSettings::getSCPPath() { return value(SCPPath).toString(); } void FWBSettings::setSCPPath(const QString &path) { setValue(SCPPath,path); } // Putty uses different parameter name for the server alive interval // and keeps it as part of the session, stored in registry. Using // separate QSettings object on windows that controls putty session // "fwb_session_with_keepalive". On all other platforms // ssh_timeout_setings_object == this bool FWBSettings::haveSSHTimeout() { return ssh_timeout_setings_object->contains(SSHTimeout); } int FWBSettings::getSSHTimeout() { return ssh_timeout_setings_object->value(SSHTimeout).toInt(); } void FWBSettings::setSSHTimeout(int value_sec) { ssh_timeout_setings_object->setValue(SSHTimeout, value_sec); } void FWBSettings::getPrinterOptions(QPrinter *printer, int &pageWidth, int &pageHeight) { QString name = getStr("PrintSetup/printerName"); if (!name.isEmpty()) printer->setPrinterName( getStr("PrintSetup/printerName")); #ifndef _WIN32 printer->setPrinterSelectionOption( getStr("PrintSetup/printerSelectionOption")); #endif #ifndef Q_OS_MAC printer->setOutputFileName(getStr("PrintSetup/outputFileName")); #endif printer->setOrientation( QPrinter::Orientation(getInt("PrintSetup/orientation"))); printer->setPageSize( QPrinter::PageSize(getInt("PrintSetup/pageSize"))); printer->setPageOrder( QPrinter::PageOrder(getInt("PrintSetup/pageOrder"))); // int res = getInt("PrintSetup/resolution"); // if (res>0) printer->setResolution(res); printer->setColorMode( QPrinter::ColorMode(getInt("PrintSetup/colorMode"))); printer->setFullPage( getBool("PrintSetup/fullPage")); // printer->setFromTo(getInt("PrintSetup/fromPage"),getInt("PrintSetup/toPage")); // printer->setNumCopies(getInt("PrintSetup/numCopies")); pageWidth = getInt("PrintSetup/pageWidth"); pageHeight = getInt("PrintSetup/pageHeight"); } void FWBSettings::setPrinterOptions(QPrinter *printer, int pageWidth, int pageHeight) { setStr("PrintSetup/printerName",printer->printerName()); #ifndef _WIN32 setStr("PrintSetup/printerSelectionOption", printer->printerSelectionOption()); #endif setStr("PrintSetup/outputFileName",printer->outputFileName()); setInt("PrintSetup/orientation",printer->orientation()); setInt("PrintSetup/pageSize",printer->pageSize()); setInt("PrintSetup/pageOrder",printer->pageOrder()); // setInt("PrintSetup/resolution",printer->resolution()); setInt("PrintSetup/colorMode",printer->colorMode()); setBool("PrintSetup/fullPage",printer->fullPage()); // setInt("PrintSetup/fromPage",printer->fromPage()); // setInt("PrintSetup/toPage",printer->toPage()); // setInt("PrintSetup/numCopies",printer->numCopies()); setInt("PrintSetup/pageWidth",pageWidth); setInt("PrintSetup/pageHeight",pageHeight); } FWBSettings::IconSize FWBSettings::getIconsInRulesSize() { QString val = value(QString(iconsInRulesSize)).toString(); if ("SIZE25X25" == val) return SIZE25X25; if ("SIZE16X16" == val) return SIZE16X16; return SIZE25X25; } void FWBSettings::setIconsInRulesSize(FWBSettings::IconSize size) { setValue(QString(iconsInRulesSize), QString(SIZE25X25 == size ? "SIZE25X25":"SIZE16X16")); } bool FWBSettings::getShowIconsInRules() { return value(showIconsInRules).toBool(); } void FWBSettings::setShowIconsInRules(bool showIcons) { setValue(showIconsInRules, showIcons); } bool FWBSettings::getShowDirectionText() { return value(showDirectionText).toBool(); } void FWBSettings::setShowDirectionText(bool showText) { setValue(showDirectionText, showText); } QFont FWBSettings::getRulesFont() { return getFontByType(rulesFont); } void FWBSettings::setRulesFont(const QFont &font) { setValue(rulesFont, font.toString()); } QFont FWBSettings::getTreeFont() { return getFontByType(treeFont); } void FWBSettings::setTreeFont(const QFont &font) { setValue(treeFont, font.toString()); } QFont FWBSettings::getUiFont() { return getFontByType(uiFont); } void FWBSettings::setUiFont(const QFont &font) { setValue(uiFont, font.toString()); } QFont FWBSettings::getCompilerOutputFont() { return getFontByType(compilerOutputFont); } void FWBSettings::setCompilerOutputFont(const QFont &font) { setValue(compilerOutputFont, font.toString()); } QFont FWBSettings::getFontByType(const char *type) { QFont font = QFont(); bool ok = font.fromString(value(type).toString()); if (ok) return font; return QApplication::font(); } bool FWBSettings::getClipComment() { return value(clipComment).toBool(); } void FWBSettings::setClipComment(bool clip) { setValue(clipComment, clip); } bool FWBSettings::getCheckUpdates() { return value(checkUpdates).toBool(); } void FWBSettings::setCheckUpdates(bool f) { setValue(checkUpdates, f); } uint FWBSettings::getTimeOfLastUpdateAvailableWarning() { return value(updateAvailableWarningLastTime).toUInt(); } void FWBSettings::setTimeOfLastUpdateAvailableWarning(uint v) { setValue(updateAvailableWarningLastTime, v); } uint FWBSettings::getTimeOfLastAnnouncement(const QString &announcement) { QByteArray h = QCryptographicHash::hash(announcement.toAscii().constData(), QCryptographicHash::Md5).toHex(); return value(QString(announcementLastTime).arg(h.constData())).toUInt(); } void FWBSettings::setTimeOfLastAnnouncement(const QString &announcement, uint v) { QByteArray h = QCryptographicHash::hash(announcement.toAscii().constData(), QCryptographicHash::Md5).toHex(); setValue(QString(announcementLastTime).arg(h.constData()), v); } QString FWBSettings::getCheckUpdatesProxy() { return value(checkUpdatesProxy).toString(); } void FWBSettings::setCheckUpdatesProxy(const QString &proxy_line) { setValue(checkUpdatesProxy, proxy_line); } void FWBSettings::getExpandedObjectIds(const QString &filename, const QString &lib, std::set &ids) { ids.clear(); QString ids_str = value( QString(SETTINGS_PATH_PREFIX "/") + "Window/" + filename + "/" + lib + "/ExpandedTreeItems").toString(); QStringList strl = ids_str.split(","); for (QStringList::iterator i=strl.begin(); i!=strl.end(); ++i) ids.insert(FWObjectDatabase::getIntId(i->toStdString())); } void FWBSettings::setExpandedObjectIds(const QString &filename, const QString &lib, const std::set &ids) { QStringList strl; for (set::const_iterator i=ids.begin(); i!=ids.end(); ++i) strl.push_back(FWObjectDatabase::getStringId(*i).c_str()); setValue( QString(SETTINGS_PATH_PREFIX "/") + "Window/" + filename + "/" + lib + "/ExpandedTreeItems", strl.join(",")); } int FWBSettings::getTreeSectionSize(const QString &filename, const QString &lib, int section_index) { int v = value( QString(SETTINGS_PATH_PREFIX "/Window/%1/%2/TreeSection/%3") .arg(filename).arg(lib).arg(section_index)).toInt(); if (v <= 0) v = 300; return v; } void FWBSettings::setTreeSectionSize(const QString &filename, const QString &lib, int section_index, int size) { setValue( QString(SETTINGS_PATH_PREFIX "/Window/%1/%2/TreeSection/%3") .arg(filename).arg(lib).arg(section_index), size); } int FWBSettings::getVisibleRuleSetId(const QString &filename, const QString &lib) { string str_id = value( QString(SETTINGS_PATH_PREFIX "/") + "Window/" + filename + "/" + lib + "/OpenedRuleSet").toString().toStdString(); return FWObjectDatabase::getIntId(str_id); } void FWBSettings::setVisibleRuleSet(const QString &filename, const QString &lib, FWObject *ruleset) { setValue(QString(SETTINGS_PATH_PREFIX "/") + "Window/" + filename + "/" + lib + "/OpenedRuleSet", FWObjectDatabase::getStringId(ruleset->getId()).c_str() ); } void FWBSettings::getCollapsedRuleGroups(const QString &filename, const QString &firewall, const QString &ruleset, QStringList &collapsed_groups) { QString key = "Window/" + filename + "/" + firewall + "/" + ruleset + "/CollapsedRuleGroups"; QString strl = value(QString(SETTINGS_PATH_PREFIX "/") + key).toString(); // QT regexp does not support negative lookbehind that we need to // find all "," if they are not preceded by a "\". Will split the // string on all commas, then find elements of the array that end // with "\" and combine them with the following ones. QStringList lst = strl.split(","); QStringListIterator i(lst); while (i.hasNext()) { QString group_name = i.next(); while (group_name.endsWith("\\") && i.hasNext()) group_name += QString(",") + i.next(); group_name.replace("\\,", ","); collapsed_groups.push_back(group_name); } if (fwbdebug) qDebug() << "FWBSettings::getCollapsedRuleGroups" << key << collapsed_groups.join(" ||| "); } void FWBSettings::setCollapsedRuleGroups(const QString &filename, const QString &firewall, const QString &ruleset, const QStringList &collapsed_groups) { QStringList lst; foreach(QString group_name, collapsed_groups) { group_name.replace(",", "\\,"); lst.push_back(group_name); } QString key = "Window/" + filename + "/" + firewall + "/" + ruleset + "/CollapsedRuleGroups"; QString val = lst.join(","); if (fwbdebug) qDebug() << "FWBSettings::setCollapsedRuleGroups" << key << val; setValue(QString(SETTINGS_PATH_PREFIX "/") + key, val); } QStringList FWBSettings::getRecentFiles() { return getList("recentFiles"); } void FWBSettings::setRecentFiles(QStringList &list) { return setList("recentFiles", list); } QString FWBSettings::getNewFirewallPlatform() { return value(newFirewallPlatform).toString(); } void FWBSettings::setNewFirewallPlatform(const QString &platform) { setValue(newFirewallPlatform, platform); } QString FWBSettings::getNewClusterFailoverProtocol() { return value(newClusterFailoverProtocol).toString(); } void FWBSettings::setNewClusterFailoverProtocol(const QString &platform) { setValue(newClusterFailoverProtocol, platform); } QString FWBSettings::getTargetStatus(const QString &platform, const QString &default_stat) { QString var_path = targetStatus + platform; bool ok = contains(var_path); if (!ok) return default_stat; return value(var_path).toString(); } void FWBSettings::setTargetStatus(const QString &platform, const QString &status) { QString var_path = targetStatus + platform; setValue(var_path, status); } int FWBSettings::getABTestingGroup() { return value(abTestingGroup).toInt(); } void FWBSettings::setABTestingGroup(int n) { setValue(abTestingGroup, n); } int FWBSettings::getStartsCounter() { return value(startsCounter).toInt(); } bool FWBSettings::isIntroDialogEnabled() { return value(introDialogEnabled).toBool(); } void FWBSettings::setIntroDialogEnabled(bool f) { setValue(introDialogEnabled, f); } bool FWBSettings::customTemplatesEnabled() { return value(customTemplatesEn).toBool(); } void FWBSettings::setCustomTemplatesEnabled(bool f) { setValue(customTemplatesEn, f); } fwbuilder-5.1.0.3599/src/libgui/listOfLibrariesModel.cpp0000644000175000017500000001205011733011756023620 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2010 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "global.h" #include "ObjectTreeView.h" #include "listOfLibrariesModel.h" #include "fwbuilder/FWObject.h" #include #include using namespace libfwbuilder; ListOfLibrariesModel::ListOfLibrariesModel(QObject *parent) : QStringListModel(parent) { top_static_items.push_back(tr("Object Libraries:")); // top_static_items.push_back(tr("----------------")); } void ListOfLibrariesModel::addStaticItems() { int row = rowCount(); foreach(QString itm, top_static_items) { insertRows(row, 1); QModelIndex idx = index(row, 0); QStringListModel::setData(idx, itm, Qt::DisplayRole); row++; } // setData(idx, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole); } Qt::ItemFlags ListOfLibrariesModel::flags(const QModelIndex &index) const { int row = index.row(); if (row < 0 || row >= items.size()) return 0; FWObject *lib = items.at(index.row()).lib; if (lib == NULL) return Qt::ItemIsEnabled; else return QStringListModel::flags(index); } bool ListOfLibrariesModel::insertRows(int row, int count, const QModelIndex & parent) { for (int c=0; c < count; ++c) items.insert(row, _item_data("", NULL, NULL)); return QStringListModel::insertRows(row, count, parent); } bool ListOfLibrariesModel::removeRows(int row, int count, const QModelIndex &parent) { int c = count; while (c > 0) { items.removeAt(row); c--; } return QStringListModel::removeRows(row, count, parent); } static bool ascendingLessThan(const _item_data &s1, const _item_data &s2) { return s1.name < s2.name; } static bool decendingLessThan(const _item_data &s1, const _item_data &s2) { return s1.name > s2.name; } void ListOfLibrariesModel::sort(int column, Qt::SortOrder order) { QList<_item_data> list; for (int i=0; igetId() == lib->getId()) { return idx; } } } return QModelIndex(); } FWObject* ListOfLibrariesModel::getLibrary(QModelIndex idx) { return getLibrary(idx.row()); } FWObject* ListOfLibrariesModel::getLibrary(int row) { if (row < 0 || row >= items.size()) return NULL; return items[row].lib; } ObjectTreeView* ListOfLibrariesModel::getTreeWidget(QModelIndex idx) { return getTreeWidget(idx.row()); } ObjectTreeView* ListOfLibrariesModel::getTreeWidget(int row) { if (row < 0 || row >= items.size()) return NULL; return items[row].tree; } void ListOfLibrariesModel::setData(QModelIndex idx, const QString &name, FWObject *lib, ObjectTreeView *otv) { int row = idx.row(); if (row < 0 || row >= items.size()) return ; items[row] = _item_data(name, lib, otv); QStringListModel::setData(idx, indentLibName(name, lib!=NULL), Qt::DisplayRole); } void ListOfLibrariesModel::setName(QModelIndex idx, const QString &name) { int row = idx.row(); if (row < 0 || row >= items.size()) return ; items[row].name = name; QStringListModel::setData(idx, indentLibName(name, items.at(row).lib!=NULL), Qt::DisplayRole); } QString ListOfLibrariesModel::indentLibName(const QString &name, bool indent) { if (indent) return " " + name; else return name; } fwbuilder-5.1.0.3599/src/libgui/CompilerDriverFactory.cpp0000644000175000017500000000375111733011756024030 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2009 NetCitadel, LLC Author: Vadim Kurland vadim@vk.crocodile.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "CompilerDriverFactory.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/FWObjectDatabase.h" #include "CompilerDriver_ipt.h" #include "CompilerDriver_pf.h" #include "CompilerDriver_ipf.h" #include "CompilerDriver_ipfw.h" #include "CompilerDriver_iosacl.h" #include "CompilerDriver_pix.h" #include "CompilerDriver_procurve_acl.h" #include using namespace libfwbuilder; using namespace fwcompiler; using namespace std; CompilerDriver* CompilerDriverFactory::createCompilerDriver(Firewall *fw) { string platform = fw->getStr("platform"); if (platform == "iptables") return new CompilerDriver_ipt(fw->getRoot()); if (platform == "pf") return new CompilerDriver_pf(fw->getRoot()); if (platform == "ipf") return new CompilerDriver_ipf(fw->getRoot()); if (platform == "ipfw") return new CompilerDriver_ipfw(fw->getRoot()); if (platform == "iosacl") return new CompilerDriver_iosacl(fw->getRoot()); if (platform == "pix" || platform == "fwsm") return new CompilerDriver_pix(fw->getRoot()); if (platform == "procurve_acl") return new CompilerDriver_procurve_acl(fw->getRoot()); return NULL; } fwbuilder-5.1.0.3599/src/libgui/icmpservicedialog_q.ui0000644000175000017500000001374311733011756023420 0ustar sylvestresylvestre ICMPServiceDialog_q true 0 0 668 230 0 0 ICMP QFrame::Box QFrame::Sunken 0 0 350 0 350 16777215 QFrame::Box QFrame::Sunken 0 0 Name: false 200 0 0 0 ICMP Type: false 80 16777215 any -1 255 Qt::Horizontal 167 20 ICMP Code: false any -1 255 Qt::Vertical 20 82 0 0 CommentKeywords QWidget
CommentKeywords.h
1
obj_name icmpType icmpCode
fwbuilder-5.1.0.3599/src/libgui/secuwallIfaceOptsDialog.cpp0000644000175000017500000001013011733011756024274 0ustar sylvestresylvestre/* * secuwallIfaceOptsDialog.cpp - secunet wall Interface options implementation * * Copyright (c) 2008 secunet Security Networks AG * Copyright (c) 2008 Adrian-Ken Rueegsegger * Copyright (c) 2008 Reto Buerki * * This work is dual-licensed under: * * o The terms of the GNU General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your option) * any later version. * * o The terms of NetCitadel End User License Agreement */ #include "secuwallIfaceOptsDialog.h" #include "platforms.h" #include "FWCmdChange.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Cluster.h" #include "fwbuilder/Resources.h" #include "fwbuilder/Firewall.h" #include "FWWindow.h" #include "Help.h" #include #include using namespace std; using namespace libfwbuilder; secuwallIfaceOptsDialog::secuwallIfaceOptsDialog(QWidget *parent, FWObject *o) : QDialog(parent) { m_dialog = new Ui::secuwallIfaceOptsDialog_q; m_dialog->setupUi(this); obj = o; FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject(); cluster_interface = (Cluster::cast(obj->getParent()) != NULL); setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj), ifopt->getStr("type").c_str()); // Using "type" control only for subinterfaces // and main interfaces of the firewall objects if (cluster_interface) { m_dialog->iface_type->hide(); m_dialog->iface_type_label->hide(); } else { m_dialog->iface_type->show(); m_dialog->iface_type_label->show(); } data.registerOption(m_dialog->iface_mtu, ifopt, "iface_mtu"); data.registerOption(m_dialog->iface_disablearp, ifopt, "iface_disablearp"); data.registerOption(m_dialog->iface_disableboot, ifopt, "iface_disableboot"); data.registerOption(m_dialog->iface_options, ifopt, "iface_options"); data.registerOption(m_dialog->vlan_id, ifopt, "vlan_id"); data.loadAll(); // perform special actions for different iface types typeChanged(""); } secuwallIfaceOptsDialog::~secuwallIfaceOptsDialog() { delete m_dialog; } /* * store all data in the object */ void secuwallIfaceOptsDialog::accept() { ProjectPanel *project = mw->activeProject(); std::auto_ptr cmd( new FWCmdChange(project, obj)); // new_state is a copy of the interface object FWObject* new_state = cmd->getNewState(); FWOptions* ifopt = Interface::cast(new_state)->getOptionsObject(); assert(ifopt!=NULL); if (cluster_interface) { ifopt->setStr("type", "cluster_interface"); } else { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); ifopt->setStr("type", new_type.toStdString()); } data.saveAll(ifopt); if (!cmd->getOldState()->cmp(new_state, true)) project->undoStack->push(cmd.release()); QDialog::accept(); } void secuwallIfaceOptsDialog::reject() { QDialog::reject(); } void secuwallIfaceOptsDialog::help() { QString tab_title = m_dialog->tabWidget->tabText( m_dialog->tabWidget->currentIndex()); QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower(); Help *h = Help::getHelpWindow(this); h->setName("Interface secunet wall"); h->setSource(QUrl("secuwallIfaceOptsDialog.html#" + anchor)); h->raise(); h->show(); } void secuwallIfaceOptsDialog::typeChanged(const QString&) { QString new_type = m_dialog->iface_type->itemData( m_dialog->iface_type->currentIndex()).toString(); // enable VLAN page for type VLAN if (new_type == "8021q") { m_dialog->options_stack->setCurrentIndex(1); return; } // page 0 is empty m_dialog->options_stack->setCurrentIndex(0); } fwbuilder-5.1.0.3599/src/libgui/FindWhereUsedWidget.cpp0000644000175000017500000002420411733011756023406 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2006 NetCitadel, LLC Author: Illiya Yalovoy $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "definitions.h" #include "global.h" #include "utils.h" #include "utils_no_qt.h" #include "platforms.h" #include "events.h" #include "FindWhereUsedWidget.h" #include "FWWindow.h" #include "FWObjectDropArea.h" #include "ObjectManipulator.h" #include "FWBTree.h" #include "FWBSettings.h" #include "ObjectTreeView.h" #include "RuleSetView.h" #include "ProjectPanel.h" #include "ColDesc.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/FWReference.h" #include "fwbuilder/RuleSet.h" #include "fwbuilder/NAT.h" #include "fwbuilder/Routing.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Rule.h" #include "fwbuilder/RuleElement.h" #include "fwbuilder/Firewall.h" #include "fwbuilder/Library.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/Resources.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace libfwbuilder; FindWhereUsedWidget::FindWhereUsedWidget(QWidget *p, ProjectPanel *pp, const char * n, Qt::WindowFlags f, bool f_mini) : QWidget(p) { project_panel = pp; m_widget = new Ui::findWhereUsedWidget_q; m_widget->setupUi(this); setObjectName(n); setWindowFlags(f); flShowObject=true; if (f_mini) { m_widget->pushButton2->hide(); m_widget->dropBox->hide(); } else { connect(m_widget->dropArea,SIGNAL(objectDeleted()),this,SLOT(init())); } } FindWhereUsedWidget::~FindWhereUsedWidget() { delete m_widget; } void FindWhereUsedWidget::setShowObject(bool fl) { flShowObject=fl; } /** * This signal is emitted when the user activates an item by single- * or double-clicking (depending on the platform, i.e. on the * QStyle::SH_ItemView_ActivateItemOnSingleClick style hint) or * pressing a special key (e.g., Enter). */ void FindWhereUsedWidget::itemActivated(QTreeWidgetItem* item, int) { FWObject *container = (FWObject*)(qVariantValue(item->data(1, Qt::UserRole))); if (flShowObject && container!=NULL) { showObject(container); } } /** * This signal is emitted when the user clicks inside the widget. * * The specified item is the item that was clicked, or 0 if no item * was clicked. The column is the item's column that was clicked. If * no item was clicked, no signal will be emitted. * */ void FindWhereUsedWidget::itemClicked(QTreeWidgetItem* item, int) { FWObject *container = (FWObject*)(qVariantValue(item->data(1, Qt::UserRole))); if (flShowObject && container!=NULL) { showObject(container); } } void FindWhereUsedWidget::find() { findFromDrop(); } void FindWhereUsedWidget::find(FWObject *obj) { m_widget->dropArea->insertObject(obj); find(); } void FindWhereUsedWidget::_find(FWObject *obj) { object = obj; m_widget->resListView->clear(); resset.clear(); if (fwbdebug) qDebug() << "FindWhereUsedWidget " << this << ": initiate search for " << obj->getName().c_str() << " project_panel " << project_panel; if (project_panel==NULL) return; FWObjectDatabase *db = obj->getRoot(); map > reference_holders; UsageResolver().findAllReferenceHolders(obj, db, reference_holders); // rearrange reference holder object we just found to be able to sort them QMap widget_items; map >::iterator it; for (it=reference_holders.begin(); it!=reference_holders.end(); ++it) { FWObject *c_obj = db->findInIndex(it->first); if (!m_widget->includeChildren->isChecked() && c_obj != obj) continue; foreach(FWObject *container, it->second) { QTreeWidgetItem *item = createQTWidgetItem(c_obj, container); if (item==NULL) continue; QStringList item_str; item_str << item->text(0) << item->text(1) << item->text(2); widget_items[item_str.join("/")] = item; } } // TODO: This is not ideal because lines are sorted alphabetically. // Rules should be sorted by their numbers numerically. QStringList keys = widget_items.keys(); qSort(keys); foreach(QString k, keys) { QTreeWidgetItem *item = widget_items[k]; m_widget->resListView->addTopLevelItem(item); } m_widget->resListView->resizeColumnToContents(0); m_widget->resListView->resizeColumnToContents(1); show(); } void FindWhereUsedWidget::init() { object = NULL; m_widget->resListView->clear(); resset.clear(); } void FindWhereUsedWidget::clear() { m_widget->dropArea->deleteObject(); // this emits signal that calls init() } void FindWhereUsedWidget::findFromDrop() { _find(m_widget->dropArea->getObject()); } void FindWhereUsedWidget::showObject(FWObject* o) { if (fwbdebug) qDebug("FindWhereUsedWidget::showObject o=%s (%s)", o->getName().c_str(), o->getTypeName().c_str()); if (object==NULL || o==NULL) return; if (RuleElement::cast(o)!=NULL || RuleElement::cast(o->getParent())!=NULL) { QCoreApplication::postEvent( project_panel, new showObjectInRulesetEvent(project_panel->getFileName(), o->getId())); return; } if (Rule::cast(o)!=NULL) { QCoreApplication::postEvent( project_panel, new openRulesetImmediatelyEvent(project_panel->getFileName(), o->getParent()->getId())); QCoreApplication::postEvent( project_panel, new selectRuleElementEvent(project_panel->getFileName(), o->getId(), ColDesc::Action)); return; } project_panel->unselectRules(); if (Group::cast(o)!=NULL) { QCoreApplication::postEvent( project_panel, new showObjectInTreeEvent(project_panel->getFileName(), o->getId())); project_panel->unselectRules(); } else { QCoreApplication::postEvent( project_panel, new showObjectInTreeEvent(project_panel->getFileName(), o->getId())); project_panel->unselectRules(); } } QTreeWidgetItem* FindWhereUsedWidget::createQTWidgetItem(FWObject *o, FWObject *container) { if (fwbdebug) qDebug() << "FindWhereUsedWidget::createQTWidgetItem" << "container:" << container->getName().c_str() << "(" << container->getTypeName().c_str() << ")"; QString c1, c2; FWObject *fw = NULL; Rule *r = NULL; RuleSet *rs = NULL; QPixmap object_icon; QPixmap parent_icon; FWBTree tree_format; if (tree_format.isSystem(container) || Library::cast(container)) return NULL; // container can be a Rule if user searched for an object used in action if (RuleElement::cast(container)!=NULL || Rule::cast(container)!=NULL) { fw = container; while (fw!=NULL && Firewall::cast(fw)==NULL) // Firewall::cast matches also Cluster { if (Rule::cast(fw)) r = Rule::cast(fw); if (RuleSet::cast(fw)) rs = RuleSet::cast(fw); fw = fw->getParent(); } if (fw==NULL || r==NULL || rs==NULL) return NULL; c1 = QString::fromUtf8(fw->getName().c_str()); QString ruleset_kind; if (NAT::isA(rs)) { ruleset_kind = tr("NAT rule set"); } else if (Policy::isA(rs)) { ruleset_kind = tr("Policy rule set"); } else if (Routing::isA(rs)) { ruleset_kind = tr("Routing rule set"); } else { ruleset_kind = tr("Rule set of unknown type"); } QString rule_element_name; if (RuleElement::cast(container)!=NULL) rule_element_name = getReadableRuleElementName( fw->getStr("platform"), container->getParent()->getTypeName()); if (Rule::cast(container)!=NULL) rule_element_name = "Action"; c2 += tr("%1 \"%2\" / Rule %3 / %4"). arg(ruleset_kind). arg(rs->getName().c_str()). arg(Rule::cast(r)->getPosition()). arg(rule_element_name); loadIcon(parent_icon, fw); } else { c1 = QString::fromUtf8(container->getName().c_str()); c2 = tr("Type: ")+QString::fromUtf8(container->getTypeName().c_str()); loadIcon(parent_icon, container); } loadIcon(object_icon, o); QStringList qsl; qsl << QString::fromUtf8(o->getName().c_str()) << c1 << c2; QTreeWidgetItem* item = new QTreeWidgetItem(qsl); item->setIcon(1, QIcon(parent_icon)); item->setIcon(0, QIcon(object_icon)); item->setData(1, Qt::UserRole, qVariantFromValue((void*)container)); return item; } fwbuilder-5.1.0.3599/src/libgui/UDPServiceDialog.h0000644000175000017500000000263111733011756022304 0ustar sylvestresylvestre/* Firewall Builder Copyright (C) 2003 NetCitadel, LLC Author: Vadim Kurland vadim@fwbuilder.org $Id$ This program is free software which we release under the GNU General Public License. You may redistribute and/or modify this program under the terms of that license as published by the Free Software Foundation; either version 2 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 General Public License for more details. To get a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __UDPSERVICEDIALOG_H_ #define __UDPSERVICEDIALOG_H_ #include "config.h" #include #include "BaseObjectDialog.h" #include #include "fwbuilder/FWObject.h" class ProjectPanel; class UDPServiceDialog : public BaseObjectDialog { Q_OBJECT; Ui::UDPServiceDialog_q *m_dialog; public: UDPServiceDialog(QWidget *parent); ~UDPServiceDialog(); public slots: virtual void applyChanges(); virtual void loadFWObject(libfwbuilder::FWObject *obj); virtual void validate(bool*); }; #endif // UDPSERVICEDIALOG_H fwbuilder-5.1.0.3599/VERSION.h0000644000175000017500000000007511733011756016276 0ustar sylvestresylvestre#define VERSION "5.1.0.3599" #define GENERATION "5.1" fwbuilder-5.1.0.3599/runqmake.sh0000755000175000017500000000031011733011756017152 0ustar sylvestresylvestre#!/bin/sh test -z "${QMAKE}" && QMAKE="qmake" C="-recursive" test -n "$QMAKESPEC" && C="$C -spec $QMAKESPEC " echo "QTDIR=\"$QTDIR\"" echo "Running qmake: $QMAKE $C" oIFS=$IFS IFS=" " $QMAKE $C